From 83e497b5162441df9ca9f06ec468cca67f2d38ac Mon Sep 17 00:00:00 2001 From: dark_sylinc Date: Sat, 22 Feb 2014 16:53:30 -0300 Subject: [PATCH] Changed ALL tabs to spaces in preparation for a merge Changed ALL line endings to LF (a few files were in CF/LF). This fixes screwup from commit 81746916438203c5dfc06177d8eb91e84d4f50f3 where all eols were changed to CF/LF --- .../MeshLodGenerator/include/OgreLodBuffer.h | 50 +- .../include/OgreLodCollapseCost.h | 26 +- .../include/OgreLodCollapseCostCurvature.h | 4 +- .../include/OgreLodCollapseCostOutside.h | 20 +- .../include/OgreLodCollapseCostProfiler.h | 34 +- .../include/OgreLodCollapseCostQuadric.h | 22 +- .../include/OgreLodCollapser.h | 86 +- .../MeshLodGenerator/include/OgreLodConfig.h | 198 +- .../include/OgreLodConfigSerializer.h | 172 +- .../MeshLodGenerator/include/OgreLodData.h | 234 +- .../include/OgreLodInputProvider.h | 16 +- .../include/OgreLodInputProviderBuffer.h | 92 +- .../include/OgreLodInputProviderMesh.h | 90 +- .../include/OgreLodOutputProvider.h | 16 +- .../include/OgreLodOutputProviderBuffer.h | 20 +- .../OgreLodOutputProviderCompressedBuffer.h | 8 +- .../OgreLodOutputProviderCompressedMesh.h | 54 +- .../include/OgreLodOutputProviderMesh.h | 14 +- .../include/OgreLodOutsideMarker.h | 244 +- .../include/OgreLodPrerequisites.h | 68 +- .../include/OgreLodWorkQueueInjector.h | 24 +- .../OgreLodWorkQueueInjectorListener.h | 8 +- .../include/OgreLodWorkQueueRequest.h | 12 +- .../include/OgreLodWorkQueueWorker.h | 22 +- .../include/OgreMeshLodGenerator.h | 196 +- .../include/OgreOutsideMarker.h | 200 +- .../include/OgreSmallVector.h | 1386 +- .../MeshLodGenerator/include/OgreVectorSet.h | 22 +- .../include/OgreVectorSetImpl.h | 136 +- .../MeshLodGenerator/src/OgreLodBuffer.cpp | 192 +- .../src/OgreLodCollapseCost.cpp | 132 +- .../src/OgreLodCollapseCostCurvature.cpp | 334 +- .../src/OgreLodCollapseCostOutside.cpp | 64 +- .../src/OgreLodCollapseCostProfiler.cpp | 128 +- .../src/OgreLodCollapseCostQuadric.cpp | 162 +- .../MeshLodGenerator/src/OgreLodCollapser.cpp | 518 +- .../MeshLodGenerator/src/OgreLodConfig.cpp | 8 +- .../src/OgreLodConfigSerializer.cpp | 634 +- .../MeshLodGenerator/src/OgreLodData.cpp | 270 +- .../src/OgreLodInputProvider.cpp | 106 +- .../src/OgreLodInputProviderBuffer.cpp | 264 +- .../src/OgreLodInputProviderMesh.cpp | 354 +- .../src/OgreLodOutputProviderBuffer.cpp | 200 +- .../OgreLodOutputProviderCompressedBuffer.cpp | 344 +- .../OgreLodOutputProviderCompressedMesh.cpp | 422 +- .../src/OgreLodOutputProviderMesh.cpp | 146 +- .../src/OgreLodOutsideMarker.cpp | 1206 +- .../src/OgreLodWorkQueueInjector.cpp | 86 +- .../src/OgreLodWorkQueueWorker.cpp | 190 +- .../src/OgreMeshLodGenerator.cpp | 660 +- .../MeshLodGenerator/src/OgreSmallVector.cpp | 20 +- Components/Overlay/include/OgreFont.h | 398 +- Components/Overlay/include/OgreFontManager.h | 44 +- Components/Overlay/include/OgreOverlay.h | 72 +- .../Overlay/include/OgreOverlayContainer.h | 50 +- .../Overlay/include/OgreOverlayElement.h | 66 +- .../include/OgreOverlayElementCommands.h | 16 +- .../include/OgreOverlayElementFactory.h | 20 +- .../Overlay/include/OgreOverlayManager.h | 190 +- .../include/OgreOverlayPrerequisites.h | 24 +- .../OgreOverlayProfileSessionListener.h | 90 +- .../Overlay/include/OgreOverlaySystem.h | 46 +- .../Overlay/include/OgrePanelOverlayElement.h | 18 +- .../include/OgreTextAreaOverlayElement.h | 30 +- .../src/OgreBorderPanelOverlayElement.cpp | 558 +- Components/Overlay/src/OgreFont.cpp | 672 +- Components/Overlay/src/OgreFontManager.cpp | 186 +- Components/Overlay/src/OgreOverlay.cpp | 96 +- .../Overlay/src/OgreOverlayContainer.cpp | 218 +- Components/Overlay/src/OgreOverlayElement.cpp | 210 +- .../src/OgreOverlayElementCommands.cpp | 16 +- Components/Overlay/src/OgreOverlayManager.cpp | 708 +- .../src/OgreOverlayProfileSessionListener.cpp | 416 +- Components/Overlay/src/OgreOverlaySystem.cpp | 86 +- .../Overlay/src/OgrePanelOverlayElement.cpp | 222 +- .../src/OgreTextAreaOverlayElement.cpp | 666 +- .../Paging/include/OgreGrid3DPageStrategy.h | 346 +- Components/Paging/include/OgrePage.h | 330 +- .../Paging/include/OgrePageConnection.h | 18 +- Components/Paging/include/OgrePageContent.h | 100 +- .../include/OgrePageContentCollection.h | 128 +- .../OgrePageContentCollectionFactory.h | 48 +- .../Paging/include/OgrePageContentFactory.h | 42 +- .../Paging/include/OgrePageFileFormats.h | 342 +- Components/Paging/include/OgrePageManager.h | 874 +- Components/Paging/include/OgrePageStrategy.h | 198 +- Components/Paging/include/OgrePagedWorld.h | 420 +- .../Paging/include/OgrePagedWorldSection.h | 554 +- .../Paging/include/OgrePagingPrerequisites.h | 58 +- .../include/OgreSimplePageContentCollection.h | 194 +- .../Paging/src/OgreGrid2DPageStrategy.cpp | 824 +- .../Paging/src/OgreGrid3DPageStrategy.cpp | 642 +- Components/Paging/src/OgrePage.cpp | 820 +- Components/Paging/src/OgrePageContent.cpp | 60 +- .../Paging/src/OgrePageContentCollection.cpp | 66 +- Components/Paging/src/OgrePageManager.cpp | 966 +- Components/Paging/src/OgrePagedWorld.cpp | 562 +- .../Paging/src/OgrePagedWorldSection.cpp | 702 +- .../src/OgreSimplePageContentCollection.cpp | 200 +- Components/Property/include/OgreProperty.h | 646 +- .../include/OgrePropertyPrerequisites.h | 20 +- Components/Property/src/OgreProperty.cpp | 406 +- .../include/OgreShaderCGProgramProcessor.h | 44 +- .../include/OgreShaderCGProgramWriter.h | 112 +- .../OgreShaderExDualQuaternionSkinning.h | 28 +- .../include/OgreShaderExHardwareSkinning.h | 514 +- .../OgreShaderExHardwareSkinningTechnique.h | 172 +- .../include/OgreShaderExIntegratedPSSM3.h | 256 +- .../include/OgreShaderExLayeredBlending.h | 288 +- .../include/OgreShaderExLinearSkinning.h | 60 +- .../include/OgreShaderExNormalMapLighting.h | 696 +- .../include/OgreShaderExPerPixelLighting.h | 410 +- .../include/OgreShaderExTextureAtlasSampler.h | 446 +- .../include/OgreShaderFFPColour.h | 202 +- .../RTShaderSystem/include/OgreShaderFFPFog.h | 240 +- .../include/OgreShaderFFPLighting.h | 326 +- .../include/OgreShaderFFPRenderState.h | 124 +- .../include/OgreShaderFFPRenderStateBuilder.h | 146 +- .../include/OgreShaderFFPTexturing.h | 378 +- .../include/OgreShaderFFPTransform.h | 68 +- .../include/OgreShaderFunction.h | 324 +- .../include/OgreShaderFunctionAtom.h | 316 +- .../OgreShaderGLSLESProgramProcessor.h | 40 +- .../include/OgreShaderGLSLESProgramWriter.h | 128 +- .../include/OgreShaderGLSLProgramProcessor.h | 46 +- .../include/OgreShaderGLSLProgramWriter.h | 132 +- .../include/OgreShaderGenerator.h | 1792 +-- .../include/OgreShaderHLSLProgramProcessor.h | 36 +- .../include/OgreShaderHLSLProgramWriter.h | 120 +- .../OgreShaderMaterialSerializerListener.h | 84 +- .../include/OgreShaderParameter.h | 1088 +- .../include/OgreShaderPrerequisites.h | 34 +- .../include/OgreShaderProgram.h | 324 +- .../include/OgreShaderProgramManager.h | 358 +- .../include/OgreShaderProgramProcessor.h | 406 +- .../include/OgreShaderProgramSet.h | 58 +- .../include/OgreShaderProgramWriter.h | 30 +- .../include/OgreShaderProgramWriterManager.h | 132 +- .../include/OgreShaderRenderState.h | 250 +- .../include/OgreShaderScriptTranslator.h | 166 +- .../include/OgreShaderSubRenderState.h | 404 +- .../src/OgreShaderCGProgramProcessor.cpp | 34 +- .../src/OgreShaderCGProgramWriter.cpp | 332 +- .../OgreShaderExDualQuaternionSkinning.cpp | 692 +- .../src/OgreShaderExHardwareSkinning.cpp | 686 +- .../OgreShaderExHardwareSkinningTechnique.cpp | 54 +- .../src/OgreShaderExIntegratedPSSM3.cpp | 570 +- .../src/OgreShaderExLayeredBlending.cpp | 714 +- .../src/OgreShaderExLinearSkinning.cpp | 508 +- .../src/OgreShaderExNormalMapLighting.cpp | 2376 +-- .../src/OgreShaderExPerPixelLighting.cpp | 1458 +- .../src/OgreShaderExTextureAtlasSampler.cpp | 738 +- .../src/OgreShaderExTriplanarTexturing.cpp | 22 +- .../src/OgreShaderFFPColour.cpp | 450 +- .../RTShaderSystem/src/OgreShaderFFPFog.cpp | 624 +- .../src/OgreShaderFFPLighting.cpp | 1260 +- .../src/OgreShaderFFPRenderStateBuilder.cpp | 194 +- .../src/OgreShaderFFPTexturing.cpp | 1708 +-- .../src/OgreShaderFFPTransform.cpp | 124 +- .../RTShaderSystem/src/OgreShaderFunction.cpp | 698 +- .../src/OgreShaderFunctionAtom.cpp | 260 +- .../src/OgreShaderGLSLESProgramProcessor.cpp | 96 +- .../src/OgreShaderGLSLESProgramWriter.cpp | 278 +- .../src/OgreShaderGLSLProgramProcessor.cpp | 220 +- .../src/OgreShaderGLSLProgramWriter.cpp | 1116 +- .../src/OgreShaderGenerator.cpp | 2572 ++-- .../src/OgreShaderHLSLProgramProcessor.cpp | 34 +- .../src/OgreShaderHLSLProgramWriter.cpp | 404 +- .../OgreShaderMaterialSerializerListener.cpp | 164 +- .../src/OgreShaderParameter.cpp | 1166 +- .../RTShaderSystem/src/OgreShaderProgram.cpp | 414 +- .../src/OgreShaderProgramManager.cpp | 892 +- .../src/OgreShaderProgramProcessor.cpp | 1586 +- .../src/OgreShaderProgramSet.cpp | 46 +- .../src/OgreShaderProgramWriter.cpp | 54 +- .../src/OgreShaderProgramWriterManager.cpp | 44 +- .../src/OgreShaderRenderState.cpp | 362 +- .../src/OgreShaderScriptTranslator.cpp | 362 +- .../src/OgreShaderSubRenderState.cpp | 146 +- Components/Terrain/include/OgreTerrain.h | 4160 ++--- .../include/OgreTerrainAutoUpdateLod.h | 134 +- Components/Terrain/include/OgreTerrainGroup.h | 1024 +- .../include/OgreTerrainLayerBlendMap.h | 304 +- .../Terrain/include/OgreTerrainLodManager.h | 228 +- .../include/OgreTerrainMaterialGenerator.h | 738 +- .../include/OgreTerrainMaterialGeneratorA.h | 464 +- .../include/OgreTerrainPagedWorldSection.h | 294 +- .../Terrain/include/OgreTerrainPaging.h | 190 +- .../include/OgreTerrainPrerequisites.h | 30 +- .../Terrain/include/OgreTerrainQuadTreeNode.h | 748 +- Components/Terrain/src/OgreTerrain.cpp | 9058 +++++------ .../Terrain/src/OgreTerrainAutoUpdateLod.cpp | 202 +- Components/Terrain/src/OgreTerrainGroup.cpp | 1972 +-- .../Terrain/src/OgreTerrainLayerBlendMap.cpp | 414 +- .../Terrain/src/OgreTerrainLodManager.cpp | 630 +- .../src/OgreTerrainMaterialGenerator.cpp | 318 +- .../src/OgreTerrainMaterialGeneratorA.cpp | 1330 +- .../src/OgreTerrainMaterialShaderHelperCg.cpp | 1738 +-- .../OgreTerrainMaterialShaderHelperHLSL.cpp | 1910 +-- .../src/OgreTerrainPagedWorldSection.cpp | 592 +- Components/Terrain/src/OgreTerrainPaging.cpp | 86 +- .../Terrain/src/OgreTerrainQuadTreeNode.cpp | 3204 ++-- .../Volume/include/OgreVolumeGridSource.h | 4 +- .../Volume/include/OgreVolumePrerequisites.h | 18 +- Components/Volume/src/OgreVolumeChunk.cpp | 10 +- .../Android/OgreAPKFileSystemArchive.h | 40 +- OgreMain/include/Android/OgreAPKZipArchive.h | 44 +- .../include/Android/OgreAndroidLogListener.h | 2 +- .../include/Android/OgreConfigDialogImp.h | 34 +- OgreMain/include/Android/OgreErrorDialogImp.h | 30 +- OgreMain/include/Android/OgreTimerImp.h | 44 +- .../include/FlashCC/OgreConfigDialogImp.h | 34 +- OgreMain/include/FlashCC/OgreTimerImp.h | 44 +- OgreMain/include/GLX/OgreConfigDialogImp.h | 68 +- OgreMain/include/GLX/OgreErrorDialogImp.h | 30 +- OgreMain/include/GLX/OgreTimerImp.h | 44 +- OgreMain/include/NaCl/OgreConfigDialogImp.h | 68 +- OgreMain/include/NaCl/OgreErrorDialogImp.h | 30 +- OgreMain/include/NaCl/OgreTimerImp.h | 44 +- OgreMain/include/OSX/OgreConfigDialogImp.h | 22 +- OgreMain/include/OSX/OgreErrorDialogImp.h | 30 +- OgreMain/include/OSX/OgreTimerImp.h | 44 +- OgreMain/include/OgreAlignedAllocator.h | 26 +- OgreMain/include/OgreAnimable.h | 552 +- OgreMain/include/OgreAnimationState.h | 228 +- OgreMain/include/OgreAnimationTrack.h | 584 +- OgreMain/include/OgreAny.h | 482 +- OgreMain/include/OgreArchive.h | 96 +- OgreMain/include/OgreArchiveFactory.h | 16 +- OgreMain/include/OgreArchiveManager.h | 42 +- OgreMain/include/OgreAtomicObject.h | 36 +- OgreMain/include/OgreAtomicScalar.h | 106 +- OgreMain/include/OgreAutoParamDataSource.h | 208 +- OgreMain/include/OgreAxisAlignedBox.h | 1402 +- OgreMain/include/OgreBillboard.h | 18 +- OgreMain/include/OgreBillboardChain.h | 670 +- .../include/OgreBillboardParticleRenderer.h | 12 +- OgreMain/include/OgreBitwise.h | 82 +- OgreMain/include/OgreBlendMode.h | 44 +- OgreMain/include/OgreBone.h | 40 +- OgreMain/include/OgreCodec.h | 90 +- OgreMain/include/OgreColourValue.h | 186 +- OgreMain/include/OgreCommon.h | 862 +- OgreMain/include/OgreCompositionPass.h | 416 +- OgreMain/include/OgreCompositionTargetPass.h | 84 +- OgreMain/include/OgreCompositionTechnique.h | 90 +- OgreMain/include/OgreCompositor.h | 90 +- OgreMain/include/OgreCompositorChain.h | 6 +- OgreMain/include/OgreCompositorLogic.h | 50 +- OgreMain/include/OgreCompositorManager.h | 436 +- OgreMain/include/OgreConfig.h | 42 +- OgreMain/include/OgreConfigFile.h | 30 +- OgreMain/include/OgreConfigOptionMap.h | 18 +- OgreMain/include/OgreController.h | 130 +- OgreMain/include/OgreConvexBody.h | 430 +- OgreMain/include/OgreCustomCompositionPass.h | 48 +- OgreMain/include/OgreDDSCodec.h | 74 +- OgreMain/include/OgreDataStream.h | 1020 +- .../OgreDefaultHardwareBufferManager.h | 180 +- OgreMain/include/OgreDeflate.h | 188 +- OgreMain/include/OgreDepthBuffer.h | 182 +- OgreMain/include/OgreDistanceLodStrategy.h | 42 +- OgreMain/include/OgreDualQuaternion.h | 286 +- OgreMain/include/OgreDynLib.h | 26 +- OgreMain/include/OgreETCCodec.h | 40 +- OgreMain/include/OgreEdgeListBuilder.h | 44 +- OgreMain/include/OgreEntity.h | 16 +- OgreMain/include/OgreException.h | 364 +- OgreMain/include/OgreExternalTextureSource.h | 250 +- .../OgreExternalTextureSourceManager.h | 74 +- OgreMain/include/OgreFileSystemLayer.h | 144 +- OgreMain/include/OgreFrameListener.h | 68 +- OgreMain/include/OgreFreeImageCodec.h | 38 +- OgreMain/include/OgreGpuProgramManager.h | 228 +- OgreMain/include/OgreGpuProgramParams.h | 12 +- OgreMain/include/OgreGpuProgramUsage.h | 56 +- OgreMain/include/OgreHardwareBuffer.h | 338 +- OgreMain/include/OgreHardwareBufferManager.h | 80 +- OgreMain/include/OgreHardwareCounterBuffer.h | 40 +- OgreMain/include/OgreHardwareIndexBuffer.h | 52 +- OgreMain/include/OgreHardwareOcclusionQuery.h | 126 +- OgreMain/include/OgreHardwarePixelBuffer.h | 176 +- OgreMain/include/OgreHardwareUniformBuffer.h | 40 +- OgreMain/include/OgreHardwareVertexBuffer.h | 426 +- OgreMain/include/OgreHeaderPrefix.h | 2 +- OgreMain/include/OgreHighLevelGpuProgram.h | 48 +- .../include/OgreHighLevelGpuProgramManager.h | 136 +- OgreMain/include/OgreImage.h | 448 +- OgreMain/include/OgreImageCodec.h | 30 +- OgreMain/include/OgreInstanceBatch.h | 146 +- OgreMain/include/OgreInstanceBatchHW.h | 108 +- OgreMain/include/OgreInstanceBatchHW_VTF.h | 104 +- OgreMain/include/OgreInstanceBatchShader.h | 96 +- OgreMain/include/OgreInstanceBatchVTF.h | 358 +- OgreMain/include/OgreInstanceManager.h | 58 +- OgreMain/include/OgreInstancedEntity.h | 486 +- OgreMain/include/OgreInstancedGeometry.h | 1580 +- OgreMain/include/OgreIteratorRange.h | 358 +- OgreMain/include/OgreIteratorWrapper.h | 342 +- OgreMain/include/OgreKeyFrame.h | 372 +- OgreMain/include/OgreLight.h | 2 +- OgreMain/include/OgreLodListener.h | 18 +- OgreMain/include/OgreLodStrategy.h | 20 +- OgreMain/include/OgreLodStrategyManager.h | 18 +- OgreMain/include/OgreLog.h | 204 +- OgreMain/include/OgreLogManager.h | 66 +- OgreMain/include/OgreManualObject.h | 1050 +- OgreMain/include/OgreMaterial.h | 194 +- OgreMain/include/OgreMaterialManager.h | 264 +- OgreMain/include/OgreMaterialSerializer.h | 430 +- OgreMain/include/OgreMath.h | 480 +- OgreMain/include/OgreMatrix3.h | 164 +- OgreMain/include/OgreMatrix4.h | 136 +- OgreMain/include/OgreMemoryAllocatedObject.h | 164 +- OgreMain/include/OgreMemoryAllocatorConfig.h | 638 +- OgreMain/include/OgreMemoryNedAlloc.h | 196 +- OgreMain/include/OgreMemoryNedPooling.h | 200 +- OgreMain/include/OgreMemorySTLAllocator.h | 354 +- OgreMain/include/OgreMemoryStdAlloc.h | 180 +- OgreMain/include/OgreMemoryTracker.h | 258 +- OgreMain/include/OgreMesh.h | 84 +- OgreMain/include/OgreMeshFileFormat.h | 190 +- OgreMain/include/OgreMeshManager.h | 250 +- OgreMain/include/OgreMeshSerializer.h | 204 +- OgreMain/include/OgreMeshSerializerImpl.h | 202 +- OgreMain/include/OgreMovableObject.h | 644 +- OgreMain/include/OgreMovablePlane.h | 24 +- OgreMain/include/OgreNode.h | 2 +- OgreMain/include/OgreNumerics.h | 40 +- OgreMain/include/OgreOptimisedUtil.h | 24 +- OgreMain/include/OgrePVRTCCodec.h | 54 +- OgreMain/include/OgreParticle.h | 60 +- OgreMain/include/OgreParticleAffector.h | 18 +- .../include/OgreParticleAffectorFactory.h | 20 +- OgreMain/include/OgreParticleEmitter.h | 110 +- .../include/OgreParticleEmitterCommands.h | 22 +- OgreMain/include/OgreParticleEmitterFactory.h | 20 +- OgreMain/include/OgreParticleIterator.h | 18 +- OgreMain/include/OgreParticleSystem.h | 540 +- OgreMain/include/OgreParticleSystemManager.h | 146 +- OgreMain/include/OgreParticleSystemRenderer.h | 92 +- OgreMain/include/OgrePass.h | 104 +- OgreMain/include/OgrePatchMesh.h | 24 +- OgreMain/include/OgrePatchSurface.h | 20 +- OgreMain/include/OgrePixelCountLodStrategy.h | 28 +- OgreMain/include/OgrePixelFormat.h | 388 +- .../include/OgrePixelFormatDescriptions.h | 4 +- OgreMain/include/OgrePlane.h | 44 +- OgreMain/include/OgrePlaneBoundedVolume.h | 18 +- OgreMain/include/OgrePlatform.h | 112 +- OgreMain/include/OgrePlatformInformation.h | 40 +- OgreMain/include/OgrePlugin.h | 188 +- OgreMain/include/OgrePolygon.h | 206 +- OgreMain/include/OgrePose.h | 198 +- OgreMain/include/OgrePredefinedControllers.h | 114 +- OgreMain/include/OgrePrefabFactory.h | 60 +- OgreMain/include/OgrePrerequisites.h | 388 +- OgreMain/include/OgreProfiler.h | 402 +- OgreMain/include/OgreQuaternion.h | 326 +- OgreMain/include/OgreRadixSort.h | 578 +- OgreMain/include/OgreRay.h | 96 +- OgreMain/include/OgreRectangle2D.h | 42 +- OgreMain/include/OgreRenderQueue.h | 198 +- OgreMain/include/OgreRenderQueueInvocation.h | 368 +- OgreMain/include/OgreRenderQueueListener.h | 60 +- .../include/OgreRenderQueueSortingGrouping.h | 782 +- OgreMain/include/OgreRenderSystem.h | 2890 ++-- .../include/OgreRenderSystemCapabilities.h | 1652 +- .../OgreRenderSystemCapabilitiesManager.h | 32 +- .../OgreRenderSystemCapabilitiesSerializer.h | 52 +- OgreMain/include/OgreRenderTarget.h | 338 +- OgreMain/include/OgreRenderTargetListener.h | 36 +- OgreMain/include/OgreRenderTexture.h | 176 +- OgreMain/include/OgreRenderWindow.h | 122 +- OgreMain/include/OgreRenderable.h | 2 +- OgreMain/include/OgreResource.h | 712 +- .../include/OgreResourceBackgroundQueue.h | 554 +- OgreMain/include/OgreResourceGroupManager.h | 1156 +- OgreMain/include/OgreResourceManager.h | 726 +- OgreMain/include/OgreRibbonTrail.h | 372 +- OgreMain/include/OgreRoot.h | 940 +- OgreMain/include/OgreRotationalSpline.h | 24 +- OgreMain/include/OgreSceneManager.h | 3200 ++-- OgreMain/include/OgreSceneManagerEnumerator.h | 254 +- OgreMain/include/OgreSceneNode.h | 126 +- OgreMain/include/OgreSceneQuery.h | 36 +- OgreMain/include/OgreScriptCompiler.h | 1574 +- OgreMain/include/OgreScriptLexer.h | 100 +- OgreMain/include/OgreScriptLoader.h | 102 +- OgreMain/include/OgreScriptParser.h | 40 +- OgreMain/include/OgreScriptTranslator.h | 488 +- OgreMain/include/OgreSerializer.h | 62 +- OgreMain/include/OgreShadowCameraSetup.h | 108 +- .../include/OgreShadowCameraSetupFocused.h | 2 +- .../include/OgreShadowCameraSetupLiSPSM.h | 394 +- OgreMain/include/OgreShadowCameraSetupPSSM.h | 176 +- .../OgreShadowCameraSetupPlaneOptimal.h | 84 +- OgreMain/include/OgreShadowTextureManager.h | 146 +- .../include/OgreShadowVolumeExtrudeProgram.h | 216 +- OgreMain/include/OgreSharedPtr.h | 274 +- OgreMain/include/OgreSimpleRenderable.h | 30 +- OgreMain/include/OgreSimpleSpline.h | 20 +- OgreMain/include/OgreSingleton.h | 36 +- OgreMain/include/OgreSkeleton.h | 274 +- OgreMain/include/OgreSkeletonFileFormat.h | 40 +- OgreMain/include/OgreSkeletonInstance.h | 62 +- OgreMain/include/OgreSkeletonManager.h | 34 +- OgreMain/include/OgreSkeletonSerializer.h | 80 +- OgreMain/include/OgreSphere.h | 102 +- OgreMain/include/OgreStableHeaders.h | 2 +- OgreMain/include/OgreStaticFaceGroup.h | 18 +- OgreMain/include/OgreStaticGeometry.h | 1426 +- OgreMain/include/OgreStdHeaders.h | 8 +- OgreMain/include/OgreStreamSerialiser.h | 702 +- OgreMain/include/OgreStringInterface.h | 58 +- OgreMain/include/OgreStringVector.h | 16 +- OgreMain/include/OgreSubEntity.h | 168 +- OgreMain/include/OgreSubMesh.h | 62 +- OgreMain/include/OgreTagPoint.h | 52 +- OgreMain/include/OgreTangentSpaceCalc.h | 440 +- OgreMain/include/OgreTechnique.h | 508 +- OgreMain/include/OgreTexture.h | 264 +- OgreMain/include/OgreTextureManager.h | 284 +- OgreMain/include/OgreTextureUnitState.h | 40 +- OgreMain/include/OgreUTFString.h | 1926 +-- .../include/OgreUnifiedHighLevelGpuProgram.h | 286 +- OgreMain/include/OgreUserObjectBindings.h | 204 +- OgreMain/include/OgreVector2.h | 146 +- OgreMain/include/OgreVector3.h | 290 +- OgreMain/include/OgreVector4.h | 88 +- OgreMain/include/OgreVertexBoneAssignment.h | 18 +- OgreMain/include/OgreVertexIndexData.h | 400 +- OgreMain/include/OgreViewport.h | 250 +- OgreMain/include/OgreWindowEventUtilities.h | 244 +- OgreMain/include/OgreWireBoundingBox.h | 48 +- OgreMain/include/OgreWorkQueue.h | 1084 +- OgreMain/include/OgreZip.h | 48 +- .../include/Threading/OgreDefaultWorkQueue.h | 8 +- .../Threading/OgreDefaultWorkQueueStandard.h | 86 +- .../Threading/OgreDefaultWorkQueueTBB.h | 78 +- .../include/Threading/OgreThreadDefines.h | 8 +- .../include/Threading/OgreThreadHeaders.h | 8 +- OgreMain/include/WIN32/OgreConfigDialogImp.h | 76 +- .../include/WIN32/OgreConfigDialogImpWinRT.h | 78 +- OgreMain/include/WIN32/OgreErrorDialogImp.h | 38 +- .../include/WIN32/OgreErrorDialogImpWinRT.h | 36 +- OgreMain/include/WIN32/OgreTimerImp.h | 74 +- OgreMain/include/asm_math.h | 64 +- OgreMain/include/gtk/OgreConfigDialogImp.h | 4 +- OgreMain/include/gtk/OgreErrorDialogImp.h | 28 +- OgreMain/include/iOS/OgreConfigDialogImp.h | 30 +- OgreMain/include/iOS/OgreErrorDialogImp.h | 30 +- OgreMain/include/iOS/OgreOSXCocoaTouchView.h | 2 +- OgreMain/include/iOS/OgreTimerImp.h | 44 +- OgreMain/src/Android/JNI/OgreActivityJNI.cpp | 440 +- .../src/Android/OgreAPKFileSystemArchive.cpp | 334 +- OgreMain/src/Android/OgreAPKZipArchive.cpp | 14 +- OgreMain/src/Android/OgreConfigDialog.cpp | 54 +- OgreMain/src/Android/OgreFileSystemLayer.cpp | 28 +- OgreMain/src/Android/OgreTimer.cpp | 26 +- OgreMain/src/FlashCC/OgreConfigDialog.cpp | 54 +- OgreMain/src/FlashCC/OgreTimer.cpp | 26 +- OgreMain/src/GLX/OgreConfigDialog.cpp | 712 +- OgreMain/src/GLX/OgreErrorDialog.cpp | 2 +- OgreMain/src/GLX/OgreFileSystemLayer.cpp | 236 +- OgreMain/src/GLX/OgreTimer.cpp | 26 +- OgreMain/src/NaCl/OgreConfigDialog.cpp | 2 +- OgreMain/src/NaCl/OgreErrorDialog.cpp | 2 +- OgreMain/src/NaCl/OgreFileSystemLayer.cpp | 20 +- OgreMain/src/NaCl/OgreTimer.cpp | 26 +- OgreMain/src/OSX/OgreFileSystemLayer.cpp | 102 +- OgreMain/src/OSX/OgreTimer.cpp | 26 +- OgreMain/src/OgreAnimable.cpp | 278 +- OgreMain/src/OgreAnimation.cpp | 874 +- OgreMain/src/OgreAnimationState.cpp | 340 +- OgreMain/src/OgreAnimationTrack.cpp | 1284 +- OgreMain/src/OgreArchiveManager.cpp | 64 +- OgreMain/src/OgreAutoParamDataSource.cpp | 1338 +- OgreMain/src/OgreAxisAlignedBox.cpp | 4 +- OgreMain/src/OgreBillboard.cpp | 4 +- OgreMain/src/OgreBillboardChain.cpp | 1562 +- .../src/OgreBillboardParticleRenderer.cpp | 166 +- OgreMain/src/OgreBillboardSet.cpp | 602 +- OgreMain/src/OgreBone.cpp | 28 +- OgreMain/src/OgreCamera.cpp | 966 +- OgreMain/src/OgreCodec.cpp | 46 +- OgreMain/src/OgreColourValue.cpp | 330 +- OgreMain/src/OgreCommon.cpp | 112 +- OgreMain/src/OgreCompositionPass.cpp | 88 +- OgreMain/src/OgreCompositionTargetPass.cpp | 20 +- OgreMain/src/OgreCompositionTechnique.cpp | 128 +- OgreMain/src/OgreCompositor.cpp | 436 +- OgreMain/src/OgreCompositorChain.cpp | 654 +- OgreMain/src/OgreCompositorInstance.cpp | 1528 +- OgreMain/src/OgreCompositorManager.cpp | 704 +- OgreMain/src/OgreConfigFile.cpp | 72 +- OgreMain/src/OgreControllerManager.cpp | 102 +- OgreMain/src/OgreConvexBody.cpp | 2340 +-- OgreMain/src/OgreDDSCodec.cpp | 1488 +- OgreMain/src/OgreDataStream.cpp | 436 +- .../src/OgreDefaultHardwareBufferManager.cpp | 398 +- OgreMain/src/OgreDefaultSceneQueries.cpp | 504 +- OgreMain/src/OgreDeflate.cpp | 696 +- OgreMain/src/OgreDepthBuffer.cpp | 190 +- OgreMain/src/OgreDualQuaternion.cpp | 112 +- OgreMain/src/OgreDynLib.cpp | 42 +- OgreMain/src/OgreDynLibManager.cpp | 58 +- OgreMain/src/OgreETCCodec.cpp | 296 +- OgreMain/src/OgreEdgeListBuilder.cpp | 86 +- OgreMain/src/OgreEntity.cpp | 1608 +- OgreMain/src/OgreException.cpp | 48 +- OgreMain/src/OgreExternalTextureSource.cpp | 280 +- .../src/OgreExternalTextureSourceManager.cpp | 178 +- OgreMain/src/OgreFileSystem.cpp | 298 +- OgreMain/src/OgreFreeImageCodec.cpp | 976 +- OgreMain/src/OgreFrustum.cpp | 1276 +- OgreMain/src/OgreGpuProgram.cpp | 408 +- OgreMain/src/OgreGpuProgramManager.cpp | 444 +- OgreMain/src/OgreGpuProgramUsage.cpp | 272 +- OgreMain/src/OgreHardwareBufferManager.cpp | 230 +- OgreMain/src/OgreHardwareCounterBuffer.cpp | 32 +- OgreMain/src/OgreHardwareIndexBuffer.cpp | 14 +- OgreMain/src/OgreHardwarePixelBuffer.cpp | 124 +- OgreMain/src/OgreHardwareUniformBuffer.cpp | 220 +- OgreMain/src/OgreHardwareVertexBuffer.cpp | 688 +- OgreMain/src/OgreHighLevelGpuProgram.cpp | 166 +- .../src/OgreHighLevelGpuProgramManager.cpp | 214 +- OgreMain/src/OgreImage.cpp | 1606 +- OgreMain/src/OgreImageResampler.h | 472 +- OgreMain/src/OgreInstanceBatch.cpp | 1086 +- OgreMain/src/OgreInstanceBatchHW.cpp | 450 +- OgreMain/src/OgreInstanceBatchHW_VTF.cpp | 1022 +- OgreMain/src/OgreInstanceBatchShader.cpp | 610 +- OgreMain/src/OgreInstanceBatchVTF.cpp | 1444 +- OgreMain/src/OgreInstanceManager.cpp | 1178 +- OgreMain/src/OgreInstancedEntity.cpp | 946 +- OgreMain/src/OgreInstancedGeometry.cpp | 4204 +++--- OgreMain/src/OgreKeyFrame.cpp | 316 +- OgreMain/src/OgreLight.cpp | 1048 +- OgreMain/src/OgreLodStrategy.cpp | 8 +- OgreMain/src/OgreLodStrategyManager.cpp | 20 +- OgreMain/src/OgreLog.cpp | 82 +- OgreMain/src/OgreLogManager.cpp | 80 +- OgreMain/src/OgreManualObject.cpp | 2204 +-- OgreMain/src/OgreMaterial.cpp | 482 +- OgreMain/src/OgreMaterialManager.cpp | 300 +- OgreMain/src/OgreMaterialSerializer.cpp | 2806 ++-- OgreMain/src/OgreMath.cpp | 780 +- OgreMain/src/OgreMatrix3.cpp | 8 +- OgreMain/src/OgreMatrix4.cpp | 34 +- OgreMain/src/OgreMemoryAllocatedObject.cpp | 30 +- OgreMain/src/OgreMemoryNedAlloc.cpp | 82 +- OgreMain/src/OgreMemoryNedPooling.cpp | 276 +- OgreMain/src/OgreMemoryTracker.cpp | 212 +- OgreMain/src/OgreMesh.cpp | 2342 +-- OgreMain/src/OgreMeshManager.cpp | 278 +- OgreMain/src/OgreMeshSerializer.cpp | 212 +- OgreMain/src/OgreMeshSerializerImpl.cpp | 5182 +++---- OgreMain/src/OgreMovableObject.cpp | 408 +- OgreMain/src/OgreNode.cpp | 626 +- OgreMain/src/OgreNumerics.cpp | 84 +- OgreMain/src/OgreOptimisedUtil.cpp | 10 +- OgreMain/src/OgreOptimisedUtilGeneral.cpp | 62 +- OgreMain/src/OgreOptimisedUtilSSE.cpp | 138 +- OgreMain/src/OgrePVRTCCodec.cpp | 210 +- OgreMain/src/OgreParticle.cpp | 2 +- OgreMain/src/OgreParticleEmitter.cpp | 158 +- OgreMain/src/OgreParticleEmitterCommands.cpp | 12 +- OgreMain/src/OgreParticleSystem.cpp | 1248 +- OgreMain/src/OgreParticleSystemManager.cpp | 272 +- OgreMain/src/OgrePass.cpp | 2672 ++-- OgreMain/src/OgrePatchMesh.cpp | 18 +- OgreMain/src/OgrePixelConversions.h | 62 +- OgreMain/src/OgrePixelFormat.cpp | 330 +- OgreMain/src/OgrePlane.cpp | 206 +- OgreMain/src/OgrePlatformInformation.cpp | 236 +- OgreMain/src/OgrePolygon.cpp | 444 +- OgreMain/src/OgrePose.cpp | 306 +- OgreMain/src/OgrePredefinedControllers.cpp | 164 +- OgreMain/src/OgrePrefabFactory.cpp | 668 +- OgreMain/src/OgreProfiler.cpp | 802 +- OgreMain/src/OgreQuaternion.cpp | 190 +- OgreMain/src/OgreRectangle2D.cpp | 104 +- OgreMain/src/OgreRenderQueue.cpp | 220 +- OgreMain/src/OgreRenderQueueInvocation.cpp | 196 +- .../src/OgreRenderQueueSortingGrouping.cpp | 530 +- OgreMain/src/OgreRenderSystem.cpp | 1116 +- OgreMain/src/OgreRenderSystemCapabilities.cpp | 786 +- .../OgreRenderSystemCapabilitiesManager.cpp | 8 +- ...OgreRenderSystemCapabilitiesSerializer.cpp | 100 +- OgreMain/src/OgreRenderTarget.cpp | 364 +- OgreMain/src/OgreRenderTexture.cpp | 66 +- OgreMain/src/OgreRenderWindow.cpp | 4 +- OgreMain/src/OgreResource.cpp | 526 +- OgreMain/src/OgreResourceBackgroundQueue.cpp | 738 +- OgreMain/src/OgreResourceGroupManager.cpp | 2740 ++-- OgreMain/src/OgreResourceManager.cpp | 740 +- OgreMain/src/OgreRibbonTrail.cpp | 910 +- OgreMain/src/OgreRoot.cpp | 1316 +- OgreMain/src/OgreRotationSpline.cpp | 2 +- OgreMain/src/OgreSIMDHelper.h | 16 +- OgreMain/src/OgreSceneManager.cpp | 7426 ++++----- OgreMain/src/OgreSceneManagerEnumerator.cpp | 512 +- OgreMain/src/OgreSceneNode.cpp | 244 +- OgreMain/src/OgreSceneQuery.cpp | 40 +- OgreMain/src/OgreScriptCompiler.cpp | 2972 ++-- OgreMain/src/OgreScriptLexer.cpp | 466 +- OgreMain/src/OgreScriptParser.cpp | 942 +- OgreMain/src/OgreScriptTranslator.cpp | 68 +- OgreMain/src/OgreSerializer.cpp | 304 +- OgreMain/src/OgreShadowCameraSetup.cpp | 330 +- OgreMain/src/OgreShadowCameraSetupFocused.cpp | 1272 +- OgreMain/src/OgreShadowCameraSetupLiSPSM.cpp | 566 +- OgreMain/src/OgreShadowCameraSetupPSSM.cpp | 200 +- .../src/OgreShadowCameraSetupPlaneOptimal.cpp | 664 +- OgreMain/src/OgreShadowCaster.cpp | 910 +- OgreMain/src/OgreShadowTextureManager.cpp | 336 +- .../src/OgreShadowVolumeExtrudeProgram.cpp | 850 +- OgreMain/src/OgreSimpleRenderable.cpp | 50 +- OgreMain/src/OgreSkeleton.cpp | 418 +- OgreMain/src/OgreSkeletonInstance.cpp | 104 +- OgreMain/src/OgreSkeletonSerializer.cpp | 428 +- OgreMain/src/OgreStaticGeometry.cpp | 3316 ++-- OgreMain/src/OgreStreamSerialiser.cpp | 1556 +- OgreMain/src/OgreString.cpp | 398 +- OgreMain/src/OgreStringInterface.cpp | 28 +- OgreMain/src/OgreSubEntity.cpp | 462 +- OgreMain/src/OgreSubMesh.cpp | 192 +- OgreMain/src/OgreTagPoint.cpp | 2 +- OgreMain/src/OgreTangentSpaceCalc.cpp | 1482 +- OgreMain/src/OgreTechnique.cpp | 1644 +- OgreMain/src/OgreTexture.cpp | 368 +- OgreMain/src/OgreTextureManager.cpp | 76 +- OgreMain/src/OgreTextureUnitState.cpp | 1034 +- OgreMain/src/OgreUTFString.cpp | 3854 ++--- .../src/OgreUnifiedHighLevelGpuProgram.cpp | 732 +- OgreMain/src/OgreUserObjectBindings.cpp | 190 +- OgreMain/src/OgreVertexIndexData.cpp | 1026 +- OgreMain/src/OgreViewport.cpp | 284 +- OgreMain/src/OgreWindowEventUtilities.cpp | 508 +- OgreMain/src/OgreWireBoundingBox.cpp | 134 +- OgreMain/src/OgreWorkQueue.cpp | 1302 +- OgreMain/src/OgreZip.cpp | 272 +- .../OgreDefaultWorkQueueStandard.cpp | 250 +- .../src/Threading/OgreDefaultWorkQueueTBB.cpp | 236 +- OgreMain/src/WIN32/OgreConfigDialog.cpp | 6 +- OgreMain/src/WIN32/OgreConfigDialogWinRT.cpp | 34 +- OgreMain/src/WIN32/OgreErrorDialog.cpp | 2 +- OgreMain/src/WIN32/OgreErrorDialogWinRT.cpp | 2 +- OgreMain/src/WIN32/OgreFileSystemLayer.cpp | 220 +- OgreMain/src/WIN32/OgreMinGWSupport.cpp | 32 +- .../WIN32/OgreOptimisedUtilDirectXMath.cpp | 84 +- OgreMain/src/WIN32/OgreTimer.cpp | 148 +- OgreMain/src/gtk/OgreConfigDialog.cpp | 10 +- OgreMain/src/gtk/OgreFileSystemLayer.cpp | 236 +- OgreMain/src/iOS/OgreConfigDialog.cpp | 54 +- OgreMain/src/iOS/OgreTimer.cpp | 26 +- OgreMain/src/nedmalloc/malloc.c.h | 6 +- OgreMain/src/nedmalloc/nedmalloc.c | 1244 +- .../BSPSceneManager/include/OgreBspLevel.h | 40 +- PlugIns/BSPSceneManager/include/OgreBspNode.h | 8 +- .../include/OgreBspPrerequisites.h | 12 +- .../include/OgreBspSceneManager.h | 62 +- .../include/OgreBspSceneManagerPlugin.h | 38 +- .../include/OgreBspSceneNode.h | 6 +- .../BSPSceneManager/include/OgreQuake3Level.h | 2 +- .../include/OgreQuake3Shader.h | 4 +- .../include/OgreQuake3ShaderManager.h | 2 +- .../BSPSceneManager/include/OgreQuake3Types.h | 10 +- PlugIns/BSPSceneManager/src/OgreBspLevel.cpp | 118 +- .../src/OgreBspResourceManager.cpp | 10 +- .../src/OgreBspSceneManager.cpp | 270 +- .../src/OgreBspSceneManagerDll.cpp | 2 +- .../src/OgreBspSceneManagerPlugin.cpp | 80 +- .../BSPSceneManager/src/OgreBspSceneNode.cpp | 104 +- .../BSPSceneManager/src/OgreQuake3Level.cpp | 18 +- .../BSPSceneManager/src/OgreQuake3Shader.cpp | 36 +- .../src/OgreQuake3ShaderManager.cpp | 6 +- .../include/OgreCgFxScriptLoader.h | 2094 +-- .../CgProgramManager/include/OgreCgPlugin.h | 36 +- .../include/OgreCgPrerequisites.h | 12 +- .../CgProgramManager/include/OgreCgProgram.h | 28 +- .../include/OgreCgProgramFactory.h | 8 +- .../src/OgreCgFxScriptLoader.cpp | 8464 +++++------ PlugIns/CgProgramManager/src/OgreCgPlugin.cpp | 62 +- .../CgProgramManager/src/OgreCgProgram.cpp | 1286 +- .../src/OgreCgProgramFactory.cpp | 2 +- .../src/OgreCgProgramManagerDll.cpp | 4 +- PlugIns/EXRCodec/src/OgreEXRCodec.cpp | 92 +- .../OctreeSceneManager/include/OgreOctree.h | 2 +- .../include/OgreOctreeNode.h | 6 +- .../include/OgreOctreePlugin.h | 36 +- .../include/OgreOctreePrerequisites.h | 2 +- .../include/OgreOctreeSceneManager.h | 26 +- PlugIns/OctreeSceneManager/src/OgreOctree.cpp | 6 +- .../src/OgreOctreeCamera.cpp | 2 +- .../OctreeSceneManager/src/OgreOctreeNode.cpp | 56 +- .../src/OgreOctreePlugin.cpp | 72 +- .../src/OgreOctreeSceneManager.cpp | 480 +- .../src/OgreOctreeSceneManagerDll.cpp | 4 +- .../src/OgreOctreeSceneQuery.cpp | 260 +- PlugIns/OctreeZone/include/OgreOctreeZone.h | 304 +- .../OctreeZone/include/OgreOctreeZoneOctree.h | 12 +- .../OctreeZone/include/OgreOctreeZonePlugin.h | 38 +- .../include/OgreOctreeZonePrerequisites.h | 2 +- PlugIns/OctreeZone/src/OgreOctreeZone.cpp | 2346 +-- PlugIns/OctreeZone/src/OgreOctreeZoneDll.cpp | 4 +- .../OctreeZone/src/OgreOctreeZoneOctree.cpp | 424 +- .../OctreeZone/src/OgreOctreeZonePlugin.cpp | 78 +- .../PCZSceneManager/include/OgreAntiPortal.h | 52 +- PlugIns/PCZSceneManager/include/OgreCapsule.h | 38 +- .../PCZSceneManager/include/OgreDefaultZone.h | 126 +- PlugIns/PCZSceneManager/include/OgrePCPlane.h | 10 +- .../PCZSceneManager/include/OgrePCZCamera.h | 46 +- .../PCZSceneManager/include/OgrePCZFrustum.h | 82 +- .../PCZSceneManager/include/OgrePCZLight.h | 50 +- .../PCZSceneManager/include/OgrePCZPlugin.h | 46 +- .../include/OgrePCZPrerequisites.h | 2 +- .../include/OgrePCZSceneManager.h | 304 +- .../include/OgrePCZSceneNode.h | 110 +- .../include/OgrePCZSceneQuery.h | 30 +- PlugIns/PCZSceneManager/include/OgrePCZone.h | 340 +- .../include/OgrePCZoneFactory.h | 84 +- PlugIns/PCZSceneManager/include/OgrePortal.h | 110 +- .../PCZSceneManager/include/OgrePortalBase.h | 512 +- PlugIns/PCZSceneManager/include/OgreSegment.h | 58 +- .../PCZSceneManager/src/OgreAntiPortal.cpp | 8 +- PlugIns/PCZSceneManager/src/OgreCapsule.cpp | 26 +- .../PCZSceneManager/src/OgreDefaultZone.cpp | 1808 +-- PlugIns/PCZSceneManager/src/OgrePCPlane.cpp | 24 +- PlugIns/PCZSceneManager/src/OgrePCZCamera.cpp | 234 +- .../PCZSceneManager/src/OgrePCZFrustum.cpp | 754 +- PlugIns/PCZSceneManager/src/OgrePCZLight.cpp | 116 +- PlugIns/PCZSceneManager/src/OgrePCZPlugin.cpp | 116 +- .../src/OgrePCZSceneManager.cpp | 2294 +-- .../src/OgrePCZSceneManagerDll.cpp | 4 +- .../PCZSceneManager/src/OgrePCZSceneNode.cpp | 440 +- .../PCZSceneManager/src/OgrePCZSceneQuery.cpp | 258 +- PlugIns/PCZSceneManager/src/OgrePCZone.cpp | 304 +- .../PCZSceneManager/src/OgrePCZoneFactory.cpp | 172 +- PlugIns/PCZSceneManager/src/OgrePortal.cpp | 16 +- .../PCZSceneManager/src/OgrePortalBase.cpp | 1614 +- PlugIns/PCZSceneManager/src/OgreSegment.cpp | 34 +- .../include/OgreColourFaderAffector2.h | 28 +- .../include/OgreColourImageAffector.h | 16 +- .../include/OgreColourInterpolatorAffector.h | 36 +- .../include/OgreDirectionRandomiserAffector.h | 24 +- .../ParticleFX/include/OgreParticleFXPlugin.h | 38 +- .../include/OgreParticleFXPrerequisites.h | 6 +- .../ParticleFX/include/OgreRotationAffector.h | 22 +- .../ParticleFX/include/OgreScaleAffector.h | 2 +- .../src/OgreColourFaderAffector2.cpp | 72 +- .../src/OgreColourImageAffector.cpp | 74 +- .../src/OgreColourInterpolatorAffector.cpp | 116 +- .../src/OgreDeflectorPlaneAffector.cpp | 6 +- .../src/OgreHollowEllipsoidEmitter.cpp | 2 +- PlugIns/ParticleFX/src/OgreParticleFX.cpp | 10 +- .../ParticleFX/src/OgreParticleFXPlugin.cpp | 250 +- .../ParticleFX/src/OgreRotationAffector.cpp | 62 +- PlugIns/ParticleFX/src/OgreScaleAffector.cpp | 26 +- .../Direct3D11/include/OgreD3D11DepthBuffer.h | 42 +- .../Direct3D11/include/OgreD3D11Device.h | 166 +- .../Direct3D11/include/OgreD3D11Driver.h | 62 +- .../Direct3D11/include/OgreD3D11DriverList.h | 24 +- .../Direct3D11/include/OgreD3D11GpuProgram.h | 216 +- .../include/OgreD3D11GpuProgramManager.h | 32 +- .../Direct3D11/include/OgreD3D11HLSLProgram.h | 586 +- .../include/OgreD3D11HLSLProgramFactory.h | 34 +- .../include/OgreD3D11HardwareBuffer.h | 88 +- .../include/OgreD3D11HardwareBufferManager.h | 116 +- .../include/OgreD3D11HardwareIndexBuffer.h | 54 +- .../include/OgreD3D11HardwareOcclusionQuery.h | 98 +- .../include/OgreD3D11HardwarePixelBuffer.h | 118 +- .../include/OgreD3D11HardwareUniformBuffer.h | 56 +- .../include/OgreD3D11HardwareVertexBuffer.h | 58 +- .../Direct3D11/include/OgreD3D11Mappings.h | 154 +- .../include/OgreD3D11MultiRenderTarget.h | 36 +- .../Direct3D11/include/OgreD3D11Plugin.h | 36 +- .../include/OgreD3D11Prerequisites.h | 108 +- .../include/OgreD3D11RenderSystem.h | 598 +- .../include/OgreD3D11RenderToVertexBuffer.h | 62 +- .../include/OgreD3D11RenderWindow.h | 302 +- .../Direct3D11/include/OgreD3D11Texture.h | 326 +- .../include/OgreD3D11TextureManager.h | 54 +- .../include/OgreD3D11VertexDeclaration.h | 68 +- .../Direct3D11/include/OgreD3D11VideoMode.h | 50 +- .../include/OgreD3D11VideoModeList.h | 26 +- .../Direct3D11/src/OgreD3D11DepthBuffer.cpp | 166 +- .../Direct3D11/src/OgreD3D11Device.cpp | 298 +- .../Direct3D11/src/OgreD3D11Driver.cpp | 214 +- .../Direct3D11/src/OgreD3D11DriverList.cpp | 146 +- .../Direct3D11/src/OgreD3D11EngineDll.cpp | 22 +- .../Direct3D11/src/OgreD3D11GpuProgram.cpp | 578 +- .../src/OgreD3D11GpuProgramManager.cpp | 164 +- .../Direct3D11/src/OgreD3D11HLSLProgram.cpp | 1882 +-- .../src/OgreD3D11HLSLProgramFactory.cpp | 56 +- .../src/OgreD3D11HardwareBuffer.cpp | 532 +- .../src/OgreD3D11HardwareBufferManager.cpp | 410 +- .../src/OgreD3D11HardwareIndexBuffer.cpp | 186 +- .../src/OgreD3D11HardwareOcclusionQuery.cpp | 116 +- .../src/OgreD3D11HardwarePixelBuffer.cpp | 1686 +-- .../src/OgreD3D11HardwareUniformBuffer.cpp | 148 +- .../src/OgreD3D11HardwareVertexBuffer.cpp | 208 +- .../Direct3D11/src/OgreD3D11Mappings.cpp | 1822 +-- .../src/OgreD3D11MultiRenderTarget.cpp | 272 +- .../Direct3D11/src/OgreD3D11Plugin.cpp | 70 +- .../Direct3D11/src/OgreD3D11RenderSystem.cpp | 6558 ++++---- .../src/OgreD3D11RenderToVertexBuffer.cpp | 262 +- .../Direct3D11/src/OgreD3D11RenderWindow.cpp | 2182 +-- .../Direct3D11/src/OgreD3D11Texture.cpp | 2030 +-- .../src/OgreD3D11TextureManager.cpp | 142 +- .../src/OgreD3D11VertexDeclaration.cpp | 318 +- .../Direct3D11/src/OgreD3D11VideoMode.cpp | 182 +- .../Direct3D11/src/OgreD3D11VideoModeList.cpp | 388 +- .../Direct3D9/include/OgreD3D9DepthBuffer.h | 44 +- .../Direct3D9/include/OgreD3D9Device.h | 242 +- .../Direct3D9/include/OgreD3D9DeviceManager.h | 70 +- .../Direct3D9/include/OgreD3D9Driver.h | 76 +- .../Direct3D9/include/OgreD3D9DriverList.h | 30 +- .../Direct3D9/include/OgreD3D9GpuProgram.h | 92 +- .../include/OgreD3D9GpuProgramManager.h | 2 +- .../Direct3D9/include/OgreD3D9HLSLProgram.h | 150 +- .../include/OgreD3D9HLSLProgramFactory.h | 8 +- .../include/OgreD3D9HardwareBufferManager.h | 44 +- .../include/OgreD3D9HardwareIndexBuffer.h | 120 +- .../include/OgreD3D9HardwareOcclusionQuery.h | 140 +- .../include/OgreD3D9HardwarePixelBuffer.h | 228 +- .../include/OgreD3D9HardwareVertexBuffer.h | 108 +- .../Direct3D9/include/OgreD3D9Mappings.h | 142 +- .../include/OgreD3D9MultiRenderTarget.h | 28 +- .../Direct3D9/include/OgreD3D9Plugin.h | 36 +- .../Direct3D9/include/OgreD3D9Prerequisites.h | 56 +- .../Direct3D9/include/OgreD3D9RenderSystem.h | 582 +- .../Direct3D9/include/OgreD3D9RenderWindow.h | 212 +- .../Direct3D9/include/OgreD3D9Resource.h | 60 +- .../include/OgreD3D9ResourceManager.h | 174 +- .../Direct3D9/include/OgreD3D9Texture.h | 326 +- .../include/OgreD3D9TextureManager.h | 20 +- .../include/OgreD3D9VertexDeclaration.h | 34 +- .../Direct3D9/include/OgreD3D9VideoMode.h | 52 +- .../Direct3D9/include/OgreD3D9VideoModeList.h | 26 +- .../Direct3D9/src/OgreD3D9DepthBuffer.cpp | 146 +- .../Direct3D9/src/OgreD3D9Device.cpp | 3068 ++-- .../Direct3D9/src/OgreD3D9DeviceManager.cpp | 938 +- .../Direct3D9/src/OgreD3D9Driver.cpp | 104 +- .../Direct3D9/src/OgreD3D9DriverList.cpp | 114 +- .../Direct3D9/src/OgreD3D9EngineDll.cpp | 26 +- .../Direct3D9/src/OgreD3D9GpuProgram.cpp | 722 +- .../Direct3D9/src/OgreD3D9HLSLProgram.cpp | 1010 +- .../src/OgreD3D9HLSLProgramFactory.cpp | 2 +- .../src/OgreD3D9HardwareBufferManager.cpp | 106 +- .../src/OgreD3D9HardwareIndexBuffer.cpp | 736 +- .../src/OgreD3D9HardwareOcclusionQuery.cpp | 320 +- .../src/OgreD3D9HardwarePixelBuffer.cpp | 1610 +- .../src/OgreD3D9HardwareVertexBuffer.cpp | 746 +- .../Direct3D9/src/OgreD3D9Mappings.cpp | 1132 +- .../src/OgreD3D9MultiRenderTarget.cpp | 210 +- .../Direct3D9/src/OgreD3D9Plugin.cpp | 92 +- .../Direct3D9/src/OgreD3D9RenderSystem.cpp | 8664 +++++------ .../Direct3D9/src/OgreD3D9RenderWindow.cpp | 1830 +-- .../Direct3D9/src/OgreD3D9Resource.cpp | 36 +- .../Direct3D9/src/OgreD3D9ResourceManager.cpp | 214 +- .../Direct3D9/src/OgreD3D9Texture.cpp | 3908 ++--- .../Direct3D9/src/OgreD3D9TextureManager.cpp | 94 +- .../src/OgreD3D9VertexDeclaration.cpp | 190 +- .../Direct3D9/src/OgreD3D9VideoMode.cpp | 46 +- .../Direct3D9/src/OgreD3D9VideoModeList.cpp | 224 +- RenderSystems/GL/include/GL/glext.h | 4 +- RenderSystems/GL/include/GL/glxext.h | 16 +- RenderSystems/GL/include/GL/glxtokens.h | 216 +- RenderSystems/GL/include/GLX/OgreGLXContext.h | 50 +- .../GL/include/GLX/OgreGLXGLSupport.h | 372 +- .../GL/include/GLX/OgreGLXRenderTexture.h | 24 +- RenderSystems/GL/include/GLX/OgreGLXUtils.h | 124 +- RenderSystems/GL/include/GLX/OgreGLXWindow.h | 170 +- .../GL/include/OSX/OgreOSXCGLContext.h | 30 +- .../GL/include/OSX/OgreOSXCarbonContext.h | 28 +- .../GL/include/OSX/OgreOSXCarbonWindow.h | 64 +- .../GL/include/OSX/OgreOSXCocoaContext.h | 40 +- .../GL/include/OSX/OgreOSXCocoaView.h | 2 +- .../GL/include/OSX/OgreOSXCocoaWindow.h | 32 +- .../include/OSX/OgreOSXCocoaWindowDelegate.h | 2 +- RenderSystems/GL/include/OSX/OgreOSXContext.h | 36 +- .../GL/include/OSX/OgreOSXGLSupport.h | 98 +- .../GL/include/OSX/OgreOSXRenderTexture.h | 10 +- RenderSystems/GL/include/OSX/OgreOSXWindow.h | 42 +- RenderSystems/GL/include/OgreGLATIFSInit.h | 8 +- RenderSystems/GL/include/OgreGLContext.h | 18 +- .../OgreGLDefaultHardwareBufferManager.h | 92 +- RenderSystems/GL/include/OgreGLDepthBuffer.h | 60 +- .../GL/include/OgreGLFBOMultiRenderTarget.h | 42 +- .../GL/include/OgreGLFBORenderTexture.h | 38 +- .../GL/include/OgreGLFrameBufferObject.h | 42 +- .../GL/include/OgreGLGpuNvparseProgram.h | 2 +- RenderSystems/GL/include/OgreGLGpuProgram.h | 38 +- .../GL/include/OgreGLHardwareBufferManager.h | 156 +- .../GL/include/OgreGLHardwareIndexBuffer.h | 12 +- .../GL/include/OgreGLHardwareOcclusionQuery.h | 36 +- .../GL/include/OgreGLHardwarePixelBuffer.h | 80 +- .../GL/include/OgreGLHardwareVertexBuffer.h | 12 +- .../GL/include/OgreGLPBRenderTexture.h | 10 +- RenderSystems/GL/include/OgreGLPixelFormat.h | 114 +- RenderSystems/GL/include/OgreGLPlugin.h | 36 +- .../GL/include/OgreGLPrerequisites.h | 28 +- RenderSystems/GL/include/OgreGLRenderSystem.h | 130 +- .../GL/include/OgreGLRenderTexture.h | 22 +- .../GL/include/OgreGLRenderToVertexBuffer.h | 24 +- .../GL/include/OgreGLStateCacheManager.h | 16 +- RenderSystems/GL/include/OgreGLSupport.h | 26 +- RenderSystems/GL/include/OgreGLTexture.h | 34 +- .../GL/include/OgreGLTextureManager.h | 14 +- RenderSystems/GL/include/OgreGLUniformCache.h | 6 +- RenderSystems/GL/include/OgreSDLGLSupport.h | 6 +- .../GL/include/OgreSDLPrerequisites.h | 4 +- RenderSystems/GL/include/OgreSDLWindow.h | 4 +- .../GL/include/Win32/OgreWin32Context.h | 16 +- .../GL/include/Win32/OgreWin32GLSupport.h | 140 +- .../GL/include/Win32/OgreWin32Prerequisites.h | 4 +- .../GL/include/Win32/OgreWin32RenderTexture.h | 18 +- .../GL/include/Win32/OgreWin32Window.h | 82 +- RenderSystems/GL/include/gtk/OgreGTKWindow.h | 14 +- .../GL/src/GLSL/include/OgreGLSLExtSupport.h | 28 +- .../GL/src/GLSL/include/OgreGLSLGpuProgram.h | 80 +- .../GL/src/GLSL/include/OgreGLSLLinkProgram.h | 180 +- .../GLSL/include/OgreGLSLLinkProgramManager.h | 198 +- .../GL/src/GLSL/include/OgreGLSLProgram.h | 234 +- .../src/GLSL/include/OgreGLSLProgramFactory.h | 14 +- .../GL/src/GLSL/src/OgreGLSLExtSupport.cpp | 78 +- .../GL/src/GLSL/src/OgreGLSLGpuProgram.cpp | 250 +- .../GL/src/GLSL/src/OgreGLSLLinkProgram.cpp | 950 +- .../GLSL/src/OgreGLSLLinkProgramManager.cpp | 958 +- .../GL/src/GLSL/src/OgreGLSLPreprocessor.cpp | 4 +- .../GL/src/GLSL/src/OgreGLSLProgram.cpp | 734 +- .../src/GLSL/src/OgreGLSLProgramFactory.cpp | 10 +- RenderSystems/GL/src/GLX/OgreGLXContext.cpp | 98 +- RenderSystems/GL/src/GLX/OgreGLXGLSupport.cpp | 1904 +-- .../GL/src/GLX/OgreGLXRenderTexture.cpp | 246 +- RenderSystems/GL/src/GLX/OgreGLXWindow.cpp | 1436 +- .../GL/src/OSX/OgreOSXCGLContext.cpp | 48 +- .../GL/src/OSX/OgreOSXCarbonContext.cpp | 52 +- .../GL/src/OSX/OgreOSXCarbonWindow.cpp | 22 +- RenderSystems/GL/src/OSX/OgreOSXContext.cpp | 28 +- .../GL/src/OSX/OgreOSXRenderTexture.cpp | 78 +- RenderSystems/GL/src/OSX/OgreOSXWindow.cpp | 4 +- RenderSystems/GL/src/OgreGLATIFSInit.cpp | 80 +- RenderSystems/GL/src/OgreGLContext.cpp | 22 +- .../OgreGLDefaultHardwareBufferManager.cpp | 242 +- RenderSystems/GL/src/OgreGLDepthBuffer.cpp | 186 +- .../GL/src/OgreGLFBOMultiRenderTarget.cpp | 96 +- .../GL/src/OgreGLFBORenderTexture.cpp | 172 +- .../GL/src/OgreGLFrameBufferObject.cpp | 290 +- .../GL/src/OgreGLGpuNvparseProgram.cpp | 24 +- RenderSystems/GL/src/OgreGLGpuProgram.cpp | 192 +- .../GL/src/OgreGLGpuProgramManager.cpp | 8 +- .../GL/src/OgreGLHardwareBufferManager.cpp | 312 +- .../GL/src/OgreGLHardwareIndexBuffer.cpp | 182 +- .../GL/src/OgreGLHardwareOcclusionQuery.cpp | 104 +- .../GL/src/OgreGLHardwarePixelBuffer.cpp | 788 +- .../GL/src/OgreGLHardwareVertexBuffer.cpp | 160 +- .../GL/src/OgreGLPBRenderTexture.cpp | 30 +- RenderSystems/GL/src/OgreGLPixelFormat.cpp | 378 +- RenderSystems/GL/src/OgreGLRenderSystem.cpp | 630 +- RenderSystems/GL/src/OgreGLRenderTexture.cpp | 20 +- .../GL/src/OgreGLRenderToVertexBuffer.cpp | 554 +- .../GL/src/OgreGLStateCacheManager.cpp | 4 +- RenderSystems/GL/src/OgreGLSupport.cpp | 20 +- RenderSystems/GL/src/OgreGLTexture.cpp | 402 +- RenderSystems/GL/src/OgreGLTextureManager.cpp | 104 +- RenderSystems/GL/src/SDL/OgreSDLGLSupport.cpp | 62 +- RenderSystems/GL/src/SDL/OgreSDLWindow.cpp | 152 +- .../OgreGLNullStateCacheManagerImp.cpp | 22 +- .../OgreGLNullStateCacheManagerImp.h | 2 +- .../OgreGLStateCacheManagerImp.cpp | 88 +- .../OgreGLStateCacheManagerImp.h | 4 +- .../OgreGLUniformCacheImp.cpp | 2 +- .../StateCacheManager/OgreGLUniformCacheImp.h | 2 +- .../GL/src/Win32/OgreWin32Context.cpp | 128 +- .../GL/src/Win32/OgreWin32GLSupport.cpp | 1186 +- .../GL/src/Win32/OgreWin32RenderTexture.cpp | 256 +- .../GL/src/Win32/OgreWin32Window.cpp | 1680 +-- .../src/atifs/include/ATI_FS_GLGpuProgram.h | 40 +- .../GL/src/atifs/include/Compiler2Pass.h | 340 +- RenderSystems/GL/src/atifs/include/ps_1_4.h | 502 +- .../GL/src/atifs/src/ATI_FS_GLGpuProgram.cpp | 100 +- .../GL/src/atifs/src/Compiler2Pass.cpp | 530 +- RenderSystems/GL/src/atifs/src/ps_1_4.cpp | 2880 ++-- RenderSystems/GL/src/glew.cpp | 14 +- RenderSystems/GL/src/gtk/OgreGTKGLSupport.cpp | 62 +- RenderSystems/GL/src/gtk/OgreGTKWindow.cpp | 260 +- RenderSystems/GL/src/nvparse/_ps1.0_lexer.cpp | 1606 +- .../GL/src/nvparse/_ps1.0_parser.cpp | 580 +- RenderSystems/GL/src/nvparse/_ps1.0_parser.h | 16 +- RenderSystems/GL/src/nvparse/_rc1.0_lexer.cpp | 2132 +-- .../GL/src/nvparse/_rc1.0_parser.cpp | 1100 +- RenderSystems/GL/src/nvparse/_ts1.0_lexer.cpp | 1708 +-- .../GL/src/nvparse/_ts1.0_parser.cpp | 578 +- RenderSystems/GL/src/nvparse/_vs1.0_lexer.cpp | 6228 ++++---- .../GL/src/nvparse/_vs1.0_parser.cpp | 754 +- RenderSystems/GL/src/nvparse/avp1.0_impl.cpp | 208 +- RenderSystems/GL/src/nvparse/macro.h | 42 +- RenderSystems/GL/src/nvparse/nvparse.cpp | 2 +- .../GL/src/nvparse/nvparse_errors.cpp | 30 +- RenderSystems/GL/src/nvparse/nvparse_errors.h | 14 +- .../GL/src/nvparse/ps1.0__test_main.cpp | 102 +- .../GL/src/nvparse/ps1.0_program.cpp | 1714 +-- RenderSystems/GL/src/nvparse/ps1.0_program.h | 24 +- .../GL/src/nvparse/rc1.0_combiners.cpp | 70 +- .../GL/src/nvparse/rc1.0_combiners.h | 24 +- RenderSystems/GL/src/nvparse/rc1.0_final.cpp | 270 +- RenderSystems/GL/src/nvparse/rc1.0_final.h | 50 +- .../GL/src/nvparse/rc1.0_general.cpp | 436 +- RenderSystems/GL/src/nvparse/rc1.0_general.h | 132 +- RenderSystems/GL/src/nvparse/rc1.0_register.h | 210 +- RenderSystems/GL/src/nvparse/ts1.0_inst.cpp | 544 +- RenderSystems/GL/src/nvparse/ts1.0_inst.h | 118 +- .../GL/src/nvparse/ts1.0_inst_list.cpp | 118 +- .../GL/src/nvparse/ts1.0_inst_list.h | 12 +- RenderSystems/GL/src/nvparse/vcp1.0_impl.cpp | 422 +- RenderSystems/GL/src/nvparse/vp1.0_impl.cpp | 226 +- RenderSystems/GL/src/nvparse/vs1.0_inst.cpp | 20 +- RenderSystems/GL/src/nvparse/vs1.0_inst.h | 28 +- .../GL/src/nvparse/vs1.0_inst_list.cpp | 256 +- .../GL/src/nvparse/vs1.0_inst_list.h | 20 +- RenderSystems/GL/src/nvparse/vsp1.0_impl.cpp | 244 +- RenderSystems/GL3Plus/include/GL/gl3w.h | 1208 +- RenderSystems/GL3Plus/include/GL/glext.h | 6 +- RenderSystems/GL3Plus/include/GL/glxext.h | 16 +- .../GL3Plus/include/GL/glxtokens-backup.h | 216 +- .../GL3Plus/include/OgreGL3PlusContext.h | 8 +- .../GL3Plus/include/OgreGL3PlusDepthBuffer.h | 60 +- .../include/OgreGL3PlusFBOMultiRenderTarget.h | 42 +- .../include/OgreGL3PlusFBORenderTexture.h | 2 +- .../include/OgreGL3PlusFrameBufferObject.h | 38 +- .../OgreGL3PlusHardwareOcclusionQuery.h | 36 +- .../GL3Plus/include/OgreGL3PlusPlugin.h | 36 +- .../include/OgreGL3PlusPrerequisites.h | 12 +- .../GL3Plus/include/OgreGL3PlusRenderSystem.h | 12 +- .../include/windowing/GLX/OgreGLXContext.h | 50 +- .../include/windowing/GLX/OgreGLXUtils.h | 100 +- .../include/windowing/GLX/OgreGLXWindow.h | 170 +- .../windowing/OSX/OgreOSXCocoaContext.h | 30 +- .../include/windowing/OSX/OgreOSXCocoaView.h | 2 +- .../windowing/OSX/OgreOSXCocoaWindow.h | 32 +- .../OSX/OgreOSXCocoaWindowDelegate.h | 2 +- .../windowing/OSX/OgreOSXGL3PlusSupport.h | 90 +- .../include/windowing/SDL/OgreSDLGLSupport.h | 6 +- .../windowing/SDL/OgreSDLPrerequisites.h | 4 +- .../include/windowing/SDL/OgreSDLWindow.h | 4 +- .../include/windowing/gtk/OgreGTKWindow.h | 14 +- .../windowing/win32/OgreWin32Context.h | 12 +- .../windowing/win32/OgreWin32GLSupport.h | 146 +- .../windowing/win32/OgreWin32Prerequisites.h | 4 +- .../include/windowing/win32/OgreWin32Window.h | 82 +- .../GL3Plus/src/OgreGL3PlusDepthBuffer.cpp | 2 +- .../src/OgreGL3PlusFrameBufferObject.cpp | 218 +- .../GL3Plus/src/OgreGL3PlusRenderSystem.cpp | 50 +- RenderSystems/GL3Plus/src/gl3w.cpp | 1298 +- .../src/windowing/SDL/OgreSDLGLSupport.cpp | 62 +- .../src/windowing/gtk/OgreGTKGLSupport.cpp | 62 +- .../src/windowing/gtk/OgreGTKWindow.cpp | 244 +- .../src/windowing/win32/OgreWin32Context.cpp | 84 +- .../windowing/win32/OgreWin32GLSupport.cpp | 1174 +- .../src/windowing/win32/OgreWin32Window.cpp | 1674 +- .../GLES/include/EAGL/OgreEAGLSupport.h | 18 +- .../GLES/include/EAGL/OgreEAGLWindow.h | 18 +- .../EGL/Android/OgreAndroidEGLSupport.h | 2 +- .../EGL/Android/OgreAndroidEGLWindow.h | 36 +- .../include/EGL/Android/OgreAndroidResource.h | 40 +- .../EGL/Android/OgreAndroidResourceManager.h | 60 +- .../GLES/include/EGL/OgreEGLContext.h | 2 +- .../GLES/include/EGL/OgreEGLRenderTexture.h | 6 +- .../GLES/include/EGL/OgreEGLSupport.h | 32 +- .../GLES/include/EGL/OgreEGLWindow.h | 34 +- .../EGL/WIN32/OgreWin32EGLRenderTexture.h | 4 +- .../include/EGL/WIN32/OgreWin32EGLSupport.h | 24 +- .../include/EGL/WIN32/OgreWin32EGLWindow.h | 22 +- .../include/EGL/X11/OgreX11EGLRenderTexture.h | 2 +- .../GLES/include/EGL/X11/OgreX11EGLSupport.h | 238 +- .../GLES/include/EGL/X11/OgreX11EGLWindow.h | 52 +- .../OgreGLESDefaultHardwareBufferManager.h | 32 +- .../GLES/include/OgreGLESDepthBuffer.h | 60 +- .../include/OgreGLESFBOMultiRenderTarget.h | 42 +- .../GLES/include/OgreGLESFBORenderTexture.h | 34 +- .../GLES/include/OgreGLESFrameBufferObject.h | 30 +- .../include/OgreGLESHardwareBufferManager.h | 110 +- .../GLES/include/OgreGLESPrerequisites.h | 56 +- .../GLES/include/OgreGLESRenderSystem.h | 30 +- .../GLES/include/OgreGLESStateCacheManager.h | 8 +- .../src/EGL/Android/OgreAndroidEGLSupport.cpp | 32 +- .../src/EGL/Android/OgreAndroidEGLWindow.cpp | 100 +- .../src/EGL/Android/OgreAndroidResource.cpp | 16 +- .../Android/OgreAndroidResourceManager.cpp | 72 +- RenderSystems/GLES/src/EGL/OgreEGLContext.cpp | 14 +- .../GLES/src/EGL/OgreEGLRenderTexture.cpp | 28 +- RenderSystems/GLES/src/EGL/OgreEGLSupport.cpp | 60 +- RenderSystems/GLES/src/EGL/OgreEGLWindow.cpp | 126 +- .../src/EGL/WIN32/OgreWin32EGLContext.cpp | 2 +- .../EGL/WIN32/OgreWin32EGLRenderTexture.cpp | 20 +- .../src/EGL/WIN32/OgreWin32EGLSupport.cpp | 246 +- .../GLES/src/EGL/WIN32/OgreWin32EGLWindow.cpp | 450 +- .../GLES/src/EGL/X11/OgreX11EGLContext.cpp | 2 +- .../src/EGL/X11/OgreX11EGLRenderTexture.cpp | 24 +- .../GLES/src/EGL/X11/OgreX11EGLSupport.cpp | 136 +- .../GLES/src/EGL/X11/OgreX11EGLWindow.cpp | 770 +- .../OgreGLESDefaultHardwareBufferManager.cpp | 18 +- .../GLES/src/OgreGLESDepthBuffer.cpp | 182 +- .../GLES/src/OgreGLESFBOMultiRenderTarget.cpp | 98 +- .../GLES/src/OgreGLESFBORenderTexture.cpp | 150 +- .../GLES/src/OgreGLESFrameBufferObject.cpp | 224 +- .../GLES/src/OgreGLESGpuProgramManager.cpp | 30 +- .../src/OgreGLESHardwareBufferManager.cpp | 38 +- .../GLES/src/OgreGLESHardwareIndexBuffer.cpp | 70 +- .../GLES/src/OgreGLESHardwarePixelBuffer.cpp | 12 +- .../GLES/src/OgreGLESHardwareVertexBuffer.cpp | 64 +- .../GLES/src/OgreGLESPixelFormat.cpp | 94 +- .../GLES/src/OgreGLESRenderSystem.cpp | 724 +- .../GLES/src/OgreGLESStateCacheManager.cpp | 4 +- RenderSystems/GLES/src/OgreGLESSupport.cpp | 64 +- RenderSystems/GLES/src/OgreGLESTexture.cpp | 54 +- .../GLES/src/OgreGLESTextureManager.cpp | 8 +- .../OgreGLESNullStateCacheManagerImp.cpp | 4 +- .../OgreGLESNullStateCacheManagerImp.h | 2 +- .../OgreGLESStateCacheManagerImp.cpp | 4 +- .../OgreGLESStateCacheManagerImp.h | 2 +- .../GLES2/include/EAGL/OgreEAGL2Support.h | 18 +- .../GLES2/include/EAGL/OgreEAGL2Window.h | 18 +- .../EGL/Android/OgreAndroidEGLSupport.h | 2 +- .../EGL/Android/OgreAndroidEGLWindow.h | 40 +- .../include/EGL/Android/OgreAndroidResource.h | 40 +- .../EGL/Android/OgreAndroidResourceManager.h | 60 +- .../GLES2/include/EGL/OgreEGLContext.h | 2 +- .../GLES2/include/EGL/OgreEGLRenderTexture.h | 6 +- .../GLES2/include/EGL/OgreEGLSupport.h | 34 +- .../GLES2/include/EGL/OgreEGLWindow.h | 34 +- .../EGL/WIN32/OgreWin32EGLRenderTexture.h | 4 +- .../include/EGL/WIN32/OgreWin32EGLSupport.h | 24 +- .../include/EGL/WIN32/OgreWin32EGLWindow.h | 22 +- .../include/EGL/X11/OgreX11EGLRenderTexture.h | 2 +- .../GLES2/include/EGL/X11/OgreX11EGLSupport.h | 234 +- .../GLES2/include/EGL/X11/OgreX11EGLWindow.h | 52 +- RenderSystems/GLES2/include/GLES2/gl2ext.h | 6 +- RenderSystems/GLES2/include/GLES2/gles2w.h | 606 +- RenderSystems/GLES2/include/GLES3/gles3w.h | 574 +- .../GLES2/include/NaCl/OgreNaClGLContext.h | 6 +- .../GLES2/include/NaCl/OgreNaClGLSupport.h | 28 +- .../GLES2/include/NaCl/OgreNaClWindow.h | 60 +- .../GLES2/include/OgreGLES2Context.h | 8 +- .../OgreGLES2DefaultHardwareBufferManager.h | 28 +- .../GLES2/include/OgreGLES2DepthBuffer.h | 60 +- .../include/OgreGLES2FBOMultiRenderTarget.h | 42 +- .../GLES2/include/OgreGLES2FBORenderTexture.h | 34 +- .../include/OgreGLES2FrameBufferObject.h | 30 +- .../GLES2/include/OgreGLES2GpuProgram.h | 14 +- .../include/OgreGLES2HardwareBufferManager.h | 48 +- .../include/OgreGLES2HardwareOcclusionQuery.h | 34 +- .../GLES2/include/OgreGLES2Prerequisites.h | 20 +- .../GLES2/include/OgreGLES2RenderSystem.h | 44 +- .../include/OgreGLES2RenderToVertexBuffer.h | 22 +- .../include/OgreGLES2StateCacheManager.h | 16 +- .../GLES2/include/OgreGLES2Support.h | 10 +- .../GLES2/include/OgreGLES2UniformCache.h | 6 +- .../include/OgreGLES2VertexDeclaration.h | 16 +- .../src/EGL/Android/OgreAndroidEGLSupport.cpp | 26 +- .../src/EGL/Android/OgreAndroidEGLWindow.cpp | 232 +- .../src/EGL/Android/OgreAndroidResource.cpp | 16 +- .../Android/OgreAndroidResourceManager.cpp | 72 +- .../GLES2/src/EGL/OgreEGLContext.cpp | 14 +- .../GLES2/src/EGL/OgreEGLRenderTexture.cpp | 30 +- .../GLES2/src/EGL/OgreEGLSupport.cpp | 14 +- RenderSystems/GLES2/src/EGL/OgreEGLWindow.cpp | 102 +- .../src/EGL/WIN32/OgreWin32EGLContext.cpp | 2 +- .../EGL/WIN32/OgreWin32EGLRenderTexture.cpp | 20 +- .../src/EGL/WIN32/OgreWin32EGLSupport.cpp | 262 +- .../src/EGL/WIN32/OgreWin32EGLWindow.cpp | 484 +- .../GLES2/src/EGL/X11/OgreX11EGLContext.cpp | 2 +- .../src/EGL/X11/OgreX11EGLRenderTexture.cpp | 20 +- .../GLES2/src/EGL/X11/OgreX11EGLSupport.cpp | 86 +- .../GLES2/src/EGL/X11/OgreX11EGLWindow.cpp | 766 +- .../src/GLSLES/include/OgreGLSLESCgProgram.h | 2 +- .../include/OgreGLSLESCgProgramFactory.h | 4 +- .../src/GLSLES/include/OgreGLSLESExtSupport.h | 26 +- .../src/GLSLES/include/OgreGLSLESGpuProgram.h | 68 +- .../GLSLES/include/OgreGLSLESLinkProgram.h | 56 +- .../include/OgreGLSLESLinkProgramManager.h | 106 +- .../GLSLES/include/OgreGLSLESPreprocessor.h | 2 +- .../src/GLSLES/include/OgreGLSLESProgram.h | 126 +- .../GLSLES/include/OgreGLSLESProgramCommon.h | 138 +- .../GLSLES/include/OgreGLSLESProgramFactory.h | 16 +- .../include/OgreGLSLESProgramManagerCommon.h | 108 +- .../include/OgreGLSLESProgramPipeline.h | 30 +- .../OgreGLSLESProgramPipelineManager.h | 30 +- .../src/GLSLES/src/OgreGLSLESCgProgram.cpp | 2 +- .../src/GLSLES/src/OgreGLSLESExtSupport.cpp | 64 +- .../src/GLSLES/src/OgreGLSLESGpuProgram.cpp | 106 +- .../src/GLSLES/src/OgreGLSLESLinkProgram.cpp | 394 +- .../src/OgreGLSLESLinkProgramManager.cpp | 164 +- .../src/GLSLES/src/OgreGLSLESPreprocessor.cpp | 2 +- .../src/GLSLES/src/OgreGLSLESProgram.cpp | 616 +- .../GLSLES/src/OgreGLSLESProgramCommon.cpp | 178 +- .../GLSLES/src/OgreGLSLESProgramFactory.cpp | 10 +- .../src/OgreGLSLESProgramManagerCommon.cpp | 492 +- .../GLSLES/src/OgreGLSLESProgramPipeline.cpp | 242 +- .../src/OgreGLSLESProgramPipelineManager.cpp | 128 +- .../GLES2/src/NaCl/OgreNaClGLContext.cpp | 6 +- .../GLES2/src/NaCl/OgreNaClGLSupport.cpp | 98 +- .../GLES2/src/NaCl/OgreNaClWindow.cpp | 178 +- .../OgreGLES2DefaultHardwareBufferManager.cpp | 22 +- .../GLES2/src/OgreGLES2DepthBuffer.cpp | 182 +- .../src/OgreGLES2FBOMultiRenderTarget.cpp | 96 +- .../GLES2/src/OgreGLES2FBORenderTexture.cpp | 134 +- .../GLES2/src/OgreGLES2FrameBufferObject.cpp | 236 +- .../GLES2/src/OgreGLES2GpuProgram.cpp | 18 +- .../src/OgreGLES2HardwareBufferManager.cpp | 26 +- .../src/OgreGLES2HardwareIndexBuffer.cpp | 26 +- .../src/OgreGLES2HardwareOcclusionQuery.cpp | 4 +- .../src/OgreGLES2HardwarePixelBuffer.cpp | 10 +- .../src/OgreGLES2HardwareUniformBuffer.cpp | 6 +- .../src/OgreGLES2HardwareVertexBuffer.cpp | 12 +- .../GLES2/src/OgreGLES2PixelFormat.cpp | 142 +- .../GLES2/src/OgreGLES2RenderSystem.cpp | 932 +- .../src/OgreGLES2RenderToVertexBuffer.cpp | 342 +- .../GLES2/src/OgreGLES2StateCacheManager.cpp | 4 +- RenderSystems/GLES2/src/OgreGLES2Texture.cpp | 94 +- .../GLES2/src/OgreGLES2TextureManager.cpp | 6 +- .../GLES2/src/OgreGLES2VertexDeclaration.cpp | 18 +- .../OgreGLES2NullStateCacheManagerImp.cpp | 6 +- .../OgreGLES2NullStateCacheManagerImp.h | 2 +- .../OgreGLES2StateCacheManagerImp.cpp | 72 +- .../OgreGLES2StateCacheManagerImp.h | 4 +- .../OgreGLES2UniformCacheImp.cpp | 2 +- .../OgreGLES2UniformCacheImp.h | 2 +- RenderSystems/GLES2/src/gles2w.cpp | 676 +- RenderSystems/GLES2/src/gles3w.cpp | 656 +- .../Ogre/Mac OS X/Classes/DemoApp.cpp | 106 +- .../Ogre/Mac OS X/Classes/DemoApp.h | 22 +- .../Ogre/Mac OS X/Classes/OgreFramework.cpp | 366 +- .../Ogre/Mac OS X/Classes/OgreFramework.h | 86 +- .../Ogre/Mac OS X/Classes/main.cpp | 12 +- .../Ogre/iPhone OS/Classes/DemoApp.cpp | 106 +- .../Ogre/iPhone OS/Classes/DemoApp.h | 22 +- .../Ogre/iPhone OS/Classes/OgreFramework.cpp | 346 +- .../Ogre/iPhone OS/Classes/OgreFramework.h | 86 +- .../Classes/OgreStaticPluginLoader.h | 128 +- .../Ogre/iPhone OS/Classes/main.cpp | 8 +- .../AppDelegate.h | 20 +- .../OgreDemoApp.cpp | 114 +- .../OgreDemoApp.h | 100 +- .../OgreFramework.cpp | 256 +- .../OgreFramework.h | 80 +- .../iOS Application.xctemplate/AppDelegate.h | 46 +- .../OgreDemoApp.cpp | 114 +- .../iOS Application.xctemplate/OgreDemoApp.h | 100 +- .../OgreFramework.cpp | 256 +- .../OgreFramework.h | 80 +- .../OgreStaticPluginLoader.h | 136 +- Samples/BSP/src/BSP.cpp | 14 +- Samples/BezierPatch/include/BezierPatch.h | 116 +- Samples/BezierPatch/src/BezierPatch.cpp | 14 +- Samples/Browser/WinRT.Xaml/App.xaml.cpp | 52 +- Samples/Browser/WinRT.Xaml/App.xaml.h | 24 +- .../WinRT.Xaml/SampleBrowserWinRT.xaml.cpp | 46 +- .../WinRT.Xaml/SampleBrowserWinRT.xaml.h | 52 +- Samples/Browser/WinRT.Xaml/pch.cpp | 2 +- Samples/Browser/WinRT.Xaml/pch.h | 2 +- Samples/Browser/include/InputManagerWinRT.h | 738 +- Samples/Browser/include/SampleBrowser.h | 76 +- .../Browser/include/SampleBrowser_Android.h | 2 +- Samples/Browser/include/SampleBrowser_NaCl.h | 50 +- Samples/Browser/include/SampleBrowser_OSX.h | 8 +- Samples/Browser/include/SampleBrowser_iOS.h | 2 +- Samples/Browser/src/SampleBrowser.cpp | 38 +- Samples/CameraTrack/include/CameraTrack.h | 44 +- Samples/CameraTrack/src/CameraTrack.cpp | 14 +- Samples/CelShading/include/CelShading.h | 98 +- Samples/CelShading/src/CelShading.cpp | 14 +- Samples/Character/include/CharacterSample.h | 212 +- .../include/SinbadCharacterController.h | 984 +- Samples/Character/src/CharacterSample.cpp | 14 +- Samples/Common/include/ExampleApplication.h | 310 +- Samples/Common/include/ExampleFrameListener.h | 834 +- Samples/Common/include/ExampleLoadingBar.h | 300 +- Samples/Common/include/InputContext.h | 122 +- .../Common/include/OgreStaticPluginLoader.h | 144 +- Samples/Common/include/Sample.h | 460 +- Samples/Common/include/SampleContext.h | 1072 +- Samples/Common/include/SamplePlugin.h | 70 +- Samples/Common/include/SdkCameraMan.h | 620 +- Samples/Common/include/SdkSample.h | 884 +- Samples/Common/include/SdkTrays.h | 6038 ++++---- Samples/Common/src/Cocoa/OgreController.h | 6 +- .../include/CompositorDemo_FrameListener.h | 30 +- .../include/ItemSelectorViewManager.h | 2 +- Samples/Compositor/src/Compositor.cpp | 14 +- .../src/CompositorDemo_FrameListener.cpp | 340 +- Samples/Compositor/src/HelperLogics.cpp | 346 +- Samples/CubeMapping/include/CubeMapping.h | 168 +- Samples/CubeMapping/src/CubeMapping.cpp | 14 +- .../DeferredShading/include/AmbientLight.h | 24 +- Samples/DeferredShading/include/DLight.h | 126 +- .../DeferredShading/include/DeferredLightCP.h | 56 +- .../DeferredShading/include/DeferredShading.h | 120 +- .../include/DeferredShadingDemo.h | 530 +- .../include/GBufferMaterialGenerator.h | 64 +- .../include/GBufferSchemeHandler.h | 62 +- Samples/DeferredShading/include/GeomUtils.h | 64 +- .../include/LightMaterialGenerator.h | 28 +- .../include/ListenerFactoryLogic.h | 36 +- .../include/MaterialGenerator.h | 96 +- .../include/NullSchemeHandler.h | 22 +- Samples/DeferredShading/include/SSAOLogic.h | 4 +- Samples/DeferredShading/include/SharedData.h | 56 +- Samples/DeferredShading/src/AmbientLight.cpp | 70 +- Samples/DeferredShading/src/DLight.cpp | 454 +- .../DeferredShading/src/DeferredLightCP.cpp | 154 +- .../DeferredShading/src/DeferredShading.cpp | 224 +- .../src/DeferredShadingDemo.cpp | 16 +- .../src/GBufferMaterialGenerator.cpp | 174 +- .../src/GBufferSchemeHandler.cpp | 320 +- Samples/DeferredShading/src/GeomUtils.cpp | 420 +- .../src/LightMaterialGenerator.cpp | 436 +- .../DeferredShading/src/MaterialGenerator.cpp | 126 +- Samples/DeferredShading/src/SSAOLogic.cpp | 12 +- Samples/Dot3Bump/include/Dot3Bump.h | 508 +- Samples/Dot3Bump/src/Dot3Bump.cpp | 14 +- Samples/DualQuaternion/src/DualQuaternion.cpp | 14 +- Samples/DynTex/include/DynTex.h | 330 +- Samples/DynTex/src/DynTex.cpp | 14 +- Samples/EndlessWorld/include/EndlessWorld.h | 806 +- .../include/PerlinNoiseTerrainGenerator.h | 84 +- Samples/EndlessWorld/src/EndlessWorld.cpp | 14 +- .../src/PerlinNoiseTerrainGenerator.cpp | 166 +- .../FacialAnimation/src/FacialAnimation.cpp | 14 +- Samples/Fresnel/include/Fresnel.h | 288 +- Samples/Fresnel/src/Fresnel.cpp | 14 +- Samples/Grass/src/Grass.cpp | 14 +- Samples/Hair/include/Hair.h | 546 +- Samples/Hair/src/Hair.cpp | 14 +- Samples/Instancing/include/Instancing.h | 896 +- Samples/Instancing/src/Instancing.cpp | 14 +- Samples/Island/include/Island.h | 336 +- Samples/Island/src/Island.cpp | 14 +- Samples/Isosurf/include/ProceduralTools.h | 2 +- Samples/Isosurf/src/Isosurf.cpp | 8 +- Samples/Lighting/include/Lighting.h | 636 +- Samples/Lighting/src/Lighting.cpp | 14 +- Samples/MeshLod/include/MeshLod.h | 92 +- Samples/MeshLod/src/MeshLod.cpp | 928 +- Samples/MeshLod/src/MeshLodPlugin.cpp | 14 +- .../NewInstancing/include/MersenneTwister.h | 90 +- Samples/NewInstancing/include/NewInstancing.h | 122 +- Samples/NewInstancing/src/NewInstancing.cpp | 1138 +- Samples/OceanDemo/include/MaterialControls.h | 22 +- Samples/OceanDemo/include/OceanDemo.h | 580 +- Samples/OceanDemo/src/MaterialControls.cpp | 24 +- Samples/OceanDemo/src/OceanDemo.cpp | 14 +- Samples/PCZTestApp/include/PCZTestApp.h | 360 +- Samples/PCZTestApp/include/RoomObject.h | 100 +- Samples/PCZTestApp/src/PCZTestApp.cpp | 2 +- Samples/PCZTestApp/src/RoomObject.cpp | 1812 +-- .../include/PNTrianglesTessellation.h | 516 +- .../src/PNTrianglesTessellation.cpp | 14 +- Samples/ParticleFX/include/ParticleFX.h | 104 +- Samples/ParticleFX/src/ParticleFX.cpp | 14 +- Samples/ParticleGS/include/RandomTools.h | 2 +- Samples/SSAO/include/SSAO.h | 212 +- Samples/SSAO/src/SSAO.cpp | 14 +- .../include/OgreShaderExInstancedViewports.h | 182 +- .../include/ShaderExReflectionMap.h | 246 +- Samples/ShaderSystem/include/ShaderSystem.h | 316 +- .../src/OgreShaderExInstancedViewports.cpp | 258 +- .../src/ShaderExReflectionMap.cpp | 618 +- Samples/ShaderSystem/src/ShaderSystem.cpp | 2744 ++-- .../include/RTShaderSRSSegmentedLights.h | 362 +- .../include/SegmentedDynamicLightManager.h | 212 +- .../include/ShaderSystemMultiLight.h | 624 +- .../src/RTShaderSRSSegmentedLights.cpp | 1578 +- .../src/SegmentedDynamicLightManager.cpp | 604 +- .../src/ShaderSystemMultiLight.cpp | 14 +- .../include/RTShaderSRSTexturedFog.h | 206 +- .../include/ShaderSystemTexturedFog.h | 342 +- .../src/RTShaderSRSTexturedFog.cpp | 484 +- .../src/ShaderSystemTexturedFog.cpp | 14 +- Samples/Shadows/include/Shadows.h | 1132 +- Samples/Shadows/src/Shadows.cpp | 14 +- .../include/SkeletalAnimation.h | 478 +- .../src/SkeletalAnimation.cpp | 14 +- Samples/SkyBox/include/SkyBox.h | 60 +- Samples/SkyBox/src/SkyBox.cpp | 14 +- Samples/SkyDome/include/SkyDome.h | 80 +- Samples/SkyDome/src/SkyDome.cpp | 14 +- Samples/SkyPlane/include/SkyPlane.h | 30 +- Samples/SkyPlane/src/SkyPlane.cpp | 14 +- Samples/Smoke/include/Smoke.h | 64 +- Samples/Smoke/src/Smoke.cpp | 14 +- Samples/SphereMapping/include/SphereMapping.h | 40 +- Samples/SphereMapping/src/SphereMapping.cpp | 14 +- Samples/Terrain/include/Terrain.h | 12 +- Samples/Terrain/src/Terrain.cpp | 14 +- .../include/TerrainTessellation.h | 610 +- .../TerrainTessellationMaterialGenerator.h | 12 +- .../src/TerrainTessellation.cpp | 14 +- .../TerrainTessellationMaterialGenerator.cpp | 88 +- Samples/Tessellation/src/Tessellation.cpp | 14 +- Samples/TextureArray/include/TextureArray.h | 96 +- Samples/TextureArray/src/TextureArray.cpp | 14 +- Samples/TextureFX/include/TextureFX.h | 56 +- Samples/TextureFX/src/TextureFX.cpp | 14 +- Samples/Transparency/include/Transparency.h | 86 +- Samples/Transparency/src/Transparency.cpp | 14 +- Samples/VolumeTex/include/Julia.h | 82 +- Samples/VolumeTex/include/ThingRenderable.h | 58 +- Samples/VolumeTex/include/VolumeRenderable.h | 54 +- Samples/VolumeTex/src/ThingRenderable.cpp | 250 +- Samples/VolumeTex/src/VolumeRenderable.cpp | 364 +- Samples/VolumeTex/src/VolumeTex.cpp | 270 +- Samples/Water/include/Water.h | 712 +- Samples/Water/include/WaterMesh.h | 74 +- Samples/Water/src/Water.cpp | 14 +- Samples/Water/src/WaterMesh.cpp | 490 +- Tests/CapsReport/main.cpp | 90 +- .../Components/Paging/include/PageCoreTests.h | 26 +- Tests/Components/Paging/src/PageCoreTests.cpp | 74 +- .../Property/include/PropertyTests.h | 14 +- .../Components/Property/src/PropertyTests.cpp | 36 +- .../Components/Terrain/include/TerrainTests.h | 20 +- Tests/Components/Terrain/src/TerrainTests.cpp | 96 +- Tests/OgreMain/include/DualQuaternionTests.h | 12 +- .../OgreMain/include/FileSystemArchiveTests.h | 4 +- Tests/OgreMain/include/RadixSortTests.h | 34 +- .../OgreMain/include/StreamSerialiserTests.h | 14 +- Tests/OgreMain/include/StringTests.h | 66 +- Tests/OgreMain/src/DualQuaternionTests.cpp | 80 +- Tests/OgreMain/src/EdgeBuilderTests.cpp | 10 +- Tests/OgreMain/src/FileSystemArchiveTests.cpp | 48 +- Tests/OgreMain/src/MeshSerializerTests.cpp | 868 +- .../src/MeshWithoutIndexDataTests.cpp | 24 +- Tests/OgreMain/src/PixelFormatTests.cpp | 94 +- Tests/OgreMain/src/RadixSort.cpp | 236 +- .../src/RenderSystemCapabilitiesTests.cpp | 28 +- Tests/OgreMain/src/StreamSerialiserTests.cpp | 74 +- Tests/OgreMain/src/StringTests.cpp | 158 +- Tests/OgreMain/src/Suite.cpp | 32 +- .../src/UseCustomCapabilitiesTests.cpp | 248 +- Tests/PlayPen/include/AnimationBlender.h | 42 +- Tests/PlayPen/include/PlayPen.h | 20 +- Tests/PlayPen/include/PlayPenSamples.h | 80 +- Tests/PlayPen/include/StaticPluginLoader.h | 100 +- Tests/PlayPen/src/AnimationBlender.cpp | 240 +- Tests/PlayPen/src/PlayPen.cpp | 12578 ++++++++-------- Tests/PlayPen/src/PlayPenSamples.cpp | 1466 +- Tests/PlayPen/src/WindowEmbedding.cpp | 248 +- .../VisualTests/PlayPen/src/PlayPenTests.cpp | 16 +- Tests/src/main.cpp | 32 +- .../PhysiqueInterface_sources/DllEntry.cpp | 50 +- .../PhysiqueInterface_sources/PhyExport.cpp | 76 +- .../PhysiqueInterface_sources/PhyExport.h | 10 +- .../PublishedInterface.cpp | 1730 +-- .../PublishedInterface.h | 128 +- .../OgreExport/include/OgreExport.h | 268 +- .../OgreExport/include/OgreMaxConfig.h | 468 +- .../OgreExport/include/OgreMaxExport.h | 22 +- .../include/OgreMaxMaterialExport.h | 38 +- .../OgreExport/include/OgreMaxMeshExport.h | 24 +- .../OgreExport/include/OgreMaxMeshXMLExport.h | 92 +- .../include/OgreMaxSkeletonXMLExport.h | 958 +- .../OgreExport/include/OgreMaxVertex.h | 76 +- .../OgreExport/src/OgreMaxConfig.cpp | 562 +- .../OgreExport/src/OgreMaxExport.cpp | 478 +- .../src/OgreMaxExportTabGeneral.cpp | 98 +- .../src/OgreMaxExportTabMaterial.cpp | 42 +- .../OgreExport/src/OgreMaxExportTabMesh.cpp | 248 +- .../src/OgreMaxExportTabSkeletalAnimation.cpp | 300 +- .../src/OgreMaxExportTabVertexAnimation.cpp | 42 +- .../OgreExport/src/OgreMaxMaterialExport.cpp | 396 +- .../OgreExport/src/OgreMaxMeshExport.cpp | 20 +- .../OgreExport/src/OgreMaxMeshXMLExport.cpp | 1656 +- .../OgreExport/src/OgreMaxVertex.cpp | 140 +- Tools/3dsmaxExport/OgreExport/src/dllmain.cpp | 96 +- Tools/LightwaveConverter/include/BitArray.h | 200 +- Tools/LightwaveConverter/include/Point.h | 140 +- Tools/LightwaveConverter/include/Vector3.h | 412 +- Tools/LightwaveConverter/include/lwClip.h | 246 +- Tools/LightwaveConverter/include/lwEnvelope.h | 76 +- Tools/LightwaveConverter/include/lwLayer.h | 74 +- Tools/LightwaveConverter/include/lwObject.h | 84 +- Tools/LightwaveConverter/include/lwPolygon.h | 58 +- Tools/LightwaveConverter/include/lwReader.h | 102 +- Tools/LightwaveConverter/include/lwo.h | 744 +- Tools/LightwaveConverter/include/lwo2mesh.h | 124 +- Tools/LightwaveConverter/src/BitArray.cpp | 120 +- Tools/LightwaveConverter/src/lwEnvelope.cpp | 622 +- Tools/LightwaveConverter/src/lwLayer.cpp | 386 +- Tools/LightwaveConverter/src/lwPolygon.cpp | 294 +- Tools/LightwaveConverter/src/lwReader.cpp | 4580 +++--- Tools/LightwaveConverter/src/lwo2mesh.cpp | 1144 +- Tools/LightwaveConverter/src/main.cpp | 1204 +- .../MaterialEditor/include/CallTipManager.h | 22 +- .../MaterialEditor/include/CgEditor.h | 20 +- .../MaterialEditor/include/CodeEditor.h | 144 +- .../MaterialEditor/include/DocManager.h | 14 +- .../MaterialEditor/include/DocPanel.h | 14 +- .../MaterialEditor/include/Editor.h | 88 +- .../include/EditorContributor.h | 8 +- .../MaterialEditor/include/EditorEventArgs.h | 8 +- .../MaterialEditor/include/EditorInput.h | 8 +- .../MaterialEditor/include/EditorManager.h | 134 +- .../MaterialEditor/include/EventArgs.h | 4 +- .../MaterialEditor/include/EventContainer.h | 18 +- .../MaterialEditor/include/GLSLEditor.h | 20 +- .../MaterialEditor/include/HLSLEditor.h | 18 +- .../MaterialEditor/include/IconManager.h | 54 +- .../MaterialEditor/include/LogPanel.h | 14 +- .../include/LogToTextRedirector.h | 10 +- .../include/MaterialController.h | 106 +- .../include/MaterialDescriptor.h | 32 +- .../include/MaterialEditorApp.h | 8 +- .../include/MaterialEditorFrame.h | 130 +- .../include/MaterialEventArgs.h | 12 +- .../MaterialEditor/include/MaterialPage.h | 24 +- .../include/MaterialPropertyGridPage.h | 18 +- .../include/MaterialScriptEditor.h | 18 +- .../MaterialEditor/include/MaterialWizard.h | 14 +- .../MaterialEditor/include/PassController.h | 190 +- .../MaterialEditor/include/PassEventArgs.h | 6 +- .../MaterialEditor/include/PassPage.h | 68 +- .../include/PassPropertyGridPage.h | 134 +- .../MaterialEditor/include/PassWizard.h | 14 +- .../MaterialEditor/include/Project.h | 100 +- .../MaterialEditor/include/ProjectEventArgs.h | 12 +- .../MaterialEditor/include/ProjectPage.h | 26 +- .../MaterialEditor/include/ProjectWizard.h | 14 +- .../MaterialEditor/include/PropertiesPanel.h | 36 +- .../MaterialEditor/include/ResourcePanel.h | 8 +- .../MaterialEditor/include/RootEventArgs.h | 2 +- .../MaterialEditor/include/RootEventPlugin.h | 96 +- .../MaterialEditor/include/ScintillaEditor.h | 148 +- .../include/SelectionEventArgs.h | 16 +- .../MaterialEditor/include/SelectionService.h | 98 +- .../MaterialEditor/include/Subject.h | 16 +- .../include/TechniqueController.h | 114 +- .../include/TechniqueEventArgs.h | 12 +- .../MaterialEditor/include/TechniquePage.h | 44 +- .../include/TechniquePropertyGridPage.h | 26 +- .../MaterialEditor/include/TechniqueWizard.h | 14 +- .../include/TextureUnitController.h | 214 +- .../include/TextureUnitPropertyGridPage.h | 86 +- .../MaterialEditor/include/Workspace.h | 104 +- .../include/WorkspaceEventArgs.h | 14 +- .../MaterialEditor/include/WorkspacePanel.h | 166 +- .../MaterialEditor/include/wxOgre.h | 220 +- .../MaterialEditor/src/CallTipManager.cpp | 116 +- .../MaterialEditor/src/CgEditor.cpp | 108 +- .../MaterialEditor/src/CodeEditor.cpp | 772 +- .../MaterialEditor/src/DocManager.cpp | 82 +- .../MaterialEditor/src/DocPanel.cpp | 78 +- .../MaterialEditor/src/Editor.cpp | 56 +- .../MaterialEditor/src/EditorManager.cpp | 312 +- .../MaterialEditor/src/EventContainer.cpp | 14 +- .../MaterialEditor/src/GLSLEditor.cpp | 106 +- .../MaterialEditor/src/HLSLEditor.cpp | 48 +- .../MaterialEditor/src/IconManager.cpp | 52 +- .../MaterialEditor/src/LogPanel.cpp | 30 +- .../src/LogToTextRedirector.cpp | 20 +- .../MaterialEditor/src/MaterialController.cpp | 216 +- .../MaterialEditor/src/MaterialDescriptor.cpp | 18 +- .../MaterialEditor/src/MaterialEditorApp.cpp | 42 +- .../src/MaterialEditorFrame.cpp | 774 +- .../MaterialEditor/src/MaterialEventArgs.cpp | 4 +- .../MaterialEditor/src/MaterialPage.cpp | 64 +- .../src/MaterialPropertyGridPage.cpp | 36 +- .../src/MaterialScriptEditor.cpp | 128 +- .../MaterialEditor/src/MaterialWizard.cpp | 20 +- .../MaterialEditor/src/PassController.cpp | 262 +- .../MaterialEditor/src/PassEventArgs.cpp | 2 +- .../MaterialEditor/src/PassPage.cpp | 170 +- .../src/PassPropertyGridPage.cpp | 758 +- .../MaterialEditor/src/PassWizard.cpp | 22 +- .../MaterialEditor/src/Project.cpp | 128 +- .../MaterialEditor/src/ProjectEventArgs.cpp | 4 +- .../MaterialEditor/src/ProjectPage.cpp | 48 +- .../MaterialEditor/src/ProjectWizard.cpp | 24 +- .../MaterialEditor/src/PropertiesPanel.cpp | 282 +- .../MaterialEditor/src/ResourcePanel.cpp | 42 +- .../MaterialEditor/src/RootEventPlugin.cpp | 16 +- .../MaterialEditor/src/ScintillaEditor.cpp | 836 +- .../MaterialEditor/src/SelectionEventArgs.cpp | 6 +- .../MaterialEditor/src/SelectionService.cpp | 24 +- .../src/TechniqueController.cpp | 202 +- .../MaterialEditor/src/TechniqueEventArgs.cpp | 4 +- .../MaterialEditor/src/TechniquePage.cpp | 100 +- .../src/TechniquePropertyGridPage.cpp | 70 +- .../MaterialEditor/src/TechniqueWizard.cpp | 22 +- .../src/TextureUnitController.cpp | 364 +- .../src/TextureUnitPropertyGridPage.cpp | 640 +- .../MaterialEditor/src/Workspace.cpp | 54 +- .../MaterialEditor/src/WorkspaceEventArgs.cpp | 4 +- .../MaterialEditor/src/WorkspacePanel.cpp | 626 +- .../MaterialEditor/src/wxOgre.cpp | 328 +- .../src/scintilla/include/Accessor.h | 108 +- .../src/scintilla/include/KeyWords.h | 78 +- .../src/scintilla/include/Platform.h | 606 +- .../src/scintilla/include/PropSet.h | 138 +- .../src/scintilla/include/SString.h | 404 +- .../src/scintilla/include/Scintilla.h | 72 +- .../src/scintilla/include/ScintillaWidget.h | 22 +- .../src/scintilla/include/WindowAccessor.h | 80 +- .../src/scintilla/src/AutoComplete.h | 82 +- .../src/scintilla/src/CallTip.h | 100 +- .../src/scintilla/src/CellBuffer.h | 348 +- .../src/scintilla/src/CharClassify.h | 16 +- .../src/scintilla/src/ContractionState.h | 66 +- .../src/scintilla/src/Document.h | 480 +- .../src/scintilla/src/DocumentAccessor.h | 92 +- .../src/scintilla/src/Editor.h | 1026 +- .../src/scintilla/src/ExternalLexer.h | 76 +- .../src/scintilla/src/Indicator.h | 10 +- .../src/scintilla/src/KeyMap.h | 24 +- .../src/scintilla/src/LineMarker.h | 74 +- .../src/scintilla/src/RESearch.h | 66 +- .../src/scintilla/src/SVector.h | 214 +- .../src/scintilla/src/ScintillaBase.h | 116 +- .../src/scintilla/src/Style.h | 74 +- .../src/scintilla/src/StyleContext.h | 278 +- .../src/scintilla/src/ViewStyle.h | 148 +- .../src/scintilla/src/XPM.h | 94 +- Tools/MayaExport/include/_singleton.h | 20 +- Tools/MayaExport/include/animation.h | 244 +- Tools/MayaExport/include/blendshape.h | 132 +- Tools/MayaExport/include/material.h | 128 +- Tools/MayaExport/include/materialSet.h | 164 +- Tools/MayaExport/include/mayaExportLayer.h | 4 +- Tools/MayaExport/include/mesh.h | 196 +- Tools/MayaExport/include/ogreExporter.h | 110 +- Tools/MayaExport/include/paramlist.h | 390 +- Tools/MayaExport/include/particles.h | 176 +- Tools/MayaExport/include/skeleton.h | 106 +- Tools/MayaExport/include/submesh.h | 82 +- Tools/MayaExport/include/vertex.h | 90 +- Tools/MayaExport/src/blendshape.cpp | 986 +- Tools/MayaExport/src/material.cpp | 1286 +- Tools/MayaExport/src/materialSet.cpp | 4 +- Tools/MayaExport/src/mesh.cpp | 3038 ++-- Tools/MayaExport/src/ogreExporter.cpp | 1098 +- Tools/MayaExport/src/paramlist.cpp | 888 +- Tools/MayaExport/src/particles.cpp | 496 +- Tools/MayaExport/src/skeleton.cpp | 1220 +- Tools/MayaExport/src/submesh.cpp | 964 +- Tools/MeshUpgrader/src/main.cpp | 1964 +-- .../MilkshapeExport/include/MilkshapePlugin.h | 12 +- Tools/MilkshapeExport/include/msLib.h | 36 +- Tools/MilkshapeExport/include/msPlugIn.h | 12 +- .../MilkshapeExport/src/MilkshapeExporter.cpp | 14 +- Tools/MilkshapeExport/src/MilkshapePlugin.cpp | 416 +- Tools/OgreZip2Cpp/src/OgreZip2Cpp.cpp | 74 +- Tools/VRMLConverter/src/VRML2mesh.cpp | 836 +- .../vrmllib/include/vrmllib/file.h | 16 +- .../vrmllib/include/vrmllib/node.h | 20 +- .../vrmllib/include/vrmllib/nodes.h | 154 +- .../vrmllib/include/vrmllib/types.h | 22 +- .../vrmllib/include/vrmllib/types_bits.h | 52 +- .../vrmllib/src/commentstream.cpp | 50 +- .../VRMLConverter/vrmllib/src/commentstream.h | 6 +- Tools/VRMLConverter/vrmllib/src/file.cpp | 98 +- .../vrmllib/src/indexed_face_set.cpp | 260 +- Tools/VRMLConverter/vrmllib/src/node.cpp | 176 +- Tools/VRMLConverter/vrmllib/src/nodes.cpp | 204 +- Tools/VRMLConverter/vrmllib/src/types.cpp | 54 +- .../include/OgreXMLMeshSerializer.h | 42 +- .../include/OgreXMLSkeletonSerializer.h | 20 +- Tools/XMLConverter/include/tinystr.h | 434 +- Tools/XMLConverter/include/tinyxml.h | 2902 ++-- .../src/OgreXMLMeshSerializer.cpp | 2906 ++-- .../src/OgreXMLSkeletonSerializer.cpp | 548 +- Tools/XMLConverter/src/main.cpp | 326 +- Tools/XMLConverter/src/tinystr.cpp | 94 +- Tools/XMLConverter/src/tinyxml.cpp | 2300 +-- Tools/XMLConverter/src/tinyxmlerror.cpp | 34 +- Tools/XMLConverter/src/tinyxmlparser.cpp | 2772 ++-- Tools/XSIExport/include/OgreXSIHelper.h | 240 +- .../include/OgreXSIMaterialExporter.h | 134 +- Tools/XSIExport/include/OgreXSIMeshExporter.h | 452 +- .../include/OgreXSISkeletonExporter.h | 128 +- Tools/XSIExport/src/OgreXSIExport.cpp | 2116 +-- Tools/XSIExport/src/OgreXSIHelper.cpp | 126 +- .../XSIExport/src/OgreXSIMaterialExporter.cpp | 1884 +-- Tools/XSIExport/src/OgreXSIMeshExporter.cpp | 2596 ++-- .../XSIExport/src/OgreXSISkeletonExporter.cpp | 966 +- Tools/dotXSIConverter/include/Exporter.h | 4 +- Tools/dotXSIConverter/src/Exporter.cpp | 52 +- Tools/rcapsdump/src/main.cpp | 84 +- 1690 files changed, 274642 insertions(+), 274642 deletions(-) diff --git a/Components/MeshLodGenerator/include/OgreLodBuffer.h b/Components/MeshLodGenerator/include/OgreLodBuffer.h index b6789b9a82b..c5591940b7c 100644 --- a/Components/MeshLodGenerator/include/OgreLodBuffer.h +++ b/Components/MeshLodGenerator/include/OgreLodBuffer.h @@ -36,42 +36,42 @@ namespace Ogre { /// Thread-safe buffer for storing Hardware index buffer struct _OgreLodExport LodIndexBuffer { - size_t indexSize; /// Index size: 2 or 4 byte/index is supported only. - size_t indexCount; /// index count from indexStart. - size_t indexStart; /// Offset from the start of the indexBuffer - size_t indexBufferSize; /// size of the index buffer in bytes - Ogre::SharedPtr indexBuffer; /// if NULL, then the previous Lod level's buffer is used. (compression) - void fillBuffer(Ogre::IndexData* data); /// Fills the buffer from an Ogre::IndexData. Call this on Ogre main thread only + size_t indexSize; /// Index size: 2 or 4 byte/index is supported only. + size_t indexCount; /// index count from indexStart. + size_t indexStart; /// Offset from the start of the indexBuffer + size_t indexBufferSize; /// size of the index buffer in bytes + Ogre::SharedPtr indexBuffer; /// if NULL, then the previous Lod level's buffer is used. (compression) + void fillBuffer(Ogre::IndexData* data); /// Fills the buffer from an Ogre::IndexData. Call this on Ogre main thread only }; /// Thread-safe buffer for storing Hardware vertex buffer struct _OgreLodExport LodVertexBuffer { - size_t vertexCount; - Ogre::SharedPtr vertexBuffer; - Ogre::SharedPtr vertexNormalBuffer; - void fillBuffer(Ogre::VertexData* data); + size_t vertexCount; + Ogre::SharedPtr vertexBuffer; + Ogre::SharedPtr vertexNormalBuffer; + void fillBuffer(Ogre::VertexData* data); }; /// Data representing all required information from a Mesh. Used by LodInputProviderBuffer. struct _OgreLodExport LodInputBuffer { - struct _OgreLodExport Submesh { - LodIndexBuffer indexBuffer; - LodVertexBuffer vertexBuffer; - bool useSharedVertexBuffer; - }; - vector::type submesh; - LodVertexBuffer sharedVertexBuffer; - String meshName; - Real boundingSphereRadius; - void fillBuffer(Ogre::MeshPtr mesh); + struct _OgreLodExport Submesh { + LodIndexBuffer indexBuffer; + LodVertexBuffer vertexBuffer; + bool useSharedVertexBuffer; + }; + vector::type submesh; + LodVertexBuffer sharedVertexBuffer; + String meshName; + Real boundingSphereRadius; + void fillBuffer(Ogre::MeshPtr mesh); }; /// Data representing the output of the Mesh reduction. Used by LodOutputProviderBuffer. struct _OgreLodExport LodOutputBuffer { - struct _OgreLodExport Submesh { - vector::type genIndexBuffers; - }; - /// Contains every generated indexBuffer from every submesh. submeshCount*lodLevelCount buffers. - vector::type submesh; + struct _OgreLodExport Submesh { + vector::type genIndexBuffers; + }; + /// Contains every generated indexBuffer from every submesh. submeshCount*lodLevelCount buffers. + vector::type submesh; }; } #endif \ No newline at end of file diff --git a/Components/MeshLodGenerator/include/OgreLodCollapseCost.h b/Components/MeshLodGenerator/include/OgreLodCollapseCost.h index e0601f23222..3a541695720 100644 --- a/Components/MeshLodGenerator/include/OgreLodCollapseCost.h +++ b/Components/MeshLodGenerator/include/OgreLodCollapseCost.h @@ -38,20 +38,20 @@ namespace Ogre class _OgreLodExport LodCollapseCost { public: - virtual ~LodCollapseCost() {} - /// This is called after the LodInputProvider has initialized LodData. - virtual void initCollapseCosts(LodData* data); - /// Called from initCollapseCosts for every edge. - virtual void initVertexCollapseCost(LodData* data, LodData::Vertex* vertex); - /// Called when edge cost gets invalid. - virtual void updateVertexCollapseCost(LodData* data, LodData::Vertex* vertex); - /// Called by initVertexCollapseCost and updateVertexCollapseCost, when the vertex minimal cost needs to be updated. - virtual void computeVertexCollapseCost(LodData* data, LodData::Vertex* vertex, Real& collapseCost, LodData::Vertex*& collapseTo); - /// Returns the collapse cost of the given edge. - virtual Real computeEdgeCollapseCost(LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge) = 0; + virtual ~LodCollapseCost() {} + /// This is called after the LodInputProvider has initialized LodData. + virtual void initCollapseCosts(LodData* data); + /// Called from initCollapseCosts for every edge. + virtual void initVertexCollapseCost(LodData* data, LodData::Vertex* vertex); + /// Called when edge cost gets invalid. + virtual void updateVertexCollapseCost(LodData* data, LodData::Vertex* vertex); + /// Called by initVertexCollapseCost and updateVertexCollapseCost, when the vertex minimal cost needs to be updated. + virtual void computeVertexCollapseCost(LodData* data, LodData::Vertex* vertex, Real& collapseCost, LodData::Vertex*& collapseTo); + /// Returns the collapse cost of the given edge. + virtual Real computeEdgeCollapseCost(LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge) = 0; protected: - // Helper functions: - bool isBorderVertex(const LodData::Vertex* vertex) const; + // Helper functions: + bool isBorderVertex(const LodData::Vertex* vertex) const; }; } diff --git a/Components/MeshLodGenerator/include/OgreLodCollapseCostCurvature.h b/Components/MeshLodGenerator/include/OgreLodCollapseCostCurvature.h index b02e502cfca..b751462aae4 100644 --- a/Components/MeshLodGenerator/include/OgreLodCollapseCostCurvature.h +++ b/Components/MeshLodGenerator/include/OgreLodCollapseCostCurvature.h @@ -38,10 +38,10 @@ namespace Ogre { class _OgreLodExport LodCollapseCostCurvature : - public LodCollapseCost + public LodCollapseCost { public: - virtual Real computeEdgeCollapseCost(LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge); + virtual Real computeEdgeCollapseCost(LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge); }; } diff --git a/Components/MeshLodGenerator/include/OgreLodCollapseCostOutside.h b/Components/MeshLodGenerator/include/OgreLodCollapseCostOutside.h index b07fe78bffb..d23daf5ed26 100644 --- a/Components/MeshLodGenerator/include/OgreLodCollapseCostOutside.h +++ b/Components/MeshLodGenerator/include/OgreLodCollapseCostOutside.h @@ -39,21 +39,21 @@ namespace Ogre { class _OgreLodExport LodCollapseCostOutside : - public LodCollapseCost + public LodCollapseCost { public: - LodCollapseCostOutside(LodCollapseCostPtr costCalculator, Real outsideWeight, Real outsideWalkAngle); - ~LodCollapseCostOutside(); - virtual void initCollapseCosts(LodData* data); - virtual Real computeEdgeCollapseCost(LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge); + LodCollapseCostOutside(LodCollapseCostPtr costCalculator, Real outsideWeight, Real outsideWalkAngle); + ~LodCollapseCostOutside(); + virtual void initCollapseCosts(LodData* data); + virtual Real computeEdgeCollapseCost(LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge); protected: - Real mOutsideWeight; - Real mOutsideWalkAngle; + Real mOutsideWeight; + Real mOutsideWalkAngle; - // Result of this collapse cost algorithm will be modified, if it is outside. - LodCollapseCostPtr mCostCalculator; - LodOutsideMarker* mOutsideMarker; + // Result of this collapse cost algorithm will be modified, if it is outside. + LodCollapseCostPtr mCostCalculator; + LodOutsideMarker* mOutsideMarker; }; } diff --git a/Components/MeshLodGenerator/include/OgreLodCollapseCostProfiler.h b/Components/MeshLodGenerator/include/OgreLodCollapseCostProfiler.h index e7066526a14..75ffd521d07 100644 --- a/Components/MeshLodGenerator/include/OgreLodCollapseCostProfiler.h +++ b/Components/MeshLodGenerator/include/OgreLodCollapseCostProfiler.h @@ -39,32 +39,32 @@ namespace Ogre { class _OgreLodExport LodCollapseCostProfiler : - public LodCollapseCost + public LodCollapseCost { public: - LodCollapseCostProfiler(LodProfile& profile, LodCollapseCostPtr& costCalculator) : mProfile(profile), mCostCalculator(costCalculator) {} - virtual void initCollapseCosts(LodData* data); - virtual void computeVertexCollapseCost(LodData* data, LodData::Vertex* vertex, Real& collapseCost, LodData::Vertex*& collapseTo); - virtual Real computeEdgeCollapseCost(LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge); + LodCollapseCostProfiler(LodProfile& profile, LodCollapseCostPtr& costCalculator) : mProfile(profile), mCostCalculator(costCalculator) {} + virtual void initCollapseCosts(LodData* data); + virtual void computeVertexCollapseCost(LodData* data, LodData::Vertex* vertex, Real& collapseCost, LodData::Vertex*& collapseTo); + virtual Real computeEdgeCollapseCost(LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge); protected: - struct ProfiledEdge { - LodData::Vertex* dst; - Real cost; - }; + struct ProfiledEdge { + LodData::Vertex* dst; + Real cost; + }; - typedef vector::type HasVertexProfileList; + typedef vector::type HasVertexProfileList; - HasVertexProfileList mHasProfile; + HasVertexProfileList mHasProfile; - typedef HashMultiMap ProfileLookup; - ProfileLookup mProfileLookup; - LodProfile mProfile; + typedef HashMultiMap ProfileLookup; + ProfileLookup mProfileLookup; + LodProfile mProfile; - // If an edge doesn't have a profile, this collapsecost algorithm will be used. - LodCollapseCostPtr mCostCalculator; + // If an edge doesn't have a profile, this collapsecost algorithm will be used. + LodCollapseCostPtr mCostCalculator; - void injectProfile(LodData* data); + void injectProfile(LodData* data); }; } diff --git a/Components/MeshLodGenerator/include/OgreLodCollapseCostQuadric.h b/Components/MeshLodGenerator/include/OgreLodCollapseCostQuadric.h index e4e9cee0c66..b1594881adf 100644 --- a/Components/MeshLodGenerator/include/OgreLodCollapseCostQuadric.h +++ b/Components/MeshLodGenerator/include/OgreLodCollapseCostQuadric.h @@ -39,21 +39,21 @@ namespace Ogre { class _OgreLodExport LodCollapseCostQuadric : - public LodCollapseCost + public LodCollapseCost { public: - virtual void initCollapseCosts(LodData* data); - virtual void updateVertexCollapseCost(LodData* data, LodData::Vertex* vertex); - virtual Real computeEdgeCollapseCost(LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge); + virtual void initCollapseCosts(LodData* data); + virtual void updateVertexCollapseCost(LodData* data, LodData::Vertex* vertex); + virtual Real computeEdgeCollapseCost(LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge); protected: - struct TriangleQuadricPlane { - Matrix4 quadric; - }; - vector::type mTrianglePlaneQuadricList; - vector::type mVertexQuadricList; - void computeTrianglePlaneQuadric(LodData* data, size_t triangleID); - void computeVertexQuadric(LodData* data, size_t vertexID); + struct TriangleQuadricPlane { + Matrix4 quadric; + }; + vector::type mTrianglePlaneQuadricList; + vector::type mVertexQuadricList; + void computeTrianglePlaneQuadric(LodData* data, size_t triangleID); + void computeVertexQuadric(LodData* data, size_t vertexID); }; } diff --git a/Components/MeshLodGenerator/include/OgreLodCollapser.h b/Components/MeshLodGenerator/include/OgreLodCollapser.h index 418dd9184b8..e602d5071b5 100644 --- a/Components/MeshLodGenerator/include/OgreLodCollapser.h +++ b/Components/MeshLodGenerator/include/OgreLodCollapser.h @@ -39,55 +39,55 @@ namespace Ogre class _OgreLodExport LodCollapser { public: - virtual ~LodCollapser() {} - /// Reduces vertices until vertexCountLimit or collapseCostLimit is reached. - virtual void collapse(LodData* data, LodCollapseCost* cost, LodOutputProvider* output, int vertexCountLimit, Real collapseCostLimit); + virtual ~LodCollapser() {} + /// Reduces vertices until vertexCountLimit or collapseCostLimit is reached. + virtual void collapse(LodData* data, LodCollapseCost* cost, LodOutputProvider* output, int vertexCountLimit, Real collapseCostLimit); - /** - * @brief Returns the last reduced vertex. - * - * You should call this function after generateLodLevels! - * - * @param data This parameter is not used, but this will guarantee that data is alive. - * @param outVec The vector receiving the position of the vertex. - * @return Whether the outVec was changed. If the mesh is reduced at least 1 vertex, then it returns true. - */ - bool _getLastVertexPos(LodData* data, Vector3& outVec); + /** + * @brief Returns the last reduced vertex. + * + * You should call this function after generateLodLevels! + * + * @param data This parameter is not used, but this will guarantee that data is alive. + * @param outVec The vector receiving the position of the vertex. + * @return Whether the outVec was changed. If the mesh is reduced at least 1 vertex, then it returns true. + */ + bool _getLastVertexPos(LodData* data, Vector3& outVec); - /** - * @brief Returns the destination of the edge, which was last reduced. - * - * You should call this function after generateLodLevels! - * - * @param data This parameter is not used, but this will guarantee that data is alive. - * @param outVec The vector receiving the CollapseTo position. - * @return Whether the outVec was changed. If the mesh is reduced at least 1 vertex, then it returns true. - */ - bool _getLastVertexCollapseTo(LodData* data, Vector3& outVec); + /** + * @brief Returns the destination of the edge, which was last reduced. + * + * You should call this function after generateLodLevels! + * + * @param data This parameter is not used, but this will guarantee that data is alive. + * @param outVec The vector receiving the CollapseTo position. + * @return Whether the outVec was changed. If the mesh is reduced at least 1 vertex, then it returns true. + */ + bool _getLastVertexCollapseTo(LodData* data, Vector3& outVec); protected: - struct CollapsedEdge { - unsigned int srcID; - unsigned int dstID; - unsigned short submeshID; - }; - - typedef vector::type CollapsedEdges; + struct CollapsedEdge { + unsigned int srcID; + unsigned int dstID; + unsigned short submeshID; + }; + + typedef vector::type CollapsedEdges; - /// tmp variable, to overcome allocation on every collapse. - CollapsedEdges tmpCollapsedEdges; + /// tmp variable, to overcome allocation on every collapse. + CollapsedEdges tmpCollapsedEdges; - /// Last reduced vertex. Can be used for debugging purposes. For example the Mesh Lod Editor uses it to select edge. - LodData::Vertex* mLastReducedVertex; + /// Last reduced vertex. Can be used for debugging purposes. For example the Mesh Lod Editor uses it to select edge. + LodData::Vertex* mLastReducedVertex; - /// Collapses a single vertex. - void collapseVertex(LodData* data, LodCollapseCost* cost, LodOutputProvider* output, LodData::Vertex* src); - void assertOutdatedCollapseCost(LodData* data, LodCollapseCost* cost, LodData::Vertex* vertex); - void assertValidMesh(LodData* data); - void assertValidVertex(LodData* data, LodData::Vertex* v); - bool hasSrcID(unsigned int srcID, unsigned short submeshID); - void removeTriangleFromEdges(LodData::Triangle* triangle, LodData::Vertex* skip); - size_t findDstID(unsigned int srcID, unsigned short submeshID); - void replaceVertexID(LodData::Triangle* triangle, unsigned int oldID, unsigned int newID, LodData::Vertex* dst); + /// Collapses a single vertex. + void collapseVertex(LodData* data, LodCollapseCost* cost, LodOutputProvider* output, LodData::Vertex* src); + void assertOutdatedCollapseCost(LodData* data, LodCollapseCost* cost, LodData::Vertex* vertex); + void assertValidMesh(LodData* data); + void assertValidVertex(LodData* data, LodData::Vertex* v); + bool hasSrcID(unsigned int srcID, unsigned short submeshID); + void removeTriangleFromEdges(LodData::Triangle* triangle, LodData::Vertex* skip); + size_t findDstID(unsigned int srcID, unsigned short submeshID); + void replaceVertexID(LodData::Triangle* triangle, unsigned int oldID, unsigned int newID, LodData::Vertex* dst); }; } diff --git a/Components/MeshLodGenerator/include/OgreLodConfig.h b/Components/MeshLodGenerator/include/OgreLodConfig.h index d48504ff78d..dd0ea34a385 100644 --- a/Components/MeshLodGenerator/include/OgreLodConfig.h +++ b/Components/MeshLodGenerator/include/OgreLodConfig.h @@ -36,9 +36,9 @@ namespace Ogre { struct _OgreLodExport ProfiledEdge { - Vector3 src; // Vertex identifier - Vector3 dst; // Direction of collapse - Real cost; // Requested collapse cost + Vector3 src; // Vertex identifier + Vector3 dst; // Direction of collapse + Real cost; // Requested collapse cost }; typedef vector::type LodProfile; @@ -47,84 +47,84 @@ typedef vector::type LodProfile; * @brief Structure for automatic Lod configuration. */ struct _OgreLodExport LodLevel { - /** - * @brief Type of the reduction. - * - * Note: The vertex count is determined by unique vertices per submesh. - * A mesh may have duplicate vertices with same position. - */ - enum VertexReductionMethod { - /** - * @brief Percentage of vertexes to be removed from each submesh. - * - * Valid range is a number between 0.0 and 1.0 - */ - VRM_PROPORTIONAL, - - /** - * @brief Exact vertex count to be removed from each submesh. - * - * Pass only integers or it will be rounded. - */ - VRM_CONSTANT, - - /** - * @brief Reduces the vertices, until the cost is bigger then the given value. - * - * Collapse cost is equal to the amount of artifact the reduction causes. - * This generates the best Lod output, but the collapse cost depends on implementation. - */ - VRM_COLLAPSE_COST - }; - - /** - * @brief Distance to swap the Lod. - * - * This depends on LodStrategy. - */ - Real distance; - - /** - * @brief Reduction method to use. - * - * @see ProgressiveMeshGenerator::VertexReductionMethod - */ - VertexReductionMethod reductionMethod; - - /** - * @brief The value, which depends on reductionMethod. - */ - Real reductionValue; - - /** - * @brief Set's a mesh as the Lod Level for given distance. - * - * This allows to generate the Lod levels in third party editors. - * The mesh should have the same submeshes, same bones and animations, like the original mesh. - * If you use this parameter, the reduction value and method will be ignored. - * Using manual mesh is less efficient, because it needs separated vertex buffers. - */ - String manualMeshName; - - /** - * @brief This is set by ProgressiveMeshGenerator::build() function. - * - * Use Mesh::getNumLodLevels() for generated Lod count. - */ - size_t outUniqueVertexCount; - - /** - * @brief Whether the Lod level generation was skipped, because it has same vertex count as the previous Lod level. - */ - bool outSkipped; + /** + * @brief Type of the reduction. + * + * Note: The vertex count is determined by unique vertices per submesh. + * A mesh may have duplicate vertices with same position. + */ + enum VertexReductionMethod { + /** + * @brief Percentage of vertexes to be removed from each submesh. + * + * Valid range is a number between 0.0 and 1.0 + */ + VRM_PROPORTIONAL, + + /** + * @brief Exact vertex count to be removed from each submesh. + * + * Pass only integers or it will be rounded. + */ + VRM_CONSTANT, + + /** + * @brief Reduces the vertices, until the cost is bigger then the given value. + * + * Collapse cost is equal to the amount of artifact the reduction causes. + * This generates the best Lod output, but the collapse cost depends on implementation. + */ + VRM_COLLAPSE_COST + }; + + /** + * @brief Distance to swap the Lod. + * + * This depends on LodStrategy. + */ + Real distance; + + /** + * @brief Reduction method to use. + * + * @see ProgressiveMeshGenerator::VertexReductionMethod + */ + VertexReductionMethod reductionMethod; + + /** + * @brief The value, which depends on reductionMethod. + */ + Real reductionValue; + + /** + * @brief Set's a mesh as the Lod Level for given distance. + * + * This allows to generate the Lod levels in third party editors. + * The mesh should have the same submeshes, same bones and animations, like the original mesh. + * If you use this parameter, the reduction value and method will be ignored. + * Using manual mesh is less efficient, because it needs separated vertex buffers. + */ + String manualMeshName; + + /** + * @brief This is set by ProgressiveMeshGenerator::build() function. + * + * Use Mesh::getNumLodLevels() for generated Lod count. + */ + size_t outUniqueVertexCount; + + /** + * @brief Whether the Lod level generation was skipped, because it has same vertex count as the previous Lod level. + */ + bool outSkipped; }; struct _OgreLodExport LodConfig { - MeshPtr mesh; /// The mesh which we want to reduce. - LodStrategy* strategy; /// Lod strategy to use. + MeshPtr mesh; /// The mesh which we want to reduce. + LodStrategy* strategy; /// Lod strategy to use. - typedef vector::type LodLevelList; - LodLevelList levels; /// Info about Lod levels + typedef vector::type LodLevelList; + LodLevelList levels; /// Info about Lod levels LodConfig(MeshPtr & _mesh, LodStrategy * _strategy = DistanceLodStrategy::getSingletonPtr()); LodConfig(); @@ -136,29 +136,29 @@ struct _OgreLodExport LodConfig { LodLevel::VertexReductionMethod reductionMethod = LodLevel::VRM_PROPORTIONAL); struct _OgreLodExport Advanced { - /// Whether you want to process it immediatelly on main thread or you want to use Ogre::WorkQueue. - /// If you use workqueue the generator will return immediately. After processed in background, - /// the LodWorkQueueInjector will inject it in frameEnd event when rendering next frame. - /// Ready LODs can also be injected by calling Root::getSingleton().getWorkQueue()->processResponses(). - /// (disabled by default) - bool useBackgroundQueue; - /// If enabled, it allows up to 50% smaller index buffers by storing once shared faces with frame shifting. - /// There is no performance disadvantage! (enabled by default) - bool useCompression; - /// Use vertex normals to improve quality. Bit slower to generate, but it has better quality most of the time. - /// (enabled by default) - bool useVertexNormals; - /// Faces inside a house can't be seen from far away. Weightening outside allows to remove those internal faces. - /// It makes generation smaller and it is not 100% accurate. Set it to 0.0 to disable. - /// (disabled by default) - Ogre::Real outsideWeight; - /// If outsideWeight is enabled, this will set the angle how deep the algorithm can walk inside the mesh. - /// This value is an acos number between -1 and 1. (by default it is 0 which means 90 degree) - Ogre::Real outsideWalkAngle; - /// If the algorithm makes errors, you can fix it, by adding the edge to the profile. - LodProfile profile; + /// Whether you want to process it immediatelly on main thread or you want to use Ogre::WorkQueue. + /// If you use workqueue the generator will return immediately. After processed in background, + /// the LodWorkQueueInjector will inject it in frameEnd event when rendering next frame. + /// Ready LODs can also be injected by calling Root::getSingleton().getWorkQueue()->processResponses(). + /// (disabled by default) + bool useBackgroundQueue; + /// If enabled, it allows up to 50% smaller index buffers by storing once shared faces with frame shifting. + /// There is no performance disadvantage! (enabled by default) + bool useCompression; + /// Use vertex normals to improve quality. Bit slower to generate, but it has better quality most of the time. + /// (enabled by default) + bool useVertexNormals; + /// Faces inside a house can't be seen from far away. Weightening outside allows to remove those internal faces. + /// It makes generation smaller and it is not 100% accurate. Set it to 0.0 to disable. + /// (disabled by default) + Ogre::Real outsideWeight; + /// If outsideWeight is enabled, this will set the angle how deep the algorithm can walk inside the mesh. + /// This value is an acos number between -1 and 1. (by default it is 0 which means 90 degree) + Ogre::Real outsideWalkAngle; + /// If the algorithm makes errors, you can fix it, by adding the edge to the profile. + LodProfile profile; Advanced(); - } advanced; + } advanced; }; } #endif diff --git a/Components/MeshLodGenerator/include/OgreLodConfigSerializer.h b/Components/MeshLodGenerator/include/OgreLodConfigSerializer.h index 80c66341fcc..7044e6e7337 100644 --- a/Components/MeshLodGenerator/include/OgreLodConfigSerializer.h +++ b/Components/MeshLodGenerator/include/OgreLodConfigSerializer.h @@ -1,87 +1,87 @@ -/* - * ----------------------------------------------------------------------------- - * This source file is part of OGRE - * (Object-oriented Graphics Rendering Engine) - * For the latest info, see http://www.ogre3d.org/ - * - * Copyright (c) 2000-2014 Torus Knot Software Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ----------------------------------------------------------------------------- - */ - -#ifndef __LogConfigSerializer_H_ -#define __LogConfigSerializer_H_ - -#include "OgreLodPrerequisites.h" - -#include "OgreDataStream.h" -#include "OgreSerializer.h" - -namespace Ogre -{ - -class _OgreLodExport LodConfigSerializer : - public Ogre::Serializer -{ - -public: - - LodConfigSerializer(); - - void exportLodConfig(Ogre::LodConfig& config, const Ogre::String& filename, - Endian endianMode = ENDIAN_NATIVE); - void exportLodConfig(Ogre::LodConfig& config, Ogre::DataStreamPtr stream, - Endian endianMode = ENDIAN_NATIVE); - - void importLodConfig(Ogre::LodConfig* config, const Ogre::String& filename); - void importLodConfig(Ogre::LodConfig* config, DataStreamPtr& stream); - -protected: - - enum LodConfigChunkID { - LCCID_FILE_HEADER = 0x300, - LCCID_LOD_CONFIG = 0x400, - LCCID_BASIC_INFO = 0x500, - LCCID_LOD_LEVELS = 0x600, - LCCID_ADVANCED_INFO = 0x700, - LCCID_PROFILE = 0x800, - }; - - void readLodConfig(); - void readLodBasicInfo(); - void readLodLevels(); - void readLodAdvancedInfo(); - void readLodProfile(); - - void writeLodConfig(); - size_t calcLodConfigSize(); - void writeLodBasicInfo(); - size_t calcLodBasicInfoSize(); - void writeLodLevels(); - size_t calcLodLevelsSize(); - void writeLodAdvancedInfo(); - size_t calcLodAdvancedInfoSize(); - void writeLodProfile(); - size_t calcLodProfileSize(); - - LodConfig* mLodConfig; -}; -} +/* + * ----------------------------------------------------------------------------- + * This source file is part of OGRE + * (Object-oriented Graphics Rendering Engine) + * For the latest info, see http://www.ogre3d.org/ + * + * Copyright (c) 2000-2014 Torus Knot Software Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ----------------------------------------------------------------------------- + */ + +#ifndef __LogConfigSerializer_H_ +#define __LogConfigSerializer_H_ + +#include "OgreLodPrerequisites.h" + +#include "OgreDataStream.h" +#include "OgreSerializer.h" + +namespace Ogre +{ + +class _OgreLodExport LodConfigSerializer : + public Ogre::Serializer +{ + +public: + + LodConfigSerializer(); + + void exportLodConfig(Ogre::LodConfig& config, const Ogre::String& filename, + Endian endianMode = ENDIAN_NATIVE); + void exportLodConfig(Ogre::LodConfig& config, Ogre::DataStreamPtr stream, + Endian endianMode = ENDIAN_NATIVE); + + void importLodConfig(Ogre::LodConfig* config, const Ogre::String& filename); + void importLodConfig(Ogre::LodConfig* config, DataStreamPtr& stream); + +protected: + + enum LodConfigChunkID { + LCCID_FILE_HEADER = 0x300, + LCCID_LOD_CONFIG = 0x400, + LCCID_BASIC_INFO = 0x500, + LCCID_LOD_LEVELS = 0x600, + LCCID_ADVANCED_INFO = 0x700, + LCCID_PROFILE = 0x800, + }; + + void readLodConfig(); + void readLodBasicInfo(); + void readLodLevels(); + void readLodAdvancedInfo(); + void readLodProfile(); + + void writeLodConfig(); + size_t calcLodConfigSize(); + void writeLodBasicInfo(); + size_t calcLodBasicInfoSize(); + void writeLodLevels(); + size_t calcLodLevelsSize(); + void writeLodAdvancedInfo(); + size_t calcLodAdvancedInfoSize(); + void writeLodProfile(); + size_t calcLodProfileSize(); + + LodConfig* mLodConfig; +}; +} #endif \ No newline at end of file diff --git a/Components/MeshLodGenerator/include/OgreLodData.h b/Components/MeshLodGenerator/include/OgreLodData.h index 21e14801fcd..a95d789822e 100644 --- a/Components/MeshLodGenerator/include/OgreLodData.h +++ b/Components/MeshLodGenerator/include/OgreLodData.h @@ -46,125 +46,125 @@ namespace Ogre struct _OgreLodExport LodData { - static const Real NEVER_COLLAPSE_COST /*= std::numeric_limits::max()*/; - static const Real UNINITIALIZED_COLLAPSE_COST /*= std::numeric_limits::infinity()*/; - - struct Edge; - struct Vertex; - struct Triangle; - struct VertexHash; - struct VertexEqual; - - typedef vector::type VertexList; - typedef vector::type TriangleList; - typedef HashSet UniqueVertexSet; - typedef multimap::type CollapseCostHeap; - - typedef VectorSet VEdges; - typedef VectorSet VTriangles; - - // Hash function for UniqueVertexSet. - struct VertexHash { - LodData* mGen; - - VertexHash() : mGen(0) { assert(0); } - VertexHash(LodData* gen) { mGen = gen; } - size_t operator() (const Vertex* v) const; - }; - - // Equality function for UniqueVertexSet. - struct VertexEqual { - bool operator() (const Vertex* lhs, const Vertex* rhs) const; - }; - - // Directed edge - struct Edge { - Vertex* dst; // destination vertex. (other end of the edge) - Real collapseCost; // cost of the edge. - int refCount; // Reference count on how many triangles are using this edge. The edge will be removed when it gets 0. - - explicit Edge(Vertex* destination); - bool operator== (const Edge& other) const; - Edge& operator= (const Edge& b); - Edge(const Edge& b); - bool operator< (const Edge& other) const; - }; - - struct Vertex { - Vector3 position; - VEdges edges; - VTriangles triangles; - - Vector3 normal; - Vertex* collapseTo; - bool seam; - CollapseCostHeap::iterator costHeapPosition; /// Iterator pointing to the position in the mCollapseCostSet, which allows fast remove. - - void addEdge(const Edge& edge); - void removeEdge(const Edge& edge); - }; - - struct Triangle { - Vertex* vertex[3]; - Vector3 normal; - bool isRemoved; - unsigned short submeshID; /// ID of the submesh. Usable with mMesh.getSubMesh() function. - unsigned int vertexID[3]; /// Vertex ID in the buffer associated with the submeshID. - - void computeNormal(); - bool hasVertex(const Vertex* v) const; - unsigned int getVertexID(const Vertex* v) const; - bool isMalformed(); - }; - - union IndexBufferPointer { - unsigned short* pshort; - unsigned int* pint; - }; - - struct IndexBufferInfo { - size_t indexSize; - size_t indexCount; - IndexBufferPointer buf; // Used by output providers only! - size_t prevOnlyIndexCount; // Used by output providers only! - size_t prevIndexCount; // Used by output providers only! - }; - - typedef vector::type IndexBufferInfoList; - - /// Provides position based vertex lookup. Position is the real identifier of a vertex. - UniqueVertexSet mUniqueVertexSet; - - VertexList mVertexList; - TriangleList mTriangleList; - - /// Makes possible to get the vertices with the smallest collapse cost. - CollapseCostHeap mCollapseCostHeap; - IndexBufferInfoList mIndexBufferInfoList; + static const Real NEVER_COLLAPSE_COST /*= std::numeric_limits::max()*/; + static const Real UNINITIALIZED_COLLAPSE_COST /*= std::numeric_limits::infinity()*/; + + struct Edge; + struct Vertex; + struct Triangle; + struct VertexHash; + struct VertexEqual; + + typedef vector::type VertexList; + typedef vector::type TriangleList; + typedef HashSet UniqueVertexSet; + typedef multimap::type CollapseCostHeap; + + typedef VectorSet VEdges; + typedef VectorSet VTriangles; + + // Hash function for UniqueVertexSet. + struct VertexHash { + LodData* mGen; + + VertexHash() : mGen(0) { assert(0); } + VertexHash(LodData* gen) { mGen = gen; } + size_t operator() (const Vertex* v) const; + }; + + // Equality function for UniqueVertexSet. + struct VertexEqual { + bool operator() (const Vertex* lhs, const Vertex* rhs) const; + }; + + // Directed edge + struct Edge { + Vertex* dst; // destination vertex. (other end of the edge) + Real collapseCost; // cost of the edge. + int refCount; // Reference count on how many triangles are using this edge. The edge will be removed when it gets 0. + + explicit Edge(Vertex* destination); + bool operator== (const Edge& other) const; + Edge& operator= (const Edge& b); + Edge(const Edge& b); + bool operator< (const Edge& other) const; + }; + + struct Vertex { + Vector3 position; + VEdges edges; + VTriangles triangles; + + Vector3 normal; + Vertex* collapseTo; + bool seam; + CollapseCostHeap::iterator costHeapPosition; /// Iterator pointing to the position in the mCollapseCostSet, which allows fast remove. + + void addEdge(const Edge& edge); + void removeEdge(const Edge& edge); + }; + + struct Triangle { + Vertex* vertex[3]; + Vector3 normal; + bool isRemoved; + unsigned short submeshID; /// ID of the submesh. Usable with mMesh.getSubMesh() function. + unsigned int vertexID[3]; /// Vertex ID in the buffer associated with the submeshID. + + void computeNormal(); + bool hasVertex(const Vertex* v) const; + unsigned int getVertexID(const Vertex* v) const; + bool isMalformed(); + }; + + union IndexBufferPointer { + unsigned short* pshort; + unsigned int* pint; + }; + + struct IndexBufferInfo { + size_t indexSize; + size_t indexCount; + IndexBufferPointer buf; // Used by output providers only! + size_t prevOnlyIndexCount; // Used by output providers only! + size_t prevIndexCount; // Used by output providers only! + }; + + typedef vector::type IndexBufferInfoList; + + /// Provides position based vertex lookup. Position is the real identifier of a vertex. + UniqueVertexSet mUniqueVertexSet; + + VertexList mVertexList; + TriangleList mTriangleList; + + /// Makes possible to get the vertices with the smallest collapse cost. + CollapseCostHeap mCollapseCostHeap; + IndexBufferInfoList mIndexBufferInfoList; #if OGRE_DEBUG_MODE - /** - * @brief The name of the mesh being processed. - * - * This is separate from mMesh in order to allow for access from background threads. - */ - String mMeshName; + /** + * @brief The name of the mesh being processed. + * + * This is separate from mMesh in order to allow for access from background threads. + */ + String mMeshName; #endif - Real mMeshBoundingSphereRadius; - bool mUseVertexNormals; - - template - static size_t getVectorIDFromPointer(const std::vector& vec, const T* pointer) { - size_t id = pointer - &vec.at(0); - OgreAssert(id < vec.size() && (&vec[id] == pointer), "Invalid pointer"); - return id; - } - - LodData() : - mUniqueVertexSet((UniqueVertexSet::size_type) 0, - (const UniqueVertexSet::hasher&) VertexHash(this)), - mMeshBoundingSphereRadius(0.0f), - mUseVertexNormals(true) - {} + Real mMeshBoundingSphereRadius; + bool mUseVertexNormals; + + template + static size_t getVectorIDFromPointer(const std::vector& vec, const T* pointer) { + size_t id = pointer - &vec.at(0); + OgreAssert(id < vec.size() && (&vec[id] == pointer), "Invalid pointer"); + return id; + } + + LodData() : + mUniqueVertexSet((UniqueVertexSet::size_type) 0, + (const UniqueVertexSet::hasher&) VertexHash(this)), + mMeshBoundingSphereRadius(0.0f), + mUseVertexNormals(true) + {} }; } diff --git a/Components/MeshLodGenerator/include/OgreLodInputProvider.h b/Components/MeshLodGenerator/include/OgreLodInputProvider.h index 58ce4f2185e..be14c773cfa 100644 --- a/Components/MeshLodGenerator/include/OgreLodInputProvider.h +++ b/Components/MeshLodGenerator/include/OgreLodInputProvider.h @@ -38,15 +38,15 @@ namespace Ogre class _OgreLodExport LodInputProvider { public: - virtual ~LodInputProvider() {} - /// Called when the data should be filled with the input. - virtual void initData(LodData* data) = 0; + virtual ~LodInputProvider() {} + /// Called when the data should be filled with the input. + virtual void initData(LodData* data) = 0; protected: - // Helper functions - void printTriangle(LodData::Triangle* triangle, stringstream& str); - void addTriangleToEdges(LodData* data, LodData::Triangle* triangle); - bool isDuplicateTriangle(LodData::Triangle* triangle, LodData::Triangle* triangle2); - LodData::Triangle* isDuplicateTriangle(LodData::Triangle* triangle); + // Helper functions + void printTriangle(LodData::Triangle* triangle, stringstream& str); + void addTriangleToEdges(LodData* data, LodData::Triangle* triangle); + bool isDuplicateTriangle(LodData::Triangle* triangle, LodData::Triangle* triangle2); + LodData::Triangle* isDuplicateTriangle(LodData::Triangle* triangle); }; } diff --git a/Components/MeshLodGenerator/include/OgreLodInputProviderBuffer.h b/Components/MeshLodGenerator/include/OgreLodInputProviderBuffer.h index caac30c4974..153f29112a7 100644 --- a/Components/MeshLodGenerator/include/OgreLodInputProviderBuffer.h +++ b/Components/MeshLodGenerator/include/OgreLodInputProviderBuffer.h @@ -40,61 +40,61 @@ namespace Ogre { class _OgreLodExport LodInputProviderBuffer : - public LodInputProvider + public LodInputProvider { public: - LodInputProviderBuffer(MeshPtr mesh); - /// Called when the data should be filled with the input. - virtual void initData(LodData* data); - + LodInputProviderBuffer(MeshPtr mesh); + /// Called when the data should be filled with the input. + virtual void initData(LodData* data); + protected: - LodInputBuffer mBuffer; + LodInputBuffer mBuffer; - typedef vector::type VertexLookupList; - // This helps to find the vertex* in LodData for index buffer indices - VertexLookupList mSharedVertexLookup; - VertexLookupList mVertexLookup; - + typedef vector::type VertexLookupList; + // This helps to find the vertex* in LodData for index buffer indices + VertexLookupList mSharedVertexLookup; + VertexLookupList mVertexLookup; + - void tuneContainerSize(LodData* data); - void initialize(LodData* data); - void addVertexData(LodData* data, LodVertexBuffer& vertexBuffer, bool useSharedVertexLookup); - void addIndexData(LodData* data, LodIndexBuffer& indexBuffer, bool useSharedVertexLookup, unsigned short submeshID); - template - void addIndexDataImpl(LodData* data, IndexType* iPos, const IndexType* iEnd, VertexLookupList& lookup, unsigned short submeshID) - { - // Loop through all triangles and connect them to the vertices. - for (; iPos < iEnd; iPos += 3) { - // It should never reallocate or every pointer will be invalid. - OgreAssert(data->mTriangleList.capacity() > data->mTriangleList.size(), ""); - data->mTriangleList.push_back(LodData::Triangle()); - LodData::Triangle* tri = &data->mTriangleList.back(); - tri->isRemoved = false; - tri->submeshID = submeshID; - for (int i = 0; i < 3; i++) { - // Invalid index: Index is bigger then vertex buffer size. - OgreAssert(iPos[i] < lookup.size(), ""); - tri->vertexID[i] = iPos[i]; - tri->vertex[i] = lookup[iPos[i]]; - } - if (tri->isMalformed()) { + void tuneContainerSize(LodData* data); + void initialize(LodData* data); + void addVertexData(LodData* data, LodVertexBuffer& vertexBuffer, bool useSharedVertexLookup); + void addIndexData(LodData* data, LodIndexBuffer& indexBuffer, bool useSharedVertexLookup, unsigned short submeshID); + template + void addIndexDataImpl(LodData* data, IndexType* iPos, const IndexType* iEnd, VertexLookupList& lookup, unsigned short submeshID) + { + // Loop through all triangles and connect them to the vertices. + for (; iPos < iEnd; iPos += 3) { + // It should never reallocate or every pointer will be invalid. + OgreAssert(data->mTriangleList.capacity() > data->mTriangleList.size(), ""); + data->mTriangleList.push_back(LodData::Triangle()); + LodData::Triangle* tri = &data->mTriangleList.back(); + tri->isRemoved = false; + tri->submeshID = submeshID; + for (int i = 0; i < 3; i++) { + // Invalid index: Index is bigger then vertex buffer size. + OgreAssert(iPos[i] < lookup.size(), ""); + tri->vertexID[i] = iPos[i]; + tri->vertex[i] = lookup[iPos[i]]; + } + if (tri->isMalformed()) { #if OGRE_DEBUG_MODE - stringstream str; - str << "In " << data->mMeshName << " malformed triangle found with ID: " << LodData::getVectorIDFromPointer(data->mTriangleList, tri) << ". " << + stringstream str; + str << "In " << data->mMeshName << " malformed triangle found with ID: " << LodData::getVectorIDFromPointer(data->mTriangleList, tri) << ". " << std::endl; - printTriangle(tri, str); - str << "It will be excluded from Lod level calculations."; - LogManager::getSingleton().stream() << str.str(); + printTriangle(tri, str); + str << "It will be excluded from Lod level calculations."; + LogManager::getSingleton().stream() << str.str(); #endif - tri->isRemoved = true; - data->mIndexBufferInfoList[tri->submeshID].indexCount -= 3; - continue; - } - tri->computeNormal(); - addTriangleToEdges(data, tri); - } - } + tri->isRemoved = true; + data->mIndexBufferInfoList[tri->submeshID].indexCount -= 3; + continue; + } + tri->computeNormal(); + addTriangleToEdges(data, tri); + } + } }; } diff --git a/Components/MeshLodGenerator/include/OgreLodInputProviderMesh.h b/Components/MeshLodGenerator/include/OgreLodInputProviderMesh.h index 8747a7f015a..78150ea7733 100644 --- a/Components/MeshLodGenerator/include/OgreLodInputProviderMesh.h +++ b/Components/MeshLodGenerator/include/OgreLodInputProviderMesh.h @@ -40,60 +40,60 @@ namespace Ogre { class _OgreLodExport LodInputProviderMesh : - public LodInputProvider + public LodInputProvider { public: - LodInputProviderMesh(MeshPtr mesh); - /// Called when the data should be filled with the input. - virtual void initData(LodData* data); - + LodInputProviderMesh(MeshPtr mesh); + /// Called when the data should be filled with the input. + virtual void initData(LodData* data); + protected: - typedef vector::type VertexLookupList; - // This helps to find the vertex* in LodData for index buffer indices - VertexLookupList mSharedVertexLookup; - VertexLookupList mVertexLookup; - MeshPtr mMesh; + typedef vector::type VertexLookupList; + // This helps to find the vertex* in LodData for index buffer indices + VertexLookupList mSharedVertexLookup; + VertexLookupList mVertexLookup; + MeshPtr mMesh; - void tuneContainerSize(LodData* data); - void initialize(LodData* data); - void addIndexData(LodData* data, IndexData* indexData, bool useSharedVertexLookup, unsigned short submeshID); - void addVertexData(LodData* data, VertexData* vertexData, bool useSharedVertexLookup); - template - void addIndexDataImpl(LodData* data, IndexType* iPos, const IndexType* iEnd, + void tuneContainerSize(LodData* data); + void initialize(LodData* data); + void addIndexData(LodData* data, IndexData* indexData, bool useSharedVertexLookup, unsigned short submeshID); + void addVertexData(LodData* data, VertexData* vertexData, bool useSharedVertexLookup); + template + void addIndexDataImpl(LodData* data, IndexType* iPos, const IndexType* iEnd, VertexLookupList& lookup, unsigned short submeshID) - { - // Loop through all triangles and connect them to the vertices. - for (; iPos < iEnd; iPos += 3) { - // It should never reallocate or every pointer will be invalid. - OgreAssert(data->mTriangleList.capacity() > data->mTriangleList.size(), ""); - data->mTriangleList.push_back(LodData::Triangle()); - LodData::Triangle* tri = &data->mTriangleList.back(); - tri->isRemoved = false; - tri->submeshID = submeshID; - for (int i = 0; i < 3; i++) { - // Invalid index: Index is bigger then vertex buffer size. - OgreAssert(iPos[i] < lookup.size(), ""); - tri->vertexID[i] = iPos[i]; - tri->vertex[i] = lookup[iPos[i]]; - } - if (tri->isMalformed()) { + { + // Loop through all triangles and connect them to the vertices. + for (; iPos < iEnd; iPos += 3) { + // It should never reallocate or every pointer will be invalid. + OgreAssert(data->mTriangleList.capacity() > data->mTriangleList.size(), ""); + data->mTriangleList.push_back(LodData::Triangle()); + LodData::Triangle* tri = &data->mTriangleList.back(); + tri->isRemoved = false; + tri->submeshID = submeshID; + for (int i = 0; i < 3; i++) { + // Invalid index: Index is bigger then vertex buffer size. + OgreAssert(iPos[i] < lookup.size(), ""); + tri->vertexID[i] = iPos[i]; + tri->vertex[i] = lookup[iPos[i]]; + } + if (tri->isMalformed()) { #if OGRE_DEBUG_MODE - stringstream str; - str << "In " << data->mMeshName << " malformed triangle found with ID: " << LodData::getVectorIDFromPointer(data->mTriangleList, tri) << ". " << + stringstream str; + str << "In " << data->mMeshName << " malformed triangle found with ID: " << LodData::getVectorIDFromPointer(data->mTriangleList, tri) << ". " << std::endl; - printTriangle(tri, str); - str << "It will be excluded from Lod level calculations."; - LogManager::getSingleton().stream() << str.str(); + printTriangle(tri, str); + str << "It will be excluded from Lod level calculations."; + LogManager::getSingleton().stream() << str.str(); #endif - tri->isRemoved = true; - data->mIndexBufferInfoList[tri->submeshID].indexCount -= 3; - continue; - } - tri->computeNormal(); - addTriangleToEdges(data, tri); - } - } + tri->isRemoved = true; + data->mIndexBufferInfoList[tri->submeshID].indexCount -= 3; + continue; + } + tri->computeNormal(); + addTriangleToEdges(data, tri); + } + } }; } diff --git a/Components/MeshLodGenerator/include/OgreLodOutputProvider.h b/Components/MeshLodGenerator/include/OgreLodOutputProvider.h index df2cd508d8b..a802b71ac87 100644 --- a/Components/MeshLodGenerator/include/OgreLodOutputProvider.h +++ b/Components/MeshLodGenerator/include/OgreLodOutputProvider.h @@ -38,14 +38,14 @@ namespace Ogre class _OgreLodExport LodOutputProvider { public: - virtual ~LodOutputProvider() {} - virtual void prepare(LodData* data) = 0; - virtual void finalize(LodData* data) = 0; - virtual void bakeManualLodLevel(LodData* data, String& manualMeshName, int lodIndex) = 0; - virtual void bakeLodLevel(LodData* data, int lodIndex) = 0; - virtual void triangleRemoved(LodData* data, LodData::Triangle* tri){} - virtual void triangleChanged(LodData* data, LodData::Triangle* tri){} - virtual void inject(){} + virtual ~LodOutputProvider() {} + virtual void prepare(LodData* data) = 0; + virtual void finalize(LodData* data) = 0; + virtual void bakeManualLodLevel(LodData* data, String& manualMeshName, int lodIndex) = 0; + virtual void bakeLodLevel(LodData* data, int lodIndex) = 0; + virtual void triangleRemoved(LodData* data, LodData::Triangle* tri){} + virtual void triangleChanged(LodData* data, LodData::Triangle* tri){} + virtual void inject(){} }; } #endif diff --git a/Components/MeshLodGenerator/include/OgreLodOutputProviderBuffer.h b/Components/MeshLodGenerator/include/OgreLodOutputProviderBuffer.h index 5ba10b7e473..bff528dc769 100644 --- a/Components/MeshLodGenerator/include/OgreLodOutputProviderBuffer.h +++ b/Components/MeshLodGenerator/include/OgreLodOutputProviderBuffer.h @@ -38,19 +38,19 @@ namespace Ogre { class _OgreLodExport LodOutputProviderBuffer : - public LodOutputProvider + public LodOutputProvider { public: - LodOutputProviderBuffer(MeshPtr mesh) : mMesh(mesh) {} - virtual void prepare(LodData* data); - virtual void finalize(LodData* data) {} - virtual void bakeManualLodLevel(LodData* data, String& manualMeshName, int lodIndex); - virtual void bakeLodLevel(LodData* data, int lodIndex); - virtual void inject(); - LodOutputBuffer& getBuffer(); + LodOutputProviderBuffer(MeshPtr mesh) : mMesh(mesh) {} + virtual void prepare(LodData* data); + virtual void finalize(LodData* data) {} + virtual void bakeManualLodLevel(LodData* data, String& manualMeshName, int lodIndex); + virtual void bakeLodLevel(LodData* data, int lodIndex); + virtual void inject(); + LodOutputBuffer& getBuffer(); protected: - MeshPtr mMesh; - LodOutputBuffer mBuffer; + MeshPtr mMesh; + LodOutputBuffer mBuffer; }; } diff --git a/Components/MeshLodGenerator/include/OgreLodOutputProviderCompressedBuffer.h b/Components/MeshLodGenerator/include/OgreLodOutputProviderCompressedBuffer.h index aa620bca6e3..5fe58d35a72 100644 --- a/Components/MeshLodGenerator/include/OgreLodOutputProviderCompressedBuffer.h +++ b/Components/MeshLodGenerator/include/OgreLodOutputProviderCompressedBuffer.h @@ -37,14 +37,14 @@ namespace Ogre { class _OgreLodExport LodOutputProviderCompressedBuffer : - public LodOutputProviderCompressedMesh + public LodOutputProviderCompressedMesh { public: - LodOutputProviderCompressedBuffer(MeshPtr mesh); + LodOutputProviderCompressedBuffer(MeshPtr mesh); protected: - virtual void bakeFirstPass(LodData* data, int lodIndex); - virtual void bakeSecondPass(LodData* data, int lodIndex); + virtual void bakeFirstPass(LodData* data, int lodIndex); + virtual void bakeSecondPass(LodData* data, int lodIndex); }; } diff --git a/Components/MeshLodGenerator/include/OgreLodOutputProviderCompressedMesh.h b/Components/MeshLodGenerator/include/OgreLodOutputProviderCompressedMesh.h index 163be88e198..780878b8331 100644 --- a/Components/MeshLodGenerator/include/OgreLodOutputProviderCompressedMesh.h +++ b/Components/MeshLodGenerator/include/OgreLodOutputProviderCompressedMesh.h @@ -38,46 +38,46 @@ namespace Ogre { class _OgreLodExport LodOutputProviderCompressedMesh : - public LodOutputProvider + public LodOutputProvider { public: - LodOutputProviderCompressedMesh(MeshPtr mesh); - ~LodOutputProviderCompressedMesh(); - virtual void prepare(LodData* data); - virtual void finalize(LodData* data); - virtual void bakeManualLodLevel(LodData* data, String& manualMeshName, int lodIndex); - virtual void bakeLodLevel(LodData* data, int lodIndex); - virtual void inject(); + LodOutputProviderCompressedMesh(MeshPtr mesh); + ~LodOutputProviderCompressedMesh(); + virtual void prepare(LodData* data); + virtual void finalize(LodData* data); + virtual void bakeManualLodLevel(LodData* data, String& manualMeshName, int lodIndex); + virtual void bakeLodLevel(LodData* data, int lodIndex); + virtual void inject(); - virtual void triangleRemoved(LodData* data, LodData::Triangle* tri); - virtual void triangleChanged(LodData* data, LodData::Triangle* tri); + virtual void triangleRemoved(LodData* data, LodData::Triangle* tri); + virtual void triangleChanged(LodData* data, LodData::Triangle* tri); protected: - LodOutputProviderCompressedMesh(); + LodOutputProviderCompressedMesh(); - struct TriangleCache { - unsigned int vertexID[3]; - bool vertexChanged; - }; + struct TriangleCache { + unsigned int vertexID[3]; + bool vertexChanged; + }; - typedef vector::type TriangleCacheList; + typedef vector::type TriangleCacheList; - /// First pass will create the mTriangleCacheList and second pass will use it. - /// This is required, because the triangles from first pass will be changed and we need to keep the information. - TriangleCacheList mTriangleCacheList; + /// First pass will create the mTriangleCacheList and second pass will use it. + /// This is required, because the triangles from first pass will be changed and we need to keep the information. + TriangleCacheList mTriangleCacheList; - /// Lod index of the buffer for mTriangleCacheList. - bool mFirstBufferPass; + /// Lod index of the buffer for mTriangleCacheList. + bool mFirstBufferPass; - /// if uneven lod levels are created, we need to fall back for the last lod level. - LodOutputProvider* fallback; - MeshPtr mMesh; + /// if uneven lod levels are created, we need to fall back for the last lod level. + LodOutputProvider* fallback; + MeshPtr mMesh; - int mLastIndexBufferID; + int mLastIndexBufferID; - virtual void bakeFirstPass(LodData* data, int lodIndex); - virtual void bakeSecondPass(LodData* data, int lodIndex); + virtual void bakeFirstPass(LodData* data, int lodIndex); + virtual void bakeSecondPass(LodData* data, int lodIndex); }; } diff --git a/Components/MeshLodGenerator/include/OgreLodOutputProviderMesh.h b/Components/MeshLodGenerator/include/OgreLodOutputProviderMesh.h index 319a0b04650..80c616d4ab4 100644 --- a/Components/MeshLodGenerator/include/OgreLodOutputProviderMesh.h +++ b/Components/MeshLodGenerator/include/OgreLodOutputProviderMesh.h @@ -38,16 +38,16 @@ namespace Ogre { class _OgreLodExport LodOutputProviderMesh : - public LodOutputProvider + public LodOutputProvider { public: - LodOutputProviderMesh(MeshPtr mesh) : mMesh(mesh) {} - virtual void prepare(LodData* data); - virtual void finalize(LodData* data) {} - virtual void bakeManualLodLevel(LodData* data, String& manualMeshName, int lodIndex); - virtual void bakeLodLevel(LodData* data, int lodIndex); + LodOutputProviderMesh(MeshPtr mesh) : mMesh(mesh) {} + virtual void prepare(LodData* data); + virtual void finalize(LodData* data) {} + virtual void bakeManualLodLevel(LodData* data, String& manualMeshName, int lodIndex); + virtual void bakeLodLevel(LodData* data, int lodIndex); protected: - MeshPtr mMesh; + MeshPtr mMesh; }; } diff --git a/Components/MeshLodGenerator/include/OgreLodOutsideMarker.h b/Components/MeshLodGenerator/include/OgreLodOutsideMarker.h index feb696293d4..2fca2119e5f 100644 --- a/Components/MeshLodGenerator/include/OgreLodOutsideMarker.h +++ b/Components/MeshLodGenerator/include/OgreLodOutsideMarker.h @@ -1,123 +1,123 @@ -/* ------------------------------------------------------------------------------ -This source file is part of OGRE -(Object-oriented Graphics Rendering Engine) -For the latest info, see http://www.ogre3d.org - -Copyright (c) 2000-2014 Torus Knot Software Ltd - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. ------------------------------------------------------------------------------ -*/ -#ifndef __OutsideMarker_H__ -#define __OutsideMarker_H__ - -#include "OgreLodPrerequisites.h" -#include "OgreLodData.h" -#include "OgreResourceGroupManager.h" - -namespace Ogre -{ -/// This class will mark vertices of a mesh, which are visible from far away (from outside). -/// Triangle is visible if each vertex of it is visible. -class _OgreLodExport LodOutsideMarker -{ -public: - /** - * @param vertexList List of vertices. vertex.position is the input and vertex.isOuterWallVertex is the output of the algorithm. - * @param walkAngle Walk angle in dot product values. Allowed range is from -1 to 1. Default = 0. Smaller value is bigger angle. - * If you set it to 1 then you can disable walking and it will only mark the vertices on the convex hull. - */ - LodOutsideMarker(LodData::VertexList & vertexList, Real boundingSphereRadius, Real walkAngle); - void markOutside(); /// Mark vertices, which are visible from outside. - MeshPtr createConvexHullMesh(const String& meshName, - const String& resourceGroupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); /// Returns a mesh containing the Convex Hull shape. - - bool isVertexOutside(LodData::Vertex* v) { - return getOutsideData(v)->isOuterWallVertex; - } - -private: - typedef LodData::Vertex CHVertex; - - struct CHTriangle { - bool removed; // Whether the triangle is excluded from hull. - CHVertex* vertex[3]; - Vector3 normal; - void computeNormal(); - }; - - - struct OutsideData - { - bool isOuterWallVertex; - bool isOuterWallVertexInPass; - bool isInsideHull; - }; - - typedef vector::type OutsideDataList; - typedef vector::type CHTriangleList; - typedef vector::type CHTrianglePList; - typedef vector >::type CHEdgeList; - - - - - const Real mEpsilon; /// Amount of allowed floating point error if 4 vertices are on the same plane. - CHTriangleList mHull; /// Contains the current triangles of the convex hull. - CHTrianglePList mVisibleTriangles; /// Temporary vector for addVisibleEdges function (prevent allocation every call). - CHEdgeList mEdges; /// Temporary vector for the horizon edges, when inserting a new vertex into the hull. - LodData::VertexList& mVertexListOrig; /// Source of input and output of the algorithm. - - OutsideDataList mOutsideData; - Vector3 mCentroid; /// Centroid of the convex hull. - Real mWalkAngle; /// Angle limit, when walking inside for marking vertices. - - LodData::Vertex* getVertex(OutsideData* d) { - return &mVertexListOrig[LodData::getVectorIDFromPointer(mOutsideData, d)]; - } - OutsideData* getOutsideData(LodData::Vertex* v) { - return &mOutsideData[LodData::getVectorIDFromPointer(mVertexListOrig, v)]; - } - - void initHull(); /// Initializes the hull for expansion. - void createTriangle(CHVertex* v1, CHVertex* v2, CHVertex* v3); /// Sets the vertices of a triangle (called from initHull only). - Real getTetrahedronVolume(CHVertex* v0, CHVertex* v1, CHVertex* v2, CHVertex* v3); - Real getPointToLineSqraredDistance(CHVertex* x1, CHVertex* x2, CHVertex* vertex); - void generateHull(); /// Generates the hull. - size_t addVertex(CHVertex* vertex); /// Adds vertex to hull. - void addEdge(CHEdgeList& edges, CHVertex* a, CHVertex* b); /// Add edge to the list of removable edges. - void cleanHull(); /// Removes Triangles, which are having CHTriangle::removed = true. - bool isVisible(CHTriangle* triangle, Vector3& vertex); /// Whether face is visible from point. - CHVertex* getFurthestVertex(CHTriangle* hull); /// Gets furthest vertex from face. - void getVisibleTriangles(const CHVertex* target, CHTrianglePList& visibleTriangles); /// Adds visible edges to the list, when viewing from target point. - void getHorizon(const CHTrianglePList& tri, CHEdgeList& ); /// Removes edges, which are not on the horizon. - void fillHorizon(CHEdgeList& e, CHVertex* target); /// Caps the hole with faces connecting to target vertex. - void markVertices(); /// if we have the convex hull, this will walk on the faces which have less then 90 degree difference. - template - void addHullTriangleVertices(std::vector& stack, T tri); /// Add triangle to stack (called from markVertices only). - /// Determines whether ptarget is on the same side of the p0-p1 line as p2. Assuming each point is on the same plane. - Real pointToLineDir(const Vector3& ptarget, const Vector3& p0, const Vector3& p1, const Vector3& p2, const Vector3& n); - bool isInsideTriangle(const Vector3& ptarget, const CHTriangle& tri); /// Whether the vertex is inside the triangle. We assume that it is on the same plane - bool isInsideLine(const Vector3& ptarget, const Vector3& p0, const Vector3& p1); /// Whether ptarget is between p0 and p1. Assuming they are on the same line. - bool isSamePosition(const Vector3& p0, const Vector3& p1); /// Whether p0 = p1 with mEpsilon allowed float error. -}; -} - +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org + +Copyright (c) 2000-2014 Torus Knot Software Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ +#ifndef __OutsideMarker_H__ +#define __OutsideMarker_H__ + +#include "OgreLodPrerequisites.h" +#include "OgreLodData.h" +#include "OgreResourceGroupManager.h" + +namespace Ogre +{ +/// This class will mark vertices of a mesh, which are visible from far away (from outside). +/// Triangle is visible if each vertex of it is visible. +class _OgreLodExport LodOutsideMarker +{ +public: + /** + * @param vertexList List of vertices. vertex.position is the input and vertex.isOuterWallVertex is the output of the algorithm. + * @param walkAngle Walk angle in dot product values. Allowed range is from -1 to 1. Default = 0. Smaller value is bigger angle. + * If you set it to 1 then you can disable walking and it will only mark the vertices on the convex hull. + */ + LodOutsideMarker(LodData::VertexList & vertexList, Real boundingSphereRadius, Real walkAngle); + void markOutside(); /// Mark vertices, which are visible from outside. + MeshPtr createConvexHullMesh(const String& meshName, + const String& resourceGroupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); /// Returns a mesh containing the Convex Hull shape. + + bool isVertexOutside(LodData::Vertex* v) { + return getOutsideData(v)->isOuterWallVertex; + } + +private: + typedef LodData::Vertex CHVertex; + + struct CHTriangle { + bool removed; // Whether the triangle is excluded from hull. + CHVertex* vertex[3]; + Vector3 normal; + void computeNormal(); + }; + + + struct OutsideData + { + bool isOuterWallVertex; + bool isOuterWallVertexInPass; + bool isInsideHull; + }; + + typedef vector::type OutsideDataList; + typedef vector::type CHTriangleList; + typedef vector::type CHTrianglePList; + typedef vector >::type CHEdgeList; + + + + + const Real mEpsilon; /// Amount of allowed floating point error if 4 vertices are on the same plane. + CHTriangleList mHull; /// Contains the current triangles of the convex hull. + CHTrianglePList mVisibleTriangles; /// Temporary vector for addVisibleEdges function (prevent allocation every call). + CHEdgeList mEdges; /// Temporary vector for the horizon edges, when inserting a new vertex into the hull. + LodData::VertexList& mVertexListOrig; /// Source of input and output of the algorithm. + + OutsideDataList mOutsideData; + Vector3 mCentroid; /// Centroid of the convex hull. + Real mWalkAngle; /// Angle limit, when walking inside for marking vertices. + + LodData::Vertex* getVertex(OutsideData* d) { + return &mVertexListOrig[LodData::getVectorIDFromPointer(mOutsideData, d)]; + } + OutsideData* getOutsideData(LodData::Vertex* v) { + return &mOutsideData[LodData::getVectorIDFromPointer(mVertexListOrig, v)]; + } + + void initHull(); /// Initializes the hull for expansion. + void createTriangle(CHVertex* v1, CHVertex* v2, CHVertex* v3); /// Sets the vertices of a triangle (called from initHull only). + Real getTetrahedronVolume(CHVertex* v0, CHVertex* v1, CHVertex* v2, CHVertex* v3); + Real getPointToLineSqraredDistance(CHVertex* x1, CHVertex* x2, CHVertex* vertex); + void generateHull(); /// Generates the hull. + size_t addVertex(CHVertex* vertex); /// Adds vertex to hull. + void addEdge(CHEdgeList& edges, CHVertex* a, CHVertex* b); /// Add edge to the list of removable edges. + void cleanHull(); /// Removes Triangles, which are having CHTriangle::removed = true. + bool isVisible(CHTriangle* triangle, Vector3& vertex); /// Whether face is visible from point. + CHVertex* getFurthestVertex(CHTriangle* hull); /// Gets furthest vertex from face. + void getVisibleTriangles(const CHVertex* target, CHTrianglePList& visibleTriangles); /// Adds visible edges to the list, when viewing from target point. + void getHorizon(const CHTrianglePList& tri, CHEdgeList& ); /// Removes edges, which are not on the horizon. + void fillHorizon(CHEdgeList& e, CHVertex* target); /// Caps the hole with faces connecting to target vertex. + void markVertices(); /// if we have the convex hull, this will walk on the faces which have less then 90 degree difference. + template + void addHullTriangleVertices(std::vector& stack, T tri); /// Add triangle to stack (called from markVertices only). + /// Determines whether ptarget is on the same side of the p0-p1 line as p2. Assuming each point is on the same plane. + Real pointToLineDir(const Vector3& ptarget, const Vector3& p0, const Vector3& p1, const Vector3& p2, const Vector3& n); + bool isInsideTriangle(const Vector3& ptarget, const CHTriangle& tri); /// Whether the vertex is inside the triangle. We assume that it is on the same plane + bool isInsideLine(const Vector3& ptarget, const Vector3& p0, const Vector3& p1); /// Whether ptarget is between p0 and p1. Assuming they are on the same line. + bool isSamePosition(const Vector3& p0, const Vector3& p1); /// Whether p0 = p1 with mEpsilon allowed float error. +}; +} + #endif /* ifndef __OutsideMarker_H__ */ \ No newline at end of file diff --git a/Components/MeshLodGenerator/include/OgreLodPrerequisites.h b/Components/MeshLodGenerator/include/OgreLodPrerequisites.h index 03e7ea84437..a99b180bc33 100644 --- a/Components/MeshLodGenerator/include/OgreLodPrerequisites.h +++ b/Components/MeshLodGenerator/include/OgreLodPrerequisites.h @@ -33,33 +33,33 @@ THE SOFTWARE. namespace Ogre { - // forward decls - class LodCollapseCost; - class LodCollapseCostCurvature; - class LodCollapseCostOutside; - class LodCollapseCostProfiler; + // forward decls + class LodCollapseCost; + class LodCollapseCostCurvature; + class LodCollapseCostOutside; + class LodCollapseCostProfiler; - class LodInputProvider; - class LodInputProviderMesh; - class LodInputProviderBuffer; - class LodOutputProvider; - class LodOutputProviderMesh; - class LodOutputProviderCompressedMesh; - class LodOutputProviderBuffer; - class LodOutputProviderCompressedBuffer; - class LodOutsideMarker; + class LodInputProvider; + class LodInputProviderMesh; + class LodInputProviderBuffer; + class LodOutputProvider; + class LodOutputProviderMesh; + class LodOutputProviderCompressedMesh; + class LodOutputProviderBuffer; + class LodOutputProviderCompressedBuffer; + class LodOutsideMarker; - class LodCollapser; - struct LodConfig; - struct LodLevel; - class LodConfigSerializer; - class MeshLodGenerator; - class LodWorkQueueWorker; - class LodWorkQueueInjector; - struct LodWorkQueueRequest; - class LodWorkQueueInjectorListener; - struct LodData; + class LodCollapser; + struct LodConfig; + struct LodLevel; + class LodConfigSerializer; + class MeshLodGenerator; + class LodWorkQueueWorker; + class LodWorkQueueInjector; + struct LodWorkQueueRequest; + class LodWorkQueueInjectorListener; + struct LodData; typedef SharedPtr LodCollapseCostPtr; typedef SharedPtr LodCollapserPtr; @@ -67,27 +67,27 @@ namespace Ogre typedef SharedPtr LodInputProviderPtr; typedef SharedPtr LodOutputProviderPtr; - typedef GeneralAllocatedObject MeshLodAlloc; + typedef GeneralAllocatedObject MeshLodAlloc; } #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT -# if defined( OGRE_STATIC_LIB ) -# define _OgreLodExport +# if defined( OGRE_STATIC_LIB ) +# define _OgreLodExport # else -# if defined( OGRE_MESHLODGENERATOR_EXPORTS ) -# define _OgreLodExport __declspec( dllexport ) -# else +# if defined( OGRE_MESHLODGENERATOR_EXPORTS ) +# define _OgreLodExport __declspec( dllexport ) +# else # if defined( __MINGW32__ ) # define _OgreLodExport # else -# define _OgreLodExport __declspec( dllimport ) +# define _OgreLodExport __declspec( dllimport ) # endif -# endif -# endif +# endif +# endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgreLodExport __attribute__ ((visibility("default"))) #else -# define _OgreLodExport +# define _OgreLodExport #endif #endif diff --git a/Components/MeshLodGenerator/include/OgreLodWorkQueueInjector.h b/Components/MeshLodGenerator/include/OgreLodWorkQueueInjector.h index 078cb0db99a..9a94ce2e4a2 100644 --- a/Components/MeshLodGenerator/include/OgreLodWorkQueueInjector.h +++ b/Components/MeshLodGenerator/include/OgreLodWorkQueueInjector.h @@ -40,23 +40,23 @@ namespace Ogre * @brief Injects the output of a request to the mesh in a thread safe way. */ class _OgreLodExport LodWorkQueueInjector : - public WorkQueue::ResponseHandler, - public Singleton + public WorkQueue::ResponseHandler, + public Singleton { public: - LodWorkQueueInjector(); - virtual ~LodWorkQueueInjector(); - - static LodWorkQueueInjector* getSingletonPtr(); - static LodWorkQueueInjector& getSingleton(); + LodWorkQueueInjector(); + virtual ~LodWorkQueueInjector(); + + static LodWorkQueueInjector* getSingletonPtr(); + static LodWorkQueueInjector& getSingleton(); - void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - void setInjectorListener(LodWorkQueueInjectorListener* injectorListener) {mInjectorListener = injectorListener;} - LodWorkQueueInjectorListener* getInjectorListener() {return mInjectorListener;} - void removeInjectorListener() {mInjectorListener = 0;} + void setInjectorListener(LodWorkQueueInjectorListener* injectorListener) {mInjectorListener = injectorListener;} + LodWorkQueueInjectorListener* getInjectorListener() {return mInjectorListener;} + void removeInjectorListener() {mInjectorListener = 0;} protected: - LodWorkQueueInjectorListener* mInjectorListener; + LodWorkQueueInjectorListener* mInjectorListener; }; } diff --git a/Components/MeshLodGenerator/include/OgreLodWorkQueueInjectorListener.h b/Components/MeshLodGenerator/include/OgreLodWorkQueueInjectorListener.h index a999117e367..c787c567f63 100644 --- a/Components/MeshLodGenerator/include/OgreLodWorkQueueInjectorListener.h +++ b/Components/MeshLodGenerator/include/OgreLodWorkQueueInjectorListener.h @@ -37,10 +37,10 @@ namespace Ogre class _OgreLodExport LodWorkQueueInjectorListener { public: - LodWorkQueueInjectorListener(){} - virtual ~LodWorkQueueInjectorListener(){} - virtual bool shouldInject(LodWorkQueueRequest* request) = 0; - virtual void injectionCompleted(LodWorkQueueRequest* request) = 0; + LodWorkQueueInjectorListener(){} + virtual ~LodWorkQueueInjectorListener(){} + virtual bool shouldInject(LodWorkQueueRequest* request) = 0; + virtual void injectionCompleted(LodWorkQueueRequest* request) = 0; }; } diff --git a/Components/MeshLodGenerator/include/OgreLodWorkQueueRequest.h b/Components/MeshLodGenerator/include/OgreLodWorkQueueRequest.h index d5dca2a69ed..7e8b3f28dde 100644 --- a/Components/MeshLodGenerator/include/OgreLodWorkQueueRequest.h +++ b/Components/MeshLodGenerator/include/OgreLodWorkQueueRequest.h @@ -40,12 +40,12 @@ namespace Ogre { struct _OgreLodExport LodWorkQueueRequest { - LodConfig config; - LodDataPtr data; - LodInputProviderPtr input; - LodOutputProviderPtr output; - LodCollapseCostPtr cost; - LodCollapserPtr collapser; + LodConfig config; + LodDataPtr data; + LodInputProviderPtr input; + LodOutputProviderPtr output; + LodCollapseCostPtr cost; + LodCollapserPtr collapser; }; } diff --git a/Components/MeshLodGenerator/include/OgreLodWorkQueueWorker.h b/Components/MeshLodGenerator/include/OgreLodWorkQueueWorker.h index 6031befc4c9..7f097a3ccf9 100644 --- a/Components/MeshLodGenerator/include/OgreLodWorkQueueWorker.h +++ b/Components/MeshLodGenerator/include/OgreLodWorkQueueWorker.h @@ -40,24 +40,24 @@ namespace Ogre * @brief Processes requests. */ class _OgreLodExport LodWorkQueueWorker : - private WorkQueue::RequestHandler, - public Singleton + private WorkQueue::RequestHandler, + public Singleton { public: - LodWorkQueueWorker(); - virtual ~LodWorkQueueWorker(); + LodWorkQueueWorker(); + virtual ~LodWorkQueueWorker(); - static LodWorkQueueWorker* getSingletonPtr(); - static LodWorkQueueWorker& getSingleton(); + static LodWorkQueueWorker* getSingletonPtr(); + static LodWorkQueueWorker& getSingleton(); - void addRequestToQueue(LodWorkQueueRequest* request); - void addRequestToQueue(LodConfig& lodConfig, LodCollapseCostPtr& cost, LodDataPtr& data, LodInputProviderPtr& input, LodOutputProviderPtr& output, LodCollapserPtr& collapser); + void addRequestToQueue(LodWorkQueueRequest* request); + void addRequestToQueue(LodConfig& lodConfig, LodCollapseCostPtr& cost, LodDataPtr& data, LodInputProviderPtr& input, LodOutputProviderPtr& output, LodCollapserPtr& collapser); - void clearPendingLodRequests(); + void clearPendingLodRequests(); protected: - ushort mChannelID; - WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + ushort mChannelID; + WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); }; } #endif diff --git a/Components/MeshLodGenerator/include/OgreMeshLodGenerator.h b/Components/MeshLodGenerator/include/OgreMeshLodGenerator.h index b37724a2535..1a0a38f46a4 100644 --- a/Components/MeshLodGenerator/include/OgreMeshLodGenerator.h +++ b/Components/MeshLodGenerator/include/OgreMeshLodGenerator.h @@ -1,98 +1,98 @@ -/* - * ----------------------------------------------------------------------------- - * This source file is part of OGRE - * (Object-oriented Graphics Rendering Engine) - * For the latest info, see http://www.ogre3d.org/ - * - * Copyright (c) 2000-2014 Torus Knot Software Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ----------------------------------------------------------------------------- - */ - -#ifndef __MeshLodGenerator_H_ -#define __MeshLodGenerator_H_ - -#include "OgreLodPrerequisites.h" -#include "OgreLodData.h" -#include "OgreLodInputProvider.h" -#include "OgreLodOutputProvider.h" -#include "OgreLodCollapseCost.h" -#include "OgreLodCollapser.h" -#include "OgreSharedPtr.h" -#include "OgreSingleton.h" - -namespace Ogre -{ - -class _OgreLodExport MeshLodGenerator : -public Singleton -{ -public: - - static MeshLodGenerator* getSingletonPtr(); - static MeshLodGenerator& getSingleton(); - - /** - * @brief Generates the Lod levels for a mesh. - */ - MeshLodGenerator(); - virtual ~MeshLodGenerator(); - - /** - * @brief Generates the Lod levels for a mesh. - * - * @param lodConfig Specification of the requested Lod levels. - */ - virtual void generateLodLevels(LodConfig& lodConfig, LodCollapseCostPtr cost = LodCollapseCostPtr(), LodDataPtr data = LodDataPtr(), LodInputProviderPtr input = LodInputProviderPtr(), LodOutputProviderPtr output = LodOutputProviderPtr(), LodCollapserPtr collapser = LodCollapserPtr()); - - /** - * @brief Generates the Lod levels for a mesh without configuring it. - * - * @param mesh Generate the Lod for this mesh. - */ - void generateAutoconfiguredLodLevels(MeshPtr& mesh); - - /** - * @brief Fills Lod Config with a config, which works on any mesh. - * - * @param inMesh Optimize for this mesh. - * @param outLodConfig Lod configuration storing the output. - */ - void getAutoconfig(MeshPtr& inMesh, LodConfig& outLodConfig); - - static void _configureMeshLodUsage(const LodConfig& lodConfig); - void _resolveComponents(LodConfig& lodConfig, LodCollapseCostPtr& cost, LodDataPtr& data, LodInputProviderPtr& input, LodOutputProviderPtr& output, LodCollapserPtr& collapser); - void _process(LodConfig& lodConfig, LodCollapseCost* cost, LodData* data, LodInputProvider* input, LodOutputProvider* output, LodCollapser* collapser); - - /// If you only use manual Lod levels, then you don't need to build LodData mesh representation. - /// This function will generate manual Lod levels without overhead, but every Lod level needs to be a manual Lod level. - void _generateManualLodLevels(LodConfig& lodConfig); - - void _initWorkQueue(); -protected: - void computeLods(LodConfig& lodConfig, LodData* data, LodCollapseCost* cost, LodOutputProvider* output, LodCollapser* collapser); - void calcLodVertexCount(const LodLevel& lodLevel, size_t uniqueVertexCount, size_t& outVertexCountLimit, Real& outCollapseCostLimit); - - LodWorkQueueWorker* mWQWorker; - LodWorkQueueInjector* mWQInjector; -}; - -} -#endif +/* + * ----------------------------------------------------------------------------- + * This source file is part of OGRE + * (Object-oriented Graphics Rendering Engine) + * For the latest info, see http://www.ogre3d.org/ + * + * Copyright (c) 2000-2014 Torus Knot Software Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ----------------------------------------------------------------------------- + */ + +#ifndef __MeshLodGenerator_H_ +#define __MeshLodGenerator_H_ + +#include "OgreLodPrerequisites.h" +#include "OgreLodData.h" +#include "OgreLodInputProvider.h" +#include "OgreLodOutputProvider.h" +#include "OgreLodCollapseCost.h" +#include "OgreLodCollapser.h" +#include "OgreSharedPtr.h" +#include "OgreSingleton.h" + +namespace Ogre +{ + +class _OgreLodExport MeshLodGenerator : +public Singleton +{ +public: + + static MeshLodGenerator* getSingletonPtr(); + static MeshLodGenerator& getSingleton(); + + /** + * @brief Generates the Lod levels for a mesh. + */ + MeshLodGenerator(); + virtual ~MeshLodGenerator(); + + /** + * @brief Generates the Lod levels for a mesh. + * + * @param lodConfig Specification of the requested Lod levels. + */ + virtual void generateLodLevels(LodConfig& lodConfig, LodCollapseCostPtr cost = LodCollapseCostPtr(), LodDataPtr data = LodDataPtr(), LodInputProviderPtr input = LodInputProviderPtr(), LodOutputProviderPtr output = LodOutputProviderPtr(), LodCollapserPtr collapser = LodCollapserPtr()); + + /** + * @brief Generates the Lod levels for a mesh without configuring it. + * + * @param mesh Generate the Lod for this mesh. + */ + void generateAutoconfiguredLodLevels(MeshPtr& mesh); + + /** + * @brief Fills Lod Config with a config, which works on any mesh. + * + * @param inMesh Optimize for this mesh. + * @param outLodConfig Lod configuration storing the output. + */ + void getAutoconfig(MeshPtr& inMesh, LodConfig& outLodConfig); + + static void _configureMeshLodUsage(const LodConfig& lodConfig); + void _resolveComponents(LodConfig& lodConfig, LodCollapseCostPtr& cost, LodDataPtr& data, LodInputProviderPtr& input, LodOutputProviderPtr& output, LodCollapserPtr& collapser); + void _process(LodConfig& lodConfig, LodCollapseCost* cost, LodData* data, LodInputProvider* input, LodOutputProvider* output, LodCollapser* collapser); + + /// If you only use manual Lod levels, then you don't need to build LodData mesh representation. + /// This function will generate manual Lod levels without overhead, but every Lod level needs to be a manual Lod level. + void _generateManualLodLevels(LodConfig& lodConfig); + + void _initWorkQueue(); +protected: + void computeLods(LodConfig& lodConfig, LodData* data, LodCollapseCost* cost, LodOutputProvider* output, LodCollapser* collapser); + void calcLodVertexCount(const LodLevel& lodLevel, size_t uniqueVertexCount, size_t& outVertexCountLimit, Real& outCollapseCostLimit); + + LodWorkQueueWorker* mWQWorker; + LodWorkQueueInjector* mWQInjector; +}; + +} +#endif diff --git a/Components/MeshLodGenerator/include/OgreOutsideMarker.h b/Components/MeshLodGenerator/include/OgreOutsideMarker.h index c705fe9b1c9..c45efb2cd18 100644 --- a/Components/MeshLodGenerator/include/OgreOutsideMarker.h +++ b/Components/MeshLodGenerator/include/OgreOutsideMarker.h @@ -1,101 +1,101 @@ -/* ------------------------------------------------------------------------------ -This source file is part of OGRE -(Object-oriented Graphics Rendering Engine) -For the latest info, see http://www.ogre3d.org - -Copyright (c) 2000-2014 Torus Knot Software Ltd - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. ------------------------------------------------------------------------------ -*/ -#ifndef __OutsideMarker_H__ -#define __OutsideMarker_H__ - -#include "OgreLodPrerequisites.h" -#include "OgreProgressiveMeshGenerator.h" -#include "OgreResourceGroupManager.h" -#include - -namespace Ogre -{ - -/// This class will mark vertices of a mesh, which are visible from far away (from outside). -/// Triangle is visible if each vertex of it is visible. -class _OgreLodExport OutsideMarker -{ -public: - /** - * @param vertexList List of vertices. vertex.position is the input and vertex.isOuterWallVertex is the output of the algorithm. - * @param walkAngle Walk angle in dot product values. Allowed range is from -1 to 1. Default = 0. Smaller value is bigger angle. - * If you set it to 1 then you can disable walking and it will only mark the vertices on the convex hull. - */ - OutsideMarker(ProgressiveMeshGenerator::VertexList & vertexList, Real boundingSphereRadius, Real walkAngle, int step); - void markOutside(); /// Mark vertices, which are visible from outside. - MeshPtr createConvexHullMesh(const String& meshName, - const String& resourceGroupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); /// Returns a mesh containing the Convex Hull shape. - -private: - typedef ProgressiveMeshGenerator::PMVertex CHVertex; - - struct CHTriangle { - bool removed; // Whether the triangle is excluded from hull. - CHVertex* vertex[3]; - Vector3 normal; - void computeNormal(); - }; - - typedef std::vector CHTriangleList; - typedef std::vector CHTrianglePList; - typedef std::vector > CHEdgeList; - - const Real mEpsilon; /// Amount of allowed floating point error if 4 vertices are on the same plane. - CHTriangleList mHull; /// Contains the current triangles of the convex hull. - CHTrianglePList mVisibleTriangles; /// Temporary vector for addVisibleEdges function (prevent allocation every call). - CHEdgeList mEdges; /// Temporary vector for the horizon edges, when inserting a new vertex into the hull. - ProgressiveMeshGenerator::VertexList& mVertexListOrig; /// Source of input and output of the algorithm. - Vector3 mCentroid; /// Centroid of the convex hull. - Real mWalkAngle; /// Angle limit, when walking inside for marking vertices. - int mStep; - - void initHull(); /// Initializes the hull for expansion. - void createTriangle(CHVertex* v1, CHVertex* v2, CHVertex* v3); /// Sets the vertices of a triangle (called from initHull only). - Real getTetrahedronVolume(CHVertex* v0, CHVertex* v1, CHVertex* v2, CHVertex* v3); - Real getPointToLineSqraredDistance(CHVertex* x1, CHVertex* x2, CHVertex* vertex); - void generateHull(); /// Generates the hull. - int addVertex(CHVertex* vertex); /// Adds vertex to hull. - void addEdge(CHEdgeList& edges, CHVertex* a, CHVertex* b); /// Add edge to the list of removable edges. - void cleanHull(); /// Removes Triangles, which are having CHTriangle::removed = true. - bool isVisible(CHTriangle* triangle, Vector3& vertex); /// Whether face is visible from point. - CHVertex* getFurthestVertex(CHTriangle* hull); /// Gets furthest vertex from face. - void getVisibleTriangles(const CHVertex* target, CHTrianglePList& visibleTriangles); /// Adds visible edges to the list, when viewing from target point. - void getHorizon(const CHTrianglePList& tri, CHEdgeList& ); /// Removes edges, which are not on the horizon. - void fillHorizon(CHEdgeList& e, CHVertex* target); /// Caps the hole with faces connecting to target vertex. - void markVertices(); /// if we have the convex hull, this will walk on the faces which have less then 90 degree difference. - template - void addHullTriangleVertices(std::vector& stack, T tri); /// Add triangle to stack (called from markVertices only). - /// Determines whether ptarget is on the same side of the p0-p1 line as p2. Assuming each point is on the same plane. - Real pointToLineDir(const Vector3& ptarget, const Vector3& p0, const Vector3& p1, const Vector3& p2, const Vector3& n); - bool isInsideTriangle(const Vector3& ptarget, const CHTriangle& tri); /// Whether the vertex is inside the triangle. We assume that it is on the same plane - bool isInsideLine(const Vector3& ptarget, const Vector3& p0, const Vector3& p1); /// Whether ptarget is between p0 and p1. Assuming they are on the same line. - bool isSamePosition(const Vector3& p0, const Vector3& p1); /// Whether p0 = p1 with mEpsilon allowed float error. -}; -} - +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org + +Copyright (c) 2000-2014 Torus Knot Software Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ +#ifndef __OutsideMarker_H__ +#define __OutsideMarker_H__ + +#include "OgreLodPrerequisites.h" +#include "OgreProgressiveMeshGenerator.h" +#include "OgreResourceGroupManager.h" +#include + +namespace Ogre +{ + +/// This class will mark vertices of a mesh, which are visible from far away (from outside). +/// Triangle is visible if each vertex of it is visible. +class _OgreLodExport OutsideMarker +{ +public: + /** + * @param vertexList List of vertices. vertex.position is the input and vertex.isOuterWallVertex is the output of the algorithm. + * @param walkAngle Walk angle in dot product values. Allowed range is from -1 to 1. Default = 0. Smaller value is bigger angle. + * If you set it to 1 then you can disable walking and it will only mark the vertices on the convex hull. + */ + OutsideMarker(ProgressiveMeshGenerator::VertexList & vertexList, Real boundingSphereRadius, Real walkAngle, int step); + void markOutside(); /// Mark vertices, which are visible from outside. + MeshPtr createConvexHullMesh(const String& meshName, + const String& resourceGroupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); /// Returns a mesh containing the Convex Hull shape. + +private: + typedef ProgressiveMeshGenerator::PMVertex CHVertex; + + struct CHTriangle { + bool removed; // Whether the triangle is excluded from hull. + CHVertex* vertex[3]; + Vector3 normal; + void computeNormal(); + }; + + typedef std::vector CHTriangleList; + typedef std::vector CHTrianglePList; + typedef std::vector > CHEdgeList; + + const Real mEpsilon; /// Amount of allowed floating point error if 4 vertices are on the same plane. + CHTriangleList mHull; /// Contains the current triangles of the convex hull. + CHTrianglePList mVisibleTriangles; /// Temporary vector for addVisibleEdges function (prevent allocation every call). + CHEdgeList mEdges; /// Temporary vector for the horizon edges, when inserting a new vertex into the hull. + ProgressiveMeshGenerator::VertexList& mVertexListOrig; /// Source of input and output of the algorithm. + Vector3 mCentroid; /// Centroid of the convex hull. + Real mWalkAngle; /// Angle limit, when walking inside for marking vertices. + int mStep; + + void initHull(); /// Initializes the hull for expansion. + void createTriangle(CHVertex* v1, CHVertex* v2, CHVertex* v3); /// Sets the vertices of a triangle (called from initHull only). + Real getTetrahedronVolume(CHVertex* v0, CHVertex* v1, CHVertex* v2, CHVertex* v3); + Real getPointToLineSqraredDistance(CHVertex* x1, CHVertex* x2, CHVertex* vertex); + void generateHull(); /// Generates the hull. + int addVertex(CHVertex* vertex); /// Adds vertex to hull. + void addEdge(CHEdgeList& edges, CHVertex* a, CHVertex* b); /// Add edge to the list of removable edges. + void cleanHull(); /// Removes Triangles, which are having CHTriangle::removed = true. + bool isVisible(CHTriangle* triangle, Vector3& vertex); /// Whether face is visible from point. + CHVertex* getFurthestVertex(CHTriangle* hull); /// Gets furthest vertex from face. + void getVisibleTriangles(const CHVertex* target, CHTrianglePList& visibleTriangles); /// Adds visible edges to the list, when viewing from target point. + void getHorizon(const CHTrianglePList& tri, CHEdgeList& ); /// Removes edges, which are not on the horizon. + void fillHorizon(CHEdgeList& e, CHVertex* target); /// Caps the hole with faces connecting to target vertex. + void markVertices(); /// if we have the convex hull, this will walk on the faces which have less then 90 degree difference. + template + void addHullTriangleVertices(std::vector& stack, T tri); /// Add triangle to stack (called from markVertices only). + /// Determines whether ptarget is on the same side of the p0-p1 line as p2. Assuming each point is on the same plane. + Real pointToLineDir(const Vector3& ptarget, const Vector3& p0, const Vector3& p1, const Vector3& p2, const Vector3& n); + bool isInsideTriangle(const Vector3& ptarget, const CHTriangle& tri); /// Whether the vertex is inside the triangle. We assume that it is on the same plane + bool isInsideLine(const Vector3& ptarget, const Vector3& p0, const Vector3& p1); /// Whether ptarget is between p0 and p1. Assuming they are on the same line. + bool isSamePosition(const Vector3& p0, const Vector3& p1); /// Whether p0 = p1 with mEpsilon allowed float error. +}; +} + #endif /* ifndef __OutsideMarker_H__ */ \ No newline at end of file diff --git a/Components/MeshLodGenerator/include/OgreSmallVector.h b/Components/MeshLodGenerator/include/OgreSmallVector.h index e7bf9129429..db3425eaa07 100644 --- a/Components/MeshLodGenerator/include/OgreSmallVector.h +++ b/Components/MeshLodGenerator/include/OgreSmallVector.h @@ -68,700 +68,700 @@ #ifdef _MSC_VER namespace std { #if _MSC_VER <= 1310 - // Work around flawed VC++ implementation of std::uninitialized_copy. Define - // additional overloads so that elements with pointer types are recognized as - // scalars and not objects, causing bizarre type conversion errors. - template - inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) { - _Scalar_ptr_iterator_tag _Cat; - return _Cat; - } - - template - inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) { - _Scalar_ptr_iterator_tag _Cat; - return _Cat; - } + // Work around flawed VC++ implementation of std::uninitialized_copy. Define + // additional overloads so that elements with pointer types are recognized as + // scalars and not objects, causing bizarre type conversion errors. + template + inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) { + _Scalar_ptr_iterator_tag _Cat; + return _Cat; + } + + template + inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) { + _Scalar_ptr_iterator_tag _Cat; + return _Cat; + } #else - // FIXME: It is not clear if the problem is fixed in VS 2005. What is clear - // is that the above hack won't work if it wasn't fixed. + // FIXME: It is not clear if the problem is fixed in VS 2005. What is clear + // is that the above hack won't work if it wasn't fixed. #endif } #endif namespace Ogre { - + // some type traits - template struct isPodLike { static const bool value = false; }; - - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template <> struct isPodLike { static const bool value = true; }; - template struct isPodLike { static const bool value = true; }; - - template - struct isPodLike > { static const bool value = isPodLike::value & isPodLike::value; }; + template struct isPodLike { static const bool value = false; }; + + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template <> struct isPodLike { static const bool value = true; }; + template struct isPodLike { static const bool value = true; }; + + template + struct isPodLike > { static const bool value = isPodLike::value & isPodLike::value; }; - /// SmallVectorBase - This is all the non-templated stuff common to all - /// SmallVectors. - class SmallVectorBase { - protected: - void *BeginX, *EndX, *CapacityX; - - // Allocate raw space for N elements of type T. If T has a ctor or dtor, we - // don't want it to be automatically run, so we need to represent the space as - // something else. An array of char would work great, but might not be + /// SmallVectorBase - This is all the non-templated stuff common to all + /// SmallVectors. + class SmallVectorBase { + protected: + void *BeginX, *EndX, *CapacityX; + + // Allocate raw space for N elements of type T. If T has a ctor or dtor, we + // don't want it to be automatically run, so we need to represent the space as + // something else. An array of char would work great, but might not be // aligned sufficiently. Instead we use some number of union instances for // the space, which guarantee maximal alignment. union U { - double D; - long double LD; - long long L; - void *P; - } FirstEl; - // Space after 'FirstEl' is clobbered, do not add any instance vars after it. - - protected: - SmallVectorBase(size_t Size) - : BeginX(&FirstEl), EndX(&FirstEl), CapacityX((char*)&FirstEl+Size) {} - - /// isSmall - Return true if this is a smallvector which has not had dynamic - /// memory allocated for it. - bool isSmall() const { - return BeginX == static_cast(&FirstEl); - } - - /// size_in_bytes - This returns size()*sizeof(T). - size_t size_in_bytes() const { - return size_t((char*)EndX - (char*)BeginX); - } - - /// capacity_in_bytes - This returns capacity()*sizeof(T). - size_t capacity_in_bytes() const { - return size_t((char*)CapacityX - (char*)BeginX); - } - - /// grow_pod - This is an implementation of the grow() method which only works + double D; + long double LD; + long long L; + void *P; + } FirstEl; + // Space after 'FirstEl' is clobbered, do not add any instance vars after it. + + protected: + SmallVectorBase(size_t Size) + : BeginX(&FirstEl), EndX(&FirstEl), CapacityX((char*)&FirstEl+Size) {} + + /// isSmall - Return true if this is a smallvector which has not had dynamic + /// memory allocated for it. + bool isSmall() const { + return BeginX == static_cast(&FirstEl); + } + + /// size_in_bytes - This returns size()*sizeof(T). + size_t size_in_bytes() const { + return size_t((char*)EndX - (char*)BeginX); + } + + /// capacity_in_bytes - This returns capacity()*sizeof(T). + size_t capacity_in_bytes() const { + return size_t((char*)CapacityX - (char*)BeginX); + } + + /// grow_pod - This is an implementation of the grow() method which only works /// on POD-like data types and is out of line to reduce code duplication. - void grow_pod(size_t MinSizeInBytes, size_t TSize); - - public: - bool empty() const { return BeginX == EndX; } - }; - - - template - class SmallVectorTemplateCommon : public SmallVectorBase { - protected: - void setEnd(T *P) { this->EndX = P; } - public: - SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(Size) {} - - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T value_type; - typedef T *iterator; - typedef const T *const_iterator; - - typedef std::reverse_iterator const_reverse_iterator; - typedef std::reverse_iterator reverse_iterator; - - typedef T &reference; - typedef const T &const_reference; - typedef T *pointer; - typedef const T *const_pointer; - - // forward iterator creation methods. - iterator begin() { return (iterator)this->BeginX; } - const_iterator begin() const { return (const_iterator)this->BeginX; } - iterator end() { return (iterator)this->EndX; } - const_iterator end() const { return (const_iterator)this->EndX; } - protected: - iterator capacity_ptr() { return (iterator)this->CapacityX; } - const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;} - public: - - // reverse iterator creation methods. - reverse_iterator rbegin() { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } - reverse_iterator rend() { return reverse_iterator(begin()); } - const_reverse_iterator rend() const { return const_reverse_iterator(begin());} - - size_type size() const { return end()-begin(); } - size_type max_size() const { return size_type(-1) / sizeof(T); } - - /// capacity - Return the total number of elements in the currently allocated - /// buffer. - size_t capacity() const { return capacity_ptr() - begin(); } - - /// data - Return a pointer to the vector's buffer, even if empty(). - pointer data() { return pointer(begin()); } - /// data - Return a pointer to the vector's buffer, even if empty(). - const_pointer data() const { return const_pointer(begin()); } - - reference operator[](unsigned idx) { - assert(begin() + idx < end()); - return begin()[idx]; - } - const_reference operator[](unsigned idx) const { - assert(begin() + idx < end()); - return begin()[idx]; - } - - reference front() { - return begin()[0]; - } - const_reference front() const { - return begin()[0]; - } - - reference back() { - return end()[-1]; - } - const_reference back() const { - return end()[-1]; - } - }; - - /// SmallVectorTemplateBase - This is where we put method - /// implementations that are designed to work with non-POD-like T's. - template - class SmallVectorTemplateBase : public SmallVectorTemplateCommon { - public: - SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon(Size) {} - - static void destroy_range(T *S, T *E) { - while (S != E) { - --E; - E->~T(); - } - } - - /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory - /// starting with "Dest", constructing elements into it as needed. - template - static void uninitialized_copy(It1 I, It1 E, It2 Dest) { - std::uninitialized_copy(I, E, Dest); - } - - /// grow - double the size of the allocated memory, guaranteeing space for at - /// least one more element or MinSize if specified. - void grow(size_t MinSize = 0); - }; - - // Define this out-of-line to dissuade the C++ compiler from inlining it. - template - void SmallVectorTemplateBase::grow(size_t MinSize) { - size_t CurCapacity = this->capacity(); - size_t CurSize = this->size(); + void grow_pod(size_t MinSizeInBytes, size_t TSize); + + public: + bool empty() const { return BeginX == EndX; } + }; + + + template + class SmallVectorTemplateCommon : public SmallVectorBase { + protected: + void setEnd(T *P) { this->EndX = P; } + public: + SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(Size) {} + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef T *iterator; + typedef const T *const_iterator; + + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + typedef T &reference; + typedef const T &const_reference; + typedef T *pointer; + typedef const T *const_pointer; + + // forward iterator creation methods. + iterator begin() { return (iterator)this->BeginX; } + const_iterator begin() const { return (const_iterator)this->BeginX; } + iterator end() { return (iterator)this->EndX; } + const_iterator end() const { return (const_iterator)this->EndX; } + protected: + iterator capacity_ptr() { return (iterator)this->CapacityX; } + const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;} + public: + + // reverse iterator creation methods. + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin());} + + size_type size() const { return end()-begin(); } + size_type max_size() const { return size_type(-1) / sizeof(T); } + + /// capacity - Return the total number of elements in the currently allocated + /// buffer. + size_t capacity() const { return capacity_ptr() - begin(); } + + /// data - Return a pointer to the vector's buffer, even if empty(). + pointer data() { return pointer(begin()); } + /// data - Return a pointer to the vector's buffer, even if empty(). + const_pointer data() const { return const_pointer(begin()); } + + reference operator[](unsigned idx) { + assert(begin() + idx < end()); + return begin()[idx]; + } + const_reference operator[](unsigned idx) const { + assert(begin() + idx < end()); + return begin()[idx]; + } + + reference front() { + return begin()[0]; + } + const_reference front() const { + return begin()[0]; + } + + reference back() { + return end()[-1]; + } + const_reference back() const { + return end()[-1]; + } + }; + + /// SmallVectorTemplateBase - This is where we put method + /// implementations that are designed to work with non-POD-like T's. + template + class SmallVectorTemplateBase : public SmallVectorTemplateCommon { + public: + SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon(Size) {} + + static void destroy_range(T *S, T *E) { + while (S != E) { + --E; + E->~T(); + } + } + + /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory + /// starting with "Dest", constructing elements into it as needed. + template + static void uninitialized_copy(It1 I, It1 E, It2 Dest) { + std::uninitialized_copy(I, E, Dest); + } + + /// grow - double the size of the allocated memory, guaranteeing space for at + /// least one more element or MinSize if specified. + void grow(size_t MinSize = 0); + }; + + // Define this out-of-line to dissuade the C++ compiler from inlining it. + template + void SmallVectorTemplateBase::grow(size_t MinSize) { + size_t CurCapacity = this->capacity(); + size_t CurSize = this->size(); size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero. - if (NewCapacity < MinSize) - NewCapacity = MinSize; - T *NewElts = static_cast(malloc(NewCapacity*sizeof(T))); - - // Copy the elements over. - this->uninitialized_copy(this->begin(), this->end(), NewElts); - - // Destroy the original elements. - destroy_range(this->begin(), this->end()); - - // If this wasn't grown from the inline copy, deallocate the old space. - if (!this->isSmall()) - free(this->begin()); - - this->setEnd(NewElts+CurSize); - this->BeginX = NewElts; - this->CapacityX = this->begin()+NewCapacity; - } - - - /// SmallVectorTemplateBase - This is where we put method - /// implementations that are designed to work with POD-like T's. - template - class SmallVectorTemplateBase : public SmallVectorTemplateCommon { - public: - SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon(Size) {} - - // No need to do a destroy loop for POD's. - static void destroy_range(T *, T *) {} - - /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory - /// starting with "Dest", constructing elements into it as needed. - template - static void uninitialized_copy(It1 I, It1 E, It2 Dest) { - // Arbitrary iterator types; just use the basic implementation. - std::uninitialized_copy(I, E, Dest); - } - - /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory - /// starting with "Dest", constructing elements into it as needed. - template - static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest) { - // Use memcpy for PODs iterated by pointers (which includes SmallVector - // iterators): std::uninitialized_copy optimizes to memmove, but we can - // use memcpy here. - memcpy(Dest, I, (E-I)*sizeof(T)); - } - - /// grow - double the size of the allocated memory, guaranteeing space for at - /// least one more element or MinSize if specified. - void grow(size_t MinSize = 0) { - this->grow_pod(MinSize*sizeof(T), sizeof(T)); - } - }; - - - /// SmallVectorImpl - This class consists of common code factored out of the - /// SmallVector class to reduce code duplication based on the SmallVector 'N' - /// template parameter. - template - class SmallVectorImpl : public SmallVectorTemplateBase::value> { - typedef SmallVectorTemplateBase::value > SuperClass; - - SmallVectorImpl(const SmallVectorImpl&); // DISABLED. - public: - typedef typename SuperClass::iterator iterator; - typedef typename SuperClass::size_type size_type; - - // Default ctor - Initialize to empty. - explicit SmallVectorImpl(unsigned N) - : SmallVectorTemplateBase::value>(N*sizeof(T)) { - } - - ~SmallVectorImpl() { - // Destroy the constructed elements in the vector. - this->destroy_range(this->begin(), this->end()); - - // If this wasn't grown from the inline copy, deallocate the old space. - if (!this->isSmall()) - free(this->begin()); - } - - - void clear() { - this->destroy_range(this->begin(), this->end()); - this->EndX = this->BeginX; - } - - void resize(unsigned N) { - if (N < this->size()) { - this->destroy_range(this->begin()+N, this->end()); - this->setEnd(this->begin()+N); - } else if (N > this->size()) { - if (this->capacity() < N) - this->grow(N); - this->construct_range(this->end(), this->begin()+N, T()); - this->setEnd(this->begin()+N); - } - } - - void resize(unsigned N, const T &NV) { - if (N < this->size()) { - this->destroy_range(this->begin()+N, this->end()); - this->setEnd(this->begin()+N); - } else if (N > this->size()) { - if (this->capacity() < N) - this->grow(N); - construct_range(this->end(), this->begin()+N, NV); - this->setEnd(this->begin()+N); - } - } - - void reserve(unsigned N) { - if (this->capacity() < N) - this->grow(N); - } - - void push_back(const T &Elt) { - if (this->EndX < this->CapacityX) { - Retry: - new (this->end()) T(Elt); - this->setEnd(this->end()+1); - return; - } - this->grow(); - goto Retry; - } - - void pop_back() { - this->setEnd(this->end()-1); - this->end()->~T(); - } - - T pop_back_val() { - T Result = this->back(); - pop_back(); - return Result; - } - - void swap(SmallVectorImpl &RHS); - - /// append - Add the specified range to the end of the SmallVector. - /// - template - void append(in_iter in_start, in_iter in_end) { - size_type NumInputs = std::distance(in_start, in_end); - // Grow allocated space if needed. - if (NumInputs > size_type(this->capacity_ptr()-this->end())) - this->grow(this->size()+NumInputs); - - // Copy the new elements over. - // TODO: NEED To compile time dispatch on whether in_iter is a random access - // iterator to use the fast uninitialized_copy. - std::uninitialized_copy(in_start, in_end, this->end()); - this->setEnd(this->end() + NumInputs); - } - - /// append - Add the specified range to the end of the SmallVector. - /// - void append(size_type NumInputs, const T &Elt) { - // Grow allocated space if needed. - if (NumInputs > size_type(this->capacity_ptr()-this->end())) - this->grow(this->size()+NumInputs); - - // Copy the new elements over. - std::uninitialized_fill_n(this->end(), NumInputs, Elt); - this->setEnd(this->end() + NumInputs); - } - - void assign(unsigned NumElts, const T &Elt) { - clear(); - if (this->capacity() < NumElts) - this->grow(NumElts); - this->setEnd(this->begin()+NumElts); - construct_range(this->begin(), this->end(), Elt); - } - - iterator erase(iterator I) { - iterator N = I; - // Shift all elts down one. - std::copy(I+1, this->end(), I); - // Drop the last elt. - pop_back(); - return(N); - } - - iterator erase(iterator S, iterator E) { - iterator N = S; - // Shift all elts down. - iterator I = std::copy(E, this->end(), S); - // Drop the last elts. - this->destroy_range(I, this->end()); - this->setEnd(I); - return(N); - } - - iterator insert(iterator I, const T &Elt) { - if (I == this->end()) { // Important special case for empty vector. - push_back(Elt); - return this->end()-1; - } - - if (this->EndX < this->CapacityX) { - Retry: - new (this->end()) T(this->back()); - this->setEnd(this->end()+1); - // Push everything else over. - std::copy_backward(I, this->end()-1, this->end()); - *I = Elt; - return I; - } - size_t EltNo = I-this->begin(); - this->grow(); - I = this->begin()+EltNo; - goto Retry; - } - - iterator insert(iterator I, size_type NumToInsert, const T &Elt) { - if (I == this->end()) { // Important special case for empty vector. - append(NumToInsert, Elt); - return this->end()-1; - } - - // Convert iterator to elt# to avoid invalidating iterator when we reserve() - size_t InsertElt = I - this->begin(); - - // Ensure there is enough space. - reserve(static_cast(this->size() + NumToInsert)); - - // Uninvalidate the iterator. - I = this->begin()+InsertElt; - - // If there are more elements between the insertion point and the end of the - // range than there are being inserted, we can use a simple approach to - // insertion. Since we already reserved space, we know that this won't - // reallocate the vector. - if (size_t(this->end()-I) >= NumToInsert) { - T *OldEnd = this->end(); - append(this->end()-NumToInsert, this->end()); - - // Copy the existing elements that get replaced. - std::copy_backward(I, OldEnd-NumToInsert, OldEnd); - - std::fill_n(I, NumToInsert, Elt); - return I; - } - - // Otherwise, we're inserting more elements than exist already, and we're - // not inserting at the end. - - // Copy over the elements that we're about to overwrite. - T *OldEnd = this->end(); - this->setEnd(this->end() + NumToInsert); - size_t NumOverwritten = OldEnd-I; - this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten); - - // Replace the overwritten part. - std::fill_n(I, NumOverwritten, Elt); - - // Insert the non-overwritten middle part. - std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt); - return I; - } - - template - iterator insert(iterator I, ItTy From, ItTy To) { - if (I == this->end()) { // Important special case for empty vector. - append(From, To); - return this->end()-1; - } - - size_t NumToInsert = std::distance(From, To); - // Convert iterator to elt# to avoid invalidating iterator when we reserve() - size_t InsertElt = I - this->begin(); - - // Ensure there is enough space. - reserve(static_cast(this->size() + NumToInsert)); - - // Uninvalidate the iterator. - I = this->begin()+InsertElt; - - // If there are more elements between the insertion point and the end of the - // range than there are being inserted, we can use a simple approach to - // insertion. Since we already reserved space, we know that this won't - // reallocate the vector. - if (size_t(this->end()-I) >= NumToInsert) { - T *OldEnd = this->end(); - append(this->end()-NumToInsert, this->end()); - - // Copy the existing elements that get replaced. - std::copy_backward(I, OldEnd-NumToInsert, OldEnd); - - std::copy(From, To, I); - return I; - } - - // Otherwise, we're inserting more elements than exist already, and we're - // not inserting at the end. - - // Copy over the elements that we're about to overwrite. - T *OldEnd = this->end(); - this->setEnd(this->end() + NumToInsert); - size_t NumOverwritten = OldEnd-I; - this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten); - - // Replace the overwritten part. - for (; NumOverwritten > 0; --NumOverwritten) { - *I = *From; - ++I; ++From; - } - - // Insert the non-overwritten middle part. - this->uninitialized_copy(From, To, OldEnd); - return I; - } - - const SmallVectorImpl - &operator=(const SmallVectorImpl &RHS); - - bool operator==(const SmallVectorImpl &RHS) const { - if (this->size() != RHS.size()) return false; - return std::equal(this->begin(), this->end(), RHS.begin()); - } - bool operator!=(const SmallVectorImpl &RHS) const { - return !(*this == RHS); - } - - bool operator<(const SmallVectorImpl &RHS) const { - return std::lexicographical_compare(this->begin(), this->end(), - RHS.begin(), RHS.end()); - } - - /// set_size - Set the array size to \arg N, which the current array must have - /// enough capacity for. - /// - /// This does not construct or destroy any elements in the vector. - /// - /// Clients can use this in conjunction with capacity() to write past the end - /// of the buffer when they know that more elements are available, and only - /// update the size later. This avoids the cost of value initializing elements - /// which will only be overwritten. - void set_size(unsigned N) { - assert(N <= this->capacity()); - this->setEnd(this->begin() + N); - } - - private: - static void construct_range(T *S, T *E, const T &Elt) { - for (; S != E; ++S) - new (S) T(Elt); - } - }; - - - template - void SmallVectorImpl::swap(SmallVectorImpl &RHS) { - if (this == &RHS) return; - - // We can only avoid copying elements if neither vector is small. - if (!this->isSmall() && !RHS.isSmall()) { - std::swap(this->BeginX, RHS.BeginX); - std::swap(this->EndX, RHS.EndX); - std::swap(this->CapacityX, RHS.CapacityX); - return; - } - if (RHS.size() > this->capacity()) - this->grow(RHS.size()); - if (this->size() > RHS.capacity()) - RHS.grow(this->size()); - - // Swap the shared elements. - size_t NumShared = this->size(); - if (NumShared > RHS.size()) NumShared = RHS.size(); - for (unsigned i = 0; i != static_cast(NumShared); ++i) - std::swap((*this)[i], RHS[i]); - - // Copy over the extra elts. - if (this->size() > RHS.size()) { - size_t EltDiff = this->size() - RHS.size(); - this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end()); - RHS.setEnd(RHS.end()+EltDiff); - this->destroy_range(this->begin()+NumShared, this->end()); - this->setEnd(this->begin()+NumShared); - } else if (RHS.size() > this->size()) { - size_t EltDiff = RHS.size() - this->size(); - this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end()); - this->setEnd(this->end() + EltDiff); - this->destroy_range(RHS.begin()+NumShared, RHS.end()); - RHS.setEnd(RHS.begin()+NumShared); - } - } - - template - const SmallVectorImpl &SmallVectorImpl:: - operator=(const SmallVectorImpl &RHS) { - // Avoid self-assignment. - if (this == &RHS) return *this; - - // If we already have sufficient space, assign the common elements, then - // destroy any excess. - size_t RHSSize = RHS.size(); - size_t CurSize = this->size(); - if (CurSize >= RHSSize) { - // Assign common elements. - iterator NewEnd; - if (RHSSize) - NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin()); - else - NewEnd = this->begin(); - - // Destroy excess elements. - this->destroy_range(NewEnd, this->end()); - - // Trim. - this->setEnd(NewEnd); - return *this; - } - - // If we have to grow to have enough elements, destroy the current elements. - // This allows us to avoid copying them during the grow. - if (this->capacity() < RHSSize) { - // Destroy current elements. - this->destroy_range(this->begin(), this->end()); - this->setEnd(this->begin()); - CurSize = 0; - this->grow(RHSSize); - } else if (CurSize) { - // Otherwise, use assignment for the already-constructed elements. - std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin()); - } - - // Copy construct the new elements in place. - this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(), - this->begin()+CurSize); - - // Set end. - this->setEnd(this->begin()+RHSSize); - return *this; - } - - - /// SmallVector - This is a 'vector' (really, a variable-sized array), optimized - /// for the case when the array is small. It contains some number of elements - /// in-place, which allows it to avoid heap allocation when the actual number of - /// elements is below that threshold. This allows normal "small" cases to be - /// fast without losing generality for large inputs. - /// - /// Note that this does not attempt to be exception safe. - /// - template - class SmallVector : public SmallVectorImpl { - /// InlineElts - These are 'N-1' elements that are stored inline in the body - /// of the vector. The extra '1' element is stored in SmallVectorImpl. - typedef typename SmallVectorImpl::U U; - enum { - // MinUs - The number of U's require to cover N T's. - MinUs = (static_cast(sizeof(T))*N + - static_cast(sizeof(U)) - 1) / + if (NewCapacity < MinSize) + NewCapacity = MinSize; + T *NewElts = static_cast(malloc(NewCapacity*sizeof(T))); + + // Copy the elements over. + this->uninitialized_copy(this->begin(), this->end(), NewElts); + + // Destroy the original elements. + destroy_range(this->begin(), this->end()); + + // If this wasn't grown from the inline copy, deallocate the old space. + if (!this->isSmall()) + free(this->begin()); + + this->setEnd(NewElts+CurSize); + this->BeginX = NewElts; + this->CapacityX = this->begin()+NewCapacity; + } + + + /// SmallVectorTemplateBase - This is where we put method + /// implementations that are designed to work with POD-like T's. + template + class SmallVectorTemplateBase : public SmallVectorTemplateCommon { + public: + SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon(Size) {} + + // No need to do a destroy loop for POD's. + static void destroy_range(T *, T *) {} + + /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory + /// starting with "Dest", constructing elements into it as needed. + template + static void uninitialized_copy(It1 I, It1 E, It2 Dest) { + // Arbitrary iterator types; just use the basic implementation. + std::uninitialized_copy(I, E, Dest); + } + + /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory + /// starting with "Dest", constructing elements into it as needed. + template + static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest) { + // Use memcpy for PODs iterated by pointers (which includes SmallVector + // iterators): std::uninitialized_copy optimizes to memmove, but we can + // use memcpy here. + memcpy(Dest, I, (E-I)*sizeof(T)); + } + + /// grow - double the size of the allocated memory, guaranteeing space for at + /// least one more element or MinSize if specified. + void grow(size_t MinSize = 0) { + this->grow_pod(MinSize*sizeof(T), sizeof(T)); + } + }; + + + /// SmallVectorImpl - This class consists of common code factored out of the + /// SmallVector class to reduce code duplication based on the SmallVector 'N' + /// template parameter. + template + class SmallVectorImpl : public SmallVectorTemplateBase::value> { + typedef SmallVectorTemplateBase::value > SuperClass; + + SmallVectorImpl(const SmallVectorImpl&); // DISABLED. + public: + typedef typename SuperClass::iterator iterator; + typedef typename SuperClass::size_type size_type; + + // Default ctor - Initialize to empty. + explicit SmallVectorImpl(unsigned N) + : SmallVectorTemplateBase::value>(N*sizeof(T)) { + } + + ~SmallVectorImpl() { + // Destroy the constructed elements in the vector. + this->destroy_range(this->begin(), this->end()); + + // If this wasn't grown from the inline copy, deallocate the old space. + if (!this->isSmall()) + free(this->begin()); + } + + + void clear() { + this->destroy_range(this->begin(), this->end()); + this->EndX = this->BeginX; + } + + void resize(unsigned N) { + if (N < this->size()) { + this->destroy_range(this->begin()+N, this->end()); + this->setEnd(this->begin()+N); + } else if (N > this->size()) { + if (this->capacity() < N) + this->grow(N); + this->construct_range(this->end(), this->begin()+N, T()); + this->setEnd(this->begin()+N); + } + } + + void resize(unsigned N, const T &NV) { + if (N < this->size()) { + this->destroy_range(this->begin()+N, this->end()); + this->setEnd(this->begin()+N); + } else if (N > this->size()) { + if (this->capacity() < N) + this->grow(N); + construct_range(this->end(), this->begin()+N, NV); + this->setEnd(this->begin()+N); + } + } + + void reserve(unsigned N) { + if (this->capacity() < N) + this->grow(N); + } + + void push_back(const T &Elt) { + if (this->EndX < this->CapacityX) { + Retry: + new (this->end()) T(Elt); + this->setEnd(this->end()+1); + return; + } + this->grow(); + goto Retry; + } + + void pop_back() { + this->setEnd(this->end()-1); + this->end()->~T(); + } + + T pop_back_val() { + T Result = this->back(); + pop_back(); + return Result; + } + + void swap(SmallVectorImpl &RHS); + + /// append - Add the specified range to the end of the SmallVector. + /// + template + void append(in_iter in_start, in_iter in_end) { + size_type NumInputs = std::distance(in_start, in_end); + // Grow allocated space if needed. + if (NumInputs > size_type(this->capacity_ptr()-this->end())) + this->grow(this->size()+NumInputs); + + // Copy the new elements over. + // TODO: NEED To compile time dispatch on whether in_iter is a random access + // iterator to use the fast uninitialized_copy. + std::uninitialized_copy(in_start, in_end, this->end()); + this->setEnd(this->end() + NumInputs); + } + + /// append - Add the specified range to the end of the SmallVector. + /// + void append(size_type NumInputs, const T &Elt) { + // Grow allocated space if needed. + if (NumInputs > size_type(this->capacity_ptr()-this->end())) + this->grow(this->size()+NumInputs); + + // Copy the new elements over. + std::uninitialized_fill_n(this->end(), NumInputs, Elt); + this->setEnd(this->end() + NumInputs); + } + + void assign(unsigned NumElts, const T &Elt) { + clear(); + if (this->capacity() < NumElts) + this->grow(NumElts); + this->setEnd(this->begin()+NumElts); + construct_range(this->begin(), this->end(), Elt); + } + + iterator erase(iterator I) { + iterator N = I; + // Shift all elts down one. + std::copy(I+1, this->end(), I); + // Drop the last elt. + pop_back(); + return(N); + } + + iterator erase(iterator S, iterator E) { + iterator N = S; + // Shift all elts down. + iterator I = std::copy(E, this->end(), S); + // Drop the last elts. + this->destroy_range(I, this->end()); + this->setEnd(I); + return(N); + } + + iterator insert(iterator I, const T &Elt) { + if (I == this->end()) { // Important special case for empty vector. + push_back(Elt); + return this->end()-1; + } + + if (this->EndX < this->CapacityX) { + Retry: + new (this->end()) T(this->back()); + this->setEnd(this->end()+1); + // Push everything else over. + std::copy_backward(I, this->end()-1, this->end()); + *I = Elt; + return I; + } + size_t EltNo = I-this->begin(); + this->grow(); + I = this->begin()+EltNo; + goto Retry; + } + + iterator insert(iterator I, size_type NumToInsert, const T &Elt) { + if (I == this->end()) { // Important special case for empty vector. + append(NumToInsert, Elt); + return this->end()-1; + } + + // Convert iterator to elt# to avoid invalidating iterator when we reserve() + size_t InsertElt = I - this->begin(); + + // Ensure there is enough space. + reserve(static_cast(this->size() + NumToInsert)); + + // Uninvalidate the iterator. + I = this->begin()+InsertElt; + + // If there are more elements between the insertion point and the end of the + // range than there are being inserted, we can use a simple approach to + // insertion. Since we already reserved space, we know that this won't + // reallocate the vector. + if (size_t(this->end()-I) >= NumToInsert) { + T *OldEnd = this->end(); + append(this->end()-NumToInsert, this->end()); + + // Copy the existing elements that get replaced. + std::copy_backward(I, OldEnd-NumToInsert, OldEnd); + + std::fill_n(I, NumToInsert, Elt); + return I; + } + + // Otherwise, we're inserting more elements than exist already, and we're + // not inserting at the end. + + // Copy over the elements that we're about to overwrite. + T *OldEnd = this->end(); + this->setEnd(this->end() + NumToInsert); + size_t NumOverwritten = OldEnd-I; + this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten); + + // Replace the overwritten part. + std::fill_n(I, NumOverwritten, Elt); + + // Insert the non-overwritten middle part. + std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt); + return I; + } + + template + iterator insert(iterator I, ItTy From, ItTy To) { + if (I == this->end()) { // Important special case for empty vector. + append(From, To); + return this->end()-1; + } + + size_t NumToInsert = std::distance(From, To); + // Convert iterator to elt# to avoid invalidating iterator when we reserve() + size_t InsertElt = I - this->begin(); + + // Ensure there is enough space. + reserve(static_cast(this->size() + NumToInsert)); + + // Uninvalidate the iterator. + I = this->begin()+InsertElt; + + // If there are more elements between the insertion point and the end of the + // range than there are being inserted, we can use a simple approach to + // insertion. Since we already reserved space, we know that this won't + // reallocate the vector. + if (size_t(this->end()-I) >= NumToInsert) { + T *OldEnd = this->end(); + append(this->end()-NumToInsert, this->end()); + + // Copy the existing elements that get replaced. + std::copy_backward(I, OldEnd-NumToInsert, OldEnd); + + std::copy(From, To, I); + return I; + } + + // Otherwise, we're inserting more elements than exist already, and we're + // not inserting at the end. + + // Copy over the elements that we're about to overwrite. + T *OldEnd = this->end(); + this->setEnd(this->end() + NumToInsert); + size_t NumOverwritten = OldEnd-I; + this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten); + + // Replace the overwritten part. + for (; NumOverwritten > 0; --NumOverwritten) { + *I = *From; + ++I; ++From; + } + + // Insert the non-overwritten middle part. + this->uninitialized_copy(From, To, OldEnd); + return I; + } + + const SmallVectorImpl + &operator=(const SmallVectorImpl &RHS); + + bool operator==(const SmallVectorImpl &RHS) const { + if (this->size() != RHS.size()) return false; + return std::equal(this->begin(), this->end(), RHS.begin()); + } + bool operator!=(const SmallVectorImpl &RHS) const { + return !(*this == RHS); + } + + bool operator<(const SmallVectorImpl &RHS) const { + return std::lexicographical_compare(this->begin(), this->end(), + RHS.begin(), RHS.end()); + } + + /// set_size - Set the array size to \arg N, which the current array must have + /// enough capacity for. + /// + /// This does not construct or destroy any elements in the vector. + /// + /// Clients can use this in conjunction with capacity() to write past the end + /// of the buffer when they know that more elements are available, and only + /// update the size later. This avoids the cost of value initializing elements + /// which will only be overwritten. + void set_size(unsigned N) { + assert(N <= this->capacity()); + this->setEnd(this->begin() + N); + } + + private: + static void construct_range(T *S, T *E, const T &Elt) { + for (; S != E; ++S) + new (S) T(Elt); + } + }; + + + template + void SmallVectorImpl::swap(SmallVectorImpl &RHS) { + if (this == &RHS) return; + + // We can only avoid copying elements if neither vector is small. + if (!this->isSmall() && !RHS.isSmall()) { + std::swap(this->BeginX, RHS.BeginX); + std::swap(this->EndX, RHS.EndX); + std::swap(this->CapacityX, RHS.CapacityX); + return; + } + if (RHS.size() > this->capacity()) + this->grow(RHS.size()); + if (this->size() > RHS.capacity()) + RHS.grow(this->size()); + + // Swap the shared elements. + size_t NumShared = this->size(); + if (NumShared > RHS.size()) NumShared = RHS.size(); + for (unsigned i = 0; i != static_cast(NumShared); ++i) + std::swap((*this)[i], RHS[i]); + + // Copy over the extra elts. + if (this->size() > RHS.size()) { + size_t EltDiff = this->size() - RHS.size(); + this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end()); + RHS.setEnd(RHS.end()+EltDiff); + this->destroy_range(this->begin()+NumShared, this->end()); + this->setEnd(this->begin()+NumShared); + } else if (RHS.size() > this->size()) { + size_t EltDiff = RHS.size() - this->size(); + this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end()); + this->setEnd(this->end() + EltDiff); + this->destroy_range(RHS.begin()+NumShared, RHS.end()); + RHS.setEnd(RHS.begin()+NumShared); + } + } + + template + const SmallVectorImpl &SmallVectorImpl:: + operator=(const SmallVectorImpl &RHS) { + // Avoid self-assignment. + if (this == &RHS) return *this; + + // If we already have sufficient space, assign the common elements, then + // destroy any excess. + size_t RHSSize = RHS.size(); + size_t CurSize = this->size(); + if (CurSize >= RHSSize) { + // Assign common elements. + iterator NewEnd; + if (RHSSize) + NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin()); + else + NewEnd = this->begin(); + + // Destroy excess elements. + this->destroy_range(NewEnd, this->end()); + + // Trim. + this->setEnd(NewEnd); + return *this; + } + + // If we have to grow to have enough elements, destroy the current elements. + // This allows us to avoid copying them during the grow. + if (this->capacity() < RHSSize) { + // Destroy current elements. + this->destroy_range(this->begin(), this->end()); + this->setEnd(this->begin()); + CurSize = 0; + this->grow(RHSSize); + } else if (CurSize) { + // Otherwise, use assignment for the already-constructed elements. + std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin()); + } + + // Copy construct the new elements in place. + this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(), + this->begin()+CurSize); + + // Set end. + this->setEnd(this->begin()+RHSSize); + return *this; + } + + + /// SmallVector - This is a 'vector' (really, a variable-sized array), optimized + /// for the case when the array is small. It contains some number of elements + /// in-place, which allows it to avoid heap allocation when the actual number of + /// elements is below that threshold. This allows normal "small" cases to be + /// fast without losing generality for large inputs. + /// + /// Note that this does not attempt to be exception safe. + /// + template + class SmallVector : public SmallVectorImpl { + /// InlineElts - These are 'N-1' elements that are stored inline in the body + /// of the vector. The extra '1' element is stored in SmallVectorImpl. + typedef typename SmallVectorImpl::U U; + enum { + // MinUs - The number of U's require to cover N T's. + MinUs = (static_cast(sizeof(T))*N + + static_cast(sizeof(U)) - 1) / static_cast(sizeof(U)), - - // NumInlineEltsElts - The number of elements actually in this array. There - // is already one in the parent class, and we have to round up to avoid - // having a zero-element array. - NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1, - - // NumTsAvailable - The number of T's we actually have space for, which may - // be more than N due to rounding. - NumTsAvailable = (NumInlineEltsElts+1)*static_cast(sizeof(U))/ - static_cast(sizeof(T)) - }; - U InlineElts[NumInlineEltsElts]; - public: - SmallVector() : SmallVectorImpl(NumTsAvailable) { - } - - explicit SmallVector(unsigned Size, const T &Value = T()) - : SmallVectorImpl(NumTsAvailable) { - this->reserve(Size); - while (Size--) - this->push_back(Value); - } - - template - SmallVector(ItTy S, ItTy E) : SmallVectorImpl(NumTsAvailable) { - this->append(S, E); - } - - SmallVector(const SmallVector &RHS) : SmallVectorImpl(NumTsAvailable) { - if (!RHS.empty()) - SmallVectorImpl::operator=(RHS); - } - - const SmallVector &operator=(const SmallVector &RHS) { - SmallVectorImpl::operator=(RHS); - return *this; - } - - }; + + // NumInlineEltsElts - The number of elements actually in this array. There + // is already one in the parent class, and we have to round up to avoid + // having a zero-element array. + NumInlineEltsElts = MinUs > 1 ? (MinUs - 1) : 1, + + // NumTsAvailable - The number of T's we actually have space for, which may + // be more than N due to rounding. + NumTsAvailable = (NumInlineEltsElts+1)*static_cast(sizeof(U))/ + static_cast(sizeof(T)) + }; + U InlineElts[NumInlineEltsElts]; + public: + SmallVector() : SmallVectorImpl(NumTsAvailable) { + } + + explicit SmallVector(unsigned Size, const T &Value = T()) + : SmallVectorImpl(NumTsAvailable) { + this->reserve(Size); + while (Size--) + this->push_back(Value); + } + + template + SmallVector(ItTy S, ItTy E) : SmallVectorImpl(NumTsAvailable) { + this->append(S, E); + } + + SmallVector(const SmallVector &RHS) : SmallVectorImpl(NumTsAvailable) { + if (!RHS.empty()) + SmallVectorImpl::operator=(RHS); + } + + const SmallVector &operator=(const SmallVector &RHS) { + SmallVectorImpl::operator=(RHS); + return *this; + } + + }; /// Specialize SmallVector at N=0. This specialization guarantees /// that it can be instantiated at an incomplete T if none of its @@ -796,19 +796,19 @@ class SmallVector : public SmallVectorImpl { } // End Ogre namespace namespace std { - /// Implement std::swap in terms of SmallVector swap. - template - inline void - swap(Ogre::SmallVectorImpl &LHS, Ogre::SmallVectorImpl &RHS) { - LHS.swap(RHS); - } - - /// Implement std::swap in terms of SmallVector swap. - template - inline void - swap(Ogre::SmallVector &LHS, Ogre::SmallVector &RHS) { - LHS.swap(RHS); - } + /// Implement std::swap in terms of SmallVector swap. + template + inline void + swap(Ogre::SmallVectorImpl &LHS, Ogre::SmallVectorImpl &RHS) { + LHS.swap(RHS); + } + + /// Implement std::swap in terms of SmallVector swap. + template + inline void + swap(Ogre::SmallVector &LHS, Ogre::SmallVector &RHS) { + LHS.swap(RHS); + } } #endif diff --git a/Components/MeshLodGenerator/include/OgreVectorSet.h b/Components/MeshLodGenerator/include/OgreVectorSet.h index c287b4adc7e..cb2dff877cc 100644 --- a/Components/MeshLodGenerator/include/OgreVectorSet.h +++ b/Components/MeshLodGenerator/include/OgreVectorSet.h @@ -40,20 +40,20 @@ namespace Ogre /// You can remove in O(1) time, if you know the position of the item. template struct VectorSet : - public SmallVector + public SmallVector { - typedef typename SmallVector::iterator iterator; + typedef typename SmallVector::iterator iterator; - void addNotExists(const T& item); // Complexity: O(1)!! - void remove(iterator it); // Complexity: O(1)!! - iterator add(const T& item); // Complexity: O(N) - void removeExists(const T& item); // Complexity: O(N) - bool remove(const T& item); // Complexity: O(N) - void replaceExists(const T& oldItem, const T& newItem); // Complexity: O(N) - bool has(const T& item); // Complexity: O(N) - iterator find(const T& item); // Complexity: O(N) - iterator findExists(const T& item); // Complexity: O(N) + void addNotExists(const T& item); // Complexity: O(1)!! + void remove(iterator it); // Complexity: O(1)!! + iterator add(const T& item); // Complexity: O(N) + void removeExists(const T& item); // Complexity: O(N) + bool remove(const T& item); // Complexity: O(N) + void replaceExists(const T& oldItem, const T& newItem); // Complexity: O(N) + bool has(const T& item); // Complexity: O(N) + iterator find(const T& item); // Complexity: O(N) + iterator findExists(const T& item); // Complexity: O(N) }; } diff --git a/Components/MeshLodGenerator/include/OgreVectorSetImpl.h b/Components/MeshLodGenerator/include/OgreVectorSetImpl.h index a11e01d42f6..ed9ff4fc299 100644 --- a/Components/MeshLodGenerator/include/OgreVectorSetImpl.h +++ b/Components/MeshLodGenerator/include/OgreVectorSetImpl.h @@ -36,82 +36,82 @@ namespace Ogre { - template - void VectorSet::addNotExists(const T& item) - { - OgreAssert(find(item) == this->end(), ""); - this->push_back(item); - } + template + void VectorSet::addNotExists(const T& item) + { + OgreAssert(find(item) == this->end(), ""); + this->push_back(item); + } - template - void VectorSet::remove(iterator it) - { - // Thats my trick to remove an item from the vector very fast! - // It works similar to the heap_pop(). - // It swaps the removable item to the back, then pops it. - *it = this->back(); - this->pop_back(); - } + template + void VectorSet::remove(iterator it) + { + // Thats my trick to remove an item from the vector very fast! + // It works similar to the heap_pop(). + // It swaps the removable item to the back, then pops it. + *it = this->back(); + this->pop_back(); + } - template - typename VectorSet::iterator VectorSet::add(const T& item) - { - iterator it = find(item); - if (it == this->end()) { - this->push_back(item); - return this->end(); - } - return it; - } + template + typename VectorSet::iterator VectorSet::add(const T& item) + { + iterator it = find(item); + if (it == this->end()) { + this->push_back(item); + return this->end(); + } + return it; + } - template - void VectorSet::removeExists(const T& item) - { - iterator it = find(item); - OgreAssert(it != this->end(), ""); - remove(it); - } + template + void VectorSet::removeExists(const T& item) + { + iterator it = find(item); + OgreAssert(it != this->end(), ""); + remove(it); + } - template - bool VectorSet::remove(const T& item) - { - iterator it = find(item); - if (it != this->end()) { - remove(it); - return true; - } else { - return false; - } - } + template + bool VectorSet::remove(const T& item) + { + iterator it = find(item); + if (it != this->end()) { + remove(it); + return true; + } else { + return false; + } + } - template - void VectorSet::replaceExists(const T& oldItem, const T& newItem) - { - iterator it = find(oldItem); - OgreAssert(it != this->end(), ""); - *it = newItem; - } + template + void VectorSet::replaceExists(const T& oldItem, const T& newItem) + { + iterator it = find(oldItem); + OgreAssert(it != this->end(), ""); + *it = newItem; + } - template - bool VectorSet::has(const T& item) - { - return find(item) != this->end(); - } + template + bool VectorSet::has(const T& item) + { + return find(item) != this->end(); + } - template - typename VectorSet::iterator VectorSet::find(const T& item) - { - return std::find(this->begin(), this->end(), item); - } + template + typename VectorSet::iterator VectorSet::find(const T& item) + { + return std::find(this->begin(), this->end(), item); + } - template - typename VectorSet::iterator VectorSet::findExists( - const T& item) - { - iterator it = find(item); - OgreAssert(it != this->end(), ""); - return it; - } + template + typename VectorSet::iterator VectorSet::findExists( + const T& item) + { + iterator it = find(item); + OgreAssert(it != this->end(), ""); + return it; + } } #endif diff --git a/Components/MeshLodGenerator/src/OgreLodBuffer.cpp b/Components/MeshLodGenerator/src/OgreLodBuffer.cpp index 8818009f0e9..b4b4135c1b1 100644 --- a/Components/MeshLodGenerator/src/OgreLodBuffer.cpp +++ b/Components/MeshLodGenerator/src/OgreLodBuffer.cpp @@ -34,108 +34,108 @@ namespace Ogre { - void LodIndexBuffer::fillBuffer( Ogre::IndexData* data ) - { - indexCount = data->indexCount; - if (indexCount > 0) { - const HardwareIndexBufferSharedPtr& hwIndexBuffer = data->indexBuffer; - indexSize = hwIndexBuffer->getIndexSize(); - unsigned char* pBuffer = (unsigned char*) hwIndexBuffer->lock(HardwareBuffer::HBL_READ_ONLY); - size_t offset = data->indexStart * indexSize; - indexBuffer = Ogre::SharedPtr(new unsigned char[indexCount * indexSize]); - indexStart = 0; - indexBufferSize = 0; - memcpy(indexBuffer.get(), pBuffer + offset, indexCount * indexSize); - hwIndexBuffer->unlock(); - } - } + void LodIndexBuffer::fillBuffer( Ogre::IndexData* data ) + { + indexCount = data->indexCount; + if (indexCount > 0) { + const HardwareIndexBufferSharedPtr& hwIndexBuffer = data->indexBuffer; + indexSize = hwIndexBuffer->getIndexSize(); + unsigned char* pBuffer = (unsigned char*) hwIndexBuffer->lock(HardwareBuffer::HBL_READ_ONLY); + size_t offset = data->indexStart * indexSize; + indexBuffer = Ogre::SharedPtr(new unsigned char[indexCount * indexSize]); + indexStart = 0; + indexBufferSize = 0; + memcpy(indexBuffer.get(), pBuffer + offset, indexCount * indexSize); + hwIndexBuffer->unlock(); + } + } - void LodVertexBuffer::fillBuffer( Ogre::VertexData* data ) - { - vertexCount = data->vertexCount; - if (vertexCount > 0) { - // Locate position element and the buffer to go with it. - const VertexElement* elemPos = data->vertexDeclaration->findElementBySemantic(VES_POSITION); + void LodVertexBuffer::fillBuffer( Ogre::VertexData* data ) + { + vertexCount = data->vertexCount; + if (vertexCount > 0) { + // Locate position element and the buffer to go with it. + const VertexElement* elemPos = data->vertexDeclaration->findElementBySemantic(VES_POSITION); - // Only float supported. - OgreAssert(elemPos->getSize() == 12, ""); + // Only float supported. + OgreAssert(elemPos->getSize() == 12, ""); - HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(elemPos->getSource()); - vertexBuffer = Ogre::SharedPtr(new Vector3[vertexCount]); + HardwareVertexBufferSharedPtr vbuf = data->vertexBufferBinding->getBuffer(elemPos->getSource()); + vertexBuffer = Ogre::SharedPtr(new Vector3[vertexCount]); - // Lock the buffer for reading. - unsigned char* vStart = static_cast(vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); - unsigned char* vertex = vStart; - size_t vSize = vbuf->getVertexSize(); + // Lock the buffer for reading. + unsigned char* vStart = static_cast(vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + unsigned char* vertex = vStart; + size_t vSize = vbuf->getVertexSize(); - const VertexElement* elemNormal = 0; - HardwareVertexBufferSharedPtr vNormalBuf; - unsigned char* vNormal; - Vector3* pNormalOut = NULL; - size_t vNormalSize; - bool useVertexNormals = true; - elemNormal = data->vertexDeclaration->findElementBySemantic(VES_NORMAL); - useVertexNormals = useVertexNormals && (elemNormal != 0); - if(useVertexNormals){ - vertexNormalBuffer = Ogre::SharedPtr(new Vector3[vertexCount]); - pNormalOut = vertexNormalBuffer.get(); - if(elemNormal->getSource() == elemPos->getSource()){ - vNormalBuf = vbuf; - vNormal = vStart; - } else { - vNormalBuf = data->vertexBufferBinding->getBuffer(elemNormal->getSource()); - assert(vNormalBuf->getSizeInBytes() == vbuf->getSizeInBytes()); - assert(vNormalBuf->getVertexSize() == vbuf->getVertexSize()); - vNormal = static_cast(vNormalBuf->lock(HardwareBuffer::HBL_READ_ONLY)); - } - vNormalSize = vNormalBuf->getVertexSize(); - } + const VertexElement* elemNormal = 0; + HardwareVertexBufferSharedPtr vNormalBuf; + unsigned char* vNormal; + Vector3* pNormalOut = NULL; + size_t vNormalSize; + bool useVertexNormals = true; + elemNormal = data->vertexDeclaration->findElementBySemantic(VES_NORMAL); + useVertexNormals = useVertexNormals && (elemNormal != 0); + if(useVertexNormals){ + vertexNormalBuffer = Ogre::SharedPtr(new Vector3[vertexCount]); + pNormalOut = vertexNormalBuffer.get(); + if(elemNormal->getSource() == elemPos->getSource()){ + vNormalBuf = vbuf; + vNormal = vStart; + } else { + vNormalBuf = data->vertexBufferBinding->getBuffer(elemNormal->getSource()); + assert(vNormalBuf->getSizeInBytes() == vbuf->getSizeInBytes()); + assert(vNormalBuf->getVertexSize() == vbuf->getVertexSize()); + vNormal = static_cast(vNormalBuf->lock(HardwareBuffer::HBL_READ_ONLY)); + } + vNormalSize = vNormalBuf->getVertexSize(); + } - // Loop through all vertices and insert them to the Unordered Map. - Vector3* pOut = vertexBuffer.get(); - Vector3* pEnd = pOut + vertexCount; - for (; pOut < pEnd; pOut++) { - float* pFloat; - elemPos->baseVertexPointerToElement(vertex, &pFloat); - pOut->x = *pFloat; - pOut->y = *(++pFloat); - pOut->z = *(++pFloat); - vertex += vSize; - if(useVertexNormals){ - elemNormal->baseVertexPointerToElement(vNormal, &pFloat); - pNormalOut->x = *pFloat; - pNormalOut->y = *(++pFloat); - pNormalOut->z = *(++pFloat); - pNormalOut++; - vNormal += vNormalSize; - } - } - vbuf->unlock(); - if(elemNormal && elemNormal->getSource() != elemPos->getSource()){ - vNormalBuf->unlock(); - } - } - } + // Loop through all vertices and insert them to the Unordered Map. + Vector3* pOut = vertexBuffer.get(); + Vector3* pEnd = pOut + vertexCount; + for (; pOut < pEnd; pOut++) { + float* pFloat; + elemPos->baseVertexPointerToElement(vertex, &pFloat); + pOut->x = *pFloat; + pOut->y = *(++pFloat); + pOut->z = *(++pFloat); + vertex += vSize; + if(useVertexNormals){ + elemNormal->baseVertexPointerToElement(vNormal, &pFloat); + pNormalOut->x = *pFloat; + pNormalOut->y = *(++pFloat); + pNormalOut->z = *(++pFloat); + pNormalOut++; + vNormal += vNormalSize; + } + } + vbuf->unlock(); + if(elemNormal && elemNormal->getSource() != elemPos->getSource()){ + vNormalBuf->unlock(); + } + } + } - void LodInputBuffer::fillBuffer( Ogre::MeshPtr mesh ) - { - meshName = mesh->getName(); - boundingSphereRadius = mesh->getBoundingSphereRadius(); - bool sharedVerticesAdded = false; - unsigned short submeshCount = mesh->getNumSubMeshes(); - submesh.resize(submeshCount); - for (unsigned short i = 0; i < submeshCount; i++) { - const SubMesh* ogresubmesh = mesh->getSubMesh(i); - LodInputBuffer::Submesh& outsubmesh = submesh[i]; - outsubmesh.indexBuffer.fillBuffer(ogresubmesh->indexData); - outsubmesh.useSharedVertexBuffer = ogresubmesh->useSharedVertices; - if (!outsubmesh.useSharedVertexBuffer) { - outsubmesh.vertexBuffer.fillBuffer(ogresubmesh->vertexData); - } else if (!sharedVerticesAdded) { - sharedVerticesAdded = true; - sharedVertexBuffer.fillBuffer(mesh->sharedVertexData); - } - } - } + void LodInputBuffer::fillBuffer( Ogre::MeshPtr mesh ) + { + meshName = mesh->getName(); + boundingSphereRadius = mesh->getBoundingSphereRadius(); + bool sharedVerticesAdded = false; + unsigned short submeshCount = mesh->getNumSubMeshes(); + submesh.resize(submeshCount); + for (unsigned short i = 0; i < submeshCount; i++) { + const SubMesh* ogresubmesh = mesh->getSubMesh(i); + LodInputBuffer::Submesh& outsubmesh = submesh[i]; + outsubmesh.indexBuffer.fillBuffer(ogresubmesh->indexData); + outsubmesh.useSharedVertexBuffer = ogresubmesh->useSharedVertices; + if (!outsubmesh.useSharedVertexBuffer) { + outsubmesh.vertexBuffer.fillBuffer(ogresubmesh->vertexData); + } else if (!sharedVerticesAdded) { + sharedVerticesAdded = true; + sharedVertexBuffer.fillBuffer(mesh->sharedVertexData); + } + } + } } diff --git a/Components/MeshLodGenerator/src/OgreLodCollapseCost.cpp b/Components/MeshLodGenerator/src/OgreLodCollapseCost.cpp index 961608b3dfc..8bedcf758d9 100644 --- a/Components/MeshLodGenerator/src/OgreLodCollapseCost.cpp +++ b/Components/MeshLodGenerator/src/OgreLodCollapseCost.cpp @@ -32,81 +32,81 @@ namespace Ogre { - void LodCollapseCost::initCollapseCosts( LodData* data ) - { - data->mCollapseCostHeap.clear(); - LodData::VertexList::iterator it = data->mVertexList.begin(); - LodData::VertexList::iterator itEnd = data->mVertexList.end(); - for (; it != itEnd; it++) { - if (!it->edges.empty()) { - initVertexCollapseCost(data, &*it); - } else { + void LodCollapseCost::initCollapseCosts( LodData* data ) + { + data->mCollapseCostHeap.clear(); + LodData::VertexList::iterator it = data->mVertexList.begin(); + LodData::VertexList::iterator itEnd = data->mVertexList.end(); + for (; it != itEnd; it++) { + if (!it->edges.empty()) { + initVertexCollapseCost(data, &*it); + } else { #if OGRE_DEBUG_MODE - LogManager::getSingleton().stream() << "In " << data->mMeshName << " never used vertex found with ID: " << data->mCollapseCostHeap.size() << ". " - << "Vertex position: (" - << it->position.x << ", " - << it->position.y << ", " - << it->position.z << ") " - << "It will be excluded from Lod level calculations."; + LogManager::getSingleton().stream() << "In " << data->mMeshName << " never used vertex found with ID: " << data->mCollapseCostHeap.size() << ". " + << "Vertex position: (" + << it->position.x << ", " + << it->position.y << ", " + << it->position.z << ") " + << "It will be excluded from Lod level calculations."; #endif - } - } - } + } + } + } - void LodCollapseCost::computeVertexCollapseCost( LodData* data, LodData::Vertex* vertex, Real& collapseCost, LodData::Vertex*& collapseTo ) - { - LodData::VEdges::iterator it = vertex->edges.begin(); - for (; it != vertex->edges.end(); ++it) { - it->collapseCost = computeEdgeCollapseCost(data, vertex, &*it); - if (collapseCost > it->collapseCost) { - collapseCost = it->collapseCost; - collapseTo = it->dst; - } - } - } - void LodCollapseCost::initVertexCollapseCost( LodData* data, LodData::Vertex* vertex ) - { - OgreAssert(!vertex->edges.empty(), ""); + void LodCollapseCost::computeVertexCollapseCost( LodData* data, LodData::Vertex* vertex, Real& collapseCost, LodData::Vertex*& collapseTo ) + { + LodData::VEdges::iterator it = vertex->edges.begin(); + for (; it != vertex->edges.end(); ++it) { + it->collapseCost = computeEdgeCollapseCost(data, vertex, &*it); + if (collapseCost > it->collapseCost) { + collapseCost = it->collapseCost; + collapseTo = it->dst; + } + } + } + void LodCollapseCost::initVertexCollapseCost( LodData* data, LodData::Vertex* vertex ) + { + OgreAssert(!vertex->edges.empty(), ""); - Real collapseCost = LodData::UNINITIALIZED_COLLAPSE_COST; - LodData::Vertex* collapseTo = NULL; - computeVertexCollapseCost(data, vertex, collapseCost, collapseTo); + Real collapseCost = LodData::UNINITIALIZED_COLLAPSE_COST; + LodData::Vertex* collapseTo = NULL; + computeVertexCollapseCost(data, vertex, collapseCost, collapseTo); - vertex->collapseTo = collapseTo; - vertex->costHeapPosition = data->mCollapseCostHeap.insert(LodData::CollapseCostHeap::value_type(collapseCost, vertex)); - } + vertex->collapseTo = collapseTo; + vertex->costHeapPosition = data->mCollapseCostHeap.insert(LodData::CollapseCostHeap::value_type(collapseCost, vertex)); + } - void LodCollapseCost::updateVertexCollapseCost( LodData* data, LodData::Vertex* vertex ) - { - Real collapseCost = LodData::UNINITIALIZED_COLLAPSE_COST; - LodData::Vertex* collapseTo = NULL; - computeVertexCollapseCost(data, vertex, collapseCost, collapseTo); + void LodCollapseCost::updateVertexCollapseCost( LodData* data, LodData::Vertex* vertex ) + { + Real collapseCost = LodData::UNINITIALIZED_COLLAPSE_COST; + LodData::Vertex* collapseTo = NULL; + computeVertexCollapseCost(data, vertex, collapseCost, collapseTo); - if (vertex->collapseTo != collapseTo || collapseCost != vertex->costHeapPosition->first) { - OgreAssert(vertex->costHeapPosition != data->mCollapseCostHeap.end(), ""); - data->mCollapseCostHeap.erase(vertex->costHeapPosition); - if (collapseCost != LodData::UNINITIALIZED_COLLAPSE_COST) { - vertex->collapseTo = collapseTo; - vertex->costHeapPosition = data->mCollapseCostHeap.insert(LodData::CollapseCostHeap::value_type(collapseCost, vertex)); - } else { + if (vertex->collapseTo != collapseTo || collapseCost != vertex->costHeapPosition->first) { + OgreAssert(vertex->costHeapPosition != data->mCollapseCostHeap.end(), ""); + data->mCollapseCostHeap.erase(vertex->costHeapPosition); + if (collapseCost != LodData::UNINITIALIZED_COLLAPSE_COST) { + vertex->collapseTo = collapseTo; + vertex->costHeapPosition = data->mCollapseCostHeap.insert(LodData::CollapseCostHeap::value_type(collapseCost, vertex)); + } else { #if OGRE_DEBUG_MODE - vertex->collapseTo = NULL; - vertex->costHeapPosition = data->mCollapseCostHeap.end(); + vertex->collapseTo = NULL; + vertex->costHeapPosition = data->mCollapseCostHeap.end(); #endif - } - } - } + } + } + } - bool LodCollapseCost::isBorderVertex(const LodData::Vertex* vertex) const - { - LodData::VEdges::const_iterator it = vertex->edges.begin(); - LodData::VEdges::const_iterator itEnd = vertex->edges.end(); - for (; it != itEnd; ++it) { - if (it->refCount == 1) { - return true; - } - } - return false; - } + bool LodCollapseCost::isBorderVertex(const LodData::Vertex* vertex) const + { + LodData::VEdges::const_iterator it = vertex->edges.begin(); + LodData::VEdges::const_iterator itEnd = vertex->edges.end(); + for (; it != itEnd; ++it) { + if (it->refCount == 1) { + return true; + } + } + return false; + } } diff --git a/Components/MeshLodGenerator/src/OgreLodCollapseCostCurvature.cpp b/Components/MeshLodGenerator/src/OgreLodCollapseCostCurvature.cpp index ed85634574b..75d2496fefa 100644 --- a/Components/MeshLodGenerator/src/OgreLodCollapseCostCurvature.cpp +++ b/Components/MeshLodGenerator/src/OgreLodCollapseCostCurvature.cpp @@ -37,172 +37,172 @@ namespace Ogre { - Real LodCollapseCostCurvature::computeEdgeCollapseCost( LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge ) - { - LodData::Vertex* dst = dstEdge->dst; - - // Degenerate case check - // Are we going to invert a face normal of one of the neighboring faces? - // Can occur when we have a very small remaining edge and collapse crosses it - // Look for a face normal changing by > 90 degrees - if(MESHLOD_QUALITY >= 2) { // 30% speedup if disabled. - LodData::VTriangles::iterator it = src->triangles.begin(); - LodData::VTriangles::iterator itEnd = src->triangles.end(); - for (; it != itEnd; ++it) { - LodData::Triangle* triangle = *it; - // Ignore the deleted faces (those including src & dest) - if (!triangle->hasVertex(dst)) { - // Test the new face normal - LodData::Vertex* pv0, * pv1, * pv2; - - // Replace src with dest wherever it is - pv0 = (triangle->vertex[0] == src) ? dst : triangle->vertex[0]; - pv1 = (triangle->vertex[1] == src) ? dst : triangle->vertex[1]; - pv2 = (triangle->vertex[2] == src) ? dst : triangle->vertex[2]; - - // Cross-product 2 edges - Vector3 e1 = pv1->position - pv0->position; - Vector3 e2 = pv2->position - pv1->position; - - Vector3 newNormal = e1.crossProduct(e2); - - // Dot old and new face normal - // If < 0 then more than 90 degree difference - if (newNormal.dotProduct(triangle->normal) < 0.0f) { - // Don't do it! - return LodData::NEVER_COLLAPSE_COST; - } - } - } - } - - Real cost; - - // Special cases - // If we're looking at a border vertex - if (isBorderVertex(src)) { - if (dstEdge->refCount > 1) { - // src is on a border, but the src-dest edge has more than one tri on it - // So it must be collapsing inwards - // Mark as very high-value cost - // curvature = 1.0f; - cost = 1.0f; - } else { - // Collapsing ALONG a border - // We can't use curvature to measure the effect on the model - // Instead, see what effect it has on 'pulling' the other border edges - // The more colinear, the less effect it will have - // So measure the 'kinkiness' (for want of a better term) - - // Find the only triangle using this edge. - // PMTriangle* triangle = findSideTriangle(src, dst); - - cost = -1.0f; - Vector3 collapseEdge = src->position - dst->position; - collapseEdge.normalise(); - LodData::VEdges::iterator it = src->edges.begin(); - LodData::VEdges::iterator itEnd = src->edges.end(); - for (; it != itEnd; it++) { - LodData::Vertex* neighbor = it->dst; - if (neighbor != dst && it->refCount == 1) { - Vector3 otherBorderEdge = src->position - neighbor->position; - otherBorderEdge.normalise(); - // This time, the nearer the dot is to -1, the better, because that means - // the edges are opposite each other, therefore less kinkiness - // Scale into [0..1] - Real kinkiness = otherBorderEdge.dotProduct(collapseEdge); - cost = std::max(cost, kinkiness); - } - } - cost = (1.002f + cost) * 0.5f; - } - } else { // not a border - - // Standard inner vertex - // Calculate curvature - // use the triangle facing most away from the sides - // to determine our curvature term - // Iterate over src's faces again - cost = 1.0f; - LodData::VTriangles::iterator it = src->triangles.begin(); - LodData::VTriangles::iterator itEnd = src->triangles.end(); - for (; it != itEnd; ++it) { - Real mincurv = -1.0f; // curve for face i and closer side to it - LodData::Triangle* triangle = *it; - LodData::VTriangles::iterator it2 = src->triangles.begin(); - for (; it2 != itEnd; ++it2) { - LodData::Triangle* triangle2 = *it2; - if (triangle2->hasVertex(dst)) { - - // Dot product of face normal gives a good delta angle - Real dotprod = triangle->normal.dotProduct(triangle2->normal); - // NB we do (1-..) to invert curvature where 1 is high curvature [0..1] - // Whilst dot product is high when angle difference is low - mincurv = std::max(mincurv, dotprod); - } - } - cost = std::min(cost, mincurv); - } - cost = (1.002f - cost) * 0.5f; - } - - // check for texture seam ripping and multiple submeshes - if (src->seam) { - if (!dst->seam) { - cost = std::max(cost, (Real)0.05f); - cost *= 64; - } else { - if(MESHLOD_QUALITY >= 3) { - int seamNeighbors = 0; - LodData::Vertex* otherSeam; - LodData::VEdges::iterator it = src->edges.begin(); - LodData::VEdges::iterator itEnd = src->edges.end(); - for (; it != itEnd; it++) { - LodData::Vertex* neighbor = it->dst; - if(neighbor->seam) { - seamNeighbors++; - if(neighbor != dst){ - otherSeam = neighbor; - } - } - } - if(seamNeighbors != 2 || (seamNeighbors == 2 && dst->edges.has(LodData::Edge(otherSeam)))) { - cost = std::max(cost, 0.05f); - cost *= 64; - } else { - cost = std::max(cost, 0.005f); - cost *= 8; - } - } else { - cost = std::max(cost, 0.005f); - cost *= 8; - } - - } - } - - Real diff = src->normal.dotProduct(dst->normal) / 8.0f; - Real dist = src->position.distance(dst->position); - cost = cost * dist; - if(data->mUseVertexNormals){ - //Take into account vertex normals. - Real normalCost = 0; - LodData::VEdges::iterator it = src->edges.begin(); - LodData::VEdges::iterator itEnd = src->edges.end(); - for (; it != itEnd; ++it) { - LodData::Vertex* neighbor = it->dst; - Real beforeDist = neighbor->position.distance(src->position); - Real afterDist = neighbor->position.distance(dst->position); - Real beforeDot = neighbor->normal.dotProduct(src->normal); - Real afterDot = neighbor->normal.dotProduct(dst->normal); - normalCost = std::max(normalCost, std::max(diff, std::abs(beforeDot - afterDot)) * - std::max(afterDist/8.0f, std::max(dist, std::abs(beforeDist - afterDist)))); - } - cost = std::max(normalCost * 0.25f, cost); - } - - OgreAssert(cost >= 0 && cost != LodData::UNINITIALIZED_COLLAPSE_COST, "Invalid collapse cost"); - return cost; - } + Real LodCollapseCostCurvature::computeEdgeCollapseCost( LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge ) + { + LodData::Vertex* dst = dstEdge->dst; + + // Degenerate case check + // Are we going to invert a face normal of one of the neighboring faces? + // Can occur when we have a very small remaining edge and collapse crosses it + // Look for a face normal changing by > 90 degrees + if(MESHLOD_QUALITY >= 2) { // 30% speedup if disabled. + LodData::VTriangles::iterator it = src->triangles.begin(); + LodData::VTriangles::iterator itEnd = src->triangles.end(); + for (; it != itEnd; ++it) { + LodData::Triangle* triangle = *it; + // Ignore the deleted faces (those including src & dest) + if (!triangle->hasVertex(dst)) { + // Test the new face normal + LodData::Vertex* pv0, * pv1, * pv2; + + // Replace src with dest wherever it is + pv0 = (triangle->vertex[0] == src) ? dst : triangle->vertex[0]; + pv1 = (triangle->vertex[1] == src) ? dst : triangle->vertex[1]; + pv2 = (triangle->vertex[2] == src) ? dst : triangle->vertex[2]; + + // Cross-product 2 edges + Vector3 e1 = pv1->position - pv0->position; + Vector3 e2 = pv2->position - pv1->position; + + Vector3 newNormal = e1.crossProduct(e2); + + // Dot old and new face normal + // If < 0 then more than 90 degree difference + if (newNormal.dotProduct(triangle->normal) < 0.0f) { + // Don't do it! + return LodData::NEVER_COLLAPSE_COST; + } + } + } + } + + Real cost; + + // Special cases + // If we're looking at a border vertex + if (isBorderVertex(src)) { + if (dstEdge->refCount > 1) { + // src is on a border, but the src-dest edge has more than one tri on it + // So it must be collapsing inwards + // Mark as very high-value cost + // curvature = 1.0f; + cost = 1.0f; + } else { + // Collapsing ALONG a border + // We can't use curvature to measure the effect on the model + // Instead, see what effect it has on 'pulling' the other border edges + // The more colinear, the less effect it will have + // So measure the 'kinkiness' (for want of a better term) + + // Find the only triangle using this edge. + // PMTriangle* triangle = findSideTriangle(src, dst); + + cost = -1.0f; + Vector3 collapseEdge = src->position - dst->position; + collapseEdge.normalise(); + LodData::VEdges::iterator it = src->edges.begin(); + LodData::VEdges::iterator itEnd = src->edges.end(); + for (; it != itEnd; it++) { + LodData::Vertex* neighbor = it->dst; + if (neighbor != dst && it->refCount == 1) { + Vector3 otherBorderEdge = src->position - neighbor->position; + otherBorderEdge.normalise(); + // This time, the nearer the dot is to -1, the better, because that means + // the edges are opposite each other, therefore less kinkiness + // Scale into [0..1] + Real kinkiness = otherBorderEdge.dotProduct(collapseEdge); + cost = std::max(cost, kinkiness); + } + } + cost = (1.002f + cost) * 0.5f; + } + } else { // not a border + + // Standard inner vertex + // Calculate curvature + // use the triangle facing most away from the sides + // to determine our curvature term + // Iterate over src's faces again + cost = 1.0f; + LodData::VTriangles::iterator it = src->triangles.begin(); + LodData::VTriangles::iterator itEnd = src->triangles.end(); + for (; it != itEnd; ++it) { + Real mincurv = -1.0f; // curve for face i and closer side to it + LodData::Triangle* triangle = *it; + LodData::VTriangles::iterator it2 = src->triangles.begin(); + for (; it2 != itEnd; ++it2) { + LodData::Triangle* triangle2 = *it2; + if (triangle2->hasVertex(dst)) { + + // Dot product of face normal gives a good delta angle + Real dotprod = triangle->normal.dotProduct(triangle2->normal); + // NB we do (1-..) to invert curvature where 1 is high curvature [0..1] + // Whilst dot product is high when angle difference is low + mincurv = std::max(mincurv, dotprod); + } + } + cost = std::min(cost, mincurv); + } + cost = (1.002f - cost) * 0.5f; + } + + // check for texture seam ripping and multiple submeshes + if (src->seam) { + if (!dst->seam) { + cost = std::max(cost, (Real)0.05f); + cost *= 64; + } else { + if(MESHLOD_QUALITY >= 3) { + int seamNeighbors = 0; + LodData::Vertex* otherSeam; + LodData::VEdges::iterator it = src->edges.begin(); + LodData::VEdges::iterator itEnd = src->edges.end(); + for (; it != itEnd; it++) { + LodData::Vertex* neighbor = it->dst; + if(neighbor->seam) { + seamNeighbors++; + if(neighbor != dst){ + otherSeam = neighbor; + } + } + } + if(seamNeighbors != 2 || (seamNeighbors == 2 && dst->edges.has(LodData::Edge(otherSeam)))) { + cost = std::max(cost, 0.05f); + cost *= 64; + } else { + cost = std::max(cost, 0.005f); + cost *= 8; + } + } else { + cost = std::max(cost, 0.005f); + cost *= 8; + } + + } + } + + Real diff = src->normal.dotProduct(dst->normal) / 8.0f; + Real dist = src->position.distance(dst->position); + cost = cost * dist; + if(data->mUseVertexNormals){ + //Take into account vertex normals. + Real normalCost = 0; + LodData::VEdges::iterator it = src->edges.begin(); + LodData::VEdges::iterator itEnd = src->edges.end(); + for (; it != itEnd; ++it) { + LodData::Vertex* neighbor = it->dst; + Real beforeDist = neighbor->position.distance(src->position); + Real afterDist = neighbor->position.distance(dst->position); + Real beforeDot = neighbor->normal.dotProduct(src->normal); + Real afterDot = neighbor->normal.dotProduct(dst->normal); + normalCost = std::max(normalCost, std::max(diff, std::abs(beforeDot - afterDot)) * + std::max(afterDist/8.0f, std::max(dist, std::abs(beforeDist - afterDist)))); + } + cost = std::max(normalCost * 0.25f, cost); + } + + OgreAssert(cost >= 0 && cost != LodData::UNINITIALIZED_COLLAPSE_COST, "Invalid collapse cost"); + return cost; + } } diff --git a/Components/MeshLodGenerator/src/OgreLodCollapseCostOutside.cpp b/Components/MeshLodGenerator/src/OgreLodCollapseCostOutside.cpp index 83c5fddd8ab..c4b1c2fe018 100644 --- a/Components/MeshLodGenerator/src/OgreLodCollapseCostOutside.cpp +++ b/Components/MeshLodGenerator/src/OgreLodCollapseCostOutside.cpp @@ -31,43 +31,43 @@ namespace Ogre { - LodCollapseCostOutside::LodCollapseCostOutside( LodCollapseCostPtr costCalculator, Real outsideWeight, Real outsideWalkAngle ) : - mOutsideWeight(outsideWeight), - mOutsideWalkAngle(outsideWalkAngle), - mCostCalculator(costCalculator), - mOutsideMarker(NULL) - { - } + LodCollapseCostOutside::LodCollapseCostOutside( LodCollapseCostPtr costCalculator, Real outsideWeight, Real outsideWalkAngle ) : + mOutsideWeight(outsideWeight), + mOutsideWalkAngle(outsideWalkAngle), + mCostCalculator(costCalculator), + mOutsideMarker(NULL) + { + } - LodCollapseCostOutside::~LodCollapseCostOutside() - { - delete mOutsideMarker; - } + LodCollapseCostOutside::~LodCollapseCostOutside() + { + delete mOutsideMarker; + } - void LodCollapseCostOutside::initCollapseCosts( LodData* data ) - { - OgreAssert(mOutsideWeight != 0.0, ""); + void LodCollapseCostOutside::initCollapseCosts( LodData* data ) + { + OgreAssert(mOutsideWeight != 0.0, ""); - delete mOutsideMarker; - mOutsideMarker = new LodOutsideMarker(data->mVertexList, data->mMeshBoundingSphereRadius, mOutsideWalkAngle); - mOutsideMarker->markOutside(); + delete mOutsideMarker; + mOutsideMarker = new LodOutsideMarker(data->mVertexList, data->mMeshBoundingSphereRadius, mOutsideWalkAngle); + mOutsideMarker->markOutside(); - mCostCalculator->initCollapseCosts(data); - } + mCostCalculator->initCollapseCosts(data); + } - Real LodCollapseCostOutside::computeEdgeCollapseCost( LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge ) - { - Real cost = mCostCalculator->computeEdgeCollapseCost(data, src, dstEdge); - if(mOutsideMarker->isVertexOutside(src) || mOutsideMarker->isVertexOutside(dstEdge->dst)) { - if(mOutsideWeight != LodData::NEVER_COLLAPSE_COST && cost != LodData::NEVER_COLLAPSE_COST) { - cost *= std::max(0.0078125f, mOutsideWeight * 8.0f); - } else { - return LodData::NEVER_COLLAPSE_COST; - } - } - OgreAssert(cost >= 0 && cost != LodData::UNINITIALIZED_COLLAPSE_COST, "Invalid collapse cost"); - return cost; - } + Real LodCollapseCostOutside::computeEdgeCollapseCost( LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge ) + { + Real cost = mCostCalculator->computeEdgeCollapseCost(data, src, dstEdge); + if(mOutsideMarker->isVertexOutside(src) || mOutsideMarker->isVertexOutside(dstEdge->dst)) { + if(mOutsideWeight != LodData::NEVER_COLLAPSE_COST && cost != LodData::NEVER_COLLAPSE_COST) { + cost *= std::max(0.0078125f, mOutsideWeight * 8.0f); + } else { + return LodData::NEVER_COLLAPSE_COST; + } + } + OgreAssert(cost >= 0 && cost != LodData::UNINITIALIZED_COLLAPSE_COST, "Invalid collapse cost"); + return cost; + } } diff --git a/Components/MeshLodGenerator/src/OgreLodCollapseCostProfiler.cpp b/Components/MeshLodGenerator/src/OgreLodCollapseCostProfiler.cpp index 3811087c0f8..4b744e523e8 100644 --- a/Components/MeshLodGenerator/src/OgreLodCollapseCostProfiler.cpp +++ b/Components/MeshLodGenerator/src/OgreLodCollapseCostProfiler.cpp @@ -31,73 +31,73 @@ namespace Ogre { - Real LodCollapseCostProfiler::computeEdgeCollapseCost( LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge ) - { - OgreAssert(0, "Only computeVertexCollapseCost should call this function."); - return 0; - } + Real LodCollapseCostProfiler::computeEdgeCollapseCost( LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge ) + { + OgreAssert(0, "Only computeVertexCollapseCost should call this function."); + return 0; + } - void LodCollapseCostProfiler::computeVertexCollapseCost( LodData* data, LodData::Vertex* vertex, Real& collapseCost, LodData::Vertex*& collapseTo ) - { - LodData::VEdges::iterator it = vertex->edges.begin(); - if(!mHasProfile[LodData::getVectorIDFromPointer(data->mVertexList, vertex)]){ - for (; it != vertex->edges.end(); ++it) { - it->collapseCost = mCostCalculator->computeEdgeCollapseCost(data, vertex, &*it); - if (collapseCost > it->collapseCost) { - collapseCost = it->collapseCost; - collapseTo = it->dst; - } - } - } else { - std::pair ret = mProfileLookup.equal_range(vertex); - for (; it != vertex->edges.end(); ++it) { - it->collapseCost = LodData::UNINITIALIZED_COLLAPSE_COST; - for(ProfileLookup::iterator it2 = ret.first; it2 != ret.second; ++it2){ - if(it2->second.dst == it->dst ){ - it->collapseCost = it2->second.cost; - break; - } - } - if(it->collapseCost == LodData::UNINITIALIZED_COLLAPSE_COST){ - it->collapseCost = mCostCalculator->computeEdgeCollapseCost(data, vertex, &*it); - } - if (collapseCost > it->collapseCost) { - collapseCost = it->collapseCost; - collapseTo = it->dst; - } - } - } - } + void LodCollapseCostProfiler::computeVertexCollapseCost( LodData* data, LodData::Vertex* vertex, Real& collapseCost, LodData::Vertex*& collapseTo ) + { + LodData::VEdges::iterator it = vertex->edges.begin(); + if(!mHasProfile[LodData::getVectorIDFromPointer(data->mVertexList, vertex)]){ + for (; it != vertex->edges.end(); ++it) { + it->collapseCost = mCostCalculator->computeEdgeCollapseCost(data, vertex, &*it); + if (collapseCost > it->collapseCost) { + collapseCost = it->collapseCost; + collapseTo = it->dst; + } + } + } else { + std::pair ret = mProfileLookup.equal_range(vertex); + for (; it != vertex->edges.end(); ++it) { + it->collapseCost = LodData::UNINITIALIZED_COLLAPSE_COST; + for(ProfileLookup::iterator it2 = ret.first; it2 != ret.second; ++it2){ + if(it2->second.dst == it->dst ){ + it->collapseCost = it2->second.cost; + break; + } + } + if(it->collapseCost == LodData::UNINITIALIZED_COLLAPSE_COST){ + it->collapseCost = mCostCalculator->computeEdgeCollapseCost(data, vertex, &*it); + } + if (collapseCost > it->collapseCost) { + collapseCost = it->collapseCost; + collapseTo = it->dst; + } + } + } + } - void LodCollapseCostProfiler::injectProfile( LodData* data) - { - mHasProfile.clear(); - mHasProfile.resize(data->mVertexList.size(), false); - LodProfile::iterator it = mProfile.begin(); - LodProfile::iterator itEnd = mProfile.end(); - for(;it != itEnd;it++){ - LodData::Vertex v; - v.position = it->src; - LodData::UniqueVertexSet::iterator src = data->mUniqueVertexSet.find(&v); - OgreAssert(src != data->mUniqueVertexSet.end(), "Invalid vertex position in Lod profile"); - mHasProfile[LodData::getVectorIDFromPointer(data->mVertexList, *src)] = true; - v.position = it->dst; - LodData::UniqueVertexSet::iterator dst = data->mUniqueVertexSet.find(&v); - OgreAssert(dst != data->mUniqueVertexSet.end(), "Invalid vertex position in Lod profile"); - ProfiledEdge e; - e.dst = *dst; - e.cost = it->cost; - OgreAssert(e.cost >= 0 && e.cost != LodData::UNINITIALIZED_COLLAPSE_COST, "Invalid collapse cost"); - mProfileLookup.insert(ProfileLookup::value_type(*src, e)); - } - } + void LodCollapseCostProfiler::injectProfile( LodData* data) + { + mHasProfile.clear(); + mHasProfile.resize(data->mVertexList.size(), false); + LodProfile::iterator it = mProfile.begin(); + LodProfile::iterator itEnd = mProfile.end(); + for(;it != itEnd;it++){ + LodData::Vertex v; + v.position = it->src; + LodData::UniqueVertexSet::iterator src = data->mUniqueVertexSet.find(&v); + OgreAssert(src != data->mUniqueVertexSet.end(), "Invalid vertex position in Lod profile"); + mHasProfile[LodData::getVectorIDFromPointer(data->mVertexList, *src)] = true; + v.position = it->dst; + LodData::UniqueVertexSet::iterator dst = data->mUniqueVertexSet.find(&v); + OgreAssert(dst != data->mUniqueVertexSet.end(), "Invalid vertex position in Lod profile"); + ProfiledEdge e; + e.dst = *dst; + e.cost = it->cost; + OgreAssert(e.cost >= 0 && e.cost != LodData::UNINITIALIZED_COLLAPSE_COST, "Invalid collapse cost"); + mProfileLookup.insert(ProfileLookup::value_type(*src, e)); + } + } - void LodCollapseCostProfiler::initCollapseCosts( LodData* data ) - { - injectProfile(data); - mProfile.clear(); - mCostCalculator->initCollapseCosts(data); - } + void LodCollapseCostProfiler::initCollapseCosts( LodData* data ) + { + injectProfile(data); + mProfile.clear(); + mCostCalculator->initCollapseCosts(data); + } } diff --git a/Components/MeshLodGenerator/src/OgreLodCollapseCostQuadric.cpp b/Components/MeshLodGenerator/src/OgreLodCollapseCostQuadric.cpp index 49ecd468141..2a52a0cbe6e 100644 --- a/Components/MeshLodGenerator/src/OgreLodCollapseCostQuadric.cpp +++ b/Components/MeshLodGenerator/src/OgreLodCollapseCostQuadric.cpp @@ -38,87 +38,87 @@ namespace Ogre { - void LodCollapseCostQuadric::initCollapseCosts( LodData* data ) - { - mTrianglePlaneQuadricList.resize(data->mTriangleList.size()); - for(size_t i=0;imVertexList.size()); - for (size_t i=0;imTriangleList[triangleID]; - Matrix4& quadric = mTrianglePlaneQuadricList[triangleID]; - Real plane[4]; - plane[0] = triangle.normal.x; - plane[1] = triangle.normal.y; - plane[2] = triangle.normal.z; - Vector3& v0 = triangle.vertex[0]->position; - plane[3] = -v0.dotProduct(triangle.normal); - for(int i=0;i<4;i++){ - for(int n=0;n<4;n++){ - quadric[i][n] = plane[i] * plane[n]; - } - } - } - - Real LodCollapseCostQuadric::computeEdgeCollapseCost( LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge ) - { - LodData::Vertex* dst = dstEdge->dst; - - if (isBorderVertex(src)) { - return LodData::NEVER_COLLAPSE_COST; - } - if (src->seam && !dst->seam) { - return LodData::NEVER_COLLAPSE_COST; - } - - Matrix4 Qnew = mVertexQuadricList[LodData::getVectorIDFromPointer(data->mVertexList, src)] + - mVertexQuadricList[LodData::getVectorIDFromPointer(data->mVertexList, dst)]; - - Vector4 Vnew(dst->position); - - // error = Vnew^T * Qnew * Vnew - Real cost = - (Vnew[0] * Qnew[0][0] + Vnew[1] * Qnew[0][1] + Vnew[2] * Qnew[0][2] + Vnew[3] * Qnew[0][3]) * Vnew[0] + - (Vnew[0] * Qnew[1][0] + Vnew[1] * Qnew[1][1] + Vnew[2] * Qnew[1][2] + Vnew[3] * Qnew[1][3]) * Vnew[1] + - (Vnew[0] * Qnew[2][0] + Vnew[1] * Qnew[2][1] + Vnew[2] * Qnew[2][2] + Vnew[3] * Qnew[2][3]) * Vnew[2] + - (Vnew[0] * Qnew[3][0] + Vnew[1] * Qnew[3][1] + Vnew[2] * Qnew[3][2] + Vnew[3] * Qnew[3][3]) * Vnew[3]; - - if (dst->seam) { - cost *= 8; - } - - return cost; - - } - - void LodCollapseCostQuadric::computeVertexQuadric( LodData* data, size_t vertexID ) - { - Matrix4& quadric = mVertexQuadricList[vertexID]; - quadric = Matrix4::ZERO; - LodData::Vertex& vertex = data->mVertexList[vertexID]; - LodData::VTriangles::iterator tri, triEnd; - tri = vertex.triangles.begin(); - triEnd = vertex.triangles.end(); - for (;tri != triEnd; ++tri) { - size_t id = LodData::getVectorIDFromPointer(data->mTriangleList, *tri); - quadric = quadric + mTrianglePlaneQuadricList[id]; - } - } - - void LodCollapseCostQuadric::updateVertexCollapseCost( LodData* data, LodData::Vertex* vertex ) - { - computeVertexQuadric(data, LodData::getVectorIDFromPointer(data->mVertexList, vertex)); - - LodCollapseCost::updateVertexCollapseCost(data, vertex); - } + void LodCollapseCostQuadric::initCollapseCosts( LodData* data ) + { + mTrianglePlaneQuadricList.resize(data->mTriangleList.size()); + for(size_t i=0;imVertexList.size()); + for (size_t i=0;imTriangleList[triangleID]; + Matrix4& quadric = mTrianglePlaneQuadricList[triangleID]; + Real plane[4]; + plane[0] = triangle.normal.x; + plane[1] = triangle.normal.y; + plane[2] = triangle.normal.z; + Vector3& v0 = triangle.vertex[0]->position; + plane[3] = -v0.dotProduct(triangle.normal); + for(int i=0;i<4;i++){ + for(int n=0;n<4;n++){ + quadric[i][n] = plane[i] * plane[n]; + } + } + } + + Real LodCollapseCostQuadric::computeEdgeCollapseCost( LodData* data, LodData::Vertex* src, LodData::Edge* dstEdge ) + { + LodData::Vertex* dst = dstEdge->dst; + + if (isBorderVertex(src)) { + return LodData::NEVER_COLLAPSE_COST; + } + if (src->seam && !dst->seam) { + return LodData::NEVER_COLLAPSE_COST; + } + + Matrix4 Qnew = mVertexQuadricList[LodData::getVectorIDFromPointer(data->mVertexList, src)] + + mVertexQuadricList[LodData::getVectorIDFromPointer(data->mVertexList, dst)]; + + Vector4 Vnew(dst->position); + + // error = Vnew^T * Qnew * Vnew + Real cost = + (Vnew[0] * Qnew[0][0] + Vnew[1] * Qnew[0][1] + Vnew[2] * Qnew[0][2] + Vnew[3] * Qnew[0][3]) * Vnew[0] + + (Vnew[0] * Qnew[1][0] + Vnew[1] * Qnew[1][1] + Vnew[2] * Qnew[1][2] + Vnew[3] * Qnew[1][3]) * Vnew[1] + + (Vnew[0] * Qnew[2][0] + Vnew[1] * Qnew[2][1] + Vnew[2] * Qnew[2][2] + Vnew[3] * Qnew[2][3]) * Vnew[2] + + (Vnew[0] * Qnew[3][0] + Vnew[1] * Qnew[3][1] + Vnew[2] * Qnew[3][2] + Vnew[3] * Qnew[3][3]) * Vnew[3]; + + if (dst->seam) { + cost *= 8; + } + + return cost; + + } + + void LodCollapseCostQuadric::computeVertexQuadric( LodData* data, size_t vertexID ) + { + Matrix4& quadric = mVertexQuadricList[vertexID]; + quadric = Matrix4::ZERO; + LodData::Vertex& vertex = data->mVertexList[vertexID]; + LodData::VTriangles::iterator tri, triEnd; + tri = vertex.triangles.begin(); + triEnd = vertex.triangles.end(); + for (;tri != triEnd; ++tri) { + size_t id = LodData::getVectorIDFromPointer(data->mTriangleList, *tri); + quadric = quadric + mTrianglePlaneQuadricList[id]; + } + } + + void LodCollapseCostQuadric::updateVertexCollapseCost( LodData* data, LodData::Vertex* vertex ) + { + computeVertexQuadric(data, LodData::getVectorIDFromPointer(data->mVertexList, vertex)); + + LodCollapseCost::updateVertexCollapseCost(data, vertex); + } diff --git a/Components/MeshLodGenerator/src/OgreLodCollapser.cpp b/Components/MeshLodGenerator/src/OgreLodCollapser.cpp index 5f1fba7747d..1f845090ddc 100644 --- a/Components/MeshLodGenerator/src/OgreLodCollapser.cpp +++ b/Components/MeshLodGenerator/src/OgreLodCollapser.cpp @@ -34,302 +34,302 @@ namespace Ogre { - void LodCollapser::collapse( LodData* data, LodCollapseCost* cost, LodOutputProvider* output, int vertexCountLimit, Real collapseCostLimit ) - { - size_t vertexCount = data->mCollapseCostHeap.size(); - for (; static_cast(vertexCountLimit) < vertexCount; vertexCount--) + void LodCollapser::collapse( LodData* data, LodCollapseCost* cost, LodOutputProvider* output, int vertexCountLimit, Real collapseCostLimit ) + { + size_t vertexCount = data->mCollapseCostHeap.size(); + for (; static_cast(vertexCountLimit) < vertexCount; vertexCount--) { - LodData::CollapseCostHeap::iterator nextVertex = data->mCollapseCostHeap.begin(); - if (nextVertex != data->mCollapseCostHeap.end() && nextVertex->first < collapseCostLimit) + LodData::CollapseCostHeap::iterator nextVertex = data->mCollapseCostHeap.begin(); + if (nextVertex != data->mCollapseCostHeap.end() && nextVertex->first < collapseCostLimit) { - mLastReducedVertex = nextVertex->second; - collapseVertex(data, cost, output, mLastReducedVertex); - } else { - break; - } - } - } + mLastReducedVertex = nextVertex->second; + collapseVertex(data, cost, output, mLastReducedVertex); + } else { + break; + } + } + } #if OGRE_DEBUG_MODE - void LodCollapser::assertValidMesh(LodData* data) - { - // Allows to find bugs in collapsing. - // size_t s1 = mUniqueVertexSet.size(); - // size_t s2 = mCollapseCostHeap.size(); - LodData::CollapseCostHeap::iterator it = data->mCollapseCostHeap.begin(); - LodData::CollapseCostHeap::iterator itEnd = data->mCollapseCostHeap.end(); - while (it != itEnd) { - assertValidVertex(data, it->second); - it++; - } - } + void LodCollapser::assertValidMesh(LodData* data) + { + // Allows to find bugs in collapsing. + // size_t s1 = mUniqueVertexSet.size(); + // size_t s2 = mCollapseCostHeap.size(); + LodData::CollapseCostHeap::iterator it = data->mCollapseCostHeap.begin(); + LodData::CollapseCostHeap::iterator itEnd = data->mCollapseCostHeap.end(); + while (it != itEnd) { + assertValidVertex(data, it->second); + it++; + } + } - void LodCollapser::assertValidVertex(LodData* data, LodData::Vertex* v) - { - // Allows to find bugs in collapsing. - LodData::VTriangles::iterator it = v->triangles.begin(); - LodData::VTriangles::iterator itEnd = v->triangles.end(); - for (; it != itEnd; it++) { - LodData::Triangle* t = *it; - for (int i = 0; i < 3; i++) { - OgreAssert(t->vertex[i]->costHeapPosition != data->mCollapseCostHeap.end(), ""); - t->vertex[i]->edges.findExists(LodData::Edge(t->vertex[i]->collapseTo)); - for (int n = 0; n < 3; n++) { - if (i != n) { - LodData::VEdges::iterator edgeIt = t->vertex[i]->edges.findExists(LodData::Edge(t->vertex[n])); - OgreAssert(edgeIt->collapseCost != LodData::UNINITIALIZED_COLLAPSE_COST, ""); - } else { - OgreAssert(t->vertex[i]->edges.find(LodData::Edge(t->vertex[n])) == t->vertex[i]->edges.end(), ""); - } - } - } - } - } + void LodCollapser::assertValidVertex(LodData* data, LodData::Vertex* v) + { + // Allows to find bugs in collapsing. + LodData::VTriangles::iterator it = v->triangles.begin(); + LodData::VTriangles::iterator itEnd = v->triangles.end(); + for (; it != itEnd; it++) { + LodData::Triangle* t = *it; + for (int i = 0; i < 3; i++) { + OgreAssert(t->vertex[i]->costHeapPosition != data->mCollapseCostHeap.end(), ""); + t->vertex[i]->edges.findExists(LodData::Edge(t->vertex[i]->collapseTo)); + for (int n = 0; n < 3; n++) { + if (i != n) { + LodData::VEdges::iterator edgeIt = t->vertex[i]->edges.findExists(LodData::Edge(t->vertex[n])); + OgreAssert(edgeIt->collapseCost != LodData::UNINITIALIZED_COLLAPSE_COST, ""); + } else { + OgreAssert(t->vertex[i]->edges.find(LodData::Edge(t->vertex[n])) == t->vertex[i]->edges.end(), ""); + } + } + } + } + } - void LodCollapser::assertOutdatedCollapseCost( LodData* data, LodCollapseCost* cost, LodData::Vertex* vertex ) - { - // Validates that collapsing has updated all edges needed by computeEdgeCollapseCost. - // This will OgreAssert if the dependencies inside computeEdgeCollapseCost changes. - LodData::VEdges::iterator it = vertex->edges.begin(); - LodData::VEdges::iterator itEnd = vertex->edges.end(); - for (; it != itEnd; it++) { - OgreAssert(it->collapseCost == cost->computeEdgeCollapseCost(data, vertex, &*it), ""); - LodData::Vertex* neighbor = it->dst; - LodData::VEdges::iterator it2 = neighbor->edges.begin(); - LodData::VEdges::iterator it2End = neighbor->edges.end(); - for (; it2 != it2End; it2++) { - OgreAssert(it2->collapseCost == cost->computeEdgeCollapseCost(data, neighbor, &*it2), ""); - } - } - } + void LodCollapser::assertOutdatedCollapseCost( LodData* data, LodCollapseCost* cost, LodData::Vertex* vertex ) + { + // Validates that collapsing has updated all edges needed by computeEdgeCollapseCost. + // This will OgreAssert if the dependencies inside computeEdgeCollapseCost changes. + LodData::VEdges::iterator it = vertex->edges.begin(); + LodData::VEdges::iterator itEnd = vertex->edges.end(); + for (; it != itEnd; it++) { + OgreAssert(it->collapseCost == cost->computeEdgeCollapseCost(data, vertex, &*it), ""); + LodData::Vertex* neighbor = it->dst; + LodData::VEdges::iterator it2 = neighbor->edges.begin(); + LodData::VEdges::iterator it2End = neighbor->edges.end(); + for (; it2 != it2End; it2++) { + OgreAssert(it2->collapseCost == cost->computeEdgeCollapseCost(data, neighbor, &*it2), ""); + } + } + } #endif // if OGRE_DEBUG_MODE - bool LodCollapser::hasSrcID(unsigned int srcID, unsigned short submeshID) - { - // This will only return exact matches. - for (size_t i = 0; i < tmpCollapsedEdges.size(); i++) { - if (tmpCollapsedEdges[i].srcID == srcID && tmpCollapsedEdges[i].submeshID == submeshID) { - return true; - } - } - return false; // Not found - } - void LodCollapser::removeTriangleFromEdges(LodData::Triangle* triangle, LodData::Vertex* skip) - { - triangle->isRemoved = true; - // skip is needed if we are iterating on the vertex's edges or triangles. - for (int i = 0; i < 3; i++) { - if (triangle->vertex[i] != skip) { - triangle->vertex[i]->triangles.removeExists(triangle); - } - } - for (int i = 0; i < 3; i++) { - for (int n = 0; n < 3; n++) { - if (i != n && triangle->vertex[i] != skip) { - triangle->vertex[i]->removeEdge(LodData::Edge(triangle->vertex[n])); - } - } - } - } + bool LodCollapser::hasSrcID(unsigned int srcID, unsigned short submeshID) + { + // This will only return exact matches. + for (size_t i = 0; i < tmpCollapsedEdges.size(); i++) { + if (tmpCollapsedEdges[i].srcID == srcID && tmpCollapsedEdges[i].submeshID == submeshID) { + return true; + } + } + return false; // Not found + } + void LodCollapser::removeTriangleFromEdges(LodData::Triangle* triangle, LodData::Vertex* skip) + { + triangle->isRemoved = true; + // skip is needed if we are iterating on the vertex's edges or triangles. + for (int i = 0; i < 3; i++) { + if (triangle->vertex[i] != skip) { + triangle->vertex[i]->triangles.removeExists(triangle); + } + } + for (int i = 0; i < 3; i++) { + for (int n = 0; n < 3; n++) { + if (i != n && triangle->vertex[i] != skip) { + triangle->vertex[i]->removeEdge(LodData::Edge(triangle->vertex[n])); + } + } + } + } - size_t LodCollapser::findDstID(unsigned int srcID, unsigned short submeshID) - { - // Tries to find a compatible edge. + size_t LodCollapser::findDstID(unsigned int srcID, unsigned short submeshID) + { + // Tries to find a compatible edge. - // Exact match search. - for (size_t i = 0; i < tmpCollapsedEdges.size(); i++) { - if (tmpCollapsedEdges[i].srcID == srcID && tmpCollapsedEdges[i].submeshID == submeshID) { - return i; - } - } + // Exact match search. + for (size_t i = 0; i < tmpCollapsedEdges.size(); i++) { + if (tmpCollapsedEdges[i].srcID == srcID && tmpCollapsedEdges[i].submeshID == submeshID) { + return i; + } + } - // Usable match search. - for (size_t i = 0; i < tmpCollapsedEdges.size(); i++) { - if (tmpCollapsedEdges[i].submeshID == submeshID) { - return i; - } - } - return std::numeric_limits::max(); // Not found - } - void LodCollapser::replaceVertexID(LodData::Triangle* triangle, unsigned int oldID, unsigned int newID, LodData::Vertex* dst) - { - dst->triangles.addNotExists(triangle); - // NOTE: triangle is not removed from src. This is implementation specific optimization. + // Usable match search. + for (size_t i = 0; i < tmpCollapsedEdges.size(); i++) { + if (tmpCollapsedEdges[i].submeshID == submeshID) { + return i; + } + } + return std::numeric_limits::max(); // Not found + } + void LodCollapser::replaceVertexID(LodData::Triangle* triangle, unsigned int oldID, unsigned int newID, LodData::Vertex* dst) + { + dst->triangles.addNotExists(triangle); + // NOTE: triangle is not removed from src. This is implementation specific optimization. - // Its up to the compiler to unroll everything. - for (int i = 0; i < 3; i++) { - if (triangle->vertexID[i] == oldID) { - for (int n = 0; n < 3; n++) { - if (i != n) { - // This is implementation specific optimization to remove following line. - // triangle->vertex[i]->removeEdge(LodData::Edge(triangle->vertex[n])); + // Its up to the compiler to unroll everything. + for (int i = 0; i < 3; i++) { + if (triangle->vertexID[i] == oldID) { + for (int n = 0; n < 3; n++) { + if (i != n) { + // This is implementation specific optimization to remove following line. + // triangle->vertex[i]->removeEdge(LodData::Edge(triangle->vertex[n])); - triangle->vertex[n]->removeEdge(LodData::Edge(triangle->vertex[i])); - triangle->vertex[n]->addEdge(LodData::Edge(dst)); - dst->addEdge(LodData::Edge(triangle->vertex[n])); - } - } - triangle->vertex[i] = dst; - triangle->vertexID[i] = newID; - return; - } - } - OgreAssert(0, ""); - } - void LodCollapser::collapseVertex( LodData* data, LodCollapseCost* cost, LodOutputProvider* output, LodData::Vertex* src ) - { - LodData::Vertex* dst = src->collapseTo; + triangle->vertex[n]->removeEdge(LodData::Edge(triangle->vertex[i])); + triangle->vertex[n]->addEdge(LodData::Edge(dst)); + dst->addEdge(LodData::Edge(triangle->vertex[n])); + } + } + triangle->vertex[i] = dst; + triangle->vertexID[i] = newID; + return; + } + } + OgreAssert(0, ""); + } + void LodCollapser::collapseVertex( LodData* data, LodCollapseCost* cost, LodOutputProvider* output, LodData::Vertex* src ) + { + LodData::Vertex* dst = src->collapseTo; #if OGRE_DEBUG_MODE - assertValidVertex(data, dst); - assertValidVertex(data, src); + assertValidVertex(data, dst); + assertValidVertex(data, src); #endif - OgreAssert(src->costHeapPosition->first != LodData::NEVER_COLLAPSE_COST, ""); - OgreAssert(src->costHeapPosition->first != LodData::UNINITIALIZED_COLLAPSE_COST, ""); - OgreAssert(!src->edges.empty(), ""); - OgreAssert(!src->triangles.empty(), ""); - OgreAssert(src->edges.find(LodData::Edge(dst)) != src->edges.end(), ""); + OgreAssert(src->costHeapPosition->first != LodData::NEVER_COLLAPSE_COST, ""); + OgreAssert(src->costHeapPosition->first != LodData::UNINITIALIZED_COLLAPSE_COST, ""); + OgreAssert(!src->edges.empty(), ""); + OgreAssert(!src->triangles.empty(), ""); + OgreAssert(src->edges.find(LodData::Edge(dst)) != src->edges.end(), ""); - // It may have vertexIDs and triangles from different submeshes(different vertex buffers), - // so we need to connect them correctly based on deleted triangle's edge. - // mCollapsedEdgeIDs will be used, when looking up the connections for replacement. - tmpCollapsedEdges.clear(); - LodData::VTriangles::iterator it = src->triangles.begin(); - LodData::VTriangles::iterator itEnd = src->triangles.end(); - for (; it != itEnd; ++it) { - LodData::Triangle* triangle = *it; - if (triangle->hasVertex(dst)) { - // Remove a triangle - // Tasks: - // 1. Add it to the collapsed edges list. - // 2. Reduce index count for the Lods, which will not have this triangle. - // 3. Remove references/pointers to this triangle and mark as removed. + // It may have vertexIDs and triangles from different submeshes(different vertex buffers), + // so we need to connect them correctly based on deleted triangle's edge. + // mCollapsedEdgeIDs will be used, when looking up the connections for replacement. + tmpCollapsedEdges.clear(); + LodData::VTriangles::iterator it = src->triangles.begin(); + LodData::VTriangles::iterator itEnd = src->triangles.end(); + for (; it != itEnd; ++it) { + LodData::Triangle* triangle = *it; + if (triangle->hasVertex(dst)) { + // Remove a triangle + // Tasks: + // 1. Add it to the collapsed edges list. + // 2. Reduce index count for the Lods, which will not have this triangle. + // 3. Remove references/pointers to this triangle and mark as removed. - // 1. task - unsigned int srcID = triangle->getVertexID(src); - if (!hasSrcID(srcID, triangle->submeshID)) { - tmpCollapsedEdges.push_back(CollapsedEdge()); - tmpCollapsedEdges.back().srcID = srcID; - tmpCollapsedEdges.back().dstID = triangle->getVertexID(dst); - tmpCollapsedEdges.back().submeshID = triangle->submeshID; - } + // 1. task + unsigned int srcID = triangle->getVertexID(src); + if (!hasSrcID(srcID, triangle->submeshID)) { + tmpCollapsedEdges.push_back(CollapsedEdge()); + tmpCollapsedEdges.back().srcID = srcID; + tmpCollapsedEdges.back().dstID = triangle->getVertexID(dst); + tmpCollapsedEdges.back().submeshID = triangle->submeshID; + } - // 2. task - data->mIndexBufferInfoList[triangle->submeshID].indexCount -= 3; - output->triangleRemoved(data, triangle); - // 3. task - removeTriangleFromEdges(triangle, src); + // 2. task + data->mIndexBufferInfoList[triangle->submeshID].indexCount -= 3; + output->triangleRemoved(data, triangle); + // 3. task + removeTriangleFromEdges(triangle, src); - } - } - OgreAssert(tmpCollapsedEdges.size(), ""); - OgreAssert(dst->edges.find(LodData::Edge(src)) == dst->edges.end(), ""); + } + } + OgreAssert(tmpCollapsedEdges.size(), ""); + OgreAssert(dst->edges.find(LodData::Edge(src)) == dst->edges.end(), ""); - it = src->triangles.begin(); - for (; it != itEnd; ++it) { - LodData::Triangle* triangle = *it; - if (!triangle->hasVertex(dst)) { - // Replace a triangle - // Tasks: - // 1. Determine the edge which we will move along. (we need to modify single vertex only) - // 2. Move along the selected edge. + it = src->triangles.begin(); + for (; it != itEnd; ++it) { + LodData::Triangle* triangle = *it; + if (!triangle->hasVertex(dst)) { + // Replace a triangle + // Tasks: + // 1. Determine the edge which we will move along. (we need to modify single vertex only) + // 2. Move along the selected edge. - // 1. task - unsigned int srcID = triangle->getVertexID(src); - size_t id = findDstID(srcID, triangle->submeshID); - if (id == std::numeric_limits::max()) { - // Not found any edge to move along. - // Destroy the triangle. - data->mIndexBufferInfoList[triangle->submeshID].indexCount -= 3; - output->triangleRemoved(data, triangle); - removeTriangleFromEdges(triangle, src); - continue; - } - unsigned int dstID = tmpCollapsedEdges[id].dstID; + // 1. task + unsigned int srcID = triangle->getVertexID(src); + size_t id = findDstID(srcID, triangle->submeshID); + if (id == std::numeric_limits::max()) { + // Not found any edge to move along. + // Destroy the triangle. + data->mIndexBufferInfoList[triangle->submeshID].indexCount -= 3; + output->triangleRemoved(data, triangle); + removeTriangleFromEdges(triangle, src); + continue; + } + unsigned int dstID = tmpCollapsedEdges[id].dstID; - // 2. task - replaceVertexID(triangle, srcID, dstID, dst); + // 2. task + replaceVertexID(triangle, srcID, dstID, dst); - output->triangleChanged(data, triangle); + output->triangleChanged(data, triangle); #if MESHLOD_QUALITY >= 3 - triangle->computeNormal(); + triangle->computeNormal(); #endif - } - } + } + } - dst->seam |= src->seam; // Inherit seam property + dst->seam |= src->seam; // Inherit seam property #if MESHLOD_QUALITY <= 2 - LodData::VEdges::iterator it3 = src->edges.begin(); - LodData::VEdges::iterator it3End = src->edges.end(); - for (; it3 != it3End; ++it3) { - cost->updateVertexCollapseCost(data, it3->dst); - } + LodData::VEdges::iterator it3 = src->edges.begin(); + LodData::VEdges::iterator it3End = src->edges.end(); + for (; it3 != it3End; ++it3) { + cost->updateVertexCollapseCost(data, it3->dst); + } #else - // TODO: Find out why is this needed. assertOutdatedCollapseCost() fails on some - // rare situations without this. For example goblin.mesh fails. - typedef SmallVector UpdatableList; - UpdatableList updatable; - LodData::VEdges::iterator it3 = src->edges.begin(); - LodData::VEdges::iterator it3End = src->edges.end(); - for (; it3 != it3End; it3++) { - updatable.push_back(it3->dst); - LodData::VEdges::iterator it4End = it3->dst->edges.end(); - LodData::VEdges::iterator it4 = it3->dst->edges.begin(); - for (; it4 != it4End; it4++) { - updatable.push_back(it4->dst); - } - } + // TODO: Find out why is this needed. assertOutdatedCollapseCost() fails on some + // rare situations without this. For example goblin.mesh fails. + typedef SmallVector UpdatableList; + UpdatableList updatable; + LodData::VEdges::iterator it3 = src->edges.begin(); + LodData::VEdges::iterator it3End = src->edges.end(); + for (; it3 != it3End; it3++) { + updatable.push_back(it3->dst); + LodData::VEdges::iterator it4End = it3->dst->edges.end(); + LodData::VEdges::iterator it4 = it3->dst->edges.begin(); + for (; it4 != it4End; it4++) { + updatable.push_back(it4->dst); + } + } - // Remove duplicates. - UpdatableList::iterator it5 = updatable.begin(); - UpdatableList::iterator it5End = updatable.end(); - std::sort(it5, it5End); - it5End = std::unique(it5, it5End); + // Remove duplicates. + UpdatableList::iterator it5 = updatable.begin(); + UpdatableList::iterator it5End = updatable.end(); + std::sort(it5, it5End); + it5End = std::unique(it5, it5End); - for (; it5 != it5End; it5++) { - cost->updateVertexCollapseCost(data, *it5); - } + for (; it5 != it5End; it5++) { + cost->updateVertexCollapseCost(data, *it5); + } #if OGRE_DEBUG_MODE - it3 = src->edges.begin(); - it3End = src->edges.end(); - for (; it3 != it3End; it3++) { - assertOutdatedCollapseCost(data, cost, it3->dst); - } - it3 = dst->edges.begin(); - it3End = dst->edges.end(); - for (; it3 != it3End; it3++) { - assertOutdatedCollapseCost(data, cost, it3->dst); - } - assertOutdatedCollapseCost(data, cost, dst); + it3 = src->edges.begin(); + it3End = src->edges.end(); + for (; it3 != it3End; it3++) { + assertOutdatedCollapseCost(data, cost, it3->dst); + } + it3 = dst->edges.begin(); + it3End = dst->edges.end(); + for (; it3 != it3End; it3++) { + assertOutdatedCollapseCost(data, cost, it3->dst); + } + assertOutdatedCollapseCost(data, cost, dst); #endif // ifndef OGRE_DEBUG_MODE #endif // ifndef MESHLOD_QUALITY - data->mCollapseCostHeap.erase(src->costHeapPosition); // Remove src from collapse costs. - src->edges.clear(); // Free memory - src->triangles.clear(); // Free memory + data->mCollapseCostHeap.erase(src->costHeapPosition); // Remove src from collapse costs. + src->edges.clear(); // Free memory + src->triangles.clear(); // Free memory #if OGRE_DEBUG_MODE - src->costHeapPosition = data->mCollapseCostHeap.end(); - assertValidVertex(data, dst); + src->costHeapPosition = data->mCollapseCostHeap.end(); + assertValidVertex(data, dst); #endif - } + } - bool LodCollapser::_getLastVertexPos(LodData* data, Vector3& outVec) - { - if(mLastReducedVertex){ - outVec = mLastReducedVertex->position; - return true; - } else { - return false; - } - } + bool LodCollapser::_getLastVertexPos(LodData* data, Vector3& outVec) + { + if(mLastReducedVertex){ + outVec = mLastReducedVertex->position; + return true; + } else { + return false; + } + } - bool LodCollapser::_getLastVertexCollapseTo(LodData* data, Vector3& outVec ) - { - if(mLastReducedVertex){ - outVec = mLastReducedVertex->collapseTo->position; - return true; - } else { - return false; - } - } + bool LodCollapser::_getLastVertexCollapseTo(LodData* data, Vector3& outVec ) + { + if(mLastReducedVertex){ + outVec = mLastReducedVertex->collapseTo->position; + return true; + } else { + return false; + } + } } diff --git a/Components/MeshLodGenerator/src/OgreLodConfig.cpp b/Components/MeshLodGenerator/src/OgreLodConfig.cpp index 6fe6a75e06a..dbe608df1e1 100644 --- a/Components/MeshLodGenerator/src/OgreLodConfig.cpp +++ b/Components/MeshLodGenerator/src/OgreLodConfig.cpp @@ -33,10 +33,10 @@ namespace Ogre LodConfig::Advanced::Advanced() : useBackgroundQueue(false), - useCompression(true), - useVertexNormals(true), - outsideWeight(0.0), - outsideWalkAngle(0.0) + useCompression(true), + useVertexNormals(true), + outsideWeight(0.0), + outsideWalkAngle(0.0) { } diff --git a/Components/MeshLodGenerator/src/OgreLodConfigSerializer.cpp b/Components/MeshLodGenerator/src/OgreLodConfigSerializer.cpp index 89468c535ae..7a9b61cde37 100644 --- a/Components/MeshLodGenerator/src/OgreLodConfigSerializer.cpp +++ b/Components/MeshLodGenerator/src/OgreLodConfigSerializer.cpp @@ -39,323 +39,323 @@ THE SOFTWARE. namespace Ogre { - LodConfigSerializer::LodConfigSerializer() - { - mVersion = "[LodConfigSerializer_v1.0]"; + LodConfigSerializer::LodConfigSerializer() + { + mVersion = "[LodConfigSerializer_v1.0]"; mLodConfig = 0; - } - - void LodConfigSerializer::importLodConfig(Ogre::LodConfig* config, const Ogre::String& filename) - { - std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); - f->open(filename.c_str(), std::ios::binary | std::ios::in); - if(f->is_open()){ - Ogre::DataStreamPtr stream(OGRE_NEW Ogre::FileStreamDataStream(f)); - - importLodConfig(config, stream); - - stream->close(); - } - } - - void LodConfigSerializer::importLodConfig(Ogre::LodConfig* config, DataStreamPtr& stream) - { - mStream = stream; - mLodConfig = config; - - // Determine endianness (must be the first thing we do!) - determineEndianness(mStream); - - // Check header - readFileHeader(mStream); - - pushInnerChunk(mStream); - while (!mStream->eof()) - { - unsigned short streamID = readChunk(mStream); - switch (streamID) - { - case LCCID_LOD_CONFIG: - readLodConfig(); - break; - default: - backpedalChunkHeader(mStream); - popInnerChunk(mStream); - return; - } - } - popInnerChunk(mStream); - } - - void LodConfigSerializer::readLodConfig() - { - pushInnerChunk(mStream); - while(!mStream->eof()) - { - unsigned short streamID = readChunk(mStream); - switch(streamID) - { - case LCCID_BASIC_INFO: - readLodBasicInfo(); - break; - case LCCID_LOD_LEVELS: - readLodLevels(); - break; - case LCCID_ADVANCED_INFO: - readLodAdvancedInfo(); - break; - case LCCID_PROFILE: - readLodProfile(); - break; - default: - // Backpedal back to start of stream - backpedalChunkHeader(mStream); - popInnerChunk(mStream); - return; - } - } - popInnerChunk(mStream); - } - - void LodConfigSerializer::readLodBasicInfo() - { - String group = readString(mStream); - String name = readString(mStream); - mLodConfig->mesh = MeshManager::getSingleton().load(name, group); - - String strategyName = readString(mStream); - mLodConfig->strategy = LodStrategyManager::getSingleton().getStrategy(strategyName); - } - - void LodConfigSerializer::readLodLevels() - { - uint32 size = 0; - readInts(mStream, &size, 1); - mLodConfig->levels.clear(); - while(size--){ - LodLevel level; - readFloats(mStream, &level.distance, 1); - readInts(mStream, (Ogre::uint32*)&level.reductionMethod, 1); - readFloats(mStream, &level.reductionValue, 1); - level.manualMeshName = readString(mStream); - mLodConfig->levels.push_back(level); - } - } - - void LodConfigSerializer::readLodAdvancedInfo() - { - readBools(mStream, &mLodConfig->advanced.useCompression, 1); - readBools(mStream, &mLodConfig->advanced.useVertexNormals, 1); - readBools(mStream, &mLodConfig->advanced.useBackgroundQueue, 1); - readFloats(mStream, &mLodConfig->advanced.outsideWeight, 1); - readFloats(mStream, &mLodConfig->advanced.outsideWalkAngle, 1); - } - - void LodConfigSerializer::readLodProfile() - { - uint32 size = 0; - readInts(mStream, &size, 1); - mLodConfig->advanced.profile.clear(); - while(size--){ - ProfiledEdge pv; - readObject(mStream, pv.src); - readObject(mStream, pv.dst); - readFloats(mStream, &pv.cost, 1); - mLodConfig->advanced.profile.push_back(pv); - } - } - - void LodConfigSerializer::exportLodConfig(Ogre::LodConfig& config, const Ogre::String& filename, Endian endianMode /*= ENDIAN_NATIVE*/ ) - { - std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); - f->open(filename.c_str(), std::ios::binary | std::ios::out); - Ogre::DataStreamPtr stream(OGRE_NEW Ogre::FileStreamDataStream(f)); - - exportLodConfig(config, stream, endianMode); - - stream->close(); - } - - void LodConfigSerializer::exportLodConfig(Ogre::LodConfig& config, Ogre::DataStreamPtr stream, Endian endianMode /*= ENDIAN_NATIVE*/ ) - { - Ogre::LogManager::getSingleton().logMessage("MeshSerializer writing mesh data to stream " + stream->getName() + "..."); - - // Decide on endian mode - determineEndianness(endianMode); - mLodConfig = &config; - mStream = stream; - if (!stream->isWriteable()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unable to use stream " + stream->getName() + " for writing", - "LodConfigSerializer::export"); - } - - writeFileHeader(); - LogManager::getSingleton().logMessage("File header written."); - - - LogManager::getSingleton().logMessage("Writing Lod Config..."); - pushInnerChunk(mStream); - writeLodConfig(); - popInnerChunk(mStream); - LogManager::getSingleton().logMessage("LodConfigSerializer export successful."); - } - - void LodConfigSerializer::writeLodConfig() - { - writeChunkHeader(LCCID_LOD_CONFIG, calcLodConfigSize()); - pushInnerChunk(mStream); - writeLodBasicInfo(); - writeLodLevels(); - writeLodAdvancedInfo(); - writeLodProfile(); - popInnerChunk(mStream); - } - - size_t LodConfigSerializer::calcLodConfigSize() - { - size_t size = calcChunkHeaderSize(); - - size += calcLodBasicInfoSize(); - - size += calcLodLevelsSize(); - - size += calcLodAdvancedInfoSize(); - - size += calcLodProfileSize(); - - return size; - } - - void LodConfigSerializer::writeLodBasicInfo() - { - writeChunkHeader(LCCID_BASIC_INFO, calcLodBasicInfoSize()); - writeString(mLodConfig->mesh->getGroup()); - writeString(mLodConfig->mesh->getName()); - writeString(mLodConfig->strategy->getName()); - } - - size_t LodConfigSerializer::calcLodBasicInfoSize() - { - size_t size = calcChunkHeaderSize(); - - size += calcStringSize(mLodConfig->mesh->getGroup()); - size += calcStringSize(mLodConfig->mesh->getName()); - size += calcStringSize(mLodConfig->strategy->getName()); - - return size; - } - - void LodConfigSerializer::writeLodLevels() - { - writeChunkHeader(LCCID_LOD_LEVELS, calcLodLevelsSize()); - uint32 size = static_cast(mLodConfig->levels.size()); - writeInts(&size, 1); - - LodConfig::LodLevelList::iterator it = mLodConfig->levels.begin(); - LodConfig::LodLevelList::iterator itEnd = mLodConfig->levels.end(); - for(;it != itEnd; it++){ - writeFloats(&it->distance, 1); - writeInts((Ogre::uint32*)&it->reductionMethod, 1); - writeFloats(&it->reductionValue, 1); - writeString(it->manualMeshName); - } - } - - size_t LodConfigSerializer::calcLodLevelsSize() - { - //lodLevel.distance - size_t levelSize = sizeof(float); - - //lodLevel.reductionMethod; - levelSize += sizeof(Ogre::uint32); - - //lodLevel.reductionValue; - levelSize += sizeof(float); - - size_t size = calcChunkHeaderSize(); - - // mLodConfig->levels.size() - size += sizeof(Ogre::uint32); - - size += levelSize * mLodConfig->levels.size(); - - for(size_t i = 0; i < mLodConfig->levels.size(); i++) { - size += calcStringSize(mLodConfig->levels[i].manualMeshName); - } - - return size; - } - - void LodConfigSerializer::writeLodAdvancedInfo() - { - writeChunkHeader(LCCID_ADVANCED_INFO, calcLodAdvancedInfoSize()); - writeBools(&mLodConfig->advanced.useCompression, 1); - writeBools(&mLodConfig->advanced.useVertexNormals, 1); - writeBools(&mLodConfig->advanced.useBackgroundQueue, 1); - writeFloats(&mLodConfig->advanced.outsideWeight, 1); - writeFloats(&mLodConfig->advanced.outsideWalkAngle, 1); - } - - size_t LodConfigSerializer::calcLodAdvancedInfoSize() - { - size_t size = calcChunkHeaderSize(); - - // mLodConfig->advanced.useCompression - size += sizeof(bool); - // mLodConfig->advanced.useVertexNormals - size += sizeof(bool); - // mLodConfig->advanced.useBackgroundQueue - size += sizeof(bool); - // mLodConfig->advanced.outsideWeight - size += sizeof(float); - // mLodConfig->advanced.outsideWalkAngle - size += sizeof(float); - - return size; - } - - void LodConfigSerializer::writeLodProfile() - { - if(mLodConfig->advanced.profile.empty()){ - return; - } - writeChunkHeader(LCCID_PROFILE, calcLodProfileSize()); - uint32 size = static_cast(mLodConfig->advanced.profile.size()); - writeInts(&size, 1); - LodProfile::iterator it = mLodConfig->advanced.profile.begin(); - LodProfile::iterator itEnd = mLodConfig->advanced.profile.end(); - for(;it != itEnd; it++){ - writeObject(it->src); - writeObject(it->dst); - writeFloats(&it->cost, 1); - } - } - - size_t LodConfigSerializer::calcLodProfileSize() - { - if(mLodConfig->advanced.profile.empty()){ - return 0; - } - // Vector3, LodProfile::ProfiledVertex::src - size_t profiledVertexSize = sizeof(float) * 3; - - // Vector3, LodProfile::ProfiledVertex::dst - profiledVertexSize += sizeof(float) * 3; - - // LodProfile::ProfiledVertex::cost - profiledVertexSize += sizeof(float); - - - size_t size = calcChunkHeaderSize(); - - // mLodConfig->advanced.profile->data.size() - size += sizeof(uint32); - - size += profiledVertexSize * mLodConfig->advanced.profile.size(); - - return size; - } + } + + void LodConfigSerializer::importLodConfig(Ogre::LodConfig* config, const Ogre::String& filename) + { + std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); + f->open(filename.c_str(), std::ios::binary | std::ios::in); + if(f->is_open()){ + Ogre::DataStreamPtr stream(OGRE_NEW Ogre::FileStreamDataStream(f)); + + importLodConfig(config, stream); + + stream->close(); + } + } + + void LodConfigSerializer::importLodConfig(Ogre::LodConfig* config, DataStreamPtr& stream) + { + mStream = stream; + mLodConfig = config; + + // Determine endianness (must be the first thing we do!) + determineEndianness(mStream); + + // Check header + readFileHeader(mStream); + + pushInnerChunk(mStream); + while (!mStream->eof()) + { + unsigned short streamID = readChunk(mStream); + switch (streamID) + { + case LCCID_LOD_CONFIG: + readLodConfig(); + break; + default: + backpedalChunkHeader(mStream); + popInnerChunk(mStream); + return; + } + } + popInnerChunk(mStream); + } + + void LodConfigSerializer::readLodConfig() + { + pushInnerChunk(mStream); + while(!mStream->eof()) + { + unsigned short streamID = readChunk(mStream); + switch(streamID) + { + case LCCID_BASIC_INFO: + readLodBasicInfo(); + break; + case LCCID_LOD_LEVELS: + readLodLevels(); + break; + case LCCID_ADVANCED_INFO: + readLodAdvancedInfo(); + break; + case LCCID_PROFILE: + readLodProfile(); + break; + default: + // Backpedal back to start of stream + backpedalChunkHeader(mStream); + popInnerChunk(mStream); + return; + } + } + popInnerChunk(mStream); + } + + void LodConfigSerializer::readLodBasicInfo() + { + String group = readString(mStream); + String name = readString(mStream); + mLodConfig->mesh = MeshManager::getSingleton().load(name, group); + + String strategyName = readString(mStream); + mLodConfig->strategy = LodStrategyManager::getSingleton().getStrategy(strategyName); + } + + void LodConfigSerializer::readLodLevels() + { + uint32 size = 0; + readInts(mStream, &size, 1); + mLodConfig->levels.clear(); + while(size--){ + LodLevel level; + readFloats(mStream, &level.distance, 1); + readInts(mStream, (Ogre::uint32*)&level.reductionMethod, 1); + readFloats(mStream, &level.reductionValue, 1); + level.manualMeshName = readString(mStream); + mLodConfig->levels.push_back(level); + } + } + + void LodConfigSerializer::readLodAdvancedInfo() + { + readBools(mStream, &mLodConfig->advanced.useCompression, 1); + readBools(mStream, &mLodConfig->advanced.useVertexNormals, 1); + readBools(mStream, &mLodConfig->advanced.useBackgroundQueue, 1); + readFloats(mStream, &mLodConfig->advanced.outsideWeight, 1); + readFloats(mStream, &mLodConfig->advanced.outsideWalkAngle, 1); + } + + void LodConfigSerializer::readLodProfile() + { + uint32 size = 0; + readInts(mStream, &size, 1); + mLodConfig->advanced.profile.clear(); + while(size--){ + ProfiledEdge pv; + readObject(mStream, pv.src); + readObject(mStream, pv.dst); + readFloats(mStream, &pv.cost, 1); + mLodConfig->advanced.profile.push_back(pv); + } + } + + void LodConfigSerializer::exportLodConfig(Ogre::LodConfig& config, const Ogre::String& filename, Endian endianMode /*= ENDIAN_NATIVE*/ ) + { + std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); + f->open(filename.c_str(), std::ios::binary | std::ios::out); + Ogre::DataStreamPtr stream(OGRE_NEW Ogre::FileStreamDataStream(f)); + + exportLodConfig(config, stream, endianMode); + + stream->close(); + } + + void LodConfigSerializer::exportLodConfig(Ogre::LodConfig& config, Ogre::DataStreamPtr stream, Endian endianMode /*= ENDIAN_NATIVE*/ ) + { + Ogre::LogManager::getSingleton().logMessage("MeshSerializer writing mesh data to stream " + stream->getName() + "..."); + + // Decide on endian mode + determineEndianness(endianMode); + mLodConfig = &config; + mStream = stream; + if (!stream->isWriteable()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Unable to use stream " + stream->getName() + " for writing", + "LodConfigSerializer::export"); + } + + writeFileHeader(); + LogManager::getSingleton().logMessage("File header written."); + + + LogManager::getSingleton().logMessage("Writing Lod Config..."); + pushInnerChunk(mStream); + writeLodConfig(); + popInnerChunk(mStream); + LogManager::getSingleton().logMessage("LodConfigSerializer export successful."); + } + + void LodConfigSerializer::writeLodConfig() + { + writeChunkHeader(LCCID_LOD_CONFIG, calcLodConfigSize()); + pushInnerChunk(mStream); + writeLodBasicInfo(); + writeLodLevels(); + writeLodAdvancedInfo(); + writeLodProfile(); + popInnerChunk(mStream); + } + + size_t LodConfigSerializer::calcLodConfigSize() + { + size_t size = calcChunkHeaderSize(); + + size += calcLodBasicInfoSize(); + + size += calcLodLevelsSize(); + + size += calcLodAdvancedInfoSize(); + + size += calcLodProfileSize(); + + return size; + } + + void LodConfigSerializer::writeLodBasicInfo() + { + writeChunkHeader(LCCID_BASIC_INFO, calcLodBasicInfoSize()); + writeString(mLodConfig->mesh->getGroup()); + writeString(mLodConfig->mesh->getName()); + writeString(mLodConfig->strategy->getName()); + } + + size_t LodConfigSerializer::calcLodBasicInfoSize() + { + size_t size = calcChunkHeaderSize(); + + size += calcStringSize(mLodConfig->mesh->getGroup()); + size += calcStringSize(mLodConfig->mesh->getName()); + size += calcStringSize(mLodConfig->strategy->getName()); + + return size; + } + + void LodConfigSerializer::writeLodLevels() + { + writeChunkHeader(LCCID_LOD_LEVELS, calcLodLevelsSize()); + uint32 size = static_cast(mLodConfig->levels.size()); + writeInts(&size, 1); + + LodConfig::LodLevelList::iterator it = mLodConfig->levels.begin(); + LodConfig::LodLevelList::iterator itEnd = mLodConfig->levels.end(); + for(;it != itEnd; it++){ + writeFloats(&it->distance, 1); + writeInts((Ogre::uint32*)&it->reductionMethod, 1); + writeFloats(&it->reductionValue, 1); + writeString(it->manualMeshName); + } + } + + size_t LodConfigSerializer::calcLodLevelsSize() + { + //lodLevel.distance + size_t levelSize = sizeof(float); + + //lodLevel.reductionMethod; + levelSize += sizeof(Ogre::uint32); + + //lodLevel.reductionValue; + levelSize += sizeof(float); + + size_t size = calcChunkHeaderSize(); + + // mLodConfig->levels.size() + size += sizeof(Ogre::uint32); + + size += levelSize * mLodConfig->levels.size(); + + for(size_t i = 0; i < mLodConfig->levels.size(); i++) { + size += calcStringSize(mLodConfig->levels[i].manualMeshName); + } + + return size; + } + + void LodConfigSerializer::writeLodAdvancedInfo() + { + writeChunkHeader(LCCID_ADVANCED_INFO, calcLodAdvancedInfoSize()); + writeBools(&mLodConfig->advanced.useCompression, 1); + writeBools(&mLodConfig->advanced.useVertexNormals, 1); + writeBools(&mLodConfig->advanced.useBackgroundQueue, 1); + writeFloats(&mLodConfig->advanced.outsideWeight, 1); + writeFloats(&mLodConfig->advanced.outsideWalkAngle, 1); + } + + size_t LodConfigSerializer::calcLodAdvancedInfoSize() + { + size_t size = calcChunkHeaderSize(); + + // mLodConfig->advanced.useCompression + size += sizeof(bool); + // mLodConfig->advanced.useVertexNormals + size += sizeof(bool); + // mLodConfig->advanced.useBackgroundQueue + size += sizeof(bool); + // mLodConfig->advanced.outsideWeight + size += sizeof(float); + // mLodConfig->advanced.outsideWalkAngle + size += sizeof(float); + + return size; + } + + void LodConfigSerializer::writeLodProfile() + { + if(mLodConfig->advanced.profile.empty()){ + return; + } + writeChunkHeader(LCCID_PROFILE, calcLodProfileSize()); + uint32 size = static_cast(mLodConfig->advanced.profile.size()); + writeInts(&size, 1); + LodProfile::iterator it = mLodConfig->advanced.profile.begin(); + LodProfile::iterator itEnd = mLodConfig->advanced.profile.end(); + for(;it != itEnd; it++){ + writeObject(it->src); + writeObject(it->dst); + writeFloats(&it->cost, 1); + } + } + + size_t LodConfigSerializer::calcLodProfileSize() + { + if(mLodConfig->advanced.profile.empty()){ + return 0; + } + // Vector3, LodProfile::ProfiledVertex::src + size_t profiledVertexSize = sizeof(float) * 3; + + // Vector3, LodProfile::ProfiledVertex::dst + profiledVertexSize += sizeof(float) * 3; + + // LodProfile::ProfiledVertex::cost + profiledVertexSize += sizeof(float); + + + size_t size = calcChunkHeaderSize(); + + // mLodConfig->advanced.profile->data.size() + size += sizeof(uint32); + + size += profiledVertexSize * mLodConfig->advanced.profile.size(); + + return size; + } } \ No newline at end of file diff --git a/Components/MeshLodGenerator/src/OgreLodData.cpp b/Components/MeshLodGenerator/src/OgreLodData.cpp index 3de66fe940e..51cdce5f516 100644 --- a/Components/MeshLodGenerator/src/OgreLodData.cpp +++ b/Components/MeshLodGenerator/src/OgreLodData.cpp @@ -1,136 +1,136 @@ -/* - * ----------------------------------------------------------------------------- - * This source file is part of OGRE - * (Object-oriented Graphics Rendering Engine) - * For the latest info, see http://www.ogre3d.org/ - * - * Copyright (c) 2000-2014 Torus Knot Software Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ----------------------------------------------------------------------------- - */ -#include "OgreLodData.h" - -namespace Ogre -{ -// Use float limits instead of Real limits, because LodConfigSerializer may convert them to float. -const Real LodData::NEVER_COLLAPSE_COST = std::numeric_limits::max(); -const Real LodData::UNINITIALIZED_COLLAPSE_COST = std::numeric_limits::infinity(); - -void LodData::Vertex::addEdge( const LodData::Edge& edge ) -{ - OgreAssert(edge.dst != this, ""); - VEdges::iterator it; - it = edges.add(edge); - if (it == edges.end()) { - edges.back().refCount = 1; - } else { - it->refCount++; - } -} - -void LodData::Vertex::removeEdge( const LodData::Edge& edge ) -{ - VEdges::iterator it = edges.findExists(edge); - if (it->refCount == 1) { - edges.remove(it); - } else { - it->refCount--; - } -} - -bool LodData::VertexEqual::operator() (const LodData::Vertex* lhs, const LodData::Vertex* rhs) const -{ - return lhs->position == rhs->position; -} - -size_t LodData::VertexHash::operator() (const LodData::Vertex* v) const -{ - // Stretch the values to an integer grid. - Real stretch = (Real)0x7fffffff / mGen->mMeshBoundingSphereRadius; - int hash = (int)(v->position.x * stretch); - hash ^= (int)(v->position.y * stretch) * 0x100; - hash ^= (int)(v->position.z * stretch) * 0x10000; - return (size_t)hash; -} - -void LodData::Triangle::computeNormal() -{ - // Cross-product 2 edges - Vector3 e1 = vertex[1]->position - vertex[0]->position; - Vector3 e2 = vertex[2]->position - vertex[1]->position; - - normal = e1.crossProduct(e2); - normal.normalise(); -} - -bool LodData::Triangle::hasVertex(const LodData::Vertex* v) const -{ - return (v == vertex[0] || v == vertex[1] || v == vertex[2]); -} - -unsigned int LodData::Triangle::getVertexID(const LodData::Vertex* v) const -{ - for (int i = 0; i < 3; i++) { - if (vertex[i] == v) { - return vertexID[i]; - } - } - OgreAssert(0, ""); - return 0; -} -bool LodData::Triangle::isMalformed() -{ - return vertex[0] == vertex[1] || vertex[0] == vertex[2] || vertex[1] == vertex[2]; -} - -LodData::Edge::Edge(LodData::Vertex* destination) : - dst(destination) -#if OGRE_DEBUG_MODE - , collapseCost(UNINITIALIZED_COLLAPSE_COST) -#endif - , refCount(0) -{ - -} - -LodData::Edge::Edge(const LodData::Edge& b) -{ - *this = b; -} - -bool LodData::Edge::operator< (const LodData::Edge& other) const -{ - return (size_t) dst < (size_t) other.dst; // Comparing pointers for uniqueness. -} - -LodData::Edge& LodData::Edge::operator= (const LodData::Edge& b) -{ - dst = b.dst; - collapseCost = b.collapseCost; - refCount = b.refCount; - return *this; -} - -bool LodData::Edge::operator== (const LodData::Edge& other) const -{ - return dst == other.dst; -} - +/* + * ----------------------------------------------------------------------------- + * This source file is part of OGRE + * (Object-oriented Graphics Rendering Engine) + * For the latest info, see http://www.ogre3d.org/ + * + * Copyright (c) 2000-2014 Torus Knot Software Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ----------------------------------------------------------------------------- + */ +#include "OgreLodData.h" + +namespace Ogre +{ +// Use float limits instead of Real limits, because LodConfigSerializer may convert them to float. +const Real LodData::NEVER_COLLAPSE_COST = std::numeric_limits::max(); +const Real LodData::UNINITIALIZED_COLLAPSE_COST = std::numeric_limits::infinity(); + +void LodData::Vertex::addEdge( const LodData::Edge& edge ) +{ + OgreAssert(edge.dst != this, ""); + VEdges::iterator it; + it = edges.add(edge); + if (it == edges.end()) { + edges.back().refCount = 1; + } else { + it->refCount++; + } +} + +void LodData::Vertex::removeEdge( const LodData::Edge& edge ) +{ + VEdges::iterator it = edges.findExists(edge); + if (it->refCount == 1) { + edges.remove(it); + } else { + it->refCount--; + } +} + +bool LodData::VertexEqual::operator() (const LodData::Vertex* lhs, const LodData::Vertex* rhs) const +{ + return lhs->position == rhs->position; +} + +size_t LodData::VertexHash::operator() (const LodData::Vertex* v) const +{ + // Stretch the values to an integer grid. + Real stretch = (Real)0x7fffffff / mGen->mMeshBoundingSphereRadius; + int hash = (int)(v->position.x * stretch); + hash ^= (int)(v->position.y * stretch) * 0x100; + hash ^= (int)(v->position.z * stretch) * 0x10000; + return (size_t)hash; +} + +void LodData::Triangle::computeNormal() +{ + // Cross-product 2 edges + Vector3 e1 = vertex[1]->position - vertex[0]->position; + Vector3 e2 = vertex[2]->position - vertex[1]->position; + + normal = e1.crossProduct(e2); + normal.normalise(); +} + +bool LodData::Triangle::hasVertex(const LodData::Vertex* v) const +{ + return (v == vertex[0] || v == vertex[1] || v == vertex[2]); +} + +unsigned int LodData::Triangle::getVertexID(const LodData::Vertex* v) const +{ + for (int i = 0; i < 3; i++) { + if (vertex[i] == v) { + return vertexID[i]; + } + } + OgreAssert(0, ""); + return 0; +} +bool LodData::Triangle::isMalformed() +{ + return vertex[0] == vertex[1] || vertex[0] == vertex[2] || vertex[1] == vertex[2]; +} + +LodData::Edge::Edge(LodData::Vertex* destination) : + dst(destination) +#if OGRE_DEBUG_MODE + , collapseCost(UNINITIALIZED_COLLAPSE_COST) +#endif + , refCount(0) +{ + +} + +LodData::Edge::Edge(const LodData::Edge& b) +{ + *this = b; +} + +bool LodData::Edge::operator< (const LodData::Edge& other) const +{ + return (size_t) dst < (size_t) other.dst; // Comparing pointers for uniqueness. +} + +LodData::Edge& LodData::Edge::operator= (const LodData::Edge& b) +{ + dst = b.dst; + collapseCost = b.collapseCost; + refCount = b.refCount; + return *this; +} + +bool LodData::Edge::operator== (const LodData::Edge& other) const +{ + return dst == other.dst; +} + } \ No newline at end of file diff --git a/Components/MeshLodGenerator/src/OgreLodInputProvider.cpp b/Components/MeshLodGenerator/src/OgreLodInputProvider.cpp index 3076f772753..bbbee651515 100644 --- a/Components/MeshLodGenerator/src/OgreLodInputProvider.cpp +++ b/Components/MeshLodGenerator/src/OgreLodInputProvider.cpp @@ -33,73 +33,73 @@ namespace Ogre { - - void LodInputProvider::printTriangle(LodData::Triangle* triangle, stringstream& str) + + void LodInputProvider::printTriangle(LodData::Triangle* triangle, stringstream& str) { - for (int i = 0; i < 3; i++) { - str << (i + 1) << ". vertex position: (" - << triangle->vertex[i]->position.x << ", " - << triangle->vertex[i]->position.y << ", " - << triangle->vertex[i]->position.z << ") " - << "vertex ID: " << triangle->vertexID[i] << std::endl; - } + for (int i = 0; i < 3; i++) { + str << (i + 1) << ". vertex position: (" + << triangle->vertex[i]->position.x << ", " + << triangle->vertex[i]->position.y << ", " + << triangle->vertex[i]->position.z << ") " + << "vertex ID: " << triangle->vertexID[i] << std::endl; + } } bool LodInputProvider::isDuplicateTriangle(LodData::Triangle* triangle, LodData::Triangle* triangle2) { - for (int i = 0; i < 3; i++) { - if (triangle->vertex[i] != triangle2->vertex[0] || - triangle->vertex[i] != triangle2->vertex[1] || - triangle->vertex[i] != triangle2->vertex[2]) { - return false; - } - } - return true; + for (int i = 0; i < 3; i++) { + if (triangle->vertex[i] != triangle2->vertex[0] || + triangle->vertex[i] != triangle2->vertex[1] || + triangle->vertex[i] != triangle2->vertex[2]) { + return false; + } + } + return true; } LodData::Triangle* LodInputProvider::isDuplicateTriangle(LodData::Triangle* triangle) { - // duplicate triangle detection (where all vertices has the same position) - LodData::VTriangles::iterator itEnd = triangle->vertex[0]->triangles.end(); - LodData::VTriangles::iterator it = triangle->vertex[0]->triangles.begin(); - for (; it != itEnd; ++it) { - LodData::Triangle* t = *it; - if (isDuplicateTriangle(triangle, t)) { - return *it; - } - } - return NULL; + // duplicate triangle detection (where all vertices has the same position) + LodData::VTriangles::iterator itEnd = triangle->vertex[0]->triangles.end(); + LodData::VTriangles::iterator it = triangle->vertex[0]->triangles.begin(); + for (; it != itEnd; ++it) { + LodData::Triangle* t = *it; + if (isDuplicateTriangle(triangle, t)) { + return *it; + } + } + return NULL; } void LodInputProvider::addTriangleToEdges(LodData* data, LodData::Triangle* triangle) { - if(MESHLOD_QUALITY >= 3) { - LodData::Triangle* duplicate = isDuplicateTriangle(triangle); - if (duplicate != NULL) { + if(MESHLOD_QUALITY >= 3) { + LodData::Triangle* duplicate = isDuplicateTriangle(triangle); + if (duplicate != NULL) { #if OGRE_DEBUG_MODE - stringstream str; - str << "In " << data->mMeshName << " duplicate triangle found." << std::endl; - str << "Triangle " << LodData::getVectorIDFromPointer(data->mTriangleList, triangle) << " positions:" << std::endl; - printTriangle(triangle, str); - str << "Triangle " << LodData::getVectorIDFromPointer(data->mTriangleList, duplicate) << " positions:" << std::endl; - printTriangle(duplicate, str); - str << "Triangle " << LodData::getVectorIDFromPointer(data->mTriangleList, triangle) << " will be excluded from Lod level calculations."; - LogManager::getSingleton().stream() << str.str(); + stringstream str; + str << "In " << data->mMeshName << " duplicate triangle found." << std::endl; + str << "Triangle " << LodData::getVectorIDFromPointer(data->mTriangleList, triangle) << " positions:" << std::endl; + printTriangle(triangle, str); + str << "Triangle " << LodData::getVectorIDFromPointer(data->mTriangleList, duplicate) << " positions:" << std::endl; + printTriangle(duplicate, str); + str << "Triangle " << LodData::getVectorIDFromPointer(data->mTriangleList, triangle) << " will be excluded from Lod level calculations."; + LogManager::getSingleton().stream() << str.str(); #endif - triangle->isRemoved = true; - data->mIndexBufferInfoList[triangle->submeshID].indexCount -= 3; - return; - } - } - for (int i = 0; i < 3; i++) { - triangle->vertex[i]->triangles.addNotExists(triangle); - } - for (int i = 0; i < 3; i++) { - for (int n = 0; n < 3; n++) { - if (i != n) { - triangle->vertex[i]->addEdge(LodData::Edge(triangle->vertex[n])); - } - } - } + triangle->isRemoved = true; + data->mIndexBufferInfoList[triangle->submeshID].indexCount -= 3; + return; + } + } + for (int i = 0; i < 3; i++) { + triangle->vertex[i]->triangles.addNotExists(triangle); + } + for (int i = 0; i < 3; i++) { + for (int n = 0; n < 3; n++) { + if (i != n) { + triangle->vertex[i]->addEdge(LodData::Edge(triangle->vertex[n])); + } + } + } } } \ No newline at end of file diff --git a/Components/MeshLodGenerator/src/OgreLodInputProviderBuffer.cpp b/Components/MeshLodGenerator/src/OgreLodInputProviderBuffer.cpp index 81c7b8fbe27..b155b4d5710 100644 --- a/Components/MeshLodGenerator/src/OgreLodInputProviderBuffer.cpp +++ b/Components/MeshLodGenerator/src/OgreLodInputProviderBuffer.cpp @@ -33,141 +33,141 @@ namespace Ogre { - LodInputProviderBuffer::LodInputProviderBuffer( MeshPtr mesh ) - { - mBuffer.fillBuffer(mesh); - } - - void LodInputProviderBuffer::initData( LodData* data ) - { - tuneContainerSize(data); - initialize(data); - } - - void LodInputProviderBuffer::tuneContainerSize(LodData* data) - { - // Get Vertex count for container tuning. - bool sharedVerticesAdded = false; - size_t vertexCount = 0; - size_t vertexLookupSize = 0; - size_t sharedVertexLookupSize = 0; - unsigned short submeshCount = mBuffer.submesh.size(); - for (unsigned short i = 0; i < submeshCount; i++) { - const LodInputBuffer::Submesh& submesh = mBuffer.submesh[i]; - if (!submesh.useSharedVertexBuffer) { - size_t count = submesh.vertexBuffer.vertexCount; - vertexLookupSize = std::max(vertexLookupSize, count); - vertexCount += count; - } else if (!sharedVerticesAdded) { - sharedVerticesAdded = true; - sharedVertexLookupSize = mBuffer.sharedVertexBuffer.vertexCount; - vertexCount += sharedVertexLookupSize; - } - } - - // Tune containers: - data->mUniqueVertexSet.rehash(4 * vertexCount); // less then 0.25 item/bucket for low collision rate - - // There are less triangles then 2 * vertexCount. Except if there are bunch of triangles, - // where all vertices have the same position, but that would not make much sense. - data->mTriangleList.reserve(2 * vertexCount); - - data->mVertexList.reserve(vertexCount); - mSharedVertexLookup.reserve(sharedVertexLookupSize); - mVertexLookup.reserve(vertexLookupSize); - data->mIndexBufferInfoList.resize(submeshCount); - } - - void LodInputProviderBuffer::initialize( LodData* data ) - { + LodInputProviderBuffer::LodInputProviderBuffer( MeshPtr mesh ) + { + mBuffer.fillBuffer(mesh); + } + + void LodInputProviderBuffer::initData( LodData* data ) + { + tuneContainerSize(data); + initialize(data); + } + + void LodInputProviderBuffer::tuneContainerSize(LodData* data) + { + // Get Vertex count for container tuning. + bool sharedVerticesAdded = false; + size_t vertexCount = 0; + size_t vertexLookupSize = 0; + size_t sharedVertexLookupSize = 0; + unsigned short submeshCount = mBuffer.submesh.size(); + for (unsigned short i = 0; i < submeshCount; i++) { + const LodInputBuffer::Submesh& submesh = mBuffer.submesh[i]; + if (!submesh.useSharedVertexBuffer) { + size_t count = submesh.vertexBuffer.vertexCount; + vertexLookupSize = std::max(vertexLookupSize, count); + vertexCount += count; + } else if (!sharedVerticesAdded) { + sharedVerticesAdded = true; + sharedVertexLookupSize = mBuffer.sharedVertexBuffer.vertexCount; + vertexCount += sharedVertexLookupSize; + } + } + + // Tune containers: + data->mUniqueVertexSet.rehash(4 * vertexCount); // less then 0.25 item/bucket for low collision rate + + // There are less triangles then 2 * vertexCount. Except if there are bunch of triangles, + // where all vertices have the same position, but that would not make much sense. + data->mTriangleList.reserve(2 * vertexCount); + + data->mVertexList.reserve(vertexCount); + mSharedVertexLookup.reserve(sharedVertexLookupSize); + mVertexLookup.reserve(vertexLookupSize); + data->mIndexBufferInfoList.resize(submeshCount); + } + + void LodInputProviderBuffer::initialize( LodData* data ) + { #if OGRE_DEBUG_MODE - data->mMeshName = mBuffer.meshName; + data->mMeshName = mBuffer.meshName; #endif - data->mMeshBoundingSphereRadius = mBuffer.boundingSphereRadius; - unsigned short submeshCount = mBuffer.submesh.size(); - for (unsigned short i = 0; i < submeshCount; ++i) { - LodInputBuffer::Submesh& submesh = mBuffer.submesh[i]; - LodVertexBuffer& vertexBuffer = - (submesh.useSharedVertexBuffer ? mBuffer.sharedVertexBuffer : submesh.vertexBuffer); - addVertexData(data, vertexBuffer, submesh.useSharedVertexBuffer); - addIndexData(data, submesh.indexBuffer, submesh.useSharedVertexBuffer, i); - } - - // These were only needed for addIndexData() and addVertexData(). - mSharedVertexLookup.clear(); - mVertexLookup.clear(); - } - void LodInputProviderBuffer::addVertexData(LodData* data, LodVertexBuffer& vertexBuffer, bool useSharedVertexLookup) - { - if (useSharedVertexLookup && !mSharedVertexLookup.empty()) { - return; // We already loaded the shared vertex buffer. - } - - VertexLookupList& lookup = useSharedVertexLookup ? mSharedVertexLookup : mVertexLookup; - lookup.clear(); - - Vector3* pNormalOut = vertexBuffer.vertexNormalBuffer.get(); - data->mUseVertexNormals = data->mUseVertexNormals && (pNormalOut != NULL); - - // Loop through all vertices and insert them to the Unordered Map. - Vector3* pOut = vertexBuffer.vertexBuffer.get(); - Vector3* pEnd = pOut + vertexBuffer.vertexCount; - for (; pOut < pEnd; pOut++) { - data->mVertexList.push_back(LodData::Vertex()); - LodData::Vertex* v = &data->mVertexList.back(); - v->position = *pOut; - std::pair ret; - ret = data->mUniqueVertexSet.insert(v); - if (!ret.second) { - // Vertex position already exists. - data->mVertexList.pop_back(); - v = *ret.first; // Point to the existing vertex. - v->seam = true; - if(data->mUseVertexNormals){ - if(v->normal.x != (*pNormalOut).x){ - v->normal += *pNormalOut; - if(v->normal.isZeroLength()){ - v->normal = Vector3(1.0, 0.0, 0.0); - } - v->normal.normalise(); - } - pNormalOut++; - } - } else { + data->mMeshBoundingSphereRadius = mBuffer.boundingSphereRadius; + unsigned short submeshCount = mBuffer.submesh.size(); + for (unsigned short i = 0; i < submeshCount; ++i) { + LodInputBuffer::Submesh& submesh = mBuffer.submesh[i]; + LodVertexBuffer& vertexBuffer = + (submesh.useSharedVertexBuffer ? mBuffer.sharedVertexBuffer : submesh.vertexBuffer); + addVertexData(data, vertexBuffer, submesh.useSharedVertexBuffer); + addIndexData(data, submesh.indexBuffer, submesh.useSharedVertexBuffer, i); + } + + // These were only needed for addIndexData() and addVertexData(). + mSharedVertexLookup.clear(); + mVertexLookup.clear(); + } + void LodInputProviderBuffer::addVertexData(LodData* data, LodVertexBuffer& vertexBuffer, bool useSharedVertexLookup) + { + if (useSharedVertexLookup && !mSharedVertexLookup.empty()) { + return; // We already loaded the shared vertex buffer. + } + + VertexLookupList& lookup = useSharedVertexLookup ? mSharedVertexLookup : mVertexLookup; + lookup.clear(); + + Vector3* pNormalOut = vertexBuffer.vertexNormalBuffer.get(); + data->mUseVertexNormals = data->mUseVertexNormals && (pNormalOut != NULL); + + // Loop through all vertices and insert them to the Unordered Map. + Vector3* pOut = vertexBuffer.vertexBuffer.get(); + Vector3* pEnd = pOut + vertexBuffer.vertexCount; + for (; pOut < pEnd; pOut++) { + data->mVertexList.push_back(LodData::Vertex()); + LodData::Vertex* v = &data->mVertexList.back(); + v->position = *pOut; + std::pair ret; + ret = data->mUniqueVertexSet.insert(v); + if (!ret.second) { + // Vertex position already exists. + data->mVertexList.pop_back(); + v = *ret.first; // Point to the existing vertex. + v->seam = true; + if(data->mUseVertexNormals){ + if(v->normal.x != (*pNormalOut).x){ + v->normal += *pNormalOut; + if(v->normal.isZeroLength()){ + v->normal = Vector3(1.0, 0.0, 0.0); + } + v->normal.normalise(); + } + pNormalOut++; + } + } else { #if OGRE_DEBUG_MODE - v->costHeapPosition = data->mCollapseCostHeap.end(); + v->costHeapPosition = data->mCollapseCostHeap.end(); #endif - v->seam = false; - if(data->mUseVertexNormals){ - v->normal = *pNormalOut; - v->normal.normalise(); - pNormalOut++; - } - } - lookup.push_back(v); - } - } - - void LodInputProviderBuffer::addIndexData(LodData* data, LodIndexBuffer& indexBuffer, bool useSharedVertexLookup, unsigned short submeshID) - { - size_t isize = indexBuffer.indexSize; - data->mIndexBufferInfoList[submeshID].indexSize = isize; - data->mIndexBufferInfoList[submeshID].indexCount = indexBuffer.indexCount; - VertexLookupList& lookup = useSharedVertexLookup ? mSharedVertexLookup : mVertexLookup; - - // Lock the buffer for reading. - unsigned char* iStart = indexBuffer.indexBuffer.get(); - if(!iStart) { - return; - } - unsigned char* iEnd = iStart + indexBuffer.indexCount * isize; - if (isize == sizeof(unsigned short)) { - addIndexDataImpl(data, (unsigned short*) iStart, (unsigned short*) iEnd, lookup, submeshID); - } else { - // Unsupported index size. - OgreAssert(isize == sizeof(unsigned int), ""); - addIndexDataImpl(data, (unsigned int*) iStart, (unsigned int*) iEnd, lookup, submeshID); - } - } + v->seam = false; + if(data->mUseVertexNormals){ + v->normal = *pNormalOut; + v->normal.normalise(); + pNormalOut++; + } + } + lookup.push_back(v); + } + } + + void LodInputProviderBuffer::addIndexData(LodData* data, LodIndexBuffer& indexBuffer, bool useSharedVertexLookup, unsigned short submeshID) + { + size_t isize = indexBuffer.indexSize; + data->mIndexBufferInfoList[submeshID].indexSize = isize; + data->mIndexBufferInfoList[submeshID].indexCount = indexBuffer.indexCount; + VertexLookupList& lookup = useSharedVertexLookup ? mSharedVertexLookup : mVertexLookup; + + // Lock the buffer for reading. + unsigned char* iStart = indexBuffer.indexBuffer.get(); + if(!iStart) { + return; + } + unsigned char* iEnd = iStart + indexBuffer.indexCount * isize; + if (isize == sizeof(unsigned short)) { + addIndexDataImpl(data, (unsigned short*) iStart, (unsigned short*) iEnd, lookup, submeshID); + } else { + // Unsupported index size. + OgreAssert(isize == sizeof(unsigned int), ""); + addIndexDataImpl(data, (unsigned int*) iStart, (unsigned int*) iEnd, lookup, submeshID); + } + } } diff --git a/Components/MeshLodGenerator/src/OgreLodInputProviderMesh.cpp b/Components/MeshLodGenerator/src/OgreLodInputProviderMesh.cpp index 8548370e374..bcb0a833ddf 100644 --- a/Components/MeshLodGenerator/src/OgreLodInputProviderMesh.cpp +++ b/Components/MeshLodGenerator/src/OgreLodInputProviderMesh.cpp @@ -33,186 +33,186 @@ namespace Ogre { - LodInputProviderMesh::LodInputProviderMesh( MeshPtr mesh ) : mMesh(mesh) - { - - } - - void LodInputProviderMesh::initData( LodData* data ) - { - tuneContainerSize(data); - initialize(data); - } - void LodInputProviderMesh::tuneContainerSize(LodData* data) - { - // Get Vertex count for container tuning. - bool sharedVerticesAdded = false; - size_t vertexCount = 0; - size_t vertexLookupSize = 0; - size_t sharedVertexLookupSize = 0; - unsigned short submeshCount = mMesh->getNumSubMeshes(); - for (unsigned short i = 0; i < submeshCount; i++) { - const SubMesh* submesh = mMesh->getSubMesh(i); - if (!submesh->useSharedVertices) { - size_t count = submesh->vertexData->vertexCount; - vertexLookupSize = std::max(vertexLookupSize, count); - vertexCount += count; - } else if (!sharedVerticesAdded) { - sharedVerticesAdded = true; - sharedVertexLookupSize = mMesh->sharedVertexData->vertexCount; - vertexCount += sharedVertexLookupSize; - } - } - - // Tune containers: - data->mUniqueVertexSet.rehash(4 * vertexCount); // less then 0.25 item/bucket for low collision rate - - // There are less triangles then 2 * vertexCount. Except if there are bunch of triangles, - // where all vertices have the same position, but that would not make much sense. - data->mTriangleList.reserve(2 * vertexCount); - - data->mVertexList.reserve(vertexCount); - mSharedVertexLookup.reserve(sharedVertexLookupSize); - mVertexLookup.reserve(vertexLookupSize); - data->mIndexBufferInfoList.resize(submeshCount); - } - - void LodInputProviderMesh::initialize( LodData* data ) - { + LodInputProviderMesh::LodInputProviderMesh( MeshPtr mesh ) : mMesh(mesh) + { + + } + + void LodInputProviderMesh::initData( LodData* data ) + { + tuneContainerSize(data); + initialize(data); + } + void LodInputProviderMesh::tuneContainerSize(LodData* data) + { + // Get Vertex count for container tuning. + bool sharedVerticesAdded = false; + size_t vertexCount = 0; + size_t vertexLookupSize = 0; + size_t sharedVertexLookupSize = 0; + unsigned short submeshCount = mMesh->getNumSubMeshes(); + for (unsigned short i = 0; i < submeshCount; i++) { + const SubMesh* submesh = mMesh->getSubMesh(i); + if (!submesh->useSharedVertices) { + size_t count = submesh->vertexData->vertexCount; + vertexLookupSize = std::max(vertexLookupSize, count); + vertexCount += count; + } else if (!sharedVerticesAdded) { + sharedVerticesAdded = true; + sharedVertexLookupSize = mMesh->sharedVertexData->vertexCount; + vertexCount += sharedVertexLookupSize; + } + } + + // Tune containers: + data->mUniqueVertexSet.rehash(4 * vertexCount); // less then 0.25 item/bucket for low collision rate + + // There are less triangles then 2 * vertexCount. Except if there are bunch of triangles, + // where all vertices have the same position, but that would not make much sense. + data->mTriangleList.reserve(2 * vertexCount); + + data->mVertexList.reserve(vertexCount); + mSharedVertexLookup.reserve(sharedVertexLookupSize); + mVertexLookup.reserve(vertexLookupSize); + data->mIndexBufferInfoList.resize(submeshCount); + } + + void LodInputProviderMesh::initialize( LodData* data ) + { #if OGRE_DEBUG_MODE - data->mMeshName = mMesh->getName(); + data->mMeshName = mMesh->getName(); #endif - data->mMeshBoundingSphereRadius = mMesh->getBoundingSphereRadius(); - unsigned short submeshCount = mMesh->getNumSubMeshes(); - for (unsigned short i = 0; i < submeshCount; ++i) { - const SubMesh* submesh = mMesh->getSubMesh(i); - VertexData* vertexData = (submesh->useSharedVertices ? mMesh->sharedVertexData : submesh->vertexData); - addVertexData(data, vertexData, submesh->useSharedVertices); - if(submesh->indexData->indexCount > 0) - addIndexData(data, submesh->indexData, submesh->useSharedVertices, i); - } - - // These were only needed for addIndexData() and addVertexData(). - mSharedVertexLookup.clear(); - mVertexLookup.clear(); - } - void LodInputProviderMesh::addVertexData(LodData* data, VertexData* vertexData, bool useSharedVertexLookup) - { - if ((useSharedVertexLookup && !mSharedVertexLookup.empty())) { // We already loaded the shared vertex buffer. - return; - } - OgreAssert(vertexData->vertexCount != 0, ""); - - // Locate position element and the buffer to go with it. - const VertexElement* elemPos = vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - - // Only float supported. - OgreAssert(elemPos->getSize() == 12, ""); - - HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(elemPos->getSource()); - - // Lock the buffer for reading. - unsigned char* vStart = static_cast(vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); - unsigned char* vertex = vStart; - size_t vSize = vbuf->getVertexSize(); - unsigned char* vEnd = vertex + vertexData->vertexCount * vSize; - - VertexLookupList& lookup = useSharedVertexLookup ? mSharedVertexLookup : mVertexLookup; - lookup.clear(); - - HardwareVertexBufferSharedPtr vNormalBuf; - unsigned char* vNormal; - size_t vNormSize; - const VertexElement* elemNormal = vertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL); - - data->mUseVertexNormals &= (elemNormal != NULL); - if(data->mUseVertexNormals){ - if(elemNormal->getSource() == elemPos->getSource()){ - // Don't open the same buffer twice. Just copy the pointer. - vNormalBuf = vbuf; - vNormal = vStart; - } else { - vNormalBuf = vertexData->vertexBufferBinding->getBuffer(elemNormal->getSource()); - vNormal = static_cast(vNormalBuf->lock(HardwareBuffer::HBL_READ_ONLY)); - } - vNormSize = vNormalBuf->getVertexSize(); - } - - - // Loop through all vertices and insert them to the Unordered Map. - for (; vertex < vEnd; vertex += vSize) { - float* pFloat; - elemPos->baseVertexPointerToElement(vertex, &pFloat); - data->mVertexList.push_back(LodData::Vertex()); - LodData::Vertex* v = &data->mVertexList.back(); - v->position.x = pFloat[0]; - v->position.y = pFloat[1]; - v->position.z = pFloat[2]; - std::pair ret; - ret = data->mUniqueVertexSet.insert(v); - if (!ret.second) { - // Vertex position already exists. - data->mVertexList.pop_back(); - v = *ret.first; // Point to the existing vertex. - v->seam = true; - } else { + data->mMeshBoundingSphereRadius = mMesh->getBoundingSphereRadius(); + unsigned short submeshCount = mMesh->getNumSubMeshes(); + for (unsigned short i = 0; i < submeshCount; ++i) { + const SubMesh* submesh = mMesh->getSubMesh(i); + VertexData* vertexData = (submesh->useSharedVertices ? mMesh->sharedVertexData : submesh->vertexData); + addVertexData(data, vertexData, submesh->useSharedVertices); + if(submesh->indexData->indexCount > 0) + addIndexData(data, submesh->indexData, submesh->useSharedVertices, i); + } + + // These were only needed for addIndexData() and addVertexData(). + mSharedVertexLookup.clear(); + mVertexLookup.clear(); + } + void LodInputProviderMesh::addVertexData(LodData* data, VertexData* vertexData, bool useSharedVertexLookup) + { + if ((useSharedVertexLookup && !mSharedVertexLookup.empty())) { // We already loaded the shared vertex buffer. + return; + } + OgreAssert(vertexData->vertexCount != 0, ""); + + // Locate position element and the buffer to go with it. + const VertexElement* elemPos = vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + + // Only float supported. + OgreAssert(elemPos->getSize() == 12, ""); + + HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(elemPos->getSource()); + + // Lock the buffer for reading. + unsigned char* vStart = static_cast(vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + unsigned char* vertex = vStart; + size_t vSize = vbuf->getVertexSize(); + unsigned char* vEnd = vertex + vertexData->vertexCount * vSize; + + VertexLookupList& lookup = useSharedVertexLookup ? mSharedVertexLookup : mVertexLookup; + lookup.clear(); + + HardwareVertexBufferSharedPtr vNormalBuf; + unsigned char* vNormal; + size_t vNormSize; + const VertexElement* elemNormal = vertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL); + + data->mUseVertexNormals &= (elemNormal != NULL); + if(data->mUseVertexNormals){ + if(elemNormal->getSource() == elemPos->getSource()){ + // Don't open the same buffer twice. Just copy the pointer. + vNormalBuf = vbuf; + vNormal = vStart; + } else { + vNormalBuf = vertexData->vertexBufferBinding->getBuffer(elemNormal->getSource()); + vNormal = static_cast(vNormalBuf->lock(HardwareBuffer::HBL_READ_ONLY)); + } + vNormSize = vNormalBuf->getVertexSize(); + } + + + // Loop through all vertices and insert them to the Unordered Map. + for (; vertex < vEnd; vertex += vSize) { + float* pFloat; + elemPos->baseVertexPointerToElement(vertex, &pFloat); + data->mVertexList.push_back(LodData::Vertex()); + LodData::Vertex* v = &data->mVertexList.back(); + v->position.x = pFloat[0]; + v->position.y = pFloat[1]; + v->position.z = pFloat[2]; + std::pair ret; + ret = data->mUniqueVertexSet.insert(v); + if (!ret.second) { + // Vertex position already exists. + data->mVertexList.pop_back(); + v = *ret.first; // Point to the existing vertex. + v->seam = true; + } else { #if OGRE_DEBUG_MODE - // Needed for an assert, don't remove it. - v->costHeapPosition = data->mCollapseCostHeap.end(); + // Needed for an assert, don't remove it. + v->costHeapPosition = data->mCollapseCostHeap.end(); #endif - v->seam = false; - } - lookup.push_back(v); - - if(data->mUseVertexNormals){ - elemNormal->baseVertexPointerToElement(vNormal, &pFloat); - if (!ret.second) { - if(v->normal.x != pFloat[0]){ - v->normal.x += pFloat[0]; - v->normal.y += pFloat[1]; - v->normal.z += pFloat[2]; - if(v->normal.isZeroLength()){ - v->normal = Vector3(1.0, 0.0, 0.0); - } - v->normal.normalise(); - } - } else { - v->normal.x = pFloat[0]; - v->normal.y = pFloat[1]; - v->normal.z = pFloat[2]; - v->normal.normalise(); - } - vNormal += vNormSize; - } - } - vbuf->unlock(); - if(data->mUseVertexNormals && elemNormal->getSource() != elemPos->getSource()){ - vNormalBuf->unlock(); - } - } - void LodInputProviderMesh::addIndexData(LodData* data, IndexData* indexData, bool useSharedVertexLookup, unsigned short submeshID) - { - const HardwareIndexBufferSharedPtr& ibuf = indexData->indexBuffer; - size_t isize = ibuf->getIndexSize(); - data->mIndexBufferInfoList[submeshID].indexSize = isize; - data->mIndexBufferInfoList[submeshID].indexCount = indexData->indexCount; - if (indexData->indexCount == 0) { - // Locking a zero length buffer on Linux with nvidia cards fails. - return; - } - VertexLookupList& lookup = useSharedVertexLookup ? mSharedVertexLookup : mVertexLookup; - - // Lock the buffer for reading. - char* iStart = static_cast(ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - char* iEnd = iStart + ibuf->getSizeInBytes(); - if (isize == sizeof(unsigned short)) { - addIndexDataImpl(data, (unsigned short*) iStart, (unsigned short*) iEnd, lookup, submeshID); - } else { - // Unsupported index size. - OgreAssert(isize == sizeof(unsigned int), ""); - addIndexDataImpl(data, (unsigned int*) iStart, (unsigned int*) iEnd, lookup, submeshID); - } - ibuf->unlock(); - } + v->seam = false; + } + lookup.push_back(v); + + if(data->mUseVertexNormals){ + elemNormal->baseVertexPointerToElement(vNormal, &pFloat); + if (!ret.second) { + if(v->normal.x != pFloat[0]){ + v->normal.x += pFloat[0]; + v->normal.y += pFloat[1]; + v->normal.z += pFloat[2]; + if(v->normal.isZeroLength()){ + v->normal = Vector3(1.0, 0.0, 0.0); + } + v->normal.normalise(); + } + } else { + v->normal.x = pFloat[0]; + v->normal.y = pFloat[1]; + v->normal.z = pFloat[2]; + v->normal.normalise(); + } + vNormal += vNormSize; + } + } + vbuf->unlock(); + if(data->mUseVertexNormals && elemNormal->getSource() != elemPos->getSource()){ + vNormalBuf->unlock(); + } + } + void LodInputProviderMesh::addIndexData(LodData* data, IndexData* indexData, bool useSharedVertexLookup, unsigned short submeshID) + { + const HardwareIndexBufferSharedPtr& ibuf = indexData->indexBuffer; + size_t isize = ibuf->getIndexSize(); + data->mIndexBufferInfoList[submeshID].indexSize = isize; + data->mIndexBufferInfoList[submeshID].indexCount = indexData->indexCount; + if (indexData->indexCount == 0) { + // Locking a zero length buffer on Linux with nvidia cards fails. + return; + } + VertexLookupList& lookup = useSharedVertexLookup ? mSharedVertexLookup : mVertexLookup; + + // Lock the buffer for reading. + char* iStart = static_cast(ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + char* iEnd = iStart + ibuf->getSizeInBytes(); + if (isize == sizeof(unsigned short)) { + addIndexDataImpl(data, (unsigned short*) iStart, (unsigned short*) iEnd, lookup, submeshID); + } else { + // Unsupported index size. + OgreAssert(isize == sizeof(unsigned int), ""); + addIndexDataImpl(data, (unsigned int*) iStart, (unsigned int*) iEnd, lookup, submeshID); + } + ibuf->unlock(); + } } diff --git a/Components/MeshLodGenerator/src/OgreLodOutputProviderBuffer.cpp b/Components/MeshLodGenerator/src/OgreLodOutputProviderBuffer.cpp index e5bb2c50396..66630acab33 100644 --- a/Components/MeshLodGenerator/src/OgreLodOutputProviderBuffer.cpp +++ b/Components/MeshLodGenerator/src/OgreLodOutputProviderBuffer.cpp @@ -33,116 +33,116 @@ namespace Ogre { - LodOutputBuffer& LodOutputProviderBuffer::getBuffer() - { - return mBuffer; - } + LodOutputBuffer& LodOutputProviderBuffer::getBuffer() + { + return mBuffer; + } - void LodOutputProviderBuffer::prepare( LodData* data ) - { + void LodOutputProviderBuffer::prepare( LodData* data ) + { - mBuffer.submesh.resize(data->mIndexBufferInfoList.size()); - } + mBuffer.submesh.resize(data->mIndexBufferInfoList.size()); + } - void LodOutputProviderBuffer::bakeManualLodLevel( LodData* data, String& manualMeshName, int lodIndex ) - { - // placeholder dummy - unsigned short submeshCount = mBuffer.submesh.size(); - LodIndexBuffer buffer; - buffer.indexSize = 2; - buffer.indexCount = 0; - buffer.indexStart = 0; - buffer.indexBufferSize = 0; - if(lodIndex < 0) { - for (unsigned short i = 0; i < submeshCount; i++) { - mBuffer.submesh[i].genIndexBuffers.push_back(buffer); - } - } else { - for (unsigned short i = 0; i < submeshCount; i++) { - mBuffer.submesh[i].genIndexBuffers.insert(mBuffer.submesh[i].genIndexBuffers.begin() + lodIndex, buffer); - } - } - } + void LodOutputProviderBuffer::bakeManualLodLevel( LodData* data, String& manualMeshName, int lodIndex ) + { + // placeholder dummy + unsigned short submeshCount = mBuffer.submesh.size(); + LodIndexBuffer buffer; + buffer.indexSize = 2; + buffer.indexCount = 0; + buffer.indexStart = 0; + buffer.indexBufferSize = 0; + if(lodIndex < 0) { + for (unsigned short i = 0; i < submeshCount; i++) { + mBuffer.submesh[i].genIndexBuffers.push_back(buffer); + } + } else { + for (unsigned short i = 0; i < submeshCount; i++) { + mBuffer.submesh[i].genIndexBuffers.insert(mBuffer.submesh[i].genIndexBuffers.begin() + lodIndex, buffer); + } + } + } - void LodOutputProviderBuffer::bakeLodLevel(LodData* data, int lodIndex) - { - unsigned short submeshCount = mBuffer.submesh.size(); + void LodOutputProviderBuffer::bakeLodLevel(LodData* data, int lodIndex) + { + unsigned short submeshCount = mBuffer.submesh.size(); - // Create buffers. - for (unsigned short i = 0; i < submeshCount; i++) { - vector::type& lods = mBuffer.submesh[i].genIndexBuffers; - size_t indexCount = data->mIndexBufferInfoList[i].indexCount; - lods.reserve(lods.size() + 1); - LodIndexBuffer& curLod = *lods.insert(lods.begin() + lodIndex, LodIndexBuffer()); - if (indexCount == 0) { - curLod.indexCount = 3; - } else { - curLod.indexCount = indexCount; - } - curLod.indexStart = 0; - curLod.indexSize = data->mIndexBufferInfoList[i].indexSize; - curLod.indexBufferSize = 0; // It means same as index count - curLod.indexBuffer = Ogre::SharedPtr(new unsigned char[curLod.indexCount * curLod.indexSize]); - // buf is an union, so pint=pshort - data->mIndexBufferInfoList[i].buf.pshort = (unsigned short*) curLod.indexBuffer.get(); + // Create buffers. + for (unsigned short i = 0; i < submeshCount; i++) { + vector::type& lods = mBuffer.submesh[i].genIndexBuffers; + size_t indexCount = data->mIndexBufferInfoList[i].indexCount; + lods.reserve(lods.size() + 1); + LodIndexBuffer& curLod = *lods.insert(lods.begin() + lodIndex, LodIndexBuffer()); + if (indexCount == 0) { + curLod.indexCount = 3; + } else { + curLod.indexCount = indexCount; + } + curLod.indexStart = 0; + curLod.indexSize = data->mIndexBufferInfoList[i].indexSize; + curLod.indexBufferSize = 0; // It means same as index count + curLod.indexBuffer = Ogre::SharedPtr(new unsigned char[curLod.indexCount * curLod.indexSize]); + // buf is an union, so pint=pshort + data->mIndexBufferInfoList[i].buf.pshort = (unsigned short*) curLod.indexBuffer.get(); - if (indexCount == 0) { - memset(data->mIndexBufferInfoList[i].buf.pshort, 0, 3 * data->mIndexBufferInfoList[i].indexSize); - } - } + if (indexCount == 0) { + memset(data->mIndexBufferInfoList[i].buf.pshort, 0, 3 * data->mIndexBufferInfoList[i].indexSize); + } + } - // Fill buffers. - size_t triangleCount = data->mTriangleList.size(); - for (size_t i = 0; i < triangleCount; i++) { - if (!data->mTriangleList[i].isRemoved) { - if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } else { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } - } - } - } + // Fill buffers. + size_t triangleCount = data->mTriangleList.size(); + for (size_t i = 0; i < triangleCount; i++) { + if (!data->mTriangleList[i].isRemoved) { + if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } else { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } + } + } + } void LodOutputProviderBuffer::inject() { - unsigned short submeshCount = mBuffer.submesh.size(); - OgreAssert(mMesh->getNumSubMeshes() == submeshCount, ""); - mMesh->removeLodLevels(); - for (unsigned short i = 0; i < submeshCount; i++) { - SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; - typedef vector::type GenBuffers; - GenBuffers& buffers = mBuffer.submesh[i].genIndexBuffers; + unsigned short submeshCount = mBuffer.submesh.size(); + OgreAssert(mMesh->getNumSubMeshes() == submeshCount, ""); + mMesh->removeLodLevels(); + for (unsigned short i = 0; i < submeshCount; i++) { + SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; + typedef vector::type GenBuffers; + GenBuffers& buffers = mBuffer.submesh[i].genIndexBuffers; - size_t buffCount = buffers.size(); - for (size_t n=0; n= 0, ""); - lods.push_back(OGRE_NEW IndexData()); - lods.back()->indexStart = buff.indexStart; - lods.back()->indexCount = buff.indexCount; - if(indexCount != 0) { - if(n > 0 && buffers[n-1].indexBuffer == buff.indexBuffer){ - lods.back()->indexBuffer = (*(++lods.rbegin()))->indexBuffer; - } else { - lods.back()->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( - buff.indexSize == 2 ? - HardwareIndexBuffer::IT_16BIT : HardwareIndexBuffer::IT_32BIT, - indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - size_t sizeInBytes = lods.back()->indexBuffer->getSizeInBytes(); - void* pOutBuff = lods.back()->indexBuffer->lock(0, sizeInBytes, HardwareBuffer::HBL_DISCARD); - memcpy(pOutBuff, buff.indexBuffer.get(), sizeInBytes); - lods.back()->indexBuffer->unlock(); - } - } - } - } + size_t buffCount = buffers.size(); + for (size_t n=0; n= 0, ""); + lods.push_back(OGRE_NEW IndexData()); + lods.back()->indexStart = buff.indexStart; + lods.back()->indexCount = buff.indexCount; + if(indexCount != 0) { + if(n > 0 && buffers[n-1].indexBuffer == buff.indexBuffer){ + lods.back()->indexBuffer = (*(++lods.rbegin()))->indexBuffer; + } else { + lods.back()->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( + buff.indexSize == 2 ? + HardwareIndexBuffer::IT_16BIT : HardwareIndexBuffer::IT_32BIT, + indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + size_t sizeInBytes = lods.back()->indexBuffer->getSizeInBytes(); + void* pOutBuff = lods.back()->indexBuffer->lock(0, sizeInBytes, HardwareBuffer::HBL_DISCARD); + memcpy(pOutBuff, buff.indexBuffer.get(), sizeInBytes); + lods.back()->indexBuffer->unlock(); + } + } + } + } } } diff --git a/Components/MeshLodGenerator/src/OgreLodOutputProviderCompressedBuffer.cpp b/Components/MeshLodGenerator/src/OgreLodOutputProviderCompressedBuffer.cpp index 18b9494fdbf..0a9c2fb6005 100644 --- a/Components/MeshLodGenerator/src/OgreLodOutputProviderCompressedBuffer.cpp +++ b/Components/MeshLodGenerator/src/OgreLodOutputProviderCompressedBuffer.cpp @@ -1,173 +1,173 @@ -/* - * ----------------------------------------------------------------------------- - * This source file is part of OGRE - * (Object-oriented Graphics Rendering Engine) - * For the latest info, see http://www.ogre3d.org/ - * - * Copyright (c) 2000-2014 Torus Knot Software Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ----------------------------------------------------------------------------- - */ - -#include "OgreLodOutputProviderCompressedBuffer.h" -#include "OgreLodOutputProviderBuffer.h" - -namespace Ogre -{ - LodOutputProviderCompressedBuffer::LodOutputProviderCompressedBuffer( MeshPtr mesh ) : - LodOutputProviderCompressedMesh() - { - mMesh = mesh; - fallback = new LodOutputProviderBuffer(mesh); - } - void LodOutputProviderCompressedBuffer::bakeFirstPass(LodData* data, int lodIndex) { - unsigned short submeshCount = data->mIndexBufferInfoList.size(); - assert(mTriangleCacheList.size() == data->mTriangleList.size()); - mLastIndexBufferID = lodIndex; - - for (unsigned short i = 0; i < submeshCount; i++) { - data->mIndexBufferInfoList[i].prevIndexCount = data->mIndexBufferInfoList[i].indexCount; - data->mIndexBufferInfoList[i].prevOnlyIndexCount = 0; - } - - size_t triangleCount = mTriangleCacheList.size(); - for (size_t i = 0; i < triangleCount; i++) { - mTriangleCacheList[i].vertexChanged = false; - if (!data->mTriangleList[i].isRemoved) { - mTriangleCacheList[i].vertexID[0] = data->mTriangleList[i].vertexID[0]; - mTriangleCacheList[i].vertexID[1] = data->mTriangleList[i].vertexID[1]; - mTriangleCacheList[i].vertexID[2] = data->mTriangleList[i].vertexID[2]; - } - } - } - void LodOutputProviderCompressedBuffer::bakeSecondPass(LodData* data, int lodIndex) { - LodOutputBuffer& buffer = static_cast(fallback)->getBuffer(); - unsigned short submeshCount = data->mIndexBufferInfoList.size(); - assert(mTriangleCacheList.size() == data->mTriangleList.size()); - assert(lodIndex > mLastIndexBufferID); // Implementation limitation - - // Create buffers. - for (unsigned short i = 0; i < submeshCount; i++) { - vector::type& lods = buffer.submesh[i].genIndexBuffers; - lods.reserve(lods.size() + 2); - size_t indexCount = data->mIndexBufferInfoList[i].indexCount + data->mIndexBufferInfoList[i].prevOnlyIndexCount; - assert(data->mIndexBufferInfoList[i].prevIndexCount >= data->mIndexBufferInfoList[i].indexCount); - assert(data->mIndexBufferInfoList[i].prevIndexCount >= data->mIndexBufferInfoList[i].prevOnlyIndexCount); - - LodIndexBuffer& prevLod = *lods.insert(lods.begin() + mLastIndexBufferID, LodIndexBuffer()); - prevLod.indexStart = 0; - prevLod.indexSize = data->mIndexBufferInfoList[i].indexSize; - - //If the index is empty we need to create a "dummy" triangle, just to keep the index buffer from being empty. - //The main reason for this is that the OpenGL render system will crash with a segfault unless the index has some values. - //This should hopefully be removed with future versions of Ogre. The most preferred solution would be to add the - //ability for a submesh to be excluded from rendering for a given LOD (which isn't possible currently 2012-12-09). - indexCount = std::max(indexCount, 3); - prevLod.indexCount = std::max(data->mIndexBufferInfoList[i].prevIndexCount, 3u); - prevLod.indexBufferSize = indexCount; - prevLod.indexBuffer = Ogre::SharedPtr(new unsigned char[indexCount * data->mIndexBufferInfoList[i].indexSize]); - data->mIndexBufferInfoList[i].buf.pshort = (unsigned short*)prevLod.indexBuffer.get(); - - //Check if we should fill it with a "dummy" triangle. - if (indexCount == 3) { - memset(data->mIndexBufferInfoList[i].buf.pshort, 0, 3 * data->mIndexBufferInfoList[i].indexSize); - } - - LodIndexBuffer& curLod = *lods.insert(lods.begin() + lodIndex, LodIndexBuffer()); - curLod.indexSize = prevLod.indexSize; - curLod.indexStart = indexCount - data->mIndexBufferInfoList[i].indexCount; - curLod.indexCount = data->mIndexBufferInfoList[i].indexCount; - curLod.indexBufferSize = prevLod.indexBufferSize; - curLod.indexBuffer = prevLod.indexBuffer; - if(curLod.indexCount == 0){ - curLod.indexStart-=3; - curLod.indexCount=3; - } - - } - - - // Fill buffers. - // Filling will be done in 3 parts. - // 1. prevLod only indices. - size_t triangleCount = data->mTriangleList.size(); - for (size_t i = 0; i < triangleCount; i++) { - if (mTriangleCacheList[i].vertexChanged) { - assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].prevIndexCount != 0); - assert(mTriangleCacheList[i].vertexID[0] != mTriangleCacheList[i].vertexID[1]); - assert(mTriangleCacheList[i].vertexID[1] != mTriangleCacheList[i].vertexID[2]); - assert(mTriangleCacheList[i].vertexID[2] != mTriangleCacheList[i].vertexID[0]); - if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = - static_cast(mTriangleCacheList[i].vertexID[m]); - } - } else { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = - static_cast(mTriangleCacheList[i].vertexID[m]); - } - } - } - } - - - // 2. shared indices. - for (size_t i = 0; i < triangleCount; i++) { - if (!data->mTriangleList[i].isRemoved && !mTriangleCacheList[i].vertexChanged) { - assert(mTriangleCacheList[i].vertexID[0] == data->mTriangleList[i].vertexID[0]); - assert(mTriangleCacheList[i].vertexID[1] == data->mTriangleList[i].vertexID[1]); - assert(mTriangleCacheList[i].vertexID[2] == data->mTriangleList[i].vertexID[2]); - - assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexCount != 0); - assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].prevIndexCount != 0); - if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } else { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } - } - } - - // 3. curLod indices only. - for (size_t i = 0; i < triangleCount; i++) { - if (!data->mTriangleList[i].isRemoved && mTriangleCacheList[i].vertexChanged) { - assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexCount != 0); - if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } else { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } - } - } - } +/* + * ----------------------------------------------------------------------------- + * This source file is part of OGRE + * (Object-oriented Graphics Rendering Engine) + * For the latest info, see http://www.ogre3d.org/ + * + * Copyright (c) 2000-2014 Torus Knot Software Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ----------------------------------------------------------------------------- + */ + +#include "OgreLodOutputProviderCompressedBuffer.h" +#include "OgreLodOutputProviderBuffer.h" + +namespace Ogre +{ + LodOutputProviderCompressedBuffer::LodOutputProviderCompressedBuffer( MeshPtr mesh ) : + LodOutputProviderCompressedMesh() + { + mMesh = mesh; + fallback = new LodOutputProviderBuffer(mesh); + } + void LodOutputProviderCompressedBuffer::bakeFirstPass(LodData* data, int lodIndex) { + unsigned short submeshCount = data->mIndexBufferInfoList.size(); + assert(mTriangleCacheList.size() == data->mTriangleList.size()); + mLastIndexBufferID = lodIndex; + + for (unsigned short i = 0; i < submeshCount; i++) { + data->mIndexBufferInfoList[i].prevIndexCount = data->mIndexBufferInfoList[i].indexCount; + data->mIndexBufferInfoList[i].prevOnlyIndexCount = 0; + } + + size_t triangleCount = mTriangleCacheList.size(); + for (size_t i = 0; i < triangleCount; i++) { + mTriangleCacheList[i].vertexChanged = false; + if (!data->mTriangleList[i].isRemoved) { + mTriangleCacheList[i].vertexID[0] = data->mTriangleList[i].vertexID[0]; + mTriangleCacheList[i].vertexID[1] = data->mTriangleList[i].vertexID[1]; + mTriangleCacheList[i].vertexID[2] = data->mTriangleList[i].vertexID[2]; + } + } + } + void LodOutputProviderCompressedBuffer::bakeSecondPass(LodData* data, int lodIndex) { + LodOutputBuffer& buffer = static_cast(fallback)->getBuffer(); + unsigned short submeshCount = data->mIndexBufferInfoList.size(); + assert(mTriangleCacheList.size() == data->mTriangleList.size()); + assert(lodIndex > mLastIndexBufferID); // Implementation limitation + + // Create buffers. + for (unsigned short i = 0; i < submeshCount; i++) { + vector::type& lods = buffer.submesh[i].genIndexBuffers; + lods.reserve(lods.size() + 2); + size_t indexCount = data->mIndexBufferInfoList[i].indexCount + data->mIndexBufferInfoList[i].prevOnlyIndexCount; + assert(data->mIndexBufferInfoList[i].prevIndexCount >= data->mIndexBufferInfoList[i].indexCount); + assert(data->mIndexBufferInfoList[i].prevIndexCount >= data->mIndexBufferInfoList[i].prevOnlyIndexCount); + + LodIndexBuffer& prevLod = *lods.insert(lods.begin() + mLastIndexBufferID, LodIndexBuffer()); + prevLod.indexStart = 0; + prevLod.indexSize = data->mIndexBufferInfoList[i].indexSize; + + //If the index is empty we need to create a "dummy" triangle, just to keep the index buffer from being empty. + //The main reason for this is that the OpenGL render system will crash with a segfault unless the index has some values. + //This should hopefully be removed with future versions of Ogre. The most preferred solution would be to add the + //ability for a submesh to be excluded from rendering for a given LOD (which isn't possible currently 2012-12-09). + indexCount = std::max(indexCount, 3); + prevLod.indexCount = std::max(data->mIndexBufferInfoList[i].prevIndexCount, 3u); + prevLod.indexBufferSize = indexCount; + prevLod.indexBuffer = Ogre::SharedPtr(new unsigned char[indexCount * data->mIndexBufferInfoList[i].indexSize]); + data->mIndexBufferInfoList[i].buf.pshort = (unsigned short*)prevLod.indexBuffer.get(); + + //Check if we should fill it with a "dummy" triangle. + if (indexCount == 3) { + memset(data->mIndexBufferInfoList[i].buf.pshort, 0, 3 * data->mIndexBufferInfoList[i].indexSize); + } + + LodIndexBuffer& curLod = *lods.insert(lods.begin() + lodIndex, LodIndexBuffer()); + curLod.indexSize = prevLod.indexSize; + curLod.indexStart = indexCount - data->mIndexBufferInfoList[i].indexCount; + curLod.indexCount = data->mIndexBufferInfoList[i].indexCount; + curLod.indexBufferSize = prevLod.indexBufferSize; + curLod.indexBuffer = prevLod.indexBuffer; + if(curLod.indexCount == 0){ + curLod.indexStart-=3; + curLod.indexCount=3; + } + + } + + + // Fill buffers. + // Filling will be done in 3 parts. + // 1. prevLod only indices. + size_t triangleCount = data->mTriangleList.size(); + for (size_t i = 0; i < triangleCount; i++) { + if (mTriangleCacheList[i].vertexChanged) { + assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].prevIndexCount != 0); + assert(mTriangleCacheList[i].vertexID[0] != mTriangleCacheList[i].vertexID[1]); + assert(mTriangleCacheList[i].vertexID[1] != mTriangleCacheList[i].vertexID[2]); + assert(mTriangleCacheList[i].vertexID[2] != mTriangleCacheList[i].vertexID[0]); + if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = + static_cast(mTriangleCacheList[i].vertexID[m]); + } + } else { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = + static_cast(mTriangleCacheList[i].vertexID[m]); + } + } + } + } + + + // 2. shared indices. + for (size_t i = 0; i < triangleCount; i++) { + if (!data->mTriangleList[i].isRemoved && !mTriangleCacheList[i].vertexChanged) { + assert(mTriangleCacheList[i].vertexID[0] == data->mTriangleList[i].vertexID[0]); + assert(mTriangleCacheList[i].vertexID[1] == data->mTriangleList[i].vertexID[1]); + assert(mTriangleCacheList[i].vertexID[2] == data->mTriangleList[i].vertexID[2]); + + assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexCount != 0); + assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].prevIndexCount != 0); + if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } else { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } + } + } + + // 3. curLod indices only. + for (size_t i = 0; i < triangleCount; i++) { + if (!data->mTriangleList[i].isRemoved && mTriangleCacheList[i].vertexChanged) { + assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexCount != 0); + if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } else { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } + } + } + } } \ No newline at end of file diff --git a/Components/MeshLodGenerator/src/OgreLodOutputProviderCompressedMesh.cpp b/Components/MeshLodGenerator/src/OgreLodOutputProviderCompressedMesh.cpp index d6aa48cb9ec..9c97fb3b4c3 100644 --- a/Components/MeshLodGenerator/src/OgreLodOutputProviderCompressedMesh.cpp +++ b/Components/MeshLodGenerator/src/OgreLodOutputProviderCompressedMesh.cpp @@ -35,216 +35,216 @@ namespace Ogre { - LodOutputProviderCompressedMesh::LodOutputProviderCompressedMesh( MeshPtr mesh ) : - mFirstBufferPass(0), mMesh(mesh), mLastIndexBufferID(0) - { - fallback = new LodOutputProviderMesh(mesh); - } - - LodOutputProviderCompressedMesh::LodOutputProviderCompressedMesh() - { - - } - - - LodOutputProviderCompressedMesh::~LodOutputProviderCompressedMesh() - { - delete fallback; - } - - void LodOutputProviderCompressedMesh::prepare( LodData* data ) - { - mFirstBufferPass = true; - mTriangleCacheList.resize(data->mTriangleList.size()); - fallback->prepare(data); - } - - void LodOutputProviderCompressedMesh::finalize( LodData* data ) - { - if(!mFirstBufferPass){ - // Uneven number of Lod levels. We need to bake the last one separately. - fallback->bakeLodLevel(data, mLastIndexBufferID); - } - fallback->finalize(data); - } - - void LodOutputProviderCompressedMesh::bakeManualLodLevel( LodData* data, String& manualMeshName, int lodIndex ) - { - if(!mFirstBufferPass){ - lodIndex--; - } - fallback->bakeManualLodLevel(data, manualMeshName, lodIndex); - } - - void LodOutputProviderCompressedMesh::inject() - { - fallback->inject(); - } - - void LodOutputProviderCompressedMesh::bakeLodLevel(LodData* data, int lodIndex) - { - if(mFirstBufferPass){ - bakeFirstPass(data, lodIndex); - } else { - bakeSecondPass(data, lodIndex); - } - mFirstBufferPass = !mFirstBufferPass; - } - void LodOutputProviderCompressedMesh::bakeFirstPass(LodData* data, int lodIndex) { - unsigned short submeshCount = mMesh->getNumSubMeshes(); - assert(mTriangleCacheList.size() == data->mTriangleList.size()); - mLastIndexBufferID = lodIndex; - - for (unsigned short i = 0; i < submeshCount; i++) { - data->mIndexBufferInfoList[i].prevIndexCount = data->mIndexBufferInfoList[i].indexCount; - data->mIndexBufferInfoList[i].prevOnlyIndexCount = 0; - } - - size_t triangleCount = mTriangleCacheList.size(); - for (size_t i = 0; i < triangleCount; i++) { - mTriangleCacheList[i].vertexChanged = false; - if (!data->mTriangleList[i].isRemoved) { - mTriangleCacheList[i].vertexID[0] = data->mTriangleList[i].vertexID[0]; - mTriangleCacheList[i].vertexID[1] = data->mTriangleList[i].vertexID[1]; - mTriangleCacheList[i].vertexID[2] = data->mTriangleList[i].vertexID[2]; - } - } - } - void LodOutputProviderCompressedMesh::bakeSecondPass(LodData* data, int lodIndex) { - unsigned short submeshCount = mMesh->getNumSubMeshes(); - assert(mTriangleCacheList.size() == data->mTriangleList.size()); - assert(lodIndex > mLastIndexBufferID); // Implementation limitation - // Create buffers. - for (unsigned short i = 0; i < submeshCount; i++) { - SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; - lods.reserve(lods.size() + 2); - size_t indexCount = data->mIndexBufferInfoList[i].indexCount + data->mIndexBufferInfoList[i].prevOnlyIndexCount; - assert(data->mIndexBufferInfoList[i].prevIndexCount >= data->mIndexBufferInfoList[i].indexCount); - assert(data->mIndexBufferInfoList[i].prevIndexCount >= data->mIndexBufferInfoList[i].prevOnlyIndexCount); - - IndexData* prevLod = *lods.insert(lods.begin() + mLastIndexBufferID, OGRE_NEW IndexData()); - prevLod->indexStart = 0; - - //If the index is empty we need to create a "dummy" triangle, just to keep the index buffer from being empty. - //The main reason for this is that the OpenGL render system will crash with a segfault unless the index has some values. - //This should hopefully be removed with future versions of Ogre. The most preferred solution would be to add the - //ability for a submesh to be excluded from rendering for a given LOD (which isn't possible currently 2012-12-09). - indexCount = std::max(indexCount, 3); - prevLod->indexCount = std::max(data->mIndexBufferInfoList[i].prevIndexCount, 3u); - - prevLod->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( - data->mIndexBufferInfoList[i].indexSize == 2 ? - HardwareIndexBuffer::IT_16BIT : HardwareIndexBuffer::IT_32BIT, - indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - - data->mIndexBufferInfoList[i].buf.pshort = - static_cast(prevLod->indexBuffer->lock(0, prevLod->indexBuffer->getSizeInBytes(), - HardwareBuffer::HBL_DISCARD)); - - //Check if we should fill it with a "dummy" triangle. - if (indexCount == 3) { - memset(data->mIndexBufferInfoList[i].buf.pshort, 0, 3 * data->mIndexBufferInfoList[i].indexSize); - } - - // Set up the other Lod - IndexData* curLod = *lods.insert(lods.begin() + lodIndex, OGRE_NEW IndexData()); - curLod->indexStart = indexCount - data->mIndexBufferInfoList[i].indexCount; - curLod->indexCount = data->mIndexBufferInfoList[i].indexCount; - if(curLod->indexCount == 0){ - curLod->indexStart-=3; - curLod->indexCount=3; - } - } - - // Fill buffers. - // Filling will be done in 3 parts. - // 1. prevLod only indices. - size_t triangleCount = mTriangleCacheList.size(); - for (size_t i = 0; i < triangleCount; i++) { - if (mTriangleCacheList[i].vertexChanged) { - assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].prevIndexCount != 0); - assert(mTriangleCacheList[i].vertexID[0] != mTriangleCacheList[i].vertexID[1]); - assert(mTriangleCacheList[i].vertexID[1] != mTriangleCacheList[i].vertexID[2]); - assert(mTriangleCacheList[i].vertexID[2] != mTriangleCacheList[i].vertexID[0]); - if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = - static_cast(mTriangleCacheList[i].vertexID[m]); - } - } else { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = - static_cast(mTriangleCacheList[i].vertexID[m]); - } - } - } - } - - - // 2. shared indices. - for (size_t i = 0; i < triangleCount; i++) { - if (!data->mTriangleList[i].isRemoved && !mTriangleCacheList[i].vertexChanged) { - assert(mTriangleCacheList[i].vertexID[0] == data->mTriangleList[i].vertexID[0]); - assert(mTriangleCacheList[i].vertexID[1] == data->mTriangleList[i].vertexID[1]); - assert(mTriangleCacheList[i].vertexID[2] == data->mTriangleList[i].vertexID[2]); - - assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexCount != 0); - assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].prevIndexCount != 0); - if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } else { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } - } - } - - // 3. curLod indices only. - for (size_t i = 0; i < triangleCount; i++) { - if (!data->mTriangleList[i].isRemoved && mTriangleCacheList[i].vertexChanged) { - assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexCount != 0); - if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } else { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } - } - } - - // Close buffers. - for (unsigned short i = 0; i < submeshCount; i++) { - SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; - IndexData* prevLod = lods[mLastIndexBufferID]; - IndexData* curLod = lods[lodIndex]; - prevLod->indexBuffer->unlock(); - curLod->indexBuffer = prevLod->indexBuffer; - } - } - - void LodOutputProviderCompressedMesh::triangleRemoved( LodData* data, LodData::Triangle* tri ) - { - triangleChanged(data, tri); - } - - void LodOutputProviderCompressedMesh::triangleChanged( LodData* data, LodData::Triangle* tri ) - { - assert(!tri->isRemoved); - TriangleCache& cache = mTriangleCacheList[LodData::getVectorIDFromPointer(data->mTriangleList, tri)]; - if(!cache.vertexChanged){ - cache.vertexChanged = true; - data->mIndexBufferInfoList[tri->submeshID].prevOnlyIndexCount += 3; - } - } + LodOutputProviderCompressedMesh::LodOutputProviderCompressedMesh( MeshPtr mesh ) : + mFirstBufferPass(0), mMesh(mesh), mLastIndexBufferID(0) + { + fallback = new LodOutputProviderMesh(mesh); + } + + LodOutputProviderCompressedMesh::LodOutputProviderCompressedMesh() + { + + } + + + LodOutputProviderCompressedMesh::~LodOutputProviderCompressedMesh() + { + delete fallback; + } + + void LodOutputProviderCompressedMesh::prepare( LodData* data ) + { + mFirstBufferPass = true; + mTriangleCacheList.resize(data->mTriangleList.size()); + fallback->prepare(data); + } + + void LodOutputProviderCompressedMesh::finalize( LodData* data ) + { + if(!mFirstBufferPass){ + // Uneven number of Lod levels. We need to bake the last one separately. + fallback->bakeLodLevel(data, mLastIndexBufferID); + } + fallback->finalize(data); + } + + void LodOutputProviderCompressedMesh::bakeManualLodLevel( LodData* data, String& manualMeshName, int lodIndex ) + { + if(!mFirstBufferPass){ + lodIndex--; + } + fallback->bakeManualLodLevel(data, manualMeshName, lodIndex); + } + + void LodOutputProviderCompressedMesh::inject() + { + fallback->inject(); + } + + void LodOutputProviderCompressedMesh::bakeLodLevel(LodData* data, int lodIndex) + { + if(mFirstBufferPass){ + bakeFirstPass(data, lodIndex); + } else { + bakeSecondPass(data, lodIndex); + } + mFirstBufferPass = !mFirstBufferPass; + } + void LodOutputProviderCompressedMesh::bakeFirstPass(LodData* data, int lodIndex) { + unsigned short submeshCount = mMesh->getNumSubMeshes(); + assert(mTriangleCacheList.size() == data->mTriangleList.size()); + mLastIndexBufferID = lodIndex; + + for (unsigned short i = 0; i < submeshCount; i++) { + data->mIndexBufferInfoList[i].prevIndexCount = data->mIndexBufferInfoList[i].indexCount; + data->mIndexBufferInfoList[i].prevOnlyIndexCount = 0; + } + + size_t triangleCount = mTriangleCacheList.size(); + for (size_t i = 0; i < triangleCount; i++) { + mTriangleCacheList[i].vertexChanged = false; + if (!data->mTriangleList[i].isRemoved) { + mTriangleCacheList[i].vertexID[0] = data->mTriangleList[i].vertexID[0]; + mTriangleCacheList[i].vertexID[1] = data->mTriangleList[i].vertexID[1]; + mTriangleCacheList[i].vertexID[2] = data->mTriangleList[i].vertexID[2]; + } + } + } + void LodOutputProviderCompressedMesh::bakeSecondPass(LodData* data, int lodIndex) { + unsigned short submeshCount = mMesh->getNumSubMeshes(); + assert(mTriangleCacheList.size() == data->mTriangleList.size()); + assert(lodIndex > mLastIndexBufferID); // Implementation limitation + // Create buffers. + for (unsigned short i = 0; i < submeshCount; i++) { + SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; + lods.reserve(lods.size() + 2); + size_t indexCount = data->mIndexBufferInfoList[i].indexCount + data->mIndexBufferInfoList[i].prevOnlyIndexCount; + assert(data->mIndexBufferInfoList[i].prevIndexCount >= data->mIndexBufferInfoList[i].indexCount); + assert(data->mIndexBufferInfoList[i].prevIndexCount >= data->mIndexBufferInfoList[i].prevOnlyIndexCount); + + IndexData* prevLod = *lods.insert(lods.begin() + mLastIndexBufferID, OGRE_NEW IndexData()); + prevLod->indexStart = 0; + + //If the index is empty we need to create a "dummy" triangle, just to keep the index buffer from being empty. + //The main reason for this is that the OpenGL render system will crash with a segfault unless the index has some values. + //This should hopefully be removed with future versions of Ogre. The most preferred solution would be to add the + //ability for a submesh to be excluded from rendering for a given LOD (which isn't possible currently 2012-12-09). + indexCount = std::max(indexCount, 3); + prevLod->indexCount = std::max(data->mIndexBufferInfoList[i].prevIndexCount, 3u); + + prevLod->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( + data->mIndexBufferInfoList[i].indexSize == 2 ? + HardwareIndexBuffer::IT_16BIT : HardwareIndexBuffer::IT_32BIT, + indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + + data->mIndexBufferInfoList[i].buf.pshort = + static_cast(prevLod->indexBuffer->lock(0, prevLod->indexBuffer->getSizeInBytes(), + HardwareBuffer::HBL_DISCARD)); + + //Check if we should fill it with a "dummy" triangle. + if (indexCount == 3) { + memset(data->mIndexBufferInfoList[i].buf.pshort, 0, 3 * data->mIndexBufferInfoList[i].indexSize); + } + + // Set up the other Lod + IndexData* curLod = *lods.insert(lods.begin() + lodIndex, OGRE_NEW IndexData()); + curLod->indexStart = indexCount - data->mIndexBufferInfoList[i].indexCount; + curLod->indexCount = data->mIndexBufferInfoList[i].indexCount; + if(curLod->indexCount == 0){ + curLod->indexStart-=3; + curLod->indexCount=3; + } + } + + // Fill buffers. + // Filling will be done in 3 parts. + // 1. prevLod only indices. + size_t triangleCount = mTriangleCacheList.size(); + for (size_t i = 0; i < triangleCount; i++) { + if (mTriangleCacheList[i].vertexChanged) { + assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].prevIndexCount != 0); + assert(mTriangleCacheList[i].vertexID[0] != mTriangleCacheList[i].vertexID[1]); + assert(mTriangleCacheList[i].vertexID[1] != mTriangleCacheList[i].vertexID[2]); + assert(mTriangleCacheList[i].vertexID[2] != mTriangleCacheList[i].vertexID[0]); + if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = + static_cast(mTriangleCacheList[i].vertexID[m]); + } + } else { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = + static_cast(mTriangleCacheList[i].vertexID[m]); + } + } + } + } + + + // 2. shared indices. + for (size_t i = 0; i < triangleCount; i++) { + if (!data->mTriangleList[i].isRemoved && !mTriangleCacheList[i].vertexChanged) { + assert(mTriangleCacheList[i].vertexID[0] == data->mTriangleList[i].vertexID[0]); + assert(mTriangleCacheList[i].vertexID[1] == data->mTriangleList[i].vertexID[1]); + assert(mTriangleCacheList[i].vertexID[2] == data->mTriangleList[i].vertexID[2]); + + assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexCount != 0); + assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].prevIndexCount != 0); + if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } else { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } + } + } + + // 3. curLod indices only. + for (size_t i = 0; i < triangleCount; i++) { + if (!data->mTriangleList[i].isRemoved && mTriangleCacheList[i].vertexChanged) { + assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexCount != 0); + if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } else { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } + } + } + + // Close buffers. + for (unsigned short i = 0; i < submeshCount; i++) { + SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; + IndexData* prevLod = lods[mLastIndexBufferID]; + IndexData* curLod = lods[lodIndex]; + prevLod->indexBuffer->unlock(); + curLod->indexBuffer = prevLod->indexBuffer; + } + } + + void LodOutputProviderCompressedMesh::triangleRemoved( LodData* data, LodData::Triangle* tri ) + { + triangleChanged(data, tri); + } + + void LodOutputProviderCompressedMesh::triangleChanged( LodData* data, LodData::Triangle* tri ) + { + assert(!tri->isRemoved); + TriangleCache& cache = mTriangleCacheList[LodData::getVectorIDFromPointer(data->mTriangleList, tri)]; + if(!cache.vertexChanged){ + cache.vertexChanged = true; + data->mIndexBufferInfoList[tri->submeshID].prevOnlyIndexCount += 3; + } + } } diff --git a/Components/MeshLodGenerator/src/OgreLodOutputProviderMesh.cpp b/Components/MeshLodGenerator/src/OgreLodOutputProviderMesh.cpp index ea0752191c5..d272559775b 100644 --- a/Components/MeshLodGenerator/src/OgreLodOutputProviderMesh.cpp +++ b/Components/MeshLodGenerator/src/OgreLodOutputProviderMesh.cpp @@ -34,87 +34,87 @@ namespace Ogre { - void LodOutputProviderMesh::prepare( LodData* data ) - { - unsigned short submeshCount = mMesh->getNumSubMeshes(); + void LodOutputProviderMesh::prepare( LodData* data ) + { + unsigned short submeshCount = mMesh->getNumSubMeshes(); - // Create buffers. - for (unsigned short i = 0; i < submeshCount; i++) { - SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; - lods.resize(1); - } - } + // Create buffers. + for (unsigned short i = 0; i < submeshCount; i++) { + SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; + lods.resize(1); + } + } - void LodOutputProviderMesh::bakeManualLodLevel( LodData* data, String& manualMeshName, int lodIndex) - { - // placeholder dummy - unsigned short submeshCount = mMesh->getNumSubMeshes(); - for (unsigned short i = 0; i < submeshCount; i++) { - SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; - lods.insert(lods.begin() + lodIndex, OGRE_NEW IndexData()); - } - } + void LodOutputProviderMesh::bakeManualLodLevel( LodData* data, String& manualMeshName, int lodIndex) + { + // placeholder dummy + unsigned short submeshCount = mMesh->getNumSubMeshes(); + for (unsigned short i = 0; i < submeshCount; i++) { + SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; + lods.insert(lods.begin() + lodIndex, OGRE_NEW IndexData()); + } + } - void LodOutputProviderMesh::bakeLodLevel(LodData* data, int lodIndex) - { - unsigned short submeshCount = mMesh->getNumSubMeshes(); + void LodOutputProviderMesh::bakeLodLevel(LodData* data, int lodIndex) + { + unsigned short submeshCount = mMesh->getNumSubMeshes(); - // Create buffers. - for (unsigned short i = 0; i < submeshCount; i++) { - SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; - size_t indexCount = data->mIndexBufferInfoList[i].indexCount; - IndexData* curLod = OGRE_NEW IndexData(); - curLod->indexStart = 0; - lods.insert(lods.begin() + lodIndex, curLod); - if (indexCount == 0) { - //If the index is empty we need to create a "dummy" triangle, just to keep the index buffer from being empty. - //The main reason for this is that the OpenGL render system will crash with a segfault unless the index has some values. - //This should hopefully be removed with future versions of Ogre. The most preferred solution would be to add the - //ability for a submesh to be excluded from rendering for a given LOD (which isn't possible currently 2012-12-09). - curLod->indexCount = 3; - } else { - curLod->indexCount = indexCount; - } + // Create buffers. + for (unsigned short i = 0; i < submeshCount; i++) { + SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; + size_t indexCount = data->mIndexBufferInfoList[i].indexCount; + IndexData* curLod = OGRE_NEW IndexData(); + curLod->indexStart = 0; + lods.insert(lods.begin() + lodIndex, curLod); + if (indexCount == 0) { + //If the index is empty we need to create a "dummy" triangle, just to keep the index buffer from being empty. + //The main reason for this is that the OpenGL render system will crash with a segfault unless the index has some values. + //This should hopefully be removed with future versions of Ogre. The most preferred solution would be to add the + //ability for a submesh to be excluded from rendering for a given LOD (which isn't possible currently 2012-12-09). + curLod->indexCount = 3; + } else { + curLod->indexCount = indexCount; + } - curLod->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( - data->mIndexBufferInfoList[i].indexSize == 2 ? - HardwareIndexBuffer::IT_16BIT : HardwareIndexBuffer::IT_32BIT, - curLod->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + curLod->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( + data->mIndexBufferInfoList[i].indexSize == 2 ? + HardwareIndexBuffer::IT_16BIT : HardwareIndexBuffer::IT_32BIT, + curLod->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - data->mIndexBufferInfoList[i].buf.pshort = - static_cast(curLod->indexBuffer->lock(0, curLod->indexBuffer->getSizeInBytes(), - HardwareBuffer::HBL_DISCARD)); + data->mIndexBufferInfoList[i].buf.pshort = + static_cast(curLod->indexBuffer->lock(0, curLod->indexBuffer->getSizeInBytes(), + HardwareBuffer::HBL_DISCARD)); - //Check if we should fill it with a "dummy" triangle. - if (indexCount == 0) { - memset(data->mIndexBufferInfoList[i].buf.pshort, 0, 3 * data->mIndexBufferInfoList[i].indexSize); - } - } + //Check if we should fill it with a "dummy" triangle. + if (indexCount == 0) { + memset(data->mIndexBufferInfoList[i].buf.pshort, 0, 3 * data->mIndexBufferInfoList[i].indexSize); + } + } - // Fill buffers. - size_t triangleCount = data->mTriangleList.size(); - for (size_t i = 0; i < triangleCount; i++) { - if (!data->mTriangleList[i].isRemoved) { - assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexCount != 0); - if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } else { - for (int m = 0; m < 3; m++) { - *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = - static_cast(data->mTriangleList[i].vertexID[m]); - } - } - } - } + // Fill buffers. + size_t triangleCount = data->mTriangleList.size(); + for (size_t i = 0; i < triangleCount; i++) { + if (!data->mTriangleList[i].isRemoved) { + assert(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexCount != 0); + if (data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].indexSize == 2) { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pshort++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } else { + for (int m = 0; m < 3; m++) { + *(data->mIndexBufferInfoList[data->mTriangleList[i].submeshID].buf.pint++) = + static_cast(data->mTriangleList[i].vertexID[m]); + } + } + } + } - // Close buffers. - for (unsigned short i = 0; i < submeshCount; i++) { - SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; - lods[lodIndex]->indexBuffer->unlock(); - } - } + // Close buffers. + for (unsigned short i = 0; i < submeshCount; i++) { + SubMesh::LODFaceList& lods = mMesh->getSubMesh(i)->mLodFaceList; + lods[lodIndex]->indexBuffer->unlock(); + } + } } diff --git a/Components/MeshLodGenerator/src/OgreLodOutsideMarker.cpp b/Components/MeshLodGenerator/src/OgreLodOutsideMarker.cpp index 3b9a071c515..36beeb9756d 100644 --- a/Components/MeshLodGenerator/src/OgreLodOutsideMarker.cpp +++ b/Components/MeshLodGenerator/src/OgreLodOutsideMarker.cpp @@ -1,603 +1,603 @@ -/* ------------------------------------------------------------------------------ -This source file is part of OGRE - (Object-oriented Graphics Rendering Engine) -For the latest info, see http://www.ogre3d.org/ - -Copyright (c) 2000-2014 Torus Knot Software Ltd - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. ------------------------------------------------------------------------------ -*/ -#include "OgreLodOutsideMarker.h" -#include "OgreHardwareBufferManager.h" -#include "OgreMeshManager.h" -#include "OgreMesh.h" -#include "OgreSubMesh.h" - -namespace Ogre -{ - -LodOutsideMarker::LodOutsideMarker(LodData::VertexList & vertexList, Real boundingSphereRadius, Real walkAngle) : - mEpsilon(boundingSphereRadius * std::numeric_limits::epsilon() * (Real)4.0), // How much floating point math error you have for equal values. This may depend on compiler flags. - mVertexListOrig(vertexList), - mWalkAngle(walkAngle) -{ - assert(!vertexList.empty()); - assert(mWalkAngle >= -1.0001f && mWalkAngle <= 1.0001f); // dot product range - assert(boundingSphereRadius > 0.0f); // invalid meshes are having a bounding sphere radius of 0.0! -} - -void LodOutsideMarker::markOutside() -{ - generateHull(); - markVertices(); -} - -void LodOutsideMarker::generateHull() -{ - initHull(); - { - for (size_t i = 0; i < mHull.size(); i++) { - if (!mHull[i].removed) { - CHVertex* furthestVertex = getFurthestVertex(&mHull[i]); - if (!furthestVertex) { - continue; - } - addVertex(furthestVertex); - } - } - } - cleanHull(); -} - -void LodOutsideMarker::initHull() -{ - mHull.clear(); - mHull.reserve(mVertexListOrig.size()); - mOutsideData.clear(); - OutsideDataList::iterator itOut, itOutEnd; - mOutsideData.resize(mVertexListOrig.size()); - itOut = mOutsideData.begin(); - itOutEnd = mOutsideData.end(); - for (; itOut != itOutEnd; itOut++) { - // reset output variables - itOut->isOuterWallVertex = false; - itOut->isInsideHull = false; - } - // We need to find 4 vertices, which are on the convex hull to start the algorithm. - CHVertex* vertex[4] = { NULL, NULL, NULL, NULL }; - - { - // Get 1. vertex: minimum y vertex - Real miny = std::numeric_limits::max(); - LodData::VertexList::iterator v, vEnd; - v = mVertexListOrig.begin(); - vEnd = mVertexListOrig.end(); - for (; v != vEnd; v++) { - Vector3& pos = v->position; - if (pos.y < miny) { - miny = pos.y; - vertex[0] = &*v; - } - } - assert(vertex[0]); // Vertex not found! - } - - { - // Get 2. vertex: furthest from 1. vertex - Real maxdist = 0.0; - LodData::VertexList::iterator v, vEnd; - v = mVertexListOrig.begin(); - vEnd = mVertexListOrig.end(); - for (; v != vEnd; v++) { - Real dist = vertex[0]->position.squaredDistance(v->position); - if (dist > maxdist) { - maxdist = dist; - vertex[1] = &*v; - } - } - assert(vertex[1]); // Vertex not found! - } - - { - // Get 3. vertex: furthest from 1. vertex and 2. vertex - Real maxdist = 0.0; - LodData::VertexList::iterator v, vEnd; - v = mVertexListOrig.begin(); - vEnd = mVertexListOrig.end(); - for (; v != vEnd; v++) { - Real dist = getPointToLineSqraredDistance(vertex[0], vertex[1], &*v); - if (dist > maxdist) { - maxdist = dist; - vertex[2] = &*v; - } - } - assert(vertex[2]); // Vertex not found! - } - - { - // Get 4. vertex: furthest from 1-2-3 triangle - Real maxdist = 0.0f; - Plane plane(vertex[0]->position, vertex[1]->position, vertex[2]->position); - plane.normalise(); - LodData::VertexList::iterator v, vEnd; - v = mVertexListOrig.begin(); - vEnd = mVertexListOrig.end(); - for (; v != vEnd; v++) { - Real dist = std::abs(plane.getDistance(v->position)); - if (dist > maxdist) { - maxdist = dist; - vertex[3] = &*v; - } - } - assert(vertex[3]); // Vertex not found! - } - - // Volume should be bigger than 0, so that we can guarantee that the centroid point is inside the hull - assert(getTetrahedronVolume(vertex[0], vertex[1], vertex[2], vertex[3]) > mEpsilon); - // Centroid = (a + b + c + d) / 4 - mCentroid = vertex[0]->position + vertex[1]->position + vertex[2]->position + vertex[3]->position; - mCentroid /= 4.0f; - - // Mark vertices, so that they will not be processed again. - getOutsideData(vertex[0])->isInsideHull = true; - getOutsideData(vertex[1])->isInsideHull = true; - getOutsideData(vertex[2])->isInsideHull = true; - getOutsideData(vertex[3])->isInsideHull = true; - - // Create the triangles - createTriangle(vertex[0], vertex[1], vertex[2]); - createTriangle(vertex[0], vertex[1], vertex[3]); - createTriangle(vertex[0], vertex[2], vertex[3]); - createTriangle(vertex[1], vertex[2], vertex[3]); -} - -void LodOutsideMarker::createTriangle( CHVertex* v1, CHVertex* v2, CHVertex* v3 ) -{ - CHTriangle tri; - tri.removed = false; - tri.vertex[0] = v1; - tri.vertex[1] = v2; - tri.vertex[2] = v3; - tri.computeNormal(); - if (isVisible(&tri, mCentroid)) { - std::swap(tri.vertex[0], tri.vertex[1]); - tri.computeNormal(); - } - mHull.push_back(tri); -} - -Real LodOutsideMarker::getPointToLineSqraredDistance(CHVertex* x1, CHVertex* x2, CHVertex* p) -{ - Real up = ((x2->position - x1->position).crossProduct(x1->position - p->position)).squaredLength(); - Real down = (x2->position - x1->position).squaredLength(); - return up / down; -} - -Real LodOutsideMarker::getTetrahedronVolume(CHVertex* a, CHVertex* b, CHVertex* c, CHVertex* d) -{ - // V = |(a-d)*[(b-d)x(c-d)]| / 6 - return std::abs((a->position - d->position).dotProduct((b->position - d->position).crossProduct(c->position - d->position))) / 6.0f; -} - -LodOutsideMarker::CHVertex* LodOutsideMarker::getFurthestVertex(CHTriangle* tri) -{ - // Find the furthest vertex from triangle plane towards the facing direction. - CHVertex* furthestVertex = NULL; - Real furthestDistance = 0; - Plane plane(tri->normal, -tri->normal.dotProduct(tri->vertex[0]->position)); - plane.normalise(); - LodData::VertexList::iterator v, vEnd; - v = mVertexListOrig.begin(); - vEnd = mVertexListOrig.end(); - for (; v != vEnd; v++) { - if (getOutsideData(&*v)->isInsideHull) { - continue; - } - Real dist = plane.getDistance(v->position); - if (dist > furthestDistance) { - furthestDistance = dist; - furthestVertex = &*v; - } - } - return furthestVertex; -} - -size_t LodOutsideMarker::addVertex( CHVertex* vertex ) -{ - getOutsideData(vertex)->isInsideHull = true; - // We use class members for triangles and edges only to prevent allocation. - mVisibleTriangles.clear(); - mEdges.clear(); - getVisibleTriangles(vertex, mVisibleTriangles); // get the hull triangles, which are facing the vertex. - if (mVisibleTriangles.empty()) { - return 0; // It's inside the Hull. - } - getHorizon(mVisibleTriangles, mEdges); // Returns the edges of a circle around the triangles. Also removes the triangles - fillHorizon(mEdges, vertex); // Creates triangles from the edges towards the vertex. - return mEdges.size(); -} - -void LodOutsideMarker::getVisibleTriangles( const CHVertex* target, CHTrianglePList& visibleTriangles ) -{ - - CHTriangleList::iterator it = mHull.begin(); - CHTriangleList::iterator itEnd = mHull.end(); - for (; it != itEnd; it++) { - if (it->removed) { - continue; - } - Real dot1 = it->normal.dotProduct(it->vertex[0]->position); - Real dot2 = it->normal.dotProduct(target->position); - if(std::abs(dot2 - dot1) <= mEpsilon) { - //Special case: The vertex is on the plane of the triangle - //mVisibleTriangles.push_back(&*it); - if (isInsideTriangle(target->position, *it)) { - // Vertex is inside of a convex hull triangle. - mVisibleTriangles.clear(); - return; - } else { - // If the vertex is outside, then we should add it to the hull. - visibleTriangles.push_back(&*it); - } - } else if (dot1 < dot2) { - visibleTriangles.push_back(&*it); - } - } -} - -void LodOutsideMarker::addEdge(CHEdgeList& edges, CHVertex* a, CHVertex* b) -{ - // We need undirectional edges, so we sort the vertices by their pointer like integers. - // This is needed, because we want to remove edges which were inside multiple triangles, - // because those are not on the horizon. - if (a <= b) { - edges.push_back(CHEdgeList::value_type(a, b)); - } else { - edges.push_back(CHEdgeList::value_type(b, a)); - } -} - -bool LodOutsideMarker::isInsideTriangle(const Vector3& ptarget, const CHTriangle& tri){ - - // The idea is that if all angle is smaller to that point, than it should be inside. - // NOTE: We assume that the vertex is on the triangle plane! - - const Vector3& p0 = tri.vertex[0]->position; - const Vector3& p1 = tri.vertex[1]->position; - const Vector3& p2 = tri.vertex[2]->position; - const Vector3& n = tri.normal; - - bool b0, b1, b2; - - // It should not contain malformed triangles! - assert(!isSamePosition(p0, p1) && !isSamePosition(p1, p2) && !isSamePosition(p2, p0)); - - { - Real d0 = pointToLineDir(ptarget, p0, p1, p2, n); - if (std::abs(d0) <= mEpsilon){ - //Vertex is on the edge, so we need to compare length. - return isInsideLine(ptarget, p0, p1); - } - b0 = d0 < 0.0f; - } - - { - Real d1 = pointToLineDir(ptarget, p1, p2, p0, n); - if (std::abs(d1) <= mEpsilon){ - //Vertex is on the edge, so we need to compare length. - return isInsideLine(ptarget, p1, p2); - } - b1 = d1 < 0.0f; - } - - if (b0 != b1) { - return false; - } - - { - Real d2 = pointToLineDir(ptarget, p2, p0, p1, n); - if (std::abs(d2) <= mEpsilon){ - //Vertex is on the edge, so we need to compare length. - return isInsideLine(ptarget, p2, p0); - } - b2 = d2 < 0.0f; - } - - return (b1 == b2); -} - -bool LodOutsideMarker::isSamePosition( const Vector3& p0, const Vector3& p1 ) -{ - return (std::abs(p0.x - p1.x) <= mEpsilon && std::abs(p0.y - p1.y) <= mEpsilon && std::abs(p0.z - p1.z) <= mEpsilon); -} - -Real LodOutsideMarker::pointToLineDir(const Vector3& ptarget, const Vector3& p0, const Vector3& p1, const Vector3& p2, const Vector3& n) -{ - return n.crossProduct(p1 - p0).dotProduct(ptarget - p0); -} - -bool LodOutsideMarker::isInsideLine( const Vector3& ptarget, const Vector3& p0, const Vector3& p1 ) -{ - // This function returns whether ptarget is between p0 and p1. - // It is outside if: - // -the dir vector is in the opposite direction - // -the length is smaller. - // -ptarget is not p0 or p1 - // NOTE: We assume that the 3 points are on the same line! - - Vector3 v1 = p1 - p0; - Vector3 v2 = ptarget - p0; - Real len1 = v1.squaredLength(); - Real len2 = v2.squaredLength(); - Real dot = v1.dotProduct(v2); - return isSamePosition(ptarget, p1) || ( - dot > 0.0 // Same direction - && len1 > len2); // Shorter -} - -void LodOutsideMarker::getHorizon( const CHTrianglePList& tri, CHEdgeList& horizon) -{ - // Create edge list and remove triangles - CHTrianglePList::const_iterator it2 = tri.begin(); - CHTrianglePList::const_iterator it2End = tri.end(); - for (; it2 != it2End; it2++) { - addEdge(horizon, (*it2)->vertex[0], (*it2)->vertex[1]); - addEdge(horizon, (*it2)->vertex[1], (*it2)->vertex[2]); - addEdge(horizon, (*it2)->vertex[2], (*it2)->vertex[0]); - (*it2)->removed = true; - } - // inside edges are twice in the edge list, because it was added by 2 triangles. - assert(!horizon.empty()); - std::sort(horizon.begin(), horizon.end()); - size_t end = horizon.size(); - size_t first = 0; - size_t last = 0; - size_t result = 0; - // Removes edges, which are 2+ times in the sorted edge list. - while (++first != end) { - if (!(horizon[result] == horizon[first])) { - if (!(horizon[last] == horizon[first])) { - size_t dist = first - last; - if (dist == 1) { - horizon[result++] = horizon[last]; - } - last = first; - } - } - } - if (first - last == 1) { - horizon[result++] = horizon[last]; - } - horizon.resize(result); -} - -void LodOutsideMarker::fillHorizon(CHEdgeList& horizon, CHVertex* target) -{ - CHTriangle tri; - tri.vertex[2] = target; - tri.removed = false; - CHEdgeList::iterator it = horizon.begin(); - CHEdgeList::iterator itEnd = horizon.end(); - for (;it != itEnd; it++) { - tri.vertex[0] = it->first; - tri.vertex[1] = it->second; - tri.computeNormal(); - if (isVisible(&tri, mCentroid)) { - std::swap(tri.vertex[0], tri.vertex[1]); - tri.computeNormal(); - } - mHull.push_back(tri); - } -} - -bool LodOutsideMarker::isVisible(CHTriangle* t, Vector3& v) -{ - // We don't need epsilon here, because we assume, that the centroid is not on the triangle. - return t->normal.dotProduct(t->vertex[0]->position) < t->normal.dotProduct(v); -} - -void LodOutsideMarker::cleanHull() -{ - // cleanHull will remove triangles, which are marked as "removed" - // For fast performance, it will swap last item into the place of removed items. - size_t end = mHull.size() - 1; - size_t start = 0; - while (start <= end) { - if (mHull[start].removed) { - // Replace removed item with last item - mHull[start].removed = mHull[end].removed; - mHull[start].vertex[0] = mHull[end].vertex[0]; - mHull[start].vertex[1] = mHull[end].vertex[1]; - mHull[start].vertex[2] = mHull[end].vertex[2]; - mHull[start].normal = mHull[end].normal; - end--; - } else { - start++; - } - } - end++; - mHull.resize(end); -} - -Ogre::MeshPtr LodOutsideMarker::createConvexHullMesh(const String& meshName, const String& resourceGroupName) -{ - // Based on the wiki sample: http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Generating+A+Mesh - - // Resource with given name should not exist! - assert(MeshManager::getSingleton().getByName(meshName).isNull()); - - generateHull(); // calculate mHull triangles. - - // Convex hull can't be empty! - assert(!mHull.empty()); - - MeshPtr mesh = MeshManager::getSingleton().createManual(meshName, resourceGroupName, NULL); - SubMesh* subMesh = mesh->createSubMesh(); - - vector::type vertexBuffer; - vector::type indexBuffer; - // 3 position/triangle * 3 Real/position - vertexBuffer.reserve(mHull.size() * 9); - // 3 index / triangle - indexBuffer.reserve(mHull.size() * 3); - int id=0; - // min & max position - Vector3 minBounds(std::numeric_limits::max(), std::numeric_limits::max(), std::numeric_limits::max()); - Vector3 maxBounds(std::numeric_limits::min(), std::numeric_limits::min(), std::numeric_limits::min()); - - for (size_t i = 0; i < mHull.size(); i++) { - assert(!mHull[i].removed); - for(size_t n = 0; n < 3; n++){ - indexBuffer.push_back(id++); - vertexBuffer.push_back(mHull[i].vertex[n]->position.x); - vertexBuffer.push_back(mHull[i].vertex[n]->position.y); - vertexBuffer.push_back(mHull[i].vertex[n]->position.z); - minBounds.x = std::min(minBounds.x, mHull[i].vertex[n]->position.x); - minBounds.y = std::min(minBounds.y, mHull[i].vertex[n]->position.y); - minBounds.z = std::min(minBounds.z, mHull[i].vertex[n]->position.z); - maxBounds.x = std::max(maxBounds.x, mHull[i].vertex[n]->position.x); - maxBounds.y = std::max(maxBounds.y, mHull[i].vertex[n]->position.y); - maxBounds.z = std::max(maxBounds.z, mHull[i].vertex[n]->position.z); - } - } - - /// Create vertex data structure for 8 vertices shared between submeshes - mesh->sharedVertexData = new VertexData(); - mesh->sharedVertexData->vertexCount = mHull.size() * 3; - - /// Create declaration (memory format) of vertex data - VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; - size_t offset = 0; - // 1st buffer - decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); - offset += VertexElement::getTypeSize(VET_FLOAT3); - - /// Allocate vertex buffer of the requested number of vertices (vertexCount) - /// and bytes per vertex (offset) - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - offset, mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - /// Upload the vertex data to the card - vbuf->writeData(0, vbuf->getSizeInBytes(), &vertexBuffer[0], true); - - /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer - VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; - bind->setBinding(0, vbuf); - - /// Allocate index buffer of the requested number of vertices (ibufCount) - HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). - createIndexBuffer( - HardwareIndexBuffer::IT_16BIT, - indexBuffer.size(), - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - /// Upload the index data to the card - ibuf->writeData(0, ibuf->getSizeInBytes(), &indexBuffer[0], true); - - /// Set parameters of the submesh - subMesh->useSharedVertices = true; - subMesh->indexData->indexBuffer = ibuf; - subMesh->indexData->indexCount = indexBuffer.size(); - subMesh->indexData->indexStart = 0; - - /// Set bounding information (for culling) - mesh->_setBounds(AxisAlignedBox(minBounds, maxBounds)); - mesh->_setBoundingSphereRadius(maxBounds.distance(minBounds) / 2.0f); - - /// Set material to transparent blue - subMesh->setMaterialName("Examples/TransparentBlue50"); - - /// Notify -Mesh object that it has been loaded - mesh->load(); - - return mesh; -} - -template -void LodOutsideMarker::addHullTriangleVertices(std::vector& stack, T tri) -{ - OutsideData* v0 = getOutsideData(tri->vertex[0]); - OutsideData* v1 = getOutsideData(tri->vertex[1]); - OutsideData* v2 = getOutsideData(tri->vertex[2]); - - if (!v0->isOuterWallVertexInPass) { - v0->isOuterWallVertexInPass = true; - v0->isOuterWallVertex = true; - stack.push_back(tri->vertex[0]); - } - if (!v1->isOuterWallVertexInPass) { - v1->isOuterWallVertexInPass = true; - v1->isOuterWallVertex = true; - stack.push_back(tri->vertex[1]); - } - - if (!v2->isOuterWallVertexInPass) { - v2->isOuterWallVertexInPass = true; - v2->isOuterWallVertex = true; - stack.push_back(tri->vertex[2]); - } -} - -void LodOutsideMarker::markVertices() -{ - OutsideDataList::iterator v, vEnd; - v = mOutsideData.begin(); - vEnd = mOutsideData.end(); - for (;v != vEnd; v++) { - v->isOuterWallVertex = false; - } - std::vector stack; - CHTriangleList::iterator tri, triEnd; - tri = mHull.begin(); - triEnd = mHull.end(); - for (; tri != triEnd; tri++) { - stack.clear(); - v = mOutsideData.begin(); - vEnd = mOutsideData.end(); - for (;v != vEnd; v++) { - v->isOuterWallVertexInPass = false; - } - addHullTriangleVertices(stack, &*tri); - while (!stack.empty()) { - CHVertex* vert = stack.back(); - stack.pop_back(); - LodData::VTriangles::iterator it, itEnd; - it = vert->triangles.begin(); - itEnd = vert->triangles.end(); - for (; it != itEnd; it++) { - if (tri->normal.dotProduct((*it)->normal) > mWalkAngle) { - addHullTriangleVertices(stack, *it); - } - } - } - } -} - -void LodOutsideMarker::CHTriangle::computeNormal() -{ - Vector3 e1 = vertex[1]->position - vertex[0]->position; - Vector3 e2 = vertex[2]->position - vertex[1]->position; - - normal = e1.crossProduct(e2); - normal.normalise(); -} - -} +/* +----------------------------------------------------------------------------- +This source file is part of OGRE + (Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org/ + +Copyright (c) 2000-2014 Torus Knot Software Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ +#include "OgreLodOutsideMarker.h" +#include "OgreHardwareBufferManager.h" +#include "OgreMeshManager.h" +#include "OgreMesh.h" +#include "OgreSubMesh.h" + +namespace Ogre +{ + +LodOutsideMarker::LodOutsideMarker(LodData::VertexList & vertexList, Real boundingSphereRadius, Real walkAngle) : + mEpsilon(boundingSphereRadius * std::numeric_limits::epsilon() * (Real)4.0), // How much floating point math error you have for equal values. This may depend on compiler flags. + mVertexListOrig(vertexList), + mWalkAngle(walkAngle) +{ + assert(!vertexList.empty()); + assert(mWalkAngle >= -1.0001f && mWalkAngle <= 1.0001f); // dot product range + assert(boundingSphereRadius > 0.0f); // invalid meshes are having a bounding sphere radius of 0.0! +} + +void LodOutsideMarker::markOutside() +{ + generateHull(); + markVertices(); +} + +void LodOutsideMarker::generateHull() +{ + initHull(); + { + for (size_t i = 0; i < mHull.size(); i++) { + if (!mHull[i].removed) { + CHVertex* furthestVertex = getFurthestVertex(&mHull[i]); + if (!furthestVertex) { + continue; + } + addVertex(furthestVertex); + } + } + } + cleanHull(); +} + +void LodOutsideMarker::initHull() +{ + mHull.clear(); + mHull.reserve(mVertexListOrig.size()); + mOutsideData.clear(); + OutsideDataList::iterator itOut, itOutEnd; + mOutsideData.resize(mVertexListOrig.size()); + itOut = mOutsideData.begin(); + itOutEnd = mOutsideData.end(); + for (; itOut != itOutEnd; itOut++) { + // reset output variables + itOut->isOuterWallVertex = false; + itOut->isInsideHull = false; + } + // We need to find 4 vertices, which are on the convex hull to start the algorithm. + CHVertex* vertex[4] = { NULL, NULL, NULL, NULL }; + + { + // Get 1. vertex: minimum y vertex + Real miny = std::numeric_limits::max(); + LodData::VertexList::iterator v, vEnd; + v = mVertexListOrig.begin(); + vEnd = mVertexListOrig.end(); + for (; v != vEnd; v++) { + Vector3& pos = v->position; + if (pos.y < miny) { + miny = pos.y; + vertex[0] = &*v; + } + } + assert(vertex[0]); // Vertex not found! + } + + { + // Get 2. vertex: furthest from 1. vertex + Real maxdist = 0.0; + LodData::VertexList::iterator v, vEnd; + v = mVertexListOrig.begin(); + vEnd = mVertexListOrig.end(); + for (; v != vEnd; v++) { + Real dist = vertex[0]->position.squaredDistance(v->position); + if (dist > maxdist) { + maxdist = dist; + vertex[1] = &*v; + } + } + assert(vertex[1]); // Vertex not found! + } + + { + // Get 3. vertex: furthest from 1. vertex and 2. vertex + Real maxdist = 0.0; + LodData::VertexList::iterator v, vEnd; + v = mVertexListOrig.begin(); + vEnd = mVertexListOrig.end(); + for (; v != vEnd; v++) { + Real dist = getPointToLineSqraredDistance(vertex[0], vertex[1], &*v); + if (dist > maxdist) { + maxdist = dist; + vertex[2] = &*v; + } + } + assert(vertex[2]); // Vertex not found! + } + + { + // Get 4. vertex: furthest from 1-2-3 triangle + Real maxdist = 0.0f; + Plane plane(vertex[0]->position, vertex[1]->position, vertex[2]->position); + plane.normalise(); + LodData::VertexList::iterator v, vEnd; + v = mVertexListOrig.begin(); + vEnd = mVertexListOrig.end(); + for (; v != vEnd; v++) { + Real dist = std::abs(plane.getDistance(v->position)); + if (dist > maxdist) { + maxdist = dist; + vertex[3] = &*v; + } + } + assert(vertex[3]); // Vertex not found! + } + + // Volume should be bigger than 0, so that we can guarantee that the centroid point is inside the hull + assert(getTetrahedronVolume(vertex[0], vertex[1], vertex[2], vertex[3]) > mEpsilon); + // Centroid = (a + b + c + d) / 4 + mCentroid = vertex[0]->position + vertex[1]->position + vertex[2]->position + vertex[3]->position; + mCentroid /= 4.0f; + + // Mark vertices, so that they will not be processed again. + getOutsideData(vertex[0])->isInsideHull = true; + getOutsideData(vertex[1])->isInsideHull = true; + getOutsideData(vertex[2])->isInsideHull = true; + getOutsideData(vertex[3])->isInsideHull = true; + + // Create the triangles + createTriangle(vertex[0], vertex[1], vertex[2]); + createTriangle(vertex[0], vertex[1], vertex[3]); + createTriangle(vertex[0], vertex[2], vertex[3]); + createTriangle(vertex[1], vertex[2], vertex[3]); +} + +void LodOutsideMarker::createTriangle( CHVertex* v1, CHVertex* v2, CHVertex* v3 ) +{ + CHTriangle tri; + tri.removed = false; + tri.vertex[0] = v1; + tri.vertex[1] = v2; + tri.vertex[2] = v3; + tri.computeNormal(); + if (isVisible(&tri, mCentroid)) { + std::swap(tri.vertex[0], tri.vertex[1]); + tri.computeNormal(); + } + mHull.push_back(tri); +} + +Real LodOutsideMarker::getPointToLineSqraredDistance(CHVertex* x1, CHVertex* x2, CHVertex* p) +{ + Real up = ((x2->position - x1->position).crossProduct(x1->position - p->position)).squaredLength(); + Real down = (x2->position - x1->position).squaredLength(); + return up / down; +} + +Real LodOutsideMarker::getTetrahedronVolume(CHVertex* a, CHVertex* b, CHVertex* c, CHVertex* d) +{ + // V = |(a-d)*[(b-d)x(c-d)]| / 6 + return std::abs((a->position - d->position).dotProduct((b->position - d->position).crossProduct(c->position - d->position))) / 6.0f; +} + +LodOutsideMarker::CHVertex* LodOutsideMarker::getFurthestVertex(CHTriangle* tri) +{ + // Find the furthest vertex from triangle plane towards the facing direction. + CHVertex* furthestVertex = NULL; + Real furthestDistance = 0; + Plane plane(tri->normal, -tri->normal.dotProduct(tri->vertex[0]->position)); + plane.normalise(); + LodData::VertexList::iterator v, vEnd; + v = mVertexListOrig.begin(); + vEnd = mVertexListOrig.end(); + for (; v != vEnd; v++) { + if (getOutsideData(&*v)->isInsideHull) { + continue; + } + Real dist = plane.getDistance(v->position); + if (dist > furthestDistance) { + furthestDistance = dist; + furthestVertex = &*v; + } + } + return furthestVertex; +} + +size_t LodOutsideMarker::addVertex( CHVertex* vertex ) +{ + getOutsideData(vertex)->isInsideHull = true; + // We use class members for triangles and edges only to prevent allocation. + mVisibleTriangles.clear(); + mEdges.clear(); + getVisibleTriangles(vertex, mVisibleTriangles); // get the hull triangles, which are facing the vertex. + if (mVisibleTriangles.empty()) { + return 0; // It's inside the Hull. + } + getHorizon(mVisibleTriangles, mEdges); // Returns the edges of a circle around the triangles. Also removes the triangles + fillHorizon(mEdges, vertex); // Creates triangles from the edges towards the vertex. + return mEdges.size(); +} + +void LodOutsideMarker::getVisibleTriangles( const CHVertex* target, CHTrianglePList& visibleTriangles ) +{ + + CHTriangleList::iterator it = mHull.begin(); + CHTriangleList::iterator itEnd = mHull.end(); + for (; it != itEnd; it++) { + if (it->removed) { + continue; + } + Real dot1 = it->normal.dotProduct(it->vertex[0]->position); + Real dot2 = it->normal.dotProduct(target->position); + if(std::abs(dot2 - dot1) <= mEpsilon) { + //Special case: The vertex is on the plane of the triangle + //mVisibleTriangles.push_back(&*it); + if (isInsideTriangle(target->position, *it)) { + // Vertex is inside of a convex hull triangle. + mVisibleTriangles.clear(); + return; + } else { + // If the vertex is outside, then we should add it to the hull. + visibleTriangles.push_back(&*it); + } + } else if (dot1 < dot2) { + visibleTriangles.push_back(&*it); + } + } +} + +void LodOutsideMarker::addEdge(CHEdgeList& edges, CHVertex* a, CHVertex* b) +{ + // We need undirectional edges, so we sort the vertices by their pointer like integers. + // This is needed, because we want to remove edges which were inside multiple triangles, + // because those are not on the horizon. + if (a <= b) { + edges.push_back(CHEdgeList::value_type(a, b)); + } else { + edges.push_back(CHEdgeList::value_type(b, a)); + } +} + +bool LodOutsideMarker::isInsideTriangle(const Vector3& ptarget, const CHTriangle& tri){ + + // The idea is that if all angle is smaller to that point, than it should be inside. + // NOTE: We assume that the vertex is on the triangle plane! + + const Vector3& p0 = tri.vertex[0]->position; + const Vector3& p1 = tri.vertex[1]->position; + const Vector3& p2 = tri.vertex[2]->position; + const Vector3& n = tri.normal; + + bool b0, b1, b2; + + // It should not contain malformed triangles! + assert(!isSamePosition(p0, p1) && !isSamePosition(p1, p2) && !isSamePosition(p2, p0)); + + { + Real d0 = pointToLineDir(ptarget, p0, p1, p2, n); + if (std::abs(d0) <= mEpsilon){ + //Vertex is on the edge, so we need to compare length. + return isInsideLine(ptarget, p0, p1); + } + b0 = d0 < 0.0f; + } + + { + Real d1 = pointToLineDir(ptarget, p1, p2, p0, n); + if (std::abs(d1) <= mEpsilon){ + //Vertex is on the edge, so we need to compare length. + return isInsideLine(ptarget, p1, p2); + } + b1 = d1 < 0.0f; + } + + if (b0 != b1) { + return false; + } + + { + Real d2 = pointToLineDir(ptarget, p2, p0, p1, n); + if (std::abs(d2) <= mEpsilon){ + //Vertex is on the edge, so we need to compare length. + return isInsideLine(ptarget, p2, p0); + } + b2 = d2 < 0.0f; + } + + return (b1 == b2); +} + +bool LodOutsideMarker::isSamePosition( const Vector3& p0, const Vector3& p1 ) +{ + return (std::abs(p0.x - p1.x) <= mEpsilon && std::abs(p0.y - p1.y) <= mEpsilon && std::abs(p0.z - p1.z) <= mEpsilon); +} + +Real LodOutsideMarker::pointToLineDir(const Vector3& ptarget, const Vector3& p0, const Vector3& p1, const Vector3& p2, const Vector3& n) +{ + return n.crossProduct(p1 - p0).dotProduct(ptarget - p0); +} + +bool LodOutsideMarker::isInsideLine( const Vector3& ptarget, const Vector3& p0, const Vector3& p1 ) +{ + // This function returns whether ptarget is between p0 and p1. + // It is outside if: + // -the dir vector is in the opposite direction + // -the length is smaller. + // -ptarget is not p0 or p1 + // NOTE: We assume that the 3 points are on the same line! + + Vector3 v1 = p1 - p0; + Vector3 v2 = ptarget - p0; + Real len1 = v1.squaredLength(); + Real len2 = v2.squaredLength(); + Real dot = v1.dotProduct(v2); + return isSamePosition(ptarget, p1) || ( + dot > 0.0 // Same direction + && len1 > len2); // Shorter +} + +void LodOutsideMarker::getHorizon( const CHTrianglePList& tri, CHEdgeList& horizon) +{ + // Create edge list and remove triangles + CHTrianglePList::const_iterator it2 = tri.begin(); + CHTrianglePList::const_iterator it2End = tri.end(); + for (; it2 != it2End; it2++) { + addEdge(horizon, (*it2)->vertex[0], (*it2)->vertex[1]); + addEdge(horizon, (*it2)->vertex[1], (*it2)->vertex[2]); + addEdge(horizon, (*it2)->vertex[2], (*it2)->vertex[0]); + (*it2)->removed = true; + } + // inside edges are twice in the edge list, because it was added by 2 triangles. + assert(!horizon.empty()); + std::sort(horizon.begin(), horizon.end()); + size_t end = horizon.size(); + size_t first = 0; + size_t last = 0; + size_t result = 0; + // Removes edges, which are 2+ times in the sorted edge list. + while (++first != end) { + if (!(horizon[result] == horizon[first])) { + if (!(horizon[last] == horizon[first])) { + size_t dist = first - last; + if (dist == 1) { + horizon[result++] = horizon[last]; + } + last = first; + } + } + } + if (first - last == 1) { + horizon[result++] = horizon[last]; + } + horizon.resize(result); +} + +void LodOutsideMarker::fillHorizon(CHEdgeList& horizon, CHVertex* target) +{ + CHTriangle tri; + tri.vertex[2] = target; + tri.removed = false; + CHEdgeList::iterator it = horizon.begin(); + CHEdgeList::iterator itEnd = horizon.end(); + for (;it != itEnd; it++) { + tri.vertex[0] = it->first; + tri.vertex[1] = it->second; + tri.computeNormal(); + if (isVisible(&tri, mCentroid)) { + std::swap(tri.vertex[0], tri.vertex[1]); + tri.computeNormal(); + } + mHull.push_back(tri); + } +} + +bool LodOutsideMarker::isVisible(CHTriangle* t, Vector3& v) +{ + // We don't need epsilon here, because we assume, that the centroid is not on the triangle. + return t->normal.dotProduct(t->vertex[0]->position) < t->normal.dotProduct(v); +} + +void LodOutsideMarker::cleanHull() +{ + // cleanHull will remove triangles, which are marked as "removed" + // For fast performance, it will swap last item into the place of removed items. + size_t end = mHull.size() - 1; + size_t start = 0; + while (start <= end) { + if (mHull[start].removed) { + // Replace removed item with last item + mHull[start].removed = mHull[end].removed; + mHull[start].vertex[0] = mHull[end].vertex[0]; + mHull[start].vertex[1] = mHull[end].vertex[1]; + mHull[start].vertex[2] = mHull[end].vertex[2]; + mHull[start].normal = mHull[end].normal; + end--; + } else { + start++; + } + } + end++; + mHull.resize(end); +} + +Ogre::MeshPtr LodOutsideMarker::createConvexHullMesh(const String& meshName, const String& resourceGroupName) +{ + // Based on the wiki sample: http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Generating+A+Mesh + + // Resource with given name should not exist! + assert(MeshManager::getSingleton().getByName(meshName).isNull()); + + generateHull(); // calculate mHull triangles. + + // Convex hull can't be empty! + assert(!mHull.empty()); + + MeshPtr mesh = MeshManager::getSingleton().createManual(meshName, resourceGroupName, NULL); + SubMesh* subMesh = mesh->createSubMesh(); + + vector::type vertexBuffer; + vector::type indexBuffer; + // 3 position/triangle * 3 Real/position + vertexBuffer.reserve(mHull.size() * 9); + // 3 index / triangle + indexBuffer.reserve(mHull.size() * 3); + int id=0; + // min & max position + Vector3 minBounds(std::numeric_limits::max(), std::numeric_limits::max(), std::numeric_limits::max()); + Vector3 maxBounds(std::numeric_limits::min(), std::numeric_limits::min(), std::numeric_limits::min()); + + for (size_t i = 0; i < mHull.size(); i++) { + assert(!mHull[i].removed); + for(size_t n = 0; n < 3; n++){ + indexBuffer.push_back(id++); + vertexBuffer.push_back(mHull[i].vertex[n]->position.x); + vertexBuffer.push_back(mHull[i].vertex[n]->position.y); + vertexBuffer.push_back(mHull[i].vertex[n]->position.z); + minBounds.x = std::min(minBounds.x, mHull[i].vertex[n]->position.x); + minBounds.y = std::min(minBounds.y, mHull[i].vertex[n]->position.y); + minBounds.z = std::min(minBounds.z, mHull[i].vertex[n]->position.z); + maxBounds.x = std::max(maxBounds.x, mHull[i].vertex[n]->position.x); + maxBounds.y = std::max(maxBounds.y, mHull[i].vertex[n]->position.y); + maxBounds.z = std::max(maxBounds.z, mHull[i].vertex[n]->position.z); + } + } + + /// Create vertex data structure for 8 vertices shared between submeshes + mesh->sharedVertexData = new VertexData(); + mesh->sharedVertexData->vertexCount = mHull.size() * 3; + + /// Create declaration (memory format) of vertex data + VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; + size_t offset = 0; + // 1st buffer + decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); + offset += VertexElement::getTypeSize(VET_FLOAT3); + + /// Allocate vertex buffer of the requested number of vertices (vertexCount) + /// and bytes per vertex (offset) + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + offset, mesh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); + /// Upload the vertex data to the card + vbuf->writeData(0, vbuf->getSizeInBytes(), &vertexBuffer[0], true); + + /// Set vertex buffer binding so buffer 0 is bound to our vertex buffer + VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; + bind->setBinding(0, vbuf); + + /// Allocate index buffer of the requested number of vertices (ibufCount) + HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). + createIndexBuffer( + HardwareIndexBuffer::IT_16BIT, + indexBuffer.size(), + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + + /// Upload the index data to the card + ibuf->writeData(0, ibuf->getSizeInBytes(), &indexBuffer[0], true); + + /// Set parameters of the submesh + subMesh->useSharedVertices = true; + subMesh->indexData->indexBuffer = ibuf; + subMesh->indexData->indexCount = indexBuffer.size(); + subMesh->indexData->indexStart = 0; + + /// Set bounding information (for culling) + mesh->_setBounds(AxisAlignedBox(minBounds, maxBounds)); + mesh->_setBoundingSphereRadius(maxBounds.distance(minBounds) / 2.0f); + + /// Set material to transparent blue + subMesh->setMaterialName("Examples/TransparentBlue50"); + + /// Notify -Mesh object that it has been loaded + mesh->load(); + + return mesh; +} + +template +void LodOutsideMarker::addHullTriangleVertices(std::vector& stack, T tri) +{ + OutsideData* v0 = getOutsideData(tri->vertex[0]); + OutsideData* v1 = getOutsideData(tri->vertex[1]); + OutsideData* v2 = getOutsideData(tri->vertex[2]); + + if (!v0->isOuterWallVertexInPass) { + v0->isOuterWallVertexInPass = true; + v0->isOuterWallVertex = true; + stack.push_back(tri->vertex[0]); + } + if (!v1->isOuterWallVertexInPass) { + v1->isOuterWallVertexInPass = true; + v1->isOuterWallVertex = true; + stack.push_back(tri->vertex[1]); + } + + if (!v2->isOuterWallVertexInPass) { + v2->isOuterWallVertexInPass = true; + v2->isOuterWallVertex = true; + stack.push_back(tri->vertex[2]); + } +} + +void LodOutsideMarker::markVertices() +{ + OutsideDataList::iterator v, vEnd; + v = mOutsideData.begin(); + vEnd = mOutsideData.end(); + for (;v != vEnd; v++) { + v->isOuterWallVertex = false; + } + std::vector stack; + CHTriangleList::iterator tri, triEnd; + tri = mHull.begin(); + triEnd = mHull.end(); + for (; tri != triEnd; tri++) { + stack.clear(); + v = mOutsideData.begin(); + vEnd = mOutsideData.end(); + for (;v != vEnd; v++) { + v->isOuterWallVertexInPass = false; + } + addHullTriangleVertices(stack, &*tri); + while (!stack.empty()) { + CHVertex* vert = stack.back(); + stack.pop_back(); + LodData::VTriangles::iterator it, itEnd; + it = vert->triangles.begin(); + itEnd = vert->triangles.end(); + for (; it != itEnd; it++) { + if (tri->normal.dotProduct((*it)->normal) > mWalkAngle) { + addHullTriangleVertices(stack, *it); + } + } + } + } +} + +void LodOutsideMarker::CHTriangle::computeNormal() +{ + Vector3 e1 = vertex[1]->position - vertex[0]->position; + Vector3 e2 = vertex[2]->position - vertex[1]->position; + + normal = e1.crossProduct(e2); + normal.normalise(); +} + +} diff --git a/Components/MeshLodGenerator/src/OgreLodWorkQueueInjector.cpp b/Components/MeshLodGenerator/src/OgreLodWorkQueueInjector.cpp index 400b35f8e59..3538f5b54fe 100644 --- a/Components/MeshLodGenerator/src/OgreLodWorkQueueInjector.cpp +++ b/Components/MeshLodGenerator/src/OgreLodWorkQueueInjector.cpp @@ -34,55 +34,55 @@ namespace Ogre { - template<> LodWorkQueueInjector* Singleton::msSingleton = 0; - LodWorkQueueInjector* LodWorkQueueInjector::getSingletonPtr(void) - { - return msSingleton; - } - LodWorkQueueInjector& LodWorkQueueInjector::getSingleton(void) - { - assert( msSingleton ); return ( *msSingleton ); - } + template<> LodWorkQueueInjector* Singleton::msSingleton = 0; + LodWorkQueueInjector* LodWorkQueueInjector::getSingletonPtr(void) + { + return msSingleton; + } + LodWorkQueueInjector& LodWorkQueueInjector::getSingleton(void) + { + assert( msSingleton ); return ( *msSingleton ); + } - LodWorkQueueInjector::LodWorkQueueInjector() : - mInjectorListener(0) - { - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - unsigned short workQueueChannel = wq->getChannel("PMGen"); - wq->addResponseHandler(workQueueChannel, this); - } + LodWorkQueueInjector::LodWorkQueueInjector() : + mInjectorListener(0) + { + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + unsigned short workQueueChannel = wq->getChannel("PMGen"); + wq->addResponseHandler(workQueueChannel, this); + } - LodWorkQueueInjector::~LodWorkQueueInjector() - { - Root* root = Root::getSingletonPtr(); - if (root) { - WorkQueue* wq = root->getWorkQueue(); - if (wq) { - unsigned short workQueueChannel = wq->getChannel("PMGen"); - wq->removeResponseHandler(workQueueChannel, this); - } - } - } + LodWorkQueueInjector::~LodWorkQueueInjector() + { + Root* root = Root::getSingletonPtr(); + if (root) { + WorkQueue* wq = root->getWorkQueue(); + if (wq) { + unsigned short workQueueChannel = wq->getChannel("PMGen"); + wq->removeResponseHandler(workQueueChannel, this); + } + } + } - void LodWorkQueueInjector::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - LodWorkQueueRequest* request = any_cast(res->getData()); + void LodWorkQueueInjector::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + LodWorkQueueRequest* request = any_cast(res->getData()); - if(mInjectorListener){ - if(!mInjectorListener->shouldInject(request)) { - return; - } - } + if(mInjectorListener){ + if(!mInjectorListener->shouldInject(request)) { + return; + } + } - request->output->inject(); - MeshLodGenerator::_configureMeshLodUsage(request->config); - //lodConfig.mesh->buildEdgeList(); + request->output->inject(); + MeshLodGenerator::_configureMeshLodUsage(request->config); + //lodConfig.mesh->buildEdgeList(); - if(mInjectorListener){ - mInjectorListener->injectionCompleted(request); - } - } + if(mInjectorListener){ + mInjectorListener->injectionCompleted(request); + } + } - + } diff --git a/Components/MeshLodGenerator/src/OgreLodWorkQueueWorker.cpp b/Components/MeshLodGenerator/src/OgreLodWorkQueueWorker.cpp index d84ee422199..bbe47ddc7af 100644 --- a/Components/MeshLodGenerator/src/OgreLodWorkQueueWorker.cpp +++ b/Components/MeshLodGenerator/src/OgreLodWorkQueueWorker.cpp @@ -1,95 +1,95 @@ -/* - * ----------------------------------------------------------------------------- - * This source file is part of OGRE - * (Object-oriented Graphics Rendering Engine) - * For the latest info, see http://www.ogre3d.org/ - * - * Copyright (c) 2000-2014 Torus Knot Software Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ----------------------------------------------------------------------------- - */ - -#include "OgreLodWorkQueueWorker.h" -#include "OgreMeshLodGenerator.h" -#include "OgreLodWorkQueueRequest.h" -#include "OgreRoot.h" - -namespace Ogre -{ - template<> LodWorkQueueWorker* Singleton::msSingleton = 0; - LodWorkQueueWorker* LodWorkQueueWorker::getSingletonPtr(void) - { - return msSingleton; - } - LodWorkQueueWorker& LodWorkQueueWorker::getSingleton(void) - { - assert( msSingleton ); return ( *msSingleton ); - } - - LodWorkQueueWorker::LodWorkQueueWorker() - { - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - mChannelID = wq->getChannel("PMGen"); - wq->addRequestHandler(mChannelID, this); - } - - void LodWorkQueueWorker::addRequestToQueue( LodWorkQueueRequest* request ) - { - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - wq->addRequest(mChannelID, 0, Any(request),0,false,true); - } - - void LodWorkQueueWorker::addRequestToQueue( LodConfig& lodConfig, LodCollapseCostPtr& cost, LodDataPtr& data, LodInputProviderPtr& input, LodOutputProviderPtr& output, LodCollapserPtr& collapser ) - { - LodWorkQueueRequest* req = new LodWorkQueueRequest(); - req->config = lodConfig; - req->cost = cost; - req->data = data; - req->input = input; - req->output = output; - req->collapser = collapser; - addRequestToQueue(req); - } - - LodWorkQueueWorker::~LodWorkQueueWorker() - { - Root* root = Root::getSingletonPtr(); - if (root) { - WorkQueue* wq = root->getWorkQueue(); - if (wq) { - wq->removeRequestHandler(mChannelID, this); - } - } - } - - void LodWorkQueueWorker::clearPendingLodRequests() - { - Ogre::WorkQueue* wq = Root::getSingleton().getWorkQueue(); - wq->abortPendingRequestsByChannel(mChannelID); - } - - WorkQueue::Response* LodWorkQueueWorker::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - // Called on worker thread by WorkQueue. - LodWorkQueueRequest* request = any_cast(req->getData()); - MeshLodGenerator::getSingleton()._process(request->config, request->cost.get(), request->data.get(), request->input.get(), request->output.get(), request->collapser.get()); - return OGRE_NEW WorkQueue::Response(req, true, req->getData()); - } -} +/* + * ----------------------------------------------------------------------------- + * This source file is part of OGRE + * (Object-oriented Graphics Rendering Engine) + * For the latest info, see http://www.ogre3d.org/ + * + * Copyright (c) 2000-2014 Torus Knot Software Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ----------------------------------------------------------------------------- + */ + +#include "OgreLodWorkQueueWorker.h" +#include "OgreMeshLodGenerator.h" +#include "OgreLodWorkQueueRequest.h" +#include "OgreRoot.h" + +namespace Ogre +{ + template<> LodWorkQueueWorker* Singleton::msSingleton = 0; + LodWorkQueueWorker* LodWorkQueueWorker::getSingletonPtr(void) + { + return msSingleton; + } + LodWorkQueueWorker& LodWorkQueueWorker::getSingleton(void) + { + assert( msSingleton ); return ( *msSingleton ); + } + + LodWorkQueueWorker::LodWorkQueueWorker() + { + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + mChannelID = wq->getChannel("PMGen"); + wq->addRequestHandler(mChannelID, this); + } + + void LodWorkQueueWorker::addRequestToQueue( LodWorkQueueRequest* request ) + { + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + wq->addRequest(mChannelID, 0, Any(request),0,false,true); + } + + void LodWorkQueueWorker::addRequestToQueue( LodConfig& lodConfig, LodCollapseCostPtr& cost, LodDataPtr& data, LodInputProviderPtr& input, LodOutputProviderPtr& output, LodCollapserPtr& collapser ) + { + LodWorkQueueRequest* req = new LodWorkQueueRequest(); + req->config = lodConfig; + req->cost = cost; + req->data = data; + req->input = input; + req->output = output; + req->collapser = collapser; + addRequestToQueue(req); + } + + LodWorkQueueWorker::~LodWorkQueueWorker() + { + Root* root = Root::getSingletonPtr(); + if (root) { + WorkQueue* wq = root->getWorkQueue(); + if (wq) { + wq->removeRequestHandler(mChannelID, this); + } + } + } + + void LodWorkQueueWorker::clearPendingLodRequests() + { + Ogre::WorkQueue* wq = Root::getSingleton().getWorkQueue(); + wq->abortPendingRequestsByChannel(mChannelID); + } + + WorkQueue::Response* LodWorkQueueWorker::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + // Called on worker thread by WorkQueue. + LodWorkQueueRequest* request = any_cast(req->getData()); + MeshLodGenerator::getSingleton()._process(request->config, request->cost.get(), request->data.get(), request->input.get(), request->output.get(), request->collapser.get()); + return OGRE_NEW WorkQueue::Response(req, true, req->getData()); + } +} diff --git a/Components/MeshLodGenerator/src/OgreMeshLodGenerator.cpp b/Components/MeshLodGenerator/src/OgreMeshLodGenerator.cpp index 24c14978bbe..c0377b19769 100644 --- a/Components/MeshLodGenerator/src/OgreMeshLodGenerator.cpp +++ b/Components/MeshLodGenerator/src/OgreMeshLodGenerator.cpp @@ -1,330 +1,330 @@ -/* - * ----------------------------------------------------------------------------- - * This source file is part of OGRE - * (Object-oriented Graphics Rendering Engine) - * For the latest info, see http://www.ogre3d.org/ - * - * Copyright (c) 2000-2014 Torus Knot Software Ltd - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * ----------------------------------------------------------------------------- - */ - -#include "OgreMeshLodGenerator.h" -#include "OgrePixelCountLodStrategy.h" -#include "OgreLodWorkQueueWorker.h" -#include "OgreLodWorkQueueInjector.h" -#include "OgreLodInputProvider.h" -#include "OgreLodInputProviderMesh.h" -#include "OgreLodInputProviderBuffer.h" -#include "OgreLodOutputProvider.h" -#include "OgreLodOutputProviderMesh.h" -#include "OgreLodOutputProviderCompressedMesh.h" -#include "OgreLodOutputProviderBuffer.h" -#include "OgreLodOutputProviderCompressedBuffer.h" -#include "OgreLodCollapseCost.h" -#include "OgreLodCollapseCostCurvature.h" -#include "OgreLodCollapseCostProfiler.h" -#include "OgreLodCollapseCostOutside.h" -#include "OgreLodData.h" -#include "OgreLodCollapser.h" - - -namespace Ogre -{ - -template<> MeshLodGenerator* Singleton::msSingleton = 0; -MeshLodGenerator* MeshLodGenerator::getSingletonPtr() -{ - return msSingleton; -} -MeshLodGenerator& MeshLodGenerator::getSingleton() -{ - assert(msSingleton); - return (*msSingleton); -} -void MeshLodGenerator::getAutoconfig(MeshPtr& inMesh, LodConfig& outLodConfig) -{ - outLodConfig.mesh = inMesh; - outLodConfig.strategy = PixelCountLodStrategy::getSingletonPtr(); - LodLevel lodLevel; - lodLevel.reductionMethod = LodLevel::VRM_COLLAPSE_COST; - Real radius = inMesh->getBoundingSphereRadius(); - for(int i = 2; i < 6; i++) { - Real i4 = (Real) (i * i * i * i); - Real i5 = i4 * (Real) i; - // Distance = pixel count - // Constant: zoom of the Lod. This could be scaled based on resolution. - // Higher constant means first Lod is nearer to camera. Smaller constant means the first Lod is further away from camera. - // i4: The stretching. Normally you want to have more Lods in the near, then in far away. - // i4 means distance is divided by 16=(2*2*2*2), 81, 256, 625=(5*5*5*5). - // if 16 would be smaller, the first Lod would be nearer. if 625 would be bigger, the last Lod would be further awaay. - // if you increase 16 and decrease 625, first and Last Lod distance would be smaller. - lodLevel.distance = 3388608.f / i4; - - // reductionValue = collapse cost - // Radius: Edges are multiplied by the length, when calculating collapse cost. So as a base value we use radius, which should help in balancing collapse cost to any mesh size. - // The constant and i5 are playing together. 1/(1/100k*i5) - // You need to determine the quality of nearest Lod and the furthest away first. - // I have chosen 1/(1/100k*(2^5)) = 3125 for nearest Lod and 1/(1/100k*(5^5)) = 32 for nearest Lod. - // if you divide radius by a bigger number, it means smaller reduction. So radius/3125 is very small reduction for nearest Lod. - // if you divide radius by a smaller number, it means bigger reduction. So radius/32 means aggressive reduction for furthest away lod. - // current values: 3125, 411, 97, 32 - lodLevel.reductionValue = radius / 100000.f * i5; - outLodConfig.levels.push_back(lodLevel); - } -} - -void MeshLodGenerator::generateAutoconfiguredLodLevels(MeshPtr& mesh) -{ - LodConfig lodConfig; - getAutoconfig(mesh, lodConfig); - generateLodLevels(lodConfig); -} - -void MeshLodGenerator::_configureMeshLodUsage(const LodConfig& lodConfig) -{ - lodConfig.mesh->freeEdgeList(); - lodConfig.mesh->setLodStrategy(lodConfig.strategy); - MeshLodUsage usage; - size_t n = 0; - lodConfig.mesh->_setLodInfo(lodConfig.levels.size() + 1); // add Lod levels - for(size_t i = 0; i < lodConfig.levels.size(); i++) { - // Record usages. First Lod usage is the mesh itself. - - // Skip lods, which have the same amount of vertices. No buffer generated for them. - if(!lodConfig.levels[i].outSkipped) { - - usage.userValue = lodConfig.levels[i].distance; - usage.value = lodConfig.mesh->getLodStrategy()->transformUserValue(usage.userValue); - usage.edgeData = NULL; - usage.manualMesh.setNull(); - usage.manualName = lodConfig.levels[i].manualMeshName; - lodConfig.mesh->_setLodUsage(++n, usage); - } - } - // Remove skipped Lod levels - lodConfig.mesh->_setLodInfo(n + 1); -} - -MeshLodGenerator::MeshLodGenerator() : - mWQWorker(NULL), - mWQInjector(NULL) -{ - -} - -MeshLodGenerator::~MeshLodGenerator() -{ - delete mWQWorker; - delete mWQInjector; -} -void MeshLodGenerator::_resolveComponents(LodConfig& lodConfig, - LodCollapseCostPtr& cost, - LodDataPtr& data, - LodInputProviderPtr& input, - LodOutputProviderPtr& output, - LodCollapserPtr& collapser) -{ - if(cost.isNull()) { - cost = LodCollapseCostPtr(new LodCollapseCostCurvature); - if(lodConfig.advanced.outsideWeight != 0) { - cost = - LodCollapseCostPtr(new LodCollapseCostOutside(cost, lodConfig.advanced.outsideWeight, - lodConfig.advanced.outsideWalkAngle)); - } - if(!lodConfig.advanced.profile.empty()) { - cost = LodCollapseCostPtr(new LodCollapseCostProfiler(lodConfig.advanced.profile, cost)); - } - - } - if(data.isNull()) { - data = LodDataPtr(new LodData()); - } - if(collapser.isNull()) { - collapser = LodCollapserPtr(new LodCollapser()); - } - if(lodConfig.advanced.useBackgroundQueue) { - if(input.isNull()) { - input = LodInputProviderPtr(new LodInputProviderBuffer(lodConfig.mesh)); - } - if(output.isNull()) { - if(lodConfig.advanced.useCompression) { - output = LodOutputProviderPtr(new LodOutputProviderCompressedBuffer(lodConfig.mesh)); - } else { - output = LodOutputProviderPtr(new LodOutputProviderBuffer(lodConfig.mesh)); - } - } - } else { - if(input.isNull()) { - input = LodInputProviderPtr(new LodInputProviderMesh(lodConfig.mesh)); - } - if(output.isNull()) { - if(lodConfig.advanced.useCompression) { - output = LodOutputProviderPtr(new LodOutputProviderCompressedMesh(lodConfig.mesh)); - } else { - output = LodOutputProviderPtr(new LodOutputProviderMesh(lodConfig.mesh)); - } - } - } -} -void MeshLodGenerator::_process(LodConfig& lodConfig, - LodCollapseCost* cost, - LodData* data, - LodInputProvider* input, - LodOutputProvider* output, - LodCollapser* collapser) -{ - input->initData(data); - data->mUseVertexNormals = data->mUseVertexNormals && lodConfig.advanced.useVertexNormals; - cost->initCollapseCosts(data); - output->prepare(data); - computeLods(lodConfig, data, cost, output, collapser); - output->finalize(data); - if(!lodConfig.advanced.useBackgroundQueue) { - // This will be processed in LodWorkQueueInjector if we use background queue. - output->inject(); - _configureMeshLodUsage(lodConfig); - //lodConfig.mesh->buildEdgeList(); - } -} -void MeshLodGenerator::generateLodLevels(LodConfig& lodConfig, - LodCollapseCostPtr cost, - LodDataPtr data, - LodInputProviderPtr input, - LodOutputProviderPtr output, - LodCollapserPtr collapser) -{ - // If we don't have generated Lod levels, we can use _generateManualLodLevels. - bool hasGeneratedLevels = false; - for(size_t i = 0; i < lodConfig.levels.size(); i++) { - if(lodConfig.levels[i].manualMeshName.empty()) { - hasGeneratedLevels = true; - break; - } - } - if(hasGeneratedLevels || (LodWorkQueueInjector::getSingletonPtr() && LodWorkQueueInjector::getSingletonPtr()->getInjectorListener())) { - _resolveComponents(lodConfig, cost, data, input, output, collapser); - if(lodConfig.advanced.useBackgroundQueue) { - _initWorkQueue(); - LodWorkQueueWorker::getSingleton().addRequestToQueue(lodConfig, cost, data, input, output, collapser); - } else { - _process(lodConfig, cost.get(), data.get(), input.get(), output.get(), collapser.get()); - } - } else { - _generateManualLodLevels(lodConfig); - } -} - -void MeshLodGenerator::computeLods(LodConfig& lodConfig, - LodData* data, - LodCollapseCost* cost, - LodOutputProvider* output, - LodCollapser* collapser) -{ - int lodID = 0; - size_t lastBakeVertexCount = data->mVertexList.size(); - for(unsigned short curLod = 0; curLod < lodConfig.levels.size(); curLod++) { - if(!lodConfig.levels[curLod].manualMeshName.empty()) { - // Manual Lod level - lodConfig.levels[curLod].outSkipped = - (curLod != 0 && lodConfig.levels[curLod].manualMeshName == lodConfig.levels[curLod - 1].manualMeshName); - lodConfig.levels[curLod].outUniqueVertexCount = 0; - lastBakeVertexCount = -1; - if(!lodConfig.levels[curLod].outSkipped) { - output->bakeManualLodLevel(data, lodConfig.levels[curLod].manualMeshName, lodID++); - } - } else { - size_t vertexCountLimit; - Real collapseCostLimit; - calcLodVertexCount(lodConfig.levels[curLod], data->mVertexList.size(), vertexCountLimit, collapseCostLimit); - collapser->collapse(data, cost, output, static_cast(vertexCountLimit), collapseCostLimit); - size_t vertexCount = data->mCollapseCostHeap.size(); - lodConfig.levels[curLod].outUniqueVertexCount = vertexCount; - lodConfig.levels[curLod].outSkipped = (vertexCount == lastBakeVertexCount); - if(!lodConfig.levels[curLod].outSkipped) { - lastBakeVertexCount = vertexCount; - output->bakeLodLevel(data, lodID++); - } - } - } -} -void MeshLodGenerator::calcLodVertexCount(const LodLevel& lodLevel, - size_t uniqueVertexCount, - size_t& outVertexCountLimit, - Real& outCollapseCostLimit) -{ - switch(lodLevel.reductionMethod) { - case LodLevel::VRM_PROPORTIONAL: - outCollapseCostLimit = LodData::NEVER_COLLAPSE_COST; - outVertexCountLimit = uniqueVertexCount - (size_t) ((Real) uniqueVertexCount * lodLevel.reductionValue); - break; - - case LodLevel::VRM_CONSTANT: - outCollapseCostLimit = LodData::NEVER_COLLAPSE_COST; - outVertexCountLimit = (size_t) lodLevel.reductionValue; - if(outVertexCountLimit < uniqueVertexCount) { - outVertexCountLimit = uniqueVertexCount - outVertexCountLimit; - } else { - outVertexCountLimit = 0; - } - break; - - case LodLevel::VRM_COLLAPSE_COST: - outCollapseCostLimit = lodLevel.reductionValue; - outVertexCountLimit = 0; - break; - - default: - OgreAssert(0, ""); - outCollapseCostLimit = LodData::NEVER_COLLAPSE_COST; - outVertexCountLimit = uniqueVertexCount; - break; - } -} - -void MeshLodGenerator::_generateManualLodLevels(LodConfig& lodConfig) -{ - LodOutputProviderMesh output(lodConfig.mesh); - output.prepare(NULL); - for(unsigned short curLod = 0; curLod < lodConfig.levels.size(); curLod++) { - OgreAssert( - !lodConfig.levels[curLod].manualMeshName.empty(), - "Only manual Lod levels are supported! Call generateLodLevels() instead!"); - lodConfig.levels[curLod].outSkipped = false; - lodConfig.levels[curLod].outUniqueVertexCount = 0; - output.bakeManualLodLevel(NULL, lodConfig.levels[curLod].manualMeshName, curLod); - } - output.finalize(NULL); - output.inject(); - _configureMeshLodUsage(lodConfig); -} - -void MeshLodGenerator::_initWorkQueue() -{ - if (!LodWorkQueueWorker::getSingletonPtr()) { - mWQWorker = new LodWorkQueueWorker(); - } - if (!LodWorkQueueInjector::getSingletonPtr()) { - mWQInjector = new LodWorkQueueInjector(); - } -} - - -} +/* + * ----------------------------------------------------------------------------- + * This source file is part of OGRE + * (Object-oriented Graphics Rendering Engine) + * For the latest info, see http://www.ogre3d.org/ + * + * Copyright (c) 2000-2014 Torus Knot Software Ltd + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * ----------------------------------------------------------------------------- + */ + +#include "OgreMeshLodGenerator.h" +#include "OgrePixelCountLodStrategy.h" +#include "OgreLodWorkQueueWorker.h" +#include "OgreLodWorkQueueInjector.h" +#include "OgreLodInputProvider.h" +#include "OgreLodInputProviderMesh.h" +#include "OgreLodInputProviderBuffer.h" +#include "OgreLodOutputProvider.h" +#include "OgreLodOutputProviderMesh.h" +#include "OgreLodOutputProviderCompressedMesh.h" +#include "OgreLodOutputProviderBuffer.h" +#include "OgreLodOutputProviderCompressedBuffer.h" +#include "OgreLodCollapseCost.h" +#include "OgreLodCollapseCostCurvature.h" +#include "OgreLodCollapseCostProfiler.h" +#include "OgreLodCollapseCostOutside.h" +#include "OgreLodData.h" +#include "OgreLodCollapser.h" + + +namespace Ogre +{ + +template<> MeshLodGenerator* Singleton::msSingleton = 0; +MeshLodGenerator* MeshLodGenerator::getSingletonPtr() +{ + return msSingleton; +} +MeshLodGenerator& MeshLodGenerator::getSingleton() +{ + assert(msSingleton); + return (*msSingleton); +} +void MeshLodGenerator::getAutoconfig(MeshPtr& inMesh, LodConfig& outLodConfig) +{ + outLodConfig.mesh = inMesh; + outLodConfig.strategy = PixelCountLodStrategy::getSingletonPtr(); + LodLevel lodLevel; + lodLevel.reductionMethod = LodLevel::VRM_COLLAPSE_COST; + Real radius = inMesh->getBoundingSphereRadius(); + for(int i = 2; i < 6; i++) { + Real i4 = (Real) (i * i * i * i); + Real i5 = i4 * (Real) i; + // Distance = pixel count + // Constant: zoom of the Lod. This could be scaled based on resolution. + // Higher constant means first Lod is nearer to camera. Smaller constant means the first Lod is further away from camera. + // i4: The stretching. Normally you want to have more Lods in the near, then in far away. + // i4 means distance is divided by 16=(2*2*2*2), 81, 256, 625=(5*5*5*5). + // if 16 would be smaller, the first Lod would be nearer. if 625 would be bigger, the last Lod would be further awaay. + // if you increase 16 and decrease 625, first and Last Lod distance would be smaller. + lodLevel.distance = 3388608.f / i4; + + // reductionValue = collapse cost + // Radius: Edges are multiplied by the length, when calculating collapse cost. So as a base value we use radius, which should help in balancing collapse cost to any mesh size. + // The constant and i5 are playing together. 1/(1/100k*i5) + // You need to determine the quality of nearest Lod and the furthest away first. + // I have chosen 1/(1/100k*(2^5)) = 3125 for nearest Lod and 1/(1/100k*(5^5)) = 32 for nearest Lod. + // if you divide radius by a bigger number, it means smaller reduction. So radius/3125 is very small reduction for nearest Lod. + // if you divide radius by a smaller number, it means bigger reduction. So radius/32 means aggressive reduction for furthest away lod. + // current values: 3125, 411, 97, 32 + lodLevel.reductionValue = radius / 100000.f * i5; + outLodConfig.levels.push_back(lodLevel); + } +} + +void MeshLodGenerator::generateAutoconfiguredLodLevels(MeshPtr& mesh) +{ + LodConfig lodConfig; + getAutoconfig(mesh, lodConfig); + generateLodLevels(lodConfig); +} + +void MeshLodGenerator::_configureMeshLodUsage(const LodConfig& lodConfig) +{ + lodConfig.mesh->freeEdgeList(); + lodConfig.mesh->setLodStrategy(lodConfig.strategy); + MeshLodUsage usage; + size_t n = 0; + lodConfig.mesh->_setLodInfo(lodConfig.levels.size() + 1); // add Lod levels + for(size_t i = 0; i < lodConfig.levels.size(); i++) { + // Record usages. First Lod usage is the mesh itself. + + // Skip lods, which have the same amount of vertices. No buffer generated for them. + if(!lodConfig.levels[i].outSkipped) { + + usage.userValue = lodConfig.levels[i].distance; + usage.value = lodConfig.mesh->getLodStrategy()->transformUserValue(usage.userValue); + usage.edgeData = NULL; + usage.manualMesh.setNull(); + usage.manualName = lodConfig.levels[i].manualMeshName; + lodConfig.mesh->_setLodUsage(++n, usage); + } + } + // Remove skipped Lod levels + lodConfig.mesh->_setLodInfo(n + 1); +} + +MeshLodGenerator::MeshLodGenerator() : + mWQWorker(NULL), + mWQInjector(NULL) +{ + +} + +MeshLodGenerator::~MeshLodGenerator() +{ + delete mWQWorker; + delete mWQInjector; +} +void MeshLodGenerator::_resolveComponents(LodConfig& lodConfig, + LodCollapseCostPtr& cost, + LodDataPtr& data, + LodInputProviderPtr& input, + LodOutputProviderPtr& output, + LodCollapserPtr& collapser) +{ + if(cost.isNull()) { + cost = LodCollapseCostPtr(new LodCollapseCostCurvature); + if(lodConfig.advanced.outsideWeight != 0) { + cost = + LodCollapseCostPtr(new LodCollapseCostOutside(cost, lodConfig.advanced.outsideWeight, + lodConfig.advanced.outsideWalkAngle)); + } + if(!lodConfig.advanced.profile.empty()) { + cost = LodCollapseCostPtr(new LodCollapseCostProfiler(lodConfig.advanced.profile, cost)); + } + + } + if(data.isNull()) { + data = LodDataPtr(new LodData()); + } + if(collapser.isNull()) { + collapser = LodCollapserPtr(new LodCollapser()); + } + if(lodConfig.advanced.useBackgroundQueue) { + if(input.isNull()) { + input = LodInputProviderPtr(new LodInputProviderBuffer(lodConfig.mesh)); + } + if(output.isNull()) { + if(lodConfig.advanced.useCompression) { + output = LodOutputProviderPtr(new LodOutputProviderCompressedBuffer(lodConfig.mesh)); + } else { + output = LodOutputProviderPtr(new LodOutputProviderBuffer(lodConfig.mesh)); + } + } + } else { + if(input.isNull()) { + input = LodInputProviderPtr(new LodInputProviderMesh(lodConfig.mesh)); + } + if(output.isNull()) { + if(lodConfig.advanced.useCompression) { + output = LodOutputProviderPtr(new LodOutputProviderCompressedMesh(lodConfig.mesh)); + } else { + output = LodOutputProviderPtr(new LodOutputProviderMesh(lodConfig.mesh)); + } + } + } +} +void MeshLodGenerator::_process(LodConfig& lodConfig, + LodCollapseCost* cost, + LodData* data, + LodInputProvider* input, + LodOutputProvider* output, + LodCollapser* collapser) +{ + input->initData(data); + data->mUseVertexNormals = data->mUseVertexNormals && lodConfig.advanced.useVertexNormals; + cost->initCollapseCosts(data); + output->prepare(data); + computeLods(lodConfig, data, cost, output, collapser); + output->finalize(data); + if(!lodConfig.advanced.useBackgroundQueue) { + // This will be processed in LodWorkQueueInjector if we use background queue. + output->inject(); + _configureMeshLodUsage(lodConfig); + //lodConfig.mesh->buildEdgeList(); + } +} +void MeshLodGenerator::generateLodLevels(LodConfig& lodConfig, + LodCollapseCostPtr cost, + LodDataPtr data, + LodInputProviderPtr input, + LodOutputProviderPtr output, + LodCollapserPtr collapser) +{ + // If we don't have generated Lod levels, we can use _generateManualLodLevels. + bool hasGeneratedLevels = false; + for(size_t i = 0; i < lodConfig.levels.size(); i++) { + if(lodConfig.levels[i].manualMeshName.empty()) { + hasGeneratedLevels = true; + break; + } + } + if(hasGeneratedLevels || (LodWorkQueueInjector::getSingletonPtr() && LodWorkQueueInjector::getSingletonPtr()->getInjectorListener())) { + _resolveComponents(lodConfig, cost, data, input, output, collapser); + if(lodConfig.advanced.useBackgroundQueue) { + _initWorkQueue(); + LodWorkQueueWorker::getSingleton().addRequestToQueue(lodConfig, cost, data, input, output, collapser); + } else { + _process(lodConfig, cost.get(), data.get(), input.get(), output.get(), collapser.get()); + } + } else { + _generateManualLodLevels(lodConfig); + } +} + +void MeshLodGenerator::computeLods(LodConfig& lodConfig, + LodData* data, + LodCollapseCost* cost, + LodOutputProvider* output, + LodCollapser* collapser) +{ + int lodID = 0; + size_t lastBakeVertexCount = data->mVertexList.size(); + for(unsigned short curLod = 0; curLod < lodConfig.levels.size(); curLod++) { + if(!lodConfig.levels[curLod].manualMeshName.empty()) { + // Manual Lod level + lodConfig.levels[curLod].outSkipped = + (curLod != 0 && lodConfig.levels[curLod].manualMeshName == lodConfig.levels[curLod - 1].manualMeshName); + lodConfig.levels[curLod].outUniqueVertexCount = 0; + lastBakeVertexCount = -1; + if(!lodConfig.levels[curLod].outSkipped) { + output->bakeManualLodLevel(data, lodConfig.levels[curLod].manualMeshName, lodID++); + } + } else { + size_t vertexCountLimit; + Real collapseCostLimit; + calcLodVertexCount(lodConfig.levels[curLod], data->mVertexList.size(), vertexCountLimit, collapseCostLimit); + collapser->collapse(data, cost, output, static_cast(vertexCountLimit), collapseCostLimit); + size_t vertexCount = data->mCollapseCostHeap.size(); + lodConfig.levels[curLod].outUniqueVertexCount = vertexCount; + lodConfig.levels[curLod].outSkipped = (vertexCount == lastBakeVertexCount); + if(!lodConfig.levels[curLod].outSkipped) { + lastBakeVertexCount = vertexCount; + output->bakeLodLevel(data, lodID++); + } + } + } +} +void MeshLodGenerator::calcLodVertexCount(const LodLevel& lodLevel, + size_t uniqueVertexCount, + size_t& outVertexCountLimit, + Real& outCollapseCostLimit) +{ + switch(lodLevel.reductionMethod) { + case LodLevel::VRM_PROPORTIONAL: + outCollapseCostLimit = LodData::NEVER_COLLAPSE_COST; + outVertexCountLimit = uniqueVertexCount - (size_t) ((Real) uniqueVertexCount * lodLevel.reductionValue); + break; + + case LodLevel::VRM_CONSTANT: + outCollapseCostLimit = LodData::NEVER_COLLAPSE_COST; + outVertexCountLimit = (size_t) lodLevel.reductionValue; + if(outVertexCountLimit < uniqueVertexCount) { + outVertexCountLimit = uniqueVertexCount - outVertexCountLimit; + } else { + outVertexCountLimit = 0; + } + break; + + case LodLevel::VRM_COLLAPSE_COST: + outCollapseCostLimit = lodLevel.reductionValue; + outVertexCountLimit = 0; + break; + + default: + OgreAssert(0, ""); + outCollapseCostLimit = LodData::NEVER_COLLAPSE_COST; + outVertexCountLimit = uniqueVertexCount; + break; + } +} + +void MeshLodGenerator::_generateManualLodLevels(LodConfig& lodConfig) +{ + LodOutputProviderMesh output(lodConfig.mesh); + output.prepare(NULL); + for(unsigned short curLod = 0; curLod < lodConfig.levels.size(); curLod++) { + OgreAssert( + !lodConfig.levels[curLod].manualMeshName.empty(), + "Only manual Lod levels are supported! Call generateLodLevels() instead!"); + lodConfig.levels[curLod].outSkipped = false; + lodConfig.levels[curLod].outUniqueVertexCount = 0; + output.bakeManualLodLevel(NULL, lodConfig.levels[curLod].manualMeshName, curLod); + } + output.finalize(NULL); + output.inject(); + _configureMeshLodUsage(lodConfig); +} + +void MeshLodGenerator::_initWorkQueue() +{ + if (!LodWorkQueueWorker::getSingletonPtr()) { + mWQWorker = new LodWorkQueueWorker(); + } + if (!LodWorkQueueInjector::getSingletonPtr()) { + mWQInjector = new LodWorkQueueInjector(); + } +} + + +} diff --git a/Components/MeshLodGenerator/src/OgreSmallVector.cpp b/Components/MeshLodGenerator/src/OgreSmallVector.cpp index 7e3aa0dccda..d01dba6206b 100644 --- a/Components/MeshLodGenerator/src/OgreSmallVector.cpp +++ b/Components/MeshLodGenerator/src/OgreSmallVector.cpp @@ -62,25 +62,25 @@ namespace Ogre { /// grow_pod - This is an implementation of the grow() method which only works /// on POD-like datatypes and is out of line to reduce code duplication. void SmallVectorBase::grow_pod(size_t MinSizeInBytes, size_t TSize) { - size_t CurSizeBytes = size_in_bytes(); + size_t CurSizeBytes = size_in_bytes(); size_t NewCapacityInBytes = 2 * capacity_in_bytes() + TSize; // Always grow. - if (NewCapacityInBytes < MinSizeInBytes) - NewCapacityInBytes = MinSizeInBytes; + if (NewCapacityInBytes < MinSizeInBytes) + NewCapacityInBytes = MinSizeInBytes; void *NewElts; if (this->isSmall()) { NewElts = malloc(NewCapacityInBytes); - - // Copy the elements over. No need to run dtors on PODs. - memcpy(NewElts, this->BeginX, CurSizeBytes); + + // Copy the elements over. No need to run dtors on PODs. + memcpy(NewElts, this->BeginX, CurSizeBytes); } else { // If this wasn't grown from the inline copy, grow the allocated space. NewElts = realloc(this->BeginX, NewCapacityInBytes); } - - this->EndX = (char*)NewElts+CurSizeBytes; - this->BeginX = NewElts; - this->CapacityX = (char*)this->BeginX + NewCapacityInBytes; + + this->EndX = (char*)NewElts+CurSizeBytes; + this->BeginX = NewElts; + this->CapacityX = (char*)this->BeginX + NewCapacityInBytes; } } diff --git a/Components/Overlay/include/OgreFont.h b/Components/Overlay/include/OgreFont.h index d6bf74935a4..2ceac669c63 100644 --- a/Components/Overlay/include/OgreFont.h +++ b/Components/Overlay/include/OgreFont.h @@ -34,13 +34,13 @@ THE SOFTWARE namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Enumerates the types of Font usable in the engine. */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Enumerates the types of Font usable in the engine. */ enum FontType { /// Generated from a truetype (.ttf) font @@ -58,65 +58,65 @@ namespace Ogre using a truetype font. You can either create the texture manually in code, or you can use a .fontdef script to define it (probably more practical since you can reuse the definition more easily) - @note - This class extends both Resource and ManualResourceLoader since it is - both a resource in it's own right, but it also provides the manual load - implementation for the Texture it creates. + @note + This class extends both Resource and ManualResourceLoader since it is + both a resource in it's own right, but it also provides the manual load + implementation for the Texture it creates. */ - class _OgreOverlayExport Font : public Resource, public ManualResourceLoader + class _OgreOverlayExport Font : public Resource, public ManualResourceLoader { protected: - /// Command object for Font - see ParamCommand - class _OgreOverlayExport CmdType : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /// Command object for Font - see ParamCommand - class _OgreOverlayExport CmdSource : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - class _OgreOverlayExport CmdCharSpacer : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; /// Command object for Font - see ParamCommand - class _OgreOverlayExport CmdSize : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /// Command object for Font - see ParamCommand - class _OgreOverlayExport CmdResolution : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /// Command object for Font - see ParamCommand - class _OgreOverlayExport CmdCodePoints : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - - // Command object for setting / getting parameters - static CmdType msTypeCmd; - static CmdSource msSourceCmd; - static CmdCharSpacer msCharacterSpacerCmd; - static CmdSize msSizeCmd; - static CmdResolution msResolutionCmd; - static CmdCodePoints msCodePointsCmd; - - /// The type of font + class _OgreOverlayExport CmdType : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for Font - see ParamCommand + class _OgreOverlayExport CmdSource : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + class _OgreOverlayExport CmdCharSpacer : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for Font - see ParamCommand + class _OgreOverlayExport CmdSize : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for Font - see ParamCommand + class _OgreOverlayExport CmdResolution : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for Font - see ParamCommand + class _OgreOverlayExport CmdCodePoints : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + + // Command object for setting / getting parameters + static CmdType msTypeCmd; + static CmdSource msSourceCmd; + static CmdCharSpacer msCharacterSpacerCmd; + static CmdSize msSizeCmd; + static CmdResolution msResolutionCmd; + static CmdCodePoints msCodePointsCmd; + + /// The type of font FontType mType; /// Source of the font (either an image name or a truetype font) @@ -130,62 +130,62 @@ namespace Ogre Real mTtfSize; /// Resolution (dpi) of truetype font uint mTtfResolution; - /// Max distance to baseline of this (truetype) font - int mTtfMaxBearingY; - - - public: - typedef Ogre::uint32 CodePoint; - typedef Ogre::FloatRect UVRect; - /// Information about the position and size of a glyph in a texture - struct GlyphInfo - { - CodePoint codePoint; - UVRect uvRect; - Real aspectRatio; - - GlyphInfo(CodePoint id, const UVRect& rect, Real aspect) - : codePoint(id), uvRect(rect), aspectRatio(aspect) - { - - } - }; - /// A range of code points, inclusive on both ends - typedef std::pair CodePointRange; - typedef vector::type CodePointRangeList; - protected: - /// Map from unicode code point to texture coordinates - typedef map::type CodePointMap; - CodePointMap mCodePointMap; + /// Max distance to baseline of this (truetype) font + int mTtfMaxBearingY; + + + public: + typedef Ogre::uint32 CodePoint; + typedef Ogre::FloatRect UVRect; + /// Information about the position and size of a glyph in a texture + struct GlyphInfo + { + CodePoint codePoint; + UVRect uvRect; + Real aspectRatio; + + GlyphInfo(CodePoint id, const UVRect& rect, Real aspect) + : codePoint(id), uvRect(rect), aspectRatio(aspect) + { + + } + }; + /// A range of code points, inclusive on both ends + typedef std::pair CodePointRange; + typedef vector::type CodePointRangeList; + protected: + /// Map from unicode code point to texture coordinates + typedef map::type CodePointMap; + CodePointMap mCodePointMap; /// The material which is generated for this font MaterialPtr mMaterial; - /// Texture pointer - TexturePtr mTexture; + /// Texture pointer + TexturePtr mTexture; /// For TRUE_TYPE font only bool mAntialiasColour; - /// Range of code points to generate glyphs for (truetype only) - CodePointRangeList mCodePointRangeList; + /// Range of code points to generate glyphs for (truetype only) + CodePointRangeList mCodePointRangeList; /// Internal method for loading from ttf void createTextureFromFont(void); - /// @copydoc Resource::loadImpl - virtual void loadImpl(); - /// @copydoc Resource::unloadImpl - virtual void unloadImpl(); - /// @copydoc Resource::calculateSize - size_t calculateSize(void) const { return 0; } // permanent resource is in the texture + /// @copydoc Resource::loadImpl + virtual void loadImpl(); + /// @copydoc Resource::unloadImpl + virtual void unloadImpl(); + /// @copydoc Resource::calculateSize + size_t calculateSize(void) const { return 0; } // permanent resource is in the texture public: /** Constructor. - @see Resource + @see Resource */ - Font(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual = false, ManualResourceLoader* loader = 0); + Font(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual = false, ManualResourceLoader* loader = 0); virtual ~Font(); /** Sets the type of font. Must be set before loading. */ @@ -205,8 +205,8 @@ namespace Ogre If you have created a font of type FT_TRUETYPE, this method tells the Font which .ttf file to use to generate the text. You will also need to call setTrueTypeSize and setTrueTypeResolution, and call addCodePointRange - as many times as required to define the range of glyphs you want to be - available. + as many times as required to define the range of glyphs you want to be + available. @param source An image file or a truetype font, depending on the type of this font */ void setSource(const String& source); @@ -253,36 +253,36 @@ namespace Ogre Only applicable for FT_TRUETYPE Font objects. */ uint getTrueTypeResolution(void) const; - /** Gets the maximum baseline distance of all glyphs used in the texture. - @remarks - Only applicable for FT_TRUETYPE Font objects. - The baseline is the vertical origin of horizontal based glyphs. The bearingY - attribute is the distance from the baseline (origin) to the top of the glyph's - bounding box. - @note - This value is only available after the font has been loaded. - */ - int getTrueTypeMaxBearingY() const; + /** Gets the maximum baseline distance of all glyphs used in the texture. + @remarks + Only applicable for FT_TRUETYPE Font objects. + The baseline is the vertical origin of horizontal based glyphs. The bearingY + attribute is the distance from the baseline (origin) to the top of the glyph's + bounding box. + @note + This value is only available after the font has been loaded. + */ + int getTrueTypeMaxBearingY() const; /** Returns the texture coordinates of the associated glyph. @remarks Parameter is a short to allow both ASCII and wide chars. @param id The code point (unicode) @return A rectangle with the UV coordinates, or null UVs if the - code point was not present + code point was not present */ inline const UVRect& getGlyphTexCoords(CodePoint id) const { - CodePointMap::const_iterator i = mCodePointMap.find(id); - if (i != mCodePointMap.end()) - { - return i->second.uvRect; - } - else - { - static UVRect nullRect(0.0, 0.0, 0.0, 0.0); - return nullRect; - } + CodePointMap::const_iterator i = mCodePointMap.find(id); + if (i != mCodePointMap.end()) + { + return i->second.uvRect; + } + else + { + static UVRect nullRect(0.0, 0.0, 0.0, 0.0); + return nullRect; + } } /** Sets the texture coordinates of a glyph. @@ -290,86 +290,86 @@ namespace Ogre You only need to call this if you're setting up a font loaded from a texture manually. @note Also sets the aspect ratio (width / height) of this character. textureAspect - is the width/height of the texture (may be non-square) + is the width/height of the texture (may be non-square) */ inline void setGlyphTexCoords(CodePoint id, Real u1, Real v1, Real u2, Real v2, Real textureAspect) { - CodePointMap::iterator i = mCodePointMap.find(id); - if (i != mCodePointMap.end()) - { - i->second.uvRect.left = u1; - i->second.uvRect.top = v1; - i->second.uvRect.right = u2; - i->second.uvRect.bottom = v2; - i->second.aspectRatio = textureAspect * (u2 - u1) / (v2 - v1); - } - else - { - mCodePointMap.insert( - CodePointMap::value_type(id, - GlyphInfo(id, UVRect(u1, v1, u2, v2), - textureAspect * (u2 - u1) / (v2 - v1)))); - } + CodePointMap::iterator i = mCodePointMap.find(id); + if (i != mCodePointMap.end()) + { + i->second.uvRect.left = u1; + i->second.uvRect.top = v1; + i->second.uvRect.right = u2; + i->second.uvRect.bottom = v2; + i->second.aspectRatio = textureAspect * (u2 - u1) / (v2 - v1); + } + else + { + mCodePointMap.insert( + CodePointMap::value_type(id, + GlyphInfo(id, UVRect(u1, v1, u2, v2), + textureAspect * (u2 - u1) / (v2 - v1)))); + } } /** Gets the aspect ratio (width / height) of this character. */ inline Real getGlyphAspectRatio(CodePoint id) const { - CodePointMap::const_iterator i = mCodePointMap.find(id); - if (i != mCodePointMap.end()) - { - return i->second.aspectRatio; - } - else - { - return 1.0; - } + CodePointMap::const_iterator i = mCodePointMap.find(id); + if (i != mCodePointMap.end()) + { + return i->second.aspectRatio; + } + else + { + return 1.0; + } } /** Sets the aspect ratio (width / height) of this character. @remarks You only need to call this if you're setting up a font loaded from a - texture manually. + texture manually. */ inline void setGlyphAspectRatio(CodePoint id, Real ratio) { - CodePointMap::iterator i = mCodePointMap.find(id); - if (i != mCodePointMap.end()) - { - i->second.aspectRatio = ratio; - } + CodePointMap::iterator i = mCodePointMap.find(id); + if (i != mCodePointMap.end()) + { + i->second.aspectRatio = ratio; + } + } + + /** Gets the information available for a glyph corresponding to a + given code point, or throws an exception if it doesn't exist; + */ + const GlyphInfo& getGlyphInfo(CodePoint id) const; + + /** Adds a range of code points to the list of code point ranges to generate + glyphs for, if this is a truetype based font. + @remarks + In order to save texture space, only the glyphs which are actually + needed by the application are generated into the texture. Before this + object is loaded you must call this method as many times as necessary + to define the code point range that you need. + */ + void addCodePointRange(const CodePointRange& range) + { + mCodePointRangeList.push_back(range); } - /** Gets the information available for a glyph corresponding to a - given code point, or throws an exception if it doesn't exist; - */ - const GlyphInfo& getGlyphInfo(CodePoint id) const; - - /** Adds a range of code points to the list of code point ranges to generate - glyphs for, if this is a truetype based font. - @remarks - In order to save texture space, only the glyphs which are actually - needed by the application are generated into the texture. Before this - object is loaded you must call this method as many times as necessary - to define the code point range that you need. - */ - void addCodePointRange(const CodePointRange& range) - { - mCodePointRangeList.push_back(range); - } - - /** Clear the list of code point ranges. - */ - void clearCodePointRanges() - { - mCodePointRangeList.clear(); - } - /** Get a const reference to the list of code point ranges to be used to - generate glyphs from a truetype font. - */ - const CodePointRangeList& getCodePointRangeList() const - { - return mCodePointRangeList; - } + /** Clear the list of code point ranges. + */ + void clearCodePointRanges() + { + mCodePointRangeList.clear(); + } + /** Get a const reference to the list of code point ranges to be used to + generate glyphs from a truetype font. + */ + const CodePointRangeList& getCodePointRangeList() const + { + return mCodePointRangeList; + } /** Gets the material generated for this font, as a weak reference. @remarks This will only be valid after the Font has been loaded. @@ -389,7 +389,7 @@ namespace Ogre /** Sets whether or not the colour of this font is antialiased as it is generated from a true type font. @remarks - This is valid only for a FT_TRUETYPE font. If you are planning on using + This is valid only for a FT_TRUETYPE font. If you are planning on using alpha blending to draw your font, then it is a good idea to set this to false (which is the default), otherwise the darkening of the font will combine with the fading out of the alpha around the edges and make your font look thinner @@ -399,24 +399,24 @@ namespace Ogre */ inline void setAntialiasColour(bool enabled) { - mAntialiasColour = enabled; + mAntialiasColour = enabled; } - /** Gets whether or not the colour of this font is antialiased as it is generated - from a true type font. - */ + /** Gets whether or not the colour of this font is antialiased as it is generated + from a true type font. + */ inline bool getAntialiasColour(void) const { return mAntialiasColour; } - /** Implementation of ManualResourceLoader::loadResource, called - when the Texture that this font creates needs to (re)load. - */ - void loadResource(Resource* resource); + /** Implementation of ManualResourceLoader::loadResource, called + when the Texture that this font creates needs to (re)load. + */ + void loadResource(Resource* resource); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/Components/Overlay/include/OgreFontManager.h b/Components/Overlay/include/OgreFontManager.h index 625800b0643..56489fff665 100644 --- a/Components/Overlay/include/OgreFontManager.h +++ b/Components/Overlay/include/OgreFontManager.h @@ -34,29 +34,29 @@ THE SOFTWARE namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Manages Font resources, parsing .fontdef files and generally organising them.*/ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Manages Font resources, parsing .fontdef files and generally organising them.*/ class _OgreOverlayExport FontManager : public ResourceManager, public Singleton< FontManager > { public: - FontManager(); - ~FontManager(); + FontManager(); + ~FontManager(); - /// Create a new font - /// @see ResourceManager::createResource - FontPtr create (const String& name, const String& group, - bool isManual = false, ManualResourceLoader* loader = 0, - const NameValuePairList* createParams = 0); + /// Create a new font + /// @see ResourceManager::createResource + FontPtr create (const String& name, const String& group, + bool isManual = false, ManualResourceLoader* loader = 0, + const NameValuePairList* createParams = 0); - /// Get a resource by name - /// @see ResourceManager::getResourceByName - FontPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + /// Get a resource by name + /// @see ResourceManager::getResourceByName + FontPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); /** @copydoc ScriptLoader::parseScript */ @@ -97,17 +97,17 @@ namespace Ogre protected: /// Internal methods - Resource* createImpl(const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, + Resource* createImpl(const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* params); - void parseAttribute(const String& line, FontPtr& pFont); + void parseAttribute(const String& line, FontPtr& pFont); void logBadAttrib(const String& line, FontPtr& pFont); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/Components/Overlay/include/OgreOverlay.h b/Components/Overlay/include/OgreOverlay.h index acf220c2f4e..9fc1df1625e 100644 --- a/Components/Overlay/include/OgreOverlay.h +++ b/Components/Overlay/include/OgreOverlay.h @@ -36,13 +36,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ - /** Represents a layer which is rendered on top of the 'normal' scene contents. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ + /** Represents a layer which is rendered on top of the 'normal' scene contents. @remarks An overlay is a container for visual components (2D and 3D) which will be rendered after the main scene in order to composite heads-up-displays, menus @@ -66,7 +66,7 @@ namespace Ogre { don't want the overlay displayed in the smaller viewports. You turn this off for a specific viewport by calling the Viewport::setDisplayOverlays method. */ - class _OgreOverlayExport Overlay : public OverlayAlloc + class _OgreOverlayExport Overlay : public OverlayAlloc { public: @@ -92,14 +92,14 @@ namespace Ogre { bool mTransformUpdated; ulong mZOrder; bool mVisible; - bool mInitialised; - String mOrigin; + bool mInitialised; + String mOrigin; /** Internal lazy update method. */ void updateTransform(void) const; - /** Internal method for initialising an overlay */ - void initialise(void); - /** Internal method for updating container elements' Z-ordering */ - void assignZOrders(void); + /** Internal method for initialising an overlay */ + void initialise(void); + /** Internal method for updating container elements' Z-ordering */ + void assignZOrders(void); public: /// Constructor: do not call direct, use OverlayManager::create @@ -107,7 +107,7 @@ namespace Ogre { virtual ~Overlay(); - OverlayContainer* getChild(const String& name); + OverlayContainer* getChild(const String& name); /** Gets the name of this overlay. */ const String& getName(void) const; @@ -123,10 +123,10 @@ namespace Ogre { /** Gets whether the overlay is displayed or not. */ bool isVisible(void) const; - /** Gets whether the overlay is initialised or not. */ - bool isInitialised(void) const { return mInitialised; } + /** Gets whether the overlay is initialised or not. */ + bool isInitialised(void) const { return mInitialised; } - /** Shows the overlay if it was hidden. */ + /** Shows the overlay if it was hidden. */ void show(void); /** Hides the overlay if it was visible. */ @@ -162,10 +162,10 @@ namespace Ogre { @par A SceneNode can have any number of 3D objects attached to it. SceneNodes are usually created using SceneManager::createSceneNode, but in this case - you should create a standard SceneNode instance manually; this is - because these scene nodes are not managed by the SceneManager and some custom - SceneManager plugins will rely on specialist behaviour the overlay does not - support. By attaching a SceneNode to an overlay, you indicate that:
    + you should create a standard SceneNode instance manually; this is + because these scene nodes are not managed by the SceneManager and some custom + SceneManager plugins will rely on specialist behaviour the overlay does not + support. By attaching a SceneNode to an overlay, you indicate that:
    1. You want the contents of this node to only appear when the overlay is active
    2. You want the node to inherit a coordinate space relative to the camera, rather than relative to the root scene node
    3. @@ -180,8 +180,8 @@ namespace Ogre { can get artefacts because of the lack of depth buffer checking. So you should ensure that any 3D objects you us in the overlay are convex, and don't overlap each other. If they must overlap, split them up and put them in 2 overlays. - Alternatively, use a 2D element underneath them which will clear the depth buffer - values underneath ready for the 3D element to be rendered correctly. + Alternatively, use a 2D element underneath them which will clear the depth buffer + values underneath ready for the 3D element to be rendered correctly. */ void add3D(SceneNode* node); @@ -247,7 +247,7 @@ namespace Ogre { void _findVisibleObjects(Camera* cam, RenderQueue* queue); /** This returns a OverlayElement at position x,y. */ - virtual OverlayElement* findElementAt(Real x, Real y); + virtual OverlayElement* findElementAt(Real x, Real y); /** Returns an iterator over all 2D elements in this manager. @remarks @@ -258,20 +258,20 @@ namespace Ogre { { return Overlay2DElementsIterator (m2DElements.begin(), m2DElements.end()); } - /** Get the origin of this overlay, e.g. a script file name. - @remarks - This property will only contain something if the creator of - this overlay chose to populate it. Script loaders are advised - to populate it. - */ - const String& getOrigin(void) const { return mOrigin; } - /// Notify this overlay of it's origin - void _notifyOrigin(const String& origin) { mOrigin = origin; } + /** Get the origin of this overlay, e.g. a script file name. + @remarks + This property will only contain something if the creator of + this overlay chose to populate it. Script loaders are advised + to populate it. + */ + const String& getOrigin(void) const { return mOrigin; } + /// Notify this overlay of it's origin + void _notifyOrigin(const String& origin) { mOrigin = origin; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/Components/Overlay/include/OgreOverlayContainer.h b/Components/Overlay/include/OgreOverlayContainer.h index 2055b179383..e21b1191e62 100644 --- a/Components/Overlay/include/OgreOverlayContainer.h +++ b/Components/Overlay/include/OgreOverlayContainer.h @@ -37,13 +37,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ - /** A 2D element which contains other OverlayElement instances. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ + /** A 2D element which contains other OverlayElement instances. @remarks This is a specialisation of OverlayElement for 2D elements that contain other elements. These are also the smallest elements that can be attached directly @@ -66,7 +66,7 @@ namespace Ogre { /// Map of container children (subset of mChildren) ChildContainerMap mChildContainers; - bool mChildrenProcessEvents; + bool mChildrenProcessEvents; public: /// Constructor: do not call direct, use OverlayManager::createOverlayElement @@ -84,8 +84,8 @@ namespace Ogre { /** Gets the named child of this container. */ virtual OverlayElement* getChild(const String& name); - /** @copydoc OverlayElement::initialise */ - void initialise(void); + /** @copydoc OverlayElement::initialise */ + void initialise(void); void _addChild(OverlayElement* elem); void _removeChild(OverlayElement* elem) { _removeChild(elem->getName()); } @@ -100,8 +100,8 @@ namespace Ogre { */ virtual ChildContainerIterator getChildContainerIterator(void); - /** Tell the object and its children to recalculate */ - virtual void _positionsOutOfDate(void); + /** Tell the object and its children to recalculate */ + virtual void _positionsOutOfDate(void); /** Overridden from OverlayElement. */ virtual void _update(void); @@ -116,34 +116,34 @@ namespace Ogre { virtual void _notifyWorldTransforms(const Matrix4& xform); /** Overridden from OverlayElement. */ - virtual void _notifyParent(OverlayContainer* parent, Overlay* overlay); + virtual void _notifyParent(OverlayContainer* parent, Overlay* overlay); /** Overridden from OverlayElement. */ virtual void _updateRenderQueue(RenderQueue* queue); /** Overridden from OverlayElement. */ - inline bool isContainer() const - { return true; } + inline bool isContainer() const + { return true; } - /** Should this container pass events to their children */ - virtual inline bool isChildrenProcessEvents() const - { return true; } + /** Should this container pass events to their children */ + virtual inline bool isChildrenProcessEvents() const + { return true; } - /** Should this container pass events to their children */ - virtual inline void setChildrenProcessEvents(bool val) - { mChildrenProcessEvents = val; } + /** Should this container pass events to their children */ + virtual inline void setChildrenProcessEvents(bool val) + { mChildrenProcessEvents = val; } /** This returns a OverlayElement at position x,y. */ - virtual OverlayElement* findElementAt(Real x, Real y); // relative to parent + virtual OverlayElement* findElementAt(Real x, Real y); // relative to parent - void copyFromTemplate(OverlayElement* templateOverlay); + void copyFromTemplate(OverlayElement* templateOverlay); virtual OverlayElement* clone(const String& instanceName); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/Components/Overlay/include/OgreOverlayElement.h b/Components/Overlay/include/OgreOverlayElement.h index 2af8cb59d22..ae7dcc24a1f 100644 --- a/Components/Overlay/include/OgreOverlayElement.h +++ b/Components/Overlay/include/OgreOverlayElement.h @@ -37,19 +37,19 @@ THE SOFTWARE. #include "OgreColourValue.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ #if OGRE_UNICODE_SUPPORT - typedef UTFString DisplayString; -# define OGRE_DEREF_DISPLAYSTRING_ITERATOR(it) it.getCharacter() + typedef UTFString DisplayString; +# define OGRE_DEREF_DISPLAYSTRING_ITERATOR(it) it.getCharacter() #else - typedef String DisplayString; -# define OGRE_DEREF_DISPLAYSTRING_ITERATOR(it) *it + typedef String DisplayString; +# define OGRE_DEREF_DISPLAYSTRING_ITERATOR(it) *it #endif /** Enum describing how the position / size of an element is to be recorded. */ @@ -158,8 +158,8 @@ namespace Ogre { /// Flag indicating if the vertex positions need recalculating bool mGeomPositionsOutOfDate; - /// Flag indicating if the vertex uvs need recalculating - bool mGeomUVsOutOfDate; + /// Flag indicating if the vertex uvs need recalculating + bool mGeomUVsOutOfDate; /** Zorder for when sending to render queue. Derived from parent */ @@ -171,8 +171,8 @@ namespace Ogre { /// Is element enabled? bool mEnabled; - /// Is element initialised? - bool mInitialised; + /// Is element initialised? + bool mInitialised; /// Used to see if this element is created from a Template OverlayElement* mSourceTemplate ; @@ -182,11 +182,11 @@ namespace Ogre { subclasses must implement this. */ virtual void updatePositionGeometry(void) = 0; - /** Internal method which is triggered when the UVs of the element get updated, - meaning the element should be rebuilding it's mesh UVs. Abstract since - subclasses must implement this. - */ - virtual void updateTextureGeometry(void) = 0; + /** Internal method which is triggered when the UVs of the element get updated, + meaning the element should be rebuilding it's mesh UVs. Abstract since + subclasses must implement this. + */ + virtual void updateTextureGeometry(void) = 0; /** Internal method for setting up the basic parameter definitions for a subclass. @remarks @@ -314,10 +314,10 @@ namespace Ogre { /** Gets the 'top' position as derived from own left and that of parents. */ virtual Real _getDerivedTop(void); - /** Gets the 'width' as derived from own width and metrics mode. */ - virtual Real _getRelativeWidth(void); - /** Gets the 'height' as derived from own height and metrics mode. */ - virtual Real _getRelativeHeight(void); + /** Gets the 'width' as derived from own width and metrics mode. */ + virtual Real _getRelativeWidth(void); + /** Gets the 'height' as derived from own height and metrics mode. */ + virtual Real _getRelativeHeight(void); /** Gets the clipping region of the element */ @@ -331,9 +331,9 @@ namespace Ogre { nested within this to ensure that containers are displayed behind contained items. This method is used internally to notify the element of a change in final Z-order which is used to render the element. - @return Return the next Z-ordering number available. For single elements, this - is simply 'newZOrder + 1', except for containers. They increment it once for each - child (or even more if those children are also containers with their own elements). + @return Return the next Z-ordering number available. For single elements, this + is simply 'newZOrder + 1', except for containers. They increment it once for each + child (or even more if those children are also containers with their own elements). */ virtual ushort _notifyZOrder(ushort newZOrder); @@ -350,9 +350,9 @@ namespace Ogre { /** Internal method to put the contents onto the render queue. */ virtual void _updateRenderQueue(RenderQueue* queue); - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false); + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false); /** Gets the type name of the element. All concrete subclasses must implement this. */ virtual const String& getTypeName(void) const = 0; @@ -363,7 +363,7 @@ namespace Ogre { However, being a common requirement it is in the top-level interface to avoid having to set it via the StringInterface all the time. */ - virtual void setCaption(const DisplayString& text); + virtual void setCaption(const DisplayString& text); /** Gets the caption for this element. */ virtual const DisplayString& getCaption(void) const; /** Sets the colour on elements that support it. @@ -434,7 +434,7 @@ namespace Ogre { virtual bool contains(Real x, Real y) const; /** Returns true if xy is within the constraints of the component */ - virtual OverlayElement* findElementAt(Real x, Real y); // relative to parent + virtual OverlayElement* findElementAt(Real x, Real y); // relative to parent /** * returns false as this class is not a container type @@ -488,8 +488,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/Components/Overlay/include/OgreOverlayElementCommands.h b/Components/Overlay/include/OgreOverlayElementCommands.h index 542f675de95..a6f613e2478 100644 --- a/Components/Overlay/include/OgreOverlayElementCommands.h +++ b/Components/Overlay/include/OgreOverlayElementCommands.h @@ -33,12 +33,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ namespace OverlayElementCommands { /// Command object for OverlayElement - see ParamCommand @@ -113,8 +113,8 @@ namespace Ogre { }; } - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/Components/Overlay/include/OgreOverlayElementFactory.h b/Components/Overlay/include/OgreOverlayElementFactory.h index d8b154a9d80..3a9def0a882 100644 --- a/Components/Overlay/include/OgreOverlayElementFactory.h +++ b/Components/Overlay/include/OgreOverlayElementFactory.h @@ -36,13 +36,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ - /** Defines the interface which all components wishing to + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ + /** Defines the interface which all components wishing to supply OverlayElement subclasses must implement. @remarks To allow the OverlayElement types available for inclusion on @@ -54,7 +54,7 @@ namespace Ogre { Each OverlayElementFactory creates a single type of OverlayElement, identified by a 'type name' which must be unique. */ - class _OgreOverlayExport OverlayElementFactory : public OverlayAlloc + class _OgreOverlayExport OverlayElementFactory : public OverlayAlloc { public: /** Destroy the overlay element factory */ @@ -106,8 +106,8 @@ namespace Ogre { /** See OverlayElementFactory */ virtual const String& getTypeName(void) const; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/Components/Overlay/include/OgreOverlayManager.h b/Components/Overlay/include/OgreOverlayManager.h index cd8559af0cd..6a23de5f732 100644 --- a/Components/Overlay/include/OgreOverlayManager.h +++ b/Components/Overlay/include/OgreOverlayManager.h @@ -36,23 +36,23 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ - /** Manages Overlay objects, parsing them from .overlay files and + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ + /** Manages Overlay objects, parsing them from .overlay files and storing a lookup library of them. Also manages the creation of - OverlayContainers and OverlayElements, used for non-interactive 2D - elements such as HUDs. + OverlayContainers and OverlayElements, used for non-interactive 2D + elements such as HUDs. */ class _OgreOverlayExport OverlayManager : public Singleton, public ScriptLoader, public OverlayAlloc { public: typedef map::type OverlayMap; - typedef map::type ElementMap; - typedef map::type FactoryMap; + typedef map::type ElementMap; + typedef map::type FactoryMap; protected: OverlayMap mOverlayMap; StringVector mScriptPatterns; @@ -68,33 +68,33 @@ namespace Ogre { bool mViewportDimensionsChanged; OrientationMode mLastViewportOrientationMode; - bool parseChildren( DataStreamPtr& chunk, const String& line, + bool parseChildren( DataStreamPtr& chunk, const String& line, Overlay* pOverlay, bool isTemplate, OverlayContainer* parent = NULL); - FactoryMap mFactories; + FactoryMap mFactories; - ElementMap mInstances; - ElementMap mTemplates; + ElementMap mInstances; + ElementMap mTemplates; - typedef set::type LoadedScripts; - LoadedScripts mLoadedScripts; + typedef set::type LoadedScripts; + LoadedScripts mLoadedScripts; - ElementMap& getElementMap(bool isTemplate); + ElementMap& getElementMap(bool isTemplate); - OverlayElement* createOverlayElementImpl(const String& typeName, const String& instanceName, ElementMap& elementMap); + OverlayElement* createOverlayElementImpl(const String& typeName, const String& instanceName, ElementMap& elementMap); - OverlayElement* getOverlayElementImpl(const String& name, ElementMap& elementMap); - - bool hasOverlayElementImpl(const String& name, ElementMap& elementMap); + OverlayElement* getOverlayElementImpl(const String& name, ElementMap& elementMap); + + bool hasOverlayElementImpl(const String& name, ElementMap& elementMap); - void destroyOverlayElementImpl(const String& instanceName, ElementMap& elementMap); + void destroyOverlayElementImpl(const String& instanceName, ElementMap& elementMap); - void destroyOverlayElementImpl(OverlayElement* pInstance, ElementMap& elementMap); + void destroyOverlayElementImpl(OverlayElement* pInstance, ElementMap& elementMap); - void destroyAllOverlayElementsImpl(ElementMap& elementMap); + void destroyAllOverlayElementsImpl(ElementMap& elementMap); public: OverlayManager(); @@ -141,74 +141,74 @@ namespace Ogre { /** Gets the orientation mode of the destination viewport. */ OrientationMode getViewportOrientationMode(void) const; - /** Creates a new OverlayElement of the type requested. - @remarks - The type of element to create is passed in as a string because this - allows plugins to register new types of component. - @param typeName The type of element to create. - @param instanceName The name to give the new instance. - */ - OverlayElement* createOverlayElement(const String& typeName, const String& instanceName, bool isTemplate = false); - - /** Gets a reference to an existing element. */ - OverlayElement* getOverlayElement(const String& name, bool isTemplate = false); - - /** Tests if an element exists. */ - bool hasOverlayElement(const String& name, bool isTemplate = false); - - /** Destroys a OverlayElement. - @remarks - Make sure you're not still using this in an Overlay. If in - doubt, let OGRE destroy elements on shutdown. - */ - void destroyOverlayElement(const String& instanceName, bool isTemplate = false); - - /** Destroys a OverlayElement. - @remarks - Make sure you're not still using this in an Overlay. If in - doubt, let OGRE destroy elements on shutdown. - */ - void destroyOverlayElement(OverlayElement* pInstance, bool isTemplate = false); - - /** Destroys all the OverlayElement created so far. - @remarks - Best to leave this to the engine to call internally, there - should rarely be a need to call it yourself. - */ - void destroyAllOverlayElements(bool isTemplate = false); - - /** Registers a new OverlayElementFactory with this manager. - @remarks - Should be used by plugins or other apps wishing to provide - a new OverlayElement subclass. - */ - void addOverlayElementFactory(OverlayElementFactory* elemFactory); - - /** Get const access to the list of registered OverlayElement factories. */ - const FactoryMap& getOverlayElementFactoryMap() const { - return mFactories; - } - - OverlayElement* createOverlayElementFromTemplate(const String& templateName, const String& typeName, const String& instanceName, bool isTemplate = false); - /** - * @remarks - * Creates a new OverlayElement object from the specified template name. The new - * object's name, and all of it's children, will be instanceName/orignalName. - */ - OverlayElement* cloneOverlayElementFromTemplate(const String& templateName, const String& instanceName); - - OverlayElement* createOverlayElementFromFactory(const String& typeName, const String& instanceName); - - typedef MapIterator TemplateIterator; - /** Returns an iterator over all templates in this manager.*/ - TemplateIterator getTemplateIterator () - { - return TemplateIterator (mTemplates.begin (), mTemplates.end ()) ; - } - /* Returns whether the Element with the given name is a Template */ - bool isTemplate (String strName) const { - return (mTemplates.find (strName) != mTemplates.end()) ; - } + /** Creates a new OverlayElement of the type requested. + @remarks + The type of element to create is passed in as a string because this + allows plugins to register new types of component. + @param typeName The type of element to create. + @param instanceName The name to give the new instance. + */ + OverlayElement* createOverlayElement(const String& typeName, const String& instanceName, bool isTemplate = false); + + /** Gets a reference to an existing element. */ + OverlayElement* getOverlayElement(const String& name, bool isTemplate = false); + + /** Tests if an element exists. */ + bool hasOverlayElement(const String& name, bool isTemplate = false); + + /** Destroys a OverlayElement. + @remarks + Make sure you're not still using this in an Overlay. If in + doubt, let OGRE destroy elements on shutdown. + */ + void destroyOverlayElement(const String& instanceName, bool isTemplate = false); + + /** Destroys a OverlayElement. + @remarks + Make sure you're not still using this in an Overlay. If in + doubt, let OGRE destroy elements on shutdown. + */ + void destroyOverlayElement(OverlayElement* pInstance, bool isTemplate = false); + + /** Destroys all the OverlayElement created so far. + @remarks + Best to leave this to the engine to call internally, there + should rarely be a need to call it yourself. + */ + void destroyAllOverlayElements(bool isTemplate = false); + + /** Registers a new OverlayElementFactory with this manager. + @remarks + Should be used by plugins or other apps wishing to provide + a new OverlayElement subclass. + */ + void addOverlayElementFactory(OverlayElementFactory* elemFactory); + + /** Get const access to the list of registered OverlayElement factories. */ + const FactoryMap& getOverlayElementFactoryMap() const { + return mFactories; + } + + OverlayElement* createOverlayElementFromTemplate(const String& templateName, const String& typeName, const String& instanceName, bool isTemplate = false); + /** + * @remarks + * Creates a new OverlayElement object from the specified template name. The new + * object's name, and all of it's children, will be instanceName/orignalName. + */ + OverlayElement* cloneOverlayElementFromTemplate(const String& templateName, const String& instanceName); + + OverlayElement* createOverlayElementFromFactory(const String& typeName, const String& instanceName); + + typedef MapIterator TemplateIterator; + /** Returns an iterator over all templates in this manager.*/ + TemplateIterator getTemplateIterator () + { + return TemplateIterator (mTemplates.begin (), mTemplates.end ()) ; + } + /* Returns whether the Element with the given name is a Template */ + bool isTemplate (String strName) const { + return (mTemplates.find (strName) != mTemplates.end()) ; + } /** Override standard Singleton retrieval. @@ -246,8 +246,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/Components/Overlay/include/OgreOverlayPrerequisites.h b/Components/Overlay/include/OgreOverlayPrerequisites.h index 5e463f262b8..875dd34aa44 100644 --- a/Components/Overlay/include/OgreOverlayPrerequisites.h +++ b/Components/Overlay/include/OgreOverlayPrerequisites.h @@ -33,10 +33,10 @@ THE SOFTWARE. namespace Ogre { - // forward decls - class Font; + // forward decls + class Font; class FontManager; - class Overlay; + class Overlay; class OverlayContainer; class OverlayElement; class OverlayElementFactory; @@ -46,23 +46,23 @@ namespace Ogre } #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT -# if defined( OGRE_STATIC_LIB ) -# define _OgreOverlayExport +# if defined( OGRE_STATIC_LIB ) +# define _OgreOverlayExport # else -# if defined( OGRE_OVERLAY_EXPORTS ) -# define _OgreOverlayExport __declspec( dllexport ) -# else +# if defined( OGRE_OVERLAY_EXPORTS ) +# define _OgreOverlayExport __declspec( dllexport ) +# else # if defined( __MINGW32__ ) # define _OgreOverlayExport # else -# define _OgreOverlayExport __declspec( dllimport ) +# define _OgreOverlayExport __declspec( dllimport ) # endif -# endif -# endif +# endif +# endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgreOverlayExport __attribute__ ((visibility("default"))) #else -# define _OgreOverlayExport +# define _OgreOverlayExport #endif diff --git a/Components/Overlay/include/OgreOverlayProfileSessionListener.h b/Components/Overlay/include/OgreOverlayProfileSessionListener.h index 5477ffeb1b6..b1882fa439c 100644 --- a/Components/Overlay/include/OgreOverlayProfileSessionListener.h +++ b/Components/Overlay/include/OgreOverlayProfileSessionListener.h @@ -34,53 +34,53 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ - /** Concrete impl. of the ProfileSessionListener which visualizes - the profling results using overlays. - */ - class _OgreOverlayExport OverlayProfileSessionListener : public ProfileSessionListener - { - public: - OverlayProfileSessionListener(); - virtual ~OverlayProfileSessionListener(); + /** Concrete impl. of the ProfileSessionListener which visualizes + the profling results using overlays. + */ + class _OgreOverlayExport OverlayProfileSessionListener : public ProfileSessionListener + { + public: + OverlayProfileSessionListener(); + virtual ~OverlayProfileSessionListener(); - /// @see ProfileSessionListener::initializeSession - virtual void initializeSession(); + /// @see ProfileSessionListener::initializeSession + virtual void initializeSession(); - /// @see ProfileSessionListener::finializeSession - virtual void finializeSession(); + /// @see ProfileSessionListener::finializeSession + virtual void finializeSession(); - /// @see ProfileSessionListener::displayResults - virtual void displayResults(const ProfileInstance& instance, ulong maxTotalFrameTime); + /// @see ProfileSessionListener::displayResults + virtual void displayResults(const ProfileInstance& instance, ulong maxTotalFrameTime); - /// @see ProfileSessionListener::changeEnableState - virtual void changeEnableState(bool enabled); + /// @see ProfileSessionListener::changeEnableState + virtual void changeEnableState(bool enabled); - /** Set the size of the profiler overlay, in pixels. */ - void setOverlayDimensions(Real width, Real height); + /** Set the size of the profiler overlay, in pixels. */ + void setOverlayDimensions(Real width, Real height); - /** Set the position of the profiler overlay, in pixels. */ - void setOverlayPosition(Real left, Real top); + /** Set the position of the profiler overlay, in pixels. */ + void setOverlayPosition(Real left, Real top); - Real getOverlayWidth() const; - Real getOverlayHeight() const; - Real getOverlayLeft() const; - Real getOverlayTop() const; + Real getOverlayWidth() const; + Real getOverlayHeight() const; + Real getOverlayLeft() const; + Real getOverlayTop() const; - private: - typedef list::type ProfileBarList; + private: + typedef list::type ProfileBarList; - /** Prints the profiling results of each frame - @remarks Recursive, for all the little children. */ - void displayResults(ProfileInstance* instance, ProfileBarList::const_iterator& bIter, Real& maxTimeMillisecs, Real& newGuiHeight, int& profileCount); + /** Prints the profiling results of each frame + @remarks Recursive, for all the little children. */ + void displayResults(ProfileInstance* instance, ProfileBarList::const_iterator& bIter, Real& maxTimeMillisecs, Real& newGuiHeight, int& profileCount); - /** An internal function to create the container which will hold our display elements*/ + /** An internal function to create the container which will hold our display elements*/ OverlayContainer* createContainer(); /** An internal function to create a text area */ @@ -94,7 +94,7 @@ namespace Ogre { /// Holds the display bars for each profile results ProfileBarList mProfileBars; - /// The overlay which contains our profiler results display + /// The overlay which contains our profiler results display Overlay* mOverlay; /// The window that displays the profiler results @@ -109,13 +109,13 @@ namespace Ogre { /// The width of the stats window Real mGuiWidth; - /// The horz position of the stats window - Real mGuiLeft; + /// The horz position of the stats window + Real mGuiLeft; - /// The vertical position of the stats window - Real mGuiTop; + /// The vertical position of the stats window + Real mGuiTop; - /// The size of the indent for each profile display bar + /// The size of the indent for each profile display bar Real mBarIndent; /// The width of the border between the profile window and each bar @@ -124,11 +124,11 @@ namespace Ogre { /// The width of the min, avg, and max lines in a profile display Real mBarLineWidth; - /// The distance between bars - Real mBarSpacing; + /// The distance between bars + Real mBarSpacing; /// The max number of profiles we can display uint mMaxDisplayProfiles; - }; + }; } #endif \ No newline at end of file diff --git a/Components/Overlay/include/OgreOverlaySystem.h b/Components/Overlay/include/OgreOverlaySystem.h index 215b8cb41f4..acbd46ddf4f 100644 --- a/Components/Overlay/include/OgreOverlaySystem.h +++ b/Components/Overlay/include/OgreOverlaySystem.h @@ -38,38 +38,38 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ - /** This class simplify initialization / finalization of the overlay system. - OGRE root did this steps before the overlay system transformed into a component. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ + /** This class simplify initialization / finalization of the overlay system. + OGRE root did this steps before the overlay system transformed into a component. @remarks Before you create a concrete instance of the OverlaySystem the OGRE::Root must be created - but not initialized. In the ctor all relevant systems are created and registered. The dtor - must be called before you delete OGRE::Root. - To make the overlays visible (= render into your viewports) you have to register this - instance as a RenderQueueListener in your scenemanager(s). + but not initialized. In the ctor all relevant systems are created and registered. The dtor + must be called before you delete OGRE::Root. + To make the overlays visible (= render into your viewports) you have to register this + instance as a RenderQueueListener in your scenemanager(s). */ - class _OgreOverlayExport OverlaySystem : public OverlayAlloc , public Ogre::RenderQueueListener - { - public: - OverlaySystem(); - virtual ~OverlaySystem(); + class _OgreOverlayExport OverlaySystem : public OverlayAlloc , public Ogre::RenderQueueListener + { + public: + OverlaySystem(); + virtual ~OverlaySystem(); - /// @see RenderQueueListener - virtual void renderQueueStarted(uint8 queueGroupId, const String& invocation, - bool& skipThisInvocation); - private: + /// @see RenderQueueListener + virtual void renderQueueStarted(uint8 queueGroupId, const String& invocation, + bool& skipThisInvocation); + private: OverlayManager* mOverlayManager; FontManager* mFontManager; #if OGRE_PROFILING - OverlayProfileSessionListener* mProfileListener; + OverlayProfileSessionListener* mProfileListener; #endif - }; + }; } #endif \ No newline at end of file diff --git a/Components/Overlay/include/OgrePanelOverlayElement.h b/Components/Overlay/include/OgrePanelOverlayElement.h index 56b9175a92e..7b41d3425df 100644 --- a/Components/Overlay/include/OgrePanelOverlayElement.h +++ b/Components/Overlay/include/OgrePanelOverlayElement.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ - /** OverlayElement representing a flat, single-material (or transparent) panel which can contain other elements. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ + /** OverlayElement representing a flat, single-material (or transparent) panel which can contain other elements. @remarks This class subclasses OverlayContainer because it can contain other elements. Like other containers, if hidden it's contents are also hidden, if moved it's contents also move etc. @@ -153,8 +153,8 @@ namespace Ogre { static CmdUVCoords msCmdUVCoords; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/Components/Overlay/include/OgreTextAreaOverlayElement.h b/Components/Overlay/include/OgreTextAreaOverlayElement.h index fe83b654b7e..5dff5682459 100644 --- a/Components/Overlay/include/OgreTextAreaOverlayElement.h +++ b/Components/Overlay/include/OgreTextAreaOverlayElement.h @@ -32,13 +32,13 @@ THE SOFTWARE namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ - /** This class implements an overlay element which contains simple unformatted text. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ + /** This class implements an overlay element which contains simple unformatted text. */ class _OgreOverlayExport TextAreaOverlayElement : public OverlayElement { @@ -56,7 +56,7 @@ namespace Ogre virtual ~TextAreaOverlayElement(); virtual void initialise(void); - virtual void setCaption(const DisplayString& text); + virtual void setCaption(const DisplayString& text); void setCharHeight( Real height ); Real getCharHeight() const; @@ -70,7 +70,7 @@ namespace Ogre /** See OverlayElement. */ virtual const String& getTypeName(void) const; /** See Renderable. */ - const MaterialPtr& getMaterial(void) const; + const MaterialPtr& getMaterial(void) const; /** See Renderable. */ void getRenderOperation(RenderOperation& op); /** Overridden from OverlayElement */ @@ -108,7 +108,7 @@ namespace Ogre inline void setAlignment( Alignment a ) { mAlignment = a; - mGeomPositionsOutOfDate = true; + mGeomPositionsOutOfDate = true; } inline Alignment getAlignment() const { @@ -234,7 +234,7 @@ namespace Ogre Real mSpaceWidth; ushort mPixelSpaceWidth; size_t mAllocSize; - Real mViewportAspectCoef; + Real mViewportAspectCoef; /// Colours to use for the vertices ColourValue mColourBottom; @@ -246,13 +246,13 @@ namespace Ogre void checkMemoryAllocation( size_t numChars ); /// Inherited function virtual void updatePositionGeometry(); - /// Inherited function - virtual void updateTextureGeometry(); + /// Inherited function + virtual void updateTextureGeometry(); /// Updates vertex colours virtual void updateColours(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/Components/Overlay/src/OgreBorderPanelOverlayElement.cpp b/Components/Overlay/src/OgreBorderPanelOverlayElement.cpp index 88c515fad0c..356b871634a 100644 --- a/Components/Overlay/src/OgreBorderPanelOverlayElement.cpp +++ b/Components/Overlay/src/OgreBorderPanelOverlayElement.cpp @@ -83,92 +83,92 @@ namespace Ogre { //--------------------------------------------------------------------- void BorderPanelOverlayElement::initialise(void) { - bool init = !mInitialised; + bool init = !mInitialised; PanelOverlayElement::initialise(); // superclass will handle the interior panel area if (init) - { - // Setup render op in advance - mRenderOp2.vertexData = OGRE_NEW VertexData(); - mRenderOp2.vertexData->vertexCount = 4 * 8; // 8 cells, can't necessarily share vertices cos - // texcoords may differ - mRenderOp2.vertexData->vertexStart = 0; - - // Vertex declaration - VertexDeclaration* decl = mRenderOp2.vertexData->vertexDeclaration; - // Position and texture coords each have their own buffers to allow - // each to be edited separately with the discard flag - decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); - decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); - - // Vertex buffer #1, position - HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton() - .createVertexBuffer( - decl->getVertexSize(POSITION_BINDING), - mRenderOp2.vertexData->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - // bind position - VertexBufferBinding* binding = mRenderOp2.vertexData->vertexBufferBinding; - binding->setBinding(POSITION_BINDING, vbuf); - - // Vertex buffer #2, texcoords - vbuf = HardwareBufferManager::getSingleton() - .createVertexBuffer( - decl->getVertexSize(TEXCOORD_BINDING), - mRenderOp2.vertexData->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); - // bind texcoord - binding->setBinding(TEXCOORD_BINDING, vbuf); - - mRenderOp2.operationType = RenderOperation::OT_TRIANGLE_LIST; - mRenderOp2.useIndexes = true; - // Index data - mRenderOp2.indexData = OGRE_NEW IndexData(); - mRenderOp2.indexData->indexCount = 8 * 6; - mRenderOp2.indexData->indexStart = 0; + { + // Setup render op in advance + mRenderOp2.vertexData = OGRE_NEW VertexData(); + mRenderOp2.vertexData->vertexCount = 4 * 8; // 8 cells, can't necessarily share vertices cos + // texcoords may differ + mRenderOp2.vertexData->vertexStart = 0; + + // Vertex declaration + VertexDeclaration* decl = mRenderOp2.vertexData->vertexDeclaration; + // Position and texture coords each have their own buffers to allow + // each to be edited separately with the discard flag + decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); + decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); + + // Vertex buffer #1, position + HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton() + .createVertexBuffer( + decl->getVertexSize(POSITION_BINDING), + mRenderOp2.vertexData->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + // bind position + VertexBufferBinding* binding = mRenderOp2.vertexData->vertexBufferBinding; + binding->setBinding(POSITION_BINDING, vbuf); + + // Vertex buffer #2, texcoords + vbuf = HardwareBufferManager::getSingleton() + .createVertexBuffer( + decl->getVertexSize(TEXCOORD_BINDING), + mRenderOp2.vertexData->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY, true); + // bind texcoord + binding->setBinding(TEXCOORD_BINDING, vbuf); + + mRenderOp2.operationType = RenderOperation::OT_TRIANGLE_LIST; + mRenderOp2.useIndexes = true; + // Index data + mRenderOp2.indexData = OGRE_NEW IndexData(); + mRenderOp2.indexData->indexCount = 8 * 6; + mRenderOp2.indexData->indexStart = 0; mRenderOp2.useGlobalInstancingVertexBufferIsAvailable = false; - /* Each cell is - 0-----2 - | /| - | / | - |/ | - 1-----3 - */ - mRenderOp2.indexData->indexBuffer = HardwareBufferManager::getSingleton(). - createIndexBuffer( - HardwareIndexBuffer::IT_16BIT, - mRenderOp2.indexData->indexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - ushort* pIdx = static_cast( - mRenderOp2.indexData->indexBuffer->lock( - 0, - mRenderOp2.indexData->indexBuffer->getSizeInBytes(), - HardwareBuffer::HBL_DISCARD) ); - - for (ushort cell = 0; cell < 8; ++cell) - { - ushort base = cell * 4; - *pIdx++ = base; - *pIdx++ = base + 1; - *pIdx++ = base + 2; - - *pIdx++ = base + 2; - *pIdx++ = base + 1; - *pIdx++ = base + 3; - } - - mRenderOp2.indexData->indexBuffer->unlock(); - - // Create sub-object for rendering border - mBorderRenderable = OGRE_NEW BorderRenderable(this); - - mInitialised = true; - } + /* Each cell is + 0-----2 + | /| + | / | + |/ | + 1-----3 + */ + mRenderOp2.indexData->indexBuffer = HardwareBufferManager::getSingleton(). + createIndexBuffer( + HardwareIndexBuffer::IT_16BIT, + mRenderOp2.indexData->indexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + + ushort* pIdx = static_cast( + mRenderOp2.indexData->indexBuffer->lock( + 0, + mRenderOp2.indexData->indexBuffer->getSizeInBytes(), + HardwareBuffer::HBL_DISCARD) ); + + for (ushort cell = 0; cell < 8; ++cell) + { + ushort base = cell * 4; + *pIdx++ = base; + *pIdx++ = base + 1; + *pIdx++ = base + 2; + + *pIdx++ = base + 2; + *pIdx++ = base + 1; + *pIdx++ = base + 3; + } + + mRenderOp2.indexData->indexBuffer->unlock(); + + // Create sub-object for rendering border + mBorderRenderable = OGRE_NEW BorderRenderable(this); + + mInitialised = true; + } } //--------------------------------------------------------------------- void BorderPanelOverlayElement::addBaseParameters(void) @@ -283,157 +283,157 @@ namespace Ogre { { if (mMetricsMode == GMM_PIXELS) { - return mPixelLeftBorderSize; - } - else - { - return mLeftBorderSize; - } + return mPixelLeftBorderSize; + } + else + { + return mLeftBorderSize; + } } //--------------------------------------------------------------------- Real BorderPanelOverlayElement::getRightBorderSize(void) const { if (mMetricsMode == GMM_PIXELS) { - return mPixelRightBorderSize; - } - else - { - return mRightBorderSize; - } + return mPixelRightBorderSize; + } + else + { + return mRightBorderSize; + } } //--------------------------------------------------------------------- Real BorderPanelOverlayElement::getTopBorderSize(void) const { if (mMetricsMode == GMM_PIXELS) { - return mPixelTopBorderSize; - } - else - { - return mTopBorderSize; - } + return mPixelTopBorderSize; + } + else + { + return mTopBorderSize; + } } //--------------------------------------------------------------------- Real BorderPanelOverlayElement::getBottomBorderSize(void) const { if (mMetricsMode == GMM_PIXELS) { - return mPixelBottomBorderSize; - } - else - { - return mBottomBorderSize; - } + return mPixelBottomBorderSize; + } + else + { + return mBottomBorderSize; + } } //--------------------------------------------------------------------- void BorderPanelOverlayElement::updateTextureGeometry() { - PanelOverlayElement::updateTextureGeometry(); - /* Each cell is - 0-----2 - | /| - | / | - |/ | - 1-----3 - */ - // No choice but to lock / unlock each time here, but lock only small sections - - HardwareVertexBufferSharedPtr vbuf = - mRenderOp2.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING); - // Can't use discard since this discards whole buffer - float* pUV = static_cast(vbuf->lock(HardwareBuffer::HBL_DISCARD)); - - for (uint i = 0; i < 8; ++i) - { - *pUV++ = mBorderUV[i].u1; *pUV++ = mBorderUV[i].v1; - *pUV++ = mBorderUV[i].u1; *pUV++ = mBorderUV[i].v2; - *pUV++ = mBorderUV[i].u2; *pUV++ = mBorderUV[i].v1; - *pUV++ = mBorderUV[i].u2; *pUV++ = mBorderUV[i].v2; - } - - vbuf->unlock(); + PanelOverlayElement::updateTextureGeometry(); + /* Each cell is + 0-----2 + | /| + | / | + |/ | + 1-----3 + */ + // No choice but to lock / unlock each time here, but lock only small sections + + HardwareVertexBufferSharedPtr vbuf = + mRenderOp2.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING); + // Can't use discard since this discards whole buffer + float* pUV = static_cast(vbuf->lock(HardwareBuffer::HBL_DISCARD)); + + for (uint i = 0; i < 8; ++i) + { + *pUV++ = mBorderUV[i].u1; *pUV++ = mBorderUV[i].v1; + *pUV++ = mBorderUV[i].u1; *pUV++ = mBorderUV[i].v2; + *pUV++ = mBorderUV[i].u2; *pUV++ = mBorderUV[i].v1; + *pUV++ = mBorderUV[i].u2; *pUV++ = mBorderUV[i].v2; + } + + vbuf->unlock(); } //--------------------------------------------------------------------- String BorderPanelOverlayElement::getCellUVString(BorderCellIndex idx) const { String ret = StringConverter::toString(mBorderUV[idx].u1) + " " + - StringConverter::toString(mBorderUV[idx].v1) + " " + - StringConverter::toString(mBorderUV[idx].u2) + " " + - StringConverter::toString(mBorderUV[idx].v2); + StringConverter::toString(mBorderUV[idx].v1) + " " + + StringConverter::toString(mBorderUV[idx].u2) + " " + + StringConverter::toString(mBorderUV[idx].v2); return ret; } //--------------------------------------------------------------------- void BorderPanelOverlayElement::setLeftBorderUV(Real u1, Real v1, Real u2, Real v2) { - mBorderUV[BCELL_LEFT].u1 = u1; - mBorderUV[BCELL_LEFT].u2 = u2; - mBorderUV[BCELL_LEFT].v1 = v1; - mBorderUV[BCELL_LEFT].v2 = v2; - mGeomUVsOutOfDate = true; + mBorderUV[BCELL_LEFT].u1 = u1; + mBorderUV[BCELL_LEFT].u2 = u2; + mBorderUV[BCELL_LEFT].v1 = v1; + mBorderUV[BCELL_LEFT].v2 = v2; + mGeomUVsOutOfDate = true; } //--------------------------------------------------------------------- void BorderPanelOverlayElement::setRightBorderUV(Real u1, Real v1, Real u2, Real v2) { - mBorderUV[BCELL_RIGHT].u1 = u1; - mBorderUV[BCELL_RIGHT].u2 = u2; - mBorderUV[BCELL_RIGHT].v1 = v1; - mBorderUV[BCELL_RIGHT].v2 = v2; - mGeomUVsOutOfDate = true; + mBorderUV[BCELL_RIGHT].u1 = u1; + mBorderUV[BCELL_RIGHT].u2 = u2; + mBorderUV[BCELL_RIGHT].v1 = v1; + mBorderUV[BCELL_RIGHT].v2 = v2; + mGeomUVsOutOfDate = true; } //--------------------------------------------------------------------- void BorderPanelOverlayElement::setTopBorderUV(Real u1, Real v1, Real u2, Real v2) { - mBorderUV[BCELL_TOP].u1 = u1; - mBorderUV[BCELL_TOP].u2 = u2; - mBorderUV[BCELL_TOP].v1 = v1; - mBorderUV[BCELL_TOP].v2 = v2; - mGeomUVsOutOfDate = true; + mBorderUV[BCELL_TOP].u1 = u1; + mBorderUV[BCELL_TOP].u2 = u2; + mBorderUV[BCELL_TOP].v1 = v1; + mBorderUV[BCELL_TOP].v2 = v2; + mGeomUVsOutOfDate = true; } //--------------------------------------------------------------------- void BorderPanelOverlayElement::setBottomBorderUV(Real u1, Real v1, Real u2, Real v2) { - mBorderUV[BCELL_BOTTOM].u1 = u1; - mBorderUV[BCELL_BOTTOM].u2 = u2; - mBorderUV[BCELL_BOTTOM].v1 = v1; - mBorderUV[BCELL_BOTTOM].v2 = v2; - mGeomUVsOutOfDate = true; + mBorderUV[BCELL_BOTTOM].u1 = u1; + mBorderUV[BCELL_BOTTOM].u2 = u2; + mBorderUV[BCELL_BOTTOM].v1 = v1; + mBorderUV[BCELL_BOTTOM].v2 = v2; + mGeomUVsOutOfDate = true; } //--------------------------------------------------------------------- void BorderPanelOverlayElement::setTopLeftBorderUV(Real u1, Real v1, Real u2, Real v2) { - mBorderUV[BCELL_TOP_LEFT].u1 = u1; - mBorderUV[BCELL_TOP_LEFT].u2 = u2; - mBorderUV[BCELL_TOP_LEFT].v1 = v1; - mBorderUV[BCELL_TOP_LEFT].v2 = v2; - mGeomUVsOutOfDate = true; + mBorderUV[BCELL_TOP_LEFT].u1 = u1; + mBorderUV[BCELL_TOP_LEFT].u2 = u2; + mBorderUV[BCELL_TOP_LEFT].v1 = v1; + mBorderUV[BCELL_TOP_LEFT].v2 = v2; + mGeomUVsOutOfDate = true; } //--------------------------------------------------------------------- void BorderPanelOverlayElement::setTopRightBorderUV(Real u1, Real v1, Real u2, Real v2) { - mBorderUV[BCELL_TOP_RIGHT].u1 = u1; - mBorderUV[BCELL_TOP_RIGHT].u2 = u2; - mBorderUV[BCELL_TOP_RIGHT].v1 = v1; - mBorderUV[BCELL_TOP_RIGHT].v2 = v2; - mGeomUVsOutOfDate = true; + mBorderUV[BCELL_TOP_RIGHT].u1 = u1; + mBorderUV[BCELL_TOP_RIGHT].u2 = u2; + mBorderUV[BCELL_TOP_RIGHT].v1 = v1; + mBorderUV[BCELL_TOP_RIGHT].v2 = v2; + mGeomUVsOutOfDate = true; } //--------------------------------------------------------------------- void BorderPanelOverlayElement::setBottomLeftBorderUV(Real u1, Real v1, Real u2, Real v2) { - mBorderUV[BCELL_BOTTOM_LEFT].u1 = u1; - mBorderUV[BCELL_BOTTOM_LEFT].u2 = u2; - mBorderUV[BCELL_BOTTOM_LEFT].v1 = v1; - mBorderUV[BCELL_BOTTOM_LEFT].v2 = v2; - mGeomUVsOutOfDate = true; + mBorderUV[BCELL_BOTTOM_LEFT].u1 = u1; + mBorderUV[BCELL_BOTTOM_LEFT].u2 = u2; + mBorderUV[BCELL_BOTTOM_LEFT].v1 = v1; + mBorderUV[BCELL_BOTTOM_LEFT].v2 = v2; + mGeomUVsOutOfDate = true; } //--------------------------------------------------------------------- void BorderPanelOverlayElement::setBottomRightBorderUV(Real u1, Real v1, Real u2, Real v2) { - mBorderUV[BCELL_BOTTOM_RIGHT].u1 = u1; - mBorderUV[BCELL_BOTTOM_RIGHT].u2 = u2; - mBorderUV[BCELL_BOTTOM_RIGHT].v1 = v1; - mBorderUV[BCELL_BOTTOM_RIGHT].v2 = v2; - mGeomUVsOutOfDate = true; + mBorderUV[BCELL_BOTTOM_RIGHT].u1 = u1; + mBorderUV[BCELL_BOTTOM_RIGHT].u2 = u2; + mBorderUV[BCELL_BOTTOM_RIGHT].v1 = v1; + mBorderUV[BCELL_BOTTOM_RIGHT].v2 = v2; + mGeomUVsOutOfDate = true; } //--------------------------------------------------------------------- @@ -487,8 +487,8 @@ namespace Ogre { mBorderMaterialName = name; mBorderMaterial = MaterialManager::getSingleton().getByName(name); if (mBorderMaterial.isNull()) - OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + name, - "BorderPanelOverlayElement::setBorderMaterialName" ); + OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + name, + "BorderPanelOverlayElement::setBorderMaterialName" ); mBorderMaterial->load(); // Set some prerequisites to be sure mBorderMaterial->setLightingEnabled(false); @@ -503,92 +503,92 @@ namespace Ogre { //--------------------------------------------------------------------- void BorderPanelOverlayElement::updatePositionGeometry(void) { - /* - Grid is like this: - +--+---------------+--+ - |0 | 1 |2 | - +--+---------------+--+ - | | | | - | | | | - |3 | center |4 | - | | | | - +--+---------------+--+ - |5 | 6 |7 | - +--+---------------+--+ - */ - // Convert positions into -1, 1 coordinate space (homogenous clip space) - // Top / bottom also need inverting since y is upside down - Real left[8], right[8], top[8], bottom[8]; - // Horizontal - left[0] = left[3] = left[5] = _getDerivedLeft() * 2 - 1; - left[1] = left[6] = right[0] = right[3] = right[5] = left[0] + (mLeftBorderSize * 2); - right[2] = right[4] = right[7] = left[0] + (mWidth * 2); - left[2] = left[4] = left[7] = right[1] = right[6] = right[2] - (mRightBorderSize * 2); - // Vertical - top[0] = top[1] = top[2] = -((_getDerivedTop() * 2) - 1); - top[3] = top[4] = bottom[0] = bottom[1] = bottom[2] = top[0] - (mTopBorderSize * 2); - bottom[5] = bottom[6] = bottom[7] = top[0] - (mHeight * 2); - top[5] = top[6] = top[7] = bottom[3] = bottom[4] = bottom[5] + (mBottomBorderSize * 2); - - // Lock the whole position buffer in discard mode - HardwareVertexBufferSharedPtr vbuf = - mRenderOp2.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); - float* pPos = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD, Root::getSingleton().getFreqUpdatedBuffersUploadOption()) ); - // Use the furthest away depth value, since materials should have depth-check off - // This initialised the depth buffer for any 3D objects in front - Real zValue = Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue(); - for (ushort cell = 0; cell < 8; ++cell) - { - /* - 0-----2 - | /| - | / | - |/ | - 1-----3 - */ - *pPos++ = left[cell]; - *pPos++ = top[cell]; - *pPos++ = zValue; - - *pPos++ = left[cell]; - *pPos++ = bottom[cell]; - *pPos++ = zValue; - - *pPos++ = right[cell]; - *pPos++ = top[cell]; - *pPos++ = zValue; - - *pPos++ = right[cell]; - *pPos++ = bottom[cell]; - *pPos++ = zValue; - - } - vbuf->unlock(); - - // Also update center geometry - // NB don't use superclass because we need to make it smaller because of border - vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); - pPos = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD, Root::getSingleton().getFreqUpdatedBuffersUploadOption()) ); - // Use cell 1 and 3 to determine positions - *pPos++ = left[1]; - *pPos++ = top[3]; - *pPos++ = zValue; - - *pPos++ = left[1]; - *pPos++ = bottom[3]; - *pPos++ = zValue; - - *pPos++ = right[1]; - *pPos++ = top[3]; - *pPos++ = zValue; - - *pPos++ = right[1]; - *pPos++ = bottom[3]; - *pPos++ = zValue; - - vbuf->unlock(); + /* + Grid is like this: + +--+---------------+--+ + |0 | 1 |2 | + +--+---------------+--+ + | | | | + | | | | + |3 | center |4 | + | | | | + +--+---------------+--+ + |5 | 6 |7 | + +--+---------------+--+ + */ + // Convert positions into -1, 1 coordinate space (homogenous clip space) + // Top / bottom also need inverting since y is upside down + Real left[8], right[8], top[8], bottom[8]; + // Horizontal + left[0] = left[3] = left[5] = _getDerivedLeft() * 2 - 1; + left[1] = left[6] = right[0] = right[3] = right[5] = left[0] + (mLeftBorderSize * 2); + right[2] = right[4] = right[7] = left[0] + (mWidth * 2); + left[2] = left[4] = left[7] = right[1] = right[6] = right[2] - (mRightBorderSize * 2); + // Vertical + top[0] = top[1] = top[2] = -((_getDerivedTop() * 2) - 1); + top[3] = top[4] = bottom[0] = bottom[1] = bottom[2] = top[0] - (mTopBorderSize * 2); + bottom[5] = bottom[6] = bottom[7] = top[0] - (mHeight * 2); + top[5] = top[6] = top[7] = bottom[3] = bottom[4] = bottom[5] + (mBottomBorderSize * 2); + + // Lock the whole position buffer in discard mode + HardwareVertexBufferSharedPtr vbuf = + mRenderOp2.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); + float* pPos = static_cast( + vbuf->lock(HardwareBuffer::HBL_DISCARD, Root::getSingleton().getFreqUpdatedBuffersUploadOption()) ); + // Use the furthest away depth value, since materials should have depth-check off + // This initialised the depth buffer for any 3D objects in front + Real zValue = Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue(); + for (ushort cell = 0; cell < 8; ++cell) + { + /* + 0-----2 + | /| + | / | + |/ | + 1-----3 + */ + *pPos++ = left[cell]; + *pPos++ = top[cell]; + *pPos++ = zValue; + + *pPos++ = left[cell]; + *pPos++ = bottom[cell]; + *pPos++ = zValue; + + *pPos++ = right[cell]; + *pPos++ = top[cell]; + *pPos++ = zValue; + + *pPos++ = right[cell]; + *pPos++ = bottom[cell]; + *pPos++ = zValue; + + } + vbuf->unlock(); + + // Also update center geometry + // NB don't use superclass because we need to make it smaller because of border + vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); + pPos = static_cast( + vbuf->lock(HardwareBuffer::HBL_DISCARD, Root::getSingleton().getFreqUpdatedBuffersUploadOption()) ); + // Use cell 1 and 3 to determine positions + *pPos++ = left[1]; + *pPos++ = top[3]; + *pPos++ = zValue; + + *pPos++ = left[1]; + *pPos++ = bottom[3]; + *pPos++ = zValue; + + *pPos++ = right[1]; + *pPos++ = top[3]; + *pPos++ = zValue; + + *pPos++ = right[1]; + *pPos++ = bottom[3]; + *pPos++ = zValue; + + vbuf->unlock(); } //--------------------------------------------------------------------- void BorderPanelOverlayElement::_updateRenderQueue(RenderQueue* queue) @@ -601,18 +601,18 @@ namespace Ogre { // Add outer queue->addRenderable(mBorderRenderable, RENDER_QUEUE_OVERLAY, mZOrder); - // do inner last so the border artifacts don't overwrite the children + // do inner last so the border artifacts don't overwrite the children // Add inner PanelOverlayElement::_updateRenderQueue(queue); } } - //--------------------------------------------------------------------- - void BorderPanelOverlayElement::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - visitor->visit(mBorderRenderable, 0, false); - PanelOverlayElement::visitRenderables(visitor, debugRenderables); - } + //--------------------------------------------------------------------- + void BorderPanelOverlayElement::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + visitor->visit(mBorderRenderable, 0, false); + PanelOverlayElement::visitRenderables(visitor, debugRenderables); + } //----------------------------------------------------------------------- void BorderPanelOverlayElement::setMetricsMode(GuiMetricsMode gmm) { @@ -637,7 +637,7 @@ namespace Ogre { mBottomBorderSize = mPixelBottomBorderSize * mPixelScaleY; mGeomPositionsOutOfDate = true; } - PanelOverlayElement::_update(); + PanelOverlayElement::_update(); } //----------------------------------------------------------------------- //--------------------------------------------------------------------- @@ -647,12 +647,12 @@ namespace Ogre { //----------------------------------------------------------------------- String BorderPanelOverlayElement::CmdBorderSize::doGet(const void* target) const { - const BorderPanelOverlayElement* t = static_cast(target); + const BorderPanelOverlayElement* t = static_cast(target); return String( - StringConverter::toString(t->getLeftBorderSize()) + " " + - StringConverter::toString(t->getRightBorderSize()) + " " + - StringConverter::toString(t->getTopBorderSize()) + " " + - StringConverter::toString(t->getBottomBorderSize()) ); + StringConverter::toString(t->getLeftBorderSize()) + " " + + StringConverter::toString(t->getRightBorderSize()) + " " + + StringConverter::toString(t->getTopBorderSize()) + " " + + StringConverter::toString(t->getBottomBorderSize()) ); } void BorderPanelOverlayElement::CmdBorderSize::doSet(void* target, const String& val) { @@ -681,7 +681,7 @@ namespace Ogre { String BorderPanelOverlayElement::CmdBorderBottomLeftUV::doGet(const void* target) const { // No need right now.. - return static_cast(target)->getBottomLeftBorderUVString(); + return static_cast(target)->getBottomLeftBorderUVString(); } void BorderPanelOverlayElement::CmdBorderBottomLeftUV::doSet(void* target, const String& val) { @@ -698,7 +698,7 @@ namespace Ogre { String BorderPanelOverlayElement::CmdBorderBottomRightUV::doGet(const void* target) const { // No need right now.. - return static_cast(target)->getBottomRightBorderUVString(); + return static_cast(target)->getBottomRightBorderUVString(); } void BorderPanelOverlayElement::CmdBorderBottomRightUV::doSet(void* target, const String& val) { @@ -715,7 +715,7 @@ namespace Ogre { String BorderPanelOverlayElement::CmdBorderTopLeftUV::doGet(const void* target) const { // No need right now.. - return static_cast(target)->getTopLeftBorderUVString(); + return static_cast(target)->getTopLeftBorderUVString(); } void BorderPanelOverlayElement::CmdBorderTopLeftUV::doSet(void* target, const String& val) { @@ -732,7 +732,7 @@ namespace Ogre { String BorderPanelOverlayElement::CmdBorderTopRightUV::doGet(const void* target) const { // No need right now.. - return static_cast(target)->getTopRightBorderUVString(); + return static_cast(target)->getTopRightBorderUVString(); } void BorderPanelOverlayElement::CmdBorderTopRightUV::doSet(void* target, const String& val) { @@ -749,7 +749,7 @@ namespace Ogre { String BorderPanelOverlayElement::CmdBorderLeftUV::doGet(const void* target) const { // No need right now.. - return static_cast(target)->getLeftBorderUVString(); + return static_cast(target)->getLeftBorderUVString(); } void BorderPanelOverlayElement::CmdBorderLeftUV::doSet(void* target, const String& val) { @@ -766,7 +766,7 @@ namespace Ogre { String BorderPanelOverlayElement::CmdBorderRightUV::doGet(const void* target) const { // No need right now.. - return static_cast(target)->getRightBorderUVString(); + return static_cast(target)->getRightBorderUVString(); } void BorderPanelOverlayElement::CmdBorderRightUV::doSet(void* target, const String& val) { @@ -783,7 +783,7 @@ namespace Ogre { String BorderPanelOverlayElement::CmdBorderTopUV::doGet(const void* target) const { // No need right now.. - return static_cast(target)->getTopBorderUVString(); + return static_cast(target)->getTopBorderUVString(); } void BorderPanelOverlayElement::CmdBorderTopUV::doSet(void* target, const String& val) { @@ -800,7 +800,7 @@ namespace Ogre { String BorderPanelOverlayElement::CmdBorderBottomUV::doGet(const void* target) const { // No need right now.. - return static_cast(target)->getBottomBorderUVString(); + return static_cast(target)->getBottomBorderUVString(); } void BorderPanelOverlayElement::CmdBorderBottomUV::doSet(void* target, const String& val) { diff --git a/Components/Overlay/src/OgreFont.cpp b/Components/Overlay/src/OgreFont.cpp index 2063b23ad84..404705a1c2b 100644 --- a/Components/Overlay/src/OgreFont.cpp +++ b/Components/Overlay/src/OgreFont.cpp @@ -35,7 +35,7 @@ THE SOFTWARE #include "OgreTechnique.h" #include "OgreBitwise.h" -#define generic _generic // keyword for C++/CX +#define generic _generic // keyword for C++/CX #include #include FT_FREETYPE_H #include FT_GLYPH_H @@ -46,42 +46,42 @@ THE SOFTWARE namespace Ogre { //--------------------------------------------------------------------- - Font::CmdType Font::msTypeCmd; - Font::CmdSource Font::msSourceCmd; - Font::CmdCharSpacer Font::msCharacterSpacerCmd; - Font::CmdSize Font::msSizeCmd; - Font::CmdResolution Font::msResolutionCmd; - Font::CmdCodePoints Font::msCodePointsCmd; + Font::CmdType Font::msTypeCmd; + Font::CmdSource Font::msSourceCmd; + Font::CmdCharSpacer Font::msCharacterSpacerCmd; + Font::CmdSize Font::msSizeCmd; + Font::CmdResolution Font::msResolutionCmd; + Font::CmdCodePoints Font::msCodePointsCmd; //--------------------------------------------------------------------- - Font::Font(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader) - :Resource (creator, name, handle, group, isManual, loader), - mType(FT_TRUETYPE), mCharacterSpacer(5), mTtfSize(0), mTtfResolution(0), mTtfMaxBearingY(0), mAntialiasColour(false) + Font::Font(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader) + :Resource (creator, name, handle, group, isManual, loader), + mType(FT_TRUETYPE), mCharacterSpacer(5), mTtfSize(0), mTtfResolution(0), mTtfMaxBearingY(0), mAntialiasColour(false) { - if (createParamDictionary("Font")) - { - ParamDictionary* dict = getParamDictionary(); - dict->addParameter( - ParameterDef("type", "'truetype' or 'image' based font", PT_STRING), - &msTypeCmd); - dict->addParameter( - ParameterDef("source", "Filename of the source of the font.", PT_STRING), - &msSourceCmd); - dict->addParameter( - ParameterDef("character_spacer", "Spacing between characters to prevent overlap artifacts.", PT_STRING), - &msCharacterSpacerCmd); - dict->addParameter( - ParameterDef("size", "True type size", PT_REAL), - &msSizeCmd); - dict->addParameter( - ParameterDef("resolution", "True type resolution", PT_UNSIGNED_INT), - &msResolutionCmd); - dict->addParameter( - ParameterDef("code_points", "Add a range of code points", PT_STRING), - &msCodePointsCmd); - } + if (createParamDictionary("Font")) + { + ParamDictionary* dict = getParamDictionary(); + dict->addParameter( + ParameterDef("type", "'truetype' or 'image' based font", PT_STRING), + &msTypeCmd); + dict->addParameter( + ParameterDef("source", "Filename of the source of the font.", PT_STRING), + &msSourceCmd); + dict->addParameter( + ParameterDef("character_spacer", "Spacing between characters to prevent overlap artifacts.", PT_STRING), + &msCharacterSpacerCmd); + dict->addParameter( + ParameterDef("size", "True type size", PT_REAL), + &msSizeCmd); + dict->addParameter( + ParameterDef("resolution", "True type resolution", PT_UNSIGNED_INT), + &msResolutionCmd); + dict->addParameter( + ParameterDef("code_points", "Add a range of code points", PT_STRING), + &msCodePointsCmd); + } } //--------------------------------------------------------------------- @@ -141,23 +141,23 @@ namespace Ogre { return mTtfResolution; } - //--------------------------------------------------------------------- - int Font::getTrueTypeMaxBearingY() const - { - return mTtfMaxBearingY; - } - //--------------------------------------------------------------------- - const Font::GlyphInfo& Font::getGlyphInfo(CodePoint id) const - { - CodePointMap::const_iterator i = mCodePointMap.find(id); - if (i == mCodePointMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Code point " + StringConverter::toString(id) + " not found in font " - + mName, "Font::getGlyphInfo"); - } - return i->second; - } + //--------------------------------------------------------------------- + int Font::getTrueTypeMaxBearingY() const + { + return mTtfMaxBearingY; + } + //--------------------------------------------------------------------- + const Font::GlyphInfo& Font::getGlyphInfo(CodePoint id) const + { + CodePointMap::const_iterator i = mCodePointMap.find(id); + if (i == mCodePointMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Code point " + StringConverter::toString(id) + " not found in font " + + mName, "Font::getGlyphInfo"); + } + return i->second; + } //--------------------------------------------------------------------- void Font::loadImpl() { @@ -165,7 +165,7 @@ namespace Ogre mMaterial = MaterialManager::getSingleton().create( "Fonts/" + mName, mGroup); - if (mMaterial.isNull()) + if (mMaterial.isNull()) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Error creating new material!", "Font::load" ); @@ -182,18 +182,18 @@ namespace Ogre } else { - // Manually load since we need to load to get alpha - mTexture = TextureManager::getSingleton().load(mSource, mGroup, TEX_TYPE_2D, 0); + // Manually load since we need to load to get alpha + mTexture = TextureManager::getSingleton().load(mSource, mGroup, TEX_TYPE_2D, 0); blendByAlpha = mTexture->hasAlpha(); texLayer = mMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(mSource); } - // Make sure material is aware of colour per vertex. - mMaterial->getTechnique(0)->getPass(0)->setVertexColourTracking(TVC_DIFFUSE); + // Make sure material is aware of colour per vertex. + mMaterial->getTechnique(0)->getPass(0)->setVertexColourTracking(TVC_DIFFUSE); // Clamp to avoid fuzzy edges texLayer->setTextureAddressingMode( TextureUnitState::TAM_CLAMP ); - // Allow min/mag filter, but no mip - texLayer->setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_NONE); + // Allow min/mag filter, but no mip + texLayer->setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_NONE); // Set up blending @@ -210,43 +210,43 @@ namespace Ogre //--------------------------------------------------------------------- void Font::unloadImpl() { - if (!mMaterial.isNull()) - { - MaterialManager::getSingleton().remove(mMaterial->getHandle()); - mMaterial.setNull(); - } - - if (!mTexture.isNull()) - { + if (!mMaterial.isNull()) + { + MaterialManager::getSingleton().remove(mMaterial->getHandle()); + mMaterial.setNull(); + } + + if (!mTexture.isNull()) + { mTexture->unload(); - mTexture.setNull(); - } + mTexture.setNull(); + } } //--------------------------------------------------------------------- void Font::createTextureFromFont(void) { - // Just create the texture here, and point it at ourselves for when - // it wants to (re)load for real - String texName = mName + "Texture"; - // Create, setting isManual to true and passing self as loader - mTexture = TextureManager::getSingleton().create( - texName, mGroup, true, this); - mTexture->setTextureType(TEX_TYPE_2D); - mTexture->setNumMipmaps(0); - mTexture->load(); - - TextureUnitState* t = mMaterial->getTechnique(0)->getPass(0)->createTextureUnitState( texName ); - // Allow min/mag filter, but no mip - t->setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_NONE); - - } - //--------------------------------------------------------------------- - void Font::loadResource(Resource* res) - { - // ManualResourceLoader implementation - load the texture - FT_Library ftLibrary; - // Init freetype + // Just create the texture here, and point it at ourselves for when + // it wants to (re)load for real + String texName = mName + "Texture"; + // Create, setting isManual to true and passing self as loader + mTexture = TextureManager::getSingleton().create( + texName, mGroup, true, this); + mTexture->setTextureType(TEX_TYPE_2D); + mTexture->setNumMipmaps(0); + mTexture->load(); + + TextureUnitState* t = mMaterial->getTechnique(0)->getPass(0)->createTextureUnitState( texName ); + // Allow min/mag filter, but no mip + t->setTextureFiltering(FO_LINEAR, FO_LINEAR, FO_NONE); + + } + //--------------------------------------------------------------------- + void Font::loadResource(Resource* res) + { + // ManualResourceLoader implementation - load the texture + FT_Library ftLibrary; + // Init freetype if( FT_Init_FreeType( &ftLibrary ) ) OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Could not init FreeType library!", "Font::Font"); @@ -254,11 +254,11 @@ namespace Ogre FT_Face face; // Locate ttf file, load it pre-buffered into memory by wrapping the - // original DataStream in a MemoryDataStream - DataStreamPtr dataStreamPtr = - ResourceGroupManager::getSingleton().openResource( - mSource, mGroup, true, this); - MemoryDataStream ttfchunk(dataStreamPtr); + // original DataStream in a MemoryDataStream + DataStreamPtr dataStreamPtr = + ResourceGroupManager::getSingleton().openResource( + mSource, mGroup, true, this); + MemoryDataStream ttfchunk(dataStreamPtr); // Load font if( FT_New_Memory_Face( ftLibrary, ttfchunk.getPtr(), (FT_Long)ttfchunk.size() , 0, &face ) ) @@ -276,66 +276,66 @@ namespace Ogre FT_Pos max_height = 0, max_width = 0; - // Backwards compatibility - if codepoints not supplied, assume 33-166 - if (mCodePointRangeList.empty()) - { - mCodePointRangeList.push_back(CodePointRange(33, 166)); - } - - // Calculate maximum width, height and bearing - size_t glyphCount = 0; - for (CodePointRangeList::const_iterator r = mCodePointRangeList.begin(); - r != mCodePointRangeList.end(); ++r) - { - const CodePointRange& range = *r; - for(CodePoint cp = range.first; cp <= range.second; ++cp, ++glyphCount) - { - FT_Load_Char( face, cp, FT_LOAD_RENDER ); - - if( ( 2 * ( face->glyph->bitmap.rows << 6 ) - face->glyph->metrics.horiBearingY ) > max_height ) - max_height = ( 2 * ( face->glyph->bitmap.rows << 6 ) - face->glyph->metrics.horiBearingY ); - if( face->glyph->metrics.horiBearingY > mTtfMaxBearingY ) - mTtfMaxBearingY = static_cast(face->glyph->metrics.horiBearingY); - - if( (face->glyph->advance.x >> 6 ) + ( face->glyph->metrics.horiBearingX >> 6 ) > max_width) - max_width = (face->glyph->advance.x >> 6 ) + ( face->glyph->metrics.horiBearingX >> 6 ); - } - - } - - // Now work out how big our texture needs to be - size_t rawSize = (max_width + mCharacterSpacer) * - ((max_height >> 6) + mCharacterSpacer) * glyphCount; - - uint32 tex_side = static_cast(Math::Sqrt((Real)rawSize)); - // just in case the size might chop a glyph in half, add another glyph width/height - tex_side += std::max(max_width, (max_height>>6)); - // Now round up to nearest power of two - uint32 roundUpSize = Bitwise::firstPO2From(tex_side); - - // Would we benefit from using a non-square texture (2X width) - uint32 finalWidth, finalHeight; - if (roundUpSize * roundUpSize * 0.5 >= rawSize) - { - finalHeight = static_cast(roundUpSize * 0.5); - } - else - { - finalHeight = roundUpSize; - } - finalWidth = roundUpSize; - - Real textureAspect = (Real)finalWidth / (Real)finalHeight; - - const size_t pixel_bytes = 2; - size_t data_width = finalWidth * pixel_bytes; - size_t data_size = finalWidth * finalHeight * pixel_bytes; - - LogManager::getSingleton().logMessage("Font " + mName + " using texture size " + - StringConverter::toString(finalWidth) + "x" + StringConverter::toString(finalHeight)); + // Backwards compatibility - if codepoints not supplied, assume 33-166 + if (mCodePointRangeList.empty()) + { + mCodePointRangeList.push_back(CodePointRange(33, 166)); + } + + // Calculate maximum width, height and bearing + size_t glyphCount = 0; + for (CodePointRangeList::const_iterator r = mCodePointRangeList.begin(); + r != mCodePointRangeList.end(); ++r) + { + const CodePointRange& range = *r; + for(CodePoint cp = range.first; cp <= range.second; ++cp, ++glyphCount) + { + FT_Load_Char( face, cp, FT_LOAD_RENDER ); + + if( ( 2 * ( face->glyph->bitmap.rows << 6 ) - face->glyph->metrics.horiBearingY ) > max_height ) + max_height = ( 2 * ( face->glyph->bitmap.rows << 6 ) - face->glyph->metrics.horiBearingY ); + if( face->glyph->metrics.horiBearingY > mTtfMaxBearingY ) + mTtfMaxBearingY = static_cast(face->glyph->metrics.horiBearingY); + + if( (face->glyph->advance.x >> 6 ) + ( face->glyph->metrics.horiBearingX >> 6 ) > max_width) + max_width = (face->glyph->advance.x >> 6 ) + ( face->glyph->metrics.horiBearingX >> 6 ); + } + + } + + // Now work out how big our texture needs to be + size_t rawSize = (max_width + mCharacterSpacer) * + ((max_height >> 6) + mCharacterSpacer) * glyphCount; + + uint32 tex_side = static_cast(Math::Sqrt((Real)rawSize)); + // just in case the size might chop a glyph in half, add another glyph width/height + tex_side += std::max(max_width, (max_height>>6)); + // Now round up to nearest power of two + uint32 roundUpSize = Bitwise::firstPO2From(tex_side); + + // Would we benefit from using a non-square texture (2X width) + uint32 finalWidth, finalHeight; + if (roundUpSize * roundUpSize * 0.5 >= rawSize) + { + finalHeight = static_cast(roundUpSize * 0.5); + } + else + { + finalHeight = roundUpSize; + } + finalWidth = roundUpSize; + + Real textureAspect = (Real)finalWidth / (Real)finalHeight; + + const size_t pixel_bytes = 2; + size_t data_width = finalWidth * pixel_bytes; + size_t data_size = finalWidth * finalHeight * pixel_bytes; + + LogManager::getSingleton().logMessage("Font " + mName + " using texture size " + + StringConverter::toString(finalWidth) + "x" + StringConverter::toString(finalHeight)); uchar* imageData = OGRE_ALLOC_T(uchar, data_size, MEMCATEGORY_GENERAL); - // Reset content (White, transparent) + // Reset content (White, transparent) for (size_t i = 0; i < data_size; i += pixel_bytes) { imageData[i + 0] = 0xFF; // luminance @@ -343,199 +343,199 @@ namespace Ogre } size_t l = 0, m = 0; - for (CodePointRangeList::const_iterator r = mCodePointRangeList.begin(); - r != mCodePointRangeList.end(); ++r) - { - const CodePointRange& range = *r; - for(CodePoint cp = range.first; cp <= range.second; ++cp ) - { - FT_Error ftResult; - - // Load & render glyph - ftResult = FT_Load_Char( face, cp, FT_LOAD_RENDER ); - if (ftResult) - { - // problem loading this glyph, continue - LogManager::getSingleton().logMessage("Info: cannot load character " + - StringConverter::toString(cp) + " in font " + mName, LML_CRITICAL); - continue; - } - - FT_Pos advance = face->glyph->advance.x >> 6; - - unsigned char* buffer = face->glyph->bitmap.buffer; - - if (!buffer) - { - // Yuck, FT didn't detect this but generated a null pointer! - LogManager::getSingleton().logMessage("Info: Freetype returned null for character " + - StringConverter::toString(cp) + " in font " + mName); - continue; - } - - FT_Pos y_bearing = ( mTtfMaxBearingY >> 6 ) - ( face->glyph->metrics.horiBearingY >> 6 ); - FT_Pos x_bearing = face->glyph->metrics.horiBearingX >> 6; - - for(int j = 0; j < face->glyph->bitmap.rows; j++ ) - { - size_t row = j + m + y_bearing; - uchar* pDest = &imageData[(row * data_width) + (l + x_bearing) * pixel_bytes]; - for(int k = 0; k < face->glyph->bitmap.width; k++ ) - { - if (mAntialiasColour) - { - // Use the same greyscale pixel for all components RGBA - *pDest++= *buffer; - } - else - { - // Always white whether 'on' or 'off' pixel, since alpha - // will turn off - *pDest++= 0xFF; - } - // Always use the greyscale value for alpha - *pDest++= *buffer++; - } - } - - this->setGlyphTexCoords(cp, - (Real)l / (Real)finalWidth, // u1 - (Real)m / (Real)finalHeight, // v1 - (Real)( l + ( face->glyph->advance.x >> 6 ) ) / (Real)finalWidth, // u2 - ( m + ( max_height >> 6 ) ) / (Real)finalHeight, // v2 - textureAspect - ); - - // Advance a column - l += (advance + mCharacterSpacer); - - // If at end of row - if( finalWidth - 1 < l + ( advance ) ) - { - m += ( max_height >> 6 ) + mCharacterSpacer; - l = 0; - } - } - } + for (CodePointRangeList::const_iterator r = mCodePointRangeList.begin(); + r != mCodePointRangeList.end(); ++r) + { + const CodePointRange& range = *r; + for(CodePoint cp = range.first; cp <= range.second; ++cp ) + { + FT_Error ftResult; + + // Load & render glyph + ftResult = FT_Load_Char( face, cp, FT_LOAD_RENDER ); + if (ftResult) + { + // problem loading this glyph, continue + LogManager::getSingleton().logMessage("Info: cannot load character " + + StringConverter::toString(cp) + " in font " + mName, LML_CRITICAL); + continue; + } + + FT_Pos advance = face->glyph->advance.x >> 6; + + unsigned char* buffer = face->glyph->bitmap.buffer; + + if (!buffer) + { + // Yuck, FT didn't detect this but generated a null pointer! + LogManager::getSingleton().logMessage("Info: Freetype returned null for character " + + StringConverter::toString(cp) + " in font " + mName); + continue; + } + + FT_Pos y_bearing = ( mTtfMaxBearingY >> 6 ) - ( face->glyph->metrics.horiBearingY >> 6 ); + FT_Pos x_bearing = face->glyph->metrics.horiBearingX >> 6; + + for(int j = 0; j < face->glyph->bitmap.rows; j++ ) + { + size_t row = j + m + y_bearing; + uchar* pDest = &imageData[(row * data_width) + (l + x_bearing) * pixel_bytes]; + for(int k = 0; k < face->glyph->bitmap.width; k++ ) + { + if (mAntialiasColour) + { + // Use the same greyscale pixel for all components RGBA + *pDest++= *buffer; + } + else + { + // Always white whether 'on' or 'off' pixel, since alpha + // will turn off + *pDest++= 0xFF; + } + // Always use the greyscale value for alpha + *pDest++= *buffer++; + } + } + + this->setGlyphTexCoords(cp, + (Real)l / (Real)finalWidth, // u1 + (Real)m / (Real)finalHeight, // v1 + (Real)( l + ( face->glyph->advance.x >> 6 ) ) / (Real)finalWidth, // u2 + ( m + ( max_height >> 6 ) ) / (Real)finalHeight, // v2 + textureAspect + ); + + // Advance a column + l += (advance + mCharacterSpacer); + + // If at end of row + if( finalWidth - 1 < l + ( advance ) ) + { + m += ( max_height >> 6 ) + mCharacterSpacer; + l = 0; + } + } + } DataStreamPtr memStream( - OGRE_NEW MemoryDataStream(imageData, data_size, true)); + OGRE_NEW MemoryDataStream(imageData, data_size, true)); Image img; - img.loadRawData( memStream, finalWidth, finalHeight, PF_BYTE_LA ); + img.loadRawData( memStream, finalWidth, finalHeight, PF_BYTE_LA ); + + Texture* tex = static_cast(res); + // Call internal _loadImages, not loadImage since that's external and + // will determine load status etc again, and this is a manual loader inside load() + ConstImagePtrList imagePtrs; + imagePtrs.push_back(&img); + tex->_loadImages( imagePtrs ); - Texture* tex = static_cast(res); - // Call internal _loadImages, not loadImage since that's external and - // will determine load status etc again, and this is a manual loader inside load() - ConstImagePtrList imagePtrs; - imagePtrs.push_back(&img); - tex->_loadImages( imagePtrs ); + FT_Done_FreeType(ftLibrary); + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + String Font::CmdType::doGet(const void* target) const + { + const Font* f = static_cast(target); + if (f->getType() == FT_TRUETYPE) + { + return "truetype"; + } + else + { + return "image"; + } + } + void Font::CmdType::doSet(void* target, const String& val) + { + Font* f = static_cast(target); + if (val == "truetype") + { + f->setType(FT_TRUETYPE); + } + else + { + f->setType(FT_IMAGE); + } + } + //----------------------------------------------------------------------- + String Font::CmdSource::doGet(const void* target) const + { + const Font* f = static_cast(target); + return f->getSource(); + } + void Font::CmdSource::doSet(void* target, const String& val) + { + Font* f = static_cast(target); + f->setSource(val); + } + //----------------------------------------------------------------------- + String Font::CmdCharSpacer::doGet(const void* target) const + { + const Font* f = static_cast(target); + char buf[sizeof(uint)]; + sprintf(buf, "%d", f->getCharacterSpacer()); + return String(buf); + } + void Font::CmdCharSpacer::doSet(void* target, const String& val) + { + Font* f = static_cast(target); + f->setCharacterSpacer(atoi(val.c_str())); + } + //----------------------------------------------------------------------- + String Font::CmdSize::doGet(const void* target) const + { + const Font* f = static_cast(target); + return StringConverter::toString(f->getTrueTypeSize()); + } + void Font::CmdSize::doSet(void* target, const String& val) + { + Font* f = static_cast(target); + f->setTrueTypeSize(StringConverter::parseReal(val)); + } + //----------------------------------------------------------------------- + String Font::CmdResolution::doGet(const void* target) const + { + const Font* f = static_cast(target); + return StringConverter::toString(f->getTrueTypeResolution()); + } + void Font::CmdResolution::doSet(void* target, const String& val) + { + Font* f = static_cast(target); + f->setTrueTypeResolution(StringConverter::parseUnsignedInt(val)); + } + //----------------------------------------------------------------------- + String Font::CmdCodePoints::doGet(const void* target) const + { + const Font* f = static_cast(target); + const CodePointRangeList& rangeList = f->getCodePointRangeList(); + StringStream str; + for (CodePointRangeList::const_iterator i = rangeList.begin(); i != rangeList.end(); ++i) + { + str << i->first << "-" << i->second << " "; + } + return str.str(); + } + void Font::CmdCodePoints::doSet(void* target, const String& val) + { + // Format is "code_points start1-end1 start2-end2" + Font* f = static_cast(target); - FT_Done_FreeType(ftLibrary); + StringVector vec = StringUtil::split(val, " \t"); + for (StringVector::iterator i = vec.begin(); i != vec.end(); ++i) + { + String& item = *i; + StringVector itemVec = StringUtil::split(item, "-"); + if (itemVec.size() == 2) + { + f->addCodePointRange(CodePointRange( + StringConverter::parseUnsignedInt(itemVec[0]), + StringConverter::parseUnsignedInt(itemVec[1]))); + } + } } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - String Font::CmdType::doGet(const void* target) const - { - const Font* f = static_cast(target); - if (f->getType() == FT_TRUETYPE) - { - return "truetype"; - } - else - { - return "image"; - } - } - void Font::CmdType::doSet(void* target, const String& val) - { - Font* f = static_cast(target); - if (val == "truetype") - { - f->setType(FT_TRUETYPE); - } - else - { - f->setType(FT_IMAGE); - } - } - //----------------------------------------------------------------------- - String Font::CmdSource::doGet(const void* target) const - { - const Font* f = static_cast(target); - return f->getSource(); - } - void Font::CmdSource::doSet(void* target, const String& val) - { - Font* f = static_cast(target); - f->setSource(val); - } - //----------------------------------------------------------------------- - String Font::CmdCharSpacer::doGet(const void* target) const - { - const Font* f = static_cast(target); - char buf[sizeof(uint)]; - sprintf(buf, "%d", f->getCharacterSpacer()); - return String(buf); - } - void Font::CmdCharSpacer::doSet(void* target, const String& val) - { - Font* f = static_cast(target); - f->setCharacterSpacer(atoi(val.c_str())); - } - //----------------------------------------------------------------------- - String Font::CmdSize::doGet(const void* target) const - { - const Font* f = static_cast(target); - return StringConverter::toString(f->getTrueTypeSize()); - } - void Font::CmdSize::doSet(void* target, const String& val) - { - Font* f = static_cast(target); - f->setTrueTypeSize(StringConverter::parseReal(val)); - } - //----------------------------------------------------------------------- - String Font::CmdResolution::doGet(const void* target) const - { - const Font* f = static_cast(target); - return StringConverter::toString(f->getTrueTypeResolution()); - } - void Font::CmdResolution::doSet(void* target, const String& val) - { - Font* f = static_cast(target); - f->setTrueTypeResolution(StringConverter::parseUnsignedInt(val)); - } - //----------------------------------------------------------------------- - String Font::CmdCodePoints::doGet(const void* target) const - { - const Font* f = static_cast(target); - const CodePointRangeList& rangeList = f->getCodePointRangeList(); - StringStream str; - for (CodePointRangeList::const_iterator i = rangeList.begin(); i != rangeList.end(); ++i) - { - str << i->first << "-" << i->second << " "; - } - return str.str(); - } - void Font::CmdCodePoints::doSet(void* target, const String& val) - { - // Format is "code_points start1-end1 start2-end2" - Font* f = static_cast(target); - - StringVector vec = StringUtil::split(val, " \t"); - for (StringVector::iterator i = vec.begin(); i != vec.end(); ++i) - { - String& item = *i; - StringVector itemVec = StringUtil::split(item, "-"); - if (itemVec.size() == 2) - { - f->addCodePointRange(CodePointRange( - StringConverter::parseUnsignedInt(itemVec[0]), - StringConverter::parseUnsignedInt(itemVec[1]))); - } - } - } } diff --git a/Components/Overlay/src/OgreFontManager.cpp b/Components/Overlay/src/OgreFontManager.cpp index b2aa69510b1..79e76cc253c 100644 --- a/Components/Overlay/src/OgreFontManager.cpp +++ b/Components/Overlay/src/OgreFontManager.cpp @@ -44,52 +44,52 @@ namespace Ogre assert( msSingleton ); return ( *msSingleton ); } //--------------------------------------------------------------------- - FontManager::FontManager() : ResourceManager() - { + FontManager::FontManager() : ResourceManager() + { // Loading order mLoadOrder = 200.0f; - // Scripting is supported by this manager - mScriptPatterns.push_back("*.fontdef"); - // Register scripting with resource group manager - ResourceGroupManager::getSingleton()._registerScriptLoader(this); + // Scripting is supported by this manager + mScriptPatterns.push_back("*.fontdef"); + // Register scripting with resource group manager + ResourceGroupManager::getSingleton()._registerScriptLoader(this); - // Resource type - mResourceType = "Font"; + // Resource type + mResourceType = "Font"; - // Register with resource group manager - ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); + // Register with resource group manager + ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); - } - //--------------------------------------------------------------------- - FontManager::~FontManager() - { - // Unregister with resource group manager - ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); - // Unegister scripting with resource group manager - ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); + } + //--------------------------------------------------------------------- + FontManager::~FontManager() + { + // Unregister with resource group manager + ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); + // Unegister scripting with resource group manager + ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); - } - //--------------------------------------------------------------------- - Resource* FontManager::createImpl(const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, + } + //--------------------------------------------------------------------- + Resource* FontManager::createImpl(const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* params) - { - return OGRE_NEW Font(this, name, handle, group, isManual, loader); - } - //----------------------------------------------------------------------- - FontPtr FontManager::getByName(const String& name, const String& groupName) - { - return getResourceByName(name, groupName).staticCast(); - } - //--------------------------------------------------------------------- - FontPtr FontManager::create (const String& name, const String& group, - bool isManual, ManualResourceLoader* loader, - const NameValuePairList* createParams) - { - return createResource(name,group,isManual,loader,createParams).staticCast(); - } - //--------------------------------------------------------------------- + { + return OGRE_NEW Font(this, name, handle, group, isManual, loader); + } + //----------------------------------------------------------------------- + FontPtr FontManager::getByName(const String& name, const String& groupName) + { + return getResourceByName(name, groupName).staticCast(); + } + //--------------------------------------------------------------------- + FontPtr FontManager::create (const String& name, const String& group, + bool isManual, ManualResourceLoader* loader, + const NameValuePairList* createParams) + { + return createResource(name,group,isManual,loader,createParams).staticCast(); + } + //--------------------------------------------------------------------- void FontManager::parseScript(DataStreamPtr& stream, const String& groupName) { String line; @@ -105,29 +105,29 @@ namespace Ogre } else { - if (pFont.isNull()) - { - // No current font - // So first valid data should be font name - if (StringUtil::startsWith(line, "font ")) - { - // chop off the 'particle_system ' needed by new compilers - line = line.substr(5); - } - pFont = create(line, groupName); - pFont->_notifyOrigin(stream->getName()); - // Skip to and over next { + if (pFont.isNull()) + { + // No current font + // So first valid data should be font name + if (StringUtil::startsWith(line, "font ")) + { + // chop off the 'particle_system ' needed by new compilers + line = line.substr(5); + } + pFont = create(line, groupName); + pFont->_notifyOrigin(stream->getName()); + // Skip to and over next { stream->skipLine("{"); - } - else - { - // Already in font - if (line == "}") - { - // Finished - pFont.setNull(); + } + else + { + // Already in font + if (line == "}") + { + // Finished + pFont.setNull(); // NB font isn't loaded until required - } + } else { parseAttribute(line, pFont); @@ -141,7 +141,7 @@ namespace Ogre { vector::type params = StringUtil::split(line); String& attrib = params[0]; - StringUtil::toLowerCase(attrib); + StringUtil::toLowerCase(attrib); if (attrib == "type") { // Check params @@ -151,7 +151,7 @@ namespace Ogre return; } // Set - StringUtil::toLowerCase(params[1]); + StringUtil::toLowerCase(params[1]); if (params[1] == "truetype") { pFont->setType(FT_TRUETYPE); @@ -182,19 +182,19 @@ namespace Ogre return; } // Set - // Support numeric and character glyph specification - Font::CodePoint cp; - if (params[1].at(0) == 'u' && params[1].size() > 1) - { - // Unicode glyph spec - String trimmed = params[1].substr(1); - cp = StringConverter::parseUnsignedInt(trimmed); - } - else - { - // Direct character - cp = params[1].at(0); - } + // Support numeric and character glyph specification + Font::CodePoint cp; + if (params[1].at(0) == 'u' && params[1].size() > 1) + { + // Unicode glyph spec + String trimmed = params[1].substr(1); + cp = StringConverter::parseUnsignedInt(trimmed); + } + else + { + // Direct character + cp = params[1].at(0); + } pFont->setGlyphTexCoords( cp, StringConverter::parseReal(params[2]), @@ -240,29 +240,29 @@ namespace Ogre } else if (attrib == "antialias_colour") { - // Check params - if (params.size() != 2) - { + // Check params + if (params.size() != 2) + { logBadAttrib(line, pFont); return; - } - // Set + } + // Set pFont->setAntialiasColour(StringConverter::parseBool(params[1])); } - else if (attrib == "code_points") - { - for (size_t c = 1; c < params.size(); ++c) - { - String& item = params[c]; - StringVector itemVec = StringUtil::split(item, "-"); - if (itemVec.size() == 2) - { - pFont->addCodePointRange(Font::CodePointRange( - StringConverter::parseUnsignedInt(itemVec[0]), - StringConverter::parseUnsignedInt(itemVec[1]))); - } - } - } + else if (attrib == "code_points") + { + for (size_t c = 1; c < params.size(); ++c) + { + String& item = params[c]; + StringVector itemVec = StringUtil::split(item, "-"); + if (itemVec.size() == 2) + { + pFont->addCodePointRange(Font::CodePointRange( + StringConverter::parseUnsignedInt(itemVec[0]), + StringConverter::parseUnsignedInt(itemVec[1]))); + } + } + } } //--------------------------------------------------------------------- diff --git a/Components/Overlay/src/OgreOverlay.cpp b/Components/Overlay/src/OgreOverlay.cpp index d1839c7d9a7..837d9aa6cde 100644 --- a/Components/Overlay/src/OgreOverlay.cpp +++ b/Components/Overlay/src/OgreOverlay.cpp @@ -52,15 +52,15 @@ namespace Ogre { //--------------------------------------------------------------------- Overlay::~Overlay() { - // remove children + // remove children OGRE_DELETE mRootNode; - - for (OverlayContainerList::iterator i = m2DElements.begin(); - i != m2DElements.end(); ++i) - { - (*i)->_notifyParent(0, 0); - } + + for (OverlayContainerList::iterator i = m2DElements.begin(); + i != m2DElements.end(); ++i) + { + (*i)->_notifyParent(0, 0); + } } //--------------------------------------------------------------------- const String& Overlay::getName(void) const @@ -69,8 +69,8 @@ namespace Ogre { } //--------------------------------------------------------------------- void Overlay::assignZOrders() - { - ushort zorder = static_cast(mZOrder * 100.0f); + { + ushort zorder = static_cast(mZOrder * 100.0f); // Notify attached 2D elements OverlayContainerList::iterator i, iend; @@ -79,7 +79,7 @@ namespace Ogre { { zorder = (*i)->_notifyZOrder(zorder); } - } + } //--------------------------------------------------------------------- void Overlay::setZOrder(ushort zorder) { @@ -88,7 +88,7 @@ namespace Ogre { mZOrder = zorder; - assignZOrders(); + assignZOrders(); } //--------------------------------------------------------------------- ushort Overlay::getZOrder(void) const @@ -104,10 +104,10 @@ namespace Ogre { void Overlay::show(void) { mVisible = true; - if (!mInitialised) - { - initialise(); - } + if (!mInitialised) + { + initialise(); + } } //--------------------------------------------------------------------- void Overlay::hide(void) @@ -115,24 +115,24 @@ namespace Ogre { mVisible = false; } //--------------------------------------------------------------------- - void Overlay::initialise(void) - { - OverlayContainerList::iterator i, iend; - iend = m2DElements.end(); - for (i = m2DElements.begin(); i != m2DElements.end(); ++i) - { - (*i)->initialise(); - } - mInitialised = true; - } - //--------------------------------------------------------------------- + void Overlay::initialise(void) + { + OverlayContainerList::iterator i, iend; + iend = m2DElements.end(); + for (i = m2DElements.begin(); i != m2DElements.end(); ++i) + { + (*i)->initialise(); + } + mInitialised = true; + } + //--------------------------------------------------------------------- void Overlay::add2D(OverlayContainer* cont) { m2DElements.push_back(cont); // Notify parent cont->_notifyParent(0, this); - assignZOrders(); + assignZOrders(); Matrix4 xform; _getWorldTransforms(&xform); @@ -143,8 +143,8 @@ namespace Ogre { void Overlay::remove2D(OverlayContainer* cont) { m2DElements.remove(cont); - cont->_notifyParent(0, 0); - assignZOrders(); + cont->_notifyParent(0, 0); + assignZOrders(); } //--------------------------------------------------------------------- void Overlay::add3D(SceneNode* node) @@ -190,10 +190,10 @@ namespace Ogre { for (i = m2DElements.begin(); i != iend; ++i) { if ((*i)->getName() == name) - { - return *i; + { + return *i; - } + } } return NULL; } @@ -331,27 +331,27 @@ namespace Ogre { mTransformOutOfDate = false; } //--------------------------------------------------------------------- - OverlayElement* Overlay::findElementAt(Real x, Real y) - { - OverlayElement* ret = NULL; - int currZ = -1; + OverlayElement* Overlay::findElementAt(Real x, Real y) + { + OverlayElement* ret = NULL; + int currZ = -1; OverlayContainerList::iterator i, iend; iend = m2DElements.end(); for (i = m2DElements.begin(); i != iend; ++i) { - int z = (*i)->getZOrder(); - if (z > currZ) - { - OverlayElement* elementFound = (*i)->findElementAt(x,y); - if(elementFound) - { - currZ = elementFound->getZOrder(); - ret = elementFound; - } - } + int z = (*i)->getZOrder(); + if (z > currZ) + { + OverlayElement* elementFound = (*i)->findElementAt(x,y); + if(elementFound) + { + currZ = elementFound->getZOrder(); + ret = elementFound; + } + } } - return ret; - } + return ret; + } } diff --git a/Components/Overlay/src/OgreOverlayContainer.cpp b/Components/Overlay/src/OgreOverlayContainer.cpp index 2c053e7b62f..2b7b180ed6d 100644 --- a/Components/Overlay/src/OgreOverlayContainer.cpp +++ b/Components/Overlay/src/OgreOverlayContainer.cpp @@ -36,38 +36,38 @@ namespace Ogre { //--------------------------------------------------------------------- OverlayContainer::OverlayContainer(const String& name) : OverlayElement(name), - mChildrenProcessEvents(true) + mChildrenProcessEvents(true) { } //--------------------------------------------------------------------- OverlayContainer::~OverlayContainer() { - // remove from parent overlay if root - if (mOverlay && !mParent) - { - mOverlay->remove2D(this); - } + // remove from parent overlay if root + if (mOverlay && !mParent) + { + mOverlay->remove2D(this); + } OverlayContainer::ChildIterator ci = getChildIterator(); while (ci.hasMoreElements()) { OverlayElement* child = ci.getNext(); - child->_notifyParent(0, 0); + child->_notifyParent(0, 0); } } //--------------------------------------------------------------------- void OverlayContainer::addChild(OverlayElement* elem) { if (elem->isContainer()) - { - addChildImpl(static_cast(elem)); - } - else - { - addChildImpl(elem); - } - - } + { + addChildImpl(static_cast(elem)); + } + else + { + addChildImpl(elem); + } + + } //--------------------------------------------------------------------- void OverlayContainer::addChildImpl(OverlayElement* elem) { @@ -82,9 +82,9 @@ namespace Ogre { mChildren.insert(ChildMap::value_type(name, elem)); // tell child about parent & Z-order elem->_notifyParent(this, mOverlay); - elem->_notifyZOrder(mZOrder + 1); - elem->_notifyWorldTransforms(mXForm); - elem->_notifyViewport(); + elem->_notifyZOrder(mZOrder + 1); + elem->_notifyWorldTransforms(mXForm); + elem->_notifyViewport(); } //--------------------------------------------------------------------- @@ -98,17 +98,17 @@ namespace Ogre { /* cont->_notifyParent(this, mOverlay); cont->_notifyZOrder(mZOrder + 1); - cont->_notifyWorldTransforms(mXForm); + cont->_notifyWorldTransforms(mXForm); - // tell children of new container the current overlay + // tell children of new container the current overlay ChildIterator it = cont->getChildIterator(); while (it.hasMoreElements()) { // Give children Z-order 1 higher than this GuiElement* pElemChild = it.getNext(); - pElemChild->_notifyParent(cont, mOverlay); + pElemChild->_notifyParent(cont, mOverlay); pElemChild->_notifyZOrder(cont->getZOrder() + 1); - pElemChild->_notifyWorldTransforms(mXForm); + pElemChild->_notifyWorldTransforms(mXForm); } */ @@ -140,14 +140,14 @@ namespace Ogre { void OverlayContainer::_addChild(OverlayElement* elem) { if (elem->isContainer()) - { - addChildImpl(static_cast(elem)); - } - else - { - addChildImpl(elem); - } - } + { + addChildImpl(static_cast(elem)); + } + else + { + addChildImpl(elem); + } + } //--------------------------------------------------------------------- void OverlayContainer::_removeChild(const String& name) { @@ -190,31 +190,31 @@ namespace Ogre { { return ChildContainerIterator(mChildContainers.begin(), mChildContainers.end()); } - //--------------------------------------------------------------------- - void OverlayContainer::initialise(void) - { - ChildContainerMap::iterator coni; - for (coni = mChildContainers.begin(); coni != mChildContainers.end(); ++coni) - { - coni->second->initialise(); - } - ChildMap::iterator ci; - for (ci = mChildren.begin(); ci != mChildren.end(); ++ci) - { - ci->second->initialise(); - } - } //--------------------------------------------------------------------- - void OverlayContainer::_positionsOutOfDate(void) - { - OverlayElement::_positionsOutOfDate(); + void OverlayContainer::initialise(void) + { + ChildContainerMap::iterator coni; + for (coni = mChildContainers.begin(); coni != mChildContainers.end(); ++coni) + { + coni->second->initialise(); + } + ChildMap::iterator ci; + for (ci = mChildren.begin(); ci != mChildren.end(); ++ci) + { + ci->second->initialise(); + } + } + //--------------------------------------------------------------------- + void OverlayContainer::_positionsOutOfDate(void) + { + OverlayElement::_positionsOutOfDate(); ChildIterator it = getChildIterator(); while (it.hasMoreElements()) { - it.getNext()->_positionsOutOfDate(); + it.getNext()->_positionsOutOfDate(); } - } + } //--------------------------------------------------------------------- void OverlayContainer::_update(void) @@ -233,8 +233,8 @@ namespace Ogre { ushort OverlayContainer::_notifyZOrder(ushort newZOrder) { OverlayElement::_notifyZOrder(newZOrder); - // One for us - newZOrder++; + // One for us + newZOrder++; // Update children ChildIterator it = getChildIterator(); @@ -244,7 +244,7 @@ namespace Ogre { newZOrder = it.getNext()->_notifyZOrder(newZOrder); } - return newZOrder; + return newZOrder; } //--------------------------------------------------------------------- void OverlayContainer::_notifyWorldTransforms(const Matrix4& xform) @@ -304,61 +304,61 @@ namespace Ogre { } - OverlayElement* OverlayContainer::findElementAt(Real x, Real y) // relative to parent - { - - OverlayElement* ret = NULL; - - int currZ = -1; - - if (mVisible) - { - ret = OverlayElement::findElementAt(x,y); //default to the current container if no others are found - if (ret && mChildrenProcessEvents) - { - ChildIterator it = getChildIterator(); - while (it.hasMoreElements()) - { - OverlayElement* currentOverlayElement = it.getNext(); - if (currentOverlayElement->isVisible() && currentOverlayElement->isEnabled()) - { - int z = currentOverlayElement->getZOrder(); - if (z > currZ) - { - OverlayElement* elementFound = currentOverlayElement->findElementAt(x ,y ); - if (elementFound) - { - currZ = z; - ret = elementFound; - } - } - } - } - } - } - return ret; - } + OverlayElement* OverlayContainer::findElementAt(Real x, Real y) // relative to parent + { + + OverlayElement* ret = NULL; + + int currZ = -1; + + if (mVisible) + { + ret = OverlayElement::findElementAt(x,y); //default to the current container if no others are found + if (ret && mChildrenProcessEvents) + { + ChildIterator it = getChildIterator(); + while (it.hasMoreElements()) + { + OverlayElement* currentOverlayElement = it.getNext(); + if (currentOverlayElement->isVisible() && currentOverlayElement->isEnabled()) + { + int z = currentOverlayElement->getZOrder(); + if (z > currZ) + { + OverlayElement* elementFound = currentOverlayElement->findElementAt(x ,y ); + if (elementFound) + { + currZ = z; + ret = elementFound; + } + } + } + } + } + } + return ret; + } void OverlayContainer::copyFromTemplate(OverlayElement* templateOverlay) { OverlayElement::copyFromTemplate(templateOverlay); - if (templateOverlay->isContainer() && isContainer()) - { - OverlayContainer::ChildIterator it = static_cast(templateOverlay)->getChildIterator(); - while (it.hasMoreElements()) - { - OverlayElement* oldChildElement = it.getNext(); - if (oldChildElement->isCloneable()) - { - OverlayElement* newChildElement = - OverlayManager::getSingleton().createOverlayElement( - oldChildElement->getTypeName(), - mName+"/"+oldChildElement->getName()); - newChildElement->copyFromTemplate(oldChildElement); - addChild(static_cast(newChildElement)); - } - } + if (templateOverlay->isContainer() && isContainer()) + { + OverlayContainer::ChildIterator it = static_cast(templateOverlay)->getChildIterator(); + while (it.hasMoreElements()) + { + OverlayElement* oldChildElement = it.getNext(); + if (oldChildElement->isCloneable()) + { + OverlayElement* newChildElement = + OverlayManager::getSingleton().createOverlayElement( + oldChildElement->getTypeName(), + mName+"/"+oldChildElement->getName()); + newChildElement->copyFromTemplate(oldChildElement); + addChild(static_cast(newChildElement)); + } + } } } @@ -368,12 +368,12 @@ namespace Ogre { newContainer = static_cast(OverlayElement::clone(instanceName)); - ChildIterator it = getChildIterator(); - while (it.hasMoreElements()) - { - OverlayElement* oldChildElement = it.getNext(); - if (oldChildElement->isCloneable()) - { + ChildIterator it = getChildIterator(); + while (it.hasMoreElements()) + { + OverlayElement* oldChildElement = it.getNext(); + if (oldChildElement->isCloneable()) + { OverlayElement* newChildElement = oldChildElement->clone(instanceName); newContainer->_addChild(newChildElement); } diff --git a/Components/Overlay/src/OgreOverlayElement.cpp b/Components/Overlay/src/OgreOverlayElement.cpp index e9920589b13..de9977ad6df 100644 --- a/Components/Overlay/src/OgreOverlayElement.cpp +++ b/Components/Overlay/src/OgreOverlayElement.cpp @@ -81,8 +81,8 @@ namespace Ogre { , mInitialised(false) , mSourceTemplate(0) { - // default overlays to preserve their own detail level - mPolygonModeOverrideable = false; + // default overlays to preserve their own detail level + mPolygonModeOverrideable = false; // use identity projection and view matrices mUseIdentityProjection = true; @@ -91,11 +91,11 @@ namespace Ogre { //--------------------------------------------------------------------- OverlayElement::~OverlayElement() { - if (mParent) - { - mParent->removeChild(mName); - mParent = 0; - } + if (mParent) + { + mParent->removeChild(mName); + mParent = 0; + } } //--------------------------------------------------------------------- const String& OverlayElement::getName(void) const @@ -168,12 +168,12 @@ namespace Ogre { { if (mMetricsMode != GMM_RELATIVE) { - return mPixelWidth; - } - else - { - return mWidth; - } + return mPixelWidth; + } + else + { + return mWidth; + } } //--------------------------------------------------------------------- void OverlayElement::setHeight(Real height) @@ -194,12 +194,12 @@ namespace Ogre { { if (mMetricsMode != GMM_RELATIVE) { - return mPixelHeight; - } - else - { - return mHeight; - } + return mPixelHeight; + } + else + { + return mHeight; + } } //--------------------------------------------------------------------- void OverlayElement::setLeft(Real left) @@ -220,12 +220,12 @@ namespace Ogre { { if (mMetricsMode != GMM_RELATIVE) { - return mPixelLeft; - } - else - { - return mLeft; - } + return mPixelLeft; + } + else + { + return mLeft; + } } //--------------------------------------------------------------------- void OverlayElement::setTop(Real top) @@ -247,12 +247,12 @@ namespace Ogre { { if (mMetricsMode != GMM_RELATIVE) { - return mPixelTop; - } - else - { - return mTop; - } + return mPixelTop; + } + else + { + return mTop; + } } //--------------------------------------------------------------------- void OverlayElement::_setLeft(Real left) @@ -321,21 +321,21 @@ namespace Ogre { void OverlayElement::setMaterialName(const String& matName) { mMaterialName = matName; - if (matName != BLANKSTRING) - { - mMaterial = MaterialManager::getSingleton().getByName(matName); - if (mMaterial.isNull()) - OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + matName, - "OverlayElement::setMaterialName" ); - mMaterial->load(); - // Set some prerequisites to be sure - mMaterial->setLightingEnabled(false); - mMaterial->setDepthCheckEnabled(false); - } - else - { - mMaterial.setNull(); - } + if (matName != BLANKSTRING) + { + mMaterial = MaterialManager::getSingleton().getByName(matName); + if (mMaterial.isNull()) + OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + matName, + "OverlayElement::setMaterialName" ); + mMaterial->load(); + // Set some prerequisites to be sure + mMaterial->setLightingEnabled(false); + mMaterial->setDepthCheckEnabled(false); + } + else + { + mMaterial.setNull(); + } } //--------------------------------------------------------------------- const MaterialPtr& OverlayElement::getMaterial(void) const @@ -348,10 +348,10 @@ namespace Ogre { mOverlay->_getWorldTransforms(xform); } //--------------------------------------------------------------------- - void OverlayElement::_positionsOutOfDate(void) - { - mGeomPositionsOutOfDate = true; - } + void OverlayElement::_positionsOutOfDate(void) + { + mGeomPositionsOutOfDate = true; + } //--------------------------------------------------------------------- void OverlayElement::_update(void) { @@ -515,10 +515,10 @@ namespace Ogre { mParent = parent; mOverlay = overlay; - if (mOverlay && mOverlay->isInitialised() && !mInitialised) - { - initialise(); - } + if (mOverlay && mOverlay->isInitialised() && !mInitialised) + { + initialise(); + } mDerivedOutOfDate = true; } @@ -540,16 +540,16 @@ namespace Ogre { } return mDerivedTop; } - //--------------------------------------------------------------------- - Real OverlayElement::_getRelativeWidth(void) - { - return mWidth; - } - //--------------------------------------------------------------------- - Real OverlayElement::_getRelativeHeight(void) - { - return mHeight; - } + //--------------------------------------------------------------------- + Real OverlayElement::_getRelativeWidth(void) + { + return mWidth; + } + //--------------------------------------------------------------------- + Real OverlayElement::_getRelativeHeight(void) + { + return mHeight; + } //--------------------------------------------------------------------- void OverlayElement::_getClippingRegion(RealRect &clippingRegion) { @@ -563,7 +563,7 @@ namespace Ogre { ushort OverlayElement::_notifyZOrder(ushort newZOrder) { mZOrder = newZOrder; - return mZOrder + 1; + return mZOrder + 1; } //--------------------------------------------------------------------- void OverlayElement::_notifyWorldTransforms(const Matrix4& xform) @@ -625,12 +625,12 @@ namespace Ogre { queue->addRenderable(this, RENDER_QUEUE_OVERLAY, mZOrder); } } - //--------------------------------------------------------------------- - void OverlayElement::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - visitor->visit(this, 0, false); - } + //--------------------------------------------------------------------- + void OverlayElement::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + visitor->visit(this, 0, false); + } //----------------------------------------------------------------------- void OverlayElement::addBaseParameters(void) { @@ -684,7 +684,7 @@ namespace Ogre { _positionsOutOfDate(); } //----------------------------------------------------------------------- - const DisplayString& OverlayElement::getCaption() const + const DisplayString& OverlayElement::getCaption() const { return mCaption; } @@ -710,9 +710,9 @@ namespace Ogre { vpWidth = (Real) (oMgr.getViewportWidth()); vpHeight = (Real) (oMgr.getViewportHeight()); - // cope with temporarily zero dimensions, avoid divide by zero - vpWidth = vpWidth == 0.0f? 1.0f : vpWidth; - vpHeight = vpHeight == 0.0f? 1.0f : vpHeight; + // cope with temporarily zero dimensions, avoid divide by zero + vpWidth = vpWidth == 0.0f? 1.0f : vpWidth; + vpHeight = vpHeight == 0.0f? 1.0f : vpHeight; mPixelScaleX = 1.0f / vpWidth; mPixelScaleY = 1.0f / vpHeight; @@ -795,53 +795,53 @@ namespace Ogre { return mVertAlign; } //----------------------------------------------------------------------- - bool OverlayElement::contains(Real x, Real y) const - { - return x >= mClippingRegion.left && x <= mClippingRegion.right && y >= mClippingRegion.top && y <= mClippingRegion.bottom; - } + bool OverlayElement::contains(Real x, Real y) const + { + return x >= mClippingRegion.left && x <= mClippingRegion.right && y >= mClippingRegion.top && y <= mClippingRegion.bottom; + } //----------------------------------------------------------------------- - OverlayElement* OverlayElement::findElementAt(Real x, Real y) // relative to parent - { - OverlayElement* ret = NULL; - if (contains(x , y )) - { - ret = this; - } - return ret; - } + OverlayElement* OverlayElement::findElementAt(Real x, Real y) // relative to parent + { + OverlayElement* ret = NULL; + if (contains(x , y )) + { + ret = this; + } + return ret; + } //----------------------------------------------------------------------- - OverlayContainer* OverlayElement::getParent() - { - return mParent; - } + OverlayContainer* OverlayElement::getParent() + { + return mParent; + } //----------------------------------------------------------------------- void OverlayElement::copyFromTemplate(OverlayElement* templateOverlay) - { - templateOverlay->copyParametersTo(this); + { + templateOverlay->copyParametersTo(this); mSourceTemplate = templateOverlay ; - return; - } + return; + } //----------------------------------------------------------------------- OverlayElement* OverlayElement::clone(const String& instanceName) { OverlayElement* newElement; newElement = OverlayManager::getSingleton().createOverlayElement( - getTypeName(), instanceName + "/" + mName); + getTypeName(), instanceName + "/" + mName); copyParametersTo(newElement); return newElement; } //----------------------------------------------------------------------- - bool OverlayElement::isEnabled() const - { - return mEnabled; - } + bool OverlayElement::isEnabled() const + { + return mEnabled; + } //----------------------------------------------------------------------- - void OverlayElement::setEnabled(bool b) - { - mEnabled = b; - } + void OverlayElement::setEnabled(bool b) + { + mEnabled = b; + } //----------------------------------------------------------------------- } diff --git a/Components/Overlay/src/OgreOverlayElementCommands.cpp b/Components/Overlay/src/OgreOverlayElementCommands.cpp index 73a6dca0ad4..6419283360c 100644 --- a/Components/Overlay/src/OgreOverlayElementCommands.cpp +++ b/Components/Overlay/src/OgreOverlayElementCommands.cpp @@ -44,7 +44,7 @@ namespace Ogre { } void CmdLeft::doSet(void* target, const String& val) { - Real r = StringConverter::parseReal(val); + Real r = StringConverter::parseReal(val); static_cast(target)->setLeft(r); } //----------------------------------------------------------------------- @@ -55,7 +55,7 @@ namespace Ogre { } void CmdTop::doSet(void* target, const String& val) { - Real r = StringConverter::parseReal(val); + Real r = StringConverter::parseReal(val); static_cast(target)->setTop(r); } //----------------------------------------------------------------------- @@ -66,7 +66,7 @@ namespace Ogre { } void CmdWidth::doSet(void* target, const String& val) { - Real r = StringConverter::parseReal(val); + Real r = StringConverter::parseReal(val); static_cast(target)->setWidth(r); } //----------------------------------------------------------------------- @@ -77,7 +77,7 @@ namespace Ogre { } void CmdHeight::doSet(void* target, const String& val) { - Real r = StringConverter::parseReal(val); + Real r = StringConverter::parseReal(val); static_cast(target)->setHeight(r); } //----------------------------------------------------------------------- @@ -87,10 +87,10 @@ namespace Ogre { } void CmdMaterial::doSet(void* target, const String& val) { - if (val != "") - { - static_cast(target)->setMaterialName(val); - } + if (val != "") + { + static_cast(target)->setMaterialName(val); + } } //----------------------------------------------------------------------- //----------------------------------------------------------------------- diff --git a/Components/Overlay/src/OgreOverlayManager.cpp b/Components/Overlay/src/OgreOverlayManager.cpp index 6d5de965f75..03c66f067dc 100644 --- a/Components/Overlay/src/OgreOverlayManager.cpp +++ b/Components/Overlay/src/OgreOverlayManager.cpp @@ -58,23 +58,23 @@ namespace Ogre { // Scripting is supported by this manager mScriptPatterns.push_back("*.overlay"); - ResourceGroupManager::getSingleton()._registerScriptLoader(this); + ResourceGroupManager::getSingleton()._registerScriptLoader(this); } //--------------------------------------------------------------------- OverlayManager::~OverlayManager() { - destroyAllOverlayElements(false); - destroyAllOverlayElements(true); + destroyAllOverlayElements(false); + destroyAllOverlayElements(true); destroyAll(); - for(FactoryMap::iterator i = mFactories.begin(); i != mFactories.end(); ++i) + for(FactoryMap::iterator i = mFactories.begin(); i != mFactories.end(); ++i) { OGRE_DELETE i->second; } // Unregister with resource group manager - ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); + ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); } //--------------------------------------------------------------------- const StringVector& OverlayManager::getScriptPatterns(void) const @@ -166,7 +166,7 @@ namespace Ogre { OGRE_DELETE i->second; } mOverlayMap.clear(); - mLoadedScripts.clear(); + mLoadedScripts.clear(); } //--------------------------------------------------------------------- OverlayManager::OverlayMapIterator OverlayManager::getOverlayIterator(void) @@ -176,88 +176,88 @@ namespace Ogre { //--------------------------------------------------------------------- void OverlayManager::parseScript(DataStreamPtr& stream, const String& groupName) { - // check if we've seen this script before (can happen if included - // multiple times) - if (!stream->getName().empty() && - mLoadedScripts.find(stream->getName()) != mLoadedScripts.end()) - { - LogManager::getSingleton().logMessage( - "Skipping loading overlay include: '" - + stream->getName() + " as it is already loaded."); - return; - } - String line; - Overlay* pOverlay = 0; - - while(!stream->eof()) - { - bool isATemplate = false; - bool skipLine = false; - line = stream->getLine(); - // Ignore comments & blanks - if (!(line.length() == 0 || line.substr(0,2) == "//")) - { - if (line.substr(0,8) == "#include") - { + // check if we've seen this script before (can happen if included + // multiple times) + if (!stream->getName().empty() && + mLoadedScripts.find(stream->getName()) != mLoadedScripts.end()) + { + LogManager::getSingleton().logMessage( + "Skipping loading overlay include: '" + + stream->getName() + " as it is already loaded."); + return; + } + String line; + Overlay* pOverlay = 0; + + while(!stream->eof()) + { + bool isATemplate = false; + bool skipLine = false; + line = stream->getLine(); + // Ignore comments & blanks + if (!(line.length() == 0 || line.substr(0,2) == "//")) + { + if (line.substr(0,8) == "#include") + { vector::type params = StringUtil::split(line, "\t\n ()<>"); DataStreamPtr includeStream = ResourceGroupManager::getSingleton().openResource( params[1], groupName); - parseScript(includeStream, groupName); - continue; - } - if (!pOverlay) - { - // No current overlay - - // check to see if there is a template - if (line.substr(0,8) == "template") - { - isATemplate = true; - } - else - { - // So first valid data should be overlay name - if (StringUtil::startsWith(line, "overlay ")) - { - // chop off the 'particle_system ' needed by new compilers - line = line.substr(8); - } - pOverlay = create(line); - pOverlay->_notifyOrigin(stream->getName()); - // Skip to and over next { - skipToNextOpenBrace(stream); - skipLine = true; - } - } - if ((pOverlay && !skipLine) || isATemplate) - { - // Already in overlay + parseScript(includeStream, groupName); + continue; + } + if (!pOverlay) + { + // No current overlay + + // check to see if there is a template + if (line.substr(0,8) == "template") + { + isATemplate = true; + } + else + { + // So first valid data should be overlay name + if (StringUtil::startsWith(line, "overlay ")) + { + // chop off the 'particle_system ' needed by new compilers + line = line.substr(8); + } + pOverlay = create(line); + pOverlay->_notifyOrigin(stream->getName()); + // Skip to and over next { + skipToNextOpenBrace(stream); + skipLine = true; + } + } + if ((pOverlay && !skipLine) || isATemplate) + { + // Already in overlay vector::type params = StringUtil::split(line, "\t\n ()"); - if (line == "}") - { - // Finished overlay - pOverlay = 0; - } - else if (parseChildren(stream,line, pOverlay, isATemplate, NULL)) - { + if (line == "}") + { + // Finished overlay + pOverlay = 0; + } + else if (parseChildren(stream,line, pOverlay, isATemplate, NULL)) + { - } - else - { - // Attribute - if (!isATemplate) - { - parseAttrib(line, pOverlay); - } - } - } - } - } + } + else + { + // Attribute + if (!isATemplate) + { + parseAttrib(line, pOverlay); + } + } + } + } + } - // record as parsed - mLoadedScripts.insert(stream->getName()); + // record as parsed + mLoadedScripts.insert(stream->getName()); } //--------------------------------------------------------------------- @@ -306,23 +306,23 @@ namespace Ogre { { String line; - OverlayElement* newElement = NULL; - newElement = - OverlayManager::getSingleton().createOverlayElementFromTemplate(templateName, elemType, elemName, isATemplate); + OverlayElement* newElement = NULL; + newElement = + OverlayManager::getSingleton().createOverlayElementFromTemplate(templateName, elemType, elemName, isATemplate); - // do not add a template to an overlay + // do not add a template to an overlay - // add new element to parent - if (container) - { - // Attach to container - container->addChild(newElement); - } - // do not add a template to the overlay. For templates overlay = 0 - else if (pOverlay) - { - pOverlay->add2D((OverlayContainer*)newElement); - } + // add new element to parent + if (container) + { + // Attach to container + container->addChild(newElement); + } + // do not add a template to the overlay. For templates overlay = 0 + else if (pOverlay) + { + pOverlay->add2D((OverlayContainer*)newElement); + } while(!stream->eof()) { @@ -339,7 +339,7 @@ namespace Ogre { { if (isContainer && parseChildren(stream,line, pOverlay, isATemplate, static_cast(newElement))) { - // nested children... don't reparse it + // nested children... don't reparse it } else { @@ -354,70 +354,70 @@ namespace Ogre { //--------------------------------------------------------------------- bool OverlayManager::parseChildren( DataStreamPtr& stream, const String& line, Overlay* pOverlay, bool isATemplate, OverlayContainer* parent) - { - bool ret = false; - uint skipParam =0; - vector::type params = StringUtil::split(line, "\t\n ()"); - - if (isATemplate) - { - if (params[0] == "template") - { - skipParam++; // the first param = 'template' on a new child element - } - } - - // top level component cannot be an element, it must be a container unless it is a template - if (params[0+skipParam] == "container" || (params[0+skipParam] == "element" && (isATemplate || parent != NULL)) ) - { - String templateName; - ret = true; - // nested container/element - if (params.size() > 3+skipParam) - { - if (params.size() != 5+skipParam) - { - LogManager::getSingleton().logMessage( - "Bad element/container line: '" - + line + "' in " + parent->getTypeName()+ " " + parent->getName() + - ", expecting ':' templateName", LML_CRITICAL); - skipToNextCloseBrace(stream); - // barf - return ret; - } - if (params[3+skipParam] != ":") - { - LogManager::getSingleton().logMessage( - "Bad element/container line: '" - + line + "' in " + parent->getTypeName()+ " " + parent->getName() + - ", expecting ':' for element inheritance", LML_CRITICAL); - skipToNextCloseBrace(stream); - // barf - return ret; - } - - templateName = params[4+skipParam]; - } - - else if (params.size() != 3+skipParam) - { - LogManager::getSingleton().logMessage( - "Bad element/container line: '" - + line + "' in " + parent->getTypeName()+ " " + parent->getName() + - ", expecting 'element type(name)'"); - skipToNextCloseBrace(stream); - // barf - return ret; - } + { + bool ret = false; + uint skipParam =0; + vector::type params = StringUtil::split(line, "\t\n ()"); + + if (isATemplate) + { + if (params[0] == "template") + { + skipParam++; // the first param = 'template' on a new child element + } + } + + // top level component cannot be an element, it must be a container unless it is a template + if (params[0+skipParam] == "container" || (params[0+skipParam] == "element" && (isATemplate || parent != NULL)) ) + { + String templateName; + ret = true; + // nested container/element + if (params.size() > 3+skipParam) + { + if (params.size() != 5+skipParam) + { + LogManager::getSingleton().logMessage( + "Bad element/container line: '" + + line + "' in " + parent->getTypeName()+ " " + parent->getName() + + ", expecting ':' templateName", LML_CRITICAL); + skipToNextCloseBrace(stream); + // barf + return ret; + } + if (params[3+skipParam] != ":") + { + LogManager::getSingleton().logMessage( + "Bad element/container line: '" + + line + "' in " + parent->getTypeName()+ " " + parent->getName() + + ", expecting ':' for element inheritance", LML_CRITICAL); + skipToNextCloseBrace(stream); + // barf + return ret; + } + + templateName = params[4+skipParam]; + } + + else if (params.size() != 3+skipParam) + { + LogManager::getSingleton().logMessage( + "Bad element/container line: '" + + line + "' in " + parent->getTypeName()+ " " + parent->getName() + + ", expecting 'element type(name)'"); + skipToNextCloseBrace(stream); + // barf + return ret; + } - skipToNextOpenBrace(stream); - parseNewElement(stream, params[1+skipParam], params[2+skipParam], true, pOverlay, isATemplate, templateName, (OverlayContainer*)parent); + skipToNextOpenBrace(stream); + parseNewElement(stream, params[1+skipParam], params[2+skipParam], true, pOverlay, isATemplate, templateName, (OverlayContainer*)parent); - } + } - return ret; - } + return ret; + } //--------------------------------------------------------------------- void OverlayManager::parseAttrib( const String& line, Overlay* pOverlay) @@ -426,7 +426,7 @@ namespace Ogre { vector::type vecparams = StringUtil::split(line, "\t ", 1); // Look up first param (command setting) - StringUtil::toLowerCase(vecparams[0]); + StringUtil::toLowerCase(vecparams[0]); if (vecparams[0] == "zorder") { pOverlay->setZOrder((ushort)StringConverter::parseUnsignedInt(vecparams[1])); @@ -444,7 +444,7 @@ namespace Ogre { vector::type vecparams = StringUtil::split(line, "\t ", 1); // Look up first param (command setting) - StringUtil::toLowerCase(vecparams[0]); + StringUtil::toLowerCase(vecparams[0]); if (!pElement->setParameter(vecparams[0], vecparams[1])) { // BAD command. BAD! @@ -503,201 +503,201 @@ namespace Ogre { #endif return mLastViewportOrientationMode; } - //--------------------------------------------------------------------- - OverlayManager::ElementMap& OverlayManager::getElementMap(bool isATemplate) - { - return (isATemplate)?mTemplates:mInstances; - } - - //--------------------------------------------------------------------- - OverlayElement* OverlayManager::createOverlayElementFromTemplate(const String& templateName, const String& typeName, const String& instanceName, bool isATemplate) - { - - OverlayElement* newObj = NULL; - - if (templateName.empty()) - { - newObj = createOverlayElement(typeName, instanceName, isATemplate); - } - else - { - // no template - OverlayElement* templateGui = getOverlayElement(templateName, true); - - String typeNameToCreate; - if (typeName.empty()) - { - typeNameToCreate = templateGui->getTypeName(); - } - else - { - typeNameToCreate = typeName; - } - - newObj = createOverlayElement(typeNameToCreate, instanceName, isATemplate); - - ((OverlayContainer*)newObj)->copyFromTemplate(templateGui); - } - - return newObj; - } - - - //--------------------------------------------------------------------- - OverlayElement* OverlayManager::cloneOverlayElementFromTemplate(const String& templateName, const String& instanceName) - { - OverlayElement* templateGui = getOverlayElement(templateName, true); - return templateGui->clone(instanceName); - } - - //--------------------------------------------------------------------- - OverlayElement* OverlayManager::createOverlayElement(const String& typeName, const String& instanceName, bool isATemplate) - { - return createOverlayElementImpl(typeName, instanceName, getElementMap(isATemplate)); - } - - //--------------------------------------------------------------------- - OverlayElement* OverlayManager::createOverlayElementImpl(const String& typeName, const String& instanceName, ElementMap& elementMap) - { - // Check not duplicated - ElementMap::iterator ii = elementMap.find(instanceName); - if (ii != elementMap.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "OverlayElement with name " + instanceName + - " already exists.", "OverlayManager::createOverlayElement" ); - } - OverlayElement* newElem = createOverlayElementFromFactory(typeName, instanceName); - - // Register - elementMap.insert(ElementMap::value_type(instanceName, newElem)); - - return newElem; - - - } - - //--------------------------------------------------------------------- - OverlayElement* OverlayManager::createOverlayElementFromFactory(const String& typeName, const String& instanceName) - { - // Look up factory - FactoryMap::iterator fi = mFactories.find(typeName); - if (fi == mFactories.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate factory for element type " + typeName, - "OverlayManager::createOverlayElement"); - } - - // create - return fi->second->createOverlayElement(instanceName); - } - - //--------------------------------------------------------------------- - OverlayElement* OverlayManager::getOverlayElement(const String& name, bool isATemplate) - { - return getOverlayElementImpl(name, getElementMap(isATemplate)); - } - //--------------------------------------------------------------------- - bool OverlayManager::hasOverlayElement(const String& name, bool isATemplate) - { - return hasOverlayElementImpl(name, getElementMap(isATemplate)); - } - //--------------------------------------------------------------------- - OverlayElement* OverlayManager::getOverlayElementImpl(const String& name, ElementMap& elementMap) - { - // Locate instance - ElementMap::iterator ii = elementMap.find(name); - if (ii == elementMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "OverlayElement with name " + name + - " not found.", "OverlayManager::getOverlayElementImpl" ); - } - - return ii->second; - } - //--------------------------------------------------------------------- - bool OverlayManager::hasOverlayElementImpl(const String& name, ElementMap& elementMap) - { - ElementMap::iterator ii = elementMap.find(name); - return ii != elementMap.end(); - } - //--------------------------------------------------------------------- - void OverlayManager::destroyOverlayElement(const String& instanceName, bool isATemplate) - { - destroyOverlayElementImpl(instanceName, getElementMap(isATemplate)); - } - - //--------------------------------------------------------------------- - void OverlayManager::destroyOverlayElement(OverlayElement* pInstance, bool isATemplate) - { - destroyOverlayElementImpl(pInstance->getName(), getElementMap(isATemplate)); - } - - //--------------------------------------------------------------------- - void OverlayManager::destroyOverlayElementImpl(const String& instanceName, ElementMap& elementMap) - { - // Locate instance - ElementMap::iterator ii = elementMap.find(instanceName); - if (ii == elementMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "OverlayElement with name " + instanceName + - " not found.", "OverlayManager::destroyOverlayElement" ); - } - // Look up factory - const String& typeName = ii->second->getTypeName(); - FactoryMap::iterator fi = mFactories.find(typeName); - if (fi == mFactories.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate factory for element type " + typeName, - "OverlayManager::destroyOverlayElement"); - } - - fi->second->destroyOverlayElement(ii->second); - elementMap.erase(ii); - } - //--------------------------------------------------------------------- - void OverlayManager::destroyAllOverlayElements(bool isATemplate) - { - destroyAllOverlayElementsImpl(getElementMap(isATemplate)); - } - //--------------------------------------------------------------------- - void OverlayManager::destroyAllOverlayElementsImpl(ElementMap& elementMap) - { - ElementMap::iterator i; - - while ((i = elementMap.begin()) != elementMap.end()) - { - OverlayElement* element = i->second; - - // Get factory to delete - FactoryMap::iterator fi = mFactories.find(element->getTypeName()); - if (fi == mFactories.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate factory for element " - + element->getName(), - "OverlayManager::destroyAllOverlayElements"); - } - - // remove from parent, if any - OverlayContainer* parent; - if ((parent = element->getParent()) != 0) - { - parent->_removeChild(element->getName()); - } - - // children of containers will be auto-removed when container is destroyed. - // destroy the element and remove it from the list - fi->second->destroyOverlayElement(element); - elementMap.erase(i); - } - } - //--------------------------------------------------------------------- - void OverlayManager::addOverlayElementFactory(OverlayElementFactory* elemFactory) - { - // Add / replace - mFactories[elemFactory->getTypeName()] = elemFactory; - - LogManager::getSingleton().logMessage("OverlayElementFactory for type " + elemFactory->getTypeName() - + " registered."); - } + //--------------------------------------------------------------------- + OverlayManager::ElementMap& OverlayManager::getElementMap(bool isATemplate) + { + return (isATemplate)?mTemplates:mInstances; + } + + //--------------------------------------------------------------------- + OverlayElement* OverlayManager::createOverlayElementFromTemplate(const String& templateName, const String& typeName, const String& instanceName, bool isATemplate) + { + + OverlayElement* newObj = NULL; + + if (templateName.empty()) + { + newObj = createOverlayElement(typeName, instanceName, isATemplate); + } + else + { + // no template + OverlayElement* templateGui = getOverlayElement(templateName, true); + + String typeNameToCreate; + if (typeName.empty()) + { + typeNameToCreate = templateGui->getTypeName(); + } + else + { + typeNameToCreate = typeName; + } + + newObj = createOverlayElement(typeNameToCreate, instanceName, isATemplate); + + ((OverlayContainer*)newObj)->copyFromTemplate(templateGui); + } + + return newObj; + } + + + //--------------------------------------------------------------------- + OverlayElement* OverlayManager::cloneOverlayElementFromTemplate(const String& templateName, const String& instanceName) + { + OverlayElement* templateGui = getOverlayElement(templateName, true); + return templateGui->clone(instanceName); + } + + //--------------------------------------------------------------------- + OverlayElement* OverlayManager::createOverlayElement(const String& typeName, const String& instanceName, bool isATemplate) + { + return createOverlayElementImpl(typeName, instanceName, getElementMap(isATemplate)); + } + + //--------------------------------------------------------------------- + OverlayElement* OverlayManager::createOverlayElementImpl(const String& typeName, const String& instanceName, ElementMap& elementMap) + { + // Check not duplicated + ElementMap::iterator ii = elementMap.find(instanceName); + if (ii != elementMap.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "OverlayElement with name " + instanceName + + " already exists.", "OverlayManager::createOverlayElement" ); + } + OverlayElement* newElem = createOverlayElementFromFactory(typeName, instanceName); + + // Register + elementMap.insert(ElementMap::value_type(instanceName, newElem)); + + return newElem; + + + } + + //--------------------------------------------------------------------- + OverlayElement* OverlayManager::createOverlayElementFromFactory(const String& typeName, const String& instanceName) + { + // Look up factory + FactoryMap::iterator fi = mFactories.find(typeName); + if (fi == mFactories.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate factory for element type " + typeName, + "OverlayManager::createOverlayElement"); + } + + // create + return fi->second->createOverlayElement(instanceName); + } + + //--------------------------------------------------------------------- + OverlayElement* OverlayManager::getOverlayElement(const String& name, bool isATemplate) + { + return getOverlayElementImpl(name, getElementMap(isATemplate)); + } + //--------------------------------------------------------------------- + bool OverlayManager::hasOverlayElement(const String& name, bool isATemplate) + { + return hasOverlayElementImpl(name, getElementMap(isATemplate)); + } + //--------------------------------------------------------------------- + OverlayElement* OverlayManager::getOverlayElementImpl(const String& name, ElementMap& elementMap) + { + // Locate instance + ElementMap::iterator ii = elementMap.find(name); + if (ii == elementMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "OverlayElement with name " + name + + " not found.", "OverlayManager::getOverlayElementImpl" ); + } + + return ii->second; + } + //--------------------------------------------------------------------- + bool OverlayManager::hasOverlayElementImpl(const String& name, ElementMap& elementMap) + { + ElementMap::iterator ii = elementMap.find(name); + return ii != elementMap.end(); + } + //--------------------------------------------------------------------- + void OverlayManager::destroyOverlayElement(const String& instanceName, bool isATemplate) + { + destroyOverlayElementImpl(instanceName, getElementMap(isATemplate)); + } + + //--------------------------------------------------------------------- + void OverlayManager::destroyOverlayElement(OverlayElement* pInstance, bool isATemplate) + { + destroyOverlayElementImpl(pInstance->getName(), getElementMap(isATemplate)); + } + + //--------------------------------------------------------------------- + void OverlayManager::destroyOverlayElementImpl(const String& instanceName, ElementMap& elementMap) + { + // Locate instance + ElementMap::iterator ii = elementMap.find(instanceName); + if (ii == elementMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "OverlayElement with name " + instanceName + + " not found.", "OverlayManager::destroyOverlayElement" ); + } + // Look up factory + const String& typeName = ii->second->getTypeName(); + FactoryMap::iterator fi = mFactories.find(typeName); + if (fi == mFactories.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate factory for element type " + typeName, + "OverlayManager::destroyOverlayElement"); + } + + fi->second->destroyOverlayElement(ii->second); + elementMap.erase(ii); + } + //--------------------------------------------------------------------- + void OverlayManager::destroyAllOverlayElements(bool isATemplate) + { + destroyAllOverlayElementsImpl(getElementMap(isATemplate)); + } + //--------------------------------------------------------------------- + void OverlayManager::destroyAllOverlayElementsImpl(ElementMap& elementMap) + { + ElementMap::iterator i; + + while ((i = elementMap.begin()) != elementMap.end()) + { + OverlayElement* element = i->second; + + // Get factory to delete + FactoryMap::iterator fi = mFactories.find(element->getTypeName()); + if (fi == mFactories.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate factory for element " + + element->getName(), + "OverlayManager::destroyAllOverlayElements"); + } + + // remove from parent, if any + OverlayContainer* parent; + if ((parent = element->getParent()) != 0) + { + parent->_removeChild(element->getName()); + } + + // children of containers will be auto-removed when container is destroyed. + // destroy the element and remove it from the list + fi->second->destroyOverlayElement(element); + elementMap.erase(i); + } + } + //--------------------------------------------------------------------- + void OverlayManager::addOverlayElementFactory(OverlayElementFactory* elemFactory) + { + // Add / replace + mFactories[elemFactory->getTypeName()] = elemFactory; + + LogManager::getSingleton().logMessage("OverlayElementFactory for type " + elemFactory->getTypeName() + + " registered."); + } } diff --git a/Components/Overlay/src/OgreOverlayProfileSessionListener.cpp b/Components/Overlay/src/OgreOverlayProfileSessionListener.cpp index 1053fed0121..a6f97bffafd 100644 --- a/Components/Overlay/src/OgreOverlayProfileSessionListener.cpp +++ b/Components/Overlay/src/OgreOverlayProfileSessionListener.cpp @@ -37,29 +37,29 @@ namespace Ogre { //----------------------------------------------------------------------- OverlayProfileSessionListener::OverlayProfileSessionListener() - : mOverlay(0) - , mProfileGui(0) - , mBarHeight(10) - , mGuiHeight(25) - , mGuiWidth(250) - , mGuiLeft(0) + : mOverlay(0) + , mProfileGui(0) + , mBarHeight(10) + , mGuiHeight(25) + , mGuiWidth(250) + , mGuiLeft(0) , mGuiTop(0) - , mBarIndent(250) - , mGuiBorderWidth(10) - , mBarLineWidth(2) - , mBarSpacing(3) - , mMaxDisplayProfiles(50) - { - } + , mBarIndent(250) + , mGuiBorderWidth(10) + , mBarLineWidth(2) + , mBarSpacing(3) + , mMaxDisplayProfiles(50) + { + } //----------------------------------------------------------------------- - OverlayProfileSessionListener::~OverlayProfileSessionListener() - { + OverlayProfileSessionListener::~OverlayProfileSessionListener() + { mProfileBars.clear(); - } + } //----------------------------------------------------------------------- - void OverlayProfileSessionListener::initializeSession() - { - // create a new overlay to hold our Profiler display + void OverlayProfileSessionListener::initializeSession() + { + // create a new overlay to hold our Profiler display mOverlay = OverlayManager::getSingleton().create("Profiler"); mOverlay->setZOrder(500); @@ -68,7 +68,7 @@ namespace Ogre // we create an initial pool of 50 profile bars for (uint i = 0; i < mMaxDisplayProfiles; ++i) - { + { // this is for the profile name and the number of times it was called in a frame OverlayElement* element = createTextArea("profileText" + StringConverter::toString(i), 90, mBarHeight, mGuiBorderWidth + (mBarHeight + mBarSpacing) * i, 0, 14, "", false); mProfileGui->addChild(element); @@ -94,167 +94,167 @@ namespace Ogre mProfileGui->addChild(element); mProfileBars.push_back(element); - // this indicates the text of the frame time - element = createTextArea("statText" + StringConverter::toString(i), 20, mBarHeight, mGuiBorderWidth + (mBarHeight + mBarSpacing) * i, 0, 14, "", false); - mProfileGui->addChild(element); - mProfileBars.push_back(element); + // this indicates the text of the frame time + element = createTextArea("statText" + StringConverter::toString(i), 20, mBarHeight, mGuiBorderWidth + (mBarHeight + mBarSpacing) * i, 0, 14, "", false); + mProfileGui->addChild(element); + mProfileBars.push_back(element); } // throw everything all the GUI stuff into the overlay and display it mOverlay->add2D(mProfileGui); - } + } //----------------------------------------------------------------------- - void OverlayProfileSessionListener::finializeSession() - { - OverlayContainer* container = dynamic_cast(mProfileGui); - if (container) - { - OverlayContainer::ChildIterator children = container->getChildIterator(); - while (children.hasMoreElements()) - { - OverlayElement* element = children.getNext(); - OverlayContainer* parent = element->getParent(); - if (parent) parent->removeChild(element->getName()); - OverlayManager::getSingleton().destroyOverlayElement(element); - } - } - if(mProfileGui) - OverlayManager::getSingleton().destroyOverlayElement(mProfileGui); - if(mOverlay) - OverlayManager::getSingleton().destroy(mOverlay); - - mProfileBars.clear(); - } + void OverlayProfileSessionListener::finializeSession() + { + OverlayContainer* container = dynamic_cast(mProfileGui); + if (container) + { + OverlayContainer::ChildIterator children = container->getChildIterator(); + while (children.hasMoreElements()) + { + OverlayElement* element = children.getNext(); + OverlayContainer* parent = element->getParent(); + if (parent) parent->removeChild(element->getName()); + OverlayManager::getSingleton().destroyOverlayElement(element); + } + } + if(mProfileGui) + OverlayManager::getSingleton().destroyOverlayElement(mProfileGui); + if(mOverlay) + OverlayManager::getSingleton().destroy(mOverlay); + + mProfileBars.clear(); + } //----------------------------------------------------------------------- - void OverlayProfileSessionListener::displayResults(const ProfileInstance& root, ulong maxTotalFrameTime) - { - Real newGuiHeight = mGuiHeight; - int profileCount = 0; - Real maxTimeMillisecs = (Real)maxTotalFrameTime / 1000.0f; - - ProfileBarList::const_iterator bIter = mProfileBars.begin(); - ProfileInstance::ProfileChildren::const_iterator it = root.children.begin(), endit = root.children.end(); - for(;it != endit; ++it) - { - ProfileInstance* child = it->second; - displayResults(child, bIter, maxTimeMillisecs, newGuiHeight, profileCount); - } - - // set the main display dimensions - mProfileGui->setMetricsMode(GMM_PIXELS); - mProfileGui->setHeight(newGuiHeight); - mProfileGui->setWidth(mGuiWidth * 2 + 15); - mProfileGui->setTop(5); - mProfileGui->setLeft(5); - - // we hide all the remaining pre-created bars - for (; bIter != mProfileBars.end(); ++bIter) - { - (*bIter)->hide(); - } - } + void OverlayProfileSessionListener::displayResults(const ProfileInstance& root, ulong maxTotalFrameTime) + { + Real newGuiHeight = mGuiHeight; + int profileCount = 0; + Real maxTimeMillisecs = (Real)maxTotalFrameTime / 1000.0f; + + ProfileBarList::const_iterator bIter = mProfileBars.begin(); + ProfileInstance::ProfileChildren::const_iterator it = root.children.begin(), endit = root.children.end(); + for(;it != endit; ++it) + { + ProfileInstance* child = it->second; + displayResults(child, bIter, maxTimeMillisecs, newGuiHeight, profileCount); + } + + // set the main display dimensions + mProfileGui->setMetricsMode(GMM_PIXELS); + mProfileGui->setHeight(newGuiHeight); + mProfileGui->setWidth(mGuiWidth * 2 + 15); + mProfileGui->setTop(5); + mProfileGui->setLeft(5); + + // we hide all the remaining pre-created bars + for (; bIter != mProfileBars.end(); ++bIter) + { + (*bIter)->hide(); + } + } //----------------------------------------------------------------------- - void OverlayProfileSessionListener::displayResults(ProfileInstance* instance, ProfileBarList::const_iterator& bIter, Real& maxTimeMillisecs, Real& newGuiHeight, int& profileCount) - { - OverlayElement* g; - - // display the profile's name and the number of times it was called in a frame - g = *bIter; - ++bIter; - g->show(); - g->setCaption(String(instance->name + " (" + StringConverter::toString(instance->history.numCallsThisFrame) + ")")); - g->setLeft(10 + instance->hierarchicalLvl * 15.0f); - - - // display the main bar that show the percentage of the frame time that this - // profile has taken - g = *bIter; - ++bIter; - g->show(); - // most of this junk has been set before, but we do this to get around a weird - // Ogre gui issue (bug?) - g->setMetricsMode(GMM_PIXELS); - g->setHeight(mBarHeight); - - if (mDisplayMode == DISPLAY_PERCENTAGE) - g->setWidth( (instance->history.currentTimePercent) * mGuiWidth); - else - g->setWidth( (instance->history.currentTimeMillisecs / maxTimeMillisecs) * mGuiWidth); - - g->setLeft(mGuiWidth); - g->setTop(mGuiBorderWidth + profileCount * (mBarHeight + mBarSpacing)); - - - - // display line to indicate the minimum frame time for this profile - g = *bIter; - ++bIter; - g->show(); - if(mDisplayMode == DISPLAY_PERCENTAGE) - g->setLeft(mBarIndent + instance->history.minTimePercent * mGuiWidth); - else - g->setLeft(mBarIndent + (instance->history.minTimeMillisecs / maxTimeMillisecs) * mGuiWidth); - - // display line to indicate the maximum frame time for this profile - g = *bIter; - ++bIter; - g->show(); - if(mDisplayMode == DISPLAY_PERCENTAGE) - g->setLeft(mBarIndent + instance->history.maxTimePercent * mGuiWidth); - else - g->setLeft(mBarIndent + (instance->history.maxTimeMillisecs / maxTimeMillisecs) * mGuiWidth); - - // display line to indicate the average frame time for this profile - g = *bIter; - ++bIter; - g->show(); - if(instance->history.totalCalls != 0) - { - if (mDisplayMode == DISPLAY_PERCENTAGE) - g->setLeft(mBarIndent + (instance->history.totalTimePercent / instance->history.totalCalls) * mGuiWidth); - else - g->setLeft(mBarIndent + ((instance->history.totalTimeMillisecs / instance->history.totalCalls) / maxTimeMillisecs) * mGuiWidth); - } - else - g->setLeft(mBarIndent); - - // display text - g = *bIter; - ++bIter; - g->show(); - if (mDisplayMode == DISPLAY_PERCENTAGE) - { - g->setLeft(mBarIndent + instance->history.currentTimePercent * mGuiWidth + 2); - g->setCaption(StringConverter::toString(instance->history.currentTimePercent * 100.0f, 3, 3) + "%"); - } - else - { - g->setLeft(mBarIndent + (instance->history.currentTimeMillisecs / maxTimeMillisecs) * mGuiWidth + 2); - g->setCaption(StringConverter::toString(instance->history.currentTimeMillisecs, 3, 3) + "ms"); - } - - // we set the height of the display with respect to the number of profiles displayed - newGuiHeight += mBarHeight + mBarSpacing; - - ++profileCount; - - // display children - ProfileInstance::ProfileChildren::const_iterator it = instance->children.begin(), endit = instance->children.end(); - for(;it != endit; ++it) - { - ProfileInstance* child = it->second; - displayResults(child, bIter, maxTimeMillisecs, newGuiHeight, profileCount); - } - } + void OverlayProfileSessionListener::displayResults(ProfileInstance* instance, ProfileBarList::const_iterator& bIter, Real& maxTimeMillisecs, Real& newGuiHeight, int& profileCount) + { + OverlayElement* g; + + // display the profile's name and the number of times it was called in a frame + g = *bIter; + ++bIter; + g->show(); + g->setCaption(String(instance->name + " (" + StringConverter::toString(instance->history.numCallsThisFrame) + ")")); + g->setLeft(10 + instance->hierarchicalLvl * 15.0f); + + + // display the main bar that show the percentage of the frame time that this + // profile has taken + g = *bIter; + ++bIter; + g->show(); + // most of this junk has been set before, but we do this to get around a weird + // Ogre gui issue (bug?) + g->setMetricsMode(GMM_PIXELS); + g->setHeight(mBarHeight); + + if (mDisplayMode == DISPLAY_PERCENTAGE) + g->setWidth( (instance->history.currentTimePercent) * mGuiWidth); + else + g->setWidth( (instance->history.currentTimeMillisecs / maxTimeMillisecs) * mGuiWidth); + + g->setLeft(mGuiWidth); + g->setTop(mGuiBorderWidth + profileCount * (mBarHeight + mBarSpacing)); + + + + // display line to indicate the minimum frame time for this profile + g = *bIter; + ++bIter; + g->show(); + if(mDisplayMode == DISPLAY_PERCENTAGE) + g->setLeft(mBarIndent + instance->history.minTimePercent * mGuiWidth); + else + g->setLeft(mBarIndent + (instance->history.minTimeMillisecs / maxTimeMillisecs) * mGuiWidth); + + // display line to indicate the maximum frame time for this profile + g = *bIter; + ++bIter; + g->show(); + if(mDisplayMode == DISPLAY_PERCENTAGE) + g->setLeft(mBarIndent + instance->history.maxTimePercent * mGuiWidth); + else + g->setLeft(mBarIndent + (instance->history.maxTimeMillisecs / maxTimeMillisecs) * mGuiWidth); + + // display line to indicate the average frame time for this profile + g = *bIter; + ++bIter; + g->show(); + if(instance->history.totalCalls != 0) + { + if (mDisplayMode == DISPLAY_PERCENTAGE) + g->setLeft(mBarIndent + (instance->history.totalTimePercent / instance->history.totalCalls) * mGuiWidth); + else + g->setLeft(mBarIndent + ((instance->history.totalTimeMillisecs / instance->history.totalCalls) / maxTimeMillisecs) * mGuiWidth); + } + else + g->setLeft(mBarIndent); + + // display text + g = *bIter; + ++bIter; + g->show(); + if (mDisplayMode == DISPLAY_PERCENTAGE) + { + g->setLeft(mBarIndent + instance->history.currentTimePercent * mGuiWidth + 2); + g->setCaption(StringConverter::toString(instance->history.currentTimePercent * 100.0f, 3, 3) + "%"); + } + else + { + g->setLeft(mBarIndent + (instance->history.currentTimeMillisecs / maxTimeMillisecs) * mGuiWidth + 2); + g->setCaption(StringConverter::toString(instance->history.currentTimeMillisecs, 3, 3) + "ms"); + } + + // we set the height of the display with respect to the number of profiles displayed + newGuiHeight += mBarHeight + mBarSpacing; + + ++profileCount; + + // display children + ProfileInstance::ProfileChildren::const_iterator it = instance->children.begin(), endit = instance->children.end(); + for(;it != endit; ++it) + { + ProfileInstance* child = it->second; + displayResults(child, bIter, maxTimeMillisecs, newGuiHeight, profileCount); + } + } //----------------------------------------------------------------------- void OverlayProfileSessionListener::changeEnableState(bool enabled) - { + { if (enabled) - { + { mOverlay->show(); } else - { + { mOverlay->hide(); } } @@ -262,8 +262,8 @@ namespace Ogre OverlayContainer* OverlayProfileSessionListener::createContainer() { OverlayContainer* container = (OverlayContainer*) - OverlayManager::getSingleton().createOverlayElement( - "BorderPanel", "profiler"); + OverlayManager::getSingleton().createOverlayElement( + "BorderPanel", "profiler"); container->setMetricsMode(GMM_PIXELS); container->setMaterialName("Core/StatsBlockCenter"); container->setHeight(mGuiHeight); @@ -313,7 +313,7 @@ namespace Ogre const String& materialName, bool show) { OverlayElement* panel = - OverlayManager::getSingleton().createOverlayElement("Panel", name); + OverlayManager::getSingleton().createOverlayElement("Panel", name); panel->setMetricsMode(GMM_PIXELS); panel->setWidth(width); panel->setHeight(height); @@ -331,41 +331,41 @@ namespace Ogre return panel; } //----------------------------------------------------------------------- - void OverlayProfileSessionListener::setOverlayPosition(Real left, Real top) - { - mGuiLeft = left; - mGuiTop = top; - - mProfileGui->setPosition(left, top); - } - //--------------------------------------------------------------------- - Real OverlayProfileSessionListener::getOverlayWidth() const - { - return mGuiWidth; - } - //--------------------------------------------------------------------- - Real OverlayProfileSessionListener::getOverlayHeight() const - { - return mGuiHeight; - } - //--------------------------------------------------------------------- - Real OverlayProfileSessionListener::getOverlayLeft() const - { - return mGuiLeft; - } - //--------------------------------------------------------------------- - Real OverlayProfileSessionListener::getOverlayTop() const - { - return mGuiTop; - } - //----------------------------------------------------------------------- - void OverlayProfileSessionListener::setOverlayDimensions(Real width, Real height) - { - mGuiWidth = width; - mGuiHeight = height; - mBarIndent = mGuiWidth; - - mProfileGui->setDimensions(width, height); - } - //----------------------------------------------------------------------- + void OverlayProfileSessionListener::setOverlayPosition(Real left, Real top) + { + mGuiLeft = left; + mGuiTop = top; + + mProfileGui->setPosition(left, top); + } + //--------------------------------------------------------------------- + Real OverlayProfileSessionListener::getOverlayWidth() const + { + return mGuiWidth; + } + //--------------------------------------------------------------------- + Real OverlayProfileSessionListener::getOverlayHeight() const + { + return mGuiHeight; + } + //--------------------------------------------------------------------- + Real OverlayProfileSessionListener::getOverlayLeft() const + { + return mGuiLeft; + } + //--------------------------------------------------------------------- + Real OverlayProfileSessionListener::getOverlayTop() const + { + return mGuiTop; + } + //----------------------------------------------------------------------- + void OverlayProfileSessionListener::setOverlayDimensions(Real width, Real height) + { + mGuiWidth = width; + mGuiHeight = height; + mBarIndent = mGuiWidth; + + mProfileGui->setDimensions(width, height); + } + //----------------------------------------------------------------------- } diff --git a/Components/Overlay/src/OgreOverlaySystem.cpp b/Components/Overlay/src/OgreOverlaySystem.cpp index 29185c32169..661d937c579 100644 --- a/Components/Overlay/src/OgreOverlaySystem.cpp +++ b/Components/Overlay/src/OgreOverlaySystem.cpp @@ -35,56 +35,56 @@ THE SOFTWARE. #include "OgreFontManager.h" namespace Ogre { - //--------------------------------------------------------------------- - OverlaySystem::OverlaySystem() - { - mOverlayManager = OGRE_NEW Ogre::OverlayManager(); - mOverlayManager->addOverlayElementFactory(OGRE_NEW Ogre::PanelOverlayElementFactory()); + //--------------------------------------------------------------------- + OverlaySystem::OverlaySystem() + { + mOverlayManager = OGRE_NEW Ogre::OverlayManager(); + mOverlayManager->addOverlayElementFactory(OGRE_NEW Ogre::PanelOverlayElementFactory()); - mOverlayManager->addOverlayElementFactory(OGRE_NEW Ogre::BorderPanelOverlayElementFactory()); + mOverlayManager->addOverlayElementFactory(OGRE_NEW Ogre::BorderPanelOverlayElementFactory()); - mOverlayManager->addOverlayElementFactory(OGRE_NEW Ogre::TextAreaOverlayElementFactory()); + mOverlayManager->addOverlayElementFactory(OGRE_NEW Ogre::TextAreaOverlayElementFactory()); - mFontManager = OGRE_NEW FontManager(); + mFontManager = OGRE_NEW FontManager(); #if OGRE_PROFILING - mProfileListener = new Ogre::OverlayProfileSessionListener(); - Ogre::Profiler* prof = Ogre::Profiler::getSingletonPtr(); + mProfileListener = new Ogre::OverlayProfileSessionListener(); + Ogre::Profiler* prof = Ogre::Profiler::getSingletonPtr(); if (prof) - { - prof->addListener(mProfileListener); - } + { + prof->addListener(mProfileListener); + } #endif - } - //--------------------------------------------------------------------- - OverlaySystem::~OverlaySystem() - { + } + //--------------------------------------------------------------------- + OverlaySystem::~OverlaySystem() + { #if OGRE_PROFILING - Ogre::Profiler* prof = Ogre::Profiler::getSingletonPtr(); + Ogre::Profiler* prof = Ogre::Profiler::getSingletonPtr(); if (prof) - { - prof->removeListener(mProfileListener); - } - delete mProfileListener; + { + prof->removeListener(mProfileListener); + } + delete mProfileListener; #endif - OGRE_DELETE mOverlayManager; - OGRE_DELETE mFontManager; - } - //--------------------------------------------------------------------- - void OverlaySystem::renderQueueStarted(uint8 queueGroupId, const String& invocation, - bool& skipThisInvocation) - { - if(queueGroupId == Ogre::RENDER_QUEUE_OVERLAY) - { - Ogre::Viewport* vp = Ogre::Root::getSingletonPtr()->getRenderSystem()->_getViewport(); - if(vp != NULL) - { - Ogre::SceneManager* sceneMgr = vp->getCamera()->getSceneManager(); - if (vp->getOverlaysEnabled() && sceneMgr->_getCurrentRenderStage() != Ogre::SceneManager::IRS_RENDER_TO_TEXTURE) - { - OverlayManager::getSingleton()._queueOverlaysForRendering(vp->getCamera(), sceneMgr->getRenderQueue(), vp); - } - } - } - } - //--------------------------------------------------------------------- + OGRE_DELETE mOverlayManager; + OGRE_DELETE mFontManager; + } + //--------------------------------------------------------------------- + void OverlaySystem::renderQueueStarted(uint8 queueGroupId, const String& invocation, + bool& skipThisInvocation) + { + if(queueGroupId == Ogre::RENDER_QUEUE_OVERLAY) + { + Ogre::Viewport* vp = Ogre::Root::getSingletonPtr()->getRenderSystem()->_getViewport(); + if(vp != NULL) + { + Ogre::SceneManager* sceneMgr = vp->getCamera()->getSceneManager(); + if (vp->getOverlaysEnabled() && sceneMgr->_getCurrentRenderStage() != Ogre::SceneManager::IRS_RENDER_TO_TEXTURE) + { + OverlayManager::getSingleton()._queueOverlaysForRendering(vp->getCamera(), sceneMgr->getRenderQueue(), vp); + } + } + } + } + //--------------------------------------------------------------------- } diff --git a/Components/Overlay/src/OgrePanelOverlayElement.cpp b/Components/Overlay/src/OgrePanelOverlayElement.cpp index 19577824c0d..a6fb54eba87 100644 --- a/Components/Overlay/src/OgrePanelOverlayElement.cpp +++ b/Components/Overlay/src/OgrePanelOverlayElement.cpp @@ -78,38 +78,38 @@ namespace Ogre { //--------------------------------------------------------------------- void PanelOverlayElement::initialise(void) { - bool init = !mInitialised; - - OverlayContainer::initialise(); - if (init) - { - // Setup render op in advance - mRenderOp.vertexData = OGRE_NEW VertexData(); - // Vertex declaration: 1 position, add texcoords later depending on #layers - // Create as separate buffers so we can lock & discard separately - VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; - decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); - - // Basic vertex data - mRenderOp.vertexData->vertexStart = 0; - mRenderOp.vertexData->vertexCount = 4; - - // Vertex buffer #1 - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY// mostly static except during resizing - ); - // Bind buffer - mRenderOp.vertexData->vertexBufferBinding->setBinding(POSITION_BINDING, vbuf); - - // No indexes & issue as a strip - mRenderOp.useIndexes = false; - mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; + bool init = !mInitialised; + + OverlayContainer::initialise(); + if (init) + { + // Setup render op in advance + mRenderOp.vertexData = OGRE_NEW VertexData(); + // Vertex declaration: 1 position, add texcoords later depending on #layers + // Create as separate buffers so we can lock & discard separately + VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; + decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); + + // Basic vertex data + mRenderOp.vertexData->vertexStart = 0; + mRenderOp.vertexData->vertexCount = 4; + + // Vertex buffer #1 + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY// mostly static except during resizing + ); + // Bind buffer + mRenderOp.vertexData->vertexBufferBinding->setBinding(POSITION_BINDING, vbuf); + + // No indexes & issue as a strip + mRenderOp.useIndexes = false; + mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false; - mInitialised = true; - } + mInitialised = true; + } } //--------------------------------------------------------------------- void PanelOverlayElement::setTiling(Real x, Real y, ushort layer) @@ -146,18 +146,18 @@ namespace Ogre { //--------------------------------------------------------------------- void PanelOverlayElement::setUV(Real u1, Real v1, Real u2, Real v2) { - mU1 = u1; - mU2 = u2; - mV1 = v1; - mV2 = v2; - mGeomUVsOutOfDate = true; + mU1 = u1; + mU2 = u2; + mV1 = v1; + mV2 = v2; + mGeomUVsOutOfDate = true; } void PanelOverlayElement::getUV(Real& u1, Real& v1, Real& u2, Real& v2) const { - u1 = mU1; - u2 = mU2; - v1 = mV1; - v2 = mV2; + u1 = mU1; + u2 = mU2; + v1 = mV1; + v2 = mV2; } //--------------------------------------------------------------------- const String& PanelOverlayElement::getTypeName(void) const @@ -197,52 +197,52 @@ namespace Ogre { //--------------------------------------------------------------------- void PanelOverlayElement::updatePositionGeometry(void) { - /* - 0-----2 - | /| - | / | - |/ | - 1-----3 - */ - Real left, right, top, bottom; - - /* Convert positions into -1, 1 coordinate space (homogenous clip space). - - Left / right is simple range conversion - - Top / bottom also need inverting since y is upside down - this means - that top will end up greater than bottom and when computing texture - coordinates, we have to flip the v-axis (ie. subtract the value from - 1.0 to get the actual correct value). - */ - left = _getDerivedLeft() * 2 - 1; - right = left + (mWidth * 2); - top = -((_getDerivedTop() * 2) - 1); - bottom = top - (mHeight * 2); - - HardwareVertexBufferSharedPtr vbuf = - mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); - float* pPos = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD, Root::getSingleton().getFreqUpdatedBuffersUploadOption()) ); - - // Use the furthest away depth value, since materials should have depth-check off - // This initialised the depth buffer for any 3D objects in front - Real zValue = Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue(); - *pPos++ = left; - *pPos++ = top; - *pPos++ = zValue; - - *pPos++ = left; - *pPos++ = bottom; - *pPos++ = zValue; - - *pPos++ = right; - *pPos++ = top; - *pPos++ = zValue; - - *pPos++ = right; - *pPos++ = bottom; - *pPos++ = zValue; - - vbuf->unlock(); + /* + 0-----2 + | /| + | / | + |/ | + 1-----3 + */ + Real left, right, top, bottom; + + /* Convert positions into -1, 1 coordinate space (homogenous clip space). + - Left / right is simple range conversion + - Top / bottom also need inverting since y is upside down - this means + that top will end up greater than bottom and when computing texture + coordinates, we have to flip the v-axis (ie. subtract the value from + 1.0 to get the actual correct value). + */ + left = _getDerivedLeft() * 2 - 1; + right = left + (mWidth * 2); + top = -((_getDerivedTop() * 2) - 1); + bottom = top - (mHeight * 2); + + HardwareVertexBufferSharedPtr vbuf = + mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); + float* pPos = static_cast( + vbuf->lock(HardwareBuffer::HBL_DISCARD, Root::getSingleton().getFreqUpdatedBuffersUploadOption()) ); + + // Use the furthest away depth value, since materials should have depth-check off + // This initialised the depth buffer for any 3D objects in front + Real zValue = Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue(); + *pPos++ = left; + *pPos++ = top; + *pPos++ = zValue; + + *pPos++ = left; + *pPos++ = bottom; + *pPos++ = zValue; + + *pPos++ = right; + *pPos++ = top; + *pPos++ = zValue; + + *pPos++ = right; + *pPos++ = bottom; + *pPos++ = zValue; + + vbuf->unlock(); } //--------------------------------------------------------------------- void PanelOverlayElement::updateTextureGeometry(void) @@ -261,7 +261,7 @@ namespace Ogre { for (size_t i = mNumTexCoordsInBuffer; i > numLayers; --i) { decl->removeElement(VES_TEXTURE_COORDINATES, - static_cast(i)); + static_cast(i)); } } else if (mNumTexCoordsInBuffer < numLayers) @@ -272,7 +272,7 @@ namespace Ogre { { decl->addElement(TEXCOORD_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, - static_cast(i)); + static_cast(i)); offset += VertexElement::getTypeSize(VET_FLOAT2); } @@ -294,31 +294,31 @@ namespace Ogre { } // Get the tcoord buffer & lock - if (mNumTexCoordsInBuffer) - { - HardwareVertexBufferSharedPtr vbuf = - mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING); - float* pVBStart = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD) ); - - size_t uvSize = VertexElement::getTypeSize(VET_FLOAT2) / sizeof(float); - size_t vertexSize = decl->getVertexSize(TEXCOORD_BINDING) / sizeof(float); - for (ushort i = 0; i < numLayers; ++i) - { - // Calc upper tex coords + if (mNumTexCoordsInBuffer) + { + HardwareVertexBufferSharedPtr vbuf = + mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING); + float* pVBStart = static_cast( + vbuf->lock(HardwareBuffer::HBL_DISCARD) ); + + size_t uvSize = VertexElement::getTypeSize(VET_FLOAT2) / sizeof(float); + size_t vertexSize = decl->getVertexSize(TEXCOORD_BINDING) / sizeof(float); + for (ushort i = 0; i < numLayers; ++i) + { + // Calc upper tex coords Real upperX = mU2 * mTileX[i]; Real upperY = mV2 * mTileY[i]; - /* - 0-----2 - | /| - | / | - |/ | - 1-----3 - */ - // Find start offset for this set - float* pTex = pVBStart + (i * uvSize); + /* + 0-----2 + | /| + | / | + |/ | + 1-----3 + */ + // Find start offset for this set + float* pTex = pVBStart + (i * uvSize); pTex[0] = mU1; pTex[1] = mV1; @@ -334,9 +334,9 @@ namespace Ogre { pTex += vertexSize; pTex[0] = upperX; pTex[1] = upperY; - } - vbuf->unlock(); - } + } + vbuf->unlock(); + } } } //----------------------------------------------------------------------- diff --git a/Components/Overlay/src/OgreTextAreaOverlayElement.cpp b/Components/Overlay/src/OgreTextAreaOverlayElement.cpp index f1f72dea3c3..a3250759b6c 100644 --- a/Components/Overlay/src/OgreTextAreaOverlayElement.cpp +++ b/Components/Overlay/src/OgreTextAreaOverlayElement.cpp @@ -51,11 +51,11 @@ namespace Ogre { //--------------------------------------------------------------------- #define POS_TEX_BINDING 0 #define COLOUR_BINDING 1 - #define UNICODE_NEL 0x0085 - #define UNICODE_CR 0x000D - #define UNICODE_LF 0x000A - #define UNICODE_SPACE 0x0020 - #define UNICODE_ZERO 0x0030 + #define UNICODE_NEL 0x0085 + #define UNICODE_CR 0x000D + #define UNICODE_LF 0x000A + #define UNICODE_SPACE 0x0020 + #define UNICODE_ZERO 0x0030 //--------------------------------------------------------------------- TextAreaOverlayElement::TextAreaOverlayElement(const String& name) : OverlayElement(name), mColourBottom(ColourValue::White), mColourTop(ColourValue::White) @@ -68,11 +68,11 @@ namespace Ogre { mAllocSize = 0; mCharHeight = 0.02; - mPixelCharHeight = 12; + mPixelCharHeight = 12; mSpaceWidthOverridden = false; - mSpaceWidth = 0; - mPixelSpaceWidth = 0; - mViewportAspectCoef = 1; + mSpaceWidth = 0; + mPixelSpaceWidth = 0; + mViewportAspectCoef = 1; if (createParamDictionary("TextAreaOverlayElement")) { @@ -82,32 +82,32 @@ namespace Ogre { void TextAreaOverlayElement::initialise(void) { - if (!mInitialised) - { - // Set up the render op - // Combine positions and texture coords since they tend to change together - // since character sizes are different - mRenderOp.vertexData = OGRE_NEW VertexData(); - VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; - size_t offset = 0; - // Positions - decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION); - offset += VertexElement::getTypeSize(VET_FLOAT3); - // Texcoords - decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); - // Colours - store these in a separate buffer because they change less often - decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE); - - mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; - mRenderOp.useIndexes = false; - mRenderOp.vertexData->vertexStart = 0; + if (!mInitialised) + { + // Set up the render op + // Combine positions and texture coords since they tend to change together + // since character sizes are different + mRenderOp.vertexData = OGRE_NEW VertexData(); + VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; + size_t offset = 0; + // Positions + decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION); + offset += VertexElement::getTypeSize(VET_FLOAT3); + // Texcoords + decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); + // Colours - store these in a separate buffer because they change less often + decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE); + + mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; + mRenderOp.useIndexes = false; + mRenderOp.vertexData->vertexStart = 0; mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false; - // Vertex buffer will be created in checkMemoryAllocation + // Vertex buffer will be created in checkMemoryAllocation - checkMemoryAllocation( DEFAULT_INITIAL_CHARS ); + checkMemoryAllocation( DEFAULT_INITIAL_CHARS ); - mInitialised = true; - } + mInitialised = true; + } } @@ -151,216 +151,216 @@ namespace Ogre { void TextAreaOverlayElement::updatePositionGeometry() { - float *pVert; + float *pVert; - if (mFont.isNull()) - { - // not initialised yet, probably due to the order of creation in a template - return; - } + if (mFont.isNull()) + { + // not initialised yet, probably due to the order of creation in a template + return; + } - size_t charlen = mCaption.size(); - checkMemoryAllocation( charlen ); + size_t charlen = mCaption.size(); + checkMemoryAllocation( charlen ); - mRenderOp.vertexData->vertexCount = charlen * 6; - // Get position / texcoord buffer - const HardwareVertexBufferSharedPtr& vbuf = - mRenderOp.vertexData->vertexBufferBinding->getBuffer(POS_TEX_BINDING); - pVert = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD, Root::getSingleton().getFreqUpdatedBuffersUploadOption()) ); + mRenderOp.vertexData->vertexCount = charlen * 6; + // Get position / texcoord buffer + const HardwareVertexBufferSharedPtr& vbuf = + mRenderOp.vertexData->vertexBufferBinding->getBuffer(POS_TEX_BINDING); + pVert = static_cast( + vbuf->lock(HardwareBuffer::HBL_DISCARD, Root::getSingleton().getFreqUpdatedBuffersUploadOption()) ); - float largestWidth = 0; - float left = _getDerivedLeft() * 2.0f - 1.0f; - float top = -( (_getDerivedTop() * 2.0f ) - 1.0f ); + float largestWidth = 0; + float left = _getDerivedLeft() * 2.0f - 1.0f; + float top = -( (_getDerivedTop() * 2.0f ) - 1.0f ); - // Derive space with from a number 0 + // Derive space with from a number 0 if(!mSpaceWidthOverridden) - { - mSpaceWidth = mFont->getGlyphAspectRatio(UNICODE_ZERO) * mCharHeight; - } - - // Use iterator - DisplayString::iterator i, iend; - iend = mCaption.end(); - bool newLine = true; - for( i = mCaption.begin(); i != iend; ++i ) - { - if( newLine ) - { - Real len = 0.0f; - for( DisplayString::iterator j = i; j != iend; j++ ) - { - Font::CodePoint character = OGRE_DEREF_DISPLAYSTRING_ITERATOR(j); - if (character == UNICODE_CR - || character == UNICODE_NEL - || character == UNICODE_LF) - { - break; - } - else if (character == UNICODE_SPACE) // space - { - len += mSpaceWidth * 2.0f * mViewportAspectCoef; - } - else - { - len += mFont->getGlyphAspectRatio(character) * mCharHeight * 2.0f * mViewportAspectCoef; - } - } - - if( mAlignment == Right ) - left -= len; - else if( mAlignment == Center ) - left -= len * 0.5f; - - newLine = false; - } - - Font::CodePoint character = OGRE_DEREF_DISPLAYSTRING_ITERATOR(i); - if (character == UNICODE_CR - || character == UNICODE_NEL - || character == UNICODE_LF) - { - left = _getDerivedLeft() * 2.0f - 1.0f; - top -= mCharHeight * 2.0f; - newLine = true; - // Also reduce tri count - mRenderOp.vertexData->vertexCount -= 6; - - // consume CR/LF in one - if (character == UNICODE_CR) - { - DisplayString::iterator peeki = i; - peeki++; - if (peeki != iend && OGRE_DEREF_DISPLAYSTRING_ITERATOR(peeki) == UNICODE_LF) - { - i = peeki; // skip both as one newline - // Also reduce tri count - mRenderOp.vertexData->vertexCount -= 6; - } - - } - continue; - } - else if (character == UNICODE_SPACE) // space - { - // Just leave a gap, no tris - left += mSpaceWidth * 2.0f * mViewportAspectCoef; - // Also reduce tri count - mRenderOp.vertexData->vertexCount -= 6; - continue; - } - - Real horiz_height = mFont->getGlyphAspectRatio(character) * mViewportAspectCoef ; - const Font::UVRect& uvRect = mFont->getGlyphTexCoords(character); - - // each vert is (x, y, z, u, v) - //------------------------------------------------------------------------------------- - // First tri - // - // Upper left - *pVert++ = left; - *pVert++ = top; - *pVert++ = -1.0; - *pVert++ = uvRect.left; - *pVert++ = uvRect.top; - - top -= mCharHeight * 2.0f; - - // Bottom left - *pVert++ = left; - *pVert++ = top; - *pVert++ = -1.0; - *pVert++ = uvRect.left; - *pVert++ = uvRect.bottom; - - top += mCharHeight * 2.0f; - left += horiz_height * mCharHeight * 2.0f; - - // Top right - *pVert++ = left; - *pVert++ = top; - *pVert++ = -1.0; - *pVert++ = uvRect.right; - *pVert++ = uvRect.top; - //------------------------------------------------------------------------------------- - - //------------------------------------------------------------------------------------- - // Second tri - // - // Top right (again) - *pVert++ = left; - *pVert++ = top; - *pVert++ = -1.0; - *pVert++ = uvRect.right; - *pVert++ = uvRect.top; - - top -= mCharHeight * 2.0f; - left -= horiz_height * mCharHeight * 2.0f; - - // Bottom left (again) - *pVert++ = left; - *pVert++ = top; - *pVert++ = -1.0; - *pVert++ = uvRect.left; - *pVert++ = uvRect.bottom; - - left += horiz_height * mCharHeight * 2.0f; - - // Bottom right - *pVert++ = left; - *pVert++ = top; - *pVert++ = -1.0; - *pVert++ = uvRect.right; - *pVert++ = uvRect.bottom; - //------------------------------------------------------------------------------------- - - // Go back up with top - top += mCharHeight * 2.0f; - - float currentWidth = (left + 1)/2 - _getDerivedLeft(); - if (currentWidth > largestWidth) - { - largestWidth = currentWidth; - - } - } - // Unlock vertex buffer - vbuf->unlock(); - - if (mMetricsMode == GMM_PIXELS) - { - // Derive parametric version of dimensions - Real vpWidth; - vpWidth = (Real) (OverlayManager::getSingleton().getViewportWidth()); - - largestWidth *= vpWidth; - }; - - if (getWidth() < largestWidth) - setWidth(largestWidth); - } - - void TextAreaOverlayElement::updateTextureGeometry() - { - // Nothing to do, we combine positions and textures - } + { + mSpaceWidth = mFont->getGlyphAspectRatio(UNICODE_ZERO) * mCharHeight; + } + + // Use iterator + DisplayString::iterator i, iend; + iend = mCaption.end(); + bool newLine = true; + for( i = mCaption.begin(); i != iend; ++i ) + { + if( newLine ) + { + Real len = 0.0f; + for( DisplayString::iterator j = i; j != iend; j++ ) + { + Font::CodePoint character = OGRE_DEREF_DISPLAYSTRING_ITERATOR(j); + if (character == UNICODE_CR + || character == UNICODE_NEL + || character == UNICODE_LF) + { + break; + } + else if (character == UNICODE_SPACE) // space + { + len += mSpaceWidth * 2.0f * mViewportAspectCoef; + } + else + { + len += mFont->getGlyphAspectRatio(character) * mCharHeight * 2.0f * mViewportAspectCoef; + } + } + + if( mAlignment == Right ) + left -= len; + else if( mAlignment == Center ) + left -= len * 0.5f; + + newLine = false; + } + + Font::CodePoint character = OGRE_DEREF_DISPLAYSTRING_ITERATOR(i); + if (character == UNICODE_CR + || character == UNICODE_NEL + || character == UNICODE_LF) + { + left = _getDerivedLeft() * 2.0f - 1.0f; + top -= mCharHeight * 2.0f; + newLine = true; + // Also reduce tri count + mRenderOp.vertexData->vertexCount -= 6; + + // consume CR/LF in one + if (character == UNICODE_CR) + { + DisplayString::iterator peeki = i; + peeki++; + if (peeki != iend && OGRE_DEREF_DISPLAYSTRING_ITERATOR(peeki) == UNICODE_LF) + { + i = peeki; // skip both as one newline + // Also reduce tri count + mRenderOp.vertexData->vertexCount -= 6; + } + + } + continue; + } + else if (character == UNICODE_SPACE) // space + { + // Just leave a gap, no tris + left += mSpaceWidth * 2.0f * mViewportAspectCoef; + // Also reduce tri count + mRenderOp.vertexData->vertexCount -= 6; + continue; + } + + Real horiz_height = mFont->getGlyphAspectRatio(character) * mViewportAspectCoef ; + const Font::UVRect& uvRect = mFont->getGlyphTexCoords(character); + + // each vert is (x, y, z, u, v) + //------------------------------------------------------------------------------------- + // First tri + // + // Upper left + *pVert++ = left; + *pVert++ = top; + *pVert++ = -1.0; + *pVert++ = uvRect.left; + *pVert++ = uvRect.top; + + top -= mCharHeight * 2.0f; + + // Bottom left + *pVert++ = left; + *pVert++ = top; + *pVert++ = -1.0; + *pVert++ = uvRect.left; + *pVert++ = uvRect.bottom; + + top += mCharHeight * 2.0f; + left += horiz_height * mCharHeight * 2.0f; + + // Top right + *pVert++ = left; + *pVert++ = top; + *pVert++ = -1.0; + *pVert++ = uvRect.right; + *pVert++ = uvRect.top; + //------------------------------------------------------------------------------------- + + //------------------------------------------------------------------------------------- + // Second tri + // + // Top right (again) + *pVert++ = left; + *pVert++ = top; + *pVert++ = -1.0; + *pVert++ = uvRect.right; + *pVert++ = uvRect.top; + + top -= mCharHeight * 2.0f; + left -= horiz_height * mCharHeight * 2.0f; + + // Bottom left (again) + *pVert++ = left; + *pVert++ = top; + *pVert++ = -1.0; + *pVert++ = uvRect.left; + *pVert++ = uvRect.bottom; + + left += horiz_height * mCharHeight * 2.0f; + + // Bottom right + *pVert++ = left; + *pVert++ = top; + *pVert++ = -1.0; + *pVert++ = uvRect.right; + *pVert++ = uvRect.bottom; + //------------------------------------------------------------------------------------- + + // Go back up with top + top += mCharHeight * 2.0f; + + float currentWidth = (left + 1)/2 - _getDerivedLeft(); + if (currentWidth > largestWidth) + { + largestWidth = currentWidth; + + } + } + // Unlock vertex buffer + vbuf->unlock(); + + if (mMetricsMode == GMM_PIXELS) + { + // Derive parametric version of dimensions + Real vpWidth; + vpWidth = (Real) (OverlayManager::getSingleton().getViewportWidth()); + + largestWidth *= vpWidth; + }; + + if (getWidth() < largestWidth) + setWidth(largestWidth); + } + + void TextAreaOverlayElement::updateTextureGeometry() + { + // Nothing to do, we combine positions and textures + } void TextAreaOverlayElement::setCaption( const DisplayString& caption ) { mCaption = caption; - mGeomPositionsOutOfDate = true; - mGeomUVsOutOfDate = true; + mGeomPositionsOutOfDate = true; + mGeomUVsOutOfDate = true; } void TextAreaOverlayElement::setFontName( const String& font ) { mFont = FontManager::getSingleton().getByName( font ); if (mFont.isNull()) - OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + font, - "TextAreaOverlayElement::setFontName" ); - - mGeomPositionsOutOfDate = true; - mGeomUVsOutOfDate = true; + OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + font, + "TextAreaOverlayElement::setFontName" ); + + mGeomPositionsOutOfDate = true; + mGeomUVsOutOfDate = true; } const String& TextAreaOverlayElement::getFontName() const { @@ -379,17 +379,17 @@ namespace Ogre { } mGeomPositionsOutOfDate = true; } - Real TextAreaOverlayElement::getCharHeight() const - { - if (mMetricsMode == GMM_PIXELS) - { - return mPixelCharHeight; - } - else - { - return mCharHeight; - } - } + Real TextAreaOverlayElement::getCharHeight() const + { + if (mMetricsMode == GMM_PIXELS) + { + return mPixelCharHeight; + } + else + { + return mCharHeight; + } + } void TextAreaOverlayElement::setSpaceWidth( Real width ) { @@ -405,17 +405,17 @@ namespace Ogre { mGeomPositionsOutOfDate = true; } - Real TextAreaOverlayElement::getSpaceWidth() const - { - if (mMetricsMode == GMM_PIXELS) - { - return mPixelSpaceWidth; - } - else - { - return mSpaceWidth; - } - } + Real TextAreaOverlayElement::getSpaceWidth() const + { + if (mMetricsMode == GMM_PIXELS) + { + return mPixelSpaceWidth; + } + else + { + return mSpaceWidth; + } + } //--------------------------------------------------------------------- TextAreaOverlayElement::~TextAreaOverlayElement() @@ -430,16 +430,16 @@ namespace Ogre { //--------------------------------------------------------------------- const MaterialPtr& TextAreaOverlayElement::getMaterial(void) const { - // On-demand load - // Moved from setFontName to avoid issues with background parsing of scripts - if (mMaterial.isNull() && !mFont.isNull()) - { - mFont->load(); - // Ugly hack, but we need to override for lazy-load - *const_cast(&mMaterial) = mFont->getMaterial(); - mMaterial->setDepthCheckEnabled(false); - mMaterial->setLightingEnabled(false); - } + // On-demand load + // Moved from setFontName to avoid issues with background parsing of scripts + if (mMaterial.isNull() && !mFont.isNull()) + { + mFont->load(); + // Ugly hack, but we need to override for lazy-load + *const_cast(&mMaterial) = mFont->getMaterial(); + mMaterial->setDepthCheckEnabled(false); + mMaterial->setLightingEnabled(false); + } return mMaterial; } //--------------------------------------------------------------------- @@ -554,81 +554,81 @@ namespace Ogre { } vbuf->unlock(); - } - //----------------------------------------------------------------------- - void TextAreaOverlayElement::setMetricsMode(GuiMetricsMode gmm) - { - Real vpWidth, vpHeight; - vpWidth = (Real) (OverlayManager::getSingleton().getViewportWidth()); - vpHeight = (Real) (OverlayManager::getSingleton().getViewportHeight()); - - mViewportAspectCoef = vpHeight/vpWidth; - - OverlayElement::setMetricsMode(gmm); - - switch (mMetricsMode) - { - case GMM_PIXELS: - // set pixel variables based on viewport multipliers - mPixelCharHeight = static_cast(mCharHeight * vpHeight); - mPixelSpaceWidth = static_cast(mSpaceWidth * vpHeight); - break; - - case GMM_RELATIVE_ASPECT_ADJUSTED: - // set pixel variables multiplied by the height constant - mPixelCharHeight = static_cast(mCharHeight * 10000.0); - mPixelSpaceWidth = static_cast(mSpaceWidth * 10000.0); - break; - - default: - break; - } - } - //----------------------------------------------------------------------- - void TextAreaOverlayElement::_update(void) - { - Real vpWidth, vpHeight; - vpWidth = (Real) (OverlayManager::getSingleton().getViewportWidth()); - vpHeight = (Real) (OverlayManager::getSingleton().getViewportHeight()); - - mViewportAspectCoef = vpHeight/vpWidth; - - // Check size if pixel-based / relative-aspect-adjusted - switch (mMetricsMode) - { - case GMM_PIXELS: - if(OverlayManager::getSingleton().hasViewportChanged() || mGeomPositionsOutOfDate) - { - // recalculate character size - mCharHeight = (Real) mPixelCharHeight / vpHeight; - mSpaceWidth = (Real) mPixelSpaceWidth / vpHeight; - mGeomPositionsOutOfDate = true; - } - break; - - case GMM_RELATIVE_ASPECT_ADJUSTED: - if(OverlayManager::getSingleton().hasViewportChanged() || mGeomPositionsOutOfDate) - { - // recalculate character size - mCharHeight = (Real) mPixelCharHeight / 10000.0f; - mSpaceWidth = (Real) mPixelSpaceWidth / 10000.0f; - mGeomPositionsOutOfDate = true; - } - break; - - default: - break; - } - - OverlayElement::_update(); - - if (mColoursChanged && mInitialised) - { - updateColours(); - mColoursChanged = false; - } - } - //--------------------------------------------------------------------------------------------- + } + //----------------------------------------------------------------------- + void TextAreaOverlayElement::setMetricsMode(GuiMetricsMode gmm) + { + Real vpWidth, vpHeight; + vpWidth = (Real) (OverlayManager::getSingleton().getViewportWidth()); + vpHeight = (Real) (OverlayManager::getSingleton().getViewportHeight()); + + mViewportAspectCoef = vpHeight/vpWidth; + + OverlayElement::setMetricsMode(gmm); + + switch (mMetricsMode) + { + case GMM_PIXELS: + // set pixel variables based on viewport multipliers + mPixelCharHeight = static_cast(mCharHeight * vpHeight); + mPixelSpaceWidth = static_cast(mSpaceWidth * vpHeight); + break; + + case GMM_RELATIVE_ASPECT_ADJUSTED: + // set pixel variables multiplied by the height constant + mPixelCharHeight = static_cast(mCharHeight * 10000.0); + mPixelSpaceWidth = static_cast(mSpaceWidth * 10000.0); + break; + + default: + break; + } + } + //----------------------------------------------------------------------- + void TextAreaOverlayElement::_update(void) + { + Real vpWidth, vpHeight; + vpWidth = (Real) (OverlayManager::getSingleton().getViewportWidth()); + vpHeight = (Real) (OverlayManager::getSingleton().getViewportHeight()); + + mViewportAspectCoef = vpHeight/vpWidth; + + // Check size if pixel-based / relative-aspect-adjusted + switch (mMetricsMode) + { + case GMM_PIXELS: + if(OverlayManager::getSingleton().hasViewportChanged() || mGeomPositionsOutOfDate) + { + // recalculate character size + mCharHeight = (Real) mPixelCharHeight / vpHeight; + mSpaceWidth = (Real) mPixelSpaceWidth / vpHeight; + mGeomPositionsOutOfDate = true; + } + break; + + case GMM_RELATIVE_ASPECT_ADJUSTED: + if(OverlayManager::getSingleton().hasViewportChanged() || mGeomPositionsOutOfDate) + { + // recalculate character size + mCharHeight = (Real) mPixelCharHeight / 10000.0f; + mSpaceWidth = (Real) mPixelSpaceWidth / 10000.0f; + mGeomPositionsOutOfDate = true; + } + break; + + default: + break; + } + + OverlayElement::_update(); + + if (mColoursChanged && mInitialised) + { + updateColours(); + mColoursChanged = false; + } + } + //--------------------------------------------------------------------------------------------- // Char height command object // String TextAreaOverlayElement::CmdCharHeight::doGet( const void* target ) const diff --git a/Components/Paging/include/OgreGrid3DPageStrategy.h b/Components/Paging/include/OgreGrid3DPageStrategy.h index 15a4d6165e0..650f48786df 100644 --- a/Components/Paging/include/OgreGrid3DPageStrategy.h +++ b/Components/Paging/include/OgreGrid3DPageStrategy.h @@ -35,188 +35,188 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Paging - * Some details on paging component - */ - /*@{*/ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Paging + * Some details on paging component + */ + /*@{*/ /** Specialisation of PageStrategyData for Grid3DPageStrategy. - @remarks - Structurally this data defines with a 3D grid of pages, with the logical - origin in the center of the entire grid. - The grid cells are indexed from 0 as a 'centre' slot, supporting both - positive and negative values. so (0,0,0) is the centre cell, (1,0,0) is the - cell to the right of the centre, (0,0,1) is the cell in front of the centre, + @remarks + Structurally this data defines with a 3D grid of pages, with the logical + origin in the center of the entire grid. + The grid cells are indexed from 0 as a 'centre' slot, supporting both + positive and negative values. so (0,0,0) is the centre cell, (1,0,0) is the + cell to the right of the centre, (0,0,1) is the cell in front of the centre, (0,1,0) the cell above the center, etc. The maximum extent of each axis is -512 to +511, so in other words enough for - over 2 billion different entries. - @par - To limit the page load requests that are generated to a fixed region, - you can set the min and max cell indexes (inclusive)for each direction; - if a page request would address a cell outside this range it is ignored - so you don't have the expense of checking for page data that will never - exist. + over 2 billion different entries. @par - The data format for this in a file is:
      - Grid3DPageStrategyData (Identifier 'G3DD')\n - [Version 1] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      NameTypeDescription
      Grid originVector3World origin of the grid.
      Grid cell sizeVector3The size of each cell (page) in the grid
      Grid cell range (minx, maxx, miny, maxy, minz, maxz)int16 * 6The extents of the world in cell indexes
      Load radiusRealThe outer radius at which new pages should start loading
      Hold radiusRealThe radius at which existing pages should be held if already loaded - but not actively loaded (should be larger than Load radius)
      + To limit the page load requests that are generated to a fixed region, + you can set the min and max cell indexes (inclusive)for each direction; + if a page request would address a cell outside this range it is ignored + so you don't have the expense of checking for page data that will never + exist. + @par + The data format for this in a file is:
      + Grid3DPageStrategyData (Identifier 'G3DD')\n + [Version 1] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeDescription
      Grid originVector3World origin of the grid.
      Grid cell sizeVector3The size of each cell (page) in the grid
      Grid cell range (minx, maxx, miny, maxy, minz, maxz)int16 * 6The extents of the world in cell indexes
      Load radiusRealThe outer radius at which new pages should start loading
      Hold radiusRealThe radius at which existing pages should be held if already loaded + but not actively loaded (should be larger than Load radius)
      @sa Grid2DPageStrategyData - */ - class _OgrePagingExport Grid3DPageStrategyData : public PageStrategyData - { - protected: - /// Origin (world space) - Vector3 mWorldOrigin; - /// Origin (grid-aligned world space) - Vector3 mOrigin; - /// Grid cell (page) size - Vector3 mCellSize; - /// Load radius - Real mLoadRadius; - /// Hold radius - Real mHoldRadius; - int32 mMinCellX; - int32 mMinCellY; - int32 mMinCellZ; - int32 mMaxCellX; - int32 mMaxCellY; - int32 mMaxCellZ; - - public: - static const uint32 CHUNK_ID; - static const uint16 CHUNK_VERSION; - - Grid3DPageStrategyData(); - ~Grid3DPageStrategyData(); - - /// Set the origin of the grid in world space - virtual void setOrigin(const Vector3& worldOrigin); - /// Get the origin of the grid in world space - virtual const Vector3& getOrigin(const Vector3& worldOrigin) { return mWorldOrigin; } - /// Set the size of the cells in the grid - virtual void setCellSize(const Vector3& sz); - /// Get the size of the cells in the grid - virtual Vector3 getCellSize() const { return mCellSize; } - /// Set the loading radius - virtual void setLoadRadius(Real sz); - /// Get the loading radius - virtual Real getLoadRadius() const { return mLoadRadius; } - /// Set the Holding radius - virtual void setHoldRadius(Real sz); - /// Get the Holding radius - virtual Real getHoldRadius() const { return mHoldRadius; } - - /// Set the index range of all cells (values outside this will be ignored) - virtual void setCellRange(int32 minX, int32 minY, int32 minZ, int32 maxX, int32 maxY, int32 maxZ); - /// Set the index range of all cells (values outside this will be ignored) - virtual void setCellRangeMinX(int32 minX); - /// Set the index range of all cells (values outside this will be ignored) - virtual void setCellRangeMinY(int32 minY); - /// Set the index range of all cells (values outside this will be ignored) - virtual void setCellRangeMinZ(int32 minZ); - /// Set the index range of all cells (values outside this will be ignored) - virtual void setCellRangeMaxX(int32 maxX); - /// Set the index range of all cells (values outside this will be ignored) - virtual void setCellRangeMaxY(int32 maxY); - /// get the index range of all cells (values outside this will be ignored) - virtual void setCellRangeMaxZ(int32 maxZ); - /// get the index range of all cells (values outside this will be ignored) - virtual int32 getCellRangeMinX() const { return mMinCellX; } - /// get the index range of all cells (values outside this will be ignored) - virtual int32 getCellRangeMinY() const { return mMinCellY; } - /// get the index range of all cells (values outside this will be ignored) - virtual int32 getCellRangeMinZ() const { return mMinCellZ; } - /// get the index range of all cells (values outside this will be ignored) - virtual int32 getCellRangeMaxX() const { return mMaxCellX; } - /// get the index range of all cells (values outside this will be ignored) - virtual int32 getCellRangeMaxY() const { return mMaxCellY; } - /// get the index range of all cells (values outside this will be ignored) - virtual int32 getCellRangeMaxZ() const { return mMaxCellZ; } - - /// Load this data from a stream (returns true if successful) - bool load(StreamSerialiser& stream); - /// Save this data to a stream - void save(StreamSerialiser& stream); - - virtual void getMidPointGridSpace(int32 x, int32 y, int32 z, Vector3& mid); - /// Get the (grid space) bottom-left of a cell - virtual void getBottomLeftGridSpace(int32 x, int32 y, int z, Vector3& bl); - /** Get the (grid space) corners of a cell. - @remarks - Populates pEightPoints in anticlockwise order from the bottom left point. - */ - virtual void getCornersGridSpace(int32 x, int32 y, int32 z, Vector3* pEightPoints); - - /// Convert a grid position into a row and column index - void determineGridLocation(const Vector3& gridpos, int32* x, int32* y, int32* z); - - PageID calculatePageID(int32 x, int32 y, int32 z); - void calculateCell(PageID inPageID, int32* x, int32* y, int32* z); - }; - - - /** Page strategy which loads new pages based on a regular 3D grid. - @remarks - The grid can be up to 1024 x 1024 x 1024 cells in size. PageIDs are generated - like this: (slice*1024 + row) * 1024 + col. The grid is centred around the grid origin, such - that the boundaries of the cell around that origin are [-CellSize/2, CellSize/2) - */ - class _OgrePagingExport Grid3DPageStrategy : public PageStrategy - { - public: - Grid3DPageStrategy(PageManager* manager); - - ~Grid3DPageStrategy(); - - // Overridden members - void notifyCamera(Camera* cam, PagedWorldSection* section); - PageStrategyData* createData(); - void destroyData(PageStrategyData* d); - void updateDebugDisplay(Page* p, SceneNode* sn); - PageID getPageID(const Vector3& worldPos, PagedWorldSection* section); - }; - - /*@}*/ - /*@}*/ + */ + class _OgrePagingExport Grid3DPageStrategyData : public PageStrategyData + { + protected: + /// Origin (world space) + Vector3 mWorldOrigin; + /// Origin (grid-aligned world space) + Vector3 mOrigin; + /// Grid cell (page) size + Vector3 mCellSize; + /// Load radius + Real mLoadRadius; + /// Hold radius + Real mHoldRadius; + int32 mMinCellX; + int32 mMinCellY; + int32 mMinCellZ; + int32 mMaxCellX; + int32 mMaxCellY; + int32 mMaxCellZ; + + public: + static const uint32 CHUNK_ID; + static const uint16 CHUNK_VERSION; + + Grid3DPageStrategyData(); + ~Grid3DPageStrategyData(); + + /// Set the origin of the grid in world space + virtual void setOrigin(const Vector3& worldOrigin); + /// Get the origin of the grid in world space + virtual const Vector3& getOrigin(const Vector3& worldOrigin) { return mWorldOrigin; } + /// Set the size of the cells in the grid + virtual void setCellSize(const Vector3& sz); + /// Get the size of the cells in the grid + virtual Vector3 getCellSize() const { return mCellSize; } + /// Set the loading radius + virtual void setLoadRadius(Real sz); + /// Get the loading radius + virtual Real getLoadRadius() const { return mLoadRadius; } + /// Set the Holding radius + virtual void setHoldRadius(Real sz); + /// Get the Holding radius + virtual Real getHoldRadius() const { return mHoldRadius; } + + /// Set the index range of all cells (values outside this will be ignored) + virtual void setCellRange(int32 minX, int32 minY, int32 minZ, int32 maxX, int32 maxY, int32 maxZ); + /// Set the index range of all cells (values outside this will be ignored) + virtual void setCellRangeMinX(int32 minX); + /// Set the index range of all cells (values outside this will be ignored) + virtual void setCellRangeMinY(int32 minY); + /// Set the index range of all cells (values outside this will be ignored) + virtual void setCellRangeMinZ(int32 minZ); + /// Set the index range of all cells (values outside this will be ignored) + virtual void setCellRangeMaxX(int32 maxX); + /// Set the index range of all cells (values outside this will be ignored) + virtual void setCellRangeMaxY(int32 maxY); + /// get the index range of all cells (values outside this will be ignored) + virtual void setCellRangeMaxZ(int32 maxZ); + /// get the index range of all cells (values outside this will be ignored) + virtual int32 getCellRangeMinX() const { return mMinCellX; } + /// get the index range of all cells (values outside this will be ignored) + virtual int32 getCellRangeMinY() const { return mMinCellY; } + /// get the index range of all cells (values outside this will be ignored) + virtual int32 getCellRangeMinZ() const { return mMinCellZ; } + /// get the index range of all cells (values outside this will be ignored) + virtual int32 getCellRangeMaxX() const { return mMaxCellX; } + /// get the index range of all cells (values outside this will be ignored) + virtual int32 getCellRangeMaxY() const { return mMaxCellY; } + /// get the index range of all cells (values outside this will be ignored) + virtual int32 getCellRangeMaxZ() const { return mMaxCellZ; } + + /// Load this data from a stream (returns true if successful) + bool load(StreamSerialiser& stream); + /// Save this data to a stream + void save(StreamSerialiser& stream); + + virtual void getMidPointGridSpace(int32 x, int32 y, int32 z, Vector3& mid); + /// Get the (grid space) bottom-left of a cell + virtual void getBottomLeftGridSpace(int32 x, int32 y, int z, Vector3& bl); + /** Get the (grid space) corners of a cell. + @remarks + Populates pEightPoints in anticlockwise order from the bottom left point. + */ + virtual void getCornersGridSpace(int32 x, int32 y, int32 z, Vector3* pEightPoints); + + /// Convert a grid position into a row and column index + void determineGridLocation(const Vector3& gridpos, int32* x, int32* y, int32* z); + + PageID calculatePageID(int32 x, int32 y, int32 z); + void calculateCell(PageID inPageID, int32* x, int32* y, int32* z); + }; + + + /** Page strategy which loads new pages based on a regular 3D grid. + @remarks + The grid can be up to 1024 x 1024 x 1024 cells in size. PageIDs are generated + like this: (slice*1024 + row) * 1024 + col. The grid is centred around the grid origin, such + that the boundaries of the cell around that origin are [-CellSize/2, CellSize/2) + */ + class _OgrePagingExport Grid3DPageStrategy : public PageStrategy + { + public: + Grid3DPageStrategy(PageManager* manager); + + ~Grid3DPageStrategy(); + + // Overridden members + void notifyCamera(Camera* cam, PagedWorldSection* section); + PageStrategyData* createData(); + void destroyData(PageStrategyData* d); + void updateDebugDisplay(Page* p, SceneNode* sn); + PageID getPageID(const Vector3& worldPos, PagedWorldSection* section); + }; + + /*@}*/ + /*@}*/ } #endif diff --git a/Components/Paging/include/OgrePage.h b/Components/Paging/include/OgrePage.h index 558c5b22c37..9acf1178fe5 100644 --- a/Components/Paging/include/OgrePage.h +++ b/Components/Paging/include/OgrePage.h @@ -36,171 +36,171 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Paging - * Some details on paging component - * @{ - */ - - /** Page class - */ - class _OgrePagingExport Page : public WorkQueue::RequestHandler, - public WorkQueue::ResponseHandler, public PageAlloc - { - public: - typedef vector::type ContentCollectionList; - protected: - PageID mID; - PagedWorldSection* mParent; - unsigned long mFrameLastHeld; - ContentCollectionList mContentCollections; - uint16 mWorkQueueChannel; - bool mDeferredProcessInProgress; - bool mModified; - - SceneNode* mDebugNode; - void updateDebugDisplay(); - - struct PageData : public PageAlloc - { - ContentCollectionList collectionsToAdd; - }; - /// Structure for holding background page requests - struct PageRequest - { - Page* srcPage; - _OgrePagingExport friend std::ostream& operator<<(std::ostream& o, const PageRequest& r) - { return o; } - - PageRequest(Page* p): srcPage(p) {} - }; - struct PageResponse - { - PageData* pageData; - - _OgrePagingExport friend std::ostream& operator<<(std::ostream& o, const PageResponse& r) - { return o; } - - PageResponse() : pageData(0) {} - }; - - - - virtual bool prepareImpl(PageData* dataToPopulate); - virtual bool prepareImpl(StreamSerialiser& str, PageData* dataToPopulate); - virtual void loadImpl(); - - String generateFilename() const; - - public: - static const uint32 CHUNK_ID; - static const uint16 CHUNK_VERSION; - - static const uint32 CHUNK_CONTENTCOLLECTION_DECLARATION_ID; - - Page(PageID pageID, PagedWorldSection* parent); - virtual ~Page(); - - PageManager* getManager() const; - SceneManager* getSceneManager() const; - - /// If true, it's not safe to access this Page at this time, contents may be changing - bool isDeferredProcessInProgress() const { return mDeferredProcessInProgress; } - - /// Get the ID of this page, unique within the parent - virtual PageID getID() const { return mID; } - /// Get the PagedWorldSection this page belongs to - virtual PagedWorldSection* getParentSection() const { return mParent; } - /** Get the frame number in which this Page was last loaded or held. - @remarks - A Page that has not been requested to be loaded or held in the recent - past will be a candidate for removal. - */ - virtual unsigned long getFrameLastHeld() { return mFrameLastHeld; } - /// 'Touch' the page to let it know it's being used - virtual void touch(); - - /** Load this page. - @param synchronous Whether to force this to happen synchronously. - */ - virtual void load(bool synchronous); - /** Unload this page. - */ - virtual void unload(); - - - /** Returns whether this page was 'held' in the last frame, that is - was it either directly needed, or requested to stay in memory (held - as - in a buffer region for example). If not, this page is eligible for - removal. - */ - virtual bool isHeld() const; - - /// Save page data to an automatically generated file name - virtual void save(); - /// Save page data to a file - virtual void save(const String& filename); - /// Save page data to a serialiser - virtual void save(StreamSerialiser& stream); - - /// Called when the frame starts - virtual void frameStart(Real timeSinceLastFrame); - /// Called when the frame ends - virtual void frameEnd(Real timeElapsed); - /// Notify a section of the current camera - virtual void notifyCamera(Camera* cam); - - /** Create a new PageContentCollection within this page. - This is equivalent to calling PageManager::createContentCollection and - then attachContentCollection. - @param typeName The name of the type of content collection (see PageManager::getContentCollectionFactories) - */ - virtual PageContentCollection* createContentCollection(const String& typeName); - - /** Destroy a PageContentCollection within this page. - This is equivalent to calling detachContentCollection and - PageManager::destroyContentCollection. - */ - virtual void destroyContentCollection(PageContentCollection* coll); - /** Destroy all PageContentCollections within this page. - */ - virtual void destroyAllContentCollections(); - /// Get the number of content collections - virtual size_t getContentCollectionCount() const; - /// Get a content collection - virtual PageContentCollection* getContentCollection(size_t index); - /// Get the list of content collections - const ContentCollectionList& getContentCollectionList() const; - - /// WorkQueue::RequestHandler override - bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); - /// WorkQueue::RequestHandler override - WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); - /// WorkQueue::ResponseHandler override - bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - /// WorkQueue::ResponseHandler override - void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - - - /// Tell the page that it is modified - void _notifyModified() { mModified = true; } - bool isModified() const { return mModified; } - - static const uint16 WORKQUEUE_PREPARE_REQUEST; - static const uint16 WORKQUEUE_CHANGECOLLECTION_REQUEST; - - /** Function for writing to a stream. - */ - _OgrePagingExport friend std::ostream& operator <<( std::ostream& o, const Page& p ); - - - - }; - - /** @} */ - /** @} */ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Paging + * Some details on paging component + * @{ + */ + + /** Page class + */ + class _OgrePagingExport Page : public WorkQueue::RequestHandler, + public WorkQueue::ResponseHandler, public PageAlloc + { + public: + typedef vector::type ContentCollectionList; + protected: + PageID mID; + PagedWorldSection* mParent; + unsigned long mFrameLastHeld; + ContentCollectionList mContentCollections; + uint16 mWorkQueueChannel; + bool mDeferredProcessInProgress; + bool mModified; + + SceneNode* mDebugNode; + void updateDebugDisplay(); + + struct PageData : public PageAlloc + { + ContentCollectionList collectionsToAdd; + }; + /// Structure for holding background page requests + struct PageRequest + { + Page* srcPage; + _OgrePagingExport friend std::ostream& operator<<(std::ostream& o, const PageRequest& r) + { return o; } + + PageRequest(Page* p): srcPage(p) {} + }; + struct PageResponse + { + PageData* pageData; + + _OgrePagingExport friend std::ostream& operator<<(std::ostream& o, const PageResponse& r) + { return o; } + + PageResponse() : pageData(0) {} + }; + + + + virtual bool prepareImpl(PageData* dataToPopulate); + virtual bool prepareImpl(StreamSerialiser& str, PageData* dataToPopulate); + virtual void loadImpl(); + + String generateFilename() const; + + public: + static const uint32 CHUNK_ID; + static const uint16 CHUNK_VERSION; + + static const uint32 CHUNK_CONTENTCOLLECTION_DECLARATION_ID; + + Page(PageID pageID, PagedWorldSection* parent); + virtual ~Page(); + + PageManager* getManager() const; + SceneManager* getSceneManager() const; + + /// If true, it's not safe to access this Page at this time, contents may be changing + bool isDeferredProcessInProgress() const { return mDeferredProcessInProgress; } + + /// Get the ID of this page, unique within the parent + virtual PageID getID() const { return mID; } + /// Get the PagedWorldSection this page belongs to + virtual PagedWorldSection* getParentSection() const { return mParent; } + /** Get the frame number in which this Page was last loaded or held. + @remarks + A Page that has not been requested to be loaded or held in the recent + past will be a candidate for removal. + */ + virtual unsigned long getFrameLastHeld() { return mFrameLastHeld; } + /// 'Touch' the page to let it know it's being used + virtual void touch(); + + /** Load this page. + @param synchronous Whether to force this to happen synchronously. + */ + virtual void load(bool synchronous); + /** Unload this page. + */ + virtual void unload(); + + + /** Returns whether this page was 'held' in the last frame, that is + was it either directly needed, or requested to stay in memory (held - as + in a buffer region for example). If not, this page is eligible for + removal. + */ + virtual bool isHeld() const; + + /// Save page data to an automatically generated file name + virtual void save(); + /// Save page data to a file + virtual void save(const String& filename); + /// Save page data to a serialiser + virtual void save(StreamSerialiser& stream); + + /// Called when the frame starts + virtual void frameStart(Real timeSinceLastFrame); + /// Called when the frame ends + virtual void frameEnd(Real timeElapsed); + /// Notify a section of the current camera + virtual void notifyCamera(Camera* cam); + + /** Create a new PageContentCollection within this page. + This is equivalent to calling PageManager::createContentCollection and + then attachContentCollection. + @param typeName The name of the type of content collection (see PageManager::getContentCollectionFactories) + */ + virtual PageContentCollection* createContentCollection(const String& typeName); + + /** Destroy a PageContentCollection within this page. + This is equivalent to calling detachContentCollection and + PageManager::destroyContentCollection. + */ + virtual void destroyContentCollection(PageContentCollection* coll); + /** Destroy all PageContentCollections within this page. + */ + virtual void destroyAllContentCollections(); + /// Get the number of content collections + virtual size_t getContentCollectionCount() const; + /// Get a content collection + virtual PageContentCollection* getContentCollection(size_t index); + /// Get the list of content collections + const ContentCollectionList& getContentCollectionList() const; + + /// WorkQueue::RequestHandler override + bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + /// WorkQueue::RequestHandler override + WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + /// WorkQueue::ResponseHandler override + bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + /// WorkQueue::ResponseHandler override + void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + + + /// Tell the page that it is modified + void _notifyModified() { mModified = true; } + bool isModified() const { return mModified; } + + static const uint16 WORKQUEUE_PREPARE_REQUEST; + static const uint16 WORKQUEUE_CHANGECOLLECTION_REQUEST; + + /** Function for writing to a stream. + */ + _OgrePagingExport friend std::ostream& operator <<( std::ostream& o, const Page& p ); + + + + }; + + /** @} */ + /** @} */ } #endif diff --git a/Components/Paging/include/OgrePageConnection.h b/Components/Paging/include/OgrePageConnection.h index 20a2958cd9d..cf3e0c3ad0f 100644 --- a/Components/Paging/include/OgrePageConnection.h +++ b/Components/Paging/include/OgrePageConnection.h @@ -34,17 +34,17 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ + /** \addtogroup Optional Components + * @{ + */ - /** \addtogroup Paging - * Some details on paging component - * @{ - */ + /** \addtogroup Paging + * Some details on paging component + * @{ + */ - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/Components/Paging/include/OgrePageContent.h b/Components/Paging/include/OgrePageContent.h index 680069075e7..68df7e3bf45 100644 --- a/Components/Paging/include/OgrePageContent.h +++ b/Components/Paging/include/OgrePageContent.h @@ -35,56 +35,56 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Paging - * Some details on paging component - * @{ - */ - - - /** Interface definition for a unit of content within a page. - */ - class _OgrePagingExport PageContent : public PageAlloc - { - protected: - PageContentFactory* mCreator; - PageContentCollection* mParent; - public: - PageContent(PageContentFactory* creator); - virtual ~PageContent(); - - PageManager* getManager() const; - SceneManager* getSceneManager() const; - - /// Internal method to notify a page that it is attached - virtual void _notifyAttached(PageContentCollection* parent); - /// Get the type of the content, which will match it's factory - virtual const String& getType() const; - - /// Save the content to a stream - virtual void save(StreamSerialiser& stream) = 0; - /// Called when the frame starts - virtual void frameStart(Real timeSinceLastFrame) {} - /// Called when the frame ends - virtual void frameEnd(Real timeElapsed) {} - /// Notify a section of the current camera - virtual void notifyCamera(Camera* cam) {} - - /// Prepare data - may be called in the background - virtual bool prepare(StreamSerialiser& ser) = 0; - /// Load - will be called in main thread - virtual void load() = 0; - /// Unload - will be called in main thread - virtual void unload() = 0; - /// Unprepare data - may be called in the background - virtual void unprepare() = 0; - - }; - - /** @} */ - /** @} */ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Paging + * Some details on paging component + * @{ + */ + + + /** Interface definition for a unit of content within a page. + */ + class _OgrePagingExport PageContent : public PageAlloc + { + protected: + PageContentFactory* mCreator; + PageContentCollection* mParent; + public: + PageContent(PageContentFactory* creator); + virtual ~PageContent(); + + PageManager* getManager() const; + SceneManager* getSceneManager() const; + + /// Internal method to notify a page that it is attached + virtual void _notifyAttached(PageContentCollection* parent); + /// Get the type of the content, which will match it's factory + virtual const String& getType() const; + + /// Save the content to a stream + virtual void save(StreamSerialiser& stream) = 0; + /// Called when the frame starts + virtual void frameStart(Real timeSinceLastFrame) {} + /// Called when the frame ends + virtual void frameEnd(Real timeElapsed) {} + /// Notify a section of the current camera + virtual void notifyCamera(Camera* cam) {} + + /// Prepare data - may be called in the background + virtual bool prepare(StreamSerialiser& ser) = 0; + /// Load - will be called in main thread + virtual void load() = 0; + /// Unload - will be called in main thread + virtual void unload() = 0; + /// Unprepare data - may be called in the background + virtual void unprepare() = 0; + + }; + + /** @} */ + /** @} */ } #endif diff --git a/Components/Paging/include/OgrePageContentCollection.h b/Components/Paging/include/OgrePageContentCollection.h index 617d8f12df2..b789b57e1f6 100644 --- a/Components/Paging/include/OgrePageContentCollection.h +++ b/Components/Paging/include/OgrePageContentCollection.h @@ -34,70 +34,70 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Paging - * Some details on paging component - * @{ - */ - - - /** Definition of the interface for a collection of PageContent instances. - @remarks - This class acts as a grouping level for PageContent instances. Rather than - PageContent instances being held in a list directly under Page, which might - be the most obvious solution, this intermediate class is here to allow - the collection of relevant PageContent instances to be modified at runtime - if required. For example, potentially you might want to define Page-level LOD - in which different collections of PageContent are loaded at different times. - */ - class _OgrePagingExport PageContentCollection : public PageAlloc - { - protected: - PageContentCollectionFactory* mCreator; - Page* mParent; - public: - static const uint32 CHUNK_ID; - static const uint16 CHUNK_VERSION; - - PageContentCollection(PageContentCollectionFactory* creator); - virtual ~PageContentCollection(); - - PageManager* getManager() const; - Page* getParentPage() const { return mParent; } - SceneManager* getSceneManager() const; - - /// Get the type of the collection, which will match it's factory - virtual const String& getType() const; - - /// Internal method to notify a collection that it is attached - virtual void _notifyAttached(Page* parent); - /// Save the collection to a stream - virtual void save(StreamSerialiser& stream) = 0; - /// Called when the frame starts - virtual void frameStart(Real timeSinceLastFrame) = 0; - /// Called when the frame ends - virtual void frameEnd(Real timeElapsed) = 0; - /// Notify a section of the current camera - virtual void notifyCamera(Camera* cam) = 0; - - - /// Prepare data - may be called in the background - virtual bool prepare(StreamSerialiser& ser) = 0; - /// Load - will be called in main thread - virtual void load() = 0; - /// Unload - will be called in main thread - virtual void unload() = 0; - /// Unprepare data - may be called in the background - virtual void unprepare() = 0; - - - }; - - - /** @} */ - /** @} */ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Paging + * Some details on paging component + * @{ + */ + + + /** Definition of the interface for a collection of PageContent instances. + @remarks + This class acts as a grouping level for PageContent instances. Rather than + PageContent instances being held in a list directly under Page, which might + be the most obvious solution, this intermediate class is here to allow + the collection of relevant PageContent instances to be modified at runtime + if required. For example, potentially you might want to define Page-level LOD + in which different collections of PageContent are loaded at different times. + */ + class _OgrePagingExport PageContentCollection : public PageAlloc + { + protected: + PageContentCollectionFactory* mCreator; + Page* mParent; + public: + static const uint32 CHUNK_ID; + static const uint16 CHUNK_VERSION; + + PageContentCollection(PageContentCollectionFactory* creator); + virtual ~PageContentCollection(); + + PageManager* getManager() const; + Page* getParentPage() const { return mParent; } + SceneManager* getSceneManager() const; + + /// Get the type of the collection, which will match it's factory + virtual const String& getType() const; + + /// Internal method to notify a collection that it is attached + virtual void _notifyAttached(Page* parent); + /// Save the collection to a stream + virtual void save(StreamSerialiser& stream) = 0; + /// Called when the frame starts + virtual void frameStart(Real timeSinceLastFrame) = 0; + /// Called when the frame ends + virtual void frameEnd(Real timeElapsed) = 0; + /// Notify a section of the current camera + virtual void notifyCamera(Camera* cam) = 0; + + + /// Prepare data - may be called in the background + virtual bool prepare(StreamSerialiser& ser) = 0; + /// Load - will be called in main thread + virtual void load() = 0; + /// Unload - will be called in main thread + virtual void unload() = 0; + /// Unprepare data - may be called in the background + virtual void unprepare() = 0; + + + }; + + + /** @} */ + /** @} */ } #endif diff --git a/Components/Paging/include/OgrePageContentCollectionFactory.h b/Components/Paging/include/OgrePageContentCollectionFactory.h index 8584678c5a8..4ec623cd55d 100644 --- a/Components/Paging/include/OgrePageContentCollectionFactory.h +++ b/Components/Paging/include/OgrePageContentCollectionFactory.h @@ -33,30 +33,30 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Paging - * Some details on paging component - * @{ - */ - - /** Define the interface to a factory class that will create subclasses - of PageContentCollection. - */ - class PageContentCollectionFactory : public PageAlloc - { - public: - PageContentCollectionFactory() {} - virtual ~PageContentCollectionFactory() {} - - virtual const String& getName() const = 0; - virtual PageContentCollection* createInstance() = 0; - virtual void destroyInstance(PageContentCollection*) = 0; - }; - - /** @} */ - /** @} */ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Paging + * Some details on paging component + * @{ + */ + + /** Define the interface to a factory class that will create subclasses + of PageContentCollection. + */ + class PageContentCollectionFactory : public PageAlloc + { + public: + PageContentCollectionFactory() {} + virtual ~PageContentCollectionFactory() {} + + virtual const String& getName() const = 0; + virtual PageContentCollection* createInstance() = 0; + virtual void destroyInstance(PageContentCollection*) = 0; + }; + + /** @} */ + /** @} */ } #endif diff --git a/Components/Paging/include/OgrePageContentFactory.h b/Components/Paging/include/OgrePageContentFactory.h index 47ac1361e59..94a71b280dd 100644 --- a/Components/Paging/include/OgrePageContentFactory.h +++ b/Components/Paging/include/OgrePageContentFactory.h @@ -35,33 +35,33 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ + /** \addtogroup Optional Components + * @{ + */ - /** \addtogroup Paging - * Some details on paging component - * @{ - */ + /** \addtogroup Paging + * Some details on paging component + * @{ + */ - /** Define the interface to a factory class that will create subclasses - of PageContent. - */ - class PageContentFactory : public PageAlloc - { - public: - PageContentFactory() {} - virtual ~PageContentFactory() {} + /** Define the interface to a factory class that will create subclasses + of PageContent. + */ + class PageContentFactory : public PageAlloc + { + public: + PageContentFactory() {} + virtual ~PageContentFactory() {} - virtual const String& getName() const = 0; - virtual PageContent* createInstance() = 0; - virtual void destroyInstance(PageContent*) = 0; + virtual const String& getName() const = 0; + virtual PageContent* createInstance() = 0; + virtual void destroyInstance(PageContent*) = 0; - }; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/Components/Paging/include/OgrePageFileFormats.h b/Components/Paging/include/OgrePageFileFormats.h index 413e50299e5..3c7e68c139e 100644 --- a/Components/Paging/include/OgrePageFileFormats.h +++ b/Components/Paging/include/OgrePageFileFormats.h @@ -41,179 +41,179 @@ THE SOFTWARE. /** @file - The paging file format is a composite one - a single file / stream can contain - data which is not necessarily all read by a single class. Instead, data - chunks can be read by different classes, allowing the format to be extended to - different types smoothly. - @par - Paging world files have by default an extension ".world", but that is not - a requirement. Internally, the only thing that matters is the data chunks - and their identifiers, which are 4-character codes embedded in a uint32 as - calculated by StreamSerialiser::makeIdentifier. All data will be read and - written using DataStream and the StreamSerialiser class. - @par - Data types are expressed at the lowest level exposed by the StreamSerialiser class, - which is used to read / write this file. - @par - Chunk Definitions - @par - PagedWorld (Identifier 'PWLD')\n - [Version 1] - - - - - - - - - - - - - - - - -
      NameTypeDescription
      World Namechar*The name of the world - should be unique
      PagedWorldSection ListChunk ListA variable-length list of nested PagedWorldSection chunks
      + The paging file format is a composite one - a single file / stream can contain + data which is not necessarily all read by a single class. Instead, data + chunks can be read by different classes, allowing the format to be extended to + different types smoothly. + @par + Paging world files have by default an extension ".world", but that is not + a requirement. Internally, the only thing that matters is the data chunks + and their identifiers, which are 4-character codes embedded in a uint32 as + calculated by StreamSerialiser::makeIdentifier. All data will be read and + written using DataStream and the StreamSerialiser class. + @par + Data types are expressed at the lowest level exposed by the StreamSerialiser class, + which is used to read / write this file. + @par + Chunk Definitions + @par + PagedWorld (Identifier 'PWLD')\n + [Version 1] + + + + + + + + + + + + + + + + +
      NameTypeDescription
      World Namechar*The name of the world - should be unique
      PagedWorldSection ListChunk ListA variable-length list of nested PagedWorldSection chunks
      - @par - PagedWorldSection (Identifier 'PWSC')\n - [Version 1] - - - - - - - - - - - - - - - - - - - - - - - - - - -
      NameTypeDescription
      World Section Namechar*The name of the world section - should be unique within world
      Bounding boxAABBAABB of this world section in world space
      PageStrategy namechar*The name of the PageStrategy class this world section uses to manage pages
      Page Strategy DataNested ChunkPageStrategy specific data for this world section
      + @par + PagedWorldSection (Identifier 'PWSC')\n + [Version 1] + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeDescription
      World Section Namechar*The name of the world section - should be unique within world
      Bounding boxAABBAABB of this world section in world space
      PageStrategy namechar*The name of the PageStrategy class this world section uses to manage pages
      Page Strategy DataNested ChunkPageStrategy specific data for this world section
      - @par - PagedStrategyData (Identifier defined by subclass)\n - [Version 1] - - - - - - - - - - - -
      NameTypeDescription
      PageStrategy defined???This chunk will contain data as defined by the specific PageStrategyData used by the - parent PagedWorldSection
      - @par - Page (Identifier 'PAGE')\n - [Version 1] - - - - - - - - - - - - - - - - -
      NameTypeDescription
      Page IDuint32The identifier of the page
      PageContentCollection listNested chunk list1-n nested chunks of type PageContentCollection
      - @par - PageContentCollection (Identifier 'PGCC')\n - [Version 1] - - - - - - - - - - - - - - - - -
      NameTypeDescription
      Factory namechar*The name of the content collection factory
      PageContentCollectionData chunkNested chunkData required to initialise & configure the content collection
      - @par - PageContentCollectionData (Identifier defined by subclass)\n - [Version 1] - - - - - - - - - - - -
      NameTypeDescription
      PageContentCollection subclass defined???This chunk will contain data as defined by the specific PageContentCollection subclass
      - @par - PageContent (Identifier 'PGCN')\n - [Version 1] - - - - - - - - - - - - - - - - -
      NameTypeDescription
      Factory namechar*The name of the content factory
      PageContentData chunkNested chunkData required to initialise & configure the content
      - @par - PageContentData (Identifier defined by subclass)\n - [Version 1] - - - - - - - - - - - -
      NameTypeDescription
      PageContent subclass defined???This chunk will contain data as defined by the specific PageContent subclass
      + @par + PagedStrategyData (Identifier defined by subclass)\n + [Version 1] + + + + + + + + + + + +
      NameTypeDescription
      PageStrategy defined???This chunk will contain data as defined by the specific PageStrategyData used by the + parent PagedWorldSection
      + @par + Page (Identifier 'PAGE')\n + [Version 1] + + + + + + + + + + + + + + + + +
      NameTypeDescription
      Page IDuint32The identifier of the page
      PageContentCollection listNested chunk list1-n nested chunks of type PageContentCollection
      + @par + PageContentCollection (Identifier 'PGCC')\n + [Version 1] + + + + + + + + + + + + + + + + +
      NameTypeDescription
      Factory namechar*The name of the content collection factory
      PageContentCollectionData chunkNested chunkData required to initialise & configure the content collection
      + @par + PageContentCollectionData (Identifier defined by subclass)\n + [Version 1] + + + + + + + + + + + +
      NameTypeDescription
      PageContentCollection subclass defined???This chunk will contain data as defined by the specific PageContentCollection subclass
      + @par + PageContent (Identifier 'PGCN')\n + [Version 1] + + + + + + + + + + + + + + + + +
      NameTypeDescription
      Factory namechar*The name of the content factory
      PageContentData chunkNested chunkData required to initialise & configure the content
      + @par + PageContentData (Identifier defined by subclass)\n + [Version 1] + + + + + + + + + + + +
      NameTypeDescription
      PageContent subclass defined???This chunk will contain data as defined by the specific PageContent subclass
      */ /*@}*/ diff --git a/Components/Paging/include/OgrePageManager.h b/Components/Paging/include/OgrePageManager.h index 106fc5d0c88..7fdfd9afc9d 100644 --- a/Components/Paging/include/OgrePageManager.h +++ b/Components/Paging/include/OgrePageManager.h @@ -37,443 +37,443 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Paging - * Some details on paging component - * @{ - */ - - class PagedWorldSection; - class PagedWorldSectionFactory; - - - /** Abstract class that can be implemented by the user application to - provide a way to retrieve or generate page data from a source of their choosing. - @note - All of the methods in this class can be called in a background, non-render thread. - */ - class PageProvider - { - public: - PageProvider() {} - virtual ~PageProvider() {} - - /** Give a provider the opportunity to prepare page content procedurally. - @remarks - This call may well happen in a separate thread so it should not access - GPU resources, use loadProceduralPage for that - @return true if the page was populated, false otherwise - */ - virtual bool prepareProceduralPage(Page* page, PagedWorldSection* section) { return false; } - /** Give a provider the opportunity to load page content procedurally. - @remarks - This call will happen in the main render thread so it can access GPU resources. - Use prepareProceduralPage for background preparation. - @return true if the page was populated, false otherwise - */ - virtual bool loadProceduralPage(Page* page, PagedWorldSection* section) { return false; } - /** Give a provider the opportunity to unload page content procedurally. - @remarks - You should not call this method directly. This call will happen in - the main render thread so it can access GPU resources. Use _unprepareProceduralPage - for background preparation. - @return true if the page was populated, false otherwise - */ - virtual bool unloadProceduralPage(Page* page, PagedWorldSection* section) { return false; } - /** Give a provider the opportunity to unprepare page content procedurally. - @remarks - You should not call this method directly. This call may well happen in - a separate thread so it should not access GPU resources, use _unloadProceduralPage - for that - @return true if the page was unpopulated, false otherwise - */ - virtual bool unprepareProceduralPage(Page* page, PagedWorldSection* section) { return false; } - - /** Get a serialiser set up to read PagedWorld data for the given world filename. - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - */ - virtual StreamSerialiser* readWorldStream(const String& filename) { return 0; } - /** Get a serialiser set up to write PagedWorld data for the given world filename. - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - */ - virtual StreamSerialiser* writeWorldStream(const String& filename) { return 0; } - /** Get a serialiser set up to read Page data for the given PageID, - or null if this provider cannot supply one. - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - @param pageID The ID of the page being requested - @param section The parent section to which this page will belong - */ - virtual StreamSerialiser* readPageStream(PageID pageID, PagedWorldSection* section) { return 0; } - - /** Get a serialiser set up to write Page data for the given PageID, - or null if this provider cannot supply one. - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - @param pageID The ID of the page being requested - @param section The parent section to which this page will belong - */ - virtual StreamSerialiser* writePageStream(PageID pageID, PagedWorldSection* section) { return 0; } - }; - - /** The PageManager is the entry point through which you load all PagedWorld instances, - and the place where PageStrategy instances and factory classes are - registered to customise the paging behaviour. - @remarks - To get started, the minimum you need is a PagedWorld with at least one PagedWorldSection - within it, and at least one Camera being tracked (see addCamera). - */ - class _OgrePagingExport PageManager : public PageAlloc - { - public: - PageManager(); - virtual ~PageManager(); - - /** Create a new PagedWorld instance. - @param name Optionally give a name to the world (if no name is given, one - will be generated). - */ - PagedWorld* createWorld(const String& name = BLANKSTRING); - - /** Destroy a world. */ - void destroyWorld(const String& name); - - /** Destroy a world. */ - void destroyWorld(PagedWorld* world); - - /** Load a new PagedWorld from a file. - @param filename The name of the file to load (standard is .world) - @param name Optionally give a name to the world (if no name is given, one - will be generated). - */ - PagedWorld* loadWorld(const String& filename, const String& name = BLANKSTRING); - /** Load a new PagedWorld from a stream. - @param stream A stream from which to load the world data - @param name Optionally give a name to the world (if no name is given, one - will be generated). - */ - PagedWorld* loadWorld(const DataStreamPtr& stream, const String& name = BLANKSTRING); - /** Save a PagedWorld instance to a file. - @param world The world to be saved - @param filename The filename to save the data to - */ - void saveWorld(PagedWorld* world, const String& filename); - /** Save a PagedWorld instance to a file. - @param world The world to be saved - @param stream The stream to save the data to - */ - void saveWorld(PagedWorld* world, const DataStreamPtr& stream); - /** Get a named world. - @param name The name of the world (not a filename, the identifying name) - @return The world, or null if the world doesn't exist. - */ - PagedWorld* getWorld(const String& name); - typedef map::type WorldMap; - /** Get a reference to the worlds that are currently loaded. */ - const WorldMap& getWorlds() const { return mWorlds; } - - - typedef map::type StrategyMap; - /** Add a new PageStrategy implementation. - @remarks - The caller remains resonsible for destruction of this instance. - */ - void addStrategy(PageStrategy* strategy); - - /** Remove a PageStrategy implementation. - */ - void removeStrategy(PageStrategy* strategy); - - /** Get a PageStrategy. - @param name The name of the strategy to retrieve - @return Pointer to a PageStrategy, or null if the strategy was not found. - */ - PageStrategy* getStrategy(const String& name); - - /** Get a reference to the registered strategies. - */ - const StrategyMap& getStrategies() const; - - - typedef map::type ContentCollectionFactoryMap; - /** Add a new PageContentCollectionFactory implementation. - @remarks - The caller remains resonsible for destruction of this instance. - */ - void addContentCollectionFactory(PageContentCollectionFactory* f); - - /** Remove a PageContentCollectionFactory implementation. - */ - void removeContentCollectionFactory(PageContentCollectionFactory* f); - - /** Get a PageContentCollectionFactory. - @param name The name of the factory to retrieve - @return Pointer to a PageContentCollectionFactory, or null if the ContentCollection was not found. - */ - PageContentCollectionFactory* getContentCollectionFactory(const String& name); - - /** Create a new instance of PageContentCollection using the registered - factories. - @param typeName The name of the type of collection to create - */ - PageContentCollection* createContentCollection(const String& typeName); - - /** Destroy an instance of PageContentCollection. */ - void destroyContentCollection(PageContentCollection* coll); - - /** Get a reference to the registered strategies. - */ - const ContentCollectionFactoryMap& getContentCollectionFactories() const; - - typedef map::type ContentFactoryMap; - /** Add a new PageContentFactory implementation. - @remarks - The caller remains resonsible for destruction of this instance. - */ - void addContentFactory(PageContentFactory* f); - - /** Remove a PageContentFactory implementation. - */ - void removeContentFactory(PageContentFactory* f); - - /** Get a PageContentFactory. - @param name The name of the factory to retrieve - @return Pointer to a PageContentFactory, or null if the Content was not found. - */ - PageContentFactory* getContentFactory(const String& name); - - /** Get a reference to the registered strategies. - */ - const ContentFactoryMap& getContentFactories() const; - - /** Create a new instance of PageContent using the registered - factories. - @param typeName The name of the type of content to create - */ - PageContent* createContent(const String& typeName); - - /** Destroy an instance of PageContent. */ - void destroyContent(PageContent* c); - - - typedef map::type WorldSectionFactoryMap; - /** Add a new PagedWorldSectionFactory implementation. - @remarks - The caller remains resonsible for destruction of this instance. - */ - void addWorldSectionFactory(PagedWorldSectionFactory* f); - - /** Remove a PagedWorldSectionFactory implementation. - */ - void removeWorldSectionFactory(PagedWorldSectionFactory* f); - - /** Get a PagedWorldSectionFactory. - @param name The name of the factory to retrieve - @return Pointer to a PagedWorldSectionFactory, or null if the WorldSection was not found. - */ - PagedWorldSectionFactory* getWorldSectionFactory(const String& name); - - /** Create a new instance of PagedWorldSection using the registered - factories. - @param typeName The name of the type of collection to create - @param name The instance name - @param parent The parent world - @param sm The SceneManager to use (can be null if this is to be loaded) - */ - PagedWorldSection* createWorldSection(const String& typeName, - const String& name, PagedWorld* parent, SceneManager* sm); - - /** Destroy an instance of PagedWorldSection. */ - void destroyWorldSection(PagedWorldSection* s); - - /** Get a reference to the registered strategies. - */ - const WorldSectionFactoryMap& getWorldSectionFactories() const; - - - /** Set the PageProvider which can provide streams for any Page. - @remarks - This is the top-level way that you can direct how Page data is loaded. - When data for a Page is requested for a PagedWorldSection, the following - sequence of classes will be checked to see if they have a provider willing - to supply the stream: PagedWorldSection, PagedWorld, PageManager. - If none of these do, then the default behaviour is to look for a file - called worldname_sectionname_pageID.page. - @note - The caller remains responsible for the destruction of the provider. - */ - void setPageProvider(PageProvider* provider) { mPageProvider = provider; } - - /** Get the PageProvider which can provide streams for any Page. */ - PageProvider* getPageProvider() const { return mPageProvider; } - - /** Give a provider the opportunity to prepare page content procedurally. - @remarks - You should not call this method directly. This call may well happen in - a separate thread so it should not access GPU resources, use _loadProceduralPage - for that - @return true if the page was populated, false otherwise - */ - virtual bool _prepareProceduralPage(Page* page, PagedWorldSection* section); - /** Give a provider the opportunity to prepare page content procedurally. - @remarks - You should not call this method directly. This call will happen in - the main render thread so it can access GPU resources. Use _prepareProceduralPage - for background preparation. - @return true if the page was populated, false otherwise - */ - virtual bool _loadProceduralPage(Page* page, PagedWorldSection* section); - /** Give a manager the opportunity to unload page content procedurally. - @remarks - You should not call this method directly. This call will happen in - the main render thread so it can access GPU resources. Use _unprepareProceduralPage - for background preparation. - @return true if the page was populated, false otherwise - */ - virtual bool _unloadProceduralPage(Page* page, PagedWorldSection* section); - /** Give a manager the opportunity to unprepare page content procedurally. - @remarks - You should not call this method directly. This call may well happen in - a separate thread so it should not access GPU resources, use _unloadProceduralPage - for that - @return true if the page was unpopulated, false otherwise - */ - virtual bool _unprepareProceduralPage(Page* page, PagedWorldSection* section); - /** Get a serialiser set up to read Page data for the given PageID. - @param pageID The ID of the page being requested - @param section The parent section to which this page will belong - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - */ - StreamSerialiser* _readPageStream(PageID pageID, PagedWorldSection* section); - - /** Get a serialiser set up to write Page data for the given PageID. - @param pageID The ID of the page being requested - @param section The parent section to which this page will belong - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - */ - StreamSerialiser* _writePageStream(PageID pageID, PagedWorldSection* section); - /** Get a serialiser set up to read PagedWorld data for the given world name. - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - */ - StreamSerialiser* _readWorldStream(const String& filename); - - /** Get a serialiser set up to write PagedWorld data. - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - */ - StreamSerialiser* _writeWorldStream(const String& filename); - - /** Get the resource group that will be used to read/write files when the - default load routines are used. - */ - const String& getPageResourceGroup() const { return mPageResourceGroup; } - /** Set the resource group that will be used to read/write files when the - default load routines are used. - */ - void setPageResourceGroup(const String& g) { mPageResourceGroup = g; } - - /** Tells the paging system to start tracking a given camera. - @remarks - In order for the paging system to function it needs to know which - Cameras to track. You may not want to have all your cameras affect - the paging system, so just add the cameras you want it to keep track of - here. - */ - void addCamera(Camera* c); - - /** Tells the paging system to stop tracking a given camera. - */ - void removeCamera(Camera* c); - - /** Returns whether or not a given camera is being watched by the paging system. - */ - bool hasCamera(Camera* c) const; - - typedef vector::type CameraList; - /** Returns a list of cameras being tracked. */ - const CameraList& getCameraList() const; - - /** Set the debug display level. - @remarks - This setting controls how much debug information is displayed in the scene. - The exact interpretation of this value depends on the PageStrategy you're - using, and whether the PageContent decides to also display debug information. - Generally speaking, 0 means no debug display, 1 means simple debug - display (usually the PageStrategy) and anything more than that is - up to the classes involved. - */ - void setDebugDisplayLevel(uint8 lvl) { mDebugDisplayLvl = lvl; } - /** Get the debug display level. */ - uint8 getDebugDisplayLevel() const { return mDebugDisplayLvl; } - - /** Pause or unpause all paging operations. - @remarks - Using this method you can stop pages being loaded or unloaded for a - period of time, 'freezing' the current page state as it is. - @param enabled True to proceed with normal paging operations, false to pause. - */ - void setPagingOperationsEnabled(bool enabled) { mPagingEnabled = enabled; } - - /** Get whether paging operations are currently allowed to happen. */ - bool getPagingOperationsEnabled() const { return mPagingEnabled; } - - - protected: - - class EventRouter : public Camera::Listener, public FrameListener - { - public: - PageManager* pManager; - WorldMap* pWorldMap; - CameraList* pCameraList; - - EventRouter() : pManager(0), pWorldMap(0), pCameraList(0) {} - ~EventRouter() {} - - void cameraPreRenderScene(Camera* cam); - void cameraDestroyed(Camera* cam); - bool frameStarted(const FrameEvent& evt); - bool frameEnded(const FrameEvent& evt); - }; - - void createStandardStrategies(); - void createStandardContentFactories(); - - WorldMap mWorlds; - StrategyMap mStrategies; - ContentCollectionFactoryMap mContentCollectionFactories; - ContentFactoryMap mContentFactories; - WorldSectionFactoryMap mWorldSectionFactories; - NameGenerator mWorldNameGenerator; - PageProvider* mPageProvider; - String mPageResourceGroup; - CameraList mCameraList; - EventRouter mEventRouter; - uint8 mDebugDisplayLvl; - bool mPagingEnabled; - - Grid2DPageStrategy* mGrid2DPageStrategy; - Grid3DPageStrategy* mGrid3DPageStrategy; - SimplePageContentCollectionFactory* mSimpleCollectionFactory; - }; - - /** @} */ - /** @} */ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Paging + * Some details on paging component + * @{ + */ + + class PagedWorldSection; + class PagedWorldSectionFactory; + + + /** Abstract class that can be implemented by the user application to + provide a way to retrieve or generate page data from a source of their choosing. + @note + All of the methods in this class can be called in a background, non-render thread. + */ + class PageProvider + { + public: + PageProvider() {} + virtual ~PageProvider() {} + + /** Give a provider the opportunity to prepare page content procedurally. + @remarks + This call may well happen in a separate thread so it should not access + GPU resources, use loadProceduralPage for that + @return true if the page was populated, false otherwise + */ + virtual bool prepareProceduralPage(Page* page, PagedWorldSection* section) { return false; } + /** Give a provider the opportunity to load page content procedurally. + @remarks + This call will happen in the main render thread so it can access GPU resources. + Use prepareProceduralPage for background preparation. + @return true if the page was populated, false otherwise + */ + virtual bool loadProceduralPage(Page* page, PagedWorldSection* section) { return false; } + /** Give a provider the opportunity to unload page content procedurally. + @remarks + You should not call this method directly. This call will happen in + the main render thread so it can access GPU resources. Use _unprepareProceduralPage + for background preparation. + @return true if the page was populated, false otherwise + */ + virtual bool unloadProceduralPage(Page* page, PagedWorldSection* section) { return false; } + /** Give a provider the opportunity to unprepare page content procedurally. + @remarks + You should not call this method directly. This call may well happen in + a separate thread so it should not access GPU resources, use _unloadProceduralPage + for that + @return true if the page was unpopulated, false otherwise + */ + virtual bool unprepareProceduralPage(Page* page, PagedWorldSection* section) { return false; } + + /** Get a serialiser set up to read PagedWorld data for the given world filename. + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + */ + virtual StreamSerialiser* readWorldStream(const String& filename) { return 0; } + /** Get a serialiser set up to write PagedWorld data for the given world filename. + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + */ + virtual StreamSerialiser* writeWorldStream(const String& filename) { return 0; } + /** Get a serialiser set up to read Page data for the given PageID, + or null if this provider cannot supply one. + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + @param pageID The ID of the page being requested + @param section The parent section to which this page will belong + */ + virtual StreamSerialiser* readPageStream(PageID pageID, PagedWorldSection* section) { return 0; } + + /** Get a serialiser set up to write Page data for the given PageID, + or null if this provider cannot supply one. + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + @param pageID The ID of the page being requested + @param section The parent section to which this page will belong + */ + virtual StreamSerialiser* writePageStream(PageID pageID, PagedWorldSection* section) { return 0; } + }; + + /** The PageManager is the entry point through which you load all PagedWorld instances, + and the place where PageStrategy instances and factory classes are + registered to customise the paging behaviour. + @remarks + To get started, the minimum you need is a PagedWorld with at least one PagedWorldSection + within it, and at least one Camera being tracked (see addCamera). + */ + class _OgrePagingExport PageManager : public PageAlloc + { + public: + PageManager(); + virtual ~PageManager(); + + /** Create a new PagedWorld instance. + @param name Optionally give a name to the world (if no name is given, one + will be generated). + */ + PagedWorld* createWorld(const String& name = BLANKSTRING); + + /** Destroy a world. */ + void destroyWorld(const String& name); + + /** Destroy a world. */ + void destroyWorld(PagedWorld* world); + + /** Load a new PagedWorld from a file. + @param filename The name of the file to load (standard is .world) + @param name Optionally give a name to the world (if no name is given, one + will be generated). + */ + PagedWorld* loadWorld(const String& filename, const String& name = BLANKSTRING); + /** Load a new PagedWorld from a stream. + @param stream A stream from which to load the world data + @param name Optionally give a name to the world (if no name is given, one + will be generated). + */ + PagedWorld* loadWorld(const DataStreamPtr& stream, const String& name = BLANKSTRING); + /** Save a PagedWorld instance to a file. + @param world The world to be saved + @param filename The filename to save the data to + */ + void saveWorld(PagedWorld* world, const String& filename); + /** Save a PagedWorld instance to a file. + @param world The world to be saved + @param stream The stream to save the data to + */ + void saveWorld(PagedWorld* world, const DataStreamPtr& stream); + /** Get a named world. + @param name The name of the world (not a filename, the identifying name) + @return The world, or null if the world doesn't exist. + */ + PagedWorld* getWorld(const String& name); + typedef map::type WorldMap; + /** Get a reference to the worlds that are currently loaded. */ + const WorldMap& getWorlds() const { return mWorlds; } + + + typedef map::type StrategyMap; + /** Add a new PageStrategy implementation. + @remarks + The caller remains resonsible for destruction of this instance. + */ + void addStrategy(PageStrategy* strategy); + + /** Remove a PageStrategy implementation. + */ + void removeStrategy(PageStrategy* strategy); + + /** Get a PageStrategy. + @param name The name of the strategy to retrieve + @return Pointer to a PageStrategy, or null if the strategy was not found. + */ + PageStrategy* getStrategy(const String& name); + + /** Get a reference to the registered strategies. + */ + const StrategyMap& getStrategies() const; + + + typedef map::type ContentCollectionFactoryMap; + /** Add a new PageContentCollectionFactory implementation. + @remarks + The caller remains resonsible for destruction of this instance. + */ + void addContentCollectionFactory(PageContentCollectionFactory* f); + + /** Remove a PageContentCollectionFactory implementation. + */ + void removeContentCollectionFactory(PageContentCollectionFactory* f); + + /** Get a PageContentCollectionFactory. + @param name The name of the factory to retrieve + @return Pointer to a PageContentCollectionFactory, or null if the ContentCollection was not found. + */ + PageContentCollectionFactory* getContentCollectionFactory(const String& name); + + /** Create a new instance of PageContentCollection using the registered + factories. + @param typeName The name of the type of collection to create + */ + PageContentCollection* createContentCollection(const String& typeName); + + /** Destroy an instance of PageContentCollection. */ + void destroyContentCollection(PageContentCollection* coll); + + /** Get a reference to the registered strategies. + */ + const ContentCollectionFactoryMap& getContentCollectionFactories() const; + + typedef map::type ContentFactoryMap; + /** Add a new PageContentFactory implementation. + @remarks + The caller remains resonsible for destruction of this instance. + */ + void addContentFactory(PageContentFactory* f); + + /** Remove a PageContentFactory implementation. + */ + void removeContentFactory(PageContentFactory* f); + + /** Get a PageContentFactory. + @param name The name of the factory to retrieve + @return Pointer to a PageContentFactory, or null if the Content was not found. + */ + PageContentFactory* getContentFactory(const String& name); + + /** Get a reference to the registered strategies. + */ + const ContentFactoryMap& getContentFactories() const; + + /** Create a new instance of PageContent using the registered + factories. + @param typeName The name of the type of content to create + */ + PageContent* createContent(const String& typeName); + + /** Destroy an instance of PageContent. */ + void destroyContent(PageContent* c); + + + typedef map::type WorldSectionFactoryMap; + /** Add a new PagedWorldSectionFactory implementation. + @remarks + The caller remains resonsible for destruction of this instance. + */ + void addWorldSectionFactory(PagedWorldSectionFactory* f); + + /** Remove a PagedWorldSectionFactory implementation. + */ + void removeWorldSectionFactory(PagedWorldSectionFactory* f); + + /** Get a PagedWorldSectionFactory. + @param name The name of the factory to retrieve + @return Pointer to a PagedWorldSectionFactory, or null if the WorldSection was not found. + */ + PagedWorldSectionFactory* getWorldSectionFactory(const String& name); + + /** Create a new instance of PagedWorldSection using the registered + factories. + @param typeName The name of the type of collection to create + @param name The instance name + @param parent The parent world + @param sm The SceneManager to use (can be null if this is to be loaded) + */ + PagedWorldSection* createWorldSection(const String& typeName, + const String& name, PagedWorld* parent, SceneManager* sm); + + /** Destroy an instance of PagedWorldSection. */ + void destroyWorldSection(PagedWorldSection* s); + + /** Get a reference to the registered strategies. + */ + const WorldSectionFactoryMap& getWorldSectionFactories() const; + + + /** Set the PageProvider which can provide streams for any Page. + @remarks + This is the top-level way that you can direct how Page data is loaded. + When data for a Page is requested for a PagedWorldSection, the following + sequence of classes will be checked to see if they have a provider willing + to supply the stream: PagedWorldSection, PagedWorld, PageManager. + If none of these do, then the default behaviour is to look for a file + called worldname_sectionname_pageID.page. + @note + The caller remains responsible for the destruction of the provider. + */ + void setPageProvider(PageProvider* provider) { mPageProvider = provider; } + + /** Get the PageProvider which can provide streams for any Page. */ + PageProvider* getPageProvider() const { return mPageProvider; } + + /** Give a provider the opportunity to prepare page content procedurally. + @remarks + You should not call this method directly. This call may well happen in + a separate thread so it should not access GPU resources, use _loadProceduralPage + for that + @return true if the page was populated, false otherwise + */ + virtual bool _prepareProceduralPage(Page* page, PagedWorldSection* section); + /** Give a provider the opportunity to prepare page content procedurally. + @remarks + You should not call this method directly. This call will happen in + the main render thread so it can access GPU resources. Use _prepareProceduralPage + for background preparation. + @return true if the page was populated, false otherwise + */ + virtual bool _loadProceduralPage(Page* page, PagedWorldSection* section); + /** Give a manager the opportunity to unload page content procedurally. + @remarks + You should not call this method directly. This call will happen in + the main render thread so it can access GPU resources. Use _unprepareProceduralPage + for background preparation. + @return true if the page was populated, false otherwise + */ + virtual bool _unloadProceduralPage(Page* page, PagedWorldSection* section); + /** Give a manager the opportunity to unprepare page content procedurally. + @remarks + You should not call this method directly. This call may well happen in + a separate thread so it should not access GPU resources, use _unloadProceduralPage + for that + @return true if the page was unpopulated, false otherwise + */ + virtual bool _unprepareProceduralPage(Page* page, PagedWorldSection* section); + /** Get a serialiser set up to read Page data for the given PageID. + @param pageID The ID of the page being requested + @param section The parent section to which this page will belong + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + */ + StreamSerialiser* _readPageStream(PageID pageID, PagedWorldSection* section); + + /** Get a serialiser set up to write Page data for the given PageID. + @param pageID The ID of the page being requested + @param section The parent section to which this page will belong + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + */ + StreamSerialiser* _writePageStream(PageID pageID, PagedWorldSection* section); + /** Get a serialiser set up to read PagedWorld data for the given world name. + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + */ + StreamSerialiser* _readWorldStream(const String& filename); + + /** Get a serialiser set up to write PagedWorld data. + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + */ + StreamSerialiser* _writeWorldStream(const String& filename); + + /** Get the resource group that will be used to read/write files when the + default load routines are used. + */ + const String& getPageResourceGroup() const { return mPageResourceGroup; } + /** Set the resource group that will be used to read/write files when the + default load routines are used. + */ + void setPageResourceGroup(const String& g) { mPageResourceGroup = g; } + + /** Tells the paging system to start tracking a given camera. + @remarks + In order for the paging system to function it needs to know which + Cameras to track. You may not want to have all your cameras affect + the paging system, so just add the cameras you want it to keep track of + here. + */ + void addCamera(Camera* c); + + /** Tells the paging system to stop tracking a given camera. + */ + void removeCamera(Camera* c); + + /** Returns whether or not a given camera is being watched by the paging system. + */ + bool hasCamera(Camera* c) const; + + typedef vector::type CameraList; + /** Returns a list of cameras being tracked. */ + const CameraList& getCameraList() const; + + /** Set the debug display level. + @remarks + This setting controls how much debug information is displayed in the scene. + The exact interpretation of this value depends on the PageStrategy you're + using, and whether the PageContent decides to also display debug information. + Generally speaking, 0 means no debug display, 1 means simple debug + display (usually the PageStrategy) and anything more than that is + up to the classes involved. + */ + void setDebugDisplayLevel(uint8 lvl) { mDebugDisplayLvl = lvl; } + /** Get the debug display level. */ + uint8 getDebugDisplayLevel() const { return mDebugDisplayLvl; } + + /** Pause or unpause all paging operations. + @remarks + Using this method you can stop pages being loaded or unloaded for a + period of time, 'freezing' the current page state as it is. + @param enabled True to proceed with normal paging operations, false to pause. + */ + void setPagingOperationsEnabled(bool enabled) { mPagingEnabled = enabled; } + + /** Get whether paging operations are currently allowed to happen. */ + bool getPagingOperationsEnabled() const { return mPagingEnabled; } + + + protected: + + class EventRouter : public Camera::Listener, public FrameListener + { + public: + PageManager* pManager; + WorldMap* pWorldMap; + CameraList* pCameraList; + + EventRouter() : pManager(0), pWorldMap(0), pCameraList(0) {} + ~EventRouter() {} + + void cameraPreRenderScene(Camera* cam); + void cameraDestroyed(Camera* cam); + bool frameStarted(const FrameEvent& evt); + bool frameEnded(const FrameEvent& evt); + }; + + void createStandardStrategies(); + void createStandardContentFactories(); + + WorldMap mWorlds; + StrategyMap mStrategies; + ContentCollectionFactoryMap mContentCollectionFactories; + ContentFactoryMap mContentFactories; + WorldSectionFactoryMap mWorldSectionFactories; + NameGenerator mWorldNameGenerator; + PageProvider* mPageProvider; + String mPageResourceGroup; + CameraList mCameraList; + EventRouter mEventRouter; + uint8 mDebugDisplayLvl; + bool mPagingEnabled; + + Grid2DPageStrategy* mGrid2DPageStrategy; + Grid3DPageStrategy* mGrid3DPageStrategy; + SimplePageContentCollectionFactory* mSimpleCollectionFactory; + }; + + /** @} */ + /** @} */ } #endif diff --git a/Components/Paging/include/OgrePageStrategy.h b/Components/Paging/include/OgrePageStrategy.h index 69fec3241e9..0ecec9f45e4 100644 --- a/Components/Paging/include/OgrePageStrategy.h +++ b/Components/Paging/include/OgrePageStrategy.h @@ -34,105 +34,105 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Paging - * Some details on paging component - */ - /*@{*/ - - - /** Abstract marker class representing the data held against the PagedWorldSection - which is specifically used by the PageStrategy. - */ - class _OgrePagingExport PageStrategyData : public PageAlloc - { - public: - PageStrategyData() {} - virtual ~PageStrategyData() {} - - /// Load this data from a stream (returns true if successful) - virtual bool load(StreamSerialiser& stream) = 0; - /// Save this data to a stream - virtual void save(StreamSerialiser& stream) = 0; - - - }; - - - /** Defines the interface to a strategy class which is responsible for deciding - when Page instances are requested for addition and removal from the - paging system. - @remarks - The interface is deliberately light, with no specific mention of requesting - new Page instances. It is entirely up to the PageStrategy to respond - to the events raised on it and to call methods on other classes (such as - requesting new pages). - */ - class _OgrePagingExport PageStrategy : public PageAlloc - { - protected: - String mName; - PageManager* mManager; - public: - PageStrategy(const String& name, PageManager* manager) - : mName(name), mManager(manager) - { - - } - - virtual ~PageStrategy() {} - - const String& getName() const { return mName; } - PageManager* getManager() const { return mManager; } - - /// Called when the frame starts - virtual void frameStart(Real timeSinceLastFrame, PagedWorldSection* section) {} - /// Called when the frame ends - virtual void frameEnd(Real timeElapsed, PagedWorldSection* section) {} - /** Called when a camera is used for any kind of rendering. - @remarks - This is probably the primary way in which the strategy will request - new pages. - @param cam Camera which is being used for rendering. Class should not - rely on this pointer remaining valid permanently because no notification - will be given when the camera is destroyed. - */ - virtual void notifyCamera(Camera* cam, PagedWorldSection* section) {} - - /** Create a PageStrategyData instance containing the data specific to this - PageStrategy. - @par - This data will be held by a given PagedWorldSection and the structure of - the data will be specific to the PageStrategy subclass. - */ - virtual PageStrategyData* createData() = 0; - - /** Destroy a PageStrategyData instance containing the data specific to this - PageStrategy. - @par - This data will be held by a given PagedWorldSection and the structure of - the data will be specific to the PageStrategy subclass. - */ - virtual void destroyData(PageStrategyData* d) = 0; - - /** Update the contents of the passed in SceneNode to reflect the - debug display of a given page. - @remarks - The PageStrategy is to have complete control of the contents of this - SceneNode, it must not be altered / added to by others. - */ - virtual void updateDebugDisplay(Page* p, SceneNode* sn) = 0; - - /** Get the page ID for a given world position. - @return The page ID - */ - virtual PageID getPageID(const Vector3& worldPos, PagedWorldSection* section) = 0; - }; - - /*@}*/ - /*@}*/ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Paging + * Some details on paging component + */ + /*@{*/ + + + /** Abstract marker class representing the data held against the PagedWorldSection + which is specifically used by the PageStrategy. + */ + class _OgrePagingExport PageStrategyData : public PageAlloc + { + public: + PageStrategyData() {} + virtual ~PageStrategyData() {} + + /// Load this data from a stream (returns true if successful) + virtual bool load(StreamSerialiser& stream) = 0; + /// Save this data to a stream + virtual void save(StreamSerialiser& stream) = 0; + + + }; + + + /** Defines the interface to a strategy class which is responsible for deciding + when Page instances are requested for addition and removal from the + paging system. + @remarks + The interface is deliberately light, with no specific mention of requesting + new Page instances. It is entirely up to the PageStrategy to respond + to the events raised on it and to call methods on other classes (such as + requesting new pages). + */ + class _OgrePagingExport PageStrategy : public PageAlloc + { + protected: + String mName; + PageManager* mManager; + public: + PageStrategy(const String& name, PageManager* manager) + : mName(name), mManager(manager) + { + + } + + virtual ~PageStrategy() {} + + const String& getName() const { return mName; } + PageManager* getManager() const { return mManager; } + + /// Called when the frame starts + virtual void frameStart(Real timeSinceLastFrame, PagedWorldSection* section) {} + /// Called when the frame ends + virtual void frameEnd(Real timeElapsed, PagedWorldSection* section) {} + /** Called when a camera is used for any kind of rendering. + @remarks + This is probably the primary way in which the strategy will request + new pages. + @param cam Camera which is being used for rendering. Class should not + rely on this pointer remaining valid permanently because no notification + will be given when the camera is destroyed. + */ + virtual void notifyCamera(Camera* cam, PagedWorldSection* section) {} + + /** Create a PageStrategyData instance containing the data specific to this + PageStrategy. + @par + This data will be held by a given PagedWorldSection and the structure of + the data will be specific to the PageStrategy subclass. + */ + virtual PageStrategyData* createData() = 0; + + /** Destroy a PageStrategyData instance containing the data specific to this + PageStrategy. + @par + This data will be held by a given PagedWorldSection and the structure of + the data will be specific to the PageStrategy subclass. + */ + virtual void destroyData(PageStrategyData* d) = 0; + + /** Update the contents of the passed in SceneNode to reflect the + debug display of a given page. + @remarks + The PageStrategy is to have complete control of the contents of this + SceneNode, it must not be altered / added to by others. + */ + virtual void updateDebugDisplay(Page* p, SceneNode* sn) = 0; + + /** Get the page ID for a given world position. + @return The page ID + */ + virtual PageID getPageID(const Vector3& worldPos, PagedWorldSection* section) = 0; + }; + + /*@}*/ + /*@}*/ } #endif diff --git a/Components/Paging/include/OgrePagedWorld.h b/Components/Paging/include/OgrePagedWorld.h index cbe3d0afdf9..a906fb0cd71 100644 --- a/Components/Paging/include/OgrePagedWorld.h +++ b/Components/Paging/include/OgrePagedWorld.h @@ -35,216 +35,216 @@ THE SOFTWARE. namespace Ogre { - class PageManager; - - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Paging - * Some details on paging component - * @{ - */ - - - /** This class represents a collection of pages which make up a world. - @remarks - It's important to bear in mind that the PagedWorld only delineates the - world and knows how to find out about the contents of it. It does not, - by design, contain all elements of the world, in memory, at once. - */ - class _OgrePagingExport PagedWorld : public PageAlloc - { - protected: - String mName; - PageManager* mManager; - PageProvider* mPageProvider; - - public: - static const uint32 CHUNK_ID; - static const uint16 CHUNK_VERSION; - static const uint32 CHUNK_SECTIONDECLARATION_ID; - /** Constructor. - @param name The name of the world, which must be enough to identify the - place where data for it can be loaded from (doesn't have to be a filename - necessarily). - @param manager The PageManager that is in charge of providing this world with - services such as related object factories. - */ - PagedWorld(const String& name, PageManager* manager); - virtual ~PagedWorld(); - - const String& getName() const { return mName; } - /// Get the manager of this world - PageManager* getManager() const { return mManager; } - - /// Load world data from a file - void load(const String& filename); - /// Load world data from a stream - void load(const DataStreamPtr& stream); - /// Load world data from a serialiser (returns true if successful) - bool load(StreamSerialiser& stream); - /** Save world data to a file - @param filename The name of the file to create; this can either be an - absolute filename or - */ - void save(const String& filename); - /// Save world data to a stream - void save(const DataStreamPtr& stream); - /// Save world data to a serialiser - void save(StreamSerialiser& stream); - - /** Create a new section of the world based on a specialised type. - @remarks - World sections are areas of the world that use a particular - PageStrategy, with a certain set of parameters specific to that - strategy, and potentially some other rules. - So you would have more than one section in a world only - if you needed different simultaneous paging strategies, or you - wanted the same strategy but parameterised differently. - @param sceneMgr The SceneManager to use for this section. - @param typeName The type of section to use (must be registered - with PageManager), or blank to use the default type (simple grid) - @param sectionName An optional name to give the section (if none is - provided, one will be generated) - */ - PagedWorldSection* createSection(SceneManager* sceneMgr, - const String& typeName, - const String& sectionName = BLANKSTRING); - - - /** Create a new manually defined section of the world. - @remarks - World sections are areas of the world that use a particular - PageStrategy, with a certain set of parameters specific to that - strategy. So you would have more than one section in a world only - if you needed different simultaneous paging strategies, or you - wanted the same strategy but parameterised differently. - @param strategyName The name of the strategy to use (must be registered - with PageManager) - @param sceneMgr The SceneManager to use for this section - @param sectionName An optional name to give the section (if none is - provided, one will be generated) - */ - PagedWorldSection* createSection(const String& strategyName, SceneManager* sceneMgr, - const String& sectionName = BLANKSTRING); - - - /** Create a manually defined new section of the world. - @remarks - World sections are areas of the world that use a particular - PageStrategy, with a certain set of parameters specific to that - strategy. So you would have more than one section in a world only - if you needed different simultaneous paging strategies, or you - wanted the same strategy but parameterised differently. - @param strategy The strategy to use - @param sceneMgr The SceneManager to use for this section - @param sectionName An optional name to give the section (if none is - provided, one will be generated) - */ - PagedWorldSection* createSection(PageStrategy* strategy, SceneManager* sceneMgr, - const String& sectionName = BLANKSTRING); - /** Destroy a section of world. */ - void destroySection(const String& name); - /** Destroy a section of world. */ - void destroySection(PagedWorldSection* sec); - /** Destroy all world sections */ - void destroyAllSections(); - - /** Get the number of sections this world has. */ - size_t getSectionCount() const { return mSections.size(); } - - /** Retrieve a section of the world. */ - PagedWorldSection* getSection(const String& name); - - typedef map::type SectionMap; - /// Retrieve a const reference to all the sections in this world - const SectionMap& getSections() const { return mSections; } - - /** Set the PageProvider which can provide streams for Pages in this world. - @remarks - This is the top-level way that you can direct how Page data is loaded. - When data for a Page is requested for a PagedWorldSection, the following - sequence of classes will be checked to see if they have a provider willing - to supply the stream: PagedWorldSection, PagedWorld, PageManager. - If none of these do, then the default behaviour is to look for a file - called worldname_sectionname_pageID.page. - @note - The caller remains responsible for the destruction of the provider. - */ - void setPageProvider(PageProvider* provider) { mPageProvider = provider; } - - /** Get the PageProvider which can provide streams for Pages in this world. */ - PageProvider* getPageProvider() const { return mPageProvider; } - - /** Give a world the opportunity to prepare page content procedurally. - @remarks - You should not call this method directly. This call may well happen in - a separate thread so it should not access GPU resources, use _loadProceduralPage - for that - @return true if the page was populated, false otherwise - */ - virtual bool _prepareProceduralPage(Page* page, PagedWorldSection* section); - /** Give a world the opportunity to prepare page content procedurally. - @remarks - You should not call this method directly. This call will happen in - the main render thread so it can access GPU resources. Use _prepareProceduralPage - for background preparation. - @return true if the page was populated, false otherwise - */ - virtual bool _loadProceduralPage(Page* page, PagedWorldSection* section); - /** Give a world the opportunity to unload page content procedurally. - @remarks - You should not call this method directly. This call will happen in - the main render thread so it can access GPU resources. Use _unprepareProceduralPage - for background preparation. - @return true if the page was populated, false otherwise - */ - virtual bool _unloadProceduralPage(Page* page, PagedWorldSection* section); - /** Give a world the opportunity to unprepare page content procedurally. - @remarks - You should not call this method directly. This call may well happen in - a separate thread so it should not access GPU resources, use _unloadProceduralPage - for that - @return true if the page was unpopulated, false otherwise - */ - virtual bool _unprepareProceduralPage(Page* page, PagedWorldSection* section); - /** Get a serialiser set up to read Page data for the given PageID. - @param pageID The ID of the page being requested - @param section The parent section to which this page will belong - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - */ - StreamSerialiser* _readPageStream(PageID pageID, PagedWorldSection* section); - - /** Get a serialiser set up to read Page data for the given PageID. - @param pageID The ID of the page being requested - @param section The parent section to which this page will belong - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - */ - StreamSerialiser* _writePageStream(PageID pageID, PagedWorldSection* section); - - /// Called when the frame starts - virtual void frameStart(Real timeSinceLastFrame); - /// Called when the frame ends - virtual void frameEnd(Real timeElapsed); - /// Notify a world of the current camera - virtual void notifyCamera(Camera* cam); - - /** Function for writing to a stream. - */ - _OgrePagingExport friend std::ostream& operator <<( std::ostream& o, const PagedWorld& p ); - - - protected: - SectionMap mSections; - NameGenerator mSectionNameGenerator; - }; - - /** @} */ - /** @} */ + class PageManager; + + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Paging + * Some details on paging component + * @{ + */ + + + /** This class represents a collection of pages which make up a world. + @remarks + It's important to bear in mind that the PagedWorld only delineates the + world and knows how to find out about the contents of it. It does not, + by design, contain all elements of the world, in memory, at once. + */ + class _OgrePagingExport PagedWorld : public PageAlloc + { + protected: + String mName; + PageManager* mManager; + PageProvider* mPageProvider; + + public: + static const uint32 CHUNK_ID; + static const uint16 CHUNK_VERSION; + static const uint32 CHUNK_SECTIONDECLARATION_ID; + /** Constructor. + @param name The name of the world, which must be enough to identify the + place where data for it can be loaded from (doesn't have to be a filename + necessarily). + @param manager The PageManager that is in charge of providing this world with + services such as related object factories. + */ + PagedWorld(const String& name, PageManager* manager); + virtual ~PagedWorld(); + + const String& getName() const { return mName; } + /// Get the manager of this world + PageManager* getManager() const { return mManager; } + + /// Load world data from a file + void load(const String& filename); + /// Load world data from a stream + void load(const DataStreamPtr& stream); + /// Load world data from a serialiser (returns true if successful) + bool load(StreamSerialiser& stream); + /** Save world data to a file + @param filename The name of the file to create; this can either be an + absolute filename or + */ + void save(const String& filename); + /// Save world data to a stream + void save(const DataStreamPtr& stream); + /// Save world data to a serialiser + void save(StreamSerialiser& stream); + + /** Create a new section of the world based on a specialised type. + @remarks + World sections are areas of the world that use a particular + PageStrategy, with a certain set of parameters specific to that + strategy, and potentially some other rules. + So you would have more than one section in a world only + if you needed different simultaneous paging strategies, or you + wanted the same strategy but parameterised differently. + @param sceneMgr The SceneManager to use for this section. + @param typeName The type of section to use (must be registered + with PageManager), or blank to use the default type (simple grid) + @param sectionName An optional name to give the section (if none is + provided, one will be generated) + */ + PagedWorldSection* createSection(SceneManager* sceneMgr, + const String& typeName, + const String& sectionName = BLANKSTRING); + + + /** Create a new manually defined section of the world. + @remarks + World sections are areas of the world that use a particular + PageStrategy, with a certain set of parameters specific to that + strategy. So you would have more than one section in a world only + if you needed different simultaneous paging strategies, or you + wanted the same strategy but parameterised differently. + @param strategyName The name of the strategy to use (must be registered + with PageManager) + @param sceneMgr The SceneManager to use for this section + @param sectionName An optional name to give the section (if none is + provided, one will be generated) + */ + PagedWorldSection* createSection(const String& strategyName, SceneManager* sceneMgr, + const String& sectionName = BLANKSTRING); + + + /** Create a manually defined new section of the world. + @remarks + World sections are areas of the world that use a particular + PageStrategy, with a certain set of parameters specific to that + strategy. So you would have more than one section in a world only + if you needed different simultaneous paging strategies, or you + wanted the same strategy but parameterised differently. + @param strategy The strategy to use + @param sceneMgr The SceneManager to use for this section + @param sectionName An optional name to give the section (if none is + provided, one will be generated) + */ + PagedWorldSection* createSection(PageStrategy* strategy, SceneManager* sceneMgr, + const String& sectionName = BLANKSTRING); + /** Destroy a section of world. */ + void destroySection(const String& name); + /** Destroy a section of world. */ + void destroySection(PagedWorldSection* sec); + /** Destroy all world sections */ + void destroyAllSections(); + + /** Get the number of sections this world has. */ + size_t getSectionCount() const { return mSections.size(); } + + /** Retrieve a section of the world. */ + PagedWorldSection* getSection(const String& name); + + typedef map::type SectionMap; + /// Retrieve a const reference to all the sections in this world + const SectionMap& getSections() const { return mSections; } + + /** Set the PageProvider which can provide streams for Pages in this world. + @remarks + This is the top-level way that you can direct how Page data is loaded. + When data for a Page is requested for a PagedWorldSection, the following + sequence of classes will be checked to see if they have a provider willing + to supply the stream: PagedWorldSection, PagedWorld, PageManager. + If none of these do, then the default behaviour is to look for a file + called worldname_sectionname_pageID.page. + @note + The caller remains responsible for the destruction of the provider. + */ + void setPageProvider(PageProvider* provider) { mPageProvider = provider; } + + /** Get the PageProvider which can provide streams for Pages in this world. */ + PageProvider* getPageProvider() const { return mPageProvider; } + + /** Give a world the opportunity to prepare page content procedurally. + @remarks + You should not call this method directly. This call may well happen in + a separate thread so it should not access GPU resources, use _loadProceduralPage + for that + @return true if the page was populated, false otherwise + */ + virtual bool _prepareProceduralPage(Page* page, PagedWorldSection* section); + /** Give a world the opportunity to prepare page content procedurally. + @remarks + You should not call this method directly. This call will happen in + the main render thread so it can access GPU resources. Use _prepareProceduralPage + for background preparation. + @return true if the page was populated, false otherwise + */ + virtual bool _loadProceduralPage(Page* page, PagedWorldSection* section); + /** Give a world the opportunity to unload page content procedurally. + @remarks + You should not call this method directly. This call will happen in + the main render thread so it can access GPU resources. Use _unprepareProceduralPage + for background preparation. + @return true if the page was populated, false otherwise + */ + virtual bool _unloadProceduralPage(Page* page, PagedWorldSection* section); + /** Give a world the opportunity to unprepare page content procedurally. + @remarks + You should not call this method directly. This call may well happen in + a separate thread so it should not access GPU resources, use _unloadProceduralPage + for that + @return true if the page was unpopulated, false otherwise + */ + virtual bool _unprepareProceduralPage(Page* page, PagedWorldSection* section); + /** Get a serialiser set up to read Page data for the given PageID. + @param pageID The ID of the page being requested + @param section The parent section to which this page will belong + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + */ + StreamSerialiser* _readPageStream(PageID pageID, PagedWorldSection* section); + + /** Get a serialiser set up to read Page data for the given PageID. + @param pageID The ID of the page being requested + @param section The parent section to which this page will belong + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + */ + StreamSerialiser* _writePageStream(PageID pageID, PagedWorldSection* section); + + /// Called when the frame starts + virtual void frameStart(Real timeSinceLastFrame); + /// Called when the frame ends + virtual void frameEnd(Real timeElapsed); + /// Notify a world of the current camera + virtual void notifyCamera(Camera* cam); + + /** Function for writing to a stream. + */ + _OgrePagingExport friend std::ostream& operator <<( std::ostream& o, const PagedWorld& p ); + + + protected: + SectionMap mSections; + NameGenerator mSectionNameGenerator; + }; + + /** @} */ + /** @} */ } diff --git a/Components/Paging/include/OgrePagedWorldSection.h b/Components/Paging/include/OgrePagedWorldSection.h index 9de5b027d97..6eb74f34eed 100644 --- a/Components/Paging/include/OgrePagedWorldSection.h +++ b/Components/Paging/include/OgrePagedWorldSection.h @@ -34,283 +34,283 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Paging - * Some details on paging component - * @{ - */ - - /** Represents a section of the PagedWorld which uses a given PageStrategy, and - which is made up of a generally localised set of Page instances. - @remarks - The reason for PagedWorldSection is that you may wish to cater for multiple - sections of your world which use a different approach to paging (ie a - different PageStrategy), or which are significantly far apart or separate - that the parameters you want to pass to the PageStrategy are different. - @par - PagedWorldSection instances are fully contained within the PagedWorld and - their definitions are loaded in their entirety when the PagedWorld is - loaded. However, no Page instances are initially loaded - those are the - responsibility of the PageStrategy. - @par - PagedWorldSection can be subclassed and derived types provided by a - PagedWorldSectionFactory. These subclasses might come preconfigured - with a strategy for example, or with additional metadata used only for - that particular type of section. - @par - A PagedWorldSection targets a specific SceneManager. When you create one - in code via PagedWorld::createSection, you pass that SceneManager in manually. - When loading from a saved world file however, the SceneManager type and - instance name are saved and that SceneManager is looked up on loading, or - created if it didn't exist. - */ - class _OgrePagingExport PagedWorldSection : public PageAlloc - { - public: - typedef map::type PageMap; - protected: - String mName; - AxisAlignedBox mAABB; - PagedWorld* mParent; - PageStrategy* mStrategy; - PageStrategyData* mStrategyData; - PageMap mPages; - PageProvider* mPageProvider; - SceneManager* mSceneMgr; - - /// Load data specific to a subtype of this class (if any) - virtual void loadSubtypeData(StreamSerialiser& ser) {} - virtual void saveSubtypeData(StreamSerialiser& ser) {} - - - public: - static const uint32 CHUNK_ID; - static const uint16 CHUNK_VERSION; - - /** Construct a new instance, specifying the parent and scene manager. */ - PagedWorldSection(const String& name, PagedWorld* parent, SceneManager* sm); - virtual ~PagedWorldSection(); - - PageManager* getManager() const; - - /// Get the name of this section - virtual const String& getName() const { return mName; } - /// Get the page strategy which this section is using - virtual PageStrategy* getStrategy() const { return mStrategy; } - /** Change the page strategy. - @remarks - Doing this will invalidate any pages attached to this world section, and - require the PageStrategyData to be repopulated. - */ - virtual void setStrategy(PageStrategy* strat); - /** Change the page strategy. - @remarks - Doing this will invalidate any pages attached to this world section, and - require the PageStrategyData to be repopulated. - */ - virtual void setStrategy(const String& stratName); - - /** Change the SceneManager. - @remarks - Doing this will invalidate any pages attached to this world section, and - require the pages to be reloaded. - */ - virtual void setSceneManager(SceneManager* sm); - - /** Change the SceneManager. - @remarks - Doing this will invalidate any pages attached to this world section, and - require the pages to be reloaded. - @param smName The instance name of the SceneManager - */ - virtual void setSceneManager(const String& smName); - /// Get the current SceneManager - virtual SceneManager* getSceneManager() const { return mSceneMgr; } - - /// Get the parent world - virtual PagedWorld* getWorld() const { return mParent; } - /// Get the data required by the PageStrategy which is specific to this world section - virtual PageStrategyData* getStrategyData() const { return mStrategyData; } - /// Set the bounds of this section - virtual void setBoundingBox(const AxisAlignedBox& box); - /// Get the bounds of this section - virtual const AxisAlignedBox& getBoundingBox() const; - - - /// Load this section from a stream (returns true if successful) - virtual bool load(StreamSerialiser& stream); - /// Save this section to a stream - virtual void save(StreamSerialiser& stream); - - - /// Called when the frame starts - virtual void frameStart(Real timeSinceLastFrame); - /// Called when the frame ends - virtual void frameEnd(Real timeElapsed); - /// Notify a section of the current camera - virtual void notifyCamera(Camera* cam); - - /** Load or create a page against this section covering the given world - space position. - @remarks - This method is designed mainly for editors - it will try to load - an existing page if there is one, otherwise it will create a new one - synchronously. - */ - virtual Page* loadOrCreatePage(const Vector3& worldPos); - - /** Get the page ID for a given world position. */ - virtual PageID getPageID(const Vector3& worldPos); - - - /** Ask for a page to be loaded with the given (section-relative) PageID - @remarks - You would not normally call this manually, the PageStrategy is in - charge of it usually. - If this page is already loaded, this request will not load it again. - If the page needs loading, then it may be an asynchronous process depending - on whether threading is enabled. - @param pageID The page ID to load - @param forceSynchronous If true, the page will always be loaded synchronously - */ - virtual void loadPage(PageID pageID, bool forceSynchronous = false); - - /** Ask for a page to be unloaded with the given (section-relative) PageID - @remarks - You would not normally call this manually, the PageStrategy is in - charge of it usually. - @param pageID The page ID to unload - @param forceSynchronous If true, the page will always be unloaded synchronously - */ - virtual void unloadPage(PageID pageID, bool forceSynchronous = false); - /** Ask for a page to be unloaded with the given (section-relative) PageID - @remarks - You would not normally call this manually, the PageStrategy is in - charge of it usually. - @param p The Page to unload - @param forceSynchronous If true, the page will always be unloaded synchronously - */ - virtual void unloadPage(Page* p, bool forceSynchronous = false); - /** Give a section the opportunity to prepare page content procedurally. - @remarks - You should not call this method directly. This call may well happen in - a separate thread so it should not access GPU resources, use _loadProceduralPage - for that - @return true if the page was populated, false otherwise - */ - virtual bool _prepareProceduralPage(Page* page); - /** Give a section the opportunity to prepare page content procedurally. - @remarks - You should not call this method directly. This call will happen in - the main render thread so it can access GPU resources. Use _prepareProceduralPage - for background preparation. - @return true if the page was populated, false otherwise - */ - virtual bool _loadProceduralPage(Page* page); - /** Give a section the opportunity to unload page content procedurally. - @remarks - You should not call this method directly. This call will happen in - the main render thread so it can access GPU resources. Use _unprepareProceduralPage - for background preparation. - @return true if the page was populated, false otherwise - */ - virtual bool _unloadProceduralPage(Page* page); - /** Give a section the opportunity to unprepare page content procedurally. - @remarks - You should not call this method directly. This call may well happen in - a separate thread so it should not access GPU resources, use _unloadProceduralPage - for that - @return true if the page was unpopulated, false otherwise - */ - virtual bool _unprepareProceduralPage(Page* page); - - /** Ask for a page to be kept in memory if it's loaded. - @remarks - This method indicates that a page should be retained if it's already - in memory, but if it's not then it won't trigger a load. This is useful - for retaining pages that have just gone out of range, but which you - don't want to unload just yet because it's quite possible they may come - back into the active set again very quickly / easily. But at the same - time, if they've already been purged you don't want to force them to load. - This is the 'maybe' region of pages. - @par - Any Page that is neither requested nor held in a frame will be - deemed a candidate for unloading. - */ - virtual void holdPage(PageID pageID); - - /** Retrieves a Page. - @remarks - This method will only return Page instances that are already loaded. It - will return null if a page is not loaded. - */ - virtual Page* getPage(PageID pageID); - - /** Remove all pages immediately. - @remarks - Effectively 'resets' this section by deleting all pages. - */ - virtual void removeAllPages(); - - /** Set the PageProvider which can provide streams Pages in this section. - @remarks - This is the top-level way that you can direct how Page data is loaded. - When data for a Page is requested for a PagedWorldSection, the following - sequence of classes will be checked to see if they have a provider willing - to supply the stream: PagedWorldSection, PagedWorld, PageManager. - If none of these do, then the default behaviour is to look for a file - called worldname_sectionname_pageID.page. - @note - The caller remains responsible for the destruction of the provider. - */ - virtual void setPageProvider(PageProvider* provider) { mPageProvider = provider; } - - /** Get the PageProvider which can provide streams for Pages in this section. */ - virtual PageProvider* getPageProvider() const { return mPageProvider; } - - /** Get a serialiser set up to read Page data for the given PageID. - @param pageID The ID of the page being requested - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - */ - virtual StreamSerialiser* _readPageStream(PageID pageID); - - /** Get a serialiser set up to write Page data for the given PageID. - @param pageID The ID of the page being requested - @remarks - The StreamSerialiser returned is the responsibility of the caller to - delete. - */ - virtual StreamSerialiser* _writePageStream(PageID pageID); - - /** Function for writing to a stream. - */ - _OgrePagingExport friend std::ostream& operator <<( std::ostream& o, const PagedWorldSection& p ); - - /** Get the type name of this section. */ - virtual const String& getType(); - - }; - - - /** A factory class for creating types of world section. - */ - class _OgrePagingExport PagedWorldSectionFactory : public PageAlloc - { - public: - virtual ~PagedWorldSectionFactory() {} - virtual const String& getName() const = 0; - virtual PagedWorldSection* createInstance(const String& name, PagedWorld* parent, SceneManager* sm) = 0; - virtual void destroyInstance(PagedWorldSection*) = 0; - - - }; - - /** @} */ - /** @} */ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Paging + * Some details on paging component + * @{ + */ + + /** Represents a section of the PagedWorld which uses a given PageStrategy, and + which is made up of a generally localised set of Page instances. + @remarks + The reason for PagedWorldSection is that you may wish to cater for multiple + sections of your world which use a different approach to paging (ie a + different PageStrategy), or which are significantly far apart or separate + that the parameters you want to pass to the PageStrategy are different. + @par + PagedWorldSection instances are fully contained within the PagedWorld and + their definitions are loaded in their entirety when the PagedWorld is + loaded. However, no Page instances are initially loaded - those are the + responsibility of the PageStrategy. + @par + PagedWorldSection can be subclassed and derived types provided by a + PagedWorldSectionFactory. These subclasses might come preconfigured + with a strategy for example, or with additional metadata used only for + that particular type of section. + @par + A PagedWorldSection targets a specific SceneManager. When you create one + in code via PagedWorld::createSection, you pass that SceneManager in manually. + When loading from a saved world file however, the SceneManager type and + instance name are saved and that SceneManager is looked up on loading, or + created if it didn't exist. + */ + class _OgrePagingExport PagedWorldSection : public PageAlloc + { + public: + typedef map::type PageMap; + protected: + String mName; + AxisAlignedBox mAABB; + PagedWorld* mParent; + PageStrategy* mStrategy; + PageStrategyData* mStrategyData; + PageMap mPages; + PageProvider* mPageProvider; + SceneManager* mSceneMgr; + + /// Load data specific to a subtype of this class (if any) + virtual void loadSubtypeData(StreamSerialiser& ser) {} + virtual void saveSubtypeData(StreamSerialiser& ser) {} + + + public: + static const uint32 CHUNK_ID; + static const uint16 CHUNK_VERSION; + + /** Construct a new instance, specifying the parent and scene manager. */ + PagedWorldSection(const String& name, PagedWorld* parent, SceneManager* sm); + virtual ~PagedWorldSection(); + + PageManager* getManager() const; + + /// Get the name of this section + virtual const String& getName() const { return mName; } + /// Get the page strategy which this section is using + virtual PageStrategy* getStrategy() const { return mStrategy; } + /** Change the page strategy. + @remarks + Doing this will invalidate any pages attached to this world section, and + require the PageStrategyData to be repopulated. + */ + virtual void setStrategy(PageStrategy* strat); + /** Change the page strategy. + @remarks + Doing this will invalidate any pages attached to this world section, and + require the PageStrategyData to be repopulated. + */ + virtual void setStrategy(const String& stratName); + + /** Change the SceneManager. + @remarks + Doing this will invalidate any pages attached to this world section, and + require the pages to be reloaded. + */ + virtual void setSceneManager(SceneManager* sm); + + /** Change the SceneManager. + @remarks + Doing this will invalidate any pages attached to this world section, and + require the pages to be reloaded. + @param smName The instance name of the SceneManager + */ + virtual void setSceneManager(const String& smName); + /// Get the current SceneManager + virtual SceneManager* getSceneManager() const { return mSceneMgr; } + + /// Get the parent world + virtual PagedWorld* getWorld() const { return mParent; } + /// Get the data required by the PageStrategy which is specific to this world section + virtual PageStrategyData* getStrategyData() const { return mStrategyData; } + /// Set the bounds of this section + virtual void setBoundingBox(const AxisAlignedBox& box); + /// Get the bounds of this section + virtual const AxisAlignedBox& getBoundingBox() const; + + + /// Load this section from a stream (returns true if successful) + virtual bool load(StreamSerialiser& stream); + /// Save this section to a stream + virtual void save(StreamSerialiser& stream); + + + /// Called when the frame starts + virtual void frameStart(Real timeSinceLastFrame); + /// Called when the frame ends + virtual void frameEnd(Real timeElapsed); + /// Notify a section of the current camera + virtual void notifyCamera(Camera* cam); + + /** Load or create a page against this section covering the given world + space position. + @remarks + This method is designed mainly for editors - it will try to load + an existing page if there is one, otherwise it will create a new one + synchronously. + */ + virtual Page* loadOrCreatePage(const Vector3& worldPos); + + /** Get the page ID for a given world position. */ + virtual PageID getPageID(const Vector3& worldPos); + + + /** Ask for a page to be loaded with the given (section-relative) PageID + @remarks + You would not normally call this manually, the PageStrategy is in + charge of it usually. + If this page is already loaded, this request will not load it again. + If the page needs loading, then it may be an asynchronous process depending + on whether threading is enabled. + @param pageID The page ID to load + @param forceSynchronous If true, the page will always be loaded synchronously + */ + virtual void loadPage(PageID pageID, bool forceSynchronous = false); + + /** Ask for a page to be unloaded with the given (section-relative) PageID + @remarks + You would not normally call this manually, the PageStrategy is in + charge of it usually. + @param pageID The page ID to unload + @param forceSynchronous If true, the page will always be unloaded synchronously + */ + virtual void unloadPage(PageID pageID, bool forceSynchronous = false); + /** Ask for a page to be unloaded with the given (section-relative) PageID + @remarks + You would not normally call this manually, the PageStrategy is in + charge of it usually. + @param p The Page to unload + @param forceSynchronous If true, the page will always be unloaded synchronously + */ + virtual void unloadPage(Page* p, bool forceSynchronous = false); + /** Give a section the opportunity to prepare page content procedurally. + @remarks + You should not call this method directly. This call may well happen in + a separate thread so it should not access GPU resources, use _loadProceduralPage + for that + @return true if the page was populated, false otherwise + */ + virtual bool _prepareProceduralPage(Page* page); + /** Give a section the opportunity to prepare page content procedurally. + @remarks + You should not call this method directly. This call will happen in + the main render thread so it can access GPU resources. Use _prepareProceduralPage + for background preparation. + @return true if the page was populated, false otherwise + */ + virtual bool _loadProceduralPage(Page* page); + /** Give a section the opportunity to unload page content procedurally. + @remarks + You should not call this method directly. This call will happen in + the main render thread so it can access GPU resources. Use _unprepareProceduralPage + for background preparation. + @return true if the page was populated, false otherwise + */ + virtual bool _unloadProceduralPage(Page* page); + /** Give a section the opportunity to unprepare page content procedurally. + @remarks + You should not call this method directly. This call may well happen in + a separate thread so it should not access GPU resources, use _unloadProceduralPage + for that + @return true if the page was unpopulated, false otherwise + */ + virtual bool _unprepareProceduralPage(Page* page); + + /** Ask for a page to be kept in memory if it's loaded. + @remarks + This method indicates that a page should be retained if it's already + in memory, but if it's not then it won't trigger a load. This is useful + for retaining pages that have just gone out of range, but which you + don't want to unload just yet because it's quite possible they may come + back into the active set again very quickly / easily. But at the same + time, if they've already been purged you don't want to force them to load. + This is the 'maybe' region of pages. + @par + Any Page that is neither requested nor held in a frame will be + deemed a candidate for unloading. + */ + virtual void holdPage(PageID pageID); + + /** Retrieves a Page. + @remarks + This method will only return Page instances that are already loaded. It + will return null if a page is not loaded. + */ + virtual Page* getPage(PageID pageID); + + /** Remove all pages immediately. + @remarks + Effectively 'resets' this section by deleting all pages. + */ + virtual void removeAllPages(); + + /** Set the PageProvider which can provide streams Pages in this section. + @remarks + This is the top-level way that you can direct how Page data is loaded. + When data for a Page is requested for a PagedWorldSection, the following + sequence of classes will be checked to see if they have a provider willing + to supply the stream: PagedWorldSection, PagedWorld, PageManager. + If none of these do, then the default behaviour is to look for a file + called worldname_sectionname_pageID.page. + @note + The caller remains responsible for the destruction of the provider. + */ + virtual void setPageProvider(PageProvider* provider) { mPageProvider = provider; } + + /** Get the PageProvider which can provide streams for Pages in this section. */ + virtual PageProvider* getPageProvider() const { return mPageProvider; } + + /** Get a serialiser set up to read Page data for the given PageID. + @param pageID The ID of the page being requested + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + */ + virtual StreamSerialiser* _readPageStream(PageID pageID); + + /** Get a serialiser set up to write Page data for the given PageID. + @param pageID The ID of the page being requested + @remarks + The StreamSerialiser returned is the responsibility of the caller to + delete. + */ + virtual StreamSerialiser* _writePageStream(PageID pageID); + + /** Function for writing to a stream. + */ + _OgrePagingExport friend std::ostream& operator <<( std::ostream& o, const PagedWorldSection& p ); + + /** Get the type name of this section. */ + virtual const String& getType(); + + }; + + + /** A factory class for creating types of world section. + */ + class _OgrePagingExport PagedWorldSectionFactory : public PageAlloc + { + public: + virtual ~PagedWorldSectionFactory() {} + virtual const String& getName() const = 0; + virtual PagedWorldSection* createInstance(const String& name, PagedWorld* parent, SceneManager* sm) = 0; + virtual void destroyInstance(PagedWorldSection*) = 0; + + + }; + + /** @} */ + /** @} */ } #endif diff --git a/Components/Paging/include/OgrePagingPrerequisites.h b/Components/Paging/include/OgrePagingPrerequisites.h index 708f9f07148..3d61716c0b1 100644 --- a/Components/Paging/include/OgrePagingPrerequisites.h +++ b/Components/Paging/include/OgrePagingPrerequisites.h @@ -33,50 +33,50 @@ THE SOFTWARE. namespace Ogre { - // forward decls - class Grid2DPageStrategy; - class Grid3DPageStrategy; - class Page; - class PageConnection; - class PageContent; - class PageContentFactory; - class PageContentCollection; - class PageContentCollectionFactory; - class PagedWorld; - class PagedWorldSection; - class PageManager; - class PageStrategy; - class PageStrategyData; - class PageProvider; - class SimplePageContentCollection; - class SimplePageContentCollectionFactory; + // forward decls + class Grid2DPageStrategy; + class Grid3DPageStrategy; + class Page; + class PageConnection; + class PageContent; + class PageContentFactory; + class PageContentCollection; + class PageContentCollectionFactory; + class PagedWorld; + class PagedWorldSection; + class PageManager; + class PageStrategy; + class PageStrategyData; + class PageProvider; + class SimplePageContentCollection; + class SimplePageContentCollectionFactory; - typedef GeneralAllocatedObject PageAlloc; + typedef GeneralAllocatedObject PageAlloc; - /// Identifier for a page - typedef uint32 PageID; + /// Identifier for a page + typedef uint32 PageID; } #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT -# if defined( OGRE_STATIC_LIB ) -# define _OgrePagingExport +# if defined( OGRE_STATIC_LIB ) +# define _OgrePagingExport # else -# if defined( OGRE_PAGING_EXPORTS ) -# define _OgrePagingExport __declspec( dllexport ) -# else +# if defined( OGRE_PAGING_EXPORTS ) +# define _OgrePagingExport __declspec( dllexport ) +# else # if defined( __MINGW32__ ) # define _OgrePagingExport # else -# define _OgrePagingExport __declspec( dllimport ) +# define _OgrePagingExport __declspec( dllimport ) # endif -# endif -# endif +# endif +# endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgrePagingExport __attribute__ ((visibility("default"))) #else -# define _OgrePagingExport +# define _OgrePagingExport #endif diff --git a/Components/Paging/include/OgreSimplePageContentCollection.h b/Components/Paging/include/OgreSimplePageContentCollection.h index e4a3fc254d0..5aec71949f8 100644 --- a/Components/Paging/include/OgreSimplePageContentCollection.h +++ b/Components/Paging/include/OgreSimplePageContentCollection.h @@ -35,103 +35,103 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Paging - * Some details on paging component - */ - /*@{*/ - - - /** Specialisation of PageContentCollection which just provides a simple list - of PageContent instances. - @par - The data format for this in a file is:
      - SimplePageContentCollectionData (Identifier 'SPCD')\n - [Version 1] - - - - - - - - - - - -
      NameTypeDescription
      Nested contentsNested chunk listA sequence of nested PageContent chunks
      - */ - class _OgrePagingExport SimplePageContentCollection : public PageContentCollection - { - public: - typedef vector::type ContentList; - static const uint32 SUBCLASS_CHUNK_ID; - static const uint16 SUBCLASS_CHUNK_VERSION; - protected: - ContentList mContentList; - public: - SimplePageContentCollection(PageContentCollectionFactory* creator); - ~SimplePageContentCollection(); - - /** Create a new PageContent within this collection. - @param typeName The name of the type of content (see PageManager::getContentFactories) - */ - virtual PageContent* createContent(const String& typeName); - - /** Destroy a PageContent within this page. - This is equivalent to calling detachContent and - PageManager::destroyContent. - */ - virtual void destroyContent(PageContent* coll); - - /// Get const access to the list of content - virtual const ContentList& getContentList() const { return mContentList; } - - // Overridden from PageContentCollection - virtual void save(StreamSerialiser& stream); - virtual void frameStart(Real timeSinceLastFrame); - virtual void frameEnd(Real timeElapsed); - virtual void notifyCamera(Camera* cam); - bool prepare(StreamSerialiser& stream); - void load(); - void unload(); - void unprepare(); - - protected: - - - - - }; - - - /// Factory class for SimplePageContentCollection - class _OgrePagingExport SimplePageContentCollectionFactory : public PageContentCollectionFactory - { - public: - static String FACTORY_NAME; - - SimplePageContentCollectionFactory() {} - ~SimplePageContentCollectionFactory() {} - - const String& getName() const { return FACTORY_NAME; } - - PageContentCollection* createInstance() - { - return OGRE_NEW SimplePageContentCollection(this); - } - void destroyInstance(PageContentCollection* c) - { - OGRE_DELETE c; - } - - - }; - - /*@}*/ - /*@}*/ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Paging + * Some details on paging component + */ + /*@{*/ + + + /** Specialisation of PageContentCollection which just provides a simple list + of PageContent instances. + @par + The data format for this in a file is:
      + SimplePageContentCollectionData (Identifier 'SPCD')\n + [Version 1] + + + + + + + + + + + +
      NameTypeDescription
      Nested contentsNested chunk listA sequence of nested PageContent chunks
      + */ + class _OgrePagingExport SimplePageContentCollection : public PageContentCollection + { + public: + typedef vector::type ContentList; + static const uint32 SUBCLASS_CHUNK_ID; + static const uint16 SUBCLASS_CHUNK_VERSION; + protected: + ContentList mContentList; + public: + SimplePageContentCollection(PageContentCollectionFactory* creator); + ~SimplePageContentCollection(); + + /** Create a new PageContent within this collection. + @param typeName The name of the type of content (see PageManager::getContentFactories) + */ + virtual PageContent* createContent(const String& typeName); + + /** Destroy a PageContent within this page. + This is equivalent to calling detachContent and + PageManager::destroyContent. + */ + virtual void destroyContent(PageContent* coll); + + /// Get const access to the list of content + virtual const ContentList& getContentList() const { return mContentList; } + + // Overridden from PageContentCollection + virtual void save(StreamSerialiser& stream); + virtual void frameStart(Real timeSinceLastFrame); + virtual void frameEnd(Real timeElapsed); + virtual void notifyCamera(Camera* cam); + bool prepare(StreamSerialiser& stream); + void load(); + void unload(); + void unprepare(); + + protected: + + + + + }; + + + /// Factory class for SimplePageContentCollection + class _OgrePagingExport SimplePageContentCollectionFactory : public PageContentCollectionFactory + { + public: + static String FACTORY_NAME; + + SimplePageContentCollectionFactory() {} + ~SimplePageContentCollectionFactory() {} + + const String& getName() const { return FACTORY_NAME; } + + PageContentCollection* createInstance() + { + return OGRE_NEW SimplePageContentCollection(this); + } + void destroyInstance(PageContentCollection* c) + { + OGRE_DELETE c; + } + + + }; + + /*@}*/ + /*@}*/ } #endif diff --git a/Components/Paging/src/OgreGrid2DPageStrategy.cpp b/Components/Paging/src/OgreGrid2DPageStrategy.cpp index 5726aa2283b..3c4992b3c8f 100644 --- a/Components/Paging/src/OgreGrid2DPageStrategy.cpp +++ b/Components/Paging/src/OgreGrid2DPageStrategy.cpp @@ -39,418 +39,418 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - const uint32 Grid2DPageStrategyData::CHUNK_ID = StreamSerialiser::makeIdentifier("G2DD"); - const uint16 Grid2DPageStrategyData::CHUNK_VERSION = 1; - //--------------------------------------------------------------------- - Grid2DPageStrategyData::Grid2DPageStrategyData() - : PageStrategyData() - , mMode(G2D_X_Z) - , mWorldOrigin(Vector3::ZERO) - , mOrigin(Vector2::ZERO) - , mCellSize(1000) - , mLoadRadius(2000) - , mHoldRadius(3000) - , mMinCellX(-32768) - , mMinCellY(-32768) - , mMaxCellX(32767) - , mMaxCellY(32767) - { - updateDerivedMetrics(); - - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::setCellRange(int32 minX, int32 minY, int32 maxX, int32 maxY) - { - mMinCellX = minX; - mMinCellY = minY; - mMaxCellX = maxX; - mMaxCellY = maxY; - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::setCellRangeMinX(int32 minX) - { - mMinCellX = minX; - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::setCellRangeMinY(int32 minY) - { - mMinCellY = minY; - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::setCellRangeMaxX(int32 maxX) - { - mMaxCellX = maxX; - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::setCellRangeMaxY(int32 maxY) - { - mMaxCellY = maxY; - } - //--------------------------------------------------------------------- - Grid2DPageStrategyData::~Grid2DPageStrategyData() - { - - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::setMode(Grid2DMode mode) - { - mMode = mode; - // reset origin - setOrigin(mWorldOrigin); - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::setOrigin(const Vector3& worldOrigin) - { - mWorldOrigin = worldOrigin; - convertWorldToGridSpace(mWorldOrigin, mOrigin); - updateDerivedMetrics(); - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::convertWorldToGridSpace(const Vector3& world, Vector2& grid) - { - switch(mMode) - { - case G2D_X_Z: - grid.x = world.x; - grid.y = -world.z; - break; - case G2D_X_Y: - grid.x = world.x; - grid.y = world.y; - break; - case G2D_Y_Z: - grid.x = -world.z; - grid.y = world.y; - break; - } - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::convertGridToWorldSpace(const Vector2& grid, Vector3& world) - { - // Note that we don't set the 3rd coordinate, let the caller determine that - switch(mMode) - { - case G2D_X_Z: - world.x = grid.x; - world.z = -grid.y; - break; - case G2D_X_Y: - world.x = grid.x; - world.y = grid.y; - break; - case G2D_Y_Z: - world.z = -grid.x; - world.y = grid.y; - break; - } - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::updateDerivedMetrics() - { - mLoadRadiusInCells = mLoadRadius / mCellSize; - mHoldRadiusInCells = mHoldRadius / mCellSize; - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::determineGridLocation(const Vector2& gridpos, int32 *x, int32 *y) - { - Vector2 relPos = gridpos - mOrigin; - Real offset = mCellSize * 0.5f; - relPos.x += offset; - relPos.y += offset; - - *x = static_cast(floor(relPos.x / mCellSize)); - *y = static_cast(floor(relPos.y / mCellSize)); - - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::getBottomLeftGridSpace(int32 x, int32 y, Vector2& bl) - { - Real offset = mCellSize * 0.5f; - bl.x = mOrigin.x - offset + x * mCellSize; - bl.y = mOrigin.y - offset + y * mCellSize; - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::getMidPointGridSpace(int32 x, int32 y, Vector2& mid) - { - mid.x = mOrigin.x + x * mCellSize; - mid.y = mOrigin.y + y * mCellSize; - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::getCornersGridSpace(int32 x, int32 y, Vector2* pFourPoints) - { - getBottomLeftGridSpace(x, y, pFourPoints[0]); - pFourPoints[1] = pFourPoints[0] + Vector2(mCellSize, 0); - pFourPoints[2] = pFourPoints[0] + Vector2(mCellSize, mCellSize); - pFourPoints[3] = pFourPoints[0] + Vector2(0, mCellSize); - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::setCellSize(Real sz) - { - mCellSize = sz; - updateDerivedMetrics(); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::setLoadRadius(Real sz) - { - mLoadRadius = sz; - updateDerivedMetrics(); - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::setHoldRadius(Real sz) - { - mHoldRadius = sz; - updateDerivedMetrics(); - } - //--------------------------------------------------------------------- - PageID Grid2DPageStrategyData::calculatePageID(int32 x, int32 y) - { - // Convert to signed 16-bit so sign bit is in bit 15 - int16 xs16 = static_cast(x); - int16 ys16 = static_cast(y); - - // convert to unsigned because we do not want to propagate sign bit to 32-bits - uint16 x16 = static_cast(xs16); - uint16 y16 = static_cast(ys16); - - uint32 key = 0; - key = (x16 << 16) | y16; - - return (PageID)key; - - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::calculateCell(PageID inPageID, int32 *x, int32 *y) - { - // inverse of calculatePageID - // unsigned versions - uint16 y16 = static_cast(inPageID & 0xFFFF); - uint16 x16 = static_cast((inPageID >> 16) & 0xFFFF); - - *x = static_cast(x16); - *y = static_cast(y16); - - } - //--------------------------------------------------------------------- - bool Grid2DPageStrategyData::load(StreamSerialiser& ser) - { - if (!ser.readChunkBegin(CHUNK_ID, CHUNK_VERSION, "Grid2DPageStrategyData")) - return false; - - uint8 readMode; - ser.read(&readMode); - mMode = (Grid2DMode)readMode; - - Vector3 origin; - ser.read(&origin); - setOrigin(origin); - - ser.read(&mCellSize); - ser.read(&mLoadRadius); - ser.read(&mHoldRadius); - ser.read(&mMinCellX); - ser.read(&mMaxCellX); - ser.read(&mMinCellY); - ser.read(&mMaxCellY); - - ser.readChunkEnd(CHUNK_ID); - - return true; - } - //--------------------------------------------------------------------- - void Grid2DPageStrategyData::save(StreamSerialiser& ser) - { - ser.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); - - uint8 readMode = (uint8)mMode; - ser.write(&readMode); - - ser.write(&mWorldOrigin); - ser.write(&mCellSize); - ser.write(&mLoadRadius); - ser.write(&mHoldRadius); - ser.write(&mMinCellX); - ser.write(&mMaxCellX); - ser.write(&mMinCellY); - ser.write(&mMaxCellY); - - ser.writeChunkEnd(CHUNK_ID); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - Grid2DPageStrategy::Grid2DPageStrategy(PageManager* manager) - : PageStrategy("Grid2D", manager) - { - - } - //--------------------------------------------------------------------- - Grid2DPageStrategy::~Grid2DPageStrategy() - { - - } - //--------------------------------------------------------------------- - void Grid2DPageStrategy::notifyCamera(Camera* cam, PagedWorldSection* section) - { - Grid2DPageStrategyData* stratData = static_cast(section->getStrategyData()); - - const Vector3& pos = cam->getDerivedPosition(); - Vector2 gridpos; - stratData->convertWorldToGridSpace(pos, gridpos); - int32 x, y; - stratData->determineGridLocation(gridpos, &x, &y); - - Real loadRadius = stratData->getLoadRadiusInCells(); - Real holdRadius = stratData->getHoldRadiusInCells(); - // scan the whole Hold range - Real fxmin = (Real)x - holdRadius; - Real fxmax = (Real)x + holdRadius; - Real fymin = (Real)y - holdRadius; - Real fymax = (Real)y + holdRadius; - - int32 xmin = stratData->getCellRangeMinX(); - int32 xmax = stratData->getCellRangeMaxX(); - int32 ymin = stratData->getCellRangeMinY(); - int32 ymax = stratData->getCellRangeMaxY(); - - // Round UP max, round DOWN min - xmin = fxmin < xmin ? xmin : (int32)floor(fxmin); - xmax = fxmax > xmax ? xmax : (int32)ceil(fxmax); - ymin = fymin < ymin ? ymin : (int32)floor(fymin); - ymax = fymax > ymax ? ymax : (int32)ceil(fymax); - // the inner, active load range - fxmin = (Real)x - loadRadius; - fxmax = (Real)x + loadRadius; - fymin = (Real)y - loadRadius; - fymax = (Real)y + loadRadius; - // Round UP max, round DOWN min - int32 loadxmin = fxmin < xmin ? xmin : (int32)floor(fxmin); - int32 loadxmax = fxmax > xmax ? xmax : (int32)ceil(fxmax); - int32 loadymin = fymin < ymin ? ymin : (int32)floor(fymin); - int32 loadymax = fymax > ymax ? ymax : (int32)ceil(fymax); - - for (int32 cy = ymin; cy <= ymax; ++cy) - { - for (int32 cx = xmin; cx <= xmax; ++cx) - { - PageID pageID = stratData->calculatePageID(cx, cy); - if (cx >= loadxmin && cx <= loadxmax && cy >= loadymin && cy <= loadymax) - { - // in the 'load' range, request it - section->loadPage(pageID); - } - else - { - // in the outer 'hold' range, keep it but don't actively load - section->holdPage(pageID); - } - // other pages will by inference be marked for unloading - } - } - - - - } - //--------------------------------------------------------------------- - PageStrategyData* Grid2DPageStrategy::createData() - { - return OGRE_NEW Grid2DPageStrategyData(); - } - //--------------------------------------------------------------------- - void Grid2DPageStrategy::destroyData(PageStrategyData* d) - { - OGRE_DELETE d; - } - //--------------------------------------------------------------------- - void Grid2DPageStrategy::updateDebugDisplay(Page* p, SceneNode* sn) - { - uint8 dbglvl = mManager->getDebugDisplayLevel(); - if (dbglvl) - { - // we could try to avoid updating the geometry every time here, but this - // wouldn't easily deal with paging parameter changes. There shouldn't - // be that many pages anyway, and this is debug after all, so update every time - int32 x, y; - Grid2DPageStrategyData* stratData = static_cast( - p->getParentSection()->getStrategyData()); - stratData->calculateCell(p->getID(), &x, &y); - - Grid2DPageStrategyData* data = static_cast(p->getParentSection()->getStrategyData()); - - // Determine our centre point, we'll anchor here - // Note that world points are initialised to ZERO since only 2 dimensions - // are updated by the grid data (we could display this grid anywhere) - Vector2 gridMidPoint; - Vector3 worldMidPoint = Vector3::ZERO; - data->getMidPointGridSpace(x, y, gridMidPoint); - data->convertGridToWorldSpace(gridMidPoint, worldMidPoint); - - sn->setPosition(worldMidPoint); - - Vector2 gridCorners[4]; - Vector3 worldCorners[4]; - - data->getCornersGridSpace(x, y, gridCorners); - for (int i = 0; i < 4; ++i) - { - worldCorners[i] = Vector3::ZERO; - data->convertGridToWorldSpace(gridCorners[i], worldCorners[i]); - // make relative to mid point - worldCorners[i] -= worldMidPoint; - } - - String matName = "Ogre/G2D/Debug"; - MaterialPtr mat = MaterialManager::getSingleton().getByName(matName); - if (mat.isNull()) - { - mat = MaterialManager::getSingleton().create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - Pass* pass = mat->getTechnique(0)->getPass(0); - pass->setLightingEnabled(false); - pass->setVertexColourTracking(TVC_AMBIENT); - pass->setDepthWriteEnabled(false); - mat->load(); - } - - - ManualObject* mo = 0; - if (sn->numAttachedObjects() == 0) - { - mo = p->getParentSection()->getSceneManager()->createManualObject(); - mo->begin(matName, RenderOperation::OT_LINE_STRIP); - } - else - { - mo = static_cast(sn->getAttachedObject(0)); - mo->beginUpdate(0); - } - - ColourValue vcol = ColourValue::Green; - for(int i = 0; i < 5; ++i) - { - mo->position(worldCorners[i%4]); - mo->colour(vcol); - } - - mo->end(); - - if (sn->numAttachedObjects() == 0) - sn->attachObject(mo); - - } - - } - //--------------------------------------------------------------------- - PageID Grid2DPageStrategy::getPageID(const Vector3& worldPos, PagedWorldSection* section) - { - Grid2DPageStrategyData* stratData = static_cast(section->getStrategyData()); - - Vector2 gridpos; - stratData->convertWorldToGridSpace(worldPos, gridpos); - int32 x, y; - stratData->determineGridLocation(gridpos, &x, &y); - return stratData->calculatePageID(x, y); - - } + //--------------------------------------------------------------------- + const uint32 Grid2DPageStrategyData::CHUNK_ID = StreamSerialiser::makeIdentifier("G2DD"); + const uint16 Grid2DPageStrategyData::CHUNK_VERSION = 1; + //--------------------------------------------------------------------- + Grid2DPageStrategyData::Grid2DPageStrategyData() + : PageStrategyData() + , mMode(G2D_X_Z) + , mWorldOrigin(Vector3::ZERO) + , mOrigin(Vector2::ZERO) + , mCellSize(1000) + , mLoadRadius(2000) + , mHoldRadius(3000) + , mMinCellX(-32768) + , mMinCellY(-32768) + , mMaxCellX(32767) + , mMaxCellY(32767) + { + updateDerivedMetrics(); + + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::setCellRange(int32 minX, int32 minY, int32 maxX, int32 maxY) + { + mMinCellX = minX; + mMinCellY = minY; + mMaxCellX = maxX; + mMaxCellY = maxY; + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::setCellRangeMinX(int32 minX) + { + mMinCellX = minX; + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::setCellRangeMinY(int32 minY) + { + mMinCellY = minY; + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::setCellRangeMaxX(int32 maxX) + { + mMaxCellX = maxX; + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::setCellRangeMaxY(int32 maxY) + { + mMaxCellY = maxY; + } + //--------------------------------------------------------------------- + Grid2DPageStrategyData::~Grid2DPageStrategyData() + { + + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::setMode(Grid2DMode mode) + { + mMode = mode; + // reset origin + setOrigin(mWorldOrigin); + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::setOrigin(const Vector3& worldOrigin) + { + mWorldOrigin = worldOrigin; + convertWorldToGridSpace(mWorldOrigin, mOrigin); + updateDerivedMetrics(); + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::convertWorldToGridSpace(const Vector3& world, Vector2& grid) + { + switch(mMode) + { + case G2D_X_Z: + grid.x = world.x; + grid.y = -world.z; + break; + case G2D_X_Y: + grid.x = world.x; + grid.y = world.y; + break; + case G2D_Y_Z: + grid.x = -world.z; + grid.y = world.y; + break; + } + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::convertGridToWorldSpace(const Vector2& grid, Vector3& world) + { + // Note that we don't set the 3rd coordinate, let the caller determine that + switch(mMode) + { + case G2D_X_Z: + world.x = grid.x; + world.z = -grid.y; + break; + case G2D_X_Y: + world.x = grid.x; + world.y = grid.y; + break; + case G2D_Y_Z: + world.z = -grid.x; + world.y = grid.y; + break; + } + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::updateDerivedMetrics() + { + mLoadRadiusInCells = mLoadRadius / mCellSize; + mHoldRadiusInCells = mHoldRadius / mCellSize; + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::determineGridLocation(const Vector2& gridpos, int32 *x, int32 *y) + { + Vector2 relPos = gridpos - mOrigin; + Real offset = mCellSize * 0.5f; + relPos.x += offset; + relPos.y += offset; + + *x = static_cast(floor(relPos.x / mCellSize)); + *y = static_cast(floor(relPos.y / mCellSize)); + + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::getBottomLeftGridSpace(int32 x, int32 y, Vector2& bl) + { + Real offset = mCellSize * 0.5f; + bl.x = mOrigin.x - offset + x * mCellSize; + bl.y = mOrigin.y - offset + y * mCellSize; + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::getMidPointGridSpace(int32 x, int32 y, Vector2& mid) + { + mid.x = mOrigin.x + x * mCellSize; + mid.y = mOrigin.y + y * mCellSize; + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::getCornersGridSpace(int32 x, int32 y, Vector2* pFourPoints) + { + getBottomLeftGridSpace(x, y, pFourPoints[0]); + pFourPoints[1] = pFourPoints[0] + Vector2(mCellSize, 0); + pFourPoints[2] = pFourPoints[0] + Vector2(mCellSize, mCellSize); + pFourPoints[3] = pFourPoints[0] + Vector2(0, mCellSize); + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::setCellSize(Real sz) + { + mCellSize = sz; + updateDerivedMetrics(); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::setLoadRadius(Real sz) + { + mLoadRadius = sz; + updateDerivedMetrics(); + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::setHoldRadius(Real sz) + { + mHoldRadius = sz; + updateDerivedMetrics(); + } + //--------------------------------------------------------------------- + PageID Grid2DPageStrategyData::calculatePageID(int32 x, int32 y) + { + // Convert to signed 16-bit so sign bit is in bit 15 + int16 xs16 = static_cast(x); + int16 ys16 = static_cast(y); + + // convert to unsigned because we do not want to propagate sign bit to 32-bits + uint16 x16 = static_cast(xs16); + uint16 y16 = static_cast(ys16); + + uint32 key = 0; + key = (x16 << 16) | y16; + + return (PageID)key; + + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::calculateCell(PageID inPageID, int32 *x, int32 *y) + { + // inverse of calculatePageID + // unsigned versions + uint16 y16 = static_cast(inPageID & 0xFFFF); + uint16 x16 = static_cast((inPageID >> 16) & 0xFFFF); + + *x = static_cast(x16); + *y = static_cast(y16); + + } + //--------------------------------------------------------------------- + bool Grid2DPageStrategyData::load(StreamSerialiser& ser) + { + if (!ser.readChunkBegin(CHUNK_ID, CHUNK_VERSION, "Grid2DPageStrategyData")) + return false; + + uint8 readMode; + ser.read(&readMode); + mMode = (Grid2DMode)readMode; + + Vector3 origin; + ser.read(&origin); + setOrigin(origin); + + ser.read(&mCellSize); + ser.read(&mLoadRadius); + ser.read(&mHoldRadius); + ser.read(&mMinCellX); + ser.read(&mMaxCellX); + ser.read(&mMinCellY); + ser.read(&mMaxCellY); + + ser.readChunkEnd(CHUNK_ID); + + return true; + } + //--------------------------------------------------------------------- + void Grid2DPageStrategyData::save(StreamSerialiser& ser) + { + ser.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); + + uint8 readMode = (uint8)mMode; + ser.write(&readMode); + + ser.write(&mWorldOrigin); + ser.write(&mCellSize); + ser.write(&mLoadRadius); + ser.write(&mHoldRadius); + ser.write(&mMinCellX); + ser.write(&mMaxCellX); + ser.write(&mMinCellY); + ser.write(&mMaxCellY); + + ser.writeChunkEnd(CHUNK_ID); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + Grid2DPageStrategy::Grid2DPageStrategy(PageManager* manager) + : PageStrategy("Grid2D", manager) + { + + } + //--------------------------------------------------------------------- + Grid2DPageStrategy::~Grid2DPageStrategy() + { + + } + //--------------------------------------------------------------------- + void Grid2DPageStrategy::notifyCamera(Camera* cam, PagedWorldSection* section) + { + Grid2DPageStrategyData* stratData = static_cast(section->getStrategyData()); + + const Vector3& pos = cam->getDerivedPosition(); + Vector2 gridpos; + stratData->convertWorldToGridSpace(pos, gridpos); + int32 x, y; + stratData->determineGridLocation(gridpos, &x, &y); + + Real loadRadius = stratData->getLoadRadiusInCells(); + Real holdRadius = stratData->getHoldRadiusInCells(); + // scan the whole Hold range + Real fxmin = (Real)x - holdRadius; + Real fxmax = (Real)x + holdRadius; + Real fymin = (Real)y - holdRadius; + Real fymax = (Real)y + holdRadius; + + int32 xmin = stratData->getCellRangeMinX(); + int32 xmax = stratData->getCellRangeMaxX(); + int32 ymin = stratData->getCellRangeMinY(); + int32 ymax = stratData->getCellRangeMaxY(); + + // Round UP max, round DOWN min + xmin = fxmin < xmin ? xmin : (int32)floor(fxmin); + xmax = fxmax > xmax ? xmax : (int32)ceil(fxmax); + ymin = fymin < ymin ? ymin : (int32)floor(fymin); + ymax = fymax > ymax ? ymax : (int32)ceil(fymax); + // the inner, active load range + fxmin = (Real)x - loadRadius; + fxmax = (Real)x + loadRadius; + fymin = (Real)y - loadRadius; + fymax = (Real)y + loadRadius; + // Round UP max, round DOWN min + int32 loadxmin = fxmin < xmin ? xmin : (int32)floor(fxmin); + int32 loadxmax = fxmax > xmax ? xmax : (int32)ceil(fxmax); + int32 loadymin = fymin < ymin ? ymin : (int32)floor(fymin); + int32 loadymax = fymax > ymax ? ymax : (int32)ceil(fymax); + + for (int32 cy = ymin; cy <= ymax; ++cy) + { + for (int32 cx = xmin; cx <= xmax; ++cx) + { + PageID pageID = stratData->calculatePageID(cx, cy); + if (cx >= loadxmin && cx <= loadxmax && cy >= loadymin && cy <= loadymax) + { + // in the 'load' range, request it + section->loadPage(pageID); + } + else + { + // in the outer 'hold' range, keep it but don't actively load + section->holdPage(pageID); + } + // other pages will by inference be marked for unloading + } + } + + + + } + //--------------------------------------------------------------------- + PageStrategyData* Grid2DPageStrategy::createData() + { + return OGRE_NEW Grid2DPageStrategyData(); + } + //--------------------------------------------------------------------- + void Grid2DPageStrategy::destroyData(PageStrategyData* d) + { + OGRE_DELETE d; + } + //--------------------------------------------------------------------- + void Grid2DPageStrategy::updateDebugDisplay(Page* p, SceneNode* sn) + { + uint8 dbglvl = mManager->getDebugDisplayLevel(); + if (dbglvl) + { + // we could try to avoid updating the geometry every time here, but this + // wouldn't easily deal with paging parameter changes. There shouldn't + // be that many pages anyway, and this is debug after all, so update every time + int32 x, y; + Grid2DPageStrategyData* stratData = static_cast( + p->getParentSection()->getStrategyData()); + stratData->calculateCell(p->getID(), &x, &y); + + Grid2DPageStrategyData* data = static_cast(p->getParentSection()->getStrategyData()); + + // Determine our centre point, we'll anchor here + // Note that world points are initialised to ZERO since only 2 dimensions + // are updated by the grid data (we could display this grid anywhere) + Vector2 gridMidPoint; + Vector3 worldMidPoint = Vector3::ZERO; + data->getMidPointGridSpace(x, y, gridMidPoint); + data->convertGridToWorldSpace(gridMidPoint, worldMidPoint); + + sn->setPosition(worldMidPoint); + + Vector2 gridCorners[4]; + Vector3 worldCorners[4]; + + data->getCornersGridSpace(x, y, gridCorners); + for (int i = 0; i < 4; ++i) + { + worldCorners[i] = Vector3::ZERO; + data->convertGridToWorldSpace(gridCorners[i], worldCorners[i]); + // make relative to mid point + worldCorners[i] -= worldMidPoint; + } + + String matName = "Ogre/G2D/Debug"; + MaterialPtr mat = MaterialManager::getSingleton().getByName(matName); + if (mat.isNull()) + { + mat = MaterialManager::getSingleton().create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + Pass* pass = mat->getTechnique(0)->getPass(0); + pass->setLightingEnabled(false); + pass->setVertexColourTracking(TVC_AMBIENT); + pass->setDepthWriteEnabled(false); + mat->load(); + } + + + ManualObject* mo = 0; + if (sn->numAttachedObjects() == 0) + { + mo = p->getParentSection()->getSceneManager()->createManualObject(); + mo->begin(matName, RenderOperation::OT_LINE_STRIP); + } + else + { + mo = static_cast(sn->getAttachedObject(0)); + mo->beginUpdate(0); + } + + ColourValue vcol = ColourValue::Green; + for(int i = 0; i < 5; ++i) + { + mo->position(worldCorners[i%4]); + mo->colour(vcol); + } + + mo->end(); + + if (sn->numAttachedObjects() == 0) + sn->attachObject(mo); + + } + + } + //--------------------------------------------------------------------- + PageID Grid2DPageStrategy::getPageID(const Vector3& worldPos, PagedWorldSection* section) + { + Grid2DPageStrategyData* stratData = static_cast(section->getStrategyData()); + + Vector2 gridpos; + stratData->convertWorldToGridSpace(worldPos, gridpos); + int32 x, y; + stratData->determineGridLocation(gridpos, &x, &y); + return stratData->calculatePageID(x, y); + + } } diff --git a/Components/Paging/src/OgreGrid3DPageStrategy.cpp b/Components/Paging/src/OgreGrid3DPageStrategy.cpp index 210fecfb033..92425711216 100644 --- a/Components/Paging/src/OgreGrid3DPageStrategy.cpp +++ b/Components/Paging/src/OgreGrid3DPageStrategy.cpp @@ -40,142 +40,142 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - const uint32 Grid3DPageStrategyData::CHUNK_ID = StreamSerialiser::makeIdentifier("G3DD"); - const uint16 Grid3DPageStrategyData::CHUNK_VERSION = 1; - //--------------------------------------------------------------------- - Grid3DPageStrategyData::Grid3DPageStrategyData() - : PageStrategyData() - , mWorldOrigin(Vector3::ZERO) - , mOrigin(Vector3::ZERO) - , mCellSize(1000,1000,1000) - , mLoadRadius(2000) - , mHoldRadius(3000) - , mMinCellX(-512) - , mMinCellY(-512) - , mMinCellZ(-512) - , mMaxCellX(511) - , mMaxCellY(511) - , mMaxCellZ(511) - { - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setCellRange(int32 minX, int32 minY, int32 minZ, int32 maxX, int32 maxY, int32 maxZ) - { - mMinCellX = minX; - mMinCellY = minY; - mMinCellZ = minZ; - mMaxCellX = maxX; - mMaxCellY = maxY; - mMaxCellZ = maxZ; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setCellRangeMinX(int32 minX) - { - mMinCellX = minX; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setCellRangeMinY(int32 minY) - { - mMinCellY = minY; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setCellRangeMinZ(int32 minZ) - { - mMinCellZ = minZ; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setCellRangeMaxX(int32 maxX) - { - mMaxCellX = maxX; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setCellRangeMaxY(int32 maxY) - { - mMaxCellY = maxY; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setCellRangeMaxZ(int32 maxZ) - { - mMaxCellZ = maxZ; - } - //--------------------------------------------------------------------- - Grid3DPageStrategyData::~Grid3DPageStrategyData() - { - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setOrigin(const Vector3& origin) - { - mWorldOrigin = origin; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::determineGridLocation(const Vector3& pos, int32 *x, int32 *y, int32 *z) - { - Vector3 relPos = pos - mOrigin + mCellSize * 0.5f; + //--------------------------------------------------------------------- + const uint32 Grid3DPageStrategyData::CHUNK_ID = StreamSerialiser::makeIdentifier("G3DD"); + const uint16 Grid3DPageStrategyData::CHUNK_VERSION = 1; + //--------------------------------------------------------------------- + Grid3DPageStrategyData::Grid3DPageStrategyData() + : PageStrategyData() + , mWorldOrigin(Vector3::ZERO) + , mOrigin(Vector3::ZERO) + , mCellSize(1000,1000,1000) + , mLoadRadius(2000) + , mHoldRadius(3000) + , mMinCellX(-512) + , mMinCellY(-512) + , mMinCellZ(-512) + , mMaxCellX(511) + , mMaxCellY(511) + , mMaxCellZ(511) + { + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setCellRange(int32 minX, int32 minY, int32 minZ, int32 maxX, int32 maxY, int32 maxZ) + { + mMinCellX = minX; + mMinCellY = minY; + mMinCellZ = minZ; + mMaxCellX = maxX; + mMaxCellY = maxY; + mMaxCellZ = maxZ; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setCellRangeMinX(int32 minX) + { + mMinCellX = minX; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setCellRangeMinY(int32 minY) + { + mMinCellY = minY; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setCellRangeMinZ(int32 minZ) + { + mMinCellZ = minZ; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setCellRangeMaxX(int32 maxX) + { + mMaxCellX = maxX; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setCellRangeMaxY(int32 maxY) + { + mMaxCellY = maxY; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setCellRangeMaxZ(int32 maxZ) + { + mMaxCellZ = maxZ; + } + //--------------------------------------------------------------------- + Grid3DPageStrategyData::~Grid3DPageStrategyData() + { + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setOrigin(const Vector3& origin) + { + mWorldOrigin = origin; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::determineGridLocation(const Vector3& pos, int32 *x, int32 *y, int32 *z) + { + Vector3 relPos = pos - mOrigin + mCellSize * 0.5f; - *x = static_cast(floor(relPos.x / mCellSize.x)); - *y = static_cast(floor(relPos.y / mCellSize.y)); - *z = static_cast(floor(relPos.z / mCellSize.z)); - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::getBottomLeftGridSpace(int32 x, int32 y, int32 z, Vector3& bl) - { - bl.x = mOrigin.x + (x-0.5f) * mCellSize.x; - bl.y = mOrigin.y + (y-0.5f) * mCellSize.y; - bl.z = mOrigin.z + (z-0.5f) * mCellSize.z; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::getMidPointGridSpace(int32 x, int32 y, int32 z, Vector3& mid) - { - mid.x = mOrigin.x + float(x) * mCellSize.x; - mid.y = mOrigin.y + float(y) * mCellSize.y; - mid.z = mOrigin.z + float(z) * mCellSize.z; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::getCornersGridSpace(int32 x, int32 y, int32 z, Vector3* pEightPoints) - { - getBottomLeftGridSpace(x, y, z, pEightPoints[0]); - pEightPoints[1] = pEightPoints[0] + Vector3(mCellSize.x, 0, 0); - pEightPoints[2] = pEightPoints[0] + Vector3(mCellSize.x, mCellSize.y, 0); - pEightPoints[3] = pEightPoints[0] + Vector3(0, mCellSize.y, 0); - pEightPoints[4] = pEightPoints[0] + Vector3(0, 0, mCellSize.z); - pEightPoints[5] = pEightPoints[1] + Vector3(0, 0, mCellSize.z); - pEightPoints[6] = pEightPoints[2] + Vector3(0, 0, mCellSize.z); - pEightPoints[7] = pEightPoints[3] + Vector3(0, 0, mCellSize.z); - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setCellSize(const Vector3& sz) - { - mCellSize = sz; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setLoadRadius(Real sz) - { - mLoadRadius = sz; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::setHoldRadius(Real sz) - { - mHoldRadius = sz; - } - //--------------------------------------------------------------------- - PageID Grid3DPageStrategyData::calculatePageID(int32 x, int32 y, int32 z) - { + *x = static_cast(floor(relPos.x / mCellSize.x)); + *y = static_cast(floor(relPos.y / mCellSize.y)); + *z = static_cast(floor(relPos.z / mCellSize.z)); + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::getBottomLeftGridSpace(int32 x, int32 y, int32 z, Vector3& bl) + { + bl.x = mOrigin.x + (x-0.5f) * mCellSize.x; + bl.y = mOrigin.y + (y-0.5f) * mCellSize.y; + bl.z = mOrigin.z + (z-0.5f) * mCellSize.z; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::getMidPointGridSpace(int32 x, int32 y, int32 z, Vector3& mid) + { + mid.x = mOrigin.x + float(x) * mCellSize.x; + mid.y = mOrigin.y + float(y) * mCellSize.y; + mid.z = mOrigin.z + float(z) * mCellSize.z; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::getCornersGridSpace(int32 x, int32 y, int32 z, Vector3* pEightPoints) + { + getBottomLeftGridSpace(x, y, z, pEightPoints[0]); + pEightPoints[1] = pEightPoints[0] + Vector3(mCellSize.x, 0, 0); + pEightPoints[2] = pEightPoints[0] + Vector3(mCellSize.x, mCellSize.y, 0); + pEightPoints[3] = pEightPoints[0] + Vector3(0, mCellSize.y, 0); + pEightPoints[4] = pEightPoints[0] + Vector3(0, 0, mCellSize.z); + pEightPoints[5] = pEightPoints[1] + Vector3(0, 0, mCellSize.z); + pEightPoints[6] = pEightPoints[2] + Vector3(0, 0, mCellSize.z); + pEightPoints[7] = pEightPoints[3] + Vector3(0, 0, mCellSize.z); + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setCellSize(const Vector3& sz) + { + mCellSize = sz; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setLoadRadius(Real sz) + { + mLoadRadius = sz; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::setHoldRadius(Real sz) + { + mHoldRadius = sz; + } + //--------------------------------------------------------------------- + PageID Grid3DPageStrategyData::calculatePageID(int32 x, int32 y, int32 z) + { // Go into positive range (simpler on decode) x -= mMinCellX; y -= mMinCellY; z -= mMinCellZ; // Push index bits into place - uint32 key = z & 1023; + uint32 key = z & 1023; key = (key<<10) | (y&1023); key = (key<<10) | (x&1023); - return (PageID)key; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::calculateCell(PageID inPageID, int32 *x, int32 *y, int32* z) - { - // Pop bits from page index: + return (PageID)key; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::calculateCell(PageID inPageID, int32 *x, int32 *y, int32* z) + { + // Pop bits from page index: int32 ox = inPageID & 1023; inPageID >>= 10; int32 oy = inPageID & 1023; inPageID >>= 10; int32 oz = inPageID & 1023; @@ -185,175 +185,175 @@ namespace Ogre //if( oy > 511 ) oy = 1024 - oy; //if( oz > 511 ) oz = 1024 - oz; // Back in the [min..max] range: - *x = ox + mMinCellX; - *y = oy + mMinCellY; - *z = oz + mMinCellZ; - } - //--------------------------------------------------------------------- - bool Grid3DPageStrategyData::load(StreamSerialiser& ser) - { - if (!ser.readChunkBegin(CHUNK_ID, CHUNK_VERSION, "Grid3DPageStrategyData")) - return false; + *x = ox + mMinCellX; + *y = oy + mMinCellY; + *z = oz + mMinCellZ; + } + //--------------------------------------------------------------------- + bool Grid3DPageStrategyData::load(StreamSerialiser& ser) + { + if (!ser.readChunkBegin(CHUNK_ID, CHUNK_VERSION, "Grid3DPageStrategyData")) + return false; - ser.read(&mOrigin); - ser.read(&mCellSize); - ser.read(&mLoadRadius); - ser.read(&mHoldRadius); - ser.read(&mMinCellX); - ser.read(&mMaxCellX); - ser.read(&mMinCellY); - ser.read(&mMaxCellY); - ser.read(&mMinCellZ); - ser.read(&mMaxCellZ); + ser.read(&mOrigin); + ser.read(&mCellSize); + ser.read(&mLoadRadius); + ser.read(&mHoldRadius); + ser.read(&mMinCellX); + ser.read(&mMaxCellX); + ser.read(&mMinCellY); + ser.read(&mMaxCellY); + ser.read(&mMinCellZ); + ser.read(&mMaxCellZ); - ser.readChunkEnd(CHUNK_ID); + ser.readChunkEnd(CHUNK_ID); - return true; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategyData::save(StreamSerialiser& ser) - { - ser.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); + return true; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategyData::save(StreamSerialiser& ser) + { + ser.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); - ser.write(&mWorldOrigin); - ser.write(&mCellSize); - ser.write(&mLoadRadius); - ser.write(&mHoldRadius); - ser.write(&mMinCellX); - ser.write(&mMaxCellX); - ser.write(&mMinCellY); - ser.write(&mMaxCellY); - ser.write(&mMinCellZ); - ser.write(&mMaxCellZ); + ser.write(&mWorldOrigin); + ser.write(&mCellSize); + ser.write(&mLoadRadius); + ser.write(&mHoldRadius); + ser.write(&mMinCellX); + ser.write(&mMaxCellX); + ser.write(&mMinCellY); + ser.write(&mMaxCellY); + ser.write(&mMinCellZ); + ser.write(&mMaxCellZ); - ser.writeChunkEnd(CHUNK_ID); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - Grid3DPageStrategy::Grid3DPageStrategy(PageManager* manager) - : PageStrategy("Grid3D", manager) - { + ser.writeChunkEnd(CHUNK_ID); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + Grid3DPageStrategy::Grid3DPageStrategy(PageManager* manager) + : PageStrategy("Grid3D", manager) + { - } - //--------------------------------------------------------------------- - Grid3DPageStrategy::~Grid3DPageStrategy() - { + } + //--------------------------------------------------------------------- + Grid3DPageStrategy::~Grid3DPageStrategy() + { - } - //--------------------------------------------------------------------- - void Grid3DPageStrategy::notifyCamera(Camera* cam, PagedWorldSection* section) - { - Grid3DPageStrategyData* stratData = static_cast(section->getStrategyData()); + } + //--------------------------------------------------------------------- + void Grid3DPageStrategy::notifyCamera(Camera* cam, PagedWorldSection* section) + { + Grid3DPageStrategyData* stratData = static_cast(section->getStrategyData()); - const Vector3& pos = cam->getDerivedPosition(); - int32 x, y, z; - stratData->determineGridLocation(pos, &x, &y, &z); + const Vector3& pos = cam->getDerivedPosition(); + int32 x, y, z; + stratData->determineGridLocation(pos, &x, &y, &z); - Real loadRadius = stratData->getLoadRadius(); - Real holdRadius = stratData->getHoldRadius(); - // scan the whole Hold range + Real loadRadius = stratData->getLoadRadius(); + Real holdRadius = stratData->getHoldRadius(); + // scan the whole Hold range Real fxmin = (Real)x - holdRadius/stratData->getCellSize().x; - Real fxmax = (Real)x + holdRadius/stratData->getCellSize().x; - Real fymin = (Real)y - holdRadius/stratData->getCellSize().y; - Real fymax = (Real)y + holdRadius/stratData->getCellSize().y; - Real fzmin = (Real)z - holdRadius/stratData->getCellSize().z; - Real fzmax = (Real)z + holdRadius/stratData->getCellSize().z; + Real fxmax = (Real)x + holdRadius/stratData->getCellSize().x; + Real fymin = (Real)y - holdRadius/stratData->getCellSize().y; + Real fymax = (Real)y + holdRadius/stratData->getCellSize().y; + Real fzmin = (Real)z - holdRadius/stratData->getCellSize().z; + Real fzmax = (Real)z + holdRadius/stratData->getCellSize().z; - int32 xmin = stratData->getCellRangeMinX(); - int32 xmax = stratData->getCellRangeMaxX(); - int32 ymin = stratData->getCellRangeMinY(); - int32 ymax = stratData->getCellRangeMaxY(); - int32 zmin = stratData->getCellRangeMinZ(); - int32 zmax = stratData->getCellRangeMaxZ(); + int32 xmin = stratData->getCellRangeMinX(); + int32 xmax = stratData->getCellRangeMaxX(); + int32 ymin = stratData->getCellRangeMinY(); + int32 ymax = stratData->getCellRangeMaxY(); + int32 zmin = stratData->getCellRangeMinZ(); + int32 zmax = stratData->getCellRangeMaxZ(); - // Round UP max, round DOWN min - xmin = fxmin < xmin ? xmin : (int32)floor(fxmin); - xmax = fxmax > xmax ? xmax : (int32)ceil(fxmax); - ymin = fymin < ymin ? ymin : (int32)floor(fymin); - ymax = fymax > ymax ? ymax : (int32)ceil(fymax); - zmin = fzmin < zmin ? zmin : (int32)floor(fzmin); - zmax = fzmax > zmax ? zmax : (int32)ceil(fzmax); - // the inner, active load range - fxmin = (Real)x - loadRadius/stratData->getCellSize().x; - fxmax = (Real)x + loadRadius/stratData->getCellSize().x; - fymin = (Real)y - loadRadius/stratData->getCellSize().y; - fymax = (Real)y + loadRadius/stratData->getCellSize().y; - fzmin = (Real)z - loadRadius/stratData->getCellSize().z; - fzmax = (Real)z + loadRadius/stratData->getCellSize().z; - // Round UP max, round DOWN min - int32 loadxmin = fxmin < xmin ? xmin : (int32)floor(fxmin); - int32 loadxmax = fxmax > xmax ? xmax : (int32)ceil(fxmax); - int32 loadymin = fymin < ymin ? ymin : (int32)floor(fymin); - int32 loadymax = fymax > ymax ? ymax : (int32)ceil(fymax); - int32 loadzmin = fzmin < zmin ? zmin : (int32)floor(fzmin); - int32 loadzmax = fzmax > zmax ? zmax : (int32)ceil(fzmax); + // Round UP max, round DOWN min + xmin = fxmin < xmin ? xmin : (int32)floor(fxmin); + xmax = fxmax > xmax ? xmax : (int32)ceil(fxmax); + ymin = fymin < ymin ? ymin : (int32)floor(fymin); + ymax = fymax > ymax ? ymax : (int32)ceil(fymax); + zmin = fzmin < zmin ? zmin : (int32)floor(fzmin); + zmax = fzmax > zmax ? zmax : (int32)ceil(fzmax); + // the inner, active load range + fxmin = (Real)x - loadRadius/stratData->getCellSize().x; + fxmax = (Real)x + loadRadius/stratData->getCellSize().x; + fymin = (Real)y - loadRadius/stratData->getCellSize().y; + fymax = (Real)y + loadRadius/stratData->getCellSize().y; + fzmin = (Real)z - loadRadius/stratData->getCellSize().z; + fzmax = (Real)z + loadRadius/stratData->getCellSize().z; + // Round UP max, round DOWN min + int32 loadxmin = fxmin < xmin ? xmin : (int32)floor(fxmin); + int32 loadxmax = fxmax > xmax ? xmax : (int32)ceil(fxmax); + int32 loadymin = fymin < ymin ? ymin : (int32)floor(fymin); + int32 loadymax = fymax > ymax ? ymax : (int32)ceil(fymax); + int32 loadzmin = fzmin < zmin ? zmin : (int32)floor(fzmin); + int32 loadzmax = fzmax > zmax ? zmax : (int32)ceil(fzmax); - for (int32 cz = zmin; cz <= zmax; ++cz) - { - for (int32 cy = ymin; cy <= ymax; ++cy) - { - for (int32 cx = xmin; cx <= xmax; ++cx) - { - PageID pageID = stratData->calculatePageID(cx, cy, cz); + for (int32 cz = zmin; cz <= zmax; ++cz) + { + for (int32 cy = ymin; cy <= ymax; ++cy) + { + for (int32 cx = xmin; cx <= xmax; ++cx) + { + PageID pageID = stratData->calculatePageID(cx, cy, cz); - if (cx >= loadxmin && cx <= loadxmax + if (cx >= loadxmin && cx <= loadxmax && cy >= loadymin && cy <= loadymax && cz >= loadzmin && cz <= loadzmax ) - { + { Vector3 bl; stratData->getBottomLeftGridSpace(cx, cy, cz, bl); Ogre::AxisAlignedBox bbox(bl, bl+stratData->getCellSize()); if( cam->isVisible(bbox) ) - section->loadPage(pageID); + section->loadPage(pageID); else - section->holdPage(pageID); - } - else - { - // in the outer 'hold' range, keep it but don't actively load - section->holdPage(pageID); - } - // other pages will by inference be marked for unloading - } - } + section->holdPage(pageID); + } + else + { + // in the outer 'hold' range, keep it but don't actively load + section->holdPage(pageID); + } + // other pages will by inference be marked for unloading + } + } } - } - //--------------------------------------------------------------------- - PageStrategyData* Grid3DPageStrategy::createData() - { - return OGRE_NEW Grid3DPageStrategyData(); - } - //--------------------------------------------------------------------- - void Grid3DPageStrategy::destroyData(PageStrategyData* d) - { - OGRE_DELETE d; - } - //--------------------------------------------------------------------- - void Grid3DPageStrategy::updateDebugDisplay(Page* p, SceneNode* sn) - { - uint8 dbglvl = mManager->getDebugDisplayLevel(); - if (dbglvl) - { - // we could try to avoid updating the geometry every time here, but this - // wouldn't easily deal with paging parameter changes. There shouldn't - // be that many pages anyway, and this is debug after all, so update every time - int32 x, y, z; - Grid3DPageStrategyData* stratData = static_cast( - p->getParentSection()->getStrategyData()); - stratData->calculateCell(p->getID(), &x, &y, &z); + } + //--------------------------------------------------------------------- + PageStrategyData* Grid3DPageStrategy::createData() + { + return OGRE_NEW Grid3DPageStrategyData(); + } + //--------------------------------------------------------------------- + void Grid3DPageStrategy::destroyData(PageStrategyData* d) + { + OGRE_DELETE d; + } + //--------------------------------------------------------------------- + void Grid3DPageStrategy::updateDebugDisplay(Page* p, SceneNode* sn) + { + uint8 dbglvl = mManager->getDebugDisplayLevel(); + if (dbglvl) + { + // we could try to avoid updating the geometry every time here, but this + // wouldn't easily deal with paging parameter changes. There shouldn't + // be that many pages anyway, and this is debug after all, so update every time + int32 x, y, z; + Grid3DPageStrategyData* stratData = static_cast( + p->getParentSection()->getStrategyData()); + stratData->calculateCell(p->getID(), &x, &y, &z); - Grid3DPageStrategyData* data = static_cast(p->getParentSection()->getStrategyData()); + Grid3DPageStrategyData* data = static_cast(p->getParentSection()->getStrategyData()); - // Determine our centre point, we'll anchor here - Vector3 midPoint; - data->getMidPointGridSpace(x, y, z, midPoint); - sn->setPosition(midPoint); + // Determine our centre point, we'll anchor here + Vector3 midPoint; + data->getMidPointGridSpace(x, y, z, midPoint); + sn->setPosition(midPoint); //--- Get coordinates, relative to midPoint : - Vector3 corners[8]; + Vector3 corners[8]; Vector3 hSize = 0.500f * stratData->getCellSize(); - for (int i = 0; i < 8; ++i) + for (int i = 0; i < 8; ++i) { corners[i].x = i&1 ? hSize.x : -hSize.x; corners[i].z = i&2 ? hSize.y : -hSize.y; @@ -361,62 +361,62 @@ namespace Ogre } //--- Get a material - String matName = "Ogre/G3D/Debug"; - MaterialPtr mat = MaterialManager::getSingleton().getByName(matName); - if (mat.isNull()) - { - mat = MaterialManager::getSingleton().create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - Pass* pass = mat->getTechnique(0)->getPass(0); - pass->setLightingEnabled(false); - pass->setVertexColourTracking(TVC_AMBIENT); - pass->setDepthWriteEnabled(false); - mat->load(); - } + String matName = "Ogre/G3D/Debug"; + MaterialPtr mat = MaterialManager::getSingleton().getByName(matName); + if (mat.isNull()) + { + mat = MaterialManager::getSingleton().create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + Pass* pass = mat->getTechnique(0)->getPass(0); + pass->setLightingEnabled(false); + pass->setVertexColourTracking(TVC_AMBIENT); + pass->setDepthWriteEnabled(false); + mat->load(); + } - ManualObject* mo = 0; + ManualObject* mo = 0; bool update = sn->numAttachedObjects() > 0; - if( update ) - { - mo = static_cast(sn->getAttachedObject(0)); - mo->beginUpdate(0); - } - else - { - mo = p->getParentSection()->getSceneManager()->createManualObject(); - mo->begin(matName, RenderOperation::OT_LINE_STRIP); - } + if( update ) + { + mo = static_cast(sn->getAttachedObject(0)); + mo->beginUpdate(0); + } + else + { + mo = p->getParentSection()->getSceneManager()->createManualObject(); + mo->begin(matName, RenderOperation::OT_LINE_STRIP); + } - ColourValue vcol = ColourValue::Green; - mo->position(corners[0]); mo->colour(vcol); // First Square... - mo->position(corners[1]); mo->colour(vcol); - mo->position(corners[3]); mo->colour(vcol); - mo->position(corners[2]); mo->colour(vcol); - mo->position(corners[0]); mo->colour(vcol); - mo->position(corners[4]); mo->colour(vcol); // 0-4 link + second square and - mo->position(corners[5]); mo->colour(vcol); - mo->position(corners[7]); mo->colour(vcol); - mo->position(corners[6]); mo->colour(vcol); - mo->position(corners[4]); mo->colour(vcol); - mo->position(corners[5]); mo->colour(vcol); // 5-1 link - mo->position(corners[1]); mo->colour(vcol); - mo->position(corners[3]); mo->colour(vcol); // 3-7 link - mo->position(corners[7]); mo->colour(vcol); - mo->position(corners[6]); mo->colour(vcol); // 6-2 link - mo->position(corners[2]); mo->colour(vcol); - mo->end(); + ColourValue vcol = ColourValue::Green; + mo->position(corners[0]); mo->colour(vcol); // First Square... + mo->position(corners[1]); mo->colour(vcol); + mo->position(corners[3]); mo->colour(vcol); + mo->position(corners[2]); mo->colour(vcol); + mo->position(corners[0]); mo->colour(vcol); + mo->position(corners[4]); mo->colour(vcol); // 0-4 link + second square and + mo->position(corners[5]); mo->colour(vcol); + mo->position(corners[7]); mo->colour(vcol); + mo->position(corners[6]); mo->colour(vcol); + mo->position(corners[4]); mo->colour(vcol); + mo->position(corners[5]); mo->colour(vcol); // 5-1 link + mo->position(corners[1]); mo->colour(vcol); + mo->position(corners[3]); mo->colour(vcol); // 3-7 link + mo->position(corners[7]); mo->colour(vcol); + mo->position(corners[6]); mo->colour(vcol); // 6-2 link + mo->position(corners[2]); mo->colour(vcol); + mo->end(); - if(!update) - sn->attachObject(mo); - } - } + if(!update) + sn->attachObject(mo); + } + } - //--------------------------------------------------------------------- - PageID Grid3DPageStrategy::getPageID(const Vector3& pos, PagedWorldSection* section) - { - Grid3DPageStrategyData* stratData = static_cast(section->getStrategyData()); + //--------------------------------------------------------------------- + PageID Grid3DPageStrategy::getPageID(const Vector3& pos, PagedWorldSection* section) + { + Grid3DPageStrategyData* stratData = static_cast(section->getStrategyData()); - int32 x, y, z; - stratData->determineGridLocation(pos, &x, &y, &z); - return stratData->calculatePageID(x, y, z); - } + int32 x, y, z; + stratData->determineGridLocation(pos, &x, &y, &z); + return stratData->calculatePageID(x, y, z); + } } diff --git a/Components/Paging/src/OgrePage.cpp b/Components/Paging/src/OgrePage.cpp index 3d7bebb4c24..73d15975c86 100644 --- a/Components/Paging/src/OgrePage.cpp +++ b/Components/Paging/src/OgrePage.cpp @@ -45,423 +45,423 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - const uint32 Page::CHUNK_ID = StreamSerialiser::makeIdentifier("PAGE"); - const uint16 Page::CHUNK_VERSION = 1; - const uint32 Page::CHUNK_CONTENTCOLLECTION_DECLARATION_ID = StreamSerialiser::makeIdentifier("PCNT"); - const uint16 Page::WORKQUEUE_PREPARE_REQUEST = 1; - const uint16 Page::WORKQUEUE_CHANGECOLLECTION_REQUEST = 3; - - //--------------------------------------------------------------------- - Page::Page(PageID pageID, PagedWorldSection* parent) - : mID(pageID) - , mParent(parent) - , mDeferredProcessInProgress(false) - , mModified(false) - , mDebugNode(0) - { - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - mWorkQueueChannel = wq->getChannel("Ogre/Page"); - wq->addRequestHandler(mWorkQueueChannel, this); - wq->addResponseHandler(mWorkQueueChannel, this); - touch(); - } - //--------------------------------------------------------------------- - Page::~Page() - { - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - wq->removeRequestHandler(mWorkQueueChannel, this); - wq->removeResponseHandler(mWorkQueueChannel, this); - - destroyAllContentCollections(); - if (mDebugNode) - { - // destroy while we have the chance - SceneNode::ObjectIterator it = mDebugNode->getAttachedObjectIterator(); - while(it.hasMoreElements()) - mParent->getSceneManager()->destroyMovableObject(it.getNext()); - mDebugNode->removeAndDestroyAllChildren(); - mParent->getSceneManager()->destroySceneNode(mDebugNode); - - mDebugNode = 0; - } - } - //--------------------------------------------------------------------- - void Page::destroyAllContentCollections() - { - for (ContentCollectionList::iterator i = mContentCollections.begin(); - i != mContentCollections.end(); ++i) - { - delete *i; - } - mContentCollections.clear(); - } - //--------------------------------------------------------------------- - PageManager* Page::getManager() const - { - return mParent->getManager(); - } - //--------------------------------------------------------------------- - void Page::touch() - { - mFrameLastHeld = Root::getSingleton().getNextFrameNumber(); - } - //--------------------------------------------------------------------- - bool Page::isHeld() const - { - unsigned long nextFrame = Root::getSingleton().getNextFrameNumber(); - unsigned long dist; - if (nextFrame < mFrameLastHeld) - { - // we must have wrapped around - dist = mFrameLastHeld + (std::numeric_limits::max() - mFrameLastHeld); - } - else - dist = nextFrame - mFrameLastHeld; - - // 5-frame tolerance - return dist <= 5; - } - //--------------------------------------------------------------------- - bool Page::prepareImpl(StreamSerialiser& stream, PageData* dataToPopulate) - { - - // Now do the real loading - if (!stream.readChunkBegin(CHUNK_ID, CHUNK_VERSION, "Page")) - return false; - - // pageID check (we should know the ID we're expecting) - uint32 storedID; - stream.read(&storedID); - if (mID != storedID) - { - LogManager::getSingleton().stream() << "Error: Tried to populate Page ID " << mID - << " with data corresponding to page ID " << storedID; - stream.undoReadChunk(CHUNK_ID); - return false; - } - - PageManager* mgr = getManager(); - - while(stream.peekNextChunkID() == CHUNK_CONTENTCOLLECTION_DECLARATION_ID) - { - const StreamSerialiser::Chunk* collChunk = stream.readChunkBegin(); - String factoryName; - stream.read(&factoryName); - stream.readChunkEnd(CHUNK_CONTENTCOLLECTION_DECLARATION_ID); - // Supported type? - PageContentCollectionFactory* collFact = mgr->getContentCollectionFactory(factoryName); - if (collFact) - { - PageContentCollection* collInst = collFact->createInstance(); - if (collInst->prepare(stream)) // read type-specific data - { - dataToPopulate->collectionsToAdd.push_back(collInst); - } - else - { - LogManager::getSingleton().stream() << "Error preparing PageContentCollection type: " - << factoryName << " in " << *this; - collFact->destroyInstance(collInst); - } - } - else - { - LogManager::getSingleton().stream() << "Unsupported PageContentCollection type: " - << factoryName << " in " << *this; - // skip - stream.readChunkEnd(collChunk->id); - } - - } - - - mModified = false; - - return true; - } - //--------------------------------------------------------------------- - void Page::load(bool synchronous) - { - if (!mDeferredProcessInProgress) - { - destroyAllContentCollections(); - PageRequest req(this); - mDeferredProcessInProgress = true; - Root::getSingleton().getWorkQueue()->addRequest(mWorkQueueChannel, WORKQUEUE_PREPARE_REQUEST, - Any(req), 0, synchronous); - } - - } - //--------------------------------------------------------------------- - void Page::unload() - { - destroyAllContentCollections(); - } - //--------------------------------------------------------------------- - bool Page::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - PageRequest preq = any_cast(req->getData()); - // only deal with own requests - // we do this because if we delete a page we want any pending tasks to be discarded - if (preq.srcPage != this) - return false; - else - return RequestHandler::canHandleRequest(req, srcQ); - - } - //--------------------------------------------------------------------- - bool Page::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - PageRequest preq = any_cast(res->getRequest()->getData()); - // only deal with own requests - // we do this because if we delete a page we want any pending tasks to be discarded - if (preq.srcPage != this) - return false; - else - return true; - - } - //--------------------------------------------------------------------- - WorkQueue::Response* Page::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - // Background thread (maybe) - - PageRequest preq = any_cast(req->getData()); - // only deal with own requests; we shouldn't ever get here though - if (preq.srcPage != this) - return 0; - - PageResponse res; - res.pageData = OGRE_NEW PageData(); - WorkQueue::Response* response = 0; - try - { - prepareImpl(res.pageData); - response = OGRE_NEW WorkQueue::Response(req, true, Any(res)); - } - catch (Exception& e) - { - // oops - response = OGRE_NEW WorkQueue::Response(req, false, Any(res), - e.getFullDescription()); - } - - return response; - } - //--------------------------------------------------------------------- - void Page::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - // Main thread - PageResponse pres = any_cast(res->getData()); - PageRequest preq = any_cast(res->getRequest()->getData()); - - // only deal with own requests - if (preq.srcPage!= this) - return; - - // final loading behaviour - if (res->succeeded()) - { - std::swap(mContentCollections, pres.pageData->collectionsToAdd); - loadImpl(); - } - - OGRE_DELETE pres.pageData; - - mDeferredProcessInProgress = false; - - } - //--------------------------------------------------------------------- - bool Page::prepareImpl(PageData* dataToPopulate) - { - // Procedural preparation - if (mParent->_prepareProceduralPage(this)) - return true; - else - { - // Background loading - String filename = generateFilename(); - - DataStreamPtr stream = Root::getSingleton().openFileStream(filename, - getManager()->getPageResourceGroup()); - StreamSerialiser ser(stream); - return prepareImpl(ser, dataToPopulate); - } - - - } - //--------------------------------------------------------------------- - void Page::loadImpl() - { - mParent->_loadProceduralPage(this); - - for (ContentCollectionList::iterator i = mContentCollections.begin(); - i != mContentCollections.end(); ++i) - { - (*i)->load(); - } - } - //--------------------------------------------------------------------- - void Page::save() - { - String filename = generateFilename(); - save(filename); - } - //--------------------------------------------------------------------- - void Page::save(const String& filename) - { - DataStreamPtr stream = Root::getSingleton().createFileStream(filename, - getManager()->getPageResourceGroup(), true); - StreamSerialiser ser(stream); - save(ser); - } - //--------------------------------------------------------------------- - void Page::save(StreamSerialiser& stream) - { - stream.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); - - // page id - stream.write(&mID); - - // content collections - for (ContentCollectionList::iterator i = mContentCollections.begin(); - i != mContentCollections.end(); ++i) - { - // declaration - stream.writeChunkBegin(CHUNK_CONTENTCOLLECTION_DECLARATION_ID); - stream.write(&(*i)->getType()); - stream.writeChunkEnd(CHUNK_CONTENTCOLLECTION_DECLARATION_ID); - // data - (*i)->save(stream); - } - - stream.writeChunkEnd(CHUNK_ID); - - mModified = false; - } - //--------------------------------------------------------------------- - void Page::frameStart(Real timeSinceLastFrame) - { - updateDebugDisplay(); - - // content collections - for (ContentCollectionList::iterator i = mContentCollections.begin(); - i != mContentCollections.end(); ++i) - { - (*i)->frameStart(timeSinceLastFrame); - } - - - } - //--------------------------------------------------------------------- - void Page::frameEnd(Real timeElapsed) - { - // content collections - for (ContentCollectionList::iterator i = mContentCollections.begin(); - i != mContentCollections.end(); ++i) - { - (*i)->frameEnd(timeElapsed); - } - - } - //--------------------------------------------------------------------- - void Page::notifyCamera(Camera* cam) - { - // content collections - for (ContentCollectionList::iterator i = mContentCollections.begin(); - i != mContentCollections.end(); ++i) - { - (*i)->notifyCamera(cam); - } - - } - //--------------------------------------------------------------------- - void Page::updateDebugDisplay() - { - uint8 dbglvl = getManager()->getDebugDisplayLevel(); - if (dbglvl > 0) - { - // update debug display - if (!mDebugNode) - { - mDebugNode = mParent->getSceneManager()->getRootSceneNode()->createChildSceneNode(); - } - mParent->getStrategy()->updateDebugDisplay(this, mDebugNode); - - mDebugNode->setVisible(true); - } - else if (mDebugNode) - { - mDebugNode->setVisible(false); - } - - } - //--------------------------------------------------------------------- - PageContentCollection* Page::createContentCollection(const String& typeName) - { - PageContentCollection* coll = getManager()->createContentCollection(typeName); - coll->_notifyAttached(this); - mContentCollections.push_back(coll); - return coll; - } - //--------------------------------------------------------------------- - void Page::destroyContentCollection(PageContentCollection* coll) - { - ContentCollectionList::iterator i = std::find( - mContentCollections.begin(), mContentCollections.end(), coll); - if (i != mContentCollections.end()) - { - mContentCollections.erase(i); - } - getManager()->destroyContentCollection(coll); - } - //--------------------------------------------------------------------- - size_t Page::getContentCollectionCount() const - { - return mContentCollections.size(); - } - //--------------------------------------------------------------------- - PageContentCollection* Page::getContentCollection(size_t index) - { - assert(index < mContentCollections.size()); - - return mContentCollections[index]; - } - //--------------------------------------------------------------------- - const Page::ContentCollectionList& Page::getContentCollectionList() const - { - return mContentCollections; - } - //--------------------------------------------------------------------- - SceneManager* Page::getSceneManager() const - { - return mParent->getSceneManager(); - } - //--------------------------------------------------------------------- - std::ostream& operator <<( std::ostream& o, const Page& p ) - { - o << "Page(ID:" << p.getID() << ", section:" << p.getParentSection()->getName() - << ", world:" << p.getParentSection()->getWorld()->getName() << ")"; - return o; - } - //--------------------------------------------------------------------- - String Page::generateFilename() const - { - StringStream str; - if (mParent) - str << mParent->getWorld()->getName() << "_" << mParent->getName(); - - str << std::setw(8) << std::setfill('0') << std::hex << mID << ".page"; + //--------------------------------------------------------------------- + const uint32 Page::CHUNK_ID = StreamSerialiser::makeIdentifier("PAGE"); + const uint16 Page::CHUNK_VERSION = 1; + const uint32 Page::CHUNK_CONTENTCOLLECTION_DECLARATION_ID = StreamSerialiser::makeIdentifier("PCNT"); + const uint16 Page::WORKQUEUE_PREPARE_REQUEST = 1; + const uint16 Page::WORKQUEUE_CHANGECOLLECTION_REQUEST = 3; + + //--------------------------------------------------------------------- + Page::Page(PageID pageID, PagedWorldSection* parent) + : mID(pageID) + , mParent(parent) + , mDeferredProcessInProgress(false) + , mModified(false) + , mDebugNode(0) + { + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + mWorkQueueChannel = wq->getChannel("Ogre/Page"); + wq->addRequestHandler(mWorkQueueChannel, this); + wq->addResponseHandler(mWorkQueueChannel, this); + touch(); + } + //--------------------------------------------------------------------- + Page::~Page() + { + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + wq->removeRequestHandler(mWorkQueueChannel, this); + wq->removeResponseHandler(mWorkQueueChannel, this); + + destroyAllContentCollections(); + if (mDebugNode) + { + // destroy while we have the chance + SceneNode::ObjectIterator it = mDebugNode->getAttachedObjectIterator(); + while(it.hasMoreElements()) + mParent->getSceneManager()->destroyMovableObject(it.getNext()); + mDebugNode->removeAndDestroyAllChildren(); + mParent->getSceneManager()->destroySceneNode(mDebugNode); + + mDebugNode = 0; + } + } + //--------------------------------------------------------------------- + void Page::destroyAllContentCollections() + { + for (ContentCollectionList::iterator i = mContentCollections.begin(); + i != mContentCollections.end(); ++i) + { + delete *i; + } + mContentCollections.clear(); + } + //--------------------------------------------------------------------- + PageManager* Page::getManager() const + { + return mParent->getManager(); + } + //--------------------------------------------------------------------- + void Page::touch() + { + mFrameLastHeld = Root::getSingleton().getNextFrameNumber(); + } + //--------------------------------------------------------------------- + bool Page::isHeld() const + { + unsigned long nextFrame = Root::getSingleton().getNextFrameNumber(); + unsigned long dist; + if (nextFrame < mFrameLastHeld) + { + // we must have wrapped around + dist = mFrameLastHeld + (std::numeric_limits::max() - mFrameLastHeld); + } + else + dist = nextFrame - mFrameLastHeld; + + // 5-frame tolerance + return dist <= 5; + } + //--------------------------------------------------------------------- + bool Page::prepareImpl(StreamSerialiser& stream, PageData* dataToPopulate) + { + + // Now do the real loading + if (!stream.readChunkBegin(CHUNK_ID, CHUNK_VERSION, "Page")) + return false; + + // pageID check (we should know the ID we're expecting) + uint32 storedID; + stream.read(&storedID); + if (mID != storedID) + { + LogManager::getSingleton().stream() << "Error: Tried to populate Page ID " << mID + << " with data corresponding to page ID " << storedID; + stream.undoReadChunk(CHUNK_ID); + return false; + } + + PageManager* mgr = getManager(); + + while(stream.peekNextChunkID() == CHUNK_CONTENTCOLLECTION_DECLARATION_ID) + { + const StreamSerialiser::Chunk* collChunk = stream.readChunkBegin(); + String factoryName; + stream.read(&factoryName); + stream.readChunkEnd(CHUNK_CONTENTCOLLECTION_DECLARATION_ID); + // Supported type? + PageContentCollectionFactory* collFact = mgr->getContentCollectionFactory(factoryName); + if (collFact) + { + PageContentCollection* collInst = collFact->createInstance(); + if (collInst->prepare(stream)) // read type-specific data + { + dataToPopulate->collectionsToAdd.push_back(collInst); + } + else + { + LogManager::getSingleton().stream() << "Error preparing PageContentCollection type: " + << factoryName << " in " << *this; + collFact->destroyInstance(collInst); + } + } + else + { + LogManager::getSingleton().stream() << "Unsupported PageContentCollection type: " + << factoryName << " in " << *this; + // skip + stream.readChunkEnd(collChunk->id); + } + + } + + + mModified = false; + + return true; + } + //--------------------------------------------------------------------- + void Page::load(bool synchronous) + { + if (!mDeferredProcessInProgress) + { + destroyAllContentCollections(); + PageRequest req(this); + mDeferredProcessInProgress = true; + Root::getSingleton().getWorkQueue()->addRequest(mWorkQueueChannel, WORKQUEUE_PREPARE_REQUEST, + Any(req), 0, synchronous); + } + + } + //--------------------------------------------------------------------- + void Page::unload() + { + destroyAllContentCollections(); + } + //--------------------------------------------------------------------- + bool Page::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + PageRequest preq = any_cast(req->getData()); + // only deal with own requests + // we do this because if we delete a page we want any pending tasks to be discarded + if (preq.srcPage != this) + return false; + else + return RequestHandler::canHandleRequest(req, srcQ); + + } + //--------------------------------------------------------------------- + bool Page::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + PageRequest preq = any_cast(res->getRequest()->getData()); + // only deal with own requests + // we do this because if we delete a page we want any pending tasks to be discarded + if (preq.srcPage != this) + return false; + else + return true; + + } + //--------------------------------------------------------------------- + WorkQueue::Response* Page::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + // Background thread (maybe) + + PageRequest preq = any_cast(req->getData()); + // only deal with own requests; we shouldn't ever get here though + if (preq.srcPage != this) + return 0; + + PageResponse res; + res.pageData = OGRE_NEW PageData(); + WorkQueue::Response* response = 0; + try + { + prepareImpl(res.pageData); + response = OGRE_NEW WorkQueue::Response(req, true, Any(res)); + } + catch (Exception& e) + { + // oops + response = OGRE_NEW WorkQueue::Response(req, false, Any(res), + e.getFullDescription()); + } + + return response; + } + //--------------------------------------------------------------------- + void Page::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + // Main thread + PageResponse pres = any_cast(res->getData()); + PageRequest preq = any_cast(res->getRequest()->getData()); + + // only deal with own requests + if (preq.srcPage!= this) + return; + + // final loading behaviour + if (res->succeeded()) + { + std::swap(mContentCollections, pres.pageData->collectionsToAdd); + loadImpl(); + } + + OGRE_DELETE pres.pageData; + + mDeferredProcessInProgress = false; + + } + //--------------------------------------------------------------------- + bool Page::prepareImpl(PageData* dataToPopulate) + { + // Procedural preparation + if (mParent->_prepareProceduralPage(this)) + return true; + else + { + // Background loading + String filename = generateFilename(); + + DataStreamPtr stream = Root::getSingleton().openFileStream(filename, + getManager()->getPageResourceGroup()); + StreamSerialiser ser(stream); + return prepareImpl(ser, dataToPopulate); + } + + + } + //--------------------------------------------------------------------- + void Page::loadImpl() + { + mParent->_loadProceduralPage(this); + + for (ContentCollectionList::iterator i = mContentCollections.begin(); + i != mContentCollections.end(); ++i) + { + (*i)->load(); + } + } + //--------------------------------------------------------------------- + void Page::save() + { + String filename = generateFilename(); + save(filename); + } + //--------------------------------------------------------------------- + void Page::save(const String& filename) + { + DataStreamPtr stream = Root::getSingleton().createFileStream(filename, + getManager()->getPageResourceGroup(), true); + StreamSerialiser ser(stream); + save(ser); + } + //--------------------------------------------------------------------- + void Page::save(StreamSerialiser& stream) + { + stream.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); + + // page id + stream.write(&mID); + + // content collections + for (ContentCollectionList::iterator i = mContentCollections.begin(); + i != mContentCollections.end(); ++i) + { + // declaration + stream.writeChunkBegin(CHUNK_CONTENTCOLLECTION_DECLARATION_ID); + stream.write(&(*i)->getType()); + stream.writeChunkEnd(CHUNK_CONTENTCOLLECTION_DECLARATION_ID); + // data + (*i)->save(stream); + } + + stream.writeChunkEnd(CHUNK_ID); + + mModified = false; + } + //--------------------------------------------------------------------- + void Page::frameStart(Real timeSinceLastFrame) + { + updateDebugDisplay(); + + // content collections + for (ContentCollectionList::iterator i = mContentCollections.begin(); + i != mContentCollections.end(); ++i) + { + (*i)->frameStart(timeSinceLastFrame); + } + + + } + //--------------------------------------------------------------------- + void Page::frameEnd(Real timeElapsed) + { + // content collections + for (ContentCollectionList::iterator i = mContentCollections.begin(); + i != mContentCollections.end(); ++i) + { + (*i)->frameEnd(timeElapsed); + } + + } + //--------------------------------------------------------------------- + void Page::notifyCamera(Camera* cam) + { + // content collections + for (ContentCollectionList::iterator i = mContentCollections.begin(); + i != mContentCollections.end(); ++i) + { + (*i)->notifyCamera(cam); + } + + } + //--------------------------------------------------------------------- + void Page::updateDebugDisplay() + { + uint8 dbglvl = getManager()->getDebugDisplayLevel(); + if (dbglvl > 0) + { + // update debug display + if (!mDebugNode) + { + mDebugNode = mParent->getSceneManager()->getRootSceneNode()->createChildSceneNode(); + } + mParent->getStrategy()->updateDebugDisplay(this, mDebugNode); + + mDebugNode->setVisible(true); + } + else if (mDebugNode) + { + mDebugNode->setVisible(false); + } + + } + //--------------------------------------------------------------------- + PageContentCollection* Page::createContentCollection(const String& typeName) + { + PageContentCollection* coll = getManager()->createContentCollection(typeName); + coll->_notifyAttached(this); + mContentCollections.push_back(coll); + return coll; + } + //--------------------------------------------------------------------- + void Page::destroyContentCollection(PageContentCollection* coll) + { + ContentCollectionList::iterator i = std::find( + mContentCollections.begin(), mContentCollections.end(), coll); + if (i != mContentCollections.end()) + { + mContentCollections.erase(i); + } + getManager()->destroyContentCollection(coll); + } + //--------------------------------------------------------------------- + size_t Page::getContentCollectionCount() const + { + return mContentCollections.size(); + } + //--------------------------------------------------------------------- + PageContentCollection* Page::getContentCollection(size_t index) + { + assert(index < mContentCollections.size()); + + return mContentCollections[index]; + } + //--------------------------------------------------------------------- + const Page::ContentCollectionList& Page::getContentCollectionList() const + { + return mContentCollections; + } + //--------------------------------------------------------------------- + SceneManager* Page::getSceneManager() const + { + return mParent->getSceneManager(); + } + //--------------------------------------------------------------------- + std::ostream& operator <<( std::ostream& o, const Page& p ) + { + o << "Page(ID:" << p.getID() << ", section:" << p.getParentSection()->getName() + << ", world:" << p.getParentSection()->getWorld()->getName() << ")"; + return o; + } + //--------------------------------------------------------------------- + String Page::generateFilename() const + { + StringStream str; + if (mParent) + str << mParent->getWorld()->getName() << "_" << mParent->getName(); + + str << std::setw(8) << std::setfill('0') << std::hex << mID << ".page"; #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS // For the iOS we need to prefix the file name with the path to the Caches folder String cacheStr(Ogre::macCachePath() + str.str()); return cacheStr; #else - return str.str(); + return str.str(); #endif - } + } diff --git a/Components/Paging/src/OgrePageContent.cpp b/Components/Paging/src/OgrePageContent.cpp index d0dfdc87c33..1aee21d84c7 100644 --- a/Components/Paging/src/OgrePageContent.cpp +++ b/Components/Paging/src/OgrePageContent.cpp @@ -31,37 +31,37 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - PageContent::PageContent(PageContentFactory* creator) - : mCreator(creator), mParent(0) - { + //--------------------------------------------------------------------- + PageContent::PageContent(PageContentFactory* creator) + : mCreator(creator), mParent(0) + { - } - //--------------------------------------------------------------------- - PageContent::~PageContent() - { - // don't call destroy(), we're not the final subclass - } - //--------------------------------------------------------------------- - PageManager* PageContent::getManager() const - { - return mParent->getManager(); - } - //--------------------------------------------------------------------- - SceneManager* PageContent::getSceneManager() const - { - return mParent->getSceneManager(); - } - //--------------------------------------------------------------------- - const String& PageContent::getType() const - { - return mCreator->getName(); - } - //--------------------------------------------------------------------- - void PageContent::_notifyAttached(PageContentCollection* parent) - { - mParent = parent; - } + } + //--------------------------------------------------------------------- + PageContent::~PageContent() + { + // don't call destroy(), we're not the final subclass + } + //--------------------------------------------------------------------- + PageManager* PageContent::getManager() const + { + return mParent->getManager(); + } + //--------------------------------------------------------------------- + SceneManager* PageContent::getSceneManager() const + { + return mParent->getSceneManager(); + } + //--------------------------------------------------------------------- + const String& PageContent::getType() const + { + return mCreator->getName(); + } + //--------------------------------------------------------------------- + void PageContent::_notifyAttached(PageContentCollection* parent) + { + mParent = parent; + } } diff --git a/Components/Paging/src/OgrePageContentCollection.cpp b/Components/Paging/src/OgrePageContentCollection.cpp index 7ed82dc1d00..95981630f9a 100644 --- a/Components/Paging/src/OgrePageContentCollection.cpp +++ b/Components/Paging/src/OgrePageContentCollection.cpp @@ -32,40 +32,40 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - const uint32 PageContentCollection::CHUNK_ID = StreamSerialiser::makeIdentifier("PGCC"); - const uint16 PageContentCollection::CHUNK_VERSION = 1; - //--------------------------------------------------------------------- - PageContentCollection::PageContentCollection(PageContentCollectionFactory* creator) - : mCreator(creator), mParent(0) - { + //--------------------------------------------------------------------- + const uint32 PageContentCollection::CHUNK_ID = StreamSerialiser::makeIdentifier("PGCC"); + const uint16 PageContentCollection::CHUNK_VERSION = 1; + //--------------------------------------------------------------------- + PageContentCollection::PageContentCollection(PageContentCollectionFactory* creator) + : mCreator(creator), mParent(0) + { - } - //--------------------------------------------------------------------- - PageContentCollection::~PageContentCollection() - { - // don't call destroy(), we're not the final subclass - } - //--------------------------------------------------------------------- - PageManager* PageContentCollection::getManager() const - { - return mParent->getManager(); - } - //--------------------------------------------------------------------- - const String& PageContentCollection::getType() const - { - return mCreator->getName(); - } - //--------------------------------------------------------------------- - void PageContentCollection::_notifyAttached(Page* parent) - { - mParent = parent; - } - //--------------------------------------------------------------------- - SceneManager* PageContentCollection::getSceneManager() const - { - return mParent->getSceneManager(); - } + } + //--------------------------------------------------------------------- + PageContentCollection::~PageContentCollection() + { + // don't call destroy(), we're not the final subclass + } + //--------------------------------------------------------------------- + PageManager* PageContentCollection::getManager() const + { + return mParent->getManager(); + } + //--------------------------------------------------------------------- + const String& PageContentCollection::getType() const + { + return mCreator->getName(); + } + //--------------------------------------------------------------------- + void PageContentCollection::_notifyAttached(Page* parent) + { + mParent = parent; + } + //--------------------------------------------------------------------- + SceneManager* PageContentCollection::getSceneManager() const + { + return mParent->getSceneManager(); + } } diff --git a/Components/Paging/src/OgrePageManager.cpp b/Components/Paging/src/OgrePageManager.cpp index b581636f971..740f52d2d25 100644 --- a/Components/Paging/src/OgrePageManager.cpp +++ b/Components/Paging/src/OgrePageManager.cpp @@ -41,482 +41,482 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - PageManager::PageManager() - : mWorldNameGenerator("World") - , mPageProvider(0) - , mPageResourceGroup(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) - , mDebugDisplayLvl(0) - , mPagingEnabled(true) - , mGrid2DPageStrategy(0) - , mGrid3DPageStrategy(0) - , mSimpleCollectionFactory(0) - { - - mEventRouter.pManager = this; - mEventRouter.pWorldMap = &mWorlds; - mEventRouter.pCameraList = &mCameraList; - - Root::getSingleton().addFrameListener(&mEventRouter); - - createStandardStrategies(); - createStandardContentFactories(); - - } - //--------------------------------------------------------------------- - PageManager::~PageManager() - { - Root::getSingleton().removeFrameListener(&mEventRouter); - - OGRE_DELETE mGrid3DPageStrategy; - OGRE_DELETE mGrid2DPageStrategy; - OGRE_DELETE mSimpleCollectionFactory; - } - //--------------------------------------------------------------------- - void PageManager::createStandardStrategies() - { - mGrid2DPageStrategy = OGRE_NEW Grid2DPageStrategy(this); - addStrategy(mGrid2DPageStrategy); - - mGrid3DPageStrategy = OGRE_NEW Grid3DPageStrategy(this); - addStrategy(mGrid3DPageStrategy); - } - //--------------------------------------------------------------------- - void PageManager::createStandardContentFactories() - { - // collections - mSimpleCollectionFactory = OGRE_NEW SimplePageContentCollectionFactory(); - addContentCollectionFactory(mSimpleCollectionFactory); - - } - //--------------------------------------------------------------------- - PagedWorld* PageManager::createWorld(const String& name) - { - String theName = name; - if (theName.empty()) - { - do - { - theName = mWorldNameGenerator.generate(); - } while (mWorlds.find(theName) != mWorlds.end()); - } - else if(mWorlds.find(theName) != mWorlds.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "World named '" + theName + "' already exists!", - "PageManager::createWorld"); - } - - PagedWorld* ret = OGRE_NEW PagedWorld(theName, this); - mWorlds[theName] = ret; - - return ret; - } - //--------------------------------------------------------------------- - void PageManager::destroyWorld(const String& name) - { - WorldMap::iterator i = mWorlds.find(name); - if (i != mWorlds.end()) - { - OGRE_DELETE i->second; - mWorlds.erase(i); - } - - } - //--------------------------------------------------------------------- - void PageManager::destroyWorld(PagedWorld* world) - { - destroyWorld(world->getName()); - } - //--------------------------------------------------------------------- - PagedWorld* PageManager::loadWorld(const String& filename, const String& name) - { - PagedWorld* ret = createWorld(name); - - StreamSerialiser* ser = _readWorldStream(filename); - ret->load(*ser); - OGRE_DELETE ser; - - return ret; - - - } - //--------------------------------------------------------------------- - PagedWorld* PageManager::loadWorld(const DataStreamPtr& stream, const String& name) - { - PagedWorld* ret = createWorld(name); - - ret->load(stream); - - return ret; - } - //--------------------------------------------------------------------- - void PageManager::saveWorld(PagedWorld* world, const String& filename) - { - world->save(filename); - } - //--------------------------------------------------------------------- - void PageManager::saveWorld(PagedWorld* world, const DataStreamPtr& stream) - { - world->save(stream); - } - //--------------------------------------------------------------------- - PagedWorld* PageManager::getWorld(const String& name) - { - WorldMap::iterator i = mWorlds.find(name); - if (i != mWorlds.end()) - return i->second; - else - return 0; - } - //--------------------------------------------------------------------- - void PageManager::addStrategy(PageStrategy* strategy) - { - // note - deliberately allowing overriding - mStrategies[strategy->getName()] = strategy; - } - //--------------------------------------------------------------------- - void PageManager::removeStrategy(PageStrategy* strategy) - { - StrategyMap::iterator i = mStrategies.find(strategy->getName()); - if (i != mStrategies.end() && i->second == strategy) - { - mStrategies.erase(i); - } - } - //--------------------------------------------------------------------- - PageStrategy* PageManager::getStrategy(const String& name) - { - StrategyMap::iterator i = mStrategies.find(name); - if (i != mStrategies.end()) - return i->second; - else - return 0; - - } - //--------------------------------------------------------------------- - const PageManager::StrategyMap& PageManager::getStrategies() const - { - return mStrategies; - } - //--------------------------------------------------------------------- - void PageManager::addContentCollectionFactory(PageContentCollectionFactory* f) - { - // note - deliberately allowing overriding - mContentCollectionFactories[f->getName()] = f; - } - //--------------------------------------------------------------------- - void PageManager::removeContentCollectionFactory(PageContentCollectionFactory* f) - { - ContentCollectionFactoryMap::iterator i = mContentCollectionFactories.find(f->getName()); - if (i != mContentCollectionFactories.end() && i->second == f) - { - mContentCollectionFactories.erase(i); - } - } - //--------------------------------------------------------------------- - PageContentCollectionFactory* PageManager::getContentCollectionFactory(const String& name) - { - ContentCollectionFactoryMap::iterator i = mContentCollectionFactories.find(name); - if (i != mContentCollectionFactories.end()) - return i->second; - else - return 0; - - } - //--------------------------------------------------------------------- - const PageManager::ContentCollectionFactoryMap& PageManager::getContentCollectionFactories() const - { - return mContentCollectionFactories; - } - //--------------------------------------------------------------------- - PageContentCollection* PageManager::createContentCollection(const String& typeName) - { - PageContentCollectionFactory* fact = getContentCollectionFactory(typeName); - if (!fact) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - typeName + " is not the name of a valid PageContentCollectionFactory", - "PageManager::createContentCollection"); - - return fact->createInstance(); - } - //--------------------------------------------------------------------- - void PageManager::destroyContentCollection(PageContentCollection* coll) - { - PageContentCollectionFactory* fact = getContentCollectionFactory(coll->getType()); - if (fact) - fact->destroyInstance(coll); - else - OGRE_DELETE coll; // normally a safe fallback - } - //--------------------------------------------------------------------- - void PageManager::addContentFactory(PageContentFactory* f) - { - // note - deliberately allowing overriding - mContentFactories[f->getName()] = f; - } - //--------------------------------------------------------------------- - void PageManager::removeContentFactory(PageContentFactory* f) - { - ContentFactoryMap::iterator i = mContentFactories.find(f->getName()); - if (i != mContentFactories.end() && i->second == f) - { - mContentFactories.erase(i); - } - } - //--------------------------------------------------------------------- - PageContentFactory* PageManager::getContentFactory(const String& name) - { - ContentFactoryMap::iterator i = mContentFactories.find(name); - if (i != mContentFactories.end()) - return i->second; - else - return 0; - - } - //--------------------------------------------------------------------- - const PageManager::ContentFactoryMap& PageManager::getContentFactories() const - { - return mContentFactories; - } - //--------------------------------------------------------------------- - PageContent* PageManager::createContent(const String& typeName) - { - PageContentFactory* fact = getContentFactory(typeName); - if (!fact) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - typeName + " is not the name of a valid PageContentFactory", - "PageManager::createContent"); - - return fact->createInstance(); - } - //--------------------------------------------------------------------- - void PageManager::destroyContent(PageContent* c) - { - PageContentFactory* fact = getContentFactory(c->getType()); - if (fact) - fact->destroyInstance(c); - else - OGRE_DELETE c; // normally a safe fallback - } - //--------------------------------------------------------------------- - void PageManager::addWorldSectionFactory(PagedWorldSectionFactory* f) - { - // note - deliberately allowing overriding - mWorldSectionFactories[f->getName()] = f; - } - //--------------------------------------------------------------------- - void PageManager::removeWorldSectionFactory(PagedWorldSectionFactory* f) - { - WorldSectionFactoryMap::iterator i = mWorldSectionFactories.find(f->getName()); - if (i != mWorldSectionFactories.end() && i->second == f) - { - mWorldSectionFactories.erase(i); - } - } - //--------------------------------------------------------------------- - PagedWorldSectionFactory* PageManager::getWorldSectionFactory(const String& name) - { - WorldSectionFactoryMap::iterator i = mWorldSectionFactories.find(name); - if (i != mWorldSectionFactories.end()) - return i->second; - else - return 0; - - } - //--------------------------------------------------------------------- - const PageManager::WorldSectionFactoryMap& PageManager::getWorldSectionFactories() const - { - return mWorldSectionFactories; - } - //--------------------------------------------------------------------- - PagedWorldSection* PageManager::createWorldSection(const String& typeName, - const String& name, PagedWorld* parent, SceneManager* sm) - { - PagedWorldSectionFactory* fact = getWorldSectionFactory(typeName); - if (!fact) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - typeName + " is not the name of a valid PagedWorldSectionFactory", - "PageManager::createWorldSection"); - - return fact->createInstance(name, parent, sm); - } - //--------------------------------------------------------------------- - void PageManager::destroyWorldSection(PagedWorldSection* coll) - { - PagedWorldSectionFactory* fact = getWorldSectionFactory(coll->getType()); - if (fact) - fact->destroyInstance(coll); - else - OGRE_DELETE coll; // normally a safe fallback - } - //--------------------------------------------------------------------- - StreamSerialiser* PageManager::_readPageStream(PageID pageID, PagedWorldSection* section) - { - StreamSerialiser* ser = 0; - if (mPageProvider) - ser = mPageProvider->readPageStream(pageID, section); - if (!ser) - { - // use default implementation - StringStream nameStr; - nameStr << section->getWorld()->getName() << "_" << section->getName() - << "_" << pageID << ".page"; - DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(nameStr.str()); - - ser = OGRE_NEW StreamSerialiser(stream); - - } - - return ser; - - } - //--------------------------------------------------------------------- - StreamSerialiser* PageManager::_writePageStream(PageID pageID, PagedWorldSection* section) - { - StreamSerialiser* ser = 0; - if (mPageProvider) - ser = mPageProvider->writePageStream(pageID, section); - if (!ser) - { - // use default implementation - StringStream nameStr; - nameStr << section->getWorld()->getName() << "_" << section->getName() - << "_" << pageID << ".page"; - - // create file, overwrite if necessary - DataStreamPtr stream = ResourceGroupManager::getSingleton().createResource( - nameStr.str(), mPageResourceGroup, true); - - ser = OGRE_NEW StreamSerialiser(stream); - - } - - return ser; - - } - //--------------------------------------------------------------------- - StreamSerialiser* PageManager::_readWorldStream(const String& filename) - { - StreamSerialiser* ser = 0; - if (mPageProvider) - ser = mPageProvider->readWorldStream(filename); - if (!ser) - { - // use default implementation - DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource( - filename); - - ser = OGRE_NEW StreamSerialiser(stream); - - } - - return ser; - - } - //--------------------------------------------------------------------- - StreamSerialiser* PageManager::_writeWorldStream(const String& filename) - { - StreamSerialiser* ser = 0; - if (mPageProvider) - ser = mPageProvider->writeWorldStream(filename); - if (!ser) - { - // use default implementation - // create file, overwrite if necessary - DataStreamPtr stream = ResourceGroupManager::getSingleton().createResource( - filename, mPageResourceGroup, true); - - ser = OGRE_NEW StreamSerialiser(stream); - - } - - return ser; - - } - //--------------------------------------------------------------------- - bool PageManager::_prepareProceduralPage(Page* page, PagedWorldSection* section) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->prepareProceduralPage(page, section); - - return generated; - } - //--------------------------------------------------------------------- - bool PageManager::_loadProceduralPage(Page* page, PagedWorldSection* section) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->loadProceduralPage(page, section); - - return generated; - } - //--------------------------------------------------------------------- - bool PageManager::_unprepareProceduralPage(Page* page, PagedWorldSection* section) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->unprepareProceduralPage(page, section); - - return generated; - } - //--------------------------------------------------------------------- - bool PageManager::_unloadProceduralPage(Page* page, PagedWorldSection* section) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->unloadProceduralPage(page, section); - - return generated; - } - //--------------------------------------------------------------------- - void PageManager::addCamera(Camera* c) - { - if (std::find(mCameraList.begin(), mCameraList.end(), c) == mCameraList.end()) - { - mCameraList.push_back(c); - c->addListener(&mEventRouter); - } - } - //--------------------------------------------------------------------- - void PageManager::removeCamera(Camera* c) - { - CameraList::iterator i = std::find(mCameraList.begin(), mCameraList.end(), c); - if (i != mCameraList.end()) - { - c->removeListener(&mEventRouter); - mCameraList.erase(i); - } - } - //--------------------------------------------------------------------- - bool PageManager::hasCamera(Camera* c) const - { - return std::find(mCameraList.begin(), mCameraList.end(), c) != mCameraList.end(); - } - //--------------------------------------------------------------------- - const PageManager::CameraList& PageManager::getCameraList() const - { - return mCameraList; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - void PageManager::EventRouter::cameraPreRenderScene(Camera* cam) - { - } - //--------------------------------------------------------------------- - void PageManager::EventRouter::cameraDestroyed(Camera* cam) - { - pManager->removeCamera(cam); - } - //--------------------------------------------------------------------- - bool PageManager::EventRouter::frameStarted(const FrameEvent& evt) - { + //--------------------------------------------------------------------- + PageManager::PageManager() + : mWorldNameGenerator("World") + , mPageProvider(0) + , mPageResourceGroup(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) + , mDebugDisplayLvl(0) + , mPagingEnabled(true) + , mGrid2DPageStrategy(0) + , mGrid3DPageStrategy(0) + , mSimpleCollectionFactory(0) + { + + mEventRouter.pManager = this; + mEventRouter.pWorldMap = &mWorlds; + mEventRouter.pCameraList = &mCameraList; + + Root::getSingleton().addFrameListener(&mEventRouter); + + createStandardStrategies(); + createStandardContentFactories(); + + } + //--------------------------------------------------------------------- + PageManager::~PageManager() + { + Root::getSingleton().removeFrameListener(&mEventRouter); + + OGRE_DELETE mGrid3DPageStrategy; + OGRE_DELETE mGrid2DPageStrategy; + OGRE_DELETE mSimpleCollectionFactory; + } + //--------------------------------------------------------------------- + void PageManager::createStandardStrategies() + { + mGrid2DPageStrategy = OGRE_NEW Grid2DPageStrategy(this); + addStrategy(mGrid2DPageStrategy); + + mGrid3DPageStrategy = OGRE_NEW Grid3DPageStrategy(this); + addStrategy(mGrid3DPageStrategy); + } + //--------------------------------------------------------------------- + void PageManager::createStandardContentFactories() + { + // collections + mSimpleCollectionFactory = OGRE_NEW SimplePageContentCollectionFactory(); + addContentCollectionFactory(mSimpleCollectionFactory); + + } + //--------------------------------------------------------------------- + PagedWorld* PageManager::createWorld(const String& name) + { + String theName = name; + if (theName.empty()) + { + do + { + theName = mWorldNameGenerator.generate(); + } while (mWorlds.find(theName) != mWorlds.end()); + } + else if(mWorlds.find(theName) != mWorlds.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "World named '" + theName + "' already exists!", + "PageManager::createWorld"); + } + + PagedWorld* ret = OGRE_NEW PagedWorld(theName, this); + mWorlds[theName] = ret; + + return ret; + } + //--------------------------------------------------------------------- + void PageManager::destroyWorld(const String& name) + { + WorldMap::iterator i = mWorlds.find(name); + if (i != mWorlds.end()) + { + OGRE_DELETE i->second; + mWorlds.erase(i); + } + + } + //--------------------------------------------------------------------- + void PageManager::destroyWorld(PagedWorld* world) + { + destroyWorld(world->getName()); + } + //--------------------------------------------------------------------- + PagedWorld* PageManager::loadWorld(const String& filename, const String& name) + { + PagedWorld* ret = createWorld(name); + + StreamSerialiser* ser = _readWorldStream(filename); + ret->load(*ser); + OGRE_DELETE ser; + + return ret; + + + } + //--------------------------------------------------------------------- + PagedWorld* PageManager::loadWorld(const DataStreamPtr& stream, const String& name) + { + PagedWorld* ret = createWorld(name); + + ret->load(stream); + + return ret; + } + //--------------------------------------------------------------------- + void PageManager::saveWorld(PagedWorld* world, const String& filename) + { + world->save(filename); + } + //--------------------------------------------------------------------- + void PageManager::saveWorld(PagedWorld* world, const DataStreamPtr& stream) + { + world->save(stream); + } + //--------------------------------------------------------------------- + PagedWorld* PageManager::getWorld(const String& name) + { + WorldMap::iterator i = mWorlds.find(name); + if (i != mWorlds.end()) + return i->second; + else + return 0; + } + //--------------------------------------------------------------------- + void PageManager::addStrategy(PageStrategy* strategy) + { + // note - deliberately allowing overriding + mStrategies[strategy->getName()] = strategy; + } + //--------------------------------------------------------------------- + void PageManager::removeStrategy(PageStrategy* strategy) + { + StrategyMap::iterator i = mStrategies.find(strategy->getName()); + if (i != mStrategies.end() && i->second == strategy) + { + mStrategies.erase(i); + } + } + //--------------------------------------------------------------------- + PageStrategy* PageManager::getStrategy(const String& name) + { + StrategyMap::iterator i = mStrategies.find(name); + if (i != mStrategies.end()) + return i->second; + else + return 0; + + } + //--------------------------------------------------------------------- + const PageManager::StrategyMap& PageManager::getStrategies() const + { + return mStrategies; + } + //--------------------------------------------------------------------- + void PageManager::addContentCollectionFactory(PageContentCollectionFactory* f) + { + // note - deliberately allowing overriding + mContentCollectionFactories[f->getName()] = f; + } + //--------------------------------------------------------------------- + void PageManager::removeContentCollectionFactory(PageContentCollectionFactory* f) + { + ContentCollectionFactoryMap::iterator i = mContentCollectionFactories.find(f->getName()); + if (i != mContentCollectionFactories.end() && i->second == f) + { + mContentCollectionFactories.erase(i); + } + } + //--------------------------------------------------------------------- + PageContentCollectionFactory* PageManager::getContentCollectionFactory(const String& name) + { + ContentCollectionFactoryMap::iterator i = mContentCollectionFactories.find(name); + if (i != mContentCollectionFactories.end()) + return i->second; + else + return 0; + + } + //--------------------------------------------------------------------- + const PageManager::ContentCollectionFactoryMap& PageManager::getContentCollectionFactories() const + { + return mContentCollectionFactories; + } + //--------------------------------------------------------------------- + PageContentCollection* PageManager::createContentCollection(const String& typeName) + { + PageContentCollectionFactory* fact = getContentCollectionFactory(typeName); + if (!fact) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + typeName + " is not the name of a valid PageContentCollectionFactory", + "PageManager::createContentCollection"); + + return fact->createInstance(); + } + //--------------------------------------------------------------------- + void PageManager::destroyContentCollection(PageContentCollection* coll) + { + PageContentCollectionFactory* fact = getContentCollectionFactory(coll->getType()); + if (fact) + fact->destroyInstance(coll); + else + OGRE_DELETE coll; // normally a safe fallback + } + //--------------------------------------------------------------------- + void PageManager::addContentFactory(PageContentFactory* f) + { + // note - deliberately allowing overriding + mContentFactories[f->getName()] = f; + } + //--------------------------------------------------------------------- + void PageManager::removeContentFactory(PageContentFactory* f) + { + ContentFactoryMap::iterator i = mContentFactories.find(f->getName()); + if (i != mContentFactories.end() && i->second == f) + { + mContentFactories.erase(i); + } + } + //--------------------------------------------------------------------- + PageContentFactory* PageManager::getContentFactory(const String& name) + { + ContentFactoryMap::iterator i = mContentFactories.find(name); + if (i != mContentFactories.end()) + return i->second; + else + return 0; + + } + //--------------------------------------------------------------------- + const PageManager::ContentFactoryMap& PageManager::getContentFactories() const + { + return mContentFactories; + } + //--------------------------------------------------------------------- + PageContent* PageManager::createContent(const String& typeName) + { + PageContentFactory* fact = getContentFactory(typeName); + if (!fact) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + typeName + " is not the name of a valid PageContentFactory", + "PageManager::createContent"); + + return fact->createInstance(); + } + //--------------------------------------------------------------------- + void PageManager::destroyContent(PageContent* c) + { + PageContentFactory* fact = getContentFactory(c->getType()); + if (fact) + fact->destroyInstance(c); + else + OGRE_DELETE c; // normally a safe fallback + } + //--------------------------------------------------------------------- + void PageManager::addWorldSectionFactory(PagedWorldSectionFactory* f) + { + // note - deliberately allowing overriding + mWorldSectionFactories[f->getName()] = f; + } + //--------------------------------------------------------------------- + void PageManager::removeWorldSectionFactory(PagedWorldSectionFactory* f) + { + WorldSectionFactoryMap::iterator i = mWorldSectionFactories.find(f->getName()); + if (i != mWorldSectionFactories.end() && i->second == f) + { + mWorldSectionFactories.erase(i); + } + } + //--------------------------------------------------------------------- + PagedWorldSectionFactory* PageManager::getWorldSectionFactory(const String& name) + { + WorldSectionFactoryMap::iterator i = mWorldSectionFactories.find(name); + if (i != mWorldSectionFactories.end()) + return i->second; + else + return 0; + + } + //--------------------------------------------------------------------- + const PageManager::WorldSectionFactoryMap& PageManager::getWorldSectionFactories() const + { + return mWorldSectionFactories; + } + //--------------------------------------------------------------------- + PagedWorldSection* PageManager::createWorldSection(const String& typeName, + const String& name, PagedWorld* parent, SceneManager* sm) + { + PagedWorldSectionFactory* fact = getWorldSectionFactory(typeName); + if (!fact) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + typeName + " is not the name of a valid PagedWorldSectionFactory", + "PageManager::createWorldSection"); + + return fact->createInstance(name, parent, sm); + } + //--------------------------------------------------------------------- + void PageManager::destroyWorldSection(PagedWorldSection* coll) + { + PagedWorldSectionFactory* fact = getWorldSectionFactory(coll->getType()); + if (fact) + fact->destroyInstance(coll); + else + OGRE_DELETE coll; // normally a safe fallback + } + //--------------------------------------------------------------------- + StreamSerialiser* PageManager::_readPageStream(PageID pageID, PagedWorldSection* section) + { + StreamSerialiser* ser = 0; + if (mPageProvider) + ser = mPageProvider->readPageStream(pageID, section); + if (!ser) + { + // use default implementation + StringStream nameStr; + nameStr << section->getWorld()->getName() << "_" << section->getName() + << "_" << pageID << ".page"; + DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(nameStr.str()); + + ser = OGRE_NEW StreamSerialiser(stream); + + } + + return ser; + + } + //--------------------------------------------------------------------- + StreamSerialiser* PageManager::_writePageStream(PageID pageID, PagedWorldSection* section) + { + StreamSerialiser* ser = 0; + if (mPageProvider) + ser = mPageProvider->writePageStream(pageID, section); + if (!ser) + { + // use default implementation + StringStream nameStr; + nameStr << section->getWorld()->getName() << "_" << section->getName() + << "_" << pageID << ".page"; + + // create file, overwrite if necessary + DataStreamPtr stream = ResourceGroupManager::getSingleton().createResource( + nameStr.str(), mPageResourceGroup, true); + + ser = OGRE_NEW StreamSerialiser(stream); + + } + + return ser; + + } + //--------------------------------------------------------------------- + StreamSerialiser* PageManager::_readWorldStream(const String& filename) + { + StreamSerialiser* ser = 0; + if (mPageProvider) + ser = mPageProvider->readWorldStream(filename); + if (!ser) + { + // use default implementation + DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource( + filename); + + ser = OGRE_NEW StreamSerialiser(stream); + + } + + return ser; + + } + //--------------------------------------------------------------------- + StreamSerialiser* PageManager::_writeWorldStream(const String& filename) + { + StreamSerialiser* ser = 0; + if (mPageProvider) + ser = mPageProvider->writeWorldStream(filename); + if (!ser) + { + // use default implementation + // create file, overwrite if necessary + DataStreamPtr stream = ResourceGroupManager::getSingleton().createResource( + filename, mPageResourceGroup, true); + + ser = OGRE_NEW StreamSerialiser(stream); + + } + + return ser; + + } + //--------------------------------------------------------------------- + bool PageManager::_prepareProceduralPage(Page* page, PagedWorldSection* section) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->prepareProceduralPage(page, section); + + return generated; + } + //--------------------------------------------------------------------- + bool PageManager::_loadProceduralPage(Page* page, PagedWorldSection* section) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->loadProceduralPage(page, section); + + return generated; + } + //--------------------------------------------------------------------- + bool PageManager::_unprepareProceduralPage(Page* page, PagedWorldSection* section) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->unprepareProceduralPage(page, section); + + return generated; + } + //--------------------------------------------------------------------- + bool PageManager::_unloadProceduralPage(Page* page, PagedWorldSection* section) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->unloadProceduralPage(page, section); + + return generated; + } + //--------------------------------------------------------------------- + void PageManager::addCamera(Camera* c) + { + if (std::find(mCameraList.begin(), mCameraList.end(), c) == mCameraList.end()) + { + mCameraList.push_back(c); + c->addListener(&mEventRouter); + } + } + //--------------------------------------------------------------------- + void PageManager::removeCamera(Camera* c) + { + CameraList::iterator i = std::find(mCameraList.begin(), mCameraList.end(), c); + if (i != mCameraList.end()) + { + c->removeListener(&mEventRouter); + mCameraList.erase(i); + } + } + //--------------------------------------------------------------------- + bool PageManager::hasCamera(Camera* c) const + { + return std::find(mCameraList.begin(), mCameraList.end(), c) != mCameraList.end(); + } + //--------------------------------------------------------------------- + const PageManager::CameraList& PageManager::getCameraList() const + { + return mCameraList; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void PageManager::EventRouter::cameraPreRenderScene(Camera* cam) + { + } + //--------------------------------------------------------------------- + void PageManager::EventRouter::cameraDestroyed(Camera* cam) + { + pManager->removeCamera(cam); + } + //--------------------------------------------------------------------- + bool PageManager::EventRouter::frameStarted(const FrameEvent& evt) + { if(pWorldMap->empty()) return true; - for(WorldMap::iterator i = pWorldMap->begin(); i != pWorldMap->end(); ++i) - { + for(WorldMap::iterator i = pWorldMap->begin(); i != pWorldMap->end(); ++i) + { i->second->frameStart(evt.timeSinceLastFrame); // Notify of all active cameras // Previously we did this in cameraPreRenderScene, but that had the effect @@ -526,21 +526,21 @@ namespace Ogre { i->second->notifyCamera(*c); } - } + } - return true; - } - //--------------------------------------------------------------------- - bool PageManager::EventRouter::frameEnded(const FrameEvent& evt) - { + return true; + } + //--------------------------------------------------------------------- + bool PageManager::EventRouter::frameEnded(const FrameEvent& evt) + { if(pWorldMap->empty()) return true; - for(WorldMap::iterator i = pWorldMap->begin(); i != pWorldMap->end(); ++i) - i->second->frameEnd(evt.timeSinceLastFrame); + for(WorldMap::iterator i = pWorldMap->begin(); i != pWorldMap->end(); ++i) + i->second->frameEnd(evt.timeSinceLastFrame); - return true; - } + return true; + } diff --git a/Components/Paging/src/OgrePagedWorld.cpp b/Components/Paging/src/OgrePagedWorld.cpp index 3d4ed016425..3fc508d64a9 100644 --- a/Components/Paging/src/OgrePagedWorld.cpp +++ b/Components/Paging/src/OgrePagedWorld.cpp @@ -32,287 +32,287 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - const uint32 PagedWorld::CHUNK_ID = StreamSerialiser::makeIdentifier("PWLD"); - const uint32 PagedWorld::CHUNK_SECTIONDECLARATION_ID = StreamSerialiser::makeIdentifier("PWLS"); - const uint16 PagedWorld::CHUNK_VERSION = 1; - //--------------------------------------------------------------------- - PagedWorld::PagedWorld(const String& name, PageManager* manager) - :mName(name), mManager(manager), mPageProvider(0), mSectionNameGenerator("Section") - { - - } - //--------------------------------------------------------------------- - PagedWorld::~PagedWorld() - { - destroyAllSections(); - } - //--------------------------------------------------------------------- - void PagedWorld::load(const String& filename) - { - StreamSerialiser* ser = mManager->_readWorldStream(filename); - load(*ser); - OGRE_DELETE ser; - } - //--------------------------------------------------------------------- - void PagedWorld::load(const DataStreamPtr& stream) - { - StreamSerialiser ser(stream); - load(ser); - } - //--------------------------------------------------------------------- - bool PagedWorld::load(StreamSerialiser& ser) - { - if (!ser.readChunkBegin(CHUNK_ID, CHUNK_VERSION, "PagedWorld")) - return false; - - // Name - ser.read(&mName); - // Sections - while(ser.peekNextChunkID() == CHUNK_SECTIONDECLARATION_ID) - { - ser.readChunkBegin(); - String sectionType, sectionName; - ser.read(§ionType); - ser.read(§ionName); - ser.readChunkEnd(CHUNK_SECTIONDECLARATION_ID); - // Scene manager will be loaded - PagedWorldSection* sec = createSection(0, sectionType, sectionName); - bool sectionsOk = sec->load(ser); - if (!sectionsOk) - destroySection(sec); - } - - ser.readChunkEnd(CHUNK_ID); - - return true; - - } - //--------------------------------------------------------------------- - void PagedWorld::save(const String& filename) - { - StreamSerialiser* ser = mManager->_writeWorldStream(filename); - save(*ser); - OGRE_DELETE ser; - } - //--------------------------------------------------------------------- - void PagedWorld::save(const DataStreamPtr& stream) - { - StreamSerialiser ser(stream); - save(ser); - } - //--------------------------------------------------------------------- - void PagedWorld::save(StreamSerialiser& ser) - { - ser.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); - - // Name - ser.write(&mName); - // Sections - for (SectionMap::iterator i = mSections.begin(); i != mSections.end(); ++i) - { - PagedWorldSection* sec = i->second; - // declaration - ser.writeChunkBegin(CHUNK_SECTIONDECLARATION_ID); - ser.write(&sec->getType()); - ser.write(&sec->getName()); - ser.writeChunkEnd(CHUNK_SECTIONDECLARATION_ID); - // data - i->second->save(ser); - } - - ser.writeChunkEnd(CHUNK_ID); - } - //--------------------------------------------------------------------- - PagedWorldSection* PagedWorld::createSection(SceneManager* sceneMgr, - const String& typeName, - const String& sectionName /*= BLANKSTRING*/) - { - String theName = sectionName; - if (theName.empty()) - { - do - { - theName = mSectionNameGenerator.generate(); - } while (mSections.find(theName) != mSections.end()); - } - else if(mSections.find(theName) != mSections.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "World section named '" + theName + "' already exists!", - "PagedWorld::createSection"); - } - - PagedWorldSection* ret = 0; - if (typeName == "General") - ret = OGRE_NEW PagedWorldSection(theName, this, sceneMgr); - else - { - PagedWorldSectionFactory* fact = getManager()->getWorldSectionFactory(typeName); - if (!fact) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "World section type '" + typeName + "' does not exist!", - "PagedWorld::createSection"); - } - - ret = fact->createInstance(theName, this, sceneMgr); - - } - mSections[theName] = ret; - - return ret; - - - } - //--------------------------------------------------------------------- - PagedWorldSection* PagedWorld::createSection(const String& strategyName, SceneManager* sceneMgr, - const String& sectionName) - { - // get the strategy - PageStrategy* strategy = mManager->getStrategy(strategyName); - - return createSection(strategy, sceneMgr, sectionName); - - } - //--------------------------------------------------------------------- - PagedWorldSection* PagedWorld::createSection(PageStrategy* strategy, SceneManager* sceneMgr, - const String& sectionName) - { - PagedWorldSection* ret = createSection(sceneMgr, "General", sectionName); - ret->setStrategy(strategy); - - return ret; - } - - //--------------------------------------------------------------------- - void PagedWorld::destroySection(const String& name) - { - SectionMap::iterator i = mSections.find(name); - if (i != mSections.end()) - { - OGRE_DELETE i->second; - mSections.erase(i); - } - } - //--------------------------------------------------------------------- - void PagedWorld::destroySection(PagedWorldSection* sec) - { - destroySection(sec->getName()); - } - //--------------------------------------------------------------------- - void PagedWorld::destroyAllSections() - { - for (SectionMap::iterator i = mSections.begin(); i != mSections.end(); ++i) - OGRE_DELETE i->second; - mSections.clear(); - } - //--------------------------------------------------------------------- - PagedWorldSection* PagedWorld::getSection(const String& name) - { - SectionMap::iterator i = mSections.find(name); - if (i != mSections.end()) - return i->second; - else - return 0; - - } - //--------------------------------------------------------------------- - bool PagedWorld::_prepareProceduralPage(Page* page, PagedWorldSection* section) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->prepareProceduralPage(page, section); - if (!generated) - generated = mManager->_prepareProceduralPage(page, section); - return generated; - - } - //--------------------------------------------------------------------- - bool PagedWorld::_loadProceduralPage(Page* page, PagedWorldSection* section) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->loadProceduralPage(page, section); - if (!generated) - generated = mManager->_loadProceduralPage(page, section); - return generated; - - } - //--------------------------------------------------------------------- - bool PagedWorld::_unprepareProceduralPage(Page* page, PagedWorldSection* section) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->unprepareProceduralPage(page, section); - if (!generated) - generated = mManager->_unprepareProceduralPage(page, section); - return generated; - - } - //--------------------------------------------------------------------- - bool PagedWorld::_unloadProceduralPage(Page* page, PagedWorldSection* section) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->unloadProceduralPage(page, section); - if (!generated) - generated = mManager->_unloadProceduralPage(page, section); - return generated; - - } - //--------------------------------------------------------------------- - StreamSerialiser* PagedWorld::_readPageStream(PageID pageID, PagedWorldSection* section) - { - StreamSerialiser* ser = 0; - if (mPageProvider) - ser = mPageProvider->readPageStream(pageID, section); - if (!ser) - ser = mManager->_readPageStream(pageID, section); - return ser; - - } - //--------------------------------------------------------------------- - StreamSerialiser* PagedWorld::_writePageStream(PageID pageID, PagedWorldSection* section) - { - StreamSerialiser* ser = 0; - if (mPageProvider) - ser = mPageProvider->writePageStream(pageID, section); - if (!ser) - ser = mManager->_writePageStream(pageID, section); - return ser; - - } - //--------------------------------------------------------------------- - void PagedWorld::frameStart(Real t) - { - for (SectionMap::iterator i = mSections.begin(); i != mSections.end(); ++i) - { - i->second->frameStart(t); - } - } - //--------------------------------------------------------------------- - void PagedWorld::frameEnd(Real t) - { - for (SectionMap::iterator i = mSections.begin(); i != mSections.end(); ++i) - { - i->second->frameEnd(t); - } - } - //--------------------------------------------------------------------- - void PagedWorld::notifyCamera(Camera* cam) - { - for (SectionMap::iterator i = mSections.begin(); i != mSections.end(); ++i) - { - i->second->notifyCamera(cam); - } - } - //--------------------------------------------------------------------- - std::ostream& operator <<( std::ostream& o, const PagedWorld& p ) - { - o << "PagedWorld(" << p.getName() << ")"; - return o; - } + //--------------------------------------------------------------------- + const uint32 PagedWorld::CHUNK_ID = StreamSerialiser::makeIdentifier("PWLD"); + const uint32 PagedWorld::CHUNK_SECTIONDECLARATION_ID = StreamSerialiser::makeIdentifier("PWLS"); + const uint16 PagedWorld::CHUNK_VERSION = 1; + //--------------------------------------------------------------------- + PagedWorld::PagedWorld(const String& name, PageManager* manager) + :mName(name), mManager(manager), mPageProvider(0), mSectionNameGenerator("Section") + { + + } + //--------------------------------------------------------------------- + PagedWorld::~PagedWorld() + { + destroyAllSections(); + } + //--------------------------------------------------------------------- + void PagedWorld::load(const String& filename) + { + StreamSerialiser* ser = mManager->_readWorldStream(filename); + load(*ser); + OGRE_DELETE ser; + } + //--------------------------------------------------------------------- + void PagedWorld::load(const DataStreamPtr& stream) + { + StreamSerialiser ser(stream); + load(ser); + } + //--------------------------------------------------------------------- + bool PagedWorld::load(StreamSerialiser& ser) + { + if (!ser.readChunkBegin(CHUNK_ID, CHUNK_VERSION, "PagedWorld")) + return false; + + // Name + ser.read(&mName); + // Sections + while(ser.peekNextChunkID() == CHUNK_SECTIONDECLARATION_ID) + { + ser.readChunkBegin(); + String sectionType, sectionName; + ser.read(§ionType); + ser.read(§ionName); + ser.readChunkEnd(CHUNK_SECTIONDECLARATION_ID); + // Scene manager will be loaded + PagedWorldSection* sec = createSection(0, sectionType, sectionName); + bool sectionsOk = sec->load(ser); + if (!sectionsOk) + destroySection(sec); + } + + ser.readChunkEnd(CHUNK_ID); + + return true; + + } + //--------------------------------------------------------------------- + void PagedWorld::save(const String& filename) + { + StreamSerialiser* ser = mManager->_writeWorldStream(filename); + save(*ser); + OGRE_DELETE ser; + } + //--------------------------------------------------------------------- + void PagedWorld::save(const DataStreamPtr& stream) + { + StreamSerialiser ser(stream); + save(ser); + } + //--------------------------------------------------------------------- + void PagedWorld::save(StreamSerialiser& ser) + { + ser.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); + + // Name + ser.write(&mName); + // Sections + for (SectionMap::iterator i = mSections.begin(); i != mSections.end(); ++i) + { + PagedWorldSection* sec = i->second; + // declaration + ser.writeChunkBegin(CHUNK_SECTIONDECLARATION_ID); + ser.write(&sec->getType()); + ser.write(&sec->getName()); + ser.writeChunkEnd(CHUNK_SECTIONDECLARATION_ID); + // data + i->second->save(ser); + } + + ser.writeChunkEnd(CHUNK_ID); + } + //--------------------------------------------------------------------- + PagedWorldSection* PagedWorld::createSection(SceneManager* sceneMgr, + const String& typeName, + const String& sectionName /*= BLANKSTRING*/) + { + String theName = sectionName; + if (theName.empty()) + { + do + { + theName = mSectionNameGenerator.generate(); + } while (mSections.find(theName) != mSections.end()); + } + else if(mSections.find(theName) != mSections.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "World section named '" + theName + "' already exists!", + "PagedWorld::createSection"); + } + + PagedWorldSection* ret = 0; + if (typeName == "General") + ret = OGRE_NEW PagedWorldSection(theName, this, sceneMgr); + else + { + PagedWorldSectionFactory* fact = getManager()->getWorldSectionFactory(typeName); + if (!fact) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "World section type '" + typeName + "' does not exist!", + "PagedWorld::createSection"); + } + + ret = fact->createInstance(theName, this, sceneMgr); + + } + mSections[theName] = ret; + + return ret; + + + } + //--------------------------------------------------------------------- + PagedWorldSection* PagedWorld::createSection(const String& strategyName, SceneManager* sceneMgr, + const String& sectionName) + { + // get the strategy + PageStrategy* strategy = mManager->getStrategy(strategyName); + + return createSection(strategy, sceneMgr, sectionName); + + } + //--------------------------------------------------------------------- + PagedWorldSection* PagedWorld::createSection(PageStrategy* strategy, SceneManager* sceneMgr, + const String& sectionName) + { + PagedWorldSection* ret = createSection(sceneMgr, "General", sectionName); + ret->setStrategy(strategy); + + return ret; + } + + //--------------------------------------------------------------------- + void PagedWorld::destroySection(const String& name) + { + SectionMap::iterator i = mSections.find(name); + if (i != mSections.end()) + { + OGRE_DELETE i->second; + mSections.erase(i); + } + } + //--------------------------------------------------------------------- + void PagedWorld::destroySection(PagedWorldSection* sec) + { + destroySection(sec->getName()); + } + //--------------------------------------------------------------------- + void PagedWorld::destroyAllSections() + { + for (SectionMap::iterator i = mSections.begin(); i != mSections.end(); ++i) + OGRE_DELETE i->second; + mSections.clear(); + } + //--------------------------------------------------------------------- + PagedWorldSection* PagedWorld::getSection(const String& name) + { + SectionMap::iterator i = mSections.find(name); + if (i != mSections.end()) + return i->second; + else + return 0; + + } + //--------------------------------------------------------------------- + bool PagedWorld::_prepareProceduralPage(Page* page, PagedWorldSection* section) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->prepareProceduralPage(page, section); + if (!generated) + generated = mManager->_prepareProceduralPage(page, section); + return generated; + + } + //--------------------------------------------------------------------- + bool PagedWorld::_loadProceduralPage(Page* page, PagedWorldSection* section) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->loadProceduralPage(page, section); + if (!generated) + generated = mManager->_loadProceduralPage(page, section); + return generated; + + } + //--------------------------------------------------------------------- + bool PagedWorld::_unprepareProceduralPage(Page* page, PagedWorldSection* section) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->unprepareProceduralPage(page, section); + if (!generated) + generated = mManager->_unprepareProceduralPage(page, section); + return generated; + + } + //--------------------------------------------------------------------- + bool PagedWorld::_unloadProceduralPage(Page* page, PagedWorldSection* section) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->unloadProceduralPage(page, section); + if (!generated) + generated = mManager->_unloadProceduralPage(page, section); + return generated; + + } + //--------------------------------------------------------------------- + StreamSerialiser* PagedWorld::_readPageStream(PageID pageID, PagedWorldSection* section) + { + StreamSerialiser* ser = 0; + if (mPageProvider) + ser = mPageProvider->readPageStream(pageID, section); + if (!ser) + ser = mManager->_readPageStream(pageID, section); + return ser; + + } + //--------------------------------------------------------------------- + StreamSerialiser* PagedWorld::_writePageStream(PageID pageID, PagedWorldSection* section) + { + StreamSerialiser* ser = 0; + if (mPageProvider) + ser = mPageProvider->writePageStream(pageID, section); + if (!ser) + ser = mManager->_writePageStream(pageID, section); + return ser; + + } + //--------------------------------------------------------------------- + void PagedWorld::frameStart(Real t) + { + for (SectionMap::iterator i = mSections.begin(); i != mSections.end(); ++i) + { + i->second->frameStart(t); + } + } + //--------------------------------------------------------------------- + void PagedWorld::frameEnd(Real t) + { + for (SectionMap::iterator i = mSections.begin(); i != mSections.end(); ++i) + { + i->second->frameEnd(t); + } + } + //--------------------------------------------------------------------- + void PagedWorld::notifyCamera(Camera* cam) + { + for (SectionMap::iterator i = mSections.begin(); i != mSections.end(); ++i) + { + i->second->notifyCamera(cam); + } + } + //--------------------------------------------------------------------- + std::ostream& operator <<( std::ostream& o, const PagedWorld& p ) + { + o << "PagedWorld(" << p.getName() << ")"; + return o; + } diff --git a/Components/Paging/src/OgrePagedWorldSection.cpp b/Components/Paging/src/OgrePagedWorldSection.cpp index 62a5feda41f..c6345d154a9 100644 --- a/Components/Paging/src/OgrePagedWorldSection.cpp +++ b/Components/Paging/src/OgrePagedWorldSection.cpp @@ -36,357 +36,357 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - const uint32 PagedWorldSection::CHUNK_ID = StreamSerialiser::makeIdentifier("PWSC"); - const uint16 PagedWorldSection::CHUNK_VERSION = 1; - //--------------------------------------------------------------------- - PagedWorldSection::PagedWorldSection(const String& name, PagedWorld* parent, SceneManager* sm) - : mName(name), mParent(parent), mStrategy(0), mStrategyData(0), mPageProvider(0), mSceneMgr(sm) - { - } - //--------------------------------------------------------------------- - PagedWorldSection::~PagedWorldSection() - { - if (mStrategy) - { - mStrategy->destroyData(mStrategyData); - mStrategyData = 0; - } - - removeAllPages(); - } - //--------------------------------------------------------------------- - PageManager* PagedWorldSection::getManager() const - { - return mParent->getManager(); - } - //--------------------------------------------------------------------- - void PagedWorldSection::setBoundingBox(const AxisAlignedBox& box) - { - mAABB = box; - } - //--------------------------------------------------------------------- - const AxisAlignedBox& PagedWorldSection::getBoundingBox() const - { - return mAABB; - } - //--------------------------------------------------------------------- - void PagedWorldSection::setStrategy(PageStrategy* strat) - { - if (strat != mStrategy) - { - if (mStrategy) - { - mStrategy->destroyData(mStrategyData); - mStrategy = 0; - mStrategyData = 0; - } - - mStrategy = strat; - if (mStrategy) - mStrategyData = mStrategy->createData(); - - removeAllPages(); - } - - } - //--------------------------------------------------------------------- - void PagedWorldSection::setStrategy(const String& stratName) - { - setStrategy(getManager()->getStrategy(stratName)); - } - //--------------------------------------------------------------------- - void PagedWorldSection::setSceneManager(SceneManager* sm) - { - if (sm != mSceneMgr) - { - mSceneMgr = sm; - removeAllPages(); - } - - - } - //--------------------------------------------------------------------- - void PagedWorldSection::setSceneManager(const String& smName) - { - setSceneManager(Root::getSingleton().getSceneManager(smName)); - } - //--------------------------------------------------------------------- - bool PagedWorldSection::load(StreamSerialiser& ser) - { - if (!ser.readChunkBegin(CHUNK_ID, CHUNK_VERSION, "PagedWorldSection")) - return false; - - // Name - ser.read(&mName); - // AABB - ser.read(&mAABB); - // SceneManager type - String smType, smInstanceName; - SceneManager* sm = 0; - ser.read(&smType); - ser.read(&smInstanceName); - Root& root = Root::getSingleton(); - if (root.hasSceneManager(smInstanceName)) - sm = root.getSceneManager(smInstanceName); - else - sm = root.createSceneManager(smType, smInstanceName); - setSceneManager(sm); - // Page Strategy Name - String stratname; - ser.read(&stratname); - setStrategy(stratname); - // Page Strategy Data - bool strategyDataOk = mStrategyData->load(ser); - if (!strategyDataOk) - LogManager::getSingleton().stream() << "Error: PageStrategyData for section '" - << mName << "' was not loaded correctly, check file contents"; - - /// Load any data specific to a subtype of this class - loadSubtypeData(ser); - - ser.readChunkEnd(CHUNK_ID); - - return true; - - } - //--------------------------------------------------------------------- - void PagedWorldSection::save(StreamSerialiser& ser) - { - ser.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); - - // Name - ser.write(&mName); - // AABB - ser.write(&mAABB); - // SceneManager type & name - ser.write(&mSceneMgr->getTypeName()); - ser.write(&mSceneMgr->getName()); - // Page Strategy Name - ser.write(&mStrategy->getName()); - // Page Strategy Data - mStrategyData->save(ser); - - /// Save any data specific to a subtype of this class - saveSubtypeData(ser); - - ser.writeChunkEnd(CHUNK_ID); - - // save all pages (in separate files) - for (PageMap::iterator i = mPages.begin(); i != mPages.end(); ++i) - { - i->second->save(); - } - - - } - //--------------------------------------------------------------------- - PageID PagedWorldSection::getPageID(const Vector3& worldPos) - { - return mStrategy->getPageID(worldPos, this); - } - //--------------------------------------------------------------------- - Page* PagedWorldSection::loadOrCreatePage(const Vector3& worldPos) - { - PageID id = getPageID(worldPos); - // this will create a Page instance no matter what, even if load fails - // we force the load attempt to happen immediately (forceSynchronous) - loadPage(id, true); - return getPage(id); - } - //--------------------------------------------------------------------- - void PagedWorldSection::loadPage(PageID pageID, bool sync) - { - if (!mParent->getManager()->getPagingOperationsEnabled()) - return; - - PageMap::iterator i = mPages.find(pageID); - if (i == mPages.end()) - { - Page* page = OGRE_NEW Page(pageID, this); - // try to insert - std::pair ret = mPages.insert( - PageMap::value_type(page->getID(), page)); - - if (!ret.second) - { - // page with this ID already in map - if (ret.first->second != page) - { - // replacing a page, delete the old one - OGRE_DELETE ret.first->second; - ret.first->second = page; - } - } - page->load(sync); - } - else - i->second->touch(); - } - //--------------------------------------------------------------------- - void PagedWorldSection::unloadPage(PageID pageID, bool sync) - { - if (!mParent->getManager()->getPagingOperationsEnabled()) - return; - - PageMap::iterator i = mPages.find(pageID); - if (i != mPages.end()) - { - Page* page = i->second; - mPages.erase(i); - - page->unload(); - - OGRE_DELETE page; - - } - } - //--------------------------------------------------------------------- - void PagedWorldSection::unloadPage(Page* p, bool sync) - { - unloadPage(p->getID(), sync); - } - //--------------------------------------------------------------------- - bool PagedWorldSection::_prepareProceduralPage(Page* page) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->prepareProceduralPage(page, this); - if (!generated) - generated = mParent->_prepareProceduralPage(page, this); - return generated; - - } - //--------------------------------------------------------------------- - bool PagedWorldSection::_loadProceduralPage(Page* page) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->loadProceduralPage(page, this); - if (!generated) - generated = mParent->_loadProceduralPage(page, this); - return generated; - - } - //--------------------------------------------------------------------- - bool PagedWorldSection::_unloadProceduralPage(Page* page) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->unloadProceduralPage(page, this); - if (!generated) - generated = mParent->_unloadProceduralPage(page, this); - return generated; - - } - //--------------------------------------------------------------------- - bool PagedWorldSection::_unprepareProceduralPage(Page* page) - { - bool generated = false; - if (mPageProvider) - generated = mPageProvider->unprepareProceduralPage(page, this); - if (!generated) - generated = mParent->_unprepareProceduralPage(page, this); - return generated; - - } - //--------------------------------------------------------------------- - void PagedWorldSection::holdPage(PageID pageID) - { - PageMap::iterator i = mPages.find(pageID); - if (i != mPages.end()) - i->second->touch(); - } - //--------------------------------------------------------------------- - Page* PagedWorldSection::getPage(PageID pageID) - { - PageMap::iterator i = mPages.find(pageID); - if (i != mPages.end()) - return i->second; - else - return 0; - } - //--------------------------------------------------------------------- - void PagedWorldSection::removeAllPages() - { - if (!mParent->getManager()->getPagingOperationsEnabled()) - return; - - for (PageMap::iterator i= mPages.begin(); i != mPages.end(); ++i) - { - OGRE_DELETE i->second; - } - mPages.clear(); - - } - //--------------------------------------------------------------------- - void PagedWorldSection::frameStart(Real timeSinceLastFrame) - { - mStrategy->frameStart(timeSinceLastFrame, this); - - for (PageMap::iterator i = mPages.begin(); i != mPages.end(); ++i) - i->second->frameStart(timeSinceLastFrame); - } - //--------------------------------------------------------------------- - void PagedWorldSection::frameEnd(Real timeElapsed) - { - mStrategy->frameEnd(timeElapsed, this); - - for (PageMap::iterator i = mPages.begin(); i != mPages.end(); ) - { - // if this page wasn't used, unload - Page* p = i->second; - // pre-increment since unloading will remove it - ++i; - if (!p->isHeld()) - unloadPage(p); - else - p->frameEnd(timeElapsed); - } - - } - //--------------------------------------------------------------------- - void PagedWorldSection::notifyCamera(Camera* cam) - { - mStrategy->notifyCamera(cam, this); - - for (PageMap::iterator i = mPages.begin(); i != mPages.end(); ++i) - i->second->notifyCamera(cam); - } - //--------------------------------------------------------------------- - StreamSerialiser* PagedWorldSection::_readPageStream(PageID pageID) - { - StreamSerialiser* ser = 0; - if (mPageProvider) - ser = mPageProvider->readPageStream(pageID, this); - if (!ser) - ser = mParent->_readPageStream(pageID, this); - return ser; - - } - //--------------------------------------------------------------------- - StreamSerialiser* PagedWorldSection::_writePageStream(PageID pageID) - { - StreamSerialiser* ser = 0; - if (mPageProvider) - ser = mPageProvider->writePageStream(pageID, this); - if (!ser) - ser = mParent->_writePageStream(pageID, this); - return ser; - - } - //--------------------------------------------------------------------- - const String& PagedWorldSection::getType() - { - static const String stype("General"); - return stype; - } - //--------------------------------------------------------------------- - std::ostream& operator <<( std::ostream& o, const PagedWorldSection& p ) - { - o << "PagedWorldSection(" << p.getName() << ", world:" << p.getWorld()->getName() << ")"; - return o; - } + //--------------------------------------------------------------------- + const uint32 PagedWorldSection::CHUNK_ID = StreamSerialiser::makeIdentifier("PWSC"); + const uint16 PagedWorldSection::CHUNK_VERSION = 1; + //--------------------------------------------------------------------- + PagedWorldSection::PagedWorldSection(const String& name, PagedWorld* parent, SceneManager* sm) + : mName(name), mParent(parent), mStrategy(0), mStrategyData(0), mPageProvider(0), mSceneMgr(sm) + { + } + //--------------------------------------------------------------------- + PagedWorldSection::~PagedWorldSection() + { + if (mStrategy) + { + mStrategy->destroyData(mStrategyData); + mStrategyData = 0; + } + + removeAllPages(); + } + //--------------------------------------------------------------------- + PageManager* PagedWorldSection::getManager() const + { + return mParent->getManager(); + } + //--------------------------------------------------------------------- + void PagedWorldSection::setBoundingBox(const AxisAlignedBox& box) + { + mAABB = box; + } + //--------------------------------------------------------------------- + const AxisAlignedBox& PagedWorldSection::getBoundingBox() const + { + return mAABB; + } + //--------------------------------------------------------------------- + void PagedWorldSection::setStrategy(PageStrategy* strat) + { + if (strat != mStrategy) + { + if (mStrategy) + { + mStrategy->destroyData(mStrategyData); + mStrategy = 0; + mStrategyData = 0; + } + + mStrategy = strat; + if (mStrategy) + mStrategyData = mStrategy->createData(); + + removeAllPages(); + } + + } + //--------------------------------------------------------------------- + void PagedWorldSection::setStrategy(const String& stratName) + { + setStrategy(getManager()->getStrategy(stratName)); + } + //--------------------------------------------------------------------- + void PagedWorldSection::setSceneManager(SceneManager* sm) + { + if (sm != mSceneMgr) + { + mSceneMgr = sm; + removeAllPages(); + } + + + } + //--------------------------------------------------------------------- + void PagedWorldSection::setSceneManager(const String& smName) + { + setSceneManager(Root::getSingleton().getSceneManager(smName)); + } + //--------------------------------------------------------------------- + bool PagedWorldSection::load(StreamSerialiser& ser) + { + if (!ser.readChunkBegin(CHUNK_ID, CHUNK_VERSION, "PagedWorldSection")) + return false; + + // Name + ser.read(&mName); + // AABB + ser.read(&mAABB); + // SceneManager type + String smType, smInstanceName; + SceneManager* sm = 0; + ser.read(&smType); + ser.read(&smInstanceName); + Root& root = Root::getSingleton(); + if (root.hasSceneManager(smInstanceName)) + sm = root.getSceneManager(smInstanceName); + else + sm = root.createSceneManager(smType, smInstanceName); + setSceneManager(sm); + // Page Strategy Name + String stratname; + ser.read(&stratname); + setStrategy(stratname); + // Page Strategy Data + bool strategyDataOk = mStrategyData->load(ser); + if (!strategyDataOk) + LogManager::getSingleton().stream() << "Error: PageStrategyData for section '" + << mName << "' was not loaded correctly, check file contents"; + + /// Load any data specific to a subtype of this class + loadSubtypeData(ser); + + ser.readChunkEnd(CHUNK_ID); + + return true; + + } + //--------------------------------------------------------------------- + void PagedWorldSection::save(StreamSerialiser& ser) + { + ser.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); + + // Name + ser.write(&mName); + // AABB + ser.write(&mAABB); + // SceneManager type & name + ser.write(&mSceneMgr->getTypeName()); + ser.write(&mSceneMgr->getName()); + // Page Strategy Name + ser.write(&mStrategy->getName()); + // Page Strategy Data + mStrategyData->save(ser); + + /// Save any data specific to a subtype of this class + saveSubtypeData(ser); + + ser.writeChunkEnd(CHUNK_ID); + + // save all pages (in separate files) + for (PageMap::iterator i = mPages.begin(); i != mPages.end(); ++i) + { + i->second->save(); + } + + + } + //--------------------------------------------------------------------- + PageID PagedWorldSection::getPageID(const Vector3& worldPos) + { + return mStrategy->getPageID(worldPos, this); + } + //--------------------------------------------------------------------- + Page* PagedWorldSection::loadOrCreatePage(const Vector3& worldPos) + { + PageID id = getPageID(worldPos); + // this will create a Page instance no matter what, even if load fails + // we force the load attempt to happen immediately (forceSynchronous) + loadPage(id, true); + return getPage(id); + } + //--------------------------------------------------------------------- + void PagedWorldSection::loadPage(PageID pageID, bool sync) + { + if (!mParent->getManager()->getPagingOperationsEnabled()) + return; + + PageMap::iterator i = mPages.find(pageID); + if (i == mPages.end()) + { + Page* page = OGRE_NEW Page(pageID, this); + // try to insert + std::pair ret = mPages.insert( + PageMap::value_type(page->getID(), page)); + + if (!ret.second) + { + // page with this ID already in map + if (ret.first->second != page) + { + // replacing a page, delete the old one + OGRE_DELETE ret.first->second; + ret.first->second = page; + } + } + page->load(sync); + } + else + i->second->touch(); + } + //--------------------------------------------------------------------- + void PagedWorldSection::unloadPage(PageID pageID, bool sync) + { + if (!mParent->getManager()->getPagingOperationsEnabled()) + return; + + PageMap::iterator i = mPages.find(pageID); + if (i != mPages.end()) + { + Page* page = i->second; + mPages.erase(i); + + page->unload(); + + OGRE_DELETE page; + + } + } + //--------------------------------------------------------------------- + void PagedWorldSection::unloadPage(Page* p, bool sync) + { + unloadPage(p->getID(), sync); + } + //--------------------------------------------------------------------- + bool PagedWorldSection::_prepareProceduralPage(Page* page) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->prepareProceduralPage(page, this); + if (!generated) + generated = mParent->_prepareProceduralPage(page, this); + return generated; + + } + //--------------------------------------------------------------------- + bool PagedWorldSection::_loadProceduralPage(Page* page) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->loadProceduralPage(page, this); + if (!generated) + generated = mParent->_loadProceduralPage(page, this); + return generated; + + } + //--------------------------------------------------------------------- + bool PagedWorldSection::_unloadProceduralPage(Page* page) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->unloadProceduralPage(page, this); + if (!generated) + generated = mParent->_unloadProceduralPage(page, this); + return generated; + + } + //--------------------------------------------------------------------- + bool PagedWorldSection::_unprepareProceduralPage(Page* page) + { + bool generated = false; + if (mPageProvider) + generated = mPageProvider->unprepareProceduralPage(page, this); + if (!generated) + generated = mParent->_unprepareProceduralPage(page, this); + return generated; + + } + //--------------------------------------------------------------------- + void PagedWorldSection::holdPage(PageID pageID) + { + PageMap::iterator i = mPages.find(pageID); + if (i != mPages.end()) + i->second->touch(); + } + //--------------------------------------------------------------------- + Page* PagedWorldSection::getPage(PageID pageID) + { + PageMap::iterator i = mPages.find(pageID); + if (i != mPages.end()) + return i->second; + else + return 0; + } + //--------------------------------------------------------------------- + void PagedWorldSection::removeAllPages() + { + if (!mParent->getManager()->getPagingOperationsEnabled()) + return; + + for (PageMap::iterator i= mPages.begin(); i != mPages.end(); ++i) + { + OGRE_DELETE i->second; + } + mPages.clear(); + + } + //--------------------------------------------------------------------- + void PagedWorldSection::frameStart(Real timeSinceLastFrame) + { + mStrategy->frameStart(timeSinceLastFrame, this); + + for (PageMap::iterator i = mPages.begin(); i != mPages.end(); ++i) + i->second->frameStart(timeSinceLastFrame); + } + //--------------------------------------------------------------------- + void PagedWorldSection::frameEnd(Real timeElapsed) + { + mStrategy->frameEnd(timeElapsed, this); + + for (PageMap::iterator i = mPages.begin(); i != mPages.end(); ) + { + // if this page wasn't used, unload + Page* p = i->second; + // pre-increment since unloading will remove it + ++i; + if (!p->isHeld()) + unloadPage(p); + else + p->frameEnd(timeElapsed); + } + + } + //--------------------------------------------------------------------- + void PagedWorldSection::notifyCamera(Camera* cam) + { + mStrategy->notifyCamera(cam, this); + + for (PageMap::iterator i = mPages.begin(); i != mPages.end(); ++i) + i->second->notifyCamera(cam); + } + //--------------------------------------------------------------------- + StreamSerialiser* PagedWorldSection::_readPageStream(PageID pageID) + { + StreamSerialiser* ser = 0; + if (mPageProvider) + ser = mPageProvider->readPageStream(pageID, this); + if (!ser) + ser = mParent->_readPageStream(pageID, this); + return ser; + + } + //--------------------------------------------------------------------- + StreamSerialiser* PagedWorldSection::_writePageStream(PageID pageID) + { + StreamSerialiser* ser = 0; + if (mPageProvider) + ser = mPageProvider->writePageStream(pageID, this); + if (!ser) + ser = mParent->_writePageStream(pageID, this); + return ser; + + } + //--------------------------------------------------------------------- + const String& PagedWorldSection::getType() + { + static const String stype("General"); + return stype; + } + //--------------------------------------------------------------------- + std::ostream& operator <<( std::ostream& o, const PagedWorldSection& p ) + { + o << "PagedWorldSection(" << p.getName() << ", world:" << p.getWorld()->getName() << ")"; + return o; + } diff --git a/Components/Paging/src/OgreSimplePageContentCollection.cpp b/Components/Paging/src/OgreSimplePageContentCollection.cpp index 2102046110f..50b42dbc9e4 100644 --- a/Components/Paging/src/OgreSimplePageContentCollection.cpp +++ b/Components/Paging/src/OgreSimplePageContentCollection.cpp @@ -32,106 +32,106 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - const uint32 SimplePageContentCollection::SUBCLASS_CHUNK_ID = StreamSerialiser::makeIdentifier("SPCD"); - const uint16 SimplePageContentCollection::SUBCLASS_CHUNK_VERSION = 1; - //--------------------------------------------------------------------- - SimplePageContentCollection::SimplePageContentCollection(PageContentCollectionFactory* creator) - : PageContentCollection(creator) - { - - } - //--------------------------------------------------------------------- - SimplePageContentCollection::~SimplePageContentCollection() - { - for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) - delete *i; - mContentList.clear(); - } - //--------------------------------------------------------------------- - PageContent* SimplePageContentCollection::createContent(const String& typeName) - { - PageContent* c = getManager()->createContent(typeName); - mContentList.push_back(c); - return c; - } - //--------------------------------------------------------------------- - void SimplePageContentCollection::destroyContent(PageContent* c) - { - ContentList::iterator i = std::find(mContentList.begin(), mContentList.end(), c); - if (i != mContentList.end()) - mContentList.erase(i); - getManager()->destroyContent(c); - } - //--------------------------------------------------------------------- - void SimplePageContentCollection::save(StreamSerialiser& stream) - { - stream.writeChunkBegin(SUBCLASS_CHUNK_ID, SUBCLASS_CHUNK_VERSION); - - for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) - (*i)->save(stream); - - stream.writeChunkEnd(SUBCLASS_CHUNK_ID); - } - //--------------------------------------------------------------------- - void SimplePageContentCollection::frameStart(Real timeSinceLastFrame) - { - for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) - (*i)->frameStart(timeSinceLastFrame); - - } - //--------------------------------------------------------------------- - void SimplePageContentCollection::frameEnd(Real timeElapsed) - { - for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) - (*i)->frameEnd(timeElapsed); - } - //--------------------------------------------------------------------- - void SimplePageContentCollection::notifyCamera(Camera* cam) - { - for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) - (*i)->notifyCamera(cam); - } - //--------------------------------------------------------------------- - bool SimplePageContentCollection::prepare(StreamSerialiser& stream) - { - if (!stream.readChunkBegin(SUBCLASS_CHUNK_ID, SUBCLASS_CHUNK_VERSION, "SimplePageContentCollection")) - return false; - - bool ret = true; - for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) - ret = (*i)->prepare(stream) && ret; - - - stream.readChunkEnd(SUBCLASS_CHUNK_ID); - - return ret; - - } - //--------------------------------------------------------------------- - void SimplePageContentCollection::load() - { - for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) - (*i)->load(); - - } - //--------------------------------------------------------------------- - void SimplePageContentCollection::unload() - { - for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) - (*i)->unload(); - - } - //--------------------------------------------------------------------- - void SimplePageContentCollection::unprepare() - { - for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) - (*i)->unprepare(); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - String SimplePageContentCollectionFactory::FACTORY_NAME = "Simple"; - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + const uint32 SimplePageContentCollection::SUBCLASS_CHUNK_ID = StreamSerialiser::makeIdentifier("SPCD"); + const uint16 SimplePageContentCollection::SUBCLASS_CHUNK_VERSION = 1; + //--------------------------------------------------------------------- + SimplePageContentCollection::SimplePageContentCollection(PageContentCollectionFactory* creator) + : PageContentCollection(creator) + { + + } + //--------------------------------------------------------------------- + SimplePageContentCollection::~SimplePageContentCollection() + { + for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) + delete *i; + mContentList.clear(); + } + //--------------------------------------------------------------------- + PageContent* SimplePageContentCollection::createContent(const String& typeName) + { + PageContent* c = getManager()->createContent(typeName); + mContentList.push_back(c); + return c; + } + //--------------------------------------------------------------------- + void SimplePageContentCollection::destroyContent(PageContent* c) + { + ContentList::iterator i = std::find(mContentList.begin(), mContentList.end(), c); + if (i != mContentList.end()) + mContentList.erase(i); + getManager()->destroyContent(c); + } + //--------------------------------------------------------------------- + void SimplePageContentCollection::save(StreamSerialiser& stream) + { + stream.writeChunkBegin(SUBCLASS_CHUNK_ID, SUBCLASS_CHUNK_VERSION); + + for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) + (*i)->save(stream); + + stream.writeChunkEnd(SUBCLASS_CHUNK_ID); + } + //--------------------------------------------------------------------- + void SimplePageContentCollection::frameStart(Real timeSinceLastFrame) + { + for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) + (*i)->frameStart(timeSinceLastFrame); + + } + //--------------------------------------------------------------------- + void SimplePageContentCollection::frameEnd(Real timeElapsed) + { + for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) + (*i)->frameEnd(timeElapsed); + } + //--------------------------------------------------------------------- + void SimplePageContentCollection::notifyCamera(Camera* cam) + { + for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) + (*i)->notifyCamera(cam); + } + //--------------------------------------------------------------------- + bool SimplePageContentCollection::prepare(StreamSerialiser& stream) + { + if (!stream.readChunkBegin(SUBCLASS_CHUNK_ID, SUBCLASS_CHUNK_VERSION, "SimplePageContentCollection")) + return false; + + bool ret = true; + for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) + ret = (*i)->prepare(stream) && ret; + + + stream.readChunkEnd(SUBCLASS_CHUNK_ID); + + return ret; + + } + //--------------------------------------------------------------------- + void SimplePageContentCollection::load() + { + for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) + (*i)->load(); + + } + //--------------------------------------------------------------------- + void SimplePageContentCollection::unload() + { + for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) + (*i)->unload(); + + } + //--------------------------------------------------------------------- + void SimplePageContentCollection::unprepare() + { + for (ContentList::iterator i = mContentList.begin(); i != mContentList.end(); ++i) + (*i)->unprepare(); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + String SimplePageContentCollectionFactory::FACTORY_NAME = "Simple"; + //--------------------------------------------------------------------- diff --git a/Components/Property/include/OgreProperty.h b/Components/Property/include/OgreProperty.h index 238653f86e8..daf7bc5cf05 100644 --- a/Components/Property/include/OgreProperty.h +++ b/Components/Property/include/OgreProperty.h @@ -46,47 +46,47 @@ THE SOFTWARE. */ /** @file - OGRE's property system allows you to associate values of arbitrary type with - names, and have those values exposed via a self-describing interface. Unlike - Ogre::StringInterface, the values are passed as their native types without - needing conversion to or from strings; they are simply wrapped in an Ogre::Any - and casts are performed to access them. - @par - Property values are actually not stored in this system; instead the property - definitions reference getter & setter methods which provide the 'backing' for - the property. This means you can directly expose features of your classes as properties - without any duplication. - @par - There are two aspects to exposing a property on your class. One is exposing - the definition of the property (PropertyDef), which should be shared between - all instances and probably stored in a static PropertyDefMap somewhere. The second - is the instance 'wiring' which ensures that a call to set a property calls - a method on this particular instance of the class; this is formed by a number of - Property instances, contained in a PropertySet. Each Property has an explicit - binding to getter and setter instance methods. - @par - So, here's an example of setting up properties on an instance: - - @code - // Make sure the property definition is created - // propertyDefs is a variable of type PropertyDefMap, shared between instances - PropertyDefMap::iterator defi = propertyDefs.find("name"); - if (defi == propertyDefs.end()) - { - defi = propertyDefs.insert(PropertyDefMap::value_type("name", - PropertyDef("name", - "The name of the object.", PROP_STRING))).first; - } - // This has established the property definition, and its description. - // Now, we need to 'wire' a property instance for this object instance - // We assume the class is called 'Foo' and the instance is pointed to by a variable called 'inst' - // 'props' is a PropertySet, specific to the instance - props.addProperty( - OGRE_NEW Property(&(defi->second), - boost::bind(&Foo::getName, inst), - boost::bind(&Foo::setName, inst, _1))); - - @endcode + OGRE's property system allows you to associate values of arbitrary type with + names, and have those values exposed via a self-describing interface. Unlike + Ogre::StringInterface, the values are passed as their native types without + needing conversion to or from strings; they are simply wrapped in an Ogre::Any + and casts are performed to access them. + @par + Property values are actually not stored in this system; instead the property + definitions reference getter & setter methods which provide the 'backing' for + the property. This means you can directly expose features of your classes as properties + without any duplication. + @par + There are two aspects to exposing a property on your class. One is exposing + the definition of the property (PropertyDef), which should be shared between + all instances and probably stored in a static PropertyDefMap somewhere. The second + is the instance 'wiring' which ensures that a call to set a property calls + a method on this particular instance of the class; this is formed by a number of + Property instances, contained in a PropertySet. Each Property has an explicit + binding to getter and setter instance methods. + @par + So, here's an example of setting up properties on an instance: + + @code + // Make sure the property definition is created + // propertyDefs is a variable of type PropertyDefMap, shared between instances + PropertyDefMap::iterator defi = propertyDefs.find("name"); + if (defi == propertyDefs.end()) + { + defi = propertyDefs.insert(PropertyDefMap::value_type("name", + PropertyDef("name", + "The name of the object.", PROP_STRING))).first; + } + // This has established the property definition, and its description. + // Now, we need to 'wire' a property instance for this object instance + // We assume the class is called 'Foo' and the instance is pointed to by a variable called 'inst' + // 'props' is a PropertySet, specific to the instance + props.addProperty( + OGRE_NEW Property(&(defi->second), + boost::bind(&Foo::getName, inst), + boost::bind(&Foo::setName, inst, _1))); + + @endcode */ @@ -94,292 +94,292 @@ THE SOFTWARE. /** @} */ namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Property - * @{ - */ - - /// The type of a property - enum PropertyType - { - PROP_SHORT = 0, - PROP_UNSIGNED_SHORT = 1, - PROP_INT = 2, - PROP_UNSIGNED_INT = 3, - PROP_LONG = 4, - PROP_UNSIGNED_LONG = 5, - PROP_REAL = 6, - PROP_STRING = 7, - PROP_VECTOR2 = 8, - PROP_VECTOR3 = 9, - PROP_VECTOR4 = 10, - PROP_COLOUR = 11, - PROP_BOOL = 12, - PROP_QUATERNION = 13, - PROP_MATRIX3 = 14, - PROP_MATRIX4 = 15, - - PROP_UNKNOWN = 999 - }; - - /** Definition of a property of an object. - @remarks - This definition is shared between all instances of an object and therefore - has no value. Property contains values. - */ - class _OgrePropertyExport PropertyDef : public PropertyAlloc - { - public: - - /** Construct a property. - @param name The name of the property - @param desc A (potentially) long description of the property - @param pType The type of the property - */ - PropertyDef(const String& name, const String& desc, PropertyType pType) - : mName(name), mDesc(desc), mType(pType) {} - - /// Get the name of the property - const String& getName() const { return mName; } - - /// Get the description of the property - const String& getDescription() const { return mDesc; } - - /// Get the type of the property - PropertyType getType() const { return mType; } - - /// Get a string name of a property type - static const String& getTypeName(PropertyType theType); - - static PropertyType getTypeForValue(const short& val) { return PROP_SHORT; } - static PropertyType getTypeForValue(const unsigned short& val) { return PROP_UNSIGNED_SHORT; } - static PropertyType getTypeForValue(const int& val) { return PROP_INT; } - static PropertyType getTypeForValue(const unsigned int& val) { return PROP_UNSIGNED_INT; } - static PropertyType getTypeForValue(const long& val) { return PROP_LONG; } - static PropertyType getTypeForValue(const unsigned long& val) { return PROP_UNSIGNED_LONG; } - static PropertyType getTypeForValue(const Real& val) { return PROP_REAL; } - static PropertyType getTypeForValue(const String& val) { return PROP_STRING; } - static PropertyType getTypeForValue(const Vector2& val) { return PROP_VECTOR2; } - static PropertyType getTypeForValue(const Vector3& val) { return PROP_VECTOR3; } - static PropertyType getTypeForValue(const Vector4& val) { return PROP_VECTOR4; } - static PropertyType getTypeForValue(const ColourValue& val) { return PROP_COLOUR; } - static PropertyType getTypeForValue(const bool& val) { return PROP_BOOL; } - static PropertyType getTypeForValue(const Quaternion& val) { return PROP_QUATERNION; } - static PropertyType getTypeForValue(const Matrix3& val) { return PROP_MATRIX3; } - static PropertyType getTypeForValue(const Matrix4& val) { return PROP_MATRIX4; } - - protected: - // no default construction - PropertyDef() {} - - String mName; - String mDesc; - PropertyType mType; - - }; - - /// Map from property name to shared definition - typedef map::type PropertyDefMap; - - /** Base interface for an instance of a property. - */ - class _OgrePropertyExport PropertyBase : public PropertyAlloc - { - public: - /// Constructor - PropertyBase(PropertyDef* def) : mDef(def) {} - virtual ~PropertyBase() {} - - /// Get the name of the property - const String& getName() const { return mDef->getName(); } - - /// Get the description of the property - const String& getDescription() const { return mDef->getDescription(); } - - /// Get the type of the property - PropertyType getType() const { return mDef->getType(); } - - /// Return the current value as an Any - virtual Ogre::Any getValue() const = 0; - - protected: - // disallow default construction - PropertyBase() {} - PropertyDef* mDef; - - }; - - /** Property instance with passthrough calls to a given object. */ - template - class Property : public PropertyBase - { - public: - typedef T value_type; - typedef boost::function< T (void) > getter_func; - typedef boost::function< void (T) > setter_func; - - /** Construct a property which is able to directly call a given - getter and setter on a specific object instance, via functors. - */ - Property(PropertyDef* def, getter_func getter, setter_func setter) - : PropertyBase(def) - , mGetter(getter) - , mSetter(setter) - { - } - - /** Set the property value. - */ - virtual void set(T val) - { - mSetter(val); - } - - virtual T get() const - { - return mGetter(); - } - - Ogre::Any getValue() const - { - return Ogre::Any(get()); - } - - protected: - // disallow default construction - Property() {} - ~Property() {} - - getter_func mGetter; - setter_func mSetter; - }; - - /** A simple structure designed just as a holder of property values between - the instances of objects they might target. There is just enough information - here to be able to interpret the results accurately but no more. - */ - struct PropertyValue - { - PropertyType propType; - Ogre::Any val; - }; - /// Defines a transferable map of properties using wrapped value types (Ogre::Any) - typedef map::type PropertyValueMap; - - - /** Defines a complete set of properties for a single object instance. - */ - class _OgrePropertyExport PropertySet : public PropertyAlloc - { - public: - PropertySet(); - ~PropertySet(); - - /** Adds a property to this set. - @remarks - The PropertySet is responsible for deleting this object. - */ - void addProperty(PropertyBase* prop); - - /** Gets the property object for a given property name. - @remarks - Note that this property will need to be cast to a templated property - compatible with the type you will be setting. You might find the - overloaded set and get methods quicker if - you already know the type. - */ - PropertyBase* getProperty(const String& name) const; - - /** Reports whether this property set contains a named property. */ - bool hasProperty(const String& name) const; + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Property + * @{ + */ + + /// The type of a property + enum PropertyType + { + PROP_SHORT = 0, + PROP_UNSIGNED_SHORT = 1, + PROP_INT = 2, + PROP_UNSIGNED_INT = 3, + PROP_LONG = 4, + PROP_UNSIGNED_LONG = 5, + PROP_REAL = 6, + PROP_STRING = 7, + PROP_VECTOR2 = 8, + PROP_VECTOR3 = 9, + PROP_VECTOR4 = 10, + PROP_COLOUR = 11, + PROP_BOOL = 12, + PROP_QUATERNION = 13, + PROP_MATRIX3 = 14, + PROP_MATRIX4 = 15, + + PROP_UNKNOWN = 999 + }; + + /** Definition of a property of an object. + @remarks + This definition is shared between all instances of an object and therefore + has no value. Property contains values. + */ + class _OgrePropertyExport PropertyDef : public PropertyAlloc + { + public: + + /** Construct a property. + @param name The name of the property + @param desc A (potentially) long description of the property + @param pType The type of the property + */ + PropertyDef(const String& name, const String& desc, PropertyType pType) + : mName(name), mDesc(desc), mType(pType) {} + + /// Get the name of the property + const String& getName() const { return mName; } + + /// Get the description of the property + const String& getDescription() const { return mDesc; } + + /// Get the type of the property + PropertyType getType() const { return mType; } + + /// Get a string name of a property type + static const String& getTypeName(PropertyType theType); + + static PropertyType getTypeForValue(const short& val) { return PROP_SHORT; } + static PropertyType getTypeForValue(const unsigned short& val) { return PROP_UNSIGNED_SHORT; } + static PropertyType getTypeForValue(const int& val) { return PROP_INT; } + static PropertyType getTypeForValue(const unsigned int& val) { return PROP_UNSIGNED_INT; } + static PropertyType getTypeForValue(const long& val) { return PROP_LONG; } + static PropertyType getTypeForValue(const unsigned long& val) { return PROP_UNSIGNED_LONG; } + static PropertyType getTypeForValue(const Real& val) { return PROP_REAL; } + static PropertyType getTypeForValue(const String& val) { return PROP_STRING; } + static PropertyType getTypeForValue(const Vector2& val) { return PROP_VECTOR2; } + static PropertyType getTypeForValue(const Vector3& val) { return PROP_VECTOR3; } + static PropertyType getTypeForValue(const Vector4& val) { return PROP_VECTOR4; } + static PropertyType getTypeForValue(const ColourValue& val) { return PROP_COLOUR; } + static PropertyType getTypeForValue(const bool& val) { return PROP_BOOL; } + static PropertyType getTypeForValue(const Quaternion& val) { return PROP_QUATERNION; } + static PropertyType getTypeForValue(const Matrix3& val) { return PROP_MATRIX3; } + static PropertyType getTypeForValue(const Matrix4& val) { return PROP_MATRIX4; } + + protected: + // no default construction + PropertyDef() {} + + String mName; + String mDesc; + PropertyType mType; + + }; + + /// Map from property name to shared definition + typedef map::type PropertyDefMap; + + /** Base interface for an instance of a property. + */ + class _OgrePropertyExport PropertyBase : public PropertyAlloc + { + public: + /// Constructor + PropertyBase(PropertyDef* def) : mDef(def) {} + virtual ~PropertyBase() {} + + /// Get the name of the property + const String& getName() const { return mDef->getName(); } + + /// Get the description of the property + const String& getDescription() const { return mDef->getDescription(); } + + /// Get the type of the property + PropertyType getType() const { return mDef->getType(); } + + /// Return the current value as an Any + virtual Ogre::Any getValue() const = 0; + + protected: + // disallow default construction + PropertyBase() {} + PropertyDef* mDef; + + }; + + /** Property instance with passthrough calls to a given object. */ + template + class Property : public PropertyBase + { + public: + typedef T value_type; + typedef boost::function< T (void) > getter_func; + typedef boost::function< void (T) > setter_func; + + /** Construct a property which is able to directly call a given + getter and setter on a specific object instance, via functors. + */ + Property(PropertyDef* def, getter_func getter, setter_func setter) + : PropertyBase(def) + , mGetter(getter) + , mSetter(setter) + { + } + + /** Set the property value. + */ + virtual void set(T val) + { + mSetter(val); + } + + virtual T get() const + { + return mGetter(); + } + + Ogre::Any getValue() const + { + return Ogre::Any(get()); + } + + protected: + // disallow default construction + Property() {} + ~Property() {} + + getter_func mGetter; + setter_func mSetter; + }; + + /** A simple structure designed just as a holder of property values between + the instances of objects they might target. There is just enough information + here to be able to interpret the results accurately but no more. + */ + struct PropertyValue + { + PropertyType propType; + Ogre::Any val; + }; + /// Defines a transferable map of properties using wrapped value types (Ogre::Any) + typedef map::type PropertyValueMap; + + + /** Defines a complete set of properties for a single object instance. + */ + class _OgrePropertyExport PropertySet : public PropertyAlloc + { + public: + PropertySet(); + ~PropertySet(); + + /** Adds a property to this set. + @remarks + The PropertySet is responsible for deleting this object. + */ + void addProperty(PropertyBase* prop); + + /** Gets the property object for a given property name. + @remarks + Note that this property will need to be cast to a templated property + compatible with the type you will be setting. You might find the + overloaded set and get methods quicker if + you already know the type. + */ + PropertyBase* getProperty(const String& name) const; + + /** Reports whether this property set contains a named property. */ + bool hasProperty(const String& name) const; /** Removes the named property from the property set. */ void removeProperty(const String& name); - typedef map::type PropertyMap; - typedef Ogre::MapIterator PropertyIterator; - /// Get an iterator over the available properties - PropertyIterator getPropertyIterator(); - - /** Gets an independently usable collection of property values from the - current state. - */ - PropertyValueMap getValueMap() const; - - /** Sets the current state from a given value map. - */ - void setValueMap(const PropertyValueMap& values); - - /** Get a named property value. - */ - template - void getValue(const String& name, T& value) const - { - getPropertyImpl(name, value, PropertyDef::getTypeForValue(value)); - } - - /** Set a named property value (via pointer to avoid copy). - */ - template - void setValue(const String& name, const T* value) - { - setPropertyImpl(name, *value, PropertyDef::getTypeForValue(*value)); - } - /** Set a named property value. - */ - template - void setValue(const String& name, T value) - { - setPropertyImpl(name, value, PropertyDef::getTypeForValue(value)); - } - /** Special-case char*, convert to String automatically. - */ - void setValue(const String& name, const char* pChar) - { - String v(pChar); - setPropertyImpl(name, v, PROP_STRING); - } - - - protected: - PropertyMap mPropertyMap; - - /// Set a named property value, internal implementation (type match required) - template - void setPropertyImpl(const String& name, const T& val, PropertyType typeCheck) - { - PropertyBase* baseProp = getProperty(name); - if (baseProp->getType() != typeCheck) - { - StringStream msg; - msg << "Property error: type passed in: '" << PropertyDef::getTypeName(typeCheck) - << "', type of property: '" << PropertyDef::getTypeName(baseProp->getType()) << "'"; - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, msg.str(), "PropertySet::setPropertyImpl"); - } - static_cast*>(baseProp)->set(val); - } - - /// Get a named property value, internal implementation (type match required) - template - void getPropertyImpl(const String& name, T& refVal, PropertyType typeCheck) const - { - PropertyBase* baseProp = getProperty(name); - if (baseProp->getType() != typeCheck) - { - StringStream msg; - msg << "Property error: type requested: '" << PropertyDef::getTypeName(typeCheck) - << "', type of property: '" << PropertyDef::getTypeName(baseProp->getType()) << "'"; - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, msg.str(), "PropertySet::getPropertyImpl"); - } - refVal = static_cast*>(baseProp)->get(); - } - - }; - - /** @} */ - /** @} */ + typedef map::type PropertyMap; + typedef Ogre::MapIterator PropertyIterator; + /// Get an iterator over the available properties + PropertyIterator getPropertyIterator(); + + /** Gets an independently usable collection of property values from the + current state. + */ + PropertyValueMap getValueMap() const; + + /** Sets the current state from a given value map. + */ + void setValueMap(const PropertyValueMap& values); + + /** Get a named property value. + */ + template + void getValue(const String& name, T& value) const + { + getPropertyImpl(name, value, PropertyDef::getTypeForValue(value)); + } + + /** Set a named property value (via pointer to avoid copy). + */ + template + void setValue(const String& name, const T* value) + { + setPropertyImpl(name, *value, PropertyDef::getTypeForValue(*value)); + } + /** Set a named property value. + */ + template + void setValue(const String& name, T value) + { + setPropertyImpl(name, value, PropertyDef::getTypeForValue(value)); + } + /** Special-case char*, convert to String automatically. + */ + void setValue(const String& name, const char* pChar) + { + String v(pChar); + setPropertyImpl(name, v, PROP_STRING); + } + + + protected: + PropertyMap mPropertyMap; + + /// Set a named property value, internal implementation (type match required) + template + void setPropertyImpl(const String& name, const T& val, PropertyType typeCheck) + { + PropertyBase* baseProp = getProperty(name); + if (baseProp->getType() != typeCheck) + { + StringStream msg; + msg << "Property error: type passed in: '" << PropertyDef::getTypeName(typeCheck) + << "', type of property: '" << PropertyDef::getTypeName(baseProp->getType()) << "'"; + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, msg.str(), "PropertySet::setPropertyImpl"); + } + static_cast*>(baseProp)->set(val); + } + + /// Get a named property value, internal implementation (type match required) + template + void getPropertyImpl(const String& name, T& refVal, PropertyType typeCheck) const + { + PropertyBase* baseProp = getProperty(name); + if (baseProp->getType() != typeCheck) + { + StringStream msg; + msg << "Property error: type requested: '" << PropertyDef::getTypeName(typeCheck) + << "', type of property: '" << PropertyDef::getTypeName(baseProp->getType()) << "'"; + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, msg.str(), "PropertySet::getPropertyImpl"); + } + refVal = static_cast*>(baseProp)->get(); + } + + }; + + /** @} */ + /** @} */ } diff --git a/Components/Property/include/OgrePropertyPrerequisites.h b/Components/Property/include/OgrePropertyPrerequisites.h index 968d4239fea..31948cc5895 100644 --- a/Components/Property/include/OgrePropertyPrerequisites.h +++ b/Components/Property/include/OgrePropertyPrerequisites.h @@ -34,28 +34,28 @@ THE SOFTWARE. namespace Ogre { - typedef GeneralAllocatedObject PropertyAlloc; + typedef GeneralAllocatedObject PropertyAlloc; } #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 -# if defined( OGRE_STATIC_LIB ) -# define _OgrePropertyExport +# if defined( OGRE_STATIC_LIB ) +# define _OgrePropertyExport # else -# if defined( OGRE_PROPERTY_EXPORTS ) -# define _OgrePropertyExport __declspec( dllexport ) -# else +# if defined( OGRE_PROPERTY_EXPORTS ) +# define _OgrePropertyExport __declspec( dllexport ) +# else # if defined( __MINGW32__ ) # define _OgrePropertyExport # else -# define _OgrePropertyExport __declspec( dllimport ) +# define _OgrePropertyExport __declspec( dllimport ) # endif -# endif -# endif +# endif +# endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgrePropertyExport __attribute__ ((visibility("default"))) #else -# define _OgrePropertyExport +# define _OgrePropertyExport #endif diff --git a/Components/Property/src/OgreProperty.cpp b/Components/Property/src/OgreProperty.cpp index 23a88256a7a..5a693125636 100644 --- a/Components/Property/src/OgreProperty.cpp +++ b/Components/Property/src/OgreProperty.cpp @@ -32,230 +32,230 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - const String& PropertyDef::getTypeName(PropertyType theType) - { - static const String sPropNames[] = { - "short", - "unsigned short", - "int", - "unsigned int", - "long", - "unsigned long", - "Real", - "String", - "Vector2", - "Vector3", - "Vector4", - "ColourValue", - "bool", - "Quaternion", - "Matrix3", - "Matrix4" - }; + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + const String& PropertyDef::getTypeName(PropertyType theType) + { + static const String sPropNames[] = { + "short", + "unsigned short", + "int", + "unsigned int", + "long", + "unsigned long", + "Real", + "String", + "Vector2", + "Vector3", + "Vector4", + "ColourValue", + "bool", + "Quaternion", + "Matrix3", + "Matrix4" + }; - return sPropNames[(int)theType]; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - PropertySet::PropertySet() - { + return sPropNames[(int)theType]; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + PropertySet::PropertySet() + { - } - //--------------------------------------------------------------------- - PropertySet::~PropertySet() - { - for (PropertyMap::iterator i = mPropertyMap.begin(); i != mPropertyMap.end(); ++i) - { - OGRE_DELETE i->second; - } - mPropertyMap.clear(); - } - //--------------------------------------------------------------------- - void PropertySet::addProperty(PropertyBase* prop) - { - std::pair retPair = - mPropertyMap.insert(PropertyMap::value_type(prop->getName(), prop)); - if (!retPair.second) - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Duplicate property entry!", - "PropertySet::addProperty"); - } - //--------------------------------------------------------------------- - bool PropertySet::hasProperty(const String& name) const - { - PropertyMap::const_iterator i = mPropertyMap.find(name); - return i != mPropertyMap.end(); - } - //--------------------------------------------------------------------- - PropertyBase* PropertySet::getProperty(const String& name) const - { - PropertyMap::const_iterator i = mPropertyMap.find(name); - if (i != mPropertyMap.end()) - return i->second; - else - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Property not found!", - "PropertySet::getProperty"); - } + } + //--------------------------------------------------------------------- + PropertySet::~PropertySet() + { + for (PropertyMap::iterator i = mPropertyMap.begin(); i != mPropertyMap.end(); ++i) + { + OGRE_DELETE i->second; + } + mPropertyMap.clear(); + } + //--------------------------------------------------------------------- + void PropertySet::addProperty(PropertyBase* prop) + { + std::pair retPair = + mPropertyMap.insert(PropertyMap::value_type(prop->getName(), prop)); + if (!retPair.second) + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Duplicate property entry!", + "PropertySet::addProperty"); + } + //--------------------------------------------------------------------- + bool PropertySet::hasProperty(const String& name) const + { + PropertyMap::const_iterator i = mPropertyMap.find(name); + return i != mPropertyMap.end(); + } + //--------------------------------------------------------------------- + PropertyBase* PropertySet::getProperty(const String& name) const + { + PropertyMap::const_iterator i = mPropertyMap.find(name); + if (i != mPropertyMap.end()) + return i->second; + else + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Property not found!", + "PropertySet::getProperty"); + } //--------------------------------------------------------------------- void PropertySet::removeProperty(const String& name) { mPropertyMap.erase(name); } - //--------------------------------------------------------------------- - PropertySet::PropertyIterator PropertySet::getPropertyIterator() - { - return PropertyIterator(mPropertyMap.begin(), mPropertyMap.end()); - } - //--------------------------------------------------------------------- - PropertyValueMap PropertySet::getValueMap() const - { - PropertyValueMap ret; - for (PropertyMap::const_iterator i = mPropertyMap.begin(); i != mPropertyMap.end(); ++i) - { - PropertyValue val; - val.propType = i->second->getType(); - switch(val.propType) - { - case PROP_SHORT: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_UNSIGNED_SHORT: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_INT: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_UNSIGNED_INT: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_LONG: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_UNSIGNED_LONG: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_REAL: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_STRING: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_VECTOR2: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_VECTOR3: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_VECTOR4: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_COLOUR: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_BOOL: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_QUATERNION: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_MATRIX3: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; - case PROP_MATRIX4: - val.val = Ogre::Any(static_cast*>(i->second)->get()); - break; + //--------------------------------------------------------------------- + PropertySet::PropertyIterator PropertySet::getPropertyIterator() + { + return PropertyIterator(mPropertyMap.begin(), mPropertyMap.end()); + } + //--------------------------------------------------------------------- + PropertyValueMap PropertySet::getValueMap() const + { + PropertyValueMap ret; + for (PropertyMap::const_iterator i = mPropertyMap.begin(); i != mPropertyMap.end(); ++i) + { + PropertyValue val; + val.propType = i->second->getType(); + switch(val.propType) + { + case PROP_SHORT: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_UNSIGNED_SHORT: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_INT: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_UNSIGNED_INT: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_LONG: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_UNSIGNED_LONG: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_REAL: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_STRING: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_VECTOR2: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_VECTOR3: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_VECTOR4: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_COLOUR: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_BOOL: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_QUATERNION: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_MATRIX3: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; + case PROP_MATRIX4: + val.val = Ogre::Any(static_cast*>(i->second)->get()); + break; case PROP_UNKNOWN: default: break; - }; - ret[i->second->getName()] = val; - } + }; + ret[i->second->getName()] = val; + } - return ret; + return ret; - } - //--------------------------------------------------------------------- - void PropertySet::setValueMap(const PropertyValueMap& values) - { - for (PropertyValueMap::const_iterator i = values.begin(); i != values.end(); ++i) - { - PropertyMap::iterator j = mPropertyMap.find(i->first); - if (j != mPropertyMap.end()) - { - // matching properties - // check type - if (j->second->getType() != i->second.propType) - { - StringStream msg; - msg << "Property " << i->first << " mismatched type; incoming type: '" - << PropertyDef::getTypeName(i->second.propType) << "', property type: '" - << PropertyDef::getTypeName(j->second->getType()) << "'"; - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, msg.str(), "PropertySet::setValueMap"); - } - switch(i->second.propType) - { - case PROP_SHORT: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_UNSIGNED_SHORT: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_INT: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_UNSIGNED_INT: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_LONG: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_UNSIGNED_LONG: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_REAL: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_STRING: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_VECTOR2: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_VECTOR3: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_VECTOR4: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_COLOUR: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_BOOL: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_QUATERNION: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_MATRIX3: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; - case PROP_MATRIX4: - static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); - break; + } + //--------------------------------------------------------------------- + void PropertySet::setValueMap(const PropertyValueMap& values) + { + for (PropertyValueMap::const_iterator i = values.begin(); i != values.end(); ++i) + { + PropertyMap::iterator j = mPropertyMap.find(i->first); + if (j != mPropertyMap.end()) + { + // matching properties + // check type + if (j->second->getType() != i->second.propType) + { + StringStream msg; + msg << "Property " << i->first << " mismatched type; incoming type: '" + << PropertyDef::getTypeName(i->second.propType) << "', property type: '" + << PropertyDef::getTypeName(j->second->getType()) << "'"; + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, msg.str(), "PropertySet::setValueMap"); + } + switch(i->second.propType) + { + case PROP_SHORT: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_UNSIGNED_SHORT: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_INT: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_UNSIGNED_INT: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_LONG: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_UNSIGNED_LONG: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_REAL: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_STRING: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_VECTOR2: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_VECTOR3: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_VECTOR4: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_COLOUR: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_BOOL: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_QUATERNION: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_MATRIX3: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; + case PROP_MATRIX4: + static_cast*>(j->second)->set(Ogre::any_cast(i->second.val)); + break; case PROP_UNKNOWN: default: break; - }; + }; - } - } + } + } - } + } } diff --git a/Components/RTShaderSystem/include/OgreShaderCGProgramProcessor.h b/Components/RTShaderSystem/include/OgreShaderCGProgramProcessor.h index 17ef34ac670..0b74494d0cd 100644 --- a/Components/RTShaderSystem/include/OgreShaderCGProgramProcessor.h +++ b/Components/RTShaderSystem/include/OgreShaderCGProgramProcessor.h @@ -47,30 +47,30 @@ class _OgreRTSSExport CGProgramProcessor : public ProgramProcessor { // Interface. -public: - - /** Class constructor. - */ - CGProgramProcessor(); - - /** Class destructor */ - virtual ~CGProgramProcessor(); - - /** Return the target language of this processor. */ - virtual const String& getTargetLanguage() const { return TargetLanguage; } - - /** - @see ProgramProcessor::preCreateGpuPrograms - */ - virtual bool preCreateGpuPrograms(ProgramSet* programSet); +public: + + /** Class constructor. + */ + CGProgramProcessor(); + + /** Class destructor */ + virtual ~CGProgramProcessor(); + + /** Return the target language of this processor. */ + virtual const String& getTargetLanguage() const { return TargetLanguage; } + + /** + @see ProgramProcessor::preCreateGpuPrograms + */ + virtual bool preCreateGpuPrograms(ProgramSet* programSet); - /** - @see ProgramProcessor::postCreateGpuPrograms - */ - virtual bool postCreateGpuPrograms(ProgramSet* programSet); + /** + @see ProgramProcessor::postCreateGpuPrograms + */ + virtual bool postCreateGpuPrograms(ProgramSet* programSet); - static String TargetLanguage; - + static String TargetLanguage; + }; diff --git a/Components/RTShaderSystem/include/OgreShaderCGProgramWriter.h b/Components/RTShaderSystem/include/OgreShaderCGProgramWriter.h index effc5cf9f71..82181ac6a00 100644 --- a/Components/RTShaderSystem/include/OgreShaderCGProgramWriter.h +++ b/Components/RTShaderSystem/include/OgreShaderCGProgramWriter.h @@ -56,60 +56,60 @@ class _OgreRTSSExport CGProgramWriter : public ProgramWriter // Interface. public: - /** Class constructor. - */ - CGProgramWriter(); + /** Class constructor. + */ + CGProgramWriter(); - /** Class destructor */ - virtual ~CGProgramWriter(); + /** Class destructor */ + virtual ~CGProgramWriter(); - /** - @see ProgramWriter::writeSourceCode. - */ - virtual void writeSourceCode(std::ostream& os, Program* program); + /** + @see ProgramWriter::writeSourceCode. + */ + virtual void writeSourceCode(std::ostream& os, Program* program); - /** - @see ProgramWriter::getTargetLanguage. - */ - virtual const String& getTargetLanguage() const { return TargetLanguage; } + /** + @see ProgramWriter::getTargetLanguage. + */ + virtual const String& getTargetLanguage() const { return TargetLanguage; } - static String TargetLanguage; + static String TargetLanguage; // Protected methods. protected: - /** Initialize string maps. */ - void initializeStringMaps(); + /** Initialize string maps. */ + void initializeStringMaps(); - /** Write the program dependencies. */ - void writeProgramDependencies(std::ostream& os, Program* program); - - /** Write a uniform parameter. */ - void writeUniformParameter(std::ostream& os, UniformParameterPtr parameter); + /** Write the program dependencies. */ + void writeProgramDependencies(std::ostream& os, Program* program); + + /** Write a uniform parameter. */ + void writeUniformParameter(std::ostream& os, UniformParameterPtr parameter); - /** Write a function parameter. */ - void writeFunctionParameter(std::ostream& os, ParameterPtr parameter); + /** Write a function parameter. */ + void writeFunctionParameter(std::ostream& os, ParameterPtr parameter); - /** Write a local parameter. */ - void writeLocalParameter(std::ostream& os, ParameterPtr parameter); + /** Write a local parameter. */ + void writeLocalParameter(std::ostream& os, ParameterPtr parameter); - /** Write a function declaration. */ - void writeFunctionDeclaration(std::ostream& os, Function* function); + /** Write a function declaration. */ + void writeFunctionDeclaration(std::ostream& os, Function* function); - /** Write function atom instance. */ - void writeAtomInstance(std::ostream& os, FunctionAtom* atom); + /** Write function atom instance. */ + void writeAtomInstance(std::ostream& os, FunctionAtom* atom); protected: - typedef map::type GpuConstTypeToStringMap; - typedef map::type ParamSemanticToStringMap; + typedef map::type GpuConstTypeToStringMap; + typedef map::type ParamSemanticToStringMap; // Attributes. protected: - // Map between GPU constant type to string value. - GpuConstTypeToStringMap mGpuConstTypeMap; - // Map between parameter semantic to string value. - ParamSemanticToStringMap mParamSemanticMap; + // Map between GPU constant type to string value. + GpuConstTypeToStringMap mGpuConstTypeMap; + // Map between parameter semantic to string value. + ParamSemanticToStringMap mParamSemanticMap; }; /** CG program writer factory implementation. @@ -118,29 +118,29 @@ class _OgreRTSSExport CGProgramWriter : public ProgramWriter class _OgreRTSSExport ShaderProgramWriterCGFactory : public ProgramWriterFactory { public: - ShaderProgramWriterCGFactory() : mLanguage("cg") - { - } - virtual ~ShaderProgramWriterCGFactory() {} - - /** - @see ProgramWriterFactory::getTargetLanguage - */ - virtual const String& getTargetLanguage(void) const - { - return mLanguage; - } - - /** - @see ProgramWriterFactory::create - */ - virtual ProgramWriter* create(void) - { - return OGRE_NEW CGProgramWriter(); - } + ShaderProgramWriterCGFactory() : mLanguage("cg") + { + } + virtual ~ShaderProgramWriterCGFactory() {} + + /** + @see ProgramWriterFactory::getTargetLanguage + */ + virtual const String& getTargetLanguage(void) const + { + return mLanguage; + } + + /** + @see ProgramWriterFactory::create + */ + virtual ProgramWriter* create(void) + { + return OGRE_NEW CGProgramWriter(); + } private: - String mLanguage; + String mLanguage; }; diff --git a/Components/RTShaderSystem/include/OgreShaderExDualQuaternionSkinning.h b/Components/RTShaderSystem/include/OgreShaderExDualQuaternionSkinning.h index d0d7d25dd79..dfef7439bcd 100644 --- a/Components/RTShaderSystem/include/OgreShaderExDualQuaternionSkinning.h +++ b/Components/RTShaderSystem/include/OgreShaderExDualQuaternionSkinning.h @@ -62,20 +62,20 @@ class _OgreRTSSExport DualQuaternionSkinning : public HardwareSkinningTechnique /** Class default constructor */ DualQuaternionSkinning(); - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet); - - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet); - - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet); + + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet); + + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); // Protected methods protected: diff --git a/Components/RTShaderSystem/include/OgreShaderExHardwareSkinning.h b/Components/RTShaderSystem/include/OgreShaderExHardwareSkinning.h index 2356a6ef4b5..5262edc7ba0 100644 --- a/Components/RTShaderSystem/include/OgreShaderExHardwareSkinning.h +++ b/Components/RTShaderSystem/include/OgreShaderExHardwareSkinning.h @@ -56,118 +56,118 @@ the points and normals by their assigned bone matricies. class _OgreRTSSExport HardwareSkinning : public SubRenderState { public: - struct SkinningData - { - SkinningData() : - isValid(true), maxBoneCount(0), maxWeightCount(0), skinningType(ST_LINEAR), correctAntipodalityHandling(false), scalingShearingSupport(false) - {} - - bool isValid; - ushort maxBoneCount; - ushort maxWeightCount; - SkinningType skinningType; - bool correctAntipodalityHandling; - bool scalingShearingSupport; - }; + struct SkinningData + { + SkinningData() : + isValid(true), maxBoneCount(0), maxWeightCount(0), skinningType(ST_LINEAR), correctAntipodalityHandling(false), scalingShearingSupport(false) + {} + + bool isValid; + ushort maxBoneCount; + ushort maxWeightCount; + SkinningType skinningType; + bool correctAntipodalityHandling; + bool scalingShearingSupport; + }; // Interface. public: - /** Class default constructor */ - HardwareSkinning(); - - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; - - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; - - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); - - /** - Set the hardware skinning parameters. - @param boneCount The maximum number of bones in the model this material - is assigned to. Note that this parameter can be higher but not - lower than the actual number of bones. - @param weightCount The maximum number of weights/bones affecting a vertex. - @param skinningType The type of skinning desired. - @param correctAntipodalityHandling If correct antipodality handling should be utilized (Only applicable for dual quaternion skinning). - @param scalingShearingSupport If scaling and shearing support should be enabled (Only applicable for dual quaternion skinning). - */ - void setHardwareSkinningParam(ushort boneCount, ushort weightCount, SkinningType skinningType = ST_LINEAR, bool correctAntipodalityHandling = false, bool scalingShearingSupport = false); - - /** - Returns the number of bones in the model assigned to the material. - @see setHardwareSkinningParam() - */ - ushort getBoneCount(); - - /** - Returns the number of weights/bones affecting a vertex. - @see setHardwareSkinningParam() - */ - ushort getWeightCount(); - - /** - Returns the current skinning type in use. - @see setHardwareSkinningParam() - */ - SkinningType getSkinningType(); - - /** - Only applicable for dual quaternion skinning. - @see setHardwareSkinningParam() - */ - bool hasCorrectAntipodalityHandling(); - - /** - Only applicable for dual quaternion skinning. - @see setHardwareSkinningParam() - */ - bool hasScalingShearingSupport(); - - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); - - /** - Set the factory which created this sub render state - */ - void _setCreator(const HardwareSkinningFactory* pCreator) { mCreator = pCreator; } - - static String Type; + /** Class default constructor */ + HardwareSkinning(); + + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; + + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; + + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); + + /** + Set the hardware skinning parameters. + @param boneCount The maximum number of bones in the model this material + is assigned to. Note that this parameter can be higher but not + lower than the actual number of bones. + @param weightCount The maximum number of weights/bones affecting a vertex. + @param skinningType The type of skinning desired. + @param correctAntipodalityHandling If correct antipodality handling should be utilized (Only applicable for dual quaternion skinning). + @param scalingShearingSupport If scaling and shearing support should be enabled (Only applicable for dual quaternion skinning). + */ + void setHardwareSkinningParam(ushort boneCount, ushort weightCount, SkinningType skinningType = ST_LINEAR, bool correctAntipodalityHandling = false, bool scalingShearingSupport = false); + + /** + Returns the number of bones in the model assigned to the material. + @see setHardwareSkinningParam() + */ + ushort getBoneCount(); + + /** + Returns the number of weights/bones affecting a vertex. + @see setHardwareSkinningParam() + */ + ushort getWeightCount(); + + /** + Returns the current skinning type in use. + @see setHardwareSkinningParam() + */ + SkinningType getSkinningType(); + + /** + Only applicable for dual quaternion skinning. + @see setHardwareSkinningParam() + */ + bool hasCorrectAntipodalityHandling(); + + /** + Only applicable for dual quaternion skinning. + @see setHardwareSkinningParam() + */ + bool hasScalingShearingSupport(); + + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); + + /** + Set the factory which created this sub render state + */ + void _setCreator(const HardwareSkinningFactory* pCreator) { mCreator = pCreator; } + + static String Type; // Protected methods protected: - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet); - - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet); - - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); - - SharedPtr mLinear; - SharedPtr mDualQuat; - SharedPtr mActiveTechnique; - - ///The factory which created this sub render state - const HardwareSkinningFactory* mCreator; - SkinningType mSkinningType; + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet); + + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet); + + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); + + SharedPtr mLinear; + SharedPtr mDualQuat; + SharedPtr mActiveTechnique; + + ///The factory which created this sub render state + const HardwareSkinningFactory* mCreator; + SkinningType mSkinningType; }; _OgreRTSSExport void operator<<(std::ostream& o, const HardwareSkinning::SkinningData& data); @@ -177,167 +177,167 @@ A factory that enables creation of HardwareSkinning instances. @remarks Sub class of SubRenderStateFactory */ class _OgreRTSSExport HardwareSkinningFactory : public SubRenderStateFactory, - public Singleton + public Singleton { public: - HardwareSkinningFactory(); - - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; - - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); - - /** - Sets the list of custom shadow caster materials - */ - virtual void setCustomShadowCasterMaterials(const SkinningType skinningType, const MaterialPtr& caster1Weight, const MaterialPtr& caster2Weight, - const MaterialPtr& caster3Weight, const MaterialPtr& caster4Weight); - - /** - Sets the list of custom shadow receiver materials - */ - virtual void setCustomShadowReceiverMaterials(const SkinningType skinningType, const MaterialPtr& receiver1Weight, const MaterialPtr& receiver2Weight, - const MaterialPtr& receiver3Weight, const MaterialPtr& receiver4Weight); - - /** - Returns the name of a custom shadow caster material for a given number of weights - */ - const MaterialPtr& getCustomShadowCasterMaterial(const SkinningType skinningType, ushort index) const; - - /** - Returns the name of a custom shadow receiver material for a given number of weights - */ - const MaterialPtr& getCustomShadowReceiverMaterial(const SkinningType skinningType, ushort index) const; - - /** - @brief - Prepares an entity's material for use in the hardware skinning (HS). - - This function prepares an entity's material for use by the HS sub-render - state. This function scans the entity and extracts the information of the amount - of bones and weights in the entity. This function replaces the need specify in - the material script the amount of bones and weights needed to make the HS work. - - Note that this class does not save the the bone and weight count information - internally. Rather this information is stored in the entity's materials as a - user binded object. - - @param pEntity A pointer to an entity who's materials need preparing. - */ - void prepareEntityForSkinning(const Entity* pEntity, SkinningType skinningType = ST_LINEAR, bool correctAntidpodalityHandling = false, bool shearScale = false); - - /** - @brief - The maximum number of bones for which hardware skinning is performed. - - This number should be limited to avoid problems of using to many parameters - in a shader. For example, in pixel shader 3 this should be around 70-90 - dependent on other sub-render states in the shader. - - The default value for this property is 70 which correspond to pixel shader model 3 limitations - */ - ushort getMaxCalculableBoneCount() const { - return mMaxCalculableBoneCount; } - /** - Sets the maximum number of bones for which hardware skinning is performed. - @see getMaxCalculableBoneCount() - */ - void setMaxCalculableBoneCount(ushort count) { - mMaxCalculableBoneCount = count; } - - /** - Override standard Singleton retrieval. - - @remarks Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static HardwareSkinningFactory& getSingleton(void); - - /** - Override standard Singleton retrieval. - - @remarks Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static HardwareSkinningFactory* getSingletonPtr(void); + HardwareSkinningFactory(); + + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; + + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + + /** + Sets the list of custom shadow caster materials + */ + virtual void setCustomShadowCasterMaterials(const SkinningType skinningType, const MaterialPtr& caster1Weight, const MaterialPtr& caster2Weight, + const MaterialPtr& caster3Weight, const MaterialPtr& caster4Weight); + + /** + Sets the list of custom shadow receiver materials + */ + virtual void setCustomShadowReceiverMaterials(const SkinningType skinningType, const MaterialPtr& receiver1Weight, const MaterialPtr& receiver2Weight, + const MaterialPtr& receiver3Weight, const MaterialPtr& receiver4Weight); + + /** + Returns the name of a custom shadow caster material for a given number of weights + */ + const MaterialPtr& getCustomShadowCasterMaterial(const SkinningType skinningType, ushort index) const; + + /** + Returns the name of a custom shadow receiver material for a given number of weights + */ + const MaterialPtr& getCustomShadowReceiverMaterial(const SkinningType skinningType, ushort index) const; + + /** + @brief + Prepares an entity's material for use in the hardware skinning (HS). + + This function prepares an entity's material for use by the HS sub-render + state. This function scans the entity and extracts the information of the amount + of bones and weights in the entity. This function replaces the need specify in + the material script the amount of bones and weights needed to make the HS work. + + Note that this class does not save the the bone and weight count information + internally. Rather this information is stored in the entity's materials as a + user binded object. + + @param pEntity A pointer to an entity who's materials need preparing. + */ + void prepareEntityForSkinning(const Entity* pEntity, SkinningType skinningType = ST_LINEAR, bool correctAntidpodalityHandling = false, bool shearScale = false); + + /** + @brief + The maximum number of bones for which hardware skinning is performed. + + This number should be limited to avoid problems of using to many parameters + in a shader. For example, in pixel shader 3 this should be around 70-90 + dependent on other sub-render states in the shader. + + The default value for this property is 70 which correspond to pixel shader model 3 limitations + */ + ushort getMaxCalculableBoneCount() const { + return mMaxCalculableBoneCount; } + /** + Sets the maximum number of bones for which hardware skinning is performed. + @see getMaxCalculableBoneCount() + */ + void setMaxCalculableBoneCount(ushort count) { + mMaxCalculableBoneCount = count; } + + /** + Override standard Singleton retrieval. + + @remarks Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static HardwareSkinningFactory& getSingleton(void); + + /** + Override standard Singleton retrieval. + + @remarks Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static HardwareSkinningFactory* getSingletonPtr(void); protected: - /** - @brief - Extracts the maximum amount of bones and weights used in an specific subentity of given entity. - - @param pEntity The entity from which the information needs to be extracted. - @param subEntityIndex The index of subentity from which the information needs to be extracted. - @param boneCount The maximum number of bones used by the entity. - @param weightCount The maximum number of weights used by the entity. - @return Returns true if the entity can use HS. False if not. - */ - bool extractSkeletonData(const Entity* pEntity, unsigned int subEntityIndex, - ushort& boneCount, ushort& weightCount); - - /** - @brief - Updates an entity's the skeleton data onto one of it's materials. - - @param pMaterial The material to update with the information. - @param isValid Tells if the material can be used with HS. - @param boneCount The maximum number of bones used by the entity. - @param weightCount The maximum number of weights used by the entity. - @return Returns true if the data was updated on the material. False if not. - */ - bool imprintSkeletonData(const MaterialPtr& pMaterial, bool isValid, - ushort boneCount, ushort weightCount, SkinningType skinningType, bool correctAntidpodalityHandling, bool scalingShearingSupport); + /** + @brief + Extracts the maximum amount of bones and weights used in an specific subentity of given entity. + + @param pEntity The entity from which the information needs to be extracted. + @param subEntityIndex The index of subentity from which the information needs to be extracted. + @param boneCount The maximum number of bones used by the entity. + @param weightCount The maximum number of weights used by the entity. + @return Returns true if the entity can use HS. False if not. + */ + bool extractSkeletonData(const Entity* pEntity, unsigned int subEntityIndex, + ushort& boneCount, ushort& weightCount); + + /** + @brief + Updates an entity's the skeleton data onto one of it's materials. + + @param pMaterial The material to update with the information. + @param isValid Tells if the material can be used with HS. + @param boneCount The maximum number of bones used by the entity. + @param weightCount The maximum number of weights used by the entity. + @return Returns true if the data was updated on the material. False if not. + */ + bool imprintSkeletonData(const MaterialPtr& pMaterial, bool isValid, + ushort boneCount, ushort weightCount, SkinningType skinningType, bool correctAntidpodalityHandling, bool scalingShearingSupport); protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); - /// A set of custom shadow caster materials - MaterialPtr mCustomShadowCasterMaterialsLinear[HS_MAX_WEIGHT_COUNT]; - MaterialPtr mCustomShadowCasterMaterialsDualQuaternion[HS_MAX_WEIGHT_COUNT]; + /// A set of custom shadow caster materials + MaterialPtr mCustomShadowCasterMaterialsLinear[HS_MAX_WEIGHT_COUNT]; + MaterialPtr mCustomShadowCasterMaterialsDualQuaternion[HS_MAX_WEIGHT_COUNT]; - /// A set of custom shadow receiver materials - MaterialPtr mCustomShadowReceiverMaterialsLinear[HS_MAX_WEIGHT_COUNT]; - MaterialPtr mCustomShadowReceiverMaterialsDualQuaternion[HS_MAX_WEIGHT_COUNT]; + /// A set of custom shadow receiver materials + MaterialPtr mCustomShadowReceiverMaterialsLinear[HS_MAX_WEIGHT_COUNT]; + MaterialPtr mCustomShadowReceiverMaterialsDualQuaternion[HS_MAX_WEIGHT_COUNT]; - ///The maximum number of bones for which hardware skinning is performed. - ///@see getMaxCalculableBoneCount() - ushort mMaxCalculableBoneCount; + ///The maximum number of bones for which hardware skinning is performed. + ///@see getMaxCalculableBoneCount() + ushort mMaxCalculableBoneCount; }; /** @} */ diff --git a/Components/RTShaderSystem/include/OgreShaderExHardwareSkinningTechnique.h b/Components/RTShaderSystem/include/OgreShaderExHardwareSkinningTechnique.h index 0f4250dd9e2..996f442d3af 100644 --- a/Components/RTShaderSystem/include/OgreShaderExHardwareSkinningTechnique.h +++ b/Components/RTShaderSystem/include/OgreShaderExHardwareSkinningTechnique.h @@ -50,97 +50,97 @@ class _OgreRTSSExport HardwareSkinningTechnique : public RTShaderSystemAlloc { // Interface. public: - /** Class default constructor */ - HardwareSkinningTechnique(); - - virtual ~HardwareSkinningTechnique(); - - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const HardwareSkinningTechnique* hardSkin); - - /** - @see HardwareSkinning::setHardwareSkinningParam. - */ - void setHardwareSkinningParam(ushort boneCount, ushort weightCount, bool correctAntipodalityHandling = false, bool scalingShearingSupport = false); - - /** - Returns the number of bones in the model assigned to the material. - @see setHardwareSkinningParam() - */ - ushort getBoneCount(); - - /** - Returns the number of weights/bones affecting a vertex. - @see setHardwareSkinningParam() - */ - ushort getWeightCount(); - - /** - Only applicable for dual quaternion skinning. - @see setHardwareSkinningParam() - */ - bool hasCorrectAntipodalityHandling(); - - /** - Only applicable for dual quaternion skinning. - @see setHardwareSkinningParam() - */ - bool hasScalingShearingSupport(); - - /** - */ - void setDoBoneCalculations(bool doBoneCalculations); - - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet) = 0; - - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet) = 0; - - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet) = 0; + /** Class default constructor */ + HardwareSkinningTechnique(); + + virtual ~HardwareSkinningTechnique(); + + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const HardwareSkinningTechnique* hardSkin); + + /** + @see HardwareSkinning::setHardwareSkinningParam. + */ + void setHardwareSkinningParam(ushort boneCount, ushort weightCount, bool correctAntipodalityHandling = false, bool scalingShearingSupport = false); + + /** + Returns the number of bones in the model assigned to the material. + @see setHardwareSkinningParam() + */ + ushort getBoneCount(); + + /** + Returns the number of weights/bones affecting a vertex. + @see setHardwareSkinningParam() + */ + ushort getWeightCount(); + + /** + Only applicable for dual quaternion skinning. + @see setHardwareSkinningParam() + */ + bool hasCorrectAntipodalityHandling(); + + /** + Only applicable for dual quaternion skinning. + @see setHardwareSkinningParam() + */ + bool hasScalingShearingSupport(); + + /** + */ + void setDoBoneCalculations(bool doBoneCalculations); + + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet) = 0; + + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet) = 0; + + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet) = 0; protected: - /** Translates an index number to a mask value */ - Operand::OpMask indexToMask (int index); + /** Translates an index number to a mask value */ + Operand::OpMask indexToMask (int index); // Attributes. protected: - ushort mBoneCount; - ushort mWeightCount; - - bool mCorrectAntipodalityHandling; - bool mScalingShearingSupport; - - bool mDoBoneCalculations; - - ParameterPtr mParamInPosition; - ParameterPtr mParamInNormal; - ParameterPtr mParamInBiNormal; - ParameterPtr mParamInTangent; - ParameterPtr mParamInIndices; - ParameterPtr mParamInWeights; - UniformParameterPtr mParamInWorldMatrices; - UniformParameterPtr mParamInInvWorldMatrix; - UniformParameterPtr mParamInViewProjMatrix; - UniformParameterPtr mParamInWorldMatrix; - UniformParameterPtr mParamInWorldViewProjMatrix; - - ParameterPtr mParamTempFloat4; - ParameterPtr mParamTempFloat3; - ParameterPtr mParamLocalPositionWorld; - ParameterPtr mParamLocalNormalWorld; - ParameterPtr mParamLocalTangentWorld; - ParameterPtr mParamLocalBinormalWorld; - ParameterPtr mParamOutPositionProj; + ushort mBoneCount; + ushort mWeightCount; + + bool mCorrectAntipodalityHandling; + bool mScalingShearingSupport; + + bool mDoBoneCalculations; + + ParameterPtr mParamInPosition; + ParameterPtr mParamInNormal; + ParameterPtr mParamInBiNormal; + ParameterPtr mParamInTangent; + ParameterPtr mParamInIndices; + ParameterPtr mParamInWeights; + UniformParameterPtr mParamInWorldMatrices; + UniformParameterPtr mParamInInvWorldMatrix; + UniformParameterPtr mParamInViewProjMatrix; + UniformParameterPtr mParamInWorldMatrix; + UniformParameterPtr mParamInWorldViewProjMatrix; + + ParameterPtr mParamTempFloat4; + ParameterPtr mParamTempFloat3; + ParameterPtr mParamLocalPositionWorld; + ParameterPtr mParamLocalNormalWorld; + ParameterPtr mParamLocalTangentWorld; + ParameterPtr mParamLocalBinormalWorld; + ParameterPtr mParamOutPositionProj; }; } diff --git a/Components/RTShaderSystem/include/OgreShaderExIntegratedPSSM3.h b/Components/RTShaderSystem/include/OgreShaderExIntegratedPSSM3.h index 85e4c2814f4..9ab5f76ff91 100644 --- a/Components/RTShaderSystem/include/OgreShaderExIntegratedPSSM3.h +++ b/Components/RTShaderSystem/include/OgreShaderExIntegratedPSSM3.h @@ -43,10 +43,10 @@ namespace RTShader { * @{ */ -#define SGX_LIB_INTEGRATEDPSSM "SGXLib_IntegratedPSSM" -#define SGX_FUNC_COMPUTE_SHADOW_COLOUR3 "SGX_ComputeShadowFactor_PSSM3" -#define SGX_FUNC_APPLYSHADOWFACTOR_DIFFUSE "SGX_ApplyShadowFactor_Diffuse" -#define SGX_FUNC_MODULATE_SCALAR "SGX_ModulateScalar" +#define SGX_LIB_INTEGRATEDPSSM "SGXLib_IntegratedPSSM" +#define SGX_FUNC_COMPUTE_SHADOW_COLOUR3 "SGX_ComputeShadowFactor_PSSM3" +#define SGX_FUNC_APPLYSHADOWFACTOR_DIFFUSE "SGX_ApplyShadowFactor_Diffuse" +#define SGX_FUNC_MODULATE_SCALAR "SGX_ModulateScalar" /** Integrated PSSM shadow receiver with 3 splits sub render state implementation. Derives from SubRenderState class. @@ -54,136 +54,136 @@ Derives from SubRenderState class. class _OgreRTSSExport IntegratedPSSM3 : public SubRenderState { - // Interface. + // Interface. public: - typedef vector::type SplitPointList; + typedef vector::type SplitPointList; - /** Class default constructor */ - IntegratedPSSM3(); + /** Class default constructor */ + IntegratedPSSM3(); - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); - - /** Manually configure a new splitting scheme. - @param newSplitPoints A list which is splitCount + 1 entries long, containing the - split points. The first value is the near point, the last value is the - far point, and each value in between is both a far point of the previous - split, and a near point for the next one. - */ - void setSplitPoints(const SplitPointList& newSplitPoints); + + /** Manually configure a new splitting scheme. + @param newSplitPoints A list which is splitCount + 1 entries long, containing the + split points. The first value is the near point, the last value is the + far point, and each value in between is both a far point of the previous + split, and a near point for the next one. + */ + void setSplitPoints(const SplitPointList& newSplitPoints); - static String Type; + static String Type; - // Protected types: + // Protected types: protected: - // Shadow texture parameters. - struct _OgreRTSSExport ShadowTextureParams - { - // The max range of this shadow texture in terms of PSSM (far plane of viewing camera). - Real mMaxRange; - // The shadow map sampler index. - unsigned int mTextureSamplerIndex; - // The shadow map sampler. - UniformParameterPtr mTextureSampler; - // The inverse texture - UniformParameterPtr mInvTextureSize; - // The source light view projection matrix combined with world matrix. - UniformParameterPtr mWorldViewProjMatrix; - // The vertex shader output position in light space. - ParameterPtr mVSOutLightPosition; - // The pixel shader input position in light space. - ParameterPtr mPSInLightPosition; - - }; - - typedef vector::type ShadowTextureParamsList; - typedef ShadowTextureParamsList::iterator ShadowTextureParamsIterator; - typedef ShadowTextureParamsList::const_iterator ShadowTextureParamsConstIterator; - - // Protected methods + // Shadow texture parameters. + struct _OgreRTSSExport ShadowTextureParams + { + // The max range of this shadow texture in terms of PSSM (far plane of viewing camera). + Real mMaxRange; + // The shadow map sampler index. + unsigned int mTextureSamplerIndex; + // The shadow map sampler. + UniformParameterPtr mTextureSampler; + // The inverse texture + UniformParameterPtr mInvTextureSize; + // The source light view projection matrix combined with world matrix. + UniformParameterPtr mWorldViewProjMatrix; + // The vertex shader output position in light space. + ParameterPtr mVSOutLightPosition; + // The pixel shader input position in light space. + ParameterPtr mPSInLightPosition; + + }; + + typedef vector::type ShadowTextureParamsList; + typedef ShadowTextureParamsList::iterator ShadowTextureParamsIterator; + typedef ShadowTextureParamsList::const_iterator ShadowTextureParamsConstIterator; + + // Protected methods protected: - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet); - - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet); - - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); - - /** - Internal method that adds related vertex shader functions invocations. - */ - bool addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter); - - /** - Internal method that adds related pixel shader functions invocations. - */ - bool addPSInvocation(Program* psProgram, const int groupOrder, int& internalCounter); - - - - - - // Attributes. -protected: - // Shadow texture parameter list. - ShadowTextureParamsList mShadowTextureParamsList; - // Split points parameter. - UniformParameterPtr mPSSplitPoints; - // Vertex shader input position parameter. - ParameterPtr mVSInPos; - // Vertex shader output position (clip space) parameter. - ParameterPtr mVSOutPos; - // Vertex shader output depth (clip space) parameter. - ParameterPtr mVSOutDepth; - // Pixel shader input depth (clip space) parameter. - ParameterPtr mPSInDepth; - // Pixel shader local computed shadow colour parameter. - ParameterPtr mPSLocalShadowFactor; - // Pixel shader in/local diffuse colour parameter. - ParameterPtr mPSDiffuse; - // Pixel shader output diffuse colour parameter. - ParameterPtr mPSOutDiffuse; - // Pixel shader in/local specular colour parameter. - ParameterPtr mPSSpecualr; - // Derived scene colour (ambient term). - UniformParameterPtr mPSDerivedSceneColour; + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet); + + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet); + + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); + + /** + Internal method that adds related vertex shader functions invocations. + */ + bool addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter); + + /** + Internal method that adds related pixel shader functions invocations. + */ + bool addPSInvocation(Program* psProgram, const int groupOrder, int& internalCounter); + + + + + + // Attributes. +protected: + // Shadow texture parameter list. + ShadowTextureParamsList mShadowTextureParamsList; + // Split points parameter. + UniformParameterPtr mPSSplitPoints; + // Vertex shader input position parameter. + ParameterPtr mVSInPos; + // Vertex shader output position (clip space) parameter. + ParameterPtr mVSOutPos; + // Vertex shader output depth (clip space) parameter. + ParameterPtr mVSOutDepth; + // Pixel shader input depth (clip space) parameter. + ParameterPtr mPSInDepth; + // Pixel shader local computed shadow colour parameter. + ParameterPtr mPSLocalShadowFactor; + // Pixel shader in/local diffuse colour parameter. + ParameterPtr mPSDiffuse; + // Pixel shader output diffuse colour parameter. + ParameterPtr mPSOutDiffuse; + // Pixel shader in/local specular colour parameter. + ParameterPtr mPSSpecualr; + // Derived scene colour (ambient term). + UniformParameterPtr mPSDerivedSceneColour; }; @@ -196,23 +196,23 @@ class _OgreRTSSExport IntegratedPSSM3Factory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); }; diff --git a/Components/RTShaderSystem/include/OgreShaderExLayeredBlending.h b/Components/RTShaderSystem/include/OgreShaderExLayeredBlending.h index bd88b8bbbf7..de486d122dd 100644 --- a/Components/RTShaderSystem/include/OgreShaderExLayeredBlending.h +++ b/Components/RTShaderSystem/include/OgreShaderExLayeredBlending.h @@ -44,110 +44,110 @@ Derives from FFPTexturing class which derives from SubRenderState class. class _OgreRTSSExport LayeredBlending : public FFPTexturing { public: - enum BlendMode - { - LB_Invalid = -1, - LB_FFPBlend, - LB_BlendNormal, - LB_BlendLighten, - LB_BlendDarken, - LB_BlendMultiply, - LB_BlendAverage, - LB_BlendAdd, - LB_BlendSubtract, - LB_BlendDifference, - LB_BlendNegation, - LB_BlendExclusion, - LB_BlendScreen, - LB_BlendOverlay, - LB_BlendSoftLight, - LB_BlendHardLight, - LB_BlendColorDodge, - LB_BlendColorBurn, - LB_BlendLinearDodge, - LB_BlendLinearBurn, - LB_BlendLinearLight, - LB_BlendVividLight, - LB_BlendPinLight, - LB_BlendHardMix, - LB_BlendReflect, - LB_BlendGlow, - LB_BlendPhoenix, - LB_BlendSaturation, - LB_BlendColor, - LB_BlendLuminosity, - LB_MaxBlendModes - }; - - enum SourceModifier - { - SM_Invalid = -1, - SM_None, - SM_Source1Modulate, - SM_Source2Modulate, - SM_Source1InvModulate, - SM_Source2InvModulate, - SM_MaxSourceModifiers - }; - - struct TextureBlend - { - TextureBlend() : blendMode(LB_Invalid), sourceModifier(SM_Invalid), customNum(0) {} - - //The blend mode to use - BlendMode blendMode; - //The source modification to use - SourceModifier sourceModifier; - // The number of the custom param controlling the source modification - int customNum; - //The parameter controlling the source modification - ParameterPtr modControlParam; - }; - - - /** Class default constructor */ - LayeredBlending(); - - /** - @see SubRenderState::getType. - */ - virtual const Ogre::String& getType () const; - - - /** - Set the blend mode of the given texture unit layer with the previous layer. - @param index The texture unit texture. Textures units (index-1) and (index) will be blended. - @param mode The blend mode to apply. - */ - void setBlendMode(unsigned short index, BlendMode mode); - - /** - Return the blend mode of the given texture unit index. - */ - BlendMode getBlendMode(unsigned short index) const; - - - - /** - Set the source modifier parameters for a given texture unit - @param modType The source modification type to use - @param customNum The custom parameter number used to control the modification - */ - void setSourceModifier(unsigned short index, SourceModifier modType, int customNum); - - /** - Returns the source modifier parameters for a given texture unit - @return True if a valid modifier exist for the given texture unit + enum BlendMode + { + LB_Invalid = -1, + LB_FFPBlend, + LB_BlendNormal, + LB_BlendLighten, + LB_BlendDarken, + LB_BlendMultiply, + LB_BlendAverage, + LB_BlendAdd, + LB_BlendSubtract, + LB_BlendDifference, + LB_BlendNegation, + LB_BlendExclusion, + LB_BlendScreen, + LB_BlendOverlay, + LB_BlendSoftLight, + LB_BlendHardLight, + LB_BlendColorDodge, + LB_BlendColorBurn, + LB_BlendLinearDodge, + LB_BlendLinearBurn, + LB_BlendLinearLight, + LB_BlendVividLight, + LB_BlendPinLight, + LB_BlendHardMix, + LB_BlendReflect, + LB_BlendGlow, + LB_BlendPhoenix, + LB_BlendSaturation, + LB_BlendColor, + LB_BlendLuminosity, + LB_MaxBlendModes + }; + + enum SourceModifier + { + SM_Invalid = -1, + SM_None, + SM_Source1Modulate, + SM_Source2Modulate, + SM_Source1InvModulate, + SM_Source2InvModulate, + SM_MaxSourceModifiers + }; + + struct TextureBlend + { + TextureBlend() : blendMode(LB_Invalid), sourceModifier(SM_Invalid), customNum(0) {} + + //The blend mode to use + BlendMode blendMode; + //The source modification to use + SourceModifier sourceModifier; + // The number of the custom param controlling the source modification + int customNum; + //The parameter controlling the source modification + ParameterPtr modControlParam; + }; + + + /** Class default constructor */ + LayeredBlending(); + + /** + @see SubRenderState::getType. + */ + virtual const Ogre::String& getType () const; + + + /** + Set the blend mode of the given texture unit layer with the previous layer. + @param index The texture unit texture. Textures units (index-1) and (index) will be blended. + @param mode The blend mode to apply. + */ + void setBlendMode(unsigned short index, BlendMode mode); + + /** + Return the blend mode of the given texture unit index. + */ + BlendMode getBlendMode(unsigned short index) const; + + + + /** + Set the source modifier parameters for a given texture unit + @param modType The source modification type to use + @param customNum The custom parameter number used to control the modification + */ + void setSourceModifier(unsigned short index, SourceModifier modType, int customNum); + + /** + Returns the source modifier parameters for a given texture unit + @return True if a valid modifier exist for the given texture unit @param index Texture blend index - @param modType The source modification type to use - @param customNum The custom parameter number used to control the modification - */ - bool getSourceModifier(unsigned short index, SourceModifier& modType, int& customNum) const; + @param modType The source modification type to use + @param customNum The custom parameter number used to control the modification + */ + bool getSourceModifier(unsigned short index, SourceModifier& modType, int& customNum) const; - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); static String Type; @@ -202,54 +202,54 @@ class LayeredBlendingFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, const TextureUnitState* srcTextureUnit, const TextureUnitState* dstTextureUnit); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, const TextureUnitState* srcTextureUnit, const TextureUnitState* dstTextureUnit); protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); - - /** - @Converts string to Enum - */ - LayeredBlending::BlendMode stringToBlendMode(const String &strValue); - /** - @Converts Enum to string - */ - String blendModeToString(LayeredBlending::BlendMode blendMode); - - /** - @Converts string to Enum - */ - LayeredBlending::SourceModifier stringToSourceModifier(const String &strValue); - - /** - @Converts Enum to string - */ - String sourceModifierToString(LayeredBlending::SourceModifier modifier); - - /** - Returns the LayeredBlending sub-rener state previously created for this material/pass. - if no such sub-render state exists creates a new one - @param translator compiler - */ - LayeredBlending* createOrRetrieveSubRenderState(SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); + + /** + @Converts string to Enum + */ + LayeredBlending::BlendMode stringToBlendMode(const String &strValue); + /** + @Converts Enum to string + */ + String blendModeToString(LayeredBlending::BlendMode blendMode); + + /** + @Converts string to Enum + */ + LayeredBlending::SourceModifier stringToSourceModifier(const String &strValue); + + /** + @Converts Enum to string + */ + String sourceModifierToString(LayeredBlending::SourceModifier modifier); + + /** + Returns the LayeredBlending sub-rener state previously created for this material/pass. + if no such sub-render state exists creates a new one + @param translator compiler + */ + LayeredBlending* createOrRetrieveSubRenderState(SGScriptTranslator* translator); }; } // namespace RTShader diff --git a/Components/RTShaderSystem/include/OgreShaderExLinearSkinning.h b/Components/RTShaderSystem/include/OgreShaderExLinearSkinning.h index 179e3904031..dde09637383 100644 --- a/Components/RTShaderSystem/include/OgreShaderExLinearSkinning.h +++ b/Components/RTShaderSystem/include/OgreShaderExLinearSkinning.h @@ -50,41 +50,41 @@ class _OgreRTSSExport LinearSkinning : public HardwareSkinningTechnique { // Interface. public: - /** Class default constructor */ - LinearSkinning(); + /** Class default constructor */ + LinearSkinning(); - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet); + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet); - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet); + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet); - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); protected: - /** Adds functions to calculate position data in world, object and projective space */ - void addPositionCalculations(Function* vsMain, int& funcCounter); - - /** Adds the weight of a given position for a given index */ - void addIndexedPositionWeight(Function* vsMain, int index, int& funcCounter); - - /** Adds the calculations for calculating a normal related element */ - void addNormalRelatedCalculations(Function* vsMain, - ParameterPtr& pNormalRelatedParam, - ParameterPtr& pNormalWorldRelatedParam, - int& funcCounter); - - /** Adds the weight of a given normal related parameter for a given index */ - void addIndexedNormalRelatedWeight(Function* vsMain, ParameterPtr& pNormalRelatedParam, - ParameterPtr& pNormalWorldRelatedParam, - int index, int& funcCounter); + /** Adds functions to calculate position data in world, object and projective space */ + void addPositionCalculations(Function* vsMain, int& funcCounter); + + /** Adds the weight of a given position for a given index */ + void addIndexedPositionWeight(Function* vsMain, int index, int& funcCounter); + + /** Adds the calculations for calculating a normal related element */ + void addNormalRelatedCalculations(Function* vsMain, + ParameterPtr& pNormalRelatedParam, + ParameterPtr& pNormalWorldRelatedParam, + int& funcCounter); + + /** Adds the weight of a given normal related parameter for a given index */ + void addIndexedNormalRelatedWeight(Function* vsMain, ParameterPtr& pNormalRelatedParam, + ParameterPtr& pNormalWorldRelatedParam, + int index, int& funcCounter); }; } diff --git a/Components/RTShaderSystem/include/OgreShaderExNormalMapLighting.h b/Components/RTShaderSystem/include/OgreShaderExNormalMapLighting.h index ec6c4e4e6ef..2fb405ef786 100644 --- a/Components/RTShaderSystem/include/OgreShaderExNormalMapLighting.h +++ b/Components/RTShaderSystem/include/OgreShaderExNormalMapLighting.h @@ -43,17 +43,17 @@ namespace RTShader { * @{ */ -#define SGX_LIB_NORMALMAPLIGHTING "SGXLib_NormalMapLighting" -#define SGX_FUNC_CONSTRUCT_TBNMATRIX "SGX_ConstructTBNMatrix" -#define SGX_FUNC_TRANSFORMNORMAL "SGX_TransformNormal" -#define SGX_FUNC_TRANSFORMPOSITION "SGX_TransformPosition" -#define SGX_FUNC_FETCHNORMAL "SGX_FetchNormal" -#define SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSE "SGX_Light_Directional_Diffuse" -#define SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR "SGX_Light_Directional_DiffuseSpecular" -#define SGX_FUNC_LIGHT_POINT_DIFFUSE "SGX_Light_Point_Diffuse" -#define SGX_FUNC_LIGHT_POINT_DIFFUSESPECULAR "SGX_Light_Point_DiffuseSpecular" -#define SGX_FUNC_LIGHT_SPOT_DIFFUSE "SGX_Light_Spot_Diffuse" -#define SGX_FUNC_LIGHT_SPOT_DIFFUSESPECULAR "SGX_Light_Spot_DiffuseSpecular" +#define SGX_LIB_NORMALMAPLIGHTING "SGXLib_NormalMapLighting" +#define SGX_FUNC_CONSTRUCT_TBNMATRIX "SGX_ConstructTBNMatrix" +#define SGX_FUNC_TRANSFORMNORMAL "SGX_TransformNormal" +#define SGX_FUNC_TRANSFORMPOSITION "SGX_TransformPosition" +#define SGX_FUNC_FETCHNORMAL "SGX_FetchNormal" +#define SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSE "SGX_Light_Directional_Diffuse" +#define SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR "SGX_Light_Directional_DiffuseSpecular" +#define SGX_FUNC_LIGHT_POINT_DIFFUSE "SGX_Light_Point_Diffuse" +#define SGX_FUNC_LIGHT_POINT_DIFFUSESPECULAR "SGX_Light_Point_DiffuseSpecular" +#define SGX_FUNC_LIGHT_SPOT_DIFFUSE "SGX_Light_Spot_Diffuse" +#define SGX_FUNC_LIGHT_SPOT_DIFFUSESPECULAR "SGX_Light_Spot_DiffuseSpecular" /** Normal Map Lighting extension sub render state implementation. Derives from SubRenderState class. @@ -63,338 +63,338 @@ class _OgreRTSSExport NormalMapLighting : public SubRenderState // Interface. public: - /** Class default constructor */ - NormalMapLighting(); - - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; - - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; - - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); - - - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); - - /** - Set the index of the input vertex shader texture coordinate set - */ - void setTexCoordIndex(unsigned int index) { mVSTexCoordSetIndex = index;} - - /** - Return the index of the input vertex shader texture coordinate set. - */ - unsigned int getTexCoordIndex() const { return mVSTexCoordSetIndex; } - - // Type of this render state. - static String Type; - - // Normal map space definition. - enum NormalMapSpace - { - NMS_TANGENT, // Normal map contains normal data in tangent space. - // This is the default normal mapping behavior and it requires that the - // target mesh will have valid tangents within its vertex data. - - NMS_OBJECT // Normal map contains normal data in object local space. - // This normal mapping technique has the advantages of better visualization results, - // lack of artifacts that comes from texture mirroring usage, it doesn't requires tangent - // and it also saves some instruction in the vertex shader stage. - // The main drawback of using this kind of normal map is that the target object must be static - // in terms of local space rotations and translations. - }; - - /** - Set the normal map space. - @param normalMapSpace The normal map space. - */ - void setNormalMapSpace(NormalMapSpace normalMapSpace) { mNormalMapSpace = normalMapSpace; } - - /** Return the normal map space. */ - NormalMapSpace getNormalMapSpace() const { return mNormalMapSpace; } - - /** - Set the normal map texture name. - */ - void setNormalMapTextureName(const String& textureName) { mNormalMapTextureName = textureName; } - - /** - Return the normal map texture name. - */ - const String& getNormalMapTextureName() const { return mNormalMapTextureName; } - - /** - Set the normal map filtering attributes. - @param minFilter The desired min filter. - @param magFilter The desired mag filter. - @param mipFilter The desired mip filter. - */ - void setNormalMapFiltering(const FilterOptions minFilter, const FilterOptions magFilter, const FilterOptions mipFilter) - { mNormalMapMinFilter = minFilter; mNormalMapMagFilter = magFilter; mNormalMapMipFilter = mipFilter; } - - /** - Return the normal map filtering attributes. - @param minFilter The desired min filter. - @param magFilter The desired mag filter. - @param mipFilter The desired mip filter. - */ - void getNormalMapFiltering(FilterOptions& minFilter, FilterOptions& magFilter, FilterOptions& mipFilter) const - { minFilter = mNormalMapMinFilter; magFilter = mNormalMapMagFilter ; mipFilter = mNormalMapMipFilter; } - - /** Setup the normal map anisotropy value. - @param anisotropy The anisotropy value. - */ - void setNormalMapAnisotropy(unsigned int anisotropy) { mNormalMapAnisotropy = anisotropy; } - - - /** Return the normal map anisotropy value. */ - unsigned int getNormalMapAnisotropy() const { return mNormalMapAnisotropy; } - - - /** Setup the normal map map mip bias value. - @param mipBias The map mip bias value. - */ - void setNormalMapMipBias(Real mipBias) { mNormalMapMipBias = mipBias; } - - - /** Return the normal map mip bias value. */ - Real getNormalMapMipBias() const { return mNormalMapMipBias; } + /** Class default constructor */ + NormalMapLighting(); + + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; + + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; + + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); + + + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); + + /** + Set the index of the input vertex shader texture coordinate set + */ + void setTexCoordIndex(unsigned int index) { mVSTexCoordSetIndex = index;} + + /** + Return the index of the input vertex shader texture coordinate set. + */ + unsigned int getTexCoordIndex() const { return mVSTexCoordSetIndex; } + + // Type of this render state. + static String Type; + + // Normal map space definition. + enum NormalMapSpace + { + NMS_TANGENT, // Normal map contains normal data in tangent space. + // This is the default normal mapping behavior and it requires that the + // target mesh will have valid tangents within its vertex data. + + NMS_OBJECT // Normal map contains normal data in object local space. + // This normal mapping technique has the advantages of better visualization results, + // lack of artifacts that comes from texture mirroring usage, it doesn't requires tangent + // and it also saves some instruction in the vertex shader stage. + // The main drawback of using this kind of normal map is that the target object must be static + // in terms of local space rotations and translations. + }; + + /** + Set the normal map space. + @param normalMapSpace The normal map space. + */ + void setNormalMapSpace(NormalMapSpace normalMapSpace) { mNormalMapSpace = normalMapSpace; } + + /** Return the normal map space. */ + NormalMapSpace getNormalMapSpace() const { return mNormalMapSpace; } + + /** + Set the normal map texture name. + */ + void setNormalMapTextureName(const String& textureName) { mNormalMapTextureName = textureName; } + + /** + Return the normal map texture name. + */ + const String& getNormalMapTextureName() const { return mNormalMapTextureName; } + + /** + Set the normal map filtering attributes. + @param minFilter The desired min filter. + @param magFilter The desired mag filter. + @param mipFilter The desired mip filter. + */ + void setNormalMapFiltering(const FilterOptions minFilter, const FilterOptions magFilter, const FilterOptions mipFilter) + { mNormalMapMinFilter = minFilter; mNormalMapMagFilter = magFilter; mNormalMapMipFilter = mipFilter; } + + /** + Return the normal map filtering attributes. + @param minFilter The desired min filter. + @param magFilter The desired mag filter. + @param mipFilter The desired mip filter. + */ + void getNormalMapFiltering(FilterOptions& minFilter, FilterOptions& magFilter, FilterOptions& mipFilter) const + { minFilter = mNormalMapMinFilter; magFilter = mNormalMapMagFilter ; mipFilter = mNormalMapMipFilter; } + + /** Setup the normal map anisotropy value. + @param anisotropy The anisotropy value. + */ + void setNormalMapAnisotropy(unsigned int anisotropy) { mNormalMapAnisotropy = anisotropy; } + + + /** Return the normal map anisotropy value. */ + unsigned int getNormalMapAnisotropy() const { return mNormalMapAnisotropy; } + + + /** Setup the normal map map mip bias value. + @param mipBias The map mip bias value. + */ + void setNormalMapMipBias(Real mipBias) { mNormalMapMipBias = mipBias; } + + + /** Return the normal map mip bias value. */ + Real getNormalMapMipBias() const { return mNormalMapMipBias; } // Protected types: protected: - - // Per light parameters. - struct _OgreRTSSExport LightParams - { - // Light type. - Light::LightTypes mType; - // Light position. - UniformParameterPtr mPosition; - // Vertex shader output vertex position to light position direction (texture space). - ParameterPtr mVSOutToLightDir; - // Pixel shader input vertex position to light position direction (texture space). - ParameterPtr mPSInToLightDir; - // Light direction. - UniformParameterPtr mDirection; - // Vertex shader output light direction (texture space). - ParameterPtr mVSOutDirection; - // Pixel shader input light direction (texture space). - ParameterPtr mPSInDirection; - // Attenuation parameters. - UniformParameterPtr mAttenuatParams; - // Spot light parameters. - UniformParameterPtr mSpotParams; - // Diffuse colour. - UniformParameterPtr mDiffuseColour; - // Specular colour. - UniformParameterPtr mSpecularColour; - - }; - - typedef vector::type LightParamsList; - typedef LightParamsList::iterator LightParamsIterator; - typedef LightParamsList::const_iterator LightParamsConstIterator; + + // Per light parameters. + struct _OgreRTSSExport LightParams + { + // Light type. + Light::LightTypes mType; + // Light position. + UniformParameterPtr mPosition; + // Vertex shader output vertex position to light position direction (texture space). + ParameterPtr mVSOutToLightDir; + // Pixel shader input vertex position to light position direction (texture space). + ParameterPtr mPSInToLightDir; + // Light direction. + UniformParameterPtr mDirection; + // Vertex shader output light direction (texture space). + ParameterPtr mVSOutDirection; + // Pixel shader input light direction (texture space). + ParameterPtr mPSInDirection; + // Attenuation parameters. + UniformParameterPtr mAttenuatParams; + // Spot light parameters. + UniformParameterPtr mSpotParams; + // Diffuse colour. + UniformParameterPtr mDiffuseColour; + // Specular colour. + UniformParameterPtr mSpecularColour; + + }; + + typedef vector::type LightParamsList; + typedef LightParamsList::iterator LightParamsIterator; + typedef LightParamsList::const_iterator LightParamsConstIterator; // Protected methods protected: - /** - Set the track per vertex colour type. Ambient, Diffuse, Specular and Emissive lighting components source - can be the vertex colour component. To establish such a link one should provide the matching flags to this - sub render state. - */ - void setTrackVertexColourType(TrackVertexColourType type) { mTrackVertexColourType = type; } - - /** - Return the current track per vertex type. - */ - TrackVertexColourType getTrackVertexColourType() const { return mTrackVertexColourType; } - - - /** - Set the light count per light type that this sub render state will generate. - @see ShaderGenerator::setLightCount. - */ - void setLightCount(const int lightCount[3]); - - /** - Get the light count per light type that this sub render state will generate. - @see ShaderGenerator::getLightCount. - */ - void getLightCount(int lightCount[3]) const; - /** - Set the specular component state. If set to true this sub render state will compute a specular - lighting component in addition to the diffuse component. - @param enable Pass true to enable specular component computation. - */ - void setSpecularEnable(bool enable) { mSpecularEnable = enable; } - - /** - Get the specular component state. - */ - bool getSpecularEnable() const { return mSpecularEnable; } - - - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet); - - /** Resolve global lighting parameters */ - bool resolveGlobalParameters(ProgramSet* programSet); - - /** Resolve per light parameters */ - bool resolvePerLightParameters(ProgramSet* programSet); - - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet); - - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); - - - /** - Internal method that adds related vertex shader functions invocations. - */ - bool addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter); - - /** - Internal method that adds per light illumination component functions invocations. - */ - bool addVSIlluminationInvocation(LightParams* curLightParams, Function* vsMain, const int groupOrder, int& internalCounter); - - /** - Internal method that perform normal fetch invocation. - */ - bool addPSNormalFetchInvocation(Function* psMain, const int groupOrder, int& internalCounter); - - - /** - Internal method that adds global illumination component functions invocations. - */ - bool addPSGlobalIlluminationInvocation(Function* psMain, const int groupOrder, int& internalCounter); - - /** - Internal method that adds per light illumination component functions invocations. - */ - bool addPSIlluminationInvocation(LightParams* curLightParams, Function* psMain, const int groupOrder, int& internalCounter); - - /** - Internal method that adds the final colour assignments. - */ - bool addPSFinalAssignmentInvocation(Function* psMain, const int groupOrder, int& internalCounter); + /** + Set the track per vertex colour type. Ambient, Diffuse, Specular and Emissive lighting components source + can be the vertex colour component. To establish such a link one should provide the matching flags to this + sub render state. + */ + void setTrackVertexColourType(TrackVertexColourType type) { mTrackVertexColourType = type; } + + /** + Return the current track per vertex type. + */ + TrackVertexColourType getTrackVertexColourType() const { return mTrackVertexColourType; } + + + /** + Set the light count per light type that this sub render state will generate. + @see ShaderGenerator::setLightCount. + */ + void setLightCount(const int lightCount[3]); + + /** + Get the light count per light type that this sub render state will generate. + @see ShaderGenerator::getLightCount. + */ + void getLightCount(int lightCount[3]) const; + /** + Set the specular component state. If set to true this sub render state will compute a specular + lighting component in addition to the diffuse component. + @param enable Pass true to enable specular component computation. + */ + void setSpecularEnable(bool enable) { mSpecularEnable = enable; } + + /** + Get the specular component state. + */ + bool getSpecularEnable() const { return mSpecularEnable; } + + + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet); + + /** Resolve global lighting parameters */ + bool resolveGlobalParameters(ProgramSet* programSet); + + /** Resolve per light parameters */ + bool resolvePerLightParameters(ProgramSet* programSet); + + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet); + + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); + + + /** + Internal method that adds related vertex shader functions invocations. + */ + bool addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter); + + /** + Internal method that adds per light illumination component functions invocations. + */ + bool addVSIlluminationInvocation(LightParams* curLightParams, Function* vsMain, const int groupOrder, int& internalCounter); + + /** + Internal method that perform normal fetch invocation. + */ + bool addPSNormalFetchInvocation(Function* psMain, const int groupOrder, int& internalCounter); + + + /** + Internal method that adds global illumination component functions invocations. + */ + bool addPSGlobalIlluminationInvocation(Function* psMain, const int groupOrder, int& internalCounter); + + /** + Internal method that adds per light illumination component functions invocations. + */ + bool addPSIlluminationInvocation(LightParams* curLightParams, Function* psMain, const int groupOrder, int& internalCounter); + + /** + Internal method that adds the final colour assignments. + */ + bool addPSFinalAssignmentInvocation(Function* psMain, const int groupOrder, int& internalCounter); // Attributes. -protected: - // The normal map texture name. - String mNormalMapTextureName; - // Track per vertex colour type. - TrackVertexColourType mTrackVertexColourType; - // Specular component enabled/disabled. - bool mSpecularEnable; - // Light list. - LightParamsList mLightParamsList; - // Normal map texture sampler index. - unsigned short mNormalMapSamplerIndex; - // Vertex shader input texture coordinate set index. - unsigned int mVSTexCoordSetIndex; - // The normal map min filter. - FilterOptions mNormalMapMinFilter; - // The normal map mag filter. - FilterOptions mNormalMapMagFilter; - // The normal map mip filter. - FilterOptions mNormalMapMipFilter; - // The normal map max anisotropy value. - unsigned int mNormalMapAnisotropy; - // The normal map mip map bias. - Real mNormalMapMipBias; - // The normal map space. - NormalMapSpace mNormalMapSpace; - // World matrix parameter. - UniformParameterPtr mWorldMatrix; - // World matrix inverse rotation matrix parameter. - UniformParameterPtr mWorldInvRotMatrix; - // Camera position in world space parameter. - UniformParameterPtr mCamPosWorldSpace; - // Vertex shader input position parameter. - ParameterPtr mVSInPosition; - // Vertex shader world position parameter. - ParameterPtr mVSWorldPosition; - // Vertex shader output view vector (position in camera space) parameter. - ParameterPtr mVSOutView; - // Pixel shader input view position (position in camera space) parameter. - ParameterPtr mPSInView; - // Vertex shader input normal. - ParameterPtr mVSInNormal; - // Vertex shader input tangent. - ParameterPtr mVSInTangent; - // Vertex shader local TNB matrix. - ParameterPtr mVSTBNMatrix; - // Vertex shader local light direction. - ParameterPtr mVSLocalDir; - // Normal map texture sampler parameter. - UniformParameterPtr mNormalMapSampler; - // Pixel shader normal parameter. - ParameterPtr mPSNormal; - // Vertex shader input texture coordinates. - ParameterPtr mVSInTexcoord; - // Vertex shader output texture coordinates. - ParameterPtr mVSOutTexcoord; - // Pixel shader input texture coordinates. - ParameterPtr mPSInTexcoord; - // Pixel shader temporary diffuse calculation parameter. - ParameterPtr mPSTempDiffuseColour; - // Pixel shader temporary specular calculation parameter. - ParameterPtr mPSTempSpecularColour; - // Pixel shader input/local diffuse parameter. - ParameterPtr mPSDiffuse; - // Pixel shader input/local specular parameter. - ParameterPtr mPSSpecular; - // Pixel shader output diffuse parameter. - ParameterPtr mPSOutDiffuse; - // Pixel shader output specular parameter. - ParameterPtr mPSOutSpecular; - // Derived scene colour parameter. - UniformParameterPtr mDerivedSceneColour; - // Ambient light colour parameter. - UniformParameterPtr mLightAmbientColour; - // Derived ambient light colour parameter. - UniformParameterPtr mDerivedAmbientLightColour; - // Surface ambient colour parameter. - UniformParameterPtr mSurfaceAmbientColour; - // Surface diffuse colour parameter. - UniformParameterPtr mSurfaceDiffuseColour; - // Surface specular colour parameter. - UniformParameterPtr mSurfaceSpecularColour; - // Surface emissive colour parameter. - UniformParameterPtr mSurfaceEmissiveColour; - // Surface shininess parameter. - UniformParameterPtr mSurfaceShininess; - // Shared blank light. - static Light msBlankLight; +protected: + // The normal map texture name. + String mNormalMapTextureName; + // Track per vertex colour type. + TrackVertexColourType mTrackVertexColourType; + // Specular component enabled/disabled. + bool mSpecularEnable; + // Light list. + LightParamsList mLightParamsList; + // Normal map texture sampler index. + unsigned short mNormalMapSamplerIndex; + // Vertex shader input texture coordinate set index. + unsigned int mVSTexCoordSetIndex; + // The normal map min filter. + FilterOptions mNormalMapMinFilter; + // The normal map mag filter. + FilterOptions mNormalMapMagFilter; + // The normal map mip filter. + FilterOptions mNormalMapMipFilter; + // The normal map max anisotropy value. + unsigned int mNormalMapAnisotropy; + // The normal map mip map bias. + Real mNormalMapMipBias; + // The normal map space. + NormalMapSpace mNormalMapSpace; + // World matrix parameter. + UniformParameterPtr mWorldMatrix; + // World matrix inverse rotation matrix parameter. + UniformParameterPtr mWorldInvRotMatrix; + // Camera position in world space parameter. + UniformParameterPtr mCamPosWorldSpace; + // Vertex shader input position parameter. + ParameterPtr mVSInPosition; + // Vertex shader world position parameter. + ParameterPtr mVSWorldPosition; + // Vertex shader output view vector (position in camera space) parameter. + ParameterPtr mVSOutView; + // Pixel shader input view position (position in camera space) parameter. + ParameterPtr mPSInView; + // Vertex shader input normal. + ParameterPtr mVSInNormal; + // Vertex shader input tangent. + ParameterPtr mVSInTangent; + // Vertex shader local TNB matrix. + ParameterPtr mVSTBNMatrix; + // Vertex shader local light direction. + ParameterPtr mVSLocalDir; + // Normal map texture sampler parameter. + UniformParameterPtr mNormalMapSampler; + // Pixel shader normal parameter. + ParameterPtr mPSNormal; + // Vertex shader input texture coordinates. + ParameterPtr mVSInTexcoord; + // Vertex shader output texture coordinates. + ParameterPtr mVSOutTexcoord; + // Pixel shader input texture coordinates. + ParameterPtr mPSInTexcoord; + // Pixel shader temporary diffuse calculation parameter. + ParameterPtr mPSTempDiffuseColour; + // Pixel shader temporary specular calculation parameter. + ParameterPtr mPSTempSpecularColour; + // Pixel shader input/local diffuse parameter. + ParameterPtr mPSDiffuse; + // Pixel shader input/local specular parameter. + ParameterPtr mPSSpecular; + // Pixel shader output diffuse parameter. + ParameterPtr mPSOutDiffuse; + // Pixel shader output specular parameter. + ParameterPtr mPSOutSpecular; + // Derived scene colour parameter. + UniformParameterPtr mDerivedSceneColour; + // Ambient light colour parameter. + UniformParameterPtr mLightAmbientColour; + // Derived ambient light colour parameter. + UniformParameterPtr mDerivedAmbientLightColour; + // Surface ambient colour parameter. + UniformParameterPtr mSurfaceAmbientColour; + // Surface diffuse colour parameter. + UniformParameterPtr mSurfaceDiffuseColour; + // Surface specular colour parameter. + UniformParameterPtr mSurfaceSpecularColour; + // Surface emissive colour parameter. + UniformParameterPtr mSurfaceEmissiveColour; + // Surface shininess parameter. + UniformParameterPtr mSurfaceShininess; + // Shared blank light. + static Light msBlankLight; }; @@ -406,28 +406,28 @@ class _OgreRTSSExport NormalMapLightingFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); - + protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); }; diff --git a/Components/RTShaderSystem/include/OgreShaderExPerPixelLighting.h b/Components/RTShaderSystem/include/OgreShaderExPerPixelLighting.h index 639ae980f91..26bebf9da0b 100644 --- a/Components/RTShaderSystem/include/OgreShaderExPerPixelLighting.h +++ b/Components/RTShaderSystem/include/OgreShaderExPerPixelLighting.h @@ -43,15 +43,15 @@ namespace RTShader { * @{ */ -#define SGX_LIB_PERPIXELLIGHTING "SGXLib_PerPixelLighting" -#define SGX_FUNC_TRANSFORMNORMAL "SGX_TransformNormal" -#define SGX_FUNC_TRANSFORMPOSITION "SGX_TransformPosition" -#define SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSE "SGX_Light_Directional_Diffuse" -#define SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR "SGX_Light_Directional_DiffuseSpecular" -#define SGX_FUNC_LIGHT_POINT_DIFFUSE "SGX_Light_Point_Diffuse" -#define SGX_FUNC_LIGHT_POINT_DIFFUSESPECULAR "SGX_Light_Point_DiffuseSpecular" -#define SGX_FUNC_LIGHT_SPOT_DIFFUSE "SGX_Light_Spot_Diffuse" -#define SGX_FUNC_LIGHT_SPOT_DIFFUSESPECULAR "SGX_Light_Spot_DiffuseSpecular" +#define SGX_LIB_PERPIXELLIGHTING "SGXLib_PerPixelLighting" +#define SGX_FUNC_TRANSFORMNORMAL "SGX_TransformNormal" +#define SGX_FUNC_TRANSFORMPOSITION "SGX_TransformPosition" +#define SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSE "SGX_Light_Directional_Diffuse" +#define SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR "SGX_Light_Directional_DiffuseSpecular" +#define SGX_FUNC_LIGHT_POINT_DIFFUSE "SGX_Light_Point_Diffuse" +#define SGX_FUNC_LIGHT_POINT_DIFFUSESPECULAR "SGX_Light_Point_DiffuseSpecular" +#define SGX_FUNC_LIGHT_SPOT_DIFFUSE "SGX_Light_Spot_Diffuse" +#define SGX_FUNC_LIGHT_SPOT_DIFFUSESPECULAR "SGX_Light_Spot_DiffuseSpecular" /** Per pixel Lighting extension sub render state implementation. Derives from SubRenderState class. @@ -61,203 +61,203 @@ class _OgreRTSSExport PerPixelLighting : public SubRenderState // Interface. public: - /** Class default constructor */ - PerPixelLighting(); + /** Class default constructor */ + PerPixelLighting(); - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); - - static String Type; + + static String Type; // Protected types: protected: - - // Per light parameters. - struct _OgreRTSSExport LightParams - { - Light::LightTypes mType; // Light type. - // Light position. - UniformParameterPtr mPosition; - // Light direction. - UniformParameterPtr mDirection; - // Attenuation parameters. - UniformParameterPtr mAttenuatParams; - // Spot light parameters. - UniformParameterPtr mSpotParams; - // Diffuse colour. - UniformParameterPtr mDiffuseColour; - // Specular colour. - UniformParameterPtr mSpecularColour; - - }; - - typedef vector::type LightParamsList; - typedef LightParamsList::iterator LightParamsIterator; - typedef LightParamsList::const_iterator LightParamsConstIterator; + + // Per light parameters. + struct _OgreRTSSExport LightParams + { + Light::LightTypes mType; // Light type. + // Light position. + UniformParameterPtr mPosition; + // Light direction. + UniformParameterPtr mDirection; + // Attenuation parameters. + UniformParameterPtr mAttenuatParams; + // Spot light parameters. + UniformParameterPtr mSpotParams; + // Diffuse colour. + UniformParameterPtr mDiffuseColour; + // Specular colour. + UniformParameterPtr mSpecularColour; + + }; + + typedef vector::type LightParamsList; + typedef LightParamsList::iterator LightParamsIterator; + typedef LightParamsList::const_iterator LightParamsConstIterator; // Protected methods protected: - /** - Set the track per vertex colour type. Ambient, Diffuse, Specular and Emissive lighting components source - can be the vertex colour component. To establish such a link one should provide the matching flags to this - sub render state. - */ - void setTrackVertexColourType(TrackVertexColourType type) { mTrackVertexColourType = type; } - - /** - Return the current track per vertex type. - */ - TrackVertexColourType getTrackVertexColourType() const { return mTrackVertexColourType; } - - - /** - Set the light count per light type that this sub render state will generate. - @see ShaderGenerator::setLightCount. - */ - void setLightCount(const int lightCount[3]); - - /** - Get the light count per light type that this sub render state will generate. - @see ShaderGenerator::getLightCount. - */ - void getLightCount(int lightCount[3]) const; - /** - Set the specular component state. If set to true this sub render state will compute a specular - lighting component in addition to the diffuse component. - @param enable Pass true to enable specular component computation. - */ - void setSpecularEnable(bool enable) { mSpecularEnable = enable; } - - /** - Get the specular component state. - */ - bool getSpecularEnable() const { return mSpecularEnable; } - - - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet); - - /** Resolve global lighting parameters */ - bool resolveGlobalParameters(ProgramSet* programSet); - - /** Resolve per light parameters */ - bool resolvePerLightParameters(ProgramSet* programSet); - - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet); - - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); - - - /** - Internal method that adds related vertex shader functions invocations. - */ - bool addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter); - - - /** - Internal method that adds global illumination component functions invocations. - */ - bool addPSGlobalIlluminationInvocation(Function* psMain, const int groupOrder, int& internalCounter); - - /** - Internal method that adds per light illumination component functions invocations. - */ - bool addPSIlluminationInvocation(LightParams* curLightParams, Function* psMain, const int groupOrder, int& internalCounter); - - /** - Internal method that adds the final colour assignments. - */ - bool addPSFinalAssignmentInvocation(Function* psMain, const int groupOrder, int& internalCounter); + /** + Set the track per vertex colour type. Ambient, Diffuse, Specular and Emissive lighting components source + can be the vertex colour component. To establish such a link one should provide the matching flags to this + sub render state. + */ + void setTrackVertexColourType(TrackVertexColourType type) { mTrackVertexColourType = type; } + + /** + Return the current track per vertex type. + */ + TrackVertexColourType getTrackVertexColourType() const { return mTrackVertexColourType; } + + + /** + Set the light count per light type that this sub render state will generate. + @see ShaderGenerator::setLightCount. + */ + void setLightCount(const int lightCount[3]); + + /** + Get the light count per light type that this sub render state will generate. + @see ShaderGenerator::getLightCount. + */ + void getLightCount(int lightCount[3]) const; + /** + Set the specular component state. If set to true this sub render state will compute a specular + lighting component in addition to the diffuse component. + @param enable Pass true to enable specular component computation. + */ + void setSpecularEnable(bool enable) { mSpecularEnable = enable; } + + /** + Get the specular component state. + */ + bool getSpecularEnable() const { return mSpecularEnable; } + + + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet); + + /** Resolve global lighting parameters */ + bool resolveGlobalParameters(ProgramSet* programSet); + + /** Resolve per light parameters */ + bool resolvePerLightParameters(ProgramSet* programSet); + + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet); + + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); + + + /** + Internal method that adds related vertex shader functions invocations. + */ + bool addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter); + + + /** + Internal method that adds global illumination component functions invocations. + */ + bool addPSGlobalIlluminationInvocation(Function* psMain, const int groupOrder, int& internalCounter); + + /** + Internal method that adds per light illumination component functions invocations. + */ + bool addPSIlluminationInvocation(LightParams* curLightParams, Function* psMain, const int groupOrder, int& internalCounter); + + /** + Internal method that adds the final colour assignments. + */ + bool addPSFinalAssignmentInvocation(Function* psMain, const int groupOrder, int& internalCounter); // Attributes. -protected: - // Track per vertex colour type. - TrackVertexColourType mTrackVertexColourType; - // Specular component enabled/disabled. - bool mSpecularEnable; - // Light list. - LightParamsList mLightParamsList; - // World view matrix parameter. - UniformParameterPtr mWorldViewMatrix; - // World view matrix inverse transpose parameter. - UniformParameterPtr mWorldViewITMatrix; - // Vertex shader input position parameter. - ParameterPtr mVSInPosition; - // Vertex shader output view position (position in camera space) parameter. - ParameterPtr mVSOutViewPos; - // Pixel shader input view position (position in camera space) parameter. - ParameterPtr mPSInViewPos; - // Vertex shader input normal. - ParameterPtr mVSInNormal; - // Vertex shader output normal. - ParameterPtr mVSOutNormal; - // Pixel shader input normal. - ParameterPtr mPSInNormal; - // Pixel shader temporary diffuse calculation parameter. - ParameterPtr mPSTempDiffuseColour; - // Pixel shader temporary specular calculation parameter. - ParameterPtr mPSTempSpecularColour; - // Pixel shader input/local diffuse parameter. - ParameterPtr mPSDiffuse; - // Pixel shader input/local specular parameter. - ParameterPtr mPSSpecular; - // Pixel shader output diffuse parameter. - ParameterPtr mPSOutDiffuse; - // Pixel shader output specular parameter. - ParameterPtr mPSOutSpecular; - // Derived scene colour parameter. - UniformParameterPtr mDerivedSceneColour; - // Ambient light colour parameter. - UniformParameterPtr mLightAmbientColour; - // Derived ambient light colour parameter. - UniformParameterPtr mDerivedAmbientLightColour; - // Surface ambient colour parameter. - UniformParameterPtr mSurfaceAmbientColour; - // Surface diffuse colour parameter. - UniformParameterPtr mSurfaceDiffuseColour; - // Surface specular colour parameter. - UniformParameterPtr mSurfaceSpecularColour; - // Surface emissive colour parameter. - UniformParameterPtr mSurfaceEmissiveColour; - // Surface shininess parameter. - UniformParameterPtr mSurfaceShininess; - // Shared blank light. - static Light msBlankLight; +protected: + // Track per vertex colour type. + TrackVertexColourType mTrackVertexColourType; + // Specular component enabled/disabled. + bool mSpecularEnable; + // Light list. + LightParamsList mLightParamsList; + // World view matrix parameter. + UniformParameterPtr mWorldViewMatrix; + // World view matrix inverse transpose parameter. + UniformParameterPtr mWorldViewITMatrix; + // Vertex shader input position parameter. + ParameterPtr mVSInPosition; + // Vertex shader output view position (position in camera space) parameter. + ParameterPtr mVSOutViewPos; + // Pixel shader input view position (position in camera space) parameter. + ParameterPtr mPSInViewPos; + // Vertex shader input normal. + ParameterPtr mVSInNormal; + // Vertex shader output normal. + ParameterPtr mVSOutNormal; + // Pixel shader input normal. + ParameterPtr mPSInNormal; + // Pixel shader temporary diffuse calculation parameter. + ParameterPtr mPSTempDiffuseColour; + // Pixel shader temporary specular calculation parameter. + ParameterPtr mPSTempSpecularColour; + // Pixel shader input/local diffuse parameter. + ParameterPtr mPSDiffuse; + // Pixel shader input/local specular parameter. + ParameterPtr mPSSpecular; + // Pixel shader output diffuse parameter. + ParameterPtr mPSOutDiffuse; + // Pixel shader output specular parameter. + ParameterPtr mPSOutSpecular; + // Derived scene colour parameter. + UniformParameterPtr mDerivedSceneColour; + // Ambient light colour parameter. + UniformParameterPtr mLightAmbientColour; + // Derived ambient light colour parameter. + UniformParameterPtr mDerivedAmbientLightColour; + // Surface ambient colour parameter. + UniformParameterPtr mSurfaceAmbientColour; + // Surface diffuse colour parameter. + UniformParameterPtr mSurfaceDiffuseColour; + // Surface specular colour parameter. + UniformParameterPtr mSurfaceSpecularColour; + // Surface emissive colour parameter. + UniformParameterPtr mSurfaceEmissiveColour; + // Surface shininess parameter. + UniformParameterPtr mSurfaceShininess; + // Shared blank light. + static Light msBlankLight; }; @@ -269,28 +269,28 @@ class _OgreRTSSExport PerPixelLightingFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); - + protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); }; diff --git a/Components/RTShaderSystem/include/OgreShaderExTextureAtlasSampler.h b/Components/RTShaderSystem/include/OgreShaderExTextureAtlasSampler.h index 6da304008bb..242e7579db7 100644 --- a/Components/RTShaderSystem/include/OgreShaderExTextureAtlasSampler.h +++ b/Components/RTShaderSystem/include/OgreShaderExTextureAtlasSampler.h @@ -43,25 +43,25 @@ namespace RTShader { */ struct _OgreRTSSExport TextureAtlasRecord { - TextureAtlasRecord(const String & texOriginalName, const String & texAtlasName, - const float texPosU, const float texPosV, const float texWidth, const float texHeight, + TextureAtlasRecord(const String & texOriginalName, const String & texAtlasName, + const float texPosU, const float texPosV, const float texWidth, const float texHeight, const size_t texIndexInAtlas) : - posU(texPosU) - , posV(texPosV) - , width(texWidth) - , height(texHeight) + posU(texPosU) + , posV(texPosV) + , width(texWidth) + , height(texHeight) , originalTextureName(texOriginalName) , atlasTextureName(texAtlasName) - , indexInAtlas(texIndexInAtlas) - { } - - float posU; - float posV; - float width; - float height; - String originalTextureName; - String atlasTextureName; - size_t indexInAtlas; + , indexInAtlas(texIndexInAtlas) + { } + + float posU; + float posV; + float width; + float height; + String originalTextureName; + String atlasTextureName; + size_t indexInAtlas; }; typedef vector::type TextureAtlasTable; @@ -96,9 +96,9 @@ might can be placed either relative or in absolute position. For example: - given 3 texture sand a relative position of 2, the shader will search assume - that the indexes exist in texture coordinate 5 (2+3) + that the indexes exist in texture coordinate 5 (2+3) - given an absolute position of 2, the shader will search for the indexes in - texture coordinate 2, regardless of the amount of textures + texture coordinate 2, regardless of the amount of textures The position of the indexes can be controlled globally through the TextureAtlasSamplerFactory class using the function setTableIndexPosition @@ -117,11 +117,11 @@ edges, especially in lower mipmaps pixel color from other images may be mixed in There are 3 ways to handle this issue, each with it's own limitations: -# Ignore the problem - bad for repetitive images in which the border colour may be quite apparent. -# Auto adjust the polling position - This the default implementation of the TextureAtlasSampler SRS. - Auto adjust the polling position in the shader according the mipmap level in use. This means that - a different (smaller) section of an image may be polled instead of the original section (especially - with in mipmaps). Bad for non repetitive accurate images. + Auto adjust the polling position in the shader according the mipmap level in use. This means that + a different (smaller) section of an image may be polled instead of the original section (especially + with in mipmaps). Bad for non repetitive accurate images. -# Generate a texture atlas where each image will contain around it a wrapped version of itself. - This solves all visual problems but is wasteful in gpu memory (up to 3 times the size of the original image) + This solves all visual problems but is wasteful in gpu memory (up to 3 times the size of the original image) You can use the NVidia "Texture Atlas Tools" to create the texture. @@ -133,74 +133,74 @@ class _OgreRTSSExport TextureAtlasSampler : public SubRenderState // Interface. public: - /** Class default constructor */ - TextureAtlasSampler(); + /** Class default constructor */ + TextureAtlasSampler(); - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); - static String Type; + static String Type; // Protected methods -protected: - virtual bool resolveParameters(ProgramSet* programSet); - virtual bool resolveDependencies(ProgramSet* programSet); - virtual bool addFunctionInvocations(ProgramSet* programSet); +protected: + virtual bool resolveParameters(ProgramSet* programSet); + virtual bool resolveDependencies(ProgramSet* programSet); + virtual bool addFunctionInvocations(ProgramSet* programSet); - /** - Given an address mode returns the function name which calculates the UV values for that addressing mode - */ - const char* getAdressingFunctionName(TextureUnitState::TextureAddressingMode mode); + /** + Given an address mode returns the function name which calculates the UV values for that addressing mode + */ + const char* getAdressingFunctionName(TextureUnitState::TextureAddressingMode mode); // Attributes. protected: - /// The index of the information on the texture in the table - ParameterPtr mVSInpTextureTableIndex; - + /// The index of the information on the texture in the table + ParameterPtr mVSInpTextureTableIndex; + /// The addressing mode for each texture - TextureUnitState::UVWAddressingMode mTextureAddressings[TAS_MAX_TEXTURES]; - /// The position and size of the texture in the atlas - ParameterPtr mVSOutTextureDatas[TAS_MAX_TEXTURES]; - /// The position and size of the texture in the atlas - ParameterPtr mPSInpTextureDatas[TAS_MAX_TEXTURES]; - /// A parameter carrying the sizes of the atlas textures - UniformParameterPtr mPSTextureSizes[TAS_MAX_TEXTURES]; - /// The table containing information on the textures in the atlas - UniformParameterPtr mVSTextureTable[TAS_MAX_TEXTURES]; - - /// The position of the texture coordinates containing the index information - ushort mAtlasTexcoordPos; - /// The texture atlas table data - TextureAtlasTablePtr mAtlasTableDatas[TAS_MAX_TEXTURES]; - /// For each texture unit in the pass tells if it uses atlas texture - bool mIsAtlasTextureUnits[TAS_MAX_TEXTURES]; - /// Tells if the data in mAtlasTableData has been uploaded to the corresponding mVSTextureTable parameter - bool mIsTableDataUpdated; - /// Tells whether border issue handling uses auto adjust polling position. - bool mAutoAdjustPollPosition; + TextureUnitState::UVWAddressingMode mTextureAddressings[TAS_MAX_TEXTURES]; + /// The position and size of the texture in the atlas + ParameterPtr mVSOutTextureDatas[TAS_MAX_TEXTURES]; + /// The position and size of the texture in the atlas + ParameterPtr mPSInpTextureDatas[TAS_MAX_TEXTURES]; + /// A parameter carrying the sizes of the atlas textures + UniformParameterPtr mPSTextureSizes[TAS_MAX_TEXTURES]; + /// The table containing information on the textures in the atlas + UniformParameterPtr mVSTextureTable[TAS_MAX_TEXTURES]; + + /// The position of the texture coordinates containing the index information + ushort mAtlasTexcoordPos; + /// The texture atlas table data + TextureAtlasTablePtr mAtlasTableDatas[TAS_MAX_TEXTURES]; + /// For each texture unit in the pass tells if it uses atlas texture + bool mIsAtlasTextureUnits[TAS_MAX_TEXTURES]; + /// Tells if the data in mAtlasTableData has been uploaded to the corresponding mVSTextureTable parameter + bool mIsTableDataUpdated; + /// Tells whether border issue handling uses auto adjust polling position. + bool mAutoAdjustPollPosition; }; @@ -212,164 +212,164 @@ A factory that enables creation of TextureAtlasSampler instances. class _OgreRTSSExport TextureAtlasSamplerFactory : public SubRenderStateFactory, public Singleton { public: - enum IndexPositionMode - { - ipmRelative, - ipmAbsolute - }; - - struct TextureAtlasAttib - { - TextureAtlasAttib(IndexPositionMode _posMode = ipmRelative, ushort _posOffset = 1, - bool _autoBorderAdjust = true) : positionMode(_posMode), positionOffset(_posOffset), - autoBorderAdjust(_autoBorderAdjust) {} - - IndexPositionMode positionMode; - ushort positionOffset; - bool autoBorderAdjust; - }; + enum IndexPositionMode + { + ipmRelative, + ipmAbsolute + }; + + struct TextureAtlasAttib + { + TextureAtlasAttib(IndexPositionMode _posMode = ipmRelative, ushort _posOffset = 1, + bool _autoBorderAdjust = true) : positionMode(_posMode), positionOffset(_posOffset), + autoBorderAdjust(_autoBorderAdjust) {} + + IndexPositionMode positionMode; + ushort positionOffset; + bool autoBorderAdjust; + }; public: - //TextureAtlasSamplerFactory c_tor - TextureAtlasSamplerFactory(); - - //Singleton implementation - static TextureAtlasSamplerFactory* getSingletonPtr(void); - static TextureAtlasSamplerFactory& getSingleton(void); - - - - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; - - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); - - /** - Adds a texture atlas definition from a stream. - - This function loads a texture atlas definition file from a stream. The accepted format for - this file is the NVidia Texture Atlas Tools ".tai" file format. This file as - - The ".tai" format consist of lines, where each line corresponds to a specific texture - in the texture atlas. Each line has the following format: - # /t/t, , , , , , , - - @param filename The full path to the file containing a ".tai" format data. - @param textureAtlasTable A table into which the data in the stream will be filled. This - parameter will be filled only if it is not null. The system factory keeps a copy of this - information in any case. - */ - bool addTexutreAtlasDefinition( const Ogre::String& filename, TextureAtlasTablePtr textureAtlasTable = TextureAtlasTablePtr()); + //TextureAtlasSamplerFactory c_tor + TextureAtlasSamplerFactory(); + + //Singleton implementation + static TextureAtlasSamplerFactory* getSingletonPtr(void); + static TextureAtlasSamplerFactory& getSingleton(void); + + + + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; + + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + + /** + Adds a texture atlas definition from a stream. + + This function loads a texture atlas definition file from a stream. The accepted format for + this file is the NVidia Texture Atlas Tools ".tai" file format. This file as + + The ".tai" format consist of lines, where each line corresponds to a specific texture + in the texture atlas. Each line has the following format: + # /t/t, , , , , , , + + @param filename The full path to the file containing a ".tai" format data. + @param textureAtlasTable A table into which the data in the stream will be filled. This + parameter will be filled only if it is not null. The system factory keeps a copy of this + information in any case. + */ + bool addTexutreAtlasDefinition( const Ogre::String& filename, TextureAtlasTablePtr textureAtlasTable = TextureAtlasTablePtr()); + /** + Adds a texture atlas definition from a stream. + + This function loads a texture atlas definition file from a stream. The accepted format for + this file is the NVidia Texture Atlas Tools ".tai" file format. This file as + + The ".tai" format consist of lines, where each line corresponds to a specific texture + in the texture atlas. Each line has the following format: + # /t/t, , , , , , , + + @param stream A stream to a file containing ".tai" format data + @param textureAtlasTable A table into which the data in the stream will be filled. This + parameter will be filled only if it is not null. The system factory keeps a copy of this + information in any case. + */ + bool addTexutreAtlasDefinition( DataStreamPtr stream, TextureAtlasTablePtr textureAtlasTable = TextureAtlasTablePtr()); + + /** + Set the texture atlas information for a given texture + @param textureName Name of an atlas texture + @param atlasData A list of records containing the position and size of each + texture in the atlas + @param autoBorderAdjust Sets whether to automatically adjust the image polling area for border + issues.See the Border issues paragraph under the class documentation for more information. + */ + void setTextureAtlasTable(const String& textureName, const TextureAtlasTablePtr& atlasData, bool autoBorderAdjust = true); + + /** + Removes the texture atlas information from a given texture + @param textureName Name of an atlas texture + */ + void removeTextureAtlasTable(const String& textureName); + + /** + Removes all texture atlas table information + */ + void removeAllTextureAtlasTables(); + + /** + Retrieve the texture atlas table information for a given texture + @param textureName Name of an atlas texture + */ + const TextureAtlasTablePtr& getTextureAtlasTable(const String& textureName) const; + + /** + Set the default attributes concerning atlas texture processing + @param mode The index positioning mode. Tells relative to where the the texture coordinates + containing the atlas image to use are positioned. + @param offset The index positioning offset. Tells the offset relative to the index positioning + mode. + @param autoAdjustBorders Tells whether to automatically adjust the polled area in the texture + relative to the used mipmap level. + @see TextureAtlasSampler + */ + void setDefaultAtlasingAttributes(IndexPositionMode mode, ushort offset, bool autoAdjustBorders); + + /** + Returns the default attributes of texture atlas processing + @see setDefaultAtlasingAttributes + */ + const TextureAtlasAttib& getDefaultAtlasingAttributes() const; + + /** + Set the default attributes concerning atlas texture processing for a specific material + @param material The material to which to add the information + @param mode The index positioning mode. Tells relative to where the the texture coordinates + containing the atlas image to use are positioned. + @param offset The index positioning offset. Tells the offset relative to the index positioning + mode. + @param autoAdjustBorders Tells whether to automatically adjust the polled area in the texture + relative to the used mipmap level. + @see TextureAtlasSampler + */ + void setMaterialAtlasingAttributes(Ogre::Material* material, + IndexPositionMode mode, ushort offset, bool autoAdjustBorders); + + /** - Adds a texture atlas definition from a stream. - - This function loads a texture atlas definition file from a stream. The accepted format for - this file is the NVidia Texture Atlas Tools ".tai" file format. This file as - - The ".tai" format consist of lines, where each line corresponds to a specific texture - in the texture atlas. Each line has the following format: - # /t/t, , , , , , , - - @param stream A stream to a file containing ".tai" format data - @param textureAtlasTable A table into which the data in the stream will be filled. This - parameter will be filled only if it is not null. The system factory keeps a copy of this - information in any case. - */ - bool addTexutreAtlasDefinition( DataStreamPtr stream, TextureAtlasTablePtr textureAtlasTable = TextureAtlasTablePtr()); - - /** - Set the texture atlas information for a given texture - @param textureName Name of an atlas texture - @param atlasData A list of records containing the position and size of each - texture in the atlas - @param autoBorderAdjust Sets whether to automatically adjust the image polling area for border - issues.See the Border issues paragraph under the class documentation for more information. - */ - void setTextureAtlasTable(const String& textureName, const TextureAtlasTablePtr& atlasData, bool autoBorderAdjust = true); - - /** - Removes the texture atlas information from a given texture - @param textureName Name of an atlas texture - */ - void removeTextureAtlasTable(const String& textureName); - - /** - Removes all texture atlas table information - */ - void removeAllTextureAtlasTables(); - - /** - Retrieve the texture atlas table information for a given texture - @param textureName Name of an atlas texture - */ - const TextureAtlasTablePtr& getTextureAtlasTable(const String& textureName) const; - - /** - Set the default attributes concerning atlas texture processing - @param mode The index positioning mode. Tells relative to where the the texture coordinates - containing the atlas image to use are positioned. - @param offset The index positioning offset. Tells the offset relative to the index positioning - mode. - @param autoAdjustBorders Tells whether to automatically adjust the polled area in the texture - relative to the used mipmap level. - @see TextureAtlasSampler - */ - void setDefaultAtlasingAttributes(IndexPositionMode mode, ushort offset, bool autoAdjustBorders); - - /** - Returns the default attributes of texture atlas processing - @see setDefaultAtlasingAttributes - */ - const TextureAtlasAttib& getDefaultAtlasingAttributes() const; - - /** - Set the default attributes concerning atlas texture processing for a specific material - @param material The material to which to add the information - @param mode The index positioning mode. Tells relative to where the the texture coordinates - containing the atlas image to use are positioned. - @param offset The index positioning offset. Tells the offset relative to the index positioning - mode. - @param autoAdjustBorders Tells whether to automatically adjust the polled area in the texture - relative to the used mipmap level. - @see TextureAtlasSampler - */ - void setMaterialAtlasingAttributes(Ogre::Material* material, - IndexPositionMode mode, ushort offset, bool autoAdjustBorders); - - - /** - Tells whether a specific material has atlas attributes associated with it. And returns the - attributes to be used. - @see setMaterialAtlasingAttributes - */ - bool hasMaterialAtlasingAttributes(Ogre::Material* material, TextureAtlasAttib* attrib = NULL) const; - + Tells whether a specific material has atlas attributes associated with it. And returns the + attributes to be used. + @see setMaterialAtlasingAttributes + */ + bool hasMaterialAtlasingAttributes(Ogre::Material* material, TextureAtlasAttib* attrib = NULL) const; + protected: - + - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); private: - //Holds a mapping of texture names and the atlas table information associated with them - TextureAtlasMap mAtlases; + //Holds a mapping of texture names and the atlas table information associated with them + TextureAtlasMap mAtlases; - TextureAtlasAttib mDefaultAtlasAttrib; + TextureAtlasAttib mDefaultAtlasAttrib; }; _OgreRTSSExport void operator<<(std::ostream& o, const TextureAtlasSamplerFactory::TextureAtlasAttib& tai); diff --git a/Components/RTShaderSystem/include/OgreShaderFFPColour.h b/Components/RTShaderSystem/include/OgreShaderFFPColour.h index e150d056d71..16f08e41600 100644 --- a/Components/RTShaderSystem/include/OgreShaderFFPColour.h +++ b/Components/RTShaderSystem/include/OgreShaderFFPColour.h @@ -48,99 +48,99 @@ class _OgreRTSSExport FFPColour : public SubRenderState { public: - // Parameter stage flags of the colour component. - enum StageFlags - { - SF_VS_INPUT_DIFFUSE = 1 << 1, - SF_VS_INPUT_SPECULAR = 1 << 2, - SF_VS_OUTPUT_DIFFUSE = 1 << 3, - SF_VS_OUTPUT_SPECULAR = 1 << 4, - SF_PS_INPUT_DIFFUSE = 1 << 5, - SF_PS_INPUT_SPECULAR = 1 << 6, - SF_PS_OUTPUT_DIFFUSE = 1 << 7, - SF_PS_OUTPUT_SPECULAR = 1 << 8 - }; + // Parameter stage flags of the colour component. + enum StageFlags + { + SF_VS_INPUT_DIFFUSE = 1 << 1, + SF_VS_INPUT_SPECULAR = 1 << 2, + SF_VS_OUTPUT_DIFFUSE = 1 << 3, + SF_VS_OUTPUT_SPECULAR = 1 << 4, + SF_PS_INPUT_DIFFUSE = 1 << 5, + SF_PS_INPUT_SPECULAR = 1 << 6, + SF_PS_OUTPUT_DIFFUSE = 1 << 7, + SF_PS_OUTPUT_SPECULAR = 1 << 8 + }; // Interface. public: - /** Class default constructor */ - FFPColour(); - - - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; - - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; - - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); - - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); - - /** - Set the resolve stage flags that this sub render state will produce. - I.E - If one want to specify that the vertex shader program needs to get a diffuse component - and the pixel shader should output diffuse component he should pass SF_VS_INPUT_DIFFUSE | SF_PS_OUTPUT_DIFFUSE. - @param flags The stage flag to set. - */ - void setResolveStageFlags(unsigned int flags) { mResolveStageFlags = flags; } - - /** - Get the current resolve stage flags. - */ - unsigned int getResolveStageFlags() const { return mResolveStageFlags; } - - /** - Add the given mask to resolve stage flags that this sub render state will produce. - @param mask The mask to add to current flag set. - */ - void addResolveStageMask(unsigned int mask) { mResolveStageFlags |= mask; } - - /** - Remove the given mask from the resolve stage flags that this sub render state will produce. - @param mask The mask to remove from current flag set. - */ - void removeResolveStageMask(unsigned int mask) { mResolveStageFlags &= ~mask; } - - static String Type; + /** Class default constructor */ + FFPColour(); + + + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; + + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; + + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); + + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); + + /** + Set the resolve stage flags that this sub render state will produce. + I.E - If one want to specify that the vertex shader program needs to get a diffuse component + and the pixel shader should output diffuse component he should pass SF_VS_INPUT_DIFFUSE | SF_PS_OUTPUT_DIFFUSE. + @param flags The stage flag to set. + */ + void setResolveStageFlags(unsigned int flags) { mResolveStageFlags = flags; } + + /** + Get the current resolve stage flags. + */ + unsigned int getResolveStageFlags() const { return mResolveStageFlags; } + + /** + Add the given mask to resolve stage flags that this sub render state will produce. + @param mask The mask to add to current flag set. + */ + void addResolveStageMask(unsigned int mask) { mResolveStageFlags |= mask; } + + /** + Remove the given mask from the resolve stage flags that this sub render state will produce. + @param mask The mask to remove from current flag set. + */ + void removeResolveStageMask(unsigned int mask) { mResolveStageFlags &= ~mask; } + + static String Type; // Protected methods -protected: - virtual bool resolveParameters(ProgramSet* programSet); - virtual bool resolveDependencies(ProgramSet* programSet); - virtual bool addFunctionInvocations(ProgramSet* programSet); +protected: + virtual bool resolveParameters(ProgramSet* programSet); + virtual bool resolveDependencies(ProgramSet* programSet); + virtual bool addFunctionInvocations(ProgramSet* programSet); // Attributes. protected: - // Vertex shader input diffuse component. - ParameterPtr mVSInputDiffuse; - // Vertex shader input specular component. - ParameterPtr mVSInputSpecular; - // Vertex shader output diffuse component. - ParameterPtr mVSOutputDiffuse; - // Vertex shader input specular component. - ParameterPtr mVSOutputSpecular; - // Pixel shader input diffuse component. - ParameterPtr mPSInputDiffuse; - // Pixel shader input specular component. - ParameterPtr mPSInputSpecular; - // Pixel shader output diffuse component. - ParameterPtr mPSOutputDiffuse; - // Pixel shader input specular component. - ParameterPtr mPSOutputSpecular; - // Stage flags that defines resolve parameters definitions. - unsigned int mResolveStageFlags; + // Vertex shader input diffuse component. + ParameterPtr mVSInputDiffuse; + // Vertex shader input specular component. + ParameterPtr mVSInputSpecular; + // Vertex shader output diffuse component. + ParameterPtr mVSOutputDiffuse; + // Vertex shader input specular component. + ParameterPtr mVSOutputSpecular; + // Pixel shader input diffuse component. + ParameterPtr mPSInputDiffuse; + // Pixel shader input specular component. + ParameterPtr mPSInputSpecular; + // Pixel shader output diffuse component. + ParameterPtr mPSOutputDiffuse; + // Pixel shader input specular component. + ParameterPtr mPSOutputSpecular; + // Stage flags that defines resolve parameters definitions. + unsigned int mResolveStageFlags; }; @@ -152,28 +152,28 @@ class _OgreRTSSExport FFPColourFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); - + protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); }; diff --git a/Components/RTShaderSystem/include/OgreShaderFFPFog.h b/Components/RTShaderSystem/include/OgreShaderFFPFog.h index ac024d338cd..9124516c072 100644 --- a/Components/RTShaderSystem/include/OgreShaderFFPFog.h +++ b/Components/RTShaderSystem/include/OgreShaderFFPFog.h @@ -50,121 +50,121 @@ class _OgreRTSSExport FFPFog : public SubRenderState { public: - // Fog calculation mode enum. - enum CalcMode - { - CM_PER_VERTEX = 1, // Per vertex fog calculations. (Default). - CM_PER_PIXEL = 2 // Per pixel fog calculations. - }; + // Fog calculation mode enum. + enum CalcMode + { + CM_PER_VERTEX = 1, // Per vertex fog calculations. (Default). + CM_PER_PIXEL = 2 // Per pixel fog calculations. + }; // Interface. public: - /** Class default constructor */ - FFPFog(); - - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; - - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; - - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); - - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); - - /** - Set the fog properties this fog sub render state should emulate. - @param fogMode The fog mode to emulate (FOG_NONE, FOG_EXP, FOG_EXP2, FOG_LINEAR). - @param fogColour The colour of the fog. - @param fogStart Start distance of fog, used for linear mode only. - @param fogEnd End distance of fog, used for linear mode only. - @param fogDensity Fog density used in exponential modes only. - @see http://msdn.microsoft.com/en-us/library/bb173401.aspx - */ - void setFogProperties(FogMode fogMode, - const ColourValue& fogColour, - float fogStart, - float fogEnd, - float fogDensity); - - /** - Set the fog calculation mode. Either per vertex or per pixel. - @param calcMode The calculation mode to set. - */ - void setCalcMode(CalcMode calcMode) { mCalcMode = calcMode; } - - /** - Return the current calculation mode. - */ - CalcMode getCalcMode() const { return mCalcMode; } - - static String Type; + /** Class default constructor */ + FFPFog(); + + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; + + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; + + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); + + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); + + /** + Set the fog properties this fog sub render state should emulate. + @param fogMode The fog mode to emulate (FOG_NONE, FOG_EXP, FOG_EXP2, FOG_LINEAR). + @param fogColour The colour of the fog. + @param fogStart Start distance of fog, used for linear mode only. + @param fogEnd End distance of fog, used for linear mode only. + @param fogDensity Fog density used in exponential modes only. + @see http://msdn.microsoft.com/en-us/library/bb173401.aspx + */ + void setFogProperties(FogMode fogMode, + const ColourValue& fogColour, + float fogStart, + float fogEnd, + float fogDensity); + + /** + Set the fog calculation mode. Either per vertex or per pixel. + @param calcMode The calculation mode to set. + */ + void setCalcMode(CalcMode calcMode) { mCalcMode = calcMode; } + + /** + Return the current calculation mode. + */ + CalcMode getCalcMode() const { return mCalcMode; } + + static String Type; // Protected methods protected: - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet); + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet); - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet); + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet); - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); // Attributes. -protected: - // Fog calculation mode. - CalcMode mCalcMode; - // Fog formula. - FogMode mFogMode; - // Fog colour value. - ColourValue mFogColourValue; - // Fog parameters (density, start, end, 1/end-start). - Vector4 mFogParamsValue; - // True if the fog parameters should be taken from the pass. - bool mPassOverrideParams; - - // World view projection parameter. - UniformParameterPtr mWorldViewProjMatrix; - // Fog colour parameter. - UniformParameterPtr mFogColour; - // Fog parameters program parameter. - UniformParameterPtr mFogParams; - // Vertex shader input position parameter. - ParameterPtr mVSInPos; - // Vertex shader output fog colour parameter. - ParameterPtr mVSOutFogFactor; - // Pixel shader input fog factor. - ParameterPtr mPSInFogFactor; - // Vertex shader output depth. - ParameterPtr mVSOutDepth; - // Pixel shader input depth. - ParameterPtr mPSInDepth; - // Pixel shader output diffuse colour. - ParameterPtr mPSOutDiffuse; +protected: + // Fog calculation mode. + CalcMode mCalcMode; + // Fog formula. + FogMode mFogMode; + // Fog colour value. + ColourValue mFogColourValue; + // Fog parameters (density, start, end, 1/end-start). + Vector4 mFogParamsValue; + // True if the fog parameters should be taken from the pass. + bool mPassOverrideParams; + + // World view projection parameter. + UniformParameterPtr mWorldViewProjMatrix; + // Fog colour parameter. + UniformParameterPtr mFogColour; + // Fog parameters program parameter. + UniformParameterPtr mFogParams; + // Vertex shader input position parameter. + ParameterPtr mVSInPos; + // Vertex shader output fog colour parameter. + ParameterPtr mVSOutFogFactor; + // Pixel shader input fog factor. + ParameterPtr mPSInFogFactor; + // Vertex shader output depth. + ParameterPtr mVSOutDepth; + // Pixel shader input depth. + ParameterPtr mPSInDepth; + // Pixel shader output diffuse colour. + ParameterPtr mPSOutDiffuse; }; @@ -176,28 +176,28 @@ class _OgreRTSSExport FFPFogFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); - + protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); }; diff --git a/Components/RTShaderSystem/include/OgreShaderFFPLighting.h b/Components/RTShaderSystem/include/OgreShaderFFPLighting.h index 58a9a376455..5ce54e01c41 100644 --- a/Components/RTShaderSystem/include/OgreShaderFFPLighting.h +++ b/Components/RTShaderSystem/include/OgreShaderFFPLighting.h @@ -53,169 +53,169 @@ class _OgreRTSSExport FFPLighting : public SubRenderState // Interface. public: - - /** Class default constructor */ - FFPLighting(); + + /** Class default constructor */ + FFPLighting(); - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); - static String Type; + static String Type; // Protected types: protected: - // Per light parameters. - struct _OgreRTSSExport LightParams - { - Light::LightTypes mType; // Light type. - // Light position. - UniformParameterPtr mPosition; - // Light direction. - UniformParameterPtr mDirection; - // Attenuation parameters. - UniformParameterPtr mAttenuatParams; - // Spot light parameters. - UniformParameterPtr mSpotParams; - // Diffuse colour. - UniformParameterPtr mDiffuseColour; - // Specular colour. - UniformParameterPtr mSpecularColour; - - }; - - typedef vector::type LightParamsList; - typedef LightParamsList::iterator LightParamsIterator; - typedef LightParamsList::const_iterator LightParamsConstIterator; + // Per light parameters. + struct _OgreRTSSExport LightParams + { + Light::LightTypes mType; // Light type. + // Light position. + UniformParameterPtr mPosition; + // Light direction. + UniformParameterPtr mDirection; + // Attenuation parameters. + UniformParameterPtr mAttenuatParams; + // Spot light parameters. + UniformParameterPtr mSpotParams; + // Diffuse colour. + UniformParameterPtr mDiffuseColour; + // Specular colour. + UniformParameterPtr mSpecularColour; + + }; + + typedef vector::type LightParamsList; + typedef LightParamsList::iterator LightParamsIterator; + typedef LightParamsList::const_iterator LightParamsConstIterator; // Protected methods protected: - /** - Set the track per vertex colour type. Ambient, Diffuse, Specular and Emissive lighting components source - can be the vertex colour component. To establish such a link one should provide the matching flags to this - sub render state. - */ - void setTrackVertexColourType(TrackVertexColourType type) { mTrackVertexColourType = type; } - - /** - Return the current track per vertex type. - */ - TrackVertexColourType getTrackVertexColourType() const { return mTrackVertexColourType; } - - /** - Set the light count per light type that this sub render state will generate. - @see ShaderGenerator::setLightCount. - */ - void setLightCount(const int lightCount[3]); - - /** - Get the light count per light type that this sub render state will generate. - @see ShaderGenerator::getLightCount. - */ - void getLightCount(int lightCount[3]) const; - - /** - Set the specular component state. If set to true this sub render state will compute a specular - lighting component in addition to the diffuse component. - @param enable Pass true to enable specular component computation. - */ - void setSpecularEnable(bool enable) { mSpecularEnable = enable; } - - /** - Get the specular component state. - */ - bool getSpecularEnable() const { return mSpecularEnable; } - - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet); - - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet); - - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); - - - /** - Internal method that adds global illumination component functions invocations. - */ - bool addGlobalIlluminationInvocation(Function* vsMain, const int groupOrder, int& internalCounter); - - /** - Internal method that adds per light illumination component functions invocations. - */ - bool addIlluminationInvocation(LightParams* curLightParams, Function* vsMain, const int groupOrder, int& internalCounter); + /** + Set the track per vertex colour type. Ambient, Diffuse, Specular and Emissive lighting components source + can be the vertex colour component. To establish such a link one should provide the matching flags to this + sub render state. + */ + void setTrackVertexColourType(TrackVertexColourType type) { mTrackVertexColourType = type; } + + /** + Return the current track per vertex type. + */ + TrackVertexColourType getTrackVertexColourType() const { return mTrackVertexColourType; } + + /** + Set the light count per light type that this sub render state will generate. + @see ShaderGenerator::setLightCount. + */ + void setLightCount(const int lightCount[3]); + + /** + Get the light count per light type that this sub render state will generate. + @see ShaderGenerator::getLightCount. + */ + void getLightCount(int lightCount[3]) const; + + /** + Set the specular component state. If set to true this sub render state will compute a specular + lighting component in addition to the diffuse component. + @param enable Pass true to enable specular component computation. + */ + void setSpecularEnable(bool enable) { mSpecularEnable = enable; } + + /** + Get the specular component state. + */ + bool getSpecularEnable() const { return mSpecularEnable; } + + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet); + + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet); + + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); + + + /** + Internal method that adds global illumination component functions invocations. + */ + bool addGlobalIlluminationInvocation(Function* vsMain, const int groupOrder, int& internalCounter); + + /** + Internal method that adds per light illumination component functions invocations. + */ + bool addIlluminationInvocation(LightParams* curLightParams, Function* vsMain, const int groupOrder, int& internalCounter); // Attributes. -protected: - // Track per vertex colour type. - TrackVertexColourType mTrackVertexColourType; - // Specular component enabled/disabled. - bool mSpecularEnable; - // Light list. - LightParamsList mLightParamsList; - // World view matrix parameter. - UniformParameterPtr mWorldViewMatrix; - // World view matrix inverse transpose parameter. - UniformParameterPtr mWorldViewITMatrix; - // Vertex shader input position parameter. - ParameterPtr mVSInPosition; - // Vertex shader input normal. - ParameterPtr mVSInNormal; - // Vertex shader diffuse. - ParameterPtr mVSDiffuse; - // Vertex shader output diffuse colour parameter. - ParameterPtr mVSOutDiffuse; - // Vertex shader output specular colour parameter. - ParameterPtr mVSOutSpecular; - // Derived scene colour parameter. - UniformParameterPtr mDerivedSceneColour; - // Ambient light colour parameter. - UniformParameterPtr mLightAmbientColour; - // Derived ambient light colour parameter. - UniformParameterPtr mDerivedAmbientLightColour; - // Surface ambient colour parameter. - UniformParameterPtr mSurfaceAmbientColour; - // Surface diffuse colour parameter. - UniformParameterPtr mSurfaceDiffuseColour; - // Surface specular colour parameter. - UniformParameterPtr mSurfaceSpecularColour; - // Surface emissive colour parameter. - UniformParameterPtr mSurfaceEmissiveColour; - // Surface shininess parameter. - UniformParameterPtr mSurfaceShininess; - // Shared blank light. - static Light msBlankLight; +protected: + // Track per vertex colour type. + TrackVertexColourType mTrackVertexColourType; + // Specular component enabled/disabled. + bool mSpecularEnable; + // Light list. + LightParamsList mLightParamsList; + // World view matrix parameter. + UniformParameterPtr mWorldViewMatrix; + // World view matrix inverse transpose parameter. + UniformParameterPtr mWorldViewITMatrix; + // Vertex shader input position parameter. + ParameterPtr mVSInPosition; + // Vertex shader input normal. + ParameterPtr mVSInNormal; + // Vertex shader diffuse. + ParameterPtr mVSDiffuse; + // Vertex shader output diffuse colour parameter. + ParameterPtr mVSOutDiffuse; + // Vertex shader output specular colour parameter. + ParameterPtr mVSOutSpecular; + // Derived scene colour parameter. + UniformParameterPtr mDerivedSceneColour; + // Ambient light colour parameter. + UniformParameterPtr mLightAmbientColour; + // Derived ambient light colour parameter. + UniformParameterPtr mDerivedAmbientLightColour; + // Surface ambient colour parameter. + UniformParameterPtr mSurfaceAmbientColour; + // Surface diffuse colour parameter. + UniformParameterPtr mSurfaceDiffuseColour; + // Surface specular colour parameter. + UniformParameterPtr mSurfaceSpecularColour; + // Surface emissive colour parameter. + UniformParameterPtr mSurfaceEmissiveColour; + // Surface shininess parameter. + UniformParameterPtr mSurfaceShininess; + // Shared blank light. + static Light msBlankLight; }; @@ -228,28 +228,28 @@ class _OgreRTSSExport FFPLightingFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); - + protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); }; diff --git a/Components/RTShaderSystem/include/OgreShaderFFPRenderState.h b/Components/RTShaderSystem/include/OgreShaderFFPRenderState.h index a3186a4196a..eccb6d47fd5 100644 --- a/Components/RTShaderSystem/include/OgreShaderFFPRenderState.h +++ b/Components/RTShaderSystem/include/OgreShaderFFPRenderState.h @@ -42,89 +42,89 @@ namespace RTShader { // Fixed Function vertex shader stages. enum FFPVertexShaderStage { - FFP_VS_PRE_PROCESS = 0, - FFP_VS_TRANSFORM = 100, - FFP_VS_COLOUR = 200, - FFP_VS_LIGHTING = 300, - FFP_VS_TEXTURING = 400, - FFP_VS_FOG = 500, - FFP_VS_POST_PROCESS = 2000 + FFP_VS_PRE_PROCESS = 0, + FFP_VS_TRANSFORM = 100, + FFP_VS_COLOUR = 200, + FFP_VS_LIGHTING = 300, + FFP_VS_TEXTURING = 400, + FFP_VS_FOG = 500, + FFP_VS_POST_PROCESS = 2000 }; // Fixed Function fragment shader stages. enum FFPFragmentShaderStage { - FFP_PS_PRE_PROCESS = 0, - FFP_PS_COLOUR_BEGIN = 100, - FFP_PS_SAMPLING = 150, - FFP_PS_TEXTURING = 200, - FFP_PS_COLOUR_END = 300, - FFP_PS_FOG = 400, - FFP_PS_POST_PROCESS = 500 + FFP_PS_PRE_PROCESS = 0, + FFP_PS_COLOUR_BEGIN = 100, + FFP_PS_SAMPLING = 150, + FFP_PS_TEXTURING = 200, + FFP_PS_COLOUR_END = 300, + FFP_PS_FOG = 400, + FFP_PS_POST_PROCESS = 500 }; // Fixed Function generic stages. enum FFPShaderStage { - FFP_PRE_PROCESS = 0, - FFP_TRANSFORM = 100, - FFP_COLOUR = 200, - FFP_LIGHTING = 300, - FFP_TEXTURING = 400, - FFP_FOG = 500, - FFP_POST_PROCESS = 600 + FFP_PRE_PROCESS = 0, + FFP_TRANSFORM = 100, + FFP_COLOUR = 200, + FFP_LIGHTING = 300, + FFP_TEXTURING = 400, + FFP_FOG = 500, + FFP_POST_PROCESS = 600 }; // Fixed Function Library: Common functions -#define FFP_LIB_COMMON "FFPLib_Common" -#define FFP_FUNC_ASSIGN "FFP_Assign" -#define FFP_FUNC_CONSTRUCT "FFP_Construct" -#define FFP_FUNC_MODULATE "FFP_Modulate" -#define FFP_FUNC_ADD "FFP_Add" -#define FFP_FUNC_SUBTRACT "FFP_Subtract" -#define FFP_FUNC_LERP "FFP_Lerp" -#define FFP_FUNC_DOTPRODUCT "FFP_DotProduct" -#define FFP_FUNC_NORMALIZE "FFP_Normalize" +#define FFP_LIB_COMMON "FFPLib_Common" +#define FFP_FUNC_ASSIGN "FFP_Assign" +#define FFP_FUNC_CONSTRUCT "FFP_Construct" +#define FFP_FUNC_MODULATE "FFP_Modulate" +#define FFP_FUNC_ADD "FFP_Add" +#define FFP_FUNC_SUBTRACT "FFP_Subtract" +#define FFP_FUNC_LERP "FFP_Lerp" +#define FFP_FUNC_DOTPRODUCT "FFP_DotProduct" +#define FFP_FUNC_NORMALIZE "FFP_Normalize" // Fixed Function Library: Transform functions -#define FFP_LIB_TRANSFORM "FFPLib_Transform" -#define FFP_FUNC_TRANSFORM "FFP_Transform" +#define FFP_LIB_TRANSFORM "FFPLib_Transform" +#define FFP_FUNC_TRANSFORM "FFP_Transform" // Fixed Function Library: Lighting functions -#define FFP_LIB_LIGHTING "FFPLib_Lighting" -#define FFP_FUNC_LIGHT_DIRECTIONAL_DIFFUSE "FFP_Light_Directional_Diffuse" -#define FFP_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR "FFP_Light_Directional_DiffuseSpecular" -#define FFP_FUNC_LIGHT_POINT_DIFFUSE "FFP_Light_Point_Diffuse" -#define FFP_FUNC_LIGHT_POINT_DIFFUSESPECULAR "FFP_Light_Point_DiffuseSpecular" -#define FFP_FUNC_LIGHT_SPOT_DIFFUSE "FFP_Light_Spot_Diffuse" -#define FFP_FUNC_LIGHT_SPOT_DIFFUSESPECULAR "FFP_Light_Spot_DiffuseSpecular" +#define FFP_LIB_LIGHTING "FFPLib_Lighting" +#define FFP_FUNC_LIGHT_DIRECTIONAL_DIFFUSE "FFP_Light_Directional_Diffuse" +#define FFP_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR "FFP_Light_Directional_DiffuseSpecular" +#define FFP_FUNC_LIGHT_POINT_DIFFUSE "FFP_Light_Point_Diffuse" +#define FFP_FUNC_LIGHT_POINT_DIFFUSESPECULAR "FFP_Light_Point_DiffuseSpecular" +#define FFP_FUNC_LIGHT_SPOT_DIFFUSE "FFP_Light_Spot_Diffuse" +#define FFP_FUNC_LIGHT_SPOT_DIFFUSESPECULAR "FFP_Light_Spot_DiffuseSpecular" // Fixed Function Library: Texturing functions -#define FFP_LIB_TEXTURING "FFPLib_Texturing" -#define FFP_FUNC_TRANSFORM_TEXCOORD "FFP_TransformTexCoord" -#define FFP_FUNC_GENERATE_TEXCOORD_ENV_NORMAL "FFP_GenerateTexCoord_EnvMap_Normal" -#define FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE "FFP_GenerateTexCoord_EnvMap_Sphere" -#define FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT "FFP_GenerateTexCoord_EnvMap_Reflect" -#define FFP_FUNC_GENERATE_TEXCOORD_PROJECTION "FFP_GenerateTexCoord_Projection" -#define FFP_FUNC_SAMPLE_TEXTURE "FFP_SampleTexture" -#define FFP_FUNC_CONSTRUCT_SAMPLER_WRAPPER "FFP_Construct_Sampler_Wrapper" //only for hlsl - -#define FFP_FUNC_SAMPLE_TEXTURE_PROJ "FFP_SampleTextureProj" -#define FFP_FUNC_MODULATEX2 "FFP_ModulateX2" -#define FFP_FUNC_MODULATEX4 "FFP_ModulateX4" -#define FFP_FUNC_ADDSIGNED "FFP_AddSigned" -#define FFP_FUNC_ADDSMOOTH "FFP_AddSmooth" +#define FFP_LIB_TEXTURING "FFPLib_Texturing" +#define FFP_FUNC_TRANSFORM_TEXCOORD "FFP_TransformTexCoord" +#define FFP_FUNC_GENERATE_TEXCOORD_ENV_NORMAL "FFP_GenerateTexCoord_EnvMap_Normal" +#define FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE "FFP_GenerateTexCoord_EnvMap_Sphere" +#define FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT "FFP_GenerateTexCoord_EnvMap_Reflect" +#define FFP_FUNC_GENERATE_TEXCOORD_PROJECTION "FFP_GenerateTexCoord_Projection" +#define FFP_FUNC_SAMPLE_TEXTURE "FFP_SampleTexture" +#define FFP_FUNC_CONSTRUCT_SAMPLER_WRAPPER "FFP_Construct_Sampler_Wrapper" //only for hlsl + +#define FFP_FUNC_SAMPLE_TEXTURE_PROJ "FFP_SampleTextureProj" +#define FFP_FUNC_MODULATEX2 "FFP_ModulateX2" +#define FFP_FUNC_MODULATEX4 "FFP_ModulateX4" +#define FFP_FUNC_ADDSIGNED "FFP_AddSigned" +#define FFP_FUNC_ADDSMOOTH "FFP_AddSmooth" // Fixed Function Library: Fog functions -#define FFP_LIB_FOG "FFPLib_Fog" -#define FFP_FUNC_VERTEXFOG_LINEAR "FFP_VertexFog_Linear" -#define FFP_FUNC_VERTEXFOG_EXP "FFP_VertexFog_Exp" -#define FFP_FUNC_VERTEXFOG_EXP2 "FFP_VertexFog_Exp2" -#define FFP_FUNC_PIXELFOG_DEPTH "FFP_PixelFog_Depth" -#define FFP_FUNC_PIXELFOG_LINEAR "FFP_PixelFog_Linear" -#define FFP_FUNC_PIXELFOG_EXP "FFP_PixelFog_Exp" -#define FFP_FUNC_PIXELFOG_EXP2 "FFP_PixelFog_Exp2" - +#define FFP_LIB_FOG "FFPLib_Fog" +#define FFP_FUNC_VERTEXFOG_LINEAR "FFP_VertexFog_Linear" +#define FFP_FUNC_VERTEXFOG_EXP "FFP_VertexFog_Exp" +#define FFP_FUNC_VERTEXFOG_EXP2 "FFP_VertexFog_Exp2" +#define FFP_FUNC_PIXELFOG_DEPTH "FFP_PixelFog_Depth" +#define FFP_FUNC_PIXELFOG_LINEAR "FFP_PixelFog_Linear" +#define FFP_FUNC_PIXELFOG_EXP "FFP_PixelFog_Exp" +#define FFP_FUNC_PIXELFOG_EXP2 "FFP_PixelFog_Exp2" + /** @} */ /** @} */ diff --git a/Components/RTShaderSystem/include/OgreShaderFFPRenderStateBuilder.h b/Components/RTShaderSystem/include/OgreShaderFFPRenderStateBuilder.h index 94038354f89..80bdee164c8 100644 --- a/Components/RTShaderSystem/include/OgreShaderFFPRenderStateBuilder.h +++ b/Components/RTShaderSystem/include/OgreShaderFFPRenderStateBuilder.h @@ -51,89 +51,89 @@ class _OgreRTSSExport FFPRenderStateBuilder : public Singleton::type SubRenderStateFactoryList; - typedef SubRenderStateFactoryList::iterator SubRenderStateFactoryIterator; - typedef SubRenderStateFactoryList::const_iterator SubRenderStateFactoryConstIterator; + typedef vector::type SubRenderStateFactoryList; + typedef SubRenderStateFactoryList::iterator SubRenderStateFactoryIterator; + typedef SubRenderStateFactoryList::const_iterator SubRenderStateFactoryConstIterator; // Protected methods. protected: - /** - Internal method that builds FFP sub render state. - */ - void buildFFPSubRenderState(int subRenderStateOrder, const String& subRenderStateType, - ShaderGenerator::SGPass* sgPass, TargetRenderState* renderState); - - /** - Internal method that resolves the colour stage flags. - */ - void resolveColourStageFlags(ShaderGenerator::SGPass* sgPass, TargetRenderState* renderState); + /** + Internal method that builds FFP sub render state. + */ + void buildFFPSubRenderState(int subRenderStateOrder, const String& subRenderStateType, + ShaderGenerator::SGPass* sgPass, TargetRenderState* renderState); + + /** + Internal method that resolves the colour stage flags. + */ + void resolveColourStageFlags(ShaderGenerator::SGPass* sgPass, TargetRenderState* renderState); // Attributes. protected: - // All factories needed by the FFP. - SubRenderStateFactoryList mFFPSubRenderStateFactoryList; - + // All factories needed by the FFP. + SubRenderStateFactoryList mFFPSubRenderStateFactoryList; + }; diff --git a/Components/RTShaderSystem/include/OgreShaderFFPTexturing.h b/Components/RTShaderSystem/include/OgreShaderFFPTexturing.h index 70e4c9feebf..67d48702c2a 100644 --- a/Components/RTShaderSystem/include/OgreShaderFFPTexturing.h +++ b/Components/RTShaderSystem/include/OgreShaderFFPTexturing.h @@ -56,189 +56,189 @@ class _OgreRTSSExport FFPTexturing : public SubRenderState // Interface. public: - /** Class default constructor */ - FFPTexturing(); - - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; - - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; - - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); - - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); - - static void AddTextureSampleWrapperInvocation(UniformParameterPtr textureSampler,UniformParameterPtr textureSamplerState, - GpuConstantType samplerType, Function* function, int groupOrder, int& internalCounter); - - - static ParameterPtr GetSamplerWrapperParam(GpuConstantType samplerType,Function* function); - - static String Type; + /** Class default constructor */ + FFPTexturing(); + + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; + + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; + + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); + + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); + + static void AddTextureSampleWrapperInvocation(UniformParameterPtr textureSampler,UniformParameterPtr textureSamplerState, + GpuConstantType samplerType, Function* function, int groupOrder, int& internalCounter); + + + static ParameterPtr GetSamplerWrapperParam(GpuConstantType samplerType,Function* function); + + static String Type; // Protected types: protected: - - // Per texture unit parameters. - struct _OgreRTSSExport TextureUnitParams - { - // Texture unit state. - TextureUnitState* mTextureUnitState; - // Texture projector. - const Frustum* mTextureProjector; - // Texture sampler index. - unsigned short mTextureSamplerIndex; - // Texture sampler index. - GpuConstantType mTextureSamplerType; - // Vertex shader input texture coordinate type. - GpuConstantType mVSInTextureCoordinateType; - // Vertex shader output texture coordinates type. - GpuConstantType mVSOutTextureCoordinateType; - // Texture coordinates calculation method. - TexCoordCalcMethod mTexCoordCalcMethod; - // Texture matrix parameter. - UniformParameterPtr mTextureMatrix; - // Texture View Projection Image space matrix parameter. - UniformParameterPtr mTextureViewProjImageMatrix; - // Texture sampler parameter. - UniformParameterPtr mTextureSampler; - // Texture sampler state parameter. - UniformParameterPtr mTextureSamplerState; - // Vertex shader input texture coordinates parameter. - ParameterPtr mVSInputTexCoord; - // Vertex shader output texture coordinates parameter. - ParameterPtr mVSOutputTexCoord; - // Pixel shader input texture coordinates parameter. - ParameterPtr mPSInputTexCoord; - }; - - typedef vector::type TextureUnitParamsList; - typedef TextureUnitParamsList::iterator TextureUnitParamsIterator; - typedef TextureUnitParamsList::const_iterator TextureUnitParamsConstIterator; + + // Per texture unit parameters. + struct _OgreRTSSExport TextureUnitParams + { + // Texture unit state. + TextureUnitState* mTextureUnitState; + // Texture projector. + const Frustum* mTextureProjector; + // Texture sampler index. + unsigned short mTextureSamplerIndex; + // Texture sampler index. + GpuConstantType mTextureSamplerType; + // Vertex shader input texture coordinate type. + GpuConstantType mVSInTextureCoordinateType; + // Vertex shader output texture coordinates type. + GpuConstantType mVSOutTextureCoordinateType; + // Texture coordinates calculation method. + TexCoordCalcMethod mTexCoordCalcMethod; + // Texture matrix parameter. + UniformParameterPtr mTextureMatrix; + // Texture View Projection Image space matrix parameter. + UniformParameterPtr mTextureViewProjImageMatrix; + // Texture sampler parameter. + UniformParameterPtr mTextureSampler; + // Texture sampler state parameter. + UniformParameterPtr mTextureSamplerState; + // Vertex shader input texture coordinates parameter. + ParameterPtr mVSInputTexCoord; + // Vertex shader output texture coordinates parameter. + ParameterPtr mVSOutputTexCoord; + // Pixel shader input texture coordinates parameter. + ParameterPtr mPSInputTexCoord; + }; + + typedef vector::type TextureUnitParamsList; + typedef TextureUnitParamsList::iterator TextureUnitParamsIterator; + typedef TextureUnitParamsList::const_iterator TextureUnitParamsConstIterator; // Protected methods protected: - /** - Set the number of texture units this texturing sub state has to handle. - @param count The number of texture unit states. - */ - void setTextureUnitCount(size_t count); - - /** - Return the number of texture units this sub state handle. - */ - size_t getTextureUnitCount() const { return mTextureUnitParamsList.size(); } - - /** - Set texture unit of a given stage index. - @param index The stage index of the given texture unit state. - @param textureUnitState The texture unit state to bound the the stage index. - */ - void setTextureUnit(unsigned short index, TextureUnitState* textureUnitState); - - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet); - - /** - Internal method that resolves uniform parameters of the given texture unit parameters. - */ - bool resolveUniformParams(TextureUnitParams* textureUnitParams, ProgramSet* programSet); - - /** - Internal method that resolves functions parameters of the given texture unit parameters. - */ - bool resolveFunctionsParams(TextureUnitParams* textureUnitParams, ProgramSet* programSet); - - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet); - - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); - - - /** - Internal method that adds vertex shader functions invocations. - */ - bool addVSFunctionInvocations(TextureUnitParams* textureUnitParams, Function* vsMain); - - /** - Internal method that adds pixel shader functions invocations. - */ - bool addPSFunctionInvocations(TextureUnitParams* textureUnitParams, Function* psMain, int& internalCounter); - - /** - Adds the fragment shader code which samples the texel color in the texture - */ - virtual void addPSSampleTexelInvocation(TextureUnitParams* textureUnitParams, Function* psMain, - const ParameterPtr& texel, int groupOrder, int& internalCounter); - - virtual void addPSArgumentInvocations(Function* psMain, ParameterPtr arg, ParameterPtr texel, - int samplerIndex, LayerBlendSource blendSrc, const ColourValue& colourValue, Real alphaValue, - bool isAlphaArgument, const int groupOrder, int& internalCounter); - - virtual void addPSBlendInvocations(Function* psMain, ParameterPtr arg1, ParameterPtr arg2, - ParameterPtr texel,int samplerIndex, const LayerBlendModeEx& blendMode, - const int groupOrder, int& internalCounter, int targetChannels); - - /** - Determines the texture coordinates calculation method of the given texture unit state. - */ - TexCoordCalcMethod getTexCalcMethod(TextureUnitState* textureUnitState); - - /** - Determines if the given texture unit state need to use texture transformation matrix. - */ - bool needsTextureMatrix(TextureUnitState* textureUnitState); - - /** - Determines whether a given texture unit needs to be processed by this srs - */ - virtual bool isProcessingNeeded(TextureUnitState* texUnitState); + /** + Set the number of texture units this texturing sub state has to handle. + @param count The number of texture unit states. + */ + void setTextureUnitCount(size_t count); + + /** + Return the number of texture units this sub state handle. + */ + size_t getTextureUnitCount() const { return mTextureUnitParamsList.size(); } + + /** + Set texture unit of a given stage index. + @param index The stage index of the given texture unit state. + @param textureUnitState The texture unit state to bound the the stage index. + */ + void setTextureUnit(unsigned short index, TextureUnitState* textureUnitState); + + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet); + + /** + Internal method that resolves uniform parameters of the given texture unit parameters. + */ + bool resolveUniformParams(TextureUnitParams* textureUnitParams, ProgramSet* programSet); + + /** + Internal method that resolves functions parameters of the given texture unit parameters. + */ + bool resolveFunctionsParams(TextureUnitParams* textureUnitParams, ProgramSet* programSet); + + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet); + + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); + + + /** + Internal method that adds vertex shader functions invocations. + */ + bool addVSFunctionInvocations(TextureUnitParams* textureUnitParams, Function* vsMain); + + /** + Internal method that adds pixel shader functions invocations. + */ + bool addPSFunctionInvocations(TextureUnitParams* textureUnitParams, Function* psMain, int& internalCounter); + + /** + Adds the fragment shader code which samples the texel color in the texture + */ + virtual void addPSSampleTexelInvocation(TextureUnitParams* textureUnitParams, Function* psMain, + const ParameterPtr& texel, int groupOrder, int& internalCounter); + + virtual void addPSArgumentInvocations(Function* psMain, ParameterPtr arg, ParameterPtr texel, + int samplerIndex, LayerBlendSource blendSrc, const ColourValue& colourValue, Real alphaValue, + bool isAlphaArgument, const int groupOrder, int& internalCounter); + + virtual void addPSBlendInvocations(Function* psMain, ParameterPtr arg1, ParameterPtr arg2, + ParameterPtr texel,int samplerIndex, const LayerBlendModeEx& blendMode, + const int groupOrder, int& internalCounter, int targetChannels); + + /** + Determines the texture coordinates calculation method of the given texture unit state. + */ + TexCoordCalcMethod getTexCalcMethod(TextureUnitState* textureUnitState); + + /** + Determines if the given texture unit state need to use texture transformation matrix. + */ + bool needsTextureMatrix(TextureUnitState* textureUnitState); + + /** + Determines whether a given texture unit needs to be processed by this srs + */ + virtual bool isProcessingNeeded(TextureUnitState* texUnitState); // Attributes. protected: - // Texture units list. - TextureUnitParamsList mTextureUnitParamsList; - // World matrix parameter. - UniformParameterPtr mWorldMatrix; - // World inverse transpose matrix parameter. - UniformParameterPtr mWorldITMatrix; - // View matrix parameter. - UniformParameterPtr mViewMatrix; - // Vertex shader input normal parameter. - ParameterPtr mVSInputNormal; - // Vertex shader input position parameter. - ParameterPtr mVSInputPos; - // Pixel shader output colour. - ParameterPtr mPSOutDiffuse; - // Pixel shader diffuse colour. - ParameterPtr mPSDiffuse; - // Pixel shader specular colour. - ParameterPtr mPSSpecular; + // Texture units list. + TextureUnitParamsList mTextureUnitParamsList; + // World matrix parameter. + UniformParameterPtr mWorldMatrix; + // World inverse transpose matrix parameter. + UniformParameterPtr mWorldITMatrix; + // View matrix parameter. + UniformParameterPtr mViewMatrix; + // Vertex shader input normal parameter. + ParameterPtr mVSInputNormal; + // Vertex shader input position parameter. + ParameterPtr mVSInputPos; + // Pixel shader output colour. + ParameterPtr mPSOutDiffuse; + // Pixel shader diffuse colour. + ParameterPtr mPSDiffuse; + // Pixel shader specular colour. + ParameterPtr mPSSpecular; }; @@ -250,28 +250,28 @@ class _OgreRTSSExport FFPTexturingFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); - + protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); }; diff --git a/Components/RTShaderSystem/include/OgreShaderFFPTransform.h b/Components/RTShaderSystem/include/OgreShaderFFPTransform.h index c1b874ae558..13b0e935dd4 100644 --- a/Components/RTShaderSystem/include/OgreShaderFFPTransform.h +++ b/Components/RTShaderSystem/include/OgreShaderFFPTransform.h @@ -50,29 +50,29 @@ class _OgreRTSSExport FFPTransform : public SubRenderState // Interface. public: - - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; + + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderState::getExecutionOrder. - */ - virtual int getExecutionOrder() const; + /** + @see SubRenderState::getExecutionOrder. + */ + virtual int getExecutionOrder() const; - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); - /** - @see SubRenderState::createCpuSubPrograms. - */ - virtual bool createCpuSubPrograms(ProgramSet* programSet); + /** + @see SubRenderState::createCpuSubPrograms. + */ + virtual bool createCpuSubPrograms(ProgramSet* programSet); - static String Type; + static String Type; }; @@ -84,27 +84,27 @@ class _OgreRTSSExport FFPTransformFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); diff --git a/Components/RTShaderSystem/include/OgreShaderFunction.h b/Components/RTShaderSystem/include/OgreShaderFunction.h index 96adcdb70c2..c2d3c7ae2d4 100644 --- a/Components/RTShaderSystem/include/OgreShaderFunction.h +++ b/Components/RTShaderSystem/include/OgreShaderFunction.h @@ -47,180 +47,180 @@ class _OgreRTSSExport Function : public RTShaderSystemAlloc { // Interface. public: - enum FunctionType - { - // internal function (default) - FFT_INTERNAL, - // Vertex program main - FFT_VS_MAIN, - // Pixel shader main - FFT_PS_MAIN - }; - - /** Get the name of this function */ - const String& getName() const { return mName; } - - /** Get the description of this function */ - const String& getDescription() const { return mDescription; } - - /** Resolve input parameter of this function - @param semantic The desired parameter semantic. - @param index The index of the desired parameter. - @param content The content of the parameter. - @param type The type of the desired parameter. - Return parameter instance in case of that resolve operation succeeded. - @remarks Pass -1 as index parameter to create a new parameter with the desired semantic and type. - */ - ParameterPtr resolveInputParameter(Parameter::Semantic semantic, int index, const Parameter::Content content, GpuConstantType type); - - - /** Resolve output parameter of this function - @param semantic The desired parameter semantic. - @param index The index of the desired parameter. - @param content The content of the parameter. - @param type The type of the desired parameter. - Return parameter instance in case of that resolve operation succeeded. - @remarks Pass -1 as index parameter to create a new parameter with the desired semantic and type. - */ - ParameterPtr resolveOutputParameter(Parameter::Semantic semantic, int index, const Parameter::Content content, GpuConstantType type); - - /** Resolve local parameter of this function - @param semantic The desired parameter semantic. - @param index The index of the desired parameter. - @param name The name of the parameter. - @param type The type of the desired parameter. - Return parameter instance in case of that resolve operation succeeded. - */ - ParameterPtr resolveLocalParameter(Parameter::Semantic semantic, int index, const String& name, GpuConstantType type); - - /** Resolve local parameter of this function - @param semantic The desired parameter semantic. - @param index The index of the desired parameter. - @param content The content of the parameter. - @param type The type of the desired parameter. - Return parameter instance in case of that resolve operation succeeded. - */ - ParameterPtr resolveLocalParameter(Parameter::Semantic semantic, int index, const Parameter::Content content, GpuConstantType type); - - - /** - Get parameter by a given name from the given parameter list. - @param parameterList The parameters list to look in. - @param name The name of the parameter to search in the list. - @remarks Return NULL if no matching parameter found. - */ - static ParameterPtr getParameterByName(const ShaderParameterList& parameterList, const String& name); - - /** - Get parameter by a given semantic and index from the given parameter list. - @param parameterList The parameters list to look in. - @param semantic The semantic of the parameter to search in the list. - @param index The index of the parameter to search in the list. - @remarks Return NULL if no matching parameter found. - */ - static ParameterPtr getParameterBySemantic(const ShaderParameterList& parameterList, const Parameter::Semantic semantic, int index); - - - /** - Get parameter by a given content and type from the given parameter list. - @param parameterList The parameters list to look in. - @param content The content of the parameter to search in the list. - @param type The type of the parameter to search in the list. - @remarks Return NULL if no matching parameter found. - */ - ParameterPtr getParameterByContent(const ShaderParameterList& parameterList, const Parameter::Content content, GpuConstantType type); - - /** Return a list of input parameters. */ - const ShaderParameterList& getInputParameters() const { return mInputParameters; } - - /** Return a list of output parameters. */ - const ShaderParameterList& getOutputParameters() const { return mOutputParameters; } - - /** Return a list of local parameters. */ - const ShaderParameterList& getLocalParameters() const { return mLocalParameters; } - - /** Add a function atom instance to this function. - @param atomInstance The atom instance to add. - */ - void addAtomInstance(FunctionAtom* atomInstance); - - /** Delete a function atom instance from this function. - @param atomInstance The atom instance to OGRE_DELETE. - */ - bool deleteAtomInstance(FunctionAtom* atomInstance); - - /** Sort all atom instances of this function. */ - void sortAtomInstances(); - - /** Return list of atom instances composing this function. */ - FunctionAtomInstanceList& getAtomInstances() { return mAtomInstances; } - - /** Return list of atom instances composing this function. (Const version) */ - const FunctionAtomInstanceList& getAtomInstances() const { return mAtomInstances; } - - /** Add input parameter to this function. */ - void addInputParameter(ParameterPtr parameter); - - /** Add output parameter to this function. */ - void addOutputParameter(ParameterPtr parameter); - - /** Delete input parameter from this function. */ - void deleteInputParameter(ParameterPtr parameter); - - /** Delete output parameter from this function. */ - void deleteOutputParameter(ParameterPtr parameter); - - /** Delete all input parameters from this function. */ - void deleteAllInputParameters(); - - /** Delete all output parameters from this function. */ - void deleteAllOutputParameters(); - - /** get function type. */ - FunctionType getFunctionType() const; + enum FunctionType + { + // internal function (default) + FFT_INTERNAL, + // Vertex program main + FFT_VS_MAIN, + // Pixel shader main + FFT_PS_MAIN + }; + + /** Get the name of this function */ + const String& getName() const { return mName; } + + /** Get the description of this function */ + const String& getDescription() const { return mDescription; } + + /** Resolve input parameter of this function + @param semantic The desired parameter semantic. + @param index The index of the desired parameter. + @param content The content of the parameter. + @param type The type of the desired parameter. + Return parameter instance in case of that resolve operation succeeded. + @remarks Pass -1 as index parameter to create a new parameter with the desired semantic and type. + */ + ParameterPtr resolveInputParameter(Parameter::Semantic semantic, int index, const Parameter::Content content, GpuConstantType type); + + + /** Resolve output parameter of this function + @param semantic The desired parameter semantic. + @param index The index of the desired parameter. + @param content The content of the parameter. + @param type The type of the desired parameter. + Return parameter instance in case of that resolve operation succeeded. + @remarks Pass -1 as index parameter to create a new parameter with the desired semantic and type. + */ + ParameterPtr resolveOutputParameter(Parameter::Semantic semantic, int index, const Parameter::Content content, GpuConstantType type); + + /** Resolve local parameter of this function + @param semantic The desired parameter semantic. + @param index The index of the desired parameter. + @param name The name of the parameter. + @param type The type of the desired parameter. + Return parameter instance in case of that resolve operation succeeded. + */ + ParameterPtr resolveLocalParameter(Parameter::Semantic semantic, int index, const String& name, GpuConstantType type); + + /** Resolve local parameter of this function + @param semantic The desired parameter semantic. + @param index The index of the desired parameter. + @param content The content of the parameter. + @param type The type of the desired parameter. + Return parameter instance in case of that resolve operation succeeded. + */ + ParameterPtr resolveLocalParameter(Parameter::Semantic semantic, int index, const Parameter::Content content, GpuConstantType type); + + + /** + Get parameter by a given name from the given parameter list. + @param parameterList The parameters list to look in. + @param name The name of the parameter to search in the list. + @remarks Return NULL if no matching parameter found. + */ + static ParameterPtr getParameterByName(const ShaderParameterList& parameterList, const String& name); + + /** + Get parameter by a given semantic and index from the given parameter list. + @param parameterList The parameters list to look in. + @param semantic The semantic of the parameter to search in the list. + @param index The index of the parameter to search in the list. + @remarks Return NULL if no matching parameter found. + */ + static ParameterPtr getParameterBySemantic(const ShaderParameterList& parameterList, const Parameter::Semantic semantic, int index); + + + /** + Get parameter by a given content and type from the given parameter list. + @param parameterList The parameters list to look in. + @param content The content of the parameter to search in the list. + @param type The type of the parameter to search in the list. + @remarks Return NULL if no matching parameter found. + */ + ParameterPtr getParameterByContent(const ShaderParameterList& parameterList, const Parameter::Content content, GpuConstantType type); + + /** Return a list of input parameters. */ + const ShaderParameterList& getInputParameters() const { return mInputParameters; } + + /** Return a list of output parameters. */ + const ShaderParameterList& getOutputParameters() const { return mOutputParameters; } + + /** Return a list of local parameters. */ + const ShaderParameterList& getLocalParameters() const { return mLocalParameters; } + + /** Add a function atom instance to this function. + @param atomInstance The atom instance to add. + */ + void addAtomInstance(FunctionAtom* atomInstance); + + /** Delete a function atom instance from this function. + @param atomInstance The atom instance to OGRE_DELETE. + */ + bool deleteAtomInstance(FunctionAtom* atomInstance); + + /** Sort all atom instances of this function. */ + void sortAtomInstances(); + + /** Return list of atom instances composing this function. */ + FunctionAtomInstanceList& getAtomInstances() { return mAtomInstances; } + + /** Return list of atom instances composing this function. (Const version) */ + const FunctionAtomInstanceList& getAtomInstances() const { return mAtomInstances; } + + /** Add input parameter to this function. */ + void addInputParameter(ParameterPtr parameter); + + /** Add output parameter to this function. */ + void addOutputParameter(ParameterPtr parameter); + + /** Delete input parameter from this function. */ + void deleteInputParameter(ParameterPtr parameter); + + /** Delete output parameter from this function. */ + void deleteOutputParameter(ParameterPtr parameter); + + /** Delete all input parameters from this function. */ + void deleteAllInputParameters(); + + /** Delete all output parameters from this function. */ + void deleteAllOutputParameters(); + + /** get function type. */ + FunctionType getFunctionType() const; protected: - /** Class constructor. - @param name The name of this function. - @param desc The description of this function. - @remarks This class is allocated via an instance of Program class. - */ - Function(const String& name, const String& desc, const FunctionType functionType); + /** Class constructor. + @param name The name of this function. + @param desc The description of this function. + @remarks This class is allocated via an instance of Program class. + */ + Function(const String& name, const String& desc, const FunctionType functionType); - /** Class destructor */ - ~Function(); + /** Class destructor */ + ~Function(); - /** Add parameter to given list */ - void addParameter(ShaderParameterList& parameterList, ParameterPtr parameter); + /** Add parameter to given list */ + void addParameter(ShaderParameterList& parameterList, ParameterPtr parameter); - /** Delete parameter from a given list */ - void deleteParameter(ShaderParameterList& parameterList, ParameterPtr parameter); + /** Delete parameter from a given list */ + void deleteParameter(ShaderParameterList& parameterList, ParameterPtr parameter); protected: - // Function name. - String mName; - // Function description. - String mDescription; - // Input parameters. - ShaderParameterList mInputParameters; - // Output parameters. - ShaderParameterList mOutputParameters; - // Local parameters. - ShaderParameterList mLocalParameters; - // Atom instances composing this function. - FunctionAtomInstanceList mAtomInstances; - // Function type - FunctionType mFunctionType; - + // Function name. + String mName; + // Function description. + String mDescription; + // Input parameters. + ShaderParameterList mInputParameters; + // Output parameters. + ShaderParameterList mOutputParameters; + // Local parameters. + ShaderParameterList mLocalParameters; + // Atom instances composing this function. + FunctionAtomInstanceList mAtomInstances; + // Function type + FunctionType mFunctionType; + private: - friend class Program; + friend class Program; }; -typedef vector::type ShaderFunctionList; -typedef ShaderFunctionList::iterator ShaderFunctionIterator; -typedef ShaderFunctionList::const_iterator ShaderFunctionConstIterator; +typedef vector::type ShaderFunctionList; +typedef ShaderFunctionList::iterator ShaderFunctionIterator; +typedef ShaderFunctionList::const_iterator ShaderFunctionConstIterator; /** @} */ /** @} */ diff --git a/Components/RTShaderSystem/include/OgreShaderFunctionAtom.h b/Components/RTShaderSystem/include/OgreShaderFunctionAtom.h index 441375f2935..6900cab7480 100644 --- a/Components/RTShaderSystem/include/OgreShaderFunctionAtom.h +++ b/Components/RTShaderSystem/include/OgreShaderFunctionAtom.h @@ -47,30 +47,30 @@ class _OgreRTSSExport FunctionAtom : public RTShaderSystemAlloc { // Interface. public: - /** Class default constructor. */ - FunctionAtom(); - - /** Class default destructor. */ - virtual ~FunctionAtom() {} - - /** Get the group execution order of this function atom. */ - int getGroupExecutionOrder() const; - - /** Get an internal execution order within a group of this function atom. */ - int getInternalExecutionOrder() const; - - /** Abstract method that writes a source code to the given output stream in the target shader language. */ - virtual void writeSourceCode(std::ostream& os, const String& targetLanguage) const = 0; - - /** Return the type of this atom instance implementation. */ - virtual const String& getFunctionAtomType() = 0; + /** Class default constructor. */ + FunctionAtom(); + + /** Class default destructor. */ + virtual ~FunctionAtom() {} + + /** Get the group execution order of this function atom. */ + int getGroupExecutionOrder() const; + + /** Get an internal execution order within a group of this function atom. */ + int getInternalExecutionOrder() const; + + /** Abstract method that writes a source code to the given output stream in the target shader language. */ + virtual void writeSourceCode(std::ostream& os, const String& targetLanguage) const = 0; + + /** Return the type of this atom instance implementation. */ + virtual const String& getFunctionAtomType() = 0; // Attributes. protected: - // The owner group execution order. - int mGroupExecutionOrder; - // The execution order within the group. - int mInternalExecutionOrder; + // The owner group execution order. + int mGroupExecutionOrder; + // The execution order within the group. + int mInternalExecutionOrder; }; /** A class that represents a function operand (its the combination of a parameter the in/out semantic and the used fields) @@ -79,143 +79,143 @@ class _OgreRTSSExport Operand : public RTShaderSystemAlloc { public: - // InOut semantic - enum OpSemantic - { - /// The parameter is a input parameter - OPS_IN, - /// The parameter is a output parameter - OPS_OUT, - /// The parameter is a input/output parameter - OPS_INOUT - }; - - // Used field mask - enum OpMask - { - OPM_ALL = 0x0001, - OPM_X = 0x0002, - OPM_Y = 0x0004, - OPM_Z = 0x0008, - OPM_W = 0x0010, - OPM_XY = OPM_X | OPM_Y, - OPM_XZ = OPM_X | OPM_Z, - OPM_XW = OPM_X | OPM_W, - OPM_YZ = OPM_Y | OPM_Z, - OPM_YW = OPM_Y | OPM_W, - OPM_ZW = OPM_Z | OPM_W, - OPM_XYZ = OPM_X | OPM_Y | OPM_Z, - OPM_XYW = OPM_X | OPM_Y | OPM_W, - OPM_XZW = OPM_X | OPM_Z | OPM_W, - OPM_YZW = OPM_Y | OPM_Z | OPM_W, - OPM_XYZW = OPM_X | OPM_Y | OPM_Z | OPM_W - }; - - /** Class constructor - @param parameter A function parameter. - @param opSemantic The in/out semantic of the parameter. - @param opMask The field mask of the parameter. - */ - Operand(ParameterPtr parameter, Operand::OpSemantic opSemantic, int opMask = Operand::OPM_ALL, ushort indirectionLevel = 0); - - /** Copy constructor */ - Operand(const Operand& rhs); - - /** Copy the given Operand to this Operand. - @param rhs The other Operand to copy to this state. - */ - Operand& operator= (const Operand & rhs); - - /** Class destructor */ - ~Operand(); - - /** Returns the parameter object as weak reference */ - const ParameterPtr& getParameter() const { return mParameter; } - - /** Returns true if not all fields used. (usage is described through semantic)*/ - bool hasFreeFields() const { return ((mMask & ~OPM_ALL) && ((mMask & ~OPM_X) || (mMask & ~OPM_Y) || (mMask & ~OPM_Z) || (mMask & ~OPM_W))); } - - /** Returns the mask bitfield. */ - int getMask() const { return mMask; } - - /** Returns the operand semantic (do we read/write or both with the parameter). */ - OpSemantic getSemantic() const { return mSemantic; } - - /** Returns the level of indirection. - The greater the indirection level the more the parameter needs to be nested in brackets. - For example given 4 parameters x1...x4 with the indirections levels 0,1,1,2 - respectively. The parameters should form the following string: x1[x2][x3[x4]]. - */ - ushort getIndirectionLevel() const { return mIndirectionLevel; } - - /** Returns the parameter name and the usage mask like this 'color.xyz' */ - String toString() const; - - /** Returns the given mask as string representation. */ - static String getMaskAsString(int mask); - - /** Return the float count of the given mask. */ - static int getFloatCount(int mask); - - /** Return the gpu constant type of the given mask. */ - static GpuConstantType getGpuConstantType(int mask); + // InOut semantic + enum OpSemantic + { + /// The parameter is a input parameter + OPS_IN, + /// The parameter is a output parameter + OPS_OUT, + /// The parameter is a input/output parameter + OPS_INOUT + }; + + // Used field mask + enum OpMask + { + OPM_ALL = 0x0001, + OPM_X = 0x0002, + OPM_Y = 0x0004, + OPM_Z = 0x0008, + OPM_W = 0x0010, + OPM_XY = OPM_X | OPM_Y, + OPM_XZ = OPM_X | OPM_Z, + OPM_XW = OPM_X | OPM_W, + OPM_YZ = OPM_Y | OPM_Z, + OPM_YW = OPM_Y | OPM_W, + OPM_ZW = OPM_Z | OPM_W, + OPM_XYZ = OPM_X | OPM_Y | OPM_Z, + OPM_XYW = OPM_X | OPM_Y | OPM_W, + OPM_XZW = OPM_X | OPM_Z | OPM_W, + OPM_YZW = OPM_Y | OPM_Z | OPM_W, + OPM_XYZW = OPM_X | OPM_Y | OPM_Z | OPM_W + }; + + /** Class constructor + @param parameter A function parameter. + @param opSemantic The in/out semantic of the parameter. + @param opMask The field mask of the parameter. + */ + Operand(ParameterPtr parameter, Operand::OpSemantic opSemantic, int opMask = Operand::OPM_ALL, ushort indirectionLevel = 0); + + /** Copy constructor */ + Operand(const Operand& rhs); + + /** Copy the given Operand to this Operand. + @param rhs The other Operand to copy to this state. + */ + Operand& operator= (const Operand & rhs); + + /** Class destructor */ + ~Operand(); + + /** Returns the parameter object as weak reference */ + const ParameterPtr& getParameter() const { return mParameter; } + + /** Returns true if not all fields used. (usage is described through semantic)*/ + bool hasFreeFields() const { return ((mMask & ~OPM_ALL) && ((mMask & ~OPM_X) || (mMask & ~OPM_Y) || (mMask & ~OPM_Z) || (mMask & ~OPM_W))); } + + /** Returns the mask bitfield. */ + int getMask() const { return mMask; } + + /** Returns the operand semantic (do we read/write or both with the parameter). */ + OpSemantic getSemantic() const { return mSemantic; } + + /** Returns the level of indirection. + The greater the indirection level the more the parameter needs to be nested in brackets. + For example given 4 parameters x1...x4 with the indirections levels 0,1,1,2 + respectively. The parameters should form the following string: x1[x2][x3[x4]]. + */ + ushort getIndirectionLevel() const { return mIndirectionLevel; } + + /** Returns the parameter name and the usage mask like this 'color.xyz' */ + String toString() const; + + /** Returns the given mask as string representation. */ + static String getMaskAsString(int mask); + + /** Return the float count of the given mask. */ + static int getFloatCount(int mask); + + /** Return the gpu constant type of the given mask. */ + static GpuConstantType getGpuConstantType(int mask); protected: - /// The parameter being carried by the operand - ParameterPtr mParameter; - /// Tells if the parameter is of type input,output or both - OpSemantic mSemantic; - /// Which part of the parameter should be passed (x,y,z,w) - int mMask; - /// The level of indirection. @see getIndirectionLevel - ushort mIndirectionLevel; + /// The parameter being carried by the operand + ParameterPtr mParameter; + /// Tells if the parameter is of type input,output or both + OpSemantic mSemantic; + /// Which part of the parameter should be passed (x,y,z,w) + int mMask; + /// The level of indirection. @see getIndirectionLevel + ushort mIndirectionLevel; }; /** A class that represents function invocation code from shader based program function. */ class _OgreRTSSExport FunctionInvocation : public FunctionAtom { - // Interface. -public: - typedef vector::type OperandVector; - - /** Class constructor - @param functionName The name of the function to invoke. - @param groupOrder The group order of this invocation. - @param internalOrder The internal order of this invocation. - @param returnType The return type of the used function. - */ - FunctionInvocation(const String& functionName, int groupOrder, int internalOrder, String returnType = "void"); + // Interface. +public: + typedef vector::type OperandVector; + + /** Class constructor + @param functionName The name of the function to invoke. + @param groupOrder The group order of this invocation. + @param internalOrder The internal order of this invocation. + @param returnType The return type of the used function. + */ + FunctionInvocation(const String& functionName, int groupOrder, int internalOrder, String returnType = "void"); /** Copy constructor */ - FunctionInvocation(const FunctionInvocation& rhs); - - /** - @see FunctionAtom::writeSourceCode - */ - virtual void writeSourceCode(std::ostream& os, const String& targetLanguage) const; - - /** - @see FunctionAtom::getFunctionAtomType - */ - virtual const String& getFunctionAtomType() { return Type; } - - /** Get a list of parameters this function invocation will use in the function call as arguments. */ - OperandVector& getOperandList() { return mOperands; } - - /** Push a new operand (on the end) to the function. - @param parameter A function parameter. - @param opSemantic The in/out semantic of the parameter. - @param opMask The field mask of the parameter. - @param indirectionLevel The level of nesting inside brackets - */ - void pushOperand(ParameterPtr parameter, Operand::OpSemantic opSemantic, int opMask = Operand::OPM_ALL, int indirectionLevel = 0); - - /** Return the function name */ - const String& getFunctionName() const { return mFunctionName; } - - /** Return the return type */ - const String& getReturnType() const { return mReturnType; } + FunctionInvocation(const FunctionInvocation& rhs); + + /** + @see FunctionAtom::writeSourceCode + */ + virtual void writeSourceCode(std::ostream& os, const String& targetLanguage) const; + + /** + @see FunctionAtom::getFunctionAtomType + */ + virtual const String& getFunctionAtomType() { return Type; } + + /** Get a list of parameters this function invocation will use in the function call as arguments. */ + OperandVector& getOperandList() { return mOperands; } + + /** Push a new operand (on the end) to the function. + @param parameter A function parameter. + @param opSemantic The in/out semantic of the parameter. + @param opMask The field mask of the parameter. + @param indirectionLevel The level of nesting inside brackets + */ + void pushOperand(ParameterPtr parameter, Operand::OpSemantic opSemantic, int opMask = Operand::OPM_ALL, int indirectionLevel = 0); + + /** Return the function name */ + const String& getFunctionName() const { return mFunctionName; } + + /** Return the return type */ + const String& getReturnType() const { return mReturnType; } /** Determines if the current object is equal to the compared one. */ bool operator == ( const FunctionInvocation& rhs ) const; @@ -242,19 +242,19 @@ class _OgreRTSSExport FunctionInvocation : public FunctionAtom bool operator()(FunctionInvocation const& lhs, FunctionInvocation const& rhs) const; }; - /// The type of this class. - static String Type; + /// The type of this class. + static String Type; - // Attributes. -protected: - String mFunctionName; - String mReturnType; - OperandVector mOperands; + // Attributes. +protected: + String mFunctionName; + String mReturnType; + OperandVector mOperands; }; -typedef vector::type FunctionAtomInstanceList; -typedef FunctionAtomInstanceList::iterator FunctionAtomInstanceIterator; -typedef FunctionAtomInstanceList::const_iterator FunctionAtomInstanceConstIterator; +typedef vector::type FunctionAtomInstanceList; +typedef FunctionAtomInstanceList::iterator FunctionAtomInstanceIterator; +typedef FunctionAtomInstanceList::const_iterator FunctionAtomInstanceConstIterator; /** @} */ /** @} */ diff --git a/Components/RTShaderSystem/include/OgreShaderGLSLESProgramProcessor.h b/Components/RTShaderSystem/include/OgreShaderGLSLESProgramProcessor.h index f294e9bc51a..04956253c1e 100644 --- a/Components/RTShaderSystem/include/OgreShaderGLSLESProgramProcessor.h +++ b/Components/RTShaderSystem/include/OgreShaderGLSLESProgramProcessor.h @@ -47,38 +47,38 @@ class GLSLESProgramProcessor : public ProgramProcessor { // Interface. -public: +public: - /** Class constructor. - */ - GLSLESProgramProcessor(); + /** Class constructor. + */ + GLSLESProgramProcessor(); - /** Class destructor */ - virtual ~GLSLESProgramProcessor(); + /** Class destructor */ + virtual ~GLSLESProgramProcessor(); - /** Return the target language of this processor. */ - virtual const String& getTargetLanguage() const { return TargetLanguage; } + /** Return the target language of this processor. */ + virtual const String& getTargetLanguage() const { return TargetLanguage; } - /** - @see ProgramProcessor::preCreateGpuPrograms + /** + @see ProgramProcessor::preCreateGpuPrograms */ - virtual bool preCreateGpuPrograms(ProgramSet* programSet); + virtual bool preCreateGpuPrograms(ProgramSet* programSet); - /** - @see ProgramProcessor::postCreateGpuPrograms - */ - virtual bool postCreateGpuPrograms(ProgramSet* programSet); + /** + @see ProgramProcessor::postCreateGpuPrograms + */ + virtual bool postCreateGpuPrograms(ProgramSet* programSet); private: - /** Bind texture samplers. */ - void bindTextureSamplers(Program* pCpuProgram, GpuProgramPtr pGpuProgram); + /** Bind texture samplers. */ + void bindTextureSamplers(Program* pCpuProgram, GpuProgramPtr pGpuProgram); - static String TargetLanguage; + static String TargetLanguage; - // The list of created library shaders. - StringVector mLibraryPrograms; + // The list of created library shaders. + StringVector mLibraryPrograms; }; diff --git a/Components/RTShaderSystem/include/OgreShaderGLSLESProgramWriter.h b/Components/RTShaderSystem/include/OgreShaderGLSLESProgramWriter.h index c38095a2de0..6cbeedac250 100644 --- a/Components/RTShaderSystem/include/OgreShaderGLSLESProgramWriter.h +++ b/Components/RTShaderSystem/include/OgreShaderGLSLESProgramWriter.h @@ -52,84 +52,84 @@ namespace RTShader { */ class GLSLESProgramWriter : public ProgramWriter { - // Interface. + // Interface. public: - /** Class constructor. - */ - GLSLESProgramWriter (); + /** Class constructor. + */ + GLSLESProgramWriter (); - /** Class destructor */ - virtual ~GLSLESProgramWriter (); + /** Class destructor */ + virtual ~GLSLESProgramWriter (); - /** - @see ProgramWriter::writeSourceCode. - */ - virtual void writeSourceCode (std::ostream& os, Program* program); + /** + @see ProgramWriter::writeSourceCode. + */ + virtual void writeSourceCode (std::ostream& os, Program* program); - /** - @see ProgramWriter::getTargetLanguage. - */ - virtual const String& getTargetLanguage () const { return TargetLanguage; } + /** + @see ProgramWriter::getTargetLanguage. + */ + virtual const String& getTargetLanguage () const { return TargetLanguage; } - static String TargetLanguage; + static String TargetLanguage; protected: - typedef map::type GpuConstTypeToStringMap; - typedef map::type ParamSemanticToStringMap; - typedef map ::type ParamContentToStringMap; - typedef map::type StringMap; - typedef map::type FunctionMap; - typedef vector::type FunctionVector; + typedef map::type GpuConstTypeToStringMap; + typedef map::type ParamSemanticToStringMap; + typedef map ::type ParamContentToStringMap; + typedef map::type StringMap; + typedef map::type FunctionMap; + typedef vector::type FunctionVector; typedef FunctionMap::const_iterator FunctionMapIterator; typedef FunctionVector::const_iterator FunctionVectorIterator; typedef GpuConstTypeToStringMap::const_iterator GpuConstTypeToStringMapIterator; - // Protected methods. + // Protected methods. protected: - /** Initialize string maps. */ - void initializeStringMaps (); + /** Initialize string maps. */ + void initializeStringMaps (); /** Cache functions of a dependency */ virtual void cacheDependencyFunctions(const String & libName); /** Create a FunctionInvocation object from a string taken out of a shader library. */ - FunctionInvocation *createInvocationFromString (const String & input); + FunctionInvocation *createInvocationFromString (const String & input); /** Write the program dependencies. */ - void writeProgramDependencies (std::ostream& os, Program* program); + void writeProgramDependencies (std::ostream& os, Program* program); - /** Write a local parameter. */ - void writeLocalParameter (std::ostream& os, ParameterPtr parameter); + /** Write a local parameter. */ + void writeLocalParameter (std::ostream& os, ParameterPtr parameter); - /** Write the input params of the function */ - void writeInputParameters (std::ostream& os, Function* function, GpuProgramType gpuType); - - /** Write the output params of the function */ - void writeOutParameters (std::ostream& os, Function* function, GpuProgramType gpuType); + /** Write the input params of the function */ + void writeInputParameters (std::ostream& os, Function* function, GpuProgramType gpuType); + + /** Write the output params of the function */ + void writeOutParameters (std::ostream& os, Function* function, GpuProgramType gpuType); - String processOperand(Operand op, GpuProgramType gpuType); - + String processOperand(Operand op, GpuProgramType gpuType); + /** Check if a string matches one of the GLSL ES basic types */ bool isBasicType(String &type); /** Search within a function body for non-builtin functions that a given function invocation depends on. */ void discoverFunctionDependencies(const FunctionInvocation &invoc, FunctionVector &depVector); - // Attributes. + // Attributes. protected: - GpuConstTypeToStringMap mGpuConstTypeMap; // Map between GPU constant type to string value. - ParamSemanticToStringMap mParamSemanticMap; // Map between parameter semantic to string value. + GpuConstTypeToStringMap mGpuConstTypeMap; // Map between GPU constant type to string value. + ParamSemanticToStringMap mParamSemanticMap; // Map between parameter semantic to string value. - StringMap mInputToGLStatesMap; // Map parameter name to a new parameter name (sometimes renaming is required to match names between vertex and fragment shader) - FunctionMap mFunctionCacheMap; // Map function invocation to body. Used as a cache to reduce library file reads and for inlining + StringMap mInputToGLStatesMap; // Map parameter name to a new parameter name (sometimes renaming is required to match names between vertex and fragment shader) + FunctionMap mFunctionCacheMap; // Map function invocation to body. Used as a cache to reduce library file reads and for inlining StringMap mDefinesMap; // Map of #defines and the function library that contains them - ParamContentToStringMap mContentToPerVertexAttributes; // Map parameter content to vertex attributes - int mGLSLVersion; // Holds the current glsl es version - StringVector mFragInputParams; // Holds the fragment input params + ParamContentToStringMap mContentToPerVertexAttributes; // Map parameter content to vertex attributes + int mGLSLVersion; // Holds the current glsl es version + StringVector mFragInputParams; // Holds the fragment input params StringMap mCachedFunctionLibraries; // Holds the cached function libraries }; @@ -139,29 +139,29 @@ class GLSLESProgramWriter : public ProgramWriter class ShaderProgramWriterGLSLESFactory : public ProgramWriterFactory { public: - ShaderProgramWriterGLSLESFactory() : mLanguage("glsles") - { - } - virtual ~ShaderProgramWriterGLSLESFactory() {} - - /** - @see ProgramWriterFactory::getTargetLanguage - */ - virtual const String& getTargetLanguage(void) const - { - return mLanguage; - } - - /** - @see ProgramWriterFactory::create - */ - virtual ProgramWriter* create(void) - { - return OGRE_NEW GLSLESProgramWriter(); - } + ShaderProgramWriterGLSLESFactory() : mLanguage("glsles") + { + } + virtual ~ShaderProgramWriterGLSLESFactory() {} + + /** + @see ProgramWriterFactory::getTargetLanguage + */ + virtual const String& getTargetLanguage(void) const + { + return mLanguage; + } + + /** + @see ProgramWriterFactory::create + */ + virtual ProgramWriter* create(void) + { + return OGRE_NEW GLSLESProgramWriter(); + } private: - String mLanguage; + String mLanguage; }; /** @} */ diff --git a/Components/RTShaderSystem/include/OgreShaderGLSLProgramProcessor.h b/Components/RTShaderSystem/include/OgreShaderGLSLProgramProcessor.h index b069efde699..aeaff7918ad 100644 --- a/Components/RTShaderSystem/include/OgreShaderGLSLProgramProcessor.h +++ b/Components/RTShaderSystem/include/OgreShaderGLSLProgramProcessor.h @@ -47,41 +47,41 @@ class _OgreRTSSExport GLSLProgramProcessor : public ProgramProcessor { // Interface. -public: +public: - /** Class constructor. - */ - GLSLProgramProcessor(); + /** Class constructor. + */ + GLSLProgramProcessor(); - /** Class destructor */ - virtual ~GLSLProgramProcessor(); + /** Class destructor */ + virtual ~GLSLProgramProcessor(); - /** Return the target language of this processor. */ - virtual const String& getTargetLanguage() const { return TargetLanguage; } + /** Return the target language of this processor. */ + virtual const String& getTargetLanguage() const { return TargetLanguage; } - /** - @see ProgramProcessor::preCreateGpuPrograms - */ - virtual bool preCreateGpuPrograms(ProgramSet* programSet); + /** + @see ProgramProcessor::preCreateGpuPrograms + */ + virtual bool preCreateGpuPrograms(ProgramSet* programSet); - /** - @see ProgramProcessor::postCreateGpuPrograms - */ - virtual bool postCreateGpuPrograms(ProgramSet* programSet); + /** + @see ProgramProcessor::postCreateGpuPrograms + */ + virtual bool postCreateGpuPrograms(ProgramSet* programSet); private: - /** Bind texture samplers. */ - void bindTextureSamplers(Program* pCpuProgram, GpuProgramPtr pGpuProgram); + /** Bind texture samplers. */ + void bindTextureSamplers(Program* pCpuProgram, GpuProgramPtr pGpuProgram); - /** Compiles sub shaders (only if the not exists) and attach them to the main gpu program. */ - void bindSubShaders(Program* program, GpuProgramPtr pGpuProgram); + /** Compiles sub shaders (only if the not exists) and attach them to the main gpu program. */ + void bindSubShaders(Program* program, GpuProgramPtr pGpuProgram); - static String TargetLanguage; + static String TargetLanguage; - // The list of created library shaders. - StringVector mLibraryPrograms; + // The list of created library shaders. + StringVector mLibraryPrograms; }; diff --git a/Components/RTShaderSystem/include/OgreShaderGLSLProgramWriter.h b/Components/RTShaderSystem/include/OgreShaderGLSLProgramWriter.h index 2aae36bdec6..eb07fcb2f92 100644 --- a/Components/RTShaderSystem/include/OgreShaderGLSLProgramWriter.h +++ b/Components/RTShaderSystem/include/OgreShaderGLSLProgramWriter.h @@ -50,69 +50,69 @@ namespace RTShader { */ class _OgreRTSSExport GLSLProgramWriter : public ProgramWriter { - // Interface. + // Interface. public: - /** Class constructor. - */ - GLSLProgramWriter(); + /** Class constructor. + */ + GLSLProgramWriter(); - /** Class destructor */ - virtual ~GLSLProgramWriter(); + /** Class destructor */ + virtual ~GLSLProgramWriter(); - /** - @see ProgramWriter::writeSourceCode. - */ - virtual void writeSourceCode(std::ostream& os, Program* program); + /** + @see ProgramWriter::writeSourceCode. + */ + virtual void writeSourceCode(std::ostream& os, Program* program); - /** - @see ProgramWriter::getTargetLanguage. - */ - virtual const String& getTargetLanguage() const { return TargetLanguage; } + /** + @see ProgramWriter::getTargetLanguage. + */ + virtual const String& getTargetLanguage() const { return TargetLanguage; } - static String TargetLanguage; + static String TargetLanguage; - // Protected methods. + // Protected methods. protected: - /** Initialize string maps. */ - void initializeStringMaps(); + /** Initialize string maps. */ + void initializeStringMaps(); - /** Write a local parameter. */ - void writeLocalParameter(std::ostream& os, ParameterPtr parameter); + /** Write a local parameter. */ + void writeLocalParameter(std::ostream& os, ParameterPtr parameter); - /** Write forward declarations. This is needed so that we can attach library shader at a later step. */ - void writeForwardDeclarations(std::ostream& os, Program* program); + /** Write forward declarations. This is needed so that we can attach library shader at a later step. */ + void writeForwardDeclarations(std::ostream& os, Program* program); - /** Write the input params of the function */ - void writeInputParameters(std::ostream& os, Function* function, GpuProgramType gpuType); - - /** Write the output params of the function */ - void writeOutParameters(std::ostream& os, Function* function, GpuProgramType gpuType); + /** Write the input params of the function */ + void writeInputParameters(std::ostream& os, Function* function, GpuProgramType gpuType); + + /** Write the output params of the function */ + void writeOutParameters(std::ostream& os, Function* function, GpuProgramType gpuType); protected: - typedef map::type GpuConstTypeToStringMap; - typedef map::type ParamSemanticToStringMap; - typedef map::type ParamContentToStringMap; - typedef map::type StringMap; + typedef map::type GpuConstTypeToStringMap; + typedef map::type ParamSemanticToStringMap; + typedef map::type ParamContentToStringMap; + typedef map::type StringMap; - // Attributes. + // Attributes. protected: - // Map between GPU constant type to string value. - GpuConstTypeToStringMap mGpuConstTypeMap; - // Map between parameter semantic to string value. - ParamSemanticToStringMap mParamSemanticMap; - - // Map parameter name to a new parameter name (sometime renaming is required to match names between vertex and fragment shader) - StringMap mInputToGLStatesMap; - // Map parameter content to vertex attributes - ParamContentToStringMap mContentToPerVertexAttributes; - // Holds the current glsl version - int mGLSLVersion; - // Holds the fragment input params - StringVector mFragInputParams; + // Map between GPU constant type to string value. + GpuConstTypeToStringMap mGpuConstTypeMap; + // Map between parameter semantic to string value. + ParamSemanticToStringMap mParamSemanticMap; + + // Map parameter name to a new parameter name (sometime renaming is required to match names between vertex and fragment shader) + StringMap mInputToGLStatesMap; + // Map parameter content to vertex attributes + ParamContentToStringMap mContentToPerVertexAttributes; + // Holds the current glsl version + int mGLSLVersion; + // Holds the fragment input params + StringVector mFragInputParams; }; /** GLSL program writer factory implementation. @@ -121,29 +121,29 @@ class _OgreRTSSExport GLSLProgramWriter : public ProgramWriter class _OgreRTSSExport ShaderProgramWriterGLSLFactory : public ProgramWriterFactory { public: - ShaderProgramWriterGLSLFactory() : mLanguage("glsl") - { - } - virtual ~ShaderProgramWriterGLSLFactory() {} - - /** - @see ProgramWriterFactory::getTargetLanguage - */ - virtual const String& getTargetLanguage(void) const - { - return mLanguage; - } - - /** - @see ProgramWriterFactory::create - */ - virtual ProgramWriter* create(void) - { - return OGRE_NEW GLSLProgramWriter(); - } + ShaderProgramWriterGLSLFactory() : mLanguage("glsl") + { + } + virtual ~ShaderProgramWriterGLSLFactory() {} + + /** + @see ProgramWriterFactory::getTargetLanguage + */ + virtual const String& getTargetLanguage(void) const + { + return mLanguage; + } + + /** + @see ProgramWriterFactory::create + */ + virtual ProgramWriter* create(void) + { + return OGRE_NEW GLSLProgramWriter(); + } private: - String mLanguage; + String mLanguage; }; diff --git a/Components/RTShaderSystem/include/OgreShaderGenerator.h b/Components/RTShaderSystem/include/OgreShaderGenerator.h index 054038bdec1..9c77705ae38 100644 --- a/Components/RTShaderSystem/include/OgreShaderGenerator.h +++ b/Components/RTShaderSystem/include/OgreShaderGenerator.h @@ -57,186 +57,186 @@ class _OgreRTSSExport ShaderGenerator : public Singleton, publi // Interface. public: - /** - Initialize the Shader Generator System. - Return true upon success. - */ - static bool initialize(); - - /** - Destroy the Shader Generator instance. - */ - static void destroy(); - - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static ShaderGenerator& getSingleton(); - - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static ShaderGenerator* getSingletonPtr(); - - /** - Add a scene manager to the shader generator scene managers list. - @param sceneMgr The scene manager to add to the list. - */ - void addSceneManager(SceneManager* sceneMgr); - - /** - Remove a scene manager from the shader generator scene managers list. - @param sceneMgr The scene manager to remove from the list. - */ - void removeSceneManager(SceneManager* sceneMgr); - - /** - Get the active scene manager that is doint the actual scene rendering. - This attribute will be update on the call to preFindVisibleObjects. - */ - SceneManager* getActiveSceneManager(); - - /** - Set the active scene manager against which new render states are compiled. - Note that normally the setting of the active scene manager is updated through the - preFindVisibleObjects method. - */ - - void _setActiveSceneManager(SceneManager* sceneManager); - - /** - Set the target shader language. - @param shaderLanguage The output shader language to use. - @remarks The default shader language is cg. - */ - void setTargetLanguage(const String& shaderLanguage,const float version = 1.0); - - /** - Return if hlsl 4.0 shading language is currently in use. - */ - bool IsHlsl4() const { return mShaderLanguage == "hlsl" && mShaderLanguageVersion == 4.0f; } - /** - Return the target shader language currently in use. - */ - const String& getTargetLanguage() const { return mShaderLanguage; } - - /** - Return the target shader language version currently in use. - */ - float getTargetLanguageVersion() const { return mShaderLanguageVersion; } - - /** - Set the output vertex shader target profiles. - @param vertexShaderProfiles The target profiles for the vertex shader. - */ - void setVertexShaderProfiles(const String& vertexShaderProfiles); - - /** - Get the output vertex shader target profiles. - */ - const String& getVertexShaderProfiles() const { return mVertexShaderProfiles; } - - /** - Get the output vertex shader target profiles as list of strings. - */ - const StringVector& getVertexShaderProfilesList() const { return mVertexShaderProfilesList; } - - - /** - Set the output fragment shader target profiles. - @param fragmentShaderProfiles The target profiles for the fragment shader. - */ - void setFragmentShaderProfiles(const String& fragmentShaderProfiles); - - /** - Get the output fragment shader target profiles. - */ - const String& getFragmentShaderProfiles() const { return mFragmentShaderProfiles; } - - /** - Get the output fragment shader target profiles as list of strings. - */ - const StringVector& getFragmentShaderProfilesList() const { return mFragmentShaderProfilesList; } - - /** - Set the output shader cache path. Generated shader code will be written to this path. - In case of empty cache path shaders will be generated directly from system memory. - @param cachePath The cache path of the shader. - The default is empty cache path. - */ - void setShaderCachePath(const String& cachePath); - - /** - Get the output shader cache path. - */ - const String& getShaderCachePath() const { return mShaderCachePath; } - - /** - Flush the shader cache. This operation will cause all active sachems to be invalidated and will - destroy any CPU/GPU program that created by this shader generator. - */ - void flushShaderCache(); - - /** - Return a global render state associated with the given scheme name. - Modifying this render state will affect all techniques that belongs to that scheme. - This is the best way to apply global changes to all techniques. - After altering the render state one should call invalidateScheme method in order to - regenerate shaders. - @param schemeName The destination scheme name. - */ - RenderState* getRenderState(const String& schemeName); - - - typedef std::pair RenderStateCreateOrRetrieveResult; - /** - Returns a requested render state. If the render state does not exist this function creates it. - @param schemeName The scheme name to retrieve. - */ - RenderStateCreateOrRetrieveResult createOrRetrieveRenderState(const String& schemeName); - - - /** - Tells if a given render state exists - @param schemeName The scheme name to check. - */ - bool hasRenderState(const String& schemeName) const; - + /** + Initialize the Shader Generator System. + Return true upon success. + */ + static bool initialize(); + + /** + Destroy the Shader Generator instance. + */ + static void destroy(); + + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static ShaderGenerator& getSingleton(); + + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static ShaderGenerator* getSingletonPtr(); + + /** + Add a scene manager to the shader generator scene managers list. + @param sceneMgr The scene manager to add to the list. + */ + void addSceneManager(SceneManager* sceneMgr); + + /** + Remove a scene manager from the shader generator scene managers list. + @param sceneMgr The scene manager to remove from the list. + */ + void removeSceneManager(SceneManager* sceneMgr); + + /** + Get the active scene manager that is doint the actual scene rendering. + This attribute will be update on the call to preFindVisibleObjects. + */ + SceneManager* getActiveSceneManager(); + + /** + Set the active scene manager against which new render states are compiled. + Note that normally the setting of the active scene manager is updated through the + preFindVisibleObjects method. + */ + + void _setActiveSceneManager(SceneManager* sceneManager); + + /** + Set the target shader language. + @param shaderLanguage The output shader language to use. + @remarks The default shader language is cg. + */ + void setTargetLanguage(const String& shaderLanguage,const float version = 1.0); + + /** + Return if hlsl 4.0 shading language is currently in use. + */ + bool IsHlsl4() const { return mShaderLanguage == "hlsl" && mShaderLanguageVersion == 4.0f; } + /** + Return the target shader language currently in use. + */ + const String& getTargetLanguage() const { return mShaderLanguage; } + + /** + Return the target shader language version currently in use. + */ + float getTargetLanguageVersion() const { return mShaderLanguageVersion; } + + /** + Set the output vertex shader target profiles. + @param vertexShaderProfiles The target profiles for the vertex shader. + */ + void setVertexShaderProfiles(const String& vertexShaderProfiles); + + /** + Get the output vertex shader target profiles. + */ + const String& getVertexShaderProfiles() const { return mVertexShaderProfiles; } + + /** + Get the output vertex shader target profiles as list of strings. + */ + const StringVector& getVertexShaderProfilesList() const { return mVertexShaderProfilesList; } + + + /** + Set the output fragment shader target profiles. + @param fragmentShaderProfiles The target profiles for the fragment shader. + */ + void setFragmentShaderProfiles(const String& fragmentShaderProfiles); + + /** + Get the output fragment shader target profiles. + */ + const String& getFragmentShaderProfiles() const { return mFragmentShaderProfiles; } /** - Get render state of specific pass. - Using this method allows the user to customize the behavior of a specific pass. - @param schemeName The destination scheme name. - @param materialName The specific material name. - @param passIndex The pass index. - */ - RenderState* getRenderState(const String& schemeName, const String& materialName, unsigned short passIndex); + Get the output fragment shader target profiles as list of strings. + */ + const StringVector& getFragmentShaderProfilesList() const { return mFragmentShaderProfilesList; } + + /** + Set the output shader cache path. Generated shader code will be written to this path. + In case of empty cache path shaders will be generated directly from system memory. + @param cachePath The cache path of the shader. + The default is empty cache path. + */ + void setShaderCachePath(const String& cachePath); + + /** + Get the output shader cache path. + */ + const String& getShaderCachePath() const { return mShaderCachePath; } + + /** + Flush the shader cache. This operation will cause all active sachems to be invalidated and will + destroy any CPU/GPU program that created by this shader generator. + */ + void flushShaderCache(); + + /** + Return a global render state associated with the given scheme name. + Modifying this render state will affect all techniques that belongs to that scheme. + This is the best way to apply global changes to all techniques. + After altering the render state one should call invalidateScheme method in order to + regenerate shaders. + @param schemeName The destination scheme name. + */ + RenderState* getRenderState(const String& schemeName); + + + typedef std::pair RenderStateCreateOrRetrieveResult; + /** + Returns a requested render state. If the render state does not exist this function creates it. + @param schemeName The scheme name to retrieve. + */ + RenderStateCreateOrRetrieveResult createOrRetrieveRenderState(const String& schemeName); + + + /** + Tells if a given render state exists + @param schemeName The scheme name to check. + */ + bool hasRenderState(const String& schemeName) const; + + + /** + Get render state of specific pass. + Using this method allows the user to customize the behavior of a specific pass. + @param schemeName The destination scheme name. + @param materialName The specific material name. + @param passIndex The pass index. + */ + RenderState* getRenderState(const String& schemeName, const String& materialName, unsigned short passIndex); /** Get render state of specific pass. @@ -248,58 +248,58 @@ class _OgreRTSSExport ShaderGenerator : public Singleton, publi */ RenderState* getRenderState(const String& schemeName, const String& materialName, const String& groupName, unsigned short passIndex); - /** - Add sub render state factory. Plugins or 3d party applications may implement sub classes of - SubRenderState interface. Add the matching factory will allow the application to create instances - of these sub classes. - @param factory The factory to add. - */ - void addSubRenderStateFactory(SubRenderStateFactory* factory); - - /** - Returns the number of existing factories - */ - size_t getNumSubRenderStateFactories() const; - - /** - Returns a sub render state factory by index - @note index must be lower than the value returned by getNumSubRenderStateFactories() - */ - SubRenderStateFactory* getSubRenderStateFactory(size_t index); - - /** - Returns a sub render state factory by name - */ - SubRenderStateFactory* getSubRenderStateFactory(const String& type); - - /** - Remove sub render state factory. - @param factory The factory to remove. - */ - void removeSubRenderStateFactory(SubRenderStateFactory* factory); - - /** - Create an instance of sub render state from a given type. - @param type The type of sub render state to create. - */ - SubRenderState* createSubRenderState(const String& type); - - - /** - Destroy an instance of sub render state. - @param subRenderState The instance to destroy. - */ - void destroySubRenderState(SubRenderState* subRenderState); + /** + Add sub render state factory. Plugins or 3d party applications may implement sub classes of + SubRenderState interface. Add the matching factory will allow the application to create instances + of these sub classes. + @param factory The factory to add. + */ + void addSubRenderStateFactory(SubRenderStateFactory* factory); + + /** + Returns the number of existing factories + */ + size_t getNumSubRenderStateFactories() const; + + /** + Returns a sub render state factory by index + @note index must be lower than the value returned by getNumSubRenderStateFactories() + */ + SubRenderStateFactory* getSubRenderStateFactory(size_t index); + /** + Returns a sub render state factory by name + */ + SubRenderStateFactory* getSubRenderStateFactory(const String& type); /** - Checks if a shader based technique has been created for a given technique. - Return true if exist. False if not. - @param materialName The source material name. - @param srcTechniqueSchemeName The source technique scheme name. - @param dstTechniqueSchemeName The destination shader based technique scheme name. - */ - bool hasShaderBasedTechnique(const String& materialName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName) const; + Remove sub render state factory. + @param factory The factory to remove. + */ + void removeSubRenderStateFactory(SubRenderStateFactory* factory); + + /** + Create an instance of sub render state from a given type. + @param type The type of sub render state to create. + */ + SubRenderState* createSubRenderState(const String& type); + + + /** + Destroy an instance of sub render state. + @param subRenderState The instance to destroy. + */ + void destroySubRenderState(SubRenderState* subRenderState); + + + /** + Checks if a shader based technique has been created for a given technique. + Return true if exist. False if not. + @param materialName The source material name. + @param srcTechniqueSchemeName The source technique scheme name. + @param dstTechniqueSchemeName The destination shader based technique scheme name. + */ + bool hasShaderBasedTechnique(const String& materialName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName) const; /** Checks if a shader based technique has been created for a given technique. @@ -312,15 +312,15 @@ class _OgreRTSSExport ShaderGenerator : public Singleton, publi bool hasShaderBasedTechnique(const String& materialName, const String& groupName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName) const; /** - Create shader based technique from a given technique. - Return true upon success. Failure may occur if the source technique is not FFP pure, or different - source technique is mapped to the requested destination scheme. - @param materialName The source material name. - @param srcTechniqueSchemeName The source technique scheme name. - @param dstTechniqueSchemeName The destination shader based technique scheme name. - @param overProgrammable If true a shader will be created even if the material has shaders - */ - bool createShaderBasedTechnique(const String& materialName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName, bool overProgrammable = false); + Create shader based technique from a given technique. + Return true upon success. Failure may occur if the source technique is not FFP pure, or different + source technique is mapped to the requested destination scheme. + @param materialName The source material name. + @param srcTechniqueSchemeName The source technique scheme name. + @param dstTechniqueSchemeName The destination shader based technique scheme name. + @param overProgrammable If true a shader will be created even if the material has shaders + */ + bool createShaderBasedTechnique(const String& materialName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName, bool overProgrammable = false); /** Create shader based technique from a given technique. @@ -336,14 +336,14 @@ class _OgreRTSSExport ShaderGenerator : public Singleton, publi /** - Remove shader based technique from a given technique. - Return true upon success. Failure may occur if the given source technique was not previously - registered successfully using the createShaderBasedTechnique method. - @param materialName The source material name. - @param srcTechniqueSchemeName The source technique scheme name. - @param dstTechniqueSchemeName The destination shader based technique scheme name. - */ - bool removeShaderBasedTechnique(const String& materialName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName); + Remove shader based technique from a given technique. + Return true upon success. Failure may occur if the given source technique was not previously + registered successfully using the createShaderBasedTechnique method. + @param materialName The source material name. + @param srcTechniqueSchemeName The source technique scheme name. + @param dstTechniqueSchemeName The destination shader based technique scheme name. + */ + bool removeShaderBasedTechnique(const String& materialName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName); /** Remove shader based technique from a given technique. @@ -357,683 +357,683 @@ class _OgreRTSSExport ShaderGenerator : public Singleton, publi bool removeShaderBasedTechnique(const String& materialName, const String& groupName, const String& srcTechniqueSchemeName, const String& dstTechniqueSchemeName); - /** - Remove all shader based techniques of the given material. - Return true upon success. - @param materialName The source material name. - @param groupName The source group name. - */ - bool removeAllShaderBasedTechniques(const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); - - /** - Clone all shader based techniques from one material to another. - This function can be used in conjunction with the Material::clone() function to copy - both material properties and RTSS state from one material to another. - @param srcMaterialName The source material name. - @param srcGroupName The source group name. - @param dstMaterialName The destination material name. - @param dstGroupName The destination group name. - @return True if successful - */ - bool cloneShaderBasedTechniques(const String& srcMaterialName, - const String& srcGroupName, const String& dstMaterialName, const String& dstGroupName); - - /** - Remove all shader based techniques that created by this shader generator. - */ - void removeAllShaderBasedTechniques(); - - /** - Create a scheme. - @param schemeName The scheme name to create. - */ - void createScheme(const String& schemeName); - - /** - Invalidate a given scheme. This action will lead to shader regeneration of all techniques belongs to the - given scheme name. - @param schemeName The scheme to invalidate. - */ - void invalidateScheme(const String& schemeName); - - /** - Validate a given scheme. This action will generate shader programs for all techniques of the - given scheme name. - @param schemeName The scheme to validate. - */ - bool validateScheme(const String& schemeName); - - /** - Invalidate specific material scheme. This action will lead to shader regeneration of the technique belongs to the - given scheme name. - @param schemeName The scheme to invalidate. - @param materialName The material to invalidate. - @param groupName The source group name. - */ - void invalidateMaterial(const String& schemeName, const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); - - /** - Validate specific material scheme. This action will generate shader programs for the technique of the - given scheme name. - @param schemeName The scheme to validate. - @param materialName The material to validate. - @param groupName The source group name. - */ - bool validateMaterial(const String& schemeName, const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); - - - /** - Return custom material Serializer of the shader generator. - This is useful when you'd like to export certain material that contains shader generator effects. - I.E - when writing an exporter you may want mark your material as shader generated material - so in the next time you will load it by your application it will automatically generate shaders with custom - attributes you wanted. To do it you'll have to do the following steps: - 1. Create shader based technique for you material via the createShaderBasedTechnique() method. - 2. Create MaterialSerializer instance. - 3. Add the return instance of serializer listener to the MaterialSerializer. - 4. Call one of the export methods of MaterialSerializer. - */ - SGMaterialSerializerListener* getMaterialSerializerListener(); - - - /** Return the current number of generated vertex shaders. */ - size_t getVertexShaderCount() const; - - - /** Return the current number of generated fragment shaders. */ - size_t getFragmentShaderCount() const; - - - - /** Set the vertex shader outputs compaction policy. - @see VSOutputCompactPolicy. - @param policy The policy to set. - */ - void setVertexShaderOutputsCompactPolicy(VSOutputCompactPolicy policy) { mVSOutputCompactPolicy = policy; } - - /** Get the vertex shader outputs compaction policy. - @see VSOutputCompactPolicy. - */ - VSOutputCompactPolicy getVertexShaderOutputsCompactPolicy() const { return mVSOutputCompactPolicy; } - - - /** Sets whether shaders are created for passes with shaders. - Note that this only refers to when the system parses the materials itself. - Not for when calling the createShaderBasedTechnique() function directly - @param value The value to set this attribute pass. - */ - void setCreateShaderOverProgrammablePass(bool value) { mCreateShaderOverProgrammablePass = value; } - - /** Returns whether shaders are created for passes with shaders. - @see setCreateShaderOverProgrammablePass(). - */ - bool getCreateShaderOverProgrammablePass() const { return mCreateShaderOverProgrammablePass; } - - - /** Returns the amount of schemes used in the for RT shader generation - */ - size_t getRTShaderSchemeCount() const; - - /** Returns the scheme name used in the for RT shader generation by index - */ - const String& getRTShaderScheme(size_t index) const; - - /// Default material scheme of the shader generator. - static String DEFAULT_SCHEME_NAME; + /** + Remove all shader based techniques of the given material. + Return true upon success. + @param materialName The source material name. + @param groupName The source group name. + */ + bool removeAllShaderBasedTechniques(const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + + /** + Clone all shader based techniques from one material to another. + This function can be used in conjunction with the Material::clone() function to copy + both material properties and RTSS state from one material to another. + @param srcMaterialName The source material name. + @param srcGroupName The source group name. + @param dstMaterialName The destination material name. + @param dstGroupName The destination group name. + @return True if successful + */ + bool cloneShaderBasedTechniques(const String& srcMaterialName, + const String& srcGroupName, const String& dstMaterialName, const String& dstGroupName); + + /** + Remove all shader based techniques that created by this shader generator. + */ + void removeAllShaderBasedTechniques(); + + /** + Create a scheme. + @param schemeName The scheme name to create. + */ + void createScheme(const String& schemeName); + + /** + Invalidate a given scheme. This action will lead to shader regeneration of all techniques belongs to the + given scheme name. + @param schemeName The scheme to invalidate. + */ + void invalidateScheme(const String& schemeName); + + /** + Validate a given scheme. This action will generate shader programs for all techniques of the + given scheme name. + @param schemeName The scheme to validate. + */ + bool validateScheme(const String& schemeName); + + /** + Invalidate specific material scheme. This action will lead to shader regeneration of the technique belongs to the + given scheme name. + @param schemeName The scheme to invalidate. + @param materialName The material to invalidate. + @param groupName The source group name. + */ + void invalidateMaterial(const String& schemeName, const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + + /** + Validate specific material scheme. This action will generate shader programs for the technique of the + given scheme name. + @param schemeName The scheme to validate. + @param materialName The material to validate. + @param groupName The source group name. + */ + bool validateMaterial(const String& schemeName, const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + + + /** + Return custom material Serializer of the shader generator. + This is useful when you'd like to export certain material that contains shader generator effects. + I.E - when writing an exporter you may want mark your material as shader generated material + so in the next time you will load it by your application it will automatically generate shaders with custom + attributes you wanted. To do it you'll have to do the following steps: + 1. Create shader based technique for you material via the createShaderBasedTechnique() method. + 2. Create MaterialSerializer instance. + 3. Add the return instance of serializer listener to the MaterialSerializer. + 4. Call one of the export methods of MaterialSerializer. + */ + SGMaterialSerializerListener* getMaterialSerializerListener(); + + + /** Return the current number of generated vertex shaders. */ + size_t getVertexShaderCount() const; + + + /** Return the current number of generated fragment shaders. */ + size_t getFragmentShaderCount() const; + + + + /** Set the vertex shader outputs compaction policy. + @see VSOutputCompactPolicy. + @param policy The policy to set. + */ + void setVertexShaderOutputsCompactPolicy(VSOutputCompactPolicy policy) { mVSOutputCompactPolicy = policy; } + + /** Get the vertex shader outputs compaction policy. + @see VSOutputCompactPolicy. + */ + VSOutputCompactPolicy getVertexShaderOutputsCompactPolicy() const { return mVSOutputCompactPolicy; } + + + /** Sets whether shaders are created for passes with shaders. + Note that this only refers to when the system parses the materials itself. + Not for when calling the createShaderBasedTechnique() function directly + @param value The value to set this attribute pass. + */ + void setCreateShaderOverProgrammablePass(bool value) { mCreateShaderOverProgrammablePass = value; } + + /** Returns whether shaders are created for passes with shaders. + @see setCreateShaderOverProgrammablePass(). + */ + bool getCreateShaderOverProgrammablePass() const { return mCreateShaderOverProgrammablePass; } + + + /** Returns the amount of schemes used in the for RT shader generation + */ + size_t getRTShaderSchemeCount() const; + + /** Returns the scheme name used in the for RT shader generation by index + */ + const String& getRTShaderScheme(size_t index) const; + + /// Default material scheme of the shader generator. + static String DEFAULT_SCHEME_NAME; // Protected types. protected: - class SGPass; - class SGTechnique; - class SGMaterial; - class SGScheme; - - typedef std::pair MatGroupPair; - struct MatGroupPair_less - { - // ensure we arrange the list first by material name then by group name - bool operator()(const MatGroupPair& p1, const MatGroupPair& p2) const - { - int cmpVal = strcmp(p1.first.c_str(),p2.first.c_str()); - return (cmpVal < 0) || ((cmpVal == 0) && (strcmp(p1.second.c_str(),p2.second.c_str()) < 0)); - } - }; - - typedef vector::type SGPassList; - typedef SGPassList::iterator SGPassIterator; - typedef SGPassList::const_iterator SGPassConstIterator; - - typedef vector::type SGTechniqueList; - typedef SGTechniqueList::iterator SGTechniqueIterator; - typedef SGTechniqueList::const_iterator SGTechniqueConstIterator; - - typedef map::type SGTechniqueMap; - typedef SGTechniqueMap::iterator SGTechniqueMapIterator; - - typedef map::type SGMaterialMap; - typedef SGMaterialMap::iterator SGMaterialIterator; - typedef SGMaterialMap::const_iterator SGMaterialConstIterator; - - typedef map::type SGSchemeMap; - typedef SGSchemeMap::iterator SGSchemeIterator; - typedef SGSchemeMap::const_iterator SGSchemeConstIterator; - - typedef map::type SGScriptTranslatorMap; - typedef SGScriptTranslatorMap::iterator SGScriptTranslatorIterator; - typedef SGScriptTranslatorMap::const_iterator SGScriptTranslatorConstIterator; - - - - /** Shader generator pass wrapper class. */ - class _OgreRTSSExport SGPass : public RTShaderSystemAlloc - { - public: - SGPass(SGTechnique* parent, Pass* srcPass, Pass* dstPass); - ~SGPass(); - - /** Build the render state. */ - void buildTargetRenderState(); - - /** Acquire the CPU/GPU programs for this pass. */ - void acquirePrograms(); - - /** Release the CPU/GPU programs of this pass. */ - void releasePrograms(); - - - /** Called when a single object is about to be rendered. */ - void notifyRenderSingleObject(Renderable* rend, const AutoParamDataSource* source, const LightList* pLightList, bool suppressRenderStateChanges); - - /** Get source pass. */ - Pass* getSrcPass() { return mSrcPass; } - - /** Get destination pass. */ - Pass* getDstPass() { return mDstPass; } - - /** Get custom FPP sub state of this pass. */ - SubRenderState* getCustomFFPSubState(int subStateOrder); - - /** Get custom render state of this pass. */ - RenderState* getCustomRenderState() { return mCustomRenderState; } - - /** Set the custom render state of this pass. */ - void setCustomRenderState(RenderState* customRenderState) { mCustomRenderState = customRenderState; } - - /// Key name for associating with a Pass instance. - static String UserKey; - - protected: - SubRenderState* getCustomFFPSubState(int subStateOrder, const RenderState* renderState); - - protected: - // Parent technique. - SGTechnique* mParent; - // Source pass. - Pass* mSrcPass; - // Destination pass. - Pass* mDstPass; - // Custom render state. - RenderState* mCustomRenderState; - // The compiled render state. - TargetRenderState* mTargetRenderState; - }; - - - /** Shader generator technique wrapper class. */ - class _OgreRTSSExport SGTechnique : public RTShaderSystemAlloc - { - public: - SGTechnique(SGMaterial* parent, Technique* srcTechnique, const String& dstTechniqueSchemeName); - ~SGTechnique(); - - /** Get the parent SGMaterial */ - const SGMaterial* getParent() const { return mParent; } - - /** Get the source technique. */ - Technique* getSourceTechnique() { return mSrcTechnique; } - - /** Get the destination technique. */ - Technique* getDestinationTechnique() { return mDstTechnique; } - - /** Get the destination technique scheme name. */ - const String& getDestinationTechniqueSchemeName() const { return mDstTechniqueSchemeName; } - - /** Build the render state. */ - void buildTargetRenderState(); - - /** Acquire the CPU/GPU programs for this technique. */ - void acquirePrograms(); - - /** Release the CPU/GPU programs of this technique. */ - void releasePrograms(); - - /** Tells the technique that it needs to generate shader code. */ - void setBuildDestinationTechnique(bool buildTechnique) { mBuildDstTechnique = buildTechnique; } - - /** Tells if the destination technique should be build. */ - bool getBuildDestinationTechnique() const { return mBuildDstTechnique; } - - /** Get render state of specific pass. - @param passIndex The pass index. - */ - RenderState* getRenderState(unsigned short passIndex); - /** Tells if a custom render state exists for the given pass. */ - bool hasRenderState(unsigned short passIndex); - - // Key name for associating with a Technique instance. - static String UserKey; - - protected: - - /** Create the passes entries. */ - void createSGPasses(); - - /** Destroy the passes entries. */ - void destroySGPasses(); - - protected: - // Parent material. - SGMaterial* mParent; - // Source technique. - Technique* mSrcTechnique; - // Destination technique. - Technique* mDstTechnique; - // All passes entries. - SGPassList mPassEntries; - // The custom render states of all passes. - RenderStateList mCustomRenderStates; - // Flag that tells if destination technique should be build. - bool mBuildDstTechnique; - // Scheme name of destination technique. - String mDstTechniqueSchemeName; + class SGPass; + class SGTechnique; + class SGMaterial; + class SGScheme; + + typedef std::pair MatGroupPair; + struct MatGroupPair_less + { + // ensure we arrange the list first by material name then by group name + bool operator()(const MatGroupPair& p1, const MatGroupPair& p2) const + { + int cmpVal = strcmp(p1.first.c_str(),p2.first.c_str()); + return (cmpVal < 0) || ((cmpVal == 0) && (strcmp(p1.second.c_str(),p2.second.c_str()) < 0)); + } }; - - /** Shader generator material wrapper class. */ - class _OgreRTSSExport SGMaterial : public RTShaderSystemAlloc - { - - public: - /** Class constructor. */ - SGMaterial(const String& materialName, const String& groupName) : mName(materialName), mGroup(groupName) - { - - } - - /** Get the material name. */ - const String& getMaterialName() const { return mName; } - - /** Get the group name. */ - const String& getGroupName() const { return mGroup; } - - /** Get the const techniques list of this material. */ - const SGTechniqueList& getTechniqueList() const { return mTechniqueEntries; } - - /** Get the techniques list of this material. */ - SGTechniqueList& getTechniqueList() { return mTechniqueEntries; } - - protected: - // The material name. - String mName; - // The group name. - String mGroup; - // All passes entries. - SGTechniqueList mTechniqueEntries; - }; - - - /** Shader generator scheme class. */ - class _OgreRTSSExport SGScheme : public RTShaderSystemAlloc - { - public: - SGScheme(const String& schemeName); - ~SGScheme(); - - - /** Return true if this scheme dose not contains any techniques. - */ - bool empty() const { return mTechniqueEntries.empty(); } - - /** Invalidate the whole scheme. - @see ShaderGenerator::invalidateScheme. - */ - void invalidate(); - - /** Validate the whole scheme. - @see ShaderGenerator::validateScheme. - */ - void validate(); - - /** Invalidate specific material. - @see ShaderGenerator::invalidateMaterial. - */ - void invalidate(const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); - - /** Validate specific material. - @see ShaderGenerator::validateMaterial. - */ - bool validate(const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); - - /** Add a technique to current techniques list. */ - void addTechniqueEntry(SGTechnique* techEntry); - - /** Remove a technique from the current techniques list. */ - void removeTechniqueEntry(SGTechnique* techEntry); - - - /** Get global render state of this scheme. - @see ShaderGenerator::getRenderState. - */ - RenderState* getRenderState(); - - /** Get specific pass render state. - @see ShaderGenerator::getRenderState. - */ - RenderState* getRenderState(const String& materialName, const String& groupName, unsigned short passIndex); - - protected: - /** Synchronize the current light settings of this scheme with the current settings of the scene. */ - void synchronizeWithLightSettings(); - - /** Synchronize the fog settings of this scheme with the current settings of the scene. */ - void synchronizeWithFogSettings(); - - - protected: - // Scheme name. - String mName; - // Technique entries. - SGTechniqueList mTechniqueEntries; - // Tells if this scheme is out of date. - bool mOutOfDate; - // The global render state of this scheme. - RenderState* mRenderState; - // Current fog mode. - FogMode mFogMode; - }; + typedef vector::type SGPassList; + typedef SGPassList::iterator SGPassIterator; + typedef SGPassList::const_iterator SGPassConstIterator; + + typedef vector::type SGTechniqueList; + typedef SGTechniqueList::iterator SGTechniqueIterator; + typedef SGTechniqueList::const_iterator SGTechniqueConstIterator; + + typedef map::type SGTechniqueMap; + typedef SGTechniqueMap::iterator SGTechniqueMapIterator; + + typedef map::type SGMaterialMap; + typedef SGMaterialMap::iterator SGMaterialIterator; + typedef SGMaterialMap::const_iterator SGMaterialConstIterator; + + typedef map::type SGSchemeMap; + typedef SGSchemeMap::iterator SGSchemeIterator; + typedef SGSchemeMap::const_iterator SGSchemeConstIterator; + + typedef map::type SGScriptTranslatorMap; + typedef SGScriptTranslatorMap::iterator SGScriptTranslatorIterator; + typedef SGScriptTranslatorMap::const_iterator SGScriptTranslatorConstIterator; + + + + /** Shader generator pass wrapper class. */ + class _OgreRTSSExport SGPass : public RTShaderSystemAlloc + { + public: + SGPass(SGTechnique* parent, Pass* srcPass, Pass* dstPass); + ~SGPass(); + + /** Build the render state. */ + void buildTargetRenderState(); + + /** Acquire the CPU/GPU programs for this pass. */ + void acquirePrograms(); + + /** Release the CPU/GPU programs of this pass. */ + void releasePrograms(); + + + /** Called when a single object is about to be rendered. */ + void notifyRenderSingleObject(Renderable* rend, const AutoParamDataSource* source, const LightList* pLightList, bool suppressRenderStateChanges); + + /** Get source pass. */ + Pass* getSrcPass() { return mSrcPass; } + + /** Get destination pass. */ + Pass* getDstPass() { return mDstPass; } + + /** Get custom FPP sub state of this pass. */ + SubRenderState* getCustomFFPSubState(int subStateOrder); + + /** Get custom render state of this pass. */ + RenderState* getCustomRenderState() { return mCustomRenderState; } + + /** Set the custom render state of this pass. */ + void setCustomRenderState(RenderState* customRenderState) { mCustomRenderState = customRenderState; } + + /// Key name for associating with a Pass instance. + static String UserKey; + + protected: + SubRenderState* getCustomFFPSubState(int subStateOrder, const RenderState* renderState); + + protected: + // Parent technique. + SGTechnique* mParent; + // Source pass. + Pass* mSrcPass; + // Destination pass. + Pass* mDstPass; + // Custom render state. + RenderState* mCustomRenderState; + // The compiled render state. + TargetRenderState* mTargetRenderState; + }; + + + /** Shader generator technique wrapper class. */ + class _OgreRTSSExport SGTechnique : public RTShaderSystemAlloc + { + public: + SGTechnique(SGMaterial* parent, Technique* srcTechnique, const String& dstTechniqueSchemeName); + ~SGTechnique(); + + /** Get the parent SGMaterial */ + const SGMaterial* getParent() const { return mParent; } + + /** Get the source technique. */ + Technique* getSourceTechnique() { return mSrcTechnique; } + + /** Get the destination technique. */ + Technique* getDestinationTechnique() { return mDstTechnique; } + + /** Get the destination technique scheme name. */ + const String& getDestinationTechniqueSchemeName() const { return mDstTechniqueSchemeName; } + + /** Build the render state. */ + void buildTargetRenderState(); + + /** Acquire the CPU/GPU programs for this technique. */ + void acquirePrograms(); + + /** Release the CPU/GPU programs of this technique. */ + void releasePrograms(); + + /** Tells the technique that it needs to generate shader code. */ + void setBuildDestinationTechnique(bool buildTechnique) { mBuildDstTechnique = buildTechnique; } + + /** Tells if the destination technique should be build. */ + bool getBuildDestinationTechnique() const { return mBuildDstTechnique; } + + /** Get render state of specific pass. + @param passIndex The pass index. + */ + RenderState* getRenderState(unsigned short passIndex); + /** Tells if a custom render state exists for the given pass. */ + bool hasRenderState(unsigned short passIndex); + + // Key name for associating with a Technique instance. + static String UserKey; + + protected: + + /** Create the passes entries. */ + void createSGPasses(); + + /** Destroy the passes entries. */ + void destroySGPasses(); + + protected: + // Parent material. + SGMaterial* mParent; + // Source technique. + Technique* mSrcTechnique; + // Destination technique. + Technique* mDstTechnique; + // All passes entries. + SGPassList mPassEntries; + // The custom render states of all passes. + RenderStateList mCustomRenderStates; + // Flag that tells if destination technique should be build. + bool mBuildDstTechnique; + // Scheme name of destination technique. + String mDstTechniqueSchemeName; + }; + + + /** Shader generator material wrapper class. */ + class _OgreRTSSExport SGMaterial : public RTShaderSystemAlloc + { + + public: + /** Class constructor. */ + SGMaterial(const String& materialName, const String& groupName) : mName(materialName), mGroup(groupName) + { + + } + + /** Get the material name. */ + const String& getMaterialName() const { return mName; } + + /** Get the group name. */ + const String& getGroupName() const { return mGroup; } + + /** Get the const techniques list of this material. */ + const SGTechniqueList& getTechniqueList() const { return mTechniqueEntries; } + + /** Get the techniques list of this material. */ + SGTechniqueList& getTechniqueList() { return mTechniqueEntries; } + + protected: + // The material name. + String mName; + // The group name. + String mGroup; + // All passes entries. + SGTechniqueList mTechniqueEntries; + }; + + + /** Shader generator scheme class. */ + class _OgreRTSSExport SGScheme : public RTShaderSystemAlloc + { + public: + SGScheme(const String& schemeName); + ~SGScheme(); + + + /** Return true if this scheme dose not contains any techniques. + */ + bool empty() const { return mTechniqueEntries.empty(); } + + /** Invalidate the whole scheme. + @see ShaderGenerator::invalidateScheme. + */ + void invalidate(); + + /** Validate the whole scheme. + @see ShaderGenerator::validateScheme. + */ + void validate(); + + /** Invalidate specific material. + @see ShaderGenerator::invalidateMaterial. + */ + void invalidate(const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + + /** Validate specific material. + @see ShaderGenerator::validateMaterial. + */ + bool validate(const String& materialName, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + + /** Add a technique to current techniques list. */ + void addTechniqueEntry(SGTechnique* techEntry); + + /** Remove a technique from the current techniques list. */ + void removeTechniqueEntry(SGTechnique* techEntry); + + + /** Get global render state of this scheme. + @see ShaderGenerator::getRenderState. + */ + RenderState* getRenderState(); + + /** Get specific pass render state. + @see ShaderGenerator::getRenderState. + */ + RenderState* getRenderState(const String& materialName, const String& groupName, unsigned short passIndex); + + protected: + /** Synchronize the current light settings of this scheme with the current settings of the scene. */ + void synchronizeWithLightSettings(); + + /** Synchronize the fog settings of this scheme with the current settings of the scene. */ + void synchronizeWithFogSettings(); + + + protected: + // Scheme name. + String mName; + // Technique entries. + SGTechniqueList mTechniqueEntries; + // Tells if this scheme is out of date. + bool mOutOfDate; + // The global render state of this scheme. + RenderState* mRenderState; + // Current fog mode. + FogMode mFogMode; + }; // Protected types. protected: - - /** Shader generator RenderObjectListener sub class. */ - class _OgreRTSSExport SGRenderObjectListener : public RenderObjectListener, public RTShaderSystemAlloc - { - public: - SGRenderObjectListener(ShaderGenerator* owner) - { - mOwner = owner; - } - - /** - Listener overridden function notify the shader generator when rendering single object. - */ - virtual void notifyRenderSingleObject(Renderable* rend, const Pass* pass, - const AutoParamDataSource* source, - const LightList* pLightList, bool suppressRenderStateChanges) - { - mOwner->notifyRenderSingleObject(rend, pass, source, pLightList, suppressRenderStateChanges); - } - - protected: - ShaderGenerator* mOwner; - }; - - /** Shader generator scene manager sub class. */ - class _OgreRTSSExport SGSceneManagerListener : public SceneManager::Listener, public RTShaderSystemAlloc - { - public: - SGSceneManagerListener(ShaderGenerator* owner) - { - mOwner = owner; - } - - /** - Listener overridden function notify the shader generator when finding visible objects process started. - */ - virtual void preFindVisibleObjects(SceneManager* source, - SceneManager::IlluminationRenderStage irs, Viewport* v) - { - mOwner->preFindVisibleObjects(source, irs, v); - } - - virtual void postFindVisibleObjects(SceneManager* source, - SceneManager::IlluminationRenderStage irs, Viewport* v) - { - - } - - virtual void shadowTexturesUpdated(size_t numberOfShadowTextures) - { - - } - - virtual void shadowTextureCasterPreViewProj(Light* light, - Camera* camera, size_t iteration) - { - - } - - virtual void shadowTextureReceiverPreViewProj(Light* light, - Frustum* frustum) - { - - } - - protected: - // The shader generator instance. - ShaderGenerator* mOwner; - }; - - /** Shader generator ScriptTranslatorManager sub class. */ - class _OgreRTSSExport SGScriptTranslatorManager : public ScriptTranslatorManager - { - public: - SGScriptTranslatorManager(ShaderGenerator* owner) - { - mOwner = owner; - } - - /// Returns the number of translators being managed - virtual size_t getNumTranslators() const - { - return mOwner->getNumTranslators(); - } - - /// Returns a manager for the given object abstract node, or null if it is not supported - virtual ScriptTranslator *getTranslator(const AbstractNodePtr& node) - { - return mOwner->getTranslator(node); - } - - protected: - // The shader generator instance. - ShaderGenerator* mOwner; - }; - - //----------------------------------------------------------------------------- - typedef map::type SubRenderStateFactoryMap; - typedef SubRenderStateFactoryMap::iterator SubRenderStateFactoryIterator; - typedef SubRenderStateFactoryMap::const_iterator SubRenderStateFactoryConstIterator; - - //----------------------------------------------------------------------------- - typedef map::type SceneManagerMap; - typedef SceneManagerMap::iterator SceneManagerIterator; - typedef SceneManagerMap::const_iterator SceneManagerConstIterator; + + /** Shader generator RenderObjectListener sub class. */ + class _OgreRTSSExport SGRenderObjectListener : public RenderObjectListener, public RTShaderSystemAlloc + { + public: + SGRenderObjectListener(ShaderGenerator* owner) + { + mOwner = owner; + } + + /** + Listener overridden function notify the shader generator when rendering single object. + */ + virtual void notifyRenderSingleObject(Renderable* rend, const Pass* pass, + const AutoParamDataSource* source, + const LightList* pLightList, bool suppressRenderStateChanges) + { + mOwner->notifyRenderSingleObject(rend, pass, source, pLightList, suppressRenderStateChanges); + } + + protected: + ShaderGenerator* mOwner; + }; + + /** Shader generator scene manager sub class. */ + class _OgreRTSSExport SGSceneManagerListener : public SceneManager::Listener, public RTShaderSystemAlloc + { + public: + SGSceneManagerListener(ShaderGenerator* owner) + { + mOwner = owner; + } + + /** + Listener overridden function notify the shader generator when finding visible objects process started. + */ + virtual void preFindVisibleObjects(SceneManager* source, + SceneManager::IlluminationRenderStage irs, Viewport* v) + { + mOwner->preFindVisibleObjects(source, irs, v); + } + + virtual void postFindVisibleObjects(SceneManager* source, + SceneManager::IlluminationRenderStage irs, Viewport* v) + { + + } + + virtual void shadowTexturesUpdated(size_t numberOfShadowTextures) + { + + } + + virtual void shadowTextureCasterPreViewProj(Light* light, + Camera* camera, size_t iteration) + { + + } + + virtual void shadowTextureReceiverPreViewProj(Light* light, + Frustum* frustum) + { + + } + + protected: + // The shader generator instance. + ShaderGenerator* mOwner; + }; + + /** Shader generator ScriptTranslatorManager sub class. */ + class _OgreRTSSExport SGScriptTranslatorManager : public ScriptTranslatorManager + { + public: + SGScriptTranslatorManager(ShaderGenerator* owner) + { + mOwner = owner; + } + + /// Returns the number of translators being managed + virtual size_t getNumTranslators() const + { + return mOwner->getNumTranslators(); + } + + /// Returns a manager for the given object abstract node, or null if it is not supported + virtual ScriptTranslator *getTranslator(const AbstractNodePtr& node) + { + return mOwner->getTranslator(node); + } + + protected: + // The shader generator instance. + ShaderGenerator* mOwner; + }; + + //----------------------------------------------------------------------------- + typedef map::type SubRenderStateFactoryMap; + typedef SubRenderStateFactoryMap::iterator SubRenderStateFactoryIterator; + typedef SubRenderStateFactoryMap::const_iterator SubRenderStateFactoryConstIterator; + + //----------------------------------------------------------------------------- + typedef map::type SceneManagerMap; + typedef SceneManagerMap::iterator SceneManagerIterator; + typedef SceneManagerMap::const_iterator SceneManagerConstIterator; protected: - /** Class default constructor */ - ShaderGenerator(); + /** Class default constructor */ + ShaderGenerator(); - /** Class destructor */ - ~ShaderGenerator(); + /** Class destructor */ + ~ShaderGenerator(); - /** Initialize the shader generator instance. */ - bool _initialize(); - - /** Destory the shader generator instance. */ - void _destroy(); + /** Initialize the shader generator instance. */ + bool _initialize(); + + /** Destory the shader generator instance. */ + void _destroy(); - /** Find source technique to generate shader based technique based on it. */ - Technique* findSourceTechnique(const String& materialName, const String& groupName, const String& srcTechniqueSchemeName, bool allowProgrammable); + /** Find source technique to generate shader based technique based on it. */ + Technique* findSourceTechnique(const String& materialName, const String& groupName, const String& srcTechniqueSchemeName, bool allowProgrammable); - /** Checks if a given technique has passes with shaders. */ - bool isProgrammable(Technique* tech) const; + /** Checks if a given technique has passes with shaders. */ + bool isProgrammable(Technique* tech) const; - /** Called from the sub class of the RenderObjectLister when single object is rendered. */ - void notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, const LightList* pLightList, bool suppressRenderStateChanges); - - /** Called from the sub class of the SceneManager::Listener when finding visible object process starts. */ - void preFindVisibleObjects(SceneManager* source, SceneManager::IlluminationRenderStage irs, Viewport* v); - - /** Create sub render state core extensions factories */ - void createSubRenderStateExFactories(); - - /** Destroy sub render state core extensions factories */ - void destroySubRenderStateExFactories(); - - /** Create an instance of the SubRenderState based on script properties using the - current sub render state factories. - @see SubRenderStateFactory::createInstance - @param compiler The compiler instance. - @param prop The abstract property node. - @param pass The pass that is the parent context of this node. - @param translator The translator for the specific SubRenderState - */ - SubRenderState* createSubRenderState(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - - /** Create an instance of the SubRenderState based on script properties using the - current sub render state factories. - @see SubRenderStateFactory::createInstance - @param compiler The compiler instance. - @param prop The abstract property node. - @param texState The texture unit state that is the parent context of this node. - @param translator The translator for the specific SubRenderState - */ - SubRenderState* createSubRenderState(ScriptCompiler* compiler, PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator); - - /** - Add custom script translator. - Return true upon success. - @param key The key name of the given translator. - @param translator The translator to associate with the given key. - */ - bool addCustomScriptTranslator(const String& key, ScriptTranslator* translator); - - /** - Remove custom script translator. - Return true upon success. - @param key The key name of the translator to remove. - */ - bool removeCustomScriptTranslator(const String& key); - - /** Return number of script translators. */ - size_t getNumTranslators() const; - - /** Return a matching script translator. */ - ScriptTranslator* getTranslator(const AbstractNodePtr& node); - - - /** This method called by instance of SGMaterialSerializerListener and - serialize a given pass entry attributes. - @param ser The material serializer. - @param passEntry The SGPass instance. - */ - void serializePassAttributes(MaterialSerializer* ser, SGPass* passEntry); - - /** This method called by instance of SGMaterialSerializerListener and - serialize a given textureUnitState entry attributes. - @param ser The material serializer. - @param passEntry The SGPass instance. - @param srcTextureUnit The TextureUnitState being serialized. - */ - void serializeTextureUnitStateAttributes(MaterialSerializer* ser, SGPass* passEntry, const TextureUnitState* srcTextureUnit); - - /** Finds an entry iterator in the mMaterialEntriesMap map. - This function is able to find materials with group specified as - AUTODETECT_RESOURCE_GROUP_NAME - */ - SGMaterialIterator findMaterialEntryIt(const String& materialName, const String& groupName); - SGMaterialConstIterator findMaterialEntryIt(const String& materialName, const String& groupName) const; - - - typedef std::pair SchemeCreateOrRetrieveResult; - /** - Returns a requested scheme. If the scheme does not exist this function creates it. - @param schemeName The scheme name to retrieve. - */ - SchemeCreateOrRetrieveResult createOrRetrieveScheme(const String& schemeName); + /** Called from the sub class of the RenderObjectLister when single object is rendered. */ + void notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, const LightList* pLightList, bool suppressRenderStateChanges); + + /** Called from the sub class of the SceneManager::Listener when finding visible object process starts. */ + void preFindVisibleObjects(SceneManager* source, SceneManager::IlluminationRenderStage irs, Viewport* v); + + /** Create sub render state core extensions factories */ + void createSubRenderStateExFactories(); + + /** Destroy sub render state core extensions factories */ + void destroySubRenderStateExFactories(); + + /** Create an instance of the SubRenderState based on script properties using the + current sub render state factories. + @see SubRenderStateFactory::createInstance + @param compiler The compiler instance. + @param prop The abstract property node. + @param pass The pass that is the parent context of this node. + @param translator The translator for the specific SubRenderState + */ + SubRenderState* createSubRenderState(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + + /** Create an instance of the SubRenderState based on script properties using the + current sub render state factories. + @see SubRenderStateFactory::createInstance + @param compiler The compiler instance. + @param prop The abstract property node. + @param texState The texture unit state that is the parent context of this node. + @param translator The translator for the specific SubRenderState + */ + SubRenderState* createSubRenderState(ScriptCompiler* compiler, PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator); + + /** + Add custom script translator. + Return true upon success. + @param key The key name of the given translator. + @param translator The translator to associate with the given key. + */ + bool addCustomScriptTranslator(const String& key, ScriptTranslator* translator); + + /** + Remove custom script translator. + Return true upon success. + @param key The key name of the translator to remove. + */ + bool removeCustomScriptTranslator(const String& key); + + /** Return number of script translators. */ + size_t getNumTranslators() const; + + /** Return a matching script translator. */ + ScriptTranslator* getTranslator(const AbstractNodePtr& node); + + + /** This method called by instance of SGMaterialSerializerListener and + serialize a given pass entry attributes. + @param ser The material serializer. + @param passEntry The SGPass instance. + */ + void serializePassAttributes(MaterialSerializer* ser, SGPass* passEntry); + + /** This method called by instance of SGMaterialSerializerListener and + serialize a given textureUnitState entry attributes. + @param ser The material serializer. + @param passEntry The SGPass instance. + @param srcTextureUnit The TextureUnitState being serialized. + */ + void serializeTextureUnitStateAttributes(MaterialSerializer* ser, SGPass* passEntry, const TextureUnitState* srcTextureUnit); + + /** Finds an entry iterator in the mMaterialEntriesMap map. + This function is able to find materials with group specified as + AUTODETECT_RESOURCE_GROUP_NAME + */ + SGMaterialIterator findMaterialEntryIt(const String& materialName, const String& groupName); + SGMaterialConstIterator findMaterialEntryIt(const String& materialName, const String& groupName) const; + + + typedef std::pair SchemeCreateOrRetrieveResult; + /** + Returns a requested scheme. If the scheme does not exist this function creates it. + @param schemeName The scheme name to retrieve. + */ + SchemeCreateOrRetrieveResult createOrRetrieveScheme(const String& schemeName); /** Used to check if finalizing */ bool getIsFinalizing() const; -protected: +protected: // Auto mutex. OGRE_AUTO_MUTEX; - // The active scene manager. - SceneManager* mActiveSceneMgr; - // A map of all scene managers this generator is bound to. - SceneManagerMap mSceneManagerMap; - // Render object listener. - SGRenderObjectListener* mRenderObjectListener; - // Scene manager listener. - SGSceneManagerListener* mSceneManagerListener; - // Script translator manager. - SGScriptTranslatorManager* mScriptTranslatorManager; - // Custom material Serializer listener - allows exporting material that contains shader generated techniques. - SGMaterialSerializerListener* mMaterialSerializerListener; - // A map of the registered custom script translators. - SGScriptTranslatorMap mScriptTranslatorsMap; - // The core translator of the RT Shader System. - SGScriptTranslator mCoreScriptTranslator; - // The target shader language (currently only cg supported). - String mShaderLanguage; - // The target shader language version. - float mShaderLanguageVersion; - // The target vertex shader profile. Will be used as argument for program compilation. - String mVertexShaderProfiles; - // List of target vertex shader profiles. - StringVector mVertexShaderProfilesList; - // The target fragment shader profile. Will be used as argument for program compilation. - String mFragmentShaderProfiles; - // List of target fragment shader profiles.. - StringVector mFragmentShaderProfilesList; - // Path for caching the generated shaders. - String mShaderCachePath; - // Shader program manager. - ProgramManager* mProgramManager; - // Shader program writer manager. - ProgramWriterManager* mProgramWriterManager; + // The active scene manager. + SceneManager* mActiveSceneMgr; + // A map of all scene managers this generator is bound to. + SceneManagerMap mSceneManagerMap; + // Render object listener. + SGRenderObjectListener* mRenderObjectListener; + // Scene manager listener. + SGSceneManagerListener* mSceneManagerListener; + // Script translator manager. + SGScriptTranslatorManager* mScriptTranslatorManager; + // Custom material Serializer listener - allows exporting material that contains shader generated techniques. + SGMaterialSerializerListener* mMaterialSerializerListener; + // A map of the registered custom script translators. + SGScriptTranslatorMap mScriptTranslatorsMap; + // The core translator of the RT Shader System. + SGScriptTranslator mCoreScriptTranslator; + // The target shader language (currently only cg supported). + String mShaderLanguage; + // The target shader language version. + float mShaderLanguageVersion; + // The target vertex shader profile. Will be used as argument for program compilation. + String mVertexShaderProfiles; + // List of target vertex shader profiles. + StringVector mVertexShaderProfilesList; + // The target fragment shader profile. Will be used as argument for program compilation. + String mFragmentShaderProfiles; + // List of target fragment shader profiles.. + StringVector mFragmentShaderProfilesList; + // Path for caching the generated shaders. + String mShaderCachePath; + // Shader program manager. + ProgramManager* mProgramManager; + // Shader program writer manager. + ProgramWriterManager* mProgramWriterManager; // File system layer manager. - FileSystemLayer* mFSLayer; - // Fixed Function Render state builder. - FFPRenderStateBuilder* mFFPRenderStateBuilder; - // Material entries map. - SGMaterialMap mMaterialEntriesMap; - // Scheme entries map. - SGSchemeMap mSchemeEntriesMap; - // All technique entries map. - SGTechniqueMap mTechniqueEntriesMap; - // Sub render state registered factories. - SubRenderStateFactoryMap mSubRenderStateFactories; - // Sub render state core extension factories. - SubRenderStateFactoryMap mSubRenderStateExFactories; - // True if active view port use a valid SGScheme. - bool mActiveViewportValid; - // Light count per light type. - int mLightCount[3]; - // Vertex shader outputs compact policy. - VSOutputCompactPolicy mVSOutputCompactPolicy; - // Tells whether shaders are created for passes with shaders - bool mCreateShaderOverProgrammablePass; + FileSystemLayer* mFSLayer; + // Fixed Function Render state builder. + FFPRenderStateBuilder* mFFPRenderStateBuilder; + // Material entries map. + SGMaterialMap mMaterialEntriesMap; + // Scheme entries map. + SGSchemeMap mSchemeEntriesMap; + // All technique entries map. + SGTechniqueMap mTechniqueEntriesMap; + // Sub render state registered factories. + SubRenderStateFactoryMap mSubRenderStateFactories; + // Sub render state core extension factories. + SubRenderStateFactoryMap mSubRenderStateExFactories; + // True if active view port use a valid SGScheme. + bool mActiveViewportValid; + // Light count per light type. + int mLightCount[3]; + // Vertex shader outputs compact policy. + VSOutputCompactPolicy mVSOutputCompactPolicy; + // Tells whether shaders are created for passes with shaders + bool mCreateShaderOverProgrammablePass; // A flag to indicate finalizing bool mIsFinalizing; private: - friend class SGPass; - friend class FFPRenderStateBuilder; - friend class SGScriptTranslatorManager; - friend class SGScriptTranslator; - friend class SGMaterialSerializerListener; - + friend class SGPass; + friend class FFPRenderStateBuilder; + friend class SGScriptTranslatorManager; + friend class SGScriptTranslator; + friend class SGMaterialSerializerListener; + }; /** @} */ diff --git a/Components/RTShaderSystem/include/OgreShaderHLSLProgramProcessor.h b/Components/RTShaderSystem/include/OgreShaderHLSLProgramProcessor.h index 2f6e1bc73db..cb693f0e64c 100644 --- a/Components/RTShaderSystem/include/OgreShaderHLSLProgramProcessor.h +++ b/Components/RTShaderSystem/include/OgreShaderHLSLProgramProcessor.h @@ -46,29 +46,29 @@ namespace RTShader { class _OgreRTSSExport HLSLProgramProcessor : public ProgramProcessor { - // Interface. -public: + // Interface. +public: - /** Class constructor. - */ - HLSLProgramProcessor(); + /** Class constructor. + */ + HLSLProgramProcessor(); - /** Class destructor */ - virtual ~HLSLProgramProcessor(); + /** Class destructor */ + virtual ~HLSLProgramProcessor(); - /** Return the target language of this processor. */ - virtual const String& getTargetLanguage() const { return TargetLanguage; } + /** Return the target language of this processor. */ + virtual const String& getTargetLanguage() const { return TargetLanguage; } - /** - @see ProgramProcessor::preCreateGpuPrograms - */ - virtual bool preCreateGpuPrograms(ProgramSet* programSet); - /** - @see ProgramProcessor::postCreateGpuPrograms - */ - virtual bool postCreateGpuPrograms(ProgramSet* programSet); + /** + @see ProgramProcessor::preCreateGpuPrograms + */ + virtual bool preCreateGpuPrograms(ProgramSet* programSet); + /** + @see ProgramProcessor::postCreateGpuPrograms + */ + virtual bool postCreateGpuPrograms(ProgramSet* programSet); - static String TargetLanguage; + static String TargetLanguage; }; diff --git a/Components/RTShaderSystem/include/OgreShaderHLSLProgramWriter.h b/Components/RTShaderSystem/include/OgreShaderHLSLProgramWriter.h index f18f17588fe..8b40f335a8b 100644 --- a/Components/RTShaderSystem/include/OgreShaderHLSLProgramWriter.h +++ b/Components/RTShaderSystem/include/OgreShaderHLSLProgramWriter.h @@ -33,7 +33,7 @@ THE SOFTWARE. #include "OgreShaderParameter.h" namespace Ogre { - namespace RTShader { + namespace RTShader { class Function; class FunctionAtom; @@ -52,65 +52,65 @@ namespace Ogre { class _OgreRTSSExport HLSLProgramWriter : public ProgramWriter { - // Interface. + // Interface. public: - /** Class constructor. - */ - HLSLProgramWriter(); + /** Class constructor. + */ + HLSLProgramWriter(); - /** Class destructor */ - virtual ~HLSLProgramWriter(); + /** Class destructor */ + virtual ~HLSLProgramWriter(); - /** - @see ProgramWriter::writeSourceCode. - */ - virtual void writeSourceCode(std::ostream& os, Program* program); + /** + @see ProgramWriter::writeSourceCode. + */ + virtual void writeSourceCode(std::ostream& os, Program* program); - /** - @see ProgramWriter::getTargetLanguage. - */ - virtual const String& getTargetLanguage() const { return TargetLanguage; } + /** + @see ProgramWriter::getTargetLanguage. + */ + virtual const String& getTargetLanguage() const { return TargetLanguage; } - static String TargetLanguage; + static String TargetLanguage; - // Protected methods. + // Protected methods. protected: - /** Initialize string maps. */ - void initializeStringMaps(); + /** Initialize string maps. */ + void initializeStringMaps(); - /** Write the program dependencies. */ - void writeProgramDependencies(std::ostream& os, Program* program); + /** Write the program dependencies. */ + void writeProgramDependencies(std::ostream& os, Program* program); - /** Write a uniform parameter. */ - void writeUniformParameter(std::ostream& os, UniformParameterPtr parameter); + /** Write a uniform parameter. */ + void writeUniformParameter(std::ostream& os, UniformParameterPtr parameter); - /** Write a function parameter. */ - void writeFunctionParameter(std::ostream& os, ParameterPtr parameter, const char* forcedSemantic); + /** Write a function parameter. */ + void writeFunctionParameter(std::ostream& os, ParameterPtr parameter, const char* forcedSemantic); - /** Write a local parameter. */ - void writeLocalParameter(std::ostream& os, ParameterPtr parameter); + /** Write a local parameter. */ + void writeLocalParameter(std::ostream& os, ParameterPtr parameter); - /** Write a function declaration. */ - void writeFunctionDeclaration(std::ostream& os, Function* function); + /** Write a function declaration. */ + void writeFunctionDeclaration(std::ostream& os, Function* function); - /** Write function atom instance. */ - void writeAtomInstance(std::ostream& os, FunctionAtom* atom); + /** Write function atom instance. */ + void writeAtomInstance(std::ostream& os, FunctionAtom* atom); protected: - typedef map::type GpuConstTypeToStringMap; - typedef map::type ParamSemanticToStringMap; + typedef map::type GpuConstTypeToStringMap; + typedef map::type ParamSemanticToStringMap; - // Attributes. + // Attributes. protected: - // Map between GPU constant type to string value. - GpuConstTypeToStringMap mGpuConstTypeMap; - // Map between GPU constant type v4 to string value. - //TODO : add abstraction per version - GpuConstTypeToStringMap mGpuConstTypeMapV4; - // Map between parameter semantic to string value. - ParamSemanticToStringMap mParamSemanticMap; + // Map between GPU constant type to string value. + GpuConstTypeToStringMap mGpuConstTypeMap; + // Map between GPU constant type v4 to string value. + //TODO : add abstraction per version + GpuConstTypeToStringMap mGpuConstTypeMapV4; + // Map between parameter semantic to string value. + ParamSemanticToStringMap mParamSemanticMap; }; /** HLSL program writer factory implementation. @@ -119,27 +119,27 @@ class _OgreRTSSExport HLSLProgramWriter : public ProgramWriter class _OgreRTSSExport ShaderProgramWriterHLSLFactory : public ProgramWriterFactory { public: - ShaderProgramWriterHLSLFactory() : mLanguage("hlsl") {} - virtual ~ShaderProgramWriterHLSLFactory() {} - - /** - @see ProgramWriterFactory::getTargetLanguage - */ - virtual const String& getTargetLanguage(void) const - { - return mLanguage; - } - - /** - @see ProgramWriterFactory::create - */ - virtual ProgramWriter* create(void) - { - return OGRE_NEW HLSLProgramWriter(); - } + ShaderProgramWriterHLSLFactory() : mLanguage("hlsl") {} + virtual ~ShaderProgramWriterHLSLFactory() {} + + /** + @see ProgramWriterFactory::getTargetLanguage + */ + virtual const String& getTargetLanguage(void) const + { + return mLanguage; + } + + /** + @see ProgramWriterFactory::create + */ + virtual ProgramWriter* create(void) + { + return OGRE_NEW HLSLProgramWriter(); + } private: - String mLanguage; + String mLanguage; }; diff --git a/Components/RTShaderSystem/include/OgreShaderMaterialSerializerListener.h b/Components/RTShaderSystem/include/OgreShaderMaterialSerializerListener.h index 1f60a3fc22f..38a00000037 100644 --- a/Components/RTShaderSystem/include/OgreShaderMaterialSerializerListener.h +++ b/Components/RTShaderSystem/include/OgreShaderMaterialSerializerListener.h @@ -50,59 +50,59 @@ class _OgreRTSSExport SGMaterialSerializerListener : public MaterialSerializer:: // Interface. public: - /** - @see MaterialSerializer::Listener::materialEventRaised - */ - virtual void materialEventRaised(MaterialSerializer* ser, - MaterialSerializer::SerializeEvent event, bool& skip, const Material* mat); - - /** - @see MaterialSerializer::Listener::techniqueEventRaised - */ - virtual void techniqueEventRaised(MaterialSerializer* ser, - MaterialSerializer::SerializeEvent event, bool& skip, const Technique* tech); - - /** - @see MaterialSerializer::Listener::passEventRaised - */ - virtual void passEventRaised(MaterialSerializer* ser, - MaterialSerializer::SerializeEvent event, bool& skip, const Pass* tech); - - /** - @see MaterialSerializer::Listener::textureUnitStateEventRaised - */ - virtual void textureUnitStateEventRaised(MaterialSerializer* ser, - MaterialSerializer::SerializeEvent event, bool& skip, const TextureUnitState* textureUnit); + /** + @see MaterialSerializer::Listener::materialEventRaised + */ + virtual void materialEventRaised(MaterialSerializer* ser, + MaterialSerializer::SerializeEvent event, bool& skip, const Material* mat); + + /** + @see MaterialSerializer::Listener::techniqueEventRaised + */ + virtual void techniqueEventRaised(MaterialSerializer* ser, + MaterialSerializer::SerializeEvent event, bool& skip, const Technique* tech); + + /** + @see MaterialSerializer::Listener::passEventRaised + */ + virtual void passEventRaised(MaterialSerializer* ser, + MaterialSerializer::SerializeEvent event, bool& skip, const Pass* tech); + + /** + @see MaterialSerializer::Listener::textureUnitStateEventRaised + */ + virtual void textureUnitStateEventRaised(MaterialSerializer* ser, + MaterialSerializer::SerializeEvent event, bool& skip, const TextureUnitState* textureUnit); // Types. protected: - typedef vector::type SGPassList; - typedef SGPassList::iterator SGPassListIterator; - typedef SGPassList::const_iterator SGPassListConstIterator; + typedef vector::type SGPassList; + typedef SGPassList::iterator SGPassListIterator; + typedef SGPassList::const_iterator SGPassListConstIterator; // Protected methods. protected: - /** Will be create and destroyed via ShaderGenerator interface. */ - SGMaterialSerializerListener(); - ~SGMaterialSerializerListener(); + /** Will be create and destroyed via ShaderGenerator interface. */ + SGMaterialSerializerListener(); + ~SGMaterialSerializerListener(); - /** Internal method that creates list of SGPass instances composing the given material. */ - void createSGPassList(Material* mat, SGPassList& passList); + /** Internal method that creates list of SGPass instances composing the given material. */ + void createSGPassList(Material* mat, SGPassList& passList); - /** Internal method that returns SGPass instance from a given source pass. */ - ShaderGenerator::SGPass* getShaderGeneratedPass (const Pass* srcPass); - + /** Internal method that returns SGPass instance from a given source pass. */ + ShaderGenerator::SGPass* getShaderGeneratedPass (const Pass* srcPass); + // Attributes. -protected: - // The current source material that is being written. - Material* mSourceMaterial; - // List of SGPass instances composing this material. - SGPassList mSGPassList; - - +protected: + // The current source material that is being written. + Material* mSourceMaterial; + // List of SGPass instances composing this material. + SGPassList mSGPassList; + + private: - friend class ShaderGenerator; + friend class ShaderGenerator; }; } diff --git a/Components/RTShaderSystem/include/OgreShaderParameter.h b/Components/RTShaderSystem/include/OgreShaderParameter.h index 176003c14b8..d03932c49c3 100644 --- a/Components/RTShaderSystem/include/OgreShaderParameter.h +++ b/Components/RTShaderSystem/include/OgreShaderParameter.h @@ -47,325 +47,325 @@ namespace RTShader { class _OgreRTSSExport Parameter : public RTShaderSystemAlloc { public: - // Shader parameter semantic. - enum Semantic - { - /// Unknown semantic - SPS_UNKNOWN = 0, - /// Position - SPS_POSITION = 1, - /// Blending weights - SPS_BLEND_WEIGHTS = 2, - /// Blending indices - SPS_BLEND_INDICES = 3, - /// Normal, 3 reals per vertex - SPS_NORMAL = 4, - /// General floating point color. - SPS_COLOR = 5, - /// Texture coordinates - SPS_TEXTURE_COORDINATES = 7, - /// Binormal (Y axis if normal is Z) - SPS_BINORMAL = 8, - /// Tangent (X axis if normal is Z) - SPS_TANGENT = 9 - }; - - // Shader parameter content. - enum Content - { - /// Unknown content - SPC_UNKNOWN, - - /// Position in object space - SPC_POSITION_OBJECT_SPACE, - - /// Position in world space - SPC_POSITION_WORLD_SPACE, - - /// Position in view space - SPC_POSITION_VIEW_SPACE, - - /// Position in projective space - SPC_POSITION_PROJECTIVE_SPACE, - - /// Position in light space index 0-7 - SPC_POSITION_LIGHT_SPACE0, - SPC_POSITION_LIGHT_SPACE1, - SPC_POSITION_LIGHT_SPACE2, - SPC_POSITION_LIGHT_SPACE3, - SPC_POSITION_LIGHT_SPACE4, - SPC_POSITION_LIGHT_SPACE5, - SPC_POSITION_LIGHT_SPACE6, - SPC_POSITION_LIGHT_SPACE7, - - /// Normal in object space - SPC_NORMAL_OBJECT_SPACE, - - /// Normal in world space - SPC_NORMAL_WORLD_SPACE, - - /// Normal in view space - SPC_NORMAL_VIEW_SPACE, - - /// Normal in tangent space - SPC_NORMAL_TANGENT_SPACE, - - /// View vector in object space - SPC_POSTOCAMERA_OBJECT_SPACE, - - /// View vector in world space - SPC_POSTOCAMERA_WORLD_SPACE, - - /// View vector in view space - SPC_POSTOCAMERA_VIEW_SPACE, - - /// View vector in tangent space - SPC_POSTOCAMERA_TANGENT_SPACE, - - /// Light vector in object space index 0-7 - SPC_POSTOLIGHT_OBJECT_SPACE0, - SPC_POSTOLIGHT_OBJECT_SPACE1, - SPC_POSTOLIGHT_OBJECT_SPACE2, - SPC_POSTOLIGHT_OBJECT_SPACE3, - SPC_POSTOLIGHT_OBJECT_SPACE4, - SPC_POSTOLIGHT_OBJECT_SPACE5, - SPC_POSTOLIGHT_OBJECT_SPACE6, - SPC_POSTOLIGHT_OBJECT_SPACE7, - - /// Light vector in world space index 0-7 - SPC_POSTOLIGHT_WORLD_SPACE0, - SPC_POSTOLIGHT_WORLD_SPACE1, - SPC_POSTOLIGHT_WORLD_SPACE2, - SPC_POSTOLIGHT_WORLD_SPACE3, - SPC_POSTOLIGHT_WORLD_SPACE4, - SPC_POSTOLIGHT_WORLD_SPACE5, - SPC_POSTOLIGHT_WORLD_SPACE6, - SPC_POSTOLIGHT_WORLD_SPACE7, - - /// Light vector in view space index 0-7 - SPC_POSTOLIGHT_VIEW_SPACE0, - SPC_POSTOLIGHT_VIEW_SPACE1, - SPC_POSTOLIGHT_VIEW_SPACE2, - SPC_POSTOLIGHT_VIEW_SPACE3, - SPC_POSTOLIGHT_VIEW_SPACE4, - SPC_POSTOLIGHT_VIEW_SPACE5, - SPC_POSTOLIGHT_VIEW_SPACE6, - SPC_POSTOLIGHT_VIEW_SPACE7, - - /// Light vector in tangent space index 0-7 - SPC_POSTOLIGHT_TANGENT_SPACE0, - SPC_POSTOLIGHT_TANGENT_SPACE1, - SPC_POSTOLIGHT_TANGENT_SPACE2, - SPC_POSTOLIGHT_TANGENT_SPACE3, - SPC_POSTOLIGHT_TANGENT_SPACE4, - SPC_POSTOLIGHT_TANGENT_SPACE5, - SPC_POSTOLIGHT_TANGENT_SPACE6, - SPC_POSTOLIGHT_TANGENT_SPACE7, - - /// Light direction in object space index 0-7 - SPC_LIGHTDIRECTION_OBJECT_SPACE0, - SPC_LIGHTDIRECTION_OBJECT_SPACE1, - SPC_LIGHTDIRECTION_OBJECT_SPACE2, - SPC_LIGHTDIRECTION_OBJECT_SPACE3, - SPC_LIGHTDIRECTION_OBJECT_SPACE4, - SPC_LIGHTDIRECTION_OBJECT_SPACE5, - SPC_LIGHTDIRECTION_OBJECT_SPACE6, - SPC_LIGHTDIRECTION_OBJECT_SPACE7, - - /// Light direction in world space index 0-7 - SPC_LIGHTDIRECTION_WORLD_SPACE0, - SPC_LIGHTDIRECTION_WORLD_SPACE1, - SPC_LIGHTDIRECTION_WORLD_SPACE2, - SPC_LIGHTDIRECTION_WORLD_SPACE3, - SPC_LIGHTDIRECTION_WORLD_SPACE4, - SPC_LIGHTDIRECTION_WORLD_SPACE5, - SPC_LIGHTDIRECTION_WORLD_SPACE6, - SPC_LIGHTDIRECTION_WORLD_SPACE7, - - /// Light direction in view space index 0-7 - SPC_LIGHTDIRECTION_VIEW_SPACE0, - SPC_LIGHTDIRECTION_VIEW_SPACE1, - SPC_LIGHTDIRECTION_VIEW_SPACE2, - SPC_LIGHTDIRECTION_VIEW_SPACE3, - SPC_LIGHTDIRECTION_VIEW_SPACE4, - SPC_LIGHTDIRECTION_VIEW_SPACE5, - SPC_LIGHTDIRECTION_VIEW_SPACE6, - SPC_LIGHTDIRECTION_VIEW_SPACE7, - - /// Light direction in tangent space index 0-7 - SPC_LIGHTDIRECTION_TANGENT_SPACE0, - SPC_LIGHTDIRECTION_TANGENT_SPACE1, - SPC_LIGHTDIRECTION_TANGENT_SPACE2, - SPC_LIGHTDIRECTION_TANGENT_SPACE3, - SPC_LIGHTDIRECTION_TANGENT_SPACE4, - SPC_LIGHTDIRECTION_TANGENT_SPACE5, - SPC_LIGHTDIRECTION_TANGENT_SPACE6, - SPC_LIGHTDIRECTION_TANGENT_SPACE7, - - /// Light position in object space index 0-7 - SPC_LIGHTPOSITION_OBJECT_SPACE0, - SPC_LIGHTPOSITION_OBJECT_SPACE1, - SPC_LIGHTPOSITION_OBJECT_SPACE2, - SPC_LIGHTPOSITION_OBJECT_SPACE3, - SPC_LIGHTPOSITION_OBJECT_SPACE4, - SPC_LIGHTPOSITION_OBJECT_SPACE5, - SPC_LIGHTPOSITION_OBJECT_SPACE6, - SPC_LIGHTPOSITION_OBJECT_SPACE7, - - /// Light position in world space index 0-7 - SPC_LIGHTPOSITION_WORLD_SPACE0, - SPC_LIGHTPOSITION_WORLD_SPACE1, - SPC_LIGHTPOSITION_WORLD_SPACE2, - SPC_LIGHTPOSITION_WORLD_SPACE3, - SPC_LIGHTPOSITION_WORLD_SPACE4, - SPC_LIGHTPOSITION_WORLD_SPACE5, - SPC_LIGHTPOSITION_WORLD_SPACE6, - SPC_LIGHTPOSITION_WORLD_SPACE7, - - /// Light position in view space index 0-7 - SPC_LIGHTPOSITIONVIEW_SPACE0, - SPC_LIGHTPOSITIONVIEW_SPACE1, - SPC_LIGHTPOSITIONVIEW_SPACE2, - SPC_LIGHTPOSITIONVIEW_SPACE3, - SPC_LIGHTPOSITIONVIEW_SPACE4, - SPC_LIGHTPOSITIONVIEW_SPACE5, - SPC_LIGHTPOSITIONVIEW_SPACE6, - SPC_LIGHTPOSITIONVIEW_SPACE7, - - /// Light position in tangent space index 0-7 - SPC_LIGHTPOSITION_TANGENT_SPACE, - - /// Blending weights - SPC_BLEND_WEIGHTS, - - /// Blending indices - SPC_BLEND_INDICES, - - /// Tangent in object space - SPC_TANGENT_OBJECT_SPACE, - - /// Tangent in world space - SPC_TANGENT_WORLD_SPACE, - - /// Tangent in view space - SPC_TANGENT_VIEW_SPACE, - - /// Tangent in tangent space - SPC_TANGENT_TANGENT_SPACE, - - /// Binormal in object space - SPC_BINORMAL_OBJECT_SPACE, - - /// Binormal in world space - SPC_BINORMAL_WORLD_SPACE, - - /// Binormal in view space - SPC_BINORMAL_VIEW_SPACE, - - /// Binormal in tangent space - SPC_BINORMAL_TANGENT_SPACE, - - /// Diffuse color - SPC_COLOR_DIFFUSE, - - /// Specular color - SPC_COLOR_SPECULAR, - - /// Depth in object space - SPC_DEPTH_OBJECT_SPACE, - - /// Depth in world space - SPC_DEPTH_WORLD_SPACE, - - /// Depth in view space - SPC_DEPTH_VIEW_SPACE, - - /// Depth in projective space - SPC_DEPTH_PROJECTIVE_SPACE, - - /// Texture coordinate set index 0-7 - SPC_TEXTURE_COORDINATE0, - SPC_TEXTURE_COORDINATE1, - SPC_TEXTURE_COORDINATE2, - SPC_TEXTURE_COORDINATE3, - SPC_TEXTURE_COORDINATE4, - SPC_TEXTURE_COORDINATE5, - SPC_TEXTURE_COORDINATE6, - SPC_TEXTURE_COORDINATE7, - - /// Reserved custom content range to be used by user custom shader extensions. - SPC_CUSTOM_CONTENT_BEGIN = 1000, - SPC_CUSTOM_CONTENT_END = 2000 - }; + // Shader parameter semantic. + enum Semantic + { + /// Unknown semantic + SPS_UNKNOWN = 0, + /// Position + SPS_POSITION = 1, + /// Blending weights + SPS_BLEND_WEIGHTS = 2, + /// Blending indices + SPS_BLEND_INDICES = 3, + /// Normal, 3 reals per vertex + SPS_NORMAL = 4, + /// General floating point color. + SPS_COLOR = 5, + /// Texture coordinates + SPS_TEXTURE_COORDINATES = 7, + /// Binormal (Y axis if normal is Z) + SPS_BINORMAL = 8, + /// Tangent (X axis if normal is Z) + SPS_TANGENT = 9 + }; + + // Shader parameter content. + enum Content + { + /// Unknown content + SPC_UNKNOWN, + + /// Position in object space + SPC_POSITION_OBJECT_SPACE, + + /// Position in world space + SPC_POSITION_WORLD_SPACE, + + /// Position in view space + SPC_POSITION_VIEW_SPACE, + + /// Position in projective space + SPC_POSITION_PROJECTIVE_SPACE, + + /// Position in light space index 0-7 + SPC_POSITION_LIGHT_SPACE0, + SPC_POSITION_LIGHT_SPACE1, + SPC_POSITION_LIGHT_SPACE2, + SPC_POSITION_LIGHT_SPACE3, + SPC_POSITION_LIGHT_SPACE4, + SPC_POSITION_LIGHT_SPACE5, + SPC_POSITION_LIGHT_SPACE6, + SPC_POSITION_LIGHT_SPACE7, + + /// Normal in object space + SPC_NORMAL_OBJECT_SPACE, + + /// Normal in world space + SPC_NORMAL_WORLD_SPACE, + + /// Normal in view space + SPC_NORMAL_VIEW_SPACE, + + /// Normal in tangent space + SPC_NORMAL_TANGENT_SPACE, + + /// View vector in object space + SPC_POSTOCAMERA_OBJECT_SPACE, + + /// View vector in world space + SPC_POSTOCAMERA_WORLD_SPACE, + + /// View vector in view space + SPC_POSTOCAMERA_VIEW_SPACE, + + /// View vector in tangent space + SPC_POSTOCAMERA_TANGENT_SPACE, + + /// Light vector in object space index 0-7 + SPC_POSTOLIGHT_OBJECT_SPACE0, + SPC_POSTOLIGHT_OBJECT_SPACE1, + SPC_POSTOLIGHT_OBJECT_SPACE2, + SPC_POSTOLIGHT_OBJECT_SPACE3, + SPC_POSTOLIGHT_OBJECT_SPACE4, + SPC_POSTOLIGHT_OBJECT_SPACE5, + SPC_POSTOLIGHT_OBJECT_SPACE6, + SPC_POSTOLIGHT_OBJECT_SPACE7, + + /// Light vector in world space index 0-7 + SPC_POSTOLIGHT_WORLD_SPACE0, + SPC_POSTOLIGHT_WORLD_SPACE1, + SPC_POSTOLIGHT_WORLD_SPACE2, + SPC_POSTOLIGHT_WORLD_SPACE3, + SPC_POSTOLIGHT_WORLD_SPACE4, + SPC_POSTOLIGHT_WORLD_SPACE5, + SPC_POSTOLIGHT_WORLD_SPACE6, + SPC_POSTOLIGHT_WORLD_SPACE7, + + /// Light vector in view space index 0-7 + SPC_POSTOLIGHT_VIEW_SPACE0, + SPC_POSTOLIGHT_VIEW_SPACE1, + SPC_POSTOLIGHT_VIEW_SPACE2, + SPC_POSTOLIGHT_VIEW_SPACE3, + SPC_POSTOLIGHT_VIEW_SPACE4, + SPC_POSTOLIGHT_VIEW_SPACE5, + SPC_POSTOLIGHT_VIEW_SPACE6, + SPC_POSTOLIGHT_VIEW_SPACE7, + + /// Light vector in tangent space index 0-7 + SPC_POSTOLIGHT_TANGENT_SPACE0, + SPC_POSTOLIGHT_TANGENT_SPACE1, + SPC_POSTOLIGHT_TANGENT_SPACE2, + SPC_POSTOLIGHT_TANGENT_SPACE3, + SPC_POSTOLIGHT_TANGENT_SPACE4, + SPC_POSTOLIGHT_TANGENT_SPACE5, + SPC_POSTOLIGHT_TANGENT_SPACE6, + SPC_POSTOLIGHT_TANGENT_SPACE7, + + /// Light direction in object space index 0-7 + SPC_LIGHTDIRECTION_OBJECT_SPACE0, + SPC_LIGHTDIRECTION_OBJECT_SPACE1, + SPC_LIGHTDIRECTION_OBJECT_SPACE2, + SPC_LIGHTDIRECTION_OBJECT_SPACE3, + SPC_LIGHTDIRECTION_OBJECT_SPACE4, + SPC_LIGHTDIRECTION_OBJECT_SPACE5, + SPC_LIGHTDIRECTION_OBJECT_SPACE6, + SPC_LIGHTDIRECTION_OBJECT_SPACE7, + + /// Light direction in world space index 0-7 + SPC_LIGHTDIRECTION_WORLD_SPACE0, + SPC_LIGHTDIRECTION_WORLD_SPACE1, + SPC_LIGHTDIRECTION_WORLD_SPACE2, + SPC_LIGHTDIRECTION_WORLD_SPACE3, + SPC_LIGHTDIRECTION_WORLD_SPACE4, + SPC_LIGHTDIRECTION_WORLD_SPACE5, + SPC_LIGHTDIRECTION_WORLD_SPACE6, + SPC_LIGHTDIRECTION_WORLD_SPACE7, + + /// Light direction in view space index 0-7 + SPC_LIGHTDIRECTION_VIEW_SPACE0, + SPC_LIGHTDIRECTION_VIEW_SPACE1, + SPC_LIGHTDIRECTION_VIEW_SPACE2, + SPC_LIGHTDIRECTION_VIEW_SPACE3, + SPC_LIGHTDIRECTION_VIEW_SPACE4, + SPC_LIGHTDIRECTION_VIEW_SPACE5, + SPC_LIGHTDIRECTION_VIEW_SPACE6, + SPC_LIGHTDIRECTION_VIEW_SPACE7, + + /// Light direction in tangent space index 0-7 + SPC_LIGHTDIRECTION_TANGENT_SPACE0, + SPC_LIGHTDIRECTION_TANGENT_SPACE1, + SPC_LIGHTDIRECTION_TANGENT_SPACE2, + SPC_LIGHTDIRECTION_TANGENT_SPACE3, + SPC_LIGHTDIRECTION_TANGENT_SPACE4, + SPC_LIGHTDIRECTION_TANGENT_SPACE5, + SPC_LIGHTDIRECTION_TANGENT_SPACE6, + SPC_LIGHTDIRECTION_TANGENT_SPACE7, + + /// Light position in object space index 0-7 + SPC_LIGHTPOSITION_OBJECT_SPACE0, + SPC_LIGHTPOSITION_OBJECT_SPACE1, + SPC_LIGHTPOSITION_OBJECT_SPACE2, + SPC_LIGHTPOSITION_OBJECT_SPACE3, + SPC_LIGHTPOSITION_OBJECT_SPACE4, + SPC_LIGHTPOSITION_OBJECT_SPACE5, + SPC_LIGHTPOSITION_OBJECT_SPACE6, + SPC_LIGHTPOSITION_OBJECT_SPACE7, + + /// Light position in world space index 0-7 + SPC_LIGHTPOSITION_WORLD_SPACE0, + SPC_LIGHTPOSITION_WORLD_SPACE1, + SPC_LIGHTPOSITION_WORLD_SPACE2, + SPC_LIGHTPOSITION_WORLD_SPACE3, + SPC_LIGHTPOSITION_WORLD_SPACE4, + SPC_LIGHTPOSITION_WORLD_SPACE5, + SPC_LIGHTPOSITION_WORLD_SPACE6, + SPC_LIGHTPOSITION_WORLD_SPACE7, + + /// Light position in view space index 0-7 + SPC_LIGHTPOSITIONVIEW_SPACE0, + SPC_LIGHTPOSITIONVIEW_SPACE1, + SPC_LIGHTPOSITIONVIEW_SPACE2, + SPC_LIGHTPOSITIONVIEW_SPACE3, + SPC_LIGHTPOSITIONVIEW_SPACE4, + SPC_LIGHTPOSITIONVIEW_SPACE5, + SPC_LIGHTPOSITIONVIEW_SPACE6, + SPC_LIGHTPOSITIONVIEW_SPACE7, + + /// Light position in tangent space index 0-7 + SPC_LIGHTPOSITION_TANGENT_SPACE, + + /// Blending weights + SPC_BLEND_WEIGHTS, + + /// Blending indices + SPC_BLEND_INDICES, + + /// Tangent in object space + SPC_TANGENT_OBJECT_SPACE, + + /// Tangent in world space + SPC_TANGENT_WORLD_SPACE, + + /// Tangent in view space + SPC_TANGENT_VIEW_SPACE, + + /// Tangent in tangent space + SPC_TANGENT_TANGENT_SPACE, + + /// Binormal in object space + SPC_BINORMAL_OBJECT_SPACE, + + /// Binormal in world space + SPC_BINORMAL_WORLD_SPACE, + + /// Binormal in view space + SPC_BINORMAL_VIEW_SPACE, + + /// Binormal in tangent space + SPC_BINORMAL_TANGENT_SPACE, + + /// Diffuse color + SPC_COLOR_DIFFUSE, + + /// Specular color + SPC_COLOR_SPECULAR, + + /// Depth in object space + SPC_DEPTH_OBJECT_SPACE, + + /// Depth in world space + SPC_DEPTH_WORLD_SPACE, + + /// Depth in view space + SPC_DEPTH_VIEW_SPACE, + + /// Depth in projective space + SPC_DEPTH_PROJECTIVE_SPACE, + + /// Texture coordinate set index 0-7 + SPC_TEXTURE_COORDINATE0, + SPC_TEXTURE_COORDINATE1, + SPC_TEXTURE_COORDINATE2, + SPC_TEXTURE_COORDINATE3, + SPC_TEXTURE_COORDINATE4, + SPC_TEXTURE_COORDINATE5, + SPC_TEXTURE_COORDINATE6, + SPC_TEXTURE_COORDINATE7, + + /// Reserved custom content range to be used by user custom shader extensions. + SPC_CUSTOM_CONTENT_BEGIN = 1000, + SPC_CUSTOM_CONTENT_END = 2000 + }; // Interface. public: - /** */ - Parameter(); + /** */ + Parameter(); - /** Class constructor. - @param type The type of this parameter. - @param name The name of this parameter. - @param semantic The semantic of this parameter. - @param index The index of this parameter. - @param content The content of this parameter. - */ - Parameter(GpuConstantType type, const String& name, - const Semantic& semantic, int index, - const Content& content, size_t size = 0); + /** Class constructor. + @param type The type of this parameter. + @param name The name of this parameter. + @param semantic The semantic of this parameter. + @param index The index of this parameter. + @param content The content of this parameter. + */ + Parameter(GpuConstantType type, const String& name, + const Semantic& semantic, int index, + const Content& content, size_t size = 0); - /** Class destructor */ - virtual ~Parameter() {}; + /** Class destructor */ + virtual ~Parameter() {}; - /** Get the name of this parameter. */ - const String& getName() const { return mName; } + /** Get the name of this parameter. */ + const String& getName() const { return mName; } - /** Get the type of this parameter. */ - GpuConstantType getType() const { return mType; } + /** Get the type of this parameter. */ + GpuConstantType getType() const { return mType; } - /** Get the semantic of this parameter. */ - const Semantic& getSemantic() const { return mSemantic; } + /** Get the semantic of this parameter. */ + const Semantic& getSemantic() const { return mSemantic; } - /** Get the index of this parameter. */ - int getIndex() const { return mIndex; } + /** Get the index of this parameter. */ + int getIndex() const { return mIndex; } - /** Return the content of this parameter. */ - Content getContent() const { return mContent; } + /** Return the content of this parameter. */ + Content getContent() const { return mContent; } - /** Returns true if this instance is a ConstParameter otherwise false. */ - virtual bool isConstParameter() const { return false; } + /** Returns true if this instance is a ConstParameter otherwise false. */ + virtual bool isConstParameter() const { return false; } - /** Returns the string representation of this parameter. */ - virtual String toString() const { return mName; } - - /** Returns Whether this parameter is an array. */ - bool isArray() const { return mSize > 0; } + /** Returns the string representation of this parameter. */ + virtual String toString() const { return mName; } + + /** Returns Whether this parameter is an array. */ + bool isArray() const { return mSize > 0; } - /** Returns the number of elements in the parameter (for arrays). */ - size_t getSize() const { return mSize; } - - /** Sets the number of elements in the parameter (for arrays). */ - void setSize(size_t size) { mSize = size; } + /** Returns the number of elements in the parameter (for arrays). */ + size_t getSize() const { return mSize; } + + /** Sets the number of elements in the parameter (for arrays). */ + void setSize(size_t size) { mSize = size; } // Attributes. protected: - // Name of this parameter. - String mName; - // Type of this parameter. - GpuConstantType mType; - // Semantic of this parameter. - Semantic mSemantic; - // Index of this parameter. - int mIndex; - // The content of this parameter. - Content mContent; - // Number of elements in the parameter (for arrays) - size_t mSize; - + // Name of this parameter. + String mName; + // Type of this parameter. + GpuConstantType mType; + // Semantic of this parameter. + Semantic mSemantic; + // Index of this parameter. + int mIndex; + // The content of this parameter. + Content mContent; + // Number of elements in the parameter (for arrays) + size_t mSize; + }; -typedef ShaderParameterList::iterator ShaderParameterIterator; -typedef ShaderParameterList::const_iterator ShaderParameterConstIterator; +typedef ShaderParameterList::iterator ShaderParameterIterator; +typedef ShaderParameterList::const_iterator ShaderParameterConstIterator; /** Uniform parameter class. Allow fast access to GPU parameter updates. */ @@ -373,197 +373,197 @@ class _OgreRTSSExport UniformParameter : public Parameter { public: - /** Class constructor. - @param type The type of this parameter. - @param name The name of this parameter. - @param semantic The semantic of this parameter. - @param index The index of this parameter. - @param content The content of this parameter. - @param variability How this parameter varies (bitwise combination of GpuProgramVariability). - @param size number of elements in the parameter. - */ - UniformParameter(GpuConstantType type, const String& name, - const Semantic& semantic, int index, - const Content& content, - uint16 variability, size_t size); - - /** Class constructor. - @param autoType The auto type of this parameter. - @param fAutoConstantData The real data for this auto constant parameter. - @param size number of elements in the parameter. - */ - UniformParameter(GpuProgramParameters::AutoConstantType autoType, Real fAutoConstantData, size_t size); - - /** Class constructor. - @param autoType The auto type of this parameter. - @param fAutoConstantData The real data for this auto constant parameter. - @param size number of elements in the parameter. - @param type The desired data type of this auto constant parameter. - */ - UniformParameter(GpuProgramParameters::AutoConstantType autoType, Real fAutoConstantData, size_t size, GpuConstantType type); - - /** Class constructor. - @param autoType The auto type of this parameter. - @param nAutoConstantData The int data for this auto constant parameter. - @param size number of elements in the parameter. - */ - UniformParameter(GpuProgramParameters::AutoConstantType autoType, size_t nAutoConstantData, size_t size); - - /** Class constructor. - @param autoType The auto type of this parameter. - @param nAutoConstantData The int data for this auto constant parameter. - @param size number of elements in the parameter. - @param type The desired data type of this auto constant parameter. - */ - UniformParameter(GpuProgramParameters::AutoConstantType autoType, size_t nAutoConstantData, size_t size, GpuConstantType type); - - - /** Get auto constant int data of this parameter, in case it is auto constant parameter. */ - size_t getAutoConstantIntData() const { return mAutoConstantIntData; } - - /** Get auto constant real data of this parameter, in case it is auto constant parameter. */ - Real getAutoConstantRealData() const { return mAutoConstantRealData; } - - /** Return true if this parameter is a floating point type, false otherwise. */ - bool isFloat() const; - - /** Return true if this parameter is a texture sampler type, false otherwise. */ - bool isSampler() const; - - /** Return true if this parameter is an auto constant parameter, false otherwise. */ - bool isAutoConstantParameter() const { return mIsAutoConstantReal || mIsAutoConstantInt; } - - /** Return true if this parameter an auto constant with int data type, false otherwise. */ - bool isAutoConstantIntParameter() const { return mIsAutoConstantInt; } - - /** Return true if this parameter an auto constant with real data type, false otherwise. */ - bool isAutoConstantRealParameter() const { return mIsAutoConstantReal; } - - /** Return the auto constant type of this parameter. */ - GpuProgramParameters::AutoConstantType getAutoConstantType () const { return mAutoConstantType; } - - /** Return the variability of this parameter. */ - uint16 getVariability() const { return mVariability; } - - /** Bind this parameter to the corresponding GPU parameter. */ - void bind(GpuProgramParametersSharedPtr paramsPtr); + /** Class constructor. + @param type The type of this parameter. + @param name The name of this parameter. + @param semantic The semantic of this parameter. + @param index The index of this parameter. + @param content The content of this parameter. + @param variability How this parameter varies (bitwise combination of GpuProgramVariability). + @param size number of elements in the parameter. + */ + UniformParameter(GpuConstantType type, const String& name, + const Semantic& semantic, int index, + const Content& content, + uint16 variability, size_t size); + + /** Class constructor. + @param autoType The auto type of this parameter. + @param fAutoConstantData The real data for this auto constant parameter. + @param size number of elements in the parameter. + */ + UniformParameter(GpuProgramParameters::AutoConstantType autoType, Real fAutoConstantData, size_t size); + + /** Class constructor. + @param autoType The auto type of this parameter. + @param fAutoConstantData The real data for this auto constant parameter. + @param size number of elements in the parameter. + @param type The desired data type of this auto constant parameter. + */ + UniformParameter(GpuProgramParameters::AutoConstantType autoType, Real fAutoConstantData, size_t size, GpuConstantType type); + + /** Class constructor. + @param autoType The auto type of this parameter. + @param nAutoConstantData The int data for this auto constant parameter. + @param size number of elements in the parameter. + */ + UniformParameter(GpuProgramParameters::AutoConstantType autoType, size_t nAutoConstantData, size_t size); + + /** Class constructor. + @param autoType The auto type of this parameter. + @param nAutoConstantData The int data for this auto constant parameter. + @param size number of elements in the parameter. + @param type The desired data type of this auto constant parameter. + */ + UniformParameter(GpuProgramParameters::AutoConstantType autoType, size_t nAutoConstantData, size_t size, GpuConstantType type); + + + /** Get auto constant int data of this parameter, in case it is auto constant parameter. */ + size_t getAutoConstantIntData() const { return mAutoConstantIntData; } + + /** Get auto constant real data of this parameter, in case it is auto constant parameter. */ + Real getAutoConstantRealData() const { return mAutoConstantRealData; } + + /** Return true if this parameter is a floating point type, false otherwise. */ + bool isFloat() const; + + /** Return true if this parameter is a texture sampler type, false otherwise. */ + bool isSampler() const; + + /** Return true if this parameter is an auto constant parameter, false otherwise. */ + bool isAutoConstantParameter() const { return mIsAutoConstantReal || mIsAutoConstantInt; } + + /** Return true if this parameter an auto constant with int data type, false otherwise. */ + bool isAutoConstantIntParameter() const { return mIsAutoConstantInt; } + + /** Return true if this parameter an auto constant with real data type, false otherwise. */ + bool isAutoConstantRealParameter() const { return mIsAutoConstantReal; } + + /** Return the auto constant type of this parameter. */ + GpuProgramParameters::AutoConstantType getAutoConstantType () const { return mAutoConstantType; } + + /** Return the variability of this parameter. */ + uint16 getVariability() const { return mVariability; } + + /** Bind this parameter to the corresponding GPU parameter. */ + void bind(GpuProgramParametersSharedPtr paramsPtr); public: - /** Update the GPU parameter with the given value. */ - void setGpuParameter(int val) - { - if (mParamsPtr != NULL) - { - mParamsPtr->_writeRawConstant(mPhysicalIndex, val); - } - } - - /** Update the GPU parameter with the given value. */ - void setGpuParameter(Real val) - { - if (mParamsPtr != NULL) - { - mParamsPtr->_writeRawConstant(mPhysicalIndex, val); - } - } - - /** Update the GPU parameter with the given value. */ - void setGpuParameter(const ColourValue& val) - { - if (mParamsPtr != NULL) - { - mParamsPtr->_writeRawConstant(mPhysicalIndex, val); - } - } - - /** Update the GPU parameter with the given value. */ - void setGpuParameter(const Vector2& val) - { - if (mParamsPtr != NULL) - { - mParamsPtr->_writeRawConstants(mPhysicalIndex, val.ptr(), 2); - } - } - - /** Update the GPU parameter with the given value. */ - void setGpuParameter(const Vector3& val) - { - if (mParamsPtr != NULL) - { - mParamsPtr->_writeRawConstant(mPhysicalIndex, val); - } - } - - /** Update the GPU parameter with the given value. */ - void setGpuParameter(const Vector4& val) - { - if (mParamsPtr != NULL) - { - mParamsPtr->_writeRawConstant(mPhysicalIndex, val); - } - } - - /** Update the GPU parameter with the given value. */ - void setGpuParameter(const Matrix4& val) - { - if (mParamsPtr != NULL) - { - mParamsPtr->_writeRawConstant(mPhysicalIndex, val, 16); - } - } - - /** Update the GPU parameter with the given value. */ - void setGpuParameter(const float *val, size_t count, size_t multiple = 4) - { - if (mParamsPtr != NULL) - { - mParamsPtr->_writeRawConstants(mPhysicalIndex, val, count * multiple); - } - } - - /** Update the GPU parameter with the given value. */ - void setGpuParameter(const double *val, size_t count, size_t multiple = 4) - { - if (mParamsPtr != NULL) - { - mParamsPtr->_writeRawConstants(mPhysicalIndex, val, count * multiple); - } - } - - /** Update the GPU parameter with the given value. */ - void setGpuParameter(const int *val, size_t count, size_t multiple = 4) - { - if (mParamsPtr != NULL) - { - mParamsPtr->_writeRawConstants(mPhysicalIndex, val, count * multiple); - } - } + /** Update the GPU parameter with the given value. */ + void setGpuParameter(int val) + { + if (mParamsPtr != NULL) + { + mParamsPtr->_writeRawConstant(mPhysicalIndex, val); + } + } + + /** Update the GPU parameter with the given value. */ + void setGpuParameter(Real val) + { + if (mParamsPtr != NULL) + { + mParamsPtr->_writeRawConstant(mPhysicalIndex, val); + } + } + + /** Update the GPU parameter with the given value. */ + void setGpuParameter(const ColourValue& val) + { + if (mParamsPtr != NULL) + { + mParamsPtr->_writeRawConstant(mPhysicalIndex, val); + } + } + + /** Update the GPU parameter with the given value. */ + void setGpuParameter(const Vector2& val) + { + if (mParamsPtr != NULL) + { + mParamsPtr->_writeRawConstants(mPhysicalIndex, val.ptr(), 2); + } + } + + /** Update the GPU parameter with the given value. */ + void setGpuParameter(const Vector3& val) + { + if (mParamsPtr != NULL) + { + mParamsPtr->_writeRawConstant(mPhysicalIndex, val); + } + } + + /** Update the GPU parameter with the given value. */ + void setGpuParameter(const Vector4& val) + { + if (mParamsPtr != NULL) + { + mParamsPtr->_writeRawConstant(mPhysicalIndex, val); + } + } + + /** Update the GPU parameter with the given value. */ + void setGpuParameter(const Matrix4& val) + { + if (mParamsPtr != NULL) + { + mParamsPtr->_writeRawConstant(mPhysicalIndex, val, 16); + } + } + + /** Update the GPU parameter with the given value. */ + void setGpuParameter(const float *val, size_t count, size_t multiple = 4) + { + if (mParamsPtr != NULL) + { + mParamsPtr->_writeRawConstants(mPhysicalIndex, val, count * multiple); + } + } + + /** Update the GPU parameter with the given value. */ + void setGpuParameter(const double *val, size_t count, size_t multiple = 4) + { + if (mParamsPtr != NULL) + { + mParamsPtr->_writeRawConstants(mPhysicalIndex, val, count * multiple); + } + } + + /** Update the GPU parameter with the given value. */ + void setGpuParameter(const int *val, size_t count, size_t multiple = 4) + { + if (mParamsPtr != NULL) + { + mParamsPtr->_writeRawConstants(mPhysicalIndex, val, count * multiple); + } + } protected: - // Is it auto constant real based parameter. - bool mIsAutoConstantReal; - // Is it auto constant int based parameter. - bool mIsAutoConstantInt; - GpuProgramParameters::AutoConstantType mAutoConstantType; // The auto constant type of this parameter. - union - { - // Auto constant int data. - size_t mAutoConstantIntData; - // Auto constant real data. - Real mAutoConstantRealData; - }; - // How this parameter varies (bitwise combination of GpuProgramVariability). - uint16 mVariability; - // The actual GPU parameters pointer. - GpuProgramParameters* mParamsPtr; - // The physical index of this parameter in the GPU program. - size_t mPhysicalIndex; + // Is it auto constant real based parameter. + bool mIsAutoConstantReal; + // Is it auto constant int based parameter. + bool mIsAutoConstantInt; + GpuProgramParameters::AutoConstantType mAutoConstantType; // The auto constant type of this parameter. + union + { + // Auto constant int data. + size_t mAutoConstantIntData; + // Auto constant real data. + Real mAutoConstantRealData; + }; + // How this parameter varies (bitwise combination of GpuProgramVariability). + uint16 mVariability; + // The actual GPU parameters pointer. + GpuProgramParameters* mParamsPtr; + // The physical index of this parameter in the GPU program. + size_t mPhysicalIndex; }; -typedef vector::type UniformParameterList; -typedef UniformParameterList::iterator UniformParameterIterator; -typedef UniformParameterList::const_iterator UniformParameterConstIterator; +typedef vector::type UniformParameterList; +typedef UniformParameterList::iterator UniformParameterIterator; +typedef UniformParameterList::const_iterator UniformParameterConstIterator; /** Helper template which is the base for our ConstParameters */ @@ -572,32 +572,32 @@ class ConstParameter : public Parameter { public: - ConstParameter( valueType val, - GpuConstantType type, - const Semantic& semantic, - const Content& content) - : Parameter(type, "Constant", semantic, 0, content) - { - mValue = val; - } + ConstParameter( valueType val, + GpuConstantType type, + const Semantic& semantic, + const Content& content) + : Parameter(type, "Constant", semantic, 0, content) + { + mValue = val; + } - virtual ~ConstParameter () {} + virtual ~ConstParameter () {} - /** Returns the native value of this parameter. (for example a Vector3) */ - const valueType& getValue() const { return mValue; } + /** Returns the native value of this parameter. (for example a Vector3) */ + const valueType& getValue() const { return mValue; } - /** - @see Parameter::isConstParameter. - */ - virtual bool isConstParameter() const { return true; } + /** + @see Parameter::isConstParameter. + */ + virtual bool isConstParameter() const { return true; } - /** - @see Parameter::toString. - */ - virtual String toString() const = 0; + /** + @see Parameter::toString. + */ + virtual String toString() const = 0; protected: - valueType mValue; + valueType mValue; }; /** Helper utility class that creates common parameters. @@ -605,47 +605,47 @@ class ConstParameter : public Parameter class _OgreRTSSExport ParameterFactory { - // Interface. + // Interface. public: - static ParameterPtr createInPosition(int index); - static ParameterPtr createOutPosition(int index); - - static ParameterPtr createInNormal(int index); - static ParameterPtr createInWeights(int index); - static ParameterPtr createInIndices(int index); - static ParameterPtr createOutNormal(int index); - static ParameterPtr createInBiNormal(int index); - static ParameterPtr createOutBiNormal(int index); - static ParameterPtr createInTangent(int index); - static ParameterPtr createOutTangent(int index); - static ParameterPtr createInColor(int index); - static ParameterPtr createOutColor(int index); - - static ParameterPtr createInTexcoord(GpuConstantType type, int index, Parameter::Content content); - static ParameterPtr createOutTexcoord(GpuConstantType type, int index, Parameter::Content content); - static ParameterPtr createInTexcoord1(int index, Parameter::Content content); - static ParameterPtr createOutTexcoord1(int index, Parameter::Content content); - static ParameterPtr createInTexcoord2(int index, Parameter::Content content); - static ParameterPtr createOutTexcoord2(int index, Parameter::Content content); - static ParameterPtr createInTexcoord3(int index, Parameter::Content content); - static ParameterPtr createOutTexcoord3(int index, Parameter::Content content); - static ParameterPtr createInTexcoord4(int index, Parameter::Content content); - static ParameterPtr createOutTexcoord4(int index, Parameter::Content content); - - static ParameterPtr createConstParamVector2(Vector2 val); - static ParameterPtr createConstParamVector3(Vector3 val); - static ParameterPtr createConstParamVector4(Vector4 val); - static ParameterPtr createConstParamFloat(float val); - - static UniformParameterPtr createSampler(GpuConstantType type, int index); - static UniformParameterPtr createSampler1D(int index); - static UniformParameterPtr createSampler2D(int index); - static UniformParameterPtr createSampler2DArray(int index); - static UniformParameterPtr createSampler3D(int index); - static UniformParameterPtr createSamplerCUBE(int index); - - static UniformParameterPtr createUniform(GpuConstantType type, int index, uint16 variability, const String& suggestedName, size_t size); + static ParameterPtr createInPosition(int index); + static ParameterPtr createOutPosition(int index); + + static ParameterPtr createInNormal(int index); + static ParameterPtr createInWeights(int index); + static ParameterPtr createInIndices(int index); + static ParameterPtr createOutNormal(int index); + static ParameterPtr createInBiNormal(int index); + static ParameterPtr createOutBiNormal(int index); + static ParameterPtr createInTangent(int index); + static ParameterPtr createOutTangent(int index); + static ParameterPtr createInColor(int index); + static ParameterPtr createOutColor(int index); + + static ParameterPtr createInTexcoord(GpuConstantType type, int index, Parameter::Content content); + static ParameterPtr createOutTexcoord(GpuConstantType type, int index, Parameter::Content content); + static ParameterPtr createInTexcoord1(int index, Parameter::Content content); + static ParameterPtr createOutTexcoord1(int index, Parameter::Content content); + static ParameterPtr createInTexcoord2(int index, Parameter::Content content); + static ParameterPtr createOutTexcoord2(int index, Parameter::Content content); + static ParameterPtr createInTexcoord3(int index, Parameter::Content content); + static ParameterPtr createOutTexcoord3(int index, Parameter::Content content); + static ParameterPtr createInTexcoord4(int index, Parameter::Content content); + static ParameterPtr createOutTexcoord4(int index, Parameter::Content content); + + static ParameterPtr createConstParamVector2(Vector2 val); + static ParameterPtr createConstParamVector3(Vector3 val); + static ParameterPtr createConstParamVector4(Vector4 val); + static ParameterPtr createConstParamFloat(float val); + + static UniformParameterPtr createSampler(GpuConstantType type, int index); + static UniformParameterPtr createSampler1D(int index); + static UniformParameterPtr createSampler2D(int index); + static UniformParameterPtr createSampler2DArray(int index); + static UniformParameterPtr createSampler3D(int index); + static UniformParameterPtr createSamplerCUBE(int index); + + static UniformParameterPtr createUniform(GpuConstantType type, int index, uint16 variability, const String& suggestedName, size_t size); }; diff --git a/Components/RTShaderSystem/include/OgreShaderPrerequisites.h b/Components/RTShaderSystem/include/OgreShaderPrerequisites.h index cf5eb0e528c..8320e099ff8 100644 --- a/Components/RTShaderSystem/include/OgreShaderPrerequisites.h +++ b/Components/RTShaderSystem/include/OgreShaderPrerequisites.h @@ -46,7 +46,7 @@ class ScriptCompiler; class PropertyAbstractNode; class MaterialSerializer; -typedef GeneralAllocatedObject RTShaderSystemAlloc; +typedef GeneralAllocatedObject RTShaderSystemAlloc; namespace RTShader { @@ -79,21 +79,21 @@ typedef vector::type ShaderParameterList; template inline void sh_hash_combine(uint32& seed, T const& v) { - seed ^= FastHash((const char*)&v, sizeof(T)) + 0x9e3779b9 + (seed<<6) + (seed>>2); + seed ^= FastHash((const char*)&v, sizeof(T)) + 0x9e3779b9 + (seed<<6) + (seed>>2); } // Vertex shader output parameters compact policy. enum VSOutputCompactPolicy -{ - VSOCP_LOW = 0, // VS Outputs will be compacted just in case the maximum slot count exceeded. - VSOCP_MEDIUM = 1, // VS Outputs will be compacted always without parameter splits. - VSOCP_HIGH = 2 // VS Outputs will be compacted always including parameter splits. +{ + VSOCP_LOW = 0, // VS Outputs will be compacted just in case the maximum slot count exceeded. + VSOCP_MEDIUM = 1, // VS Outputs will be compacted always without parameter splits. + VSOCP_HIGH = 2 // VS Outputs will be compacted always including parameter splits. }; enum SkinningType { - ST_LINEAR, - ST_DUAL_QUATERNION + ST_LINEAR, + ST_DUAL_QUATERNION }; @@ -101,23 +101,23 @@ enum SkinningType } #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT -# if defined( OGRE_STATIC_LIB ) -# define _OgreRTSSExport +# if defined( OGRE_STATIC_LIB ) +# define _OgreRTSSExport # else -# if defined( OgreRTShaderSystem_EXPORTS ) -# define _OgreRTSSExport __declspec( dllexport ) -# else +# if defined( OgreRTShaderSystem_EXPORTS ) +# define _OgreRTSSExport __declspec( dllexport ) +# else # if defined( __MINGW32__ ) # define _OgreRTSSExport # else -# define _OgreRTSSExport __declspec( dllimport ) +# define _OgreRTSSExport __declspec( dllimport ) # endif -# endif -# endif +# endif +# endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgreRTSSExport __attribute__ ((visibility("default"))) #else -# define _OgreRTSSExport +# define _OgreRTSSExport #endif diff --git a/Components/RTShaderSystem/include/OgreShaderProgram.h b/Components/RTShaderSystem/include/OgreShaderProgram.h index e4fb9ce9cae..729101b3078 100644 --- a/Components/RTShaderSystem/include/OgreShaderProgram.h +++ b/Components/RTShaderSystem/include/OgreShaderProgram.h @@ -49,188 +49,188 @@ class _OgreRTSSExport Program : public RTShaderSystemAlloc { // Interface. -public: - /** Get the type of this program. */ - GpuProgramType getType() const; - - /** Resolve uniform auto constant parameter with associated real data of this program. - @param autoType The auto type of the desired parameter. - @param data The data to associate with the auto parameter. - @param size number of elements in the parameter. - Return parameter instance in case of that resolve operation succeeded. - */ - UniformParameterPtr resolveAutoParameterReal(GpuProgramParameters::AutoConstantType autoType, Real data, size_t size = 0); - - /** Resolve uniform auto constant parameter with associated real data of this program. - @param autoType The auto type of the desired parameter. - @param type The desired data type of the auto parameter. - @param data The data to associate with the auto parameter. - @param size number of elements in the parameter. - Return parameter instance in case of that resolve operation succeeded. - */ - UniformParameterPtr resolveAutoParameterReal(GpuProgramParameters::AutoConstantType autoType, GpuConstantType type, Real data, size_t size = 0); - - /** Resolve uniform auto constant parameter with associated int data of this program. - @param autoType The auto type of the desired parameter. - @param data The data to associate with the auto parameter. - @param size number of elements in the parameter. - Return parameter instance in case of that resolve operation succeeded. - */ - UniformParameterPtr resolveAutoParameterInt(GpuProgramParameters::AutoConstantType autoType, size_t data, size_t size = 0); - - /** Resolve uniform auto constant parameter with associated int data of this program. - @param autoType The auto type of the desired parameter. - @param type The desired data type of the auto parameter. - @param data The data to associate with the auto parameter. - @param size number of elements in the parameter. - Return parameter instance in case of that resolve operation succeeded. - */ - UniformParameterPtr resolveAutoParameterInt(GpuProgramParameters::AutoConstantType autoType, GpuConstantType type, size_t data, size_t size = 0); - - /** Resolve uniform parameter of this program. - @param type The type of the desired parameter. - @param index The index of the desired parameter. - @param suggestedName The suggested name for the parameter in case new one should be create. - @param variability How this parameter varies (bitwise combination of GpuProgramVariability). - @param size number of elements in the parameter. - Return parameter instance in case of that resolve operation succeeded. - @remarks Pass -1 as index parameter to create a new parameter with the desired type and index. - */ - UniformParameterPtr resolveParameter(GpuConstantType type, int index, uint16 variability, const String& suggestedName, size_t size = 0); - - /** Get parameter by a given name. - @param name The name of the parameter to search for. - @remarks Return NULL if no matching parameter found. - */ - UniformParameterPtr getParameterByName(const String& name); - - /** Get parameter by a given auto constant type. - @param autoType The auto type of the parameter to search for. - @remarks Return NULL if no matching parameter found. - */ - UniformParameterPtr getParameterByAutoType(GpuProgramParameters::AutoConstantType autoType); - - /** Get parameter by a given type and index. - @param type The type of the parameter to search for. - @param index The index of the parameter to search for. - @remarks Return NULL if no matching parameter found. - */ - UniformParameterPtr getParameterByType(GpuConstantType type, int index); - - /** Get the list of uniform parameters of this program. - */ - const UniformParameterList& getParameters() const { return mParameters; }; - - /** Create new function in this program. Return the newly created function instance. - @param name The name of the function to create. - @param desc The description of the function. - */ - Function* createFunction(const String& name, const String& desc, const Function::FunctionType functionType); - - /** Get a function by a given name. Return NULL if no matching function found. - @param name The name of the function to search for. - */ - Function* getFunctionByName(const String& name); - - /** Get the function list of this program. - */ - const ShaderFunctionList& getFunctions() const { return mFunctions; }; - - /** Set the entry point function. - @param function The function that will use as entry point of this program. - */ - void setEntryPointFunction(Function* function) { mEntryPointFunction = function; } - - /** Get the entry point function of this program.*/ - Function* getEntryPointFunction() { return mEntryPointFunction; } - - /** Add dependency for this program. Basically a filename that will be included in this - program and provide predefined shader functions code. - One should verify that the given library file he provides can be reached by the resource manager. - This step can be achieved using the ResourceGroupManager::addResourceLocation method. - */ - void addDependency(const String& libFileName); - - /** Get the number of external libs this program depends on */ - size_t getDependencyCount() const; - - /** Get the library name of the given index dependency. - @param index The index of the dependecy. - */ - const String& getDependency(unsigned int index) const; - - - /** Sets whether a vertex program includes the required instructions +public: + /** Get the type of this program. */ + GpuProgramType getType() const; + + /** Resolve uniform auto constant parameter with associated real data of this program. + @param autoType The auto type of the desired parameter. + @param data The data to associate with the auto parameter. + @param size number of elements in the parameter. + Return parameter instance in case of that resolve operation succeeded. + */ + UniformParameterPtr resolveAutoParameterReal(GpuProgramParameters::AutoConstantType autoType, Real data, size_t size = 0); + + /** Resolve uniform auto constant parameter with associated real data of this program. + @param autoType The auto type of the desired parameter. + @param type The desired data type of the auto parameter. + @param data The data to associate with the auto parameter. + @param size number of elements in the parameter. + Return parameter instance in case of that resolve operation succeeded. + */ + UniformParameterPtr resolveAutoParameterReal(GpuProgramParameters::AutoConstantType autoType, GpuConstantType type, Real data, size_t size = 0); + + /** Resolve uniform auto constant parameter with associated int data of this program. + @param autoType The auto type of the desired parameter. + @param data The data to associate with the auto parameter. + @param size number of elements in the parameter. + Return parameter instance in case of that resolve operation succeeded. + */ + UniformParameterPtr resolveAutoParameterInt(GpuProgramParameters::AutoConstantType autoType, size_t data, size_t size = 0); + + /** Resolve uniform auto constant parameter with associated int data of this program. + @param autoType The auto type of the desired parameter. + @param type The desired data type of the auto parameter. + @param data The data to associate with the auto parameter. + @param size number of elements in the parameter. + Return parameter instance in case of that resolve operation succeeded. + */ + UniformParameterPtr resolveAutoParameterInt(GpuProgramParameters::AutoConstantType autoType, GpuConstantType type, size_t data, size_t size = 0); + + /** Resolve uniform parameter of this program. + @param type The type of the desired parameter. + @param index The index of the desired parameter. + @param suggestedName The suggested name for the parameter in case new one should be create. + @param variability How this parameter varies (bitwise combination of GpuProgramVariability). + @param size number of elements in the parameter. + Return parameter instance in case of that resolve operation succeeded. + @remarks Pass -1 as index parameter to create a new parameter with the desired type and index. + */ + UniformParameterPtr resolveParameter(GpuConstantType type, int index, uint16 variability, const String& suggestedName, size_t size = 0); + + /** Get parameter by a given name. + @param name The name of the parameter to search for. + @remarks Return NULL if no matching parameter found. + */ + UniformParameterPtr getParameterByName(const String& name); + + /** Get parameter by a given auto constant type. + @param autoType The auto type of the parameter to search for. + @remarks Return NULL if no matching parameter found. + */ + UniformParameterPtr getParameterByAutoType(GpuProgramParameters::AutoConstantType autoType); + + /** Get parameter by a given type and index. + @param type The type of the parameter to search for. + @param index The index of the parameter to search for. + @remarks Return NULL if no matching parameter found. + */ + UniformParameterPtr getParameterByType(GpuConstantType type, int index); + + /** Get the list of uniform parameters of this program. + */ + const UniformParameterList& getParameters() const { return mParameters; }; + + /** Create new function in this program. Return the newly created function instance. + @param name The name of the function to create. + @param desc The description of the function. + */ + Function* createFunction(const String& name, const String& desc, const Function::FunctionType functionType); + + /** Get a function by a given name. Return NULL if no matching function found. + @param name The name of the function to search for. + */ + Function* getFunctionByName(const String& name); + + /** Get the function list of this program. + */ + const ShaderFunctionList& getFunctions() const { return mFunctions; }; + + /** Set the entry point function. + @param function The function that will use as entry point of this program. + */ + void setEntryPointFunction(Function* function) { mEntryPointFunction = function; } + + /** Get the entry point function of this program.*/ + Function* getEntryPointFunction() { return mEntryPointFunction; } + + /** Add dependency for this program. Basically a filename that will be included in this + program and provide predefined shader functions code. + One should verify that the given library file he provides can be reached by the resource manager. + This step can be achieved using the ResourceGroupManager::addResourceLocation method. + */ + void addDependency(const String& libFileName); + + /** Get the number of external libs this program depends on */ + size_t getDependencyCount() const; + + /** Get the library name of the given index dependency. + @param index The index of the dependecy. + */ + const String& getDependency(unsigned int index) const; + + + /** Sets whether a vertex program includes the required instructions to perform skeletal animation. */ - void setSkeletalAnimationIncluded(bool value) { mSkeletalAnimation = value; } + void setSkeletalAnimationIncluded(bool value) { mSkeletalAnimation = value; } - /** Returns whether a vertex program includes the required instructions + /** Returns whether a vertex program includes the required instructions to perform skeletal animation. */ bool getSkeletalAnimationIncluded() const { return mSkeletalAnimation; } - /** Tells Ogre whether auto-bound matrices should be sent in column or row-major order. - @remarks - This method has the same effect as column_major_matrices option used when declaring manually written hlsl program. - You want to use this method only when you use float3x4 type in a shader, e.g. for bone matrices. - In mentioned case you should call this method with false as parameter. - @par - For more detail see OGRE Manual, section 3.1.6 DirectX9 HLSL. - @note - This setting has any effect only when the target language is HLSL. - @param value Should Ogre pass auto-bound matrices as column-major? The default is true. - */ - void setUseColumnMajorMatrices(bool value) { mColumnMajorMatrices = value; } - - /** Returns whether Ogre will pass auto-bound matrices as column-major. - @return - true, when the matrices will be passed in column-major order, false, when they will be passed as row-major. - */ - bool getUseColumnMajorMatrices() const { return mColumnMajorMatrices; } + /** Tells Ogre whether auto-bound matrices should be sent in column or row-major order. + @remarks + This method has the same effect as column_major_matrices option used when declaring manually written hlsl program. + You want to use this method only when you use float3x4 type in a shader, e.g. for bone matrices. + In mentioned case you should call this method with false as parameter. + @par + For more detail see OGRE Manual, section 3.1.6 DirectX9 HLSL. + @note + This setting has any effect only when the target language is HLSL. + @param value Should Ogre pass auto-bound matrices as column-major? The default is true. + */ + void setUseColumnMajorMatrices(bool value) { mColumnMajorMatrices = value; } + + /** Returns whether Ogre will pass auto-bound matrices as column-major. + @return + true, when the matrices will be passed in column-major order, false, when they will be passed as row-major. + */ + bool getUseColumnMajorMatrices() const { return mColumnMajorMatrices; } // Protected methods. protected: - /** Class constructor. - @param type The type of this program. - */ - Program(GpuProgramType type); + /** Class constructor. + @param type The type of this program. + */ + Program(GpuProgramType type); - /** Class destructor */ - ~Program(); + /** Class destructor */ + ~Program(); - /** Destroy all parameters of this program. */ - void destroyParameters(); + /** Destroy all parameters of this program. */ + void destroyParameters(); - /** Destroy all functions of this program. */ - void destroyFunctions(); + /** Destroy all functions of this program. */ + void destroyFunctions(); - /** Add parameter to this program. */ - void addParameter(UniformParameterPtr parameter); - - /** Remove parameter from this program. */ - void removeParameter(UniformParameterPtr parameter); + /** Add parameter to this program. */ + void addParameter(UniformParameterPtr parameter); + + /** Remove parameter from this program. */ + void removeParameter(UniformParameterPtr parameter); // Attributes. protected: - // Program type. (Vertex, Fragment, Geometry). - GpuProgramType mType; - // Program uniform parameters. - UniformParameterList mParameters; - // Function list. - ShaderFunctionList mFunctions; - // Entry point function for this program. - Function* mEntryPointFunction; - // Program dependencies. - StringVector mDependencies; - // Skeletal animation calculation - bool mSkeletalAnimation; - // Whether to pass matrices as column-major. - bool mColumnMajorMatrices; + // Program type. (Vertex, Fragment, Geometry). + GpuProgramType mType; + // Program uniform parameters. + UniformParameterList mParameters; + // Function list. + ShaderFunctionList mFunctions; + // Entry point function for this program. + Function* mEntryPointFunction; + // Program dependencies. + StringVector mDependencies; + // Skeletal animation calculation + bool mSkeletalAnimation; + // Whether to pass matrices as column-major. + bool mColumnMajorMatrices; private: - friend class ProgramManager; + friend class ProgramManager; }; /** @} */ diff --git a/Components/RTShaderSystem/include/OgreShaderProgramManager.h b/Components/RTShaderSystem/include/OgreShaderProgramManager.h index ce264237187..c97b60233d2 100644 --- a/Components/RTShaderSystem/include/OgreShaderProgramManager.h +++ b/Components/RTShaderSystem/include/OgreShaderProgramManager.h @@ -51,198 +51,198 @@ class _OgreRTSSExport ProgramManager : public Singleton, public // Interface. public: - /** Class default constructor */ - ProgramManager(); - - /** Class destructor */ - ~ProgramManager(); - - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static ProgramManager& getSingleton(); - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static ProgramManager* getSingletonPtr(); - - /** Acquire CPU/GPU programs set associated with the given render state and bind them to the pass. - @param pass The pass to bind the programs to. - @param renderState The render state that describes the program that need to be generated. - */ - void acquirePrograms(Pass* pass, TargetRenderState* renderState); - - /** Release CPU/GPU programs set associated with the given render state and pass. - @param pass The pass to release the programs from. - @param renderState The render state holds the programs. - */ - void releasePrograms(Pass* pass, TargetRenderState* renderState); - - /** Flush the local GPU programs cache. - */ - void flushGpuProgramsCache(); + /** Class default constructor */ + ProgramManager(); + + /** Class destructor */ + ~ProgramManager(); + + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static ProgramManager& getSingleton(); + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static ProgramManager* getSingletonPtr(); + + /** Acquire CPU/GPU programs set associated with the given render state and bind them to the pass. + @param pass The pass to bind the programs to. + @param renderState The render state that describes the program that need to be generated. + */ + void acquirePrograms(Pass* pass, TargetRenderState* renderState); + + /** Release CPU/GPU programs set associated with the given render state and pass. + @param pass The pass to release the programs from. + @param renderState The render state holds the programs. + */ + void releasePrograms(Pass* pass, TargetRenderState* renderState); + + /** Flush the local GPU programs cache. + */ + void flushGpuProgramsCache(); protected: - //----------------------------------------------------------------------------- - typedef map::type GpuProgramsMap; - typedef map::type ProgramSourceToNameMap; - typedef GpuProgramsMap::iterator GpuProgramsMapIterator; - typedef GpuProgramsMap::const_iterator GpuProgramsMapConstIterator; - - //----------------------------------------------------------------------------- - typedef set::type ProgramList; - typedef ProgramList::iterator ProgramListIterator; - typedef map::type ProgramWriterMap; - typedef ProgramWriterMap::iterator ProgramWriterIterator; - typedef vector::type ProgramWriterFactoryList; - - //----------------------------------------------------------------------------- - typedef map::type ProgramProcessorMap; - typedef ProgramProcessorMap::iterator ProgramProcessorIterator; - typedef ProgramProcessorMap::const_iterator ProgramProcessorConstIterator; - typedef vector::type ProgramProcessorList; - - + //----------------------------------------------------------------------------- + typedef map::type GpuProgramsMap; + typedef map::type ProgramSourceToNameMap; + typedef GpuProgramsMap::iterator GpuProgramsMapIterator; + typedef GpuProgramsMap::const_iterator GpuProgramsMapConstIterator; + + //----------------------------------------------------------------------------- + typedef set::type ProgramList; + typedef ProgramList::iterator ProgramListIterator; + typedef map::type ProgramWriterMap; + typedef ProgramWriterMap::iterator ProgramWriterIterator; + typedef vector::type ProgramWriterFactoryList; + + //----------------------------------------------------------------------------- + typedef map::type ProgramProcessorMap; + typedef ProgramProcessorMap::iterator ProgramProcessorIterator; + typedef ProgramProcessorMap::const_iterator ProgramProcessorConstIterator; + typedef vector::type ProgramProcessorList; + + protected: - /** Create default program processors. */ - void createDefaultProgramProcessors(); - - /** Destroy default program processors. */ - void destroyDefaultProgramProcessors(); - - /** Create default program processors. */ - void createDefaultProgramWriterFactories(); - - /** Destroy default program processors. */ - void destroyDefaultProgramWriterFactories(); - - /** Destroy all program writers. */ - void destroyProgramWriters(); - - /** Create CPU program . - @param type The type of the program to create. - */ - Program* createCpuProgram(GpuProgramType type); - - /** Destroy a CPU program by name. - @param shaderProgram The CPU program instance to destroy. - */ - void destroyCpuProgram(Program* shaderProgram); - - /** Create GPU programs for the given program set based on the CPU programs it contains. - @param programSet The program set container. - */ - bool createGpuPrograms(ProgramSet* programSet); - - /** - Generates a unique guid value from a string - @param programString string to generate a hash value for - @return A string representing a 128 bit hash value of the original string - */ - String generateGUID(const String& programString); - - /** Create GPU program based on the give CPU program. - @param shaderProgram The CPU program instance. - @param programWriter The program writer instance. - @param language The target shader language. - @param profiles The profiles string for program compilation. - @param profilesList The profiles string for program compilation as string list. - @param cachePath The output path to write the program into. - */ - GpuProgramPtr createGpuProgram(Program* shaderProgram, - ProgramWriter* programWriter, - const String& language, - const String& profiles, - const StringVector& profilesList, - const String& cachePath); - - /** - Add program processor instance to this manager. - @param processor The instance to add. - */ - void addProgramProcessor(ProgramProcessor* processor); - - /** - Remove program processor instance from this manager. - @param processor The instance to remove. - */ - void removeProgramProcessor(ProgramProcessor* processor); - - /** Destroy a GPU program by name. - @param gpuProgram The program to destroy. - */ - void destroyGpuProgram(GpuProgramPtr& gpuProgram); - - /** Flush the local GPU programs cache. - @param gpuProgramsMap The GPU programs cache. - */ - void flushGpuProgramsCache(GpuProgramsMap& gpuProgramsMap); - - /** Return the number of created vertex shaders. */ - size_t getVertexShaderCount() const { return mVertexShaderMap.size(); } - - /** Return the number of created fragment shaders. */ - size_t getFragmentShaderCount() const { return mFragmentShaderMap.size(); } - - /** Fix the input of the pixel shader to be the same as the output of the vertex shader */ - void synchronizePixelnToBeVertexOut(ProgramSet* programSet); - - /** Bind the uniform parameters of a given CPU and GPU program set. */ - void bindUniformParameters(Program* pCpuProgram, const GpuProgramParametersSharedPtr& passParams); + /** Create default program processors. */ + void createDefaultProgramProcessors(); + + /** Destroy default program processors. */ + void destroyDefaultProgramProcessors(); + + /** Create default program processors. */ + void createDefaultProgramWriterFactories(); + + /** Destroy default program processors. */ + void destroyDefaultProgramWriterFactories(); + + /** Destroy all program writers. */ + void destroyProgramWriters(); + + /** Create CPU program . + @param type The type of the program to create. + */ + Program* createCpuProgram(GpuProgramType type); + + /** Destroy a CPU program by name. + @param shaderProgram The CPU program instance to destroy. + */ + void destroyCpuProgram(Program* shaderProgram); + + /** Create GPU programs for the given program set based on the CPU programs it contains. + @param programSet The program set container. + */ + bool createGpuPrograms(ProgramSet* programSet); + + /** + Generates a unique guid value from a string + @param programString string to generate a hash value for + @return A string representing a 128 bit hash value of the original string + */ + String generateGUID(const String& programString); + + /** Create GPU program based on the give CPU program. + @param shaderProgram The CPU program instance. + @param programWriter The program writer instance. + @param language The target shader language. + @param profiles The profiles string for program compilation. + @param profilesList The profiles string for program compilation as string list. + @param cachePath The output path to write the program into. + */ + GpuProgramPtr createGpuProgram(Program* shaderProgram, + ProgramWriter* programWriter, + const String& language, + const String& profiles, + const StringVector& profilesList, + const String& cachePath); + + /** + Add program processor instance to this manager. + @param processor The instance to add. + */ + void addProgramProcessor(ProgramProcessor* processor); + + /** + Remove program processor instance from this manager. + @param processor The instance to remove. + */ + void removeProgramProcessor(ProgramProcessor* processor); + + /** Destroy a GPU program by name. + @param gpuProgram The program to destroy. + */ + void destroyGpuProgram(GpuProgramPtr& gpuProgram); + + /** Flush the local GPU programs cache. + @param gpuProgramsMap The GPU programs cache. + */ + void flushGpuProgramsCache(GpuProgramsMap& gpuProgramsMap); + + /** Return the number of created vertex shaders. */ + size_t getVertexShaderCount() const { return mVertexShaderMap.size(); } + + /** Return the number of created fragment shaders. */ + size_t getFragmentShaderCount() const { return mFragmentShaderMap.size(); } + + /** Fix the input of the pixel shader to be the same as the output of the vertex shader */ + void synchronizePixelnToBeVertexOut(ProgramSet* programSet); + + /** Bind the uniform parameters of a given CPU and GPU program set. */ + void bindUniformParameters(Program* pCpuProgram, const GpuProgramParametersSharedPtr& passParams); protected: - + protected: - // CPU programs list. - ProgramList mCpuProgramsList; - // Map between target language and shader program writer. - ProgramWriterMap mProgramWritersMap; - // Map between target language and shader program processor. - ProgramProcessorMap mProgramProcessorsMap; - // Holds standard shader writer factories - ProgramWriterFactoryList mProgramWriterFactories; - // The generated vertex shaders. - GpuProgramsMap mVertexShaderMap; - // The generated fragment shaders. - GpuProgramsMap mFragmentShaderMap; - // The default program processors. - ProgramProcessorList mDefaultProgramProcessors; + // CPU programs list. + ProgramList mCpuProgramsList; + // Map between target language and shader program writer. + ProgramWriterMap mProgramWritersMap; + // Map between target language and shader program processor. + ProgramProcessorMap mProgramProcessorsMap; + // Holds standard shader writer factories + ProgramWriterFactoryList mProgramWriterFactories; + // The generated vertex shaders. + GpuProgramsMap mVertexShaderMap; + // The generated fragment shaders. + GpuProgramsMap mFragmentShaderMap; + // The default program processors. + ProgramProcessorList mDefaultProgramProcessors; // map the source code of the shaders to a name for them ProgramSourceToNameMap mProgramSourceToNameMap; private: - friend class ProgramSet; - friend class TargetRenderState; - friend class ShaderGenerator; + friend class ProgramSet; + friend class TargetRenderState; + friend class ShaderGenerator; }; /** @} */ diff --git a/Components/RTShaderSystem/include/OgreShaderProgramProcessor.h b/Components/RTShaderSystem/include/OgreShaderProgramProcessor.h index 2fa0081da8e..12f4502f2b1 100644 --- a/Components/RTShaderSystem/include/OgreShaderProgramProcessor.h +++ b/Components/RTShaderSystem/include/OgreShaderProgramProcessor.h @@ -49,217 +49,217 @@ class _OgreRTSSExport ProgramProcessor : public RTShaderSystemAlloc { // Interface. -public: - - /** Class constructor. - */ - ProgramProcessor(); - - /** Class destructor */ - virtual ~ProgramProcessor(); - - /** Return the target language of this processor. */ - virtual const String& getTargetLanguage() const = 0; - - /** Called before creation of the GPU programs. - Do several preparation operation such as validation, register compaction and specific target language optimizations. - @param programSet The program set container. - Return true on success. - */ - virtual bool preCreateGpuPrograms(ProgramSet* programSet) = 0; - - /** Called after creation of the GPU programs. - @param programSet The program set container. - Return true on success. - */ - virtual bool postCreateGpuPrograms(ProgramSet* programSet) = 0; +public: + + /** Class constructor. + */ + ProgramProcessor(); + + /** Class destructor */ + virtual ~ProgramProcessor(); + + /** Return the target language of this processor. */ + virtual const String& getTargetLanguage() const = 0; + + /** Called before creation of the GPU programs. + Do several preparation operation such as validation, register compaction and specific target language optimizations. + @param programSet The program set container. + Return true on success. + */ + virtual bool preCreateGpuPrograms(ProgramSet* programSet) = 0; + + /** Called after creation of the GPU programs. + @param programSet The program set container. + Return true on success. + */ + virtual bool postCreateGpuPrograms(ProgramSet* programSet) = 0; // Protected types. protected: - - //----------------------------------------------------------------------------- - // Class that holds merge parameter information. - class _OgreRTSSExport MergeParameter - { - // Interface. - public: - /** Class constructor. */ - MergeParameter(); - - - /** Clear the state of this merge parameter. */ - void clear(); - - /** Add source parameter to this merged */ - void addSourceParameter(ParameterPtr srcParam, int mask); - - /** Return the source parameter count. */ - size_t getSourceParameterCount() const { return mSrcParameterCount; } - - /** Return source parameter by index. */ - ParameterPtr getSourceParameter(unsigned int index) { return mSrcParameter[index]; } - - /** Return source parameter mask by index. */ - int getSourceParameterMask(unsigned int index) const { return mSrcParameterMask[index]; } - - /** Return destination parameter mask by index. */ - int getDestinationParameterMask(unsigned int index) const { return mDstParameterMask[index]; } - - /** Return the number of used floats. */ - int getUsedFloatCount(); - - /** Return the destination parameter. */ - ParameterPtr getDestinationParameter(int usage, int index); - - protected: - - /** Creates the destination parameter by a given class and index. */ - void createDestinationParameter(int usage, int index); - - - protected: - // Destination merged parameter. - ParameterPtr mDstParameter; - // Source parameters - 4 source at max 1,1,1,1 -> 4. - ParameterPtr mSrcParameter[4]; - // Source parameters mask. OPM_ALL means all fields used, otherwise it is split source parameter. - int mSrcParameterMask[4]; - // Destination parameters mask. OPM_ALL means all fields used, otherwise it is split source parameter. - int mDstParameterMask[4]; - // The actual source parameters count. - size_t mSrcParameterCount; - // The number of used floats. - int mUsedFloatCount; - }; - typedef vector::type MergeParameterList; - - - //----------------------------------------------------------------------------- - // A struct that defines merge parameters combination. - struct _OgreRTSSExport MergeCombination - { - // The count of each source type. I.E (1 FLOAT1, 0 FLOAT2, 1 FLOAT3, 0 FLOAT4). - size_t srcParameterTypeCount[4]; - // Source parameters mask. OPM_ALL means all fields used, otherwise it is split source parameter. - int srcParameterMask[4]; - - MergeCombination( - int float1Count, int float1Mask, - int float2Count, int float2Mask, - int float3Count, int float3Mask, - int float4Count, int float4Mask) - { - srcParameterTypeCount[0] = float1Count; - srcParameterTypeCount[1] = float2Count; - srcParameterTypeCount[2] = float3Count; - srcParameterTypeCount[3] = float4Count; - srcParameterMask[0] = float1Mask; - srcParameterMask[1] = float2Mask; - srcParameterMask[2] = float3Mask; - srcParameterMask[3] = float4Mask; - - } - }; - typedef vector::type MergeCombinationList; - - //----------------------------------------------------------------------------- - typedef vector::type OperandPtrVector; - typedef map::type ParameterOperandMap; - typedef map::type LocalParameterMap; + + //----------------------------------------------------------------------------- + // Class that holds merge parameter information. + class _OgreRTSSExport MergeParameter + { + // Interface. + public: + /** Class constructor. */ + MergeParameter(); + + + /** Clear the state of this merge parameter. */ + void clear(); + + /** Add source parameter to this merged */ + void addSourceParameter(ParameterPtr srcParam, int mask); + + /** Return the source parameter count. */ + size_t getSourceParameterCount() const { return mSrcParameterCount; } + + /** Return source parameter by index. */ + ParameterPtr getSourceParameter(unsigned int index) { return mSrcParameter[index]; } + + /** Return source parameter mask by index. */ + int getSourceParameterMask(unsigned int index) const { return mSrcParameterMask[index]; } + + /** Return destination parameter mask by index. */ + int getDestinationParameterMask(unsigned int index) const { return mDstParameterMask[index]; } + + /** Return the number of used floats. */ + int getUsedFloatCount(); + + /** Return the destination parameter. */ + ParameterPtr getDestinationParameter(int usage, int index); + + protected: + + /** Creates the destination parameter by a given class and index. */ + void createDestinationParameter(int usage, int index); + + + protected: + // Destination merged parameter. + ParameterPtr mDstParameter; + // Source parameters - 4 source at max 1,1,1,1 -> 4. + ParameterPtr mSrcParameter[4]; + // Source parameters mask. OPM_ALL means all fields used, otherwise it is split source parameter. + int mSrcParameterMask[4]; + // Destination parameters mask. OPM_ALL means all fields used, otherwise it is split source parameter. + int mDstParameterMask[4]; + // The actual source parameters count. + size_t mSrcParameterCount; + // The number of used floats. + int mUsedFloatCount; + }; + typedef vector::type MergeParameterList; + + + //----------------------------------------------------------------------------- + // A struct that defines merge parameters combination. + struct _OgreRTSSExport MergeCombination + { + // The count of each source type. I.E (1 FLOAT1, 0 FLOAT2, 1 FLOAT3, 0 FLOAT4). + size_t srcParameterTypeCount[4]; + // Source parameters mask. OPM_ALL means all fields used, otherwise it is split source parameter. + int srcParameterMask[4]; + + MergeCombination( + int float1Count, int float1Mask, + int float2Count, int float2Mask, + int float3Count, int float3Mask, + int float4Count, int float4Mask) + { + srcParameterTypeCount[0] = float1Count; + srcParameterTypeCount[1] = float2Count; + srcParameterTypeCount[2] = float3Count; + srcParameterTypeCount[3] = float4Count; + srcParameterMask[0] = float1Mask; + srcParameterMask[1] = float2Mask; + srcParameterMask[2] = float3Mask; + srcParameterMask[3] = float4Mask; + + } + }; + typedef vector::type MergeCombinationList; + + //----------------------------------------------------------------------------- + typedef vector::type OperandPtrVector; + typedef map::type ParameterOperandMap; + typedef map::type LocalParameterMap; protected: - /** Build parameter merging combinations. */ - void buildMergeCombinations(); - - /** Compact the vertex shader output registers. - @param vsMain The vertex shader entry function. - @param fsMain The fragment shader entry function. - Return true on success. - */ - virtual bool compactVsOutputs(Function* vsMain, Function* fsMain); - - /** Internal method that counts vertex shader texcoord output slots and output floats. - @param vsMain The vertex shader entry function. - @param outTexCoordSlots Will hold the number of used output texcoord slots. - @param outTexCoordFloats Will hold the total number of floats used by output texcoord slots. - */ - void countVsTexcoordOutputs(Function* vsMain, int& outTexCoordSlots, int& outTexCoordFloats); - - /** Internal function that builds parameters table. - @param paramList The parameter list. - @param outParamsTable Will hold the texcoord params sorted by types in each row. - */ - void buildTexcoordTable(const ShaderParameterList& paramList, ShaderParameterList outParamsTable[4]); - - - /** Merge the parameters from the given table. - @param paramsTable Source parameters table. - @param mergedParams Will hold the merged parameters list. - */ - void mergeParameters(ShaderParameterList paramsTable[4], MergeParameterList& mergedParams, ShaderParameterList& splitParams); - - - /** Internal function that creates merged parameter using pre defined combinations. - @param paramsTable Source parameters table. - @param mergedParams The merged parameters list. - */ - void mergeParametersByPredefinedCombinations(ShaderParameterList paramsTable[4], MergeParameterList& mergedParams); - - /** Internal function that creates merged parameter from given combination. - @param combination The merge combination to try. - @param paramsTable The params table sorted by types in each row. - @param mergedParameter Will hold the merged parameter. - */ - bool mergeParametersByCombination(const MergeCombination& combination, ShaderParameterList paramsTable[4], - MergeParameter* mergedParameter); - - /** Merge reminders parameters that could not be merged into one slot using the predefined combinations. - @param paramsTable The params table sorted by types in each row. - @param mergedParams The merged parameters list. - @param splitParams The split parameters list. - */ - void mergeParametersReminders(ShaderParameterList paramsTable[4], MergeParameterList& mergedParams, ShaderParameterList& splitParams); - - - /** Generates local parameters for the split parameters and perform packing/unpacking operation using them. */ - void generateLocalSplitParameters(Function* func, GpuProgramType progType, MergeParameterList& mergedParams, ShaderParameterList& splitParams, LocalParameterMap& localParamsMap); - - /** Rebuild the given parameters list using the merged parameters. - */ - void rebuildParameterList(Function* func, int paramsUsage, MergeParameterList& mergedParams); - - /** Rebuild function invocations by replacing references to old source parameters with the matching merged parameters components. */ - void rebuildFunctionInvocations(FunctionAtomInstanceList& funcAtomList, MergeParameterList& mergedParams, LocalParameterMap& localParamsMap); - - /** Builds a map between parameter and all the references to it. */ - void buildParameterReferenceMap(FunctionAtomInstanceList& funcAtomList, ParameterOperandMap& paramsRefMap); - - /** Replace references to old parameters with the new merged parameters. */ - void replaceParametersReferences(MergeParameterList& mergedParams, ParameterOperandMap& paramsRefMap); - - /** Replace references to old parameters that have been split with the new local parameters that represents them. */ - void replaceSplitParametersReferences(LocalParameterMap& localParamsMap, ParameterOperandMap& paramsRefMap); - - /** Return number of floats needed by the given type. */ - static int getParameterFloatCount(GpuConstantType type); - - /** Return the parameter mask of by the given parameter type (I.E: X|Y for FLOAT2 etc..) */ - static int getParameterMaskByType(GpuConstantType type); - - /** Return the parameter mask of by the float count type (I.E: X|Y for 2 etc..) */ - static int getParameterMaskByFloatCount(int floatCount); - - /** Bind the auto parameters for a given CPU and GPU program set. */ - void bindAutoParameters(Program* pCpuProgram, GpuProgramPtr pGpuProgram); + /** Build parameter merging combinations. */ + void buildMergeCombinations(); + + /** Compact the vertex shader output registers. + @param vsMain The vertex shader entry function. + @param fsMain The fragment shader entry function. + Return true on success. + */ + virtual bool compactVsOutputs(Function* vsMain, Function* fsMain); + + /** Internal method that counts vertex shader texcoord output slots and output floats. + @param vsMain The vertex shader entry function. + @param outTexCoordSlots Will hold the number of used output texcoord slots. + @param outTexCoordFloats Will hold the total number of floats used by output texcoord slots. + */ + void countVsTexcoordOutputs(Function* vsMain, int& outTexCoordSlots, int& outTexCoordFloats); + + /** Internal function that builds parameters table. + @param paramList The parameter list. + @param outParamsTable Will hold the texcoord params sorted by types in each row. + */ + void buildTexcoordTable(const ShaderParameterList& paramList, ShaderParameterList outParamsTable[4]); + + + /** Merge the parameters from the given table. + @param paramsTable Source parameters table. + @param mergedParams Will hold the merged parameters list. + */ + void mergeParameters(ShaderParameterList paramsTable[4], MergeParameterList& mergedParams, ShaderParameterList& splitParams); + + + /** Internal function that creates merged parameter using pre defined combinations. + @param paramsTable Source parameters table. + @param mergedParams The merged parameters list. + */ + void mergeParametersByPredefinedCombinations(ShaderParameterList paramsTable[4], MergeParameterList& mergedParams); + + /** Internal function that creates merged parameter from given combination. + @param combination The merge combination to try. + @param paramsTable The params table sorted by types in each row. + @param mergedParameter Will hold the merged parameter. + */ + bool mergeParametersByCombination(const MergeCombination& combination, ShaderParameterList paramsTable[4], + MergeParameter* mergedParameter); + + /** Merge reminders parameters that could not be merged into one slot using the predefined combinations. + @param paramsTable The params table sorted by types in each row. + @param mergedParams The merged parameters list. + @param splitParams The split parameters list. + */ + void mergeParametersReminders(ShaderParameterList paramsTable[4], MergeParameterList& mergedParams, ShaderParameterList& splitParams); + + + /** Generates local parameters for the split parameters and perform packing/unpacking operation using them. */ + void generateLocalSplitParameters(Function* func, GpuProgramType progType, MergeParameterList& mergedParams, ShaderParameterList& splitParams, LocalParameterMap& localParamsMap); + + /** Rebuild the given parameters list using the merged parameters. + */ + void rebuildParameterList(Function* func, int paramsUsage, MergeParameterList& mergedParams); + + /** Rebuild function invocations by replacing references to old source parameters with the matching merged parameters components. */ + void rebuildFunctionInvocations(FunctionAtomInstanceList& funcAtomList, MergeParameterList& mergedParams, LocalParameterMap& localParamsMap); + + /** Builds a map between parameter and all the references to it. */ + void buildParameterReferenceMap(FunctionAtomInstanceList& funcAtomList, ParameterOperandMap& paramsRefMap); + + /** Replace references to old parameters with the new merged parameters. */ + void replaceParametersReferences(MergeParameterList& mergedParams, ParameterOperandMap& paramsRefMap); + + /** Replace references to old parameters that have been split with the new local parameters that represents them. */ + void replaceSplitParametersReferences(LocalParameterMap& localParamsMap, ParameterOperandMap& paramsRefMap); + + /** Return number of floats needed by the given type. */ + static int getParameterFloatCount(GpuConstantType type); + + /** Return the parameter mask of by the given parameter type (I.E: X|Y for FLOAT2 etc..) */ + static int getParameterMaskByType(GpuConstantType type); + + /** Return the parameter mask of by the float count type (I.E: X|Y for 2 etc..) */ + static int getParameterMaskByFloatCount(int floatCount); + + /** Bind the auto parameters for a given CPU and GPU program set. */ + void bindAutoParameters(Program* pCpuProgram, GpuProgramPtr pGpuProgram); protected: - // Merging combinations defs. - MergeCombinationList mParamMergeCombinations; - // Maximum texcoord slots. - int mMaxTexCoordSlots; - // Maximum texcoord floats count. - int mMaxTexCoordFloats; + // Merging combinations defs. + MergeCombinationList mParamMergeCombinations; + // Maximum texcoord slots. + int mMaxTexCoordSlots; + // Maximum texcoord floats count. + int mMaxTexCoordFloats; map::type mFunctionMap; // Map between function signatures and source code }; diff --git a/Components/RTShaderSystem/include/OgreShaderProgramSet.h b/Components/RTShaderSystem/include/OgreShaderProgramSet.h index 1302f466627..b5e599bc1d7 100644 --- a/Components/RTShaderSystem/include/OgreShaderProgramSet.h +++ b/Components/RTShaderSystem/include/OgreShaderProgramSet.h @@ -46,49 +46,49 @@ Holds both a CPU representation and GPU representation of vertex and fragment pr class _OgreRTSSExport ProgramSet : public RTShaderSystemAlloc { - // Interface. + // Interface. public: - /** Class default constructor */ - ProgramSet(); + /** Class default constructor */ + ProgramSet(); - /** Class destructor */ - ~ProgramSet(); + /** Class destructor */ + ~ProgramSet(); - /** Get the vertex shader CPU program. */ - Program* getCpuVertexProgram(); + /** Get the vertex shader CPU program. */ + Program* getCpuVertexProgram(); - /** Get the fragment shader CPU program. */ - Program* getCpuFragmentProgram(); + /** Get the fragment shader CPU program. */ + Program* getCpuFragmentProgram(); - /** Get the vertex shader GPU program. */ - GpuProgramPtr getGpuVertexProgram(); + /** Get the vertex shader GPU program. */ + GpuProgramPtr getGpuVertexProgram(); - /** Get the fragment shader GPU program. */ - GpuProgramPtr getGpuFragmentProgram(); + /** Get the fragment shader GPU program. */ + GpuProgramPtr getGpuFragmentProgram(); - // Protected methods. + // Protected methods. protected: - void setCpuVertexProgram(Program* vsCpuProgram); - void setCpuFragmentProgram(Program* psCpuProgram); + void setCpuVertexProgram(Program* vsCpuProgram); + void setCpuFragmentProgram(Program* psCpuProgram); - void setGpuVertexProgram(GpuProgramPtr vsGpuProgram); - void setGpuFragmentProgram(GpuProgramPtr psGpuProgram); + void setGpuVertexProgram(GpuProgramPtr vsGpuProgram); + void setGpuFragmentProgram(GpuProgramPtr psGpuProgram); - // Attributes. + // Attributes. protected: - // Vertex shader CPU program. - Program* mVSCpuProgram; - // Fragment shader CPU program. - Program* mPSCpuProgram; - // Vertex shader GPU program. - GpuProgramPtr mVSGpuProgram; - // Fragment shader CPU program. - GpuProgramPtr mPSGpuProgram; + // Vertex shader CPU program. + Program* mVSCpuProgram; + // Fragment shader CPU program. + Program* mPSCpuProgram; + // Vertex shader GPU program. + GpuProgramPtr mVSGpuProgram; + // Fragment shader CPU program. + GpuProgramPtr mPSGpuProgram; private: - friend class ProgramManager; - friend class TargetRenderState; + friend class ProgramManager; + friend class TargetRenderState; }; diff --git a/Components/RTShaderSystem/include/OgreShaderProgramWriter.h b/Components/RTShaderSystem/include/OgreShaderProgramWriter.h index 5e2e65c274c..4a099b999a7 100644 --- a/Components/RTShaderSystem/include/OgreShaderProgramWriter.h +++ b/Components/RTShaderSystem/include/OgreShaderProgramWriter.h @@ -62,29 +62,29 @@ class _OgreRTSSExport ProgramWriter : public RTShaderSystemAlloc // Interface. public: - /** Class destructor */ - virtual ~ProgramWriter () {} + /** Class destructor */ + virtual ~ProgramWriter () {} - /** Write the program shader source code. - @param os The output stream to write to code into. - @param program The source CPU program for the GPU program code. - */ - virtual void writeSourceCode (std::ostream& os, Program* program) = 0; + /** Write the program shader source code. + @param os The output stream to write to code into. + @param program The source CPU program for the GPU program code. + */ + virtual void writeSourceCode (std::ostream& os, Program* program) = 0; - /** Return the target language of this writer. */ - virtual const String& getTargetLanguage () const = 0; + /** Return the target language of this writer. */ + virtual const String& getTargetLanguage () const = 0; // Protected methods. protected: - /** Write the program title. */ - void writeProgramTitle (std::ostream& os, Program* program); + /** Write the program title. */ + void writeProgramTitle (std::ostream& os, Program* program); - /** Write the uniform parameters title. */ - void writeUniformParametersTitle (std::ostream& os, Program* program); + /** Write the uniform parameters title. */ + void writeUniformParametersTitle (std::ostream& os, Program* program); - /** Write a function title. */ - void writeFunctionTitle (std::ostream& os, Function* function); + /** Write a function title. */ + void writeFunctionTitle (std::ostream& os, Function* function); }; /** @} */ diff --git a/Components/RTShaderSystem/include/OgreShaderProgramWriterManager.h b/Components/RTShaderSystem/include/OgreShaderProgramWriterManager.h index 724b7d4289d..844313c8c3f 100644 --- a/Components/RTShaderSystem/include/OgreShaderProgramWriterManager.h +++ b/Components/RTShaderSystem/include/OgreShaderProgramWriterManager.h @@ -47,80 +47,80 @@ namespace RTShader { class _OgreRTSSExport ProgramWriterFactory : public RTShaderSystemAlloc { public: - ProgramWriterFactory() {} - virtual ~ProgramWriterFactory() {} - - /// Get the name of the language this factory creates programs for - virtual const String& getTargetLanguage(void) const = 0; - - /// Create writer instance - virtual ProgramWriter* create(void) = 0; + ProgramWriterFactory() {} + virtual ~ProgramWriterFactory() {} + + /// Get the name of the language this factory creates programs for + virtual const String& getTargetLanguage(void) const = 0; + + /// Create writer instance + virtual ProgramWriter* create(void) = 0; }; class _OgreRTSSExport ProgramWriterManager - : public Singleton, public RTShaderSystemAlloc + : public Singleton, public RTShaderSystemAlloc { public: - typedef map::type FactoryMap; + typedef map::type FactoryMap; protected: - /// Factories capable of creating ShaderProgramWriterFactory instances - FactoryMap mFactories; + /// Factories capable of creating ShaderProgramWriterFactory instances + FactoryMap mFactories; public: - ProgramWriterManager(); - ~ProgramWriterManager(); - - /** Add a new factory object for high-level programs of a given language. */ - void addFactory(ProgramWriterFactory* factory); - - /** Remove a factory object for high-level programs of a given language. */ - void removeFactory(ProgramWriterFactory* factory); - - /** Returns whether a given high-level language is supported. */ - bool isLanguageSupported(const String& lang); - - /** Create a new, unloaded HighLevelGpuProgram. - @par - This method creates a new program of the type specified as the second and third parameters. - You will have to call further methods on the returned program in order to - define the program fully before you can load it. - @param language Code of the language to use (e.g. "cg") - */ - ProgramWriter* createProgramWriter( const String& language); - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static ProgramWriterManager& getSingleton(); - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static ProgramWriterManager* getSingletonPtr(); + ProgramWriterManager(); + ~ProgramWriterManager(); + + /** Add a new factory object for high-level programs of a given language. */ + void addFactory(ProgramWriterFactory* factory); + + /** Remove a factory object for high-level programs of a given language. */ + void removeFactory(ProgramWriterFactory* factory); + + /** Returns whether a given high-level language is supported. */ + bool isLanguageSupported(const String& lang); + + /** Create a new, unloaded HighLevelGpuProgram. + @par + This method creates a new program of the type specified as the second and third parameters. + You will have to call further methods on the returned program in order to + define the program fully before you can load it. + @param language Code of the language to use (e.g. "cg") + */ + ProgramWriter* createProgramWriter( const String& language); + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static ProgramWriterManager& getSingleton(); + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static ProgramWriterManager* getSingletonPtr(); }; /** @} */ /** @} */ diff --git a/Components/RTShaderSystem/include/OgreShaderRenderState.h b/Components/RTShaderSystem/include/OgreShaderRenderState.h index 66a5dda16f2..568a0d1748b 100644 --- a/Components/RTShaderSystem/include/OgreShaderRenderState.h +++ b/Components/RTShaderSystem/include/OgreShaderRenderState.h @@ -49,86 +49,86 @@ perform a per pixel lighting model, get the render state of the target material class _OgreRTSSExport RenderState : public RTShaderSystemAlloc { - // Interface. + // Interface. public: - /** Class default constructor. */ - RenderState(); - - /** Class destructor */ - virtual ~RenderState(); - - /** Reset this render state */ - void reset(); - - /** Add a template sub render state to this render state. - @param subRenderState The sub render state template to add. - */ - void addTemplateSubRenderState(SubRenderState* subRenderState); - - /** Remove a template sub render state from this render state. - @param subRenderState The sub render state to remove. - */ - void removeTemplateSubRenderState(SubRenderState* subRenderState); - - /** Get the list of the template sub render states composing this render state. */ - const SubRenderStateList& getTemplateSubRenderStateList() const { return mSubRenderStateList; } - - /** - Set the light count per light type. - @param - lightCount The light count per type. - lightCount[0] defines the point light count. - lightCount[1] defines the directional light count. - lightCount[2] defines the spot light count. - */ - void setLightCount(const int lightCount[3]); - - /** - Get the light count per light type. - @param - lightCount The light count per type. - lightCount[0] defines the point light count. - lightCount[1] defines the directional light count. - lightCount[2] defines the spot light count. - */ - void getLightCount(int lightCount[3]) const; - - /** - Set the light count auto update state. - If the value is false the light count will remain static for the values that were set by the user. - If the value is true the light count will be updated from the owner shader generator scheme based on current scene lights. - The default is true. - */ - void setLightCountAutoUpdate(bool autoUpdate) { mLightCountAutoUpdate = autoUpdate; } - - /** - Return true if this render state override the light count. - If light count is not overridden it will be updated from the shader generator based on current scene lights. - */ - bool getLightCountAutoUpdate() const { return mLightCountAutoUpdate; } - - - - - // Attributes. + /** Class default constructor. */ + RenderState(); + + /** Class destructor */ + virtual ~RenderState(); + + /** Reset this render state */ + void reset(); + + /** Add a template sub render state to this render state. + @param subRenderState The sub render state template to add. + */ + void addTemplateSubRenderState(SubRenderState* subRenderState); + + /** Remove a template sub render state from this render state. + @param subRenderState The sub render state to remove. + */ + void removeTemplateSubRenderState(SubRenderState* subRenderState); + + /** Get the list of the template sub render states composing this render state. */ + const SubRenderStateList& getTemplateSubRenderStateList() const { return mSubRenderStateList; } + + /** + Set the light count per light type. + @param + lightCount The light count per type. + lightCount[0] defines the point light count. + lightCount[1] defines the directional light count. + lightCount[2] defines the spot light count. + */ + void setLightCount(const int lightCount[3]); + + /** + Get the light count per light type. + @param + lightCount The light count per type. + lightCount[0] defines the point light count. + lightCount[1] defines the directional light count. + lightCount[2] defines the spot light count. + */ + void getLightCount(int lightCount[3]) const; + + /** + Set the light count auto update state. + If the value is false the light count will remain static for the values that were set by the user. + If the value is true the light count will be updated from the owner shader generator scheme based on current scene lights. + The default is true. + */ + void setLightCountAutoUpdate(bool autoUpdate) { mLightCountAutoUpdate = autoUpdate; } + + /** + Return true if this render state override the light count. + If light count is not overridden it will be updated from the shader generator based on current scene lights. + */ + bool getLightCountAutoUpdate() const { return mLightCountAutoUpdate; } + + + + + // Attributes. protected: - // The sub render states list. - SubRenderStateList mSubRenderStateList; - // The light count per light type definition. - int mLightCount[3]; - // True if light count was explicitly set. - bool mLightCountAutoUpdate; + // The sub render states list. + SubRenderStateList mSubRenderStateList; + // The light count per light type definition. + int mLightCount[3]; + // True if light count was explicitly set. + bool mLightCountAutoUpdate; private: - friend class ProgramManager; - friend class FFPRenderStateBuilder; + friend class ProgramManager; + friend class FFPRenderStateBuilder; }; -typedef vector::type RenderStateList; -typedef RenderStateList::iterator RenderStateIterator; -typedef RenderStateList::const_iterator RenderStateConstIterator; +typedef vector::type RenderStateList; +typedef RenderStateList::iterator RenderStateIterator; +typedef RenderStateList::const_iterator RenderStateConstIterator; /** This is the target render state. This class will hold the actual generated CPU/GPU programs. @@ -140,72 +140,72 @@ class TargetRenderState : public RenderState // Interface. public: - - /** Class default constructor. */ - TargetRenderState(); - - /** Class destructor */ - virtual ~TargetRenderState(); - - /** Link this target render state with the given render state. - Only sub render states with execution order that don't exist in this render state will be added. - @param other The other render state to append to this state. - @param srcPass The source pass that this render state is constructed from. - @param dstPass The destination pass that constructed from this render state. - */ - void link(const RenderState& other, Pass* srcPass, Pass* dstPass); - - /** Update the GPU programs constant parameters before a renderable is rendered. - @param rend The renderable object that is going to be rendered. - @param pass The pass that is used to do the rendering operation. - @param source The auto parameter auto source instance. - @param pLightList The light list used for the current rendering operation. - */ - void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - + + /** Class default constructor. */ + TargetRenderState(); + + /** Class destructor */ + virtual ~TargetRenderState(); + + /** Link this target render state with the given render state. + Only sub render states with execution order that don't exist in this render state will be added. + @param other The other render state to append to this state. + @param srcPass The source pass that this render state is constructed from. + @param dstPass The destination pass that constructed from this render state. + */ + void link(const RenderState& other, Pass* srcPass, Pass* dstPass); + + /** Update the GPU programs constant parameters before a renderable is rendered. + @param rend The renderable object that is going to be rendered. + @param pass The pass that is used to do the rendering operation. + @param source The auto parameter auto source instance. + @param pLightList The light list used for the current rendering operation. + */ + void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + // Protected methods protected: - /** Sort the sub render states composing this render state. */ - void sortSubRenderStates(); - - /** Create CPU programs that represent this render state. - */ - bool createCpuPrograms(); + /** Sort the sub render states composing this render state. */ + void sortSubRenderStates(); + + /** Create CPU programs that represent this render state. + */ + bool createCpuPrograms(); - /** Create the program set of this render state. - */ - ProgramSet* createProgramSet(); + /** Create the program set of this render state. + */ + ProgramSet* createProgramSet(); - /* Destroy the program set of this render state. */ - void destroyProgramSet(); + /* Destroy the program set of this render state. */ + void destroyProgramSet(); - /** Return the program set of this render state. - */ - ProgramSet* getProgramSet() { return mProgramSet; } + /** Return the program set of this render state. + */ + ProgramSet* getProgramSet() { return mProgramSet; } - /** Add sub render state to this render state. - @param subRenderState The sub render state to add. - */ - void addSubRenderStateInstance(SubRenderState* subRenderState); + /** Add sub render state to this render state. + @param subRenderState The sub render state to add. + */ + void addSubRenderStateInstance(SubRenderState* subRenderState); - /** Remove sub render state from this render state. - @param subRenderState The sub render state to remove. - */ - void removeSubRenderStateInstance(SubRenderState* subRenderState); + /** Remove sub render state from this render state. + @param subRenderState The sub render state to remove. + */ + void removeSubRenderStateInstance(SubRenderState* subRenderState); - + // Attributes. protected: - // Tells if the list of the sub render states is sorted. - bool mSubRenderStateSortValid; - // The program set of this RenderState. - ProgramSet* mProgramSet; - + // Tells if the list of the sub render states is sorted. + bool mSubRenderStateSortValid; + // The program set of this RenderState. + ProgramSet* mProgramSet; + private: - friend class ProgramManager; - friend class FFPRenderStateBuilder; + friend class ProgramManager; + friend class FFPRenderStateBuilder; }; diff --git a/Components/RTShaderSystem/include/OgreShaderScriptTranslator.h b/Components/RTShaderSystem/include/OgreShaderScriptTranslator.h index eb933b5196c..38fa94e009b 100644 --- a/Components/RTShaderSystem/include/OgreShaderScriptTranslator.h +++ b/Components/RTShaderSystem/include/OgreShaderScriptTranslator.h @@ -47,95 +47,95 @@ Ogre material scripts. class _OgreRTSSExport SGScriptTranslator : public ScriptTranslator { public: - - SGScriptTranslator(); - - /** - *@see ScriptTranslator::translate. - */ - virtual void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - - /** - *@see ScriptTranslator::getBoolean. - */ - using ScriptTranslator::getBoolean; - - /** - *@see ScriptTranslator::getBoolean. - */ - using ScriptTranslator::getString; - - /** - *@see ScriptTranslator::getReal. - */ - using ScriptTranslator::getReal; - - /** - *@see ScriptTranslator::getFloat. - */ - using ScriptTranslator::getFloat; - - /** - *@see ScriptTranslator::getInt. - */ - using ScriptTranslator::getInt; - - /** - *@see ScriptTranslator::getUInt. - */ - using ScriptTranslator::getUInt; - - /** - *@see ScriptTranslator::getColour. - */ - using ScriptTranslator::getColour; - - /** - * Returns a sub render state of a given name which has already - * been created for material currently being generated by the - * script translator - * @note + + SGScriptTranslator(); + + /** + *@see ScriptTranslator::translate. + */ + virtual void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + + /** + *@see ScriptTranslator::getBoolean. + */ + using ScriptTranslator::getBoolean; + + /** + *@see ScriptTranslator::getBoolean. + */ + using ScriptTranslator::getString; + + /** + *@see ScriptTranslator::getReal. + */ + using ScriptTranslator::getReal; + + /** + *@see ScriptTranslator::getFloat. + */ + using ScriptTranslator::getFloat; + + /** + *@see ScriptTranslator::getInt. + */ + using ScriptTranslator::getInt; + + /** + *@see ScriptTranslator::getUInt. + */ + using ScriptTranslator::getUInt; + + /** + *@see ScriptTranslator::getColour. + */ + using ScriptTranslator::getColour; + + /** + * Returns a sub render state of a given name which has already + * been created for material currently being generated by the + * script translator + * @note * This function is meant to be used from within the createInstance - * function of sub-render state factories to avoid creating multiple - * sub-render state to the same material. - * - * @param typeName The type of the sub-render state to find. - */ - virtual SubRenderState* getGeneratedSubRenderState(const String& typeName); + * function of sub-render state factories to avoid creating multiple + * sub-render state to the same material. + * + * @param typeName The type of the sub-render state to find. + */ + virtual SubRenderState* getGeneratedSubRenderState(const String& typeName); protected: - /** - * Translates RT Shader System section within a pass context. - * @param compiler The compiler invoking this translator - * @param node The current AST node to be translated - */ - void translatePass(ScriptCompiler *compiler, const AbstractNodePtr &node); - - /** - * Translates RT Shader System section within a texture_unit context. - * @param compiler The compiler invoking this translator - * @param node The current AST node to be translated - */ - void translateTextureUnit(ScriptCompiler *compiler, const AbstractNodePtr &node); - - /** - * Adds a newly created subrender state to the material being translated - * @param newSubRenderState The sub-render state to add - * @param dstTechniqueSchemeName The technique which the sub render state is associated with - * @param materialName The material name which the sub render state is associated with - * @param groupName The material group name which the sub render state is associated with - * @param passIndex The index of the pass which the sub render state is associated with - */ - void addSubRenderState(SubRenderState* newSubRenderState, - const String& dstTechniqueSchemeName, const String& materialName, - const String& groupName, unsigned short passIndex); - - + /** + * Translates RT Shader System section within a pass context. + * @param compiler The compiler invoking this translator + * @param node The current AST node to be translated + */ + void translatePass(ScriptCompiler *compiler, const AbstractNodePtr &node); + + /** + * Translates RT Shader System section within a texture_unit context. + * @param compiler The compiler invoking this translator + * @param node The current AST node to be translated + */ + void translateTextureUnit(ScriptCompiler *compiler, const AbstractNodePtr &node); + + /** + * Adds a newly created subrender state to the material being translated + * @param newSubRenderState The sub-render state to add + * @param dstTechniqueSchemeName The technique which the sub render state is associated with + * @param materialName The material name which the sub render state is associated with + * @param groupName The material group name which the sub render state is associated with + * @param passIndex The index of the pass which the sub render state is associated with + */ + void addSubRenderState(SubRenderState* newSubRenderState, + const String& dstTechniqueSchemeName, const String& materialName, + const String& groupName, unsigned short passIndex); + + protected: - //Render state created as a result of the current node being parsed - RenderState* mGeneratedRenderState; + //Render state created as a result of the current node being parsed + RenderState* mGeneratedRenderState; }; diff --git a/Components/RTShaderSystem/include/OgreShaderSubRenderState.h b/Components/RTShaderSystem/include/OgreShaderSubRenderState.h index 2a18937c28b..54a82bd5283 100644 --- a/Components/RTShaderSystem/include/OgreShaderSubRenderState.h +++ b/Components/RTShaderSystem/include/OgreShaderSubRenderState.h @@ -40,7 +40,7 @@ namespace RTShader { * @{ */ -typedef SharedPtr SubRenderStateAccessorPtr; +typedef SharedPtr SubRenderStateAccessorPtr; /** This class is the base interface of sub part from a shader based rendering pipeline. @@ -54,113 +54,113 @@ class _OgreRTSSExport SubRenderState : public RTShaderSystemAlloc // Interface. public: - /** Class default constructor */ - SubRenderState(); - - /** Class destructor */ - virtual ~SubRenderState(); - - - /** Get the type of this sub render state. - @remarks - The type string should be unique among all registered sub render states. - */ - virtual const String& getType() const = 0; - - - /** Get the execution order of this sub render state. - @remarks - The return value should be synchronized with the predefined values - of the FFPShaderStage enum. - */ - virtual int getExecutionOrder() const = 0; - - - /** Copy details from a given sub render state to this one. - @param rhs the source sub state to copy from. - */ - virtual void copyFrom(const SubRenderState& rhs) = 0; - - /** Operator = declaration. Assign the given source sub state to this sub state. - @param rhs the source sub state to copy from. - */ - SubRenderState& operator= (const SubRenderState& rhs); - - /** Create sub programs that represents this sub render state as part of a program set. - The given program set contains CPU programs that represents a vertex shader and pixel shader. - One should use these program class API to create a representation of the sub state he wished to - implement. - @param programSet container class of CPU and GPU programs that this sub state will affect on. - */ - virtual bool createCpuSubPrograms(ProgramSet* programSet); - - /** Update GPU programs parameters before a rendering operation occurs. - This method is called in the context of SceneManager::renderSingle object via the RenderObjectListener interface and - lets this sub render state instance opportunity to update custom GPU program parameters before the rendering action occurs. - @see RenderObjectListener::notifyRenderSingleObject. - @param rend The renderable that is about to be rendered. - @param pass The pass that used for this rendering. - @param source The auto parameter source. - @param pLightList The light list used in the current rendering context. - */ - virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList) { } - - /** Called before adding this sub render state to the given render state. - Allows this sub render state class to configure specific parameters depending on source pass or parent render state. - Return of false value will cause canceling the add operation. - @param renderState The target render state container this sub render state is about to be added. - @param srcPass The source pass. - @param dstPass The destination pass. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { return true; } - - /** Return the accessor object to this sub render state. - @see SubRenderStateAccessor. - */ - SubRenderStateAccessorPtr getAccessor(); - - /** Return the accessor object to this sub render state. - @see SubRenderStateAccessor. - */ - SubRenderStateAccessorPtr getAccessor() const; + /** Class default constructor */ + SubRenderState(); + + /** Class destructor */ + virtual ~SubRenderState(); + + + /** Get the type of this sub render state. + @remarks + The type string should be unique among all registered sub render states. + */ + virtual const String& getType() const = 0; + + + /** Get the execution order of this sub render state. + @remarks + The return value should be synchronized with the predefined values + of the FFPShaderStage enum. + */ + virtual int getExecutionOrder() const = 0; + + + /** Copy details from a given sub render state to this one. + @param rhs the source sub state to copy from. + */ + virtual void copyFrom(const SubRenderState& rhs) = 0; + + /** Operator = declaration. Assign the given source sub state to this sub state. + @param rhs the source sub state to copy from. + */ + SubRenderState& operator= (const SubRenderState& rhs); + + /** Create sub programs that represents this sub render state as part of a program set. + The given program set contains CPU programs that represents a vertex shader and pixel shader. + One should use these program class API to create a representation of the sub state he wished to + implement. + @param programSet container class of CPU and GPU programs that this sub state will affect on. + */ + virtual bool createCpuSubPrograms(ProgramSet* programSet); + + /** Update GPU programs parameters before a rendering operation occurs. + This method is called in the context of SceneManager::renderSingle object via the RenderObjectListener interface and + lets this sub render state instance opportunity to update custom GPU program parameters before the rendering action occurs. + @see RenderObjectListener::notifyRenderSingleObject. + @param rend The renderable that is about to be rendered. + @param pass The pass that used for this rendering. + @param source The auto parameter source. + @param pLightList The light list used in the current rendering context. + */ + virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList) { } + + /** Called before adding this sub render state to the given render state. + Allows this sub render state class to configure specific parameters depending on source pass or parent render state. + Return of false value will cause canceling the add operation. + @param renderState The target render state container this sub render state is about to be added. + @param srcPass The source pass. + @param dstPass The destination pass. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { return true; } + + /** Return the accessor object to this sub render state. + @see SubRenderStateAccessor. + */ + SubRenderStateAccessorPtr getAccessor(); + + /** Return the accessor object to this sub render state. + @see SubRenderStateAccessor. + */ + SubRenderStateAccessorPtr getAccessor() const; // Protected methods protected: - /** Resolve parameters that this sub render state requires. - @param programSet container class of CPU and GPU programs that this sub state will affect on. - @remarks Internal method called in the context of SubRenderState::createCpuSubPrograms implementation. - */ - virtual bool resolveParameters(ProgramSet* programSet); + /** Resolve parameters that this sub render state requires. + @param programSet container class of CPU and GPU programs that this sub state will affect on. + @remarks Internal method called in the context of SubRenderState::createCpuSubPrograms implementation. + */ + virtual bool resolveParameters(ProgramSet* programSet); - /** Resolve dependencies that this sub render state requires. - @param programSet container class of CPU and GPU programs that this sub state will affect on. - @remarks Internal method called in the context of SubRenderState::createCpuSubPrograms implementation. - */ - virtual bool resolveDependencies(ProgramSet* programSet); + /** Resolve dependencies that this sub render state requires. + @param programSet container class of CPU and GPU programs that this sub state will affect on. + @remarks Internal method called in the context of SubRenderState::createCpuSubPrograms implementation. + */ + virtual bool resolveDependencies(ProgramSet* programSet); - /** Add function invocation that this sub render state requires. - @param programSet container class of CPU and GPU programs that this sub state will affect on. - @remarks Internal method called in the context of SubRenderState::createCpuSubPrograms implementation. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); + /** Add function invocation that this sub render state requires. + @param programSet container class of CPU and GPU programs that this sub state will affect on. + @remarks Internal method called in the context of SubRenderState::createCpuSubPrograms implementation. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); // Attributes. -private: - // The accessor of this instance. - mutable SubRenderStateAccessorPtr mThisAccessor; - // The accessor of the source instance which used as base to create this instance. - SubRenderStateAccessorPtr mOtherAccessor; - +private: + // The accessor of this instance. + mutable SubRenderStateAccessorPtr mThisAccessor; + // The accessor of the source instance which used as base to create this instance. + SubRenderStateAccessorPtr mOtherAccessor; + }; -typedef vector::type SubRenderStateList; -typedef SubRenderStateList::iterator SubRenderStateListIterator; -typedef SubRenderStateList::const_iterator SubRenderStateListConstIterator; +typedef vector::type SubRenderStateList; +typedef SubRenderStateList::iterator SubRenderStateListIterator; +typedef SubRenderStateList::const_iterator SubRenderStateListConstIterator; -typedef set::type SubRenderStateSet; -typedef SubRenderStateSet::iterator SubRenderStateSetIterator; -typedef SubRenderStateSet::const_iterator SubRenderStateSetConstIterator; +typedef set::type SubRenderStateSet; +typedef SubRenderStateSet::iterator SubRenderStateSetIterator; +typedef SubRenderStateSet::const_iterator SubRenderStateSetConstIterator; /** This class uses as accessor from a template SubRenderState to all of its instances that @@ -172,43 +172,43 @@ that will trigger some GPU uniform parameter updates. class _OgreRTSSExport SubRenderStateAccessor { public: - /** Add SubRenderState instance to this accessor. - */ - void addSubRenderStateInstance(SubRenderState* subRenderState) const - { - mSubRenderStateInstancesSet.insert(subRenderState); - } - - /** Remove SubRenderState instance to this accessor. - */ - void removeSubRenderStateInstance(SubRenderState* subRenderState) const - { - SubRenderStateSetIterator itFind = mSubRenderStateInstancesSet.find(subRenderState); - - if (itFind != mSubRenderStateInstancesSet.end()) - { - mSubRenderStateInstancesSet.erase(itFind); - } - } - - /** Return a set of all instances of the template SubRenderState. */ - SubRenderStateSet& getSubRenderStateInstanceSet() { return mSubRenderStateInstancesSet; } - - /** Return a set of all instances of the template SubRenderState. (const version). */ - const SubRenderStateSet& getSubRenderStateInstanceSet() const { return mSubRenderStateInstancesSet; } + /** Add SubRenderState instance to this accessor. + */ + void addSubRenderStateInstance(SubRenderState* subRenderState) const + { + mSubRenderStateInstancesSet.insert(subRenderState); + } + + /** Remove SubRenderState instance to this accessor. + */ + void removeSubRenderStateInstance(SubRenderState* subRenderState) const + { + SubRenderStateSetIterator itFind = mSubRenderStateInstancesSet.find(subRenderState); + + if (itFind != mSubRenderStateInstancesSet.end()) + { + mSubRenderStateInstancesSet.erase(itFind); + } + } + + /** Return a set of all instances of the template SubRenderState. */ + SubRenderStateSet& getSubRenderStateInstanceSet() { return mSubRenderStateInstancesSet; } + + /** Return a set of all instances of the template SubRenderState. (const version). */ + const SubRenderStateSet& getSubRenderStateInstanceSet() const { return mSubRenderStateInstancesSet; } protected: - /** Construct SubRenderState accessor based on the given template SubRenderState. - */ - SubRenderStateAccessor(const SubRenderState* templateSubRenderState) : mTemplateSubRenderState(templateSubRenderState) {} + /** Construct SubRenderState accessor based on the given template SubRenderState. + */ + SubRenderStateAccessor(const SubRenderState* templateSubRenderState) : mTemplateSubRenderState(templateSubRenderState) {} protected: - const SubRenderState* mTemplateSubRenderState; - mutable SubRenderStateSet mSubRenderStateInstancesSet; + const SubRenderState* mTemplateSubRenderState; + mutable SubRenderStateSet mSubRenderStateInstancesSet; private: - friend class SubRenderState; + friend class SubRenderState; }; @@ -228,87 +228,87 @@ class _OgreRTSSExport SubRenderStateFactory : public RTShaderSystemAlloc { public: - SubRenderStateFactory() {} - virtual ~SubRenderStateFactory(); - - /** Get the type of this sub render state factory. - @remarks - The type string should be the same as the type of the SubRenderState sub class it is going to create. - @see SubRenderState::getType. - */ - virtual const String& getType() const = 0; - - /** Create an instance of the SubRenderState sub class it suppose to create. - */ - virtual SubRenderState* createInstance(); - - /** Create an instance of the SubRenderState based on script properties. - This method is called in the context of script parsing and let this factory - the opportunity to create custom SubRenderState instances based on extended script properties. - @param compiler The compiler instance. - @param prop The abstract property node. - @param pass The pass that is the parent context of this node. + SubRenderStateFactory() {} + virtual ~SubRenderStateFactory(); + + /** Get the type of this sub render state factory. + @remarks + The type string should be the same as the type of the SubRenderState sub class it is going to create. + @see SubRenderState::getType. + */ + virtual const String& getType() const = 0; + + /** Create an instance of the SubRenderState sub class it suppose to create. + */ + virtual SubRenderState* createInstance(); + + /** Create an instance of the SubRenderState based on script properties. + This method is called in the context of script parsing and let this factory + the opportunity to create custom SubRenderState instances based on extended script properties. + @param compiler The compiler instance. + @param prop The abstract property node. + @param pass The pass that is the parent context of this node. @param translator The translator instance holding existing scripts. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { return NULL; } - - /** Create an instance of the SubRenderState based on script properties. - This method is called in the context of script parsing and let this factory - the opportunity to create custom SubRenderState instances based on extended script properties. - @param compiler The compiler instance. - @param prop The abstract property node. - @param texState The pass that is the parent context of this node. + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { return NULL; } + + /** Create an instance of the SubRenderState based on script properties. + This method is called in the context of script parsing and let this factory + the opportunity to create custom SubRenderState instances based on extended script properties. + @param compiler The compiler instance. + @param prop The abstract property node. + @param texState The pass that is the parent context of this node. @param translator The translator instance holding existing scripts. - */ - virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator) { return NULL; } - - /** Retrieve the previous instance the SRS in the script translator or - * create a new instance if not found - @param translator The translator instance holding existing scripts. - */ - virtual SubRenderState* createOrRetrieveInstance(SGScriptTranslator* translator); - - /** Destroy the given instance. - @param subRenderState The instance to destroy. - */ - virtual void destroyInstance(SubRenderState* subRenderState); - - /** Destroy all the instances that created by this factory. - */ - virtual void destroyAllInstances(); - - /** Write the given sub-render state instance using the material serializer. - This method is called in the context of material serialization. It is useful for integrating into - bigger context of material exporters from various environment that want to take advantage of the RT Shader System. - Sub classes of this interface should override in case they need to write custom properties into the script context. - @param ser The material serializer instance. - @param subRenderState The sub render state instance to write down. - @param srcPass The source pass. - @param dstPass The generated shader based pass. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass) {} - - /** Write the given sub-render state instance using the material serializer. - This method is called in the context of material serialization. It is useful for integrating into - bigger context of material exporters from various environment that want to take advantage of the RT Shader System. - Sub classes of this interface should override in case they need to write custom properties into the script context. - @param ser The material serializer instance. - @param subRenderState The sub render state instance to write down. - @param srcTextureUnit The source texture unit state. - @param dstTextureUnit The generated shader based texture unit state. - */ - virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, const TextureUnitState* srcTextureUnit, const TextureUnitState* dstTextureUnit) {} + */ + virtual SubRenderState* createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator) { return NULL; } + + /** Retrieve the previous instance the SRS in the script translator or + * create a new instance if not found + @param translator The translator instance holding existing scripts. + */ + virtual SubRenderState* createOrRetrieveInstance(SGScriptTranslator* translator); + + /** Destroy the given instance. + @param subRenderState The instance to destroy. + */ + virtual void destroyInstance(SubRenderState* subRenderState); + + /** Destroy all the instances that created by this factory. + */ + virtual void destroyAllInstances(); + + /** Write the given sub-render state instance using the material serializer. + This method is called in the context of material serialization. It is useful for integrating into + bigger context of material exporters from various environment that want to take advantage of the RT Shader System. + Sub classes of this interface should override in case they need to write custom properties into the script context. + @param ser The material serializer instance. + @param subRenderState The sub render state instance to write down. + @param srcPass The source pass. + @param dstPass The generated shader based pass. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass) {} + + /** Write the given sub-render state instance using the material serializer. + This method is called in the context of material serialization. It is useful for integrating into + bigger context of material exporters from various environment that want to take advantage of the RT Shader System. + Sub classes of this interface should override in case they need to write custom properties into the script context. + @param ser The material serializer instance. + @param subRenderState The sub render state instance to write down. + @param srcTextureUnit The source texture unit state. + @param dstTextureUnit The generated shader based texture unit state. + */ + virtual void writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, const TextureUnitState* srcTextureUnit, const TextureUnitState* dstTextureUnit) {} protected: - /** Create instance implementation method. Each sub class of this interface - must implement this method in which it will allocate the specific sub class of - the SubRenderState. - */ - virtual SubRenderState* createInstanceImpl() = 0; + /** Create instance implementation method. Each sub class of this interface + must implement this method in which it will allocate the specific sub class of + the SubRenderState. + */ + virtual SubRenderState* createInstanceImpl() = 0; // Attributes. protected: - // List of all sub render states instances this factory created. - SubRenderStateSet mSubRenderStateList; + // List of all sub render states instances this factory created. + SubRenderStateSet mSubRenderStateList; }; /** @} */ diff --git a/Components/RTShaderSystem/src/OgreShaderCGProgramProcessor.cpp b/Components/RTShaderSystem/src/OgreShaderCGProgramProcessor.cpp index 22bdfb85395..2c92dab2028 100644 --- a/Components/RTShaderSystem/src/OgreShaderCGProgramProcessor.cpp +++ b/Components/RTShaderSystem/src/OgreShaderCGProgramProcessor.cpp @@ -37,42 +37,42 @@ String CGProgramProcessor::TargetLanguage = "cg"; //----------------------------------------------------------------------------- CGProgramProcessor::CGProgramProcessor() { - + } //----------------------------------------------------------------------------- CGProgramProcessor::~CGProgramProcessor() { - + } //----------------------------------------------------------------------------- bool CGProgramProcessor::preCreateGpuPrograms( ProgramSet* programSet ) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* fsMain = psProgram->getEntryPointFunction(); - bool success; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* fsMain = psProgram->getEntryPointFunction(); + bool success; - // Compact vertex shader outputs. - success = ProgramProcessor::compactVsOutputs(vsMain, fsMain); - if (success == false) - return false; + // Compact vertex shader outputs. + success = ProgramProcessor::compactVsOutputs(vsMain, fsMain); + if (success == false) + return false; - return true; + return true; } //----------------------------------------------------------------------------- bool CGProgramProcessor::postCreateGpuPrograms( ProgramSet* programSet ) { - // Bind vertex shader auto parameters. - bindAutoParameters(programSet->getCpuVertexProgram(), programSet->getGpuVertexProgram()); + // Bind vertex shader auto parameters. + bindAutoParameters(programSet->getCpuVertexProgram(), programSet->getGpuVertexProgram()); - // Bind fragment shader auto parameters. - bindAutoParameters(programSet->getCpuFragmentProgram(), programSet->getGpuFragmentProgram()); + // Bind fragment shader auto parameters. + bindAutoParameters(programSet->getCpuFragmentProgram(), programSet->getGpuFragmentProgram()); - return true; + return true; } } } diff --git a/Components/RTShaderSystem/src/OgreShaderCGProgramWriter.cpp b/Components/RTShaderSystem/src/OgreShaderCGProgramWriter.cpp index 9687dc7e715..4cc3e47eb21 100644 --- a/Components/RTShaderSystem/src/OgreShaderCGProgramWriter.cpp +++ b/Components/RTShaderSystem/src/OgreShaderCGProgramWriter.cpp @@ -39,7 +39,7 @@ String CGProgramWriter::TargetLanguage = "cg"; //----------------------------------------------------------------------- CGProgramWriter::CGProgramWriter() { - initializeStringMaps(); + initializeStringMaps(); } //----------------------------------------------------------------------- @@ -51,240 +51,240 @@ CGProgramWriter::~CGProgramWriter() //----------------------------------------------------------------------- void CGProgramWriter::initializeStringMaps() { - mGpuConstTypeMap[GCT_FLOAT1] = "float"; - mGpuConstTypeMap[GCT_FLOAT2] = "float2"; - mGpuConstTypeMap[GCT_FLOAT3] = "float3"; - mGpuConstTypeMap[GCT_FLOAT4] = "float4"; - mGpuConstTypeMap[GCT_SAMPLER1D] = "sampler1D"; - mGpuConstTypeMap[GCT_SAMPLER2D] = "sampler2D"; - mGpuConstTypeMap[GCT_SAMPLER3D] = "sampler3D"; - mGpuConstTypeMap[GCT_SAMPLERCUBE] = "samplerCUBE"; - mGpuConstTypeMap[GCT_MATRIX_2X2] = "float2x2"; - mGpuConstTypeMap[GCT_MATRIX_2X3] = "float2x3"; - mGpuConstTypeMap[GCT_MATRIX_2X4] = "float2x4"; - mGpuConstTypeMap[GCT_MATRIX_3X2] = "float3x2"; - mGpuConstTypeMap[GCT_MATRIX_3X3] = "float3x3"; - mGpuConstTypeMap[GCT_MATRIX_3X4] = "float3x4"; - mGpuConstTypeMap[GCT_MATRIX_4X2] = "float4x2"; - mGpuConstTypeMap[GCT_MATRIX_4X3] = "float4x3"; - mGpuConstTypeMap[GCT_MATRIX_4X4] = "float4x4"; - mGpuConstTypeMap[GCT_INT1] = "int"; - mGpuConstTypeMap[GCT_INT2] = "int2"; - mGpuConstTypeMap[GCT_INT3] = "int3"; - mGpuConstTypeMap[GCT_INT4] = "int4"; - mGpuConstTypeMap[GCT_UINT1] = "uint"; - mGpuConstTypeMap[GCT_UINT2] = "uint2"; - mGpuConstTypeMap[GCT_UINT3] = "uint3"; - mGpuConstTypeMap[GCT_UINT4] = "uint4"; - - - mParamSemanticMap[Parameter::SPS_POSITION] = "POSITION"; - mParamSemanticMap[Parameter::SPS_BLEND_WEIGHTS] = "BLENDWEIGHT"; - mParamSemanticMap[Parameter::SPS_BLEND_INDICES] = "BLENDINDICES"; - mParamSemanticMap[Parameter::SPS_NORMAL] = "NORMAL"; - mParamSemanticMap[Parameter::SPS_COLOR] = "COLOR"; - mParamSemanticMap[Parameter::SPS_TEXTURE_COORDINATES] = "TEXCOORD"; - mParamSemanticMap[Parameter::SPS_BINORMAL] = "BINORMAL"; - mParamSemanticMap[Parameter::SPS_TANGENT] = "TANGENT"; - mParamSemanticMap[Parameter::SPS_UNKNOWN] = ""; + mGpuConstTypeMap[GCT_FLOAT1] = "float"; + mGpuConstTypeMap[GCT_FLOAT2] = "float2"; + mGpuConstTypeMap[GCT_FLOAT3] = "float3"; + mGpuConstTypeMap[GCT_FLOAT4] = "float4"; + mGpuConstTypeMap[GCT_SAMPLER1D] = "sampler1D"; + mGpuConstTypeMap[GCT_SAMPLER2D] = "sampler2D"; + mGpuConstTypeMap[GCT_SAMPLER3D] = "sampler3D"; + mGpuConstTypeMap[GCT_SAMPLERCUBE] = "samplerCUBE"; + mGpuConstTypeMap[GCT_MATRIX_2X2] = "float2x2"; + mGpuConstTypeMap[GCT_MATRIX_2X3] = "float2x3"; + mGpuConstTypeMap[GCT_MATRIX_2X4] = "float2x4"; + mGpuConstTypeMap[GCT_MATRIX_3X2] = "float3x2"; + mGpuConstTypeMap[GCT_MATRIX_3X3] = "float3x3"; + mGpuConstTypeMap[GCT_MATRIX_3X4] = "float3x4"; + mGpuConstTypeMap[GCT_MATRIX_4X2] = "float4x2"; + mGpuConstTypeMap[GCT_MATRIX_4X3] = "float4x3"; + mGpuConstTypeMap[GCT_MATRIX_4X4] = "float4x4"; + mGpuConstTypeMap[GCT_INT1] = "int"; + mGpuConstTypeMap[GCT_INT2] = "int2"; + mGpuConstTypeMap[GCT_INT3] = "int3"; + mGpuConstTypeMap[GCT_INT4] = "int4"; + mGpuConstTypeMap[GCT_UINT1] = "uint"; + mGpuConstTypeMap[GCT_UINT2] = "uint2"; + mGpuConstTypeMap[GCT_UINT3] = "uint3"; + mGpuConstTypeMap[GCT_UINT4] = "uint4"; + + + mParamSemanticMap[Parameter::SPS_POSITION] = "POSITION"; + mParamSemanticMap[Parameter::SPS_BLEND_WEIGHTS] = "BLENDWEIGHT"; + mParamSemanticMap[Parameter::SPS_BLEND_INDICES] = "BLENDINDICES"; + mParamSemanticMap[Parameter::SPS_NORMAL] = "NORMAL"; + mParamSemanticMap[Parameter::SPS_COLOR] = "COLOR"; + mParamSemanticMap[Parameter::SPS_TEXTURE_COORDINATES] = "TEXCOORD"; + mParamSemanticMap[Parameter::SPS_BINORMAL] = "BINORMAL"; + mParamSemanticMap[Parameter::SPS_TANGENT] = "TANGENT"; + mParamSemanticMap[Parameter::SPS_UNKNOWN] = ""; } //----------------------------------------------------------------------- void CGProgramWriter::writeSourceCode(std::ostream& os, Program* program) { - const ShaderFunctionList& functionList = program->getFunctions(); - ShaderFunctionConstIterator itFunction; + const ShaderFunctionList& functionList = program->getFunctions(); + ShaderFunctionConstIterator itFunction; - const UniformParameterList& parameterList = program->getParameters(); - UniformParameterConstIterator itUniformParam = parameterList.begin(); + const UniformParameterList& parameterList = program->getParameters(); + UniformParameterConstIterator itUniformParam = parameterList.begin(); - // Generate source code header. - writeProgramTitle(os, program); - os << std::endl; + // Generate source code header. + writeProgramTitle(os, program); + os << std::endl; - // Generate dependencies. - writeProgramDependencies(os, program); - os << std::endl; + // Generate dependencies. + writeProgramDependencies(os, program); + os << std::endl; - // Generate global variable code. - writeUniformParametersTitle(os, program); - os << std::endl; + // Generate global variable code. + writeUniformParametersTitle(os, program); + os << std::endl; - for (itUniformParam=parameterList.begin(); itUniformParam != parameterList.end(); ++itUniformParam) - { - writeUniformParameter(os, *itUniformParam); - os << ";" << std::endl; - } - os << std::endl; + for (itUniformParam=parameterList.begin(); itUniformParam != parameterList.end(); ++itUniformParam) + { + writeUniformParameter(os, *itUniformParam); + os << ";" << std::endl; + } + os << std::endl; - // Write program function(s). - for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) - { - Function* curFunction = *itFunction; + // Write program function(s). + for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) + { + Function* curFunction = *itFunction; - writeFunctionTitle(os, curFunction); - writeFunctionDeclaration(os, curFunction); + writeFunctionTitle(os, curFunction); + writeFunctionDeclaration(os, curFunction); - os << "{" << std::endl; + os << "{" << std::endl; - // Write local parameters. - const ShaderParameterList& localParams = curFunction->getLocalParameters(); - ShaderParameterConstIterator itParam; + // Write local parameters. + const ShaderParameterList& localParams = curFunction->getLocalParameters(); + ShaderParameterConstIterator itParam; - for (itParam=localParams.begin(); itParam != localParams.end(); ++itParam) - { - os << "\t"; - writeLocalParameter(os, *itParam); - os << ";" << std::endl; - } + for (itParam=localParams.begin(); itParam != localParams.end(); ++itParam) + { + os << "\t"; + writeLocalParameter(os, *itParam); + os << ";" << std::endl; + } - // Sort and write function atoms. - curFunction->sortAtomInstances(); + // Sort and write function atoms. + curFunction->sortAtomInstances(); - const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances(); - FunctionAtomInstanceConstIterator itAtom; + const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances(); + FunctionAtomInstanceConstIterator itAtom; - for (itAtom=atomInstances.begin(); itAtom != atomInstances.end(); ++itAtom) - { - writeAtomInstance(os, *itAtom); - } + for (itAtom=atomInstances.begin(); itAtom != atomInstances.end(); ++itAtom) + { + writeAtomInstance(os, *itAtom); + } - os << "}" << std::endl; - } + os << "}" << std::endl; + } - os << std::endl; + os << std::endl; } //----------------------------------------------------------------------- void CGProgramWriter::writeProgramDependencies(std::ostream& os, Program* program) { - os << "//-----------------------------------------------------------------------------" << std::endl; - os << "// PROGRAM DEPENDENCIES" << std::endl; - os << "//-----------------------------------------------------------------------------" << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; + os << "// PROGRAM DEPENDENCIES" << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; - for (unsigned int i=0; i < program->getDependencyCount(); ++i) - { - const String& curDependency = program->getDependency(i); + for (unsigned int i=0; i < program->getDependencyCount(); ++i) + { + const String& curDependency = program->getDependency(i); - os << "#include " << '\"' << curDependency << "." << getTargetLanguage() << '\"' << std::endl; - } + os << "#include " << '\"' << curDependency << "." << getTargetLanguage() << '\"' << std::endl; + } } //----------------------------------------------------------------------- void CGProgramWriter::writeUniformParameter(std::ostream& os, UniformParameterPtr parameter) { - os << mGpuConstTypeMap[parameter->getType()]; - os << "\t"; - os << parameter->getName(); - if (parameter->isArray() == true) - { - os << "[" << parameter->getSize() << "]"; - } - - if (parameter->isSampler()) - { - os << " : register(s" << parameter->getIndex() << ")"; - } + os << mGpuConstTypeMap[parameter->getType()]; + os << "\t"; + os << parameter->getName(); + if (parameter->isArray() == true) + { + os << "[" << parameter->getSize() << "]"; + } + + if (parameter->isSampler()) + { + os << " : register(s" << parameter->getIndex() << ")"; + } } //----------------------------------------------------------------------- void CGProgramWriter::writeFunctionParameter(std::ostream& os, ParameterPtr parameter) { - os << mGpuConstTypeMap[parameter->getType()]; - - os << "\t"; - os << parameter->getName(); - if (parameter->isArray() == true) - { - os << "[" << parameter->getSize() << "]"; - } - - if (parameter->getSemantic() != Parameter::SPS_UNKNOWN) - { - os << " : "; - os << mParamSemanticMap[parameter->getSemantic()]; - - if (parameter->getSemantic() != Parameter::SPS_POSITION && - parameter->getSemantic() != Parameter::SPS_NORMAL && - parameter->getSemantic() != Parameter::SPS_TANGENT && - parameter->getSemantic() != Parameter::SPS_BLEND_INDICES && - parameter->getSemantic() != Parameter::SPS_BLEND_WEIGHTS && - (!(parameter->getSemantic() == Parameter::SPS_COLOR && parameter->getIndex() == 0)) && - parameter->getIndex() >= 0) - { - os << StringConverter::toString(parameter->getIndex()).c_str(); - } - } + os << mGpuConstTypeMap[parameter->getType()]; + + os << "\t"; + os << parameter->getName(); + if (parameter->isArray() == true) + { + os << "[" << parameter->getSize() << "]"; + } + + if (parameter->getSemantic() != Parameter::SPS_UNKNOWN) + { + os << " : "; + os << mParamSemanticMap[parameter->getSemantic()]; + + if (parameter->getSemantic() != Parameter::SPS_POSITION && + parameter->getSemantic() != Parameter::SPS_NORMAL && + parameter->getSemantic() != Parameter::SPS_TANGENT && + parameter->getSemantic() != Parameter::SPS_BLEND_INDICES && + parameter->getSemantic() != Parameter::SPS_BLEND_WEIGHTS && + (!(parameter->getSemantic() == Parameter::SPS_COLOR && parameter->getIndex() == 0)) && + parameter->getIndex() >= 0) + { + os << StringConverter::toString(parameter->getIndex()).c_str(); + } + } } //----------------------------------------------------------------------- void CGProgramWriter::writeLocalParameter(std::ostream& os, ParameterPtr parameter) { - os << mGpuConstTypeMap[parameter->getType()]; - os << "\t"; - os << parameter->getName(); - if (parameter->isArray() == true) - { - os << "[" << parameter->getSize() << "]"; - } + os << mGpuConstTypeMap[parameter->getType()]; + os << "\t"; + os << parameter->getName(); + if (parameter->isArray() == true) + { + os << "[" << parameter->getSize() << "]"; + } } //----------------------------------------------------------------------- void CGProgramWriter::writeFunctionDeclaration(std::ostream& os, Function* function) { - const ShaderParameterList& inParams = function->getInputParameters(); - const ShaderParameterList& outParams = function->getOutputParameters(); + const ShaderParameterList& inParams = function->getInputParameters(); + const ShaderParameterList& outParams = function->getOutputParameters(); - os << "void"; - os << " "; + os << "void"; + os << " "; - os << function->getName(); - os << std::endl << "\t(" << std::endl; + os << function->getName(); + os << std::endl << "\t(" << std::endl; - ShaderParameterConstIterator it; - size_t paramsCount = inParams.size() + outParams.size(); - size_t curParamIndex = 0; + ShaderParameterConstIterator it; + size_t paramsCount = inParams.size() + outParams.size(); + size_t curParamIndex = 0; - // Write input parameters. - for (it=inParams.begin(); it != inParams.end(); ++it) - { - os << "\t in "; + // Write input parameters. + for (it=inParams.begin(); it != inParams.end(); ++it) + { + os << "\t in "; - writeFunctionParameter(os, *it); + writeFunctionParameter(os, *it); - if (curParamIndex + 1 != paramsCount) - os << ", " << std::endl; + if (curParamIndex + 1 != paramsCount) + os << ", " << std::endl; - curParamIndex++; - } + curParamIndex++; + } - // Write output parameters. - for (it=outParams.begin(); it != outParams.end(); ++it) - { - os << "\t out "; - writeFunctionParameter(os, *it); + // Write output parameters. + for (it=outParams.begin(); it != outParams.end(); ++it) + { + os << "\t out "; + writeFunctionParameter(os, *it); - if (curParamIndex + 1 != paramsCount) - os << ", " << std::endl; + if (curParamIndex + 1 != paramsCount) + os << ", " << std::endl; - curParamIndex++; - } + curParamIndex++; + } - os << std::endl << "\t)" << std::endl; + os << std::endl << "\t)" << std::endl; } //----------------------------------------------------------------------- void CGProgramWriter::writeAtomInstance(std::ostream& os, FunctionAtom* atom) { - os << std::endl << "\t"; - atom->writeSourceCode(os, getTargetLanguage()); - os << std::endl; + os << std::endl << "\t"; + atom->writeSourceCode(os, getTargetLanguage()); + os << std::endl; } } diff --git a/Components/RTShaderSystem/src/OgreShaderExDualQuaternionSkinning.cpp b/Components/RTShaderSystem/src/OgreShaderExDualQuaternionSkinning.cpp index f7d3df20879..de76a3db53e 100644 --- a/Components/RTShaderSystem/src/OgreShaderExDualQuaternionSkinning.cpp +++ b/Components/RTShaderSystem/src/OgreShaderExDualQuaternionSkinning.cpp @@ -51,386 +51,386 @@ DualQuaternionSkinning::DualQuaternionSkinning() : HardwareSkinningTechnique() //----------------------------------------------------------------------- bool DualQuaternionSkinning::resolveParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - - //if needed mark this vertex program as hardware skinned - if (mDoBoneCalculations == true) - { - vsProgram->setSkeletalAnimationIncluded(true); - } - - // - // get the parameters we need whether we are doing bone calculations or not - // - // Note: in order to be consistent we will always output position, normal, - // tangent and binormal in both object and world space. And output position - // in projective space to cover the responsibility of the transform stage - - //input param - mParamInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - mParamInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - mParamInBiNormal = vsMain->resolveInputParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_OBJECT_SPACE, GCT_FLOAT3); - mParamInTangent = vsMain->resolveInputParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_OBJECT_SPACE, GCT_FLOAT3); - - //local param - mParamLocalBlendPosition = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "BlendedPosition", GCT_FLOAT3); - mParamLocalPositionWorld = vsMain->resolveLocalParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT4); - mParamLocalNormalWorld = vsMain->resolveLocalParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_WORLD_SPACE, GCT_FLOAT3); - mParamLocalTangentWorld = vsMain->resolveLocalParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_WORLD_SPACE, GCT_FLOAT3); - mParamLocalBinormalWorld = vsMain->resolveLocalParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_WORLD_SPACE, GCT_FLOAT3); - - //output param - mParamOutPositionProj = vsMain->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); - - //check if parameter retrival went well - bool isValid = - (mParamInPosition.get() != NULL) && - (mParamInNormal.get() != NULL) && - (mParamInBiNormal.get() != NULL) && - (mParamInTangent.get() != NULL) && - (mParamLocalPositionWorld.get() != NULL) && - (mParamLocalNormalWorld.get() != NULL) && - (mParamLocalTangentWorld.get() != NULL) && - (mParamLocalBinormalWorld.get() != NULL) && - (mParamOutPositionProj.get() != NULL); - - - if (mDoBoneCalculations == true) - { - //input parameters - mParamInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - mParamInBiNormal = vsMain->resolveInputParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_OBJECT_SPACE, GCT_FLOAT3); - mParamInTangent = vsMain->resolveInputParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_OBJECT_SPACE, GCT_FLOAT3); - mParamInIndices = vsMain->resolveInputParameter(Parameter::SPS_BLEND_INDICES, 0, Parameter::SPC_UNKNOWN, GCT_FLOAT4); - mParamInWeights = vsMain->resolveInputParameter(Parameter::SPS_BLEND_WEIGHTS, 0, Parameter::SPC_UNKNOWN, GCT_FLOAT4); - //ACT_WORLD_DUALQUATERNION_ARRAY_2x4 is an array of float4s, so there are two indices for each bone - mParamInWorldMatrices = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4, GCT_FLOAT4, 0, mBoneCount * 2); - mParamInInvWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_WORLD_MATRIX, 0); - mParamInViewProjMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEWPROJ_MATRIX, 0); - - mParamTempWorldMatrix = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "worldMatrix", GCT_MATRIX_2X4); - mParamBlendDQ = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "blendDQ", GCT_MATRIX_2X4); - mParamInitialDQ = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "initialDQ", GCT_MATRIX_2X4); - mParamIndex1 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "index1", GCT_FLOAT1); - mParamIndex2 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "index2", GCT_FLOAT1); - - if(mScalingShearingSupport) - { - if (ShaderGenerator::getSingleton().getTargetLanguage() == "hlsl") - { - //set hlsl shader to use row-major matrices instead of column-major. - //it enables the use of auto-bound 3x4 matrices in generated hlsl shader. - vsProgram->setUseColumnMajorMatrices(false); - } - - mParamInScaleShearMatrices = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_SCALE_SHEAR_MATRIX_ARRAY_3x4, 0, mBoneCount); - mParamBlendS = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "blendS", GCT_MATRIX_3X4); - mParamTempFloat3x3 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal3x3", GCT_MATRIX_3X3); - mParamTempFloat3x4 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal3x4", GCT_MATRIX_3X4); - } - - mParamTempFloat2x4 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal2x4", GCT_MATRIX_2X4); - mParamTempFloat4 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal4", GCT_FLOAT4); - mParamTempFloat3 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal3", GCT_FLOAT3); - - //check if parameter retrival went well - isValid &= - (mParamInIndices.get() != NULL) && - (mParamInWeights.get() != NULL) && - (mParamInWorldMatrices.get() != NULL) && - (mParamInViewProjMatrix.get() != NULL) && - (mParamInInvWorldMatrix.get() != NULL) && - (mParamBlendDQ.get() != NULL) && - (mParamInitialDQ.get() != NULL) && - (mParamIndex1.get() != NULL) && - (mParamIndex2.get() != NULL) && - - (!mScalingShearingSupport || (mScalingShearingSupport && - (mParamInScaleShearMatrices.get() != NULL && - mParamBlendS.get() != NULL && - mParamTempFloat3x3.get() != NULL && - mParamTempFloat3x4.get() != NULL))) && - - (mParamTempFloat2x4.get() != NULL) && - (mParamTempFloat4.get() != NULL) && - (mParamTempFloat3.get() != NULL); - } - else - { - mParamInWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - mParamInWorldViewProjMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); - - //check if parameter retrival went well - isValid &= - (mParamInWorldMatrix.get() != NULL) && - (mParamInWorldViewProjMatrix.get() != NULL); - } - return isValid; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + + //if needed mark this vertex program as hardware skinned + if (mDoBoneCalculations == true) + { + vsProgram->setSkeletalAnimationIncluded(true); + } + + // + // get the parameters we need whether we are doing bone calculations or not + // + // Note: in order to be consistent we will always output position, normal, + // tangent and binormal in both object and world space. And output position + // in projective space to cover the responsibility of the transform stage + + //input param + mParamInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + mParamInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + mParamInBiNormal = vsMain->resolveInputParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_OBJECT_SPACE, GCT_FLOAT3); + mParamInTangent = vsMain->resolveInputParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_OBJECT_SPACE, GCT_FLOAT3); + + //local param + mParamLocalBlendPosition = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "BlendedPosition", GCT_FLOAT3); + mParamLocalPositionWorld = vsMain->resolveLocalParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT4); + mParamLocalNormalWorld = vsMain->resolveLocalParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_WORLD_SPACE, GCT_FLOAT3); + mParamLocalTangentWorld = vsMain->resolveLocalParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_WORLD_SPACE, GCT_FLOAT3); + mParamLocalBinormalWorld = vsMain->resolveLocalParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_WORLD_SPACE, GCT_FLOAT3); + + //output param + mParamOutPositionProj = vsMain->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); + + //check if parameter retrival went well + bool isValid = + (mParamInPosition.get() != NULL) && + (mParamInNormal.get() != NULL) && + (mParamInBiNormal.get() != NULL) && + (mParamInTangent.get() != NULL) && + (mParamLocalPositionWorld.get() != NULL) && + (mParamLocalNormalWorld.get() != NULL) && + (mParamLocalTangentWorld.get() != NULL) && + (mParamLocalBinormalWorld.get() != NULL) && + (mParamOutPositionProj.get() != NULL); + + + if (mDoBoneCalculations == true) + { + //input parameters + mParamInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + mParamInBiNormal = vsMain->resolveInputParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_OBJECT_SPACE, GCT_FLOAT3); + mParamInTangent = vsMain->resolveInputParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_OBJECT_SPACE, GCT_FLOAT3); + mParamInIndices = vsMain->resolveInputParameter(Parameter::SPS_BLEND_INDICES, 0, Parameter::SPC_UNKNOWN, GCT_FLOAT4); + mParamInWeights = vsMain->resolveInputParameter(Parameter::SPS_BLEND_WEIGHTS, 0, Parameter::SPC_UNKNOWN, GCT_FLOAT4); + //ACT_WORLD_DUALQUATERNION_ARRAY_2x4 is an array of float4s, so there are two indices for each bone + mParamInWorldMatrices = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4, GCT_FLOAT4, 0, mBoneCount * 2); + mParamInInvWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_WORLD_MATRIX, 0); + mParamInViewProjMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEWPROJ_MATRIX, 0); + + mParamTempWorldMatrix = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "worldMatrix", GCT_MATRIX_2X4); + mParamBlendDQ = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "blendDQ", GCT_MATRIX_2X4); + mParamInitialDQ = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "initialDQ", GCT_MATRIX_2X4); + mParamIndex1 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "index1", GCT_FLOAT1); + mParamIndex2 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "index2", GCT_FLOAT1); + + if(mScalingShearingSupport) + { + if (ShaderGenerator::getSingleton().getTargetLanguage() == "hlsl") + { + //set hlsl shader to use row-major matrices instead of column-major. + //it enables the use of auto-bound 3x4 matrices in generated hlsl shader. + vsProgram->setUseColumnMajorMatrices(false); + } + + mParamInScaleShearMatrices = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_SCALE_SHEAR_MATRIX_ARRAY_3x4, 0, mBoneCount); + mParamBlendS = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "blendS", GCT_MATRIX_3X4); + mParamTempFloat3x3 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal3x3", GCT_MATRIX_3X3); + mParamTempFloat3x4 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal3x4", GCT_MATRIX_3X4); + } + + mParamTempFloat2x4 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal2x4", GCT_MATRIX_2X4); + mParamTempFloat4 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal4", GCT_FLOAT4); + mParamTempFloat3 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal3", GCT_FLOAT3); + + //check if parameter retrival went well + isValid &= + (mParamInIndices.get() != NULL) && + (mParamInWeights.get() != NULL) && + (mParamInWorldMatrices.get() != NULL) && + (mParamInViewProjMatrix.get() != NULL) && + (mParamInInvWorldMatrix.get() != NULL) && + (mParamBlendDQ.get() != NULL) && + (mParamInitialDQ.get() != NULL) && + (mParamIndex1.get() != NULL) && + (mParamIndex2.get() != NULL) && + + (!mScalingShearingSupport || (mScalingShearingSupport && + (mParamInScaleShearMatrices.get() != NULL && + mParamBlendS.get() != NULL && + mParamTempFloat3x3.get() != NULL && + mParamTempFloat3x4.get() != NULL))) && + + (mParamTempFloat2x4.get() != NULL) && + (mParamTempFloat4.get() != NULL) && + (mParamTempFloat3.get() != NULL); + } + else + { + mParamInWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + mParamInWorldViewProjMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); + + //check if parameter retrival went well + isValid &= + (mParamInWorldMatrix.get() != NULL) && + (mParamInWorldViewProjMatrix.get() != NULL); + } + return isValid; } //----------------------------------------------------------------------- bool DualQuaternionSkinning::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - vsProgram->addDependency(FFP_LIB_COMMON); - vsProgram->addDependency(FFP_LIB_TRANSFORM); - vsProgram->addDependency(SGX_LIB_DUAL_QUATERNION); + Program* vsProgram = programSet->getCpuVertexProgram(); + vsProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(FFP_LIB_TRANSFORM); + vsProgram->addDependency(SGX_LIB_DUAL_QUATERNION); - return true; + return true; } //----------------------------------------------------------------------- bool DualQuaternionSkinning::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - int internalCounter = 0; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + int internalCounter = 0; - //add functions to calculate position data in world, object and projective space - addPositionCalculations(vsMain, internalCounter); + //add functions to calculate position data in world, object and projective space + addPositionCalculations(vsMain, internalCounter); - //add functions to calculate normal and normal related data in world and object space - addNormalRelatedCalculations(vsMain, mParamInNormal, mParamLocalNormalWorld, internalCounter); - addNormalRelatedCalculations(vsMain, mParamInTangent, mParamLocalTangentWorld, internalCounter); - addNormalRelatedCalculations(vsMain, mParamInBiNormal, mParamLocalBinormalWorld, internalCounter); + //add functions to calculate normal and normal related data in world and object space + addNormalRelatedCalculations(vsMain, mParamInNormal, mParamLocalNormalWorld, internalCounter); + addNormalRelatedCalculations(vsMain, mParamInTangent, mParamLocalTangentWorld, internalCounter); + addNormalRelatedCalculations(vsMain, mParamInBiNormal, mParamLocalBinormalWorld, internalCounter); - return true; + return true; } //----------------------------------------------------------------------- void DualQuaternionSkinning::addPositionCalculations(Function* vsMain, int& funcCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - if (mDoBoneCalculations == true) - { - if(mScalingShearingSupport) - { - //Construct a scaling and shearing matrix based on the blend weights - for(int i = 0 ; i < getWeightCount() ; ++i) - { - //Assign the local param based on the current index of the scaling and shearing matrices - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInScaleShearMatrices, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexToMask(i), 1); - curFuncInvocation->pushOperand(mParamTempFloat3x4, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //Calculate the resultant scaling and shearing matrix based on the weights given - addIndexedPositionWeight(vsMain, i, mParamTempFloat3x4, mParamTempFloat3x4, mParamBlendS, funcCounter); - } - - //Transform the position based by the scaling and shearing matrix - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamBlendS, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - //Assign the input position to the local blended position - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - //Set functions to calculate world position - for(int i = 0 ; i < getWeightCount() ; ++i) - { - //Set the index of the matrix - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexToMask(i)); - curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //Multiply the index by 2 - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(2.0f), Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //Add 1 to the index and assign as the second row's index - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0f), Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamIndex2, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //Build the dual quaternion matrix - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_BUILD_DUAL_QUATERNION_MATRIX, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN, Operand::OPM_ALL, 1); - curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamIndex2, Operand::OPS_IN, Operand::OPM_ALL, 1); - curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //Adjust the podalities of the dual quaternions - if(mCorrectAntipodalityHandling) - { - adjustForCorrectAntipodality(vsMain, i, funcCounter, mParamTempFloat2x4); - } - - //Calculate the resultant dual quaternion based on the weights given - addIndexedPositionWeight(vsMain, i, mParamTempFloat2x4, mParamTempFloat2x4, mParamBlendDQ, funcCounter); - } - - //Normalize the dual quaternion - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_NORMALIZE_DUAL_QUATERNION, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_INOUT); - vsMain->addAtomInstance(curFuncInvocation); - - //Calculate the blend position - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_CALCULATE_BLEND_POSITION, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //Update from object to projective space - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInViewProjMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - //update from object to world space - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //update from object to projective space - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInWorldViewProjMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } + FunctionInvocation* curFuncInvocation = NULL; + + if (mDoBoneCalculations == true) + { + if(mScalingShearingSupport) + { + //Construct a scaling and shearing matrix based on the blend weights + for(int i = 0 ; i < getWeightCount() ; ++i) + { + //Assign the local param based on the current index of the scaling and shearing matrices + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInScaleShearMatrices, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexToMask(i), 1); + curFuncInvocation->pushOperand(mParamTempFloat3x4, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //Calculate the resultant scaling and shearing matrix based on the weights given + addIndexedPositionWeight(vsMain, i, mParamTempFloat3x4, mParamTempFloat3x4, mParamBlendS, funcCounter); + } + + //Transform the position based by the scaling and shearing matrix + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamBlendS, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + //Assign the input position to the local blended position + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + //Set functions to calculate world position + for(int i = 0 ; i < getWeightCount() ; ++i) + { + //Set the index of the matrix + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexToMask(i)); + curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //Multiply the index by 2 + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(2.0f), Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //Add 1 to the index and assign as the second row's index + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0f), Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamIndex2, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //Build the dual quaternion matrix + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_BUILD_DUAL_QUATERNION_MATRIX, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamIndex1, Operand::OPS_IN, Operand::OPM_ALL, 1); + curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamIndex2, Operand::OPS_IN, Operand::OPM_ALL, 1); + curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //Adjust the podalities of the dual quaternions + if(mCorrectAntipodalityHandling) + { + adjustForCorrectAntipodality(vsMain, i, funcCounter, mParamTempFloat2x4); + } + + //Calculate the resultant dual quaternion based on the weights given + addIndexedPositionWeight(vsMain, i, mParamTempFloat2x4, mParamTempFloat2x4, mParamBlendDQ, funcCounter); + } + + //Normalize the dual quaternion + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_NORMALIZE_DUAL_QUATERNION, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_INOUT); + vsMain->addAtomInstance(curFuncInvocation); + + //Calculate the blend position + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_CALCULATE_BLEND_POSITION, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamLocalBlendPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //Update from object to projective space + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInViewProjMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + //update from object to world space + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //update from object to projective space + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInWorldViewProjMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } } //----------------------------------------------------------------------- void DualQuaternionSkinning::addNormalRelatedCalculations(Function* vsMain, - ParameterPtr& pNormalRelatedParam, - ParameterPtr& pNormalWorldRelatedParam, - int& funcCounter) + ParameterPtr& pNormalRelatedParam, + ParameterPtr& pNormalWorldRelatedParam, + int& funcCounter) { - FunctionInvocation* curFuncInvocation; - - if (mDoBoneCalculations == true) - { - if(mScalingShearingSupport) - { - //Calculate the adjoint transpose of the blended scaling and shearing matrix - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_ADJOINT_TRANSPOSE_MATRIX, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamBlendS, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamTempFloat3x3, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //Transform the normal by the adjoint transpose of the blended scaling and shearing matrix - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamTempFloat3x3, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //Need to normalize again after transforming the normal - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_NORMALIZE, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_INOUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - //Transform the normal according to the dual quaternion - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_CALCULATE_BLEND_NORMAL, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //update back the original position relative to the object - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - //update from object to world space - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } + FunctionInvocation* curFuncInvocation; + + if (mDoBoneCalculations == true) + { + if(mScalingShearingSupport) + { + //Calculate the adjoint transpose of the blended scaling and shearing matrix + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_ADJOINT_TRANSPOSE_MATRIX, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamBlendS, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamTempFloat3x3, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //Transform the normal by the adjoint transpose of the blended scaling and shearing matrix + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamTempFloat3x3, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //Need to normalize again after transforming the normal + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_NORMALIZE, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_INOUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + //Transform the normal according to the dual quaternion + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_CALCULATE_BLEND_NORMAL, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamBlendDQ, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //update back the original position relative to the object + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + //update from object to world space + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } } //----------------------------------------------------------------------- void DualQuaternionSkinning::adjustForCorrectAntipodality(Function* vsMain, - int index, int& funcCounter, const ParameterPtr& pTempWorldMatrix) + int index, int& funcCounter, const ParameterPtr& pTempWorldMatrix) { - FunctionInvocation* curFuncInvocation; - - //Antipodality doesn't need to be adjusted for dq0 on itself (used as the basis of antipodality calculations) - if(index > 0) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_ANTIPODALITY_ADJUSTMENT, FFP_VS_TRANSFORM, funcCounter++); - //This is the base dual quaternion dq0, which the antipodality calculations are based on - curFuncInvocation->pushOperand(mParamInitialDQ, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_IN); - curFuncInvocation->pushOperand(pTempWorldMatrix, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else if(index == 0) - { - //Set the first dual quaternion as the initial dq - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInitialDQ, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } + FunctionInvocation* curFuncInvocation; + + //Antipodality doesn't need to be adjusted for dq0 on itself (used as the basis of antipodality calculations) + if(index > 0) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_ANTIPODALITY_ADJUSTMENT, FFP_VS_TRANSFORM, funcCounter++); + //This is the base dual quaternion dq0, which the antipodality calculations are based on + curFuncInvocation->pushOperand(mParamInitialDQ, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_IN); + curFuncInvocation->pushOperand(pTempWorldMatrix, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else if(index == 0) + { + //Set the first dual quaternion as the initial dq + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamTempFloat2x4, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInitialDQ, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } } //----------------------------------------------------------------------- void DualQuaternionSkinning::addIndexedPositionWeight(Function* vsMain, int index, - ParameterPtr& pWorldMatrix, ParameterPtr& pPositionTempParameter, - ParameterPtr& pPositionRelatedOutputParam, int& funcCounter) + ParameterPtr& pWorldMatrix, ParameterPtr& pPositionTempParameter, + ParameterPtr& pPositionRelatedOutputParam, int& funcCounter) { - Operand::OpMask indexMask = indexToMask(index); - FunctionInvocation* curFuncInvocation; - - //multiply position with world matrix and put into temporary param - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_BLEND_WEIGHT, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInWeights, Operand::OPS_IN, indexMask); - curFuncInvocation->pushOperand(pWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //check if on first iteration - if (index == 0) - { - //set the local param as the value of the world param - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_IN); - curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - //add the local param as the value of the world param - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_IN); - curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } + Operand::OpMask indexMask = indexToMask(index); + FunctionInvocation* curFuncInvocation; + + //multiply position with world matrix and put into temporary param + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_BLEND_WEIGHT, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInWeights, Operand::OPS_IN, indexMask); + curFuncInvocation->pushOperand(pWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //check if on first iteration + if (index == 0) + { + //set the local param as the value of the world param + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_IN); + curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + //add the local param as the value of the world param + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(pPositionTempParameter, Operand::OPS_IN); + curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(pPositionRelatedOutputParam, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } } } diff --git a/Components/RTShaderSystem/src/OgreShaderExHardwareSkinning.cpp b/Components/RTShaderSystem/src/OgreShaderExHardwareSkinning.cpp index 84c8d2ab6e9..2aa899a10e5 100644 --- a/Components/RTShaderSystem/src/OgreShaderExHardwareSkinning.cpp +++ b/Components/RTShaderSystem/src/OgreShaderExHardwareSkinning.cpp @@ -62,187 +62,187 @@ String HardwareSkinning::Type = "SGX_HardwareSkinning"; /* */ /************************************************************************/ HardwareSkinning::HardwareSkinning() : - mCreator(NULL), - mSkinningType(ST_LINEAR) + mCreator(NULL), + mSkinningType(ST_LINEAR) { } //----------------------------------------------------------------------- const String& HardwareSkinning::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- int HardwareSkinning::getExecutionOrder() const { - return FFP_TRANSFORM; + return FFP_TRANSFORM; } //----------------------------------------------------------------------- void HardwareSkinning::setHardwareSkinningParam(ushort boneCount, ushort weightCount, SkinningType skinningType, bool correctAntipodalityHandling, bool scalingShearingSupport) { - mSkinningType = skinningType; - - if(skinningType == ST_DUAL_QUATERNION) - { - if(mDualQuat.isNull()) - { - mDualQuat.bind(OGRE_NEW DualQuaternionSkinning); - } - - mActiveTechnique = mDualQuat; - } - else //if(skinningType == ST_LINEAR) - { - if(mLinear.isNull()) - { - mLinear.bind(OGRE_NEW LinearSkinning); - } - - mActiveTechnique = mLinear; - } - - mActiveTechnique->setHardwareSkinningParam(boneCount, weightCount, correctAntipodalityHandling, scalingShearingSupport); + mSkinningType = skinningType; + + if(skinningType == ST_DUAL_QUATERNION) + { + if(mDualQuat.isNull()) + { + mDualQuat.bind(OGRE_NEW DualQuaternionSkinning); + } + + mActiveTechnique = mDualQuat; + } + else //if(skinningType == ST_LINEAR) + { + if(mLinear.isNull()) + { + mLinear.bind(OGRE_NEW LinearSkinning); + } + + mActiveTechnique = mLinear; + } + + mActiveTechnique->setHardwareSkinningParam(boneCount, weightCount, correctAntipodalityHandling, scalingShearingSupport); } //----------------------------------------------------------------------- ushort HardwareSkinning::getBoneCount() { - assert(!mActiveTechnique.isNull()); - return mActiveTechnique->getBoneCount(); + assert(!mActiveTechnique.isNull()); + return mActiveTechnique->getBoneCount(); } //----------------------------------------------------------------------- ushort HardwareSkinning::getWeightCount() { - assert(!mActiveTechnique.isNull()); - return mActiveTechnique->getWeightCount(); + assert(!mActiveTechnique.isNull()); + return mActiveTechnique->getWeightCount(); } //----------------------------------------------------------------------- SkinningType HardwareSkinning::getSkinningType() { - assert(!mActiveTechnique.isNull()); - return mSkinningType; + assert(!mActiveTechnique.isNull()); + return mSkinningType; } //----------------------------------------------------------------------- bool HardwareSkinning::hasCorrectAntipodalityHandling() { - assert(!mActiveTechnique.isNull()); - return mActiveTechnique->hasCorrectAntipodalityHandling(); + assert(!mActiveTechnique.isNull()); + return mActiveTechnique->hasCorrectAntipodalityHandling(); } //----------------------------------------------------------------------- bool HardwareSkinning::hasScalingShearingSupport() { - assert(!mActiveTechnique.isNull()); - return mActiveTechnique->hasScalingShearingSupport(); + assert(!mActiveTechnique.isNull()); + return mActiveTechnique->hasScalingShearingSupport(); } //----------------------------------------------------------------------- void HardwareSkinning::copyFrom(const SubRenderState& rhs) { - const HardwareSkinning& hardSkin = static_cast(rhs); - - mDualQuat = hardSkin.mDualQuat; - mLinear = hardSkin.mLinear; - mActiveTechnique = hardSkin.mActiveTechnique; - - mCreator = hardSkin.mCreator; - mSkinningType = hardSkin.mSkinningType; + const HardwareSkinning& hardSkin = static_cast(rhs); + + mDualQuat = hardSkin.mDualQuat; + mLinear = hardSkin.mLinear; + mActiveTechnique = hardSkin.mActiveTechnique; + + mCreator = hardSkin.mCreator; + mSkinningType = hardSkin.mSkinningType; } //----------------------------------------------------------------------- void operator<<(std::ostream& o, const HardwareSkinning::SkinningData& data) { - o << data.isValid; - o << data.maxBoneCount; - o << data.maxWeightCount; - o << data.skinningType; - o << data.correctAntipodalityHandling; - o << data.scalingShearingSupport; + o << data.isValid; + o << data.maxBoneCount; + o << data.maxWeightCount; + o << data.skinningType; + o << data.correctAntipodalityHandling; + o << data.scalingShearingSupport; } //----------------------------------------------------------------------- bool HardwareSkinning::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { - bool isValid = true; - Technique* pFirstTech = srcPass->getParent()->getParent()->getTechnique(0); - const Any& hsAny = pFirstTech->getUserObjectBindings().getUserAny(HS_DATA_BIND_NAME); - - if (hsAny.isEmpty() == false) - { - HardwareSkinning::SkinningData pData = - (any_cast(hsAny)); - isValid = pData.isValid; - - //If the skinning data is being passed through the material, we need to create an instance of the appropriate - //skinning type and set its parameters here - setHardwareSkinningParam(pData.maxBoneCount, pData.maxWeightCount, pData.skinningType, - pData.correctAntipodalityHandling, pData.scalingShearingSupport); - } - - //If there is no associated technique, default to linear skinning as a pass-through - if(mActiveTechnique.isNull()) - { - setHardwareSkinningParam(0, 0, ST_LINEAR, false, false); - } - - int boneCount = mActiveTechnique->getBoneCount(); - int weightCount = mActiveTechnique->getWeightCount(); - - bool doBoneCalculations = isValid && - (boneCount != 0) && (boneCount <= 256) && - (weightCount != 0) && (weightCount <= 4) && - ((mCreator == NULL) || (boneCount <= mCreator->getMaxCalculableBoneCount())); - - mActiveTechnique->setDoBoneCalculations(doBoneCalculations); - - if ((doBoneCalculations) && (mCreator)) - { - //update the receiver and caster materials - if (dstPass->getParent()->getShadowCasterMaterial().isNull()) - { - dstPass->getParent()->setShadowCasterMaterial( - mCreator->getCustomShadowCasterMaterial(mSkinningType, weightCount - 1)); - } - - if (dstPass->getParent()->getShadowReceiverMaterial().isNull()) - { - dstPass->getParent()->setShadowReceiverMaterial( - mCreator->getCustomShadowReceiverMaterial(mSkinningType, weightCount - 1)); - } - } - - return true; + bool isValid = true; + Technique* pFirstTech = srcPass->getParent()->getParent()->getTechnique(0); + const Any& hsAny = pFirstTech->getUserObjectBindings().getUserAny(HS_DATA_BIND_NAME); + + if (hsAny.isEmpty() == false) + { + HardwareSkinning::SkinningData pData = + (any_cast(hsAny)); + isValid = pData.isValid; + + //If the skinning data is being passed through the material, we need to create an instance of the appropriate + //skinning type and set its parameters here + setHardwareSkinningParam(pData.maxBoneCount, pData.maxWeightCount, pData.skinningType, + pData.correctAntipodalityHandling, pData.scalingShearingSupport); + } + + //If there is no associated technique, default to linear skinning as a pass-through + if(mActiveTechnique.isNull()) + { + setHardwareSkinningParam(0, 0, ST_LINEAR, false, false); + } + + int boneCount = mActiveTechnique->getBoneCount(); + int weightCount = mActiveTechnique->getWeightCount(); + + bool doBoneCalculations = isValid && + (boneCount != 0) && (boneCount <= 256) && + (weightCount != 0) && (weightCount <= 4) && + ((mCreator == NULL) || (boneCount <= mCreator->getMaxCalculableBoneCount())); + + mActiveTechnique->setDoBoneCalculations(doBoneCalculations); + + if ((doBoneCalculations) && (mCreator)) + { + //update the receiver and caster materials + if (dstPass->getParent()->getShadowCasterMaterial().isNull()) + { + dstPass->getParent()->setShadowCasterMaterial( + mCreator->getCustomShadowCasterMaterial(mSkinningType, weightCount - 1)); + } + + if (dstPass->getParent()->getShadowReceiverMaterial().isNull()) + { + dstPass->getParent()->setShadowReceiverMaterial( + mCreator->getCustomShadowReceiverMaterial(mSkinningType, weightCount - 1)); + } + } + + return true; } //----------------------------------------------------------------------- bool HardwareSkinning::resolveParameters(ProgramSet* programSet) { - assert(!mActiveTechnique.isNull()); - return mActiveTechnique->resolveParameters(programSet); + assert(!mActiveTechnique.isNull()); + return mActiveTechnique->resolveParameters(programSet); } //----------------------------------------------------------------------- bool HardwareSkinning::resolveDependencies(ProgramSet* programSet) { - assert(!mActiveTechnique.isNull()); - return mActiveTechnique->resolveDependencies(programSet); + assert(!mActiveTechnique.isNull()); + return mActiveTechnique->resolveDependencies(programSet); } //----------------------------------------------------------------------- bool HardwareSkinning::addFunctionInvocations(ProgramSet* programSet) { - assert(!mActiveTechnique.isNull()); - return mActiveTechnique->addFunctionInvocations(programSet); + assert(!mActiveTechnique.isNull()); + return mActiveTechnique->addFunctionInvocations(programSet); } //----------------------------------------------------------------------- HardwareSkinningFactory::HardwareSkinningFactory() : - mMaxCalculableBoneCount(70) + mMaxCalculableBoneCount(70) { } @@ -250,292 +250,292 @@ HardwareSkinningFactory::HardwareSkinningFactory() : //----------------------------------------------------------------------- const String& HardwareSkinningFactory::getType() const { - return HardwareSkinning::Type; + return HardwareSkinning::Type; } //----------------------------------------------------------------------- -SubRenderState* HardwareSkinningFactory::createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* HardwareSkinningFactory::createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "hardware_skinning") - { - bool hasError = false; - uint32 boneCount = 0; - uint32 weightCount = 0; - String skinningType = ""; - SkinningType skinType = ST_LINEAR; - bool correctAntipodalityHandling = false; - bool scalingShearingSupport = false; - - if(prop->values.size() >= 2) - { - AbstractNodeList::iterator it = prop->values.begin(); - if(false == SGScriptTranslator::getUInt(*it, &boneCount)) - hasError = true; - - ++it; - if(false == SGScriptTranslator::getUInt(*it, &weightCount)) - hasError = true; - - if(prop->values.size() >= 5) - { - ++it; - SGScriptTranslator::getString(*it, &skinningType); - - ++it; - SGScriptTranslator::getBoolean(*it, &correctAntipodalityHandling); - - ++it; - SGScriptTranslator::getBoolean(*it, &scalingShearingSupport); - } - - //If the skinningType is not specified or is specified incorrectly, default to linear skinning. - if(skinningType == "dual_quaternion") - { - skinType = ST_DUAL_QUATERNION; - } - else - { - skinType = ST_LINEAR; - } - } - - if (hasError == true) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, "Expected the format: hardware_skinning [skinning type] [correct antipodality handling] [scaling/shearing support]"); - return NULL; - } - else - { - //create and update the hardware skinning sub render state - SubRenderState* subRenderState = createOrRetrieveInstance(translator); - HardwareSkinning* hardSkinSrs = static_cast(subRenderState); - hardSkinSrs->setHardwareSkinningParam(boneCount, weightCount, skinType, correctAntipodalityHandling, scalingShearingSupport); - - return subRenderState; - } - - } - - return NULL; + if (prop->name == "hardware_skinning") + { + bool hasError = false; + uint32 boneCount = 0; + uint32 weightCount = 0; + String skinningType = ""; + SkinningType skinType = ST_LINEAR; + bool correctAntipodalityHandling = false; + bool scalingShearingSupport = false; + + if(prop->values.size() >= 2) + { + AbstractNodeList::iterator it = prop->values.begin(); + if(false == SGScriptTranslator::getUInt(*it, &boneCount)) + hasError = true; + + ++it; + if(false == SGScriptTranslator::getUInt(*it, &weightCount)) + hasError = true; + + if(prop->values.size() >= 5) + { + ++it; + SGScriptTranslator::getString(*it, &skinningType); + + ++it; + SGScriptTranslator::getBoolean(*it, &correctAntipodalityHandling); + + ++it; + SGScriptTranslator::getBoolean(*it, &scalingShearingSupport); + } + + //If the skinningType is not specified or is specified incorrectly, default to linear skinning. + if(skinningType == "dual_quaternion") + { + skinType = ST_DUAL_QUATERNION; + } + else + { + skinType = ST_LINEAR; + } + } + + if (hasError == true) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, "Expected the format: hardware_skinning [skinning type] [correct antipodality handling] [scaling/shearing support]"); + return NULL; + } + else + { + //create and update the hardware skinning sub render state + SubRenderState* subRenderState = createOrRetrieveInstance(translator); + HardwareSkinning* hardSkinSrs = static_cast(subRenderState); + hardSkinSrs->setHardwareSkinningParam(boneCount, weightCount, skinType, correctAntipodalityHandling, scalingShearingSupport); + + return subRenderState; + } + + } + + return NULL; } //----------------------------------------------------------------------- void HardwareSkinningFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + Pass* srcPass, Pass* dstPass) { - ser->writeAttribute(4, "hardware_skinning"); - - HardwareSkinning* hardSkinSrs = static_cast(subRenderState); - ser->writeValue(StringConverter::toString(hardSkinSrs->getBoneCount())); - ser->writeValue(StringConverter::toString(hardSkinSrs->getWeightCount())); - - //Correct antipodality handling and scaling and shearing support are only really valid for dual quaternion skinning - if(hardSkinSrs->getSkinningType() == ST_DUAL_QUATERNION) - { - ser->writeValue("dual_quaternion"); - ser->writeValue(StringConverter::toString(hardSkinSrs->hasCorrectAntipodalityHandling())); - ser->writeValue(StringConverter::toString(hardSkinSrs->hasScalingShearingSupport())); - } + ser->writeAttribute(4, "hardware_skinning"); + + HardwareSkinning* hardSkinSrs = static_cast(subRenderState); + ser->writeValue(StringConverter::toString(hardSkinSrs->getBoneCount())); + ser->writeValue(StringConverter::toString(hardSkinSrs->getWeightCount())); + + //Correct antipodality handling and scaling and shearing support are only really valid for dual quaternion skinning + if(hardSkinSrs->getSkinningType() == ST_DUAL_QUATERNION) + { + ser->writeValue("dual_quaternion"); + ser->writeValue(StringConverter::toString(hardSkinSrs->hasCorrectAntipodalityHandling())); + ser->writeValue(StringConverter::toString(hardSkinSrs->hasScalingShearingSupport())); + } } //----------------------------------------------------------------------- SubRenderState* HardwareSkinningFactory::createInstanceImpl() { - HardwareSkinning* pSkin = OGRE_NEW HardwareSkinning; - - pSkin->_setCreator(this); - return pSkin; + HardwareSkinning* pSkin = OGRE_NEW HardwareSkinning; + + pSkin->_setCreator(this); + return pSkin; } //----------------------------------------------------------------------- void HardwareSkinningFactory::setCustomShadowCasterMaterials(const SkinningType skinningType, const MaterialPtr& caster1Weight, const MaterialPtr& caster2Weight, - const MaterialPtr& caster3Weight, const MaterialPtr& caster4Weight) + const MaterialPtr& caster3Weight, const MaterialPtr& caster4Weight) { - if(skinningType == ST_DUAL_QUATERNION) - { - mCustomShadowCasterMaterialsDualQuaternion[0] = caster1Weight; - mCustomShadowCasterMaterialsDualQuaternion[1] = caster2Weight; - mCustomShadowCasterMaterialsDualQuaternion[2] = caster3Weight; - mCustomShadowCasterMaterialsDualQuaternion[3] = caster4Weight; - } - else //if(skinningType == ST_LINEAR) - { - mCustomShadowCasterMaterialsLinear[0] = caster1Weight; - mCustomShadowCasterMaterialsLinear[1] = caster2Weight; - mCustomShadowCasterMaterialsLinear[2] = caster3Weight; - mCustomShadowCasterMaterialsLinear[3] = caster4Weight; - } + if(skinningType == ST_DUAL_QUATERNION) + { + mCustomShadowCasterMaterialsDualQuaternion[0] = caster1Weight; + mCustomShadowCasterMaterialsDualQuaternion[1] = caster2Weight; + mCustomShadowCasterMaterialsDualQuaternion[2] = caster3Weight; + mCustomShadowCasterMaterialsDualQuaternion[3] = caster4Weight; + } + else //if(skinningType == ST_LINEAR) + { + mCustomShadowCasterMaterialsLinear[0] = caster1Weight; + mCustomShadowCasterMaterialsLinear[1] = caster2Weight; + mCustomShadowCasterMaterialsLinear[2] = caster3Weight; + mCustomShadowCasterMaterialsLinear[3] = caster4Weight; + } } //----------------------------------------------------------------------- void HardwareSkinningFactory::setCustomShadowReceiverMaterials(const SkinningType skinningType, const MaterialPtr& receiver1Weight, const MaterialPtr& receiver2Weight, - const MaterialPtr& receiver3Weight, const MaterialPtr& receiver4Weight) + const MaterialPtr& receiver3Weight, const MaterialPtr& receiver4Weight) { - if(skinningType == ST_DUAL_QUATERNION) - { - mCustomShadowReceiverMaterialsDualQuaternion[0] = receiver1Weight; - mCustomShadowReceiverMaterialsDualQuaternion[1] = receiver2Weight; - mCustomShadowReceiverMaterialsDualQuaternion[2] = receiver3Weight; - mCustomShadowReceiverMaterialsDualQuaternion[3] = receiver4Weight; - } - else //if(skinningType == ST_LINEAR) - { - mCustomShadowReceiverMaterialsLinear[0] = receiver1Weight; - mCustomShadowReceiverMaterialsLinear[1] = receiver2Weight; - mCustomShadowReceiverMaterialsLinear[2] = receiver3Weight; - mCustomShadowReceiverMaterialsLinear[3] = receiver4Weight; - } + if(skinningType == ST_DUAL_QUATERNION) + { + mCustomShadowReceiverMaterialsDualQuaternion[0] = receiver1Weight; + mCustomShadowReceiverMaterialsDualQuaternion[1] = receiver2Weight; + mCustomShadowReceiverMaterialsDualQuaternion[2] = receiver3Weight; + mCustomShadowReceiverMaterialsDualQuaternion[3] = receiver4Weight; + } + else //if(skinningType == ST_LINEAR) + { + mCustomShadowReceiverMaterialsLinear[0] = receiver1Weight; + mCustomShadowReceiverMaterialsLinear[1] = receiver2Weight; + mCustomShadowReceiverMaterialsLinear[2] = receiver3Weight; + mCustomShadowReceiverMaterialsLinear[3] = receiver4Weight; + } } //----------------------------------------------------------------------- const MaterialPtr& HardwareSkinningFactory::getCustomShadowCasterMaterial(const SkinningType skinningType, ushort index) const { - assert(index < HS_MAX_WEIGHT_COUNT); - - if(skinningType == ST_DUAL_QUATERNION) - { - return mCustomShadowCasterMaterialsDualQuaternion[index]; - } - else //if(skinningType = ST_LINEAR) - { - return mCustomShadowCasterMaterialsLinear[index]; - } + assert(index < HS_MAX_WEIGHT_COUNT); + + if(skinningType == ST_DUAL_QUATERNION) + { + return mCustomShadowCasterMaterialsDualQuaternion[index]; + } + else //if(skinningType = ST_LINEAR) + { + return mCustomShadowCasterMaterialsLinear[index]; + } } //----------------------------------------------------------------------- const MaterialPtr& HardwareSkinningFactory::getCustomShadowReceiverMaterial(const SkinningType skinningType, ushort index) const { - assert(index < HS_MAX_WEIGHT_COUNT); - - if(skinningType == ST_DUAL_QUATERNION) - { - return mCustomShadowReceiverMaterialsDualQuaternion[index]; - } - else //if(skinningType == ST_LINEAR) - { - return mCustomShadowReceiverMaterialsLinear[index]; - } + assert(index < HS_MAX_WEIGHT_COUNT); + + if(skinningType == ST_DUAL_QUATERNION) + { + return mCustomShadowReceiverMaterialsDualQuaternion[index]; + } + else //if(skinningType == ST_LINEAR) + { + return mCustomShadowReceiverMaterialsLinear[index]; + } } //----------------------------------------------------------------------- void HardwareSkinningFactory::prepareEntityForSkinning(const Entity* pEntity, SkinningType skinningType, - bool correctAntidpodalityHandling, bool shearScale) + bool correctAntidpodalityHandling, bool shearScale) { - if (pEntity != NULL) - { - size_t lodLevels = pEntity->getNumManualLodLevels() + 1; - for(size_t indexLod = 0 ; indexLod < lodLevels ; ++indexLod) - { - const Entity* pCurEntity = pEntity; - if (indexLod > 0) pCurEntity = pEntity->getManualLodLevel(indexLod - 1); - - unsigned int numSubEntities = pCurEntity->getNumSubEntities(); - for(unsigned int indexSub = 0 ; indexSub < numSubEntities ; ++indexSub) - { - ushort boneCount = 0,weightCount = 0; - bool isValid = extractSkeletonData(pCurEntity, indexSub, boneCount, weightCount); - - SubEntity* pSubEntity = pCurEntity->getSubEntity(indexSub); - const MaterialPtr& pMat = pSubEntity->getMaterial(); - imprintSkeletonData(pMat, isValid, boneCount, weightCount, skinningType, correctAntidpodalityHandling, shearScale); - } - } - } + if (pEntity != NULL) + { + size_t lodLevels = pEntity->getNumManualLodLevels() + 1; + for(size_t indexLod = 0 ; indexLod < lodLevels ; ++indexLod) + { + const Entity* pCurEntity = pEntity; + if (indexLod > 0) pCurEntity = pEntity->getManualLodLevel(indexLod - 1); + + unsigned int numSubEntities = pCurEntity->getNumSubEntities(); + for(unsigned int indexSub = 0 ; indexSub < numSubEntities ; ++indexSub) + { + ushort boneCount = 0,weightCount = 0; + bool isValid = extractSkeletonData(pCurEntity, indexSub, boneCount, weightCount); + + SubEntity* pSubEntity = pCurEntity->getSubEntity(indexSub); + const MaterialPtr& pMat = pSubEntity->getMaterial(); + imprintSkeletonData(pMat, isValid, boneCount, weightCount, skinningType, correctAntidpodalityHandling, shearScale); + } + } + } } //----------------------------------------------------------------------- bool HardwareSkinningFactory::extractSkeletonData(const Entity* pEntity, unsigned int subEntityIndex, ushort& boneCount, ushort& weightCount) { - bool isValidData = false; - boneCount = 0; - weightCount = 0; - - //Check if we have pose animation which the HS sub render state does not - //know how to handle - bool hasVertexAnim = pEntity->getMesh()->hasVertexAnimation(); - - //gather data on the skeleton - if (!hasVertexAnim && pEntity->hasSkeleton()) - { - //get weights count - MeshPtr pMesh = pEntity->getMesh(); - - RenderOperation ro; - SubMesh* pSubMesh = pMesh->getSubMesh(subEntityIndex); - pSubMesh->_getRenderOperation(ro,0); - - //get the largest bone assignment - boneCount = std::max(pMesh->sharedBlendIndexToBoneIndexMap.size(), pSubMesh->blendIndexToBoneIndexMap.size()); - - //go over vertex deceleration - //check that they have blend indices and blend weights - const VertexElement* pDeclWeights = ro.vertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_WEIGHTS,0); - const VertexElement* pDeclIndexes = ro.vertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_INDICES,0); - if ((pDeclWeights != NULL) && (pDeclIndexes != NULL)) - { - isValidData = true; - switch (pDeclWeights->getType()) - { - case VET_FLOAT1: weightCount = 1; break; - case VET_FLOAT2: weightCount = 2; break; - case VET_FLOAT3: weightCount = 3; break; - case VET_FLOAT4: weightCount = 4; break; - default: isValidData = false; - } - } - } - return isValidData; + bool isValidData = false; + boneCount = 0; + weightCount = 0; + + //Check if we have pose animation which the HS sub render state does not + //know how to handle + bool hasVertexAnim = pEntity->getMesh()->hasVertexAnimation(); + + //gather data on the skeleton + if (!hasVertexAnim && pEntity->hasSkeleton()) + { + //get weights count + MeshPtr pMesh = pEntity->getMesh(); + + RenderOperation ro; + SubMesh* pSubMesh = pMesh->getSubMesh(subEntityIndex); + pSubMesh->_getRenderOperation(ro,0); + + //get the largest bone assignment + boneCount = std::max(pMesh->sharedBlendIndexToBoneIndexMap.size(), pSubMesh->blendIndexToBoneIndexMap.size()); + + //go over vertex deceleration + //check that they have blend indices and blend weights + const VertexElement* pDeclWeights = ro.vertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_WEIGHTS,0); + const VertexElement* pDeclIndexes = ro.vertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_INDICES,0); + if ((pDeclWeights != NULL) && (pDeclIndexes != NULL)) + { + isValidData = true; + switch (pDeclWeights->getType()) + { + case VET_FLOAT1: weightCount = 1; break; + case VET_FLOAT2: weightCount = 2; break; + case VET_FLOAT3: weightCount = 3; break; + case VET_FLOAT4: weightCount = 4; break; + default: isValidData = false; + } + } + } + return isValidData; } //----------------------------------------------------------------------- bool HardwareSkinningFactory::imprintSkeletonData(const MaterialPtr& pMaterial, bool isVaild, - ushort boneCount, ushort weightCount, SkinningType skinningType, bool correctAntidpodalityHandling, bool scalingShearingSupport) + ushort boneCount, ushort weightCount, SkinningType skinningType, bool correctAntidpodalityHandling, bool scalingShearingSupport) { - bool isUpdated = false; - if (pMaterial->getNumTechniques() > 0) - { - HardwareSkinning::SkinningData data; - - //get the previous skinning data if available - UserObjectBindings& binding = pMaterial->getTechnique(0)->getUserObjectBindings(); - const Any& hsAny = binding.getUserAny(HS_DATA_BIND_NAME); - if (hsAny.isEmpty() == false) - { - data = (any_cast(hsAny)); - } - - //check if we need to update the data - if (((data.isValid == true) && (isVaild == false)) || - (data.maxBoneCount < boneCount) || - (data.maxWeightCount < weightCount)) - { - //update the data - isUpdated = true; - data.isValid &= isVaild; - data.maxBoneCount = std::max(data.maxBoneCount, boneCount); - data.maxWeightCount = std::max(data.maxWeightCount, weightCount); - data.skinningType = skinningType; - data.correctAntipodalityHandling = correctAntidpodalityHandling; - data.scalingShearingSupport = scalingShearingSupport; - - //update the data in the material and invalidate it in the RTShader system - //do it will be regenerated - binding.setUserAny(HS_DATA_BIND_NAME, Any(data)); - - size_t schemeCount = ShaderGenerator::getSingleton().getRTShaderSchemeCount(); - for(size_t i = 0 ; i < schemeCount ; ++i) - { - //invalidate the material so it will be recreated with the correct - //amount of bones and weights - const String& schemeName = ShaderGenerator::getSingleton().getRTShaderScheme(i); - ShaderGenerator::getSingleton().invalidateMaterial( - schemeName, pMaterial->getName(), pMaterial->getGroup()); - - } - - } - } - return isUpdated; + bool isUpdated = false; + if (pMaterial->getNumTechniques() > 0) + { + HardwareSkinning::SkinningData data; + + //get the previous skinning data if available + UserObjectBindings& binding = pMaterial->getTechnique(0)->getUserObjectBindings(); + const Any& hsAny = binding.getUserAny(HS_DATA_BIND_NAME); + if (hsAny.isEmpty() == false) + { + data = (any_cast(hsAny)); + } + + //check if we need to update the data + if (((data.isValid == true) && (isVaild == false)) || + (data.maxBoneCount < boneCount) || + (data.maxWeightCount < weightCount)) + { + //update the data + isUpdated = true; + data.isValid &= isVaild; + data.maxBoneCount = std::max(data.maxBoneCount, boneCount); + data.maxWeightCount = std::max(data.maxWeightCount, weightCount); + data.skinningType = skinningType; + data.correctAntipodalityHandling = correctAntidpodalityHandling; + data.scalingShearingSupport = scalingShearingSupport; + + //update the data in the material and invalidate it in the RTShader system + //do it will be regenerated + binding.setUserAny(HS_DATA_BIND_NAME, Any(data)); + + size_t schemeCount = ShaderGenerator::getSingleton().getRTShaderSchemeCount(); + for(size_t i = 0 ; i < schemeCount ; ++i) + { + //invalidate the material so it will be recreated with the correct + //amount of bones and weights + const String& schemeName = ShaderGenerator::getSingleton().getRTShaderScheme(i); + ShaderGenerator::getSingleton().invalidateMaterial( + schemeName, pMaterial->getName(), pMaterial->getGroup()); + + } + + } + } + return isUpdated; } diff --git a/Components/RTShaderSystem/src/OgreShaderExHardwareSkinningTechnique.cpp b/Components/RTShaderSystem/src/OgreShaderExHardwareSkinningTechnique.cpp index 79af448d472..f97ee614cf8 100644 --- a/Components/RTShaderSystem/src/OgreShaderExHardwareSkinningTechnique.cpp +++ b/Components/RTShaderSystem/src/OgreShaderExHardwareSkinningTechnique.cpp @@ -39,11 +39,11 @@ namespace RTShader { /* */ /************************************************************************/ HardwareSkinningTechnique::HardwareSkinningTechnique() : - mBoneCount(0), - mWeightCount(0), - mCorrectAntipodalityHandling(false), - mScalingShearingSupport(false), - mDoBoneCalculations(false) + mBoneCount(0), + mWeightCount(0), + mCorrectAntipodalityHandling(false), + mScalingShearingSupport(false), + mDoBoneCalculations(false) { } @@ -55,63 +55,63 @@ HardwareSkinningTechnique::~HardwareSkinningTechnique() //----------------------------------------------------------------------- void HardwareSkinningTechnique::setHardwareSkinningParam(ushort boneCount, ushort weightCount, bool correctAntipodalityHandling, bool scalingShearingSupport) { - mBoneCount = std::min(boneCount, 256); - mWeightCount = std::min(weightCount, 4); - mCorrectAntipodalityHandling = correctAntipodalityHandling; - mScalingShearingSupport = scalingShearingSupport; + mBoneCount = std::min(boneCount, 256); + mWeightCount = std::min(weightCount, 4); + mCorrectAntipodalityHandling = correctAntipodalityHandling; + mScalingShearingSupport = scalingShearingSupport; } //----------------------------------------------------------------------- void HardwareSkinningTechnique::setDoBoneCalculations(bool doBoneCalculations) { - mDoBoneCalculations = doBoneCalculations; + mDoBoneCalculations = doBoneCalculations; } //----------------------------------------------------------------------- ushort HardwareSkinningTechnique::getBoneCount() { - return mBoneCount; + return mBoneCount; } //----------------------------------------------------------------------- ushort HardwareSkinningTechnique::getWeightCount() { - return mWeightCount; + return mWeightCount; } //----------------------------------------------------------------------- bool HardwareSkinningTechnique::hasCorrectAntipodalityHandling() { - return mCorrectAntipodalityHandling; + return mCorrectAntipodalityHandling; } //----------------------------------------------------------------------- bool HardwareSkinningTechnique::hasScalingShearingSupport() { - return mScalingShearingSupport; + return mScalingShearingSupport; } //----------------------------------------------------------------------- Operand::OpMask HardwareSkinningTechnique::indexToMask(int index) { - switch(index) - { - case 0: return Operand::OPM_X; - case 1: return Operand::OPM_Y; - case 2: return Operand::OPM_Z; - case 3: return Operand::OPM_W; - default: OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Illegal value", "HardwareSkinningTechnique::indexToMask"); - } + switch(index) + { + case 0: return Operand::OPM_X; + case 1: return Operand::OPM_Y; + case 2: return Operand::OPM_Z; + case 3: return Operand::OPM_W; + default: OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Illegal value", "HardwareSkinningTechnique::indexToMask"); + } } //----------------------------------------------------------------------- void HardwareSkinningTechnique::copyFrom(const HardwareSkinningTechnique* hardSkin) { - mWeightCount = hardSkin->mWeightCount; - mBoneCount = hardSkin->mBoneCount; - mDoBoneCalculations = hardSkin->mDoBoneCalculations; - mCorrectAntipodalityHandling = hardSkin->mCorrectAntipodalityHandling; - mScalingShearingSupport = hardSkin->mScalingShearingSupport; + mWeightCount = hardSkin->mWeightCount; + mBoneCount = hardSkin->mBoneCount; + mDoBoneCalculations = hardSkin->mDoBoneCalculations; + mCorrectAntipodalityHandling = hardSkin->mCorrectAntipodalityHandling; + mScalingShearingSupport = hardSkin->mScalingShearingSupport; } } diff --git a/Components/RTShaderSystem/src/OgreShaderExIntegratedPSSM3.cpp b/Components/RTShaderSystem/src/OgreShaderExIntegratedPSSM3.cpp index a36a1f9f89b..777fe19e7fa 100644 --- a/Components/RTShaderSystem/src/OgreShaderExIntegratedPSSM3.cpp +++ b/Components/RTShaderSystem/src/OgreShaderExIntegratedPSSM3.cpp @@ -46,320 +46,320 @@ String IntegratedPSSM3::Type = "SGX_IntegratedPSSM3"; //----------------------------------------------------------------------- IntegratedPSSM3::IntegratedPSSM3() -{ - +{ + } //----------------------------------------------------------------------- const String& IntegratedPSSM3::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int IntegratedPSSM3::getExecutionOrder() const +int IntegratedPSSM3::getExecutionOrder() const { - return FFP_TEXTURING + 1; + return FFP_TEXTURING + 1; } //----------------------------------------------------------------------- void IntegratedPSSM3::updateGpuProgramsParams(Renderable* rend, Pass* pass, - const AutoParamDataSource* source, - const LightList* pLightList) + const AutoParamDataSource* source, + const LightList* pLightList) { - ShadowTextureParamsIterator it = mShadowTextureParamsList.begin(); - size_t shadowIndex = 0; + ShadowTextureParamsIterator it = mShadowTextureParamsList.begin(); + size_t shadowIndex = 0; - while(it != mShadowTextureParamsList.end()) - { - it->mWorldViewProjMatrix->setGpuParameter(source->getTextureWorldViewProjMatrix(shadowIndex)); - it->mInvTextureSize->setGpuParameter(source->getInverseTextureSize(it->mTextureSamplerIndex)); - - ++it; - ++shadowIndex; - } + while(it != mShadowTextureParamsList.end()) + { + it->mWorldViewProjMatrix->setGpuParameter(source->getTextureWorldViewProjMatrix(shadowIndex)); + it->mInvTextureSize->setGpuParameter(source->getInverseTextureSize(it->mTextureSamplerIndex)); + + ++it; + ++shadowIndex; + } - Vector4 vSplitPoints; + Vector4 vSplitPoints; - vSplitPoints.x = mShadowTextureParamsList[0].mMaxRange; - vSplitPoints.y = mShadowTextureParamsList[1].mMaxRange; - vSplitPoints.z = 0.0; - vSplitPoints.w = 0.0; + vSplitPoints.x = mShadowTextureParamsList[0].mMaxRange; + vSplitPoints.y = mShadowTextureParamsList[1].mMaxRange; + vSplitPoints.z = 0.0; + vSplitPoints.w = 0.0; - mPSSplitPoints->setGpuParameter(vSplitPoints); + mPSSplitPoints->setGpuParameter(vSplitPoints); } //----------------------------------------------------------------------- void IntegratedPSSM3::copyFrom(const SubRenderState& rhs) { - const IntegratedPSSM3& rhsPssm= static_cast(rhs); + const IntegratedPSSM3& rhsPssm= static_cast(rhs); - mShadowTextureParamsList.resize(rhsPssm.mShadowTextureParamsList.size()); + mShadowTextureParamsList.resize(rhsPssm.mShadowTextureParamsList.size()); - ShadowTextureParamsConstIterator itSrc = rhsPssm.mShadowTextureParamsList.begin(); - ShadowTextureParamsIterator itDst = mShadowTextureParamsList.begin(); + ShadowTextureParamsConstIterator itSrc = rhsPssm.mShadowTextureParamsList.begin(); + ShadowTextureParamsIterator itDst = mShadowTextureParamsList.begin(); - while(itDst != mShadowTextureParamsList.end()) - { - itDst->mMaxRange = itSrc->mMaxRange; - ++itSrc; - ++itDst; - } + while(itDst != mShadowTextureParamsList.end()) + { + itDst->mMaxRange = itSrc->mMaxRange; + ++itSrc; + ++itDst; + } } //----------------------------------------------------------------------- bool IntegratedPSSM3::preAddToRenderState(const RenderState* renderState, - Pass* srcPass, Pass* dstPass) + Pass* srcPass, Pass* dstPass) { - if (srcPass->getLightingEnabled() == false || - srcPass->getParent()->getParent()->getReceiveShadows() == false) - return false; - - ShadowTextureParamsIterator it = mShadowTextureParamsList.begin(); - - while(it != mShadowTextureParamsList.end()) - { - TextureUnitState* curShadowTexture = dstPass->createTextureUnitState(); - - curShadowTexture->setContentType(TextureUnitState::CONTENT_SHADOW); - curShadowTexture->setTextureAddressingMode(TextureUnitState::TAM_BORDER); - curShadowTexture->setTextureBorderColour(ColourValue::White); - it->mTextureSamplerIndex = dstPass->getNumTextureUnitStates() - 1; - ++it; - } - - - - return true; + if (srcPass->getLightingEnabled() == false || + srcPass->getParent()->getParent()->getReceiveShadows() == false) + return false; + + ShadowTextureParamsIterator it = mShadowTextureParamsList.begin(); + + while(it != mShadowTextureParamsList.end()) + { + TextureUnitState* curShadowTexture = dstPass->createTextureUnitState(); + + curShadowTexture->setContentType(TextureUnitState::CONTENT_SHADOW); + curShadowTexture->setTextureAddressingMode(TextureUnitState::TAM_BORDER); + curShadowTexture->setTextureBorderColour(ColourValue::White); + it->mTextureSamplerIndex = dstPass->getNumTextureUnitStates() - 1; + ++it; + } + + + + return true; } //----------------------------------------------------------------------- void IntegratedPSSM3::setSplitPoints(const SplitPointList& newSplitPoints) { - if (newSplitPoints.size() != 4) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "IntegratedPSSM3 sub render state supports only 4 split points", - "IntegratedPSSM3::setSplitPoints"); - } + if (newSplitPoints.size() != 4) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "IntegratedPSSM3 sub render state supports only 4 split points", + "IntegratedPSSM3::setSplitPoints"); + } - mShadowTextureParamsList.resize(newSplitPoints.size() - 1); + mShadowTextureParamsList.resize(newSplitPoints.size() - 1); - for (unsigned int i=1; i < newSplitPoints.size(); ++i) - { - ShadowTextureParams& curParams = mShadowTextureParamsList[i-1]; + for (unsigned int i=1; i < newSplitPoints.size(); ++i) + { + ShadowTextureParams& curParams = mShadowTextureParamsList[i-1]; - curParams.mMaxRange = newSplitPoints[i]; - } + curParams.mMaxRange = newSplitPoints[i]; + } } //----------------------------------------------------------------------- bool IntegratedPSSM3::resolveParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - - // Get input position parameter. - mVSInPos = vsMain->getParameterBySemantic(vsMain->getInputParameters(), Parameter::SPS_POSITION, 0); - - // Get output position parameter. - mVSOutPos = vsMain->getParameterBySemantic(vsMain->getOutputParameters(), Parameter::SPS_POSITION, 0); - - // Resolve vertex shader output depth. - mVSOutDepth = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::SPC_DEPTH_VIEW_SPACE, - GCT_FLOAT1); - - // Resolve input depth parameter. - mPSInDepth = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSOutDepth->getIndex(), - mVSOutDepth->getContent(), - GCT_FLOAT1); - - // Get in/local diffuse parameter. - mPSDiffuse = psMain->getParameterBySemantic(psMain->getInputParameters(), Parameter::SPS_COLOR, 0); - if (mPSDiffuse.get() == NULL) - { - mPSDiffuse = psMain->getParameterBySemantic(psMain->getLocalParameters(), Parameter::SPS_COLOR, 0); - } - - // Resolve output diffuse parameter. - mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - - // Get in/local specular parameter. - mPSSpecualr = psMain->getParameterBySemantic(psMain->getInputParameters(), Parameter::SPS_COLOR, 1); - if (mPSSpecualr.get() == NULL) - { - mPSSpecualr = psMain->getParameterBySemantic(psMain->getLocalParameters(), Parameter::SPS_COLOR, 1); - } - - // Resolve computed local shadow colour parameter. - mPSLocalShadowFactor = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lShadowFactor", GCT_FLOAT1); - - // Resolve computed local shadow colour parameter. - mPSSplitPoints = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "pssm_split_points"); - - // Get derived scene colour. - mPSDerivedSceneColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, 0); - - ShadowTextureParamsIterator it = mShadowTextureParamsList.begin(); - int lightIndex = 0; - - while(it != mShadowTextureParamsList.end()) - { - it->mWorldViewProjMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_PER_OBJECT, "world_texture_view_proj"); - - it->mVSOutLightPosition = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::Content(Parameter::SPC_POSITION_LIGHT_SPACE0 + lightIndex), - GCT_FLOAT4); - - it->mPSInLightPosition = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - it->mVSOutLightPosition->getIndex(), - it->mVSOutLightPosition->getContent(), - GCT_FLOAT4); - - it->mTextureSampler = psProgram->resolveParameter(GCT_SAMPLER2D, it->mTextureSamplerIndex, (uint16)GPV_GLOBAL, "shadow_map"); - - it->mInvTextureSize = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "inv_shadow_texture_size"); - - if (!(it->mInvTextureSize.get()) || !(it->mTextureSampler.get()) || !(it->mPSInLightPosition.get()) || - !(it->mVSOutLightPosition.get()) || !(it->mWorldViewProjMatrix.get())) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "IntegratedPSSM3::resolveParameters" ); - } - - ++lightIndex; - ++it; - } - - if (!(mVSInPos.get()) || !(mVSOutPos.get()) || !(mVSOutDepth.get()) || !(mPSInDepth.get()) || !(mPSDiffuse.get()) || !(mPSOutDiffuse.get()) || - !(mPSSpecualr.get()) || !(mPSLocalShadowFactor.get()) || !(mPSSplitPoints.get()) || !(mPSDerivedSceneColour.get())) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "IntegratedPSSM3::resolveParameters" ); - } - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + + // Get input position parameter. + mVSInPos = vsMain->getParameterBySemantic(vsMain->getInputParameters(), Parameter::SPS_POSITION, 0); + + // Get output position parameter. + mVSOutPos = vsMain->getParameterBySemantic(vsMain->getOutputParameters(), Parameter::SPS_POSITION, 0); + + // Resolve vertex shader output depth. + mVSOutDepth = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::SPC_DEPTH_VIEW_SPACE, + GCT_FLOAT1); + + // Resolve input depth parameter. + mPSInDepth = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSOutDepth->getIndex(), + mVSOutDepth->getContent(), + GCT_FLOAT1); + + // Get in/local diffuse parameter. + mPSDiffuse = psMain->getParameterBySemantic(psMain->getInputParameters(), Parameter::SPS_COLOR, 0); + if (mPSDiffuse.get() == NULL) + { + mPSDiffuse = psMain->getParameterBySemantic(psMain->getLocalParameters(), Parameter::SPS_COLOR, 0); + } + + // Resolve output diffuse parameter. + mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + + // Get in/local specular parameter. + mPSSpecualr = psMain->getParameterBySemantic(psMain->getInputParameters(), Parameter::SPS_COLOR, 1); + if (mPSSpecualr.get() == NULL) + { + mPSSpecualr = psMain->getParameterBySemantic(psMain->getLocalParameters(), Parameter::SPS_COLOR, 1); + } + + // Resolve computed local shadow colour parameter. + mPSLocalShadowFactor = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lShadowFactor", GCT_FLOAT1); + + // Resolve computed local shadow colour parameter. + mPSSplitPoints = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "pssm_split_points"); + + // Get derived scene colour. + mPSDerivedSceneColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, 0); + + ShadowTextureParamsIterator it = mShadowTextureParamsList.begin(); + int lightIndex = 0; + + while(it != mShadowTextureParamsList.end()) + { + it->mWorldViewProjMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_PER_OBJECT, "world_texture_view_proj"); + + it->mVSOutLightPosition = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::Content(Parameter::SPC_POSITION_LIGHT_SPACE0 + lightIndex), + GCT_FLOAT4); + + it->mPSInLightPosition = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + it->mVSOutLightPosition->getIndex(), + it->mVSOutLightPosition->getContent(), + GCT_FLOAT4); + + it->mTextureSampler = psProgram->resolveParameter(GCT_SAMPLER2D, it->mTextureSamplerIndex, (uint16)GPV_GLOBAL, "shadow_map"); + + it->mInvTextureSize = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "inv_shadow_texture_size"); + + if (!(it->mInvTextureSize.get()) || !(it->mTextureSampler.get()) || !(it->mPSInLightPosition.get()) || + !(it->mVSOutLightPosition.get()) || !(it->mWorldViewProjMatrix.get())) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "IntegratedPSSM3::resolveParameters" ); + } + + ++lightIndex; + ++it; + } + + if (!(mVSInPos.get()) || !(mVSOutPos.get()) || !(mVSOutDepth.get()) || !(mPSInDepth.get()) || !(mPSDiffuse.get()) || !(mPSOutDiffuse.get()) || + !(mPSSpecualr.get()) || !(mPSLocalShadowFactor.get()) || !(mPSSplitPoints.get()) || !(mPSDerivedSceneColour.get())) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "IntegratedPSSM3::resolveParameters" ); + } + + return true; } //----------------------------------------------------------------------- bool IntegratedPSSM3::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); - vsProgram->addDependency(FFP_LIB_COMMON); - - psProgram->addDependency(FFP_LIB_COMMON); - psProgram->addDependency(SGX_LIB_INTEGRATEDPSSM); + vsProgram->addDependency(FFP_LIB_COMMON); + + psProgram->addDependency(FFP_LIB_COMMON); + psProgram->addDependency(SGX_LIB_INTEGRATEDPSSM); - return true; + return true; } //----------------------------------------------------------------------- bool IntegratedPSSM3::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Program* psProgram = programSet->getCpuFragmentProgram(); - int internalCounter; - - // Add vertex shader invocations. - internalCounter = 0; - if (false == addVSInvocation(vsMain, FFP_VS_TEXTURING + 1, internalCounter)) - return false; - - // Add pixel shader invocations. - internalCounter = 0; - if (false == addPSInvocation(psProgram, FFP_PS_COLOUR_BEGIN + 2, internalCounter)) - return false; - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Program* psProgram = programSet->getCpuFragmentProgram(); + int internalCounter; + + // Add vertex shader invocations. + internalCounter = 0; + if (false == addVSInvocation(vsMain, FFP_VS_TEXTURING + 1, internalCounter)) + return false; + + // Add pixel shader invocations. + internalCounter = 0; + if (false == addPSInvocation(psProgram, FFP_PS_COLOUR_BEGIN + 2, internalCounter)) + return false; + + return true; } //----------------------------------------------------------------------- bool IntegratedPSSM3::addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation; + FunctionInvocation* curFuncInvocation; - // Output the vertex depth in camera space. - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSOutPos, Operand::OPS_IN, Operand::OPM_Z); - curFuncInvocation->pushOperand(mVSOutDepth, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); + // Output the vertex depth in camera space. + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSOutPos, Operand::OPS_IN, Operand::OPM_Z); + curFuncInvocation->pushOperand(mVSOutDepth, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); - // Compute world space position. - ShadowTextureParamsIterator it = mShadowTextureParamsList.begin(); + // Compute world space position. + ShadowTextureParamsIterator it = mShadowTextureParamsList.begin(); - while(it != mShadowTextureParamsList.end()) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(it->mWorldViewProjMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(it->mVSOutLightPosition, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); + while(it != mShadowTextureParamsList.end()) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(it->mWorldViewProjMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(it->mVSOutLightPosition, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); - ++it; - } + ++it; + } - return true; + return true; } //----------------------------------------------------------------------- bool IntegratedPSSM3::addPSInvocation(Program* psProgram, const int groupOrder, int& internalCounter) { - Function* psMain = psProgram->getEntryPointFunction(); - FunctionInvocation* curFuncInvocation; - - ShadowTextureParams& splitParams0 = mShadowTextureParamsList[0]; - ShadowTextureParams& splitParams1 = mShadowTextureParamsList[1]; - ShadowTextureParams& splitParams2 = mShadowTextureParamsList[2]; - - // Compute shadow factor. - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_COMPUTE_SHADOW_COLOUR3, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSInDepth, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSSplitPoints, Operand::OPS_IN); - curFuncInvocation->pushOperand(splitParams0.mPSInLightPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(splitParams1.mPSInLightPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(splitParams2.mPSInLightPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(splitParams0.mTextureSampler, Operand::OPS_IN); - curFuncInvocation->pushOperand(splitParams1.mTextureSampler, Operand::OPS_IN); - curFuncInvocation->pushOperand(splitParams2.mTextureSampler, Operand::OPS_IN); - curFuncInvocation->pushOperand(splitParams0.mInvTextureSize, Operand::OPS_IN); - curFuncInvocation->pushOperand(splitParams1.mInvTextureSize, Operand::OPS_IN); - curFuncInvocation->pushOperand(splitParams2.mInvTextureSize, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSLocalShadowFactor, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - // Apply shadow factor on diffuse colour. - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_APPLYSHADOWFACTOR_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDerivedSceneColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSLocalShadowFactor, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - // Apply shadow factor on specular colour. - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_MODULATE_SCALAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSLocalShadowFactor, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSSpecualr, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSSpecualr, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - // Assign the local diffuse to output diffuse. - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - return true; + Function* psMain = psProgram->getEntryPointFunction(); + FunctionInvocation* curFuncInvocation; + + ShadowTextureParams& splitParams0 = mShadowTextureParamsList[0]; + ShadowTextureParams& splitParams1 = mShadowTextureParamsList[1]; + ShadowTextureParams& splitParams2 = mShadowTextureParamsList[2]; + + // Compute shadow factor. + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_COMPUTE_SHADOW_COLOUR3, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSInDepth, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSSplitPoints, Operand::OPS_IN); + curFuncInvocation->pushOperand(splitParams0.mPSInLightPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(splitParams1.mPSInLightPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(splitParams2.mPSInLightPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(splitParams0.mTextureSampler, Operand::OPS_IN); + curFuncInvocation->pushOperand(splitParams1.mTextureSampler, Operand::OPS_IN); + curFuncInvocation->pushOperand(splitParams2.mTextureSampler, Operand::OPS_IN); + curFuncInvocation->pushOperand(splitParams0.mInvTextureSize, Operand::OPS_IN); + curFuncInvocation->pushOperand(splitParams1.mInvTextureSize, Operand::OPS_IN); + curFuncInvocation->pushOperand(splitParams2.mInvTextureSize, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSLocalShadowFactor, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + // Apply shadow factor on diffuse colour. + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_APPLYSHADOWFACTOR_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDerivedSceneColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSLocalShadowFactor, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + // Apply shadow factor on specular colour. + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_MODULATE_SCALAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSLocalShadowFactor, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSSpecualr, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSSpecualr, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + // Assign the local diffuse to output diffuse. + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + return true; } @@ -367,60 +367,60 @@ bool IntegratedPSSM3::addPSInvocation(Program* psProgram, const int groupOrder, //----------------------------------------------------------------------- const String& IntegratedPSSM3Factory::getType() const { - return IntegratedPSSM3::Type; + return IntegratedPSSM3::Type; } //----------------------------------------------------------------------- -SubRenderState* IntegratedPSSM3Factory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* IntegratedPSSM3Factory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "integrated_pssm4") - { - if (prop->values.size() != 4) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - } - else - { - IntegratedPSSM3::SplitPointList splitPointList; - - AbstractNodeList::const_iterator it = prop->values.begin(); - AbstractNodeList::const_iterator itEnd = prop->values.end(); - - while(it != itEnd) - { - Real curSplitValue; - - if (false == SGScriptTranslator::getReal(*it, &curSplitValue)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - break; - } - - splitPointList.push_back(curSplitValue); - - ++it; - } - - if (splitPointList.size() == 4) - { - SubRenderState* subRenderState = createOrRetrieveInstance(translator); - IntegratedPSSM3* pssmSubRenderState = static_cast(subRenderState); - - pssmSubRenderState->setSplitPoints(splitPointList); - - return pssmSubRenderState; - } - } - } - - return NULL; + if (prop->name == "integrated_pssm4") + { + if (prop->values.size() != 4) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + } + else + { + IntegratedPSSM3::SplitPointList splitPointList; + + AbstractNodeList::const_iterator it = prop->values.begin(); + AbstractNodeList::const_iterator itEnd = prop->values.end(); + + while(it != itEnd) + { + Real curSplitValue; + + if (false == SGScriptTranslator::getReal(*it, &curSplitValue)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + break; + } + + splitPointList.push_back(curSplitValue); + + ++it; + } + + if (splitPointList.size() == 4) + { + SubRenderState* subRenderState = createOrRetrieveInstance(translator); + IntegratedPSSM3* pssmSubRenderState = static_cast(subRenderState); + + pssmSubRenderState->setSplitPoints(splitPointList); + + return pssmSubRenderState; + } + } + } + + return NULL; } //----------------------------------------------------------------------- SubRenderState* IntegratedPSSM3Factory::createInstanceImpl() { - return OGRE_NEW IntegratedPSSM3; + return OGRE_NEW IntegratedPSSM3; } } diff --git a/Components/RTShaderSystem/src/OgreShaderExLayeredBlending.cpp b/Components/RTShaderSystem/src/OgreShaderExLayeredBlending.cpp index a2517cc4387..f82e75fc147 100644 --- a/Components/RTShaderSystem/src/OgreShaderExLayeredBlending.cpp +++ b/Components/RTShaderSystem/src/OgreShaderExLayeredBlending.cpp @@ -49,37 +49,37 @@ String LayeredBlending::Type = "LayeredBlendRTSSEx"; }; const BlendModeDescription _blendModes[(int)LayeredBlending::LB_MaxBlendModes] = { - { LayeredBlending::LB_FFPBlend ,"default", ""}, - { LayeredBlending::LB_BlendNormal ,"normal", "SGX_blend_normal"}, - { LayeredBlending::LB_BlendLighten,"lighten", "SGX_blend_lighten"}, - { LayeredBlending::LB_BlendDarken ,"darken", "SGX_blend_darken"}, - { LayeredBlending::LB_BlendMultiply ,"multiply", "SGX_blend_multiply"}, - { LayeredBlending::LB_BlendAverage ,"average", "SGX_blend_average"}, - { LayeredBlending::LB_BlendAdd ,"add", "SGX_blend_add"}, - { LayeredBlending::LB_BlendSubtract ,"subtract", "SGX_blend_subtract"}, - { LayeredBlending::LB_BlendDifference ,"difference", "SGX_blend_difference"}, - { LayeredBlending::LB_BlendNegation ,"negation", "SGX_blend_negation"}, - { LayeredBlending::LB_BlendExclusion ,"exclusion", "SGX_blend_exclusion"}, - { LayeredBlending::LB_BlendScreen ,"screen", "SGX_blend_screen"}, - { LayeredBlending::LB_BlendOverlay ,"overlay", "SGX_blend_overlay"}, - { LayeredBlending::LB_BlendHardLight ,"hard_light", "SGX_blend_hardLight"}, - { LayeredBlending::LB_BlendSoftLight ,"soft_light", "SGX_blend_softLight"}, - { LayeredBlending::LB_BlendColorDodge ,"color_dodge", "SGX_blend_colorDodge"}, - { LayeredBlending::LB_BlendColorBurn ,"color_burn", "SGX_blend_colorBurn"}, - { LayeredBlending::LB_BlendLinearDodge ,"linear_dodge", "SGX_blend_linearDodge"}, - { LayeredBlending::LB_BlendLinearBurn ,"linear_burn", "SGX_blend_linearBurn"}, - { LayeredBlending::LB_BlendLinearLight ,"linear_light", "SGX_blend_linearLight"}, - { LayeredBlending::LB_BlendVividLight ,"vivid_light", "SGX_blend_vividLight"}, - { LayeredBlending::LB_BlendPinLight ,"pin_light", "SGX_blend_pinLight"}, - { LayeredBlending::LB_BlendHardMix ,"hard_mix", "SGX_blend_hardMix"}, - { LayeredBlending::LB_BlendReflect ,"reflect", "SGX_blend_reflect"}, - { LayeredBlending::LB_BlendGlow ,"glow", "SGX_blend_glow"}, - { LayeredBlending::LB_BlendPhoenix ,"phoenix", "SGX_blend_phoenix"}, - { LayeredBlending::LB_BlendSaturation ,"saturation", "SGX_blend_saturation"}, - { LayeredBlending::LB_BlendColor ,"color", "SGX_blend_color"}, - { LayeredBlending::LB_BlendLuminosity, "luminosity", "SGX_blend_luminosity"} - }; - + { LayeredBlending::LB_FFPBlend ,"default", ""}, + { LayeredBlending::LB_BlendNormal ,"normal", "SGX_blend_normal"}, + { LayeredBlending::LB_BlendLighten,"lighten", "SGX_blend_lighten"}, + { LayeredBlending::LB_BlendDarken ,"darken", "SGX_blend_darken"}, + { LayeredBlending::LB_BlendMultiply ,"multiply", "SGX_blend_multiply"}, + { LayeredBlending::LB_BlendAverage ,"average", "SGX_blend_average"}, + { LayeredBlending::LB_BlendAdd ,"add", "SGX_blend_add"}, + { LayeredBlending::LB_BlendSubtract ,"subtract", "SGX_blend_subtract"}, + { LayeredBlending::LB_BlendDifference ,"difference", "SGX_blend_difference"}, + { LayeredBlending::LB_BlendNegation ,"negation", "SGX_blend_negation"}, + { LayeredBlending::LB_BlendExclusion ,"exclusion", "SGX_blend_exclusion"}, + { LayeredBlending::LB_BlendScreen ,"screen", "SGX_blend_screen"}, + { LayeredBlending::LB_BlendOverlay ,"overlay", "SGX_blend_overlay"}, + { LayeredBlending::LB_BlendHardLight ,"hard_light", "SGX_blend_hardLight"}, + { LayeredBlending::LB_BlendSoftLight ,"soft_light", "SGX_blend_softLight"}, + { LayeredBlending::LB_BlendColorDodge ,"color_dodge", "SGX_blend_colorDodge"}, + { LayeredBlending::LB_BlendColorBurn ,"color_burn", "SGX_blend_colorBurn"}, + { LayeredBlending::LB_BlendLinearDodge ,"linear_dodge", "SGX_blend_linearDodge"}, + { LayeredBlending::LB_BlendLinearBurn ,"linear_burn", "SGX_blend_linearBurn"}, + { LayeredBlending::LB_BlendLinearLight ,"linear_light", "SGX_blend_linearLight"}, + { LayeredBlending::LB_BlendVividLight ,"vivid_light", "SGX_blend_vividLight"}, + { LayeredBlending::LB_BlendPinLight ,"pin_light", "SGX_blend_pinLight"}, + { LayeredBlending::LB_BlendHardMix ,"hard_mix", "SGX_blend_hardMix"}, + { LayeredBlending::LB_BlendReflect ,"reflect", "SGX_blend_reflect"}, + { LayeredBlending::LB_BlendGlow ,"glow", "SGX_blend_glow"}, + { LayeredBlending::LB_BlendPhoenix ,"phoenix", "SGX_blend_phoenix"}, + { LayeredBlending::LB_BlendSaturation ,"saturation", "SGX_blend_saturation"}, + { LayeredBlending::LB_BlendColor ,"color", "SGX_blend_color"}, + { LayeredBlending::LB_BlendLuminosity, "luminosity", "SGX_blend_luminosity"} + }; + struct SourceModifierDescription { /* Type of the source modifier*/ @@ -91,12 +91,12 @@ const BlendModeDescription _blendModes[(int)LayeredBlending::LB_MaxBlendModes] = }; const SourceModifierDescription _sourceModifiers[(int)LayeredBlending::SM_MaxSourceModifiers] = { - { LayeredBlending::SM_None ,""}, - { LayeredBlending::SM_Source1Modulate ,"src1_modulate"}, - { LayeredBlending::SM_Source2Modulate ,"src2_modulate"}, - { LayeredBlending::SM_Source1InvModulate ,"src1_inverse_modulate"}, - { LayeredBlending::SM_Source2InvModulate ,"src2_inverse_modulate"} - }; + { LayeredBlending::SM_None ,""}, + { LayeredBlending::SM_Source1Modulate ,"src1_modulate"}, + { LayeredBlending::SM_Source2Modulate ,"src2_modulate"}, + { LayeredBlending::SM_Source1InvModulate ,"src1_inverse_modulate"}, + { LayeredBlending::SM_Source2InvModulate ,"src2_inverse_modulate"} + }; //----------------------------------------------------------------------- LayeredBlending::LayeredBlending() { @@ -106,7 +106,7 @@ LayeredBlending::LayeredBlending() //----------------------------------------------------------------------- const Ogre::String& LayeredBlending::getType() const { - return Type; + return Type; } @@ -114,32 +114,32 @@ const Ogre::String& LayeredBlending::getType() const bool LayeredBlending::resolveParameters(ProgramSet* programSet) { - //resolve peremeter for normal texturing procedures - bool isSuccess = FFPTexturing::resolveParameters(programSet); - - if (isSuccess) - { - //resolve source modification parameters - Program* psProgram = programSet->getCpuFragmentProgram(); - - for(size_t i = mTextureBlends.size() - 1; i != (size_t)-1 ; --i) - { - TextureBlend& texBlend = mTextureBlends[i]; - if ((texBlend.sourceModifier != SM_Invalid) && - (texBlend.sourceModifier != SM_None)) - { - - texBlend.modControlParam = psProgram->resolveAutoParameterInt( - GpuProgramParameters::ACT_CUSTOM, texBlend.customNum); - if (texBlend.modControlParam.get() == NULL) - { - isSuccess = false; - break; - } - } - } - } - return isSuccess; + //resolve peremeter for normal texturing procedures + bool isSuccess = FFPTexturing::resolveParameters(programSet); + + if (isSuccess) + { + //resolve source modification parameters + Program* psProgram = programSet->getCpuFragmentProgram(); + + for(size_t i = mTextureBlends.size() - 1; i != (size_t)-1 ; --i) + { + TextureBlend& texBlend = mTextureBlends[i]; + if ((texBlend.sourceModifier != SM_Invalid) && + (texBlend.sourceModifier != SM_None)) + { + + texBlend.modControlParam = psProgram->resolveAutoParameterInt( + GpuProgramParameters::ACT_CUSTOM, texBlend.customNum); + if (texBlend.modControlParam.get() == NULL) + { + isSuccess = false; + break; + } + } + } + } + return isSuccess; } @@ -147,170 +147,170 @@ bool LayeredBlending::resolveParameters(ProgramSet* programSet) //----------------------------------------------------------------------- bool LayeredBlending::resolveDependencies(ProgramSet* programSet) { - FFPTexturing::resolveDependencies(programSet); - Program* psProgram = programSet->getCpuFragmentProgram(); + FFPTexturing::resolveDependencies(programSet); + Program* psProgram = programSet->getCpuFragmentProgram(); - psProgram->addDependency(SGX_LIB_LAYEREDBLENDING); + psProgram->addDependency(SGX_LIB_LAYEREDBLENDING); - return true; + return true; } //----------------------------------------------------------------------- void LayeredBlending::copyFrom(const SubRenderState& rhs) { - FFPTexturing::copyFrom(rhs); - - const LayeredBlending& rhsTexture = static_cast(rhs); - mTextureBlends = rhsTexture.mTextureBlends; + FFPTexturing::copyFrom(rhs); + + const LayeredBlending& rhsTexture = static_cast(rhs); + mTextureBlends = rhsTexture.mTextureBlends; } //----------------------------------------------------------------------- void LayeredBlending::addPSBlendInvocations(Function* psMain, - ParameterPtr arg1, - ParameterPtr arg2, - ParameterPtr texel, - int samplerIndex, - const LayerBlendModeEx& blendMode, - const int groupOrder, - int& internalCounter, - int targetChannels) + ParameterPtr arg1, + ParameterPtr arg2, + ParameterPtr texel, + int samplerIndex, + const LayerBlendModeEx& blendMode, + const int groupOrder, + int& internalCounter, + int targetChannels) { - // - // Add the modifier invocation - // - - addPSModifierInvocation(psMain, samplerIndex, arg1, arg2, groupOrder, internalCounter, targetChannels); - - // - // Add the blending function invocations - // - - BlendMode mode = getBlendMode(samplerIndex); - - if ((LB_FFPBlend == mode) || (LB_Invalid == mode)) - { - FFPTexturing::addPSBlendInvocations(psMain, arg1, arg2, texel, samplerIndex, blendMode, groupOrder, internalCounter, targetChannels); - } - else - { - //find the function name for the blend mode - String funcName; - for(int i = 0 ; i < (int)LayeredBlending::LB_MaxBlendModes ; ++i) - { - if (_blendModes[i].type == mode) - { - funcName = _blendModes[i].funcName; - break; - } - } - - //add the function of the blend mode - if (funcName.empty() == false) - { - FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(funcName, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - } - } + // + // Add the modifier invocation + // + + addPSModifierInvocation(psMain, samplerIndex, arg1, arg2, groupOrder, internalCounter, targetChannels); + + // + // Add the blending function invocations + // + + BlendMode mode = getBlendMode(samplerIndex); + + if ((LB_FFPBlend == mode) || (LB_Invalid == mode)) + { + FFPTexturing::addPSBlendInvocations(psMain, arg1, arg2, texel, samplerIndex, blendMode, groupOrder, internalCounter, targetChannels); + } + else + { + //find the function name for the blend mode + String funcName; + for(int i = 0 ; i < (int)LayeredBlending::LB_MaxBlendModes ; ++i) + { + if (_blendModes[i].type == mode) + { + funcName = _blendModes[i].funcName; + break; + } + } + + //add the function of the blend mode + if (funcName.empty() == false) + { + FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(funcName, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + } + } } //----------------------------------------------------------------------- void LayeredBlending::addPSModifierInvocation(Function* psMain, - int samplerIndex, - ParameterPtr arg1, - ParameterPtr arg2, - const int groupOrder, - int& internalCounter, - int targetChannels) + int samplerIndex, + ParameterPtr arg1, + ParameterPtr arg2, + const int groupOrder, + int& internalCounter, + int targetChannels) { - SourceModifier modType; - int customNum; - if (getSourceModifier(samplerIndex, modType, customNum) == true) - { - ParameterPtr modifiedParam; - String funcName; - switch (modType) - { - case SM_Source1Modulate: - funcName = "SGX_src_mod_modulate"; - modifiedParam = arg1; - break; - case SM_Source2Modulate: - funcName = "SGX_src_mod_modulate"; - modifiedParam = arg2; - break; - case SM_Source1InvModulate: - funcName = "SGX_src_mod_inv_modulate"; - modifiedParam = arg1; - break; - case SM_Source2InvModulate: - funcName = "SGX_src_mod_inv_modulate"; - modifiedParam = arg2; - break; - default: - break; - } - - //add the function of the blend mode - if (funcName.empty() == false) - { - ParameterPtr& controlParam = mTextureBlends[samplerIndex].modControlParam; - - FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(funcName, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(modifiedParam, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(controlParam, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(modifiedParam, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - } - } + SourceModifier modType; + int customNum; + if (getSourceModifier(samplerIndex, modType, customNum) == true) + { + ParameterPtr modifiedParam; + String funcName; + switch (modType) + { + case SM_Source1Modulate: + funcName = "SGX_src_mod_modulate"; + modifiedParam = arg1; + break; + case SM_Source2Modulate: + funcName = "SGX_src_mod_modulate"; + modifiedParam = arg2; + break; + case SM_Source1InvModulate: + funcName = "SGX_src_mod_inv_modulate"; + modifiedParam = arg1; + break; + case SM_Source2InvModulate: + funcName = "SGX_src_mod_inv_modulate"; + modifiedParam = arg2; + break; + default: + break; + } + + //add the function of the blend mode + if (funcName.empty() == false) + { + ParameterPtr& controlParam = mTextureBlends[samplerIndex].modControlParam; + + FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(funcName, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(modifiedParam, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(controlParam, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(modifiedParam, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + } + } } //----------------------------------------------------------------------- void LayeredBlending::setBlendMode(unsigned short index, BlendMode mode) { - if(mTextureBlends.size() < (size_t)index + 1) - { - mTextureBlends.resize(index + 1); - } - mTextureBlends[index].blendMode = mode; + if(mTextureBlends.size() < (size_t)index + 1) + { + mTextureBlends.resize(index + 1); + } + mTextureBlends[index].blendMode = mode; } //----------------------------------------------------------------------- LayeredBlending::BlendMode LayeredBlending::getBlendMode(unsigned short index) const { - if(index < mTextureBlends.size()) - { - return mTextureBlends[index].blendMode; - } - return LB_Invalid; + if(index < mTextureBlends.size()) + { + return mTextureBlends[index].blendMode; + } + return LB_Invalid; } //----------------------------------------------------------------------- void LayeredBlending::setSourceModifier(unsigned short index, SourceModifier modType, int customNum) { - if(mTextureBlends.size() < (size_t)index + 1) - { - mTextureBlends.resize(index + 1); - } - mTextureBlends[index].sourceModifier = modType; - mTextureBlends[index].customNum = customNum; + if(mTextureBlends.size() < (size_t)index + 1) + { + mTextureBlends.resize(index + 1); + } + mTextureBlends[index].sourceModifier = modType; + mTextureBlends[index].customNum = customNum; } //----------------------------------------------------------------------- bool LayeredBlending::getSourceModifier(unsigned short index, SourceModifier& modType, int& customNum) const { - modType = SM_Invalid; - customNum = 0; - if(index < mTextureBlends.size()) - { - modType = mTextureBlends[index].sourceModifier; - customNum = mTextureBlends[index].customNum; - } - return (modType != SM_Invalid); + modType = SM_Invalid; + customNum = 0; + if(index < mTextureBlends.size()) + { + modType = mTextureBlends[index].sourceModifier; + customNum = mTextureBlends[index].customNum; + } + return (modType != SM_Invalid); } @@ -318,213 +318,213 @@ bool LayeredBlending::getSourceModifier(unsigned short index, SourceModifier& mo //----------------------------------------------------------------------- const String& LayeredBlendingFactory::getType() const { - return LayeredBlending::Type; + return LayeredBlending::Type; } //----------------------------------------------------------------------- -SubRenderState* LayeredBlendingFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator) +SubRenderState* LayeredBlendingFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator) { - if (prop->name == "layered_blend") - { - String blendType; - if(false == SGScriptTranslator::getString(prop->values.front(), &blendType)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - return NULL; - } - - LayeredBlending::BlendMode blendMode = stringToBlendMode(blendType); - if (blendMode == LayeredBlending::LB_Invalid) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, - "Expected one of the following blend modes: default, normal, " \ - "lighten, darken, multiply, average, add, " \ - "subtract, difference, negation, exclusion, " \ - "screen, overlay, hard_light, soft_light, " \ - "color_dodge, color_burn, linear_dodge, linear_burn, " \ - "linear_light, vivid_light, pin_light, hard_mix, " \ - "reflect, glow, phoenix, saturation, color and luminosity"); - return NULL; - } - - - //get the layer blend sub-render state to work on - LayeredBlending* layeredBlendState = - createOrRetrieveSubRenderState(translator); - - //update the layer sub render state - unsigned short texIndex = texState->getParent()->getTextureUnitStateIndex(texState); - layeredBlendState->setBlendMode(texIndex, blendMode); - - return layeredBlendState; - } - if (prop->name == "source_modifier") - { - if(prop->values.size() < 3) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, - "Expected three or more parameters."); - return NULL; - } - - // Read light model type. - bool isParseSuccess; - String modifierString; - String paramType; - int customNum; - - AbstractNodeList::const_iterator itValue = prop->values.begin(); - isParseSuccess = SGScriptTranslator::getString(*itValue, &modifierString); - LayeredBlending::SourceModifier modType = stringToSourceModifier(modifierString); - isParseSuccess &= modType != LayeredBlending::SM_Invalid; - if(isParseSuccess == false) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, - "Expected one of the following modifier type as first parameter: " \ - "src1_modulate, src2_modulate, src1_inverse_modulate, src2_inverse_modulate."); - return NULL; - } - - ++itValue; - isParseSuccess = SGScriptTranslator::getString(*itValue, ¶mType); - isParseSuccess &= (paramType == "custom"); - if(isParseSuccess == false) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, - "Expected reserved word custom as second parameter."); - return NULL; - } - ++itValue; - isParseSuccess = SGScriptTranslator::getInt(*itValue, &customNum); - if(isParseSuccess == false) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, - "Expected number of custom parameter as third parameter."); - return NULL; - } - - //get the layer blend sub-render state to work on - LayeredBlending* layeredBlendState = - createOrRetrieveSubRenderState(translator); - - //update the layer sub render state - unsigned short texIndex = texState->getParent()->getTextureUnitStateIndex(texState); - layeredBlendState->setSourceModifier(texIndex, modType, customNum); - - return layeredBlendState; - - } - - return NULL; - + if (prop->name == "layered_blend") + { + String blendType; + if(false == SGScriptTranslator::getString(prop->values.front(), &blendType)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + return NULL; + } + + LayeredBlending::BlendMode blendMode = stringToBlendMode(blendType); + if (blendMode == LayeredBlending::LB_Invalid) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, + "Expected one of the following blend modes: default, normal, " \ + "lighten, darken, multiply, average, add, " \ + "subtract, difference, negation, exclusion, " \ + "screen, overlay, hard_light, soft_light, " \ + "color_dodge, color_burn, linear_dodge, linear_burn, " \ + "linear_light, vivid_light, pin_light, hard_mix, " \ + "reflect, glow, phoenix, saturation, color and luminosity"); + return NULL; + } + + + //get the layer blend sub-render state to work on + LayeredBlending* layeredBlendState = + createOrRetrieveSubRenderState(translator); + + //update the layer sub render state + unsigned short texIndex = texState->getParent()->getTextureUnitStateIndex(texState); + layeredBlendState->setBlendMode(texIndex, blendMode); + + return layeredBlendState; + } + if (prop->name == "source_modifier") + { + if(prop->values.size() < 3) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, + "Expected three or more parameters."); + return NULL; + } + + // Read light model type. + bool isParseSuccess; + String modifierString; + String paramType; + int customNum; + + AbstractNodeList::const_iterator itValue = prop->values.begin(); + isParseSuccess = SGScriptTranslator::getString(*itValue, &modifierString); + LayeredBlending::SourceModifier modType = stringToSourceModifier(modifierString); + isParseSuccess &= modType != LayeredBlending::SM_Invalid; + if(isParseSuccess == false) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, + "Expected one of the following modifier type as first parameter: " \ + "src1_modulate, src2_modulate, src1_inverse_modulate, src2_inverse_modulate."); + return NULL; + } + + ++itValue; + isParseSuccess = SGScriptTranslator::getString(*itValue, ¶mType); + isParseSuccess &= (paramType == "custom"); + if(isParseSuccess == false) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, + "Expected reserved word custom as second parameter."); + return NULL; + } + ++itValue; + isParseSuccess = SGScriptTranslator::getInt(*itValue, &customNum); + if(isParseSuccess == false) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line, + "Expected number of custom parameter as third parameter."); + return NULL; + } + + //get the layer blend sub-render state to work on + LayeredBlending* layeredBlendState = + createOrRetrieveSubRenderState(translator); + + //update the layer sub render state + unsigned short texIndex = texState->getParent()->getTextureUnitStateIndex(texState); + layeredBlendState->setSourceModifier(texIndex, modType, customNum); + + return layeredBlendState; + + } + + return NULL; + } //----------------------------------------------------------------------- void LayeredBlendingFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, - const TextureUnitState* srcTextureState, const TextureUnitState* dstTextureState) + const TextureUnitState* srcTextureState, const TextureUnitState* dstTextureState) { - unsigned short texIndex = srcTextureState->getParent()-> - getTextureUnitStateIndex(srcTextureState); - - //get blend mode for current texture unit - LayeredBlending* layeredBlendingSubRenderState = static_cast(subRenderState); - - //write the blend mode - LayeredBlending::BlendMode blendMode = layeredBlendingSubRenderState->getBlendMode(texIndex); - if (blendMode != LayeredBlending::LB_Invalid) - { - ser->writeAttribute(5, "layered_blend"); - ser->writeValue(blendModeToString(blendMode)); - } - - //write the source modifier - LayeredBlending::SourceModifier modType; - int customNum; - if (layeredBlendingSubRenderState->getSourceModifier(texIndex, modType, customNum) == true) - { - ser->writeAttribute(5, "source_modifier"); - ser->writeValue(sourceModifierToString(modType)); - ser->writeValue("custom"); - ser->writeValue(StringConverter::toString(customNum)); - } + unsigned short texIndex = srcTextureState->getParent()-> + getTextureUnitStateIndex(srcTextureState); + + //get blend mode for current texture unit + LayeredBlending* layeredBlendingSubRenderState = static_cast(subRenderState); + + //write the blend mode + LayeredBlending::BlendMode blendMode = layeredBlendingSubRenderState->getBlendMode(texIndex); + if (blendMode != LayeredBlending::LB_Invalid) + { + ser->writeAttribute(5, "layered_blend"); + ser->writeValue(blendModeToString(blendMode)); + } + + //write the source modifier + LayeredBlending::SourceModifier modType; + int customNum; + if (layeredBlendingSubRenderState->getSourceModifier(texIndex, modType, customNum) == true) + { + ser->writeAttribute(5, "source_modifier"); + ser->writeValue(sourceModifierToString(modType)); + ser->writeValue("custom"); + ser->writeValue(StringConverter::toString(customNum)); + } } //----------------------------------------------------------------------- -SubRenderState* LayeredBlendingFactory::createInstanceImpl() +SubRenderState* LayeredBlendingFactory::createInstanceImpl() { - return OGRE_NEW LayeredBlending; + return OGRE_NEW LayeredBlending; } //----------------------------------------------------------------------- LayeredBlending::BlendMode LayeredBlendingFactory::stringToBlendMode(const String &strValue) { - for(int i = 0 ; i < (int)LayeredBlending::LB_MaxBlendModes ; ++i) - { - if (_blendModes[i].name == strValue) - { - return _blendModes[i].type; - } - } - return LayeredBlending::LB_Invalid; + for(int i = 0 ; i < (int)LayeredBlending::LB_MaxBlendModes ; ++i) + { + if (_blendModes[i].name == strValue) + { + return _blendModes[i].type; + } + } + return LayeredBlending::LB_Invalid; } //----------------------------------------------------------------------- String LayeredBlendingFactory::blendModeToString(LayeredBlending::BlendMode blendMode) { - for(int i = 0 ; i < (int)LayeredBlending::LB_MaxBlendModes ; ++i) - { - if (_blendModes[i].type == blendMode) - { - return _blendModes[i].name; - } - } - return ""; + for(int i = 0 ; i < (int)LayeredBlending::LB_MaxBlendModes ; ++i) + { + if (_blendModes[i].type == blendMode) + { + return _blendModes[i].name; + } + } + return ""; } //----------------------------------------------------------------------- LayeredBlending::SourceModifier LayeredBlendingFactory::stringToSourceModifier(const String &strValue) { - for(int i = 0 ; i < (int)LayeredBlending::SM_MaxSourceModifiers ; ++i) - { - if (_sourceModifiers[i].name == strValue) - { - return _sourceModifiers[i].type; - } - } - return LayeredBlending::SM_Invalid; + for(int i = 0 ; i < (int)LayeredBlending::SM_MaxSourceModifiers ; ++i) + { + if (_sourceModifiers[i].name == strValue) + { + return _sourceModifiers[i].type; + } + } + return LayeredBlending::SM_Invalid; } //----------------------------------------------------------------------- String LayeredBlendingFactory::sourceModifierToString(LayeredBlending::SourceModifier modifier) { - for(int i = 0 ; i < (int)LayeredBlending::SM_MaxSourceModifiers ; ++i) - { - if (_sourceModifiers[i].type == modifier) - { - return _sourceModifiers[i].name; - } - } - return ""; + for(int i = 0 ; i < (int)LayeredBlending::SM_MaxSourceModifiers ; ++i) + { + if (_sourceModifiers[i].type == modifier) + { + return _sourceModifiers[i].name; + } + } + return ""; } //----------------------------------------------------------------------- LayeredBlending* LayeredBlendingFactory::createOrRetrieveSubRenderState(SGScriptTranslator* translator) { - LayeredBlending* layeredBlendState; - //check if we already create a blend srs - SubRenderState* subState = translator->getGeneratedSubRenderState(getType()); - if (subState != NULL) - { - layeredBlendState = static_cast(subState); - } - else - { - SubRenderState* subRenderState = createOrRetrieveInstance(translator); - layeredBlendState = static_cast(subRenderState); - } - return layeredBlendState; + LayeredBlending* layeredBlendState; + //check if we already create a blend srs + SubRenderState* subState = translator->getGeneratedSubRenderState(getType()); + if (subState != NULL) + { + layeredBlendState = static_cast(subState); + } + else + { + SubRenderState* subRenderState = createOrRetrieveInstance(translator); + layeredBlendState = static_cast(subRenderState); + } + return layeredBlendState; } diff --git a/Components/RTShaderSystem/src/OgreShaderExLinearSkinning.cpp b/Components/RTShaderSystem/src/OgreShaderExLinearSkinning.cpp index 5f44c4e120c..774dd915ad5 100644 --- a/Components/RTShaderSystem/src/OgreShaderExLinearSkinning.cpp +++ b/Components/RTShaderSystem/src/OgreShaderExLinearSkinning.cpp @@ -52,297 +52,297 @@ LinearSkinning::LinearSkinning() : HardwareSkinningTechnique() bool LinearSkinning::resolveParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - - //if needed mark this vertex program as hardware skinned - if (mDoBoneCalculations == true) - { - vsProgram->setSkeletalAnimationIncluded(true); - } - - // - // get the parameters we need whether we are doing bone calculations or not - // - // Note: in order to be consistent we will always output position, normal, - // tangent and binormal in both object and world space. And output position - // in projective space to cover the responsibility of the transform stage - - //input param - mParamInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - mParamInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - mParamInBiNormal = vsMain->resolveInputParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_OBJECT_SPACE, GCT_FLOAT3); - mParamInTangent = vsMain->resolveInputParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_OBJECT_SPACE, GCT_FLOAT3); - - //local param - mParamLocalPositionWorld = vsMain->resolveLocalParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT4); - mParamLocalNormalWorld = vsMain->resolveLocalParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_WORLD_SPACE, GCT_FLOAT3); - mParamLocalTangentWorld = vsMain->resolveLocalParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_WORLD_SPACE, GCT_FLOAT3); - mParamLocalBinormalWorld = vsMain->resolveLocalParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_WORLD_SPACE, GCT_FLOAT3); - - //output param - mParamOutPositionProj = vsMain->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); - - //check if parameter retrival went well - bool isValid = - (mParamInPosition.get() != NULL) && - (mParamInNormal.get() != NULL) && - (mParamInBiNormal.get() != NULL) && - (mParamInTangent.get() != NULL) && - (mParamLocalPositionWorld.get() != NULL) && - (mParamLocalNormalWorld.get() != NULL) && - (mParamLocalTangentWorld.get() != NULL) && - (mParamLocalBinormalWorld.get() != NULL) && - (mParamOutPositionProj.get() != NULL); - - - if (mDoBoneCalculations == true) - { - if (ShaderGenerator::getSingleton().getTargetLanguage() == "hlsl") - { - //set hlsl shader to use row-major matrices instead of column-major. - //it enables the use of 3x4 matrices in hlsl shader instead of full 4x4 matrix. - vsProgram->setUseColumnMajorMatrices(false); - } - - //input parameters - mParamInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - mParamInBiNormal = vsMain->resolveInputParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_OBJECT_SPACE, GCT_FLOAT3); - mParamInTangent = vsMain->resolveInputParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_OBJECT_SPACE, GCT_FLOAT3); - mParamInIndices = vsMain->resolveInputParameter(Parameter::SPS_BLEND_INDICES, 0, Parameter::SPC_UNKNOWN, GCT_FLOAT4); - mParamInWeights = vsMain->resolveInputParameter(Parameter::SPS_BLEND_WEIGHTS, 0, Parameter::SPC_UNKNOWN, GCT_FLOAT4); - mParamInWorldMatrices = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4, 0, mBoneCount); - mParamInInvWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_WORLD_MATRIX, 0); - mParamInViewProjMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEWPROJ_MATRIX, 0); - - mParamTempFloat4 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal4", GCT_FLOAT4); - mParamTempFloat3 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal3", GCT_FLOAT3); - - //check if parameter retrival went well - isValid &= - (mParamInIndices.get() != NULL) && - (mParamInWeights.get() != NULL) && - (mParamInWorldMatrices.get() != NULL) && - (mParamInViewProjMatrix.get() != NULL) && - (mParamInInvWorldMatrix.get() != NULL) && - (mParamTempFloat4.get() != NULL) && - (mParamTempFloat3.get() != NULL); - } - else - { - mParamInWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - mParamInWorldViewProjMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); - - //check if parameter retrival went well - isValid &= - (mParamInWorldMatrix.get() != NULL) && - (mParamInWorldViewProjMatrix.get() != NULL); - } - return isValid; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + + //if needed mark this vertex program as hardware skinned + if (mDoBoneCalculations == true) + { + vsProgram->setSkeletalAnimationIncluded(true); + } + + // + // get the parameters we need whether we are doing bone calculations or not + // + // Note: in order to be consistent we will always output position, normal, + // tangent and binormal in both object and world space. And output position + // in projective space to cover the responsibility of the transform stage + + //input param + mParamInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + mParamInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + mParamInBiNormal = vsMain->resolveInputParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_OBJECT_SPACE, GCT_FLOAT3); + mParamInTangent = vsMain->resolveInputParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_OBJECT_SPACE, GCT_FLOAT3); + + //local param + mParamLocalPositionWorld = vsMain->resolveLocalParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT4); + mParamLocalNormalWorld = vsMain->resolveLocalParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_WORLD_SPACE, GCT_FLOAT3); + mParamLocalTangentWorld = vsMain->resolveLocalParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_WORLD_SPACE, GCT_FLOAT3); + mParamLocalBinormalWorld = vsMain->resolveLocalParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_WORLD_SPACE, GCT_FLOAT3); + + //output param + mParamOutPositionProj = vsMain->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); + + //check if parameter retrival went well + bool isValid = + (mParamInPosition.get() != NULL) && + (mParamInNormal.get() != NULL) && + (mParamInBiNormal.get() != NULL) && + (mParamInTangent.get() != NULL) && + (mParamLocalPositionWorld.get() != NULL) && + (mParamLocalNormalWorld.get() != NULL) && + (mParamLocalTangentWorld.get() != NULL) && + (mParamLocalBinormalWorld.get() != NULL) && + (mParamOutPositionProj.get() != NULL); + + + if (mDoBoneCalculations == true) + { + if (ShaderGenerator::getSingleton().getTargetLanguage() == "hlsl") + { + //set hlsl shader to use row-major matrices instead of column-major. + //it enables the use of 3x4 matrices in hlsl shader instead of full 4x4 matrix. + vsProgram->setUseColumnMajorMatrices(false); + } + + //input parameters + mParamInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + mParamInBiNormal = vsMain->resolveInputParameter(Parameter::SPS_BINORMAL, 0, Parameter::SPC_BINORMAL_OBJECT_SPACE, GCT_FLOAT3); + mParamInTangent = vsMain->resolveInputParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_OBJECT_SPACE, GCT_FLOAT3); + mParamInIndices = vsMain->resolveInputParameter(Parameter::SPS_BLEND_INDICES, 0, Parameter::SPC_UNKNOWN, GCT_FLOAT4); + mParamInWeights = vsMain->resolveInputParameter(Parameter::SPS_BLEND_WEIGHTS, 0, Parameter::SPC_UNKNOWN, GCT_FLOAT4); + mParamInWorldMatrices = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4, 0, mBoneCount); + mParamInInvWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_WORLD_MATRIX, 0); + mParamInViewProjMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEWPROJ_MATRIX, 0); + + mParamTempFloat4 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal4", GCT_FLOAT4); + mParamTempFloat3 = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "TempVal3", GCT_FLOAT3); + + //check if parameter retrival went well + isValid &= + (mParamInIndices.get() != NULL) && + (mParamInWeights.get() != NULL) && + (mParamInWorldMatrices.get() != NULL) && + (mParamInViewProjMatrix.get() != NULL) && + (mParamInInvWorldMatrix.get() != NULL) && + (mParamTempFloat4.get() != NULL) && + (mParamTempFloat3.get() != NULL); + } + else + { + mParamInWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + mParamInWorldViewProjMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); + + //check if parameter retrival went well + isValid &= + (mParamInWorldMatrix.get() != NULL) && + (mParamInWorldViewProjMatrix.get() != NULL); + } + return isValid; } //----------------------------------------------------------------------- bool LinearSkinning::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - vsProgram->addDependency(FFP_LIB_COMMON); - vsProgram->addDependency(FFP_LIB_TRANSFORM); + Program* vsProgram = programSet->getCpuVertexProgram(); + vsProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(FFP_LIB_TRANSFORM); - return true; + return true; } //----------------------------------------------------------------------- bool LinearSkinning::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - int internalCounter = 0; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + int internalCounter = 0; - //add functions to calculate position data in world, object and projective space - addPositionCalculations(vsMain, internalCounter); + //add functions to calculate position data in world, object and projective space + addPositionCalculations(vsMain, internalCounter); - //add functions to calculate normal and normal related data in world and object space - addNormalRelatedCalculations(vsMain, mParamInNormal, mParamLocalNormalWorld, internalCounter); - addNormalRelatedCalculations(vsMain, mParamInTangent, mParamLocalTangentWorld, internalCounter); - addNormalRelatedCalculations(vsMain, mParamInBiNormal, mParamLocalBinormalWorld, internalCounter); - return true; + //add functions to calculate normal and normal related data in world and object space + addNormalRelatedCalculations(vsMain, mParamInNormal, mParamLocalNormalWorld, internalCounter); + addNormalRelatedCalculations(vsMain, mParamInTangent, mParamLocalTangentWorld, internalCounter); + addNormalRelatedCalculations(vsMain, mParamInBiNormal, mParamLocalBinormalWorld, internalCounter); + return true; } //----------------------------------------------------------------------- void LinearSkinning::addPositionCalculations(Function* vsMain, int& funcCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - if (mDoBoneCalculations == true) - { - //set functions to calculate world position - for(int i = 0 ; i < getWeightCount() ; ++i) - { - addIndexedPositionWeight(vsMain, i, funcCounter); - } - - //update back the original position relative to the object - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //update the projective position thereby filling the transform stage role - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInViewProjMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - //update from object to world space - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //update from object to projective space - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInWorldViewProjMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } + FunctionInvocation* curFuncInvocation = NULL; + + if (mDoBoneCalculations == true) + { + //set functions to calculate world position + for(int i = 0 ; i < getWeightCount() ; ++i) + { + addIndexedPositionWeight(vsMain, i, funcCounter); + } + + //update back the original position relative to the object + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //update the projective position thereby filling the transform stage role + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInViewProjMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + //update from object to world space + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //update from object to projective space + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInWorldViewProjMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamOutPositionProj, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } } //----------------------------------------------------------------------- void LinearSkinning::addNormalRelatedCalculations(Function* vsMain, - ParameterPtr& pNormalRelatedParam, - ParameterPtr& pNormalWorldRelatedParam, - int& funcCounter) + ParameterPtr& pNormalRelatedParam, + ParameterPtr& pNormalWorldRelatedParam, + int& funcCounter) { - FunctionInvocation* curFuncInvocation; - - if (mDoBoneCalculations == true) - { - //set functions to calculate world normal - for(int i = 0 ; i < getWeightCount() ; ++i) - { - addIndexedNormalRelatedWeight(vsMain, pNormalRelatedParam, pNormalWorldRelatedParam, i, funcCounter); - } - - //update back the original position relative to the object - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - //update from object to world space - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } + FunctionInvocation* curFuncInvocation; + + if (mDoBoneCalculations == true) + { + //set functions to calculate world normal + for(int i = 0 ; i < getWeightCount() ; ++i) + { + addIndexedNormalRelatedWeight(vsMain, pNormalRelatedParam, pNormalWorldRelatedParam, i, funcCounter); + } + + //update back the original position relative to the object + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInInvWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + //update from object to world space + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalRelatedParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } } //----------------------------------------------------------------------- void LinearSkinning::addIndexedPositionWeight(Function* vsMain, - int index, int& funcCounter) + int index, int& funcCounter) { - Operand::OpMask indexMask = indexToMask(index); - - FunctionInvocation* curFuncInvocation; - - //multiply position with world matrix and put into temporary param - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexMask, 1); - curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT, Operand::OPM_XYZ); - vsMain->addAtomInstance(curFuncInvocation); - - //set w value of temporary param to 1 - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0f), Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT, Operand::OPM_W); - vsMain->addAtomInstance(curFuncInvocation); - - //multiply temporary param with weight - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInWeights, Operand::OPS_IN, indexMask); - curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //check if on first iteration - if (index == 0) - { - //set the local param as the value of the world param - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - //add the local param as the value of the world param - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } + Operand::OpMask indexMask = indexToMask(index); + + FunctionInvocation* curFuncInvocation; + + //multiply position with world matrix and put into temporary param + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexMask, 1); + curFuncInvocation->pushOperand(mParamInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT, Operand::OPM_XYZ); + vsMain->addAtomInstance(curFuncInvocation); + + //set w value of temporary param to 1 + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0f), Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT, Operand::OPM_W); + vsMain->addAtomInstance(curFuncInvocation); + + //multiply temporary param with weight + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInWeights, Operand::OPS_IN, indexMask); + curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //check if on first iteration + if (index == 0) + { + //set the local param as the value of the world param + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + //add the local param as the value of the world param + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamTempFloat4, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamLocalPositionWorld, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } } //----------------------------------------------------------------------- void LinearSkinning::addIndexedNormalRelatedWeight(Function* vsMain, - ParameterPtr& pNormalParam, - ParameterPtr& pNormalWorldRelatedParam, - int index, int& funcCounter) + ParameterPtr& pNormalParam, + ParameterPtr& pNormalWorldRelatedParam, + int index, int& funcCounter) { - FunctionInvocation* curFuncInvocation; - - Operand::OpMask indexMask = indexToMask(index); - - //multiply position with world matrix and put into temporary param - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN, Operand::OPM_ALL); - curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexMask, 1); - curFuncInvocation->pushOperand(pNormalParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //multiply temporary param with weight - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_IN); - curFuncInvocation->pushOperand(mParamInWeights, Operand::OPS_IN, indexMask); - curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - //check if on first iteration - if (index == 0) - { - //set the local param as the value of the world normal - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - //add the local param as the value of the world normal - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); - curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } + FunctionInvocation* curFuncInvocation; + + Operand::OpMask indexMask = indexToMask(index); + + //multiply position with world matrix and put into temporary param + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamInWorldMatrices, Operand::OPS_IN, Operand::OPM_ALL); + curFuncInvocation->pushOperand(mParamInIndices, Operand::OPS_IN, indexMask, 1); + curFuncInvocation->pushOperand(pNormalParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //multiply temporary param with weight + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_IN); + curFuncInvocation->pushOperand(mParamInWeights, Operand::OPS_IN, indexMask); + curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + //check if on first iteration + if (index == 0) + { + //set the local param as the value of the world normal + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + //add the local param as the value of the world normal + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_VS_TRANSFORM, funcCounter++); + curFuncInvocation->pushOperand(mParamTempFloat3, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(pNormalWorldRelatedParam, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } } } diff --git a/Components/RTShaderSystem/src/OgreShaderExNormalMapLighting.cpp b/Components/RTShaderSystem/src/OgreShaderExNormalMapLighting.cpp index 87707615322..8de73baac9b 100644 --- a/Components/RTShaderSystem/src/OgreShaderExNormalMapLighting.cpp +++ b/Components/RTShaderSystem/src/OgreShaderExNormalMapLighting.cpp @@ -41,1329 +41,1329 @@ namespace RTShader { /************************************************************************/ /* */ /************************************************************************/ -String NormalMapLighting::Type = "SGX_NormalMapLighting"; +String NormalMapLighting::Type = "SGX_NormalMapLighting"; Light NormalMapLighting::msBlankLight; //----------------------------------------------------------------------- NormalMapLighting::NormalMapLighting() { - mTrackVertexColourType = TVC_NONE; - mNormalMapSamplerIndex = 0; - mVSTexCoordSetIndex = 0; - mSpecularEnable = false; - mNormalMapSpace = NMS_TANGENT; - mNormalMapMinFilter = FO_LINEAR; - mNormalMapMagFilter = FO_LINEAR; - mNormalMapMipFilter = FO_POINT; - mNormalMapAnisotropy = 1; - mNormalMapMipBias = -1.0; - - msBlankLight.setDiffuseColour(ColourValue::Black); - msBlankLight.setSpecularColour(ColourValue::Black); - msBlankLight.setAttenuation(0,1,0,0); + mTrackVertexColourType = TVC_NONE; + mNormalMapSamplerIndex = 0; + mVSTexCoordSetIndex = 0; + mSpecularEnable = false; + mNormalMapSpace = NMS_TANGENT; + mNormalMapMinFilter = FO_LINEAR; + mNormalMapMagFilter = FO_LINEAR; + mNormalMapMipFilter = FO_POINT; + mNormalMapAnisotropy = 1; + mNormalMapMipBias = -1.0; + + msBlankLight.setDiffuseColour(ColourValue::Black); + msBlankLight.setSpecularColour(ColourValue::Black); + msBlankLight.setAttenuation(0,1,0,0); } //----------------------------------------------------------------------- const String& NormalMapLighting::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int NormalMapLighting::getExecutionOrder() const +int NormalMapLighting::getExecutionOrder() const { - return FFP_LIGHTING; + return FFP_LIGHTING; } //----------------------------------------------------------------------- void NormalMapLighting::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, - const LightList* pLightList) -{ - if (mLightParamsList.empty()) - return; - - Light::LightTypes curLightType = Light::LT_DIRECTIONAL; - unsigned int curSearchLightIndex = 0; - const Matrix4& matWorld = source->getWorldMatrix(); - Matrix3 matWorldInvRotation; - Vector3 vRow0(matWorld[0][0], matWorld[0][1], matWorld[0][2]); - Vector3 vRow1(matWorld[1][0], matWorld[1][1], matWorld[1][2]); - Vector3 vRow2(matWorld[2][0], matWorld[2][1], matWorld[2][2]); - - vRow0.normalise(); - vRow1.normalise(); - vRow2.normalise(); - - matWorldInvRotation.SetColumn(0, vRow0); - matWorldInvRotation.SetColumn(1, vRow1); - matWorldInvRotation.SetColumn(2, vRow2); - - // Update inverse rotation parameter. - if (mWorldInvRotMatrix.get() != NULL) - mWorldInvRotMatrix->setGpuParameter(matWorldInvRotation); - - // Update per light parameters. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - const LightParams& curParams = mLightParamsList[i]; - - if (curLightType != curParams.mType) - { - curLightType = curParams.mType; - curSearchLightIndex = 0; - } - - Light* srcLight = NULL; - Vector4 vParameter; - ColourValue colour; - - // Search a matching light from the current sorted lights of the given renderable. - for (unsigned int j = curSearchLightIndex; j < pLightList->size(); ++j) - { - if (pLightList->at(j)->getType() == curLightType) - { - srcLight = pLightList->at(j); - curSearchLightIndex = j + 1; - break; - } - } - - // No matching light found -> use a blank dummy light for parameter update. - if (srcLight == NULL) - { - srcLight = &msBlankLight; - } - - - switch (curParams.mType) - { - case Light::LT_DIRECTIONAL: - { - Vector3 vec3; - - // Update light direction. (Object space). - vec3 = matWorldInvRotation * srcLight->getDerivedDirection(); - vec3.normalise(); - - vParameter.x = -vec3.x; - vParameter.y = -vec3.y; - vParameter.z = -vec3.z; - vParameter.w = 0.0; - curParams.mDirection->setGpuParameter(vParameter); - } - break; - - case Light::LT_POINT: - - // Update light position. (World space). - vParameter = srcLight->getAs4DVector(true); - curParams.mPosition->setGpuParameter(vParameter); - - // Update light attenuation parameters. - vParameter.x = srcLight->getAttenuationRange(); - vParameter.y = srcLight->getAttenuationConstant(); - vParameter.z = srcLight->getAttenuationLinear(); - vParameter.w = srcLight->getAttenuationQuadric(); - curParams.mAttenuatParams->setGpuParameter(vParameter); - break; - - case Light::LT_SPOTLIGHT: - { - Vector3 vec3; - - // Update light position. (World space). - vParameter = srcLight->getAs4DVector(true); - curParams.mPosition->setGpuParameter(vParameter); - - - // Update light direction. (Object space). - vec3 = matWorldInvRotation * srcLight->getDerivedDirection(); - vec3.normalise(); - - vParameter.x = -vec3.x; - vParameter.y = -vec3.y; - vParameter.z = -vec3.z; - vParameter.w = 0.0; - curParams.mDirection->setGpuParameter(vParameter); - - // Update light attenuation parameters. - vParameter.x = srcLight->getAttenuationRange(); - vParameter.y = srcLight->getAttenuationConstant(); - vParameter.z = srcLight->getAttenuationLinear(); - vParameter.w = srcLight->getAttenuationQuadric(); - curParams.mAttenuatParams->setGpuParameter(vParameter); - - // Update spotlight parameters. - Real phi = Math::Cos(srcLight->getSpotlightOuterAngle().valueRadians() * 0.5f); - Real theta = Math::Cos(srcLight->getSpotlightInnerAngle().valueRadians() * 0.5f); - - vec3.x = theta; - vec3.y = phi; - vec3.z = srcLight->getSpotlightFalloff(); - - curParams.mSpotParams->setGpuParameter(vec3); - } - break; - } - - - // Update diffuse colour. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - colour = srcLight->getDiffuseColour() * pass->getDiffuse() * srcLight->getPowerScale(); - curParams.mDiffuseColour->setGpuParameter(colour); - } - else - { - colour = srcLight->getDiffuseColour() * srcLight->getPowerScale(); - curParams.mDiffuseColour->setGpuParameter(colour); - } - - // Update specular colour if need to. - if (mSpecularEnable) - { - // Update diffuse colour. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - colour = srcLight->getSpecularColour() * pass->getSpecular() * srcLight->getPowerScale(); - curParams.mSpecularColour->setGpuParameter(colour); - } - else - { - colour = srcLight->getSpecularColour() * srcLight->getPowerScale(); - curParams.mSpecularColour->setGpuParameter(colour); - } - } - } + const LightList* pLightList) +{ + if (mLightParamsList.empty()) + return; + + Light::LightTypes curLightType = Light::LT_DIRECTIONAL; + unsigned int curSearchLightIndex = 0; + const Matrix4& matWorld = source->getWorldMatrix(); + Matrix3 matWorldInvRotation; + Vector3 vRow0(matWorld[0][0], matWorld[0][1], matWorld[0][2]); + Vector3 vRow1(matWorld[1][0], matWorld[1][1], matWorld[1][2]); + Vector3 vRow2(matWorld[2][0], matWorld[2][1], matWorld[2][2]); + + vRow0.normalise(); + vRow1.normalise(); + vRow2.normalise(); + + matWorldInvRotation.SetColumn(0, vRow0); + matWorldInvRotation.SetColumn(1, vRow1); + matWorldInvRotation.SetColumn(2, vRow2); + + // Update inverse rotation parameter. + if (mWorldInvRotMatrix.get() != NULL) + mWorldInvRotMatrix->setGpuParameter(matWorldInvRotation); + + // Update per light parameters. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + const LightParams& curParams = mLightParamsList[i]; + + if (curLightType != curParams.mType) + { + curLightType = curParams.mType; + curSearchLightIndex = 0; + } + + Light* srcLight = NULL; + Vector4 vParameter; + ColourValue colour; + + // Search a matching light from the current sorted lights of the given renderable. + for (unsigned int j = curSearchLightIndex; j < pLightList->size(); ++j) + { + if (pLightList->at(j)->getType() == curLightType) + { + srcLight = pLightList->at(j); + curSearchLightIndex = j + 1; + break; + } + } + + // No matching light found -> use a blank dummy light for parameter update. + if (srcLight == NULL) + { + srcLight = &msBlankLight; + } + + + switch (curParams.mType) + { + case Light::LT_DIRECTIONAL: + { + Vector3 vec3; + + // Update light direction. (Object space). + vec3 = matWorldInvRotation * srcLight->getDerivedDirection(); + vec3.normalise(); + + vParameter.x = -vec3.x; + vParameter.y = -vec3.y; + vParameter.z = -vec3.z; + vParameter.w = 0.0; + curParams.mDirection->setGpuParameter(vParameter); + } + break; + + case Light::LT_POINT: + + // Update light position. (World space). + vParameter = srcLight->getAs4DVector(true); + curParams.mPosition->setGpuParameter(vParameter); + + // Update light attenuation parameters. + vParameter.x = srcLight->getAttenuationRange(); + vParameter.y = srcLight->getAttenuationConstant(); + vParameter.z = srcLight->getAttenuationLinear(); + vParameter.w = srcLight->getAttenuationQuadric(); + curParams.mAttenuatParams->setGpuParameter(vParameter); + break; + + case Light::LT_SPOTLIGHT: + { + Vector3 vec3; + + // Update light position. (World space). + vParameter = srcLight->getAs4DVector(true); + curParams.mPosition->setGpuParameter(vParameter); + + + // Update light direction. (Object space). + vec3 = matWorldInvRotation * srcLight->getDerivedDirection(); + vec3.normalise(); + + vParameter.x = -vec3.x; + vParameter.y = -vec3.y; + vParameter.z = -vec3.z; + vParameter.w = 0.0; + curParams.mDirection->setGpuParameter(vParameter); + + // Update light attenuation parameters. + vParameter.x = srcLight->getAttenuationRange(); + vParameter.y = srcLight->getAttenuationConstant(); + vParameter.z = srcLight->getAttenuationLinear(); + vParameter.w = srcLight->getAttenuationQuadric(); + curParams.mAttenuatParams->setGpuParameter(vParameter); + + // Update spotlight parameters. + Real phi = Math::Cos(srcLight->getSpotlightOuterAngle().valueRadians() * 0.5f); + Real theta = Math::Cos(srcLight->getSpotlightInnerAngle().valueRadians() * 0.5f); + + vec3.x = theta; + vec3.y = phi; + vec3.z = srcLight->getSpotlightFalloff(); + + curParams.mSpotParams->setGpuParameter(vec3); + } + break; + } + + + // Update diffuse colour. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + colour = srcLight->getDiffuseColour() * pass->getDiffuse() * srcLight->getPowerScale(); + curParams.mDiffuseColour->setGpuParameter(colour); + } + else + { + colour = srcLight->getDiffuseColour() * srcLight->getPowerScale(); + curParams.mDiffuseColour->setGpuParameter(colour); + } + + // Update specular colour if need to. + if (mSpecularEnable) + { + // Update diffuse colour. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + colour = srcLight->getSpecularColour() * pass->getSpecular() * srcLight->getPowerScale(); + curParams.mSpecularColour->setGpuParameter(colour); + } + else + { + colour = srcLight->getSpecularColour() * srcLight->getPowerScale(); + curParams.mSpecularColour->setGpuParameter(colour); + } + } + } } //----------------------------------------------------------------------- bool NormalMapLighting::resolveParameters(ProgramSet* programSet) { - if (false == resolveGlobalParameters(programSet)) - return false; - - if (false == resolvePerLightParameters(programSet)) - return false; - - return true; + if (false == resolveGlobalParameters(programSet)) + return false; + + if (false == resolvePerLightParameters(programSet)) + return false; + + return true; } //----------------------------------------------------------------------- bool NormalMapLighting::resolveGlobalParameters(ProgramSet* programSet) { - bool hasError = false; - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - - // Resolve normal map texture sampler parameter. - mNormalMapSampler = psProgram->resolveParameter(GCT_SAMPLER2D, mNormalMapSamplerIndex, (uint16)GPV_PER_OBJECT, "gNormalMapSampler"); - - // Get surface ambient colour if need to. - if ((mTrackVertexColourType & TVC_AMBIENT) == 0) - { - mDerivedAmbientLightColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR, 0); - hasError |= !(mDerivedAmbientLightColour.get()); - } - else - { - mLightAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, 0); - mSurfaceAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR, 0); - - hasError |= !(mDerivedAmbientLightColour.get()) || !(mLightAmbientColour.get()); - } - - // Get surface diffuse colour if need to. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - mSurfaceDiffuseColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR, 0); - hasError |= !(mSurfaceDiffuseColour.get()); - } - - // Get surface specular colour if need to. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - mSurfaceSpecularColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR, 0); - hasError |= !(mSurfaceSpecularColour.get()); - } - - - // Get surface emissive colour if need to. - if ((mTrackVertexColourType & TVC_EMISSIVE) == 0) - { - mSurfaceEmissiveColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR, 0); - hasError |= !(mSurfaceEmissiveColour.get()); - } - - // Get derived scene colour. - mDerivedSceneColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, 0); - - // Get surface shininess. - mSurfaceShininess = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SHININESS, 0); - - // Resolve input vertex shader normal. - mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - - // Resolve input vertex shader tangent. - if (mNormalMapSpace == NMS_TANGENT) - { - mVSInTangent = vsMain->resolveInputParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_OBJECT_SPACE, GCT_FLOAT3); - - // Resolve local vertex shader TNB matrix. - mVSTBNMatrix = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lMatTBN", GCT_MATRIX_3X3); - - hasError |= !(mVSTBNMatrix.get()) || !(mVSInTangent.get()); - } - - // Resolve input vertex shader texture coordinates. - mVSInTexcoord = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSTexCoordSetIndex, - Parameter::Content(Parameter::SPC_TEXTURE_COORDINATE0 + mVSTexCoordSetIndex), - GCT_FLOAT2); - - // Resolve output vertex shader texture coordinates. - mVSOutTexcoord = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::Content(Parameter::SPC_TEXTURE_COORDINATE0 + mVSTexCoordSetIndex), - GCT_FLOAT2); - - // Resolve pixel input texture coordinates normal. - mPSInTexcoord = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutTexcoord->getIndex(), - mVSOutTexcoord->getContent(), - mVSOutTexcoord->getType()); - - // Resolve pixel shader normal. - if (mNormalMapSpace == NMS_OBJECT) - { - mPSNormal = psMain->resolveLocalParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT4); - hasError |= !(mPSNormal.get()); - } - else if (mNormalMapSpace == NMS_TANGENT) - { - mPSNormal = psMain->resolveLocalParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_TANGENT_SPACE, GCT_FLOAT4); - hasError |= !(mPSNormal.get()); - } - - - const ShaderParameterList& inputParams = psMain->getInputParameters(); - const ShaderParameterList& localParams = psMain->getLocalParameters(); - - mPSDiffuse = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - if (mPSDiffuse.get() == NULL) - { - mPSDiffuse = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - } - - mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - mPSTempDiffuseColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lNormalMapDiffuse", GCT_FLOAT4); - - if (mSpecularEnable) - { - mPSSpecular = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - if (mPSSpecular.get() == NULL) - { - mPSSpecular = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - } - - mPSTempSpecularColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lNormalMapSpecular", GCT_FLOAT4); - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - - if (mNormalMapSpace == NMS_TANGENT) - { - mVSOutView = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::SPC_POSTOCAMERA_TANGENT_SPACE, GCT_FLOAT3); - hasError |= !(mVSOutView.get()); - } - else if (mNormalMapSpace == NMS_OBJECT) - { - mVSOutView = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::SPC_POSTOCAMERA_OBJECT_SPACE, GCT_FLOAT3); - hasError |= !(mVSOutView.get()); - } - - - mPSInView = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutView->getIndex(), - mVSOutView->getContent(), - mVSOutView->getType()); - - // Resolve camera position world space. - mCamPosWorldSpace = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_CAMERA_POSITION, 0); - mVSLocalDir = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lNormalMapTempDir", GCT_FLOAT3); - mVSWorldPosition = vsMain->resolveLocalParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT3); - // Resolve world matrix. - mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - - // Resolve inverse world rotation matrix. - mWorldInvRotMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_PER_OBJECT, "inv_world_rotation_matrix"); - - hasError |= !(mPSSpecular.get()) || !(mPSTempSpecularColour.get()) || !(mVSInPosition.get()) || !(mPSInView.get()) || !(mCamPosWorldSpace.get()) || - !(mVSLocalDir.get()) || !(mVSWorldPosition.get()) || !(mWorldMatrix.get()) || !(mWorldInvRotMatrix.get()); - } - - hasError |= !(mNormalMapSampler.get()) || !(mDerivedSceneColour.get()) || !(mSurfaceShininess.get()) || !(mVSInNormal.get()) || - !(mVSInTexcoord.get()) || !(mVSOutTexcoord.get()) || !(mPSInTexcoord.get()) || !(mPSDiffuse.get()) || !(mPSOutDiffuse.get()) || - !(mPSTempDiffuseColour.get()); - - if (hasError) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "NormalMapLighting::resolveGlobalParameters" ); - } - return true; + bool hasError = false; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + + // Resolve normal map texture sampler parameter. + mNormalMapSampler = psProgram->resolveParameter(GCT_SAMPLER2D, mNormalMapSamplerIndex, (uint16)GPV_PER_OBJECT, "gNormalMapSampler"); + + // Get surface ambient colour if need to. + if ((mTrackVertexColourType & TVC_AMBIENT) == 0) + { + mDerivedAmbientLightColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR, 0); + hasError |= !(mDerivedAmbientLightColour.get()); + } + else + { + mLightAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, 0); + mSurfaceAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR, 0); + + hasError |= !(mDerivedAmbientLightColour.get()) || !(mLightAmbientColour.get()); + } + + // Get surface diffuse colour if need to. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + mSurfaceDiffuseColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR, 0); + hasError |= !(mSurfaceDiffuseColour.get()); + } + + // Get surface specular colour if need to. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + mSurfaceSpecularColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR, 0); + hasError |= !(mSurfaceSpecularColour.get()); + } + + + // Get surface emissive colour if need to. + if ((mTrackVertexColourType & TVC_EMISSIVE) == 0) + { + mSurfaceEmissiveColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR, 0); + hasError |= !(mSurfaceEmissiveColour.get()); + } + + // Get derived scene colour. + mDerivedSceneColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, 0); + + // Get surface shininess. + mSurfaceShininess = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SHININESS, 0); + + // Resolve input vertex shader normal. + mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + + // Resolve input vertex shader tangent. + if (mNormalMapSpace == NMS_TANGENT) + { + mVSInTangent = vsMain->resolveInputParameter(Parameter::SPS_TANGENT, 0, Parameter::SPC_TANGENT_OBJECT_SPACE, GCT_FLOAT3); + + // Resolve local vertex shader TNB matrix. + mVSTBNMatrix = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lMatTBN", GCT_MATRIX_3X3); + + hasError |= !(mVSTBNMatrix.get()) || !(mVSInTangent.get()); + } + + // Resolve input vertex shader texture coordinates. + mVSInTexcoord = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSTexCoordSetIndex, + Parameter::Content(Parameter::SPC_TEXTURE_COORDINATE0 + mVSTexCoordSetIndex), + GCT_FLOAT2); + + // Resolve output vertex shader texture coordinates. + mVSOutTexcoord = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::Content(Parameter::SPC_TEXTURE_COORDINATE0 + mVSTexCoordSetIndex), + GCT_FLOAT2); + + // Resolve pixel input texture coordinates normal. + mPSInTexcoord = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutTexcoord->getIndex(), + mVSOutTexcoord->getContent(), + mVSOutTexcoord->getType()); + + // Resolve pixel shader normal. + if (mNormalMapSpace == NMS_OBJECT) + { + mPSNormal = psMain->resolveLocalParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT4); + hasError |= !(mPSNormal.get()); + } + else if (mNormalMapSpace == NMS_TANGENT) + { + mPSNormal = psMain->resolveLocalParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_TANGENT_SPACE, GCT_FLOAT4); + hasError |= !(mPSNormal.get()); + } + + + const ShaderParameterList& inputParams = psMain->getInputParameters(); + const ShaderParameterList& localParams = psMain->getLocalParameters(); + + mPSDiffuse = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + if (mPSDiffuse.get() == NULL) + { + mPSDiffuse = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + } + + mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + mPSTempDiffuseColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lNormalMapDiffuse", GCT_FLOAT4); + + if (mSpecularEnable) + { + mPSSpecular = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + if (mPSSpecular.get() == NULL) + { + mPSSpecular = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + } + + mPSTempSpecularColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lNormalMapSpecular", GCT_FLOAT4); + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + + if (mNormalMapSpace == NMS_TANGENT) + { + mVSOutView = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::SPC_POSTOCAMERA_TANGENT_SPACE, GCT_FLOAT3); + hasError |= !(mVSOutView.get()); + } + else if (mNormalMapSpace == NMS_OBJECT) + { + mVSOutView = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::SPC_POSTOCAMERA_OBJECT_SPACE, GCT_FLOAT3); + hasError |= !(mVSOutView.get()); + } + + + mPSInView = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutView->getIndex(), + mVSOutView->getContent(), + mVSOutView->getType()); + + // Resolve camera position world space. + mCamPosWorldSpace = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_CAMERA_POSITION, 0); + mVSLocalDir = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lNormalMapTempDir", GCT_FLOAT3); + mVSWorldPosition = vsMain->resolveLocalParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT3); + // Resolve world matrix. + mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + + // Resolve inverse world rotation matrix. + mWorldInvRotMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_PER_OBJECT, "inv_world_rotation_matrix"); + + hasError |= !(mPSSpecular.get()) || !(mPSTempSpecularColour.get()) || !(mVSInPosition.get()) || !(mPSInView.get()) || !(mCamPosWorldSpace.get()) || + !(mVSLocalDir.get()) || !(mVSWorldPosition.get()) || !(mWorldMatrix.get()) || !(mWorldInvRotMatrix.get()); + } + + hasError |= !(mNormalMapSampler.get()) || !(mDerivedSceneColour.get()) || !(mSurfaceShininess.get()) || !(mVSInNormal.get()) || + !(mVSInTexcoord.get()) || !(mVSOutTexcoord.get()) || !(mPSInTexcoord.get()) || !(mPSDiffuse.get()) || !(mPSOutDiffuse.get()) || + !(mPSTempDiffuseColour.get()); + + if (hasError) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "NormalMapLighting::resolveGlobalParameters" ); + } + return true; } //----------------------------------------------------------------------- bool NormalMapLighting::resolvePerLightParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - - bool hasError = false; - // Resolve per light parameters. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - switch (mLightParamsList[i].mType) - { - case Light::LT_DIRECTIONAL: - mLightParamsList[i].mDirection = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS|GPV_PER_OBJECT, "light_direction_obj_space"); - - if (mNormalMapSpace == NMS_TANGENT) - { - mLightParamsList[i].mVSOutDirection = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::Content(Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE0 + i), - GCT_FLOAT3); - } - else if (mNormalMapSpace == NMS_OBJECT) - { - mLightParamsList[i].mVSOutDirection = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::Content(Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE0 + i), - GCT_FLOAT3); - } - - mLightParamsList[i].mPSInDirection = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mLightParamsList[i].mVSOutDirection->getIndex(), - mLightParamsList[i].mVSOutDirection->getContent(), - mLightParamsList[i].mVSOutDirection->getType()); - - hasError = !(mLightParamsList[i].mDirection.get()) || !(mLightParamsList[i].mVSOutDirection.get()) || !(mLightParamsList[i].mPSInDirection.get()); - break; - - case Light::LT_POINT: - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - - mLightParamsList[i].mPosition = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS|GPV_PER_OBJECT, "light_position_world_space"); - - if (mNormalMapSpace == NMS_TANGENT) - { - mLightParamsList[i].mVSOutToLightDir = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::Content(Parameter::SPC_POSTOLIGHT_TANGENT_SPACE0 + i), - GCT_FLOAT3); - } - else if (mNormalMapSpace == NMS_OBJECT) - { - mLightParamsList[i].mVSOutToLightDir = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::Content(Parameter::SPC_POSTOLIGHT_OBJECT_SPACE0 + i), - GCT_FLOAT3); - } - - mLightParamsList[i].mPSInToLightDir = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mLightParamsList[i].mVSOutToLightDir->getIndex(), - mLightParamsList[i].mVSOutToLightDir->getContent(), - mLightParamsList[i].mVSOutToLightDir->getType()); - - mLightParamsList[i].mAttenuatParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); - - // Resolve local dir. - if (mVSLocalDir.get() == NULL) - { - mVSLocalDir = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lNormalMapTempDir", GCT_FLOAT3); - } - - // Resolve world position. - if (mVSWorldPosition.get() == NULL) - { - mVSWorldPosition = vsMain->resolveLocalParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT3); - } - - // Resolve world matrix. - if (mWorldMatrix.get() == NULL) - { - mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - } - - // Resolve inverse world rotation matrix. - if (mWorldInvRotMatrix.get() == NULL) - { - mWorldInvRotMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_PER_OBJECT, "inv_world_rotation_matrix"); - } - - hasError |= !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || !(mLightParamsList[i].mVSOutToLightDir.get()) || - !(mLightParamsList[i].mPSInToLightDir.get()) || !(mLightParamsList[i].mAttenuatParams.get()) || !(mVSLocalDir.get()) || - !(mVSWorldPosition.get()) || !(mWorldMatrix.get()) || !(mWorldInvRotMatrix.get()); - - break; - - case Light::LT_SPOTLIGHT: - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - mLightParamsList[i].mPosition = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS|GPV_PER_OBJECT, "light_position_world_space"); - - if (mNormalMapSpace == NMS_TANGENT) - { - mLightParamsList[i].mVSOutToLightDir = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::Content(Parameter::SPC_POSTOLIGHT_TANGENT_SPACE0 + i), - GCT_FLOAT3); - } - else if (mNormalMapSpace == NMS_OBJECT) - { - mLightParamsList[i].mVSOutToLightDir = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::Content(Parameter::SPC_POSTOLIGHT_OBJECT_SPACE0 + i), - GCT_FLOAT3); - } - - mLightParamsList[i].mPSInToLightDir = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mLightParamsList[i].mVSOutToLightDir->getIndex(), - mLightParamsList[i].mVSOutToLightDir->getContent(), - mLightParamsList[i].mVSOutToLightDir->getType()); - - mLightParamsList[i].mDirection = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS|GPV_PER_OBJECT, "light_direction_obj_space"); - - if (mNormalMapSpace == NMS_TANGENT) - { - mLightParamsList[i].mVSOutDirection = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::Content(Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE0 + i), - GCT_FLOAT3); - } - else if (mNormalMapSpace == NMS_OBJECT) - { - mLightParamsList[i].mVSOutDirection = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::Content(Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE0 + i), - GCT_FLOAT3); - } - - mLightParamsList[i].mPSInDirection = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mLightParamsList[i].mVSOutDirection->getIndex(), - mLightParamsList[i].mVSOutDirection->getContent(), - mLightParamsList[i].mVSOutDirection->getType()); - - mLightParamsList[i].mAttenuatParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); - - mLightParamsList[i].mSpotParams = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "spotlight_params"); - - // Resolve local dir. - if (mVSLocalDir.get() == NULL) - { - mVSLocalDir = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lNormalMapTempDir", GCT_FLOAT3); - } - - // Resolve world position. - if (mVSWorldPosition.get() == NULL) - { - mVSWorldPosition = vsMain->resolveLocalParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT3); - } - - // Resolve world matrix. - if (mWorldMatrix.get() == NULL) - { - mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - } - - // Resolve inverse world rotation matrix. - if (mWorldInvRotMatrix.get() == NULL) - { - mWorldInvRotMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_PER_OBJECT, "inv_world_rotation_matrix"); - } - - hasError |= !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || !(mLightParamsList[i].mVSOutToLightDir.get()) || - !(mLightParamsList[i].mPSInToLightDir.get()) || !(mLightParamsList[i].mDirection.get()) || !(mLightParamsList[i].mVSOutDirection.get()) || - !(mLightParamsList[i].mPSInDirection.get()) || !(mLightParamsList[i].mAttenuatParams.get()) || !(mLightParamsList[i].mSpotParams.get()) || - !(mVSLocalDir.get()) || !(mVSWorldPosition.get()) || !(mWorldMatrix.get()) || !(mWorldInvRotMatrix.get()); - - break; - } - - // Resolve diffuse colour. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "derived_light_diffuse"); - } - else - { - mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_diffuse"); - } - - hasError |= !(mLightParamsList[i].mDiffuseColour.get()); - - if (mSpecularEnable) - { - // Resolve specular colour. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "derived_light_specular"); - } - else - { - mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_specular"); - } - hasError |= !(mLightParamsList[i].mSpecularColour.get()); - } - - } - - - if (hasError) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "NormalMapLighting::resolvePerLightParameters" ); - } - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + + bool hasError = false; + // Resolve per light parameters. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + switch (mLightParamsList[i].mType) + { + case Light::LT_DIRECTIONAL: + mLightParamsList[i].mDirection = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS|GPV_PER_OBJECT, "light_direction_obj_space"); + + if (mNormalMapSpace == NMS_TANGENT) + { + mLightParamsList[i].mVSOutDirection = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::Content(Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE0 + i), + GCT_FLOAT3); + } + else if (mNormalMapSpace == NMS_OBJECT) + { + mLightParamsList[i].mVSOutDirection = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::Content(Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE0 + i), + GCT_FLOAT3); + } + + mLightParamsList[i].mPSInDirection = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mLightParamsList[i].mVSOutDirection->getIndex(), + mLightParamsList[i].mVSOutDirection->getContent(), + mLightParamsList[i].mVSOutDirection->getType()); + + hasError = !(mLightParamsList[i].mDirection.get()) || !(mLightParamsList[i].mVSOutDirection.get()) || !(mLightParamsList[i].mPSInDirection.get()); + break; + + case Light::LT_POINT: + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + + mLightParamsList[i].mPosition = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS|GPV_PER_OBJECT, "light_position_world_space"); + + if (mNormalMapSpace == NMS_TANGENT) + { + mLightParamsList[i].mVSOutToLightDir = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::Content(Parameter::SPC_POSTOLIGHT_TANGENT_SPACE0 + i), + GCT_FLOAT3); + } + else if (mNormalMapSpace == NMS_OBJECT) + { + mLightParamsList[i].mVSOutToLightDir = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::Content(Parameter::SPC_POSTOLIGHT_OBJECT_SPACE0 + i), + GCT_FLOAT3); + } + + mLightParamsList[i].mPSInToLightDir = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mLightParamsList[i].mVSOutToLightDir->getIndex(), + mLightParamsList[i].mVSOutToLightDir->getContent(), + mLightParamsList[i].mVSOutToLightDir->getType()); + + mLightParamsList[i].mAttenuatParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); + + // Resolve local dir. + if (mVSLocalDir.get() == NULL) + { + mVSLocalDir = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lNormalMapTempDir", GCT_FLOAT3); + } + + // Resolve world position. + if (mVSWorldPosition.get() == NULL) + { + mVSWorldPosition = vsMain->resolveLocalParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT3); + } + + // Resolve world matrix. + if (mWorldMatrix.get() == NULL) + { + mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + } + + // Resolve inverse world rotation matrix. + if (mWorldInvRotMatrix.get() == NULL) + { + mWorldInvRotMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_PER_OBJECT, "inv_world_rotation_matrix"); + } + + hasError |= !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || !(mLightParamsList[i].mVSOutToLightDir.get()) || + !(mLightParamsList[i].mPSInToLightDir.get()) || !(mLightParamsList[i].mAttenuatParams.get()) || !(mVSLocalDir.get()) || + !(mVSWorldPosition.get()) || !(mWorldMatrix.get()) || !(mWorldInvRotMatrix.get()); + + break; + + case Light::LT_SPOTLIGHT: + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + mLightParamsList[i].mPosition = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS|GPV_PER_OBJECT, "light_position_world_space"); + + if (mNormalMapSpace == NMS_TANGENT) + { + mLightParamsList[i].mVSOutToLightDir = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::Content(Parameter::SPC_POSTOLIGHT_TANGENT_SPACE0 + i), + GCT_FLOAT3); + } + else if (mNormalMapSpace == NMS_OBJECT) + { + mLightParamsList[i].mVSOutToLightDir = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::Content(Parameter::SPC_POSTOLIGHT_OBJECT_SPACE0 + i), + GCT_FLOAT3); + } + + mLightParamsList[i].mPSInToLightDir = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mLightParamsList[i].mVSOutToLightDir->getIndex(), + mLightParamsList[i].mVSOutToLightDir->getContent(), + mLightParamsList[i].mVSOutToLightDir->getType()); + + mLightParamsList[i].mDirection = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS|GPV_PER_OBJECT, "light_direction_obj_space"); + + if (mNormalMapSpace == NMS_TANGENT) + { + mLightParamsList[i].mVSOutDirection = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::Content(Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE0 + i), + GCT_FLOAT3); + } + else if (mNormalMapSpace == NMS_OBJECT) + { + mLightParamsList[i].mVSOutDirection = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::Content(Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE0 + i), + GCT_FLOAT3); + } + + mLightParamsList[i].mPSInDirection = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mLightParamsList[i].mVSOutDirection->getIndex(), + mLightParamsList[i].mVSOutDirection->getContent(), + mLightParamsList[i].mVSOutDirection->getType()); + + mLightParamsList[i].mAttenuatParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); + + mLightParamsList[i].mSpotParams = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "spotlight_params"); + + // Resolve local dir. + if (mVSLocalDir.get() == NULL) + { + mVSLocalDir = vsMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lNormalMapTempDir", GCT_FLOAT3); + } + + // Resolve world position. + if (mVSWorldPosition.get() == NULL) + { + mVSWorldPosition = vsMain->resolveLocalParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT3); + } + + // Resolve world matrix. + if (mWorldMatrix.get() == NULL) + { + mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + } + + // Resolve inverse world rotation matrix. + if (mWorldInvRotMatrix.get() == NULL) + { + mWorldInvRotMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_PER_OBJECT, "inv_world_rotation_matrix"); + } + + hasError |= !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || !(mLightParamsList[i].mVSOutToLightDir.get()) || + !(mLightParamsList[i].mPSInToLightDir.get()) || !(mLightParamsList[i].mDirection.get()) || !(mLightParamsList[i].mVSOutDirection.get()) || + !(mLightParamsList[i].mPSInDirection.get()) || !(mLightParamsList[i].mAttenuatParams.get()) || !(mLightParamsList[i].mSpotParams.get()) || + !(mVSLocalDir.get()) || !(mVSWorldPosition.get()) || !(mWorldMatrix.get()) || !(mWorldInvRotMatrix.get()); + + break; + } + + // Resolve diffuse colour. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "derived_light_diffuse"); + } + else + { + mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_diffuse"); + } + + hasError |= !(mLightParamsList[i].mDiffuseColour.get()); + + if (mSpecularEnable) + { + // Resolve specular colour. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "derived_light_specular"); + } + else + { + mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_specular"); + } + hasError |= !(mLightParamsList[i].mSpecularColour.get()); + } + + } + + + if (hasError) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "NormalMapLighting::resolvePerLightParameters" ); + } + return true; } //----------------------------------------------------------------------- bool NormalMapLighting::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); - vsProgram->addDependency(FFP_LIB_COMMON); - vsProgram->addDependency(SGX_LIB_NORMALMAPLIGHTING); + vsProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(SGX_LIB_NORMALMAPLIGHTING); - psProgram->addDependency(FFP_LIB_COMMON); - psProgram->addDependency(SGX_LIB_NORMALMAPLIGHTING); + psProgram->addDependency(FFP_LIB_COMMON); + psProgram->addDependency(SGX_LIB_NORMALMAPLIGHTING); - return true; + return true; } //----------------------------------------------------------------------- bool NormalMapLighting::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* psMain = psProgram->getEntryPointFunction(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* psMain = psProgram->getEntryPointFunction(); - int internalCounter = 0; + int internalCounter = 0; - // Add the global illumination functions. - if (false == addVSInvocation(vsMain, FFP_VS_LIGHTING, internalCounter)) - return false; + // Add the global illumination functions. + if (false == addVSInvocation(vsMain, FFP_VS_LIGHTING, internalCounter)) + return false; - internalCounter = 0; + internalCounter = 0; - // Add the normal fetch function invocation. - if (false == addPSNormalFetchInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; + // Add the normal fetch function invocation. + if (false == addPSNormalFetchInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; - - // Add the global illumination functions. - if (false == addPSGlobalIlluminationInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; + + // Add the global illumination functions. + if (false == addPSGlobalIlluminationInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; - // Add per light functions. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - if (false == addPSIlluminationInvocation(&mLightParamsList[i], psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; - } + // Add per light functions. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + if (false == addPSIlluminationInvocation(&mLightParamsList[i], psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; + } - // Assign back temporary variables to the ps diffuse and specular components. - if (false == addPSFinalAssignmentInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; + // Assign back temporary variables to the ps diffuse and specular components. + if (false == addPSFinalAssignmentInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; - return true; + return true; } //----------------------------------------------------------------------- bool NormalMapLighting::addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - // Construct TNB matrix. - if (mNormalMapSpace == NMS_TANGENT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_CONSTRUCT_TBNMATRIX, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInTangent, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSTBNMatrix, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - - // Output texture coordinates. - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSInTexcoord, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutTexcoord, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - // Compute world space position. - if (mVSWorldPosition.get() != NULL) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMPOSITION, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSWorldPosition, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - - // Compute view vector. - if (mVSInPosition.get() != NULL && - mVSOutView.get() != NULL) - { - // View vector in world space. - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mCamPosWorldSpace, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSWorldPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - // Transform to object space. - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldInvRotMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - // Transform to tangent space. - if (mNormalMapSpace == NMS_TANGENT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSTBNMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutView, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - // Output object space. - else if (mNormalMapSpace == NMS_OBJECT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutView, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - } - - // Add per light functions. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - if (false == addVSIlluminationInvocation(&mLightParamsList[i], vsMain, groupOrder, internalCounter)) - return false; - } - - - return true; + FunctionInvocation* curFuncInvocation = NULL; + + // Construct TNB matrix. + if (mNormalMapSpace == NMS_TANGENT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_CONSTRUCT_TBNMATRIX, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInTangent, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSTBNMatrix, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + + // Output texture coordinates. + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSInTexcoord, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutTexcoord, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + // Compute world space position. + if (mVSWorldPosition.get() != NULL) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMPOSITION, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSWorldPosition, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + + // Compute view vector. + if (mVSInPosition.get() != NULL && + mVSOutView.get() != NULL) + { + // View vector in world space. + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mCamPosWorldSpace, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSWorldPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + // Transform to object space. + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldInvRotMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + // Transform to tangent space. + if (mNormalMapSpace == NMS_TANGENT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSTBNMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutView, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + // Output object space. + else if (mNormalMapSpace == NMS_OBJECT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutView, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + } + + // Add per light functions. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + if (false == addVSIlluminationInvocation(&mLightParamsList[i], vsMain, groupOrder, internalCounter)) + return false; + } + + + return true; } //----------------------------------------------------------------------- bool NormalMapLighting::addVSIlluminationInvocation(LightParams* curLightParams, Function* vsMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - // Compute light direction in texture space. - if (curLightParams->mDirection.get() != NULL && - curLightParams->mVSOutDirection.get() != NULL) - { - // Transform to texture space. - if (mNormalMapSpace == NMS_TANGENT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSTBNMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mVSOutDirection, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - // Output object space. - else if (mNormalMapSpace == NMS_OBJECT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mVSOutDirection, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - } - - // Transform light vector to target space.. - if (curLightParams->mPosition.get() != NULL && - curLightParams->mVSOutToLightDir.get() != NULL) - { - // Compute light vector. - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSWorldPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - // Transform to object space. - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldInvRotMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - // Transform to tangent space. - if (mNormalMapSpace == NMS_TANGENT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSTBNMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mVSOutToLightDir, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - // Output object space. - else if (mNormalMapSpace == NMS_OBJECT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mVSOutToLightDir, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - } - - - return true; + FunctionInvocation* curFuncInvocation = NULL; + + // Compute light direction in texture space. + if (curLightParams->mDirection.get() != NULL && + curLightParams->mVSOutDirection.get() != NULL) + { + // Transform to texture space. + if (mNormalMapSpace == NMS_TANGENT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSTBNMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mVSOutDirection, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + // Output object space. + else if (mNormalMapSpace == NMS_OBJECT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mVSOutDirection, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + } + + // Transform light vector to target space.. + if (curLightParams->mPosition.get() != NULL && + curLightParams->mVSOutToLightDir.get() != NULL) + { + // Compute light vector. + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSWorldPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + // Transform to object space. + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldInvRotMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + // Transform to tangent space. + if (mNormalMapSpace == NMS_TANGENT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSTBNMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mVSOutToLightDir, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + // Output object space. + else if (mNormalMapSpace == NMS_OBJECT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSLocalDir, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mVSOutToLightDir, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + } + + + return true; } //----------------------------------------------------------------------- bool NormalMapLighting::addPSNormalFetchInvocation(Function* psMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; + FunctionInvocation* curFuncInvocation = NULL; - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_FETCHNORMAL, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mNormalMapSampler, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInTexcoord, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_FETCHNORMAL, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mNormalMapSampler, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInTexcoord, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); - return true; + return true; } //----------------------------------------------------------------------- bool NormalMapLighting::addPSGlobalIlluminationInvocation(Function* psMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && - (mTrackVertexColourType & TVC_EMISSIVE) == 0) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - if (mTrackVertexColourType & TVC_AMBIENT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mDerivedAmbientLightColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - if (mTrackVertexColourType & TVC_EMISSIVE) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mSurfaceEmissiveColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - } - - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - return true; + FunctionInvocation* curFuncInvocation = NULL; + + if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && + (mTrackVertexColourType & TVC_EMISSIVE) == 0) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + if (mTrackVertexColourType & TVC_AMBIENT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mDerivedAmbientLightColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + if (mTrackVertexColourType & TVC_EMISSIVE) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mSurfaceEmissiveColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + } + + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + return true; } //----------------------------------------------------------------------- bool NormalMapLighting::addPSIlluminationInvocation(LightParams* curLightParams, Function* psMain, const int groupOrder, int& internalCounter) -{ - FunctionInvocation* curFuncInvocation = NULL; - - // Merge diffuse colour with vertex colour if need to. - if (mTrackVertexColourType & TVC_DIFFUSE) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - // Merge specular colour with vertex colour if need to. - if (mSpecularEnable && mTrackVertexColourType & TVC_SPECULAR) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - switch (curLightParams->mType) - { - - case Light::LT_DIRECTIONAL: - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInView, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPSInDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPSInDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - break; - - case Light::LT_POINT: - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_POINT_DIFFUSESPECULAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInView, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPSInToLightDir, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_POINT_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPSInToLightDir, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - break; - - case Light::LT_SPOTLIGHT: - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_SPOT_DIFFUSESPECULAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInView, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPSInToLightDir, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mPSInDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_SPOT_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPSInToLightDir, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mPSInDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - break; - } - - return true; +{ + FunctionInvocation* curFuncInvocation = NULL; + + // Merge diffuse colour with vertex colour if need to. + if (mTrackVertexColourType & TVC_DIFFUSE) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + // Merge specular colour with vertex colour if need to. + if (mSpecularEnable && mTrackVertexColourType & TVC_SPECULAR) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + switch (curLightParams->mType) + { + + case Light::LT_DIRECTIONAL: + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInView, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPSInDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPSInDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + break; + + case Light::LT_POINT: + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_POINT_DIFFUSESPECULAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInView, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPSInToLightDir, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_POINT_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPSInToLightDir, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + break; + + case Light::LT_SPOTLIGHT: + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_SPOT_DIFFUSESPECULAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInView, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPSInToLightDir, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mPSInDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_SPOT_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPSInToLightDir, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mPSInDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + break; + } + + return true; } //----------------------------------------------------------------------- bool NormalMapLighting::addPSFinalAssignmentInvocation( Function* psMain, const int groupOrder, int& internalCounter ) { - FunctionInvocation* curFuncInvocation; - - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - return true; + FunctionInvocation* curFuncInvocation; + + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + return true; } //----------------------------------------------------------------------- void NormalMapLighting::copyFrom(const SubRenderState& rhs) { - const NormalMapLighting& rhsLighting = static_cast(rhs); + const NormalMapLighting& rhsLighting = static_cast(rhs); - int lightCount[3]; + int lightCount[3]; - rhsLighting.getLightCount(lightCount); - setLightCount(lightCount); + rhsLighting.getLightCount(lightCount); + setLightCount(lightCount); - mTrackVertexColourType = rhsLighting.mTrackVertexColourType; - mSpecularEnable = rhsLighting.mSpecularEnable; - mNormalMapSpace = rhsLighting.mNormalMapSpace; - mNormalMapTextureName = rhsLighting.mNormalMapTextureName; - mNormalMapMinFilter = rhsLighting.mNormalMapMinFilter; - mNormalMapMagFilter = rhsLighting.mNormalMapMagFilter; - mNormalMapMipFilter = rhsLighting.mNormalMapMipFilter; - mNormalMapMipBias = rhsLighting.mNormalMapMipBias; + mTrackVertexColourType = rhsLighting.mTrackVertexColourType; + mSpecularEnable = rhsLighting.mSpecularEnable; + mNormalMapSpace = rhsLighting.mNormalMapSpace; + mNormalMapTextureName = rhsLighting.mNormalMapTextureName; + mNormalMapMinFilter = rhsLighting.mNormalMapMinFilter; + mNormalMapMagFilter = rhsLighting.mNormalMapMagFilter; + mNormalMapMipFilter = rhsLighting.mNormalMapMipFilter; + mNormalMapMipBias = rhsLighting.mNormalMapMipBias; } //----------------------------------------------------------------------- bool NormalMapLighting::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { - if (srcPass->getLightingEnabled() == false) - return false; - - int lightCount[3]; - - renderState->getLightCount(lightCount); - - TextureUnitState* normalMapTexture = dstPass->createTextureUnitState(); - - normalMapTexture->setTextureName(mNormalMapTextureName); - normalMapTexture->setTextureFiltering(mNormalMapMinFilter, mNormalMapMagFilter, mNormalMapMipFilter); - normalMapTexture->setTextureAnisotropy(mNormalMapAnisotropy); - normalMapTexture->setTextureMipmapBias(mNormalMapMipBias); - mNormalMapSamplerIndex = dstPass->getNumTextureUnitStates() - 1; - - setTrackVertexColourType(srcPass->getVertexColourTracking()); - - if (srcPass->getShininess() > 0.0 && - srcPass->getSpecular() != ColourValue::Black) - { - setSpecularEnable(true); - } - else - { - setSpecularEnable(false); - } - - // Case this pass should run once per light(s) -> override the light policy. - if (srcPass->getIteratePerLight()) - { - - // This is the preferred case -> only one type of light is handled. - if (srcPass->getRunOnlyForOneLightType()) - { - if (srcPass->getOnlyLightType() == Light::LT_POINT) - { - lightCount[0] = srcPass->getLightCountPerIteration(); - lightCount[1] = 0; - lightCount[2] = 0; - } - else if (srcPass->getOnlyLightType() == Light::LT_DIRECTIONAL) - { - lightCount[0] = 0; - lightCount[1] = srcPass->getLightCountPerIteration(); - lightCount[2] = 0; - } - else if (srcPass->getOnlyLightType() == Light::LT_SPOTLIGHT) - { - lightCount[0] = 0; - lightCount[1] = 0; - lightCount[2] = srcPass->getLightCountPerIteration(); - } - } - - // This is worse case -> all light types expected to be handled. - // Can not handle this request in efficient way - throw an exception. - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Using iterative lighting method with RT Shader System requires specifying explicit light type.", - "NormalMapLighting::preAddToRenderState"); - } - } - - setLightCount(lightCount); - - return true; + if (srcPass->getLightingEnabled() == false) + return false; + + int lightCount[3]; + + renderState->getLightCount(lightCount); + + TextureUnitState* normalMapTexture = dstPass->createTextureUnitState(); + + normalMapTexture->setTextureName(mNormalMapTextureName); + normalMapTexture->setTextureFiltering(mNormalMapMinFilter, mNormalMapMagFilter, mNormalMapMipFilter); + normalMapTexture->setTextureAnisotropy(mNormalMapAnisotropy); + normalMapTexture->setTextureMipmapBias(mNormalMapMipBias); + mNormalMapSamplerIndex = dstPass->getNumTextureUnitStates() - 1; + + setTrackVertexColourType(srcPass->getVertexColourTracking()); + + if (srcPass->getShininess() > 0.0 && + srcPass->getSpecular() != ColourValue::Black) + { + setSpecularEnable(true); + } + else + { + setSpecularEnable(false); + } + + // Case this pass should run once per light(s) -> override the light policy. + if (srcPass->getIteratePerLight()) + { + + // This is the preferred case -> only one type of light is handled. + if (srcPass->getRunOnlyForOneLightType()) + { + if (srcPass->getOnlyLightType() == Light::LT_POINT) + { + lightCount[0] = srcPass->getLightCountPerIteration(); + lightCount[1] = 0; + lightCount[2] = 0; + } + else if (srcPass->getOnlyLightType() == Light::LT_DIRECTIONAL) + { + lightCount[0] = 0; + lightCount[1] = srcPass->getLightCountPerIteration(); + lightCount[2] = 0; + } + else if (srcPass->getOnlyLightType() == Light::LT_SPOTLIGHT) + { + lightCount[0] = 0; + lightCount[1] = 0; + lightCount[2] = srcPass->getLightCountPerIteration(); + } + } + + // This is worse case -> all light types expected to be handled. + // Can not handle this request in efficient way - throw an exception. + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Using iterative lighting method with RT Shader System requires specifying explicit light type.", + "NormalMapLighting::preAddToRenderState"); + } + } + + setLightCount(lightCount); + + return true; } //----------------------------------------------------------------------- void NormalMapLighting::setLightCount(const int lightCount[3]) { - for (int type=0; type < 3; ++type) - { - for (int i=0; i < lightCount[type]; ++i) - { - LightParams curParams; - - if (type == 0) - curParams.mType = Light::LT_POINT; - else if (type == 1) - curParams.mType = Light::LT_DIRECTIONAL; - else if (type == 2) - curParams.mType = Light::LT_SPOTLIGHT; - - mLightParamsList.push_back(curParams); - } - } + for (int type=0; type < 3; ++type) + { + for (int i=0; i < lightCount[type]; ++i) + { + LightParams curParams; + + if (type == 0) + curParams.mType = Light::LT_POINT; + else if (type == 1) + curParams.mType = Light::LT_DIRECTIONAL; + else if (type == 2) + curParams.mType = Light::LT_SPOTLIGHT; + + mLightParamsList.push_back(curParams); + } + } } //----------------------------------------------------------------------- void NormalMapLighting::getLightCount(int lightCount[3]) const { - lightCount[0] = 0; - lightCount[1] = 0; - lightCount[2] = 0; - - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - const LightParams curParams = mLightParamsList[i]; - - if (curParams.mType == Light::LT_POINT) - lightCount[0]++; - else if (curParams.mType == Light::LT_DIRECTIONAL) - lightCount[1]++; - else if (curParams.mType == Light::LT_SPOTLIGHT) - lightCount[2]++; - } + lightCount[0] = 0; + lightCount[1] = 0; + lightCount[2] = 0; + + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + const LightParams curParams = mLightParamsList[i]; + + if (curParams.mType == Light::LT_POINT) + lightCount[0]++; + else if (curParams.mType == Light::LT_DIRECTIONAL) + lightCount[1]++; + else if (curParams.mType == Light::LT_SPOTLIGHT) + lightCount[2]++; + } } //----------------------------------------------------------------------- const String& NormalMapLightingFactory::getType() const { - return NormalMapLighting::Type; + return NormalMapLighting::Type; } //----------------------------------------------------------------------- -SubRenderState* NormalMapLightingFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* NormalMapLightingFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "lighting_stage") - { - if(prop->values.size() >= 2) - { - String strValue; - AbstractNodeList::const_iterator it = prop->values.begin(); - - // Read light model type. - if(false == SGScriptTranslator::getString(*it, &strValue)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - return NULL; - } - - // Case light model type is normal map - if (strValue == "normal_map") - { - ++it; - if (false == SGScriptTranslator::getString(*it, &strValue)) - { - compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); - return NULL; - } - - - SubRenderState* subRenderState = createOrRetrieveInstance(translator); - NormalMapLighting* normalMapSubRenderState = static_cast(subRenderState); - - normalMapSubRenderState->setNormalMapTextureName(strValue); - - - // Read normal map space type. - if (prop->values.size() >= 3) - { - ++it; - if (false == SGScriptTranslator::getString(*it, &strValue)) - { - compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); - return NULL; - } - - // Normal map defines normals in tangent space. - if (strValue == "tangent_space") - { - normalMapSubRenderState->setNormalMapSpace(NormalMapLighting::NMS_TANGENT); - } - - // Normal map defines normals in object space. - if (strValue == "object_space") - { - normalMapSubRenderState->setNormalMapSpace(NormalMapLighting::NMS_OBJECT); - } - } - - // Read texture coordinate index. - if (prop->values.size() >= 4) - { - unsigned int textureCoordinateIndex = 0; - - ++it; - if (SGScriptTranslator::getUInt(*it, &textureCoordinateIndex)) - { - normalMapSubRenderState->setTexCoordIndex(textureCoordinateIndex); - } - } - - // Read texture filtering format. - if (prop->values.size() >= 5) - { - ++it; - if (false == SGScriptTranslator::getString(*it, &strValue)) - { - compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); - return NULL; - } - - if (strValue == "none") - { - normalMapSubRenderState->setNormalMapFiltering(FO_POINT, FO_POINT, FO_NONE); - } - - else if (strValue == "bilinear") - { - normalMapSubRenderState->setNormalMapFiltering(FO_LINEAR, FO_LINEAR, FO_POINT); - } - - else if (strValue == "trilinear") - { - normalMapSubRenderState->setNormalMapFiltering(FO_LINEAR, FO_LINEAR, FO_LINEAR); - } - - else if (strValue == "anisotropic") - { - normalMapSubRenderState->setNormalMapFiltering(FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR); - } - } - - // Read max anisotropy value. - if (prop->values.size() >= 6) - { - unsigned int maxAnisotropy = 0; - - ++it; - if (SGScriptTranslator::getUInt(*it, &maxAnisotropy)) - { - normalMapSubRenderState->setNormalMapAnisotropy(maxAnisotropy); - } - } - - // Read mip bias value. - if (prop->values.size() >= 7) - { - Real mipBias = 0; - - ++it; - if (SGScriptTranslator::getReal(*it, &mipBias)) - { - normalMapSubRenderState->setNormalMapMipBias(mipBias); - } - } - - return subRenderState; - } - } - } - - return NULL; + if (prop->name == "lighting_stage") + { + if(prop->values.size() >= 2) + { + String strValue; + AbstractNodeList::const_iterator it = prop->values.begin(); + + // Read light model type. + if(false == SGScriptTranslator::getString(*it, &strValue)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + return NULL; + } + + // Case light model type is normal map + if (strValue == "normal_map") + { + ++it; + if (false == SGScriptTranslator::getString(*it, &strValue)) + { + compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); + return NULL; + } + + + SubRenderState* subRenderState = createOrRetrieveInstance(translator); + NormalMapLighting* normalMapSubRenderState = static_cast(subRenderState); + + normalMapSubRenderState->setNormalMapTextureName(strValue); + + + // Read normal map space type. + if (prop->values.size() >= 3) + { + ++it; + if (false == SGScriptTranslator::getString(*it, &strValue)) + { + compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); + return NULL; + } + + // Normal map defines normals in tangent space. + if (strValue == "tangent_space") + { + normalMapSubRenderState->setNormalMapSpace(NormalMapLighting::NMS_TANGENT); + } + + // Normal map defines normals in object space. + if (strValue == "object_space") + { + normalMapSubRenderState->setNormalMapSpace(NormalMapLighting::NMS_OBJECT); + } + } + + // Read texture coordinate index. + if (prop->values.size() >= 4) + { + unsigned int textureCoordinateIndex = 0; + + ++it; + if (SGScriptTranslator::getUInt(*it, &textureCoordinateIndex)) + { + normalMapSubRenderState->setTexCoordIndex(textureCoordinateIndex); + } + } + + // Read texture filtering format. + if (prop->values.size() >= 5) + { + ++it; + if (false == SGScriptTranslator::getString(*it, &strValue)) + { + compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); + return NULL; + } + + if (strValue == "none") + { + normalMapSubRenderState->setNormalMapFiltering(FO_POINT, FO_POINT, FO_NONE); + } + + else if (strValue == "bilinear") + { + normalMapSubRenderState->setNormalMapFiltering(FO_LINEAR, FO_LINEAR, FO_POINT); + } + + else if (strValue == "trilinear") + { + normalMapSubRenderState->setNormalMapFiltering(FO_LINEAR, FO_LINEAR, FO_LINEAR); + } + + else if (strValue == "anisotropic") + { + normalMapSubRenderState->setNormalMapFiltering(FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR); + } + } + + // Read max anisotropy value. + if (prop->values.size() >= 6) + { + unsigned int maxAnisotropy = 0; + + ++it; + if (SGScriptTranslator::getUInt(*it, &maxAnisotropy)) + { + normalMapSubRenderState->setNormalMapAnisotropy(maxAnisotropy); + } + } + + // Read mip bias value. + if (prop->values.size() >= 7) + { + Real mipBias = 0; + + ++it; + if (SGScriptTranslator::getReal(*it, &mipBias)) + { + normalMapSubRenderState->setNormalMapMipBias(mipBias); + } + } + + return subRenderState; + } + } + } + + return NULL; } //----------------------------------------------------------------------- void NormalMapLightingFactory::writeInstance(MaterialSerializer* ser, - SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + SubRenderState* subRenderState, + Pass* srcPass, Pass* dstPass) { - NormalMapLighting* normalMapSubRenderState = static_cast(subRenderState); - - ser->writeAttribute(4, "lighting_stage"); - ser->writeValue("normal_map"); - ser->writeValue(normalMapSubRenderState->getNormalMapTextureName()); - - if (normalMapSubRenderState->getNormalMapSpace() == NormalMapLighting::NMS_TANGENT) - { - ser->writeValue("tangent_space"); - } - else if (normalMapSubRenderState->getNormalMapSpace() == NormalMapLighting::NMS_OBJECT) - { - ser->writeValue("object_space"); - } - - ser->writeValue(StringConverter::toString(normalMapSubRenderState->getTexCoordIndex())); + NormalMapLighting* normalMapSubRenderState = static_cast(subRenderState); + + ser->writeAttribute(4, "lighting_stage"); + ser->writeValue("normal_map"); + ser->writeValue(normalMapSubRenderState->getNormalMapTextureName()); + + if (normalMapSubRenderState->getNormalMapSpace() == NormalMapLighting::NMS_TANGENT) + { + ser->writeValue("tangent_space"); + } + else if (normalMapSubRenderState->getNormalMapSpace() == NormalMapLighting::NMS_OBJECT) + { + ser->writeValue("object_space"); + } + + ser->writeValue(StringConverter::toString(normalMapSubRenderState->getTexCoordIndex())); } //----------------------------------------------------------------------- -SubRenderState* NormalMapLightingFactory::createInstanceImpl() +SubRenderState* NormalMapLightingFactory::createInstanceImpl() { - return OGRE_NEW NormalMapLighting; + return OGRE_NEW NormalMapLighting; } } diff --git a/Components/RTShaderSystem/src/OgreShaderExPerPixelLighting.cpp b/Components/RTShaderSystem/src/OgreShaderExPerPixelLighting.cpp index 332b488bd21..86af7eec924 100644 --- a/Components/RTShaderSystem/src/OgreShaderExPerPixelLighting.cpp +++ b/Components/RTShaderSystem/src/OgreShaderExPerPixelLighting.cpp @@ -47,852 +47,852 @@ Light PerPixelLighting::msBlankLight; //----------------------------------------------------------------------- PerPixelLighting::PerPixelLighting() { - mTrackVertexColourType = TVC_NONE; - mSpecularEnable = false; + mTrackVertexColourType = TVC_NONE; + mSpecularEnable = false; - msBlankLight.setDiffuseColour(ColourValue::Black); - msBlankLight.setSpecularColour(ColourValue::Black); - msBlankLight.setAttenuation(0,1,0,0); + msBlankLight.setDiffuseColour(ColourValue::Black); + msBlankLight.setSpecularColour(ColourValue::Black); + msBlankLight.setAttenuation(0,1,0,0); } //----------------------------------------------------------------------- const String& PerPixelLighting::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int PerPixelLighting::getExecutionOrder() const +int PerPixelLighting::getExecutionOrder() const { - return FFP_LIGHTING; + return FFP_LIGHTING; } //----------------------------------------------------------------------- void PerPixelLighting::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, - const LightList* pLightList) + const LightList* pLightList) { - if (mLightParamsList.empty()) - return; - - const Matrix4& matView = source->getViewMatrix(); - Light::LightTypes curLightType = Light::LT_DIRECTIONAL; - unsigned int curSearchLightIndex = 0; - - // Update per light parameters. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - const LightParams& curParams = mLightParamsList[i]; - - if (curLightType != curParams.mType) - { - curLightType = curParams.mType; - curSearchLightIndex = 0; - } - - Light* srcLight = NULL; - Vector4 vParameter; - ColourValue colour; - - // Search a matching light from the current sorted lights of the given renderable. - for (unsigned int j = curSearchLightIndex; j < pLightList->size(); ++j) - { - if (pLightList->at(j)->getType() == curLightType) - { - srcLight = pLightList->at(j); - curSearchLightIndex = j + 1; - break; - } - } - - // No matching light found -> use a blank dummy light for parameter update. - if (srcLight == NULL) - { - srcLight = &msBlankLight; - } - - - switch (curParams.mType) - { - case Light::LT_DIRECTIONAL: - - // Update light direction. - vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); - curParams.mDirection->setGpuParameter(vParameter); - break; - - case Light::LT_POINT: - - // Update light position. - vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); - curParams.mPosition->setGpuParameter(vParameter); - - // Update light attenuation parameters. - vParameter.x = srcLight->getAttenuationRange(); - vParameter.y = srcLight->getAttenuationConstant(); - vParameter.z = srcLight->getAttenuationLinear(); - vParameter.w = srcLight->getAttenuationQuadric(); - curParams.mAttenuatParams->setGpuParameter(vParameter); - break; - - case Light::LT_SPOTLIGHT: - { - Vector3 vec3; - Matrix3 matViewIT; - - - // Update light position. - vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); - curParams.mPosition->setGpuParameter(vParameter); - - - // Update light direction. - source->getInverseTransposeViewMatrix().extract3x3Matrix(matViewIT); - vec3 = matViewIT * srcLight->getDerivedDirection(); - vec3.normalise(); - - vParameter.x = -vec3.x; - vParameter.y = -vec3.y; - vParameter.z = -vec3.z; - vParameter.w = 0.0; - curParams.mDirection->setGpuParameter(vParameter); - - // Update light attenuation parameters. - vParameter.x = srcLight->getAttenuationRange(); - vParameter.y = srcLight->getAttenuationConstant(); - vParameter.z = srcLight->getAttenuationLinear(); - vParameter.w = srcLight->getAttenuationQuadric(); - curParams.mAttenuatParams->setGpuParameter(vParameter); - - // Update spotlight parameters. - Real phi = Math::Cos(srcLight->getSpotlightOuterAngle().valueRadians() * 0.5f); - Real theta = Math::Cos(srcLight->getSpotlightInnerAngle().valueRadians() * 0.5f); - - vec3.x = theta; - vec3.y = phi; - vec3.z = srcLight->getSpotlightFalloff(); - - curParams.mSpotParams->setGpuParameter(vec3); - } - break; - } - - - // Update diffuse colour. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - colour = srcLight->getDiffuseColour() * pass->getDiffuse() * srcLight->getPowerScale(); - curParams.mDiffuseColour->setGpuParameter(colour); - } - else - { - colour = srcLight->getDiffuseColour() * srcLight->getPowerScale(); - curParams.mDiffuseColour->setGpuParameter(colour); - } - - // Update specular colour if need to. - if (mSpecularEnable) - { - // Update diffuse colour. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - colour = srcLight->getSpecularColour() * pass->getSpecular() * srcLight->getPowerScale(); - curParams.mSpecularColour->setGpuParameter(colour); - } - else - { - colour = srcLight->getSpecularColour() * srcLight->getPowerScale(); - curParams.mSpecularColour->setGpuParameter(colour); - } - } - } + if (mLightParamsList.empty()) + return; + + const Matrix4& matView = source->getViewMatrix(); + Light::LightTypes curLightType = Light::LT_DIRECTIONAL; + unsigned int curSearchLightIndex = 0; + + // Update per light parameters. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + const LightParams& curParams = mLightParamsList[i]; + + if (curLightType != curParams.mType) + { + curLightType = curParams.mType; + curSearchLightIndex = 0; + } + + Light* srcLight = NULL; + Vector4 vParameter; + ColourValue colour; + + // Search a matching light from the current sorted lights of the given renderable. + for (unsigned int j = curSearchLightIndex; j < pLightList->size(); ++j) + { + if (pLightList->at(j)->getType() == curLightType) + { + srcLight = pLightList->at(j); + curSearchLightIndex = j + 1; + break; + } + } + + // No matching light found -> use a blank dummy light for parameter update. + if (srcLight == NULL) + { + srcLight = &msBlankLight; + } + + + switch (curParams.mType) + { + case Light::LT_DIRECTIONAL: + + // Update light direction. + vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); + curParams.mDirection->setGpuParameter(vParameter); + break; + + case Light::LT_POINT: + + // Update light position. + vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); + curParams.mPosition->setGpuParameter(vParameter); + + // Update light attenuation parameters. + vParameter.x = srcLight->getAttenuationRange(); + vParameter.y = srcLight->getAttenuationConstant(); + vParameter.z = srcLight->getAttenuationLinear(); + vParameter.w = srcLight->getAttenuationQuadric(); + curParams.mAttenuatParams->setGpuParameter(vParameter); + break; + + case Light::LT_SPOTLIGHT: + { + Vector3 vec3; + Matrix3 matViewIT; + + + // Update light position. + vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); + curParams.mPosition->setGpuParameter(vParameter); + + + // Update light direction. + source->getInverseTransposeViewMatrix().extract3x3Matrix(matViewIT); + vec3 = matViewIT * srcLight->getDerivedDirection(); + vec3.normalise(); + + vParameter.x = -vec3.x; + vParameter.y = -vec3.y; + vParameter.z = -vec3.z; + vParameter.w = 0.0; + curParams.mDirection->setGpuParameter(vParameter); + + // Update light attenuation parameters. + vParameter.x = srcLight->getAttenuationRange(); + vParameter.y = srcLight->getAttenuationConstant(); + vParameter.z = srcLight->getAttenuationLinear(); + vParameter.w = srcLight->getAttenuationQuadric(); + curParams.mAttenuatParams->setGpuParameter(vParameter); + + // Update spotlight parameters. + Real phi = Math::Cos(srcLight->getSpotlightOuterAngle().valueRadians() * 0.5f); + Real theta = Math::Cos(srcLight->getSpotlightInnerAngle().valueRadians() * 0.5f); + + vec3.x = theta; + vec3.y = phi; + vec3.z = srcLight->getSpotlightFalloff(); + + curParams.mSpotParams->setGpuParameter(vec3); + } + break; + } + + + // Update diffuse colour. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + colour = srcLight->getDiffuseColour() * pass->getDiffuse() * srcLight->getPowerScale(); + curParams.mDiffuseColour->setGpuParameter(colour); + } + else + { + colour = srcLight->getDiffuseColour() * srcLight->getPowerScale(); + curParams.mDiffuseColour->setGpuParameter(colour); + } + + // Update specular colour if need to. + if (mSpecularEnable) + { + // Update diffuse colour. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + colour = srcLight->getSpecularColour() * pass->getSpecular() * srcLight->getPowerScale(); + curParams.mSpecularColour->setGpuParameter(colour); + } + else + { + colour = srcLight->getSpecularColour() * srcLight->getPowerScale(); + curParams.mSpecularColour->setGpuParameter(colour); + } + } + } } //----------------------------------------------------------------------- bool PerPixelLighting::resolveParameters(ProgramSet* programSet) { - if (false == resolveGlobalParameters(programSet)) - return false; - - if (false == resolvePerLightParameters(programSet)) - return false; - - return true; + if (false == resolveGlobalParameters(programSet)) + return false; + + if (false == resolvePerLightParameters(programSet)) + return false; + + return true; } //----------------------------------------------------------------------- bool PerPixelLighting::resolveGlobalParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - bool hasError = false; - // Resolve world view IT matrix. - mWorldViewITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, 0); - hasError |= !(mWorldViewITMatrix.get()); - - // Get surface ambient colour if need to. - if ((mTrackVertexColourType & TVC_AMBIENT) == 0) - { - mDerivedAmbientLightColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR, 0); - hasError |= !(mDerivedAmbientLightColour.get()); - } - else - { - mLightAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, 0); - mSurfaceAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR, 0); - - hasError |= !(mSurfaceAmbientColour.get()) || !(mLightAmbientColour.get()); - } - - // Get surface diffuse colour if need to. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - mSurfaceDiffuseColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR, 0); - hasError |= !(mSurfaceDiffuseColour.get()); - } - - // Get surface specular colour if need to. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - mSurfaceSpecularColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR, 0); - hasError |= !(mSurfaceSpecularColour.get()); - } - - - // Get surface emissive colour if need to. - if ((mTrackVertexColourType & TVC_EMISSIVE) == 0) - { - mSurfaceEmissiveColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR, 0); - hasError |= !(mSurfaceEmissiveColour.get()); - } - - // Get derived scene colour. - mDerivedSceneColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, 0); - - // Get surface shininess. - mSurfaceShininess = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SHININESS, 0); - - // Resolve input vertex shader normal. - mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - - // Resolve output vertex shader normal. - mVSOutNormal = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_NORMAL_VIEW_SPACE, GCT_FLOAT3); - - // Resolve input pixel shader normal. - mPSInNormal = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutNormal->getIndex(), - mVSOutNormal->getContent(), - GCT_FLOAT3); - - const ShaderParameterList& inputParams = psMain->getInputParameters(); - const ShaderParameterList& localParams = psMain->getLocalParameters(); - - mPSDiffuse = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - if (mPSDiffuse.get() == NULL) - { - mPSDiffuse = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - } - - mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - mPSTempDiffuseColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lPerPixelDiffuse", GCT_FLOAT4); - - hasError |= !(mDerivedSceneColour.get()) || !(mSurfaceShininess.get()) || !(mVSInNormal.get()) || !(mVSOutNormal.get()) || !(mPSInNormal.get()) || !( - mPSDiffuse.get()) || !(mPSOutDiffuse.get()) || !(mPSTempDiffuseColour.get()); - - if (mSpecularEnable) - { - mPSSpecular = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - if (mPSSpecular.get() == NULL) - { - mPSSpecular = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - } - - mPSTempSpecularColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lPerPixelSpecular", GCT_FLOAT4); - - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - - mVSOutViewPos = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_VIEW_SPACE, GCT_FLOAT3); - - mPSInViewPos = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutViewPos->getIndex(), - mVSOutViewPos->getContent(), - GCT_FLOAT3); - - mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); - - hasError |= !(mPSSpecular.get()) || !(mPSTempSpecularColour.get()) || !(mVSInPosition.get()) || !(mVSOutViewPos.get()) || - !(mPSInViewPos.get()) || !(mWorldViewMatrix.get()); - } - - if (hasError) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "PerPixelLighting::resolveGlobalParameters" ); - } - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + bool hasError = false; + // Resolve world view IT matrix. + mWorldViewITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, 0); + hasError |= !(mWorldViewITMatrix.get()); + + // Get surface ambient colour if need to. + if ((mTrackVertexColourType & TVC_AMBIENT) == 0) + { + mDerivedAmbientLightColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR, 0); + hasError |= !(mDerivedAmbientLightColour.get()); + } + else + { + mLightAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, 0); + mSurfaceAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR, 0); + + hasError |= !(mSurfaceAmbientColour.get()) || !(mLightAmbientColour.get()); + } + + // Get surface diffuse colour if need to. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + mSurfaceDiffuseColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR, 0); + hasError |= !(mSurfaceDiffuseColour.get()); + } + + // Get surface specular colour if need to. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + mSurfaceSpecularColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR, 0); + hasError |= !(mSurfaceSpecularColour.get()); + } + + + // Get surface emissive colour if need to. + if ((mTrackVertexColourType & TVC_EMISSIVE) == 0) + { + mSurfaceEmissiveColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR, 0); + hasError |= !(mSurfaceEmissiveColour.get()); + } + + // Get derived scene colour. + mDerivedSceneColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, 0); + + // Get surface shininess. + mSurfaceShininess = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SHININESS, 0); + + // Resolve input vertex shader normal. + mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + + // Resolve output vertex shader normal. + mVSOutNormal = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_NORMAL_VIEW_SPACE, GCT_FLOAT3); + + // Resolve input pixel shader normal. + mPSInNormal = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutNormal->getIndex(), + mVSOutNormal->getContent(), + GCT_FLOAT3); + + const ShaderParameterList& inputParams = psMain->getInputParameters(); + const ShaderParameterList& localParams = psMain->getLocalParameters(); + + mPSDiffuse = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + if (mPSDiffuse.get() == NULL) + { + mPSDiffuse = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + } + + mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + mPSTempDiffuseColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lPerPixelDiffuse", GCT_FLOAT4); + + hasError |= !(mDerivedSceneColour.get()) || !(mSurfaceShininess.get()) || !(mVSInNormal.get()) || !(mVSOutNormal.get()) || !(mPSInNormal.get()) || !( + mPSDiffuse.get()) || !(mPSOutDiffuse.get()) || !(mPSTempDiffuseColour.get()); + + if (mSpecularEnable) + { + mPSSpecular = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + if (mPSSpecular.get() == NULL) + { + mPSSpecular = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + } + + mPSTempSpecularColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lPerPixelSpecular", GCT_FLOAT4); + + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + + mVSOutViewPos = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_VIEW_SPACE, GCT_FLOAT3); + + mPSInViewPos = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutViewPos->getIndex(), + mVSOutViewPos->getContent(), + GCT_FLOAT3); + + mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); + + hasError |= !(mPSSpecular.get()) || !(mPSTempSpecularColour.get()) || !(mVSInPosition.get()) || !(mVSOutViewPos.get()) || + !(mPSInViewPos.get()) || !(mWorldViewMatrix.get()); + } + + if (hasError) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "PerPixelLighting::resolveGlobalParameters" ); + } + return true; } //----------------------------------------------------------------------- bool PerPixelLighting::resolvePerLightParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - bool hasError = false; - - // Resolve per light parameters. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - switch (mLightParamsList[i].mType) - { - case Light::LT_DIRECTIONAL: - mLightParamsList[i].mDirection = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_direction_view_space"); - break; - - case Light::LT_POINT: - mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - mLightParamsList[i].mPosition = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_position_view_space"); - mLightParamsList[i].mAttenuatParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); - - if (mVSOutViewPos.get() == NULL) - { - mVSOutViewPos = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_VIEW_SPACE, GCT_FLOAT3); - - mPSInViewPos = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutViewPos->getIndex(), - mVSOutViewPos->getContent(), - GCT_FLOAT3); - } - - hasError |= !(mWorldViewMatrix.get()) || !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || - !(mLightParamsList[i].mAttenuatParams.get()) || !(mVSOutViewPos.get()) || !(mPSInViewPos.get()); - - break; - - case Light::LT_SPOTLIGHT: - mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); - - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - mLightParamsList[i].mPosition = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_position_view_space"); - mLightParamsList[i].mDirection = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_direction_view_space"); - mLightParamsList[i].mAttenuatParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); - - mLightParamsList[i].mSpotParams = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "spotlight_params"); - - if (mVSOutViewPos.get() == NULL) - { - mVSOutViewPos = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_VIEW_SPACE, GCT_FLOAT3); - - mPSInViewPos = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutViewPos->getIndex(), - mVSOutViewPos->getContent(), - GCT_FLOAT3); - } - - hasError |= !(mWorldViewMatrix.get()) || !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || - !(mLightParamsList[i].mDirection.get()) || !(mLightParamsList[i].mAttenuatParams.get()) || - !(mLightParamsList[i].mSpotParams.get()) || !(mVSOutViewPos.get()) || !(mPSInViewPos.get()); - - break; - } - - // Resolve diffuse colour. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS | (uint16)GPV_GLOBAL, "derived_light_diffuse"); - } - else - { - mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_diffuse"); - } - - hasError |= !(mLightParamsList[i].mDiffuseColour.get()); - - if (mSpecularEnable) - { - // Resolve specular colour. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS | (uint16)GPV_GLOBAL, "derived_light_specular"); - } - else - { - mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_specular"); - } - hasError |= !(mLightParamsList[i].mSpecularColour.get()); - } - } - - if (hasError) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "PerPixelLighting::resolvePerLightParameters" ); - } - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + bool hasError = false; + + // Resolve per light parameters. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + switch (mLightParamsList[i].mType) + { + case Light::LT_DIRECTIONAL: + mLightParamsList[i].mDirection = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_direction_view_space"); + break; + + case Light::LT_POINT: + mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + mLightParamsList[i].mPosition = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_position_view_space"); + mLightParamsList[i].mAttenuatParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); + + if (mVSOutViewPos.get() == NULL) + { + mVSOutViewPos = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_VIEW_SPACE, GCT_FLOAT3); + + mPSInViewPos = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutViewPos->getIndex(), + mVSOutViewPos->getContent(), + GCT_FLOAT3); + } + + hasError |= !(mWorldViewMatrix.get()) || !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || + !(mLightParamsList[i].mAttenuatParams.get()) || !(mVSOutViewPos.get()) || !(mPSInViewPos.get()); + + break; + + case Light::LT_SPOTLIGHT: + mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); + + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + mLightParamsList[i].mPosition = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_position_view_space"); + mLightParamsList[i].mDirection = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_direction_view_space"); + mLightParamsList[i].mAttenuatParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); + + mLightParamsList[i].mSpotParams = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "spotlight_params"); + + if (mVSOutViewPos.get() == NULL) + { + mVSOutViewPos = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_VIEW_SPACE, GCT_FLOAT3); + + mPSInViewPos = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutViewPos->getIndex(), + mVSOutViewPos->getContent(), + GCT_FLOAT3); + } + + hasError |= !(mWorldViewMatrix.get()) || !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || + !(mLightParamsList[i].mDirection.get()) || !(mLightParamsList[i].mAttenuatParams.get()) || + !(mLightParamsList[i].mSpotParams.get()) || !(mVSOutViewPos.get()) || !(mPSInViewPos.get()); + + break; + } + + // Resolve diffuse colour. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS | (uint16)GPV_GLOBAL, "derived_light_diffuse"); + } + else + { + mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_diffuse"); + } + + hasError |= !(mLightParamsList[i].mDiffuseColour.get()); + + if (mSpecularEnable) + { + // Resolve specular colour. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS | (uint16)GPV_GLOBAL, "derived_light_specular"); + } + else + { + mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_specular"); + } + hasError |= !(mLightParamsList[i].mSpecularColour.get()); + } + } + + if (hasError) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "PerPixelLighting::resolvePerLightParameters" ); + } + return true; } //----------------------------------------------------------------------- bool PerPixelLighting::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); - vsProgram->addDependency(FFP_LIB_COMMON); - vsProgram->addDependency(SGX_LIB_PERPIXELLIGHTING); + vsProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(SGX_LIB_PERPIXELLIGHTING); - psProgram->addDependency(FFP_LIB_COMMON); - psProgram->addDependency(SGX_LIB_PERPIXELLIGHTING); + psProgram->addDependency(FFP_LIB_COMMON); + psProgram->addDependency(SGX_LIB_PERPIXELLIGHTING); - return true; + return true; } //----------------------------------------------------------------------- bool PerPixelLighting::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* psMain = psProgram->getEntryPointFunction(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* psMain = psProgram->getEntryPointFunction(); - int internalCounter = 0; + int internalCounter = 0; - // Add the global illumination functions. - if (false == addVSInvocation(vsMain, FFP_VS_LIGHTING, internalCounter)) - return false; + // Add the global illumination functions. + if (false == addVSInvocation(vsMain, FFP_VS_LIGHTING, internalCounter)) + return false; - internalCounter = 0; + internalCounter = 0; - // Add the global illumination functions. - if (false == addPSGlobalIlluminationInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; + // Add the global illumination functions. + if (false == addPSGlobalIlluminationInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; - // Add per light functions. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - if (false == addPSIlluminationInvocation(&mLightParamsList[i], psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; - } + // Add per light functions. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + if (false == addPSIlluminationInvocation(&mLightParamsList[i], psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; + } - // Assign back temporary variables to the ps diffuse and specular components. - if (false == addPSFinalAssignmentInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; + // Assign back temporary variables to the ps diffuse and specular components. + if (false == addPSFinalAssignmentInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; - return true; + return true; } //----------------------------------------------------------------------- bool PerPixelLighting::addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - // Transform normal in view space. - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - // Transform view space position if need to. - if (mVSOutViewPos.get() != NULL) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMPOSITION, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutViewPos, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - - return true; + FunctionInvocation* curFuncInvocation = NULL; + + // Transform normal in view space. + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + // Transform view space position if need to. + if (mVSOutViewPos.get() != NULL) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRANSFORMPOSITION, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutViewPos, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + + return true; } //----------------------------------------------------------------------- bool PerPixelLighting::addPSGlobalIlluminationInvocation(Function* psMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && - (mTrackVertexColourType & TVC_EMISSIVE) == 0) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - if (mTrackVertexColourType & TVC_AMBIENT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mDerivedAmbientLightColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - if (mTrackVertexColourType & TVC_EMISSIVE) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mSurfaceEmissiveColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - } - - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - return true; + FunctionInvocation* curFuncInvocation = NULL; + + if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && + (mTrackVertexColourType & TVC_EMISSIVE) == 0) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + if (mTrackVertexColourType & TVC_AMBIENT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mDerivedAmbientLightColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + if (mTrackVertexColourType & TVC_EMISSIVE) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mSurfaceEmissiveColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + } + + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + return true; } //----------------------------------------------------------------------- bool PerPixelLighting::addPSIlluminationInvocation(LightParams* curLightParams, Function* psMain, const int groupOrder, int& internalCounter) -{ - FunctionInvocation* curFuncInvocation = NULL; - - // Merge diffuse colour with vertex colour if need to. - if (mTrackVertexColourType & TVC_DIFFUSE) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - // Merge specular colour with vertex colour if need to. - if (mSpecularEnable && mTrackVertexColourType & TVC_SPECULAR) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - switch (curLightParams->mType) - { - - case Light::LT_DIRECTIONAL: - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInViewPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - break; - - case Light::LT_POINT: - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_POINT_DIFFUSESPECULAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInViewPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_POINT_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInViewPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - break; - - case Light::LT_SPOTLIGHT: - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_SPOT_DIFFUSESPECULAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInViewPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_SPOT_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInViewPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - break; - } - - return true; +{ + FunctionInvocation* curFuncInvocation = NULL; + + // Merge diffuse colour with vertex colour if need to. + if (mTrackVertexColourType & TVC_DIFFUSE) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + // Merge specular colour with vertex colour if need to. + if (mSpecularEnable && mTrackVertexColourType & TVC_SPECULAR) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + switch (curLightParams->mType) + { + + case Light::LT_DIRECTIONAL: + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInViewPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_DIRECTIONAL_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + break; + + case Light::LT_POINT: + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_POINT_DIFFUSESPECULAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInViewPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_POINT_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInViewPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + break; + + case Light::LT_SPOTLIGHT: + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_SPOT_DIFFUSESPECULAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInViewPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_LIGHT_SPOT_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInViewPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + break; + } + + return true; } //----------------------------------------------------------------------- bool PerPixelLighting::addPSFinalAssignmentInvocation( Function* psMain, const int groupOrder, int& internalCounter ) { - FunctionInvocation* curFuncInvocation; - - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - return true; + FunctionInvocation* curFuncInvocation; + + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + return true; } //----------------------------------------------------------------------- void PerPixelLighting::copyFrom(const SubRenderState& rhs) { - const PerPixelLighting& rhsLighting = static_cast(rhs); + const PerPixelLighting& rhsLighting = static_cast(rhs); - int lightCount[3]; + int lightCount[3]; - rhsLighting.getLightCount(lightCount); - setLightCount(lightCount); + rhsLighting.getLightCount(lightCount); + setLightCount(lightCount); } //----------------------------------------------------------------------- bool PerPixelLighting::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { - if (srcPass->getLightingEnabled() == false) - return false; - - int lightCount[3]; - - renderState->getLightCount(lightCount); - - setTrackVertexColourType(srcPass->getVertexColourTracking()); - - if (srcPass->getShininess() > 0.0 && - srcPass->getSpecular() != ColourValue::Black) - { - setSpecularEnable(true); - } - else - { - setSpecularEnable(false); - } - - // Case this pass should run once per light(s) -> override the light policy. - if (srcPass->getIteratePerLight()) - { - - // This is the preferred case -> only one type of light is handled. - if (srcPass->getRunOnlyForOneLightType()) - { - if (srcPass->getOnlyLightType() == Light::LT_POINT) - { - lightCount[0] = srcPass->getLightCountPerIteration(); - lightCount[1] = 0; - lightCount[2] = 0; - } - else if (srcPass->getOnlyLightType() == Light::LT_DIRECTIONAL) - { - lightCount[0] = 0; - lightCount[1] = srcPass->getLightCountPerIteration(); - lightCount[2] = 0; - } - else if (srcPass->getOnlyLightType() == Light::LT_SPOTLIGHT) - { - lightCount[0] = 0; - lightCount[1] = 0; - lightCount[2] = srcPass->getLightCountPerIteration(); - } - } - - // This is worse case -> all light types expected to be handled. - // Can not handle this request in efficient way - throw an exception. - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Using iterative lighting method with RT Shader System requires specifying explicit light type.", - "PerPixelLighting::preAddToRenderState"); - } - } - - setLightCount(lightCount); - - return true; + if (srcPass->getLightingEnabled() == false) + return false; + + int lightCount[3]; + + renderState->getLightCount(lightCount); + + setTrackVertexColourType(srcPass->getVertexColourTracking()); + + if (srcPass->getShininess() > 0.0 && + srcPass->getSpecular() != ColourValue::Black) + { + setSpecularEnable(true); + } + else + { + setSpecularEnable(false); + } + + // Case this pass should run once per light(s) -> override the light policy. + if (srcPass->getIteratePerLight()) + { + + // This is the preferred case -> only one type of light is handled. + if (srcPass->getRunOnlyForOneLightType()) + { + if (srcPass->getOnlyLightType() == Light::LT_POINT) + { + lightCount[0] = srcPass->getLightCountPerIteration(); + lightCount[1] = 0; + lightCount[2] = 0; + } + else if (srcPass->getOnlyLightType() == Light::LT_DIRECTIONAL) + { + lightCount[0] = 0; + lightCount[1] = srcPass->getLightCountPerIteration(); + lightCount[2] = 0; + } + else if (srcPass->getOnlyLightType() == Light::LT_SPOTLIGHT) + { + lightCount[0] = 0; + lightCount[1] = 0; + lightCount[2] = srcPass->getLightCountPerIteration(); + } + } + + // This is worse case -> all light types expected to be handled. + // Can not handle this request in efficient way - throw an exception. + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Using iterative lighting method with RT Shader System requires specifying explicit light type.", + "PerPixelLighting::preAddToRenderState"); + } + } + + setLightCount(lightCount); + + return true; } //----------------------------------------------------------------------- void PerPixelLighting::setLightCount(const int lightCount[3]) { - for (int type=0; type < 3; ++type) - { - for (int i=0; i < lightCount[type]; ++i) - { - LightParams curParams; - - if (type == 0) - curParams.mType = Light::LT_POINT; - else if (type == 1) - curParams.mType = Light::LT_DIRECTIONAL; - else if (type == 2) - curParams.mType = Light::LT_SPOTLIGHT; - - mLightParamsList.push_back(curParams); - } - } + for (int type=0; type < 3; ++type) + { + for (int i=0; i < lightCount[type]; ++i) + { + LightParams curParams; + + if (type == 0) + curParams.mType = Light::LT_POINT; + else if (type == 1) + curParams.mType = Light::LT_DIRECTIONAL; + else if (type == 2) + curParams.mType = Light::LT_SPOTLIGHT; + + mLightParamsList.push_back(curParams); + } + } } //----------------------------------------------------------------------- void PerPixelLighting::getLightCount(int lightCount[3]) const { - lightCount[0] = 0; - lightCount[1] = 0; - lightCount[2] = 0; - - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - const LightParams curParams = mLightParamsList[i]; - - if (curParams.mType == Light::LT_POINT) - lightCount[0]++; - else if (curParams.mType == Light::LT_DIRECTIONAL) - lightCount[1]++; - else if (curParams.mType == Light::LT_SPOTLIGHT) - lightCount[2]++; - } + lightCount[0] = 0; + lightCount[1] = 0; + lightCount[2] = 0; + + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + const LightParams curParams = mLightParamsList[i]; + + if (curParams.mType == Light::LT_POINT) + lightCount[0]++; + else if (curParams.mType == Light::LT_DIRECTIONAL) + lightCount[1]++; + else if (curParams.mType == Light::LT_SPOTLIGHT) + lightCount[2]++; + } } //----------------------------------------------------------------------- const String& PerPixelLightingFactory::getType() const { - return PerPixelLighting::Type; + return PerPixelLighting::Type; } //----------------------------------------------------------------------- -SubRenderState* PerPixelLightingFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* PerPixelLightingFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "lighting_stage") - { - if(prop->values.size() == 1) - { - String modelType; - - if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - return NULL; - } - - if (modelType == "per_pixel") - { - return createOrRetrieveInstance(translator); - } - } - } - - return NULL; + if (prop->name == "lighting_stage") + { + if(prop->values.size() == 1) + { + String modelType; + + if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + return NULL; + } + + if (modelType == "per_pixel") + { + return createOrRetrieveInstance(translator); + } + } + } + + return NULL; } //----------------------------------------------------------------------- void PerPixelLightingFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + Pass* srcPass, Pass* dstPass) { - ser->writeAttribute(4, "lighting_stage"); - ser->writeValue("per_pixel"); + ser->writeAttribute(4, "lighting_stage"); + ser->writeValue("per_pixel"); } //----------------------------------------------------------------------- -SubRenderState* PerPixelLightingFactory::createInstanceImpl() +SubRenderState* PerPixelLightingFactory::createInstanceImpl() { - return OGRE_NEW PerPixelLighting; + return OGRE_NEW PerPixelLighting; } } diff --git a/Components/RTShaderSystem/src/OgreShaderExTextureAtlasSampler.cpp b/Components/RTShaderSystem/src/OgreShaderExTextureAtlasSampler.cpp index dc63e62b93d..f25f3de9e85 100644 --- a/Components/RTShaderSystem/src/OgreShaderExTextureAtlasSampler.cpp +++ b/Components/RTShaderSystem/src/OgreShaderExTextureAtlasSampler.cpp @@ -55,7 +55,7 @@ namespace RTShader { void operator<<(std::ostream& o, const TextureAtlasSamplerFactory::TextureAtlasAttib& tai) { - o << tai.autoBorderAdjust << tai.positionMode << tai.positionOffset; + o << tai.autoBorderAdjust << tai.positionMode << tai.positionOffset; } const TextureAtlasTablePtr c_BlankAtlasTable; @@ -65,303 +65,303 @@ String c_RTAtlasKey = "RTAtlas"; //----------------------------------------------------------------------- TextureAtlasSampler::TextureAtlasSampler() : - mAtlasTexcoordPos(0), - mIsTableDataUpdated(false), - mAutoAdjustPollPosition(true) + mAtlasTexcoordPos(0), + mIsTableDataUpdated(false), + mAutoAdjustPollPosition(true) { mTextureAddressings->u = mTextureAddressings->v = mTextureAddressings->w = TextureUnitState::TAM_UNKNOWN; - memset(mIsAtlasTextureUnits, 0, sizeof(bool) * TAS_MAX_TEXTURES); + memset(mIsAtlasTextureUnits, 0, sizeof(bool) * TAS_MAX_TEXTURES); } //----------------------------------------------------------------------- const String& TextureAtlasSampler::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int TextureAtlasSampler::getExecutionOrder() const +int TextureAtlasSampler::getExecutionOrder() const { - return FFP_TEXTURING + 25; + return FFP_TEXTURING + 25; } //----------------------------------------------------------------------- bool TextureAtlasSampler::resolveParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - - - // - // Define vertex shader parameters used to find the position of the textures in the atlas - // - Parameter::Content indexContent = (Parameter::Content)((int)Parameter::SPC_TEXTURE_COORDINATE0 + mAtlasTexcoordPos); - GpuConstantType indexType = GCT_FLOAT4; - - mVSInpTextureTableIndex = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mAtlasTexcoordPos, indexContent, indexType); - - - // - // Define parameters to carry the information on the location of the texture from the vertex to - // the pixel shader - // - for(ushort i = 0 ; i < TAS_MAX_TEXTURES ; ++ i) - { - if (mIsAtlasTextureUnits[i] == true) - { - mVSTextureTable[i] = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "AtlasData", mAtlasTableDatas[i]->size()); - mVSOutTextureDatas[i] = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, - -1, Parameter::SPC_UNKNOWN, GCT_FLOAT4); - mPSInpTextureDatas[i] = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutTextureDatas[i]->getIndex(), Parameter::SPC_UNKNOWN, GCT_FLOAT4); - mPSTextureSizes[i] = psProgram->resolveParameter(GCT_FLOAT2,-1, (uint16)GPV_PER_OBJECT, "AtlasSize"); - } - } - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + + + // + // Define vertex shader parameters used to find the position of the textures in the atlas + // + Parameter::Content indexContent = (Parameter::Content)((int)Parameter::SPC_TEXTURE_COORDINATE0 + mAtlasTexcoordPos); + GpuConstantType indexType = GCT_FLOAT4; + + mVSInpTextureTableIndex = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mAtlasTexcoordPos, indexContent, indexType); + + + // + // Define parameters to carry the information on the location of the texture from the vertex to + // the pixel shader + // + for(ushort i = 0 ; i < TAS_MAX_TEXTURES ; ++ i) + { + if (mIsAtlasTextureUnits[i] == true) + { + mVSTextureTable[i] = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "AtlasData", mAtlasTableDatas[i]->size()); + mVSOutTextureDatas[i] = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, + -1, Parameter::SPC_UNKNOWN, GCT_FLOAT4); + mPSInpTextureDatas[i] = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutTextureDatas[i]->getIndex(), Parameter::SPC_UNKNOWN, GCT_FLOAT4); + mPSTextureSizes[i] = psProgram->resolveParameter(GCT_FLOAT2,-1, (uint16)GPV_PER_OBJECT, "AtlasSize"); + } + } + return true; } //----------------------------------------------------------------------- bool TextureAtlasSampler::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - vsProgram->addDependency(FFP_LIB_COMMON); - psProgram->addDependency(SGX_LIB_TEXTURE_ATLAS); + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + vsProgram->addDependency(FFP_LIB_COMMON); + psProgram->addDependency(SGX_LIB_TEXTURE_ATLAS); - return true; + return true; } //----------------------------------------------------------------------- bool TextureAtlasSampler::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* psMain = psProgram->getEntryPointFunction(); - FunctionInvocation* curFuncInvocation = NULL; - - // - // Calculate the position and size of the texture in the atlas in the vertex shader - // - int groupOrder = (FFP_VS_TEXTURING - FFP_VS_LIGHTING) / 2; - int internalCounter = 0; - - for(ushort i = 0 ; i < TAS_MAX_TEXTURES; ++i) - { - if (mIsAtlasTextureUnits[i] == true) - { - Operand::OpMask textureIndexMask = Operand::OPM_X; - switch (i) - { - case 1: textureIndexMask = Operand::OPM_Y; break; - case 2: textureIndexMask = Operand::OPM_Z; break; - case 3: textureIndexMask = Operand::OPM_W; break; - } - - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSTextureTable[i], Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInpTextureTableIndex, Operand::OPS_IN, textureIndexMask, 1); - curFuncInvocation->pushOperand(mVSOutTextureDatas[i], Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - } - - // - // sample the texture in the fragment shader given the extracted data in the pixel shader - // - - - groupOrder = (FFP_PS_SAMPLING + FFP_PS_TEXTURING) / 2; - - internalCounter = 0; - - const ShaderParameterList& inpParams = psMain->getInputParameters(); - const ShaderParameterList& localParams = psMain->getLocalParameters(); - - ParameterPtr psAtlasTextureCoord = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, - -1, "atlasCoord", GCT_FLOAT2); - - for(ushort j = 0 ; j < TAS_MAX_TEXTURES; ++j) - { - if (mIsAtlasTextureUnits[j] == true) - { - //Find the texture coordinates texel and sampler from the original FFPTexturing - ParameterPtr texcoord = psMain->getParameterByContent(inpParams, (Parameter::Content)(Parameter::SPC_TEXTURE_COORDINATE0 + j), GCT_FLOAT2); - ParameterPtr texel = psMain->getParameterByName(localParams, c_ParamTexel + Ogre::StringConverter::toString(j)); - UniformParameterPtr sampler = psProgram->getParameterByType(GCT_SAMPLER2D, j); - UniformParameterPtr samplerState; - if (Ogre::RTShader::ShaderGenerator::getSingletonPtr()->IsHlsl4()) - samplerState = psProgram->getParameterByType(GCT_SAMPLER_STATE, j); - - const char* addressUFuncName = getAdressingFunctionName(mTextureAddressings[j].u); - const char* addressVFuncName = getAdressingFunctionName(mTextureAddressings[j].v); - - //Create a function which will replace the texel with the texture texel - if ((texcoord.isNull() == false) && (texel.isNull() == false) && - (sampler.isNull() == false) && (addressUFuncName != NULL) && (addressVFuncName != NULL)) - { - //calculate the U value due to addressing mode - curFuncInvocation = OGRE_NEW FunctionInvocation(addressUFuncName, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(texcoord, Operand::OPS_IN, Operand::OPM_X); - curFuncInvocation->pushOperand(psAtlasTextureCoord, Operand::OPS_OUT, Operand::OPM_X); - psMain->addAtomInstance(curFuncInvocation); - - //calculate the V value due to addressing mode - curFuncInvocation = OGRE_NEW FunctionInvocation(addressVFuncName, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(texcoord, Operand::OPS_IN, Operand::OPM_Y); - curFuncInvocation->pushOperand(psAtlasTextureCoord, Operand::OPS_OUT, Operand::OPM_Y); - psMain->addAtomInstance(curFuncInvocation); - - bool isHLSL = Ogre::RTShader::ShaderGenerator::getSingleton().getTargetLanguage() == "hlsl"; - - if (isHLSL) - FFPTexturing::AddTextureSampleWrapperInvocation(sampler,samplerState,GCT_SAMPLER2D,psMain,groupOrder,internalCounter); - - //sample the texel color - curFuncInvocation = OGRE_NEW FunctionInvocation( - mAutoAdjustPollPosition ? SGX_FUNC_ATLAS_SAMPLE_AUTO_ADJUST : SGX_FUNC_ATLAS_SAMPLE_NORMAL, groupOrder, internalCounter++); - if (isHLSL) - curFuncInvocation->pushOperand(FFPTexturing::GetSamplerWrapperParam(GCT_SAMPLER2D,psMain), Operand::OPS_IN); - else - curFuncInvocation->pushOperand(sampler, Operand::OPS_IN); - curFuncInvocation->pushOperand(texcoord, Operand::OPS_IN, Operand::OPM_XY); - curFuncInvocation->pushOperand(psAtlasTextureCoord, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInpTextureDatas[j], Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTextureSizes[j], Operand::OPS_IN); - curFuncInvocation->pushOperand(texel, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - } - } - } - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* psMain = psProgram->getEntryPointFunction(); + FunctionInvocation* curFuncInvocation = NULL; + + // + // Calculate the position and size of the texture in the atlas in the vertex shader + // + int groupOrder = (FFP_VS_TEXTURING - FFP_VS_LIGHTING) / 2; + int internalCounter = 0; + + for(ushort i = 0 ; i < TAS_MAX_TEXTURES; ++i) + { + if (mIsAtlasTextureUnits[i] == true) + { + Operand::OpMask textureIndexMask = Operand::OPM_X; + switch (i) + { + case 1: textureIndexMask = Operand::OPM_Y; break; + case 2: textureIndexMask = Operand::OPM_Z; break; + case 3: textureIndexMask = Operand::OPM_W; break; + } + + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSTextureTable[i], Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInpTextureTableIndex, Operand::OPS_IN, textureIndexMask, 1); + curFuncInvocation->pushOperand(mVSOutTextureDatas[i], Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + } + + // + // sample the texture in the fragment shader given the extracted data in the pixel shader + // + + + groupOrder = (FFP_PS_SAMPLING + FFP_PS_TEXTURING) / 2; + + internalCounter = 0; + + const ShaderParameterList& inpParams = psMain->getInputParameters(); + const ShaderParameterList& localParams = psMain->getLocalParameters(); + + ParameterPtr psAtlasTextureCoord = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, + -1, "atlasCoord", GCT_FLOAT2); + + for(ushort j = 0 ; j < TAS_MAX_TEXTURES; ++j) + { + if (mIsAtlasTextureUnits[j] == true) + { + //Find the texture coordinates texel and sampler from the original FFPTexturing + ParameterPtr texcoord = psMain->getParameterByContent(inpParams, (Parameter::Content)(Parameter::SPC_TEXTURE_COORDINATE0 + j), GCT_FLOAT2); + ParameterPtr texel = psMain->getParameterByName(localParams, c_ParamTexel + Ogre::StringConverter::toString(j)); + UniformParameterPtr sampler = psProgram->getParameterByType(GCT_SAMPLER2D, j); + UniformParameterPtr samplerState; + if (Ogre::RTShader::ShaderGenerator::getSingletonPtr()->IsHlsl4()) + samplerState = psProgram->getParameterByType(GCT_SAMPLER_STATE, j); + + const char* addressUFuncName = getAdressingFunctionName(mTextureAddressings[j].u); + const char* addressVFuncName = getAdressingFunctionName(mTextureAddressings[j].v); + + //Create a function which will replace the texel with the texture texel + if ((texcoord.isNull() == false) && (texel.isNull() == false) && + (sampler.isNull() == false) && (addressUFuncName != NULL) && (addressVFuncName != NULL)) + { + //calculate the U value due to addressing mode + curFuncInvocation = OGRE_NEW FunctionInvocation(addressUFuncName, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(texcoord, Operand::OPS_IN, Operand::OPM_X); + curFuncInvocation->pushOperand(psAtlasTextureCoord, Operand::OPS_OUT, Operand::OPM_X); + psMain->addAtomInstance(curFuncInvocation); + + //calculate the V value due to addressing mode + curFuncInvocation = OGRE_NEW FunctionInvocation(addressVFuncName, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(texcoord, Operand::OPS_IN, Operand::OPM_Y); + curFuncInvocation->pushOperand(psAtlasTextureCoord, Operand::OPS_OUT, Operand::OPM_Y); + psMain->addAtomInstance(curFuncInvocation); + + bool isHLSL = Ogre::RTShader::ShaderGenerator::getSingleton().getTargetLanguage() == "hlsl"; + + if (isHLSL) + FFPTexturing::AddTextureSampleWrapperInvocation(sampler,samplerState,GCT_SAMPLER2D,psMain,groupOrder,internalCounter); + + //sample the texel color + curFuncInvocation = OGRE_NEW FunctionInvocation( + mAutoAdjustPollPosition ? SGX_FUNC_ATLAS_SAMPLE_AUTO_ADJUST : SGX_FUNC_ATLAS_SAMPLE_NORMAL, groupOrder, internalCounter++); + if (isHLSL) + curFuncInvocation->pushOperand(FFPTexturing::GetSamplerWrapperParam(GCT_SAMPLER2D,psMain), Operand::OPS_IN); + else + curFuncInvocation->pushOperand(sampler, Operand::OPS_IN); + curFuncInvocation->pushOperand(texcoord, Operand::OPS_IN, Operand::OPM_XY); + curFuncInvocation->pushOperand(psAtlasTextureCoord, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInpTextureDatas[j], Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTextureSizes[j], Operand::OPS_IN); + curFuncInvocation->pushOperand(texel, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + } + } + } + return true; } //----------------------------------------------------------------------- const char* TextureAtlasSampler::getAdressingFunctionName(TextureUnitState::TextureAddressingMode mode) { - switch (mode) - { - case TextureUnitState::TAM_WRAP: return SGX_FUNC_ATLAS_WRAP; + switch (mode) + { + case TextureUnitState::TAM_WRAP: return SGX_FUNC_ATLAS_WRAP; case TextureUnitState::TAM_UNKNOWN: return SGX_FUNC_ATLAS_WRAP; - case TextureUnitState::TAM_MIRROR: return SGX_FUNC_ATLAS_MIRROR; - case TextureUnitState::TAM_CLAMP: return SGX_FUNC_ATLAS_CLAMP; - case TextureUnitState::TAM_BORDER: return SGX_FUNC_ATLAS_BORDER; - } - return NULL; + case TextureUnitState::TAM_MIRROR: return SGX_FUNC_ATLAS_MIRROR; + case TextureUnitState::TAM_CLAMP: return SGX_FUNC_ATLAS_CLAMP; + case TextureUnitState::TAM_BORDER: return SGX_FUNC_ATLAS_BORDER; + } + return NULL; } //----------------------------------------------------------------------- void TextureAtlasSampler::copyFrom(const SubRenderState& rhs) { - const TextureAtlasSampler& rhsColour = static_cast(rhs); - - mAtlasTexcoordPos = rhsColour.mAtlasTexcoordPos; - for(ushort j = 0 ; j < TAS_MAX_TEXTURES ; ++j) - { - mIsAtlasTextureUnits[j] = rhsColour.mIsAtlasTextureUnits[j]; - mTextureAddressings[j] = rhsColour.mTextureAddressings[j]; - mAtlasTableDatas[j] = rhsColour.mAtlasTableDatas[j]; - mIsAtlasTextureUnits[j] = rhsColour.mIsAtlasTextureUnits[j]; - } + const TextureAtlasSampler& rhsColour = static_cast(rhs); + + mAtlasTexcoordPos = rhsColour.mAtlasTexcoordPos; + for(ushort j = 0 ; j < TAS_MAX_TEXTURES ; ++j) + { + mIsAtlasTextureUnits[j] = rhsColour.mIsAtlasTextureUnits[j]; + mTextureAddressings[j] = rhsColour.mTextureAddressings[j]; + mAtlasTableDatas[j] = rhsColour.mAtlasTableDatas[j]; + mIsAtlasTextureUnits[j] = rhsColour.mIsAtlasTextureUnits[j]; + } } //----------------------------------------------------------------------- void TextureAtlasSampler::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList) { - if (mIsTableDataUpdated == false) - { - mIsTableDataUpdated = true; - for(ushort j = 0 ; j < TAS_MAX_TEXTURES ; ++j) - { - if (mIsAtlasTextureUnits[j] == true) - { - // - // Update the information of the size of the atlas textures - // - std::pair< size_t, size_t > texSizeInt = pass->getTextureUnitState(j)->getTextureDimensions(); + if (mIsTableDataUpdated == false) + { + mIsTableDataUpdated = true; + for(ushort j = 0 ; j < TAS_MAX_TEXTURES ; ++j) + { + if (mIsAtlasTextureUnits[j] == true) + { + // + // Update the information of the size of the atlas textures + // + std::pair< size_t, size_t > texSizeInt = pass->getTextureUnitState(j)->getTextureDimensions(); Vector2 texSize((Ogre::Real)texSizeInt.first, (Ogre::Real)texSizeInt.second); - mPSTextureSizes[j]->setGpuParameter(texSize); - - // - //Update the information of which texture exist where in the atlas - // - GpuProgramParametersSharedPtr vsGpuParams = pass->getVertexProgramParameters(); - vector::type buffer(mAtlasTableDatas[j]->size() * 4); - for(size_t i = 0 ; i < mAtlasTableDatas[j]->size() ; ++i) - { - buffer[i*4] = (*(mAtlasTableDatas[j]))[i].posU; - buffer[i*4 + 1] = (*(mAtlasTableDatas[j]))[i].posV; - buffer[i*4 + 2] = (float)Ogre::Math::Log2((*(mAtlasTableDatas[j]))[i].width * texSize.x); - buffer[i*4 + 3] = (float)Ogre::Math::Log2((*(mAtlasTableDatas[j]))[i].height * texSize.y); - } - vsGpuParams->setNamedConstant(mVSTextureTable[j]->getName(), (const float*)(&(buffer[0])), (mAtlasTableDatas[j])->size()); - } - } - } + mPSTextureSizes[j]->setGpuParameter(texSize); + + // + //Update the information of which texture exist where in the atlas + // + GpuProgramParametersSharedPtr vsGpuParams = pass->getVertexProgramParameters(); + vector::type buffer(mAtlasTableDatas[j]->size() * 4); + for(size_t i = 0 ; i < mAtlasTableDatas[j]->size() ; ++i) + { + buffer[i*4] = (*(mAtlasTableDatas[j]))[i].posU; + buffer[i*4 + 1] = (*(mAtlasTableDatas[j]))[i].posV; + buffer[i*4 + 2] = (float)Ogre::Math::Log2((*(mAtlasTableDatas[j]))[i].width * texSize.x); + buffer[i*4 + 3] = (float)Ogre::Math::Log2((*(mAtlasTableDatas[j]))[i].height * texSize.y); + } + vsGpuParams->setNamedConstant(mVSTextureTable[j]->getName(), (const float*)(&(buffer[0])), (mAtlasTableDatas[j])->size()); + } + } + } } //----------------------------------------------------------------------- bool TextureAtlasSampler::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { - mAtlasTexcoordPos = 0; - - const TextureAtlasSamplerFactory& factory = TextureAtlasSamplerFactory::getSingleton(); - - bool hasAtlas = false; - unsigned short texCount = srcPass->getNumTextureUnitStates(); - for(unsigned short i = 0 ; i < texCount ; ++i) - { - TextureUnitState* pState = srcPass->getTextureUnitState(i); - - const TextureAtlasTablePtr& table = factory.getTextureAtlasTable(pState->getTextureName()); - if (table.isNull() == false) - { - if (table->size() > TAS_MAX_SAFE_ATLASED_TEXTURES) - { - LogManager::getSingleton().logMessage(LML_CRITICAL, - "Warning : Compiling atlas texture has to many internally defined textures. Shader may fail to compile."); - } - if (i >= TAS_MAX_TEXTURES) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Texture atlas sub-render does not support more than TAS_MAX_TEXTURES (4) atlas textures", - "TextureAtlasSampler::preAddToRenderState" ); - } - if (pState->getTextureType() != TEX_TYPE_2D) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Texture atlas sub-render state only supports 2d textures.", - "TextureAtlasSampler::preAddToRenderState" ); - - } - - mAtlasTableDatas[i] = table; - mTextureAddressings[i] = pState->getTextureAddressingMode(); - mIsAtlasTextureUnits[i] = true; - hasAtlas = true; - } - } - - //gather the materials atlas processing attributes - //and calculate the position of the indexes - TextureAtlasSamplerFactory::TextureAtlasAttib attrib; - factory.hasMaterialAtlasingAttributes(srcPass->getParent()->getParent(), &attrib); - - mAutoAdjustPollPosition = attrib.autoBorderAdjust; - mAtlasTexcoordPos = attrib.positionOffset; - if (attrib.positionMode == TextureAtlasSamplerFactory::ipmRelative) - { - mAtlasTexcoordPos += texCount - 1; - } - - return hasAtlas; + mAtlasTexcoordPos = 0; + + const TextureAtlasSamplerFactory& factory = TextureAtlasSamplerFactory::getSingleton(); + + bool hasAtlas = false; + unsigned short texCount = srcPass->getNumTextureUnitStates(); + for(unsigned short i = 0 ; i < texCount ; ++i) + { + TextureUnitState* pState = srcPass->getTextureUnitState(i); + + const TextureAtlasTablePtr& table = factory.getTextureAtlasTable(pState->getTextureName()); + if (table.isNull() == false) + { + if (table->size() > TAS_MAX_SAFE_ATLASED_TEXTURES) + { + LogManager::getSingleton().logMessage(LML_CRITICAL, + "Warning : Compiling atlas texture has to many internally defined textures. Shader may fail to compile."); + } + if (i >= TAS_MAX_TEXTURES) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Texture atlas sub-render does not support more than TAS_MAX_TEXTURES (4) atlas textures", + "TextureAtlasSampler::preAddToRenderState" ); + } + if (pState->getTextureType() != TEX_TYPE_2D) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Texture atlas sub-render state only supports 2d textures.", + "TextureAtlasSampler::preAddToRenderState" ); + + } + + mAtlasTableDatas[i] = table; + mTextureAddressings[i] = pState->getTextureAddressingMode(); + mIsAtlasTextureUnits[i] = true; + hasAtlas = true; + } + } + + //gather the materials atlas processing attributes + //and calculate the position of the indexes + TextureAtlasSamplerFactory::TextureAtlasAttib attrib; + factory.hasMaterialAtlasingAttributes(srcPass->getParent()->getParent(), &attrib); + + mAutoAdjustPollPosition = attrib.autoBorderAdjust; + mAtlasTexcoordPos = attrib.positionOffset; + if (attrib.positionMode == TextureAtlasSamplerFactory::ipmRelative) + { + mAtlasTexcoordPos += texCount - 1; + } + + return hasAtlas; } TextureAtlasSamplerFactory::TextureAtlasSamplerFactory() @@ -372,11 +372,11 @@ TextureAtlasSamplerFactory::TextureAtlasSamplerFactory() TextureAtlasSamplerFactory* TextureAtlasSamplerFactory::getSingletonPtr(void) { - return msSingleton; + return msSingleton; } TextureAtlasSamplerFactory& TextureAtlasSamplerFactory::getSingleton(void) { - assert( msSingleton ); return ( *msSingleton ); + assert( msSingleton ); return ( *msSingleton ); } @@ -384,191 +384,191 @@ TextureAtlasSamplerFactory& TextureAtlasSamplerFactory::getSingleton(void) //----------------------------------------------------------------------- const String& TextureAtlasSamplerFactory::getType() const { - return TextureAtlasSampler::Type; + return TextureAtlasSampler::Type; } //----------------------------------------------------------------------- -SubRenderState* TextureAtlasSamplerFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* TextureAtlasSamplerFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - return NULL; + return NULL; } //----------------------------------------------------------------------- void TextureAtlasSamplerFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + Pass* srcPass, Pass* dstPass) { } //----------------------------------------------------------------------- bool TextureAtlasSamplerFactory::addTexutreAtlasDefinition( const Ogre::String& filename, TextureAtlasTablePtr textureAtlasTable ) { - std::ifstream inp; - inp.open(filename.c_str(), std::ios::in | std::ios::binary); - if(!inp) - { - OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, "'" + filename + "' file not found!", - "TextureAtlasSamplerFactory::addTexutreAtlasDefinition" ); - } - DataStreamPtr stream(OGRE_NEW FileStreamDataStream(filename, &inp, false)); - return addTexutreAtlasDefinition(stream, textureAtlasTable); + std::ifstream inp; + inp.open(filename.c_str(), std::ios::in | std::ios::binary); + if(!inp) + { + OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, "'" + filename + "' file not found!", + "TextureAtlasSamplerFactory::addTexutreAtlasDefinition" ); + } + DataStreamPtr stream(OGRE_NEW FileStreamDataStream(filename, &inp, false)); + return addTexutreAtlasDefinition(stream, textureAtlasTable); } //----------------------------------------------------------------------- bool TextureAtlasSamplerFactory::addTexutreAtlasDefinition( DataStreamPtr stream, TextureAtlasTablePtr textureAtlasTable ) { - stream->seek(0); - - bool isSuccess = false; - if (stream->isReadable() == true) - { - TextureAtlasMap tmpMap; - - while (stream->eof() == false) - { - String line = stream->getLine(true); - size_t nonWhiteSpacePos = line.find_first_not_of(" \t\r\n"); - //check this is a line with information - if ((nonWhiteSpacePos != String::npos) && (line[nonWhiteSpacePos] != '#')) - { - //parse the line - vector::type strings = StringUtil::split(line, ",\t"); - - if (strings.size() > 8) - { - String textureName = strings[1]; - - TextureAtlasMap::iterator it = tmpMap.find(textureName); - if (tmpMap.find(textureName) == tmpMap.end()) - { - it = tmpMap.insert(TextureAtlasMap::value_type(textureName, TextureAtlasTablePtr(new TextureAtlasTable))).first; - } - - // file line format: /t/t, , , , , , , - // 0 1 2 3 4 5 6 7 8 - TextureAtlasRecord newRecord( - strings[0], // original texture filename - strings[1], // atlas filename - (float)StringConverter::parseReal(strings[4]), // woffset - (float)StringConverter::parseReal(strings[5]), // hoffset - (float)StringConverter::parseReal(strings[7]), // width - (float)StringConverter::parseReal(strings[8]), // height - it->second->size() // texture index in atlas texture - ); - - it->second->push_back(newRecord); - if (!textureAtlasTable.isNull()) - { - textureAtlasTable->push_back(newRecord); - } - - isSuccess = true; - } - } - } - - //place the information in the main texture - size_t maxTextureCount = 0; - TextureAtlasMap::const_iterator it = tmpMap.begin(); - TextureAtlasMap::const_iterator itEnd = tmpMap.end(); - for(;it != itEnd; ++it) - { - setTextureAtlasTable(it->first, it->second); - maxTextureCount = std::max(maxTextureCount, it->second->size()); - } - - if (maxTextureCount > TAS_MAX_SAFE_ATLASED_TEXTURES) - { - LogManager::getSingleton().logMessage(LML_CRITICAL, - ("Warning : " + stream->getName() + - " atlas texture has to many internally defined textures. Shader may fail to compile.")); - } - } - return isSuccess; + stream->seek(0); + + bool isSuccess = false; + if (stream->isReadable() == true) + { + TextureAtlasMap tmpMap; + + while (stream->eof() == false) + { + String line = stream->getLine(true); + size_t nonWhiteSpacePos = line.find_first_not_of(" \t\r\n"); + //check this is a line with information + if ((nonWhiteSpacePos != String::npos) && (line[nonWhiteSpacePos] != '#')) + { + //parse the line + vector::type strings = StringUtil::split(line, ",\t"); + + if (strings.size() > 8) + { + String textureName = strings[1]; + + TextureAtlasMap::iterator it = tmpMap.find(textureName); + if (tmpMap.find(textureName) == tmpMap.end()) + { + it = tmpMap.insert(TextureAtlasMap::value_type(textureName, TextureAtlasTablePtr(new TextureAtlasTable))).first; + } + + // file line format: /t/t, , , , , , , + // 0 1 2 3 4 5 6 7 8 + TextureAtlasRecord newRecord( + strings[0], // original texture filename + strings[1], // atlas filename + (float)StringConverter::parseReal(strings[4]), // woffset + (float)StringConverter::parseReal(strings[5]), // hoffset + (float)StringConverter::parseReal(strings[7]), // width + (float)StringConverter::parseReal(strings[8]), // height + it->second->size() // texture index in atlas texture + ); + + it->second->push_back(newRecord); + if (!textureAtlasTable.isNull()) + { + textureAtlasTable->push_back(newRecord); + } + + isSuccess = true; + } + } + } + + //place the information in the main texture + size_t maxTextureCount = 0; + TextureAtlasMap::const_iterator it = tmpMap.begin(); + TextureAtlasMap::const_iterator itEnd = tmpMap.end(); + for(;it != itEnd; ++it) + { + setTextureAtlasTable(it->first, it->second); + maxTextureCount = std::max(maxTextureCount, it->second->size()); + } + + if (maxTextureCount > TAS_MAX_SAFE_ATLASED_TEXTURES) + { + LogManager::getSingleton().logMessage(LML_CRITICAL, + ("Warning : " + stream->getName() + + " atlas texture has to many internally defined textures. Shader may fail to compile.")); + } + } + return isSuccess; } //----------------------------------------------------------------------- void TextureAtlasSamplerFactory::setTextureAtlasTable(const String& textureName, const TextureAtlasTablePtr& atlasData, bool autoBorderAdjust) { - if ((atlasData.isNull() == true) || (atlasData->empty())) - removeTextureAtlasTable(textureName); - else mAtlases.insert(TextureAtlasMap::value_type(textureName, atlasData)); + if ((atlasData.isNull() == true) || (atlasData->empty())) + removeTextureAtlasTable(textureName); + else mAtlases.insert(TextureAtlasMap::value_type(textureName, atlasData)); } //----------------------------------------------------------------------- void TextureAtlasSamplerFactory::removeTextureAtlasTable(const String& textureName) { - mAtlases.erase(textureName); + mAtlases.erase(textureName); } //----------------------------------------------------------------------- void TextureAtlasSamplerFactory::removeAllTextureAtlasTables() { - mAtlases.clear(); + mAtlases.clear(); } //----------------------------------------------------------------------- const TextureAtlasTablePtr& TextureAtlasSamplerFactory::getTextureAtlasTable(const String& textureName) const { - TextureAtlasMap::const_iterator it = mAtlases.find(textureName); - if (it != mAtlases.end()) - { - return it->second; - } - else return c_BlankAtlasTable; + TextureAtlasMap::const_iterator it = mAtlases.find(textureName); + if (it != mAtlases.end()) + { + return it->second; + } + else return c_BlankAtlasTable; } //----------------------------------------------------------------------- void TextureAtlasSamplerFactory::setDefaultAtlasingAttributes(IndexPositionMode mode, ushort offset, bool autoAdjustBorders) { - mDefaultAtlasAttrib = TextureAtlasAttib(mode, offset, autoAdjustBorders); + mDefaultAtlasAttrib = TextureAtlasAttib(mode, offset, autoAdjustBorders); } //----------------------------------------------------------------------- const TextureAtlasSamplerFactory::TextureAtlasAttib& TextureAtlasSamplerFactory::getDefaultAtlasingAttributes() const { - return mDefaultAtlasAttrib; + return mDefaultAtlasAttrib; } //----------------------------------------------------------------------- void TextureAtlasSamplerFactory::setMaterialAtlasingAttributes(Ogre::Material* material, - IndexPositionMode mode, ushort offset, bool autoAdjustBorders) + IndexPositionMode mode, ushort offset, bool autoAdjustBorders) { - if ((material) && (material->getNumTechniques())) - { - material->getTechnique(0)->getUserObjectBindings().setUserAny(c_RTAtlasKey, - Ogre::Any(TextureAtlasAttib(mode, offset, autoAdjustBorders))); - } + if ((material) && (material->getNumTechniques())) + { + material->getTechnique(0)->getUserObjectBindings().setUserAny(c_RTAtlasKey, + Ogre::Any(TextureAtlasAttib(mode, offset, autoAdjustBorders))); + } } //----------------------------------------------------------------------- bool TextureAtlasSamplerFactory::hasMaterialAtlasingAttributes(Ogre::Material* material, - TextureAtlasAttib* attrib) const + TextureAtlasAttib* attrib) const { - bool isMaterialSpecific = false; - if ((material) && (material->getNumTechniques())) - { - const Ogre::Any& anyAttrib = - //find if the "IsTerrain" flag exists in the first technique - material->getTechnique(0)->getUserObjectBindings().getUserAny(c_RTAtlasKey); - isMaterialSpecific = (anyAttrib.isEmpty() == false); - if ((isMaterialSpecific) && (attrib)) - { - *attrib = Ogre::any_cast(anyAttrib); - } - } - if ((!isMaterialSpecific) && (attrib)) - { - *attrib = mDefaultAtlasAttrib; - } - return isMaterialSpecific; + bool isMaterialSpecific = false; + if ((material) && (material->getNumTechniques())) + { + const Ogre::Any& anyAttrib = + //find if the "IsTerrain" flag exists in the first technique + material->getTechnique(0)->getUserObjectBindings().getUserAny(c_RTAtlasKey); + isMaterialSpecific = (anyAttrib.isEmpty() == false); + if ((isMaterialSpecific) && (attrib)) + { + *attrib = Ogre::any_cast(anyAttrib); + } + } + if ((!isMaterialSpecific) && (attrib)) + { + *attrib = mDefaultAtlasAttrib; + } + return isMaterialSpecific; } //----------------------------------------------------------------------- -SubRenderState* TextureAtlasSamplerFactory::createInstanceImpl() +SubRenderState* TextureAtlasSamplerFactory::createInstanceImpl() { - return OGRE_NEW TextureAtlasSampler; + return OGRE_NEW TextureAtlasSampler; } diff --git a/Components/RTShaderSystem/src/OgreShaderExTriplanarTexturing.cpp b/Components/RTShaderSystem/src/OgreShaderExTriplanarTexturing.cpp index 55e424e8f3b..5234ad5e720 100644 --- a/Components/RTShaderSystem/src/OgreShaderExTriplanarTexturing.cpp +++ b/Components/RTShaderSystem/src/OgreShaderExTriplanarTexturing.cpp @@ -84,7 +84,7 @@ namespace RTShader { return false; mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - if (mPSOutDiffuse.get() == NULL) + if (mPSOutDiffuse.get() == NULL) return false; mPSTPParams = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_GLOBAL, "gTPParams"); @@ -115,12 +115,12 @@ namespace RTShader { FunctionInvocation *curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, internalCounter++); curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT); + curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, internalCounter++); curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutPosition, Operand::OPS_OUT); + curFuncInvocation->pushOperand(mVSOutPosition, Operand::OPS_OUT); vsMain->addAtomInstance(curFuncInvocation); curFuncInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_TRIPLANAR_TEXTURING, FFP_PS_TEXTURING, internalCounter++); @@ -132,7 +132,7 @@ namespace RTShader { curFuncInvocation->pushOperand(mSamplerFromZ, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSTPParams, Operand::OPS_IN); curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); + psMain->addAtomInstance(curFuncInvocation); return true; } @@ -144,7 +144,7 @@ namespace RTShader { } //----------------------------------------------------------------------- - int TriplanarTexturing::getExecutionOrder() const + int TriplanarTexturing::getExecutionOrder() const { return FFP_TEXTURING; } @@ -156,15 +156,15 @@ namespace RTShader { // Create the mapping textures textureUnit = dstPass->createTextureUnitState(); - textureUnit->setTextureName(mTextureNameFromX); + textureUnit->setTextureName(mTextureNameFromX); mTextureSamplerIndexFromX = dstPass->getNumTextureUnitStates() - 1; textureUnit = dstPass->createTextureUnitState(); - textureUnit->setTextureName(mTextureNameFromY); + textureUnit->setTextureName(mTextureNameFromY); mTextureSamplerIndexFromY = dstPass->getNumTextureUnitStates() - 1; textureUnit = dstPass->createTextureUnitState(); - textureUnit->setTextureName(mTextureNameFromZ); + textureUnit->setTextureName(mTextureNameFromZ); mTextureSamplerIndexFromZ = dstPass->getNumTextureUnitStates() - 1; return true; } @@ -227,7 +227,7 @@ namespace RTShader { } //----------------------------------------------------------------------- - SubRenderState* TriplanarTexturingFactory::createInstance(ScriptCompiler* compiler, + SubRenderState* TriplanarTexturingFactory::createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { if (prop->name == "triplanarTexturing") @@ -237,7 +237,7 @@ namespace RTShader { SubRenderState* subRenderState = createOrRetrieveInstance(translator); TriplanarTexturing* tpSubRenderState = static_cast(subRenderState); - AbstractNodeList::const_iterator it = prop->values.begin(); + AbstractNodeList::const_iterator it = prop->values.begin(); float parameters[3]; if (false == SGScriptTranslator::getFloat(*it, parameters)) { @@ -291,7 +291,7 @@ namespace RTShader { } //----------------------------------------------------------------------- - SubRenderState* TriplanarTexturingFactory::createInstanceImpl() + SubRenderState* TriplanarTexturingFactory::createInstanceImpl() { return OGRE_NEW TriplanarTexturing; } diff --git a/Components/RTShaderSystem/src/OgreShaderFFPColour.cpp b/Components/RTShaderSystem/src/OgreShaderFFPColour.cpp index c7c61652ae8..c13db9a4253 100644 --- a/Components/RTShaderSystem/src/OgreShaderFFPColour.cpp +++ b/Components/RTShaderSystem/src/OgreShaderFFPColour.cpp @@ -44,290 +44,290 @@ String FFPColour::Type = "FFP_Colour"; //----------------------------------------------------------------------- FFPColour::FFPColour() { - mResolveStageFlags = SF_PS_OUTPUT_DIFFUSE; + mResolveStageFlags = SF_PS_OUTPUT_DIFFUSE; } //----------------------------------------------------------------------- const String& FFPColour::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int FFPColour::getExecutionOrder() const +int FFPColour::getExecutionOrder() const { - return FFP_COLOUR; + return FFP_COLOUR; } //----------------------------------------------------------------------- bool FFPColour::resolveParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - bool hasError = false; - - if (mResolveStageFlags & SF_VS_INPUT_DIFFUSE) - mVSInputDiffuse = vsMain->resolveInputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - - if (mResolveStageFlags & SF_VS_INPUT_SPECULAR) - mVSInputSpecular = vsMain->resolveInputParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - - // Resolve VS color outputs if have inputs from vertex stream. - if (mVSInputDiffuse.get() != NULL || mResolveStageFlags & SF_VS_OUTPUT_DIFFUSE) - mVSOutputDiffuse = vsMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - - if (mVSInputSpecular.get() != NULL || mResolveStageFlags & SF_VS_OUTPUT_SPECULAR) - mVSOutputSpecular = vsMain->resolveOutputParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - - // Resolve PS color inputs if have inputs from vertex shader. - if (mVSOutputDiffuse.get() != NULL || mResolveStageFlags & SF_PS_INPUT_DIFFUSE) - mPSInputDiffuse = psMain->resolveInputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - - if (mVSOutputSpecular.get() != NULL || mResolveStageFlags & SF_PS_INPUT_SPECULAR) - mPSInputSpecular = psMain->resolveInputParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - - - // Resolve PS output diffuse color. - if (mResolveStageFlags & SF_PS_OUTPUT_DIFFUSE) - { - mPSOutputDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - hasError |= !(mPSOutputDiffuse.get()); - } - - // Resolve PS output specular color. - if (mResolveStageFlags & SF_PS_OUTPUT_SPECULAR) - { - mPSOutputSpecular = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - hasError |= !(mPSOutputSpecular.get()); - } - - - if (hasError) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "FFPColour::resolveParameters" ); - } - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + bool hasError = false; + + if (mResolveStageFlags & SF_VS_INPUT_DIFFUSE) + mVSInputDiffuse = vsMain->resolveInputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + + if (mResolveStageFlags & SF_VS_INPUT_SPECULAR) + mVSInputSpecular = vsMain->resolveInputParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + + // Resolve VS color outputs if have inputs from vertex stream. + if (mVSInputDiffuse.get() != NULL || mResolveStageFlags & SF_VS_OUTPUT_DIFFUSE) + mVSOutputDiffuse = vsMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + + if (mVSInputSpecular.get() != NULL || mResolveStageFlags & SF_VS_OUTPUT_SPECULAR) + mVSOutputSpecular = vsMain->resolveOutputParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + + // Resolve PS color inputs if have inputs from vertex shader. + if (mVSOutputDiffuse.get() != NULL || mResolveStageFlags & SF_PS_INPUT_DIFFUSE) + mPSInputDiffuse = psMain->resolveInputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + + if (mVSOutputSpecular.get() != NULL || mResolveStageFlags & SF_PS_INPUT_SPECULAR) + mPSInputSpecular = psMain->resolveInputParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + + + // Resolve PS output diffuse color. + if (mResolveStageFlags & SF_PS_OUTPUT_DIFFUSE) + { + mPSOutputDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + hasError |= !(mPSOutputDiffuse.get()); + } + + // Resolve PS output specular color. + if (mResolveStageFlags & SF_PS_OUTPUT_SPECULAR) + { + mPSOutputSpecular = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + hasError |= !(mPSOutputSpecular.get()); + } + + + if (hasError) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "FFPColour::resolveParameters" ); + } + return true; } //----------------------------------------------------------------------- bool FFPColour::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); - vsProgram->addDependency(FFP_LIB_COMMON); - psProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(FFP_LIB_COMMON); + psProgram->addDependency(FFP_LIB_COMMON); - return true; + return true; } //----------------------------------------------------------------------- bool FFPColour::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - FunctionInvocation* curFuncInvocation = NULL; - int internalCounter; - - - // Create vertex shader colour invocations. - ParameterPtr vsDiffuse; - ParameterPtr vsSpecular; - internalCounter = 0; - if (mVSInputDiffuse.get() != NULL) - { - vsDiffuse = mVSInputDiffuse; - } - else - { - vsDiffuse = vsMain->resolveLocalParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_VS_COLOUR, internalCounter++); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(vsDiffuse, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - if (mVSOutputDiffuse.get() != NULL) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_COLOUR, internalCounter++); - curFuncInvocation->pushOperand(vsDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutputDiffuse, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - if (mVSInputSpecular.get() != NULL) - { - vsSpecular = mVSInputSpecular; - } - else - { - vsSpecular = vsMain->resolveLocalParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_VS_COLOUR, internalCounter++); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(vsSpecular, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - if (mVSOutputSpecular.get() != NULL) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_COLOUR, internalCounter++); - curFuncInvocation->pushOperand(vsSpecular, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutputSpecular, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - - - // Create fragment shader colour invocations. - ParameterPtr psDiffuse; - ParameterPtr psSpecular; - internalCounter = 0; - - // Handle diffuse colour. - if (mPSInputDiffuse.get() != NULL) - { - psDiffuse = mPSInputDiffuse; - } - else - { - psDiffuse = psMain->resolveLocalParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_PS_COLOUR_BEGIN, internalCounter++); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(psDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - // Handle specular colour. - if (mPSInputSpecular.get() != NULL) - { - psSpecular = mPSInputSpecular; - } - else - { - psSpecular = psMain->resolveLocalParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_PS_COLOUR_BEGIN, internalCounter++); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); - curFuncInvocation->pushOperand(psSpecular, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - // Assign diffuse colour. - if (mPSOutputDiffuse.get() != NULL) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN, internalCounter++); - curFuncInvocation->pushOperand(psDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - // Assign specular colour. - if (mPSOutputSpecular.get() != NULL) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN, internalCounter++); - curFuncInvocation->pushOperand(psSpecular, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutputSpecular, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - // Add specular to out colour. - internalCounter = 0; - if (mPSOutputDiffuse.get() != NULL && psSpecular.get() != NULL) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_PS_COLOUR_END, internalCounter++); - curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(psSpecular, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + FunctionInvocation* curFuncInvocation = NULL; + int internalCounter; + + + // Create vertex shader colour invocations. + ParameterPtr vsDiffuse; + ParameterPtr vsSpecular; + internalCounter = 0; + if (mVSInputDiffuse.get() != NULL) + { + vsDiffuse = mVSInputDiffuse; + } + else + { + vsDiffuse = vsMain->resolveLocalParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_VS_COLOUR, internalCounter++); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(vsDiffuse, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + if (mVSOutputDiffuse.get() != NULL) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_COLOUR, internalCounter++); + curFuncInvocation->pushOperand(vsDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutputDiffuse, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + if (mVSInputSpecular.get() != NULL) + { + vsSpecular = mVSInputSpecular; + } + else + { + vsSpecular = vsMain->resolveLocalParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_VS_COLOUR, internalCounter++); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(vsSpecular, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + if (mVSOutputSpecular.get() != NULL) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_COLOUR, internalCounter++); + curFuncInvocation->pushOperand(vsSpecular, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutputSpecular, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + + + // Create fragment shader colour invocations. + ParameterPtr psDiffuse; + ParameterPtr psSpecular; + internalCounter = 0; + + // Handle diffuse colour. + if (mPSInputDiffuse.get() != NULL) + { + psDiffuse = mPSInputDiffuse; + } + else + { + psDiffuse = psMain->resolveLocalParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_PS_COLOUR_BEGIN, internalCounter++); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(1.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(psDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + // Handle specular colour. + if (mPSInputSpecular.get() != NULL) + { + psSpecular = mPSInputSpecular; + } + else + { + psSpecular = psMain->resolveLocalParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, FFP_PS_COLOUR_BEGIN, internalCounter++); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(0.0), Operand::OPS_IN); + curFuncInvocation->pushOperand(psSpecular, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + // Assign diffuse colour. + if (mPSOutputDiffuse.get() != NULL) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN, internalCounter++); + curFuncInvocation->pushOperand(psDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + // Assign specular colour. + if (mPSOutputSpecular.get() != NULL) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN, internalCounter++); + curFuncInvocation->pushOperand(psSpecular, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutputSpecular, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + // Add specular to out colour. + internalCounter = 0; + if (mPSOutputDiffuse.get() != NULL && psSpecular.get() != NULL) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, FFP_PS_COLOUR_END, internalCounter++); + curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(psSpecular, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSOutputDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + return true; } //----------------------------------------------------------------------- void FFPColour::copyFrom(const SubRenderState& rhs) { - const FFPColour& rhsColour = static_cast(rhs); + const FFPColour& rhsColour = static_cast(rhs); - setResolveStageFlags(rhsColour.mResolveStageFlags); + setResolveStageFlags(rhsColour.mResolveStageFlags); } //----------------------------------------------------------------------- bool FFPColour::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { - TrackVertexColourType trackColour = srcPass->getVertexColourTracking(); + TrackVertexColourType trackColour = srcPass->getVertexColourTracking(); - if (trackColour != 0) - addResolveStageMask(FFPColour::SF_VS_INPUT_DIFFUSE); - - return true; + if (trackColour != 0) + addResolveStageMask(FFPColour::SF_VS_INPUT_DIFFUSE); + + return true; } //----------------------------------------------------------------------- const String& FFPColourFactory::getType() const { - return FFPColour::Type; + return FFPColour::Type; } //----------------------------------------------------------------------- -SubRenderState* FFPColourFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* FFPColourFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "colour_stage") - { - if(prop->values.size() == 1) - { - String modelType; - - if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - return NULL; - } - - if (modelType == "ffp") - { - return createOrRetrieveInstance(translator); - } - } - } - - return NULL; + if (prop->name == "colour_stage") + { + if(prop->values.size() == 1) + { + String modelType; + + if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + return NULL; + } + + if (modelType == "ffp") + { + return createOrRetrieveInstance(translator); + } + } + } + + return NULL; } //----------------------------------------------------------------------- void FFPColourFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + Pass* srcPass, Pass* dstPass) { - ser->writeAttribute(4, "colour_stage"); - ser->writeValue("ffp"); + ser->writeAttribute(4, "colour_stage"); + ser->writeValue("ffp"); } //----------------------------------------------------------------------- -SubRenderState* FFPColourFactory::createInstanceImpl() +SubRenderState* FFPColourFactory::createInstanceImpl() { - return OGRE_NEW FFPColour; + return OGRE_NEW FFPColour; } diff --git a/Components/RTShaderSystem/src/OgreShaderFFPFog.cpp b/Components/RTShaderSystem/src/OgreShaderFFPFog.cpp index 733316896ae..458a0803d15 100644 --- a/Components/RTShaderSystem/src/OgreShaderFFPFog.cpp +++ b/Components/RTShaderSystem/src/OgreShaderFFPFog.cpp @@ -45,402 +45,402 @@ String FFPFog::Type = "FFP_Fog"; //----------------------------------------------------------------------- FFPFog::FFPFog() { - mFogMode = FOG_NONE; - mCalcMode = CM_PER_VERTEX; - mPassOverrideParams = false; + mFogMode = FOG_NONE; + mCalcMode = CM_PER_VERTEX; + mPassOverrideParams = false; } //----------------------------------------------------------------------- const String& FFPFog::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int FFPFog::getExecutionOrder() const +int FFPFog::getExecutionOrder() const { - return FFP_FOG; + return FFP_FOG; } //----------------------------------------------------------------------- void FFPFog::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, - const LightList* pLightList) -{ - if (mFogMode == FOG_NONE) - return; - - FogMode fogMode; - ColourValue newFogColour; - Real newFogStart, newFogEnd, newFogDensity; - - if (mPassOverrideParams) - { - fogMode = pass->getFogMode(); - newFogColour = pass->getFogColour(); - newFogStart = pass->getFogStart(); - newFogEnd = pass->getFogEnd(); - newFogDensity = pass->getFogDensity(); - } - else - { - SceneManager* sceneMgr = ShaderGenerator::getSingleton().getActiveSceneManager(); - - fogMode = sceneMgr->getFogMode(); - newFogColour = sceneMgr->getFogColour(); - newFogStart = sceneMgr->getFogStart(); - newFogEnd = sceneMgr->getFogEnd(); - newFogDensity = sceneMgr->getFogDensity(); - } - - // Set fog properties. - setFogProperties(fogMode, newFogColour, newFogStart, newFogEnd, newFogDensity); + const LightList* pLightList) +{ + if (mFogMode == FOG_NONE) + return; + + FogMode fogMode; + ColourValue newFogColour; + Real newFogStart, newFogEnd, newFogDensity; + + if (mPassOverrideParams) + { + fogMode = pass->getFogMode(); + newFogColour = pass->getFogColour(); + newFogStart = pass->getFogStart(); + newFogEnd = pass->getFogEnd(); + newFogDensity = pass->getFogDensity(); + } + else + { + SceneManager* sceneMgr = ShaderGenerator::getSingleton().getActiveSceneManager(); + + fogMode = sceneMgr->getFogMode(); + newFogColour = sceneMgr->getFogColour(); + newFogStart = sceneMgr->getFogStart(); + newFogEnd = sceneMgr->getFogEnd(); + newFogDensity = sceneMgr->getFogDensity(); + } + + // Set fog properties. + setFogProperties(fogMode, newFogColour, newFogStart, newFogEnd, newFogDensity); mFogParams->setGpuParameter(mFogParamsValue); - mFogColour->setGpuParameter(mFogColourValue); + mFogColour->setGpuParameter(mFogColourValue); } //----------------------------------------------------------------------- bool FFPFog::resolveParameters(ProgramSet* programSet) { - if (mFogMode == FOG_NONE) - return true; - - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - bool hasError = false; - - // Resolve world view matrix. - mWorldViewProjMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); - - // Resolve vertex shader input position. - mVSInPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - - // Resolve fog colour. - mFogColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "gFogColor"); - - // Resolve pixel shader output diffuse color. - mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - - // Per pixel fog. - if (mCalcMode == CM_PER_PIXEL) - { - // Resolve fog params. - mFogParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "gFogParams"); - - // Resolve vertex shader output depth. - mVSOutDepth = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::SPC_DEPTH_VIEW_SPACE, - GCT_FLOAT1); - - // Resolve pixel shader input depth. - mPSInDepth = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSOutDepth->getIndex(), - mVSOutDepth->getContent(), - GCT_FLOAT1); - - hasError |= !(mPSInDepth.get()) || !(mVSOutDepth.get()) || !(mFogParams.get()); - } - // Per vertex fog. - else - { - // Resolve fog params. - mFogParams = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "gFogParams"); - - // Resolve vertex shader output fog factor. - mVSOutFogFactor = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::SPC_UNKNOWN, - GCT_FLOAT1); - - // Resolve pixel shader input fog factor. - mPSInFogFactor = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSOutFogFactor->getIndex(), - mVSOutFogFactor->getContent(), - GCT_FLOAT1); - - hasError |= !(mPSInFogFactor.get()) || !(mVSOutFogFactor.get()) || !(mFogParams.get()); - } - - hasError |= !(mWorldViewProjMatrix.get()) || !(mVSInPos.get()) || !(mFogColour.get()) || !(mPSOutDiffuse.get()); - - if (hasError) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "FFPFog::resolveParameters" ); - } - return true; + if (mFogMode == FOG_NONE) + return true; + + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + bool hasError = false; + + // Resolve world view matrix. + mWorldViewProjMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); + + // Resolve vertex shader input position. + mVSInPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + + // Resolve fog colour. + mFogColour = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "gFogColor"); + + // Resolve pixel shader output diffuse color. + mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + + // Per pixel fog. + if (mCalcMode == CM_PER_PIXEL) + { + // Resolve fog params. + mFogParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "gFogParams"); + + // Resolve vertex shader output depth. + mVSOutDepth = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::SPC_DEPTH_VIEW_SPACE, + GCT_FLOAT1); + + // Resolve pixel shader input depth. + mPSInDepth = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSOutDepth->getIndex(), + mVSOutDepth->getContent(), + GCT_FLOAT1); + + hasError |= !(mPSInDepth.get()) || !(mVSOutDepth.get()) || !(mFogParams.get()); + } + // Per vertex fog. + else + { + // Resolve fog params. + mFogParams = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "gFogParams"); + + // Resolve vertex shader output fog factor. + mVSOutFogFactor = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::SPC_UNKNOWN, + GCT_FLOAT1); + + // Resolve pixel shader input fog factor. + mPSInFogFactor = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSOutFogFactor->getIndex(), + mVSOutFogFactor->getContent(), + GCT_FLOAT1); + + hasError |= !(mPSInFogFactor.get()) || !(mVSOutFogFactor.get()) || !(mFogParams.get()); + } + + hasError |= !(mWorldViewProjMatrix.get()) || !(mVSInPos.get()) || !(mFogColour.get()) || !(mPSOutDiffuse.get()); + + if (hasError) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "FFPFog::resolveParameters" ); + } + return true; } //----------------------------------------------------------------------- bool FFPFog::resolveDependencies(ProgramSet* programSet) { - if (mFogMode == FOG_NONE) - return true; + if (mFogMode == FOG_NONE) + return true; - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); - vsProgram->addDependency(FFP_LIB_FOG); - psProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(FFP_LIB_FOG); + psProgram->addDependency(FFP_LIB_COMMON); - // Per pixel fog. - if (mCalcMode == CM_PER_PIXEL) - { - psProgram->addDependency(FFP_LIB_FOG); + // Per pixel fog. + if (mCalcMode == CM_PER_PIXEL) + { + psProgram->addDependency(FFP_LIB_FOG); - } + } - return true; + return true; } //----------------------------------------------------------------------- bool FFPFog::addFunctionInvocations(ProgramSet* programSet) { - if (mFogMode == FOG_NONE) - return true; - - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - FunctionInvocation* curFuncInvocation = NULL; - int internalCounter; - - - // Per pixel fog. - if (mCalcMode == CM_PER_PIXEL) - { - internalCounter = 0; - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_DEPTH, FFP_VS_FOG, internalCounter++); - curFuncInvocation->pushOperand(mWorldViewProjMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutDepth, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - internalCounter = 0; - switch (mFogMode) - { - case FOG_LINEAR: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_LINEAR, FFP_PS_FOG, internalCounter++); - break; - case FOG_EXP: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP, FFP_PS_FOG, internalCounter++); - break; - case FOG_EXP2: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP2, FFP_PS_FOG, internalCounter++); - break; + if (mFogMode == FOG_NONE) + return true; + + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + FunctionInvocation* curFuncInvocation = NULL; + int internalCounter; + + + // Per pixel fog. + if (mCalcMode == CM_PER_PIXEL) + { + internalCounter = 0; + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_DEPTH, FFP_VS_FOG, internalCounter++); + curFuncInvocation->pushOperand(mWorldViewProjMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutDepth, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + internalCounter = 0; + switch (mFogMode) + { + case FOG_LINEAR: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_LINEAR, FFP_PS_FOG, internalCounter++); + break; + case FOG_EXP: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP, FFP_PS_FOG, internalCounter++); + break; + case FOG_EXP2: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP2, FFP_PS_FOG, internalCounter++); + break; case FOG_NONE: default: break; - } - - curFuncInvocation->pushOperand(mPSInDepth, Operand::OPS_IN); - curFuncInvocation->pushOperand(mFogParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(mFogColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - } - - // Per vertex fog. - else - { - internalCounter = 0; - - switch (mFogMode) - { - case FOG_LINEAR: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_LINEAR, FFP_VS_FOG, internalCounter++); - break; - case FOG_EXP: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_EXP, FFP_VS_FOG, internalCounter++); - break; - case FOG_EXP2: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_EXP2, FFP_VS_FOG, internalCounter++); - break; + } + + curFuncInvocation->pushOperand(mPSInDepth, Operand::OPS_IN); + curFuncInvocation->pushOperand(mFogParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(mFogColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + } + + // Per vertex fog. + else + { + internalCounter = 0; + + switch (mFogMode) + { + case FOG_LINEAR: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_LINEAR, FFP_VS_FOG, internalCounter++); + break; + case FOG_EXP: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_EXP, FFP_VS_FOG, internalCounter++); + break; + case FOG_EXP2: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_VERTEXFOG_EXP2, FFP_VS_FOG, internalCounter++); + break; case FOG_NONE: default: break; - } - - curFuncInvocation->pushOperand(mWorldViewProjMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(mFogParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutFogFactor, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); + } + + curFuncInvocation->pushOperand(mWorldViewProjMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(mFogParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutFogFactor, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); - internalCounter = 0; + internalCounter = 0; - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, FFP_PS_FOG, internalCounter++); - curFuncInvocation->pushOperand(mFogColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInFogFactor, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, FFP_PS_FOG, internalCounter++); + curFuncInvocation->pushOperand(mFogColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInFogFactor, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } - return true; + return true; } //----------------------------------------------------------------------- void FFPFog::copyFrom(const SubRenderState& rhs) { - const FFPFog& rhsFog = static_cast(rhs); + const FFPFog& rhsFog = static_cast(rhs); - mFogMode = rhsFog.mFogMode; - mFogColourValue = rhsFog.mFogColourValue; - mFogParamsValue = rhsFog.mFogParamsValue; + mFogMode = rhsFog.mFogMode; + mFogColourValue = rhsFog.mFogColourValue; + mFogParamsValue = rhsFog.mFogParamsValue; - setCalcMode(rhsFog.mCalcMode); + setCalcMode(rhsFog.mCalcMode); } //----------------------------------------------------------------------- bool FFPFog::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) -{ - FogMode fogMode; - ColourValue newFogColour; - Real newFogStart, newFogEnd, newFogDensity; - - if (srcPass->getFogOverride()) - { - fogMode = srcPass->getFogMode(); - newFogColour = srcPass->getFogColour(); - newFogStart = srcPass->getFogStart(); - newFogEnd = srcPass->getFogEnd(); - newFogDensity = srcPass->getFogDensity(); - mPassOverrideParams = true; - } - else - { - SceneManager* sceneMgr = ShaderGenerator::getSingleton().getActiveSceneManager(); - - if (sceneMgr == NULL) - { - fogMode = FOG_NONE; - newFogColour = ColourValue::White; - newFogStart = 0.0; - newFogEnd = 0.0; - newFogDensity = 0.0; - } - else - { - fogMode = sceneMgr->getFogMode(); - newFogColour = sceneMgr->getFogColour(); - newFogStart = sceneMgr->getFogStart(); - newFogEnd = sceneMgr->getFogEnd(); - newFogDensity = sceneMgr->getFogDensity(); - } - mPassOverrideParams = false; - } - - // Set fog properties. - setFogProperties(fogMode, newFogColour, newFogStart, newFogEnd, newFogDensity); - - - // Override scene fog since it will happen in shader. - dstPass->setFog(true, FOG_NONE, newFogColour, newFogDensity, newFogStart, newFogEnd); - - return true; +{ + FogMode fogMode; + ColourValue newFogColour; + Real newFogStart, newFogEnd, newFogDensity; + + if (srcPass->getFogOverride()) + { + fogMode = srcPass->getFogMode(); + newFogColour = srcPass->getFogColour(); + newFogStart = srcPass->getFogStart(); + newFogEnd = srcPass->getFogEnd(); + newFogDensity = srcPass->getFogDensity(); + mPassOverrideParams = true; + } + else + { + SceneManager* sceneMgr = ShaderGenerator::getSingleton().getActiveSceneManager(); + + if (sceneMgr == NULL) + { + fogMode = FOG_NONE; + newFogColour = ColourValue::White; + newFogStart = 0.0; + newFogEnd = 0.0; + newFogDensity = 0.0; + } + else + { + fogMode = sceneMgr->getFogMode(); + newFogColour = sceneMgr->getFogColour(); + newFogStart = sceneMgr->getFogStart(); + newFogEnd = sceneMgr->getFogEnd(); + newFogDensity = sceneMgr->getFogDensity(); + } + mPassOverrideParams = false; + } + + // Set fog properties. + setFogProperties(fogMode, newFogColour, newFogStart, newFogEnd, newFogDensity); + + + // Override scene fog since it will happen in shader. + dstPass->setFog(true, FOG_NONE, newFogColour, newFogDensity, newFogStart, newFogEnd); + + return true; } //----------------------------------------------------------------------- void FFPFog::setFogProperties(FogMode fogMode, - const ColourValue& fogColour, - float fogStart, - float fogEnd, - float fogDensity) + const ColourValue& fogColour, + float fogStart, + float fogEnd, + float fogDensity) { - mFogMode = fogMode; - mFogColourValue = fogColour; - mFogParamsValue.x = fogDensity; - mFogParamsValue.y = fogStart; - mFogParamsValue.z = fogEnd; - mFogParamsValue.w = fogEnd != fogStart ? 1 / (fogEnd - fogStart) : 0; + mFogMode = fogMode; + mFogColourValue = fogColour; + mFogParamsValue.x = fogDensity; + mFogParamsValue.y = fogStart; + mFogParamsValue.z = fogEnd; + mFogParamsValue.w = fogEnd != fogStart ? 1 / (fogEnd - fogStart) : 0; } //----------------------------------------------------------------------- const String& FFPFogFactory::getType() const { - return FFPFog::Type; + return FFPFog::Type; } //----------------------------------------------------------------------- -SubRenderState* FFPFogFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* FFPFogFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "fog_stage") - { - if(prop->values.size() >= 1) - { - String strValue; - - if(false == SGScriptTranslator::getString(prop->values.front(), &strValue)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - return NULL; - } - - if (strValue == "ffp") - { - SubRenderState* subRenderState = createOrRetrieveInstance(translator); - FFPFog* fogSubRenderState = static_cast(subRenderState); - AbstractNodeList::const_iterator it = prop->values.begin(); - - if(prop->values.size() >= 2) - { - ++it; - if (false == SGScriptTranslator::getString(*it, &strValue)) - { - compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); - return NULL; - } - - if (strValue == "per_vertex") - { - fogSubRenderState->setCalcMode(FFPFog::CM_PER_VERTEX); - } - else if (strValue == "per_pixel") - { - fogSubRenderState->setCalcMode(FFPFog::CM_PER_PIXEL); - } - } - - return subRenderState; - } - } - } - - return NULL; + if (prop->name == "fog_stage") + { + if(prop->values.size() >= 1) + { + String strValue; + + if(false == SGScriptTranslator::getString(prop->values.front(), &strValue)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + return NULL; + } + + if (strValue == "ffp") + { + SubRenderState* subRenderState = createOrRetrieveInstance(translator); + FFPFog* fogSubRenderState = static_cast(subRenderState); + AbstractNodeList::const_iterator it = prop->values.begin(); + + if(prop->values.size() >= 2) + { + ++it; + if (false == SGScriptTranslator::getString(*it, &strValue)) + { + compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); + return NULL; + } + + if (strValue == "per_vertex") + { + fogSubRenderState->setCalcMode(FFPFog::CM_PER_VERTEX); + } + else if (strValue == "per_pixel") + { + fogSubRenderState->setCalcMode(FFPFog::CM_PER_PIXEL); + } + } + + return subRenderState; + } + } + } + + return NULL; } //----------------------------------------------------------------------- void FFPFogFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + Pass* srcPass, Pass* dstPass) { - ser->writeAttribute(4, "fog_stage"); - ser->writeValue("ffp"); + ser->writeAttribute(4, "fog_stage"); + ser->writeValue("ffp"); - FFPFog* fogSubRenderState = static_cast(subRenderState); + FFPFog* fogSubRenderState = static_cast(subRenderState); - if (fogSubRenderState->getCalcMode() == FFPFog::CM_PER_VERTEX) - { - ser->writeValue("per_vertex"); - } - else if (fogSubRenderState->getCalcMode() == FFPFog::CM_PER_PIXEL) - { - ser->writeValue("per_pixel"); - } + if (fogSubRenderState->getCalcMode() == FFPFog::CM_PER_VERTEX) + { + ser->writeValue("per_vertex"); + } + else if (fogSubRenderState->getCalcMode() == FFPFog::CM_PER_PIXEL) + { + ser->writeValue("per_pixel"); + } } //----------------------------------------------------------------------- -SubRenderState* FFPFogFactory::createInstanceImpl() +SubRenderState* FFPFogFactory::createInstanceImpl() { - return OGRE_NEW FFPFog; + return OGRE_NEW FFPFog; } } diff --git a/Components/RTShaderSystem/src/OgreShaderFFPLighting.cpp b/Components/RTShaderSystem/src/OgreShaderFFPLighting.cpp index 1fb33779cea..81548b15b0b 100644 --- a/Components/RTShaderSystem/src/OgreShaderFFPLighting.cpp +++ b/Components/RTShaderSystem/src/OgreShaderFFPLighting.cpp @@ -47,718 +47,718 @@ Light FFPLighting::msBlankLight; //----------------------------------------------------------------------- FFPLighting::FFPLighting() { - mTrackVertexColourType = TVC_NONE; - mSpecularEnable = false; + mTrackVertexColourType = TVC_NONE; + mSpecularEnable = false; - msBlankLight.setDiffuseColour(ColourValue::Black); - msBlankLight.setSpecularColour(ColourValue::Black); - msBlankLight.setAttenuation(0,1,0,0); + msBlankLight.setDiffuseColour(ColourValue::Black); + msBlankLight.setSpecularColour(ColourValue::Black); + msBlankLight.setAttenuation(0,1,0,0); } //----------------------------------------------------------------------- const String& FFPLighting::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int FFPLighting::getExecutionOrder() const +int FFPLighting::getExecutionOrder() const { - return FFP_LIGHTING; + return FFP_LIGHTING; } //----------------------------------------------------------------------- void FFPLighting::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, - const LightList* pLightList) -{ - if (mLightParamsList.empty()) - return; - - const Matrix4& matView = source->getViewMatrix(); - Light::LightTypes curLightType = Light::LT_DIRECTIONAL; - unsigned int curSearchLightIndex = 0; - - // Update per light parameters. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - const LightParams& curParams = mLightParamsList[i]; - - if (curLightType != curParams.mType) - { - curLightType = curParams.mType; - curSearchLightIndex = 0; - } - - Light* srcLight = NULL; - Vector4 vParameter; - ColourValue colour; - - // Search a matching light from the current sorted lights of the given renderable. - for (unsigned int j = curSearchLightIndex; j < pLightList->size(); ++j) - { - if (pLightList->at(j)->getType() == curLightType) - { - srcLight = pLightList->at(j); - curSearchLightIndex = j + 1; - break; - } - } - - // No matching light found -> use a blank dummy light for parameter update. - if (srcLight == NULL) - { - srcLight = &msBlankLight; - } - - - switch (curParams.mType) - { - case Light::LT_DIRECTIONAL: - - // Update light direction. - vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); - curParams.mDirection->setGpuParameter(vParameter); - break; - - case Light::LT_POINT: - - // Update light position. - vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); - curParams.mPosition->setGpuParameter(vParameter); - - // Update light attenuation parameters. - vParameter.x = srcLight->getAttenuationRange(); - vParameter.y = srcLight->getAttenuationConstant(); - vParameter.z = srcLight->getAttenuationLinear(); - vParameter.w = srcLight->getAttenuationQuadric(); - curParams.mAttenuatParams->setGpuParameter(vParameter); - break; - - case Light::LT_SPOTLIGHT: - { - Vector3 vec3; - Matrix3 matViewIT; - - source->getInverseTransposeViewMatrix().extract3x3Matrix(matViewIT); - - - // Update light position. - vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); - curParams.mPosition->setGpuParameter(vParameter); - - - vec3 = matViewIT * srcLight->getDerivedDirection(); - vec3.normalise(); - - vParameter.x = -vec3.x; - vParameter.y = -vec3.y; - vParameter.z = -vec3.z; - vParameter.w = 0.0; - curParams.mDirection->setGpuParameter(vParameter); - - // Update light attenuation parameters. - vParameter.x = srcLight->getAttenuationRange(); - vParameter.y = srcLight->getAttenuationConstant(); - vParameter.z = srcLight->getAttenuationLinear(); - vParameter.w = srcLight->getAttenuationQuadric(); - curParams.mAttenuatParams->setGpuParameter(vParameter); - - // Update spotlight parameters. - Real phi = Math::Cos(srcLight->getSpotlightOuterAngle().valueRadians() * 0.5f); - Real theta = Math::Cos(srcLight->getSpotlightInnerAngle().valueRadians() * 0.5f); - - vec3.x = theta; - vec3.y = phi; - vec3.z = srcLight->getSpotlightFalloff(); - - curParams.mSpotParams->setGpuParameter(vec3); - } - break; - } - - - // Update diffuse colour. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - colour = srcLight->getDiffuseColour() * pass->getDiffuse() * srcLight->getPowerScale(); - curParams.mDiffuseColour->setGpuParameter(colour); - } - else - { - colour = srcLight->getDiffuseColour() * srcLight->getPowerScale(); - curParams.mDiffuseColour->setGpuParameter(colour); - } - - // Update specular colour if need to. - if (mSpecularEnable) - { - // Update diffuse colour. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - colour = srcLight->getSpecularColour() * pass->getSpecular() * srcLight->getPowerScale(); - curParams.mSpecularColour->setGpuParameter(colour); - } - else - { - colour = srcLight->getSpecularColour() * srcLight->getPowerScale(); - curParams.mSpecularColour->setGpuParameter(colour); - } - } - } + const LightList* pLightList) +{ + if (mLightParamsList.empty()) + return; + + const Matrix4& matView = source->getViewMatrix(); + Light::LightTypes curLightType = Light::LT_DIRECTIONAL; + unsigned int curSearchLightIndex = 0; + + // Update per light parameters. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + const LightParams& curParams = mLightParamsList[i]; + + if (curLightType != curParams.mType) + { + curLightType = curParams.mType; + curSearchLightIndex = 0; + } + + Light* srcLight = NULL; + Vector4 vParameter; + ColourValue colour; + + // Search a matching light from the current sorted lights of the given renderable. + for (unsigned int j = curSearchLightIndex; j < pLightList->size(); ++j) + { + if (pLightList->at(j)->getType() == curLightType) + { + srcLight = pLightList->at(j); + curSearchLightIndex = j + 1; + break; + } + } + + // No matching light found -> use a blank dummy light for parameter update. + if (srcLight == NULL) + { + srcLight = &msBlankLight; + } + + + switch (curParams.mType) + { + case Light::LT_DIRECTIONAL: + + // Update light direction. + vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); + curParams.mDirection->setGpuParameter(vParameter); + break; + + case Light::LT_POINT: + + // Update light position. + vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); + curParams.mPosition->setGpuParameter(vParameter); + + // Update light attenuation parameters. + vParameter.x = srcLight->getAttenuationRange(); + vParameter.y = srcLight->getAttenuationConstant(); + vParameter.z = srcLight->getAttenuationLinear(); + vParameter.w = srcLight->getAttenuationQuadric(); + curParams.mAttenuatParams->setGpuParameter(vParameter); + break; + + case Light::LT_SPOTLIGHT: + { + Vector3 vec3; + Matrix3 matViewIT; + + source->getInverseTransposeViewMatrix().extract3x3Matrix(matViewIT); + + + // Update light position. + vParameter = matView.transformAffine(srcLight->getAs4DVector(true)); + curParams.mPosition->setGpuParameter(vParameter); + + + vec3 = matViewIT * srcLight->getDerivedDirection(); + vec3.normalise(); + + vParameter.x = -vec3.x; + vParameter.y = -vec3.y; + vParameter.z = -vec3.z; + vParameter.w = 0.0; + curParams.mDirection->setGpuParameter(vParameter); + + // Update light attenuation parameters. + vParameter.x = srcLight->getAttenuationRange(); + vParameter.y = srcLight->getAttenuationConstant(); + vParameter.z = srcLight->getAttenuationLinear(); + vParameter.w = srcLight->getAttenuationQuadric(); + curParams.mAttenuatParams->setGpuParameter(vParameter); + + // Update spotlight parameters. + Real phi = Math::Cos(srcLight->getSpotlightOuterAngle().valueRadians() * 0.5f); + Real theta = Math::Cos(srcLight->getSpotlightInnerAngle().valueRadians() * 0.5f); + + vec3.x = theta; + vec3.y = phi; + vec3.z = srcLight->getSpotlightFalloff(); + + curParams.mSpotParams->setGpuParameter(vec3); + } + break; + } + + + // Update diffuse colour. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + colour = srcLight->getDiffuseColour() * pass->getDiffuse() * srcLight->getPowerScale(); + curParams.mDiffuseColour->setGpuParameter(colour); + } + else + { + colour = srcLight->getDiffuseColour() * srcLight->getPowerScale(); + curParams.mDiffuseColour->setGpuParameter(colour); + } + + // Update specular colour if need to. + if (mSpecularEnable) + { + // Update diffuse colour. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + colour = srcLight->getSpecularColour() * pass->getSpecular() * srcLight->getPowerScale(); + curParams.mSpecularColour->setGpuParameter(colour); + } + else + { + colour = srcLight->getSpecularColour() * srcLight->getPowerScale(); + curParams.mSpecularColour->setGpuParameter(colour); + } + } + } } //----------------------------------------------------------------------- bool FFPLighting::resolveParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - bool hasError = false; - - // Resolve world view IT matrix. - mWorldViewITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, 0); - - // Get surface ambient colour if need to. - if ((mTrackVertexColourType & TVC_AMBIENT) == 0) - { - mDerivedAmbientLightColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR, 0); - hasError |= !(mDerivedAmbientLightColour.get()); - } - else - { - mLightAmbientColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, 0); - mSurfaceAmbientColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR, 0); - - hasError |= !(mLightAmbientColour.get()) || !(mSurfaceAmbientColour.get()); - } - - // Get surface diffuse colour if need to. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - mSurfaceDiffuseColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR, 0); - hasError |= !(mSurfaceDiffuseColour.get()); - } - - // Get surface specular colour if need to. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - mSurfaceSpecularColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR, 0); - hasError |= !(mSurfaceSpecularColour.get()); - } - - - // Get surface emissive colour if need to. - if ((mTrackVertexColourType & TVC_EMISSIVE) == 0) - { - mSurfaceEmissiveColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR, 0); - hasError |= !(mSurfaceEmissiveColour.get()); - } - - // Get derived scene colour. - mDerivedSceneColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, 0); - - // Get surface shininess. - mSurfaceShininess = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SHININESS, 0); - - // Resolve input vertex shader normal. - mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - - if (mTrackVertexColourType != 0) - { - mVSDiffuse = vsMain->resolveInputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - hasError |= !(mVSDiffuse.get()); - } - - - // Resolve output vertex shader diffuse colour. - mVSOutDiffuse = vsMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - - // Resolve per light parameters. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - switch (mLightParamsList[i].mType) - { - case Light::LT_DIRECTIONAL: - mLightParamsList[i].mDirection = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_position_view_space"); - hasError |= !(mLightParamsList[i].mDirection.get()); - break; - - case Light::LT_POINT: - mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); - - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - - mLightParamsList[i].mPosition = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_position_view_space"); - - mLightParamsList[i].mAttenuatParams = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); - - hasError |= !(mWorldViewMatrix.get()) || !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || !(mLightParamsList[i].mAttenuatParams.get()); - break; - - case Light::LT_SPOTLIGHT: - mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); - - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - - mLightParamsList[i].mPosition = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_position_view_space"); - - mLightParamsList[i].mDirection = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_direction_view_space"); - - mLightParamsList[i].mAttenuatParams = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); - - mLightParamsList[i].mSpotParams = vsProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "spotlight_params"); - - hasError |= !(mWorldViewMatrix.get()) || !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || - !(mLightParamsList[i].mDirection.get()) || !(mLightParamsList[i].mAttenuatParams.get()) || !(mLightParamsList[i].mSpotParams.get()); - break; - } - - // Resolve diffuse colour. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - mLightParamsList[i].mDiffuseColour = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL | (uint16)GPV_LIGHTS, "derived_light_diffuse"); - hasError |= !(mLightParamsList[i].mDiffuseColour.get()); - } - else - { - mLightParamsList[i].mDiffuseColour = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_diffuse"); - hasError |= !(mLightParamsList[i].mDiffuseColour.get()); - } - - if (mSpecularEnable) - { - // Resolve specular colour. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - mLightParamsList[i].mSpecularColour = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL | (uint16)GPV_LIGHTS, "derived_light_specular"); - hasError |= !(mLightParamsList[i].mSpecularColour.get()); - } - else - { - mLightParamsList[i].mSpecularColour = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_specular"); - hasError |= !(mLightParamsList[i].mSpecularColour.get()); - } - - if (mVSOutSpecular.get() == NULL) - { - mVSOutSpecular = vsMain->resolveOutputParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - hasError |= !(mVSOutSpecular.get()); - } - - if (mVSInPosition.get() == NULL) - { - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - hasError |= !(mVSInPosition.get()); - } - - if (mWorldViewMatrix.get() == NULL) - { - mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); - hasError |= !(mWorldViewMatrix.get()); - } - } - } - - hasError |= !(mWorldViewITMatrix.get()) || !(mDerivedSceneColour.get()) || !(mSurfaceShininess.get()) || - !(mVSInNormal.get()) || !(mVSOutDiffuse.get()); - - - if (hasError) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "PerPixelLighting::resolveGlobalParameters" ); - } - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + bool hasError = false; + + // Resolve world view IT matrix. + mWorldViewITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, 0); + + // Get surface ambient colour if need to. + if ((mTrackVertexColourType & TVC_AMBIENT) == 0) + { + mDerivedAmbientLightColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR, 0); + hasError |= !(mDerivedAmbientLightColour.get()); + } + else + { + mLightAmbientColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, 0); + mSurfaceAmbientColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR, 0); + + hasError |= !(mLightAmbientColour.get()) || !(mSurfaceAmbientColour.get()); + } + + // Get surface diffuse colour if need to. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + mSurfaceDiffuseColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR, 0); + hasError |= !(mSurfaceDiffuseColour.get()); + } + + // Get surface specular colour if need to. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + mSurfaceSpecularColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR, 0); + hasError |= !(mSurfaceSpecularColour.get()); + } + + + // Get surface emissive colour if need to. + if ((mTrackVertexColourType & TVC_EMISSIVE) == 0) + { + mSurfaceEmissiveColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR, 0); + hasError |= !(mSurfaceEmissiveColour.get()); + } + + // Get derived scene colour. + mDerivedSceneColour = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, 0); + + // Get surface shininess. + mSurfaceShininess = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SHININESS, 0); + + // Resolve input vertex shader normal. + mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + + if (mTrackVertexColourType != 0) + { + mVSDiffuse = vsMain->resolveInputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + hasError |= !(mVSDiffuse.get()); + } + + + // Resolve output vertex shader diffuse colour. + mVSOutDiffuse = vsMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + + // Resolve per light parameters. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + switch (mLightParamsList[i].mType) + { + case Light::LT_DIRECTIONAL: + mLightParamsList[i].mDirection = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_position_view_space"); + hasError |= !(mLightParamsList[i].mDirection.get()); + break; + + case Light::LT_POINT: + mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); + + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + + mLightParamsList[i].mPosition = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_position_view_space"); + + mLightParamsList[i].mAttenuatParams = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); + + hasError |= !(mWorldViewMatrix.get()) || !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || !(mLightParamsList[i].mAttenuatParams.get()); + break; + + case Light::LT_SPOTLIGHT: + mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); + + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + + mLightParamsList[i].mPosition = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_position_view_space"); + + mLightParamsList[i].mDirection = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_direction_view_space"); + + mLightParamsList[i].mAttenuatParams = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_attenuation"); + + mLightParamsList[i].mSpotParams = vsProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "spotlight_params"); + + hasError |= !(mWorldViewMatrix.get()) || !(mVSInPosition.get()) || !(mLightParamsList[i].mPosition.get()) || + !(mLightParamsList[i].mDirection.get()) || !(mLightParamsList[i].mAttenuatParams.get()) || !(mLightParamsList[i].mSpotParams.get()); + break; + } + + // Resolve diffuse colour. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + mLightParamsList[i].mDiffuseColour = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL | (uint16)GPV_LIGHTS, "derived_light_diffuse"); + hasError |= !(mLightParamsList[i].mDiffuseColour.get()); + } + else + { + mLightParamsList[i].mDiffuseColour = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_diffuse"); + hasError |= !(mLightParamsList[i].mDiffuseColour.get()); + } + + if (mSpecularEnable) + { + // Resolve specular colour. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + mLightParamsList[i].mSpecularColour = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL | (uint16)GPV_LIGHTS, "derived_light_specular"); + hasError |= !(mLightParamsList[i].mSpecularColour.get()); + } + else + { + mLightParamsList[i].mSpecularColour = vsProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_LIGHTS, "light_specular"); + hasError |= !(mLightParamsList[i].mSpecularColour.get()); + } + + if (mVSOutSpecular.get() == NULL) + { + mVSOutSpecular = vsMain->resolveOutputParameter(Parameter::SPS_COLOR, 1, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + hasError |= !(mVSOutSpecular.get()); + } + + if (mVSInPosition.get() == NULL) + { + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + hasError |= !(mVSInPosition.get()); + } + + if (mWorldViewMatrix.get() == NULL) + { + mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); + hasError |= !(mWorldViewMatrix.get()); + } + } + } + + hasError |= !(mWorldViewITMatrix.get()) || !(mDerivedSceneColour.get()) || !(mSurfaceShininess.get()) || + !(mVSInNormal.get()) || !(mVSOutDiffuse.get()); + + + if (hasError) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "PerPixelLighting::resolveGlobalParameters" ); + } + + return true; } //----------------------------------------------------------------------- bool FFPLighting::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); + Program* vsProgram = programSet->getCpuVertexProgram(); - vsProgram->addDependency(FFP_LIB_COMMON); - vsProgram->addDependency(FFP_LIB_LIGHTING); + vsProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(FFP_LIB_LIGHTING); - return true; + return true; } //----------------------------------------------------------------------- bool FFPLighting::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - - int internalCounter = 0; - - // Add the global illumination functions. - if (false == addGlobalIlluminationInvocation(vsMain, FFP_VS_LIGHTING, internalCounter)) - return false; - - - // Add per light functions. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - if (false == addIlluminationInvocation(&mLightParamsList[i], vsMain, FFP_VS_LIGHTING, internalCounter)) - return false; - } - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + + int internalCounter = 0; + + // Add the global illumination functions. + if (false == addGlobalIlluminationInvocation(vsMain, FFP_VS_LIGHTING, internalCounter)) + return false; + + + // Add per light functions. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + if (false == addIlluminationInvocation(&mLightParamsList[i], vsMain, FFP_VS_LIGHTING, internalCounter)) + return false; + } + + return true; } //----------------------------------------------------------------------- bool FFPLighting::addGlobalIlluminationInvocation(Function* vsMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && - (mTrackVertexColourType & TVC_EMISSIVE) == 0) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - if (mTrackVertexColourType & TVC_AMBIENT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mDerivedAmbientLightColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); - vsMain->addAtomInstance(curFuncInvocation); - } - - if (mTrackVertexColourType & TVC_EMISSIVE) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mSurfaceEmissiveColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - } - - return true; + FunctionInvocation* curFuncInvocation = NULL; + + if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && + (mTrackVertexColourType & TVC_EMISSIVE) == 0) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + if (mTrackVertexColourType & TVC_AMBIENT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mDerivedAmbientLightColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); + vsMain->addAtomInstance(curFuncInvocation); + } + + if (mTrackVertexColourType & TVC_EMISSIVE) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mSurfaceEmissiveColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + } + + return true; } //----------------------------------------------------------------------- bool FFPLighting::addIlluminationInvocation(LightParams* curLightParams, Function* vsMain, const int groupOrder, int& internalCounter) -{ - FunctionInvocation* curFuncInvocation = NULL; - - // Merge diffuse colour with vertex colour if need to. - if (mTrackVertexColourType & TVC_DIFFUSE) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - vsMain->addAtomInstance(curFuncInvocation); - } - - // Merge specular colour with vertex colour if need to. - if (mSpecularEnable && mTrackVertexColourType & TVC_SPECULAR) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - vsMain->addAtomInstance(curFuncInvocation); - } - - switch (curLightParams->mType) - { - - case Light::LT_DIRECTIONAL: - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_OUT, Operand::OPM_XYZ); - vsMain->addAtomInstance(curFuncInvocation); - } - - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_DIRECTIONAL_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); - vsMain->addAtomInstance(curFuncInvocation); - } - break; - - case Light::LT_POINT: - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_POINT_DIFFUSESPECULAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_OUT, Operand::OPM_XYZ); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_POINT_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); - vsMain->addAtomInstance(curFuncInvocation); - } - - break; - - case Light::LT_SPOTLIGHT: - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_SPOT_DIFFUSESPECULAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_OUT, Operand::OPM_XYZ); - vsMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_SPOT_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); - vsMain->addAtomInstance(curFuncInvocation); - } - break; - } - - return true; +{ + FunctionInvocation* curFuncInvocation = NULL; + + // Merge diffuse colour with vertex colour if need to. + if (mTrackVertexColourType & TVC_DIFFUSE) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + vsMain->addAtomInstance(curFuncInvocation); + } + + // Merge specular colour with vertex colour if need to. + if (mSpecularEnable && mTrackVertexColourType & TVC_SPECULAR) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mVSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + vsMain->addAtomInstance(curFuncInvocation); + } + + switch (curLightParams->mType) + { + + case Light::LT_DIRECTIONAL: + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_OUT, Operand::OPM_XYZ); + vsMain->addAtomInstance(curFuncInvocation); + } + + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_DIRECTIONAL_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); + vsMain->addAtomInstance(curFuncInvocation); + } + break; + + case Light::LT_POINT: + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_POINT_DIFFUSESPECULAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_OUT, Operand::OPM_XYZ); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_POINT_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); + vsMain->addAtomInstance(curFuncInvocation); + } + + break; + + case Light::LT_SPOTLIGHT: + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_SPOT_DIFFUSESPECULAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutSpecular, Operand::OPS_OUT, Operand::OPM_XYZ); + vsMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LIGHT_SPOT_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mWorldViewITMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(curLightParams->mAttenuatParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mVSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); + vsMain->addAtomInstance(curFuncInvocation); + } + break; + } + + return true; } //----------------------------------------------------------------------- void FFPLighting::copyFrom(const SubRenderState& rhs) { - const FFPLighting& rhsLighting = static_cast(rhs); + const FFPLighting& rhsLighting = static_cast(rhs); - int lightCount[3]; + int lightCount[3]; - rhsLighting.getLightCount(lightCount); - setLightCount(lightCount); + rhsLighting.getLightCount(lightCount); + setLightCount(lightCount); } //----------------------------------------------------------------------- bool FFPLighting::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { - if (srcPass->getLightingEnabled() == false) - return false; - - int lightCount[3]; - - renderState->getLightCount(lightCount); - - setTrackVertexColourType(srcPass->getVertexColourTracking()); - - if (srcPass->getShininess() > 0.0 && - srcPass->getSpecular() != ColourValue::Black) - { - setSpecularEnable(true); - } - else - { - setSpecularEnable(false); - } - - // Case this pass should run once per light(s) -> override the light policy. - if (srcPass->getIteratePerLight()) - { - - // This is the preferred case -> only one type of light is handled. - if (srcPass->getRunOnlyForOneLightType()) - { - if (srcPass->getOnlyLightType() == Light::LT_POINT) - { - lightCount[0] = srcPass->getLightCountPerIteration(); - lightCount[1] = 0; - lightCount[2] = 0; - } - else if (srcPass->getOnlyLightType() == Light::LT_DIRECTIONAL) - { - lightCount[0] = 0; - lightCount[1] = srcPass->getLightCountPerIteration(); - lightCount[2] = 0; - } - else if (srcPass->getOnlyLightType() == Light::LT_SPOTLIGHT) - { - lightCount[0] = 0; - lightCount[1] = 0; - lightCount[2] = srcPass->getLightCountPerIteration(); - } - } - - // This is worse case -> all light types expected to be handled. - // Can not handle this request in efficient way - throw an exception. - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Using iterative lighting method with RT Shader System requires specifying explicit light type.", - "FFPLighting::preAddToRenderState"); - } - } - - setLightCount(lightCount); - - return true; + if (srcPass->getLightingEnabled() == false) + return false; + + int lightCount[3]; + + renderState->getLightCount(lightCount); + + setTrackVertexColourType(srcPass->getVertexColourTracking()); + + if (srcPass->getShininess() > 0.0 && + srcPass->getSpecular() != ColourValue::Black) + { + setSpecularEnable(true); + } + else + { + setSpecularEnable(false); + } + + // Case this pass should run once per light(s) -> override the light policy. + if (srcPass->getIteratePerLight()) + { + + // This is the preferred case -> only one type of light is handled. + if (srcPass->getRunOnlyForOneLightType()) + { + if (srcPass->getOnlyLightType() == Light::LT_POINT) + { + lightCount[0] = srcPass->getLightCountPerIteration(); + lightCount[1] = 0; + lightCount[2] = 0; + } + else if (srcPass->getOnlyLightType() == Light::LT_DIRECTIONAL) + { + lightCount[0] = 0; + lightCount[1] = srcPass->getLightCountPerIteration(); + lightCount[2] = 0; + } + else if (srcPass->getOnlyLightType() == Light::LT_SPOTLIGHT) + { + lightCount[0] = 0; + lightCount[1] = 0; + lightCount[2] = srcPass->getLightCountPerIteration(); + } + } + + // This is worse case -> all light types expected to be handled. + // Can not handle this request in efficient way - throw an exception. + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Using iterative lighting method with RT Shader System requires specifying explicit light type.", + "FFPLighting::preAddToRenderState"); + } + } + + setLightCount(lightCount); + + return true; } //----------------------------------------------------------------------- void FFPLighting::setLightCount(const int lightCount[3]) { - for (int type=0; type < 3; ++type) - { - for (int i=0; i < lightCount[type]; ++i) - { - LightParams curParams; - - if (type == 0) - curParams.mType = Light::LT_POINT; - else if (type == 1) - curParams.mType = Light::LT_DIRECTIONAL; - else if (type == 2) - curParams.mType = Light::LT_SPOTLIGHT; - - mLightParamsList.push_back(curParams); - } - } + for (int type=0; type < 3; ++type) + { + for (int i=0; i < lightCount[type]; ++i) + { + LightParams curParams; + + if (type == 0) + curParams.mType = Light::LT_POINT; + else if (type == 1) + curParams.mType = Light::LT_DIRECTIONAL; + else if (type == 2) + curParams.mType = Light::LT_SPOTLIGHT; + + mLightParamsList.push_back(curParams); + } + } } //----------------------------------------------------------------------- void FFPLighting::getLightCount(int lightCount[3]) const { - lightCount[0] = 0; - lightCount[1] = 0; - lightCount[2] = 0; - - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - const LightParams curParams = mLightParamsList[i]; - - if (curParams.mType == Light::LT_POINT) - lightCount[0]++; - else if (curParams.mType == Light::LT_DIRECTIONAL) - lightCount[1]++; - else if (curParams.mType == Light::LT_SPOTLIGHT) - lightCount[2]++; - } + lightCount[0] = 0; + lightCount[1] = 0; + lightCount[2] = 0; + + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + const LightParams curParams = mLightParamsList[i]; + + if (curParams.mType == Light::LT_POINT) + lightCount[0]++; + else if (curParams.mType == Light::LT_DIRECTIONAL) + lightCount[1]++; + else if (curParams.mType == Light::LT_SPOTLIGHT) + lightCount[2]++; + } } //----------------------------------------------------------------------- const String& FFPLightingFactory::getType() const { - return FFPLighting::Type; + return FFPLighting::Type; } //----------------------------------------------------------------------- -SubRenderState* FFPLightingFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* FFPLightingFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "lighting_stage") - { - if(prop->values.size() == 1) - { - String modelType; - - if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - return NULL; - } - - if (modelType == "ffp") - { - return createOrRetrieveInstance(translator); - } - } - } - - return NULL; + if (prop->name == "lighting_stage") + { + if(prop->values.size() == 1) + { + String modelType; + + if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + return NULL; + } + + if (modelType == "ffp") + { + return createOrRetrieveInstance(translator); + } + } + } + + return NULL; } //----------------------------------------------------------------------- void FFPLightingFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + Pass* srcPass, Pass* dstPass) { - ser->writeAttribute(4, "lighting_stage"); - ser->writeValue("ffp"); + ser->writeAttribute(4, "lighting_stage"); + ser->writeValue("ffp"); } //----------------------------------------------------------------------- -SubRenderState* FFPLightingFactory::createInstanceImpl() +SubRenderState* FFPLightingFactory::createInstanceImpl() { - return OGRE_NEW FFPLighting; + return OGRE_NEW FFPLighting; } } diff --git a/Components/RTShaderSystem/src/OgreShaderFFPRenderStateBuilder.cpp b/Components/RTShaderSystem/src/OgreShaderFFPRenderStateBuilder.cpp index c1ac0844d31..248f57eaeec 100644 --- a/Components/RTShaderSystem/src/OgreShaderFFPRenderStateBuilder.cpp +++ b/Components/RTShaderSystem/src/OgreShaderFFPRenderStateBuilder.cpp @@ -49,159 +49,159 @@ namespace RTShader { //----------------------------------------------------------------------- FFPRenderStateBuilder* FFPRenderStateBuilder::getSingletonPtr() { - return msSingleton; + return msSingleton; } //----------------------------------------------------------------------- FFPRenderStateBuilder& FFPRenderStateBuilder::getSingleton() { - assert( msSingleton ); - return ( *msSingleton ); + assert( msSingleton ); + return ( *msSingleton ); } //----------------------------------------------------------------------------- FFPRenderStateBuilder::FFPRenderStateBuilder() { - + } //----------------------------------------------------------------------------- FFPRenderStateBuilder::~FFPRenderStateBuilder() { - + } //----------------------------------------------------------------------------- bool FFPRenderStateBuilder::initialize() { - SubRenderStateFactory* curFactory; + SubRenderStateFactory* curFactory; - curFactory = OGRE_NEW FFPTransformFactory; - ShaderGenerator::getSingleton().addSubRenderStateFactory(curFactory); - mFFPSubRenderStateFactoryList.push_back(curFactory); + curFactory = OGRE_NEW FFPTransformFactory; + ShaderGenerator::getSingleton().addSubRenderStateFactory(curFactory); + mFFPSubRenderStateFactoryList.push_back(curFactory); - curFactory = OGRE_NEW FFPColourFactory; - ShaderGenerator::getSingleton().addSubRenderStateFactory(curFactory); - mFFPSubRenderStateFactoryList.push_back(curFactory); + curFactory = OGRE_NEW FFPColourFactory; + ShaderGenerator::getSingleton().addSubRenderStateFactory(curFactory); + mFFPSubRenderStateFactoryList.push_back(curFactory); - curFactory = OGRE_NEW FFPLightingFactory; - ShaderGenerator::getSingleton().addSubRenderStateFactory(curFactory); - mFFPSubRenderStateFactoryList.push_back(curFactory); + curFactory = OGRE_NEW FFPLightingFactory; + ShaderGenerator::getSingleton().addSubRenderStateFactory(curFactory); + mFFPSubRenderStateFactoryList.push_back(curFactory); - curFactory = OGRE_NEW FFPTexturingFactory; - ShaderGenerator::getSingleton().addSubRenderStateFactory(curFactory); - mFFPSubRenderStateFactoryList.push_back(curFactory); + curFactory = OGRE_NEW FFPTexturingFactory; + ShaderGenerator::getSingleton().addSubRenderStateFactory(curFactory); + mFFPSubRenderStateFactoryList.push_back(curFactory); - curFactory = OGRE_NEW FFPFogFactory; - ShaderGenerator::getSingleton().addSubRenderStateFactory(curFactory); - mFFPSubRenderStateFactoryList.push_back(curFactory); + curFactory = OGRE_NEW FFPFogFactory; + ShaderGenerator::getSingleton().addSubRenderStateFactory(curFactory); + mFFPSubRenderStateFactoryList.push_back(curFactory); - return true; + return true; } //----------------------------------------------------------------------------- void FFPRenderStateBuilder::destroy() { - SubRenderStateFactoryIterator it; - - for (it = mFFPSubRenderStateFactoryList.begin(); it != mFFPSubRenderStateFactoryList.end(); ++it) - { - ShaderGenerator::getSingleton().removeSubRenderStateFactory(*it); - OGRE_DELETE *it; - } - mFFPSubRenderStateFactoryList.clear(); + SubRenderStateFactoryIterator it; + + for (it = mFFPSubRenderStateFactoryList.begin(); it != mFFPSubRenderStateFactoryList.end(); ++it) + { + ShaderGenerator::getSingleton().removeSubRenderStateFactory(*it); + OGRE_DELETE *it; + } + mFFPSubRenderStateFactoryList.clear(); } //----------------------------------------------------------------------------- void FFPRenderStateBuilder::buildRenderState(ShaderGenerator::SGPass* sgPass, TargetRenderState* renderState) { - renderState->reset(); + renderState->reset(); - // Build transformation sub state. - buildFFPSubRenderState(FFP_TRANSFORM, FFPTransform::Type, sgPass, renderState); + // Build transformation sub state. + buildFFPSubRenderState(FFP_TRANSFORM, FFPTransform::Type, sgPass, renderState); - // Build colour sub state. - buildFFPSubRenderState(FFP_COLOUR, FFPColour::Type, sgPass, renderState); + // Build colour sub state. + buildFFPSubRenderState(FFP_COLOUR, FFPColour::Type, sgPass, renderState); - // Build lighting sub state. - buildFFPSubRenderState(FFP_LIGHTING, FFPLighting::Type, sgPass, renderState); + // Build lighting sub state. + buildFFPSubRenderState(FFP_LIGHTING, FFPLighting::Type, sgPass, renderState); - // Build texturing sub state. - buildFFPSubRenderState(FFP_TEXTURING, FFPTexturing::Type, sgPass, renderState); - - // Build fog sub state. - buildFFPSubRenderState(FFP_FOG, FFPFog::Type, sgPass, renderState); - - // Resolve colour stage flags. - resolveColourStageFlags(sgPass, renderState); + // Build texturing sub state. + buildFFPSubRenderState(FFP_TEXTURING, FFPTexturing::Type, sgPass, renderState); + + // Build fog sub state. + buildFFPSubRenderState(FFP_FOG, FFPFog::Type, sgPass, renderState); + + // Resolve colour stage flags. + resolveColourStageFlags(sgPass, renderState); } //----------------------------------------------------------------------------- void FFPRenderStateBuilder::buildFFPSubRenderState(int subRenderStateOrder, const String& subRenderStateType, - ShaderGenerator::SGPass* sgPass, TargetRenderState* renderState) + ShaderGenerator::SGPass* sgPass, TargetRenderState* renderState) { - SubRenderState* subRenderState; - - subRenderState = sgPass->getCustomFFPSubState(subRenderStateOrder); - - if (subRenderState == NULL) - { - subRenderState = ShaderGenerator::getSingleton().createSubRenderState(subRenderStateType); - } - - if (subRenderState->preAddToRenderState(renderState, sgPass->getSrcPass(), sgPass->getDstPass())) - { - renderState->addSubRenderStateInstance(subRenderState); - } - else - { - ShaderGenerator::getSingleton().destroySubRenderState(subRenderState); - } + SubRenderState* subRenderState; + + subRenderState = sgPass->getCustomFFPSubState(subRenderStateOrder); + + if (subRenderState == NULL) + { + subRenderState = ShaderGenerator::getSingleton().createSubRenderState(subRenderStateType); + } + + if (subRenderState->preAddToRenderState(renderState, sgPass->getSrcPass(), sgPass->getDstPass())) + { + renderState->addSubRenderStateInstance(subRenderState); + } + else + { + ShaderGenerator::getSingleton().destroySubRenderState(subRenderState); + } } //----------------------------------------------------------------------------- void FFPRenderStateBuilder::resolveColourStageFlags( ShaderGenerator::SGPass* sgPass, TargetRenderState* renderState ) { - const SubRenderStateList& subRenderStateList = renderState->getTemplateSubRenderStateList(); - FFPColour* colourSubState = NULL; - - // Find the colour sub state. - for (SubRenderStateListConstIterator it=subRenderStateList.begin(); it != subRenderStateList.end(); ++it) - { - SubRenderState* curSubRenderState = *it; - - if (curSubRenderState->getType() == FFPColour::Type) - { - colourSubState = static_cast(curSubRenderState); - break; - } - } - - for (SubRenderStateListConstIterator it=subRenderStateList.begin(); it != subRenderStateList.end(); ++it) - { - SubRenderState* curSubRenderState = *it; - - // Add vertex shader specular lighting output in case of specular enabled. - if (curSubRenderState->getType() == FFPLighting::Type && colourSubState != NULL) - { - colourSubState->addResolveStageMask(FFPColour::SF_VS_OUTPUT_DIFFUSE); - - Pass* srcPass = sgPass->getSrcPass(); - - if (srcPass->getShininess() > 0.0 && - srcPass->getSpecular() != ColourValue::Black) - { - colourSubState->addResolveStageMask(FFPColour::SF_VS_OUTPUT_SPECULAR); - } - break; - } - } + const SubRenderStateList& subRenderStateList = renderState->getTemplateSubRenderStateList(); + FFPColour* colourSubState = NULL; + + // Find the colour sub state. + for (SubRenderStateListConstIterator it=subRenderStateList.begin(); it != subRenderStateList.end(); ++it) + { + SubRenderState* curSubRenderState = *it; + + if (curSubRenderState->getType() == FFPColour::Type) + { + colourSubState = static_cast(curSubRenderState); + break; + } + } + + for (SubRenderStateListConstIterator it=subRenderStateList.begin(); it != subRenderStateList.end(); ++it) + { + SubRenderState* curSubRenderState = *it; + + // Add vertex shader specular lighting output in case of specular enabled. + if (curSubRenderState->getType() == FFPLighting::Type && colourSubState != NULL) + { + colourSubState->addResolveStageMask(FFPColour::SF_VS_OUTPUT_DIFFUSE); + + Pass* srcPass = sgPass->getSrcPass(); + + if (srcPass->getShininess() > 0.0 && + srcPass->getSpecular() != ColourValue::Black) + { + colourSubState->addResolveStageMask(FFPColour::SF_VS_OUTPUT_SPECULAR); + } + break; + } + } } diff --git a/Components/RTShaderSystem/src/OgreShaderFFPTexturing.cpp b/Components/RTShaderSystem/src/OgreShaderFFPTexturing.cpp index 2bf47cb0805..fa8cacf8785 100644 --- a/Components/RTShaderSystem/src/OgreShaderFFPTexturing.cpp +++ b/Components/RTShaderSystem/src/OgreShaderFFPTexturing.cpp @@ -49,120 +49,120 @@ const String c_ParamTexelEx("texel_"); //----------------------------------------------------------------------- FFPTexturing::FFPTexturing() -{ +{ } //----------------------------------------------------------------------- const String& FFPTexturing::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int FFPTexturing::getExecutionOrder() const -{ - return FFP_TEXTURING; +int FFPTexturing::getExecutionOrder() const +{ + return FFP_TEXTURING; } //----------------------------------------------------------------------- bool FFPTexturing::resolveParameters(ProgramSet* programSet) { - for (unsigned int i=0; i < mTextureUnitParamsList.size(); ++i) - { - TextureUnitParams* curParams = &mTextureUnitParamsList[i]; + for (unsigned int i=0; i < mTextureUnitParamsList.size(); ++i) + { + TextureUnitParams* curParams = &mTextureUnitParamsList[i]; - if (false == resolveUniformParams(curParams, programSet)) - return false; + if (false == resolveUniformParams(curParams, programSet)) + return false; - if (false == resolveFunctionsParams(curParams, programSet)) - return false; - } - + if (false == resolveFunctionsParams(curParams, programSet)) + return false; + } + - return true; + return true; } //----------------------------------------------------------------------- bool FFPTexturing::resolveUniformParams(TextureUnitParams* textureUnitParams, ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - bool hasError = false; - - // Resolve texture sampler parameter. - textureUnitParams->mTextureSampler = psProgram->resolveParameter(textureUnitParams->mTextureSamplerType, textureUnitParams->mTextureSamplerIndex, (uint16)GPV_GLOBAL, "gTextureSampler"); - - if (Ogre::RTShader::ShaderGenerator::getSingletonPtr()->IsHlsl4()) - { - //Resolve texture sampler state parameter for hlsl 4.0 - textureUnitParams->mTextureSamplerState = psProgram->resolveParameter(GCT_SAMPLER_STATE, textureUnitParams->mTextureSamplerIndex, (uint16)GPV_GLOBAL, "gTextureSamplerState"); - hasError |= !(textureUnitParams->mTextureSamplerState.get()); - } - - // Resolve texture matrix parameter. - if (needsTextureMatrix(textureUnitParams->mTextureUnitState)) - { - textureUnitParams->mTextureMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_TEXTURE_MATRIX, textureUnitParams->mTextureSamplerIndex); - hasError |= !(textureUnitParams->mTextureMatrix.get()); - } - - switch (textureUnitParams->mTexCoordCalcMethod) - { - case TEXCALC_NONE: - break; - - // Resolve World + View matrices. - case TEXCALC_ENVIRONMENT_MAP: - case TEXCALC_ENVIRONMENT_MAP_PLANAR: - case TEXCALC_ENVIRONMENT_MAP_NORMAL: - //TODO: change the following 'mWorldITMatrix' member to 'mWorldViewITMatrix' - mWorldITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, 0); - mViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEW_MATRIX, 0); - mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - - hasError |= !(mWorldITMatrix.get()) || !(mViewMatrix.get()) || !(mWorldMatrix.get()); - break; - - case TEXCALC_ENVIRONMENT_MAP_REFLECTION: - mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - mWorldITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, 0); - mViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEW_MATRIX, 0); - - hasError |= !(mWorldMatrix.get()) || !(mWorldITMatrix.get()) || !(mViewMatrix.get()); - break; - - case TEXCALC_PROJECTIVE_TEXTURE: - - mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - textureUnitParams->mTextureViewProjImageMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_LIGHTS, "gTexViewProjImageMatrix"); - - hasError |= !(mWorldMatrix.get()) || !(textureUnitParams->mTextureViewProjImageMatrix.get()); - - const TextureUnitState::EffectMap& effectMap = textureUnitParams->mTextureUnitState->getEffects(); - TextureUnitState::EffectMap::const_iterator effi; - - for (effi = effectMap.begin(); effi != effectMap.end(); ++effi) - { - if (effi->second.type == TextureUnitState::ET_PROJECTIVE_TEXTURE) - { - textureUnitParams->mTextureProjector = effi->second.frustum; - break; - } - } - - hasError |= !(textureUnitParams->mTextureProjector); - break; - } - - - if (hasError) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "FFPTexturing::resolveUniformParams" ); - } - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + bool hasError = false; + + // Resolve texture sampler parameter. + textureUnitParams->mTextureSampler = psProgram->resolveParameter(textureUnitParams->mTextureSamplerType, textureUnitParams->mTextureSamplerIndex, (uint16)GPV_GLOBAL, "gTextureSampler"); + + if (Ogre::RTShader::ShaderGenerator::getSingletonPtr()->IsHlsl4()) + { + //Resolve texture sampler state parameter for hlsl 4.0 + textureUnitParams->mTextureSamplerState = psProgram->resolveParameter(GCT_SAMPLER_STATE, textureUnitParams->mTextureSamplerIndex, (uint16)GPV_GLOBAL, "gTextureSamplerState"); + hasError |= !(textureUnitParams->mTextureSamplerState.get()); + } + + // Resolve texture matrix parameter. + if (needsTextureMatrix(textureUnitParams->mTextureUnitState)) + { + textureUnitParams->mTextureMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_TEXTURE_MATRIX, textureUnitParams->mTextureSamplerIndex); + hasError |= !(textureUnitParams->mTextureMatrix.get()); + } + + switch (textureUnitParams->mTexCoordCalcMethod) + { + case TEXCALC_NONE: + break; + + // Resolve World + View matrices. + case TEXCALC_ENVIRONMENT_MAP: + case TEXCALC_ENVIRONMENT_MAP_PLANAR: + case TEXCALC_ENVIRONMENT_MAP_NORMAL: + //TODO: change the following 'mWorldITMatrix' member to 'mWorldViewITMatrix' + mWorldITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, 0); + mViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEW_MATRIX, 0); + mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + + hasError |= !(mWorldITMatrix.get()) || !(mViewMatrix.get()) || !(mWorldMatrix.get()); + break; + + case TEXCALC_ENVIRONMENT_MAP_REFLECTION: + mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + mWorldITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, 0); + mViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEW_MATRIX, 0); + + hasError |= !(mWorldMatrix.get()) || !(mWorldITMatrix.get()) || !(mViewMatrix.get()); + break; + + case TEXCALC_PROJECTIVE_TEXTURE: + + mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + textureUnitParams->mTextureViewProjImageMatrix = vsProgram->resolveParameter(GCT_MATRIX_4X4, -1, (uint16)GPV_LIGHTS, "gTexViewProjImageMatrix"); + + hasError |= !(mWorldMatrix.get()) || !(textureUnitParams->mTextureViewProjImageMatrix.get()); + + const TextureUnitState::EffectMap& effectMap = textureUnitParams->mTextureUnitState->getEffects(); + TextureUnitState::EffectMap::const_iterator effi; + + for (effi = effectMap.begin(); effi != effectMap.end(); ++effi) + { + if (effi->second.type == TextureUnitState::ET_PROJECTIVE_TEXTURE) + { + textureUnitParams->mTextureProjector = effi->second.frustum; + break; + } + } + + hasError |= !(textureUnitParams->mTextureProjector); + break; + } + + + if (hasError) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "FFPTexturing::resolveUniformParams" ); + } + return true; } @@ -170,817 +170,817 @@ bool FFPTexturing::resolveUniformParams(TextureUnitParams* textureUnitParams, Pr //----------------------------------------------------------------------- bool FFPTexturing::resolveFunctionsParams(TextureUnitParams* textureUnitParams, ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - Parameter::Content texCoordContent = Parameter::SPC_UNKNOWN; - bool hasError = false; - - switch (textureUnitParams->mTexCoordCalcMethod) - { - case TEXCALC_NONE: - // Resolve explicit vs input texture coordinates. - - if (textureUnitParams->mTextureMatrix.get() == NULL) - texCoordContent = Parameter::Content(Parameter::SPC_TEXTURE_COORDINATE0 + textureUnitParams->mTextureUnitState->getTextureCoordSet()); - - textureUnitParams->mVSInputTexCoord = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - textureUnitParams->mTextureUnitState->getTextureCoordSet(), - Parameter::Content(Parameter::SPC_TEXTURE_COORDINATE0 + textureUnitParams->mTextureUnitState->getTextureCoordSet()), - textureUnitParams->mVSInTextureCoordinateType); - hasError |= !(textureUnitParams->mVSInputTexCoord.get()); - break; - - case TEXCALC_ENVIRONMENT_MAP: - case TEXCALC_ENVIRONMENT_MAP_PLANAR: - case TEXCALC_ENVIRONMENT_MAP_NORMAL: - // Resolve vertex normal. - mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - mVSInputNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - hasError |= !(mVSInputNormal.get()) || !(mVSInputPos.get()); - break; - - case TEXCALC_ENVIRONMENT_MAP_REFLECTION: - - // Resolve vertex normal. - mVSInputNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - // Resolve vertex position. - mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - - hasError |= !(mVSInputNormal.get()) || !(mVSInputPos.get()); - break; - - case TEXCALC_PROJECTIVE_TEXTURE: - // Resolve vertex position. - mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - hasError |= !(mVSInputPos.get()); - break; - } - - // Resolve vs output texture coordinates. - textureUnitParams->mVSOutputTexCoord = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, - -1, - texCoordContent, - textureUnitParams->mVSOutTextureCoordinateType); - - // Resolve ps input texture coordinates. - textureUnitParams->mPSInputTexCoord = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - textureUnitParams->mVSOutputTexCoord->getIndex(), - textureUnitParams->mVSOutputTexCoord->getContent(), - textureUnitParams->mVSOutTextureCoordinateType); - - const ShaderParameterList& inputParams = psMain->getInputParameters(); - const ShaderParameterList& localParams = psMain->getLocalParameters(); - - mPSDiffuse = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - if (mPSDiffuse.get() == NULL) - { - mPSDiffuse = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - } - - mPSSpecular = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - if (mPSSpecular.get() == NULL) - { - mPSSpecular = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - } - - mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - - hasError |= !(textureUnitParams->mVSOutputTexCoord.get()) || !(textureUnitParams->mPSInputTexCoord.get()) || - !(mPSDiffuse.get()) || !(mPSSpecular.get()) || !(mPSOutDiffuse.get()); - - if (hasError) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "FFPTexturing::resolveFunctionsParams" ); - } - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + Parameter::Content texCoordContent = Parameter::SPC_UNKNOWN; + bool hasError = false; + + switch (textureUnitParams->mTexCoordCalcMethod) + { + case TEXCALC_NONE: + // Resolve explicit vs input texture coordinates. + + if (textureUnitParams->mTextureMatrix.get() == NULL) + texCoordContent = Parameter::Content(Parameter::SPC_TEXTURE_COORDINATE0 + textureUnitParams->mTextureUnitState->getTextureCoordSet()); + + textureUnitParams->mVSInputTexCoord = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + textureUnitParams->mTextureUnitState->getTextureCoordSet(), + Parameter::Content(Parameter::SPC_TEXTURE_COORDINATE0 + textureUnitParams->mTextureUnitState->getTextureCoordSet()), + textureUnitParams->mVSInTextureCoordinateType); + hasError |= !(textureUnitParams->mVSInputTexCoord.get()); + break; + + case TEXCALC_ENVIRONMENT_MAP: + case TEXCALC_ENVIRONMENT_MAP_PLANAR: + case TEXCALC_ENVIRONMENT_MAP_NORMAL: + // Resolve vertex normal. + mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + mVSInputNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + hasError |= !(mVSInputNormal.get()) || !(mVSInputPos.get()); + break; + + case TEXCALC_ENVIRONMENT_MAP_REFLECTION: + + // Resolve vertex normal. + mVSInputNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + // Resolve vertex position. + mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + + hasError |= !(mVSInputNormal.get()) || !(mVSInputPos.get()); + break; + + case TEXCALC_PROJECTIVE_TEXTURE: + // Resolve vertex position. + mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + hasError |= !(mVSInputPos.get()); + break; + } + + // Resolve vs output texture coordinates. + textureUnitParams->mVSOutputTexCoord = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, + -1, + texCoordContent, + textureUnitParams->mVSOutTextureCoordinateType); + + // Resolve ps input texture coordinates. + textureUnitParams->mPSInputTexCoord = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + textureUnitParams->mVSOutputTexCoord->getIndex(), + textureUnitParams->mVSOutputTexCoord->getContent(), + textureUnitParams->mVSOutTextureCoordinateType); + + const ShaderParameterList& inputParams = psMain->getInputParameters(); + const ShaderParameterList& localParams = psMain->getLocalParameters(); + + mPSDiffuse = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + if (mPSDiffuse.get() == NULL) + { + mPSDiffuse = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + } + + mPSSpecular = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + if (mPSSpecular.get() == NULL) + { + mPSSpecular = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + } + + mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + + hasError |= !(textureUnitParams->mVSOutputTexCoord.get()) || !(textureUnitParams->mPSInputTexCoord.get()) || + !(mPSDiffuse.get()) || !(mPSSpecular.get()) || !(mPSOutDiffuse.get()); + + if (hasError) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "FFPTexturing::resolveFunctionsParams" ); + } + return true; } //----------------------------------------------------------------------- bool FFPTexturing::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); - vsProgram->addDependency(FFP_LIB_COMMON); - vsProgram->addDependency(FFP_LIB_TEXTURING); - psProgram->addDependency(FFP_LIB_COMMON); - psProgram->addDependency(FFP_LIB_TEXTURING); + vsProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(FFP_LIB_TEXTURING); + psProgram->addDependency(FFP_LIB_COMMON); + psProgram->addDependency(FFP_LIB_TEXTURING); - return true; + return true; } //----------------------------------------------------------------------- bool FFPTexturing::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - int internalCounter = 0; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + int internalCounter = 0; - for (unsigned int i=0; i < mTextureUnitParamsList.size(); ++i) - { - TextureUnitParams* curParams = &mTextureUnitParamsList[i]; + for (unsigned int i=0; i < mTextureUnitParamsList.size(); ++i) + { + TextureUnitParams* curParams = &mTextureUnitParamsList[i]; - if (false == addVSFunctionInvocations(curParams, vsMain)) - return false; + if (false == addVSFunctionInvocations(curParams, vsMain)) + return false; - if (false == addPSFunctionInvocations(curParams, psMain, internalCounter)) - return false; - } + if (false == addPSFunctionInvocations(curParams, psMain, internalCounter)) + return false; + } - return true; + return true; } //----------------------------------------------------------------------- bool FFPTexturing::addVSFunctionInvocations(TextureUnitParams* textureUnitParams, Function* vsMain) { - FunctionInvocation* texCoordCalcFunc = NULL; - - - switch (textureUnitParams->mTexCoordCalcMethod) - { - case TEXCALC_NONE: - if (textureUnitParams->mTextureMatrix.get() == NULL) - { - texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); - - texCoordCalcFunc->pushOperand(textureUnitParams->mVSInputTexCoord, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); - } - else - { - texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM_TEXCOORD, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); - - texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mVSInputTexCoord, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); - } - break; - - case TEXCALC_ENVIRONMENT_MAP: - case TEXCALC_ENVIRONMENT_MAP_PLANAR: - if (textureUnitParams->mTextureMatrix.get() == NULL) - { - texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); - - //TODO: Add field member mWorldViewITMatrix - texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); - } - else - { - texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); - - texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); - } - break; - - - case TEXCALC_ENVIRONMENT_MAP_REFLECTION: - if (textureUnitParams->mTextureMatrix.get() == NULL) - { - texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); - - texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); - } - else - { - texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); - - texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); - } - break; - - case TEXCALC_ENVIRONMENT_MAP_NORMAL: - if (textureUnitParams->mTextureMatrix.get() == NULL) - { - texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_NORMAL, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); - - texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); - } - else - { - texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_NORMAL, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); - - texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); - } - break; - - case TEXCALC_PROJECTIVE_TEXTURE: - - texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_PROJECTION, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); - - texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mTextureViewProjImageMatrix, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); - texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); - - break; - } - - if (texCoordCalcFunc != NULL) - vsMain->addAtomInstance(texCoordCalcFunc); - - return true; + FunctionInvocation* texCoordCalcFunc = NULL; + + + switch (textureUnitParams->mTexCoordCalcMethod) + { + case TEXCALC_NONE: + if (textureUnitParams->mTextureMatrix.get() == NULL) + { + texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); + + texCoordCalcFunc->pushOperand(textureUnitParams->mVSInputTexCoord, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); + } + else + { + texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM_TEXCOORD, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); + + texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mVSInputTexCoord, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); + } + break; + + case TEXCALC_ENVIRONMENT_MAP: + case TEXCALC_ENVIRONMENT_MAP_PLANAR: + if (textureUnitParams->mTextureMatrix.get() == NULL) + { + texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); + + //TODO: Add field member mWorldViewITMatrix + texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); + } + else + { + texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); + + texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); + } + break; + + + case TEXCALC_ENVIRONMENT_MAP_REFLECTION: + if (textureUnitParams->mTextureMatrix.get() == NULL) + { + texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); + + texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); + } + else + { + texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); + + texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); + } + break; + + case TEXCALC_ENVIRONMENT_MAP_NORMAL: + if (textureUnitParams->mTextureMatrix.get() == NULL) + { + texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_NORMAL, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); + + texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); + } + else + { + texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_NORMAL, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); + + texCoordCalcFunc->pushOperand(mWorldITMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mViewMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mTextureMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputNormal, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); + } + break; + + case TEXCALC_PROJECTIVE_TEXTURE: + + texCoordCalcFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_PROJECTION, FFP_VS_TEXTURING, textureUnitParams->mTextureSamplerIndex); + + texCoordCalcFunc->pushOperand(mWorldMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mTextureViewProjImageMatrix, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(mVSInputPos, Operand::OPS_IN); + texCoordCalcFunc->pushOperand(textureUnitParams->mVSOutputTexCoord, Operand::OPS_OUT); + + break; + } + + if (texCoordCalcFunc != NULL) + vsMain->addAtomInstance(texCoordCalcFunc); + + return true; } //----------------------------------------------------------------------- bool FFPTexturing::addPSFunctionInvocations(TextureUnitParams* textureUnitParams, Function* psMain, int& internalCounter) { - const LayerBlendModeEx& colourBlend = textureUnitParams->mTextureUnitState->getColourBlendMode(); - const LayerBlendModeEx& alphaBlend = textureUnitParams->mTextureUnitState->getAlphaBlendMode(); - ParameterPtr source1; - ParameterPtr source2; - int groupOrder = FFP_PS_TEXTURING; - - - // Add texture sampling code. - ParameterPtr texel = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, c_ParamTexelEx + StringConverter::toString(textureUnitParams->mTextureSamplerIndex), GCT_FLOAT4); - addPSSampleTexelInvocation(textureUnitParams, psMain, texel, FFP_PS_SAMPLING, internalCounter); - - // Build colour argument for source1. - source1 = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "source1", GCT_FLOAT4); - - addPSArgumentInvocations(psMain, source1, texel, - textureUnitParams->mTextureSamplerIndex, - colourBlend.source1, colourBlend.colourArg1, - colourBlend.alphaArg1, false, groupOrder, internalCounter); - - // Build colour argument for source2. - source2 = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "source2", GCT_FLOAT4); - - addPSArgumentInvocations(psMain, source2, texel, - textureUnitParams->mTextureSamplerIndex, - colourBlend.source2, colourBlend.colourArg2, - colourBlend.alphaArg2, false, groupOrder, internalCounter); - - bool needDifferentAlphaBlend = false; - if (alphaBlend.operation != colourBlend.operation || - alphaBlend.source1 != colourBlend.source1 || - alphaBlend.source2 != colourBlend.source2 || - colourBlend.source1 == LBS_MANUAL || - colourBlend.source2 == LBS_MANUAL || - alphaBlend.source1 == LBS_MANUAL || - alphaBlend.source2 == LBS_MANUAL) - needDifferentAlphaBlend = true; - - // Build colours blend - addPSBlendInvocations(psMain, source1, source2, texel, - textureUnitParams->mTextureSamplerIndex, - colourBlend, groupOrder, internalCounter, - needDifferentAlphaBlend ? Operand::OPM_XYZ : Operand::OPM_ALL); - - // Case we need different alpha channel code. - if (needDifferentAlphaBlend) - { - // Build alpha argument for source1. - addPSArgumentInvocations(psMain, source1, texel, - textureUnitParams->mTextureSamplerIndex, - alphaBlend.source1, alphaBlend.colourArg1, - alphaBlend.alphaArg1, true, groupOrder, internalCounter); - - // Build alpha argument for source2. - addPSArgumentInvocations(psMain, source2, texel, - textureUnitParams->mTextureSamplerIndex, - alphaBlend.source2, alphaBlend.colourArg2, - alphaBlend.alphaArg2, true, groupOrder, internalCounter); - - // Build alpha blend - addPSBlendInvocations(psMain, source1, source2, texel, - textureUnitParams->mTextureSamplerIndex, - alphaBlend, groupOrder, internalCounter, - Operand::OPM_W); - } - - - - return true; + const LayerBlendModeEx& colourBlend = textureUnitParams->mTextureUnitState->getColourBlendMode(); + const LayerBlendModeEx& alphaBlend = textureUnitParams->mTextureUnitState->getAlphaBlendMode(); + ParameterPtr source1; + ParameterPtr source2; + int groupOrder = FFP_PS_TEXTURING; + + + // Add texture sampling code. + ParameterPtr texel = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, c_ParamTexelEx + StringConverter::toString(textureUnitParams->mTextureSamplerIndex), GCT_FLOAT4); + addPSSampleTexelInvocation(textureUnitParams, psMain, texel, FFP_PS_SAMPLING, internalCounter); + + // Build colour argument for source1. + source1 = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "source1", GCT_FLOAT4); + + addPSArgumentInvocations(psMain, source1, texel, + textureUnitParams->mTextureSamplerIndex, + colourBlend.source1, colourBlend.colourArg1, + colourBlend.alphaArg1, false, groupOrder, internalCounter); + + // Build colour argument for source2. + source2 = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "source2", GCT_FLOAT4); + + addPSArgumentInvocations(psMain, source2, texel, + textureUnitParams->mTextureSamplerIndex, + colourBlend.source2, colourBlend.colourArg2, + colourBlend.alphaArg2, false, groupOrder, internalCounter); + + bool needDifferentAlphaBlend = false; + if (alphaBlend.operation != colourBlend.operation || + alphaBlend.source1 != colourBlend.source1 || + alphaBlend.source2 != colourBlend.source2 || + colourBlend.source1 == LBS_MANUAL || + colourBlend.source2 == LBS_MANUAL || + alphaBlend.source1 == LBS_MANUAL || + alphaBlend.source2 == LBS_MANUAL) + needDifferentAlphaBlend = true; + + // Build colours blend + addPSBlendInvocations(psMain, source1, source2, texel, + textureUnitParams->mTextureSamplerIndex, + colourBlend, groupOrder, internalCounter, + needDifferentAlphaBlend ? Operand::OPM_XYZ : Operand::OPM_ALL); + + // Case we need different alpha channel code. + if (needDifferentAlphaBlend) + { + // Build alpha argument for source1. + addPSArgumentInvocations(psMain, source1, texel, + textureUnitParams->mTextureSamplerIndex, + alphaBlend.source1, alphaBlend.colourArg1, + alphaBlend.alphaArg1, true, groupOrder, internalCounter); + + // Build alpha argument for source2. + addPSArgumentInvocations(psMain, source2, texel, + textureUnitParams->mTextureSamplerIndex, + alphaBlend.source2, alphaBlend.colourArg2, + alphaBlend.alphaArg2, true, groupOrder, internalCounter); + + // Build alpha blend + addPSBlendInvocations(psMain, source1, source2, texel, + textureUnitParams->mTextureSamplerIndex, + alphaBlend, groupOrder, internalCounter, + Operand::OPM_W); + } + + + + return true; } ParameterPtr FFPTexturing::GetSamplerWrapperParam(GpuConstantType samplerType,Function* function) { - Ogre::String paramName = "lLocalSamplerWrapper_"; - int samplerParamDim = samplerType - GCT_SAMPLER1D + 1; - if (samplerParamDim <= 3 ) - paramName += StringConverter::toString(samplerParamDim) + "D"; - else if (samplerParamDim == 4 ) - paramName += "Cube"; - - GpuConstantType margin = (GpuConstantType)(GCT_SAMPLER_WRAPPER1D - GCT_SAMPLER1D); - GpuConstantType samplerWrapperType = (GpuConstantType)(samplerType + margin); - - ParameterPtr samplerWrapperParam = function->resolveLocalParameter(Parameter::SPS_UNKNOWN,-1, paramName,samplerWrapperType); - return samplerWrapperParam; + Ogre::String paramName = "lLocalSamplerWrapper_"; + int samplerParamDim = samplerType - GCT_SAMPLER1D + 1; + if (samplerParamDim <= 3 ) + paramName += StringConverter::toString(samplerParamDim) + "D"; + else if (samplerParamDim == 4 ) + paramName += "Cube"; + + GpuConstantType margin = (GpuConstantType)(GCT_SAMPLER_WRAPPER1D - GCT_SAMPLER1D); + GpuConstantType samplerWrapperType = (GpuConstantType)(samplerType + margin); + + ParameterPtr samplerWrapperParam = function->resolveLocalParameter(Parameter::SPS_UNKNOWN,-1, paramName,samplerWrapperType); + return samplerWrapperParam; } void FFPTexturing::AddTextureSampleWrapperInvocation(UniformParameterPtr textureSampler,UniformParameterPtr textureSamplerState, - GpuConstantType samplerType, Function* function, int groupOrder, int& internalCounter) + GpuConstantType samplerType, Function* function, int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - ParameterPtr samplerWrapperParam = GetSamplerWrapperParam(samplerType,function); - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT_SAMPLER_WRAPPER, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(textureSampler, Operand::OPS_IN); + FunctionInvocation* curFuncInvocation = NULL; + + ParameterPtr samplerWrapperParam = GetSamplerWrapperParam(samplerType,function); + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT_SAMPLER_WRAPPER, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(textureSampler, Operand::OPS_IN); - if (Ogre::RTShader::ShaderGenerator::getSingletonPtr()->IsHlsl4()) - curFuncInvocation->pushOperand(textureSamplerState, Operand::OPS_IN); + if (Ogre::RTShader::ShaderGenerator::getSingletonPtr()->IsHlsl4()) + curFuncInvocation->pushOperand(textureSamplerState, Operand::OPS_IN); - curFuncInvocation->pushOperand(samplerWrapperParam, Operand::OPS_OUT); - function->addAtomInstance(curFuncInvocation); + curFuncInvocation->pushOperand(samplerWrapperParam, Operand::OPS_OUT); + function->addAtomInstance(curFuncInvocation); } //----------------------------------------------------------------------- void FFPTexturing::addPSSampleTexelInvocation(TextureUnitParams* textureUnitParams, Function* psMain, - const ParameterPtr& texel, int groupOrder, int& internalCounter) + const ParameterPtr& texel, int groupOrder, int& internalCounter) { - Ogre::String targetLanguage = RTShader::ShaderGenerator::getSingleton().getTargetLanguage(); - - if (targetLanguage == "hlsl") - { - FunctionInvocation* curFuncInvocation = NULL; - ParameterPtr samplerWrapperParam = GetSamplerWrapperParam(textureUnitParams->mTextureSamplerType,psMain); - AddTextureSampleWrapperInvocation(textureUnitParams->mTextureSampler,textureUnitParams->mTextureSamplerState,textureUnitParams->mTextureSamplerType,psMain,groupOrder,internalCounter); - - if (textureUnitParams->mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE) - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE_PROJ, groupOrder, internalCounter++); - else - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE, groupOrder, internalCounter++); - - - curFuncInvocation->pushOperand(samplerWrapperParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(textureUnitParams->mPSInputTexCoord, Operand::OPS_IN); - curFuncInvocation->pushOperand(texel, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - - } - else - { // Old behaviour for CG and GLSL - FunctionInvocation* curFuncInvocation = NULL; - - if (textureUnitParams->mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE) - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE_PROJ, groupOrder, internalCounter++); - else - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE, groupOrder, internalCounter++); - - curFuncInvocation->pushOperand(textureUnitParams->mTextureSampler, Operand::OPS_IN); - curFuncInvocation->pushOperand(textureUnitParams->mPSInputTexCoord, Operand::OPS_IN); - curFuncInvocation->pushOperand(texel, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } + Ogre::String targetLanguage = RTShader::ShaderGenerator::getSingleton().getTargetLanguage(); + + if (targetLanguage == "hlsl") + { + FunctionInvocation* curFuncInvocation = NULL; + ParameterPtr samplerWrapperParam = GetSamplerWrapperParam(textureUnitParams->mTextureSamplerType,psMain); + AddTextureSampleWrapperInvocation(textureUnitParams->mTextureSampler,textureUnitParams->mTextureSamplerState,textureUnitParams->mTextureSamplerType,psMain,groupOrder,internalCounter); + + if (textureUnitParams->mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE) + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE_PROJ, groupOrder, internalCounter++); + else + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE, groupOrder, internalCounter++); + + + curFuncInvocation->pushOperand(samplerWrapperParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(textureUnitParams->mPSInputTexCoord, Operand::OPS_IN); + curFuncInvocation->pushOperand(texel, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + + } + else + { // Old behaviour for CG and GLSL + FunctionInvocation* curFuncInvocation = NULL; + + if (textureUnitParams->mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE) + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE_PROJ, groupOrder, internalCounter++); + else + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE, groupOrder, internalCounter++); + + curFuncInvocation->pushOperand(textureUnitParams->mTextureSampler, Operand::OPS_IN); + curFuncInvocation->pushOperand(textureUnitParams->mPSInputTexCoord, Operand::OPS_IN); + curFuncInvocation->pushOperand(texel, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } } //----------------------------------------------------------------------- void FFPTexturing::addPSArgumentInvocations(Function* psMain, - ParameterPtr arg, - ParameterPtr texel, - int samplerIndex, - LayerBlendSource blendSrc, - const ColourValue& colourValue, - Real alphaValue, - bool isAlphaArgument, - const int groupOrder, - int& internalCounter) + ParameterPtr arg, + ParameterPtr texel, + int samplerIndex, + LayerBlendSource blendSrc, + const ColourValue& colourValue, + Real alphaValue, + bool isAlphaArgument, + const int groupOrder, + int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - switch(blendSrc) - { - case LBS_CURRENT: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - if (samplerIndex == 0) - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - else - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBS_TEXTURE: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(texel, Operand::OPS_IN); - curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBS_DIFFUSE: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBS_SPECULAR: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN); - curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - break; - - case LBS_MANUAL: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, groupOrder, internalCounter++); - - if (isAlphaArgument) - { - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(alphaValue), Operand::OPS_IN); - } - else - { - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.r), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.g), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.b), Operand::OPS_IN); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.a), Operand::OPS_IN); - } - - curFuncInvocation->pushOperand(arg, Operand::OPS_IN); - psMain->addAtomInstance(curFuncInvocation); - break; - } + FunctionInvocation* curFuncInvocation = NULL; + + switch(blendSrc) + { + case LBS_CURRENT: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + if (samplerIndex == 0) + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + else + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBS_TEXTURE: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(texel, Operand::OPS_IN); + curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBS_DIFFUSE: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBS_SPECULAR: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN); + curFuncInvocation->pushOperand(arg, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + break; + + case LBS_MANUAL: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_CONSTRUCT, groupOrder, internalCounter++); + + if (isAlphaArgument) + { + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(alphaValue), Operand::OPS_IN); + } + else + { + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.r), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.g), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.b), Operand::OPS_IN); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(colourValue.a), Operand::OPS_IN); + } + + curFuncInvocation->pushOperand(arg, Operand::OPS_IN); + psMain->addAtomInstance(curFuncInvocation); + break; + } } //----------------------------------------------------------------------- void FFPTexturing::addPSBlendInvocations(Function* psMain, - ParameterPtr arg1, - ParameterPtr arg2, - ParameterPtr texel, - int samplerIndex, - const LayerBlendModeEx& blendMode, - const int groupOrder, - int& internalCounter, - int targetChannels) + ParameterPtr arg1, + ParameterPtr arg2, + ParameterPtr texel, + int samplerIndex, + const LayerBlendModeEx& blendMode, + const int groupOrder, + int& internalCounter, + int targetChannels) { - FunctionInvocation* curFuncInvocation = NULL; - - switch(blendMode.operation) - { - case LBX_SOURCE1: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_SOURCE2: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_MODULATE: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_MODULATE_X2: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATEX2, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_MODULATE_X4: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATEX4, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_ADD: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_ADD_SIGNED: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADDSIGNED, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_ADD_SMOOTH: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADDSMOOTH, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_SUBTRACT: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_BLEND_DIFFUSE_ALPHA: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_W); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_BLEND_TEXTURE_ALPHA: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(texel, Operand::OPS_IN, Operand::OPM_W); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_BLEND_CURRENT_ALPHA: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - - if (samplerIndex == 0) - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_W); - else - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN, Operand::OPM_W); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_BLEND_MANUAL: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(blendMode.factor), Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_DOTPRODUCT: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_DOTPRODUCT, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - case LBX_BLEND_DIFFUSE_COLOUR: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); - psMain->addAtomInstance(curFuncInvocation); - break; - } + FunctionInvocation* curFuncInvocation = NULL; + + switch(blendMode.operation) + { + case LBX_SOURCE1: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_SOURCE2: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_MODULATE: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_MODULATE_X2: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATEX2, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_MODULATE_X4: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATEX4, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_ADD: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_ADD_SIGNED: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADDSIGNED, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_ADD_SMOOTH: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADDSMOOTH, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_SUBTRACT: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_BLEND_DIFFUSE_ALPHA: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SUBTRACT, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_W); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_BLEND_TEXTURE_ALPHA: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(texel, Operand::OPS_IN, Operand::OPM_W); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_BLEND_CURRENT_ALPHA: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + + if (samplerIndex == 0) + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_W); + else + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN, Operand::OPM_W); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_BLEND_MANUAL: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(ParameterFactory::createConstParamFloat(blendMode.factor), Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_DOTPRODUCT: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_DOTPRODUCT, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + case LBX_BLEND_DIFFUSE_COLOUR: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_LERP, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(arg2, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(arg1, Operand::OPS_IN, targetChannels); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, targetChannels); + psMain->addAtomInstance(curFuncInvocation); + break; + } } //----------------------------------------------------------------------- TexCoordCalcMethod FFPTexturing::getTexCalcMethod(TextureUnitState* textureUnitState) { - TexCoordCalcMethod texCoordCalcMethod = TEXCALC_NONE; - const TextureUnitState::EffectMap& effectMap = textureUnitState->getEffects(); - TextureUnitState::EffectMap::const_iterator effi; - - for (effi = effectMap.begin(); effi != effectMap.end(); ++effi) - { - switch (effi->second.type) - { - case TextureUnitState::ET_ENVIRONMENT_MAP: - if (effi->second.subtype == TextureUnitState::ENV_CURVED) - { - texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP; - } - else if (effi->second.subtype == TextureUnitState::ENV_PLANAR) - { - texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP_PLANAR; - } - else if (effi->second.subtype == TextureUnitState::ENV_REFLECTION) - { - texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP_REFLECTION; - } - else if (effi->second.subtype == TextureUnitState::ENV_NORMAL) - { - texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP_NORMAL; - } - break; - case TextureUnitState::ET_UVSCROLL: - case TextureUnitState::ET_USCROLL: - case TextureUnitState::ET_VSCROLL: - case TextureUnitState::ET_ROTATE: - case TextureUnitState::ET_TRANSFORM: - break; - case TextureUnitState::ET_PROJECTIVE_TEXTURE: - texCoordCalcMethod = TEXCALC_PROJECTIVE_TEXTURE; - break; - } - } - - return texCoordCalcMethod; + TexCoordCalcMethod texCoordCalcMethod = TEXCALC_NONE; + const TextureUnitState::EffectMap& effectMap = textureUnitState->getEffects(); + TextureUnitState::EffectMap::const_iterator effi; + + for (effi = effectMap.begin(); effi != effectMap.end(); ++effi) + { + switch (effi->second.type) + { + case TextureUnitState::ET_ENVIRONMENT_MAP: + if (effi->second.subtype == TextureUnitState::ENV_CURVED) + { + texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP; + } + else if (effi->second.subtype == TextureUnitState::ENV_PLANAR) + { + texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP_PLANAR; + } + else if (effi->second.subtype == TextureUnitState::ENV_REFLECTION) + { + texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP_REFLECTION; + } + else if (effi->second.subtype == TextureUnitState::ENV_NORMAL) + { + texCoordCalcMethod = TEXCALC_ENVIRONMENT_MAP_NORMAL; + } + break; + case TextureUnitState::ET_UVSCROLL: + case TextureUnitState::ET_USCROLL: + case TextureUnitState::ET_VSCROLL: + case TextureUnitState::ET_ROTATE: + case TextureUnitState::ET_TRANSFORM: + break; + case TextureUnitState::ET_PROJECTIVE_TEXTURE: + texCoordCalcMethod = TEXCALC_PROJECTIVE_TEXTURE; + break; + } + } + + return texCoordCalcMethod; } //----------------------------------------------------------------------- bool FFPTexturing::needsTextureMatrix(TextureUnitState* textureUnitState) { - const TextureUnitState::EffectMap& effectMap = textureUnitState->getEffects(); - TextureUnitState::EffectMap::const_iterator effi; - - for (effi = effectMap.begin(); effi != effectMap.end(); ++effi) - { - switch (effi->second.type) - { - - case TextureUnitState::ET_UVSCROLL: - case TextureUnitState::ET_USCROLL: - case TextureUnitState::ET_VSCROLL: - case TextureUnitState::ET_ROTATE: - case TextureUnitState::ET_TRANSFORM: - case TextureUnitState::ET_ENVIRONMENT_MAP: - case TextureUnitState::ET_PROJECTIVE_TEXTURE: - return true; - } - } - - const Ogre::Matrix4 matTexture = textureUnitState->getTextureTransform(); - - // Resolve texture matrix parameter. - if (matTexture != Matrix4::IDENTITY) - return true; - - return false; + const TextureUnitState::EffectMap& effectMap = textureUnitState->getEffects(); + TextureUnitState::EffectMap::const_iterator effi; + + for (effi = effectMap.begin(); effi != effectMap.end(); ++effi) + { + switch (effi->second.type) + { + + case TextureUnitState::ET_UVSCROLL: + case TextureUnitState::ET_USCROLL: + case TextureUnitState::ET_VSCROLL: + case TextureUnitState::ET_ROTATE: + case TextureUnitState::ET_TRANSFORM: + case TextureUnitState::ET_ENVIRONMENT_MAP: + case TextureUnitState::ET_PROJECTIVE_TEXTURE: + return true; + } + } + + const Ogre::Matrix4 matTexture = textureUnitState->getTextureTransform(); + + // Resolve texture matrix parameter. + if (matTexture != Matrix4::IDENTITY) + return true; + + return false; } //----------------------------------------------------------------------- void FFPTexturing::copyFrom(const SubRenderState& rhs) { - const FFPTexturing& rhsTexture = static_cast(rhs); + const FFPTexturing& rhsTexture = static_cast(rhs); - setTextureUnitCount(rhsTexture.getTextureUnitCount()); + setTextureUnitCount(rhsTexture.getTextureUnitCount()); - for (unsigned int i=0; i < rhsTexture.getTextureUnitCount(); ++i) - { - setTextureUnit(i, rhsTexture.mTextureUnitParamsList[i].mTextureUnitState); - } + for (unsigned int i=0; i < rhsTexture.getTextureUnitCount(); ++i) + { + setTextureUnit(i, rhsTexture.mTextureUnitParamsList[i].mTextureUnitState); + } } //----------------------------------------------------------------------- bool FFPTexturing::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { - //count the number of texture units we need to process - size_t validTexUnits = 0; - for (unsigned short i=0; i < srcPass->getNumTextureUnitStates(); ++i) - { - if (isProcessingNeeded(srcPass->getTextureUnitState(i))) - { - ++validTexUnits; - } - } - - setTextureUnitCount(validTexUnits); - - // Build texture stage sub states. - for (unsigned short i=0; i < srcPass->getNumTextureUnitStates(); ++i) - { - TextureUnitState* texUnitState = srcPass->getTextureUnitState(i); - - if (isProcessingNeeded(texUnitState)) - { - setTextureUnit(i, texUnitState); - } - } - - return true; + //count the number of texture units we need to process + size_t validTexUnits = 0; + for (unsigned short i=0; i < srcPass->getNumTextureUnitStates(); ++i) + { + if (isProcessingNeeded(srcPass->getTextureUnitState(i))) + { + ++validTexUnits; + } + } + + setTextureUnitCount(validTexUnits); + + // Build texture stage sub states. + for (unsigned short i=0; i < srcPass->getNumTextureUnitStates(); ++i) + { + TextureUnitState* texUnitState = srcPass->getTextureUnitState(i); + + if (isProcessingNeeded(texUnitState)) + { + setTextureUnit(i, texUnitState); + } + } + + return true; } //----------------------------------------------------------------------- void FFPTexturing::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, - const LightList* pLightList) + const LightList* pLightList) { - for (unsigned int i=0; i < mTextureUnitParamsList.size(); ++i) - { - TextureUnitParams* curParams = &mTextureUnitParamsList[i]; - - if (curParams->mTextureProjector != NULL && curParams->mTextureViewProjImageMatrix.get() != NULL) - { - Matrix4 matTexViewProjImage; - - matTexViewProjImage = - Matrix4::CLIPSPACE2DTOIMAGESPACE * - curParams->mTextureProjector->getProjectionMatrixWithRSDepth() * - curParams->mTextureProjector->getViewMatrix(); - - curParams->mTextureViewProjImageMatrix->setGpuParameter(matTexViewProjImage); - } - } + for (unsigned int i=0; i < mTextureUnitParamsList.size(); ++i) + { + TextureUnitParams* curParams = &mTextureUnitParamsList[i]; + + if (curParams->mTextureProjector != NULL && curParams->mTextureViewProjImageMatrix.get() != NULL) + { + Matrix4 matTexViewProjImage; + + matTexViewProjImage = + Matrix4::CLIPSPACE2DTOIMAGESPACE * + curParams->mTextureProjector->getProjectionMatrixWithRSDepth() * + curParams->mTextureProjector->getViewMatrix(); + + curParams->mTextureViewProjImageMatrix->setGpuParameter(matTexViewProjImage); + } + } } //----------------------------------------------------------------------- void FFPTexturing::setTextureUnitCount(size_t count) { - mTextureUnitParamsList.resize(count); - - for (unsigned int i=0; i < count; ++i) - { - TextureUnitParams& curParams = mTextureUnitParamsList[i]; - - curParams.mTextureUnitState = NULL; - curParams.mTextureProjector = NULL; - curParams.mTextureSamplerIndex = 0; - curParams.mTextureSamplerType = GCT_SAMPLER2D; - curParams.mVSInTextureCoordinateType = GCT_FLOAT2; - curParams.mVSOutTextureCoordinateType = GCT_FLOAT2; - } + mTextureUnitParamsList.resize(count); + + for (unsigned int i=0; i < count; ++i) + { + TextureUnitParams& curParams = mTextureUnitParamsList[i]; + + curParams.mTextureUnitState = NULL; + curParams.mTextureProjector = NULL; + curParams.mTextureSamplerIndex = 0; + curParams.mTextureSamplerType = GCT_SAMPLER2D; + curParams.mVSInTextureCoordinateType = GCT_FLOAT2; + curParams.mVSOutTextureCoordinateType = GCT_FLOAT2; + } } //----------------------------------------------------------------------- void FFPTexturing::setTextureUnit(unsigned short index, TextureUnitState* textureUnitState) { - if (index >= mTextureUnitParamsList.size()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "FFPTexturing unit index out of bounds !!!", - "FFPTexturing::setTextureUnit"); - } - - if (textureUnitState->getBindingType() == TextureUnitState::BT_VERTEX) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "FFP Texture unit does not support vertex texture fetch !!!", - "FFPTexturing::setTextureUnit"); - } - - if (textureUnitState->getBindingType() == TextureUnitState::BT_GEOMETRY) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "FFP Texture unit does not support geometry texture fetch !!!", - "FFPTexturing::setTextureUnit"); - } - - if (textureUnitState->getBindingType() == TextureUnitState::BT_COMPUTE) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "FFP Texture unit does not support comput texture fetch !!!", - "FFPTexturing::setTextureUnit"); - } - - if (textureUnitState->getBindingType() == TextureUnitState::BT_TESSELLATION_DOMAIN) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "FFP Texture unit does not support domain texture fetch !!!", - "FFPTexturing::setTextureUnit"); - } - - if (textureUnitState->getBindingType() == TextureUnitState::BT_TESSELLATION_HULL) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "FFP Texture unit does not support hull texture fetch !!!", - "FFPTexturing::setTextureUnit"); - } - - TextureUnitParams& curParams = mTextureUnitParamsList[index]; - - - curParams.mTextureSamplerIndex = index; - curParams.mTextureUnitState = textureUnitState; - - switch (curParams.mTextureUnitState->getTextureType()) - { - case TEX_TYPE_1D: - curParams.mTextureSamplerType = GCT_SAMPLER1D; - curParams.mVSInTextureCoordinateType = GCT_FLOAT1; - break; - case TEX_TYPE_2D: - curParams.mTextureSamplerType = GCT_SAMPLER2D; - curParams.mVSInTextureCoordinateType = GCT_FLOAT2; - break; + if (index >= mTextureUnitParamsList.size()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "FFPTexturing unit index out of bounds !!!", + "FFPTexturing::setTextureUnit"); + } + + if (textureUnitState->getBindingType() == TextureUnitState::BT_VERTEX) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "FFP Texture unit does not support vertex texture fetch !!!", + "FFPTexturing::setTextureUnit"); + } + + if (textureUnitState->getBindingType() == TextureUnitState::BT_GEOMETRY) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "FFP Texture unit does not support geometry texture fetch !!!", + "FFPTexturing::setTextureUnit"); + } + + if (textureUnitState->getBindingType() == TextureUnitState::BT_COMPUTE) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "FFP Texture unit does not support comput texture fetch !!!", + "FFPTexturing::setTextureUnit"); + } + + if (textureUnitState->getBindingType() == TextureUnitState::BT_TESSELLATION_DOMAIN) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "FFP Texture unit does not support domain texture fetch !!!", + "FFPTexturing::setTextureUnit"); + } + + if (textureUnitState->getBindingType() == TextureUnitState::BT_TESSELLATION_HULL) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "FFP Texture unit does not support hull texture fetch !!!", + "FFPTexturing::setTextureUnit"); + } + + TextureUnitParams& curParams = mTextureUnitParamsList[index]; + + + curParams.mTextureSamplerIndex = index; + curParams.mTextureUnitState = textureUnitState; + + switch (curParams.mTextureUnitState->getTextureType()) + { + case TEX_TYPE_1D: + curParams.mTextureSamplerType = GCT_SAMPLER1D; + curParams.mVSInTextureCoordinateType = GCT_FLOAT1; + break; + case TEX_TYPE_2D: + curParams.mTextureSamplerType = GCT_SAMPLER2D; + curParams.mVSInTextureCoordinateType = GCT_FLOAT2; + break; case TEX_TYPE_2D_RECT: curParams.mTextureSamplerType = GCT_SAMPLERRECT; curParams.mVSInTextureCoordinateType = GCT_FLOAT2; @@ -989,74 +989,74 @@ void FFPTexturing::setTextureUnit(unsigned short index, TextureUnitState* textur curParams.mTextureSamplerType = GCT_SAMPLER2DARRAY; curParams.mVSInTextureCoordinateType = GCT_FLOAT3; break; - case TEX_TYPE_3D: - curParams.mTextureSamplerType = GCT_SAMPLER3D; - curParams.mVSInTextureCoordinateType = GCT_FLOAT3; - break; - case TEX_TYPE_CUBE_MAP: - curParams.mTextureSamplerType = GCT_SAMPLERCUBE; - curParams.mVSInTextureCoordinateType = GCT_FLOAT3; - break; - } - - curParams.mVSOutTextureCoordinateType = curParams.mVSInTextureCoordinateType; - curParams.mTexCoordCalcMethod = getTexCalcMethod(curParams.mTextureUnitState); - - if (curParams.mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE) - curParams.mVSOutTextureCoordinateType = GCT_FLOAT3; + case TEX_TYPE_3D: + curParams.mTextureSamplerType = GCT_SAMPLER3D; + curParams.mVSInTextureCoordinateType = GCT_FLOAT3; + break; + case TEX_TYPE_CUBE_MAP: + curParams.mTextureSamplerType = GCT_SAMPLERCUBE; + curParams.mVSInTextureCoordinateType = GCT_FLOAT3; + break; + } + + curParams.mVSOutTextureCoordinateType = curParams.mVSInTextureCoordinateType; + curParams.mTexCoordCalcMethod = getTexCalcMethod(curParams.mTextureUnitState); + + if (curParams.mTexCoordCalcMethod == TEXCALC_PROJECTIVE_TEXTURE) + curParams.mVSOutTextureCoordinateType = GCT_FLOAT3; } //----------------------------------------------------------------------- bool FFPTexturing::isProcessingNeeded(TextureUnitState* texUnitState) { - return texUnitState->getBindingType() == TextureUnitState::BT_FRAGMENT; + return texUnitState->getBindingType() == TextureUnitState::BT_FRAGMENT; } //----------------------------------------------------------------------- const String& FFPTexturingFactory::getType() const { - return FFPTexturing::Type; + return FFPTexturing::Type; } //----------------------------------------------------------------------- -SubRenderState* FFPTexturingFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* FFPTexturingFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "texturing_stage") - { - if(prop->values.size() == 1) - { - String modelType; - - if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - return NULL; - } - - if (modelType == "ffp") - { - return createOrRetrieveInstance(translator); - } - } - } - - return NULL; + if (prop->name == "texturing_stage") + { + if(prop->values.size() == 1) + { + String modelType; + + if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + return NULL; + } + + if (modelType == "ffp") + { + return createOrRetrieveInstance(translator); + } + } + } + + return NULL; } //----------------------------------------------------------------------- void FFPTexturingFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + Pass* srcPass, Pass* dstPass) { - ser->writeAttribute(4, "texturing_stage"); - ser->writeValue("ffp"); + ser->writeAttribute(4, "texturing_stage"); + ser->writeValue("ffp"); } //----------------------------------------------------------------------- -SubRenderState* FFPTexturingFactory::createInstanceImpl() +SubRenderState* FFPTexturingFactory::createInstanceImpl() { - return OGRE_NEW FFPTexturing; + return OGRE_NEW FFPTexturing; } diff --git a/Components/RTShaderSystem/src/OgreShaderFFPTransform.cpp b/Components/RTShaderSystem/src/OgreShaderFFPTransform.cpp index 3f7e6712ab8..494ce5d7078 100644 --- a/Components/RTShaderSystem/src/OgreShaderFFPTransform.cpp +++ b/Components/RTShaderSystem/src/OgreShaderFFPTransform.cpp @@ -43,50 +43,50 @@ String FFPTransform::Type = "FFP_Transform"; //----------------------------------------------------------------------- const String& FFPTransform::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int FFPTransform::getExecutionOrder() const +int FFPTransform::getExecutionOrder() const { - return FFP_TRANSFORM; + return FFP_TRANSFORM; } //----------------------------------------------------------------------- bool FFPTransform::createCpuSubPrograms(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsEntry = vsProgram->getEntryPointFunction(); - - // Resolve World View Projection Matrix. - UniformParameterPtr wvpMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); - - // Resolve input position parameter. - ParameterPtr positionIn = vsEntry->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - - // Resolve output position parameter. - ParameterPtr positionOut = vsEntry->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); - - if (!(wvpMatrix.get()) || !(positionIn.get()) || !(positionOut.get())) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "FFPTransform::createCpuSubPrograms" ); - } - - // Add dependency. - vsProgram->addDependency(FFP_LIB_TRANSFORM); - - FunctionInvocation* transformFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, 0); - - transformFunc->pushOperand(wvpMatrix, Operand::OPS_IN); - transformFunc->pushOperand(positionIn, Operand::OPS_IN); - transformFunc->pushOperand(positionOut, Operand::OPS_OUT); - - vsEntry->addAtomInstance(transformFunc); - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsEntry = vsProgram->getEntryPointFunction(); + + // Resolve World View Projection Matrix. + UniformParameterPtr wvpMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, 0); + + // Resolve input position parameter. + ParameterPtr positionIn = vsEntry->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + + // Resolve output position parameter. + ParameterPtr positionOut = vsEntry->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); + + if (!(wvpMatrix.get()) || !(positionIn.get()) || !(positionOut.get())) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "FFPTransform::createCpuSubPrograms" ); + } + + // Add dependency. + vsProgram->addDependency(FFP_LIB_TRANSFORM); + + FunctionInvocation* transformFunc = OGRE_NEW FunctionInvocation(FFP_FUNC_TRANSFORM, FFP_VS_TRANSFORM, 0); + + transformFunc->pushOperand(wvpMatrix, Operand::OPS_IN); + transformFunc->pushOperand(positionIn, Operand::OPS_IN); + transformFunc->pushOperand(positionOut, Operand::OPS_OUT); + + vsEntry->addAtomInstance(transformFunc); + + return true; } @@ -99,47 +99,47 @@ void FFPTransform::copyFrom(const SubRenderState& rhs) //----------------------------------------------------------------------- const String& FFPTransformFactory::getType() const { - return FFPTransform::Type; + return FFPTransform::Type; } //----------------------------------------------------------------------- -SubRenderState* FFPTransformFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* FFPTransformFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "transform_stage") - { - if(prop->values.size() == 1) - { - String modelType; - - if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - return NULL; - } - - if (modelType == "ffp") - { - return createOrRetrieveInstance(translator); - } - } - } - - return NULL; + if (prop->name == "transform_stage") + { + if(prop->values.size() == 1) + { + String modelType; + + if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + return NULL; + } + + if (modelType == "ffp") + { + return createOrRetrieveInstance(translator); + } + } + } + + return NULL; } //----------------------------------------------------------------------- void FFPTransformFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + Pass* srcPass, Pass* dstPass) { - ser->writeAttribute(4, "transform_stage"); - ser->writeValue("ffp"); + ser->writeAttribute(4, "transform_stage"); + ser->writeValue("ffp"); } //----------------------------------------------------------------------- -SubRenderState* FFPTransformFactory::createInstanceImpl() +SubRenderState* FFPTransformFactory::createInstanceImpl() { - return OGRE_NEW FFPTransform; + return OGRE_NEW FFPTransform; } diff --git a/Components/RTShaderSystem/src/OgreShaderFunction.cpp b/Components/RTShaderSystem/src/OgreShaderFunction.cpp index 37cbc2d029b..26f393ad055 100644 --- a/Components/RTShaderSystem/src/OgreShaderFunction.cpp +++ b/Components/RTShaderSystem/src/OgreShaderFunction.cpp @@ -33,475 +33,475 @@ namespace RTShader { //----------------------------------------------------------------------------- Function::Function(const String& name, const String& desc, const FunctionType functionType) { - mName = name; - mDescription = desc; - mFunctionType = functionType; + mName = name; + mDescription = desc; + mFunctionType = functionType; } //----------------------------------------------------------------------------- Function::~Function() { - for (FunctionAtomInstanceIterator it=mAtomInstances.begin(); it != mAtomInstances.end(); ++it) - OGRE_DELETE (*it); - mAtomInstances.clear(); + for (FunctionAtomInstanceIterator it=mAtomInstances.begin(); it != mAtomInstances.end(); ++it) + OGRE_DELETE (*it); + mAtomInstances.clear(); - for (ShaderParameterIterator it = mInputParameters.begin(); it != mInputParameters.end(); ++it) - (*it).setNull(); - mInputParameters.clear(); + for (ShaderParameterIterator it = mInputParameters.begin(); it != mInputParameters.end(); ++it) + (*it).setNull(); + mInputParameters.clear(); - for (ShaderParameterIterator it = mOutputParameters.begin(); it != mOutputParameters.end(); ++it) - (*it).setNull(); - mOutputParameters.clear(); + for (ShaderParameterIterator it = mOutputParameters.begin(); it != mOutputParameters.end(); ++it) + (*it).setNull(); + mOutputParameters.clear(); - for (ShaderParameterIterator it = mLocalParameters.begin(); it != mLocalParameters.end(); ++it) - (*it).setNull(); - mLocalParameters.clear(); + for (ShaderParameterIterator it = mLocalParameters.begin(); it != mLocalParameters.end(); ++it) + (*it).setNull(); + mLocalParameters.clear(); } //----------------------------------------------------------------------------- ParameterPtr Function::resolveInputParameter(Parameter::Semantic semantic, - int index, - const Parameter::Content content, - GpuConstantType type) + int index, + const Parameter::Content content, + GpuConstantType type) { - ParameterPtr param; - - // Check if desired parameter already defined. - param = getParameterByContent(mInputParameters, content, type); - if (param.get() != NULL) - return param; - - // Case we have to create new parameter. - if (index == -1) - { - index = 0; - - // Find the next available index of the target semantic. - ShaderParameterIterator it; - - for (it = mInputParameters.begin(); it != mInputParameters.end(); ++it) - { - if ((*it)->getSemantic() == semantic) - { - index++; - } - } - } - else - { - // Check if desired parameter already defined. - param = getParameterBySemantic(mInputParameters, semantic, index); - if (param.get() != NULL && param->getContent() == content) - { - if (param->getType() == type) - { - return param; - } - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " due to type mismatch. Function <" + getName() + ">", - "Function::resolveInputParameter" ); - } - } - } - - - - // No parameter found -> create new one. - switch (semantic) - { - case Parameter::SPS_POSITION: - assert(type == GCT_FLOAT4); - param = ParameterFactory::createInPosition(index); - break; - - case Parameter::SPS_BLEND_WEIGHTS: - assert(type == GCT_FLOAT4); - param = ParameterFactory::createInWeights(index); - break; - - case Parameter::SPS_BLEND_INDICES: - assert(type == GCT_FLOAT4); - param = ParameterFactory::createInIndices(index); - break; - - case Parameter::SPS_NORMAL: - assert(type == GCT_FLOAT3); - param = ParameterFactory::createInNormal(index); - break; - - case Parameter::SPS_COLOR: - assert(type == GCT_FLOAT4); - param = ParameterFactory::createInColor(index); - break; - - case Parameter::SPS_TEXTURE_COORDINATES: - param = ParameterFactory::createInTexcoord(type, index, content); - break; - - case Parameter::SPS_BINORMAL: - assert(type == GCT_FLOAT3); - param = ParameterFactory::createInBiNormal(index); - break; - - case Parameter::SPS_TANGENT: - assert(type == GCT_FLOAT3); - param = ParameterFactory::createInTangent(index); - break; - case Parameter::SPS_UNKNOWN: + ParameterPtr param; + + // Check if desired parameter already defined. + param = getParameterByContent(mInputParameters, content, type); + if (param.get() != NULL) + return param; + + // Case we have to create new parameter. + if (index == -1) + { + index = 0; + + // Find the next available index of the target semantic. + ShaderParameterIterator it; + + for (it = mInputParameters.begin(); it != mInputParameters.end(); ++it) + { + if ((*it)->getSemantic() == semantic) + { + index++; + } + } + } + else + { + // Check if desired parameter already defined. + param = getParameterBySemantic(mInputParameters, semantic, index); + if (param.get() != NULL && param->getContent() == content) + { + if (param->getType() == type) + { + return param; + } + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " due to type mismatch. Function <" + getName() + ">", + "Function::resolveInputParameter" ); + } + } + } + + + + // No parameter found -> create new one. + switch (semantic) + { + case Parameter::SPS_POSITION: + assert(type == GCT_FLOAT4); + param = ParameterFactory::createInPosition(index); break; - } + + case Parameter::SPS_BLEND_WEIGHTS: + assert(type == GCT_FLOAT4); + param = ParameterFactory::createInWeights(index); + break; + + case Parameter::SPS_BLEND_INDICES: + assert(type == GCT_FLOAT4); + param = ParameterFactory::createInIndices(index); + break; + + case Parameter::SPS_NORMAL: + assert(type == GCT_FLOAT3); + param = ParameterFactory::createInNormal(index); + break; + + case Parameter::SPS_COLOR: + assert(type == GCT_FLOAT4); + param = ParameterFactory::createInColor(index); + break; + + case Parameter::SPS_TEXTURE_COORDINATES: + param = ParameterFactory::createInTexcoord(type, index, content); + break; + + case Parameter::SPS_BINORMAL: + assert(type == GCT_FLOAT3); + param = ParameterFactory::createInBiNormal(index); + break; + + case Parameter::SPS_TANGENT: + assert(type == GCT_FLOAT3); + param = ParameterFactory::createInTangent(index); + break; + case Parameter::SPS_UNKNOWN: + break; + } - if (param.get() != NULL) - addInputParameter(param); + if (param.get() != NULL) + addInputParameter(param); - return param; + return param; } //----------------------------------------------------------------------------- ParameterPtr Function::resolveOutputParameter(Parameter::Semantic semantic, - int index, - Parameter::Content content, - GpuConstantType type) + int index, + Parameter::Content content, + GpuConstantType type) { - ParameterPtr param; - - // Check if desired parameter already defined. - param = getParameterByContent(mOutputParameters, content, type); - if (param.get() != NULL) - return param; - - // Case we have to create new parameter. - if (index == -1) - { - index = 0; - - // Find the next available index of the target semantic. - ShaderParameterIterator it; - - for (it = mOutputParameters.begin(); it != mOutputParameters.end(); ++it) - { - if ((*it)->getSemantic() == semantic) - { - index++; - } - } - } - else - { - // Check if desired parameter already defined. - param = getParameterBySemantic(mOutputParameters, semantic, index); - if (param.get() != NULL && param->getContent() == content) - { - if (param->getType() == type) - { - return param; - } - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " due to type mismatch. Function <" + getName() + ">", - "Function::resolveOutputParameter" ); - } - } - } - - - // No parameter found -> create new one. - switch (semantic) - { - case Parameter::SPS_POSITION: - assert(type == GCT_FLOAT4); - param = ParameterFactory::createOutPosition(index); - break; - - case Parameter::SPS_BLEND_WEIGHTS: - case Parameter::SPS_BLEND_INDICES: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " since support in it is not implemented yet. Function <" + getName() + ">", - "Function::resolveOutputParameter" ); - break; - - case Parameter::SPS_NORMAL: - assert(type == GCT_FLOAT3); - param = ParameterFactory::createOutNormal(index); - break; - - case Parameter::SPS_COLOR: - assert(type == GCT_FLOAT4); - param = ParameterFactory::createOutColor(index); - break; - - case Parameter::SPS_TEXTURE_COORDINATES: - param = ParameterFactory::createOutTexcoord(type, index, content); - break; - - case Parameter::SPS_BINORMAL: - assert(type == GCT_FLOAT3); - param = ParameterFactory::createOutBiNormal(index); - break; - - case Parameter::SPS_TANGENT: - assert(type == GCT_FLOAT3); - param = ParameterFactory::createOutTangent(index); - break; - case Parameter::SPS_UNKNOWN: + ParameterPtr param; + + // Check if desired parameter already defined. + param = getParameterByContent(mOutputParameters, content, type); + if (param.get() != NULL) + return param; + + // Case we have to create new parameter. + if (index == -1) + { + index = 0; + + // Find the next available index of the target semantic. + ShaderParameterIterator it; + + for (it = mOutputParameters.begin(); it != mOutputParameters.end(); ++it) + { + if ((*it)->getSemantic() == semantic) + { + index++; + } + } + } + else + { + // Check if desired parameter already defined. + param = getParameterBySemantic(mOutputParameters, semantic, index); + if (param.get() != NULL && param->getContent() == content) + { + if (param->getType() == type) + { + return param; + } + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " due to type mismatch. Function <" + getName() + ">", + "Function::resolveOutputParameter" ); + } + } + } + + + // No parameter found -> create new one. + switch (semantic) + { + case Parameter::SPS_POSITION: + assert(type == GCT_FLOAT4); + param = ParameterFactory::createOutPosition(index); + break; + + case Parameter::SPS_BLEND_WEIGHTS: + case Parameter::SPS_BLEND_INDICES: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " since support in it is not implemented yet. Function <" + getName() + ">", + "Function::resolveOutputParameter" ); + break; + + case Parameter::SPS_NORMAL: + assert(type == GCT_FLOAT3); + param = ParameterFactory::createOutNormal(index); + break; + + case Parameter::SPS_COLOR: + assert(type == GCT_FLOAT4); + param = ParameterFactory::createOutColor(index); + break; + + case Parameter::SPS_TEXTURE_COORDINATES: + param = ParameterFactory::createOutTexcoord(type, index, content); + break; + + case Parameter::SPS_BINORMAL: + assert(type == GCT_FLOAT3); + param = ParameterFactory::createOutBiNormal(index); + break; + + case Parameter::SPS_TANGENT: + assert(type == GCT_FLOAT3); + param = ParameterFactory::createOutTangent(index); + break; + case Parameter::SPS_UNKNOWN: break; - } + } - if (param.get() != NULL) - addOutputParameter(param); + if (param.get() != NULL) + addOutputParameter(param); - return param; + return param; } //----------------------------------------------------------------------------- ParameterPtr Function::resolveLocalParameter(Parameter::Semantic semantic, int index, - const String& name, - GpuConstantType type) + const String& name, + GpuConstantType type) { - ParameterPtr param; - - param = getParameterByName(mLocalParameters, name); - if (param.get() != NULL) - { - if (param->getType() == type && - param->getSemantic() == semantic && - param->getIndex() == index) - { - return param; - } - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Can not resolve local parameter due to type mismatch. Function <" + getName() + ">", - "Function::resolveLocalParameter" ); - } - } - - param = ParameterPtr(OGRE_NEW Parameter(type, name, semantic, index, Parameter::SPC_UNKNOWN)); - addParameter(mLocalParameters, param); - - return param; + ParameterPtr param; + + param = getParameterByName(mLocalParameters, name); + if (param.get() != NULL) + { + if (param->getType() == type && + param->getSemantic() == semantic && + param->getIndex() == index) + { + return param; + } + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Can not resolve local parameter due to type mismatch. Function <" + getName() + ">", + "Function::resolveLocalParameter" ); + } + } + + param = ParameterPtr(OGRE_NEW Parameter(type, name, semantic, index, Parameter::SPC_UNKNOWN)); + addParameter(mLocalParameters, param); + + return param; } //----------------------------------------------------------------------------- ParameterPtr Function::resolveLocalParameter(Parameter::Semantic semantic, int index, - const Parameter::Content content, - GpuConstantType type) + const Parameter::Content content, + GpuConstantType type) { - ParameterPtr param; + ParameterPtr param; - param = getParameterByContent(mLocalParameters, content, type); - if (param.get() != NULL) - return param; + param = getParameterByContent(mLocalParameters, content, type); + if (param.get() != NULL) + return param; - param = ParameterPtr(OGRE_NEW Parameter(type, "lLocalParam_" + StringConverter::toString(mLocalParameters.size()), semantic, index, content)); - addParameter(mLocalParameters, param); + param = ParameterPtr(OGRE_NEW Parameter(type, "lLocalParam_" + StringConverter::toString(mLocalParameters.size()), semantic, index, content)); + addParameter(mLocalParameters, param); - return param; + return param; } //----------------------------------------------------------------------------- void Function::addInputParameter(ParameterPtr parameter) { - // Check that parameter with the same semantic and index in input parameters list. - if (getParameterBySemantic(mInputParameters, parameter->getSemantic(), parameter->getIndex()).get() != NULL) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Parameter <" + parameter->getName() + "> has equal sematic parameter in function <" + getName() + ">", - "Function::addInputParameter" ); - } + // Check that parameter with the same semantic and index in input parameters list. + if (getParameterBySemantic(mInputParameters, parameter->getSemantic(), parameter->getIndex()).get() != NULL) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Parameter <" + parameter->getName() + "> has equal sematic parameter in function <" + getName() + ">", + "Function::addInputParameter" ); + } - addParameter(mInputParameters, parameter); + addParameter(mInputParameters, parameter); } //----------------------------------------------------------------------------- void Function::addOutputParameter(ParameterPtr parameter) { - // Check that parameter with the same semantic and index in output parameters list. - if (getParameterBySemantic(mOutputParameters, parameter->getSemantic(), parameter->getIndex()).get() != NULL) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Parameter <" + parameter->getName() + "> has equal sematic parameter in function <" + getName() + ">", - "Function::addOutputParameter" ); - } - - addParameter(mOutputParameters, parameter); + // Check that parameter with the same semantic and index in output parameters list. + if (getParameterBySemantic(mOutputParameters, parameter->getSemantic(), parameter->getIndex()).get() != NULL) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Parameter <" + parameter->getName() + "> has equal sematic parameter in function <" + getName() + ">", + "Function::addOutputParameter" ); + } + + addParameter(mOutputParameters, parameter); } //----------------------------------------------------------------------------- void Function::deleteInputParameter(ParameterPtr parameter) { - deleteParameter(mInputParameters, parameter); + deleteParameter(mInputParameters, parameter); } //----------------------------------------------------------------------------- void Function::deleteOutputParameter(ParameterPtr parameter) { - deleteParameter(mOutputParameters, parameter); + deleteParameter(mOutputParameters, parameter); } //----------------------------------------------------------------------------- void Function::deleteAllInputParameters() { - mInputParameters.clear(); + mInputParameters.clear(); } //----------------------------------------------------------------------------- void Function::deleteAllOutputParameters() { - mOutputParameters.clear(); + mOutputParameters.clear(); } //----------------------------------------------------------------------------- void Function::addParameter(ShaderParameterList& parameterList, ParameterPtr parameter) - + { - // Check that parameter with the same name doest exist in input parameters list. - if (getParameterByName(mInputParameters, parameter->getName()).get() != NULL) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Parameter <" + parameter->getName() + "> already declared in function <" + getName() + ">", - "Function::addParameter" ); - } - - // Check that parameter with the same name doest exist in output parameters list. - if (getParameterByName(mOutputParameters, parameter->getName()).get() != NULL) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Parameter <" + parameter->getName() + "> already declared in function <" + getName() + ">", - "Function::addParameter" ); - } - - - // Add to given parameters list. - parameterList.push_back(parameter); + // Check that parameter with the same name doest exist in input parameters list. + if (getParameterByName(mInputParameters, parameter->getName()).get() != NULL) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Parameter <" + parameter->getName() + "> already declared in function <" + getName() + ">", + "Function::addParameter" ); + } + + // Check that parameter with the same name doest exist in output parameters list. + if (getParameterByName(mOutputParameters, parameter->getName()).get() != NULL) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Parameter <" + parameter->getName() + "> already declared in function <" + getName() + ">", + "Function::addParameter" ); + } + + + // Add to given parameters list. + parameterList.push_back(parameter); } //----------------------------------------------------------------------------- void Function::deleteParameter(ShaderParameterList& parameterList, ParameterPtr parameter) { - ShaderParameterIterator it; - - for (it = parameterList.begin(); it != parameterList.end(); ++it) - { - if (*it == parameter) - { - (*it).setNull(); - parameterList.erase(it); - break; - } - } + ShaderParameterIterator it; + + for (it = parameterList.begin(); it != parameterList.end(); ++it) + { + if (*it == parameter) + { + (*it).setNull(); + parameterList.erase(it); + break; + } + } } //----------------------------------------------------------------------------- ParameterPtr Function::getParameterByName( const ShaderParameterList& parameterList, const String& name ) { - ShaderParameterConstIterator it; + ShaderParameterConstIterator it; - for (it = parameterList.begin(); it != parameterList.end(); ++it) - { - if ((*it)->getName() == name) - { - return *it; - } - } + for (it = parameterList.begin(); it != parameterList.end(); ++it) + { + if ((*it)->getName() == name) + { + return *it; + } + } - return ParameterPtr(); + return ParameterPtr(); } //----------------------------------------------------------------------------- ParameterPtr Function::getParameterBySemantic(const ShaderParameterList& parameterList, - const Parameter::Semantic semantic, - int index) + const Parameter::Semantic semantic, + int index) { - ShaderParameterConstIterator it; - - for (it = parameterList.begin(); it != parameterList.end(); ++it) - { - if ((*it)->getSemantic() == semantic && - (*it)->getIndex() == index) - { - return *it; - } - } - - return ParameterPtr(); + ShaderParameterConstIterator it; + + for (it = parameterList.begin(); it != parameterList.end(); ++it) + { + if ((*it)->getSemantic() == semantic && + (*it)->getIndex() == index) + { + return *it; + } + } + + return ParameterPtr(); } //----------------------------------------------------------------------------- ParameterPtr Function::getParameterByContent(const ShaderParameterList& parameterList, const Parameter::Content content, GpuConstantType type) { - ShaderParameterConstIterator it; - - // Search only for known content. - if (content != Parameter::SPC_UNKNOWN) - { - for (it = parameterList.begin(); it != parameterList.end(); ++it) - { - if ((*it)->getContent() == content && - (*it)->getType() == type) - { - return *it; - } - } - } - - return ParameterPtr(); + ShaderParameterConstIterator it; + + // Search only for known content. + if (content != Parameter::SPC_UNKNOWN) + { + for (it = parameterList.begin(); it != parameterList.end(); ++it) + { + if ((*it)->getContent() == content && + (*it)->getType() == type) + { + return *it; + } + } + } + + return ParameterPtr(); } //----------------------------------------------------------------------------- void Function::addAtomInstance(FunctionAtom* atomInstance) { - mAtomInstances.push_back(atomInstance); + mAtomInstances.push_back(atomInstance); } //----------------------------------------------------------------------------- bool Function::deleteAtomInstance(FunctionAtom* atomInstance) { - FunctionAtomInstanceIterator it; - - for (it=mAtomInstances.begin(); it != mAtomInstances.end(); ++it) - { - if (*it == atomInstance) - { - OGRE_DELETE atomInstance; - mAtomInstances.erase(it); - return true; - } - } - - return false; - + FunctionAtomInstanceIterator it; + + for (it=mAtomInstances.begin(); it != mAtomInstances.end(); ++it) + { + if (*it == atomInstance) + { + OGRE_DELETE atomInstance; + mAtomInstances.erase(it); + return true; + } + } + + return false; + } namespace { - struct CmpAtomInstance { - bool operator()(const FunctionAtom* a, const FunctionAtom* b) const - { - if (a->getGroupExecutionOrder() < b->getGroupExecutionOrder()) - return true; - if (b->getGroupExecutionOrder() < a->getGroupExecutionOrder()) - return false; - return a->getInternalExecutionOrder() < b->getInternalExecutionOrder(); - } - }; + struct CmpAtomInstance { + bool operator()(const FunctionAtom* a, const FunctionAtom* b) const + { + if (a->getGroupExecutionOrder() < b->getGroupExecutionOrder()) + return true; + if (b->getGroupExecutionOrder() < a->getGroupExecutionOrder()) + return false; + return a->getInternalExecutionOrder() < b->getInternalExecutionOrder(); + } + }; } //----------------------------------------------------------------------------- void Function::sortAtomInstances() { - std::sort(mAtomInstances.begin(), mAtomInstances.end(), CmpAtomInstance()); + std::sort(mAtomInstances.begin(), mAtomInstances.end(), CmpAtomInstance()); } //----------------------------------------------------------------------------- Ogre::RTShader::Function::FunctionType Function::getFunctionType() const { - return mFunctionType; + return mFunctionType; } } diff --git a/Components/RTShaderSystem/src/OgreShaderFunctionAtom.cpp b/Components/RTShaderSystem/src/OgreShaderFunctionAtom.cpp index de7847c56cd..c9dfd534a12 100644 --- a/Components/RTShaderSystem/src/OgreShaderFunctionAtom.cpp +++ b/Components/RTShaderSystem/src/OgreShaderFunctionAtom.cpp @@ -38,138 +38,138 @@ Operand::Operand(ParameterPtr parameter, Operand::OpSemantic opSemantic, int opM //----------------------------------------------------------------------------- Operand::Operand(const Operand& other) { - *this = other; + *this = other; } //----------------------------------------------------------------------------- Operand& Operand::operator= (const Operand & other) { - if (this != &other) - { - mParameter = other.mParameter; - mSemantic = other.mSemantic; - mMask = other.mMask; - mIndirectionLevel = other.mIndirectionLevel; - } - return *this; + if (this != &other) + { + mParameter = other.mParameter; + mSemantic = other.mSemantic; + mMask = other.mMask; + mIndirectionLevel = other.mIndirectionLevel; + } + return *this; } //----------------------------------------------------------------------------- Operand::~Operand() { - // nothing todo + // nothing todo } //----------------------------------------------------------------------------- String Operand::getMaskAsString(int mask) { - String retVal = ""; - - if (mask & ~OPM_ALL) - { - if (mask & OPM_X) - { - retVal += "x"; - } - - if (mask & OPM_Y) - { - retVal += "y"; - } - - if (mask & OPM_Z) - { - retVal += "z"; - } - - if (mask & OPM_W) - { - retVal += "w"; - } - } - - return retVal; + String retVal = ""; + + if (mask & ~OPM_ALL) + { + if (mask & OPM_X) + { + retVal += "x"; + } + + if (mask & OPM_Y) + { + retVal += "y"; + } + + if (mask & OPM_Z) + { + retVal += "z"; + } + + if (mask & OPM_W) + { + retVal += "w"; + } + } + + return retVal; } //----------------------------------------------------------------------------- int Operand::getFloatCount(int mask) { - int floatCount = 0; + int floatCount = 0; - while (mask != 0) - { - if ((mask & Operand::OPM_X) != 0) - { - floatCount++; + while (mask != 0) + { + if ((mask & Operand::OPM_X) != 0) + { + floatCount++; - } - mask = mask >> 1; - } + } + mask = mask >> 1; + } - return floatCount; + return floatCount; } //----------------------------------------------------------------------------- -GpuConstantType Operand::getGpuConstantType(int mask) +GpuConstantType Operand::getGpuConstantType(int mask) { - int floatCount = getFloatCount(mask); - GpuConstantType type; + int floatCount = getFloatCount(mask); + GpuConstantType type; - switch (floatCount) - { + switch (floatCount) + { - case 1: - type = GCT_FLOAT1; - break; + case 1: + type = GCT_FLOAT1; + break; - case 2: - type = GCT_FLOAT2; - break; + case 2: + type = GCT_FLOAT2; + break; - case 3: - type = GCT_FLOAT3; - break; + case 3: + type = GCT_FLOAT3; + break; - case 4: - type = GCT_FLOAT4; - break; + case 4: + type = GCT_FLOAT4; + break; - default: - type = GCT_UNKNOWN; - break; - } + default: + type = GCT_UNKNOWN; + break; + } - return type; + return type; } //----------------------------------------------------------------------------- String Operand::toString() const { - String retVal = mParameter->toString(); - if ((mMask & OPM_ALL) || ((mMask & OPM_X) && (mMask & OPM_Y) && (mMask & OPM_Z) && (mMask & OPM_W))) - { - return retVal; - } + String retVal = mParameter->toString(); + if ((mMask & OPM_ALL) || ((mMask & OPM_X) && (mMask & OPM_Y) && (mMask & OPM_Z) && (mMask & OPM_W))) + { + return retVal; + } - retVal += "." + getMaskAsString(mMask); + retVal += "." + getMaskAsString(mMask); - return retVal; + return retVal; } //----------------------------------------------------------------------------- FunctionAtom::FunctionAtom() { - mGroupExecutionOrder = -1; - mInternalExecutionOrder = -1; + mGroupExecutionOrder = -1; + mInternalExecutionOrder = -1; } //----------------------------------------------------------------------------- int FunctionAtom::getGroupExecutionOrder() const { - return mGroupExecutionOrder; + return mGroupExecutionOrder; } //----------------------------------------------------------------------------- -int FunctionAtom::getInternalExecutionOrder() const +int FunctionAtom::getInternalExecutionOrder() const { - return mInternalExecutionOrder; + return mInternalExecutionOrder; } @@ -177,19 +177,19 @@ String FunctionInvocation::Type = "FunctionInvocation"; //----------------------------------------------------------------------- FunctionInvocation::FunctionInvocation(const String& functionName, - int groupOrder, int internalOrder, String returnType) : + int groupOrder, int internalOrder, String returnType) : mFunctionName(functionName), mReturnType(returnType) { - mGroupExecutionOrder = groupOrder; - mInternalExecutionOrder = internalOrder; + mGroupExecutionOrder = groupOrder; + mInternalExecutionOrder = internalOrder; } //----------------------------------------------------------------------------- FunctionInvocation::FunctionInvocation(const FunctionInvocation& other) : mFunctionName(other.mFunctionName), mReturnType(other.mReturnType) { - mGroupExecutionOrder = other.mGroupExecutionOrder; - mInternalExecutionOrder = other.mInternalExecutionOrder; + mGroupExecutionOrder = other.mGroupExecutionOrder; + mInternalExecutionOrder = other.mInternalExecutionOrder; for ( OperandVector::const_iterator it = other.mOperands.begin(); it != other.mOperands.end(); ++it) mOperands.push_back(Operand(*it)); @@ -198,56 +198,56 @@ FunctionInvocation::FunctionInvocation(const FunctionInvocation& other) : //----------------------------------------------------------------------- void FunctionInvocation::writeSourceCode(std::ostream& os, const String& targetLanguage) const { - // Write function name. - os << mFunctionName << "("; - - // Write parameters. - ushort curIndLevel = 0; - for (OperandVector::const_iterator it = mOperands.begin(); it != mOperands.end(); ) - { - os << (*it).toString(); - ++it; - - ushort opIndLevel = 0; - if (it != mOperands.end()) - { - opIndLevel = (*it).getIndirectionLevel(); - } - - if (curIndLevel < opIndLevel) - { - while (curIndLevel < opIndLevel) - { - ++curIndLevel; - os << "["; - } - } - else //if (curIndLevel >= opIndLevel) - { - while (curIndLevel > opIndLevel) - { - --curIndLevel; - os << "]"; - } - if (opIndLevel != 0) - { - os << "]["; - } - else if (it != mOperands.end()) - { - os << ", "; - } - } - } - - // Write function call closer. - os << ");"; + // Write function name. + os << mFunctionName << "("; + + // Write parameters. + ushort curIndLevel = 0; + for (OperandVector::const_iterator it = mOperands.begin(); it != mOperands.end(); ) + { + os << (*it).toString(); + ++it; + + ushort opIndLevel = 0; + if (it != mOperands.end()) + { + opIndLevel = (*it).getIndirectionLevel(); + } + + if (curIndLevel < opIndLevel) + { + while (curIndLevel < opIndLevel) + { + ++curIndLevel; + os << "["; + } + } + else //if (curIndLevel >= opIndLevel) + { + while (curIndLevel > opIndLevel) + { + --curIndLevel; + os << "]"; + } + if (opIndLevel != 0) + { + os << "]["; + } + else if (it != mOperands.end()) + { + os << ", "; + } + } + } + + // Write function call closer. + os << ");"; } //----------------------------------------------------------------------- void FunctionInvocation::pushOperand(ParameterPtr parameter, Operand::OpSemantic opSemantic, int opMask, int indirectionLevel) { - mOperands.push_back(Operand(parameter, opSemantic, opMask, indirectionLevel)); + mOperands.push_back(Operand(parameter, opSemantic, opMask, indirectionLevel)); } //----------------------------------------------------------------------- diff --git a/Components/RTShaderSystem/src/OgreShaderGLSLESProgramProcessor.cpp b/Components/RTShaderSystem/src/OgreShaderGLSLESProgramProcessor.cpp index a85a2a60ff1..ca8d21e5544 100644 --- a/Components/RTShaderSystem/src/OgreShaderGLSLESProgramProcessor.cpp +++ b/Components/RTShaderSystem/src/OgreShaderGLSLESProgramProcessor.cpp @@ -44,81 +44,81 @@ GLSLESProgramProcessor::GLSLESProgramProcessor() //----------------------------------------------------------------------------- GLSLESProgramProcessor::~GLSLESProgramProcessor() { - StringVector::iterator it = mLibraryPrograms.begin(); - StringVector::iterator itEnd = mLibraryPrograms.end(); - - for (; it != itEnd; ++it) - { - HighLevelGpuProgramManager::getSingleton().remove(*it); - } - mLibraryPrograms.clear(); + StringVector::iterator it = mLibraryPrograms.begin(); + StringVector::iterator itEnd = mLibraryPrograms.end(); + + for (; it != itEnd; ++it) + { + HighLevelGpuProgramManager::getSingleton().remove(*it); + } + mLibraryPrograms.clear(); } //----------------------------------------------------------------------------- bool GLSLESProgramProcessor::preCreateGpuPrograms(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* fsProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* fsMain = fsProgram->getEntryPointFunction(); - bool success; - - // Compact vertex shader outputs. - success = ProgramProcessor::compactVsOutputs(vsMain, fsMain); - if (success == false) - return false; - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* fsProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* fsMain = fsProgram->getEntryPointFunction(); + bool success; + + // Compact vertex shader outputs. + success = ProgramProcessor::compactVsOutputs(vsMain, fsMain); + if (success == false) + return false; + + return true; } //----------------------------------------------------------------------------- bool GLSLESProgramProcessor::postCreateGpuPrograms(ProgramSet* programSet) { - Program* vsCpuProgram = programSet->getCpuVertexProgram(); - Program* fsCpuProgram = programSet->getCpuFragmentProgram(); - GpuProgramPtr vsGpuProgram = programSet->getGpuVertexProgram(); - GpuProgramPtr fsGpuProgram = programSet->getGpuFragmentProgram(); + Program* vsCpuProgram = programSet->getCpuVertexProgram(); + Program* fsCpuProgram = programSet->getCpuFragmentProgram(); + GpuProgramPtr vsGpuProgram = programSet->getGpuVertexProgram(); + GpuProgramPtr fsGpuProgram = programSet->getGpuFragmentProgram(); - // Bind vertex shader auto parameters. - bindAutoParameters(programSet->getCpuVertexProgram(), programSet->getGpuVertexProgram()); + // Bind vertex shader auto parameters. + bindAutoParameters(programSet->getCpuVertexProgram(), programSet->getGpuVertexProgram()); - // Bind fragment shader auto parameters. - bindAutoParameters(programSet->getCpuFragmentProgram(), programSet->getGpuFragmentProgram()); + // Bind fragment shader auto parameters. + bindAutoParameters(programSet->getCpuFragmentProgram(), programSet->getGpuFragmentProgram()); - // Bind texture samplers for the vertex shader. - bindTextureSamplers(vsCpuProgram, vsGpuProgram); + // Bind texture samplers for the vertex shader. + bindTextureSamplers(vsCpuProgram, vsGpuProgram); - // Bind texture samplers for the fragment shader. - bindTextureSamplers(fsCpuProgram, fsGpuProgram); + // Bind texture samplers for the fragment shader. + bindTextureSamplers(fsCpuProgram, fsGpuProgram); #if !OGRE_NO_GLES2_GLSL_OPTIMISER - vsGpuProgram->setParameter("use_optimiser", "true"); - fsGpuProgram->setParameter("use_optimiser", "true"); + vsGpuProgram->setParameter("use_optimiser", "true"); + fsGpuProgram->setParameter("use_optimiser", "true"); #endif - return true; + return true; } //----------------------------------------------------------------------------- void GLSLESProgramProcessor::bindTextureSamplers(Program* pCpuProgram, GpuProgramPtr pGpuProgram) { - GpuProgramParametersSharedPtr pGpuParams = pGpuProgram->getDefaultParameters(); - const UniformParameterList& progParams = pCpuProgram->getParameters(); - UniformParameterConstIterator itParams; - - // Bind the samplers. - for (itParams = progParams.begin(); itParams != progParams.end(); ++itParams) - { - const UniformParameterPtr pCurParam = *itParams; - - if (pCurParam->isSampler()) - { + GpuProgramParametersSharedPtr pGpuParams = pGpuProgram->getDefaultParameters(); + const UniformParameterList& progParams = pCpuProgram->getParameters(); + UniformParameterConstIterator itParams; + + // Bind the samplers. + for (itParams = progParams.begin(); itParams != progParams.end(); ++itParams) + { + const UniformParameterPtr pCurParam = *itParams; + + if (pCurParam->isSampler()) + { // The optimizer may remove some unnecessary parameters, so we should ignore them pGpuParams->setIgnoreMissingParams(true); pGpuParams->setNamedConstant(pCurParam->getName(), pCurParam->getIndex()); - } - } + } + } } } diff --git a/Components/RTShaderSystem/src/OgreShaderGLSLESProgramWriter.cpp b/Components/RTShaderSystem/src/OgreShaderGLSLESProgramWriter.cpp index 775fe7b5f15..610e238a050 100644 --- a/Components/RTShaderSystem/src/OgreShaderGLSLESProgramWriter.cpp +++ b/Components/RTShaderSystem/src/OgreShaderGLSLESProgramWriter.cpp @@ -93,9 +93,9 @@ namespace Ogre { // 3. The name if(paramTokens.size() == 3) { - StringUtil::trim(paramTokens[0]); - StringUtil::trim(paramTokens[1]); - StringUtil::trim(paramTokens[2]); + StringUtil::trim(paramTokens[0]); + StringUtil::trim(paramTokens[1]); + StringUtil::trim(paramTokens[2]); Operand::OpSemantic semantic = Operand::OPS_IN; GpuConstantType gpuType = GCT_UNKNOWN; @@ -129,7 +129,7 @@ namespace Ogre { { OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can not convert Operand::OpMask to GpuConstantType", - "GLSLESProgramWriter::createInvocationFromString" ); + "GLSLESProgramWriter::createInvocationFromString" ); } if(gpuType == GCT_SAMPLER1D) @@ -173,25 +173,25 @@ namespace Ogre { { StringVector moreTokens = StringUtil::split(*it, " "); - if (!moreTokens.empty()) - { + if (!moreTokens.empty()) + { FunctionMap::const_iterator itFuncCache = mFunctionCacheMap.begin(); - for (; itFuncCache != mFunctionCacheMap.end(); ++itFuncCache) - { - - FunctionInvocation fi = itFuncCache->first; - - if(fi.getFunctionName() == moreTokens.back()) - { - // Add the function declaration - depVector.push_back(FunctionInvocation((*itFuncCache).first)); - - discoverFunctionDependencies(itFuncCache->first, depVector); - } - } - } - } + for (; itFuncCache != mFunctionCacheMap.end(); ++itFuncCache) + { + + FunctionInvocation fi = itFuncCache->first; + + if(fi.getFunctionName() == moreTokens.back()) + { + // Add the function declaration + depVector.push_back(FunctionInvocation((*itFuncCache).first)); + + discoverFunctionDependencies(itFuncCache->first, depVector); + } + } + } + } } else @@ -211,7 +211,7 @@ namespace Ogre { mGpuConstTypeMap[GCT_SAMPLER1D] = "sampler2D"; mGpuConstTypeMap[GCT_SAMPLER2D] = "sampler2D"; mGpuConstTypeMap[GCT_SAMPLER3D] = "sampler3D"; - mGpuConstTypeMap[GCT_SAMPLER2DARRAY] = "sampler2DArray"; + mGpuConstTypeMap[GCT_SAMPLER2DARRAY] = "sampler2DArray"; mGpuConstTypeMap[GCT_SAMPLERCUBE] = "samplerCube"; mGpuConstTypeMap[GCT_SAMPLER1DSHADOW] = "sampler1DShadow"; mGpuConstTypeMap[GCT_SAMPLER2DSHADOW] = "sampler2DShadow"; @@ -228,10 +228,10 @@ namespace Ogre { mGpuConstTypeMap[GCT_INT2] = "int2"; mGpuConstTypeMap[GCT_INT3] = "int3"; mGpuConstTypeMap[GCT_INT4] = "int4"; - mGpuConstTypeMap[GCT_UINT1] = "uint"; - mGpuConstTypeMap[GCT_UINT2] = "uint2"; - mGpuConstTypeMap[GCT_UINT3] = "uint3"; - mGpuConstTypeMap[GCT_UINT4] = "uint4"; + mGpuConstTypeMap[GCT_UINT1] = "uint"; + mGpuConstTypeMap[GCT_UINT2] = "uint2"; + mGpuConstTypeMap[GCT_UINT3] = "uint3"; + mGpuConstTypeMap[GCT_UINT4] = "uint4"; // Custom vertex attributes defined http://www.ogre3d.org/docs/manual/manual_21.html mContentToPerVertexAttributes[Parameter::SPC_POSITION_OBJECT_SPACE] = "vertex"; @@ -253,15 +253,15 @@ namespace Ogre { //----------------------------------------------------------------------- void GLSLESProgramWriter::writeSourceCode( - std::ostream& os, - Program* program) + std::ostream& os, + Program* program) { GpuProgramType gpuType = program->getType(); if(gpuType == GPT_GEOMETRY_PROGRAM) { OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, "Geometry Programs not supported in GLSL ES writer ", - "GLSLESProgramWriter::writeSourceCode" ); + "GLSLESProgramWriter::writeSourceCode" ); } // Clear out old input params @@ -315,13 +315,13 @@ namespace Ogre { os << mGpuConstTypeMap[pUniformParam->getType()]; os << "\t"; os << pUniformParam->getName(); - if (pUniformParam->isArray() == true) - { - os << "[" << pUniformParam->getSize() << "]"; - } + if (pUniformParam->isArray() == true) + { + os << "[" << pUniformParam->getSize() << "]"; + } os << ";" << std::endl; } - os << std::endl; + os << std::endl; // Write program function(s). for (itFunction = functionList.begin(); itFunction != functionList.end(); ++itFunction) @@ -340,14 +340,14 @@ namespace Ogre { // The function name must always main. os << "void main() {" << std::endl; - if (gpuType == GPT_FRAGMENT_PROGRAM) - { - os << "\tvec4 outputColor;" << std::endl; - } - else if (gpuType == GPT_VERTEX_PROGRAM) - { - os << "\tvec4 outputPosition;" << std::endl; - } + if (gpuType == GPT_FRAGMENT_PROGRAM) + { + os << "\tvec4 outputColor;" << std::endl; + } + else if (gpuType == GPT_VERTEX_PROGRAM) + { + os << "\tvec4 outputPosition;" << std::endl; + } // Write local parameters. const ShaderParameterList& localParams = curFunction->getLocalParameters(); @@ -357,10 +357,10 @@ namespace Ogre { for (; itParam != itParamEnd; ++itParam) { os << "\t"; - writeLocalParameter(os, *itParam); - os << ";" << std::endl; + writeLocalParameter(os, *itParam); + os << ";" << std::endl; } - os << std::endl; + os << std::endl; // Sort function atoms. curFunction->sortAtomInstances(); @@ -370,7 +370,7 @@ namespace Ogre { FunctionAtomInstanceConstIterator itAtomEnd = atomInstances.end(); for (; itAtom != itAtomEnd; ++itAtom) - { + { FunctionInvocation* pFuncInvoc = (FunctionInvocation*)*itAtom; FunctionInvocation::OperandVector::iterator itOperand = pFuncInvoc->getOperandList().begin(); FunctionInvocation::OperandVector::const_iterator itOperandEnd = pFuncInvoc->getOperandList().end(); @@ -378,10 +378,10 @@ namespace Ogre { // Local string stream StringStream localOs; - // Write function name + // Write function name localOs << "\t" << pFuncInvoc->getFunctionName() << "("; - int curIndLevel = 0; + int curIndLevel = 0; for (; itOperand != itOperandEnd; ) { Operand op = *itOperand; @@ -391,16 +391,16 @@ namespace Ogre { // Check if we write to a varying because the are only readable in fragment programs if (opSemantic == Operand::OPS_OUT || opSemantic == Operand::OPS_INOUT) - { + { // Is the written parameter a varying bool isVarying = false; // Check if we write to a varying because the are only readable in fragment programs if (gpuType == GPT_FRAGMENT_PROGRAM) - { - StringVector::iterator itFound = std::find(mFragInputParams.begin(), mFragInputParams.end(), paramName); + { + StringVector::iterator itFound = std::find(mFragInputParams.begin(), mFragInputParams.end(), paramName); if(itFound != mFragInputParams.end()) - { + { // Declare the copy variable String newVar = "local_" + paramName; String tempVar = paramName; @@ -411,7 +411,7 @@ namespace Ogre { tempVar.replace(tempVar.begin(), tempVar.begin() + 1, "o"); // Declare the copy variable and assign the original - os << "\t" << mGpuConstTypeMap[op.getParameter()->getType()] << " " << newVar << " = " << tempVar << ";\n" << std::endl; + os << "\t" << mGpuConstTypeMap[op.getParameter()->getType()] << " " << newVar << " = " << tempVar << ";\n" << std::endl; // From now on we replace it automatic mInputToGLStatesMap[paramName] = newVar; @@ -427,7 +427,7 @@ namespace Ogre { { UniformParameterList::const_iterator itFound = std::find_if( parameterList.begin(), parameterList.end(), std::bind2nd( CompareUniformByName(), paramName ) ); if(itFound != parameterList.end()) - { + { // Declare the copy variable String newVar = "local_" + paramName; @@ -435,7 +435,7 @@ namespace Ogre { if(mInputToGLStatesMap.find(newVar) == mInputToGLStatesMap.end()) { // Declare the copy variable and assign the original - os << "\t" << mGpuConstTypeMap[itFound->get()->getType()] << " " << newVar << " = " << paramName << ";\n" << std::endl; + os << "\t" << mGpuConstTypeMap[itFound->get()->getType()] << " " << newVar << " = " << paramName << ";\n" << std::endl; // From now on we replace it automatic mInputToGLStatesMap[paramName] = newVar; @@ -456,7 +456,7 @@ namespace Ogre { if(mask != Operand::OPM_ALL) { newParam += "." + Operand::getMaskAsString(mask); - } + } // Now that every texcoord is a vec4 (passed as vertex attributes) we // have to swizzle them according the desired type. else if(gpuType == GPT_VERTEX_PROGRAM && @@ -489,7 +489,7 @@ namespace Ogre { default: break; } - } + } } else { @@ -501,46 +501,46 @@ namespace Ogre { // Prepare for the next operand localOs << newParam; - // Prepare for the next operand - ushort opIndLevel = 0; - if (itOperand != itOperandEnd) - { - opIndLevel = itOperand->getIndirectionLevel(); - } - - if (curIndLevel != 0) - { - localOs << ")"; - } - - if (curIndLevel < opIndLevel) - { - while (curIndLevel < opIndLevel) - { - ++curIndLevel; - localOs << "["; - } - } - else //if (curIndLevel >= opIndLevel) - { - while (curIndLevel > opIndLevel) - { - --curIndLevel; - localOs << "]"; - } - if (opIndLevel != 0) - { - localOs << "]["; - } - else if (itOperand != itOperandEnd) - { - localOs << ", "; - } - } - if (curIndLevel != 0) - { - localOs << "int("; - } + // Prepare for the next operand + ushort opIndLevel = 0; + if (itOperand != itOperandEnd) + { + opIndLevel = itOperand->getIndirectionLevel(); + } + + if (curIndLevel != 0) + { + localOs << ")"; + } + + if (curIndLevel < opIndLevel) + { + while (curIndLevel < opIndLevel) + { + ++curIndLevel; + localOs << "["; + } + } + else //if (curIndLevel >= opIndLevel) + { + while (curIndLevel > opIndLevel) + { + --curIndLevel; + localOs << "]"; + } + if (opIndLevel != 0) + { + localOs << "]["; + } + else if (itOperand != itOperandEnd) + { + localOs << ", "; + } + } + if (curIndLevel != 0) + { + localOs << "int("; + } } // Write function call closer. @@ -548,9 +548,9 @@ namespace Ogre { localOs << std::endl; os << localOs.str(); } - - if (gpuType == GPT_FRAGMENT_PROGRAM) - { + + if (gpuType == GPT_FRAGMENT_PROGRAM) + { // GLSL fragment program has to write always gl_FragColor (but this is also deprecated after version 130) // Always add gl_FragColor as an output. The name is for compatibility. if(mGLSLVersion > 100) @@ -561,12 +561,12 @@ namespace Ogre { { os << "\tgl_FragColor = outputColor;" << std::endl; } - } - else if (gpuType == GPT_VERTEX_PROGRAM) - { - os << "\tgl_Position = outputPosition;" << std::endl; - } - + } + else if (gpuType == GPT_VERTEX_PROGRAM) + { + os << "\tgl_Position = outputPosition;" << std::endl; + } + os << "}" << std::endl; } os << std::endl; @@ -574,9 +574,9 @@ namespace Ogre { //----------------------------------------------------------------------- void GLSLESProgramWriter::writeInputParameters( - std::ostream& os, - Function* function, - GpuProgramType gpuType) + std::ostream& os, + Function* function, + GpuProgramType gpuType) { const ShaderParameterList& inParams = function->getInputParameters(); @@ -584,13 +584,13 @@ namespace Ogre { ShaderParameterConstIterator itParamEnd = inParams.end(); for ( ; itParam != itParamEnd; ++itParam) - { + { ParameterPtr pParam = *itParam; Parameter::Content paramContent = pParam->getContent(); String paramName = pParam->getName(); if (gpuType == GPT_FRAGMENT_PROGRAM) - { + { // push fragment inputs they all could be written (in glsl you can not write // input params in the fragment program) mFragInputParams.push_back(paramName); @@ -598,7 +598,7 @@ namespace Ogre { // In the vertex and fragment program the variable names must match. // Unfortunately now the input params are prefixed with an 'i' and output params with 'o'. // Thats why we are using a map for name mapping (we rename the params which are used in function atoms). - paramName.replace(paramName.begin(), paramName.begin() + 1, "o"); + paramName.replace(paramName.begin(), paramName.begin() + 1, "o"); mInputToGLStatesMap[pParam->getName()] = paramName; if(mGLSLVersion > 100) @@ -607,9 +607,9 @@ namespace Ogre { os << "varying\t"; os << mGpuConstTypeMap[pParam->getType()]; - os << "\t"; + os << "\t"; os << paramName; - os << ";" << std::endl; + os << ";" << std::endl; } else if (gpuType == GPT_VERTEX_PROGRAM && mContentToPerVertexAttributes.find(paramContent) != mContentToPerVertexAttributes.end()) @@ -638,26 +638,26 @@ namespace Ogre { { os << mGpuConstTypeMap[pParam->getType()]; } - os << "\t"; + os << "\t"; os << mContentToPerVertexAttributes[paramContent]; - os << ";" << std::endl; + os << ";" << std::endl; } else { os << "uniform \t "; os << mGpuConstTypeMap[pParam->getType()]; - os << "\t"; + os << "\t"; os << paramName; - os << ";" << std::endl; - } + os << ";" << std::endl; + } } } //----------------------------------------------------------------------- void GLSLESProgramWriter::writeOutParameters( - std::ostream& os, - Function* function, - GpuProgramType gpuType) + std::ostream& os, + Function* function, + GpuProgramType gpuType) { const ShaderParameterList& outParams = function->getOutputParameters(); @@ -684,11 +684,11 @@ namespace Ogre { os << mGpuConstTypeMap[pParam->getType()]; os << "\t"; os << pParam->getName(); - if (pParam->isArray() == true) - { - os << "[" << pParam->getSize() << "]"; - } - os << ";" << std::endl; + if (pParam->isArray() == true) + { + os << "[" << pParam->getSize() << "]"; + } + os << ";" << std::endl; } } else if(gpuType == GPT_FRAGMENT_PROGRAM && @@ -714,8 +714,8 @@ namespace Ogre { // 5. Go back to step 1 until we have found all the functions // void GLSLESProgramWriter::writeProgramDependencies( - std::ostream& os, - Program* program) + std::ostream& os, + Program* program) { for(unsigned int i = 0; i < program->getDependencyCount(); ++i) { @@ -737,7 +737,7 @@ namespace Ogre { FunctionAtomInstanceConstIterator itAtomEnd = atomInstances.end(); // Now iterate over all function atoms for ( ; itAtom != itAtomEnd; ++itAtom) - { + { // Skip non function invocation atoms. if ((*itAtom)->getFunctionAtomType() != FunctionInvocation::Type) continue; @@ -794,8 +794,8 @@ namespace Ogre { break; } - if(invoc.getFunctionName().length()) - { + if(invoc.getFunctionName().length()) + { // Write out the function from the cached FunctionInvocation; os << invoc.getReturnType(); os << " "; @@ -846,7 +846,7 @@ namespace Ogre { { OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can not convert Operand::OpMask to GpuConstantType", - "GLSLESProgramWriter::writeProgramDependencies" ); + "GLSLESProgramWriter::writeProgramDependencies" ); } os << mGpuConstTypeMap[gpuType] << " " << paramName; @@ -890,12 +890,12 @@ namespace Ogre { void GLSLESProgramWriter::writeLocalParameter(std::ostream& os, ParameterPtr parameter) { os << mGpuConstTypeMap[parameter->getType()]; - os << "\t"; - os << parameter->getName(); - if (parameter->isArray() == true) - { - os << "[" << parameter->getSize() << "]"; - } + os << "\t"; + os << parameter->getName(); + if (parameter->isArray() == true) + { + os << "[" << parameter->getSize() << "]"; + } } //----------------------------------------------------------------------- void GLSLESProgramWriter::cacheDependencyFunctions(const String & libName) diff --git a/Components/RTShaderSystem/src/OgreShaderGLSLProgramProcessor.cpp b/Components/RTShaderSystem/src/OgreShaderGLSLProgramProcessor.cpp index 3bcdc264dc1..5dcc650719e 100644 --- a/Components/RTShaderSystem/src/OgreShaderGLSLProgramProcessor.cpp +++ b/Components/RTShaderSystem/src/OgreShaderGLSLProgramProcessor.cpp @@ -47,147 +47,147 @@ GLSLProgramProcessor::GLSLProgramProcessor() //----------------------------------------------------------------------------- GLSLProgramProcessor::~GLSLProgramProcessor() { - StringVector::iterator it = mLibraryPrograms.begin(); - StringVector::iterator itEnd = mLibraryPrograms.end(); - - for (; it != itEnd; ++it) - { - HighLevelGpuProgramManager::getSingleton().remove(*it); - } - mLibraryPrograms.clear(); + StringVector::iterator it = mLibraryPrograms.begin(); + StringVector::iterator itEnd = mLibraryPrograms.end(); + + for (; it != itEnd; ++it) + { + HighLevelGpuProgramManager::getSingleton().remove(*it); + } + mLibraryPrograms.clear(); } //----------------------------------------------------------------------------- bool GLSLProgramProcessor::preCreateGpuPrograms(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* fsProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* fsMain = fsProgram->getEntryPointFunction(); - bool success; - - // Compact vertex shader outputs. - success = ProgramProcessor::compactVsOutputs(vsMain, fsMain); - if (success == false) - return false; - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* fsProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* fsMain = fsProgram->getEntryPointFunction(); + bool success; + + // Compact vertex shader outputs. + success = ProgramProcessor::compactVsOutputs(vsMain, fsMain); + if (success == false) + return false; + + return true; } //----------------------------------------------------------------------------- bool GLSLProgramProcessor::postCreateGpuPrograms(ProgramSet* programSet) { - Program* vsCpuProgram = programSet->getCpuVertexProgram(); - Program* fsCpuProgram = programSet->getCpuFragmentProgram(); - GpuProgramPtr vsGpuProgram = programSet->getGpuVertexProgram(); - GpuProgramPtr fsGpuProgram = programSet->getGpuFragmentProgram(); - - // Bind sub shaders for the vertex shader. - bindSubShaders(vsCpuProgram, vsGpuProgram); - - // Bind sub shaders for the fragment shader. - bindSubShaders(fsCpuProgram, fsGpuProgram); + Program* vsCpuProgram = programSet->getCpuVertexProgram(); + Program* fsCpuProgram = programSet->getCpuFragmentProgram(); + GpuProgramPtr vsGpuProgram = programSet->getGpuVertexProgram(); + GpuProgramPtr fsGpuProgram = programSet->getGpuFragmentProgram(); + + // Bind sub shaders for the vertex shader. + bindSubShaders(vsCpuProgram, vsGpuProgram); + + // Bind sub shaders for the fragment shader. + bindSubShaders(fsCpuProgram, fsGpuProgram); - // Bind vertex shader auto parameters. - bindAutoParameters(programSet->getCpuVertexProgram(), programSet->getGpuVertexProgram()); + // Bind vertex shader auto parameters. + bindAutoParameters(programSet->getCpuVertexProgram(), programSet->getGpuVertexProgram()); - // Bind fragment shader auto parameters. - bindAutoParameters(programSet->getCpuFragmentProgram(), programSet->getGpuFragmentProgram()); + // Bind fragment shader auto parameters. + bindAutoParameters(programSet->getCpuFragmentProgram(), programSet->getGpuFragmentProgram()); - // Bind texture samplers for the vertex shader. - bindTextureSamplers(vsCpuProgram, vsGpuProgram); + // Bind texture samplers for the vertex shader. + bindTextureSamplers(vsCpuProgram, vsGpuProgram); - // Bind texture samplers for the fragment shader. - bindTextureSamplers(fsCpuProgram, fsGpuProgram); + // Bind texture samplers for the fragment shader. + bindTextureSamplers(fsCpuProgram, fsGpuProgram); - return true; + return true; } //----------------------------------------------------------------------------- void GLSLProgramProcessor::bindSubShaders(Program* program, GpuProgramPtr pGpuProgram) { - if (program->getDependencyCount() > 0) - { - // Get all attached shaders so we do not attach shaders twice. - // maybe GLSLProgram should take care of that ( prevent add duplicate shaders ) - String attachedShaders = pGpuProgram->getParameter("attach"); - String subShaderDef = ""; - - for (unsigned int i=0; i < program->getDependencyCount(); ++i) - { - // Here we append _VS and _FS to the library shaders (so max each lib shader - // is compiled twice once as vertex and once as fragment shader) - String subShaderName = program->getDependency(i); - if (program->getType() == GPT_VERTEX_PROGRAM) - { - subShaderName += "_VS"; - } - else - { - subShaderName += "_FS"; - } - - // Check if the library shader already compiled - if(!HighLevelGpuProgramManager::getSingleton().resourceExists(subShaderName)) - { - // Create the library shader - HighLevelGpuProgramPtr pSubGpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(subShaderName, - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TargetLanguage, program->getType()); - - // Set the source name - String sourceName = program->getDependency(i) + "." + TargetLanguage; - pSubGpuProgram->setSourceFile(sourceName); + if (program->getDependencyCount() > 0) + { + // Get all attached shaders so we do not attach shaders twice. + // maybe GLSLProgram should take care of that ( prevent add duplicate shaders ) + String attachedShaders = pGpuProgram->getParameter("attach"); + String subShaderDef = ""; + + for (unsigned int i=0; i < program->getDependencyCount(); ++i) + { + // Here we append _VS and _FS to the library shaders (so max each lib shader + // is compiled twice once as vertex and once as fragment shader) + String subShaderName = program->getDependency(i); + if (program->getType() == GPT_VERTEX_PROGRAM) + { + subShaderName += "_VS"; + } + else + { + subShaderName += "_FS"; + } + + // Check if the library shader already compiled + if(!HighLevelGpuProgramManager::getSingleton().resourceExists(subShaderName)) + { + // Create the library shader + HighLevelGpuProgramPtr pSubGpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(subShaderName, + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TargetLanguage, program->getType()); + + // Set the source name + String sourceName = program->getDependency(i) + "." + TargetLanguage; + pSubGpuProgram->setSourceFile(sourceName); pSubGpuProgram->load(); // Prepend the current GLSL version String versionLine = "#version " + StringConverter::toString(Root::getSingleton().getRenderSystem()->getNativeShadingLanguageVersion()) + "\n"; pSubGpuProgram->setSource(versionLine + pSubGpuProgram->getSource()); - // If we have compile errors than stop processing - if (pSubGpuProgram->hasCompileError()) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Could not compile shader library from the source file: " + sourceName, - "GLSLProgramProcessor::bindSubShaders" ); - } - - mLibraryPrograms.push_back(subShaderName); - } - - // Check if the lib shader already attached to this shader - if (attachedShaders.find(subShaderName) == String::npos) - { - // Append the shader name to subShaders - subShaderDef += subShaderName + " "; - } - } - - // Check if we have something to attach - if (subShaderDef.length() > 0) - { - pGpuProgram->setParameter("attach", subShaderDef); - } - } - + // If we have compile errors than stop processing + if (pSubGpuProgram->hasCompileError()) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Could not compile shader library from the source file: " + sourceName, + "GLSLProgramProcessor::bindSubShaders" ); + } + + mLibraryPrograms.push_back(subShaderName); + } + + // Check if the lib shader already attached to this shader + if (attachedShaders.find(subShaderName) == String::npos) + { + // Append the shader name to subShaders + subShaderDef += subShaderName + " "; + } + } + + // Check if we have something to attach + if (subShaderDef.length() > 0) + { + pGpuProgram->setParameter("attach", subShaderDef); + } + } + } //----------------------------------------------------------------------------- void GLSLProgramProcessor::bindTextureSamplers(Program* pCpuProgram, GpuProgramPtr pGpuProgram) { - GpuProgramParametersSharedPtr pGpuParams = pGpuProgram->getDefaultParameters(); - const UniformParameterList& progParams = pCpuProgram->getParameters(); - UniformParameterConstIterator itParams; - - // Bind the samplers. - for (itParams=progParams.begin(); itParams != progParams.end(); ++itParams) - { - const UniformParameterPtr pCurParam = *itParams; - - if (pCurParam->isSampler()) - { - pGpuParams->setNamedConstant(pCurParam->getName(), pCurParam->getIndex()); - } - } + GpuProgramParametersSharedPtr pGpuParams = pGpuProgram->getDefaultParameters(); + const UniformParameterList& progParams = pCpuProgram->getParameters(); + UniformParameterConstIterator itParams; + + // Bind the samplers. + for (itParams=progParams.begin(); itParams != progParams.end(); ++itParams) + { + const UniformParameterPtr pCurParam = *itParams; + + if (pCurParam->isSampler()) + { + pGpuParams->setNamedConstant(pCurParam->getName(), pCurParam->getIndex()); + } + } } } diff --git a/Components/RTShaderSystem/src/OgreShaderGLSLProgramWriter.cpp b/Components/RTShaderSystem/src/OgreShaderGLSLProgramWriter.cpp index 39f79e8315c..8922fe4cca2 100644 --- a/Components/RTShaderSystem/src/OgreShaderGLSLProgramWriter.cpp +++ b/Components/RTShaderSystem/src/OgreShaderGLSLProgramWriter.cpp @@ -38,8 +38,8 @@ String GLSLProgramWriter::TargetLanguage = "glsl"; //----------------------------------------------------------------------- GLSLProgramWriter::GLSLProgramWriter() { - mGLSLVersion = Ogre::Root::getSingleton().getRenderSystem()->getNativeShadingLanguageVersion(); - initializeStringMaps(); + mGLSLVersion = Ogre::Root::getSingleton().getRenderSystem()->getNativeShadingLanguageVersion(); + initializeStringMaps(); } //----------------------------------------------------------------------- @@ -51,491 +51,491 @@ GLSLProgramWriter::~GLSLProgramWriter() //----------------------------------------------------------------------- void GLSLProgramWriter::initializeStringMaps() { - // basic glsl types - mGpuConstTypeMap[GCT_FLOAT1] = "float"; - mGpuConstTypeMap[GCT_FLOAT2] = "vec2"; - mGpuConstTypeMap[GCT_FLOAT3] = "vec3"; - mGpuConstTypeMap[GCT_FLOAT4] = "vec4"; - mGpuConstTypeMap[GCT_SAMPLER1D] = "sampler1D"; - mGpuConstTypeMap[GCT_SAMPLER2D] = "sampler2D"; - mGpuConstTypeMap[GCT_SAMPLER2DARRAY] = "sampler2DArray"; - mGpuConstTypeMap[GCT_SAMPLER3D] = "sampler3D"; - mGpuConstTypeMap[GCT_SAMPLERCUBE] = "samplerCube"; - mGpuConstTypeMap[GCT_SAMPLER1DSHADOW] = "sampler1DShadow"; - mGpuConstTypeMap[GCT_SAMPLER2DSHADOW] = "sampler2DShadow"; - mGpuConstTypeMap[GCT_MATRIX_2X2] = "mat2"; - mGpuConstTypeMap[GCT_MATRIX_2X3] = "mat2x3"; - mGpuConstTypeMap[GCT_MATRIX_2X4] = "mat2x4"; - mGpuConstTypeMap[GCT_MATRIX_3X2] = "mat3x2"; - mGpuConstTypeMap[GCT_MATRIX_3X3] = "mat3"; - mGpuConstTypeMap[GCT_MATRIX_3X4] = "mat3x4"; - mGpuConstTypeMap[GCT_MATRIX_4X2] = "mat4x2"; - mGpuConstTypeMap[GCT_MATRIX_4X3] = "mat4x3"; - mGpuConstTypeMap[GCT_MATRIX_4X4] = "mat4"; - mGpuConstTypeMap[GCT_INT1] = "int"; - mGpuConstTypeMap[GCT_INT2] = "int2"; - mGpuConstTypeMap[GCT_INT3] = "int3"; - mGpuConstTypeMap[GCT_INT4] = "int4"; - mGpuConstTypeMap[GCT_UINT1] = "uint"; - mGpuConstTypeMap[GCT_UINT2] = "uint2"; - mGpuConstTypeMap[GCT_UINT3] = "uint3"; - mGpuConstTypeMap[GCT_UINT4] = "uint4"; - - // Custom vertex attributes defined http://www.ogre3d.org/docs/manual/manual_21.html - mContentToPerVertexAttributes[Parameter::SPC_POSITION_OBJECT_SPACE] = "vertex"; - mContentToPerVertexAttributes[Parameter::SPC_NORMAL_OBJECT_SPACE] = "normal"; - mContentToPerVertexAttributes[Parameter::SPC_TANGENT_OBJECT_SPACE] = "tangent"; - mContentToPerVertexAttributes[Parameter::SPC_BINORMAL_OBJECT_SPACE] = "binormal"; - - mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE0] = "uv0"; - mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE1] = "uv1"; - mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE2] = "uv2"; - mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE3] = "uv3"; - mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE4] = "uv4"; - mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE5] = "uv5"; - mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE6] = "uv6"; - mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE7] = "uv7"; - - if (mGLSLVersion >= 130) - { - mContentToPerVertexAttributes[Parameter::SPC_COLOR_DIFFUSE] = "colour"; - mContentToPerVertexAttributes[Parameter::SPC_COLOR_SPECULAR] = "secondary_colour"; - } + // basic glsl types + mGpuConstTypeMap[GCT_FLOAT1] = "float"; + mGpuConstTypeMap[GCT_FLOAT2] = "vec2"; + mGpuConstTypeMap[GCT_FLOAT3] = "vec3"; + mGpuConstTypeMap[GCT_FLOAT4] = "vec4"; + mGpuConstTypeMap[GCT_SAMPLER1D] = "sampler1D"; + mGpuConstTypeMap[GCT_SAMPLER2D] = "sampler2D"; + mGpuConstTypeMap[GCT_SAMPLER2DARRAY] = "sampler2DArray"; + mGpuConstTypeMap[GCT_SAMPLER3D] = "sampler3D"; + mGpuConstTypeMap[GCT_SAMPLERCUBE] = "samplerCube"; + mGpuConstTypeMap[GCT_SAMPLER1DSHADOW] = "sampler1DShadow"; + mGpuConstTypeMap[GCT_SAMPLER2DSHADOW] = "sampler2DShadow"; + mGpuConstTypeMap[GCT_MATRIX_2X2] = "mat2"; + mGpuConstTypeMap[GCT_MATRIX_2X3] = "mat2x3"; + mGpuConstTypeMap[GCT_MATRIX_2X4] = "mat2x4"; + mGpuConstTypeMap[GCT_MATRIX_3X2] = "mat3x2"; + mGpuConstTypeMap[GCT_MATRIX_3X3] = "mat3"; + mGpuConstTypeMap[GCT_MATRIX_3X4] = "mat3x4"; + mGpuConstTypeMap[GCT_MATRIX_4X2] = "mat4x2"; + mGpuConstTypeMap[GCT_MATRIX_4X3] = "mat4x3"; + mGpuConstTypeMap[GCT_MATRIX_4X4] = "mat4"; + mGpuConstTypeMap[GCT_INT1] = "int"; + mGpuConstTypeMap[GCT_INT2] = "int2"; + mGpuConstTypeMap[GCT_INT3] = "int3"; + mGpuConstTypeMap[GCT_INT4] = "int4"; + mGpuConstTypeMap[GCT_UINT1] = "uint"; + mGpuConstTypeMap[GCT_UINT2] = "uint2"; + mGpuConstTypeMap[GCT_UINT3] = "uint3"; + mGpuConstTypeMap[GCT_UINT4] = "uint4"; + + // Custom vertex attributes defined http://www.ogre3d.org/docs/manual/manual_21.html + mContentToPerVertexAttributes[Parameter::SPC_POSITION_OBJECT_SPACE] = "vertex"; + mContentToPerVertexAttributes[Parameter::SPC_NORMAL_OBJECT_SPACE] = "normal"; + mContentToPerVertexAttributes[Parameter::SPC_TANGENT_OBJECT_SPACE] = "tangent"; + mContentToPerVertexAttributes[Parameter::SPC_BINORMAL_OBJECT_SPACE] = "binormal"; + + mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE0] = "uv0"; + mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE1] = "uv1"; + mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE2] = "uv2"; + mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE3] = "uv3"; + mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE4] = "uv4"; + mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE5] = "uv5"; + mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE6] = "uv6"; + mContentToPerVertexAttributes[Parameter::SPC_TEXTURE_COORDINATE7] = "uv7"; + + if (mGLSLVersion >= 130) + { + mContentToPerVertexAttributes[Parameter::SPC_COLOR_DIFFUSE] = "colour"; + mContentToPerVertexAttributes[Parameter::SPC_COLOR_SPECULAR] = "secondary_colour"; + } } //----------------------------------------------------------------------- void GLSLProgramWriter::writeSourceCode(std::ostream& os, Program* program) { - GpuProgramType gpuType = program->getType(); - if(gpuType == GPT_GEOMETRY_PROGRAM) - { - OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, - "Geometry Program not supported in GLSL writer ", - "GLSLProgramWriter::writeSourceCode" ); - } - - // Clear out old input params - mFragInputParams.clear(); - - const ShaderFunctionList& functionList = program->getFunctions(); - ShaderFunctionConstIterator itFunction; - - const UniformParameterList& parameterList = program->getParameters(); - UniformParameterConstIterator itUniformParam = parameterList.begin(); - - // Write the current version (this force the driver to more fulfill the glsl standard) - os << "#version "<< mGLSLVersion << std::endl; - - // Generate source code header. - writeProgramTitle(os, program); - os<< std::endl; - - // Write forward declarations - writeForwardDeclarations(os, program); - os<< std::endl; - - // Generate global variable code. - writeUniformParametersTitle(os, program); - os << std::endl; - - // Write the uniforms - for (itUniformParam = parameterList.begin(); itUniformParam != parameterList.end(); ++itUniformParam) - { - ParameterPtr pUniformParam = *itUniformParam; - - os << "uniform\t"; - os << mGpuConstTypeMap[pUniformParam->getType()]; - os << "\t"; - os << pUniformParam->getName(); - if (pUniformParam->isArray() == true) - { - os << "[" << pUniformParam->getSize() << "]"; - } - os << ";" << std::endl; - } - os << std::endl; - - // Write program function(s). - for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) - { - Function* curFunction = *itFunction; - - writeFunctionTitle(os, curFunction); - - // Clear output mapping this map is used when we use - // glsl built in types like gl_Color for example - mInputToGLStatesMap.clear(); - - // Write inout params and fill mInputToGLStatesMap - writeInputParameters(os, curFunction, gpuType); - writeOutParameters(os, curFunction, gpuType); - - // The function name must always main. - os << "void main(void) {" << std::endl; - - // Write local parameters. - const ShaderParameterList& localParams = curFunction->getLocalParameters(); - ShaderParameterConstIterator itParam = localParams.begin(); - ShaderParameterConstIterator itParamEnd = localParams.end(); - - for (; itParam != itParamEnd; ++itParam) - { - os << "\t"; - writeLocalParameter(os, *itParam); - os << ";" << std::endl; - } - os << std::endl; - - // Sort function atoms. - curFunction->sortAtomInstances(); - - const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances(); - FunctionAtomInstanceConstIterator itAtom = atomInstances.begin(); - FunctionAtomInstanceConstIterator itAtomEnd = atomInstances.end(); - - for (; itAtom != itAtomEnd; ++itAtom) - { - FunctionInvocation* pFuncInvoc = (FunctionInvocation*)*itAtom; - FunctionInvocation::OperandVector::iterator itOperand = pFuncInvoc->getOperandList().begin(); - FunctionInvocation::OperandVector::iterator itOperandEnd = pFuncInvoc->getOperandList().end(); - - // Local string stream - StringStream localOs; - - // Write function name - localOs << "\t" << pFuncInvoc->getFunctionName() << "("; - - ushort curIndLevel = 0; - - for (; itOperand != itOperandEnd; ) - { - Operand op = *itOperand; - Operand::OpSemantic opSemantic = op.getSemantic(); - String paramName = op.getParameter()->getName(); - Parameter::Content content = op.getParameter()->getContent(); - - if (opSemantic == Operand::OPS_OUT || opSemantic == Operand::OPS_INOUT) - { - // Is the written parameter a varying - bool isVarying = false; - - // Check if we write to an varying because the are only readable in fragment programs - if (gpuType == GPT_FRAGMENT_PROGRAM) - { - StringVector::iterator itFound = std::find(mFragInputParams.begin(), mFragInputParams.end(), paramName); - if(itFound != mFragInputParams.end()) - { - // Declare the copy variable - String newVar = "local_" + paramName; - String tempVar = paramName; - isVarying = true; - - // We stored the original values in the mFragInputParams thats why we have to replace the first var with o - // because all vertex output vars are prefixed with o in glsl the name has to match in the fragment program. - tempVar.replace(tempVar.begin(), tempVar.begin() + 1, "o"); - - // Declare the copy variable and assign the original - os << "\t" << mGpuConstTypeMap[op.getParameter()->getType()] << " " << newVar << " = " << tempVar << ";\n" << std::endl; - - // From now on we replace it automatic - mInputToGLStatesMap[paramName] = newVar; - - // Remove the param because now it is replaced automatic with the local variable - // (which could be written). - mFragInputParams.erase(itFound++); - } - } - - // If its not a varying param check if a uniform is written - if(!isVarying) - { - UniformParameterList::const_iterator itFound = std::find_if( parameterList.begin(), parameterList.end(), std::bind2nd( CompareUniformByName(), paramName ) ); - if(itFound != parameterList.end()) - { - // Declare the copy variable - String newVar = "local_" + paramName; - - // now we check if we already declared a uniform redirector var - if(mInputToGLStatesMap.find(newVar) == mInputToGLStatesMap.end()) - { - // Declare the copy variable and assign the original - os << "\t" << mGpuConstTypeMap[itFound->get()->getType()] << " " << newVar << " = " << paramName << ";\n" << std::endl; - - // From now on we replace it automatic - mInputToGLStatesMap[paramName] = newVar; - } - } - } - } - - if(mInputToGLStatesMap.find(paramName) != mInputToGLStatesMap.end()) - { - int mask = op.getMask(); // our swizzle mask - - // Here we insert the renamed param name - localOs << mInputToGLStatesMap[paramName]; - - if(mask != Operand::OPM_ALL) - { - localOs << "." << Operand::getMaskAsString(mask); - } - // Now that every texcoord is a vec4 (passed as vertex attributes) we - // have to swizzle them according the desired type. - else if(gpuType == GPT_VERTEX_PROGRAM && - (content == Parameter::SPC_TEXTURE_COORDINATE0 || - content == Parameter::SPC_TEXTURE_COORDINATE1 || - content == Parameter::SPC_TEXTURE_COORDINATE2 || - content == Parameter::SPC_TEXTURE_COORDINATE3 || - content == Parameter::SPC_TEXTURE_COORDINATE4 || - content == Parameter::SPC_TEXTURE_COORDINATE5 || - content == Parameter::SPC_TEXTURE_COORDINATE6 || - content == Parameter::SPC_TEXTURE_COORDINATE7) ) - { - // Now generate the swizzel mask according - // the type. - switch(op.getParameter()->getType()) - { - case GCT_FLOAT1: - localOs << ".x"; - break; - case GCT_FLOAT2: - localOs << ".xy"; - break; - case GCT_FLOAT3: - localOs << ".xyz"; - break; - case GCT_FLOAT4: - localOs << ".xyzw"; - break; - - default: - break; - } - } - } - else - { - localOs << op.toString(); - } - - ++itOperand; - - // Prepare for the next operand - ushort opIndLevel = 0; - if (itOperand != itOperandEnd) - { - opIndLevel = itOperand->getIndirectionLevel(); - } - - if (curIndLevel != 0) - { - localOs << ")"; - } - - if (curIndLevel < opIndLevel) - { - while (curIndLevel < opIndLevel) - { - ++curIndLevel; - localOs << "["; - } - } - else //if (curIndLevel >= opIndLevel) - { - while (curIndLevel > opIndLevel) - { - --curIndLevel; - localOs << "]"; - } - if (opIndLevel != 0) - { - localOs << "]["; - } - else if (itOperand != itOperandEnd) - { - localOs << ", "; - } - } - if (curIndLevel != 0) - { - localOs << "int("; - } - } - - // Write function call closer. - localOs << ");" << std::endl; - localOs << std::endl; - os << localOs.str(); - } - os << "}" << std::endl; - } - os << std::endl; + GpuProgramType gpuType = program->getType(); + if(gpuType == GPT_GEOMETRY_PROGRAM) + { + OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, + "Geometry Program not supported in GLSL writer ", + "GLSLProgramWriter::writeSourceCode" ); + } + + // Clear out old input params + mFragInputParams.clear(); + + const ShaderFunctionList& functionList = program->getFunctions(); + ShaderFunctionConstIterator itFunction; + + const UniformParameterList& parameterList = program->getParameters(); + UniformParameterConstIterator itUniformParam = parameterList.begin(); + + // Write the current version (this force the driver to more fulfill the glsl standard) + os << "#version "<< mGLSLVersion << std::endl; + + // Generate source code header. + writeProgramTitle(os, program); + os<< std::endl; + + // Write forward declarations + writeForwardDeclarations(os, program); + os<< std::endl; + + // Generate global variable code. + writeUniformParametersTitle(os, program); + os << std::endl; + + // Write the uniforms + for (itUniformParam = parameterList.begin(); itUniformParam != parameterList.end(); ++itUniformParam) + { + ParameterPtr pUniformParam = *itUniformParam; + + os << "uniform\t"; + os << mGpuConstTypeMap[pUniformParam->getType()]; + os << "\t"; + os << pUniformParam->getName(); + if (pUniformParam->isArray() == true) + { + os << "[" << pUniformParam->getSize() << "]"; + } + os << ";" << std::endl; + } + os << std::endl; + + // Write program function(s). + for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) + { + Function* curFunction = *itFunction; + + writeFunctionTitle(os, curFunction); + + // Clear output mapping this map is used when we use + // glsl built in types like gl_Color for example + mInputToGLStatesMap.clear(); + + // Write inout params and fill mInputToGLStatesMap + writeInputParameters(os, curFunction, gpuType); + writeOutParameters(os, curFunction, gpuType); + + // The function name must always main. + os << "void main(void) {" << std::endl; + + // Write local parameters. + const ShaderParameterList& localParams = curFunction->getLocalParameters(); + ShaderParameterConstIterator itParam = localParams.begin(); + ShaderParameterConstIterator itParamEnd = localParams.end(); + + for (; itParam != itParamEnd; ++itParam) + { + os << "\t"; + writeLocalParameter(os, *itParam); + os << ";" << std::endl; + } + os << std::endl; + + // Sort function atoms. + curFunction->sortAtomInstances(); + + const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances(); + FunctionAtomInstanceConstIterator itAtom = atomInstances.begin(); + FunctionAtomInstanceConstIterator itAtomEnd = atomInstances.end(); + + for (; itAtom != itAtomEnd; ++itAtom) + { + FunctionInvocation* pFuncInvoc = (FunctionInvocation*)*itAtom; + FunctionInvocation::OperandVector::iterator itOperand = pFuncInvoc->getOperandList().begin(); + FunctionInvocation::OperandVector::iterator itOperandEnd = pFuncInvoc->getOperandList().end(); + + // Local string stream + StringStream localOs; + + // Write function name + localOs << "\t" << pFuncInvoc->getFunctionName() << "("; + + ushort curIndLevel = 0; + + for (; itOperand != itOperandEnd; ) + { + Operand op = *itOperand; + Operand::OpSemantic opSemantic = op.getSemantic(); + String paramName = op.getParameter()->getName(); + Parameter::Content content = op.getParameter()->getContent(); + + if (opSemantic == Operand::OPS_OUT || opSemantic == Operand::OPS_INOUT) + { + // Is the written parameter a varying + bool isVarying = false; + + // Check if we write to an varying because the are only readable in fragment programs + if (gpuType == GPT_FRAGMENT_PROGRAM) + { + StringVector::iterator itFound = std::find(mFragInputParams.begin(), mFragInputParams.end(), paramName); + if(itFound != mFragInputParams.end()) + { + // Declare the copy variable + String newVar = "local_" + paramName; + String tempVar = paramName; + isVarying = true; + + // We stored the original values in the mFragInputParams thats why we have to replace the first var with o + // because all vertex output vars are prefixed with o in glsl the name has to match in the fragment program. + tempVar.replace(tempVar.begin(), tempVar.begin() + 1, "o"); + + // Declare the copy variable and assign the original + os << "\t" << mGpuConstTypeMap[op.getParameter()->getType()] << " " << newVar << " = " << tempVar << ";\n" << std::endl; + + // From now on we replace it automatic + mInputToGLStatesMap[paramName] = newVar; + + // Remove the param because now it is replaced automatic with the local variable + // (which could be written). + mFragInputParams.erase(itFound++); + } + } + + // If its not a varying param check if a uniform is written + if(!isVarying) + { + UniformParameterList::const_iterator itFound = std::find_if( parameterList.begin(), parameterList.end(), std::bind2nd( CompareUniformByName(), paramName ) ); + if(itFound != parameterList.end()) + { + // Declare the copy variable + String newVar = "local_" + paramName; + + // now we check if we already declared a uniform redirector var + if(mInputToGLStatesMap.find(newVar) == mInputToGLStatesMap.end()) + { + // Declare the copy variable and assign the original + os << "\t" << mGpuConstTypeMap[itFound->get()->getType()] << " " << newVar << " = " << paramName << ";\n" << std::endl; + + // From now on we replace it automatic + mInputToGLStatesMap[paramName] = newVar; + } + } + } + } + + if(mInputToGLStatesMap.find(paramName) != mInputToGLStatesMap.end()) + { + int mask = op.getMask(); // our swizzle mask + + // Here we insert the renamed param name + localOs << mInputToGLStatesMap[paramName]; + + if(mask != Operand::OPM_ALL) + { + localOs << "." << Operand::getMaskAsString(mask); + } + // Now that every texcoord is a vec4 (passed as vertex attributes) we + // have to swizzle them according the desired type. + else if(gpuType == GPT_VERTEX_PROGRAM && + (content == Parameter::SPC_TEXTURE_COORDINATE0 || + content == Parameter::SPC_TEXTURE_COORDINATE1 || + content == Parameter::SPC_TEXTURE_COORDINATE2 || + content == Parameter::SPC_TEXTURE_COORDINATE3 || + content == Parameter::SPC_TEXTURE_COORDINATE4 || + content == Parameter::SPC_TEXTURE_COORDINATE5 || + content == Parameter::SPC_TEXTURE_COORDINATE6 || + content == Parameter::SPC_TEXTURE_COORDINATE7) ) + { + // Now generate the swizzel mask according + // the type. + switch(op.getParameter()->getType()) + { + case GCT_FLOAT1: + localOs << ".x"; + break; + case GCT_FLOAT2: + localOs << ".xy"; + break; + case GCT_FLOAT3: + localOs << ".xyz"; + break; + case GCT_FLOAT4: + localOs << ".xyzw"; + break; + + default: + break; + } + } + } + else + { + localOs << op.toString(); + } + + ++itOperand; + + // Prepare for the next operand + ushort opIndLevel = 0; + if (itOperand != itOperandEnd) + { + opIndLevel = itOperand->getIndirectionLevel(); + } + + if (curIndLevel != 0) + { + localOs << ")"; + } + + if (curIndLevel < opIndLevel) + { + while (curIndLevel < opIndLevel) + { + ++curIndLevel; + localOs << "["; + } + } + else //if (curIndLevel >= opIndLevel) + { + while (curIndLevel > opIndLevel) + { + --curIndLevel; + localOs << "]"; + } + if (opIndLevel != 0) + { + localOs << "]["; + } + else if (itOperand != itOperandEnd) + { + localOs << ", "; + } + } + if (curIndLevel != 0) + { + localOs << "int("; + } + } + + // Write function call closer. + localOs << ");" << std::endl; + localOs << std::endl; + os << localOs.str(); + } + os << "}" << std::endl; + } + os << std::endl; } //----------------------------------------------------------------------- void GLSLProgramWriter::writeForwardDeclarations(std::ostream& os, Program* program) { - os << "//-----------------------------------------------------------------------------" << std::endl; - os << "// FORWARD DECLARATIONS" << std::endl; - os << "//-----------------------------------------------------------------------------" << std::endl; - - StringVector forwardDecl; // holds all generated function declarations - const ShaderFunctionList& functionList = program->getFunctions(); - ShaderFunctionConstIterator itFunction; - - // Iterate over all functions in the current program (in our case this is always the main() function) - for ( itFunction = functionList.begin(); itFunction != functionList.end(); ++itFunction) - { - Function* curFunction = *itFunction; - const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances(); - FunctionAtomInstanceConstIterator itAtom = atomInstances.begin(); - FunctionAtomInstanceConstIterator itAtomEnd = atomInstances.end(); - - // Now iterate over all function atoms - for ( ; itAtom != itAtomEnd; ++itAtom) - { - // Skip non function invocation atoms. - if ((*itAtom)->getFunctionAtomType() != FunctionInvocation::Type) - continue; - - FunctionInvocation* pFuncInvoc = static_cast(*itAtom); - FunctionInvocation::OperandVector::iterator itOperator = pFuncInvoc->getOperandList().begin(); - FunctionInvocation::OperandVector::iterator itOperatorEnd = pFuncInvoc->getOperandList().end(); - - // Start with function declaration - String funcDecl = pFuncInvoc->getReturnType() + " " + pFuncInvoc->getFunctionName() + "("; - - // Now iterate overall operands - for (; itOperator != itOperatorEnd; ) - { - ParameterPtr pParam = (*itOperator).getParameter(); - Operand::OpSemantic opSemantic = (*itOperator).getSemantic(); - int opMask = (*itOperator).getMask(); - GpuConstantType gpuType = GCT_UNKNOWN; - - // Write the semantic in, out, inout - switch(opSemantic) - { - case Operand::OPS_IN: - funcDecl += "in "; - break; - - case Operand::OPS_OUT: - funcDecl += "out "; - break; - - case Operand::OPS_INOUT: - funcDecl += "inout "; - break; - - default: - break; - } - - // Swizzle masks are only defined for types like vec2, vec3, vec4. - if (opMask == Operand::OPM_ALL) - { - gpuType = pParam->getType(); - } - else - { - // Now we have to convert the mask to operator - gpuType = Operand::getGpuConstantType(opMask); - } - - // We need a valid type otherwise glsl compilation will not work - if (gpuType == GCT_UNKNOWN) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Can not convert Operand::OpMask to GpuConstantType", - "GLSLProgramWriter::writeForwardDeclarations" ); - } - - // Write the operand type. - funcDecl += mGpuConstTypeMap[gpuType]; - - ++itOperator; - //move over all operators with indirection - while ((itOperator != itOperatorEnd) && (itOperator->getIndirectionLevel() != 0)) - { - ++itOperator; - } - - // Prepare for the next operand - if (itOperator != itOperatorEnd) - { - funcDecl += ", "; - } - } - // Write function call closer. - funcDecl += ");\n"; - - // Push the generated declaration into the vector - // duplicate declarations will be removed later. - forwardDecl.push_back(funcDecl); - } - } - - // Now remove duplicate declaration, first we have to sort the vector. - std::sort(forwardDecl.begin(), forwardDecl.end()); - StringVector::iterator endIt = std::unique(forwardDecl.begin(), forwardDecl.end()); - - // Finally write all function declarations to the shader file - for (StringVector::iterator it = forwardDecl.begin(); it != endIt; ++it) - { - os << *it; - } + os << "//-----------------------------------------------------------------------------" << std::endl; + os << "// FORWARD DECLARATIONS" << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; + + StringVector forwardDecl; // holds all generated function declarations + const ShaderFunctionList& functionList = program->getFunctions(); + ShaderFunctionConstIterator itFunction; + + // Iterate over all functions in the current program (in our case this is always the main() function) + for ( itFunction = functionList.begin(); itFunction != functionList.end(); ++itFunction) + { + Function* curFunction = *itFunction; + const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances(); + FunctionAtomInstanceConstIterator itAtom = atomInstances.begin(); + FunctionAtomInstanceConstIterator itAtomEnd = atomInstances.end(); + + // Now iterate over all function atoms + for ( ; itAtom != itAtomEnd; ++itAtom) + { + // Skip non function invocation atoms. + if ((*itAtom)->getFunctionAtomType() != FunctionInvocation::Type) + continue; + + FunctionInvocation* pFuncInvoc = static_cast(*itAtom); + FunctionInvocation::OperandVector::iterator itOperator = pFuncInvoc->getOperandList().begin(); + FunctionInvocation::OperandVector::iterator itOperatorEnd = pFuncInvoc->getOperandList().end(); + + // Start with function declaration + String funcDecl = pFuncInvoc->getReturnType() + " " + pFuncInvoc->getFunctionName() + "("; + + // Now iterate overall operands + for (; itOperator != itOperatorEnd; ) + { + ParameterPtr pParam = (*itOperator).getParameter(); + Operand::OpSemantic opSemantic = (*itOperator).getSemantic(); + int opMask = (*itOperator).getMask(); + GpuConstantType gpuType = GCT_UNKNOWN; + + // Write the semantic in, out, inout + switch(opSemantic) + { + case Operand::OPS_IN: + funcDecl += "in "; + break; + + case Operand::OPS_OUT: + funcDecl += "out "; + break; + + case Operand::OPS_INOUT: + funcDecl += "inout "; + break; + + default: + break; + } + + // Swizzle masks are only defined for types like vec2, vec3, vec4. + if (opMask == Operand::OPM_ALL) + { + gpuType = pParam->getType(); + } + else + { + // Now we have to convert the mask to operator + gpuType = Operand::getGpuConstantType(opMask); + } + + // We need a valid type otherwise glsl compilation will not work + if (gpuType == GCT_UNKNOWN) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Can not convert Operand::OpMask to GpuConstantType", + "GLSLProgramWriter::writeForwardDeclarations" ); + } + + // Write the operand type. + funcDecl += mGpuConstTypeMap[gpuType]; + + ++itOperator; + //move over all operators with indirection + while ((itOperator != itOperatorEnd) && (itOperator->getIndirectionLevel() != 0)) + { + ++itOperator; + } + + // Prepare for the next operand + if (itOperator != itOperatorEnd) + { + funcDecl += ", "; + } + } + // Write function call closer. + funcDecl += ");\n"; + + // Push the generated declaration into the vector + // duplicate declarations will be removed later. + forwardDecl.push_back(funcDecl); + } + } + + // Now remove duplicate declaration, first we have to sort the vector. + std::sort(forwardDecl.begin(), forwardDecl.end()); + StringVector::iterator endIt = std::unique(forwardDecl.begin(), forwardDecl.end()); + + // Finally write all function declarations to the shader file + for (StringVector::iterator it = forwardDecl.begin(); it != endIt; ++it) + { + os << *it; + } } //----------------------------------------------------------------------- void GLSLProgramWriter::writeInputParameters(std::ostream& os, Function* function, GpuProgramType gpuType) { - const ShaderParameterList& inParams = function->getInputParameters(); - - ShaderParameterConstIterator itParam = inParams.begin(); - ShaderParameterConstIterator itParamEnd = inParams.end(); - - for ( ; itParam != itParamEnd; ++itParam) - { - ParameterPtr pParam = *itParam; - Parameter::Content paramContent = pParam->getContent(); - String paramName = pParam->getName(); - - if (gpuType == GPT_FRAGMENT_PROGRAM) - { - // push fragment inputs they all could be written (in glsl you can not write - // input params in the fragment program) - mFragInputParams.push_back(paramName); - - // In the vertex and fragment program the variable names must match. - // Unfortunately now the input params are prefixed with an 'i' and output params with 'o'. - // Thats why we are using a map for name mapping (we rename the params which are used in function atoms). - paramName.replace(paramName.begin(), paramName.begin() + 1, "o"); - mInputToGLStatesMap[pParam->getName()] = paramName; - - // After GLSL 1.20 varying is deprecated - if(mGLSLVersion <= 120) - { - os << "varying\t"; - } - else - { - os << "in\t"; - } - - os << mGpuConstTypeMap[pParam->getType()]; - os << "\t"; - os << paramName; - os << ";" << std::endl; - } - else if (gpuType == GPT_VERTEX_PROGRAM && - mContentToPerVertexAttributes.find(paramContent) != mContentToPerVertexAttributes.end()) - { - // Due the fact that glsl does not have register like cg we have to rename the params - // according there content. - mInputToGLStatesMap[paramName] = mContentToPerVertexAttributes[paramContent]; - - // After GLSL 1.40 attribute is deprecated + const ShaderParameterList& inParams = function->getInputParameters(); + + ShaderParameterConstIterator itParam = inParams.begin(); + ShaderParameterConstIterator itParamEnd = inParams.end(); + + for ( ; itParam != itParamEnd; ++itParam) + { + ParameterPtr pParam = *itParam; + Parameter::Content paramContent = pParam->getContent(); + String paramName = pParam->getName(); + + if (gpuType == GPT_FRAGMENT_PROGRAM) + { + // push fragment inputs they all could be written (in glsl you can not write + // input params in the fragment program) + mFragInputParams.push_back(paramName); + + // In the vertex and fragment program the variable names must match. + // Unfortunately now the input params are prefixed with an 'i' and output params with 'o'. + // Thats why we are using a map for name mapping (we rename the params which are used in function atoms). + paramName.replace(paramName.begin(), paramName.begin() + 1, "o"); + mInputToGLStatesMap[pParam->getName()] = paramName; + + // After GLSL 1.20 varying is deprecated + if(mGLSLVersion <= 120) + { + os << "varying\t"; + } + else + { + os << "in\t"; + } + + os << mGpuConstTypeMap[pParam->getType()]; + os << "\t"; + os << paramName; + os << ";" << std::endl; + } + else if (gpuType == GPT_VERTEX_PROGRAM && + mContentToPerVertexAttributes.find(paramContent) != mContentToPerVertexAttributes.end()) + { + // Due the fact that glsl does not have register like cg we have to rename the params + // according there content. + mInputToGLStatesMap[paramName] = mContentToPerVertexAttributes[paramContent]; + + // After GLSL 1.40 attribute is deprecated if (mGLSLVersion >= 140) { os << "in\t"; @@ -545,90 +545,90 @@ void GLSLProgramWriter::writeInputParameters(std::ostream& os, Function* functio os << "attribute\t"; } - // all uv texcoords passed by ogre are vec4 - if (paramContent == Parameter::SPC_TEXTURE_COORDINATE0 || - paramContent == Parameter::SPC_TEXTURE_COORDINATE1 || - paramContent == Parameter::SPC_TEXTURE_COORDINATE2 || - paramContent == Parameter::SPC_TEXTURE_COORDINATE3 || - paramContent == Parameter::SPC_TEXTURE_COORDINATE4 || - paramContent == Parameter::SPC_TEXTURE_COORDINATE5 || - paramContent == Parameter::SPC_TEXTURE_COORDINATE6 || - paramContent == Parameter::SPC_TEXTURE_COORDINATE7 ) - { - os << "vec4"; - } - else - { - os << mGpuConstTypeMap[pParam->getType()]; - } - os << "\t"; - os << mContentToPerVertexAttributes[paramContent]; - os << ";" << std::endl; - } - else if(paramContent == Parameter::SPC_COLOR_DIFFUSE) - { - mInputToGLStatesMap[paramName] = "gl_Color"; - } - else if(paramContent == Parameter::SPC_COLOR_SPECULAR) - { - mInputToGLStatesMap[paramName] = "gl_SecondaryColor"; - } - else - { - os << "uniform \t "; - os << mGpuConstTypeMap[pParam->getType()]; - os << "\t"; - os << paramName; - os << ";" << std::endl; - } - } + // all uv texcoords passed by ogre are vec4 + if (paramContent == Parameter::SPC_TEXTURE_COORDINATE0 || + paramContent == Parameter::SPC_TEXTURE_COORDINATE1 || + paramContent == Parameter::SPC_TEXTURE_COORDINATE2 || + paramContent == Parameter::SPC_TEXTURE_COORDINATE3 || + paramContent == Parameter::SPC_TEXTURE_COORDINATE4 || + paramContent == Parameter::SPC_TEXTURE_COORDINATE5 || + paramContent == Parameter::SPC_TEXTURE_COORDINATE6 || + paramContent == Parameter::SPC_TEXTURE_COORDINATE7 ) + { + os << "vec4"; + } + else + { + os << mGpuConstTypeMap[pParam->getType()]; + } + os << "\t"; + os << mContentToPerVertexAttributes[paramContent]; + os << ";" << std::endl; + } + else if(paramContent == Parameter::SPC_COLOR_DIFFUSE) + { + mInputToGLStatesMap[paramName] = "gl_Color"; + } + else if(paramContent == Parameter::SPC_COLOR_SPECULAR) + { + mInputToGLStatesMap[paramName] = "gl_SecondaryColor"; + } + else + { + os << "uniform \t "; + os << mGpuConstTypeMap[pParam->getType()]; + os << "\t"; + os << paramName; + os << ";" << std::endl; + } + } } //----------------------------------------------------------------------- void GLSLProgramWriter::writeOutParameters(std::ostream& os, Function* function, GpuProgramType gpuType) { - const ShaderParameterList& outParams = function->getOutputParameters(); - - ShaderParameterConstIterator itParam = outParams.begin(); - ShaderParameterConstIterator itParamEnd = outParams.end(); - - for ( ; itParam != itParamEnd; ++itParam) - { - ParameterPtr pParam = *itParam; - - if(gpuType == GPT_VERTEX_PROGRAM) - { - // GLSL vertex program has to write always gl_Position (but this is also deprecated after version 130) - if(pParam->getContent() == Parameter::SPC_POSITION_PROJECTIVE_SPACE) - { - mInputToGLStatesMap[pParam->getName()] = "gl_Position"; - } - else - { - // After GLSL 1.20 varying is deprecated - if(mGLSLVersion <= 120) - { - os << "varying\t"; - } - else - { - os << "out\t"; - } - - os << mGpuConstTypeMap[pParam->getType()]; - os << "\t"; - os << pParam->getName(); - if (pParam->isArray() == true) - { - os << "[" << pParam->getSize() << "]"; - } - os << ";" << std::endl; - } - } - else if(gpuType == GPT_FRAGMENT_PROGRAM && - pParam->getSemantic() == Parameter::SPS_COLOR) - { - // GLSL fragment program has to write always gl_FragColor (but this is also deprecated after version 130) + const ShaderParameterList& outParams = function->getOutputParameters(); + + ShaderParameterConstIterator itParam = outParams.begin(); + ShaderParameterConstIterator itParamEnd = outParams.end(); + + for ( ; itParam != itParamEnd; ++itParam) + { + ParameterPtr pParam = *itParam; + + if(gpuType == GPT_VERTEX_PROGRAM) + { + // GLSL vertex program has to write always gl_Position (but this is also deprecated after version 130) + if(pParam->getContent() == Parameter::SPC_POSITION_PROJECTIVE_SPACE) + { + mInputToGLStatesMap[pParam->getName()] = "gl_Position"; + } + else + { + // After GLSL 1.20 varying is deprecated + if(mGLSLVersion <= 120) + { + os << "varying\t"; + } + else + { + os << "out\t"; + } + + os << mGpuConstTypeMap[pParam->getType()]; + os << "\t"; + os << pParam->getName(); + if (pParam->isArray() == true) + { + os << "[" << pParam->getSize() << "]"; + } + os << ";" << std::endl; + } + } + else if(gpuType == GPT_FRAGMENT_PROGRAM && + pParam->getSemantic() == Parameter::SPS_COLOR) + { + // GLSL fragment program has to write always gl_FragColor (but this is also deprecated after version 130) // Always add gl_FragColor as an output. The name is for compatibility. if(mGLSLVersion <= 130) { @@ -656,13 +656,13 @@ void GLSLProgramWriter::writeOutParameters(std::ostream& os, Function* function, //----------------------------------------------------------------------- void GLSLProgramWriter::writeLocalParameter(std::ostream& os, ParameterPtr parameter) { - os << mGpuConstTypeMap[parameter->getType()]; - os << "\t"; - os << parameter->getName(); - if (parameter->isArray() == true) - { - os << "[" << parameter->getSize() << "]"; - } + os << mGpuConstTypeMap[parameter->getType()]; + os << "\t"; + os << parameter->getName(); + if (parameter->isArray() == true) + { + os << "[" << parameter->getSize() << "]"; + } } //----------------------------------------------------------------------- } diff --git a/Components/RTShaderSystem/src/OgreShaderGenerator.cpp b/Components/RTShaderSystem/src/OgreShaderGenerator.cpp index cccdb8c0f9c..22d0f4e483b 100644 --- a/Components/RTShaderSystem/src/OgreShaderGenerator.cpp +++ b/Components/RTShaderSystem/src/OgreShaderGenerator.cpp @@ -54,22 +54,22 @@ RTShader::ShaderGenerator* Singleton::msSingleton = 0 namespace RTShader { -String ShaderGenerator::DEFAULT_SCHEME_NAME = "ShaderGeneratorDefaultScheme"; -String GENERATED_SHADERS_GROUP_NAME = "ShaderGeneratorResourceGroup"; -String ShaderGenerator::SGPass::UserKey = "SGPass"; -String ShaderGenerator::SGTechnique::UserKey = "SGTechnique"; +String ShaderGenerator::DEFAULT_SCHEME_NAME = "ShaderGeneratorDefaultScheme"; +String GENERATED_SHADERS_GROUP_NAME = "ShaderGeneratorResourceGroup"; +String ShaderGenerator::SGPass::UserKey = "SGPass"; +String ShaderGenerator::SGTechnique::UserKey = "SGTechnique"; //----------------------------------------------------------------------- ShaderGenerator* ShaderGenerator::getSingletonPtr() { - return msSingleton; + return msSingleton; } //----------------------------------------------------------------------- ShaderGenerator& ShaderGenerator::getSingleton() { - assert( msSingleton ); - return ( *msSingleton ); + assert( msSingleton ); + return ( *msSingleton ); } //----------------------------------------------------------------------------- @@ -79,66 +79,66 @@ ShaderGenerator::ShaderGenerator() : mFSLayer(0), mFFPRenderStateBuilder(NULL),mActiveViewportValid(false), mVSOutputCompactPolicy(VSOCP_LOW), mCreateShaderOverProgrammablePass(false), mIsFinalizing(false) { - mLightCount[0] = 0; - mLightCount[1] = 0; - mLightCount[2] = 0; - - HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton(); - - if (hmgr.isLanguageSupported("glsles")) - { - mShaderLanguage = "glsles"; - } - else if (hmgr.isLanguageSupported("cg")) - { - mShaderLanguage = "cg"; - } - else if (hmgr.isLanguageSupported("glsl")) - { - mShaderLanguage = "glsl"; - } - else if (hmgr.isLanguageSupported("hlsl")) - { - mShaderLanguage = "hlsl"; - } - else - { - // ASSAF: This is disabled for now - to stop an exception on the iOS - // when running with the OpenGL ES 1.x that doesn't support shaders... - /* - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "ShaderGenerator creation error: None of the profiles is supported.", - "ShaderGenerator::ShaderGenerator" ); - - */ - mShaderLanguage = "cg"; // HACK for now - } - - setVertexShaderProfiles("gpu_vp gp4vp vp40 vp30 arbvp1 vs_4_0 vs_4_0_level_9_3 vs_4_0_level_9_1 vs_3_0 vs_2_x vs_2_a vs_2_0 vs_1_1"); - setFragmentShaderProfiles("ps_4_0 ps_4_0_level_9_3 ps_4_0_level_9_1 ps_3_x ps_3_0 fp40 fp30 fp20 arbfp1 ps_2_x ps_2_a ps_2_b ps_2_0 ps_1_4 ps_1_3 ps_1_2 ps_1_1"); + mLightCount[0] = 0; + mLightCount[1] = 0; + mLightCount[2] = 0; + + HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton(); + + if (hmgr.isLanguageSupported("glsles")) + { + mShaderLanguage = "glsles"; + } + else if (hmgr.isLanguageSupported("cg")) + { + mShaderLanguage = "cg"; + } + else if (hmgr.isLanguageSupported("glsl")) + { + mShaderLanguage = "glsl"; + } + else if (hmgr.isLanguageSupported("hlsl")) + { + mShaderLanguage = "hlsl"; + } + else + { + // ASSAF: This is disabled for now - to stop an exception on the iOS + // when running with the OpenGL ES 1.x that doesn't support shaders... + /* + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "ShaderGenerator creation error: None of the profiles is supported.", + "ShaderGenerator::ShaderGenerator" ); + + */ + mShaderLanguage = "cg"; // HACK for now + } + + setVertexShaderProfiles("gpu_vp gp4vp vp40 vp30 arbvp1 vs_4_0 vs_4_0_level_9_3 vs_4_0_level_9_1 vs_3_0 vs_2_x vs_2_a vs_2_0 vs_1_1"); + setFragmentShaderProfiles("ps_4_0 ps_4_0_level_9_3 ps_4_0_level_9_1 ps_3_x ps_3_0 fp40 fp30 fp20 arbfp1 ps_2_x ps_2_a ps_2_b ps_2_0 ps_1_4 ps_1_3 ps_1_2 ps_1_1"); } //----------------------------------------------------------------------------- ShaderGenerator::~ShaderGenerator() { - + } //----------------------------------------------------------------------------- bool ShaderGenerator::initialize() { - if (msSingleton == NULL) - { - msSingleton = OGRE_NEW ShaderGenerator; - if (false == msSingleton->_initialize()) - { - OGRE_DELETE msSingleton; - msSingleton = NULL; - return false; - } - } - - return true; + if (msSingleton == NULL) + { + msSingleton = OGRE_NEW ShaderGenerator; + if (false == msSingleton->_initialize()) + { + OGRE_DELETE msSingleton; + msSingleton = NULL; + return false; + } + } + + return true; } //----------------------------------------------------------------------------- @@ -146,32 +146,32 @@ bool ShaderGenerator::_initialize() { OGRE_LOCK_AUTO_MUTEX; - // Allocate program writer manager. - mProgramWriterManager = OGRE_NEW ProgramWriterManager; + // Allocate program writer manager. + mProgramWriterManager = OGRE_NEW ProgramWriterManager; - // Allocate program manager. - mProgramManager = OGRE_NEW ProgramManager; + // Allocate program manager. + mProgramManager = OGRE_NEW ProgramManager; - // Allocate and initialize FFP render state builder. + // Allocate and initialize FFP render state builder. #ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS - mFFPRenderStateBuilder = OGRE_NEW FFPRenderStateBuilder; - if (false == mFFPRenderStateBuilder->initialize()) - return false; + mFFPRenderStateBuilder = OGRE_NEW FFPRenderStateBuilder; + if (false == mFFPRenderStateBuilder->initialize()) + return false; #endif - // Create extensions factories. - createSubRenderStateExFactories(); + // Create extensions factories. + createSubRenderStateExFactories(); - // Allocate script translator manager. - mScriptTranslatorManager = OGRE_NEW SGScriptTranslatorManager(this); - ScriptCompilerManager::getSingleton().addTranslatorManager(mScriptTranslatorManager); + // Allocate script translator manager. + mScriptTranslatorManager = OGRE_NEW SGScriptTranslatorManager(this); + ScriptCompilerManager::getSingleton().addTranslatorManager(mScriptTranslatorManager); - addCustomScriptTranslator("rtshader_system", &mCoreScriptTranslator); + addCustomScriptTranslator("rtshader_system", &mCoreScriptTranslator); - // Create the default scheme. - createScheme(DEFAULT_SCHEME_NAME); + // Create the default scheme. + createScheme(DEFAULT_SCHEME_NAME); - return true; + return true; } @@ -182,7 +182,7 @@ void ShaderGenerator::createSubRenderStateExFactories() #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS OGRE_LOCK_AUTO_MUTEX; - SubRenderStateFactory* curFactory; + SubRenderStateFactory* curFactory; // check if we are running an old shader level in d3d11 bool d3d11AndLowProfile = ( (GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0_level_9_1") || @@ -190,142 +190,142 @@ void ShaderGenerator::createSubRenderStateExFactories() && !GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0")); if(!d3d11AndLowProfile) { - curFactory = OGRE_NEW PerPixelLightingFactory; + curFactory = OGRE_NEW PerPixelLightingFactory; addSubRenderStateFactory(curFactory); mSubRenderStateExFactories[curFactory->getType()] = (curFactory); - curFactory = OGRE_NEW NormalMapLightingFactory; + curFactory = OGRE_NEW NormalMapLightingFactory; addSubRenderStateFactory(curFactory); mSubRenderStateExFactories[curFactory->getType()] = (curFactory); - curFactory = OGRE_NEW IntegratedPSSM3Factory; + curFactory = OGRE_NEW IntegratedPSSM3Factory; addSubRenderStateFactory(curFactory); mSubRenderStateExFactories[curFactory->getType()] = (curFactory); - curFactory = OGRE_NEW LayeredBlendingFactory; + curFactory = OGRE_NEW LayeredBlendingFactory; addSubRenderStateFactory(curFactory); mSubRenderStateExFactories[curFactory->getType()] = (curFactory); - curFactory = OGRE_NEW HardwareSkinningFactory; + curFactory = OGRE_NEW HardwareSkinningFactory; addSubRenderStateFactory(curFactory); mSubRenderStateExFactories[curFactory->getType()] = (curFactory); } - curFactory = OGRE_NEW TextureAtlasSamplerFactory; - addSubRenderStateFactory(curFactory); - mSubRenderStateExFactories[curFactory->getType()] = (curFactory); - - curFactory = OGRE_NEW TriplanarTexturingFactory; - addSubRenderStateFactory(curFactory); - mSubRenderStateExFactories[curFactory->getType()] = (curFactory); + curFactory = OGRE_NEW TextureAtlasSamplerFactory; + addSubRenderStateFactory(curFactory); + mSubRenderStateExFactories[curFactory->getType()] = (curFactory); + + curFactory = OGRE_NEW TriplanarTexturingFactory; + addSubRenderStateFactory(curFactory); + mSubRenderStateExFactories[curFactory->getType()] = (curFactory); #endif } //----------------------------------------------------------------------------- void ShaderGenerator::destroy() { - if (msSingleton != NULL) - { - msSingleton->_destroy(); + if (msSingleton != NULL) + { + msSingleton->_destroy(); - OGRE_DELETE msSingleton; - msSingleton = NULL; - } + OGRE_DELETE msSingleton; + msSingleton = NULL; + } } //----------------------------------------------------------------------------- void ShaderGenerator::_destroy() { OGRE_LOCK_AUTO_MUTEX; - + mIsFinalizing = true; - - // Delete technique entries. - for (SGTechniqueMapIterator itTech = mTechniqueEntriesMap.begin(); itTech != mTechniqueEntriesMap.end(); ++itTech) - { - OGRE_DELETE (itTech->second); - } - mTechniqueEntriesMap.clear(); - - // Delete material entries. - for (SGMaterialIterator itMat = mMaterialEntriesMap.begin(); itMat != mMaterialEntriesMap.end(); ++itMat) - { - OGRE_DELETE (itMat->second); - } - mMaterialEntriesMap.clear(); - - // Delete scheme entries. - for (SGSchemeIterator itScheme = mSchemeEntriesMap.begin(); itScheme != mSchemeEntriesMap.end(); ++itScheme) - { - OGRE_DELETE (itScheme->second); - } - mSchemeEntriesMap.clear(); - - // Destroy extensions factories. - destroySubRenderStateExFactories(); + + // Delete technique entries. + for (SGTechniqueMapIterator itTech = mTechniqueEntriesMap.begin(); itTech != mTechniqueEntriesMap.end(); ++itTech) + { + OGRE_DELETE (itTech->second); + } + mTechniqueEntriesMap.clear(); + + // Delete material entries. + for (SGMaterialIterator itMat = mMaterialEntriesMap.begin(); itMat != mMaterialEntriesMap.end(); ++itMat) + { + OGRE_DELETE (itMat->second); + } + mMaterialEntriesMap.clear(); + + // Delete scheme entries. + for (SGSchemeIterator itScheme = mSchemeEntriesMap.begin(); itScheme != mSchemeEntriesMap.end(); ++itScheme) + { + OGRE_DELETE (itScheme->second); + } + mSchemeEntriesMap.clear(); + + // Destroy extensions factories. + destroySubRenderStateExFactories(); #ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS - // Delete FFP Emulator. - if (mFFPRenderStateBuilder != NULL) - { - mFFPRenderStateBuilder->destroy(); - OGRE_DELETE mFFPRenderStateBuilder; - mFFPRenderStateBuilder = NULL; - } + // Delete FFP Emulator. + if (mFFPRenderStateBuilder != NULL) + { + mFFPRenderStateBuilder->destroy(); + OGRE_DELETE mFFPRenderStateBuilder; + mFFPRenderStateBuilder = NULL; + } #endif - // Delete Program manager. - if (mProgramManager != NULL) - { - OGRE_DELETE mProgramManager; - mProgramManager = NULL; - } - - // Delete Program writer manager. - if(mProgramWriterManager != NULL) - { - OGRE_DELETE mProgramWriterManager; - mProgramWriterManager = NULL; - } - - removeCustomScriptTranslator("rtshader_system"); - - // Delete script translator manager. - if (mScriptTranslatorManager != NULL) - { - ScriptCompilerManager::getSingleton().removeTranslatorManager(mScriptTranslatorManager); - OGRE_DELETE mScriptTranslatorManager; - mScriptTranslatorManager = NULL; - } - - // Delete material Serializer listener. - if (mMaterialSerializerListener != NULL) - { - OGRE_DELETE mMaterialSerializerListener; - mMaterialSerializerListener = NULL; - } - - // Remove all scene managers. - while (mSceneManagerMap.empty() == false) - { - SceneManagerIterator itSceneMgr = mSceneManagerMap.begin(); - - removeSceneManager(itSceneMgr->second); - } - - // Delete render object listener. - if (mRenderObjectListener != NULL) - { - OGRE_DELETE mRenderObjectListener; - mRenderObjectListener = NULL; - } - - // Delete scene manager listener. - if (mSceneManagerListener != NULL) - { - OGRE_DELETE mSceneManagerListener; - mSceneManagerListener = NULL; - } + // Delete Program manager. + if (mProgramManager != NULL) + { + OGRE_DELETE mProgramManager; + mProgramManager = NULL; + } + + // Delete Program writer manager. + if(mProgramWriterManager != NULL) + { + OGRE_DELETE mProgramWriterManager; + mProgramWriterManager = NULL; + } + + removeCustomScriptTranslator("rtshader_system"); + + // Delete script translator manager. + if (mScriptTranslatorManager != NULL) + { + ScriptCompilerManager::getSingleton().removeTranslatorManager(mScriptTranslatorManager); + OGRE_DELETE mScriptTranslatorManager; + mScriptTranslatorManager = NULL; + } + + // Delete material Serializer listener. + if (mMaterialSerializerListener != NULL) + { + OGRE_DELETE mMaterialSerializerListener; + mMaterialSerializerListener = NULL; + } + + // Remove all scene managers. + while (mSceneManagerMap.empty() == false) + { + SceneManagerIterator itSceneMgr = mSceneManagerMap.begin(); + + removeSceneManager(itSceneMgr->second); + } + + // Delete render object listener. + if (mRenderObjectListener != NULL) + { + OGRE_DELETE mRenderObjectListener; + mRenderObjectListener = NULL; + } + + // Delete scene manager listener. + if (mSceneManagerListener != NULL) + { + OGRE_DELETE mSceneManagerListener; + mSceneManagerListener = NULL; + } } //----------------------------------------------------------------------------- @@ -333,14 +333,14 @@ void ShaderGenerator::destroySubRenderStateExFactories() { OGRE_LOCK_AUTO_MUTEX; - SubRenderStateFactoryIterator it; + SubRenderStateFactoryIterator it; - for (it = mSubRenderStateExFactories.begin(); it != mSubRenderStateExFactories.end(); ++it) - { - removeSubRenderStateFactory(it->second); - OGRE_DELETE it->second; - } - mSubRenderStateExFactories.clear(); + for (it = mSubRenderStateExFactories.begin(); it != mSubRenderStateExFactories.end(); ++it) + { + removeSubRenderStateFactory(it->second); + OGRE_DELETE it->second; + } + mSubRenderStateExFactories.clear(); } //----------------------------------------------------------------------------- @@ -348,53 +348,53 @@ void ShaderGenerator::addSubRenderStateFactory(SubRenderStateFactory* factory) { OGRE_LOCK_AUTO_MUTEX; - SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.find(factory->getType()); + SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.find(factory->getType()); - if (itFind != mSubRenderStateFactories.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "A factory of type '" + factory->getType() + "' already exists.", - "ShaderGenerator::addSubRenderStateFactory"); - } - - mSubRenderStateFactories[factory->getType()] = factory; + if (itFind != mSubRenderStateFactories.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "A factory of type '" + factory->getType() + "' already exists.", + "ShaderGenerator::addSubRenderStateFactory"); + } + + mSubRenderStateFactories[factory->getType()] = factory; } //----------------------------------------------------------------------------- size_t ShaderGenerator::getNumSubRenderStateFactories() const { - return mSubRenderStateFactories.size(); + return mSubRenderStateFactories.size(); } //----------------------------------------------------------------------------- SubRenderStateFactory* ShaderGenerator::getSubRenderStateFactory(size_t index) { - { + { OGRE_LOCK_AUTO_MUTEX; - SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.begin(); - for(; index != 0 && itFind != mSubRenderStateFactories.end(); --index , ++itFind); + SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.begin(); + for(; index != 0 && itFind != mSubRenderStateFactories.end(); --index , ++itFind); - if (itFind != mSubRenderStateFactories.end()) - { - return itFind->second; - } - } + if (itFind != mSubRenderStateFactories.end()) + { + return itFind->second; + } + } - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "A factory on index " + StringConverter::toString(index) + " does not exist.", - "ShaderGenerator::addSubRenderStateFactory"); - - return NULL; + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "A factory on index " + StringConverter::toString(index) + " does not exist.", + "ShaderGenerator::addSubRenderStateFactory"); + + return NULL; } //----------------------------------------------------------------------------- SubRenderStateFactory* ShaderGenerator::getSubRenderStateFactory(const String& type) { OGRE_LOCK_AUTO_MUTEX; - SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.find(type); - return (itFind != mSubRenderStateFactories.end()) ? itFind->second : NULL; + SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.find(type); + return (itFind != mSubRenderStateFactories.end()) ? itFind->second : NULL; } //----------------------------------------------------------------------------- @@ -402,29 +402,29 @@ void ShaderGenerator::removeSubRenderStateFactory(SubRenderStateFactory* factory { OGRE_LOCK_AUTO_MUTEX; - SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.find(factory->getType()); + SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.find(factory->getType()); - if (itFind != mSubRenderStateFactories.end()) - mSubRenderStateFactories.erase(itFind); + if (itFind != mSubRenderStateFactories.end()) + mSubRenderStateFactories.erase(itFind); } //----------------------------------------------------------------------------- -SubRenderState* ShaderGenerator::createSubRenderState(const String& type) +SubRenderState* ShaderGenerator::createSubRenderState(const String& type) { OGRE_LOCK_AUTO_MUTEX; - SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.find(type); + SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.find(type); - if (itFind != mSubRenderStateFactories.end()) - return itFind->second->createInstance(); + if (itFind != mSubRenderStateFactories.end()) + return itFind->second->createInstance(); - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "A factory of type '" + type + "' doesn't exists.", - "ShaderGenerator::createSubRenderState"); + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "A factory of type '" + type + "' doesn't exists.", + "ShaderGenerator::createSubRenderState"); - return NULL; + return NULL; } //----------------------------------------------------------------------------- @@ -432,55 +432,55 @@ void ShaderGenerator::destroySubRenderState(SubRenderState* subRenderState) { OGRE_LOCK_AUTO_MUTEX; - SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.find(subRenderState->getType()); + SubRenderStateFactoryIterator itFind = mSubRenderStateFactories.find(subRenderState->getType()); - if (itFind != mSubRenderStateFactories.end()) - { - itFind->second->destroyInstance(subRenderState); - } + if (itFind != mSubRenderStateFactories.end()) + { + itFind->second->destroyInstance(subRenderState); + } } //----------------------------------------------------------------------------- -SubRenderState* ShaderGenerator::createSubRenderState(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* ShaderGenerator::createSubRenderState(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { OGRE_LOCK_AUTO_MUTEX; - SubRenderStateFactoryIterator it = mSubRenderStateFactories.begin(); - SubRenderStateFactoryIterator itEnd = mSubRenderStateFactories.end(); - SubRenderState* subRenderState = NULL; + SubRenderStateFactoryIterator it = mSubRenderStateFactories.begin(); + SubRenderStateFactoryIterator itEnd = mSubRenderStateFactories.end(); + SubRenderState* subRenderState = NULL; - while (it != itEnd) - { - subRenderState = it->second->createInstance(compiler, prop, pass, translator); - if (subRenderState != NULL) - break; - ++it; - } + while (it != itEnd) + { + subRenderState = it->second->createInstance(compiler, prop, pass, translator); + if (subRenderState != NULL) + break; + ++it; + } - return subRenderState; + return subRenderState; } //----------------------------------------------------------------------------- -SubRenderState* ShaderGenerator::createSubRenderState(ScriptCompiler* compiler, - PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator) +SubRenderState* ShaderGenerator::createSubRenderState(ScriptCompiler* compiler, + PropertyAbstractNode* prop, TextureUnitState* texState, SGScriptTranslator* translator) { OGRE_LOCK_AUTO_MUTEX; - SubRenderStateFactoryIterator it = mSubRenderStateFactories.begin(); - SubRenderStateFactoryIterator itEnd = mSubRenderStateFactories.end(); - SubRenderState* subRenderState = NULL; + SubRenderStateFactoryIterator it = mSubRenderStateFactories.begin(); + SubRenderStateFactoryIterator itEnd = mSubRenderStateFactories.end(); + SubRenderState* subRenderState = NULL; - while (it != itEnd) - { - subRenderState = it->second->createInstance(compiler, prop, texState, translator); - if (subRenderState != NULL) - break; - ++it; - } + while (it != itEnd) + { + subRenderState = it->second->createInstance(compiler, prop, texState, translator); + if (subRenderState != NULL) + break; + ++it; + } - return subRenderState; + return subRenderState; } //----------------------------------------------------------------------------- @@ -488,14 +488,14 @@ void ShaderGenerator::createScheme(const String& schemeName) { OGRE_LOCK_AUTO_MUTEX; - SGSchemeIterator itFind = mSchemeEntriesMap.find(schemeName); - SGScheme* schemeEntry = NULL; + SGSchemeIterator itFind = mSchemeEntriesMap.find(schemeName); + SGScheme* schemeEntry = NULL; - if (itFind == mSchemeEntriesMap.end()) - { - schemeEntry = OGRE_NEW SGScheme(schemeName); - mSchemeEntriesMap[schemeName] = schemeEntry; - } + if (itFind == mSchemeEntriesMap.end()) + { + schemeEntry = OGRE_NEW SGScheme(schemeName); + mSchemeEntriesMap[schemeName] = schemeEntry; + } } //----------------------------------------------------------------------------- @@ -503,16 +503,16 @@ RenderState* ShaderGenerator::getRenderState(const String& schemeName) { OGRE_LOCK_AUTO_MUTEX; - SGSchemeIterator itFind = mSchemeEntriesMap.find(schemeName); - - if (itFind == mSchemeEntriesMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "A scheme named'" + schemeName + "' doesn't exists.", - "ShaderGenerator::getRenderState"); - } - - return itFind->second->getRenderState(); + SGSchemeIterator itFind = mSchemeEntriesMap.find(schemeName); + + if (itFind == mSchemeEntriesMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "A scheme named'" + schemeName + "' doesn't exists.", + "ShaderGenerator::getRenderState"); + } + + return itFind->second->getRenderState(); } //----------------------------------------------------------------------------- @@ -520,15 +520,15 @@ bool ShaderGenerator::hasRenderState(const String& schemeName) const { OGRE_LOCK_AUTO_MUTEX; - SGSchemeConstIterator itFind = mSchemeEntriesMap.find(schemeName); - return itFind != mSchemeEntriesMap.end(); + SGSchemeConstIterator itFind = mSchemeEntriesMap.find(schemeName); + return itFind != mSchemeEntriesMap.end(); } //----------------------------------------------------------------------------- ShaderGenerator::RenderStateCreateOrRetrieveResult ShaderGenerator::createOrRetrieveRenderState(const String& schemeName) { - SchemeCreateOrRetrieveResult res = createOrRetrieveScheme(schemeName); - return RenderStateCreateOrRetrieveResult(res.first->getRenderState(),res.second); + SchemeCreateOrRetrieveResult res = createOrRetrieveScheme(schemeName); + return RenderStateCreateOrRetrieveResult(res.first->getRenderState(),res.second); } //----------------------------------------------------------------------------- @@ -536,331 +536,331 @@ ShaderGenerator::SchemeCreateOrRetrieveResult ShaderGenerator::createOrRetrieveS { OGRE_LOCK_AUTO_MUTEX; - bool wasCreated = false; - SGSchemeIterator itScheme = mSchemeEntriesMap.find(schemeName); - SGScheme* schemeEntry = NULL; + bool wasCreated = false; + SGSchemeIterator itScheme = mSchemeEntriesMap.find(schemeName); + SGScheme* schemeEntry = NULL; - if (itScheme == mSchemeEntriesMap.end()) - { - schemeEntry = OGRE_NEW SGScheme(schemeName); - mSchemeEntriesMap.insert(SGSchemeMap::value_type(schemeName, schemeEntry)); - wasCreated = true; - } - else - { - schemeEntry = itScheme->second; - } + if (itScheme == mSchemeEntriesMap.end()) + { + schemeEntry = OGRE_NEW SGScheme(schemeName); + mSchemeEntriesMap.insert(SGSchemeMap::value_type(schemeName, schemeEntry)); + wasCreated = true; + } + else + { + schemeEntry = itScheme->second; + } - return SchemeCreateOrRetrieveResult(schemeEntry, wasCreated); + return SchemeCreateOrRetrieveResult(schemeEntry, wasCreated); } //----------------------------------------------------------------------------- RenderState* ShaderGenerator::getRenderState(const String& schemeName, - const String& materialName, - unsigned short passIndex) + const String& materialName, + unsigned short passIndex) { - return getRenderState(schemeName, materialName, - ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, passIndex); + return getRenderState(schemeName, materialName, + ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, passIndex); } //----------------------------------------------------------------------------- RenderState* ShaderGenerator::getRenderState(const String& schemeName, - const String& materialName, - const String& groupName, - unsigned short passIndex) + const String& materialName, + const String& groupName, + unsigned short passIndex) { OGRE_LOCK_AUTO_MUTEX; - SGSchemeIterator itFind = mSchemeEntriesMap.find(schemeName); + SGSchemeIterator itFind = mSchemeEntriesMap.find(schemeName); - if (itFind == mSchemeEntriesMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "A scheme named'" + schemeName + "' doesn't exists.", - "ShaderGenerator::getRenderState"); - } + if (itFind == mSchemeEntriesMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "A scheme named'" + schemeName + "' doesn't exists.", + "ShaderGenerator::getRenderState"); + } - return itFind->second->getRenderState(materialName, groupName, passIndex); + return itFind->second->getRenderState(materialName, groupName, passIndex); } //----------------------------------------------------------------------------- void ShaderGenerator::addSceneManager(SceneManager* sceneMgr) { - // Make sure this scene manager not exists in the map. - SceneManagerIterator itFind = mSceneManagerMap.find(sceneMgr->getName()); - - if (itFind != mSceneManagerMap.end()) - return; + // Make sure this scene manager not exists in the map. + SceneManagerIterator itFind = mSceneManagerMap.find(sceneMgr->getName()); + + if (itFind != mSceneManagerMap.end()) + return; - if (mRenderObjectListener == NULL) - mRenderObjectListener = OGRE_NEW SGRenderObjectListener(this); - - sceneMgr->addRenderObjectListener(mRenderObjectListener); + if (mRenderObjectListener == NULL) + mRenderObjectListener = OGRE_NEW SGRenderObjectListener(this); + + sceneMgr->addRenderObjectListener(mRenderObjectListener); - if (mSceneManagerListener == NULL) - mSceneManagerListener = OGRE_NEW SGSceneManagerListener(this); - - sceneMgr->addListener(mSceneManagerListener); + if (mSceneManagerListener == NULL) + mSceneManagerListener = OGRE_NEW SGSceneManagerListener(this); + + sceneMgr->addListener(mSceneManagerListener); - mSceneManagerMap[sceneMgr->getName()] = sceneMgr; + mSceneManagerMap[sceneMgr->getName()] = sceneMgr; - // Update the active scene manager. - if (mActiveSceneMgr == NULL) - mActiveSceneMgr = sceneMgr; + // Update the active scene manager. + if (mActiveSceneMgr == NULL) + mActiveSceneMgr = sceneMgr; } //----------------------------------------------------------------------------- void ShaderGenerator::removeSceneManager(SceneManager* sceneMgr) { - // Make sure this scene manager exists in the map. - SceneManagerIterator itFind = mSceneManagerMap.find(sceneMgr->getName()); - - if (itFind != mSceneManagerMap.end()) - { - itFind->second->removeRenderObjectListener(mRenderObjectListener); - itFind->second->removeListener(mSceneManagerListener); + // Make sure this scene manager exists in the map. + SceneManagerIterator itFind = mSceneManagerMap.find(sceneMgr->getName()); + + if (itFind != mSceneManagerMap.end()) + { + itFind->second->removeRenderObjectListener(mRenderObjectListener); + itFind->second->removeListener(mSceneManagerListener); - mSceneManagerMap.erase(itFind); + mSceneManagerMap.erase(itFind); - // Update the active scene manager. - if (mActiveSceneMgr == sceneMgr) - mActiveSceneMgr = NULL; - } + // Update the active scene manager. + if (mActiveSceneMgr == sceneMgr) + mActiveSceneMgr = NULL; + } } //----------------------------------------------------------------------------- SceneManager* ShaderGenerator::getActiveSceneManager() { - return mActiveSceneMgr; + return mActiveSceneMgr; } //----------------------------------------------------------------------------- void ShaderGenerator::_setActiveSceneManager(SceneManager* sceneManager) { - mActiveViewportValid &= (mActiveSceneMgr == sceneManager); - mActiveSceneMgr = sceneManager; + mActiveViewportValid &= (mActiveSceneMgr == sceneManager); + mActiveSceneMgr = sceneManager; } //----------------------------------------------------------------------------- void ShaderGenerator::setVertexShaderProfiles(const String& vertexShaderProfiles) { - mVertexShaderProfiles = vertexShaderProfiles; - mVertexShaderProfilesList = StringUtil::split(vertexShaderProfiles); + mVertexShaderProfiles = vertexShaderProfiles; + mVertexShaderProfilesList = StringUtil::split(vertexShaderProfiles); } //----------------------------------------------------------------------------- void ShaderGenerator::setFragmentShaderProfiles(const String& fragmentShaderProfiles) { - mFragmentShaderProfiles = fragmentShaderProfiles; - mFragmentShaderProfilesList = StringUtil::split(fragmentShaderProfiles); + mFragmentShaderProfiles = fragmentShaderProfiles; + mFragmentShaderProfilesList = StringUtil::split(fragmentShaderProfiles); } //----------------------------------------------------------------------------- bool ShaderGenerator::hasShaderBasedTechnique(const String& materialName, - const String& srcTechniqueSchemeName, - const String& dstTechniqueSchemeName) const + const String& srcTechniqueSchemeName, + const String& dstTechniqueSchemeName) const { - return hasShaderBasedTechnique(materialName, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, - srcTechniqueSchemeName, dstTechniqueSchemeName); + return hasShaderBasedTechnique(materialName, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, + srcTechniqueSchemeName, dstTechniqueSchemeName); } //----------------------------------------------------------------------------- bool ShaderGenerator::hasShaderBasedTechnique(const String& materialName, - const String& groupName, - const String& srcTechniqueSchemeName, - const String& dstTechniqueSchemeName) const + const String& groupName, + const String& srcTechniqueSchemeName, + const String& dstTechniqueSchemeName) const { OGRE_LOCK_AUTO_MUTEX; - // Make sure material exists; - if (false == MaterialManager::getSingleton().resourceExists(materialName)) - return false; - - - SGMaterialConstIterator itMatEntry = findMaterialEntryIt(materialName, groupName); - - // Check if technique already created. - if (itMatEntry != mMaterialEntriesMap.end()) - { - const SGTechniqueList& techniqueEntires = itMatEntry->second->getTechniqueList(); - SGTechniqueConstIterator itTechEntry = techniqueEntires.begin(); - - for (; itTechEntry != techniqueEntires.end(); ++itTechEntry) - { - // Check requested mapping already exists. - if ((*itTechEntry)->getSourceTechnique()->getSchemeName() == srcTechniqueSchemeName && - (*itTechEntry)->getDestinationTechniqueSchemeName() == dstTechniqueSchemeName) - { - return true; - } - } - } - return false; + // Make sure material exists; + if (false == MaterialManager::getSingleton().resourceExists(materialName)) + return false; + + + SGMaterialConstIterator itMatEntry = findMaterialEntryIt(materialName, groupName); + + // Check if technique already created. + if (itMatEntry != mMaterialEntriesMap.end()) + { + const SGTechniqueList& techniqueEntires = itMatEntry->second->getTechniqueList(); + SGTechniqueConstIterator itTechEntry = techniqueEntires.begin(); + + for (; itTechEntry != techniqueEntires.end(); ++itTechEntry) + { + // Check requested mapping already exists. + if ((*itTechEntry)->getSourceTechnique()->getSchemeName() == srcTechniqueSchemeName && + (*itTechEntry)->getDestinationTechniqueSchemeName() == dstTechniqueSchemeName) + { + return true; + } + } + } + return false; } //----------------------------------------------------------------------------- bool ShaderGenerator::createShaderBasedTechnique(const String& materialName, - const String& srcTechniqueSchemeName, - const String& dstTechniqueSchemeName, - bool overProgrammable) + const String& srcTechniqueSchemeName, + const String& dstTechniqueSchemeName, + bool overProgrammable) { - return createShaderBasedTechnique(materialName, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, - srcTechniqueSchemeName, dstTechniqueSchemeName, overProgrammable); + return createShaderBasedTechnique(materialName, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, + srcTechniqueSchemeName, dstTechniqueSchemeName, overProgrammable); } //----------------------------------------------------------------------------- bool ShaderGenerator::createShaderBasedTechnique(const String& materialName, - const String& groupName, - const String& srcTechniqueSchemeName, - const String& dstTechniqueSchemeName, - bool overProgrammable) + const String& groupName, + const String& srcTechniqueSchemeName, + const String& dstTechniqueSchemeName, + bool overProgrammable) { OGRE_LOCK_AUTO_MUTEX; - // Make sure material exists. - MaterialPtr srcMat = MaterialManager::getSingleton().getByName(materialName, groupName); - if (srcMat.isNull() == true) - return false; - - // Update group name in case it is AUTODETECT_RESOURCE_GROUP_NAME - const String& trueGroupName = srcMat->getGroup(); - - // Case the requested material belongs to different group and it is not AUTODETECT_RESOURCE_GROUP_NAME. - if (trueGroupName != groupName && - groupName != ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) - { - return false; - } - - SGMaterialIterator itMatEntry = findMaterialEntryIt(materialName, trueGroupName); - - // Check if technique already created. - if (itMatEntry != mMaterialEntriesMap.end()) - { - const SGTechniqueList& techniqueEntires = itMatEntry->second->getTechniqueList(); - SGTechniqueConstIterator itTechEntry = techniqueEntires.begin(); - - for (; itTechEntry != techniqueEntires.end(); ++itTechEntry) - { - // Case the requested mapping already exists. - if ((*itTechEntry)->getSourceTechnique()->getSchemeName() == srcTechniqueSchemeName && - (*itTechEntry)->getDestinationTechniqueSchemeName() == dstTechniqueSchemeName) - { - return true; - } - - - // Case a shader based technique with the same scheme name already defined based - // on different source technique. - // This state might lead to conflicts during shader generation - we prevent it by returning false here. - else if ((*itTechEntry)->getDestinationTechniqueSchemeName() == dstTechniqueSchemeName) - { - return false; - } - } - } - - // No technique created -> check if one can be created from the given source technique scheme. - Technique* srcTechnique = NULL; - srcTechnique = findSourceTechnique(materialName, trueGroupName, srcTechniqueSchemeName, overProgrammable); - - // No appropriate source technique found. - if (srcTechnique == NULL) - { - return false; - } - - - // Create shader based technique from the given source technique. - SGMaterial* matEntry = NULL; - - if (itMatEntry == mMaterialEntriesMap.end()) - { - matEntry = OGRE_NEW SGMaterial(materialName, trueGroupName); - mMaterialEntriesMap.insert(SGMaterialMap::value_type( - MatGroupPair(materialName, trueGroupName), matEntry)); - } - else - { - matEntry = itMatEntry->second; - } - - // Create the new technique entry. - SGTechnique* techEntry = OGRE_NEW SGTechnique(matEntry, srcTechnique, dstTechniqueSchemeName); - - - // Add to material entry map. - matEntry->getTechniqueList().push_back(techEntry); - - // Add to all technique map. - mTechniqueEntriesMap[techEntry] = techEntry; - - // Add to scheme. - SGScheme* schemeEntry = createOrRetrieveScheme(dstTechniqueSchemeName).first; - schemeEntry->addTechniqueEntry(techEntry); - - return true; + // Make sure material exists. + MaterialPtr srcMat = MaterialManager::getSingleton().getByName(materialName, groupName); + if (srcMat.isNull() == true) + return false; + + // Update group name in case it is AUTODETECT_RESOURCE_GROUP_NAME + const String& trueGroupName = srcMat->getGroup(); + + // Case the requested material belongs to different group and it is not AUTODETECT_RESOURCE_GROUP_NAME. + if (trueGroupName != groupName && + groupName != ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) + { + return false; + } + + SGMaterialIterator itMatEntry = findMaterialEntryIt(materialName, trueGroupName); + + // Check if technique already created. + if (itMatEntry != mMaterialEntriesMap.end()) + { + const SGTechniqueList& techniqueEntires = itMatEntry->second->getTechniqueList(); + SGTechniqueConstIterator itTechEntry = techniqueEntires.begin(); + + for (; itTechEntry != techniqueEntires.end(); ++itTechEntry) + { + // Case the requested mapping already exists. + if ((*itTechEntry)->getSourceTechnique()->getSchemeName() == srcTechniqueSchemeName && + (*itTechEntry)->getDestinationTechniqueSchemeName() == dstTechniqueSchemeName) + { + return true; + } + + + // Case a shader based technique with the same scheme name already defined based + // on different source technique. + // This state might lead to conflicts during shader generation - we prevent it by returning false here. + else if ((*itTechEntry)->getDestinationTechniqueSchemeName() == dstTechniqueSchemeName) + { + return false; + } + } + } + + // No technique created -> check if one can be created from the given source technique scheme. + Technique* srcTechnique = NULL; + srcTechnique = findSourceTechnique(materialName, trueGroupName, srcTechniqueSchemeName, overProgrammable); + + // No appropriate source technique found. + if (srcTechnique == NULL) + { + return false; + } + + + // Create shader based technique from the given source technique. + SGMaterial* matEntry = NULL; + + if (itMatEntry == mMaterialEntriesMap.end()) + { + matEntry = OGRE_NEW SGMaterial(materialName, trueGroupName); + mMaterialEntriesMap.insert(SGMaterialMap::value_type( + MatGroupPair(materialName, trueGroupName), matEntry)); + } + else + { + matEntry = itMatEntry->second; + } + + // Create the new technique entry. + SGTechnique* techEntry = OGRE_NEW SGTechnique(matEntry, srcTechnique, dstTechniqueSchemeName); + + + // Add to material entry map. + matEntry->getTechniqueList().push_back(techEntry); + + // Add to all technique map. + mTechniqueEntriesMap[techEntry] = techEntry; + + // Add to scheme. + SGScheme* schemeEntry = createOrRetrieveScheme(dstTechniqueSchemeName).first; + schemeEntry->addTechniqueEntry(techEntry); + + return true; } //----------------------------------------------------------------------------- bool ShaderGenerator::removeShaderBasedTechnique(const String& materialName, - const String& srcTechniqueSchemeName, - const String& dstTechniqueSchemeName) + const String& srcTechniqueSchemeName, + const String& dstTechniqueSchemeName) { - return removeShaderBasedTechnique(materialName,ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, - srcTechniqueSchemeName,dstTechniqueSchemeName); + return removeShaderBasedTechnique(materialName,ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, + srcTechniqueSchemeName,dstTechniqueSchemeName); } //----------------------------------------------------------------------------- bool ShaderGenerator::removeShaderBasedTechnique(const String& materialName, - const String& groupName, - const String& srcTechniqueSchemeName, - const String& dstTechniqueSchemeName) + const String& groupName, + const String& srcTechniqueSchemeName, + const String& dstTechniqueSchemeName) { OGRE_LOCK_AUTO_MUTEX; - // Make sure scheme exists. - SGSchemeIterator itScheme = mSchemeEntriesMap.find(dstTechniqueSchemeName); - SGScheme* schemeEntry = NULL; + // Make sure scheme exists. + SGSchemeIterator itScheme = mSchemeEntriesMap.find(dstTechniqueSchemeName); + SGScheme* schemeEntry = NULL; - if (itScheme == mSchemeEntriesMap.end()) - return false; - - schemeEntry = itScheme->second; - + if (itScheme == mSchemeEntriesMap.end()) + return false; + + schemeEntry = itScheme->second; + - // Find the material entry. - SGMaterialIterator itMatEntry = findMaterialEntryIt(materialName,groupName); + // Find the material entry. + SGMaterialIterator itMatEntry = findMaterialEntryIt(materialName,groupName); - // Case material not found. - if (itMatEntry == mMaterialEntriesMap.end()) - return false; + // Case material not found. + if (itMatEntry == mMaterialEntriesMap.end()) + return false; - SGTechniqueList& matTechniqueEntires = itMatEntry->second->getTechniqueList(); - SGTechniqueIterator itTechEntry = matTechniqueEntires.begin(); - SGTechnique* dstTechnique = NULL; + SGTechniqueList& matTechniqueEntires = itMatEntry->second->getTechniqueList(); + SGTechniqueIterator itTechEntry = matTechniqueEntires.begin(); + SGTechnique* dstTechnique = NULL; - // Remove destination technique entry from material techniques list. - for (; itTechEntry != matTechniqueEntires.end(); ++itTechEntry) - { - if ((*itTechEntry)->getSourceTechnique()->getSchemeName() == srcTechniqueSchemeName && - (*itTechEntry)->getDestinationTechniqueSchemeName() == dstTechniqueSchemeName) - { - dstTechnique = *itTechEntry; - matTechniqueEntires.erase(itTechEntry); - break; - } - } + // Remove destination technique entry from material techniques list. + for (; itTechEntry != matTechniqueEntires.end(); ++itTechEntry) + { + if ((*itTechEntry)->getSourceTechnique()->getSchemeName() == srcTechniqueSchemeName && + (*itTechEntry)->getDestinationTechniqueSchemeName() == dstTechniqueSchemeName) + { + dstTechnique = *itTechEntry; + matTechniqueEntires.erase(itTechEntry); + break; + } + } - // Technique not found. - if (dstTechnique == NULL) - return false; + // Technique not found. + if (dstTechnique == NULL) + return false; - schemeEntry->removeTechniqueEntry(dstTechnique); + schemeEntry->removeTechniqueEntry(dstTechnique); - SGTechniqueMapIterator itTechMap = mTechniqueEntriesMap.find(dstTechnique); + SGTechniqueMapIterator itTechMap = mTechniqueEntriesMap.find(dstTechnique); - if (itTechMap != mTechniqueEntriesMap.end()) - mTechniqueEntriesMap.erase(itTechMap); - - OGRE_DELETE dstTechnique; - - return true; + if (itTechMap != mTechniqueEntriesMap.end()) + mTechniqueEntriesMap.erase(itTechMap); + + OGRE_DELETE dstTechnique; + + return true; } //----------------------------------------------------------------------------- @@ -868,147 +868,147 @@ bool ShaderGenerator::removeAllShaderBasedTechniques(const String& materialName, { OGRE_LOCK_AUTO_MUTEX; - // Find the material entry. - SGMaterialIterator itMatEntry = findMaterialEntryIt(materialName, groupName); - - // Case material not found. - if (itMatEntry == mMaterialEntriesMap.end()) - return false; + // Find the material entry. + SGMaterialIterator itMatEntry = findMaterialEntryIt(materialName, groupName); + + // Case material not found. + if (itMatEntry == mMaterialEntriesMap.end()) + return false; - SGTechniqueList& matTechniqueEntires = itMatEntry->second->getTechniqueList(); - - // Remove all technique entries from material techniques list. - while (matTechniqueEntires.empty() == false) - { - SGTechniqueIterator itTechEntry = matTechniqueEntires.begin(); + SGTechniqueList& matTechniqueEntires = itMatEntry->second->getTechniqueList(); + + // Remove all technique entries from material techniques list. + while (matTechniqueEntires.empty() == false) + { + SGTechniqueIterator itTechEntry = matTechniqueEntires.begin(); - removeShaderBasedTechnique(materialName, itMatEntry->first.second, (*itTechEntry)->getSourceTechnique()->getSchemeName(), - (*itTechEntry)->getDestinationTechniqueSchemeName()); - } + removeShaderBasedTechnique(materialName, itMatEntry->first.second, (*itTechEntry)->getSourceTechnique()->getSchemeName(), + (*itTechEntry)->getDestinationTechniqueSchemeName()); + } - OGRE_DELETE itMatEntry->second; - mMaterialEntriesMap.erase(itMatEntry); - - return true; + OGRE_DELETE itMatEntry->second; + mMaterialEntriesMap.erase(itMatEntry); + + return true; } //----------------------------------------------------------------------------- bool ShaderGenerator::cloneShaderBasedTechniques(const String& srcMaterialName, - const String& srcGroupName, - const String& dstMaterialName, - const String& dstGroupName) + const String& srcGroupName, + const String& dstMaterialName, + const String& dstGroupName) { OGRE_LOCK_AUTO_MUTEX; - // - // Check that both source and destination material exist - // - - // Make sure material exists. - MaterialPtr srcMat = MaterialManager::getSingleton().getByName(srcMaterialName, srcGroupName); - MaterialPtr dstMat = MaterialManager::getSingleton().getByName(dstMaterialName, dstGroupName); - if ((srcMat.isNull() == true) || (dstMat.isNull() == true) || (srcMat == dstMat)) - return false; - - // Update group name in case it is AUTODETECT_RESOURCE_GROUP_NAME - const String& trueSrcGroupName = srcMat->getGroup(); - const String& trueDstGroupName = dstMat->getGroup(); - - // Case the requested material belongs to different group and it is not AUTODETECT_RESOURCE_GROUP_NAME. - if ((trueSrcGroupName != srcGroupName && srcGroupName != ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) || - (trueSrcGroupName != dstGroupName && dstGroupName != ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME)) - { - return false; - } - - SGMaterialIterator itSrcMatEntry = findMaterialEntryIt(srcMaterialName, trueSrcGroupName); - - //remove any techniques in the destination material so the new techniques may be copied - removeAllShaderBasedTechniques(dstMaterialName, trueDstGroupName); - - // - //remove any techniques from the destination material which have RTSS associated schemes from - //the source material. This code is performed in case the user performed a clone of a material - //which has already generated RTSS techniques in the source material. - // - - //first gather the techniques to remove - set::type schemesToRemove; - unsigned short techCount = srcMat->getNumTechniques(); - for(unsigned short ti = 0 ; ti < techCount ; ++ti) - { - Technique* pSrcTech = srcMat->getTechnique(ti); - Pass* pSrcPass = pSrcTech->getNumPasses() > 0 ? pSrcTech->getPass(0) : NULL; - if (pSrcPass) - { - const Any& passUserData = pSrcPass->getUserObjectBindings().getUserAny(SGPass::UserKey); - if (!passUserData.isEmpty()) - { - schemesToRemove.insert(pSrcTech->_getSchemeIndex()); - } - } - } - //remove the techniques from the destination material - techCount = dstMat->getNumTechniques(); - for(unsigned short ti = techCount - 1 ; ti != (unsigned short)-1 ; --ti) - { - Technique* pDstTech = dstMat->getTechnique(ti); - if (schemesToRemove.find(pDstTech->_getSchemeIndex()) != schemesToRemove.end()) - { - dstMat->removeTechnique(ti); - } - } - - // - // Clone the render states from source to destination - // - - // Check if RTSS techniques exist in the source material - if (itSrcMatEntry != mMaterialEntriesMap.end()) - { - const SGTechniqueList& techniqueEntires = itSrcMatEntry->second->getTechniqueList(); - SGTechniqueConstIterator itTechEntry = techniqueEntires.begin(); - - //Go over all rtss techniques in the source material - for (; itTechEntry != techniqueEntires.end(); ++itTechEntry) - { - String srcFromTechniqueScheme = (*itTechEntry)->getSourceTechnique()->getSchemeName(); - String srcToTechniqueScheme = (*itTechEntry)->getDestinationTechniqueSchemeName(); - - //for every technique in the source material create a shader based technique in the - //destination material - if (createShaderBasedTechnique(dstMaterialName, trueDstGroupName, srcFromTechniqueScheme, srcToTechniqueScheme)) - { - //check for custom render states in the source material - unsigned short passCount = (*itTechEntry)->getSourceTechnique()->getNumPasses(); - for(unsigned short pi = 0 ; pi < passCount ; ++pi) - { - if ((*itTechEntry)->hasRenderState(pi)) - { - //copy the custom render state from the source material to the destination material - RenderState* srcRenderState = (*itTechEntry)->getRenderState(pi); - RenderState* dstRenderState = getRenderState(srcToTechniqueScheme, dstMaterialName, trueDstGroupName, pi); - - const SubRenderStateList& srcSubRenderState = - srcRenderState->getTemplateSubRenderStateList(); - - SubRenderStateList::const_iterator itSubState = srcSubRenderState.begin(), - itSubStateEnd = srcSubRenderState.end(); - for(;itSubState != itSubStateEnd ; ++itSubState) - { - SubRenderState* srcSubState = *itSubState; - SubRenderState* dstSubState = createSubRenderState(srcSubState->getType()); - (*dstSubState) = (*srcSubState); - dstRenderState->addTemplateSubRenderState(dstSubState); - } - } - } - } - } - } - - return true; + // + // Check that both source and destination material exist + // + + // Make sure material exists. + MaterialPtr srcMat = MaterialManager::getSingleton().getByName(srcMaterialName, srcGroupName); + MaterialPtr dstMat = MaterialManager::getSingleton().getByName(dstMaterialName, dstGroupName); + if ((srcMat.isNull() == true) || (dstMat.isNull() == true) || (srcMat == dstMat)) + return false; + + // Update group name in case it is AUTODETECT_RESOURCE_GROUP_NAME + const String& trueSrcGroupName = srcMat->getGroup(); + const String& trueDstGroupName = dstMat->getGroup(); + + // Case the requested material belongs to different group and it is not AUTODETECT_RESOURCE_GROUP_NAME. + if ((trueSrcGroupName != srcGroupName && srcGroupName != ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) || + (trueSrcGroupName != dstGroupName && dstGroupName != ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME)) + { + return false; + } + + SGMaterialIterator itSrcMatEntry = findMaterialEntryIt(srcMaterialName, trueSrcGroupName); + + //remove any techniques in the destination material so the new techniques may be copied + removeAllShaderBasedTechniques(dstMaterialName, trueDstGroupName); + + // + //remove any techniques from the destination material which have RTSS associated schemes from + //the source material. This code is performed in case the user performed a clone of a material + //which has already generated RTSS techniques in the source material. + // + + //first gather the techniques to remove + set::type schemesToRemove; + unsigned short techCount = srcMat->getNumTechniques(); + for(unsigned short ti = 0 ; ti < techCount ; ++ti) + { + Technique* pSrcTech = srcMat->getTechnique(ti); + Pass* pSrcPass = pSrcTech->getNumPasses() > 0 ? pSrcTech->getPass(0) : NULL; + if (pSrcPass) + { + const Any& passUserData = pSrcPass->getUserObjectBindings().getUserAny(SGPass::UserKey); + if (!passUserData.isEmpty()) + { + schemesToRemove.insert(pSrcTech->_getSchemeIndex()); + } + } + } + //remove the techniques from the destination material + techCount = dstMat->getNumTechniques(); + for(unsigned short ti = techCount - 1 ; ti != (unsigned short)-1 ; --ti) + { + Technique* pDstTech = dstMat->getTechnique(ti); + if (schemesToRemove.find(pDstTech->_getSchemeIndex()) != schemesToRemove.end()) + { + dstMat->removeTechnique(ti); + } + } + + // + // Clone the render states from source to destination + // + + // Check if RTSS techniques exist in the source material + if (itSrcMatEntry != mMaterialEntriesMap.end()) + { + const SGTechniqueList& techniqueEntires = itSrcMatEntry->second->getTechniqueList(); + SGTechniqueConstIterator itTechEntry = techniqueEntires.begin(); + + //Go over all rtss techniques in the source material + for (; itTechEntry != techniqueEntires.end(); ++itTechEntry) + { + String srcFromTechniqueScheme = (*itTechEntry)->getSourceTechnique()->getSchemeName(); + String srcToTechniqueScheme = (*itTechEntry)->getDestinationTechniqueSchemeName(); + + //for every technique in the source material create a shader based technique in the + //destination material + if (createShaderBasedTechnique(dstMaterialName, trueDstGroupName, srcFromTechniqueScheme, srcToTechniqueScheme)) + { + //check for custom render states in the source material + unsigned short passCount = (*itTechEntry)->getSourceTechnique()->getNumPasses(); + for(unsigned short pi = 0 ; pi < passCount ; ++pi) + { + if ((*itTechEntry)->hasRenderState(pi)) + { + //copy the custom render state from the source material to the destination material + RenderState* srcRenderState = (*itTechEntry)->getRenderState(pi); + RenderState* dstRenderState = getRenderState(srcToTechniqueScheme, dstMaterialName, trueDstGroupName, pi); + + const SubRenderStateList& srcSubRenderState = + srcRenderState->getTemplateSubRenderStateList(); + + SubRenderStateList::const_iterator itSubState = srcSubRenderState.begin(), + itSubStateEnd = srcSubRenderState.end(); + for(;itSubState != itSubStateEnd ; ++itSubState) + { + SubRenderState* srcSubState = *itSubState; + SubRenderState* dstSubState = createSubRenderState(srcSubState->getType()); + (*dstSubState) = (*srcSubState); + dstRenderState->addTemplateSubRenderState(dstSubState); + } + } + } + } + } + } + + return true; } //----------------------------------------------------------------------------- @@ -1016,87 +1016,87 @@ void ShaderGenerator::removeAllShaderBasedTechniques() { OGRE_LOCK_AUTO_MUTEX; - while (!mMaterialEntriesMap.empty()) - { - SGMaterialIterator itMatEntry = mMaterialEntriesMap.begin(); + while (!mMaterialEntriesMap.empty()) + { + SGMaterialIterator itMatEntry = mMaterialEntriesMap.begin(); - removeAllShaderBasedTechniques(itMatEntry->first.first, itMatEntry->first.second); - } + removeAllShaderBasedTechniques(itMatEntry->first.first, itMatEntry->first.second); + } } - + //----------------------------------------------------------------------------- Technique* ShaderGenerator::findSourceTechnique(const String& materialName, - const String& groupName, const String& srcTechniqueSchemeName, bool allowProgrammable) + const String& groupName, const String& srcTechniqueSchemeName, bool allowProgrammable) { MaterialPtr mat = MaterialManager::getSingleton().getByName(materialName, groupName); - Material::TechniqueIterator itMatTechniques = mat->getTechniqueIterator(); - + Material::TechniqueIterator itMatTechniques = mat->getTechniqueIterator(); + - // Find the source technique and make sure it is not programmable. - while (itMatTechniques.hasMoreElements()) - { - Technique* curTechnique = itMatTechniques.getNext(); + // Find the source technique and make sure it is not programmable. + while (itMatTechniques.hasMoreElements()) + { + Technique* curTechnique = itMatTechniques.getNext(); - if (curTechnique->getSchemeName() == srcTechniqueSchemeName && (allowProgrammable || !isProgrammable(curTechnique))) - { - return curTechnique; - } - } + if (curTechnique->getSchemeName() == srcTechniqueSchemeName && (allowProgrammable || !isProgrammable(curTechnique))) + { + return curTechnique; + } + } - return NULL; + return NULL; } //----------------------------------------------------------------------------- bool ShaderGenerator::isProgrammable(Technique* tech) const { - if (tech != NULL) - { - for (unsigned short i=0; i < tech->getNumPasses(); ++i) - { - if (tech->getPass(i)->isProgrammable() == true) - { - return true; - } - } - } - return false; + if (tech != NULL) + { + for (unsigned short i=0; i < tech->getNumPasses(); ++i) + { + if (tech->getPass(i)->isProgrammable() == true) + { + return true; + } + } + } + return false; } //----------------------------------------------------------------------------- void ShaderGenerator::notifyRenderSingleObject(Renderable* rend, - const Pass* pass, - const AutoParamDataSource* source, - const LightList* pLightList, bool suppressRenderStateChanges) + const Pass* pass, + const AutoParamDataSource* source, + const LightList* pLightList, bool suppressRenderStateChanges) { - if (mActiveViewportValid) - { - const Any& passUserData = pass->getUserObjectBindings().getUserAny(SGPass::UserKey); + if (mActiveViewportValid) + { + const Any& passUserData = pass->getUserObjectBindings().getUserAny(SGPass::UserKey); - if (passUserData.isEmpty()) - return; + if (passUserData.isEmpty()) + return; - OGRE_LOCK_AUTO_MUTEX; + OGRE_LOCK_AUTO_MUTEX; - SGPass* passEntry = any_cast(passUserData); + SGPass* passEntry = any_cast(passUserData); - passEntry->notifyRenderSingleObject(rend, source, pLightList, suppressRenderStateChanges); - - } + passEntry->notifyRenderSingleObject(rend, source, pLightList, suppressRenderStateChanges); + + } } //----------------------------------------------------------------------------- void ShaderGenerator::preFindVisibleObjects(SceneManager* source, - SceneManager::IlluminationRenderStage irs, - Viewport* v) + SceneManager::IlluminationRenderStage irs, + Viewport* v) { OGRE_LOCK_AUTO_MUTEX; - const String& curMaterialScheme = v->getMaterialScheme(); - - mActiveSceneMgr = source; - mActiveViewportValid = validateScheme(curMaterialScheme); + const String& curMaterialScheme = v->getMaterialScheme(); + + mActiveSceneMgr = source; + mActiveViewportValid = validateScheme(curMaterialScheme); } //----------------------------------------------------------------------------- @@ -1104,11 +1104,11 @@ void ShaderGenerator::invalidateScheme(const String& schemeName) { OGRE_LOCK_AUTO_MUTEX; - SGSchemeIterator itScheme = mSchemeEntriesMap.find(schemeName); + SGSchemeIterator itScheme = mSchemeEntriesMap.find(schemeName); - if (itScheme != mSchemeEntriesMap.end()) - itScheme->second->invalidate(); - + if (itScheme != mSchemeEntriesMap.end()) + itScheme->second->invalidate(); + } //----------------------------------------------------------------------------- @@ -1116,15 +1116,15 @@ bool ShaderGenerator::validateScheme(const String& schemeName) { OGRE_LOCK_AUTO_MUTEX; - SGSchemeIterator itScheme = mSchemeEntriesMap.find(schemeName); + SGSchemeIterator itScheme = mSchemeEntriesMap.find(schemeName); - // No such scheme exists. - if (itScheme == mSchemeEntriesMap.end()) - return false; + // No such scheme exists. + if (itScheme == mSchemeEntriesMap.end()) + return false; - itScheme->second->validate(); + itScheme->second->validate(); - return true; + return true; } //----------------------------------------------------------------------------- @@ -1132,10 +1132,10 @@ void ShaderGenerator::invalidateMaterial(const String& schemeName, const String& { OGRE_LOCK_AUTO_MUTEX; - SGSchemeIterator itScheme = mSchemeEntriesMap.find(schemeName); - - if (itScheme != mSchemeEntriesMap.end()) - itScheme->second->invalidate(materialName, groupName); + SGSchemeIterator itScheme = mSchemeEntriesMap.find(schemeName); + + if (itScheme != mSchemeEntriesMap.end()) + itScheme->second->invalidate(materialName, groupName); } //----------------------------------------------------------------------------- @@ -1143,46 +1143,46 @@ bool ShaderGenerator::validateMaterial(const String& schemeName, const String& m { OGRE_LOCK_AUTO_MUTEX; - SGSchemeIterator itScheme = mSchemeEntriesMap.find(schemeName); + SGSchemeIterator itScheme = mSchemeEntriesMap.find(schemeName); - // No such scheme exists. - if (itScheme == mSchemeEntriesMap.end()) - return false; + // No such scheme exists. + if (itScheme == mSchemeEntriesMap.end()) + return false; - return itScheme->second->validate(materialName, groupName); + return itScheme->second->validate(materialName, groupName); } //----------------------------------------------------------------------------- SGMaterialSerializerListener* ShaderGenerator::getMaterialSerializerListener() { - if (mMaterialSerializerListener == NULL) - mMaterialSerializerListener = OGRE_NEW SGMaterialSerializerListener; + if (mMaterialSerializerListener == NULL) + mMaterialSerializerListener = OGRE_NEW SGMaterialSerializerListener; - return mMaterialSerializerListener; + return mMaterialSerializerListener; } //----------------------------------------------------------------------------- void ShaderGenerator::flushShaderCache() { - SGTechniqueMapIterator itTech = mTechniqueEntriesMap.begin(); - SGTechniqueMapIterator itTechEnd = mTechniqueEntriesMap.end(); + SGTechniqueMapIterator itTech = mTechniqueEntriesMap.begin(); + SGTechniqueMapIterator itTechEnd = mTechniqueEntriesMap.end(); - // Release all programs. - for (; itTech != itTechEnd; ++itTech) - { - itTech->second->releasePrograms(); - } + // Release all programs. + for (; itTech != itTechEnd; ++itTech) + { + itTech->second->releasePrograms(); + } - ProgramManager::getSingleton().flushGpuProgramsCache(); - - SGSchemeIterator itScheme = mSchemeEntriesMap.begin(); - SGSchemeIterator itSchemeEnd = mSchemeEntriesMap.end(); + ProgramManager::getSingleton().flushGpuProgramsCache(); + + SGSchemeIterator itScheme = mSchemeEntriesMap.begin(); + SGSchemeIterator itSchemeEnd = mSchemeEntriesMap.end(); - // Invalidate all schemes. - for (; itScheme != itSchemeEnd; ++itScheme) - { - itScheme->second->invalidate(); - } + // Invalidate all schemes. + for (; itScheme != itSchemeEnd; ++itScheme) + { + itScheme->second->invalidate(); + } } //----------------------------------------------------------------------------- @@ -1190,14 +1190,14 @@ bool ShaderGenerator::addCustomScriptTranslator(const String& key, ScriptTransla { OGRE_LOCK_AUTO_MUTEX; - SGScriptTranslatorIterator itFind = mScriptTranslatorsMap.find(key); + SGScriptTranslatorIterator itFind = mScriptTranslatorsMap.find(key); - if (itFind != mScriptTranslatorsMap.end()) - return false; - - mScriptTranslatorsMap[key] = translator; + if (itFind != mScriptTranslatorsMap.end()) + return false; + + mScriptTranslatorsMap[key] = translator; - return true; + return true; } //----------------------------------------------------------------------------- @@ -1205,14 +1205,14 @@ bool ShaderGenerator::removeCustomScriptTranslator(const String& key) { OGRE_LOCK_AUTO_MUTEX; - SGScriptTranslatorIterator itFind = mScriptTranslatorsMap.find(key); + SGScriptTranslatorIterator itFind = mScriptTranslatorsMap.find(key); - if (itFind == mScriptTranslatorsMap.end()) - return false; + if (itFind == mScriptTranslatorsMap.end()) + return false; - mScriptTranslatorsMap.erase(itFind); + mScriptTranslatorsMap.erase(itFind); - return true; + return true; } //----------------------------------------------------------------------------- @@ -1220,7 +1220,7 @@ size_t ShaderGenerator::getNumTranslators() const { OGRE_LOCK_AUTO_MUTEX; - return mScriptTranslatorsMap.size(); + return mScriptTranslatorsMap.size(); } //----------------------------------------------------------------------------- @@ -1228,53 +1228,53 @@ ScriptTranslator* ShaderGenerator::getTranslator(const AbstractNodePtr& node) { OGRE_LOCK_AUTO_MUTEX; - ScriptTranslator *translator = 0; - - if(node->type == Ogre::ANT_OBJECT) - { - ObjectAbstractNode *obj = reinterpret_cast(node.get()); - SGScriptTranslatorIterator itFind = mScriptTranslatorsMap.find(obj->cls); - - if(itFind != mScriptTranslatorsMap.end()) - translator = itFind->second; - } - - return translator; + ScriptTranslator *translator = 0; + + if(node->type == Ogre::ANT_OBJECT) + { + ObjectAbstractNode *obj = reinterpret_cast(node.get()); + SGScriptTranslatorIterator itFind = mScriptTranslatorsMap.find(obj->cls); + + if(itFind != mScriptTranslatorsMap.end()) + translator = itFind->second; + } + + return translator; } //----------------------------------------------------------------------------- void ShaderGenerator::serializePassAttributes(MaterialSerializer* ser, SGPass* passEntry) { - - // Write section header and begin it. - ser->writeAttribute(3, "rtshader_system"); - ser->beginSection(3); - - // Grab the custom render state this pass uses. - RenderState* customRenderState = passEntry->getCustomRenderState(); + + // Write section header and begin it. + ser->writeAttribute(3, "rtshader_system"); + ser->beginSection(3); - if (customRenderState != NULL) - { - // Write each of the sub-render states that composing the final render state. - const SubRenderStateList& subRenderStates = customRenderState->getTemplateSubRenderStateList(); - SubRenderStateListConstIterator it = subRenderStates.begin(); - SubRenderStateListConstIterator itEnd = subRenderStates.end(); + // Grab the custom render state this pass uses. + RenderState* customRenderState = passEntry->getCustomRenderState(); - for (; it != itEnd; ++it) - { - SubRenderState* curSubRenderState = *it; - SubRenderStateFactoryIterator itFactory = mSubRenderStateFactories.find(curSubRenderState->getType()); - - if (itFactory != mSubRenderStateFactories.end()) - { - SubRenderStateFactory* curFactory = itFactory->second; - curFactory->writeInstance(ser, curSubRenderState, passEntry->getSrcPass(), passEntry->getDstPass()); - } - } - } - - // Write section end. - ser->endSection(3); + if (customRenderState != NULL) + { + // Write each of the sub-render states that composing the final render state. + const SubRenderStateList& subRenderStates = customRenderState->getTemplateSubRenderStateList(); + SubRenderStateListConstIterator it = subRenderStates.begin(); + SubRenderStateListConstIterator itEnd = subRenderStates.end(); + + for (; it != itEnd; ++it) + { + SubRenderState* curSubRenderState = *it; + SubRenderStateFactoryIterator itFactory = mSubRenderStateFactories.find(curSubRenderState->getType()); + + if (itFactory != mSubRenderStateFactories.end()) + { + SubRenderStateFactory* curFactory = itFactory->second; + curFactory->writeInstance(ser, curSubRenderState, passEntry->getSrcPass(), passEntry->getDstPass()); + } + } + } + + // Write section end. + ser->endSection(3); } @@ -1282,190 +1282,190 @@ void ShaderGenerator::serializePassAttributes(MaterialSerializer* ser, SGPass* p //----------------------------------------------------------------------------- void ShaderGenerator::serializeTextureUnitStateAttributes(MaterialSerializer* ser, SGPass* passEntry, const TextureUnitState* srcTextureUnit) { - - // Write section header and begin it. - ser->writeAttribute(4, "rtshader_system"); - ser->beginSection(4); - - // Grab the custom render state this pass uses. - RenderState* customRenderState = passEntry->getCustomRenderState(); - - if (customRenderState != NULL) - { - //retrive the destintion texture unit state - TextureUnitState* dstTextureUnit = NULL; - unsigned short texIndex = srcTextureUnit->getParent()->getTextureUnitStateIndex(srcTextureUnit); - if (texIndex < passEntry->getDstPass()->getNumTextureUnitStates()) - { - dstTextureUnit = passEntry->getDstPass()->getTextureUnitState(texIndex); - } - - // Write each of the sub-render states that composing the final render state. - const SubRenderStateList& subRenderStates = customRenderState->getTemplateSubRenderStateList(); - SubRenderStateListConstIterator it = subRenderStates.begin(); - SubRenderStateListConstIterator itEnd = subRenderStates.end(); - - for (; it != itEnd; ++it) - { - SubRenderState* curSubRenderState = *it; - SubRenderStateFactoryIterator itFactory = mSubRenderStateFactories.find(curSubRenderState->getType()); - - if (itFactory != mSubRenderStateFactories.end()) - { - SubRenderStateFactory* curFactory = itFactory->second; - curFactory->writeInstance(ser, curSubRenderState, srcTextureUnit, dstTextureUnit); - } - } - } - - // Write section end. - ser->endSection(4); + + // Write section header and begin it. + ser->writeAttribute(4, "rtshader_system"); + ser->beginSection(4); + + // Grab the custom render state this pass uses. + RenderState* customRenderState = passEntry->getCustomRenderState(); + + if (customRenderState != NULL) + { + //retrive the destintion texture unit state + TextureUnitState* dstTextureUnit = NULL; + unsigned short texIndex = srcTextureUnit->getParent()->getTextureUnitStateIndex(srcTextureUnit); + if (texIndex < passEntry->getDstPass()->getNumTextureUnitStates()) + { + dstTextureUnit = passEntry->getDstPass()->getTextureUnitState(texIndex); + } + + // Write each of the sub-render states that composing the final render state. + const SubRenderStateList& subRenderStates = customRenderState->getTemplateSubRenderStateList(); + SubRenderStateListConstIterator it = subRenderStates.begin(); + SubRenderStateListConstIterator itEnd = subRenderStates.end(); + + for (; it != itEnd; ++it) + { + SubRenderState* curSubRenderState = *it; + SubRenderStateFactoryIterator itFactory = mSubRenderStateFactories.find(curSubRenderState->getType()); + + if (itFactory != mSubRenderStateFactories.end()) + { + SubRenderStateFactory* curFactory = itFactory->second; + curFactory->writeInstance(ser, curSubRenderState, srcTextureUnit, dstTextureUnit); + } + } + } + + // Write section end. + ser->endSection(4); } //----------------------------------------------------------------------------- size_t ShaderGenerator::getVertexShaderCount() const { - return mProgramManager->getVertexShaderCount(); + return mProgramManager->getVertexShaderCount(); } //----------------------------------------------------------------------------- size_t ShaderGenerator::getFragmentShaderCount() const { - return mProgramManager->getFragmentShaderCount(); + return mProgramManager->getFragmentShaderCount(); } //----------------------------------------------------------------------------- void ShaderGenerator::setTargetLanguage(const String& shaderLanguage,const float version) { - // Make sure that the shader language is supported. - if (HighLevelGpuProgramManager::getSingleton().isLanguageSupported(shaderLanguage) == false) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "The language " + shaderLanguage + " is not supported !!", - "ShaderGenerator::setShaderLanguage"); - } + // Make sure that the shader language is supported. + if (HighLevelGpuProgramManager::getSingleton().isLanguageSupported(shaderLanguage) == false) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "The language " + shaderLanguage + " is not supported !!", + "ShaderGenerator::setShaderLanguage"); + } - // Case target language changed -> flush the shaders cache. - if (mShaderLanguage != shaderLanguage || mShaderLanguageVersion != version ) - { - mShaderLanguage = shaderLanguage; - mShaderLanguageVersion = version; - flushShaderCache(); - } + // Case target language changed -> flush the shaders cache. + if (mShaderLanguage != shaderLanguage || mShaderLanguageVersion != version ) + { + mShaderLanguage = shaderLanguage; + mShaderLanguageVersion = version; + flushShaderCache(); + } } //----------------------------------------------------------------------------- void ShaderGenerator::setShaderCachePath( const String& cachePath ) { - String stdCachePath = cachePath; + String stdCachePath = cachePath; - // Standardise the cache path in case of none empty string. - if (stdCachePath.empty() == false) - stdCachePath = StringUtil::standardisePath(stdCachePath); + // Standardise the cache path in case of none empty string. + if (stdCachePath.empty() == false) + stdCachePath = StringUtil::standardisePath(stdCachePath); - if (mShaderCachePath != stdCachePath) - { - // Remove previous cache path. - if (mShaderCachePath.empty() == false) - { - ResourceGroupManager::getSingleton().removeResourceLocation(mShaderCachePath, GENERATED_SHADERS_GROUP_NAME); - } - - mShaderCachePath = stdCachePath; - - // Case this is a valid file path -> add as resource location in order to make sure that - // generated shaders could be loaded by the file system archive. - if (mShaderCachePath.empty() == false) - { - // Make sure this is a valid writable path. - String outTestFileName(mShaderCachePath + "ShaderGenerator.tst"); - std::ofstream outFile(outTestFileName.c_str()); - - if (!outFile) - { - OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, - "Could create output files in the given shader cache path '" + mShaderCachePath, - "ShaderGenerator::setShaderCachePath"); - } - - // Close and remove the test file. - outFile.close(); - remove(outTestFileName.c_str()); - - ResourceGroupManager::getSingleton().addResourceLocation(mShaderCachePath, "FileSystem", GENERATED_SHADERS_GROUP_NAME); - } - } + if (mShaderCachePath != stdCachePath) + { + // Remove previous cache path. + if (mShaderCachePath.empty() == false) + { + ResourceGroupManager::getSingleton().removeResourceLocation(mShaderCachePath, GENERATED_SHADERS_GROUP_NAME); + } + + mShaderCachePath = stdCachePath; + + // Case this is a valid file path -> add as resource location in order to make sure that + // generated shaders could be loaded by the file system archive. + if (mShaderCachePath.empty() == false) + { + // Make sure this is a valid writable path. + String outTestFileName(mShaderCachePath + "ShaderGenerator.tst"); + std::ofstream outFile(outTestFileName.c_str()); + + if (!outFile) + { + OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, + "Could create output files in the given shader cache path '" + mShaderCachePath, + "ShaderGenerator::setShaderCachePath"); + } + + // Close and remove the test file. + outFile.close(); + remove(outTestFileName.c_str()); + + ResourceGroupManager::getSingleton().addResourceLocation(mShaderCachePath, "FileSystem", GENERATED_SHADERS_GROUP_NAME); + } + } } //----------------------------------------------------------------------------- ShaderGenerator::SGMaterialIterator ShaderGenerator::findMaterialEntryIt(const String& materialName, const String& groupName) { - SGMaterialIterator itMatEntry; - //check if we have auto detect request - if (groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) - { - //find the possible first entry - itMatEntry = mMaterialEntriesMap.lower_bound(MatGroupPair(materialName,"")); - if ((itMatEntry != mMaterialEntriesMap.end()) && - (itMatEntry->first.first != materialName)) - { - //no entry found - itMatEntry = mMaterialEntriesMap.end(); - } - } - else - { - //find entry with group name specified - itMatEntry = mMaterialEntriesMap.find(MatGroupPair(materialName,groupName)); - } - return itMatEntry; + SGMaterialIterator itMatEntry; + //check if we have auto detect request + if (groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) + { + //find the possible first entry + itMatEntry = mMaterialEntriesMap.lower_bound(MatGroupPair(materialName,"")); + if ((itMatEntry != mMaterialEntriesMap.end()) && + (itMatEntry->first.first != materialName)) + { + //no entry found + itMatEntry = mMaterialEntriesMap.end(); + } + } + else + { + //find entry with group name specified + itMatEntry = mMaterialEntriesMap.find(MatGroupPair(materialName,groupName)); + } + return itMatEntry; } //----------------------------------------------------------------------------- ShaderGenerator::SGMaterialConstIterator ShaderGenerator::findMaterialEntryIt(const String& materialName, const String& groupName) const { - SGMaterialConstIterator itMatEntry; - //check if we have auto detect request - if (groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) - { - //find the possible first entry - itMatEntry = mMaterialEntriesMap.lower_bound(MatGroupPair(materialName,"")); - if ((itMatEntry != mMaterialEntriesMap.end()) && - (itMatEntry->first.first != materialName)) - { - //no entry found - itMatEntry = mMaterialEntriesMap.end(); - } - } - else - { - //find entry with group name specified - itMatEntry = mMaterialEntriesMap.find(MatGroupPair(materialName,groupName)); - } - return itMatEntry; + SGMaterialConstIterator itMatEntry; + //check if we have auto detect request + if (groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) + { + //find the possible first entry + itMatEntry = mMaterialEntriesMap.lower_bound(MatGroupPair(materialName,"")); + if ((itMatEntry != mMaterialEntriesMap.end()) && + (itMatEntry->first.first != materialName)) + { + //no entry found + itMatEntry = mMaterialEntriesMap.end(); + } + } + else + { + //find entry with group name specified + itMatEntry = mMaterialEntriesMap.find(MatGroupPair(materialName,groupName)); + } + return itMatEntry; } //----------------------------------------------------------------------------- size_t ShaderGenerator::getRTShaderSchemeCount() const { OGRE_LOCK_AUTO_MUTEX; - return mSchemeEntriesMap.size(); + return mSchemeEntriesMap.size(); } //----------------------------------------------------------------------------- const String& ShaderGenerator::getRTShaderScheme(size_t index) const { OGRE_LOCK_AUTO_MUTEX; - SGSchemeMap::const_iterator it = mSchemeEntriesMap.begin(); - while ((index != 0) && (it != mSchemeEntriesMap.end())) - { - --index; - ++it; - } + SGSchemeMap::const_iterator it = mSchemeEntriesMap.begin(); + while ((index != 0) && (it != mSchemeEntriesMap.end())) + { + --index; + ++it; + } - assert((it != mSchemeEntriesMap.end()) && "Index out of bounds"); - if (it != mSchemeEntriesMap.end()) - return it->first; - else return cBlankString; + assert((it != mSchemeEntriesMap.end()) && "Index out of bounds"); + if (it != mSchemeEntriesMap.end()) + return it->first; + else return cBlankString; } //----------------------------------------------------------------------------- @@ -1478,133 +1478,133 @@ bool ShaderGenerator::getIsFinalizing() const //----------------------------------------------------------------------------- ShaderGenerator::SGPass::SGPass(SGTechnique* parent, Pass* srcPass, Pass* dstPass) { - mParent = parent; - mSrcPass = srcPass; - mDstPass = dstPass; - mCustomRenderState = NULL; - mTargetRenderState = NULL; - mDstPass->getUserObjectBindings().setUserAny(SGPass::UserKey, Any(this)); + mParent = parent; + mSrcPass = srcPass; + mDstPass = dstPass; + mCustomRenderState = NULL; + mTargetRenderState = NULL; + mDstPass->getUserObjectBindings().setUserAny(SGPass::UserKey, Any(this)); } //----------------------------------------------------------------------------- ShaderGenerator::SGPass::~SGPass() { - if (mTargetRenderState != NULL) - { - OGRE_DELETE mTargetRenderState; - mTargetRenderState = NULL; - } + if (mTargetRenderState != NULL) + { + OGRE_DELETE mTargetRenderState; + mTargetRenderState = NULL; + } } //----------------------------------------------------------------------------- void ShaderGenerator::SGPass::buildTargetRenderState() -{ - const String& schemeName = mParent->getDestinationTechniqueSchemeName(); - const RenderState* renderStateGlobal = ShaderGenerator::getSingleton().getRenderState(schemeName); - - - mTargetRenderState = OGRE_NEW TargetRenderState; - - // Set light properties. - int lightCount[3] = {0}; - - // Use light count definitions of the custom render state if exists. - if (mCustomRenderState != NULL && mCustomRenderState->getLightCountAutoUpdate() == false) - { - mCustomRenderState->getLightCount(lightCount); - } - - // Use light count definitions of the global render state if exists. - else if (renderStateGlobal != NULL) - { - renderStateGlobal->getLightCount(lightCount); - } - - - mTargetRenderState->setLightCount(lightCount); - +{ + const String& schemeName = mParent->getDestinationTechniqueSchemeName(); + const RenderState* renderStateGlobal = ShaderGenerator::getSingleton().getRenderState(schemeName); + + + mTargetRenderState = OGRE_NEW TargetRenderState; + + // Set light properties. + int lightCount[3] = {0}; + + // Use light count definitions of the custom render state if exists. + if (mCustomRenderState != NULL && mCustomRenderState->getLightCountAutoUpdate() == false) + { + mCustomRenderState->getLightCount(lightCount); + } + + // Use light count definitions of the global render state if exists. + else if (renderStateGlobal != NULL) + { + renderStateGlobal->getLightCount(lightCount); + } + + + mTargetRenderState->setLightCount(lightCount); + #ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS - // Build the FFP state. - FFPRenderStateBuilder::getSingleton().buildRenderState(this, mTargetRenderState); + // Build the FFP state. + FFPRenderStateBuilder::getSingleton().buildRenderState(this, mTargetRenderState); #endif - // Link the target render state with the custom render state of this pass if exists. - if (mCustomRenderState != NULL) - { - mTargetRenderState->link(*mCustomRenderState, mSrcPass, mDstPass); - } + // Link the target render state with the custom render state of this pass if exists. + if (mCustomRenderState != NULL) + { + mTargetRenderState->link(*mCustomRenderState, mSrcPass, mDstPass); + } - // Link the target render state with the scheme render state of the shader generator. - if (renderStateGlobal != NULL) - { - mTargetRenderState->link(*renderStateGlobal, mSrcPass, mDstPass); - } + // Link the target render state with the scheme render state of the shader generator. + if (renderStateGlobal != NULL) + { + mTargetRenderState->link(*renderStateGlobal, mSrcPass, mDstPass); + } } //----------------------------------------------------------------------------- void ShaderGenerator::SGPass::acquirePrograms() { - ProgramManager::getSingleton().acquirePrograms(mDstPass, mTargetRenderState); + ProgramManager::getSingleton().acquirePrograms(mDstPass, mTargetRenderState); } //----------------------------------------------------------------------------- void ShaderGenerator::SGPass::releasePrograms() { - ProgramManager::getSingleton().releasePrograms(mDstPass, mTargetRenderState); + ProgramManager::getSingleton().releasePrograms(mDstPass, mTargetRenderState); } //----------------------------------------------------------------------------- void ShaderGenerator::SGPass::notifyRenderSingleObject(Renderable* rend, const AutoParamDataSource* source, - const LightList* pLightList, bool suppressRenderStateChanges) + const LightList* pLightList, bool suppressRenderStateChanges) { - if (mTargetRenderState != NULL && suppressRenderStateChanges == false) - mTargetRenderState->updateGpuProgramsParams(rend, mDstPass, source, pLightList); + if (mTargetRenderState != NULL && suppressRenderStateChanges == false) + mTargetRenderState->updateGpuProgramsParams(rend, mDstPass, source, pLightList); } //----------------------------------------------------------------------------- -SubRenderState* ShaderGenerator::SGPass::getCustomFFPSubState(int subStateOrder) +SubRenderState* ShaderGenerator::SGPass::getCustomFFPSubState(int subStateOrder) { - SubRenderState* customSubState = NULL; + SubRenderState* customSubState = NULL; - // Try to override with custom render state of this pass. - customSubState = getCustomFFPSubState(subStateOrder, mCustomRenderState); - - // Case no custom sub state of this pass found, try to override with global scheme state. - if (customSubState == NULL) - { - const String& schemeName = mParent->getDestinationTechniqueSchemeName(); - const RenderState* renderStateGlobal = ShaderGenerator::getSingleton().getRenderState(schemeName); + // Try to override with custom render state of this pass. + customSubState = getCustomFFPSubState(subStateOrder, mCustomRenderState); + + // Case no custom sub state of this pass found, try to override with global scheme state. + if (customSubState == NULL) + { + const String& schemeName = mParent->getDestinationTechniqueSchemeName(); + const RenderState* renderStateGlobal = ShaderGenerator::getSingleton().getRenderState(schemeName); - customSubState = getCustomFFPSubState(subStateOrder, renderStateGlobal); - } + customSubState = getCustomFFPSubState(subStateOrder, renderStateGlobal); + } - return customSubState; + return customSubState; } //----------------------------------------------------------------------------- -SubRenderState* ShaderGenerator::SGPass::getCustomFFPSubState(int subStateOrder, const RenderState* renderState) +SubRenderState* ShaderGenerator::SGPass::getCustomFFPSubState(int subStateOrder, const RenderState* renderState) { - if (renderState != NULL) - { - const SubRenderStateList& subRenderStateList = renderState->getTemplateSubRenderStateList(); + if (renderState != NULL) + { + const SubRenderStateList& subRenderStateList = renderState->getTemplateSubRenderStateList(); - for (SubRenderStateListConstIterator it=subRenderStateList.begin(); it != subRenderStateList.end(); ++it) - { - SubRenderState* curSubRenderState = *it; + for (SubRenderStateListConstIterator it=subRenderStateList.begin(); it != subRenderStateList.end(); ++it) + { + SubRenderState* curSubRenderState = *it; - if (curSubRenderState->getExecutionOrder() == subStateOrder) - { - SubRenderState* clone; + if (curSubRenderState->getExecutionOrder() == subStateOrder) + { + SubRenderState* clone; - clone = ShaderGenerator::getSingleton().createSubRenderState(curSubRenderState->getType()); - *clone = *curSubRenderState; + clone = ShaderGenerator::getSingleton().createSubRenderState(curSubRenderState->getType()); + *clone = *curSubRenderState; - return clone; - } - } - } - - return NULL; + return clone; + } + } + } + + return NULL; } //----------------------------------------------------------------------------- @@ -1616,40 +1616,40 @@ ShaderGenerator::SGTechnique::SGTechnique(SGMaterial* parent, Technique* srcTech //----------------------------------------------------------------------------- void ShaderGenerator::SGTechnique::createSGPasses() { - // Create pass entry for each pass. - for (unsigned short i=0; i < mSrcTechnique->getNumPasses(); ++i) - { - Pass* srcPass = mSrcTechnique->getPass(i); - Pass* dstPass = mDstTechnique->getPass(i); + // Create pass entry for each pass. + for (unsigned short i=0; i < mSrcTechnique->getNumPasses(); ++i) + { + Pass* srcPass = mSrcTechnique->getPass(i); + Pass* dstPass = mDstTechnique->getPass(i); - SGPass* passEntry = OGRE_NEW SGPass(this, srcPass, dstPass); + SGPass* passEntry = OGRE_NEW SGPass(this, srcPass, dstPass); - if (i < mCustomRenderStates.size()) - passEntry->setCustomRenderState(mCustomRenderStates[i]); - mPassEntries.push_back(passEntry); - } + if (i < mCustomRenderStates.size()) + passEntry->setCustomRenderState(mCustomRenderStates[i]); + mPassEntries.push_back(passEntry); + } } //----------------------------------------------------------------------------- ShaderGenerator::SGTechnique::~SGTechnique() { - const String& materialName = mParent->getMaterialName(); - const String& groupName = mParent->getGroupName(); + const String& materialName = mParent->getMaterialName(); + const String& groupName = mParent->getGroupName(); - if (MaterialManager::getSingleton().resourceExists(materialName)) - { - MaterialPtr mat = MaterialManager::getSingleton().getByName(materialName, groupName); - - // Remove the destination technique from parent material. - for (unsigned int i=0; i < mat->getNumTechniques(); ++i) - { - if (mDstTechnique == mat->getTechnique(i)) - { - // Unload the generated technique in order tor free referenced resources. - mDstTechnique->_unload(); - - // Remove the generated technique in order to restore the material to its original state. - mat->removeTechnique(i); + if (MaterialManager::getSingleton().resourceExists(materialName)) + { + MaterialPtr mat = MaterialManager::getSingleton().getByName(materialName, groupName); + + // Remove the destination technique from parent material. + for (unsigned int i=0; i < mat->getNumTechniques(); ++i) + { + if (mDstTechnique == mat->getTechnique(i)) + { + // Unload the generated technique in order tor free referenced resources. + mDstTechnique->_unload(); + + // Remove the generated technique in order to restore the material to its original state. + mat->removeTechnique(i); // touch when finalizing - will reload the textures - so no touch if finalizing if (ShaderGenerator::getSingleton().getIsFinalizing() == false) @@ -1657,137 +1657,137 @@ ShaderGenerator::SGTechnique::~SGTechnique() // Make sure the material goes back to its original state. mat->touch(); } - break; - } - } - } - - // Release CPU/GPU programs that associated with this technique passes. - for (SGPassIterator itPass = mPassEntries.begin(); itPass != mPassEntries.end(); ++itPass) - { - (*itPass)->releasePrograms(); - } - - // Destroy the passes. - destroySGPasses(); - - // Delete the custom render states of each pass if exist. - for (unsigned int i=0; i < mCustomRenderStates.size(); ++i) - { - if (mCustomRenderStates[i] != NULL) - { - OGRE_DELETE mCustomRenderStates[i]; - mCustomRenderStates[i] = NULL; - } - } - mCustomRenderStates.clear(); - + break; + } + } + } + + // Release CPU/GPU programs that associated with this technique passes. + for (SGPassIterator itPass = mPassEntries.begin(); itPass != mPassEntries.end(); ++itPass) + { + (*itPass)->releasePrograms(); + } + + // Destroy the passes. + destroySGPasses(); + + // Delete the custom render states of each pass if exist. + for (unsigned int i=0; i < mCustomRenderStates.size(); ++i) + { + if (mCustomRenderStates[i] != NULL) + { + OGRE_DELETE mCustomRenderStates[i]; + mCustomRenderStates[i] = NULL; + } + } + mCustomRenderStates.clear(); + } //----------------------------------------------------------------------------- void ShaderGenerator::SGTechnique::destroySGPasses() { - for (SGPassIterator itPass = mPassEntries.begin(); itPass != mPassEntries.end(); ++itPass) - { - OGRE_DELETE (*itPass); - } - mPassEntries.clear(); + for (SGPassIterator itPass = mPassEntries.begin(); itPass != mPassEntries.end(); ++itPass) + { + OGRE_DELETE (*itPass); + } + mPassEntries.clear(); } //----------------------------------------------------------------------------- void ShaderGenerator::SGTechnique::buildTargetRenderState() { - // Remove existing destination technique and passes - // in order to build it again from scratch. - if (mDstTechnique != NULL) - { - Material* mat = mSrcTechnique->getParent(); - - for (unsigned short i=0; i < mat->getNumTechniques(); ++i) - { - if (mat->getTechnique(i) == mDstTechnique) - { - mat->removeTechnique(i); - break; - } - } - destroySGPasses(); - } - - // Create the destination technique and passes. - mDstTechnique = mSrcTechnique->getParent()->createTechnique(); - mDstTechnique->getUserObjectBindings().setUserAny(SGTechnique::UserKey, Any(this)); - *mDstTechnique = *mSrcTechnique; - mDstTechnique->setSchemeName(mDstTechniqueSchemeName); - createSGPasses(); - - - // Build render state for each pass. - for (SGPassIterator itPass = mPassEntries.begin(); itPass != mPassEntries.end(); ++itPass) - { - (*itPass)->buildTargetRenderState(); - } + // Remove existing destination technique and passes + // in order to build it again from scratch. + if (mDstTechnique != NULL) + { + Material* mat = mSrcTechnique->getParent(); + + for (unsigned short i=0; i < mat->getNumTechniques(); ++i) + { + if (mat->getTechnique(i) == mDstTechnique) + { + mat->removeTechnique(i); + break; + } + } + destroySGPasses(); + } + + // Create the destination technique and passes. + mDstTechnique = mSrcTechnique->getParent()->createTechnique(); + mDstTechnique->getUserObjectBindings().setUserAny(SGTechnique::UserKey, Any(this)); + *mDstTechnique = *mSrcTechnique; + mDstTechnique->setSchemeName(mDstTechniqueSchemeName); + createSGPasses(); + + + // Build render state for each pass. + for (SGPassIterator itPass = mPassEntries.begin(); itPass != mPassEntries.end(); ++itPass) + { + (*itPass)->buildTargetRenderState(); + } } //----------------------------------------------------------------------------- void ShaderGenerator::SGTechnique::acquirePrograms() { - for (SGPassIterator itPass = mPassEntries.begin(); itPass != mPassEntries.end(); ++itPass) - { - (*itPass)->acquirePrograms(); - } + for (SGPassIterator itPass = mPassEntries.begin(); itPass != mPassEntries.end(); ++itPass) + { + (*itPass)->acquirePrograms(); + } } //----------------------------------------------------------------------------- void ShaderGenerator::SGTechnique::releasePrograms() { - // Remove destination technique. - if (mDstTechnique != NULL) - { - Material* mat = mSrcTechnique->getParent(); - - for (unsigned short i=0; i < mat->getNumTechniques(); ++i) - { - if (mat->getTechnique(i) == mDstTechnique) - { - mat->removeTechnique(i); - break; - } - } - mDstTechnique = NULL; - } + // Remove destination technique. + if (mDstTechnique != NULL) + { + Material* mat = mSrcTechnique->getParent(); + + for (unsigned short i=0; i < mat->getNumTechniques(); ++i) + { + if (mat->getTechnique(i) == mDstTechnique) + { + mat->removeTechnique(i); + break; + } + } + mDstTechnique = NULL; + } - // Release CPU/GPU programs that associated with this technique passes. - for (SGPassIterator itPass = mPassEntries.begin(); itPass != mPassEntries.end(); ++itPass) - { - (*itPass)->releasePrograms(); - } + // Release CPU/GPU programs that associated with this technique passes. + for (SGPassIterator itPass = mPassEntries.begin(); itPass != mPassEntries.end(); ++itPass) + { + (*itPass)->releasePrograms(); + } - // Destroy the passes. - destroySGPasses(); + // Destroy the passes. + destroySGPasses(); } //----------------------------------------------------------------------------- RenderState* ShaderGenerator::SGTechnique::getRenderState(unsigned short passIndex) { - RenderState* renderState = NULL; + RenderState* renderState = NULL; - if (passIndex >= mCustomRenderStates.size()) - mCustomRenderStates.resize(passIndex + 1, NULL); + if (passIndex >= mCustomRenderStates.size()) + mCustomRenderStates.resize(passIndex + 1, NULL); - renderState = mCustomRenderStates[passIndex]; - if (renderState == NULL) - { - renderState = OGRE_NEW RenderState; - mCustomRenderStates[passIndex] = renderState; - } - - return renderState; + renderState = mCustomRenderStates[passIndex]; + if (renderState == NULL) + { + renderState = OGRE_NEW RenderState; + mCustomRenderStates[passIndex] = renderState; + } + + return renderState; } //----------------------------------------------------------------------------- bool ShaderGenerator::SGTechnique::hasRenderState(unsigned short passIndex) { - return (passIndex < mCustomRenderStates.size()) && (mCustomRenderStates[passIndex] != NULL); + return (passIndex < mCustomRenderStates.size()) && (mCustomRenderStates[passIndex] != NULL); } @@ -1800,233 +1800,233 @@ ShaderGenerator::SGScheme::SGScheme(const String& schemeName) : //----------------------------------------------------------------------------- ShaderGenerator::SGScheme::~SGScheme() { - if (mRenderState != NULL) - { - OGRE_DELETE mRenderState; - mRenderState = NULL; - } + if (mRenderState != NULL) + { + OGRE_DELETE mRenderState; + mRenderState = NULL; + } } //----------------------------------------------------------------------------- RenderState* ShaderGenerator::SGScheme::getRenderState() { - if (mRenderState == NULL) - mRenderState = OGRE_NEW RenderState; + if (mRenderState == NULL) + mRenderState = OGRE_NEW RenderState; - return mRenderState; + return mRenderState; } //----------------------------------------------------------------------------- RenderState* ShaderGenerator::SGScheme::getRenderState(const String& materialName, const String& groupName, unsigned short passIndex) { - SGTechniqueIterator itTech; + SGTechniqueIterator itTech; - // Find the desired technique. - bool doAutoDetect = groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; - for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) - { - SGTechnique* curTechEntry = *itTech; - Material* curMat = curTechEntry->getSourceTechnique()->getParent(); - if ((curMat->getName() == materialName) && - ((doAutoDetect == true) || (curMat->getGroup() == groupName))) - { - return curTechEntry->getRenderState(passIndex); - } - } + // Find the desired technique. + bool doAutoDetect = groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; + for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) + { + SGTechnique* curTechEntry = *itTech; + Material* curMat = curTechEntry->getSourceTechnique()->getParent(); + if ((curMat->getName() == materialName) && + ((doAutoDetect == true) || (curMat->getGroup() == groupName))) + { + return curTechEntry->getRenderState(passIndex); + } + } - return NULL; + return NULL; } //----------------------------------------------------------------------------- void ShaderGenerator::SGScheme::addTechniqueEntry(SGTechnique* techEntry) { - mTechniqueEntries.push_back(techEntry); + mTechniqueEntries.push_back(techEntry); - // Mark as out of data. - mOutOfDate = true; + // Mark as out of data. + mOutOfDate = true; } //----------------------------------------------------------------------------- void ShaderGenerator::SGScheme::removeTechniqueEntry(SGTechnique* techEntry) { - SGTechniqueIterator itTech; + SGTechniqueIterator itTech; - // Build render state for each technique. - for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) - { - SGTechnique* curTechEntry = *itTech; + // Build render state for each technique. + for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) + { + SGTechnique* curTechEntry = *itTech; - if (curTechEntry == techEntry) - { - mTechniqueEntries.erase(itTech); - break; - } - } + if (curTechEntry == techEntry) + { + mTechniqueEntries.erase(itTech); + break; + } + } } //----------------------------------------------------------------------------- void ShaderGenerator::SGScheme::validate() -{ - // Synchronize with light settings. - synchronizeWithLightSettings(); - - // Synchronize with fog settings. - synchronizeWithFogSettings(); - - // The target scheme is up to date. - if (mOutOfDate == false) - return; - - SGTechniqueIterator itTech; - - // Build render state for each technique. - for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) - { - SGTechnique* curTechEntry = *itTech; - - if (curTechEntry->getBuildDestinationTechnique()) - curTechEntry->buildTargetRenderState(); - } - - // Acquire GPU programs for each technique. - for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) - { - SGTechnique* curTechEntry = *itTech; - - if (curTechEntry->getBuildDestinationTechnique()) - curTechEntry->acquirePrograms(); - } - - // Turn off the build destination technique flag. - for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) - { - SGTechnique* curTechEntry = *itTech; - - curTechEntry->setBuildDestinationTechnique(false); - } - - // Mark this scheme as up to date. - mOutOfDate = false; +{ + // Synchronize with light settings. + synchronizeWithLightSettings(); + + // Synchronize with fog settings. + synchronizeWithFogSettings(); + + // The target scheme is up to date. + if (mOutOfDate == false) + return; + + SGTechniqueIterator itTech; + + // Build render state for each technique. + for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) + { + SGTechnique* curTechEntry = *itTech; + + if (curTechEntry->getBuildDestinationTechnique()) + curTechEntry->buildTargetRenderState(); + } + + // Acquire GPU programs for each technique. + for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) + { + SGTechnique* curTechEntry = *itTech; + + if (curTechEntry->getBuildDestinationTechnique()) + curTechEntry->acquirePrograms(); + } + + // Turn off the build destination technique flag. + for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) + { + SGTechnique* curTechEntry = *itTech; + + curTechEntry->setBuildDestinationTechnique(false); + } + + // Mark this scheme as up to date. + mOutOfDate = false; } //----------------------------------------------------------------------------- void ShaderGenerator::SGScheme::synchronizeWithLightSettings() { - SceneManager* sceneManager = ShaderGenerator::getSingleton().getActiveSceneManager(); - RenderState* curRenderState = getRenderState(); - - if (sceneManager != NULL && curRenderState->getLightCountAutoUpdate()) - { - const LightList& lightList = sceneManager->_getLightsAffectingFrustum(); - - int sceneLightCount[3] = {0}; - int currLightCount[3] = {0}; + SceneManager* sceneManager = ShaderGenerator::getSingleton().getActiveSceneManager(); + RenderState* curRenderState = getRenderState(); - for (unsigned int i=0; i < lightList.size(); ++i) - { - sceneLightCount[lightList[i]->getType()]++; - } - - mRenderState->getLightCount(currLightCount); - - // Case light state has been changed -> invalidate this scheme. - if (currLightCount[0] != sceneLightCount[0] || - currLightCount[1] != sceneLightCount[1] || - currLightCount[2] != sceneLightCount[2]) - { - curRenderState->setLightCount(sceneLightCount); - invalidate(); - } - } + if (sceneManager != NULL && curRenderState->getLightCountAutoUpdate()) + { + const LightList& lightList = sceneManager->_getLightsAffectingFrustum(); + + int sceneLightCount[3] = {0}; + int currLightCount[3] = {0}; + + for (unsigned int i=0; i < lightList.size(); ++i) + { + sceneLightCount[lightList[i]->getType()]++; + } + + mRenderState->getLightCount(currLightCount); + + // Case light state has been changed -> invalidate this scheme. + if (currLightCount[0] != sceneLightCount[0] || + currLightCount[1] != sceneLightCount[1] || + currLightCount[2] != sceneLightCount[2]) + { + curRenderState->setLightCount(sceneLightCount); + invalidate(); + } + } } //----------------------------------------------------------------------------- void ShaderGenerator::SGScheme::synchronizeWithFogSettings() { - SceneManager* sceneManager = ShaderGenerator::getSingleton().getActiveSceneManager(); + SceneManager* sceneManager = ShaderGenerator::getSingleton().getActiveSceneManager(); - if (sceneManager != NULL && sceneManager->getFogMode() != mFogMode) - { - mFogMode = sceneManager->getFogMode(); - invalidate(); - } + if (sceneManager != NULL && sceneManager->getFogMode() != mFogMode) + { + mFogMode = sceneManager->getFogMode(); + invalidate(); + } } //----------------------------------------------------------------------------- bool ShaderGenerator::SGScheme::validate(const String& materialName, const String& groupName) { - // Synchronize with light settings. - synchronizeWithLightSettings(); - - // Synchronize with fog settings. - synchronizeWithFogSettings(); - + // Synchronize with light settings. + synchronizeWithLightSettings(); - SGTechniqueIterator itTech; - - // Find the desired technique. - bool doAutoDetect = groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; - for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) - { - SGTechnique* curTechEntry = *itTech; - const SGMaterial* curMat = curTechEntry->getParent(); - if ((curMat->getMaterialName() == materialName) && - ((doAutoDetect == true) || (curMat->getGroupName() == groupName)) && - (curTechEntry->getBuildDestinationTechnique())) - { - // Build render state for each technique. - curTechEntry->buildTargetRenderState(); + // Synchronize with fog settings. + synchronizeWithFogSettings(); - // Acquire the CPU/GPU programs. - curTechEntry->acquirePrograms(); - // Turn off the build destination technique flag. - curTechEntry->setBuildDestinationTechnique(false); - - return true; - } - } + SGTechniqueIterator itTech; + + // Find the desired technique. + bool doAutoDetect = groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; + for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) + { + SGTechnique* curTechEntry = *itTech; + const SGMaterial* curMat = curTechEntry->getParent(); + if ((curMat->getMaterialName() == materialName) && + ((doAutoDetect == true) || (curMat->getGroupName() == groupName)) && + (curTechEntry->getBuildDestinationTechnique())) + { + // Build render state for each technique. + curTechEntry->buildTargetRenderState(); + + // Acquire the CPU/GPU programs. + curTechEntry->acquirePrograms(); + + // Turn off the build destination technique flag. + curTechEntry->setBuildDestinationTechnique(false); + + return true; + } + } - return false; + return false; } //----------------------------------------------------------------------------- void ShaderGenerator::SGScheme::invalidate(const String& materialName, const String& groupName) { - SGTechniqueIterator itTech; + SGTechniqueIterator itTech; - // Find the desired technique. - bool doAutoDetect = groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; - for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) - { - SGTechnique* curTechEntry = *itTech; - const SGMaterial* curMaterial = curTechEntry->getParent(); - if ((curMaterial->getMaterialName() == materialName) && - ((doAutoDetect == true) || (curMaterial->getGroupName() == groupName))) - { - // Turn on the build destination technique flag. - curTechEntry->setBuildDestinationTechnique(true); - break; - } - } + // Find the desired technique. + bool doAutoDetect = groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; + for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) + { + SGTechnique* curTechEntry = *itTech; + const SGMaterial* curMaterial = curTechEntry->getParent(); + if ((curMaterial->getMaterialName() == materialName) && + ((doAutoDetect == true) || (curMaterial->getGroupName() == groupName))) + { + // Turn on the build destination technique flag. + curTechEntry->setBuildDestinationTechnique(true); + break; + } + } - mOutOfDate = true; + mOutOfDate = true; } //----------------------------------------------------------------------------- void ShaderGenerator::SGScheme::invalidate() -{ - SGTechniqueIterator itTech; - - // Turn on the build destination technique flag of all techniques. - for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) - { - SGTechnique* curTechEntry = *itTech; - - curTechEntry->setBuildDestinationTechnique(true); - } - - mOutOfDate = true; +{ + SGTechniqueIterator itTech; + + // Turn on the build destination technique flag of all techniques. + for (itTech = mTechniqueEntries.begin(); itTech != mTechniqueEntries.end(); ++itTech) + { + SGTechnique* curTechEntry = *itTech; + + curTechEntry->setBuildDestinationTechnique(true); + } + + mOutOfDate = true; } } diff --git a/Components/RTShaderSystem/src/OgreShaderHLSLProgramProcessor.cpp b/Components/RTShaderSystem/src/OgreShaderHLSLProgramProcessor.cpp index 80d56380990..6b8ebb2991f 100644 --- a/Components/RTShaderSystem/src/OgreShaderHLSLProgramProcessor.cpp +++ b/Components/RTShaderSystem/src/OgreShaderHLSLProgramProcessor.cpp @@ -49,30 +49,30 @@ HLSLProgramProcessor::~HLSLProgramProcessor() //----------------------------------------------------------------------------- bool HLSLProgramProcessor::preCreateGpuPrograms( ProgramSet* programSet ) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* fsMain = psProgram->getEntryPointFunction(); - bool success; - - // Compact vertex shader outputs. - success = ProgramProcessor::compactVsOutputs(vsMain, fsMain); - if (success == false) - return false; - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* fsMain = psProgram->getEntryPointFunction(); + bool success; + + // Compact vertex shader outputs. + success = ProgramProcessor::compactVsOutputs(vsMain, fsMain); + if (success == false) + return false; + + return true; } //----------------------------------------------------------------------------- bool HLSLProgramProcessor::postCreateGpuPrograms( ProgramSet* programSet ) { - // Bind vertex shader auto parameters. - bindAutoParameters(programSet->getCpuVertexProgram(), programSet->getGpuVertexProgram()); + // Bind vertex shader auto parameters. + bindAutoParameters(programSet->getCpuVertexProgram(), programSet->getGpuVertexProgram()); - // Bind fragment shader auto parameters. - bindAutoParameters(programSet->getCpuFragmentProgram(), programSet->getGpuFragmentProgram()); + // Bind fragment shader auto parameters. + bindAutoParameters(programSet->getCpuFragmentProgram(), programSet->getGpuFragmentProgram()); - return true; + return true; } } diff --git a/Components/RTShaderSystem/src/OgreShaderHLSLProgramWriter.cpp b/Components/RTShaderSystem/src/OgreShaderHLSLProgramWriter.cpp index 3a28ea7e5b9..b3603af01fc 100644 --- a/Components/RTShaderSystem/src/OgreShaderHLSLProgramWriter.cpp +++ b/Components/RTShaderSystem/src/OgreShaderHLSLProgramWriter.cpp @@ -40,7 +40,7 @@ String HLSLProgramWriter::TargetLanguage = "hlsl"; //----------------------------------------------------------------------- HLSLProgramWriter::HLSLProgramWriter() { - initializeStringMaps(); + initializeStringMaps(); } //----------------------------------------------------------------------- @@ -52,170 +52,170 @@ HLSLProgramWriter::~HLSLProgramWriter() //----------------------------------------------------------------------- void HLSLProgramWriter::initializeStringMaps() { - mGpuConstTypeMap[GCT_FLOAT1] = "float"; - mGpuConstTypeMap[GCT_FLOAT2] = "float2"; - mGpuConstTypeMap[GCT_FLOAT3] = "float3"; - mGpuConstTypeMap[GCT_FLOAT4] = "float4"; - mGpuConstTypeMap[GCT_SAMPLER1D] = "sampler1D"; - mGpuConstTypeMap[GCT_SAMPLER2D] = "sampler2D"; - mGpuConstTypeMap[GCT_SAMPLER3D] = "sampler3D"; - mGpuConstTypeMap[GCT_SAMPLERCUBE] = "samplerCUBE"; - mGpuConstTypeMap[GCT_SAMPLER_WRAPPER1D] = "SamplerData1D"; - mGpuConstTypeMap[GCT_SAMPLER_WRAPPER2D] = "SamplerData2D"; - mGpuConstTypeMap[GCT_SAMPLER_WRAPPER3D] = "SamplerData3D"; - mGpuConstTypeMap[GCT_SAMPLER_WRAPPERCUBE] = "SamplerDataCube"; - mGpuConstTypeMap[GCT_SAMPLER_STATE] = "SamplerState"; - - mGpuConstTypeMap[GCT_MATRIX_2X2] = "float2x2"; - mGpuConstTypeMap[GCT_MATRIX_2X3] = "float2x3"; - mGpuConstTypeMap[GCT_MATRIX_2X4] = "float2x4"; - mGpuConstTypeMap[GCT_MATRIX_3X2] = "float3x2"; - mGpuConstTypeMap[GCT_MATRIX_3X3] = "float3x3"; - mGpuConstTypeMap[GCT_MATRIX_3X4] = "float3x4"; - mGpuConstTypeMap[GCT_MATRIX_4X2] = "float4x2"; - mGpuConstTypeMap[GCT_MATRIX_4X3] = "float4x3"; - mGpuConstTypeMap[GCT_MATRIX_4X4] = "float4x4"; - mGpuConstTypeMap[GCT_INT1] = "int"; - mGpuConstTypeMap[GCT_INT2] = "int2"; - mGpuConstTypeMap[GCT_INT3] = "int3"; - mGpuConstTypeMap[GCT_INT4] = "int4"; - mGpuConstTypeMap[GCT_UINT1] = "uint"; - mGpuConstTypeMap[GCT_UINT2] = "uint2"; - mGpuConstTypeMap[GCT_UINT3] = "uint3"; - mGpuConstTypeMap[GCT_UINT4] = "uint4"; - - mParamSemanticMap[Parameter::SPS_POSITION] = "POSITION"; - mParamSemanticMap[Parameter::SPS_BLEND_WEIGHTS] = "BLENDWEIGHT"; - mParamSemanticMap[Parameter::SPS_BLEND_INDICES] = "BLENDINDICES"; - mParamSemanticMap[Parameter::SPS_NORMAL] = "NORMAL"; - mParamSemanticMap[Parameter::SPS_COLOR] = "COLOR"; - mParamSemanticMap[Parameter::SPS_TEXTURE_COORDINATES] = "TEXCOORD"; - mParamSemanticMap[Parameter::SPS_BINORMAL] = "BINORMAL"; - mParamSemanticMap[Parameter::SPS_TANGENT] = "TANGENT"; - mParamSemanticMap[Parameter::SPS_UNKNOWN] = ""; - - mGpuConstTypeMapV4[GCT_SAMPLER1D] = "Texture1D"; - mGpuConstTypeMapV4[GCT_SAMPLER2D] = "Texture2D"; - mGpuConstTypeMapV4[GCT_SAMPLER3D] = "Texture3D"; - mGpuConstTypeMapV4[GCT_SAMPLERCUBE] = "TextureCube"; + mGpuConstTypeMap[GCT_FLOAT1] = "float"; + mGpuConstTypeMap[GCT_FLOAT2] = "float2"; + mGpuConstTypeMap[GCT_FLOAT3] = "float3"; + mGpuConstTypeMap[GCT_FLOAT4] = "float4"; + mGpuConstTypeMap[GCT_SAMPLER1D] = "sampler1D"; + mGpuConstTypeMap[GCT_SAMPLER2D] = "sampler2D"; + mGpuConstTypeMap[GCT_SAMPLER3D] = "sampler3D"; + mGpuConstTypeMap[GCT_SAMPLERCUBE] = "samplerCUBE"; + mGpuConstTypeMap[GCT_SAMPLER_WRAPPER1D] = "SamplerData1D"; + mGpuConstTypeMap[GCT_SAMPLER_WRAPPER2D] = "SamplerData2D"; + mGpuConstTypeMap[GCT_SAMPLER_WRAPPER3D] = "SamplerData3D"; + mGpuConstTypeMap[GCT_SAMPLER_WRAPPERCUBE] = "SamplerDataCube"; + mGpuConstTypeMap[GCT_SAMPLER_STATE] = "SamplerState"; + + mGpuConstTypeMap[GCT_MATRIX_2X2] = "float2x2"; + mGpuConstTypeMap[GCT_MATRIX_2X3] = "float2x3"; + mGpuConstTypeMap[GCT_MATRIX_2X4] = "float2x4"; + mGpuConstTypeMap[GCT_MATRIX_3X2] = "float3x2"; + mGpuConstTypeMap[GCT_MATRIX_3X3] = "float3x3"; + mGpuConstTypeMap[GCT_MATRIX_3X4] = "float3x4"; + mGpuConstTypeMap[GCT_MATRIX_4X2] = "float4x2"; + mGpuConstTypeMap[GCT_MATRIX_4X3] = "float4x3"; + mGpuConstTypeMap[GCT_MATRIX_4X4] = "float4x4"; + mGpuConstTypeMap[GCT_INT1] = "int"; + mGpuConstTypeMap[GCT_INT2] = "int2"; + mGpuConstTypeMap[GCT_INT3] = "int3"; + mGpuConstTypeMap[GCT_INT4] = "int4"; + mGpuConstTypeMap[GCT_UINT1] = "uint"; + mGpuConstTypeMap[GCT_UINT2] = "uint2"; + mGpuConstTypeMap[GCT_UINT3] = "uint3"; + mGpuConstTypeMap[GCT_UINT4] = "uint4"; + + mParamSemanticMap[Parameter::SPS_POSITION] = "POSITION"; + mParamSemanticMap[Parameter::SPS_BLEND_WEIGHTS] = "BLENDWEIGHT"; + mParamSemanticMap[Parameter::SPS_BLEND_INDICES] = "BLENDINDICES"; + mParamSemanticMap[Parameter::SPS_NORMAL] = "NORMAL"; + mParamSemanticMap[Parameter::SPS_COLOR] = "COLOR"; + mParamSemanticMap[Parameter::SPS_TEXTURE_COORDINATES] = "TEXCOORD"; + mParamSemanticMap[Parameter::SPS_BINORMAL] = "BINORMAL"; + mParamSemanticMap[Parameter::SPS_TANGENT] = "TANGENT"; + mParamSemanticMap[Parameter::SPS_UNKNOWN] = ""; + + mGpuConstTypeMapV4[GCT_SAMPLER1D] = "Texture1D"; + mGpuConstTypeMapV4[GCT_SAMPLER2D] = "Texture2D"; + mGpuConstTypeMapV4[GCT_SAMPLER3D] = "Texture3D"; + mGpuConstTypeMapV4[GCT_SAMPLERCUBE] = "TextureCube"; } //----------------------------------------------------------------------- void HLSLProgramWriter::writeSourceCode(std::ostream& os, Program* program) { - const ShaderFunctionList& functionList = program->getFunctions(); - ShaderFunctionConstIterator itFunction; + const ShaderFunctionList& functionList = program->getFunctions(); + ShaderFunctionConstIterator itFunction; - const UniformParameterList& parameterList = program->getParameters(); - UniformParameterConstIterator itUniformParam = parameterList.begin(); + const UniformParameterList& parameterList = program->getParameters(); + UniformParameterConstIterator itUniformParam = parameterList.begin(); - // Generate source code header. - writeProgramTitle(os, program); - os << std::endl; + // Generate source code header. + writeProgramTitle(os, program); + os << std::endl; - // Generate dependencies. - writeProgramDependencies(os, program); - os << std::endl; + // Generate dependencies. + writeProgramDependencies(os, program); + os << std::endl; - // Generate global variable code. - writeUniformParametersTitle(os, program); - os << std::endl; + // Generate global variable code. + writeUniformParametersTitle(os, program); + os << std::endl; - for (itUniformParam=parameterList.begin(); itUniformParam != parameterList.end(); ++itUniformParam) - { - writeUniformParameter(os, *itUniformParam); - os << ";" << std::endl; - } - os << std::endl; + for (itUniformParam=parameterList.begin(); itUniformParam != parameterList.end(); ++itUniformParam) + { + writeUniformParameter(os, *itUniformParam); + os << ";" << std::endl; + } + os << std::endl; - // Write program function(s). - for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) - { - Function* curFunction = *itFunction; + // Write program function(s). + for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) + { + Function* curFunction = *itFunction; - writeFunctionTitle(os, curFunction); + writeFunctionTitle(os, curFunction); - writeFunctionDeclaration(os, curFunction); + writeFunctionDeclaration(os, curFunction); - os << "{" << std::endl; + os << "{" << std::endl; - // Write local parameters. - const ShaderParameterList& localParams = curFunction->getLocalParameters(); - ShaderParameterConstIterator itParam = localParams.begin(); + // Write local parameters. + const ShaderParameterList& localParams = curFunction->getLocalParameters(); + ShaderParameterConstIterator itParam = localParams.begin(); - for (; itParam != localParams.end(); ++itParam) - { - os << "\t"; - writeLocalParameter(os, *itParam); - os << ";" << std::endl; - } + for (; itParam != localParams.end(); ++itParam) + { + os << "\t"; + writeLocalParameter(os, *itParam); + os << ";" << std::endl; + } - // Sort and write function atoms. - curFunction->sortAtomInstances(); + // Sort and write function atoms. + curFunction->sortAtomInstances(); - const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances(); - FunctionAtomInstanceConstIterator itAtom; + const FunctionAtomInstanceList& atomInstances = curFunction->getAtomInstances(); + FunctionAtomInstanceConstIterator itAtom; - for (itAtom=atomInstances.begin(); itAtom != atomInstances.end(); ++itAtom) - { - writeAtomInstance(os, *itAtom); - } + for (itAtom=atomInstances.begin(); itAtom != atomInstances.end(); ++itAtom) + { + writeAtomInstance(os, *itAtom); + } - os << "}" << std::endl; - } + os << "}" << std::endl; + } - os << std::endl; + os << std::endl; } //----------------------------------------------------------------------- void HLSLProgramWriter::writeProgramDependencies(std::ostream& os, Program* program) { - os << "//-----------------------------------------------------------------------------" << std::endl; - os << "// PROGRAM DEPENDENCIES" << std::endl; - os << "//-----------------------------------------------------------------------------" << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; + os << "// PROGRAM DEPENDENCIES" << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; - for (unsigned int i=0; i < program->getDependencyCount(); ++i) - { - const String& curDependency = program->getDependency(i); + for (unsigned int i=0; i < program->getDependencyCount(); ++i) + { + const String& curDependency = program->getDependency(i); - os << "#include " << '\"' << curDependency << "." << getTargetLanguage() << '\"' << std::endl; - } + os << "#include " << '\"' << curDependency << "." << getTargetLanguage() << '\"' << std::endl; + } } //----------------------------------------------------------------------- void HLSLProgramWriter::writeUniformParameter(std::ostream& os, UniformParameterPtr parameter) { - bool isHlsl4 = Ogre::RTShader::ShaderGenerator::getSingletonPtr()->IsHlsl4(); - - GpuConstantType paramType = parameter->getType(); - - if (isHlsl4 && paramType >= GCT_SAMPLER1D && paramType <= GCT_SAMPLERCUBE) - os<getName(); - - if (parameter->isArray() == true) - { - os << "[" << parameter->getSize() << "]"; - } - if (parameter->isSampler()) - { - if (isHlsl4) - os << " : register(t" << parameter->getIndex() << ")"; - else - os << " : register(s" << parameter->getIndex() << ")"; - - } - else if (parameter->getType() == GCT_SAMPLER_STATE) - { - os << " : register(s" << parameter->getIndex() << ")"; - } + bool isHlsl4 = Ogre::RTShader::ShaderGenerator::getSingletonPtr()->IsHlsl4(); + + GpuConstantType paramType = parameter->getType(); + + if (isHlsl4 && paramType >= GCT_SAMPLER1D && paramType <= GCT_SAMPLERCUBE) + os<getName(); + + if (parameter->isArray() == true) + { + os << "[" << parameter->getSize() << "]"; + } + if (parameter->isSampler()) + { + if (isHlsl4) + os << " : register(t" << parameter->getIndex() << ")"; + else + os << " : register(s" << parameter->getIndex() << ")"; + + } + else if (parameter->getType() == GCT_SAMPLER_STATE) + { + os << " : register(s" << parameter->getIndex() << ")"; + } } @@ -223,110 +223,110 @@ void HLSLProgramWriter::writeUniformParameter(std::ostream& os, UniformParameter void HLSLProgramWriter::writeFunctionParameter(std::ostream& os, ParameterPtr parameter, const char* forcedSemantic) { - os << mGpuConstTypeMap[parameter->getType()]; - - os << "\t"; - os << parameter->getName(); - if (parameter->isArray() == true) - { - os << "[" << parameter->getSize() << "]"; - } - - if(forcedSemantic) - { - os << " : " << forcedSemantic; - } - else if (parameter->getSemantic() != Parameter::SPS_UNKNOWN) - { - os << " : "; - - os << mParamSemanticMap[parameter->getSemantic()]; - - if (parameter->getSemantic() != Parameter::SPS_POSITION && - parameter->getSemantic() != Parameter::SPS_NORMAL && - parameter->getSemantic() != Parameter::SPS_BLEND_INDICES && - parameter->getSemantic() != Parameter::SPS_BLEND_WEIGHTS && - (!(parameter->getSemantic() == Parameter::SPS_COLOR && parameter->getIndex() == 0)) && - parameter->getIndex() >= 0) - { - os << StringConverter::toString(parameter->getIndex()).c_str(); - } - } + os << mGpuConstTypeMap[parameter->getType()]; + + os << "\t"; + os << parameter->getName(); + if (parameter->isArray() == true) + { + os << "[" << parameter->getSize() << "]"; + } + + if(forcedSemantic) + { + os << " : " << forcedSemantic; + } + else if (parameter->getSemantic() != Parameter::SPS_UNKNOWN) + { + os << " : "; + + os << mParamSemanticMap[parameter->getSemantic()]; + + if (parameter->getSemantic() != Parameter::SPS_POSITION && + parameter->getSemantic() != Parameter::SPS_NORMAL && + parameter->getSemantic() != Parameter::SPS_BLEND_INDICES && + parameter->getSemantic() != Parameter::SPS_BLEND_WEIGHTS && + (!(parameter->getSemantic() == Parameter::SPS_COLOR && parameter->getIndex() == 0)) && + parameter->getIndex() >= 0) + { + os << StringConverter::toString(parameter->getIndex()).c_str(); + } + } } //----------------------------------------------------------------------- void HLSLProgramWriter::writeLocalParameter(std::ostream& os, ParameterPtr parameter) { - os << mGpuConstTypeMap[parameter->getType()]; - os << "\t"; - os << parameter->getName(); - if (parameter->isArray() == true) - { - os << "[" << parameter->getSize() << "]"; - } + os << mGpuConstTypeMap[parameter->getType()]; + os << "\t"; + os << parameter->getName(); + if (parameter->isArray() == true) + { + os << "[" << parameter->getSize() << "]"; + } } //----------------------------------------------------------------------- void HLSLProgramWriter::writeFunctionDeclaration(std::ostream& os, Function* function) { - const ShaderParameterList& inParams = function->getInputParameters(); - const ShaderParameterList& outParams = function->getOutputParameters(); + const ShaderParameterList& inParams = function->getInputParameters(); + const ShaderParameterList& outParams = function->getOutputParameters(); - os << "void"; - os << " "; + os << "void"; + os << " "; - os << function->getName(); - os << std::endl << "\t(" << std::endl; + os << function->getName(); + os << std::endl << "\t(" << std::endl; - ShaderParameterConstIterator it; - size_t paramsCount = inParams.size() + outParams.size(); - size_t curParamIndex = 0; + ShaderParameterConstIterator it; + size_t paramsCount = inParams.size() + outParams.size(); + size_t curParamIndex = 0; - bool isVs4 = GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0_level_9_1"); + bool isVs4 = GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0_level_9_1"); - // Write input parameters. - for (it=inParams.begin(); it != inParams.end(); ++it) - { - os << "\t in "; + // Write input parameters. + for (it=inParams.begin(); it != inParams.end(); ++it) + { + os << "\t in "; - const char* forcedSemantic = - (isVs4 && function->getFunctionType() == Function::FFT_PS_MAIN && (*it)->getSemantic() == Parameter::SPS_POSITION) ? "SV_Position" : NULL; + const char* forcedSemantic = + (isVs4 && function->getFunctionType() == Function::FFT_PS_MAIN && (*it)->getSemantic() == Parameter::SPS_POSITION) ? "SV_Position" : NULL; - writeFunctionParameter(os, *it, forcedSemantic); + writeFunctionParameter(os, *it, forcedSemantic); - if (curParamIndex + 1 != paramsCount) - os << ", " << std::endl; + if (curParamIndex + 1 != paramsCount) + os << ", " << std::endl; - curParamIndex++; - } + curParamIndex++; + } - // Write output parameters. - for (it=outParams.begin(); it != outParams.end(); ++it) - { - os << "\t out "; + // Write output parameters. + for (it=outParams.begin(); it != outParams.end(); ++it) + { + os << "\t out "; - const char* forcedSemantic = - (isVs4 && function->getFunctionType() == Function::FFT_PS_MAIN) ? "SV_Target" : - (isVs4 && function->getFunctionType() == Function::FFT_VS_MAIN && (*it)->getSemantic() == Parameter::SPS_POSITION) ? "SV_Position" : NULL; + const char* forcedSemantic = + (isVs4 && function->getFunctionType() == Function::FFT_PS_MAIN) ? "SV_Target" : + (isVs4 && function->getFunctionType() == Function::FFT_VS_MAIN && (*it)->getSemantic() == Parameter::SPS_POSITION) ? "SV_Position" : NULL; - writeFunctionParameter(os, *it, forcedSemantic); + writeFunctionParameter(os, *it, forcedSemantic); - if (curParamIndex + 1 != paramsCount) - os << ", " << std::endl; + if (curParamIndex + 1 != paramsCount) + os << ", " << std::endl; - curParamIndex++; - } - - os << std::endl << "\t)" << std::endl; + curParamIndex++; + } + + os << std::endl << "\t)" << std::endl; } //----------------------------------------------------------------------- void HLSLProgramWriter::writeAtomInstance(std::ostream& os, FunctionAtom* atom) { - os << std::endl << "\t"; - atom->writeSourceCode(os, getTargetLanguage()); - os << std::endl; + os << std::endl << "\t"; + atom->writeSourceCode(os, getTargetLanguage()); + os << std::endl; } /** @} */ diff --git a/Components/RTShaderSystem/src/OgreShaderMaterialSerializerListener.cpp b/Components/RTShaderSystem/src/OgreShaderMaterialSerializerListener.cpp index fc9b34b8fd2..b0c0edb05bd 100644 --- a/Components/RTShaderSystem/src/OgreShaderMaterialSerializerListener.cpp +++ b/Components/RTShaderSystem/src/OgreShaderMaterialSerializerListener.cpp @@ -35,7 +35,7 @@ namespace RTShader { //----------------------------------------------------------------------------- SGMaterialSerializerListener::SGMaterialSerializerListener() { - mSourceMaterial = NULL; + mSourceMaterial = NULL; } //----------------------------------------------------------------------------- @@ -47,116 +47,116 @@ SGMaterialSerializerListener::~SGMaterialSerializerListener() //----------------------------------------------------------------------------- void SGMaterialSerializerListener::materialEventRaised(MaterialSerializer* ser, - MaterialSerializer::SerializeEvent event, - bool& skip, const Material* mat) + MaterialSerializer::SerializeEvent event, + bool& skip, const Material* mat) { - if (event == MaterialSerializer::MSE_PRE_WRITE) - { - MaterialPtr matPtr = MaterialManager::getSingleton().getByName(mat->getName()); - mSourceMaterial = matPtr.get(); - createSGPassList(mSourceMaterial, mSGPassList); - } - - if (event == MaterialSerializer::MSE_POST_WRITE) - { - mSourceMaterial = NULL; - mSGPassList.clear(); - } + if (event == MaterialSerializer::MSE_PRE_WRITE) + { + MaterialPtr matPtr = MaterialManager::getSingleton().getByName(mat->getName()); + mSourceMaterial = matPtr.get(); + createSGPassList(mSourceMaterial, mSGPassList); + } + + if (event == MaterialSerializer::MSE_POST_WRITE) + { + mSourceMaterial = NULL; + mSGPassList.clear(); + } } //----------------------------------------------------------------------------- void SGMaterialSerializerListener::techniqueEventRaised(MaterialSerializer* ser, - MaterialSerializer::SerializeEvent event, - bool& skip, const Technique* tech) + MaterialSerializer::SerializeEvent event, + bool& skip, const Technique* tech) { - // Pre technique write event. - if (event == MaterialSerializer::MSE_PRE_WRITE) - { - const Any& techUserData = tech->getUserObjectBindings().getUserAny(ShaderGenerator::SGTechnique::UserKey); - - // Skip writing this technique since it was generated by the Shader Generator. - if (techUserData.isEmpty() == false) - { - skip = true; - return; - } - } + // Pre technique write event. + if (event == MaterialSerializer::MSE_PRE_WRITE) + { + const Any& techUserData = tech->getUserObjectBindings().getUserAny(ShaderGenerator::SGTechnique::UserKey); + + // Skip writing this technique since it was generated by the Shader Generator. + if (techUserData.isEmpty() == false) + { + skip = true; + return; + } + } } //----------------------------------------------------------------------------- void SGMaterialSerializerListener::passEventRaised(MaterialSerializer* ser, - MaterialSerializer::SerializeEvent event, - bool& skip, const Pass* pass) + MaterialSerializer::SerializeEvent event, + bool& skip, const Pass* pass) { - // End of pass writing event. - if (event == MaterialSerializer::MSE_WRITE_END) - { - // Grab the shader generator pass instance. - ShaderGenerator::SGPass* passEntry = getShaderGeneratedPass(pass); - - // Case this pass use as source pass for shader generated pass. - if (passEntry != NULL) - ShaderGenerator::getSingleton().serializePassAttributes(ser, passEntry); - } + // End of pass writing event. + if (event == MaterialSerializer::MSE_WRITE_END) + { + // Grab the shader generator pass instance. + ShaderGenerator::SGPass* passEntry = getShaderGeneratedPass(pass); + + // Case this pass use as source pass for shader generated pass. + if (passEntry != NULL) + ShaderGenerator::getSingleton().serializePassAttributes(ser, passEntry); + } } //----------------------------------------------------------------------------- void SGMaterialSerializerListener::textureUnitStateEventRaised(MaterialSerializer* ser, - MaterialSerializer::SerializeEvent event, - bool& skip, const TextureUnitState* textureUnit) + MaterialSerializer::SerializeEvent event, + bool& skip, const TextureUnitState* textureUnit) { - // End of pass writing event. - if (event == MaterialSerializer::MSE_WRITE_END) - { - // Grab the shader generator pass instance. - ShaderGenerator::SGPass* passEntry = getShaderGeneratedPass(textureUnit->getParent()); - - // Case this pass use as source pass for shader generated pass. - if (passEntry != NULL) - ShaderGenerator::getSingleton().serializeTextureUnitStateAttributes(ser, passEntry, textureUnit); - } + // End of pass writing event. + if (event == MaterialSerializer::MSE_WRITE_END) + { + // Grab the shader generator pass instance. + ShaderGenerator::SGPass* passEntry = getShaderGeneratedPass(textureUnit->getParent()); + + // Case this pass use as source pass for shader generated pass. + if (passEntry != NULL) + ShaderGenerator::getSingleton().serializeTextureUnitStateAttributes(ser, passEntry, textureUnit); + } } //----------------------------------------------------------------------------- void SGMaterialSerializerListener::createSGPassList(Material* mat, SGPassList& passList) { - for (unsigned short techniqueIndex = 0; techniqueIndex < mat->getNumTechniques(); ++techniqueIndex) - { - Technique* curTechnique = mat->getTechnique(techniqueIndex); - - for (unsigned short passIndex = 0; passIndex < curTechnique->getNumPasses(); ++passIndex) - { - Pass* curPass = curTechnique->getPass(passIndex); - const Any& passUserData = curPass->getUserObjectBindings().getUserAny(ShaderGenerator::SGPass::UserKey); - - // Case this pass created by the shader generator. - if (passUserData.isEmpty() == false) - { - ShaderGenerator::SGPass* passEntry = any_cast(passUserData); - - passList.push_back(passEntry); - } - } - } + for (unsigned short techniqueIndex = 0; techniqueIndex < mat->getNumTechniques(); ++techniqueIndex) + { + Technique* curTechnique = mat->getTechnique(techniqueIndex); + + for (unsigned short passIndex = 0; passIndex < curTechnique->getNumPasses(); ++passIndex) + { + Pass* curPass = curTechnique->getPass(passIndex); + const Any& passUserData = curPass->getUserObjectBindings().getUserAny(ShaderGenerator::SGPass::UserKey); + + // Case this pass created by the shader generator. + if (passUserData.isEmpty() == false) + { + ShaderGenerator::SGPass* passEntry = any_cast(passUserData); + + passList.push_back(passEntry); + } + } + } } //----------------------------------------------------------------------------- ShaderGenerator::SGPass* SGMaterialSerializerListener::getShaderGeneratedPass(const Pass* srcPass) { - SGPassListIterator it = mSGPassList.begin(); - SGPassListIterator itEnd = mSGPassList.end(); + SGPassListIterator it = mSGPassList.begin(); + SGPassListIterator itEnd = mSGPassList.end(); - for (; it != itEnd; ++it) - { - ShaderGenerator::SGPass* currPassEntry = *it; + for (; it != itEnd; ++it) + { + ShaderGenerator::SGPass* currPassEntry = *it; - if (currPassEntry->getSrcPass() == srcPass) - { - return currPassEntry; - } - } + if (currPassEntry->getSrcPass() == srcPass) + { + return currPassEntry; + } + } - return NULL; + return NULL; } diff --git a/Components/RTShaderSystem/src/OgreShaderParameter.cpp b/Components/RTShaderSystem/src/OgreShaderParameter.cpp index dbeb0df1d29..f8ece0155fe 100644 --- a/Components/RTShaderSystem/src/OgreShaderParameter.cpp +++ b/Components/RTShaderSystem/src/OgreShaderParameter.cpp @@ -35,301 +35,301 @@ THE SOFTWARE. namespace Ogre { namespace RTShader { - //----------------------------------------------------------------------- - // Define some ConstParameterTypes - //----------------------------------------------------------------------- - - /** ConstParameterVec2 represents a Vector2 constant. - */ - class ConstParameterVec2 : public ConstParameter - { - public: - ConstParameterVec2( Vector2 val, - GpuConstantType type, - const Semantic& semantic, - const Content& content) - : ConstParameter(val, type, semantic, content) - { - } - - ~ConstParameterVec2() {} - - /** - @see Parameter::toString. - */ - virtual String toString () const - { - const String& lang = ShaderGenerator::getSingleton().getTargetLanguage(); - return - ((lang.empty() == false) && (lang[0] == 'g') ? String("vec2(") : String("float2(")) + - Ogre::StringConverter::toString(mValue.x) + "," + - Ogre::StringConverter::toString(mValue.y) + ")"; - } - }; - - /** ConstParameterVec3 represents a Vector3 constant. - */ - class ConstParameterVec3 : public ConstParameter - { - public: - ConstParameterVec3( Vector3 val, - GpuConstantType type, - const Semantic& semantic, - const Content& content) - : ConstParameter(val, type, semantic, content) - { - } - ~ConstParameterVec3() {} - - /** - @see Parameter::toString. - */ - virtual String toString () const - { - const String& lang = ShaderGenerator::getSingleton().getTargetLanguage(); - return - ((lang.empty() == false) && (lang[0] == 'g') ? String("vec3(") : String("float3(")) + - Ogre::StringConverter::toString(mValue.x) + "," + - Ogre::StringConverter::toString(mValue.y) + "," + - Ogre::StringConverter::toString(mValue.z) + ")"; - } - }; - - /** ConstParameterVec4 represents a Vector2 Vector4. - */ - class ConstParameterVec4 : public ConstParameter - { - public: - ConstParameterVec4( Vector4 val, - GpuConstantType type, - const Semantic& semantic, - const Content& content) - : ConstParameter(val, type, semantic, content) - { - } - ~ConstParameterVec4() {} - - /** - @see Parameter::toString. - */ - virtual String toString () const - { - const String& lang = ShaderGenerator::getSingleton().getTargetLanguage(); - return - ((lang.empty() == false) && (lang[0] == 'g') ? String("vec4(") : String("float4(")) + - Ogre::StringConverter::toString(mValue.x) + "," + - Ogre::StringConverter::toString(mValue.y) + "," + - Ogre::StringConverter::toString(mValue.z) + "," + - Ogre::StringConverter::toString(mValue.w) + ")"; - } - }; - - /** ConstParameterFloat represents a float constant. - */ - class ConstParameterFloat : public ConstParameter - { - public: - ConstParameterFloat(float val, - GpuConstantType type, - const Semantic& semantic, - const Content& content) - : ConstParameter(val, type, semantic, content) - { - } - - ~ConstParameterFloat() {} - - /** - @see Parameter::toString. - */ - virtual String toString () const - { - String val = Ogre::StringConverter::toString(mValue); - - // Make sure that float params have always this representation #.# - if(val.find(".") == String::npos) - { - val += ".0"; - } - - return val; - } - }; - /** ConstParameterInt represents an int constant. - */ - class ConstParameterInt : public ConstParameter - { - public: - ConstParameterInt(int val, - GpuConstantType type, - const Semantic& semantic, - const Content& content) - : ConstParameter(val, type, semantic, content) - { - } - - ~ConstParameterInt() {} - - /** - @see Parameter::toString. - */ - virtual String toString () const - { - return Ogre::StringConverter::toString(mValue); - } - }; - - //----------------------------------------------------------------------- - - struct AutoShaderParameter - { - GpuProgramParameters::AutoConstantType autoType; - String name; - GpuConstantType type; - - - AutoShaderParameter(GpuProgramParameters::AutoConstantType _autoType, - const String& _name, - GpuConstantType _type) : autoType(_autoType), name(_name), type(_type) - { - } - }; - - AutoShaderParameter g_AutoParameters[] = { - AutoShaderParameter(GpuProgramParameters::ACT_WORLD_MATRIX, "world_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_WORLD_MATRIX, "inverse_world_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_WORLD_MATRIX, "transpose_world_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, "inverse_transpose_world_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4, "world_matrix_array_3x4", GCT_MATRIX_3X4), - AutoShaderParameter(GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY, "world_matrix_array", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4, "world_dualquaternion_array_2x4", GCT_MATRIX_2X4), - AutoShaderParameter(GpuProgramParameters::ACT_WORLD_SCALE_SHEAR_MATRIX_ARRAY_3x4, "world_scale_shear_matrix_array_3x4", GCT_MATRIX_3X4), - AutoShaderParameter(GpuProgramParameters::ACT_VIEW_MATRIX, "view_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_VIEW_MATRIX, "inverse_view_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_VIEW_MATRIX, "transpose_view_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_VIEW_MATRIX, "inverse_transpose_view_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_PROJECTION_MATRIX, "projection_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_PROJECTION_MATRIX, "inverse_projection_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_PROJECTION_MATRIX, "transpose_projection_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_PROJECTION_MATRIX, "inverse_transpose_projection_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_VIEWPROJ_MATRIX, "viewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_VIEWPROJ_MATRIX, "inverse_viewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_VIEWPROJ_MATRIX, "transpose_viewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_VIEWPROJ_MATRIX, "inverse_transpose_viewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, "worldview_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_WORLDVIEW_MATRIX, "inverse_worldview_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_WORLDVIEW_MATRIX, "transpose_worldview_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, "inverse_transpose_worldview_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, "worldviewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_WORLDVIEWPROJ_MATRIX, "inverse_worldviewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_WORLDVIEWPROJ_MATRIX, "transpose_worldviewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEWPROJ_MATRIX, "inverse_transpose_worldviewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_RENDER_TARGET_FLIPPING, "render_target_flipping", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_VERTEX_WINDING, "vertex_winding", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_FOG_COLOUR, "fog_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_FOG_PARAMS, "fog_params", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR, "surface_ambient_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR, "surface_diffuse_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR, "surface_specular_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR, "surface_emissive_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_SHININESS, "surface_shininess", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_ALPHA_REJECTION_VALUE, "surface_alpha_rejection_value", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_COUNT, "light_count", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, "ambient_light_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, "light_diffuse_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, "light_specular_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_ATTENUATION, "light_attenuation", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_PARAMS, "spotlight_params", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION, "light_position", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, "light_position_object_space", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE, "light_position_view_space", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION, "light_direction", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_OBJECT_SPACE, "light_direction_object_space", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_VIEW_SPACE, "light_direction_view_space", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DISTANCE_OBJECT_SPACE, "light_distance_object_space", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POWER_SCALE, "light_power", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED, "light_diffuse_colour_power_scaled", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED, "light_specular_colour_power_scaled", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR_ARRAY, "light_diffuse_colour_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR_ARRAY, "light_specular_colour_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED_ARRAY, "light_diffuse_colour_power_scaled_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED_ARRAY, "light_specular_colour_power_scaled_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_ATTENUATION_ARRAY, "light_attenuation_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION_ARRAY, "light_position_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE_ARRAY, "light_position_object_space_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY, "light_position_view_space_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_ARRAY, "light_direction_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_OBJECT_SPACE_ARRAY, "light_direction_object_space_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_VIEW_SPACE_ARRAY, "light_direction_view_space_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DISTANCE_OBJECT_SPACE_ARRAY, "light_distance_object_space_array", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POWER_SCALE_ARRAY, "light_power_array", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_PARAMS_ARRAY, "spotlight_params_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR, "derived_ambient_light_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, "derived_scene_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR, "derived_light_diffuse_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_LIGHT_SPECULAR_COLOUR, "derived_light_specular_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR_ARRAY, "derived_light_diffuse_colour_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_LIGHT_SPECULAR_COLOUR_ARRAY, "derived_light_specular_colour_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_NUMBER, "light_number", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_CASTS_SHADOWS, "light_casts_shadows", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_CASTS_SHADOWS_ARRAY, "light_casts_shadows_array", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_SHADOW_EXTRUSION_DISTANCE, "shadow_extrusion_distance", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_CAMERA_POSITION, "camera_position", GCT_FLOAT3), - AutoShaderParameter(GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE, "camera_position_object_space", GCT_FLOAT3), - AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, "texture_viewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX_ARRAY, "texture_viewproj_matrix_array", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_WORLDVIEWPROJ_MATRIX, "texture_worldviewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_WORLDVIEWPROJ_MATRIX_ARRAY, "texture_worldviewproj_matrix_array", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_VIEWPROJ_MATRIX, "spotlight_viewproj_matrix", GCT_MATRIX_4X4), + //----------------------------------------------------------------------- + // Define some ConstParameterTypes + //----------------------------------------------------------------------- + + /** ConstParameterVec2 represents a Vector2 constant. + */ + class ConstParameterVec2 : public ConstParameter + { + public: + ConstParameterVec2( Vector2 val, + GpuConstantType type, + const Semantic& semantic, + const Content& content) + : ConstParameter(val, type, semantic, content) + { + } + + ~ConstParameterVec2() {} + + /** + @see Parameter::toString. + */ + virtual String toString () const + { + const String& lang = ShaderGenerator::getSingleton().getTargetLanguage(); + return + ((lang.empty() == false) && (lang[0] == 'g') ? String("vec2(") : String("float2(")) + + Ogre::StringConverter::toString(mValue.x) + "," + + Ogre::StringConverter::toString(mValue.y) + ")"; + } + }; + + /** ConstParameterVec3 represents a Vector3 constant. + */ + class ConstParameterVec3 : public ConstParameter + { + public: + ConstParameterVec3( Vector3 val, + GpuConstantType type, + const Semantic& semantic, + const Content& content) + : ConstParameter(val, type, semantic, content) + { + } + ~ConstParameterVec3() {} + + /** + @see Parameter::toString. + */ + virtual String toString () const + { + const String& lang = ShaderGenerator::getSingleton().getTargetLanguage(); + return + ((lang.empty() == false) && (lang[0] == 'g') ? String("vec3(") : String("float3(")) + + Ogre::StringConverter::toString(mValue.x) + "," + + Ogre::StringConverter::toString(mValue.y) + "," + + Ogre::StringConverter::toString(mValue.z) + ")"; + } + }; + + /** ConstParameterVec4 represents a Vector2 Vector4. + */ + class ConstParameterVec4 : public ConstParameter + { + public: + ConstParameterVec4( Vector4 val, + GpuConstantType type, + const Semantic& semantic, + const Content& content) + : ConstParameter(val, type, semantic, content) + { + } + ~ConstParameterVec4() {} + + /** + @see Parameter::toString. + */ + virtual String toString () const + { + const String& lang = ShaderGenerator::getSingleton().getTargetLanguage(); + return + ((lang.empty() == false) && (lang[0] == 'g') ? String("vec4(") : String("float4(")) + + Ogre::StringConverter::toString(mValue.x) + "," + + Ogre::StringConverter::toString(mValue.y) + "," + + Ogre::StringConverter::toString(mValue.z) + "," + + Ogre::StringConverter::toString(mValue.w) + ")"; + } + }; + + /** ConstParameterFloat represents a float constant. + */ + class ConstParameterFloat : public ConstParameter + { + public: + ConstParameterFloat(float val, + GpuConstantType type, + const Semantic& semantic, + const Content& content) + : ConstParameter(val, type, semantic, content) + { + } + + ~ConstParameterFloat() {} + + /** + @see Parameter::toString. + */ + virtual String toString () const + { + String val = Ogre::StringConverter::toString(mValue); + + // Make sure that float params have always this representation #.# + if(val.find(".") == String::npos) + { + val += ".0"; + } + + return val; + } + }; + /** ConstParameterInt represents an int constant. + */ + class ConstParameterInt : public ConstParameter + { + public: + ConstParameterInt(int val, + GpuConstantType type, + const Semantic& semantic, + const Content& content) + : ConstParameter(val, type, semantic, content) + { + } + + ~ConstParameterInt() {} + + /** + @see Parameter::toString. + */ + virtual String toString () const + { + return Ogre::StringConverter::toString(mValue); + } + }; + + //----------------------------------------------------------------------- + + struct AutoShaderParameter + { + GpuProgramParameters::AutoConstantType autoType; + String name; + GpuConstantType type; + + + AutoShaderParameter(GpuProgramParameters::AutoConstantType _autoType, + const String& _name, + GpuConstantType _type) : autoType(_autoType), name(_name), type(_type) + { + } + }; + + AutoShaderParameter g_AutoParameters[] = { + AutoShaderParameter(GpuProgramParameters::ACT_WORLD_MATRIX, "world_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_WORLD_MATRIX, "inverse_world_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_WORLD_MATRIX, "transpose_world_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, "inverse_transpose_world_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4, "world_matrix_array_3x4", GCT_MATRIX_3X4), + AutoShaderParameter(GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY, "world_matrix_array", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4, "world_dualquaternion_array_2x4", GCT_MATRIX_2X4), + AutoShaderParameter(GpuProgramParameters::ACT_WORLD_SCALE_SHEAR_MATRIX_ARRAY_3x4, "world_scale_shear_matrix_array_3x4", GCT_MATRIX_3X4), + AutoShaderParameter(GpuProgramParameters::ACT_VIEW_MATRIX, "view_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_VIEW_MATRIX, "inverse_view_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_VIEW_MATRIX, "transpose_view_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_VIEW_MATRIX, "inverse_transpose_view_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_PROJECTION_MATRIX, "projection_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_PROJECTION_MATRIX, "inverse_projection_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_PROJECTION_MATRIX, "transpose_projection_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_PROJECTION_MATRIX, "inverse_transpose_projection_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_VIEWPROJ_MATRIX, "viewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_VIEWPROJ_MATRIX, "inverse_viewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_VIEWPROJ_MATRIX, "transpose_viewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_VIEWPROJ_MATRIX, "inverse_transpose_viewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, "worldview_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_WORLDVIEW_MATRIX, "inverse_worldview_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_WORLDVIEW_MATRIX, "transpose_worldview_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, "inverse_transpose_worldview_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX, "worldviewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_WORLDVIEWPROJ_MATRIX, "inverse_worldviewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_TRANSPOSE_WORLDVIEWPROJ_MATRIX, "transpose_worldviewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEWPROJ_MATRIX, "inverse_transpose_worldviewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_RENDER_TARGET_FLIPPING, "render_target_flipping", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_VERTEX_WINDING, "vertex_winding", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_FOG_COLOUR, "fog_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_FOG_PARAMS, "fog_params", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR, "surface_ambient_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR, "surface_diffuse_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR, "surface_specular_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR, "surface_emissive_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_SHININESS, "surface_shininess", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_SURFACE_ALPHA_REJECTION_VALUE, "surface_alpha_rejection_value", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_COUNT, "light_count", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, "ambient_light_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, "light_diffuse_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, "light_specular_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_ATTENUATION, "light_attenuation", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_PARAMS, "spotlight_params", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION, "light_position", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, "light_position_object_space", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE, "light_position_view_space", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION, "light_direction", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_OBJECT_SPACE, "light_direction_object_space", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_VIEW_SPACE, "light_direction_view_space", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DISTANCE_OBJECT_SPACE, "light_distance_object_space", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POWER_SCALE, "light_power", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED, "light_diffuse_colour_power_scaled", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED, "light_specular_colour_power_scaled", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR_ARRAY, "light_diffuse_colour_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR_ARRAY, "light_specular_colour_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR_POWER_SCALED_ARRAY, "light_diffuse_colour_power_scaled_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR_POWER_SCALED_ARRAY, "light_specular_colour_power_scaled_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_ATTENUATION_ARRAY, "light_attenuation_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION_ARRAY, "light_position_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE_ARRAY, "light_position_object_space_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE_ARRAY, "light_position_view_space_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_ARRAY, "light_direction_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_OBJECT_SPACE_ARRAY, "light_direction_object_space_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DIRECTION_VIEW_SPACE_ARRAY, "light_direction_view_space_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_DISTANCE_OBJECT_SPACE_ARRAY, "light_distance_object_space_array", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_POWER_SCALE_ARRAY, "light_power_array", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_PARAMS_ARRAY, "spotlight_params_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR, "derived_ambient_light_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, "derived_scene_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR, "derived_light_diffuse_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_LIGHT_SPECULAR_COLOUR, "derived_light_specular_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR_ARRAY, "derived_light_diffuse_colour_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_DERIVED_LIGHT_SPECULAR_COLOUR_ARRAY, "derived_light_specular_colour_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_NUMBER, "light_number", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_CASTS_SHADOWS, "light_casts_shadows", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_CASTS_SHADOWS_ARRAY, "light_casts_shadows_array", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_SHADOW_EXTRUSION_DISTANCE, "shadow_extrusion_distance", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_CAMERA_POSITION, "camera_position", GCT_FLOAT3), + AutoShaderParameter(GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE, "camera_position_object_space", GCT_FLOAT3), + AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, "texture_viewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX_ARRAY, "texture_viewproj_matrix_array", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_WORLDVIEWPROJ_MATRIX, "texture_worldviewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_WORLDVIEWPROJ_MATRIX_ARRAY, "texture_worldviewproj_matrix_array", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_VIEWPROJ_MATRIX, "spotlight_viewproj_matrix", GCT_MATRIX_4X4), AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_VIEWPROJ_MATRIX_ARRAY, "spotlight_viewproj_matrix_array", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX, "spotlight_worldviewproj_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX_ARRAY, "spotlight_worldviewproj_matrix_array", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_CUSTOM, "custom", GCT_FLOAT4), // *** needs to be tested - AutoShaderParameter(GpuProgramParameters::ACT_TIME, "time", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_X, "time_0_x", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_COSTIME_0_X, "costime_0_x", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_SINTIME_0_X, "sintime_0_x", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_TANTIME_0_X, "tantime_0_x", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_X_PACKED, "time_0_x_packed", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_1, "time_0_1", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_COSTIME_0_1, "costime_0_1", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_SINTIME_0_1, "sintime_0_1", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_TANTIME_0_1, "tantime_0_1", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_1_PACKED, "time_0_1_packed", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_2PI, "time_0_2pi", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_COSTIME_0_2PI, "costime_0_2pi", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_SINTIME_0_2PI, "sintime_0_2pi", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_TANTIME_0_2PI, "tantime_0_2pi", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_2PI_PACKED, "time_0_2pi_packed", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_FRAME_TIME, "frame_time", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_FPS, "fps", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_VIEWPORT_WIDTH, "viewport_width", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_VIEWPORT_HEIGHT, "viewport_height", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_VIEWPORT_WIDTH, "inverse_viewport_width", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_VIEWPORT_HEIGHT, "inverse_viewport_height", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_VIEWPORT_SIZE, "viewport_size", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_VIEW_DIRECTION, "view_direction", GCT_FLOAT3), - AutoShaderParameter(GpuProgramParameters::ACT_VIEW_SIDE_VECTOR, "view_side_vector", GCT_FLOAT3), - AutoShaderParameter(GpuProgramParameters::ACT_VIEW_UP_VECTOR, "view_up_vector", GCT_FLOAT3), - AutoShaderParameter(GpuProgramParameters::ACT_FOV, "fov", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_NEAR_CLIP_DISTANCE, "near_clip_distance", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_FAR_CLIP_DISTANCE, "far_clip_distance", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_PASS_NUMBER, "pass_number", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_PASS_ITERATION_NUMBER, "pass_iteration_number", GCT_FLOAT1), - AutoShaderParameter(GpuProgramParameters::ACT_ANIMATION_PARAMETRIC, "animation_parametric", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_TEXEL_OFFSETS, "texel_offsets", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_SCENE_DEPTH_RANGE, "scene_depth_range", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE, "shadow_scene_depth_range", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE_ARRAY, "shadow_scene_depth_range_array", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_SHADOW_COLOUR, "shadow_colour", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_SIZE, "texture_size", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, "inverse_texture_size", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_PACKED_TEXTURE_SIZE, "packed_texture_size", GCT_FLOAT4), - AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_MATRIX, "texture_matrix", GCT_MATRIX_4X4), - AutoShaderParameter(GpuProgramParameters::ACT_LOD_CAMERA_POSITION, "lod_camera_position", GCT_FLOAT3), - AutoShaderParameter(GpuProgramParameters::ACT_LOD_CAMERA_POSITION_OBJECT_SPACE, "lod_camera_position_object_space", GCT_FLOAT3), + AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX, "spotlight_worldviewproj_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX_ARRAY, "spotlight_worldviewproj_matrix_array", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_CUSTOM, "custom", GCT_FLOAT4), // *** needs to be tested + AutoShaderParameter(GpuProgramParameters::ACT_TIME, "time", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_X, "time_0_x", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_COSTIME_0_X, "costime_0_x", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_SINTIME_0_X, "sintime_0_x", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_TANTIME_0_X, "tantime_0_x", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_X_PACKED, "time_0_x_packed", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_1, "time_0_1", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_COSTIME_0_1, "costime_0_1", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_SINTIME_0_1, "sintime_0_1", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_TANTIME_0_1, "tantime_0_1", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_1_PACKED, "time_0_1_packed", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_2PI, "time_0_2pi", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_COSTIME_0_2PI, "costime_0_2pi", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_SINTIME_0_2PI, "sintime_0_2pi", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_TANTIME_0_2PI, "tantime_0_2pi", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_TIME_0_2PI_PACKED, "time_0_2pi_packed", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_FRAME_TIME, "frame_time", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_FPS, "fps", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_VIEWPORT_WIDTH, "viewport_width", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_VIEWPORT_HEIGHT, "viewport_height", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_VIEWPORT_WIDTH, "inverse_viewport_width", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_VIEWPORT_HEIGHT, "inverse_viewport_height", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_VIEWPORT_SIZE, "viewport_size", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_VIEW_DIRECTION, "view_direction", GCT_FLOAT3), + AutoShaderParameter(GpuProgramParameters::ACT_VIEW_SIDE_VECTOR, "view_side_vector", GCT_FLOAT3), + AutoShaderParameter(GpuProgramParameters::ACT_VIEW_UP_VECTOR, "view_up_vector", GCT_FLOAT3), + AutoShaderParameter(GpuProgramParameters::ACT_FOV, "fov", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_NEAR_CLIP_DISTANCE, "near_clip_distance", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_FAR_CLIP_DISTANCE, "far_clip_distance", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_PASS_NUMBER, "pass_number", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_PASS_ITERATION_NUMBER, "pass_iteration_number", GCT_FLOAT1), + AutoShaderParameter(GpuProgramParameters::ACT_ANIMATION_PARAMETRIC, "animation_parametric", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_TEXEL_OFFSETS, "texel_offsets", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_SCENE_DEPTH_RANGE, "scene_depth_range", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE, "shadow_scene_depth_range", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE_ARRAY, "shadow_scene_depth_range_array", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_SHADOW_COLOUR, "shadow_colour", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_SIZE, "texture_size", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, "inverse_texture_size", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_PACKED_TEXTURE_SIZE, "packed_texture_size", GCT_FLOAT4), + AutoShaderParameter(GpuProgramParameters::ACT_TEXTURE_MATRIX, "texture_matrix", GCT_MATRIX_4X4), + AutoShaderParameter(GpuProgramParameters::ACT_LOD_CAMERA_POSITION, "lod_camera_position", GCT_FLOAT3), + AutoShaderParameter(GpuProgramParameters::ACT_LOD_CAMERA_POSITION_OBJECT_SPACE, "lod_camera_position_object_space", GCT_FLOAT3), AutoShaderParameter(GpuProgramParameters::ACT_LIGHT_CUSTOM, "light_custom", GCT_FLOAT1) - }; + }; //----------------------------------------------------------------------- Parameter::Parameter() : mName(""), mType(GCT_UNKNOWN), mSemantic(SPS_UNKNOWN), mIndex(0), mContent(SPC_UNKNOWN), mSize(0) @@ -338,7 +338,7 @@ Parameter::Parameter() : mName(""), mType(GCT_UNKNOWN), mSemantic(SPS_UNKNOWN), //----------------------------------------------------------------------- Parameter::Parameter(GpuConstantType type, const String& name, - const Semantic& semantic, int index, + const Semantic& semantic, int index, const Content& content, size_t size) : mName(name), mType(type), mSemantic(semantic), mIndex(index), mContent(content), mSize(size) { @@ -347,289 +347,289 @@ Parameter::Parameter(GpuConstantType type, const String& name, //----------------------------------------------------------------------- bool UniformParameter::isFloat() const { - switch(getType()) - { - case GCT_INT1: - case GCT_INT2: - case GCT_INT3: - case GCT_INT4: - case GCT_UINT1: - case GCT_UINT2: - case GCT_UINT3: - case GCT_UINT4: - case GCT_SAMPLER1D: - case GCT_SAMPLER2D: + switch(getType()) + { + case GCT_INT1: + case GCT_INT2: + case GCT_INT3: + case GCT_INT4: + case GCT_UINT1: + case GCT_UINT2: + case GCT_UINT3: + case GCT_UINT4: + case GCT_SAMPLER1D: + case GCT_SAMPLER2D: case GCT_SAMPLER2DARRAY: - case GCT_SAMPLER3D: - case GCT_SAMPLERCUBE: - case GCT_SAMPLER1DSHADOW: - case GCT_SAMPLER2DSHADOW: - return false; - default: - return true; - }; + case GCT_SAMPLER3D: + case GCT_SAMPLERCUBE: + case GCT_SAMPLER1DSHADOW: + case GCT_SAMPLER2DSHADOW: + return false; + default: + return true; + }; } //----------------------------------------------------------------------- bool UniformParameter::isSampler() const { - switch(getType()) - { - case GCT_SAMPLER1D: - case GCT_SAMPLER2D: + switch(getType()) + { + case GCT_SAMPLER1D: + case GCT_SAMPLER2D: case GCT_SAMPLER2DARRAY: - case GCT_SAMPLER3D: - case GCT_SAMPLERCUBE: - case GCT_SAMPLER1DSHADOW: - case GCT_SAMPLER2DSHADOW: - return true; - default: - return false; - }; + case GCT_SAMPLER3D: + case GCT_SAMPLERCUBE: + case GCT_SAMPLER1DSHADOW: + case GCT_SAMPLER2DSHADOW: + return true; + default: + return false; + }; } //----------------------------------------------------------------------- UniformParameter::UniformParameter(GpuConstantType type, const String& name, - const Semantic& semantic, int index, - const Content& content, - uint16 variability, size_t size) : Parameter(type, name, semantic, index, content, size) -{ - mIsAutoConstantReal = false; - mIsAutoConstantInt = false; - mAutoConstantIntData = 0; - mVariability = variability; - mParamsPtr = NULL; - mPhysicalIndex = -1; + const Semantic& semantic, int index, + const Content& content, + uint16 variability, size_t size) : Parameter(type, name, semantic, index, content, size) +{ + mIsAutoConstantReal = false; + mIsAutoConstantInt = false; + mAutoConstantIntData = 0; + mVariability = variability; + mParamsPtr = NULL; + mPhysicalIndex = -1; mAutoConstantType = GpuProgramParameters::ACT_UNKNOWN; } //----------------------------------------------------------------------- UniformParameter::UniformParameter(GpuProgramParameters::AutoConstantType autoType, Real fAutoConstantData, size_t size) { - AutoShaderParameter* parameterDef = &g_AutoParameters[autoType]; - - mName = parameterDef->name; - if (fAutoConstantData != 0.0) - { - mName += StringConverter::toString(fAutoConstantData); - //replace possible illegal point character in name - std::replace(mName.begin(), mName.end(), '.', '_'); - } - mType = parameterDef->type; - mSemantic = SPS_UNKNOWN; - mIndex = -1; - mContent = SPC_UNKNOWN; - mIsAutoConstantReal = true; - mIsAutoConstantInt = false; - mAutoConstantType = autoType; - mAutoConstantRealData = fAutoConstantData; - mVariability = (uint16)GPV_GLOBAL; - mParamsPtr = NULL; - mPhysicalIndex = -1; - mSize = size; + AutoShaderParameter* parameterDef = &g_AutoParameters[autoType]; + + mName = parameterDef->name; + if (fAutoConstantData != 0.0) + { + mName += StringConverter::toString(fAutoConstantData); + //replace possible illegal point character in name + std::replace(mName.begin(), mName.end(), '.', '_'); + } + mType = parameterDef->type; + mSemantic = SPS_UNKNOWN; + mIndex = -1; + mContent = SPC_UNKNOWN; + mIsAutoConstantReal = true; + mIsAutoConstantInt = false; + mAutoConstantType = autoType; + mAutoConstantRealData = fAutoConstantData; + mVariability = (uint16)GPV_GLOBAL; + mParamsPtr = NULL; + mPhysicalIndex = -1; + mSize = size; } //----------------------------------------------------------------------- UniformParameter::UniformParameter(GpuProgramParameters::AutoConstantType autoType, Real fAutoConstantData, size_t size, GpuConstantType type) { - AutoShaderParameter* parameterDef = &g_AutoParameters[autoType]; - - mName = parameterDef->name; - if (fAutoConstantData != 0.0) - { - mName += StringConverter::toString(fAutoConstantData); - //replace possible illegal point character in name - std::replace(mName.begin(), mName.end(), '.', '_'); - } - mType = type; - mSemantic = SPS_UNKNOWN; - mIndex = -1; - mContent = SPC_UNKNOWN; - mIsAutoConstantReal = true; - mIsAutoConstantInt = false; - mAutoConstantType = autoType; - mAutoConstantRealData = fAutoConstantData; - mVariability = (uint16)GPV_GLOBAL; - mParamsPtr = NULL; - mPhysicalIndex = -1; - mSize = size; + AutoShaderParameter* parameterDef = &g_AutoParameters[autoType]; + + mName = parameterDef->name; + if (fAutoConstantData != 0.0) + { + mName += StringConverter::toString(fAutoConstantData); + //replace possible illegal point character in name + std::replace(mName.begin(), mName.end(), '.', '_'); + } + mType = type; + mSemantic = SPS_UNKNOWN; + mIndex = -1; + mContent = SPC_UNKNOWN; + mIsAutoConstantReal = true; + mIsAutoConstantInt = false; + mAutoConstantType = autoType; + mAutoConstantRealData = fAutoConstantData; + mVariability = (uint16)GPV_GLOBAL; + mParamsPtr = NULL; + mPhysicalIndex = -1; + mSize = size; } //----------------------------------------------------------------------- UniformParameter::UniformParameter(GpuProgramParameters::AutoConstantType autoType, size_t nAutoConstantData, size_t size) { - AutoShaderParameter* parameterDef = &g_AutoParameters[autoType]; + AutoShaderParameter* parameterDef = &g_AutoParameters[autoType]; - mName = parameterDef->name; - if (nAutoConstantData != 0) - mName += StringConverter::toString(nAutoConstantData); - mType = parameterDef->type; - mSemantic = SPS_UNKNOWN; - mIndex = -1; - mContent = SPC_UNKNOWN; - mIsAutoConstantReal = false; - mIsAutoConstantInt = true; - mAutoConstantType = autoType; - mAutoConstantIntData = nAutoConstantData; - mVariability = (uint16)GPV_GLOBAL; - mParamsPtr = NULL; - mPhysicalIndex = -1; - mSize = size; + mName = parameterDef->name; + if (nAutoConstantData != 0) + mName += StringConverter::toString(nAutoConstantData); + mType = parameterDef->type; + mSemantic = SPS_UNKNOWN; + mIndex = -1; + mContent = SPC_UNKNOWN; + mIsAutoConstantReal = false; + mIsAutoConstantInt = true; + mAutoConstantType = autoType; + mAutoConstantIntData = nAutoConstantData; + mVariability = (uint16)GPV_GLOBAL; + mParamsPtr = NULL; + mPhysicalIndex = -1; + mSize = size; } //----------------------------------------------------------------------- UniformParameter::UniformParameter(GpuProgramParameters::AutoConstantType autoType, size_t nAutoConstantData, size_t size, GpuConstantType type) { - AutoShaderParameter* parameterDef = &g_AutoParameters[autoType]; + AutoShaderParameter* parameterDef = &g_AutoParameters[autoType]; - mName = parameterDef->name; - if (nAutoConstantData != 0) - mName += StringConverter::toString(nAutoConstantData); - mType = type; - mSemantic = SPS_UNKNOWN; - mIndex = -1; - mContent = SPC_UNKNOWN; - mIsAutoConstantReal = false; - mIsAutoConstantInt = true; - mAutoConstantType = autoType; - mAutoConstantIntData = nAutoConstantData; - mVariability = (uint16)GPV_GLOBAL; - mParamsPtr = NULL; - mPhysicalIndex = -1; - mSize = size; + mName = parameterDef->name; + if (nAutoConstantData != 0) + mName += StringConverter::toString(nAutoConstantData); + mType = type; + mSemantic = SPS_UNKNOWN; + mIndex = -1; + mContent = SPC_UNKNOWN; + mIsAutoConstantReal = false; + mIsAutoConstantInt = true; + mAutoConstantType = autoType; + mAutoConstantIntData = nAutoConstantData; + mVariability = (uint16)GPV_GLOBAL; + mParamsPtr = NULL; + mPhysicalIndex = -1; + mSize = size; } //----------------------------------------------------------------------- void UniformParameter::bind(GpuProgramParametersSharedPtr paramsPtr) -{ - if (paramsPtr.get() != NULL) - { - const GpuConstantDefinition* def = paramsPtr->_findNamedConstantDefinition(mName); +{ + if (paramsPtr.get() != NULL) + { + const GpuConstantDefinition* def = paramsPtr->_findNamedConstantDefinition(mName); - if (def != NULL) - { - mParamsPtr = paramsPtr.get(); - mPhysicalIndex = def->physicalIndex; - } - } + if (def != NULL) + { + mParamsPtr = paramsPtr.get(); + mPhysicalIndex = def->physicalIndex; + } + } } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInPosition(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "iPos_" + StringConverter::toString(index), - Parameter::SPS_POSITION, index, - Parameter::SPC_POSITION_OBJECT_SPACE)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "iPos_" + StringConverter::toString(index), + Parameter::SPS_POSITION, index, + Parameter::SPC_POSITION_OBJECT_SPACE)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createOutPosition(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "oPos_" + StringConverter::toString(index), - Parameter::SPS_POSITION, index, - Parameter::SPC_POSITION_PROJECTIVE_SPACE)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "oPos_" + StringConverter::toString(index), + Parameter::SPS_POSITION, index, + Parameter::SPC_POSITION_PROJECTIVE_SPACE)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInNormal(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "iNormal_" + StringConverter::toString(index), - Parameter::SPS_NORMAL, index, - Parameter::SPC_NORMAL_OBJECT_SPACE)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "iNormal_" + StringConverter::toString(index), + Parameter::SPS_NORMAL, index, + Parameter::SPC_NORMAL_OBJECT_SPACE)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInWeights(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "iBlendWeights_" + StringConverter::toString(index), - Parameter::SPS_BLEND_WEIGHTS, index, - Parameter::SPC_BLEND_WEIGHTS)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "iBlendWeights_" + StringConverter::toString(index), + Parameter::SPS_BLEND_WEIGHTS, index, + Parameter::SPC_BLEND_WEIGHTS)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInIndices(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "iBlendIndices_" + StringConverter::toString(index), - Parameter::SPS_BLEND_INDICES, index, - Parameter::SPC_BLEND_INDICES)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "iBlendIndices_" + StringConverter::toString(index), + Parameter::SPS_BLEND_INDICES, index, + Parameter::SPC_BLEND_INDICES)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInBiNormal(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "iBiNormal_" + StringConverter::toString(index), - Parameter::SPS_BINORMAL, index, - Parameter::SPC_BINORMAL_OBJECT_SPACE)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "iBiNormal_" + StringConverter::toString(index), + Parameter::SPS_BINORMAL, index, + Parameter::SPC_BINORMAL_OBJECT_SPACE)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInTangent(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "iTangent_" + StringConverter::toString(index), - Parameter::SPS_TANGENT, index, - Parameter::SPC_TANGENT_OBJECT_SPACE)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "iTangent_" + StringConverter::toString(index), + Parameter::SPS_TANGENT, index, + Parameter::SPC_TANGENT_OBJECT_SPACE)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createOutNormal(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "oNormal_" + StringConverter::toString(index), - Parameter::SPS_NORMAL, index, - Parameter::SPC_NORMAL_OBJECT_SPACE)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "oNormal_" + StringConverter::toString(index), + Parameter::SPS_NORMAL, index, + Parameter::SPC_NORMAL_OBJECT_SPACE)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createOutBiNormal(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "oBiNormal_" + StringConverter::toString(index), - Parameter::SPS_BINORMAL, index, - Parameter::SPC_BINORMAL_OBJECT_SPACE)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "oBiNormal_" + StringConverter::toString(index), + Parameter::SPS_BINORMAL, index, + Parameter::SPC_BINORMAL_OBJECT_SPACE)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createOutTangent(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "oTangent_" + StringConverter::toString(index), - Parameter::SPS_TANGENT, index, - Parameter::SPC_TANGENT_OBJECT_SPACE)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "oTangent_" + StringConverter::toString(index), + Parameter::SPS_TANGENT, index, + Parameter::SPC_TANGENT_OBJECT_SPACE)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInColor(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "iColor_" + StringConverter::toString(index), - Parameter::SPS_COLOR, index, - index == 0 ? Parameter::SPC_COLOR_DIFFUSE : Parameter::SPC_COLOR_SPECULAR)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "iColor_" + StringConverter::toString(index), + Parameter::SPS_COLOR, index, + index == 0 ? Parameter::SPC_COLOR_DIFFUSE : Parameter::SPC_COLOR_SPECULAR)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createOutColor(int index) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "oColor_" + StringConverter::toString(index), - Parameter::SPS_COLOR, index, - index == 0 ? Parameter::SPC_COLOR_DIFFUSE : Parameter::SPC_COLOR_SPECULAR)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "oColor_" + StringConverter::toString(index), + Parameter::SPS_COLOR, index, + index == 0 ? Parameter::SPC_COLOR_DIFFUSE : Parameter::SPC_COLOR_SPECULAR)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInTexcoord(GpuConstantType type, int index, Parameter::Content content) { - switch (type) - { - case GCT_FLOAT1: - return createInTexcoord1(index, content); - - case GCT_FLOAT2: - return createInTexcoord2(index, content); - - case GCT_FLOAT3: - return createInTexcoord3(index, content); - - case GCT_FLOAT4: - return createInTexcoord4(index, content); + switch (type) + { + case GCT_FLOAT1: + return createInTexcoord1(index, content); + + case GCT_FLOAT2: + return createInTexcoord2(index, content); + + case GCT_FLOAT3: + return createInTexcoord3(index, content); + + case GCT_FLOAT4: + return createInTexcoord4(index, content); default: - case GCT_SAMPLER1D: + case GCT_SAMPLER1D: case GCT_SAMPLER2D: case GCT_SAMPLER2DARRAY: case GCT_SAMPLER3D: @@ -645,40 +645,40 @@ ParameterPtr ParameterFactory::createInTexcoord(GpuConstantType type, int index, case GCT_MATRIX_4X2: case GCT_MATRIX_4X3: case GCT_MATRIX_4X4: - case GCT_INT1: - case GCT_INT2: - case GCT_INT3: - case GCT_INT4: - case GCT_UINT1: - case GCT_UINT2: - case GCT_UINT3: - case GCT_UINT4: - case GCT_UNKNOWN: + case GCT_INT1: + case GCT_INT2: + case GCT_INT3: + case GCT_INT4: + case GCT_UINT1: + case GCT_UINT2: + case GCT_UINT3: + case GCT_UINT4: + case GCT_UNKNOWN: break; - } + } - return ParameterPtr(); + return ParameterPtr(); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createOutTexcoord(GpuConstantType type, int index, Parameter::Content content) { - switch (type) - { - case GCT_FLOAT1: - return createOutTexcoord1(index, content); + switch (type) + { + case GCT_FLOAT1: + return createOutTexcoord1(index, content); - case GCT_FLOAT2: - return createOutTexcoord2(index, content); + case GCT_FLOAT2: + return createOutTexcoord2(index, content); - case GCT_FLOAT3: - return createOutTexcoord3(index, content); + case GCT_FLOAT3: + return createOutTexcoord3(index, content); - case GCT_FLOAT4: - return createOutTexcoord4(index, content); + case GCT_FLOAT4: + return createOutTexcoord4(index, content); default: - case GCT_SAMPLER1D: + case GCT_SAMPLER1D: case GCT_SAMPLER2D: case GCT_SAMPLER2DARRAY: case GCT_SAMPLER3D: @@ -698,100 +698,100 @@ ParameterPtr ParameterFactory::createOutTexcoord(GpuConstantType type, int index case GCT_INT2: case GCT_INT3: case GCT_INT4: - case GCT_UINT1: - case GCT_UINT2: - case GCT_UINT3: - case GCT_UINT4: - case GCT_UNKNOWN: + case GCT_UINT1: + case GCT_UINT2: + case GCT_UINT3: + case GCT_UINT4: + case GCT_UNKNOWN: break; - } + } - return ParameterPtr(); + return ParameterPtr(); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInTexcoord1(int index, Parameter::Content content) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT1, "iTexcoord1_" + StringConverter::toString(index), - Parameter::SPS_TEXTURE_COORDINATES, index, - content)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT1, "iTexcoord1_" + StringConverter::toString(index), + Parameter::SPS_TEXTURE_COORDINATES, index, + content)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createOutTexcoord1(int index, Parameter::Content content) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT1, "oTexcoord1_" + StringConverter::toString(index), - Parameter::SPS_TEXTURE_COORDINATES, index, - content)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT1, "oTexcoord1_" + StringConverter::toString(index), + Parameter::SPS_TEXTURE_COORDINATES, index, + content)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInTexcoord2(int index, Parameter::Content content) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT2, "iTexcoord2_" + StringConverter::toString(index), - Parameter::SPS_TEXTURE_COORDINATES, index, - content)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT2, "iTexcoord2_" + StringConverter::toString(index), + Parameter::SPS_TEXTURE_COORDINATES, index, + content)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createOutTexcoord2(int index, Parameter::Content content) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT2, "oTexcoord2_" + StringConverter::toString(index), - Parameter::SPS_TEXTURE_COORDINATES, index, - content)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT2, "oTexcoord2_" + StringConverter::toString(index), + Parameter::SPS_TEXTURE_COORDINATES, index, + content)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInTexcoord3(int index, Parameter::Content content) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "iTexcoord3_" + StringConverter::toString(index), - Parameter::SPS_TEXTURE_COORDINATES, index, - content)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "iTexcoord3_" + StringConverter::toString(index), + Parameter::SPS_TEXTURE_COORDINATES, index, + content)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createOutTexcoord3(int index, Parameter::Content content) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "oTexcoord3_" + StringConverter::toString(index), - Parameter::SPS_TEXTURE_COORDINATES, index, - content)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT3, "oTexcoord3_" + StringConverter::toString(index), + Parameter::SPS_TEXTURE_COORDINATES, index, + content)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createInTexcoord4(int index, Parameter::Content content) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "iTexcoord4_" + StringConverter::toString(index), - Parameter::SPS_TEXTURE_COORDINATES, index, - content)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "iTexcoord4_" + StringConverter::toString(index), + Parameter::SPS_TEXTURE_COORDINATES, index, + content)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createOutTexcoord4(int index, Parameter::Content content) { - return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "oTexcoord4_" + StringConverter::toString(index), - Parameter::SPS_TEXTURE_COORDINATES, index, - content)); + return ParameterPtr(OGRE_NEW Parameter(GCT_FLOAT4, "oTexcoord4_" + StringConverter::toString(index), + Parameter::SPS_TEXTURE_COORDINATES, index, + content)); } //----------------------------------------------------------------------- UniformParameterPtr ParameterFactory::createSampler(GpuConstantType type, int index) { - switch (type) - { - case GCT_SAMPLER1D: - return createSampler1D(index); + switch (type) + { + case GCT_SAMPLER1D: + return createSampler1D(index); - case GCT_SAMPLER2D: - return createSampler2D(index); + case GCT_SAMPLER2D: + return createSampler2D(index); case GCT_SAMPLER2DARRAY: return createSampler2DArray(index); - case GCT_SAMPLER3D: - return createSampler3D(index); + case GCT_SAMPLER3D: + return createSampler3D(index); - case GCT_SAMPLERCUBE: - return createSamplerCUBE(index); + case GCT_SAMPLERCUBE: + return createSamplerCUBE(index); default: case GCT_SAMPLER1DSHADOW: @@ -809,34 +809,34 @@ UniformParameterPtr ParameterFactory::createSampler(GpuConstantType type, int in case GCT_INT2: case GCT_INT3: case GCT_INT4: - case GCT_UINT1: - case GCT_UINT2: - case GCT_UINT3: - case GCT_UINT4: + case GCT_UINT1: + case GCT_UINT2: + case GCT_UINT3: + case GCT_UINT4: case GCT_UNKNOWN: break; - } + } - return UniformParameterPtr(); - + return UniformParameterPtr(); + } //----------------------------------------------------------------------- UniformParameterPtr ParameterFactory::createSampler1D(int index) { - return UniformParameterPtr(OGRE_NEW UniformParameter(GCT_SAMPLER1D, "gSampler1D_" + StringConverter::toString(index), - Parameter::SPS_UNKNOWN, index, - Parameter::SPC_UNKNOWN, - (uint16)GPV_GLOBAL, 1)); + return UniformParameterPtr(OGRE_NEW UniformParameter(GCT_SAMPLER1D, "gSampler1D_" + StringConverter::toString(index), + Parameter::SPS_UNKNOWN, index, + Parameter::SPC_UNKNOWN, + (uint16)GPV_GLOBAL, 1)); } //----------------------------------------------------------------------- UniformParameterPtr ParameterFactory::createSampler2D(int index) { - return UniformParameterPtr(OGRE_NEW UniformParameter(GCT_SAMPLER2D, "gSampler2D_" + StringConverter::toString(index), - Parameter::SPS_UNKNOWN, index, - Parameter::SPC_UNKNOWN, - (uint16)GPV_GLOBAL, 1)); + return UniformParameterPtr(OGRE_NEW UniformParameter(GCT_SAMPLER2D, "gSampler2D_" + StringConverter::toString(index), + Parameter::SPS_UNKNOWN, index, + Parameter::SPC_UNKNOWN, + (uint16)GPV_GLOBAL, 1)); } //----------------------------------------------------------------------- @@ -851,69 +851,69 @@ UniformParameterPtr ParameterFactory::createSampler2DArray(int index) //----------------------------------------------------------------------- UniformParameterPtr ParameterFactory::createSampler3D(int index) { - return UniformParameterPtr(OGRE_NEW UniformParameter(GCT_SAMPLER3D, "gSampler3D_" + StringConverter::toString(index), - Parameter::SPS_UNKNOWN, index, - Parameter::SPC_UNKNOWN, - (uint16)GPV_GLOBAL, 1)); + return UniformParameterPtr(OGRE_NEW UniformParameter(GCT_SAMPLER3D, "gSampler3D_" + StringConverter::toString(index), + Parameter::SPS_UNKNOWN, index, + Parameter::SPC_UNKNOWN, + (uint16)GPV_GLOBAL, 1)); } //----------------------------------------------------------------------- UniformParameterPtr ParameterFactory::createSamplerCUBE(int index) { - return UniformParameterPtr(OGRE_NEW UniformParameter(GCT_SAMPLERCUBE, "gSamplerCUBE_" + StringConverter::toString(index), - Parameter::SPS_UNKNOWN, index, - Parameter::SPC_UNKNOWN, - (uint16)GPV_GLOBAL, 1)); + return UniformParameterPtr(OGRE_NEW UniformParameter(GCT_SAMPLERCUBE, "gSamplerCUBE_" + StringConverter::toString(index), + Parameter::SPS_UNKNOWN, index, + Parameter::SPC_UNKNOWN, + (uint16)GPV_GLOBAL, 1)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createConstParamVector2(Vector2 val) { - return ParameterPtr((Parameter*)OGRE_NEW ConstParameterVec2(val, - GCT_FLOAT2, - Parameter::SPS_UNKNOWN, - Parameter::SPC_UNKNOWN)); + return ParameterPtr((Parameter*)OGRE_NEW ConstParameterVec2(val, + GCT_FLOAT2, + Parameter::SPS_UNKNOWN, + Parameter::SPC_UNKNOWN)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createConstParamVector3(Vector3 val) { - return ParameterPtr((Parameter*)OGRE_NEW ConstParameterVec3(val, - GCT_FLOAT3, - Parameter::SPS_UNKNOWN, - Parameter::SPC_UNKNOWN)); + return ParameterPtr((Parameter*)OGRE_NEW ConstParameterVec3(val, + GCT_FLOAT3, + Parameter::SPS_UNKNOWN, + Parameter::SPC_UNKNOWN)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createConstParamVector4(Vector4 val) { - return ParameterPtr((Parameter*)OGRE_NEW ConstParameterVec4(val, - GCT_FLOAT4, - Parameter::SPS_UNKNOWN, - Parameter::SPC_UNKNOWN)); + return ParameterPtr((Parameter*)OGRE_NEW ConstParameterVec4(val, + GCT_FLOAT4, + Parameter::SPS_UNKNOWN, + Parameter::SPC_UNKNOWN)); } //----------------------------------------------------------------------- ParameterPtr ParameterFactory::createConstParamFloat(float val) { - return ParameterPtr((Parameter*)OGRE_NEW ConstParameterFloat(val, - GCT_FLOAT1, - Parameter::SPS_UNKNOWN, - Parameter::SPC_UNKNOWN)); + return ParameterPtr((Parameter*)OGRE_NEW ConstParameterFloat(val, + GCT_FLOAT1, + Parameter::SPS_UNKNOWN, + Parameter::SPC_UNKNOWN)); } //----------------------------------------------------------------------- UniformParameterPtr ParameterFactory::createUniform(GpuConstantType type, - int index, uint16 variability, - const String& suggestedName, - size_t size) -{ - UniformParameterPtr param; - - param = UniformParameterPtr(OGRE_NEW UniformParameter(type, suggestedName + StringConverter::toString(index), - Parameter::SPS_UNKNOWN, index, - Parameter::SPC_UNKNOWN, variability, size)); - - return param; + int index, uint16 variability, + const String& suggestedName, + size_t size) +{ + UniformParameterPtr param; + + param = UniformParameterPtr(OGRE_NEW UniformParameter(type, suggestedName + StringConverter::toString(index), + Parameter::SPS_UNKNOWN, index, + Parameter::SPC_UNKNOWN, variability, size)); + + return param; } } diff --git a/Components/RTShaderSystem/src/OgreShaderProgram.cpp b/Components/RTShaderSystem/src/OgreShaderProgram.cpp index f0389d99541..890ed24003a 100644 --- a/Components/RTShaderSystem/src/OgreShaderProgram.cpp +++ b/Components/RTShaderSystem/src/OgreShaderProgram.cpp @@ -33,212 +33,212 @@ namespace RTShader { //----------------------------------------------------------------------------- Program::Program(GpuProgramType type) { - mType = type; - mEntryPointFunction = NULL; - mSkeletalAnimation = false; - mColumnMajorMatrices = true; + mType = type; + mEntryPointFunction = NULL; + mSkeletalAnimation = false; + mColumnMajorMatrices = true; } //----------------------------------------------------------------------------- Program::~Program() { - destroyParameters(); + destroyParameters(); - destroyFunctions(); + destroyFunctions(); } //----------------------------------------------------------------------------- void Program::destroyParameters() { - mParameters.clear(); + mParameters.clear(); } //----------------------------------------------------------------------------- void Program::destroyFunctions() { - ShaderFunctionIterator it; + ShaderFunctionIterator it; - for (it = mFunctions.begin(); it != mFunctions.end(); ++it) - { + for (it = mFunctions.begin(); it != mFunctions.end(); ++it) + { OGRE_DELETE *it; - } - mFunctions.clear(); + } + mFunctions.clear(); } //----------------------------------------------------------------------------- GpuProgramType Program::getType() const { - return mType; + return mType; } //----------------------------------------------------------------------------- void Program::addParameter(UniformParameterPtr parameter) { - if (getParameterByName(parameter->getName()).get() != NULL) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Parameter <" + parameter->getName() + "> already declared in program.", - "Program::addParameter" ); - } - - mParameters.push_back(parameter); + if (getParameterByName(parameter->getName()).get() != NULL) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Parameter <" + parameter->getName() + "> already declared in program.", + "Program::addParameter" ); + } + + mParameters.push_back(parameter); } //----------------------------------------------------------------------------- void Program::removeParameter(UniformParameterPtr parameter) { - UniformParameterIterator it; - - for (it = mParameters.begin(); it != mParameters.end(); ++it) - { - if ((*it) == parameter) - { - (*it).setNull(); - mParameters.erase(it); + UniformParameterIterator it; + + for (it = mParameters.begin(); it != mParameters.end(); ++it) + { + if ((*it) == parameter) + { + (*it).setNull(); + mParameters.erase(it); break; - } - } + } + } } //----------------------------------------------------------------------------- UniformParameterPtr Program::resolveAutoParameterReal(GpuProgramParameters::AutoConstantType autoType, - Real data, size_t size) + Real data, size_t size) { - UniformParameterPtr param; - - // Check if parameter already exists. - param = getParameterByAutoType(autoType); - if (param.get() != NULL) - { - if (param->isAutoConstantRealParameter() && - param->getAutoConstantRealData() == data) - { - param->setSize(std::max(size, param->getSize())); - return param; - } - } - - // Create new parameter. - param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size)); - addParameter(param); - - return param; + UniformParameterPtr param; + + // Check if parameter already exists. + param = getParameterByAutoType(autoType); + if (param.get() != NULL) + { + if (param->isAutoConstantRealParameter() && + param->getAutoConstantRealData() == data) + { + param->setSize(std::max(size, param->getSize())); + return param; + } + } + + // Create new parameter. + param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size)); + addParameter(param); + + return param; } //----------------------------------------------------------------------------- UniformParameterPtr Program::resolveAutoParameterReal(GpuProgramParameters::AutoConstantType autoType, GpuConstantType type, - Real data, size_t size) + Real data, size_t size) { - UniformParameterPtr param; - - // Check if parameter already exists. - param = getParameterByAutoType(autoType); - if (param.get() != NULL) - { - if (param->isAutoConstantRealParameter() && - param->getAutoConstantRealData() == data) - { - param->setSize(std::max(size, param->getSize())); - return param; - } - } - - // Create new parameter. - param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size, type)); - addParameter(param); - - return param; + UniformParameterPtr param; + + // Check if parameter already exists. + param = getParameterByAutoType(autoType); + if (param.get() != NULL) + { + if (param->isAutoConstantRealParameter() && + param->getAutoConstantRealData() == data) + { + param->setSize(std::max(size, param->getSize())); + return param; + } + } + + // Create new parameter. + param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size, type)); + addParameter(param); + + return param; } //----------------------------------------------------------------------------- UniformParameterPtr Program::resolveAutoParameterInt(GpuProgramParameters::AutoConstantType autoType, - size_t data, size_t size) + size_t data, size_t size) { - UniformParameterPtr param; - - // Check if parameter already exists. - param = getParameterByAutoType(autoType); - if (param.get() != NULL) - { - if (param->isAutoConstantIntParameter() && - param->getAutoConstantIntData() == data) - { - param->setSize(std::max(size, param->getSize())); - return param; - } - } - - // Create new parameter. - param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size)); - addParameter(param); - - return param; + UniformParameterPtr param; + + // Check if parameter already exists. + param = getParameterByAutoType(autoType); + if (param.get() != NULL) + { + if (param->isAutoConstantIntParameter() && + param->getAutoConstantIntData() == data) + { + param->setSize(std::max(size, param->getSize())); + return param; + } + } + + // Create new parameter. + param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size)); + addParameter(param); + + return param; } //----------------------------------------------------------------------------- UniformParameterPtr Program::resolveAutoParameterInt(GpuProgramParameters::AutoConstantType autoType, GpuConstantType type, - size_t data, size_t size) + size_t data, size_t size) { - UniformParameterPtr param; - - // Check if parameter already exists. - param = getParameterByAutoType(autoType); - if (param.get() != NULL) - { - if (param->isAutoConstantIntParameter() && - param->getAutoConstantIntData() == data) - { - param->setSize(std::max(size, param->getSize())); - return param; - } - } - - // Create new parameter. - param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size, type)); - addParameter(param); - - return param; + UniformParameterPtr param; + + // Check if parameter already exists. + param = getParameterByAutoType(autoType); + if (param.get() != NULL) + { + if (param->isAutoConstantIntParameter() && + param->getAutoConstantIntData() == data) + { + param->setSize(std::max(size, param->getSize())); + return param; + } + } + + // Create new parameter. + param = UniformParameterPtr(OGRE_NEW UniformParameter(autoType, data, size, type)); + addParameter(param); + + return param; } //----------------------------------------------------------------------------- UniformParameterPtr Program::resolveParameter(GpuConstantType type, - int index, uint16 variability, - const String& suggestedName, - size_t size) + int index, uint16 variability, + const String& suggestedName, + size_t size) { - UniformParameterPtr param; - - if (index == -1) - { - index = 0; - - // Find the next available index of the target type. - UniformParameterIterator it; - - for (it = mParameters.begin(); it != mParameters.end(); ++it) - { - if ((*it)->getType() == type && - (*it)->isAutoConstantParameter() == false) - { - index++; - } - } - } - else - { - // Check if parameter already exists. - param = getParameterByType(type, index); - if (param.get() != NULL) - { - return param; - } - } - - // Create new parameter. - param = ParameterFactory::createUniform(type, index, variability, suggestedName, size); - addParameter(param); - - return param; + UniformParameterPtr param; + + if (index == -1) + { + index = 0; + + // Find the next available index of the target type. + UniformParameterIterator it; + + for (it = mParameters.begin(); it != mParameters.end(); ++it) + { + if ((*it)->getType() == type && + (*it)->isAutoConstantParameter() == false) + { + index++; + } + } + } + else + { + // Check if parameter already exists. + param = getParameterByType(type, index); + if (param.get() != NULL) + { + return param; + } + } + + // Create new parameter. + param = ParameterFactory::createUniform(type, index, variability, suggestedName, size); + addParameter(param); + + return param; } @@ -246,110 +246,110 @@ UniformParameterPtr Program::resolveParameter(GpuConstantType type, //----------------------------------------------------------------------------- UniformParameterPtr Program::getParameterByName(const String& name) { - UniformParameterIterator it; + UniformParameterIterator it; - for (it = mParameters.begin(); it != mParameters.end(); ++it) - { - if ((*it)->getName() == name) - { - return *it; - } - } + for (it = mParameters.begin(); it != mParameters.end(); ++it) + { + if ((*it)->getName() == name) + { + return *it; + } + } - return UniformParameterPtr(); + return UniformParameterPtr(); } //----------------------------------------------------------------------------- UniformParameterPtr Program::getParameterByType(GpuConstantType type, int index) { - UniformParameterIterator it; - - for (it = mParameters.begin(); it != mParameters.end(); ++it) - { - if ((*it)->getType() == type && - (*it)->getIndex() == index) - { - return *it; - } - } - - return UniformParameterPtr(); + UniformParameterIterator it; + + for (it = mParameters.begin(); it != mParameters.end(); ++it) + { + if ((*it)->getType() == type && + (*it)->getIndex() == index) + { + return *it; + } + } + + return UniformParameterPtr(); } //----------------------------------------------------------------------------- UniformParameterPtr Program::getParameterByAutoType(GpuProgramParameters::AutoConstantType autoType) { - UniformParameterIterator it; + UniformParameterIterator it; - for (it = mParameters.begin(); it != mParameters.end(); ++it) - { - if ((*it)->isAutoConstantParameter() && (*it)->getAutoConstantType() == autoType) - { - return *it; - } - } + for (it = mParameters.begin(); it != mParameters.end(); ++it) + { + if ((*it)->isAutoConstantParameter() && (*it)->getAutoConstantType() == autoType) + { + return *it; + } + } - return UniformParameterPtr(); + return UniformParameterPtr(); } //----------------------------------------------------------------------------- Function* Program::createFunction(const String& name, const String& desc, const Function::FunctionType functionType) { - Function* shaderFunction; + Function* shaderFunction; - shaderFunction = getFunctionByName(name); - if (shaderFunction != NULL) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Function " + name + " already declared in program.", - "Program::createFunction" ); - } + shaderFunction = getFunctionByName(name); + if (shaderFunction != NULL) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Function " + name + " already declared in program.", + "Program::createFunction" ); + } - shaderFunction = OGRE_NEW Function(name, desc, functionType); - mFunctions.push_back(shaderFunction); + shaderFunction = OGRE_NEW Function(name, desc, functionType); + mFunctions.push_back(shaderFunction); - return shaderFunction; + return shaderFunction; } //----------------------------------------------------------------------------- Function* Program::getFunctionByName(const String& name) { - ShaderFunctionIterator it; + ShaderFunctionIterator it; - for (it = mFunctions.begin(); it != mFunctions.end(); ++it) - { - if ((*it)->getName() == name) - { - return *it; - } - } + for (it = mFunctions.begin(); it != mFunctions.end(); ++it) + { + if ((*it)->getName() == name) + { + return *it; + } + } - return NULL; + return NULL; } //----------------------------------------------------------------------------- void Program::addDependency(const String& libFileName) { - for (unsigned int i=0; i < mDependencies.size(); ++i) - { - if (mDependencies[i] == libFileName) - { - return; - } - } - mDependencies.push_back(libFileName); + for (unsigned int i=0; i < mDependencies.size(); ++i) + { + if (mDependencies[i] == libFileName) + { + return; + } + } + mDependencies.push_back(libFileName); } //----------------------------------------------------------------------------- size_t Program::getDependencyCount() const { - return mDependencies.size(); + return mDependencies.size(); } //----------------------------------------------------------------------------- const String& Program::getDependency(unsigned int index) const { - return mDependencies[index]; + return mDependencies[index]; } } diff --git a/Components/RTShaderSystem/src/OgreShaderProgramManager.cpp b/Components/RTShaderSystem/src/OgreShaderProgramManager.cpp index 5505d49c441..59e8ef6a273 100644 --- a/Components/RTShaderSystem/src/OgreShaderProgramManager.cpp +++ b/Components/RTShaderSystem/src/OgreShaderProgramManager.cpp @@ -62,341 +62,341 @@ namespace RTShader { //----------------------------------------------------------------------- ProgramManager* ProgramManager::getSingletonPtr() { - return msSingleton; + return msSingleton; } //----------------------------------------------------------------------- ProgramManager& ProgramManager::getSingleton() { - assert( msSingleton ); - return ( *msSingleton ); + assert( msSingleton ); + return ( *msSingleton ); } //----------------------------------------------------------------------------- ProgramManager::ProgramManager() { - createDefaultProgramProcessors(); - createDefaultProgramWriterFactories(); + createDefaultProgramProcessors(); + createDefaultProgramWriterFactories(); } //----------------------------------------------------------------------------- ProgramManager::~ProgramManager() { - flushGpuProgramsCache(); - destroyDefaultProgramWriterFactories(); - destroyDefaultProgramProcessors(); - destroyProgramWriters(); + flushGpuProgramsCache(); + destroyDefaultProgramWriterFactories(); + destroyDefaultProgramProcessors(); + destroyProgramWriters(); } //----------------------------------------------------------------------------- void ProgramManager::acquirePrograms(Pass* pass, TargetRenderState* renderState) { - // Create the CPU programs. - if (false == renderState->createCpuPrograms()) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Could not apply render state ", - "ProgramManager::acquireGpuPrograms" ); - } - - ProgramSet* programSet = renderState->getProgramSet(); - - // Create the GPU programs. - if (false == createGpuPrograms(programSet)) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Could not create gpu programs from render state ", - "ProgramManager::acquireGpuPrograms" ); - } - - // Bind the created GPU programs to the target pass. - pass->setVertexProgram(programSet->getGpuVertexProgram()->getName()); - pass->setFragmentProgram(programSet->getGpuFragmentProgram()->getName()); - - // Bind uniform parameters to pass parameters. - bindUniformParameters(programSet->getCpuVertexProgram(), pass->getVertexProgramParameters()); - bindUniformParameters(programSet->getCpuFragmentProgram(), pass->getFragmentProgramParameters()); + // Create the CPU programs. + if (false == renderState->createCpuPrograms()) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Could not apply render state ", + "ProgramManager::acquireGpuPrograms" ); + } + + ProgramSet* programSet = renderState->getProgramSet(); + + // Create the GPU programs. + if (false == createGpuPrograms(programSet)) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Could not create gpu programs from render state ", + "ProgramManager::acquireGpuPrograms" ); + } + + // Bind the created GPU programs to the target pass. + pass->setVertexProgram(programSet->getGpuVertexProgram()->getName()); + pass->setFragmentProgram(programSet->getGpuFragmentProgram()->getName()); + + // Bind uniform parameters to pass parameters. + bindUniformParameters(programSet->getCpuVertexProgram(), pass->getVertexProgramParameters()); + bindUniformParameters(programSet->getCpuFragmentProgram(), pass->getFragmentProgramParameters()); } //----------------------------------------------------------------------------- void ProgramManager::releasePrograms(Pass* pass, TargetRenderState* renderState) { - ProgramSet* programSet = renderState->getProgramSet(); - - if (programSet != NULL) - { - pass->setVertexProgram(BLANKSTRING); - pass->setFragmentProgram(BLANKSTRING); - - GpuProgramPtr vsProgram(programSet->getGpuVertexProgram()); - GpuProgramPtr psProgram(programSet->getGpuFragmentProgram()); - - GpuProgramsMapIterator itVsGpuProgram = vsProgram.isNull() ? mVertexShaderMap.end() : mVertexShaderMap.find(vsProgram->getName()); - GpuProgramsMapIterator itFsGpuProgram = psProgram.isNull() ? mFragmentShaderMap.end() : mFragmentShaderMap.find(psProgram->getName()); - - renderState->destroyProgramSet(); - - if (itVsGpuProgram != mVertexShaderMap.end()) - { - if (itVsGpuProgram->second.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) - { - destroyGpuProgram(itVsGpuProgram->second); - mVertexShaderMap.erase(itVsGpuProgram); - } - } - - if (itFsGpuProgram != mFragmentShaderMap.end()) - { - if (itFsGpuProgram->second.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) - { - destroyGpuProgram(itFsGpuProgram->second); - mFragmentShaderMap.erase(itFsGpuProgram); - } - } - } + ProgramSet* programSet = renderState->getProgramSet(); + + if (programSet != NULL) + { + pass->setVertexProgram(BLANKSTRING); + pass->setFragmentProgram(BLANKSTRING); + + GpuProgramPtr vsProgram(programSet->getGpuVertexProgram()); + GpuProgramPtr psProgram(programSet->getGpuFragmentProgram()); + + GpuProgramsMapIterator itVsGpuProgram = vsProgram.isNull() ? mVertexShaderMap.end() : mVertexShaderMap.find(vsProgram->getName()); + GpuProgramsMapIterator itFsGpuProgram = psProgram.isNull() ? mFragmentShaderMap.end() : mFragmentShaderMap.find(psProgram->getName()); + + renderState->destroyProgramSet(); + + if (itVsGpuProgram != mVertexShaderMap.end()) + { + if (itVsGpuProgram->second.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) + { + destroyGpuProgram(itVsGpuProgram->second); + mVertexShaderMap.erase(itVsGpuProgram); + } + } + + if (itFsGpuProgram != mFragmentShaderMap.end()) + { + if (itFsGpuProgram->second.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) + { + destroyGpuProgram(itFsGpuProgram->second); + mFragmentShaderMap.erase(itFsGpuProgram); + } + } + } } //----------------------------------------------------------------------------- void ProgramManager::flushGpuProgramsCache() { - flushGpuProgramsCache(mVertexShaderMap); - flushGpuProgramsCache(mFragmentShaderMap); + flushGpuProgramsCache(mVertexShaderMap); + flushGpuProgramsCache(mFragmentShaderMap); } //----------------------------------------------------------------------------- void ProgramManager::flushGpuProgramsCache(GpuProgramsMap& gpuProgramsMap) { - while (gpuProgramsMap.size() > 0) - { - GpuProgramsMapIterator it = gpuProgramsMap.begin(); + while (gpuProgramsMap.size() > 0) + { + GpuProgramsMapIterator it = gpuProgramsMap.begin(); - destroyGpuProgram(it->second); - gpuProgramsMap.erase(it); - } + destroyGpuProgram(it->second); + gpuProgramsMap.erase(it); + } } //----------------------------------------------------------------------------- void ProgramManager::createDefaultProgramWriterFactories() { - // Add standard shader writer factories + // Add standard shader writer factories #if OGRE_PLATFORM != OGRE_PLATFORM_ANDROID - mProgramWriterFactories.push_back(OGRE_NEW ShaderProgramWriterCGFactory()); - mProgramWriterFactories.push_back(OGRE_NEW ShaderProgramWriterGLSLFactory()); - mProgramWriterFactories.push_back(OGRE_NEW ShaderProgramWriterHLSLFactory()); + mProgramWriterFactories.push_back(OGRE_NEW ShaderProgramWriterCGFactory()); + mProgramWriterFactories.push_back(OGRE_NEW ShaderProgramWriterGLSLFactory()); + mProgramWriterFactories.push_back(OGRE_NEW ShaderProgramWriterHLSLFactory()); #endif - mProgramWriterFactories.push_back(OGRE_NEW ShaderProgramWriterGLSLESFactory()); - - for (unsigned int i=0; i < mProgramWriterFactories.size(); ++i) - { - ProgramWriterManager::getSingletonPtr()->addFactory(mProgramWriterFactories[i]); - } + mProgramWriterFactories.push_back(OGRE_NEW ShaderProgramWriterGLSLESFactory()); + + for (unsigned int i=0; i < mProgramWriterFactories.size(); ++i) + { + ProgramWriterManager::getSingletonPtr()->addFactory(mProgramWriterFactories[i]); + } } //----------------------------------------------------------------------------- void ProgramManager::destroyDefaultProgramWriterFactories() { - for (unsigned int i=0; iremoveFactory(mProgramWriterFactories[i]); - OGRE_DELETE mProgramWriterFactories[i]; - } - mProgramWriterFactories.clear(); + for (unsigned int i=0; iremoveFactory(mProgramWriterFactories[i]); + OGRE_DELETE mProgramWriterFactories[i]; + } + mProgramWriterFactories.clear(); } //----------------------------------------------------------------------------- void ProgramManager::createDefaultProgramProcessors() { - // Add standard shader processors + // Add standard shader processors #if OGRE_PLATFORM != OGRE_PLATFORM_ANDROID - mDefaultProgramProcessors.push_back(OGRE_NEW CGProgramProcessor); - mDefaultProgramProcessors.push_back(OGRE_NEW GLSLProgramProcessor); - mDefaultProgramProcessors.push_back(OGRE_NEW HLSLProgramProcessor); + mDefaultProgramProcessors.push_back(OGRE_NEW CGProgramProcessor); + mDefaultProgramProcessors.push_back(OGRE_NEW GLSLProgramProcessor); + mDefaultProgramProcessors.push_back(OGRE_NEW HLSLProgramProcessor); #endif - mDefaultProgramProcessors.push_back(OGRE_NEW GLSLESProgramProcessor); + mDefaultProgramProcessors.push_back(OGRE_NEW GLSLESProgramProcessor); - for (unsigned int i=0; i < mDefaultProgramProcessors.size(); ++i) - { - addProgramProcessor(mDefaultProgramProcessors[i]); - } + for (unsigned int i=0; i < mDefaultProgramProcessors.size(); ++i) + { + addProgramProcessor(mDefaultProgramProcessors[i]); + } } //----------------------------------------------------------------------------- void ProgramManager::destroyDefaultProgramProcessors() { - for (unsigned int i=0; i < mDefaultProgramProcessors.size(); ++i) - { - removeProgramProcessor(mDefaultProgramProcessors[i]); - OGRE_DELETE mDefaultProgramProcessors[i]; - } - mDefaultProgramProcessors.clear(); + for (unsigned int i=0; i < mDefaultProgramProcessors.size(); ++i) + { + removeProgramProcessor(mDefaultProgramProcessors[i]); + OGRE_DELETE mDefaultProgramProcessors[i]; + } + mDefaultProgramProcessors.clear(); } //----------------------------------------------------------------------------- void ProgramManager::destroyProgramWriters() { - ProgramWriterIterator it = mProgramWritersMap.begin(); - ProgramWriterIterator itEnd = mProgramWritersMap.end(); - - for (; it != itEnd; ++it) - { - if (it->second != NULL) - { - OGRE_DELETE it->second; - it->second = NULL; - } - } - mProgramWritersMap.clear(); + ProgramWriterIterator it = mProgramWritersMap.begin(); + ProgramWriterIterator itEnd = mProgramWritersMap.end(); + + for (; it != itEnd; ++it) + { + if (it->second != NULL) + { + OGRE_DELETE it->second; + it->second = NULL; + } + } + mProgramWritersMap.clear(); } //----------------------------------------------------------------------------- Program* ProgramManager::createCpuProgram(GpuProgramType type) { - Program* shaderProgram = OGRE_NEW Program(type); + Program* shaderProgram = OGRE_NEW Program(type); - mCpuProgramsList.insert(shaderProgram); + mCpuProgramsList.insert(shaderProgram); - return shaderProgram; + return shaderProgram; } //----------------------------------------------------------------------------- void ProgramManager::destroyCpuProgram(Program* shaderProgram) { - ProgramListIterator it = mCpuProgramsList.find(shaderProgram); - - if (it != mCpuProgramsList.end()) - { - OGRE_DELETE *it; - mCpuProgramsList.erase(it); - } + ProgramListIterator it = mCpuProgramsList.find(shaderProgram); + + if (it != mCpuProgramsList.end()) + { + OGRE_DELETE *it; + mCpuProgramsList.erase(it); + } } //----------------------------------------------------------------------------- bool ProgramManager::createGpuPrograms(ProgramSet* programSet) { - // Before we start we need to make sure that the pixel shader input - // parameters are the same as the vertex output, this required by - // shader models 4 and 5. - // This change may incrase the number of register used in older shader - // models - this is why the check is present here. - bool isVs4 = GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0_level_9_1"); - if (isVs4) - { - synchronizePixelnToBeVertexOut(programSet); - } - - // Grab the matching writer. - const String& language = ShaderGenerator::getSingleton().getTargetLanguage(); - ProgramWriterIterator itWriter = mProgramWritersMap.find(language); - ProgramWriter* programWriter = NULL; - - // No writer found -> create new one. - if (itWriter == mProgramWritersMap.end()) - { - programWriter = ProgramWriterManager::getSingletonPtr()->createProgramWriter(language); - mProgramWritersMap[language] = programWriter; - } - else - { - programWriter = itWriter->second; - } - - ProgramProcessorIterator itProcessor = mProgramProcessorsMap.find(language); - ProgramProcessor* programProcessor = NULL; - - if (itProcessor == mProgramProcessorsMap.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "Could not find processor for language '" + language, - "ProgramManager::createGpuPrograms"); - } - - programProcessor = itProcessor->second; - - bool success; - - // Call the pre creation of GPU programs method. - success = programProcessor->preCreateGpuPrograms(programSet); - if (success == false) - return false; - - // Create the vertex shader program. - GpuProgramPtr vsGpuProgram; - - vsGpuProgram = createGpuProgram(programSet->getCpuVertexProgram(), - programWriter, - language, - ShaderGenerator::getSingleton().getVertexShaderProfiles(), - ShaderGenerator::getSingleton().getVertexShaderProfilesList(), - ShaderGenerator::getSingleton().getShaderCachePath()); - - if (vsGpuProgram.isNull()) - return false; - - programSet->setGpuVertexProgram(vsGpuProgram); - - //update flags - programSet->getGpuVertexProgram()->setSkeletalAnimationIncluded( - programSet->getCpuVertexProgram()->getSkeletalAnimationIncluded()); - // Create the fragment shader program. - GpuProgramPtr psGpuProgram; - - psGpuProgram = createGpuProgram(programSet->getCpuFragmentProgram(), - programWriter, - language, - ShaderGenerator::getSingleton().getFragmentShaderProfiles(), - ShaderGenerator::getSingleton().getFragmentShaderProfilesList(), - ShaderGenerator::getSingleton().getShaderCachePath()); - - if (psGpuProgram.isNull()) - return false; - - programSet->setGpuFragmentProgram(psGpuProgram); - - // Call the post creation of GPU programs method. - success = programProcessor->postCreateGpuPrograms(programSet); - if (success == false) - return false; - - - return true; - + // Before we start we need to make sure that the pixel shader input + // parameters are the same as the vertex output, this required by + // shader models 4 and 5. + // This change may incrase the number of register used in older shader + // models - this is why the check is present here. + bool isVs4 = GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0_level_9_1"); + if (isVs4) + { + synchronizePixelnToBeVertexOut(programSet); + } + + // Grab the matching writer. + const String& language = ShaderGenerator::getSingleton().getTargetLanguage(); + ProgramWriterIterator itWriter = mProgramWritersMap.find(language); + ProgramWriter* programWriter = NULL; + + // No writer found -> create new one. + if (itWriter == mProgramWritersMap.end()) + { + programWriter = ProgramWriterManager::getSingletonPtr()->createProgramWriter(language); + mProgramWritersMap[language] = programWriter; + } + else + { + programWriter = itWriter->second; + } + + ProgramProcessorIterator itProcessor = mProgramProcessorsMap.find(language); + ProgramProcessor* programProcessor = NULL; + + if (itProcessor == mProgramProcessorsMap.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "Could not find processor for language '" + language, + "ProgramManager::createGpuPrograms"); + } + + programProcessor = itProcessor->second; + + bool success; + + // Call the pre creation of GPU programs method. + success = programProcessor->preCreateGpuPrograms(programSet); + if (success == false) + return false; + + // Create the vertex shader program. + GpuProgramPtr vsGpuProgram; + + vsGpuProgram = createGpuProgram(programSet->getCpuVertexProgram(), + programWriter, + language, + ShaderGenerator::getSingleton().getVertexShaderProfiles(), + ShaderGenerator::getSingleton().getVertexShaderProfilesList(), + ShaderGenerator::getSingleton().getShaderCachePath()); + + if (vsGpuProgram.isNull()) + return false; + + programSet->setGpuVertexProgram(vsGpuProgram); + + //update flags + programSet->getGpuVertexProgram()->setSkeletalAnimationIncluded( + programSet->getCpuVertexProgram()->getSkeletalAnimationIncluded()); + // Create the fragment shader program. + GpuProgramPtr psGpuProgram; + + psGpuProgram = createGpuProgram(programSet->getCpuFragmentProgram(), + programWriter, + language, + ShaderGenerator::getSingleton().getFragmentShaderProfiles(), + ShaderGenerator::getSingleton().getFragmentShaderProfilesList(), + ShaderGenerator::getSingleton().getShaderCachePath()); + + if (psGpuProgram.isNull()) + return false; + + programSet->setGpuFragmentProgram(psGpuProgram); + + // Call the post creation of GPU programs method. + success = programProcessor->postCreateGpuPrograms(programSet); + if (success == false) + return false; + + + return true; + } //----------------------------------------------------------------------------- void ProgramManager::bindUniformParameters(Program* pCpuProgram, const GpuProgramParametersSharedPtr& passParams) { - const UniformParameterList& progParams = pCpuProgram->getParameters(); - UniformParameterConstIterator itParams = progParams.begin(); - UniformParameterConstIterator itParamsEnd = progParams.end(); - - // Bind each uniform parameter to its GPU parameter. - for (; itParams != itParamsEnd; ++itParams) - { - (*itParams)->bind(passParams); - } + const UniformParameterList& progParams = pCpuProgram->getParameters(); + UniformParameterConstIterator itParams = progParams.begin(); + UniformParameterConstIterator itParamsEnd = progParams.end(); + + // Bind each uniform parameter to its GPU parameter. + for (; itParams != itParamsEnd; ++itParams) + { + (*itParams)->bind(passParams); + } } //----------------------------------------------------------------------------- GpuProgramPtr ProgramManager::createGpuProgram(Program* shaderProgram, - ProgramWriter* programWriter, - const String& language, - const String& profiles, - const StringVector& profilesList, - const String& cachePath) + ProgramWriter* programWriter, + const String& language, + const String& profiles, + const StringVector& profilesList, + const String& cachePath) { stringstream sourceCodeStringStream; - String programName; + String programName; - // Generate source code. - programWriter->writeSourceCode(sourceCodeStringStream, shaderProgram); + // Generate source code. + programWriter->writeSourceCode(sourceCodeStringStream, shaderProgram); String source = sourceCodeStringStream.str(); #if OGRE_PLATFORM != OGRE_PLATFORM_ANDROID - - // Generate program name. - programName = generateGUID(source); + + // Generate program name. + programName = generateGUID(source); #else // Disable caching on android devices @@ -405,247 +405,247 @@ GpuProgramPtr ProgramManager::createGpuProgram(Program* shaderProgram, programName = "RTSS_" + StringConverter::toString(++gpuProgramID); #endif - - if (shaderProgram->getType() == GPT_VERTEX_PROGRAM) - { - programName += "_VS"; - } - else if (shaderProgram->getType() == GPT_FRAGMENT_PROGRAM) - { - programName += "_FS"; - } - - // Try to get program by name. - HighLevelGpuProgramPtr pGpuProgram = HighLevelGpuProgramManager::getSingleton().getByName(programName); - - // Case the program doesn't exist yet. - if (pGpuProgram.isNull()) - { - // Create new GPU program. - pGpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName, - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, language, shaderProgram->getType()); - - // Case cache directory specified -> create program from file. - if (cachePath.empty() == false) - { - const String programFullName = programName + "." + language; - const String programFileName = cachePath + programFullName; - std::ifstream programFile; - bool writeFile = true; - - - // Check if program file already exist. - programFile.open(programFileName.c_str()); - - // Case no matching file found -> we have to write it. - if (!programFile) - { - writeFile = true; - } - else - { - writeFile = false; - programFile.close(); - } - - // Case we have to write the program to a file. - if (writeFile) - { - std::ofstream outFile(programFileName.c_str()); - - if (!outFile) - return GpuProgramPtr(); - - outFile << source; - outFile.close(); - } - - pGpuProgram->setSourceFile(programFullName); - } - - // No cache directory specified -> create program from system memory. - else - { - pGpuProgram->setSource(source); - } - - - pGpuProgram->setParameter("entry_point", shaderProgram->getEntryPointFunction()->getName()); - - if (language == "hlsl") - { - // HLSL program requires specific target profile settings - we have to split the profile string. - StringVector::const_iterator it = profilesList.begin(); - StringVector::const_iterator itEnd = profilesList.end(); - - for (; it != itEnd; ++it) - { - if (GpuProgramManager::getSingleton().isSyntaxSupported(*it)) - { - pGpuProgram->setParameter("target", *it); - break; - } - } - - pGpuProgram->setParameter("enable_backwards_compatibility", "false"); - pGpuProgram->setParameter("column_major_matrices", StringConverter::toString(shaderProgram->getUseColumnMajorMatrices())); - } - - pGpuProgram->setParameter("profiles", profiles); - pGpuProgram->load(); - - // Case an error occurred. - if (pGpuProgram->hasCompileError()) - { - pGpuProgram.setNull(); - return GpuProgramPtr(pGpuProgram); - } - - // Add the created GPU program to local cache. - if (pGpuProgram->getType() == GPT_VERTEX_PROGRAM) - { - mVertexShaderMap[programName] = pGpuProgram; - } - else if (pGpuProgram->getType() == GPT_FRAGMENT_PROGRAM) - { - mFragmentShaderMap[programName] = pGpuProgram; - } - } - - return GpuProgramPtr(pGpuProgram); + + if (shaderProgram->getType() == GPT_VERTEX_PROGRAM) + { + programName += "_VS"; + } + else if (shaderProgram->getType() == GPT_FRAGMENT_PROGRAM) + { + programName += "_FS"; + } + + // Try to get program by name. + HighLevelGpuProgramPtr pGpuProgram = HighLevelGpuProgramManager::getSingleton().getByName(programName); + + // Case the program doesn't exist yet. + if (pGpuProgram.isNull()) + { + // Create new GPU program. + pGpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName, + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, language, shaderProgram->getType()); + + // Case cache directory specified -> create program from file. + if (cachePath.empty() == false) + { + const String programFullName = programName + "." + language; + const String programFileName = cachePath + programFullName; + std::ifstream programFile; + bool writeFile = true; + + + // Check if program file already exist. + programFile.open(programFileName.c_str()); + + // Case no matching file found -> we have to write it. + if (!programFile) + { + writeFile = true; + } + else + { + writeFile = false; + programFile.close(); + } + + // Case we have to write the program to a file. + if (writeFile) + { + std::ofstream outFile(programFileName.c_str()); + + if (!outFile) + return GpuProgramPtr(); + + outFile << source; + outFile.close(); + } + + pGpuProgram->setSourceFile(programFullName); + } + + // No cache directory specified -> create program from system memory. + else + { + pGpuProgram->setSource(source); + } + + + pGpuProgram->setParameter("entry_point", shaderProgram->getEntryPointFunction()->getName()); + + if (language == "hlsl") + { + // HLSL program requires specific target profile settings - we have to split the profile string. + StringVector::const_iterator it = profilesList.begin(); + StringVector::const_iterator itEnd = profilesList.end(); + + for (; it != itEnd; ++it) + { + if (GpuProgramManager::getSingleton().isSyntaxSupported(*it)) + { + pGpuProgram->setParameter("target", *it); + break; + } + } + + pGpuProgram->setParameter("enable_backwards_compatibility", "false"); + pGpuProgram->setParameter("column_major_matrices", StringConverter::toString(shaderProgram->getUseColumnMajorMatrices())); + } + + pGpuProgram->setParameter("profiles", profiles); + pGpuProgram->load(); + + // Case an error occurred. + if (pGpuProgram->hasCompileError()) + { + pGpuProgram.setNull(); + return GpuProgramPtr(pGpuProgram); + } + + // Add the created GPU program to local cache. + if (pGpuProgram->getType() == GPT_VERTEX_PROGRAM) + { + mVertexShaderMap[programName] = pGpuProgram; + } + else if (pGpuProgram->getType() == GPT_FRAGMENT_PROGRAM) + { + mFragmentShaderMap[programName] = pGpuProgram; + } + } + + return GpuProgramPtr(pGpuProgram); } //----------------------------------------------------------------------------- String ProgramManager::generateGUID(const String& programString) { - //To generate a unique value this component used to use _StringHash class. - //However when this generates a hash value it selects a maximum of 10 places within the string - //and bases the hash value on those position. This is not good enough for this situation. - // - //Different programs must have unique hash values. Some programs only differ in the size of array parameters. - //This means that only 1 or 2 letters will be changed. Using the _StringHash class in these case will, in all - //likelihood, produce the same values. - - unsigned int val1 = 0x9e3779b9; - unsigned int val2 = 0x61C88646; - unsigned int val3 = 0x9e3779b9; - unsigned int val4 = 0x61C88646; - - //instead of generating the hash from the individual characters we will treat this string as a long - //integer value for faster processing. We dismiss the last non-full int. - size_t sizeInInts = (programString.size() - 3) / 4; - const uint32* intBuffer = (const uint32*)programString.c_str(); - - size_t i = 0; - for( ; i < sizeInInts - 2 ; i += 3) - { - uint32 bufVal0 = *(intBuffer + i); - uint32 bufVal1 = *(intBuffer + i + 1); - uint32 bufVal2 = *(intBuffer + i + 2); - val1 ^= (val1<<6) + (val1>>2) + bufVal0; - val2 ^= (val2<<6) + (val2>>2) + bufVal1; - val3 ^= (val3<<6) + (val3>>2) + bufVal2; - //ensure greater uniqueness by having the forth int value dependent on the entire string - val4 ^= (val4<<6) + (val4>>2) + bufVal0 + bufVal1 + bufVal2; - } - //read the end of the string we missed - if (i < sizeInInts - 1) - val1 ^= (val1<<6) + (val1>>2) + *(intBuffer + i - 1); - if (i < sizeInInts) - val2 ^= (val2<<6) + (val2>>2) + *(intBuffer + i); - - //Generate the guid string - stringstream stream; - stream.fill('0'); - stream.setf(std::ios::fixed); - stream.setf(std::ios::hex, std::ios::basefield); - stream.width(8); stream << val1 << "-"; - stream.width(4); stream << (uint16)(val2 >> 16) << "-"; - stream.width(4); stream << (uint16)(val2) << "-"; - stream.width(4); stream << (uint16)(val3 >> 16) << "-"; - stream.width(4); stream << (uint16)(val3); - stream.width(8); stream << val4; - return stream.str(); + //To generate a unique value this component used to use _StringHash class. + //However when this generates a hash value it selects a maximum of 10 places within the string + //and bases the hash value on those position. This is not good enough for this situation. + // + //Different programs must have unique hash values. Some programs only differ in the size of array parameters. + //This means that only 1 or 2 letters will be changed. Using the _StringHash class in these case will, in all + //likelihood, produce the same values. + + unsigned int val1 = 0x9e3779b9; + unsigned int val2 = 0x61C88646; + unsigned int val3 = 0x9e3779b9; + unsigned int val4 = 0x61C88646; + + //instead of generating the hash from the individual characters we will treat this string as a long + //integer value for faster processing. We dismiss the last non-full int. + size_t sizeInInts = (programString.size() - 3) / 4; + const uint32* intBuffer = (const uint32*)programString.c_str(); + + size_t i = 0; + for( ; i < sizeInInts - 2 ; i += 3) + { + uint32 bufVal0 = *(intBuffer + i); + uint32 bufVal1 = *(intBuffer + i + 1); + uint32 bufVal2 = *(intBuffer + i + 2); + val1 ^= (val1<<6) + (val1>>2) + bufVal0; + val2 ^= (val2<<6) + (val2>>2) + bufVal1; + val3 ^= (val3<<6) + (val3>>2) + bufVal2; + //ensure greater uniqueness by having the forth int value dependent on the entire string + val4 ^= (val4<<6) + (val4>>2) + bufVal0 + bufVal1 + bufVal2; + } + //read the end of the string we missed + if (i < sizeInInts - 1) + val1 ^= (val1<<6) + (val1>>2) + *(intBuffer + i - 1); + if (i < sizeInInts) + val2 ^= (val2<<6) + (val2>>2) + *(intBuffer + i); + + //Generate the guid string + stringstream stream; + stream.fill('0'); + stream.setf(std::ios::fixed); + stream.setf(std::ios::hex, std::ios::basefield); + stream.width(8); stream << val1 << "-"; + stream.width(4); stream << (uint16)(val2 >> 16) << "-"; + stream.width(4); stream << (uint16)(val2) << "-"; + stream.width(4); stream << (uint16)(val3 >> 16) << "-"; + stream.width(4); stream << (uint16)(val3); + stream.width(8); stream << val4; + return stream.str(); } //----------------------------------------------------------------------------- void ProgramManager::addProgramProcessor(ProgramProcessor* processor) { - - ProgramProcessorIterator itFind = mProgramProcessorsMap.find(processor->getTargetLanguage()); + + ProgramProcessorIterator itFind = mProgramProcessorsMap.find(processor->getTargetLanguage()); - if (itFind != mProgramProcessorsMap.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "A processor for language '" + processor->getTargetLanguage() + "' already exists.", - "ProgramManager::addProgramProcessor"); - } + if (itFind != mProgramProcessorsMap.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "A processor for language '" + processor->getTargetLanguage() + "' already exists.", + "ProgramManager::addProgramProcessor"); + } - mProgramProcessorsMap[processor->getTargetLanguage()] = processor; + mProgramProcessorsMap[processor->getTargetLanguage()] = processor; } //----------------------------------------------------------------------------- void ProgramManager::removeProgramProcessor(ProgramProcessor* processor) { - ProgramProcessorIterator itFind = mProgramProcessorsMap.find(processor->getTargetLanguage()); + ProgramProcessorIterator itFind = mProgramProcessorsMap.find(processor->getTargetLanguage()); - if (itFind != mProgramProcessorsMap.end()) - mProgramProcessorsMap.erase(itFind); + if (itFind != mProgramProcessorsMap.end()) + mProgramProcessorsMap.erase(itFind); } //----------------------------------------------------------------------------- void ProgramManager::destroyGpuProgram(GpuProgramPtr& gpuProgram) -{ - const String& programName = gpuProgram->getName(); - ResourcePtr res = HighLevelGpuProgramManager::getSingleton().getByName(programName); - - if (res.isNull() == false) - { - HighLevelGpuProgramManager::getSingleton().remove(programName); - } +{ + const String& programName = gpuProgram->getName(); + ResourcePtr res = HighLevelGpuProgramManager::getSingleton().getByName(programName); + + if (res.isNull() == false) + { + HighLevelGpuProgramManager::getSingleton().remove(programName); + } } //----------------------------------------------------------------------- void ProgramManager::synchronizePixelnToBeVertexOut( ProgramSet* programSet ) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - - // first find the vertex shader - ShaderFunctionConstIterator itFunction ; - Function* vertexMain = NULL; - Function* pixelMain = NULL; - - // find vertex shader main - { - const ShaderFunctionList& functionList = vsProgram->getFunctions(); - for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) - { - Function* curFunction = *itFunction; - if (curFunction->getFunctionType() == Function::FFT_VS_MAIN) - { - vertexMain = curFunction; - break; - } - } - } - - // find pixel shader main - { - const ShaderFunctionList& functionList = psProgram->getFunctions(); - for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) - { - Function* curFunction = *itFunction; - if (curFunction->getFunctionType() == Function::FFT_PS_MAIN) - { - pixelMain = curFunction; - break; - } - } - } + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + + // first find the vertex shader + ShaderFunctionConstIterator itFunction ; + Function* vertexMain = NULL; + Function* pixelMain = NULL; + + // find vertex shader main + { + const ShaderFunctionList& functionList = vsProgram->getFunctions(); + for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) + { + Function* curFunction = *itFunction; + if (curFunction->getFunctionType() == Function::FFT_VS_MAIN) + { + vertexMain = curFunction; + break; + } + } + } + + // find pixel shader main + { + const ShaderFunctionList& functionList = psProgram->getFunctions(); + for (itFunction=functionList.begin(); itFunction != functionList.end(); ++itFunction) + { + Function* curFunction = *itFunction; + if (curFunction->getFunctionType() == Function::FFT_PS_MAIN) + { + pixelMain = curFunction; + break; + } + } + } if(pixelMain) { diff --git a/Components/RTShaderSystem/src/OgreShaderProgramProcessor.cpp b/Components/RTShaderSystem/src/OgreShaderProgramProcessor.cpp index 948277e1f60..82c4add0682 100644 --- a/Components/RTShaderSystem/src/OgreShaderProgramProcessor.cpp +++ b/Components/RTShaderSystem/src/OgreShaderProgramProcessor.cpp @@ -38,207 +38,207 @@ namespace RTShader { //----------------------------------------------------------------------------- ProgramProcessor::ProgramProcessor() { - mMaxTexCoordSlots = 16; - mMaxTexCoordFloats = mMaxTexCoordSlots * 4; - + mMaxTexCoordSlots = 16; + mMaxTexCoordFloats = mMaxTexCoordSlots * 4; + } //----------------------------------------------------------------------------- ProgramProcessor::~ProgramProcessor() { - + } //----------------------------------------------------------------------------- void ProgramProcessor::bindAutoParameters(Program* pCpuProgram, GpuProgramPtr pGpuProgram) { - GpuProgramParametersSharedPtr pGpuParams = pGpuProgram->getDefaultParameters(); - const UniformParameterList& progParams = pCpuProgram->getParameters(); - UniformParameterConstIterator itParams; - - for (itParams=progParams.begin(); itParams != progParams.end(); ++itParams) - { - const UniformParameterPtr pCurParam = *itParams; - const GpuConstantDefinition* gpuConstDef = pGpuParams->_findNamedConstantDefinition(pCurParam->getName()); - - if (gpuConstDef != NULL) - { - // Handle auto parameters. - if (pCurParam->isAutoConstantParameter()) - { - if (pCurParam->isAutoConstantRealParameter()) - { - pGpuParams->setNamedAutoConstantReal(pCurParam->getName(), - pCurParam->getAutoConstantType(), - pCurParam->getAutoConstantRealData()); - - } - else if (pCurParam->isAutoConstantIntParameter()) - { - pGpuParams->setNamedAutoConstant(pCurParam->getName(), - pCurParam->getAutoConstantType(), - pCurParam->getAutoConstantIntData()); - } - } - - // Case this is not auto constant - we have to update its variability ourself. - else - { - gpuConstDef->variability |= pCurParam->getVariability(); - - // Update variability in the float map. - if (gpuConstDef->isSampler() == false) - { - GpuLogicalBufferStructPtr floatLogical = pGpuParams->getFloatLogicalBufferStruct(); - if (floatLogical.get()) - { - for (GpuLogicalIndexUseMap::const_iterator i = floatLogical->map.begin(); i != floatLogical->map.end(); ++i) - { - if (i->second.physicalIndex == gpuConstDef->physicalIndex) - { - i->second.variability |= gpuConstDef->variability; - break; - } - } - } - } - } - } - } + GpuProgramParametersSharedPtr pGpuParams = pGpuProgram->getDefaultParameters(); + const UniformParameterList& progParams = pCpuProgram->getParameters(); + UniformParameterConstIterator itParams; + + for (itParams=progParams.begin(); itParams != progParams.end(); ++itParams) + { + const UniformParameterPtr pCurParam = *itParams; + const GpuConstantDefinition* gpuConstDef = pGpuParams->_findNamedConstantDefinition(pCurParam->getName()); + + if (gpuConstDef != NULL) + { + // Handle auto parameters. + if (pCurParam->isAutoConstantParameter()) + { + if (pCurParam->isAutoConstantRealParameter()) + { + pGpuParams->setNamedAutoConstantReal(pCurParam->getName(), + pCurParam->getAutoConstantType(), + pCurParam->getAutoConstantRealData()); + + } + else if (pCurParam->isAutoConstantIntParameter()) + { + pGpuParams->setNamedAutoConstant(pCurParam->getName(), + pCurParam->getAutoConstantType(), + pCurParam->getAutoConstantIntData()); + } + } + + // Case this is not auto constant - we have to update its variability ourself. + else + { + gpuConstDef->variability |= pCurParam->getVariability(); + + // Update variability in the float map. + if (gpuConstDef->isSampler() == false) + { + GpuLogicalBufferStructPtr floatLogical = pGpuParams->getFloatLogicalBufferStruct(); + if (floatLogical.get()) + { + for (GpuLogicalIndexUseMap::const_iterator i = floatLogical->map.begin(); i != floatLogical->map.end(); ++i) + { + if (i->second.physicalIndex == gpuConstDef->physicalIndex) + { + i->second.variability |= gpuConstDef->variability; + break; + } + } + } + } + } + } + } } //----------------------------------------------------------------------------- bool ProgramProcessor::compactVsOutputs(Function* vsMain, Function* fsMain) { - int outTexCoordSlots; - int outTexCoordFloats; + int outTexCoordSlots; + int outTexCoordFloats; - // Count vertex shader texcoords outputs. - countVsTexcoordOutputs(vsMain, outTexCoordSlots, outTexCoordFloats); + // Count vertex shader texcoords outputs. + countVsTexcoordOutputs(vsMain, outTexCoordSlots, outTexCoordFloats); - // Case the total number of used floats is bigger than maximum - nothing we can do. - if (outTexCoordFloats > mMaxTexCoordFloats) - return false; + // Case the total number of used floats is bigger than maximum - nothing we can do. + if (outTexCoordFloats > mMaxTexCoordFloats) + return false; - // Only one slot used -> nothing to compact. - if (outTexCoordSlots <= 1) - return true; + // Only one slot used -> nothing to compact. + if (outTexCoordSlots <= 1) + return true; - // Case compact policy is low and output slots are enough -> quit compacting process. - if (ShaderGenerator::getSingleton().getVertexShaderOutputsCompactPolicy() == VSOCP_LOW && outTexCoordSlots <= mMaxTexCoordSlots) - return true; + // Case compact policy is low and output slots are enough -> quit compacting process. + if (ShaderGenerator::getSingleton().getVertexShaderOutputsCompactPolicy() == VSOCP_LOW && outTexCoordSlots <= mMaxTexCoordSlots) + return true; - // Build output parameter tables - each row represents different parameter type (GCT_FLOAT1-4). - ShaderParameterList vsOutParamsTable[4]; - ShaderParameterList fsInParamsTable[4]; + // Build output parameter tables - each row represents different parameter type (GCT_FLOAT1-4). + ShaderParameterList vsOutParamsTable[4]; + ShaderParameterList fsInParamsTable[4]; - buildTexcoordTable(vsMain->getOutputParameters(), vsOutParamsTable); - buildTexcoordTable(fsMain->getInputParameters(), fsInParamsTable); + buildTexcoordTable(vsMain->getOutputParameters(), vsOutParamsTable); + buildTexcoordTable(fsMain->getInputParameters(), fsInParamsTable); - // Create merge parameters entries using the predefined merge combinations. - MergeParameterList vsMergedParamsList; - MergeParameterList fsMergedParamsList; - ShaderParameterList vsSplitParams; - ShaderParameterList fsSplitParams; - bool hasMergedParameters = false; - - mergeParameters(vsOutParamsTable, vsMergedParamsList, vsSplitParams); + // Create merge parameters entries using the predefined merge combinations. + MergeParameterList vsMergedParamsList; + MergeParameterList fsMergedParamsList; + ShaderParameterList vsSplitParams; + ShaderParameterList fsSplitParams; + bool hasMergedParameters = false; + + mergeParameters(vsOutParamsTable, vsMergedParamsList, vsSplitParams); - - // Check if any parameter has been merged - means at least two parameters takes the same slot. - for (unsigned int i=0; i < vsMergedParamsList.size(); ++i) - { - if (vsMergedParamsList[i].getSourceParameterCount() > 1) - { - hasMergedParameters = true; - break; - } - } + + // Check if any parameter has been merged - means at least two parameters takes the same slot. + for (unsigned int i=0; i < vsMergedParamsList.size(); ++i) + { + if (vsMergedParamsList[i].getSourceParameterCount() > 1) + { + hasMergedParameters = true; + break; + } + } - // Case no parameter has been merged -> quit compacting process. - if (hasMergedParameters == false) - return true; + // Case no parameter has been merged -> quit compacting process. + if (hasMergedParameters == false) + return true; - mergeParameters(fsInParamsTable, fsMergedParamsList, fsSplitParams); + mergeParameters(fsInParamsTable, fsMergedParamsList, fsSplitParams); - // Generate local params for split source parameters. - LocalParameterMap vsLocalParamsMap; - LocalParameterMap fsLocalParamsMap; + // Generate local params for split source parameters. + LocalParameterMap vsLocalParamsMap; + LocalParameterMap fsLocalParamsMap; - generateLocalSplitParameters(vsMain, GPT_VERTEX_PROGRAM, vsMergedParamsList, vsSplitParams, vsLocalParamsMap); - generateLocalSplitParameters(fsMain, GPT_FRAGMENT_PROGRAM, fsMergedParamsList, fsSplitParams, fsLocalParamsMap); + generateLocalSplitParameters(vsMain, GPT_VERTEX_PROGRAM, vsMergedParamsList, vsSplitParams, vsLocalParamsMap); + generateLocalSplitParameters(fsMain, GPT_FRAGMENT_PROGRAM, fsMergedParamsList, fsSplitParams, fsLocalParamsMap); - - // Rebuild functions parameter lists. - rebuildParameterList(vsMain, Operand::OPS_OUT, vsMergedParamsList); - rebuildParameterList(fsMain, Operand::OPS_IN, fsMergedParamsList); + + // Rebuild functions parameter lists. + rebuildParameterList(vsMain, Operand::OPS_OUT, vsMergedParamsList); + rebuildParameterList(fsMain, Operand::OPS_IN, fsMergedParamsList); - // Adjust function invocations operands to reference the new merged parameters. - rebuildFunctionInvocations(vsMain->getAtomInstances(), vsMergedParamsList, vsLocalParamsMap); - rebuildFunctionInvocations(fsMain->getAtomInstances(), fsMergedParamsList, fsLocalParamsMap); + // Adjust function invocations operands to reference the new merged parameters. + rebuildFunctionInvocations(vsMain->getAtomInstances(), vsMergedParamsList, vsLocalParamsMap); + rebuildFunctionInvocations(fsMain->getAtomInstances(), fsMergedParamsList, fsLocalParamsMap); - return true; + return true; } //----------------------------------------------------------------------------- void ProgramProcessor::countVsTexcoordOutputs(Function* vsMain, - int& outTexCoordSlots, - int& outTexCoordFloats) + int& outTexCoordSlots, + int& outTexCoordFloats) { - outTexCoordSlots = 0; - outTexCoordFloats = 0; + outTexCoordSlots = 0; + outTexCoordFloats = 0; - const ShaderParameterList& vsOutputs = vsMain->getOutputParameters(); - ShaderParameterConstIterator it = vsOutputs.begin(); - ShaderParameterConstIterator itEnd = vsOutputs.end(); + const ShaderParameterList& vsOutputs = vsMain->getOutputParameters(); + ShaderParameterConstIterator it = vsOutputs.begin(); + ShaderParameterConstIterator itEnd = vsOutputs.end(); - // Grab vertex shader output information. - for (; it != itEnd; ++it) - { - const ParameterPtr curParam = *it; + // Grab vertex shader output information. + for (; it != itEnd; ++it) + { + const ParameterPtr curParam = *it; - if (curParam->getSemantic() == Parameter::SPS_TEXTURE_COORDINATES) - { - outTexCoordSlots++; - outTexCoordFloats += getParameterFloatCount(curParam->getType()); - } - } + if (curParam->getSemantic() == Parameter::SPS_TEXTURE_COORDINATES) + { + outTexCoordSlots++; + outTexCoordFloats += getParameterFloatCount(curParam->getType()); + } + } } //----------------------------------------------------------------------------- void ProgramProcessor::buildTexcoordTable(const ShaderParameterList& paramList, ShaderParameterList outParamsTable[4]) { - ShaderParameterConstIterator it = paramList.begin(); - ShaderParameterConstIterator itEnd = paramList.end(); + ShaderParameterConstIterator it = paramList.begin(); + ShaderParameterConstIterator itEnd = paramList.end(); - for (; it != itEnd; ++it) - { - const ParameterPtr curParam = *it; + for (; it != itEnd; ++it) + { + const ParameterPtr curParam = *it; - if (curParam->getSemantic() == Parameter::SPS_TEXTURE_COORDINATES) - { + if (curParam->getSemantic() == Parameter::SPS_TEXTURE_COORDINATES) + { - switch (curParam->getType()) - { - case GCT_FLOAT1: - outParamsTable[0].push_back(curParam); - break; + switch (curParam->getType()) + { + case GCT_FLOAT1: + outParamsTable[0].push_back(curParam); + break; - case GCT_FLOAT2: - outParamsTable[1].push_back(curParam); - break; + case GCT_FLOAT2: + outParamsTable[1].push_back(curParam); + break; - case GCT_FLOAT3: - outParamsTable[2].push_back(curParam); - break; + case GCT_FLOAT3: + outParamsTable[2].push_back(curParam); + break; - case GCT_FLOAT4: - outParamsTable[3].push_back(curParam); - break; + case GCT_FLOAT4: + outParamsTable[3].push_back(curParam); + break; case GCT_SAMPLER1D: case GCT_SAMPLER2D: case GCT_SAMPLER2DARRAY: @@ -259,616 +259,616 @@ void ProgramProcessor::buildTexcoordTable(const ShaderParameterList& paramList, case GCT_INT2: case GCT_INT3: case GCT_INT4: - case GCT_UINT1: - case GCT_UINT2: - case GCT_UINT3: - case GCT_UINT4: + case GCT_UINT1: + case GCT_UINT2: + case GCT_UINT3: + case GCT_UINT4: case GCT_UNKNOWN: default: break; - } - } - } + } + } + } } //----------------------------------------------------------------------------- void ProgramProcessor::mergeParameters(ShaderParameterList paramsTable[4], MergeParameterList& mergedParams, - ShaderParameterList& splitParams) + ShaderParameterList& splitParams) { - // Merge using the predefined combinations. - mergeParametersByPredefinedCombinations(paramsTable, mergedParams); - - // Merge the reminders parameters if such left. - if (paramsTable[0].size() + paramsTable[1].size() + - paramsTable[2].size() + paramsTable[3].size() > 0) - { - mergeParametersReminders(paramsTable, mergedParams, splitParams); - } + // Merge using the predefined combinations. + mergeParametersByPredefinedCombinations(paramsTable, mergedParams); + + // Merge the reminders parameters if such left. + if (paramsTable[0].size() + paramsTable[1].size() + + paramsTable[2].size() + paramsTable[3].size() > 0) + { + mergeParametersReminders(paramsTable, mergedParams, splitParams); + } } //----------------------------------------------------------------------------- void ProgramProcessor::mergeParametersByPredefinedCombinations(ShaderParameterList paramsTable[4], - MergeParameterList& mergedParams) + MergeParameterList& mergedParams) { - // Make sure the merge combinations are ready. - if (mParamMergeCombinations.empty()) - { - buildMergeCombinations(); - } - - // Create the full used merged params - means FLOAT4 params that all of their components are used. - for (unsigned int i=0; i < mParamMergeCombinations.size(); ++i) - { - const MergeCombination& curCombination = mParamMergeCombinations[i]; - - // Case all parameters have been merged. - if (paramsTable[0].size() + paramsTable[1].size() + - paramsTable[2].size() + paramsTable[3].empty()) - return; - - MergeParameter curMergeParam; - - while (mergeParametersByCombination(curCombination, paramsTable, &curMergeParam)) - { - mergedParams.push_back(curMergeParam); - curMergeParam.clear(); - } - } - - // Case low/medium compacting policy -> use these simplified combinations in order to prevent splits. - if (ShaderGenerator::getSingleton().getVertexShaderOutputsCompactPolicy() == VSOCP_LOW || - ShaderGenerator::getSingleton().getVertexShaderOutputsCompactPolicy() == VSOCP_MEDIUM) - { - const int curUsedSlots = static_cast(mergedParams.size()); - const int float1ParamCount = static_cast(paramsTable[0].size()); - const int float2ParamCount = static_cast(paramsTable[1].size()); - const int float3ParamCount = static_cast(paramsTable[2].size()); - int reqSlots = 0; - - // Compute the required slots. - - // Add all float3 since each one of them require one slot for himself. - reqSlots += float3ParamCount; - - // Add the float2 count -> at max it will be 1 since all pairs have been merged previously. - if (float2ParamCount > 1) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid float2 reminder count.", - "ProgramProcessor::mergeParametersByPredefinedCombinations"); - } - - reqSlots += float2ParamCount; - - // Compute how much space needed for the float1(s) that left -> at max it will be 3. - if (float1ParamCount > 0) - { - if (float2ParamCount > 3) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid float1 reminder count.", - "ProgramProcessor::mergeParametersByPredefinedCombinations"); - } - - // No float2 -> we need one more slot for these float1(s). - if (float2ParamCount == 0) - { - reqSlots += 1; - } - else - { - // Float2 exists -> there must be at max 1 float1. - if (float1ParamCount > 1) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid float1 reminder count.", - "ProgramProcessor::mergeParametersByPredefinedCombinations"); - } - } - } - - // Case maximum slot count will be exceeded -> fall back to full compaction. - if (curUsedSlots + reqSlots > mMaxTexCoordSlots) - return; - - MergeCombination simpleCombinations[6] = - { - // Deal with the float3 parameters. - MergeCombination( - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 1, Operand::OPM_ALL, - 0, Operand::OPM_ALL), - - // Deal with float2 + float1 combination. - MergeCombination( - 1, Operand::OPM_ALL, - 1, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL), - - // Deal with the float2 parameter. - MergeCombination( - 0, Operand::OPM_ALL, - 1, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL), - - // Deal with the 3 float1 combination. - MergeCombination( - 3, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL), - - // Deal with the 2 float1 combination. - MergeCombination( - 2, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL), - - // Deal with the 1 float1 combination. - MergeCombination( - 1, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL), - - }; - - for (unsigned int i=0; i < 6; ++i) - { - const MergeCombination& curCombination = simpleCombinations[i]; - - // Case all parameters have been merged. - if (paramsTable[0].size() + paramsTable[1].size() + paramsTable[2].size() + paramsTable[3].empty()) - break; - - MergeParameter curMergeParam; - - while (mergeParametersByCombination(curCombination, paramsTable, &curMergeParam)) - { - mergedParams.push_back(curMergeParam); - curMergeParam.clear(); - } - } - } + // Make sure the merge combinations are ready. + if (mParamMergeCombinations.empty()) + { + buildMergeCombinations(); + } + + // Create the full used merged params - means FLOAT4 params that all of their components are used. + for (unsigned int i=0; i < mParamMergeCombinations.size(); ++i) + { + const MergeCombination& curCombination = mParamMergeCombinations[i]; + + // Case all parameters have been merged. + if (paramsTable[0].size() + paramsTable[1].size() + + paramsTable[2].size() + paramsTable[3].empty()) + return; + + MergeParameter curMergeParam; + + while (mergeParametersByCombination(curCombination, paramsTable, &curMergeParam)) + { + mergedParams.push_back(curMergeParam); + curMergeParam.clear(); + } + } + + // Case low/medium compacting policy -> use these simplified combinations in order to prevent splits. + if (ShaderGenerator::getSingleton().getVertexShaderOutputsCompactPolicy() == VSOCP_LOW || + ShaderGenerator::getSingleton().getVertexShaderOutputsCompactPolicy() == VSOCP_MEDIUM) + { + const int curUsedSlots = static_cast(mergedParams.size()); + const int float1ParamCount = static_cast(paramsTable[0].size()); + const int float2ParamCount = static_cast(paramsTable[1].size()); + const int float3ParamCount = static_cast(paramsTable[2].size()); + int reqSlots = 0; + + // Compute the required slots. + + // Add all float3 since each one of them require one slot for himself. + reqSlots += float3ParamCount; + + // Add the float2 count -> at max it will be 1 since all pairs have been merged previously. + if (float2ParamCount > 1) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid float2 reminder count.", + "ProgramProcessor::mergeParametersByPredefinedCombinations"); + } + + reqSlots += float2ParamCount; + + // Compute how much space needed for the float1(s) that left -> at max it will be 3. + if (float1ParamCount > 0) + { + if (float2ParamCount > 3) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid float1 reminder count.", + "ProgramProcessor::mergeParametersByPredefinedCombinations"); + } + + // No float2 -> we need one more slot for these float1(s). + if (float2ParamCount == 0) + { + reqSlots += 1; + } + else + { + // Float2 exists -> there must be at max 1 float1. + if (float1ParamCount > 1) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid float1 reminder count.", + "ProgramProcessor::mergeParametersByPredefinedCombinations"); + } + } + } + + // Case maximum slot count will be exceeded -> fall back to full compaction. + if (curUsedSlots + reqSlots > mMaxTexCoordSlots) + return; + + MergeCombination simpleCombinations[6] = + { + // Deal with the float3 parameters. + MergeCombination( + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 1, Operand::OPM_ALL, + 0, Operand::OPM_ALL), + + // Deal with float2 + float1 combination. + MergeCombination( + 1, Operand::OPM_ALL, + 1, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL), + + // Deal with the float2 parameter. + MergeCombination( + 0, Operand::OPM_ALL, + 1, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL), + + // Deal with the 3 float1 combination. + MergeCombination( + 3, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL), + + // Deal with the 2 float1 combination. + MergeCombination( + 2, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL), + + // Deal with the 1 float1 combination. + MergeCombination( + 1, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL), + + }; + + for (unsigned int i=0; i < 6; ++i) + { + const MergeCombination& curCombination = simpleCombinations[i]; + + // Case all parameters have been merged. + if (paramsTable[0].size() + paramsTable[1].size() + paramsTable[2].size() + paramsTable[3].empty()) + break; + + MergeParameter curMergeParam; + + while (mergeParametersByCombination(curCombination, paramsTable, &curMergeParam)) + { + mergedParams.push_back(curMergeParam); + curMergeParam.clear(); + } + } + } } //----------------------------------------------------------------------------- bool ProgramProcessor::mergeParametersByCombination(const MergeCombination& combination, - ShaderParameterList paramsTable[4], - MergeParameter* mergedParameter) + ShaderParameterList paramsTable[4], + MergeParameter* mergedParameter) { - // Make sure we have enough parameters to combine. - if (combination.srcParameterTypeCount[0] > paramsTable[0].size() || - combination.srcParameterTypeCount[1] > paramsTable[1].size() || - combination.srcParameterTypeCount[2] > paramsTable[2].size() || - combination.srcParameterTypeCount[3] > paramsTable[3].size()) - { - return false; - } - - // Create the new output parameter. - for (int i=0; i < 4; ++i) - { - ShaderParameterList& curParamList = paramsTable[i]; - int srcParameterTypeCount = static_cast(combination.srcParameterTypeCount[i]); - int srcParameterCount = 0; - - while (srcParameterTypeCount > 0) - { - mergedParameter->addSourceParameter(curParamList.back(), combination.srcParameterMask[srcParameterCount]); - curParamList.pop_back(); - srcParameterCount++; - --srcParameterTypeCount; - } - } - - - return true; + // Make sure we have enough parameters to combine. + if (combination.srcParameterTypeCount[0] > paramsTable[0].size() || + combination.srcParameterTypeCount[1] > paramsTable[1].size() || + combination.srcParameterTypeCount[2] > paramsTable[2].size() || + combination.srcParameterTypeCount[3] > paramsTable[3].size()) + { + return false; + } + + // Create the new output parameter. + for (int i=0; i < 4; ++i) + { + ShaderParameterList& curParamList = paramsTable[i]; + int srcParameterTypeCount = static_cast(combination.srcParameterTypeCount[i]); + int srcParameterCount = 0; + + while (srcParameterTypeCount > 0) + { + mergedParameter->addSourceParameter(curParamList.back(), combination.srcParameterMask[srcParameterCount]); + curParamList.pop_back(); + srcParameterCount++; + --srcParameterTypeCount; + } + } + + + return true; } //----------------------------------------------------------------------------- void ProgramProcessor::mergeParametersReminders(ShaderParameterList paramsTable[4], MergeParameterList& mergedParams, ShaderParameterList& splitParams) { - - // Handle reminders parameters - All of the parameters that could not packed perfectly. - const size_t mergedParamsBaseIndex = mergedParams.size(); - const size_t remindersFloatCount = (1 * paramsTable[0].size()) + (2 * paramsTable[1].size()) + (3 * paramsTable[2].size()) + (4 * paramsTable[3].size()); - const size_t remindersFloatMod = remindersFloatCount % 4; - const size_t remindersFullSlotCount = remindersFloatCount / 4; - const size_t remindersPartialSlotCount = remindersFloatMod > 0 ? 1 : 0; - const size_t remindersTotalSlotCount = remindersFullSlotCount + remindersPartialSlotCount; - - // First pass -> fill the slots with the largest reminders parameters. - for (unsigned int slot=0; slot < remindersTotalSlotCount; ++slot) - { - MergeParameter curMergeParam; - - for (unsigned int row=0; row < 4; ++row) - { - ShaderParameterList& curParamList = paramsTable[3 - row]; - - // Case this list contains parameters -> pop it out and add to merged params. - if (curParamList.size() > 0) - { - curMergeParam.addSourceParameter(curParamList.back(), Operand::OPM_ALL); - curParamList.pop_back(); - mergedParams.push_back(curMergeParam); - break; - } - } - } - - // Second pass -> merge the reminders parameters. - for (unsigned int row=0; row < 4; ++row) - { - ShaderParameterList& curParamList = paramsTable[3 - row]; - - // Merge the all the parameters of the current list. - while (curParamList.size() > 0) - { - ParameterPtr srcParameter = curParamList.back(); - int splitCount = 0; // How many times the source parameter has been split. - int srcParameterComponents; - int srcParameterFloats; - int curSrcParameterFloats; - - srcParameterFloats = getParameterFloatCount(srcParameter->getType()); - curSrcParameterFloats = srcParameterFloats; - srcParameterComponents = getParameterMaskByType(srcParameter->getType()); - - - // While this parameter has remaining components -> split it. - while (curSrcParameterFloats > 0) - { - for (unsigned int slot=0; slot < remindersTotalSlotCount && curSrcParameterFloats > 0; ++slot) - { - MergeParameter& curMergeParam = mergedParams[mergedParamsBaseIndex + slot]; - const int freeFloatCount = 4 - curMergeParam.getUsedFloatCount(); - - // Case this slot has free space. - if (freeFloatCount > 0) - { - // Case current components of source parameter can go all into this slot without split. - if (srcParameterFloats < freeFloatCount && splitCount == 0) - { - curMergeParam.addSourceParameter(srcParameter, Operand::OPM_ALL); - } - - // Case we have to split the current source parameter. - else - { - int srcComponentsMask; - - // Create the mask that tell us which part of the source component is added to the merged parameter. - srcComponentsMask = getParameterMaskByFloatCount(freeFloatCount) << splitCount; - - // Add the partial source parameter to merged parameter. - curMergeParam.addSourceParameter(srcParameter, srcComponentsMask & srcParameterComponents); - } - splitCount++; - - // Update left floats count. - if (srcParameterFloats < freeFloatCount) - { - curSrcParameterFloats -= srcParameterFloats; - } - else - { - curSrcParameterFloats -= freeFloatCount; - } - } - } - } - - // Add to split params list. - if (splitCount > 1) - splitParams.push_back(srcParameter); - - - curParamList.pop_back(); - } - } + + // Handle reminders parameters - All of the parameters that could not packed perfectly. + const size_t mergedParamsBaseIndex = mergedParams.size(); + const size_t remindersFloatCount = (1 * paramsTable[0].size()) + (2 * paramsTable[1].size()) + (3 * paramsTable[2].size()) + (4 * paramsTable[3].size()); + const size_t remindersFloatMod = remindersFloatCount % 4; + const size_t remindersFullSlotCount = remindersFloatCount / 4; + const size_t remindersPartialSlotCount = remindersFloatMod > 0 ? 1 : 0; + const size_t remindersTotalSlotCount = remindersFullSlotCount + remindersPartialSlotCount; + + // First pass -> fill the slots with the largest reminders parameters. + for (unsigned int slot=0; slot < remindersTotalSlotCount; ++slot) + { + MergeParameter curMergeParam; + + for (unsigned int row=0; row < 4; ++row) + { + ShaderParameterList& curParamList = paramsTable[3 - row]; + + // Case this list contains parameters -> pop it out and add to merged params. + if (curParamList.size() > 0) + { + curMergeParam.addSourceParameter(curParamList.back(), Operand::OPM_ALL); + curParamList.pop_back(); + mergedParams.push_back(curMergeParam); + break; + } + } + } + + // Second pass -> merge the reminders parameters. + for (unsigned int row=0; row < 4; ++row) + { + ShaderParameterList& curParamList = paramsTable[3 - row]; + + // Merge the all the parameters of the current list. + while (curParamList.size() > 0) + { + ParameterPtr srcParameter = curParamList.back(); + int splitCount = 0; // How many times the source parameter has been split. + int srcParameterComponents; + int srcParameterFloats; + int curSrcParameterFloats; + + srcParameterFloats = getParameterFloatCount(srcParameter->getType()); + curSrcParameterFloats = srcParameterFloats; + srcParameterComponents = getParameterMaskByType(srcParameter->getType()); + + + // While this parameter has remaining components -> split it. + while (curSrcParameterFloats > 0) + { + for (unsigned int slot=0; slot < remindersTotalSlotCount && curSrcParameterFloats > 0; ++slot) + { + MergeParameter& curMergeParam = mergedParams[mergedParamsBaseIndex + slot]; + const int freeFloatCount = 4 - curMergeParam.getUsedFloatCount(); + + // Case this slot has free space. + if (freeFloatCount > 0) + { + // Case current components of source parameter can go all into this slot without split. + if (srcParameterFloats < freeFloatCount && splitCount == 0) + { + curMergeParam.addSourceParameter(srcParameter, Operand::OPM_ALL); + } + + // Case we have to split the current source parameter. + else + { + int srcComponentsMask; + + // Create the mask that tell us which part of the source component is added to the merged parameter. + srcComponentsMask = getParameterMaskByFloatCount(freeFloatCount) << splitCount; + + // Add the partial source parameter to merged parameter. + curMergeParam.addSourceParameter(srcParameter, srcComponentsMask & srcParameterComponents); + } + splitCount++; + + // Update left floats count. + if (srcParameterFloats < freeFloatCount) + { + curSrcParameterFloats -= srcParameterFloats; + } + else + { + curSrcParameterFloats -= freeFloatCount; + } + } + } + } + + // Add to split params list. + if (splitCount > 1) + splitParams.push_back(srcParameter); + + + curParamList.pop_back(); + } + } } //----------------------------------------------------------------------------- void ProgramProcessor::rebuildParameterList(Function* func, int paramsUsage, MergeParameterList& mergedParams) { - // Delete the old merged parameters. - for (unsigned int i=0; i < mergedParams.size(); ++i) - { - MergeParameter& curMergeParameter = mergedParams[i]; - - for (unsigned int j=0; j < curMergeParameter.getSourceParameterCount(); ++j) - { - ParameterPtr curSrcParam = curMergeParameter.getSourceParameter(j); - - if (paramsUsage == Operand::OPS_OUT) - { - func->deleteOutputParameter(curSrcParam); - } - else if (paramsUsage == Operand::OPS_IN) - { - func->deleteInputParameter(curSrcParam); - } - } - } - - // Add the new combined parameters. - for (unsigned int i=0; i < mergedParams.size(); ++i) - { - MergeParameter& curMergeParameter = mergedParams[i]; - - if (paramsUsage == Operand::OPS_OUT) - { - func->addOutputParameter(curMergeParameter.getDestinationParameter(paramsUsage, i)); - } - else if (paramsUsage == Operand::OPS_IN) - { - func->addInputParameter(curMergeParameter.getDestinationParameter(paramsUsage, i)); - } - } + // Delete the old merged parameters. + for (unsigned int i=0; i < mergedParams.size(); ++i) + { + MergeParameter& curMergeParameter = mergedParams[i]; + + for (unsigned int j=0; j < curMergeParameter.getSourceParameterCount(); ++j) + { + ParameterPtr curSrcParam = curMergeParameter.getSourceParameter(j); + + if (paramsUsage == Operand::OPS_OUT) + { + func->deleteOutputParameter(curSrcParam); + } + else if (paramsUsage == Operand::OPS_IN) + { + func->deleteInputParameter(curSrcParam); + } + } + } + + // Add the new combined parameters. + for (unsigned int i=0; i < mergedParams.size(); ++i) + { + MergeParameter& curMergeParameter = mergedParams[i]; + + if (paramsUsage == Operand::OPS_OUT) + { + func->addOutputParameter(curMergeParameter.getDestinationParameter(paramsUsage, i)); + } + else if (paramsUsage == Operand::OPS_IN) + { + func->addInputParameter(curMergeParameter.getDestinationParameter(paramsUsage, i)); + } + } } //----------------------------------------------------------------------------- void ProgramProcessor::generateLocalSplitParameters(Function* func, GpuProgramType progType, - MergeParameterList& mergedParams, - ShaderParameterList& splitParams, LocalParameterMap& localParamsMap) + MergeParameterList& mergedParams, + ShaderParameterList& splitParams, LocalParameterMap& localParamsMap) { - // No split params created. - if (splitParams.empty()) - return; - - // Create the local parameters + map from source to local. - for (unsigned int i=0; i < splitParams.size(); ++i) - { - ParameterPtr srcParameter = splitParams[i]; - ParameterPtr localParameter = func->resolveLocalParameter(srcParameter->getSemantic(), srcParameter->getIndex(), "lsplit_" + srcParameter->getName(), srcParameter->getType()); - - localParamsMap[srcParameter.get()] = localParameter; - } - - int invocationCounter = 0; - - // Establish link between the local parameter to the merged parameter. - for (unsigned int i=0; i < mergedParams.size(); ++i) - { - MergeParameter& curMergeParameter = mergedParams[i]; - - for (unsigned int p=0; p < curMergeParameter.getSourceParameterCount(); ++p) - { - ParameterPtr srcMergedParameter = curMergeParameter.getSourceParameter(p); - LocalParameterMap::iterator itFind = localParamsMap.find(srcMergedParameter.get()); - - // Case the source parameter is split parameter. - if (itFind != localParamsMap.end()) - { - // Case it is the vertex shader -> assign the local parameter to the output merged parameter. - if (progType == GPT_VERTEX_PROGRAM) - { - FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_POST_PROCESS, invocationCounter++); - - curFuncInvocation->pushOperand(itFind->second, Operand::OPS_IN, curMergeParameter.getSourceParameterMask(p)); - curFuncInvocation->pushOperand(curMergeParameter.getDestinationParameter(Operand::OPS_OUT, i), Operand::OPS_OUT, curMergeParameter.getDestinationParameterMask(p)); - func->addAtomInstance(curFuncInvocation); - } - else if (progType == GPT_FRAGMENT_PROGRAM) - { - FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_PRE_PROCESS, invocationCounter++); - - curFuncInvocation->pushOperand(curMergeParameter.getDestinationParameter(Operand::OPS_IN, i), Operand::OPS_IN, curMergeParameter.getDestinationParameterMask(p)); - curFuncInvocation->pushOperand(itFind->second, Operand::OPS_OUT, curMergeParameter.getSourceParameterMask(p)); - func->addAtomInstance(curFuncInvocation); - } - } - } - } + // No split params created. + if (splitParams.empty()) + return; + + // Create the local parameters + map from source to local. + for (unsigned int i=0; i < splitParams.size(); ++i) + { + ParameterPtr srcParameter = splitParams[i]; + ParameterPtr localParameter = func->resolveLocalParameter(srcParameter->getSemantic(), srcParameter->getIndex(), "lsplit_" + srcParameter->getName(), srcParameter->getType()); + + localParamsMap[srcParameter.get()] = localParameter; + } + + int invocationCounter = 0; + + // Establish link between the local parameter to the merged parameter. + for (unsigned int i=0; i < mergedParams.size(); ++i) + { + MergeParameter& curMergeParameter = mergedParams[i]; + + for (unsigned int p=0; p < curMergeParameter.getSourceParameterCount(); ++p) + { + ParameterPtr srcMergedParameter = curMergeParameter.getSourceParameter(p); + LocalParameterMap::iterator itFind = localParamsMap.find(srcMergedParameter.get()); + + // Case the source parameter is split parameter. + if (itFind != localParamsMap.end()) + { + // Case it is the vertex shader -> assign the local parameter to the output merged parameter. + if (progType == GPT_VERTEX_PROGRAM) + { + FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_VS_POST_PROCESS, invocationCounter++); + + curFuncInvocation->pushOperand(itFind->second, Operand::OPS_IN, curMergeParameter.getSourceParameterMask(p)); + curFuncInvocation->pushOperand(curMergeParameter.getDestinationParameter(Operand::OPS_OUT, i), Operand::OPS_OUT, curMergeParameter.getDestinationParameterMask(p)); + func->addAtomInstance(curFuncInvocation); + } + else if (progType == GPT_FRAGMENT_PROGRAM) + { + FunctionInvocation* curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_PRE_PROCESS, invocationCounter++); + + curFuncInvocation->pushOperand(curMergeParameter.getDestinationParameter(Operand::OPS_IN, i), Operand::OPS_IN, curMergeParameter.getDestinationParameterMask(p)); + curFuncInvocation->pushOperand(itFind->second, Operand::OPS_OUT, curMergeParameter.getSourceParameterMask(p)); + func->addAtomInstance(curFuncInvocation); + } + } + } + } } //----------------------------------------------------------------------------- void ProgramProcessor::rebuildFunctionInvocations(FunctionAtomInstanceList& funcAtomList, - MergeParameterList& mergedParams, - LocalParameterMap& localParamsMap) -{ - ParameterOperandMap paramsRefMap; + MergeParameterList& mergedParams, + LocalParameterMap& localParamsMap) +{ + ParameterOperandMap paramsRefMap; - // Build reference map of source parameters. - buildParameterReferenceMap(funcAtomList, paramsRefMap); + // Build reference map of source parameters. + buildParameterReferenceMap(funcAtomList, paramsRefMap); - // Replace references to old parameters with references to new parameters. - replaceParametersReferences(mergedParams, paramsRefMap); + // Replace references to old parameters with references to new parameters. + replaceParametersReferences(mergedParams, paramsRefMap); - // Replace references to old parameters with references to new split parameters. - replaceSplitParametersReferences(localParamsMap, paramsRefMap); + // Replace references to old parameters with references to new split parameters. + replaceSplitParametersReferences(localParamsMap, paramsRefMap); } //----------------------------------------------------------------------------- void ProgramProcessor::buildParameterReferenceMap(FunctionAtomInstanceList& funcAtomList, ParameterOperandMap& paramsRefMap) { - - FunctionAtomInstanceIterator it = funcAtomList.begin(); - FunctionAtomInstanceIterator itEnd = funcAtomList.end(); - - for (; it != itEnd; ++it) - { - FunctionAtom* curAtom = *it; - - // Deal only with function invocations. - if (curAtom->getFunctionAtomType() == FunctionInvocation::Type) - { - FunctionInvocation* curFuncInvocation = static_cast(curAtom); - FunctionInvocation::OperandVector& funcOperands = curFuncInvocation->getOperandList(); - - for (unsigned int op=0; op < funcOperands.size(); ++op) - { - Operand& curOperand = funcOperands[op]; - - paramsRefMap[curOperand.getParameter().get()].push_back(&curOperand); - } - } - } + + FunctionAtomInstanceIterator it = funcAtomList.begin(); + FunctionAtomInstanceIterator itEnd = funcAtomList.end(); + + for (; it != itEnd; ++it) + { + FunctionAtom* curAtom = *it; + + // Deal only with function invocations. + if (curAtom->getFunctionAtomType() == FunctionInvocation::Type) + { + FunctionInvocation* curFuncInvocation = static_cast(curAtom); + FunctionInvocation::OperandVector& funcOperands = curFuncInvocation->getOperandList(); + + for (unsigned int op=0; op < funcOperands.size(); ++op) + { + Operand& curOperand = funcOperands[op]; + + paramsRefMap[curOperand.getParameter().get()].push_back(&curOperand); + } + } + } } //----------------------------------------------------------------------------- void ProgramProcessor::replaceParametersReferences(MergeParameterList& mergedParams, ParameterOperandMap& paramsRefMap) { - for (unsigned int i=0; i < mergedParams.size(); ++i) - { - MergeParameter& curMergeParameter = mergedParams[i]; - int paramBitMaskOffset = 0; - - for (unsigned int j=0; j < curMergeParameter.getSourceParameterCount(); ++j) - { - ParameterPtr curSrcParam = curMergeParameter.getSourceParameter(j); - ParameterOperandMap::iterator itParamRefs = paramsRefMap.find(curSrcParam.get()); - - // Case the source parameter has some references - if (itParamRefs != paramsRefMap.end()) - { - OperandPtrVector& srcParamRefs = itParamRefs->second; - ParameterPtr dstParameter; - - // Case the source parameter is fully contained within the destination merged parameter. - if (curMergeParameter.getSourceParameterMask(j) == Operand::OPM_ALL) - { - dstParameter = curMergeParameter.getDestinationParameter(Operand::OPS_INOUT, i); - - for (unsigned int op=0; op < srcParamRefs.size(); ++op) - { - Operand* srcOperandPtr = srcParamRefs[op]; - int dstOpMask; - - if (srcOperandPtr->getMask() == Operand::OPM_ALL) - { - // Case the merged parameter contains only one source - no point in adding special mask. - if (curMergeParameter.getSourceParameterCount() == 1) - { - dstOpMask = Operand::OPM_ALL; - } - else - { - dstOpMask = getParameterMaskByType(curSrcParam->getType()) << paramBitMaskOffset; - } - } - else - { - dstOpMask = srcOperandPtr->getMask() << paramBitMaskOffset; - } - - // Replace the original source operand with a new operand the reference the new merged parameter. - *srcOperandPtr = Operand(dstParameter, srcOperandPtr->getSemantic(), dstOpMask); - } - } - } - - - // Update the bit mask offset. - paramBitMaskOffset += getParameterFloatCount(curSrcParam->getType()); - } - } + for (unsigned int i=0; i < mergedParams.size(); ++i) + { + MergeParameter& curMergeParameter = mergedParams[i]; + int paramBitMaskOffset = 0; + + for (unsigned int j=0; j < curMergeParameter.getSourceParameterCount(); ++j) + { + ParameterPtr curSrcParam = curMergeParameter.getSourceParameter(j); + ParameterOperandMap::iterator itParamRefs = paramsRefMap.find(curSrcParam.get()); + + // Case the source parameter has some references + if (itParamRefs != paramsRefMap.end()) + { + OperandPtrVector& srcParamRefs = itParamRefs->second; + ParameterPtr dstParameter; + + // Case the source parameter is fully contained within the destination merged parameter. + if (curMergeParameter.getSourceParameterMask(j) == Operand::OPM_ALL) + { + dstParameter = curMergeParameter.getDestinationParameter(Operand::OPS_INOUT, i); + + for (unsigned int op=0; op < srcParamRefs.size(); ++op) + { + Operand* srcOperandPtr = srcParamRefs[op]; + int dstOpMask; + + if (srcOperandPtr->getMask() == Operand::OPM_ALL) + { + // Case the merged parameter contains only one source - no point in adding special mask. + if (curMergeParameter.getSourceParameterCount() == 1) + { + dstOpMask = Operand::OPM_ALL; + } + else + { + dstOpMask = getParameterMaskByType(curSrcParam->getType()) << paramBitMaskOffset; + } + } + else + { + dstOpMask = srcOperandPtr->getMask() << paramBitMaskOffset; + } + + // Replace the original source operand with a new operand the reference the new merged parameter. + *srcOperandPtr = Operand(dstParameter, srcOperandPtr->getSemantic(), dstOpMask); + } + } + } + + + // Update the bit mask offset. + paramBitMaskOffset += getParameterFloatCount(curSrcParam->getType()); + } + } } //----------------------------------------------------------------------------- void ProgramProcessor::replaceSplitParametersReferences(LocalParameterMap& localParamsMap, ParameterOperandMap& paramsRefMap) { - LocalParameterMap::iterator it = localParamsMap.begin(); - LocalParameterMap::iterator itEnd = localParamsMap.end(); - - for (; it != itEnd; ++it) - { - Parameter* curSrcParam = it->first; - ParameterOperandMap::iterator itParamRefs = paramsRefMap.find(curSrcParam); - - if (itParamRefs != paramsRefMap.end()) - { - ParameterPtr dstParameter = it->second; - OperandPtrVector& srcParamRefs = itParamRefs->second; - - for (unsigned int op=0; op < srcParamRefs.size(); ++op) - { - Operand* srcOperandPtr = srcParamRefs[op]; - int dstOpMask; - - if (srcOperandPtr->getMask() == Operand::OPM_ALL) - { - dstOpMask = getParameterMaskByType(curSrcParam->getType()); - } - else - { - dstOpMask = srcOperandPtr->getMask(); - } - - // Replace the original source operand with a new operand the reference the new merged parameter. - *srcOperandPtr = Operand(dstParameter, srcOperandPtr->getSemantic(), dstOpMask); - } - } - } + LocalParameterMap::iterator it = localParamsMap.begin(); + LocalParameterMap::iterator itEnd = localParamsMap.end(); + + for (; it != itEnd; ++it) + { + Parameter* curSrcParam = it->first; + ParameterOperandMap::iterator itParamRefs = paramsRefMap.find(curSrcParam); + + if (itParamRefs != paramsRefMap.end()) + { + ParameterPtr dstParameter = it->second; + OperandPtrVector& srcParamRefs = itParamRefs->second; + + for (unsigned int op=0; op < srcParamRefs.size(); ++op) + { + Operand* srcOperandPtr = srcParamRefs[op]; + int dstOpMask; + + if (srcOperandPtr->getMask() == Operand::OPM_ALL) + { + dstOpMask = getParameterMaskByType(curSrcParam->getType()); + } + else + { + dstOpMask = srcOperandPtr->getMask(); + } + + // Replace the original source operand with a new operand the reference the new merged parameter. + *srcOperandPtr = Operand(dstParameter, srcOperandPtr->getSemantic(), dstOpMask); + } + } + } } //----------------------------------------------------------------------------- -int ProgramProcessor::getParameterFloatCount(GpuConstantType type) +int ProgramProcessor::getParameterFloatCount(GpuConstantType type) { - int floatCount = 0; - - switch (type) - { - case GCT_FLOAT1: floatCount = 1; break; - case GCT_FLOAT2: floatCount = 2; break; - case GCT_FLOAT3: floatCount = 3; break; - case GCT_FLOAT4: floatCount = 4; break; - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid parameter float type.", - "ProgramProcessor::getParameterFloatCount"); - } - - return floatCount; + int floatCount = 0; + + switch (type) + { + case GCT_FLOAT1: floatCount = 1; break; + case GCT_FLOAT2: floatCount = 2; break; + case GCT_FLOAT3: floatCount = 3; break; + case GCT_FLOAT4: floatCount = 4; break; + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid parameter float type.", + "ProgramProcessor::getParameterFloatCount"); + } + + return floatCount; } //----------------------------------------------------------------------------- int ProgramProcessor::getParameterMaskByType(GpuConstantType type) { - int paramMask = 0; - - switch (type) - { - case GCT_FLOAT1: paramMask = Operand::OPM_X; break; - case GCT_FLOAT2: paramMask = Operand::OPM_XY; break; - case GCT_FLOAT3: paramMask = Operand::OPM_XYZ; break; - case GCT_FLOAT4: paramMask = Operand::OPM_XYZW; break; - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid parameter float type.", - "ProgramProcessor::getParameterMaskByType"); - } - - return paramMask; + int paramMask = 0; + + switch (type) + { + case GCT_FLOAT1: paramMask = Operand::OPM_X; break; + case GCT_FLOAT2: paramMask = Operand::OPM_XY; break; + case GCT_FLOAT3: paramMask = Operand::OPM_XYZ; break; + case GCT_FLOAT4: paramMask = Operand::OPM_XYZW; break; + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid parameter float type.", + "ProgramProcessor::getParameterMaskByType"); + } + + return paramMask; } //----------------------------------------------------------------------------- int ProgramProcessor::getParameterMaskByFloatCount(int floatCount) { - int paramMask = 0; - - switch (floatCount) - { - case 1: paramMask = Operand::OPM_X; break; - case 2: paramMask = Operand::OPM_XY; break; - case 3: paramMask = Operand::OPM_XYZ; break; - case 4: paramMask = Operand::OPM_XYZW; break; - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid parameter float type.", - "ProgramProcessor::getParameterMaskByFloatCount"); - } - - return paramMask; + int paramMask = 0; + + switch (floatCount) + { + case 1: paramMask = Operand::OPM_X; break; + case 2: paramMask = Operand::OPM_XY; break; + case 3: paramMask = Operand::OPM_XYZ; break; + case 4: paramMask = Operand::OPM_XYZW; break; + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid parameter float type.", + "ProgramProcessor::getParameterMaskByFloatCount"); + } + + return paramMask; } @@ -876,152 +876,152 @@ int ProgramProcessor::getParameterMaskByFloatCount(int floatCount) //----------------------------------------------------------------------------- void ProgramProcessor::buildMergeCombinations() { - mParamMergeCombinations.push_back( - MergeCombination( - 1, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 1, Operand::OPM_ALL, - 0, Operand::OPM_ALL)); - - mParamMergeCombinations.push_back( - MergeCombination( - 2, Operand::OPM_ALL, - 1, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL)); - - mParamMergeCombinations.push_back( - MergeCombination( - 4, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL)); - - mParamMergeCombinations.push_back( - MergeCombination( - 0, Operand::OPM_ALL, - 2, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL)); - - mParamMergeCombinations.push_back( - MergeCombination( - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 0, Operand::OPM_ALL, - 1, Operand::OPM_ALL)); + mParamMergeCombinations.push_back( + MergeCombination( + 1, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 1, Operand::OPM_ALL, + 0, Operand::OPM_ALL)); + + mParamMergeCombinations.push_back( + MergeCombination( + 2, Operand::OPM_ALL, + 1, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL)); + + mParamMergeCombinations.push_back( + MergeCombination( + 4, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL)); + + mParamMergeCombinations.push_back( + MergeCombination( + 0, Operand::OPM_ALL, + 2, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL)); + + mParamMergeCombinations.push_back( + MergeCombination( + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 0, Operand::OPM_ALL, + 1, Operand::OPM_ALL)); } //----------------------------------------------------------------------------- ProgramProcessor::MergeParameter::MergeParameter() { - clear(); + clear(); } //----------------------------------------------------------------------------- void ProgramProcessor::MergeParameter::addSourceParameter(ParameterPtr srcParam, int mask) { - // Case source count exceeded maximum - if (mSrcParameterCount >= 4) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Merged parameter source parameters overflow", - "MergeParameter::addSourceParameter"); - } - - mSrcParameter[mSrcParameterCount] = srcParam; - mSrcParameterMask[mSrcParameterCount] = mask; - - if (mask == Operand::OPM_ALL) - { - mDstParameterMask[mSrcParameterCount] = mask; - - mUsedFloatCount += getParameterFloatCount(srcParam->getType()); - } - else - { - int srcParamFloatCount = Operand::getFloatCount(mask); - - mDstParameterMask[mSrcParameterCount] = getParameterMaskByFloatCount(srcParamFloatCount) << mUsedFloatCount; - mUsedFloatCount += srcParamFloatCount; - } - - mSrcParameterCount++; - - - // Case float count exceeded maximum - if (mUsedFloatCount > 4) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Merged parameter floats overflow", - "MergeParameter::addSourceParameter"); - } + // Case source count exceeded maximum + if (mSrcParameterCount >= 4) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Merged parameter source parameters overflow", + "MergeParameter::addSourceParameter"); + } + + mSrcParameter[mSrcParameterCount] = srcParam; + mSrcParameterMask[mSrcParameterCount] = mask; + + if (mask == Operand::OPM_ALL) + { + mDstParameterMask[mSrcParameterCount] = mask; + + mUsedFloatCount += getParameterFloatCount(srcParam->getType()); + } + else + { + int srcParamFloatCount = Operand::getFloatCount(mask); + + mDstParameterMask[mSrcParameterCount] = getParameterMaskByFloatCount(srcParamFloatCount) << mUsedFloatCount; + mUsedFloatCount += srcParamFloatCount; + } + + mSrcParameterCount++; + + + // Case float count exceeded maximum + if (mUsedFloatCount > 4) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Merged parameter floats overflow", + "MergeParameter::addSourceParameter"); + } } //----------------------------------------------------------------------------- int ProgramProcessor::MergeParameter::getUsedFloatCount() { - return mUsedFloatCount; + return mUsedFloatCount; } //----------------------------------------------------------------------------- void ProgramProcessor::MergeParameter::createDestinationParameter(int usage, int index) { - GpuConstantType dstParamType = GCT_UNKNOWN; + GpuConstantType dstParamType = GCT_UNKNOWN; - switch (getUsedFloatCount()) - { - case 1: - dstParamType = GCT_FLOAT1; - break; + switch (getUsedFloatCount()) + { + case 1: + dstParamType = GCT_FLOAT1; + break; - case 2: - dstParamType = GCT_FLOAT2; - break; + case 2: + dstParamType = GCT_FLOAT2; + break; - case 3: - dstParamType = GCT_FLOAT3; - break; + case 3: + dstParamType = GCT_FLOAT3; + break; - case 4: - dstParamType = GCT_FLOAT4; - break; + case 4: + dstParamType = GCT_FLOAT4; + break; - } + } - if (usage == Operand::OPS_IN) - { - mDstParameter = ParameterFactory::createInTexcoord(dstParamType, index, Parameter::SPC_UNKNOWN); - } - else if (usage == Operand::OPS_OUT) - { - mDstParameter = ParameterFactory::createOutTexcoord(dstParamType, index, Parameter::SPC_UNKNOWN); - } + if (usage == Operand::OPS_IN) + { + mDstParameter = ParameterFactory::createInTexcoord(dstParamType, index, Parameter::SPC_UNKNOWN); + } + else if (usage == Operand::OPS_OUT) + { + mDstParameter = ParameterFactory::createOutTexcoord(dstParamType, index, Parameter::SPC_UNKNOWN); + } } //----------------------------------------------------------------------------- Ogre::RTShader::ParameterPtr ProgramProcessor::MergeParameter::getDestinationParameter(int usage, int index) { - if (mDstParameter.isNull()) - createDestinationParameter(usage, index); + if (mDstParameter.isNull()) + createDestinationParameter(usage, index); - return mDstParameter; + return mDstParameter; } //----------------------------------------------------------------------------- void ProgramProcessor::MergeParameter::clear() { - mDstParameter.setNull(); - for (unsigned int i=0; i < 4; ++i) - { - mSrcParameter[i].setNull(); - mSrcParameterMask[i] = 0; - mDstParameterMask[i] = 0; - } - mSrcParameterCount = 0; - mUsedFloatCount = 0; + mDstParameter.setNull(); + for (unsigned int i=0; i < 4; ++i) + { + mSrcParameter[i].setNull(); + mSrcParameterMask[i] = 0; + mDstParameterMask[i] = 0; + } + mSrcParameterCount = 0; + mUsedFloatCount = 0; } } diff --git a/Components/RTShaderSystem/src/OgreShaderProgramSet.cpp b/Components/RTShaderSystem/src/OgreShaderProgramSet.cpp index 92617588313..5a77ed1ee97 100644 --- a/Components/RTShaderSystem/src/OgreShaderProgramSet.cpp +++ b/Components/RTShaderSystem/src/OgreShaderProgramSet.cpp @@ -33,74 +33,74 @@ namespace RTShader { //----------------------------------------------------------------------------- ProgramSet::ProgramSet() : mVSCpuProgram(0), mPSCpuProgram(0) -{ +{ } //----------------------------------------------------------------------------- ProgramSet::~ProgramSet() { - if (mVSCpuProgram != NULL) - { - ProgramManager::getSingleton().destroyCpuProgram(mVSCpuProgram); - mVSCpuProgram = NULL; - } - - if (mPSCpuProgram != NULL) - { - ProgramManager::getSingleton().destroyCpuProgram(mPSCpuProgram); - mPSCpuProgram = NULL; - } - - mVSGpuProgram.setNull(); - mPSGpuProgram.setNull(); + if (mVSCpuProgram != NULL) + { + ProgramManager::getSingleton().destroyCpuProgram(mVSCpuProgram); + mVSCpuProgram = NULL; + } + + if (mPSCpuProgram != NULL) + { + ProgramManager::getSingleton().destroyCpuProgram(mPSCpuProgram); + mPSCpuProgram = NULL; + } + + mVSGpuProgram.setNull(); + mPSGpuProgram.setNull(); } //----------------------------------------------------------------------------- void ProgramSet::setCpuVertexProgram(Program* vsCpuProgram) { - mVSCpuProgram = vsCpuProgram; + mVSCpuProgram = vsCpuProgram; } //----------------------------------------------------------------------------- Program* ProgramSet::getCpuVertexProgram() { - return mVSCpuProgram; + return mVSCpuProgram; } //----------------------------------------------------------------------------- void ProgramSet::setCpuFragmentProgram(Program* psCpuProgram) { - mPSCpuProgram = psCpuProgram; + mPSCpuProgram = psCpuProgram; } //----------------------------------------------------------------------------- Program* ProgramSet::getCpuFragmentProgram() { - return mPSCpuProgram; + return mPSCpuProgram; } //----------------------------------------------------------------------------- void ProgramSet::setGpuVertexProgram(GpuProgramPtr vsGpuProgram) { - mVSGpuProgram = vsGpuProgram; + mVSGpuProgram = vsGpuProgram; } //----------------------------------------------------------------------------- GpuProgramPtr ProgramSet::getGpuVertexProgram() { - return mVSGpuProgram; + return mVSGpuProgram; } //----------------------------------------------------------------------------- void ProgramSet::setGpuFragmentProgram(GpuProgramPtr psGpuProgram) { - mPSGpuProgram = psGpuProgram; + mPSGpuProgram = psGpuProgram; } //----------------------------------------------------------------------------- GpuProgramPtr ProgramSet::getGpuFragmentProgram() { - return mPSGpuProgram; + return mPSGpuProgram; } } diff --git a/Components/RTShaderSystem/src/OgreShaderProgramWriter.cpp b/Components/RTShaderSystem/src/OgreShaderProgramWriter.cpp index caef74f1846..c2578229242 100644 --- a/Components/RTShaderSystem/src/OgreShaderProgramWriter.cpp +++ b/Components/RTShaderSystem/src/OgreShaderProgramWriter.cpp @@ -33,42 +33,42 @@ namespace RTShader { //----------------------------------------------------------------------- void ProgramWriter::writeProgramTitle(std::ostream& os, Program* program) { - os << "//-----------------------------------------------------------------------------" << std::endl; - os << "// Program Type: "; - switch(program->getType()) - { - case GPT_VERTEX_PROGRAM: - os << "Vertex shader"; - break; - case GPT_FRAGMENT_PROGRAM: - os << "Fragment shader"; - break; - case GPT_GEOMETRY_PROGRAM: - os << "Geometry shader"; - break; - default: - break; - } - os << std::endl; - os << "// Language: " << getTargetLanguage() << std::endl; - os << "// Created by Ogre RT Shader Generator. All rights reserved." << std::endl; - os << "//-----------------------------------------------------------------------------" << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; + os << "// Program Type: "; + switch(program->getType()) + { + case GPT_VERTEX_PROGRAM: + os << "Vertex shader"; + break; + case GPT_FRAGMENT_PROGRAM: + os << "Fragment shader"; + break; + case GPT_GEOMETRY_PROGRAM: + os << "Geometry shader"; + break; + default: + break; + } + os << std::endl; + os << "// Language: " << getTargetLanguage() << std::endl; + os << "// Created by Ogre RT Shader Generator. All rights reserved." << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; } //----------------------------------------------------------------------- void ProgramWriter::writeUniformParametersTitle(std::ostream& os, Program* program) { - os << "//-----------------------------------------------------------------------------" << std::endl; - os << "// GLOBAL PARAMETERS" << std::endl; - os << "//-----------------------------------------------------------------------------" << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; + os << "// GLOBAL PARAMETERS" << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; } //----------------------------------------------------------------------- void ProgramWriter::writeFunctionTitle(std::ostream& os, Function* function) { - os << "//-----------------------------------------------------------------------------" << std::endl; - os << "// Function Name: " << function->getName() << std::endl; - os << "// Function Desc: " << function->getDescription() << std::endl; - os << "//-----------------------------------------------------------------------------" << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; + os << "// Function Name: " << function->getName() << std::endl; + os << "// Function Desc: " << function->getDescription() << std::endl; + os << "//-----------------------------------------------------------------------------" << std::endl; } } diff --git a/Components/RTShaderSystem/src/OgreShaderProgramWriterManager.cpp b/Components/RTShaderSystem/src/OgreShaderProgramWriterManager.cpp index 6e720878174..97933099144 100644 --- a/Components/RTShaderSystem/src/OgreShaderProgramWriterManager.cpp +++ b/Components/RTShaderSystem/src/OgreShaderProgramWriterManager.cpp @@ -39,13 +39,13 @@ namespace RTShader { //----------------------------------------------------------------------- ProgramWriterManager* ProgramWriterManager::getSingletonPtr(void) { - return msSingleton; + return msSingleton; } //----------------------------------------------------------------------- ProgramWriterManager& ProgramWriterManager::getSingleton(void) { - assert( msSingleton ); - return ( *msSingleton ); + assert( msSingleton ); + return ( *msSingleton ); } //----------------------------------------------------------------------- ProgramWriterManager::ProgramWriterManager() @@ -60,39 +60,39 @@ ProgramWriterManager::~ProgramWriterManager() //----------------------------------------------------------------------- void ProgramWriterManager::addFactory(ProgramWriterFactory* factory) { - mFactories[factory->getTargetLanguage()] = factory; + mFactories[factory->getTargetLanguage()] = factory; } //----------------------------------------------------------------------- void ProgramWriterManager::removeFactory(ProgramWriterFactory* factory) { - // Remove only if equal to registered one, since it might overridden - // by other plugins - FactoryMap::iterator it = mFactories.find(factory->getTargetLanguage()); - if (it != mFactories.end() && it->second == factory) - { - mFactories.erase(it); - } + // Remove only if equal to registered one, since it might overridden + // by other plugins + FactoryMap::iterator it = mFactories.find(factory->getTargetLanguage()); + if (it != mFactories.end() && it->second == factory) + { + mFactories.erase(it); + } } //----------------------------------------------------------------------- bool ProgramWriterManager::isLanguageSupported(const String& lang) { - FactoryMap::iterator i = mFactories.find(lang); + FactoryMap::iterator i = mFactories.find(lang); - return i != mFactories.end(); + return i != mFactories.end(); } //----------------------------------------------------------------------- ProgramWriter* ProgramWriterManager::createProgramWriter( const String& language) { - FactoryMap::iterator it = mFactories.find(language); + FactoryMap::iterator it = mFactories.find(language); - if (it != mFactories.end()) - { - return (it->second)->create(); - } - - OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, - "Could not create ShaderProgramWriter unknown language ", - "ShaderProgramWriterManager::createProgramWriter" ); + if (it != mFactories.end()) + { + return (it->second)->create(); + } + + OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, + "Could not create ShaderProgramWriter unknown language ", + "ShaderProgramWriterManager::createProgramWriter" ); } } diff --git a/Components/RTShaderSystem/src/OgreShaderRenderState.cpp b/Components/RTShaderSystem/src/OgreShaderRenderState.cpp index 19b1123424d..e7d91b57aed 100644 --- a/Components/RTShaderSystem/src/OgreShaderRenderState.cpp +++ b/Components/RTShaderSystem/src/OgreShaderRenderState.cpp @@ -42,277 +42,277 @@ namespace RTShader { //----------------------------------------------------------------------- RenderState::RenderState() { - mLightCountAutoUpdate = true; - mLightCount[0] = 0; - mLightCount[1] = 0; - mLightCount[2] = 0; + mLightCountAutoUpdate = true; + mLightCount[0] = 0; + mLightCount[1] = 0; + mLightCount[2] = 0; } //----------------------------------------------------------------------- RenderState::~RenderState() { - reset(); + reset(); } //----------------------------------------------------------------------- void RenderState::reset() { - for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) - { - ShaderGenerator::getSingleton().destroySubRenderState(*it); - } - mSubRenderStateList.clear(); + for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) + { + ShaderGenerator::getSingleton().destroySubRenderState(*it); + } + mSubRenderStateList.clear(); } //----------------------------------------------------------------------- void RenderState::setLightCount(const int lightCount[3]) { - mLightCount[0] = lightCount[0]; - mLightCount[1] = lightCount[1]; - mLightCount[2] = lightCount[2]; + mLightCount[0] = lightCount[0]; + mLightCount[1] = lightCount[1]; + mLightCount[2] = lightCount[2]; } //----------------------------------------------------------------------- void RenderState::getLightCount(int lightCount[3]) const { - lightCount[0] = mLightCount[0]; - lightCount[1] = mLightCount[1]; - lightCount[2] = mLightCount[2]; + lightCount[0] = mLightCount[0]; + lightCount[1] = mLightCount[1]; + lightCount[2] = mLightCount[2]; } //----------------------------------------------------------------------- void RenderState::addTemplateSubRenderState(SubRenderState* subRenderState) { - bool addSubRenderState = true; - - // Go over the current sub render state. - for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) - { - // Case the same instance already exists -> do not add to list. - if (*it == subRenderState) - { - addSubRenderState = false; - break; - } - - // Case it is different sub render state instance with the same type, use the new sub render state - // instead of the previous sub render state. This scenario is usually caused by material inheritance, so we use the derived material sub render state - // and destroy the base sub render state. - else if ((*it)->getType() == subRenderState->getType()) - { - removeTemplateSubRenderState(*it); - break; - } - } - - // Add only if this sub render state instance is not on the list. - if (addSubRenderState) - { - mSubRenderStateList.push_back(subRenderState); - } + bool addSubRenderState = true; + + // Go over the current sub render state. + for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) + { + // Case the same instance already exists -> do not add to list. + if (*it == subRenderState) + { + addSubRenderState = false; + break; + } + + // Case it is different sub render state instance with the same type, use the new sub render state + // instead of the previous sub render state. This scenario is usually caused by material inheritance, so we use the derived material sub render state + // and destroy the base sub render state. + else if ((*it)->getType() == subRenderState->getType()) + { + removeTemplateSubRenderState(*it); + break; + } + } + + // Add only if this sub render state instance is not on the list. + if (addSubRenderState) + { + mSubRenderStateList.push_back(subRenderState); + } } //----------------------------------------------------------------------- void RenderState::removeTemplateSubRenderState(SubRenderState* subRenderState) { - for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) - { - if ((*it) == subRenderState) - { - ShaderGenerator::getSingleton().destroySubRenderState(*it); - mSubRenderStateList.erase(it); - break; - } - } + for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) + { + if ((*it) == subRenderState) + { + ShaderGenerator::getSingleton().destroySubRenderState(*it); + mSubRenderStateList.erase(it); + break; + } + } } //----------------------------------------------------------------------- TargetRenderState::TargetRenderState() -{ - mProgramSet = NULL; - mSubRenderStateSortValid = false; +{ + mProgramSet = NULL; + mSubRenderStateSortValid = false; } //----------------------------------------------------------------------- TargetRenderState::~TargetRenderState() { - destroyProgramSet(); + destroyProgramSet(); } //----------------------------------------------------------------------- void TargetRenderState::addSubRenderStateInstance(SubRenderState* subRenderState) { - mSubRenderStateList.push_back(subRenderState); - mSubRenderStateSortValid = false; + mSubRenderStateList.push_back(subRenderState); + mSubRenderStateSortValid = false; } //----------------------------------------------------------------------- void TargetRenderState::removeSubRenderStateInstance(SubRenderState* subRenderState) { - for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) - { - if ((*it) == subRenderState) - { - ShaderGenerator::getSingleton().destroySubRenderState(*it); - mSubRenderStateList.erase(it); - break; - } - } + for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) + { + if ((*it) == subRenderState) + { + ShaderGenerator::getSingleton().destroySubRenderState(*it); + mSubRenderStateList.erase(it); + break; + } + } } //----------------------------------------------------------------------- bool TargetRenderState::createCpuPrograms() { - sortSubRenderStates(); + sortSubRenderStates(); - ProgramSet* programSet = createProgramSet(); - Program* vsProgram = ProgramManager::getSingleton().createCpuProgram(GPT_VERTEX_PROGRAM); - Program* psProgram = ProgramManager::getSingleton().createCpuProgram(GPT_FRAGMENT_PROGRAM); - RTShader::Function* vsMainFunc = NULL; - RTShader::Function* psMainFunc = NULL; + ProgramSet* programSet = createProgramSet(); + Program* vsProgram = ProgramManager::getSingleton().createCpuProgram(GPT_VERTEX_PROGRAM); + Program* psProgram = ProgramManager::getSingleton().createCpuProgram(GPT_FRAGMENT_PROGRAM); + RTShader::Function* vsMainFunc = NULL; + RTShader::Function* psMainFunc = NULL; - programSet->setCpuVertexProgram(vsProgram); - programSet->setCpuFragmentProgram(psProgram); + programSet->setCpuVertexProgram(vsProgram); + programSet->setCpuFragmentProgram(psProgram); - // Create entry point functions. - vsMainFunc = vsProgram->createFunction("main", "Vertex Program Entry point", Function::FFT_VS_MAIN); - vsProgram->setEntryPointFunction(vsMainFunc); + // Create entry point functions. + vsMainFunc = vsProgram->createFunction("main", "Vertex Program Entry point", Function::FFT_VS_MAIN); + vsProgram->setEntryPointFunction(vsMainFunc); - psMainFunc = psProgram->createFunction("main", "Pixel Program Entry point", Function::FFT_PS_MAIN); - psProgram->setEntryPointFunction(psMainFunc); + psMainFunc = psProgram->createFunction("main", "Pixel Program Entry point", Function::FFT_PS_MAIN); + psProgram->setEntryPointFunction(psMainFunc); - for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) - { - SubRenderState* srcSubRenderState = *it; + for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) + { + SubRenderState* srcSubRenderState = *it; - if (false == srcSubRenderState->createCpuSubPrograms(programSet)) - { - LogManager::getSingleton().stream() << "RTShader::TargetRenderState : Could not generate sub render program of type: " << srcSubRenderState->getType(); - return false; - } - } + if (false == srcSubRenderState->createCpuSubPrograms(programSet)) + { + LogManager::getSingleton().stream() << "RTShader::TargetRenderState : Could not generate sub render program of type: " << srcSubRenderState->getType(); + return false; + } + } - return true; + return true; } //----------------------------------------------------------------------- -ProgramSet* TargetRenderState::createProgramSet() +ProgramSet* TargetRenderState::createProgramSet() { - destroyProgramSet(); + destroyProgramSet(); - mProgramSet = OGRE_NEW ProgramSet; + mProgramSet = OGRE_NEW ProgramSet; - return mProgramSet; + return mProgramSet; } //----------------------------------------------------------------------- void TargetRenderState::destroyProgramSet() { - if (mProgramSet != NULL) - { - OGRE_DELETE mProgramSet; - mProgramSet = NULL; - } + if (mProgramSet != NULL) + { + OGRE_DELETE mProgramSet; + mProgramSet = NULL; + } } //----------------------------------------------------------------------- void TargetRenderState::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, - const LightList* pLightList) + const LightList* pLightList) { - for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) - { - SubRenderState* curSubRenderState = *it; + for (SubRenderStateListIterator it=mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) + { + SubRenderState* curSubRenderState = *it; - curSubRenderState->updateGpuProgramsParams(rend, pass, source, pLightList); - } + curSubRenderState->updateGpuProgramsParams(rend, pass, source, pLightList); + } } //----------------------------------------------------------------------- void TargetRenderState::link(const RenderState& rhs, Pass* srcPass, Pass* dstPass) -{ - SubRenderStateList customSubRenderStates; - - // Sort current render states. - sortSubRenderStates(); - - // Insert all custom sub render states. (I.E Not FFP sub render states). - const SubRenderStateList& subRenderStateList = rhs.getTemplateSubRenderStateList(); - - for (SubRenderStateListConstIterator itSrc=subRenderStateList.begin(); itSrc != subRenderStateList.end(); ++itSrc) - { - const SubRenderState* srcSubRenderState = *itSrc; - bool isCustomSubRenderState = true; - - if (srcSubRenderState->getExecutionOrder() == FFP_TRANSFORM || - srcSubRenderState->getExecutionOrder() == FFP_COLOUR || - srcSubRenderState->getExecutionOrder() == FFP_LIGHTING || - srcSubRenderState->getExecutionOrder() == FFP_TEXTURING || - srcSubRenderState->getExecutionOrder() == FFP_FOG) - { - isCustomSubRenderState = false; - } - - - // Case it is a custom sub render state. - if (isCustomSubRenderState) - { - bool subStateTypeExists = false; - - // Check if this type of sub render state already exists. - for (SubRenderStateListConstIterator itDst=mSubRenderStateList.begin(); itDst != mSubRenderStateList.end(); ++itDst) - { - if ((*itDst)->getType() == srcSubRenderState->getType()) - { - subStateTypeExists = true; - break; - } - } - - // Case custom sub render state not exits -> add it to custom list. - if (subStateTypeExists == false) - { - SubRenderState* newSubRenderState = NULL; - - newSubRenderState = ShaderGenerator::getSingleton().createSubRenderState(srcSubRenderState->getType()); - *newSubRenderState = *srcSubRenderState; - customSubRenderStates.push_back(newSubRenderState); - } - } - } - - // Merge the local custom sub render states. - for (SubRenderStateListIterator itSrc=customSubRenderStates.begin(); itSrc != customSubRenderStates.end(); ++itSrc) - { - SubRenderState* customSubRenderState = *itSrc; - - if (customSubRenderState->preAddToRenderState(this, srcPass, dstPass)) - { - addSubRenderStateInstance(customSubRenderState); - } - else - { - ShaderGenerator::getSingleton().destroySubRenderState(customSubRenderState); - } - } +{ + SubRenderStateList customSubRenderStates; + + // Sort current render states. + sortSubRenderStates(); + + // Insert all custom sub render states. (I.E Not FFP sub render states). + const SubRenderStateList& subRenderStateList = rhs.getTemplateSubRenderStateList(); + + for (SubRenderStateListConstIterator itSrc=subRenderStateList.begin(); itSrc != subRenderStateList.end(); ++itSrc) + { + const SubRenderState* srcSubRenderState = *itSrc; + bool isCustomSubRenderState = true; + + if (srcSubRenderState->getExecutionOrder() == FFP_TRANSFORM || + srcSubRenderState->getExecutionOrder() == FFP_COLOUR || + srcSubRenderState->getExecutionOrder() == FFP_LIGHTING || + srcSubRenderState->getExecutionOrder() == FFP_TEXTURING || + srcSubRenderState->getExecutionOrder() == FFP_FOG) + { + isCustomSubRenderState = false; + } + + + // Case it is a custom sub render state. + if (isCustomSubRenderState) + { + bool subStateTypeExists = false; + + // Check if this type of sub render state already exists. + for (SubRenderStateListConstIterator itDst=mSubRenderStateList.begin(); itDst != mSubRenderStateList.end(); ++itDst) + { + if ((*itDst)->getType() == srcSubRenderState->getType()) + { + subStateTypeExists = true; + break; + } + } + + // Case custom sub render state not exits -> add it to custom list. + if (subStateTypeExists == false) + { + SubRenderState* newSubRenderState = NULL; + + newSubRenderState = ShaderGenerator::getSingleton().createSubRenderState(srcSubRenderState->getType()); + *newSubRenderState = *srcSubRenderState; + customSubRenderStates.push_back(newSubRenderState); + } + } + } + + // Merge the local custom sub render states. + for (SubRenderStateListIterator itSrc=customSubRenderStates.begin(); itSrc != customSubRenderStates.end(); ++itSrc) + { + SubRenderState* customSubRenderState = *itSrc; + + if (customSubRenderState->preAddToRenderState(this, srcPass, dstPass)) + { + addSubRenderStateInstance(customSubRenderState); + } + else + { + ShaderGenerator::getSingleton().destroySubRenderState(customSubRenderState); + } + } } namespace { - struct CmpSubRenderStates { - bool operator()(const SubRenderState* a, const SubRenderState* b) const - { - return a->getExecutionOrder() < b->getExecutionOrder(); - } - }; + struct CmpSubRenderStates { + bool operator()(const SubRenderState* a, const SubRenderState* b) const + { + return a->getExecutionOrder() < b->getExecutionOrder(); + } + }; } //----------------------------------------------------------------------- void TargetRenderState::sortSubRenderStates() { - if (mSubRenderStateSortValid == false) - { - std::sort(mSubRenderStateList.begin(), mSubRenderStateList.end(), CmpSubRenderStates()); - mSubRenderStateSortValid = true; - } + if (mSubRenderStateSortValid == false) + { + std::sort(mSubRenderStateList.begin(), mSubRenderStateList.end(), CmpSubRenderStates()); + mSubRenderStateSortValid = true; + } } } diff --git a/Components/RTShaderSystem/src/OgreShaderScriptTranslator.cpp b/Components/RTShaderSystem/src/OgreShaderScriptTranslator.cpp index a28853c7709..67e6750101c 100644 --- a/Components/RTShaderSystem/src/OgreShaderScriptTranslator.cpp +++ b/Components/RTShaderSystem/src/OgreShaderScriptTranslator.cpp @@ -35,217 +35,217 @@ namespace RTShader { //----------------------------------------------------------------------------- SGScriptTranslator::SGScriptTranslator() : - mGeneratedRenderState(NULL) + mGeneratedRenderState(NULL) { } //----------------------------------------------------------------------------- void SGScriptTranslator::translate(ScriptCompiler* compiler, const AbstractNodePtr &node) { - ObjectAbstractNode* obj = reinterpret_cast(node.get()); - ObjectAbstractNode* parent = reinterpret_cast(obj->parent); - - // Translate section within a pass context. - if (parent->cls == "pass") - { - translatePass(compiler, node); - } - if (parent->cls == "texture_unit") - { - translateTextureUnit(compiler, node); - } + ObjectAbstractNode* obj = reinterpret_cast(node.get()); + ObjectAbstractNode* parent = reinterpret_cast(obj->parent); + + // Translate section within a pass context. + if (parent->cls == "pass") + { + translatePass(compiler, node); + } + if (parent->cls == "texture_unit") + { + translateTextureUnit(compiler, node); + } } //----------------------------------------------------------------------------- SubRenderState* SGScriptTranslator::getGeneratedSubRenderState(const String& typeName) { - //check if we are in the middle of parsing - if (mGeneratedRenderState) - { - /** Get the list of the template sub render states composing this render state. */ - const SubRenderStateList& rsList = - mGeneratedRenderState->getTemplateSubRenderStateList(); - - SubRenderStateList::const_iterator it = rsList.begin(); - SubRenderStateList::const_iterator itEnd = rsList.end(); - for(; it != itEnd; ++it) - { - if ((*it)->getType() == typeName) - return *it; - } - } - return NULL; + //check if we are in the middle of parsing + if (mGeneratedRenderState) + { + /** Get the list of the template sub render states composing this render state. */ + const SubRenderStateList& rsList = + mGeneratedRenderState->getTemplateSubRenderStateList(); + + SubRenderStateList::const_iterator it = rsList.begin(); + SubRenderStateList::const_iterator itEnd = rsList.end(); + for(; it != itEnd; ++it) + { + if ((*it)->getType() == typeName) + return *it; + } + } + return NULL; } - + //----------------------------------------------------------------------------- /* note: we can know the texture unit index by getting parent then finding it in the list of children */ void SGScriptTranslator::translateTextureUnit(ScriptCompiler* compiler, const AbstractNodePtr &node) { - ObjectAbstractNode *obj = reinterpret_cast(node.get()); - TextureUnitState* texState = any_cast(obj->parent->context); - Pass* pass = texState->getParent(); - Technique* technique = pass->getParent(); - Material* material = technique->getParent(); - ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr(); - String dstTechniqueSchemeName = obj->name; - bool techniqueCreated; - - // Make sure the scheme name is valid - use default if none exists. - if (dstTechniqueSchemeName.empty()) - dstTechniqueSchemeName = ShaderGenerator::DEFAULT_SCHEME_NAME; - - - //check if technique already created - techniqueCreated = shaderGenerator->hasShaderBasedTechnique(material->getName(), - material->getGroup(), - technique->getSchemeName(), - dstTechniqueSchemeName); - - if (techniqueCreated == false) - { - // Create the shader based technique. - techniqueCreated = shaderGenerator->createShaderBasedTechnique(material->getName(), - material->getGroup(), - technique->getSchemeName(), - dstTechniqueSchemeName, - shaderGenerator->getCreateShaderOverProgrammablePass()); - } - - - - // Case technique successfully created. - if (techniqueCreated) - { - //Attempt to get the render state which might have been created by the pass parsing - mGeneratedRenderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, - material->getName(), material->getGroup(), pass->getIndex()); - - // Go over all the render state properties. - for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) - { - if((*i)->type == ANT_PROPERTY) - { - PropertyAbstractNode *prop = reinterpret_cast((*i).get()); - SubRenderState* subRenderState = ShaderGenerator::getSingleton().createSubRenderState(compiler, prop, texState, this); - - if (subRenderState) - { - addSubRenderState(subRenderState, dstTechniqueSchemeName, material->getName(), - material->getGroup(), pass->getIndex()); - } - } - else - { - processNode(compiler, *i); - } - } - - mGeneratedRenderState = NULL; - } + ObjectAbstractNode *obj = reinterpret_cast(node.get()); + TextureUnitState* texState = any_cast(obj->parent->context); + Pass* pass = texState->getParent(); + Technique* technique = pass->getParent(); + Material* material = technique->getParent(); + ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr(); + String dstTechniqueSchemeName = obj->name; + bool techniqueCreated; + + // Make sure the scheme name is valid - use default if none exists. + if (dstTechniqueSchemeName.empty()) + dstTechniqueSchemeName = ShaderGenerator::DEFAULT_SCHEME_NAME; + + + //check if technique already created + techniqueCreated = shaderGenerator->hasShaderBasedTechnique(material->getName(), + material->getGroup(), + technique->getSchemeName(), + dstTechniqueSchemeName); + + if (techniqueCreated == false) + { + // Create the shader based technique. + techniqueCreated = shaderGenerator->createShaderBasedTechnique(material->getName(), + material->getGroup(), + technique->getSchemeName(), + dstTechniqueSchemeName, + shaderGenerator->getCreateShaderOverProgrammablePass()); + } + + + + // Case technique successfully created. + if (techniqueCreated) + { + //Attempt to get the render state which might have been created by the pass parsing + mGeneratedRenderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, + material->getName(), material->getGroup(), pass->getIndex()); + + // Go over all the render state properties. + for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) + { + if((*i)->type == ANT_PROPERTY) + { + PropertyAbstractNode *prop = reinterpret_cast((*i).get()); + SubRenderState* subRenderState = ShaderGenerator::getSingleton().createSubRenderState(compiler, prop, texState, this); + + if (subRenderState) + { + addSubRenderState(subRenderState, dstTechniqueSchemeName, material->getName(), + material->getGroup(), pass->getIndex()); + } + } + else + { + processNode(compiler, *i); + } + } + + mGeneratedRenderState = NULL; + } } //----------------------------------------------------------------------------- void SGScriptTranslator::translatePass(ScriptCompiler* compiler, const AbstractNodePtr &node) { - ObjectAbstractNode *obj = reinterpret_cast(node.get()); - Pass* pass = any_cast(obj->parent->context); - Technique* technique = pass->getParent(); - Material* material = technique->getParent(); - ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr(); - String dstTechniqueSchemeName = obj->name; - bool techniqueCreated; - - // Make sure the scheme name is valid - use default if none exists. - if (dstTechniqueSchemeName.empty()) - dstTechniqueSchemeName = ShaderGenerator::DEFAULT_SCHEME_NAME; - - - // Create the shader based technique. - techniqueCreated = shaderGenerator->createShaderBasedTechnique(material->getName(), - material->getGroup(), - technique->getSchemeName(), - dstTechniqueSchemeName, - shaderGenerator->getCreateShaderOverProgrammablePass()); - - - // Case technique successfully created. - if (techniqueCreated) - { - // Go over all the render state properties. - for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) - { - if((*i)->type == ANT_PROPERTY) - { - PropertyAbstractNode *prop = reinterpret_cast((*i).get()); - - // Handle light count property. - if (prop->name == "light_count") - { - if (prop->values.size() != 3) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - } - else - { - int lightCount[3]; - - if (false == SGScriptTranslator::getInts(prop->values.begin(), prop->values.end(), lightCount, 3)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - } - else - { - shaderGenerator->createScheme(dstTechniqueSchemeName); - RenderState* renderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, - material->getName(), material->getGroup(), pass->getIndex()); - - renderState->setLightCount(lightCount); - renderState->setLightCountAutoUpdate(false); - } - } - } - - // Handle the rest of the custom properties. - else - { - SubRenderState* subRenderState = ShaderGenerator::getSingleton().createSubRenderState(compiler, prop, pass, this); - if (subRenderState) - { - addSubRenderState(subRenderState, dstTechniqueSchemeName, material->getName(), material->getGroup(), pass->getIndex()); - } - } - } - else - { - processNode(compiler, *i); - } - } - - mGeneratedRenderState = NULL; - } + ObjectAbstractNode *obj = reinterpret_cast(node.get()); + Pass* pass = any_cast(obj->parent->context); + Technique* technique = pass->getParent(); + Material* material = technique->getParent(); + ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr(); + String dstTechniqueSchemeName = obj->name; + bool techniqueCreated; + + // Make sure the scheme name is valid - use default if none exists. + if (dstTechniqueSchemeName.empty()) + dstTechniqueSchemeName = ShaderGenerator::DEFAULT_SCHEME_NAME; + + + // Create the shader based technique. + techniqueCreated = shaderGenerator->createShaderBasedTechnique(material->getName(), + material->getGroup(), + technique->getSchemeName(), + dstTechniqueSchemeName, + shaderGenerator->getCreateShaderOverProgrammablePass()); + + + // Case technique successfully created. + if (techniqueCreated) + { + // Go over all the render state properties. + for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) + { + if((*i)->type == ANT_PROPERTY) + { + PropertyAbstractNode *prop = reinterpret_cast((*i).get()); + + // Handle light count property. + if (prop->name == "light_count") + { + if (prop->values.size() != 3) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + } + else + { + int lightCount[3]; + + if (false == SGScriptTranslator::getInts(prop->values.begin(), prop->values.end(), lightCount, 3)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + } + else + { + shaderGenerator->createScheme(dstTechniqueSchemeName); + RenderState* renderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, + material->getName(), material->getGroup(), pass->getIndex()); + + renderState->setLightCount(lightCount); + renderState->setLightCountAutoUpdate(false); + } + } + } + + // Handle the rest of the custom properties. + else + { + SubRenderState* subRenderState = ShaderGenerator::getSingleton().createSubRenderState(compiler, prop, pass, this); + if (subRenderState) + { + addSubRenderState(subRenderState, dstTechniqueSchemeName, material->getName(), material->getGroup(), pass->getIndex()); + } + } + } + else + { + processNode(compiler, *i); + } + } + + mGeneratedRenderState = NULL; + } } //----------------------------------------------------------------------------- void SGScriptTranslator::addSubRenderState(SubRenderState* newSubRenderState, - const String& dstTechniqueSchemeName, const String& materialName, const String& groupName, unsigned short passIndex) + const String& dstTechniqueSchemeName, const String& materialName, const String& groupName, unsigned short passIndex) { - assert(newSubRenderState); - - //check if a different sub render state of the same type already exists - ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr(); - - //create a new scheme if needed - shaderGenerator->createScheme(dstTechniqueSchemeName); - - //update the active render state - mGeneratedRenderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, materialName, groupName, passIndex); - - //add the new sub render state - mGeneratedRenderState->addTemplateSubRenderState(newSubRenderState); + assert(newSubRenderState); + + //check if a different sub render state of the same type already exists + ShaderGenerator* shaderGenerator = ShaderGenerator::getSingletonPtr(); + + //create a new scheme if needed + shaderGenerator->createScheme(dstTechniqueSchemeName); + + //update the active render state + mGeneratedRenderState = shaderGenerator->getRenderState(dstTechniqueSchemeName, materialName, groupName, passIndex); + + //add the new sub render state + mGeneratedRenderState->addTemplateSubRenderState(newSubRenderState); } } diff --git a/Components/RTShaderSystem/src/OgreShaderSubRenderState.cpp b/Components/RTShaderSystem/src/OgreShaderSubRenderState.cpp index c154231bfab..958cb7a52e5 100644 --- a/Components/RTShaderSystem/src/OgreShaderSubRenderState.cpp +++ b/Components/RTShaderSystem/src/OgreShaderSubRenderState.cpp @@ -36,158 +36,158 @@ namespace RTShader { //----------------------------------------------------------------------- SubRenderState::SubRenderState() { - + } //----------------------------------------------------------------------- SubRenderState::~SubRenderState() { - if (mOtherAccessor.isNull() == false) - { - mOtherAccessor->removeSubRenderStateInstance(this); - } + if (mOtherAccessor.isNull() == false) + { + mOtherAccessor->removeSubRenderStateInstance(this); + } } //----------------------------------------------------------------------- SubRenderStateFactory::~SubRenderStateFactory() { - assert(mSubRenderStateList.empty() && - "SubRenderStateFactory::~SubRenderStateFactory -> Sub render states still exists !!!"); + assert(mSubRenderStateList.empty() && + "SubRenderStateFactory::~SubRenderStateFactory -> Sub render states still exists !!!"); } //----------------------------------------------------------------------- -SubRenderState* SubRenderStateFactory::createInstance() +SubRenderState* SubRenderStateFactory::createInstance() { - SubRenderState* subRenderState = createInstanceImpl(); + SubRenderState* subRenderState = createInstanceImpl(); - mSubRenderStateList.insert(subRenderState); + mSubRenderStateList.insert(subRenderState); - return subRenderState; + return subRenderState; } //----------------------------------------------------------------------- -SubRenderState* SubRenderStateFactory::createOrRetrieveInstance(SGScriptTranslator* translator) +SubRenderState* SubRenderStateFactory::createOrRetrieveInstance(SGScriptTranslator* translator) { - //check if we already create a SRS - SubRenderState* subRenderState = translator->getGeneratedSubRenderState(getType()); - if (subRenderState == NULL) - { - //create a new sub render state - subRenderState = SubRenderStateFactory::createInstance(); - } - return subRenderState; + //check if we already create a SRS + SubRenderState* subRenderState = translator->getGeneratedSubRenderState(getType()); + if (subRenderState == NULL) + { + //create a new sub render state + subRenderState = SubRenderStateFactory::createInstance(); + } + return subRenderState; } //----------------------------------------------------------------------- void SubRenderStateFactory::destroyInstance(SubRenderState* subRenderState) { - SubRenderStateSetIterator it = mSubRenderStateList.find(subRenderState); + SubRenderStateSetIterator it = mSubRenderStateList.find(subRenderState); - if (it != mSubRenderStateList.end()) - { - OGRE_DELETE *it; - mSubRenderStateList.erase(it); - } + if (it != mSubRenderStateList.end()) + { + OGRE_DELETE *it; + mSubRenderStateList.erase(it); + } } //----------------------------------------------------------------------- void SubRenderStateFactory::destroyAllInstances() { - SubRenderStateSetIterator it; + SubRenderStateSetIterator it; - for (it = mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) - { - OGRE_DELETE *it; - } - mSubRenderStateList.clear(); + for (it = mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it) + { + OGRE_DELETE *it; + } + mSubRenderStateList.clear(); } //----------------------------------------------------------------------- SubRenderState& SubRenderState::operator=(const SubRenderState& rhs) { - if (getType() != rhs.getType()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Can not copy sub render states of different types !!", - "SubRenderState::operator="); - } + if (getType() != rhs.getType()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Can not copy sub render states of different types !!", + "SubRenderState::operator="); + } - copyFrom(rhs); + copyFrom(rhs); - SubRenderStateAccessorPtr rhsAccessor = rhs.getAccessor(); + SubRenderStateAccessorPtr rhsAccessor = rhs.getAccessor(); - rhsAccessor->addSubRenderStateInstance(this); - mOtherAccessor = rhsAccessor; + rhsAccessor->addSubRenderStateInstance(this); + mOtherAccessor = rhsAccessor; - return *this; + return *this; } //----------------------------------------------------------------------- bool SubRenderState::createCpuSubPrograms(ProgramSet* programSet) { - bool result; + bool result; - // Resolve parameters. - result = resolveParameters(programSet); - if (false == result) - return false; + // Resolve parameters. + result = resolveParameters(programSet); + if (false == result) + return false; - // Resolve dependencies. - result = resolveDependencies(programSet); - if (false == result) - return false; + // Resolve dependencies. + result = resolveDependencies(programSet); + if (false == result) + return false; - // Add function invocations. - result = addFunctionInvocations(programSet); - if (false == result) - return false; + // Add function invocations. + result = addFunctionInvocations(programSet); + if (false == result) + return false; - return true; + return true; } //----------------------------------------------------------------------- bool SubRenderState::resolveParameters(ProgramSet* programSet) { - return true; + return true; } //----------------------------------------------------------------------- bool SubRenderState::resolveDependencies(ProgramSet* programSet) { - return true; + return true; } //----------------------------------------------------------------------- bool SubRenderState::addFunctionInvocations( ProgramSet* programSet ) { - return true; + return true; } //----------------------------------------------------------------------- SubRenderStateAccessorPtr SubRenderState::getAccessor() { - if (mThisAccessor.isNull()) - { - SubRenderStateAccessor* accessor = OGRE_NEW_T(SubRenderStateAccessor, MEMCATEGORY_GENERAL)(this); - - mThisAccessor.bind(accessor, SPFM_DELETE_T); - } + if (mThisAccessor.isNull()) + { + SubRenderStateAccessor* accessor = OGRE_NEW_T(SubRenderStateAccessor, MEMCATEGORY_GENERAL)(this); + + mThisAccessor.bind(accessor, SPFM_DELETE_T); + } - return mThisAccessor; + return mThisAccessor; } //----------------------------------------------------------------------- SubRenderStateAccessorPtr SubRenderState::getAccessor() const { - if (mThisAccessor.isNull()) - { - SubRenderStateAccessor* accessor = OGRE_NEW_T(SubRenderStateAccessor, MEMCATEGORY_GENERAL)(this); + if (mThisAccessor.isNull()) + { + SubRenderStateAccessor* accessor = OGRE_NEW_T(SubRenderStateAccessor, MEMCATEGORY_GENERAL)(this); - mThisAccessor.bind(accessor, SPFM_DELETE_T); - } + mThisAccessor.bind(accessor, SPFM_DELETE_T); + } - return mThisAccessor; + return mThisAccessor; } diff --git a/Components/Terrain/include/OgreTerrain.h b/Components/Terrain/include/OgreTerrain.h index 79500ed4bd8..0b902df9740 100644 --- a/Components/Terrain/include/OgreTerrain.h +++ b/Components/Terrain/include/OgreTerrain.h @@ -41,1614 +41,1614 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Terrain - * Some details on the terrain component - * @{ - */ - - /** The main containing class for a chunk of terrain. - @par - Terrain can be edited and stored. - The data format for this in a file is:
      - TerrainData (Identifier 'TERR')\n - [Version 1] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      NameTypeDescription
      Terrain orientationuint8The orientation of the terrain; XZ = 0, XY = 1, YZ = 2
      Terrain sizeuint16The number of vertices along one side of the terrain
      Terrain world sizeRealThe world size of one side of the terrain
      Max batch sizeuint16The maximum batch size in vertices along one side
      Min batch sizeuint16The minimum batch size in vertices along one side
      PositionVector3The location of the centre of the terrain
      Height datafloat[size*size]List of floating point heights
      LayerDeclarationLayerDeclaration*The layer declaration for this terrain (see below)
      Layer countuint8The number of layers in this terrain
      LayerInstance listLayerInstance*A number of LayerInstance definitions based on layer count (see below)
      Layer blend map sizeuint16The size of the layer blend maps as stored in this file
      Packed blend texture datauint8*layerCount-1 sets of blend texture data interleaved as either RGB or RGBA - depending on layer count
      Optional derived map dataTerrainDerivedMap list0 or more sets of map data derived from the original terrain
      Delta datafloat[size*size]At each vertex, delta information for the LOD at which this vertex disappears
      Quadtree delta datafloat[quadtrees*lods]At each quadtree node, for each lod a record of the max delta value in the region
      - TerrainLayerDeclaration (Identifier 'TDCL')\n - [Version 1] - - - - - - - - - - - - - - - - - - - - - - - - - - -
      NameTypeDescription
      TerrainLayerSampler Countuint8Number of samplers in this declaration
      TerrainLayerSampler ListTerrainLayerSampler*List of TerrainLayerSampler structures
      Sampler Element Countuint8Number of sampler elements in this declaration
      TerrainLayerSamplerElement ListTerrainLayerSamplerElement*List of TerrainLayerSamplerElement structures
      - TerrainLayerSampler (Identifier 'TSAM')\n - [Version 1] - - - - - - - - - - - - - - - - -
      NameTypeDescription
      AliasStringAlias name of this sampler
      Formatuint8Desired pixel format
      - TerrainLayerSamplerElement (Identifier 'TSEL')\n - [Version 1] - - - - - - - - - - - - - - - - - - - - - - - - - - -
      NameTypeDescription
      Sourceuint8Sampler source index
      Semanticuint8Semantic interpretation of this element
      Element startuint8Start of this element in the sampler
      Element countuint8Number of elements in the sampler used by this entry
      - LayerInstance (Identifier 'TLIN')\n - [Version 1] - - - - - - - - - - - - - - - - -
      NameTypeDescription
      World sizeRealThe world size of this layer (determines UV scaling)
      Texture listString*List of texture names corresponding to the number of samplers in the layer declaration
      - TerrainDerivedData (Identifier 'TDDA')\n - [Version 1] - - - - - - - - - - - - - - - - - - - - - -
      NameTypeDescription
      Derived data type nameStringName of the derived data type ('normalmap', 'lightmap', 'colourmap', 'compositemap')
      Sizeuint16Size of the data along one edge
      Datavaries based on typeThe data
      - */ - class _OgreTerrainExport Terrain : public SceneManager::Listener, - public WorkQueue::RequestHandler, public WorkQueue::ResponseHandler, public TerrainAlloc - { - public: - friend class TerrainLodManager; - - /** Constructor. - @param sm The SceneManager to use. - */ - Terrain(SceneManager* sm); - virtual ~Terrain(); - - static const uint32 TERRAIN_CHUNK_ID; - static const uint16 TERRAIN_CHUNK_VERSION; - static const uint16 TERRAIN_MAX_BATCH_SIZE; - static const uint64 TERRAIN_GENERATE_MATERIAL_INTERVAL_MS; - - static const uint32 TERRAINLAYERDECLARATION_CHUNK_ID; - static const uint16 TERRAINLAYERDECLARATION_CHUNK_VERSION; - static const uint32 TERRAINLAYERSAMPLER_CHUNK_ID; - static const uint16 TERRAINLAYERSAMPLER_CHUNK_VERSION; - static const uint32 TERRAINLAYERSAMPLERELEMENT_CHUNK_ID; - static const uint16 TERRAINLAYERSAMPLERELEMENT_CHUNK_VERSION; - static const uint32 TERRAINLAYERINSTANCE_CHUNK_ID; - static const uint16 TERRAINLAYERINSTANCE_CHUNK_VERSION; - static const uint32 TERRAINDERIVEDDATA_CHUNK_ID; - static const uint16 TERRAINDERIVEDDATA_CHUNK_VERSION; - static const uint32 TERRAINGENERALINFO_CHUNK_ID; - static const uint16 TERRAINGENERALINFO_CHUNK_VERSION; - - static const size_t LOD_MORPH_CUSTOM_PARAM; - - typedef vector::type RealVector; - - /** An instance of a layer, with specific texture names - */ - struct _OgreTerrainExport LayerInstance - { - /// The world size of the texture to be applied in this layer - Real worldSize; - /// List of texture names to import; must match with TerrainLayerDeclaration - StringVector textureNames; - - LayerInstance() - : worldSize(100) {} - }; - typedef vector::type LayerInstanceList; - - /// The alignment of the terrain - enum Alignment - { - /// Terrain is in the X/Z plane - ALIGN_X_Z = 0, - /// Terrain is in the X/Y plane - ALIGN_X_Y = 1, - /// Terrain is in the Y/Z plane - ALIGN_Y_Z = 2 - }; - - /** Structure encapsulating import data that you may use to bootstrap - the terrain without loading from a native data stream. - */ - struct ImportData - { - /// The alignment of the terrain - Alignment terrainAlign; - /// Terrain size (along one edge) in vertices; must be 2^n+1 - uint16 terrainSize; - /** Maximum batch size (along one edge) in vertices; must be 2^n+1 and <= 65 - @remarks - The terrain will be divided into hierarchical tiles, and this is the maximum - size of one tile in vertices (at any LOD). - */ - uint16 maxBatchSize; - /** Minimum batch size (along one edge) in vertices; must be 2^n+1. - @remarks - The terrain will be divided into tiles, and this is the minimum - size of one tile in vertices (at any LOD). Adjacent tiles will be - collected together into one batch to drop LOD levels once they are individually at this minimum, - so setting this value higher means greater batching at the expense - of making adjacent tiles use a common LOD. - Once the entire terrain is collected together into one batch this - effectively sets the minimum LOD. - */ - uint16 minBatchSize; - - /** Position of the terrain. - @remarks - Represents the position of the centre of the terrain. - */ - Vector3 pos; - - /** The world size of the terrain. */ - Real worldSize; - - /** Optional heightmap providing the initial heights for the terrain. - @remarks - If supplied, should ideally be terrainSize * terrainSize, but if - it isn't it will be resized. - */ - Image* inputImage; - - /** Optional list of terrainSize * terrainSize floats defining the terrain. - The list of floats wil be interpreted such that the first row - in the array equates to the bottom row of vertices. - */ - float* inputFloat; - - /** If neither inputImage or inputFloat are supplied, the constant - height at which the initial terrain should be created (flat). - */ - float constantHeight; - - /** Whether this structure should 'own' the input data (inputImage and - inputFloat), and therefore delete it on destruction. - The default is false so you have to manage your own memory. If you - set it to true, then you must have allocated the memory through - OGRE_NEW (for Image) and OGRE_ALLOC_T (for inputFloat), the latter - with the category MEMCATEGORY_GEOMETRY. - */ - bool deleteInputData; - - /// How to scale the input values provided (if any) - Real inputScale; - /// How to bias the input values provided (if any) - Real inputBias; - - /** Definition of the contents of each layer (required). - Most likely, you will pull a declaration from a TerrainMaterialGenerator - of your choice. - */ - TerrainLayerDeclaration layerDeclaration; - /** List of layer structures, one for each layer required. - Can be empty or underfilled if required, list will be padded with - blank textures. - */ - LayerInstanceList layerList; - - ImportData() - : terrainAlign(ALIGN_X_Z) - , terrainSize(1025) - , maxBatchSize(65) - , minBatchSize(17) - , pos(Vector3::ZERO) - , worldSize(1000) - , inputImage(0) - , inputFloat(0) - , constantHeight(0) - , deleteInputData(false) - , inputScale(1.0) - , inputBias(0.0) - { - - } - - ImportData(const ImportData& rhs) - : terrainAlign(ALIGN_X_Z) - , terrainSize(1025) - , maxBatchSize(65) - , minBatchSize(17) - , pos(Vector3::ZERO) - , worldSize(1000) - , inputImage(0) - , inputFloat(0) - , constantHeight(0) - , deleteInputData(false) - , inputScale(1.0) - , inputBias(0.0) - { - *this = rhs; - } - - ImportData& operator=(const ImportData& rhs) - { - // basic copy - terrainAlign = rhs.terrainAlign; - terrainSize = rhs.terrainSize; - maxBatchSize = rhs.maxBatchSize; - minBatchSize = rhs.minBatchSize; - pos = rhs.pos; - worldSize = rhs.worldSize; - constantHeight = rhs.constantHeight; - deleteInputData = rhs.deleteInputData; - inputScale = rhs.inputScale; - inputBias = rhs.inputBias; - layerDeclaration = rhs.layerDeclaration; - layerList = rhs.layerList; - - // By-value copies in ownership cases - if (rhs.deleteInputData) - { - if (rhs.inputImage) - inputImage = OGRE_NEW Image(*rhs.inputImage); - else - inputImage = 0; - - if (rhs.inputFloat) - { - inputFloat = OGRE_ALLOC_T(float, terrainSize*terrainSize, MEMCATEGORY_GEOMETRY); - memcpy(inputFloat, rhs.inputFloat, sizeof(float) * terrainSize*terrainSize); - } - else - inputFloat = 0; - } - else - { - // re-use pointers - inputImage = rhs.inputImage; - inputFloat = rhs.inputFloat; - } - return *this; - } - - /// Delete any input data if this struct is set to do so - void destroy() - { - if (deleteInputData) - { - OGRE_DELETE inputImage; - OGRE_FREE(inputFloat, MEMCATEGORY_GEOMETRY); - inputImage = 0; - inputFloat = 0; - } - - } - - ~ImportData() - { - destroy(); - } - - }; - - /// Neighbour index enumeration - indexed anticlockwise from East like angles - enum NeighbourIndex - { - NEIGHBOUR_EAST = 0, - NEIGHBOUR_NORTHEAST = 1, - NEIGHBOUR_NORTH = 2, - NEIGHBOUR_NORTHWEST = 3, - NEIGHBOUR_WEST = 4, - NEIGHBOUR_SOUTHWEST = 5, - NEIGHBOUR_SOUTH = 6, - NEIGHBOUR_SOUTHEAST = 7, - - NEIGHBOUR_COUNT = 8 - }; - - SceneManager* getSceneManager() const { return mSceneMgr; } - - /// Enumeration of relative spaces that you might want to use to address the terrain - enum Space - { - /// Simple global world space, axes and positions are all in world space - WORLD_SPACE = 0, - /// As world space, but positions are relative to the terrain world position - LOCAL_SPACE = 1, - /** x & y are parametric values on the terrain from 0 to 1, with the - origin at the bottom left. z is the world space height at that point. - */ - TERRAIN_SPACE = 2, - /** x & y are integer points on the terrain from 0 to size-1, with the - origin at the bottom left. z is the world space height at that point. - */ - POINT_SPACE = 3 - }; - - /** Interface used to by the Terrain instance to allocate GPU buffers. - @remarks This class exists to make it easier to re-use buffers between - multiple instances of terrain. - */ - class _OgreTerrainExport GpuBufferAllocator : public TerrainAlloc - { - public: - GpuBufferAllocator() {} - virtual ~GpuBufferAllocator() {} - - /** Allocate (or reuse) vertex buffers for a terrain LOD. - @param numVertices The total number of vertices - @param destPos Pointer to a vertex buffer for positions, to be bound - @param destDelta Pointer to a vertex buffer for deltas, to be bound - */ - virtual void allocateVertexBuffers(Terrain* forTerrain, size_t numVertices, HardwareVertexBufferSharedPtr& destPos, HardwareVertexBufferSharedPtr& destDelta) = 0; - /** Free (or return to the pool) vertex buffers for terrain. - */ - virtual void freeVertexBuffers(const HardwareVertexBufferSharedPtr& posbuf, const HardwareVertexBufferSharedPtr& deltabuf) = 0; - - /** Get a shared index buffer for a given number of settings. - @remarks - Since all index structures are the same at the same LOD level and - relative position, we can share index buffers. Therefore the - buffer returned from this method does not need to be 'freed' like - the vertex buffers since it is never owned. - @param batchSize The batch size along one edge - @param vdatasize The size of the referenced vertex data along one edge - @param vertexIncrement The number of vertices to increment for each new indexed row / column - @param xoffset The x offset from the start of vdatasize, at that resolution - @param yoffset The y offset from the start of vdatasize, at that resolution - @param numSkirtRowsCols Number of rows and columns of skirts - @param skirtRowColSkip The number of rows / cols to skip in between skirts - */ - virtual HardwareIndexBufferSharedPtr getSharedIndexBuffer(uint16 batchSize, - uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, - uint16 skirtRowColSkip) = 0; - - /// Free any buffers we're holding - virtual void freeAllBuffers() = 0; - - }; - /// Standard implementation of a buffer allocator which re-uses buffers - class _OgreTerrainExport DefaultGpuBufferAllocator : public GpuBufferAllocator - { - public: - DefaultGpuBufferAllocator(); - virtual ~DefaultGpuBufferAllocator(); - void allocateVertexBuffers(Terrain* forTerrain, size_t numVertices, HardwareVertexBufferSharedPtr& destPos, HardwareVertexBufferSharedPtr& destDelta); - void freeVertexBuffers(const HardwareVertexBufferSharedPtr& posbuf, const HardwareVertexBufferSharedPtr& deltabuf); - HardwareIndexBufferSharedPtr getSharedIndexBuffer(uint16 batchSize, - uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, - uint16 skirtRowColSkip); - void freeAllBuffers(); - - /** 'Warm start' the allocator based on needing x instances of - terrain with the given configuration. - */ - void warmStart(size_t numInstances, uint16 terrainSize, uint16 maxBatchSize, - uint16 minBatchSize); - - protected: - typedef list::type VBufList; - VBufList mFreePosBufList; - VBufList mFreeDeltaBufList; - typedef map::type IBufMap; - IBufMap mSharedIBufMap; - - uint32 hashIndexBuffer(uint16 batchSize, - uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, - uint16 skirtRowColSkip); - HardwareVertexBufferSharedPtr getVertexBuffer(VBufList& list, size_t vertexSize, size_t numVertices); - - }; - - /** Tell this instance to use the given GpuBufferAllocator. - @remarks - May only be called when the terrain is not loaded. - */ - void setGpuBufferAllocator(GpuBufferAllocator* alloc); - - /// Get the current buffer allocator - GpuBufferAllocator* getGpuBufferAllocator(); - - /// Utility method to get the number of indexes required to render a given batch - static size_t _getNumIndexesForBatchSize(uint16 batchSize); - /** Utility method to populate a (locked) index buffer. - @param pIndexes Pointer to an index buffer to populate - @param batchSize The number of vertices down one side of the batch - @param vdatasize The number of vertices down one side of the vertex data being referenced - @param vertexIncrement The number of vertices to increment for each new indexed row / column - @param xoffset The x offset from the start of the vertex data being referenced - @param yoffset The y offset from the start of the vertex data being referenced - @param numSkirtRowsCols Number of rows and columns of skirts - @param skirtRowColSkip The number of rows / cols to skip in between skirts - - */ - static void _populateIndexBuffer(uint16* pIndexes, uint16 batchSize, - uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, - uint16 skirtRowColSkip); - - /** Utility method to calculate the skirt index for a given original vertex index. */ - static uint16 _calcSkirtVertexIndex(uint16 mainIndex, uint16 vdatasize, bool isCol, - uint16 numSkirtRowsCols, uint16 skirtRowColSkip); - - /** Convert a position from one space to another with respect to this terrain. - @param inSpace The space that inPos is expressed as - @param inPos The incoming position - @param outSpace The space which outPos should be expressed as - @param outPos The output position to be populated - */ - void convertPosition(Space inSpace, const Vector3& inPos, Space outSpace, Vector3& outPos) const; - /** Convert a position from one space to another with respect to this terrain. - @param inSpace The space that inPos is expressed as - @param inPos The incoming position - @param outSpace The space which outPos should be expressed as - @return The output position - */ - Vector3 convertPosition(Space inSpace, const Vector3& inPos, Space outSpace) const; - /** Convert a direction from one space to another with respect to this terrain. - @param inSpace The space that inDir is expressed as - @param inDir The incoming direction - @param outSpace The space which outDir should be expressed as - @param outDir The output direction to be populated - */ - void convertDirection(Space inSpace, const Vector3& inDir, Space outSpace, Vector3& outDir) const; - /** Convert a direction from one space to another with respect to this terrain. - @param inSpace The space that inDir is expressed as - @param inDir The incoming direction - @param outSpace The space which outDir should be expressed as - @return The output direction - */ - Vector3 convertDirection(Space inSpace, const Vector3& inDir, Space outSpace) const; - - /** Set the resource group to use when loading / saving. - @param resGroup Resource group name - you can set this to blank to use - the default in TerrainGlobalOptions. - */ - void setResourceGroup(const String& resGroup) { mResourceGroup = resGroup; } - - /** Get the resource group to use when loading / saving. - If this is blank, the default in TerrainGlobalOptions will be used. - */ - const String& getResourceGroup() const { return mResourceGroup; } - - /** Get the final resource group to use when loading / saving. - */ - const String& _getDerivedResourceGroup() const; - - /** Save terrain data in native form to a standalone file - @param filename The name of the file to save to. If this is a filename with - no path elements, then it is saved in the first writeable location - available in the resource group you have chosen to use for this - terrain. If the filename includes path specifiers then it is saved - directly instead (but note that it may not be reloadable via the - resource system if the location is not on the path). - */ - void save(const String& filename); - /** Save terrain data in native form to a serializing stream. - @remarks - If you want complete control over where the terrain data goes, use - this form. - */ - void save(StreamSerialiser& stream); - - /** Prepare the terrain from a standalone file. - @note - This is safe to do in a background thread as it creates no GPU resources. - It reads data from a native terrain data chunk. For more advanced uses, - such as loading from a shared file, use the StreamSerialiser form. - */ - bool prepare(const String& filename); - /** Prepare terrain data from saved data. - @remarks - This is safe to do in a background thread as it creates no GPU resources. - It reads data from a native terrain data chunk. - @return true if the preparation was successful - */ - bool prepare(DataStreamPtr& stream); - /** Prepare terrain data from saved data. - @remarks - This is safe to do in a background thread as it creates no GPU resources. - It reads data from a native terrain data chunk. - @return true if the preparation was successful - */ - bool prepare(StreamSerialiser& stream); - - /** Prepare the terrain from some import data rather than loading from - native data. - @remarks - This method may be called in a background thread. - */ - bool prepare(const ImportData& importData); - - /** Prepare and load the terrain in one simple call from a standalone file. - @note - This method must be called from the primary render thread. To load data - in a background thread, use the prepare() method. - */ - void load(const String& filename); - - /** Prepare and load the terrain in one simple call from a stream. - @note - This method must be called from the primary render thread. To load data - in a background thread, use the prepare() method. - */ - void load(StreamSerialiser& stream); - - /** Load the terrain based on the data already populated via prepare methods. - @remarks - This method must be called in the main render thread. - @param lodLevel Load the specified LOD level - @param synchronous Load type - */ - void load(int lodLevel = 0, bool synchronous = true); - - /** Return whether the terrain is loaded. - @remarks - Should only be called from the render thread really, since this is - where the loaded state changes. - */ - bool isLoaded() const { return mIsLoaded; } - - /** Returns whether this terrain has been modified since it was first loaded / defined. - @remarks - This flag is reset on save(). - */ - bool isModified() const { return mModified; } - - - /** Returns whether terrain heights have been modified since the terrain was first loaded / defined. - @remarks - This flag is reset on save(). - */ - bool isHeightDataModified() const { return mHeightDataModified; } - - - /** Unload the terrain and free GPU resources. - @remarks - This method must be called in the main render thread. - */ - void unload(); - - /** Free CPU resources created during prepare methods. - @remarks - This is safe to do in a background thread after calling unload(). - */ - void unprepare(); - - - /** Get a pointer to all the height data for this terrain. - @remarks - The height data is in world coordinates, relative to the position - of the terrain. - @par - This pointer is not const, so you can update the height data if you - wish. However, changes will not be propagated until you call - Terrain::dirty or Terrain::dirtyRect. - */ - float* getHeightData() const; - - /** Get a pointer to the height data for a given point. - */ - float* getHeightData(long x, long y) const; - - /** Get the height data for a given terrain point. - @param x, y Discrete coordinates in terrain vertices, values from 0 to size-1, - left/right bottom/top - */ - float getHeightAtPoint(long x, long y) const; - - /** Set the height data for a given terrain point. - @note this doesn't take effect until you call update() - @param x, y Discrete coordinates in terrain vertices, values from 0 to size-1, - left/right bottom/top - @param h The new height - */ - void setHeightAtPoint(long x, long y, float h); - - /** Get the height data for a given terrain position. - @param x, y Position in terrain space, values from 0 to 1 left/right bottom/top - */ - float getHeightAtTerrainPosition(Real x, Real y) const; - - /** Get the height data for a given world position (projecting the point - down on to the terrain). - @param x, y,z Position in world space. Positions will be clamped to the edge - of the terrain - */ - float getHeightAtWorldPosition(Real x, Real y, Real z) const; - - /** Get the height data for a given world position (projecting the point - down on to the terrain). - @param pos Position in world space. Positions will be clamped to the edge - of the terrain - */ - float getHeightAtWorldPosition(const Vector3& pos) const; - - /** Get a pointer to all the delta data for this terrain. - @remarks - The delta data is a measure at a given vertex of by how much vertically - a vertex will have to move to reach the point at which it will be - removed in the next lower LOD. - */ - const float* getDeltaData() const; - - /** Get a pointer to the delta data for a given point. - */ - const float* getDeltaData(long x, long y) const; - - /** Get a Vector3 of the world-space point on the terrain, aligned as per - options. - @note This point is relative to Terrain::getPosition - */ - void getPoint(long x, long y, Vector3* outpos) const; - - /** Get a Vector3 of the world-space point on the terrain, aligned as per - options. Cascades into neighbours if out of bounds. - @note This point is relative to Terrain::getPosition - neighbours are - adjusted to be relative to this tile - */ - void getPointFromSelfOrNeighbour(long x, long y, Vector3* outpos) const; - - /** Get a Vector3 of the world-space point on the terrain, supplying the - height data manually (can be more optimal). - @note This point is relative to Terrain::getPosition - */ - void getPoint(long x, long y, float height, Vector3* outpos) const; - /** Get a transform which converts Vector4(xindex, yindex, height, 1) into - an object-space position including scalings and alignment. - */ - void getPointTransform(Matrix4* outXform) const; - /** Translate a vector from world space to local terrain space based on the alignment options. - @param inVec The vector in basis space, where x/y represents the - terrain plane and z represents the up vector - */ - void getTerrainVector(const Vector3& inVec, Vector3* outVec) const; - /** Translate a vector from world space to local terrain space based on a specified alignment. - @param inVec The vector in basis space, where x/y represents the - terrain plane and z represents the up vector - */ - void getTerrainVectorAlign(const Vector3& inVec, Alignment align, Vector3* outVec) const; - - /** Translate a vector from world space to local terrain space based on the alignment options. - @param x, y, z The vector in basis space, where x/y represents the - terrain plane and z represents the up vector - */ - void getTerrainVector(Real x, Real y, Real z, Vector3* outVec) const; - /** Translate a vector from world space to local terrain space based on a specified alignment. - @param x, y, z The vector in world space, where x/y represents the - terrain plane and z represents the up vector - */ - void getTerrainVectorAlign(Real x, Real y, Real z, Alignment align, Vector3* outVec) const; - - /** Translate a vector into world space based on the alignment options. - @param inVec The vector in basis space, where x/y represents the - terrain plane and z represents the up vector - */ - void getVector(const Vector3& inVec, Vector3* outVec) const; - /** Translate a vector into world space based on a specified alignment. - @param inVec The vector in basis space, where x/y represents the - terrain plane and z represents the up vector - */ - void getVectorAlign(const Vector3& inVec, Alignment align, Vector3* outVec) const; - - /** Translate a vector into world space based on the alignment options. - @param x, y, z The vector in basis space, where x/y represents the - terrain plane and z represents the up vector - */ - void getVector(Real x, Real y, Real z, Vector3* outVec) const; - /** Translate a vector into world space based on a specified alignment. - @param x, y, z The vector in basis space, where x/y represents the - terrain plane and z represents the up vector - */ - void getVectorAlign(Real x, Real y, Real z, Alignment align, Vector3* outVec) const; - - - /** Convert a position from terrain basis space to world space. - @param TSpos Terrain space position, where (0,0) is the bottom-left of the - terrain, and (1,1) is the top-right. The Z coordinate is in absolute - height units. - @note This position is relative to Terrain::getPosition - @param outWSpos World space output position (setup according to current alignment). - */ - void getPosition(const Vector3& TSpos, Vector3* outWSpos) const; - /** Convert a position from terrain basis space to world space. - @param x,y,z Terrain space position, where (0,0) is the bottom-left of the - terrain, and (1,1) is the top-right. The Z coordinate is in absolute - height units. - @note This position is relative to Terrain::getPosition - @param outWSpos World space output position (setup according to current alignment). - */ - void getPosition(Real x, Real y, Real z, Vector3* outWSpos) const; - - /** Convert a position from world space to terrain basis space. - @param WSpos World space position (setup according to current alignment). - @param outTSpos Terrain space output position, where (0,0) is the bottom-left of the - terrain, and (1,1) is the top-right. The Z coordinate is in absolute - height units. - */ - void getTerrainPosition(const Vector3& WSpos, Vector3* outTSpos) const; - /** Convert a position from world space to terrain basis space. - @param x,y,z World space position (setup according to current alignment). - @param outTSpos Terrain space output position, where (0,0) is the bottom-left of the - terrain, and (1,1) is the top-right. The Z coordinate is in absolute - height units. - */ - void getTerrainPosition(Real x, Real y, Real z, Vector3* outTSpos) const; - /** Convert a position from terrain basis space to world space based on a specified alignment. - @param TSpos Terrain space position, where (0,0) is the bottom-left of the - terrain, and (1,1) is the top-right. The Z coordinate is in absolute - height units. - @param outWSpos World space output position (setup according to alignment). - */ - void getPositionAlign(const Vector3& TSpos, Alignment align, Vector3* outWSpos) const; - /** Convert a position from terrain basis space to world space based on a specified alignment. - @param x,y,z Terrain space position, where (0,0) is the bottom-left of the - terrain, and (1,1) is the top-right. The Z coordinate is in absolute - height units. - @param outWSpos World space output position (setup according to alignment). - */ - void getPositionAlign(Real x, Real y, Real z, Alignment align, Vector3* outWSpos) const; - - /** Convert a position from world space to terrain basis space based on a specified alignment. - @param WSpos World space position (setup according to alignment). - @param outTSpos Terrain space output position, where (0,0) is the bottom-left of the - terrain, and (1,1) is the top-right. The Z coordinate is in absolute - height units. - */ - void getTerrainPositionAlign(const Vector3& WSpos, Alignment align, Vector3* outTSpos) const; - /** Convert a position from world space to terrain basis space based on a specified alignment. - @param x,y,z World space position (setup according to alignment). - @param outTSpos Terrain space output position, where (0,0) is the bottom-left of the - terrain, and (1,1) is the top-right. The Z coordinate is in absolute - height units. - */ - void getTerrainPositionAlign(Real x, Real y, Real z, Alignment align, Vector3* outTSpos) const; - - - /// Get the alignment of the terrain - Alignment getAlignment() const; - /// Get the size of the terrain in vertices along one side - uint16 getSize() const; - /** Set the size of terrain in vertices along one side. - @note The existing height data will be bilinear filtered to fill the new size - @param newSize the new size of the terrain - */ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Terrain + * Some details on the terrain component + * @{ + */ + + /** The main containing class for a chunk of terrain. + @par + Terrain can be edited and stored. + The data format for this in a file is:
      + TerrainData (Identifier 'TERR')\n + [Version 1] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeDescription
      Terrain orientationuint8The orientation of the terrain; XZ = 0, XY = 1, YZ = 2
      Terrain sizeuint16The number of vertices along one side of the terrain
      Terrain world sizeRealThe world size of one side of the terrain
      Max batch sizeuint16The maximum batch size in vertices along one side
      Min batch sizeuint16The minimum batch size in vertices along one side
      PositionVector3The location of the centre of the terrain
      Height datafloat[size*size]List of floating point heights
      LayerDeclarationLayerDeclaration*The layer declaration for this terrain (see below)
      Layer countuint8The number of layers in this terrain
      LayerInstance listLayerInstance*A number of LayerInstance definitions based on layer count (see below)
      Layer blend map sizeuint16The size of the layer blend maps as stored in this file
      Packed blend texture datauint8*layerCount-1 sets of blend texture data interleaved as either RGB or RGBA + depending on layer count
      Optional derived map dataTerrainDerivedMap list0 or more sets of map data derived from the original terrain
      Delta datafloat[size*size]At each vertex, delta information for the LOD at which this vertex disappears
      Quadtree delta datafloat[quadtrees*lods]At each quadtree node, for each lod a record of the max delta value in the region
      + TerrainLayerDeclaration (Identifier 'TDCL')\n + [Version 1] + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeDescription
      TerrainLayerSampler Countuint8Number of samplers in this declaration
      TerrainLayerSampler ListTerrainLayerSampler*List of TerrainLayerSampler structures
      Sampler Element Countuint8Number of sampler elements in this declaration
      TerrainLayerSamplerElement ListTerrainLayerSamplerElement*List of TerrainLayerSamplerElement structures
      + TerrainLayerSampler (Identifier 'TSAM')\n + [Version 1] + + + + + + + + + + + + + + + + +
      NameTypeDescription
      AliasStringAlias name of this sampler
      Formatuint8Desired pixel format
      + TerrainLayerSamplerElement (Identifier 'TSEL')\n + [Version 1] + + + + + + + + + + + + + + + + + + + + + + + + + + +
      NameTypeDescription
      Sourceuint8Sampler source index
      Semanticuint8Semantic interpretation of this element
      Element startuint8Start of this element in the sampler
      Element countuint8Number of elements in the sampler used by this entry
      + LayerInstance (Identifier 'TLIN')\n + [Version 1] + + + + + + + + + + + + + + + + +
      NameTypeDescription
      World sizeRealThe world size of this layer (determines UV scaling)
      Texture listString*List of texture names corresponding to the number of samplers in the layer declaration
      + TerrainDerivedData (Identifier 'TDDA')\n + [Version 1] + + + + + + + + + + + + + + + + + + + + + +
      NameTypeDescription
      Derived data type nameStringName of the derived data type ('normalmap', 'lightmap', 'colourmap', 'compositemap')
      Sizeuint16Size of the data along one edge
      Datavaries based on typeThe data
      + */ + class _OgreTerrainExport Terrain : public SceneManager::Listener, + public WorkQueue::RequestHandler, public WorkQueue::ResponseHandler, public TerrainAlloc + { + public: + friend class TerrainLodManager; + + /** Constructor. + @param sm The SceneManager to use. + */ + Terrain(SceneManager* sm); + virtual ~Terrain(); + + static const uint32 TERRAIN_CHUNK_ID; + static const uint16 TERRAIN_CHUNK_VERSION; + static const uint16 TERRAIN_MAX_BATCH_SIZE; + static const uint64 TERRAIN_GENERATE_MATERIAL_INTERVAL_MS; + + static const uint32 TERRAINLAYERDECLARATION_CHUNK_ID; + static const uint16 TERRAINLAYERDECLARATION_CHUNK_VERSION; + static const uint32 TERRAINLAYERSAMPLER_CHUNK_ID; + static const uint16 TERRAINLAYERSAMPLER_CHUNK_VERSION; + static const uint32 TERRAINLAYERSAMPLERELEMENT_CHUNK_ID; + static const uint16 TERRAINLAYERSAMPLERELEMENT_CHUNK_VERSION; + static const uint32 TERRAINLAYERINSTANCE_CHUNK_ID; + static const uint16 TERRAINLAYERINSTANCE_CHUNK_VERSION; + static const uint32 TERRAINDERIVEDDATA_CHUNK_ID; + static const uint16 TERRAINDERIVEDDATA_CHUNK_VERSION; + static const uint32 TERRAINGENERALINFO_CHUNK_ID; + static const uint16 TERRAINGENERALINFO_CHUNK_VERSION; + + static const size_t LOD_MORPH_CUSTOM_PARAM; + + typedef vector::type RealVector; + + /** An instance of a layer, with specific texture names + */ + struct _OgreTerrainExport LayerInstance + { + /// The world size of the texture to be applied in this layer + Real worldSize; + /// List of texture names to import; must match with TerrainLayerDeclaration + StringVector textureNames; + + LayerInstance() + : worldSize(100) {} + }; + typedef vector::type LayerInstanceList; + + /// The alignment of the terrain + enum Alignment + { + /// Terrain is in the X/Z plane + ALIGN_X_Z = 0, + /// Terrain is in the X/Y plane + ALIGN_X_Y = 1, + /// Terrain is in the Y/Z plane + ALIGN_Y_Z = 2 + }; + + /** Structure encapsulating import data that you may use to bootstrap + the terrain without loading from a native data stream. + */ + struct ImportData + { + /// The alignment of the terrain + Alignment terrainAlign; + /// Terrain size (along one edge) in vertices; must be 2^n+1 + uint16 terrainSize; + /** Maximum batch size (along one edge) in vertices; must be 2^n+1 and <= 65 + @remarks + The terrain will be divided into hierarchical tiles, and this is the maximum + size of one tile in vertices (at any LOD). + */ + uint16 maxBatchSize; + /** Minimum batch size (along one edge) in vertices; must be 2^n+1. + @remarks + The terrain will be divided into tiles, and this is the minimum + size of one tile in vertices (at any LOD). Adjacent tiles will be + collected together into one batch to drop LOD levels once they are individually at this minimum, + so setting this value higher means greater batching at the expense + of making adjacent tiles use a common LOD. + Once the entire terrain is collected together into one batch this + effectively sets the minimum LOD. + */ + uint16 minBatchSize; + + /** Position of the terrain. + @remarks + Represents the position of the centre of the terrain. + */ + Vector3 pos; + + /** The world size of the terrain. */ + Real worldSize; + + /** Optional heightmap providing the initial heights for the terrain. + @remarks + If supplied, should ideally be terrainSize * terrainSize, but if + it isn't it will be resized. + */ + Image* inputImage; + + /** Optional list of terrainSize * terrainSize floats defining the terrain. + The list of floats wil be interpreted such that the first row + in the array equates to the bottom row of vertices. + */ + float* inputFloat; + + /** If neither inputImage or inputFloat are supplied, the constant + height at which the initial terrain should be created (flat). + */ + float constantHeight; + + /** Whether this structure should 'own' the input data (inputImage and + inputFloat), and therefore delete it on destruction. + The default is false so you have to manage your own memory. If you + set it to true, then you must have allocated the memory through + OGRE_NEW (for Image) and OGRE_ALLOC_T (for inputFloat), the latter + with the category MEMCATEGORY_GEOMETRY. + */ + bool deleteInputData; + + /// How to scale the input values provided (if any) + Real inputScale; + /// How to bias the input values provided (if any) + Real inputBias; + + /** Definition of the contents of each layer (required). + Most likely, you will pull a declaration from a TerrainMaterialGenerator + of your choice. + */ + TerrainLayerDeclaration layerDeclaration; + /** List of layer structures, one for each layer required. + Can be empty or underfilled if required, list will be padded with + blank textures. + */ + LayerInstanceList layerList; + + ImportData() + : terrainAlign(ALIGN_X_Z) + , terrainSize(1025) + , maxBatchSize(65) + , minBatchSize(17) + , pos(Vector3::ZERO) + , worldSize(1000) + , inputImage(0) + , inputFloat(0) + , constantHeight(0) + , deleteInputData(false) + , inputScale(1.0) + , inputBias(0.0) + { + + } + + ImportData(const ImportData& rhs) + : terrainAlign(ALIGN_X_Z) + , terrainSize(1025) + , maxBatchSize(65) + , minBatchSize(17) + , pos(Vector3::ZERO) + , worldSize(1000) + , inputImage(0) + , inputFloat(0) + , constantHeight(0) + , deleteInputData(false) + , inputScale(1.0) + , inputBias(0.0) + { + *this = rhs; + } + + ImportData& operator=(const ImportData& rhs) + { + // basic copy + terrainAlign = rhs.terrainAlign; + terrainSize = rhs.terrainSize; + maxBatchSize = rhs.maxBatchSize; + minBatchSize = rhs.minBatchSize; + pos = rhs.pos; + worldSize = rhs.worldSize; + constantHeight = rhs.constantHeight; + deleteInputData = rhs.deleteInputData; + inputScale = rhs.inputScale; + inputBias = rhs.inputBias; + layerDeclaration = rhs.layerDeclaration; + layerList = rhs.layerList; + + // By-value copies in ownership cases + if (rhs.deleteInputData) + { + if (rhs.inputImage) + inputImage = OGRE_NEW Image(*rhs.inputImage); + else + inputImage = 0; + + if (rhs.inputFloat) + { + inputFloat = OGRE_ALLOC_T(float, terrainSize*terrainSize, MEMCATEGORY_GEOMETRY); + memcpy(inputFloat, rhs.inputFloat, sizeof(float) * terrainSize*terrainSize); + } + else + inputFloat = 0; + } + else + { + // re-use pointers + inputImage = rhs.inputImage; + inputFloat = rhs.inputFloat; + } + return *this; + } + + /// Delete any input data if this struct is set to do so + void destroy() + { + if (deleteInputData) + { + OGRE_DELETE inputImage; + OGRE_FREE(inputFloat, MEMCATEGORY_GEOMETRY); + inputImage = 0; + inputFloat = 0; + } + + } + + ~ImportData() + { + destroy(); + } + + }; + + /// Neighbour index enumeration - indexed anticlockwise from East like angles + enum NeighbourIndex + { + NEIGHBOUR_EAST = 0, + NEIGHBOUR_NORTHEAST = 1, + NEIGHBOUR_NORTH = 2, + NEIGHBOUR_NORTHWEST = 3, + NEIGHBOUR_WEST = 4, + NEIGHBOUR_SOUTHWEST = 5, + NEIGHBOUR_SOUTH = 6, + NEIGHBOUR_SOUTHEAST = 7, + + NEIGHBOUR_COUNT = 8 + }; + + SceneManager* getSceneManager() const { return mSceneMgr; } + + /// Enumeration of relative spaces that you might want to use to address the terrain + enum Space + { + /// Simple global world space, axes and positions are all in world space + WORLD_SPACE = 0, + /// As world space, but positions are relative to the terrain world position + LOCAL_SPACE = 1, + /** x & y are parametric values on the terrain from 0 to 1, with the + origin at the bottom left. z is the world space height at that point. + */ + TERRAIN_SPACE = 2, + /** x & y are integer points on the terrain from 0 to size-1, with the + origin at the bottom left. z is the world space height at that point. + */ + POINT_SPACE = 3 + }; + + /** Interface used to by the Terrain instance to allocate GPU buffers. + @remarks This class exists to make it easier to re-use buffers between + multiple instances of terrain. + */ + class _OgreTerrainExport GpuBufferAllocator : public TerrainAlloc + { + public: + GpuBufferAllocator() {} + virtual ~GpuBufferAllocator() {} + + /** Allocate (or reuse) vertex buffers for a terrain LOD. + @param numVertices The total number of vertices + @param destPos Pointer to a vertex buffer for positions, to be bound + @param destDelta Pointer to a vertex buffer for deltas, to be bound + */ + virtual void allocateVertexBuffers(Terrain* forTerrain, size_t numVertices, HardwareVertexBufferSharedPtr& destPos, HardwareVertexBufferSharedPtr& destDelta) = 0; + /** Free (or return to the pool) vertex buffers for terrain. + */ + virtual void freeVertexBuffers(const HardwareVertexBufferSharedPtr& posbuf, const HardwareVertexBufferSharedPtr& deltabuf) = 0; + + /** Get a shared index buffer for a given number of settings. + @remarks + Since all index structures are the same at the same LOD level and + relative position, we can share index buffers. Therefore the + buffer returned from this method does not need to be 'freed' like + the vertex buffers since it is never owned. + @param batchSize The batch size along one edge + @param vdatasize The size of the referenced vertex data along one edge + @param vertexIncrement The number of vertices to increment for each new indexed row / column + @param xoffset The x offset from the start of vdatasize, at that resolution + @param yoffset The y offset from the start of vdatasize, at that resolution + @param numSkirtRowsCols Number of rows and columns of skirts + @param skirtRowColSkip The number of rows / cols to skip in between skirts + */ + virtual HardwareIndexBufferSharedPtr getSharedIndexBuffer(uint16 batchSize, + uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, + uint16 skirtRowColSkip) = 0; + + /// Free any buffers we're holding + virtual void freeAllBuffers() = 0; + + }; + /// Standard implementation of a buffer allocator which re-uses buffers + class _OgreTerrainExport DefaultGpuBufferAllocator : public GpuBufferAllocator + { + public: + DefaultGpuBufferAllocator(); + virtual ~DefaultGpuBufferAllocator(); + void allocateVertexBuffers(Terrain* forTerrain, size_t numVertices, HardwareVertexBufferSharedPtr& destPos, HardwareVertexBufferSharedPtr& destDelta); + void freeVertexBuffers(const HardwareVertexBufferSharedPtr& posbuf, const HardwareVertexBufferSharedPtr& deltabuf); + HardwareIndexBufferSharedPtr getSharedIndexBuffer(uint16 batchSize, + uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, + uint16 skirtRowColSkip); + void freeAllBuffers(); + + /** 'Warm start' the allocator based on needing x instances of + terrain with the given configuration. + */ + void warmStart(size_t numInstances, uint16 terrainSize, uint16 maxBatchSize, + uint16 minBatchSize); + + protected: + typedef list::type VBufList; + VBufList mFreePosBufList; + VBufList mFreeDeltaBufList; + typedef map::type IBufMap; + IBufMap mSharedIBufMap; + + uint32 hashIndexBuffer(uint16 batchSize, + uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, + uint16 skirtRowColSkip); + HardwareVertexBufferSharedPtr getVertexBuffer(VBufList& list, size_t vertexSize, size_t numVertices); + + }; + + /** Tell this instance to use the given GpuBufferAllocator. + @remarks + May only be called when the terrain is not loaded. + */ + void setGpuBufferAllocator(GpuBufferAllocator* alloc); + + /// Get the current buffer allocator + GpuBufferAllocator* getGpuBufferAllocator(); + + /// Utility method to get the number of indexes required to render a given batch + static size_t _getNumIndexesForBatchSize(uint16 batchSize); + /** Utility method to populate a (locked) index buffer. + @param pIndexes Pointer to an index buffer to populate + @param batchSize The number of vertices down one side of the batch + @param vdatasize The number of vertices down one side of the vertex data being referenced + @param vertexIncrement The number of vertices to increment for each new indexed row / column + @param xoffset The x offset from the start of the vertex data being referenced + @param yoffset The y offset from the start of the vertex data being referenced + @param numSkirtRowsCols Number of rows and columns of skirts + @param skirtRowColSkip The number of rows / cols to skip in between skirts + + */ + static void _populateIndexBuffer(uint16* pIndexes, uint16 batchSize, + uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, + uint16 skirtRowColSkip); + + /** Utility method to calculate the skirt index for a given original vertex index. */ + static uint16 _calcSkirtVertexIndex(uint16 mainIndex, uint16 vdatasize, bool isCol, + uint16 numSkirtRowsCols, uint16 skirtRowColSkip); + + /** Convert a position from one space to another with respect to this terrain. + @param inSpace The space that inPos is expressed as + @param inPos The incoming position + @param outSpace The space which outPos should be expressed as + @param outPos The output position to be populated + */ + void convertPosition(Space inSpace, const Vector3& inPos, Space outSpace, Vector3& outPos) const; + /** Convert a position from one space to another with respect to this terrain. + @param inSpace The space that inPos is expressed as + @param inPos The incoming position + @param outSpace The space which outPos should be expressed as + @return The output position + */ + Vector3 convertPosition(Space inSpace, const Vector3& inPos, Space outSpace) const; + /** Convert a direction from one space to another with respect to this terrain. + @param inSpace The space that inDir is expressed as + @param inDir The incoming direction + @param outSpace The space which outDir should be expressed as + @param outDir The output direction to be populated + */ + void convertDirection(Space inSpace, const Vector3& inDir, Space outSpace, Vector3& outDir) const; + /** Convert a direction from one space to another with respect to this terrain. + @param inSpace The space that inDir is expressed as + @param inDir The incoming direction + @param outSpace The space which outDir should be expressed as + @return The output direction + */ + Vector3 convertDirection(Space inSpace, const Vector3& inDir, Space outSpace) const; + + /** Set the resource group to use when loading / saving. + @param resGroup Resource group name - you can set this to blank to use + the default in TerrainGlobalOptions. + */ + void setResourceGroup(const String& resGroup) { mResourceGroup = resGroup; } + + /** Get the resource group to use when loading / saving. + If this is blank, the default in TerrainGlobalOptions will be used. + */ + const String& getResourceGroup() const { return mResourceGroup; } + + /** Get the final resource group to use when loading / saving. + */ + const String& _getDerivedResourceGroup() const; + + /** Save terrain data in native form to a standalone file + @param filename The name of the file to save to. If this is a filename with + no path elements, then it is saved in the first writeable location + available in the resource group you have chosen to use for this + terrain. If the filename includes path specifiers then it is saved + directly instead (but note that it may not be reloadable via the + resource system if the location is not on the path). + */ + void save(const String& filename); + /** Save terrain data in native form to a serializing stream. + @remarks + If you want complete control over where the terrain data goes, use + this form. + */ + void save(StreamSerialiser& stream); + + /** Prepare the terrain from a standalone file. + @note + This is safe to do in a background thread as it creates no GPU resources. + It reads data from a native terrain data chunk. For more advanced uses, + such as loading from a shared file, use the StreamSerialiser form. + */ + bool prepare(const String& filename); + /** Prepare terrain data from saved data. + @remarks + This is safe to do in a background thread as it creates no GPU resources. + It reads data from a native terrain data chunk. + @return true if the preparation was successful + */ + bool prepare(DataStreamPtr& stream); + /** Prepare terrain data from saved data. + @remarks + This is safe to do in a background thread as it creates no GPU resources. + It reads data from a native terrain data chunk. + @return true if the preparation was successful + */ + bool prepare(StreamSerialiser& stream); + + /** Prepare the terrain from some import data rather than loading from + native data. + @remarks + This method may be called in a background thread. + */ + bool prepare(const ImportData& importData); + + /** Prepare and load the terrain in one simple call from a standalone file. + @note + This method must be called from the primary render thread. To load data + in a background thread, use the prepare() method. + */ + void load(const String& filename); + + /** Prepare and load the terrain in one simple call from a stream. + @note + This method must be called from the primary render thread. To load data + in a background thread, use the prepare() method. + */ + void load(StreamSerialiser& stream); + + /** Load the terrain based on the data already populated via prepare methods. + @remarks + This method must be called in the main render thread. + @param lodLevel Load the specified LOD level + @param synchronous Load type + */ + void load(int lodLevel = 0, bool synchronous = true); + + /** Return whether the terrain is loaded. + @remarks + Should only be called from the render thread really, since this is + where the loaded state changes. + */ + bool isLoaded() const { return mIsLoaded; } + + /** Returns whether this terrain has been modified since it was first loaded / defined. + @remarks + This flag is reset on save(). + */ + bool isModified() const { return mModified; } + + + /** Returns whether terrain heights have been modified since the terrain was first loaded / defined. + @remarks + This flag is reset on save(). + */ + bool isHeightDataModified() const { return mHeightDataModified; } + + + /** Unload the terrain and free GPU resources. + @remarks + This method must be called in the main render thread. + */ + void unload(); + + /** Free CPU resources created during prepare methods. + @remarks + This is safe to do in a background thread after calling unload(). + */ + void unprepare(); + + + /** Get a pointer to all the height data for this terrain. + @remarks + The height data is in world coordinates, relative to the position + of the terrain. + @par + This pointer is not const, so you can update the height data if you + wish. However, changes will not be propagated until you call + Terrain::dirty or Terrain::dirtyRect. + */ + float* getHeightData() const; + + /** Get a pointer to the height data for a given point. + */ + float* getHeightData(long x, long y) const; + + /** Get the height data for a given terrain point. + @param x, y Discrete coordinates in terrain vertices, values from 0 to size-1, + left/right bottom/top + */ + float getHeightAtPoint(long x, long y) const; + + /** Set the height data for a given terrain point. + @note this doesn't take effect until you call update() + @param x, y Discrete coordinates in terrain vertices, values from 0 to size-1, + left/right bottom/top + @param h The new height + */ + void setHeightAtPoint(long x, long y, float h); + + /** Get the height data for a given terrain position. + @param x, y Position in terrain space, values from 0 to 1 left/right bottom/top + */ + float getHeightAtTerrainPosition(Real x, Real y) const; + + /** Get the height data for a given world position (projecting the point + down on to the terrain). + @param x, y,z Position in world space. Positions will be clamped to the edge + of the terrain + */ + float getHeightAtWorldPosition(Real x, Real y, Real z) const; + + /** Get the height data for a given world position (projecting the point + down on to the terrain). + @param pos Position in world space. Positions will be clamped to the edge + of the terrain + */ + float getHeightAtWorldPosition(const Vector3& pos) const; + + /** Get a pointer to all the delta data for this terrain. + @remarks + The delta data is a measure at a given vertex of by how much vertically + a vertex will have to move to reach the point at which it will be + removed in the next lower LOD. + */ + const float* getDeltaData() const; + + /** Get a pointer to the delta data for a given point. + */ + const float* getDeltaData(long x, long y) const; + + /** Get a Vector3 of the world-space point on the terrain, aligned as per + options. + @note This point is relative to Terrain::getPosition + */ + void getPoint(long x, long y, Vector3* outpos) const; + + /** Get a Vector3 of the world-space point on the terrain, aligned as per + options. Cascades into neighbours if out of bounds. + @note This point is relative to Terrain::getPosition - neighbours are + adjusted to be relative to this tile + */ + void getPointFromSelfOrNeighbour(long x, long y, Vector3* outpos) const; + + /** Get a Vector3 of the world-space point on the terrain, supplying the + height data manually (can be more optimal). + @note This point is relative to Terrain::getPosition + */ + void getPoint(long x, long y, float height, Vector3* outpos) const; + /** Get a transform which converts Vector4(xindex, yindex, height, 1) into + an object-space position including scalings and alignment. + */ + void getPointTransform(Matrix4* outXform) const; + /** Translate a vector from world space to local terrain space based on the alignment options. + @param inVec The vector in basis space, where x/y represents the + terrain plane and z represents the up vector + */ + void getTerrainVector(const Vector3& inVec, Vector3* outVec) const; + /** Translate a vector from world space to local terrain space based on a specified alignment. + @param inVec The vector in basis space, where x/y represents the + terrain plane and z represents the up vector + */ + void getTerrainVectorAlign(const Vector3& inVec, Alignment align, Vector3* outVec) const; + + /** Translate a vector from world space to local terrain space based on the alignment options. + @param x, y, z The vector in basis space, where x/y represents the + terrain plane and z represents the up vector + */ + void getTerrainVector(Real x, Real y, Real z, Vector3* outVec) const; + /** Translate a vector from world space to local terrain space based on a specified alignment. + @param x, y, z The vector in world space, where x/y represents the + terrain plane and z represents the up vector + */ + void getTerrainVectorAlign(Real x, Real y, Real z, Alignment align, Vector3* outVec) const; + + /** Translate a vector into world space based on the alignment options. + @param inVec The vector in basis space, where x/y represents the + terrain plane and z represents the up vector + */ + void getVector(const Vector3& inVec, Vector3* outVec) const; + /** Translate a vector into world space based on a specified alignment. + @param inVec The vector in basis space, where x/y represents the + terrain plane and z represents the up vector + */ + void getVectorAlign(const Vector3& inVec, Alignment align, Vector3* outVec) const; + + /** Translate a vector into world space based on the alignment options. + @param x, y, z The vector in basis space, where x/y represents the + terrain plane and z represents the up vector + */ + void getVector(Real x, Real y, Real z, Vector3* outVec) const; + /** Translate a vector into world space based on a specified alignment. + @param x, y, z The vector in basis space, where x/y represents the + terrain plane and z represents the up vector + */ + void getVectorAlign(Real x, Real y, Real z, Alignment align, Vector3* outVec) const; + + + /** Convert a position from terrain basis space to world space. + @param TSpos Terrain space position, where (0,0) is the bottom-left of the + terrain, and (1,1) is the top-right. The Z coordinate is in absolute + height units. + @note This position is relative to Terrain::getPosition + @param outWSpos World space output position (setup according to current alignment). + */ + void getPosition(const Vector3& TSpos, Vector3* outWSpos) const; + /** Convert a position from terrain basis space to world space. + @param x,y,z Terrain space position, where (0,0) is the bottom-left of the + terrain, and (1,1) is the top-right. The Z coordinate is in absolute + height units. + @note This position is relative to Terrain::getPosition + @param outWSpos World space output position (setup according to current alignment). + */ + void getPosition(Real x, Real y, Real z, Vector3* outWSpos) const; + + /** Convert a position from world space to terrain basis space. + @param WSpos World space position (setup according to current alignment). + @param outTSpos Terrain space output position, where (0,0) is the bottom-left of the + terrain, and (1,1) is the top-right. The Z coordinate is in absolute + height units. + */ + void getTerrainPosition(const Vector3& WSpos, Vector3* outTSpos) const; + /** Convert a position from world space to terrain basis space. + @param x,y,z World space position (setup according to current alignment). + @param outTSpos Terrain space output position, where (0,0) is the bottom-left of the + terrain, and (1,1) is the top-right. The Z coordinate is in absolute + height units. + */ + void getTerrainPosition(Real x, Real y, Real z, Vector3* outTSpos) const; + /** Convert a position from terrain basis space to world space based on a specified alignment. + @param TSpos Terrain space position, where (0,0) is the bottom-left of the + terrain, and (1,1) is the top-right. The Z coordinate is in absolute + height units. + @param outWSpos World space output position (setup according to alignment). + */ + void getPositionAlign(const Vector3& TSpos, Alignment align, Vector3* outWSpos) const; + /** Convert a position from terrain basis space to world space based on a specified alignment. + @param x,y,z Terrain space position, where (0,0) is the bottom-left of the + terrain, and (1,1) is the top-right. The Z coordinate is in absolute + height units. + @param outWSpos World space output position (setup according to alignment). + */ + void getPositionAlign(Real x, Real y, Real z, Alignment align, Vector3* outWSpos) const; + + /** Convert a position from world space to terrain basis space based on a specified alignment. + @param WSpos World space position (setup according to alignment). + @param outTSpos Terrain space output position, where (0,0) is the bottom-left of the + terrain, and (1,1) is the top-right. The Z coordinate is in absolute + height units. + */ + void getTerrainPositionAlign(const Vector3& WSpos, Alignment align, Vector3* outTSpos) const; + /** Convert a position from world space to terrain basis space based on a specified alignment. + @param x,y,z World space position (setup according to alignment). + @param outTSpos Terrain space output position, where (0,0) is the bottom-left of the + terrain, and (1,1) is the top-right. The Z coordinate is in absolute + height units. + */ + void getTerrainPositionAlign(Real x, Real y, Real z, Alignment align, Vector3* outTSpos) const; + + + /// Get the alignment of the terrain + Alignment getAlignment() const; + /// Get the size of the terrain in vertices along one side + uint16 getSize() const; + /** Set the size of terrain in vertices along one side. + @note The existing height data will be bilinear filtered to fill the new size + @param newSize the new size of the terrain + */ void setSize(uint16 newSize); - /// Get the maximum size in vertices along one side of a batch - uint16 getMaxBatchSize() const; - /// Get the minimum size in vertices along one side of a batch - uint16 getMinBatchSize() const; - /// Get the size of the terrain in world units - Real getWorldSize() const; - /** Set the world size of terrain. - @param newWorldSize the new world size of the terrain - */ + /// Get the maximum size in vertices along one side of a batch + uint16 getMaxBatchSize() const; + /// Get the minimum size in vertices along one side of a batch + uint16 getMinBatchSize() const; + /// Get the size of the terrain in world units + Real getWorldSize() const; + /** Set the world size of terrain. + @param newWorldSize the new world size of the terrain + */ void setWorldSize(Real newWorldSize); - /** Get the number of layers in this terrain. */ - uint8 getLayerCount() const { return static_cast(mLayers.size()); } - - /** Get the declaration which describes the layers in this terrain. */ - const TerrainLayerDeclaration& getLayerDeclaration() const { return mLayerDecl; } - - /** Add a new layer to this terrain. - @param worldSize The size of the texture in this layer in world units. Default - to zero to use the default - @param textureNames A list of textures to assign to the samplers in this - layer. Leave blank to provide these later. - */ - void addLayer(Real worldSize = 0, const StringVector* textureNames = 0); - - /** Add a new layer to this terrain at a specific index. - @param index The index at which to insert this layer (existing layers are shifted forwards) - @param worldSize The size of the texture in this layer in world units. Default - to zero to use the default - @param textureNames A list of textures to assign to the samplers in this - layer. Leave blank to provide these later. - */ - void addLayer(uint8 index, Real worldSize = 0, const StringVector* textureNames = 0); - - /** Remove a layer from the terrain. - */ - void removeLayer(uint8 index); - - /** Replace an existing terrain layer, optionally preserving all other layer blend maps - @param index The 0 based index of the terrain layer to replace - @param keepBlends True to keep using the existing blend maps. False to reset the blend map for the layer. - Irrelevant if index == 0 - @param worldSize The size of the texture in this layer in world units. Default - to zero to use the default - @param textureNames A list of textures to assign to the samplers in this - layer. Leave blank to provide these later. - */ + /** Get the number of layers in this terrain. */ + uint8 getLayerCount() const { return static_cast(mLayers.size()); } + + /** Get the declaration which describes the layers in this terrain. */ + const TerrainLayerDeclaration& getLayerDeclaration() const { return mLayerDecl; } + + /** Add a new layer to this terrain. + @param worldSize The size of the texture in this layer in world units. Default + to zero to use the default + @param textureNames A list of textures to assign to the samplers in this + layer. Leave blank to provide these later. + */ + void addLayer(Real worldSize = 0, const StringVector* textureNames = 0); + + /** Add a new layer to this terrain at a specific index. + @param index The index at which to insert this layer (existing layers are shifted forwards) + @param worldSize The size of the texture in this layer in world units. Default + to zero to use the default + @param textureNames A list of textures to assign to the samplers in this + layer. Leave blank to provide these later. + */ + void addLayer(uint8 index, Real worldSize = 0, const StringVector* textureNames = 0); + + /** Remove a layer from the terrain. + */ + void removeLayer(uint8 index); + + /** Replace an existing terrain layer, optionally preserving all other layer blend maps + @param index The 0 based index of the terrain layer to replace + @param keepBlends True to keep using the existing blend maps. False to reset the blend map for the layer. + Irrelevant if index == 0 + @param worldSize The size of the texture in this layer in world units. Default + to zero to use the default + @param textureNames A list of textures to assign to the samplers in this + layer. Leave blank to provide these later. + */ void replaceLayer(uint8 index, bool keepBlends, Real worldSize = 0, const StringVector* textureNames = 0); - /** Get the maximum number of layers supported with the current options. - @note When you change the options requested, this value can change. - */ - uint8 getMaxLayers() const; - - /** How large an area in world space the texture in a terrain layer covers - before repeating. - @param index The layer index. - */ - Real getLayerWorldSize(uint8 index) const; - /** How large an area in world space the texture in a terrain layer covers - before repeating. - @param index The layer index. - @param size The world size of the texture before repeating - */ - void setLayerWorldSize(uint8 index, Real size); - - /** Get the layer UV multiplier. - @remarks - This is derived from the texture world size. The base UVs in the - terrain vary from 0 to 1 and this multiplier is used (in a fixed-function - texture coord scaling or a shader parameter) to translate it to the - final value. - @param index The layer index. - */ - Real getLayerUVMultiplier(uint8 index) const; - - /** Get the name of the texture bound to a given index within a given layer. - See the LayerDeclaration for a list of sampelrs within a layer. - @param layerIndex The layer index. - @param samplerIndex The sampler index within a layer - */ - const String& getLayerTextureName(uint8 layerIndex, uint8 samplerIndex) const; - /** Set the name of the texture bound to a given index within a given layer. - See the LayerDeclaration for a list of sampelrs within a layer. - @param layerIndex The layer index. - @param samplerIndex The sampler index within a layer - @param textureName The name of the texture to use - */ - void setLayerTextureName(uint8 layerIndex, uint8 samplerIndex, const String& textureName); - - /** Get the requested size of the blend maps used to blend between layers - for this terrain. - Note that where hardware limits this, the actual blend maps may be lower - resolution. This option is derived from TerrainGlobalOptions when the - terrain is created. - */ - uint16 getLayerBlendMapSize() const { return mLayerBlendMapSize; } - - /** Get the requested size of lightmap for this terrain. - Note that where hardware limits this, the actual lightmap may be lower - resolution. This option is derived from TerrainGlobalOptions when the - terrain is created. - */ - uint16 getLightmapSize() const { return mLightmapSize; } - - /// Get access to the lightmap, if enabled (as requested by the material generator) - const TexturePtr& getLightmap() const { return mLightmap; } - - /** Get the requested size of composite map for this terrain. - Note that where hardware limits this, the actual texture may be lower - resolution. This option is derived from TerrainGlobalOptions when the - terrain is created. - */ - uint16 getCompositeMapSize() const { return mCompositeMapSize; } - - /// Get access to the composite map, if enabled (as requested by the material generator) - const TexturePtr& getCompositeMap() const { return mCompositeMap; } - - /// Get the world position of the terrain centre - const Vector3& getPosition() const { return mPos; } - /// Set the position of the terrain centre in world coordinates - void setPosition(const Vector3& pos); - /// Get the root scene node for the terrain (internal use only) - SceneNode* _getRootSceneNode() const; - /** Mark the entire terrain as dirty. - By marking a section of the terrain as dirty, you are stating that you have - changed the height data within this rectangle. This rectangle will be merged with - any existing outstanding changes. To finalise the changes, you must - call update(), updateGeometry(), or updateDerivedData(). - */ - void dirty(); - - /** Mark a region of the terrain as dirty. - By marking a section of the terrain as dirty, you are stating that you have - changed the height data within this rectangle. This rectangle will be merged with - any existing outstanding changes. To finalise the changes, you must - call update(), updateGeometry(), or updateDerivedData(). - @param rect A rectangle expressed in vertices describing the dirty region; - left < right, top < bottom, left & top are inclusive, right & bottom exclusive - */ - void dirtyRect(const Rect& rect); - - /** Mark a region of the terrain composite map as dirty. - @remarks - You don't usually need to call this directly, it is inferred from - changing the other data on the terrain. - */ - void _dirtyCompositeMapRect(const Rect& rect); - - /** Mark a region of the lightmap as dirty. - @remarks - You only need to call this if you need to tell the terrain to update - the lightmap data for some reason other than the terrain geometry - has changed. Changing terrain geometry automatically dirties the - correct lightmap areas. - @note - The lightmap won't actually be updated until update() or updateDerivedData() - is called. - */ - void dirtyLightmapRect(const Rect& rect); - - /** Mark a the entire lightmap as dirty. - @remarks - You only need to call this if you need to tell the terrain to update - the lightmap data for some reason other than the terrain geometry - has changed. Changing terrain geometry automatically dirties the - correct lightmap areas. - @note - The lightmap won't actually be updated until update() or updateDerivedData() - is called. - */ - void dirtyLightmap(); - - /** Trigger the update process for the terrain. - @remarks - Updating the terrain will process any dirty sections of the terrain. - This may affect many things: -
      1. The terrain geometry
      2. -
      3. The terrain error metrics which determine LOD transitions
      4. -
      5. The terrain normal map, if present
      6. -
      7. The terrain lighting map, if present
      8. -
      9. The terrain composite map, if present
      10. -
      - If threading is enabled, only item 1 (the geometry) will be updated - synchronously, ie will be fully up to date when this method returns. - The other elements are more expensive to compute, and will be queued - for processing in a background thread, in the order shown above. As these - updates complete, the effects will be shown. - - You can also separate the timing of updating the geometry, LOD and the lighting - information if you want, by calling updateGeometry() and - updateDerivedData() separately. - @param synchronous If true, all updates will happen immediately and not - in a separate thread. - */ - void update(bool synchronous = false); - - /** Performs an update on the terrain geometry based on the dirty region. - @remarks - Terrain geometry will be updated when this method returns. - */ - void updateGeometry(); - /** Performs an update on the terrain geometry based on the dirty region. - @remarks - Terrain geometry will be updated when this method returns, and no - neighbours will be notified. - */ - void updateGeometryWithoutNotifyNeighbours(); - - // Used as a type mask for updateDerivedData - static const uint8 DERIVED_DATA_DELTAS; - static const uint8 DERIVED_DATA_NORMALS; - static const uint8 DERIVED_DATA_LIGHTMAP; - static const uint8 DERIVED_DATA_ALL; - - /** Updates derived data for the terrain (LOD, lighting) to reflect changed height data, in a separate - thread if threading is enabled (OGRE_THREAD_SUPPORT). - If threading is enabled, on return from this method the derived - data will not necessarily be updated immediately, the calculation - may be done in the background. Only one update will run in the background - at once. This derived data can typically survive being out of sync for a - few frames which is why it is not done synchronously - @param synchronous If true, the update will happen immediately and not - in a separate thread. - @param typeMask Mask indicating the types of data we should generate - */ - void updateDerivedData(bool synchronous = false, uint8 typeMask = 0xFF); - - /** Performs an update on the terrain composite map based on its dirty region. - @remarks - Rather than calling this directly, call updateDerivedData, which will - also call it after the other derived data has been updated (there is - no point updating the composite map until lighting has been updated). - However the blend maps may call this directly when only the blending - information has been updated. - */ - void updateCompositeMap(); - - /** Performs an update on the terrain composite map based on its dirty region, - but only at a maximum frequency. - @remarks - Rather than calling this directly, call updateDerivedData, which will - also call it after the other derived data has been updated (there is - no point updating the composite map until lighting has been updated). - However the blend maps may call this directly when only the blending - information has been updated. - @note - This method will log the request for an update, but won't do it just yet - unless there are no further requests in the next 'delay' seconds. This means - you can call it all the time but only pick up changes in quiet times. - */ - void updateCompositeMapWithDelay(Real delay = 2); - - - /** The default size of 'skirts' used to hide terrain cracks - (default 10, set for new Terrain using TerrainGlobalOptions) - */ - Real getSkirtSize() const { return mSkirtSize; } - - /// Get the total number of LOD levels in the terrain - uint16 getNumLodLevels() const { return mNumLodLevels; } - - /// Get the number of LOD levels in a leaf of the terrain quadtree - uint16 getNumLodLevelsPerLeaf() const { return mNumLodLevelsPerLeafNode; } - - /** Calculate (or recalculate) the delta values of heights between a vertex - in its recorded position, and the place it will end up in the LOD - in which it is removed. - @param rect Rectangle describing the area in which heights have altered - @return A Rectangle describing the area which was updated (may be wider - than the input rectangle) - */ - Rect calculateHeightDeltas(const Rect& rect); - - /** Finalise the height deltas. - Calculated height deltas are kept in a separate calculation field to make - them safe to perform in a background thread. This call promotes those - calculations to the runtime values, and must be called in the main thread. - @param rect Rectangle describing the area to finalise - @param cpuData When updating vertex data, update the CPU copy (background) - */ - void finaliseHeightDeltas(const Rect& rect, bool cpuData); - - /** Calculate (or recalculate) the normals on the terrain - @param rect Rectangle describing the area of heights that were changed - @param outFinalRect Output rectangle describing the area updated - @return Pointer to a PixelBox full of normals (caller responsible for deletion) - */ - PixelBox* calculateNormals(const Rect& rect, Rect& outFinalRect); - - /** Finalise the normals. - Calculated normals are kept in a separate calculation area to make - them safe to perform in a background thread. This call promotes those - calculations to the runtime values, and must be called in the main thread. - @param rect Rectangle describing the area to finalise - @param normalsBox Pointer to a PixelBox full of normals - */ - void finaliseNormals(const Rect& rect, PixelBox* normalsBox); - - /** Calculate (or recalculate) the terrain lightmap - @param rect Rectangle describing the area of heights that were changed - @param extraTargetRect Rectangle describing a target area of the terrain that - needs to be calculated additionally (e.g. from a neighbour) - @param outFinalRect Output rectangle describing the area updated in the lightmap - @return Pointer to a PixelBox full of lighting data (caller responsible for deletion) - */ - PixelBox* calculateLightmap(const Rect& rect, const Rect& extraTargetRect, Rect& outFinalRect); - - /** Finalise the lightmap. - Calculating lightmaps is kept in a separate calculation area to make - it safe to perform in a background thread. This call promotes those - calculations to the runtime values, and must be called in the main thread. - @param rect Rectangle describing the area to finalise - @param lightmapBox Pointer to a PixelBox full of normals - */ - void finaliseLightmap(const Rect& rect, PixelBox* lightmapBox); - - /** Gets the resolution of the entire terrain (down one edge) at a - given LOD level. - */ - uint16 getResolutionAtLod(uint16 lodLevel) const; - - /** Test for intersection of a given ray with the terrain. If the ray hits - the terrain, the point of intersection is returned. - @param ray The ray to test for intersection - @param cascadeToNeighbours Whether the ray will be projected onto neighbours if - no intersection is found - @param distanceLimit The distance from the ray origin at which we will stop looking, - 0 indicates no limit - @return A pair which contains whether the ray hit the terrain and, if so, where. - @remarks This can be called from any thread as long as no parallel write to - the heightmap data occurs. - */ - std::pair rayIntersects(const Ray& ray, - bool cascadeToNeighbours = false, Real distanceLimit = 0); //const; - - /// Get the AABB (local coords) of the entire terrain - const AxisAlignedBox& getAABB() const; - /// Get the AABB (world coords) of the entire terrain - AxisAlignedBox getWorldAABB() const; - /// Get the minimum height of the terrain - Real getMinHeight() const; - /// Get the maximum height of the terrain - Real getMaxHeight() const; - /// Get the bounding radius of the entire terrain - Real getBoundingRadius() const; - - /// Get the material being used for the terrain - const MaterialPtr& getMaterial() const; - /// Internal getting of material - const MaterialPtr& _getMaterial() const { return mMaterial; } - /// Get the material being used for the terrain composite map - const MaterialPtr& getCompositeMapMaterial() const; - /// Internal getting of material for the terrain composite map - const MaterialPtr& _getCompositeMapMaterial() const { return mCompositeMapMaterial; } - - /// Get the name of the material being used for the terrain - const String& getMaterialName() const { return mMaterialName; } - - /// Overridden from SceneManager::Listener - void preFindVisibleObjects(SceneManager* source, - SceneManager::IlluminationRenderStage irs, Viewport* v); - /// Overridden from SceneManager::Listener - void sceneManagerDestroyed(SceneManager* source); - - /// Get the render queue group that this terrain will be rendered into - uint8 getRenderQueueGroup(void) const { return mRenderQueueGroup; } - /** Set the render queue group that this terrain will be rendered into. - @remarks The default is specified in TerrainGlobalOptions - */ - void setRenderQueueGroup(uint8 grp) { mRenderQueueGroup = grp; } - - /// Get the visibility flags for this terrain. - uint32 getVisibilityFlags(void) const { return mVisibilityFlags; } - /** Set the visibility flags for this terrain. - @remarks The default is specified in TerrainGlobalOptions - */ - void setVisibilityFlags(uint32 flags) { mVisibilityFlags = flags; } - - /// Get the query flags for this terrain. - uint32 getQueryFlags(void) const { return mQueryFlags; } - /** Set the query flags for this terrain. - @remarks The default is specified in TerrainGlobalOptions - */ - void setQueryFlags(uint32 flags) { mQueryFlags = flags; } - - /** As setQueryFlags, except the flags passed as parameters are appended to the existing flags on this object. */ - void addQueryFlags(uint32 flags) { mQueryFlags |= flags; } - - /* As setQueryFlags, except the flags passed as parameters are removed from the existing flags on this object. */ - void removeQueryFlags(uint32 flags) { mQueryFlags &= ~flags; } - - - /** Retrieve the layer blending map for a given layer, which may - be used to edit the blending information for that layer. - @note - You can only do this after the terrain has been loaded. You may - edit the content of the blend layer in another thread, but you - may only upload it in the main render thread. - @param layerIndex The layer index, which should be 1 or higher (since - the bottom layer has no blending). - @return Pointer to the TerrainLayerBlendMap requested. The caller must - not delete this instance, use freeTemporaryResources if you want - to save the memory after completing your editing. - */ - TerrainLayerBlendMap* getLayerBlendMap(uint8 layerIndex); - - /** Get the index of the blend texture that a given layer uses. - @param layerIndex The layer index, must be >= 1 and less than the number - of layers - @return The index of the shared blend texture - */ - uint8 getBlendTextureIndex(uint8 layerIndex) const; - - /// Get the number of blend textures in use - uint8 getBlendTextureCount() const; - /// Get the number of blend textures needed for a given number of layers - uint8 getBlendTextureCount(uint8 numLayers) const; - - - /** Get the name of the packed blend texture at a specific index. - @param textureIndex This is the blend texture index, not the layer index - (multiple layers will share a blend texture) - */ - const String& getBlendTextureName(uint8 textureIndex) const; - - /** Set whether a global colour map is enabled. - @remarks - A global colour map can add variation to your terrain and reduce the - perceived tiling effect you might get in areas of continuous lighting - and the same texture. - The global colour map is only used when the material generator chooses - to use it. - @note You must only call this from the main render thread - @param enabled Whether the global colour map is enabled or not - @param size The resolution of the colour map. A value of zero means 'no change' - and the default is set in TerrainGlobalOptions. - */ - void setGlobalColourMapEnabled(bool enabled, uint16 size = 0); - /// Get whether a global colour map is enabled on this terrain - bool getGlobalColourMapEnabled() const { return mGlobalColourMapEnabled; } - /// Get the size of the global colour map (if used) - uint16 getGlobalColourMapSize() const { return mGlobalColourMapSize; } - /// Get access to the global colour map, if enabled - const TexturePtr& getGlobalColourMap() const { return mColourMap; } - - /** Widen a rectangular area of terrain to take into account an extrusion vector. - @param vec A vector in world space - @param inRect Input rectangle - @param outRect Output rectangle - */ - void widenRectByVector(const Vector3& vec, const Rect& inRect, Rect& outRect); - - /** Widen a rectangular area of terrain to take into account an extrusion vector, - but specify the min / max heights to extrude manually. - @param vec A vector in world space - @param inRect Input rectangle - @param minHeight, maxHeight The extents of the height to extrude - @param outRect Output rectangle - */ - void widenRectByVector(const Vector3& vec, const Rect& inRect, - Real minHeight, Real maxHeight, Rect& outRect); - - /** Free as many resources as possible for optimal run-time memory use. - @remarks - This class keeps some temporary storage around in order to make - certain actions (such as editing) possible more quickly. Calling this - method will cause as many of those resources as possible to be - freed. You might want to do this for example when you are finished - editing a particular terrain and want to have optimal runtime - efficiency. - */ - void freeTemporaryResources(); - - /** Get a blend texture with a given index. - @param index The blend texture index (note: not layer index; derive - the texture index from getLayerBlendTextureIndex) - */ - const TexturePtr& getLayerBlendTexture(uint8 index) const; - - /** Get the texture index and colour channel of the blend information for - a given layer. - @param layerIndex The index of the layer (1 or higher, layer 0 has no blend data) - @return A pair in which the first value is the texture index, and the - second value is the colour channel (RGBA) - */ - std::pair getLayerBlendTextureIndex(uint8 layerIndex) const; - - /** Request internal implementation options for the terrain material to use, - in this case vertex morphing information. - The TerrainMaterialGenerator should call this method to specify the - options it would like to use when creating a material. Not all the data - is guaranteed to be up to date on return from this method - for example som - maps may be generated in the background. However, on return from this method - all the features that are requested will be referenceable by materials, the - data may just take a few frames to be fully populated. - @param morph Whether LOD morphing information is required to be calculated - */ - void _setMorphRequired(bool morph) { mLodMorphRequired = morph; } - /// Get whether LOD morphing is needed - bool _getMorphRequired() const { return mLodMorphRequired; } - - /** Request internal implementation options for the terrain material to use, - in this case a terrain-wide normal map. - The TerrainMaterialGenerator should call this method to specify the - options it would like to use when creating a material. Not all the data - is guaranteed to be up to date on return from this method - for example some - maps may be generated in the background. However, on return from this method - all the features that are requested will be referenceable by materials, the - data may just take a few frames to be fully populated. - @param normalMap Whether a terrain-wide normal map is requested. This is usually - mutually exclusive with the lightmap option. - */ - void _setNormalMapRequired(bool normalMap); - - /** Request internal implementation options for the terrain material to use, - in this case a terrain-wide normal map. - The TerrainMaterialGenerator should call this method to specify the - options it would like to use when creating a material. Not all the data - is guaranteed to be up to date on return from this method - for example some - maps may be generated in the background. However, on return from this method - all the features that are requested will be referenceable by materials, the - data may just take a few frames to be fully populated. - @param lightMap Whether a terrain-wide lightmap including precalculated - lighting is required (light direction in TerrainGlobalOptions) - @param shadowsOnly If true, the lightmap contains only shadows, - no directional lighting intensity - */ - void _setLightMapRequired(bool lightMap, bool shadowsOnly = false); - - /** Request internal implementation options for the terrain material to use, - in this case a terrain-wide composite map. - The TerrainMaterialGenerator should call this method to specify the - options it would like to use when creating a material. Not all the data - is guaranteed to be up to date on return from this method - for example some - maps may be generated in the background. However, on return from this method - all the features that are requested will be referenceable by materials, the - data may just take a few frames to be fully populated. - @param compositeMap Whether a terrain-wide composite map is needed. A composite - map is a texture with all of the blending and lighting baked in, such that - at distance this texture can be used as an approximation of the multi-layer - blended material. It is actually up to the material generator to render this - composite map, because obviously precisely what it looks like depends on what - the main material looks like. For this reason, the composite map is one piece - of derived terrain data that is always calculated in the render thread, and - usually on the GPU. It is expected that if this option is requested, - the material generator will use it to construct distant LOD techniques. - */ - void _setCompositeMapRequired(bool compositeMap); - - /// Whether we're using vertex compression or not - bool _getUseVertexCompression() const; - - /// WorkQueue::RequestHandler override - bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); - /// WorkQueue::RequestHandler override - WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); - /// WorkQueue::ResponseHandler override - bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - /// WorkQueue::ResponseHandler override - void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - /// Handler for GenerateMaterial - void handleGenerateMaterialResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - - static const uint16 WORKQUEUE_DERIVED_DATA_REQUEST; - static const uint16 WORKQUEUE_GENERATE_MATERIAL_REQUEST; - - /// Utility method, get the first LOD Level at which this vertex is no longer included - uint16 getLODLevelWhenVertexEliminated(long x, long y) const; - /// Utility method, get the first LOD Level at which this vertex is no longer included - uint16 getLODLevelWhenVertexEliminated(long rowOrColulmn) const; - - - /// Get the top level of the quad tree which is used to divide up the terrain - TerrainQuadTreeNode* getQuadTree() { return mQuadTree; } - - /// Get the (global) normal map texture - TexturePtr getTerrainNormalMap() const { return mTerrainNormalMap; } - - /** Retrieve the terrain's neighbour, or null if not present. - @remarks - Terrains only know about their neighbours if they are notified via - setNeighbour. This information is not saved with the terrain since every - tile must be able to be independent. - @param index The index of the neighbour - */ - Terrain* getNeighbour(NeighbourIndex index) const; - - /** Set a terrain's neighbour, or null to detach one. - @remarks - This information is not saved with the terrain since every - tile must be able to be independent. However if modifications are - made to a tile which can affect its neighbours, while connected the - changes will be propagated. - @param index The index of the neighbour - @param neighbour The terrain instance to become the neighbour, or null to reset. - @param recalculate If true, this terrain instance will recalculate elements - that could be affected by the connection of this tile (e.g. matching - heights, calcaulting normals, calculating shadows crossing the boundary). - If false, this terrain's state is assumed to be up to date already - (e.g. was calculated with this tile present before and the state saved). - @param notifyOther Whether the neighbour should also be notified (recommended - to leave this at the default so relationships are up to date before - background updates are triggered) - */ - void setNeighbour(NeighbourIndex index, Terrain* neighbour, bool recalculate = false, bool notifyOther = true); - - /** Get the opposite neighbour relationship (useful for finding the - neighbour index from the perspective of the tile the other side of the - boundary). - */ - static NeighbourIndex getOppositeNeighbour(NeighbourIndex index); - - /** Get the neighbour enum for a given offset in a grid (signed). - */ - static NeighbourIndex getNeighbourIndex(long offsetx, long offsety); - - /** Tell this instance to notify all neighbours that will be affected - by a height change that has taken place. - @remarks - This method will determine which neighbours need notification and call - their neighbourModified method. It is called automatically by - updateGeometry(). - */ - void notifyNeighbours(); - - /** Notify that a neighbour has just finished updating and that this - change affects this tile. - @param index The neighbour index (from this tile's perspective) - @param edgerect The area at the edge of this tile that needs height / normal - recalculation (may be null) - @param shadowrect The area on this tile where shadows need recalculating (may be null) - */ - void neighbourModified(NeighbourIndex index, const Rect& edgerect, const Rect& shadowrect); - - /** Utility method to pick a neighbour based on a ray. - @param ray The ray in world space - @param distanceLimit Limit beyond which we want to ignore neighbours (0 for infinite) - @return The first neighbour along this ray, or null - */ - Terrain* raySelectNeighbour(const Ray& ray, Real distanceLimit = 0); - - /** Dump textures to files. - @remarks - This is a debugging method. - */ - void _dumpTextures(const String& prefix, const String& suffix); - - /** Query whether a derived data update is in progress or not. */ - bool isDerivedDataUpdateInProgress() const { return mDerivedDataUpdateInProgress; } - - - /// Utility method to convert axes from world space to terrain space (xy terrain, z up) - static void convertWorldToTerrainAxes(Alignment align, const Vector3& worldVec, Vector3* terrainVec); - /// Utility method to convert axes from terrain space (xy terrain, z up) tp world space - static void convertTerrainToWorldAxes(Alignment align, const Vector3& terrainVec, Vector3* worldVec); - - /// Utility method to write a layer declaration to a stream - static void writeLayerDeclaration(const TerrainLayerDeclaration& decl, StreamSerialiser& ser); - /// Utility method to read a layer declaration from a stream - static bool readLayerDeclaration(StreamSerialiser& ser, TerrainLayerDeclaration& targetdecl); - /// Utility method to write a layer instance list to a stream - static void writeLayerInstanceList(const Terrain::LayerInstanceList& lst, StreamSerialiser& ser); - /// Utility method to read a layer instance list from a stream - static bool readLayerInstanceList(StreamSerialiser& ser, size_t numSamplers, Terrain::LayerInstanceList& targetlst); - - // This mutex is write-locked by neighbours if they are in the process of deleting themselves. - // It should be read-locked whenever using neighbours in calculations which are possibly running in a - // background thread. - OGRE_RW_MUTEX(mNeighbourMutex); - - protected: - /** Gets the data size at a given LOD level. - */ - uint getGeoDataSizeAtLod(uint16 lodLevel) const; + /** Get the maximum number of layers supported with the current options. + @note When you change the options requested, this value can change. + */ + uint8 getMaxLayers() const; + + /** How large an area in world space the texture in a terrain layer covers + before repeating. + @param index The layer index. + */ + Real getLayerWorldSize(uint8 index) const; + /** How large an area in world space the texture in a terrain layer covers + before repeating. + @param index The layer index. + @param size The world size of the texture before repeating + */ + void setLayerWorldSize(uint8 index, Real size); + + /** Get the layer UV multiplier. + @remarks + This is derived from the texture world size. The base UVs in the + terrain vary from 0 to 1 and this multiplier is used (in a fixed-function + texture coord scaling or a shader parameter) to translate it to the + final value. + @param index The layer index. + */ + Real getLayerUVMultiplier(uint8 index) const; + + /** Get the name of the texture bound to a given index within a given layer. + See the LayerDeclaration for a list of sampelrs within a layer. + @param layerIndex The layer index. + @param samplerIndex The sampler index within a layer + */ + const String& getLayerTextureName(uint8 layerIndex, uint8 samplerIndex) const; + /** Set the name of the texture bound to a given index within a given layer. + See the LayerDeclaration for a list of sampelrs within a layer. + @param layerIndex The layer index. + @param samplerIndex The sampler index within a layer + @param textureName The name of the texture to use + */ + void setLayerTextureName(uint8 layerIndex, uint8 samplerIndex, const String& textureName); + + /** Get the requested size of the blend maps used to blend between layers + for this terrain. + Note that where hardware limits this, the actual blend maps may be lower + resolution. This option is derived from TerrainGlobalOptions when the + terrain is created. + */ + uint16 getLayerBlendMapSize() const { return mLayerBlendMapSize; } + + /** Get the requested size of lightmap for this terrain. + Note that where hardware limits this, the actual lightmap may be lower + resolution. This option is derived from TerrainGlobalOptions when the + terrain is created. + */ + uint16 getLightmapSize() const { return mLightmapSize; } + + /// Get access to the lightmap, if enabled (as requested by the material generator) + const TexturePtr& getLightmap() const { return mLightmap; } + + /** Get the requested size of composite map for this terrain. + Note that where hardware limits this, the actual texture may be lower + resolution. This option is derived from TerrainGlobalOptions when the + terrain is created. + */ + uint16 getCompositeMapSize() const { return mCompositeMapSize; } + + /// Get access to the composite map, if enabled (as requested by the material generator) + const TexturePtr& getCompositeMap() const { return mCompositeMap; } + + /// Get the world position of the terrain centre + const Vector3& getPosition() const { return mPos; } + /// Set the position of the terrain centre in world coordinates + void setPosition(const Vector3& pos); + /// Get the root scene node for the terrain (internal use only) + SceneNode* _getRootSceneNode() const; + /** Mark the entire terrain as dirty. + By marking a section of the terrain as dirty, you are stating that you have + changed the height data within this rectangle. This rectangle will be merged with + any existing outstanding changes. To finalise the changes, you must + call update(), updateGeometry(), or updateDerivedData(). + */ + void dirty(); + + /** Mark a region of the terrain as dirty. + By marking a section of the terrain as dirty, you are stating that you have + changed the height data within this rectangle. This rectangle will be merged with + any existing outstanding changes. To finalise the changes, you must + call update(), updateGeometry(), or updateDerivedData(). + @param rect A rectangle expressed in vertices describing the dirty region; + left < right, top < bottom, left & top are inclusive, right & bottom exclusive + */ + void dirtyRect(const Rect& rect); + + /** Mark a region of the terrain composite map as dirty. + @remarks + You don't usually need to call this directly, it is inferred from + changing the other data on the terrain. + */ + void _dirtyCompositeMapRect(const Rect& rect); + + /** Mark a region of the lightmap as dirty. + @remarks + You only need to call this if you need to tell the terrain to update + the lightmap data for some reason other than the terrain geometry + has changed. Changing terrain geometry automatically dirties the + correct lightmap areas. + @note + The lightmap won't actually be updated until update() or updateDerivedData() + is called. + */ + void dirtyLightmapRect(const Rect& rect); + + /** Mark a the entire lightmap as dirty. + @remarks + You only need to call this if you need to tell the terrain to update + the lightmap data for some reason other than the terrain geometry + has changed. Changing terrain geometry automatically dirties the + correct lightmap areas. + @note + The lightmap won't actually be updated until update() or updateDerivedData() + is called. + */ + void dirtyLightmap(); + + /** Trigger the update process for the terrain. + @remarks + Updating the terrain will process any dirty sections of the terrain. + This may affect many things: +
      1. The terrain geometry
      2. +
      3. The terrain error metrics which determine LOD transitions
      4. +
      5. The terrain normal map, if present
      6. +
      7. The terrain lighting map, if present
      8. +
      9. The terrain composite map, if present
      10. +
      + If threading is enabled, only item 1 (the geometry) will be updated + synchronously, ie will be fully up to date when this method returns. + The other elements are more expensive to compute, and will be queued + for processing in a background thread, in the order shown above. As these + updates complete, the effects will be shown. + + You can also separate the timing of updating the geometry, LOD and the lighting + information if you want, by calling updateGeometry() and + updateDerivedData() separately. + @param synchronous If true, all updates will happen immediately and not + in a separate thread. + */ + void update(bool synchronous = false); + + /** Performs an update on the terrain geometry based on the dirty region. + @remarks + Terrain geometry will be updated when this method returns. + */ + void updateGeometry(); + /** Performs an update on the terrain geometry based on the dirty region. + @remarks + Terrain geometry will be updated when this method returns, and no + neighbours will be notified. + */ + void updateGeometryWithoutNotifyNeighbours(); + + // Used as a type mask for updateDerivedData + static const uint8 DERIVED_DATA_DELTAS; + static const uint8 DERIVED_DATA_NORMALS; + static const uint8 DERIVED_DATA_LIGHTMAP; + static const uint8 DERIVED_DATA_ALL; + + /** Updates derived data for the terrain (LOD, lighting) to reflect changed height data, in a separate + thread if threading is enabled (OGRE_THREAD_SUPPORT). + If threading is enabled, on return from this method the derived + data will not necessarily be updated immediately, the calculation + may be done in the background. Only one update will run in the background + at once. This derived data can typically survive being out of sync for a + few frames which is why it is not done synchronously + @param synchronous If true, the update will happen immediately and not + in a separate thread. + @param typeMask Mask indicating the types of data we should generate + */ + void updateDerivedData(bool synchronous = false, uint8 typeMask = 0xFF); + + /** Performs an update on the terrain composite map based on its dirty region. + @remarks + Rather than calling this directly, call updateDerivedData, which will + also call it after the other derived data has been updated (there is + no point updating the composite map until lighting has been updated). + However the blend maps may call this directly when only the blending + information has been updated. + */ + void updateCompositeMap(); + + /** Performs an update on the terrain composite map based on its dirty region, + but only at a maximum frequency. + @remarks + Rather than calling this directly, call updateDerivedData, which will + also call it after the other derived data has been updated (there is + no point updating the composite map until lighting has been updated). + However the blend maps may call this directly when only the blending + information has been updated. + @note + This method will log the request for an update, but won't do it just yet + unless there are no further requests in the next 'delay' seconds. This means + you can call it all the time but only pick up changes in quiet times. + */ + void updateCompositeMapWithDelay(Real delay = 2); + + + /** The default size of 'skirts' used to hide terrain cracks + (default 10, set for new Terrain using TerrainGlobalOptions) + */ + Real getSkirtSize() const { return mSkirtSize; } + + /// Get the total number of LOD levels in the terrain + uint16 getNumLodLevels() const { return mNumLodLevels; } + + /// Get the number of LOD levels in a leaf of the terrain quadtree + uint16 getNumLodLevelsPerLeaf() const { return mNumLodLevelsPerLeafNode; } + + /** Calculate (or recalculate) the delta values of heights between a vertex + in its recorded position, and the place it will end up in the LOD + in which it is removed. + @param rect Rectangle describing the area in which heights have altered + @return A Rectangle describing the area which was updated (may be wider + than the input rectangle) + */ + Rect calculateHeightDeltas(const Rect& rect); + + /** Finalise the height deltas. + Calculated height deltas are kept in a separate calculation field to make + them safe to perform in a background thread. This call promotes those + calculations to the runtime values, and must be called in the main thread. + @param rect Rectangle describing the area to finalise + @param cpuData When updating vertex data, update the CPU copy (background) + */ + void finaliseHeightDeltas(const Rect& rect, bool cpuData); + + /** Calculate (or recalculate) the normals on the terrain + @param rect Rectangle describing the area of heights that were changed + @param outFinalRect Output rectangle describing the area updated + @return Pointer to a PixelBox full of normals (caller responsible for deletion) + */ + PixelBox* calculateNormals(const Rect& rect, Rect& outFinalRect); + + /** Finalise the normals. + Calculated normals are kept in a separate calculation area to make + them safe to perform in a background thread. This call promotes those + calculations to the runtime values, and must be called in the main thread. + @param rect Rectangle describing the area to finalise + @param normalsBox Pointer to a PixelBox full of normals + */ + void finaliseNormals(const Rect& rect, PixelBox* normalsBox); + + /** Calculate (or recalculate) the terrain lightmap + @param rect Rectangle describing the area of heights that were changed + @param extraTargetRect Rectangle describing a target area of the terrain that + needs to be calculated additionally (e.g. from a neighbour) + @param outFinalRect Output rectangle describing the area updated in the lightmap + @return Pointer to a PixelBox full of lighting data (caller responsible for deletion) + */ + PixelBox* calculateLightmap(const Rect& rect, const Rect& extraTargetRect, Rect& outFinalRect); + + /** Finalise the lightmap. + Calculating lightmaps is kept in a separate calculation area to make + it safe to perform in a background thread. This call promotes those + calculations to the runtime values, and must be called in the main thread. + @param rect Rectangle describing the area to finalise + @param lightmapBox Pointer to a PixelBox full of normals + */ + void finaliseLightmap(const Rect& rect, PixelBox* lightmapBox); + + /** Gets the resolution of the entire terrain (down one edge) at a + given LOD level. + */ + uint16 getResolutionAtLod(uint16 lodLevel) const; + + /** Test for intersection of a given ray with the terrain. If the ray hits + the terrain, the point of intersection is returned. + @param ray The ray to test for intersection + @param cascadeToNeighbours Whether the ray will be projected onto neighbours if + no intersection is found + @param distanceLimit The distance from the ray origin at which we will stop looking, + 0 indicates no limit + @return A pair which contains whether the ray hit the terrain and, if so, where. + @remarks This can be called from any thread as long as no parallel write to + the heightmap data occurs. + */ + std::pair rayIntersects(const Ray& ray, + bool cascadeToNeighbours = false, Real distanceLimit = 0); //const; + + /// Get the AABB (local coords) of the entire terrain + const AxisAlignedBox& getAABB() const; + /// Get the AABB (world coords) of the entire terrain + AxisAlignedBox getWorldAABB() const; + /// Get the minimum height of the terrain + Real getMinHeight() const; + /// Get the maximum height of the terrain + Real getMaxHeight() const; + /// Get the bounding radius of the entire terrain + Real getBoundingRadius() const; + + /// Get the material being used for the terrain + const MaterialPtr& getMaterial() const; + /// Internal getting of material + const MaterialPtr& _getMaterial() const { return mMaterial; } + /// Get the material being used for the terrain composite map + const MaterialPtr& getCompositeMapMaterial() const; + /// Internal getting of material for the terrain composite map + const MaterialPtr& _getCompositeMapMaterial() const { return mCompositeMapMaterial; } + + /// Get the name of the material being used for the terrain + const String& getMaterialName() const { return mMaterialName; } + + /// Overridden from SceneManager::Listener + void preFindVisibleObjects(SceneManager* source, + SceneManager::IlluminationRenderStage irs, Viewport* v); + /// Overridden from SceneManager::Listener + void sceneManagerDestroyed(SceneManager* source); + + /// Get the render queue group that this terrain will be rendered into + uint8 getRenderQueueGroup(void) const { return mRenderQueueGroup; } + /** Set the render queue group that this terrain will be rendered into. + @remarks The default is specified in TerrainGlobalOptions + */ + void setRenderQueueGroup(uint8 grp) { mRenderQueueGroup = grp; } + + /// Get the visibility flags for this terrain. + uint32 getVisibilityFlags(void) const { return mVisibilityFlags; } + /** Set the visibility flags for this terrain. + @remarks The default is specified in TerrainGlobalOptions + */ + void setVisibilityFlags(uint32 flags) { mVisibilityFlags = flags; } + + /// Get the query flags for this terrain. + uint32 getQueryFlags(void) const { return mQueryFlags; } + /** Set the query flags for this terrain. + @remarks The default is specified in TerrainGlobalOptions + */ + void setQueryFlags(uint32 flags) { mQueryFlags = flags; } + + /** As setQueryFlags, except the flags passed as parameters are appended to the existing flags on this object. */ + void addQueryFlags(uint32 flags) { mQueryFlags |= flags; } + + /* As setQueryFlags, except the flags passed as parameters are removed from the existing flags on this object. */ + void removeQueryFlags(uint32 flags) { mQueryFlags &= ~flags; } + + + /** Retrieve the layer blending map for a given layer, which may + be used to edit the blending information for that layer. + @note + You can only do this after the terrain has been loaded. You may + edit the content of the blend layer in another thread, but you + may only upload it in the main render thread. + @param layerIndex The layer index, which should be 1 or higher (since + the bottom layer has no blending). + @return Pointer to the TerrainLayerBlendMap requested. The caller must + not delete this instance, use freeTemporaryResources if you want + to save the memory after completing your editing. + */ + TerrainLayerBlendMap* getLayerBlendMap(uint8 layerIndex); + + /** Get the index of the blend texture that a given layer uses. + @param layerIndex The layer index, must be >= 1 and less than the number + of layers + @return The index of the shared blend texture + */ + uint8 getBlendTextureIndex(uint8 layerIndex) const; + + /// Get the number of blend textures in use + uint8 getBlendTextureCount() const; + /// Get the number of blend textures needed for a given number of layers + uint8 getBlendTextureCount(uint8 numLayers) const; + + + /** Get the name of the packed blend texture at a specific index. + @param textureIndex This is the blend texture index, not the layer index + (multiple layers will share a blend texture) + */ + const String& getBlendTextureName(uint8 textureIndex) const; + + /** Set whether a global colour map is enabled. + @remarks + A global colour map can add variation to your terrain and reduce the + perceived tiling effect you might get in areas of continuous lighting + and the same texture. + The global colour map is only used when the material generator chooses + to use it. + @note You must only call this from the main render thread + @param enabled Whether the global colour map is enabled or not + @param size The resolution of the colour map. A value of zero means 'no change' + and the default is set in TerrainGlobalOptions. + */ + void setGlobalColourMapEnabled(bool enabled, uint16 size = 0); + /// Get whether a global colour map is enabled on this terrain + bool getGlobalColourMapEnabled() const { return mGlobalColourMapEnabled; } + /// Get the size of the global colour map (if used) + uint16 getGlobalColourMapSize() const { return mGlobalColourMapSize; } + /// Get access to the global colour map, if enabled + const TexturePtr& getGlobalColourMap() const { return mColourMap; } + + /** Widen a rectangular area of terrain to take into account an extrusion vector. + @param vec A vector in world space + @param inRect Input rectangle + @param outRect Output rectangle + */ + void widenRectByVector(const Vector3& vec, const Rect& inRect, Rect& outRect); + + /** Widen a rectangular area of terrain to take into account an extrusion vector, + but specify the min / max heights to extrude manually. + @param vec A vector in world space + @param inRect Input rectangle + @param minHeight, maxHeight The extents of the height to extrude + @param outRect Output rectangle + */ + void widenRectByVector(const Vector3& vec, const Rect& inRect, + Real minHeight, Real maxHeight, Rect& outRect); + + /** Free as many resources as possible for optimal run-time memory use. + @remarks + This class keeps some temporary storage around in order to make + certain actions (such as editing) possible more quickly. Calling this + method will cause as many of those resources as possible to be + freed. You might want to do this for example when you are finished + editing a particular terrain and want to have optimal runtime + efficiency. + */ + void freeTemporaryResources(); + + /** Get a blend texture with a given index. + @param index The blend texture index (note: not layer index; derive + the texture index from getLayerBlendTextureIndex) + */ + const TexturePtr& getLayerBlendTexture(uint8 index) const; + + /** Get the texture index and colour channel of the blend information for + a given layer. + @param layerIndex The index of the layer (1 or higher, layer 0 has no blend data) + @return A pair in which the first value is the texture index, and the + second value is the colour channel (RGBA) + */ + std::pair getLayerBlendTextureIndex(uint8 layerIndex) const; + + /** Request internal implementation options for the terrain material to use, + in this case vertex morphing information. + The TerrainMaterialGenerator should call this method to specify the + options it would like to use when creating a material. Not all the data + is guaranteed to be up to date on return from this method - for example som + maps may be generated in the background. However, on return from this method + all the features that are requested will be referenceable by materials, the + data may just take a few frames to be fully populated. + @param morph Whether LOD morphing information is required to be calculated + */ + void _setMorphRequired(bool morph) { mLodMorphRequired = morph; } + /// Get whether LOD morphing is needed + bool _getMorphRequired() const { return mLodMorphRequired; } + + /** Request internal implementation options for the terrain material to use, + in this case a terrain-wide normal map. + The TerrainMaterialGenerator should call this method to specify the + options it would like to use when creating a material. Not all the data + is guaranteed to be up to date on return from this method - for example some + maps may be generated in the background. However, on return from this method + all the features that are requested will be referenceable by materials, the + data may just take a few frames to be fully populated. + @param normalMap Whether a terrain-wide normal map is requested. This is usually + mutually exclusive with the lightmap option. + */ + void _setNormalMapRequired(bool normalMap); + + /** Request internal implementation options for the terrain material to use, + in this case a terrain-wide normal map. + The TerrainMaterialGenerator should call this method to specify the + options it would like to use when creating a material. Not all the data + is guaranteed to be up to date on return from this method - for example some + maps may be generated in the background. However, on return from this method + all the features that are requested will be referenceable by materials, the + data may just take a few frames to be fully populated. + @param lightMap Whether a terrain-wide lightmap including precalculated + lighting is required (light direction in TerrainGlobalOptions) + @param shadowsOnly If true, the lightmap contains only shadows, + no directional lighting intensity + */ + void _setLightMapRequired(bool lightMap, bool shadowsOnly = false); + + /** Request internal implementation options for the terrain material to use, + in this case a terrain-wide composite map. + The TerrainMaterialGenerator should call this method to specify the + options it would like to use when creating a material. Not all the data + is guaranteed to be up to date on return from this method - for example some + maps may be generated in the background. However, on return from this method + all the features that are requested will be referenceable by materials, the + data may just take a few frames to be fully populated. + @param compositeMap Whether a terrain-wide composite map is needed. A composite + map is a texture with all of the blending and lighting baked in, such that + at distance this texture can be used as an approximation of the multi-layer + blended material. It is actually up to the material generator to render this + composite map, because obviously precisely what it looks like depends on what + the main material looks like. For this reason, the composite map is one piece + of derived terrain data that is always calculated in the render thread, and + usually on the GPU. It is expected that if this option is requested, + the material generator will use it to construct distant LOD techniques. + */ + void _setCompositeMapRequired(bool compositeMap); + + /// Whether we're using vertex compression or not + bool _getUseVertexCompression() const; + + /// WorkQueue::RequestHandler override + bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + /// WorkQueue::RequestHandler override + WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + /// WorkQueue::ResponseHandler override + bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + /// WorkQueue::ResponseHandler override + void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + /// Handler for GenerateMaterial + void handleGenerateMaterialResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + + static const uint16 WORKQUEUE_DERIVED_DATA_REQUEST; + static const uint16 WORKQUEUE_GENERATE_MATERIAL_REQUEST; + + /// Utility method, get the first LOD Level at which this vertex is no longer included + uint16 getLODLevelWhenVertexEliminated(long x, long y) const; + /// Utility method, get the first LOD Level at which this vertex is no longer included + uint16 getLODLevelWhenVertexEliminated(long rowOrColulmn) const; + + + /// Get the top level of the quad tree which is used to divide up the terrain + TerrainQuadTreeNode* getQuadTree() { return mQuadTree; } + + /// Get the (global) normal map texture + TexturePtr getTerrainNormalMap() const { return mTerrainNormalMap; } + + /** Retrieve the terrain's neighbour, or null if not present. + @remarks + Terrains only know about their neighbours if they are notified via + setNeighbour. This information is not saved with the terrain since every + tile must be able to be independent. + @param index The index of the neighbour + */ + Terrain* getNeighbour(NeighbourIndex index) const; + + /** Set a terrain's neighbour, or null to detach one. + @remarks + This information is not saved with the terrain since every + tile must be able to be independent. However if modifications are + made to a tile which can affect its neighbours, while connected the + changes will be propagated. + @param index The index of the neighbour + @param neighbour The terrain instance to become the neighbour, or null to reset. + @param recalculate If true, this terrain instance will recalculate elements + that could be affected by the connection of this tile (e.g. matching + heights, calcaulting normals, calculating shadows crossing the boundary). + If false, this terrain's state is assumed to be up to date already + (e.g. was calculated with this tile present before and the state saved). + @param notifyOther Whether the neighbour should also be notified (recommended + to leave this at the default so relationships are up to date before + background updates are triggered) + */ + void setNeighbour(NeighbourIndex index, Terrain* neighbour, bool recalculate = false, bool notifyOther = true); + + /** Get the opposite neighbour relationship (useful for finding the + neighbour index from the perspective of the tile the other side of the + boundary). + */ + static NeighbourIndex getOppositeNeighbour(NeighbourIndex index); + + /** Get the neighbour enum for a given offset in a grid (signed). + */ + static NeighbourIndex getNeighbourIndex(long offsetx, long offsety); + + /** Tell this instance to notify all neighbours that will be affected + by a height change that has taken place. + @remarks + This method will determine which neighbours need notification and call + their neighbourModified method. It is called automatically by + updateGeometry(). + */ + void notifyNeighbours(); + + /** Notify that a neighbour has just finished updating and that this + change affects this tile. + @param index The neighbour index (from this tile's perspective) + @param edgerect The area at the edge of this tile that needs height / normal + recalculation (may be null) + @param shadowrect The area on this tile where shadows need recalculating (may be null) + */ + void neighbourModified(NeighbourIndex index, const Rect& edgerect, const Rect& shadowrect); + + /** Utility method to pick a neighbour based on a ray. + @param ray The ray in world space + @param distanceLimit Limit beyond which we want to ignore neighbours (0 for infinite) + @return The first neighbour along this ray, or null + */ + Terrain* raySelectNeighbour(const Ray& ray, Real distanceLimit = 0); + + /** Dump textures to files. + @remarks + This is a debugging method. + */ + void _dumpTextures(const String& prefix, const String& suffix); + + /** Query whether a derived data update is in progress or not. */ + bool isDerivedDataUpdateInProgress() const { return mDerivedDataUpdateInProgress; } + + + /// Utility method to convert axes from world space to terrain space (xy terrain, z up) + static void convertWorldToTerrainAxes(Alignment align, const Vector3& worldVec, Vector3* terrainVec); + /// Utility method to convert axes from terrain space (xy terrain, z up) tp world space + static void convertTerrainToWorldAxes(Alignment align, const Vector3& terrainVec, Vector3* worldVec); + + /// Utility method to write a layer declaration to a stream + static void writeLayerDeclaration(const TerrainLayerDeclaration& decl, StreamSerialiser& ser); + /// Utility method to read a layer declaration from a stream + static bool readLayerDeclaration(StreamSerialiser& ser, TerrainLayerDeclaration& targetdecl); + /// Utility method to write a layer instance list to a stream + static void writeLayerInstanceList(const Terrain::LayerInstanceList& lst, StreamSerialiser& ser); + /// Utility method to read a layer instance list from a stream + static bool readLayerInstanceList(StreamSerialiser& ser, size_t numSamplers, Terrain::LayerInstanceList& targetlst); + + // This mutex is write-locked by neighbours if they are in the process of deleting themselves. + // It should be read-locked whenever using neighbours in calculations which are possibly running in a + // background thread. + OGRE_RW_MUTEX(mNeighbourMutex); + + protected: + /** Gets the data size at a given LOD level. + */ + uint getGeoDataSizeAtLod(uint16 lodLevel) const; /** Get the real lod level @param lodLevel LOD level which can be negative. @note After mapping, [-mNumLodLevels, -1] equals to [0,mNumLodLevels-1] @@ -1656,37 +1656,37 @@ namespace Ogre */ inline int getPositiveLodLevel( int lodLevel ) const { - return (lodLevel>=0) ? lodLevel : mNumLodLevels+lodLevel; + return (lodLevel>=0) ? lodLevel : mNumLodLevels+lodLevel; } - void freeLodData(); - - void freeCPUResources(); - void freeGPUResources(); - void determineLodLevels(); - void distributeVertexData(); - void updateBaseScale(); - void createGPUBlendTextures(); - void createLayerBlendMaps(); - void createOrDestroyGPUNormalMap(); - void createOrDestroyGPUColourMap(); - void createOrDestroyGPULightmap(); - void createOrDestroyGPUCompositeMap(); - void waitForDerivedProcesses(); - void convertSpace(Space inSpace, const Vector3& inVec, Space outSpace, Vector3& outVec, bool translation) const; - Vector3 convertWorldToTerrainAxes(const Vector3& inVec) const; - Vector3 convertTerrainToWorldAxes(const Vector3& inVec) const; - /** Get a Vector3 of the world-space point on the terrain, aligned Y-up always. - @note This point is relative to Terrain::getPosition - */ - void getPointAlign(long x, long y, Alignment align, Vector3* outpos) const; - /** Get a Vector3 of the world-space point on the terrain, supplying the - height data manually (can be more optimal). - @note This point is relative to Terrain::getPosition - */ - void getPointAlign(long x, long y, float height, Alignment align, Vector3* outpos) const; - void calculateCurrentLod(Viewport* vp); - /// Test a single quad of the terrain for ray intersection. - std::pair checkQuadIntersection(int x, int y, const Ray& ray); //const; + void freeLodData(); + + void freeCPUResources(); + void freeGPUResources(); + void determineLodLevels(); + void distributeVertexData(); + void updateBaseScale(); + void createGPUBlendTextures(); + void createLayerBlendMaps(); + void createOrDestroyGPUNormalMap(); + void createOrDestroyGPUColourMap(); + void createOrDestroyGPULightmap(); + void createOrDestroyGPUCompositeMap(); + void waitForDerivedProcesses(); + void convertSpace(Space inSpace, const Vector3& inVec, Space outSpace, Vector3& outVec, bool translation) const; + Vector3 convertWorldToTerrainAxes(const Vector3& inVec) const; + Vector3 convertTerrainToWorldAxes(const Vector3& inVec) const; + /** Get a Vector3 of the world-space point on the terrain, aligned Y-up always. + @note This point is relative to Terrain::getPosition + */ + void getPointAlign(long x, long y, Alignment align, Vector3* outpos) const; + /** Get a Vector3 of the world-space point on the terrain, supplying the + height data manually (can be more optimal). + @note This point is relative to Terrain::getPosition + */ + void getPointAlign(long x, long y, float height, Alignment align, Vector3* outpos) const; + void calculateCurrentLod(Viewport* vp); + /// Test a single quad of the terrain for ray intersection. + std::pair checkQuadIntersection(int x, int y, const Ray& ray); //const; /// Delete blend maps for all layers >= lowIndex void deleteBlendMaps(uint8 lowIndex); @@ -1697,454 +1697,454 @@ namespace Ogre /// Copy a GPU blend channel from one source to another. Source and Dest are not required to be in the same texture void copyBlendTextureChannel(uint8 srcIndex, uint8 srcChannel, uint8 destIndex, uint8 destChannel ); /// Reset a blend channel back to full black - void clearGPUBlendChannel(uint8 index, uint channel); - - void copyGlobalOptions(); - void checkLayers(bool includeGPUResources); - void checkDeclaration(); - void deriveUVMultipliers(); - PixelFormat getBlendTextureFormat(uint8 textureIndex, uint8 numLayers) const; - - void updateDerivedDataImpl(const Rect& rect, const Rect& lightmapExtraRect, bool synchronous, uint8 typeMask); - - void getEdgeRect(NeighbourIndex index, long range, Rect* outRect) const; - // get the equivalent of the passed in edge rectangle in neighbour - void getNeighbourEdgeRect(NeighbourIndex index, const Rect& inRect, Rect* outRect) const; - // get the equivalent of the passed in edge point in neighbour - void getNeighbourPoint(NeighbourIndex index, long x, long y, long *outx, long *outy) const; - // overflow a point into a neighbour index and point - void getNeighbourPointOverflow(long x, long y, NeighbourIndex *outindex, long *outx, long *outy) const; - - /// Removes this terrain instance from neighbouring terrain's list of neighbours. - void removeFromNeighbours(); - - uint16 mWorkQueueChannel; - SceneManager* mSceneMgr; - SceneNode* mRootNode; - String mResourceGroup; - bool mIsLoaded; - bool mModified; - bool mHeightDataModified; - - /// The height data (world coords relative to mPos) - float* mHeightData; - /// The delta information defining how a vertex moves before it is removed at a lower LOD - float* mDeltaData; - Alignment mAlign; - Real mWorldSize; - uint16 mSize; - uint16 mMaxBatchSize; - uint16 mMinBatchSize; - Vector3 mPos; - TerrainQuadTreeNode* mQuadTree; - uint16 mNumLodLevels; - uint16 mNumLodLevelsPerLeafNode; - uint16 mTreeDepth; - /// Base position in world space, relative to mPos - Real mBase; - /// Relationship between one point on the terrain and world size - Real mScale; - TerrainLayerDeclaration mLayerDecl; - LayerInstanceList mLayers; - RealVector mLayerUVMultiplier; - - Real mSkirtSize; - uint8 mRenderQueueGroup; - uint32 mVisibilityFlags; - uint32 mQueryFlags; - - Rect mDirtyGeometryRect; - Rect mDirtyDerivedDataRect; - Rect mDirtyGeometryRectForNeighbours; - Rect mDirtyLightmapFromNeighboursRect; - bool mDerivedDataUpdateInProgress; + void clearGPUBlendChannel(uint8 index, uint channel); + + void copyGlobalOptions(); + void checkLayers(bool includeGPUResources); + void checkDeclaration(); + void deriveUVMultipliers(); + PixelFormat getBlendTextureFormat(uint8 textureIndex, uint8 numLayers) const; + + void updateDerivedDataImpl(const Rect& rect, const Rect& lightmapExtraRect, bool synchronous, uint8 typeMask); + + void getEdgeRect(NeighbourIndex index, long range, Rect* outRect) const; + // get the equivalent of the passed in edge rectangle in neighbour + void getNeighbourEdgeRect(NeighbourIndex index, const Rect& inRect, Rect* outRect) const; + // get the equivalent of the passed in edge point in neighbour + void getNeighbourPoint(NeighbourIndex index, long x, long y, long *outx, long *outy) const; + // overflow a point into a neighbour index and point + void getNeighbourPointOverflow(long x, long y, NeighbourIndex *outindex, long *outx, long *outy) const; + + /// Removes this terrain instance from neighbouring terrain's list of neighbours. + void removeFromNeighbours(); + + uint16 mWorkQueueChannel; + SceneManager* mSceneMgr; + SceneNode* mRootNode; + String mResourceGroup; + bool mIsLoaded; + bool mModified; + bool mHeightDataModified; + + /// The height data (world coords relative to mPos) + float* mHeightData; + /// The delta information defining how a vertex moves before it is removed at a lower LOD + float* mDeltaData; + Alignment mAlign; + Real mWorldSize; + uint16 mSize; + uint16 mMaxBatchSize; + uint16 mMinBatchSize; + Vector3 mPos; + TerrainQuadTreeNode* mQuadTree; + uint16 mNumLodLevels; + uint16 mNumLodLevelsPerLeafNode; + uint16 mTreeDepth; + /// Base position in world space, relative to mPos + Real mBase; + /// Relationship between one point on the terrain and world size + Real mScale; + TerrainLayerDeclaration mLayerDecl; + LayerInstanceList mLayers; + RealVector mLayerUVMultiplier; + + Real mSkirtSize; + uint8 mRenderQueueGroup; + uint32 mVisibilityFlags; + uint32 mQueryFlags; + + Rect mDirtyGeometryRect; + Rect mDirtyDerivedDataRect; + Rect mDirtyGeometryRectForNeighbours; + Rect mDirtyLightmapFromNeighboursRect; + bool mDerivedDataUpdateInProgress; /// If another update is requested while one is already running - uint8 mDerivedUpdatePendingMask; - - bool mGenerateMaterialInProgress; - /// Don't release Height/DeltaData when preparing - mutable bool mPrepareInProgress; - /// A data holder for communicating with the background derived data update - struct DerivedDataRequest - { - Terrain* terrain; - // types requested - uint8 typeMask; - Rect dirtyRect; - Rect lightmapExtraDirtyRect; - _OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const DerivedDataRequest& r) - { return o; } - }; - - /// A data holder for communicating with the background derived data update - struct DerivedDataResponse - { - Terrain* terrain; - /// Remaining types not yet processed - uint8 remainingTypeMask; - /// The area of deltas that was updated - Rect deltaUpdateRect; - /// The area of normals that was updated - Rect normalUpdateRect; - /// The area of lightmap that was updated - Rect lightmapUpdateRect; - /// All CPU-side data, independent of textures; to be blitted in main thread - PixelBox* normalMapBox; - PixelBox* lightMapBox; - _OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const DerivedDataResponse& r) - { return o; } - }; - - enum GenerateMaterialStage{ - GEN_MATERIAL, - GEN_COMPOSITE_MAP_MATERIAL - }; - /// A data holder for communicating with the background GetMaterial - struct GenerateMaterialRequest - { - Terrain* terrain; - unsigned long startTime; - GenerateMaterialStage stage; - bool synchronous; - _OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const GenerateMaterialRequest& r) - { return o; } - }; - - String mMaterialName; - mutable MaterialPtr mMaterial; - mutable TerrainMaterialGeneratorPtr mMaterialGenerator; - mutable unsigned long long int mMaterialGenerationCount; - mutable bool mMaterialDirty; - mutable bool mMaterialParamsDirty; - - uint16 mLayerBlendMapSize; - uint16 mLayerBlendMapSizeActual; - typedef vector::type BytePointerList; - /// Staging post for blend map data - BytePointerList mCpuBlendMapStorage; - typedef vector::type TexturePtrList; - TexturePtrList mBlendTextureList; - TerrainLayerBlendMapList mLayerBlendMapList; - - uint16 mGlobalColourMapSize; - bool mGlobalColourMapEnabled; - TexturePtr mColourMap; - uint8* mCpuColourMapStorage; - - uint16 mLightmapSize; - uint16 mLightmapSizeActual; - TexturePtr mLightmap; - uint8* mCpuLightmapStorage; - - uint16 mCompositeMapSize; - uint16 mCompositeMapSizeActual; - TexturePtr mCompositeMap; - uint8* mCpuCompositeMapStorage; - Rect mCompositeMapDirtyRect; - unsigned long mCompositeMapUpdateCountdown; - unsigned long mLastMillis; - /// True if the updates included lightmap changes (widen) - bool mCompositeMapDirtyRectLightmapUpdate; - mutable MaterialPtr mCompositeMapMaterial; - - - static NameGenerator msBlendTextureGenerator; - static NameGenerator msNormalMapNameGenerator; - static NameGenerator msLightmapNameGenerator; - static NameGenerator msCompositeMapNameGenerator; - - bool mLodMorphRequired; - bool mNormalMapRequired; - bool mLightMapRequired; - bool mLightMapShadowsOnly; - bool mCompositeMapRequired; - /// Texture storing normals for the whole terrrain - TexturePtr mTerrainNormalMap; - - /// Pending data - PixelBox* mCpuTerrainNormalMap; - - const Camera* mLastLODCamera; - unsigned long mLastLODFrame; - int mLastViewportHeight; - - Terrain* mNeighbours[NEIGHBOUR_COUNT]; - - GpuBufferAllocator* mCustomGpuBufferAllocator; - DefaultGpuBufferAllocator mDefaultGpuBufferAllocator; - - size_t getPositionBufVertexSize() const; - size_t getDeltaBufVertexSize() const; - - TerrainLodManager* mLodManager; - - public: - /** Increase Terrain's LOD level by 1 - @param synchronous Run synchronously - */ - void increaseLodLevel(bool synchronous = false); - /** Removes highest LOD level loaded - @remarks If there is LOD level load in progress it's load is canceled instead of removal of already loaded one. - */ - void decreaseLodLevel(); - - int getHighestLodPrepared() const { return (mLodManager) ? mLodManager->getHighestLodPrepared() : -1; }; - int getHighestLodLoaded() const { return (mLodManager) ? mLodManager->getHighestLodLoaded() : -1; }; - int getTargetLodLevel() const { return (mLodManager) ? mLodManager->getTargetLodLevel() : -1; }; - }; - - - /** Options class which just stores default options for the terrain. - @remarks - None of these options are stored with the terrain when saved. They are - options that you can use to modify the behaviour of the terrain when it - is loaded or created. - @note - You should construct a single instance of this class per application and - do so before you start working with any other terrain classes. - */ - class _OgreTerrainExport TerrainGlobalOptions : public TerrainAlloc, public Singleton - { - protected: - - Real mSkirtSize; - Vector3 mLightMapDir; - bool mCastsShadows; - Real mMaxPixelError; - uint8 mRenderQueueGroup; - uint32 mVisibilityFlags; - uint32 mQueryFlags; - bool mUseRayBoxDistanceCalculation; - TerrainMaterialGeneratorPtr mDefaultMaterialGenerator; - uint16 mLayerBlendMapSize; - Real mDefaultLayerTextureWorldSize; - uint16 mDefaultGlobalColourMapSize; - uint16 mLightmapSize; - uint16 mCompositeMapSize; - ColourValue mCompositeMapAmbient; - ColourValue mCompositeMapDiffuse; - Real mCompositeMapDistance; - String mResourceGroup; - bool mUseVertexCompressionWhenAvailable; - - public: - TerrainGlobalOptions(); - virtual ~TerrainGlobalOptions() {} - - - /** The default size of 'skirts' used to hide terrain cracks - (default 10) - */ - Real getSkirtSize() const { return mSkirtSize; } - /** method - the default size of 'skirts' used to hide terrain cracks - (default 10) - @remarks - Changing this value only applies to Terrain instances loaded / reloaded afterwards. - */ - void setSkirtSize(Real skirtSz) { mSkirtSize = skirtSz; } - /// Get the shadow map light direction to use (world space) - const Vector3& getLightMapDirection() const { return mLightMapDir; } - /** Set the shadow map light direction to use (world space). */ - void setLightMapDirection(const Vector3& v) { mLightMapDir = v; } - /// Get the composite map ambient light to use - const ColourValue& getCompositeMapAmbient() const { return mCompositeMapAmbient; } - /// Set the composite map ambient light to use - void setCompositeMapAmbient(const ColourValue& c) { mCompositeMapAmbient = c; } - /// Get the composite map iffuse light to use - const ColourValue& getCompositeMapDiffuse() const { return mCompositeMapDiffuse; } - /// Set the composite map diffuse light to use - void setCompositeMapDiffuse(const ColourValue& c) { mCompositeMapDiffuse = c; } - /// Get the distance at which to start using a composite map if present - Real getCompositeMapDistance() const { return mCompositeMapDistance; } - /// Set the distance at which to start using a composite map if present - void setCompositeMapDistance(Real c) { mCompositeMapDistance = c; } - - - /** Whether the terrain will be able to cast shadows (texture shadows - only are supported, and you must be using depth shadow maps). - */ - bool getCastsDynamicShadows() const { return mCastsShadows; } - - /** Whether the terrain will be able to cast shadows (texture shadows - only are supported, and you must be using depth shadow maps). - This value can be set dynamically, and affects all existing terrains. - It defaults to false. - */ - void setCastsDynamicShadows(bool s) { mCastsShadows = s; } - - /** Get the maximum screen pixel error that should be allowed when rendering. */ - Real getMaxPixelError() const { return mMaxPixelError; } - - /** Set the maximum screen pixel error that should be allowed when rendering. - @note - This value can be varied dynamically and affects all existing terrains. - It will be weighted by the LOD bias on viewports. - */ - void setMaxPixelError(Real pixerr) { mMaxPixelError = pixerr; } - - /// Get the render queue group that this terrain will be rendered into - uint8 getRenderQueueGroup(void) const { return mRenderQueueGroup; } - /** Set the render queue group that terrains will be rendered into. - @remarks This applies to newly created terrains, after which they will - maintain their own queue group settings - */ - void setRenderQueueGroup(uint8 grp) { mRenderQueueGroup = grp; } - - /// Get the visbility flags that terrains will be rendered with - uint32 getVisibilityFlags(void) const { return mVisibilityFlags; } - /** Set the visbility flags that terrains will be rendered with - @remarks This applies to newly created terrains, after which they will - maintain their own settings - */ - void setVisibilityFlags(uint32 flags) { mVisibilityFlags = flags; } - - /** Set the default query flags for terrains. - @remarks This applies to newly created terrains, after which they will - maintain their own settings - */ - void setQueryFlags(uint32 flags) { mQueryFlags = flags; } - /** Get the default query flags for terrains. - */ - uint32 getQueryFlags(void) const { return mQueryFlags; } - - /** As setQueryFlags, except the flags passed as parameters are appended to the existing flags on this object. */ - void addQueryFlags(uint32 flags) { mQueryFlags |= flags; } - - /* As setQueryFlags, except the flags passed as parameters are removed from the existing flags on this object. */ - void removeQueryFlags(uint32 flags) { mQueryFlags &= ~flags; } - - /** Returns whether or not to use an accurate calculation of camera distance - from a terrain tile (ray / AABB intersection) or whether to use the - simpler distance from the tile centre. - */ - bool getUseRayBoxDistanceCalculation() const { return mUseRayBoxDistanceCalculation; } - - /** Sets whether to use an accurate ray / box intersection to determine - distance from a terrain tile, or whether to use the simple distance - from the tile centre. - Using ray/box intersection will result in higher detail terrain because - the LOD calculation is more conservative, assuming the 'worst case scenario' - of a large height difference at the edge of a tile. This is guaranteed to give you at least - the max pixel error or better, but will often give you more detail than - you need. Not using the ray/box method is cheaper but will only use - the max pixel error as a guide, the actual error will vary above and - below that. The default is not to use the ray/box approach. - */ - void setUseRayBoxDistanceCalculation(bool rb) { mUseRayBoxDistanceCalculation = rb; } - - /** Get the default material generator. - */ - TerrainMaterialGeneratorPtr getDefaultMaterialGenerator(); - - /** Set the default material generator. - */ - void setDefaultMaterialGenerator(TerrainMaterialGeneratorPtr gen); - - /** Get the default size of the blend maps for a new terrain. - */ - uint16 getLayerBlendMapSize() const { return mLayerBlendMapSize; } - - /** Sets the default size of blend maps for a new terrain. - This is the resolution of each blending layer for a new terrain. - Once created, this information will be stored with the terrain. - */ - void setLayerBlendMapSize(uint16 sz) { mLayerBlendMapSize = sz;} - - /** Get the default world size for a layer 'splat' texture to cover. - */ - Real getDefaultLayerTextureWorldSize() const { return mDefaultLayerTextureWorldSize; } - - /** Set the default world size for a layer 'splat' texture to cover. - */ - void setDefaultLayerTextureWorldSize(Real sz) { mDefaultLayerTextureWorldSize = sz; } - - /** Get the default size of the terrain global colour map for a new terrain. - */ - uint16 getDefaultGlobalColourMapSize() const { return mDefaultGlobalColourMapSize; } - - /** Set the default size of the terrain global colour map for a new terrain. - Once created, this information will be stored with the terrain. - */ - void setDefaultGlobalColourMapSize(uint16 sz) { mDefaultGlobalColourMapSize = sz;} - - - /** Get the default size of the lightmaps for a new terrain. - */ - uint16 getLightMapSize() const { return mLightmapSize; } - - /** Sets the default size of lightmaps for a new terrain. - */ - void setLightMapSize(uint16 sz) { mLightmapSize = sz;} - - /** Get the default size of the composite maps for a new terrain. - */ - uint16 getCompositeMapSize() const { return mCompositeMapSize; } - - /** Sets the default size of composite maps for a new terrain. - */ - void setCompositeMapSize(uint16 sz) { mCompositeMapSize = sz;} - - /** Set the default resource group to use to load / save terrains. - */ - void setDefaultResourceGroup(const String& grp) { mResourceGroup = grp; } - - /** Get the default resource group to use to load / save terrains. - */ - const String& getDefaultResourceGroup() const { return mResourceGroup; } - - /** Get whether to allow vertex compression to be used when the material - generator states that it supports it. - */ - bool getUseVertexCompressionWhenAvailable() const { return mUseVertexCompressionWhenAvailable; } - - /** Set whether to allow vertex compression to be used when the material - generator states that it supports it. - @note You should only call this before creating any terrain instances. - The default is true, so if a material generator supports compressed vertices, - and so does the hardware (this basically means shader support), they will be used). - However you can disable this in an emergency if required. - */ - void setUseVertexCompressionWhenAvailable(bool enable) { mUseVertexCompressionWhenAvailable = enable; } - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static TerrainGlobalOptions& getSingleton(void); - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static TerrainGlobalOptions* getSingletonPtr(void); - - - }; - - - /** @} */ - /** @} */ + uint8 mDerivedUpdatePendingMask; + + bool mGenerateMaterialInProgress; + /// Don't release Height/DeltaData when preparing + mutable bool mPrepareInProgress; + /// A data holder for communicating with the background derived data update + struct DerivedDataRequest + { + Terrain* terrain; + // types requested + uint8 typeMask; + Rect dirtyRect; + Rect lightmapExtraDirtyRect; + _OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const DerivedDataRequest& r) + { return o; } + }; + + /// A data holder for communicating with the background derived data update + struct DerivedDataResponse + { + Terrain* terrain; + /// Remaining types not yet processed + uint8 remainingTypeMask; + /// The area of deltas that was updated + Rect deltaUpdateRect; + /// The area of normals that was updated + Rect normalUpdateRect; + /// The area of lightmap that was updated + Rect lightmapUpdateRect; + /// All CPU-side data, independent of textures; to be blitted in main thread + PixelBox* normalMapBox; + PixelBox* lightMapBox; + _OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const DerivedDataResponse& r) + { return o; } + }; + + enum GenerateMaterialStage{ + GEN_MATERIAL, + GEN_COMPOSITE_MAP_MATERIAL + }; + /// A data holder for communicating with the background GetMaterial + struct GenerateMaterialRequest + { + Terrain* terrain; + unsigned long startTime; + GenerateMaterialStage stage; + bool synchronous; + _OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const GenerateMaterialRequest& r) + { return o; } + }; + + String mMaterialName; + mutable MaterialPtr mMaterial; + mutable TerrainMaterialGeneratorPtr mMaterialGenerator; + mutable unsigned long long int mMaterialGenerationCount; + mutable bool mMaterialDirty; + mutable bool mMaterialParamsDirty; + + uint16 mLayerBlendMapSize; + uint16 mLayerBlendMapSizeActual; + typedef vector::type BytePointerList; + /// Staging post for blend map data + BytePointerList mCpuBlendMapStorage; + typedef vector::type TexturePtrList; + TexturePtrList mBlendTextureList; + TerrainLayerBlendMapList mLayerBlendMapList; + + uint16 mGlobalColourMapSize; + bool mGlobalColourMapEnabled; + TexturePtr mColourMap; + uint8* mCpuColourMapStorage; + + uint16 mLightmapSize; + uint16 mLightmapSizeActual; + TexturePtr mLightmap; + uint8* mCpuLightmapStorage; + + uint16 mCompositeMapSize; + uint16 mCompositeMapSizeActual; + TexturePtr mCompositeMap; + uint8* mCpuCompositeMapStorage; + Rect mCompositeMapDirtyRect; + unsigned long mCompositeMapUpdateCountdown; + unsigned long mLastMillis; + /// True if the updates included lightmap changes (widen) + bool mCompositeMapDirtyRectLightmapUpdate; + mutable MaterialPtr mCompositeMapMaterial; + + + static NameGenerator msBlendTextureGenerator; + static NameGenerator msNormalMapNameGenerator; + static NameGenerator msLightmapNameGenerator; + static NameGenerator msCompositeMapNameGenerator; + + bool mLodMorphRequired; + bool mNormalMapRequired; + bool mLightMapRequired; + bool mLightMapShadowsOnly; + bool mCompositeMapRequired; + /// Texture storing normals for the whole terrrain + TexturePtr mTerrainNormalMap; + + /// Pending data + PixelBox* mCpuTerrainNormalMap; + + const Camera* mLastLODCamera; + unsigned long mLastLODFrame; + int mLastViewportHeight; + + Terrain* mNeighbours[NEIGHBOUR_COUNT]; + + GpuBufferAllocator* mCustomGpuBufferAllocator; + DefaultGpuBufferAllocator mDefaultGpuBufferAllocator; + + size_t getPositionBufVertexSize() const; + size_t getDeltaBufVertexSize() const; + + TerrainLodManager* mLodManager; + + public: + /** Increase Terrain's LOD level by 1 + @param synchronous Run synchronously + */ + void increaseLodLevel(bool synchronous = false); + /** Removes highest LOD level loaded + @remarks If there is LOD level load in progress it's load is canceled instead of removal of already loaded one. + */ + void decreaseLodLevel(); + + int getHighestLodPrepared() const { return (mLodManager) ? mLodManager->getHighestLodPrepared() : -1; }; + int getHighestLodLoaded() const { return (mLodManager) ? mLodManager->getHighestLodLoaded() : -1; }; + int getTargetLodLevel() const { return (mLodManager) ? mLodManager->getTargetLodLevel() : -1; }; + }; + + + /** Options class which just stores default options for the terrain. + @remarks + None of these options are stored with the terrain when saved. They are + options that you can use to modify the behaviour of the terrain when it + is loaded or created. + @note + You should construct a single instance of this class per application and + do so before you start working with any other terrain classes. + */ + class _OgreTerrainExport TerrainGlobalOptions : public TerrainAlloc, public Singleton + { + protected: + + Real mSkirtSize; + Vector3 mLightMapDir; + bool mCastsShadows; + Real mMaxPixelError; + uint8 mRenderQueueGroup; + uint32 mVisibilityFlags; + uint32 mQueryFlags; + bool mUseRayBoxDistanceCalculation; + TerrainMaterialGeneratorPtr mDefaultMaterialGenerator; + uint16 mLayerBlendMapSize; + Real mDefaultLayerTextureWorldSize; + uint16 mDefaultGlobalColourMapSize; + uint16 mLightmapSize; + uint16 mCompositeMapSize; + ColourValue mCompositeMapAmbient; + ColourValue mCompositeMapDiffuse; + Real mCompositeMapDistance; + String mResourceGroup; + bool mUseVertexCompressionWhenAvailable; + + public: + TerrainGlobalOptions(); + virtual ~TerrainGlobalOptions() {} + + + /** The default size of 'skirts' used to hide terrain cracks + (default 10) + */ + Real getSkirtSize() const { return mSkirtSize; } + /** method - the default size of 'skirts' used to hide terrain cracks + (default 10) + @remarks + Changing this value only applies to Terrain instances loaded / reloaded afterwards. + */ + void setSkirtSize(Real skirtSz) { mSkirtSize = skirtSz; } + /// Get the shadow map light direction to use (world space) + const Vector3& getLightMapDirection() const { return mLightMapDir; } + /** Set the shadow map light direction to use (world space). */ + void setLightMapDirection(const Vector3& v) { mLightMapDir = v; } + /// Get the composite map ambient light to use + const ColourValue& getCompositeMapAmbient() const { return mCompositeMapAmbient; } + /// Set the composite map ambient light to use + void setCompositeMapAmbient(const ColourValue& c) { mCompositeMapAmbient = c; } + /// Get the composite map iffuse light to use + const ColourValue& getCompositeMapDiffuse() const { return mCompositeMapDiffuse; } + /// Set the composite map diffuse light to use + void setCompositeMapDiffuse(const ColourValue& c) { mCompositeMapDiffuse = c; } + /// Get the distance at which to start using a composite map if present + Real getCompositeMapDistance() const { return mCompositeMapDistance; } + /// Set the distance at which to start using a composite map if present + void setCompositeMapDistance(Real c) { mCompositeMapDistance = c; } + + + /** Whether the terrain will be able to cast shadows (texture shadows + only are supported, and you must be using depth shadow maps). + */ + bool getCastsDynamicShadows() const { return mCastsShadows; } + + /** Whether the terrain will be able to cast shadows (texture shadows + only are supported, and you must be using depth shadow maps). + This value can be set dynamically, and affects all existing terrains. + It defaults to false. + */ + void setCastsDynamicShadows(bool s) { mCastsShadows = s; } + + /** Get the maximum screen pixel error that should be allowed when rendering. */ + Real getMaxPixelError() const { return mMaxPixelError; } + + /** Set the maximum screen pixel error that should be allowed when rendering. + @note + This value can be varied dynamically and affects all existing terrains. + It will be weighted by the LOD bias on viewports. + */ + void setMaxPixelError(Real pixerr) { mMaxPixelError = pixerr; } + + /// Get the render queue group that this terrain will be rendered into + uint8 getRenderQueueGroup(void) const { return mRenderQueueGroup; } + /** Set the render queue group that terrains will be rendered into. + @remarks This applies to newly created terrains, after which they will + maintain their own queue group settings + */ + void setRenderQueueGroup(uint8 grp) { mRenderQueueGroup = grp; } + + /// Get the visbility flags that terrains will be rendered with + uint32 getVisibilityFlags(void) const { return mVisibilityFlags; } + /** Set the visbility flags that terrains will be rendered with + @remarks This applies to newly created terrains, after which they will + maintain their own settings + */ + void setVisibilityFlags(uint32 flags) { mVisibilityFlags = flags; } + + /** Set the default query flags for terrains. + @remarks This applies to newly created terrains, after which they will + maintain their own settings + */ + void setQueryFlags(uint32 flags) { mQueryFlags = flags; } + /** Get the default query flags for terrains. + */ + uint32 getQueryFlags(void) const { return mQueryFlags; } + + /** As setQueryFlags, except the flags passed as parameters are appended to the existing flags on this object. */ + void addQueryFlags(uint32 flags) { mQueryFlags |= flags; } + + /* As setQueryFlags, except the flags passed as parameters are removed from the existing flags on this object. */ + void removeQueryFlags(uint32 flags) { mQueryFlags &= ~flags; } + + /** Returns whether or not to use an accurate calculation of camera distance + from a terrain tile (ray / AABB intersection) or whether to use the + simpler distance from the tile centre. + */ + bool getUseRayBoxDistanceCalculation() const { return mUseRayBoxDistanceCalculation; } + + /** Sets whether to use an accurate ray / box intersection to determine + distance from a terrain tile, or whether to use the simple distance + from the tile centre. + Using ray/box intersection will result in higher detail terrain because + the LOD calculation is more conservative, assuming the 'worst case scenario' + of a large height difference at the edge of a tile. This is guaranteed to give you at least + the max pixel error or better, but will often give you more detail than + you need. Not using the ray/box method is cheaper but will only use + the max pixel error as a guide, the actual error will vary above and + below that. The default is not to use the ray/box approach. + */ + void setUseRayBoxDistanceCalculation(bool rb) { mUseRayBoxDistanceCalculation = rb; } + + /** Get the default material generator. + */ + TerrainMaterialGeneratorPtr getDefaultMaterialGenerator(); + + /** Set the default material generator. + */ + void setDefaultMaterialGenerator(TerrainMaterialGeneratorPtr gen); + + /** Get the default size of the blend maps for a new terrain. + */ + uint16 getLayerBlendMapSize() const { return mLayerBlendMapSize; } + + /** Sets the default size of blend maps for a new terrain. + This is the resolution of each blending layer for a new terrain. + Once created, this information will be stored with the terrain. + */ + void setLayerBlendMapSize(uint16 sz) { mLayerBlendMapSize = sz;} + + /** Get the default world size for a layer 'splat' texture to cover. + */ + Real getDefaultLayerTextureWorldSize() const { return mDefaultLayerTextureWorldSize; } + + /** Set the default world size for a layer 'splat' texture to cover. + */ + void setDefaultLayerTextureWorldSize(Real sz) { mDefaultLayerTextureWorldSize = sz; } + + /** Get the default size of the terrain global colour map for a new terrain. + */ + uint16 getDefaultGlobalColourMapSize() const { return mDefaultGlobalColourMapSize; } + + /** Set the default size of the terrain global colour map for a new terrain. + Once created, this information will be stored with the terrain. + */ + void setDefaultGlobalColourMapSize(uint16 sz) { mDefaultGlobalColourMapSize = sz;} + + + /** Get the default size of the lightmaps for a new terrain. + */ + uint16 getLightMapSize() const { return mLightmapSize; } + + /** Sets the default size of lightmaps for a new terrain. + */ + void setLightMapSize(uint16 sz) { mLightmapSize = sz;} + + /** Get the default size of the composite maps for a new terrain. + */ + uint16 getCompositeMapSize() const { return mCompositeMapSize; } + + /** Sets the default size of composite maps for a new terrain. + */ + void setCompositeMapSize(uint16 sz) { mCompositeMapSize = sz;} + + /** Set the default resource group to use to load / save terrains. + */ + void setDefaultResourceGroup(const String& grp) { mResourceGroup = grp; } + + /** Get the default resource group to use to load / save terrains. + */ + const String& getDefaultResourceGroup() const { return mResourceGroup; } + + /** Get whether to allow vertex compression to be used when the material + generator states that it supports it. + */ + bool getUseVertexCompressionWhenAvailable() const { return mUseVertexCompressionWhenAvailable; } + + /** Set whether to allow vertex compression to be used when the material + generator states that it supports it. + @note You should only call this before creating any terrain instances. + The default is true, so if a material generator supports compressed vertices, + and so does the hardware (this basically means shader support), they will be used). + However you can disable this in an emergency if required. + */ + void setUseVertexCompressionWhenAvailable(bool enable) { mUseVertexCompressionWhenAvailable = enable; } + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static TerrainGlobalOptions& getSingleton(void); + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static TerrainGlobalOptions* getSingletonPtr(void); + + + }; + + + /** @} */ + /** @} */ } diff --git a/Components/Terrain/include/OgreTerrainAutoUpdateLod.h b/Components/Terrain/include/OgreTerrainAutoUpdateLod.h index cd0d189211e..c0a4e52b88e 100644 --- a/Components/Terrain/include/OgreTerrainAutoUpdateLod.h +++ b/Components/Terrain/include/OgreTerrainAutoUpdateLod.h @@ -33,79 +33,79 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Terrain - * Some details on the terrain auto load - * @{ - */ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Terrain + * Some details on the terrain auto load + * @{ + */ - /** Terrain automatic LOD loading - @par - This set of classes is used for automatic change of terrain LOD level. Base is TerrainAutoUpdateLod interface with just - one public method autoUpdateLod. This method gets called by terrain whenever user thinks something has - changed(typically in application's main loop) what could affect terrain's LOD level. It is designed in such a way - so user can use whatever algorithm he likes to change terrain's LOD level. For example see TerrainAutoUpdateLod - implementation TerrainAutoUpdateLodByDistance. - It is also used as a null object for auto-LOD-updating. - */ - class _OgreTerrainExport TerrainAutoUpdateLod : public TerrainAlloc - { - public: + /** Terrain automatic LOD loading + @par + This set of classes is used for automatic change of terrain LOD level. Base is TerrainAutoUpdateLod interface with just + one public method autoUpdateLod. This method gets called by terrain whenever user thinks something has + changed(typically in application's main loop) what could affect terrain's LOD level. It is designed in such a way + so user can use whatever algorithm he likes to change terrain's LOD level. For example see TerrainAutoUpdateLod + implementation TerrainAutoUpdateLodByDistance. + It is also used as a null object for auto-LOD-updating. + */ + class _OgreTerrainExport TerrainAutoUpdateLod : public TerrainAlloc + { + public: virtual ~TerrainAutoUpdateLod() {} - /** Method to be called to change terrain's LOD level. - @param terrain Instance of Terrain which LOD level is going to be changed - @param synchronous Run this as part of main thread or in background - @param data Any user specific data. - */ - virtual void autoUpdateLod(Terrain *terrain, bool synchronous, const Any &data) = 0; - virtual uint32 getStrategyId() = 0; - }; + /** Method to be called to change terrain's LOD level. + @param terrain Instance of Terrain which LOD level is going to be changed + @param synchronous Run this as part of main thread or in background + @param data Any user specific data. + */ + virtual void autoUpdateLod(Terrain *terrain, bool synchronous, const Any &data) = 0; + virtual uint32 getStrategyId() = 0; + }; - // other Strategy's id start from 2 - enum TerrainAutoUpdateLodStrategy - { - NONE = 0, - BY_DISTANCE = 1 - }; + // other Strategy's id start from 2 + enum TerrainAutoUpdateLodStrategy + { + NONE = 0, + BY_DISTANCE = 1 + }; - /** Class implementing TerrainAutoUpdateLod interface. It does LOD level increase/decrease according to camera's - distance to Terrain. - */ - class _OgreTerrainExport TerrainAutoUpdateLodByDistance : public TerrainAutoUpdateLod - { - public: - virtual void autoUpdateLod(Terrain *terrain, bool synchronous, const Any &data); - virtual uint32 getStrategyId() { return BY_DISTANCE; } + /** Class implementing TerrainAutoUpdateLod interface. It does LOD level increase/decrease according to camera's + distance to Terrain. + */ + class _OgreTerrainExport TerrainAutoUpdateLodByDistance : public TerrainAutoUpdateLod + { + public: + virtual void autoUpdateLod(Terrain *terrain, bool synchronous, const Any &data); + virtual uint32 getStrategyId() { return BY_DISTANCE; } - protected: - /** Modifies Terrain's LOD level according to it's distance from camera. - @param holdDistance How far ahead of terrain's LOD level change this LOD level should be loaded. - */ - void autoUpdateLodByDistance(Terrain *terrain, bool synchronous, const Real holdDistance); - /// Traverse Terrain's QuadTree and calculate what LOD level is needed. - int traverseTreeByDistance(TerrainQuadTreeNode *node, const Camera *cam, Real cFactor, const Real holdDistance); - }; + protected: + /** Modifies Terrain's LOD level according to it's distance from camera. + @param holdDistance How far ahead of terrain's LOD level change this LOD level should be loaded. + */ + void autoUpdateLodByDistance(Terrain *terrain, bool synchronous, const Real holdDistance); + /// Traverse Terrain's QuadTree and calculate what LOD level is needed. + int traverseTreeByDistance(TerrainQuadTreeNode *node, const Camera *cam, Real cFactor, const Real holdDistance); + }; - class _OgreTerrainExport TerrainAutoUpdateLodFactory - { - public: - static TerrainAutoUpdateLod* getAutoUpdateLod( uint32 strategy ) - { - switch(strategy) - { - case BY_DISTANCE: - return OGRE_NEW TerrainAutoUpdateLodByDistance; - case NONE: - default: - return 0; - } - return 0; - } - }; - /** @} */ - /** @} */ + class _OgreTerrainExport TerrainAutoUpdateLodFactory + { + public: + static TerrainAutoUpdateLod* getAutoUpdateLod( uint32 strategy ) + { + switch(strategy) + { + case BY_DISTANCE: + return OGRE_NEW TerrainAutoUpdateLodByDistance; + case NONE: + default: + return 0; + } + return 0; + } + }; + /** @} */ + /** @} */ } #endif diff --git a/Components/Terrain/include/OgreTerrainGroup.h b/Components/Terrain/include/OgreTerrainGroup.h index d93284d3034..2421ff5d9c1 100644 --- a/Components/Terrain/include/OgreTerrainGroup.h +++ b/Components/Terrain/include/OgreTerrainGroup.h @@ -38,520 +38,520 @@ namespace Ogre { class TerrainAutoUpdateLod; - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Terrain - * Some details on the terrain component - * @{ - */ - - /** Helper class to assist you in managing multiple terrain instances - that are connected to each other. - @remarks - This class makes it easy to specify the same options for a group of - terrain instances and have them positioned relative to each other and - associated via each other's neighbour connections. You can do all this - manually but this class just makes things easier, so that you only - have to specify most options once. - @par - Terrains are maintained in a grid of entries, and for simplicity - the grid cells are indexed from 0 as a 'centre' slot, supporting both - positive and negative values. so (0,0) is the centre slot, (1,0) is the - slot to the right of the centre, (1,0) is the slot above the centre, (-2,1) - is the slot two to the left of the centre and one up, etc. The maximum - extent of each axis is -32768 to +32767, so in other words enough for - over 4 billion entries. That should be enough for anyone! - @par - Note that this is not a 'paging' class as such. It's simply a way to make it easier to - perform common tasks with multiple terrain instances, which you choose when - to define, load and remove. Automatic paging is handled separately by the Paging - component. - */ - class _OgreTerrainExport TerrainGroup : public WorkQueue::RequestHandler, - public WorkQueue::ResponseHandler, public TerrainAlloc - { - public: - /** Constructor. - @param sm The SceneManager which will parent the terrain instances. - @param align The alignment that all terrain instances will use - @param terrainSize The size of each terrain down one edge in vertices (2^n+1) - @param terrainWorldSize The world size of each terrain instance - */ - TerrainGroup(SceneManager* sm, Terrain::Alignment align, uint16 terrainSize, - Real terrainWorldSize); - /** Alternate constructor. - @remarks - You can ONLY use this constructor if you subsequently call loadGroupDefinition - to populate the rest. - */ - TerrainGroup(SceneManager* sm); - virtual ~TerrainGroup(); - - /** Retrieve a shared structure which will provide the base settings for - all terrains created via this group. - @remarks - All neighbouring terrains should have the same basic settings (particularly - the size parameters) - to avoid having to set the terrain import information - more than once, you can retrieve the standard settings for this group - here and modify them to your needs. Once you've done that you can - use the shortcut methods in this class to create new terrain instances - using these base settings (plus any per-instance settings you might - want to use). - @note - The structure returned from this method is intended for in-place modification, - that's why it is not const and there is no equivalent 'set' method. - You should not, however, change the alignment or any of the size parameters - after you start constructing instances, since neighbouring terrains - should have the same size & alignment. - */ - virtual Terrain::ImportData& getDefaultImportSettings() { return mDefaultImportData; } - - /** Define the centre position of the grid of terrain. - */ - virtual void setOrigin(const Vector3& pos); - - /** Retrieve the centre position of the grid of terrain. - */ - virtual const Vector3& getOrigin() const { return mOrigin; } - - /** Retrieve the alignment of the grid of terrain (cannot be modified after construction). - */ - virtual Terrain::Alignment getAlignment() const { return mAlignment; } - - /** Retrieve the world size of each terrain instance - */ - virtual Real getTerrainWorldSize() const { return mTerrainWorldSize; } - /** Set the world size of terrain. - @note This will cause the terrains to change position due to their size change - @param newWorldSize the new world size of each terrain instance - */ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Terrain + * Some details on the terrain component + * @{ + */ + + /** Helper class to assist you in managing multiple terrain instances + that are connected to each other. + @remarks + This class makes it easy to specify the same options for a group of + terrain instances and have them positioned relative to each other and + associated via each other's neighbour connections. You can do all this + manually but this class just makes things easier, so that you only + have to specify most options once. + @par + Terrains are maintained in a grid of entries, and for simplicity + the grid cells are indexed from 0 as a 'centre' slot, supporting both + positive and negative values. so (0,0) is the centre slot, (1,0) is the + slot to the right of the centre, (1,0) is the slot above the centre, (-2,1) + is the slot two to the left of the centre and one up, etc. The maximum + extent of each axis is -32768 to +32767, so in other words enough for + over 4 billion entries. That should be enough for anyone! + @par + Note that this is not a 'paging' class as such. It's simply a way to make it easier to + perform common tasks with multiple terrain instances, which you choose when + to define, load and remove. Automatic paging is handled separately by the Paging + component. + */ + class _OgreTerrainExport TerrainGroup : public WorkQueue::RequestHandler, + public WorkQueue::ResponseHandler, public TerrainAlloc + { + public: + /** Constructor. + @param sm The SceneManager which will parent the terrain instances. + @param align The alignment that all terrain instances will use + @param terrainSize The size of each terrain down one edge in vertices (2^n+1) + @param terrainWorldSize The world size of each terrain instance + */ + TerrainGroup(SceneManager* sm, Terrain::Alignment align, uint16 terrainSize, + Real terrainWorldSize); + /** Alternate constructor. + @remarks + You can ONLY use this constructor if you subsequently call loadGroupDefinition + to populate the rest. + */ + TerrainGroup(SceneManager* sm); + virtual ~TerrainGroup(); + + /** Retrieve a shared structure which will provide the base settings for + all terrains created via this group. + @remarks + All neighbouring terrains should have the same basic settings (particularly + the size parameters) - to avoid having to set the terrain import information + more than once, you can retrieve the standard settings for this group + here and modify them to your needs. Once you've done that you can + use the shortcut methods in this class to create new terrain instances + using these base settings (plus any per-instance settings you might + want to use). + @note + The structure returned from this method is intended for in-place modification, + that's why it is not const and there is no equivalent 'set' method. + You should not, however, change the alignment or any of the size parameters + after you start constructing instances, since neighbouring terrains + should have the same size & alignment. + */ + virtual Terrain::ImportData& getDefaultImportSettings() { return mDefaultImportData; } + + /** Define the centre position of the grid of terrain. + */ + virtual void setOrigin(const Vector3& pos); + + /** Retrieve the centre position of the grid of terrain. + */ + virtual const Vector3& getOrigin() const { return mOrigin; } + + /** Retrieve the alignment of the grid of terrain (cannot be modified after construction). + */ + virtual Terrain::Alignment getAlignment() const { return mAlignment; } + + /** Retrieve the world size of each terrain instance + */ + virtual Real getTerrainWorldSize() const { return mTerrainWorldSize; } + /** Set the world size of terrain. + @note This will cause the terrains to change position due to their size change + @param newWorldSize the new world size of each terrain instance + */ virtual void setTerrainWorldSize(Real newWorldSize); - /** Retrieve the size of each terrain instance in number of vertices down one side - */ - virtual uint16 getTerrainSize() const { return mTerrainSize; } - /** Set the size of each terrain instance in number of vertices down one side. - @note This will cause the height data in each nested terrain to be bilinear - filtered to fit the new data size. - @param newTerrainSize the new map size of each terrain instance - */ + /** Retrieve the size of each terrain instance in number of vertices down one side + */ + virtual uint16 getTerrainSize() const { return mTerrainSize; } + /** Set the size of each terrain instance in number of vertices down one side. + @note This will cause the height data in each nested terrain to be bilinear + filtered to fit the new data size. + @param newTerrainSize the new map size of each terrain instance + */ virtual void setTerrainSize(uint16 newTerrainSize); - /** Retrieve the SceneManager being used for this group. - */ - virtual SceneManager* getSceneManager() const { return mSceneManager; } - - /** Set the naming convention for file names in this terrain group. - @remarks - You can more easily generate file names for saved / loaded terrain slots - if you define a naming prefix. When you call saveAllTerrains(), all the - terrain instances currently loaded will be saved to a file named - <prefix>_<index>.<extension>, where <index> is - given by packing the x and y coordinates of the entry into a 32-bit - index (@see packIndex). - */ - void setFilenameConvention(const String& prefix, const String& extension); - /// @see setFilenameConvention - void setFilenamePrefix(const String& prefix); - /// @see setFilenameConvention - void setFilenameExtension(const String& extension); - /// @see setFilenameConvention - const String& getFilenamePrefix() const { return mFilenamePrefix; } - /// @see setFilenameConvention - const String& getFilenameExtension() const { return mFilenameExtension; } - - /** Set the resource group in which files will be located. */ - void setResourceGroup(const String& grp) { mResourceGroup = grp; } - /** Get the resource group in which files will be located. */ - const String& getResourceGroup() const { return mResourceGroup; } - /** Define a 'slot' in the terrain grid - in this case to be loaded from - a generated file name. - @remarks - At this stage the terrain instance isn't actually present in the grid, - you're merely expressing an intention for it to take its place there - once it's loaded. The reason we do it like this is to support - background preparation of this terrain instance. - @note This method assumes that you want a file name to be generated from - the naming convention that you have supplied (@see setFilenameConvention). - If a file of that name isn't found during loading, then a flat terrain is - created instead at height 0. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - */ - virtual void defineTerrain(long x, long y); - - /** Define a 'slot' in the terrain grid - in this case a flat terrain. - @remarks - At this stage the terrain instance isn't actually present in the grid, - you're merely expressing an intention for it to take its place there - once it's loaded. The reason we do it like this is to support - background preparation of this terrain instance. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - @param constantHeight The constant, uniform height that you want the terrain - to start at - */ - virtual void defineTerrain(long x, long y, float constantHeight); - - /** Define the content of a 'slot' in the terrain grid. - @remarks - At this stage the terrain instance isn't actually present in the grid, - you're merely expressing an intention for it to take its place there - once it's loaded. The reason we do it like this is to support - background preparation of this terrain instance. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - @param importData Import data - this data is copied during the - call so you may destroy your copy afterwards. - */ - virtual void defineTerrain(long x, long y, const Terrain::ImportData* importData); - - /** Define the content of a 'slot' in the terrain grid. - @remarks - At this stage the terrain instance isn't actually present in the grid, - you're merely expressing an intention for it to take its place there - once it's loaded. The reason we do it like this is to support - background preparation of this terrain instance. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - @param img Heightfield image - this data is copied during the call so you may destroy your copy afterwards. - @param layers Optional texture layers to use (if not supplied, default import - data layers will be used) - this data is copied during the - call so you may destroy your copy afterwards. - */ - virtual void defineTerrain(long x, long y, const Image* img, const Terrain::LayerInstanceList* layers = 0); - - /** Define the content of a 'slot' in the terrain grid. - @remarks - At this stage the terrain instance isn't actually present in the grid, - you're merely expressing an intention for it to take its place there - once it's loaded. The reason we do it like this is to support - background preparation of this terrain instance. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - @param pFloat Heights array - @param layers Optional texture layers to use (if not supplied, default import - data layers will be used) - this data is copied during the - call so you may destroy your copy afterwards. - */ - virtual void defineTerrain(long x, long y, const float* pFloat, const Terrain::LayerInstanceList* layers = 0); - - /** Define the content of a 'slot' in the terrain grid. - @remarks - At this stage the terrain instance isn't actually present in the grid, - you're merely expressing an intention for it to take its place there - once it's loaded. The reason we do it like this is to support - background preparation of this terrain instance. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - @param filename The name of a file which fully defines the terrain (as - written by Terrain::save). Size settings from all files must agree. - */ - virtual void defineTerrain(long x, long y, const String& filename); - - - /** Load any terrain instances that have been defined but not loaded yet. - @param synchronous Whether we should force this to happen entirely in the - primary thread (default false, operations are threaded if possible) - */ - virtual void loadAllTerrains(bool synchronous = false); - - /** Load a specific terrain slot based on the definition that has already - been supplied. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - @param synchronous Whether we should force this to happen entirely in the - primary thread (default false, operations are threaded if possible) - */ - virtual void loadTerrain(long x, long y, bool synchronous = false); - - /** Unload a specific terrain slot. - @remarks - This destroys the Terrain instance but retains the slot definition (so - it would be reloaded next time you call loadAllTerrains() if you did not - remove it beforehand). - @note - While the definition of the terrain is kept, if you used import data - to populate it, this will have been lost so repeat loading cannot occur. - The only way to support repeat loading is via the 'filename' option of - defineTerrain instead. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - */ - virtual void unloadTerrain(long x, long y); - - /** Remove a specific terrain slot. - @remarks - This destroys any Terrain instance at this position and also removes the - definition, so it essentially no longer exists. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - */ - virtual void removeTerrain(long x, long y); - - /** Remove all terrain instances. - */ - void removeAllTerrains(); - - /** Save all terrain instances using the assigned file names, or - via the filename convention. - @see setFilenameConvention - @see setResourceGroup - @param onlyIfModified If true, only terrains that have been modified since load(), - or since the last save(), will be saved. You want to set this to true if - you loaded the terrain from these same files, but false if you - defined them using some other input data since the files wouldn't exist. - @param replaceManualFilenames If true, replaces any manually defined filenames - in the TerrainSlotDefinition with the generated names from the convention. - This is recommended since it makes everything more consistent, although - you might want to use manual filenames in the original definition to import - previously separate data. - */ - void saveAllTerrains(bool onlyIfModified, bool replaceManualFilenames = true); - - /** Definition of how to populate a 'slot' in the terrain group. - */ - struct _OgreTerrainExport TerrainSlotDefinition - { - /// Filename, if this is to be loaded from a file - String filename; - /// Import data, if this is to be defined based on importing - Terrain::ImportData* importData; - - TerrainSlotDefinition() :importData(0) {} - ~TerrainSlotDefinition(); - - /// Set to use import data - void useImportData(); - /// Set to use file name - void useFilename(); - /// Destroy temp import resources - void freeImportData(); - }; - - /** Slot for a terrain instance, together with its definition. */ - struct _OgreTerrainExport TerrainSlot : public TerrainAlloc - { - /// The coordinates of the terrain slot relative to the centre slot (signed). - long x, y; - /// Definition used to load the terrain - TerrainSlotDefinition def; - /// Actual terrain instance - Terrain* instance; - - TerrainSlot(long _x, long _y) : x(_x), y(_y), instance(0) {} - virtual ~TerrainSlot(); - void freeInstance(); - }; - - /** Get the definition of a slot in the terrain. - @remarks - Definitions exist before the actual instances to allow background loading. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - @return The definition, or null if nothing is in this slot. While this return value is - not const, you should be careful about modifying it; it will have no effect unless you load - the terrain afterwards, and can cause a race condition if you modify it while a background - load is in progress. - */ - virtual TerrainSlotDefinition* getTerrainDefinition(long x, long y) const; - - /** Get the terrain instance at a given slot, if loaded. - @param x, y The coordinates of the terrain slot relative to the centre slot (signed). - @return The terrain, or null if no terrain is loaded in this slot (call getTerrainDefinition if - you want to access the definition before it is loaded). - */ - virtual Terrain* getTerrain(long x, long y) const; - - /** Free as many resources as possible for optimal run-time memory use for all - terrain tiles. - @see Terrain::freeTemporaryResources - */ - void freeTemporaryResources(); - - /** Trigger the update process for all terrain instances. - @see Terrain::update - */ - void update(bool synchronous = false); - - /** Performs an update on all terrain geometry. - @see Terrain::updateGeometry - */ - void updateGeometry(); - - /** Updates derived data for all terrains (LOD, lighting) to reflect changed height data. - @see Terrain::updateDerivedData - */ - void updateDerivedData(bool synchronous = false, uint8 typeMask = 0xFF); - - /** Result from a terrain ray intersection with the terrain group. - */ - struct _OgreTerrainExport RayResult - { - /// Whether an intersection occurred - bool hit; - /// Which terrain instance was hit, if any - Terrain* terrain; - /// Position at which the intersection occurred - Vector3 position; - - RayResult(bool _hit, Terrain* _terrain, const Vector3& _pos) - : hit(_hit), terrain(_terrain), position(_pos) {} - }; - - /** Get the height data for a given world position (projecting the point - down on to the terrain underneath). - @param x, y,z Position in world space. Positions will be clamped to the edge - of the terrain - @param ppTerrain Pointer to a pointer to a terrain which will be completed - with the terrain that was found to resolve this query, or null if none were - */ - float getHeightAtWorldPosition(Real x, Real y, Real z, Terrain** ppTerrain = 0); - - /** Get the height data for a given world position (projecting the point - down on to the terrain). - @param pos Position in world space. Positions will be clamped to the edge - of the terrain - @param ppTerrain Pointer to a pointer to a terrain which will be completed - with the terrain that was found to resolve this query, or null if none were - */ - float getHeightAtWorldPosition(const Vector3& pos, Terrain** ppTerrain = 0); - - /** Test for intersection of a given ray with any terrain in the group. If the ray hits - a terrain, the point of intersection and terrain instance is returned. - @param ray The ray to test for intersection - @param distanceLimit The distance from the ray origin at which we will stop looking, - 0 indicates no limit - @return A result structure which contains whether the ray hit a terrain and if so, where. - @remarks This can be called from any thread as long as no parallel write to - the terrain data occurs. - */ - RayResult rayIntersects(const Ray& ray, Real distanceLimit = 0) const; - - typedef vector::type TerrainList; - /** Test intersection of a box with the terrain. - @remarks - Tests an AABB for overlap with a terrain bounding box. Note that this does not mean that the box - touches the terrain itself, just the bounding box for the terrain. You can use this to get region - results for further testing or use (e.g. painting areas). - @param box The AABB you want to test in world units - @param resultList Pointer to a list of terrain pointers which will be updated to include just - the terrains that overlap - */ - void boxIntersects(const AxisAlignedBox& box, TerrainList* resultList) const; - /** Test intersection of a sphere with the terrain. - @remarks - Tests a sphere for overlap with a terrain bounding box. Note that this does not mean that the sphere - touches the terrain itself, just the bounding box for the terrain. You can use this to get region - results for further testing or use (e.g. painting areas). - @param sphere The sphere you want to test in world units - @param resultList Pointer to a list of terrain pointers which will be updated to include just - the terrains that overlap - */ - void sphereIntersects(const Sphere& sphere, TerrainList* resultList) const; - - /** Convert a world position to terrain slot coordinates. - @param pos The world position - @param x,y Pointers to the coordinates to be completed. - */ - void convertWorldPositionToTerrainSlot(const Vector3& pos, long *x, long *y) const; - - /** Convert a slot location to a world position at the centre - @param x,y The slot coordinates - @param pos Pointer to the world position to be completed - */ - void convertTerrainSlotToWorldPosition(long x, long y, Vector3* pos) const; - - /** Calls Terrain::isDerivedDataUpdateInProgress on each loaded instance and returns true - if any of them are undergoing a derived update. - */ - bool isDerivedDataUpdateInProgress() const; - - /// Packed map, signed 16 bits for each axis from -32767 to +32767 - typedef map::type TerrainSlotMap; - typedef MapIterator TerrainIterator; - typedef ConstMapIterator ConstTerrainIterator; - - /// Get an iterator over the defined terrains. - TerrainIterator getTerrainIterator(); - /// Get an iterator over the defined terrains (const) - ConstTerrainIterator getTerrainIterator() const; - - /// WorkQueue::RequestHandler override - bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); - /// WorkQueue::RequestHandler override - WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); - /// WorkQueue::ResponseHandler override - bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - /// WorkQueue::ResponseHandler override - void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - - /// Convert coordinates to a packed integer index - uint32 packIndex(long x, long y) const; - - /// Convert a packed integer index to coordinates - void unpackIndex(uint32 key, long *x, long *y); - - /// Generate a file name based on the current naming convention - String generateFilename(long x, long y) const; - - /** Save the group data only in native form to a file. - */ - void saveGroupDefinition(const String& filename); - /** Save the group data only in native form to a serializing stream. - */ - void saveGroupDefinition(StreamSerialiser& stream); - /** Load the group definition only in native form from a file. - */ - void loadGroupDefinition(const String& filename); - /** Load the group definition only in native form from a serializing stream. - */ - void loadGroupDefinition(StreamSerialiser& stream); - - - static const uint16 WORKQUEUE_LOAD_REQUEST; - static const uint32 CHUNK_ID; - static const uint16 CHUNK_VERSION; - - /// Loads terrain's next LOD level. - void increaseLodLevel(long x, long y, bool synchronous = false); - /// Removes terrain's highest LOD level. - void decreaseLodLevel(long x, long y); - - void setAutoUpdateLod(TerrainAutoUpdateLod* updater); - /// Automatically checks if terrain's LOD level needs to be updated. - void autoUpdateLod(long x, long y, bool synchronous, const Any &data); - void autoUpdateLodAll(bool synchronous, const Any &data); - - protected: - SceneManager *mSceneManager; - Terrain::Alignment mAlignment; - uint16 mTerrainSize; - Real mTerrainWorldSize; - Terrain::ImportData mDefaultImportData; - Vector3 mOrigin; - TerrainSlotMap mTerrainSlots; - uint16 mWorkQueueChannel; - String mFilenamePrefix; - String mFilenameExtension; - String mResourceGroup; - TerrainAutoUpdateLod *mAutoUpdateLod; - Terrain::DefaultGpuBufferAllocator mBufferAllocator; - - /// Get the position of a terrain instance - Vector3 getTerrainSlotPosition(long x, long y); - /// Retrieve a slot, potentially allocate one - TerrainSlot* getTerrainSlot(long x, long y, bool createIfMissing); - TerrainSlot* getTerrainSlot(long x, long y) const; - void connectNeighbour(TerrainSlot* slot, long offsetx, long offsety); - - void loadTerrainImpl(TerrainSlot* slot, bool synchronous); - - /// Structure for holding the load request - struct LoadRequest - { - TerrainSlot* slot; - TerrainGroup* origin; - static uint loadingTaskNum; - _OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const LoadRequest& r) - { return o; } - }; - - - }; - - - /** @} */ - /** @} */ + /** Retrieve the SceneManager being used for this group. + */ + virtual SceneManager* getSceneManager() const { return mSceneManager; } + + /** Set the naming convention for file names in this terrain group. + @remarks + You can more easily generate file names for saved / loaded terrain slots + if you define a naming prefix. When you call saveAllTerrains(), all the + terrain instances currently loaded will be saved to a file named + <prefix>_<index>.<extension>, where <index> is + given by packing the x and y coordinates of the entry into a 32-bit + index (@see packIndex). + */ + void setFilenameConvention(const String& prefix, const String& extension); + /// @see setFilenameConvention + void setFilenamePrefix(const String& prefix); + /// @see setFilenameConvention + void setFilenameExtension(const String& extension); + /// @see setFilenameConvention + const String& getFilenamePrefix() const { return mFilenamePrefix; } + /// @see setFilenameConvention + const String& getFilenameExtension() const { return mFilenameExtension; } + + /** Set the resource group in which files will be located. */ + void setResourceGroup(const String& grp) { mResourceGroup = grp; } + /** Get the resource group in which files will be located. */ + const String& getResourceGroup() const { return mResourceGroup; } + /** Define a 'slot' in the terrain grid - in this case to be loaded from + a generated file name. + @remarks + At this stage the terrain instance isn't actually present in the grid, + you're merely expressing an intention for it to take its place there + once it's loaded. The reason we do it like this is to support + background preparation of this terrain instance. + @note This method assumes that you want a file name to be generated from + the naming convention that you have supplied (@see setFilenameConvention). + If a file of that name isn't found during loading, then a flat terrain is + created instead at height 0. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + */ + virtual void defineTerrain(long x, long y); + + /** Define a 'slot' in the terrain grid - in this case a flat terrain. + @remarks + At this stage the terrain instance isn't actually present in the grid, + you're merely expressing an intention for it to take its place there + once it's loaded. The reason we do it like this is to support + background preparation of this terrain instance. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + @param constantHeight The constant, uniform height that you want the terrain + to start at + */ + virtual void defineTerrain(long x, long y, float constantHeight); + + /** Define the content of a 'slot' in the terrain grid. + @remarks + At this stage the terrain instance isn't actually present in the grid, + you're merely expressing an intention for it to take its place there + once it's loaded. The reason we do it like this is to support + background preparation of this terrain instance. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + @param importData Import data - this data is copied during the + call so you may destroy your copy afterwards. + */ + virtual void defineTerrain(long x, long y, const Terrain::ImportData* importData); + + /** Define the content of a 'slot' in the terrain grid. + @remarks + At this stage the terrain instance isn't actually present in the grid, + you're merely expressing an intention for it to take its place there + once it's loaded. The reason we do it like this is to support + background preparation of this terrain instance. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + @param img Heightfield image - this data is copied during the call so you may destroy your copy afterwards. + @param layers Optional texture layers to use (if not supplied, default import + data layers will be used) - this data is copied during the + call so you may destroy your copy afterwards. + */ + virtual void defineTerrain(long x, long y, const Image* img, const Terrain::LayerInstanceList* layers = 0); + + /** Define the content of a 'slot' in the terrain grid. + @remarks + At this stage the terrain instance isn't actually present in the grid, + you're merely expressing an intention for it to take its place there + once it's loaded. The reason we do it like this is to support + background preparation of this terrain instance. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + @param pFloat Heights array + @param layers Optional texture layers to use (if not supplied, default import + data layers will be used) - this data is copied during the + call so you may destroy your copy afterwards. + */ + virtual void defineTerrain(long x, long y, const float* pFloat, const Terrain::LayerInstanceList* layers = 0); + + /** Define the content of a 'slot' in the terrain grid. + @remarks + At this stage the terrain instance isn't actually present in the grid, + you're merely expressing an intention for it to take its place there + once it's loaded. The reason we do it like this is to support + background preparation of this terrain instance. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + @param filename The name of a file which fully defines the terrain (as + written by Terrain::save). Size settings from all files must agree. + */ + virtual void defineTerrain(long x, long y, const String& filename); + + + /** Load any terrain instances that have been defined but not loaded yet. + @param synchronous Whether we should force this to happen entirely in the + primary thread (default false, operations are threaded if possible) + */ + virtual void loadAllTerrains(bool synchronous = false); + + /** Load a specific terrain slot based on the definition that has already + been supplied. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + @param synchronous Whether we should force this to happen entirely in the + primary thread (default false, operations are threaded if possible) + */ + virtual void loadTerrain(long x, long y, bool synchronous = false); + + /** Unload a specific terrain slot. + @remarks + This destroys the Terrain instance but retains the slot definition (so + it would be reloaded next time you call loadAllTerrains() if you did not + remove it beforehand). + @note + While the definition of the terrain is kept, if you used import data + to populate it, this will have been lost so repeat loading cannot occur. + The only way to support repeat loading is via the 'filename' option of + defineTerrain instead. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + */ + virtual void unloadTerrain(long x, long y); + + /** Remove a specific terrain slot. + @remarks + This destroys any Terrain instance at this position and also removes the + definition, so it essentially no longer exists. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + */ + virtual void removeTerrain(long x, long y); + + /** Remove all terrain instances. + */ + void removeAllTerrains(); + + /** Save all terrain instances using the assigned file names, or + via the filename convention. + @see setFilenameConvention + @see setResourceGroup + @param onlyIfModified If true, only terrains that have been modified since load(), + or since the last save(), will be saved. You want to set this to true if + you loaded the terrain from these same files, but false if you + defined them using some other input data since the files wouldn't exist. + @param replaceManualFilenames If true, replaces any manually defined filenames + in the TerrainSlotDefinition with the generated names from the convention. + This is recommended since it makes everything more consistent, although + you might want to use manual filenames in the original definition to import + previously separate data. + */ + void saveAllTerrains(bool onlyIfModified, bool replaceManualFilenames = true); + + /** Definition of how to populate a 'slot' in the terrain group. + */ + struct _OgreTerrainExport TerrainSlotDefinition + { + /// Filename, if this is to be loaded from a file + String filename; + /// Import data, if this is to be defined based on importing + Terrain::ImportData* importData; + + TerrainSlotDefinition() :importData(0) {} + ~TerrainSlotDefinition(); + + /// Set to use import data + void useImportData(); + /// Set to use file name + void useFilename(); + /// Destroy temp import resources + void freeImportData(); + }; + + /** Slot for a terrain instance, together with its definition. */ + struct _OgreTerrainExport TerrainSlot : public TerrainAlloc + { + /// The coordinates of the terrain slot relative to the centre slot (signed). + long x, y; + /// Definition used to load the terrain + TerrainSlotDefinition def; + /// Actual terrain instance + Terrain* instance; + + TerrainSlot(long _x, long _y) : x(_x), y(_y), instance(0) {} + virtual ~TerrainSlot(); + void freeInstance(); + }; + + /** Get the definition of a slot in the terrain. + @remarks + Definitions exist before the actual instances to allow background loading. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + @return The definition, or null if nothing is in this slot. While this return value is + not const, you should be careful about modifying it; it will have no effect unless you load + the terrain afterwards, and can cause a race condition if you modify it while a background + load is in progress. + */ + virtual TerrainSlotDefinition* getTerrainDefinition(long x, long y) const; + + /** Get the terrain instance at a given slot, if loaded. + @param x, y The coordinates of the terrain slot relative to the centre slot (signed). + @return The terrain, or null if no terrain is loaded in this slot (call getTerrainDefinition if + you want to access the definition before it is loaded). + */ + virtual Terrain* getTerrain(long x, long y) const; + + /** Free as many resources as possible for optimal run-time memory use for all + terrain tiles. + @see Terrain::freeTemporaryResources + */ + void freeTemporaryResources(); + + /** Trigger the update process for all terrain instances. + @see Terrain::update + */ + void update(bool synchronous = false); + + /** Performs an update on all terrain geometry. + @see Terrain::updateGeometry + */ + void updateGeometry(); + + /** Updates derived data for all terrains (LOD, lighting) to reflect changed height data. + @see Terrain::updateDerivedData + */ + void updateDerivedData(bool synchronous = false, uint8 typeMask = 0xFF); + + /** Result from a terrain ray intersection with the terrain group. + */ + struct _OgreTerrainExport RayResult + { + /// Whether an intersection occurred + bool hit; + /// Which terrain instance was hit, if any + Terrain* terrain; + /// Position at which the intersection occurred + Vector3 position; + + RayResult(bool _hit, Terrain* _terrain, const Vector3& _pos) + : hit(_hit), terrain(_terrain), position(_pos) {} + }; + + /** Get the height data for a given world position (projecting the point + down on to the terrain underneath). + @param x, y,z Position in world space. Positions will be clamped to the edge + of the terrain + @param ppTerrain Pointer to a pointer to a terrain which will be completed + with the terrain that was found to resolve this query, or null if none were + */ + float getHeightAtWorldPosition(Real x, Real y, Real z, Terrain** ppTerrain = 0); + + /** Get the height data for a given world position (projecting the point + down on to the terrain). + @param pos Position in world space. Positions will be clamped to the edge + of the terrain + @param ppTerrain Pointer to a pointer to a terrain which will be completed + with the terrain that was found to resolve this query, or null if none were + */ + float getHeightAtWorldPosition(const Vector3& pos, Terrain** ppTerrain = 0); + + /** Test for intersection of a given ray with any terrain in the group. If the ray hits + a terrain, the point of intersection and terrain instance is returned. + @param ray The ray to test for intersection + @param distanceLimit The distance from the ray origin at which we will stop looking, + 0 indicates no limit + @return A result structure which contains whether the ray hit a terrain and if so, where. + @remarks This can be called from any thread as long as no parallel write to + the terrain data occurs. + */ + RayResult rayIntersects(const Ray& ray, Real distanceLimit = 0) const; + + typedef vector::type TerrainList; + /** Test intersection of a box with the terrain. + @remarks + Tests an AABB for overlap with a terrain bounding box. Note that this does not mean that the box + touches the terrain itself, just the bounding box for the terrain. You can use this to get region + results for further testing or use (e.g. painting areas). + @param box The AABB you want to test in world units + @param resultList Pointer to a list of terrain pointers which will be updated to include just + the terrains that overlap + */ + void boxIntersects(const AxisAlignedBox& box, TerrainList* resultList) const; + /** Test intersection of a sphere with the terrain. + @remarks + Tests a sphere for overlap with a terrain bounding box. Note that this does not mean that the sphere + touches the terrain itself, just the bounding box for the terrain. You can use this to get region + results for further testing or use (e.g. painting areas). + @param sphere The sphere you want to test in world units + @param resultList Pointer to a list of terrain pointers which will be updated to include just + the terrains that overlap + */ + void sphereIntersects(const Sphere& sphere, TerrainList* resultList) const; + + /** Convert a world position to terrain slot coordinates. + @param pos The world position + @param x,y Pointers to the coordinates to be completed. + */ + void convertWorldPositionToTerrainSlot(const Vector3& pos, long *x, long *y) const; + + /** Convert a slot location to a world position at the centre + @param x,y The slot coordinates + @param pos Pointer to the world position to be completed + */ + void convertTerrainSlotToWorldPosition(long x, long y, Vector3* pos) const; + + /** Calls Terrain::isDerivedDataUpdateInProgress on each loaded instance and returns true + if any of them are undergoing a derived update. + */ + bool isDerivedDataUpdateInProgress() const; + + /// Packed map, signed 16 bits for each axis from -32767 to +32767 + typedef map::type TerrainSlotMap; + typedef MapIterator TerrainIterator; + typedef ConstMapIterator ConstTerrainIterator; + + /// Get an iterator over the defined terrains. + TerrainIterator getTerrainIterator(); + /// Get an iterator over the defined terrains (const) + ConstTerrainIterator getTerrainIterator() const; + + /// WorkQueue::RequestHandler override + bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + /// WorkQueue::RequestHandler override + WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + /// WorkQueue::ResponseHandler override + bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + /// WorkQueue::ResponseHandler override + void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + + /// Convert coordinates to a packed integer index + uint32 packIndex(long x, long y) const; + + /// Convert a packed integer index to coordinates + void unpackIndex(uint32 key, long *x, long *y); + + /// Generate a file name based on the current naming convention + String generateFilename(long x, long y) const; + + /** Save the group data only in native form to a file. + */ + void saveGroupDefinition(const String& filename); + /** Save the group data only in native form to a serializing stream. + */ + void saveGroupDefinition(StreamSerialiser& stream); + /** Load the group definition only in native form from a file. + */ + void loadGroupDefinition(const String& filename); + /** Load the group definition only in native form from a serializing stream. + */ + void loadGroupDefinition(StreamSerialiser& stream); + + + static const uint16 WORKQUEUE_LOAD_REQUEST; + static const uint32 CHUNK_ID; + static const uint16 CHUNK_VERSION; + + /// Loads terrain's next LOD level. + void increaseLodLevel(long x, long y, bool synchronous = false); + /// Removes terrain's highest LOD level. + void decreaseLodLevel(long x, long y); + + void setAutoUpdateLod(TerrainAutoUpdateLod* updater); + /// Automatically checks if terrain's LOD level needs to be updated. + void autoUpdateLod(long x, long y, bool synchronous, const Any &data); + void autoUpdateLodAll(bool synchronous, const Any &data); + + protected: + SceneManager *mSceneManager; + Terrain::Alignment mAlignment; + uint16 mTerrainSize; + Real mTerrainWorldSize; + Terrain::ImportData mDefaultImportData; + Vector3 mOrigin; + TerrainSlotMap mTerrainSlots; + uint16 mWorkQueueChannel; + String mFilenamePrefix; + String mFilenameExtension; + String mResourceGroup; + TerrainAutoUpdateLod *mAutoUpdateLod; + Terrain::DefaultGpuBufferAllocator mBufferAllocator; + + /// Get the position of a terrain instance + Vector3 getTerrainSlotPosition(long x, long y); + /// Retrieve a slot, potentially allocate one + TerrainSlot* getTerrainSlot(long x, long y, bool createIfMissing); + TerrainSlot* getTerrainSlot(long x, long y) const; + void connectNeighbour(TerrainSlot* slot, long offsetx, long offsety); + + void loadTerrainImpl(TerrainSlot* slot, bool synchronous); + + /// Structure for holding the load request + struct LoadRequest + { + TerrainSlot* slot; + TerrainGroup* origin; + static uint loadingTaskNum; + _OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const LoadRequest& r) + { return o; } + }; + + + }; + + + /** @} */ + /** @} */ } diff --git a/Components/Terrain/include/OgreTerrainLayerBlendMap.h b/Components/Terrain/include/OgreTerrainLayerBlendMap.h index 73bd01ed6de..5fbfd9ef5ea 100644 --- a/Components/Terrain/include/OgreTerrainLayerBlendMap.h +++ b/Components/Terrain/include/OgreTerrainLayerBlendMap.h @@ -35,160 +35,160 @@ THE SOFTWARE. namespace Ogre { - class Image; - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Terrain - * Some details on the terrain component - * @{ - */ - - - /** Class exposing an interface to a blend map for a given layer. - Each layer after the first layer in a terrain has a blend map which - expresses how it is alpha blended with the layers beneath. Internally, this - blend map is packed into one channel of an RGB or RGBA texture in - order to use the smallest number of samplers, but this class allows - a caller to manipulate the data more easily without worrying about - this packing. Also, the values you use to interact with the blend map are - floating point, which gives you full precision for updating, but in fact the - values are packed into 8-bit integers in the actual blend map. - @par - You shouldn't construct this class directly, use Terrain::getLayerBlendMap(). - */ - class _OgreTerrainExport TerrainLayerBlendMap : public TerrainAlloc - { - protected: - Terrain* mParent; - uint8 mLayerIdx; - uint8 mChannel; // RGBA - uint8 mChannelOffset; // in pixel format - Box mDirtyBox; - bool mDirty; - HardwarePixelBuffer* mBuffer; - float* mData; - - void download(); - void upload(); - - public: - /** Constructor - @param parent The parent terrain - @param layerIndex The layer index (should be 1 or higher) - @param buf The buffer holding the data - */ - TerrainLayerBlendMap(Terrain* parent, uint8 layerIndex, HardwarePixelBuffer* buf); - virtual ~TerrainLayerBlendMap(); - /// Get the parent terrain - Terrain* getParent() const { return mParent; } - /// Get the index of the layer this is targeting - uint8 getLayerIndex() const { return mLayerIdx; } - - /** Helper method - convert a point in world space to UV space based on the - terrain settings. - @param worldPos World position - @param outX, outY Pointers to variables which will be filled in with the - local UV space value. Note they are deliberately signed Real values, because the - point you supply may be outside of image space and may be between texels. - The values will range from 0 to 1, top/bottom, left/right. - */ - void convertWorldToUVSpace(const Vector3& worldPos, Real *outX, Real* outY); - - /** Helper method - convert a point in local space to worldspace based on the - terrain settings. - @param x,y Local position, ranging from 0 to 1, top/bottom, left/right. - @param outWorldPos Pointer will be filled in with the world space value - */ - void convertUVToWorldSpace(Real x, Real y, Vector3* outWorldPos); - - /** Convert local space values (0,1) to image space (0, imageSize). - */ - void convertUVToImageSpace(Real x, Real y, size_t* outX, size_t* outY); - /** Convert image space (0, imageSize) to local space values (0,1). - */ - void convertImageToUVSpace(size_t x, size_t y, Real* outX, Real* outY); - /** Convert image space (0, imageSize) to terrain space values (0,1). - */ - void convertImageToTerrainSpace(size_t x, size_t y, Real* outX, Real* outY); - /** Convert terrain space values (0,1) to image space (0, imageSize). - */ - void convertTerrainToImageSpace(Real x, Real y, size_t* outX, size_t* outY); - - /** Get a single value of blend information, in image space. - @param x,y Coordinates of the point of data to get, in image space (top down) - @return The blend data - */ - float getBlendValue(size_t x, size_t y); - - /** Set a single value of blend information (0 = transparent, 255 = solid) - @param x,y Coordinates of the point of data to get, in image space (top down) - @param val The blend value to set (0..1) - */ - void setBlendValue(size_t x, size_t y, float val); - - /** Get a pointer to the whole blend data. - @remarks - This method allows you to get a raw pointer to all the blend data, to - update it as you like. However, you must then call dirtyRect manually - if you want those changes to be recognised. - */ - float* getBlendPointer(); - - /** Indicate that all of the blend data is dirty and needs updating. - */ - void dirty(); - - /** Indicate that a portion of the blend data is dirty and needs updating. - @param rect Rectangle in image space - */ - void dirtyRect(const Rect& rect); - - /** Blits a set of values into a region on the blend map. - @param src PixelBox containing the source pixels and format - @param dstBox Image::Box describing the destination region in this map + class Image; + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Terrain + * Some details on the terrain component + * @{ + */ + + + /** Class exposing an interface to a blend map for a given layer. + Each layer after the first layer in a terrain has a blend map which + expresses how it is alpha blended with the layers beneath. Internally, this + blend map is packed into one channel of an RGB or RGBA texture in + order to use the smallest number of samplers, but this class allows + a caller to manipulate the data more easily without worrying about + this packing. Also, the values you use to interact with the blend map are + floating point, which gives you full precision for updating, but in fact the + values are packed into 8-bit integers in the actual blend map. + @par + You shouldn't construct this class directly, use Terrain::getLayerBlendMap(). + */ + class _OgreTerrainExport TerrainLayerBlendMap : public TerrainAlloc + { + protected: + Terrain* mParent; + uint8 mLayerIdx; + uint8 mChannel; // RGBA + uint8 mChannelOffset; // in pixel format + Box mDirtyBox; + bool mDirty; + HardwarePixelBuffer* mBuffer; + float* mData; + + void download(); + void upload(); + + public: + /** Constructor + @param parent The parent terrain + @param layerIndex The layer index (should be 1 or higher) + @param buf The buffer holding the data + */ + TerrainLayerBlendMap(Terrain* parent, uint8 layerIndex, HardwarePixelBuffer* buf); + virtual ~TerrainLayerBlendMap(); + /// Get the parent terrain + Terrain* getParent() const { return mParent; } + /// Get the index of the layer this is targeting + uint8 getLayerIndex() const { return mLayerIdx; } + + /** Helper method - convert a point in world space to UV space based on the + terrain settings. + @param worldPos World position + @param outX, outY Pointers to variables which will be filled in with the + local UV space value. Note they are deliberately signed Real values, because the + point you supply may be outside of image space and may be between texels. + The values will range from 0 to 1, top/bottom, left/right. + */ + void convertWorldToUVSpace(const Vector3& worldPos, Real *outX, Real* outY); + + /** Helper method - convert a point in local space to worldspace based on the + terrain settings. + @param x,y Local position, ranging from 0 to 1, top/bottom, left/right. + @param outWorldPos Pointer will be filled in with the world space value + */ + void convertUVToWorldSpace(Real x, Real y, Vector3* outWorldPos); + + /** Convert local space values (0,1) to image space (0, imageSize). + */ + void convertUVToImageSpace(Real x, Real y, size_t* outX, size_t* outY); + /** Convert image space (0, imageSize) to local space values (0,1). + */ + void convertImageToUVSpace(size_t x, size_t y, Real* outX, Real* outY); + /** Convert image space (0, imageSize) to terrain space values (0,1). + */ + void convertImageToTerrainSpace(size_t x, size_t y, Real* outX, Real* outY); + /** Convert terrain space values (0,1) to image space (0, imageSize). + */ + void convertTerrainToImageSpace(Real x, Real y, size_t* outX, size_t* outY); + + /** Get a single value of blend information, in image space. + @param x,y Coordinates of the point of data to get, in image space (top down) + @return The blend data + */ + float getBlendValue(size_t x, size_t y); + + /** Set a single value of blend information (0 = transparent, 255 = solid) + @param x,y Coordinates of the point of data to get, in image space (top down) + @param val The blend value to set (0..1) + */ + void setBlendValue(size_t x, size_t y, float val); + + /** Get a pointer to the whole blend data. + @remarks + This method allows you to get a raw pointer to all the blend data, to + update it as you like. However, you must then call dirtyRect manually + if you want those changes to be recognised. + */ + float* getBlendPointer(); + + /** Indicate that all of the blend data is dirty and needs updating. + */ + void dirty(); + + /** Indicate that a portion of the blend data is dirty and needs updating. + @param rect Rectangle in image space + */ + void dirtyRect(const Rect& rect); + + /** Blits a set of values into a region on the blend map. + @param src PixelBox containing the source pixels and format + @param dstBox Image::Box describing the destination region in this map @remarks The source and destination regions dimensions don't have to match, in which case scaling is done. - @note You can call this method in a background thread if you want. - You still need to call update() to commit the changes to the GPU. - */ - void blit(const PixelBox &src, const Box &dstBox); - - /** Blits a set of values into the entire map. The source data is scaled if needed. - @param src PixelBox containing the source pixels and format - @note You can call this method in a background thread if you want. - You still need to call update() to commit the changes to the GPU. - - */ - void blit(const PixelBox &src); - - /** Load an image into this blend layer. - */ - void loadImage(const Image& img); - - /** Load an image into this blend layer. - @param stream Stream containing the image data - @param ext Extension identifying the image type, if the stream data doesn't identify - */ - void loadImage(DataStreamPtr& stream, const String& ext = BLANKSTRING); - - /** Load an image into this blend layer. - */ - void loadImage(const String& filename, const String& groupName); - - /** Publish any changes you made to the blend data back to the blend map. - @note - Can only be called in the main render thread. - */ - void update(); - - - }; - - typedef vector::type TerrainLayerBlendMapList; - - /** @} */ - /** @} */ + @note You can call this method in a background thread if you want. + You still need to call update() to commit the changes to the GPU. + */ + void blit(const PixelBox &src, const Box &dstBox); + + /** Blits a set of values into the entire map. The source data is scaled if needed. + @param src PixelBox containing the source pixels and format + @note You can call this method in a background thread if you want. + You still need to call update() to commit the changes to the GPU. + + */ + void blit(const PixelBox &src); + + /** Load an image into this blend layer. + */ + void loadImage(const Image& img); + + /** Load an image into this blend layer. + @param stream Stream containing the image data + @param ext Extension identifying the image type, if the stream data doesn't identify + */ + void loadImage(DataStreamPtr& stream, const String& ext = BLANKSTRING); + + /** Load an image into this blend layer. + */ + void loadImage(const String& filename, const String& groupName); + + /** Publish any changes you made to the blend data back to the blend map. + @note + Can only be called in the main render thread. + */ + void update(); + + + }; + + typedef vector::type TerrainLayerBlendMapList; + + /** @} */ + /** @} */ } diff --git a/Components/Terrain/include/OgreTerrainLodManager.h b/Components/Terrain/include/OgreTerrainLodManager.h index 3aa5babb428..4d649337757 100644 --- a/Components/Terrain/include/OgreTerrainLodManager.h +++ b/Components/Terrain/include/OgreTerrainLodManager.h @@ -35,132 +35,132 @@ THE SOFTWARE. namespace Ogre { - class Terrain; - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Terrain - * Some details on the terrain LOD manager - * @{ - */ - - /** Terrain LOD data manager - @par - This class is used for managing terrain LOD data's loading, unloading. - */ - - class _OgreTerrainExport TerrainLodManager : public WorkQueue::RequestHandler, public WorkQueue::ResponseHandler, public TerrainAlloc - { - public: - static const uint32 TERRAINLODDATA_CHUNK_ID; - static const uint16 TERRAINLODDATA_CHUNK_VERSION; - typedef vector::type LodData; - typedef vector::type LodsData; - - struct LoadLodRequest - { - LoadLodRequest( TerrainLodManager* r, uint16 preparedLod, uint16 loadedLod, uint16 target ) - : requestee(r) - , currentPreparedLod(preparedLod) - , currentLoadedLod(loadedLod) - , requestedLod(target) - { - } - TerrainLodManager* requestee; - uint16 currentPreparedLod; - uint16 currentLoadedLod; - uint16 requestedLod; - _OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const LoadLodRequest& r) - { return o; } - }; - - struct LodInfo - { - uint treeStart; - uint treeEnd; - bool isLast; - uint16 resolution; - uint size; - }; - public: + class Terrain; + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Terrain + * Some details on the terrain LOD manager + * @{ + */ + + /** Terrain LOD data manager + @par + This class is used for managing terrain LOD data's loading, unloading. + */ + + class _OgreTerrainExport TerrainLodManager : public WorkQueue::RequestHandler, public WorkQueue::ResponseHandler, public TerrainAlloc + { + public: + static const uint32 TERRAINLODDATA_CHUNK_ID; + static const uint16 TERRAINLODDATA_CHUNK_VERSION; + typedef vector::type LodData; + typedef vector::type LodsData; + + struct LoadLodRequest + { + LoadLodRequest( TerrainLodManager* r, uint16 preparedLod, uint16 loadedLod, uint16 target ) + : requestee(r) + , currentPreparedLod(preparedLod) + , currentLoadedLod(loadedLod) + , requestedLod(target) + { + } + TerrainLodManager* requestee; + uint16 currentPreparedLod; + uint16 currentLoadedLod; + uint16 requestedLod; + _OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const LoadLodRequest& r) + { return o; } + }; + + struct LodInfo + { + uint treeStart; + uint treeEnd; + bool isLast; + uint16 resolution; + uint size; + }; + public: TerrainLodManager(Terrain* t, DataStreamPtr& stream); TerrainLodManager(Terrain* t, const String& filename = ""); virtual ~TerrainLodManager(); - static const uint16 WORKQUEUE_LOAD_LOD_DATA_REQUEST; - virtual bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); - virtual bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + static const uint16 WORKQUEUE_LOAD_LOD_DATA_REQUEST; + virtual bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + virtual bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); virtual WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); virtual void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - void updateToLodLevel(int lodLevel, bool synchronous = false); - /// Save each LOD level separately compressed so seek is possible - static void saveLodData(StreamSerialiser& stream, Terrain* terrain); - - /** Copy geometry data from buffer to mHeightData/mDeltaData - @param lodLevel A LOD level to work with - @param data Buffer which holds geometry data if separated form - @remarks Data in buffer has to be both height and delta data. First half is height data. - Seconds half is delta data. - */ - void fillBufferAtLod(uint lodLevel, const float* data, uint dataSize ); - /** Read separated geometry data from file into allocated memory - @param lowerLodBound Lower bound of LOD levels to load + void updateToLodLevel(int lodLevel, bool synchronous = false); + /// Save each LOD level separately compressed so seek is possible + static void saveLodData(StreamSerialiser& stream, Terrain* terrain); + + /** Copy geometry data from buffer to mHeightData/mDeltaData + @param lodLevel A LOD level to work with + @param data Buffer which holds geometry data if separated form + @remarks Data in buffer has to be both height and delta data. First half is height data. + Seconds half is delta data. + */ + void fillBufferAtLod(uint lodLevel, const float* data, uint dataSize ); + /** Read separated geometry data from file into allocated memory + @param lowerLodBound Lower bound of LOD levels to load @param higherLodBound Upper bound of LOD levels to load - @remarks Geometry data are uncompressed using inflate() and stored into - allocated buffer - */ - void readLodData(uint16 lowerLodBound, uint16 higherLodBound); - void waitForDerivedProcesses(); - - int getHighestLodPrepared(){ return mHighestLodPrepared; } - int getHighestLodLoaded(){ return mHighestLodLoaded; } - int getTargetLodLevel(){ return mTargetLodLevel; } - - LodInfo& getLodInfo(uint lodLevel) - { - if(!mLodInfoTable) - buildLodInfoTable(); - return mLodInfoTable[lodLevel]; - } - private: - void init(); - void buildLodInfoTable(); - - /** Separate geometry data by LOD level - @param data A geometry data to separate i.e. mHeightData/mDeltaData + @remarks Geometry data are uncompressed using inflate() and stored into + allocated buffer + */ + void readLodData(uint16 lowerLodBound, uint16 higherLodBound); + void waitForDerivedProcesses(); + + int getHighestLodPrepared(){ return mHighestLodPrepared; } + int getHighestLodLoaded(){ return mHighestLodLoaded; } + int getTargetLodLevel(){ return mTargetLodLevel; } + + LodInfo& getLodInfo(uint lodLevel) + { + if(!mLodInfoTable) + buildLodInfoTable(); + return mLodInfoTable[lodLevel]; + } + private: + void init(); + void buildLodInfoTable(); + + /** Separate geometry data by LOD level + @param data A geometry data to separate i.e. mHeightData/mDeltaData @param size Dimension of the input data @param numLodLevels Number of LOD levels in the input data @param lods The separated LOD data @remarks Allocates new array and fills it with geometry data coupled by LOD level from lowest LOD level to highest. Example: - before separation: - 00 01 02 03 04 - 05 06 07 08 09 - 10 11 12 13 14 - 15 16 17 18 19 - 20 21 22 23 24 - after separation: - 2: 00 04 20 24 - 1: 02 10 12 14 22 - 0: 01 03 05 06 07 08 09 11 13 15 16 17 18 19 21 23 - */ - static void separateData(float* data, uint16 size, uint16 numLodLevels, LodsData& lods ); - private: - Terrain* mTerrain; - DataStreamPtr mDataStream; - size_t mStreamOffset; - uint16 mWorkQueueChannel; - - LodInfo* mLodInfoTable; - int mTargetLodLevel; /// Which LOD level is demanded - int mHighestLodPrepared; /// Highest LOD level stored in memory i.e. mHeightData/mDeltaData - int mHighestLodLoaded; /// Highest LOD level loaded in GPU - - bool mIncreaseLodLevelInProgress; /// Is increaseLodLevel() running? - bool mLastRequestSynchronous; - }; - /** @} */ - /** @} */ + before separation: + 00 01 02 03 04 + 05 06 07 08 09 + 10 11 12 13 14 + 15 16 17 18 19 + 20 21 22 23 24 + after separation: + 2: 00 04 20 24 + 1: 02 10 12 14 22 + 0: 01 03 05 06 07 08 09 11 13 15 16 17 18 19 21 23 + */ + static void separateData(float* data, uint16 size, uint16 numLodLevels, LodsData& lods ); + private: + Terrain* mTerrain; + DataStreamPtr mDataStream; + size_t mStreamOffset; + uint16 mWorkQueueChannel; + + LodInfo* mLodInfoTable; + int mTargetLodLevel; /// Which LOD level is demanded + int mHighestLodPrepared; /// Highest LOD level stored in memory i.e. mHeightData/mDeltaData + int mHighestLodLoaded; /// Highest LOD level loaded in GPU + + bool mIncreaseLodLevelInProgress; /// Is increaseLodLevel() running? + bool mLastRequestSynchronous; + }; + /** @} */ + /** @} */ } #endif diff --git a/Components/Terrain/include/OgreTerrainMaterialGenerator.h b/Components/Terrain/include/OgreTerrainMaterialGenerator.h index a9781e7733b..44a23181fe5 100644 --- a/Components/Terrain/include/OgreTerrainMaterialGenerator.h +++ b/Components/Terrain/include/OgreTerrainMaterialGenerator.h @@ -35,384 +35,384 @@ THE SOFTWARE. namespace Ogre { - class Terrain; - - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Terrain - * Some details on the terrain component - * @{ - */ - - - /** Enumeration of types of data that can be read from textures that are - specific to a given layer. Notice that global texture information - such as shadows and terrain normals are not represented - here because they are not a per-layer attribute, and blending - is stored in packed texture structures which are stored separately. - */ - enum TerrainLayerSamplerSemantic - { - /// Albedo colour (diffuse reflectance colour) - TLSS_ALBEDO = 0, - /// Tangent-space normal information from a detail texture - TLSS_NORMAL = 1, - /// Height information for the detail texture - TLSS_HEIGHT = 2, - /// Specular reflectance - TLSS_SPECULAR = 3 - }; - - /** Information about one element of a sampler / texture within a layer. - */ - struct _OgreTerrainExport TerrainLayerSamplerElement - { - /// The source sampler index of this element relative to LayerDeclaration's list - uint8 source; - /// The semantic this element represents - TerrainLayerSamplerSemantic semantic; - /// The colour element at which this element starts - uint8 elementStart; - /// The number of colour elements this semantic uses (usually standard per semantic) - uint8 elementCount; - - bool operator==(const TerrainLayerSamplerElement& e) const - { - return source == e.source && - semantic == e.semantic && - elementStart == e.elementStart && - elementCount == e.elementCount; - } - - TerrainLayerSamplerElement() : + class Terrain; + + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Terrain + * Some details on the terrain component + * @{ + */ + + + /** Enumeration of types of data that can be read from textures that are + specific to a given layer. Notice that global texture information + such as shadows and terrain normals are not represented + here because they are not a per-layer attribute, and blending + is stored in packed texture structures which are stored separately. + */ + enum TerrainLayerSamplerSemantic + { + /// Albedo colour (diffuse reflectance colour) + TLSS_ALBEDO = 0, + /// Tangent-space normal information from a detail texture + TLSS_NORMAL = 1, + /// Height information for the detail texture + TLSS_HEIGHT = 2, + /// Specular reflectance + TLSS_SPECULAR = 3 + }; + + /** Information about one element of a sampler / texture within a layer. + */ + struct _OgreTerrainExport TerrainLayerSamplerElement + { + /// The source sampler index of this element relative to LayerDeclaration's list + uint8 source; + /// The semantic this element represents + TerrainLayerSamplerSemantic semantic; + /// The colour element at which this element starts + uint8 elementStart; + /// The number of colour elements this semantic uses (usually standard per semantic) + uint8 elementCount; + + bool operator==(const TerrainLayerSamplerElement& e) const + { + return source == e.source && + semantic == e.semantic && + elementStart == e.elementStart && + elementCount == e.elementCount; + } + + TerrainLayerSamplerElement() : source(0), semantic(TLSS_ALBEDO), elementStart(0), elementCount(0) {} - TerrainLayerSamplerElement(uint8 src, TerrainLayerSamplerSemantic sem, - uint8 elemStart, uint8 elemCount) - : source(src), semantic(sem), elementStart(elemStart), elementCount(elemCount) - { - } - }; - typedef vector::type TerrainLayerSamplerElementList; - - /** Description of a sampler that will be used with each layer. - */ - struct _OgreTerrainExport TerrainLayerSampler - { - /// A descriptive name that is merely used to assist in recognition - String alias; - /// The format required of this texture - PixelFormat format; - - bool operator==(const TerrainLayerSampler& s) const - { - return alias == s.alias && format == s.format; - } + TerrainLayerSamplerElement(uint8 src, TerrainLayerSamplerSemantic sem, + uint8 elemStart, uint8 elemCount) + : source(src), semantic(sem), elementStart(elemStart), elementCount(elemCount) + { + } + }; + typedef vector::type TerrainLayerSamplerElementList; + + /** Description of a sampler that will be used with each layer. + */ + struct _OgreTerrainExport TerrainLayerSampler + { + /// A descriptive name that is merely used to assist in recognition + String alias; + /// The format required of this texture + PixelFormat format; + + bool operator==(const TerrainLayerSampler& s) const + { + return alias == s.alias && format == s.format; + } TerrainLayerSampler() : alias(""), format(PF_UNKNOWN) { } - TerrainLayerSampler(const String& aliasName, PixelFormat fmt) - : alias(aliasName), format(fmt) - { - } - }; - typedef vector::type TerrainLayerSamplerList; - - /** The definition of the information each layer will contain in this terrain. - All layers must contain the same structure of information, although the - input textures can be different per layer instance. - */ - struct _OgreTerrainExport TerrainLayerDeclaration - { - TerrainLayerSamplerList samplers; - TerrainLayerSamplerElementList elements; - - bool operator==(const TerrainLayerDeclaration& dcl) const - { - return samplers == dcl.samplers && elements == dcl.elements; - } - }; - - /** Class that provides functionality to generate materials for use with a terrain. - @remarks - Terrains are composed of one or more layers of texture information, and - require that a material is generated to render them. There are various approaches - to rendering the terrain, which may vary due to: -
      • Hardware support (static)
      • -
      • Texture instances assigned to a particular terrain (dynamic in an editor)
      • -
      • User selection (e.g. changing to a cheaper option in order to increase performance, - or in order to test how the material might look on other hardware (dynamic)
      • -
      - Subclasses of this class are responsible for responding to these factors and - to generate a terrain material. - @par - In order to cope with both hardware support and user selection, the generator - must expose a number of named 'profiles'. These profiles should function on - a known range of hardware, and be graded by quality. At runtime, the user - should be able to select the profile they wish to use (provided hardware - support is available). - */ - class _OgreTerrainExport TerrainMaterialGenerator : public TerrainAlloc - { - public: - /** Inner class which should also be subclassed to provide profile-specific - material generation. - */ - class _OgreTerrainExport Profile : public TerrainAlloc - { - protected: - TerrainMaterialGenerator* mParent; - String mName; - String mDesc; - public: - Profile(TerrainMaterialGenerator* parent, const String& name, const String& desc) - : mParent(parent), mName(name), mDesc(desc) {} - Profile(const Profile& prof) - : mParent(prof.mParent), mName(prof.mName), mDesc(prof.mDesc) {} - virtual ~Profile() {} - /// Get the generator which owns this profile - TerrainMaterialGenerator* getParent() const { return mParent; } - /// Get the name of this profile - const String& getName() const { return mName; } - /// Get the description of this profile - const String& getDescription() const { return mDesc; } - /// Compressed vertex format supported? - virtual bool isVertexCompressionSupported() const = 0; - /// Generate / reuse a material for the terrain - virtual MaterialPtr generate(const Terrain* terrain) = 0; - /// Generate / reuse a material for the terrain - virtual MaterialPtr generateForCompositeMap(const Terrain* terrain) = 0; - /// Whether to support a light map over the terrain in the shader, if it's present (default true) - virtual void setLightmapEnabled(bool enabled) = 0; - /// Get the number of layers supported - virtual uint8 getMaxLayers(const Terrain* terrain) const = 0; - /// Update the composite map for a terrain - virtual void updateCompositeMap(const Terrain* terrain, const Rect& rect); - - /// Update params for a terrain - virtual void updateParams(const MaterialPtr& mat, const Terrain* terrain) = 0; - /// Update params for a terrain - virtual void updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain) = 0; - - /// Request the options needed from the terrain - virtual void requestOptions(Terrain* terrain) = 0; - - }; - - TerrainMaterialGenerator(); - virtual ~TerrainMaterialGenerator(); - - /// List of profiles - NB should be ordered in descending complexity - typedef vector::type ProfileList; - - /** Get the list of profiles that this generator supports. - */ - virtual const ProfileList& getProfiles() const { return mProfiles; } - - /** Set the active profile by name. */ - virtual void setActiveProfile(const String& name) - { - if (!mActiveProfile || mActiveProfile->getName() != name) - { - for (ProfileList::iterator i = mProfiles.begin(); i != mProfiles.end(); ++i) - { - if ((*i)->getName() == name) - { - setActiveProfile(*i); - break; - } - } - } - - } - - /** Set the active Profile. */ - virtual void setActiveProfile(Profile* p) - { - if (mActiveProfile != p) - { - mActiveProfile = p; - _markChanged(); - } - } - /// Get the active profile - Profile* getActiveProfile() const - { - // default if not chosen yet - if (!mActiveProfile && !mProfiles.empty()) - mActiveProfile = mProfiles[0]; - - return mActiveProfile; - } - - /// Internal method - indicates that a change has been made that would require material regeneration - void _markChanged() { ++mChangeCounter; } - - /** Returns the number of times the generator has undergone a change which - would require materials to be regenerated. - */ - unsigned long long int getChangeCount() const { return mChangeCounter; } - - /** Get the layer declaration that this material generator operates with. - */ - virtual const TerrainLayerDeclaration& getLayerDeclaration() const { return mLayerDecl; } - /** Whether this generator can generate a material for a given declaration. - By default this only returns true if the declaration is equal to the - standard one returned from getLayerDeclaration, but if a subclass wants - to be flexible to generate materials for other declarations too, it - can specify here. - */ - virtual bool canGenerateUsingDeclaration(const TerrainLayerDeclaration& decl) - { - return decl == mLayerDecl; - } - - /** Return whether this material generator supports using a compressed - vertex format. This is only possible when using shaders. - */ - virtual bool isVertexCompressionSupported() const - { - return getActiveProfile()->isVertexCompressionSupported(); - } - - /** Triggers the generator to request the options that it needs. - */ - virtual void requestOptions(Terrain* terrain) - { - Profile* p = getActiveProfile(); - if (p) - p->requestOptions(terrain); - - } - /** Generate a material for the given terrain using the active profile. - */ - virtual MaterialPtr generate(const Terrain* terrain) - { - Profile* p = getActiveProfile(); - if (!p) - return MaterialPtr(); - else - return p->generate(terrain); - } - /** Generate a material for the given composite map of the terrain using the active profile. - */ - virtual MaterialPtr generateForCompositeMap(const Terrain* terrain) - { - Profile* p = getActiveProfile(); - if (!p) - return MaterialPtr(); - else - return p->generateForCompositeMap(terrain); - } - /** Whether to support a light map over the terrain in the shader, - if it's present (default true). - */ - virtual void setLightmapEnabled(bool enabled) - { - Profile* p = getActiveProfile(); - if (p) - return p->setLightmapEnabled(enabled); - } - /** Get the maximum number of layers supported with the given terrain. - @note When you change the options on the terrain, this value can change. - */ - virtual uint8 getMaxLayers(const Terrain* terrain) const - { - Profile* p = getActiveProfile(); - if (p) - return p->getMaxLayers(terrain); - else - return 0; - } - - /** Update the composite map for a terrain. - The composite map for a terrain must match what the terrain should look like - at distance. This method will only be called in the render thread so the - generator is free to render into a texture to support this, so long as - the results are blitted into the Terrain's own composite map afterwards. - */ - virtual void updateCompositeMap(const Terrain* terrain, const Rect& rect) - { - Profile* p = getActiveProfile(); - if (!p) - return; - else - p->updateCompositeMap(terrain, rect); - } - - - /** Update parameters for the given terrain using the active profile. - */ - virtual void updateParams(const MaterialPtr& mat, const Terrain* terrain) - { - Profile* p = getActiveProfile(); - if (p) - p->updateParams(mat, terrain); - } - /** Update parameters for the given terrain composite map using the active profile. - */ - virtual void updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain) - { - Profile* p = getActiveProfile(); - if (p) - p->updateParamsForCompositeMap(mat, terrain); - } - - /** Set the debug level of the material. - @remarks - Sets the level of debug display for this material. - What this debug level means is entirely depdendent on the generator, - the only constant is that 0 means 'no debug' and non-zero means - 'some level of debugging', with any graduations in non-zero values - being generator-specific. - */ - virtual void setDebugLevel(unsigned int dbg) - { - if (mDebugLevel != dbg) - { - mDebugLevel = dbg; - _markChanged(); - } - } - /// Get the debug level of the material. - virtual unsigned int getDebugLevel() const { return mDebugLevel; } - - /** Helper method to render a composite map. - @param size The requested composite map size - @param rect The region of the composite map to update, in image space - @param mat The material to use to render the map - @param destCompositeMap A TexturePtr for the composite map to be written into - */ - virtual void _renderCompositeMap(size_t size, const Rect& rect, - const MaterialPtr& mat, const TexturePtr& destCompositeMap); - - Texture* _getCompositeMapRTT() { return mCompositeMapRTT; } - protected: - - ProfileList mProfiles; - mutable Profile* mActiveProfile; - unsigned long long int mChangeCounter; - TerrainLayerDeclaration mLayerDecl; - unsigned int mDebugLevel; - SceneManager* mCompositeMapSM; - Camera* mCompositeMapCam; - Texture* mCompositeMapRTT; // deliberately holding this by raw pointer to avoid shutdown issues - ManualObject* mCompositeMapPlane; - Light* mCompositeMapLight; - - - - }; - - typedef SharedPtr TerrainMaterialGeneratorPtr; - - /** @} */ - /** @} */ + TerrainLayerSampler(const String& aliasName, PixelFormat fmt) + : alias(aliasName), format(fmt) + { + } + }; + typedef vector::type TerrainLayerSamplerList; + + /** The definition of the information each layer will contain in this terrain. + All layers must contain the same structure of information, although the + input textures can be different per layer instance. + */ + struct _OgreTerrainExport TerrainLayerDeclaration + { + TerrainLayerSamplerList samplers; + TerrainLayerSamplerElementList elements; + + bool operator==(const TerrainLayerDeclaration& dcl) const + { + return samplers == dcl.samplers && elements == dcl.elements; + } + }; + + /** Class that provides functionality to generate materials for use with a terrain. + @remarks + Terrains are composed of one or more layers of texture information, and + require that a material is generated to render them. There are various approaches + to rendering the terrain, which may vary due to: +
      • Hardware support (static)
      • +
      • Texture instances assigned to a particular terrain (dynamic in an editor)
      • +
      • User selection (e.g. changing to a cheaper option in order to increase performance, + or in order to test how the material might look on other hardware (dynamic)
      • +
      + Subclasses of this class are responsible for responding to these factors and + to generate a terrain material. + @par + In order to cope with both hardware support and user selection, the generator + must expose a number of named 'profiles'. These profiles should function on + a known range of hardware, and be graded by quality. At runtime, the user + should be able to select the profile they wish to use (provided hardware + support is available). + */ + class _OgreTerrainExport TerrainMaterialGenerator : public TerrainAlloc + { + public: + /** Inner class which should also be subclassed to provide profile-specific + material generation. + */ + class _OgreTerrainExport Profile : public TerrainAlloc + { + protected: + TerrainMaterialGenerator* mParent; + String mName; + String mDesc; + public: + Profile(TerrainMaterialGenerator* parent, const String& name, const String& desc) + : mParent(parent), mName(name), mDesc(desc) {} + Profile(const Profile& prof) + : mParent(prof.mParent), mName(prof.mName), mDesc(prof.mDesc) {} + virtual ~Profile() {} + /// Get the generator which owns this profile + TerrainMaterialGenerator* getParent() const { return mParent; } + /// Get the name of this profile + const String& getName() const { return mName; } + /// Get the description of this profile + const String& getDescription() const { return mDesc; } + /// Compressed vertex format supported? + virtual bool isVertexCompressionSupported() const = 0; + /// Generate / reuse a material for the terrain + virtual MaterialPtr generate(const Terrain* terrain) = 0; + /// Generate / reuse a material for the terrain + virtual MaterialPtr generateForCompositeMap(const Terrain* terrain) = 0; + /// Whether to support a light map over the terrain in the shader, if it's present (default true) + virtual void setLightmapEnabled(bool enabled) = 0; + /// Get the number of layers supported + virtual uint8 getMaxLayers(const Terrain* terrain) const = 0; + /// Update the composite map for a terrain + virtual void updateCompositeMap(const Terrain* terrain, const Rect& rect); + + /// Update params for a terrain + virtual void updateParams(const MaterialPtr& mat, const Terrain* terrain) = 0; + /// Update params for a terrain + virtual void updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain) = 0; + + /// Request the options needed from the terrain + virtual void requestOptions(Terrain* terrain) = 0; + + }; + + TerrainMaterialGenerator(); + virtual ~TerrainMaterialGenerator(); + + /// List of profiles - NB should be ordered in descending complexity + typedef vector::type ProfileList; + + /** Get the list of profiles that this generator supports. + */ + virtual const ProfileList& getProfiles() const { return mProfiles; } + + /** Set the active profile by name. */ + virtual void setActiveProfile(const String& name) + { + if (!mActiveProfile || mActiveProfile->getName() != name) + { + for (ProfileList::iterator i = mProfiles.begin(); i != mProfiles.end(); ++i) + { + if ((*i)->getName() == name) + { + setActiveProfile(*i); + break; + } + } + } + + } + + /** Set the active Profile. */ + virtual void setActiveProfile(Profile* p) + { + if (mActiveProfile != p) + { + mActiveProfile = p; + _markChanged(); + } + } + /// Get the active profile + Profile* getActiveProfile() const + { + // default if not chosen yet + if (!mActiveProfile && !mProfiles.empty()) + mActiveProfile = mProfiles[0]; + + return mActiveProfile; + } + + /// Internal method - indicates that a change has been made that would require material regeneration + void _markChanged() { ++mChangeCounter; } + + /** Returns the number of times the generator has undergone a change which + would require materials to be regenerated. + */ + unsigned long long int getChangeCount() const { return mChangeCounter; } + + /** Get the layer declaration that this material generator operates with. + */ + virtual const TerrainLayerDeclaration& getLayerDeclaration() const { return mLayerDecl; } + /** Whether this generator can generate a material for a given declaration. + By default this only returns true if the declaration is equal to the + standard one returned from getLayerDeclaration, but if a subclass wants + to be flexible to generate materials for other declarations too, it + can specify here. + */ + virtual bool canGenerateUsingDeclaration(const TerrainLayerDeclaration& decl) + { + return decl == mLayerDecl; + } + + /** Return whether this material generator supports using a compressed + vertex format. This is only possible when using shaders. + */ + virtual bool isVertexCompressionSupported() const + { + return getActiveProfile()->isVertexCompressionSupported(); + } + + /** Triggers the generator to request the options that it needs. + */ + virtual void requestOptions(Terrain* terrain) + { + Profile* p = getActiveProfile(); + if (p) + p->requestOptions(terrain); + + } + /** Generate a material for the given terrain using the active profile. + */ + virtual MaterialPtr generate(const Terrain* terrain) + { + Profile* p = getActiveProfile(); + if (!p) + return MaterialPtr(); + else + return p->generate(terrain); + } + /** Generate a material for the given composite map of the terrain using the active profile. + */ + virtual MaterialPtr generateForCompositeMap(const Terrain* terrain) + { + Profile* p = getActiveProfile(); + if (!p) + return MaterialPtr(); + else + return p->generateForCompositeMap(terrain); + } + /** Whether to support a light map over the terrain in the shader, + if it's present (default true). + */ + virtual void setLightmapEnabled(bool enabled) + { + Profile* p = getActiveProfile(); + if (p) + return p->setLightmapEnabled(enabled); + } + /** Get the maximum number of layers supported with the given terrain. + @note When you change the options on the terrain, this value can change. + */ + virtual uint8 getMaxLayers(const Terrain* terrain) const + { + Profile* p = getActiveProfile(); + if (p) + return p->getMaxLayers(terrain); + else + return 0; + } + + /** Update the composite map for a terrain. + The composite map for a terrain must match what the terrain should look like + at distance. This method will only be called in the render thread so the + generator is free to render into a texture to support this, so long as + the results are blitted into the Terrain's own composite map afterwards. + */ + virtual void updateCompositeMap(const Terrain* terrain, const Rect& rect) + { + Profile* p = getActiveProfile(); + if (!p) + return; + else + p->updateCompositeMap(terrain, rect); + } + + + /** Update parameters for the given terrain using the active profile. + */ + virtual void updateParams(const MaterialPtr& mat, const Terrain* terrain) + { + Profile* p = getActiveProfile(); + if (p) + p->updateParams(mat, terrain); + } + /** Update parameters for the given terrain composite map using the active profile. + */ + virtual void updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain) + { + Profile* p = getActiveProfile(); + if (p) + p->updateParamsForCompositeMap(mat, terrain); + } + + /** Set the debug level of the material. + @remarks + Sets the level of debug display for this material. + What this debug level means is entirely depdendent on the generator, + the only constant is that 0 means 'no debug' and non-zero means + 'some level of debugging', with any graduations in non-zero values + being generator-specific. + */ + virtual void setDebugLevel(unsigned int dbg) + { + if (mDebugLevel != dbg) + { + mDebugLevel = dbg; + _markChanged(); + } + } + /// Get the debug level of the material. + virtual unsigned int getDebugLevel() const { return mDebugLevel; } + + /** Helper method to render a composite map. + @param size The requested composite map size + @param rect The region of the composite map to update, in image space + @param mat The material to use to render the map + @param destCompositeMap A TexturePtr for the composite map to be written into + */ + virtual void _renderCompositeMap(size_t size, const Rect& rect, + const MaterialPtr& mat, const TexturePtr& destCompositeMap); + + Texture* _getCompositeMapRTT() { return mCompositeMapRTT; } + protected: + + ProfileList mProfiles; + mutable Profile* mActiveProfile; + unsigned long long int mChangeCounter; + TerrainLayerDeclaration mLayerDecl; + unsigned int mDebugLevel; + SceneManager* mCompositeMapSM; + Camera* mCompositeMapCam; + Texture* mCompositeMapRTT; // deliberately holding this by raw pointer to avoid shutdown issues + ManualObject* mCompositeMapPlane; + Light* mCompositeMapLight; + + + + }; + + typedef SharedPtr TerrainMaterialGeneratorPtr; + + /** @} */ + /** @} */ } #endif diff --git a/Components/Terrain/include/OgreTerrainMaterialGeneratorA.h b/Components/Terrain/include/OgreTerrainMaterialGeneratorA.h index 66409442dab..ce8c940d9b2 100644 --- a/Components/Terrain/include/OgreTerrainMaterialGeneratorA.h +++ b/Components/Terrain/include/OgreTerrainMaterialGeneratorA.h @@ -34,257 +34,257 @@ THE SOFTWARE. namespace Ogre { - class PSSMShadowCameraSetup; + class PSSMShadowCameraSetup; - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Terrain - * Some details on the terrain component - * @{ - */ + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Terrain + * Some details on the terrain component + * @{ + */ - /** A TerrainMaterialGenerator which can cope with normal mapped, specular mapped - terrain. - @note Requires the Cg plugin to render correctly - */ - class _OgreTerrainExport TerrainMaterialGeneratorA : public TerrainMaterialGenerator - { - public: - TerrainMaterialGeneratorA(); - virtual ~TerrainMaterialGeneratorA(); + /** A TerrainMaterialGenerator which can cope with normal mapped, specular mapped + terrain. + @note Requires the Cg plugin to render correctly + */ + class _OgreTerrainExport TerrainMaterialGeneratorA : public TerrainMaterialGenerator + { + public: + TerrainMaterialGeneratorA(); + virtual ~TerrainMaterialGeneratorA(); - /** Shader model 2 profile target. - */ - class _OgreTerrainExport SM2Profile : public TerrainMaterialGenerator::Profile - { - public: - SM2Profile(TerrainMaterialGenerator* parent, const String& name, const String& desc); - virtual ~SM2Profile(); - MaterialPtr generate(const Terrain* terrain); - MaterialPtr generateForCompositeMap(const Terrain* terrain); - uint8 getMaxLayers(const Terrain* terrain) const; - void updateParams(const MaterialPtr& mat, const Terrain* terrain); - void updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain); - void requestOptions(Terrain* terrain); - bool isVertexCompressionSupported() const; + /** Shader model 2 profile target. + */ + class _OgreTerrainExport SM2Profile : public TerrainMaterialGenerator::Profile + { + public: + SM2Profile(TerrainMaterialGenerator* parent, const String& name, const String& desc); + virtual ~SM2Profile(); + MaterialPtr generate(const Terrain* terrain); + MaterialPtr generateForCompositeMap(const Terrain* terrain); + uint8 getMaxLayers(const Terrain* terrain) const; + void updateParams(const MaterialPtr& mat, const Terrain* terrain); + void updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain); + void requestOptions(Terrain* terrain); + bool isVertexCompressionSupported() const; - /** Whether to support normal mapping per layer in the shader (default true). - */ - bool isLayerNormalMappingEnabled() const { return mLayerNormalMappingEnabled; } - /** Whether to support normal mapping per layer in the shader (default true). - */ - void setLayerNormalMappingEnabled(bool enabled); - /** Whether to support parallax mapping per layer in the shader (default true). - */ - bool isLayerParallaxMappingEnabled() const { return mLayerParallaxMappingEnabled; } - /** Whether to support parallax mapping per layer in the shader (default true). - */ - void setLayerParallaxMappingEnabled(bool enabled); - /** Whether to support specular mapping per layer in the shader (default true). - */ - bool isLayerSpecularMappingEnabled() const { return mLayerSpecularMappingEnabled; } - /** Whether to support specular mapping per layer in the shader (default true). - */ - void setLayerSpecularMappingEnabled(bool enabled); - /** Whether to support a global colour map over the terrain in the shader, - if it's present (default true). - */ - bool isGlobalColourMapEnabled() const { return mGlobalColourMapEnabled; } - /** Whether to support a global colour map over the terrain in the shader, - if it's present (default true). - */ - void setGlobalColourMapEnabled(bool enabled); - /** Whether to support a light map over the terrain in the shader, - if it's present (default true). - */ - bool isLightmapEnabled() const { return mLightmapEnabled; } - /** Whether to support a light map over the terrain in the shader, - if it's present (default true). - */ - void setLightmapEnabled(bool enabled); - /** Whether to use the composite map to provide a lower LOD technique - in the distance (default true). - */ - bool isCompositeMapEnabled() const { return mCompositeMapEnabled; } - /** Whether to use the composite map to provide a lower LOD technique - in the distance (default true). - */ - void setCompositeMapEnabled(bool enabled); - /** Whether to support dynamic texture shadows received from other - objects, on the terrain (default true). - */ - bool getReceiveDynamicShadowsEnabled() const { return mReceiveDynamicShadows; } - /** Whether to support dynamic texture shadows received from other - objects, on the terrain (default true). - */ - void setReceiveDynamicShadowsEnabled(bool enabled); + /** Whether to support normal mapping per layer in the shader (default true). + */ + bool isLayerNormalMappingEnabled() const { return mLayerNormalMappingEnabled; } + /** Whether to support normal mapping per layer in the shader (default true). + */ + void setLayerNormalMappingEnabled(bool enabled); + /** Whether to support parallax mapping per layer in the shader (default true). + */ + bool isLayerParallaxMappingEnabled() const { return mLayerParallaxMappingEnabled; } + /** Whether to support parallax mapping per layer in the shader (default true). + */ + void setLayerParallaxMappingEnabled(bool enabled); + /** Whether to support specular mapping per layer in the shader (default true). + */ + bool isLayerSpecularMappingEnabled() const { return mLayerSpecularMappingEnabled; } + /** Whether to support specular mapping per layer in the shader (default true). + */ + void setLayerSpecularMappingEnabled(bool enabled); + /** Whether to support a global colour map over the terrain in the shader, + if it's present (default true). + */ + bool isGlobalColourMapEnabled() const { return mGlobalColourMapEnabled; } + /** Whether to support a global colour map over the terrain in the shader, + if it's present (default true). + */ + void setGlobalColourMapEnabled(bool enabled); + /** Whether to support a light map over the terrain in the shader, + if it's present (default true). + */ + bool isLightmapEnabled() const { return mLightmapEnabled; } + /** Whether to support a light map over the terrain in the shader, + if it's present (default true). + */ + void setLightmapEnabled(bool enabled); + /** Whether to use the composite map to provide a lower LOD technique + in the distance (default true). + */ + bool isCompositeMapEnabled() const { return mCompositeMapEnabled; } + /** Whether to use the composite map to provide a lower LOD technique + in the distance (default true). + */ + void setCompositeMapEnabled(bool enabled); + /** Whether to support dynamic texture shadows received from other + objects, on the terrain (default true). + */ + bool getReceiveDynamicShadowsEnabled() const { return mReceiveDynamicShadows; } + /** Whether to support dynamic texture shadows received from other + objects, on the terrain (default true). + */ + void setReceiveDynamicShadowsEnabled(bool enabled); - /** Whether to use PSSM support dynamic texture shadows, and if so the - settings to use (default 0). - */ - void setReceiveDynamicShadowsPSSM(PSSMShadowCameraSetup* pssmSettings); - /** Whether to use PSSM support dynamic texture shadows, and if so the - settings to use (default 0). - */ - PSSMShadowCameraSetup* getReceiveDynamicShadowsPSSM() const { return mPSSM; } - /** Whether to use depth shadows (default false). - */ - void setReceiveDynamicShadowsDepth(bool enabled); - /** Whether to use depth shadows (default false). - */ - bool getReceiveDynamicShadowsDepth() const { return mDepthShadows; } - /** Whether to use shadows on low LOD material rendering (when using composite map) (default false). - */ - void setReceiveDynamicShadowsLowLod(bool enabled); - /** Whether to use shadows on low LOD material rendering (when using composite map) (default false). - */ - bool getReceiveDynamicShadowsLowLod() const { return mLowLodShadows; } + /** Whether to use PSSM support dynamic texture shadows, and if so the + settings to use (default 0). + */ + void setReceiveDynamicShadowsPSSM(PSSMShadowCameraSetup* pssmSettings); + /** Whether to use PSSM support dynamic texture shadows, and if so the + settings to use (default 0). + */ + PSSMShadowCameraSetup* getReceiveDynamicShadowsPSSM() const { return mPSSM; } + /** Whether to use depth shadows (default false). + */ + void setReceiveDynamicShadowsDepth(bool enabled); + /** Whether to use depth shadows (default false). + */ + bool getReceiveDynamicShadowsDepth() const { return mDepthShadows; } + /** Whether to use shadows on low LOD material rendering (when using composite map) (default false). + */ + void setReceiveDynamicShadowsLowLod(bool enabled); + /** Whether to use shadows on low LOD material rendering (when using composite map) (default false). + */ + bool getReceiveDynamicShadowsLowLod() const { return mLowLodShadows; } - /// Internal - bool _isSM3Available() const { return mSM3Available; } - bool _isSM4Available() const { return mSM4Available; } + /// Internal + bool _isSM3Available() const { return mSM3Available; } + bool _isSM4Available() const { return mSM4Available; } String _getShaderLanguage() const { return mShaderLanguage; } - - protected: - typedef StringStream stringstream; + + protected: + typedef StringStream stringstream; - enum TechniqueType - { - HIGH_LOD, - LOW_LOD, - RENDER_COMPOSITE_MAP - }; - void addTechnique(const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt); + enum TechniqueType + { + HIGH_LOD, + LOW_LOD, + RENDER_COMPOSITE_MAP + }; + void addTechnique(const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt); - /// Interface definition for helper class to generate shaders - class _OgreTerrainExport ShaderHelper : public TerrainAlloc - { - public: - ShaderHelper() : mShadowSamplerStartHi(0), mShadowSamplerStartLo(0) {} - virtual ~ShaderHelper() {} - virtual HighLevelGpuProgramPtr generateVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - virtual HighLevelGpuProgramPtr generateFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - virtual void updateParams(const SM2Profile* prof, const MaterialPtr& mat, const Terrain* terrain, bool compositeMap); - protected: - virtual String getVertexProgramName(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - virtual String getFragmentProgramName(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - virtual HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) = 0; - virtual HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) = 0; - virtual void generateVertexProgramSource(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - virtual void generateFragmentProgramSource(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - virtual void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) = 0; - virtual void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) = 0; - virtual void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) = 0; - virtual void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) = 0; - virtual void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) = 0; - virtual void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) = 0; - virtual void defaultVpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog); - virtual void defaultFpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog); - virtual void updateVpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params); - virtual void updateFpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params); - static String getChannel(uint idx); + /// Interface definition for helper class to generate shaders + class _OgreTerrainExport ShaderHelper : public TerrainAlloc + { + public: + ShaderHelper() : mShadowSamplerStartHi(0), mShadowSamplerStartLo(0) {} + virtual ~ShaderHelper() {} + virtual HighLevelGpuProgramPtr generateVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + virtual HighLevelGpuProgramPtr generateFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + virtual void updateParams(const SM2Profile* prof, const MaterialPtr& mat, const Terrain* terrain, bool compositeMap); + protected: + virtual String getVertexProgramName(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + virtual String getFragmentProgramName(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + virtual HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) = 0; + virtual HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) = 0; + virtual void generateVertexProgramSource(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + virtual void generateFragmentProgramSource(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + virtual void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) = 0; + virtual void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) = 0; + virtual void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) = 0; + virtual void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) = 0; + virtual void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) = 0; + virtual void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) = 0; + virtual void defaultVpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog); + virtual void defaultFpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog); + virtual void updateVpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params); + virtual void updateFpParams(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params); + static String getChannel(uint idx); - size_t mShadowSamplerStartHi; - size_t mShadowSamplerStartLo; - }; + size_t mShadowSamplerStartHi; + size_t mShadowSamplerStartLo; + }; - /// Utility class to help with generating shaders for Cg / HLSL. - class _OgreTerrainExport ShaderHelperCg : public ShaderHelper - { - protected: - HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); - void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); - void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateVpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadowsHelpers(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadowsParams(uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - }; + /// Utility class to help with generating shaders for Cg / HLSL. + class _OgreTerrainExport ShaderHelperCg : public ShaderHelper + { + protected: + HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); + void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); + void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateVpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadowsHelpers(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadowsParams(uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + }; - class _OgreTerrainExport ShaderHelperHLSL : public ShaderHelperCg - { - protected: - HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); - void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); - void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateVpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadowsHelpers(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadowsParams(uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - }; + class _OgreTerrainExport ShaderHelperHLSL : public ShaderHelperCg + { + protected: + HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); + void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); + void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateVpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadowsHelpers(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadowsParams(uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + }; - /// Utility class to help with generating shaders for GLSL. - class _OgreTerrainExport ShaderHelperGLSL : public ShaderHelper - { - protected: - HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); - void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); - void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateVpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadowsHelpers(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadowsParams(uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - }; + /// Utility class to help with generating shaders for GLSL. + class _OgreTerrainExport ShaderHelperGLSL : public ShaderHelper + { + protected: + HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); + void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); + void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateVpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadowsHelpers(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadowsParams(uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + }; /// Utility class to help with generating shaders for GLSL ES. - class ShaderHelperGLSLES : public ShaderHelper - { - protected: - HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); - void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); - void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); - void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateVpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadowsHelpers(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadowsParams(uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - void generateFpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); - }; + class ShaderHelperGLSLES : public ShaderHelper + { + protected: + HighLevelGpuProgramPtr createVertexProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + HighLevelGpuProgramPtr createFragmentProgram(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt); + void generateVpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpHeader(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateVpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); + void generateFpLayer(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream); + void generateVpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpFooter(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + uint generateVpDynamicShadowsParams(uint texCoordStart, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateVpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadowsHelpers(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadowsParams(uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + void generateFpDynamicShadows(const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream); + }; - ShaderHelper* mShaderGen; - bool mLayerNormalMappingEnabled; - bool mLayerParallaxMappingEnabled; - bool mLayerSpecularMappingEnabled; - bool mGlobalColourMapEnabled; - bool mLightmapEnabled; - bool mCompositeMapEnabled; - bool mReceiveDynamicShadows; - PSSMShadowCameraSetup* mPSSM; - bool mDepthShadows; - bool mLowLodShadows; - bool mSM3Available; - bool mSM4Available; + ShaderHelper* mShaderGen; + bool mLayerNormalMappingEnabled; + bool mLayerParallaxMappingEnabled; + bool mLayerSpecularMappingEnabled; + bool mGlobalColourMapEnabled; + bool mLightmapEnabled; + bool mCompositeMapEnabled; + bool mReceiveDynamicShadows; + PSSMShadowCameraSetup* mPSSM; + bool mDepthShadows; + bool mLowLodShadows; + bool mSM3Available; + bool mSM4Available; String mShaderLanguage; - bool isShadowingEnabled(TechniqueType tt, const Terrain* terrain) const; - }; - }; - /** @} */ - /** @} */ + bool isShadowingEnabled(TechniqueType tt, const Terrain* terrain) const; + }; + }; + /** @} */ + /** @} */ } #endif diff --git a/Components/Terrain/include/OgreTerrainPagedWorldSection.h b/Components/Terrain/include/OgreTerrainPagedWorldSection.h index 624f970be2a..70184ed0534 100644 --- a/Components/Terrain/include/OgreTerrainPagedWorldSection.h +++ b/Components/Terrain/include/OgreTerrainPagedWorldSection.h @@ -37,164 +37,164 @@ THE SOFTWARE. namespace Ogre { - class Grid2DPageStrategy; - class Grid2DPageStrategyData; - - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Terrain - * Some details on the terrain component - * @{ - */ - - /** A world section which includes paged terrain. - @remarks - Rather than implement terrain paging as a PageContent subclass, because terrain - benefits from direct knowledge of neighbour arrangements and the tight - coupling between that and the paging strategy, instead we use a PagedWorldSection - subclass. This automatically provides a PageStrategy subclass of the - correct type (Grid2DPageStrategy) and derives the correct settings for - it compared to the terrain being used. This frees the user from having to - try to match all these up through the generic interfaces. - @par - When creating this in code, the user should make use of the helper - functions on the TerrainPaging class. The basic sequence is that - you define your terrain settings in a TerrainGroup, and then create an - instance of TerrainPagedWorldSection via TerrainPaging::createWorldSection. - That's basically all there is to it - the normal rules of TerrainGroup - apply, it's just that instead of having to choose when to try to load / unload - pages from the TerrainGroup, that is automatically done by the paging system. - You can also create other types of content in this PagedWorldSection other - than terrain, it's just that this comes with terrain handling built-in. - @par - When this world data is saved, you basically get 3 sets of data - firstly - the top-level 'world data' which is where the definition of the world - sections are stored (and hence, the definition of this class, although none - of the terrain instance content is included). Secondly, you get a number - of .page files which include any other content that you might have inserted - into the pages. Lastly, you get the standard terrain data files which are - saved as per TerrainGroup. - */ - class _OgreTerrainExport TerrainPagedWorldSection : public PagedWorldSection, - public WorkQueue::RequestHandler, public WorkQueue::ResponseHandler - { - public: - /** Constructor. - @param name The name of the section - @param parent The parent world - @param sm The SceneManager to use (can be left as null if to be loaded) - */ - TerrainPagedWorldSection(const String& name, PagedWorld* parent, SceneManager* sm); - virtual ~TerrainPagedWorldSection(); - - /** Initialise this section from an existing TerrainGroup instance. - @remarks - This is the route you will take if you're defining this world section - from scratch in code. The other alternative is that you'll be loading - this section from a file, in which case all the settings will be - derived from that. - @param grp The TerrainGroup which will form the basis of this world section. - The instance will be owned by this class from now on and will be destroyed by it. - */ - virtual void init(TerrainGroup* grp); - - /** Get the TerrainGroup which this world section is using. - @remarks For information, you can use the returned TerrainGroup to - convert to/from x/y locations and the pageID, since the grid strategy - is the same. - */ - virtual TerrainGroup* getTerrainGroup() { return mTerrainGroup; } - - /// Set the loading radius - virtual void setLoadRadius(Real sz); - /// Get the loading radius - virtual Real getLoadRadius() const; - /// Set the Holding radius - virtual void setHoldRadius(Real sz); - /// Get the Holding radius - virtual Real getHoldRadius(); - /// Set the index range of all Pages (values outside this will be ignored) - virtual void setPageRange(int32 minX, int32 minY, int32 maxX, int32 maxY); - /// Set the index range of all Pages (values outside this will be ignored) - virtual void setPageRangeMinX(int32 minX); - /// Set the index range of all Pages (values outside this will be ignored) - virtual void setPageRangeMinY(int32 minY); - /// Set the index range of all Pages (values outside this will be ignored) - virtual void setPageRangeMaxX(int32 maxX); - /// Set the index range of all Pages (values outside this will be ignored) - virtual void setPageRangeMaxY(int32 maxY); - /// get the index range of all Pages (values outside this will be ignored) - virtual int32 getPageRangeMinX() const; - /// get the index range of all Pages (values outside this will be ignored) - virtual int32 getPageRangeMinY() const; - /// get the index range of all Pages (values outside this will be ignored) - virtual int32 getPageRangeMaxX() const; - /// get the index range of all Pages (values outside this will be ignored) - virtual int32 getPageRangeMaxY() const; - - /// Convenience method - this section always uses a grid strategy - virtual Grid2DPageStrategy* getGridStrategy() const; - /// Convenience method - this section always uses a grid strategy - virtual Grid2DPageStrategyData* getGridStrategyData() const; - - /// Set the interval between the loading of single pages in milliseconds (ms) - virtual void setLoadingIntervalMs(uint32 loadingIntervalMs); - /// Get the interval between the loading of single pages in milliseconds (ms) - virtual uint32 getLoadingIntervalMs() const; - - /// Overridden from PagedWorldSection - void loadPage(PageID pageID, bool forceSynchronous = false); - /// Overridden from PagedWorldSection - void unloadPage(PageID pageID, bool forceSynchronous = false); - - /// WorkQueue::RequestHandler override - WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); - /// WorkQueue::ResponseHandler override - void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - - static const uint16 WORKQUEUE_LOAD_TERRAIN_PAGE_REQUEST; - - class TerrainDefiner : public TerrainAlloc - { - public: - virtual void define(TerrainGroup* terrainGroup, long x, long y) - { - terrainGroup->defineTerrain(x,y); - } + class Grid2DPageStrategy; + class Grid2DPageStrategyData; + + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Terrain + * Some details on the terrain component + * @{ + */ + + /** A world section which includes paged terrain. + @remarks + Rather than implement terrain paging as a PageContent subclass, because terrain + benefits from direct knowledge of neighbour arrangements and the tight + coupling between that and the paging strategy, instead we use a PagedWorldSection + subclass. This automatically provides a PageStrategy subclass of the + correct type (Grid2DPageStrategy) and derives the correct settings for + it compared to the terrain being used. This frees the user from having to + try to match all these up through the generic interfaces. + @par + When creating this in code, the user should make use of the helper + functions on the TerrainPaging class. The basic sequence is that + you define your terrain settings in a TerrainGroup, and then create an + instance of TerrainPagedWorldSection via TerrainPaging::createWorldSection. + That's basically all there is to it - the normal rules of TerrainGroup + apply, it's just that instead of having to choose when to try to load / unload + pages from the TerrainGroup, that is automatically done by the paging system. + You can also create other types of content in this PagedWorldSection other + than terrain, it's just that this comes with terrain handling built-in. + @par + When this world data is saved, you basically get 3 sets of data - firstly + the top-level 'world data' which is where the definition of the world + sections are stored (and hence, the definition of this class, although none + of the terrain instance content is included). Secondly, you get a number + of .page files which include any other content that you might have inserted + into the pages. Lastly, you get the standard terrain data files which are + saved as per TerrainGroup. + */ + class _OgreTerrainExport TerrainPagedWorldSection : public PagedWorldSection, + public WorkQueue::RequestHandler, public WorkQueue::ResponseHandler + { + public: + /** Constructor. + @param name The name of the section + @param parent The parent world + @param sm The SceneManager to use (can be left as null if to be loaded) + */ + TerrainPagedWorldSection(const String& name, PagedWorld* parent, SceneManager* sm); + virtual ~TerrainPagedWorldSection(); + + /** Initialise this section from an existing TerrainGroup instance. + @remarks + This is the route you will take if you're defining this world section + from scratch in code. The other alternative is that you'll be loading + this section from a file, in which case all the settings will be + derived from that. + @param grp The TerrainGroup which will form the basis of this world section. + The instance will be owned by this class from now on and will be destroyed by it. + */ + virtual void init(TerrainGroup* grp); + + /** Get the TerrainGroup which this world section is using. + @remarks For information, you can use the returned TerrainGroup to + convert to/from x/y locations and the pageID, since the grid strategy + is the same. + */ + virtual TerrainGroup* getTerrainGroup() { return mTerrainGroup; } + + /// Set the loading radius + virtual void setLoadRadius(Real sz); + /// Get the loading radius + virtual Real getLoadRadius() const; + /// Set the Holding radius + virtual void setHoldRadius(Real sz); + /// Get the Holding radius + virtual Real getHoldRadius(); + /// Set the index range of all Pages (values outside this will be ignored) + virtual void setPageRange(int32 minX, int32 minY, int32 maxX, int32 maxY); + /// Set the index range of all Pages (values outside this will be ignored) + virtual void setPageRangeMinX(int32 minX); + /// Set the index range of all Pages (values outside this will be ignored) + virtual void setPageRangeMinY(int32 minY); + /// Set the index range of all Pages (values outside this will be ignored) + virtual void setPageRangeMaxX(int32 maxX); + /// Set the index range of all Pages (values outside this will be ignored) + virtual void setPageRangeMaxY(int32 maxY); + /// get the index range of all Pages (values outside this will be ignored) + virtual int32 getPageRangeMinX() const; + /// get the index range of all Pages (values outside this will be ignored) + virtual int32 getPageRangeMinY() const; + /// get the index range of all Pages (values outside this will be ignored) + virtual int32 getPageRangeMaxX() const; + /// get the index range of all Pages (values outside this will be ignored) + virtual int32 getPageRangeMaxY() const; + + /// Convenience method - this section always uses a grid strategy + virtual Grid2DPageStrategy* getGridStrategy() const; + /// Convenience method - this section always uses a grid strategy + virtual Grid2DPageStrategyData* getGridStrategyData() const; + + /// Set the interval between the loading of single pages in milliseconds (ms) + virtual void setLoadingIntervalMs(uint32 loadingIntervalMs); + /// Get the interval between the loading of single pages in milliseconds (ms) + virtual uint32 getLoadingIntervalMs() const; + + /// Overridden from PagedWorldSection + void loadPage(PageID pageID, bool forceSynchronous = false); + /// Overridden from PagedWorldSection + void unloadPage(PageID pageID, bool forceSynchronous = false); + + /// WorkQueue::RequestHandler override + WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + /// WorkQueue::ResponseHandler override + void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + + static const uint16 WORKQUEUE_LOAD_TERRAIN_PAGE_REQUEST; + + class TerrainDefiner : public TerrainAlloc + { + public: + virtual void define(TerrainGroup* terrainGroup, long x, long y) + { + terrainGroup->defineTerrain(x,y); + } virtual ~TerrainDefiner() {} - }; + }; - void setDefiner(TerrainDefiner* terrainDefiner) - { - if(mTerrainDefiner) - OGRE_DELETE mTerrainDefiner; - mTerrainDefiner = terrainDefiner; - } + void setDefiner(TerrainDefiner* terrainDefiner) + { + if(mTerrainDefiner) + OGRE_DELETE mTerrainDefiner; + mTerrainDefiner = terrainDefiner; + } - protected: - TerrainGroup* mTerrainGroup; - TerrainDefiner* mTerrainDefiner; - std::list mPagesInLoading; - bool mHasRunningTasks; - uint16 mWorkQueueChannel; - unsigned long mNextLoadingTime; - uint32 mLoadingIntervalMs; + protected: + TerrainGroup* mTerrainGroup; + TerrainDefiner* mTerrainDefiner; + std::list mPagesInLoading; + bool mHasRunningTasks; + uint16 mWorkQueueChannel; + unsigned long mNextLoadingTime; + uint32 mLoadingIntervalMs; - /// Overridden from PagedWorldSection - void loadSubtypeData(StreamSerialiser& ser); - void saveSubtypeData(StreamSerialiser& ser); + /// Overridden from PagedWorldSection + void loadSubtypeData(StreamSerialiser& ser); + void saveSubtypeData(StreamSerialiser& ser); - virtual void syncSettings(); + virtual void syncSettings(); - }; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/Components/Terrain/include/OgreTerrainPaging.h b/Components/Terrain/include/OgreTerrainPaging.h index 0765e03492a..fa61b974063 100644 --- a/Components/Terrain/include/OgreTerrainPaging.h +++ b/Components/Terrain/include/OgreTerrainPaging.h @@ -35,101 +35,101 @@ THE SOFTWARE. namespace Ogre { - class PagedWorld; - class TerrainGroup; - class TerrainPagedWorldSection; - - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Terrain - * Some details on the terrain component - * @{ - */ - - /** This class is the 'core' class for paging terrain, that will integrate - with the larger paging system and provide the appropriate utility - classes required. - @remarks - You should construct this class after PageManager and before any PagedWorlds - that might use it are created / loaded. Once constructed, it will make - the "Terrain" PagedWorldSection type available, which uses a grid strategy for - paging and uses TerrainGroup for the content. Other content can - be embedded in the pages too but the terrain is done like this in order - to maintain connections between pages and other global data. - @par - Because PagedWorld and all attached classes have to be loadable from a stream, - most of the functionality is provided behind generalised interfaces. However, - for constructing a paged terrain in code you can use utility methods on - this class. This procedurally created data can then be saved in a generic - form which will reconstruct on loading. Alternatively you can use the - generic methods and simply cast based on your prior knowledge of the types - (or checking the type names exposed). - - */ - class _OgreTerrainExport TerrainPaging : public TerrainAlloc - { - public: - /** Constructor. - @param pageMgr The PageManager which this class should attach to. - */ - TerrainPaging(PageManager* pageMgr); - virtual ~TerrainPaging(); - - /** Create a TerrainPagedWorldSection. - @remarks - This is the simplest way to create a world section which is configured - to contain terrain (among other objects if you want). You can also do this - by calling PagedWorld::createSection with the type "Terrain" but there - are more steps to configuring it that way (note: this is how loading - works though so it remains generic). - @param world The PagedWorld that is to contain this section - @param terrainGroup A TerrainGroup which must have been pre-configured before - this call, to at least set the origin, the world size, and the file name - convention. - @param loadRadius The radius from the camera at which terrain pages will be loaded - @param holdRadius The radius from the camera at which terrain pages will be held in memory - but not loaded if they're not already. This must be larger than loadRadius and is used - to minimise thrashing if the camera goes backwards and forwards at the loading border. - @param minX,minY,maxX,maxY The min/max page indexes that the world will try to load pages for, - as measured from the origin page at (0,0) by a signed index. The default is -10 to 10 - in each direction or 20x20 pages. - @param sectionName An optional name to give the section (if none is - provided, one will be generated) - @param loadingIntervalMs An optional interval in milliseconds to wait between loading single - pages. The default is 900 ms. - @return The world section which is already attached to and owned by the world you passed in. - There is no 'destroy' method because you destroy via the PagedWorld, this is just a - helper function. - */ - TerrainPagedWorldSection* createWorldSection(PagedWorld* world, TerrainGroup* terrainGroup, - Real loadRadius, Real holdRadius, - int32 minX = -10, int32 minY = -10, int32 maxX = 10, int32 maxY = 10, - const String& sectionName = BLANKSTRING, uint32 loadingIntervalMs = 900); - - protected: - PageManager* mManager; - - class _OgreTerrainExport SectionFactory : public PagedWorldSectionFactory - { - public: - static const String FACTORY_NAME; - const String& getName() const; - PagedWorldSection* createInstance(const String& name, PagedWorld* parent, SceneManager* sm); - void destroyInstance(PagedWorldSection*); - - }; - - SectionFactory mSectionFactory; - - }; - - - - - - /** @} */ - /** @} */ + class PagedWorld; + class TerrainGroup; + class TerrainPagedWorldSection; + + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Terrain + * Some details on the terrain component + * @{ + */ + + /** This class is the 'core' class for paging terrain, that will integrate + with the larger paging system and provide the appropriate utility + classes required. + @remarks + You should construct this class after PageManager and before any PagedWorlds + that might use it are created / loaded. Once constructed, it will make + the "Terrain" PagedWorldSection type available, which uses a grid strategy for + paging and uses TerrainGroup for the content. Other content can + be embedded in the pages too but the terrain is done like this in order + to maintain connections between pages and other global data. + @par + Because PagedWorld and all attached classes have to be loadable from a stream, + most of the functionality is provided behind generalised interfaces. However, + for constructing a paged terrain in code you can use utility methods on + this class. This procedurally created data can then be saved in a generic + form which will reconstruct on loading. Alternatively you can use the + generic methods and simply cast based on your prior knowledge of the types + (or checking the type names exposed). + + */ + class _OgreTerrainExport TerrainPaging : public TerrainAlloc + { + public: + /** Constructor. + @param pageMgr The PageManager which this class should attach to. + */ + TerrainPaging(PageManager* pageMgr); + virtual ~TerrainPaging(); + + /** Create a TerrainPagedWorldSection. + @remarks + This is the simplest way to create a world section which is configured + to contain terrain (among other objects if you want). You can also do this + by calling PagedWorld::createSection with the type "Terrain" but there + are more steps to configuring it that way (note: this is how loading + works though so it remains generic). + @param world The PagedWorld that is to contain this section + @param terrainGroup A TerrainGroup which must have been pre-configured before + this call, to at least set the origin, the world size, and the file name + convention. + @param loadRadius The radius from the camera at which terrain pages will be loaded + @param holdRadius The radius from the camera at which terrain pages will be held in memory + but not loaded if they're not already. This must be larger than loadRadius and is used + to minimise thrashing if the camera goes backwards and forwards at the loading border. + @param minX,minY,maxX,maxY The min/max page indexes that the world will try to load pages for, + as measured from the origin page at (0,0) by a signed index. The default is -10 to 10 + in each direction or 20x20 pages. + @param sectionName An optional name to give the section (if none is + provided, one will be generated) + @param loadingIntervalMs An optional interval in milliseconds to wait between loading single + pages. The default is 900 ms. + @return The world section which is already attached to and owned by the world you passed in. + There is no 'destroy' method because you destroy via the PagedWorld, this is just a + helper function. + */ + TerrainPagedWorldSection* createWorldSection(PagedWorld* world, TerrainGroup* terrainGroup, + Real loadRadius, Real holdRadius, + int32 minX = -10, int32 minY = -10, int32 maxX = 10, int32 maxY = 10, + const String& sectionName = BLANKSTRING, uint32 loadingIntervalMs = 900); + + protected: + PageManager* mManager; + + class _OgreTerrainExport SectionFactory : public PagedWorldSectionFactory + { + public: + static const String FACTORY_NAME; + const String& getName() const; + PagedWorldSection* createInstance(const String& name, PagedWorld* parent, SceneManager* sm); + void destroyInstance(PagedWorldSection*); + + }; + + SectionFactory mSectionFactory; + + }; + + + + + + /** @} */ + /** @} */ } #endif diff --git a/Components/Terrain/include/OgreTerrainPrerequisites.h b/Components/Terrain/include/OgreTerrainPrerequisites.h index d9695713138..6d1288c5875 100644 --- a/Components/Terrain/include/OgreTerrainPrerequisites.h +++ b/Components/Terrain/include/OgreTerrainPrerequisites.h @@ -33,36 +33,36 @@ THE SOFTWARE. namespace Ogre { - // forward decls - class Terrain; - class TerrainPageContent; - class TerrainPageContentFactory; - class TerrainQuadTreeNode; + // forward decls + class Terrain; + class TerrainPageContent; + class TerrainPageContentFactory; + class TerrainQuadTreeNode; - typedef GeneralAllocatedObject TerrainAlloc; + typedef GeneralAllocatedObject TerrainAlloc; } #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT -# if defined( OGRE_STATIC_LIB ) -# define _OgreTerrainExport +# if defined( OGRE_STATIC_LIB ) +# define _OgreTerrainExport # else -# if defined( OGRE_TERRAIN_EXPORTS ) -# define _OgreTerrainExport __declspec( dllexport ) -# else +# if defined( OGRE_TERRAIN_EXPORTS ) +# define _OgreTerrainExport __declspec( dllexport ) +# else # if defined( __MINGW32__ ) # define _OgreTerrainExport # else -# define _OgreTerrainExport __declspec( dllimport ) +# define _OgreTerrainExport __declspec( dllimport ) # endif -# endif -# endif +# endif +# endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgreTerrainExport __attribute__ ((visibility("default"))) #else -# define _OgreTerrainExport +# define _OgreTerrainExport #endif #endif diff --git a/Components/Terrain/include/OgreTerrainQuadTreeNode.h b/Components/Terrain/include/OgreTerrainQuadTreeNode.h index e31a2b54482..292676c3caa 100644 --- a/Components/Terrain/include/OgreTerrainQuadTreeNode.h +++ b/Components/Terrain/include/OgreTerrainQuadTreeNode.h @@ -36,381 +36,381 @@ THE SOFTWARE. namespace Ogre { - class HardwareVertexBufferSharedPtr; - - /** \addtogroup Optional Components - * @{ - */ - /** \addtogroup Terrain - * Some details on the terrain component - * @{ - */ - - - /** A node in a quad tree used to store a patch of terrain. - @remarks - Algorithm overview: - @par - Our goal is to perform traditional chunked LOD with geomorphing. But, - instead of just dividing the terrain into tiles, we will divide them into - a hierarchy of tiles, a quadtree, where any level of the quadtree can - be a rendered tile (to the exclusion of its children). The idea is to - collect together children into a larger batch with their siblings as LOD - decreases, to improve performance. - @par - The minBatchSize and maxBatchSize parameters on Terrain a key to - defining this behaviour. Both values are expressed in vertices down one axis. - maxBatchSize determines the number of tiles on one side of the terrain, - which is numTiles = (terrainSize-1) / (maxBatchSize-1). This in turn determines the depth - of the quad tree, which is sqrt(numTiles). The minBatchSize determines - the 'floor' of how low the number of vertices can go in a tile before it - has to be grouped together with its siblings to drop any lower. We also do not group - a tile with its siblings unless all of them are at this minimum batch size, - rather than trying to group them when they all end up on the same 'middle' LOD; - this is for several reasons; firstly, tiles hitting the same 'middle' LOD is - less likely and more transient if they have different levels of 'roughness', - and secondly since we're sharing a vertex / index pool between all tiles, - only grouping at the min level means that the number of combinations of - buffer sizes for any one tile is greatly simplified, making it easier to - pool data. To be more specific, any tile / quadtree node can only have - log2(maxBatchSize-1) - log2(minBatchSize-1) + 1 LOD levels (and if you set them - to the same value, LOD can only change by going up/down the quadtree). - The numbers of vertices / indices in each of these levels is constant for - the same (relative) LOD index no matter where you are in the tree, therefore - buffers can potentially be reused more easily. - */ - class _OgreTerrainExport TerrainQuadTreeNode : public TerrainAlloc - { - public: - /** Constructor. - @param terrain The ultimate parent terrain - @param parent Optional parent node (in which case xoff, yoff are 0 and size must be entire terrain) - @param xoff, yoff Offsets from the start of the terrain data in 2D - @param size The size of the node in vertices at the highest LOD - @param lod The base LOD level - @param depth The depth that this node is at in the tree (or convenience) - @param quadrant The index of the quadrant (0, 1, 2, 3) - */ - TerrainQuadTreeNode(Terrain* terrain, TerrainQuadTreeNode* parent, - uint16 xoff, uint16 yoff, uint16 size, uint16 lod, uint16 depth, uint16 quadrant); - virtual ~TerrainQuadTreeNode(); - - /// Get the horizontal offset into the main terrain data of this node - uint16 getXOffset() const { return mOffsetX; } - /// Get the vertical offset into the main terrain data of this node - uint16 getYOffset() const { return mOffsetY; } - /// Is this a leaf node (no children) - bool isLeaf() const; - /// Get the base LOD level this node starts at (the highest LOD it handles) - uint16 getBaseLod() const { return mBaseLod; } - /// Get the number of LOD levels this node can represent itself (only > 1 for leaf nodes) - uint16 getLodCount() const; - /// Get child node - TerrainQuadTreeNode* getChild(unsigned short child) const; - /// Get parent node - TerrainQuadTreeNode* getParent() const; - /// Get ultimate parent terrain - Terrain* getTerrain() const; - - /// Prepare node and children (perform CPU tasks, may be background thread) - void prepare(); - /// Prepare node from a stream - void prepare(StreamSerialiser& stream); - /// Load node and children (perform GPU tasks, will be render thread) - void load(); - /// Load node and children in a depth range (perform GPU tasks, will be render thread) - void load(uint16 depthStart, uint16 depthEnd); - void loadSelf(); - /// Unload node and children (perform GPU tasks, will be render thread) - void unload(); - /// Unload node and children in a depth range (perform GPU tasks, will be render thread) - void unload(uint16 depthStart, uint16 depthEnd); - /// Unprepare node and children (perform CPU tasks, may be background thread) - void unprepare(); - /// Save node to a stream - void save(StreamSerialiser& stream); - - struct _OgreTerrainExport LodLevel : public TerrainAlloc - { - /// Number of vertices rendered down one side (not including skirts) - uint16 batchSize; - /// Index data on the gpu - IndexData* gpuIndexData; - /// Maximum delta height between this and the next lower lod - Real maxHeightDelta; - /// Temp calc area for max height delta - Real calcMaxHeightDelta; - /// The most recently calculated transition distance - Real lastTransitionDist; - /// The cFactor value used to calculate transitionDist - Real lastCFactor; - - LodLevel() : batchSize(0), gpuIndexData(0), maxHeightDelta(0), calcMaxHeightDelta(0), - lastTransitionDist(0), lastCFactor(0) {} - }; - typedef vector::type LodLevelList; - - /** Get the LodLevel information for a given lod. - @param lod The lod level index relative to this classes own list; if you - want to use a global lod level, subtract getBaseLod() first. Higher - LOD levels are lower detail. - */ - const LodLevel* getLodLevel(uint16 lod); - - /** Notify the node (and children) that deltas are going to be calculated for a given range. - @remarks - Based on this call, we can know whether or not to reset the max height. - */ - void preDeltaCalculation(const Rect& rect); - - /** Notify the node (and children) of a height delta value. */ - void notifyDelta(uint16 x, uint16 y, uint16 lod, Real delta); - - /** Notify the node (and children) that deltas have finished being calculated. - */ - void postDeltaCalculation(const Rect& rect); - - /** Promote the delta values calculated to the runtime ones (this must - be called in the main thread). - */ - void finaliseDeltaValues(const Rect& rect); - - /** Assign vertex data to the tree, from a depth and at a given resolution. - @param treeDepthStart The first depth of tree that should use this data, owns the data - @param treeDepthEnd The end of the depth that should use this data (exclusive) - @param resolution The resolution of the data to use (compared to full terrain) - @param sz The size of the data along one edge - */ - void assignVertexData(uint16 treeDepthStart, uint16 treeDepthEnd, uint16 resolution, uint sz); - - /** Tell a node that it should use an anscestor's vertex data. - @param treeDepthEnd The end of the depth that should use this data (exclusive) - @param resolution The resolution of the data to use - */ - void useAncestorVertexData(TerrainQuadTreeNode* owner, uint16 treeDepthEnd, uint16 resolution); - - /** Tell the node to update its vertex data for a given region. - */ - void updateVertexData(bool positions, bool deltas, const Rect& rect, bool cpuData); - - - - /** Merge a point (relative to terrain node) into the local bounds, - and that of children if applicable. - @param x,y The point on the terrain to which this position corresponds - (affects which nodes update their bounds) - @param pos The position relative to the terrain centre - */ - void mergeIntoBounds(long x, long y, const Vector3& pos); - /** Reset the bounds of this node and all its children for the region given. - @param rect The region for which bounds should be reset, in top-level terrain coords - */ - void resetBounds(const Rect& rect); - - /** Returns true if the given rectangle overlaps the terrain area that - this node references. - @param rect The region in top-level terrain coords - */ - bool rectIntersectsNode(const Rect& rect); - /** Returns true if the given rectangle completely contains the terrain area that - this node references. - @param rect The region in top-level terrain coords - */ - bool rectContainsNode(const Rect& rect); - /** Returns true if the given point is in the terrain area that - this node references. - @param x,y The point in top-level terrain coords - */ - bool pointIntersectsNode(long x, long y); - - /// Get the AABB (local coords) of this node - const AxisAlignedBox& getAABB() const; - /// Get the bounding radius of this node - Real getBoundingRadius() const; - /// Get the local centre of this node, relative to parent terrain centre - const Vector3& getLocalCentre() const { return mLocalCentre; } - /// Get the minimum height of the node - Real getMinHeight() const; - /// Get the maximum height of the node - Real getMaxHeight() const; - - /** Calculate appropriate LOD for this node and children - @param cam The camera to be used (this should already be the LOD camera) - @param cFactor The cFactor which incorporates the viewport size, max pixel error and lod bias - @return true if this node or any of its children were selected for rendering - */ - bool calculateCurrentLod(const Camera* cam, Real cFactor); - - /// Get the current LOD index (only valid after calculateCurrentLod) - int getCurrentLod() const { return mCurrentLod; } - /// Returns whether this node is rendering itself at the current LOD level - bool isRenderedAtCurrentLod() const; - /// Returns whether this node or its children are being rendered at the current LOD level - bool isSelfOrChildRenderedAtCurrentLod() const; - /// Manually set the current LOD, intended for internal use only - void setCurrentLod(int lod); - /// Get the transition state between the current LOD and the next lower one (only valid after calculateCurrentLod) - float getLodTransition() const { return mLodTransition; } - /// Manually set the current LOD transition state, intended for internal use only - void setLodTransition(float t); - - /// Buffer binding used for holding positions - static unsigned short POSITION_BUFFER; - /// Buffer binding used for holding delta values - static unsigned short DELTA_BUFFER; - - /// Returns the internal renderable object for this node - Renderable *_getRenderable(); - protected: - Terrain* mTerrain; - TerrainQuadTreeNode* mParent; - TerrainQuadTreeNode* mChildren[4]; - LodLevelList mLodLevels; - - uint16 mOffsetX, mOffsetY; - uint16 mBoundaryX, mBoundaryY; - /// The number of vertices at the original terrain resolution this node encompasses - uint16 mSize; - uint16 mBaseLod; - uint16 mDepth; - uint16 mQuadrant; - Vector3 mLocalCentre; /// Relative to terrain centre - AxisAlignedBox mAABB; /// Relative to mLocalCentre - Real mBoundingRadius; /// Relative to mLocalCentre - int mCurrentLod; /// -1 = none (do not render) - unsigned short mMaterialLodIndex; - float mLodTransition; /// 0-1 transition to lower LOD - /// The child with the largest height delta - TerrainQuadTreeNode* mChildWithMaxHeightDelta; - bool mSelfOrChildRendered; - - struct VertexDataRecord : public TerrainAlloc - { - VertexData* cpuVertexData; - VertexData* gpuVertexData; - /// Resolution of the data compared to the base terrain data (NOT number of vertices!) - uint16 resolution; - /// Size of the data along one edge - uint16 size; - /// Number of quadtree levels (including this one) this data applies to - uint16 treeLevels; - /// Number of rows and columns of skirts - uint16 numSkirtRowsCols; - /// The number of rows / cols to skip in between skirts - uint16 skirtRowColSkip; - /// Is the GPU vertex data out of date? - bool gpuVertexDataDirty; - - VertexDataRecord(uint16 res, uint16 sz, uint16 lvls) - : cpuVertexData(0), gpuVertexData(0), resolution(res), size(sz), - treeLevels(lvls), numSkirtRowsCols(0), + class HardwareVertexBufferSharedPtr; + + /** \addtogroup Optional Components + * @{ + */ + /** \addtogroup Terrain + * Some details on the terrain component + * @{ + */ + + + /** A node in a quad tree used to store a patch of terrain. + @remarks + Algorithm overview: + @par + Our goal is to perform traditional chunked LOD with geomorphing. But, + instead of just dividing the terrain into tiles, we will divide them into + a hierarchy of tiles, a quadtree, where any level of the quadtree can + be a rendered tile (to the exclusion of its children). The idea is to + collect together children into a larger batch with their siblings as LOD + decreases, to improve performance. + @par + The minBatchSize and maxBatchSize parameters on Terrain a key to + defining this behaviour. Both values are expressed in vertices down one axis. + maxBatchSize determines the number of tiles on one side of the terrain, + which is numTiles = (terrainSize-1) / (maxBatchSize-1). This in turn determines the depth + of the quad tree, which is sqrt(numTiles). The minBatchSize determines + the 'floor' of how low the number of vertices can go in a tile before it + has to be grouped together with its siblings to drop any lower. We also do not group + a tile with its siblings unless all of them are at this minimum batch size, + rather than trying to group them when they all end up on the same 'middle' LOD; + this is for several reasons; firstly, tiles hitting the same 'middle' LOD is + less likely and more transient if they have different levels of 'roughness', + and secondly since we're sharing a vertex / index pool between all tiles, + only grouping at the min level means that the number of combinations of + buffer sizes for any one tile is greatly simplified, making it easier to + pool data. To be more specific, any tile / quadtree node can only have + log2(maxBatchSize-1) - log2(minBatchSize-1) + 1 LOD levels (and if you set them + to the same value, LOD can only change by going up/down the quadtree). + The numbers of vertices / indices in each of these levels is constant for + the same (relative) LOD index no matter where you are in the tree, therefore + buffers can potentially be reused more easily. + */ + class _OgreTerrainExport TerrainQuadTreeNode : public TerrainAlloc + { + public: + /** Constructor. + @param terrain The ultimate parent terrain + @param parent Optional parent node (in which case xoff, yoff are 0 and size must be entire terrain) + @param xoff, yoff Offsets from the start of the terrain data in 2D + @param size The size of the node in vertices at the highest LOD + @param lod The base LOD level + @param depth The depth that this node is at in the tree (or convenience) + @param quadrant The index of the quadrant (0, 1, 2, 3) + */ + TerrainQuadTreeNode(Terrain* terrain, TerrainQuadTreeNode* parent, + uint16 xoff, uint16 yoff, uint16 size, uint16 lod, uint16 depth, uint16 quadrant); + virtual ~TerrainQuadTreeNode(); + + /// Get the horizontal offset into the main terrain data of this node + uint16 getXOffset() const { return mOffsetX; } + /// Get the vertical offset into the main terrain data of this node + uint16 getYOffset() const { return mOffsetY; } + /// Is this a leaf node (no children) + bool isLeaf() const; + /// Get the base LOD level this node starts at (the highest LOD it handles) + uint16 getBaseLod() const { return mBaseLod; } + /// Get the number of LOD levels this node can represent itself (only > 1 for leaf nodes) + uint16 getLodCount() const; + /// Get child node + TerrainQuadTreeNode* getChild(unsigned short child) const; + /// Get parent node + TerrainQuadTreeNode* getParent() const; + /// Get ultimate parent terrain + Terrain* getTerrain() const; + + /// Prepare node and children (perform CPU tasks, may be background thread) + void prepare(); + /// Prepare node from a stream + void prepare(StreamSerialiser& stream); + /// Load node and children (perform GPU tasks, will be render thread) + void load(); + /// Load node and children in a depth range (perform GPU tasks, will be render thread) + void load(uint16 depthStart, uint16 depthEnd); + void loadSelf(); + /// Unload node and children (perform GPU tasks, will be render thread) + void unload(); + /// Unload node and children in a depth range (perform GPU tasks, will be render thread) + void unload(uint16 depthStart, uint16 depthEnd); + /// Unprepare node and children (perform CPU tasks, may be background thread) + void unprepare(); + /// Save node to a stream + void save(StreamSerialiser& stream); + + struct _OgreTerrainExport LodLevel : public TerrainAlloc + { + /// Number of vertices rendered down one side (not including skirts) + uint16 batchSize; + /// Index data on the gpu + IndexData* gpuIndexData; + /// Maximum delta height between this and the next lower lod + Real maxHeightDelta; + /// Temp calc area for max height delta + Real calcMaxHeightDelta; + /// The most recently calculated transition distance + Real lastTransitionDist; + /// The cFactor value used to calculate transitionDist + Real lastCFactor; + + LodLevel() : batchSize(0), gpuIndexData(0), maxHeightDelta(0), calcMaxHeightDelta(0), + lastTransitionDist(0), lastCFactor(0) {} + }; + typedef vector::type LodLevelList; + + /** Get the LodLevel information for a given lod. + @param lod The lod level index relative to this classes own list; if you + want to use a global lod level, subtract getBaseLod() first. Higher + LOD levels are lower detail. + */ + const LodLevel* getLodLevel(uint16 lod); + + /** Notify the node (and children) that deltas are going to be calculated for a given range. + @remarks + Based on this call, we can know whether or not to reset the max height. + */ + void preDeltaCalculation(const Rect& rect); + + /** Notify the node (and children) of a height delta value. */ + void notifyDelta(uint16 x, uint16 y, uint16 lod, Real delta); + + /** Notify the node (and children) that deltas have finished being calculated. + */ + void postDeltaCalculation(const Rect& rect); + + /** Promote the delta values calculated to the runtime ones (this must + be called in the main thread). + */ + void finaliseDeltaValues(const Rect& rect); + + /** Assign vertex data to the tree, from a depth and at a given resolution. + @param treeDepthStart The first depth of tree that should use this data, owns the data + @param treeDepthEnd The end of the depth that should use this data (exclusive) + @param resolution The resolution of the data to use (compared to full terrain) + @param sz The size of the data along one edge + */ + void assignVertexData(uint16 treeDepthStart, uint16 treeDepthEnd, uint16 resolution, uint sz); + + /** Tell a node that it should use an anscestor's vertex data. + @param treeDepthEnd The end of the depth that should use this data (exclusive) + @param resolution The resolution of the data to use + */ + void useAncestorVertexData(TerrainQuadTreeNode* owner, uint16 treeDepthEnd, uint16 resolution); + + /** Tell the node to update its vertex data for a given region. + */ + void updateVertexData(bool positions, bool deltas, const Rect& rect, bool cpuData); + + + + /** Merge a point (relative to terrain node) into the local bounds, + and that of children if applicable. + @param x,y The point on the terrain to which this position corresponds + (affects which nodes update their bounds) + @param pos The position relative to the terrain centre + */ + void mergeIntoBounds(long x, long y, const Vector3& pos); + /** Reset the bounds of this node and all its children for the region given. + @param rect The region for which bounds should be reset, in top-level terrain coords + */ + void resetBounds(const Rect& rect); + + /** Returns true if the given rectangle overlaps the terrain area that + this node references. + @param rect The region in top-level terrain coords + */ + bool rectIntersectsNode(const Rect& rect); + /** Returns true if the given rectangle completely contains the terrain area that + this node references. + @param rect The region in top-level terrain coords + */ + bool rectContainsNode(const Rect& rect); + /** Returns true if the given point is in the terrain area that + this node references. + @param x,y The point in top-level terrain coords + */ + bool pointIntersectsNode(long x, long y); + + /// Get the AABB (local coords) of this node + const AxisAlignedBox& getAABB() const; + /// Get the bounding radius of this node + Real getBoundingRadius() const; + /// Get the local centre of this node, relative to parent terrain centre + const Vector3& getLocalCentre() const { return mLocalCentre; } + /// Get the minimum height of the node + Real getMinHeight() const; + /// Get the maximum height of the node + Real getMaxHeight() const; + + /** Calculate appropriate LOD for this node and children + @param cam The camera to be used (this should already be the LOD camera) + @param cFactor The cFactor which incorporates the viewport size, max pixel error and lod bias + @return true if this node or any of its children were selected for rendering + */ + bool calculateCurrentLod(const Camera* cam, Real cFactor); + + /// Get the current LOD index (only valid after calculateCurrentLod) + int getCurrentLod() const { return mCurrentLod; } + /// Returns whether this node is rendering itself at the current LOD level + bool isRenderedAtCurrentLod() const; + /// Returns whether this node or its children are being rendered at the current LOD level + bool isSelfOrChildRenderedAtCurrentLod() const; + /// Manually set the current LOD, intended for internal use only + void setCurrentLod(int lod); + /// Get the transition state between the current LOD and the next lower one (only valid after calculateCurrentLod) + float getLodTransition() const { return mLodTransition; } + /// Manually set the current LOD transition state, intended for internal use only + void setLodTransition(float t); + + /// Buffer binding used for holding positions + static unsigned short POSITION_BUFFER; + /// Buffer binding used for holding delta values + static unsigned short DELTA_BUFFER; + + /// Returns the internal renderable object for this node + Renderable *_getRenderable(); + protected: + Terrain* mTerrain; + TerrainQuadTreeNode* mParent; + TerrainQuadTreeNode* mChildren[4]; + LodLevelList mLodLevels; + + uint16 mOffsetX, mOffsetY; + uint16 mBoundaryX, mBoundaryY; + /// The number of vertices at the original terrain resolution this node encompasses + uint16 mSize; + uint16 mBaseLod; + uint16 mDepth; + uint16 mQuadrant; + Vector3 mLocalCentre; /// Relative to terrain centre + AxisAlignedBox mAABB; /// Relative to mLocalCentre + Real mBoundingRadius; /// Relative to mLocalCentre + int mCurrentLod; /// -1 = none (do not render) + unsigned short mMaterialLodIndex; + float mLodTransition; /// 0-1 transition to lower LOD + /// The child with the largest height delta + TerrainQuadTreeNode* mChildWithMaxHeightDelta; + bool mSelfOrChildRendered; + + struct VertexDataRecord : public TerrainAlloc + { + VertexData* cpuVertexData; + VertexData* gpuVertexData; + /// Resolution of the data compared to the base terrain data (NOT number of vertices!) + uint16 resolution; + /// Size of the data along one edge + uint16 size; + /// Number of quadtree levels (including this one) this data applies to + uint16 treeLevels; + /// Number of rows and columns of skirts + uint16 numSkirtRowsCols; + /// The number of rows / cols to skip in between skirts + uint16 skirtRowColSkip; + /// Is the GPU vertex data out of date? + bool gpuVertexDataDirty; + + VertexDataRecord(uint16 res, uint16 sz, uint16 lvls) + : cpuVertexData(0), gpuVertexData(0), resolution(res), size(sz), + treeLevels(lvls), numSkirtRowsCols(0), skirtRowColSkip(0), gpuVertexDataDirty(false) {} - }; - - TerrainQuadTreeNode* mNodeWithVertexData; - VertexDataRecord* mVertexDataRecord; - - /** MovableObject implementation to provide the hook to the scene. - @remarks - In one sense, it would be most convenient to have a single MovableObject - to represent the whole Terrain object, and then internally perform - some quadtree frustum culling to narrow down which specific tiles are rendered. - However, the one major flaw with that is that exposing the bounds to - the SceneManager at that level prevents it from doing anything smarter - in terms of culling - for example a portal or occlusion culling SceneManager - would have no opportunity to process the leaf nodes in those terms, and - a simple frustum cull may give significantly poorer results. - @par - Therefore, we in fact register a MovableObject at every node, and - use the LOD factor to determine which one is currently active. LODs - must be mutually exclusive and to deal with precision errors, we really - need to evaluate them all at once, rather than as part of the - _notifyCurrentCamera function. Therefore the root Terrain registers - a SceneManager::Listener to precalculate which nodes will be displayed - when it comes to purely a LOD basis. - */ - class _OgreTerrainExport Movable : public MovableObject - { - protected: - TerrainQuadTreeNode* mParent; - public: - Movable(TerrainQuadTreeNode* parent); - virtual ~Movable(); - - // necessary overrides - const String& getMovableType(void) const; - const AxisAlignedBox& getBoundingBox(void) const; - Real getBoundingRadius(void) const; - void _updateRenderQueue(RenderQueue* queue); - void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables = false); - bool isVisible(void) const; - uint32 getVisibilityFlags(void) const; - uint32 getQueryFlags(void) const; - bool getCastShadows(void) const; - - }; - Movable* mMovable; - friend class Movable; - SceneNode* mLocalNode; - - /// Hook to the render queue - class _OgreTerrainExport Rend : public Renderable, public TerrainAlloc - { - protected: - TerrainQuadTreeNode* mParent; - public: - Rend(TerrainQuadTreeNode* parent); - virtual ~Rend(); - - const MaterialPtr& getMaterial(void) const; - Technique* getTechnique(void) const; - void getRenderOperation(RenderOperation& op); - void getWorldTransforms(Matrix4* xform) const; - Real getSquaredViewDepth(const Camera* cam) const; - const LightList& getLights(void) const; - bool getCastsShadows(void) const; - - }; - Rend* mRend; - friend class Rend; - - // actual implementation of MovableObject methods - void updateRenderQueue(RenderQueue* queue); - void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables = false); - // actual implementations of Renderable methods - const MaterialPtr& getMaterial(void) const; - Technique* getTechnique(void) const; - void getRenderOperation(RenderOperation& op); - void getWorldTransforms(Matrix4* xform) const; - Real getSquaredViewDepth(const Camera* cam) const; - const LightList& getLights(void) const; - bool getCastsShadows(void) const; - - - const VertexDataRecord* getVertexDataRecord() const; - void createCpuVertexData(); - /* Update the vertex buffers - the rect in question is relative to the whole terrain, - not the local vertex data (which may use a subset) - */ - void updateVertexBuffer(HardwareVertexBufferSharedPtr& posbuf, HardwareVertexBufferSharedPtr& deltabuf, const Rect& rect); - void destroyCpuVertexData(); - - void createGpuVertexData(); - void destroyGpuVertexData(); - void updateGpuVertexData(); - void createGpuIndexData(); - void destroyGpuIndexData(); - - void populateIndexData(uint16 batchSize, IndexData* destData); - void writePosVertex(bool compress, uint16 x, uint16 y, float height, const Vector3& pos, float uvScale, float** ppPos); - void writeDeltaVertex(bool compress, uint16 x, uint16 y, float delta, float deltaThresh, float** ppDelta); - - uint16 calcSkirtVertexIndex(uint16 mainIndex, bool isCol); - - }; - - /** @} */ - /** @} */ + }; + + TerrainQuadTreeNode* mNodeWithVertexData; + VertexDataRecord* mVertexDataRecord; + + /** MovableObject implementation to provide the hook to the scene. + @remarks + In one sense, it would be most convenient to have a single MovableObject + to represent the whole Terrain object, and then internally perform + some quadtree frustum culling to narrow down which specific tiles are rendered. + However, the one major flaw with that is that exposing the bounds to + the SceneManager at that level prevents it from doing anything smarter + in terms of culling - for example a portal or occlusion culling SceneManager + would have no opportunity to process the leaf nodes in those terms, and + a simple frustum cull may give significantly poorer results. + @par + Therefore, we in fact register a MovableObject at every node, and + use the LOD factor to determine which one is currently active. LODs + must be mutually exclusive and to deal with precision errors, we really + need to evaluate them all at once, rather than as part of the + _notifyCurrentCamera function. Therefore the root Terrain registers + a SceneManager::Listener to precalculate which nodes will be displayed + when it comes to purely a LOD basis. + */ + class _OgreTerrainExport Movable : public MovableObject + { + protected: + TerrainQuadTreeNode* mParent; + public: + Movable(TerrainQuadTreeNode* parent); + virtual ~Movable(); + + // necessary overrides + const String& getMovableType(void) const; + const AxisAlignedBox& getBoundingBox(void) const; + Real getBoundingRadius(void) const; + void _updateRenderQueue(RenderQueue* queue); + void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables = false); + bool isVisible(void) const; + uint32 getVisibilityFlags(void) const; + uint32 getQueryFlags(void) const; + bool getCastShadows(void) const; + + }; + Movable* mMovable; + friend class Movable; + SceneNode* mLocalNode; + + /// Hook to the render queue + class _OgreTerrainExport Rend : public Renderable, public TerrainAlloc + { + protected: + TerrainQuadTreeNode* mParent; + public: + Rend(TerrainQuadTreeNode* parent); + virtual ~Rend(); + + const MaterialPtr& getMaterial(void) const; + Technique* getTechnique(void) const; + void getRenderOperation(RenderOperation& op); + void getWorldTransforms(Matrix4* xform) const; + Real getSquaredViewDepth(const Camera* cam) const; + const LightList& getLights(void) const; + bool getCastsShadows(void) const; + + }; + Rend* mRend; + friend class Rend; + + // actual implementation of MovableObject methods + void updateRenderQueue(RenderQueue* queue); + void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables = false); + // actual implementations of Renderable methods + const MaterialPtr& getMaterial(void) const; + Technique* getTechnique(void) const; + void getRenderOperation(RenderOperation& op); + void getWorldTransforms(Matrix4* xform) const; + Real getSquaredViewDepth(const Camera* cam) const; + const LightList& getLights(void) const; + bool getCastsShadows(void) const; + + + const VertexDataRecord* getVertexDataRecord() const; + void createCpuVertexData(); + /* Update the vertex buffers - the rect in question is relative to the whole terrain, + not the local vertex data (which may use a subset) + */ + void updateVertexBuffer(HardwareVertexBufferSharedPtr& posbuf, HardwareVertexBufferSharedPtr& deltabuf, const Rect& rect); + void destroyCpuVertexData(); + + void createGpuVertexData(); + void destroyGpuVertexData(); + void updateGpuVertexData(); + void createGpuIndexData(); + void destroyGpuIndexData(); + + void populateIndexData(uint16 batchSize, IndexData* destData); + void writePosVertex(bool compress, uint16 x, uint16 y, float height, const Vector3& pos, float uvScale, float** ppPos); + void writeDeltaVertex(bool compress, uint16 x, uint16 y, float delta, float deltaThresh, float** ppDelta); + + uint16 calcSkirtVertexIndex(uint16 mainIndex, bool isCol); + + }; + + /** @} */ + /** @} */ } #endif diff --git a/Components/Terrain/src/OgreTerrain.cpp b/Components/Terrain/src/OgreTerrain.cpp index f7b1a0f7283..e6a76ae365f 100644 --- a/Components/Terrain/src/OgreTerrain.cpp +++ b/Components/Terrain/src/OgreTerrain.cpp @@ -59,615 +59,615 @@ THE SOFTWARE. #endif namespace Ogre { - //--------------------------------------------------------------------- - const uint32 Terrain::TERRAIN_CHUNK_ID = StreamSerialiser::makeIdentifier("TERR"); - const uint16 Terrain::TERRAIN_CHUNK_VERSION = 2; - const uint32 Terrain::TERRAINGENERALINFO_CHUNK_ID = StreamSerialiser::makeIdentifier("TGIN"); - const uint16 Terrain::TERRAINGENERALINFO_CHUNK_VERSION = 1; - const uint32 Terrain::TERRAINLAYERDECLARATION_CHUNK_ID = StreamSerialiser::makeIdentifier("TDCL"); - const uint16 Terrain::TERRAINLAYERDECLARATION_CHUNK_VERSION = 1; - const uint32 Terrain::TERRAINLAYERSAMPLER_CHUNK_ID = StreamSerialiser::makeIdentifier("TSAM"); - const uint16 Terrain::TERRAINLAYERSAMPLER_CHUNK_VERSION = 1; - const uint32 Terrain::TERRAINLAYERSAMPLERELEMENT_CHUNK_ID = StreamSerialiser::makeIdentifier("TSEL"); - const uint16 Terrain::TERRAINLAYERSAMPLERELEMENT_CHUNK_VERSION = 1; - const uint32 Terrain::TERRAINLAYERINSTANCE_CHUNK_ID = StreamSerialiser::makeIdentifier("TLIN"); - const uint16 Terrain::TERRAINLAYERINSTANCE_CHUNK_VERSION = 1; - const uint32 Terrain::TERRAINDERIVEDDATA_CHUNK_ID = StreamSerialiser::makeIdentifier("TDDA"); - const uint16 Terrain::TERRAINDERIVEDDATA_CHUNK_VERSION = 1; - // since 129^2 is the greatest power we can address in 16-bit index - const uint16 Terrain::TERRAIN_MAX_BATCH_SIZE = 129; - const uint16 Terrain::WORKQUEUE_DERIVED_DATA_REQUEST = 1; - const uint64 Terrain::TERRAIN_GENERATE_MATERIAL_INTERVAL_MS = 400; - const uint16 Terrain::WORKQUEUE_GENERATE_MATERIAL_REQUEST = 2; - const size_t Terrain::LOD_MORPH_CUSTOM_PARAM = 1001; - const uint8 Terrain::DERIVED_DATA_DELTAS = 1; - const uint8 Terrain::DERIVED_DATA_NORMALS = 2; - const uint8 Terrain::DERIVED_DATA_LIGHTMAP = 4; - // This MUST match the bitwise OR of all the types above with no extra bits! - const uint8 Terrain::DERIVED_DATA_ALL = 7; - //----------------------------------------------------------------------- - template<> TerrainGlobalOptions* Singleton::msSingleton = 0; - TerrainGlobalOptions* TerrainGlobalOptions::getSingletonPtr(void) - { - return msSingleton; - } - TerrainGlobalOptions& TerrainGlobalOptions::getSingleton(void) - { - assert( msSingleton ); return ( *msSingleton ); - } - //--------------------------------------------------------------------- - TerrainGlobalOptions::TerrainGlobalOptions() - : mSkirtSize(30) - , mLightMapDir(Vector3(1, -1, 0).normalisedCopy()) - , mCastsShadows(false) - , mMaxPixelError(3.0) - , mRenderQueueGroup(RENDER_QUEUE_MAIN) - , mVisibilityFlags(0xFFFFFFFF) - , mQueryFlags(0xFFFFFFFF) - , mUseRayBoxDistanceCalculation(false) - , mLayerBlendMapSize(1024) - , mDefaultLayerTextureWorldSize(10) - , mDefaultGlobalColourMapSize(1024) - , mLightmapSize(1024) - , mCompositeMapSize(1024) - , mCompositeMapAmbient(ColourValue::White) - , mCompositeMapDiffuse(ColourValue::White) - , mCompositeMapDistance(4000) - , mResourceGroup(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) - , mUseVertexCompressionWhenAvailable(true) - { - } - //--------------------------------------------------------------------- - void TerrainGlobalOptions::setDefaultMaterialGenerator(TerrainMaterialGeneratorPtr gen) - { - mDefaultMaterialGenerator = gen; - } - //--------------------------------------------------------------------- - TerrainMaterialGeneratorPtr TerrainGlobalOptions::getDefaultMaterialGenerator() - { - if (mDefaultMaterialGenerator.isNull()) - { - // default - mDefaultMaterialGenerator.bind(OGRE_NEW TerrainMaterialGeneratorA()); - } - - return mDefaultMaterialGenerator; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - NameGenerator Terrain::msBlendTextureGenerator = NameGenerator("TerrBlend"); - //--------------------------------------------------------------------- - Terrain::Terrain(SceneManager* sm) - : mSceneMgr(sm) - , mResourceGroup(BLANKSTRING) - , mIsLoaded(false) - , mModified(false) - , mHeightDataModified(false) - , mHeightData(0) - , mDeltaData(0) + //--------------------------------------------------------------------- + const uint32 Terrain::TERRAIN_CHUNK_ID = StreamSerialiser::makeIdentifier("TERR"); + const uint16 Terrain::TERRAIN_CHUNK_VERSION = 2; + const uint32 Terrain::TERRAINGENERALINFO_CHUNK_ID = StreamSerialiser::makeIdentifier("TGIN"); + const uint16 Terrain::TERRAINGENERALINFO_CHUNK_VERSION = 1; + const uint32 Terrain::TERRAINLAYERDECLARATION_CHUNK_ID = StreamSerialiser::makeIdentifier("TDCL"); + const uint16 Terrain::TERRAINLAYERDECLARATION_CHUNK_VERSION = 1; + const uint32 Terrain::TERRAINLAYERSAMPLER_CHUNK_ID = StreamSerialiser::makeIdentifier("TSAM"); + const uint16 Terrain::TERRAINLAYERSAMPLER_CHUNK_VERSION = 1; + const uint32 Terrain::TERRAINLAYERSAMPLERELEMENT_CHUNK_ID = StreamSerialiser::makeIdentifier("TSEL"); + const uint16 Terrain::TERRAINLAYERSAMPLERELEMENT_CHUNK_VERSION = 1; + const uint32 Terrain::TERRAINLAYERINSTANCE_CHUNK_ID = StreamSerialiser::makeIdentifier("TLIN"); + const uint16 Terrain::TERRAINLAYERINSTANCE_CHUNK_VERSION = 1; + const uint32 Terrain::TERRAINDERIVEDDATA_CHUNK_ID = StreamSerialiser::makeIdentifier("TDDA"); + const uint16 Terrain::TERRAINDERIVEDDATA_CHUNK_VERSION = 1; + // since 129^2 is the greatest power we can address in 16-bit index + const uint16 Terrain::TERRAIN_MAX_BATCH_SIZE = 129; + const uint16 Terrain::WORKQUEUE_DERIVED_DATA_REQUEST = 1; + const uint64 Terrain::TERRAIN_GENERATE_MATERIAL_INTERVAL_MS = 400; + const uint16 Terrain::WORKQUEUE_GENERATE_MATERIAL_REQUEST = 2; + const size_t Terrain::LOD_MORPH_CUSTOM_PARAM = 1001; + const uint8 Terrain::DERIVED_DATA_DELTAS = 1; + const uint8 Terrain::DERIVED_DATA_NORMALS = 2; + const uint8 Terrain::DERIVED_DATA_LIGHTMAP = 4; + // This MUST match the bitwise OR of all the types above with no extra bits! + const uint8 Terrain::DERIVED_DATA_ALL = 7; + //----------------------------------------------------------------------- + template<> TerrainGlobalOptions* Singleton::msSingleton = 0; + TerrainGlobalOptions* TerrainGlobalOptions::getSingletonPtr(void) + { + return msSingleton; + } + TerrainGlobalOptions& TerrainGlobalOptions::getSingleton(void) + { + assert( msSingleton ); return ( *msSingleton ); + } + //--------------------------------------------------------------------- + TerrainGlobalOptions::TerrainGlobalOptions() + : mSkirtSize(30) + , mLightMapDir(Vector3(1, -1, 0).normalisedCopy()) + , mCastsShadows(false) + , mMaxPixelError(3.0) + , mRenderQueueGroup(RENDER_QUEUE_MAIN) + , mVisibilityFlags(0xFFFFFFFF) + , mQueryFlags(0xFFFFFFFF) + , mUseRayBoxDistanceCalculation(false) + , mLayerBlendMapSize(1024) + , mDefaultLayerTextureWorldSize(10) + , mDefaultGlobalColourMapSize(1024) + , mLightmapSize(1024) + , mCompositeMapSize(1024) + , mCompositeMapAmbient(ColourValue::White) + , mCompositeMapDiffuse(ColourValue::White) + , mCompositeMapDistance(4000) + , mResourceGroup(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) + , mUseVertexCompressionWhenAvailable(true) + { + } + //--------------------------------------------------------------------- + void TerrainGlobalOptions::setDefaultMaterialGenerator(TerrainMaterialGeneratorPtr gen) + { + mDefaultMaterialGenerator = gen; + } + //--------------------------------------------------------------------- + TerrainMaterialGeneratorPtr TerrainGlobalOptions::getDefaultMaterialGenerator() + { + if (mDefaultMaterialGenerator.isNull()) + { + // default + mDefaultMaterialGenerator.bind(OGRE_NEW TerrainMaterialGeneratorA()); + } + + return mDefaultMaterialGenerator; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + NameGenerator Terrain::msBlendTextureGenerator = NameGenerator("TerrBlend"); + //--------------------------------------------------------------------- + Terrain::Terrain(SceneManager* sm) + : mSceneMgr(sm) + , mResourceGroup(BLANKSTRING) + , mIsLoaded(false) + , mModified(false) + , mHeightDataModified(false) + , mHeightData(0) + , mDeltaData(0) , mAlign(ALIGN_X_Z) , mWorldSize(0) , mSize(0) , mMaxBatchSize(0) , mMinBatchSize(0) - , mPos(Vector3::ZERO) - , mQuadTree(0) - , mNumLodLevels(0) - , mNumLodLevelsPerLeafNode(0) - , mTreeDepth(0) + , mPos(Vector3::ZERO) + , mQuadTree(0) + , mNumLodLevels(0) + , mNumLodLevelsPerLeafNode(0) + , mTreeDepth(0) , mBase(0) , mScale(0) , mSkirtSize(0) , mRenderQueueGroup(0) , mVisibilityFlags(0) , mQueryFlags(0) - , mDirtyGeometryRect(0, 0, 0, 0) - , mDirtyDerivedDataRect(0, 0, 0, 0) - , mDirtyGeometryRectForNeighbours(0, 0, 0, 0) - , mDirtyLightmapFromNeighboursRect(0, 0, 0, 0) - , mDerivedDataUpdateInProgress(false) + , mDirtyGeometryRect(0, 0, 0, 0) + , mDirtyDerivedDataRect(0, 0, 0, 0) + , mDirtyGeometryRectForNeighbours(0, 0, 0, 0) + , mDirtyLightmapFromNeighboursRect(0, 0, 0, 0) + , mDerivedDataUpdateInProgress(false) , mDerivedUpdatePendingMask(0) - , mGenerateMaterialInProgress(false) - , mPrepareInProgress(false) - , mMaterialGenerationCount(0) - , mMaterialDirty(false) - , mMaterialParamsDirty(false) + , mGenerateMaterialInProgress(false) + , mPrepareInProgress(false) + , mMaterialGenerationCount(0) + , mMaterialDirty(false) + , mMaterialParamsDirty(false) , mLayerBlendMapSize(0) , mLayerBlendMapSizeActual(0) - , mGlobalColourMapSize(0) - , mGlobalColourMapEnabled(false) - , mCpuColourMapStorage(0) + , mGlobalColourMapSize(0) + , mGlobalColourMapEnabled(false) + , mCpuColourMapStorage(0) , mLightmapSize(0) , mLightmapSizeActual(0) - , mCpuLightmapStorage(0) + , mCpuLightmapStorage(0) , mCompositeMapSize(0) , mCompositeMapSizeActual(0) - , mCpuCompositeMapStorage(0) - , mCompositeMapDirtyRect(0, 0, 0, 0) - , mCompositeMapUpdateCountdown(0) - , mLastMillis(0) - , mCompositeMapDirtyRectLightmapUpdate(false) - , mLodMorphRequired(false) - , mNormalMapRequired(false) - , mLightMapRequired(false) - , mLightMapShadowsOnly(true) - , mCompositeMapRequired(false) - , mCpuTerrainNormalMap(0) - , mLastLODCamera(0) - , mLastLODFrame(0) - , mLastViewportHeight(0) + , mCpuCompositeMapStorage(0) + , mCompositeMapDirtyRect(0, 0, 0, 0) + , mCompositeMapUpdateCountdown(0) + , mLastMillis(0) + , mCompositeMapDirtyRectLightmapUpdate(false) + , mLodMorphRequired(false) + , mNormalMapRequired(false) + , mLightMapRequired(false) + , mLightMapShadowsOnly(true) + , mCompositeMapRequired(false) + , mCpuTerrainNormalMap(0) + , mLastLODCamera(0) + , mLastLODFrame(0) + , mLastViewportHeight(0) , mCustomGpuBufferAllocator(0) , mLodManager(0) - { - mRootNode = sm->getRootSceneNode()->createChildSceneNode(); - sm->addListener(this); - - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - mWorkQueueChannel = wq->getChannel("Ogre/Terrain"); - wq->addRequestHandler(mWorkQueueChannel, this); - wq->addResponseHandler(mWorkQueueChannel, this); - - // generate a material name, it's important for the terrain material - // name to be consistent & unique no matter what generator is being used - // so use our own pointer as identifier, use FashHash rather than just casting - // the pointer to a long so we support 64-bit pointers - Terrain* pTerrain = this; - mMaterialName = "OgreTerrain/" + StringConverter::toString(FastHash((const char*)&pTerrain, sizeof(Terrain*))); - - memset(mNeighbours, 0, sizeof(Terrain*) * NEIGHBOUR_COUNT); - } - //--------------------------------------------------------------------- - Terrain::~Terrain() - { - mDerivedUpdatePendingMask = 0; - waitForDerivedProcesses(); - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - wq->removeRequestHandler(mWorkQueueChannel, this); - wq->removeResponseHandler(mWorkQueueChannel, this); - - removeFromNeighbours(); - - freeLodData(); - freeTemporaryResources(); - freeGPUResources(); - freeCPUResources(); - if (mSceneMgr) - { - mSceneMgr->destroySceneNode(mRootNode); - mSceneMgr->removeListener(this); - } - } - //--------------------------------------------------------------------- - const AxisAlignedBox& Terrain::getAABB() const - { - if (!mQuadTree) - return AxisAlignedBox::BOX_NULL; - else - return mQuadTree->getAABB(); - } - //--------------------------------------------------------------------- - AxisAlignedBox Terrain::getWorldAABB() const - { - Matrix4 m = Matrix4::IDENTITY; - m.setTrans(getPosition()); - - AxisAlignedBox ret = getAABB(); - ret.transformAffine(m); - return ret; - } - //--------------------------------------------------------------------- - Real Terrain::getMinHeight() const - { - if (!mQuadTree) - return 0; - else - return mQuadTree->getMinHeight(); - } - //--------------------------------------------------------------------- - Real Terrain::getMaxHeight() const - { - if (!mQuadTree) - return 0; - else - return mQuadTree->getMaxHeight(); - } - //--------------------------------------------------------------------- - Real Terrain::getBoundingRadius() const - { - if (!mQuadTree) - return 0; - else - return mQuadTree->getBoundingRadius(); - } - //--------------------------------------------------------------------- - void Terrain::save(const String& filename) - { - // force to load highest lod, or quadTree may contain hole - load(0,true); + { + mRootNode = sm->getRootSceneNode()->createChildSceneNode(); + sm->addListener(this); + + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + mWorkQueueChannel = wq->getChannel("Ogre/Terrain"); + wq->addRequestHandler(mWorkQueueChannel, this); + wq->addResponseHandler(mWorkQueueChannel, this); + + // generate a material name, it's important for the terrain material + // name to be consistent & unique no matter what generator is being used + // so use our own pointer as identifier, use FashHash rather than just casting + // the pointer to a long so we support 64-bit pointers + Terrain* pTerrain = this; + mMaterialName = "OgreTerrain/" + StringConverter::toString(FastHash((const char*)&pTerrain, sizeof(Terrain*))); + + memset(mNeighbours, 0, sizeof(Terrain*) * NEIGHBOUR_COUNT); + } + //--------------------------------------------------------------------- + Terrain::~Terrain() + { + mDerivedUpdatePendingMask = 0; + waitForDerivedProcesses(); + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + wq->removeRequestHandler(mWorkQueueChannel, this); + wq->removeResponseHandler(mWorkQueueChannel, this); + + removeFromNeighbours(); + + freeLodData(); + freeTemporaryResources(); + freeGPUResources(); + freeCPUResources(); + if (mSceneMgr) + { + mSceneMgr->destroySceneNode(mRootNode); + mSceneMgr->removeListener(this); + } + } + //--------------------------------------------------------------------- + const AxisAlignedBox& Terrain::getAABB() const + { + if (!mQuadTree) + return AxisAlignedBox::BOX_NULL; + else + return mQuadTree->getAABB(); + } + //--------------------------------------------------------------------- + AxisAlignedBox Terrain::getWorldAABB() const + { + Matrix4 m = Matrix4::IDENTITY; + m.setTrans(getPosition()); + + AxisAlignedBox ret = getAABB(); + ret.transformAffine(m); + return ret; + } + //--------------------------------------------------------------------- + Real Terrain::getMinHeight() const + { + if (!mQuadTree) + return 0; + else + return mQuadTree->getMinHeight(); + } + //--------------------------------------------------------------------- + Real Terrain::getMaxHeight() const + { + if (!mQuadTree) + return 0; + else + return mQuadTree->getMaxHeight(); + } + //--------------------------------------------------------------------- + Real Terrain::getBoundingRadius() const + { + if (!mQuadTree) + return 0; + else + return mQuadTree->getBoundingRadius(); + } + //--------------------------------------------------------------------- + void Terrain::save(const String& filename) + { + // force to load highest lod, or quadTree may contain hole + load(0,true); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS - DataStreamPtr stream = Root::getSingleton().createFileStream(macBundlePath() + "/../Documents/" + filename, + DataStreamPtr stream = Root::getSingleton().createFileStream(macBundlePath() + "/../Documents/" + filename, _getDerivedResourceGroup(), true); #else - DataStreamPtr stream = Root::getSingleton().createFileStream(filename, + DataStreamPtr stream = Root::getSingleton().createFileStream(filename, _getDerivedResourceGroup(), true); #endif - StreamSerialiser ser(stream); - save(ser); - } - //--------------------------------------------------------------------- - void Terrain::save(StreamSerialiser& stream) - { - // wait for any queued processes to finish - waitForDerivedProcesses(); - - if (mHeightDataModified) - { - // When modifying, for efficiency we only increase the max deltas at each LOD, - // we never reduce them (since that would require re-examining more samples) - // Since we now save this data in the file though, we need to make sure we've - // calculated the optimal - Rect rect; - rect.top = 0; rect.bottom = mSize; - rect.left = 0; rect.right = mSize; - calculateHeightDeltas(rect); - finaliseHeightDeltas(rect, false); - } - - stream.writeChunkBegin(TERRAIN_CHUNK_ID, TERRAIN_CHUNK_VERSION); - - stream.writeChunkBegin(TERRAINGENERALINFO_CHUNK_ID, TERRAINGENERALINFO_CHUNK_VERSION); - uint8 align = (uint8)mAlign; - stream.write(&align); - - stream.write(&mSize); - stream.write(&mWorldSize); - stream.write(&mMaxBatchSize); - stream.write(&mMinBatchSize); - stream.write(&mPos); - stream.writeChunkEnd(TERRAINGENERALINFO_CHUNK_ID); - - TerrainLodManager::saveLodData(stream,this); - - // start compressing - stream.startDeflate(); - - writeLayerDeclaration(mLayerDecl, stream); - - // Layers - checkLayers(false); - uint8 numLayers = (uint8)mLayers.size(); - writeLayerInstanceList(mLayers, stream); - - // Packed layer blend data - if(!mCpuBlendMapStorage.empty()) - { - // save from CPU data if it's there, it means GPU data was never created - stream.write(&mLayerBlendMapSize); - - // load packed CPU data - int numBlendTex = getBlendTextureCount(numLayers); - for (int i = 0; i < numBlendTex; ++i) - { - PixelFormat fmt = getBlendTextureFormat(i, numLayers); - size_t channels = PixelUtil::getNumElemBytes(fmt); - size_t dataSz = channels * mLayerBlendMapSize * mLayerBlendMapSize; - uint8* pData = mCpuBlendMapStorage[i]; - stream.write(pData, dataSz); - } - } - else - { - if (mLayerBlendMapSize != mLayerBlendMapSizeActual) - { - LogManager::getSingleton().stream() << - "WARNING: blend maps were requested at a size larger than was supported " - "on this hardware, which means the quality has been degraded"; - } - stream.write(&mLayerBlendMapSizeActual); - uint8* tmpData = (uint8*)OGRE_MALLOC(mLayerBlendMapSizeActual * mLayerBlendMapSizeActual * 4, MEMCATEGORY_GENERAL); - uint8 texIndex = 0; - for (TexturePtrList::iterator i = mBlendTextureList.begin(); i != mBlendTextureList.end(); ++i, ++texIndex) - { - // Must blit back in CPU format! - PixelFormat cpuFormat = getBlendTextureFormat(texIndex, getLayerCount()); - PixelBox dst(mLayerBlendMapSizeActual, mLayerBlendMapSizeActual, 1, cpuFormat, tmpData); - (*i)->getBuffer()->blitToMemory(dst); - size_t dataSz = PixelUtil::getNumElemBytes((*i)->getFormat()) * - mLayerBlendMapSizeActual * mLayerBlendMapSizeActual; - stream.write(tmpData, dataSz); - } - OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); - } - - // other data - // normals - stream.writeChunkBegin(TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION); - String normalDataType("normalmap"); - stream.write(&normalDataType); - stream.write(&mSize); - if (mCpuTerrainNormalMap) - { - // save from CPU data if it's there, it means GPU data was never created - stream.write((uint8*)mCpuTerrainNormalMap->data, mSize * mSize * 3); - } - else - { - uint8* tmpData = (uint8*)OGRE_MALLOC(mSize * mSize * 3, MEMCATEGORY_GENERAL); - PixelBox dst(mSize, mSize, 1, PF_BYTE_RGB, tmpData); - mTerrainNormalMap->getBuffer()->blitToMemory(dst); - stream.write(tmpData, mSize * mSize * 3); - OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); - } - stream.writeChunkEnd(TERRAINDERIVEDDATA_CHUNK_ID); - - - // colourmap - if (mGlobalColourMapEnabled) - { - stream.writeChunkBegin(TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION); - String colourDataType("colourmap"); - stream.write(&colourDataType); - stream.write(&mGlobalColourMapSize); - if (mCpuColourMapStorage) - { - // save from CPU data if it's there, it means GPU data was never created - stream.write(mCpuColourMapStorage, mGlobalColourMapSize * mGlobalColourMapSize * 3); - } - else - { - uint8* tmpData = (uint8*)OGRE_MALLOC(mGlobalColourMapSize * mGlobalColourMapSize * 3, MEMCATEGORY_GENERAL); - PixelBox dst(mGlobalColourMapSize, mGlobalColourMapSize, 1, PF_BYTE_RGB, tmpData); - mColourMap->getBuffer()->blitToMemory(dst); - stream.write(tmpData, mGlobalColourMapSize * mGlobalColourMapSize * 3); - OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); - } - stream.writeChunkEnd(TERRAINDERIVEDDATA_CHUNK_ID); - - } - - // lightmap - if (mLightMapRequired) - { - stream.writeChunkBegin(TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION); - String lightmapDataType("lightmap"); - stream.write(&lightmapDataType); - stream.write(&mLightmapSize); - if (mCpuLightmapStorage) - { - // save from CPU data if it's there, it means GPU data was never created - stream.write(mCpuLightmapStorage, mLightmapSize * mLightmapSize); - } - else - { - uint8* tmpData = (uint8*)OGRE_MALLOC(mLightmapSize * mLightmapSize, MEMCATEGORY_GENERAL); - PixelBox dst(mLightmapSize, mLightmapSize, 1, PF_L8, tmpData); - mLightmap->getBuffer()->blitToMemory(dst); - stream.write(tmpData, mLightmapSize * mLightmapSize); - OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); - } - stream.writeChunkEnd(TERRAINDERIVEDDATA_CHUNK_ID); - } - - // composite map - if (mCompositeMapRequired) - { - stream.writeChunkBegin(TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION); - String compositeMapDataType("compositemap"); - stream.write(&compositeMapDataType); - stream.write(&mCompositeMapSize); - if (mCpuCompositeMapStorage) - { - // save from CPU data if it's there, it means GPU data was never created - stream.write(mCpuCompositeMapStorage, mCompositeMapSize * mCompositeMapSize * 4); - } - else - { - // composite map is 4 channel, 3x diffuse, 1x specular mask - uint8* tmpData = (uint8*)OGRE_MALLOC(mCompositeMapSize * mCompositeMapSize * 4, MEMCATEGORY_GENERAL); - PixelBox dst(mCompositeMapSize, mCompositeMapSize, 1, PF_BYTE_RGBA, tmpData); - mCompositeMap->getBuffer()->blitToMemory(dst); - stream.write(tmpData, mCompositeMapSize * mCompositeMapSize * 4); - OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); - } - stream.writeChunkEnd(TERRAINDERIVEDDATA_CHUNK_ID); - } - - // write the quadtree - mQuadTree->save(stream); - - // stop compressing - stream.stopDeflate(); - - stream.writeChunkEnd(TERRAIN_CHUNK_ID); - - mModified = false; - mHeightDataModified = false; - - } - //--------------------------------------------------------------------- - void Terrain::writeLayerDeclaration(const TerrainLayerDeclaration& decl, StreamSerialiser& stream) - { - // Layer declaration - stream.writeChunkBegin(TERRAINLAYERDECLARATION_CHUNK_ID, TERRAINLAYERDECLARATION_CHUNK_VERSION); - // samplers - uint8 numSamplers = (uint8)decl.samplers.size(); - stream.write(&numSamplers); - for (TerrainLayerSamplerList::const_iterator i = decl.samplers.begin(); - i != decl.samplers.end(); ++i) - { - const TerrainLayerSampler& sampler = *i; - stream.writeChunkBegin(TERRAINLAYERSAMPLER_CHUNK_ID, TERRAINLAYERSAMPLER_CHUNK_VERSION); - stream.write(&sampler.alias); - uint8 pixFmt = (uint8)sampler.format; - stream.write(&pixFmt); - stream.writeChunkEnd(TERRAINLAYERSAMPLER_CHUNK_ID); - } - // elements - uint8 numElems = (uint8)decl.elements.size(); - stream.write(&numElems); - for (TerrainLayerSamplerElementList::const_iterator i = decl.elements.begin(); - i != decl.elements.end(); ++i) - { - const TerrainLayerSamplerElement& elem= *i; - stream.writeChunkBegin(TERRAINLAYERSAMPLERELEMENT_CHUNK_ID, TERRAINLAYERSAMPLERELEMENT_CHUNK_VERSION); - stream.write(&elem.source); - uint8 sem = (uint8)elem.semantic; - stream.write(&sem); - stream.write(&elem.elementStart); - stream.write(&elem.elementCount); - stream.writeChunkEnd(TERRAINLAYERSAMPLERELEMENT_CHUNK_ID); - } - stream.writeChunkEnd(TERRAINLAYERDECLARATION_CHUNK_ID); - } - //--------------------------------------------------------------------- - bool Terrain::readLayerDeclaration(StreamSerialiser& stream, TerrainLayerDeclaration& targetdecl) - { - if (!stream.readChunkBegin(TERRAINLAYERDECLARATION_CHUNK_ID, TERRAINLAYERDECLARATION_CHUNK_VERSION)) - return false; - // samplers - uint8 numSamplers; - stream.read(&numSamplers); - targetdecl.samplers.resize(numSamplers); - for (uint8 s = 0; s < numSamplers; ++s) - { - if (!stream.readChunkBegin(TERRAINLAYERSAMPLER_CHUNK_ID, TERRAINLAYERSAMPLER_CHUNK_VERSION)) - return false; - - stream.read(&(targetdecl.samplers[s].alias)); - uint8 pixFmt; - stream.read(&pixFmt); - targetdecl.samplers[s].format = (PixelFormat)pixFmt; - stream.readChunkEnd(TERRAINLAYERSAMPLER_CHUNK_ID); - } - // elements - uint8 numElems; - stream.read(&numElems); - targetdecl.elements.resize(numElems); - for (uint8 e = 0; e < numElems; ++e) - { - if (!stream.readChunkBegin(TERRAINLAYERSAMPLERELEMENT_CHUNK_ID, TERRAINLAYERSAMPLERELEMENT_CHUNK_VERSION)) - return false; - - stream.read(&(targetdecl.elements[e].source)); - uint8 sem; - stream.read(&sem); - targetdecl.elements[e].semantic = (TerrainLayerSamplerSemantic)sem; - stream.read(&(targetdecl.elements[e].elementStart)); - stream.read(&(targetdecl.elements[e].elementCount)); - stream.readChunkEnd(TERRAINLAYERSAMPLERELEMENT_CHUNK_ID); - } - stream.readChunkEnd(TERRAINLAYERDECLARATION_CHUNK_ID); - - return true; - } - //--------------------------------------------------------------------- - void Terrain::writeLayerInstanceList(const Terrain::LayerInstanceList& layers, StreamSerialiser& stream) - { - uint8 numLayers = (uint8)layers.size(); - stream.write(&numLayers); - for (LayerInstanceList::const_iterator i = layers.begin(); i != layers.end(); ++i) - { - const LayerInstance& inst = *i; - stream.writeChunkBegin(TERRAINLAYERINSTANCE_CHUNK_ID, TERRAINLAYERINSTANCE_CHUNK_VERSION); - stream.write(&inst.worldSize); - for (StringVector::const_iterator t = inst.textureNames.begin(); - t != inst.textureNames.end(); ++t) - { - stream.write(&(*t)); - } - stream.writeChunkEnd(TERRAINLAYERINSTANCE_CHUNK_ID); - } - - } - //--------------------------------------------------------------------- - bool Terrain::readLayerInstanceList(StreamSerialiser& stream, size_t numSamplers, Terrain::LayerInstanceList& targetlayers) - { - uint8 numLayers; - stream.read(&numLayers); - targetlayers.resize(numLayers); - for (uint8 l = 0; l < numLayers; ++l) - { - if (!stream.readChunkBegin(TERRAINLAYERINSTANCE_CHUNK_ID, TERRAINLAYERINSTANCE_CHUNK_VERSION)) - return false; - stream.read(&targetlayers[l].worldSize); - targetlayers[l].textureNames.resize(numSamplers); - for (size_t t = 0; t < numSamplers; ++t) - { - stream.read(&(targetlayers[l].textureNames[t])); - } - stream.readChunkEnd(TERRAINLAYERINSTANCE_CHUNK_ID); - } - - return true; - } - //--------------------------------------------------------------------- - const String& Terrain::_getDerivedResourceGroup() const - { - if (mResourceGroup.empty()) - return TerrainGlobalOptions::getSingleton().getDefaultResourceGroup(); - else - return mResourceGroup; - } - //--------------------------------------------------------------------- - bool Terrain::prepare(const String& filename) - { + StreamSerialiser ser(stream); + save(ser); + } + //--------------------------------------------------------------------- + void Terrain::save(StreamSerialiser& stream) + { + // wait for any queued processes to finish + waitForDerivedProcesses(); + + if (mHeightDataModified) + { + // When modifying, for efficiency we only increase the max deltas at each LOD, + // we never reduce them (since that would require re-examining more samples) + // Since we now save this data in the file though, we need to make sure we've + // calculated the optimal + Rect rect; + rect.top = 0; rect.bottom = mSize; + rect.left = 0; rect.right = mSize; + calculateHeightDeltas(rect); + finaliseHeightDeltas(rect, false); + } + + stream.writeChunkBegin(TERRAIN_CHUNK_ID, TERRAIN_CHUNK_VERSION); + + stream.writeChunkBegin(TERRAINGENERALINFO_CHUNK_ID, TERRAINGENERALINFO_CHUNK_VERSION); + uint8 align = (uint8)mAlign; + stream.write(&align); + + stream.write(&mSize); + stream.write(&mWorldSize); + stream.write(&mMaxBatchSize); + stream.write(&mMinBatchSize); + stream.write(&mPos); + stream.writeChunkEnd(TERRAINGENERALINFO_CHUNK_ID); + + TerrainLodManager::saveLodData(stream,this); + + // start compressing + stream.startDeflate(); + + writeLayerDeclaration(mLayerDecl, stream); + + // Layers + checkLayers(false); + uint8 numLayers = (uint8)mLayers.size(); + writeLayerInstanceList(mLayers, stream); + + // Packed layer blend data + if(!mCpuBlendMapStorage.empty()) + { + // save from CPU data if it's there, it means GPU data was never created + stream.write(&mLayerBlendMapSize); + + // load packed CPU data + int numBlendTex = getBlendTextureCount(numLayers); + for (int i = 0; i < numBlendTex; ++i) + { + PixelFormat fmt = getBlendTextureFormat(i, numLayers); + size_t channels = PixelUtil::getNumElemBytes(fmt); + size_t dataSz = channels * mLayerBlendMapSize * mLayerBlendMapSize; + uint8* pData = mCpuBlendMapStorage[i]; + stream.write(pData, dataSz); + } + } + else + { + if (mLayerBlendMapSize != mLayerBlendMapSizeActual) + { + LogManager::getSingleton().stream() << + "WARNING: blend maps were requested at a size larger than was supported " + "on this hardware, which means the quality has been degraded"; + } + stream.write(&mLayerBlendMapSizeActual); + uint8* tmpData = (uint8*)OGRE_MALLOC(mLayerBlendMapSizeActual * mLayerBlendMapSizeActual * 4, MEMCATEGORY_GENERAL); + uint8 texIndex = 0; + for (TexturePtrList::iterator i = mBlendTextureList.begin(); i != mBlendTextureList.end(); ++i, ++texIndex) + { + // Must blit back in CPU format! + PixelFormat cpuFormat = getBlendTextureFormat(texIndex, getLayerCount()); + PixelBox dst(mLayerBlendMapSizeActual, mLayerBlendMapSizeActual, 1, cpuFormat, tmpData); + (*i)->getBuffer()->blitToMemory(dst); + size_t dataSz = PixelUtil::getNumElemBytes((*i)->getFormat()) * + mLayerBlendMapSizeActual * mLayerBlendMapSizeActual; + stream.write(tmpData, dataSz); + } + OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); + } + + // other data + // normals + stream.writeChunkBegin(TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION); + String normalDataType("normalmap"); + stream.write(&normalDataType); + stream.write(&mSize); + if (mCpuTerrainNormalMap) + { + // save from CPU data if it's there, it means GPU data was never created + stream.write((uint8*)mCpuTerrainNormalMap->data, mSize * mSize * 3); + } + else + { + uint8* tmpData = (uint8*)OGRE_MALLOC(mSize * mSize * 3, MEMCATEGORY_GENERAL); + PixelBox dst(mSize, mSize, 1, PF_BYTE_RGB, tmpData); + mTerrainNormalMap->getBuffer()->blitToMemory(dst); + stream.write(tmpData, mSize * mSize * 3); + OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); + } + stream.writeChunkEnd(TERRAINDERIVEDDATA_CHUNK_ID); + + + // colourmap + if (mGlobalColourMapEnabled) + { + stream.writeChunkBegin(TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION); + String colourDataType("colourmap"); + stream.write(&colourDataType); + stream.write(&mGlobalColourMapSize); + if (mCpuColourMapStorage) + { + // save from CPU data if it's there, it means GPU data was never created + stream.write(mCpuColourMapStorage, mGlobalColourMapSize * mGlobalColourMapSize * 3); + } + else + { + uint8* tmpData = (uint8*)OGRE_MALLOC(mGlobalColourMapSize * mGlobalColourMapSize * 3, MEMCATEGORY_GENERAL); + PixelBox dst(mGlobalColourMapSize, mGlobalColourMapSize, 1, PF_BYTE_RGB, tmpData); + mColourMap->getBuffer()->blitToMemory(dst); + stream.write(tmpData, mGlobalColourMapSize * mGlobalColourMapSize * 3); + OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); + } + stream.writeChunkEnd(TERRAINDERIVEDDATA_CHUNK_ID); + + } + + // lightmap + if (mLightMapRequired) + { + stream.writeChunkBegin(TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION); + String lightmapDataType("lightmap"); + stream.write(&lightmapDataType); + stream.write(&mLightmapSize); + if (mCpuLightmapStorage) + { + // save from CPU data if it's there, it means GPU data was never created + stream.write(mCpuLightmapStorage, mLightmapSize * mLightmapSize); + } + else + { + uint8* tmpData = (uint8*)OGRE_MALLOC(mLightmapSize * mLightmapSize, MEMCATEGORY_GENERAL); + PixelBox dst(mLightmapSize, mLightmapSize, 1, PF_L8, tmpData); + mLightmap->getBuffer()->blitToMemory(dst); + stream.write(tmpData, mLightmapSize * mLightmapSize); + OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); + } + stream.writeChunkEnd(TERRAINDERIVEDDATA_CHUNK_ID); + } + + // composite map + if (mCompositeMapRequired) + { + stream.writeChunkBegin(TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION); + String compositeMapDataType("compositemap"); + stream.write(&compositeMapDataType); + stream.write(&mCompositeMapSize); + if (mCpuCompositeMapStorage) + { + // save from CPU data if it's there, it means GPU data was never created + stream.write(mCpuCompositeMapStorage, mCompositeMapSize * mCompositeMapSize * 4); + } + else + { + // composite map is 4 channel, 3x diffuse, 1x specular mask + uint8* tmpData = (uint8*)OGRE_MALLOC(mCompositeMapSize * mCompositeMapSize * 4, MEMCATEGORY_GENERAL); + PixelBox dst(mCompositeMapSize, mCompositeMapSize, 1, PF_BYTE_RGBA, tmpData); + mCompositeMap->getBuffer()->blitToMemory(dst); + stream.write(tmpData, mCompositeMapSize * mCompositeMapSize * 4); + OGRE_FREE(tmpData, MEMCATEGORY_GENERAL); + } + stream.writeChunkEnd(TERRAINDERIVEDDATA_CHUNK_ID); + } + + // write the quadtree + mQuadTree->save(stream); + + // stop compressing + stream.stopDeflate(); + + stream.writeChunkEnd(TERRAIN_CHUNK_ID); + + mModified = false; + mHeightDataModified = false; + + } + //--------------------------------------------------------------------- + void Terrain::writeLayerDeclaration(const TerrainLayerDeclaration& decl, StreamSerialiser& stream) + { + // Layer declaration + stream.writeChunkBegin(TERRAINLAYERDECLARATION_CHUNK_ID, TERRAINLAYERDECLARATION_CHUNK_VERSION); + // samplers + uint8 numSamplers = (uint8)decl.samplers.size(); + stream.write(&numSamplers); + for (TerrainLayerSamplerList::const_iterator i = decl.samplers.begin(); + i != decl.samplers.end(); ++i) + { + const TerrainLayerSampler& sampler = *i; + stream.writeChunkBegin(TERRAINLAYERSAMPLER_CHUNK_ID, TERRAINLAYERSAMPLER_CHUNK_VERSION); + stream.write(&sampler.alias); + uint8 pixFmt = (uint8)sampler.format; + stream.write(&pixFmt); + stream.writeChunkEnd(TERRAINLAYERSAMPLER_CHUNK_ID); + } + // elements + uint8 numElems = (uint8)decl.elements.size(); + stream.write(&numElems); + for (TerrainLayerSamplerElementList::const_iterator i = decl.elements.begin(); + i != decl.elements.end(); ++i) + { + const TerrainLayerSamplerElement& elem= *i; + stream.writeChunkBegin(TERRAINLAYERSAMPLERELEMENT_CHUNK_ID, TERRAINLAYERSAMPLERELEMENT_CHUNK_VERSION); + stream.write(&elem.source); + uint8 sem = (uint8)elem.semantic; + stream.write(&sem); + stream.write(&elem.elementStart); + stream.write(&elem.elementCount); + stream.writeChunkEnd(TERRAINLAYERSAMPLERELEMENT_CHUNK_ID); + } + stream.writeChunkEnd(TERRAINLAYERDECLARATION_CHUNK_ID); + } + //--------------------------------------------------------------------- + bool Terrain::readLayerDeclaration(StreamSerialiser& stream, TerrainLayerDeclaration& targetdecl) + { + if (!stream.readChunkBegin(TERRAINLAYERDECLARATION_CHUNK_ID, TERRAINLAYERDECLARATION_CHUNK_VERSION)) + return false; + // samplers + uint8 numSamplers; + stream.read(&numSamplers); + targetdecl.samplers.resize(numSamplers); + for (uint8 s = 0; s < numSamplers; ++s) + { + if (!stream.readChunkBegin(TERRAINLAYERSAMPLER_CHUNK_ID, TERRAINLAYERSAMPLER_CHUNK_VERSION)) + return false; + + stream.read(&(targetdecl.samplers[s].alias)); + uint8 pixFmt; + stream.read(&pixFmt); + targetdecl.samplers[s].format = (PixelFormat)pixFmt; + stream.readChunkEnd(TERRAINLAYERSAMPLER_CHUNK_ID); + } + // elements + uint8 numElems; + stream.read(&numElems); + targetdecl.elements.resize(numElems); + for (uint8 e = 0; e < numElems; ++e) + { + if (!stream.readChunkBegin(TERRAINLAYERSAMPLERELEMENT_CHUNK_ID, TERRAINLAYERSAMPLERELEMENT_CHUNK_VERSION)) + return false; + + stream.read(&(targetdecl.elements[e].source)); + uint8 sem; + stream.read(&sem); + targetdecl.elements[e].semantic = (TerrainLayerSamplerSemantic)sem; + stream.read(&(targetdecl.elements[e].elementStart)); + stream.read(&(targetdecl.elements[e].elementCount)); + stream.readChunkEnd(TERRAINLAYERSAMPLERELEMENT_CHUNK_ID); + } + stream.readChunkEnd(TERRAINLAYERDECLARATION_CHUNK_ID); + + return true; + } + //--------------------------------------------------------------------- + void Terrain::writeLayerInstanceList(const Terrain::LayerInstanceList& layers, StreamSerialiser& stream) + { + uint8 numLayers = (uint8)layers.size(); + stream.write(&numLayers); + for (LayerInstanceList::const_iterator i = layers.begin(); i != layers.end(); ++i) + { + const LayerInstance& inst = *i; + stream.writeChunkBegin(TERRAINLAYERINSTANCE_CHUNK_ID, TERRAINLAYERINSTANCE_CHUNK_VERSION); + stream.write(&inst.worldSize); + for (StringVector::const_iterator t = inst.textureNames.begin(); + t != inst.textureNames.end(); ++t) + { + stream.write(&(*t)); + } + stream.writeChunkEnd(TERRAINLAYERINSTANCE_CHUNK_ID); + } + + } + //--------------------------------------------------------------------- + bool Terrain::readLayerInstanceList(StreamSerialiser& stream, size_t numSamplers, Terrain::LayerInstanceList& targetlayers) + { + uint8 numLayers; + stream.read(&numLayers); + targetlayers.resize(numLayers); + for (uint8 l = 0; l < numLayers; ++l) + { + if (!stream.readChunkBegin(TERRAINLAYERINSTANCE_CHUNK_ID, TERRAINLAYERINSTANCE_CHUNK_VERSION)) + return false; + stream.read(&targetlayers[l].worldSize); + targetlayers[l].textureNames.resize(numSamplers); + for (size_t t = 0; t < numSamplers; ++t) + { + stream.read(&(targetlayers[l].textureNames[t])); + } + stream.readChunkEnd(TERRAINLAYERINSTANCE_CHUNK_ID); + } + + return true; + } + //--------------------------------------------------------------------- + const String& Terrain::_getDerivedResourceGroup() const + { + if (mResourceGroup.empty()) + return TerrainGlobalOptions::getSingleton().getDefaultResourceGroup(); + else + return mResourceGroup; + } + //--------------------------------------------------------------------- + bool Terrain::prepare(const String& filename) + { DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(filename, _getDerivedResourceGroup()); - return prepare(stream); - } - //--------------------------------------------------------------------- - bool Terrain::prepare(DataStreamPtr& stream) - { - freeLodData(); - mLodManager = OGRE_NEW TerrainLodManager( this, stream ); - StreamSerialiser ser(stream); - return prepare(ser); - } - //--------------------------------------------------------------------- - bool Terrain::prepare(StreamSerialiser& stream) - { - mPrepareInProgress = true; - - freeTemporaryResources(); - freeCPUResources(); - - if(mLodManager == NULL) - { - mLodManager = OGRE_NEW TerrainLodManager( this ); - } - - copyGlobalOptions(); - - const StreamSerialiser::Chunk *mainChunk = stream.readChunkBegin(TERRAIN_CHUNK_ID, TERRAIN_CHUNK_VERSION); - if (!mainChunk) - return false; + return prepare(stream); + } + //--------------------------------------------------------------------- + bool Terrain::prepare(DataStreamPtr& stream) + { + freeLodData(); + mLodManager = OGRE_NEW TerrainLodManager( this, stream ); + StreamSerialiser ser(stream); + return prepare(ser); + } + //--------------------------------------------------------------------- + bool Terrain::prepare(StreamSerialiser& stream) + { + mPrepareInProgress = true; + + freeTemporaryResources(); + freeCPUResources(); + + if(mLodManager == NULL) + { + mLodManager = OGRE_NEW TerrainLodManager( this ); + } + + copyGlobalOptions(); + + const StreamSerialiser::Chunk *mainChunk = stream.readChunkBegin(TERRAIN_CHUNK_ID, TERRAIN_CHUNK_VERSION); + if (!mainChunk) + return false; if(mainChunk->version > 1) stream.readChunkBegin(Terrain::TERRAINGENERALINFO_CHUNK_ID, Terrain::TERRAINGENERALINFO_CHUNK_VERSION); - uint8 align; - stream.read(&align); - mAlign = (Alignment)align; - stream.read(&mSize); - stream.read(&mWorldSize); - - stream.read(&mMaxBatchSize); - stream.read(&mMinBatchSize); - stream.read(&mPos); - mRootNode->setPosition(mPos); - updateBaseScale(); - determineLodLevels(); + uint8 align; + stream.read(&align); + mAlign = (Alignment)align; + stream.read(&mSize); + stream.read(&mWorldSize); + + stream.read(&mMaxBatchSize); + stream.read(&mMinBatchSize); + stream.read(&mPos); + mRootNode->setPosition(mPos); + updateBaseScale(); + determineLodLevels(); if(mainChunk->version > 1) stream.readChunkEnd(Terrain::TERRAINGENERALINFO_CHUNK_ID); - size_t numVertices = mSize * mSize; - mHeightData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GEOMETRY); - mDeltaData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GEOMETRY); - // As we may not load full data, so we should make it clean first - memset(mHeightData, 0.0f, sizeof(float)*numVertices); - memset(mDeltaData, 0.0f, sizeof(float)*numVertices); + size_t numVertices = mSize * mSize; + mHeightData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GEOMETRY); + mDeltaData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GEOMETRY); + // As we may not load full data, so we should make it clean first + memset(mHeightData, 0.0f, sizeof(float)*numVertices); + memset(mDeltaData, 0.0f, sizeof(float)*numVertices); if(mainChunk->version > 1) { @@ -686,78 +686,78 @@ namespace Ogre stream.read(mHeightData, numVertices); } - // Layer declaration - if (!readLayerDeclaration(stream, mLayerDecl)) - return false; - checkDeclaration(); - - - // Layers - if (!readLayerInstanceList(stream, mLayerDecl.samplers.size(), mLayers)) - return false; - deriveUVMultipliers(); - - // Packed layer blend data - uint8 numLayers = (uint8)mLayers.size(); - stream.read(&mLayerBlendMapSize); - mLayerBlendMapSizeActual = mLayerBlendMapSize; // for now, until we check - // load packed CPU data - int numBlendTex = getBlendTextureCount(numLayers); - for (int i = 0; i < numBlendTex; ++i) - { - PixelFormat fmt = getBlendTextureFormat(i, numLayers); - size_t channels = PixelUtil::getNumElemBytes(fmt); - size_t dataSz = channels * mLayerBlendMapSize * mLayerBlendMapSize; - uint8* pData = (uint8*)OGRE_MALLOC(dataSz, MEMCATEGORY_RESOURCE); - stream.read(pData, dataSz); - mCpuBlendMapStorage.push_back(pData); - } - - // derived data - while (!stream.isEndOfChunk(TERRAIN_CHUNK_ID) && - stream.peekNextChunkID() == TERRAINDERIVEDDATA_CHUNK_ID) - { - stream.readChunkBegin(TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION); - // name - String name; - stream.read(&name); - uint16 sz; - stream.read(&sz); - if (name == "normalmap") - { - mNormalMapRequired = true; - uint8* pData = static_cast(OGRE_MALLOC(sz * sz * 3, MEMCATEGORY_GENERAL)); - mCpuTerrainNormalMap = OGRE_NEW PixelBox(sz, sz, 1, PF_BYTE_RGB, pData); - - stream.read(pData, sz * sz * 3); - - } - else if (name == "colourmap") - { - mGlobalColourMapEnabled = true; - mGlobalColourMapSize = sz; - mCpuColourMapStorage = static_cast(OGRE_MALLOC(sz * sz * 3, MEMCATEGORY_GENERAL)); - stream.read(mCpuColourMapStorage, sz * sz * 3); - } - else if (name == "lightmap") - { - mLightMapRequired = true; - mLightmapSize = sz; - mCpuLightmapStorage = static_cast(OGRE_MALLOC(sz * sz, MEMCATEGORY_GENERAL)); - stream.read(mCpuLightmapStorage, sz * sz); - } - else if (name == "compositemap") - { - mCompositeMapRequired = true; - mCompositeMapSize = sz; - mCpuCompositeMapStorage = static_cast(OGRE_MALLOC(sz * sz * 4, MEMCATEGORY_GENERAL)); - stream.read(mCpuCompositeMapStorage, sz * sz * 4); - } - - stream.readChunkEnd(TERRAINDERIVEDDATA_CHUNK_ID); - - - } + // Layer declaration + if (!readLayerDeclaration(stream, mLayerDecl)) + return false; + checkDeclaration(); + + + // Layers + if (!readLayerInstanceList(stream, mLayerDecl.samplers.size(), mLayers)) + return false; + deriveUVMultipliers(); + + // Packed layer blend data + uint8 numLayers = (uint8)mLayers.size(); + stream.read(&mLayerBlendMapSize); + mLayerBlendMapSizeActual = mLayerBlendMapSize; // for now, until we check + // load packed CPU data + int numBlendTex = getBlendTextureCount(numLayers); + for (int i = 0; i < numBlendTex; ++i) + { + PixelFormat fmt = getBlendTextureFormat(i, numLayers); + size_t channels = PixelUtil::getNumElemBytes(fmt); + size_t dataSz = channels * mLayerBlendMapSize * mLayerBlendMapSize; + uint8* pData = (uint8*)OGRE_MALLOC(dataSz, MEMCATEGORY_RESOURCE); + stream.read(pData, dataSz); + mCpuBlendMapStorage.push_back(pData); + } + + // derived data + while (!stream.isEndOfChunk(TERRAIN_CHUNK_ID) && + stream.peekNextChunkID() == TERRAINDERIVEDDATA_CHUNK_ID) + { + stream.readChunkBegin(TERRAINDERIVEDDATA_CHUNK_ID, TERRAINDERIVEDDATA_CHUNK_VERSION); + // name + String name; + stream.read(&name); + uint16 sz; + stream.read(&sz); + if (name == "normalmap") + { + mNormalMapRequired = true; + uint8* pData = static_cast(OGRE_MALLOC(sz * sz * 3, MEMCATEGORY_GENERAL)); + mCpuTerrainNormalMap = OGRE_NEW PixelBox(sz, sz, 1, PF_BYTE_RGB, pData); + + stream.read(pData, sz * sz * 3); + + } + else if (name == "colourmap") + { + mGlobalColourMapEnabled = true; + mGlobalColourMapSize = sz; + mCpuColourMapStorage = static_cast(OGRE_MALLOC(sz * sz * 3, MEMCATEGORY_GENERAL)); + stream.read(mCpuColourMapStorage, sz * sz * 3); + } + else if (name == "lightmap") + { + mLightMapRequired = true; + mLightmapSize = sz; + mCpuLightmapStorage = static_cast(OGRE_MALLOC(sz * sz, MEMCATEGORY_GENERAL)); + stream.read(mCpuLightmapStorage, sz * sz); + } + else if (name == "compositemap") + { + mCompositeMapRequired = true; + mCompositeMapSize = sz; + mCpuCompositeMapStorage = static_cast(OGRE_MALLOC(sz * sz * 4, MEMCATEGORY_GENERAL)); + stream.read(mCpuCompositeMapStorage, sz * sz * 4); + } + + stream.readChunkEnd(TERRAINDERIVEDDATA_CHUNK_ID); + + + } if(mainChunk->version == 1) { @@ -766,3790 +766,3790 @@ namespace Ogre stream.read(mDeltaData, numVertices); } - // Create & load quadtree - mQuadTree = OGRE_NEW TerrainQuadTreeNode(this, 0, 0, 0, mSize, mNumLodLevels - 1, 0, 0); - mQuadTree->prepare(stream); + // Create & load quadtree + mQuadTree = OGRE_NEW TerrainQuadTreeNode(this, 0, 0, 0, mSize, mNumLodLevels - 1, 0, 0); + mQuadTree->prepare(stream); - // stop uncompressing + // stop uncompressing if(mainChunk->version > 1) stream.stopDeflate(); - stream.readChunkEnd(TERRAIN_CHUNK_ID); - - mModified = false; - mHeightDataModified = false; - - mPrepareInProgress = false; - - return true; - } - //--------------------------------------------------------------------- - bool Terrain::prepare(const ImportData& importData) - { - mPrepareInProgress = true; - freeTemporaryResources(); - freeLodData(); - freeCPUResources(); - mLodManager = OGRE_NEW TerrainLodManager( this ); - - copyGlobalOptions(); - - // validate - if (!(Bitwise::isPO2(importData.terrainSize - 1) && Bitwise::isPO2(importData.minBatchSize - 1) - && Bitwise::isPO2(importData.maxBatchSize - 1))) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "terrainSize, minBatchSize and maxBatchSize must all be 2^n + 1", - "Terrain::prepare"); - } - - if (importData.minBatchSize > importData.maxBatchSize) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "minBatchSize must be less than or equal to maxBatchSize", - "Terrain::prepare"); - } - - if (importData.maxBatchSize > TERRAIN_MAX_BATCH_SIZE) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "maxBatchSize must be no larger than " + - StringConverter::toString(TERRAIN_MAX_BATCH_SIZE), - "Terrain::prepare"); - } - - mAlign = importData.terrainAlign; - mSize = importData.terrainSize; - mWorldSize = importData.worldSize; - mLayerDecl = importData.layerDeclaration; - checkDeclaration(); - mLayers = importData.layerList; - checkLayers(false); - deriveUVMultipliers(); - mMaxBatchSize = importData.maxBatchSize; - mMinBatchSize = importData.minBatchSize; - setPosition(importData.pos); - - updateBaseScale(); - determineLodLevels(); - - size_t numVertices = mSize * mSize; - - mHeightData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GEOMETRY); - - if (importData.inputFloat) - { - if (Math::RealEqual(importData.inputBias, 0.0) && Math::RealEqual(importData.inputScale, 1.0)) - { - // straight copy - memcpy(mHeightData, importData.inputFloat, sizeof(float) * numVertices); - } - else - { - // scale & bias - float* src = importData.inputFloat; - float* dst = mHeightData; - for (size_t i = 0; i < numVertices; ++i) - *dst++ = (*src++ * importData.inputScale) + importData.inputBias; - } - } - else if (importData.inputImage) - { - Image* img = importData.inputImage; - - if (img->getWidth() != mSize || img->getHeight() != mSize) - img->resize(mSize, mSize); - - // convert image data to floats - // Do this on a row-by-row basis, because we describe the terrain in - // a bottom-up fashion (ie ascending world coords), while Image is top-down - unsigned char* pSrcBase = img->getData(); - for (size_t i = 0; i < mSize; ++i) - { - size_t srcy = mSize - i - 1; - unsigned char* pSrc = pSrcBase + srcy * img->getRowSpan(); - float* pDst = mHeightData + i * mSize; - PixelUtil::bulkPixelConversion(pSrc, img->getFormat(), - pDst, PF_FLOAT32_R, mSize); - } - - if (!Math::RealEqual(importData.inputBias, 0.0) || !Math::RealEqual(importData.inputScale, 1.0)) - { - float* pAdj = mHeightData; - for (size_t i = 0; i < numVertices; ++i) - { - *pAdj = (*pAdj * importData.inputScale) + importData.inputBias; - ++pAdj; - } - } - - } - else - { - // start with flat terrain - if (importData.constantHeight == 0) - memset(mHeightData, 0, sizeof(float) * mSize * mSize); - else - { - float* pFloat = mHeightData; - for (long i = 0 ; i < mSize * mSize; ++i) - *pFloat++ = importData.constantHeight; - - } - } - - mDeltaData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GEOMETRY); - memset(mDeltaData, 0, sizeof(float) * numVertices); - - mQuadTree = OGRE_NEW TerrainQuadTreeNode(this, 0, 0, 0, mSize, mNumLodLevels - 1, 0, 0); - mQuadTree->prepare(); - - // calculate entire terrain - Rect rect; - rect.top = 0; rect.bottom = mSize; - rect.left = 0; rect.right = mSize; - calculateHeightDeltas(rect); - finaliseHeightDeltas(rect, true); - - distributeVertexData(); - - // Imported data is treated as modified because it's not saved - mModified = true; - mHeightDataModified = true; - - mPrepareInProgress = false; - - return true; - - } - //--------------------------------------------------------------------- - void Terrain::copyGlobalOptions() - { - TerrainGlobalOptions& opts = TerrainGlobalOptions::getSingleton(); - mSkirtSize = opts.getSkirtSize(); - mRenderQueueGroup = opts.getRenderQueueGroup(); - mVisibilityFlags = opts.getVisibilityFlags(); - mQueryFlags = opts.getQueryFlags(); - mLayerBlendMapSize = opts.getLayerBlendMapSize(); - mLayerBlendMapSizeActual = mLayerBlendMapSize; // for now, until we check - mLightmapSize = opts.getLightMapSize(); - mLightmapSizeActual = mLightmapSize; // for now, until we check - mCompositeMapSize = opts.getCompositeMapSize(); - mCompositeMapSizeActual = mCompositeMapSize; // for now, until we check - - } - //--------------------------------------------------------------------- - void Terrain::determineLodLevels() - { - /* On a leaf-node basis, LOD can vary from maxBatch to minBatch in - number of vertices. After that, nodes will be gathered into parent - nodes with the same number of vertices, but they are combined with - 3 of their siblings. In practice, the number of LOD levels overall - is: - LODlevels = log2(size - 1) - log2(minBatch - 1) + 1 - TreeDepth = log2((size - 1) / (maxBatch - 1)) + 1 - - .. it's just that at the max LOD, the terrain is divided into - (size - 1) / (maxBatch - 1) tiles each of maxBatch vertices, and - at the lowest LOD the terrain is made up of one single tile of - minBatch vertices. - - Example: size = 257, minBatch = 17, maxBatch = 33 - - LODlevels = log2(257 - 1) - log2(17 - 1) + 1 = 8 - 4 + 1 = 5 - TreeDepth = log2((size - 1) / (maxBatch - 1)) + 1 = 4 - - LOD list - this assumes everything changes at once, which rarely happens of course - in fact except where groupings must occur, tiles can change independently - LOD 0: 257 vertices, 8 x 33 vertex tiles (tree depth 3) - LOD 1: 129 vertices, 8 x 17 vertex tiles (tree depth 3) - LOD 2: 65 vertices, 4 x 17 vertex tiles (tree depth 2) - LOD 3: 33 vertices, 2 x 17 vertex tiles (tree depth 1) - LOD 4: 17 vertices, 1 x 17 vertex tiles (tree depth 0) - - Notice how we only have 2 sizes of index buffer to be concerned about, - 17 vertices (per side) or 33. This makes buffer re-use much easier while - still giving the full range of LODs. - */ - mNumLodLevelsPerLeafNode = (uint16) (Math::Log2(mMaxBatchSize - 1.0f) - Math::Log2(mMinBatchSize - 1.0f) + 1.0f); - mNumLodLevels = (uint16) (Math::Log2(mSize - 1.0f) - Math::Log2(mMinBatchSize - 1.0f) + 1.0f); - //mTreeDepth = Math::Log2(mMaxBatchSize - 1) - Math::Log2(mMinBatchSize - 1) + 2; - mTreeDepth = mNumLodLevels - mNumLodLevelsPerLeafNode + 1; - - LogManager::getSingleton().stream() << "Terrain created; size=" << mSize - << " minBatch=" << mMinBatchSize << " maxBatch=" << mMaxBatchSize - << " treeDepth=" << mTreeDepth << " lodLevels=" << mNumLodLevels - << " leafLods=" << mNumLodLevelsPerLeafNode; - } - //--------------------------------------------------------------------- - void Terrain::distributeVertexData() - { - /* Now we need to figure out how to distribute vertex data. We want to - use 16-bit indexes for compatibility, which means that the maximum patch - size that we can address (even sparsely for lower LODs) is 129x129 - (the next one up, 257x257 is too big). - - So we need to split the vertex data into chunks of 129. The number of - primary tiles this creates also indicates the point above which in - the node tree that we can no longer merge tiles at lower LODs without - using different vertex data. For example, using the 257x257 input example - above, the vertex data would have to be split in 2 (in each dimension) - in order to fit within the 129x129 range. This data could be shared by - all tree depths from 1 onwards, it's just that LODs 3-1 would sample - the 129x129 data sparsely. LOD 0 would sample all of the vertices. - - LOD 4 however, the lowest LOD, could not work with the same vertex data - because it needs to cover the entire terrain. There are 2 choices here: - create another set of vertex data at 17x17 which is only used by LOD 4, - or make LOD 4 occur at tree depth 1 instead (ie still split up, and - rendered as 2x9 along each edge instead. - - Since rendering very small batches is not desirable, and the vertex counts - are inherently not going to be large, creating a separate vertex set is - preferable. This will also be more efficient on the vertex cache with - distant terrains. - - We probably need a larger example, because in this case only 1 level (LOD 0) - needs to use this separate vertex data. Higher detail terrains will need - it for multiple levels, here's a 2049x2049 example with 65 / 33 batch settings: - - LODlevels = log2(2049 - 1) - log2(33 - 1) + 1 = 11 - 5 + 1 = 7 - TreeDepth = log2((2049 - 1) / (65 - 1)) + 1 = 6 - Number of vertex data splits at most detailed level: - (size - 1) / (TERRAIN_MAX_BATCH_SIZE - 1) = 2048 / 128 = 16 - - LOD 0: 2049 vertices, 32 x 65 vertex tiles (tree depth 5) vdata 0-15 [129x16] - LOD 1: 1025 vertices, 32 x 33 vertex tiles (tree depth 5) vdata 0-15 [129x16] - LOD 2: 513 vertices, 16 x 33 vertex tiles (tree depth 4) vdata 0-15 [129x16] - LOD 3: 257 vertices, 8 x 33 vertex tiles (tree depth 3) vdata 16-17 [129x2] - LOD 4: 129 vertices, 4 x 33 vertex tiles (tree depth 2) vdata 16-17 [129x2] - LOD 5: 65 vertices, 2 x 33 vertex tiles (tree depth 1) vdata 16-17 [129x2] - LOD 6: 33 vertices, 1 x 33 vertex tiles (tree depth 0) vdata 18 [33] - - All the vertex counts are to be squared, they are just along one edge. - So as you can see, we need to have 3 levels of vertex data to satisy this - (admittedly quite extreme) case, and a total of 19 sets of vertex data. - The full detail geometry, which is 16(x16) sets of 129(x129), used by - LODs 0-2. LOD 3 can't use this set because it needs to group across them, - because it has only 8 tiles, so we make another set which satisfies this - at a maximum of 129 vertices per vertex data section. In this case LOD - 3 needs 257(x257) total vertices so we still split into 2(x2) sets of 129. - This set is good up to and including LOD 5, but LOD 6 needs a single - contiguous set of vertices, so we make a 33x33 vertex set for it. - - In terms of vertex data stored, this means that while our primary data is: - 2049^2 = 4198401 vertices - our final stored vertex data is - (16 * 129)^2 + (2 * 129)^2 + 33^2 = 4327749 vertices - - That equals a 3% premium, but it's both necessary and worth it for the - reduction in batch count resulting from the grouping. In addition, at - LODs 3 and 6 (or rather tree depth 3 and 0) there is the opportunity - to free up the vertex data used by more detailed LODs, which is - important when dealing with large terrains. For example, if we - freed the (GPU) vertex data for LOD 0-2 in the medium distance, - we would save 98% of the memory overhead for this terrain. - - */ - - LogManager& logMgr = LogManager::getSingleton(); - logMgr.stream(LML_TRIVIAL) << "Terrain::distributeVertexData processing source " - "terrain size of " << mSize; - - uint16 depth = mTreeDepth; - uint16 prevdepth = depth; - uint16 currresolution = mSize; - uint16 bakedresolution = mSize; - uint16 targetSplits = (bakedresolution - 1) / (TERRAIN_MAX_BATCH_SIZE - 1); - while(depth-- && targetSplits) - { - uint splits = 1 << depth; - if (splits == targetSplits) - { - logMgr.stream(LML_TRIVIAL) << " Assigning vertex data, resolution=" - << bakedresolution << " startDepth=" << depth << " endDepth=" << prevdepth - << " splits=" << splits; - // vertex data goes at this level, at bakedresolution - // applies to all lower levels (except those with a closer vertex data) - // determine physical size (as opposed to resolution) - uint sz = ((bakedresolution-1) / splits) + 1; - mQuadTree->assignVertexData(depth, prevdepth, bakedresolution, sz); - - // next set to look for - bakedresolution = ((currresolution - 1) >> 1) + 1; - targetSplits = (bakedresolution - 1) / (TERRAIN_MAX_BATCH_SIZE - 1); - prevdepth = depth; - - } - - currresolution = ((currresolution - 1) >> 1) + 1; - - - } - - // Always assign vertex data to the top of the tree - if (prevdepth > 0) - { - mQuadTree->assignVertexData(0, 1, bakedresolution, bakedresolution); - logMgr.stream(LML_TRIVIAL) << " Assigning vertex data, resolution: " - << bakedresolution << " startDepth=0 endDepth=1 splits=1"; - - } - - logMgr.stream(LML_TRIVIAL) << "Terrain::distributeVertexData finished"; - - } - //--------------------------------------------------------------------- - void Terrain::load(const String& filename) - { - if (prepare(filename)) - load(); - else - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Error while preparing " + filename + ", see log for details", - __FUNCTION__); - } - //--------------------------------------------------------------------- - void Terrain::load(StreamSerialiser& stream) - { - if (prepare(stream)) - load(); - else - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Error while preparing from stream, see log for details", - __FUNCTION__); - } - //--------------------------------------------------------------------- - void Terrain::load(int lodLevel, bool synchronous) - { - if (mQuadTree) - mLodManager->updateToLodLevel(lodLevel,synchronous); - - if (mIsLoaded || mGenerateMaterialInProgress) - return; - - checkLayers(true); - createOrDestroyGPUColourMap(); - createOrDestroyGPUNormalMap(); - createOrDestroyGPULightmap(); - createOrDestroyGPUCompositeMap(); - - mMaterialGenerator->requestOptions(this); - - mGenerateMaterialInProgress = true; - GenerateMaterialRequest req; - req.terrain = this; - req.stage = GEN_MATERIAL; - req.startTime = synchronous ? 0 : Root::getSingletonPtr()->getTimer()->getMilliseconds() + TERRAIN_GENERATE_MATERIAL_INTERVAL_MS; - req.synchronous = synchronous; - - Root::getSingleton().getWorkQueue()->addRequest( - mWorkQueueChannel, WORKQUEUE_GENERATE_MATERIAL_REQUEST, - Any(req), 0, synchronous); - } - //--------------------------------------------------------------------- - void Terrain::unload() - { - if (!mIsLoaded) - return; - - if (mQuadTree) - mQuadTree->unload(); - - // free own buffers if used, but not custom - mDefaultGpuBufferAllocator.freeAllBuffers(); - - mIsLoaded = false; - mModified = false; - mHeightDataModified = false; - - } - //--------------------------------------------------------------------- - void Terrain::unprepare() - { - if (mQuadTree) - mQuadTree->unprepare(); - } - //--------------------------------------------------------------------- - float* Terrain::getHeightData() const - { - return mHeightData; - } - //--------------------------------------------------------------------- - float* Terrain::getHeightData(long x, long y) const - { - assert (x >= 0 && x < mSize && y >= 0 && y < mSize); - return &mHeightData[y * mSize + x]; - } - //--------------------------------------------------------------------- - float Terrain::getHeightAtPoint(long x, long y) const - { - // clamp - x = std::min(x, (long)mSize - 1L); - x = std::max(x, 0L); - y = std::min(y, (long)mSize - 1L); - y = std::max(y, 0L); - - int highestLod = mLodManager->getHighestLodPrepared(); - long skip = 1 << (highestLod != -1 ? highestLod : 0); - if (x % skip == 0 && y % skip == 0) - return *getHeightData(x, y); - - long x1 = std::min( (x/skip) * skip , (long)mSize - 1L ); - long x2 = std::min( ((x+skip) / skip) * skip, (long)mSize - 1L ); - long y1 = std::min( (y/skip) * skip , (long)mSize - 1L ); - long y2 = std::min( ((y+skip) / skip) * skip, (long)mSize - 1L ); - - float rx = (float(x % skip) / skip); - float ry = (float(y % skip) / skip); - - return *getHeightData(x1, y1) * (1.0f-rx) * (1.0f-ry) - + *getHeightData(x2, y1) * rx * (1.0f-ry) - + *getHeightData(x1, y2) * (1.0f-rx) * ry - + *getHeightData(x2, y2) * rx * ry; - } - //--------------------------------------------------------------------- - void Terrain::setHeightAtPoint(long x, long y, float h) - { - // force to load all data - load(0,true); - // clamp - x = std::min(x, (long)mSize - 1L); - x = std::max(x, 0L); - y = std::min(y, (long)mSize - 1L); - y = std::max(y, 0L); - - *getHeightData(x, y) = h; - Rect rect; - rect.left = x; - rect.right = x+1; - rect.top = y; - rect.bottom = y+1; - dirtyRect(rect); - } - //--------------------------------------------------------------------- - float Terrain::getHeightAtTerrainPosition(Real x, Real y) const - { - // get left / bottom points (rounded down) - Real factor = (Real)mSize - 1.0f; - Real invFactor = 1.0f / factor; - - long startX = static_cast(x * factor); - long startY = static_cast(y * factor); - long endX = startX + 1; - long endY = startY + 1; - - // now get points in terrain space (effectively rounding them to boundaries) - // note that we do not clamp! We need a valid plane - Real startXTS = startX * invFactor; - Real startYTS = startY * invFactor; - Real endXTS = endX * invFactor; - Real endYTS = endY * invFactor; - - // now clamp - endX = std::min(endX, (long)mSize-1); - endY = std::min(endY, (long)mSize-1); - - // get parametric from start coord to next point - Real xParam = (x - startXTS) / invFactor; - Real yParam = (y - startYTS) / invFactor; - - - /* For even / odd tri strip rows, triangles are this shape: - even odd - 3---2 3---2 - | / | | \ | - 0---1 0---1 - */ - - // Build all 4 positions in terrain space, using point-sampled height - Vector3 v0 (startXTS, startYTS, getHeightAtPoint(startX, startY)); - Vector3 v1 (endXTS, startYTS, getHeightAtPoint(endX, startY)); - Vector3 v2 (endXTS, endYTS, getHeightAtPoint(endX, endY)); - Vector3 v3 (startXTS, endYTS, getHeightAtPoint(startX, endY)); - // define this plane in terrain space - Plane plane; - if (startY % 2) - { - // odd row - bool secondTri = ((1.0 - yParam) > xParam); - if (secondTri) - plane.redefine(v0, v1, v3); - else - plane.redefine(v1, v2, v3); - } - else - { - // even row - bool secondTri = (yParam > xParam); - if (secondTri) - plane.redefine(v0, v2, v3); - else - plane.redefine(v0, v1, v2); - } - - // Solve plane equation for z - return (-plane.normal.x * x - -plane.normal.y * y - - plane.d) / plane.normal.z; - - - } - //--------------------------------------------------------------------- - float Terrain::getHeightAtWorldPosition(Real x, Real y, Real z) const - { - Vector3 terrPos; - getTerrainPosition(x, y, z, &terrPos); - return getHeightAtTerrainPosition(terrPos.x, terrPos.y); - } - //--------------------------------------------------------------------- - float Terrain::getHeightAtWorldPosition(const Vector3& pos) const - { - return getHeightAtWorldPosition(pos.x, pos.y, pos.z); - } - //--------------------------------------------------------------------- - const float* Terrain::getDeltaData() const - { - return mDeltaData; - } - //--------------------------------------------------------------------- - const float* Terrain::getDeltaData(long x, long y) const - { - assert (x >= 0 && x < mSize && y >= 0 && y < mSize); - return &mDeltaData[y * mSize + x]; - } - //--------------------------------------------------------------------- - Vector3 Terrain::convertPosition(Space inSpace, const Vector3& inPos, Space outSpace) const - { - Vector3 ret; - convertPosition(inSpace, inPos, outSpace, ret); - return ret; - } - //--------------------------------------------------------------------- - Vector3 Terrain::convertDirection(Space inSpace, const Vector3& inDir, Space outSpace) const - { - Vector3 ret; - convertDirection(inSpace, inDir, outSpace, ret); - return ret; - } - //--------------------------------------------------------------------- - void Terrain::convertPosition(Space inSpace, const Vector3& inPos, Space outSpace, Vector3& outPos) const - { - convertSpace(inSpace, inPos, outSpace, outPos, true); - } - //--------------------------------------------------------------------- - void Terrain::convertDirection(Space inSpace, const Vector3& inDir, Space outSpace, Vector3& outDir) const - { - convertSpace(inSpace, inDir, outSpace, outDir, false); - } - //--------------------------------------------------------------------- - void Terrain::convertSpace(Space inSpace, const Vector3& inVec, Space outSpace, Vector3& outVec, bool translation) const - { - Space currSpace = inSpace; - outVec = inVec; - while (currSpace != outSpace) - { - switch(currSpace) - { - case WORLD_SPACE: - // In all cases, transition to local space - if (translation) - outVec -= mPos; - currSpace = LOCAL_SPACE; - break; - case LOCAL_SPACE: - switch(outSpace) - { - case WORLD_SPACE: - if (translation) - outVec += mPos; - currSpace = WORLD_SPACE; - break; - case POINT_SPACE: - case TERRAIN_SPACE: - // go via terrain space - outVec = convertWorldToTerrainAxes(outVec); - if (translation) - { - outVec.x -= mBase; outVec.y -= mBase; - outVec.x /= (mSize - 1) * mScale; outVec.y /= (mSize - 1) * mScale; - } - currSpace = TERRAIN_SPACE; - break; - case LOCAL_SPACE: - default: - break; - }; - break; - case TERRAIN_SPACE: - switch(outSpace) - { - case WORLD_SPACE: - case LOCAL_SPACE: - // go via local space - if (translation) - { - outVec.x *= (mSize - 1) * mScale; outVec.y *= (mSize - 1) * mScale; - outVec.x += mBase; outVec.y += mBase; - } - outVec = convertTerrainToWorldAxes(outVec); - currSpace = LOCAL_SPACE; - break; - case POINT_SPACE: - if (translation) - { - outVec.x *= (mSize - 1); outVec.y *= (mSize - 1); - // rounding up/down - // this is why POINT_SPACE is the last on the list, because it loses data - outVec.x = static_cast(static_cast(outVec.x + 0.5)); - outVec.y = static_cast(static_cast(outVec.y + 0.5)); - } - currSpace = POINT_SPACE; - break; - case TERRAIN_SPACE: - default: - break; - }; - break; - case POINT_SPACE: - // always go via terrain space - if (translation) - outVec.x /= (mSize - 1); outVec.y /= (mSize - 1); - currSpace = TERRAIN_SPACE; - break; - - }; - } - - } - //--------------------------------------------------------------------- - void Terrain::convertWorldToTerrainAxes(Alignment align, const Vector3& worldVec, Vector3* terrainVec) - { - switch (align) - { - case ALIGN_X_Z: - terrainVec->z = worldVec.y; - terrainVec->x = worldVec.x; - terrainVec->y = -worldVec.z; - break; - case ALIGN_Y_Z: - terrainVec->z = worldVec.x; - terrainVec->x = -worldVec.z; - terrainVec->y = worldVec.y; - break; - case ALIGN_X_Y: - *terrainVec = worldVec; - break; - }; - - } - //--------------------------------------------------------------------- - void Terrain::convertTerrainToWorldAxes(Alignment align, const Vector3& terrainVec, Vector3* worldVec) - { - switch (align) - { - case ALIGN_X_Z: - worldVec->x = terrainVec.x; - worldVec->y = terrainVec.z; - worldVec->z = -terrainVec.y; - break; - case ALIGN_Y_Z: - worldVec->x = terrainVec.z; - worldVec->y = terrainVec.y; - worldVec->z = -terrainVec.x; - break; - case ALIGN_X_Y: - *worldVec = terrainVec; - break; - }; - - } - //--------------------------------------------------------------------- - Vector3 Terrain::convertWorldToTerrainAxes(const Vector3& inVec) const - { - Vector3 ret; - convertWorldToTerrainAxes(mAlign, inVec, &ret); - - return ret; - } - //--------------------------------------------------------------------- - Vector3 Terrain::convertTerrainToWorldAxes(const Vector3& inVec) const - { - Vector3 ret; - convertTerrainToWorldAxes(mAlign, inVec, &ret); - - return ret; - } - //--------------------------------------------------------------------- - void Terrain::getPoint(long x, long y, Vector3* outpos) const - { - getPointAlign(x, y, mAlign, outpos); - } - //--------------------------------------------------------------------- - void Terrain::getPoint(long x, long y, float height, Vector3* outpos) const - { - getPointAlign(x, y, height, mAlign, outpos); - } - //--------------------------------------------------------------------- - void Terrain::getPointAlign(long x, long y, Alignment align, Vector3* outpos) const - { - getPointAlign(x, y, *getHeightData(x, y), align, outpos); - } - //--------------------------------------------------------------------- - void Terrain::getPointAlign(long x, long y, float height, Alignment align, Vector3* outpos) const - { - switch(align) - { - case ALIGN_X_Z: - outpos->y = height; - outpos->x = x * mScale + mBase; - outpos->z = y * -mScale - mBase; - break; - case ALIGN_Y_Z: - outpos->x = height; - outpos->z = x * -mScale - mBase; - outpos->y = y * mScale + mBase; - break; - case ALIGN_X_Y: - outpos->z = height; - outpos->x = x * mScale + mBase; - outpos->y = y * mScale + mBase; - break; - }; - - } - //--------------------------------------------------------------------- - void Terrain::getPointTransform(Matrix4* outXform) const - { - *outXform = Matrix4::ZERO; - switch(mAlign) - { - case ALIGN_X_Z: - //outpos->y = height (z) - (*outXform)[1][2] = 1.0f; - //outpos->x = x * mScale + mBase; - (*outXform)[0][0] = mScale; - (*outXform)[0][3] = mBase; - //outpos->z = y * -mScale - mBase; - (*outXform)[2][1] = -mScale; - (*outXform)[2][3] = -mBase; - break; - case ALIGN_Y_Z: - //outpos->x = height; - (*outXform)[0][2] = 1.0f; - //outpos->z = x * -mScale - mBase; - (*outXform)[2][0] = -mScale; - (*outXform)[2][3] = -mBase; - //outpos->y = y * mScale + mBase; - (*outXform)[1][1] = mScale; - (*outXform)[1][3] = mBase; - break; - case ALIGN_X_Y: - //outpos->z = height; - (*outXform)[2][2] = 1.0f; // strictly already the case, but.. - //outpos->x = x * mScale + mBase; - (*outXform)[0][0] = mScale; - (*outXform)[0][3] = mBase; - //outpos->y = y * mScale + mBase; - (*outXform)[1][1] = mScale; - (*outXform)[1][3] = mBase; - break; - }; - (*outXform)[3][3] = 1.0f; - } - //--------------------------------------------------------------------- - void Terrain::getVector(const Vector3& inVec, Vector3* outVec) const - { - getVectorAlign(inVec.x, inVec.y, inVec.z, mAlign, outVec); - } - //--------------------------------------------------------------------- - void Terrain::getVector(Real x, Real y, Real z, Vector3* outVec) const - { - getVectorAlign(x, y, z, mAlign, outVec); - } - //--------------------------------------------------------------------- - void Terrain::getVectorAlign(const Vector3& inVec, Alignment align, Vector3* outVec) const - { - getVectorAlign(inVec.x, inVec.y, inVec.z, align, outVec); - } - //--------------------------------------------------------------------- - void Terrain::getVectorAlign(Real x, Real y, Real z, Alignment align, Vector3* outVec) const - { - - switch(align) - { - case ALIGN_X_Z: - outVec->y = z; - outVec->x = x; - outVec->z = -y; - break; - case ALIGN_Y_Z: - outVec->x = z; - outVec->y = y; - outVec->z = -x; - break; - case ALIGN_X_Y: - outVec->x = x; - outVec->y = y; - outVec->z = z; - break; - }; - - } - //--------------------------------------------------------------------- - void Terrain::getPosition(const Vector3& TSpos, Vector3* outWSpos) const - { - getPositionAlign(TSpos, mAlign, outWSpos); - } - //--------------------------------------------------------------------- - void Terrain::getPosition(Real x, Real y, Real z, Vector3* outWSpos) const - { - getPositionAlign(x, y, z, mAlign, outWSpos); - } - //--------------------------------------------------------------------- - void Terrain::getTerrainPosition(const Vector3& WSpos, Vector3* outTSpos) const - { - getTerrainPositionAlign(WSpos, mAlign, outTSpos); - } - //--------------------------------------------------------------------- - void Terrain::getTerrainPosition(Real x, Real y, Real z, Vector3* outTSpos) const - { - getTerrainPositionAlign(x, y, z, mAlign, outTSpos); - } - //--------------------------------------------------------------------- - void Terrain::getPositionAlign(const Vector3& TSpos, Alignment align, Vector3* outWSpos) const - { - getPositionAlign(TSpos.x, TSpos.y, TSpos.z, align, outWSpos); - } - //--------------------------------------------------------------------- - void Terrain::getPositionAlign(Real x, Real y, Real z, Alignment align, Vector3* outWSpos) const - { - switch(align) - { - case ALIGN_X_Z: - outWSpos->y = z; - outWSpos->x = x * (mSize - 1) * mScale + mBase; - outWSpos->z = y * (mSize - 1) * -mScale - mBase; - break; - case ALIGN_Y_Z: - outWSpos->x = z; - outWSpos->y = y * (mSize - 1) * mScale + mBase; - outWSpos->z = x * (mSize - 1) * -mScale - mBase; - break; - case ALIGN_X_Y: - outWSpos->z = z; - outWSpos->x = x * (mSize - 1) * mScale + mBase; - outWSpos->y = y * (mSize - 1) * mScale + mBase; - break; - }; - - } - //--------------------------------------------------------------------- - void Terrain::getTerrainPositionAlign(const Vector3& WSpos, Alignment align, Vector3* outTSpos) const - { - getTerrainPositionAlign(WSpos.x, WSpos.y, WSpos.z, align, outTSpos); - } - //--------------------------------------------------------------------- - void Terrain::getTerrainPositionAlign(Real x, Real y, Real z, Alignment align, Vector3* outTSpos) const - { - switch(align) - { - case ALIGN_X_Z: - outTSpos->x = (x - mBase - mPos.x) / ((mSize - 1) * mScale); - outTSpos->y = (z + mBase - mPos.z) / ((mSize - 1) * -mScale); - outTSpos->z = y; - break; - case ALIGN_Y_Z: - outTSpos->x = (z - mBase - mPos.z) / ((mSize - 1) * -mScale); - outTSpos->y = (y + mBase - mPos.y) / ((mSize - 1) * mScale); - outTSpos->z = x; - break; - case ALIGN_X_Y: - outTSpos->x = (x - mBase - mPos.x) / ((mSize - 1) * mScale); - outTSpos->y = (y - mBase - mPos.y) / ((mSize - 1) * mScale); - outTSpos->z = z; - break; - }; - - } - //--------------------------------------------------------------------- - void Terrain::getTerrainVector(const Vector3& inVec, Vector3* outVec) const - { - getTerrainVectorAlign(inVec.x, inVec.y, inVec.z, mAlign, outVec); - } - //--------------------------------------------------------------------- - void Terrain::getTerrainVector(Real x, Real y, Real z, Vector3* outVec) const - { - getTerrainVectorAlign(x, y, z, mAlign, outVec); - } - //--------------------------------------------------------------------- - void Terrain::getTerrainVectorAlign(const Vector3& inVec, Alignment align, Vector3* outVec) const - { - getTerrainVectorAlign(inVec.x, inVec.y, inVec.z, align, outVec); - } - //--------------------------------------------------------------------- - void Terrain::getTerrainVectorAlign(Real x, Real y, Real z, Alignment align, Vector3* outVec) const - { - - switch(align) - { - case ALIGN_X_Z: - outVec->z = y; - outVec->x = x; - outVec->y = -z; - break; - case ALIGN_Y_Z: - outVec->z = x; - outVec->y = y; - outVec->x = -z; - break; - case ALIGN_X_Y: - outVec->x = x; - outVec->y = y; - outVec->z = z; - break; - }; - - } - //--------------------------------------------------------------------- - Terrain::Alignment Terrain::getAlignment() const - { - return mAlign; - } - //--------------------------------------------------------------------- - uint16 Terrain::getSize() const - { - return mSize; - } - //--------------------------------------------------------------------- - uint16 Terrain::getMaxBatchSize() const - { - return mMaxBatchSize; - } - //--------------------------------------------------------------------- - uint16 Terrain::getMinBatchSize() const - { - return mMinBatchSize; - } - //--------------------------------------------------------------------- - Real Terrain::getWorldSize() const - { - return mWorldSize; - } - //--------------------------------------------------------------------- - Real Terrain::getLayerWorldSize(uint8 index) const - { - if (index < mLayers.size()) - { - return mLayers[index].worldSize; - } - else if (!mLayers.empty()) - { - return mLayers[0].worldSize; - } - else - { - return TerrainGlobalOptions::getSingleton().getDefaultLayerTextureWorldSize(); - } - } - //--------------------------------------------------------------------- - void Terrain::setLayerWorldSize(uint8 index, Real size) - { - if (index < mLayers.size()) - { - - if (index >= mLayerUVMultiplier.size()) - mLayerUVMultiplier.resize(index + 1); - - mLayers[index].worldSize = size; - mLayerUVMultiplier[index] = mWorldSize / size; - mMaterialParamsDirty = true; - mModified = true; - } - } - //--------------------------------------------------------------------- - Real Terrain::getLayerUVMultiplier(uint8 index) const - { - if (index < mLayerUVMultiplier.size()) - { - return mLayerUVMultiplier[index]; - } - else if (!mLayerUVMultiplier.empty()) - { - return mLayerUVMultiplier[0]; - } - else - { - // default to tile 100 times - return 100; - } - } - //--------------------------------------------------------------------- - void Terrain::deriveUVMultipliers() - { - mLayerUVMultiplier.resize(mLayers.size()); - for (size_t i = 0; i < mLayers.size(); ++i) - { - const LayerInstance& inst = mLayers[i]; - - mLayerUVMultiplier[i] = mWorldSize / inst.worldSize; - - } - } - //--------------------------------------------------------------------- - const String& Terrain::getLayerTextureName(uint8 layerIndex, uint8 samplerIndex) const - { - if (layerIndex < mLayers.size() && samplerIndex < mLayerDecl.samplers.size()) - { - return mLayers[layerIndex].textureNames[samplerIndex]; - } - else - { - return BLANKSTRING; - } - - } - //--------------------------------------------------------------------- - void Terrain::setLayerTextureName(uint8 layerIndex, uint8 samplerIndex, const String& textureName) - { - if (layerIndex < mLayers.size() && samplerIndex < mLayerDecl.samplers.size()) - { - if (mLayers[layerIndex].textureNames[samplerIndex] != textureName) - { - mLayers[layerIndex].textureNames[samplerIndex] = textureName; - mMaterialDirty = true; - mMaterialParamsDirty = true; - mModified = true; - } - } - } - //--------------------------------------------------------------------- - void Terrain::setPosition(const Vector3& pos) - { - if (pos != mPos) - { - mPos = pos; - mRootNode->setPosition(pos); - updateBaseScale(); - mModified = true; - } - } - //--------------------------------------------------------------------- - SceneNode* Terrain::_getRootSceneNode() const - { - return mRootNode; - } - //--------------------------------------------------------------------- - void Terrain::updateBaseScale() - { - // centre the terrain on local origin - mBase = -mWorldSize * 0.5; - // scale determines what 1 unit on the grid becomes in world space - mScale = mWorldSize / (Real)(mSize-1); - } - //--------------------------------------------------------------------- - void Terrain::dirty() - { - Rect rect; - rect.top = 0; rect.bottom = mSize; - rect.left = 0; rect.right = mSize; - dirtyRect(rect); - } - //--------------------------------------------------------------------- - void Terrain::dirtyRect(const Rect& rect) - { - mDirtyGeometryRect.merge(rect); - mDirtyGeometryRectForNeighbours.merge(rect); - mDirtyDerivedDataRect.merge(rect); - mCompositeMapDirtyRect.merge(rect); - - mModified = true; - mHeightDataModified = true; - - } - //--------------------------------------------------------------------- - void Terrain::_dirtyCompositeMapRect(const Rect& rect) - { - mCompositeMapDirtyRect.merge(rect); - mModified = true; - } - //--------------------------------------------------------------------- - void Terrain::dirtyLightmapRect(const Rect& rect) - { - mDirtyDerivedDataRect.merge(rect); - - mModified = true; - - } - //--------------------------------------------------------------------- - void Terrain::dirtyLightmap() - { - Rect rect; - rect.top = 0; rect.bottom = mSize; - rect.left = 0; rect.right = mSize; - dirtyLightmapRect(rect); - } - //--------------------------------------------------------------------- - void Terrain::update(bool synchronous) - { - updateGeometry(); - updateDerivedData(synchronous); - } - //--------------------------------------------------------------------- - void Terrain::updateGeometry() - { - if (!mDirtyGeometryRect.isNull()) - { - mQuadTree->updateVertexData(true, false, mDirtyGeometryRect, false); - mDirtyGeometryRect.setNull(); - } - - // propagate changes - notifyNeighbours(); - } - //--------------------------------------------------------------------- - void Terrain::updateGeometryWithoutNotifyNeighbours() - { - if (!mDirtyGeometryRect.isNull()) - { - mQuadTree->updateVertexData(true, false, mDirtyGeometryRect, false); - mDirtyGeometryRect.setNull(); - } - } - //--------------------------------------------------------------------- - void Terrain::updateDerivedData(bool synchronous, uint8 typeMask) - { - if (!mDirtyDerivedDataRect.isNull() || !mDirtyLightmapFromNeighboursRect.isNull()) - { - mModified = true; - if (mDerivedDataUpdateInProgress) - { - // Don't launch many updates, instead wait for the other one - // to finish and issue another afterwards. - mDerivedUpdatePendingMask |= typeMask; - } - else - { - updateDerivedDataImpl(mDirtyDerivedDataRect, mDirtyLightmapFromNeighboursRect, - synchronous, typeMask); - mDirtyDerivedDataRect.setNull(); - mDirtyLightmapFromNeighboursRect.setNull(); - } - } - else - { - // Usually the composite map is updated after the other background - // data is updated (no point doing it beforehand), but if there's - // nothing to update, then we'll do it right now. - updateCompositeMap(); - } - - - } - //--------------------------------------------------------------------- - void Terrain::updateDerivedDataImpl(const Rect& rect, const Rect& lightmapExtraRect, - bool synchronous, uint8 typeMask) - { - mDerivedDataUpdateInProgress = true; - mDerivedUpdatePendingMask = 0; - - DerivedDataRequest req; - req.terrain = this; - req.dirtyRect = rect; - req.lightmapExtraDirtyRect = lightmapExtraRect; - req.typeMask = typeMask; - if (!mNormalMapRequired) - req.typeMask = req.typeMask & ~DERIVED_DATA_NORMALS; - if (!mLightMapRequired) - req.typeMask = req.typeMask & ~DERIVED_DATA_LIGHTMAP; - - Root::getSingleton().getWorkQueue()->addRequest( - mWorkQueueChannel, WORKQUEUE_DERIVED_DATA_REQUEST, - Any(req), 0, synchronous); - - } - //--------------------------------------------------------------------- - void Terrain::waitForDerivedProcesses() - { - while (mDerivedDataUpdateInProgress || mGenerateMaterialInProgress || mPrepareInProgress) - { - // we need to wait for this to finish - OGRE_THREAD_SLEEP(50); - Root::getSingleton().getWorkQueue()->processResponses(); - } - - } - //--------------------------------------------------------------------- - void Terrain::freeCPUResources() - { - OGRE_FREE(mHeightData, MEMCATEGORY_GEOMETRY); - mHeightData = 0; - - OGRE_FREE(mDeltaData, MEMCATEGORY_GEOMETRY); - mDeltaData = 0; - - OGRE_DELETE mQuadTree; - mQuadTree = 0; - - if (mCpuTerrainNormalMap) - { - OGRE_FREE(mCpuTerrainNormalMap->data, MEMCATEGORY_GENERAL); - OGRE_DELETE mCpuTerrainNormalMap; - mCpuTerrainNormalMap = 0; - } - - OGRE_FREE(mCpuColourMapStorage, MEMCATEGORY_GENERAL); - mCpuColourMapStorage = 0; - - OGRE_FREE(mCpuLightmapStorage, MEMCATEGORY_GENERAL); - mCpuLightmapStorage = 0; - - OGRE_FREE(mCpuCompositeMapStorage, MEMCATEGORY_GENERAL); - mCpuCompositeMapStorage = 0; - } - //--------------------------------------------------------------------- - void Terrain::freeGPUResources() - { - // remove textures - TextureManager* tmgr = TextureManager::getSingletonPtr(); - if (tmgr) - { - for (TexturePtrList::iterator i = mBlendTextureList.begin(); i != mBlendTextureList.end(); ++i) - { - tmgr->remove((*i)->getHandle()); - } - mBlendTextureList.clear(); + stream.readChunkEnd(TERRAIN_CHUNK_ID); - if (!mTerrainNormalMap.isNull()) - { - tmgr->remove(mTerrainNormalMap->getHandle()); - mTerrainNormalMap.setNull(); - } + mModified = false; + mHeightDataModified = false; - if (!mColourMap.isNull()) - { - tmgr->remove(mColourMap->getHandle()); - mColourMap.setNull(); - } + mPrepareInProgress = false; - if (!mLightmap.isNull()) + return true; + } + //--------------------------------------------------------------------- + bool Terrain::prepare(const ImportData& importData) + { + mPrepareInProgress = true; + freeTemporaryResources(); + freeLodData(); + freeCPUResources(); + mLodManager = OGRE_NEW TerrainLodManager( this ); + + copyGlobalOptions(); + + // validate + if (!(Bitwise::isPO2(importData.terrainSize - 1) && Bitwise::isPO2(importData.minBatchSize - 1) + && Bitwise::isPO2(importData.maxBatchSize - 1))) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "terrainSize, minBatchSize and maxBatchSize must all be 2^n + 1", + "Terrain::prepare"); + } + + if (importData.minBatchSize > importData.maxBatchSize) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "minBatchSize must be less than or equal to maxBatchSize", + "Terrain::prepare"); + } + + if (importData.maxBatchSize > TERRAIN_MAX_BATCH_SIZE) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "maxBatchSize must be no larger than " + + StringConverter::toString(TERRAIN_MAX_BATCH_SIZE), + "Terrain::prepare"); + } + + mAlign = importData.terrainAlign; + mSize = importData.terrainSize; + mWorldSize = importData.worldSize; + mLayerDecl = importData.layerDeclaration; + checkDeclaration(); + mLayers = importData.layerList; + checkLayers(false); + deriveUVMultipliers(); + mMaxBatchSize = importData.maxBatchSize; + mMinBatchSize = importData.minBatchSize; + setPosition(importData.pos); + + updateBaseScale(); + determineLodLevels(); + + size_t numVertices = mSize * mSize; + + mHeightData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GEOMETRY); + + if (importData.inputFloat) + { + if (Math::RealEqual(importData.inputBias, 0.0) && Math::RealEqual(importData.inputScale, 1.0)) { - tmgr->remove(mLightmap->getHandle()); - mLightmap.setNull(); + // straight copy + memcpy(mHeightData, importData.inputFloat, sizeof(float) * numVertices); } - - if (!mCompositeMap.isNull()) + else { - tmgr->remove(mCompositeMap->getHandle()); - mCompositeMap.setNull(); + // scale & bias + float* src = importData.inputFloat; + float* dst = mHeightData; + for (size_t i = 0; i < numVertices; ++i) + *dst++ = (*src++ * importData.inputScale) + importData.inputBias; } - } - - if (!mMaterial.isNull()) - { - MaterialManager::getSingleton().remove(mMaterial->getHandle()); - mMaterial.setNull(); - } - if (!mCompositeMapMaterial.isNull()) - { - MaterialManager::getSingleton().remove(mCompositeMapMaterial->getHandle()); - mCompositeMapMaterial.setNull(); - } - - - } - //--------------------------------------------------------------------- - void Terrain::freeLodData() - { - if(mLodManager) - { - OGRE_DELETE mLodManager; - mLodManager = 0; - } - } - //--------------------------------------------------------------------- - Rect Terrain::calculateHeightDeltas(const Rect& rect) - { - Rect clampedRect(rect); - clampedRect.left = std::max(0L, clampedRect.left); - clampedRect.top = std::max(0L, clampedRect.top); - clampedRect.right = std::min((long)mSize, clampedRect.right); - clampedRect.bottom = std::min((long)mSize, clampedRect.bottom); - - Rect finalRect(clampedRect); - - mQuadTree->preDeltaCalculation(clampedRect); - - /// Iterate over target levels, - for (int targetLevel = 1; targetLevel < mNumLodLevels; ++targetLevel) - { - int sourceLevel = targetLevel - 1; - int step = 1 << targetLevel; - // The step of the next higher LOD -// int higherstep = step >> 1; - - // need to widen the dirty rectangle since change will affect surrounding - // vertices at lower LOD - Rect widenedRect(rect); - widenedRect.left = std::max(0L, widenedRect.left - step); - widenedRect.top = std::max(0L, widenedRect.top - step); - widenedRect.right = std::min((long)mSize, widenedRect.right + step); - widenedRect.bottom = std::min((long)mSize, widenedRect.bottom + step); - - // keep a merge of the widest - finalRect.merge(widenedRect); - - - // now round the rectangle at this level so that it starts & ends on - // the step boundaries - Rect lodRect(widenedRect); - lodRect.left -= lodRect.left % step; - lodRect.top -= lodRect.top % step; - if (lodRect.right % step) - lodRect.right += step - (lodRect.right % step); - if (lodRect.bottom % step) - lodRect.bottom += step - (lodRect.bottom % step); - - for (long j = lodRect.top; j < lodRect.bottom - step; j += step ) - { - for (long i = lodRect.left; i < lodRect.right - step; i += step ) - { - // Form planes relating to the lower detail tris to be produced - // For even tri strip rows, they are this shape: - // 2---3 - // | / | - // 0---1 - // For odd tri strip rows, they are this shape: - // 2---3 - // | \ | - // 0---1 - - Vector3 v0, v1, v2, v3; - getPointAlign(i, j, ALIGN_X_Y, &v0); - getPointAlign(i + step, j, ALIGN_X_Y, &v1); - getPointAlign(i, j + step, ALIGN_X_Y, &v2); - getPointAlign(i + step, j + step, ALIGN_X_Y, &v3); - - Plane t1, t2; - bool backwardTri = false; - // Odd or even in terms of target level - if ((j / step) % 2 == 0) - { - t1.redefine(v0, v1, v3); - t2.redefine(v0, v3, v2); - } - else - { - t1.redefine(v1, v3, v2); - t2.redefine(v0, v1, v2); - backwardTri = true; - } - - // include the bottommost row of vertices if this is the last row - int yubound = (j == (mSize - step)? step : step - 1); - for ( int y = 0; y <= yubound; y++ ) - { - // include the rightmost col of vertices if this is the last col - int xubound = (i == (mSize - step)? step : step - 1); - for ( int x = 0; x <= xubound; x++ ) - { - int fulldetailx = static_cast(i + x); - int fulldetaily = static_cast(j + y); - if ( fulldetailx % step == 0 && - fulldetaily % step == 0 ) - { - // Skip, this one is a vertex at this level - continue; - } - - Real ypct = (Real)y / (Real)step; - Real xpct = (Real)x / (Real)step; - - //interpolated height - Vector3 actualPos; - getPointAlign(fulldetailx, fulldetaily, ALIGN_X_Y, &actualPos); - Real interp_h; - // Determine which tri we're on - if ((xpct > ypct && !backwardTri) || - (xpct > (1-ypct) && backwardTri)) - { - // Solve for x/z - interp_h = - (-t1.normal.x * actualPos.x - - t1.normal.y * actualPos.y - - t1.d) / t1.normal.z; - } - else - { - // Second tri - interp_h = - (-t2.normal.x * actualPos.x - - t2.normal.y * actualPos.y - - t2.d) / t2.normal.z; - } - - Real actual_h = actualPos.z; - Real delta = interp_h - actual_h; - - // max(delta) is the worst case scenario at this LOD - // compared to the original heightmap - - // tell the quadtree about this - mQuadTree->notifyDelta(fulldetailx, fulldetaily, sourceLevel, delta); - - - // If this vertex is being removed at this LOD, - // then save the height difference since that's the move - // it will need to make. Vertices to be removed at this LOD - // are halfway between the steps, but exclude those that - // would have been eliminated at earlier levels - int halfStep = step / 2; - if ( - ((fulldetailx % step) == halfStep && (fulldetaily % halfStep) == 0) || - ((fulldetaily % step) == halfStep && (fulldetailx % halfStep) == 0)) - { - // Save height difference - mDeltaData[fulldetailx + (fulldetaily * mSize)] = delta; - } - - } - - } - } // i - } // j - - } // targetLevel - - mQuadTree->postDeltaCalculation(clampedRect); - - return finalRect; - - } - //--------------------------------------------------------------------- - void Terrain::finaliseHeightDeltas(const Rect& rect, bool cpuData) - { - - Rect clampedRect(rect); - clampedRect.left = std::max(0L, clampedRect.left); - clampedRect.top = std::max(0L, clampedRect.top); - clampedRect.right = std::min((long)mSize, clampedRect.right); - clampedRect.bottom = std::min((long)mSize, clampedRect.bottom); - - // min/max information - mQuadTree->finaliseDeltaValues(clampedRect); - // delta vertex data - mQuadTree->updateVertexData(false, true, clampedRect, cpuData); - - } - - //--------------------------------------------------------------------- - uint16 Terrain::getResolutionAtLod(uint16 lodLevel) const - { - return ((mSize - 1) >> lodLevel) + 1; - } - //--------------------------------------------------------------------- - uint Terrain::getGeoDataSizeAtLod(uint16 lodLevel) const - { - uint size = getResolutionAtLod(lodLevel); - uint prevSize = (lodLevelgetMilliseconds(); - unsigned long elapsedMillis = currMillis - mLastMillis; - if (mCompositeMapUpdateCountdown > 0 && elapsedMillis) - { - if (elapsedMillis > mCompositeMapUpdateCountdown) - mCompositeMapUpdateCountdown = 0; - else - mCompositeMapUpdateCountdown -= elapsedMillis; - - if (!mCompositeMapUpdateCountdown) - updateCompositeMap(); - } - mLastMillis = currMillis; - // only calculate LOD once per LOD camera, per frame, per viewport height - const Camera* lodCamera = v->getCamera()->getLodCamera(); - unsigned long frameNum = Root::getSingleton().getNextFrameNumber(); - int vpHeight = v->getActualHeight(); - if (mLastLODCamera != lodCamera || frameNum != mLastLODFrame - || mLastViewportHeight != vpHeight) - { - mLastLODCamera = lodCamera; - mLastLODFrame = frameNum; - mLastViewportHeight = vpHeight; - calculateCurrentLod(v); - } - } - //--------------------------------------------------------------------- - void Terrain::sceneManagerDestroyed(SceneManager* source) - { - unload(); - unprepare(); - if (source == mSceneMgr) - mSceneMgr = 0; - } - //--------------------------------------------------------------------- - void Terrain::calculateCurrentLod(Viewport* vp) - { - if (mQuadTree) - { - // calculate error terms - const Camera* cam = vp->getCamera()->getLodCamera(); - - // W. de Boer 2000 calculation - // A = vp_near / abs(vp_top) - // A = 1 / tan(fovy*0.5) (== 1 for fovy=45*2) - Real A = 1.0f / Math::Tan(cam->getFOVy() * 0.5f); - // T = 2 * maxPixelError / vertRes - Real maxPixelError = TerrainGlobalOptions::getSingleton().getMaxPixelError() * cam->_getLodBiasInverse(); - Viewport* lodVp = cam->getViewport(); - Real T = 2.0f * maxPixelError / (Real)lodVp->getActualHeight(); - - // CFactor = A / T - Real cFactor = A / T; - - mQuadTree->calculateCurrentLod(cam, cFactor); - } - } - //--------------------------------------------------------------------- - std::pair Terrain::rayIntersects(const Ray& ray, - bool cascadeToNeighbours /* = false */, Real distanceLimit /* = 0 */) - { - typedef std::pair Result; - // first step: convert the ray to a local vertex space - // we assume terrain to be in the x-z plane, with the [0,0] vertex - // at origin and a plane distance of 1 between vertices. - // This makes calculations easier. - Vector3 rayOrigin = ray.getOrigin() - getPosition(); - Vector3 rayDirection = ray.getDirection(); - // change alignment - Vector3 tmp; - switch (getAlignment()) - { - case ALIGN_X_Y: - std::swap(rayOrigin.y, rayOrigin.z); - std::swap(rayDirection.y, rayDirection.z); - break; - case ALIGN_Y_Z: - // x = z, z = y, y = -x - tmp.x = rayOrigin.z; - tmp.z = rayOrigin.y; - tmp.y = -rayOrigin.x; - rayOrigin = tmp; - tmp.x = rayDirection.z; - tmp.z = rayDirection.y; - tmp.y = -rayDirection.x; - rayDirection = tmp; - break; - case ALIGN_X_Z: - // already in X/Z but values increase in -Z - rayOrigin.z = -rayOrigin.z; - rayDirection.z = -rayDirection.z; - break; - } - // readjust coordinate origin - rayOrigin.x += mWorldSize/2; - rayOrigin.z += mWorldSize/2; - // scale down to vertex level - rayOrigin.x /= mScale; - rayOrigin.z /= mScale; - rayDirection.x /= mScale; - rayDirection.z /= mScale; - rayDirection.normalise(); - Ray localRay (rayOrigin, rayDirection); - - // test if the ray actually hits the terrain's bounds - Real maxHeight = getMaxHeight(); - Real minHeight = getMinHeight(); - - AxisAlignedBox aabb (Vector3(0, minHeight, 0), Vector3(mSize, maxHeight, mSize)); - std::pair aabbTest = localRay.intersects(aabb); - if (!aabbTest.first) - { - if (cascadeToNeighbours) - { - OGRE_LOCK_RW_MUTEX_READ(mNeighbourMutex); - Terrain* neighbour = raySelectNeighbour(ray, distanceLimit); - if (neighbour) - return neighbour->rayIntersects(ray, cascadeToNeighbours, distanceLimit); - } - return Result(false, Vector3()); - } - // get intersection point and move inside - Vector3 cur = localRay.getPoint(aabbTest.second); - - // now check every quad the ray touches - int quadX = std::min(std::max(static_cast(cur.x), 0), (int)mSize-2); - int quadZ = std::min(std::max(static_cast(cur.z), 0), (int)mSize-2); - int flipX = (rayDirection.x < 0 ? 0 : 1); - int flipZ = (rayDirection.z < 0 ? 0 : 1); - int xDir = (rayDirection.x < 0 ? -1 : 1); - int zDir = (rayDirection.z < 0 ? -1 : 1); - - Result result(true, Vector3::ZERO); - Real dummyHighValue = (Real)mSize * 10000.0f; - - - while (cur.y >= (minHeight - 1e-3) && cur.y <= (maxHeight + 1e-3)) - { - if (quadX < 0 || quadX >= (int)mSize-1 || quadZ < 0 || quadZ >= (int)mSize-1) - break; - - result = checkQuadIntersection(quadX, quadZ, localRay); - if (result.first) - break; - - // determine next quad to test - Real xDist = Math::RealEqual(rayDirection.x, 0.0) ? dummyHighValue : - (quadX - cur.x + flipX) / rayDirection.x; - Real zDist = Math::RealEqual(rayDirection.z, 0.0) ? dummyHighValue : - (quadZ - cur.z + flipZ) / rayDirection.z; - if (xDist < zDist) - { - quadX += xDir; - cur += rayDirection * xDist; - } - else - { - quadZ += zDir; - cur += rayDirection * zDist; - } - - } - - if (result.first) - { - // transform the point of intersection back to world space - result.second.x *= mScale; - result.second.z *= mScale; - result.second.x -= mWorldSize/2; - result.second.z -= mWorldSize/2; - switch (getAlignment()) - { - case ALIGN_X_Y: - std::swap(result.second.y, result.second.z); - break; - case ALIGN_Y_Z: - // z = x, y = z, x = -y - tmp.x = -rayOrigin.y; - tmp.y = rayOrigin.z; - tmp.z = rayOrigin.x; - rayOrigin = tmp; - break; - case ALIGN_X_Z: - result.second.z = -result.second.z; - break; - } - result.second += getPosition(); - } - else if (cascadeToNeighbours) - { - Terrain* neighbour = raySelectNeighbour(ray, distanceLimit); - if (neighbour) - result = neighbour->rayIntersects(ray, cascadeToNeighbours, distanceLimit); - } - return result; - } - //--------------------------------------------------------------------- - std::pair Terrain::checkQuadIntersection(int x, int z, const Ray& ray) - { - // build the two planes belonging to the quad's triangles - Vector3 v1 ((Real)x, *getHeightData(x,z), (Real)z); - Vector3 v2 ((Real)x+1, *getHeightData(x+1,z), (Real)z); - Vector3 v3 ((Real)x, *getHeightData(x,z+1), (Real)z+1); - Vector3 v4 ((Real)x+1, *getHeightData(x+1,z+1), (Real)z+1); - - Plane p1, p2; - bool oddRow = false; - if (z % 2) - { - /* odd - 3---4 - | \ | - 1---2 - */ - p1.redefine(v2, v4, v3); - p2.redefine(v1, v2, v3); - oddRow = true; - } - else - { - /* even - 3---4 - | / | - 1---2 - */ - p1.redefine(v1, v2, v4); - p2.redefine(v1, v4, v3); - } - - // Test for intersection with the two planes. - // Then test that the intersection points are actually - // still inside the triangle (with a small error margin) - // Also check which triangle it is in - std::pair planeInt = ray.intersects(p1); - if (planeInt.first) - { - Vector3 where = ray.getPoint(planeInt.second); - Vector3 rel = where - v1; - if (rel.x >= -0.01 && rel.x <= 1.01 && rel.z >= -0.01 && rel.z <= 1.01 // quad bounds - && ((rel.x >= rel.z && !oddRow) || (rel.x >= (1 - rel.z) && oddRow))) // triangle bounds - return std::pair(true, where); - } - planeInt = ray.intersects(p2); - if (planeInt.first) - { - Vector3 where = ray.getPoint(planeInt.second); - Vector3 rel = where - v1; - if (rel.x >= -0.01 && rel.x <= 1.01 && rel.z >= -0.01 && rel.z <= 1.01 // quad bounds - && ((rel.x <= rel.z && !oddRow) || (rel.x <= (1 - rel.z) && oddRow))) // triangle bounds - return std::pair(true, where); - } - - return std::pair(false, Vector3()); - } - //--------------------------------------------------------------------- - const MaterialPtr& Terrain::getMaterial() const - { - if (mMaterial.isNull() || - mMaterialGenerator->getChangeCount() != mMaterialGenerationCount || - mMaterialDirty) - { - mMaterial = mMaterialGenerator->generate(this); - mMaterial->load(); - if (mCompositeMapRequired) - { - mCompositeMapMaterial = mMaterialGenerator->generateForCompositeMap(this); - mCompositeMapMaterial->load(); - } - mMaterialGenerationCount = mMaterialGenerator->getChangeCount(); - mMaterialDirty = false; - } - if (mMaterialParamsDirty) - { - mMaterialGenerator->updateParams(mMaterial, this); - if(mCompositeMapRequired) - mMaterialGenerator->updateParamsForCompositeMap(mCompositeMapMaterial, this); - mMaterialParamsDirty = false; - - } - - return mMaterial; - } - //--------------------------------------------------------------------- - const MaterialPtr& Terrain::getCompositeMapMaterial() const - { - // both materials updated together since they change at the same time - getMaterial(); - return mCompositeMapMaterial; - } - //--------------------------------------------------------------------- - void Terrain::checkLayers(bool includeGPUResources) - { - for (LayerInstanceList::iterator it = mLayers.begin(); it != mLayers.end(); ++it) - { - LayerInstance& layer = *it; - // If we're missing sampler entries compared to the declaration, initialise them - for (size_t i = layer.textureNames.size(); i < mLayerDecl.samplers.size(); ++i) - { - layer.textureNames.push_back(BLANKSTRING); - } - - // if we have too many layers for the declaration, trim them - if (layer.textureNames.size() > mLayerDecl.samplers.size()) - { - layer.textureNames.resize(mLayerDecl.samplers.size()); - } - } - - if (includeGPUResources) - { - createGPUBlendTextures(); - createLayerBlendMaps(); - } - - } - //--------------------------------------------------------------------- - void Terrain::checkDeclaration() - { - if (mMaterialGenerator.isNull()) - { - mMaterialGenerator = TerrainGlobalOptions::getSingleton().getDefaultMaterialGenerator(); - } - - if (mLayerDecl.elements.empty()) - { - // default the declaration - mLayerDecl = mMaterialGenerator->getLayerDeclaration(); - } - - } - //--------------------------------------------------------------------- - void Terrain::replaceLayer(uint8 index, bool keepBlends, Real worldSize, const StringVector* textureNames) - { - if (getLayerCount() > 0) + } + else if (importData.inputImage) { - if (index >= getLayerCount()) - index = getLayerCount() - 1; + Image* img = importData.inputImage; - LayerInstanceList::iterator i = mLayers.begin(); - std::advance(i, index); - - if (textureNames) - { - (*i).textureNames = *textureNames; - } + if (img->getWidth() != mSize || img->getHeight() != mSize) + img->resize(mSize, mSize); - // use utility method to update UV scaling - setLayerWorldSize(index, worldSize); + // convert image data to floats + // Do this on a row-by-row basis, because we describe the terrain in + // a bottom-up fashion (ie ascending world coords), while Image is top-down + unsigned char* pSrcBase = img->getData(); + for (size_t i = 0; i < mSize; ++i) + { + size_t srcy = mSize - i - 1; + unsigned char* pSrc = pSrcBase + srcy * img->getRowSpan(); + float* pDst = mHeightData + i * mSize; + PixelUtil::bulkPixelConversion(pSrc, img->getFormat(), + pDst, PF_FLOAT32_R, mSize); + } - // Delete the blend map if its not the base - if ( !keepBlends && index > 0 ) + if (!Math::RealEqual(importData.inputBias, 0.0) || !Math::RealEqual(importData.inputScale, 1.0)) { - if (mLayerBlendMapList[index-1]) + float* pAdj = mHeightData; + for (size_t i = 0; i < numVertices; ++i) { - delete mLayerBlendMapList[index-1]; - mLayerBlendMapList[index-1] = 0; + *pAdj = (*pAdj * importData.inputScale) + importData.inputBias; + ++pAdj; } - - // Reset the layer to black - std::pair layerPair = getLayerBlendTextureIndex(index); - clearGPUBlendChannel( layerPair.first, layerPair.second ); } - mMaterialDirty = true; - mMaterialParamsDirty = true; - mModified = true; } - } - //--------------------------------------------------------------------- - void Terrain::addLayer(Real worldSize, const StringVector* textureNames) - { - addLayer(getLayerCount(), worldSize, textureNames); - } - //--------------------------------------------------------------------- - void Terrain::addLayer(uint8 index, Real worldSize, const StringVector* textureNames) - { - if (!worldSize) - worldSize = TerrainGlobalOptions::getSingleton().getDefaultLayerTextureWorldSize(); - - uint8 blendIndex = std::max(index-1,0); - if (index >= getLayerCount()) - { - mLayers.push_back(LayerInstance()); - index = getLayerCount() - 1; - } - else - { - LayerInstanceList::iterator i = mLayers.begin(); - std::advance(i, index); - mLayers.insert(i, LayerInstance()); - - RealVector::iterator uvi = mLayerUVMultiplier.begin(); - std::advance(uvi, index); - mLayerUVMultiplier.insert(uvi, 0.0f); - - TerrainLayerBlendMapList::iterator bi = mLayerBlendMapList.begin(); - std::advance(bi, blendIndex); - mLayerBlendMapList.insert(bi, static_cast(0)); - } - if (textureNames) - { - LayerInstance& inst = mLayers[index]; - inst.textureNames = *textureNames; - } - // use utility method to update UV scaling - setLayerWorldSize(index, worldSize); - checkLayers(true); - - // Is this an insert into the middle of the layer list? - if (index < getLayerCount() - 1) + else { - // Shift all GPU texture channels up one - shiftUpGPUBlendChannels(blendIndex); + // start with flat terrain + if (importData.constantHeight == 0) + memset(mHeightData, 0, sizeof(float) * mSize * mSize); + else + { + float* pFloat = mHeightData; + for (long i = 0 ; i < mSize * mSize; ++i) + *pFloat++ = importData.constantHeight; - // All blend maps above this layer index will need to be recreated since their buffers/channels have changed - deleteBlendMaps(index); + } } - mMaterialDirty = true; - mMaterialParamsDirty = true; - mModified = true; + mDeltaData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GEOMETRY); + memset(mDeltaData, 0, sizeof(float) * numVertices); - } - //--------------------------------------------------------------------- - void Terrain::removeLayer(uint8 index) - { - if (index < mLayers.size()) - { + mQuadTree = OGRE_NEW TerrainQuadTreeNode(this, 0, 0, 0, mSize, mNumLodLevels - 1, 0, 0); + mQuadTree->prepare(); + + // calculate entire terrain + Rect rect; + rect.top = 0; rect.bottom = mSize; + rect.left = 0; rect.right = mSize; + calculateHeightDeltas(rect); + finaliseHeightDeltas(rect, true); + + distributeVertexData(); + + // Imported data is treated as modified because it's not saved + mModified = true; + mHeightDataModified = true; + + mPrepareInProgress = false; + + return true; + + } + //--------------------------------------------------------------------- + void Terrain::copyGlobalOptions() + { + TerrainGlobalOptions& opts = TerrainGlobalOptions::getSingleton(); + mSkirtSize = opts.getSkirtSize(); + mRenderQueueGroup = opts.getRenderQueueGroup(); + mVisibilityFlags = opts.getVisibilityFlags(); + mQueryFlags = opts.getQueryFlags(); + mLayerBlendMapSize = opts.getLayerBlendMapSize(); + mLayerBlendMapSizeActual = mLayerBlendMapSize; // for now, until we check + mLightmapSize = opts.getLightMapSize(); + mLightmapSizeActual = mLightmapSize; // for now, until we check + mCompositeMapSize = opts.getCompositeMapSize(); + mCompositeMapSizeActual = mCompositeMapSize; // for now, until we check + + } + //--------------------------------------------------------------------- + void Terrain::determineLodLevels() + { + /* On a leaf-node basis, LOD can vary from maxBatch to minBatch in + number of vertices. After that, nodes will be gathered into parent + nodes with the same number of vertices, but they are combined with + 3 of their siblings. In practice, the number of LOD levels overall + is: + LODlevels = log2(size - 1) - log2(minBatch - 1) + 1 + TreeDepth = log2((size - 1) / (maxBatch - 1)) + 1 + + .. it's just that at the max LOD, the terrain is divided into + (size - 1) / (maxBatch - 1) tiles each of maxBatch vertices, and + at the lowest LOD the terrain is made up of one single tile of + minBatch vertices. + + Example: size = 257, minBatch = 17, maxBatch = 33 + + LODlevels = log2(257 - 1) - log2(17 - 1) + 1 = 8 - 4 + 1 = 5 + TreeDepth = log2((size - 1) / (maxBatch - 1)) + 1 = 4 + + LOD list - this assumes everything changes at once, which rarely happens of course + in fact except where groupings must occur, tiles can change independently + LOD 0: 257 vertices, 8 x 33 vertex tiles (tree depth 3) + LOD 1: 129 vertices, 8 x 17 vertex tiles (tree depth 3) + LOD 2: 65 vertices, 4 x 17 vertex tiles (tree depth 2) + LOD 3: 33 vertices, 2 x 17 vertex tiles (tree depth 1) + LOD 4: 17 vertices, 1 x 17 vertex tiles (tree depth 0) + + Notice how we only have 2 sizes of index buffer to be concerned about, + 17 vertices (per side) or 33. This makes buffer re-use much easier while + still giving the full range of LODs. + */ + mNumLodLevelsPerLeafNode = (uint16) (Math::Log2(mMaxBatchSize - 1.0f) - Math::Log2(mMinBatchSize - 1.0f) + 1.0f); + mNumLodLevels = (uint16) (Math::Log2(mSize - 1.0f) - Math::Log2(mMinBatchSize - 1.0f) + 1.0f); + //mTreeDepth = Math::Log2(mMaxBatchSize - 1) - Math::Log2(mMinBatchSize - 1) + 2; + mTreeDepth = mNumLodLevels - mNumLodLevelsPerLeafNode + 1; + + LogManager::getSingleton().stream() << "Terrain created; size=" << mSize + << " minBatch=" << mMinBatchSize << " maxBatch=" << mMaxBatchSize + << " treeDepth=" << mTreeDepth << " lodLevels=" << mNumLodLevels + << " leafLods=" << mNumLodLevelsPerLeafNode; + } + //--------------------------------------------------------------------- + void Terrain::distributeVertexData() + { + /* Now we need to figure out how to distribute vertex data. We want to + use 16-bit indexes for compatibility, which means that the maximum patch + size that we can address (even sparsely for lower LODs) is 129x129 + (the next one up, 257x257 is too big). + + So we need to split the vertex data into chunks of 129. The number of + primary tiles this creates also indicates the point above which in + the node tree that we can no longer merge tiles at lower LODs without + using different vertex data. For example, using the 257x257 input example + above, the vertex data would have to be split in 2 (in each dimension) + in order to fit within the 129x129 range. This data could be shared by + all tree depths from 1 onwards, it's just that LODs 3-1 would sample + the 129x129 data sparsely. LOD 0 would sample all of the vertices. + + LOD 4 however, the lowest LOD, could not work with the same vertex data + because it needs to cover the entire terrain. There are 2 choices here: + create another set of vertex data at 17x17 which is only used by LOD 4, + or make LOD 4 occur at tree depth 1 instead (ie still split up, and + rendered as 2x9 along each edge instead. + + Since rendering very small batches is not desirable, and the vertex counts + are inherently not going to be large, creating a separate vertex set is + preferable. This will also be more efficient on the vertex cache with + distant terrains. + + We probably need a larger example, because in this case only 1 level (LOD 0) + needs to use this separate vertex data. Higher detail terrains will need + it for multiple levels, here's a 2049x2049 example with 65 / 33 batch settings: + + LODlevels = log2(2049 - 1) - log2(33 - 1) + 1 = 11 - 5 + 1 = 7 + TreeDepth = log2((2049 - 1) / (65 - 1)) + 1 = 6 + Number of vertex data splits at most detailed level: + (size - 1) / (TERRAIN_MAX_BATCH_SIZE - 1) = 2048 / 128 = 16 + + LOD 0: 2049 vertices, 32 x 65 vertex tiles (tree depth 5) vdata 0-15 [129x16] + LOD 1: 1025 vertices, 32 x 33 vertex tiles (tree depth 5) vdata 0-15 [129x16] + LOD 2: 513 vertices, 16 x 33 vertex tiles (tree depth 4) vdata 0-15 [129x16] + LOD 3: 257 vertices, 8 x 33 vertex tiles (tree depth 3) vdata 16-17 [129x2] + LOD 4: 129 vertices, 4 x 33 vertex tiles (tree depth 2) vdata 16-17 [129x2] + LOD 5: 65 vertices, 2 x 33 vertex tiles (tree depth 1) vdata 16-17 [129x2] + LOD 6: 33 vertices, 1 x 33 vertex tiles (tree depth 0) vdata 18 [33] + + All the vertex counts are to be squared, they are just along one edge. + So as you can see, we need to have 3 levels of vertex data to satisy this + (admittedly quite extreme) case, and a total of 19 sets of vertex data. + The full detail geometry, which is 16(x16) sets of 129(x129), used by + LODs 0-2. LOD 3 can't use this set because it needs to group across them, + because it has only 8 tiles, so we make another set which satisfies this + at a maximum of 129 vertices per vertex data section. In this case LOD + 3 needs 257(x257) total vertices so we still split into 2(x2) sets of 129. + This set is good up to and including LOD 5, but LOD 6 needs a single + contiguous set of vertices, so we make a 33x33 vertex set for it. + + In terms of vertex data stored, this means that while our primary data is: + 2049^2 = 4198401 vertices + our final stored vertex data is + (16 * 129)^2 + (2 * 129)^2 + 33^2 = 4327749 vertices + + That equals a 3% premium, but it's both necessary and worth it for the + reduction in batch count resulting from the grouping. In addition, at + LODs 3 and 6 (or rather tree depth 3 and 0) there is the opportunity + to free up the vertex data used by more detailed LODs, which is + important when dealing with large terrains. For example, if we + freed the (GPU) vertex data for LOD 0-2 in the medium distance, + we would save 98% of the memory overhead for this terrain. + + */ + + LogManager& logMgr = LogManager::getSingleton(); + logMgr.stream(LML_TRIVIAL) << "Terrain::distributeVertexData processing source " + "terrain size of " << mSize; + + uint16 depth = mTreeDepth; + uint16 prevdepth = depth; + uint16 currresolution = mSize; + uint16 bakedresolution = mSize; + uint16 targetSplits = (bakedresolution - 1) / (TERRAIN_MAX_BATCH_SIZE - 1); + while(depth-- && targetSplits) + { + uint splits = 1 << depth; + if (splits == targetSplits) + { + logMgr.stream(LML_TRIVIAL) << " Assigning vertex data, resolution=" + << bakedresolution << " startDepth=" << depth << " endDepth=" << prevdepth + << " splits=" << splits; + // vertex data goes at this level, at bakedresolution + // applies to all lower levels (except those with a closer vertex data) + // determine physical size (as opposed to resolution) + uint sz = ((bakedresolution-1) / splits) + 1; + mQuadTree->assignVertexData(depth, prevdepth, bakedresolution, sz); + + // next set to look for + bakedresolution = ((currresolution - 1) >> 1) + 1; + targetSplits = (bakedresolution - 1) / (TERRAIN_MAX_BATCH_SIZE - 1); + prevdepth = depth; + + } + + currresolution = ((currresolution - 1) >> 1) + 1; + + + } + + // Always assign vertex data to the top of the tree + if (prevdepth > 0) + { + mQuadTree->assignVertexData(0, 1, bakedresolution, bakedresolution); + logMgr.stream(LML_TRIVIAL) << " Assigning vertex data, resolution: " + << bakedresolution << " startDepth=0 endDepth=1 splits=1"; + + } + + logMgr.stream(LML_TRIVIAL) << "Terrain::distributeVertexData finished"; + + } + //--------------------------------------------------------------------- + void Terrain::load(const String& filename) + { + if (prepare(filename)) + load(); + else + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Error while preparing " + filename + ", see log for details", + __FUNCTION__); + } + //--------------------------------------------------------------------- + void Terrain::load(StreamSerialiser& stream) + { + if (prepare(stream)) + load(); + else + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Error while preparing from stream, see log for details", + __FUNCTION__); + } + //--------------------------------------------------------------------- + void Terrain::load(int lodLevel, bool synchronous) + { + if (mQuadTree) + mLodManager->updateToLodLevel(lodLevel,synchronous); + + if (mIsLoaded || mGenerateMaterialInProgress) + return; + + checkLayers(true); + createOrDestroyGPUColourMap(); + createOrDestroyGPUNormalMap(); + createOrDestroyGPULightmap(); + createOrDestroyGPUCompositeMap(); + + mMaterialGenerator->requestOptions(this); + + mGenerateMaterialInProgress = true; + GenerateMaterialRequest req; + req.terrain = this; + req.stage = GEN_MATERIAL; + req.startTime = synchronous ? 0 : Root::getSingletonPtr()->getTimer()->getMilliseconds() + TERRAIN_GENERATE_MATERIAL_INTERVAL_MS; + req.synchronous = synchronous; + + Root::getSingleton().getWorkQueue()->addRequest( + mWorkQueueChannel, WORKQUEUE_GENERATE_MATERIAL_REQUEST, + Any(req), 0, synchronous); + } + //--------------------------------------------------------------------- + void Terrain::unload() + { + if (!mIsLoaded) + return; + + if (mQuadTree) + mQuadTree->unload(); + + // free own buffers if used, but not custom + mDefaultGpuBufferAllocator.freeAllBuffers(); + + mIsLoaded = false; + mModified = false; + mHeightDataModified = false; + + } + //--------------------------------------------------------------------- + void Terrain::unprepare() + { + if (mQuadTree) + mQuadTree->unprepare(); + } + //--------------------------------------------------------------------- + float* Terrain::getHeightData() const + { + return mHeightData; + } + //--------------------------------------------------------------------- + float* Terrain::getHeightData(long x, long y) const + { + assert (x >= 0 && x < mSize && y >= 0 && y < mSize); + return &mHeightData[y * mSize + x]; + } + //--------------------------------------------------------------------- + float Terrain::getHeightAtPoint(long x, long y) const + { + // clamp + x = std::min(x, (long)mSize - 1L); + x = std::max(x, 0L); + y = std::min(y, (long)mSize - 1L); + y = std::max(y, 0L); + + int highestLod = mLodManager->getHighestLodPrepared(); + long skip = 1 << (highestLod != -1 ? highestLod : 0); + if (x % skip == 0 && y % skip == 0) + return *getHeightData(x, y); + + long x1 = std::min( (x/skip) * skip , (long)mSize - 1L ); + long x2 = std::min( ((x+skip) / skip) * skip, (long)mSize - 1L ); + long y1 = std::min( (y/skip) * skip , (long)mSize - 1L ); + long y2 = std::min( ((y+skip) / skip) * skip, (long)mSize - 1L ); + + float rx = (float(x % skip) / skip); + float ry = (float(y % skip) / skip); + + return *getHeightData(x1, y1) * (1.0f-rx) * (1.0f-ry) + + *getHeightData(x2, y1) * rx * (1.0f-ry) + + *getHeightData(x1, y2) * (1.0f-rx) * ry + + *getHeightData(x2, y2) * rx * ry; + } + //--------------------------------------------------------------------- + void Terrain::setHeightAtPoint(long x, long y, float h) + { + // force to load all data + load(0,true); + // clamp + x = std::min(x, (long)mSize - 1L); + x = std::max(x, 0L); + y = std::min(y, (long)mSize - 1L); + y = std::max(y, 0L); + + *getHeightData(x, y) = h; + Rect rect; + rect.left = x; + rect.right = x+1; + rect.top = y; + rect.bottom = y+1; + dirtyRect(rect); + } + //--------------------------------------------------------------------- + float Terrain::getHeightAtTerrainPosition(Real x, Real y) const + { + // get left / bottom points (rounded down) + Real factor = (Real)mSize - 1.0f; + Real invFactor = 1.0f / factor; + + long startX = static_cast(x * factor); + long startY = static_cast(y * factor); + long endX = startX + 1; + long endY = startY + 1; + + // now get points in terrain space (effectively rounding them to boundaries) + // note that we do not clamp! We need a valid plane + Real startXTS = startX * invFactor; + Real startYTS = startY * invFactor; + Real endXTS = endX * invFactor; + Real endYTS = endY * invFactor; + + // now clamp + endX = std::min(endX, (long)mSize-1); + endY = std::min(endY, (long)mSize-1); + + // get parametric from start coord to next point + Real xParam = (x - startXTS) / invFactor; + Real yParam = (y - startYTS) / invFactor; + + + /* For even / odd tri strip rows, triangles are this shape: + even odd + 3---2 3---2 + | / | | \ | + 0---1 0---1 + */ + + // Build all 4 positions in terrain space, using point-sampled height + Vector3 v0 (startXTS, startYTS, getHeightAtPoint(startX, startY)); + Vector3 v1 (endXTS, startYTS, getHeightAtPoint(endX, startY)); + Vector3 v2 (endXTS, endYTS, getHeightAtPoint(endX, endY)); + Vector3 v3 (startXTS, endYTS, getHeightAtPoint(startX, endY)); + // define this plane in terrain space + Plane plane; + if (startY % 2) + { + // odd row + bool secondTri = ((1.0 - yParam) > xParam); + if (secondTri) + plane.redefine(v0, v1, v3); + else + plane.redefine(v1, v2, v3); + } + else + { + // even row + bool secondTri = (yParam > xParam); + if (secondTri) + plane.redefine(v0, v2, v3); + else + plane.redefine(v0, v1, v2); + } + + // Solve plane equation for z + return (-plane.normal.x * x + -plane.normal.y * y + - plane.d) / plane.normal.z; + + + } + //--------------------------------------------------------------------- + float Terrain::getHeightAtWorldPosition(Real x, Real y, Real z) const + { + Vector3 terrPos; + getTerrainPosition(x, y, z, &terrPos); + return getHeightAtTerrainPosition(terrPos.x, terrPos.y); + } + //--------------------------------------------------------------------- + float Terrain::getHeightAtWorldPosition(const Vector3& pos) const + { + return getHeightAtWorldPosition(pos.x, pos.y, pos.z); + } + //--------------------------------------------------------------------- + const float* Terrain::getDeltaData() const + { + return mDeltaData; + } + //--------------------------------------------------------------------- + const float* Terrain::getDeltaData(long x, long y) const + { + assert (x >= 0 && x < mSize && y >= 0 && y < mSize); + return &mDeltaData[y * mSize + x]; + } + //--------------------------------------------------------------------- + Vector3 Terrain::convertPosition(Space inSpace, const Vector3& inPos, Space outSpace) const + { + Vector3 ret; + convertPosition(inSpace, inPos, outSpace, ret); + return ret; + } + //--------------------------------------------------------------------- + Vector3 Terrain::convertDirection(Space inSpace, const Vector3& inDir, Space outSpace) const + { + Vector3 ret; + convertDirection(inSpace, inDir, outSpace, ret); + return ret; + } + //--------------------------------------------------------------------- + void Terrain::convertPosition(Space inSpace, const Vector3& inPos, Space outSpace, Vector3& outPos) const + { + convertSpace(inSpace, inPos, outSpace, outPos, true); + } + //--------------------------------------------------------------------- + void Terrain::convertDirection(Space inSpace, const Vector3& inDir, Space outSpace, Vector3& outDir) const + { + convertSpace(inSpace, inDir, outSpace, outDir, false); + } + //--------------------------------------------------------------------- + void Terrain::convertSpace(Space inSpace, const Vector3& inVec, Space outSpace, Vector3& outVec, bool translation) const + { + Space currSpace = inSpace; + outVec = inVec; + while (currSpace != outSpace) + { + switch(currSpace) + { + case WORLD_SPACE: + // In all cases, transition to local space + if (translation) + outVec -= mPos; + currSpace = LOCAL_SPACE; + break; + case LOCAL_SPACE: + switch(outSpace) + { + case WORLD_SPACE: + if (translation) + outVec += mPos; + currSpace = WORLD_SPACE; + break; + case POINT_SPACE: + case TERRAIN_SPACE: + // go via terrain space + outVec = convertWorldToTerrainAxes(outVec); + if (translation) + { + outVec.x -= mBase; outVec.y -= mBase; + outVec.x /= (mSize - 1) * mScale; outVec.y /= (mSize - 1) * mScale; + } + currSpace = TERRAIN_SPACE; + break; + case LOCAL_SPACE: + default: + break; + }; + break; + case TERRAIN_SPACE: + switch(outSpace) + { + case WORLD_SPACE: + case LOCAL_SPACE: + // go via local space + if (translation) + { + outVec.x *= (mSize - 1) * mScale; outVec.y *= (mSize - 1) * mScale; + outVec.x += mBase; outVec.y += mBase; + } + outVec = convertTerrainToWorldAxes(outVec); + currSpace = LOCAL_SPACE; + break; + case POINT_SPACE: + if (translation) + { + outVec.x *= (mSize - 1); outVec.y *= (mSize - 1); + // rounding up/down + // this is why POINT_SPACE is the last on the list, because it loses data + outVec.x = static_cast(static_cast(outVec.x + 0.5)); + outVec.y = static_cast(static_cast(outVec.y + 0.5)); + } + currSpace = POINT_SPACE; + break; + case TERRAIN_SPACE: + default: + break; + }; + break; + case POINT_SPACE: + // always go via terrain space + if (translation) + outVec.x /= (mSize - 1); outVec.y /= (mSize - 1); + currSpace = TERRAIN_SPACE; + break; + + }; + } + + } + //--------------------------------------------------------------------- + void Terrain::convertWorldToTerrainAxes(Alignment align, const Vector3& worldVec, Vector3* terrainVec) + { + switch (align) + { + case ALIGN_X_Z: + terrainVec->z = worldVec.y; + terrainVec->x = worldVec.x; + terrainVec->y = -worldVec.z; + break; + case ALIGN_Y_Z: + terrainVec->z = worldVec.x; + terrainVec->x = -worldVec.z; + terrainVec->y = worldVec.y; + break; + case ALIGN_X_Y: + *terrainVec = worldVec; + break; + }; + + } + //--------------------------------------------------------------------- + void Terrain::convertTerrainToWorldAxes(Alignment align, const Vector3& terrainVec, Vector3* worldVec) + { + switch (align) + { + case ALIGN_X_Z: + worldVec->x = terrainVec.x; + worldVec->y = terrainVec.z; + worldVec->z = -terrainVec.y; + break; + case ALIGN_Y_Z: + worldVec->x = terrainVec.z; + worldVec->y = terrainVec.y; + worldVec->z = -terrainVec.x; + break; + case ALIGN_X_Y: + *worldVec = terrainVec; + break; + }; + + } + //--------------------------------------------------------------------- + Vector3 Terrain::convertWorldToTerrainAxes(const Vector3& inVec) const + { + Vector3 ret; + convertWorldToTerrainAxes(mAlign, inVec, &ret); + + return ret; + } + //--------------------------------------------------------------------- + Vector3 Terrain::convertTerrainToWorldAxes(const Vector3& inVec) const + { + Vector3 ret; + convertTerrainToWorldAxes(mAlign, inVec, &ret); + + return ret; + } + //--------------------------------------------------------------------- + void Terrain::getPoint(long x, long y, Vector3* outpos) const + { + getPointAlign(x, y, mAlign, outpos); + } + //--------------------------------------------------------------------- + void Terrain::getPoint(long x, long y, float height, Vector3* outpos) const + { + getPointAlign(x, y, height, mAlign, outpos); + } + //--------------------------------------------------------------------- + void Terrain::getPointAlign(long x, long y, Alignment align, Vector3* outpos) const + { + getPointAlign(x, y, *getHeightData(x, y), align, outpos); + } + //--------------------------------------------------------------------- + void Terrain::getPointAlign(long x, long y, float height, Alignment align, Vector3* outpos) const + { + switch(align) + { + case ALIGN_X_Z: + outpos->y = height; + outpos->x = x * mScale + mBase; + outpos->z = y * -mScale - mBase; + break; + case ALIGN_Y_Z: + outpos->x = height; + outpos->z = x * -mScale - mBase; + outpos->y = y * mScale + mBase; + break; + case ALIGN_X_Y: + outpos->z = height; + outpos->x = x * mScale + mBase; + outpos->y = y * mScale + mBase; + break; + }; + + } + //--------------------------------------------------------------------- + void Terrain::getPointTransform(Matrix4* outXform) const + { + *outXform = Matrix4::ZERO; + switch(mAlign) + { + case ALIGN_X_Z: + //outpos->y = height (z) + (*outXform)[1][2] = 1.0f; + //outpos->x = x * mScale + mBase; + (*outXform)[0][0] = mScale; + (*outXform)[0][3] = mBase; + //outpos->z = y * -mScale - mBase; + (*outXform)[2][1] = -mScale; + (*outXform)[2][3] = -mBase; + break; + case ALIGN_Y_Z: + //outpos->x = height; + (*outXform)[0][2] = 1.0f; + //outpos->z = x * -mScale - mBase; + (*outXform)[2][0] = -mScale; + (*outXform)[2][3] = -mBase; + //outpos->y = y * mScale + mBase; + (*outXform)[1][1] = mScale; + (*outXform)[1][3] = mBase; + break; + case ALIGN_X_Y: + //outpos->z = height; + (*outXform)[2][2] = 1.0f; // strictly already the case, but.. + //outpos->x = x * mScale + mBase; + (*outXform)[0][0] = mScale; + (*outXform)[0][3] = mBase; + //outpos->y = y * mScale + mBase; + (*outXform)[1][1] = mScale; + (*outXform)[1][3] = mBase; + break; + }; + (*outXform)[3][3] = 1.0f; + } + //--------------------------------------------------------------------- + void Terrain::getVector(const Vector3& inVec, Vector3* outVec) const + { + getVectorAlign(inVec.x, inVec.y, inVec.z, mAlign, outVec); + } + //--------------------------------------------------------------------- + void Terrain::getVector(Real x, Real y, Real z, Vector3* outVec) const + { + getVectorAlign(x, y, z, mAlign, outVec); + } + //--------------------------------------------------------------------- + void Terrain::getVectorAlign(const Vector3& inVec, Alignment align, Vector3* outVec) const + { + getVectorAlign(inVec.x, inVec.y, inVec.z, align, outVec); + } + //--------------------------------------------------------------------- + void Terrain::getVectorAlign(Real x, Real y, Real z, Alignment align, Vector3* outVec) const + { + + switch(align) + { + case ALIGN_X_Z: + outVec->y = z; + outVec->x = x; + outVec->z = -y; + break; + case ALIGN_Y_Z: + outVec->x = z; + outVec->y = y; + outVec->z = -x; + break; + case ALIGN_X_Y: + outVec->x = x; + outVec->y = y; + outVec->z = z; + break; + }; + + } + //--------------------------------------------------------------------- + void Terrain::getPosition(const Vector3& TSpos, Vector3* outWSpos) const + { + getPositionAlign(TSpos, mAlign, outWSpos); + } + //--------------------------------------------------------------------- + void Terrain::getPosition(Real x, Real y, Real z, Vector3* outWSpos) const + { + getPositionAlign(x, y, z, mAlign, outWSpos); + } + //--------------------------------------------------------------------- + void Terrain::getTerrainPosition(const Vector3& WSpos, Vector3* outTSpos) const + { + getTerrainPositionAlign(WSpos, mAlign, outTSpos); + } + //--------------------------------------------------------------------- + void Terrain::getTerrainPosition(Real x, Real y, Real z, Vector3* outTSpos) const + { + getTerrainPositionAlign(x, y, z, mAlign, outTSpos); + } + //--------------------------------------------------------------------- + void Terrain::getPositionAlign(const Vector3& TSpos, Alignment align, Vector3* outWSpos) const + { + getPositionAlign(TSpos.x, TSpos.y, TSpos.z, align, outWSpos); + } + //--------------------------------------------------------------------- + void Terrain::getPositionAlign(Real x, Real y, Real z, Alignment align, Vector3* outWSpos) const + { + switch(align) + { + case ALIGN_X_Z: + outWSpos->y = z; + outWSpos->x = x * (mSize - 1) * mScale + mBase; + outWSpos->z = y * (mSize - 1) * -mScale - mBase; + break; + case ALIGN_Y_Z: + outWSpos->x = z; + outWSpos->y = y * (mSize - 1) * mScale + mBase; + outWSpos->z = x * (mSize - 1) * -mScale - mBase; + break; + case ALIGN_X_Y: + outWSpos->z = z; + outWSpos->x = x * (mSize - 1) * mScale + mBase; + outWSpos->y = y * (mSize - 1) * mScale + mBase; + break; + }; + + } + //--------------------------------------------------------------------- + void Terrain::getTerrainPositionAlign(const Vector3& WSpos, Alignment align, Vector3* outTSpos) const + { + getTerrainPositionAlign(WSpos.x, WSpos.y, WSpos.z, align, outTSpos); + } + //--------------------------------------------------------------------- + void Terrain::getTerrainPositionAlign(Real x, Real y, Real z, Alignment align, Vector3* outTSpos) const + { + switch(align) + { + case ALIGN_X_Z: + outTSpos->x = (x - mBase - mPos.x) / ((mSize - 1) * mScale); + outTSpos->y = (z + mBase - mPos.z) / ((mSize - 1) * -mScale); + outTSpos->z = y; + break; + case ALIGN_Y_Z: + outTSpos->x = (z - mBase - mPos.z) / ((mSize - 1) * -mScale); + outTSpos->y = (y + mBase - mPos.y) / ((mSize - 1) * mScale); + outTSpos->z = x; + break; + case ALIGN_X_Y: + outTSpos->x = (x - mBase - mPos.x) / ((mSize - 1) * mScale); + outTSpos->y = (y - mBase - mPos.y) / ((mSize - 1) * mScale); + outTSpos->z = z; + break; + }; + + } + //--------------------------------------------------------------------- + void Terrain::getTerrainVector(const Vector3& inVec, Vector3* outVec) const + { + getTerrainVectorAlign(inVec.x, inVec.y, inVec.z, mAlign, outVec); + } + //--------------------------------------------------------------------- + void Terrain::getTerrainVector(Real x, Real y, Real z, Vector3* outVec) const + { + getTerrainVectorAlign(x, y, z, mAlign, outVec); + } + //--------------------------------------------------------------------- + void Terrain::getTerrainVectorAlign(const Vector3& inVec, Alignment align, Vector3* outVec) const + { + getTerrainVectorAlign(inVec.x, inVec.y, inVec.z, align, outVec); + } + //--------------------------------------------------------------------- + void Terrain::getTerrainVectorAlign(Real x, Real y, Real z, Alignment align, Vector3* outVec) const + { + + switch(align) + { + case ALIGN_X_Z: + outVec->z = y; + outVec->x = x; + outVec->y = -z; + break; + case ALIGN_Y_Z: + outVec->z = x; + outVec->y = y; + outVec->x = -z; + break; + case ALIGN_X_Y: + outVec->x = x; + outVec->y = y; + outVec->z = z; + break; + }; + + } + //--------------------------------------------------------------------- + Terrain::Alignment Terrain::getAlignment() const + { + return mAlign; + } + //--------------------------------------------------------------------- + uint16 Terrain::getSize() const + { + return mSize; + } + //--------------------------------------------------------------------- + uint16 Terrain::getMaxBatchSize() const + { + return mMaxBatchSize; + } + //--------------------------------------------------------------------- + uint16 Terrain::getMinBatchSize() const + { + return mMinBatchSize; + } + //--------------------------------------------------------------------- + Real Terrain::getWorldSize() const + { + return mWorldSize; + } + //--------------------------------------------------------------------- + Real Terrain::getLayerWorldSize(uint8 index) const + { + if (index < mLayers.size()) + { + return mLayers[index].worldSize; + } + else if (!mLayers.empty()) + { + return mLayers[0].worldSize; + } + else + { + return TerrainGlobalOptions::getSingleton().getDefaultLayerTextureWorldSize(); + } + } + //--------------------------------------------------------------------- + void Terrain::setLayerWorldSize(uint8 index, Real size) + { + if (index < mLayers.size()) + { + + if (index >= mLayerUVMultiplier.size()) + mLayerUVMultiplier.resize(index + 1); + + mLayers[index].worldSize = size; + mLayerUVMultiplier[index] = mWorldSize / size; + mMaterialParamsDirty = true; + mModified = true; + } + } + //--------------------------------------------------------------------- + Real Terrain::getLayerUVMultiplier(uint8 index) const + { + if (index < mLayerUVMultiplier.size()) + { + return mLayerUVMultiplier[index]; + } + else if (!mLayerUVMultiplier.empty()) + { + return mLayerUVMultiplier[0]; + } + else + { + // default to tile 100 times + return 100; + } + } + //--------------------------------------------------------------------- + void Terrain::deriveUVMultipliers() + { + mLayerUVMultiplier.resize(mLayers.size()); + for (size_t i = 0; i < mLayers.size(); ++i) + { + const LayerInstance& inst = mLayers[i]; + + mLayerUVMultiplier[i] = mWorldSize / inst.worldSize; + + } + } + //--------------------------------------------------------------------- + const String& Terrain::getLayerTextureName(uint8 layerIndex, uint8 samplerIndex) const + { + if (layerIndex < mLayers.size() && samplerIndex < mLayerDecl.samplers.size()) + { + return mLayers[layerIndex].textureNames[samplerIndex]; + } + else + { + return BLANKSTRING; + } + + } + //--------------------------------------------------------------------- + void Terrain::setLayerTextureName(uint8 layerIndex, uint8 samplerIndex, const String& textureName) + { + if (layerIndex < mLayers.size() && samplerIndex < mLayerDecl.samplers.size()) + { + if (mLayers[layerIndex].textureNames[samplerIndex] != textureName) + { + mLayers[layerIndex].textureNames[samplerIndex] = textureName; + mMaterialDirty = true; + mMaterialParamsDirty = true; + mModified = true; + } + } + } + //--------------------------------------------------------------------- + void Terrain::setPosition(const Vector3& pos) + { + if (pos != mPos) + { + mPos = pos; + mRootNode->setPosition(pos); + updateBaseScale(); + mModified = true; + } + } + //--------------------------------------------------------------------- + SceneNode* Terrain::_getRootSceneNode() const + { + return mRootNode; + } + //--------------------------------------------------------------------- + void Terrain::updateBaseScale() + { + // centre the terrain on local origin + mBase = -mWorldSize * 0.5; + // scale determines what 1 unit on the grid becomes in world space + mScale = mWorldSize / (Real)(mSize-1); + } + //--------------------------------------------------------------------- + void Terrain::dirty() + { + Rect rect; + rect.top = 0; rect.bottom = mSize; + rect.left = 0; rect.right = mSize; + dirtyRect(rect); + } + //--------------------------------------------------------------------- + void Terrain::dirtyRect(const Rect& rect) + { + mDirtyGeometryRect.merge(rect); + mDirtyGeometryRectForNeighbours.merge(rect); + mDirtyDerivedDataRect.merge(rect); + mCompositeMapDirtyRect.merge(rect); + + mModified = true; + mHeightDataModified = true; + + } + //--------------------------------------------------------------------- + void Terrain::_dirtyCompositeMapRect(const Rect& rect) + { + mCompositeMapDirtyRect.merge(rect); + mModified = true; + } + //--------------------------------------------------------------------- + void Terrain::dirtyLightmapRect(const Rect& rect) + { + mDirtyDerivedDataRect.merge(rect); + + mModified = true; + + } + //--------------------------------------------------------------------- + void Terrain::dirtyLightmap() + { + Rect rect; + rect.top = 0; rect.bottom = mSize; + rect.left = 0; rect.right = mSize; + dirtyLightmapRect(rect); + } + //--------------------------------------------------------------------- + void Terrain::update(bool synchronous) + { + updateGeometry(); + updateDerivedData(synchronous); + } + //--------------------------------------------------------------------- + void Terrain::updateGeometry() + { + if (!mDirtyGeometryRect.isNull()) + { + mQuadTree->updateVertexData(true, false, mDirtyGeometryRect, false); + mDirtyGeometryRect.setNull(); + } + + // propagate changes + notifyNeighbours(); + } + //--------------------------------------------------------------------- + void Terrain::updateGeometryWithoutNotifyNeighbours() + { + if (!mDirtyGeometryRect.isNull()) + { + mQuadTree->updateVertexData(true, false, mDirtyGeometryRect, false); + mDirtyGeometryRect.setNull(); + } + } + //--------------------------------------------------------------------- + void Terrain::updateDerivedData(bool synchronous, uint8 typeMask) + { + if (!mDirtyDerivedDataRect.isNull() || !mDirtyLightmapFromNeighboursRect.isNull()) + { + mModified = true; + if (mDerivedDataUpdateInProgress) + { + // Don't launch many updates, instead wait for the other one + // to finish and issue another afterwards. + mDerivedUpdatePendingMask |= typeMask; + } + else + { + updateDerivedDataImpl(mDirtyDerivedDataRect, mDirtyLightmapFromNeighboursRect, + synchronous, typeMask); + mDirtyDerivedDataRect.setNull(); + mDirtyLightmapFromNeighboursRect.setNull(); + } + } + else + { + // Usually the composite map is updated after the other background + // data is updated (no point doing it beforehand), but if there's + // nothing to update, then we'll do it right now. + updateCompositeMap(); + } + + + } + //--------------------------------------------------------------------- + void Terrain::updateDerivedDataImpl(const Rect& rect, const Rect& lightmapExtraRect, + bool synchronous, uint8 typeMask) + { + mDerivedDataUpdateInProgress = true; + mDerivedUpdatePendingMask = 0; + + DerivedDataRequest req; + req.terrain = this; + req.dirtyRect = rect; + req.lightmapExtraDirtyRect = lightmapExtraRect; + req.typeMask = typeMask; + if (!mNormalMapRequired) + req.typeMask = req.typeMask & ~DERIVED_DATA_NORMALS; + if (!mLightMapRequired) + req.typeMask = req.typeMask & ~DERIVED_DATA_LIGHTMAP; + + Root::getSingleton().getWorkQueue()->addRequest( + mWorkQueueChannel, WORKQUEUE_DERIVED_DATA_REQUEST, + Any(req), 0, synchronous); + + } + //--------------------------------------------------------------------- + void Terrain::waitForDerivedProcesses() + { + while (mDerivedDataUpdateInProgress || mGenerateMaterialInProgress || mPrepareInProgress) + { + // we need to wait for this to finish + OGRE_THREAD_SLEEP(50); + Root::getSingleton().getWorkQueue()->processResponses(); + } + + } + //--------------------------------------------------------------------- + void Terrain::freeCPUResources() + { + OGRE_FREE(mHeightData, MEMCATEGORY_GEOMETRY); + mHeightData = 0; + + OGRE_FREE(mDeltaData, MEMCATEGORY_GEOMETRY); + mDeltaData = 0; + + OGRE_DELETE mQuadTree; + mQuadTree = 0; + + if (mCpuTerrainNormalMap) + { + OGRE_FREE(mCpuTerrainNormalMap->data, MEMCATEGORY_GENERAL); + OGRE_DELETE mCpuTerrainNormalMap; + mCpuTerrainNormalMap = 0; + } + + OGRE_FREE(mCpuColourMapStorage, MEMCATEGORY_GENERAL); + mCpuColourMapStorage = 0; + + OGRE_FREE(mCpuLightmapStorage, MEMCATEGORY_GENERAL); + mCpuLightmapStorage = 0; + + OGRE_FREE(mCpuCompositeMapStorage, MEMCATEGORY_GENERAL); + mCpuCompositeMapStorage = 0; + } + //--------------------------------------------------------------------- + void Terrain::freeGPUResources() + { + // remove textures + TextureManager* tmgr = TextureManager::getSingletonPtr(); + if (tmgr) + { + for (TexturePtrList::iterator i = mBlendTextureList.begin(); i != mBlendTextureList.end(); ++i) + { + tmgr->remove((*i)->getHandle()); + } + mBlendTextureList.clear(); + + if (!mTerrainNormalMap.isNull()) + { + tmgr->remove(mTerrainNormalMap->getHandle()); + mTerrainNormalMap.setNull(); + } + + if (!mColourMap.isNull()) + { + tmgr->remove(mColourMap->getHandle()); + mColourMap.setNull(); + } + + if (!mLightmap.isNull()) + { + tmgr->remove(mLightmap->getHandle()); + mLightmap.setNull(); + } + + if (!mCompositeMap.isNull()) + { + tmgr->remove(mCompositeMap->getHandle()); + mCompositeMap.setNull(); + } + } + + if (!mMaterial.isNull()) + { + MaterialManager::getSingleton().remove(mMaterial->getHandle()); + mMaterial.setNull(); + } + if (!mCompositeMapMaterial.isNull()) + { + MaterialManager::getSingleton().remove(mCompositeMapMaterial->getHandle()); + mCompositeMapMaterial.setNull(); + } + + + } + //--------------------------------------------------------------------- + void Terrain::freeLodData() + { + if(mLodManager) + { + OGRE_DELETE mLodManager; + mLodManager = 0; + } + } + //--------------------------------------------------------------------- + Rect Terrain::calculateHeightDeltas(const Rect& rect) + { + Rect clampedRect(rect); + clampedRect.left = std::max(0L, clampedRect.left); + clampedRect.top = std::max(0L, clampedRect.top); + clampedRect.right = std::min((long)mSize, clampedRect.right); + clampedRect.bottom = std::min((long)mSize, clampedRect.bottom); + + Rect finalRect(clampedRect); + + mQuadTree->preDeltaCalculation(clampedRect); + + /// Iterate over target levels, + for (int targetLevel = 1; targetLevel < mNumLodLevels; ++targetLevel) + { + int sourceLevel = targetLevel - 1; + int step = 1 << targetLevel; + // The step of the next higher LOD +// int higherstep = step >> 1; + + // need to widen the dirty rectangle since change will affect surrounding + // vertices at lower LOD + Rect widenedRect(rect); + widenedRect.left = std::max(0L, widenedRect.left - step); + widenedRect.top = std::max(0L, widenedRect.top - step); + widenedRect.right = std::min((long)mSize, widenedRect.right + step); + widenedRect.bottom = std::min((long)mSize, widenedRect.bottom + step); + + // keep a merge of the widest + finalRect.merge(widenedRect); + + + // now round the rectangle at this level so that it starts & ends on + // the step boundaries + Rect lodRect(widenedRect); + lodRect.left -= lodRect.left % step; + lodRect.top -= lodRect.top % step; + if (lodRect.right % step) + lodRect.right += step - (lodRect.right % step); + if (lodRect.bottom % step) + lodRect.bottom += step - (lodRect.bottom % step); + + for (long j = lodRect.top; j < lodRect.bottom - step; j += step ) + { + for (long i = lodRect.left; i < lodRect.right - step; i += step ) + { + // Form planes relating to the lower detail tris to be produced + // For even tri strip rows, they are this shape: + // 2---3 + // | / | + // 0---1 + // For odd tri strip rows, they are this shape: + // 2---3 + // | \ | + // 0---1 + + Vector3 v0, v1, v2, v3; + getPointAlign(i, j, ALIGN_X_Y, &v0); + getPointAlign(i + step, j, ALIGN_X_Y, &v1); + getPointAlign(i, j + step, ALIGN_X_Y, &v2); + getPointAlign(i + step, j + step, ALIGN_X_Y, &v3); + + Plane t1, t2; + bool backwardTri = false; + // Odd or even in terms of target level + if ((j / step) % 2 == 0) + { + t1.redefine(v0, v1, v3); + t2.redefine(v0, v3, v2); + } + else + { + t1.redefine(v1, v3, v2); + t2.redefine(v0, v1, v2); + backwardTri = true; + } + + // include the bottommost row of vertices if this is the last row + int yubound = (j == (mSize - step)? step : step - 1); + for ( int y = 0; y <= yubound; y++ ) + { + // include the rightmost col of vertices if this is the last col + int xubound = (i == (mSize - step)? step : step - 1); + for ( int x = 0; x <= xubound; x++ ) + { + int fulldetailx = static_cast(i + x); + int fulldetaily = static_cast(j + y); + if ( fulldetailx % step == 0 && + fulldetaily % step == 0 ) + { + // Skip, this one is a vertex at this level + continue; + } + + Real ypct = (Real)y / (Real)step; + Real xpct = (Real)x / (Real)step; + + //interpolated height + Vector3 actualPos; + getPointAlign(fulldetailx, fulldetaily, ALIGN_X_Y, &actualPos); + Real interp_h; + // Determine which tri we're on + if ((xpct > ypct && !backwardTri) || + (xpct > (1-ypct) && backwardTri)) + { + // Solve for x/z + interp_h = + (-t1.normal.x * actualPos.x + - t1.normal.y * actualPos.y + - t1.d) / t1.normal.z; + } + else + { + // Second tri + interp_h = + (-t2.normal.x * actualPos.x + - t2.normal.y * actualPos.y + - t2.d) / t2.normal.z; + } + + Real actual_h = actualPos.z; + Real delta = interp_h - actual_h; + + // max(delta) is the worst case scenario at this LOD + // compared to the original heightmap + + // tell the quadtree about this + mQuadTree->notifyDelta(fulldetailx, fulldetaily, sourceLevel, delta); + + + // If this vertex is being removed at this LOD, + // then save the height difference since that's the move + // it will need to make. Vertices to be removed at this LOD + // are halfway between the steps, but exclude those that + // would have been eliminated at earlier levels + int halfStep = step / 2; + if ( + ((fulldetailx % step) == halfStep && (fulldetaily % halfStep) == 0) || + ((fulldetaily % step) == halfStep && (fulldetailx % halfStep) == 0)) + { + // Save height difference + mDeltaData[fulldetailx + (fulldetaily * mSize)] = delta; + } + + } + + } + } // i + } // j + + } // targetLevel + + mQuadTree->postDeltaCalculation(clampedRect); + + return finalRect; + + } + //--------------------------------------------------------------------- + void Terrain::finaliseHeightDeltas(const Rect& rect, bool cpuData) + { + + Rect clampedRect(rect); + clampedRect.left = std::max(0L, clampedRect.left); + clampedRect.top = std::max(0L, clampedRect.top); + clampedRect.right = std::min((long)mSize, clampedRect.right); + clampedRect.bottom = std::min((long)mSize, clampedRect.bottom); + + // min/max information + mQuadTree->finaliseDeltaValues(clampedRect); + // delta vertex data + mQuadTree->updateVertexData(false, true, clampedRect, cpuData); + + } + + //--------------------------------------------------------------------- + uint16 Terrain::getResolutionAtLod(uint16 lodLevel) const + { + return ((mSize - 1) >> lodLevel) + 1; + } + //--------------------------------------------------------------------- + uint Terrain::getGeoDataSizeAtLod(uint16 lodLevel) const + { + uint size = getResolutionAtLod(lodLevel); + uint prevSize = (lodLevelgetMilliseconds(); + unsigned long elapsedMillis = currMillis - mLastMillis; + if (mCompositeMapUpdateCountdown > 0 && elapsedMillis) + { + if (elapsedMillis > mCompositeMapUpdateCountdown) + mCompositeMapUpdateCountdown = 0; + else + mCompositeMapUpdateCountdown -= elapsedMillis; + + if (!mCompositeMapUpdateCountdown) + updateCompositeMap(); + } + mLastMillis = currMillis; + // only calculate LOD once per LOD camera, per frame, per viewport height + const Camera* lodCamera = v->getCamera()->getLodCamera(); + unsigned long frameNum = Root::getSingleton().getNextFrameNumber(); + int vpHeight = v->getActualHeight(); + if (mLastLODCamera != lodCamera || frameNum != mLastLODFrame + || mLastViewportHeight != vpHeight) + { + mLastLODCamera = lodCamera; + mLastLODFrame = frameNum; + mLastViewportHeight = vpHeight; + calculateCurrentLod(v); + } + } + //--------------------------------------------------------------------- + void Terrain::sceneManagerDestroyed(SceneManager* source) + { + unload(); + unprepare(); + if (source == mSceneMgr) + mSceneMgr = 0; + } + //--------------------------------------------------------------------- + void Terrain::calculateCurrentLod(Viewport* vp) + { + if (mQuadTree) + { + // calculate error terms + const Camera* cam = vp->getCamera()->getLodCamera(); + + // W. de Boer 2000 calculation + // A = vp_near / abs(vp_top) + // A = 1 / tan(fovy*0.5) (== 1 for fovy=45*2) + Real A = 1.0f / Math::Tan(cam->getFOVy() * 0.5f); + // T = 2 * maxPixelError / vertRes + Real maxPixelError = TerrainGlobalOptions::getSingleton().getMaxPixelError() * cam->_getLodBiasInverse(); + Viewport* lodVp = cam->getViewport(); + Real T = 2.0f * maxPixelError / (Real)lodVp->getActualHeight(); + + // CFactor = A / T + Real cFactor = A / T; + + mQuadTree->calculateCurrentLod(cam, cFactor); + } + } + //--------------------------------------------------------------------- + std::pair Terrain::rayIntersects(const Ray& ray, + bool cascadeToNeighbours /* = false */, Real distanceLimit /* = 0 */) + { + typedef std::pair Result; + // first step: convert the ray to a local vertex space + // we assume terrain to be in the x-z plane, with the [0,0] vertex + // at origin and a plane distance of 1 between vertices. + // This makes calculations easier. + Vector3 rayOrigin = ray.getOrigin() - getPosition(); + Vector3 rayDirection = ray.getDirection(); + // change alignment + Vector3 tmp; + switch (getAlignment()) + { + case ALIGN_X_Y: + std::swap(rayOrigin.y, rayOrigin.z); + std::swap(rayDirection.y, rayDirection.z); + break; + case ALIGN_Y_Z: + // x = z, z = y, y = -x + tmp.x = rayOrigin.z; + tmp.z = rayOrigin.y; + tmp.y = -rayOrigin.x; + rayOrigin = tmp; + tmp.x = rayDirection.z; + tmp.z = rayDirection.y; + tmp.y = -rayDirection.x; + rayDirection = tmp; + break; + case ALIGN_X_Z: + // already in X/Z but values increase in -Z + rayOrigin.z = -rayOrigin.z; + rayDirection.z = -rayDirection.z; + break; + } + // readjust coordinate origin + rayOrigin.x += mWorldSize/2; + rayOrigin.z += mWorldSize/2; + // scale down to vertex level + rayOrigin.x /= mScale; + rayOrigin.z /= mScale; + rayDirection.x /= mScale; + rayDirection.z /= mScale; + rayDirection.normalise(); + Ray localRay (rayOrigin, rayDirection); + + // test if the ray actually hits the terrain's bounds + Real maxHeight = getMaxHeight(); + Real minHeight = getMinHeight(); + + AxisAlignedBox aabb (Vector3(0, minHeight, 0), Vector3(mSize, maxHeight, mSize)); + std::pair aabbTest = localRay.intersects(aabb); + if (!aabbTest.first) + { + if (cascadeToNeighbours) + { + OGRE_LOCK_RW_MUTEX_READ(mNeighbourMutex); + Terrain* neighbour = raySelectNeighbour(ray, distanceLimit); + if (neighbour) + return neighbour->rayIntersects(ray, cascadeToNeighbours, distanceLimit); + } + return Result(false, Vector3()); + } + // get intersection point and move inside + Vector3 cur = localRay.getPoint(aabbTest.second); + + // now check every quad the ray touches + int quadX = std::min(std::max(static_cast(cur.x), 0), (int)mSize-2); + int quadZ = std::min(std::max(static_cast(cur.z), 0), (int)mSize-2); + int flipX = (rayDirection.x < 0 ? 0 : 1); + int flipZ = (rayDirection.z < 0 ? 0 : 1); + int xDir = (rayDirection.x < 0 ? -1 : 1); + int zDir = (rayDirection.z < 0 ? -1 : 1); + + Result result(true, Vector3::ZERO); + Real dummyHighValue = (Real)mSize * 10000.0f; + + + while (cur.y >= (minHeight - 1e-3) && cur.y <= (maxHeight + 1e-3)) + { + if (quadX < 0 || quadX >= (int)mSize-1 || quadZ < 0 || quadZ >= (int)mSize-1) + break; + + result = checkQuadIntersection(quadX, quadZ, localRay); + if (result.first) + break; + + // determine next quad to test + Real xDist = Math::RealEqual(rayDirection.x, 0.0) ? dummyHighValue : + (quadX - cur.x + flipX) / rayDirection.x; + Real zDist = Math::RealEqual(rayDirection.z, 0.0) ? dummyHighValue : + (quadZ - cur.z + flipZ) / rayDirection.z; + if (xDist < zDist) + { + quadX += xDir; + cur += rayDirection * xDist; + } + else + { + quadZ += zDir; + cur += rayDirection * zDist; + } + + } + + if (result.first) + { + // transform the point of intersection back to world space + result.second.x *= mScale; + result.second.z *= mScale; + result.second.x -= mWorldSize/2; + result.second.z -= mWorldSize/2; + switch (getAlignment()) + { + case ALIGN_X_Y: + std::swap(result.second.y, result.second.z); + break; + case ALIGN_Y_Z: + // z = x, y = z, x = -y + tmp.x = -rayOrigin.y; + tmp.y = rayOrigin.z; + tmp.z = rayOrigin.x; + rayOrigin = tmp; + break; + case ALIGN_X_Z: + result.second.z = -result.second.z; + break; + } + result.second += getPosition(); + } + else if (cascadeToNeighbours) + { + Terrain* neighbour = raySelectNeighbour(ray, distanceLimit); + if (neighbour) + result = neighbour->rayIntersects(ray, cascadeToNeighbours, distanceLimit); + } + return result; + } + //--------------------------------------------------------------------- + std::pair Terrain::checkQuadIntersection(int x, int z, const Ray& ray) + { + // build the two planes belonging to the quad's triangles + Vector3 v1 ((Real)x, *getHeightData(x,z), (Real)z); + Vector3 v2 ((Real)x+1, *getHeightData(x+1,z), (Real)z); + Vector3 v3 ((Real)x, *getHeightData(x,z+1), (Real)z+1); + Vector3 v4 ((Real)x+1, *getHeightData(x+1,z+1), (Real)z+1); + + Plane p1, p2; + bool oddRow = false; + if (z % 2) + { + /* odd + 3---4 + | \ | + 1---2 + */ + p1.redefine(v2, v4, v3); + p2.redefine(v1, v2, v3); + oddRow = true; + } + else + { + /* even + 3---4 + | / | + 1---2 + */ + p1.redefine(v1, v2, v4); + p2.redefine(v1, v4, v3); + } + + // Test for intersection with the two planes. + // Then test that the intersection points are actually + // still inside the triangle (with a small error margin) + // Also check which triangle it is in + std::pair planeInt = ray.intersects(p1); + if (planeInt.first) + { + Vector3 where = ray.getPoint(planeInt.second); + Vector3 rel = where - v1; + if (rel.x >= -0.01 && rel.x <= 1.01 && rel.z >= -0.01 && rel.z <= 1.01 // quad bounds + && ((rel.x >= rel.z && !oddRow) || (rel.x >= (1 - rel.z) && oddRow))) // triangle bounds + return std::pair(true, where); + } + planeInt = ray.intersects(p2); + if (planeInt.first) + { + Vector3 where = ray.getPoint(planeInt.second); + Vector3 rel = where - v1; + if (rel.x >= -0.01 && rel.x <= 1.01 && rel.z >= -0.01 && rel.z <= 1.01 // quad bounds + && ((rel.x <= rel.z && !oddRow) || (rel.x <= (1 - rel.z) && oddRow))) // triangle bounds + return std::pair(true, where); + } + + return std::pair(false, Vector3()); + } + //--------------------------------------------------------------------- + const MaterialPtr& Terrain::getMaterial() const + { + if (mMaterial.isNull() || + mMaterialGenerator->getChangeCount() != mMaterialGenerationCount || + mMaterialDirty) + { + mMaterial = mMaterialGenerator->generate(this); + mMaterial->load(); + if (mCompositeMapRequired) + { + mCompositeMapMaterial = mMaterialGenerator->generateForCompositeMap(this); + mCompositeMapMaterial->load(); + } + mMaterialGenerationCount = mMaterialGenerator->getChangeCount(); + mMaterialDirty = false; + } + if (mMaterialParamsDirty) + { + mMaterialGenerator->updateParams(mMaterial, this); + if(mCompositeMapRequired) + mMaterialGenerator->updateParamsForCompositeMap(mCompositeMapMaterial, this); + mMaterialParamsDirty = false; + + } + + return mMaterial; + } + //--------------------------------------------------------------------- + const MaterialPtr& Terrain::getCompositeMapMaterial() const + { + // both materials updated together since they change at the same time + getMaterial(); + return mCompositeMapMaterial; + } + //--------------------------------------------------------------------- + void Terrain::checkLayers(bool includeGPUResources) + { + for (LayerInstanceList::iterator it = mLayers.begin(); it != mLayers.end(); ++it) + { + LayerInstance& layer = *it; + // If we're missing sampler entries compared to the declaration, initialise them + for (size_t i = layer.textureNames.size(); i < mLayerDecl.samplers.size(); ++i) + { + layer.textureNames.push_back(BLANKSTRING); + } + + // if we have too many layers for the declaration, trim them + if (layer.textureNames.size() > mLayerDecl.samplers.size()) + { + layer.textureNames.resize(mLayerDecl.samplers.size()); + } + } + + if (includeGPUResources) + { + createGPUBlendTextures(); + createLayerBlendMaps(); + } + + } + //--------------------------------------------------------------------- + void Terrain::checkDeclaration() + { + if (mMaterialGenerator.isNull()) + { + mMaterialGenerator = TerrainGlobalOptions::getSingleton().getDefaultMaterialGenerator(); + } + + if (mLayerDecl.elements.empty()) + { + // default the declaration + mLayerDecl = mMaterialGenerator->getLayerDeclaration(); + } + + } + //--------------------------------------------------------------------- + void Terrain::replaceLayer(uint8 index, bool keepBlends, Real worldSize, const StringVector* textureNames) + { + if (getLayerCount() > 0) + { + if (index >= getLayerCount()) + index = getLayerCount() - 1; + + LayerInstanceList::iterator i = mLayers.begin(); + std::advance(i, index); + + if (textureNames) + { + (*i).textureNames = *textureNames; + } + + // use utility method to update UV scaling + setLayerWorldSize(index, worldSize); + + // Delete the blend map if its not the base + if ( !keepBlends && index > 0 ) + { + if (mLayerBlendMapList[index-1]) + { + delete mLayerBlendMapList[index-1]; + mLayerBlendMapList[index-1] = 0; + } + + // Reset the layer to black + std::pair layerPair = getLayerBlendTextureIndex(index); + clearGPUBlendChannel( layerPair.first, layerPair.second ); + } + + mMaterialDirty = true; + mMaterialParamsDirty = true; + mModified = true; + } + } + //--------------------------------------------------------------------- + void Terrain::addLayer(Real worldSize, const StringVector* textureNames) + { + addLayer(getLayerCount(), worldSize, textureNames); + } + //--------------------------------------------------------------------- + void Terrain::addLayer(uint8 index, Real worldSize, const StringVector* textureNames) + { + if (!worldSize) + worldSize = TerrainGlobalOptions::getSingleton().getDefaultLayerTextureWorldSize(); + + uint8 blendIndex = std::max(index-1,0); + if (index >= getLayerCount()) + { + mLayers.push_back(LayerInstance()); + index = getLayerCount() - 1; + } + else + { + LayerInstanceList::iterator i = mLayers.begin(); + std::advance(i, index); + mLayers.insert(i, LayerInstance()); + + RealVector::iterator uvi = mLayerUVMultiplier.begin(); + std::advance(uvi, index); + mLayerUVMultiplier.insert(uvi, 0.0f); + + TerrainLayerBlendMapList::iterator bi = mLayerBlendMapList.begin(); + std::advance(bi, blendIndex); + mLayerBlendMapList.insert(bi, static_cast(0)); + } + if (textureNames) + { + LayerInstance& inst = mLayers[index]; + inst.textureNames = *textureNames; + } + // use utility method to update UV scaling + setLayerWorldSize(index, worldSize); + checkLayers(true); + + // Is this an insert into the middle of the layer list? + if (index < getLayerCount() - 1) + { + // Shift all GPU texture channels up one + shiftUpGPUBlendChannels(blendIndex); + + // All blend maps above this layer index will need to be recreated since their buffers/channels have changed + deleteBlendMaps(index); + } + + mMaterialDirty = true; + mMaterialParamsDirty = true; + mModified = true; + + } + //--------------------------------------------------------------------- + void Terrain::removeLayer(uint8 index) + { + if (index < mLayers.size()) + { uint8 blendIndex = std::max(index-1,0); - // Shift all GPU texture channels down one - shiftDownGPUBlendChannels(blendIndex); + // Shift all GPU texture channels down one + shiftDownGPUBlendChannels(blendIndex); + + LayerInstanceList::iterator i = mLayers.begin(); + std::advance(i, index); + mLayers.erase(i); + + RealVector::iterator uvi = mLayerUVMultiplier.begin(); + std::advance(uvi, index); + mLayerUVMultiplier.erase(uvi); + + if (mLayerBlendMapList.size() > 0) + { + // If they removed the base OR the first layer, we need to erase the first blend map + TerrainLayerBlendMapList::iterator bi = mLayerBlendMapList.begin(); + std::advance(bi, blendIndex); + OGRE_DELETE *bi; + mLayerBlendMapList.erase(bi); + + // Check to see if a GPU textures can be released + checkLayers(true); + + // All blend maps for layers above the erased will need to be recreated since their buffers/channels have changed + deleteBlendMaps(blendIndex); + } + + mMaterialDirty = true; + mMaterialParamsDirty = true; + mModified = true; + } + } + //--------------------------------------------------------------------- + uint8 Terrain::getMaxLayers() const + { + return mMaterialGenerator->getMaxLayers(this); + } + //--------------------------------------------------------------------- + TerrainLayerBlendMap* Terrain::getLayerBlendMap(uint8 layerIndex) + { + if (layerIndex == 0 || layerIndex-1 >= (uint8)mLayerBlendMapList.size()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid layer index", "Terrain::getLayerBlendMap"); + + uint8 idx = layerIndex - 1; + if (!mLayerBlendMapList[idx]) + { + if (mBlendTextureList.size() < static_cast(idx / 4)) + checkLayers(true); + + const TexturePtr& tex = mBlendTextureList[idx / 4]; + mLayerBlendMapList[idx] = OGRE_NEW TerrainLayerBlendMap(this, layerIndex, tex->getBuffer().getPointer()); + } + + return mLayerBlendMapList[idx]; + + } + //--------------------------------------------------------------------- + uint8 Terrain::getBlendTextureCount(uint8 numLayers) const + { + return ((numLayers - 2) / 4) + 1; + } + //--------------------------------------------------------------------- + uint8 Terrain::getBlendTextureCount() const + { + return (uint8)mBlendTextureList.size(); + } + //--------------------------------------------------------------------- + PixelFormat Terrain::getBlendTextureFormat(uint8 textureIndex, uint8 numLayers) const + { + /* + if (numLayers - 1 - (textureIndex * 4) > 3) + return PF_BYTE_RGBA; + else + return PF_BYTE_RGB; + */ + // Always create RGBA; no point trying to create RGB since all cards pad to 32-bit (XRGB) + // and it makes it harder to expand layer count dynamically if format has to change + return PF_BYTE_RGBA; + } + //--------------------------------------------------------------------- + void Terrain::shiftUpGPUBlendChannels(uint8 index) + { + // checkLayers() has been called to make sure the blend textures have been created + assert( mBlendTextureList.size() == getBlendTextureCount(getLayerCount()) ); + + // Shift all blend channels > index UP one slot, possibly into the next texture + // Example: index = 2 + // Before: [1 2 3 4] [5] + // After: [1 2 0 3] [4 5] + + uint8 layerIndex = index + 1; + for (uint8 i=getLayerCount()-1; i > layerIndex; --i ) + { + std::pair destPair = getLayerBlendTextureIndex(i); + std::pair srcPair = getLayerBlendTextureIndex(i - 1); + + copyBlendTextureChannel( srcPair.first, srcPair.second, destPair.first, destPair.second ); + } + + // Reset the layer to black + std::pair layerPair = getLayerBlendTextureIndex(layerIndex); + clearGPUBlendChannel( layerPair.first, layerPair.second ); + } + //--------------------------------------------------------------------- + void Terrain::shiftDownGPUBlendChannels(uint8 index) + { + // checkLayers() has been called to make sure the blend textures have been created + assert( mBlendTextureList.size() == getBlendTextureCount(getLayerCount()) ); + + // Shift all blend channels above layerIndex DOWN one slot, possibly into the previous texture + // Example: index = 2 + // Before: [1 2 3 4] [5] + // After: [1 2 4 5] [0] + + uint8 layerIndex = index + 1; + for (uint8 i=layerIndex; i < getLayerCount() - 1; ++i ) + { + std::pair destPair = getLayerBlendTextureIndex(i); + std::pair srcPair = getLayerBlendTextureIndex(i + 1); + + copyBlendTextureChannel( srcPair.first, srcPair.second, destPair.first, destPair.second ); + } + + // Reset the layer to black + if ( getLayerCount() > 1 ) + { + std::pair layerPair = getLayerBlendTextureIndex(getLayerCount() - 1); + clearGPUBlendChannel( layerPair.first, layerPair.second ); + } + } + //--------------------------------------------------------------------- + void Terrain::copyBlendTextureChannel(uint8 srcIndex, uint8 srcChannel, uint8 destIndex, uint8 destChannel ) + { + HardwarePixelBufferSharedPtr srcBuffer = getLayerBlendTexture(srcIndex)->getBuffer(); + HardwarePixelBufferSharedPtr destBuffer = getLayerBlendTexture(destIndex)->getBuffer(); + + unsigned char rgbaShift[4]; + Image::Box box(0, 0, destBuffer->getWidth(), destBuffer->getHeight()); + + uint8* pDestBase = static_cast(destBuffer->lock(box, HardwareBuffer::HBL_NORMAL).data); + PixelUtil::getBitShifts(destBuffer->getFormat(), rgbaShift); + uint8* pDest = pDestBase + rgbaShift[destChannel] / 8; + size_t destInc = PixelUtil::getNumElemBytes(destBuffer->getFormat()); + + size_t srcInc; + uint8* pSrc; + + if ( destBuffer == srcBuffer ) + { + pSrc = pDestBase + rgbaShift[srcChannel] / 8; + srcInc = destInc; + } + else + { + pSrc = static_cast(srcBuffer->lock(box, HardwareBuffer::HBL_READ_ONLY).data); + PixelUtil::getBitShifts(srcBuffer->getFormat(), rgbaShift); + pSrc += rgbaShift[srcChannel] / 8; + srcInc = PixelUtil::getNumElemBytes(srcBuffer->getFormat()); + } + + for (size_t y = box.top; y < box.bottom; ++y) + { + for (size_t x = box.left; x < box.right; ++x) + { + *pDest = *pSrc; + pSrc += srcInc; + pDest += destInc; + } + } + + destBuffer->unlock(); + if ( destBuffer != srcBuffer ) + srcBuffer->unlock(); + } + //--------------------------------------------------------------------- + void Terrain::clearGPUBlendChannel(uint8 index, uint channel) + { + HardwarePixelBufferSharedPtr buffer = getLayerBlendTexture(index)->getBuffer(); + + unsigned char rgbaShift[4]; + Image::Box box(0, 0, buffer->getWidth(), buffer->getHeight()); + + uint8* pData = static_cast(buffer->lock(box, HardwareBuffer::HBL_NORMAL).data); + PixelUtil::getBitShifts(buffer->getFormat(), rgbaShift); + pData += rgbaShift[channel] / 8; + size_t inc = PixelUtil::getNumElemBytes(buffer->getFormat()); + + for (size_t y = box.top; y < box.bottom; ++y) + { + for (size_t x = box.left; x < box.right; ++x) + { + *pData = 0; + pData += inc; + } + } + buffer->unlock(); + } + //--------------------------------------------------------------------- + void Terrain::createGPUBlendTextures() + { + // Create enough RGBA/RGB textures to cope with blend layers + uint8 numTex = getBlendTextureCount(getLayerCount()); + // delete extras + TextureManager* tmgr = TextureManager::getSingletonPtr(); + if (!tmgr) + return; + + while (mBlendTextureList.size() > numTex) + { + tmgr->remove(mBlendTextureList.back()->getHandle()); + mBlendTextureList.pop_back(); + } + + uint8 currentTex = (uint8)mBlendTextureList.size(); + mBlendTextureList.resize(numTex); + // create new textures + for (uint8 i = currentTex; i < numTex; ++i) + { + PixelFormat fmt = getBlendTextureFormat(i, getLayerCount()); + // Use TU_STATIC because although we will update this, we won't do it every frame + // in normal circumstances, so we don't want TU_DYNAMIC. Also we will + // read it (if we've cleared local temp areas) so no WRITE_ONLY + mBlendTextureList[i] = TextureManager::getSingleton().createManual( + msBlendTextureGenerator.generate(), _getDerivedResourceGroup(), + TEX_TYPE_2D, mLayerBlendMapSize, mLayerBlendMapSize, 1, 0, fmt, TU_STATIC); + + mLayerBlendMapSizeActual = mBlendTextureList[i]->getWidth(); + + if (mCpuBlendMapStorage.size() > i) + { + // Load blend data + PixelBox src(mLayerBlendMapSize, mLayerBlendMapSize, 1, fmt, mCpuBlendMapStorage[i]); + mBlendTextureList[i]->getBuffer()->blitFromMemory(src); + // release CPU copy, don't need it anymore + OGRE_FREE(mCpuBlendMapStorage[i], MEMCATEGORY_RESOURCE); + } + else + { + // initialise black + Box box(0, 0, mLayerBlendMapSize, mLayerBlendMapSize); + HardwarePixelBufferSharedPtr buf = mBlendTextureList[i]->getBuffer(); + uint8* pInit = static_cast(buf->lock(box, HardwarePixelBuffer::HBL_DISCARD).data); + memset(pInit, 0, PixelUtil::getNumElemBytes(fmt) * mLayerBlendMapSize * mLayerBlendMapSize); + buf->unlock(); + } + } + mCpuBlendMapStorage.clear(); + + + } + //--------------------------------------------------------------------- + void Terrain::createLayerBlendMaps() + { + // delete extra blend layers (affects GPU) + while (mLayerBlendMapList.size() > mLayers.size() - 1) + { + OGRE_DELETE mLayerBlendMapList.back(); + mLayerBlendMapList.pop_back(); + } + + // resize up (initialises to 0, populate as necessary) + if ( mLayers.size() > 1 ) + mLayerBlendMapList.resize(mLayers.size() - 1, 0); + + } + //--------------------------------------------------------------------- + void Terrain::createOrDestroyGPUNormalMap() + { + if (mNormalMapRequired && mTerrainNormalMap.isNull()) + { + // create + mTerrainNormalMap = TextureManager::getSingleton().createManual( + mMaterialName + "/nm", _getDerivedResourceGroup(), + TEX_TYPE_2D, mSize, mSize, 1, 0, PF_BYTE_RGB, TU_STATIC); + + // Upload loaded normal data if present + if (mCpuTerrainNormalMap) + { + mTerrainNormalMap->getBuffer()->blitFromMemory(*mCpuTerrainNormalMap); + OGRE_FREE(mCpuTerrainNormalMap->data, MEMCATEGORY_GENERAL); + OGRE_DELETE mCpuTerrainNormalMap; + mCpuTerrainNormalMap = 0; + } + + } + else if (!mNormalMapRequired && !mTerrainNormalMap.isNull()) + { + // destroy + TextureManager::getSingleton().remove(mTerrainNormalMap->getHandle()); + mTerrainNormalMap.setNull(); + } + + } + //--------------------------------------------------------------------- + void Terrain::freeTemporaryResources() + { + // CPU blend maps + for (BytePointerList::iterator i = mCpuBlendMapStorage.begin(); + i != mCpuBlendMapStorage.end(); ++i) + { + OGRE_FREE(*i, MEMCATEGORY_RESOURCE); + } + mCpuBlendMapStorage.clear(); + + // Editable structures for blend layers (not needed at runtime, only blend textures are) + deleteBlendMaps(0); + } + //--------------------------------------------------------------------- + void Terrain::deleteBlendMaps(uint8 lowIndex) + { + TerrainLayerBlendMapList::iterator i = mLayerBlendMapList.begin(); + std::advance(i, lowIndex); + for (; i != mLayerBlendMapList.end(); ++i ) + { + OGRE_DELETE *i; + *i = 0; + } + } + //--------------------------------------------------------------------- + const TexturePtr& Terrain::getLayerBlendTexture(uint8 index) const + { + assert(index < mBlendTextureList.size()); + + return mBlendTextureList[index]; + } + //--------------------------------------------------------------------- + std::pair Terrain::getLayerBlendTextureIndex(uint8 layerIndex) const + { + assert(layerIndex > 0 && layerIndex < mLayers.size()); + uint8 idx = layerIndex - 1; + return std::pair(idx / 4, idx % 4); + } + //--------------------------------------------------------------------- + void Terrain::_setNormalMapRequired(bool normalMap) + { + if (normalMap != mNormalMapRequired) + { + mNormalMapRequired = normalMap; + + // Check NPOT textures supported. We have to use NPOT textures to map + // texels to vertices directly! + if (!mNormalMapRequired && Root::getSingleton().getRenderSystem() + ->getCapabilities()->hasCapability(RSC_NON_POWER_OF_2_TEXTURES)) + { + mNormalMapRequired = false; + LogManager::getSingleton().stream(LML_CRITICAL) << + "Terrain: Ignoring request for normal map generation since " + "non-power-of-two texture support is required."; + } + + createOrDestroyGPUNormalMap(); + + // if we enabled, generate normal maps + if (mNormalMapRequired) + { + // update derived data for whole terrain, but just normals + mDirtyDerivedDataRect.left = mDirtyDerivedDataRect.top = 0; + mDirtyDerivedDataRect.right = mDirtyDerivedDataRect.bottom = mSize; + updateDerivedData(false, DERIVED_DATA_NORMALS); + } + + } + } + //--------------------------------------------------------------------- + void Terrain::_setLightMapRequired(bool lightMap, bool shadowsOnly) + { + if (lightMap != mLightMapRequired || shadowsOnly != mLightMapShadowsOnly) + { + mLightMapRequired = lightMap; + mLightMapShadowsOnly = shadowsOnly; + + createOrDestroyGPULightmap(); + + // if we enabled, generate light maps + if (mLightMapRequired) + { + // update derived data for whole terrain, but just lightmap + mDirtyDerivedDataRect.left = mDirtyDerivedDataRect.top = 0; + mDirtyDerivedDataRect.right = mDirtyDerivedDataRect.bottom = mSize; + updateDerivedData(false, DERIVED_DATA_LIGHTMAP); + } + } + + } + //--------------------------------------------------------------------- + void Terrain::_setCompositeMapRequired(bool compositeMap) + { + if (compositeMap != mCompositeMapRequired) + { + mCompositeMapRequired = compositeMap; + + createOrDestroyGPUCompositeMap(); + + // if we enabled, generate composite maps + if (mCompositeMapRequired) + { + mCompositeMapDirtyRect.left = mCompositeMapDirtyRect.top = 0; + mCompositeMapDirtyRect.right = mCompositeMapDirtyRect.bottom = mSize; + updateCompositeMap(); + } + + } + + } + //--------------------------------------------------------------------- + bool Terrain::_getUseVertexCompression() const + { + return mMaterialGenerator->isVertexCompressionSupported() && + TerrainGlobalOptions::getSingleton().getUseVertexCompressionWhenAvailable(); + } + //--------------------------------------------------------------------- + bool Terrain::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + if(req->getType()==WORKQUEUE_DERIVED_DATA_REQUEST) + { + DerivedDataRequest ddr = any_cast(req->getData()); + // only deal with own requests + // we do this because if we delete a terrain we want any pending tasks to be discarded + if (ddr.terrain != this) + return false; + } + else if(req->getType()==WORKQUEUE_GENERATE_MATERIAL_REQUEST) + { + GenerateMaterialRequest gmreq = any_cast(req->getData()); + if (gmreq.terrain != this) + return false; + } + + return RequestHandler::canHandleRequest(req, srcQ); + + } + //--------------------------------------------------------------------- + bool Terrain::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + const WorkQueue::Request* req = res->getRequest(); + if(req->getType()==WORKQUEUE_DERIVED_DATA_REQUEST) + { + DerivedDataRequest ddreq = any_cast(req->getData()); + // only deal with own requests + // we do this because if we delete a terrain we want any pending tasks to be discarded + if (ddreq.terrain != this) + return false; + } + else if(req->getType()==WORKQUEUE_GENERATE_MATERIAL_REQUEST) + { + GenerateMaterialRequest gmreq = any_cast(req->getData()); + if (gmreq.terrain != this) + return false; + } + return true; + } + //--------------------------------------------------------------------- + WorkQueue::Response* Terrain::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + // Background thread (maybe) + if(req->getType()==WORKQUEUE_GENERATE_MATERIAL_REQUEST) + { + return OGRE_NEW WorkQueue::Response(req, true, Any()); + } + + DerivedDataRequest ddr = any_cast(req->getData()); + DerivedDataResponse ddres; + ddres.remainingTypeMask = ddr.typeMask & DERIVED_DATA_ALL; + + // Do only ONE type of task per background iteration, in order of priority + // this means we return faster, can abort faster and we repeat less redundant calcs + // we don't do this as separate requests, because we only want one background + // task per Terrain instance in flight at once + if (ddr.typeMask & DERIVED_DATA_DELTAS) + { + ddres.deltaUpdateRect = calculateHeightDeltas(ddr.dirtyRect); + ddres.remainingTypeMask &= ~ DERIVED_DATA_DELTAS; + } + else if (ddr.typeMask & DERIVED_DATA_NORMALS) + { + ddres.normalMapBox = calculateNormals(ddr.dirtyRect, ddres.normalUpdateRect); + ddres.remainingTypeMask &= ~ DERIVED_DATA_NORMALS; + } + else if (ddr.typeMask & DERIVED_DATA_LIGHTMAP) + { + ddres.lightMapBox = calculateLightmap(ddr.dirtyRect, ddr.lightmapExtraDirtyRect, ddres.lightmapUpdateRect); + ddres.remainingTypeMask &= ~ DERIVED_DATA_LIGHTMAP; + } + + ddres.terrain = ddr.terrain; + WorkQueue::Response* response = OGRE_NEW WorkQueue::Response(req, true, Any(ddres)); + return response; + } + //--------------------------------------------------------------------- + void Terrain::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + // Main thread + if(res->getRequest()->getType()==WORKQUEUE_GENERATE_MATERIAL_REQUEST) + { + handleGenerateMaterialResponse(res,srcQ); + return; + } + + DerivedDataResponse ddres = any_cast(res->getData()); + DerivedDataRequest ddreq = any_cast(res->getRequest()->getData()); + + // only deal with own requests + if (ddreq.terrain != this) + return; + + if ((ddreq.typeMask & DERIVED_DATA_DELTAS) && + !(ddres.remainingTypeMask & DERIVED_DATA_DELTAS)) + finaliseHeightDeltas(ddres.deltaUpdateRect, false); + if ((ddreq.typeMask & DERIVED_DATA_NORMALS) && + !(ddres.remainingTypeMask & DERIVED_DATA_NORMALS)) + { + finaliseNormals(ddres.normalUpdateRect, ddres.normalMapBox); + mCompositeMapDirtyRect.merge(ddreq.dirtyRect); + } + if ((ddreq.typeMask & DERIVED_DATA_LIGHTMAP) && + !(ddres.remainingTypeMask & DERIVED_DATA_LIGHTMAP)) + { + finaliseLightmap(ddres.lightmapUpdateRect, ddres.lightMapBox); + mCompositeMapDirtyRect.merge(ddreq.dirtyRect); + mCompositeMapDirtyRectLightmapUpdate = true; + } + + mDerivedDataUpdateInProgress = false; + + // Re-trigger another request if there are still things to do, or if + // we had a new request since this one + Rect newRect(0,0,0,0); + if (ddres.remainingTypeMask) + newRect.merge(ddreq.dirtyRect); + if (mDerivedUpdatePendingMask) + { + newRect.merge(mDirtyDerivedDataRect); + mDirtyDerivedDataRect.setNull(); + } + Rect newLightmapExtraRect(0,0,0,0); + if (ddres.remainingTypeMask) + newLightmapExtraRect.merge(ddreq.lightmapExtraDirtyRect); + if (mDerivedUpdatePendingMask) + { + newLightmapExtraRect.merge(mDirtyLightmapFromNeighboursRect); + mDirtyLightmapFromNeighboursRect.setNull(); + } + uint8 newMask = ddres.remainingTypeMask | mDerivedUpdatePendingMask; + if (newMask) + { + // trigger again + updateDerivedDataImpl(newRect, newLightmapExtraRect, false, newMask); + } + else + { + // we've finished all the background processes + // update the composite map if enabled + if (mCompositeMapRequired) + updateCompositeMap(); + } + + } + //--------------------------------------------------------------------- + void Terrain::handleGenerateMaterialResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + GenerateMaterialRequest gmreq = any_cast(res->getRequest()->getData()); + unsigned long currentTime = Root::getSingletonPtr()->getTimer()->getMilliseconds(); + + // process + switch(gmreq.stage) + { + case GEN_MATERIAL: + mMaterial = mMaterialGenerator->generate(this); + mMaterial->load(); + // init next stage + if (mCompositeMapRequired) + { + gmreq.stage = GEN_COMPOSITE_MAP_MATERIAL; + gmreq.startTime = currentTime + TERRAIN_GENERATE_MATERIAL_INTERVAL_MS; + Root::getSingleton().getWorkQueue()->addRequest( + mWorkQueueChannel, WORKQUEUE_GENERATE_MATERIAL_REQUEST, + Any(gmreq), 0, gmreq.synchronous); + return; + } + break; + case GEN_COMPOSITE_MAP_MATERIAL: + mCompositeMapMaterial = mMaterialGenerator->generateForCompositeMap(this); + mCompositeMapMaterial->load(); + break; + } + mMaterialGenerationCount = mMaterialGenerator->getChangeCount(); + mMaterialDirty = false; + + mGenerateMaterialInProgress = false; + mIsLoaded = true; + } + //--------------------------------------------------------------------- + uint16 Terrain::getLODLevelWhenVertexEliminated(long x, long y) const + { + // gets eliminated by either row or column first + return std::min(getLODLevelWhenVertexEliminated(x), getLODLevelWhenVertexEliminated(y)); + } + //--------------------------------------------------------------------- + uint16 Terrain::getLODLevelWhenVertexEliminated(long rowOrColulmn) const + { + // LOD levels bisect the domain. + // start at the lowest detail + uint16 currentElim = (mSize - 1) / (mMinBatchSize - 1); + // start at a non-exitant LOD index, this applies to the min batch vertices + // which are never eliminated + uint16 currentLod = mNumLodLevels; + + while (rowOrColulmn % currentElim) + { + // not on this boundary, look finer + currentElim = currentElim / 2; + --currentLod; + + // This will always terminate since (anything % 1 == 0) + } + + return currentLod; + } + //--------------------------------------------------------------------- + PixelBox* Terrain::calculateNormals(const Rect &rect, Rect& finalRect) + { + // Widen the rectangle by 1 element in all directions since height + // changes affect neighbours normals + Rect widenedRect( + std::max(0L, rect.left - 1L), + std::max(0L, rect.top - 1L), + std::min((long)mSize, rect.right + 1L), + std::min((long)mSize, rect.bottom + 1L) + ); + // allocate memory for RGB + uint8* pData = static_cast( + OGRE_MALLOC(widenedRect.width() * widenedRect.height() * 3, MEMCATEGORY_GENERAL)); + + PixelBox* pixbox = OGRE_NEW PixelBox(static_cast(widenedRect.width()), + static_cast(widenedRect.height()), 1, PF_BYTE_RGB, pData); + + // Evaluate normal like this + // 3---2---1 + // | \ | / | + // 4---P---0 + // | / | \ | + // 5---6---7 + + Plane plane; + for (long y = widenedRect.top; y < widenedRect.bottom; ++y) + { + for (long x = widenedRect.left; x < widenedRect.right; ++x) + { + Vector3 cumulativeNormal = Vector3::ZERO; + + // Build points to sample + Vector3 centrePoint; + Vector3 adjacentPoints[8]; + getPointFromSelfOrNeighbour(x , y, ¢rePoint); + getPointFromSelfOrNeighbour(x+1, y, &adjacentPoints[0]); + getPointFromSelfOrNeighbour(x+1, y+1, &adjacentPoints[1]); + getPointFromSelfOrNeighbour(x, y+1, &adjacentPoints[2]); + getPointFromSelfOrNeighbour(x-1, y+1, &adjacentPoints[3]); + getPointFromSelfOrNeighbour(x-1, y, &adjacentPoints[4]); + getPointFromSelfOrNeighbour(x-1, y-1, &adjacentPoints[5]); + getPointFromSelfOrNeighbour(x, y-1, &adjacentPoints[6]); + getPointFromSelfOrNeighbour(x+1, y-1, &adjacentPoints[7]); + + for (int i = 0; i < 8; ++i) + { + plane.redefine(centrePoint, adjacentPoints[i], adjacentPoints[(i+1)%8]); + cumulativeNormal += plane.normal; + } + + // normalise & store normal + cumulativeNormal.normalise(); + + // encode as RGB, object space + // invert the Y to deal with image space + long storeX = x - widenedRect.left; + long storeY = widenedRect.bottom - y - 1; + + uint8* pStore = pData + ((storeY * widenedRect.width()) + storeX) * 3; + *pStore++ = static_cast((cumulativeNormal.x + 1.0f) * 0.5f * 255.0f); + *pStore++ = static_cast((cumulativeNormal.y + 1.0f) * 0.5f * 255.0f); + *pStore++ = static_cast((cumulativeNormal.z + 1.0f) * 0.5f * 255.0f); + + + } + } + + finalRect = widenedRect; + + return pixbox; + } + //--------------------------------------------------------------------- + void Terrain::finaliseNormals(const Ogre::Rect &rect, Ogre::PixelBox *normalsBox) + { + createOrDestroyGPUNormalMap(); + // deal with race condition where nm has been disabled while we were working! + if (!mTerrainNormalMap.isNull()) + { + // blit the normals into the texture + if (rect.left == 0 && rect.top == 0 && rect.bottom == mSize && rect.right == mSize) + { + mTerrainNormalMap->getBuffer()->blitFromMemory(*normalsBox); + } + else + { + // content of normalsBox is already inverted in Y, but rect is still + // in terrain space for dealing with sub-rect, so invert + Image::Box dstBox; + dstBox.left = static_cast(rect.left); + dstBox.right = static_cast(rect.right); + dstBox.top = static_cast(mSize - rect.bottom); + dstBox.bottom = static_cast(mSize - rect.top); + mTerrainNormalMap->getBuffer()->blitFromMemory(*normalsBox, dstBox); + } + } + + + // delete memory + OGRE_FREE(normalsBox->data, MEMCATEGORY_GENERAL); + OGRE_DELETE(normalsBox); + + } + //--------------------------------------------------------------------- + void Terrain::widenRectByVector(const Vector3& vec, const Rect& inRect, Rect& outRect) + { + widenRectByVector(vec, inRect, getMinHeight(), getMaxHeight(), outRect); + } + //--------------------------------------------------------------------- + void Terrain::widenRectByVector(const Vector3& vec, const Rect& inRect, + Real minHeight, Real maxHeight, Rect& outRect) + { + + outRect = inRect; + + Plane p; + switch(getAlignment()) + { + case ALIGN_X_Y: + p.redefine(Vector3::UNIT_Z, Vector3(0, 0, vec.z < 0.0 ? minHeight : maxHeight)); + break; + case ALIGN_X_Z: + p.redefine(Vector3::UNIT_Y, Vector3(0, vec.y < 0.0 ? minHeight : maxHeight, 0)); + break; + case ALIGN_Y_Z: + p.redefine(Vector3::UNIT_X, Vector3(vec.x < 0.0 ? minHeight : maxHeight, 0, 0)); + break; + } + float verticalVal = vec.dotProduct(p.normal); + + if (Math::RealEqual(verticalVal, 0.0)) + return; + + Vector3 corners[4]; + Real startHeight = verticalVal < 0.0 ? maxHeight : minHeight; + getPoint(inRect.left, inRect.top, startHeight, &corners[0]); + getPoint(inRect.right-1, inRect.top, startHeight, &corners[1]); + getPoint(inRect.left, inRect.bottom-1, startHeight, &corners[2]); + getPoint(inRect.right-1, inRect.bottom-1, startHeight, &corners[3]); + + for (int i = 0; i < 4; ++i) + { + Ray ray(corners[i] + mPos, vec); + std::pair rayHit = ray.intersects(p); + if(rayHit.first) + { + Vector3 pt = ray.getPoint(rayHit.second); + // convert back to terrain point + Vector3 terrainHitPos; + getTerrainPosition(pt, &terrainHitPos); + // build rectangle which has rounded down & rounded up values + // remember right & bottom are exclusive + Rect mergeRect( + (long)(terrainHitPos.x * (mSize - 1)), + (long)(terrainHitPos.y * (mSize - 1)), + (long)(terrainHitPos.x * (float)(mSize - 1) + 0.5) + 1, + (long)(terrainHitPos.y * (float)(mSize - 1) + 0.5) + 1 + ); + outRect.merge(mergeRect); + } + } + + } + //--------------------------------------------------------------------- + PixelBox* Terrain::calculateLightmap(const Rect& rect, const Rect& extraTargetRect, Rect& outFinalRect) + { + // as well as calculating the lighting changes for the area that is + // dirty, we also need to calculate the effect on casting shadow on + // other areas. To do this, we project the dirt rect by the light direction + // onto the minimum height + + + const Vector3& lightVec = TerrainGlobalOptions::getSingleton().getLightMapDirection(); + Ogre::Rect widenedRect; + widenRectByVector(lightVec, rect, widenedRect); + + // merge in the extra area (e.g. from neighbours) + widenedRect.merge(extraTargetRect); + + // widenedRect now contains terrain point space version of the area we + // need to calculate. However, we need to calculate in lightmap image space + float terrainToLightmapScale = (float)mLightmapSizeActual / (float)mSize; + widenedRect.left = (long)(widenedRect.left * terrainToLightmapScale); + widenedRect.right = (long)(widenedRect.right * terrainToLightmapScale); + widenedRect.top = (long)(widenedRect.top * terrainToLightmapScale); + widenedRect.bottom = (long)(widenedRect.bottom * terrainToLightmapScale); + + // clamp + widenedRect.left = std::max(0L, widenedRect.left); + widenedRect.top = std::max(0L, widenedRect.top); + widenedRect.right = std::min((long)mLightmapSizeActual, widenedRect.right); + widenedRect.bottom = std::min((long)mLightmapSizeActual, widenedRect.bottom); + + outFinalRect = widenedRect; + + // allocate memory (L8) + uint8* pData = static_cast( + OGRE_MALLOC(widenedRect.width() * widenedRect.height(), MEMCATEGORY_GENERAL)); + + PixelBox* pixbox = OGRE_NEW PixelBox(static_cast(widenedRect.width()), + static_cast(widenedRect.height()), 1, PF_L8, pData); + + Real heightPad = (getMaxHeight() - getMinHeight()) * 1.0e-3f; + + for (long y = widenedRect.top; y < widenedRect.bottom; ++y) + { + for (long x = widenedRect.left; x < widenedRect.right; ++x) + { + float litVal = 1.0f; + + // convert to terrain space (not points, allow this to go between points) + float Tx = (float)x / (float)(mLightmapSizeActual-1); + float Ty = (float)y / (float)(mLightmapSizeActual-1); + + // get world space point + // add a little height padding to stop shadowing self + Vector3 wpos = Vector3::ZERO; + getPosition(Tx, Ty, getHeightAtTerrainPosition(Tx, Ty) + heightPad, &wpos); + wpos += getPosition(); + // build ray, cast backwards along light direction + Ray ray(wpos, -lightVec); + + // Cascade into neighbours when casting, but don't travel further + // than world size + std::pair rayHit = rayIntersects(ray, true, mWorldSize); + + if (rayHit.first) + litVal = 0.0f; + + // encode as L8 + // invert the Y to deal with image space + long storeX = x - widenedRect.left; + long storeY = widenedRect.bottom - y - 1; + + uint8* pStore = pData + ((storeY * widenedRect.width()) + storeX); + *pStore = (unsigned char)(litVal * 255.0); + + } + } + + return pixbox; + + + } + //--------------------------------------------------------------------- + void Terrain::finaliseLightmap(const Rect& rect, PixelBox* lightmapBox) + { + createOrDestroyGPULightmap(); + // deal with race condition where lm has been disabled while we were working! + if (!mLightmap.isNull()) + { + // blit the normals into the texture + if (rect.left == 0 && rect.top == 0 && rect.bottom == mLightmapSizeActual && rect.right == mLightmapSizeActual) + { + mLightmap->getBuffer()->blitFromMemory(*lightmapBox); + } + else + { + // content of PixelBox is already inverted in Y, but rect is still + // in terrain space for dealing with sub-rect, so invert + Image::Box dstBox; + dstBox.left = static_cast(rect.left); + dstBox.right = static_cast(rect.right); + dstBox.top = static_cast(mLightmapSizeActual - rect.bottom); + dstBox.bottom = static_cast(mLightmapSizeActual - rect.top); + mLightmap->getBuffer()->blitFromMemory(*lightmapBox, dstBox); + } + } + + // delete memory + OGRE_FREE(lightmapBox->data, MEMCATEGORY_GENERAL); + OGRE_DELETE(lightmapBox); + + + } + //--------------------------------------------------------------------- + void Terrain::updateCompositeMap() + { + // All done in the render thread + if (mCompositeMapRequired && !mCompositeMapDirtyRect.isNull()) + { + mModified = true; + createOrDestroyGPUCompositeMap(); + if (mCompositeMapDirtyRectLightmapUpdate && + (mCompositeMapDirtyRect.width() < mSize || mCompositeMapDirtyRect.height() < mSize)) + { + // widen the dirty rectangle since lighting makes it wider + Rect widenedRect; + widenRectByVector(TerrainGlobalOptions::getSingleton().getLightMapDirection(), mCompositeMapDirtyRect, widenedRect); + // clamp + widenedRect.left = std::max(widenedRect.left, 0L); + widenedRect.top = std::max(widenedRect.top, 0L); + widenedRect.right = std::min(widenedRect.right, (long)mSize); + widenedRect.bottom = std::min(widenedRect.bottom, (long)mSize); + mMaterialGenerator->updateCompositeMap(this, widenedRect); + } + else + mMaterialGenerator->updateCompositeMap(this, mCompositeMapDirtyRect); + + mCompositeMapDirtyRectLightmapUpdate = false; + mCompositeMapDirtyRect.setNull(); + + + } + } + //--------------------------------------------------------------------- + void Terrain::updateCompositeMapWithDelay(Real delay) + { + mCompositeMapUpdateCountdown = (long)(delay * 1000); + } + //--------------------------------------------------------------------- + uint8 Terrain::getBlendTextureIndex(uint8 layerIndex) const + { + if (layerIndex == 0 || layerIndex-1 >= (uint8)mLayerBlendMapList.size()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid layer index", "Terrain::getBlendTextureIndex"); + + return (layerIndex - 1) % 4; + + } + //--------------------------------------------------------------------- + const String& Terrain::getBlendTextureName(uint8 textureIndex) const + { + if (textureIndex >= (uint8)mBlendTextureList.size()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid texture index", "Terrain::getBlendTextureName"); + + return mBlendTextureList[textureIndex]->getName(); + } + //--------------------------------------------------------------------- + void Terrain::setGlobalColourMapEnabled(bool enabled, uint16 sz) + { + if (!sz) + sz = TerrainGlobalOptions::getSingleton().getDefaultGlobalColourMapSize(); + + if (enabled != mGlobalColourMapEnabled || + (enabled && mGlobalColourMapSize != sz)) + { + mGlobalColourMapEnabled = enabled; + mGlobalColourMapSize = sz; + + createOrDestroyGPUColourMap(); + + mMaterialDirty = true; + mMaterialParamsDirty = true; + mModified = true; + } + + } + //--------------------------------------------------------------------- + void Terrain::createOrDestroyGPUColourMap() + { + if (mGlobalColourMapEnabled && mColourMap.isNull()) + { + // create + mColourMap = TextureManager::getSingleton().createManual( + mMaterialName + "/cm", _getDerivedResourceGroup(), + TEX_TYPE_2D, mGlobalColourMapSize, mGlobalColourMapSize, MIP_DEFAULT, + PF_BYTE_RGB, TU_AUTOMIPMAP|TU_STATIC); + + if (mCpuColourMapStorage) + { + // Load cached data + PixelBox src(mGlobalColourMapSize, mGlobalColourMapSize, 1, PF_BYTE_RGB, mCpuColourMapStorage); + mColourMap->getBuffer()->blitFromMemory(src); + // release CPU copy, don't need it anymore + OGRE_FREE(mCpuColourMapStorage, MEMCATEGORY_RESOURCE); + mCpuColourMapStorage = 0; + + } + } + else if (!mGlobalColourMapEnabled && !mColourMap.isNull()) + { + // destroy + TextureManager::getSingleton().remove(mColourMap->getHandle()); + mColourMap.setNull(); + } + + } + //--------------------------------------------------------------------- + void Terrain::createOrDestroyGPULightmap() + { + if (mLightMapRequired && mLightmap.isNull()) + { + // create + mLightmap = TextureManager::getSingleton().createManual( + mMaterialName + "/lm", _getDerivedResourceGroup(), + TEX_TYPE_2D, mLightmapSize, mLightmapSize, 0, PF_L8, TU_STATIC); + + mLightmapSizeActual = mLightmap->getWidth(); + + if (mCpuLightmapStorage) + { + // Load cached data + PixelBox src(mLightmapSize, mLightmapSize, 1, PF_L8, mCpuLightmapStorage); + mLightmap->getBuffer()->blitFromMemory(src); + // release CPU copy, don't need it anymore + OGRE_FREE(mCpuLightmapStorage, MEMCATEGORY_RESOURCE); + mCpuLightmapStorage = 0; + + } + else + { + // initialise to full-bright + Box box(0, 0, mLightmapSizeActual, mLightmapSizeActual); + HardwarePixelBufferSharedPtr buf = mLightmap->getBuffer(); + uint8* pInit = static_cast(buf->lock(box, HardwarePixelBuffer::HBL_DISCARD).data); + memset(pInit, 255, mLightmapSizeActual * mLightmapSizeActual); + buf->unlock(); + + } + } + else if (!mLightMapRequired && !mLightmap.isNull()) + { + // destroy + TextureManager::getSingleton().remove(mLightmap->getHandle()); + mLightmap.setNull(); + } + + } + //--------------------------------------------------------------------- + void Terrain::createOrDestroyGPUCompositeMap() + { + if (mCompositeMapRequired && mCompositeMap.isNull()) + { + // create + mCompositeMap = TextureManager::getSingleton().createManual( + mMaterialName + "/comp", _getDerivedResourceGroup(), + TEX_TYPE_2D, mCompositeMapSize, mCompositeMapSize, 0, PF_BYTE_RGBA, TU_STATIC); + + mCompositeMapSizeActual = mCompositeMap->getWidth(); + + if (mCpuCompositeMapStorage) + { + // Load cached data + PixelBox src(mCompositeMapSize, mCompositeMapSize, 1, PF_BYTE_RGBA, mCpuCompositeMapStorage); + mCompositeMap->getBuffer()->blitFromMemory(src); + // release CPU copy, don't need it anymore + OGRE_FREE(mCpuCompositeMapStorage, MEMCATEGORY_RESOURCE); + mCpuCompositeMapStorage = 0; + + } + else + { + // initialise to black + Box box(0, 0, mCompositeMapSizeActual, mCompositeMapSizeActual); + HardwarePixelBufferSharedPtr buf = mCompositeMap->getBuffer(); + uint8* pInit = static_cast(buf->lock(box, HardwarePixelBuffer::HBL_DISCARD).data); + memset(pInit, 0, mCompositeMapSizeActual * mCompositeMapSizeActual * 4); + buf->unlock(); + + } + } + else if (!mCompositeMapRequired && !mCompositeMap.isNull()) + { + // destroy + TextureManager::getSingleton().remove(mCompositeMap->getHandle()); + mCompositeMap.setNull(); + } + + } + //--------------------------------------------------------------------- + Terrain* Terrain::getNeighbour(NeighbourIndex index) const + { + return mNeighbours[index]; + } + //--------------------------------------------------------------------- + void Terrain::setNeighbour(NeighbourIndex index, Terrain* neighbour, + bool recalculate /*= false*/, bool notifyOther /* = true */) + { + if (mNeighbours[index] != neighbour) + { + assert(neighbour != this && "Can't set self as own neighbour!"); + + // detach existing + if (mNeighbours[index] && notifyOther) + mNeighbours[index]->setNeighbour(getOppositeNeighbour(index), 0, false, false); + + mNeighbours[index] = neighbour; + if (neighbour && notifyOther) + mNeighbours[index]->setNeighbour(getOppositeNeighbour(index), this, recalculate, false); + + if (recalculate) + { + // Recalculate, pass OUR edge rect + Rect edgerect; + getEdgeRect(index, 2, &edgerect); + neighbourModified(index, edgerect, edgerect); + } + } + } + //--------------------------------------------------------------------- + Terrain::NeighbourIndex Terrain::getOppositeNeighbour(NeighbourIndex index) + { + int intindex = static_cast(index); + intindex += NEIGHBOUR_COUNT / 2; + intindex = intindex % NEIGHBOUR_COUNT; + return static_cast(intindex); + } + //--------------------------------------------------------------------- + Terrain::NeighbourIndex Terrain::getNeighbourIndex(long x, long y) + { + if (x < 0) + { + if (y < 0) + return NEIGHBOUR_SOUTHWEST; + else if (y > 0) + return NEIGHBOUR_NORTHWEST; + else + return NEIGHBOUR_WEST; + } + else if (x > 0) + { + if (y < 0) + return NEIGHBOUR_SOUTHEAST; + else if (y > 0) + return NEIGHBOUR_NORTHEAST; + else + return NEIGHBOUR_EAST; + } + + if (y < 0) + { + if (x == 0) + return NEIGHBOUR_SOUTH; + } + else if (y > 0) + { + if (x == 0) + return NEIGHBOUR_NORTH; + } + + return NEIGHBOUR_NORTH; + + } + //--------------------------------------------------------------------- + void Terrain::notifyNeighbours() + { + // There are 3 things that can need updating: + // Height at edge - match to neighbour (first one to update 'loses' to other since read-only) + // Normal at edge - use heights from across boundary too + // Shadows across edge + // The extent to which these can affect the current tile vary: + // Height at edge - only affected by a change at the adjoining edge / corner + // Normal at edge - only affected by a change to the 2 rows adjoining the edge / corner + // Shadows across edge - possible effect extends based on the projection of the + // neighbour AABB along the light direction (worst case scenario) + + if (!mDirtyGeometryRectForNeighbours.isNull()) + { + Rect dirtyRectForNeighbours(mDirtyGeometryRectForNeighbours); + mDirtyGeometryRectForNeighbours.setNull(); + // calculate light update rectangle + const Vector3& lightVec = TerrainGlobalOptions::getSingleton().getLightMapDirection(); + Rect lightmapRect; + widenRectByVector(lightVec, dirtyRectForNeighbours, getMinHeight(), getMaxHeight(), lightmapRect); + + for (int i = 0; i < (int)NEIGHBOUR_COUNT; ++i) + { + NeighbourIndex ni = static_cast(i); + Terrain* neighbour = getNeighbour(ni); + if (!neighbour) + continue; + + // Intersect the incoming rectangles with the edge regions related to this neighbour + Rect edgeRect; + getEdgeRect(ni, 2, &edgeRect); + Rect heightEdgeRect = edgeRect.intersect(dirtyRectForNeighbours); + Rect lightmapEdgeRect = edgeRect.intersect(lightmapRect); + + if (!heightEdgeRect.isNull() || !lightmapRect.isNull()) + { + // ok, we have something valid to pass on + Rect neighbourHeightEdgeRect, neighbourLightmapEdgeRect; + if (!heightEdgeRect.isNull()) + getNeighbourEdgeRect(ni, heightEdgeRect, &neighbourHeightEdgeRect); + if (!lightmapRect.isNull()) + getNeighbourEdgeRect(ni, lightmapEdgeRect, &neighbourLightmapEdgeRect); + + neighbour->neighbourModified(getOppositeNeighbour(ni), + neighbourHeightEdgeRect, neighbourLightmapEdgeRect); + + } + + } + } + } + //--------------------------------------------------------------------- + void Terrain::neighbourModified(NeighbourIndex index, const Rect& edgerect, const Rect& shadowrect) + { + // We can safely assume that we would not have been contacted if it wasn't + // important + const Terrain* neighbour = getNeighbour(index); + if (!neighbour) + return; // bogus request + + bool updateGeom = false; + uint8 updateDerived = 0; + + + if (!edgerect.isNull()) + { + // update edges; match heights first, then recalculate normals + // reduce to just single line / corner + Rect heightMatchRect; + getEdgeRect(index, 1, &heightMatchRect); + heightMatchRect = heightMatchRect.intersect(edgerect); + + for (long y = heightMatchRect.top; y < heightMatchRect.bottom; ++y) + { + for (long x = heightMatchRect.left; x < heightMatchRect.right; ++x) + { + long nx, ny; + getNeighbourPoint(index, x, y, &nx, &ny); + float neighbourHeight = neighbour->getHeightAtPoint(nx, ny); + if (!Math::RealEqual(neighbourHeight, getHeightAtPoint(x, y), 1e-3f)) + { + setHeightAtPoint(x, y, neighbourHeight); + if (!updateGeom) + { + updateGeom = true; + updateDerived |= DERIVED_DATA_ALL; + } + + } + } + } + // if we didn't need to update heights, we still need to update normals + // because this was called only if neighbor changed + if (!updateGeom) + { + // ideally we would deal with normal dirty rect separately (as we do with + // lightmaps) because a dirty geom rectangle will actually grow by one + // element in each direction for normals recalculation. However for + // the sake of one row/column it's really not worth it. + mDirtyDerivedDataRect.merge(edgerect); + updateDerived |= DERIVED_DATA_NORMALS; + } + } + + if (!shadowrect.isNull()) + { + // update shadows + // here we need to widen the rect passed in based on the min/max height + // of the *neighbour* + const Vector3& lightVec = TerrainGlobalOptions::getSingleton().getLightMapDirection(); + Rect widenedRect; + widenRectByVector(lightVec, shadowrect, neighbour->getMinHeight(), neighbour->getMaxHeight(), widenedRect); + + // set the special-case lightmap dirty rectangle + mDirtyLightmapFromNeighboursRect.merge(widenedRect); + updateDerived |= DERIVED_DATA_LIGHTMAP; + } + + if (updateGeom) + updateGeometry(); + if (updateDerived) + updateDerivedData(false, updateDerived); + + + + } + //--------------------------------------------------------------------- + void Terrain::getEdgeRect(NeighbourIndex index, long range, Rect* outRect) const + { + // We make the edge rectangle 2 rows / columns at the edge of the tile + // 2 because this copes with normal changes and potentially filtered + // shadows. + // all right / bottom values are exclusive + // terrain origin is bottom-left remember so north is highest value + + // set left/right + switch(index) + { + case NEIGHBOUR_EAST: + case NEIGHBOUR_NORTHEAST: + case NEIGHBOUR_SOUTHEAST: + outRect->left = mSize - range; + outRect->right = mSize; + break; + case NEIGHBOUR_WEST: + case NEIGHBOUR_NORTHWEST: + case NEIGHBOUR_SOUTHWEST: + outRect->left = 0; + outRect->right = range; + break; + case NEIGHBOUR_NORTH: + case NEIGHBOUR_SOUTH: + outRect->left = 0; + outRect->right = mSize; + break; + case NEIGHBOUR_COUNT: + default: + break; + }; + + // set top / bottom + switch(index) + { + case NEIGHBOUR_NORTH: + case NEIGHBOUR_NORTHEAST: + case NEIGHBOUR_NORTHWEST: + outRect->top = mSize - range; + outRect->bottom = mSize; + break; + case NEIGHBOUR_SOUTH: + case NEIGHBOUR_SOUTHWEST: + case NEIGHBOUR_SOUTHEAST: + outRect->top = 0; + outRect->bottom = range; + break; + case NEIGHBOUR_EAST: + case NEIGHBOUR_WEST: + outRect->top = 0; + outRect->bottom = mSize; + break; + case NEIGHBOUR_COUNT: + default: + break; + }; + } + //--------------------------------------------------------------------- + void Terrain::getNeighbourEdgeRect(NeighbourIndex index, const Rect& inRect, Rect* outRect) const + { + assert (mSize == getNeighbour(index)->getSize()); + + // Basically just reflect the rect + // remember index is neighbour relationship from OUR perspective so + // arrangement is backwards to getEdgeRect + + // left/right + switch(index) + { + case NEIGHBOUR_EAST: + case NEIGHBOUR_NORTHEAST: + case NEIGHBOUR_SOUTHEAST: + case NEIGHBOUR_WEST: + case NEIGHBOUR_NORTHWEST: + case NEIGHBOUR_SOUTHWEST: + outRect->left = mSize - inRect.right; + outRect->right = mSize - inRect.left; + break; + default: + outRect->left = inRect.left; + outRect->right = inRect.right; + break; + }; + + // top / bottom + switch(index) + { + case NEIGHBOUR_NORTH: + case NEIGHBOUR_NORTHEAST: + case NEIGHBOUR_NORTHWEST: + case NEIGHBOUR_SOUTH: + case NEIGHBOUR_SOUTHWEST: + case NEIGHBOUR_SOUTHEAST: + outRect->top = mSize - inRect.bottom; + outRect->bottom = mSize - inRect.top; + break; + default: + outRect->top = inRect.top; + outRect->bottom = inRect.bottom; + break; + }; + + } + //--------------------------------------------------------------------- + void Terrain::getNeighbourPoint(NeighbourIndex index, long x, long y, long *outx, long *outy) const + { + // Get the index of the point we should be looking at on a neighbour + // in order to match up points + assert (mSize == getNeighbour(index)->getSize()); + + // left/right + switch(index) + { + case NEIGHBOUR_EAST: + case NEIGHBOUR_NORTHEAST: + case NEIGHBOUR_SOUTHEAST: + case NEIGHBOUR_WEST: + case NEIGHBOUR_NORTHWEST: + case NEIGHBOUR_SOUTHWEST: + *outx = mSize - x - 1; + break; + default: + *outx = x; + break; + }; + + // top / bottom + switch(index) + { + case NEIGHBOUR_NORTH: + case NEIGHBOUR_NORTHEAST: + case NEIGHBOUR_NORTHWEST: + case NEIGHBOUR_SOUTH: + case NEIGHBOUR_SOUTHWEST: + case NEIGHBOUR_SOUTHEAST: + *outy = mSize - y - 1; + break; + default: + *outy = y; + break; + }; + } + //--------------------------------------------------------------------- + void Terrain::getPointFromSelfOrNeighbour(long x, long y, Vector3* outpos) const + { + if (x >= 0 && y >=0 && x < mSize && y < mSize) + getPoint(x, y, outpos); + else + { + long nx, ny; + NeighbourIndex ni = NEIGHBOUR_EAST; + getNeighbourPointOverflow(x, y, &ni, &nx, &ny); + Terrain* neighbour = getNeighbour(ni); + if (neighbour) + { + Vector3 neighbourPos = Vector3::ZERO; + neighbour->getPoint(nx, ny, &neighbourPos); + // adjust to make it relative to our position + *outpos = neighbourPos + neighbour->getPosition() - getPosition(); + } + else + { + // use our getPoint() after all, just clamp + x = std::min(x, mSize - 1L); + y = std::min(y, mSize - 1L); + x = std::max(x, 0L); + y = std::max(y, 0L); + getPoint(x, y, outpos); + } + + } + } + //--------------------------------------------------------------------- + void Terrain::getNeighbourPointOverflow(long x, long y, NeighbourIndex *outindex, long *outx, long *outy) const + { + if (x < 0) + { + *outx = x + mSize - 1; + if (y < 0) + *outindex = NEIGHBOUR_SOUTHWEST; + else if (y >= mSize) + *outindex = NEIGHBOUR_NORTHWEST; + else + *outindex = NEIGHBOUR_WEST; + } + else if (x >= mSize) + { + *outx = x - mSize + 1; + if (y < 0) + *outindex = NEIGHBOUR_SOUTHEAST; + else if (y >= mSize) + *outindex = NEIGHBOUR_NORTHEAST; + else + *outindex = NEIGHBOUR_EAST; + } + else + *outx = x; - LayerInstanceList::iterator i = mLayers.begin(); - std::advance(i, index); - mLayers.erase(i); + if (y < 0) + { + *outy = y + mSize - 1; + if (x >= 0 && x < mSize) + *outindex = NEIGHBOUR_SOUTH; + } + else if (y >= mSize) + { + *outy = y - mSize + 1; + if (x >= 0 && x < mSize) + *outindex = NEIGHBOUR_NORTH; + } + else + *outy = y; + } + //--------------------------------------------------------------------- + Terrain* Terrain::raySelectNeighbour(const Ray& ray, Real distanceLimit /* = 0 */) + { + Ray modifiedRay(ray.getOrigin(), ray.getDirection()); + // Move back half a square - if we're on the edge of the AABB we might + // miss the intersection otherwise; it's ok for everywhere else since + // we want the far intersection anyway + modifiedRay.setOrigin(modifiedRay.getPoint(-mWorldSize/mSize * 0.5f)); + + // transform into terrain space + Vector3 tPos, tDir; + convertPosition(WORLD_SPACE, modifiedRay.getOrigin(), TERRAIN_SPACE, tPos); + convertDirection(WORLD_SPACE, modifiedRay.getDirection(), TERRAIN_SPACE, tDir); + // Discard rays with no lateral component + if (Math::RealEqual(tDir.x, 0.0f, 1e-4) && Math::RealEqual(tDir.y, 0.0f, 1e-4)) + return 0; + + Ray terrainRay(tPos, tDir); + // Intersect with boundary planes + // Only collide with the positive (exit) side of the plane, because we may be + // querying from a point outside ourselves if we've cascaded more than once + Real dist = std::numeric_limits::max(); + std::pair intersectResult; + if (tDir.x < 0.0f) + { + intersectResult = Math::intersects(terrainRay, Plane(Vector3::UNIT_X, Vector3::ZERO)); + if (intersectResult.first && intersectResult.second < dist) + dist = intersectResult.second; + } + else if (tDir.x > 0.0f) + { + intersectResult = Math::intersects(terrainRay, Plane(Vector3::NEGATIVE_UNIT_X, Vector3(1,0,0))); + if (intersectResult.first && intersectResult.second < dist) + dist = intersectResult.second; + } + if (tDir.y < 0.0f) + { + intersectResult = Math::intersects(terrainRay, Plane(Vector3::UNIT_Y, Vector3::ZERO)); + if (intersectResult.first && intersectResult.second < dist) + dist = intersectResult.second; + } + else if (tDir.y > 0.0f) + { + intersectResult = Math::intersects(terrainRay, Plane(Vector3::NEGATIVE_UNIT_Y, Vector3(0,1,0))); + if (intersectResult.first && intersectResult.second < dist) + dist = intersectResult.second; + } - RealVector::iterator uvi = mLayerUVMultiplier.begin(); - std::advance(uvi, index); - mLayerUVMultiplier.erase(uvi); - if (mLayerBlendMapList.size() > 0) - { - // If they removed the base OR the first layer, we need to erase the first blend map - TerrainLayerBlendMapList::iterator bi = mLayerBlendMapList.begin(); - std::advance(bi, blendIndex); - OGRE_DELETE *bi; - mLayerBlendMapList.erase(bi); + // discard out of range + if (dist * mWorldSize > distanceLimit) + return 0; - // Check to see if a GPU textures can be released - checkLayers(true); + Vector3 terrainIntersectPos = terrainRay.getPoint(dist); + Real x = terrainIntersectPos.x; + Real y = terrainIntersectPos.y; + Real dx = tDir.x; + Real dy = tDir.y; - // All blend maps for layers above the erased will need to be recreated since their buffers/channels have changed - deleteBlendMaps(blendIndex); - } - - mMaterialDirty = true; - mMaterialParamsDirty = true; - mModified = true; - } - } - //--------------------------------------------------------------------- - uint8 Terrain::getMaxLayers() const - { - return mMaterialGenerator->getMaxLayers(this); - } - //--------------------------------------------------------------------- - TerrainLayerBlendMap* Terrain::getLayerBlendMap(uint8 layerIndex) - { - if (layerIndex == 0 || layerIndex-1 >= (uint8)mLayerBlendMapList.size()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid layer index", "Terrain::getLayerBlendMap"); - - uint8 idx = layerIndex - 1; - if (!mLayerBlendMapList[idx]) - { - if (mBlendTextureList.size() < static_cast(idx / 4)) - checkLayers(true); - - const TexturePtr& tex = mBlendTextureList[idx / 4]; - mLayerBlendMapList[idx] = OGRE_NEW TerrainLayerBlendMap(this, layerIndex, tex->getBuffer().getPointer()); - } - - return mLayerBlendMapList[idx]; - - } - //--------------------------------------------------------------------- - uint8 Terrain::getBlendTextureCount(uint8 numLayers) const - { - return ((numLayers - 2) / 4) + 1; - } - //--------------------------------------------------------------------- - uint8 Terrain::getBlendTextureCount() const - { - return (uint8)mBlendTextureList.size(); - } - //--------------------------------------------------------------------- - PixelFormat Terrain::getBlendTextureFormat(uint8 textureIndex, uint8 numLayers) const - { - /* - if (numLayers - 1 - (textureIndex * 4) > 3) - return PF_BYTE_RGBA; - else - return PF_BYTE_RGB; - */ - // Always create RGBA; no point trying to create RGB since all cards pad to 32-bit (XRGB) - // and it makes it harder to expand layer count dynamically if format has to change - return PF_BYTE_RGBA; - } - //--------------------------------------------------------------------- - void Terrain::shiftUpGPUBlendChannels(uint8 index) - { - // checkLayers() has been called to make sure the blend textures have been created - assert( mBlendTextureList.size() == getBlendTextureCount(getLayerCount()) ); + // Never return diagonal directions, we will navigate those recursively anyway + if (Math::RealEqual(x, 1.0f, 1e-4f) && dx > 0) + return getNeighbour(NEIGHBOUR_EAST); + else if (Math::RealEqual(x, 0.0f, 1e-4f) && dx < 0) + return getNeighbour(NEIGHBOUR_WEST); + else if (Math::RealEqual(y, 1.0f, 1e-4f) && dy > 0) + return getNeighbour(NEIGHBOUR_NORTH); + else if (Math::RealEqual(y, 0.0f, 1e-4f) && dy < 0) + return getNeighbour(NEIGHBOUR_SOUTH); - // Shift all blend channels > index UP one slot, possibly into the next texture - // Example: index = 2 - // Before: [1 2 3 4] [5] - // After: [1 2 0 3] [4 5] - uint8 layerIndex = index + 1; - for (uint8 i=getLayerCount()-1; i > layerIndex; --i ) - { - std::pair destPair = getLayerBlendTextureIndex(i); - std::pair srcPair = getLayerBlendTextureIndex(i - 1); - - copyBlendTextureChannel( srcPair.first, srcPair.second, destPair.first, destPair.second ); - } - // Reset the layer to black - std::pair layerPair = getLayerBlendTextureIndex(layerIndex); - clearGPUBlendChannel( layerPair.first, layerPair.second ); + return 0; } - //--------------------------------------------------------------------- - void Terrain::shiftDownGPUBlendChannels(uint8 index) + //--------------------------------------------------------------------- + void Terrain::_dumpTextures(const String& prefix, const String& suffix) { - // checkLayers() has been called to make sure the blend textures have been created - assert( mBlendTextureList.size() == getBlendTextureCount(getLayerCount()) ); + if (!mTerrainNormalMap.isNull()) + { + Image img; + mTerrainNormalMap->convertToImage(img); + img.save(prefix + "_normalmap" + suffix); + } - // Shift all blend channels above layerIndex DOWN one slot, possibly into the previous texture - // Example: index = 2 - // Before: [1 2 3 4] [5] - // After: [1 2 4 5] [0] + if (!mColourMap.isNull()) + { + Image img; + mColourMap->convertToImage(img); + img.save(prefix + "_colourmap" + suffix); + } - uint8 layerIndex = index + 1; - for (uint8 i=layerIndex; i < getLayerCount() - 1; ++i ) - { - std::pair destPair = getLayerBlendTextureIndex(i); - std::pair srcPair = getLayerBlendTextureIndex(i + 1); - - copyBlendTextureChannel( srcPair.first, srcPair.second, destPair.first, destPair.second ); + if (!mLightmap.isNull()) + { + Image img; + mLightmap->convertToImage(img); + img.save(prefix + "_lightmap" + suffix); } - // Reset the layer to black - if ( getLayerCount() > 1 ) + if (!mCompositeMap.isNull()) { - std::pair layerPair = getLayerBlendTextureIndex(getLayerCount() - 1); - clearGPUBlendChannel( layerPair.first, layerPair.second ); + Image img; + mCompositeMap->convertToImage(img); + img.save(prefix + "_compositemap" + suffix); + } + + int blendTexture = 0; + for (TexturePtrList::iterator i = mBlendTextureList.begin(); i != mBlendTextureList.end(); ++i, ++blendTexture) + { + if (!i->isNull()) + { + Image img; + (*i)->convertToImage(img); + img.save(prefix + "_blendtexture" + StringConverter::toString(blendTexture) + suffix); + } } + } - //--------------------------------------------------------------------- - void Terrain::copyBlendTextureChannel(uint8 srcIndex, uint8 srcChannel, uint8 destIndex, uint8 destChannel ) + //--------------------------------------------------------------------- + void Terrain::setGpuBufferAllocator(GpuBufferAllocator* alloc) { - HardwarePixelBufferSharedPtr srcBuffer = getLayerBlendTexture(srcIndex)->getBuffer(); - HardwarePixelBufferSharedPtr destBuffer = getLayerBlendTexture(destIndex)->getBuffer(); + if (alloc != getGpuBufferAllocator()) + { + if (isLoaded()) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Cannot alter the allocator when loaded!", __FUNCTION__); - unsigned char rgbaShift[4]; - Image::Box box(0, 0, destBuffer->getWidth(), destBuffer->getHeight()); + mCustomGpuBufferAllocator = alloc; + } + } + //--------------------------------------------------------------------- + Terrain::GpuBufferAllocator* Terrain::getGpuBufferAllocator() + { + if (mCustomGpuBufferAllocator) + return mCustomGpuBufferAllocator; + else + return &mDefaultGpuBufferAllocator; + } + //--------------------------------------------------------------------- + size_t Terrain::getPositionBufVertexSize() const + { + size_t sz = 0; + if (_getUseVertexCompression()) + { + // short2 position + sz += sizeof(short) * 2; + // float1 height + sz += sizeof(float); + } + else + { + // float3 position + sz += sizeof(float) * 3; + // float2 uv + sz += sizeof(float) * 2; + } - uint8* pDestBase = static_cast(destBuffer->lock(box, HardwareBuffer::HBL_NORMAL).data); - PixelUtil::getBitShifts(destBuffer->getFormat(), rgbaShift); - uint8* pDest = pDestBase + rgbaShift[destChannel] / 8; - size_t destInc = PixelUtil::getNumElemBytes(destBuffer->getFormat()); + return sz; - size_t srcInc; - uint8* pSrc; + } + //--------------------------------------------------------------------- + size_t Terrain::getDeltaBufVertexSize() const + { + // float2(delta, deltaLODthreshold) + return sizeof(float) * 2; + } + //--------------------------------------------------------------------- + size_t Terrain::_getNumIndexesForBatchSize(uint16 batchSize) + { + size_t mainIndexesPerRow = batchSize * 2 + 1; + size_t numRows = batchSize - 1; + size_t mainIndexCount = mainIndexesPerRow * numRows; + // skirts share edges, so they take 1 less row per side than batchSize, + // but with 2 extra at the end (repeated) to finish the strip + // * 2 for the vertical line, * 4 for the sides, +2 to finish + size_t skirtIndexCount = (batchSize - 1) * 2 * 4 + 2; + return mainIndexCount + skirtIndexCount; - if ( destBuffer == srcBuffer ) + } + //--------------------------------------------------------------------- + void Terrain::_populateIndexBuffer(uint16* pI, uint16 batchSize, + uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, + uint16 skirtRowColSkip) + { + /* For even / odd tri strip rows, triangles are this shape: + 6---7---8 + | \ | \ | + 3---4---5 + | / | / | + 0---1---2 + Note how vertex rows count upwards. In order to match up the anti-clockwise + winding and this upward transitioning list, we need to start from the + right hand side. So we get (2,5,1,4,0,3) etc on even lines (right-left) + and (3,6,4,7,5,8) etc on odd lines (left-right). At the turn, we emit the end index + twice, this forms a degenerate triangle, which lets us turn without any artefacts. + So the full list in this simple case is (2,5,1,4,0,3,3,6,4,7,5,8) + + Skirts are part of the same strip, so after finishing on 8, where sX is + the skirt vertex corresponding to main vertex X, we go + anticlockwise around the edge, (s8,7,s7,6,s6) to do the top skirt, + then (3,s3,0,s0),(1,s1,2,s2),(5,s5,8,s8) to finish the left, bottom, and + right skirts respectively. + */ + + // to issue a complete row, it takes issuing the upper and lower row + // and one extra index, which is the degenerate triangle and also turning + // around the winding + + size_t rowSize = vdatasize * vertexIncrement; + size_t numRows = batchSize - 1; + + // Start on the right + uint16 currentVertex = (batchSize - 1) * vertexIncrement; + // but, our quad area might not start at 0 in this vertex data + // offsets are at main terrain resolution, remember + uint16 columnStart = xoffset; + uint16 rowStart = yoffset; + currentVertex += rowStart * vdatasize + columnStart; + bool rightToLeft = true; + for (uint16 r = 0; r < numRows; ++r) { - pSrc = pDestBase + rgbaShift[srcChannel] / 8; - srcInc = destInc; + for (uint16 c = 0; c < batchSize; ++c) + { + + *pI++ = currentVertex; + *pI++ = currentVertex + rowSize; + + // don't increment / decrement at a border, keep this vertex for next + // row as we 'snake' across the tile + if (c+1 < batchSize) + { + currentVertex = rightToLeft ? + currentVertex - vertexIncrement : currentVertex + vertexIncrement; + } + } + rightToLeft = !rightToLeft; + currentVertex += rowSize; + // issue one extra index to turn winding around + *pI++ = currentVertex; + } + + // Skirts + for (uint16 s = 0; s < 4; ++s) + { + // edgeIncrement is the index offset from one original edge vertex to the next + // in this row or column. Columns skip based on a row size here + // skirtIncrement is the index offset from one skirt vertex to the next, + // because skirts are packed in rows/cols then there is no row multiplier for + // processing columns + int edgeIncrement = 0, skirtIncrement = 0; + switch(s) + { + case 0: // top + edgeIncrement = -static_cast(vertexIncrement); + skirtIncrement = -static_cast(vertexIncrement); + break; + case 1: // left + edgeIncrement = -static_cast(rowSize); + skirtIncrement = -static_cast(vertexIncrement); + break; + case 2: // bottom + edgeIncrement = static_cast(vertexIncrement); + skirtIncrement = static_cast(vertexIncrement); + break; + case 3: // right + edgeIncrement = static_cast(rowSize); + skirtIncrement = static_cast(vertexIncrement); + break; + } + // Skirts are stored in contiguous rows / columns (rows 0/2, cols 1/3) + uint16 skirtIndex = _calcSkirtVertexIndex(currentVertex, vdatasize, + (s % 2) != 0, numSkirtRowsCols, skirtRowColSkip); + for (uint16 c = 0; c < batchSize - 1; ++c) + { + *pI++ = currentVertex; + *pI++ = skirtIndex; + currentVertex += edgeIncrement; + skirtIndex += skirtIncrement; + } + if (s == 3) + { + // we issue an extra 2 indices to finish the skirt off + *pI++ = currentVertex; + *pI++ = skirtIndex; + currentVertex += edgeIncrement; + } + } + + } + //--------------------------------------------------------------------- + uint16 Terrain::_calcSkirtVertexIndex(uint16 mainIndex, uint16 vdatasize, bool isCol, + uint16 numSkirtRowsCols, uint16 skirtRowColSkip) + { + // row / col in main vertex resolution + uint16 row = mainIndex / vdatasize; + uint16 col = mainIndex % vdatasize; + + // skirts are after main vertices, so skip them + uint16 base = vdatasize * vdatasize; + + // The layout in vertex data is: + // 1. row skirts + // numSkirtRowsCols rows of resolution vertices each + // 2. column skirts + // numSkirtRowsCols cols of resolution vertices each + + // No offsets used here, this is an index into the current vertex data, + // which is already relative + if (isCol) + { + uint16 skirtNum = col / skirtRowColSkip; + uint16 colbase = numSkirtRowsCols * vdatasize; + return base + colbase + vdatasize * skirtNum + row; } else { - pSrc = static_cast(srcBuffer->lock(box, HardwareBuffer::HBL_READ_ONLY).data); - PixelUtil::getBitShifts(srcBuffer->getFormat(), rgbaShift); - pSrc += rgbaShift[srcChannel] / 8; - srcInc = PixelUtil::getNumElemBytes(srcBuffer->getFormat()); + uint16 skirtNum = row / skirtRowColSkip; + return base + vdatasize * skirtNum + col; } - for (size_t y = box.top; y < box.bottom; ++y) - { - for (size_t x = box.left; x < box.right; ++x) - { - *pDest = *pSrc; - pSrc += srcInc; - pDest += destInc; - } - } - - destBuffer->unlock(); - if ( destBuffer != srcBuffer ) - srcBuffer->unlock(); } //--------------------------------------------------------------------- - void Terrain::clearGPUBlendChannel(uint8 index, uint channel) + void Terrain::setWorldSize(Real newWorldSize) { - HardwarePixelBufferSharedPtr buffer = getLayerBlendTexture(index)->getBuffer(); + if(mWorldSize != newWorldSize) + { + waitForDerivedProcesses(); - unsigned char rgbaShift[4]; - Image::Box box(0, 0, buffer->getWidth(), buffer->getHeight()); + mWorldSize = newWorldSize; - uint8* pData = static_cast(buffer->lock(box, HardwareBuffer::HBL_NORMAL).data); - PixelUtil::getBitShifts(buffer->getFormat(), rgbaShift); - pData += rgbaShift[channel] / 8; - size_t inc = PixelUtil::getNumElemBytes(buffer->getFormat()); + updateBaseScale(); - for (size_t y = box.top; y < box.bottom; ++y) - { - for (size_t x = box.left; x < box.right; ++x) - { - *pData = 0; - pData += inc; - } - } - buffer->unlock(); - } - //--------------------------------------------------------------------- - void Terrain::createGPUBlendTextures() - { - // Create enough RGBA/RGB textures to cope with blend layers - uint8 numTex = getBlendTextureCount(getLayerCount()); - // delete extras - TextureManager* tmgr = TextureManager::getSingletonPtr(); - if (!tmgr) - return; - - while (mBlendTextureList.size() > numTex) - { - tmgr->remove(mBlendTextureList.back()->getHandle()); - mBlendTextureList.pop_back(); - } - - uint8 currentTex = (uint8)mBlendTextureList.size(); - mBlendTextureList.resize(numTex); - // create new textures - for (uint8 i = currentTex; i < numTex; ++i) - { - PixelFormat fmt = getBlendTextureFormat(i, getLayerCount()); - // Use TU_STATIC because although we will update this, we won't do it every frame - // in normal circumstances, so we don't want TU_DYNAMIC. Also we will - // read it (if we've cleared local temp areas) so no WRITE_ONLY - mBlendTextureList[i] = TextureManager::getSingleton().createManual( - msBlendTextureGenerator.generate(), _getDerivedResourceGroup(), - TEX_TYPE_2D, mLayerBlendMapSize, mLayerBlendMapSize, 1, 0, fmt, TU_STATIC); - - mLayerBlendMapSizeActual = mBlendTextureList[i]->getWidth(); - - if (mCpuBlendMapStorage.size() > i) - { - // Load blend data - PixelBox src(mLayerBlendMapSize, mLayerBlendMapSize, 1, fmt, mCpuBlendMapStorage[i]); - mBlendTextureList[i]->getBuffer()->blitFromMemory(src); - // release CPU copy, don't need it anymore - OGRE_FREE(mCpuBlendMapStorage[i], MEMCATEGORY_RESOURCE); - } - else - { - // initialise black - Box box(0, 0, mLayerBlendMapSize, mLayerBlendMapSize); - HardwarePixelBufferSharedPtr buf = mBlendTextureList[i]->getBuffer(); - uint8* pInit = static_cast(buf->lock(box, HardwarePixelBuffer::HBL_DISCARD).data); - memset(pInit, 0, PixelUtil::getNumElemBytes(fmt) * mLayerBlendMapSize * mLayerBlendMapSize); - buf->unlock(); - } - } - mCpuBlendMapStorage.clear(); - - - } - //--------------------------------------------------------------------- - void Terrain::createLayerBlendMaps() - { - // delete extra blend layers (affects GPU) - while (mLayerBlendMapList.size() > mLayers.size() - 1) - { - OGRE_DELETE mLayerBlendMapList.back(); - mLayerBlendMapList.pop_back(); - } - - // resize up (initialises to 0, populate as necessary) - if ( mLayers.size() > 1 ) - mLayerBlendMapList.resize(mLayers.size() - 1, 0); - - } - //--------------------------------------------------------------------- - void Terrain::createOrDestroyGPUNormalMap() - { - if (mNormalMapRequired && mTerrainNormalMap.isNull()) - { - // create - mTerrainNormalMap = TextureManager::getSingleton().createManual( - mMaterialName + "/nm", _getDerivedResourceGroup(), - TEX_TYPE_2D, mSize, mSize, 1, 0, PF_BYTE_RGB, TU_STATIC); - - // Upload loaded normal data if present - if (mCpuTerrainNormalMap) - { - mTerrainNormalMap->getBuffer()->blitFromMemory(*mCpuTerrainNormalMap); - OGRE_FREE(mCpuTerrainNormalMap->data, MEMCATEGORY_GENERAL); - OGRE_DELETE mCpuTerrainNormalMap; - mCpuTerrainNormalMap = 0; - } - - } - else if (!mNormalMapRequired && !mTerrainNormalMap.isNull()) - { - // destroy - TextureManager::getSingleton().remove(mTerrainNormalMap->getHandle()); - mTerrainNormalMap.setNull(); - } - - } - //--------------------------------------------------------------------- - void Terrain::freeTemporaryResources() - { - // CPU blend maps - for (BytePointerList::iterator i = mCpuBlendMapStorage.begin(); - i != mCpuBlendMapStorage.end(); ++i) - { - OGRE_FREE(*i, MEMCATEGORY_RESOURCE); - } - mCpuBlendMapStorage.clear(); - - // Editable structures for blend layers (not needed at runtime, only blend textures are) - deleteBlendMaps(0); - } - //--------------------------------------------------------------------- - void Terrain::deleteBlendMaps(uint8 lowIndex) - { - TerrainLayerBlendMapList::iterator i = mLayerBlendMapList.begin(); - std::advance(i, lowIndex); - for (; i != mLayerBlendMapList.end(); ++i ) - { - OGRE_DELETE *i; - *i = 0; - } - } - //--------------------------------------------------------------------- - const TexturePtr& Terrain::getLayerBlendTexture(uint8 index) const - { - assert(index < mBlendTextureList.size()); - - return mBlendTextureList[index]; - } - //--------------------------------------------------------------------- - std::pair Terrain::getLayerBlendTextureIndex(uint8 layerIndex) const - { - assert(layerIndex > 0 && layerIndex < mLayers.size()); - uint8 idx = layerIndex - 1; - return std::pair(idx / 4, idx % 4); - } - //--------------------------------------------------------------------- - void Terrain::_setNormalMapRequired(bool normalMap) - { - if (normalMap != mNormalMapRequired) - { - mNormalMapRequired = normalMap; - - // Check NPOT textures supported. We have to use NPOT textures to map - // texels to vertices directly! - if (!mNormalMapRequired && Root::getSingleton().getRenderSystem() - ->getCapabilities()->hasCapability(RSC_NON_POWER_OF_2_TEXTURES)) - { - mNormalMapRequired = false; - LogManager::getSingleton().stream(LML_CRITICAL) << - "Terrain: Ignoring request for normal map generation since " - "non-power-of-two texture support is required."; - } - - createOrDestroyGPUNormalMap(); - - // if we enabled, generate normal maps - if (mNormalMapRequired) - { - // update derived data for whole terrain, but just normals - mDirtyDerivedDataRect.left = mDirtyDerivedDataRect.top = 0; - mDirtyDerivedDataRect.right = mDirtyDerivedDataRect.bottom = mSize; - updateDerivedData(false, DERIVED_DATA_NORMALS); - } - - } - } - //--------------------------------------------------------------------- - void Terrain::_setLightMapRequired(bool lightMap, bool shadowsOnly) - { - if (lightMap != mLightMapRequired || shadowsOnly != mLightMapShadowsOnly) - { - mLightMapRequired = lightMap; - mLightMapShadowsOnly = shadowsOnly; - - createOrDestroyGPULightmap(); - - // if we enabled, generate light maps - if (mLightMapRequired) - { - // update derived data for whole terrain, but just lightmap - mDirtyDerivedDataRect.left = mDirtyDerivedDataRect.top = 0; - mDirtyDerivedDataRect.right = mDirtyDerivedDataRect.bottom = mSize; - updateDerivedData(false, DERIVED_DATA_LIGHTMAP); - } - } - - } - //--------------------------------------------------------------------- - void Terrain::_setCompositeMapRequired(bool compositeMap) - { - if (compositeMap != mCompositeMapRequired) - { - mCompositeMapRequired = compositeMap; - - createOrDestroyGPUCompositeMap(); - - // if we enabled, generate composite maps - if (mCompositeMapRequired) - { - mCompositeMapDirtyRect.left = mCompositeMapDirtyRect.top = 0; - mCompositeMapDirtyRect.right = mCompositeMapDirtyRect.bottom = mSize; - updateCompositeMap(); - } - - } - - } - //--------------------------------------------------------------------- - bool Terrain::_getUseVertexCompression() const - { - return mMaterialGenerator->isVertexCompressionSupported() && - TerrainGlobalOptions::getSingleton().getUseVertexCompressionWhenAvailable(); - } - //--------------------------------------------------------------------- - bool Terrain::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - if(req->getType()==WORKQUEUE_DERIVED_DATA_REQUEST) - { - DerivedDataRequest ddr = any_cast(req->getData()); - // only deal with own requests - // we do this because if we delete a terrain we want any pending tasks to be discarded - if (ddr.terrain != this) - return false; - } - else if(req->getType()==WORKQUEUE_GENERATE_MATERIAL_REQUEST) - { - GenerateMaterialRequest gmreq = any_cast(req->getData()); - if (gmreq.terrain != this) - return false; - } - - return RequestHandler::canHandleRequest(req, srcQ); - - } - //--------------------------------------------------------------------- - bool Terrain::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - const WorkQueue::Request* req = res->getRequest(); - if(req->getType()==WORKQUEUE_DERIVED_DATA_REQUEST) - { - DerivedDataRequest ddreq = any_cast(req->getData()); - // only deal with own requests - // we do this because if we delete a terrain we want any pending tasks to be discarded - if (ddreq.terrain != this) - return false; - } - else if(req->getType()==WORKQUEUE_GENERATE_MATERIAL_REQUEST) - { - GenerateMaterialRequest gmreq = any_cast(req->getData()); - if (gmreq.terrain != this) - return false; - } - return true; - } - //--------------------------------------------------------------------- - WorkQueue::Response* Terrain::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - // Background thread (maybe) - if(req->getType()==WORKQUEUE_GENERATE_MATERIAL_REQUEST) - { - return OGRE_NEW WorkQueue::Response(req, true, Any()); - } - - DerivedDataRequest ddr = any_cast(req->getData()); - DerivedDataResponse ddres; - ddres.remainingTypeMask = ddr.typeMask & DERIVED_DATA_ALL; - - // Do only ONE type of task per background iteration, in order of priority - // this means we return faster, can abort faster and we repeat less redundant calcs - // we don't do this as separate requests, because we only want one background - // task per Terrain instance in flight at once - if (ddr.typeMask & DERIVED_DATA_DELTAS) - { - ddres.deltaUpdateRect = calculateHeightDeltas(ddr.dirtyRect); - ddres.remainingTypeMask &= ~ DERIVED_DATA_DELTAS; - } - else if (ddr.typeMask & DERIVED_DATA_NORMALS) - { - ddres.normalMapBox = calculateNormals(ddr.dirtyRect, ddres.normalUpdateRect); - ddres.remainingTypeMask &= ~ DERIVED_DATA_NORMALS; - } - else if (ddr.typeMask & DERIVED_DATA_LIGHTMAP) - { - ddres.lightMapBox = calculateLightmap(ddr.dirtyRect, ddr.lightmapExtraDirtyRect, ddres.lightmapUpdateRect); - ddres.remainingTypeMask &= ~ DERIVED_DATA_LIGHTMAP; - } - - ddres.terrain = ddr.terrain; - WorkQueue::Response* response = OGRE_NEW WorkQueue::Response(req, true, Any(ddres)); - return response; - } - //--------------------------------------------------------------------- - void Terrain::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - // Main thread - if(res->getRequest()->getType()==WORKQUEUE_GENERATE_MATERIAL_REQUEST) - { - handleGenerateMaterialResponse(res,srcQ); - return; - } - - DerivedDataResponse ddres = any_cast(res->getData()); - DerivedDataRequest ddreq = any_cast(res->getRequest()->getData()); - - // only deal with own requests - if (ddreq.terrain != this) - return; - - if ((ddreq.typeMask & DERIVED_DATA_DELTAS) && - !(ddres.remainingTypeMask & DERIVED_DATA_DELTAS)) - finaliseHeightDeltas(ddres.deltaUpdateRect, false); - if ((ddreq.typeMask & DERIVED_DATA_NORMALS) && - !(ddres.remainingTypeMask & DERIVED_DATA_NORMALS)) - { - finaliseNormals(ddres.normalUpdateRect, ddres.normalMapBox); - mCompositeMapDirtyRect.merge(ddreq.dirtyRect); - } - if ((ddreq.typeMask & DERIVED_DATA_LIGHTMAP) && - !(ddres.remainingTypeMask & DERIVED_DATA_LIGHTMAP)) - { - finaliseLightmap(ddres.lightmapUpdateRect, ddres.lightMapBox); - mCompositeMapDirtyRect.merge(ddreq.dirtyRect); - mCompositeMapDirtyRectLightmapUpdate = true; - } - - mDerivedDataUpdateInProgress = false; - - // Re-trigger another request if there are still things to do, or if - // we had a new request since this one - Rect newRect(0,0,0,0); - if (ddres.remainingTypeMask) - newRect.merge(ddreq.dirtyRect); - if (mDerivedUpdatePendingMask) - { - newRect.merge(mDirtyDerivedDataRect); - mDirtyDerivedDataRect.setNull(); - } - Rect newLightmapExtraRect(0,0,0,0); - if (ddres.remainingTypeMask) - newLightmapExtraRect.merge(ddreq.lightmapExtraDirtyRect); - if (mDerivedUpdatePendingMask) - { - newLightmapExtraRect.merge(mDirtyLightmapFromNeighboursRect); - mDirtyLightmapFromNeighboursRect.setNull(); - } - uint8 newMask = ddres.remainingTypeMask | mDerivedUpdatePendingMask; - if (newMask) - { - // trigger again - updateDerivedDataImpl(newRect, newLightmapExtraRect, false, newMask); - } - else - { - // we've finished all the background processes - // update the composite map if enabled - if (mCompositeMapRequired) - updateCompositeMap(); - } - - } - //--------------------------------------------------------------------- - void Terrain::handleGenerateMaterialResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - GenerateMaterialRequest gmreq = any_cast(res->getRequest()->getData()); - unsigned long currentTime = Root::getSingletonPtr()->getTimer()->getMilliseconds(); - - // process - switch(gmreq.stage) - { - case GEN_MATERIAL: - mMaterial = mMaterialGenerator->generate(this); - mMaterial->load(); - // init next stage - if (mCompositeMapRequired) - { - gmreq.stage = GEN_COMPOSITE_MAP_MATERIAL; - gmreq.startTime = currentTime + TERRAIN_GENERATE_MATERIAL_INTERVAL_MS; - Root::getSingleton().getWorkQueue()->addRequest( - mWorkQueueChannel, WORKQUEUE_GENERATE_MATERIAL_REQUEST, - Any(gmreq), 0, gmreq.synchronous); - return; - } - break; - case GEN_COMPOSITE_MAP_MATERIAL: - mCompositeMapMaterial = mMaterialGenerator->generateForCompositeMap(this); - mCompositeMapMaterial->load(); - break; - } - mMaterialGenerationCount = mMaterialGenerator->getChangeCount(); - mMaterialDirty = false; - - mGenerateMaterialInProgress = false; - mIsLoaded = true; - } - //--------------------------------------------------------------------- - uint16 Terrain::getLODLevelWhenVertexEliminated(long x, long y) const - { - // gets eliminated by either row or column first - return std::min(getLODLevelWhenVertexEliminated(x), getLODLevelWhenVertexEliminated(y)); - } - //--------------------------------------------------------------------- - uint16 Terrain::getLODLevelWhenVertexEliminated(long rowOrColulmn) const - { - // LOD levels bisect the domain. - // start at the lowest detail - uint16 currentElim = (mSize - 1) / (mMinBatchSize - 1); - // start at a non-exitant LOD index, this applies to the min batch vertices - // which are never eliminated - uint16 currentLod = mNumLodLevels; - - while (rowOrColulmn % currentElim) - { - // not on this boundary, look finer - currentElim = currentElim / 2; - --currentLod; - - // This will always terminate since (anything % 1 == 0) - } - - return currentLod; - } - //--------------------------------------------------------------------- - PixelBox* Terrain::calculateNormals(const Rect &rect, Rect& finalRect) - { - // Widen the rectangle by 1 element in all directions since height - // changes affect neighbours normals - Rect widenedRect( - std::max(0L, rect.left - 1L), - std::max(0L, rect.top - 1L), - std::min((long)mSize, rect.right + 1L), - std::min((long)mSize, rect.bottom + 1L) - ); - // allocate memory for RGB - uint8* pData = static_cast( - OGRE_MALLOC(widenedRect.width() * widenedRect.height() * 3, MEMCATEGORY_GENERAL)); - - PixelBox* pixbox = OGRE_NEW PixelBox(static_cast(widenedRect.width()), - static_cast(widenedRect.height()), 1, PF_BYTE_RGB, pData); + deriveUVMultipliers(); - // Evaluate normal like this - // 3---2---1 - // | \ | / | - // 4---P---0 - // | / | \ | - // 5---6---7 - - Plane plane; - for (long y = widenedRect.top; y < widenedRect.bottom; ++y) - { - for (long x = widenedRect.left; x < widenedRect.right; ++x) - { - Vector3 cumulativeNormal = Vector3::ZERO; - - // Build points to sample - Vector3 centrePoint; - Vector3 adjacentPoints[8]; - getPointFromSelfOrNeighbour(x , y, ¢rePoint); - getPointFromSelfOrNeighbour(x+1, y, &adjacentPoints[0]); - getPointFromSelfOrNeighbour(x+1, y+1, &adjacentPoints[1]); - getPointFromSelfOrNeighbour(x, y+1, &adjacentPoints[2]); - getPointFromSelfOrNeighbour(x-1, y+1, &adjacentPoints[3]); - getPointFromSelfOrNeighbour(x-1, y, &adjacentPoints[4]); - getPointFromSelfOrNeighbour(x-1, y-1, &adjacentPoints[5]); - getPointFromSelfOrNeighbour(x, y-1, &adjacentPoints[6]); - getPointFromSelfOrNeighbour(x+1, y-1, &adjacentPoints[7]); - - for (int i = 0; i < 8; ++i) - { - plane.redefine(centrePoint, adjacentPoints[i], adjacentPoints[(i+1)%8]); - cumulativeNormal += plane.normal; - } - - // normalise & store normal - cumulativeNormal.normalise(); - - // encode as RGB, object space - // invert the Y to deal with image space - long storeX = x - widenedRect.left; - long storeY = widenedRect.bottom - y - 1; - - uint8* pStore = pData + ((storeY * widenedRect.width()) + storeX) * 3; - *pStore++ = static_cast((cumulativeNormal.x + 1.0f) * 0.5f * 255.0f); - *pStore++ = static_cast((cumulativeNormal.y + 1.0f) * 0.5f * 255.0f); - *pStore++ = static_cast((cumulativeNormal.z + 1.0f) * 0.5f * 255.0f); - - - } - } - - finalRect = widenedRect; - - return pixbox; - } - //--------------------------------------------------------------------- - void Terrain::finaliseNormals(const Ogre::Rect &rect, Ogre::PixelBox *normalsBox) - { - createOrDestroyGPUNormalMap(); - // deal with race condition where nm has been disabled while we were working! - if (!mTerrainNormalMap.isNull()) - { - // blit the normals into the texture - if (rect.left == 0 && rect.top == 0 && rect.bottom == mSize && rect.right == mSize) - { - mTerrainNormalMap->getBuffer()->blitFromMemory(*normalsBox); - } - else - { - // content of normalsBox is already inverted in Y, but rect is still - // in terrain space for dealing with sub-rect, so invert - Image::Box dstBox; - dstBox.left = static_cast(rect.left); - dstBox.right = static_cast(rect.right); - dstBox.top = static_cast(mSize - rect.bottom); - dstBox.bottom = static_cast(mSize - rect.top); - mTerrainNormalMap->getBuffer()->blitFromMemory(*normalsBox, dstBox); - } - } - - - // delete memory - OGRE_FREE(normalsBox->data, MEMCATEGORY_GENERAL); - OGRE_DELETE(normalsBox); - - } - //--------------------------------------------------------------------- - void Terrain::widenRectByVector(const Vector3& vec, const Rect& inRect, Rect& outRect) - { - widenRectByVector(vec, inRect, getMinHeight(), getMaxHeight(), outRect); - } - //--------------------------------------------------------------------- - void Terrain::widenRectByVector(const Vector3& vec, const Rect& inRect, - Real minHeight, Real maxHeight, Rect& outRect) - { - - outRect = inRect; - - Plane p; - switch(getAlignment()) - { - case ALIGN_X_Y: - p.redefine(Vector3::UNIT_Z, Vector3(0, 0, vec.z < 0.0 ? minHeight : maxHeight)); - break; - case ALIGN_X_Z: - p.redefine(Vector3::UNIT_Y, Vector3(0, vec.y < 0.0 ? minHeight : maxHeight, 0)); - break; - case ALIGN_Y_Z: - p.redefine(Vector3::UNIT_X, Vector3(vec.x < 0.0 ? minHeight : maxHeight, 0, 0)); - break; - } - float verticalVal = vec.dotProduct(p.normal); - - if (Math::RealEqual(verticalVal, 0.0)) - return; - - Vector3 corners[4]; - Real startHeight = verticalVal < 0.0 ? maxHeight : minHeight; - getPoint(inRect.left, inRect.top, startHeight, &corners[0]); - getPoint(inRect.right-1, inRect.top, startHeight, &corners[1]); - getPoint(inRect.left, inRect.bottom-1, startHeight, &corners[2]); - getPoint(inRect.right-1, inRect.bottom-1, startHeight, &corners[3]); - - for (int i = 0; i < 4; ++i) - { - Ray ray(corners[i] + mPos, vec); - std::pair rayHit = ray.intersects(p); - if(rayHit.first) - { - Vector3 pt = ray.getPoint(rayHit.second); - // convert back to terrain point - Vector3 terrainHitPos; - getTerrainPosition(pt, &terrainHitPos); - // build rectangle which has rounded down & rounded up values - // remember right & bottom are exclusive - Rect mergeRect( - (long)(terrainHitPos.x * (mSize - 1)), - (long)(terrainHitPos.y * (mSize - 1)), - (long)(terrainHitPos.x * (float)(mSize - 1) + 0.5) + 1, - (long)(terrainHitPos.y * (float)(mSize - 1) + 0.5) + 1 - ); - outRect.merge(mergeRect); - } - } - - } - //--------------------------------------------------------------------- - PixelBox* Terrain::calculateLightmap(const Rect& rect, const Rect& extraTargetRect, Rect& outFinalRect) - { - // as well as calculating the lighting changes for the area that is - // dirty, we also need to calculate the effect on casting shadow on - // other areas. To do this, we project the dirt rect by the light direction - // onto the minimum height - - - const Vector3& lightVec = TerrainGlobalOptions::getSingleton().getLightMapDirection(); - Ogre::Rect widenedRect; - widenRectByVector(lightVec, rect, widenedRect); + mMaterialParamsDirty = true; - // merge in the extra area (e.g. from neighbours) - widenedRect.merge(extraTargetRect); + if(mIsLoaded) + { + Rect dRect(0, 0, mSize, mSize); + dirtyRect(dRect); + update(); + } - // widenedRect now contains terrain point space version of the area we - // need to calculate. However, we need to calculate in lightmap image space - float terrainToLightmapScale = (float)mLightmapSizeActual / (float)mSize; - widenedRect.left = (long)(widenedRect.left * terrainToLightmapScale); - widenedRect.right = (long)(widenedRect.right * terrainToLightmapScale); - widenedRect.top = (long)(widenedRect.top * terrainToLightmapScale); - widenedRect.bottom = (long)(widenedRect.bottom * terrainToLightmapScale); + mModified = true; + } + } + //--------------------------------------------------------------------- + void Terrain::setSize(uint16 newSize) + { + if(mSize != newSize) + { + waitForDerivedProcesses(); + // load full HeightData + load(0,true); - // clamp - widenedRect.left = std::max(0L, widenedRect.left); - widenedRect.top = std::max(0L, widenedRect.top); - widenedRect.right = std::min((long)mLightmapSizeActual, widenedRect.right); - widenedRect.bottom = std::min((long)mLightmapSizeActual, widenedRect.bottom); + size_t numVertices = newSize * newSize; - outFinalRect = widenedRect; + PixelBox src(mSize, mSize, 1, Ogre::PF_FLOAT32_R, (void*)getHeightData()); - // allocate memory (L8) - uint8* pData = static_cast( - OGRE_MALLOC(widenedRect.width() * widenedRect.height(), MEMCATEGORY_GENERAL)); + float* tmpData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GENERAL); - PixelBox* pixbox = OGRE_NEW PixelBox(static_cast(widenedRect.width()), - static_cast(widenedRect.height()), 1, PF_L8, pData); + PixelBox dst(newSize, newSize, 1, Ogre::PF_FLOAT32_R, tmpData); - Real heightPad = (getMaxHeight() - getMinHeight()) * 1.0e-3f; - - for (long y = widenedRect.top; y < widenedRect.bottom; ++y) - { - for (long x = widenedRect.left; x < widenedRect.right; ++x) - { - float litVal = 1.0f; - - // convert to terrain space (not points, allow this to go between points) - float Tx = (float)x / (float)(mLightmapSizeActual-1); - float Ty = (float)y / (float)(mLightmapSizeActual-1); - - // get world space point - // add a little height padding to stop shadowing self - Vector3 wpos = Vector3::ZERO; - getPosition(Tx, Ty, getHeightAtTerrainPosition(Tx, Ty) + heightPad, &wpos); - wpos += getPosition(); - // build ray, cast backwards along light direction - Ray ray(wpos, -lightVec); - - // Cascade into neighbours when casting, but don't travel further - // than world size - std::pair rayHit = rayIntersects(ray, true, mWorldSize); - - if (rayHit.first) - litVal = 0.0f; - - // encode as L8 - // invert the Y to deal with image space - long storeX = x - widenedRect.left; - long storeY = widenedRect.bottom - y - 1; - - uint8* pStore = pData + ((storeY * widenedRect.width()) + storeX); - *pStore = (unsigned char)(litVal * 255.0); - - } - } - - return pixbox; - - - } - //--------------------------------------------------------------------- - void Terrain::finaliseLightmap(const Rect& rect, PixelBox* lightmapBox) - { - createOrDestroyGPULightmap(); - // deal with race condition where lm has been disabled while we were working! - if (!mLightmap.isNull()) - { - // blit the normals into the texture - if (rect.left == 0 && rect.top == 0 && rect.bottom == mLightmapSizeActual && rect.right == mLightmapSizeActual) - { - mLightmap->getBuffer()->blitFromMemory(*lightmapBox); - } - else - { - // content of PixelBox is already inverted in Y, but rect is still - // in terrain space for dealing with sub-rect, so invert - Image::Box dstBox; - dstBox.left = static_cast(rect.left); - dstBox.right = static_cast(rect.right); - dstBox.top = static_cast(mLightmapSizeActual - rect.bottom); - dstBox.bottom = static_cast(mLightmapSizeActual - rect.top); - mLightmap->getBuffer()->blitFromMemory(*lightmapBox, dstBox); - } - } - - // delete memory - OGRE_FREE(lightmapBox->data, MEMCATEGORY_GENERAL); - OGRE_DELETE(lightmapBox); - - - } - //--------------------------------------------------------------------- - void Terrain::updateCompositeMap() - { - // All done in the render thread - if (mCompositeMapRequired && !mCompositeMapDirtyRect.isNull()) - { - mModified = true; - createOrDestroyGPUCompositeMap(); - if (mCompositeMapDirtyRectLightmapUpdate && - (mCompositeMapDirtyRect.width() < mSize || mCompositeMapDirtyRect.height() < mSize)) - { - // widen the dirty rectangle since lighting makes it wider - Rect widenedRect; - widenRectByVector(TerrainGlobalOptions::getSingleton().getLightMapDirection(), mCompositeMapDirtyRect, widenedRect); - // clamp - widenedRect.left = std::max(widenedRect.left, 0L); - widenedRect.top = std::max(widenedRect.top, 0L); - widenedRect.right = std::min(widenedRect.right, (long)mSize); - widenedRect.bottom = std::min(widenedRect.bottom, (long)mSize); - mMaterialGenerator->updateCompositeMap(this, widenedRect); - } - else - mMaterialGenerator->updateCompositeMap(this, mCompositeMapDirtyRect); - - mCompositeMapDirtyRectLightmapUpdate = false; - mCompositeMapDirtyRect.setNull(); - - - } - } - //--------------------------------------------------------------------- - void Terrain::updateCompositeMapWithDelay(Real delay) - { - mCompositeMapUpdateCountdown = (long)(delay * 1000); - } - //--------------------------------------------------------------------- - uint8 Terrain::getBlendTextureIndex(uint8 layerIndex) const - { - if (layerIndex == 0 || layerIndex-1 >= (uint8)mLayerBlendMapList.size()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid layer index", "Terrain::getBlendTextureIndex"); - - return (layerIndex - 1) % 4; - - } - //--------------------------------------------------------------------- - const String& Terrain::getBlendTextureName(uint8 textureIndex) const - { - if (textureIndex >= (uint8)mBlendTextureList.size()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid texture index", "Terrain::getBlendTextureName"); - - return mBlendTextureList[textureIndex]->getName(); - } - //--------------------------------------------------------------------- - void Terrain::setGlobalColourMapEnabled(bool enabled, uint16 sz) - { - if (!sz) - sz = TerrainGlobalOptions::getSingleton().getDefaultGlobalColourMapSize(); - - if (enabled != mGlobalColourMapEnabled || - (enabled && mGlobalColourMapSize != sz)) - { - mGlobalColourMapEnabled = enabled; - mGlobalColourMapSize = sz; - - createOrDestroyGPUColourMap(); - - mMaterialDirty = true; - mMaterialParamsDirty = true; - mModified = true; - } - - } - //--------------------------------------------------------------------- - void Terrain::createOrDestroyGPUColourMap() - { - if (mGlobalColourMapEnabled && mColourMap.isNull()) - { - // create - mColourMap = TextureManager::getSingleton().createManual( - mMaterialName + "/cm", _getDerivedResourceGroup(), - TEX_TYPE_2D, mGlobalColourMapSize, mGlobalColourMapSize, MIP_DEFAULT, - PF_BYTE_RGB, TU_AUTOMIPMAP|TU_STATIC); - - if (mCpuColourMapStorage) - { - // Load cached data - PixelBox src(mGlobalColourMapSize, mGlobalColourMapSize, 1, PF_BYTE_RGB, mCpuColourMapStorage); - mColourMap->getBuffer()->blitFromMemory(src); - // release CPU copy, don't need it anymore - OGRE_FREE(mCpuColourMapStorage, MEMCATEGORY_RESOURCE); - mCpuColourMapStorage = 0; - - } - } - else if (!mGlobalColourMapEnabled && !mColourMap.isNull()) - { - // destroy - TextureManager::getSingleton().remove(mColourMap->getHandle()); - mColourMap.setNull(); - } - - } - //--------------------------------------------------------------------- - void Terrain::createOrDestroyGPULightmap() - { - if (mLightMapRequired && mLightmap.isNull()) - { - // create - mLightmap = TextureManager::getSingleton().createManual( - mMaterialName + "/lm", _getDerivedResourceGroup(), - TEX_TYPE_2D, mLightmapSize, mLightmapSize, 0, PF_L8, TU_STATIC); - - mLightmapSizeActual = mLightmap->getWidth(); - - if (mCpuLightmapStorage) - { - // Load cached data - PixelBox src(mLightmapSize, mLightmapSize, 1, PF_L8, mCpuLightmapStorage); - mLightmap->getBuffer()->blitFromMemory(src); - // release CPU copy, don't need it anymore - OGRE_FREE(mCpuLightmapStorage, MEMCATEGORY_RESOURCE); - mCpuLightmapStorage = 0; - - } - else - { - // initialise to full-bright - Box box(0, 0, mLightmapSizeActual, mLightmapSizeActual); - HardwarePixelBufferSharedPtr buf = mLightmap->getBuffer(); - uint8* pInit = static_cast(buf->lock(box, HardwarePixelBuffer::HBL_DISCARD).data); - memset(pInit, 255, mLightmapSizeActual * mLightmapSizeActual); - buf->unlock(); - - } - } - else if (!mLightMapRequired && !mLightmap.isNull()) - { - // destroy - TextureManager::getSingleton().remove(mLightmap->getHandle()); - mLightmap.setNull(); - } - - } - //--------------------------------------------------------------------- - void Terrain::createOrDestroyGPUCompositeMap() - { - if (mCompositeMapRequired && mCompositeMap.isNull()) - { - // create - mCompositeMap = TextureManager::getSingleton().createManual( - mMaterialName + "/comp", _getDerivedResourceGroup(), - TEX_TYPE_2D, mCompositeMapSize, mCompositeMapSize, 0, PF_BYTE_RGBA, TU_STATIC); - - mCompositeMapSizeActual = mCompositeMap->getWidth(); - - if (mCpuCompositeMapStorage) - { - // Load cached data - PixelBox src(mCompositeMapSize, mCompositeMapSize, 1, PF_BYTE_RGBA, mCpuCompositeMapStorage); - mCompositeMap->getBuffer()->blitFromMemory(src); - // release CPU copy, don't need it anymore - OGRE_FREE(mCpuCompositeMapStorage, MEMCATEGORY_RESOURCE); - mCpuCompositeMapStorage = 0; - - } - else - { - // initialise to black - Box box(0, 0, mCompositeMapSizeActual, mCompositeMapSizeActual); - HardwarePixelBufferSharedPtr buf = mCompositeMap->getBuffer(); - uint8* pInit = static_cast(buf->lock(box, HardwarePixelBuffer::HBL_DISCARD).data); - memset(pInit, 0, mCompositeMapSizeActual * mCompositeMapSizeActual * 4); - buf->unlock(); - - } - } - else if (!mCompositeMapRequired && !mCompositeMap.isNull()) - { - // destroy - TextureManager::getSingleton().remove(mCompositeMap->getHandle()); - mCompositeMap.setNull(); - } - - } - //--------------------------------------------------------------------- - Terrain* Terrain::getNeighbour(NeighbourIndex index) const - { - return mNeighbours[index]; - } - //--------------------------------------------------------------------- - void Terrain::setNeighbour(NeighbourIndex index, Terrain* neighbour, - bool recalculate /*= false*/, bool notifyOther /* = true */) - { - if (mNeighbours[index] != neighbour) - { - assert(neighbour != this && "Can't set self as own neighbour!"); - - // detach existing - if (mNeighbours[index] && notifyOther) - mNeighbours[index]->setNeighbour(getOppositeNeighbour(index), 0, false, false); - - mNeighbours[index] = neighbour; - if (neighbour && notifyOther) - mNeighbours[index]->setNeighbour(getOppositeNeighbour(index), this, recalculate, false); - - if (recalculate) - { - // Recalculate, pass OUR edge rect - Rect edgerect; - getEdgeRect(index, 2, &edgerect); - neighbourModified(index, edgerect, edgerect); - } - } - } - //--------------------------------------------------------------------- - Terrain::NeighbourIndex Terrain::getOppositeNeighbour(NeighbourIndex index) - { - int intindex = static_cast(index); - intindex += NEIGHBOUR_COUNT / 2; - intindex = intindex % NEIGHBOUR_COUNT; - return static_cast(intindex); - } - //--------------------------------------------------------------------- - Terrain::NeighbourIndex Terrain::getNeighbourIndex(long x, long y) - { - if (x < 0) - { - if (y < 0) - return NEIGHBOUR_SOUTHWEST; - else if (y > 0) - return NEIGHBOUR_NORTHWEST; - else - return NEIGHBOUR_WEST; - } - else if (x > 0) - { - if (y < 0) - return NEIGHBOUR_SOUTHEAST; - else if (y > 0) - return NEIGHBOUR_NORTHEAST; - else - return NEIGHBOUR_EAST; - } - - if (y < 0) - { - if (x == 0) - return NEIGHBOUR_SOUTH; - } - else if (y > 0) - { - if (x == 0) - return NEIGHBOUR_NORTH; - } - - return NEIGHBOUR_NORTH; - - } - //--------------------------------------------------------------------- - void Terrain::notifyNeighbours() - { - // There are 3 things that can need updating: - // Height at edge - match to neighbour (first one to update 'loses' to other since read-only) - // Normal at edge - use heights from across boundary too - // Shadows across edge - // The extent to which these can affect the current tile vary: - // Height at edge - only affected by a change at the adjoining edge / corner - // Normal at edge - only affected by a change to the 2 rows adjoining the edge / corner - // Shadows across edge - possible effect extends based on the projection of the - // neighbour AABB along the light direction (worst case scenario) - - if (!mDirtyGeometryRectForNeighbours.isNull()) - { - Rect dirtyRectForNeighbours(mDirtyGeometryRectForNeighbours); - mDirtyGeometryRectForNeighbours.setNull(); - // calculate light update rectangle - const Vector3& lightVec = TerrainGlobalOptions::getSingleton().getLightMapDirection(); - Rect lightmapRect; - widenRectByVector(lightVec, dirtyRectForNeighbours, getMinHeight(), getMaxHeight(), lightmapRect); - - for (int i = 0; i < (int)NEIGHBOUR_COUNT; ++i) - { - NeighbourIndex ni = static_cast(i); - Terrain* neighbour = getNeighbour(ni); - if (!neighbour) - continue; - - // Intersect the incoming rectangles with the edge regions related to this neighbour - Rect edgeRect; - getEdgeRect(ni, 2, &edgeRect); - Rect heightEdgeRect = edgeRect.intersect(dirtyRectForNeighbours); - Rect lightmapEdgeRect = edgeRect.intersect(lightmapRect); - - if (!heightEdgeRect.isNull() || !lightmapRect.isNull()) - { - // ok, we have something valid to pass on - Rect neighbourHeightEdgeRect, neighbourLightmapEdgeRect; - if (!heightEdgeRect.isNull()) - getNeighbourEdgeRect(ni, heightEdgeRect, &neighbourHeightEdgeRect); - if (!lightmapRect.isNull()) - getNeighbourEdgeRect(ni, lightmapEdgeRect, &neighbourLightmapEdgeRect); - - neighbour->neighbourModified(getOppositeNeighbour(ni), - neighbourHeightEdgeRect, neighbourLightmapEdgeRect); - - } - - } - } - } - //--------------------------------------------------------------------- - void Terrain::neighbourModified(NeighbourIndex index, const Rect& edgerect, const Rect& shadowrect) - { - // We can safely assume that we would not have been contacted if it wasn't - // important - const Terrain* neighbour = getNeighbour(index); - if (!neighbour) - return; // bogus request - - bool updateGeom = false; - uint8 updateDerived = 0; - - - if (!edgerect.isNull()) - { - // update edges; match heights first, then recalculate normals - // reduce to just single line / corner - Rect heightMatchRect; - getEdgeRect(index, 1, &heightMatchRect); - heightMatchRect = heightMatchRect.intersect(edgerect); - - for (long y = heightMatchRect.top; y < heightMatchRect.bottom; ++y) - { - for (long x = heightMatchRect.left; x < heightMatchRect.right; ++x) - { - long nx, ny; - getNeighbourPoint(index, x, y, &nx, &ny); - float neighbourHeight = neighbour->getHeightAtPoint(nx, ny); - if (!Math::RealEqual(neighbourHeight, getHeightAtPoint(x, y), 1e-3f)) - { - setHeightAtPoint(x, y, neighbourHeight); - if (!updateGeom) - { - updateGeom = true; - updateDerived |= DERIVED_DATA_ALL; - } - - } - } - } - // if we didn't need to update heights, we still need to update normals - // because this was called only if neighbor changed - if (!updateGeom) - { - // ideally we would deal with normal dirty rect separately (as we do with - // lightmaps) because a dirty geom rectangle will actually grow by one - // element in each direction for normals recalculation. However for - // the sake of one row/column it's really not worth it. - mDirtyDerivedDataRect.merge(edgerect); - updateDerived |= DERIVED_DATA_NORMALS; - } - } - - if (!shadowrect.isNull()) - { - // update shadows - // here we need to widen the rect passed in based on the min/max height - // of the *neighbour* - const Vector3& lightVec = TerrainGlobalOptions::getSingleton().getLightMapDirection(); - Rect widenedRect; - widenRectByVector(lightVec, shadowrect, neighbour->getMinHeight(), neighbour->getMaxHeight(), widenedRect); - - // set the special-case lightmap dirty rectangle - mDirtyLightmapFromNeighboursRect.merge(widenedRect); - updateDerived |= DERIVED_DATA_LIGHTMAP; - } - - if (updateGeom) - updateGeometry(); - if (updateDerived) - updateDerivedData(false, updateDerived); - - - - } - //--------------------------------------------------------------------- - void Terrain::getEdgeRect(NeighbourIndex index, long range, Rect* outRect) const - { - // We make the edge rectangle 2 rows / columns at the edge of the tile - // 2 because this copes with normal changes and potentially filtered - // shadows. - // all right / bottom values are exclusive - // terrain origin is bottom-left remember so north is highest value - - // set left/right - switch(index) - { - case NEIGHBOUR_EAST: - case NEIGHBOUR_NORTHEAST: - case NEIGHBOUR_SOUTHEAST: - outRect->left = mSize - range; - outRect->right = mSize; - break; - case NEIGHBOUR_WEST: - case NEIGHBOUR_NORTHWEST: - case NEIGHBOUR_SOUTHWEST: - outRect->left = 0; - outRect->right = range; - break; - case NEIGHBOUR_NORTH: - case NEIGHBOUR_SOUTH: - outRect->left = 0; - outRect->right = mSize; - break; - case NEIGHBOUR_COUNT: - default: - break; - }; - - // set top / bottom - switch(index) - { - case NEIGHBOUR_NORTH: - case NEIGHBOUR_NORTHEAST: - case NEIGHBOUR_NORTHWEST: - outRect->top = mSize - range; - outRect->bottom = mSize; - break; - case NEIGHBOUR_SOUTH: - case NEIGHBOUR_SOUTHWEST: - case NEIGHBOUR_SOUTHEAST: - outRect->top = 0; - outRect->bottom = range; - break; - case NEIGHBOUR_EAST: - case NEIGHBOUR_WEST: - outRect->top = 0; - outRect->bottom = mSize; - break; - case NEIGHBOUR_COUNT: - default: - break; - }; - } - //--------------------------------------------------------------------- - void Terrain::getNeighbourEdgeRect(NeighbourIndex index, const Rect& inRect, Rect* outRect) const - { - assert (mSize == getNeighbour(index)->getSize()); - - // Basically just reflect the rect - // remember index is neighbour relationship from OUR perspective so - // arrangement is backwards to getEdgeRect - - // left/right - switch(index) - { - case NEIGHBOUR_EAST: - case NEIGHBOUR_NORTHEAST: - case NEIGHBOUR_SOUTHEAST: - case NEIGHBOUR_WEST: - case NEIGHBOUR_NORTHWEST: - case NEIGHBOUR_SOUTHWEST: - outRect->left = mSize - inRect.right; - outRect->right = mSize - inRect.left; - break; - default: - outRect->left = inRect.left; - outRect->right = inRect.right; - break; - }; - - // top / bottom - switch(index) - { - case NEIGHBOUR_NORTH: - case NEIGHBOUR_NORTHEAST: - case NEIGHBOUR_NORTHWEST: - case NEIGHBOUR_SOUTH: - case NEIGHBOUR_SOUTHWEST: - case NEIGHBOUR_SOUTHEAST: - outRect->top = mSize - inRect.bottom; - outRect->bottom = mSize - inRect.top; - break; - default: - outRect->top = inRect.top; - outRect->bottom = inRect.bottom; - break; - }; - - } - //--------------------------------------------------------------------- - void Terrain::getNeighbourPoint(NeighbourIndex index, long x, long y, long *outx, long *outy) const - { - // Get the index of the point we should be looking at on a neighbour - // in order to match up points - assert (mSize == getNeighbour(index)->getSize()); - - // left/right - switch(index) - { - case NEIGHBOUR_EAST: - case NEIGHBOUR_NORTHEAST: - case NEIGHBOUR_SOUTHEAST: - case NEIGHBOUR_WEST: - case NEIGHBOUR_NORTHWEST: - case NEIGHBOUR_SOUTHWEST: - *outx = mSize - x - 1; - break; - default: - *outx = x; - break; - }; - - // top / bottom - switch(index) - { - case NEIGHBOUR_NORTH: - case NEIGHBOUR_NORTHEAST: - case NEIGHBOUR_NORTHWEST: - case NEIGHBOUR_SOUTH: - case NEIGHBOUR_SOUTHWEST: - case NEIGHBOUR_SOUTHEAST: - *outy = mSize - y - 1; - break; - default: - *outy = y; - break; - }; - } - //--------------------------------------------------------------------- - void Terrain::getPointFromSelfOrNeighbour(long x, long y, Vector3* outpos) const - { - if (x >= 0 && y >=0 && x < mSize && y < mSize) - getPoint(x, y, outpos); - else - { - long nx, ny; - NeighbourIndex ni = NEIGHBOUR_EAST; - getNeighbourPointOverflow(x, y, &ni, &nx, &ny); - Terrain* neighbour = getNeighbour(ni); - if (neighbour) - { - Vector3 neighbourPos = Vector3::ZERO; - neighbour->getPoint(nx, ny, &neighbourPos); - // adjust to make it relative to our position - *outpos = neighbourPos + neighbour->getPosition() - getPosition(); - } - else - { - // use our getPoint() after all, just clamp - x = std::min(x, mSize - 1L); - y = std::min(y, mSize - 1L); - x = std::max(x, 0L); - y = std::max(y, 0L); - getPoint(x, y, outpos); - } - - } - } - //--------------------------------------------------------------------- - void Terrain::getNeighbourPointOverflow(long x, long y, NeighbourIndex *outindex, long *outx, long *outy) const - { - if (x < 0) - { - *outx = x + mSize - 1; - if (y < 0) - *outindex = NEIGHBOUR_SOUTHWEST; - else if (y >= mSize) - *outindex = NEIGHBOUR_NORTHWEST; - else - *outindex = NEIGHBOUR_WEST; - } - else if (x >= mSize) - { - *outx = x - mSize + 1; - if (y < 0) - *outindex = NEIGHBOUR_SOUTHEAST; - else if (y >= mSize) - *outindex = NEIGHBOUR_NORTHEAST; - else - *outindex = NEIGHBOUR_EAST; - } - else - *outx = x; - - if (y < 0) - { - *outy = y + mSize - 1; - if (x >= 0 && x < mSize) - *outindex = NEIGHBOUR_SOUTH; - } - else if (y >= mSize) - { - *outy = y - mSize + 1; - if (x >= 0 && x < mSize) - *outindex = NEIGHBOUR_NORTH; - } - else - *outy = y; - } - //--------------------------------------------------------------------- - Terrain* Terrain::raySelectNeighbour(const Ray& ray, Real distanceLimit /* = 0 */) - { - Ray modifiedRay(ray.getOrigin(), ray.getDirection()); - // Move back half a square - if we're on the edge of the AABB we might - // miss the intersection otherwise; it's ok for everywhere else since - // we want the far intersection anyway - modifiedRay.setOrigin(modifiedRay.getPoint(-mWorldSize/mSize * 0.5f)); - - // transform into terrain space - Vector3 tPos, tDir; - convertPosition(WORLD_SPACE, modifiedRay.getOrigin(), TERRAIN_SPACE, tPos); - convertDirection(WORLD_SPACE, modifiedRay.getDirection(), TERRAIN_SPACE, tDir); - // Discard rays with no lateral component - if (Math::RealEqual(tDir.x, 0.0f, 1e-4) && Math::RealEqual(tDir.y, 0.0f, 1e-4)) - return 0; - - Ray terrainRay(tPos, tDir); - // Intersect with boundary planes - // Only collide with the positive (exit) side of the plane, because we may be - // querying from a point outside ourselves if we've cascaded more than once - Real dist = std::numeric_limits::max(); - std::pair intersectResult; - if (tDir.x < 0.0f) - { - intersectResult = Math::intersects(terrainRay, Plane(Vector3::UNIT_X, Vector3::ZERO)); - if (intersectResult.first && intersectResult.second < dist) - dist = intersectResult.second; - } - else if (tDir.x > 0.0f) - { - intersectResult = Math::intersects(terrainRay, Plane(Vector3::NEGATIVE_UNIT_X, Vector3(1,0,0))); - if (intersectResult.first && intersectResult.second < dist) - dist = intersectResult.second; - } - if (tDir.y < 0.0f) - { - intersectResult = Math::intersects(terrainRay, Plane(Vector3::UNIT_Y, Vector3::ZERO)); - if (intersectResult.first && intersectResult.second < dist) - dist = intersectResult.second; - } - else if (tDir.y > 0.0f) - { - intersectResult = Math::intersects(terrainRay, Plane(Vector3::NEGATIVE_UNIT_Y, Vector3(0,1,0))); - if (intersectResult.first && intersectResult.second < dist) - dist = intersectResult.second; - } - - - // discard out of range - if (dist * mWorldSize > distanceLimit) - return 0; - - Vector3 terrainIntersectPos = terrainRay.getPoint(dist); - Real x = terrainIntersectPos.x; - Real y = terrainIntersectPos.y; - Real dx = tDir.x; - Real dy = tDir.y; - - // Never return diagonal directions, we will navigate those recursively anyway - if (Math::RealEqual(x, 1.0f, 1e-4f) && dx > 0) - return getNeighbour(NEIGHBOUR_EAST); - else if (Math::RealEqual(x, 0.0f, 1e-4f) && dx < 0) - return getNeighbour(NEIGHBOUR_WEST); - else if (Math::RealEqual(y, 1.0f, 1e-4f) && dy > 0) - return getNeighbour(NEIGHBOUR_NORTH); - else if (Math::RealEqual(y, 0.0f, 1e-4f) && dy < 0) - return getNeighbour(NEIGHBOUR_SOUTH); - - - - return 0; - } - //--------------------------------------------------------------------- - void Terrain::_dumpTextures(const String& prefix, const String& suffix) - { - if (!mTerrainNormalMap.isNull()) - { - Image img; - mTerrainNormalMap->convertToImage(img); - img.save(prefix + "_normalmap" + suffix); - } - - if (!mColourMap.isNull()) - { - Image img; - mColourMap->convertToImage(img); - img.save(prefix + "_colourmap" + suffix); - } - - if (!mLightmap.isNull()) - { - Image img; - mLightmap->convertToImage(img); - img.save(prefix + "_lightmap" + suffix); - } - - if (!mCompositeMap.isNull()) - { - Image img; - mCompositeMap->convertToImage(img); - img.save(prefix + "_compositemap" + suffix); - } - - int blendTexture = 0; - for (TexturePtrList::iterator i = mBlendTextureList.begin(); i != mBlendTextureList.end(); ++i, ++blendTexture) - { - if (!i->isNull()) - { - Image img; - (*i)->convertToImage(img); - img.save(prefix + "_blendtexture" + StringConverter::toString(blendTexture) + suffix); - } - } - - } - //--------------------------------------------------------------------- - void Terrain::setGpuBufferAllocator(GpuBufferAllocator* alloc) - { - if (alloc != getGpuBufferAllocator()) - { - if (isLoaded()) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Cannot alter the allocator when loaded!", __FUNCTION__); - - mCustomGpuBufferAllocator = alloc; - } - } - //--------------------------------------------------------------------- - Terrain::GpuBufferAllocator* Terrain::getGpuBufferAllocator() - { - if (mCustomGpuBufferAllocator) - return mCustomGpuBufferAllocator; - else - return &mDefaultGpuBufferAllocator; - } - //--------------------------------------------------------------------- - size_t Terrain::getPositionBufVertexSize() const - { - size_t sz = 0; - if (_getUseVertexCompression()) - { - // short2 position - sz += sizeof(short) * 2; - // float1 height - sz += sizeof(float); - } - else - { - // float3 position - sz += sizeof(float) * 3; - // float2 uv - sz += sizeof(float) * 2; - } - - return sz; - - } - //--------------------------------------------------------------------- - size_t Terrain::getDeltaBufVertexSize() const - { - // float2(delta, deltaLODthreshold) - return sizeof(float) * 2; - } - //--------------------------------------------------------------------- - size_t Terrain::_getNumIndexesForBatchSize(uint16 batchSize) - { - size_t mainIndexesPerRow = batchSize * 2 + 1; - size_t numRows = batchSize - 1; - size_t mainIndexCount = mainIndexesPerRow * numRows; - // skirts share edges, so they take 1 less row per side than batchSize, - // but with 2 extra at the end (repeated) to finish the strip - // * 2 for the vertical line, * 4 for the sides, +2 to finish - size_t skirtIndexCount = (batchSize - 1) * 2 * 4 + 2; - return mainIndexCount + skirtIndexCount; - - } - //--------------------------------------------------------------------- - void Terrain::_populateIndexBuffer(uint16* pI, uint16 batchSize, - uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, - uint16 skirtRowColSkip) - { - /* For even / odd tri strip rows, triangles are this shape: - 6---7---8 - | \ | \ | - 3---4---5 - | / | / | - 0---1---2 - Note how vertex rows count upwards. In order to match up the anti-clockwise - winding and this upward transitioning list, we need to start from the - right hand side. So we get (2,5,1,4,0,3) etc on even lines (right-left) - and (3,6,4,7,5,8) etc on odd lines (left-right). At the turn, we emit the end index - twice, this forms a degenerate triangle, which lets us turn without any artefacts. - So the full list in this simple case is (2,5,1,4,0,3,3,6,4,7,5,8) - - Skirts are part of the same strip, so after finishing on 8, where sX is - the skirt vertex corresponding to main vertex X, we go - anticlockwise around the edge, (s8,7,s7,6,s6) to do the top skirt, - then (3,s3,0,s0),(1,s1,2,s2),(5,s5,8,s8) to finish the left, bottom, and - right skirts respectively. - */ - - // to issue a complete row, it takes issuing the upper and lower row - // and one extra index, which is the degenerate triangle and also turning - // around the winding - - size_t rowSize = vdatasize * vertexIncrement; - size_t numRows = batchSize - 1; - - // Start on the right - uint16 currentVertex = (batchSize - 1) * vertexIncrement; - // but, our quad area might not start at 0 in this vertex data - // offsets are at main terrain resolution, remember - uint16 columnStart = xoffset; - uint16 rowStart = yoffset; - currentVertex += rowStart * vdatasize + columnStart; - bool rightToLeft = true; - for (uint16 r = 0; r < numRows; ++r) - { - for (uint16 c = 0; c < batchSize; ++c) - { - - *pI++ = currentVertex; - *pI++ = currentVertex + rowSize; - - // don't increment / decrement at a border, keep this vertex for next - // row as we 'snake' across the tile - if (c+1 < batchSize) - { - currentVertex = rightToLeft ? - currentVertex - vertexIncrement : currentVertex + vertexIncrement; - } - } - rightToLeft = !rightToLeft; - currentVertex += rowSize; - // issue one extra index to turn winding around - *pI++ = currentVertex; - } - - // Skirts - for (uint16 s = 0; s < 4; ++s) - { - // edgeIncrement is the index offset from one original edge vertex to the next - // in this row or column. Columns skip based on a row size here - // skirtIncrement is the index offset from one skirt vertex to the next, - // because skirts are packed in rows/cols then there is no row multiplier for - // processing columns - int edgeIncrement = 0, skirtIncrement = 0; - switch(s) - { - case 0: // top - edgeIncrement = -static_cast(vertexIncrement); - skirtIncrement = -static_cast(vertexIncrement); - break; - case 1: // left - edgeIncrement = -static_cast(rowSize); - skirtIncrement = -static_cast(vertexIncrement); - break; - case 2: // bottom - edgeIncrement = static_cast(vertexIncrement); - skirtIncrement = static_cast(vertexIncrement); - break; - case 3: // right - edgeIncrement = static_cast(rowSize); - skirtIncrement = static_cast(vertexIncrement); - break; - } - // Skirts are stored in contiguous rows / columns (rows 0/2, cols 1/3) - uint16 skirtIndex = _calcSkirtVertexIndex(currentVertex, vdatasize, - (s % 2) != 0, numSkirtRowsCols, skirtRowColSkip); - for (uint16 c = 0; c < batchSize - 1; ++c) - { - *pI++ = currentVertex; - *pI++ = skirtIndex; - currentVertex += edgeIncrement; - skirtIndex += skirtIncrement; - } - if (s == 3) - { - // we issue an extra 2 indices to finish the skirt off - *pI++ = currentVertex; - *pI++ = skirtIndex; - currentVertex += edgeIncrement; - } - } - - } - //--------------------------------------------------------------------- - uint16 Terrain::_calcSkirtVertexIndex(uint16 mainIndex, uint16 vdatasize, bool isCol, - uint16 numSkirtRowsCols, uint16 skirtRowColSkip) - { - // row / col in main vertex resolution - uint16 row = mainIndex / vdatasize; - uint16 col = mainIndex % vdatasize; - - // skirts are after main vertices, so skip them - uint16 base = vdatasize * vdatasize; - - // The layout in vertex data is: - // 1. row skirts - // numSkirtRowsCols rows of resolution vertices each - // 2. column skirts - // numSkirtRowsCols cols of resolution vertices each - - // No offsets used here, this is an index into the current vertex data, - // which is already relative - if (isCol) - { - uint16 skirtNum = col / skirtRowColSkip; - uint16 colbase = numSkirtRowsCols * vdatasize; - return base + colbase + vdatasize * skirtNum + row; - } - else - { - uint16 skirtNum = row / skirtRowColSkip; - return base + vdatasize * skirtNum + col; - } - - } - //--------------------------------------------------------------------- - void Terrain::setWorldSize(Real newWorldSize) - { - if(mWorldSize != newWorldSize) - { - waitForDerivedProcesses(); - - mWorldSize = newWorldSize; - - updateBaseScale(); - - deriveUVMultipliers(); - - mMaterialParamsDirty = true; - - if(mIsLoaded) - { - Rect dRect(0, 0, mSize, mSize); - dirtyRect(dRect); - update(); - } - - mModified = true; - } - } - //--------------------------------------------------------------------- - void Terrain::setSize(uint16 newSize) - { - if(mSize != newSize) - { - waitForDerivedProcesses(); - // load full HeightData - load(0,true); - - size_t numVertices = newSize * newSize; - - PixelBox src(mSize, mSize, 1, Ogre::PF_FLOAT32_R, (void*)getHeightData()); - - float* tmpData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GENERAL); - - PixelBox dst(newSize, newSize, 1, Ogre::PF_FLOAT32_R, tmpData); - - Image::scale(src, dst, Image::FILTER_BILINEAR); + Image::scale(src, dst, Image::FILTER_BILINEAR); if (!mTerrainNormalMap.isNull()) { @@ -4557,175 +4557,175 @@ namespace Ogre mTerrainNormalMap.setNull(); } - freeLodData(); + freeLodData(); freeCPUResources(); - mLodManager = OGRE_NEW TerrainLodManager( this ); - mSize = newSize; - - determineLodLevels(); - - updateBaseScale(); - - deriveUVMultipliers(); - - mMaterialParamsDirty = true; - - mHeightData = tmpData; - mDeltaData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GEOMETRY); - memset(mDeltaData, 0, sizeof(float) * numVertices); - - mQuadTree = OGRE_NEW TerrainQuadTreeNode(this, 0, 0, 0, mSize, mNumLodLevels - 1, 0, 0); - mQuadTree->prepare(); - - // calculate entire terrain - Rect rect; - rect.top = 0; rect.bottom = mSize; - rect.left = 0; rect.right = mSize; - calculateHeightDeltas(rect); - finaliseHeightDeltas(rect, true); - - if(mIsLoaded) - { - load(0,true); - } - - mModified = true; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - Terrain::DefaultGpuBufferAllocator::DefaultGpuBufferAllocator() - { - - } - //--------------------------------------------------------------------- - Terrain::DefaultGpuBufferAllocator::~DefaultGpuBufferAllocator() - { - freeAllBuffers(); - } - //--------------------------------------------------------------------- - void Terrain::DefaultGpuBufferAllocator::allocateVertexBuffers(Terrain* forTerrain, - size_t numVertices, HardwareVertexBufferSharedPtr& destPos, HardwareVertexBufferSharedPtr& destDelta) - { - destPos = getVertexBuffer(mFreePosBufList, forTerrain->getPositionBufVertexSize(), numVertices); - destDelta = getVertexBuffer(mFreeDeltaBufList, forTerrain->getDeltaBufVertexSize(), numVertices); - - } - //--------------------------------------------------------------------- - HardwareVertexBufferSharedPtr Terrain::DefaultGpuBufferAllocator::getVertexBuffer( - VBufList& list, size_t vertexSize, size_t numVertices) - { - size_t sz = vertexSize * numVertices; - for (VBufList::iterator i = list.begin(); i != list.end(); ++i) - { - if ((*i)->getSizeInBytes() == sz) - { - HardwareVertexBufferSharedPtr ret = *i; - list.erase(i); - return ret; - } - } - // Didn't find one? - return HardwareBufferManager::getSingleton() - .createVertexBuffer(vertexSize, numVertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - - } - //--------------------------------------------------------------------- - void Terrain::DefaultGpuBufferAllocator::freeVertexBuffers( - const HardwareVertexBufferSharedPtr& posbuf, const HardwareVertexBufferSharedPtr& deltabuf) - { - mFreePosBufList.push_back(posbuf); - mFreeDeltaBufList.push_back(deltabuf); - } - //--------------------------------------------------------------------- - HardwareIndexBufferSharedPtr Terrain::DefaultGpuBufferAllocator::getSharedIndexBuffer(uint16 batchSize, - uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, - uint16 skirtRowColSkip) - { - uint32 hsh = hashIndexBuffer(batchSize, vdatasize, vertexIncrement, xoffset, yoffset, - numSkirtRowsCols, skirtRowColSkip); - - IBufMap::iterator i = mSharedIBufMap.find(hsh); - if (i == mSharedIBufMap.end()) - { - // create new - size_t indexCount = Terrain::_getNumIndexesForBatchSize(batchSize); - HardwareIndexBufferSharedPtr ret = HardwareBufferManager::getSingleton() - .createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - uint16* pI = static_cast(ret->lock(HardwareBuffer::HBL_DISCARD)); - Terrain::_populateIndexBuffer(pI, batchSize, vdatasize, vertexIncrement, xoffset, yoffset, numSkirtRowsCols, skirtRowColSkip); - ret->unlock(); - - mSharedIBufMap[hsh] = ret; - return ret; - } - else - return i->second; - - } - //--------------------------------------------------------------------- - void Terrain::DefaultGpuBufferAllocator::freeAllBuffers() - { - mFreePosBufList.clear(); - mFreeDeltaBufList.clear(); - mSharedIBufMap.clear(); - } - //--------------------------------------------------------------------- - void Terrain::DefaultGpuBufferAllocator::warmStart(size_t numInstances, uint16 terrainSize, uint16 maxBatchSize, - uint16 minBatchSize) - { - // TODO - - } - //--------------------------------------------------------------------- - uint32 Terrain::DefaultGpuBufferAllocator::hashIndexBuffer(uint16 batchSize, - uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, - uint16 skirtRowColSkip) - { - uint32 ret = 0; - ret = HashCombine(ret, batchSize); - ret = HashCombine(ret, vdatasize); - ret = HashCombine(ret, vertexIncrement); - ret = HashCombine(ret, xoffset); - ret = HashCombine(ret, yoffset); - ret = HashCombine(ret, numSkirtRowsCols); - ret = HashCombine(ret, skirtRowColSkip); - return ret; - - } - //--------------------------------------------------------------------- - void Terrain::increaseLodLevel(bool synchronous /* = false */) - { - int lodLevel = mLodManager->getTargetLodLevel(); - if(lodLevel<0) - mLodManager->updateToLodLevel(-1, synchronous); - else if( --lodLevel >= 0 ) - mLodManager->updateToLodLevel(lodLevel, synchronous); - } - //--------------------------------------------------------------------- - void Terrain::decreaseLodLevel() - { - int lodLevel = mLodManager->getTargetLodLevel() + 1; - if( lodLevel>0 && lodLevelupdateToLodLevel(lodLevel); - } - - void Terrain::removeFromNeighbours() - { - // We are reading the list of neighbours here - OGRE_LOCK_RW_MUTEX_READ(mNeighbourMutex); - for (int i = 0; i < (int)NEIGHBOUR_COUNT; ++i) - { - NeighbourIndex ni = static_cast(i); - Terrain* neighbour = getNeighbour(ni); - if (!neighbour) - continue; - - OGRE_LOCK_RW_MUTEX_WRITE(neighbour->mNeighbourMutex); - // TODO: do we want to re-calculate? probably not, but not sure - neighbour->setNeighbour(getOppositeNeighbour(ni), 0, false, false); - } - } + mLodManager = OGRE_NEW TerrainLodManager( this ); + mSize = newSize; + + determineLodLevels(); + + updateBaseScale(); + + deriveUVMultipliers(); + + mMaterialParamsDirty = true; + + mHeightData = tmpData; + mDeltaData = OGRE_ALLOC_T(float, numVertices, MEMCATEGORY_GEOMETRY); + memset(mDeltaData, 0, sizeof(float) * numVertices); + + mQuadTree = OGRE_NEW TerrainQuadTreeNode(this, 0, 0, 0, mSize, mNumLodLevels - 1, 0, 0); + mQuadTree->prepare(); + + // calculate entire terrain + Rect rect; + rect.top = 0; rect.bottom = mSize; + rect.left = 0; rect.right = mSize; + calculateHeightDeltas(rect); + finaliseHeightDeltas(rect, true); + + if(mIsLoaded) + { + load(0,true); + } + + mModified = true; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + Terrain::DefaultGpuBufferAllocator::DefaultGpuBufferAllocator() + { + + } + //--------------------------------------------------------------------- + Terrain::DefaultGpuBufferAllocator::~DefaultGpuBufferAllocator() + { + freeAllBuffers(); + } + //--------------------------------------------------------------------- + void Terrain::DefaultGpuBufferAllocator::allocateVertexBuffers(Terrain* forTerrain, + size_t numVertices, HardwareVertexBufferSharedPtr& destPos, HardwareVertexBufferSharedPtr& destDelta) + { + destPos = getVertexBuffer(mFreePosBufList, forTerrain->getPositionBufVertexSize(), numVertices); + destDelta = getVertexBuffer(mFreeDeltaBufList, forTerrain->getDeltaBufVertexSize(), numVertices); + + } + //--------------------------------------------------------------------- + HardwareVertexBufferSharedPtr Terrain::DefaultGpuBufferAllocator::getVertexBuffer( + VBufList& list, size_t vertexSize, size_t numVertices) + { + size_t sz = vertexSize * numVertices; + for (VBufList::iterator i = list.begin(); i != list.end(); ++i) + { + if ((*i)->getSizeInBytes() == sz) + { + HardwareVertexBufferSharedPtr ret = *i; + list.erase(i); + return ret; + } + } + // Didn't find one? + return HardwareBufferManager::getSingleton() + .createVertexBuffer(vertexSize, numVertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); + + + } + //--------------------------------------------------------------------- + void Terrain::DefaultGpuBufferAllocator::freeVertexBuffers( + const HardwareVertexBufferSharedPtr& posbuf, const HardwareVertexBufferSharedPtr& deltabuf) + { + mFreePosBufList.push_back(posbuf); + mFreeDeltaBufList.push_back(deltabuf); + } + //--------------------------------------------------------------------- + HardwareIndexBufferSharedPtr Terrain::DefaultGpuBufferAllocator::getSharedIndexBuffer(uint16 batchSize, + uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, + uint16 skirtRowColSkip) + { + uint32 hsh = hashIndexBuffer(batchSize, vdatasize, vertexIncrement, xoffset, yoffset, + numSkirtRowsCols, skirtRowColSkip); + + IBufMap::iterator i = mSharedIBufMap.find(hsh); + if (i == mSharedIBufMap.end()) + { + // create new + size_t indexCount = Terrain::_getNumIndexesForBatchSize(batchSize); + HardwareIndexBufferSharedPtr ret = HardwareBufferManager::getSingleton() + .createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + uint16* pI = static_cast(ret->lock(HardwareBuffer::HBL_DISCARD)); + Terrain::_populateIndexBuffer(pI, batchSize, vdatasize, vertexIncrement, xoffset, yoffset, numSkirtRowsCols, skirtRowColSkip); + ret->unlock(); + + mSharedIBufMap[hsh] = ret; + return ret; + } + else + return i->second; + + } + //--------------------------------------------------------------------- + void Terrain::DefaultGpuBufferAllocator::freeAllBuffers() + { + mFreePosBufList.clear(); + mFreeDeltaBufList.clear(); + mSharedIBufMap.clear(); + } + //--------------------------------------------------------------------- + void Terrain::DefaultGpuBufferAllocator::warmStart(size_t numInstances, uint16 terrainSize, uint16 maxBatchSize, + uint16 minBatchSize) + { + // TODO + + } + //--------------------------------------------------------------------- + uint32 Terrain::DefaultGpuBufferAllocator::hashIndexBuffer(uint16 batchSize, + uint16 vdatasize, size_t vertexIncrement, uint16 xoffset, uint16 yoffset, uint16 numSkirtRowsCols, + uint16 skirtRowColSkip) + { + uint32 ret = 0; + ret = HashCombine(ret, batchSize); + ret = HashCombine(ret, vdatasize); + ret = HashCombine(ret, vertexIncrement); + ret = HashCombine(ret, xoffset); + ret = HashCombine(ret, yoffset); + ret = HashCombine(ret, numSkirtRowsCols); + ret = HashCombine(ret, skirtRowColSkip); + return ret; + + } + //--------------------------------------------------------------------- + void Terrain::increaseLodLevel(bool synchronous /* = false */) + { + int lodLevel = mLodManager->getTargetLodLevel(); + if(lodLevel<0) + mLodManager->updateToLodLevel(-1, synchronous); + else if( --lodLevel >= 0 ) + mLodManager->updateToLodLevel(lodLevel, synchronous); + } + //--------------------------------------------------------------------- + void Terrain::decreaseLodLevel() + { + int lodLevel = mLodManager->getTargetLodLevel() + 1; + if( lodLevel>0 && lodLevelupdateToLodLevel(lodLevel); + } + + void Terrain::removeFromNeighbours() + { + // We are reading the list of neighbours here + OGRE_LOCK_RW_MUTEX_READ(mNeighbourMutex); + for (int i = 0; i < (int)NEIGHBOUR_COUNT; ++i) + { + NeighbourIndex ni = static_cast(i); + Terrain* neighbour = getNeighbour(ni); + if (!neighbour) + continue; + + OGRE_LOCK_RW_MUTEX_WRITE(neighbour->mNeighbourMutex); + // TODO: do we want to re-calculate? probably not, but not sure + neighbour->setNeighbour(getOppositeNeighbour(ni), 0, false, false); + } + } } diff --git a/Components/Terrain/src/OgreTerrainAutoUpdateLod.cpp b/Components/Terrain/src/OgreTerrainAutoUpdateLod.cpp index 6d4acb6ac14..8c9545be28b 100644 --- a/Components/Terrain/src/OgreTerrainAutoUpdateLod.cpp +++ b/Components/Terrain/src/OgreTerrainAutoUpdateLod.cpp @@ -45,105 +45,105 @@ THE SOFTWARE. namespace Ogre { - void TerrainAutoUpdateLodByDistance::autoUpdateLod(Terrain *terrain, bool synchronous, const Any &data) - { - if( terrain ) - autoUpdateLodByDistance(terrain, synchronous, any_cast(data)); - } - - void TerrainAutoUpdateLodByDistance::autoUpdateLodByDistance(Terrain *terrain, bool synchronous, const Real holdDistance) - { - if (!terrain->isLoaded()) - return; - - // calculate error terms - const Viewport* vp = terrain->getSceneManager()->getCurrentViewport(); - if(!vp) - return; - const Camera* cam = vp->getCamera()->getLodCamera(); - - // W. de Boer 2000 calculation - // A = vp_near / abs(vp_top) - // A = 1 / tan(fovy*0.5) (== 1 for fovy=45*2) - Real A = 1.0f / Math::Tan(cam->getFOVy() * 0.5f); - // T = 2 * maxPixelError / vertRes - Real maxPixelError = TerrainGlobalOptions::getSingleton().getMaxPixelError() * cam->_getLodBiasInverse(); - Real T = 2.0f * maxPixelError / (Real)vp->getActualHeight(); - - // CFactor = A / T - Real cFactor = A / T; - - int maxLod = traverseTreeByDistance(terrain->getQuadTree(), cam, cFactor, holdDistance); - if (maxLod >= 0) - terrain->load(maxLod,synchronous); - } - - int TerrainAutoUpdateLodByDistance::traverseTreeByDistance(TerrainQuadTreeNode *node, - const Camera *cam, Real cFactor, const Real holdDistance) - { - if (!node->isLeaf()) - { - int tmp = -1; - for (int i = 0; i < 4; ++i) - { - int ret = traverseTreeByDistance(node->getChild(i), cam, cFactor, holdDistance); - if (ret != -1) - { - if (tmp == -1 || ret < tmp) - tmp = ret; - } - } - - if (tmp != -1) - return tmp; - } - - Vector3 localPos = cam->getDerivedPosition() - node->getLocalCentre() - node->getTerrain()->getPosition(); - Real dist; - if (TerrainGlobalOptions::getSingleton().getUseRayBoxDistanceCalculation()) - { - // Get distance to this terrain node (to closest point of the box) - // head towards centre of the box (note, box may not cover mLocalCentre because of height) - Vector3 dir(node->getAABB().getCenter() - localPos); - dir.normalise(); - Ray ray(localPos, dir); - std::pair intersectRes = Math::intersects(ray, node->getAABB()); - - // ray will always intersect, we just want the distance - dist = intersectRes.second; - } - else - { - // distance to tile centre - dist = localPos.length(); - // deduct half the radius of the box, assume that on average the - // worst case is best approximated by this - dist -= (node->getBoundingRadius() * 0.5f); - } - - // For each LOD, the distance at which the LOD will transition *downwards* - // is given by - // distTransition = maxDelta * cFactor; - for (uint16 lodLevel = 0; lodLevel < node->getLodCount(); ++lodLevel) - { - // If we have no parent, and this is the lowest LOD, we always render - // this is the 'last resort' so to speak, we always enoucnter this last - if (lodLevel+1 == node->getLodCount() && !node->getParent()) - return lodLevel + node->getBaseLod(); - else - { - // Calculate or reuse transition distance - Real distTransition; - if (Math::RealEqual(cFactor, node->getLodLevel(lodLevel)->lastCFactor)) - distTransition = node->getLodLevel(lodLevel)->lastTransitionDist; - else - distTransition = node->getLodLevel(lodLevel)->maxHeightDelta * cFactor; - - if ((dist - holdDistance) < distTransition) - return lodLevel + node->getBaseLod(); - } - } - - return -1; - } + void TerrainAutoUpdateLodByDistance::autoUpdateLod(Terrain *terrain, bool synchronous, const Any &data) + { + if( terrain ) + autoUpdateLodByDistance(terrain, synchronous, any_cast(data)); + } + + void TerrainAutoUpdateLodByDistance::autoUpdateLodByDistance(Terrain *terrain, bool synchronous, const Real holdDistance) + { + if (!terrain->isLoaded()) + return; + + // calculate error terms + const Viewport* vp = terrain->getSceneManager()->getCurrentViewport(); + if(!vp) + return; + const Camera* cam = vp->getCamera()->getLodCamera(); + + // W. de Boer 2000 calculation + // A = vp_near / abs(vp_top) + // A = 1 / tan(fovy*0.5) (== 1 for fovy=45*2) + Real A = 1.0f / Math::Tan(cam->getFOVy() * 0.5f); + // T = 2 * maxPixelError / vertRes + Real maxPixelError = TerrainGlobalOptions::getSingleton().getMaxPixelError() * cam->_getLodBiasInverse(); + Real T = 2.0f * maxPixelError / (Real)vp->getActualHeight(); + + // CFactor = A / T + Real cFactor = A / T; + + int maxLod = traverseTreeByDistance(terrain->getQuadTree(), cam, cFactor, holdDistance); + if (maxLod >= 0) + terrain->load(maxLod,synchronous); + } + + int TerrainAutoUpdateLodByDistance::traverseTreeByDistance(TerrainQuadTreeNode *node, + const Camera *cam, Real cFactor, const Real holdDistance) + { + if (!node->isLeaf()) + { + int tmp = -1; + for (int i = 0; i < 4; ++i) + { + int ret = traverseTreeByDistance(node->getChild(i), cam, cFactor, holdDistance); + if (ret != -1) + { + if (tmp == -1 || ret < tmp) + tmp = ret; + } + } + + if (tmp != -1) + return tmp; + } + + Vector3 localPos = cam->getDerivedPosition() - node->getLocalCentre() - node->getTerrain()->getPosition(); + Real dist; + if (TerrainGlobalOptions::getSingleton().getUseRayBoxDistanceCalculation()) + { + // Get distance to this terrain node (to closest point of the box) + // head towards centre of the box (note, box may not cover mLocalCentre because of height) + Vector3 dir(node->getAABB().getCenter() - localPos); + dir.normalise(); + Ray ray(localPos, dir); + std::pair intersectRes = Math::intersects(ray, node->getAABB()); + + // ray will always intersect, we just want the distance + dist = intersectRes.second; + } + else + { + // distance to tile centre + dist = localPos.length(); + // deduct half the radius of the box, assume that on average the + // worst case is best approximated by this + dist -= (node->getBoundingRadius() * 0.5f); + } + + // For each LOD, the distance at which the LOD will transition *downwards* + // is given by + // distTransition = maxDelta * cFactor; + for (uint16 lodLevel = 0; lodLevel < node->getLodCount(); ++lodLevel) + { + // If we have no parent, and this is the lowest LOD, we always render + // this is the 'last resort' so to speak, we always enoucnter this last + if (lodLevel+1 == node->getLodCount() && !node->getParent()) + return lodLevel + node->getBaseLod(); + else + { + // Calculate or reuse transition distance + Real distTransition; + if (Math::RealEqual(cFactor, node->getLodLevel(lodLevel)->lastCFactor)) + distTransition = node->getLodLevel(lodLevel)->lastTransitionDist; + else + distTransition = node->getLodLevel(lodLevel)->maxHeightDelta * cFactor; + + if ((dist - holdDistance) < distTransition) + return lodLevel + node->getBaseLod(); + } + } + + return -1; + } } diff --git a/Components/Terrain/src/OgreTerrainGroup.cpp b/Components/Terrain/src/OgreTerrainGroup.cpp index 9d77af1566d..dca98b32dd2 100644 --- a/Components/Terrain/src/OgreTerrainGroup.cpp +++ b/Components/Terrain/src/OgreTerrainGroup.cpp @@ -35,998 +35,998 @@ THE SOFTWARE. namespace Ogre { - const uint16 TerrainGroup::WORKQUEUE_LOAD_REQUEST = 1; - const uint32 TerrainGroup::CHUNK_ID = StreamSerialiser::makeIdentifier("TERG"); - const uint16 TerrainGroup::CHUNK_VERSION = 1; - uint TerrainGroup::LoadRequest::loadingTaskNum = 0; - - //--------------------------------------------------------------------- - TerrainGroup::TerrainGroup(SceneManager* sm, Terrain::Alignment align, - uint16 terrainSize, Real terrainWorldSize) - : mSceneManager(sm) - , mAlignment(align) - , mTerrainSize(terrainSize) - , mTerrainWorldSize(terrainWorldSize) - , mOrigin(Vector3::ZERO) - , mFilenamePrefix("terrain") - , mFilenameExtension("dat") - , mResourceGroup(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) - , mAutoUpdateLod( TerrainAutoUpdateLodFactory::getAutoUpdateLod(NONE) ) - { - mDefaultImportData.terrainAlign = align; - mDefaultImportData.terrainSize = terrainSize; - mDefaultImportData.worldSize = terrainWorldSize; - // by default we delete input data because we copy it, unless user - // passes us an ImportData where they explicitly don't want it copied - mDefaultImportData.deleteInputData = true; - - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - mWorkQueueChannel = wq->getChannel("Ogre/TerrainGroup"); - wq->addRequestHandler(mWorkQueueChannel, this); - wq->addResponseHandler(mWorkQueueChannel, this); - - } - //--------------------------------------------------------------------- - TerrainGroup::TerrainGroup(SceneManager* sm) - : mSceneManager(sm) - , mAlignment(Terrain::ALIGN_X_Z) - , mTerrainSize(0) - , mTerrainWorldSize(0) - , mOrigin(Vector3::ZERO) - , mFilenamePrefix("terrain") - , mFilenameExtension("dat") - , mResourceGroup(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) - , mAutoUpdateLod(0) - { - mDefaultImportData.terrainAlign = mAlignment; - mDefaultImportData.terrainSize = 0; - mDefaultImportData.worldSize = 0; - // by default we delete input data because we copy it, unless user - // passes us an ImportData where they explicitly don't want it copied - mDefaultImportData.deleteInputData = true; - - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - mWorkQueueChannel = wq->getChannel("Ogre/TerrainGroup"); - wq->addRequestHandler(mWorkQueueChannel, this); - wq->addResponseHandler(mWorkQueueChannel, this); - } - //--------------------------------------------------------------------- - TerrainGroup::~TerrainGroup() - { - if(mAutoUpdateLod) - { - OGRE_DELETE mAutoUpdateLod; - mAutoUpdateLod = 0; - } - - // waiting for terrain preparing finished - while(LoadRequest::loadingTaskNum>0) - { - OGRE_THREAD_SLEEP(50); - Root::getSingleton().getWorkQueue()->processResponses(); - } - - removeAllTerrains(); - - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - wq->removeRequestHandler(mWorkQueueChannel, this); - wq->removeResponseHandler(mWorkQueueChannel, this); - - } - //--------------------------------------------------------------------- - void TerrainGroup::setOrigin(const Vector3& pos) - { - if (pos != mOrigin) - { - mOrigin = pos; - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - TerrainSlot* slot = i->second; - if (slot->instance) - { - slot->instance->setPosition(getTerrainSlotPosition(slot->x, slot->y)); - } - } - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::setFilenameConvention(const String& prefix, const String& extension) - { - mFilenamePrefix = prefix; - mFilenameExtension = extension; - } - //--------------------------------------------------------------------- - void TerrainGroup::setFilenamePrefix(const String& prefix) - { - mFilenamePrefix = prefix; - } - //--------------------------------------------------------------------- - void TerrainGroup::setFilenameExtension(const String& extension) - { - mFilenameExtension = extension; - } - //--------------------------------------------------------------------- - void TerrainGroup::defineTerrain(long x, long y) - { - defineTerrain(x, y, generateFilename(x, y)); - } - //--------------------------------------------------------------------- - void TerrainGroup::defineTerrain(long x, long y, float constantHeight) - { - TerrainSlot* slot = getTerrainSlot(x, y, true); - - slot->def.useImportData(); - - // Copy all settings, but make sure our primary settings are immutable - *slot->def.importData = mDefaultImportData; - slot->def.importData->constantHeight = constantHeight; - slot->def.importData->terrainAlign = mAlignment; - slot->def.importData->terrainSize = mTerrainSize; - slot->def.importData->worldSize = mTerrainWorldSize; - } - //--------------------------------------------------------------------- - void TerrainGroup::defineTerrain(long x, long y, const Terrain::ImportData* importData) - { - TerrainSlot* slot = getTerrainSlot(x, y, true); - - slot->def.useImportData(); - - // Copy all settings, but make sure our primary settings are immutable - *slot->def.importData = *importData; - slot->def.importData->terrainAlign = mAlignment; - slot->def.importData->terrainSize = mTerrainSize; - slot->def.importData->worldSize = mTerrainWorldSize; - - } - //--------------------------------------------------------------------- - void TerrainGroup::defineTerrain(long x, long y, const Image* img, - const Terrain::LayerInstanceList* layers /*= 0*/) - { - TerrainSlot* slot = getTerrainSlot(x, y, true); - - slot->freeInstance(); - slot->def.useImportData(); - - *slot->def.importData = mDefaultImportData; - - // Copy all settings, but make sure our primary settings are immutable - // copy image - this will get deleted by importData - slot->def.importData->inputImage = OGRE_NEW Image(*img); - if (layers) - { - // copy (held by value) - slot->def.importData->layerList = *layers; - } - slot->def.importData->terrainAlign = mAlignment; - slot->def.importData->terrainSize = mTerrainSize; - slot->def.importData->worldSize = mTerrainWorldSize; - - } - //--------------------------------------------------------------------- - void TerrainGroup::defineTerrain(long x, long y, const float* pFloat /*= 0*/, - const Terrain::LayerInstanceList* layers /*= 0*/) - { - TerrainSlot* slot = getTerrainSlot(x, y, true); - - slot->freeInstance(); - slot->def.useImportData(); - - *slot->def.importData = mDefaultImportData; - - // Copy all settings, but make sure our primary settings are immutable - if(pFloat) - { - // copy data - this will get deleted by importData - slot->def.importData->inputFloat = OGRE_ALLOC_T(float, mTerrainSize*mTerrainSize, MEMCATEGORY_GEOMETRY); - memcpy(slot->def.importData->inputFloat, pFloat, sizeof(float) * mTerrainSize*mTerrainSize); - } - if (layers) - { - // copy (held by value) - slot->def.importData->layerList = *layers; - } - slot->def.importData->terrainAlign = mAlignment; - slot->def.importData->terrainSize = mTerrainSize; - slot->def.importData->worldSize = mTerrainWorldSize; - - } - //--------------------------------------------------------------------- - void TerrainGroup::defineTerrain(long x, long y, const String& filename) - { - TerrainSlot* slot = getTerrainSlot(x, y, true); - - slot->freeInstance(); - - slot->def.useFilename(); - slot->def.filename = filename; - - } - //--------------------------------------------------------------------- - void TerrainGroup::loadAllTerrains(bool synchronous /*= false*/) - { - // Just a straight iteration - for the numbers involved not worth - // keeping a loaded / unloaded list - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - TerrainSlot* slot = i->second; - loadTerrainImpl(slot, synchronous); - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::saveAllTerrains(bool onlyIfModified, bool replaceFilenames) - { - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - TerrainSlot* slot = i->second; - if (slot->instance) - { - Terrain* t = slot->instance; - if (t->isLoaded() && - (!onlyIfModified || t->isModified())) - { - // Overwrite the file names? - if (replaceFilenames) - slot->def.filename = generateFilename(slot->x, slot->y); - - String filename; - if (!slot->def.filename.empty()) - filename = slot->def.filename; - else - filename = generateFilename(slot->x, slot->y); - - t->save(filename); - - } - } - - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::loadTerrain(long x, long y, bool synchronous /*= false*/) - { - TerrainSlot* slot = getTerrainSlot(x, y, false); - if (slot) - { - loadTerrainImpl(slot, synchronous); - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::loadTerrainImpl(TerrainSlot* slot, bool synchronous) - { - if (!slot->instance && - (!slot->def.filename.empty() || slot->def.importData)) - { - // Allocate in main thread so no race conditions - slot->instance = OGRE_NEW Terrain(mSceneManager); - slot->instance->setResourceGroup(mResourceGroup); - // Use shared pool of buffers - slot->instance->setGpuBufferAllocator(&mBufferAllocator); - - LoadRequest req; - req.slot = slot; - req.origin = this; - ++LoadRequest::loadingTaskNum; - Root::getSingleton().getWorkQueue()->addRequest( - mWorkQueueChannel, WORKQUEUE_LOAD_REQUEST, - Any(req), 0, synchronous); - - } - } - //--------------------------------------------------------------------- - void TerrainGroup::increaseLodLevel(long x, long y, bool synchronous /* = false */) - { - TerrainSlot* slot = getTerrainSlot(x, y, false); - if (slot && slot->instance) - { - slot->instance->increaseLodLevel(synchronous); - } - } - void TerrainGroup::decreaseLodLevel(long x, long y) - { - TerrainSlot* slot = getTerrainSlot(x, y, false); - if (slot && slot->instance) - { - slot->instance->decreaseLodLevel(); - } - } - //--------------------------------------------------------------------- - void TerrainGroup::setAutoUpdateLod(TerrainAutoUpdateLod* updater) - { - if(mAutoUpdateLod) - OGRE_DELETE mAutoUpdateLod; - mAutoUpdateLod = updater; - } - //--------------------------------------------------------------------- - void TerrainGroup::autoUpdateLod(long x, long y, bool synchronous, const Any &data) - { - if(mAutoUpdateLod) - { - TerrainSlot* slot = getTerrainSlot(x, y, synchronous); - if (slot) - { - mAutoUpdateLod->autoUpdateLod(slot->instance, synchronous, data); - } - } - } - //--------------------------------------------------------------------- - void TerrainGroup::autoUpdateLodAll(bool synchronous, const Any &data) - { - if(mAutoUpdateLod) - { - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - TerrainSlot* slot = i->second; - mAutoUpdateLod->autoUpdateLod(slot->instance, synchronous, data); - } - } - } - //--------------------------------------------------------------------- - void TerrainGroup::unloadTerrain(long x, long y) - { - TerrainSlot* slot = getTerrainSlot(x, y, false); - if (slot) - { - slot->freeInstance(); - } - - - } - //--------------------------------------------------------------------- - void TerrainGroup::removeTerrain(long x, long y) - { - uint32 key = packIndex(x, y); - TerrainSlotMap::iterator i = mTerrainSlots.find(key); - if (i != mTerrainSlots.end()) - { - OGRE_DELETE i->second; - mTerrainSlots.erase(i); - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::removeAllTerrains() - { - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - OGRE_DELETE i->second; - } - mTerrainSlots.clear(); - // Also clear buffer pools, if we're clearing completely may not be representative - mBufferAllocator.freeAllBuffers(); - } - //--------------------------------------------------------------------- - TerrainGroup::TerrainSlotDefinition* TerrainGroup::getTerrainDefinition(long x, long y) const - { - TerrainSlot* slot = getTerrainSlot(x, y); - if (slot) - return &slot->def; - else - return 0; - - } - //--------------------------------------------------------------------- - Terrain* TerrainGroup::getTerrain(long x, long y) const - { - TerrainSlot* slot = getTerrainSlot(x, y); - if (slot) - return slot->instance; - else - return 0; - } - //--------------------------------------------------------------------- - float TerrainGroup::getHeightAtWorldPosition(Real x, Real y, Real z, Terrain** ppTerrain /* = 0*/) - { - return getHeightAtWorldPosition(Vector3(x, y, z), ppTerrain); - - } - //--------------------------------------------------------------------- - float TerrainGroup::getHeightAtWorldPosition(const Vector3& pos, Terrain** ppTerrain /*= 0*/) - { - long x, y; - convertWorldPositionToTerrainSlot(pos, &x, &y); - TerrainSlot* slot = getTerrainSlot(x, y); - if (slot && slot->instance && slot->instance->isLoaded()) - { - if (ppTerrain) - *ppTerrain = slot->instance; - return slot->instance->getHeightAtWorldPosition(pos); - } - else - { - if (ppTerrain) - *ppTerrain = 0; - return 0; - } - } - //--------------------------------------------------------------------- - TerrainGroup::RayResult TerrainGroup::rayIntersects(const Ray& ray, Real distanceLimit /* = 0*/) const - { - long curr_x, curr_z; - convertWorldPositionToTerrainSlot(ray.getOrigin(), &curr_x, &curr_z); - TerrainSlot* slot = getTerrainSlot(curr_x, curr_z); - RayResult result(false, 0, Vector3::ZERO); - - Vector3 tmp, localRayDir, centreOrigin, offset; - // get the middle of the current tile - convertTerrainSlotToWorldPosition(curr_x, curr_z, ¢reOrigin); - offset = ray.getOrigin() - centreOrigin; - localRayDir = ray.getDirection(); - switch (getAlignment()) - { - case Terrain::ALIGN_X_Y: - std::swap(localRayDir.y, localRayDir.z); - std::swap(offset.y, offset.z); - break; - case Terrain::ALIGN_Y_Z: - // x = z, z = y, y = -x - tmp.x = localRayDir.z; - tmp.z = localRayDir.y; - tmp.y = -localRayDir.x; - localRayDir = tmp; - tmp.x = offset.z; - tmp.z = offset.y; - tmp.y = -offset.x; - offset = tmp; - break; - case Terrain::ALIGN_X_Z: - // already in X/Z but values increase in -Z - localRayDir.z = -localRayDir.z; - offset.z = -offset.z; - break; - } - // Normalise the offset based on the world size of a square, and rebase to the bottom left - offset /= mTerrainWorldSize; - offset += 0.5f; - // this is our counter moving away from the 'current' square - Vector3 inc(Math::Abs(localRayDir.x), Math::Abs(localRayDir.y), Math::Abs(localRayDir.z)); - long xdir = localRayDir.x > 0.0f ? 1 : -1; - long zdir = localRayDir.z > 0.0f ? 1 : -1; - - // We're always counting from 0 to 1 regardless of what direction we're heading - if (xdir < 0) - offset.x = 1.0f - offset.x; - if (zdir < 0) - offset.z = 1.0f - offset.z; - - // find next slot - bool keepSearching = true; - int numGaps = 0; - while(keepSearching) - { - if (Math::RealEqual(inc.x, 0.0f) && Math::RealEqual(inc.z, 0.0f)) - keepSearching = false; + const uint16 TerrainGroup::WORKQUEUE_LOAD_REQUEST = 1; + const uint32 TerrainGroup::CHUNK_ID = StreamSerialiser::makeIdentifier("TERG"); + const uint16 TerrainGroup::CHUNK_VERSION = 1; + uint TerrainGroup::LoadRequest::loadingTaskNum = 0; + + //--------------------------------------------------------------------- + TerrainGroup::TerrainGroup(SceneManager* sm, Terrain::Alignment align, + uint16 terrainSize, Real terrainWorldSize) + : mSceneManager(sm) + , mAlignment(align) + , mTerrainSize(terrainSize) + , mTerrainWorldSize(terrainWorldSize) + , mOrigin(Vector3::ZERO) + , mFilenamePrefix("terrain") + , mFilenameExtension("dat") + , mResourceGroup(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) + , mAutoUpdateLod( TerrainAutoUpdateLodFactory::getAutoUpdateLod(NONE) ) + { + mDefaultImportData.terrainAlign = align; + mDefaultImportData.terrainSize = terrainSize; + mDefaultImportData.worldSize = terrainWorldSize; + // by default we delete input data because we copy it, unless user + // passes us an ImportData where they explicitly don't want it copied + mDefaultImportData.deleteInputData = true; + + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + mWorkQueueChannel = wq->getChannel("Ogre/TerrainGroup"); + wq->addRequestHandler(mWorkQueueChannel, this); + wq->addResponseHandler(mWorkQueueChannel, this); + + } + //--------------------------------------------------------------------- + TerrainGroup::TerrainGroup(SceneManager* sm) + : mSceneManager(sm) + , mAlignment(Terrain::ALIGN_X_Z) + , mTerrainSize(0) + , mTerrainWorldSize(0) + , mOrigin(Vector3::ZERO) + , mFilenamePrefix("terrain") + , mFilenameExtension("dat") + , mResourceGroup(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) + , mAutoUpdateLod(0) + { + mDefaultImportData.terrainAlign = mAlignment; + mDefaultImportData.terrainSize = 0; + mDefaultImportData.worldSize = 0; + // by default we delete input data because we copy it, unless user + // passes us an ImportData where they explicitly don't want it copied + mDefaultImportData.deleteInputData = true; + + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + mWorkQueueChannel = wq->getChannel("Ogre/TerrainGroup"); + wq->addRequestHandler(mWorkQueueChannel, this); + wq->addResponseHandler(mWorkQueueChannel, this); + } + //--------------------------------------------------------------------- + TerrainGroup::~TerrainGroup() + { + if(mAutoUpdateLod) + { + OGRE_DELETE mAutoUpdateLod; + mAutoUpdateLod = 0; + } + + // waiting for terrain preparing finished + while(LoadRequest::loadingTaskNum>0) + { + OGRE_THREAD_SLEEP(50); + Root::getSingleton().getWorkQueue()->processResponses(); + } + + removeAllTerrains(); + + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + wq->removeRequestHandler(mWorkQueueChannel, this); + wq->removeResponseHandler(mWorkQueueChannel, this); + + } + //--------------------------------------------------------------------- + void TerrainGroup::setOrigin(const Vector3& pos) + { + if (pos != mOrigin) + { + mOrigin = pos; + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + TerrainSlot* slot = i->second; + if (slot->instance) + { + slot->instance->setPosition(getTerrainSlotPosition(slot->x, slot->y)); + } + } + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::setFilenameConvention(const String& prefix, const String& extension) + { + mFilenamePrefix = prefix; + mFilenameExtension = extension; + } + //--------------------------------------------------------------------- + void TerrainGroup::setFilenamePrefix(const String& prefix) + { + mFilenamePrefix = prefix; + } + //--------------------------------------------------------------------- + void TerrainGroup::setFilenameExtension(const String& extension) + { + mFilenameExtension = extension; + } + //--------------------------------------------------------------------- + void TerrainGroup::defineTerrain(long x, long y) + { + defineTerrain(x, y, generateFilename(x, y)); + } + //--------------------------------------------------------------------- + void TerrainGroup::defineTerrain(long x, long y, float constantHeight) + { + TerrainSlot* slot = getTerrainSlot(x, y, true); + + slot->def.useImportData(); + + // Copy all settings, but make sure our primary settings are immutable + *slot->def.importData = mDefaultImportData; + slot->def.importData->constantHeight = constantHeight; + slot->def.importData->terrainAlign = mAlignment; + slot->def.importData->terrainSize = mTerrainSize; + slot->def.importData->worldSize = mTerrainWorldSize; + } + //--------------------------------------------------------------------- + void TerrainGroup::defineTerrain(long x, long y, const Terrain::ImportData* importData) + { + TerrainSlot* slot = getTerrainSlot(x, y, true); + + slot->def.useImportData(); + + // Copy all settings, but make sure our primary settings are immutable + *slot->def.importData = *importData; + slot->def.importData->terrainAlign = mAlignment; + slot->def.importData->terrainSize = mTerrainSize; + slot->def.importData->worldSize = mTerrainWorldSize; + + } + //--------------------------------------------------------------------- + void TerrainGroup::defineTerrain(long x, long y, const Image* img, + const Terrain::LayerInstanceList* layers /*= 0*/) + { + TerrainSlot* slot = getTerrainSlot(x, y, true); + + slot->freeInstance(); + slot->def.useImportData(); + + *slot->def.importData = mDefaultImportData; + + // Copy all settings, but make sure our primary settings are immutable + // copy image - this will get deleted by importData + slot->def.importData->inputImage = OGRE_NEW Image(*img); + if (layers) + { + // copy (held by value) + slot->def.importData->layerList = *layers; + } + slot->def.importData->terrainAlign = mAlignment; + slot->def.importData->terrainSize = mTerrainSize; + slot->def.importData->worldSize = mTerrainWorldSize; + + } + //--------------------------------------------------------------------- + void TerrainGroup::defineTerrain(long x, long y, const float* pFloat /*= 0*/, + const Terrain::LayerInstanceList* layers /*= 0*/) + { + TerrainSlot* slot = getTerrainSlot(x, y, true); + + slot->freeInstance(); + slot->def.useImportData(); + + *slot->def.importData = mDefaultImportData; + + // Copy all settings, but make sure our primary settings are immutable + if(pFloat) + { + // copy data - this will get deleted by importData + slot->def.importData->inputFloat = OGRE_ALLOC_T(float, mTerrainSize*mTerrainSize, MEMCATEGORY_GEOMETRY); + memcpy(slot->def.importData->inputFloat, pFloat, sizeof(float) * mTerrainSize*mTerrainSize); + } + if (layers) + { + // copy (held by value) + slot->def.importData->layerList = *layers; + } + slot->def.importData->terrainAlign = mAlignment; + slot->def.importData->terrainSize = mTerrainSize; + slot->def.importData->worldSize = mTerrainWorldSize; + + } + //--------------------------------------------------------------------- + void TerrainGroup::defineTerrain(long x, long y, const String& filename) + { + TerrainSlot* slot = getTerrainSlot(x, y, true); + + slot->freeInstance(); + + slot->def.useFilename(); + slot->def.filename = filename; + + } + //--------------------------------------------------------------------- + void TerrainGroup::loadAllTerrains(bool synchronous /*= false*/) + { + // Just a straight iteration - for the numbers involved not worth + // keeping a loaded / unloaded list + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + TerrainSlot* slot = i->second; + loadTerrainImpl(slot, synchronous); + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::saveAllTerrains(bool onlyIfModified, bool replaceFilenames) + { + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + TerrainSlot* slot = i->second; + if (slot->instance) + { + Terrain* t = slot->instance; + if (t->isLoaded() && + (!onlyIfModified || t->isModified())) + { + // Overwrite the file names? + if (replaceFilenames) + slot->def.filename = generateFilename(slot->x, slot->y); + + String filename; + if (!slot->def.filename.empty()) + filename = slot->def.filename; + else + filename = generateFilename(slot->x, slot->y); + + t->save(filename); + + } + } + + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::loadTerrain(long x, long y, bool synchronous /*= false*/) + { + TerrainSlot* slot = getTerrainSlot(x, y, false); + if (slot) + { + loadTerrainImpl(slot, synchronous); + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::loadTerrainImpl(TerrainSlot* slot, bool synchronous) + { + if (!slot->instance && + (!slot->def.filename.empty() || slot->def.importData)) + { + // Allocate in main thread so no race conditions + slot->instance = OGRE_NEW Terrain(mSceneManager); + slot->instance->setResourceGroup(mResourceGroup); + // Use shared pool of buffers + slot->instance->setGpuBufferAllocator(&mBufferAllocator); + + LoadRequest req; + req.slot = slot; + req.origin = this; + ++LoadRequest::loadingTaskNum; + Root::getSingleton().getWorkQueue()->addRequest( + mWorkQueueChannel, WORKQUEUE_LOAD_REQUEST, + Any(req), 0, synchronous); + + } + } + //--------------------------------------------------------------------- + void TerrainGroup::increaseLodLevel(long x, long y, bool synchronous /* = false */) + { + TerrainSlot* slot = getTerrainSlot(x, y, false); + if (slot && slot->instance) + { + slot->instance->increaseLodLevel(synchronous); + } + } + void TerrainGroup::decreaseLodLevel(long x, long y) + { + TerrainSlot* slot = getTerrainSlot(x, y, false); + if (slot && slot->instance) + { + slot->instance->decreaseLodLevel(); + } + } + //--------------------------------------------------------------------- + void TerrainGroup::setAutoUpdateLod(TerrainAutoUpdateLod* updater) + { + if(mAutoUpdateLod) + OGRE_DELETE mAutoUpdateLod; + mAutoUpdateLod = updater; + } + //--------------------------------------------------------------------- + void TerrainGroup::autoUpdateLod(long x, long y, bool synchronous, const Any &data) + { + if(mAutoUpdateLod) + { + TerrainSlot* slot = getTerrainSlot(x, y, synchronous); + if (slot) + { + mAutoUpdateLod->autoUpdateLod(slot->instance, synchronous, data); + } + } + } + //--------------------------------------------------------------------- + void TerrainGroup::autoUpdateLodAll(bool synchronous, const Any &data) + { + if(mAutoUpdateLod) + { + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + TerrainSlot* slot = i->second; + mAutoUpdateLod->autoUpdateLod(slot->instance, synchronous, data); + } + } + } + //--------------------------------------------------------------------- + void TerrainGroup::unloadTerrain(long x, long y) + { + TerrainSlot* slot = getTerrainSlot(x, y, false); + if (slot) + { + slot->freeInstance(); + } + + + } + //--------------------------------------------------------------------- + void TerrainGroup::removeTerrain(long x, long y) + { + uint32 key = packIndex(x, y); + TerrainSlotMap::iterator i = mTerrainSlots.find(key); + if (i != mTerrainSlots.end()) + { + OGRE_DELETE i->second; + mTerrainSlots.erase(i); + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::removeAllTerrains() + { + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + OGRE_DELETE i->second; + } + mTerrainSlots.clear(); + // Also clear buffer pools, if we're clearing completely may not be representative + mBufferAllocator.freeAllBuffers(); + } + //--------------------------------------------------------------------- + TerrainGroup::TerrainSlotDefinition* TerrainGroup::getTerrainDefinition(long x, long y) const + { + TerrainSlot* slot = getTerrainSlot(x, y); + if (slot) + return &slot->def; + else + return 0; + + } + //--------------------------------------------------------------------- + Terrain* TerrainGroup::getTerrain(long x, long y) const + { + TerrainSlot* slot = getTerrainSlot(x, y); + if (slot) + return slot->instance; + else + return 0; + } + //--------------------------------------------------------------------- + float TerrainGroup::getHeightAtWorldPosition(Real x, Real y, Real z, Terrain** ppTerrain /* = 0*/) + { + return getHeightAtWorldPosition(Vector3(x, y, z), ppTerrain); + + } + //--------------------------------------------------------------------- + float TerrainGroup::getHeightAtWorldPosition(const Vector3& pos, Terrain** ppTerrain /*= 0*/) + { + long x, y; + convertWorldPositionToTerrainSlot(pos, &x, &y); + TerrainSlot* slot = getTerrainSlot(x, y); + if (slot && slot->instance && slot->instance->isLoaded()) + { + if (ppTerrain) + *ppTerrain = slot->instance; + return slot->instance->getHeightAtWorldPosition(pos); + } + else + { + if (ppTerrain) + *ppTerrain = 0; + return 0; + } + } + //--------------------------------------------------------------------- + TerrainGroup::RayResult TerrainGroup::rayIntersects(const Ray& ray, Real distanceLimit /* = 0*/) const + { + long curr_x, curr_z; + convertWorldPositionToTerrainSlot(ray.getOrigin(), &curr_x, &curr_z); + TerrainSlot* slot = getTerrainSlot(curr_x, curr_z); + RayResult result(false, 0, Vector3::ZERO); + + Vector3 tmp, localRayDir, centreOrigin, offset; + // get the middle of the current tile + convertTerrainSlotToWorldPosition(curr_x, curr_z, ¢reOrigin); + offset = ray.getOrigin() - centreOrigin; + localRayDir = ray.getDirection(); + switch (getAlignment()) + { + case Terrain::ALIGN_X_Y: + std::swap(localRayDir.y, localRayDir.z); + std::swap(offset.y, offset.z); + break; + case Terrain::ALIGN_Y_Z: + // x = z, z = y, y = -x + tmp.x = localRayDir.z; + tmp.z = localRayDir.y; + tmp.y = -localRayDir.x; + localRayDir = tmp; + tmp.x = offset.z; + tmp.z = offset.y; + tmp.y = -offset.x; + offset = tmp; + break; + case Terrain::ALIGN_X_Z: + // already in X/Z but values increase in -Z + localRayDir.z = -localRayDir.z; + offset.z = -offset.z; + break; + } + // Normalise the offset based on the world size of a square, and rebase to the bottom left + offset /= mTerrainWorldSize; + offset += 0.5f; + // this is our counter moving away from the 'current' square + Vector3 inc(Math::Abs(localRayDir.x), Math::Abs(localRayDir.y), Math::Abs(localRayDir.z)); + long xdir = localRayDir.x > 0.0f ? 1 : -1; + long zdir = localRayDir.z > 0.0f ? 1 : -1; + + // We're always counting from 0 to 1 regardless of what direction we're heading + if (xdir < 0) + offset.x = 1.0f - offset.x; + if (zdir < 0) + offset.z = 1.0f - offset.z; + + // find next slot + bool keepSearching = true; + int numGaps = 0; + while(keepSearching) + { + if (Math::RealEqual(inc.x, 0.0f) && Math::RealEqual(inc.z, 0.0f)) + keepSearching = false; while ( (!slot || !slot->instance) && keepSearching) - { - ++numGaps; - /// if we don't find any filled slot in 6 traversals, give up - if (numGaps > 6) - { - keepSearching = false; - break; - } - // find next slot - Vector3 oldoffset = offset; - while (offset.x < 1.0f && offset.z < 1.0f) - offset += inc; - if (offset.x >= 1.0f && offset.z >= 1.0f) - { - // We crossed a corner, need to figure out which we passed first - Real diffz = 1.0f - oldoffset.z; - Real diffx = 1.0f - oldoffset.x; - Real distz = diffz / inc.z; - Real distx = diffx / inc.x; - if (distx < distz) - { - curr_x += xdir; - offset.x -= 1.0f; - } - else - { - curr_z += zdir; - offset.z -= 1.0f; - } - - } - else if (offset.x >= 1.0f) - { - curr_x += xdir; - offset.x -= 1.0f; - } - else if (offset.z >= 1.0f) - { - curr_z += zdir; - offset.z -= 1.0f; - } - if (distanceLimit) - { - Vector3 worldPos; - convertTerrainSlotToWorldPosition(curr_x, curr_z, &worldPos); - if (ray.getOrigin().distance(worldPos) > distanceLimit) - { - keepSearching = false; - break; - } - } - slot = getTerrainSlot(curr_x, curr_z); - } - if (slot && slot->instance) - { - numGaps = 0; - // don't cascade into neighbours - std::pair raypair = slot->instance->rayIntersects(ray, false, distanceLimit); - if (raypair.first) - { - keepSearching = false; - result.hit = true; - result.terrain = slot->instance; - result.position = raypair.second; - } - else - { - // not this one, trigger search for another slot - slot = 0; - } - } - - } - - - return result; - - } - //--------------------------------------------------------------------- - void TerrainGroup::boxIntersects(const AxisAlignedBox& box, TerrainList* resultList) const - { - resultList->clear(); - // Much simpler test - for (TerrainSlotMap::const_iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - if (i->second->instance && box.intersects(i->second->instance->getWorldAABB())) - resultList->push_back(i->second->instance); - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::sphereIntersects(const Sphere& sphere, TerrainList* resultList) const - { - resultList->clear(); - // Much simpler test - for (TerrainSlotMap::const_iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - if (i->second->instance && sphere.intersects(i->second->instance->getWorldAABB())) - resultList->push_back(i->second->instance); - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::convertWorldPositionToTerrainSlot(const Vector3& pos, long *x, long *y) const - { - // 0,0 terrain is centred at the origin - Vector3 terrainPos; - // convert to standard xy base (z up), make relative to origin - Terrain::convertWorldToTerrainAxes(mAlignment, pos - mOrigin, &terrainPos); - - Real offset = mTerrainWorldSize * 0.5f; - terrainPos.x += offset; - terrainPos.y += offset; - - *x = static_cast(floor(terrainPos.x / mTerrainWorldSize)); - *y = static_cast(floor(terrainPos.y / mTerrainWorldSize)); - - - } - //--------------------------------------------------------------------- - void TerrainGroup::convertTerrainSlotToWorldPosition(long x, long y, Vector3* pos) const - { - Vector3 terrainPos(x * mTerrainWorldSize, y * mTerrainWorldSize, 0); - - Terrain::convertTerrainToWorldAxes(mAlignment, terrainPos, pos); - *pos += mOrigin; - - - } - //--------------------------------------------------------------------- - bool TerrainGroup::isDerivedDataUpdateInProgress() const - { - for (TerrainSlotMap::const_iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - if (i->second->instance && i->second->instance->isDerivedDataUpdateInProgress()) - return true; - } - return false; - } - //--------------------------------------------------------------------- - bool TerrainGroup::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - LoadRequest lreq = any_cast(req->getData()); - // only deal with own requests - if (lreq.origin != this) - return false; - else - return RequestHandler::canHandleRequest(req, srcQ); - - } - //--------------------------------------------------------------------- - WorkQueue::Response* TerrainGroup::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - LoadRequest lreq = any_cast(req->getData()); - - TerrainSlotDefinition& def = lreq.slot->def; - Terrain* t = lreq.slot->instance; - assert(t && "Terrain instance should have been constructed in the main thread"); - WorkQueue::Response* response = 0; - try - { - if (!def.filename.empty()) - t->prepare(def.filename); - else - { - assert(def.importData && "No import data or file name"); - t->prepare(*def.importData); - // if this worked, we can destroy the input data to save space - def.freeImportData(); - } - response = OGRE_NEW WorkQueue::Response(req, true, Any()); - } - catch (Exception& e) - { - // oops - response = OGRE_NEW WorkQueue::Response(req, false, Any(), - e.getFullDescription()); - } - - return response; - - - } - //--------------------------------------------------------------------- - bool TerrainGroup::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - LoadRequest lreq = any_cast(res->getRequest()->getData()); - // only deal with own requests - if (lreq.origin != this) - return false; - else - return true; - - } - //--------------------------------------------------------------------- - void TerrainGroup::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - // No response data, just request - LoadRequest lreq = any_cast(res->getRequest()->getData()); - --LoadRequest::loadingTaskNum; - - if (res->succeeded()) - { - TerrainSlot* slot = lreq.slot; - Terrain* terrain = slot->instance; - if (terrain) - { - // do final load now we've prepared in the background - // we must set the position - terrain->setPosition(getTerrainSlotPosition(slot->x, slot->y)); - - // the LOD will be auto-updated, then load lowest LOD - if(mAutoUpdateLod) - terrain->load(-1,false); - else - terrain->load(0,true); - - // hook up with neighbours - for (int i = -1; i <= 1; ++i) - { - for (int j = -1; j <= 1; ++j) - { - if (i != 0 || j != 0) - connectNeighbour(slot, i, j); - } - - } - } - } - else - { - // oh dear - LogManager::getSingleton().stream(LML_CRITICAL) << - "We failed to prepare the terrain at (" << lreq.slot->x << ", " << - lreq.slot->y <<") with the error '" << res->getMessages() << "'"; - lreq.slot->freeInstance(); - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::connectNeighbour(TerrainSlot* slot, long offsetx, long offsety) - { - TerrainSlot* neighbourSlot = getTerrainSlot(slot->x + offsetx, slot->y + offsety); - if (neighbourSlot && neighbourSlot->instance && neighbourSlot->instance->isLoaded()) - { - // reclaculate if imported - slot->instance->setNeighbour(Terrain::getNeighbourIndex(offsetx, offsety), neighbourSlot->instance, - slot->def.importData != 0); - } - } - //--------------------------------------------------------------------- - uint32 TerrainGroup::packIndex(long x, long y) const - { - // Convert to signed 16-bit so sign bit is in bit 15 - int16 xs16 = static_cast(x); - int16 ys16 = static_cast(y); - - // convert to unsigned because we do not want to propagate sign bit to 32-bits - uint16 x16 = static_cast(xs16); - uint16 y16 = static_cast(ys16); - - uint32 key = 0; - key = (x16 << 16) | y16; - - return key; - - - } - //--------------------------------------------------------------------- - void TerrainGroup::unpackIndex(uint32 key, long *x, long *y) - { - // inverse of packIndex - // unsigned versions - uint16 y16 = static_cast(key & 0xFFFF); - uint16 x16 = static_cast((key >> 16) & 0xFFFF); - - *x = static_cast(x16); - *y = static_cast(y16); - - } - - //--------------------------------------------------------------------- - String TerrainGroup::generateFilename(long x, long y) const - { - StringStream str; - str << mFilenamePrefix << "_" << - std::setw(8) << std::setfill('0') << std::hex << packIndex(x, y) << - "." << mFilenameExtension; - return str.str(); - } - //--------------------------------------------------------------------- - Vector3 TerrainGroup::getTerrainSlotPosition(long x, long y) - { - Vector3 pos; - convertTerrainSlotToWorldPosition(x, y, &pos); - return pos; - } - //--------------------------------------------------------------------- - TerrainGroup::TerrainSlot* TerrainGroup::getTerrainSlot(long x, long y, bool createIfMissing) - { - uint32 key = packIndex(x, y); - TerrainSlotMap::iterator i = mTerrainSlots.find(key); - if (i != mTerrainSlots.end()) - return i->second; - else if (createIfMissing) - { - TerrainSlot* slot = OGRE_NEW TerrainSlot(x, y); - mTerrainSlots[key] = slot; - return slot; - } - return 0; - } - //--------------------------------------------------------------------- - TerrainGroup::TerrainSlot* TerrainGroup::getTerrainSlot(long x, long y) const - { - uint32 key = packIndex(x, y); - TerrainSlotMap::const_iterator i = mTerrainSlots.find(key); - if (i != mTerrainSlots.end()) - return i->second; - else - return 0; - - } - //--------------------------------------------------------------------- - void TerrainGroup::freeTemporaryResources() - { - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - if (i->second->instance) - i->second->instance->freeTemporaryResources(); - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::update(bool synchronous) - { - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - if (i->second->instance) - i->second->instance->update(); - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::updateGeometry() - { - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - if (i->second->instance) - i->second->instance->updateGeometry(); - } - - } - //--------------------------------------------------------------------- - void TerrainGroup::updateDerivedData(bool synchronous, uint8 typeMask) - { - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - if (i->second->instance) - i->second->instance->updateDerivedData(); - } - - } - //--------------------------------------------------------------------- - TerrainGroup::TerrainIterator TerrainGroup::getTerrainIterator() - { - return TerrainIterator(mTerrainSlots.begin(), mTerrainSlots.end()); - } - //--------------------------------------------------------------------- - TerrainGroup::ConstTerrainIterator TerrainGroup::getTerrainIterator() const - { - return ConstTerrainIterator(mTerrainSlots.begin(), mTerrainSlots.end()); - } - //--------------------------------------------------------------------- - void TerrainGroup::saveGroupDefinition(const String& filename) - { - DataStreamPtr stream = Root::getSingleton().createFileStream(filename, - getResourceGroup(), true); - StreamSerialiser ser(stream); - saveGroupDefinition(ser); - } - //--------------------------------------------------------------------- - void TerrainGroup::saveGroupDefinition(StreamSerialiser& ser) - { - ser.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); - // Base details - ser.write(&mAlignment); - ser.write(&mTerrainSize); - ser.write(&mTerrainWorldSize); - ser.write(&mFilenamePrefix); - ser.write(&mFilenameExtension); - ser.write(&mResourceGroup); - ser.write(&mOrigin); - - uint32 autoUpdateLodStrategyId = (mAutoUpdateLod) ? mAutoUpdateLod->getStrategyId() : 0; - ser.write(&autoUpdateLodStrategyId); - - // Default import settings (those not duplicated by the above) - ser.write(&mDefaultImportData.constantHeight); - ser.write(&mDefaultImportData.inputBias); - ser.write(&mDefaultImportData.inputScale); - ser.write(&mDefaultImportData.maxBatchSize); - ser.write(&mDefaultImportData.minBatchSize); - Terrain::writeLayerDeclaration(mDefaultImportData.layerDeclaration, ser); - Terrain::writeLayerInstanceList(mDefaultImportData.layerList, ser); - - - ser.writeChunkEnd(CHUNK_ID); - } - //--------------------------------------------------------------------- - void TerrainGroup::loadGroupDefinition(const String& filename) - { - DataStreamPtr stream = Root::getSingleton().openFileStream(filename, - getResourceGroup()); - StreamSerialiser ser(stream); - loadGroupDefinition(ser); - } - //--------------------------------------------------------------------- - void TerrainGroup::loadGroupDefinition(StreamSerialiser& ser) - { - if (!ser.readChunkBegin(CHUNK_ID, CHUNK_VERSION)) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Stream does not contain TerrainGroup data", __FUNCTION__); - - // Base details - ser.read(&mAlignment); - ser.read(&mTerrainSize); - ser.read(&mTerrainWorldSize); - ser.read(&mFilenamePrefix); - ser.read(&mFilenameExtension); - ser.read(&mResourceGroup); - ser.read(&mOrigin); - uint32 autoUpdateLodStrategyId; - ser.read(&autoUpdateLodStrategyId); - mAutoUpdateLod = TerrainAutoUpdateLodFactory::getAutoUpdateLod( autoUpdateLodStrategyId ); - - // Default import settings (those not duplicated by the above) - ser.read(&mDefaultImportData.constantHeight); - ser.read(&mDefaultImportData.inputBias); - ser.read(&mDefaultImportData.inputScale); - ser.read(&mDefaultImportData.maxBatchSize); - ser.read(&mDefaultImportData.minBatchSize); - Terrain::readLayerDeclaration(ser, mDefaultImportData.layerDeclaration); - Terrain::readLayerInstanceList(ser, mDefaultImportData.layerDeclaration.samplers.size(), - mDefaultImportData.layerList); - - // copy data that would have normally happened on construction - mDefaultImportData.terrainAlign = mAlignment; - mDefaultImportData.terrainSize = mTerrainSize; - mDefaultImportData.worldSize = mTerrainWorldSize; - mDefaultImportData.deleteInputData = true; - - ser.readChunkEnd(CHUNK_ID); - - - } - //--------------------------------------------------------------------- + { + ++numGaps; + /// if we don't find any filled slot in 6 traversals, give up + if (numGaps > 6) + { + keepSearching = false; + break; + } + // find next slot + Vector3 oldoffset = offset; + while (offset.x < 1.0f && offset.z < 1.0f) + offset += inc; + if (offset.x >= 1.0f && offset.z >= 1.0f) + { + // We crossed a corner, need to figure out which we passed first + Real diffz = 1.0f - oldoffset.z; + Real diffx = 1.0f - oldoffset.x; + Real distz = diffz / inc.z; + Real distx = diffx / inc.x; + if (distx < distz) + { + curr_x += xdir; + offset.x -= 1.0f; + } + else + { + curr_z += zdir; + offset.z -= 1.0f; + } + + } + else if (offset.x >= 1.0f) + { + curr_x += xdir; + offset.x -= 1.0f; + } + else if (offset.z >= 1.0f) + { + curr_z += zdir; + offset.z -= 1.0f; + } + if (distanceLimit) + { + Vector3 worldPos; + convertTerrainSlotToWorldPosition(curr_x, curr_z, &worldPos); + if (ray.getOrigin().distance(worldPos) > distanceLimit) + { + keepSearching = false; + break; + } + } + slot = getTerrainSlot(curr_x, curr_z); + } + if (slot && slot->instance) + { + numGaps = 0; + // don't cascade into neighbours + std::pair raypair = slot->instance->rayIntersects(ray, false, distanceLimit); + if (raypair.first) + { + keepSearching = false; + result.hit = true; + result.terrain = slot->instance; + result.position = raypair.second; + } + else + { + // not this one, trigger search for another slot + slot = 0; + } + } + + } + + + return result; + + } + //--------------------------------------------------------------------- + void TerrainGroup::boxIntersects(const AxisAlignedBox& box, TerrainList* resultList) const + { + resultList->clear(); + // Much simpler test + for (TerrainSlotMap::const_iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + if (i->second->instance && box.intersects(i->second->instance->getWorldAABB())) + resultList->push_back(i->second->instance); + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::sphereIntersects(const Sphere& sphere, TerrainList* resultList) const + { + resultList->clear(); + // Much simpler test + for (TerrainSlotMap::const_iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + if (i->second->instance && sphere.intersects(i->second->instance->getWorldAABB())) + resultList->push_back(i->second->instance); + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::convertWorldPositionToTerrainSlot(const Vector3& pos, long *x, long *y) const + { + // 0,0 terrain is centred at the origin + Vector3 terrainPos; + // convert to standard xy base (z up), make relative to origin + Terrain::convertWorldToTerrainAxes(mAlignment, pos - mOrigin, &terrainPos); + + Real offset = mTerrainWorldSize * 0.5f; + terrainPos.x += offset; + terrainPos.y += offset; + + *x = static_cast(floor(terrainPos.x / mTerrainWorldSize)); + *y = static_cast(floor(terrainPos.y / mTerrainWorldSize)); + + + } + //--------------------------------------------------------------------- + void TerrainGroup::convertTerrainSlotToWorldPosition(long x, long y, Vector3* pos) const + { + Vector3 terrainPos(x * mTerrainWorldSize, y * mTerrainWorldSize, 0); + + Terrain::convertTerrainToWorldAxes(mAlignment, terrainPos, pos); + *pos += mOrigin; + + + } + //--------------------------------------------------------------------- + bool TerrainGroup::isDerivedDataUpdateInProgress() const + { + for (TerrainSlotMap::const_iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + if (i->second->instance && i->second->instance->isDerivedDataUpdateInProgress()) + return true; + } + return false; + } + //--------------------------------------------------------------------- + bool TerrainGroup::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + LoadRequest lreq = any_cast(req->getData()); + // only deal with own requests + if (lreq.origin != this) + return false; + else + return RequestHandler::canHandleRequest(req, srcQ); + + } + //--------------------------------------------------------------------- + WorkQueue::Response* TerrainGroup::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + LoadRequest lreq = any_cast(req->getData()); + + TerrainSlotDefinition& def = lreq.slot->def; + Terrain* t = lreq.slot->instance; + assert(t && "Terrain instance should have been constructed in the main thread"); + WorkQueue::Response* response = 0; + try + { + if (!def.filename.empty()) + t->prepare(def.filename); + else + { + assert(def.importData && "No import data or file name"); + t->prepare(*def.importData); + // if this worked, we can destroy the input data to save space + def.freeImportData(); + } + response = OGRE_NEW WorkQueue::Response(req, true, Any()); + } + catch (Exception& e) + { + // oops + response = OGRE_NEW WorkQueue::Response(req, false, Any(), + e.getFullDescription()); + } + + return response; + + + } + //--------------------------------------------------------------------- + bool TerrainGroup::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + LoadRequest lreq = any_cast(res->getRequest()->getData()); + // only deal with own requests + if (lreq.origin != this) + return false; + else + return true; + + } + //--------------------------------------------------------------------- + void TerrainGroup::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + // No response data, just request + LoadRequest lreq = any_cast(res->getRequest()->getData()); + --LoadRequest::loadingTaskNum; + + if (res->succeeded()) + { + TerrainSlot* slot = lreq.slot; + Terrain* terrain = slot->instance; + if (terrain) + { + // do final load now we've prepared in the background + // we must set the position + terrain->setPosition(getTerrainSlotPosition(slot->x, slot->y)); + + // the LOD will be auto-updated, then load lowest LOD + if(mAutoUpdateLod) + terrain->load(-1,false); + else + terrain->load(0,true); + + // hook up with neighbours + for (int i = -1; i <= 1; ++i) + { + for (int j = -1; j <= 1; ++j) + { + if (i != 0 || j != 0) + connectNeighbour(slot, i, j); + } + + } + } + } + else + { + // oh dear + LogManager::getSingleton().stream(LML_CRITICAL) << + "We failed to prepare the terrain at (" << lreq.slot->x << ", " << + lreq.slot->y <<") with the error '" << res->getMessages() << "'"; + lreq.slot->freeInstance(); + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::connectNeighbour(TerrainSlot* slot, long offsetx, long offsety) + { + TerrainSlot* neighbourSlot = getTerrainSlot(slot->x + offsetx, slot->y + offsety); + if (neighbourSlot && neighbourSlot->instance && neighbourSlot->instance->isLoaded()) + { + // reclaculate if imported + slot->instance->setNeighbour(Terrain::getNeighbourIndex(offsetx, offsety), neighbourSlot->instance, + slot->def.importData != 0); + } + } + //--------------------------------------------------------------------- + uint32 TerrainGroup::packIndex(long x, long y) const + { + // Convert to signed 16-bit so sign bit is in bit 15 + int16 xs16 = static_cast(x); + int16 ys16 = static_cast(y); + + // convert to unsigned because we do not want to propagate sign bit to 32-bits + uint16 x16 = static_cast(xs16); + uint16 y16 = static_cast(ys16); + + uint32 key = 0; + key = (x16 << 16) | y16; + + return key; + + + } + //--------------------------------------------------------------------- + void TerrainGroup::unpackIndex(uint32 key, long *x, long *y) + { + // inverse of packIndex + // unsigned versions + uint16 y16 = static_cast(key & 0xFFFF); + uint16 x16 = static_cast((key >> 16) & 0xFFFF); + + *x = static_cast(x16); + *y = static_cast(y16); + + } + + //--------------------------------------------------------------------- + String TerrainGroup::generateFilename(long x, long y) const + { + StringStream str; + str << mFilenamePrefix << "_" << + std::setw(8) << std::setfill('0') << std::hex << packIndex(x, y) << + "." << mFilenameExtension; + return str.str(); + } + //--------------------------------------------------------------------- + Vector3 TerrainGroup::getTerrainSlotPosition(long x, long y) + { + Vector3 pos; + convertTerrainSlotToWorldPosition(x, y, &pos); + return pos; + } + //--------------------------------------------------------------------- + TerrainGroup::TerrainSlot* TerrainGroup::getTerrainSlot(long x, long y, bool createIfMissing) + { + uint32 key = packIndex(x, y); + TerrainSlotMap::iterator i = mTerrainSlots.find(key); + if (i != mTerrainSlots.end()) + return i->second; + else if (createIfMissing) + { + TerrainSlot* slot = OGRE_NEW TerrainSlot(x, y); + mTerrainSlots[key] = slot; + return slot; + } + return 0; + } + //--------------------------------------------------------------------- + TerrainGroup::TerrainSlot* TerrainGroup::getTerrainSlot(long x, long y) const + { + uint32 key = packIndex(x, y); + TerrainSlotMap::const_iterator i = mTerrainSlots.find(key); + if (i != mTerrainSlots.end()) + return i->second; + else + return 0; + + } + //--------------------------------------------------------------------- + void TerrainGroup::freeTemporaryResources() + { + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + if (i->second->instance) + i->second->instance->freeTemporaryResources(); + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::update(bool synchronous) + { + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + if (i->second->instance) + i->second->instance->update(); + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::updateGeometry() + { + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + if (i->second->instance) + i->second->instance->updateGeometry(); + } + + } + //--------------------------------------------------------------------- + void TerrainGroup::updateDerivedData(bool synchronous, uint8 typeMask) + { + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + if (i->second->instance) + i->second->instance->updateDerivedData(); + } + + } + //--------------------------------------------------------------------- + TerrainGroup::TerrainIterator TerrainGroup::getTerrainIterator() + { + return TerrainIterator(mTerrainSlots.begin(), mTerrainSlots.end()); + } + //--------------------------------------------------------------------- + TerrainGroup::ConstTerrainIterator TerrainGroup::getTerrainIterator() const + { + return ConstTerrainIterator(mTerrainSlots.begin(), mTerrainSlots.end()); + } + //--------------------------------------------------------------------- + void TerrainGroup::saveGroupDefinition(const String& filename) + { + DataStreamPtr stream = Root::getSingleton().createFileStream(filename, + getResourceGroup(), true); + StreamSerialiser ser(stream); + saveGroupDefinition(ser); + } + //--------------------------------------------------------------------- + void TerrainGroup::saveGroupDefinition(StreamSerialiser& ser) + { + ser.writeChunkBegin(CHUNK_ID, CHUNK_VERSION); + // Base details + ser.write(&mAlignment); + ser.write(&mTerrainSize); + ser.write(&mTerrainWorldSize); + ser.write(&mFilenamePrefix); + ser.write(&mFilenameExtension); + ser.write(&mResourceGroup); + ser.write(&mOrigin); + + uint32 autoUpdateLodStrategyId = (mAutoUpdateLod) ? mAutoUpdateLod->getStrategyId() : 0; + ser.write(&autoUpdateLodStrategyId); + + // Default import settings (those not duplicated by the above) + ser.write(&mDefaultImportData.constantHeight); + ser.write(&mDefaultImportData.inputBias); + ser.write(&mDefaultImportData.inputScale); + ser.write(&mDefaultImportData.maxBatchSize); + ser.write(&mDefaultImportData.minBatchSize); + Terrain::writeLayerDeclaration(mDefaultImportData.layerDeclaration, ser); + Terrain::writeLayerInstanceList(mDefaultImportData.layerList, ser); + + + ser.writeChunkEnd(CHUNK_ID); + } + //--------------------------------------------------------------------- + void TerrainGroup::loadGroupDefinition(const String& filename) + { + DataStreamPtr stream = Root::getSingleton().openFileStream(filename, + getResourceGroup()); + StreamSerialiser ser(stream); + loadGroupDefinition(ser); + } + //--------------------------------------------------------------------- + void TerrainGroup::loadGroupDefinition(StreamSerialiser& ser) + { + if (!ser.readChunkBegin(CHUNK_ID, CHUNK_VERSION)) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Stream does not contain TerrainGroup data", __FUNCTION__); + + // Base details + ser.read(&mAlignment); + ser.read(&mTerrainSize); + ser.read(&mTerrainWorldSize); + ser.read(&mFilenamePrefix); + ser.read(&mFilenameExtension); + ser.read(&mResourceGroup); + ser.read(&mOrigin); + uint32 autoUpdateLodStrategyId; + ser.read(&autoUpdateLodStrategyId); + mAutoUpdateLod = TerrainAutoUpdateLodFactory::getAutoUpdateLod( autoUpdateLodStrategyId ); + + // Default import settings (those not duplicated by the above) + ser.read(&mDefaultImportData.constantHeight); + ser.read(&mDefaultImportData.inputBias); + ser.read(&mDefaultImportData.inputScale); + ser.read(&mDefaultImportData.maxBatchSize); + ser.read(&mDefaultImportData.minBatchSize); + Terrain::readLayerDeclaration(ser, mDefaultImportData.layerDeclaration); + Terrain::readLayerInstanceList(ser, mDefaultImportData.layerDeclaration.samplers.size(), + mDefaultImportData.layerList); + + // copy data that would have normally happened on construction + mDefaultImportData.terrainAlign = mAlignment; + mDefaultImportData.terrainSize = mTerrainSize; + mDefaultImportData.worldSize = mTerrainWorldSize; + mDefaultImportData.deleteInputData = true; + + ser.readChunkEnd(CHUNK_ID); + + + } + //--------------------------------------------------------------------- void TerrainGroup::setTerrainWorldSize(Real newWorldSize) { - if (newWorldSize != mTerrainWorldSize) - { - mTerrainWorldSize = newWorldSize; - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - if (i->second->instance) - { - i->second->instance->setWorldSize(newWorldSize); - i->second->instance->setPosition(getTerrainSlotPosition(i->second->x, i->second->y)); - } - } - } - } - //--------------------------------------------------------------------- + if (newWorldSize != mTerrainWorldSize) + { + mTerrainWorldSize = newWorldSize; + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + if (i->second->instance) + { + i->second->instance->setWorldSize(newWorldSize); + i->second->instance->setPosition(getTerrainSlotPosition(i->second->x, i->second->y)); + } + } + } + } + //--------------------------------------------------------------------- void TerrainGroup::setTerrainSize(uint16 newTerrainSize) { - if (newTerrainSize != mTerrainSize) - { - mTerrainSize = newTerrainSize; - for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) - { - if (i->second->instance) - { - i->second->instance->setSize(newTerrainSize); - } - } - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - TerrainGroup::TerrainSlotDefinition::~TerrainSlotDefinition() - { - freeImportData(); - } - //--------------------------------------------------------------------- - void TerrainGroup::TerrainSlotDefinition::freeImportData() - { - OGRE_DELETE_T(importData, ImportData, MEMCATEGORY_GEOMETRY); - importData = 0; - } - //--------------------------------------------------------------------- - void TerrainGroup::TerrainSlotDefinition::useImportData() - { - filename.clear(); - freeImportData(); - importData = OGRE_NEW_T(Terrain::ImportData, MEMCATEGORY_GEOMETRY); - // we're going to own all the data in the def - importData->deleteInputData = true; - - } - //--------------------------------------------------------------------- - void TerrainGroup::TerrainSlotDefinition::useFilename() - { - freeImportData(); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - TerrainGroup::TerrainSlot::~TerrainSlot() - { - freeInstance(); - } - //--------------------------------------------------------------------- - void TerrainGroup::TerrainSlot::freeInstance() - { - OGRE_DELETE instance; - instance = 0; - } + if (newTerrainSize != mTerrainSize) + { + mTerrainSize = newTerrainSize; + for (TerrainSlotMap::iterator i = mTerrainSlots.begin(); i != mTerrainSlots.end(); ++i) + { + if (i->second->instance) + { + i->second->instance->setSize(newTerrainSize); + } + } + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + TerrainGroup::TerrainSlotDefinition::~TerrainSlotDefinition() + { + freeImportData(); + } + //--------------------------------------------------------------------- + void TerrainGroup::TerrainSlotDefinition::freeImportData() + { + OGRE_DELETE_T(importData, ImportData, MEMCATEGORY_GEOMETRY); + importData = 0; + } + //--------------------------------------------------------------------- + void TerrainGroup::TerrainSlotDefinition::useImportData() + { + filename.clear(); + freeImportData(); + importData = OGRE_NEW_T(Terrain::ImportData, MEMCATEGORY_GEOMETRY); + // we're going to own all the data in the def + importData->deleteInputData = true; + + } + //--------------------------------------------------------------------- + void TerrainGroup::TerrainSlotDefinition::useFilename() + { + freeImportData(); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + TerrainGroup::TerrainSlot::~TerrainSlot() + { + freeInstance(); + } + //--------------------------------------------------------------------- + void TerrainGroup::TerrainSlot::freeInstance() + { + OGRE_DELETE instance; + instance = 0; + } } diff --git a/Components/Terrain/src/OgreTerrainLayerBlendMap.cpp b/Components/Terrain/src/OgreTerrainLayerBlendMap.cpp index a2a08ec3718..4f30ce0c453 100644 --- a/Components/Terrain/src/OgreTerrainLayerBlendMap.cpp +++ b/Components/Terrain/src/OgreTerrainLayerBlendMap.cpp @@ -37,229 +37,229 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - TerrainLayerBlendMap::TerrainLayerBlendMap(Terrain* parent, uint8 layerIndex, - HardwarePixelBuffer* buf) - : mParent(parent) - , mLayerIdx(layerIndex) - , mChannel((layerIndex-1) % 4) - , mDirty(false) - , mBuffer(buf) - , mData(0) - { - mData = static_cast(OGRE_MALLOC(mBuffer->getWidth() * mBuffer->getHeight() * sizeof(float), MEMCATEGORY_RESOURCE)); + //--------------------------------------------------------------------- + TerrainLayerBlendMap::TerrainLayerBlendMap(Terrain* parent, uint8 layerIndex, + HardwarePixelBuffer* buf) + : mParent(parent) + , mLayerIdx(layerIndex) + , mChannel((layerIndex-1) % 4) + , mDirty(false) + , mBuffer(buf) + , mData(0) + { + mData = static_cast(OGRE_MALLOC(mBuffer->getWidth() * mBuffer->getHeight() * sizeof(float), MEMCATEGORY_RESOURCE)); - // we know which of RGBA we need to look at, now find it in the format - // because we can't guarantee what precise format the RS gives us - unsigned char rgbaShift[4]; - PixelFormat fmt = mBuffer->getFormat(); - PixelUtil::getBitShifts(fmt, rgbaShift); - mChannelOffset = rgbaShift[mChannel] / 8; // /8 to convert to bytes + // we know which of RGBA we need to look at, now find it in the format + // because we can't guarantee what precise format the RS gives us + unsigned char rgbaShift[4]; + PixelFormat fmt = mBuffer->getFormat(); + PixelUtil::getBitShifts(fmt, rgbaShift); + mChannelOffset = rgbaShift[mChannel] / 8; // /8 to convert to bytes #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - // invert (dealing bytewise) - mChannelOffset = PixelUtil::getNumElemBytes(fmt) - mChannelOffset - 1; + // invert (dealing bytewise) + mChannelOffset = PixelUtil::getNumElemBytes(fmt) - mChannelOffset - 1; #endif - download(); + download(); - } - //--------------------------------------------------------------------- - TerrainLayerBlendMap::~TerrainLayerBlendMap() - { - OGRE_FREE(mData, MEMCATEGORY_RESOURCE); - mData = 0; - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::download() - { - float* pDst = mData; - // Download data - Image::Box box(0, 0, mBuffer->getWidth(), mBuffer->getHeight()); - uint8* pSrc = static_cast(mBuffer->lock(box, HardwareBuffer::HBL_READ_ONLY).data); - pSrc += mChannelOffset; - size_t srcInc = PixelUtil::getNumElemBytes(mBuffer->getFormat()); - for (size_t y = box.top; y < box.bottom; ++y) - { - for (size_t x = box.left; x < box.right; ++x) - { - *pDst++ = static_cast(*pSrc) / 255.0f; - pSrc += srcInc; - } - } - mBuffer->unlock(); + } + //--------------------------------------------------------------------- + TerrainLayerBlendMap::~TerrainLayerBlendMap() + { + OGRE_FREE(mData, MEMCATEGORY_RESOURCE); + mData = 0; + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::download() + { + float* pDst = mData; + // Download data + Image::Box box(0, 0, mBuffer->getWidth(), mBuffer->getHeight()); + uint8* pSrc = static_cast(mBuffer->lock(box, HardwareBuffer::HBL_READ_ONLY).data); + pSrc += mChannelOffset; + size_t srcInc = PixelUtil::getNumElemBytes(mBuffer->getFormat()); + for (size_t y = box.top; y < box.bottom; ++y) + { + for (size_t x = box.left; x < box.right; ++x) + { + *pDst++ = static_cast(*pSrc) / 255.0f; + pSrc += srcInc; + } + } + mBuffer->unlock(); - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::convertWorldToUVSpace(const Vector3& worldPos, Real *outX, Real* outY) - { - Vector3 terrainSpace; - mParent->getTerrainPosition(worldPos, &terrainSpace); - *outX = terrainSpace.x; - *outY = 1.0f - terrainSpace.y; - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::convertUVToWorldSpace(Real x, Real y, Vector3* outWorldPos) - { - mParent->getPosition(x, 1.0f - y, 0, outWorldPos); - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::convertUVToImageSpace(Real x, Real y, size_t* outX, size_t* outY) - { - *outX = (unsigned long)(x * (mBuffer->getWidth() - 1)); - *outY = (unsigned long)(y * (mBuffer->getHeight() - 1)); - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::convertImageToUVSpace(size_t x, size_t y, Real* outX, Real* outY) - { - *outX = x / (Real)(mBuffer->getWidth() - 1); - *outY = y / (Real)(mBuffer->getHeight() - 1); - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::convertImageToTerrainSpace(size_t x, size_t y, Real* outX, Real* outY) - { - convertImageToUVSpace(x, y, outX, outY); - *outY = 1.0f - *outY; - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::convertTerrainToImageSpace(Real x, Real y, size_t* outX, size_t* outY) - { - convertUVToImageSpace(x, 1.0f - y, outX, outY); - } - //--------------------------------------------------------------------- - float TerrainLayerBlendMap::getBlendValue(size_t x, size_t y) - { - return *(mData + y * mBuffer->getWidth() + x); - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::setBlendValue(size_t x, size_t y, float val) - { - *(mData + y * mBuffer->getWidth() + x) = val; - dirtyRect(Rect(x, y, x+1, y+1)); + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::convertWorldToUVSpace(const Vector3& worldPos, Real *outX, Real* outY) + { + Vector3 terrainSpace; + mParent->getTerrainPosition(worldPos, &terrainSpace); + *outX = terrainSpace.x; + *outY = 1.0f - terrainSpace.y; + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::convertUVToWorldSpace(Real x, Real y, Vector3* outWorldPos) + { + mParent->getPosition(x, 1.0f - y, 0, outWorldPos); + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::convertUVToImageSpace(Real x, Real y, size_t* outX, size_t* outY) + { + *outX = (unsigned long)(x * (mBuffer->getWidth() - 1)); + *outY = (unsigned long)(y * (mBuffer->getHeight() - 1)); + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::convertImageToUVSpace(size_t x, size_t y, Real* outX, Real* outY) + { + *outX = x / (Real)(mBuffer->getWidth() - 1); + *outY = y / (Real)(mBuffer->getHeight() - 1); + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::convertImageToTerrainSpace(size_t x, size_t y, Real* outX, Real* outY) + { + convertImageToUVSpace(x, y, outX, outY); + *outY = 1.0f - *outY; + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::convertTerrainToImageSpace(Real x, Real y, size_t* outX, size_t* outY) + { + convertUVToImageSpace(x, 1.0f - y, outX, outY); + } + //--------------------------------------------------------------------- + float TerrainLayerBlendMap::getBlendValue(size_t x, size_t y) + { + return *(mData + y * mBuffer->getWidth() + x); + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::setBlendValue(size_t x, size_t y, float val) + { + *(mData + y * mBuffer->getWidth() + x) = val; + dirtyRect(Rect(x, y, x+1, y+1)); - } - //--------------------------------------------------------------------- - float* TerrainLayerBlendMap::getBlendPointer() - { - return mData; - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::dirty() - { - Rect rect; - rect.top = 0; rect.bottom = mBuffer->getHeight(); - rect.left = 0; rect.right = mBuffer->getWidth(); - dirtyRect(rect); + } + //--------------------------------------------------------------------- + float* TerrainLayerBlendMap::getBlendPointer() + { + return mData; + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::dirty() + { + Rect rect; + rect.top = 0; rect.bottom = mBuffer->getHeight(); + rect.left = 0; rect.right = mBuffer->getWidth(); + dirtyRect(rect); - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::dirtyRect(const Rect& rect) - { - if (mDirty) - { - mDirtyBox.left = std::min(mDirtyBox.left, static_cast(rect.left)); - mDirtyBox.top = std::min(mDirtyBox.top, static_cast(rect.top)); - mDirtyBox.right = std::max(mDirtyBox.right, static_cast(rect.right)); - mDirtyBox.bottom = std::max(mDirtyBox.bottom, static_cast(rect.bottom)); - } - else - { - mDirtyBox.left = static_cast(rect.left); - mDirtyBox.right = static_cast(rect.right); - mDirtyBox.top = static_cast(rect.top); - mDirtyBox.bottom = static_cast(rect.bottom); - mDirty = true; - } - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::update() - { - if (mData && mDirty) - { - // Upload data - float* pSrcBase = mData + mDirtyBox.top * mBuffer->getWidth() + mDirtyBox.left; - uint8* pDstBase = static_cast(mBuffer->lock(mDirtyBox, HardwarePixelBuffer::HBL_NORMAL).data); - pDstBase += mChannelOffset; - size_t dstInc = PixelUtil::getNumElemBytes(mBuffer->getFormat()); - for (size_t y = 0; y < mDirtyBox.getHeight(); ++y) - { - float* pSrc = pSrcBase + y * mBuffer->getWidth(); - uint8* pDst = pDstBase + y * mBuffer->getWidth() * dstInc; - for (size_t x = 0; x < mDirtyBox.getWidth(); ++x) - { - *pDst = static_cast(*pSrc++ * 255); - pDst += dstInc; - } - } - mBuffer->unlock(); + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::dirtyRect(const Rect& rect) + { + if (mDirty) + { + mDirtyBox.left = std::min(mDirtyBox.left, static_cast(rect.left)); + mDirtyBox.top = std::min(mDirtyBox.top, static_cast(rect.top)); + mDirtyBox.right = std::max(mDirtyBox.right, static_cast(rect.right)); + mDirtyBox.bottom = std::max(mDirtyBox.bottom, static_cast(rect.bottom)); + } + else + { + mDirtyBox.left = static_cast(rect.left); + mDirtyBox.right = static_cast(rect.right); + mDirtyBox.top = static_cast(rect.top); + mDirtyBox.bottom = static_cast(rect.bottom); + mDirty = true; + } + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::update() + { + if (mData && mDirty) + { + // Upload data + float* pSrcBase = mData + mDirtyBox.top * mBuffer->getWidth() + mDirtyBox.left; + uint8* pDstBase = static_cast(mBuffer->lock(mDirtyBox, HardwarePixelBuffer::HBL_NORMAL).data); + pDstBase += mChannelOffset; + size_t dstInc = PixelUtil::getNumElemBytes(mBuffer->getFormat()); + for (size_t y = 0; y < mDirtyBox.getHeight(); ++y) + { + float* pSrc = pSrcBase + y * mBuffer->getWidth(); + uint8* pDst = pDstBase + y * mBuffer->getWidth() * dstInc; + for (size_t x = 0; x < mDirtyBox.getWidth(); ++x) + { + *pDst = static_cast(*pSrc++ * 255); + pDst += dstInc; + } + } + mBuffer->unlock(); - mDirty = false; + mDirty = false; - // make sure composite map is updated - // mDirtyBox is in image space, convert to terrain units - Rect compositeMapRect; - float blendToTerrain = (float)mParent->getSize() / (float)mBuffer->getWidth(); - compositeMapRect.left = (long)(mDirtyBox.left * blendToTerrain); - compositeMapRect.right = (long)(mDirtyBox.right * blendToTerrain + 1); - compositeMapRect.top = (long)((mBuffer->getHeight() - mDirtyBox.bottom) * blendToTerrain); - compositeMapRect.bottom = (long)((mBuffer->getHeight() - mDirtyBox.top) * blendToTerrain + 1); - mParent->_dirtyCompositeMapRect(compositeMapRect); - mParent->updateCompositeMapWithDelay(); + // make sure composite map is updated + // mDirtyBox is in image space, convert to terrain units + Rect compositeMapRect; + float blendToTerrain = (float)mParent->getSize() / (float)mBuffer->getWidth(); + compositeMapRect.left = (long)(mDirtyBox.left * blendToTerrain); + compositeMapRect.right = (long)(mDirtyBox.right * blendToTerrain + 1); + compositeMapRect.top = (long)((mBuffer->getHeight() - mDirtyBox.bottom) * blendToTerrain); + compositeMapRect.bottom = (long)((mBuffer->getHeight() - mDirtyBox.top) * blendToTerrain + 1); + mParent->_dirtyCompositeMapRect(compositeMapRect); + mParent->updateCompositeMapWithDelay(); - } - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::blit(const PixelBox &src, const Box &dstBox) - { - const PixelBox* srcBox = &src; + } + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::blit(const PixelBox &src, const Box &dstBox) + { + const PixelBox* srcBox = &src; - if (srcBox->getWidth() != dstBox.getWidth() || srcBox->getHeight() != dstBox.getHeight()) - { - // we need to rescale src to dst size first (also confvert format) - void* tmpData = OGRE_MALLOC(dstBox.getWidth() * dstBox.getHeight(), MEMCATEGORY_GENERAL); - srcBox = OGRE_NEW PixelBox(dstBox.getWidth(), dstBox.getHeight(), 1, PF_L8, tmpData); + if (srcBox->getWidth() != dstBox.getWidth() || srcBox->getHeight() != dstBox.getHeight()) + { + // we need to rescale src to dst size first (also confvert format) + void* tmpData = OGRE_MALLOC(dstBox.getWidth() * dstBox.getHeight(), MEMCATEGORY_GENERAL); + srcBox = OGRE_NEW PixelBox(dstBox.getWidth(), dstBox.getHeight(), 1, PF_L8, tmpData); - Image::scale(src, *srcBox); - } + Image::scale(src, *srcBox); + } - // pixel conversion - PixelBox dstMemBox(dstBox, PF_L8, mData); - PixelUtil::bulkPixelConversion(*srcBox, dstMemBox); + // pixel conversion + PixelBox dstMemBox(dstBox, PF_L8, mData); + PixelUtil::bulkPixelConversion(*srcBox, dstMemBox); - if (srcBox != &src) - { - // free temp - OGRE_FREE(srcBox->data, MEMCATEGORY_GENERAL); - OGRE_DELETE srcBox; - srcBox = 0; - } + if (srcBox != &src) + { + // free temp + OGRE_FREE(srcBox->data, MEMCATEGORY_GENERAL); + OGRE_DELETE srcBox; + srcBox = 0; + } - Rect dRect(dstBox.left, dstBox.top, dstBox.right, dstBox.bottom); - dirtyRect(dRect); + Rect dRect(dstBox.left, dstBox.top, dstBox.right, dstBox.bottom); + dirtyRect(dRect); - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::blit(const PixelBox &src) - { - blit(src, Box(0,0,0,mBuffer->getWidth(),mBuffer->getHeight(),1)); - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::loadImage(const Image& img) - { - blit(img.getPixelBox()); - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::loadImage(DataStreamPtr& stream, const String& ext) - { - Image img; - img.load(stream, ext); - loadImage(img); - } - //--------------------------------------------------------------------- - void TerrainLayerBlendMap::loadImage(const String& filename, const String& groupName) - { - Image img; - img.load(filename, groupName); - loadImage(img); - } + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::blit(const PixelBox &src) + { + blit(src, Box(0,0,0,mBuffer->getWidth(),mBuffer->getHeight(),1)); + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::loadImage(const Image& img) + { + blit(img.getPixelBox()); + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::loadImage(DataStreamPtr& stream, const String& ext) + { + Image img; + img.load(stream, ext); + loadImage(img); + } + //--------------------------------------------------------------------- + void TerrainLayerBlendMap::loadImage(const String& filename, const String& groupName) + { + Image img; + img.load(filename, groupName); + loadImage(img); + } } diff --git a/Components/Terrain/src/OgreTerrainLodManager.cpp b/Components/Terrain/src/OgreTerrainLodManager.cpp index dcf6fa9b2af..91d4d2284ae 100644 --- a/Components/Terrain/src/OgreTerrainLodManager.cpp +++ b/Components/Terrain/src/OgreTerrainLodManager.cpp @@ -34,288 +34,288 @@ THE SOFTWARE. namespace Ogre { - const uint16 TerrainLodManager::WORKQUEUE_LOAD_LOD_DATA_REQUEST = 1; - const uint32 TerrainLodManager::TERRAINLODDATA_CHUNK_ID = StreamSerialiser::makeIdentifier("TLDA"); - const uint16 TerrainLodManager::TERRAINLODDATA_CHUNK_VERSION = 1; - - TerrainLodManager::TerrainLodManager(Terrain* t, DataStreamPtr& stream) - : mTerrain(t) - { - init(); - mDataStream = stream; - mStreamOffset = mDataStream.isNull() ? 0 : mDataStream->tell(); - } - - TerrainLodManager::TerrainLodManager(Terrain* t, const String& filename) - : mTerrain(t), mStreamOffset(0) - { - init(); - - if(!filename.empty() && filename.length() > 0) - mDataStream = Root::getSingleton().openFileStream(filename, mTerrain->_getDerivedResourceGroup()); - } - - void TerrainLodManager::init() - { - mHighestLodPrepared = -1; - mHighestLodLoaded = -1; - mTargetLodLevel = -1; - mIncreaseLodLevelInProgress = false; - mLastRequestSynchronous = false; - mLodInfoTable = 0; - - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - mWorkQueueChannel = wq->getChannel("Ogre/TerrainLodManager"); - wq->addRequestHandler(mWorkQueueChannel, this); - wq->addResponseHandler(mWorkQueueChannel, this); - } - - TerrainLodManager::~TerrainLodManager() - { - waitForDerivedProcesses(); - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - wq->removeRequestHandler(mWorkQueueChannel, this); - wq->removeResponseHandler(mWorkQueueChannel, this); - - if(mLodInfoTable) - OGRE_FREE(mLodInfoTable,MEMCATEGORY_GENERAL); - } - - bool TerrainLodManager::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - LoadLodRequest lreq = any_cast(req->getData()); - if (lreq.requestee != this) - return false; - return RequestHandler::canHandleRequest(req, srcQ); - } - //--------------------------------------------------------------------- - bool TerrainLodManager::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - LoadLodRequest lreq = any_cast(res->getRequest()->getData()); - return (lreq.requestee == this); - } - - WorkQueue::Response* TerrainLodManager::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - LoadLodRequest lreq = any_cast(req->getData()); - // read data from file into temporary height & delta buffer - try { - if(lreq.currentPreparedLod>lreq.requestedLod) - readLodData(lreq.currentPreparedLod-1, lreq.requestedLod); - } catch (Exception& e) { - return OGRE_NEW WorkQueue::Response(req, false, Any(), e.getFullDescription()); - } - - int lastTreeStart = -1; - for( int level=lreq.currentLoadedLod-1; level>=lreq.requestedLod; --level ) - { - LodInfo& lodinfo = getLodInfo(level); - // skip re-assign - if(lastTreeStart != (int)lodinfo.treeStart) - { - mTerrain->getQuadTree()->assignVertexData(lodinfo.treeStart, lodinfo.treeEnd, - lodinfo.resolution, lodinfo.size); - lastTreeStart = lodinfo.treeStart; - } - } - return OGRE_NEW WorkQueue::Response(req, true, Any()); - } + const uint16 TerrainLodManager::WORKQUEUE_LOAD_LOD_DATA_REQUEST = 1; + const uint32 TerrainLodManager::TERRAINLODDATA_CHUNK_ID = StreamSerialiser::makeIdentifier("TLDA"); + const uint16 TerrainLodManager::TERRAINLODDATA_CHUNK_VERSION = 1; + + TerrainLodManager::TerrainLodManager(Terrain* t, DataStreamPtr& stream) + : mTerrain(t) + { + init(); + mDataStream = stream; + mStreamOffset = mDataStream.isNull() ? 0 : mDataStream->tell(); + } + + TerrainLodManager::TerrainLodManager(Terrain* t, const String& filename) + : mTerrain(t), mStreamOffset(0) + { + init(); + + if(!filename.empty() && filename.length() > 0) + mDataStream = Root::getSingleton().openFileStream(filename, mTerrain->_getDerivedResourceGroup()); + } + + void TerrainLodManager::init() + { + mHighestLodPrepared = -1; + mHighestLodLoaded = -1; + mTargetLodLevel = -1; + mIncreaseLodLevelInProgress = false; + mLastRequestSynchronous = false; + mLodInfoTable = 0; + + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + mWorkQueueChannel = wq->getChannel("Ogre/TerrainLodManager"); + wq->addRequestHandler(mWorkQueueChannel, this); + wq->addResponseHandler(mWorkQueueChannel, this); + } + + TerrainLodManager::~TerrainLodManager() + { + waitForDerivedProcesses(); + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + wq->removeRequestHandler(mWorkQueueChannel, this); + wq->removeResponseHandler(mWorkQueueChannel, this); + + if(mLodInfoTable) + OGRE_FREE(mLodInfoTable,MEMCATEGORY_GENERAL); + } + + bool TerrainLodManager::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + LoadLodRequest lreq = any_cast(req->getData()); + if (lreq.requestee != this) + return false; + return RequestHandler::canHandleRequest(req, srcQ); + } + //--------------------------------------------------------------------- + bool TerrainLodManager::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + LoadLodRequest lreq = any_cast(res->getRequest()->getData()); + return (lreq.requestee == this); + } + + WorkQueue::Response* TerrainLodManager::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + LoadLodRequest lreq = any_cast(req->getData()); + // read data from file into temporary height & delta buffer + try { + if(lreq.currentPreparedLod>lreq.requestedLod) + readLodData(lreq.currentPreparedLod-1, lreq.requestedLod); + } catch (Exception& e) { + return OGRE_NEW WorkQueue::Response(req, false, Any(), e.getFullDescription()); + } + + int lastTreeStart = -1; + for( int level=lreq.currentLoadedLod-1; level>=lreq.requestedLod; --level ) + { + LodInfo& lodinfo = getLodInfo(level); + // skip re-assign + if(lastTreeStart != (int)lodinfo.treeStart) + { + mTerrain->getQuadTree()->assignVertexData(lodinfo.treeStart, lodinfo.treeEnd, + lodinfo.resolution, lodinfo.size); + lastTreeStart = lodinfo.treeStart; + } + } + return OGRE_NEW WorkQueue::Response(req, true, Any()); + } void TerrainLodManager::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - const WorkQueue::Request* req = res->getRequest(); - // No response data, just request - LoadLodRequest lreq = any_cast(req->getData()); - - mIncreaseLodLevelInProgress = false; - - if (res->succeeded()) - { - // no others update LOD status - if(lreq.currentPreparedLod == mHighestLodPrepared && lreq.currentLoadedLod == mHighestLodLoaded ) - { - if( lreq.requestedLod < mHighestLodPrepared ) - mHighestLodPrepared = lreq.requestedLod; - - int lastTreeStart = -1; - for( int level = mHighestLodLoaded-1; level>=lreq.requestedLod && level>=mTargetLodLevel; --level ) - { - LodInfo& lodinfo = getLodInfo(level); - // skip re-load - if(lastTreeStart != (int)lodinfo.treeStart) - { - mTerrain->getQuadTree()->load(lodinfo.treeStart, lodinfo.treeEnd); - lastTreeStart = lodinfo.treeStart; - } - --mHighestLodLoaded; - } - } - - // has streamed in new data, should update terrain - if(lreq.currentPreparedLod>lreq.requestedLod) - { - mTerrain->dirty(); - mTerrain->updateGeometryWithoutNotifyNeighbours(); - } - - // there are new requests - if(mHighestLodLoaded != mTargetLodLevel) - updateToLodLevel(mTargetLodLevel,mLastRequestSynchronous); - } - else - { - LogManager::getSingleton().stream(LML_CRITICAL) << "Failed to prepare and load terrain LOD: " << res->getMessages(); - } - } - void TerrainLodManager::buildLodInfoTable() - { - uint16 numLodLevels = mTerrain->getNumLodLevels(); - mLodInfoTable = OGRE_ALLOC_T(LodInfo, numLodLevels, MEMCATEGORY_GENERAL); - - uint16 size = mTerrain->getSize(); - uint16 depth = mTerrain->mTreeDepth; - uint16 prevdepth = depth; - uint16 last = 0; - uint16 currresolution = size; - uint16 bakedresolution = size; - uint16 targetSplits = (bakedresolution - 1) / (Terrain::TERRAIN_MAX_BATCH_SIZE - 1); - - int *lodDepth = OGRE_ALLOC_T(int, numLodLevels, MEMCATEGORY_GENERAL); - for(int level=0; levelgetNumLodLevelsPerLeaf()) ? depth-1 : numLodLevels-level-1; - - while(depth-- && targetSplits) - { - uint splits = 1 << depth; - if (splits == targetSplits) - { - for(uint level=0; level= depth && lodDepth[level] < prevdepth) - { - mLodInfoTable[level].treeStart = depth; - mLodInfoTable[level].treeEnd = prevdepth; - mLodInfoTable[level].isLast = level == last+prevdepth-depth-static_cast(1); - mLodInfoTable[level].resolution = bakedresolution; - mLodInfoTable[level].size = ((bakedresolution-1) / splits) + 1; - // this lod info has been filled - lodDepth[level] = -1; - } - } - // next set to look for - bakedresolution = ((currresolution - 1) >> 1) + 1; - targetSplits = (bakedresolution - 1) / (Terrain::TERRAIN_MAX_BATCH_SIZE - 1); - prevdepth = depth; - } - currresolution = ((currresolution - 1) >> 1) + 1; - last++; - } - for(int level=0; level=0 && lodDepth[level]<=prevdepth) - { - mLodInfoTable[level].treeStart = 0; - mLodInfoTable[level].treeEnd = 1; - mLodInfoTable[level].isLast = level == last+prevdepth-depth-1; - mLodInfoTable[level].resolution = bakedresolution; - mLodInfoTable[level].size = bakedresolution; - } - } - OGRE_FREE(lodDepth,MEMCATEGORY_GENERAL); - } + { + const WorkQueue::Request* req = res->getRequest(); + // No response data, just request + LoadLodRequest lreq = any_cast(req->getData()); + + mIncreaseLodLevelInProgress = false; + + if (res->succeeded()) + { + // no others update LOD status + if(lreq.currentPreparedLod == mHighestLodPrepared && lreq.currentLoadedLod == mHighestLodLoaded ) + { + if( lreq.requestedLod < mHighestLodPrepared ) + mHighestLodPrepared = lreq.requestedLod; + + int lastTreeStart = -1; + for( int level = mHighestLodLoaded-1; level>=lreq.requestedLod && level>=mTargetLodLevel; --level ) + { + LodInfo& lodinfo = getLodInfo(level); + // skip re-load + if(lastTreeStart != (int)lodinfo.treeStart) + { + mTerrain->getQuadTree()->load(lodinfo.treeStart, lodinfo.treeEnd); + lastTreeStart = lodinfo.treeStart; + } + --mHighestLodLoaded; + } + } + + // has streamed in new data, should update terrain + if(lreq.currentPreparedLod>lreq.requestedLod) + { + mTerrain->dirty(); + mTerrain->updateGeometryWithoutNotifyNeighbours(); + } + + // there are new requests + if(mHighestLodLoaded != mTargetLodLevel) + updateToLodLevel(mTargetLodLevel,mLastRequestSynchronous); + } + else + { + LogManager::getSingleton().stream(LML_CRITICAL) << "Failed to prepare and load terrain LOD: " << res->getMessages(); + } + } + void TerrainLodManager::buildLodInfoTable() + { + uint16 numLodLevels = mTerrain->getNumLodLevels(); + mLodInfoTable = OGRE_ALLOC_T(LodInfo, numLodLevels, MEMCATEGORY_GENERAL); + + uint16 size = mTerrain->getSize(); + uint16 depth = mTerrain->mTreeDepth; + uint16 prevdepth = depth; + uint16 last = 0; + uint16 currresolution = size; + uint16 bakedresolution = size; + uint16 targetSplits = (bakedresolution - 1) / (Terrain::TERRAIN_MAX_BATCH_SIZE - 1); + + int *lodDepth = OGRE_ALLOC_T(int, numLodLevels, MEMCATEGORY_GENERAL); + for(int level=0; levelgetNumLodLevelsPerLeaf()) ? depth-1 : numLodLevels-level-1; + + while(depth-- && targetSplits) + { + uint splits = 1 << depth; + if (splits == targetSplits) + { + for(uint level=0; level= depth && lodDepth[level] < prevdepth) + { + mLodInfoTable[level].treeStart = depth; + mLodInfoTable[level].treeEnd = prevdepth; + mLodInfoTable[level].isLast = level == last+prevdepth-depth-static_cast(1); + mLodInfoTable[level].resolution = bakedresolution; + mLodInfoTable[level].size = ((bakedresolution-1) / splits) + 1; + // this lod info has been filled + lodDepth[level] = -1; + } + } + // next set to look for + bakedresolution = ((currresolution - 1) >> 1) + 1; + targetSplits = (bakedresolution - 1) / (Terrain::TERRAIN_MAX_BATCH_SIZE - 1); + prevdepth = depth; + } + currresolution = ((currresolution - 1) >> 1) + 1; + last++; + } + for(int level=0; level=0 && lodDepth[level]<=prevdepth) + { + mLodInfoTable[level].treeStart = 0; + mLodInfoTable[level].treeEnd = 1; + mLodInfoTable[level].isLast = level == last+prevdepth-depth-1; + mLodInfoTable[level].resolution = bakedresolution; + mLodInfoTable[level].size = bakedresolution; + } + } + OGRE_FREE(lodDepth,MEMCATEGORY_GENERAL); + } // data are reorganized from lowest lod level(mNumLodLevels-1) to highest(0) - void TerrainLodManager::separateData(float* data, uint16 size, uint16 numLodLevels, LodsData& lods) - { - lods.resize(numLodLevels); - for (int level = numLodLevels - 1; level >= 0; level--) - { - unsigned int inc = 1 << level; - unsigned int prev = 1 << (level + 1); - - for (uint16 y = 0; y < size; y += inc) - { - for (uint16 x = 0; x < size-1; x += inc) - if ((level == numLodLevels - 1) || ((x % prev != 0) || (y % prev != 0))) - lods[level].push_back( data[y*size + x] ); - if ((level == numLodLevels -1) || (y % prev) != 0) - lods[level].push_back( data[y*size + size-1] ); - if (y+inc > size) - break; - } - } - } - //--------------------------------------------------------------------- - void TerrainLodManager::updateToLodLevel(int lodLevel, bool synchronous /* = false */) - { - //init - if(mHighestLodPrepared==-1) - mHighestLodPrepared = mTerrain->getNumLodLevels(); - if(mHighestLodLoaded==-1) - mHighestLodLoaded = mTerrain->getNumLodLevels(); - - lodLevel = mTerrain->getPositiveLodLevel(lodLevel); - - mTargetLodLevel = lodLevel; - mLastRequestSynchronous = synchronous; - - // need loading - if(mTargetLodLeveladdRequest( - mWorkQueueChannel, WORKQUEUE_LOAD_LOD_DATA_REQUEST, - Any(req), 0, synchronous); - } - else if(synchronous) - waitForDerivedProcesses(); - } - // need unloading - else if(mTargetLodLevel>mHighestLodLoaded) - { - for( int level=mHighestLodLoaded; levelgetQuadTree()->unload(lod.treeStart, lod.treeEnd); - mHighestLodLoaded = level+1; - } - } - } - } - - // save each LOD level separately compressed so seek is possible - void TerrainLodManager::saveLodData(StreamSerialiser& stream, Terrain* terrain) - { - uint16 numLodLevels = terrain->getNumLodLevels(); - - LodsData lods; - separateData(terrain->mHeightData, terrain->getSize(), numLodLevels, lods); - separateData(terrain->mDeltaData, terrain->getSize(), numLodLevels, lods); - - for (int level = numLodLevels - 1; level >=0; level--) - { - stream.writeChunkBegin(TERRAINLODDATA_CHUNK_ID, TERRAINLODDATA_CHUNK_VERSION); - stream.startDeflate(); - stream.write(&(lods[level][0]), lods[level].size()); - stream.stopDeflate(); - stream.writeChunkEnd(TERRAINLODDATA_CHUNK_ID); - } - } - - void TerrainLodManager::readLodData(uint16 lowerLodBound, uint16 higherLodBound) - { - if(mDataStream.isNull()) // No file to read from - return; - - uint16 numLodLevels = mTerrain->getNumLodLevels(); - mDataStream->seek(mStreamOffset); - StreamSerialiser stream(mDataStream); + void TerrainLodManager::separateData(float* data, uint16 size, uint16 numLodLevels, LodsData& lods) + { + lods.resize(numLodLevels); + for (int level = numLodLevels - 1; level >= 0; level--) + { + unsigned int inc = 1 << level; + unsigned int prev = 1 << (level + 1); + + for (uint16 y = 0; y < size; y += inc) + { + for (uint16 x = 0; x < size-1; x += inc) + if ((level == numLodLevels - 1) || ((x % prev != 0) || (y % prev != 0))) + lods[level].push_back( data[y*size + x] ); + if ((level == numLodLevels -1) || (y % prev) != 0) + lods[level].push_back( data[y*size + size-1] ); + if (y+inc > size) + break; + } + } + } + //--------------------------------------------------------------------- + void TerrainLodManager::updateToLodLevel(int lodLevel, bool synchronous /* = false */) + { + //init + if(mHighestLodPrepared==-1) + mHighestLodPrepared = mTerrain->getNumLodLevels(); + if(mHighestLodLoaded==-1) + mHighestLodLoaded = mTerrain->getNumLodLevels(); + + lodLevel = mTerrain->getPositiveLodLevel(lodLevel); + + mTargetLodLevel = lodLevel; + mLastRequestSynchronous = synchronous; + + // need loading + if(mTargetLodLeveladdRequest( + mWorkQueueChannel, WORKQUEUE_LOAD_LOD_DATA_REQUEST, + Any(req), 0, synchronous); + } + else if(synchronous) + waitForDerivedProcesses(); + } + // need unloading + else if(mTargetLodLevel>mHighestLodLoaded) + { + for( int level=mHighestLodLoaded; levelgetQuadTree()->unload(lod.treeStart, lod.treeEnd); + mHighestLodLoaded = level+1; + } + } + } + } + + // save each LOD level separately compressed so seek is possible + void TerrainLodManager::saveLodData(StreamSerialiser& stream, Terrain* terrain) + { + uint16 numLodLevels = terrain->getNumLodLevels(); + + LodsData lods; + separateData(terrain->mHeightData, terrain->getSize(), numLodLevels, lods); + separateData(terrain->mDeltaData, terrain->getSize(), numLodLevels, lods); + + for (int level = numLodLevels - 1; level >=0; level--) + { + stream.writeChunkBegin(TERRAINLODDATA_CHUNK_ID, TERRAINLODDATA_CHUNK_VERSION); + stream.startDeflate(); + stream.write(&(lods[level][0]), lods[level].size()); + stream.stopDeflate(); + stream.writeChunkEnd(TERRAINLODDATA_CHUNK_ID); + } + } + + void TerrainLodManager::readLodData(uint16 lowerLodBound, uint16 higherLodBound) + { + if(mDataStream.isNull()) // No file to read from + return; + + uint16 numLodLevels = mTerrain->getNumLodLevels(); + mDataStream->seek(mStreamOffset); + StreamSerialiser stream(mDataStream); const StreamSerialiser::Chunk *mainChunk = stream.readChunkBegin(Terrain::TERRAIN_CHUNK_ID, Terrain::TERRAIN_CHUNK_VERSION); @@ -355,41 +355,41 @@ namespace Ogre OGRE_FREE(lodData, MEMCATEGORY_GENERAL); } - } - void TerrainLodManager::fillBufferAtLod(uint lodLevel, const float* data, uint dataSize ) - { - unsigned int inc = 1 << lodLevel; - unsigned int prev = 1 << (lodLevel + 1); - uint16 numLodLevels = mTerrain->getNumLodLevels(); - uint16 size = mTerrain->getSize(); - - const float* heightDataPtr = data; - const float* deltaDataPtr = data+dataSize/2; - - for (uint16 y = 0; y < size; y += inc) - { - for (uint16 x = 0; x < size-1; x += inc) - if ((lodLevel == numLodLevels - static_cast(1)) || (x % prev) || (y % prev)) - { - mTerrain->mHeightData[y*size + x] = *(heightDataPtr++); - mTerrain->mDeltaData[y*size + x] = *(deltaDataPtr++); - } - if ((lodLevel == numLodLevels - static_cast(1)) || (y % prev)) - { - mTerrain->mHeightData[y*size + size-1] = *(heightDataPtr++); - mTerrain->mDeltaData[y*size + size-1] = *(deltaDataPtr++); - } - if (y+inc > size) - break; - } - } - void TerrainLodManager::waitForDerivedProcesses() - { - while (mIncreaseLodLevelInProgress) - { - // we need to wait for this to finish - OGRE_THREAD_SLEEP(50); - Root::getSingleton().getWorkQueue()->processResponses(); - } - } + } + void TerrainLodManager::fillBufferAtLod(uint lodLevel, const float* data, uint dataSize ) + { + unsigned int inc = 1 << lodLevel; + unsigned int prev = 1 << (lodLevel + 1); + uint16 numLodLevels = mTerrain->getNumLodLevels(); + uint16 size = mTerrain->getSize(); + + const float* heightDataPtr = data; + const float* deltaDataPtr = data+dataSize/2; + + for (uint16 y = 0; y < size; y += inc) + { + for (uint16 x = 0; x < size-1; x += inc) + if ((lodLevel == numLodLevels - static_cast(1)) || (x % prev) || (y % prev)) + { + mTerrain->mHeightData[y*size + x] = *(heightDataPtr++); + mTerrain->mDeltaData[y*size + x] = *(deltaDataPtr++); + } + if ((lodLevel == numLodLevels - static_cast(1)) || (y % prev)) + { + mTerrain->mHeightData[y*size + size-1] = *(heightDataPtr++); + mTerrain->mDeltaData[y*size + size-1] = *(deltaDataPtr++); + } + if (y+inc > size) + break; + } + } + void TerrainLodManager::waitForDerivedProcesses() + { + while (mIncreaseLodLevelInProgress) + { + // we need to wait for this to finish + OGRE_THREAD_SLEEP(50); + Root::getSingleton().getWorkQueue()->processResponses(); + } + } } diff --git a/Components/Terrain/src/OgreTerrainMaterialGenerator.cpp b/Components/Terrain/src/OgreTerrainMaterialGenerator.cpp index 55a8b9f19aa..07efa4d2899 100644 --- a/Components/Terrain/src/OgreTerrainMaterialGenerator.cpp +++ b/Components/Terrain/src/OgreTerrainMaterialGenerator.cpp @@ -47,168 +47,168 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - TerrainMaterialGenerator::TerrainMaterialGenerator() - : mActiveProfile(0) - , mChangeCounter(0) - , mDebugLevel(0) - , mCompositeMapSM(0) - , mCompositeMapCam(0) - , mCompositeMapRTT(0) - , mCompositeMapPlane(0) - , mCompositeMapLight(0) - { - - } - //--------------------------------------------------------------------- - TerrainMaterialGenerator::~TerrainMaterialGenerator() - { - for (ProfileList::iterator i = mProfiles.begin(); i != mProfiles.end(); ++i) - OGRE_DELETE *i; - - if (mCompositeMapRTT && TextureManager::getSingletonPtr()) - { - TextureManager::getSingleton().remove(mCompositeMapRTT->getHandle()); - mCompositeMapRTT = 0; - } - if (mCompositeMapSM && Root::getSingletonPtr()) - { - // will also delete cam and objects etc - Root::getSingleton().destroySceneManager(mCompositeMapSM); - mCompositeMapSM = 0; - mCompositeMapCam = 0; - mCompositeMapPlane = 0; - mCompositeMapLight = 0; - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGenerator::_renderCompositeMap(size_t size, - const Rect& rect, const MaterialPtr& mat, const TexturePtr& destCompositeMap) - { - if (!mCompositeMapSM) - { - // dedicated SceneManager - mCompositeMapSM = Root::getSingleton().createSceneManager(DefaultSceneManagerFactory::FACTORY_TYPE_NAME); - float camDist = 100; - float halfCamDist = camDist * 0.5f; - mCompositeMapCam = mCompositeMapSM->createCamera("cam"); - mCompositeMapCam->setPosition(0, 0, camDist); - mCompositeMapCam->lookAt(Vector3::ZERO); - mCompositeMapCam->setProjectionType(PT_ORTHOGRAPHIC); - mCompositeMapCam->setNearClipDistance(10); - mCompositeMapCam->setFarClipDistance(500); - mCompositeMapCam->setOrthoWindow(camDist, camDist); - - // Just in case material relies on light auto params - mCompositeMapLight = mCompositeMapSM->createLight(); - mCompositeMapLight->setType(Light::LT_DIRECTIONAL); - - RenderSystem* rSys = Root::getSingleton().getRenderSystem(); - Real hOffset = rSys->getHorizontalTexelOffset() / (Real)size; - Real vOffset = rSys->getVerticalTexelOffset() / (Real)size; - - - // set up scene - mCompositeMapPlane = mCompositeMapSM->createManualObject(); - mCompositeMapPlane->begin(mat->getName()); - mCompositeMapPlane->position(-halfCamDist, halfCamDist, 0); - mCompositeMapPlane->textureCoord(0 - hOffset, 0 - vOffset); - mCompositeMapPlane->position(-halfCamDist, -halfCamDist, 0); - mCompositeMapPlane->textureCoord(0 - hOffset, 1 - vOffset); - mCompositeMapPlane->position(halfCamDist, -halfCamDist, 0); - mCompositeMapPlane->textureCoord(1 - hOffset, 1 - vOffset); - mCompositeMapPlane->position(halfCamDist, halfCamDist, 0); - mCompositeMapPlane->textureCoord(1 - hOffset, 0 - vOffset); - mCompositeMapPlane->quad(0, 1, 2, 3); - mCompositeMapPlane->end(); - mCompositeMapSM->getRootSceneNode()->attachObject(mCompositeMapPlane); - - } - - // update - mCompositeMapPlane->setMaterialName(0, mat->getName()); - TerrainGlobalOptions& globalopts = TerrainGlobalOptions::getSingleton(); - mCompositeMapLight->setDirection(globalopts.getLightMapDirection()); - mCompositeMapLight->setDiffuseColour(globalopts.getCompositeMapDiffuse()); - mCompositeMapSM->setAmbientLight(globalopts.getCompositeMapAmbient()); - - - // check for size change (allow smaller to be reused) - if (mCompositeMapRTT && size != mCompositeMapRTT->getWidth()) - { - TextureManager::getSingleton().remove(mCompositeMapRTT->getHandle()); - mCompositeMapRTT = 0; - } - - if (!mCompositeMapRTT) - { - mCompositeMapRTT = TextureManager::getSingleton().createManual( - mCompositeMapSM->getName() + "/compRTT", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, static_cast(size), static_cast(size), 0, PF_BYTE_RGBA, - TU_RENDERTARGET).get(); - RenderTarget* rtt = mCompositeMapRTT->getBuffer()->getRenderTarget(); - // don't render all the time, only on demand - rtt->setAutoUpdated(false); - Viewport* vp = rtt->addViewport(mCompositeMapCam); - // don't render overlays - vp->setOverlaysEnabled(false); - - } - - // calculate the area we need to update - Real vpleft = (Real)rect.left / (Real)size; - Real vptop = (Real)rect.top / (Real)size; - Real vpright = (Real)rect.right / (Real)size; - Real vpbottom = (Real)rect.bottom / (Real)size; - - RenderTarget* rtt = mCompositeMapRTT->getBuffer()->getRenderTarget(); - mCompositeMapCam->setWindow(vpleft, vptop, vpright, vpbottom); - - rtt->update(); - - // We have an RTT, we want to copy the results into a regular texture - // That's because in non-update scenarios we don't want to keep an RTT - // around. We use a single RTT to serve all terrain pages which is more - // efficient. - Image::Box box(static_cast(rect.left), + //--------------------------------------------------------------------- + TerrainMaterialGenerator::TerrainMaterialGenerator() + : mActiveProfile(0) + , mChangeCounter(0) + , mDebugLevel(0) + , mCompositeMapSM(0) + , mCompositeMapCam(0) + , mCompositeMapRTT(0) + , mCompositeMapPlane(0) + , mCompositeMapLight(0) + { + + } + //--------------------------------------------------------------------- + TerrainMaterialGenerator::~TerrainMaterialGenerator() + { + for (ProfileList::iterator i = mProfiles.begin(); i != mProfiles.end(); ++i) + OGRE_DELETE *i; + + if (mCompositeMapRTT && TextureManager::getSingletonPtr()) + { + TextureManager::getSingleton().remove(mCompositeMapRTT->getHandle()); + mCompositeMapRTT = 0; + } + if (mCompositeMapSM && Root::getSingletonPtr()) + { + // will also delete cam and objects etc + Root::getSingleton().destroySceneManager(mCompositeMapSM); + mCompositeMapSM = 0; + mCompositeMapCam = 0; + mCompositeMapPlane = 0; + mCompositeMapLight = 0; + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGenerator::_renderCompositeMap(size_t size, + const Rect& rect, const MaterialPtr& mat, const TexturePtr& destCompositeMap) + { + if (!mCompositeMapSM) + { + // dedicated SceneManager + mCompositeMapSM = Root::getSingleton().createSceneManager(DefaultSceneManagerFactory::FACTORY_TYPE_NAME); + float camDist = 100; + float halfCamDist = camDist * 0.5f; + mCompositeMapCam = mCompositeMapSM->createCamera("cam"); + mCompositeMapCam->setPosition(0, 0, camDist); + mCompositeMapCam->lookAt(Vector3::ZERO); + mCompositeMapCam->setProjectionType(PT_ORTHOGRAPHIC); + mCompositeMapCam->setNearClipDistance(10); + mCompositeMapCam->setFarClipDistance(500); + mCompositeMapCam->setOrthoWindow(camDist, camDist); + + // Just in case material relies on light auto params + mCompositeMapLight = mCompositeMapSM->createLight(); + mCompositeMapLight->setType(Light::LT_DIRECTIONAL); + + RenderSystem* rSys = Root::getSingleton().getRenderSystem(); + Real hOffset = rSys->getHorizontalTexelOffset() / (Real)size; + Real vOffset = rSys->getVerticalTexelOffset() / (Real)size; + + + // set up scene + mCompositeMapPlane = mCompositeMapSM->createManualObject(); + mCompositeMapPlane->begin(mat->getName()); + mCompositeMapPlane->position(-halfCamDist, halfCamDist, 0); + mCompositeMapPlane->textureCoord(0 - hOffset, 0 - vOffset); + mCompositeMapPlane->position(-halfCamDist, -halfCamDist, 0); + mCompositeMapPlane->textureCoord(0 - hOffset, 1 - vOffset); + mCompositeMapPlane->position(halfCamDist, -halfCamDist, 0); + mCompositeMapPlane->textureCoord(1 - hOffset, 1 - vOffset); + mCompositeMapPlane->position(halfCamDist, halfCamDist, 0); + mCompositeMapPlane->textureCoord(1 - hOffset, 0 - vOffset); + mCompositeMapPlane->quad(0, 1, 2, 3); + mCompositeMapPlane->end(); + mCompositeMapSM->getRootSceneNode()->attachObject(mCompositeMapPlane); + + } + + // update + mCompositeMapPlane->setMaterialName(0, mat->getName()); + TerrainGlobalOptions& globalopts = TerrainGlobalOptions::getSingleton(); + mCompositeMapLight->setDirection(globalopts.getLightMapDirection()); + mCompositeMapLight->setDiffuseColour(globalopts.getCompositeMapDiffuse()); + mCompositeMapSM->setAmbientLight(globalopts.getCompositeMapAmbient()); + + + // check for size change (allow smaller to be reused) + if (mCompositeMapRTT && size != mCompositeMapRTT->getWidth()) + { + TextureManager::getSingleton().remove(mCompositeMapRTT->getHandle()); + mCompositeMapRTT = 0; + } + + if (!mCompositeMapRTT) + { + mCompositeMapRTT = TextureManager::getSingleton().createManual( + mCompositeMapSM->getName() + "/compRTT", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, static_cast(size), static_cast(size), 0, PF_BYTE_RGBA, + TU_RENDERTARGET).get(); + RenderTarget* rtt = mCompositeMapRTT->getBuffer()->getRenderTarget(); + // don't render all the time, only on demand + rtt->setAutoUpdated(false); + Viewport* vp = rtt->addViewport(mCompositeMapCam); + // don't render overlays + vp->setOverlaysEnabled(false); + + } + + // calculate the area we need to update + Real vpleft = (Real)rect.left / (Real)size; + Real vptop = (Real)rect.top / (Real)size; + Real vpright = (Real)rect.right / (Real)size; + Real vpbottom = (Real)rect.bottom / (Real)size; + + RenderTarget* rtt = mCompositeMapRTT->getBuffer()->getRenderTarget(); + mCompositeMapCam->setWindow(vpleft, vptop, vpright, vpbottom); + + rtt->update(); + + // We have an RTT, we want to copy the results into a regular texture + // That's because in non-update scenarios we don't want to keep an RTT + // around. We use a single RTT to serve all terrain pages which is more + // efficient. + Image::Box box(static_cast(rect.left), static_cast(rect.top), static_cast(rect.right), static_cast(rect.bottom)); - destCompositeMap->getBuffer()->blit(mCompositeMapRTT->getBuffer(), box, box); - - - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - void TerrainMaterialGenerator::Profile::updateCompositeMap(const Terrain* terrain, const Rect& rect) - { - // convert point-space rect into image space - size_t compSize = terrain->getCompositeMap()->getWidth(); - Rect imgRect; - Vector3 inVec, outVec; - inVec.x = rect.left; - inVec.y = rect.bottom - 1; // this is 'top' in image space, also make inclusive - terrain->convertPosition(Terrain::POINT_SPACE, inVec, Terrain::TERRAIN_SPACE, outVec); - imgRect.left = outVec.x * compSize; - imgRect.top = (1.0f - outVec.y) * compSize; - inVec.x = rect.right - 1; - inVec.y = rect.top; // this is 'bottom' in image space - terrain->convertPosition(Terrain::POINT_SPACE, inVec, Terrain::TERRAIN_SPACE, outVec); - imgRect.right = outVec.x * (Real)compSize + 1; - imgRect.bottom = (1.0 - outVec.y) * compSize + 1; - - imgRect.left = std::max(0L, imgRect.left); - imgRect.top = std::max(0L, imgRect.top); - imgRect.right = std::min((long)compSize, imgRect.right); - imgRect.bottom = std::min((long)compSize, imgRect.bottom); - - - mParent->_renderCompositeMap( - compSize, imgRect, - terrain->getCompositeMapMaterial(), - terrain->getCompositeMap()); - - } + destCompositeMap->getBuffer()->blit(mCompositeMapRTT->getBuffer(), box, box); + + + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void TerrainMaterialGenerator::Profile::updateCompositeMap(const Terrain* terrain, const Rect& rect) + { + // convert point-space rect into image space + size_t compSize = terrain->getCompositeMap()->getWidth(); + Rect imgRect; + Vector3 inVec, outVec; + inVec.x = rect.left; + inVec.y = rect.bottom - 1; // this is 'top' in image space, also make inclusive + terrain->convertPosition(Terrain::POINT_SPACE, inVec, Terrain::TERRAIN_SPACE, outVec); + imgRect.left = outVec.x * compSize; + imgRect.top = (1.0f - outVec.y) * compSize; + inVec.x = rect.right - 1; + inVec.y = rect.top; // this is 'bottom' in image space + terrain->convertPosition(Terrain::POINT_SPACE, inVec, Terrain::TERRAIN_SPACE, outVec); + imgRect.right = outVec.x * (Real)compSize + 1; + imgRect.bottom = (1.0 - outVec.y) * compSize + 1; + + imgRect.left = std::max(0L, imgRect.left); + imgRect.top = std::max(0L, imgRect.top); + imgRect.right = std::min((long)compSize, imgRect.right); + imgRect.bottom = std::min((long)compSize, imgRect.bottom); + + + mParent->_renderCompositeMap( + compSize, imgRect, + terrain->getCompositeMapMaterial(), + terrain->getCompositeMap()); + + } } diff --git a/Components/Terrain/src/OgreTerrainMaterialGeneratorA.cpp b/Components/Terrain/src/OgreTerrainMaterialGeneratorA.cpp index 235da243564..de5a3ee23fa 100644 --- a/Components/Terrain/src/OgreTerrainMaterialGeneratorA.cpp +++ b/Components/Terrain/src/OgreTerrainMaterialGeneratorA.cpp @@ -41,56 +41,56 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - TerrainMaterialGeneratorA::TerrainMaterialGeneratorA() - { - // define the layers - // We expect terrain textures to have no alpha, so we use the alpha channel - // in the albedo texture to store specular reflection - // similarly we double-up the normal and height (for parallax) - mLayerDecl.samplers.push_back(TerrainLayerSampler("albedo_specular", PF_BYTE_RGBA)); - mLayerDecl.samplers.push_back(TerrainLayerSampler("normal_height", PF_BYTE_RGBA)); - - mLayerDecl.elements.push_back( - TerrainLayerSamplerElement(0, TLSS_ALBEDO, 0, 3)); - mLayerDecl.elements.push_back( - TerrainLayerSamplerElement(0, TLSS_SPECULAR, 3, 1)); - mLayerDecl.elements.push_back( - TerrainLayerSamplerElement(1, TLSS_NORMAL, 0, 3)); - mLayerDecl.elements.push_back( - TerrainLayerSamplerElement(1, TLSS_HEIGHT, 3, 1)); - - - mProfiles.push_back(OGRE_NEW SM2Profile(this, "SM2", "Profile for rendering on Shader Model 2 capable cards")); - // TODO - check hardware capabilities & use fallbacks if required (more profiles needed) - setActiveProfile("SM2"); - - } - //--------------------------------------------------------------------- - TerrainMaterialGeneratorA::~TerrainMaterialGeneratorA() - { - - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - TerrainMaterialGeneratorA::SM2Profile::SM2Profile(TerrainMaterialGenerator* parent, const String& name, const String& desc) - : Profile(parent, name, desc) - , mShaderGen(0) - , mLayerNormalMappingEnabled(true) - , mLayerParallaxMappingEnabled(true) - , mLayerSpecularMappingEnabled(true) - , mGlobalColourMapEnabled(true) - , mLightmapEnabled(true) - , mCompositeMapEnabled(true) - , mReceiveDynamicShadows(true) - , mPSSM(0) - , mDepthShadows(false) - , mLowLodShadows(false) + //--------------------------------------------------------------------- + TerrainMaterialGeneratorA::TerrainMaterialGeneratorA() + { + // define the layers + // We expect terrain textures to have no alpha, so we use the alpha channel + // in the albedo texture to store specular reflection + // similarly we double-up the normal and height (for parallax) + mLayerDecl.samplers.push_back(TerrainLayerSampler("albedo_specular", PF_BYTE_RGBA)); + mLayerDecl.samplers.push_back(TerrainLayerSampler("normal_height", PF_BYTE_RGBA)); + + mLayerDecl.elements.push_back( + TerrainLayerSamplerElement(0, TLSS_ALBEDO, 0, 3)); + mLayerDecl.elements.push_back( + TerrainLayerSamplerElement(0, TLSS_SPECULAR, 3, 1)); + mLayerDecl.elements.push_back( + TerrainLayerSamplerElement(1, TLSS_NORMAL, 0, 3)); + mLayerDecl.elements.push_back( + TerrainLayerSamplerElement(1, TLSS_HEIGHT, 3, 1)); + + + mProfiles.push_back(OGRE_NEW SM2Profile(this, "SM2", "Profile for rendering on Shader Model 2 capable cards")); + // TODO - check hardware capabilities & use fallbacks if required (more profiles needed) + setActiveProfile("SM2"); + + } + //--------------------------------------------------------------------- + TerrainMaterialGeneratorA::~TerrainMaterialGeneratorA() + { + + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + TerrainMaterialGeneratorA::SM2Profile::SM2Profile(TerrainMaterialGenerator* parent, const String& name, const String& desc) + : Profile(parent, name, desc) + , mShaderGen(0) + , mLayerNormalMappingEnabled(true) + , mLayerParallaxMappingEnabled(true) + , mLayerSpecularMappingEnabled(true) + , mGlobalColourMapEnabled(true) + , mLightmapEnabled(true) + , mCompositeMapEnabled(true) + , mReceiveDynamicShadows(true) + , mPSSM(0) + , mDepthShadows(false) + , mLowLodShadows(false) , mSM3Available(false) , mSM4Available(false) - { - HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton(); - if (hmgr.isLanguageSupported("hlsl")) + { + HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton(); + if (hmgr.isLanguageSupported("hlsl")) { mShaderLanguage = "hlsl"; } @@ -102,7 +102,7 @@ namespace Ogre { mShaderLanguage = "glsles"; } - else if (hmgr.isLanguageSupported("cg")) + else if (hmgr.isLanguageSupported("cg")) { mShaderLanguage = "cg"; } @@ -110,517 +110,517 @@ namespace Ogre { // todo } - } - //--------------------------------------------------------------------- - TerrainMaterialGeneratorA::SM2Profile::~SM2Profile() - { - OGRE_DELETE mShaderGen; - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::requestOptions(Terrain* terrain) - { - terrain->_setMorphRequired(true); - terrain->_setNormalMapRequired(true); - terrain->_setLightMapRequired(mLightmapEnabled, true); - terrain->_setCompositeMapRequired(mCompositeMapEnabled); - } - //--------------------------------------------------------------------- - bool TerrainMaterialGeneratorA::SM2Profile::isVertexCompressionSupported() const - { + } + //--------------------------------------------------------------------- + TerrainMaterialGeneratorA::SM2Profile::~SM2Profile() + { + OGRE_DELETE mShaderGen; + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::requestOptions(Terrain* terrain) + { + terrain->_setMorphRequired(true); + terrain->_setNormalMapRequired(true); + terrain->_setLightMapRequired(mLightmapEnabled, true); + terrain->_setCompositeMapRequired(mCompositeMapEnabled); + } + //--------------------------------------------------------------------- + bool TerrainMaterialGeneratorA::SM2Profile::isVertexCompressionSupported() const + { // FIXME: Not supporting compression on GLSL at the moment if ((mShaderLanguage == "glsl") || (mShaderLanguage == "glsles")) return false; else return true; - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::setLayerNormalMappingEnabled(bool enabled) - { - if (enabled != mLayerNormalMappingEnabled) - { - mLayerNormalMappingEnabled = enabled; - mParent->_markChanged(); - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::setLayerParallaxMappingEnabled(bool enabled) - { - if (enabled != mLayerParallaxMappingEnabled) - { - mLayerParallaxMappingEnabled = enabled; - mParent->_markChanged(); - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::setLayerSpecularMappingEnabled(bool enabled) - { - if (enabled != mLayerSpecularMappingEnabled) - { - mLayerSpecularMappingEnabled = enabled; - mParent->_markChanged(); - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::setGlobalColourMapEnabled(bool enabled) - { - if (enabled != mGlobalColourMapEnabled) - { - mGlobalColourMapEnabled = enabled; - mParent->_markChanged(); - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::setLightmapEnabled(bool enabled) - { - if (enabled != mLightmapEnabled) - { - mLightmapEnabled = enabled; - mParent->_markChanged(); - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::setCompositeMapEnabled(bool enabled) - { - if (enabled != mCompositeMapEnabled) - { - mCompositeMapEnabled = enabled; - mParent->_markChanged(); - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::setReceiveDynamicShadowsEnabled(bool enabled) - { - if (enabled != mReceiveDynamicShadows) - { - mReceiveDynamicShadows = enabled; - mParent->_markChanged(); - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::setReceiveDynamicShadowsPSSM(PSSMShadowCameraSetup* pssmSettings) - { - if (pssmSettings != mPSSM) - { - mPSSM = pssmSettings; - mParent->_markChanged(); - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::setReceiveDynamicShadowsDepth(bool enabled) - { - if (enabled != mDepthShadows) - { - mDepthShadows = enabled; - mParent->_markChanged(); - } - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::setReceiveDynamicShadowsLowLod(bool enabled) - { - if (enabled != mLowLodShadows) - { - mLowLodShadows = enabled; - mParent->_markChanged(); - } - } - //--------------------------------------------------------------------- - uint8 TerrainMaterialGeneratorA::SM2Profile::getMaxLayers(const Terrain* terrain) const - { - // count the texture units free - uint8 freeTextureUnits = 16; - // lightmap - --freeTextureUnits; - // normalmap - --freeTextureUnits; - // colourmap - if (terrain->getGlobalColourMapEnabled()) - --freeTextureUnits; - if (isShadowingEnabled(HIGH_LOD, terrain)) - { - uint8 numShadowTextures = 1; - if (getReceiveDynamicShadowsPSSM()) - { - numShadowTextures = (uint8)getReceiveDynamicShadowsPSSM()->getSplitCount(); - } - freeTextureUnits -= numShadowTextures; - } - - // each layer needs 2.25 units (1xdiffusespec, 1xnormalheight, 0.25xblend) - return static_cast(freeTextureUnits / 2.25f); - - - } - //--------------------------------------------------------------------- - MaterialPtr TerrainMaterialGeneratorA::SM2Profile::generate(const Terrain* terrain) - { - // re-use old material if exists - MaterialPtr mat = terrain->_getMaterial(); - if (mat.isNull()) - { - MaterialManager& matMgr = MaterialManager::getSingleton(); - - // it's important that the names are deterministic for a given terrain, so - // use the terrain pointer as an ID - const String& matName = terrain->getMaterialName(); - mat = matMgr.getByName(matName); - if (mat.isNull()) - { - mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - } - } - // clear everything - mat->removeAllTechniques(); - - // Automatically disable normal & parallax mapping if card cannot handle it - // We do this rather than having a specific technique for it since it's simpler - GpuProgramManager& gmgr = GpuProgramManager::getSingleton(); - if (!gmgr.isSyntaxSupported("ps_4_0") && !gmgr.isSyntaxSupported("ps_3_0") && !gmgr.isSyntaxSupported("ps_2_x") - && !gmgr.isSyntaxSupported("fp40") && !gmgr.isSyntaxSupported("arbfp1") && !gmgr.isSyntaxSupported("glsl") + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::setLayerNormalMappingEnabled(bool enabled) + { + if (enabled != mLayerNormalMappingEnabled) + { + mLayerNormalMappingEnabled = enabled; + mParent->_markChanged(); + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::setLayerParallaxMappingEnabled(bool enabled) + { + if (enabled != mLayerParallaxMappingEnabled) + { + mLayerParallaxMappingEnabled = enabled; + mParent->_markChanged(); + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::setLayerSpecularMappingEnabled(bool enabled) + { + if (enabled != mLayerSpecularMappingEnabled) + { + mLayerSpecularMappingEnabled = enabled; + mParent->_markChanged(); + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::setGlobalColourMapEnabled(bool enabled) + { + if (enabled != mGlobalColourMapEnabled) + { + mGlobalColourMapEnabled = enabled; + mParent->_markChanged(); + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::setLightmapEnabled(bool enabled) + { + if (enabled != mLightmapEnabled) + { + mLightmapEnabled = enabled; + mParent->_markChanged(); + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::setCompositeMapEnabled(bool enabled) + { + if (enabled != mCompositeMapEnabled) + { + mCompositeMapEnabled = enabled; + mParent->_markChanged(); + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::setReceiveDynamicShadowsEnabled(bool enabled) + { + if (enabled != mReceiveDynamicShadows) + { + mReceiveDynamicShadows = enabled; + mParent->_markChanged(); + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::setReceiveDynamicShadowsPSSM(PSSMShadowCameraSetup* pssmSettings) + { + if (pssmSettings != mPSSM) + { + mPSSM = pssmSettings; + mParent->_markChanged(); + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::setReceiveDynamicShadowsDepth(bool enabled) + { + if (enabled != mDepthShadows) + { + mDepthShadows = enabled; + mParent->_markChanged(); + } + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::setReceiveDynamicShadowsLowLod(bool enabled) + { + if (enabled != mLowLodShadows) + { + mLowLodShadows = enabled; + mParent->_markChanged(); + } + } + //--------------------------------------------------------------------- + uint8 TerrainMaterialGeneratorA::SM2Profile::getMaxLayers(const Terrain* terrain) const + { + // count the texture units free + uint8 freeTextureUnits = 16; + // lightmap + --freeTextureUnits; + // normalmap + --freeTextureUnits; + // colourmap + if (terrain->getGlobalColourMapEnabled()) + --freeTextureUnits; + if (isShadowingEnabled(HIGH_LOD, terrain)) + { + uint8 numShadowTextures = 1; + if (getReceiveDynamicShadowsPSSM()) + { + numShadowTextures = (uint8)getReceiveDynamicShadowsPSSM()->getSplitCount(); + } + freeTextureUnits -= numShadowTextures; + } + + // each layer needs 2.25 units (1xdiffusespec, 1xnormalheight, 0.25xblend) + return static_cast(freeTextureUnits / 2.25f); + + + } + //--------------------------------------------------------------------- + MaterialPtr TerrainMaterialGeneratorA::SM2Profile::generate(const Terrain* terrain) + { + // re-use old material if exists + MaterialPtr mat = terrain->_getMaterial(); + if (mat.isNull()) + { + MaterialManager& matMgr = MaterialManager::getSingleton(); + + // it's important that the names are deterministic for a given terrain, so + // use the terrain pointer as an ID + const String& matName = terrain->getMaterialName(); + mat = matMgr.getByName(matName); + if (mat.isNull()) + { + mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + } + } + // clear everything + mat->removeAllTechniques(); + + // Automatically disable normal & parallax mapping if card cannot handle it + // We do this rather than having a specific technique for it since it's simpler + GpuProgramManager& gmgr = GpuProgramManager::getSingleton(); + if (!gmgr.isSyntaxSupported("ps_4_0") && !gmgr.isSyntaxSupported("ps_3_0") && !gmgr.isSyntaxSupported("ps_2_x") + && !gmgr.isSyntaxSupported("fp40") && !gmgr.isSyntaxSupported("arbfp1") && !gmgr.isSyntaxSupported("glsl") && !gmgr.isSyntaxSupported("glsles")) - { - setLayerNormalMappingEnabled(false); - setLayerParallaxMappingEnabled(false); - } - - addTechnique(mat, terrain, HIGH_LOD); - - // LOD - if(mCompositeMapEnabled) - { - addTechnique(mat, terrain, LOW_LOD); - Material::LodValueList lodValues; - lodValues.push_back(TerrainGlobalOptions::getSingleton().getCompositeMapDistance()); - mat->setLodLevels(lodValues); - Technique* lowLodTechnique = mat->getTechnique(1); - lowLodTechnique->setLodIndex(1); - } - - updateParams(mat, terrain); - - return mat; - - } - //--------------------------------------------------------------------- - MaterialPtr TerrainMaterialGeneratorA::SM2Profile::generateForCompositeMap(const Terrain* terrain) - { - // re-use old material if exists - MaterialPtr mat = terrain->_getCompositeMapMaterial(); - if (mat.isNull()) - { - MaterialManager& matMgr = MaterialManager::getSingleton(); - - // it's important that the names are deterministic for a given terrain, so - // use the terrain pointer as an ID - const String& matName = terrain->getMaterialName() + "/comp"; - mat = matMgr.getByName(matName); - if (mat.isNull()) - { - mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - } - } - // clear everything - mat->removeAllTechniques(); - - addTechnique(mat, terrain, RENDER_COMPOSITE_MAP); - - updateParamsForCompositeMap(mat, terrain); - - return mat; - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::addTechnique( - const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt) - { - Technique* tech = mat->createTechnique(); - - // Only supporting one pass - Pass* pass = tech->createPass(); - - GpuProgramManager& gmgr = GpuProgramManager::getSingleton(); - HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton(); - if (!mShaderGen) - { - bool check2x = mLayerNormalMappingEnabled || mLayerParallaxMappingEnabled; - if (hmgr.isLanguageSupported("hlsl") && - ((check2x && gmgr.isSyntaxSupported("ps_4_0")) )) + { + setLayerNormalMappingEnabled(false); + setLayerParallaxMappingEnabled(false); + } + + addTechnique(mat, terrain, HIGH_LOD); + + // LOD + if(mCompositeMapEnabled) + { + addTechnique(mat, terrain, LOW_LOD); + Material::LodValueList lodValues; + lodValues.push_back(TerrainGlobalOptions::getSingleton().getCompositeMapDistance()); + mat->setLodLevels(lodValues); + Technique* lowLodTechnique = mat->getTechnique(1); + lowLodTechnique->setLodIndex(1); + } + + updateParams(mat, terrain); + + return mat; + + } + //--------------------------------------------------------------------- + MaterialPtr TerrainMaterialGeneratorA::SM2Profile::generateForCompositeMap(const Terrain* terrain) + { + // re-use old material if exists + MaterialPtr mat = terrain->_getCompositeMapMaterial(); + if (mat.isNull()) + { + MaterialManager& matMgr = MaterialManager::getSingleton(); + + // it's important that the names are deterministic for a given terrain, so + // use the terrain pointer as an ID + const String& matName = terrain->getMaterialName() + "/comp"; + mat = matMgr.getByName(matName); + if (mat.isNull()) + { + mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + } + } + // clear everything + mat->removeAllTechniques(); + + addTechnique(mat, terrain, RENDER_COMPOSITE_MAP); + + updateParamsForCompositeMap(mat, terrain); + + return mat; + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::addTechnique( + const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt) + { + Technique* tech = mat->createTechnique(); + + // Only supporting one pass + Pass* pass = tech->createPass(); + + GpuProgramManager& gmgr = GpuProgramManager::getSingleton(); + HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton(); + if (!mShaderGen) + { + bool check2x = mLayerNormalMappingEnabled || mLayerParallaxMappingEnabled; + if (hmgr.isLanguageSupported("hlsl") && + ((check2x && gmgr.isSyntaxSupported("ps_4_0")) )) { - mShaderGen = OGRE_NEW ShaderHelperHLSL(); + mShaderGen = OGRE_NEW ShaderHelperHLSL(); } - else if (hmgr.isLanguageSupported("glsl")) + else if (hmgr.isLanguageSupported("glsl")) { - mShaderGen = OGRE_NEW ShaderHelperGLSL(); + mShaderGen = OGRE_NEW ShaderHelperGLSL(); } - else if (hmgr.isLanguageSupported("glsles")) + else if (hmgr.isLanguageSupported("glsles")) { - mShaderGen = OGRE_NEW ShaderHelperGLSLES(); + mShaderGen = OGRE_NEW ShaderHelperGLSLES(); } - else if (hmgr.isLanguageSupported("cg")) + else if (hmgr.isLanguageSupported("cg")) { - mShaderGen = OGRE_NEW ShaderHelperCg(); + mShaderGen = OGRE_NEW ShaderHelperCg(); } - - // check SM3 features - mSM3Available = GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0"); - mSM4Available = GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0"); - } - - HighLevelGpuProgramPtr vprog = mShaderGen->generateVertexProgram(this, terrain, tt); - HighLevelGpuProgramPtr fprog = mShaderGen->generateFragmentProgram(this, terrain, tt); - - pass->setVertexProgram(vprog->getName()); - pass->setFragmentProgram(fprog->getName()); - - if (tt == HIGH_LOD || tt == RENDER_COMPOSITE_MAP) - { - // global normal map - TextureUnitState* tu = pass->createTextureUnitState(); - tu->setTextureName(terrain->getTerrainNormalMap()->getName()); - // Bugfix for D3D11 Render System - // tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); - - // global colour map - if (terrain->getGlobalColourMapEnabled() && isGlobalColourMapEnabled()) - { - tu = pass->createTextureUnitState(terrain->getGlobalColourMap()->getName()); - //tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); - } - - // light map - if (isLightmapEnabled()) - { - tu = pass->createTextureUnitState(terrain->getLightmap()->getName()); - //tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); - } - - // blend maps - uint maxLayers = getMaxLayers(terrain); - uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount()); - uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); - for (uint i = 0; i < numBlendTextures; ++i) - { - tu = pass->createTextureUnitState(terrain->getBlendTextureName(i)); - //tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); - } - - // layer textures - for (uint i = 0; i < numLayers; ++i) - { - // diffuse / specular - pass->createTextureUnitState(terrain->getLayerTextureName(i, 0)); - // normal / height - pass->createTextureUnitState(terrain->getLayerTextureName(i, 1)); - } - - } - else - { - // LOW_LOD textures - // composite map - TextureUnitState* tu = pass->createTextureUnitState(); - tu->setTextureName(terrain->getCompositeMap()->getName()); - tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); - - // That's it! - - } - - // Add shadow textures (always at the end) - if (isShadowingEnabled(tt, terrain)) - { - uint numTextures = 1; - if (getReceiveDynamicShadowsPSSM()) - { - numTextures = (uint)getReceiveDynamicShadowsPSSM()->getSplitCount(); - } - for (uint i = 0; i < numTextures; ++i) - { - TextureUnitState* tu = pass->createTextureUnitState(); - tu->setContentType(TextureUnitState::CONTENT_SHADOW); - tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER); - tu->setTextureBorderColour(ColourValue::White); - } - } - - } - //--------------------------------------------------------------------- - bool TerrainMaterialGeneratorA::SM2Profile::isShadowingEnabled(TechniqueType tt, const Terrain* terrain) const - { - return getReceiveDynamicShadowsEnabled() && tt != RENDER_COMPOSITE_MAP && - (tt != LOW_LOD || mLowLodShadows) && - terrain->getSceneManager()->isShadowTechniqueTextureBased(); - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::updateParams(const MaterialPtr& mat, const Terrain* terrain) - { - mShaderGen->updateParams(this, mat, terrain, false); - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain) - { - mShaderGen->updateParams(this, mat, terrain, true); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - HighLevelGpuProgramPtr - TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::generateVertexProgram( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) - { - HighLevelGpuProgramPtr ret = createVertexProgram(prof, terrain, tt); - - StringStream sourceStr; - generateVertexProgramSource(prof, terrain, tt, sourceStr); - - ret->setSource(sourceStr.str()); - ret->load(); - defaultVpParams(prof, terrain, tt, ret); + + // check SM3 features + mSM3Available = GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0"); + mSM4Available = GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0"); + } + + HighLevelGpuProgramPtr vprog = mShaderGen->generateVertexProgram(this, terrain, tt); + HighLevelGpuProgramPtr fprog = mShaderGen->generateFragmentProgram(this, terrain, tt); + + pass->setVertexProgram(vprog->getName()); + pass->setFragmentProgram(fprog->getName()); + + if (tt == HIGH_LOD || tt == RENDER_COMPOSITE_MAP) + { + // global normal map + TextureUnitState* tu = pass->createTextureUnitState(); + tu->setTextureName(terrain->getTerrainNormalMap()->getName()); + // Bugfix for D3D11 Render System + // tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); + + // global colour map + if (terrain->getGlobalColourMapEnabled() && isGlobalColourMapEnabled()) + { + tu = pass->createTextureUnitState(terrain->getGlobalColourMap()->getName()); + //tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); + } + + // light map + if (isLightmapEnabled()) + { + tu = pass->createTextureUnitState(terrain->getLightmap()->getName()); + //tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); + } + + // blend maps + uint maxLayers = getMaxLayers(terrain); + uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount()); + uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); + for (uint i = 0; i < numBlendTextures; ++i) + { + tu = pass->createTextureUnitState(terrain->getBlendTextureName(i)); + //tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); + } + + // layer textures + for (uint i = 0; i < numLayers; ++i) + { + // diffuse / specular + pass->createTextureUnitState(terrain->getLayerTextureName(i, 0)); + // normal / height + pass->createTextureUnitState(terrain->getLayerTextureName(i, 1)); + } + + } + else + { + // LOW_LOD textures + // composite map + TextureUnitState* tu = pass->createTextureUnitState(); + tu->setTextureName(terrain->getCompositeMap()->getName()); + tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); + + // That's it! + + } + + // Add shadow textures (always at the end) + if (isShadowingEnabled(tt, terrain)) + { + uint numTextures = 1; + if (getReceiveDynamicShadowsPSSM()) + { + numTextures = (uint)getReceiveDynamicShadowsPSSM()->getSplitCount(); + } + for (uint i = 0; i < numTextures; ++i) + { + TextureUnitState* tu = pass->createTextureUnitState(); + tu->setContentType(TextureUnitState::CONTENT_SHADOW); + tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER); + tu->setTextureBorderColour(ColourValue::White); + } + } + + } + //--------------------------------------------------------------------- + bool TerrainMaterialGeneratorA::SM2Profile::isShadowingEnabled(TechniqueType tt, const Terrain* terrain) const + { + return getReceiveDynamicShadowsEnabled() && tt != RENDER_COMPOSITE_MAP && + (tt != LOW_LOD || mLowLodShadows) && + terrain->getSceneManager()->isShadowTechniqueTextureBased(); + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::updateParams(const MaterialPtr& mat, const Terrain* terrain) + { + mShaderGen->updateParams(this, mat, terrain, false); + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::updateParamsForCompositeMap(const MaterialPtr& mat, const Terrain* terrain) + { + mShaderGen->updateParams(this, mat, terrain, true); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + HighLevelGpuProgramPtr + TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::generateVertexProgram( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) + { + HighLevelGpuProgramPtr ret = createVertexProgram(prof, terrain, tt); + + StringStream sourceStr; + generateVertexProgramSource(prof, terrain, tt, sourceStr); + + ret->setSource(sourceStr.str()); + ret->load(); + defaultVpParams(prof, terrain, tt, ret); #if OGRE_DEBUG_MODE - LogManager::getSingleton().stream(LML_TRIVIAL) << "*** Terrain Vertex Program: " - << ret->getName() << " ***\n" << ret->getSource() << "\n*** ***"; + LogManager::getSingleton().stream(LML_TRIVIAL) << "*** Terrain Vertex Program: " + << ret->getName() << " ***\n" << ret->getSource() << "\n*** ***"; #endif - return ret; - - } - //--------------------------------------------------------------------- - HighLevelGpuProgramPtr - TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::generateFragmentProgram( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) - { - HighLevelGpuProgramPtr ret = createFragmentProgram(prof, terrain, tt); - - StringStream sourceStr; - generateFragmentProgramSource(prof, terrain, tt, sourceStr); - ret->setSource(sourceStr.str()); - ret->load(); - defaultFpParams(prof, terrain, tt, ret); + return ret; + + } + //--------------------------------------------------------------------- + HighLevelGpuProgramPtr + TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::generateFragmentProgram( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) + { + HighLevelGpuProgramPtr ret = createFragmentProgram(prof, terrain, tt); + + StringStream sourceStr; + generateFragmentProgramSource(prof, terrain, tt, sourceStr); + ret->setSource(sourceStr.str()); + ret->load(); + defaultFpParams(prof, terrain, tt, ret); #if OGRE_DEBUG_MODE - LogManager::getSingleton().stream(LML_TRIVIAL) << "*** Terrain Fragment Program: " - << ret->getName() << " ***\n" << ret->getSource() << "\n*** ***"; + LogManager::getSingleton().stream(LML_TRIVIAL) << "*** Terrain Fragment Program: " + << ret->getName() << " ***\n" << ret->getSource() << "\n*** ***"; #endif - return ret; - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::generateVertexProgramSource( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - generateVpHeader(prof, terrain, tt, outStream); - - if (tt != LOW_LOD) - { - uint maxLayers = prof->getMaxLayers(terrain); - uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); - - for (uint i = 0; i < numLayers; ++i) - generateVpLayer(prof, terrain, tt, i, outStream); - } - - generateVpFooter(prof, terrain, tt, outStream); - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::generateFragmentProgramSource( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - generateFpHeader(prof, terrain, tt, outStream); - - if (tt != LOW_LOD) - { - uint maxLayers = prof->getMaxLayers(terrain); - uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); - - for (uint i = 0; i < numLayers; ++i) - generateFpLayer(prof, terrain, tt, i, outStream); - } - - generateFpFooter(prof, terrain, tt, outStream); - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::defaultVpParams( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog) - { - GpuProgramParametersSharedPtr params = prog->getDefaultParameters(); - params->setIgnoreMissingParams(true); - params->setNamedAutoConstant("worldMatrix", GpuProgramParameters::ACT_WORLD_MATRIX); - params->setNamedAutoConstant("viewProjMatrix", GpuProgramParameters::ACT_VIEWPROJ_MATRIX); - params->setNamedAutoConstant("lodMorph", GpuProgramParameters::ACT_CUSTOM, - Terrain::LOD_MORPH_CUSTOM_PARAM); - params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); - - if (prof->isShadowingEnabled(tt, terrain)) - { - uint numTextures = 1; - if (prof->getReceiveDynamicShadowsPSSM()) - { - numTextures = (uint)prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - } - for (uint i = 0; i < numTextures; ++i) - { - params->setNamedAutoConstant("texViewProjMatrix" + StringConverter::toString(i), - GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, i); - if (prof->getReceiveDynamicShadowsDepth()) - { - params->setNamedAutoConstant("depthRange" + StringConverter::toString(i), - GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE, i); - } - } - } - - if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP) - { - Matrix4 posIndexToObjectSpace; - terrain->getPointTransform(&posIndexToObjectSpace); - params->setNamedConstant("posIndexToObjectSpace", posIndexToObjectSpace); - } - - - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::defaultFpParams( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog) - { - GpuProgramParametersSharedPtr params = prog->getDefaultParameters(); - params->setIgnoreMissingParams(true); - - params->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR); - params->setNamedAutoConstant("lightPosObjSpace", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, 0); - params->setNamedAutoConstant("lightDiffuseColour", GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, 0); - params->setNamedAutoConstant("lightSpecularColour", GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, 0); - params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE); - params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); - - if (prof->isShadowingEnabled(tt, terrain)) - { - uint numTextures = 1; - if (prof->getReceiveDynamicShadowsPSSM()) - { - PSSMShadowCameraSetup* pssm = prof->getReceiveDynamicShadowsPSSM(); - numTextures = (uint)pssm->getSplitCount(); - Vector4 splitPoints; - const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssm->getSplitPoints(); - // Populate from split point 1, not 0, since split 0 isn't useful (usually 0) - for (uint i = 1; i < numTextures; ++i) - { - splitPoints[i-1] = splitPointList[i]; - } - params->setNamedConstant("pssmSplitPoints", splitPoints); - } - - if (prof->getReceiveDynamicShadowsDepth()) - { - size_t samplerOffset = (tt == HIGH_LOD) ? mShadowSamplerStartHi : mShadowSamplerStartLo; - for (uint i = 0; i < numTextures; ++i) - { - params->setNamedAutoConstant("inverseShadowmapSize" + StringConverter::toString(i), - GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i + samplerOffset); - } - } - } + return ret; + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::generateVertexProgramSource( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + generateVpHeader(prof, terrain, tt, outStream); + + if (tt != LOW_LOD) + { + uint maxLayers = prof->getMaxLayers(terrain); + uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); + + for (uint i = 0; i < numLayers; ++i) + generateVpLayer(prof, terrain, tt, i, outStream); + } + + generateVpFooter(prof, terrain, tt, outStream); + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::generateFragmentProgramSource( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + generateFpHeader(prof, terrain, tt, outStream); + + if (tt != LOW_LOD) + { + uint maxLayers = prof->getMaxLayers(terrain); + uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); + + for (uint i = 0; i < numLayers; ++i) + generateFpLayer(prof, terrain, tt, i, outStream); + } + + generateFpFooter(prof, terrain, tt, outStream); + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::defaultVpParams( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog) + { + GpuProgramParametersSharedPtr params = prog->getDefaultParameters(); + params->setIgnoreMissingParams(true); + params->setNamedAutoConstant("worldMatrix", GpuProgramParameters::ACT_WORLD_MATRIX); + params->setNamedAutoConstant("viewProjMatrix", GpuProgramParameters::ACT_VIEWPROJ_MATRIX); + params->setNamedAutoConstant("lodMorph", GpuProgramParameters::ACT_CUSTOM, + Terrain::LOD_MORPH_CUSTOM_PARAM); + params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS); + + if (prof->isShadowingEnabled(tt, terrain)) + { + uint numTextures = 1; + if (prof->getReceiveDynamicShadowsPSSM()) + { + numTextures = (uint)prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + } + for (uint i = 0; i < numTextures; ++i) + { + params->setNamedAutoConstant("texViewProjMatrix" + StringConverter::toString(i), + GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX, i); + if (prof->getReceiveDynamicShadowsDepth()) + { + params->setNamedAutoConstant("depthRange" + StringConverter::toString(i), + GpuProgramParameters::ACT_SHADOW_SCENE_DEPTH_RANGE, i); + } + } + } + + if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP) + { + Matrix4 posIndexToObjectSpace; + terrain->getPointTransform(&posIndexToObjectSpace); + params->setNamedConstant("posIndexToObjectSpace", posIndexToObjectSpace); + } + + + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::defaultFpParams( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog) + { + GpuProgramParametersSharedPtr params = prog->getDefaultParameters(); + params->setIgnoreMissingParams(true); + + params->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR); + params->setNamedAutoConstant("lightPosObjSpace", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, 0); + params->setNamedAutoConstant("lightDiffuseColour", GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, 0); + params->setNamedAutoConstant("lightSpecularColour", GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, 0); + params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE); + params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR); + + if (prof->isShadowingEnabled(tt, terrain)) + { + uint numTextures = 1; + if (prof->getReceiveDynamicShadowsPSSM()) + { + PSSMShadowCameraSetup* pssm = prof->getReceiveDynamicShadowsPSSM(); + numTextures = (uint)pssm->getSplitCount(); + Vector4 splitPoints; + const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssm->getSplitPoints(); + // Populate from split point 1, not 0, since split 0 isn't useful (usually 0) + for (uint i = 1; i < numTextures; ++i) + { + splitPoints[i-1] = splitPointList[i]; + } + params->setNamedConstant("pssmSplitPoints", splitPoints); + } + + if (prof->getReceiveDynamicShadowsDepth()) + { + size_t samplerOffset = (tt == HIGH_LOD) ? mShadowSamplerStartHi : mShadowSamplerStartLo; + for (uint i = 0; i < numTextures; ++i) + { + params->setNamedAutoConstant("inverseShadowmapSize" + StringConverter::toString(i), + GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i + samplerOffset); + } + } + } // Explicitly bind samplers for GLSL if ((prof->_getShaderLanguage() == "glsl") || (prof->_getShaderLanguage() == "glsles")) @@ -670,129 +670,129 @@ namespace Ogre } } } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::updateParams( - const SM2Profile* prof, const MaterialPtr& mat, const Terrain* terrain, bool compositeMap) - { - Pass* p = mat->getTechnique(0)->getPass(0); - if (compositeMap) - { - updateVpParams(prof, terrain, RENDER_COMPOSITE_MAP, p->getVertexProgramParameters()); - updateFpParams(prof, terrain, RENDER_COMPOSITE_MAP, p->getFragmentProgramParameters()); - } - else - { - // high lod - updateVpParams(prof, terrain, HIGH_LOD, p->getVertexProgramParameters()); - updateFpParams(prof, terrain, HIGH_LOD, p->getFragmentProgramParameters()); - - if(prof->isCompositeMapEnabled()) - { - // low lod - p = mat->getTechnique(1)->getPass(0); - updateVpParams(prof, terrain, LOW_LOD, p->getVertexProgramParameters()); - updateFpParams(prof, terrain, LOW_LOD, p->getFragmentProgramParameters()); - } - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::updateVpParams( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params) - { - params->setIgnoreMissingParams(true); - uint maxLayers = prof->getMaxLayers(terrain); - uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); - uint numUVMul = numLayers / 4; - if (numLayers % 4) - ++numUVMul; - for (uint i = 0; i < numUVMul; ++i) - { - Vector4 uvMul( - terrain->getLayerUVMultiplier(i * 4), - terrain->getLayerUVMultiplier(i * 4 + 1), - terrain->getLayerUVMultiplier(i * 4 + 2), - terrain->getLayerUVMultiplier(i * 4 + 3) - ); - params->setNamedConstant("uvMul_" + StringConverter::toString(i), uvMul); - } - - if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP) - { - Real baseUVScale = 1.0f / (terrain->getSize() - 1); - params->setNamedConstant("baseUVScale", baseUVScale); - } - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::updateFpParams( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params) - { - params->setIgnoreMissingParams(true); - // TODO - parameterise this? - Vector4 scaleBiasSpecular(0.03, -0.04, 32, 1); - params->setNamedConstant("scaleBiasSpecular", scaleBiasSpecular); - - } - //--------------------------------------------------------------------- - String TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::getChannel(uint idx) - { - uint rem = idx % 4; - switch(rem) - { - case 0: - default: - return "r"; - case 1: - return "g"; - case 2: - return "b"; - case 3: - return "a"; - }; - } - //--------------------------------------------------------------------- - String TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::getVertexProgramName( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) - { - String progName = terrain->getMaterialName() + "/sm2/vp"; - - switch(tt) - { - case HIGH_LOD: - progName += "/hlod"; - break; - case LOW_LOD: - progName += "/llod"; - break; - case RENDER_COMPOSITE_MAP: - progName += "/comp"; - break; - } - - return progName; - - } - //--------------------------------------------------------------------- - String TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::getFragmentProgramName( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) - { - - String progName = terrain->getMaterialName() + "/sm2/fp"; - - switch(tt) - { - case HIGH_LOD: - progName += "/hlod"; - break; - case LOW_LOD: - progName += "/llod"; - break; - case RENDER_COMPOSITE_MAP: - progName += "/comp"; - break; - } - - return progName; - } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::updateParams( + const SM2Profile* prof, const MaterialPtr& mat, const Terrain* terrain, bool compositeMap) + { + Pass* p = mat->getTechnique(0)->getPass(0); + if (compositeMap) + { + updateVpParams(prof, terrain, RENDER_COMPOSITE_MAP, p->getVertexProgramParameters()); + updateFpParams(prof, terrain, RENDER_COMPOSITE_MAP, p->getFragmentProgramParameters()); + } + else + { + // high lod + updateVpParams(prof, terrain, HIGH_LOD, p->getVertexProgramParameters()); + updateFpParams(prof, terrain, HIGH_LOD, p->getFragmentProgramParameters()); + + if(prof->isCompositeMapEnabled()) + { + // low lod + p = mat->getTechnique(1)->getPass(0); + updateVpParams(prof, terrain, LOW_LOD, p->getVertexProgramParameters()); + updateFpParams(prof, terrain, LOW_LOD, p->getFragmentProgramParameters()); + } + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::updateVpParams( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params) + { + params->setIgnoreMissingParams(true); + uint maxLayers = prof->getMaxLayers(terrain); + uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); + uint numUVMul = numLayers / 4; + if (numLayers % 4) + ++numUVMul; + for (uint i = 0; i < numUVMul; ++i) + { + Vector4 uvMul( + terrain->getLayerUVMultiplier(i * 4), + terrain->getLayerUVMultiplier(i * 4 + 1), + terrain->getLayerUVMultiplier(i * 4 + 2), + terrain->getLayerUVMultiplier(i * 4 + 3) + ); + params->setNamedConstant("uvMul_" + StringConverter::toString(i), uvMul); + } + + if (terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP) + { + Real baseUVScale = 1.0f / (terrain->getSize() - 1); + params->setNamedConstant("baseUVScale", baseUVScale); + } + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::updateFpParams( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const GpuProgramParametersSharedPtr& params) + { + params->setIgnoreMissingParams(true); + // TODO - parameterise this? + Vector4 scaleBiasSpecular(0.03, -0.04, 32, 1); + params->setNamedConstant("scaleBiasSpecular", scaleBiasSpecular); + + } + //--------------------------------------------------------------------- + String TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::getChannel(uint idx) + { + uint rem = idx % 4; + switch(rem) + { + case 0: + default: + return "r"; + case 1: + return "g"; + case 2: + return "b"; + case 3: + return "a"; + }; + } + //--------------------------------------------------------------------- + String TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::getVertexProgramName( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) + { + String progName = terrain->getMaterialName() + "/sm2/vp"; + + switch(tt) + { + case HIGH_LOD: + progName += "/hlod"; + break; + case LOW_LOD: + progName += "/llod"; + break; + case RENDER_COMPOSITE_MAP: + progName += "/comp"; + break; + } + + return progName; + + } + //--------------------------------------------------------------------- + String TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::getFragmentProgramName( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) + { + + String progName = terrain->getMaterialName() + "/sm2/fp"; + + switch(tt) + { + case HIGH_LOD: + progName += "/hlod"; + break; + case LOW_LOD: + progName += "/llod"; + break; + case RENDER_COMPOSITE_MAP: + progName += "/comp"; + break; + } + + return progName; + } } diff --git a/Components/Terrain/src/OgreTerrainMaterialShaderHelperCg.cpp b/Components/Terrain/src/OgreTerrainMaterialShaderHelperCg.cpp index 02a3f4ae93e..1c834a7dc96 100644 --- a/Components/Terrain/src/OgreTerrainMaterialShaderHelperCg.cpp +++ b/Components/Terrain/src/OgreTerrainMaterialShaderHelperCg.cpp @@ -33,873 +33,873 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - HighLevelGpuProgramPtr - TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::createVertexProgram( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) - { - HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); - String progName = getVertexProgramName(prof, terrain, tt); - HighLevelGpuProgramPtr ret = mgr.getByName(progName).staticCast(); - if (ret.isNull()) - { - ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - "cg", GPT_VERTEX_PROGRAM).staticCast(); - } - else - { - ret->unload(); - } - - ret->setParameter("profiles", "vs_4_0 vs_3_0 vs_2_0 arbvp1"); - ret->setParameter("entry_point", "main_vp"); - - return ret; - - } - //--------------------------------------------------------------------- - HighLevelGpuProgramPtr - TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::createFragmentProgram( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) - { - HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); - String progName = getFragmentProgramName(prof, terrain, tt); - - HighLevelGpuProgramPtr ret = mgr.getByName(progName).staticCast(); - if (ret.isNull()) - { - ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - "cg", GPT_FRAGMENT_PROGRAM).staticCast(); - } - else - { - ret->unload(); - } - - if(prof->isLayerNormalMappingEnabled() || prof->isLayerParallaxMappingEnabled()) - ret->setParameter("profiles", "ps_4_0 ps_3_0 ps_2_x fp40 arbfp1"); - else - ret->setParameter("profiles", "ps_4_0 ps_3_0 ps_2_0 fp30 arbfp1"); - ret->setParameter("entry_point", "main_fp"); - - return ret; - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateVpHeader( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - outStream << - "void main_vp(\n"; - bool compression = terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP; - if (compression) - { - outStream << - "float2 posIndex : POSITION,\n" - "float height : TEXCOORD0,\n"; - } - else - { - outStream << - "float4 pos : POSITION,\n" - "float2 uv : TEXCOORD0,\n"; - - } - if (tt != RENDER_COMPOSITE_MAP) - outStream << "float2 delta : TEXCOORD1,\n"; // lodDelta, lodThreshold - - outStream << - "uniform float4x4 worldMatrix,\n" - "uniform float4x4 viewProjMatrix,\n" - "uniform float2 lodMorph,\n"; // morph amount, morph LOD target - - if (compression) - { - outStream << - "uniform float4x4 posIndexToObjectSpace,\n" - "uniform float baseUVScale,\n"; - } - // uv multipliers - uint maxLayers = prof->getMaxLayers(terrain); - uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); - uint numUVMultipliers = (numLayers / 4); - if (numLayers % 4) - ++numUVMultipliers; - for (uint i = 0; i < numUVMultipliers; ++i) - outStream << "uniform float4 uvMul_" << i << ", \n"; - - outStream << - "out float4 oPos : POSITION,\n" - "out float4 oPosObj : TEXCOORD0 \n"; - - uint texCoordSet = 1; - outStream << - ", out float4 oUVMisc : TEXCOORD" << texCoordSet++ <<" // xy = uv, z = camDepth\n"; - - // layer UV's premultiplied, packed as xy/zw - uint numUVSets = numLayers / 2; - if (numLayers % 2) - ++numUVSets; - if (tt != LOW_LOD) - { - for (uint i = 0; i < numUVSets; ++i) - { - outStream << - ", out float4 oUV" << i << " : TEXCOORD" << texCoordSet++ << "\n"; - } - } - - if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP) - { - outStream << ", out float2 lodInfo : TEXCOORD" << texCoordSet++ << "\n"; - } - - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - outStream << - ", uniform float4 fogParams\n" - ", out float fogVal : COLOR\n"; - } - - if (prof->isShadowingEnabled(tt, terrain)) - { - texCoordSet = generateVpDynamicShadowsParams(texCoordSet, prof, terrain, tt, outStream); - } - - // check we haven't exceeded texture coordinates - if (texCoordSet > 8) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Requested options require too many texture coordinate sets! Try reducing the number of layers.", - __FUNCTION__); - } - - outStream << - ")\n" - "{\n"; - if (compression) - { - outStream << - " float4 pos;\n" - " pos = mul(posIndexToObjectSpace, float4(posIndex, height, 1));\n" - " float2 uv = float2(posIndex.x * baseUVScale, 1.0 - (posIndex.y * baseUVScale));\n"; - } - outStream << - " float4 worldPos = mul(worldMatrix, pos);\n" - " oPosObj = pos;\n"; - - if (tt != RENDER_COMPOSITE_MAP) - { - // determine whether to apply the LOD morph to this vertex - // we store the deltas against all vertices so we only want to apply - // the morph to the ones which would disappear. The target LOD which is - // being morphed to is stored in lodMorph.y, and the LOD at which - // the vertex should be morphed is stored in uv.w. If we subtract - // the former from the latter, and arrange to only morph if the - // result is negative (it will only be -1 in fact, since after that - // the vertex will never be indexed), we will achieve our aim. - // sign(vertexLOD - targetLOD) == -1 is to morph - outStream << - " float toMorph = -min(0, sign(delta.y - lodMorph.y));\n"; - // this will either be 1 (morph) or 0 (don't morph) - if (prof->getParent()->getDebugLevel()) - { - // x == LOD level (-1 since value is target level, we want to display actual) - outStream << "lodInfo.x = (lodMorph.y - 1) / " << terrain->getNumLodLevels() << ";\n"; - // y == LOD morph - outStream << "lodInfo.y = toMorph * lodMorph.x;\n"; - } - - // morph - switch (terrain->getAlignment()) - { - case Terrain::ALIGN_X_Y: - outStream << " worldPos.z += delta.x * toMorph * lodMorph.x;\n"; - break; - case Terrain::ALIGN_X_Z: - outStream << " worldPos.y += delta.x * toMorph * lodMorph.x;\n"; - break; - case Terrain::ALIGN_Y_Z: - outStream << " worldPos.x += delta.x * toMorph * lodMorph.x;\n"; - break; - }; - } - - - // generate UVs - if (tt != LOW_LOD) - { - for (uint i = 0; i < numUVSets; ++i) - { - uint layer = i * 2; - uint uvMulIdx = layer / 4; - - outStream << - " oUV" << i << ".xy = " << " uv.xy * uvMul_" << uvMulIdx << "." << getChannel(layer) << ";\n"; - outStream << - " oUV" << i << ".zw = " << " uv.xy * uvMul_" << uvMulIdx << "." << getChannel(layer+1) << ";\n"; - - } - - } - - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpHeader( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - - // Main header - outStream << - // helpers - "float4 expand(float4 v)\n" - "{ \n" - " return v * 2 - 1;\n" - "}\n\n\n"; - - if (prof->isShadowingEnabled(tt, terrain)) - generateFpDynamicShadowsHelpers(prof, terrain, tt, outStream); - - - outStream << - "float4 main_fp(\n" - "float4 vertexPos : POSITION,\n" - "float4 position : TEXCOORD0,\n"; - - uint texCoordSet = 1; - outStream << - "float4 uvMisc : TEXCOORD" << texCoordSet++ << ",\n"; - - // UV's premultiplied, packed as xy/zw - uint maxLayers = prof->getMaxLayers(terrain); - uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount()); - uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); - uint numUVSets = numLayers / 2; - if (numLayers % 2) - ++numUVSets; - if (tt != LOW_LOD) - { - for (uint i = 0; i < numUVSets; ++i) - { - outStream << - "float4 layerUV" << i << " : TEXCOORD" << texCoordSet++ << ", \n"; - } - - } - if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP) - { - outStream << "float2 lodInfo : TEXCOORD" << texCoordSet++ << ", \n"; - } - - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - outStream << - "uniform float3 fogColour, \n" - "float fogVal : COLOR,\n"; - } - - uint currentSamplerIdx = 0; - - outStream << - // Only 1 light supported in this version - // deferred shading profile / generator later, ok? :) - "uniform float3 ambient,\n" - "uniform float4 lightPosObjSpace,\n" - "uniform float3 lightDiffuseColour,\n" - "uniform float3 lightSpecularColour,\n" - "uniform float3 eyePosObjSpace,\n" - // pack scale, bias and specular - "uniform float4 scaleBiasSpecular,\n"; - - if (tt == LOW_LOD) - { - // single composite map covers all the others below - outStream << - "uniform sampler2D compositeMap : register(s" << currentSamplerIdx++ << ")\n"; - } - else - { - outStream << - "uniform sampler2D globalNormal : register(s" << currentSamplerIdx++ << ")\n"; - - - if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) - { - outStream << ", uniform sampler2D globalColourMap : register(s" - << currentSamplerIdx++ << ")\n"; - } - if (prof->isLightmapEnabled()) - { - outStream << ", uniform sampler2D lightMap : register(s" - << currentSamplerIdx++ << ")\n"; - } - // Blend textures - sampler definitions - for (uint i = 0; i < numBlendTextures; ++i) - { - outStream << ", uniform sampler2D blendTex" << i - << " : register(s" << currentSamplerIdx++ << ")\n"; - } - - // Layer textures - sampler definitions & UV multipliers - for (uint i = 0; i < numLayers; ++i) - { - outStream << ", uniform sampler2D difftex" << i - << " : register(s" << currentSamplerIdx++ << ")\n"; - outStream << ", uniform sampler2D normtex" << i - << " : register(s" << currentSamplerIdx++ << ")\n"; - } - } - - if (prof->isShadowingEnabled(tt, terrain)) - { - generateFpDynamicShadowsParams(&texCoordSet, ¤tSamplerIdx, prof, terrain, tt, outStream); - } - - // check we haven't exceeded samplers - if (currentSamplerIdx > 16) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Requested options require too many texture samplers! Try reducing the number of layers.", - __FUNCTION__); - } - - outStream << - ") : COLOR\n" - "{\n" - " float4 outputCol;\n" - " float shadow = 1.0;\n" - " float2 uv = uvMisc.xy;\n" - // base colour - " outputCol = float4(0,0,0,1);\n"; - - if (tt != LOW_LOD) - { - outStream << - // global normal - " float3 normal = expand(tex2D(globalNormal, uv)).rgb;\n"; - - } - - outStream << - " float3 lightDir = \n" - " lightPosObjSpace.xyz - (position.xyz * lightPosObjSpace.w);\n" - " float3 eyeDir = eyePosObjSpace - position.xyz;\n" - - // set up accumulation areas - " float3 diffuse = float3(0,0,0);\n" - " float specular = 0;\n"; - - - if (tt == LOW_LOD) - { - // we just do a single calculation from composite map - outStream << - " float4 composite = tex2D(compositeMap, uv);\n" - " diffuse = composite.rgb;\n"; - // TODO - specular; we'll need normals for this! - } - else - { - // set up the blend values - for (uint i = 0; i < numBlendTextures; ++i) - { - outStream << " float4 blendTexVal" << i << " = tex2D(blendTex" << i << ", uv);\n"; - } - - if (prof->isLayerNormalMappingEnabled()) - { - // derive the tangent space basis - // we do this in the pixel shader because we don't have per-vertex normals - // because of the LOD, we use a normal map - // tangent is always +x or -z in object space depending on alignment - switch(terrain->getAlignment()) - { - case Terrain::ALIGN_X_Y: - case Terrain::ALIGN_X_Z: - outStream << " float3 tangent = float3(1, 0, 0);\n"; - break; - case Terrain::ALIGN_Y_Z: - outStream << " float3 tangent = float3(0, 0, -1);\n"; - break; - }; - - outStream << " float3 binormal = normalize(cross(tangent, normal));\n"; - // note, now we need to re-cross to derive tangent again because it wasn't orthonormal - outStream << " tangent = normalize(cross(normal, binormal));\n"; - // derive final matrix - outStream << " float3x3 TBN = float3x3(tangent, binormal, normal);\n"; - - // set up lighting result placeholders for interpolation - outStream << " float4 litRes, litResLayer;\n"; - outStream << " float3 TSlightDir, TSeyeDir, TShalfAngle, TSnormal;\n"; - if (prof->isLayerParallaxMappingEnabled()) - outStream << " float displacement;\n"; - // move - outStream << " TSlightDir = normalize(mul(TBN, lightDir));\n"; - outStream << " TSeyeDir = normalize(mul(TBN, eyeDir));\n"; - - } - else - { - // simple per-pixel lighting with no normal mapping - outStream << " lightDir = normalize(lightDir);\n"; - outStream << " eyeDir = normalize(eyeDir);\n"; - outStream << " float3 halfAngle = normalize(lightDir + eyeDir);\n"; - outStream << " float4 litRes = lit(dot(lightDir, normal), dot(halfAngle, normal), scaleBiasSpecular.z);\n"; - - } - } - - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateVpLayer( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) - { - // nothing to do - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpLayer( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) - { - uint uvIdx = layer / 2; - String uvChannels = (layer % 2) ? ".zw" : ".xy"; - uint blendIdx = (layer-1) / 4; - String blendChannel = getChannel(layer-1); - String blendWeightStr = String("blendTexVal") + StringConverter::toString(blendIdx) + - "." + blendChannel; - - // generate early-out conditional - /* Disable - causing some issues even when trying to force the use of texldd - if (layer && prof->_isSM3Available()) - outStream << " if (" << blendWeightStr << " > 0.0003)\n { \n"; - */ - - // generate UV - outStream << " float2 uv" << layer << " = layerUV" << uvIdx << uvChannels << ";\n"; - - // calculate lighting here if normal mapping - if (prof->isLayerNormalMappingEnabled()) - { - if (prof->isLayerParallaxMappingEnabled() && tt != RENDER_COMPOSITE_MAP) - { - // modify UV - note we have to sample an extra time - outStream << " displacement = tex2D(normtex" << layer << ", uv" << layer << ").a\n" - " * scaleBiasSpecular.x + scaleBiasSpecular.y;\n"; - outStream << " uv" << layer << " += TSeyeDir.xy * displacement;\n"; - } - - // access TS normal map - outStream << " TSnormal = expand(tex2D(normtex" << layer << ", uv" << layer << ")).rgb;\n"; - outStream << " TShalfAngle = normalize(TSlightDir + TSeyeDir);\n"; - outStream << " litResLayer = lit(dot(TSlightDir, TSnormal), dot(TShalfAngle, TSnormal), scaleBiasSpecular.z);\n"; - if (!layer) - outStream << " litRes = litResLayer;\n"; - else - outStream << " litRes = lerp(litRes, litResLayer, " << blendWeightStr << ");\n"; - - } - - // sample diffuse texture - outStream << " float4 diffuseSpecTex" << layer - << " = tex2D(difftex" << layer << ", uv" << layer << ");\n"; - - // apply to common - if (!layer) - { - outStream << " diffuse = diffuseSpecTex0.rgb;\n"; - if (prof->isLayerSpecularMappingEnabled()) - outStream << " specular = diffuseSpecTex0.a;\n"; - } - else - { - outStream << " diffuse = lerp(diffuse, diffuseSpecTex" << layer - << ".rgb, " << blendWeightStr << ");\n"; - if (prof->isLayerSpecularMappingEnabled()) - outStream << " specular = lerp(specular, diffuseSpecTex" << layer - << ".a, " << blendWeightStr << ");\n"; - - } - - // End early-out - /* Disable - causing some issues even when trying to force the use of texldd - if (layer && prof->_isSM3Available()) - outStream << " } // early-out blend value\n"; - */ - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateVpFooter( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - - outStream << - " oPos = mul(viewProjMatrix, worldPos);\n" - " oUVMisc.xy = uv.xy;\n"; - - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) - { - outStream << - " fogVal = saturate((oPos.z - fogParams.y) * fogParams.w);\n"; - } - else - { - outStream << - " fogVal = 1 - saturate(1 / (exp(oPos.z * fogParams.x)));\n"; - } - } - - if (prof->isShadowingEnabled(tt, terrain)) - generateVpDynamicShadows(prof, terrain, tt, outStream); - - outStream << - "}\n"; - - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpFooter( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - - if (tt == LOW_LOD) - { - if (prof->isShadowingEnabled(tt, terrain)) - { - generateFpDynamicShadows(prof, terrain, tt, outStream); - outStream << - " outputCol.rgb = diffuse * rtshadow;\n"; - } - else - { - outStream << - " outputCol.rgb = diffuse;\n"; - } - } - else - { - if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) - { - // sample colour map and apply to diffuse - outStream << " diffuse *= tex2D(globalColourMap, uv).rgb;\n"; - } - if (prof->isLightmapEnabled()) - { - // sample lightmap - outStream << " shadow = tex2D(lightMap, uv).r;\n"; - } - - if (prof->isShadowingEnabled(tt, terrain)) - { - generateFpDynamicShadows(prof, terrain, tt, outStream); - } - - // diffuse lighting - outStream << " outputCol.rgb += ambient.rgb * diffuse + litRes.y * lightDiffuseColour * diffuse * shadow;\n"; - - // specular default - if (!prof->isLayerSpecularMappingEnabled()) - outStream << " specular = 1.0;\n"; - - if (tt == RENDER_COMPOSITE_MAP) - { - // Lighting embedded in alpha - outStream << - " outputCol.a = shadow;\n"; - - } - else - { - // Apply specular - outStream << " outputCol.rgb += litRes.z * lightSpecularColour * specular * shadow;\n"; - - if (prof->getParent()->getDebugLevel()) - { - outStream << " outputCol.rg += lodInfo.xy;\n"; - } - } - } - - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - outStream << " outputCol.rgb = lerp(outputCol.rgb, fogColour, fogVal);\n"; - } - - // Final return - outStream << " return outputCol;\n" - << "}\n"; - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpDynamicShadowsHelpers( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - // TODO make filtering configurable - outStream << - "// Simple PCF \n" - "// Number of samples in one dimension (square for total samples) \n" - "#define NUM_SHADOW_SAMPLES_1D 2.0 \n" - "#define SHADOW_FILTER_SCALE 1 \n" - - "#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D \n" - - "float4 offsetSample(float4 uv, float2 offset, float invMapSize) \n" - "{ \n" - " return float4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w); \n" - "} \n"; - - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - "float calcDepthShadow(sampler2D shadowMap, float4 uv, float invShadowMapSize) \n" - "{ \n" - " // 4-sample PCF \n" - - " float shadow = 0.0; \n" - " float offset = (NUM_SHADOW_SAMPLES_1D/2 - 0.5) * SHADOW_FILTER_SCALE; \n" - " for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE) \n" - " for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE) \n" - " { \n" - " float4 newUV = offsetSample(uv, float2(x, y), invShadowMapSize);\n" - " // manually project and assign derivatives \n" - " // to avoid gradient issues inside loops \n" - " newUV = newUV / newUV.w; \n" - " float depth = tex2D(shadowMap, newUV.xy, 1, 1).x; \n" - " if (depth >= 1 || depth >= uv.z)\n" - " shadow += 1.0;\n" - " } \n" - - " shadow /= SHADOW_SAMPLES; \n" - - " return shadow; \n" - "} \n"; - } - else - { - outStream << - "float calcSimpleShadow(sampler2D shadowMap, float4 shadowMapPos) \n" - "{ \n" - " return tex2Dproj(shadowMap, shadowMapPos).x; \n" - "} \n"; - - } - - if (prof->getReceiveDynamicShadowsPSSM()) - { - uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - - - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - "float calcPSSMDepthShadow("; - } - else - { - outStream << - "float calcPSSMSimpleShadow("; - } - - outStream << "\n "; - for (uint i = 0; i < numTextures; ++i) - outStream << "sampler2D shadowMap" << i << ", "; - outStream << "\n "; - for (uint i = 0; i < numTextures; ++i) - outStream << "float4 lsPos" << i << ", "; - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << "\n "; - for (uint i = 0; i < numTextures; ++i) - outStream << "float invShadowmapSize" << i << ", "; - } - outStream << "\n" - " float4 pssmSplitPoints, float camDepth) \n" - "{ \n" - " float shadow; \n" - " // calculate shadow \n"; - - for (uint i = 0; i < numTextures; ++i) - { - if (!i) - outStream << " if (camDepth <= pssmSplitPoints." << ShaderHelper::getChannel(i) << ") \n"; - else if (i < numTextures - 1) - outStream << " else if (camDepth <= pssmSplitPoints." << ShaderHelper::getChannel(i) << ") \n"; - else - outStream << " else \n"; - - outStream << - " { \n"; - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - " shadow = calcDepthShadow(shadowMap" << i << ", lsPos" << i << ", invShadowmapSize" << i << "); \n"; - } - else - { - outStream << - " shadow = calcSimpleShadow(shadowMap" << i << ", lsPos" << i << "); \n"; - } - outStream << - " } \n"; - - } - - outStream << - " return shadow; \n" - "} \n\n\n"; - } - - - } - //--------------------------------------------------------------------- - uint TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateVpDynamicShadowsParams( - uint texCoord, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - // out semantics & params - uint numTextures = 1; - if (prof->getReceiveDynamicShadowsPSSM()) - { - numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - } - for (uint i = 0; i < numTextures; ++i) - { - outStream << - ", out float4 oLightSpacePos" << i << " : TEXCOORD" << texCoord++ << " \n" << - ", uniform float4x4 texViewProjMatrix" << i << " \n"; - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - ", uniform float4 depthRange" << i << " // x = min, y = max, z = range, w = 1/range \n"; - } - } - - return texCoord; - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateVpDynamicShadows( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - uint numTextures = 1; - if (prof->getReceiveDynamicShadowsPSSM()) - { - numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - } - - // Calculate the position of vertex in light space - for (uint i = 0; i < numTextures; ++i) - { - outStream << - " oLightSpacePos" << i << " = mul(texViewProjMatrix" << i << ", worldPos); \n"; - if (prof->getReceiveDynamicShadowsDepth()) - { - // make linear - outStream << - "oLightSpacePos" << i << ".z = (oLightSpacePos" << i << ".z - depthRange" << i << ".x) * depthRange" << i << ".w;\n"; - - } - } - - - if (prof->getReceiveDynamicShadowsPSSM()) - { - outStream << - " // pass cam depth\n" - " oUVMisc.z = oPos.z;\n"; - } - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpDynamicShadowsParams( - uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - if (tt == HIGH_LOD) - mShadowSamplerStartHi = *sampler; - else if (tt == LOW_LOD) - mShadowSamplerStartLo = *sampler; - - // in semantics & params - uint numTextures = 1; - if (prof->getReceiveDynamicShadowsPSSM()) - { - numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - outStream << - ", uniform float4 pssmSplitPoints \n"; - } - for (uint i = 0; i < numTextures; ++i) - { - outStream << - ", float4 lightSpacePos" << i << " : TEXCOORD" << *texCoord << " \n" << - ", uniform sampler2D shadowMap" << i << " : register(s" << *sampler << ") \n"; - *sampler = *sampler + 1; - *texCoord = *texCoord + 1; - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - ", uniform float inverseShadowmapSize" << i << " \n"; - } - } - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpDynamicShadows( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - if (prof->getReceiveDynamicShadowsPSSM()) - { - uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - outStream << - " float camDepth = uvMisc.z;\n"; - - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - " float rtshadow = calcPSSMDepthShadow("; - } - else - { - outStream << - " float rtshadow = calcPSSMSimpleShadow("; - } - for (uint i = 0; i < numTextures; ++i) - outStream << "shadowMap" << i << ", "; - outStream << "\n "; - - for (uint i = 0; i < numTextures; ++i) - outStream << "lightSpacePos" << i << ", "; - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << "\n "; - for (uint i = 0; i < numTextures; ++i) - outStream << "inverseShadowmapSize" << i << ", "; - } - outStream << "\n" << - " pssmSplitPoints, camDepth);\n"; - - } - else - { - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - " float rtshadow = calcDepthShadow(shadowMap0, lightSpacePos0, inverseShadowmapSize0);"; - } - else - { - outStream << - " float rtshadow = calcSimpleShadow(shadowMap0, lightSpacePos0);"; - } - } - - outStream << - " shadow = min(shadow, rtshadow);\n"; - - } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + HighLevelGpuProgramPtr + TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::createVertexProgram( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) + { + HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); + String progName = getVertexProgramName(prof, terrain, tt); + HighLevelGpuProgramPtr ret = mgr.getByName(progName).staticCast(); + if (ret.isNull()) + { + ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + "cg", GPT_VERTEX_PROGRAM).staticCast(); + } + else + { + ret->unload(); + } + + ret->setParameter("profiles", "vs_4_0 vs_3_0 vs_2_0 arbvp1"); + ret->setParameter("entry_point", "main_vp"); + + return ret; + + } + //--------------------------------------------------------------------- + HighLevelGpuProgramPtr + TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::createFragmentProgram( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) + { + HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); + String progName = getFragmentProgramName(prof, terrain, tt); + + HighLevelGpuProgramPtr ret = mgr.getByName(progName).staticCast(); + if (ret.isNull()) + { + ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + "cg", GPT_FRAGMENT_PROGRAM).staticCast(); + } + else + { + ret->unload(); + } + + if(prof->isLayerNormalMappingEnabled() || prof->isLayerParallaxMappingEnabled()) + ret->setParameter("profiles", "ps_4_0 ps_3_0 ps_2_x fp40 arbfp1"); + else + ret->setParameter("profiles", "ps_4_0 ps_3_0 ps_2_0 fp30 arbfp1"); + ret->setParameter("entry_point", "main_fp"); + + return ret; + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateVpHeader( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + outStream << + "void main_vp(\n"; + bool compression = terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP; + if (compression) + { + outStream << + "float2 posIndex : POSITION,\n" + "float height : TEXCOORD0,\n"; + } + else + { + outStream << + "float4 pos : POSITION,\n" + "float2 uv : TEXCOORD0,\n"; + + } + if (tt != RENDER_COMPOSITE_MAP) + outStream << "float2 delta : TEXCOORD1,\n"; // lodDelta, lodThreshold + + outStream << + "uniform float4x4 worldMatrix,\n" + "uniform float4x4 viewProjMatrix,\n" + "uniform float2 lodMorph,\n"; // morph amount, morph LOD target + + if (compression) + { + outStream << + "uniform float4x4 posIndexToObjectSpace,\n" + "uniform float baseUVScale,\n"; + } + // uv multipliers + uint maxLayers = prof->getMaxLayers(terrain); + uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); + uint numUVMultipliers = (numLayers / 4); + if (numLayers % 4) + ++numUVMultipliers; + for (uint i = 0; i < numUVMultipliers; ++i) + outStream << "uniform float4 uvMul_" << i << ", \n"; + + outStream << + "out float4 oPos : POSITION,\n" + "out float4 oPosObj : TEXCOORD0 \n"; + + uint texCoordSet = 1; + outStream << + ", out float4 oUVMisc : TEXCOORD" << texCoordSet++ <<" // xy = uv, z = camDepth\n"; + + // layer UV's premultiplied, packed as xy/zw + uint numUVSets = numLayers / 2; + if (numLayers % 2) + ++numUVSets; + if (tt != LOW_LOD) + { + for (uint i = 0; i < numUVSets; ++i) + { + outStream << + ", out float4 oUV" << i << " : TEXCOORD" << texCoordSet++ << "\n"; + } + } + + if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP) + { + outStream << ", out float2 lodInfo : TEXCOORD" << texCoordSet++ << "\n"; + } + + bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; + if (fog) + { + outStream << + ", uniform float4 fogParams\n" + ", out float fogVal : COLOR\n"; + } + + if (prof->isShadowingEnabled(tt, terrain)) + { + texCoordSet = generateVpDynamicShadowsParams(texCoordSet, prof, terrain, tt, outStream); + } + + // check we haven't exceeded texture coordinates + if (texCoordSet > 8) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Requested options require too many texture coordinate sets! Try reducing the number of layers.", + __FUNCTION__); + } + + outStream << + ")\n" + "{\n"; + if (compression) + { + outStream << + " float4 pos;\n" + " pos = mul(posIndexToObjectSpace, float4(posIndex, height, 1));\n" + " float2 uv = float2(posIndex.x * baseUVScale, 1.0 - (posIndex.y * baseUVScale));\n"; + } + outStream << + " float4 worldPos = mul(worldMatrix, pos);\n" + " oPosObj = pos;\n"; + + if (tt != RENDER_COMPOSITE_MAP) + { + // determine whether to apply the LOD morph to this vertex + // we store the deltas against all vertices so we only want to apply + // the morph to the ones which would disappear. The target LOD which is + // being morphed to is stored in lodMorph.y, and the LOD at which + // the vertex should be morphed is stored in uv.w. If we subtract + // the former from the latter, and arrange to only morph if the + // result is negative (it will only be -1 in fact, since after that + // the vertex will never be indexed), we will achieve our aim. + // sign(vertexLOD - targetLOD) == -1 is to morph + outStream << + " float toMorph = -min(0, sign(delta.y - lodMorph.y));\n"; + // this will either be 1 (morph) or 0 (don't morph) + if (prof->getParent()->getDebugLevel()) + { + // x == LOD level (-1 since value is target level, we want to display actual) + outStream << "lodInfo.x = (lodMorph.y - 1) / " << terrain->getNumLodLevels() << ";\n"; + // y == LOD morph + outStream << "lodInfo.y = toMorph * lodMorph.x;\n"; + } + + // morph + switch (terrain->getAlignment()) + { + case Terrain::ALIGN_X_Y: + outStream << " worldPos.z += delta.x * toMorph * lodMorph.x;\n"; + break; + case Terrain::ALIGN_X_Z: + outStream << " worldPos.y += delta.x * toMorph * lodMorph.x;\n"; + break; + case Terrain::ALIGN_Y_Z: + outStream << " worldPos.x += delta.x * toMorph * lodMorph.x;\n"; + break; + }; + } + + + // generate UVs + if (tt != LOW_LOD) + { + for (uint i = 0; i < numUVSets; ++i) + { + uint layer = i * 2; + uint uvMulIdx = layer / 4; + + outStream << + " oUV" << i << ".xy = " << " uv.xy * uvMul_" << uvMulIdx << "." << getChannel(layer) << ";\n"; + outStream << + " oUV" << i << ".zw = " << " uv.xy * uvMul_" << uvMulIdx << "." << getChannel(layer+1) << ";\n"; + + } + + } + + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpHeader( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + + // Main header + outStream << + // helpers + "float4 expand(float4 v)\n" + "{ \n" + " return v * 2 - 1;\n" + "}\n\n\n"; + + if (prof->isShadowingEnabled(tt, terrain)) + generateFpDynamicShadowsHelpers(prof, terrain, tt, outStream); + + + outStream << + "float4 main_fp(\n" + "float4 vertexPos : POSITION,\n" + "float4 position : TEXCOORD0,\n"; + + uint texCoordSet = 1; + outStream << + "float4 uvMisc : TEXCOORD" << texCoordSet++ << ",\n"; + + // UV's premultiplied, packed as xy/zw + uint maxLayers = prof->getMaxLayers(terrain); + uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount()); + uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); + uint numUVSets = numLayers / 2; + if (numLayers % 2) + ++numUVSets; + if (tt != LOW_LOD) + { + for (uint i = 0; i < numUVSets; ++i) + { + outStream << + "float4 layerUV" << i << " : TEXCOORD" << texCoordSet++ << ", \n"; + } + + } + if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP) + { + outStream << "float2 lodInfo : TEXCOORD" << texCoordSet++ << ", \n"; + } + + bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; + if (fog) + { + outStream << + "uniform float3 fogColour, \n" + "float fogVal : COLOR,\n"; + } + + uint currentSamplerIdx = 0; + + outStream << + // Only 1 light supported in this version + // deferred shading profile / generator later, ok? :) + "uniform float3 ambient,\n" + "uniform float4 lightPosObjSpace,\n" + "uniform float3 lightDiffuseColour,\n" + "uniform float3 lightSpecularColour,\n" + "uniform float3 eyePosObjSpace,\n" + // pack scale, bias and specular + "uniform float4 scaleBiasSpecular,\n"; + + if (tt == LOW_LOD) + { + // single composite map covers all the others below + outStream << + "uniform sampler2D compositeMap : register(s" << currentSamplerIdx++ << ")\n"; + } + else + { + outStream << + "uniform sampler2D globalNormal : register(s" << currentSamplerIdx++ << ")\n"; + + + if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) + { + outStream << ", uniform sampler2D globalColourMap : register(s" + << currentSamplerIdx++ << ")\n"; + } + if (prof->isLightmapEnabled()) + { + outStream << ", uniform sampler2D lightMap : register(s" + << currentSamplerIdx++ << ")\n"; + } + // Blend textures - sampler definitions + for (uint i = 0; i < numBlendTextures; ++i) + { + outStream << ", uniform sampler2D blendTex" << i + << " : register(s" << currentSamplerIdx++ << ")\n"; + } + + // Layer textures - sampler definitions & UV multipliers + for (uint i = 0; i < numLayers; ++i) + { + outStream << ", uniform sampler2D difftex" << i + << " : register(s" << currentSamplerIdx++ << ")\n"; + outStream << ", uniform sampler2D normtex" << i + << " : register(s" << currentSamplerIdx++ << ")\n"; + } + } + + if (prof->isShadowingEnabled(tt, terrain)) + { + generateFpDynamicShadowsParams(&texCoordSet, ¤tSamplerIdx, prof, terrain, tt, outStream); + } + + // check we haven't exceeded samplers + if (currentSamplerIdx > 16) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Requested options require too many texture samplers! Try reducing the number of layers.", + __FUNCTION__); + } + + outStream << + ") : COLOR\n" + "{\n" + " float4 outputCol;\n" + " float shadow = 1.0;\n" + " float2 uv = uvMisc.xy;\n" + // base colour + " outputCol = float4(0,0,0,1);\n"; + + if (tt != LOW_LOD) + { + outStream << + // global normal + " float3 normal = expand(tex2D(globalNormal, uv)).rgb;\n"; + + } + + outStream << + " float3 lightDir = \n" + " lightPosObjSpace.xyz - (position.xyz * lightPosObjSpace.w);\n" + " float3 eyeDir = eyePosObjSpace - position.xyz;\n" + + // set up accumulation areas + " float3 diffuse = float3(0,0,0);\n" + " float specular = 0;\n"; + + + if (tt == LOW_LOD) + { + // we just do a single calculation from composite map + outStream << + " float4 composite = tex2D(compositeMap, uv);\n" + " diffuse = composite.rgb;\n"; + // TODO - specular; we'll need normals for this! + } + else + { + // set up the blend values + for (uint i = 0; i < numBlendTextures; ++i) + { + outStream << " float4 blendTexVal" << i << " = tex2D(blendTex" << i << ", uv);\n"; + } + + if (prof->isLayerNormalMappingEnabled()) + { + // derive the tangent space basis + // we do this in the pixel shader because we don't have per-vertex normals + // because of the LOD, we use a normal map + // tangent is always +x or -z in object space depending on alignment + switch(terrain->getAlignment()) + { + case Terrain::ALIGN_X_Y: + case Terrain::ALIGN_X_Z: + outStream << " float3 tangent = float3(1, 0, 0);\n"; + break; + case Terrain::ALIGN_Y_Z: + outStream << " float3 tangent = float3(0, 0, -1);\n"; + break; + }; + + outStream << " float3 binormal = normalize(cross(tangent, normal));\n"; + // note, now we need to re-cross to derive tangent again because it wasn't orthonormal + outStream << " tangent = normalize(cross(normal, binormal));\n"; + // derive final matrix + outStream << " float3x3 TBN = float3x3(tangent, binormal, normal);\n"; + + // set up lighting result placeholders for interpolation + outStream << " float4 litRes, litResLayer;\n"; + outStream << " float3 TSlightDir, TSeyeDir, TShalfAngle, TSnormal;\n"; + if (prof->isLayerParallaxMappingEnabled()) + outStream << " float displacement;\n"; + // move + outStream << " TSlightDir = normalize(mul(TBN, lightDir));\n"; + outStream << " TSeyeDir = normalize(mul(TBN, eyeDir));\n"; + + } + else + { + // simple per-pixel lighting with no normal mapping + outStream << " lightDir = normalize(lightDir);\n"; + outStream << " eyeDir = normalize(eyeDir);\n"; + outStream << " float3 halfAngle = normalize(lightDir + eyeDir);\n"; + outStream << " float4 litRes = lit(dot(lightDir, normal), dot(halfAngle, normal), scaleBiasSpecular.z);\n"; + + } + } + + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateVpLayer( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) + { + // nothing to do + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpLayer( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) + { + uint uvIdx = layer / 2; + String uvChannels = (layer % 2) ? ".zw" : ".xy"; + uint blendIdx = (layer-1) / 4; + String blendChannel = getChannel(layer-1); + String blendWeightStr = String("blendTexVal") + StringConverter::toString(blendIdx) + + "." + blendChannel; + + // generate early-out conditional + /* Disable - causing some issues even when trying to force the use of texldd + if (layer && prof->_isSM3Available()) + outStream << " if (" << blendWeightStr << " > 0.0003)\n { \n"; + */ + + // generate UV + outStream << " float2 uv" << layer << " = layerUV" << uvIdx << uvChannels << ";\n"; + + // calculate lighting here if normal mapping + if (prof->isLayerNormalMappingEnabled()) + { + if (prof->isLayerParallaxMappingEnabled() && tt != RENDER_COMPOSITE_MAP) + { + // modify UV - note we have to sample an extra time + outStream << " displacement = tex2D(normtex" << layer << ", uv" << layer << ").a\n" + " * scaleBiasSpecular.x + scaleBiasSpecular.y;\n"; + outStream << " uv" << layer << " += TSeyeDir.xy * displacement;\n"; + } + + // access TS normal map + outStream << " TSnormal = expand(tex2D(normtex" << layer << ", uv" << layer << ")).rgb;\n"; + outStream << " TShalfAngle = normalize(TSlightDir + TSeyeDir);\n"; + outStream << " litResLayer = lit(dot(TSlightDir, TSnormal), dot(TShalfAngle, TSnormal), scaleBiasSpecular.z);\n"; + if (!layer) + outStream << " litRes = litResLayer;\n"; + else + outStream << " litRes = lerp(litRes, litResLayer, " << blendWeightStr << ");\n"; + + } + + // sample diffuse texture + outStream << " float4 diffuseSpecTex" << layer + << " = tex2D(difftex" << layer << ", uv" << layer << ");\n"; + + // apply to common + if (!layer) + { + outStream << " diffuse = diffuseSpecTex0.rgb;\n"; + if (prof->isLayerSpecularMappingEnabled()) + outStream << " specular = diffuseSpecTex0.a;\n"; + } + else + { + outStream << " diffuse = lerp(diffuse, diffuseSpecTex" << layer + << ".rgb, " << blendWeightStr << ");\n"; + if (prof->isLayerSpecularMappingEnabled()) + outStream << " specular = lerp(specular, diffuseSpecTex" << layer + << ".a, " << blendWeightStr << ");\n"; + + } + + // End early-out + /* Disable - causing some issues even when trying to force the use of texldd + if (layer && prof->_isSM3Available()) + outStream << " } // early-out blend value\n"; + */ + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateVpFooter( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + + outStream << + " oPos = mul(viewProjMatrix, worldPos);\n" + " oUVMisc.xy = uv.xy;\n"; + + bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; + if (fog) + { + if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) + { + outStream << + " fogVal = saturate((oPos.z - fogParams.y) * fogParams.w);\n"; + } + else + { + outStream << + " fogVal = 1 - saturate(1 / (exp(oPos.z * fogParams.x)));\n"; + } + } + + if (prof->isShadowingEnabled(tt, terrain)) + generateVpDynamicShadows(prof, terrain, tt, outStream); + + outStream << + "}\n"; + + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpFooter( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + + if (tt == LOW_LOD) + { + if (prof->isShadowingEnabled(tt, terrain)) + { + generateFpDynamicShadows(prof, terrain, tt, outStream); + outStream << + " outputCol.rgb = diffuse * rtshadow;\n"; + } + else + { + outStream << + " outputCol.rgb = diffuse;\n"; + } + } + else + { + if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) + { + // sample colour map and apply to diffuse + outStream << " diffuse *= tex2D(globalColourMap, uv).rgb;\n"; + } + if (prof->isLightmapEnabled()) + { + // sample lightmap + outStream << " shadow = tex2D(lightMap, uv).r;\n"; + } + + if (prof->isShadowingEnabled(tt, terrain)) + { + generateFpDynamicShadows(prof, terrain, tt, outStream); + } + + // diffuse lighting + outStream << " outputCol.rgb += ambient.rgb * diffuse + litRes.y * lightDiffuseColour * diffuse * shadow;\n"; + + // specular default + if (!prof->isLayerSpecularMappingEnabled()) + outStream << " specular = 1.0;\n"; + + if (tt == RENDER_COMPOSITE_MAP) + { + // Lighting embedded in alpha + outStream << + " outputCol.a = shadow;\n"; + + } + else + { + // Apply specular + outStream << " outputCol.rgb += litRes.z * lightSpecularColour * specular * shadow;\n"; + + if (prof->getParent()->getDebugLevel()) + { + outStream << " outputCol.rg += lodInfo.xy;\n"; + } + } + } + + bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; + if (fog) + { + outStream << " outputCol.rgb = lerp(outputCol.rgb, fogColour, fogVal);\n"; + } + + // Final return + outStream << " return outputCol;\n" + << "}\n"; + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpDynamicShadowsHelpers( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + // TODO make filtering configurable + outStream << + "// Simple PCF \n" + "// Number of samples in one dimension (square for total samples) \n" + "#define NUM_SHADOW_SAMPLES_1D 2.0 \n" + "#define SHADOW_FILTER_SCALE 1 \n" + + "#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D \n" + + "float4 offsetSample(float4 uv, float2 offset, float invMapSize) \n" + "{ \n" + " return float4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w); \n" + "} \n"; + + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + "float calcDepthShadow(sampler2D shadowMap, float4 uv, float invShadowMapSize) \n" + "{ \n" + " // 4-sample PCF \n" + + " float shadow = 0.0; \n" + " float offset = (NUM_SHADOW_SAMPLES_1D/2 - 0.5) * SHADOW_FILTER_SCALE; \n" + " for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE) \n" + " for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE) \n" + " { \n" + " float4 newUV = offsetSample(uv, float2(x, y), invShadowMapSize);\n" + " // manually project and assign derivatives \n" + " // to avoid gradient issues inside loops \n" + " newUV = newUV / newUV.w; \n" + " float depth = tex2D(shadowMap, newUV.xy, 1, 1).x; \n" + " if (depth >= 1 || depth >= uv.z)\n" + " shadow += 1.0;\n" + " } \n" + + " shadow /= SHADOW_SAMPLES; \n" + + " return shadow; \n" + "} \n"; + } + else + { + outStream << + "float calcSimpleShadow(sampler2D shadowMap, float4 shadowMapPos) \n" + "{ \n" + " return tex2Dproj(shadowMap, shadowMapPos).x; \n" + "} \n"; + + } + + if (prof->getReceiveDynamicShadowsPSSM()) + { + uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + + + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + "float calcPSSMDepthShadow("; + } + else + { + outStream << + "float calcPSSMSimpleShadow("; + } + + outStream << "\n "; + for (uint i = 0; i < numTextures; ++i) + outStream << "sampler2D shadowMap" << i << ", "; + outStream << "\n "; + for (uint i = 0; i < numTextures; ++i) + outStream << "float4 lsPos" << i << ", "; + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << "\n "; + for (uint i = 0; i < numTextures; ++i) + outStream << "float invShadowmapSize" << i << ", "; + } + outStream << "\n" + " float4 pssmSplitPoints, float camDepth) \n" + "{ \n" + " float shadow; \n" + " // calculate shadow \n"; + + for (uint i = 0; i < numTextures; ++i) + { + if (!i) + outStream << " if (camDepth <= pssmSplitPoints." << ShaderHelper::getChannel(i) << ") \n"; + else if (i < numTextures - 1) + outStream << " else if (camDepth <= pssmSplitPoints." << ShaderHelper::getChannel(i) << ") \n"; + else + outStream << " else \n"; + + outStream << + " { \n"; + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + " shadow = calcDepthShadow(shadowMap" << i << ", lsPos" << i << ", invShadowmapSize" << i << "); \n"; + } + else + { + outStream << + " shadow = calcSimpleShadow(shadowMap" << i << ", lsPos" << i << "); \n"; + } + outStream << + " } \n"; + + } + + outStream << + " return shadow; \n" + "} \n\n\n"; + } + + + } + //--------------------------------------------------------------------- + uint TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateVpDynamicShadowsParams( + uint texCoord, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + // out semantics & params + uint numTextures = 1; + if (prof->getReceiveDynamicShadowsPSSM()) + { + numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + } + for (uint i = 0; i < numTextures; ++i) + { + outStream << + ", out float4 oLightSpacePos" << i << " : TEXCOORD" << texCoord++ << " \n" << + ", uniform float4x4 texViewProjMatrix" << i << " \n"; + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + ", uniform float4 depthRange" << i << " // x = min, y = max, z = range, w = 1/range \n"; + } + } + + return texCoord; + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateVpDynamicShadows( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + uint numTextures = 1; + if (prof->getReceiveDynamicShadowsPSSM()) + { + numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + } + + // Calculate the position of vertex in light space + for (uint i = 0; i < numTextures; ++i) + { + outStream << + " oLightSpacePos" << i << " = mul(texViewProjMatrix" << i << ", worldPos); \n"; + if (prof->getReceiveDynamicShadowsDepth()) + { + // make linear + outStream << + "oLightSpacePos" << i << ".z = (oLightSpacePos" << i << ".z - depthRange" << i << ".x) * depthRange" << i << ".w;\n"; + + } + } + + + if (prof->getReceiveDynamicShadowsPSSM()) + { + outStream << + " // pass cam depth\n" + " oUVMisc.z = oPos.z;\n"; + } + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpDynamicShadowsParams( + uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + if (tt == HIGH_LOD) + mShadowSamplerStartHi = *sampler; + else if (tt == LOW_LOD) + mShadowSamplerStartLo = *sampler; + + // in semantics & params + uint numTextures = 1; + if (prof->getReceiveDynamicShadowsPSSM()) + { + numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + outStream << + ", uniform float4 pssmSplitPoints \n"; + } + for (uint i = 0; i < numTextures; ++i) + { + outStream << + ", float4 lightSpacePos" << i << " : TEXCOORD" << *texCoord << " \n" << + ", uniform sampler2D shadowMap" << i << " : register(s" << *sampler << ") \n"; + *sampler = *sampler + 1; + *texCoord = *texCoord + 1; + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + ", uniform float inverseShadowmapSize" << i << " \n"; + } + } + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperCg::generateFpDynamicShadows( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + if (prof->getReceiveDynamicShadowsPSSM()) + { + uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + outStream << + " float camDepth = uvMisc.z;\n"; + + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + " float rtshadow = calcPSSMDepthShadow("; + } + else + { + outStream << + " float rtshadow = calcPSSMSimpleShadow("; + } + for (uint i = 0; i < numTextures; ++i) + outStream << "shadowMap" << i << ", "; + outStream << "\n "; + + for (uint i = 0; i < numTextures; ++i) + outStream << "lightSpacePos" << i << ", "; + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << "\n "; + for (uint i = 0; i < numTextures; ++i) + outStream << "inverseShadowmapSize" << i << ", "; + } + outStream << "\n" << + " pssmSplitPoints, camDepth);\n"; + + } + else + { + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + " float rtshadow = calcDepthShadow(shadowMap0, lightSpacePos0, inverseShadowmapSize0);"; + } + else + { + outStream << + " float rtshadow = calcSimpleShadow(shadowMap0, lightSpacePos0);"; + } + } + + outStream << + " shadow = min(shadow, rtshadow);\n"; + + } } diff --git a/Components/Terrain/src/OgreTerrainMaterialShaderHelperHLSL.cpp b/Components/Terrain/src/OgreTerrainMaterialShaderHelperHLSL.cpp index 4cf11ecde44..a03ccbdb87c 100644 --- a/Components/Terrain/src/OgreTerrainMaterialShaderHelperHLSL.cpp +++ b/Components/Terrain/src/OgreTerrainMaterialShaderHelperHLSL.cpp @@ -33,960 +33,960 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - HighLevelGpuProgramPtr - TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::createVertexProgram( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) - { - HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); - String progName = getVertexProgramName(prof, terrain, tt); - - HighLevelGpuProgramPtr ret = mgr.getByName(progName); - if (ret.isNull()) - { - ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - "hlsl", GPT_VERTEX_PROGRAM); - } - else - { - ret->unload(); - } - // creating Shader Model 4.0 type hlsl shader fol DirectX11 Render System - if (prof->_isSM4Available()) - ret->setParameter("target", "vs_4_0"); - //else if (prof->_isSM3Available()) - // ret->setParameter("target", "vs_3_0"); - //else - // ret->setParameter("target", "vs_2_0"); - ret->setParameter("entry_point", "main_vp"); - - return ret; - - } - //--------------------------------------------------------------------- - HighLevelGpuProgramPtr - TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::createFragmentProgram( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) - { - HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); - String progName = getFragmentProgramName(prof, terrain, tt); - - HighLevelGpuProgramPtr ret = mgr.getByName(progName); - if (ret.isNull()) - { - ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - "hlsl", GPT_FRAGMENT_PROGRAM); - } - else - { - ret->unload(); - } - // creating Shader Model 4.0 type hlsl shader fol DirectX11 Render System - if (prof->_isSM4Available()) - ret->setParameter("target", "ps_4_0"); - //else if (prof->_isSM3Available()) - // ret->setParameter("target", "ps_3_0"); - //else - // ret->setParameter("target", "ps_2_x"); - ret->setParameter("entry_point", "main_fp"); - - return ret; - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateVpHeader( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - // generate some structures needed for SM4 before the header - - // vertex shader output, pixel shader input struct. - outStream << - "struct v2p\n" - "{\n"; - - outStream << - "float4 oPos : SV_POSITION;\n" - "float4 oPosObj : TEXCOORD0; \n"; - - uint texCoordSet = 1; - outStream << - "float4 oUVMisc : TEXCOORD" << texCoordSet++ <<"; // xy = uv, z = camDepth\n"; - - // uv multipliers - uint maxLayers = prof->getMaxLayers(terrain); - uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); - uint numUVMultipliers = (numLayers / 4); - if (numLayers % 4) - ++numUVMultipliers; - - // layer UV's premultiplied, packed as xy/zw - uint numUVSets = numLayers / 2; - if (numLayers % 2) - ++numUVSets; - if (tt != LOW_LOD) - { - for (uint i = 0; i < numUVSets; ++i) - { - outStream << - "float4 oUV" << i << " : TEXCOORD" << texCoordSet++ << ";\n"; - } - } - - if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP) - { - outStream << "float2 lodInfo : TEXCOORD" << texCoordSet++ << ";\n"; - } - - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - outStream << "float fogVal : COLOR;\n"; - } - - uint numTextures = 1; - if (prof->getReceiveDynamicShadowsPSSM()) - { - numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - } - for (uint i = 0; i < numTextures; ++i) - { - outStream << - "float4 oLightSpacePos" << i << " : TEXCOORD" << texCoordSet++ << " ;\n"; - } - - outStream << "};\n"; - //output/input structure finished - - outStream << - "v2p main_vp(\n"; - bool compression = terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP; - if (compression) - { - outStream << - "float2 posIndex : POSITION,\n" - "float height : TEXCOORD0,\n"; - } - else - { - outStream << - "float4 pos : POSITION,\n" - "float2 uv : TEXCOORD0,\n"; - - } - if (tt != RENDER_COMPOSITE_MAP) - outStream << "float2 delta : TEXCOORD1,\n"; // lodDelta, lodThreshold - - outStream << - "uniform matrix worldMatrix,\n" - "uniform matrix viewProjMatrix,\n" - "uniform float2 lodMorph,\n"; // morph amount, morph LOD target - - if (compression) - { - outStream << - "uniform matrix posIndexToObjectSpace,\n" - "uniform float baseUVScale,\n"; - } - - for (uint i = 0; i < numUVMultipliers - 1; ++i) - outStream << "uniform float4 uvMul_" << i << ", \n"; - outStream << "uniform float4 uvMul_" << numUVMultipliers - 1 << " \n"; - - if (fog) - { - outStream << - ", uniform float4 fogParams\n"; - } - - if (prof->isShadowingEnabled(tt, terrain)) - { - texCoordSet = generateVpDynamicShadowsParams(texCoordSet, prof, terrain, tt, outStream); - } - - // check we haven't exceeded texture coordinates - if (texCoordSet > 8) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Requested options require too many texture coordinate sets! Try reducing the number of layers.", - __FUNCTION__); - } - - outStream << - ")\n" - "{\n"; - if (compression) - { - outStream << - " float4 pos;\n" - " pos = mul(posIndexToObjectSpace, float4(posIndex, height, 1));\n" - " float2 uv = float2(posIndex.x * baseUVScale, 1.0 - (posIndex.y * baseUVScale));\n"; - } - outStream << - " float4 worldPos = mul(worldMatrix, pos);\n" - " v2p output;\n" - " output.oPosObj = pos;\n"; - - if (tt != RENDER_COMPOSITE_MAP) - { - // determine whether to apply the LOD morph to this vertex - // we store the deltas against all vertices so we only want to apply - // the morph to the ones which would disappear. The target LOD which is - // being morphed to is stored in lodMorph.y, and the LOD at which - // the vertex should be morphed is stored in uv.w. If we subtract - // the former from the latter, and arrange to only morph if the - // result is negative (it will only be -1 in fact, since after that - // the vertex will never be indexed), we will achieve our aim. - // sign(vertexLOD - targetLOD) == -1 is to morph - outStream << - " float toMorph = -min(0, sign(delta.y - lodMorph.y));\n"; - // this will either be 1 (morph) or 0 (don't morph) - if (prof->getParent()->getDebugLevel()) - { - // x == LOD level (-1 since value is target level, we want to display actual) - outStream << "output.lodInfo.x = (lodMorph.y - 1) / " << terrain->getNumLodLevels() << ";\n"; - // y == LOD morph - outStream << "output.lodInfo.y = toMorph * lodMorph.x;\n"; - } - - // morph - switch (terrain->getAlignment()) - { - case Terrain::ALIGN_X_Y: - outStream << " worldPos.z += delta.x * toMorph * lodMorph.x;\n"; - break; - case Terrain::ALIGN_X_Z: - outStream << " worldPos.y += delta.x * toMorph * lodMorph.x;\n"; - break; - case Terrain::ALIGN_Y_Z: - outStream << " worldPos.x += delta.x * toMorph * lodMorph.x;\n"; - break; - }; - } - - - // generate UVs - if (tt != LOW_LOD) - { - for (uint i = 0; i < numUVSets; ++i) - { - uint layer = i * 2; - uint uvMulIdx = layer / 4; - - outStream << - " output.oUV" << i << ".xy = " << " uv.xy * uvMul_" << uvMulIdx << "." << getChannel(layer) << ";\n"; - outStream << - " output.oUV" << i << ".zw = " << " uv.xy * uvMul_" << uvMulIdx << "." << getChannel(layer+1) << ";\n"; - - } - - } - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateVpLayer( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) - { - // nothing to do - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateVpFooter( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - - outStream << - " output.oPos = mul(viewProjMatrix, worldPos);\n" - " output.oUVMisc.xy = uv.xy;\n"; - - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) - { - outStream << - " output.fogVal = saturate((output.oPos.z - fogParams.y) * fogParams.w);\n"; - } - else - { - outStream << - " output.fogVal = 1 - saturate(1 / (exp(output.oPos.z * fogParams.x)));\n"; - } - } - - if (prof->isShadowingEnabled(tt, terrain)) - generateVpDynamicShadows(prof, terrain, tt, outStream); - - outStream << - "return output;" - "}\n"; - - } - //--------------------------------------------------------------------- - uint TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateVpDynamicShadowsParams( - uint texCoord, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - // out semantics & params - uint numTextures = 1; - if (prof->getReceiveDynamicShadowsPSSM()) - { - numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - } - for (uint i = 0; i < numTextures; ++i) - { - outStream << - ", uniform matrix texViewProjMatrix" << i << " \n"; - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - ", uniform float4 depthRange" << i << " // x = min, y = max, z = range, w = 1/range \n"; - } - } - - return texCoord; - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateVpDynamicShadows( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - uint numTextures = 1; - if (prof->getReceiveDynamicShadowsPSSM()) - { - numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - } - - // Calculate the position of vertex in light space - for (uint i = 0; i < numTextures; ++i) - { - outStream << - " output.oLightSpacePos" << i << " = mul(texViewProjMatrix" << i << ", worldPos); \n"; - if (prof->getReceiveDynamicShadowsDepth()) - { - // make linear - outStream << - "output.oLightSpacePos" << i << ".z = (output.oLightSpacePos" << i << ".z - depthRange" << i << ".x) * depthRange" << i << ".w;\n"; - - } - } - - - if (prof->getReceiveDynamicShadowsPSSM()) - { - outStream << - " // pass cam depth\n" - " output.oUVMisc.z = output.oPos.z;\n"; - } - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpHeader( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - // adding samplerstate for shadowmapping - outStream << - "SamplerState g_SamLinear\n" - "{\n" - " Filter = MIN_MAG_MIP_LINEAR;\n" - " AddressU = Wrap;\n" - " AddressV = Wrap;\n" - "};\n" - "SamplerState g_SamClamp\n" - "{\n" - " Filter = MIN_MAG_MIP_LINEAR;\n" - " AddressU = Clamp;\n" - " AddressV = Clamp;\n" - "};\n" - ; - - // Main header - outStream << - // helpers - "float4 expand(float4 v)\n" - "{ \n" - " return v * 2 - 1;\n" - "}\n\n\n"; - - if (prof->isShadowingEnabled(tt, terrain)) - generateFpDynamicShadowsHelpers(prof, terrain, tt, outStream); - - // vertex shader output, pixel shader input struct. - outStream << - "struct v2p\n" - "{\n"; - - outStream << - "float4 oPos : SV_POSITION;\n" - "float4 oPosObj : TEXCOORD0; \n"; - - uint texCoordSet = 1; - outStream << - "float4 oUVMisc : TEXCOORD" << texCoordSet++ <<"; // xy = uv, z = camDepth\n"; - - // uv multipliers - uint maxLayers = prof->getMaxLayers(terrain); - uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); - uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount()); - uint numUVMultipliers = (numLayers / 4); - if (numLayers % 4) - ++numUVMultipliers; - - // layer UV's premultiplied, packed as xy/zw - uint numUVSets = numLayers / 2; - if (numLayers % 2) - ++numUVSets; - if (tt != LOW_LOD) - { - for (uint i = 0; i < numUVSets; ++i) - { - outStream << - "float4 oUV" << i << " : TEXCOORD" << texCoordSet++ << ";\n"; - } - } - - if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP) - { - outStream << "float2 lodInfo : TEXCOORD" << texCoordSet++ << ";\n"; - } - - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - outStream << "float fogVal : COLOR;\n"; - } - - uint numTextures = 1; - if (prof->getReceiveDynamicShadowsPSSM()) - { - numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - } - for (uint i = 0; i < numTextures; ++i) - { - outStream << - "float4 oLightSpacePos" << i << " : TEXCOORD" << texCoordSet++ << " ;\n"; - } - - outStream << "};\n"; - //output/input structure finished - - uint currentSamplerIdx = 0; - if (tt == LOW_LOD) - { - // single composite map covers all the others below - outStream << - "Texture2D compositeMap : register(s" << currentSamplerIdx++ << ");\n"; - } - else - { - outStream << - "Texture2D globalNormal : register(s" << currentSamplerIdx++ << ");\n"; - - - if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) - { - outStream << "Texture2D globalColourMap : register(s" - << currentSamplerIdx++ << ");\n"; - } - if (prof->isLightmapEnabled()) - { - outStream << "Texture2D lightMap : register(s" - << currentSamplerIdx++ << ");\n"; - } - // Blend textures - sampler definitions - for (uint i = 0; i < numBlendTextures; ++i) - { - outStream << "Texture2D blendTex" << i - << " : register(s" << currentSamplerIdx++ << ");\n"; - } - - // Layer textures - sampler definitions & UV multipliers - for (uint i = 0; i < numLayers; ++i) - { - outStream << "Texture2D difftex" << i - << " : register(s" << currentSamplerIdx++ << ");\n"; - outStream << "Texture2D normtex" << i - << " : register(s" << currentSamplerIdx++ << ");\n"; - } - } - - outStream << - "float4 main_fp(\n" - "v2p input,\n"; - - if (fog) - { - outStream << - "uniform float3 fogColour, \n"; - } - - outStream << - // Only 1 light supported in this version - // deferred shading profile / generator later, ok? :) - "uniform float3 ambient,\n" - "uniform float4 lightPosObjSpace,\n" - "uniform float3 lightDiffuseColour,\n" - "uniform float3 lightSpecularColour,\n" - "uniform float3 eyePosObjSpace,\n" - // pack scale, bias and specular - "uniform float4 scaleBiasSpecular\n"; - - if (prof->isShadowingEnabled(tt, terrain)) - { - generateFpDynamicShadowsParams(&texCoordSet, ¤tSamplerIdx, prof, terrain, tt, outStream); - } - - // check we haven't exceeded samplers - if (currentSamplerIdx > 16) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Requested options require too many texture samplers! Try reducing the number of layers.", - __FUNCTION__); - } - - outStream << - ") : SV_Target\n" - "{\n" - " float4 outputCol;\n" - " float shadow = 1.0;\n" - " float2 uv = input.oUVMisc.xy;\n" - // base colour - " outputCol = float4(0.0,0.0,0.0,1.0);\n"; - - if (tt != LOW_LOD) - { - outStream << - // global normal - " float3 normal = expand(globalNormal.Sample(g_SamClamp, uv)).rgb;\n"; - - } - - outStream << - " float3 lightDir = \n" - " lightPosObjSpace.xyz - (input.oPosObj.xyz * lightPosObjSpace.w);\n" - " float3 eyeDir = eyePosObjSpace - input.oPosObj.xyz;\n" - - // set up accumulation areas - " float3 diffuse = float3(0,0,0);\n" - " float specular = 0;\n"; - - - if (tt == LOW_LOD) - { - // we just do a single calculation from composite map - outStream << - " float4 composite = compositeMap.Sample(g_SamClamp, uv);\n" - " diffuse = composite.rgb;\n"; - // TODO - specular; we'll need normals for this! - } - else - { - // set up the blend values - for (uint i = 0; i < numBlendTextures; ++i) - { - outStream << " float4 blendTexVal" << i << " = blendTex" << i << ".Sample(g_SamClamp, uv);\n"; - } - - if (prof->isLayerNormalMappingEnabled()) - { - // derive the tangent space basis - // we do this in the pixel shader because we don't have per-vertex normals - // because of the LOD, we use a normal map - // tangent is always +x or -z in object space depending on alignment - switch(terrain->getAlignment()) - { - case Terrain::ALIGN_X_Y: - case Terrain::ALIGN_X_Z: - outStream << " float3 tangent = float3(1, 0, 0);\n"; - break; - case Terrain::ALIGN_Y_Z: - outStream << " float3 tangent = float3(0, 0, -1);\n"; - break; - }; - - outStream << " float3 binormal = normalize(cross(tangent, normal));\n"; - // note, now we need to re-cross to derive tangent again because it wasn't orthonormal - outStream << " tangent = normalize(cross(normal, binormal));\n"; - // derive final matrix - outStream << " float3x3 TBN = float3x3(tangent, binormal, normal);\n"; - - // set up lighting result placeholders for interpolation - outStream << " float4 litRes, litResLayer;\n"; - outStream << " float3 TSlightDir, TSeyeDir, TShalfAngle, TSnormal;\n"; - if (prof->isLayerParallaxMappingEnabled()) - outStream << " float displacement;\n"; - // move - outStream << " TSlightDir = normalize(mul(TBN, lightDir));\n"; - outStream << " TSeyeDir = normalize(mul(TBN, eyeDir));\n"; - - } - else - { - // simple per-pixel lighting with no normal mapping - outStream << " lightDir = normalize(lightDir);\n"; - outStream << " eyeDir = normalize(eyeDir);\n"; - outStream << " float3 halfAngle = normalize(lightDir + eyeDir);\n"; - outStream << " float4 litRes = lit(dot(lightDir, normal), dot(halfAngle, normal), scaleBiasSpecular.z);\n"; - - } - } - - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpLayer( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) - { - uint uvIdx = layer / 2; - String uvChannels = (layer % 2) ? ".zw" : ".xy"; - uint blendIdx = (layer-1) / 4; - String blendChannel = getChannel(layer-1); - String blendWeightStr = String("blendTexVal") + StringConverter::toString(blendIdx) + - "." + blendChannel; - - // generate early-out conditional - /* Disable - causing some issues even when trying to force the use of texldd - if (layer && prof->_isSM3Available()) - outStream << " if (" << blendWeightStr << " > 0.0003)\n { \n"; - */ - - // generate UV - outStream << " float2 uv" << layer << " = input.oUV" << uvIdx << uvChannels << ";\n"; - - // calculate lighting here if normal mapping - if (prof->isLayerNormalMappingEnabled()) - { - if (prof->isLayerParallaxMappingEnabled() && tt != RENDER_COMPOSITE_MAP) - { - // modify UV - note we have to sample an extra time - outStream << " displacement = normtex" << layer << ".Sample(g_SamLinear, uv" << layer << ").a\n" - " * scaleBiasSpecular.x + scaleBiasSpecular.y;\n"; - outStream << " uv" << layer << " += TSeyeDir.xy * displacement;\n"; - } - - // access TS normal map - outStream << " TSnormal = expand(normtex" << layer << ".Sample(g_SamLinear, uv" << layer << ")).rgb;\n"; - outStream << " TShalfAngle = normalize(TSlightDir + TSeyeDir);\n"; - outStream << " litResLayer = lit(dot(TSlightDir, TSnormal), dot(TShalfAngle, TSnormal), scaleBiasSpecular.z);\n"; - if (!layer) - outStream << " litRes = litResLayer;\n"; - else - outStream << " litRes = lerp(litRes, litResLayer, " << blendWeightStr << ");\n"; - - } - - // sample diffuse texture - outStream << " float4 diffuseSpecTex" << layer - << " = difftex" << layer << ".Sample(g_SamLinear, uv" << layer << ");\n"; - - // apply to common - if (!layer) - { - outStream << " diffuse = diffuseSpecTex0.rgb;\n"; - if (prof->isLayerSpecularMappingEnabled()) - outStream << " specular = diffuseSpecTex0.a;\n"; - } - else - { - outStream << " diffuse = lerp(diffuse, diffuseSpecTex" << layer - << ".rgb, " << blendWeightStr << ");\n"; - if (prof->isLayerSpecularMappingEnabled()) - outStream << " specular = lerp(specular, diffuseSpecTex" << layer - << ".a, " << blendWeightStr << ");\n"; - - } - - // End early-out - /* Disable - causing some issues even when trying to force the use of texldd - if (layer && prof->_isSM3Available()) - outStream << " } // early-out blend value\n"; - */ - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpFooter( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - - if (tt == LOW_LOD) - { - if (prof->isShadowingEnabled(tt, terrain)) - { - generateFpDynamicShadows(prof, terrain, tt, outStream); - outStream << - " outputCol.rgb = diffuse * rtshadow;\n"; - } - else - { - outStream << - " outputCol.rgb = diffuse;\n"; - } - } - else - { - if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) - { - // sample colour map and apply to diffuse - outStream << " diffuse *= globalColourMap.Sample(g_SamClamp, uv).rgb;\n"; - } - if (prof->isLightmapEnabled()) - { - // sample lightmap - outStream << " shadow = lightMap.Sample(g_SamClamp, uv).r;\n"; - } - - if (prof->isShadowingEnabled(tt, terrain)) - { - generateFpDynamicShadows(prof, terrain, tt, outStream); - } - - // diffuse lighting - outStream << " outputCol.rgb += ambient.rgb * diffuse + litRes.y * lightDiffuseColour * diffuse * shadow;\n"; - - // specular default - if (!prof->isLayerSpecularMappingEnabled()) - outStream << " specular = 1.0;\n"; - - if (tt == RENDER_COMPOSITE_MAP) - { - // Lighting embedded in alpha - outStream << - " outputCol.a = shadow;\n"; - - } - else - { - // Apply specular - outStream << " outputCol.rgb += litRes.z * lightSpecularColour * specular * shadow;\n"; - - if (prof->getParent()->getDebugLevel()) - { - outStream << " outputCol.rg += input.lodInfo.xy;\n"; - } - } - } - - bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; - if (fog) - { - outStream << " outputCol.rgb = lerp(outputCol.rgb, fogColour, input.fogVal);\n"; - } - - // Final return - outStream << " return outputCol;\n" - << "}\n"; - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpDynamicShadowsHelpers( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - // TODO make filtering configurable - outStream << - "// Simple PCF \n" - "// Number of samples in one dimension (square for total samples) \n" - "#define NUM_SHADOW_SAMPLES_1D 2.0 \n" - "#define SHADOW_FILTER_SCALE 1 \n" - - "#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D \n" - - "float4 offsetSample(float4 uv, float2 offset, float invMapSize) \n" - "{ \n" - " return float4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w); \n" - "} \n"; - - // adding samplerstate for shadowmapping - outStream << - "SamplerState ShadowSampler\n" - "{\n" - " Filter = MIN_MAG_MIP_LINEAR;\n" - " AddressU = Wrap;\n" - " AddressV = Wrap;\n" - "};\n"; - - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - "float calcDepthShadow(Texture2D shadowMap, float4 uv, float invShadowMapSize) \n" - "{ \n" - " // 4-sample PCF \n" - - " float shadow = 0.0; \n" - " float offset = (NUM_SHADOW_SAMPLES_1D/2 - 0.5) * SHADOW_FILTER_SCALE; \n" - " for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE) \n" - " for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE) \n" - " { \n" - " float4 newUV = offsetSample(uv, float2(x, y), invShadowMapSize);\n" - " // manually project and assign derivatives \n" - " // to avoid gradient issues inside loops \n" - " newUV = newUV / newUV.w; \n" - " float depth = shadowMap.Sample(ShadowSampler, newUV.xy, 1, 1).x; \n" - " if (depth >= 1 || depth >= uv.z)\n" - " shadow += 1.0;\n" - " } \n" - - " shadow /= SHADOW_SAMPLES; \n" - - " return shadow; \n" - "} \n"; - } - else - { - outStream << - "float calcSimpleShadow(Texture2D shadowMap, float4 shadowMapPos) \n" - "{ \n" - " // return tex2Dproj(shadowMap,shadowMapPos); " - " return shadowMap.Sample(ShadowSampler, shadowMapPos.xy / shadowMapPos.w).x; \n" - "} \n"; - - } - - if (prof->getReceiveDynamicShadowsPSSM()) - { - uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - - - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - "float calcPSSMDepthShadow("; - } - else - { - outStream << - "float calcPSSMSimpleShadow("; - } - - outStream << "\n "; - for (uint i = 0; i < numTextures; ++i) - outStream << "Texture2D shadowMap" << i << ", "; - outStream << "\n "; - for (uint i = 0; i < numTextures; ++i) - outStream << "float4 lsPos" << i << ", "; - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << "\n "; - for (uint i = 0; i < numTextures; ++i) - outStream << "float invShadowmapSize" << i << ", "; - } - outStream << "\n" - " float4 pssmSplitPoints, float camDepth) \n" - "{ \n" - " float shadow; \n" - " // calculate shadow \n"; - - for (uint i = 0; i < numTextures; ++i) - { - if (!i) - outStream << " if (camDepth <= pssmSplitPoints." << ShaderHelper::getChannel(i) << ") \n"; - else if (i < numTextures - 1) - outStream << " else if (camDepth <= pssmSplitPoints." << ShaderHelper::getChannel(i) << ") \n"; - else - outStream << " else \n"; - - outStream << - " { \n"; - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - " shadow = calcDepthShadow(shadowMap" << i << ", lsPos" << i << ", invShadowmapSize" << i << "); \n"; - } - else - { - outStream << - " shadow = calcSimpleShadow(shadowMap" << i << ", lsPos" << i << "); \n"; - } - outStream << - " } \n"; - - } - - outStream << - " return shadow; \n" - "} \n\n\n"; - } - - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpDynamicShadowsParams( - uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - if (tt == HIGH_LOD) - mShadowSamplerStartHi = *sampler; - else if (tt == LOW_LOD) - mShadowSamplerStartLo = *sampler; - - // in semantics & params - uint numTextures = 1; - if (prof->getReceiveDynamicShadowsPSSM()) - { - numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - outStream << - ", uniform float4 pssmSplitPoints \n"; - } - for (uint i = 0; i < numTextures; ++i) - { - outStream << - ", uniform sampler2D shadowMap" << i << " : register(s" << *sampler << ") \n"; - *sampler = *sampler + 1; - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - ", uniform float inverseShadowmapSize" << i << " \n"; - } - } - - } - //--------------------------------------------------------------------- - void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpDynamicShadows( - const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) - { - if (prof->getReceiveDynamicShadowsPSSM()) - { - uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); - outStream << - " float camDepth = input.oUVMisc.z;\n"; - - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - " float rtshadow = calcPSSMDepthShadow("; - } - else - { - outStream << - " float rtshadow = calcPSSMSimpleShadow("; - } - for (uint i = 0; i < numTextures; ++i) - outStream << "shadowMap" << i << ", "; - outStream << "\n "; - - for (uint i = 0; i < numTextures; ++i) - outStream << "input.oLightSpacePos" << i << ", "; - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << "\n "; - for (uint i = 0; i < numTextures; ++i) - outStream << "inverseShadowmapSize" << i << ", "; - } - outStream << "\n" << - " pssmSplitPoints, camDepth);\n"; - - } - else - { - if (prof->getReceiveDynamicShadowsDepth()) - { - outStream << - " float rtshadow = calcDepthShadow(shadowMap0, input.oLightSpacePos0, inverseShadowmapSize0);"; - } - else - { - outStream << - " float rtshadow = calcSimpleShadow(shadowMap0, input.LightSpacePos0);"; - } - } - - outStream << - " shadow = min(shadow, rtshadow);\n"; - - } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + HighLevelGpuProgramPtr + TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::createVertexProgram( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) + { + HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); + String progName = getVertexProgramName(prof, terrain, tt); + + HighLevelGpuProgramPtr ret = mgr.getByName(progName); + if (ret.isNull()) + { + ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + "hlsl", GPT_VERTEX_PROGRAM); + } + else + { + ret->unload(); + } + // creating Shader Model 4.0 type hlsl shader fol DirectX11 Render System + if (prof->_isSM4Available()) + ret->setParameter("target", "vs_4_0"); + //else if (prof->_isSM3Available()) + // ret->setParameter("target", "vs_3_0"); + //else + // ret->setParameter("target", "vs_2_0"); + ret->setParameter("entry_point", "main_vp"); + + return ret; + + } + //--------------------------------------------------------------------- + HighLevelGpuProgramPtr + TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::createFragmentProgram( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt) + { + HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); + String progName = getFragmentProgramName(prof, terrain, tt); + + HighLevelGpuProgramPtr ret = mgr.getByName(progName); + if (ret.isNull()) + { + ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + "hlsl", GPT_FRAGMENT_PROGRAM); + } + else + { + ret->unload(); + } + // creating Shader Model 4.0 type hlsl shader fol DirectX11 Render System + if (prof->_isSM4Available()) + ret->setParameter("target", "ps_4_0"); + //else if (prof->_isSM3Available()) + // ret->setParameter("target", "ps_3_0"); + //else + // ret->setParameter("target", "ps_2_x"); + ret->setParameter("entry_point", "main_fp"); + + return ret; + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateVpHeader( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + // generate some structures needed for SM4 before the header + + // vertex shader output, pixel shader input struct. + outStream << + "struct v2p\n" + "{\n"; + + outStream << + "float4 oPos : SV_POSITION;\n" + "float4 oPosObj : TEXCOORD0; \n"; + + uint texCoordSet = 1; + outStream << + "float4 oUVMisc : TEXCOORD" << texCoordSet++ <<"; // xy = uv, z = camDepth\n"; + + // uv multipliers + uint maxLayers = prof->getMaxLayers(terrain); + uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); + uint numUVMultipliers = (numLayers / 4); + if (numLayers % 4) + ++numUVMultipliers; + + // layer UV's premultiplied, packed as xy/zw + uint numUVSets = numLayers / 2; + if (numLayers % 2) + ++numUVSets; + if (tt != LOW_LOD) + { + for (uint i = 0; i < numUVSets; ++i) + { + outStream << + "float4 oUV" << i << " : TEXCOORD" << texCoordSet++ << ";\n"; + } + } + + if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP) + { + outStream << "float2 lodInfo : TEXCOORD" << texCoordSet++ << ";\n"; + } + + bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; + if (fog) + { + outStream << "float fogVal : COLOR;\n"; + } + + uint numTextures = 1; + if (prof->getReceiveDynamicShadowsPSSM()) + { + numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + } + for (uint i = 0; i < numTextures; ++i) + { + outStream << + "float4 oLightSpacePos" << i << " : TEXCOORD" << texCoordSet++ << " ;\n"; + } + + outStream << "};\n"; + //output/input structure finished + + outStream << + "v2p main_vp(\n"; + bool compression = terrain->_getUseVertexCompression() && tt != RENDER_COMPOSITE_MAP; + if (compression) + { + outStream << + "float2 posIndex : POSITION,\n" + "float height : TEXCOORD0,\n"; + } + else + { + outStream << + "float4 pos : POSITION,\n" + "float2 uv : TEXCOORD0,\n"; + + } + if (tt != RENDER_COMPOSITE_MAP) + outStream << "float2 delta : TEXCOORD1,\n"; // lodDelta, lodThreshold + + outStream << + "uniform matrix worldMatrix,\n" + "uniform matrix viewProjMatrix,\n" + "uniform float2 lodMorph,\n"; // morph amount, morph LOD target + + if (compression) + { + outStream << + "uniform matrix posIndexToObjectSpace,\n" + "uniform float baseUVScale,\n"; + } + + for (uint i = 0; i < numUVMultipliers - 1; ++i) + outStream << "uniform float4 uvMul_" << i << ", \n"; + outStream << "uniform float4 uvMul_" << numUVMultipliers - 1 << " \n"; + + if (fog) + { + outStream << + ", uniform float4 fogParams\n"; + } + + if (prof->isShadowingEnabled(tt, terrain)) + { + texCoordSet = generateVpDynamicShadowsParams(texCoordSet, prof, terrain, tt, outStream); + } + + // check we haven't exceeded texture coordinates + if (texCoordSet > 8) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Requested options require too many texture coordinate sets! Try reducing the number of layers.", + __FUNCTION__); + } + + outStream << + ")\n" + "{\n"; + if (compression) + { + outStream << + " float4 pos;\n" + " pos = mul(posIndexToObjectSpace, float4(posIndex, height, 1));\n" + " float2 uv = float2(posIndex.x * baseUVScale, 1.0 - (posIndex.y * baseUVScale));\n"; + } + outStream << + " float4 worldPos = mul(worldMatrix, pos);\n" + " v2p output;\n" + " output.oPosObj = pos;\n"; + + if (tt != RENDER_COMPOSITE_MAP) + { + // determine whether to apply the LOD morph to this vertex + // we store the deltas against all vertices so we only want to apply + // the morph to the ones which would disappear. The target LOD which is + // being morphed to is stored in lodMorph.y, and the LOD at which + // the vertex should be morphed is stored in uv.w. If we subtract + // the former from the latter, and arrange to only morph if the + // result is negative (it will only be -1 in fact, since after that + // the vertex will never be indexed), we will achieve our aim. + // sign(vertexLOD - targetLOD) == -1 is to morph + outStream << + " float toMorph = -min(0, sign(delta.y - lodMorph.y));\n"; + // this will either be 1 (morph) or 0 (don't morph) + if (prof->getParent()->getDebugLevel()) + { + // x == LOD level (-1 since value is target level, we want to display actual) + outStream << "output.lodInfo.x = (lodMorph.y - 1) / " << terrain->getNumLodLevels() << ";\n"; + // y == LOD morph + outStream << "output.lodInfo.y = toMorph * lodMorph.x;\n"; + } + + // morph + switch (terrain->getAlignment()) + { + case Terrain::ALIGN_X_Y: + outStream << " worldPos.z += delta.x * toMorph * lodMorph.x;\n"; + break; + case Terrain::ALIGN_X_Z: + outStream << " worldPos.y += delta.x * toMorph * lodMorph.x;\n"; + break; + case Terrain::ALIGN_Y_Z: + outStream << " worldPos.x += delta.x * toMorph * lodMorph.x;\n"; + break; + }; + } + + + // generate UVs + if (tt != LOW_LOD) + { + for (uint i = 0; i < numUVSets; ++i) + { + uint layer = i * 2; + uint uvMulIdx = layer / 4; + + outStream << + " output.oUV" << i << ".xy = " << " uv.xy * uvMul_" << uvMulIdx << "." << getChannel(layer) << ";\n"; + outStream << + " output.oUV" << i << ".zw = " << " uv.xy * uvMul_" << uvMulIdx << "." << getChannel(layer+1) << ";\n"; + + } + + } + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateVpLayer( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) + { + // nothing to do + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateVpFooter( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + + outStream << + " output.oPos = mul(viewProjMatrix, worldPos);\n" + " output.oUVMisc.xy = uv.xy;\n"; + + bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; + if (fog) + { + if (terrain->getSceneManager()->getFogMode() == FOG_LINEAR) + { + outStream << + " output.fogVal = saturate((output.oPos.z - fogParams.y) * fogParams.w);\n"; + } + else + { + outStream << + " output.fogVal = 1 - saturate(1 / (exp(output.oPos.z * fogParams.x)));\n"; + } + } + + if (prof->isShadowingEnabled(tt, terrain)) + generateVpDynamicShadows(prof, terrain, tt, outStream); + + outStream << + "return output;" + "}\n"; + + } + //--------------------------------------------------------------------- + uint TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateVpDynamicShadowsParams( + uint texCoord, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + // out semantics & params + uint numTextures = 1; + if (prof->getReceiveDynamicShadowsPSSM()) + { + numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + } + for (uint i = 0; i < numTextures; ++i) + { + outStream << + ", uniform matrix texViewProjMatrix" << i << " \n"; + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + ", uniform float4 depthRange" << i << " // x = min, y = max, z = range, w = 1/range \n"; + } + } + + return texCoord; + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateVpDynamicShadows( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + uint numTextures = 1; + if (prof->getReceiveDynamicShadowsPSSM()) + { + numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + } + + // Calculate the position of vertex in light space + for (uint i = 0; i < numTextures; ++i) + { + outStream << + " output.oLightSpacePos" << i << " = mul(texViewProjMatrix" << i << ", worldPos); \n"; + if (prof->getReceiveDynamicShadowsDepth()) + { + // make linear + outStream << + "output.oLightSpacePos" << i << ".z = (output.oLightSpacePos" << i << ".z - depthRange" << i << ".x) * depthRange" << i << ".w;\n"; + + } + } + + + if (prof->getReceiveDynamicShadowsPSSM()) + { + outStream << + " // pass cam depth\n" + " output.oUVMisc.z = output.oPos.z;\n"; + } + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpHeader( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + // adding samplerstate for shadowmapping + outStream << + "SamplerState g_SamLinear\n" + "{\n" + " Filter = MIN_MAG_MIP_LINEAR;\n" + " AddressU = Wrap;\n" + " AddressV = Wrap;\n" + "};\n" + "SamplerState g_SamClamp\n" + "{\n" + " Filter = MIN_MAG_MIP_LINEAR;\n" + " AddressU = Clamp;\n" + " AddressV = Clamp;\n" + "};\n" + ; + + // Main header + outStream << + // helpers + "float4 expand(float4 v)\n" + "{ \n" + " return v * 2 - 1;\n" + "}\n\n\n"; + + if (prof->isShadowingEnabled(tt, terrain)) + generateFpDynamicShadowsHelpers(prof, terrain, tt, outStream); + + // vertex shader output, pixel shader input struct. + outStream << + "struct v2p\n" + "{\n"; + + outStream << + "float4 oPos : SV_POSITION;\n" + "float4 oPosObj : TEXCOORD0; \n"; + + uint texCoordSet = 1; + outStream << + "float4 oUVMisc : TEXCOORD" << texCoordSet++ <<"; // xy = uv, z = camDepth\n"; + + // uv multipliers + uint maxLayers = prof->getMaxLayers(terrain); + uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); + uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount()); + uint numUVMultipliers = (numLayers / 4); + if (numLayers % 4) + ++numUVMultipliers; + + // layer UV's premultiplied, packed as xy/zw + uint numUVSets = numLayers / 2; + if (numLayers % 2) + ++numUVSets; + if (tt != LOW_LOD) + { + for (uint i = 0; i < numUVSets; ++i) + { + outStream << + "float4 oUV" << i << " : TEXCOORD" << texCoordSet++ << ";\n"; + } + } + + if (prof->getParent()->getDebugLevel() && tt != RENDER_COMPOSITE_MAP) + { + outStream << "float2 lodInfo : TEXCOORD" << texCoordSet++ << ";\n"; + } + + bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; + if (fog) + { + outStream << "float fogVal : COLOR;\n"; + } + + uint numTextures = 1; + if (prof->getReceiveDynamicShadowsPSSM()) + { + numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + } + for (uint i = 0; i < numTextures; ++i) + { + outStream << + "float4 oLightSpacePos" << i << " : TEXCOORD" << texCoordSet++ << " ;\n"; + } + + outStream << "};\n"; + //output/input structure finished + + uint currentSamplerIdx = 0; + if (tt == LOW_LOD) + { + // single composite map covers all the others below + outStream << + "Texture2D compositeMap : register(s" << currentSamplerIdx++ << ");\n"; + } + else + { + outStream << + "Texture2D globalNormal : register(s" << currentSamplerIdx++ << ");\n"; + + + if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) + { + outStream << "Texture2D globalColourMap : register(s" + << currentSamplerIdx++ << ");\n"; + } + if (prof->isLightmapEnabled()) + { + outStream << "Texture2D lightMap : register(s" + << currentSamplerIdx++ << ");\n"; + } + // Blend textures - sampler definitions + for (uint i = 0; i < numBlendTextures; ++i) + { + outStream << "Texture2D blendTex" << i + << " : register(s" << currentSamplerIdx++ << ");\n"; + } + + // Layer textures - sampler definitions & UV multipliers + for (uint i = 0; i < numLayers; ++i) + { + outStream << "Texture2D difftex" << i + << " : register(s" << currentSamplerIdx++ << ");\n"; + outStream << "Texture2D normtex" << i + << " : register(s" << currentSamplerIdx++ << ");\n"; + } + } + + outStream << + "float4 main_fp(\n" + "v2p input,\n"; + + if (fog) + { + outStream << + "uniform float3 fogColour, \n"; + } + + outStream << + // Only 1 light supported in this version + // deferred shading profile / generator later, ok? :) + "uniform float3 ambient,\n" + "uniform float4 lightPosObjSpace,\n" + "uniform float3 lightDiffuseColour,\n" + "uniform float3 lightSpecularColour,\n" + "uniform float3 eyePosObjSpace,\n" + // pack scale, bias and specular + "uniform float4 scaleBiasSpecular\n"; + + if (prof->isShadowingEnabled(tt, terrain)) + { + generateFpDynamicShadowsParams(&texCoordSet, ¤tSamplerIdx, prof, terrain, tt, outStream); + } + + // check we haven't exceeded samplers + if (currentSamplerIdx > 16) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Requested options require too many texture samplers! Try reducing the number of layers.", + __FUNCTION__); + } + + outStream << + ") : SV_Target\n" + "{\n" + " float4 outputCol;\n" + " float shadow = 1.0;\n" + " float2 uv = input.oUVMisc.xy;\n" + // base colour + " outputCol = float4(0.0,0.0,0.0,1.0);\n"; + + if (tt != LOW_LOD) + { + outStream << + // global normal + " float3 normal = expand(globalNormal.Sample(g_SamClamp, uv)).rgb;\n"; + + } + + outStream << + " float3 lightDir = \n" + " lightPosObjSpace.xyz - (input.oPosObj.xyz * lightPosObjSpace.w);\n" + " float3 eyeDir = eyePosObjSpace - input.oPosObj.xyz;\n" + + // set up accumulation areas + " float3 diffuse = float3(0,0,0);\n" + " float specular = 0;\n"; + + + if (tt == LOW_LOD) + { + // we just do a single calculation from composite map + outStream << + " float4 composite = compositeMap.Sample(g_SamClamp, uv);\n" + " diffuse = composite.rgb;\n"; + // TODO - specular; we'll need normals for this! + } + else + { + // set up the blend values + for (uint i = 0; i < numBlendTextures; ++i) + { + outStream << " float4 blendTexVal" << i << " = blendTex" << i << ".Sample(g_SamClamp, uv);\n"; + } + + if (prof->isLayerNormalMappingEnabled()) + { + // derive the tangent space basis + // we do this in the pixel shader because we don't have per-vertex normals + // because of the LOD, we use a normal map + // tangent is always +x or -z in object space depending on alignment + switch(terrain->getAlignment()) + { + case Terrain::ALIGN_X_Y: + case Terrain::ALIGN_X_Z: + outStream << " float3 tangent = float3(1, 0, 0);\n"; + break; + case Terrain::ALIGN_Y_Z: + outStream << " float3 tangent = float3(0, 0, -1);\n"; + break; + }; + + outStream << " float3 binormal = normalize(cross(tangent, normal));\n"; + // note, now we need to re-cross to derive tangent again because it wasn't orthonormal + outStream << " tangent = normalize(cross(normal, binormal));\n"; + // derive final matrix + outStream << " float3x3 TBN = float3x3(tangent, binormal, normal);\n"; + + // set up lighting result placeholders for interpolation + outStream << " float4 litRes, litResLayer;\n"; + outStream << " float3 TSlightDir, TSeyeDir, TShalfAngle, TSnormal;\n"; + if (prof->isLayerParallaxMappingEnabled()) + outStream << " float displacement;\n"; + // move + outStream << " TSlightDir = normalize(mul(TBN, lightDir));\n"; + outStream << " TSeyeDir = normalize(mul(TBN, eyeDir));\n"; + + } + else + { + // simple per-pixel lighting with no normal mapping + outStream << " lightDir = normalize(lightDir);\n"; + outStream << " eyeDir = normalize(eyeDir);\n"; + outStream << " float3 halfAngle = normalize(lightDir + eyeDir);\n"; + outStream << " float4 litRes = lit(dot(lightDir, normal), dot(halfAngle, normal), scaleBiasSpecular.z);\n"; + + } + } + + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpLayer( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, uint layer, StringStream& outStream) + { + uint uvIdx = layer / 2; + String uvChannels = (layer % 2) ? ".zw" : ".xy"; + uint blendIdx = (layer-1) / 4; + String blendChannel = getChannel(layer-1); + String blendWeightStr = String("blendTexVal") + StringConverter::toString(blendIdx) + + "." + blendChannel; + + // generate early-out conditional + /* Disable - causing some issues even when trying to force the use of texldd + if (layer && prof->_isSM3Available()) + outStream << " if (" << blendWeightStr << " > 0.0003)\n { \n"; + */ + + // generate UV + outStream << " float2 uv" << layer << " = input.oUV" << uvIdx << uvChannels << ";\n"; + + // calculate lighting here if normal mapping + if (prof->isLayerNormalMappingEnabled()) + { + if (prof->isLayerParallaxMappingEnabled() && tt != RENDER_COMPOSITE_MAP) + { + // modify UV - note we have to sample an extra time + outStream << " displacement = normtex" << layer << ".Sample(g_SamLinear, uv" << layer << ").a\n" + " * scaleBiasSpecular.x + scaleBiasSpecular.y;\n"; + outStream << " uv" << layer << " += TSeyeDir.xy * displacement;\n"; + } + + // access TS normal map + outStream << " TSnormal = expand(normtex" << layer << ".Sample(g_SamLinear, uv" << layer << ")).rgb;\n"; + outStream << " TShalfAngle = normalize(TSlightDir + TSeyeDir);\n"; + outStream << " litResLayer = lit(dot(TSlightDir, TSnormal), dot(TShalfAngle, TSnormal), scaleBiasSpecular.z);\n"; + if (!layer) + outStream << " litRes = litResLayer;\n"; + else + outStream << " litRes = lerp(litRes, litResLayer, " << blendWeightStr << ");\n"; + + } + + // sample diffuse texture + outStream << " float4 diffuseSpecTex" << layer + << " = difftex" << layer << ".Sample(g_SamLinear, uv" << layer << ");\n"; + + // apply to common + if (!layer) + { + outStream << " diffuse = diffuseSpecTex0.rgb;\n"; + if (prof->isLayerSpecularMappingEnabled()) + outStream << " specular = diffuseSpecTex0.a;\n"; + } + else + { + outStream << " diffuse = lerp(diffuse, diffuseSpecTex" << layer + << ".rgb, " << blendWeightStr << ");\n"; + if (prof->isLayerSpecularMappingEnabled()) + outStream << " specular = lerp(specular, diffuseSpecTex" << layer + << ".a, " << blendWeightStr << ");\n"; + + } + + // End early-out + /* Disable - causing some issues even when trying to force the use of texldd + if (layer && prof->_isSM3Available()) + outStream << " } // early-out blend value\n"; + */ + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpFooter( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + + if (tt == LOW_LOD) + { + if (prof->isShadowingEnabled(tt, terrain)) + { + generateFpDynamicShadows(prof, terrain, tt, outStream); + outStream << + " outputCol.rgb = diffuse * rtshadow;\n"; + } + else + { + outStream << + " outputCol.rgb = diffuse;\n"; + } + } + else + { + if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled()) + { + // sample colour map and apply to diffuse + outStream << " diffuse *= globalColourMap.Sample(g_SamClamp, uv).rgb;\n"; + } + if (prof->isLightmapEnabled()) + { + // sample lightmap + outStream << " shadow = lightMap.Sample(g_SamClamp, uv).r;\n"; + } + + if (prof->isShadowingEnabled(tt, terrain)) + { + generateFpDynamicShadows(prof, terrain, tt, outStream); + } + + // diffuse lighting + outStream << " outputCol.rgb += ambient.rgb * diffuse + litRes.y * lightDiffuseColour * diffuse * shadow;\n"; + + // specular default + if (!prof->isLayerSpecularMappingEnabled()) + outStream << " specular = 1.0;\n"; + + if (tt == RENDER_COMPOSITE_MAP) + { + // Lighting embedded in alpha + outStream << + " outputCol.a = shadow;\n"; + + } + else + { + // Apply specular + outStream << " outputCol.rgb += litRes.z * lightSpecularColour * specular * shadow;\n"; + + if (prof->getParent()->getDebugLevel()) + { + outStream << " outputCol.rg += input.lodInfo.xy;\n"; + } + } + } + + bool fog = terrain->getSceneManager()->getFogMode() != FOG_NONE && tt != RENDER_COMPOSITE_MAP; + if (fog) + { + outStream << " outputCol.rgb = lerp(outputCol.rgb, fogColour, input.fogVal);\n"; + } + + // Final return + outStream << " return outputCol;\n" + << "}\n"; + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpDynamicShadowsHelpers( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + // TODO make filtering configurable + outStream << + "// Simple PCF \n" + "// Number of samples in one dimension (square for total samples) \n" + "#define NUM_SHADOW_SAMPLES_1D 2.0 \n" + "#define SHADOW_FILTER_SCALE 1 \n" + + "#define SHADOW_SAMPLES NUM_SHADOW_SAMPLES_1D*NUM_SHADOW_SAMPLES_1D \n" + + "float4 offsetSample(float4 uv, float2 offset, float invMapSize) \n" + "{ \n" + " return float4(uv.xy + offset * invMapSize * uv.w, uv.z, uv.w); \n" + "} \n"; + + // adding samplerstate for shadowmapping + outStream << + "SamplerState ShadowSampler\n" + "{\n" + " Filter = MIN_MAG_MIP_LINEAR;\n" + " AddressU = Wrap;\n" + " AddressV = Wrap;\n" + "};\n"; + + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + "float calcDepthShadow(Texture2D shadowMap, float4 uv, float invShadowMapSize) \n" + "{ \n" + " // 4-sample PCF \n" + + " float shadow = 0.0; \n" + " float offset = (NUM_SHADOW_SAMPLES_1D/2 - 0.5) * SHADOW_FILTER_SCALE; \n" + " for (float y = -offset; y <= offset; y += SHADOW_FILTER_SCALE) \n" + " for (float x = -offset; x <= offset; x += SHADOW_FILTER_SCALE) \n" + " { \n" + " float4 newUV = offsetSample(uv, float2(x, y), invShadowMapSize);\n" + " // manually project and assign derivatives \n" + " // to avoid gradient issues inside loops \n" + " newUV = newUV / newUV.w; \n" + " float depth = shadowMap.Sample(ShadowSampler, newUV.xy, 1, 1).x; \n" + " if (depth >= 1 || depth >= uv.z)\n" + " shadow += 1.0;\n" + " } \n" + + " shadow /= SHADOW_SAMPLES; \n" + + " return shadow; \n" + "} \n"; + } + else + { + outStream << + "float calcSimpleShadow(Texture2D shadowMap, float4 shadowMapPos) \n" + "{ \n" + " // return tex2Dproj(shadowMap,shadowMapPos); " + " return shadowMap.Sample(ShadowSampler, shadowMapPos.xy / shadowMapPos.w).x; \n" + "} \n"; + + } + + if (prof->getReceiveDynamicShadowsPSSM()) + { + uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + + + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + "float calcPSSMDepthShadow("; + } + else + { + outStream << + "float calcPSSMSimpleShadow("; + } + + outStream << "\n "; + for (uint i = 0; i < numTextures; ++i) + outStream << "Texture2D shadowMap" << i << ", "; + outStream << "\n "; + for (uint i = 0; i < numTextures; ++i) + outStream << "float4 lsPos" << i << ", "; + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << "\n "; + for (uint i = 0; i < numTextures; ++i) + outStream << "float invShadowmapSize" << i << ", "; + } + outStream << "\n" + " float4 pssmSplitPoints, float camDepth) \n" + "{ \n" + " float shadow; \n" + " // calculate shadow \n"; + + for (uint i = 0; i < numTextures; ++i) + { + if (!i) + outStream << " if (camDepth <= pssmSplitPoints." << ShaderHelper::getChannel(i) << ") \n"; + else if (i < numTextures - 1) + outStream << " else if (camDepth <= pssmSplitPoints." << ShaderHelper::getChannel(i) << ") \n"; + else + outStream << " else \n"; + + outStream << + " { \n"; + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + " shadow = calcDepthShadow(shadowMap" << i << ", lsPos" << i << ", invShadowmapSize" << i << "); \n"; + } + else + { + outStream << + " shadow = calcSimpleShadow(shadowMap" << i << ", lsPos" << i << "); \n"; + } + outStream << + " } \n"; + + } + + outStream << + " return shadow; \n" + "} \n\n\n"; + } + + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpDynamicShadowsParams( + uint* texCoord, uint* sampler, const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + if (tt == HIGH_LOD) + mShadowSamplerStartHi = *sampler; + else if (tt == LOW_LOD) + mShadowSamplerStartLo = *sampler; + + // in semantics & params + uint numTextures = 1; + if (prof->getReceiveDynamicShadowsPSSM()) + { + numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + outStream << + ", uniform float4 pssmSplitPoints \n"; + } + for (uint i = 0; i < numTextures; ++i) + { + outStream << + ", uniform sampler2D shadowMap" << i << " : register(s" << *sampler << ") \n"; + *sampler = *sampler + 1; + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + ", uniform float inverseShadowmapSize" << i << " \n"; + } + } + + } + //--------------------------------------------------------------------- + void TerrainMaterialGeneratorA::SM2Profile::ShaderHelperHLSL::generateFpDynamicShadows( + const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, StringStream& outStream) + { + if (prof->getReceiveDynamicShadowsPSSM()) + { + uint numTextures = prof->getReceiveDynamicShadowsPSSM()->getSplitCount(); + outStream << + " float camDepth = input.oUVMisc.z;\n"; + + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + " float rtshadow = calcPSSMDepthShadow("; + } + else + { + outStream << + " float rtshadow = calcPSSMSimpleShadow("; + } + for (uint i = 0; i < numTextures; ++i) + outStream << "shadowMap" << i << ", "; + outStream << "\n "; + + for (uint i = 0; i < numTextures; ++i) + outStream << "input.oLightSpacePos" << i << ", "; + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << "\n "; + for (uint i = 0; i < numTextures; ++i) + outStream << "inverseShadowmapSize" << i << ", "; + } + outStream << "\n" << + " pssmSplitPoints, camDepth);\n"; + + } + else + { + if (prof->getReceiveDynamicShadowsDepth()) + { + outStream << + " float rtshadow = calcDepthShadow(shadowMap0, input.oLightSpacePos0, inverseShadowmapSize0);"; + } + else + { + outStream << + " float rtshadow = calcSimpleShadow(shadowMap0, input.LightSpacePos0);"; + } + } + + outStream << + " shadow = min(shadow, rtshadow);\n"; + + } } diff --git a/Components/Terrain/src/OgreTerrainPagedWorldSection.cpp b/Components/Terrain/src/OgreTerrainPagedWorldSection.cpp index e6bf2ba896b..362a781cfe1 100644 --- a/Components/Terrain/src/OgreTerrainPagedWorldSection.cpp +++ b/Components/Terrain/src/OgreTerrainPagedWorldSection.cpp @@ -35,301 +35,301 @@ THE SOFTWARE. namespace Ogre { - const uint16 TerrainPagedWorldSection::WORKQUEUE_LOAD_TERRAIN_PAGE_REQUEST = 1; - - //--------------------------------------------------------------------- - TerrainPagedWorldSection::TerrainPagedWorldSection(const String& name, PagedWorld* parent, SceneManager* sm) - : PagedWorldSection(name, parent, sm) - , mTerrainGroup(0) - , mTerrainDefiner(0) - , mHasRunningTasks(false) - , mLoadingIntervalMs(900) - { - // we always use a grid strategy - setStrategy(parent->getManager()->getStrategy("Grid2D")); - - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - mWorkQueueChannel = wq->getChannel("Ogre/TerrainPagedWorldSection"); - wq->addRequestHandler(mWorkQueueChannel, this); - wq->addResponseHandler(mWorkQueueChannel, this); - - mNextLoadingTime = Root::getSingletonPtr()->getTimer()->getMilliseconds(); - } - //--------------------------------------------------------------------- - TerrainPagedWorldSection::~TerrainPagedWorldSection() - { - //remove the pending tasks, but keep the front one, as it may have been in running - if(!mPagesInLoading.empty()) - mPagesInLoading.erase( ++mPagesInLoading.begin(), mPagesInLoading.end() ); - - while(!mPagesInLoading.empty()) - { - OGRE_THREAD_SLEEP(50); - Root::getSingleton().getWorkQueue()->processResponses(); - } - - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - wq->removeRequestHandler(mWorkQueueChannel, this); - wq->removeResponseHandler(mWorkQueueChannel, this); - - OGRE_DELETE mTerrainGroup; - if(mTerrainDefiner) - OGRE_DELETE mTerrainDefiner; - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::init(TerrainGroup* grp) - { - if (mTerrainGroup == grp) - return; - - if (mTerrainGroup) - OGRE_DELETE mTerrainGroup; - - mTerrainGroup = grp; - syncSettings(); - - // Unload all existing terrain pages, because we want the paging system - // to be in charge of this - mTerrainGroup->removeAllTerrains(); - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::syncSettings() - { - - // Base grid on terrain settings - Grid2DPageStrategyData* gridData = getGridStrategyData(); - switch (mTerrainGroup->getAlignment()) - { - case Terrain::ALIGN_X_Y: - gridData->setMode(G2D_X_Y); - break; - case Terrain::ALIGN_X_Z: - gridData->setMode(G2D_X_Z); - break; - case Terrain::ALIGN_Y_Z: - gridData->setMode(G2D_Y_Z); - break; - } - gridData->setOrigin(mTerrainGroup->getOrigin()); - - gridData->setCellSize(mTerrainGroup->getTerrainWorldSize()); - - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::setLoadRadius(Real sz) - { - getGridStrategyData()->setLoadRadius(sz); - } - //--------------------------------------------------------------------- - Real TerrainPagedWorldSection::getLoadRadius() const - { - return getGridStrategyData()->getLoadRadius(); - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::setHoldRadius(Real sz) - { - getGridStrategyData()->setHoldRadius(sz); - } - //--------------------------------------------------------------------- - Real TerrainPagedWorldSection::getHoldRadius() - { - return getGridStrategyData()->getHoldRadius(); - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::setPageRange(int32 minX, int32 minY, int32 maxX, int32 maxY) - { - getGridStrategyData()->setCellRange(minX, minY, maxX, maxY); - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::setPageRangeMinX(int32 minX) - { - getGridStrategyData()->setCellRangeMinX(minX); - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::setPageRangeMinY(int32 minY) - { - getGridStrategyData()->setCellRangeMinY(minY); - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::setPageRangeMaxX(int32 maxX) - { - getGridStrategyData()->setCellRangeMaxX(maxX); - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::setPageRangeMaxY(int32 maxY) - { - getGridStrategyData()->setCellRangeMaxY(maxY); - } - //--------------------------------------------------------------------- - int32 TerrainPagedWorldSection::getPageRangeMinX() const - { - return getGridStrategyData()->getCellRangeMinX(); - } - //--------------------------------------------------------------------- - int32 TerrainPagedWorldSection::getPageRangeMinY() const - { - return getGridStrategyData()->getCellRangeMinY(); - } - //--------------------------------------------------------------------- - int32 TerrainPagedWorldSection::getPageRangeMaxX() const - { - return getGridStrategyData()->getCellRangeMaxX(); - } - //--------------------------------------------------------------------- - int32 TerrainPagedWorldSection::getPageRangeMaxY() const - { - return getGridStrategyData()->getCellRangeMaxY(); - } - //--------------------------------------------------------------------- - Grid2DPageStrategy* TerrainPagedWorldSection::getGridStrategy() const - { - return static_cast(this->getStrategy()); - } - //--------------------------------------------------------------------- - Grid2DPageStrategyData* TerrainPagedWorldSection::getGridStrategyData() const - { - return static_cast(mStrategyData); - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::setLoadingIntervalMs(uint32 loadingIntervalMs) - { - mLoadingIntervalMs = loadingIntervalMs; - } - //--------------------------------------------------------------------- - uint32 TerrainPagedWorldSection::getLoadingIntervalMs() const - { - return mLoadingIntervalMs; - } - - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::loadSubtypeData(StreamSerialiser& ser) - { - // we load the TerrainGroup information from here - if (!mTerrainGroup) - mTerrainGroup = OGRE_NEW TerrainGroup(getSceneManager()); - - mTerrainGroup->loadGroupDefinition(ser); - - // params that are in the Grid2DStrategyData will have already been loaded - // as part of the main load() routine - - syncSettings(); - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::saveSubtypeData(StreamSerialiser& ser) - { - mTerrainGroup->saveGroupDefinition(ser); - - // params that are in the Grid2DStrategyData will have already been saved - // as part of the main save() routine - - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::loadPage(PageID pageID, bool forceSynchronous) - { - if (!mParent->getManager()->getPagingOperationsEnabled()) - return; - - PageMap::iterator i = mPages.find(pageID); - if (i == mPages.end()) - { - std::list::iterator it = find( mPagesInLoading.begin(), mPagesInLoading.end(), pageID); - if(it==mPagesInLoading.end()) - { - mPagesInLoading.push_back(pageID); - mHasRunningTasks = true; - } - - // no running tasks, start the new one - if(mPagesInLoading.size()==1) - { - Root::getSingleton().getWorkQueue()->addRequest( - mWorkQueueChannel, WORKQUEUE_LOAD_TERRAIN_PAGE_REQUEST, - Any(), 0, forceSynchronous); - } - } - - PagedWorldSection::loadPage(pageID, forceSynchronous); - } - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::unloadPage(PageID pageID, bool forceSynchronous) - { - if (!mParent->getManager()->getPagingOperationsEnabled()) - return; - - PagedWorldSection::unloadPage(pageID, forceSynchronous); - - std::list::iterator it = find( mPagesInLoading.begin(), mPagesInLoading.end(), pageID); - // hasn't been loaded, just remove from the queue - if(it!=mPagesInLoading.end()) - { - mPagesInLoading.erase(it); - } - else - { - // trigger terrain unload - long x, y; - // pageID is the same as a packed index - mTerrainGroup->unpackIndex(pageID, &x, &y); - mTerrainGroup->unloadTerrain(x, y); - } - } - //--------------------------------------------------------------------- - WorkQueue::Response* TerrainPagedWorldSection::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - if(mPagesInLoading.empty()) - { - mHasRunningTasks = false; - req->abortRequest(); - return OGRE_NEW WorkQueue::Response(req, true, Any()); - } - - unsigned long currentTime = Root::getSingletonPtr()->getTimer()->getMilliseconds(); - if(currentTime < mNextLoadingTime) - { - // Wait until the next page is to be loaded -> we are in background thread here - OGRE_THREAD_SLEEP(mNextLoadingTime - currentTime); - } - - PageID pageID = mPagesInLoading.front(); - - // call the TerrainDefiner from the background thread - long x, y; - // pageID is the same as a packed index - mTerrainGroup->unpackIndex(pageID, &x, &y); - - if(!mTerrainDefiner) - mTerrainDefiner = OGRE_NEW TerrainDefiner(); - mTerrainDefiner->define(mTerrainGroup, x, y); - - // continue loading in main thread - return OGRE_NEW WorkQueue::Response(req, true, Any()); - } - - //--------------------------------------------------------------------- - void TerrainPagedWorldSection::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - PageID pageID = mPagesInLoading.front(); - - // trigger terrain load - long x, y; - // pageID is the same as a packed index - mTerrainGroup->unpackIndex(pageID, &x, &y); - mTerrainGroup->loadTerrain(x, y, false); - mPagesInLoading.pop_front(); - - unsigned long currentTime = Root::getSingletonPtr()->getTimer()->getMilliseconds(); - mNextLoadingTime = currentTime + mLoadingIntervalMs; - - if(!mPagesInLoading.empty()) - { - // Continue loading other pages - Root::getSingleton().getWorkQueue()->addRequest( - mWorkQueueChannel, WORKQUEUE_LOAD_TERRAIN_PAGE_REQUEST, - Any(), 0, false); - } - else - mHasRunningTasks = false; - } + const uint16 TerrainPagedWorldSection::WORKQUEUE_LOAD_TERRAIN_PAGE_REQUEST = 1; + + //--------------------------------------------------------------------- + TerrainPagedWorldSection::TerrainPagedWorldSection(const String& name, PagedWorld* parent, SceneManager* sm) + : PagedWorldSection(name, parent, sm) + , mTerrainGroup(0) + , mTerrainDefiner(0) + , mHasRunningTasks(false) + , mLoadingIntervalMs(900) + { + // we always use a grid strategy + setStrategy(parent->getManager()->getStrategy("Grid2D")); + + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + mWorkQueueChannel = wq->getChannel("Ogre/TerrainPagedWorldSection"); + wq->addRequestHandler(mWorkQueueChannel, this); + wq->addResponseHandler(mWorkQueueChannel, this); + + mNextLoadingTime = Root::getSingletonPtr()->getTimer()->getMilliseconds(); + } + //--------------------------------------------------------------------- + TerrainPagedWorldSection::~TerrainPagedWorldSection() + { + //remove the pending tasks, but keep the front one, as it may have been in running + if(!mPagesInLoading.empty()) + mPagesInLoading.erase( ++mPagesInLoading.begin(), mPagesInLoading.end() ); + + while(!mPagesInLoading.empty()) + { + OGRE_THREAD_SLEEP(50); + Root::getSingleton().getWorkQueue()->processResponses(); + } + + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + wq->removeRequestHandler(mWorkQueueChannel, this); + wq->removeResponseHandler(mWorkQueueChannel, this); + + OGRE_DELETE mTerrainGroup; + if(mTerrainDefiner) + OGRE_DELETE mTerrainDefiner; + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::init(TerrainGroup* grp) + { + if (mTerrainGroup == grp) + return; + + if (mTerrainGroup) + OGRE_DELETE mTerrainGroup; + + mTerrainGroup = grp; + syncSettings(); + + // Unload all existing terrain pages, because we want the paging system + // to be in charge of this + mTerrainGroup->removeAllTerrains(); + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::syncSettings() + { + + // Base grid on terrain settings + Grid2DPageStrategyData* gridData = getGridStrategyData(); + switch (mTerrainGroup->getAlignment()) + { + case Terrain::ALIGN_X_Y: + gridData->setMode(G2D_X_Y); + break; + case Terrain::ALIGN_X_Z: + gridData->setMode(G2D_X_Z); + break; + case Terrain::ALIGN_Y_Z: + gridData->setMode(G2D_Y_Z); + break; + } + gridData->setOrigin(mTerrainGroup->getOrigin()); + + gridData->setCellSize(mTerrainGroup->getTerrainWorldSize()); + + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::setLoadRadius(Real sz) + { + getGridStrategyData()->setLoadRadius(sz); + } + //--------------------------------------------------------------------- + Real TerrainPagedWorldSection::getLoadRadius() const + { + return getGridStrategyData()->getLoadRadius(); + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::setHoldRadius(Real sz) + { + getGridStrategyData()->setHoldRadius(sz); + } + //--------------------------------------------------------------------- + Real TerrainPagedWorldSection::getHoldRadius() + { + return getGridStrategyData()->getHoldRadius(); + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::setPageRange(int32 minX, int32 minY, int32 maxX, int32 maxY) + { + getGridStrategyData()->setCellRange(minX, minY, maxX, maxY); + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::setPageRangeMinX(int32 minX) + { + getGridStrategyData()->setCellRangeMinX(minX); + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::setPageRangeMinY(int32 minY) + { + getGridStrategyData()->setCellRangeMinY(minY); + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::setPageRangeMaxX(int32 maxX) + { + getGridStrategyData()->setCellRangeMaxX(maxX); + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::setPageRangeMaxY(int32 maxY) + { + getGridStrategyData()->setCellRangeMaxY(maxY); + } + //--------------------------------------------------------------------- + int32 TerrainPagedWorldSection::getPageRangeMinX() const + { + return getGridStrategyData()->getCellRangeMinX(); + } + //--------------------------------------------------------------------- + int32 TerrainPagedWorldSection::getPageRangeMinY() const + { + return getGridStrategyData()->getCellRangeMinY(); + } + //--------------------------------------------------------------------- + int32 TerrainPagedWorldSection::getPageRangeMaxX() const + { + return getGridStrategyData()->getCellRangeMaxX(); + } + //--------------------------------------------------------------------- + int32 TerrainPagedWorldSection::getPageRangeMaxY() const + { + return getGridStrategyData()->getCellRangeMaxY(); + } + //--------------------------------------------------------------------- + Grid2DPageStrategy* TerrainPagedWorldSection::getGridStrategy() const + { + return static_cast(this->getStrategy()); + } + //--------------------------------------------------------------------- + Grid2DPageStrategyData* TerrainPagedWorldSection::getGridStrategyData() const + { + return static_cast(mStrategyData); + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::setLoadingIntervalMs(uint32 loadingIntervalMs) + { + mLoadingIntervalMs = loadingIntervalMs; + } + //--------------------------------------------------------------------- + uint32 TerrainPagedWorldSection::getLoadingIntervalMs() const + { + return mLoadingIntervalMs; + } + + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::loadSubtypeData(StreamSerialiser& ser) + { + // we load the TerrainGroup information from here + if (!mTerrainGroup) + mTerrainGroup = OGRE_NEW TerrainGroup(getSceneManager()); + + mTerrainGroup->loadGroupDefinition(ser); + + // params that are in the Grid2DStrategyData will have already been loaded + // as part of the main load() routine + + syncSettings(); + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::saveSubtypeData(StreamSerialiser& ser) + { + mTerrainGroup->saveGroupDefinition(ser); + + // params that are in the Grid2DStrategyData will have already been saved + // as part of the main save() routine + + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::loadPage(PageID pageID, bool forceSynchronous) + { + if (!mParent->getManager()->getPagingOperationsEnabled()) + return; + + PageMap::iterator i = mPages.find(pageID); + if (i == mPages.end()) + { + std::list::iterator it = find( mPagesInLoading.begin(), mPagesInLoading.end(), pageID); + if(it==mPagesInLoading.end()) + { + mPagesInLoading.push_back(pageID); + mHasRunningTasks = true; + } + + // no running tasks, start the new one + if(mPagesInLoading.size()==1) + { + Root::getSingleton().getWorkQueue()->addRequest( + mWorkQueueChannel, WORKQUEUE_LOAD_TERRAIN_PAGE_REQUEST, + Any(), 0, forceSynchronous); + } + } + + PagedWorldSection::loadPage(pageID, forceSynchronous); + } + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::unloadPage(PageID pageID, bool forceSynchronous) + { + if (!mParent->getManager()->getPagingOperationsEnabled()) + return; + + PagedWorldSection::unloadPage(pageID, forceSynchronous); + + std::list::iterator it = find( mPagesInLoading.begin(), mPagesInLoading.end(), pageID); + // hasn't been loaded, just remove from the queue + if(it!=mPagesInLoading.end()) + { + mPagesInLoading.erase(it); + } + else + { + // trigger terrain unload + long x, y; + // pageID is the same as a packed index + mTerrainGroup->unpackIndex(pageID, &x, &y); + mTerrainGroup->unloadTerrain(x, y); + } + } + //--------------------------------------------------------------------- + WorkQueue::Response* TerrainPagedWorldSection::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + if(mPagesInLoading.empty()) + { + mHasRunningTasks = false; + req->abortRequest(); + return OGRE_NEW WorkQueue::Response(req, true, Any()); + } + + unsigned long currentTime = Root::getSingletonPtr()->getTimer()->getMilliseconds(); + if(currentTime < mNextLoadingTime) + { + // Wait until the next page is to be loaded -> we are in background thread here + OGRE_THREAD_SLEEP(mNextLoadingTime - currentTime); + } + + PageID pageID = mPagesInLoading.front(); + + // call the TerrainDefiner from the background thread + long x, y; + // pageID is the same as a packed index + mTerrainGroup->unpackIndex(pageID, &x, &y); + + if(!mTerrainDefiner) + mTerrainDefiner = OGRE_NEW TerrainDefiner(); + mTerrainDefiner->define(mTerrainGroup, x, y); + + // continue loading in main thread + return OGRE_NEW WorkQueue::Response(req, true, Any()); + } + + //--------------------------------------------------------------------- + void TerrainPagedWorldSection::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + PageID pageID = mPagesInLoading.front(); + + // trigger terrain load + long x, y; + // pageID is the same as a packed index + mTerrainGroup->unpackIndex(pageID, &x, &y); + mTerrainGroup->loadTerrain(x, y, false); + mPagesInLoading.pop_front(); + + unsigned long currentTime = Root::getSingletonPtr()->getTimer()->getMilliseconds(); + mNextLoadingTime = currentTime + mLoadingIntervalMs; + + if(!mPagesInLoading.empty()) + { + // Continue loading other pages + Root::getSingleton().getWorkQueue()->addRequest( + mWorkQueueChannel, WORKQUEUE_LOAD_TERRAIN_PAGE_REQUEST, + Any(), 0, false); + } + else + mHasRunningTasks = false; + } } diff --git a/Components/Terrain/src/OgreTerrainPaging.cpp b/Components/Terrain/src/OgreTerrainPaging.cpp index 4ebaacf644c..aa0929af1e1 100644 --- a/Components/Terrain/src/OgreTerrainPaging.cpp +++ b/Components/Terrain/src/OgreTerrainPaging.cpp @@ -33,53 +33,53 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - TerrainPaging::TerrainPaging(PageManager* pageMgr) - : mManager(pageMgr) - { - mManager->addWorldSectionFactory(&mSectionFactory); - } - //--------------------------------------------------------------------- - TerrainPaging::~TerrainPaging() - { - mManager->removeWorldSectionFactory(&mSectionFactory); - } - //--------------------------------------------------------------------- - TerrainPagedWorldSection* TerrainPaging::createWorldSection( - PagedWorld* world, TerrainGroup* terrainGroup, - Real loadRadius, Real holdRadius, int32 minX, int32 minY, int32 maxX, int32 maxY, - const String& sectionName, uint32 loadingIntervalMs) - { - TerrainPagedWorldSection* ret = static_cast( - world->createSection(terrainGroup->getSceneManager(), SectionFactory::FACTORY_NAME, sectionName)); + //--------------------------------------------------------------------- + TerrainPaging::TerrainPaging(PageManager* pageMgr) + : mManager(pageMgr) + { + mManager->addWorldSectionFactory(&mSectionFactory); + } + //--------------------------------------------------------------------- + TerrainPaging::~TerrainPaging() + { + mManager->removeWorldSectionFactory(&mSectionFactory); + } + //--------------------------------------------------------------------- + TerrainPagedWorldSection* TerrainPaging::createWorldSection( + PagedWorld* world, TerrainGroup* terrainGroup, + Real loadRadius, Real holdRadius, int32 minX, int32 minY, int32 maxX, int32 maxY, + const String& sectionName, uint32 loadingIntervalMs) + { + TerrainPagedWorldSection* ret = static_cast( + world->createSection(terrainGroup->getSceneManager(), SectionFactory::FACTORY_NAME, sectionName)); - ret->init(terrainGroup); - ret->setLoadRadius(loadRadius); - ret->setHoldRadius(holdRadius); - ret->setPageRange(minX, minY, maxX, maxY); - ret->setLoadingIntervalMs(loadingIntervalMs); + ret->init(terrainGroup); + ret->setLoadRadius(loadRadius); + ret->setHoldRadius(holdRadius); + ret->setPageRange(minX, minY, maxX, maxY); + ret->setLoadingIntervalMs(loadingIntervalMs); - return ret; + return ret; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - const String TerrainPaging::SectionFactory::FACTORY_NAME("Terrain"); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + const String TerrainPaging::SectionFactory::FACTORY_NAME("Terrain"); - const String& TerrainPaging::SectionFactory::getName() const - { - return FACTORY_NAME; - } - //--------------------------------------------------------------------- - PagedWorldSection* TerrainPaging::SectionFactory::createInstance(const String& name, PagedWorld* parent, SceneManager* sm) - { - return OGRE_NEW TerrainPagedWorldSection(name, parent, sm); - } - //--------------------------------------------------------------------- - void TerrainPaging::SectionFactory::destroyInstance(PagedWorldSection* s) - { - OGRE_DELETE s; - } + const String& TerrainPaging::SectionFactory::getName() const + { + return FACTORY_NAME; + } + //--------------------------------------------------------------------- + PagedWorldSection* TerrainPaging::SectionFactory::createInstance(const String& name, PagedWorld* parent, SceneManager* sm) + { + return OGRE_NEW TerrainPagedWorldSection(name, parent, sm); + } + //--------------------------------------------------------------------- + void TerrainPaging::SectionFactory::destroyInstance(PagedWorldSection* s) + { + OGRE_DELETE s; + } } diff --git a/Components/Terrain/src/OgreTerrainQuadTreeNode.cpp b/Components/Terrain/src/OgreTerrainQuadTreeNode.cpp index ec88c336a54..5513484d56b 100644 --- a/Components/Terrain/src/OgreTerrainQuadTreeNode.cpp +++ b/Components/Terrain/src/OgreTerrainQuadTreeNode.cpp @@ -1,1602 +1,1602 @@ -/* ------------------------------------------------------------------------------ -This source file is part of OGRE -(Object-oriented Graphics Rendering Engine) -For the latest info, see http://www.ogre3d.org/ - -Copyright (c) 2000-2014 Torus Knot Software Ltd - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. ------------------------------------------------------------------------------ -*/ -#include "OgreTerrainQuadTreeNode.h" -#include "OgreTerrain.h" -#include "OgreVertexIndexData.h" -#include "OgreDefaultHardwareBufferManager.h" -#include "OgreCamera.h" -#include "OgreStreamSerialiser.h" -#include "OgreSceneNode.h" -#include "OgreLodStrategy.h" - -#if OGRE_COMPILER == OGRE_COMPILER_MSVC -// we do lots of conversions here, casting them all is tedious & cluttered, we know what we're doing -# pragma warning (disable : 4244) -#endif - -namespace Ogre -{ - unsigned short TerrainQuadTreeNode::POSITION_BUFFER = 0; - unsigned short TerrainQuadTreeNode::DELTA_BUFFER = 1; - - //--------------------------------------------------------------------- - TerrainQuadTreeNode::TerrainQuadTreeNode(Terrain* terrain, - TerrainQuadTreeNode* parent, uint16 xoff, uint16 yoff, uint16 size, - uint16 lod, uint16 depth, uint16 quadrant) - : mTerrain(terrain) - , mParent(parent) - , mOffsetX(xoff) - , mOffsetY(yoff) - , mBoundaryX(xoff + size) - , mBoundaryY(yoff + size) - , mSize(size) - , mBaseLod(lod) - , mDepth(depth) - , mQuadrant(quadrant) - , mBoundingRadius(0) - , mCurrentLod(-1) - , mMaterialLodIndex(0) - , mLodTransition(0) - , mChildWithMaxHeightDelta(0) - , mSelfOrChildRendered(false) - , mNodeWithVertexData(0) - , mVertexDataRecord(0) - , mMovable(0) - , mLocalNode(0) - , mRend(0) - { - if (terrain->getMaxBatchSize() < size) - { - uint16 childSize = (uint16)(((size - 1) * 0.5f) + 1); - uint16 childOff = childSize - 1; - uint16 childLod = lod - 1; // LOD levels decrease down the tree (higher detail) - uint16 childDepth = depth + 1; - // create children - mChildren[0] = OGRE_NEW TerrainQuadTreeNode(terrain, this, xoff, yoff, childSize, childLod, childDepth, 0); - mChildren[1] = OGRE_NEW TerrainQuadTreeNode(terrain, this, xoff + childOff, yoff, childSize, childLod, childDepth, 1); - mChildren[2] = OGRE_NEW TerrainQuadTreeNode(terrain, this, xoff, yoff + childOff, childSize, childLod, childDepth, 2); - mChildren[3] = OGRE_NEW TerrainQuadTreeNode(terrain, this, xoff + childOff, yoff + childOff, childSize, childLod, childDepth, 3); - - LodLevel* ll = OGRE_NEW LodLevel(); - // non-leaf nodes always render with minBatchSize vertices - ll->batchSize = terrain->getMinBatchSize(); - ll->maxHeightDelta = 0; - ll->calcMaxHeightDelta = 0; - mLodLevels.push_back(ll); - - } - else - { - // No children - memset(mChildren, 0, sizeof(TerrainQuadTreeNode*) * 4); - - // this is a leaf node and may have internal LODs of its own - uint16 ownLod = terrain->getNumLodLevelsPerLeaf(); - assert (lod == (ownLod - 1) && "The lod passed in should reflect the number of " - "lods in a leaf"); - // leaf nodes always have a base LOD of 0, because they're always handling - // the highest level of detail - mBaseLod = 0; - // leaf nodes render from max batch size to min batch size - uint16 sz = terrain->getMaxBatchSize(); - - while (ownLod--) - { - LodLevel* ll = OGRE_NEW LodLevel(); - ll->batchSize = sz; - ll->maxHeightDelta = 0; - ll->calcMaxHeightDelta = 0; - mLodLevels.push_back(ll); - if (ownLod) - sz = (uint16)(((sz - 1) * 0.5) + 1); - } - - assert(sz == terrain->getMinBatchSize()); - - } - - // Local centre calculation - // Because of pow2 + 1 there is always a middle point - uint16 midoffset = (size - 1) / 2; - uint16 midpointx = mOffsetX + midoffset; - uint16 midpointy = mOffsetY + midoffset; - // derive the local centre, but give it a height of 0 - // TODO - what if we actually centred this at the terrain height at this point? - // would this be better? - mTerrain->getPoint(midpointx, midpointy, 0, &mLocalCentre); - - mMovable = OGRE_NEW Movable(this); - mRend = OGRE_NEW Rend(this); - - - } - //--------------------------------------------------------------------- - TerrainQuadTreeNode::~TerrainQuadTreeNode() - { - if (mMovable->isAttached()) - mLocalNode->detachObject(mMovable); - OGRE_DELETE mMovable; - mMovable = 0; - OGRE_DELETE mRend; - mRend = 0; - - if (mLocalNode) - { - mTerrain->_getRootSceneNode()->removeAndDestroyChild(mLocalNode->getName()); - mLocalNode = 0; - } - - for (int i = 0; i < 4; ++i) - OGRE_DELETE mChildren[i]; - - destroyCpuVertexData(); - destroyGpuVertexData(); - destroyGpuIndexData(); - - for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i) - OGRE_DELETE *i; - - OGRE_DELETE mVertexDataRecord; - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::isLeaf() const - { - return mChildren[0] == 0; - } - //--------------------------------------------------------------------- - TerrainQuadTreeNode* TerrainQuadTreeNode::getChild(unsigned short child) const - { - if (isLeaf() || child >= 4) - return 0; - - return mChildren[child]; - } - //--------------------------------------------------------------------- - TerrainQuadTreeNode* TerrainQuadTreeNode::getParent() const - { - return mParent; - } - //--------------------------------------------------------------------- - Terrain* TerrainQuadTreeNode::getTerrain() const - { - return mTerrain; - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::prepare() - { - if (!isLeaf()) - { - for (int i = 0; i < 4; ++i) - mChildren[i]->prepare(); - } - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::prepare(StreamSerialiser& stream) - { - // load LOD data we need - for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i) - { - LodLevel* ll = *i; - // only read 'calc' and then copy to final (separation is only for - // real-time calculation - // Basically this is what finaliseHeightDeltas does in calc path - stream.read(&ll->calcMaxHeightDelta); - ll->maxHeightDelta = ll->calcMaxHeightDelta; - ll->lastCFactor = 0; - } - - if (!isLeaf()) - { - for (int i = 0; i < 4; ++i) - mChildren[i]->prepare(stream); - } - - // If this is the root, do the post delta calc to finish - if (!mParent) - { - Rect rect; - rect.top = mOffsetY; rect.bottom = mBoundaryY; - rect.left = mOffsetX; rect.right = mBoundaryX; - postDeltaCalculation(rect); - } - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::save(StreamSerialiser& stream) - { - // save LOD data we need - for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i) - { - LodLevel* ll = *i; - stream.write(&ll->maxHeightDelta); - } - - if (!isLeaf()) - { - for (int i = 0; i < 4; ++i) - mChildren[i]->save(stream); - } - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::load() - { - loadSelf(); - - if (!isLeaf()) - for (int i = 0; i < 4; ++i) - mChildren[i]->load(); - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::load(uint16 treeDepthStart, uint16 treeDepthEnd) - { - if (mDepth >= treeDepthEnd) - return ; - - if (mDepth >= treeDepthStart && mDepth < treeDepthEnd && mNodeWithVertexData) - loadSelf(); - - if (!isLeaf()) - for (int i = 0; i < 4; ++i) - mChildren[i]->load(treeDepthStart, treeDepthEnd); - } - void TerrainQuadTreeNode::loadSelf() - { - createGpuVertexData(); - createGpuIndexData(); - if (!mLocalNode) - mLocalNode = mTerrain->_getRootSceneNode()->createChildSceneNode(mLocalCentre); - - if (!mMovable->isAttached()) - mLocalNode->attachObject(mMovable); - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::unload() - { - if (!isLeaf()) - for (int i = 0; i < 4; ++i) - mChildren[i]->unload(); - - destroyGpuVertexData(); - - if (mMovable->isAttached()) - mLocalNode->detachObject(mMovable); - } - - void TerrainQuadTreeNode::unload(uint16 treeDepthStart, uint16 treeDepthEnd) - { - if (mDepth >= treeDepthEnd) - return ; - - if (!isLeaf()) - for (int i = 0; i < 4; ++i) - mChildren[i]->unload(treeDepthStart, treeDepthEnd); - - if (mDepth >= treeDepthStart && mDepth < treeDepthEnd) - { - destroyGpuVertexData(); - if (mMovable->isAttached()) - mLocalNode->detachObject(mMovable); - - } - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::unprepare() - { - if (!isLeaf()) - for (int i = 0; i < 4; ++i) - mChildren[i]->unprepare(); - - destroyCpuVertexData(); - } - //--------------------------------------------------------------------- - uint16 TerrainQuadTreeNode::getLodCount() const - { - return static_cast(mLodLevels.size()); - } - //--------------------------------------------------------------------- - const TerrainQuadTreeNode::LodLevel* TerrainQuadTreeNode::getLodLevel(uint16 lod) - { - assert(lod < mLodLevels.size()); - - return mLodLevels[lod]; - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::preDeltaCalculation(const Rect& rect) - { - if (rect.left <= mBoundaryX || rect.right > mOffsetX - || rect.top <= mBoundaryY || rect.bottom > mOffsetY) - { - // relevant to this node (overlaps) - - // if the rect covers the whole node, reset the max height - // this means that if you recalculate the deltas progressively, end up keeping - // a max height that's no longer the case (ie more conservative lod), - // but that's the price for not recaculating the whole node. If a - // complete recalculation is required, just dirty the entire node. (or terrain) - - // Note we use the 'calc' field here to avoid interfering with any - // ongoing LOD calculations (this can be in the background) - - if (rect.left <= mOffsetX && rect.right > mBoundaryX - && rect.top <= mOffsetY && rect.bottom > mBoundaryY) - { - for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i) - (*i)->calcMaxHeightDelta = 0.0; - } - - // pass on to children - if (!isLeaf()) - { - for (int i = 0; i < 4; ++i) - mChildren[i]->preDeltaCalculation(rect); - - } - } - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::notifyDelta(uint16 x, uint16 y, uint16 lod, Real delta) - { - if (x >= mOffsetX && x < mBoundaryX - && y >= mOffsetY && y < mBoundaryY) - { - // within our bounds, check it's our LOD level - if (lod >= mBaseLod && lod < mBaseLod + mLodLevels.size()) - { - // Apply the delta to all LODs equal or lower detail to lod - LodLevelList::iterator i = mLodLevels.begin(); - std::advance(i, lod - mBaseLod); - (*i)->calcMaxHeightDelta = std::max((*i)->calcMaxHeightDelta, delta); - } - - // pass on to children - if (!isLeaf()) - { - for (int i = 0; i < 4; ++i) - { - mChildren[i]->notifyDelta(x, y, lod, delta); - } - } - - } - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::postDeltaCalculation(const Rect& rect) - { - if (rect.left <= mBoundaryX || rect.right > mOffsetX - || rect.top <= mBoundaryY || rect.bottom > mOffsetY) - { - // relevant to this node (overlaps) - - // each non-leaf node should know which of its children transitions - // to the lower LOD level last, because this is the one which controls - // when the parent takes over - if (!isLeaf()) - { - Real maxChildDelta = -1; - TerrainQuadTreeNode* childWithMaxHeightDelta = 0; - for (int i = 0; i < 4; ++i) - { - TerrainQuadTreeNode* child = mChildren[i]; - - child->postDeltaCalculation(rect); - - Real childDelta = child->getLodLevel(child->getLodCount()-1)->calcMaxHeightDelta; - if (childDelta > maxChildDelta) - { - childWithMaxHeightDelta = child; - maxChildDelta = childDelta; - } - - } - - // make sure that our highest delta value is greater than all children's - // otherwise we could have some crossover problems - // for a non-leaf, there is only one LOD level - mLodLevels[0]->calcMaxHeightDelta = std::max(mLodLevels[0]->calcMaxHeightDelta, maxChildDelta * (Real)1.05); - mChildWithMaxHeightDelta = childWithMaxHeightDelta; - - } - else - { - // make sure own LOD levels delta values ascend - for (size_t i = 0; i < mLodLevels.size() - 1; ++i) - { - // the next LOD after this one should have a higher delta - // otherwise it won't come into affect further back like it should! - mLodLevels[i+1]->calcMaxHeightDelta = - std::max(mLodLevels[i+1]->calcMaxHeightDelta, - mLodLevels[i]->calcMaxHeightDelta * (Real)1.05); - } - - } - } - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::finaliseDeltaValues(const Rect& rect) - { - if (rect.left <= mBoundaryX || rect.right > mOffsetX - || rect.top <= mBoundaryY || rect.bottom > mOffsetY) - { - // relevant to this node (overlaps) - - // Children - if (!isLeaf()) - { - for (int i = 0; i < 4; ++i) - { - TerrainQuadTreeNode* child = mChildren[i]; - child->finaliseDeltaValues(rect); - } - - } - - // Self - for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i) - { - // copy from 'calc' area to runtime value - (*i)->maxHeightDelta = (*i)->calcMaxHeightDelta; - // also trash stored cfactor - (*i)->lastCFactor = 0; - } - - } - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::assignVertexData(uint16 treeDepthStart, - uint16 treeDepthEnd, uint16 resolution, uint sz) - { - assert(treeDepthStart >= mDepth && "Should not be calling this"); - - if (mDepth == treeDepthStart) - { - // we own this vertex data - mNodeWithVertexData = this; - if (!mVertexDataRecord) - mVertexDataRecord = OGRE_NEW VertexDataRecord(resolution, sz, treeDepthEnd - treeDepthStart); - - createCpuVertexData(); - - // pass on to children - if (!isLeaf() && treeDepthEnd > (mDepth + 1)) // treeDepthEnd is exclusive, and this is children - { - for (int i = 0; i < 4; ++i) - mChildren[i]->useAncestorVertexData(this, treeDepthEnd, resolution); - - } - } - else - { - assert(!isLeaf() && "No more levels below this!"); - - for (int i = 0; i < 4; ++i) - mChildren[i]->assignVertexData(treeDepthStart, treeDepthEnd, resolution, sz); - - } - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::useAncestorVertexData(TerrainQuadTreeNode* owner, uint16 treeDepthEnd, uint16 resolution) - { - mNodeWithVertexData = owner; - mVertexDataRecord = 0; - - if (!isLeaf() && treeDepthEnd > (mDepth + 1)) // treeDepthEnd is exclusive, and this is children - { - for (int i = 0; i < 4; ++i) - mChildren[i]->useAncestorVertexData(owner, treeDepthEnd, resolution); - - } - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::updateVertexData(bool positions, bool deltas, - const Rect& rect, bool cpuData) - { - if (rect.left <= mBoundaryX || rect.right > mOffsetX - || rect.top <= mBoundaryY || rect.bottom > mOffsetY) - { - // Do we have vertex data? - if (mVertexDataRecord) - { - // Trim to our bounds - Rect updateRect(mOffsetX, mOffsetY, mBoundaryX, mBoundaryY); - updateRect.left = std::max(updateRect.left, rect.left); - updateRect.right = std::min(updateRect.right, rect.right); - updateRect.top = std::max(updateRect.top, rect.top); - updateRect.bottom = std::min(updateRect.bottom, rect.bottom); - - // update the GPU buffer directly - // TODO: do we have no use for CPU vertex data after initial load? - // if so, destroy it to free RAM, this should be fast enough to - // to direct - HardwareVertexBufferSharedPtr posbuf, deltabuf; - VertexData* targetVertexData = mVertexDataRecord->cpuVertexData; - if(!cpuData) - { - if(mVertexDataRecord->gpuVertexData == NULL) - createGpuVertexData(); - targetVertexData = mVertexDataRecord->gpuVertexData; - } - - if (positions) - posbuf = targetVertexData->vertexBufferBinding->getBuffer(POSITION_BUFFER); - if (deltas) - deltabuf = targetVertexData->vertexBufferBinding->getBuffer(DELTA_BUFFER); - updateVertexBuffer(posbuf, deltabuf, updateRect); - } - - // pass on to children - if (!isLeaf()) - { - for (int i = 0; i < 4; ++i) - { - mChildren[i]->updateVertexData(positions, deltas, rect, cpuData); - - // merge bounds from children - AxisAlignedBox childBox = mChildren[i]->getAABB(); - // this box is relative to child centre - Vector3 boxoffset = mChildren[i]->getLocalCentre() - getLocalCentre(); - childBox.setMinimum(childBox.getMinimum() + boxoffset); - childBox.setMaximum(childBox.getMaximum() + boxoffset); - mAABB.merge(childBox); - } - - } - // Make sure node knows to update - if (mMovable && mMovable->isAttached()) - mMovable->getParentSceneNode()->needUpdate(); - - - - } - - } - //--------------------------------------------------------------------- - const TerrainQuadTreeNode::VertexDataRecord* TerrainQuadTreeNode::getVertexDataRecord() const - { - return mNodeWithVertexData ? mNodeWithVertexData->mVertexDataRecord : 0; - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::createCpuVertexData() - { - if (mVertexDataRecord) - { - destroyCpuVertexData(); - - // create vertex structure, not using GPU for now (these are CPU structures) - VertexDeclaration* dcl = OGRE_NEW VertexDeclaration(); - VertexBufferBinding* bufbind = OGRE_NEW VertexBufferBinding(); - - mVertexDataRecord->cpuVertexData = OGRE_NEW VertexData(dcl, bufbind); - - // Vertex declaration - size_t offset = 0; - - if (mTerrain->_getUseVertexCompression()) - { - // 16 bytes per vertex, shaders only - // POSITION (encoded x/y as indexes from base) - // short2(x, y) - offset += dcl->addElement(POSITION_BUFFER, offset, VET_SHORT2, VES_POSITION).getSize(); - // UV0 - height - // float(height) - dcl->addElement(POSITION_BUFFER, offset, VET_FLOAT1, VES_TEXTURE_COORDINATES, 0).getSize(); - // UV1 delta information - // float2(delta, deltaLODthreshold) - dcl->addElement(DELTA_BUFFER, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, 1).getSize(); - } - else - { - // 28 bytes per vertex, compatibility - // POSITION - // float3(x, y, z) - offset += dcl->addElement(POSITION_BUFFER, offset, VET_FLOAT3, VES_POSITION).getSize(); - // UV0 - // float2(u, v) - dcl->addElement(POSITION_BUFFER, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0).getSize(); - // UV1 delta information - // float2(delta, deltaLODthreshold) - dcl->addElement(DELTA_BUFFER, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, 1).getSize(); - } - - // Calculate number of vertices - // Base geometry size * size - size_t baseNumVerts = (size_t)Math::Sqr(mVertexDataRecord->size); - size_t numVerts = baseNumVerts; - // Now add space for skirts - // Skirts will be rendered as copies of the edge vertices translated downwards - // Some people use one big fan with only 3 vertices at the bottom, - // but this requires creating them much bigger that necessary, meaning - // more unnecessary overdraw, so we'll use more vertices - // You need 2^levels + 1 rows of full resolution (max 129) vertex copies, plus - // the same number of columns. There are common vertices at intersections - uint16 levels = mVertexDataRecord->treeLevels; - mVertexDataRecord->numSkirtRowsCols = (uint16)(Math::Pow(2, levels) + 1); - mVertexDataRecord->skirtRowColSkip = (mVertexDataRecord->size - 1) / (mVertexDataRecord->numSkirtRowsCols - 1); - numVerts += mVertexDataRecord->size * mVertexDataRecord->numSkirtRowsCols; - numVerts += mVertexDataRecord->size * mVertexDataRecord->numSkirtRowsCols; - // manually create CPU-side buffer - HardwareVertexBufferSharedPtr posbuf( - OGRE_NEW DefaultHardwareVertexBuffer(dcl->getVertexSize(POSITION_BUFFER), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY)); - HardwareVertexBufferSharedPtr deltabuf( - OGRE_NEW DefaultHardwareVertexBuffer(dcl->getVertexSize(DELTA_BUFFER), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY)); - - mVertexDataRecord->cpuVertexData->vertexStart = 0; - mVertexDataRecord->cpuVertexData->vertexCount = numVerts; - - Rect updateRect(mOffsetX, mOffsetY, mBoundaryX, mBoundaryY); - updateVertexBuffer(posbuf, deltabuf, updateRect); - bufbind->setBinding(POSITION_BUFFER, posbuf); - bufbind->setBinding(DELTA_BUFFER, deltabuf); - mVertexDataRecord->gpuVertexDataDirty = true; - } - } - //---------------------------------------------------------------------- - void TerrainQuadTreeNode::updateVertexBuffer(HardwareVertexBufferSharedPtr& posbuf, - HardwareVertexBufferSharedPtr& deltabuf, const Rect& rect) - { - assert (rect.left >= mOffsetX && rect.right <= mBoundaryX && - rect.top >= mOffsetY && rect.bottom <= mBoundaryY); - - // potentially reset our bounds depending on coverage of the update - resetBounds(rect); - - // Main data - uint16 inc = (mTerrain->getSize()-1) / (mVertexDataRecord->resolution-1); - long destOffsetX = rect.left <= mOffsetX ? 0 : (rect.left - mOffsetX) / inc; - long destOffsetY = rect.top <= mOffsetY ? 0 : (rect.top - mOffsetY) / inc; - // Fill the buffers - - HardwareBuffer::LockOptions lockMode; - if (destOffsetX || destOffsetY || rect.width() < mSize - || rect.height() < mSize) - { - lockMode = HardwareBuffer::HBL_NORMAL; - } - else - { - lockMode = HardwareBuffer::HBL_DISCARD; - } - - Real uvScale = 1.0f / (mTerrain->getSize() - 1); - const float* pBaseHeight = mTerrain->getHeightData(rect.left, rect.top); - const float* pBaseDelta = mTerrain->getDeltaData(rect.left, rect.top); - uint16 rowskip = mTerrain->getSize() * inc; - uint16 destPosRowSkip = 0, destDeltaRowSkip = 0; - unsigned char* pRootPosBuf = 0; - unsigned char* pRootDeltaBuf = 0; - unsigned char* pRowPosBuf = 0; - unsigned char* pRowDeltaBuf = 0; - - if (!posbuf.isNull()) - { - destPosRowSkip = mVertexDataRecord->size * posbuf->getVertexSize(); - pRootPosBuf = static_cast(posbuf->lock(lockMode)); - pRowPosBuf = pRootPosBuf; - // skip dest buffer in by left/top - pRowPosBuf += destOffsetY * destPosRowSkip + destOffsetX * posbuf->getVertexSize(); - } - if (!deltabuf.isNull()) - { - destDeltaRowSkip = mVertexDataRecord->size * deltabuf->getVertexSize(); - pRootDeltaBuf = static_cast(deltabuf->lock(lockMode)); - pRowDeltaBuf = pRootDeltaBuf; - // skip dest buffer in by left/top - pRowDeltaBuf += destOffsetY * destDeltaRowSkip + destOffsetX * deltabuf->getVertexSize(); - } - Vector3 pos; - - bool vcompress = mTerrain->_getUseVertexCompression(); - - for (uint16 y = rect.top; y < rect.bottom; y += inc) - { - const float* pHeight = pBaseHeight; - const float* pDelta = pBaseDelta; - float* pPosBuf = static_cast(static_cast(pRowPosBuf)); - float* pDeltaBuf = static_cast(static_cast(pRowDeltaBuf)); - for (uint16 x = rect.left; x < rect.right; x += inc) - { - if (pPosBuf) - { - mTerrain->getPoint(x, y, *pHeight, &pos); - - // Update bounds *before* making relative - mergeIntoBounds(x, y, pos); - // relative to local centre - pos -= mLocalCentre; - - writePosVertex(vcompress, x, y, *pHeight, pos, uvScale, &pPosBuf); - pHeight += inc; - - - } - - if (pDeltaBuf) - { - // delta, and delta LOD threshold - // we want delta to apply to LODs no higher than this value - // at runtime this will be combined with a per-renderable parameter - // to ensure we only apply morph to the correct LOD - writeDeltaVertex(vcompress, x, y, *pDelta, - (float)mTerrain->getLODLevelWhenVertexEliminated(x, y) - 1.0f, - &pDeltaBuf); - pDelta += inc; - - } - - - } - pBaseHeight += rowskip; - pBaseDelta += rowskip; - if (pRowPosBuf) - pRowPosBuf += destPosRowSkip; - if (pRowDeltaBuf) - pRowDeltaBuf += destDeltaRowSkip; - - } - - // Skirts now - // skirt spacing based on top-level resolution (* inc to cope with resolution which is not the max) - uint16 skirtSpacing = mVertexDataRecord->skirtRowColSkip * inc; - Vector3 skirtOffset; - mTerrain->getVector(0, 0, -mTerrain->getSkirtSize(), &skirtOffset); - - // skirt rows - // clamp rows to skirt spacing (round up) - long skirtStartX = rect.left; - long skirtStartY = rect.top; - // for rows, clamp Y to skirt frequency, X to inc (LOD resolution vs top) - if (skirtStartY % skirtSpacing) - skirtStartY += skirtSpacing - (skirtStartY % skirtSpacing); - if (skirtStartX % inc) - skirtStartX += inc - (skirtStartX % inc); - skirtStartY = std::max(skirtStartY, (long)mOffsetY); - pBaseHeight = mTerrain->getHeightData(skirtStartX, skirtStartY); - if (!posbuf.isNull()) - { - // position dest buffer just after the main vertex data - pRowPosBuf = pRootPosBuf + posbuf->getVertexSize() - * mVertexDataRecord->size * mVertexDataRecord->size; - // move it onwards to skip the skirts we don't need to update - pRowPosBuf += destPosRowSkip * ((skirtStartY - mOffsetY) / skirtSpacing); - pRowPosBuf += posbuf->getVertexSize() * (skirtStartX - mOffsetX) / inc; - } - if (!deltabuf.isNull()) - { - // position dest buffer just after the main vertex data - pRowDeltaBuf = pRootDeltaBuf + deltabuf->getVertexSize() - * mVertexDataRecord->size * mVertexDataRecord->size; - // move it onwards to skip the skirts we don't need to update - pRowDeltaBuf += destDeltaRowSkip * (skirtStartY - mOffsetY) / skirtSpacing; - pRowDeltaBuf += deltabuf->getVertexSize() * (skirtStartX - mOffsetX) / inc; - } - for (uint16 y = skirtStartY; y < rect.bottom; y += skirtSpacing) - { - const float* pHeight = pBaseHeight; - float* pPosBuf = static_cast(static_cast(pRowPosBuf)); - float* pDeltaBuf = static_cast(static_cast(pRowDeltaBuf)); - for (uint16 x = skirtStartX; x < rect.right; x += inc) - { - if (pPosBuf) - { - mTerrain->getPoint(x, y, *pHeight, &pos); - // relative to local centre - pos -= mLocalCentre; - pos += skirtOffset; - writePosVertex(vcompress, x, y, *pHeight - mTerrain->getSkirtSize(), pos, uvScale, &pPosBuf); - - pHeight += inc; - - - - } - - if (pDeltaBuf) - { - // delta (none) - // delta threshold (irrelevant) - writeDeltaVertex(vcompress, x, y, 0, 99, &pDeltaBuf); - } - } - pBaseHeight += mTerrain->getSize() * skirtSpacing; - if (pRowPosBuf) - pRowPosBuf += destPosRowSkip; - if (pRowDeltaBuf) - pRowDeltaBuf += destDeltaRowSkip; - } - // skirt cols - // clamp cols to skirt spacing (round up) - skirtStartX = rect.left; - if (skirtStartX % skirtSpacing) - skirtStartX += skirtSpacing - (skirtStartX % skirtSpacing); - // clamp Y to inc (LOD resolution vs top) - skirtStartY = rect.top; - if (skirtStartY % inc) - skirtStartY += inc - (skirtStartY % inc); - skirtStartX = std::max(skirtStartX, (long)mOffsetX); - if (!posbuf.isNull()) - { - // position dest buffer just after the main vertex data and skirt rows - pRowPosBuf = pRootPosBuf + posbuf->getVertexSize() - * mVertexDataRecord->size * mVertexDataRecord->size; - // skip the row skirts - pRowPosBuf += mVertexDataRecord->numSkirtRowsCols * mVertexDataRecord->size * posbuf->getVertexSize(); - // move it onwards to skip the skirts we don't need to update - pRowPosBuf += destPosRowSkip * (skirtStartX - mOffsetX) / skirtSpacing; - pRowPosBuf += posbuf->getVertexSize() * (skirtStartY - mOffsetY) / inc; - } - if (!deltabuf.isNull()) - { - // Delta dest buffer just after the main vertex data and skirt rows - pRowDeltaBuf = pRootDeltaBuf + deltabuf->getVertexSize() - * mVertexDataRecord->size * mVertexDataRecord->size; - // skip the row skirts - pRowDeltaBuf += mVertexDataRecord->numSkirtRowsCols * mVertexDataRecord->size * deltabuf->getVertexSize(); - // move it onwards to skip the skirts we don't need to update - pRowDeltaBuf += destDeltaRowSkip * (skirtStartX - mOffsetX) / skirtSpacing; - pRowDeltaBuf += deltabuf->getVertexSize() * (skirtStartY - mOffsetY) / inc; - } - - for (uint16 x = skirtStartX; x < rect.right; x += skirtSpacing) - { - float* pPosBuf = static_cast(static_cast(pRowPosBuf)); - float* pDeltaBuf = static_cast(static_cast(pRowDeltaBuf)); - for (uint16 y = skirtStartY; y < rect.bottom; y += inc) - { - if (pPosBuf) - { - float height = mTerrain->getHeightAtPoint(x, y); - mTerrain->getPoint(x, y, height, &pos); - // relative to local centre - pos -= mLocalCentre; - pos += skirtOffset; - - writePosVertex(vcompress, x, y, height - mTerrain->getSkirtSize(), pos, uvScale, &pPosBuf); - - } - if (pDeltaBuf) - { - // delta (none) - // delta threshold (irrelevant) - writeDeltaVertex(vcompress, x, y, 0, 99, &pDeltaBuf); - } - } - if (pRowPosBuf) - pRowPosBuf += destPosRowSkip; - if (pRowDeltaBuf) - pRowDeltaBuf += destDeltaRowSkip; - } - - if (!posbuf.isNull()) - posbuf->unlock(); - if (!deltabuf.isNull()) - deltabuf->unlock(); - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::writePosVertex(bool compress, uint16 x, uint16 y, float height, - const Vector3& pos, float uvScale, float** ppPos) - { - float* pPosBuf = *ppPos; - - if (compress) - { - short* pPosShort = static_cast(static_cast(pPosBuf)); - *pPosShort++ = (short)x; - *pPosShort++ = (short)y; - pPosBuf = static_cast(static_cast(pPosShort)); - - *pPosBuf++ = height; - } - else - { - *pPosBuf++ = pos.x; - *pPosBuf++ = pos.y; - *pPosBuf++ = pos.z; - - // UVs - base UVs vary from 0 to 1, all other values - // will be derived using scalings - *pPosBuf++ = x * uvScale; - *pPosBuf++ = 1.0f - (y * uvScale); - } - - *ppPos = pPosBuf; - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::writeDeltaVertex(bool compress, uint16 x, uint16 y, - float delta, float deltaThresh, float** ppDelta) - { - *(*ppDelta)++ = delta; - *(*ppDelta)++ = deltaThresh; - } - //--------------------------------------------------------------------- - uint16 TerrainQuadTreeNode::calcSkirtVertexIndex(uint16 mainIndex, bool isCol) - { - const VertexDataRecord* vdr = getVertexDataRecord(); - // row / col in main vertex resolution - uint16 row = mainIndex / vdr->size; - uint16 col = mainIndex % vdr->size; - - // skrits are after main vertices, so skip them - uint16 base = vdr->size * vdr->size; - - // The layout in vertex data is: - // 1. row skirts - // numSkirtRowsCols rows of resolution vertices each - // 2. column skirts - // numSkirtRowsCols cols of resolution vertices each - - // No offsets used here, this is an index into the current vertex data, - // which is already relative - if (isCol) - { - uint16 skirtNum = col / vdr->skirtRowColSkip; - uint16 colbase = vdr->numSkirtRowsCols * vdr->size; - return base + colbase + vdr->size * skirtNum + row; - } - else - { - uint16 skirtNum = row / vdr->skirtRowColSkip; - return base + vdr->size * skirtNum + col; - } - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::destroyCpuVertexData() - { - if (mVertexDataRecord && mVertexDataRecord->cpuVertexData) - { - // avoid copy empty buffer - mVertexDataRecord->gpuVertexDataDirty = false; - // delete the bindings and declaration manually since not from a buf mgr - OGRE_DELETE mVertexDataRecord->cpuVertexData->vertexDeclaration; - mVertexDataRecord->cpuVertexData->vertexDeclaration = 0; - - OGRE_DELETE mVertexDataRecord->cpuVertexData->vertexBufferBinding; - mVertexDataRecord->cpuVertexData->vertexBufferBinding = 0; - - OGRE_DELETE mVertexDataRecord->cpuVertexData; - mVertexDataRecord->cpuVertexData = 0; - } - - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::populateIndexData(uint16 batchSize, IndexData* destData) - { - const VertexDataRecord* vdr = getVertexDataRecord(); - - // Ratio of the main terrain resolution in relation to this vertex data resolution - size_t resolutionRatio = (mTerrain->getSize() - 1) / (vdr->resolution - 1); - // At what frequency do we sample the vertex data we're using? - // mSize is the coverage in terms of the original terrain data (not split to fit in 16-bit) - size_t vertexIncrement = (mSize-1) / (batchSize-1); - // however, the vertex data we're referencing may not be at the full resolution anyway - vertexIncrement /= resolutionRatio; - uint16 vdatasizeOffsetX = (mOffsetX - mNodeWithVertexData->mOffsetX) / resolutionRatio; - uint16 vdatasizeOffsetY = (mOffsetY - mNodeWithVertexData->mOffsetY) / resolutionRatio; - - destData->indexBuffer = mTerrain->getGpuBufferAllocator()->getSharedIndexBuffer(batchSize, vdr->size, - vertexIncrement, vdatasizeOffsetX, vdatasizeOffsetY, - vdr->numSkirtRowsCols, vdr->skirtRowColSkip); - destData->indexStart = 0; - destData->indexCount = destData->indexBuffer->getNumIndexes(); - - // shared index buffer is pre-populated - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::createGpuVertexData() - { - // TODO - mutex cpu data - if (mVertexDataRecord && mVertexDataRecord->cpuVertexData && !mVertexDataRecord->gpuVertexData) - { - // copy data from CPU to GPU, but re-use vertex buffers (so don't use regular clone) - mVertexDataRecord->gpuVertexData = OGRE_NEW VertexData(); - VertexData* srcData = mVertexDataRecord->cpuVertexData; - VertexData* destData = mVertexDataRecord->gpuVertexData; - - // copy vertex buffers - // get new buffers - HardwareVertexBufferSharedPtr destPosBuf, destDeltaBuf; - mTerrain->getGpuBufferAllocator()->allocateVertexBuffers(mTerrain, srcData->vertexCount, - destPosBuf, destDeltaBuf); - - // copy data - destPosBuf->copyData(*srcData->vertexBufferBinding->getBuffer(POSITION_BUFFER)); - destDeltaBuf->copyData(*srcData->vertexBufferBinding->getBuffer(DELTA_BUFFER)); - - // set bindings - destData->vertexBufferBinding->setBinding(POSITION_BUFFER, destPosBuf); - destData->vertexBufferBinding->setBinding(DELTA_BUFFER, destDeltaBuf); - - // Basic vertex info - destData->vertexStart = srcData->vertexStart; - destData->vertexCount = srcData->vertexCount; - // Copy elements - const VertexDeclaration::VertexElementList elems = - srcData->vertexDeclaration->getElements(); - VertexDeclaration::VertexElementList::const_iterator ei, eiend; - eiend = elems.end(); - for (ei = elems.begin(); ei != eiend; ++ei) - { - destData->vertexDeclaration->addElement( - ei->getSource(), - ei->getOffset(), - ei->getType(), - ei->getSemantic(), - ei->getIndex() ); - } - - // We don't need the CPU copy anymore - destroyCpuVertexData(); - } - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::updateGpuVertexData() - { - if (mVertexDataRecord && mVertexDataRecord->gpuVertexDataDirty) - { - mVertexDataRecord->gpuVertexData->vertexBufferBinding->getBuffer(POSITION_BUFFER)-> - copyData(*mVertexDataRecord->cpuVertexData->vertexBufferBinding->getBuffer(POSITION_BUFFER).get()); - mVertexDataRecord->gpuVertexData->vertexBufferBinding->getBuffer(DELTA_BUFFER)-> - copyData(*mVertexDataRecord->cpuVertexData->vertexBufferBinding->getBuffer(DELTA_BUFFER).get()); - mVertexDataRecord->gpuVertexDataDirty = false; - } - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::destroyGpuVertexData() - { - if (mVertexDataRecord && mVertexDataRecord->gpuVertexData) - { - // Before we delete, free up the vertex buffers for someone else - mTerrain->getGpuBufferAllocator()->freeVertexBuffers( - mVertexDataRecord->gpuVertexData->vertexBufferBinding->getBuffer(POSITION_BUFFER), - mVertexDataRecord->gpuVertexData->vertexBufferBinding->getBuffer(DELTA_BUFFER)); - OGRE_DELETE mVertexDataRecord->gpuVertexData; - mVertexDataRecord->gpuVertexData = 0; - } - - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::createGpuIndexData() - { - for (size_t lod = 0; lod < mLodLevels.size(); ++lod) - { - LodLevel* ll = mLodLevels[lod]; - - if (!ll->gpuIndexData) - { - // clone, using default buffer manager ie hardware - ll->gpuIndexData = OGRE_NEW IndexData(); - populateIndexData(ll->batchSize, ll->gpuIndexData); - } - - } - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::destroyGpuIndexData() - { - for (size_t lod = 0; lod < mLodLevels.size(); ++lod) - { - LodLevel* ll = mLodLevels[lod]; - - OGRE_DELETE ll->gpuIndexData; - ll->gpuIndexData = 0; - } - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::mergeIntoBounds(long x, long y, const Vector3& pos) - { - if (pointIntersectsNode(x, y)) - { - Vector3 localPos = pos - mLocalCentre; - mAABB.merge(localPos); - mBoundingRadius = std::max(mBoundingRadius, localPos.length()); - - if (!isLeaf()) - { - for (int i = 0; i < 4; ++i) - mChildren[i]->mergeIntoBounds(x, y, pos); - } - } - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::resetBounds(const Rect& rect) - { - if (rectContainsNode(rect)) - { - mAABB.setNull(); - mBoundingRadius = 0; - - if (!isLeaf()) - { - for (int i = 0; i < 4; ++i) - mChildren[i]->resetBounds(rect); - } - - - } - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::rectContainsNode(const Rect& rect) - { - return (rect.left <= mOffsetX && rect.right > mBoundaryX && - rect.top <= mOffsetY && rect.bottom > mBoundaryY); - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::rectIntersectsNode(const Rect& rect) - { - return (rect.right >= mOffsetX && rect.left <= mBoundaryX && - rect.bottom >= mOffsetY && rect.top <= mBoundaryY); - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::pointIntersectsNode(long x, long y) - { - return x >= mOffsetX && x < mBoundaryX && - y >= mOffsetY && y < mBoundaryY; - } - //--------------------------------------------------------------------- - const AxisAlignedBox& TerrainQuadTreeNode::getAABB() const - { - return mAABB; - } - //--------------------------------------------------------------------- - Real TerrainQuadTreeNode::getBoundingRadius() const - { - return mBoundingRadius; - } - //--------------------------------------------------------------------- - Real TerrainQuadTreeNode::getMinHeight() const - { - switch (mTerrain->getAlignment()) - { - case Terrain::ALIGN_X_Y: - default: - return mAABB.getMinimum().z; - case Terrain::ALIGN_X_Z: - return mAABB.getMinimum().y; - case Terrain::ALIGN_Y_Z: - return mAABB.getMinimum().x; - }; - } - //--------------------------------------------------------------------- - Real TerrainQuadTreeNode::getMaxHeight() const - { - switch (mTerrain->getAlignment()) - { - case Terrain::ALIGN_X_Y: - default: - return mAABB.getMaximum().z; - case Terrain::ALIGN_X_Z: - return mAABB.getMaximum().y; - case Terrain::ALIGN_Y_Z: - return mAABB.getMaximum().x; - }; - - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::calculateCurrentLod(const Camera* cam, Real cFactor) - { - mSelfOrChildRendered = false; - - // early-out - /* disable this, could cause 'jumps' in LOD as children go out of frustum - if (!cam->isVisible(mMovable->getWorldBoundingBox(true))) - { - mCurrentLod = -1; - return mSelfOrChildRendered; - } - */ - - // Check children first - int childRenderedCount = 0; - if (!isLeaf()) - { - for (int i = 0; i < 4; ++i) - { - if (mChildren[i]->calculateCurrentLod(cam, cFactor)) - ++childRenderedCount; - } - - } - - // this node not loaded yet so skip - if (!mMovable->isAttached()) - { - mCurrentLod = -1; - return mSelfOrChildRendered; - } - - if (childRenderedCount == 0) - { - - // no children were within their LOD ranges, so we should consider our own - Vector3 localPos = cam->getDerivedPosition() - mLocalCentre - mTerrain->getPosition(); - Real dist; - if (TerrainGlobalOptions::getSingleton().getUseRayBoxDistanceCalculation()) - { - // Get distance to this terrain node (to closest point of the box) - // head towards centre of the box (note, box may not cover mLocalCentre because of height) - Vector3 dir(mAABB.getCenter() - localPos); - dir.normalise(); - Ray ray(localPos, dir); - std::pair intersectRes = Math::intersects(ray, mAABB); - - // ray will always intersect, we just want the distance - dist = intersectRes.second; - } - else - { - // distance to tile centre - dist = localPos.length(); - // deduct half the radius of the box, assume that on average the - // worst case is best approximated by this - dist -= (mBoundingRadius * 0.5f); - } - - // Do material LOD - MaterialPtr material = getMaterial(); - const LodStrategy *materialStrategy = material->getLodStrategy(); - Real lodValue = materialStrategy->getValue(mMovable, cam); - // Get the index at this biased depth - mMaterialLodIndex = material->getLodIndex(lodValue); - - - // For each LOD, the distance at which the LOD will transition *downwards* - // is given by - // distTransition = maxDelta * cFactor; - uint lodLvl = 0; - mCurrentLod = -1; - for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i, ++lodLvl) - { - // If we have no parent, and this is the lowest LOD, we always render - // this is the 'last resort' so to speak, we always enoucnter this last - if (lodLvl+1 == mLodLevels.size() && !mParent) - { - mCurrentLod = lodLvl; - mSelfOrChildRendered = true; - mLodTransition = 0; - } - else - { - // check the distance - LodLevel* ll = *i; - - // Calculate or reuse transition distance - Real distTransition; - if (Math::RealEqual(cFactor, ll->lastCFactor)) - distTransition = ll->lastTransitionDist; - else - { - distTransition = ll->maxHeightDelta * cFactor; - ll->lastCFactor = cFactor; - ll->lastTransitionDist = distTransition; - } - - if (dist < distTransition) - { - // we're within range of this LOD - mCurrentLod = lodLvl; - mSelfOrChildRendered = true; - - if (mTerrain->_getMorphRequired()) - { - // calculate the transition percentage - // we need a percentage of the total distance for just this LOD, - // which means taking off the distance for the next higher LOD - // which is either the previous entry in the LOD list, - // or the largest of any children. In both cases these will - // have been calculated before this point, since we process - // children first. Distances at lower LODs are guaranteed - // to be larger than those at higher LODs - - Real distTotal = distTransition; - if (isLeaf()) - { - // Any higher LODs? - if (i != mLodLevels.begin()) - { - LodLevelList::iterator prev = i - 1; - distTotal -= (*prev)->lastTransitionDist; - } - } - else - { - // Take the distance of the lowest LOD of child - const LodLevel* childLod = mChildWithMaxHeightDelta->getLodLevel( - mChildWithMaxHeightDelta->getLodCount()-1); - distTotal -= childLod->lastTransitionDist; - } - // fade from 0 to 1 in the last 25% of the distance - Real distMorphRegion = distTotal * 0.25f; - Real distRemain = distTransition - dist; - - mLodTransition = 1.0f - (distRemain / distMorphRegion); - mLodTransition = std::min(1.0f, mLodTransition); - mLodTransition = std::max(0.0f, mLodTransition); - - // Pass both the transition % and target LOD (GLOBAL current + 1) - // this selectively applies the morph just to the - // vertices which would drop out at this LOD, even - // while using the single shared vertex data - mRend->setCustomParameter(Terrain::LOD_MORPH_CUSTOM_PARAM, - Vector4(mLodTransition, mCurrentLod + mBaseLod + 1, 0, 0)); - - } - // since LODs are ordered from highest to lowest detail, - // we can stop looking now - break; - } - - } - } - - } - else - { - // we should not render ourself - mCurrentLod = -1; - mSelfOrChildRendered = true; - if (childRenderedCount < 4) - { - // only *some* children decided to render on their own, but either - // none or all need to render, so set the others manually to their lowest - for (int i = 0; i < 4; ++i) - { - TerrainQuadTreeNode* child = mChildren[i]; - if (!child->isSelfOrChildRenderedAtCurrentLod()) - { - child->setCurrentLod(child->getLodCount()-1); - child->setLodTransition(1.0); - } - } - } // (childRenderedCount < 4) - - } // (childRenderedCount == 0) - - - return mSelfOrChildRendered; - - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::setCurrentLod(int lod) - { - mCurrentLod = lod; - mRend->setCustomParameter(Terrain::LOD_MORPH_CUSTOM_PARAM, - Vector4(mLodTransition, mCurrentLod + mBaseLod + 1, 0, 0)); - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::setLodTransition(float t) - { - mLodTransition = t; - mRend->setCustomParameter(Terrain::LOD_MORPH_CUSTOM_PARAM, - Vector4(mLodTransition, mCurrentLod + mBaseLod + 1, 0, 0)); - } - //--------------------------------------------------------------------- - Renderable *TerrainQuadTreeNode::_getRenderable() - { - return mRend; - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::isRenderedAtCurrentLod() const - { - return mCurrentLod != -1; - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::isSelfOrChildRenderedAtCurrentLod() const - { - return mSelfOrChildRendered; - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::updateRenderQueue(RenderQueue* queue) - { - if (isRenderedAtCurrentLod()) - { - queue->addRenderable(mRend, mTerrain->getRenderQueueGroup()); - } - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::visitRenderables(Renderable::Visitor* visitor, bool debugRenderables) - { - visitor->visit(mRend, 0, false); - } - //--------------------------------------------------------------------- - const MaterialPtr& TerrainQuadTreeNode::getMaterial(void) const - { - return mTerrain->getMaterial(); - } - //--------------------------------------------------------------------- - Technique* TerrainQuadTreeNode::getTechnique(void) const - { - return getMaterial()->getBestTechnique(mMaterialLodIndex, mRend); - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::getRenderOperation(RenderOperation& op) - { - mNodeWithVertexData->updateGpuVertexData(); - - op.indexData = mLodLevels[mCurrentLod]->gpuIndexData; - op.operationType = RenderOperation::OT_TRIANGLE_STRIP; - op.useIndexes = true; - op.vertexData = getVertexDataRecord()->gpuVertexData; - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::getWorldTransforms(Matrix4* xform) const - { - if (mTerrain->_getUseVertexCompression()) - { - // vertex data is generated in terrain space - *xform = Matrix4::IDENTITY; - xform->setTrans(mTerrain->getPosition()); - - } - else - { - // the vertex data is relative to the node that owns the vertex data - *xform = mNodeWithVertexData->mMovable->_getParentNodeFullTransform(); - } - - } - //--------------------------------------------------------------------- - Real TerrainQuadTreeNode::getSquaredViewDepth(const Camera* cam) const - { - return mMovable->getParentSceneNode()->getSquaredViewDepth(cam); - } - //--------------------------------------------------------------------- - const LightList& TerrainQuadTreeNode::getLights(void) const - { - return mMovable->queryLights(); - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::getCastsShadows(void) const - { - return TerrainGlobalOptions::getSingleton().getCastsDynamicShadows(); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - TerrainQuadTreeNode::Movable::Movable(TerrainQuadTreeNode* parent) - : mParent(parent) - { - } - //--------------------------------------------------------------------- - TerrainQuadTreeNode::Movable::~Movable() - { - - } - //--------------------------------------------------------------------- - const String& TerrainQuadTreeNode::Movable::getMovableType(void) const - { - static String stype("OgreTerrainNodeMovable"); - - return stype; - - } - //--------------------------------------------------------------------- - const AxisAlignedBox& TerrainQuadTreeNode::Movable::getBoundingBox(void) const - { - return mParent->getAABB(); - } - //--------------------------------------------------------------------- - Real TerrainQuadTreeNode::Movable::getBoundingRadius(void) const - { - return mParent->getBoundingRadius(); - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::Movable::isVisible(void) const - { - if (mParent->getCurrentLod() == -1) - return false; - else - return MovableObject::isVisible(); - } - //--------------------------------------------------------------------- - uint32 TerrainQuadTreeNode::Movable::getVisibilityFlags(void) const - { - // Combine own vis (in case anyone sets this) and terrain overall - return mVisibilityFlags & mParent->getTerrain()->getVisibilityFlags(); - } - //--------------------------------------------------------------------- - uint32 TerrainQuadTreeNode::Movable::getQueryFlags(void) const - { - // Combine own vis (in case anyone sets this) and terrain overall - return mQueryFlags & mParent->getTerrain()->getQueryFlags(); - } - //------------------------------------------------------------------------ - void TerrainQuadTreeNode::Movable::_updateRenderQueue(RenderQueue* queue) - { - mParent->updateRenderQueue(queue); - } - //------------------------------------------------------------------------ - void TerrainQuadTreeNode::Movable::visitRenderables(Renderable::Visitor* visitor, bool debugRenderables) - { - mParent->visitRenderables(visitor, debugRenderables); - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::Movable::getCastShadows(void) const - { - return mParent->getCastsShadows(); - } - //------------------------------------------------------------------------ - //--------------------------------------------------------------------- - TerrainQuadTreeNode::Rend::Rend(TerrainQuadTreeNode* parent) - :mParent(parent) - { - } - //--------------------------------------------------------------------- - TerrainQuadTreeNode::Rend::~Rend() - { - } - //--------------------------------------------------------------------- - const MaterialPtr& TerrainQuadTreeNode::Rend::getMaterial(void) const - { - return mParent->getMaterial(); - } - //--------------------------------------------------------------------- - Technique* TerrainQuadTreeNode::Rend::getTechnique() const - { - return mParent->getTechnique(); - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::Rend::getRenderOperation(RenderOperation& op) - { - mParent->getRenderOperation(op); - } - //--------------------------------------------------------------------- - void TerrainQuadTreeNode::Rend::getWorldTransforms(Matrix4* xform) const - { - mParent->getWorldTransforms(xform); - } - //--------------------------------------------------------------------- - Real TerrainQuadTreeNode::Rend::getSquaredViewDepth(const Camera* cam) const - { - return mParent->getSquaredViewDepth(cam); - } - //--------------------------------------------------------------------- - const LightList& TerrainQuadTreeNode::Rend::getLights(void) const - { - return mParent->getLights(); - } - //--------------------------------------------------------------------- - bool TerrainQuadTreeNode::Rend::getCastsShadows(void) const - { - return mParent->getCastsShadows(); - } - //--------------------------------------------------------------------- - - - - - - -} - +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org/ + +Copyright (c) 2000-2014 Torus Knot Software Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ +#include "OgreTerrainQuadTreeNode.h" +#include "OgreTerrain.h" +#include "OgreVertexIndexData.h" +#include "OgreDefaultHardwareBufferManager.h" +#include "OgreCamera.h" +#include "OgreStreamSerialiser.h" +#include "OgreSceneNode.h" +#include "OgreLodStrategy.h" + +#if OGRE_COMPILER == OGRE_COMPILER_MSVC +// we do lots of conversions here, casting them all is tedious & cluttered, we know what we're doing +# pragma warning (disable : 4244) +#endif + +namespace Ogre +{ + unsigned short TerrainQuadTreeNode::POSITION_BUFFER = 0; + unsigned short TerrainQuadTreeNode::DELTA_BUFFER = 1; + + //--------------------------------------------------------------------- + TerrainQuadTreeNode::TerrainQuadTreeNode(Terrain* terrain, + TerrainQuadTreeNode* parent, uint16 xoff, uint16 yoff, uint16 size, + uint16 lod, uint16 depth, uint16 quadrant) + : mTerrain(terrain) + , mParent(parent) + , mOffsetX(xoff) + , mOffsetY(yoff) + , mBoundaryX(xoff + size) + , mBoundaryY(yoff + size) + , mSize(size) + , mBaseLod(lod) + , mDepth(depth) + , mQuadrant(quadrant) + , mBoundingRadius(0) + , mCurrentLod(-1) + , mMaterialLodIndex(0) + , mLodTransition(0) + , mChildWithMaxHeightDelta(0) + , mSelfOrChildRendered(false) + , mNodeWithVertexData(0) + , mVertexDataRecord(0) + , mMovable(0) + , mLocalNode(0) + , mRend(0) + { + if (terrain->getMaxBatchSize() < size) + { + uint16 childSize = (uint16)(((size - 1) * 0.5f) + 1); + uint16 childOff = childSize - 1; + uint16 childLod = lod - 1; // LOD levels decrease down the tree (higher detail) + uint16 childDepth = depth + 1; + // create children + mChildren[0] = OGRE_NEW TerrainQuadTreeNode(terrain, this, xoff, yoff, childSize, childLod, childDepth, 0); + mChildren[1] = OGRE_NEW TerrainQuadTreeNode(terrain, this, xoff + childOff, yoff, childSize, childLod, childDepth, 1); + mChildren[2] = OGRE_NEW TerrainQuadTreeNode(terrain, this, xoff, yoff + childOff, childSize, childLod, childDepth, 2); + mChildren[3] = OGRE_NEW TerrainQuadTreeNode(terrain, this, xoff + childOff, yoff + childOff, childSize, childLod, childDepth, 3); + + LodLevel* ll = OGRE_NEW LodLevel(); + // non-leaf nodes always render with minBatchSize vertices + ll->batchSize = terrain->getMinBatchSize(); + ll->maxHeightDelta = 0; + ll->calcMaxHeightDelta = 0; + mLodLevels.push_back(ll); + + } + else + { + // No children + memset(mChildren, 0, sizeof(TerrainQuadTreeNode*) * 4); + + // this is a leaf node and may have internal LODs of its own + uint16 ownLod = terrain->getNumLodLevelsPerLeaf(); + assert (lod == (ownLod - 1) && "The lod passed in should reflect the number of " + "lods in a leaf"); + // leaf nodes always have a base LOD of 0, because they're always handling + // the highest level of detail + mBaseLod = 0; + // leaf nodes render from max batch size to min batch size + uint16 sz = terrain->getMaxBatchSize(); + + while (ownLod--) + { + LodLevel* ll = OGRE_NEW LodLevel(); + ll->batchSize = sz; + ll->maxHeightDelta = 0; + ll->calcMaxHeightDelta = 0; + mLodLevels.push_back(ll); + if (ownLod) + sz = (uint16)(((sz - 1) * 0.5) + 1); + } + + assert(sz == terrain->getMinBatchSize()); + + } + + // Local centre calculation + // Because of pow2 + 1 there is always a middle point + uint16 midoffset = (size - 1) / 2; + uint16 midpointx = mOffsetX + midoffset; + uint16 midpointy = mOffsetY + midoffset; + // derive the local centre, but give it a height of 0 + // TODO - what if we actually centred this at the terrain height at this point? + // would this be better? + mTerrain->getPoint(midpointx, midpointy, 0, &mLocalCentre); + + mMovable = OGRE_NEW Movable(this); + mRend = OGRE_NEW Rend(this); + + + } + //--------------------------------------------------------------------- + TerrainQuadTreeNode::~TerrainQuadTreeNode() + { + if (mMovable->isAttached()) + mLocalNode->detachObject(mMovable); + OGRE_DELETE mMovable; + mMovable = 0; + OGRE_DELETE mRend; + mRend = 0; + + if (mLocalNode) + { + mTerrain->_getRootSceneNode()->removeAndDestroyChild(mLocalNode->getName()); + mLocalNode = 0; + } + + for (int i = 0; i < 4; ++i) + OGRE_DELETE mChildren[i]; + + destroyCpuVertexData(); + destroyGpuVertexData(); + destroyGpuIndexData(); + + for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i) + OGRE_DELETE *i; + + OGRE_DELETE mVertexDataRecord; + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::isLeaf() const + { + return mChildren[0] == 0; + } + //--------------------------------------------------------------------- + TerrainQuadTreeNode* TerrainQuadTreeNode::getChild(unsigned short child) const + { + if (isLeaf() || child >= 4) + return 0; + + return mChildren[child]; + } + //--------------------------------------------------------------------- + TerrainQuadTreeNode* TerrainQuadTreeNode::getParent() const + { + return mParent; + } + //--------------------------------------------------------------------- + Terrain* TerrainQuadTreeNode::getTerrain() const + { + return mTerrain; + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::prepare() + { + if (!isLeaf()) + { + for (int i = 0; i < 4; ++i) + mChildren[i]->prepare(); + } + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::prepare(StreamSerialiser& stream) + { + // load LOD data we need + for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i) + { + LodLevel* ll = *i; + // only read 'calc' and then copy to final (separation is only for + // real-time calculation + // Basically this is what finaliseHeightDeltas does in calc path + stream.read(&ll->calcMaxHeightDelta); + ll->maxHeightDelta = ll->calcMaxHeightDelta; + ll->lastCFactor = 0; + } + + if (!isLeaf()) + { + for (int i = 0; i < 4; ++i) + mChildren[i]->prepare(stream); + } + + // If this is the root, do the post delta calc to finish + if (!mParent) + { + Rect rect; + rect.top = mOffsetY; rect.bottom = mBoundaryY; + rect.left = mOffsetX; rect.right = mBoundaryX; + postDeltaCalculation(rect); + } + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::save(StreamSerialiser& stream) + { + // save LOD data we need + for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i) + { + LodLevel* ll = *i; + stream.write(&ll->maxHeightDelta); + } + + if (!isLeaf()) + { + for (int i = 0; i < 4; ++i) + mChildren[i]->save(stream); + } + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::load() + { + loadSelf(); + + if (!isLeaf()) + for (int i = 0; i < 4; ++i) + mChildren[i]->load(); + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::load(uint16 treeDepthStart, uint16 treeDepthEnd) + { + if (mDepth >= treeDepthEnd) + return ; + + if (mDepth >= treeDepthStart && mDepth < treeDepthEnd && mNodeWithVertexData) + loadSelf(); + + if (!isLeaf()) + for (int i = 0; i < 4; ++i) + mChildren[i]->load(treeDepthStart, treeDepthEnd); + } + void TerrainQuadTreeNode::loadSelf() + { + createGpuVertexData(); + createGpuIndexData(); + if (!mLocalNode) + mLocalNode = mTerrain->_getRootSceneNode()->createChildSceneNode(mLocalCentre); + + if (!mMovable->isAttached()) + mLocalNode->attachObject(mMovable); + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::unload() + { + if (!isLeaf()) + for (int i = 0; i < 4; ++i) + mChildren[i]->unload(); + + destroyGpuVertexData(); + + if (mMovable->isAttached()) + mLocalNode->detachObject(mMovable); + } + + void TerrainQuadTreeNode::unload(uint16 treeDepthStart, uint16 treeDepthEnd) + { + if (mDepth >= treeDepthEnd) + return ; + + if (!isLeaf()) + for (int i = 0; i < 4; ++i) + mChildren[i]->unload(treeDepthStart, treeDepthEnd); + + if (mDepth >= treeDepthStart && mDepth < treeDepthEnd) + { + destroyGpuVertexData(); + if (mMovable->isAttached()) + mLocalNode->detachObject(mMovable); + + } + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::unprepare() + { + if (!isLeaf()) + for (int i = 0; i < 4; ++i) + mChildren[i]->unprepare(); + + destroyCpuVertexData(); + } + //--------------------------------------------------------------------- + uint16 TerrainQuadTreeNode::getLodCount() const + { + return static_cast(mLodLevels.size()); + } + //--------------------------------------------------------------------- + const TerrainQuadTreeNode::LodLevel* TerrainQuadTreeNode::getLodLevel(uint16 lod) + { + assert(lod < mLodLevels.size()); + + return mLodLevels[lod]; + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::preDeltaCalculation(const Rect& rect) + { + if (rect.left <= mBoundaryX || rect.right > mOffsetX + || rect.top <= mBoundaryY || rect.bottom > mOffsetY) + { + // relevant to this node (overlaps) + + // if the rect covers the whole node, reset the max height + // this means that if you recalculate the deltas progressively, end up keeping + // a max height that's no longer the case (ie more conservative lod), + // but that's the price for not recaculating the whole node. If a + // complete recalculation is required, just dirty the entire node. (or terrain) + + // Note we use the 'calc' field here to avoid interfering with any + // ongoing LOD calculations (this can be in the background) + + if (rect.left <= mOffsetX && rect.right > mBoundaryX + && rect.top <= mOffsetY && rect.bottom > mBoundaryY) + { + for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i) + (*i)->calcMaxHeightDelta = 0.0; + } + + // pass on to children + if (!isLeaf()) + { + for (int i = 0; i < 4; ++i) + mChildren[i]->preDeltaCalculation(rect); + + } + } + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::notifyDelta(uint16 x, uint16 y, uint16 lod, Real delta) + { + if (x >= mOffsetX && x < mBoundaryX + && y >= mOffsetY && y < mBoundaryY) + { + // within our bounds, check it's our LOD level + if (lod >= mBaseLod && lod < mBaseLod + mLodLevels.size()) + { + // Apply the delta to all LODs equal or lower detail to lod + LodLevelList::iterator i = mLodLevels.begin(); + std::advance(i, lod - mBaseLod); + (*i)->calcMaxHeightDelta = std::max((*i)->calcMaxHeightDelta, delta); + } + + // pass on to children + if (!isLeaf()) + { + for (int i = 0; i < 4; ++i) + { + mChildren[i]->notifyDelta(x, y, lod, delta); + } + } + + } + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::postDeltaCalculation(const Rect& rect) + { + if (rect.left <= mBoundaryX || rect.right > mOffsetX + || rect.top <= mBoundaryY || rect.bottom > mOffsetY) + { + // relevant to this node (overlaps) + + // each non-leaf node should know which of its children transitions + // to the lower LOD level last, because this is the one which controls + // when the parent takes over + if (!isLeaf()) + { + Real maxChildDelta = -1; + TerrainQuadTreeNode* childWithMaxHeightDelta = 0; + for (int i = 0; i < 4; ++i) + { + TerrainQuadTreeNode* child = mChildren[i]; + + child->postDeltaCalculation(rect); + + Real childDelta = child->getLodLevel(child->getLodCount()-1)->calcMaxHeightDelta; + if (childDelta > maxChildDelta) + { + childWithMaxHeightDelta = child; + maxChildDelta = childDelta; + } + + } + + // make sure that our highest delta value is greater than all children's + // otherwise we could have some crossover problems + // for a non-leaf, there is only one LOD level + mLodLevels[0]->calcMaxHeightDelta = std::max(mLodLevels[0]->calcMaxHeightDelta, maxChildDelta * (Real)1.05); + mChildWithMaxHeightDelta = childWithMaxHeightDelta; + + } + else + { + // make sure own LOD levels delta values ascend + for (size_t i = 0; i < mLodLevels.size() - 1; ++i) + { + // the next LOD after this one should have a higher delta + // otherwise it won't come into affect further back like it should! + mLodLevels[i+1]->calcMaxHeightDelta = + std::max(mLodLevels[i+1]->calcMaxHeightDelta, + mLodLevels[i]->calcMaxHeightDelta * (Real)1.05); + } + + } + } + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::finaliseDeltaValues(const Rect& rect) + { + if (rect.left <= mBoundaryX || rect.right > mOffsetX + || rect.top <= mBoundaryY || rect.bottom > mOffsetY) + { + // relevant to this node (overlaps) + + // Children + if (!isLeaf()) + { + for (int i = 0; i < 4; ++i) + { + TerrainQuadTreeNode* child = mChildren[i]; + child->finaliseDeltaValues(rect); + } + + } + + // Self + for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i) + { + // copy from 'calc' area to runtime value + (*i)->maxHeightDelta = (*i)->calcMaxHeightDelta; + // also trash stored cfactor + (*i)->lastCFactor = 0; + } + + } + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::assignVertexData(uint16 treeDepthStart, + uint16 treeDepthEnd, uint16 resolution, uint sz) + { + assert(treeDepthStart >= mDepth && "Should not be calling this"); + + if (mDepth == treeDepthStart) + { + // we own this vertex data + mNodeWithVertexData = this; + if (!mVertexDataRecord) + mVertexDataRecord = OGRE_NEW VertexDataRecord(resolution, sz, treeDepthEnd - treeDepthStart); + + createCpuVertexData(); + + // pass on to children + if (!isLeaf() && treeDepthEnd > (mDepth + 1)) // treeDepthEnd is exclusive, and this is children + { + for (int i = 0; i < 4; ++i) + mChildren[i]->useAncestorVertexData(this, treeDepthEnd, resolution); + + } + } + else + { + assert(!isLeaf() && "No more levels below this!"); + + for (int i = 0; i < 4; ++i) + mChildren[i]->assignVertexData(treeDepthStart, treeDepthEnd, resolution, sz); + + } + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::useAncestorVertexData(TerrainQuadTreeNode* owner, uint16 treeDepthEnd, uint16 resolution) + { + mNodeWithVertexData = owner; + mVertexDataRecord = 0; + + if (!isLeaf() && treeDepthEnd > (mDepth + 1)) // treeDepthEnd is exclusive, and this is children + { + for (int i = 0; i < 4; ++i) + mChildren[i]->useAncestorVertexData(owner, treeDepthEnd, resolution); + + } + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::updateVertexData(bool positions, bool deltas, + const Rect& rect, bool cpuData) + { + if (rect.left <= mBoundaryX || rect.right > mOffsetX + || rect.top <= mBoundaryY || rect.bottom > mOffsetY) + { + // Do we have vertex data? + if (mVertexDataRecord) + { + // Trim to our bounds + Rect updateRect(mOffsetX, mOffsetY, mBoundaryX, mBoundaryY); + updateRect.left = std::max(updateRect.left, rect.left); + updateRect.right = std::min(updateRect.right, rect.right); + updateRect.top = std::max(updateRect.top, rect.top); + updateRect.bottom = std::min(updateRect.bottom, rect.bottom); + + // update the GPU buffer directly + // TODO: do we have no use for CPU vertex data after initial load? + // if so, destroy it to free RAM, this should be fast enough to + // to direct + HardwareVertexBufferSharedPtr posbuf, deltabuf; + VertexData* targetVertexData = mVertexDataRecord->cpuVertexData; + if(!cpuData) + { + if(mVertexDataRecord->gpuVertexData == NULL) + createGpuVertexData(); + targetVertexData = mVertexDataRecord->gpuVertexData; + } + + if (positions) + posbuf = targetVertexData->vertexBufferBinding->getBuffer(POSITION_BUFFER); + if (deltas) + deltabuf = targetVertexData->vertexBufferBinding->getBuffer(DELTA_BUFFER); + updateVertexBuffer(posbuf, deltabuf, updateRect); + } + + // pass on to children + if (!isLeaf()) + { + for (int i = 0; i < 4; ++i) + { + mChildren[i]->updateVertexData(positions, deltas, rect, cpuData); + + // merge bounds from children + AxisAlignedBox childBox = mChildren[i]->getAABB(); + // this box is relative to child centre + Vector3 boxoffset = mChildren[i]->getLocalCentre() - getLocalCentre(); + childBox.setMinimum(childBox.getMinimum() + boxoffset); + childBox.setMaximum(childBox.getMaximum() + boxoffset); + mAABB.merge(childBox); + } + + } + // Make sure node knows to update + if (mMovable && mMovable->isAttached()) + mMovable->getParentSceneNode()->needUpdate(); + + + + } + + } + //--------------------------------------------------------------------- + const TerrainQuadTreeNode::VertexDataRecord* TerrainQuadTreeNode::getVertexDataRecord() const + { + return mNodeWithVertexData ? mNodeWithVertexData->mVertexDataRecord : 0; + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::createCpuVertexData() + { + if (mVertexDataRecord) + { + destroyCpuVertexData(); + + // create vertex structure, not using GPU for now (these are CPU structures) + VertexDeclaration* dcl = OGRE_NEW VertexDeclaration(); + VertexBufferBinding* bufbind = OGRE_NEW VertexBufferBinding(); + + mVertexDataRecord->cpuVertexData = OGRE_NEW VertexData(dcl, bufbind); + + // Vertex declaration + size_t offset = 0; + + if (mTerrain->_getUseVertexCompression()) + { + // 16 bytes per vertex, shaders only + // POSITION (encoded x/y as indexes from base) + // short2(x, y) + offset += dcl->addElement(POSITION_BUFFER, offset, VET_SHORT2, VES_POSITION).getSize(); + // UV0 - height + // float(height) + dcl->addElement(POSITION_BUFFER, offset, VET_FLOAT1, VES_TEXTURE_COORDINATES, 0).getSize(); + // UV1 delta information + // float2(delta, deltaLODthreshold) + dcl->addElement(DELTA_BUFFER, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, 1).getSize(); + } + else + { + // 28 bytes per vertex, compatibility + // POSITION + // float3(x, y, z) + offset += dcl->addElement(POSITION_BUFFER, offset, VET_FLOAT3, VES_POSITION).getSize(); + // UV0 + // float2(u, v) + dcl->addElement(POSITION_BUFFER, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0).getSize(); + // UV1 delta information + // float2(delta, deltaLODthreshold) + dcl->addElement(DELTA_BUFFER, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, 1).getSize(); + } + + // Calculate number of vertices + // Base geometry size * size + size_t baseNumVerts = (size_t)Math::Sqr(mVertexDataRecord->size); + size_t numVerts = baseNumVerts; + // Now add space for skirts + // Skirts will be rendered as copies of the edge vertices translated downwards + // Some people use one big fan with only 3 vertices at the bottom, + // but this requires creating them much bigger that necessary, meaning + // more unnecessary overdraw, so we'll use more vertices + // You need 2^levels + 1 rows of full resolution (max 129) vertex copies, plus + // the same number of columns. There are common vertices at intersections + uint16 levels = mVertexDataRecord->treeLevels; + mVertexDataRecord->numSkirtRowsCols = (uint16)(Math::Pow(2, levels) + 1); + mVertexDataRecord->skirtRowColSkip = (mVertexDataRecord->size - 1) / (mVertexDataRecord->numSkirtRowsCols - 1); + numVerts += mVertexDataRecord->size * mVertexDataRecord->numSkirtRowsCols; + numVerts += mVertexDataRecord->size * mVertexDataRecord->numSkirtRowsCols; + // manually create CPU-side buffer + HardwareVertexBufferSharedPtr posbuf( + OGRE_NEW DefaultHardwareVertexBuffer(dcl->getVertexSize(POSITION_BUFFER), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY)); + HardwareVertexBufferSharedPtr deltabuf( + OGRE_NEW DefaultHardwareVertexBuffer(dcl->getVertexSize(DELTA_BUFFER), numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY)); + + mVertexDataRecord->cpuVertexData->vertexStart = 0; + mVertexDataRecord->cpuVertexData->vertexCount = numVerts; + + Rect updateRect(mOffsetX, mOffsetY, mBoundaryX, mBoundaryY); + updateVertexBuffer(posbuf, deltabuf, updateRect); + bufbind->setBinding(POSITION_BUFFER, posbuf); + bufbind->setBinding(DELTA_BUFFER, deltabuf); + mVertexDataRecord->gpuVertexDataDirty = true; + } + } + //---------------------------------------------------------------------- + void TerrainQuadTreeNode::updateVertexBuffer(HardwareVertexBufferSharedPtr& posbuf, + HardwareVertexBufferSharedPtr& deltabuf, const Rect& rect) + { + assert (rect.left >= mOffsetX && rect.right <= mBoundaryX && + rect.top >= mOffsetY && rect.bottom <= mBoundaryY); + + // potentially reset our bounds depending on coverage of the update + resetBounds(rect); + + // Main data + uint16 inc = (mTerrain->getSize()-1) / (mVertexDataRecord->resolution-1); + long destOffsetX = rect.left <= mOffsetX ? 0 : (rect.left - mOffsetX) / inc; + long destOffsetY = rect.top <= mOffsetY ? 0 : (rect.top - mOffsetY) / inc; + // Fill the buffers + + HardwareBuffer::LockOptions lockMode; + if (destOffsetX || destOffsetY || rect.width() < mSize + || rect.height() < mSize) + { + lockMode = HardwareBuffer::HBL_NORMAL; + } + else + { + lockMode = HardwareBuffer::HBL_DISCARD; + } + + Real uvScale = 1.0f / (mTerrain->getSize() - 1); + const float* pBaseHeight = mTerrain->getHeightData(rect.left, rect.top); + const float* pBaseDelta = mTerrain->getDeltaData(rect.left, rect.top); + uint16 rowskip = mTerrain->getSize() * inc; + uint16 destPosRowSkip = 0, destDeltaRowSkip = 0; + unsigned char* pRootPosBuf = 0; + unsigned char* pRootDeltaBuf = 0; + unsigned char* pRowPosBuf = 0; + unsigned char* pRowDeltaBuf = 0; + + if (!posbuf.isNull()) + { + destPosRowSkip = mVertexDataRecord->size * posbuf->getVertexSize(); + pRootPosBuf = static_cast(posbuf->lock(lockMode)); + pRowPosBuf = pRootPosBuf; + // skip dest buffer in by left/top + pRowPosBuf += destOffsetY * destPosRowSkip + destOffsetX * posbuf->getVertexSize(); + } + if (!deltabuf.isNull()) + { + destDeltaRowSkip = mVertexDataRecord->size * deltabuf->getVertexSize(); + pRootDeltaBuf = static_cast(deltabuf->lock(lockMode)); + pRowDeltaBuf = pRootDeltaBuf; + // skip dest buffer in by left/top + pRowDeltaBuf += destOffsetY * destDeltaRowSkip + destOffsetX * deltabuf->getVertexSize(); + } + Vector3 pos; + + bool vcompress = mTerrain->_getUseVertexCompression(); + + for (uint16 y = rect.top; y < rect.bottom; y += inc) + { + const float* pHeight = pBaseHeight; + const float* pDelta = pBaseDelta; + float* pPosBuf = static_cast(static_cast(pRowPosBuf)); + float* pDeltaBuf = static_cast(static_cast(pRowDeltaBuf)); + for (uint16 x = rect.left; x < rect.right; x += inc) + { + if (pPosBuf) + { + mTerrain->getPoint(x, y, *pHeight, &pos); + + // Update bounds *before* making relative + mergeIntoBounds(x, y, pos); + // relative to local centre + pos -= mLocalCentre; + + writePosVertex(vcompress, x, y, *pHeight, pos, uvScale, &pPosBuf); + pHeight += inc; + + + } + + if (pDeltaBuf) + { + // delta, and delta LOD threshold + // we want delta to apply to LODs no higher than this value + // at runtime this will be combined with a per-renderable parameter + // to ensure we only apply morph to the correct LOD + writeDeltaVertex(vcompress, x, y, *pDelta, + (float)mTerrain->getLODLevelWhenVertexEliminated(x, y) - 1.0f, + &pDeltaBuf); + pDelta += inc; + + } + + + } + pBaseHeight += rowskip; + pBaseDelta += rowskip; + if (pRowPosBuf) + pRowPosBuf += destPosRowSkip; + if (pRowDeltaBuf) + pRowDeltaBuf += destDeltaRowSkip; + + } + + // Skirts now + // skirt spacing based on top-level resolution (* inc to cope with resolution which is not the max) + uint16 skirtSpacing = mVertexDataRecord->skirtRowColSkip * inc; + Vector3 skirtOffset; + mTerrain->getVector(0, 0, -mTerrain->getSkirtSize(), &skirtOffset); + + // skirt rows + // clamp rows to skirt spacing (round up) + long skirtStartX = rect.left; + long skirtStartY = rect.top; + // for rows, clamp Y to skirt frequency, X to inc (LOD resolution vs top) + if (skirtStartY % skirtSpacing) + skirtStartY += skirtSpacing - (skirtStartY % skirtSpacing); + if (skirtStartX % inc) + skirtStartX += inc - (skirtStartX % inc); + skirtStartY = std::max(skirtStartY, (long)mOffsetY); + pBaseHeight = mTerrain->getHeightData(skirtStartX, skirtStartY); + if (!posbuf.isNull()) + { + // position dest buffer just after the main vertex data + pRowPosBuf = pRootPosBuf + posbuf->getVertexSize() + * mVertexDataRecord->size * mVertexDataRecord->size; + // move it onwards to skip the skirts we don't need to update + pRowPosBuf += destPosRowSkip * ((skirtStartY - mOffsetY) / skirtSpacing); + pRowPosBuf += posbuf->getVertexSize() * (skirtStartX - mOffsetX) / inc; + } + if (!deltabuf.isNull()) + { + // position dest buffer just after the main vertex data + pRowDeltaBuf = pRootDeltaBuf + deltabuf->getVertexSize() + * mVertexDataRecord->size * mVertexDataRecord->size; + // move it onwards to skip the skirts we don't need to update + pRowDeltaBuf += destDeltaRowSkip * (skirtStartY - mOffsetY) / skirtSpacing; + pRowDeltaBuf += deltabuf->getVertexSize() * (skirtStartX - mOffsetX) / inc; + } + for (uint16 y = skirtStartY; y < rect.bottom; y += skirtSpacing) + { + const float* pHeight = pBaseHeight; + float* pPosBuf = static_cast(static_cast(pRowPosBuf)); + float* pDeltaBuf = static_cast(static_cast(pRowDeltaBuf)); + for (uint16 x = skirtStartX; x < rect.right; x += inc) + { + if (pPosBuf) + { + mTerrain->getPoint(x, y, *pHeight, &pos); + // relative to local centre + pos -= mLocalCentre; + pos += skirtOffset; + writePosVertex(vcompress, x, y, *pHeight - mTerrain->getSkirtSize(), pos, uvScale, &pPosBuf); + + pHeight += inc; + + + + } + + if (pDeltaBuf) + { + // delta (none) + // delta threshold (irrelevant) + writeDeltaVertex(vcompress, x, y, 0, 99, &pDeltaBuf); + } + } + pBaseHeight += mTerrain->getSize() * skirtSpacing; + if (pRowPosBuf) + pRowPosBuf += destPosRowSkip; + if (pRowDeltaBuf) + pRowDeltaBuf += destDeltaRowSkip; + } + // skirt cols + // clamp cols to skirt spacing (round up) + skirtStartX = rect.left; + if (skirtStartX % skirtSpacing) + skirtStartX += skirtSpacing - (skirtStartX % skirtSpacing); + // clamp Y to inc (LOD resolution vs top) + skirtStartY = rect.top; + if (skirtStartY % inc) + skirtStartY += inc - (skirtStartY % inc); + skirtStartX = std::max(skirtStartX, (long)mOffsetX); + if (!posbuf.isNull()) + { + // position dest buffer just after the main vertex data and skirt rows + pRowPosBuf = pRootPosBuf + posbuf->getVertexSize() + * mVertexDataRecord->size * mVertexDataRecord->size; + // skip the row skirts + pRowPosBuf += mVertexDataRecord->numSkirtRowsCols * mVertexDataRecord->size * posbuf->getVertexSize(); + // move it onwards to skip the skirts we don't need to update + pRowPosBuf += destPosRowSkip * (skirtStartX - mOffsetX) / skirtSpacing; + pRowPosBuf += posbuf->getVertexSize() * (skirtStartY - mOffsetY) / inc; + } + if (!deltabuf.isNull()) + { + // Delta dest buffer just after the main vertex data and skirt rows + pRowDeltaBuf = pRootDeltaBuf + deltabuf->getVertexSize() + * mVertexDataRecord->size * mVertexDataRecord->size; + // skip the row skirts + pRowDeltaBuf += mVertexDataRecord->numSkirtRowsCols * mVertexDataRecord->size * deltabuf->getVertexSize(); + // move it onwards to skip the skirts we don't need to update + pRowDeltaBuf += destDeltaRowSkip * (skirtStartX - mOffsetX) / skirtSpacing; + pRowDeltaBuf += deltabuf->getVertexSize() * (skirtStartY - mOffsetY) / inc; + } + + for (uint16 x = skirtStartX; x < rect.right; x += skirtSpacing) + { + float* pPosBuf = static_cast(static_cast(pRowPosBuf)); + float* pDeltaBuf = static_cast(static_cast(pRowDeltaBuf)); + for (uint16 y = skirtStartY; y < rect.bottom; y += inc) + { + if (pPosBuf) + { + float height = mTerrain->getHeightAtPoint(x, y); + mTerrain->getPoint(x, y, height, &pos); + // relative to local centre + pos -= mLocalCentre; + pos += skirtOffset; + + writePosVertex(vcompress, x, y, height - mTerrain->getSkirtSize(), pos, uvScale, &pPosBuf); + + } + if (pDeltaBuf) + { + // delta (none) + // delta threshold (irrelevant) + writeDeltaVertex(vcompress, x, y, 0, 99, &pDeltaBuf); + } + } + if (pRowPosBuf) + pRowPosBuf += destPosRowSkip; + if (pRowDeltaBuf) + pRowDeltaBuf += destDeltaRowSkip; + } + + if (!posbuf.isNull()) + posbuf->unlock(); + if (!deltabuf.isNull()) + deltabuf->unlock(); + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::writePosVertex(bool compress, uint16 x, uint16 y, float height, + const Vector3& pos, float uvScale, float** ppPos) + { + float* pPosBuf = *ppPos; + + if (compress) + { + short* pPosShort = static_cast(static_cast(pPosBuf)); + *pPosShort++ = (short)x; + *pPosShort++ = (short)y; + pPosBuf = static_cast(static_cast(pPosShort)); + + *pPosBuf++ = height; + } + else + { + *pPosBuf++ = pos.x; + *pPosBuf++ = pos.y; + *pPosBuf++ = pos.z; + + // UVs - base UVs vary from 0 to 1, all other values + // will be derived using scalings + *pPosBuf++ = x * uvScale; + *pPosBuf++ = 1.0f - (y * uvScale); + } + + *ppPos = pPosBuf; + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::writeDeltaVertex(bool compress, uint16 x, uint16 y, + float delta, float deltaThresh, float** ppDelta) + { + *(*ppDelta)++ = delta; + *(*ppDelta)++ = deltaThresh; + } + //--------------------------------------------------------------------- + uint16 TerrainQuadTreeNode::calcSkirtVertexIndex(uint16 mainIndex, bool isCol) + { + const VertexDataRecord* vdr = getVertexDataRecord(); + // row / col in main vertex resolution + uint16 row = mainIndex / vdr->size; + uint16 col = mainIndex % vdr->size; + + // skrits are after main vertices, so skip them + uint16 base = vdr->size * vdr->size; + + // The layout in vertex data is: + // 1. row skirts + // numSkirtRowsCols rows of resolution vertices each + // 2. column skirts + // numSkirtRowsCols cols of resolution vertices each + + // No offsets used here, this is an index into the current vertex data, + // which is already relative + if (isCol) + { + uint16 skirtNum = col / vdr->skirtRowColSkip; + uint16 colbase = vdr->numSkirtRowsCols * vdr->size; + return base + colbase + vdr->size * skirtNum + row; + } + else + { + uint16 skirtNum = row / vdr->skirtRowColSkip; + return base + vdr->size * skirtNum + col; + } + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::destroyCpuVertexData() + { + if (mVertexDataRecord && mVertexDataRecord->cpuVertexData) + { + // avoid copy empty buffer + mVertexDataRecord->gpuVertexDataDirty = false; + // delete the bindings and declaration manually since not from a buf mgr + OGRE_DELETE mVertexDataRecord->cpuVertexData->vertexDeclaration; + mVertexDataRecord->cpuVertexData->vertexDeclaration = 0; + + OGRE_DELETE mVertexDataRecord->cpuVertexData->vertexBufferBinding; + mVertexDataRecord->cpuVertexData->vertexBufferBinding = 0; + + OGRE_DELETE mVertexDataRecord->cpuVertexData; + mVertexDataRecord->cpuVertexData = 0; + } + + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::populateIndexData(uint16 batchSize, IndexData* destData) + { + const VertexDataRecord* vdr = getVertexDataRecord(); + + // Ratio of the main terrain resolution in relation to this vertex data resolution + size_t resolutionRatio = (mTerrain->getSize() - 1) / (vdr->resolution - 1); + // At what frequency do we sample the vertex data we're using? + // mSize is the coverage in terms of the original terrain data (not split to fit in 16-bit) + size_t vertexIncrement = (mSize-1) / (batchSize-1); + // however, the vertex data we're referencing may not be at the full resolution anyway + vertexIncrement /= resolutionRatio; + uint16 vdatasizeOffsetX = (mOffsetX - mNodeWithVertexData->mOffsetX) / resolutionRatio; + uint16 vdatasizeOffsetY = (mOffsetY - mNodeWithVertexData->mOffsetY) / resolutionRatio; + + destData->indexBuffer = mTerrain->getGpuBufferAllocator()->getSharedIndexBuffer(batchSize, vdr->size, + vertexIncrement, vdatasizeOffsetX, vdatasizeOffsetY, + vdr->numSkirtRowsCols, vdr->skirtRowColSkip); + destData->indexStart = 0; + destData->indexCount = destData->indexBuffer->getNumIndexes(); + + // shared index buffer is pre-populated + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::createGpuVertexData() + { + // TODO - mutex cpu data + if (mVertexDataRecord && mVertexDataRecord->cpuVertexData && !mVertexDataRecord->gpuVertexData) + { + // copy data from CPU to GPU, but re-use vertex buffers (so don't use regular clone) + mVertexDataRecord->gpuVertexData = OGRE_NEW VertexData(); + VertexData* srcData = mVertexDataRecord->cpuVertexData; + VertexData* destData = mVertexDataRecord->gpuVertexData; + + // copy vertex buffers + // get new buffers + HardwareVertexBufferSharedPtr destPosBuf, destDeltaBuf; + mTerrain->getGpuBufferAllocator()->allocateVertexBuffers(mTerrain, srcData->vertexCount, + destPosBuf, destDeltaBuf); + + // copy data + destPosBuf->copyData(*srcData->vertexBufferBinding->getBuffer(POSITION_BUFFER)); + destDeltaBuf->copyData(*srcData->vertexBufferBinding->getBuffer(DELTA_BUFFER)); + + // set bindings + destData->vertexBufferBinding->setBinding(POSITION_BUFFER, destPosBuf); + destData->vertexBufferBinding->setBinding(DELTA_BUFFER, destDeltaBuf); + + // Basic vertex info + destData->vertexStart = srcData->vertexStart; + destData->vertexCount = srcData->vertexCount; + // Copy elements + const VertexDeclaration::VertexElementList elems = + srcData->vertexDeclaration->getElements(); + VertexDeclaration::VertexElementList::const_iterator ei, eiend; + eiend = elems.end(); + for (ei = elems.begin(); ei != eiend; ++ei) + { + destData->vertexDeclaration->addElement( + ei->getSource(), + ei->getOffset(), + ei->getType(), + ei->getSemantic(), + ei->getIndex() ); + } + + // We don't need the CPU copy anymore + destroyCpuVertexData(); + } + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::updateGpuVertexData() + { + if (mVertexDataRecord && mVertexDataRecord->gpuVertexDataDirty) + { + mVertexDataRecord->gpuVertexData->vertexBufferBinding->getBuffer(POSITION_BUFFER)-> + copyData(*mVertexDataRecord->cpuVertexData->vertexBufferBinding->getBuffer(POSITION_BUFFER).get()); + mVertexDataRecord->gpuVertexData->vertexBufferBinding->getBuffer(DELTA_BUFFER)-> + copyData(*mVertexDataRecord->cpuVertexData->vertexBufferBinding->getBuffer(DELTA_BUFFER).get()); + mVertexDataRecord->gpuVertexDataDirty = false; + } + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::destroyGpuVertexData() + { + if (mVertexDataRecord && mVertexDataRecord->gpuVertexData) + { + // Before we delete, free up the vertex buffers for someone else + mTerrain->getGpuBufferAllocator()->freeVertexBuffers( + mVertexDataRecord->gpuVertexData->vertexBufferBinding->getBuffer(POSITION_BUFFER), + mVertexDataRecord->gpuVertexData->vertexBufferBinding->getBuffer(DELTA_BUFFER)); + OGRE_DELETE mVertexDataRecord->gpuVertexData; + mVertexDataRecord->gpuVertexData = 0; + } + + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::createGpuIndexData() + { + for (size_t lod = 0; lod < mLodLevels.size(); ++lod) + { + LodLevel* ll = mLodLevels[lod]; + + if (!ll->gpuIndexData) + { + // clone, using default buffer manager ie hardware + ll->gpuIndexData = OGRE_NEW IndexData(); + populateIndexData(ll->batchSize, ll->gpuIndexData); + } + + } + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::destroyGpuIndexData() + { + for (size_t lod = 0; lod < mLodLevels.size(); ++lod) + { + LodLevel* ll = mLodLevels[lod]; + + OGRE_DELETE ll->gpuIndexData; + ll->gpuIndexData = 0; + } + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::mergeIntoBounds(long x, long y, const Vector3& pos) + { + if (pointIntersectsNode(x, y)) + { + Vector3 localPos = pos - mLocalCentre; + mAABB.merge(localPos); + mBoundingRadius = std::max(mBoundingRadius, localPos.length()); + + if (!isLeaf()) + { + for (int i = 0; i < 4; ++i) + mChildren[i]->mergeIntoBounds(x, y, pos); + } + } + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::resetBounds(const Rect& rect) + { + if (rectContainsNode(rect)) + { + mAABB.setNull(); + mBoundingRadius = 0; + + if (!isLeaf()) + { + for (int i = 0; i < 4; ++i) + mChildren[i]->resetBounds(rect); + } + + + } + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::rectContainsNode(const Rect& rect) + { + return (rect.left <= mOffsetX && rect.right > mBoundaryX && + rect.top <= mOffsetY && rect.bottom > mBoundaryY); + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::rectIntersectsNode(const Rect& rect) + { + return (rect.right >= mOffsetX && rect.left <= mBoundaryX && + rect.bottom >= mOffsetY && rect.top <= mBoundaryY); + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::pointIntersectsNode(long x, long y) + { + return x >= mOffsetX && x < mBoundaryX && + y >= mOffsetY && y < mBoundaryY; + } + //--------------------------------------------------------------------- + const AxisAlignedBox& TerrainQuadTreeNode::getAABB() const + { + return mAABB; + } + //--------------------------------------------------------------------- + Real TerrainQuadTreeNode::getBoundingRadius() const + { + return mBoundingRadius; + } + //--------------------------------------------------------------------- + Real TerrainQuadTreeNode::getMinHeight() const + { + switch (mTerrain->getAlignment()) + { + case Terrain::ALIGN_X_Y: + default: + return mAABB.getMinimum().z; + case Terrain::ALIGN_X_Z: + return mAABB.getMinimum().y; + case Terrain::ALIGN_Y_Z: + return mAABB.getMinimum().x; + }; + } + //--------------------------------------------------------------------- + Real TerrainQuadTreeNode::getMaxHeight() const + { + switch (mTerrain->getAlignment()) + { + case Terrain::ALIGN_X_Y: + default: + return mAABB.getMaximum().z; + case Terrain::ALIGN_X_Z: + return mAABB.getMaximum().y; + case Terrain::ALIGN_Y_Z: + return mAABB.getMaximum().x; + }; + + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::calculateCurrentLod(const Camera* cam, Real cFactor) + { + mSelfOrChildRendered = false; + + // early-out + /* disable this, could cause 'jumps' in LOD as children go out of frustum + if (!cam->isVisible(mMovable->getWorldBoundingBox(true))) + { + mCurrentLod = -1; + return mSelfOrChildRendered; + } + */ + + // Check children first + int childRenderedCount = 0; + if (!isLeaf()) + { + for (int i = 0; i < 4; ++i) + { + if (mChildren[i]->calculateCurrentLod(cam, cFactor)) + ++childRenderedCount; + } + + } + + // this node not loaded yet so skip + if (!mMovable->isAttached()) + { + mCurrentLod = -1; + return mSelfOrChildRendered; + } + + if (childRenderedCount == 0) + { + + // no children were within their LOD ranges, so we should consider our own + Vector3 localPos = cam->getDerivedPosition() - mLocalCentre - mTerrain->getPosition(); + Real dist; + if (TerrainGlobalOptions::getSingleton().getUseRayBoxDistanceCalculation()) + { + // Get distance to this terrain node (to closest point of the box) + // head towards centre of the box (note, box may not cover mLocalCentre because of height) + Vector3 dir(mAABB.getCenter() - localPos); + dir.normalise(); + Ray ray(localPos, dir); + std::pair intersectRes = Math::intersects(ray, mAABB); + + // ray will always intersect, we just want the distance + dist = intersectRes.second; + } + else + { + // distance to tile centre + dist = localPos.length(); + // deduct half the radius of the box, assume that on average the + // worst case is best approximated by this + dist -= (mBoundingRadius * 0.5f); + } + + // Do material LOD + MaterialPtr material = getMaterial(); + const LodStrategy *materialStrategy = material->getLodStrategy(); + Real lodValue = materialStrategy->getValue(mMovable, cam); + // Get the index at this biased depth + mMaterialLodIndex = material->getLodIndex(lodValue); + + + // For each LOD, the distance at which the LOD will transition *downwards* + // is given by + // distTransition = maxDelta * cFactor; + uint lodLvl = 0; + mCurrentLod = -1; + for (LodLevelList::iterator i = mLodLevels.begin(); i != mLodLevels.end(); ++i, ++lodLvl) + { + // If we have no parent, and this is the lowest LOD, we always render + // this is the 'last resort' so to speak, we always enoucnter this last + if (lodLvl+1 == mLodLevels.size() && !mParent) + { + mCurrentLod = lodLvl; + mSelfOrChildRendered = true; + mLodTransition = 0; + } + else + { + // check the distance + LodLevel* ll = *i; + + // Calculate or reuse transition distance + Real distTransition; + if (Math::RealEqual(cFactor, ll->lastCFactor)) + distTransition = ll->lastTransitionDist; + else + { + distTransition = ll->maxHeightDelta * cFactor; + ll->lastCFactor = cFactor; + ll->lastTransitionDist = distTransition; + } + + if (dist < distTransition) + { + // we're within range of this LOD + mCurrentLod = lodLvl; + mSelfOrChildRendered = true; + + if (mTerrain->_getMorphRequired()) + { + // calculate the transition percentage + // we need a percentage of the total distance for just this LOD, + // which means taking off the distance for the next higher LOD + // which is either the previous entry in the LOD list, + // or the largest of any children. In both cases these will + // have been calculated before this point, since we process + // children first. Distances at lower LODs are guaranteed + // to be larger than those at higher LODs + + Real distTotal = distTransition; + if (isLeaf()) + { + // Any higher LODs? + if (i != mLodLevels.begin()) + { + LodLevelList::iterator prev = i - 1; + distTotal -= (*prev)->lastTransitionDist; + } + } + else + { + // Take the distance of the lowest LOD of child + const LodLevel* childLod = mChildWithMaxHeightDelta->getLodLevel( + mChildWithMaxHeightDelta->getLodCount()-1); + distTotal -= childLod->lastTransitionDist; + } + // fade from 0 to 1 in the last 25% of the distance + Real distMorphRegion = distTotal * 0.25f; + Real distRemain = distTransition - dist; + + mLodTransition = 1.0f - (distRemain / distMorphRegion); + mLodTransition = std::min(1.0f, mLodTransition); + mLodTransition = std::max(0.0f, mLodTransition); + + // Pass both the transition % and target LOD (GLOBAL current + 1) + // this selectively applies the morph just to the + // vertices which would drop out at this LOD, even + // while using the single shared vertex data + mRend->setCustomParameter(Terrain::LOD_MORPH_CUSTOM_PARAM, + Vector4(mLodTransition, mCurrentLod + mBaseLod + 1, 0, 0)); + + } + // since LODs are ordered from highest to lowest detail, + // we can stop looking now + break; + } + + } + } + + } + else + { + // we should not render ourself + mCurrentLod = -1; + mSelfOrChildRendered = true; + if (childRenderedCount < 4) + { + // only *some* children decided to render on their own, but either + // none or all need to render, so set the others manually to their lowest + for (int i = 0; i < 4; ++i) + { + TerrainQuadTreeNode* child = mChildren[i]; + if (!child->isSelfOrChildRenderedAtCurrentLod()) + { + child->setCurrentLod(child->getLodCount()-1); + child->setLodTransition(1.0); + } + } + } // (childRenderedCount < 4) + + } // (childRenderedCount == 0) + + + return mSelfOrChildRendered; + + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::setCurrentLod(int lod) + { + mCurrentLod = lod; + mRend->setCustomParameter(Terrain::LOD_MORPH_CUSTOM_PARAM, + Vector4(mLodTransition, mCurrentLod + mBaseLod + 1, 0, 0)); + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::setLodTransition(float t) + { + mLodTransition = t; + mRend->setCustomParameter(Terrain::LOD_MORPH_CUSTOM_PARAM, + Vector4(mLodTransition, mCurrentLod + mBaseLod + 1, 0, 0)); + } + //--------------------------------------------------------------------- + Renderable *TerrainQuadTreeNode::_getRenderable() + { + return mRend; + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::isRenderedAtCurrentLod() const + { + return mCurrentLod != -1; + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::isSelfOrChildRenderedAtCurrentLod() const + { + return mSelfOrChildRendered; + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::updateRenderQueue(RenderQueue* queue) + { + if (isRenderedAtCurrentLod()) + { + queue->addRenderable(mRend, mTerrain->getRenderQueueGroup()); + } + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::visitRenderables(Renderable::Visitor* visitor, bool debugRenderables) + { + visitor->visit(mRend, 0, false); + } + //--------------------------------------------------------------------- + const MaterialPtr& TerrainQuadTreeNode::getMaterial(void) const + { + return mTerrain->getMaterial(); + } + //--------------------------------------------------------------------- + Technique* TerrainQuadTreeNode::getTechnique(void) const + { + return getMaterial()->getBestTechnique(mMaterialLodIndex, mRend); + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::getRenderOperation(RenderOperation& op) + { + mNodeWithVertexData->updateGpuVertexData(); + + op.indexData = mLodLevels[mCurrentLod]->gpuIndexData; + op.operationType = RenderOperation::OT_TRIANGLE_STRIP; + op.useIndexes = true; + op.vertexData = getVertexDataRecord()->gpuVertexData; + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::getWorldTransforms(Matrix4* xform) const + { + if (mTerrain->_getUseVertexCompression()) + { + // vertex data is generated in terrain space + *xform = Matrix4::IDENTITY; + xform->setTrans(mTerrain->getPosition()); + + } + else + { + // the vertex data is relative to the node that owns the vertex data + *xform = mNodeWithVertexData->mMovable->_getParentNodeFullTransform(); + } + + } + //--------------------------------------------------------------------- + Real TerrainQuadTreeNode::getSquaredViewDepth(const Camera* cam) const + { + return mMovable->getParentSceneNode()->getSquaredViewDepth(cam); + } + //--------------------------------------------------------------------- + const LightList& TerrainQuadTreeNode::getLights(void) const + { + return mMovable->queryLights(); + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::getCastsShadows(void) const + { + return TerrainGlobalOptions::getSingleton().getCastsDynamicShadows(); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + TerrainQuadTreeNode::Movable::Movable(TerrainQuadTreeNode* parent) + : mParent(parent) + { + } + //--------------------------------------------------------------------- + TerrainQuadTreeNode::Movable::~Movable() + { + + } + //--------------------------------------------------------------------- + const String& TerrainQuadTreeNode::Movable::getMovableType(void) const + { + static String stype("OgreTerrainNodeMovable"); + + return stype; + + } + //--------------------------------------------------------------------- + const AxisAlignedBox& TerrainQuadTreeNode::Movable::getBoundingBox(void) const + { + return mParent->getAABB(); + } + //--------------------------------------------------------------------- + Real TerrainQuadTreeNode::Movable::getBoundingRadius(void) const + { + return mParent->getBoundingRadius(); + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::Movable::isVisible(void) const + { + if (mParent->getCurrentLod() == -1) + return false; + else + return MovableObject::isVisible(); + } + //--------------------------------------------------------------------- + uint32 TerrainQuadTreeNode::Movable::getVisibilityFlags(void) const + { + // Combine own vis (in case anyone sets this) and terrain overall + return mVisibilityFlags & mParent->getTerrain()->getVisibilityFlags(); + } + //--------------------------------------------------------------------- + uint32 TerrainQuadTreeNode::Movable::getQueryFlags(void) const + { + // Combine own vis (in case anyone sets this) and terrain overall + return mQueryFlags & mParent->getTerrain()->getQueryFlags(); + } + //------------------------------------------------------------------------ + void TerrainQuadTreeNode::Movable::_updateRenderQueue(RenderQueue* queue) + { + mParent->updateRenderQueue(queue); + } + //------------------------------------------------------------------------ + void TerrainQuadTreeNode::Movable::visitRenderables(Renderable::Visitor* visitor, bool debugRenderables) + { + mParent->visitRenderables(visitor, debugRenderables); + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::Movable::getCastShadows(void) const + { + return mParent->getCastsShadows(); + } + //------------------------------------------------------------------------ + //--------------------------------------------------------------------- + TerrainQuadTreeNode::Rend::Rend(TerrainQuadTreeNode* parent) + :mParent(parent) + { + } + //--------------------------------------------------------------------- + TerrainQuadTreeNode::Rend::~Rend() + { + } + //--------------------------------------------------------------------- + const MaterialPtr& TerrainQuadTreeNode::Rend::getMaterial(void) const + { + return mParent->getMaterial(); + } + //--------------------------------------------------------------------- + Technique* TerrainQuadTreeNode::Rend::getTechnique() const + { + return mParent->getTechnique(); + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::Rend::getRenderOperation(RenderOperation& op) + { + mParent->getRenderOperation(op); + } + //--------------------------------------------------------------------- + void TerrainQuadTreeNode::Rend::getWorldTransforms(Matrix4* xform) const + { + mParent->getWorldTransforms(xform); + } + //--------------------------------------------------------------------- + Real TerrainQuadTreeNode::Rend::getSquaredViewDepth(const Camera* cam) const + { + return mParent->getSquaredViewDepth(cam); + } + //--------------------------------------------------------------------- + const LightList& TerrainQuadTreeNode::Rend::getLights(void) const + { + return mParent->getLights(); + } + //--------------------------------------------------------------------- + bool TerrainQuadTreeNode::Rend::getCastsShadows(void) const + { + return mParent->getCastsShadows(); + } + //--------------------------------------------------------------------- + + + + + + +} + diff --git a/Components/Volume/include/OgreVolumeGridSource.h b/Components/Volume/include/OgreVolumeGridSource.h index 50858af7ad5..a2de11858a2 100644 --- a/Components/Volume/include/OgreVolumeGridSource.h +++ b/Components/Volume/include/OgreVolumeGridSource.h @@ -49,11 +49,11 @@ namespace Volume { /// The texture height. size_t mHeight; - + /// The texture depth. size_t mDepth; - /// The scale of the position based on the world width. + /// The scale of the position based on the world width. Real mPosXScale; /// The scale of the position based on the world height. diff --git a/Components/Volume/include/OgreVolumePrerequisites.h b/Components/Volume/include/OgreVolumePrerequisites.h index e38b76e90ad..c43afbd83ae 100644 --- a/Components/Volume/include/OgreVolumePrerequisites.h +++ b/Components/Volume/include/OgreVolumePrerequisites.h @@ -31,23 +31,23 @@ THE SOFTWARE. #include "OgrePrerequisites.h" #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 -# if defined( OGRE_STATIC_LIB ) -# define _OgreVolumeExport +# if defined( OGRE_STATIC_LIB ) +# define _OgreVolumeExport # else -# if defined( OGRE_VOLUME_EXPORTS ) -# define _OgreVolumeExport __declspec( dllexport ) -# else +# if defined( OGRE_VOLUME_EXPORTS ) +# define _OgreVolumeExport __declspec( dllexport ) +# else # if defined( __MINGW32__ ) # define _OgreVolumeExport # else -# define _OgreVolumeExport __declspec( dllimport ) +# define _OgreVolumeExport __declspec( dllimport ) # endif -# endif -# endif +# endif +# endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgreVolumeExport __attribute__ ((visibility("default"))) #else -# define _OgreVolumeExport +# define _OgreVolumeExport #endif #endif \ No newline at end of file diff --git a/Components/Volume/src/OgreVolumeChunk.cpp b/Components/Volume/src/OgreVolumeChunk.cpp index 796cbc79b6f..b69b214b031 100644 --- a/Components/Volume/src/OgreVolumeChunk.cpp +++ b/Components/Volume/src/OgreVolumeChunk.cpp @@ -259,11 +259,11 @@ namespace Volume { OGRE_DELETE mRenderOp.indexData; OGRE_DELETE mRenderOp.vertexData; - // Root might already be shutdown. - if (Root::getSingletonPtr()) - { - Root::getSingleton().removeFrameListener(this); - } + // Root might already be shutdown. + if (Root::getSingletonPtr()) + { + Root::getSingleton().removeFrameListener(this); + } if (mChildren) { diff --git a/OgreMain/include/Android/OgreAPKFileSystemArchive.h b/OgreMain/include/Android/OgreAPKFileSystemArchive.h index 91c25f3fa90..00d9eab37e4 100644 --- a/OgreMain/include/Android/OgreAPKFileSystemArchive.h +++ b/OgreMain/include/Android/OgreAPKFileSystemArchive.h @@ -33,15 +33,15 @@ THE SOFTWARE. #include #include -namespace Ogre{ - class APKFileSystemArchive : public Archive - { - private: - AAssetManager* mAssetMgr; - String mPathPreFix; - - public: - APKFileSystemArchive(const String& name, const String& archType, AAssetManager* assetMgr); +namespace Ogre{ + class APKFileSystemArchive : public Archive + { + private: + AAssetManager* mAssetMgr; + String mPathPreFix; + + public: + APKFileSystemArchive(const String& name, const String& archType, AAssetManager* assetMgr); ~APKFileSystemArchive(); /// @copydoc Archive::isCaseSensitive @@ -55,13 +55,13 @@ namespace Ogre{ /// @copydoc Archive::open DataStreamPtr open(const String& filename, bool readOnly = true) const; - /// @copydoc Archive::create - DataStreamPtr create(const String& filename) const; + /// @copydoc Archive::create + DataStreamPtr create(const String& filename) const; - /// @copydoc Archive::delete - void remove(const String& filename) const; + /// @copydoc Archive::delete + void remove(const String& filename) const; - /// @copydoc Archive::list + /// @copydoc Archive::list StringVectorPtr list(bool recursive = true, bool dirs = false); /// @copydoc Archive::listFileInfo @@ -76,14 +76,14 @@ namespace Ogre{ /// @copydoc Archive::exists bool exists(const String& filename); - /// @copydoc Archive::getModifiedTime - time_t getModifiedTime(const String& filename); - }; - - class APKFileSystemArchiveFactory : public ArchiveFactory + /// @copydoc Archive::getModifiedTime + time_t getModifiedTime(const String& filename); + }; + + class APKFileSystemArchiveFactory : public ArchiveFactory { public: - APKFileSystemArchiveFactory(AAssetManager* assetMgr) : mAssetMgr(assetMgr) {} + APKFileSystemArchiveFactory(AAssetManager* assetMgr) : mAssetMgr(assetMgr) {} virtual ~APKFileSystemArchiveFactory() {} /// @copydoc FactoryObj::getType const String& getType(void) const; diff --git a/OgreMain/include/Android/OgreAPKZipArchive.h b/OgreMain/include/Android/OgreAPKZipArchive.h index 96b9b0b2525..5b7fad15b24 100644 --- a/OgreMain/include/Android/OgreAPKZipArchive.h +++ b/OgreMain/include/Android/OgreAPKZipArchive.h @@ -35,34 +35,34 @@ THE SOFTWARE. namespace Ogre{ - class APKZipArchiveFactory : public EmbeddedZipArchiveFactory - { - protected: - AAssetManager* mAssetMgr; - public: - APKZipArchiveFactory(AAssetManager* assetMgr) : mAssetMgr(assetMgr) {} - virtual ~APKZipArchiveFactory() {} + class APKZipArchiveFactory : public EmbeddedZipArchiveFactory + { + protected: + AAssetManager* mAssetMgr; + public: + APKZipArchiveFactory(AAssetManager* assetMgr) : mAssetMgr(assetMgr) {} + virtual ~APKZipArchiveFactory() {} - /// @copydoc FactoryObj::getType - const String& getType(void) const; + /// @copydoc FactoryObj::getType + const String& getType(void) const; - /// @copydoc FactoryObj::createInstance - Archive *createInstance( const String& name, bool readOnly ) - { - String apkName = name; - if (apkName.size() > 0 && apkName[0] == '/') - apkName.erase(apkName.begin()); + /// @copydoc FactoryObj::createInstance + Archive *createInstance( const String& name, bool readOnly ) + { + String apkName = name; + if (apkName.size() > 0 && apkName[0] == '/') + apkName.erase(apkName.begin()); - AAsset* asset = AAssetManager_open(mAssetMgr, apkName.c_str(), AASSET_MODE_BUFFER); - if(asset) - { - EmbeddedZipArchiveFactory::addEmbbeddedFile(apkName, (const Ogre::uint8*)AAsset_getBuffer(asset), AAsset_getLength(asset), 0); - } + AAsset* asset = AAssetManager_open(mAssetMgr, apkName.c_str(), AASSET_MODE_BUFFER); + if(asset) + { + EmbeddedZipArchiveFactory::addEmbbeddedFile(apkName, (const Ogre::uint8*)AAsset_getBuffer(asset), AAsset_getLength(asset), 0); + } ZipArchive * resZipArchive = OGRE_NEW ZipArchive(apkName, "APKZip", mPluginIo); return resZipArchive; - } - }; + } + }; } #endif diff --git a/OgreMain/include/Android/OgreAndroidLogListener.h b/OgreMain/include/Android/OgreAndroidLogListener.h index eef071857f4..5ea4f8e3022 100644 --- a/OgreMain/include/Android/OgreAndroidLogListener.h +++ b/OgreMain/include/Android/OgreAndroidLogListener.h @@ -38,7 +38,7 @@ namespace Ogre { public: AndroidLogListener(); - + virtual void messageLogged(const Ogre::String& message, Ogre::LogMessageLevel lml, bool maskDebug, const Ogre::String &logName, bool& skipThisMessage ); }; } diff --git a/OgreMain/include/Android/OgreConfigDialogImp.h b/OgreMain/include/Android/OgreConfigDialogImp.h index f155ab039b1..9046f9f4d05 100644 --- a/OgreMain/include/Android/OgreConfigDialogImp.h +++ b/OgreMain/include/Android/OgreConfigDialogImp.h @@ -35,23 +35,23 @@ THE SOFTWARE. namespace Ogre { - class _OgreExport ConfigDialog : public UtilityAlloc - { - public: - ConfigDialog(); - ~ConfigDialog(); - - public: - void initialise(); - void run(); - void cancel(); - - bool display(); - - protected: - RenderSystem* iSelectedRenderSystem; - bool iDisplayStatus; - }; + class _OgreExport ConfigDialog : public UtilityAlloc + { + public: + ConfigDialog(); + ~ConfigDialog(); + + public: + void initialise(); + void run(); + void cancel(); + + bool display(); + + protected: + RenderSystem* iSelectedRenderSystem; + bool iDisplayStatus; + }; } #endif // __AndroidConfigDialog_H__ diff --git a/OgreMain/include/Android/OgreErrorDialogImp.h b/OgreMain/include/Android/OgreErrorDialogImp.h index 656806f0b4a..ed493f0efe8 100644 --- a/OgreMain/include/Android/OgreErrorDialogImp.h +++ b/OgreMain/include/Android/OgreErrorDialogImp.h @@ -32,21 +32,21 @@ THE SOFTWARE. namespace Ogre { - /** Class for displaying the error dialog if Ogre fails badly. */ - class _OgreExport ErrorDialog - { - public: - ErrorDialog(); + /** Class for displaying the error dialog if Ogre fails badly. */ + class _OgreExport ErrorDialog + { + public: + ErrorDialog(); - /** - @remarks - Displays the error dialog. - @param - errorMessage The error message which has caused the failure. - @param - logName Optional name of the log to display in the detail pane. - */ - void display(const String& errorMessage, String logName = ""); - }; + /** + @remarks + Displays the error dialog. + @param + errorMessage The error message which has caused the failure. + @param + logName Optional name of the log to display in the detail pane. + */ + void display(const String& errorMessage, String logName = ""); + }; } #endif diff --git a/OgreMain/include/Android/OgreTimerImp.h b/OgreMain/include/Android/OgreTimerImp.h index 37c6307f42b..024b96e89f5 100644 --- a/OgreMain/include/Android/OgreTimerImp.h +++ b/OgreMain/include/Android/OgreTimerImp.h @@ -33,20 +33,20 @@ THE SOFTWARE. namespace Ogre { - /** Timer class */ - class _OgreExport Timer : public TimerAlloc - { - private: - struct timeval start; - clock_t zeroClock; - public: - Timer(); - ~Timer(); + /** Timer class */ + class _OgreExport Timer : public TimerAlloc + { + private: + struct timeval start; + clock_t zeroClock; + public: + Timer(); + ~Timer(); - /** Method for setting a specific option of the Timer. These options are usually + /** Method for setting a specific option of the Timer. These options are usually specific for a certain implementation of the Timer class, and may (and probably will) not exist across different implementations. reset() must be called after - all setOption() calls. + all setOption() calls. @param strKey The name of the option to set @param @@ -59,20 +59,20 @@ namespace Ogre */ bool setOption( const String& strKey, const void* pValue ) { return false; } - /** Resets timer */ - void reset(); + /** Resets timer */ + void reset(); - /** Returns milliseconds since initialisation or last reset */ - unsigned long getMilliseconds(); + /** Returns milliseconds since initialisation or last reset */ + unsigned long getMilliseconds(); - /** Returns microseconds since initialisation or last reset */ - unsigned long getMicroseconds(); + /** Returns microseconds since initialisation or last reset */ + unsigned long getMicroseconds(); - /** Returns milliseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMillisecondsCPU(); + /** Returns milliseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMillisecondsCPU(); - /** Returns microseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMicrosecondsCPU(); - }; + /** Returns microseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMicrosecondsCPU(); + }; } #endif diff --git a/OgreMain/include/FlashCC/OgreConfigDialogImp.h b/OgreMain/include/FlashCC/OgreConfigDialogImp.h index 7bcab6ad626..7b4b8ce46cf 100644 --- a/OgreMain/include/FlashCC/OgreConfigDialogImp.h +++ b/OgreMain/include/FlashCC/OgreConfigDialogImp.h @@ -35,23 +35,23 @@ THE SOFTWARE. namespace Ogre { - class _OgreExport ConfigDialog : public UtilityAlloc - { - public: - ConfigDialog(); - ~ConfigDialog(); - - public: - void initialise(); - void run(); - void cancel(); - - bool display(); - - protected: - RenderSystem* iSelectedRenderSystem; - bool iDisplayStatus; - }; + class _OgreExport ConfigDialog : public UtilityAlloc + { + public: + ConfigDialog(); + ~ConfigDialog(); + + public: + void initialise(); + void run(); + void cancel(); + + bool display(); + + protected: + RenderSystem* iSelectedRenderSystem; + bool iDisplayStatus; + }; } #endif // __AndroidConfigDialog_H__ diff --git a/OgreMain/include/FlashCC/OgreTimerImp.h b/OgreMain/include/FlashCC/OgreTimerImp.h index aabdb25eab9..8edcc981aff 100644 --- a/OgreMain/include/FlashCC/OgreTimerImp.h +++ b/OgreMain/include/FlashCC/OgreTimerImp.h @@ -33,20 +33,20 @@ THE SOFTWARE. namespace Ogre { - /** Timer class */ - class _OgreExport Timer : public TimerAlloc - { - private: - struct timeval start; - clock_t zeroClock; - public: - Timer(); - ~Timer(); + /** Timer class */ + class _OgreExport Timer : public TimerAlloc + { + private: + struct timeval start; + clock_t zeroClock; + public: + Timer(); + ~Timer(); - /** Method for setting a specific option of the Timer. These options are usually + /** Method for setting a specific option of the Timer. These options are usually specific for a certain implementation of the Timer class, and may (and probably will) not exist across different implementations. reset() must be called after - all setOption() calls. + all setOption() calls. @param strKey The name of the option to set @param @@ -59,20 +59,20 @@ namespace Ogre */ bool setOption( const String& strKey, const void* pValue ) { return false; } - /** Resets timer */ - void reset(); + /** Resets timer */ + void reset(); - /** Returns milliseconds since initialisation or last reset */ - unsigned long getMilliseconds(); + /** Returns milliseconds since initialisation or last reset */ + unsigned long getMilliseconds(); - /** Returns microseconds since initialisation or last reset */ - unsigned long getMicroseconds(); + /** Returns microseconds since initialisation or last reset */ + unsigned long getMicroseconds(); - /** Returns milliseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMillisecondsCPU(); + /** Returns milliseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMillisecondsCPU(); - /** Returns microseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMicrosecondsCPU(); - }; + /** Returns microseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMicrosecondsCPU(); + }; } #endif diff --git a/OgreMain/include/GLX/OgreConfigDialogImp.h b/OgreMain/include/GLX/OgreConfigDialogImp.h index b0ad6ecd57c..55c5b5ed25e 100644 --- a/OgreMain/include/GLX/OgreConfigDialogImp.h +++ b/OgreMain/include/GLX/OgreConfigDialogImp.h @@ -35,41 +35,41 @@ THE SOFTWARE. namespace Ogre { - /** Defines the behaviour of an automatic renderer configuration dialog. - @remarks - OGRE comes with it's own renderer configuration dialog, which - applications can use to easily allow the user to configure the - settings appropriate to their machine. This class defines the - interface to this standard dialog. Because dialogs are inherently - tied to a particular platform's windowing system, there will be a - different subclass for each platform. - @author - Steven J. Streeting - */ - class _OgreExport ConfigDialog : public UtilityAlloc - { - public: - ConfigDialog(); + /** Defines the behaviour of an automatic renderer configuration dialog. + @remarks + OGRE comes with it's own renderer configuration dialog, which + applications can use to easily allow the user to configure the + settings appropriate to their machine. This class defines the + interface to this standard dialog. Because dialogs are inherently + tied to a particular platform's windowing system, there will be a + different subclass for each platform. + @author + Steven J. Streeting + */ + class _OgreExport ConfigDialog : public UtilityAlloc + { + public: + ConfigDialog(); - /** Displays the dialog. - @remarks - This method displays the dialog and from then on the dialog - interacts with the user independently. The dialog will be - calling the relevant OGRE rendering systems to query them for - options and to set the options the user selects. The method - returns when the user closes the dialog. - @returns - If the user accepted the dialog, true is returned. - @par - If the user cancelled the dialog (indicating the application - should probably terminate), false is returned. - @see - RenderSystem - */ - bool display(); + /** Displays the dialog. + @remarks + This method displays the dialog and from then on the dialog + interacts with the user independently. The dialog will be + calling the relevant OGRE rendering systems to query them for + options and to set the options the user selects. The method + returns when the user closes the dialog. + @returns + If the user accepted the dialog, true is returned. + @par + If the user cancelled the dialog (indicating the application + should probably terminate), false is returned. + @see + RenderSystem + */ + bool display(); - protected: - RenderSystem* mSelectedRenderSystem; - }; + protected: + RenderSystem* mSelectedRenderSystem; + }; } #endif diff --git a/OgreMain/include/GLX/OgreErrorDialogImp.h b/OgreMain/include/GLX/OgreErrorDialogImp.h index 48c3ec75315..bc6eb3fc871 100644 --- a/OgreMain/include/GLX/OgreErrorDialogImp.h +++ b/OgreMain/include/GLX/OgreErrorDialogImp.h @@ -32,21 +32,21 @@ THE SOFTWARE. namespace Ogre { - /** Class for displaying the error dialog if Ogre fails badly. */ - class _OgreExport ErrorDialog - { - public: - ErrorDialog(); + /** Class for displaying the error dialog if Ogre fails badly. */ + class _OgreExport ErrorDialog + { + public: + ErrorDialog(); - /** - @remarks - Displays the error dialog. - @param - errorMessage The error message which has caused the failure. - @param - logName Optional name of the log to display in the detail pane. - */ - void display(const String& errorMessage, String logName = ""); - }; + /** + @remarks + Displays the error dialog. + @param + errorMessage The error message which has caused the failure. + @param + logName Optional name of the log to display in the detail pane. + */ + void display(const String& errorMessage, String logName = ""); + }; } #endif diff --git a/OgreMain/include/GLX/OgreTimerImp.h b/OgreMain/include/GLX/OgreTimerImp.h index a8e88fcc85f..1e88d672fe3 100644 --- a/OgreMain/include/GLX/OgreTimerImp.h +++ b/OgreMain/include/GLX/OgreTimerImp.h @@ -33,20 +33,20 @@ THE SOFTWARE. namespace Ogre { - /** Timer class */ - class _OgreExport Timer : public TimerAlloc - { - private: - struct timeval start; - clock_t zeroClock; - public: - Timer(); - ~Timer(); + /** Timer class */ + class _OgreExport Timer : public TimerAlloc + { + private: + struct timeval start; + clock_t zeroClock; + public: + Timer(); + ~Timer(); - /** Method for setting a specific option of the Timer. These options are usually + /** Method for setting a specific option of the Timer. These options are usually specific for a certain implementation of the Timer class, and may (and probably will) not exist across different implementations. reset() must be called after - all setOption() calls. + all setOption() calls. @param strKey The name of the option to set @param @@ -60,20 +60,20 @@ namespace Ogre bool setOption( const String& strKey, const void* pValue ) { (void)strKey; (void)pValue; return false; } - /** Resets timer */ - void reset(); + /** Resets timer */ + void reset(); - /** Returns milliseconds since initialisation or last reset */ - unsigned long getMilliseconds(); + /** Returns milliseconds since initialisation or last reset */ + unsigned long getMilliseconds(); - /** Returns microseconds since initialisation or last reset */ - unsigned long getMicroseconds(); + /** Returns microseconds since initialisation or last reset */ + unsigned long getMicroseconds(); - /** Returns milliseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMillisecondsCPU(); + /** Returns milliseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMillisecondsCPU(); - /** Returns microseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMicrosecondsCPU(); - }; + /** Returns microseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMicrosecondsCPU(); + }; } #endif diff --git a/OgreMain/include/NaCl/OgreConfigDialogImp.h b/OgreMain/include/NaCl/OgreConfigDialogImp.h index e2dd1d2ae28..3afe6bce560 100644 --- a/OgreMain/include/NaCl/OgreConfigDialogImp.h +++ b/OgreMain/include/NaCl/OgreConfigDialogImp.h @@ -35,41 +35,41 @@ THE SOFTWARE. namespace Ogre { - /** Defines the behaviour of an automatic renderer configuration dialog. - @remarks - OGRE comes with it's own renderer configuration dialog, which - applications can use to easily allow the user to configure the - settings appropriate to their machine. This class defines the - interface to this standard dialog. Because dialogs are inherently - tied to a particular platform's windowing system, there will be a - different subclass for each platform. - @author - Steven J. Streeting - */ - class _OgreExport ConfigDialog : public UtilityAlloc - { - public: - ConfigDialog(); + /** Defines the behaviour of an automatic renderer configuration dialog. + @remarks + OGRE comes with it's own renderer configuration dialog, which + applications can use to easily allow the user to configure the + settings appropriate to their machine. This class defines the + interface to this standard dialog. Because dialogs are inherently + tied to a particular platform's windowing system, there will be a + different subclass for each platform. + @author + Steven J. Streeting + */ + class _OgreExport ConfigDialog : public UtilityAlloc + { + public: + ConfigDialog(); - /** Displays the dialog. - @remarks - This method displays the dialog and from then on the dialog - interacts with the user independently. The dialog will be - calling the relevant OGRE rendering systems to query them for - options and to set the options the user selects. The method - returns when the user closes the dialog. - @returns - If the user accepted the dialog, true is returned. - @par - If the user cancelled the dialog (indicating the application - should probably terminate), false is returned. - @see - RenderSystem - */ - bool display(); + /** Displays the dialog. + @remarks + This method displays the dialog and from then on the dialog + interacts with the user independently. The dialog will be + calling the relevant OGRE rendering systems to query them for + options and to set the options the user selects. The method + returns when the user closes the dialog. + @returns + If the user accepted the dialog, true is returned. + @par + If the user cancelled the dialog (indicating the application + should probably terminate), false is returned. + @see + RenderSystem + */ + bool display(); - protected: - RenderSystem* mSelectedRenderSystem; - }; + protected: + RenderSystem* mSelectedRenderSystem; + }; } #endif diff --git a/OgreMain/include/NaCl/OgreErrorDialogImp.h b/OgreMain/include/NaCl/OgreErrorDialogImp.h index a5f0096a8eb..cff6f13ad57 100644 --- a/OgreMain/include/NaCl/OgreErrorDialogImp.h +++ b/OgreMain/include/NaCl/OgreErrorDialogImp.h @@ -32,21 +32,21 @@ THE SOFTWARE. namespace Ogre { - /** Class for displaying the error dialog if Ogre fails badly. */ - class _OgreExport ErrorDialog - { - public: - ErrorDialog(); + /** Class for displaying the error dialog if Ogre fails badly. */ + class _OgreExport ErrorDialog + { + public: + ErrorDialog(); - /** - @remarks - Displays the error dialog. - @param - errorMessage The error message which has caused the failure. - @param - logName Optional name of the log to display in the detail pane. - */ - void display(const String& errorMessage, String logName = ""); - }; + /** + @remarks + Displays the error dialog. + @param + errorMessage The error message which has caused the failure. + @param + logName Optional name of the log to display in the detail pane. + */ + void display(const String& errorMessage, String logName = ""); + }; } #endif diff --git a/OgreMain/include/NaCl/OgreTimerImp.h b/OgreMain/include/NaCl/OgreTimerImp.h index c2ac1412b6d..42118eb048a 100644 --- a/OgreMain/include/NaCl/OgreTimerImp.h +++ b/OgreMain/include/NaCl/OgreTimerImp.h @@ -37,20 +37,20 @@ THE SOFTWARE. namespace Ogre { - /** Timer class */ - class _OgreExport Timer : public TimerAlloc - { - private: - struct timeval start; - clock_t zeroClock; - public: - Timer(); - ~Timer(); + /** Timer class */ + class _OgreExport Timer : public TimerAlloc + { + private: + struct timeval start; + clock_t zeroClock; + public: + Timer(); + ~Timer(); - /** Method for setting a specific option of the Timer. These options are usually + /** Method for setting a specific option of the Timer. These options are usually specific for a certain implementation of the Timer class, and may (and probably will) not exist across different implementations. reset() must be called after - all setOption() calls. + all setOption() calls. @param strKey The name of the option to set @param @@ -64,20 +64,20 @@ namespace Ogre bool setOption( const String& strKey, const void* pValue ) { (void)strKey; (void)pValue; return false; } - /** Resets timer */ - void reset(); + /** Resets timer */ + void reset(); - /** Returns milliseconds since initialisation or last reset */ - unsigned long getMilliseconds(); + /** Returns milliseconds since initialisation or last reset */ + unsigned long getMilliseconds(); - /** Returns microseconds since initialisation or last reset */ - unsigned long getMicroseconds(); + /** Returns microseconds since initialisation or last reset */ + unsigned long getMicroseconds(); - /** Returns milliseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMillisecondsCPU(); + /** Returns milliseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMillisecondsCPU(); - /** Returns microseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMicrosecondsCPU(); - }; + /** Returns microseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMicrosecondsCPU(); + }; } #endif diff --git a/OgreMain/include/OSX/OgreConfigDialogImp.h b/OgreMain/include/OSX/OgreConfigDialogImp.h index 9fb4e61577e..0385d50f265 100644 --- a/OgreMain/include/OSX/OgreConfigDialogImp.h +++ b/OgreMain/include/OSX/OgreConfigDialogImp.h @@ -79,21 +79,21 @@ THE SOFTWARE. namespace Ogre { - class _OgreExport ConfigDialog : public UtilityAlloc - { - public: - ConfigDialog(); - ~ConfigDialog(); - - void initialise(); - bool display(); + class _OgreExport ConfigDialog : public UtilityAlloc + { + public: + ConfigDialog(); + ~ConfigDialog(); + + void initialise(); + bool display(); - protected: + protected: #ifdef __OBJC__ OgreConfigWindowDelegate *mWindowDelegate; #endif - RenderSystem *mSelectedRenderSystem; - }; + RenderSystem *mSelectedRenderSystem; + }; } #endif // __OSX_CONFIG_DIALOG_H__ diff --git a/OgreMain/include/OSX/OgreErrorDialogImp.h b/OgreMain/include/OSX/OgreErrorDialogImp.h index d669e49e68a..1dab2aae023 100644 --- a/OgreMain/include/OSX/OgreErrorDialogImp.h +++ b/OgreMain/include/OSX/OgreErrorDialogImp.h @@ -32,21 +32,21 @@ THE SOFTWARE. namespace Ogre { - /** Class for displaying the error dialog if Ogre fails badly. */ - class _OgreExport ErrorDialog - { - public: - ErrorDialog(); + /** Class for displaying the error dialog if Ogre fails badly. */ + class _OgreExport ErrorDialog + { + public: + ErrorDialog(); - /** - @remarks - Displays the error dialog. - @param - errorMessage The error message which has caused the failure. - @param - logName Optional name of the log to display in the detail pane. - */ - void display(const String& errorMessage, String logName = ""); - }; + /** + @remarks + Displays the error dialog. + @param + errorMessage The error message which has caused the failure. + @param + logName Optional name of the log to display in the detail pane. + */ + void display(const String& errorMessage, String logName = ""); + }; } #endif diff --git a/OgreMain/include/OSX/OgreTimerImp.h b/OgreMain/include/OSX/OgreTimerImp.h index 2e9388bd62b..b5262c0d662 100644 --- a/OgreMain/include/OSX/OgreTimerImp.h +++ b/OgreMain/include/OSX/OgreTimerImp.h @@ -33,20 +33,20 @@ THE SOFTWARE. namespace Ogre { - /** Timer class */ - class _OgreExport Timer : public TimerAlloc - { - private: - struct timeval start; - clock_t zeroClock; - public: - Timer(); - ~Timer(); + /** Timer class */ + class _OgreExport Timer : public TimerAlloc + { + private: + struct timeval start; + clock_t zeroClock; + public: + Timer(); + ~Timer(); - /** Method for setting a specific option of the Timer. These options are usually + /** Method for setting a specific option of the Timer. These options are usually specific for a certain implementation of the Timer class, and may (and probably will) not exist across different implementations. reset() must be called after - all setOption() calls. + all setOption() calls. @param strKey The name of the option to set @param @@ -59,20 +59,20 @@ namespace Ogre */ bool setOption( const String& strKey, const void* pValue ) { return false; } - /** Resets timer */ - void reset(); + /** Resets timer */ + void reset(); - /** Returns milliseconds since initialisation or last reset */ - unsigned long getMilliseconds(); + /** Returns milliseconds since initialisation or last reset */ + unsigned long getMilliseconds(); - /** Returns microseconds since initialisation or last reset */ - unsigned long getMicroseconds(); + /** Returns microseconds since initialisation or last reset */ + unsigned long getMicroseconds(); - /** Returns milliseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMillisecondsCPU(); + /** Returns milliseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMillisecondsCPU(); - /** Returns microseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMicrosecondsCPU(); - }; + /** Returns microseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMicrosecondsCPU(); + }; } #endif diff --git a/OgreMain/include/OgreAlignedAllocator.h b/OgreMain/include/OgreAlignedAllocator.h index 9d6dd3ab853..ad249399e43 100644 --- a/OgreMain/include/OgreAlignedAllocator.h +++ b/OgreMain/include/OgreAlignedAllocator.h @@ -30,15 +30,15 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ + /** \addtogroup Core + * @{ + */ - /** \addtogroup Memory - * @{ - */ + /** \addtogroup Memory + * @{ + */ - /** Class to provide aligned memory allocate functionality. + /** Class to provide aligned memory allocate functionality. @remarks All SIMD processing are friendly with aligned memory, and some SIMD routines are designed for working with aligned memory only. If the data are intended to @@ -56,9 +56,9 @@ namespace Ogre { @note This class intended to use by advanced user only. */ - class _OgreExport AlignedMemory - { - public: + class _OgreExport AlignedMemory + { + public: /** Allocate memory with given alignment. @param size The size of memory need to allocate. @@ -93,10 +93,10 @@ namespace Ogre { On NULL pointer, nothing happen. */ static void deallocate(void* p); - }; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreAnimable.h b/OgreMain/include/OgreAnimable.h index 78c371966c8..bf0fce5e5a8 100644 --- a/OgreMain/include/OgreAnimable.h +++ b/OgreMain/include/OgreAnimable.h @@ -41,291 +41,291 @@ namespace Ogre { class Any; - /** \addtogroup Core - * @{ - */ - - /** \addtogroup Animation - * @{ - */ - - /** Defines an object property which is animable, i.e. may be keyframed. - @remarks - Animable properties are those which can be altered over time by a - predefined keyframe sequence. They may be set directly, or they may - be modified from their existing state (common if multiple animations - are expected to apply at once). Implementors of this interface are - expected to override the 'setValue', 'setCurrentStateAsBaseValue' and - 'applyDeltaValue' methods appropriate to the type in question, and to - initialise the type. - @par - AnimableValue instances are accessible through any class which extends - AnimableObject in order to expose it's animable properties. - @note - This class is an instance of the Adapter pattern, since it generalises - access to a particular property. Whilst it could have been templated - such that the type which was being referenced was compiled in, this would - make it more difficult to aggregated generically, and since animations - are often comprised of multiple properties it helps to be able to deal - with all values through a single class. - */ - class _OgreExport AnimableValue : public AnimableAlloc - { - public: - /// The type of the value being animated - enum ValueType - { - INT, - REAL, - VECTOR2, - VECTOR3, - VECTOR4, - QUATERNION, - COLOUR, - RADIAN, - DEGREE - }; - protected: - /// Value type - ValueType mType; - - /// Base value data - union - { - int mBaseValueInt; - Real mBaseValueReal[4]; - }; - - /// Internal method to set a value as base - virtual void setAsBaseValue(int val) { mBaseValueInt = val; } - /// Internal method to set a value as base - virtual void setAsBaseValue(Real val) { mBaseValueReal[0] = val; } - /// Internal method to set a value as base - virtual void setAsBaseValue(const Vector2& val) - { memcpy(mBaseValueReal, val.ptr(), sizeof(Real)*2); } - /// Internal method to set a value as base - virtual void setAsBaseValue(const Vector3& val) - { memcpy(mBaseValueReal, val.ptr(), sizeof(Real)*3); } - /// Internal method to set a value as base - virtual void setAsBaseValue(const Vector4& val) - { memcpy(mBaseValueReal, val.ptr(), sizeof(Real)*4); } - /// Internal method to set a value as base - virtual void setAsBaseValue(const Quaternion& val) - { memcpy(mBaseValueReal, val.ptr(), sizeof(Real)*4); } - /// Internal method to set a value as base - virtual void setAsBaseValue(const Any& val); - /// Internal method to set a value as base - virtual void setAsBaseValue(const ColourValue& val) - { - mBaseValueReal[0] = val.r; - mBaseValueReal[1] = val.g; - mBaseValueReal[2] = val.b; - mBaseValueReal[3] = val.a; - } - /// Internal method to set a value as base - virtual void setAsBaseValue(const Radian& val) - { - mBaseValueReal[0] = val.valueRadians(); - } - /// Internal method to set a value as base - virtual void setAsBaseValue(const Degree& val) - { - mBaseValueReal[0] = val.valueRadians(); - } - - - public: - AnimableValue(ValueType t) : mType(t) {} - virtual ~AnimableValue() {} - - /// Gets the value type of this animable value - ValueType getType(void) const { return mType; } - - /// Sets the current state as the 'base' value; used for delta animation - virtual void setCurrentStateAsBaseValue(void) = 0; - - /// Set value - virtual void setValue(int) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Set value - virtual void setValue(Real) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Set value - virtual void setValue(const Vector2&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Set value - virtual void setValue(const Vector3&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Set value - virtual void setValue(const Vector4&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Set value - virtual void setValue(const Quaternion&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Set value - virtual void setValue(const ColourValue&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Set value - virtual void setValue(const Radian&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Set value - virtual void setValue(const Degree&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Set value - virtual void setValue(const Any& val); - - // reset to base value - virtual void resetToBaseValue(void); - - /// Apply delta value - virtual void applyDeltaValue(int) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Set value - virtual void applyDeltaValue(Real) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Apply delta value - virtual void applyDeltaValue(const Vector2&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Apply delta value - virtual void applyDeltaValue(const Vector3&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Apply delta value - virtual void applyDeltaValue(const Vector4&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Apply delta value - virtual void applyDeltaValue(const Quaternion&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Apply delta value - virtual void applyDeltaValue(const ColourValue&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Apply delta value - virtual void applyDeltaValue(const Degree&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Apply delta value - virtual void applyDeltaValue(const Radian&) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); - } - /// Apply delta value - virtual void applyDeltaValue(const Any& val); - - - }; - - /** Defines an interface to classes which have one or more AnimableValue - instances to expose. - */ - class _OgreExport AnimableObject - { - protected: - typedef map::type AnimableDictionaryMap; - /// Static map of class name to list of animable value names - static AnimableDictionaryMap msAnimableDictionary; - /** Get the name of the animable dictionary for this class. - @remarks - Subclasses must override this if they want to support animation of - their values. - */ - virtual const String& getAnimableDictionaryName(void) const - { return BLANKSTRING; } + /** \addtogroup Core + * @{ + */ + + /** \addtogroup Animation + * @{ + */ + + /** Defines an object property which is animable, i.e. may be keyframed. + @remarks + Animable properties are those which can be altered over time by a + predefined keyframe sequence. They may be set directly, or they may + be modified from their existing state (common if multiple animations + are expected to apply at once). Implementors of this interface are + expected to override the 'setValue', 'setCurrentStateAsBaseValue' and + 'applyDeltaValue' methods appropriate to the type in question, and to + initialise the type. + @par + AnimableValue instances are accessible through any class which extends + AnimableObject in order to expose it's animable properties. + @note + This class is an instance of the Adapter pattern, since it generalises + access to a particular property. Whilst it could have been templated + such that the type which was being referenced was compiled in, this would + make it more difficult to aggregated generically, and since animations + are often comprised of multiple properties it helps to be able to deal + with all values through a single class. + */ + class _OgreExport AnimableValue : public AnimableAlloc + { + public: + /// The type of the value being animated + enum ValueType + { + INT, + REAL, + VECTOR2, + VECTOR3, + VECTOR4, + QUATERNION, + COLOUR, + RADIAN, + DEGREE + }; + protected: + /// Value type + ValueType mType; + + /// Base value data + union + { + int mBaseValueInt; + Real mBaseValueReal[4]; + }; + + /// Internal method to set a value as base + virtual void setAsBaseValue(int val) { mBaseValueInt = val; } + /// Internal method to set a value as base + virtual void setAsBaseValue(Real val) { mBaseValueReal[0] = val; } + /// Internal method to set a value as base + virtual void setAsBaseValue(const Vector2& val) + { memcpy(mBaseValueReal, val.ptr(), sizeof(Real)*2); } + /// Internal method to set a value as base + virtual void setAsBaseValue(const Vector3& val) + { memcpy(mBaseValueReal, val.ptr(), sizeof(Real)*3); } + /// Internal method to set a value as base + virtual void setAsBaseValue(const Vector4& val) + { memcpy(mBaseValueReal, val.ptr(), sizeof(Real)*4); } + /// Internal method to set a value as base + virtual void setAsBaseValue(const Quaternion& val) + { memcpy(mBaseValueReal, val.ptr(), sizeof(Real)*4); } + /// Internal method to set a value as base + virtual void setAsBaseValue(const Any& val); + /// Internal method to set a value as base + virtual void setAsBaseValue(const ColourValue& val) + { + mBaseValueReal[0] = val.r; + mBaseValueReal[1] = val.g; + mBaseValueReal[2] = val.b; + mBaseValueReal[3] = val.a; + } + /// Internal method to set a value as base + virtual void setAsBaseValue(const Radian& val) + { + mBaseValueReal[0] = val.valueRadians(); + } + /// Internal method to set a value as base + virtual void setAsBaseValue(const Degree& val) + { + mBaseValueReal[0] = val.valueRadians(); + } + + + public: + AnimableValue(ValueType t) : mType(t) {} + virtual ~AnimableValue() {} + + /// Gets the value type of this animable value + ValueType getType(void) const { return mType; } + + /// Sets the current state as the 'base' value; used for delta animation + virtual void setCurrentStateAsBaseValue(void) = 0; + + /// Set value + virtual void setValue(int) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Set value + virtual void setValue(Real) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Set value + virtual void setValue(const Vector2&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Set value + virtual void setValue(const Vector3&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Set value + virtual void setValue(const Vector4&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Set value + virtual void setValue(const Quaternion&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Set value + virtual void setValue(const ColourValue&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Set value + virtual void setValue(const Radian&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Set value + virtual void setValue(const Degree&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Set value + virtual void setValue(const Any& val); + + // reset to base value + virtual void resetToBaseValue(void); + + /// Apply delta value + virtual void applyDeltaValue(int) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Set value + virtual void applyDeltaValue(Real) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Apply delta value + virtual void applyDeltaValue(const Vector2&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Apply delta value + virtual void applyDeltaValue(const Vector3&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Apply delta value + virtual void applyDeltaValue(const Vector4&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Apply delta value + virtual void applyDeltaValue(const Quaternion&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Apply delta value + virtual void applyDeltaValue(const ColourValue&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Apply delta value + virtual void applyDeltaValue(const Degree&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Apply delta value + virtual void applyDeltaValue(const Radian&) { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "", ""); + } + /// Apply delta value + virtual void applyDeltaValue(const Any& val); + + + }; + + /** Defines an interface to classes which have one or more AnimableValue + instances to expose. + */ + class _OgreExport AnimableObject + { + protected: + typedef map::type AnimableDictionaryMap; + /// Static map of class name to list of animable value names + static AnimableDictionaryMap msAnimableDictionary; + /** Get the name of the animable dictionary for this class. + @remarks + Subclasses must override this if they want to support animation of + their values. + */ + virtual const String& getAnimableDictionaryName(void) const + { return BLANKSTRING; } /** Internal method for creating a dictionary of animable value names - for the class, if it does not already exist. + for the class, if it does not already exist. */ void createAnimableDictionary(void) const { if (msAnimableDictionary.find(getAnimableDictionaryName()) - == msAnimableDictionary.end()) + == msAnimableDictionary.end()) + { + StringVector vec; + initialiseAnimableDictionary(vec); + msAnimableDictionary[getAnimableDictionaryName()] = vec; + } + + } + + /// Get an updateable reference to animable value list + StringVector& _getAnimableValueNames(void) + { + AnimableDictionaryMap::iterator i = + msAnimableDictionary.find(getAnimableDictionaryName()); + if (i != msAnimableDictionary.end()) + { + return i->second; + } + else { - StringVector vec; - initialiseAnimableDictionary(vec); - msAnimableDictionary[getAnimableDictionaryName()] = vec; + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Animable value list not found for " + getAnimableDictionaryName(), + "AnimableObject::getAnimableValueNames"); } } - - /// Get an updateable reference to animable value list - StringVector& _getAnimableValueNames(void) - { - AnimableDictionaryMap::iterator i = - msAnimableDictionary.find(getAnimableDictionaryName()); - if (i != msAnimableDictionary.end()) - { - return i->second; - } - else - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Animable value list not found for " + getAnimableDictionaryName(), - "AnimableObject::getAnimableValueNames"); - } - - } - - /** Internal method for initialising dictionary; should be implemented by - subclasses wanting to expose animable parameters. - */ - virtual void initialiseAnimableDictionary(StringVector&) const {} - - - public: - AnimableObject() {} - virtual ~AnimableObject() {} - - /** Gets a list of animable value names for this object. */ - const StringVector& getAnimableValueNames(void) const - { - createAnimableDictionary(); - - AnimableDictionaryMap::iterator i = - msAnimableDictionary.find(getAnimableDictionaryName()); - if (i != msAnimableDictionary.end()) - { - return i->second; - } - else - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Animable value list not found for " + getAnimableDictionaryName(), - "AnimableObject::getAnimableValueNames"); - } - - } - - /** Create a reference-counted AnimableValuePtr for the named value. - @remarks - You can use the returned object to animate a value on this object, - using AnimationTrack. Subclasses must override this if they wish - to support animation of their values. - */ - virtual AnimableValuePtr createAnimableValue(const String& valueName) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "No animable value named '" + valueName + "' present.", - "AnimableObject::createAnimableValue"); - } - - - - }; - - /** @} */ - /** @} */ + + /** Internal method for initialising dictionary; should be implemented by + subclasses wanting to expose animable parameters. + */ + virtual void initialiseAnimableDictionary(StringVector&) const {} + + + public: + AnimableObject() {} + virtual ~AnimableObject() {} + + /** Gets a list of animable value names for this object. */ + const StringVector& getAnimableValueNames(void) const + { + createAnimableDictionary(); + + AnimableDictionaryMap::iterator i = + msAnimableDictionary.find(getAnimableDictionaryName()); + if (i != msAnimableDictionary.end()) + { + return i->second; + } + else + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Animable value list not found for " + getAnimableDictionaryName(), + "AnimableObject::getAnimableValueNames"); + } + + } + + /** Create a reference-counted AnimableValuePtr for the named value. + @remarks + You can use the returned object to animate a value on this object, + using AnimationTrack. Subclasses must override this if they wish + to support animation of their values. + */ + virtual AnimableValuePtr createAnimableValue(const String& valueName) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "No animable value named '" + valueName + "' present.", + "AnimableObject::createAnimableValue"); + } + + + + }; + + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreAnimationState.h b/OgreMain/include/OgreAnimationState.h index 1fbe524bae0..e150a23f71a 100644 --- a/OgreMain/include/OgreAnimationState.h +++ b/OgreMain/include/OgreAnimationState.h @@ -39,19 +39,19 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ /** Represents the state of an animation and the weight of its influence. @remarks Other classes can hold instances of this class to store the state of any animations they are using. */ - class _OgreExport AnimationState : public AnimationAlloc + class _OgreExport AnimationState : public AnimationAlloc { public: @@ -73,10 +73,10 @@ namespace Ogre { enabled Whether the animation state is enabled. */ AnimationState(const String& animName, AnimationStateSet *parent, - Real timePos, Real length, Real weight = 1.0, bool enabled = false); - /// Constructor to copy from an existing state with new parent - AnimationState(AnimationStateSet* parent, const AnimationState &rhs); - virtual ~AnimationState(); + Real timePos, Real length, Real weight = 1.0, bool enabled = false); + /// Constructor to copy from an existing state with new parent + AnimationState(AnimationStateSet* parent, const AnimationState &rhs); + virtual ~AnimationState(); /// Gets the name of the animation to which this state applies const String& getAnimationName() const; @@ -99,8 +99,8 @@ namespace Ogre { */ void addTime(Real offset); - /// Returns true if the animation has reached the end and is not looping - bool hasEnded(void) const; + /// Returns true if the animation has reached the end and is not looping + bool hasEnded(void) const; /// Returns true if this animation is currently enabled bool getEnabled(void) const; @@ -125,8 +125,8 @@ namespace Ogre { */ void copyStateFrom(const AnimationState& animState); - /// Get the parent animation state set - AnimationStateSet* getParent(void) const { return mParent; } + /// Get the parent animation state set + AnimationStateSet* getParent(void) const { return mParent; } /** @brief Create a new blend mask with the given number of entries * @@ -135,8 +135,8 @@ namespace Ogre { * * @param blendMaskSizeHint * The number of bones of the skeleton owning this AnimationState. - * @param initialWeight - * The value all the blend mask entries will be initialised with (negative to skip initialisation) + * @param initialWeight + * The value all the blend mask entries will be initialised with (negative to skip initialisation) */ void createBlendMask(size_t blendMaskSizeHint, float initialWeight = 1.0f); /// Destroy the currently set blend mask @@ -174,7 +174,7 @@ namespace Ogre { BoneBlendMask* mBlendMask; String mAnimationName; - AnimationStateSet* mParent; + AnimationStateSet* mParent; Real mTimePos; Real mLength; Real mWeight; @@ -183,114 +183,114 @@ namespace Ogre { }; - // A map of animation states - typedef map::type AnimationStateMap; - typedef MapIterator AnimationStateIterator; - typedef ConstMapIterator ConstAnimationStateIterator; + // A map of animation states + typedef map::type AnimationStateMap; + typedef MapIterator AnimationStateIterator; + typedef ConstMapIterator ConstAnimationStateIterator; // A list of enabled animation states typedef list::type EnabledAnimationStateList; typedef ConstVectorIterator ConstEnabledAnimationStateIterator; - /** Class encapsulating a set of AnimationState objects. - */ - class _OgreExport AnimationStateSet : public AnimationAlloc - { - public: - /// Mutex, public for external locking if needed + /** Class encapsulating a set of AnimationState objects. + */ + class _OgreExport AnimationStateSet : public AnimationAlloc + { + public: + /// Mutex, public for external locking if needed OGRE_AUTO_MUTEX; - /// Create a blank animation state set - AnimationStateSet(); - /// Create an animation set by copying the contents of another - AnimationStateSet(const AnimationStateSet& rhs); - - ~AnimationStateSet(); - - /** Create a new AnimationState instance. - @param animName The name of the animation - @param timePos Starting time position - @param length Length of the animation to play - @param weight Weight to apply the animation with - @param enabled Whether the animation is enabled - */ - AnimationState* createAnimationState(const String& animName, - Real timePos, Real length, Real weight = 1.0, bool enabled = false); - /// Get an animation state by the name of the animation - AnimationState* getAnimationState(const String& name) const; - /// Tests if state for the named animation is present - bool hasAnimationState(const String& name) const; - /// Remove animation state with the given name - void removeAnimationState(const String& name); - /// Remove all animation states - void removeAllAnimationStates(void); - - /** Get an iterator over all the animation states in this set. - @note - The iterator returned from this method is not threadsafe, - you will need to manually lock the public mutex on this - class to ensure thread safety if you need it. - */ - AnimationStateIterator getAnimationStateIterator(void); - /** Get an iterator over all the animation states in this set. - @note - The iterator returned from this method is not threadsafe, - you will need to manually lock the public mutex on this - class to ensure thread safety if you need it. - */ - ConstAnimationStateIterator getAnimationStateIterator(void) const; - /// Copy the state of any matching animation states from this to another - void copyMatchingState(AnimationStateSet* target) const; - /// Set the dirty flag and dirty frame number on this state set - void _notifyDirty(void); - /// Get the latest animation state been altered frame number - unsigned long getDirtyFrameNumber(void) const { return mDirtyFrameNumber; } + /// Create a blank animation state set + AnimationStateSet(); + /// Create an animation set by copying the contents of another + AnimationStateSet(const AnimationStateSet& rhs); + + ~AnimationStateSet(); + + /** Create a new AnimationState instance. + @param animName The name of the animation + @param timePos Starting time position + @param length Length of the animation to play + @param weight Weight to apply the animation with + @param enabled Whether the animation is enabled + */ + AnimationState* createAnimationState(const String& animName, + Real timePos, Real length, Real weight = 1.0, bool enabled = false); + /// Get an animation state by the name of the animation + AnimationState* getAnimationState(const String& name) const; + /// Tests if state for the named animation is present + bool hasAnimationState(const String& name) const; + /// Remove animation state with the given name + void removeAnimationState(const String& name); + /// Remove all animation states + void removeAllAnimationStates(void); + + /** Get an iterator over all the animation states in this set. + @note + The iterator returned from this method is not threadsafe, + you will need to manually lock the public mutex on this + class to ensure thread safety if you need it. + */ + AnimationStateIterator getAnimationStateIterator(void); + /** Get an iterator over all the animation states in this set. + @note + The iterator returned from this method is not threadsafe, + you will need to manually lock the public mutex on this + class to ensure thread safety if you need it. + */ + ConstAnimationStateIterator getAnimationStateIterator(void) const; + /// Copy the state of any matching animation states from this to another + void copyMatchingState(AnimationStateSet* target) const; + /// Set the dirty flag and dirty frame number on this state set + void _notifyDirty(void); + /// Get the latest animation state been altered frame number + unsigned long getDirtyFrameNumber(void) const { return mDirtyFrameNumber; } /// Internal method respond to enable/disable an animation state void _notifyAnimationStateEnabled(AnimationState* target, bool enabled); /// Tests if exists enabled animation state in this set bool hasEnabledAnimationState(void) const { return !mEnabledAnimationStates.empty(); } - /** Get an iterator over all the enabled animation states in this set - @note - The iterator returned from this method is not threadsafe, - you will need to manually lock the public mutex on this - class to ensure thread safety if you need it. - */ - ConstEnabledAnimationStateIterator getEnabledAnimationStateIterator(void) const; - - protected: - unsigned long mDirtyFrameNumber; - AnimationStateMap mAnimationStates; + /** Get an iterator over all the enabled animation states in this set + @note + The iterator returned from this method is not threadsafe, + you will need to manually lock the public mutex on this + class to ensure thread safety if you need it. + */ + ConstEnabledAnimationStateIterator getEnabledAnimationStateIterator(void) const; + + protected: + unsigned long mDirtyFrameNumber; + AnimationStateMap mAnimationStates; EnabledAnimationStateList mEnabledAnimationStates; - }; - - /** ControllerValue wrapper class for AnimationState. - @remarks - In Azathoth and earlier, AnimationState was a ControllerValue but this - actually causes memory problems since Controllers delete their values - automatically when there are no further references to them, but AnimationState - is deleted explicitly elsewhere so this causes double-free problems. - This wrapper acts as a bridge and it is this which is destroyed automatically. - */ - class _OgreExport AnimationStateControllerValue : public ControllerValue - { - protected: - AnimationState* mTargetAnimationState; - public: - /** Constructor, pass in the target animation state. */ - AnimationStateControllerValue(AnimationState* targetAnimationState) - : mTargetAnimationState(targetAnimationState) {} - /// Destructor (parent already virtual) - ~AnimationStateControllerValue() {} - /** ControllerValue implementation. */ - Real getValue(void) const; - - /** ControllerValue implementation. */ - void setValue(Real value); - - }; - - /** @} */ - /** @} */ + }; + + /** ControllerValue wrapper class for AnimationState. + @remarks + In Azathoth and earlier, AnimationState was a ControllerValue but this + actually causes memory problems since Controllers delete their values + automatically when there are no further references to them, but AnimationState + is deleted explicitly elsewhere so this causes double-free problems. + This wrapper acts as a bridge and it is this which is destroyed automatically. + */ + class _OgreExport AnimationStateControllerValue : public ControllerValue + { + protected: + AnimationState* mTargetAnimationState; + public: + /** Constructor, pass in the target animation state. */ + AnimationStateControllerValue(AnimationState* targetAnimationState) + : mTargetAnimationState(targetAnimationState) {} + /// Destructor (parent already virtual) + ~AnimationStateControllerValue() {} + /** ControllerValue implementation. */ + Real getValue(void) const; + + /** ControllerValue implementation. */ + void setValue(Real value); + + }; + + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreAnimationTrack.h b/OgreMain/include/OgreAnimationTrack.h index 0709721eb4f..0b782802cfc 100644 --- a/OgreMain/include/OgreAnimationTrack.h +++ b/OgreMain/include/OgreAnimationTrack.h @@ -40,12 +40,12 @@ namespace Ogre class VertexPoseKeyFrame; class KeyFrame; - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ /** Time index object used to search keyframe at the given position. */ class _OgreExport TimeIndex @@ -115,36 +115,36 @@ namespace Ogre Since the most common animable object is a Node, there are options in this class for associating the track with a Node which will receive keyframe updates automatically when the 'apply' method is called. - @remarks - By default rotation is done using shortest-path algorithm. - It is possible to change this behaviour using - setUseShortestRotationPath() method. + @remarks + By default rotation is done using shortest-path algorithm. + It is possible to change this behaviour using + setUseShortestRotationPath() method. */ - class _OgreExport AnimationTrack : public AnimationAlloc + class _OgreExport AnimationTrack : public AnimationAlloc { public: - /** Listener allowing you to override certain behaviour of a track, - for example to drive animation procedurally. - */ - class _OgreExport Listener - { - public: - virtual ~Listener() {} + /** Listener allowing you to override certain behaviour of a track, + for example to drive animation procedurally. + */ + class _OgreExport Listener + { + public: + virtual ~Listener() {} - /** Get an interpolated keyframe for this track at the given time. - @return true if the KeyFrame was populated, false if not. - */ - virtual bool getInterpolatedKeyFrame(const AnimationTrack* t, const TimeIndex& timeIndex, KeyFrame* kf) = 0; - }; + /** Get an interpolated keyframe for this track at the given time. + @return true if the KeyFrame was populated, false if not. + */ + virtual bool getInterpolatedKeyFrame(const AnimationTrack* t, const TimeIndex& timeIndex, KeyFrame* kf) = 0; + }; /// Constructor AnimationTrack(Animation* parent, unsigned short handle); virtual ~AnimationTrack(); - /** Get the handle associated with this track. */ - unsigned short getHandle(void) const { return mHandle; } + /** Get the handle associated with this track. */ + unsigned short getHandle(void) const { return mHandle; } /** Returns the number of keyframes in this animation. */ virtual unsigned short getNumKeyFrames(void) const; @@ -207,23 +207,23 @@ namespace Ogre @param timeIndex The time position in the animation to apply. @param weight The influence to give to this track, 1.0 for full influence, less to blend with other animations. - @param scale The scale to apply to translations and scalings, useful for - adapting an animation to a different size target. + @param scale The scale to apply to translations and scalings, useful for + adapting an animation to a different size target. */ virtual void apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f) = 0; /** Internal method used to tell the track that keyframe data has been changed, which may cause it to rebuild some internal data. */ - virtual void _keyFrameDataChanged(void) const {} + virtual void _keyFrameDataChanged(void) const {} - /** Method to determine if this track has any KeyFrames which are - doing anything useful - can be used to determine if this track - can be optimised out. - */ - virtual bool hasNonZeroKeyFrames(void) const { return true; } + /** Method to determine if this track has any KeyFrames which are + doing anything useful - can be used to determine if this track + can be optimised out. + */ + virtual bool hasNonZeroKeyFrames(void) const { return true; } - /** Optimise the current track by removing any duplicate keyframes. */ - virtual void optimise(void) {} + /** Optimise the current track by removing any duplicate keyframes. */ + virtual void optimise(void) {} /** Internal method to collect keyframe times, in unique, ordered format. */ virtual void _collectKeyFrameTimes(vector::type& keyFrameTimes); @@ -231,46 +231,46 @@ namespace Ogre /** Internal method to build keyframe time index map to translate global lower bound index to local lower bound index. */ virtual void _buildKeyFrameIndexMap(const vector::type& keyFrameTimes); - - /** Internal method to re-base the keyframes relative to a given keyframe. */ - virtual void _applyBaseKeyFrame(const KeyFrame* base) {} + + /** Internal method to re-base the keyframes relative to a given keyframe. */ + virtual void _applyBaseKeyFrame(const KeyFrame* base) {} - /** Set a listener for this track. */ - virtual void setListener(Listener* l) { mListener = l; } + /** Set a listener for this track. */ + virtual void setListener(Listener* l) { mListener = l; } - /** Returns the parent Animation object for this track. */ - Animation *getParent() const { return mParent; } + /** Returns the parent Animation object for this track. */ + Animation *getParent() const { return mParent; } protected: typedef vector::type KeyFrameList; KeyFrameList mKeyFrames; Animation* mParent; - unsigned short mHandle; - Listener* mListener; + unsigned short mHandle; + Listener* mListener; /// Map used to translate global keyframe time lower bound index to local lower bound index typedef vector::type KeyFrameIndexMap; KeyFrameIndexMap mKeyFrameIndexMap; - /// Create a keyframe implementation - must be overridden - virtual KeyFrame* createKeyFrameImpl(Real time) = 0; + /// Create a keyframe implementation - must be overridden + virtual KeyFrame* createKeyFrameImpl(Real time) = 0; - /// Internal method for clone implementation - virtual void populateClone(AnimationTrack* clone) const; - + /// Internal method for clone implementation + virtual void populateClone(AnimationTrack* clone) const; + }; - /** Specialised AnimationTrack for dealing with generic animable values. - */ - class _OgreExport NumericAnimationTrack : public AnimationTrack - { - public: - /// Constructor - NumericAnimationTrack(Animation* parent, unsigned short handle); - /// Constructor, associates with an AnimableValue - NumericAnimationTrack(Animation* parent, unsigned short handle, - AnimableValuePtr& target); + /** Specialised AnimationTrack for dealing with generic animable values. + */ + class _OgreExport NumericAnimationTrack : public AnimationTrack + { + public: + /// Constructor + NumericAnimationTrack(Animation* parent, unsigned short handle); + /// Constructor, associates with an AnimableValue + NumericAnimationTrack(Animation* parent, unsigned short handle, + AnimableValuePtr& target); /** Creates a new KeyFrame and adds it to this animation at the given time index. @remarks @@ -281,57 +281,57 @@ namespace Ogre */ virtual NumericKeyFrame* createNumericKeyFrame(Real timePos); - /// @copydoc AnimationTrack::getInterpolatedKeyFrame + /// @copydoc AnimationTrack::getInterpolatedKeyFrame virtual void getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf) const; - /// @copydoc AnimationTrack::apply - virtual void apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f); + /// @copydoc AnimationTrack::apply + virtual void apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f); /** Applies an animation track to a given animable value. - @param anim The AnimableValue to which to apply the animation + @param anim The AnimableValue to which to apply the animation @param timeIndex The time position in the animation to apply. @param weight The influence to give to this track, 1.0 for full influence, less to blend with other animations. - @param scale The scale to apply to translations and scalings, useful for - adapting an animation to a different size target. + @param scale The scale to apply to translations and scalings, useful for + adapting an animation to a different size target. */ - void applyToAnimable(const AnimableValuePtr& anim, const TimeIndex& timeIndex, - Real weight = 1.0, Real scale = 1.0f); + void applyToAnimable(const AnimableValuePtr& anim, const TimeIndex& timeIndex, + Real weight = 1.0, Real scale = 1.0f); - /** Returns a pointer to the associated animable object (if any). */ - virtual const AnimableValuePtr& getAssociatedAnimable(void) const; + /** Returns a pointer to the associated animable object (if any). */ + virtual const AnimableValuePtr& getAssociatedAnimable(void) const; - /** Sets the associated animable object which will be automatically - affected by calls to 'apply'. */ - virtual void setAssociatedAnimable(const AnimableValuePtr& val); + /** Sets the associated animable object which will be automatically + affected by calls to 'apply'. */ + virtual void setAssociatedAnimable(const AnimableValuePtr& val); - /** Returns the KeyFrame at the specified index. */ - NumericKeyFrame* getNumericKeyFrame(unsigned short index) const; + /** Returns the KeyFrame at the specified index. */ + NumericKeyFrame* getNumericKeyFrame(unsigned short index) const; - /** Clone this track (internal use only) */ - NumericAnimationTrack* _clone(Animation* newParent) const; + /** Clone this track (internal use only) */ + NumericAnimationTrack* _clone(Animation* newParent) const; - protected: - /// Target to animate - AnimableValuePtr mTargetAnim; + protected: + /// Target to animate + AnimableValuePtr mTargetAnim; - /// @copydoc AnimationTrack::createKeyFrameImpl - KeyFrame* createKeyFrameImpl(Real time); + /// @copydoc AnimationTrack::createKeyFrameImpl + KeyFrame* createKeyFrameImpl(Real time); - }; + }; - /** Specialised AnimationTrack for dealing with node transforms. - */ - class _OgreExport NodeAnimationTrack : public AnimationTrack - { - public: - /// Constructor - NodeAnimationTrack(Animation* parent, unsigned short handle); - /// Constructor, associates with a Node - NodeAnimationTrack(Animation* parent, unsigned short handle, - Node* targetNode); + /** Specialised AnimationTrack for dealing with node transforms. + */ + class _OgreExport NodeAnimationTrack : public AnimationTrack + { + public: + /// Constructor + NodeAnimationTrack(Animation* parent, unsigned short handle); + /// Constructor, associates with a Node + NodeAnimationTrack(Animation* parent, unsigned short handle, + Node* targetNode); /// Destructor virtual ~NodeAnimationTrack(); /** Creates a new KeyFrame and adds it to this animation at the given time index. @@ -342,241 +342,241 @@ namespace Ogre @param timePos The time from which this KeyFrame will apply. */ virtual TransformKeyFrame* createNodeKeyFrame(Real timePos); - /** Returns a pointer to the associated Node object (if any). */ - virtual Node* getAssociatedNode(void) const; + /** Returns a pointer to the associated Node object (if any). */ + virtual Node* getAssociatedNode(void) const; - /** Sets the associated Node object which will be automatically affected by calls to 'apply'. */ - virtual void setAssociatedNode(Node* node); + /** Sets the associated Node object which will be automatically affected by calls to 'apply'. */ + virtual void setAssociatedNode(Node* node); - /** As the 'apply' method but applies to a specified Node instead of associated node. */ - virtual void applyToNode(Node* node, const TimeIndex& timeIndex, Real weight = 1.0, - Real scale = 1.0f); + /** As the 'apply' method but applies to a specified Node instead of associated node. */ + virtual void applyToNode(Node* node, const TimeIndex& timeIndex, Real weight = 1.0, + Real scale = 1.0f); - /** Sets the method of rotation calculation */ - virtual void setUseShortestRotationPath(bool useShortestPath); + /** Sets the method of rotation calculation */ + virtual void setUseShortestRotationPath(bool useShortestPath); - /** Gets the method of rotation calculation */ - virtual bool getUseShortestRotationPath() const; + /** Gets the method of rotation calculation */ + virtual bool getUseShortestRotationPath() const; - /// @copydoc AnimationTrack::getInterpolatedKeyFrame + /// @copydoc AnimationTrack::getInterpolatedKeyFrame virtual void getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf) const; - /// @copydoc AnimationTrack::apply - virtual void apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f); + /// @copydoc AnimationTrack::apply + virtual void apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f); - /// @copydoc AnimationTrack::_keyFrameDataChanged - void _keyFrameDataChanged(void) const; + /// @copydoc AnimationTrack::_keyFrameDataChanged + void _keyFrameDataChanged(void) const; - /** Returns the KeyFrame at the specified index. */ - virtual TransformKeyFrame* getNodeKeyFrame(unsigned short index) const; + /** Returns the KeyFrame at the specified index. */ + virtual TransformKeyFrame* getNodeKeyFrame(unsigned short index) const; - /** Method to determine if this track has any KeyFrames which are - doing anything useful - can be used to determine if this track - can be optimised out. - */ - virtual bool hasNonZeroKeyFrames(void) const; + /** Method to determine if this track has any KeyFrames which are + doing anything useful - can be used to determine if this track + can be optimised out. + */ + virtual bool hasNonZeroKeyFrames(void) const; - /** Optimise the current track by removing any duplicate keyframes. */ - virtual void optimise(void); + /** Optimise the current track by removing any duplicate keyframes. */ + virtual void optimise(void); - /** Clone this track (internal use only) */ - NodeAnimationTrack* _clone(Animation* newParent) const; - - void _applyBaseKeyFrame(const KeyFrame* base); - - protected: - /// Specialised keyframe creation - KeyFrame* createKeyFrameImpl(Real time); - // Flag indicating we need to rebuild the splines next time - virtual void buildInterpolationSplines(void) const; + /** Clone this track (internal use only) */ + NodeAnimationTrack* _clone(Animation* newParent) const; + + void _applyBaseKeyFrame(const KeyFrame* base); + + protected: + /// Specialised keyframe creation + KeyFrame* createKeyFrameImpl(Real time); + // Flag indicating we need to rebuild the splines next time + virtual void buildInterpolationSplines(void) const; // Struct for store splines, allocate on demand for better memory footprint struct Splines { - SimpleSpline positionSpline; - SimpleSpline scaleSpline; - RotationalSpline rotationSpline; + SimpleSpline positionSpline; + SimpleSpline scaleSpline; + RotationalSpline rotationSpline; }; - Node* mTargetNode; - // Prebuilt splines, must be mutable since lazy-update in const method - mutable Splines* mSplines; - mutable bool mSplineBuildNeeded; - /// Defines if rotation is done using shortest path - mutable bool mUseShortestRotationPath ; - }; - - /** Type of vertex animation. - Vertex animation comes in 2 types, morph and pose. The reason - for the 2 types is that we have 2 different potential goals - to encapsulate - a complete, flowing morph animation with multiple keyframes (a typical animation, - but implemented by having snapshots of the vertex data at each keyframe), - or to represent a single pose change, for example a facial expression. - Whilst both could in fact be implemented using the same system, we choose - to separate them since the requirements and limitations of each are quite - different. - @par - Morph animation is a simple approach where we have a whole series of - snapshots of vertex data which must be interpolated, e.g. a running - animation implemented as morph targets. Because this is based on simple - snapshots, it's quite fast to use when animating an entire mesh because - it's a simple linear change between keyframes. However, this simplistic - approach does not support blending between multiple morph animations. - If you need animation blending, you are advised to use skeletal animation - for full-mesh animation, and pose animation for animation of subsets of - meshes or where skeletal animation doesn't fit - for example facial animation. - For animating in a vertex shader, morph animation is quite simple and - just requires the 2 vertex buffers (one the original position buffer) - of absolute position data, and an interpolation factor. Each track in - a morph animation references a unique set of vertex data. - @par - Pose animation is more complex. Like morph animation each track references - a single unique set of vertex data, but unlike morph animation, each - keyframe references 1 or more 'poses', each with an influence level. - A pose is a series of offsets to the base vertex data, and may be sparse - ie it - may not reference every vertex. Because they're offsets, they can be - blended - both within a track and between animations. This set of features - is very well suited to facial animation. - @par - For example, let's say you modelled a face (one set of vertex data), and - defined a set of poses which represented the various phonetic positions - of the face. You could then define an animation called 'SayHello', containing - a single track which referenced the face vertex data, and which included - a series of keyframes, each of which referenced one or more of the facial - positions at different influence levels - the combination of which over - time made the face form the shapes required to say the word 'hello'. Since - the poses are only stored once, but can be referenced may times in - many animations, this is a very powerful way to build up a speech system. - @par - The downside of pose animation is that it can be more difficult to set up. - Also, since it uses more buffers (one for the base data, and one for each - active pose), if you're animating in hardware using vertex shaders you need - to keep an eye on how many poses you're blending at once. You define a - maximum supported number in your vertex program definition, see the - includes_pose_animation material script entry. - @par - So, by partitioning the vertex animation approaches into 2, we keep the - simple morph technique easy to use, whilst still allowing all - the powerful techniques to be used. Note that morph animation cannot - be blended with other types of vertex animation (pose animation or other - morph animation); pose animation can be blended with other pose animation - though, and both types can be combined with skeletal animation. Also note - that all morph animation can be expressed as pose animation, but not vice - versa. - */ - enum VertexAnimationType - { - /// No animation - VAT_NONE = 0, - /// Morph animation is made up of many interpolated snapshot keyframes - VAT_MORPH = 1, - /// Pose animation is made up of a single delta pose keyframe - VAT_POSE = 2 - }; - - /** Specialised AnimationTrack for dealing with changing vertex position information. - @see VertexAnimationType - */ - class _OgreExport VertexAnimationTrack : public AnimationTrack - { - public: - /** The target animation mode */ - enum TargetMode - { - /// Interpolate vertex positions in software - TM_SOFTWARE, - /** Bind keyframe 1 to position, and keyframe 2 to a texture coordinate - for interpolation in hardware */ - TM_HARDWARE - }; - /// Constructor - VertexAnimationTrack(Animation* parent, unsigned short handle, VertexAnimationType animType); - /// Constructor, associates with target VertexData and temp buffer (for software) - VertexAnimationTrack(Animation* parent, unsigned short handle, VertexAnimationType animType, - VertexData* targetData, TargetMode target = TM_SOFTWARE); - - /** Get the type of vertex animation we're performing. */ - VertexAnimationType getAnimationType(void) const { return mAnimationType; } - - /** Whether the vertex animation (if present) includes normals */ - bool getVertexAnimationIncludesNormals() const; - - /** Creates a new morph KeyFrame and adds it to this animation at the given time index. - @remarks - It is better to create KeyFrames in time order. Creating them out of order can result - in expensive reordering processing. Note that a KeyFrame at time index 0.0 is always created - for you, so you don't need to create this one, just access it using getKeyFrame(0); - @param timePos The time from which this KeyFrame will apply. - */ - virtual VertexMorphKeyFrame* createVertexMorphKeyFrame(Real timePos); - - /** Creates the single pose KeyFrame and adds it to this animation. - */ - virtual VertexPoseKeyFrame* createVertexPoseKeyFrame(Real timePos); - - /** @copydoc AnimationTrack::getInterpolatedKeyFrame - */ + Node* mTargetNode; + // Prebuilt splines, must be mutable since lazy-update in const method + mutable Splines* mSplines; + mutable bool mSplineBuildNeeded; + /// Defines if rotation is done using shortest path + mutable bool mUseShortestRotationPath ; + }; + + /** Type of vertex animation. + Vertex animation comes in 2 types, morph and pose. The reason + for the 2 types is that we have 2 different potential goals - to encapsulate + a complete, flowing morph animation with multiple keyframes (a typical animation, + but implemented by having snapshots of the vertex data at each keyframe), + or to represent a single pose change, for example a facial expression. + Whilst both could in fact be implemented using the same system, we choose + to separate them since the requirements and limitations of each are quite + different. + @par + Morph animation is a simple approach where we have a whole series of + snapshots of vertex data which must be interpolated, e.g. a running + animation implemented as morph targets. Because this is based on simple + snapshots, it's quite fast to use when animating an entire mesh because + it's a simple linear change between keyframes. However, this simplistic + approach does not support blending between multiple morph animations. + If you need animation blending, you are advised to use skeletal animation + for full-mesh animation, and pose animation for animation of subsets of + meshes or where skeletal animation doesn't fit - for example facial animation. + For animating in a vertex shader, morph animation is quite simple and + just requires the 2 vertex buffers (one the original position buffer) + of absolute position data, and an interpolation factor. Each track in + a morph animation references a unique set of vertex data. + @par + Pose animation is more complex. Like morph animation each track references + a single unique set of vertex data, but unlike morph animation, each + keyframe references 1 or more 'poses', each with an influence level. + A pose is a series of offsets to the base vertex data, and may be sparse - ie it + may not reference every vertex. Because they're offsets, they can be + blended - both within a track and between animations. This set of features + is very well suited to facial animation. + @par + For example, let's say you modelled a face (one set of vertex data), and + defined a set of poses which represented the various phonetic positions + of the face. You could then define an animation called 'SayHello', containing + a single track which referenced the face vertex data, and which included + a series of keyframes, each of which referenced one or more of the facial + positions at different influence levels - the combination of which over + time made the face form the shapes required to say the word 'hello'. Since + the poses are only stored once, but can be referenced may times in + many animations, this is a very powerful way to build up a speech system. + @par + The downside of pose animation is that it can be more difficult to set up. + Also, since it uses more buffers (one for the base data, and one for each + active pose), if you're animating in hardware using vertex shaders you need + to keep an eye on how many poses you're blending at once. You define a + maximum supported number in your vertex program definition, see the + includes_pose_animation material script entry. + @par + So, by partitioning the vertex animation approaches into 2, we keep the + simple morph technique easy to use, whilst still allowing all + the powerful techniques to be used. Note that morph animation cannot + be blended with other types of vertex animation (pose animation or other + morph animation); pose animation can be blended with other pose animation + though, and both types can be combined with skeletal animation. Also note + that all morph animation can be expressed as pose animation, but not vice + versa. + */ + enum VertexAnimationType + { + /// No animation + VAT_NONE = 0, + /// Morph animation is made up of many interpolated snapshot keyframes + VAT_MORPH = 1, + /// Pose animation is made up of a single delta pose keyframe + VAT_POSE = 2 + }; + + /** Specialised AnimationTrack for dealing with changing vertex position information. + @see VertexAnimationType + */ + class _OgreExport VertexAnimationTrack : public AnimationTrack + { + public: + /** The target animation mode */ + enum TargetMode + { + /// Interpolate vertex positions in software + TM_SOFTWARE, + /** Bind keyframe 1 to position, and keyframe 2 to a texture coordinate + for interpolation in hardware */ + TM_HARDWARE + }; + /// Constructor + VertexAnimationTrack(Animation* parent, unsigned short handle, VertexAnimationType animType); + /// Constructor, associates with target VertexData and temp buffer (for software) + VertexAnimationTrack(Animation* parent, unsigned short handle, VertexAnimationType animType, + VertexData* targetData, TargetMode target = TM_SOFTWARE); + + /** Get the type of vertex animation we're performing. */ + VertexAnimationType getAnimationType(void) const { return mAnimationType; } + + /** Whether the vertex animation (if present) includes normals */ + bool getVertexAnimationIncludesNormals() const; + + /** Creates a new morph KeyFrame and adds it to this animation at the given time index. + @remarks + It is better to create KeyFrames in time order. Creating them out of order can result + in expensive reordering processing. Note that a KeyFrame at time index 0.0 is always created + for you, so you don't need to create this one, just access it using getKeyFrame(0); + @param timePos The time from which this KeyFrame will apply. + */ + virtual VertexMorphKeyFrame* createVertexMorphKeyFrame(Real timePos); + + /** Creates the single pose KeyFrame and adds it to this animation. + */ + virtual VertexPoseKeyFrame* createVertexPoseKeyFrame(Real timePos); + + /** @copydoc AnimationTrack::getInterpolatedKeyFrame + */ virtual void getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf) const; - /// @copydoc AnimationTrack::apply - virtual void apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f); + /// @copydoc AnimationTrack::apply + virtual void apply(const TimeIndex& timeIndex, Real weight = 1.0, Real scale = 1.0f); - /** As the 'apply' method but applies to specified VertexData instead of - associated data. */ - virtual void applyToVertexData(VertexData* data, - const TimeIndex& timeIndex, Real weight = 1.0, - const PoseList* poseList = 0); + /** As the 'apply' method but applies to specified VertexData instead of + associated data. */ + virtual void applyToVertexData(VertexData* data, + const TimeIndex& timeIndex, Real weight = 1.0, + const PoseList* poseList = 0); - /** Returns the morph KeyFrame at the specified index. */ - VertexMorphKeyFrame* getVertexMorphKeyFrame(unsigned short index) const; + /** Returns the morph KeyFrame at the specified index. */ + VertexMorphKeyFrame* getVertexMorphKeyFrame(unsigned short index) const; - /** Returns the pose KeyFrame at the specified index. */ - VertexPoseKeyFrame* getVertexPoseKeyFrame(unsigned short index) const; + /** Returns the pose KeyFrame at the specified index. */ + VertexPoseKeyFrame* getVertexPoseKeyFrame(unsigned short index) const; - /** Sets the associated VertexData which this track will update. */ - void setAssociatedVertexData(VertexData* data) { mTargetVertexData = data; } - /** Gets the associated VertexData which this track will update. */ - VertexData* getAssociatedVertexData(void) const { return mTargetVertexData; } + /** Sets the associated VertexData which this track will update. */ + void setAssociatedVertexData(VertexData* data) { mTargetVertexData = data; } + /** Gets the associated VertexData which this track will update. */ + VertexData* getAssociatedVertexData(void) const { return mTargetVertexData; } - /// Set the target mode - void setTargetMode(TargetMode m) { mTargetMode = m; } - /// Get the target mode - TargetMode getTargetMode(void) const { return mTargetMode; } + /// Set the target mode + void setTargetMode(TargetMode m) { mTargetMode = m; } + /// Get the target mode + TargetMode getTargetMode(void) const { return mTargetMode; } - /** Method to determine if this track has any KeyFrames which are - doing anything useful - can be used to determine if this track - can be optimised out. - */ - virtual bool hasNonZeroKeyFrames(void) const; + /** Method to determine if this track has any KeyFrames which are + doing anything useful - can be used to determine if this track + can be optimised out. + */ + virtual bool hasNonZeroKeyFrames(void) const; - /** Optimise the current track by removing any duplicate keyframes. */ - virtual void optimise(void); + /** Optimise the current track by removing any duplicate keyframes. */ + virtual void optimise(void); - /** Clone this track (internal use only) */ - VertexAnimationTrack* _clone(Animation* newParent) const; - - void _applyBaseKeyFrame(const KeyFrame* base); + /** Clone this track (internal use only) */ + VertexAnimationTrack* _clone(Animation* newParent) const; + + void _applyBaseKeyFrame(const KeyFrame* base); - protected: - /// Animation type - VertexAnimationType mAnimationType; - /// Target to animate - VertexData* mTargetVertexData; - /// Mode to apply - TargetMode mTargetMode; + protected: + /// Animation type + VertexAnimationType mAnimationType; + /// Target to animate + VertexData* mTargetVertexData; + /// Mode to apply + TargetMode mTargetMode; - /// @copydoc AnimationTrack::createKeyFrameImpl - KeyFrame* createKeyFrameImpl(Real time); + /// @copydoc AnimationTrack::createKeyFrameImpl + KeyFrame* createKeyFrameImpl(Real time); - /// Utility method for applying pose animation - void applyPoseToVertexData(const Pose* pose, VertexData* data, Real influence); + /// Utility method for applying pose animation + void applyPoseToVertexData(const Pose* pose, VertexData* data, Real influence); - }; - /** @} */ - /** @} */ + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreAny.h b/OgreMain/include/OgreAny.h index cf138b53331..82ba70c1f9c 100644 --- a/OgreMain/include/OgreAny.h +++ b/OgreMain/include/OgreAny.h @@ -43,15 +43,15 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** Variant type that can hold Any other type. - */ - class Any + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** Variant type that can hold Any other type. + */ + class Any { public: // constructors @@ -109,23 +109,23 @@ namespace Ogre return mContent ? mContent->getType() : typeid(void); } - inline friend std::ostream& operator << - ( std::ostream& o, const Any& v ) - { - if (v.mContent) - v.mContent->writeToStream(o); - return o; - } + inline friend std::ostream& operator << + ( std::ostream& o, const Any& v ) + { + if (v.mContent) + v.mContent->writeToStream(o); + return o; + } - void destroy() - { - OGRE_DELETE_T(mContent, placeholder, MEMCATEGORY_GENERAL); - mContent = NULL; - } + void destroy() + { + OGRE_DELETE_T(mContent, placeholder, MEMCATEGORY_GENERAL); + mContent = NULL; + } protected: // types - class placeholder + class placeholder { public: // structors @@ -139,7 +139,7 @@ namespace Ogre virtual placeholder * clone() const = 0; - virtual void writeToStream(std::ostream& o) = 0; + virtual void writeToStream(std::ostream& o) = 0; }; @@ -165,10 +165,10 @@ namespace Ogre return OGRE_NEW_T(holder, MEMCATEGORY_GENERAL)(held); } - virtual void writeToStream(std::ostream& o) - { - o << held; - } + virtual void writeToStream(std::ostream& o) + { + o << held; + } public: // representation @@ -188,215 +188,215 @@ namespace Ogre public: - template - ValueType operator()() const - { - if (!mContent) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Bad cast from uninitialised Any", - "Any::operator()"); - } - else if(getType() == typeid(ValueType)) - { - return static_cast *>(mContent)->held; - } - else - { - StringStream str; - str << "Bad cast from type '" << getType().name() << "' " - << "to '" << typeid(ValueType).name() << "'"; - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - str.str(), - "Any::operator()"); - } - } - - template - ValueType get(void) const - { - if (!mContent) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Bad cast from uninitialised Any", - "Any::operator()"); - } - else if(getType() == typeid(ValueType)) - { - return static_cast *>(mContent)->held; - } - else - { - StringStream str; - str << "Bad cast from type '" << getType().name() << "' " - << "to '" << typeid(ValueType).name() << "'"; - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - str.str(), - "Any::operator()"); - } - } + template + ValueType operator()() const + { + if (!mContent) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Bad cast from uninitialised Any", + "Any::operator()"); + } + else if(getType() == typeid(ValueType)) + { + return static_cast *>(mContent)->held; + } + else + { + StringStream str; + str << "Bad cast from type '" << getType().name() << "' " + << "to '" << typeid(ValueType).name() << "'"; + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + str.str(), + "Any::operator()"); + } + } + + template + ValueType get(void) const + { + if (!mContent) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Bad cast from uninitialised Any", + "Any::operator()"); + } + else if(getType() == typeid(ValueType)) + { + return static_cast *>(mContent)->held; + } + else + { + StringStream str; + str << "Bad cast from type '" << getType().name() << "' " + << "to '" << typeid(ValueType).name() << "'"; + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + str.str(), + "Any::operator()"); + } + } }; - /** Specialised Any class which has built in arithmetic operators, but can - hold only types which support operator +,-,* and / . - */ - class AnyNumeric : public Any - { - public: - AnyNumeric() - : Any() - { - } - - template - AnyNumeric(const ValueType & value) - - { - mContent = OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(value); - } - - AnyNumeric(const AnyNumeric & other) + /** Specialised Any class which has built in arithmetic operators, but can + hold only types which support operator +,-,* and / . + */ + class AnyNumeric : public Any + { + public: + AnyNumeric() + : Any() + { + } + + template + AnyNumeric(const ValueType & value) + + { + mContent = OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(value); + } + + AnyNumeric(const AnyNumeric & other) : Any() - { - mContent = other.mContent ? other.mContent->clone() : 0; - } - - protected: - class numplaceholder : public Any::placeholder - { - public: // structors - - ~numplaceholder() - { - } - virtual placeholder* add(placeholder* rhs) = 0; - virtual placeholder* subtract(placeholder* rhs) = 0; - virtual placeholder* multiply(placeholder* rhs) = 0; - virtual placeholder* multiply(Real factor) = 0; - virtual placeholder* divide(placeholder* rhs) = 0; - }; - - template - class numholder : public numplaceholder - { - public: // structors - - numholder(const ValueType & value) - : held(value) - { - } - - public: // queries - - virtual const std::type_info & getType() const - { - return typeid(ValueType); - } - - virtual placeholder * clone() const - { - return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held); - } - - virtual placeholder* add(placeholder* rhs) - { - return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held + static_cast(rhs)->held); - } - virtual placeholder* subtract(placeholder* rhs) - { - return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held - static_cast(rhs)->held); - } - virtual placeholder* multiply(placeholder* rhs) - { - return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * static_cast(rhs)->held); - } - virtual placeholder* multiply(Real factor) - { - return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * factor); - } - virtual placeholder* divide(placeholder* rhs) - { - return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held / static_cast(rhs)->held); - } - virtual void writeToStream(std::ostream& o) - { - o << held; - } - - public: // representation - - ValueType held; - - }; - - /// Construct from holder - AnyNumeric(placeholder* pholder) - { - mContent = pholder; - } - - public: - AnyNumeric & operator=(const AnyNumeric & rhs) - { - AnyNumeric(rhs).swap(*this); - return *this; - } - AnyNumeric operator+(const AnyNumeric& rhs) const - { - return AnyNumeric( - static_cast(mContent)->add(rhs.mContent)); - } - AnyNumeric operator-(const AnyNumeric& rhs) const - { - return AnyNumeric( - static_cast(mContent)->subtract(rhs.mContent)); - } - AnyNumeric operator*(const AnyNumeric& rhs) const - { - return AnyNumeric( - static_cast(mContent)->multiply(rhs.mContent)); - } - AnyNumeric operator*(Real factor) const - { - return AnyNumeric( - static_cast(mContent)->multiply(factor)); - } - AnyNumeric operator/(const AnyNumeric& rhs) const - { - return AnyNumeric( - static_cast(mContent)->divide(rhs.mContent)); - } - AnyNumeric& operator+=(const AnyNumeric& rhs) - { - *this = AnyNumeric( - static_cast(mContent)->add(rhs.mContent)); - return *this; - } - AnyNumeric& operator-=(const AnyNumeric& rhs) - { - *this = AnyNumeric( - static_cast(mContent)->subtract(rhs.mContent)); - return *this; - } - AnyNumeric& operator*=(const AnyNumeric& rhs) - { - *this = AnyNumeric( - static_cast(mContent)->multiply(rhs.mContent)); - return *this; - } - AnyNumeric& operator/=(const AnyNumeric& rhs) - { - *this = AnyNumeric( - static_cast(mContent)->divide(rhs.mContent)); - return *this; - } - - - - - }; + { + mContent = other.mContent ? other.mContent->clone() : 0; + } + + protected: + class numplaceholder : public Any::placeholder + { + public: // structors + + ~numplaceholder() + { + } + virtual placeholder* add(placeholder* rhs) = 0; + virtual placeholder* subtract(placeholder* rhs) = 0; + virtual placeholder* multiply(placeholder* rhs) = 0; + virtual placeholder* multiply(Real factor) = 0; + virtual placeholder* divide(placeholder* rhs) = 0; + }; + + template + class numholder : public numplaceholder + { + public: // structors + + numholder(const ValueType & value) + : held(value) + { + } + + public: // queries + + virtual const std::type_info & getType() const + { + return typeid(ValueType); + } + + virtual placeholder * clone() const + { + return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held); + } + + virtual placeholder* add(placeholder* rhs) + { + return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held + static_cast(rhs)->held); + } + virtual placeholder* subtract(placeholder* rhs) + { + return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held - static_cast(rhs)->held); + } + virtual placeholder* multiply(placeholder* rhs) + { + return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * static_cast(rhs)->held); + } + virtual placeholder* multiply(Real factor) + { + return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held * factor); + } + virtual placeholder* divide(placeholder* rhs) + { + return OGRE_NEW_T(numholder, MEMCATEGORY_GENERAL)(held / static_cast(rhs)->held); + } + virtual void writeToStream(std::ostream& o) + { + o << held; + } + + public: // representation + + ValueType held; + + }; + + /// Construct from holder + AnyNumeric(placeholder* pholder) + { + mContent = pholder; + } + + public: + AnyNumeric & operator=(const AnyNumeric & rhs) + { + AnyNumeric(rhs).swap(*this); + return *this; + } + AnyNumeric operator+(const AnyNumeric& rhs) const + { + return AnyNumeric( + static_cast(mContent)->add(rhs.mContent)); + } + AnyNumeric operator-(const AnyNumeric& rhs) const + { + return AnyNumeric( + static_cast(mContent)->subtract(rhs.mContent)); + } + AnyNumeric operator*(const AnyNumeric& rhs) const + { + return AnyNumeric( + static_cast(mContent)->multiply(rhs.mContent)); + } + AnyNumeric operator*(Real factor) const + { + return AnyNumeric( + static_cast(mContent)->multiply(factor)); + } + AnyNumeric operator/(const AnyNumeric& rhs) const + { + return AnyNumeric( + static_cast(mContent)->divide(rhs.mContent)); + } + AnyNumeric& operator+=(const AnyNumeric& rhs) + { + *this = AnyNumeric( + static_cast(mContent)->add(rhs.mContent)); + return *this; + } + AnyNumeric& operator-=(const AnyNumeric& rhs) + { + *this = AnyNumeric( + static_cast(mContent)->subtract(rhs.mContent)); + return *this; + } + AnyNumeric& operator*=(const AnyNumeric& rhs) + { + *this = AnyNumeric( + static_cast(mContent)->multiply(rhs.mContent)); + return *this; + } + AnyNumeric& operator/=(const AnyNumeric& rhs) + { + *this = AnyNumeric( + static_cast(mContent)->divide(rhs.mContent)); + return *this; + } + + + + + }; template @@ -418,18 +418,18 @@ namespace Ogre { const ValueType * result = any_cast(&operand); if(!result) - { - StringStream str; - str << "Bad cast from type '" << operand.getType().name() << "' " - << "to '" << typeid(ValueType).name() << "'"; - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - str.str(), - "Ogre::any_cast"); - } + { + StringStream str; + str << "Bad cast from type '" << operand.getType().name() << "' " + << "to '" << typeid(ValueType).name() << "'"; + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + str.str(), + "Ogre::any_cast"); + } return *result; } - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreArchive.h b/OgreMain/include/OgreArchive.h index d0a0f686d36..1a7a919edd7 100644 --- a/OgreMain/include/OgreArchive.h +++ b/OgreMain/include/OgreArchive.h @@ -37,21 +37,21 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ /** Information about a file/directory within the archive will be returned using a FileInfo struct. @see Archive */ struct FileInfo { - /// The archive in which the file has been found (for info when performing - /// multi-Archive searches, note you should still open through ResourceGroupManager) - const Archive* archive; + /// The archive in which the file has been found (for info when performing + /// multi-Archive searches, note you should still open through ResourceGroupManager) + const Archive* archive; /// The file's fully qualified name String filename; /// Path name; separated by '/' and ending with '/' @@ -83,15 +83,15 @@ namespace Ogre { to benefit from OGRE's automatic searching of multiple file locations for the resources you are looking for. */ - class _OgreExport Archive : public ArchiveAlloc + class _OgreExport Archive : public ArchiveAlloc { protected: /// Archive name String mName; /// Archive type code String mType; - /// Read-only flag - bool mReadOnly; + /// Read-only flag + bool mReadOnly; public: @@ -104,8 +104,8 @@ namespace Ogre { */ virtual ~Archive() {} - /// Get the name of this archive - const String& getName(void) const { return mName; } + /// Get the name of this archive + const String& getName(void) const { return mName; } /// Returns whether this archive is case sensitive in the way it matches files virtual bool isCaseSensitive(void) const = 0; @@ -126,49 +126,49 @@ namespace Ogre { */ virtual void unload() = 0; - /** Reports whether this Archive is read-only, or whether the contents - can be updated. - */ - virtual bool isReadOnly() const { return mReadOnly; } + /** Reports whether this Archive is read-only, or whether the contents + can be updated. + */ + virtual bool isReadOnly() const { return mReadOnly; } /** Open a stream on a given file. @note There is no equivalent 'close' method; the returned stream controls the lifecycle of this file operation. @param filename The fully qualified name of the file - @param readOnly Whether to open the file in read-only mode or not (note, - if the archive is read-only then this cannot be set to false) + @param readOnly Whether to open the file in read-only mode or not (note, + if the archive is read-only then this cannot be set to false) @return A shared pointer to a DataStream which can be used to read / write the file. If the file is not present, returns a null - shared pointer. + shared pointer. */ virtual DataStreamPtr open(const String& filename, bool readOnly = true) const = 0; - /** Create a new file (or overwrite one already there). - @note If the archive is read-only then this method will fail. - @param filename The fully qualified name of the file - @return A shared pointer to a DataStream which can be used to - read / write the file. - */ - virtual DataStreamPtr create(const String& filename) const - { + /** Create a new file (or overwrite one already there). + @note If the archive is read-only then this method will fail. + @param filename The fully qualified name of the file + @return A shared pointer to a DataStream which can be used to + read / write the file. + */ + virtual DataStreamPtr create(const String& filename) const + { (void)filename; - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This archive does not support creation of files.", - "Archive::create"); - } - - /** Delete a named file. - @remarks Not possible on read-only archives - @param filename The fully qualified name of the file - */ - virtual void remove(const String& filename) const - { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This archive does not support creation of files.", + "Archive::create"); + } + + /** Delete a named file. + @remarks Not possible on read-only archives + @param filename The fully qualified name of the file + */ + virtual void remove(const String& filename) const + { (void)filename; - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This archive does not support removal of files.", - "Archive::remove"); - } + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This archive does not support removal of files.", + "Archive::remove"); + } /** List all file names in the archive. @note @@ -210,8 +210,8 @@ namespace Ogre { /** Find out if the named file exists (note: fully qualified filename required) */ virtual bool exists(const String& filename) = 0; - /** Retrieve the modification time of a given file */ - virtual time_t getModifiedTime(const String& filename) = 0; + /** Retrieve the modification time of a given file */ + virtual time_t getModifiedTime(const String& filename) = 0; /** Find all files or directories matching a given pattern in this @@ -231,8 +231,8 @@ namespace Ogre { const String& getType(void) const { return mType; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreArchiveFactory.h b/OgreMain/include/OgreArchiveFactory.h index cffc7b9d06b..4267e242d6f 100644 --- a/OgreMain/include/OgreArchiveFactory.h +++ b/OgreMain/include/OgreArchiveFactory.h @@ -34,12 +34,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ /** Abstract factory class, archive codec plugins can register concrete subclasses of this. @remarks @@ -70,8 +70,8 @@ namespace Ogre { virtual Archive* createInstance(const String& name) { return createInstance(name, true); } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreArchiveManager.h b/OgreMain/include/OgreArchiveManager.h index ff284cfe876..9d13a197b0c 100644 --- a/OgreMain/include/OgreArchiveManager.h +++ b/OgreMain/include/OgreArchiveManager.h @@ -36,12 +36,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ /** This class manages the available ArchiveFactory plugins. */ class _OgreExport ArchiveManager : public Singleton, public ArchiveAlloc @@ -78,19 +78,19 @@ namespace Ogre { */ Archive* load( const String& filename, const String& archiveType, bool readOnly); - /** Unloads an archive. - @remarks - You must ensure that this archive is not being used before removing it. - */ - void unload(Archive* arch); - /** Unloads an archive by name. - @remarks - You must ensure that this archive is not being used before removing it. - */ - void unload(const String& filename); - typedef MapIterator ArchiveMapIterator; - /** Get an iterator over the Archives in this Manager. */ - ArchiveMapIterator getArchiveIterator(void); + /** Unloads an archive. + @remarks + You must ensure that this archive is not being used before removing it. + */ + void unload(Archive* arch); + /** Unloads an archive by name. + @remarks + You must ensure that this archive is not being used before removing it. + */ + void unload(const String& filename); + typedef MapIterator ArchiveMapIterator; + /** Get an iterator over the Archives in this Manager. */ + ArchiveMapIterator getArchiveIterator(void); /** Adds a new ArchiveFactory to the list of available factories. @remarks @@ -132,8 +132,8 @@ namespace Ogre { */ static ArchiveManager* getSingletonPtr(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreAtomicObject.h b/OgreMain/include/OgreAtomicObject.h index ce243d724e2..8e83ac27ee0 100644 --- a/OgreMain/include/OgreAtomicObject.h +++ b/OgreMain/include/OgreAtomicObject.h @@ -34,12 +34,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ template class AtomicObject { public: @@ -98,19 +98,19 @@ namespace Ogre { return mField--; } - T operator+=(const T &add) - { + T operator+=(const T &add) + { OGRE_LOCK_AUTO_MUTEX; - mField += add; - return mField; - } + mField += add; + return mField; + } - T operator-=(const T &sub) - { + T operator-=(const T &sub) + { OGRE_LOCK_AUTO_MUTEX; - mField -= sub; - return mField; - } + mField -= sub; + return mField; + } protected: @@ -119,8 +119,8 @@ namespace Ogre { volatile T mField; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreAtomicScalar.h b/OgreMain/include/OgreAtomicScalar.h index e3c0166e1b7..7edc21738e2 100644 --- a/OgreMain/include/OgreAtomicScalar.h +++ b/OgreMain/include/OgreAtomicScalar.h @@ -47,12 +47,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ template class AtomicScalar { @@ -109,15 +109,15 @@ namespace Ogre { return BUILTIN_FETCH_ADD (&mField, -1); } - T operator+=(const T &add) - { - return BUILTIN_ADD_FETCH (&mField, add); - } + T operator+=(const T &add) + { + return BUILTIN_ADD_FETCH (&mField, add); + } - T operator-=(const T &sub) - { - return BUILTIN_SUB_FETCH (&mField, sub); - } + T operator-=(const T &sub) + { + return BUILTIN_SUB_FETCH (&mField, sub); + } // Need special alignment for atomic functions on ARM CPU's #if OGRE_CPU == OGRE_CPU_ARM @@ -131,8 +131,8 @@ namespace Ogre { #endif }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } @@ -143,7 +143,7 @@ namespace Ogre { # define WIN32_LEAN_AND_MEAN #endif #if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min #endif #include #include @@ -209,11 +209,11 @@ namespace Ogre { }; /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + * @{ + */ + /** \addtogroup General + * @{ + */ template class AtomicScalar { @@ -250,14 +250,14 @@ namespace Ogre { if (sizeof(T)==2) { return _InterlockedCompareExchange16((SHORT*)&mField, static_cast(nu), static_cast(old)) == static_cast(old); } - else if (sizeof(T)==4) - { + else if (sizeof(T)==4) + { return _InterlockedCompareExchange((LONG*)&mField, static_cast(nu), static_cast(old)) == static_cast(old); - } - else if (sizeof(T)==8 && InterlockedCompareExchange64Wrapper::Ogre_InterlockedCompareExchange64 != NULL) { + } + else if (sizeof(T)==8 && InterlockedCompareExchange64Wrapper::Ogre_InterlockedCompareExchange64 != NULL) { return InterlockedCompareExchange64Wrapper::Ogre_InterlockedCompareExchange64((LONGLONG*)&mField, static_cast(nu), static_cast(old)) == static_cast(old); } - else { + else { OGRE_LOCK_AUTO_MUTEX; if (mField != old) return false; mField = nu; @@ -321,8 +321,8 @@ namespace Ogre { } } - T operator+=(const T &add) - { + T operator+=(const T &add) + { if ((sizeof(T)==2) || (sizeof(T)==4) || (sizeof(T)==8 && InterlockedCompareExchange64Wrapper::Ogre_InterlockedCompareExchange64 != NULL)) { //The function InterlockedExchangeAdd is not available for 64 and 16 bit version //We will use the cas operation instead. @@ -342,10 +342,10 @@ namespace Ogre { mField += add; return mField; } - } + } - T operator-=(const T &sub) - { + T operator-=(const T &sub) + { if ((sizeof(T)==2) || (sizeof(T)==4) || (sizeof(T)==8 && InterlockedCompareExchange64Wrapper::Ogre_InterlockedCompareExchange64 != NULL)) { //The function InterlockedExchangeAdd is not available for 64 and 16 bit version //We will use the cas operation instead. @@ -365,7 +365,7 @@ namespace Ogre { mField -= sub; return mField; } - } + } protected: @@ -374,8 +374,8 @@ namespace Ogre { volatile T mField; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } @@ -387,12 +387,12 @@ namespace Ogre { namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ template class AtomicScalar { public: @@ -458,19 +458,19 @@ namespace Ogre { return mField--; } - T operator+=(const T &add) - { + T operator+=(const T &add) + { OGRE_LOCK_AUTO_MUTEX; - mField += add; - return mField; - } + mField += add; + return mField; + } - T operator-=(const T &sub) - { + T operator-=(const T &sub) + { OGRE_LOCK_AUTO_MUTEX; - mField -= sub; - return mField; - } + mField -= sub; + return mField; + } protected: @@ -479,8 +479,8 @@ namespace Ogre { volatile T mField; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreAutoParamDataSource.h b/OgreMain/include/OgreAutoParamDataSource.h index 50adc2d307c..586410cb53e 100644 --- a/OgreMain/include/OgreAutoParamDataSource.h +++ b/OgreMain/include/OgreAutoParamDataSource.h @@ -34,15 +34,15 @@ THE SOFTWARE. namespace Ogre { - // forward decls - struct VisibleObjectsBoundsInfo; + // forward decls + struct VisibleObjectsBoundsInfo; - /** \addtogroup Core - * @{ - */ - /** \addtogroup Materials - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Materials + * @{ + */ /** This utility class is used to hold the information used to generate the matrices @@ -55,10 +55,10 @@ namespace Ogre { matrices when they are requested more than once when the underlying information has not altered. */ - class _OgreExport AutoParamDataSource : public SceneMgtAlloc + class _OgreExport AutoParamDataSource : public SceneMgtAlloc { protected: - const Light& getLight(size_t index) const; + const Light& getLight(size_t index) const; mutable Matrix4 mWorldMatrix[256]; mutable size_t mWorldMatrixCount; mutable const Matrix4* mWorldMatrixArray; @@ -70,18 +70,18 @@ namespace Ogre { mutable Matrix4 mInverseViewMatrix; mutable Matrix4 mInverseTransposeWorldMatrix; mutable Matrix4 mInverseTransposeWorldViewMatrix; - mutable Vector4 mCameraPosition; + mutable Vector4 mCameraPosition; mutable Vector4 mCameraPositionObjectSpace; mutable Matrix4 mTextureViewProjMatrix[OGRE_MAX_SIMULTANEOUS_LIGHTS]; - mutable Matrix4 mTextureWorldViewProjMatrix[OGRE_MAX_SIMULTANEOUS_LIGHTS]; - mutable Matrix4 mSpotlightViewProjMatrix[OGRE_MAX_SIMULTANEOUS_LIGHTS]; - mutable Matrix4 mSpotlightWorldViewProjMatrix[OGRE_MAX_SIMULTANEOUS_LIGHTS]; - mutable Vector4 mShadowCamDepthRanges[OGRE_MAX_SIMULTANEOUS_LIGHTS]; + mutable Matrix4 mTextureWorldViewProjMatrix[OGRE_MAX_SIMULTANEOUS_LIGHTS]; + mutable Matrix4 mSpotlightViewProjMatrix[OGRE_MAX_SIMULTANEOUS_LIGHTS]; + mutable Matrix4 mSpotlightWorldViewProjMatrix[OGRE_MAX_SIMULTANEOUS_LIGHTS]; + mutable Vector4 mShadowCamDepthRanges[OGRE_MAX_SIMULTANEOUS_LIGHTS]; mutable Matrix4 mViewMatrix; mutable Matrix4 mProjectionMatrix; - mutable Real mDirLightExtrusionDistance; - mutable Vector4 mLodCameraPosition; - mutable Vector4 mLodCameraPositionObjectSpace; + mutable Real mDirLightExtrusionDistance; + mutable Vector4 mLodCameraPosition; + mutable Vector4 mLodCameraPositionObjectSpace; mutable bool mWorldMatrixDirty; mutable bool mViewMatrixDirty; @@ -94,32 +94,32 @@ namespace Ogre { mutable bool mInverseViewMatrixDirty; mutable bool mInverseTransposeWorldMatrixDirty; mutable bool mInverseTransposeWorldViewMatrixDirty; - mutable bool mCameraPositionDirty; + mutable bool mCameraPositionDirty; mutable bool mCameraPositionObjectSpaceDirty; mutable bool mTextureViewProjMatrixDirty[OGRE_MAX_SIMULTANEOUS_LIGHTS]; - mutable bool mTextureWorldViewProjMatrixDirty[OGRE_MAX_SIMULTANEOUS_LIGHTS]; - mutable bool mSpotlightViewProjMatrixDirty[OGRE_MAX_SIMULTANEOUS_LIGHTS]; - mutable bool mSpotlightWorldViewProjMatrixDirty[OGRE_MAX_SIMULTANEOUS_LIGHTS]; - mutable bool mShadowCamDepthRangesDirty[OGRE_MAX_SIMULTANEOUS_LIGHTS]; - mutable ColourValue mAmbientLight; + mutable bool mTextureWorldViewProjMatrixDirty[OGRE_MAX_SIMULTANEOUS_LIGHTS]; + mutable bool mSpotlightViewProjMatrixDirty[OGRE_MAX_SIMULTANEOUS_LIGHTS]; + mutable bool mSpotlightWorldViewProjMatrixDirty[OGRE_MAX_SIMULTANEOUS_LIGHTS]; + mutable bool mShadowCamDepthRangesDirty[OGRE_MAX_SIMULTANEOUS_LIGHTS]; + mutable ColourValue mAmbientLight; mutable ColourValue mFogColour; mutable Vector4 mFogParams; mutable int mPassNumber; - mutable Vector4 mSceneDepthRange; - mutable bool mSceneDepthRangeDirty; - mutable bool mLodCameraPositionDirty; - mutable bool mLodCameraPositionObjectSpaceDirty; + mutable Vector4 mSceneDepthRange; + mutable bool mSceneDepthRangeDirty; + mutable bool mLodCameraPositionDirty; + mutable bool mLodCameraPositionObjectSpaceDirty; const Renderable* mCurrentRenderable; const Camera* mCurrentCamera; - bool mCameraRelativeRendering; - Vector3 mCameraRelativePosition; + bool mCameraRelativeRendering; + Vector3 mCameraRelativePosition; const LightList* mCurrentLightList; const Frustum* mCurrentTextureProjector[OGRE_MAX_SIMULTANEOUS_LIGHTS]; const RenderTarget* mCurrentRenderTarget; const Viewport* mCurrentViewport; - const SceneManager* mCurrentSceneManager; - const VisibleObjectsBoundsInfo* mMainCamBoundsInfo; + const SceneManager* mCurrentSceneManager; + const VisibleObjectsBoundsInfo* mMainCamBoundsInfo; const Pass* mCurrentPass; Light mBlankLight; @@ -140,12 +140,12 @@ namespace Ogre { virtual void setCurrentRenderTarget(const RenderTarget* target); /** Sets the current viewport */ virtual void setCurrentViewport(const Viewport* viewport); - /** Sets the shadow extrusion distance to be used for point lights. */ - virtual void setShadowDirLightExtrusionDistance(Real dist); - /** Sets the main camera's scene bounding information */ - virtual void setMainCamBoundsInfo(VisibleObjectsBoundsInfo* info); - /** Set the current scene manager for enquiring on demand */ - virtual void setCurrentSceneManager(const SceneManager* sm); + /** Sets the shadow extrusion distance to be used for point lights. */ + virtual void setShadowDirLightExtrusionDistance(Real dist); + /** Sets the main camera's scene bounding information */ + virtual void setMainCamBoundsInfo(VisibleObjectsBoundsInfo* info); + /** Set the current scene manager for enquiring on demand */ + virtual void setCurrentSceneManager(const SceneManager* sm); /** Sets the current pass */ virtual void setCurrentPass(const Pass* pass); @@ -166,25 +166,25 @@ namespace Ogre { virtual const Matrix4& getInverseTransposeWorldViewMatrix(void) const; virtual const Vector4& getCameraPosition(void) const; virtual const Vector4& getCameraPositionObjectSpace(void) const; - virtual const Vector4& getLodCameraPosition(void) const; - virtual const Vector4& getLodCameraPositionObjectSpace(void) const; - virtual bool hasLightList() const { return mCurrentLightList != 0; } + virtual const Vector4& getLodCameraPosition(void) const; + virtual const Vector4& getLodCameraPositionObjectSpace(void) const; + virtual bool hasLightList() const { return mCurrentLightList != 0; } /** Get the light which is 'index'th closest to the current object */ - virtual float getLightNumber(size_t index) const; - virtual float getLightCount() const; - virtual float getLightCastsShadows(size_t index) const; - virtual const ColourValue& getLightDiffuseColour(size_t index) const; - virtual const ColourValue& getLightSpecularColour(size_t index) const; - virtual const ColourValue getLightDiffuseColourWithPower(size_t index) const; - virtual const ColourValue getLightSpecularColourWithPower(size_t index) const; - virtual const Vector3& getLightPosition(size_t index) const; - virtual Vector4 getLightAs4DVector(size_t index) const; - virtual const Vector3& getLightDirection(size_t index) const; - virtual Real getLightPowerScale(size_t index) const; - virtual Vector4 getLightAttenuation(size_t index) const; - virtual Vector4 getSpotlightParams(size_t index) const; - virtual void setAmbientLightColour(const ColourValue& ambient); - virtual const ColourValue& getAmbientLightColour(void) const; + virtual float getLightNumber(size_t index) const; + virtual float getLightCount() const; + virtual float getLightCastsShadows(size_t index) const; + virtual const ColourValue& getLightDiffuseColour(size_t index) const; + virtual const ColourValue& getLightSpecularColour(size_t index) const; + virtual const ColourValue getLightDiffuseColourWithPower(size_t index) const; + virtual const ColourValue getLightSpecularColourWithPower(size_t index) const; + virtual const Vector3& getLightPosition(size_t index) const; + virtual Vector4 getLightAs4DVector(size_t index) const; + virtual const Vector3& getLightDirection(size_t index) const; + virtual Real getLightPowerScale(size_t index) const; + virtual Vector4 getLightAttenuation(size_t index) const; + virtual Vector4 getSpotlightParams(size_t index) const; + virtual void setAmbientLightColour(const ColourValue& ambient); + virtual const ColourValue& getAmbientLightColour(void) const; virtual const ColourValue& getSurfaceAmbientColour(void) const; virtual const ColourValue& getSurfaceDiffuseColour(void) const; virtual const ColourValue& getSurfaceSpecularColour(void) const; @@ -197,9 +197,9 @@ namespace Ogre { virtual const ColourValue& getFogColour(void) const; virtual const Vector4& getFogParams(void) const; virtual const Matrix4& getTextureViewProjMatrix(size_t index) const; - virtual const Matrix4& getTextureWorldViewProjMatrix(size_t index) const; - virtual const Matrix4& getSpotlightViewProjMatrix(size_t index) const; - virtual const Matrix4& getSpotlightWorldViewProjMatrix(size_t index) const; + virtual const Matrix4& getTextureWorldViewProjMatrix(size_t index) const; + virtual const Matrix4& getSpotlightViewProjMatrix(size_t index) const; + virtual const Matrix4& getSpotlightWorldViewProjMatrix(size_t index) const; virtual const Matrix4& getTextureTransformMatrix(size_t index) const; virtual const RenderTarget* getCurrentRenderTarget(void) const; virtual const Renderable* getCurrentRenderable(void) const; @@ -207,58 +207,58 @@ namespace Ogre { virtual Vector4 getTextureSize(size_t index) const; virtual Vector4 getInverseTextureSize(size_t index) const; virtual Vector4 getPackedTextureSize(size_t index) const; - virtual Real getShadowExtrusionDistance(void) const; - virtual const Vector4& getSceneDepthRange() const; - virtual const Vector4& getShadowSceneDepthRange(size_t index) const; - virtual const ColourValue& getShadowColour() const; - virtual Matrix4 getInverseViewProjMatrix(void) const; - virtual Matrix4 getInverseTransposeViewProjMatrix() const; - virtual Matrix4 getTransposeViewProjMatrix() const; - virtual Matrix4 getTransposeViewMatrix() const; + virtual Real getShadowExtrusionDistance(void) const; + virtual const Vector4& getSceneDepthRange() const; + virtual const Vector4& getShadowSceneDepthRange(size_t index) const; + virtual const ColourValue& getShadowColour() const; + virtual Matrix4 getInverseViewProjMatrix(void) const; + virtual Matrix4 getInverseTransposeViewProjMatrix() const; + virtual Matrix4 getTransposeViewProjMatrix() const; + virtual Matrix4 getTransposeViewMatrix() const; virtual Matrix4 getInverseTransposeViewMatrix() const; - virtual Matrix4 getTransposeProjectionMatrix() const; - virtual Matrix4 getInverseProjectionMatrix() const; - virtual Matrix4 getInverseTransposeProjectionMatrix() const; - virtual Matrix4 getTransposeWorldViewProjMatrix() const; - virtual Matrix4 getInverseWorldViewProjMatrix() const; - virtual Matrix4 getInverseTransposeWorldViewProjMatrix() const; - virtual Matrix4 getTransposeWorldViewMatrix() const; - virtual Matrix4 getTransposeWorldMatrix() const; + virtual Matrix4 getTransposeProjectionMatrix() const; + virtual Matrix4 getInverseProjectionMatrix() const; + virtual Matrix4 getInverseTransposeProjectionMatrix() const; + virtual Matrix4 getTransposeWorldViewProjMatrix() const; + virtual Matrix4 getInverseWorldViewProjMatrix() const; + virtual Matrix4 getInverseTransposeWorldViewProjMatrix() const; + virtual Matrix4 getTransposeWorldViewMatrix() const; + virtual Matrix4 getTransposeWorldMatrix() const; virtual Real getTime(void) const; - virtual Real getTime_0_X(Real x) const; - virtual Real getCosTime_0_X(Real x) const; - virtual Real getSinTime_0_X(Real x) const; - virtual Real getTanTime_0_X(Real x) const; - virtual Vector4 getTime_0_X_packed(Real x) const; - virtual Real getTime_0_1(Real x) const; - virtual Real getCosTime_0_1(Real x) const; - virtual Real getSinTime_0_1(Real x) const; - virtual Real getTanTime_0_1(Real x) const; - virtual Vector4 getTime_0_1_packed(Real x) const; - virtual Real getTime_0_2Pi(Real x) const; - virtual Real getCosTime_0_2Pi(Real x) const; - virtual Real getSinTime_0_2Pi(Real x) const; - virtual Real getTanTime_0_2Pi(Real x) const; - virtual Vector4 getTime_0_2Pi_packed(Real x) const; + virtual Real getTime_0_X(Real x) const; + virtual Real getCosTime_0_X(Real x) const; + virtual Real getSinTime_0_X(Real x) const; + virtual Real getTanTime_0_X(Real x) const; + virtual Vector4 getTime_0_X_packed(Real x) const; + virtual Real getTime_0_1(Real x) const; + virtual Real getCosTime_0_1(Real x) const; + virtual Real getSinTime_0_1(Real x) const; + virtual Real getTanTime_0_1(Real x) const; + virtual Vector4 getTime_0_1_packed(Real x) const; + virtual Real getTime_0_2Pi(Real x) const; + virtual Real getCosTime_0_2Pi(Real x) const; + virtual Real getSinTime_0_2Pi(Real x) const; + virtual Real getTanTime_0_2Pi(Real x) const; + virtual Vector4 getTime_0_2Pi_packed(Real x) const; virtual Real getFrameTime(void) const; - virtual Real getFPS() const; - virtual Real getViewportWidth() const; - virtual Real getViewportHeight() const; - virtual Real getInverseViewportWidth() const; - virtual Real getInverseViewportHeight() const; - virtual Vector3 getViewDirection() const; - virtual Vector3 getViewSideVector() const; - virtual Vector3 getViewUpVector() const; - virtual Real getFOV() const; - virtual Real getNearClipDistance() const; - virtual Real getFarClipDistance() const; + virtual Real getFPS() const; + virtual Real getViewportWidth() const; + virtual Real getViewportHeight() const; + virtual Real getInverseViewportWidth() const; + virtual Real getInverseViewportHeight() const; + virtual Vector3 getViewDirection() const; + virtual Vector3 getViewSideVector() const; + virtual Vector3 getViewUpVector() const; + virtual Real getFOV() const; + virtual Real getNearClipDistance() const; + virtual Real getFarClipDistance() const; virtual int getPassNumber(void) const; virtual void setPassNumber(const int passNumber); virtual void incPassNumber(void); - virtual void updateLightCustomGpuParameter(const GpuProgramParameters::AutoConstantEntry& constantEntry, GpuProgramParameters *params) const; + virtual void updateLightCustomGpuParameter(const GpuProgramParameters::AutoConstantEntry& constantEntry, GpuProgramParameters *params) const; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreAxisAlignedBox.h b/OgreMain/include/OgreAxisAlignedBox.h index b7a5462c717..9fe46faf23b 100644 --- a/OgreMain/include/OgreAxisAlignedBox.h +++ b/OgreMain/include/OgreAxisAlignedBox.h @@ -34,40 +34,40 @@ THE SOFTWARE. #include "OgreMatrix4.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - - /** A 3D box aligned with the x/y/z axes. - @remarks - This class represents a simple box which is aligned with the - axes. Internally it only stores 2 points as the extremeties of - the box, one which is the minima of all 3 axes, and the other - which is the maxima of all 3 axes. This class is typically used - for an axis-aligned bounding box (AABB) for collision and - visibility determination. - */ - class _OgreExport AxisAlignedBox - { - public: - enum Extent - { - EXTENT_NULL, - EXTENT_FINITE, - EXTENT_INFINITE - }; - protected: - - Vector3 mMinimum; - Vector3 mMaximum; - Extent mExtent; - mutable Vector3* mCorners; - - public: - /* + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + + /** A 3D box aligned with the x/y/z axes. + @remarks + This class represents a simple box which is aligned with the + axes. Internally it only stores 2 points as the extremeties of + the box, one which is the minima of all 3 axes, and the other + which is the maxima of all 3 axes. This class is typically used + for an axis-aligned bounding box (AABB) for collision and + visibility determination. + */ + class _OgreExport AxisAlignedBox + { + public: + enum Extent + { + EXTENT_NULL, + EXTENT_FINITE, + EXTENT_INFINITE + }; + protected: + + Vector3 mMinimum; + Vector3 mMaximum; + Extent mExtent; + mutable Vector3* mCorners; + + public: + /* 1-------2 /| /| / | / | @@ -76,217 +76,217 @@ namespace Ogre { | / | / |/ |/ 6-------7 - */ - typedef enum { - FAR_LEFT_BOTTOM = 0, - FAR_LEFT_TOP = 1, - FAR_RIGHT_TOP = 2, - FAR_RIGHT_BOTTOM = 3, - NEAR_RIGHT_BOTTOM = 7, - NEAR_LEFT_BOTTOM = 6, - NEAR_LEFT_TOP = 5, - NEAR_RIGHT_TOP = 4 - } CornerEnum; - inline AxisAlignedBox() : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0) - { - // Default to a null box - setMinimum( -0.5, -0.5, -0.5 ); - setMaximum( 0.5, 0.5, 0.5 ); - mExtent = EXTENT_NULL; - } - inline AxisAlignedBox(Extent e) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0) - { - setMinimum( -0.5, -0.5, -0.5 ); - setMaximum( 0.5, 0.5, 0.5 ); - mExtent = e; - } - - inline AxisAlignedBox(const AxisAlignedBox & rkBox) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0) - - { - if (rkBox.isNull()) - setNull(); - else if (rkBox.isInfinite()) - setInfinite(); - else - setExtents( rkBox.mMinimum, rkBox.mMaximum ); - } - - inline AxisAlignedBox( const Vector3& min, const Vector3& max ) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0) - { - setExtents( min, max ); - } - - inline AxisAlignedBox( - Real mx, Real my, Real mz, - Real Mx, Real My, Real Mz ) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0) - { - setExtents( mx, my, mz, Mx, My, Mz ); - } - - AxisAlignedBox& operator=(const AxisAlignedBox& rhs) - { - // Specifically override to avoid copying mCorners - if (rhs.isNull()) - setNull(); - else if (rhs.isInfinite()) - setInfinite(); - else - setExtents(rhs.mMinimum, rhs.mMaximum); - - return *this; - } - - ~AxisAlignedBox() - { - if (mCorners) - OGRE_FREE(mCorners, MEMCATEGORY_SCENE_CONTROL); - } - - - /** Gets the minimum corner of the box. - */ - inline const Vector3& getMinimum(void) const - { - return mMinimum; - } - - /** Gets a modifiable version of the minimum - corner of the box. - */ - inline Vector3& getMinimum(void) - { - return mMinimum; - } - - /** Gets the maximum corner of the box. - */ - inline const Vector3& getMaximum(void) const - { - return mMaximum; - } - - /** Gets a modifiable version of the maximum - corner of the box. - */ - inline Vector3& getMaximum(void) - { - return mMaximum; - } - - - /** Sets the minimum corner of the box. - */ - inline void setMinimum( const Vector3& vec ) - { - mExtent = EXTENT_FINITE; - mMinimum = vec; - } - - inline void setMinimum( Real x, Real y, Real z ) - { - mExtent = EXTENT_FINITE; - mMinimum.x = x; - mMinimum.y = y; - mMinimum.z = z; - } - - /** Changes one of the components of the minimum corner of the box - used to resize only one dimension of the box - */ - inline void setMinimumX(Real x) - { - mMinimum.x = x; - } - - inline void setMinimumY(Real y) - { - mMinimum.y = y; - } - - inline void setMinimumZ(Real z) - { - mMinimum.z = z; - } - - /** Sets the maximum corner of the box. - */ - inline void setMaximum( const Vector3& vec ) - { - mExtent = EXTENT_FINITE; - mMaximum = vec; - } - - inline void setMaximum( Real x, Real y, Real z ) - { - mExtent = EXTENT_FINITE; - mMaximum.x = x; - mMaximum.y = y; - mMaximum.z = z; - } - - /** Changes one of the components of the maximum corner of the box - used to resize only one dimension of the box - */ - inline void setMaximumX( Real x ) - { - mMaximum.x = x; - } - - inline void setMaximumY( Real y ) - { - mMaximum.y = y; - } - - inline void setMaximumZ( Real z ) - { - mMaximum.z = z; - } - - /** Sets both minimum and maximum extents at once. - */ - inline void setExtents( const Vector3& min, const Vector3& max ) - { + */ + typedef enum { + FAR_LEFT_BOTTOM = 0, + FAR_LEFT_TOP = 1, + FAR_RIGHT_TOP = 2, + FAR_RIGHT_BOTTOM = 3, + NEAR_RIGHT_BOTTOM = 7, + NEAR_LEFT_BOTTOM = 6, + NEAR_LEFT_TOP = 5, + NEAR_RIGHT_TOP = 4 + } CornerEnum; + inline AxisAlignedBox() : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0) + { + // Default to a null box + setMinimum( -0.5, -0.5, -0.5 ); + setMaximum( 0.5, 0.5, 0.5 ); + mExtent = EXTENT_NULL; + } + inline AxisAlignedBox(Extent e) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0) + { + setMinimum( -0.5, -0.5, -0.5 ); + setMaximum( 0.5, 0.5, 0.5 ); + mExtent = e; + } + + inline AxisAlignedBox(const AxisAlignedBox & rkBox) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0) + + { + if (rkBox.isNull()) + setNull(); + else if (rkBox.isInfinite()) + setInfinite(); + else + setExtents( rkBox.mMinimum, rkBox.mMaximum ); + } + + inline AxisAlignedBox( const Vector3& min, const Vector3& max ) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0) + { + setExtents( min, max ); + } + + inline AxisAlignedBox( + Real mx, Real my, Real mz, + Real Mx, Real My, Real Mz ) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0) + { + setExtents( mx, my, mz, Mx, My, Mz ); + } + + AxisAlignedBox& operator=(const AxisAlignedBox& rhs) + { + // Specifically override to avoid copying mCorners + if (rhs.isNull()) + setNull(); + else if (rhs.isInfinite()) + setInfinite(); + else + setExtents(rhs.mMinimum, rhs.mMaximum); + + return *this; + } + + ~AxisAlignedBox() + { + if (mCorners) + OGRE_FREE(mCorners, MEMCATEGORY_SCENE_CONTROL); + } + + + /** Gets the minimum corner of the box. + */ + inline const Vector3& getMinimum(void) const + { + return mMinimum; + } + + /** Gets a modifiable version of the minimum + corner of the box. + */ + inline Vector3& getMinimum(void) + { + return mMinimum; + } + + /** Gets the maximum corner of the box. + */ + inline const Vector3& getMaximum(void) const + { + return mMaximum; + } + + /** Gets a modifiable version of the maximum + corner of the box. + */ + inline Vector3& getMaximum(void) + { + return mMaximum; + } + + + /** Sets the minimum corner of the box. + */ + inline void setMinimum( const Vector3& vec ) + { + mExtent = EXTENT_FINITE; + mMinimum = vec; + } + + inline void setMinimum( Real x, Real y, Real z ) + { + mExtent = EXTENT_FINITE; + mMinimum.x = x; + mMinimum.y = y; + mMinimum.z = z; + } + + /** Changes one of the components of the minimum corner of the box + used to resize only one dimension of the box + */ + inline void setMinimumX(Real x) + { + mMinimum.x = x; + } + + inline void setMinimumY(Real y) + { + mMinimum.y = y; + } + + inline void setMinimumZ(Real z) + { + mMinimum.z = z; + } + + /** Sets the maximum corner of the box. + */ + inline void setMaximum( const Vector3& vec ) + { + mExtent = EXTENT_FINITE; + mMaximum = vec; + } + + inline void setMaximum( Real x, Real y, Real z ) + { + mExtent = EXTENT_FINITE; + mMaximum.x = x; + mMaximum.y = y; + mMaximum.z = z; + } + + /** Changes one of the components of the maximum corner of the box + used to resize only one dimension of the box + */ + inline void setMaximumX( Real x ) + { + mMaximum.x = x; + } + + inline void setMaximumY( Real y ) + { + mMaximum.y = y; + } + + inline void setMaximumZ( Real z ) + { + mMaximum.z = z; + } + + /** Sets both minimum and maximum extents at once. + */ + inline void setExtents( const Vector3& min, const Vector3& max ) + { assert( (min.x <= max.x && min.y <= max.y && min.z <= max.z) && "The minimum corner of the box must be less than or equal to maximum corner" ); - mExtent = EXTENT_FINITE; - mMinimum = min; - mMaximum = max; - } + mExtent = EXTENT_FINITE; + mMinimum = min; + mMaximum = max; + } - inline void setExtents( - Real mx, Real my, Real mz, - Real Mx, Real My, Real Mz ) - { + inline void setExtents( + Real mx, Real my, Real mz, + Real Mx, Real My, Real Mz ) + { assert( (mx <= Mx && my <= My && mz <= Mz) && "The minimum corner of the box must be less than or equal to maximum corner" ); - mExtent = EXTENT_FINITE; - - mMinimum.x = mx; - mMinimum.y = my; - mMinimum.z = mz; - - mMaximum.x = Mx; - mMaximum.y = My; - mMaximum.z = Mz; - - } - - /** Returns a pointer to an array of 8 corner points, useful for - collision vs. non-aligned objects. - @remarks - If the order of these corners is important, they are as - follows: The 4 points of the minimum Z face (note that - because Ogre uses right-handed coordinates, the minimum Z is - at the 'back' of the box) starting with the minimum point of - all, then anticlockwise around this face (if you are looking - onto the face from outside the box). Then the 4 points of the - maximum Z face, starting with maximum point of all, then - anticlockwise around this face (looking onto the face from - outside the box). Like this: -
      +            mExtent = EXTENT_FINITE;
      +
      +            mMinimum.x = mx;
      +            mMinimum.y = my;
      +            mMinimum.z = mz;
      +
      +            mMaximum.x = Mx;
      +            mMaximum.y = My;
      +            mMaximum.z = Mz;
      +
      +        }
      +
      +        /** Returns a pointer to an array of 8 corner points, useful for
      +        collision vs. non-aligned objects.
      +        @remarks
      +        If the order of these corners is important, they are as
      +        follows: The 4 points of the minimum Z face (note that
      +        because Ogre uses right-handed coordinates, the minimum Z is
      +        at the 'back' of the box) starting with the minimum point of
      +        all, then anticlockwise around this face (if you are looking
      +        onto the face from outside the box). Then the 4 points of the
      +        maximum Z face, starting with maximum point of all, then
      +        anticlockwise around this face (looking onto the face from
      +        outside the box). Like this:
      +        
                  1-------2
                 /|      /|
                / |     / |
      @@ -295,317 +295,317 @@ namespace Ogre {
               | /     | /
               |/      |/
               6-------7
      -		
      - */ - inline const Vector3* getAllCorners(void) const - { - assert( (mExtent == EXTENT_FINITE) && "Can't get corners of a null or infinite AAB" ); - - // The order of these items is, using right-handed co-ordinates: - // Minimum Z face, starting with Min(all), then anticlockwise - // around face (looking onto the face) - // Maximum Z face, starting with Max(all), then anticlockwise - // around face (looking onto the face) - // Only for optimization/compatibility. - if (!mCorners) - mCorners = OGRE_ALLOC_T(Vector3, 8, MEMCATEGORY_SCENE_CONTROL); - - mCorners[0] = mMinimum; - mCorners[1].x = mMinimum.x; mCorners[1].y = mMaximum.y; mCorners[1].z = mMinimum.z; - mCorners[2].x = mMaximum.x; mCorners[2].y = mMaximum.y; mCorners[2].z = mMinimum.z; - mCorners[3].x = mMaximum.x; mCorners[3].y = mMinimum.y; mCorners[3].z = mMinimum.z; - - mCorners[4] = mMaximum; - mCorners[5].x = mMinimum.x; mCorners[5].y = mMaximum.y; mCorners[5].z = mMaximum.z; - mCorners[6].x = mMinimum.x; mCorners[6].y = mMinimum.y; mCorners[6].z = mMaximum.z; - mCorners[7].x = mMaximum.x; mCorners[7].y = mMinimum.y; mCorners[7].z = mMaximum.z; - - return mCorners; - } - - /** Gets the position of one of the corners - */ - Vector3 getCorner(CornerEnum cornerToGet) const - { - switch(cornerToGet) - { - case FAR_LEFT_BOTTOM: - return mMinimum; - case FAR_LEFT_TOP: - return Vector3(mMinimum.x, mMaximum.y, mMinimum.z); - case FAR_RIGHT_TOP: - return Vector3(mMaximum.x, mMaximum.y, mMinimum.z); - case FAR_RIGHT_BOTTOM: - return Vector3(mMaximum.x, mMinimum.y, mMinimum.z); - case NEAR_RIGHT_BOTTOM: - return Vector3(mMaximum.x, mMinimum.y, mMaximum.z); - case NEAR_LEFT_BOTTOM: - return Vector3(mMinimum.x, mMinimum.y, mMaximum.z); - case NEAR_LEFT_TOP: - return Vector3(mMinimum.x, mMaximum.y, mMaximum.z); - case NEAR_RIGHT_TOP: - return mMaximum; - default: - return Vector3(); - } - } - - _OgreExport friend std::ostream& operator<<( std::ostream& o, const AxisAlignedBox &aab ) - { - switch (aab.mExtent) - { - case EXTENT_NULL: - o << "AxisAlignedBox(null)"; - return o; - - case EXTENT_FINITE: - o << "AxisAlignedBox(min=" << aab.mMinimum << ", max=" << aab.mMaximum << ")"; - return o; - - case EXTENT_INFINITE: - o << "AxisAlignedBox(infinite)"; - return o; - - default: // shut up compiler - assert( false && "Never reached" ); - return o; - } - } - - /** Merges the passed in box into the current box. The result is the - box which encompasses both. - */ - void merge( const AxisAlignedBox& rhs ) - { - // Do nothing if rhs null, or this is infinite - if ((rhs.mExtent == EXTENT_NULL) || (mExtent == EXTENT_INFINITE)) - { - return; - } - // Otherwise if rhs is infinite, make this infinite, too - else if (rhs.mExtent == EXTENT_INFINITE) - { - mExtent = EXTENT_INFINITE; - } - // Otherwise if current null, just take rhs - else if (mExtent == EXTENT_NULL) - { - setExtents(rhs.mMinimum, rhs.mMaximum); - } - // Otherwise merge - else - { - Vector3 min = mMinimum; - Vector3 max = mMaximum; - max.makeCeil(rhs.mMaximum); - min.makeFloor(rhs.mMinimum); - - setExtents(min, max); - } - - } - - /** Extends the box to encompass the specified point (if needed). - */ - inline void merge( const Vector3& point ) - { - switch (mExtent) - { - case EXTENT_NULL: // if null, use this point - setExtents(point, point); - return; - - case EXTENT_FINITE: - mMaximum.makeCeil(point); - mMinimum.makeFloor(point); - return; - - case EXTENT_INFINITE: // if infinite, makes no difference - return; - } - - assert( false && "Never reached" ); - } - - /** Transforms the box according to the matrix supplied. - @remarks - By calling this method you get the axis-aligned box which - surrounds the transformed version of this box. Therefore each - corner of the box is transformed by the matrix, then the - extents are mapped back onto the axes to produce another - AABB. Useful when you have a local AABB for an object which - is then transformed. - */ - inline void transform( const Matrix4& matrix ) - { - // Do nothing if current null or infinite - if( mExtent != EXTENT_FINITE ) - return; - - Vector3 oldMin, oldMax, currentCorner; - - // Getting the old values so that we can use the existing merge method. - oldMin = mMinimum; - oldMax = mMaximum; - - // reset - setNull(); - - // We sequentially compute the corners in the following order : - // 0, 6, 5, 1, 2, 4 ,7 , 3 - // This sequence allows us to only change one member at a time to get at all corners. - - // For each one, we transform it using the matrix - // Which gives the resulting point and merge the resulting point. - - // First corner - // min min min - currentCorner = oldMin; - merge( matrix * currentCorner ); - - // min,min,max - currentCorner.z = oldMax.z; - merge( matrix * currentCorner ); - - // min max max - currentCorner.y = oldMax.y; - merge( matrix * currentCorner ); - - // min max min - currentCorner.z = oldMin.z; - merge( matrix * currentCorner ); - - // max max min - currentCorner.x = oldMax.x; - merge( matrix * currentCorner ); - - // max max max - currentCorner.z = oldMax.z; - merge( matrix * currentCorner ); - - // max min max - currentCorner.y = oldMin.y; - merge( matrix * currentCorner ); - - // max min min - currentCorner.z = oldMin.z; - merge( matrix * currentCorner ); - } - - /** Transforms the box according to the affine matrix supplied. - @remarks - By calling this method you get the axis-aligned box which - surrounds the transformed version of this box. Therefore each - corner of the box is transformed by the matrix, then the - extents are mapped back onto the axes to produce another - AABB. Useful when you have a local AABB for an object which - is then transformed. - @note - The matrix must be an affine matrix. @see Matrix4::isAffine. - */ - void transformAffine(const Matrix4& m) - { - assert(m.isAffine()); - - // Do nothing if current null or infinite - if ( mExtent != EXTENT_FINITE ) - return; - - Vector3 centre = getCenter(); - Vector3 halfSize = getHalfSize(); - - Vector3 newCentre = m.transformAffine(centre); - Vector3 newHalfSize( - Math::Abs(m[0][0]) * halfSize.x + Math::Abs(m[0][1]) * halfSize.y + Math::Abs(m[0][2]) * halfSize.z, - Math::Abs(m[1][0]) * halfSize.x + Math::Abs(m[1][1]) * halfSize.y + Math::Abs(m[1][2]) * halfSize.z, - Math::Abs(m[2][0]) * halfSize.x + Math::Abs(m[2][1]) * halfSize.y + Math::Abs(m[2][2]) * halfSize.z); - - setExtents(newCentre - newHalfSize, newCentre + newHalfSize); - } - - /** Sets the box to a 'null' value i.e. not a box. - */ - inline void setNull() - { - mExtent = EXTENT_NULL; - } - - /** Returns true if the box is null i.e. empty. - */ - inline bool isNull(void) const - { - return (mExtent == EXTENT_NULL); - } - - /** Returns true if the box is finite. - */ - bool isFinite(void) const - { - return (mExtent == EXTENT_FINITE); - } - - /** Sets the box to 'infinite' - */ - inline void setInfinite() - { - mExtent = EXTENT_INFINITE; - } - - /** Returns true if the box is infinite. - */ - bool isInfinite(void) const - { - return (mExtent == EXTENT_INFINITE); - } - - /** Returns whether or not this box intersects another. */ - inline bool intersects(const AxisAlignedBox& b2) const - { - // Early-fail for nulls - if (this->isNull() || b2.isNull()) - return false; - - // Early-success for infinites - if (this->isInfinite() || b2.isInfinite()) - return true; - - // Use up to 6 separating planes - if (mMaximum.x < b2.mMinimum.x) - return false; - if (mMaximum.y < b2.mMinimum.y) - return false; - if (mMaximum.z < b2.mMinimum.z) - return false; - - if (mMinimum.x > b2.mMaximum.x) - return false; - if (mMinimum.y > b2.mMaximum.y) - return false; - if (mMinimum.z > b2.mMaximum.z) - return false; - - // otherwise, must be intersecting - return true; - - } - - /// Calculate the area of intersection of this box and another - inline AxisAlignedBox intersection(const AxisAlignedBox& b2) const - { +
      + */ + inline const Vector3* getAllCorners(void) const + { + assert( (mExtent == EXTENT_FINITE) && "Can't get corners of a null or infinite AAB" ); + + // The order of these items is, using right-handed co-ordinates: + // Minimum Z face, starting with Min(all), then anticlockwise + // around face (looking onto the face) + // Maximum Z face, starting with Max(all), then anticlockwise + // around face (looking onto the face) + // Only for optimization/compatibility. + if (!mCorners) + mCorners = OGRE_ALLOC_T(Vector3, 8, MEMCATEGORY_SCENE_CONTROL); + + mCorners[0] = mMinimum; + mCorners[1].x = mMinimum.x; mCorners[1].y = mMaximum.y; mCorners[1].z = mMinimum.z; + mCorners[2].x = mMaximum.x; mCorners[2].y = mMaximum.y; mCorners[2].z = mMinimum.z; + mCorners[3].x = mMaximum.x; mCorners[3].y = mMinimum.y; mCorners[3].z = mMinimum.z; + + mCorners[4] = mMaximum; + mCorners[5].x = mMinimum.x; mCorners[5].y = mMaximum.y; mCorners[5].z = mMaximum.z; + mCorners[6].x = mMinimum.x; mCorners[6].y = mMinimum.y; mCorners[6].z = mMaximum.z; + mCorners[7].x = mMaximum.x; mCorners[7].y = mMinimum.y; mCorners[7].z = mMaximum.z; + + return mCorners; + } + + /** Gets the position of one of the corners + */ + Vector3 getCorner(CornerEnum cornerToGet) const + { + switch(cornerToGet) + { + case FAR_LEFT_BOTTOM: + return mMinimum; + case FAR_LEFT_TOP: + return Vector3(mMinimum.x, mMaximum.y, mMinimum.z); + case FAR_RIGHT_TOP: + return Vector3(mMaximum.x, mMaximum.y, mMinimum.z); + case FAR_RIGHT_BOTTOM: + return Vector3(mMaximum.x, mMinimum.y, mMinimum.z); + case NEAR_RIGHT_BOTTOM: + return Vector3(mMaximum.x, mMinimum.y, mMaximum.z); + case NEAR_LEFT_BOTTOM: + return Vector3(mMinimum.x, mMinimum.y, mMaximum.z); + case NEAR_LEFT_TOP: + return Vector3(mMinimum.x, mMaximum.y, mMaximum.z); + case NEAR_RIGHT_TOP: + return mMaximum; + default: + return Vector3(); + } + } + + _OgreExport friend std::ostream& operator<<( std::ostream& o, const AxisAlignedBox &aab ) + { + switch (aab.mExtent) + { + case EXTENT_NULL: + o << "AxisAlignedBox(null)"; + return o; + + case EXTENT_FINITE: + o << "AxisAlignedBox(min=" << aab.mMinimum << ", max=" << aab.mMaximum << ")"; + return o; + + case EXTENT_INFINITE: + o << "AxisAlignedBox(infinite)"; + return o; + + default: // shut up compiler + assert( false && "Never reached" ); + return o; + } + } + + /** Merges the passed in box into the current box. The result is the + box which encompasses both. + */ + void merge( const AxisAlignedBox& rhs ) + { + // Do nothing if rhs null, or this is infinite + if ((rhs.mExtent == EXTENT_NULL) || (mExtent == EXTENT_INFINITE)) + { + return; + } + // Otherwise if rhs is infinite, make this infinite, too + else if (rhs.mExtent == EXTENT_INFINITE) + { + mExtent = EXTENT_INFINITE; + } + // Otherwise if current null, just take rhs + else if (mExtent == EXTENT_NULL) + { + setExtents(rhs.mMinimum, rhs.mMaximum); + } + // Otherwise merge + else + { + Vector3 min = mMinimum; + Vector3 max = mMaximum; + max.makeCeil(rhs.mMaximum); + min.makeFloor(rhs.mMinimum); + + setExtents(min, max); + } + + } + + /** Extends the box to encompass the specified point (if needed). + */ + inline void merge( const Vector3& point ) + { + switch (mExtent) + { + case EXTENT_NULL: // if null, use this point + setExtents(point, point); + return; + + case EXTENT_FINITE: + mMaximum.makeCeil(point); + mMinimum.makeFloor(point); + return; + + case EXTENT_INFINITE: // if infinite, makes no difference + return; + } + + assert( false && "Never reached" ); + } + + /** Transforms the box according to the matrix supplied. + @remarks + By calling this method you get the axis-aligned box which + surrounds the transformed version of this box. Therefore each + corner of the box is transformed by the matrix, then the + extents are mapped back onto the axes to produce another + AABB. Useful when you have a local AABB for an object which + is then transformed. + */ + inline void transform( const Matrix4& matrix ) + { + // Do nothing if current null or infinite + if( mExtent != EXTENT_FINITE ) + return; + + Vector3 oldMin, oldMax, currentCorner; + + // Getting the old values so that we can use the existing merge method. + oldMin = mMinimum; + oldMax = mMaximum; + + // reset + setNull(); + + // We sequentially compute the corners in the following order : + // 0, 6, 5, 1, 2, 4 ,7 , 3 + // This sequence allows us to only change one member at a time to get at all corners. + + // For each one, we transform it using the matrix + // Which gives the resulting point and merge the resulting point. + + // First corner + // min min min + currentCorner = oldMin; + merge( matrix * currentCorner ); + + // min,min,max + currentCorner.z = oldMax.z; + merge( matrix * currentCorner ); + + // min max max + currentCorner.y = oldMax.y; + merge( matrix * currentCorner ); + + // min max min + currentCorner.z = oldMin.z; + merge( matrix * currentCorner ); + + // max max min + currentCorner.x = oldMax.x; + merge( matrix * currentCorner ); + + // max max max + currentCorner.z = oldMax.z; + merge( matrix * currentCorner ); + + // max min max + currentCorner.y = oldMin.y; + merge( matrix * currentCorner ); + + // max min min + currentCorner.z = oldMin.z; + merge( matrix * currentCorner ); + } + + /** Transforms the box according to the affine matrix supplied. + @remarks + By calling this method you get the axis-aligned box which + surrounds the transformed version of this box. Therefore each + corner of the box is transformed by the matrix, then the + extents are mapped back onto the axes to produce another + AABB. Useful when you have a local AABB for an object which + is then transformed. + @note + The matrix must be an affine matrix. @see Matrix4::isAffine. + */ + void transformAffine(const Matrix4& m) + { + assert(m.isAffine()); + + // Do nothing if current null or infinite + if ( mExtent != EXTENT_FINITE ) + return; + + Vector3 centre = getCenter(); + Vector3 halfSize = getHalfSize(); + + Vector3 newCentre = m.transformAffine(centre); + Vector3 newHalfSize( + Math::Abs(m[0][0]) * halfSize.x + Math::Abs(m[0][1]) * halfSize.y + Math::Abs(m[0][2]) * halfSize.z, + Math::Abs(m[1][0]) * halfSize.x + Math::Abs(m[1][1]) * halfSize.y + Math::Abs(m[1][2]) * halfSize.z, + Math::Abs(m[2][0]) * halfSize.x + Math::Abs(m[2][1]) * halfSize.y + Math::Abs(m[2][2]) * halfSize.z); + + setExtents(newCentre - newHalfSize, newCentre + newHalfSize); + } + + /** Sets the box to a 'null' value i.e. not a box. + */ + inline void setNull() + { + mExtent = EXTENT_NULL; + } + + /** Returns true if the box is null i.e. empty. + */ + inline bool isNull(void) const + { + return (mExtent == EXTENT_NULL); + } + + /** Returns true if the box is finite. + */ + bool isFinite(void) const + { + return (mExtent == EXTENT_FINITE); + } + + /** Sets the box to 'infinite' + */ + inline void setInfinite() + { + mExtent = EXTENT_INFINITE; + } + + /** Returns true if the box is infinite. + */ + bool isInfinite(void) const + { + return (mExtent == EXTENT_INFINITE); + } + + /** Returns whether or not this box intersects another. */ + inline bool intersects(const AxisAlignedBox& b2) const + { + // Early-fail for nulls if (this->isNull() || b2.isNull()) - { - return AxisAlignedBox(); - } - else if (this->isInfinite()) - { - return b2; - } - else if (b2.isInfinite()) - { - return *this; - } - - Vector3 intMin = mMinimum; + return false; + + // Early-success for infinites + if (this->isInfinite() || b2.isInfinite()) + return true; + + // Use up to 6 separating planes + if (mMaximum.x < b2.mMinimum.x) + return false; + if (mMaximum.y < b2.mMinimum.y) + return false; + if (mMaximum.z < b2.mMinimum.z) + return false; + + if (mMinimum.x > b2.mMaximum.x) + return false; + if (mMinimum.y > b2.mMaximum.y) + return false; + if (mMinimum.z > b2.mMaximum.z) + return false; + + // otherwise, must be intersecting + return true; + + } + + /// Calculate the area of intersection of this box and another + inline AxisAlignedBox intersection(const AxisAlignedBox& b2) const + { + if (this->isNull() || b2.isNull()) + { + return AxisAlignedBox(); + } + else if (this->isInfinite()) + { + return b2; + } + else if (b2.isInfinite()) + { + return *this; + } + + Vector3 intMin = mMinimum; Vector3 intMax = mMaximum; intMin.makeCeil(b2.getMinimum()); @@ -620,129 +620,129 @@ namespace Ogre { } return AxisAlignedBox(); - } - - /// Calculate the volume of this box - Real volume(void) const - { - switch (mExtent) - { - case EXTENT_NULL: - return 0.0f; - - case EXTENT_FINITE: - { - Vector3 diff = mMaximum - mMinimum; - return diff.x * diff.y * diff.z; - } - - case EXTENT_INFINITE: - return Math::POS_INFINITY; - - default: // shut up compiler - assert( false && "Never reached" ); - return 0.0f; - } - } - - /** Scales the AABB by the vector given. */ - inline void scale(const Vector3& s) - { - // Do nothing if current null or infinite - if (mExtent != EXTENT_FINITE) - return; - - // NB assumes centered on origin - Vector3 min = mMinimum * s; - Vector3 max = mMaximum * s; - setExtents(min, max); - } - - /** Tests whether this box intersects a sphere. */ - bool intersects(const Sphere& s) const - { - return Math::intersects(s, *this); - } - /** Tests whether this box intersects a plane. */ - bool intersects(const Plane& p) const - { - return Math::intersects(p, *this); - } - /** Tests whether the vector point is within this box. */ - bool intersects(const Vector3& v) const - { - switch (mExtent) - { - case EXTENT_NULL: - return false; - - case EXTENT_FINITE: - return(v.x >= mMinimum.x && v.x <= mMaximum.x && - v.y >= mMinimum.y && v.y <= mMaximum.y && - v.z >= mMinimum.z && v.z <= mMaximum.z); - - case EXTENT_INFINITE: - return true; - - default: // shut up compiler - assert( false && "Never reached" ); - return false; - } - } - /// Gets the centre of the box - Vector3 getCenter(void) const - { - assert( (mExtent == EXTENT_FINITE) && "Can't get center of a null or infinite AAB" ); - - return Vector3( - (mMaximum.x + mMinimum.x) * 0.5f, - (mMaximum.y + mMinimum.y) * 0.5f, - (mMaximum.z + mMinimum.z) * 0.5f); - } - /// Gets the size of the box - Vector3 getSize(void) const - { - switch (mExtent) - { - case EXTENT_NULL: - return Vector3::ZERO; - - case EXTENT_FINITE: - return mMaximum - mMinimum; - - case EXTENT_INFINITE: - return Vector3( - Math::POS_INFINITY, - Math::POS_INFINITY, - Math::POS_INFINITY); - - default: // shut up compiler - assert( false && "Never reached" ); - return Vector3::ZERO; - } - } - /// Gets the half-size of the box - Vector3 getHalfSize(void) const - { - switch (mExtent) - { - case EXTENT_NULL: - return Vector3::ZERO; - - case EXTENT_FINITE: - return (mMaximum - mMinimum) * 0.5; - - case EXTENT_INFINITE: - return Vector3( - Math::POS_INFINITY, - Math::POS_INFINITY, - Math::POS_INFINITY); - - default: // shut up compiler - assert( false && "Never reached" ); - return Vector3::ZERO; - } - } + } + + /// Calculate the volume of this box + Real volume(void) const + { + switch (mExtent) + { + case EXTENT_NULL: + return 0.0f; + + case EXTENT_FINITE: + { + Vector3 diff = mMaximum - mMinimum; + return diff.x * diff.y * diff.z; + } + + case EXTENT_INFINITE: + return Math::POS_INFINITY; + + default: // shut up compiler + assert( false && "Never reached" ); + return 0.0f; + } + } + + /** Scales the AABB by the vector given. */ + inline void scale(const Vector3& s) + { + // Do nothing if current null or infinite + if (mExtent != EXTENT_FINITE) + return; + + // NB assumes centered on origin + Vector3 min = mMinimum * s; + Vector3 max = mMaximum * s; + setExtents(min, max); + } + + /** Tests whether this box intersects a sphere. */ + bool intersects(const Sphere& s) const + { + return Math::intersects(s, *this); + } + /** Tests whether this box intersects a plane. */ + bool intersects(const Plane& p) const + { + return Math::intersects(p, *this); + } + /** Tests whether the vector point is within this box. */ + bool intersects(const Vector3& v) const + { + switch (mExtent) + { + case EXTENT_NULL: + return false; + + case EXTENT_FINITE: + return(v.x >= mMinimum.x && v.x <= mMaximum.x && + v.y >= mMinimum.y && v.y <= mMaximum.y && + v.z >= mMinimum.z && v.z <= mMaximum.z); + + case EXTENT_INFINITE: + return true; + + default: // shut up compiler + assert( false && "Never reached" ); + return false; + } + } + /// Gets the centre of the box + Vector3 getCenter(void) const + { + assert( (mExtent == EXTENT_FINITE) && "Can't get center of a null or infinite AAB" ); + + return Vector3( + (mMaximum.x + mMinimum.x) * 0.5f, + (mMaximum.y + mMinimum.y) * 0.5f, + (mMaximum.z + mMinimum.z) * 0.5f); + } + /// Gets the size of the box + Vector3 getSize(void) const + { + switch (mExtent) + { + case EXTENT_NULL: + return Vector3::ZERO; + + case EXTENT_FINITE: + return mMaximum - mMinimum; + + case EXTENT_INFINITE: + return Vector3( + Math::POS_INFINITY, + Math::POS_INFINITY, + Math::POS_INFINITY); + + default: // shut up compiler + assert( false && "Never reached" ); + return Vector3::ZERO; + } + } + /// Gets the half-size of the box + Vector3 getHalfSize(void) const + { + switch (mExtent) + { + case EXTENT_NULL: + return Vector3::ZERO; + + case EXTENT_FINITE: + return (mMaximum - mMinimum) * 0.5; + + case EXTENT_INFINITE: + return Vector3( + Math::POS_INFINITY, + Math::POS_INFINITY, + Math::POS_INFINITY); + + default: // shut up compiler + assert( false && "Never reached" ); + return Vector3::ZERO; + } + } /** Tests whether the given point contained by this box. */ @@ -757,42 +757,42 @@ namespace Ogre { mMinimum.y <= v.y && v.y <= mMaximum.y && mMinimum.z <= v.z && v.z <= mMaximum.z; } - - /** Returns the squared minimum distance between a given point and any part of the box. - * This is faster than distance since avoiding a squareroot, so use if you can. */ + + /** Returns the squared minimum distance between a given point and any part of the box. + * This is faster than distance since avoiding a squareroot, so use if you can. */ Real squaredDistance(const Vector3& v) const { - if (this->contains(v)) - return 0; - else - { - Vector3 maxDist(0,0,0); + if (this->contains(v)) + return 0; + else + { + Vector3 maxDist(0,0,0); - if (v.x < mMinimum.x) - maxDist.x = mMinimum.x - v.x; - else if (v.x > mMaximum.x) - maxDist.x = v.x - mMaximum.x; + if (v.x < mMinimum.x) + maxDist.x = mMinimum.x - v.x; + else if (v.x > mMaximum.x) + maxDist.x = v.x - mMaximum.x; - if (v.y < mMinimum.y) - maxDist.y = mMinimum.y - v.y; - else if (v.y > mMaximum.y) - maxDist.y = v.y - mMaximum.y; + if (v.y < mMinimum.y) + maxDist.y = mMinimum.y - v.y; + else if (v.y > mMaximum.y) + maxDist.y = v.y - mMaximum.y; - if (v.z < mMinimum.z) - maxDist.z = mMinimum.z - v.z; - else if (v.z > mMaximum.z) - maxDist.z = v.z - mMaximum.z; + if (v.z < mMinimum.z) + maxDist.z = mMinimum.z - v.z; + else if (v.z > mMaximum.z) + maxDist.z = v.z - mMaximum.z; - return maxDist.squaredLength(); - } + return maxDist.squaredLength(); + } } /** Returns the minimum distance between a given point and any part of the box. */ Real distance (const Vector3& v) const { - return Ogre::Math::Sqrt(squaredDistance(v)); - } + return Ogre::Math::Sqrt(squaredDistance(v)); + } /** Tests whether another box contained by this box. */ @@ -833,15 +833,15 @@ namespace Ogre { return !(*this == rhs); } - // special values - static const AxisAlignedBox BOX_NULL; - static const AxisAlignedBox BOX_INFINITE; + // special values + static const AxisAlignedBox BOX_NULL; + static const AxisAlignedBox BOX_INFINITE; - }; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace Ogre #endif diff --git a/OgreMain/include/OgreBillboard.h b/OgreMain/include/OgreBillboard.h index a8549c5e090..15e3f3d30f1 100644 --- a/OgreMain/include/OgreBillboard.h +++ b/OgreMain/include/OgreBillboard.h @@ -36,12 +36,12 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ /** A billboard is a primitive which always faces the camera in every frame. @remarks @@ -63,7 +63,7 @@ namespace Ogre { BillboardSet */ - class _OgreExport Billboard : public FXAlloc + class _OgreExport Billboard : public FXAlloc { friend class BillboardSet; friend class BillboardParticleRenderer; @@ -217,8 +217,8 @@ namespace Ogre { const FloatRect& getTexcoordRect(void) const { return mTexcoordRect; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreBillboardChain.h b/OgreMain/include/OgreBillboardChain.h index b98bfb1df63..354054962ce 100644 --- a/OgreMain/include/OgreBillboardChain.h +++ b/OgreMain/include/OgreBillboardChain.h @@ -41,345 +41,345 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - - /** Allows the rendering of a chain of connected billboards. - @remarks - A billboard chain operates much like a traditional billboard, i.e. its - segments always face the camera; the difference being that instead of - a set of disconnected quads, the elements in this class are connected - together in a chain which must always stay in a continuous strip. This - kind of effect is useful for creating effects such as trails, beams, - lightning effects, etc. - @par - A single instance of this class can actually render multiple separate - chain segments in a single render operation, provided they all use the - same material. To clarify the terminology: a 'segment' is a separate - sub-part of the chain with its own start and end (called the 'head' - and the 'tail'). An 'element' is a single position / colour / texcoord - entry in a segment. You can add items to the head of a chain, and - remove them from the tail, very efficiently. Each segment has a max - size, and if adding an element to the segment would exceed this size, - the tail element is automatically removed and re-used as the new item - on the head. - @par - This class has no auto-updating features to do things like alter the - colour of the elements or to automatically add / remove elements over - time - you have to do all this yourself as a user of the class. - Subclasses can however be used to provide this kind of behaviour - automatically. @see RibbonTrail - */ - class _OgreExport BillboardChain : public MovableObject, public Renderable - { - - public: - - /** Contains the data of an element of the BillboardChain. - */ - class _OgreExport Element - { - - public: - - Element(); - - Element(const Vector3 &position, - Real width, - Real texCoord, - const ColourValue &colour, - const Quaternion &orientation); - - Vector3 position; - Real width; - /// U or V texture coord depending on options - Real texCoord; - ColourValue colour; - - /// Only used when mFaceCamera == false - Quaternion orientation; - }; - typedef vector::type ElementList; - - /** Constructor (don't use directly, use factory) - @param name The name to give this object - @param maxElements The maximum number of elements per chain - @param numberOfChains The number of separate chain segments contained in this object - @param useTextureCoords If true, use texture coordinates from the chain elements - @param useColours If true, use vertex colours from the chain elements - @param dynamic If true, buffers are created with the intention of being updated - */ - BillboardChain(const String& name, size_t maxElements = 20, size_t numberOfChains = 1, - bool useTextureCoords = true, bool useColours = true, bool dynamic = true); - /// Destructor - virtual ~BillboardChain(); - - /** Set the maximum number of chain elements per chain - */ - virtual void setMaxChainElements(size_t maxElements); - /** Get the maximum number of chain elements per chain - */ - virtual size_t getMaxChainElements(void) const { return mMaxElementsPerChain; } - /** Set the number of chain segments (this class can render multiple chains - at once using the same material). - */ - virtual void setNumberOfChains(size_t numChains); - /** Get the number of chain segments (this class can render multiple chains - at once using the same material). - */ - virtual size_t getNumberOfChains(void) const { return mChainCount; } - - /** Sets whether texture coordinate information should be included in the - final buffers generated. - @note You must use either texture coordinates or vertex colour since the - vertices have no normals and without one of these there is no source of - colour for the vertices. - */ - virtual void setUseTextureCoords(bool use); - /** Gets whether texture coordinate information should be included in the - final buffers generated. - */ - virtual bool getUseTextureCoords(void) const { return mUseTexCoords; } - - /** The direction in which texture coordinates from elements of the - chain are used. - */ - enum TexCoordDirection - { - /// Tex coord in elements is treated as the 'u' texture coordinate - TCD_U, - /// Tex coord in elements is treated as the 'v' texture coordinate - TCD_V - }; - /** Sets the direction in which texture coords specified on each element - are deemed to run along the length of the chain. - @param dir The direction, default is TCD_U. - */ - virtual void setTextureCoordDirection(TexCoordDirection dir); - /** Gets the direction in which texture coords specified on each element - are deemed to run. - */ - virtual TexCoordDirection getTextureCoordDirection(void) { return mTexCoordDir; } - - /** Set the range of the texture coordinates generated across the width of - the chain elements. - @param start Start coordinate, default 0.0 - @param end End coordinate, default 1.0 - */ - virtual void setOtherTextureCoordRange(Real start, Real end); - /** Get the range of the texture coordinates generated across the width of - the chain elements. - */ - virtual const Real* getOtherTextureCoordRange(void) const { return mOtherTexCoordRange; } - - /** Sets whether vertex colour information should be included in the - final buffers generated. - @note You must use either texture coordinates or vertex colour since the - vertices have no normals and without one of these there is no source of - colour for the vertices. - */ - virtual void setUseVertexColours(bool use); - /** Gets whether vertex colour information should be included in the - final buffers generated. - */ - virtual bool getUseVertexColours(void) const { return mUseVertexColour; } - - /** Sets whether or not the buffers created for this object are suitable - for dynamic alteration. - */ - virtual void setDynamic(bool dyn); - - /** Gets whether or not the buffers created for this object are suitable - for dynamic alteration. - */ - virtual bool getDynamic(void) const { return mDynamic; } - - /** Add an element to the 'head' of a chain. - @remarks - If this causes the number of elements to exceed the maximum elements - per chain, the last element in the chain (the 'tail') will be removed - to allow the additional element to be added. - @param chainIndex The index of the chain - @param billboardChainElement The details to add - */ - virtual void addChainElement(size_t chainIndex, - const Element& billboardChainElement); - /** Remove an element from the 'tail' of a chain. - @param chainIndex The index of the chain - */ - virtual void removeChainElement(size_t chainIndex); - /** Update the details of an existing chain element. - @param chainIndex The index of the chain - @param elementIndex The element index within the chain, measured from - the 'head' of the chain - @param billboardChainElement The details to set - */ - virtual void updateChainElement(size_t chainIndex, size_t elementIndex, - const Element& billboardChainElement); - /** Get the detail of a chain element. - @param chainIndex The index of the chain - @param elementIndex The element index within the chain, measured from - the 'head' of the chain - */ - virtual const Element& getChainElement(size_t chainIndex, size_t elementIndex) const; - - /** Returns the number of chain elements. */ - virtual size_t getNumChainElements(size_t chainIndex) const; - - /** Remove all elements of a given chain (but leave the chain intact). */ - virtual void clearChain(size_t chainIndex); - /** Remove all elements from all chains (but leave the chains themselves intact). */ - virtual void clearAllChains(void); - - /** Sets whether the billboard should always be facing the camera or a custom direction - set by each point element. - @remarks - Billboards facing the camera are useful for smoke trails, light beams, etc by - simulating a cylinder. However, because of this property, wide trails can cause - several artefacts unless the head is properly covered. - Therefore, non-camera-facing billboards are much more convenient for leaving big - trails of movement from thin objects, for example a sword swing as seen in many - fighting games. - @param faceCamera True to be always facing the camera (Default value: True) - @param normalVector Only used when faceCamera == false. Must be a non-zero vector. - This vector is the "point of reference" for each point orientation. For example, - if normalVector is Vector3::UNIT_Z, and the point's orientation is an identity - matrix, the segment corresponding to that point will be facing towards UNIT_Z - This vector is internally normalized. - */ - void setFaceCamera( bool faceCamera, const Vector3 &normalVector=Vector3::UNIT_X ); - - /// Get the material name in use - virtual const String& getMaterialName(void) const { return mMaterialName; } - /// Set the material name to use for rendering - virtual void setMaterialName( const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME ); - - - // Overridden members follow - Real getSquaredViewDepth(const Camera* cam) const; - Real getBoundingRadius(void) const; - const AxisAlignedBox& getBoundingBox(void) const; - const MaterialPtr& getMaterial(void) const; - const String& getMovableType(void) const; - void _updateRenderQueue(RenderQueue *); - void getRenderOperation(RenderOperation &); - virtual bool preRender(SceneManager* sm, RenderSystem* rsys); - void getWorldTransforms(Matrix4 *) const; - const LightList& getLights(void) const; - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false); - - - - protected: - - /// Maximum length of each chain - size_t mMaxElementsPerChain; - /// Number of chains - size_t mChainCount; - /// Use texture coords? - bool mUseTexCoords; - /// Use vertex colour? - bool mUseVertexColour; - /// Dynamic use? - bool mDynamic; - /// Vertex data - VertexData* mVertexData; - /// Index data (to allow multiple unconnected chains) - IndexData* mIndexData; - /// Is the vertex declaration dirty? - bool mVertexDeclDirty; - /// Do the buffers need recreating? - bool mBuffersNeedRecreating; - /// Do the bounds need redefining? - mutable bool mBoundsDirty; - /// Is the index buffer dirty? - bool mIndexContentDirty; + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + + /** Allows the rendering of a chain of connected billboards. + @remarks + A billboard chain operates much like a traditional billboard, i.e. its + segments always face the camera; the difference being that instead of + a set of disconnected quads, the elements in this class are connected + together in a chain which must always stay in a continuous strip. This + kind of effect is useful for creating effects such as trails, beams, + lightning effects, etc. + @par + A single instance of this class can actually render multiple separate + chain segments in a single render operation, provided they all use the + same material. To clarify the terminology: a 'segment' is a separate + sub-part of the chain with its own start and end (called the 'head' + and the 'tail'). An 'element' is a single position / colour / texcoord + entry in a segment. You can add items to the head of a chain, and + remove them from the tail, very efficiently. Each segment has a max + size, and if adding an element to the segment would exceed this size, + the tail element is automatically removed and re-used as the new item + on the head. + @par + This class has no auto-updating features to do things like alter the + colour of the elements or to automatically add / remove elements over + time - you have to do all this yourself as a user of the class. + Subclasses can however be used to provide this kind of behaviour + automatically. @see RibbonTrail + */ + class _OgreExport BillboardChain : public MovableObject, public Renderable + { + + public: + + /** Contains the data of an element of the BillboardChain. + */ + class _OgreExport Element + { + + public: + + Element(); + + Element(const Vector3 &position, + Real width, + Real texCoord, + const ColourValue &colour, + const Quaternion &orientation); + + Vector3 position; + Real width; + /// U or V texture coord depending on options + Real texCoord; + ColourValue colour; + + /// Only used when mFaceCamera == false + Quaternion orientation; + }; + typedef vector::type ElementList; + + /** Constructor (don't use directly, use factory) + @param name The name to give this object + @param maxElements The maximum number of elements per chain + @param numberOfChains The number of separate chain segments contained in this object + @param useTextureCoords If true, use texture coordinates from the chain elements + @param useColours If true, use vertex colours from the chain elements + @param dynamic If true, buffers are created with the intention of being updated + */ + BillboardChain(const String& name, size_t maxElements = 20, size_t numberOfChains = 1, + bool useTextureCoords = true, bool useColours = true, bool dynamic = true); + /// Destructor + virtual ~BillboardChain(); + + /** Set the maximum number of chain elements per chain + */ + virtual void setMaxChainElements(size_t maxElements); + /** Get the maximum number of chain elements per chain + */ + virtual size_t getMaxChainElements(void) const { return mMaxElementsPerChain; } + /** Set the number of chain segments (this class can render multiple chains + at once using the same material). + */ + virtual void setNumberOfChains(size_t numChains); + /** Get the number of chain segments (this class can render multiple chains + at once using the same material). + */ + virtual size_t getNumberOfChains(void) const { return mChainCount; } + + /** Sets whether texture coordinate information should be included in the + final buffers generated. + @note You must use either texture coordinates or vertex colour since the + vertices have no normals and without one of these there is no source of + colour for the vertices. + */ + virtual void setUseTextureCoords(bool use); + /** Gets whether texture coordinate information should be included in the + final buffers generated. + */ + virtual bool getUseTextureCoords(void) const { return mUseTexCoords; } + + /** The direction in which texture coordinates from elements of the + chain are used. + */ + enum TexCoordDirection + { + /// Tex coord in elements is treated as the 'u' texture coordinate + TCD_U, + /// Tex coord in elements is treated as the 'v' texture coordinate + TCD_V + }; + /** Sets the direction in which texture coords specified on each element + are deemed to run along the length of the chain. + @param dir The direction, default is TCD_U. + */ + virtual void setTextureCoordDirection(TexCoordDirection dir); + /** Gets the direction in which texture coords specified on each element + are deemed to run. + */ + virtual TexCoordDirection getTextureCoordDirection(void) { return mTexCoordDir; } + + /** Set the range of the texture coordinates generated across the width of + the chain elements. + @param start Start coordinate, default 0.0 + @param end End coordinate, default 1.0 + */ + virtual void setOtherTextureCoordRange(Real start, Real end); + /** Get the range of the texture coordinates generated across the width of + the chain elements. + */ + virtual const Real* getOtherTextureCoordRange(void) const { return mOtherTexCoordRange; } + + /** Sets whether vertex colour information should be included in the + final buffers generated. + @note You must use either texture coordinates or vertex colour since the + vertices have no normals and without one of these there is no source of + colour for the vertices. + */ + virtual void setUseVertexColours(bool use); + /** Gets whether vertex colour information should be included in the + final buffers generated. + */ + virtual bool getUseVertexColours(void) const { return mUseVertexColour; } + + /** Sets whether or not the buffers created for this object are suitable + for dynamic alteration. + */ + virtual void setDynamic(bool dyn); + + /** Gets whether or not the buffers created for this object are suitable + for dynamic alteration. + */ + virtual bool getDynamic(void) const { return mDynamic; } + + /** Add an element to the 'head' of a chain. + @remarks + If this causes the number of elements to exceed the maximum elements + per chain, the last element in the chain (the 'tail') will be removed + to allow the additional element to be added. + @param chainIndex The index of the chain + @param billboardChainElement The details to add + */ + virtual void addChainElement(size_t chainIndex, + const Element& billboardChainElement); + /** Remove an element from the 'tail' of a chain. + @param chainIndex The index of the chain + */ + virtual void removeChainElement(size_t chainIndex); + /** Update the details of an existing chain element. + @param chainIndex The index of the chain + @param elementIndex The element index within the chain, measured from + the 'head' of the chain + @param billboardChainElement The details to set + */ + virtual void updateChainElement(size_t chainIndex, size_t elementIndex, + const Element& billboardChainElement); + /** Get the detail of a chain element. + @param chainIndex The index of the chain + @param elementIndex The element index within the chain, measured from + the 'head' of the chain + */ + virtual const Element& getChainElement(size_t chainIndex, size_t elementIndex) const; + + /** Returns the number of chain elements. */ + virtual size_t getNumChainElements(size_t chainIndex) const; + + /** Remove all elements of a given chain (but leave the chain intact). */ + virtual void clearChain(size_t chainIndex); + /** Remove all elements from all chains (but leave the chains themselves intact). */ + virtual void clearAllChains(void); + + /** Sets whether the billboard should always be facing the camera or a custom direction + set by each point element. + @remarks + Billboards facing the camera are useful for smoke trails, light beams, etc by + simulating a cylinder. However, because of this property, wide trails can cause + several artefacts unless the head is properly covered. + Therefore, non-camera-facing billboards are much more convenient for leaving big + trails of movement from thin objects, for example a sword swing as seen in many + fighting games. + @param faceCamera True to be always facing the camera (Default value: True) + @param normalVector Only used when faceCamera == false. Must be a non-zero vector. + This vector is the "point of reference" for each point orientation. For example, + if normalVector is Vector3::UNIT_Z, and the point's orientation is an identity + matrix, the segment corresponding to that point will be facing towards UNIT_Z + This vector is internally normalized. + */ + void setFaceCamera( bool faceCamera, const Vector3 &normalVector=Vector3::UNIT_X ); + + /// Get the material name in use + virtual const String& getMaterialName(void) const { return mMaterialName; } + /// Set the material name to use for rendering + virtual void setMaterialName( const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME ); + + + // Overridden members follow + Real getSquaredViewDepth(const Camera* cam) const; + Real getBoundingRadius(void) const; + const AxisAlignedBox& getBoundingBox(void) const; + const MaterialPtr& getMaterial(void) const; + const String& getMovableType(void) const; + void _updateRenderQueue(RenderQueue *); + void getRenderOperation(RenderOperation &); + virtual bool preRender(SceneManager* sm, RenderSystem* rsys); + void getWorldTransforms(Matrix4 *) const; + const LightList& getLights(void) const; + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false); + + + + protected: + + /// Maximum length of each chain + size_t mMaxElementsPerChain; + /// Number of chains + size_t mChainCount; + /// Use texture coords? + bool mUseTexCoords; + /// Use vertex colour? + bool mUseVertexColour; + /// Dynamic use? + bool mDynamic; + /// Vertex data + VertexData* mVertexData; + /// Index data (to allow multiple unconnected chains) + IndexData* mIndexData; + /// Is the vertex declaration dirty? + bool mVertexDeclDirty; + /// Do the buffers need recreating? + bool mBuffersNeedRecreating; + /// Do the bounds need redefining? + mutable bool mBoundsDirty; + /// Is the index buffer dirty? + bool mIndexContentDirty; /// Is the vertex buffer dirty? bool mVertexContentDirty; - /// AABB - mutable AxisAlignedBox mAABB; - /// Bounding radius - mutable Real mRadius; - /// Material - String mMaterialName; - MaterialPtr mMaterial; - /// Texture coord direction - TexCoordDirection mTexCoordDir; - /// Other texture coord range - Real mOtherTexCoordRange[2]; + /// AABB + mutable AxisAlignedBox mAABB; + /// Bounding radius + mutable Real mRadius; + /// Material + String mMaterialName; + MaterialPtr mMaterial; + /// Texture coord direction + TexCoordDirection mTexCoordDir; + /// Other texture coord range + Real mOtherTexCoordRange[2]; /// Camera last used to build the vertex buffer Camera *mVertexCameraUsed; - /// When true, the billboards always face the camera - bool mFaceCamera; - /// Used when mFaceCamera == false; determines the billboard's "normal". i.e. - /// when the orientation is identity, the billboard is perpendicular to this - /// vector - Vector3 mNormalBase; - - - /// The list holding the chain elements - ElementList mChainElementList; - - /** Simple struct defining a chain segment by referencing a subset of - the preallocated buffer (which will be mMaxElementsPerChain * mChainCount - long), by it's chain index, and a head and tail value which describe - the current chain. The buffer subset wraps at mMaxElementsPerChain - so that head and tail can move freely. head and tail are inclusive, - when the chain is empty head and tail are filled with high-values. - */ - struct ChainSegment - { - /// The start of this chains subset of the buffer - size_t start; - /// The 'head' of the chain, relative to start - size_t head; - /// The 'tail' of the chain, relative to start - size_t tail; - }; - typedef vector::type ChainSegmentList; - ChainSegmentList mChainSegmentList; - - /// Setup the STL collections - virtual void setupChainContainers(void); - /// Setup vertex declaration - virtual void setupVertexDeclaration(void); - /// Setup buffers - virtual void setupBuffers(void); - /// Update the contents of the vertex buffer - virtual void updateVertexBuffer(Camera* cam); - /// Update the contents of the index buffer - virtual void updateIndexBuffer(void); - virtual void updateBoundingBox(void) const; - - /// Chain segment has no elements - static const size_t SEGMENT_EMPTY; - }; - - - /** Factory object for creating BillboardChain instances */ - class _OgreExport BillboardChainFactory : public MovableObjectFactory - { - protected: - MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params); - public: - BillboardChainFactory() {} - ~BillboardChainFactory() {} - - static String FACTORY_TYPE_NAME; - - const String& getType(void) const; - void destroyInstance( MovableObject* obj); - - }; - - /** @} */ - /** @} */ + /// When true, the billboards always face the camera + bool mFaceCamera; + /// Used when mFaceCamera == false; determines the billboard's "normal". i.e. + /// when the orientation is identity, the billboard is perpendicular to this + /// vector + Vector3 mNormalBase; + + + /// The list holding the chain elements + ElementList mChainElementList; + + /** Simple struct defining a chain segment by referencing a subset of + the preallocated buffer (which will be mMaxElementsPerChain * mChainCount + long), by it's chain index, and a head and tail value which describe + the current chain. The buffer subset wraps at mMaxElementsPerChain + so that head and tail can move freely. head and tail are inclusive, + when the chain is empty head and tail are filled with high-values. + */ + struct ChainSegment + { + /// The start of this chains subset of the buffer + size_t start; + /// The 'head' of the chain, relative to start + size_t head; + /// The 'tail' of the chain, relative to start + size_t tail; + }; + typedef vector::type ChainSegmentList; + ChainSegmentList mChainSegmentList; + + /// Setup the STL collections + virtual void setupChainContainers(void); + /// Setup vertex declaration + virtual void setupVertexDeclaration(void); + /// Setup buffers + virtual void setupBuffers(void); + /// Update the contents of the vertex buffer + virtual void updateVertexBuffer(Camera* cam); + /// Update the contents of the index buffer + virtual void updateIndexBuffer(void); + virtual void updateBoundingBox(void) const; + + /// Chain segment has no elements + static const size_t SEGMENT_EMPTY; + }; + + + /** Factory object for creating BillboardChain instances */ + class _OgreExport BillboardChainFactory : public MovableObjectFactory + { + protected: + MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params); + public: + BillboardChainFactory() {} + ~BillboardChainFactory() {} + + static String FACTORY_TYPE_NAME; + + const String& getType(void) const; + void destroyInstance( MovableObject* obj); + + }; + + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreBillboardParticleRenderer.h b/OgreMain/include/OgreBillboardParticleRenderer.h index 5adb5f40fc3..40e7df9847c 100644 --- a/OgreMain/include/OgreBillboardParticleRenderer.h +++ b/OgreMain/include/OgreBillboardParticleRenderer.h @@ -220,12 +220,12 @@ namespace Ogre { void _notifyAttached(Node* parent, bool isTagPoint = false); /// @copydoc ParticleSystemRenderer::_notifyDefaultDimensions void _notifyDefaultDimensions(Real width, Real height); - /// @copydoc ParticleSystemRenderer::setRenderQueueGroup - void setRenderQueueGroup(uint8 queueID); - /// @copydoc MovableObject::setRenderQueueGroupAndPriority - void setRenderQueueGroupAndPriority(uint8 queueID, ushort priority); - /// @copydoc ParticleSystemRenderer::setKeepParticlesInLocalSpace - void setKeepParticlesInLocalSpace(bool keepLocal); + /// @copydoc ParticleSystemRenderer::setRenderQueueGroup + void setRenderQueueGroup(uint8 queueID); + /// @copydoc MovableObject::setRenderQueueGroupAndPriority + void setRenderQueueGroupAndPriority(uint8 queueID, ushort priority); + /// @copydoc ParticleSystemRenderer::setKeepParticlesInLocalSpace + void setKeepParticlesInLocalSpace(bool keepLocal); /// @copydoc ParticleSystemRenderer::_getSortMode SortMode _getSortMode(void) const; diff --git a/OgreMain/include/OgreBitwise.h b/OgreMain/include/OgreBitwise.h index 854f28a2aff..e3682637766 100644 --- a/OgreMain/include/OgreBitwise.h +++ b/OgreMain/include/OgreBitwise.h @@ -31,12 +31,12 @@ THE SOFTWARE. #include "OgrePrerequisites.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ /** Class for manipulating bit patterns. */ @@ -79,46 +79,46 @@ namespace Ogre { /** Returns the number of bits a pattern must be shifted right by to remove right-hand zeros. */ - template + template static FORCEINLINE unsigned int getBitShift(T mask) - { - if (mask == 0) - return 0; + { + if (mask == 0) + return 0; - unsigned int result = 0; - while ((mask & 1) == 0) { - ++result; - mask >>= 1; - } - return result; - } + unsigned int result = 0; + while ((mask & 1) == 0) { + ++result; + mask >>= 1; + } + return result; + } /** Takes a value with a given src bit mask, and produces another value with a desired bit mask. @remarks This routine is useful for colour conversion. */ - template + template static inline DestT convertBitPattern(SrcT srcValue, SrcT srcBitMask, DestT destBitMask) - { - // Mask off irrelevant source value bits (if any) - srcValue = srcValue & srcBitMask; + { + // Mask off irrelevant source value bits (if any) + srcValue = srcValue & srcBitMask; - // Shift source down to bottom of DWORD - const unsigned int srcBitShift = getBitShift(srcBitMask); - srcValue >>= srcBitShift; + // Shift source down to bottom of DWORD + const unsigned int srcBitShift = getBitShift(srcBitMask); + srcValue >>= srcBitShift; - // Get max value possible in source from srcMask - const SrcT srcMax = srcBitMask >> srcBitShift; + // Get max value possible in source from srcMask + const SrcT srcMax = srcBitMask >> srcBitShift; - // Get max available in dest - const unsigned int destBitShift = getBitShift(destBitMask); - const DestT destMax = destBitMask >> destBitShift; + // Get max available in dest + const unsigned int destBitShift = getBitShift(destBitMask); + const DestT destMax = destBitMask >> destBitShift; - // Scale source value into destination, and shift back - DestT destValue = (srcValue * destMax) / srcMax; - return (destValue << destBitShift); - } + // Scale source value into destination, and shift back + DestT destValue = (srcValue * destMax) / srcMax; + return (destValue << destBitShift); + } /** * Convert N bit colour channel value to P bits. It fills P bits with the @@ -217,7 +217,7 @@ namespace Ogre { } /** Convert a float32 to a float16 (NV_half_float) - Courtesy of OpenEXR + Courtesy of OpenEXR */ static inline uint16 floatToHalf(float i) { @@ -225,8 +225,8 @@ namespace Ogre { v.f = i; return floatToHalfI(v.i); } - /** Converts float in uint32 format to a a half in uint16 format - */ + /** Converts float in uint32 format to a a half in uint16 format + */ static inline uint16 floatToHalfI(uint32 i) { register int s = (i >> 16) & 0x00008000; @@ -276,9 +276,9 @@ namespace Ogre { v.i = halfToFloatI(y); return v.f; } - /** Converts a half in uint16 format to a float - in uint32 format - */ + /** Converts a half in uint16 format to a float + in uint32 format + */ static inline uint32 halfToFloatI(uint16 y) { register int s = (y >> 15) & 0x00000001; @@ -323,8 +323,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreBlendMode.h b/OgreMain/include/OgreBlendMode.h index ff0024a8ef5..5028c757a5c 100644 --- a/OgreMain/include/OgreBlendMode.h +++ b/OgreMain/include/OgreBlendMode.h @@ -32,12 +32,12 @@ THE SOFTWARE. #include "OgreColourValue.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Materials - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Materials + * @{ + */ /** Type of texture blend mode. */ @@ -220,8 +220,8 @@ namespace Ogre { SBT_TRANSPARENT_COLOUR, /// Add the texture values to the existing scene content SBT_ADD, - /// Multiply the 2 colours together - SBT_MODULATE, + /// Multiply the 2 colours together + SBT_MODULATE, /// The default blend mode where source replaces destination SBT_REPLACE // TODO : more @@ -246,20 +246,20 @@ namespace Ogre { }; - /** Blending operations controls how objects are blended into the scene. The default operation - is add (+) but by changing this you can change how drawn objects are blended into the - existing scene. - */ - enum SceneBlendOperation - { - SBO_ADD, - SBO_SUBTRACT, - SBO_REVERSE_SUBTRACT, - SBO_MIN, - SBO_MAX - }; - /** @} */ - /** @} */ + /** Blending operations controls how objects are blended into the scene. The default operation + is add (+) but by changing this you can change how drawn objects are blended into the + existing scene. + */ + enum SceneBlendOperation + { + SBO_ADD, + SBO_SUBTRACT, + SBO_REVERSE_SUBTRACT, + SBO_MIN, + SBO_MAX + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreBone.h b/OgreMain/include/OgreBone.h index d141cee2613..d4eb993d7a3 100644 --- a/OgreMain/include/OgreBone.h +++ b/OgreMain/include/OgreBone.h @@ -35,12 +35,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ /** A bone in a skeleton. @remarks @@ -95,10 +95,10 @@ namespace Ogre that you should also make sure that there are no AnimationTrack objects referencing this bone, or if there are, you should disable them using pAnimation->destroyTrack(pBone->getHandle()); - @par - You can also use AnimationState::setBlendMask to mask out animation from - chosen tracks if you want to prevent application of a scripted animation - to a bone without altering the Animation definition. + @par + You can also use AnimationState::setBlendMask to mask out animation from + chosen tracks if you want to prevent application of a scripted animation + to a bone without altering the Animation definition. */ void setManuallyControlled(bool manuallyControlled); @@ -112,15 +112,15 @@ namespace Ogre */ void _getOffsetTransform(Matrix4& m) const; - /** Gets the inverted binding pose scale. */ - const Vector3& _getBindingPoseInverseScale(void) const { return mBindDerivedInverseScale; } - /** Gets the inverted binding pose position. */ - const Vector3& _getBindingPoseInversePosition(void) const { return mBindDerivedInversePosition; } - /** Gets the inverted binding pose orientation. */ - const Quaternion& _getBindingPoseInverseOrientation(void) const { return mBindDerivedInverseOrientation; } + /** Gets the inverted binding pose scale. */ + const Vector3& _getBindingPoseInverseScale(void) const { return mBindDerivedInverseScale; } + /** Gets the inverted binding pose position. */ + const Vector3& _getBindingPoseInversePosition(void) const { return mBindDerivedInversePosition; } + /** Gets the inverted binding pose orientation. */ + const Quaternion& _getBindingPoseInverseOrientation(void) const { return mBindDerivedInverseOrientation; } - /// @see Node::needUpdate - void needUpdate(bool forceParentUpdate = false); + /// @see Node::needUpdate + void needUpdate(bool forceParentUpdate = false); protected: @@ -146,8 +146,8 @@ namespace Ogre Vector3 mBindDerivedInversePosition; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreCodec.h b/OgreMain/include/OgreCodec.h index 78b79ae0c76..7f50d9f6078 100644 --- a/OgreMain/include/OgreCodec.h +++ b/OgreMain/include/OgreCodec.h @@ -35,12 +35,12 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ /** Abstract class that defines a 'codec'. @remarks @@ -51,7 +51,7 @@ namespace Ogre { The codec concept is a pretty generic one - you can easily understand how it can be used for images, sounds, archives, even compressed data. */ - class _OgreExport Codec : public CodecAlloc + class _OgreExport Codec : public CodecAlloc { protected: typedef map< String, Codec* >::type CodecList; @@ -74,28 +74,28 @@ namespace Ogre { typedef ConstMapIterator CodecIterator; public: - virtual ~Codec(); - + virtual ~Codec(); + /** Registers a new codec in the database. */ static void registerCodec( Codec *pCodec ) { - CodecList::iterator i = msMapCodecs.find(pCodec->getType()); - if (i != msMapCodecs.end()) - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - pCodec->getType() + " already has a registered codec. ", __FUNCTION__); + CodecList::iterator i = msMapCodecs.find(pCodec->getType()); + if (i != msMapCodecs.end()) + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + pCodec->getType() + " already has a registered codec. ", __FUNCTION__); msMapCodecs[pCodec->getType()] = pCodec; } - /** Return whether a codec is registered already. - */ - static bool isCodecRegistered( const String& codecType ) - { - return msMapCodecs.find(codecType) != msMapCodecs.end(); - } + /** Return whether a codec is registered already. + */ + static bool isCodecRegistered( const String& codecType ) + { + return msMapCodecs.find(codecType) != msMapCodecs.end(); + } - /** Unregisters a codec from the database. + /** Unregisters a codec from the database. */ static void unregisterCodec( Codec *pCodec ) { @@ -114,13 +114,13 @@ namespace Ogre { /** Gets the codec registered for the passed in file extension. */ static Codec* getCodec(const String& extension); - /** Gets the codec that can handle the given 'magic' identifier. - @param magicNumberPtr Pointer to a stream of bytes which should identify the file. - Note that this may be more than needed - each codec may be looking for - a different size magic number. - @param maxbytes The number of bytes passed - */ - static Codec* getCodec(char *magicNumberPtr, size_t maxbytes); + /** Gets the codec that can handle the given 'magic' identifier. + @param magicNumberPtr Pointer to a stream of bytes which should identify the file. + Note that this may be more than needed - each codec may be looking for + a different size magic number. + @param maxbytes The number of bytes passed + */ + static Codec* getCodec(char *magicNumberPtr, size_t maxbytes); /** Codes the data in the input stream and saves the result in the output stream. @@ -150,25 +150,25 @@ namespace Ogre { */ virtual String getDataType() const = 0; - /** Returns whether a magic number header matches this codec. - @param magicNumberPtr Pointer to a stream of bytes which should identify the file. - Note that this may be more than needed - each codec may be looking for - a different size magic number. - @param maxbytes The number of bytes passed - */ - virtual bool magicNumberMatch(const char *magicNumberPtr, size_t maxbytes) const - { return !magicNumberToFileExt(magicNumberPtr, maxbytes).empty(); } - /** Maps a magic number header to a file extension, if this codec recognises it. - @param magicNumberPtr Pointer to a stream of bytes which should identify the file. - Note that this may be more than needed - each codec may be looking for - a different size magic number. - @param maxbytes The number of bytes passed - @return A blank string if the magic number was unknown, or a file extension. - */ - virtual String magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const = 0; + /** Returns whether a magic number header matches this codec. + @param magicNumberPtr Pointer to a stream of bytes which should identify the file. + Note that this may be more than needed - each codec may be looking for + a different size magic number. + @param maxbytes The number of bytes passed + */ + virtual bool magicNumberMatch(const char *magicNumberPtr, size_t maxbytes) const + { return !magicNumberToFileExt(magicNumberPtr, maxbytes).empty(); } + /** Maps a magic number header to a file extension, if this codec recognises it. + @param magicNumberPtr Pointer to a stream of bytes which should identify the file. + Note that this may be more than needed - each codec may be looking for + a different size magic number. + @param maxbytes The number of bytes passed + @return A blank string if the magic number was unknown, or a file extension. + */ + virtual String magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const = 0; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreColourValue.h b/OgreMain/include/OgreColourValue.h index bcf41831607..f35f4f6878f 100644 --- a/OgreMain/include/OgreColourValue.h +++ b/OgreMain/include/OgreColourValue.h @@ -31,28 +31,28 @@ THE SOFTWARE. #include "OgrePrerequisites.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ typedef uint32 RGBA; typedef uint32 ARGB; typedef uint32 ABGR; - typedef uint32 BGRA; + typedef uint32 BGRA; /** Class representing colour. - @remarks - Colour is represented as 4 components, each of which is a - floating-point value from 0.0 to 1.0. - @par - The 3 'normal' colour components are red, green and blue, a higher - number indicating greater amounts of that component in the colour. - The forth component is the 'alpha' value, which represents - transparency. In this case, 0.0 is completely transparent and 1.0 is - fully opaque. + @remarks + Colour is represented as 4 components, each of which is a + floating-point value from 0.0 to 1.0. + @par + The 3 'normal' colour components are red, green and blue, a higher + number indicating greater amounts of that component in the colour. + The forth component is the 'alpha' value, which represents + transparency. In this case, 0.0 is completely transparent and 1.0 is + fully opaque. */ class _OgreExport ColourValue { @@ -64,46 +64,46 @@ namespace Ogre { static const ColourValue Green; static const ColourValue Blue; - explicit ColourValue( float red = 1.0f, - float green = 1.0f, - float blue = 1.0f, - float alpha = 1.0f ) : r(red), g(green), b(blue), a(alpha) + explicit ColourValue( float red = 1.0f, + float green = 1.0f, + float blue = 1.0f, + float alpha = 1.0f ) : r(red), g(green), b(blue), a(alpha) { } - bool operator==(const ColourValue& rhs) const; - bool operator!=(const ColourValue& rhs) const; + bool operator==(const ColourValue& rhs) const; + bool operator!=(const ColourValue& rhs) const; float r,g,b,a; - /** Retrieves colour as RGBA. - */ - RGBA getAsRGBA(void) const; + /** Retrieves colour as RGBA. + */ + RGBA getAsRGBA(void) const; - /** Retrieves colour as ARGB. - */ - ARGB getAsARGB(void) const; + /** Retrieves colour as ARGB. + */ + ARGB getAsARGB(void) const; - /** Retrieves colour as BGRA. - */ - BGRA getAsBGRA(void) const; + /** Retrieves colour as BGRA. + */ + BGRA getAsBGRA(void) const; - /** Retrieves colours as ABGR */ - ABGR getAsABGR(void) const; + /** Retrieves colours as ABGR */ + ABGR getAsABGR(void) const; - /** Sets colour as RGBA. - */ + /** Sets colour as RGBA. + */ void setAsRGBA(const RGBA val); - /** Sets colour as ARGB. - */ + /** Sets colour as ARGB. + */ void setAsARGB(const ARGB val); - /** Sets colour as BGRA. - */ - void setAsBGRA(const BGRA val); + /** Sets colour as BGRA. + */ + void setAsBGRA(const BGRA val); - /** Sets colour as ABGR. - */ + /** Sets colour as ABGR. + */ void setAsABGR(const ABGR val); /** Clamps colour value to the range [0, 1]. @@ -140,35 +140,35 @@ namespace Ogre { return ret; } - /// Array accessor operator - inline float operator [] ( const size_t i ) const - { - assert( i < 4 ); - - return *(&r+i); - } - - /// Array accessor operator - inline float& operator [] ( const size_t i ) - { - assert( i < 4 ); - - return *(&r+i); - } - - /// Pointer accessor for direct copying - inline float* ptr() - { - return &r; - } - /// Pointer accessor for direct copying - inline const float* ptr() const - { - return &r; - } - - - // arithmetic operations + /// Array accessor operator + inline float operator [] ( const size_t i ) const + { + assert( i < 4 ); + + return *(&r+i); + } + + /// Array accessor operator + inline float& operator [] ( const size_t i ) + { + assert( i < 4 ); + + return *(&r+i); + } + + /// Pointer accessor for direct copying + inline float* ptr() + { + return &r; + } + /// Pointer accessor for direct copying + inline const float* ptr() const + { + return &r; + } + + + // arithmetic operations inline ColourValue operator + ( const ColourValue& rkVector ) const { ColourValue kSum; @@ -300,34 +300,34 @@ namespace Ogre { return *this; } - /** Set a colour value from Hue, Saturation and Brightness. - @param hue Hue value, scaled to the [0,1] range as opposed to the 0-360 - @param saturation Saturation level, [0,1] - @param brightness Brightness level, [0,1] - */ - void setHSB(Real hue, Real saturation, Real brightness); + /** Set a colour value from Hue, Saturation and Brightness. + @param hue Hue value, scaled to the [0,1] range as opposed to the 0-360 + @param saturation Saturation level, [0,1] + @param brightness Brightness level, [0,1] + */ + void setHSB(Real hue, Real saturation, Real brightness); - /** Convert the current colour to Hue, Saturation and Brightness values. - @param hue Output hue value, scaled to the [0,1] range as opposed to the 0-360 - @param saturation Output saturation level, [0,1] - @param brightness Output brightness level, [0,1] - */ - void getHSB(Real* hue, Real* saturation, Real* brightness) const; + /** Convert the current colour to Hue, Saturation and Brightness values. + @param hue Output hue value, scaled to the [0,1] range as opposed to the 0-360 + @param saturation Output saturation level, [0,1] + @param brightness Output brightness level, [0,1] + */ + void getHSB(Real* hue, Real* saturation, Real* brightness) const; - /** Function for writing to a stream. - */ - inline _OgreExport friend std::ostream& operator << - ( std::ostream& o, const ColourValue& c ) - { - o << "ColourValue(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")"; - return o; - } + /** Function for writing to a stream. + */ + inline _OgreExport friend std::ostream& operator << + ( std::ostream& o, const ColourValue& c ) + { + o << "ColourValue(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")"; + return o; + } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreCommon.h b/OgreMain/include/OgreCommon.h index 922b34f4e5c..b3118d4f2d7 100644 --- a/OgreMain/include/OgreCommon.h +++ b/OgreMain/include/OgreCommon.h @@ -43,25 +43,25 @@ namespace Ogre { typedef _StringBase String; - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - - /// Fast general hashing algorithm - uint32 _OgreExport FastHash (const char * data, int len, uint32 hashSoFar = 0); - /// Combine hashes with same style as boost::hash_combine - template - uint32 HashCombine (uint32 hashSoFar, const T& data) - { - return FastHash((const char*)&data, sizeof(T), hashSoFar); - } + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + + /// Fast general hashing algorithm + uint32 _OgreExport FastHash (const char * data, int len, uint32 hashSoFar = 0); + /// Combine hashes with same style as boost::hash_combine + template + uint32 HashCombine (uint32 hashSoFar, const T& data) + { + return FastHash((const char*)&data, sizeof(T), hashSoFar); + } /** Comparison functions used for the depth/stencil buffer operations and - others. */ + others. */ enum CompareFunction { CMPF_ALWAYS_FAIL, @@ -85,7 +85,7 @@ namespace Ogre { /// Equal to: min=FO_LINEAR, mag=FO_LINEAR, mip=FO_LINEAR TFO_TRILINEAR, /// Equal to: min=FO_ANISOTROPIC, max=FO_ANISOTROPIC, mip=FO_LINEAR - TFO_ANISOTROPIC + TFO_ANISOTROPIC }; enum FilterType @@ -145,9 +145,9 @@ namespace Ogre { /** Manual culling modes based on vertex normals. This setting applies to how the software culls triangles before sending them to the - hardware API. This culling mode is used by scene managers which choose to implement it - - normally those which deal with large amounts of fixed world geometry which is often - planar (software culling movable variable geometry is expensive). */ + hardware API. This culling mode is used by scene managers which choose to implement it - + normally those which deal with large amounts of fixed world geometry which is often + planar (software culling movable variable geometry is expensive). */ enum ManualCullingMode { /// No culling so everything is sent to the hardware. @@ -171,19 +171,19 @@ namespace Ogre { WFT_SAWTOOTH, /// Gradual steady decrease from max to min over the period, with an instant return to max at the end. WFT_INVERSE_SAWTOOTH, - /// Pulse Width Modulation. Works like WFT_SQUARE, except the high to low transition is controlled by duty cycle. - /// With a duty cycle of 50% (0.5) will give the same output as WFT_SQUARE. - WFT_PWM + /// Pulse Width Modulation. Works like WFT_SQUARE, except the high to low transition is controlled by duty cycle. + /// With a duty cycle of 50% (0.5) will give the same output as WFT_SQUARE. + WFT_PWM }; /** The polygon mode to use when rasterising. */ enum PolygonMode { - /// Only points are rendered. + /// Only points are rendered. PM_POINTS = 1, - /// Wireframe models are rendered. + /// Wireframe models are rendered. PM_WIREFRAME = 2, - /// Solid polygons are rendered. + /// Solid polygons are rendered. PM_SOLID = 3 }; @@ -192,22 +192,22 @@ namespace Ogre { { /** No shadows */ SHADOWTYPE_NONE = 0x00, - /** Mask for additive shadows (not for direct use, use SHADOWTYPE_ enum instead) - */ - SHADOWDETAILTYPE_ADDITIVE = 0x01, - /** Mask for modulative shadows (not for direct use, use SHADOWTYPE_ enum instead) - */ - SHADOWDETAILTYPE_MODULATIVE = 0x02, - /** Mask for integrated shadows (not for direct use, use SHADOWTYPE_ enum instead) - */ - SHADOWDETAILTYPE_INTEGRATED = 0x04, - /** Mask for stencil shadows (not for direct use, use SHADOWTYPE_ enum instead) - */ - SHADOWDETAILTYPE_STENCIL = 0x10, - /** Mask for texture shadows (not for direct use, use SHADOWTYPE_ enum instead) - */ - SHADOWDETAILTYPE_TEXTURE = 0x20, - + /** Mask for additive shadows (not for direct use, use SHADOWTYPE_ enum instead) + */ + SHADOWDETAILTYPE_ADDITIVE = 0x01, + /** Mask for modulative shadows (not for direct use, use SHADOWTYPE_ enum instead) + */ + SHADOWDETAILTYPE_MODULATIVE = 0x02, + /** Mask for integrated shadows (not for direct use, use SHADOWTYPE_ enum instead) + */ + SHADOWDETAILTYPE_INTEGRATED = 0x04, + /** Mask for stencil shadows (not for direct use, use SHADOWTYPE_ enum instead) + */ + SHADOWDETAILTYPE_STENCIL = 0x10, + /** Mask for texture shadows (not for direct use, use SHADOWTYPE_ enum instead) + */ + SHADOWDETAILTYPE_TEXTURE = 0x20, + /** Stencil shadow technique which renders all shadow volumes as a modulation after all the non-transparent areas have been rendered. This technique is considerably less fillrate intensive @@ -228,49 +228,49 @@ namespace Ogre { shadow receivers as a modulative pass. */ SHADOWTYPE_TEXTURE_MODULATIVE = 0x22, - + /** Texture-based shadow technique which involves a render-to-texture of the shadow caster and a projection of that texture onto the shadow receivers, built up per light as additive passes. - This technique can be very fillrate intensive because it requires numLights + 2 - passes of the entire scene. However, it is a more accurate model than the - modulative approach and this is especially apparent when using coloured lights - or bump mapping. + This technique can be very fillrate intensive because it requires numLights + 2 + passes of the entire scene. However, it is a more accurate model than the + modulative approach and this is especially apparent when using coloured lights + or bump mapping. */ SHADOWTYPE_TEXTURE_ADDITIVE = 0x21, - /** Texture-based shadow technique which involves a render-to-texture - of the shadow caster and a projection of that texture on to the shadow - receivers, with the usage of those shadow textures completely controlled - by the materials of the receivers. - This technique is easily the most flexible of all techniques because - the material author is in complete control over how the shadows are - combined with regular rendering. It can perform shadows as accurately - as SHADOWTYPE_TEXTURE_ADDITIVE but more efficiently because it requires - less passes. However it also requires more expertise to use, and - in almost all cases, shader capable hardware to really use to the full. - @note The 'additive' part of this mode means that the colour of - the rendered shadow texture is by default plain black. It does - not mean it does the adding on your receivers automatically though, how you - use that result is up to you. - */ - SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED = 0x25, - /** Texture-based shadow technique which involves a render-to-texture - of the shadow caster and a projection of that texture on to the shadow - receivers, with the usage of those shadow textures completely controlled - by the materials of the receivers. - This technique is easily the most flexible of all techniques because - the material author is in complete control over how the shadows are - combined with regular rendering. It can perform shadows as accurately - as SHADOWTYPE_TEXTURE_ADDITIVE but more efficiently because it requires - less passes. However it also requires more expertise to use, and - in almost all cases, shader capable hardware to really use to the full. - @note The 'modulative' part of this mode means that the colour of - the rendered shadow texture is by default the 'shadow colour'. It does - not mean it modulates on your receivers automatically though, how you - use that result is up to you. - */ - SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED = 0x26 + /** Texture-based shadow technique which involves a render-to-texture + of the shadow caster and a projection of that texture on to the shadow + receivers, with the usage of those shadow textures completely controlled + by the materials of the receivers. + This technique is easily the most flexible of all techniques because + the material author is in complete control over how the shadows are + combined with regular rendering. It can perform shadows as accurately + as SHADOWTYPE_TEXTURE_ADDITIVE but more efficiently because it requires + less passes. However it also requires more expertise to use, and + in almost all cases, shader capable hardware to really use to the full. + @note The 'additive' part of this mode means that the colour of + the rendered shadow texture is by default plain black. It does + not mean it does the adding on your receivers automatically though, how you + use that result is up to you. + */ + SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED = 0x25, + /** Texture-based shadow technique which involves a render-to-texture + of the shadow caster and a projection of that texture on to the shadow + receivers, with the usage of those shadow textures completely controlled + by the materials of the receivers. + This technique is easily the most flexible of all techniques because + the material author is in complete control over how the shadows are + combined with regular rendering. It can perform shadows as accurately + as SHADOWTYPE_TEXTURE_ADDITIVE but more efficiently because it requires + less passes. However it also requires more expertise to use, and + in almost all cases, shader capable hardware to really use to the full. + @note The 'modulative' part of this mode means that the colour of + the rendered shadow texture is by default the 'shadow colour'. It does + not mean it modulates on your receivers automatically though, how you + use that result is up to you. + */ + SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED = 0x26 }; /** An enumeration describing which material properties should track the vertex colours */ @@ -299,248 +299,248 @@ namespace Ogre { FBT_STENCIL = 0x4 }; - /** Flags for the Instance Manager when calculating ideal number of instances per batch */ - enum InstanceManagerFlags - { - /** Forces an amount of instances per batch low enough so that vertices * numInst < 65535 - since usually improves performance. In HW instanced techniques, this flag is ignored - */ - IM_USE16BIT = 0x0001, + /** Flags for the Instance Manager when calculating ideal number of instances per batch */ + enum InstanceManagerFlags + { + /** Forces an amount of instances per batch low enough so that vertices * numInst < 65535 + since usually improves performance. In HW instanced techniques, this flag is ignored + */ + IM_USE16BIT = 0x0001, - /** The num. of instances is adjusted so that as few pixels as possible are wasted - in the vertex texture */ - IM_VTFBESTFIT = 0x0002, + /** The num. of instances is adjusted so that as few pixels as possible are wasted + in the vertex texture */ + IM_VTFBESTFIT = 0x0002, - /** Use a limited number of skeleton animations shared among all instances. - Update only that limited amount of animations in the vertex texture.*/ - IM_VTFBONEMATRIXLOOKUP = 0x0004, + /** Use a limited number of skeleton animations shared among all instances. + Update only that limited amount of animations in the vertex texture.*/ + IM_VTFBONEMATRIXLOOKUP = 0x0004, - IM_USEBONEDUALQUATERNIONS = 0x0008, + IM_USEBONEDUALQUATERNIONS = 0x0008, - /** Use one weight per vertex when recommended (i.e. VTF). */ - IM_USEONEWEIGHT = 0x0010, + /** Use one weight per vertex when recommended (i.e. VTF). */ + IM_USEONEWEIGHT = 0x0010, - /** All techniques are forced to one weight per vertex. */ - IM_FORCEONEWEIGHT = 0x0020, + /** All techniques are forced to one weight per vertex. */ + IM_FORCEONEWEIGHT = 0x0020, - IM_USEALL = IM_USE16BIT|IM_VTFBESTFIT|IM_USEONEWEIGHT - }; + IM_USEALL = IM_USE16BIT|IM_VTFBESTFIT|IM_USEONEWEIGHT + }; - - /** A hashed vector. - */ - template - class HashedVector - { - public: - typedef std::vector > VectorImpl; - protected: - VectorImpl mList; - mutable uint32 mListHash; - mutable bool mListHashDirty; - - void addToHash(const T& newPtr) const - { - mListHash = FastHash((const char*)&newPtr, sizeof(T), mListHash); - } - void recalcHash() const - { - mListHash = 0; - for (const_iterator i = mList.begin(); i != mList.end(); ++i) - addToHash(*i); - mListHashDirty = false; - - } - - public: - typedef typename VectorImpl::value_type value_type; - typedef typename VectorImpl::pointer pointer; - typedef typename VectorImpl::reference reference; - typedef typename VectorImpl::const_reference const_reference; - typedef typename VectorImpl::size_type size_type; - typedef typename VectorImpl::difference_type difference_type; - typedef typename VectorImpl::iterator iterator; - typedef typename VectorImpl::const_iterator const_iterator; - typedef typename VectorImpl::reverse_iterator reverse_iterator; - typedef typename VectorImpl::const_reverse_iterator const_reverse_iterator; - - void dirtyHash() - { - mListHashDirty = true; - } - bool isHashDirty() const - { - return mListHashDirty; - } - - iterator begin() - { - // we have to assume that hash needs recalculating on non-const - dirtyHash(); - return mList.begin(); - } - iterator end() { return mList.end(); } - const_iterator begin() const { return mList.begin(); } - const_iterator end() const { return mList.end(); } - reverse_iterator rbegin() - { - // we have to assume that hash needs recalculating on non-const - dirtyHash(); - return mList.rbegin(); - } - reverse_iterator rend() { return mList.rend(); } - const_reverse_iterator rbegin() const { return mList.rbegin(); } - const_reverse_iterator rend() const { return mList.rend(); } - size_type size() const { return mList.size(); } - size_type max_size() const { return mList.max_size(); } - size_type capacity() const { return mList.capacity(); } - bool empty() const { return mList.empty(); } - reference operator[](size_type n) - { - // we have to assume that hash needs recalculating on non-const - dirtyHash(); - return mList[n]; - } - const_reference operator[](size_type n) const { return mList[n]; } - reference at(size_type n) - { - // we have to assume that hash needs recalculating on non-const - dirtyHash(); - return mList.const_iterator(n); - } - const_reference at(size_type n) const { return mList.at(n); } - HashedVector() : mListHash(0), mListHashDirty(false) {} - HashedVector(size_type n) : mList(n), mListHash(0), mListHashDirty(n > 0) {} - HashedVector(size_type n, const T& t) : mList(n, t), mListHash(0), mListHashDirty(n > 0) {} - HashedVector(const HashedVector& rhs) - : mList(rhs.mList), mListHash(rhs.mListHash), mListHashDirty(rhs.mListHashDirty) {} - - template - HashedVector(InputIterator a, InputIterator b) - : mList(a, b), mListHash(0), mListHashDirty(false) - { - dirtyHash(); - } - - ~HashedVector() {} - HashedVector& operator=(const HashedVector& rhs) - { - mList = rhs.mList; - mListHash = rhs.mListHash; - mListHashDirty = rhs.mListHashDirty; - return *this; - } - - void reserve(size_t t) { mList.reserve(t); } - reference front() - { - // we have to assume that hash needs recalculating on non-const - dirtyHash(); - return mList.front(); - } - const_reference front() const { return mList.front(); } - reference back() - { - // we have to assume that hash needs recalculating on non-const - dirtyHash(); - return mList.back(); - } - const_reference back() const { return mList.back(); } - void push_back(const T& t) - { - mList.push_back(t); - // Quick progressive hash add - if (!isHashDirty()) - addToHash(t); - } - void pop_back() - { - mList.pop_back(); - dirtyHash(); - } - void swap(HashedVector& rhs) - { - mList.swap(rhs.mList); - dirtyHash(); - } - iterator insert(iterator pos, const T& t) - { - bool recalc = (pos != end()); - iterator ret = mList.insert(pos, t); - if (recalc) - dirtyHash(); - else - addToHash(t); - return ret; - } - - template - void insert(iterator pos, - InputIterator f, InputIterator l) - { - mList.insert(pos, f, l); - dirtyHash(); - } - - void insert(iterator pos, size_type n, const T& x) - { - mList.insert(pos, n, x); - dirtyHash(); - } - - iterator erase(iterator pos) - { - iterator ret = mList.erase(pos); - dirtyHash(); - return ret; - } - iterator erase(iterator first, iterator last) - { - iterator ret = mList.erase(first, last); - dirtyHash(); - return ret; - } - void clear() - { - mList.clear(); - mListHash = 0; - mListHashDirty = false; - } - - void resize(size_type n, const T& t = T()) - { - bool recalc = false; - if (n != size()) - recalc = true; - - mList.resize(n, t); - if (recalc) - dirtyHash(); - } - - bool operator==(const HashedVector& b) - { return mListHash == b.mListHash; } - - bool operator<(const HashedVector& b) - { return mListHash < b.mListHash; } - - - /// Get the hash value - uint32 getHash() const - { - if (isHashDirty()) - recalcHash(); - - return mListHash; - } - public: - - - - }; - - class Light; - typedef HashedVector LightList; + + /** A hashed vector. + */ + template + class HashedVector + { + public: + typedef std::vector > VectorImpl; + protected: + VectorImpl mList; + mutable uint32 mListHash; + mutable bool mListHashDirty; + + void addToHash(const T& newPtr) const + { + mListHash = FastHash((const char*)&newPtr, sizeof(T), mListHash); + } + void recalcHash() const + { + mListHash = 0; + for (const_iterator i = mList.begin(); i != mList.end(); ++i) + addToHash(*i); + mListHashDirty = false; + + } + + public: + typedef typename VectorImpl::value_type value_type; + typedef typename VectorImpl::pointer pointer; + typedef typename VectorImpl::reference reference; + typedef typename VectorImpl::const_reference const_reference; + typedef typename VectorImpl::size_type size_type; + typedef typename VectorImpl::difference_type difference_type; + typedef typename VectorImpl::iterator iterator; + typedef typename VectorImpl::const_iterator const_iterator; + typedef typename VectorImpl::reverse_iterator reverse_iterator; + typedef typename VectorImpl::const_reverse_iterator const_reverse_iterator; + + void dirtyHash() + { + mListHashDirty = true; + } + bool isHashDirty() const + { + return mListHashDirty; + } + + iterator begin() + { + // we have to assume that hash needs recalculating on non-const + dirtyHash(); + return mList.begin(); + } + iterator end() { return mList.end(); } + const_iterator begin() const { return mList.begin(); } + const_iterator end() const { return mList.end(); } + reverse_iterator rbegin() + { + // we have to assume that hash needs recalculating on non-const + dirtyHash(); + return mList.rbegin(); + } + reverse_iterator rend() { return mList.rend(); } + const_reverse_iterator rbegin() const { return mList.rbegin(); } + const_reverse_iterator rend() const { return mList.rend(); } + size_type size() const { return mList.size(); } + size_type max_size() const { return mList.max_size(); } + size_type capacity() const { return mList.capacity(); } + bool empty() const { return mList.empty(); } + reference operator[](size_type n) + { + // we have to assume that hash needs recalculating on non-const + dirtyHash(); + return mList[n]; + } + const_reference operator[](size_type n) const { return mList[n]; } + reference at(size_type n) + { + // we have to assume that hash needs recalculating on non-const + dirtyHash(); + return mList.const_iterator(n); + } + const_reference at(size_type n) const { return mList.at(n); } + HashedVector() : mListHash(0), mListHashDirty(false) {} + HashedVector(size_type n) : mList(n), mListHash(0), mListHashDirty(n > 0) {} + HashedVector(size_type n, const T& t) : mList(n, t), mListHash(0), mListHashDirty(n > 0) {} + HashedVector(const HashedVector& rhs) + : mList(rhs.mList), mListHash(rhs.mListHash), mListHashDirty(rhs.mListHashDirty) {} + + template + HashedVector(InputIterator a, InputIterator b) + : mList(a, b), mListHash(0), mListHashDirty(false) + { + dirtyHash(); + } + + ~HashedVector() {} + HashedVector& operator=(const HashedVector& rhs) + { + mList = rhs.mList; + mListHash = rhs.mListHash; + mListHashDirty = rhs.mListHashDirty; + return *this; + } + + void reserve(size_t t) { mList.reserve(t); } + reference front() + { + // we have to assume that hash needs recalculating on non-const + dirtyHash(); + return mList.front(); + } + const_reference front() const { return mList.front(); } + reference back() + { + // we have to assume that hash needs recalculating on non-const + dirtyHash(); + return mList.back(); + } + const_reference back() const { return mList.back(); } + void push_back(const T& t) + { + mList.push_back(t); + // Quick progressive hash add + if (!isHashDirty()) + addToHash(t); + } + void pop_back() + { + mList.pop_back(); + dirtyHash(); + } + void swap(HashedVector& rhs) + { + mList.swap(rhs.mList); + dirtyHash(); + } + iterator insert(iterator pos, const T& t) + { + bool recalc = (pos != end()); + iterator ret = mList.insert(pos, t); + if (recalc) + dirtyHash(); + else + addToHash(t); + return ret; + } + + template + void insert(iterator pos, + InputIterator f, InputIterator l) + { + mList.insert(pos, f, l); + dirtyHash(); + } + + void insert(iterator pos, size_type n, const T& x) + { + mList.insert(pos, n, x); + dirtyHash(); + } + + iterator erase(iterator pos) + { + iterator ret = mList.erase(pos); + dirtyHash(); + return ret; + } + iterator erase(iterator first, iterator last) + { + iterator ret = mList.erase(first, last); + dirtyHash(); + return ret; + } + void clear() + { + mList.clear(); + mListHash = 0; + mListHashDirty = false; + } + + void resize(size_type n, const T& t = T()) + { + bool recalc = false; + if (n != size()) + recalc = true; + + mList.resize(n, t); + if (recalc) + dirtyHash(); + } + + bool operator==(const HashedVector& b) + { return mListHash == b.mListHash; } + + bool operator<(const HashedVector& b) + { return mListHash < b.mListHash; } + + + /// Get the hash value + uint32 getHash() const + { + if (isHashDirty()) + recalcHash(); + + return mListHash; + } + public: + + + + }; + + class Light; + typedef HashedVector LightList; /// Constant blank string, useful for returning by ref where local does not exist @@ -549,8 +549,8 @@ namespace Ogre { typedef map::type UnaryOptionList; typedef map::type BinaryOptionList; - /// Name / value parameter pair (first = name, second = value) - typedef map::type NameValuePairList; + /// Name / value parameter pair (first = name, second = value) + typedef map::type NameValuePairList; /// Alias / Texture name pair (first = alias, second = texture name) typedef map::type AliasTextureNamePairList; @@ -583,98 +583,98 @@ namespace Ogre { { return bottom - top; } - bool isNull() const - { - return width() == 0 || height() == 0; - } - void setNull() - { - left = right = top = bottom = 0; - } - TRect & merge(const TRect& rhs) - { - if (isNull()) - { - *this = rhs; - } - else if (!rhs.isNull()) - { - left = std::min(left, rhs.left); - right = std::max(right, rhs.right); - top = std::min(top, rhs.top); - bottom = std::max(bottom, rhs.bottom); - } - - return *this; - - } - TRect intersect(const TRect& rhs) const - { - TRect ret; - if (isNull() || rhs.isNull()) - { - // empty - return ret; - } - else - { - ret.left = std::max(left, rhs.left); - ret.right = std::min(right, rhs.right); - ret.top = std::max(top, rhs.top); - ret.bottom = std::min(bottom, rhs.bottom); - } - - if (ret.left > ret.right || ret.top > ret.bottom) - { - // no intersection, return empty - ret.left = ret.top = ret.right = ret.bottom = 0; - } - - return ret; - - } + bool isNull() const + { + return width() == 0 || height() == 0; + } + void setNull() + { + left = right = top = bottom = 0; + } + TRect & merge(const TRect& rhs) + { + if (isNull()) + { + *this = rhs; + } + else if (!rhs.isNull()) + { + left = std::min(left, rhs.left); + right = std::max(right, rhs.right); + top = std::min(top, rhs.top); + bottom = std::max(bottom, rhs.bottom); + } + + return *this; + + } + TRect intersect(const TRect& rhs) const + { + TRect ret; + if (isNull() || rhs.isNull()) + { + // empty + return ret; + } + else + { + ret.left = std::max(left, rhs.left); + ret.right = std::min(right, rhs.right); + ret.top = std::max(top, rhs.top); + ret.bottom = std::min(bottom, rhs.bottom); + } + + if (ret.left > ret.right || ret.top > ret.bottom) + { + // no intersection, return empty + ret.left = ret.top = ret.right = ret.bottom = 0; + } + + return ret; + + } }; - template - std::ostream& operator<<(std::ostream& o, const TRect& r) - { - o << "TRect<>(l:" << r.left << ", t:" << r.top << ", r:" << r.right << ", b:" << r.bottom << ")"; - return o; - } + template + std::ostream& operator<<(std::ostream& o, const TRect& r) + { + o << "TRect<>(l:" << r.left << ", t:" << r.top << ", r:" << r.right << ", b:" << r.bottom << ")"; + return o; + } /** Structure used to define a rectangle in a 2-D floating point space. */ typedef TRect FloatRect; - /** Structure used to define a rectangle in a 2-D floating point space, - subject to double / single floating point settings. - */ - typedef TRect RealRect; + /** Structure used to define a rectangle in a 2-D floating point space, + subject to double / single floating point settings. + */ + typedef TRect RealRect; /** Structure used to define a rectangle in a 2-D integer space. */ typedef TRect< long > Rect; /** Structure used to define a box in a 3-D integer space. - Note that the left, top, and front edges are included but the right, - bottom and back ones are not. + Note that the left, top, and front edges are included but the right, + bottom and back ones are not. */ struct Box { uint32 left, top, right, bottom, front, back; - /// Parameterless constructor for setting the members manually + /// Parameterless constructor for setting the members manually Box() - : left(0), top(0), right(1), bottom(1), front(0), back(1) + : left(0), top(0), right(1), bottom(1), front(0), back(1) { } /** Define a box from left, top, right and bottom coordinates - This box will have depth one (front=0 and back=1). - @param l x value of left edge - @param t y value of top edge - @param r x value of right edge - @param b y value of bottom edge - @note Note that the left, top, and front edges are included - but the right, bottom and back ones are not. + This box will have depth one (front=0 and back=1). + @param l x value of left edge + @param t y value of top edge + @param r x value of right edge + @param b y value of bottom edge + @note Note that the left, top, and front edges are included + but the right, bottom and back ones are not. */ Box( uint32 l, uint32 t, uint32 r, uint32 b ): left(l), @@ -684,18 +684,18 @@ namespace Ogre { front(0), back(1) { - assert(right >= left && bottom >= top && back >= front); + assert(right >= left && bottom >= top && back >= front); } /** Define a box from left, top, front, right, bottom and back - coordinates. - @param l x value of left edge - @param t y value of top edge - @param ff z value of front edge - @param r x value of right edge - @param b y value of bottom edge - @param bb z value of back edge - @note Note that the left, top, and front edges are included - but the right, bottom and back ones are not. + coordinates. + @param l x value of left edge + @param t y value of top edge + @param ff z value of front edge + @param r x value of right edge + @param b y value of bottom edge + @param bb z value of back edge + @note Note that the left, top, and front edges are included + but the right, bottom and back ones are not. */ Box( uint32 l, uint32 t, uint32 ff, uint32 r, uint32 b, uint32 bb ): left(l), @@ -705,14 +705,14 @@ namespace Ogre { front(ff), back(bb) { - assert(right >= left && bottom >= top && back >= front); + assert(right >= left && bottom >= top && back >= front); } /// Return true if the other box is a part of this one bool contains(const Box &def) const { - return (def.left >= left && def.top >= top && def.front >= front && - def.right <= right && def.bottom <= bottom && def.back <= back); + return (def.left >= left && def.top >= top && def.front >= front && + def.right <= right && def.bottom <= bottom && def.back <= back); } /// Get the width of this box @@ -724,8 +724,8 @@ namespace Ogre { }; - - /** Locate command-line options of the unary form '-blah' and of the + + /** Locate command-line options of the unary form '-blah' and of the binary form '-blah foo', passing back the index of the next non-option. @param numargs, argv The standard parameters passed to the main method @param unaryOptList Map of unary options (i.e. those that do not require a parameter). @@ -739,35 +739,35 @@ namespace Ogre { int _OgreExport findCommandLineOpts(int numargs, char** argv, UnaryOptionList& unaryOptList, BinaryOptionList& binOptList); - /// Generic result of clipping - enum ClipResult - { - /// Nothing was clipped - CLIPPED_NONE = 0, - /// Partially clipped - CLIPPED_SOME = 1, - /// Everything was clipped away - CLIPPED_ALL = 2 - }; - - /// Render window creation parameters. - struct RenderWindowDescription - { - String name; - unsigned int width; - unsigned int height; - bool useFullScreen; - NameValuePairList miscParams; - }; - - /// Render window creation parameters container. - typedef vector::type RenderWindowDescriptionList; - - /// Render window container. - typedef vector::type RenderWindowList; - - /** @} */ - /** @} */ + /// Generic result of clipping + enum ClipResult + { + /// Nothing was clipped + CLIPPED_NONE = 0, + /// Partially clipped + CLIPPED_SOME = 1, + /// Everything was clipped away + CLIPPED_ALL = 2 + }; + + /// Render window creation parameters. + struct RenderWindowDescription + { + String name; + unsigned int width; + unsigned int height; + bool useFullScreen; + NameValuePairList miscParams; + }; + + /// Render window creation parameters container. + typedef vector::type RenderWindowDescriptionList; + + /// Render window container. + typedef vector::type RenderWindowList; + + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreCompositionPass.h b/OgreMain/include/OgreCompositionPass.h index 2211910c3aa..87cf1a9d74c 100644 --- a/OgreMain/include/OgreCompositionPass.h +++ b/OgreMain/include/OgreCompositionPass.h @@ -34,16 +34,16 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Object representing one pass or operation in a composition sequence. This provides a - method to conveniently interleave RenderSystem commands between Render Queues. - */ - class _OgreExport CompositionPass : public CompositorInstAlloc + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Object representing one pass or operation in a composition sequence. This provides a + method to conveniently interleave RenderSystem commands between Render Queues. + */ + class _OgreExport CompositionPass : public CompositorInstAlloc { public: CompositionPass(CompositionTargetPass *parent); @@ -54,10 +54,10 @@ namespace Ogre { enum PassType { PT_CLEAR, /// Clear target to one colour - PT_STENCIL, /// Set stencil operation + PT_STENCIL, /// Set stencil operation PT_RENDERSCENE, /// Render the scene or part of it PT_RENDERQUAD, /// Render a full screen quad - PT_RENDERCUSTOM /// Render a custom sequence + PT_RENDERCUSTOM /// Render a custom sequence }; /** Set the type of composition pass */ @@ -65,209 +65,209 @@ namespace Ogre { /** Get the type of composition pass */ PassType getType() const; - /** Set an identifier for this pass. This identifier can be used to - "listen in" on this pass with an CompositorInstance::Listener. - */ - void setIdentifier(uint32 id); - /** Get the identifier for this pass */ - uint32 getIdentifier() const; + /** Set an identifier for this pass. This identifier can be used to + "listen in" on this pass with an CompositorInstance::Listener. + */ + void setIdentifier(uint32 id); + /** Get the identifier for this pass */ + uint32 getIdentifier() const; /** Set the material used by this pass - @note applies when PassType is RENDERQUAD - */ + @note applies when PassType is RENDERQUAD + */ void setMaterial(const MaterialPtr& mat); /** Set the material used by this pass - @note applies when PassType is RENDERQUAD - */ + @note applies when PassType is RENDERQUAD + */ void setMaterialName(const String &name); /** Get the material used by this pass - @note applies when PassType is RENDERQUAD - */ + @note applies when PassType is RENDERQUAD + */ const MaterialPtr& getMaterial() const; - /** Set the first render queue to be rendered in this pass (inclusive) - @note applies when PassType is RENDERSCENE - */ + /** Set the first render queue to be rendered in this pass (inclusive) + @note applies when PassType is RENDERSCENE + */ void setFirstRenderQueue(uint8 id); - /** Get the first render queue to be rendered in this pass (inclusive) - @note applies when PassType is RENDERSCENE - */ - uint8 getFirstRenderQueue() const; - /** Set the last render queue to be rendered in this pass (inclusive) - @note applies when PassType is RENDERSCENE - */ + /** Get the first render queue to be rendered in this pass (inclusive) + @note applies when PassType is RENDERSCENE + */ + uint8 getFirstRenderQueue() const; + /** Set the last render queue to be rendered in this pass (inclusive) + @note applies when PassType is RENDERSCENE + */ void setLastRenderQueue(uint8 id); - /** Get the last render queue to be rendered in this pass (inclusive) - @note applies when PassType is RENDERSCENE - */ - uint8 getLastRenderQueue() const; + /** Get the last render queue to be rendered in this pass (inclusive) + @note applies when PassType is RENDERSCENE + */ + uint8 getLastRenderQueue() const; - /** Set the material scheme used by this pass. - @remarks - Only applicable to passes that render the scene. - @see Technique::setScheme. - */ - void setMaterialScheme(const String& schemeName); - /** Get the material scheme used by this pass. - @remarks - Only applicable to passes that render the scene. - @see Technique::setScheme. - */ - const String& getMaterialScheme(void) const; + /** Set the material scheme used by this pass. + @remarks + Only applicable to passes that render the scene. + @see Technique::setScheme. + */ + void setMaterialScheme(const String& schemeName); + /** Get the material scheme used by this pass. + @remarks + Only applicable to passes that render the scene. + @see Technique::setScheme. + */ + const String& getMaterialScheme(void) const; - /** Would be nice to have for RENDERSCENE: - flags to: - exclude transparents - override material (at least -- color) - */ + /** Would be nice to have for RENDERSCENE: + flags to: + exclude transparents + override material (at least -- color) + */ /** Set the viewport clear buffers (defaults to FBT_COLOUR|FBT_DEPTH) @param val is a combination of FBT_COLOUR, FBT_DEPTH, FBT_STENCIL. - @note applies when PassType is CLEAR + @note applies when PassType is CLEAR */ void setClearBuffers(uint32 val); /** Get the viewport clear buffers. - @note applies when PassType is CLEAR + @note applies when PassType is CLEAR */ uint32 getClearBuffers() const; /** Set the viewport clear colour (defaults to 0,0,0,0) - @note applies when PassType is CLEAR - */ + @note applies when PassType is CLEAR + */ void setClearColour(const ColourValue &val); - /** Get the viewport clear colour (defaults to 0,0,0,0) - @note applies when PassType is CLEAR - */ + /** Get the viewport clear colour (defaults to 0,0,0,0) + @note applies when PassType is CLEAR + */ const ColourValue &getClearColour() const; /** Set the viewport clear depth (defaults to 1.0) - @note applies when PassType is CLEAR - */ + @note applies when PassType is CLEAR + */ void setClearDepth(Real depth); /** Get the viewport clear depth (defaults to 1.0) - @note applies when PassType is CLEAR - */ + @note applies when PassType is CLEAR + */ Real getClearDepth() const; - /** Set the viewport clear stencil value (defaults to 0) - @note applies when PassType is CLEAR - */ + /** Set the viewport clear stencil value (defaults to 0) + @note applies when PassType is CLEAR + */ void setClearStencil(uint32 value); /** Get the viewport clear stencil value (defaults to 0) - @note applies when PassType is CLEAR - */ + @note applies when PassType is CLEAR + */ uint32 getClearStencil() const; - /** Set stencil check on or off. - @note applies when PassType is STENCIL - */ - void setStencilCheck(bool value); - /** Get stencil check enable. - @note applies when PassType is STENCIL - */ - bool getStencilCheck() const; - /** Set stencil compare function. - @note applies when PassType is STENCIL - */ - void setStencilFunc(CompareFunction value); - /** Get stencil compare function. - @note applies when PassType is STENCIL - */ - CompareFunction getStencilFunc() const; - /** Set stencil reference value. - @note applies when PassType is STENCIL - */ - void setStencilRefValue(uint32 value); - /** Get stencil reference value. - @note applies when PassType is STENCIL - */ - uint32 getStencilRefValue() const; - /** Set stencil mask. - @note applies when PassType is STENCIL - */ - void setStencilMask(uint32 value); - /** Get stencil mask. - @note applies when PassType is STENCIL - */ - uint32 getStencilMask() const; - /** Set stencil fail operation. - @note applies when PassType is STENCIL - */ - void setStencilFailOp(StencilOperation value); - /** Get stencil fail operation. - @note applies when PassType is STENCIL - */ - StencilOperation getStencilFailOp() const; - /** Set stencil depth fail operation. - @note applies when PassType is STENCIL - */ - void setStencilDepthFailOp(StencilOperation value); - /** Get stencil depth fail operation. - @note applies when PassType is STENCIL - */ - StencilOperation getStencilDepthFailOp() const; - /** Set stencil pass operation. - @note applies when PassType is STENCIL - */ - void setStencilPassOp(StencilOperation value); - /** Get stencil pass operation. - @note applies when PassType is STENCIL - */ - StencilOperation getStencilPassOp() const; - /** Set two sided stencil operation. - @note applies when PassType is STENCIL - */ - void setStencilTwoSidedOperation(bool value); - /** Get two sided stencil operation. - @note applies when PassType is STENCIL - */ - bool getStencilTwoSidedOperation() const; + /** Set stencil check on or off. + @note applies when PassType is STENCIL + */ + void setStencilCheck(bool value); + /** Get stencil check enable. + @note applies when PassType is STENCIL + */ + bool getStencilCheck() const; + /** Set stencil compare function. + @note applies when PassType is STENCIL + */ + void setStencilFunc(CompareFunction value); + /** Get stencil compare function. + @note applies when PassType is STENCIL + */ + CompareFunction getStencilFunc() const; + /** Set stencil reference value. + @note applies when PassType is STENCIL + */ + void setStencilRefValue(uint32 value); + /** Get stencil reference value. + @note applies when PassType is STENCIL + */ + uint32 getStencilRefValue() const; + /** Set stencil mask. + @note applies when PassType is STENCIL + */ + void setStencilMask(uint32 value); + /** Get stencil mask. + @note applies when PassType is STENCIL + */ + uint32 getStencilMask() const; + /** Set stencil fail operation. + @note applies when PassType is STENCIL + */ + void setStencilFailOp(StencilOperation value); + /** Get stencil fail operation. + @note applies when PassType is STENCIL + */ + StencilOperation getStencilFailOp() const; + /** Set stencil depth fail operation. + @note applies when PassType is STENCIL + */ + void setStencilDepthFailOp(StencilOperation value); + /** Get stencil depth fail operation. + @note applies when PassType is STENCIL + */ + StencilOperation getStencilDepthFailOp() const; + /** Set stencil pass operation. + @note applies when PassType is STENCIL + */ + void setStencilPassOp(StencilOperation value); + /** Get stencil pass operation. + @note applies when PassType is STENCIL + */ + StencilOperation getStencilPassOp() const; + /** Set two sided stencil operation. + @note applies when PassType is STENCIL + */ + void setStencilTwoSidedOperation(bool value); + /** Get two sided stencil operation. + @note applies when PassType is STENCIL + */ + bool getStencilTwoSidedOperation() const; - /** Set read back stencil-depth buffer as texture operation. - @note applies when PassType is STENCIL - */ - void setStencilReadBackAsTextureOperation(bool value); - /** Get read back stencil-depth buffer - @note applies when PassType is STENCIL - */ - bool getStencilReadBackAsTextureOperation() const; + /** Set read back stencil-depth buffer as texture operation. + @note applies when PassType is STENCIL + */ + void setStencilReadBackAsTextureOperation(bool value); + /** Get read back stencil-depth buffer + @note applies when PassType is STENCIL + */ + bool getStencilReadBackAsTextureOperation() const; - /// Inputs (for material used for rendering the quad) - struct InputTex - { - /// Name (local) of the input texture (empty == no input) - String name; - /// MRT surface index if applicable - size_t mrtIndex; - InputTex() : name(BLANKSTRING), mrtIndex(0) {} - InputTex(const String& _name, size_t _mrtIndex = 0) - : name(_name), mrtIndex(_mrtIndex) {} - }; + /// Inputs (for material used for rendering the quad) + struct InputTex + { + /// Name (local) of the input texture (empty == no input) + String name; + /// MRT surface index if applicable + size_t mrtIndex; + InputTex() : name(BLANKSTRING), mrtIndex(0) {} + InputTex(const String& _name, size_t _mrtIndex = 0) + : name(_name), mrtIndex(_mrtIndex) {} + }; /** Set an input local texture. An empty string clears the input. @param id Input to set. Must be in 0..OGRE_MAX_TEXTURE_LAYERS-1 @param input Which texture to bind to this input. An empty string clears the input. - @param mrtIndex Which surface of an MRT to retrieve - @note applies when PassType is RENDERQUAD + @param mrtIndex Which surface of an MRT to retrieve + @note applies when PassType is RENDERQUAD */ void setInput(size_t id, const String &input=BLANKSTRING, size_t mrtIndex=0); /** Get the value of an input. @param id Input to get. Must be in 0..OGRE_MAX_TEXTURE_LAYERS-1. - @note applies when PassType is RENDERQUAD + @note applies when PassType is RENDERQUAD */ const InputTex &getInput(size_t id) const; /** Get the number of inputs used. - @note applies when PassType is RENDERQUAD + @note applies when PassType is RENDERQUAD */ size_t getNumInputs() const; /** Clear all inputs. - @note applies when PassType is RENDERQUAD + @note applies when PassType is RENDERQUAD */ void clearAllInputs(); /** Get parent object - @note applies when PassType is RENDERQUAD - */ + @note applies when PassType is RENDERQUAD + */ CompositionTargetPass *getParent(); /** Determine if this target pass is supported on the current rendering device. @@ -284,68 +284,68 @@ namespace Ogre { */ bool getQuadCorners(Real & left,Real & top,Real & right,Real & bottom) const; - /** Sets the use of camera frustum far corners provided in the quad's normals - @note applies when PassType is RENDERQUAD - */ - void setQuadFarCorners(bool farCorners, bool farCornersViewSpace); + /** Sets the use of camera frustum far corners provided in the quad's normals + @note applies when PassType is RENDERQUAD + */ + void setQuadFarCorners(bool farCorners, bool farCornersViewSpace); - /** Returns true if camera frustum far corners are provided in the quad. - @note applies when PassType is RENDERQUAD - */ - bool getQuadFarCorners() const; + /** Returns true if camera frustum far corners are provided in the quad. + @note applies when PassType is RENDERQUAD + */ + bool getQuadFarCorners() const; - /** Returns true if the far corners provided in the quad are in view space - @note applies when PassType is RENDERQUAD - */ - bool getQuadFarCornersViewSpace() const; + /** Returns true if the far corners provided in the quad are in view space + @note applies when PassType is RENDERQUAD + */ + bool getQuadFarCornersViewSpace() const; - /** Set the type name of this custom composition pass. - @note applies when PassType is RENDERCUSTOM - @see CompositorManager::registerCustomCompositionPass - */ - void setCustomType(const String& customType); + /** Set the type name of this custom composition pass. + @note applies when PassType is RENDERCUSTOM + @see CompositorManager::registerCustomCompositionPass + */ + void setCustomType(const String& customType); - /** Get the type name of this custom composition pass. - @note applies when PassType is RENDERCUSTOM - @see CompositorManager::registerCustomCompositionPass - */ - const String& getCustomType() const; + /** Get the type name of this custom composition pass. + @note applies when PassType is RENDERCUSTOM + @see CompositorManager::registerCustomCompositionPass + */ + const String& getCustomType() const; private: /// Parent technique CompositionTargetPass *mParent; /// Type of composition pass PassType mType; - /// Identifier for this pass - uint32 mIdentifier; + /// Identifier for this pass + uint32 mIdentifier; /// Material used for rendering MaterialPtr mMaterial; /// [first,last] render queue to render this pass (in case of PT_RENDERSCENE) - uint8 mFirstRenderQueue; - uint8 mLastRenderQueue; - /// Material scheme name - String mMaterialScheme; + uint8 mFirstRenderQueue; + uint8 mLastRenderQueue; + /// Material scheme name + String mMaterialScheme; /// Clear buffers (in case of PT_CLEAR) uint32 mClearBuffers; /// Clear colour (in case of PT_CLEAR) ColourValue mClearColour; - /// Clear depth (in case of PT_CLEAR) - Real mClearDepth; - /// Clear stencil value (in case of PT_CLEAR) - uint32 mClearStencil; + /// Clear depth (in case of PT_CLEAR) + Real mClearDepth; + /// Clear stencil value (in case of PT_CLEAR) + uint32 mClearStencil; /** Inputs (for material used for rendering the quad). An empty string signifies that no input is used */ InputTex mInputs[OGRE_MAX_TEXTURE_LAYERS]; - /// Stencil operation parameters - bool mStencilCheck; - CompareFunction mStencilFunc; - uint32 mStencilRefValue; - uint32 mStencilMask; - StencilOperation mStencilFailOp; - StencilOperation mStencilDepthFailOp; - StencilOperation mStencilPassOp; - bool mStencilTwoSidedOperation; - bool mStencilReadBackAsTexture; + /// Stencil operation parameters + bool mStencilCheck; + CompareFunction mStencilFunc; + uint32 mStencilRefValue; + uint32 mStencilMask; + StencilOperation mStencilFailOp; + StencilOperation mStencilDepthFailOp; + StencilOperation mStencilPassOp; + bool mStencilTwoSidedOperation; + bool mStencilReadBackAsTexture; /// True if quad should not cover whole screen bool mQuadCornerModified; @@ -355,12 +355,12 @@ namespace Ogre { Real mQuadRight; Real mQuadBottom; - bool mQuadFarCorners, mQuadFarCornersViewSpace; - /// The type name of the custom composition pass. - String mCustomType; + bool mQuadFarCorners, mQuadFarCornersViewSpace; + /// The type name of the custom composition pass. + String mCustomType; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreCompositionTargetPass.h b/OgreMain/include/OgreCompositionTargetPass.h index 093f79a357a..55979682623 100644 --- a/OgreMain/include/OgreCompositionTargetPass.h +++ b/OgreMain/include/OgreCompositionTargetPass.h @@ -33,16 +33,16 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Object representing one render to a RenderTarget or Viewport in the Ogre Composition - framework. - */ - class _OgreExport CompositionTargetPass : public CompositorInstAlloc + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Object representing one render to a RenderTarget or Viewport in the Ogre Composition + framework. + */ + class _OgreExport CompositionTargetPass : public CompositorInstAlloc { public: CompositionTargetPass(CompositionTechnique *parent); @@ -84,33 +84,33 @@ namespace Ogre { */ uint32 getVisibilityMask(); - /** Set the material scheme used by this target pass. - @remarks - Only applicable to targets that render the scene as - one of their passes. - @see Technique::setScheme. - */ - void setMaterialScheme(const String& schemeName); - /** Get the material scheme used by this target pass. - @remarks - Only applicable to targets that render the scene as - one of their passes. - @see Technique::setScheme. - */ - const String& getMaterialScheme(void) const; + /** Set the material scheme used by this target pass. + @remarks + Only applicable to targets that render the scene as + one of their passes. + @see Technique::setScheme. + */ + void setMaterialScheme(const String& schemeName); + /** Get the material scheme used by this target pass. + @remarks + Only applicable to targets that render the scene as + one of their passes. + @see Technique::setScheme. + */ + const String& getMaterialScheme(void) const; - /** Set whether shadows are enabled in this target pass. - @remarks - Only applicable to targets that render the scene as - one of their passes. - */ - void setShadowsEnabled(bool enabled); - /** Get whether shadows are enabled in this target pass. - @remarks - Only applicable to targets that render the scene as - one of their passes. - */ - bool getShadowsEnabled(void) const; + /** Set whether shadows are enabled in this target pass. + @remarks + Only applicable to targets that render the scene as + one of their passes. + */ + void setShadowsEnabled(bool enabled); + /** Get whether shadows are enabled in this target pass. + @remarks + Only applicable to targets that render the scene as + one of their passes. + */ + bool getShadowsEnabled(void) const; /** Set the scene LOD bias used by this pass. The default is 1.0, everything below that means lower quality, higher means higher quality. */ @@ -162,14 +162,14 @@ namespace Ogre { uint32 mVisibilityMask; /// LOD bias of this render float mLodBias; - /// Material scheme name - String mMaterialScheme; - /// Shadows option - bool mShadowsEnabled; + /// Material scheme name + String mMaterialScheme; + /// Shadows option + bool mShadowsEnabled; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreCompositionTechnique.h b/OgreMain/include/OgreCompositionTechnique.h index 066d190ef44..00413fa5e16 100644 --- a/OgreMain/include/OgreCompositionTechnique.h +++ b/OgreMain/include/OgreCompositionTechnique.h @@ -34,15 +34,15 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Base composition technique, can be subclassed in plugins. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Base composition technique, can be subclassed in plugins. */ - class _OgreExport CompositionTechnique : public CompositorInstAlloc + class _OgreExport CompositionTechnique : public CompositorInstAlloc { public: CompositionTechnique(Compositor *parent); @@ -63,22 +63,22 @@ namespace Ogre { { public: String name; - //Texture definition being a reference is determined by these two fields not being empty. - String refCompName; //If a reference, the name of the compositor being referenced - String refTexName; //If a reference, the name of the texture in the compositor being referenced + //Texture definition being a reference is determined by these two fields not being empty. + String refCompName; //If a reference, the name of the compositor being referenced + String refTexName; //If a reference, the name of the texture in the compositor being referenced size_t width; // 0 means adapt to target width size_t height; // 0 means adapt to target height - float widthFactor; // multiple of target width to use (if width = 0) - float heightFactor; // multiple of target height to use (if height = 0) + float widthFactor; // multiple of target width to use (if width = 0) + float heightFactor; // multiple of target height to use (if height = 0) PixelFormatList formatList; // more than one means MRT - bool fsaa; // FSAA enabled; true = determine from main target (if render_scene), false = disable - bool hwGammaWrite; // Do sRGB gamma correction on write (only 8-bit per channel formats) - uint16 depthBufferId;//Depth Buffer's pool ID. (unrelated to "pool" variable below) - bool pooled; // whether to use pooled textures for this one + bool fsaa; // FSAA enabled; true = determine from main target (if render_scene), false = disable + bool hwGammaWrite; // Do sRGB gamma correction on write (only 8-bit per channel formats) + uint16 depthBufferId;//Depth Buffer's pool ID. (unrelated to "pool" variable below) + bool pooled; // whether to use pooled textures for this one TextureScope scope; // Which scope has access to this texture - TextureDefinition() :width(0), height(0), widthFactor(1.0f), heightFactor(1.0f), - fsaa(true), hwGammaWrite(false), depthBufferId(1), pooled(false), scope(TS_LOCAL) {} + TextureDefinition() :width(0), height(0), widthFactor(1.0f), heightFactor(1.0f), + fsaa(true), hwGammaWrite(false), depthBufferId(1), pooled(false), scope(TS_LOCAL) {} }; /// Typedefs for several iterators typedef vector::type TargetPasses; @@ -99,11 +99,11 @@ namespace Ogre { */ TextureDefinition *getTextureDefinition(size_t idx); - /** Get a local texture definition with a specific name. - */ - TextureDefinition *getTextureDefinition(const String& name); + /** Get a local texture definition with a specific name. + */ + TextureDefinition *getTextureDefinition(const String& name); - /** Get the number of local texture definitions. + /** Get the number of local texture definitions. */ size_t getNumTextureDefinitions(); @@ -142,24 +142,24 @@ namespace Ogre { CompositionTargetPass *getOutputTargetPass(); /** Determine if this technique is supported on the current rendering device. - @param allowTextureDegradation True to accept a reduction in texture depth + @param allowTextureDegradation True to accept a reduction in texture depth */ virtual bool isSupported(bool allowTextureDegradation); - /** Assign a scheme name to this technique, used to switch between - multiple techniques by choice rather than for hardware compatibility. - */ - virtual void setSchemeName(const String& schemeName); - /** Get the scheme name assigned to this technique. */ - const String& getSchemeName() const { return mSchemeName; } - - /** Set the name of the compositor logic assigned to this technique. - Instances of this technique will be auto-coupled with the matching logic. - */ - void setCompositorLogicName(const String& compositorLogicName) - { mCompositorLogicName = compositorLogicName; } - /** Get the compositor logic name assigned to this technique */ - const String& getCompositorLogicName() const { return mCompositorLogicName; } + /** Assign a scheme name to this technique, used to switch between + multiple techniques by choice rather than for hardware compatibility. + */ + virtual void setSchemeName(const String& schemeName); + /** Get the scheme name assigned to this technique. */ + const String& getSchemeName() const { return mSchemeName; } + + /** Set the name of the compositor logic assigned to this technique. + Instances of this technique will be auto-coupled with the matching logic. + */ + void setCompositorLogicName(const String& compositorLogicName) + { mCompositorLogicName = compositorLogicName; } + /** Get the compositor logic name assigned to this technique */ + const String& getCompositorLogicName() const { return mCompositorLogicName; } /** Get parent object */ Compositor *getParent(); @@ -174,15 +174,15 @@ namespace Ogre { /// Output target pass (can be only one) CompositionTargetPass *mOutputTarget; - /// Optional scheme name - String mSchemeName; - - /// Optional compositor logic name - String mCompositorLogicName; + /// Optional scheme name + String mSchemeName; + + /// Optional compositor logic name + String mCompositorLogicName; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreCompositor.h b/OgreMain/include/OgreCompositor.h index bfa67ffba7b..abf95de570e 100644 --- a/OgreMain/include/OgreCompositor.h +++ b/OgreMain/include/OgreCompositor.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Class representing a Compositor object. Compositors provide the means + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Class representing a Compositor object. Compositors provide the means to flexibly "composite" the final rendering result from multiple scene renders and intermediate operations like rendering fullscreen quads. This makes it possible to apply postfilter effects, HDRI postprocessing, and shadow @@ -104,36 +104,36 @@ namespace Ogre { */ TechniqueIterator getSupportedTechniqueIterator(void); - /** Get a pointer to a supported technique for a given scheme. - @remarks - If there is no specific supported technique with this scheme name, - then the first supported technique with no specific scheme will be returned. - @param schemeName The scheme name you are looking for. Blank means to - look for techniques with no scheme associated - */ - CompositionTechnique *getSupportedTechnique(const String& schemeName = BLANKSTRING); - - /** Get the instance name for a global texture. - @param name The name of the texture in the original compositor definition - @param mrtIndex If name identifies a MRT, which texture attachment to retrieve - @return The instance name for the texture, corresponds to a real texture - */ - const String& getTextureInstanceName(const String& name, size_t mrtIndex); - - /** Get the instance of a global texture. - @param name The name of the texture in the original compositor definition - @param mrtIndex If name identifies a MRT, which texture attachment to retrieve - @return The texture pointer, corresponds to a real texture - */ - TexturePtr getTextureInstance(const String& name, size_t mrtIndex); - - /** Get the render target for a given render texture name. - @remarks - You can use this to add listeners etc, but do not use it to update the - targets manually or any other modifications, the compositor instance - is in charge of this. - */ - RenderTarget* getRenderTarget(const String& name); + /** Get a pointer to a supported technique for a given scheme. + @remarks + If there is no specific supported technique with this scheme name, + then the first supported technique with no specific scheme will be returned. + @param schemeName The scheme name you are looking for. Blank means to + look for techniques with no scheme associated + */ + CompositionTechnique *getSupportedTechnique(const String& schemeName = BLANKSTRING); + + /** Get the instance name for a global texture. + @param name The name of the texture in the original compositor definition + @param mrtIndex If name identifies a MRT, which texture attachment to retrieve + @return The instance name for the texture, corresponds to a real texture + */ + const String& getTextureInstanceName(const String& name, size_t mrtIndex); + + /** Get the instance of a global texture. + @param name The name of the texture in the original compositor definition + @param mrtIndex If name identifies a MRT, which texture attachment to retrieve + @return The texture pointer, corresponds to a real texture + */ + TexturePtr getTextureInstance(const String& name, size_t mrtIndex); + + /** Get the render target for a given render texture name. + @remarks + You can use this to add listeners etc, but do not use it to update the + targets manually or any other modifications, the compositor instance + is in charge of this. + */ + RenderTarget* getRenderTarget(const String& name); protected: /// @copydoc Resource::loadImpl @@ -156,7 +156,7 @@ namespace Ogre { /// re-evaluated. bool mCompilationRequired; - /** Create global rendertextures. + /** Create global rendertextures. */ void createGlobalTextures(); @@ -164,16 +164,16 @@ namespace Ogre { */ void freeGlobalTextures(); - //TODO GSOC : These typedefs are duplicated from CompositorInstance. Solve? - /// Map from name->local texture + //TODO GSOC : These typedefs are duplicated from CompositorInstance. Solve? + /// Map from name->local texture typedef map::type GlobalTextureMap; GlobalTextureMap mGlobalTextures; - /// Store a list of MRTs we've created - typedef map::type GlobalMRTMap; - GlobalMRTMap mGlobalMRTs; + /// Store a list of MRTs we've created + typedef map::type GlobalMRTMap; + GlobalMRTMap mGlobalMRTs; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreCompositorChain.h b/OgreMain/include/OgreCompositorChain.h index d72404b7cbf..2a63609ef2a 100644 --- a/OgreMain/include/OgreCompositorChain.h +++ b/OgreMain/include/OgreCompositorChain.h @@ -133,9 +133,9 @@ namespace Ogre { /** Get viewport that is the target of this chain */ Viewport *getViewport(); - /** Set viewport that is the target of this chain - */ - void _notifyViewport(Viewport* vp); + /** Set viewport that is the target of this chain + */ + void _notifyViewport(Viewport* vp); /** Remove a compositor by pointer. This is internally used by CompositionTechnique to "weak" remove any instanced of a deleted technique. diff --git a/OgreMain/include/OgreCompositorLogic.h b/OgreMain/include/OgreCompositorLogic.h index a91a124d42b..6d0e38d0c7c 100644 --- a/OgreMain/include/OgreCompositorLogic.h +++ b/OgreMain/include/OgreCompositorLogic.h @@ -31,38 +31,38 @@ THE SOFTWARE. #include "OgrePrerequisites.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Interface for compositor logics, which can be automatically binded to compositors, - * allowing per-compositor logic (such as attaching a relevant listener) to happen - * automatically. - * @remarks All methods have empty implementations to not force an implementer into - * extending all of them. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Interface for compositor logics, which can be automatically binded to compositors, + * allowing per-compositor logic (such as attaching a relevant listener) to happen + * automatically. + * @remarks All methods have empty implementations to not force an implementer into + * extending all of them. */ class _OgreExport CompositorLogic { - public: - /** Called when a compositor instance has been created. - @remarks - This happens after its setup was finished, so the chain is also accessible. - This is an ideal method to automatically attach a compositor listener. + public: + /** Called when a compositor instance has been created. + @remarks + This happens after its setup was finished, so the chain is also accessible. + This is an ideal method to automatically attach a compositor listener. */ - virtual void compositorInstanceCreated(CompositorInstance* newInstance) {} + virtual void compositorInstanceCreated(CompositorInstance* newInstance) {} - /** Called when a compositor instance has been destroyed - @remarks - The chain that contained the compositor is still alive during this call. + /** Called when a compositor instance has been destroyed + @remarks + The chain that contained the compositor is still alive during this call. */ - virtual void compositorInstanceDestroyed(CompositorInstance* destroyedInstance) {} + virtual void compositorInstanceDestroyed(CompositorInstance* destroyedInstance) {} - virtual ~CompositorLogic() {} - }; - /** @} */ - /** @} */ + virtual ~CompositorLogic() {} + }; + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreCompositorManager.h b/OgreMain/include/OgreCompositorManager.h index 4fdf1896c5f..349c715e347 100644 --- a/OgreMain/include/OgreCompositorManager.h +++ b/OgreMain/include/OgreCompositorManager.h @@ -38,13 +38,13 @@ namespace Ogre { class Rectangle2D; - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Class for managing Compositor settings for Ogre. Compositors provide the means + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Class for managing Compositor settings for Ogre. Compositors provide the means to flexibly "composite" the final rendering result from multiple scene renders and intermediate operations like rendering fullscreen quads. This makes it possible to apply postfilter effects, HDRI postprocessing, and shadow @@ -72,17 +72,17 @@ namespace Ogre { parse all available .compositor scripts. */ void initialise(void); - /** - * Create a new compositor - * @see ResourceManager::createResource - */ - CompositorPtr create (const String& name, const String& group, - bool isManual = false, ManualResourceLoader* loader = 0, - const NameValuePairList* createParams = 0); + /** + * Create a new compositor + * @see ResourceManager::createResource + */ + CompositorPtr create (const String& name, const String& group, + bool isManual = false, ManualResourceLoader* loader = 0, + const NameValuePairList* createParams = 0); - /// Get a resource by name - /// @see ResourceManager::getResourceByName - CompositorPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + /// Get a resource by name + /// @see ResourceManager::getResourceByName + CompositorPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); /** @see ScriptLoader::parseScript @@ -90,132 +90,132 @@ namespace Ogre { void parseScript(DataStreamPtr& stream, const String& groupName); /** Get the compositor chain for a Viewport. If there is none yet, a new - compositor chain is registered. - XXX We need a _notifyViewportRemoved to find out when this viewport disappears, - so we can destroy its chain as well. + compositor chain is registered. + XXX We need a _notifyViewportRemoved to find out when this viewport disappears, + so we can destroy its chain as well. */ CompositorChain *getCompositorChain(Viewport *vp); - /** Returns whether exists compositor chain for a viewport. + /** Returns whether exists compositor chain for a viewport. */ - bool hasCompositorChain(Viewport *vp) const; + bool hasCompositorChain(Viewport *vp) const; - /** Remove the compositor chain from a viewport if exists. - */ + /** Remove the compositor chain from a viewport if exists. + */ void removeCompositorChain(Viewport *vp); - /** Add a compositor to a viewport. By default, it is added to end of the chain, - after the other compositors. - @param vp Viewport to modify - @param compositor The name of the compositor to apply - @param addPosition At which position to add, defaults to the end (-1). - @return pointer to instance, or 0 if it failed. - */ - CompositorInstance *addCompositor(Viewport *vp, const String &compositor, int addPosition=-1); - - /** Remove a compositor from a viewport - */ - void removeCompositor(Viewport *vp, const String &compositor); - - /** Set the state of a compositor on a viewport to enabled or disabled. - Disabling a compositor stops it from rendering but does not free any resources. - This can be more efficient than using removeCompositor and addCompositor in cases - the filter is switched on and off a lot. - */ - void setCompositorEnabled(Viewport *vp, const String &compositor, bool value); - - /** Get a textured fullscreen 2D rectangle, for internal use. - */ - Renderable *_getTexturedRectangle2D(); - - /** Overridden from ResourceManager since we have to clean up chains too. */ - void removeAll(void); - - /** Internal method for forcing all active compositors to recreate their resources. */ - void _reconstructAllCompositorResources(); - - typedef set::type UniqueTextureSet; - - /** Utility function to get an existing pooled texture matching a given - definition, or creating one if one doesn't exist. It also takes into - account whether a pooled texture has already been supplied to this - same requester already, in which case it won't give the same texture - twice (this is important for example if you request 2 ping-pong textures, - you don't want to get the same texture for both requests! - */ - TexturePtr getPooledTexture(const String& name, const String& localName, - size_t w, size_t h, - PixelFormat f, uint aa, const String& aaHint, bool srgb, UniqueTextureSet& texturesAlreadyAssigned, - CompositorInstance* inst, CompositionTechnique::TextureScope scope); - - /** Free pooled textures from the shared pool (compositor instances still - using them will keep them in memory though). - */ - void freePooledTextures(bool onlyIfUnreferenced = true); - - /** Register a compositor logic for listening in to expecting composition - techniques. - */ - void registerCompositorLogic(const String& name, CompositorLogic* logic); - - /** Removes a listener for compositor logic registered with registerCompositorLogic - */ - void unregisterCompositorLogic(const String& name); - - /** Get a compositor logic by its name - */ - CompositorLogic* getCompositorLogic(const String& name); - - /** Register a custom composition pass. - */ - void registerCustomCompositionPass(const String& name, CustomCompositionPass* customPass); - - /** Get a custom composition pass by its name - */ - CustomCompositionPass* getCustomCompositionPass(const String& name); - - /** - Relocates a compositor chain from one viewport to another - @param sourceVP The viewport to take the chain from - @param destVP The viewport to connect the chain to - */ - void _relocateChain(Viewport* sourceVP, Viewport* destVP); - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static CompositorManager& getSingleton(void); - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static CompositorManager* getSingletonPtr(void); - - - private: + /** Add a compositor to a viewport. By default, it is added to end of the chain, + after the other compositors. + @param vp Viewport to modify + @param compositor The name of the compositor to apply + @param addPosition At which position to add, defaults to the end (-1). + @return pointer to instance, or 0 if it failed. + */ + CompositorInstance *addCompositor(Viewport *vp, const String &compositor, int addPosition=-1); + + /** Remove a compositor from a viewport + */ + void removeCompositor(Viewport *vp, const String &compositor); + + /** Set the state of a compositor on a viewport to enabled or disabled. + Disabling a compositor stops it from rendering but does not free any resources. + This can be more efficient than using removeCompositor and addCompositor in cases + the filter is switched on and off a lot. + */ + void setCompositorEnabled(Viewport *vp, const String &compositor, bool value); + + /** Get a textured fullscreen 2D rectangle, for internal use. + */ + Renderable *_getTexturedRectangle2D(); + + /** Overridden from ResourceManager since we have to clean up chains too. */ + void removeAll(void); + + /** Internal method for forcing all active compositors to recreate their resources. */ + void _reconstructAllCompositorResources(); + + typedef set::type UniqueTextureSet; + + /** Utility function to get an existing pooled texture matching a given + definition, or creating one if one doesn't exist. It also takes into + account whether a pooled texture has already been supplied to this + same requester already, in which case it won't give the same texture + twice (this is important for example if you request 2 ping-pong textures, + you don't want to get the same texture for both requests! + */ + TexturePtr getPooledTexture(const String& name, const String& localName, + size_t w, size_t h, + PixelFormat f, uint aa, const String& aaHint, bool srgb, UniqueTextureSet& texturesAlreadyAssigned, + CompositorInstance* inst, CompositionTechnique::TextureScope scope); + + /** Free pooled textures from the shared pool (compositor instances still + using them will keep them in memory though). + */ + void freePooledTextures(bool onlyIfUnreferenced = true); + + /** Register a compositor logic for listening in to expecting composition + techniques. + */ + void registerCompositorLogic(const String& name, CompositorLogic* logic); + + /** Removes a listener for compositor logic registered with registerCompositorLogic + */ + void unregisterCompositorLogic(const String& name); + + /** Get a compositor logic by its name + */ + CompositorLogic* getCompositorLogic(const String& name); + + /** Register a custom composition pass. + */ + void registerCustomCompositionPass(const String& name, CustomCompositionPass* customPass); + + /** Get a custom composition pass by its name + */ + CustomCompositionPass* getCustomCompositionPass(const String& name); + + /** + Relocates a compositor chain from one viewport to another + @param sourceVP The viewport to take the chain from + @param destVP The viewport to connect the chain to + */ + void _relocateChain(Viewport* sourceVP, Viewport* destVP); + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static CompositorManager& getSingleton(void); + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static CompositorManager* getSingletonPtr(void); + + + private: typedef map::type Chains; Chains mChains; @@ -223,90 +223,90 @@ namespace Ogre { */ void freeChains(); - Rectangle2D *mRectangle; - - /// List of instances - typedef vector::type Instances; - Instances mInstances; - - /// Map of registered compositor logics - typedef map::type CompositorLogicMap; - CompositorLogicMap mCompositorLogics; - - /// Map of registered custom composition passes - typedef map::type CustomCompositionPassMap; - CustomCompositionPassMap mCustomCompositionPasses; - - typedef vector::type TextureList; - typedef VectorIterator TextureIterator; - - struct TextureDef - { - size_t width, height; - PixelFormat format; - uint fsaa; - String fsaaHint; - bool sRGBwrite; - - TextureDef(size_t w, size_t h, PixelFormat f, uint aa, const String& aaHint, bool srgb) - : width(w), height(h), format(f), fsaa(aa), fsaaHint(aaHint), sRGBwrite(srgb) - { - - } - }; - struct TextureDefLess - { - bool _OgreExport operator()(const TextureDef& x, const TextureDef& y) const - { - if (x.format < y.format) - return true; - else if (x.format == y.format) - { - if (x.width < y.width) - return true; - else if (x.width == y.width) - { - if (x.height < y.height) - return true; - else if (x.height == y.height) - { - if (x.fsaa < y.fsaa) - return true; - else if (x.fsaa == y.fsaa) - { - if (x.fsaaHint < y.fsaaHint) - return true; - else if (x.fsaaHint == y.fsaaHint) - { - if (!x.sRGBwrite && y.sRGBwrite) - return true; - } - - } - } - } - } - return false; - } - virtual ~TextureDefLess() {} - }; - typedef map::type TexturesByDef; - TexturesByDef mTexturesByDef; - - typedef std::pair StringPair; - typedef map::type TextureDefMap; - typedef map::type ChainTexturesByDef; - - ChainTexturesByDef mChainTexturesByDef; - - bool isInputPreviousTarget(CompositorInstance* inst, const Ogre::String& localName); - bool isInputPreviousTarget(CompositorInstance* inst, TexturePtr tex); - bool isInputToOutputTarget(CompositorInstance* inst, const Ogre::String& localName); - bool isInputToOutputTarget(CompositorInstance* inst, TexturePtr tex); + Rectangle2D *mRectangle; + + /// List of instances + typedef vector::type Instances; + Instances mInstances; + + /// Map of registered compositor logics + typedef map::type CompositorLogicMap; + CompositorLogicMap mCompositorLogics; + + /// Map of registered custom composition passes + typedef map::type CustomCompositionPassMap; + CustomCompositionPassMap mCustomCompositionPasses; + + typedef vector::type TextureList; + typedef VectorIterator TextureIterator; + + struct TextureDef + { + size_t width, height; + PixelFormat format; + uint fsaa; + String fsaaHint; + bool sRGBwrite; + + TextureDef(size_t w, size_t h, PixelFormat f, uint aa, const String& aaHint, bool srgb) + : width(w), height(h), format(f), fsaa(aa), fsaaHint(aaHint), sRGBwrite(srgb) + { + + } + }; + struct TextureDefLess + { + bool _OgreExport operator()(const TextureDef& x, const TextureDef& y) const + { + if (x.format < y.format) + return true; + else if (x.format == y.format) + { + if (x.width < y.width) + return true; + else if (x.width == y.width) + { + if (x.height < y.height) + return true; + else if (x.height == y.height) + { + if (x.fsaa < y.fsaa) + return true; + else if (x.fsaa == y.fsaa) + { + if (x.fsaaHint < y.fsaaHint) + return true; + else if (x.fsaaHint == y.fsaaHint) + { + if (!x.sRGBwrite && y.sRGBwrite) + return true; + } + + } + } + } + } + return false; + } + virtual ~TextureDefLess() {} + }; + typedef map::type TexturesByDef; + TexturesByDef mTexturesByDef; + + typedef std::pair StringPair; + typedef map::type TextureDefMap; + typedef map::type ChainTexturesByDef; + + ChainTexturesByDef mChainTexturesByDef; + + bool isInputPreviousTarget(CompositorInstance* inst, const Ogre::String& localName); + bool isInputPreviousTarget(CompositorInstance* inst, TexturePtr tex); + bool isInputToOutputTarget(CompositorInstance* inst, const Ogre::String& localName); + bool isInputToOutputTarget(CompositorInstance* inst, TexturePtr tex); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreConfig.h b/OgreMain/include/OgreConfig.h index b5535c08908..ce44a3fbf95 100644 --- a/OgreMain/include/OgreConfig.h +++ b/OgreMain/include/OgreConfig.h @@ -35,7 +35,7 @@ THE SOFTWARE. #include "OgreBuildSettings.h" /** If set to 1, profiling code will be included in the application. When you - are deploying your application you will probably want to set this to 0 */ + are deploying your application you will probably want to set this to 0 */ #ifndef OGRE_PROFILING #define OGRE_PROFILING 0 #endif @@ -56,8 +56,8 @@ THE SOFTWARE. /** If set to 1, Real is typedef'ed to double. Otherwise, Real is typedef'ed to float. Setting this allows you to perform mathematical operations in the - CPU (Quaternion, Vector3 etc) with more precision, but bear in mind that the - GPU still operates in single-precision mode. + CPU (Quaternion, Vector3 etc) with more precision, but bear in mind that the + GPU still operates in single-precision mode. */ #ifndef OGRE_DOUBLE_PRECISION #define OGRE_DOUBLE_PRECISION 0 @@ -98,7 +98,7 @@ THE SOFTWARE. //#define OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR 1 // Doing this will mean Ogre's strings will not be compatible with std::string however #ifndef OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR -# define OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR 0 +# define OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR 0 #endif // enable or disable the memory tracker, recording the memory allocations & tracking leaks @@ -118,21 +118,21 @@ THE SOFTWARE. /** Support for multithreading, there are 3 options OGRE_THREAD_SUPPORT = 0 - No support for threading. + No support for threading. OGRE_THREAD_SUPPORT = 1 - Thread support for background loading, by both loading and constructing resources - in a background thread. Resource management and SharedPtr handling becomes - thread-safe, and resources may be completely loaded in the background. - The places where threading is available are clearly - marked, you should assume state is NOT thread safe unless otherwise - stated in relation to this flag. + Thread support for background loading, by both loading and constructing resources + in a background thread. Resource management and SharedPtr handling becomes + thread-safe, and resources may be completely loaded in the background. + The places where threading is available are clearly + marked, you should assume state is NOT thread safe unless otherwise + stated in relation to this flag. OGRE_THREAD_SUPPORT = 2 - Thread support for background resource preparation. This means that resource - data can streamed into memory in the background, but the final resource - construction (including RenderSystem dependencies) is still done in the primary - thread. Has a lower synchronisation primitive overhead than full threading - while still allowing the major blocking aspects of resource management (I/O) - to be done in the background. + Thread support for background resource preparation. This means that resource + data can streamed into memory in the background, but the final resource + construction (including RenderSystem dependencies) is still done in the primary + thread. Has a lower synchronisation primitive overhead than full threading + while still allowing the major blocking aspects of resource management (I/O) + to be done in the background. */ #ifndef OGRE_THREAD_SUPPORT #define OGRE_THREAD_SUPPORT 0 @@ -144,13 +144,13 @@ OGRE_THREAD_SUPPORT = 2 /** Provider for threading functionality, there are 4 options. OGRE_THREAD_PROVIDER = 0 - No support for threading. + No support for threading. OGRE_THREAD_PROVIDER = 1 - Boost libraries provide threading functionality. + Boost libraries provide threading functionality. OGRE_THREAD_PROVIDER = 2 - Poco libraries provide threading functionality. + Poco libraries provide threading functionality. OGRE_THREAD_PROVIDER = 3 - TBB library provides threading functionality. + TBB library provides threading functionality. */ #ifndef OGRE_THREAD_PROVIDER #define OGRE_THREAD_PROVIDER 0 diff --git a/OgreMain/include/OgreConfigFile.h b/OgreMain/include/OgreConfigFile.h index b44f25e6896..535314d18b2 100644 --- a/OgreMain/include/OgreConfigFile.h +++ b/OgreMain/include/OgreConfigFile.h @@ -37,13 +37,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** Class for quickly loading settings from a text file. + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** Class for quickly loading settings from a text file. @remarks This class is designed to quickly parse a simple file containing key/value pairs, mainly for use in configuration settings. @@ -58,7 +58,7 @@ namespace Ogre { Settings can be optionally grouped in sections, using a header beforehand of the form [SectionName]. */ - class _OgreExport ConfigFile : public ConfigAlloc + class _OgreExport ConfigFile : public ConfigAlloc { public: @@ -70,15 +70,15 @@ namespace Ogre { void load(const String& filename, const String& resourceGroup, const String& separators = "\t:=", bool trimWhitespace = true); /// load from a data stream void load(const DataStreamPtr& stream, const String& separators = "\t:=", bool trimWhitespace = true); - /// load from a filename (not using resource group locations) - void loadDirect(const String& filename, const String& separators = "\t:=", bool trimWhitespace = true); - /// load from a filename (using resource group locations) - void loadFromResourceSystem(const String& filename, const String& resourceGroup, const String& separators = "\t:=", bool trimWhitespace = true); + /// load from a filename (not using resource group locations) + void loadDirect(const String& filename, const String& separators = "\t:=", bool trimWhitespace = true); + /// load from a filename (using resource group locations) + void loadFromResourceSystem(const String& filename, const String& resourceGroup, const String& separators = "\t:=", bool trimWhitespace = true); /** Gets the first setting from the file with the named key. @param key The name of the setting @param section The name of the section it must be in (if any) - @param defaultValue The value to return if the setting is not found + @param defaultValue The value to return if the setting is not found */ String getSetting(const String& key, const String& section = BLANKSTRING, const String& defaultValue = BLANKSTRING) const; /** Gets all settings from the file with the named key. */ @@ -101,8 +101,8 @@ namespace Ogre { protected: SettingsBySection mSettings; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreConfigOptionMap.h b/OgreMain/include/OgreConfigOptionMap.h index 1ddbcf0b9c6..6f6736c980a 100644 --- a/OgreMain/include/OgreConfigOptionMap.h +++ b/OgreMain/include/OgreConfigOptionMap.h @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** Packages the details of a configuration option. + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** Packages the details of a configuration option. @remarks Used for RenderSystem::getConfigOptions. If immutable is true, this option must be disabled for modifying. @@ -55,8 +55,8 @@ namespace Ogre { } ConfigOption; typedef map< String, ConfigOption >::type ConfigOptionMap; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreController.h b/OgreMain/include/OgreController.h index f45c2d9eeed..c5502c79dd9 100644 --- a/OgreMain/include/OgreController.h +++ b/OgreMain/include/OgreController.h @@ -34,15 +34,15 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - - - /** Subclasses of this class are responsible for performing a function on an input value for a Controller. + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + + + /** Subclasses of this class are responsible for performing a function on an input value for a Controller. @remarks This abstract class provides the interface that needs to be supported for a custom function which can be 'plugged in' to a Controller instance, which controls some object value based on an input value. @@ -51,8 +51,8 @@ namespace Ogre { @par You are free to create your own subclasses in order to define any function you wish. */ - template - class ControllerFunction : public ControllerAlloc + template + class ControllerFunction : public ControllerAlloc { protected: /// If true, function will add input values together and wrap at 1.0 before evaluating @@ -75,7 +75,7 @@ namespace Ogre { return mDeltaCount; } else - { + { return input; } } @@ -92,7 +92,7 @@ namespace Ogre { mDeltaCount = 0; } - virtual ~ControllerFunction() {} + virtual ~ControllerFunction() {} virtual T calculate(T sourceValue) = 0; }; @@ -100,8 +100,8 @@ namespace Ogre { /** Can either be used as an input or output value. */ - template - class ControllerValue : public ControllerAlloc + template + class ControllerValue : public ControllerAlloc { public: @@ -131,8 +131,8 @@ namespace Ogre { ControllerFunction */ - template - class Controller : public ControllerAlloc + template + class Controller : public ControllerAlloc { protected: /// Source value @@ -141,7 +141,7 @@ namespace Ogre { SharedPtr< ControllerValue > mDest; /// Function SharedPtr< ControllerFunction > mFunc; - /// Controller is enabled or not + /// Controller is enabled or not bool mEnabled; @@ -153,80 +153,80 @@ namespace Ogre { with the Controller when it is deleted (they can be shared) so you must delete these as appropriate. */ Controller(const SharedPtr< ControllerValue >& src, - const SharedPtr< ControllerValue >& dest, const SharedPtr< ControllerFunction >& func) - : mSource(src), mDest(dest), mFunc(func) - { - mEnabled = true; - } + const SharedPtr< ControllerValue >& dest, const SharedPtr< ControllerFunction >& func) + : mSource(src), mDest(dest), mFunc(func) + { + mEnabled = true; + } /** Default d-tor. */ - virtual ~Controller() {} + virtual ~Controller() {} - /// Sets the input controller value + /// Sets the input controller value void setSource(const SharedPtr< ControllerValue >& src) - { - mSource = src; - } - /// Gets the input controller value + { + mSource = src; + } + /// Gets the input controller value const SharedPtr< ControllerValue >& getSource(void) const - { - return mSource; - } - /// Sets the output controller value + { + return mSource; + } + /// Sets the output controller value void setDestination(const SharedPtr< ControllerValue >& dest) - { - mDest = dest; - } + { + mDest = dest; + } - /// Gets the output controller value + /// Gets the output controller value const SharedPtr< ControllerValue >& getDestination(void) const - { - return mDest; - } + { + return mDest; + } /// Returns true if this controller is currently enabled bool getEnabled(void) const - { - return mEnabled; - } + { + return mEnabled; + } /// Sets whether this controller is enabled void setEnabled(bool enabled) - { - mEnabled = enabled; - } + { + mEnabled = enabled; + } /** Sets the function object to be used by this controller. */ void setFunction(const SharedPtr< ControllerFunction >& func) - { - mFunc = func; - } + { + mFunc = func; + } /** Returns a pointer to the function object used by this controller. */ const SharedPtr< ControllerFunction >& getFunction(void) const - { - return mFunc; - } - - /** Tells this controller to map it's input controller value - to it's output controller value, via the controller function. - @remarks - This method is called automatically every frame by ControllerManager. - */ - void update(void) - { - if(mEnabled) - mDest->setValue(mFunc->calculate(mSource->getValue())); - } + { + return mFunc; + } + + /** Tells this controller to map it's input controller value + to it's output controller value, via the controller function. + @remarks + This method is called automatically every frame by ControllerManager. + */ + void update(void) + { + if(mEnabled) + mDest->setValue(mFunc->calculate(mSource->getValue())); + } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreConvexBody.h b/OgreMain/include/OgreConvexBody.h index 39258e75b6f..07cd1fd81e7 100644 --- a/OgreMain/include/OgreConvexBody.h +++ b/OgreMain/include/OgreConvexBody.h @@ -5,7 +5,7 @@ This source file is part of OGRE For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd -Copyright (c) 2006 Matthias Fink, netAllied GmbH +Copyright (c) 2006 Matthias Fink, netAllied GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -37,223 +37,223 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Holds a solid representation of a convex body. - @remarks - Administers a convex body. All polygons of the body are convex and - planar. Several operations may be applied, ranging from intersection - to join where each result it itself a convex body. - */ - class _OgreExport ConvexBody - { - public: - typedef vector< Polygon* >::type PolygonList; - - protected: - PolygonList mPolygons; - - // Static 'free list' of polygons to save reallocation, shared between all bodies - static PolygonList msFreePolygons; + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Holds a solid representation of a convex body. + @remarks + Administers a convex body. All polygons of the body are convex and + planar. Several operations may be applied, ranging from intersection + to join where each result it itself a convex body. + */ + class _OgreExport ConvexBody + { + public: + typedef vector< Polygon* >::type PolygonList; + + protected: + PolygonList mPolygons; + + // Static 'free list' of polygons to save reallocation, shared between all bodies + static PolygonList msFreePolygons; #if OGRE_THREAD_SUPPORT - OGRE_STATIC_MUTEX(msFreePolygonsMutex); + OGRE_STATIC_MUTEX(msFreePolygonsMutex); #endif - public: - ConvexBody(); - ~ConvexBody(); - ConvexBody( const ConvexBody& cpy ); - - /** Build a new polygon representation from a frustum. - */ - void define(const Frustum& frustum); - - /** Build a new polygon representation from an AAB. - */ - void define(const AxisAlignedBox& aab); - - /** Clips the body with a frustum. The resulting holes - are filled with new polygons. - */ - void clip( const Frustum& frustum ); - - /** Clips the body with an AAB. The resulting holes - are filled with new polygons. - */ - void clip( const AxisAlignedBox& aab ); - - /** Clips the body with another body. - */ - void clip(const ConvexBody& body); - - /** Clips the object by the positive half space of a plane - */ - void clip(const Plane& pl, bool keepNegative = true); - - /** Extends the existing body to incorporate the passed in point as a - convex hull. - @remarks - You must already have constructed a basic body using a 'construct' - method. - */ - void extend(const Vector3& pt); - - /** Resets the object. - */ - void reset( void ); - - /** Returns the current number of polygons. - */ - size_t getPolygonCount( void ) const; - - /** Returns the number of vertices for a polygon - */ - size_t getVertexCount( size_t poly ) const; - - /** Returns a polygon. - */ - const Polygon& getPolygon( size_t poly ) const; - - /** Returns a specific vertex of a polygon. - */ - const Vector3& getVertex( size_t poly, size_t vertex ) const; - - /** Returns the normal of a specified polygon. - */ - const Vector3& getNormal( size_t poly ); - - /** Returns an AABB representation. - */ - AxisAlignedBox getAABB( void ) const; - - /** Checks if the body has a closed hull. - */ - bool hasClosedHull( void ) const; - - /** Merges all neighboring polygons into one single polygon if they are - lay in the same plane. - */ - void mergePolygons( void ); - - /** Determines if the current object is equal to the compared one. - */ - bool operator == ( const ConvexBody& rhs ) const; - - /** Determines if the current object is not equal to the compared one. - */ - bool operator != ( const ConvexBody& rhs ) const - { return !( *this == rhs ); } - - /** Prints out the body with all its polygons. - */ - _OgreExport friend std::ostream& operator<< ( std::ostream& strm, const ConvexBody& body ); - - /** Log details of this body */ - void logInfo() const; - - /// Initialise the internal polygon pool used to minimise allocations - static void _initialisePool(); - /// Tear down the internal polygon pool used to minimise allocations - static void _destroyPool(); - - - protected: - /** Get a new polygon from the pool. - */ - static Polygon* allocatePolygon(); - /** Release a polygon back tot he pool. */ - static void freePolygon(Polygon* poly); - /** Inserts a polygon at a particular point in the body. - @note - After this method is called, the ConvexBody 'owns' this Polygon - and will be responsible for deleting it. - */ - void insertPolygon(Polygon* pdata, size_t poly); - /** Inserts a polygon at the end. - @note - After this method is called, the ConvexBody 'owns' this Polygon - and will be responsible for deleting it. - */ - void insertPolygon(Polygon* pdata); - - /** Inserts a vertex for a polygon at a particular point. - @note - No checks are done whether the assembled polygon is (still) planar, - the caller must ensure that this is the case. - */ - void insertVertex(size_t poly, const Vector3& vdata, size_t vertex); - /** Inserts a vertex for a polygon at the end. - @note - No checks are done whether the assembled polygon is (still) planar, - the caller must ensure that this is the case. - */ - void insertVertex(size_t poly, const Vector3& vdata); - /** Deletes a specific polygon. - */ - void deletePolygon(size_t poly); - - /** Removes a specific polygon from the body without deleting it. - @note - The retrieved polygon needs to be deleted later by the caller. - */ - Polygon* unlinkPolygon(size_t poly); - - /** Moves all polygons from the parameter body to this instance. - @note Both the passed in object and this instance are modified - */ - void moveDataFromBody(ConvexBody& body); - - /** Deletes a specific vertex of a specific polygon. - */ - void deleteVertex(size_t poly, size_t vertex); - - /** Replace a polygon at a particular index. - @note Again, the passed in polygon is owned by this object after this - call returns, and this object is resonsible for deleting it. - */ - void setPolygon(Polygon* pdata, size_t poly ); - - /** Replace a specific vertex of a polygon. - @note - No checks are done whether the assembled polygon is (still) planar, - the caller must ensure that this is the case. - */ - void setVertex( size_t poly, const Vector3& vdata, size_t vertex ); - - /** Returns the single edges in an EdgeMap (= edges where one side is a vertex and the - other is empty space (a hole in the body)). - */ - Polygon::EdgeMap getSingleEdges() const; - - /** Stores the edges of a specific polygon in a passed in structure. - */ - void storeEdgesOfPolygon(size_t poly, Polygon::EdgeMap *edgeMap) const; - - /** Allocates space for an specified amount of polygons with - each of them having a specified number of vertices. - @note - Old data (if available) will be erased. - */ - void allocateSpace(size_t numPolygons, size_t numVertices); - - /** Searches for a pair (an edge) in the intersectionList with an entry - that equals vec, and removes it from the passed in list. - @param vec The vertex to search for in intersectionEdges - @param intersectionEdges A list of edges, which is updated if a match is found - @param vNext A reference to a vector which will be filled with the other - vertex at the matching edge, if found. - @return True if a match was found - */ - bool findAndEraseEdgePair(const Vector3& vec, - Polygon::EdgeMap& intersectionEdges, Vector3& vNext ) const; - - }; - /** @} */ - /** @} */ + public: + ConvexBody(); + ~ConvexBody(); + ConvexBody( const ConvexBody& cpy ); + + /** Build a new polygon representation from a frustum. + */ + void define(const Frustum& frustum); + + /** Build a new polygon representation from an AAB. + */ + void define(const AxisAlignedBox& aab); + + /** Clips the body with a frustum. The resulting holes + are filled with new polygons. + */ + void clip( const Frustum& frustum ); + + /** Clips the body with an AAB. The resulting holes + are filled with new polygons. + */ + void clip( const AxisAlignedBox& aab ); + + /** Clips the body with another body. + */ + void clip(const ConvexBody& body); + + /** Clips the object by the positive half space of a plane + */ + void clip(const Plane& pl, bool keepNegative = true); + + /** Extends the existing body to incorporate the passed in point as a + convex hull. + @remarks + You must already have constructed a basic body using a 'construct' + method. + */ + void extend(const Vector3& pt); + + /** Resets the object. + */ + void reset( void ); + + /** Returns the current number of polygons. + */ + size_t getPolygonCount( void ) const; + + /** Returns the number of vertices for a polygon + */ + size_t getVertexCount( size_t poly ) const; + + /** Returns a polygon. + */ + const Polygon& getPolygon( size_t poly ) const; + + /** Returns a specific vertex of a polygon. + */ + const Vector3& getVertex( size_t poly, size_t vertex ) const; + + /** Returns the normal of a specified polygon. + */ + const Vector3& getNormal( size_t poly ); + + /** Returns an AABB representation. + */ + AxisAlignedBox getAABB( void ) const; + + /** Checks if the body has a closed hull. + */ + bool hasClosedHull( void ) const; + + /** Merges all neighboring polygons into one single polygon if they are + lay in the same plane. + */ + void mergePolygons( void ); + + /** Determines if the current object is equal to the compared one. + */ + bool operator == ( const ConvexBody& rhs ) const; + + /** Determines if the current object is not equal to the compared one. + */ + bool operator != ( const ConvexBody& rhs ) const + { return !( *this == rhs ); } + + /** Prints out the body with all its polygons. + */ + _OgreExport friend std::ostream& operator<< ( std::ostream& strm, const ConvexBody& body ); + + /** Log details of this body */ + void logInfo() const; + + /// Initialise the internal polygon pool used to minimise allocations + static void _initialisePool(); + /// Tear down the internal polygon pool used to minimise allocations + static void _destroyPool(); + + + protected: + /** Get a new polygon from the pool. + */ + static Polygon* allocatePolygon(); + /** Release a polygon back tot he pool. */ + static void freePolygon(Polygon* poly); + /** Inserts a polygon at a particular point in the body. + @note + After this method is called, the ConvexBody 'owns' this Polygon + and will be responsible for deleting it. + */ + void insertPolygon(Polygon* pdata, size_t poly); + /** Inserts a polygon at the end. + @note + After this method is called, the ConvexBody 'owns' this Polygon + and will be responsible for deleting it. + */ + void insertPolygon(Polygon* pdata); + + /** Inserts a vertex for a polygon at a particular point. + @note + No checks are done whether the assembled polygon is (still) planar, + the caller must ensure that this is the case. + */ + void insertVertex(size_t poly, const Vector3& vdata, size_t vertex); + /** Inserts a vertex for a polygon at the end. + @note + No checks are done whether the assembled polygon is (still) planar, + the caller must ensure that this is the case. + */ + void insertVertex(size_t poly, const Vector3& vdata); + /** Deletes a specific polygon. + */ + void deletePolygon(size_t poly); + + /** Removes a specific polygon from the body without deleting it. + @note + The retrieved polygon needs to be deleted later by the caller. + */ + Polygon* unlinkPolygon(size_t poly); + + /** Moves all polygons from the parameter body to this instance. + @note Both the passed in object and this instance are modified + */ + void moveDataFromBody(ConvexBody& body); + + /** Deletes a specific vertex of a specific polygon. + */ + void deleteVertex(size_t poly, size_t vertex); + + /** Replace a polygon at a particular index. + @note Again, the passed in polygon is owned by this object after this + call returns, and this object is resonsible for deleting it. + */ + void setPolygon(Polygon* pdata, size_t poly ); + + /** Replace a specific vertex of a polygon. + @note + No checks are done whether the assembled polygon is (still) planar, + the caller must ensure that this is the case. + */ + void setVertex( size_t poly, const Vector3& vdata, size_t vertex ); + + /** Returns the single edges in an EdgeMap (= edges where one side is a vertex and the + other is empty space (a hole in the body)). + */ + Polygon::EdgeMap getSingleEdges() const; + + /** Stores the edges of a specific polygon in a passed in structure. + */ + void storeEdgesOfPolygon(size_t poly, Polygon::EdgeMap *edgeMap) const; + + /** Allocates space for an specified amount of polygons with + each of them having a specified number of vertices. + @note + Old data (if available) will be erased. + */ + void allocateSpace(size_t numPolygons, size_t numVertices); + + /** Searches for a pair (an edge) in the intersectionList with an entry + that equals vec, and removes it from the passed in list. + @param vec The vertex to search for in intersectionEdges + @param intersectionEdges A list of edges, which is updated if a match is found + @param vNext A reference to a vector which will be filled with the other + vertex at the matching edge, if found. + @return True if a match was found + */ + bool findAndEraseEdgePair(const Vector3& vec, + Polygon::EdgeMap& intersectionEdges, Vector3& vNext ) const; + + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreCustomCompositionPass.h b/OgreMain/include/OgreCustomCompositionPass.h index 7baa4c132d5..19ebf1d7b82 100644 --- a/OgreMain/include/OgreCustomCompositionPass.h +++ b/OgreMain/include/OgreCustomCompositionPass.h @@ -32,34 +32,34 @@ THE SOFTWARE. #include "OgreCompositionPass.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Interface for custom composition passes, allowing custom operations (in addition to - * the quad, scene and clear operations) in composition passes. - * @see CompositorManager::registerCustomCompositionPass + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Interface for custom composition passes, allowing custom operations (in addition to + * the quad, scene and clear operations) in composition passes. + * @see CompositorManager::registerCustomCompositionPass */ class _OgreExport CustomCompositionPass { - public: - /** Create a custom composition operation. - @param pass The CompositionPass that triggered the request - @param instance The compositor instance that this operation will be performed in - @remarks This call only happens once during creation. The RenderSystemOperation will - get called each render. - @remarks The created operation must be instanciated using the OGRE_NEW macro. - */ - virtual CompositorInstance::RenderSystemOperation* createOperation( - CompositorInstance* instance, const CompositionPass* pass) = 0; + public: + /** Create a custom composition operation. + @param pass The CompositionPass that triggered the request + @param instance The compositor instance that this operation will be performed in + @remarks This call only happens once during creation. The RenderSystemOperation will + get called each render. + @remarks The created operation must be instanciated using the OGRE_NEW macro. + */ + virtual CompositorInstance::RenderSystemOperation* createOperation( + CompositorInstance* instance, const CompositionPass* pass) = 0; - protected: - virtual ~CustomCompositionPass() {} - }; - /** @} */ - /** @} */ + protected: + virtual ~CustomCompositionPass() {} + }; + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreDDSCodec.h b/OgreMain/include/OgreDDSCodec.h index 11b91d3f4f6..516cfee727c 100644 --- a/OgreMain/include/OgreDDSCodec.h +++ b/OgreMain/include/OgreDDSCodec.h @@ -30,46 +30,46 @@ THE SOFTWARE. #include "OgreImageCodec.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Image - * @{ - */ - - // Forward declarations - struct DXTColourBlock; - struct DXTExplicitAlphaBlock; - struct DXTInterpolatedAlphaBlock; + /** \addtogroup Core + * @{ + */ + /** \addtogroup Image + * @{ + */ + + // Forward declarations + struct DXTColourBlock; + struct DXTExplicitAlphaBlock; + struct DXTInterpolatedAlphaBlock; /** Codec specialized in loading DDS (Direct Draw Surface) images. - @remarks - We implement our own codec here since we need to be able to keep DXT - data compressed if the card supports it. + @remarks + We implement our own codec here since we need to be able to keep DXT + data compressed if the card supports it. */ class _OgreExport DDSCodec : public ImageCodec { private: String mType; - void flipEndian(void * pData, size_t size, size_t count) const; - void flipEndian(void * pData, size_t size) const; + void flipEndian(void * pData, size_t size, size_t count) const; + void flipEndian(void * pData, size_t size) const; - PixelFormat convertFourCCFormat(uint32 fourcc) const; - PixelFormat convertDXToOgreFormat(uint32 fourcc) const; - PixelFormat convertPixelFormat(uint32 rgbBits, uint32 rMask, - uint32 gMask, uint32 bMask, uint32 aMask) const; + PixelFormat convertFourCCFormat(uint32 fourcc) const; + PixelFormat convertDXToOgreFormat(uint32 fourcc) const; + PixelFormat convertPixelFormat(uint32 rgbBits, uint32 rMask, + uint32 gMask, uint32 bMask, uint32 aMask) const; - /// Unpack DXT colours into array of 16 colour values - void unpackDXTColour(PixelFormat pf, const DXTColourBlock& block, ColourValue* pCol) const; - /// Unpack DXT alphas into array of 16 colour values - void unpackDXTAlpha(const DXTExplicitAlphaBlock& block, ColourValue* pCol) const; - /// Unpack DXT alphas into array of 16 colour values - void unpackDXTAlpha(const DXTInterpolatedAlphaBlock& block, ColourValue* pCol) const; + /// Unpack DXT colours into array of 16 colour values + void unpackDXTColour(PixelFormat pf, const DXTColourBlock& block, ColourValue* pCol) const; + /// Unpack DXT alphas into array of 16 colour values + void unpackDXTAlpha(const DXTExplicitAlphaBlock& block, ColourValue* pCol) const; + /// Unpack DXT alphas into array of 16 colour values + void unpackDXTAlpha(const DXTInterpolatedAlphaBlock& block, ColourValue* pCol) const; - /// Single registered codec instance - static DDSCodec* msInstance; - public: + /// Single registered codec instance + static DDSCodec* msInstance; + public: DDSCodec(); virtual ~DDSCodec() { } @@ -79,19 +79,19 @@ namespace Ogre { void encodeToFile(MemoryDataStreamPtr& input, const String& outFileName, CodecDataPtr& pData) const; /// @copydoc Codec::decode DecodeResult decode(DataStreamPtr& input) const; - /// @copydoc Codec::magicNumberToFileExt - String magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const; + /// @copydoc Codec::magicNumberToFileExt + String magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const; virtual String getType() const; - /// Static method to startup and register the DDS codec - static void startup(void); - /// Static method to shutdown and unregister the DDS codec - static void shutdown(void); + /// Static method to startup and register the DDS codec + static void startup(void); + /// Static method to shutdown and unregister the DDS codec + static void shutdown(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreDataStream.h b/OgreMain/include/OgreDataStream.h index 92602dd8e20..9a764329414 100644 --- a/OgreMain/include/OgreDataStream.h +++ b/OgreMain/include/OgreDataStream.h @@ -37,362 +37,362 @@ namespace Ogre { typedef _StringBase String; - /** Template version of cache based on static array. - 'cacheSize' defines size of cache in bytes. */ - template - class StaticCache - { - protected: - /// Static buffer - char mBuffer[cacheSize]; - - /// Number of bytes valid in cache (written from the beginning of static buffer) - size_t mValidBytes; - /// Current read position - size_t mPos; - - public: - /// Constructor - StaticCache() - { - mValidBytes = 0; - mPos = 0; + /** Template version of cache based on static array. + 'cacheSize' defines size of cache in bytes. */ + template + class StaticCache + { + protected: + /// Static buffer + char mBuffer[cacheSize]; + + /// Number of bytes valid in cache (written from the beginning of static buffer) + size_t mValidBytes; + /// Current read position + size_t mPos; + + public: + /// Constructor + StaticCache() + { + mValidBytes = 0; + mPos = 0; memset(mBuffer, 0, cacheSize); - } - - /** Cache data pointed by 'buf'. If 'count' is greater than cache size, we cache only last bytes. - Returns number of bytes written to cache. */ - size_t cacheData(const void* buf, size_t count) - { - assert(avail() == 0 && "It is assumed that you cache data only after you have read everything."); - - if (count < cacheSize) - { - // number of bytes written is less than total size of cache - if (count + mValidBytes <= cacheSize) - { - // just append - memcpy(mBuffer + mValidBytes, buf, count); - mValidBytes += count; - } - else - { - size_t begOff = count - (cacheSize - mValidBytes); - // override old cache content in the beginning - memmove(mBuffer, mBuffer + begOff, mValidBytes - begOff); - // append new data - memcpy(mBuffer + cacheSize - count, buf, count); - mValidBytes = cacheSize; - } - mPos = mValidBytes; - return count; - } - else - { - // discard all - memcpy(mBuffer, (const char*)buf + count - cacheSize, cacheSize); - mValidBytes = mPos = cacheSize; - return cacheSize; - } - } - /** Read data from cache to 'buf' (maximum 'count' bytes). Returns number of bytes read from cache. */ - size_t read(void* buf, size_t count) - { - size_t rb = avail(); - rb = (rb < count) ? rb : count; - memcpy(buf, mBuffer + mPos, rb); - mPos += rb; - return rb; - } - - /** Step back in cached stream by 'count' bytes. Returns 'true' if cache contains resulting position. */ - bool rewind(size_t count) - { - if (mPos < count) - { - clear(); - return false; - } - else - { - mPos -= count; - return true; - } - } - /** Step forward in cached stream by 'count' bytes. Returns 'true' if cache contains resulting position. */ - bool ff(size_t count) - { - if (avail() < count) - { - clear(); - return false; - } - else - { - mPos += count; - return true; - } - } - - /** Returns number of bytes available for reading in cache after rewinding. */ - size_t avail() const - { - return mValidBytes - mPos; - } - - /** Clear the cache */ - void clear() - { - mValidBytes = 0; - mPos = 0; - } - }; - - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - - /** General purpose class used for encapsulating the reading and writing of data. - @remarks - This class performs basically the same tasks as std::basic_istream, - except that it does not have any formatting capabilities, and is - designed to be subclassed to receive data from multiple sources, - including libraries which have no compatibility with the STL's - stream interfaces. As such, this is an abstraction of a set of - wrapper classes which pretend to be standard stream classes but - can actually be implemented quite differently. - @par - Generally, if a plugin or application provides an ArchiveFactory, - it should also provide a DataStream subclass which will be used - to stream data out of that Archive implementation, unless it can - use one of the common implementations included. - @note - Ogre makes no guarantees about thread safety, for performance reasons. - If you wish to access stream data asynchronously then you should - organise your own mutexes to avoid race conditions. - */ - class _OgreExport DataStream : public StreamAlloc - { - public: - enum AccessMode - { - READ = 1, - WRITE = 2 - }; - protected: - /// The name (e.g. resource name) that can be used to identify the source for this data (optional) - String mName; + } + + /** Cache data pointed by 'buf'. If 'count' is greater than cache size, we cache only last bytes. + Returns number of bytes written to cache. */ + size_t cacheData(const void* buf, size_t count) + { + assert(avail() == 0 && "It is assumed that you cache data only after you have read everything."); + + if (count < cacheSize) + { + // number of bytes written is less than total size of cache + if (count + mValidBytes <= cacheSize) + { + // just append + memcpy(mBuffer + mValidBytes, buf, count); + mValidBytes += count; + } + else + { + size_t begOff = count - (cacheSize - mValidBytes); + // override old cache content in the beginning + memmove(mBuffer, mBuffer + begOff, mValidBytes - begOff); + // append new data + memcpy(mBuffer + cacheSize - count, buf, count); + mValidBytes = cacheSize; + } + mPos = mValidBytes; + return count; + } + else + { + // discard all + memcpy(mBuffer, (const char*)buf + count - cacheSize, cacheSize); + mValidBytes = mPos = cacheSize; + return cacheSize; + } + } + /** Read data from cache to 'buf' (maximum 'count' bytes). Returns number of bytes read from cache. */ + size_t read(void* buf, size_t count) + { + size_t rb = avail(); + rb = (rb < count) ? rb : count; + memcpy(buf, mBuffer + mPos, rb); + mPos += rb; + return rb; + } + + /** Step back in cached stream by 'count' bytes. Returns 'true' if cache contains resulting position. */ + bool rewind(size_t count) + { + if (mPos < count) + { + clear(); + return false; + } + else + { + mPos -= count; + return true; + } + } + /** Step forward in cached stream by 'count' bytes. Returns 'true' if cache contains resulting position. */ + bool ff(size_t count) + { + if (avail() < count) + { + clear(); + return false; + } + else + { + mPos += count; + return true; + } + } + + /** Returns number of bytes available for reading in cache after rewinding. */ + size_t avail() const + { + return mValidBytes - mPos; + } + + /** Clear the cache */ + void clear() + { + mValidBytes = 0; + mPos = 0; + } + }; + + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + + /** General purpose class used for encapsulating the reading and writing of data. + @remarks + This class performs basically the same tasks as std::basic_istream, + except that it does not have any formatting capabilities, and is + designed to be subclassed to receive data from multiple sources, + including libraries which have no compatibility with the STL's + stream interfaces. As such, this is an abstraction of a set of + wrapper classes which pretend to be standard stream classes but + can actually be implemented quite differently. + @par + Generally, if a plugin or application provides an ArchiveFactory, + it should also provide a DataStream subclass which will be used + to stream data out of that Archive implementation, unless it can + use one of the common implementations included. + @note + Ogre makes no guarantees about thread safety, for performance reasons. + If you wish to access stream data asynchronously then you should + organise your own mutexes to avoid race conditions. + */ + class _OgreExport DataStream : public StreamAlloc + { + public: + enum AccessMode + { + READ = 1, + WRITE = 2 + }; + protected: + /// The name (e.g. resource name) that can be used to identify the source for this data (optional) + String mName; /// Size of the data in the stream (may be 0 if size cannot be determined) size_t mSize; - /// What type of access is allowed (AccessMode) - uint16 mAccess; + /// What type of access is allowed (AccessMode) + uint16 mAccess; #define OGRE_STREAM_TEMP_SIZE 128 - public: - /// Constructor for creating unnamed streams + public: + /// Constructor for creating unnamed streams DataStream(uint16 accessMode = READ) : mSize(0), mAccess(accessMode) {} - /// Constructor for creating named streams - DataStream(const String& name, uint16 accessMode = READ) - : mName(name), mSize(0), mAccess(accessMode) {} - /// Returns the name of the stream, if it has one. - const String& getName(void) { return mName; } - /// Gets the access mode of the stream - uint16 getAccessMode() const { return mAccess; } - /** Reports whether this stream is readable. */ - virtual bool isReadable() const { return (mAccess & READ) != 0; } - /** Reports whether this stream is writeable. */ - virtual bool isWriteable() const { return (mAccess & WRITE) != 0; } + /// Constructor for creating named streams + DataStream(const String& name, uint16 accessMode = READ) + : mName(name), mSize(0), mAccess(accessMode) {} + /// Returns the name of the stream, if it has one. + const String& getName(void) { return mName; } + /// Gets the access mode of the stream + uint16 getAccessMode() const { return mAccess; } + /** Reports whether this stream is readable. */ + virtual bool isReadable() const { return (mAccess & READ) != 0; } + /** Reports whether this stream is writeable. */ + virtual bool isWriteable() const { return (mAccess & WRITE) != 0; } virtual ~DataStream() {} - // Streaming operators + // Streaming operators template DataStream& operator>>(T& val); - /** Read the requisite number of bytes from the stream, - stopping at the end of the file. - @param buf Reference to a buffer pointer - @param count Number of bytes to read - @return The number of bytes read - */ - virtual size_t read(void* buf, size_t count) = 0; - /** Write the requisite number of bytes from the stream (only applicable to - streams that are not read-only) - @param buf Pointer to a buffer containing the bytes to write - @param count Number of bytes to write - @return The number of bytes written - */ - virtual size_t write(const void* buf, size_t count) - { + /** Read the requisite number of bytes from the stream, + stopping at the end of the file. + @param buf Reference to a buffer pointer + @param count Number of bytes to read + @return The number of bytes read + */ + virtual size_t read(void* buf, size_t count) = 0; + /** Write the requisite number of bytes from the stream (only applicable to + streams that are not read-only) + @param buf Pointer to a buffer containing the bytes to write + @param count Number of bytes to write + @return The number of bytes written + */ + virtual size_t write(const void* buf, size_t count) + { (void)buf; (void)count; - // default to not supported - return 0; - } - - /** Get a single line from the stream. - @remarks - The delimiter character is not included in the data - returned, and it is skipped over so the next read will occur - after it. The buffer contents will include a - terminating character. + // default to not supported + return 0; + } + + /** Get a single line from the stream. + @remarks + The delimiter character is not included in the data + returned, and it is skipped over so the next read will occur + after it. The buffer contents will include a + terminating character. @note If you used this function, you must open the stream in binary mode, otherwise, it'll produce unexpected results. - @param buf Reference to a buffer pointer - @param maxCount The maximum length of data to be read, excluding the terminating character - @param delim The delimiter to stop at - @return The number of bytes read, excluding the terminating character - */ - virtual size_t readLine(char* buf, size_t maxCount, const String& delim = "\n"); - - /** Returns a String containing the next line of data, optionally - trimmed for whitespace. - @remarks - This is a convenience method for text streams only, allowing you to - retrieve a String object containing the next line of data. The data - is read up to the next newline character and the result trimmed if - required. + @param buf Reference to a buffer pointer + @param maxCount The maximum length of data to be read, excluding the terminating character + @param delim The delimiter to stop at + @return The number of bytes read, excluding the terminating character + */ + virtual size_t readLine(char* buf, size_t maxCount, const String& delim = "\n"); + + /** Returns a String containing the next line of data, optionally + trimmed for whitespace. + @remarks + This is a convenience method for text streams only, allowing you to + retrieve a String object containing the next line of data. The data + is read up to the next newline character and the result trimmed if + required. @note If you used this function, you must open the stream in binary mode, otherwise, it'll produce unexpected results. - @param - trimAfter If true, the line is trimmed for whitespace (as in - String.trim(true,true)) - */ - virtual String getLine( bool trimAfter = true ); - - /** Returns a String containing the entire stream. - @remarks - This is a convenience method for text streams only, allowing you to - retrieve a String object containing all the data in the stream. - */ - virtual String getAsString(void); - - /** Skip a single line from the stream. + @param + trimAfter If true, the line is trimmed for whitespace (as in + String.trim(true,true)) + */ + virtual String getLine( bool trimAfter = true ); + + /** Returns a String containing the entire stream. + @remarks + This is a convenience method for text streams only, allowing you to + retrieve a String object containing all the data in the stream. + */ + virtual String getAsString(void); + + /** Skip a single line from the stream. @note If you used this function, you must open the stream in binary mode, otherwise, it'll produce unexpected results. - @param delim The delimiter(s) to stop at - @return The number of bytes skipped - */ - virtual size_t skipLine(const String& delim = "\n"); - - /** Skip a defined number of bytes. This can also be a negative value, in which case - the file pointer rewinds a defined number of bytes. */ - virtual void skip(long count) = 0; - - /** Repositions the read point to a specified byte. - */ - virtual void seek( size_t pos ) = 0; - - /** Returns the current byte offset from beginning */ - virtual size_t tell(void) const = 0; - - /** Returns true if the stream has reached the end. - */ - virtual bool eof(void) const = 0; - - /** Returns the total size of the data to be read from the stream, - or 0 if this is indeterminate for this stream. - */ + @param delim The delimiter(s) to stop at + @return The number of bytes skipped + */ + virtual size_t skipLine(const String& delim = "\n"); + + /** Skip a defined number of bytes. This can also be a negative value, in which case + the file pointer rewinds a defined number of bytes. */ + virtual void skip(long count) = 0; + + /** Repositions the read point to a specified byte. + */ + virtual void seek( size_t pos ) = 0; + + /** Returns the current byte offset from beginning */ + virtual size_t tell(void) const = 0; + + /** Returns true if the stream has reached the end. + */ + virtual bool eof(void) const = 0; + + /** Returns the total size of the data to be read from the stream, + or 0 if this is indeterminate for this stream. + */ size_t size(void) const { return mSize; } /** Close the stream; this makes further operations invalid. */ virtual void close(void) = 0; - + - }; + }; - /// List of DataStream items - typedef list::type DataStreamList; - /// Shared pointer to list of DataStream items - typedef SharedPtr DataStreamListPtr; + /// List of DataStream items + typedef list::type DataStreamList; + /// Shared pointer to list of DataStream items + typedef SharedPtr DataStreamListPtr; - /** Common subclass of DataStream for handling data from chunks of memory. - */ - class _OgreExport MemoryDataStream : public DataStream - { - protected: + /** Common subclass of DataStream for handling data from chunks of memory. + */ + class _OgreExport MemoryDataStream : public DataStream + { + protected: /// Pointer to the start of the data area - uchar* mData; + uchar* mData; /// Pointer to the current position in the memory - uchar* mPos; + uchar* mPos; /// Pointer to the end of the memory - uchar* mEnd; + uchar* mEnd; /// Do we delete the memory on close - bool mFreeOnClose; - public: - - /** Wrap an existing memory chunk in a stream. - @param pMem Pointer to the existing memory - @param size The size of the memory chunk in bytes - @param freeOnClose If true, the memory associated will be destroyed - when the stream is closed. Note: it's important that if you set - this option to true, that you allocated the memory using OGRE_ALLOC_T - with a category of MEMCATEGORY_GENERAL to ensure the freeing of memory - matches up. - @param readOnly Whether to make the stream on this memory read-only once created - */ - MemoryDataStream(void* pMem, size_t size, bool freeOnClose = false, bool readOnly = false); - - /** Wrap an existing memory chunk in a named stream. - @param name The name to give the stream - @param pMem Pointer to the existing memory - @param size The size of the memory chunk in bytes - @param freeOnClose If true, the memory associated will be destroyed - when the stream is destroyed. Note: it's important that if you set - this option to true, that you allocated the memory using OGRE_ALLOC_T - with a category of MEMCATEGORY_GENERAL ensure the freeing of memory - matches up. - @param readOnly Whether to make the stream on this memory read-only once created - */ - MemoryDataStream(const String& name, void* pMem, size_t size, - bool freeOnClose = false, bool readOnly = false); - - /** Create a stream which pre-buffers the contents of another stream. - @remarks - This constructor can be used to intentionally read in the entire - contents of another stream, copying them to the internal buffer - and thus making them available in memory as a single unit. - @param sourceStream Another DataStream which will provide the source - of data - @param freeOnClose If true, the memory associated will be destroyed - when the stream is destroyed. - @param readOnly Whether to make the stream on this memory read-only once created - */ - MemoryDataStream(DataStream& sourceStream, - bool freeOnClose = true, bool readOnly = false); - - /** Create a stream which pre-buffers the contents of another stream. - @remarks - This constructor can be used to intentionally read in the entire - contents of another stream, copying them to the internal buffer - and thus making them available in memory as a single unit. - @param sourceStream Another DataStream which will provide the source - of data - @param freeOnClose If true, the memory associated will be destroyed - when the stream is destroyed. - @param readOnly Whether to make the stream on this memory read-only once created - */ - MemoryDataStream(DataStreamPtr& sourceStream, - bool freeOnClose = true, bool readOnly = false); - - /** Create a named stream which pre-buffers the contents of - another stream. - @remarks - This constructor can be used to intentionally read in the entire - contents of another stream, copying them to the internal buffer - and thus making them available in memory as a single unit. - @param name The name to give the stream - @param sourceStream Another DataStream which will provide the source - of data - @param freeOnClose If true, the memory associated will be destroyed - when the stream is destroyed. - @param readOnly Whether to make the stream on this memory read-only once created - */ - MemoryDataStream(const String& name, DataStream& sourceStream, - bool freeOnClose = true, bool readOnly = false); + bool mFreeOnClose; + public: + + /** Wrap an existing memory chunk in a stream. + @param pMem Pointer to the existing memory + @param size The size of the memory chunk in bytes + @param freeOnClose If true, the memory associated will be destroyed + when the stream is closed. Note: it's important that if you set + this option to true, that you allocated the memory using OGRE_ALLOC_T + with a category of MEMCATEGORY_GENERAL to ensure the freeing of memory + matches up. + @param readOnly Whether to make the stream on this memory read-only once created + */ + MemoryDataStream(void* pMem, size_t size, bool freeOnClose = false, bool readOnly = false); + + /** Wrap an existing memory chunk in a named stream. + @param name The name to give the stream + @param pMem Pointer to the existing memory + @param size The size of the memory chunk in bytes + @param freeOnClose If true, the memory associated will be destroyed + when the stream is destroyed. Note: it's important that if you set + this option to true, that you allocated the memory using OGRE_ALLOC_T + with a category of MEMCATEGORY_GENERAL ensure the freeing of memory + matches up. + @param readOnly Whether to make the stream on this memory read-only once created + */ + MemoryDataStream(const String& name, void* pMem, size_t size, + bool freeOnClose = false, bool readOnly = false); + + /** Create a stream which pre-buffers the contents of another stream. + @remarks + This constructor can be used to intentionally read in the entire + contents of another stream, copying them to the internal buffer + and thus making them available in memory as a single unit. + @param sourceStream Another DataStream which will provide the source + of data + @param freeOnClose If true, the memory associated will be destroyed + when the stream is destroyed. + @param readOnly Whether to make the stream on this memory read-only once created + */ + MemoryDataStream(DataStream& sourceStream, + bool freeOnClose = true, bool readOnly = false); + + /** Create a stream which pre-buffers the contents of another stream. + @remarks + This constructor can be used to intentionally read in the entire + contents of another stream, copying them to the internal buffer + and thus making them available in memory as a single unit. + @param sourceStream Another DataStream which will provide the source + of data + @param freeOnClose If true, the memory associated will be destroyed + when the stream is destroyed. + @param readOnly Whether to make the stream on this memory read-only once created + */ + MemoryDataStream(DataStreamPtr& sourceStream, + bool freeOnClose = true, bool readOnly = false); + + /** Create a named stream which pre-buffers the contents of + another stream. + @remarks + This constructor can be used to intentionally read in the entire + contents of another stream, copying them to the internal buffer + and thus making them available in memory as a single unit. + @param name The name to give the stream + @param sourceStream Another DataStream which will provide the source + of data + @param freeOnClose If true, the memory associated will be destroyed + when the stream is destroyed. + @param readOnly Whether to make the stream on this memory read-only once created + */ + MemoryDataStream(const String& name, DataStream& sourceStream, + bool freeOnClose = true, bool readOnly = false); /** Create a named stream which pre-buffers the contents of another stream. @@ -405,128 +405,128 @@ namespace Ogre { of data @param freeOnClose If true, the memory associated will be destroyed when the stream is destroyed. - @param readOnly Whether to make the stream on this memory read-only once created + @param readOnly Whether to make the stream on this memory read-only once created */ MemoryDataStream(const String& name, const DataStreamPtr& sourceStream, bool freeOnClose = true, bool readOnly = false); /** Create a stream with a brand new empty memory chunk. - @param size The size of the memory chunk to create in bytes - @param freeOnClose If true, the memory associated will be destroyed - when the stream is destroyed. - @param readOnly Whether to make the stream on this memory read-only once created - */ - MemoryDataStream(size_t size, bool freeOnClose = true, bool readOnly = false); - /** Create a named stream with a brand new empty memory chunk. - @param name The name to give the stream - @param size The size of the memory chunk to create in bytes - @param freeOnClose If true, the memory associated will be destroyed - when the stream is destroyed. - @param readOnly Whether to make the stream on this memory read-only once created - */ - MemoryDataStream(const String& name, size_t size, - bool freeOnClose = true, bool readOnly = false); - - ~MemoryDataStream(); - - /** Get a pointer to the start of the memory block this stream holds. */ - uchar* getPtr(void) { return mData; } - - /** Get a pointer to the current position in the memory block this stream holds. */ - uchar* getCurrentPtr(void) { return mPos; } - - /** @copydoc DataStream::read - */ - size_t read(void* buf, size_t count); - - /** @copydoc DataStream::write - */ - size_t write(const void* buf, size_t count); - - /** @copydoc DataStream::readLine - */ - size_t readLine(char* buf, size_t maxCount, const String& delim = "\n"); - - /** @copydoc DataStream::skipLine - */ - size_t skipLine(const String& delim = "\n"); - - /** @copydoc DataStream::skip - */ - void skip(long count); - - /** @copydoc DataStream::seek - */ - void seek( size_t pos ); - - /** @copydoc DataStream::tell - */ - size_t tell(void) const; - - /** @copydoc DataStream::eof - */ - bool eof(void) const; + @param size The size of the memory chunk to create in bytes + @param freeOnClose If true, the memory associated will be destroyed + when the stream is destroyed. + @param readOnly Whether to make the stream on this memory read-only once created + */ + MemoryDataStream(size_t size, bool freeOnClose = true, bool readOnly = false); + /** Create a named stream with a brand new empty memory chunk. + @param name The name to give the stream + @param size The size of the memory chunk to create in bytes + @param freeOnClose If true, the memory associated will be destroyed + when the stream is destroyed. + @param readOnly Whether to make the stream on this memory read-only once created + */ + MemoryDataStream(const String& name, size_t size, + bool freeOnClose = true, bool readOnly = false); + + ~MemoryDataStream(); + + /** Get a pointer to the start of the memory block this stream holds. */ + uchar* getPtr(void) { return mData; } + + /** Get a pointer to the current position in the memory block this stream holds. */ + uchar* getCurrentPtr(void) { return mPos; } + + /** @copydoc DataStream::read + */ + size_t read(void* buf, size_t count); + + /** @copydoc DataStream::write + */ + size_t write(const void* buf, size_t count); + + /** @copydoc DataStream::readLine + */ + size_t readLine(char* buf, size_t maxCount, const String& delim = "\n"); + + /** @copydoc DataStream::skipLine + */ + size_t skipLine(const String& delim = "\n"); + + /** @copydoc DataStream::skip + */ + void skip(long count); + + /** @copydoc DataStream::seek + */ + void seek( size_t pos ); + + /** @copydoc DataStream::tell + */ + size_t tell(void) const; + + /** @copydoc DataStream::eof + */ + bool eof(void) const; /** @copydoc DataStream::close */ void close(void); - /** Sets whether or not to free the encapsulated memory on close. */ - void setFreeOnClose(bool free) { mFreeOnClose = free; } - }; + /** Sets whether or not to free the encapsulated memory on close. */ + void setFreeOnClose(bool free) { mFreeOnClose = free; } + }; /** Common subclass of DataStream for handling data from - std::basic_istream. - */ - class _OgreExport FileStreamDataStream : public DataStream - { - protected: - /// Reference to source stream (read) - std::istream* mInStream; - /// Reference to source file stream (read-only) - std::ifstream* mFStreamRO; - /// Reference to source file stream (read-write) - std::fstream* mFStream; - bool mFreeOnClose; - - void determineAccess(); - public: - /** Construct a read-only stream from an STL stream + std::basic_istream. + */ + class _OgreExport FileStreamDataStream : public DataStream + { + protected: + /// Reference to source stream (read) + std::istream* mInStream; + /// Reference to source file stream (read-only) + std::ifstream* mFStreamRO; + /// Reference to source file stream (read-write) + std::fstream* mFStream; + bool mFreeOnClose; + + void determineAccess(); + public: + /** Construct a read-only stream from an STL stream @param s Pointer to source stream @param freeOnClose Whether to delete the underlying stream on destruction of this class */ - FileStreamDataStream(std::ifstream* s, + FileStreamDataStream(std::ifstream* s, + bool freeOnClose = true); + /** Construct a read-write stream from an STL stream + @param s Pointer to source stream + @param freeOnClose Whether to delete the underlying stream on + destruction of this class + */ + FileStreamDataStream(std::fstream* s, bool freeOnClose = true); - /** Construct a read-write stream from an STL stream - @param s Pointer to source stream - @param freeOnClose Whether to delete the underlying stream on - destruction of this class - */ - FileStreamDataStream(std::fstream* s, - bool freeOnClose = true); - - /** Construct named read-only stream from an STL stream + + /** Construct named read-only stream from an STL stream @param name The name to give this stream @param s Pointer to source stream @param freeOnClose Whether to delete the underlying stream on destruction of this class */ - FileStreamDataStream(const String& name, + FileStreamDataStream(const String& name, std::ifstream* s, bool freeOnClose = true); - /** Construct named read-write stream from an STL stream - @param name The name to give this stream - @param s Pointer to source stream - @param freeOnClose Whether to delete the underlying stream on - destruction of this class - */ - FileStreamDataStream(const String& name, - std::fstream* s, - bool freeOnClose = true); - - /** Construct named read-only stream from an STL stream, and tell it the size + /** Construct named read-write stream from an STL stream + @param name The name to give this stream + @param s Pointer to source stream + @param freeOnClose Whether to delete the underlying stream on + destruction of this class + */ + FileStreamDataStream(const String& name, + std::fstream* s, + bool freeOnClose = true); + + /** Construct named read-only stream from an STL stream, and tell it the size @remarks This variant tells the class the size of the stream too, which means this class does not need to seek to the end of the stream @@ -537,121 +537,121 @@ namespace Ogre { @param size Size of the stream contents in bytes @param freeOnClose Whether to delete the underlying stream on destruction of this class. If you specify 'true' for this you - must ensure that the stream was allocated using OGRE_NEW_T with - MEMCATEGRORY_GENERAL. + must ensure that the stream was allocated using OGRE_NEW_T with + MEMCATEGRORY_GENERAL. */ - FileStreamDataStream(const String& name, + FileStreamDataStream(const String& name, std::ifstream* s, size_t size, bool freeOnClose = true); - /** Construct named read-write stream from an STL stream, and tell it the size - @remarks - This variant tells the class the size of the stream too, which - means this class does not need to seek to the end of the stream - to determine the size up-front. This can be beneficial if you have - metadata about the contents of the stream already. - @param name The name to give this stream - @param s Pointer to source stream - @param size Size of the stream contents in bytes - @param freeOnClose Whether to delete the underlying stream on - destruction of this class. If you specify 'true' for this you - must ensure that the stream was allocated using OGRE_NEW_T with - MEMCATEGRORY_GENERAL. - */ - FileStreamDataStream(const String& name, - std::fstream* s, - size_t size, - bool freeOnClose = true); - - ~FileStreamDataStream(); - - /** @copydoc DataStream::read - */ - size_t read(void* buf, size_t count); - - /** @copydoc DataStream::write - */ - size_t write(const void* buf, size_t count); - - /** @copydoc DataStream::readLine - */ + /** Construct named read-write stream from an STL stream, and tell it the size + @remarks + This variant tells the class the size of the stream too, which + means this class does not need to seek to the end of the stream + to determine the size up-front. This can be beneficial if you have + metadata about the contents of the stream already. + @param name The name to give this stream + @param s Pointer to source stream + @param size Size of the stream contents in bytes + @param freeOnClose Whether to delete the underlying stream on + destruction of this class. If you specify 'true' for this you + must ensure that the stream was allocated using OGRE_NEW_T with + MEMCATEGRORY_GENERAL. + */ + FileStreamDataStream(const String& name, + std::fstream* s, + size_t size, + bool freeOnClose = true); + + ~FileStreamDataStream(); + + /** @copydoc DataStream::read + */ + size_t read(void* buf, size_t count); + + /** @copydoc DataStream::write + */ + size_t write(const void* buf, size_t count); + + /** @copydoc DataStream::readLine + */ size_t readLine(char* buf, size_t maxCount, const String& delim = "\n"); - - /** @copydoc DataStream::skip - */ - void skip(long count); - - /** @copydoc DataStream::seek - */ - void seek( size_t pos ); - - /** @copydoc DataStream::tell - */ - size_t tell(void) const; - - /** @copydoc DataStream::eof - */ - bool eof(void) const; + + /** @copydoc DataStream::skip + */ + void skip(long count); + + /** @copydoc DataStream::seek + */ + void seek( size_t pos ); + + /** @copydoc DataStream::tell + */ + size_t tell(void) const; + + /** @copydoc DataStream::eof + */ + bool eof(void) const; /** @copydoc DataStream::close */ void close(void); - - - }; + + + }; - /** Common subclass of DataStream for handling data from C-style file - handles. + /** Common subclass of DataStream for handling data from C-style file + handles. @remarks Use of this class is generally discouraged; if you want to wrap file access in a DataStream, you should definitely be using the C++ friendly FileStreamDataStream. However, since there are quite a few applications and libraries still wedded to the old FILE handle access, this stream wrapper provides some backwards compatibility. - */ - class _OgreExport FileHandleDataStream : public DataStream - { - protected: - FILE* mFileHandle; - public: - /// Create stream from a C file handle - FileHandleDataStream(FILE* handle, uint16 accessMode = READ); - /// Create named stream from a C file handle - FileHandleDataStream(const String& name, FILE* handle, uint16 accessMode = READ); + */ + class _OgreExport FileHandleDataStream : public DataStream + { + protected: + FILE* mFileHandle; + public: + /// Create stream from a C file handle + FileHandleDataStream(FILE* handle, uint16 accessMode = READ); + /// Create named stream from a C file handle + FileHandleDataStream(const String& name, FILE* handle, uint16 accessMode = READ); ~FileHandleDataStream(); - /** @copydoc DataStream::read - */ - size_t read(void* buf, size_t count); + /** @copydoc DataStream::read + */ + size_t read(void* buf, size_t count); - /** @copydoc DataStream::write - */ - size_t write(const void* buf, size_t count); + /** @copydoc DataStream::write + */ + size_t write(const void* buf, size_t count); - /** @copydoc DataStream::skip - */ - void skip(long count); - - /** @copydoc DataStream::seek - */ - void seek( size_t pos ); + /** @copydoc DataStream::skip + */ + void skip(long count); + + /** @copydoc DataStream::seek + */ + void seek( size_t pos ); - /** @copydoc DataStream::tell - */ - size_t tell(void) const; + /** @copydoc DataStream::tell + */ + size_t tell(void) const; - /** @copydoc DataStream::eof - */ - bool eof(void) const; + /** @copydoc DataStream::eof + */ + bool eof(void) const; /** @copydoc DataStream::close */ void close(void); - }; - /** @} */ - /** @} */ + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreDefaultHardwareBufferManager.h b/OgreMain/include/OgreDefaultHardwareBufferManager.h index 6367edfa672..468848d2b8c 100644 --- a/OgreMain/include/OgreDefaultHardwareBufferManager.h +++ b/OgreMain/include/OgreDefaultHardwareBufferManager.h @@ -37,106 +37,106 @@ THE SOFTWARE. #include "OgreHardwareVertexBuffer.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ /// Specialisation of HardwareVertexBuffer for emulation class _OgreExport DefaultHardwareVertexBuffer : public HardwareVertexBuffer { - protected: - unsigned char* mData; + protected: + unsigned char* mData; /** See HardwareBuffer. */ void* lockImpl(size_t offset, size_t length, LockOptions options); /** See HardwareBuffer. */ - void unlockImpl(void); + void unlockImpl(void); public: - DefaultHardwareVertexBuffer(size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage); - DefaultHardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, + DefaultHardwareVertexBuffer(size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage); + DefaultHardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage); ~DefaultHardwareVertexBuffer(); /** See HardwareBuffer. */ void readData(size_t offset, size_t length, void* pDest); /** See HardwareBuffer. */ void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); + bool discardWholeBuffer = false); /** Override HardwareBuffer to turn off all shadowing. */ void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); /** Override HardwareBuffer to turn off all shadowing. */ - void unlock(void); + void unlock(void); }; - /// Specialisation of HardwareIndexBuffer for emulation + /// Specialisation of HardwareIndexBuffer for emulation class _OgreExport DefaultHardwareIndexBuffer : public HardwareIndexBuffer { - protected: - unsigned char* mData; + protected: + unsigned char* mData; /** See HardwareBuffer. */ void* lockImpl(size_t offset, size_t length, LockOptions options); /** See HardwareBuffer. */ - void unlockImpl(void); + void unlockImpl(void); public: - DefaultHardwareIndexBuffer(IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage); + DefaultHardwareIndexBuffer(IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage); ~DefaultHardwareIndexBuffer(); /** See HardwareBuffer. */ void readData(size_t offset, size_t length, void* pDest); /** See HardwareBuffer. */ void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); + bool discardWholeBuffer = false); /** Override HardwareBuffer to turn off all shadowing. */ void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); /** Override HardwareBuffer to turn off all shadowing. */ - void unlock(void); + void unlock(void); }; - /// Specialisation of HardwareUniformBuffer for emulation - class _OgreExport DefaultHardwareUniformBuffer : public HardwareUniformBuffer - { - protected: - unsigned char* mData; - /** See HardwareBuffer. */ + /// Specialisation of HardwareUniformBuffer for emulation + class _OgreExport DefaultHardwareUniformBuffer : public HardwareUniformBuffer + { + protected: + unsigned char* mData; + /** See HardwareBuffer. */ void* lockImpl(size_t offset, size_t length, LockOptions options); /** See HardwareBuffer. */ - void unlockImpl(void); - /** */ - //bool updateStructure(const Any& renderSystemInfo); + void unlockImpl(void); + /** */ + //bool updateStructure(const Any& renderSystemInfo); - public: - DefaultHardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer = false, const String& name = ""); - ~DefaultHardwareUniformBuffer(); - /** See HardwareBuffer. */ + public: + DefaultHardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer = false, const String& name = ""); + ~DefaultHardwareUniformBuffer(); + /** See HardwareBuffer. */ void readData(size_t offset, size_t length, void* pDest); /** See HardwareBuffer. */ void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); + bool discardWholeBuffer = false); /** Override HardwareBuffer to turn off all shadowing. */ void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); /** Override HardwareBuffer to turn off all shadowing. */ - void unlock(void); - }; + void unlock(void); + }; /// Specialisation of HardwareCounterBuffer for emulation - class _OgreExport DefaultHardwareCounterBuffer : public HardwareCounterBuffer - { - protected: - unsigned char* mData; - /** See HardwareBuffer. */ + class _OgreExport DefaultHardwareCounterBuffer : public HardwareCounterBuffer + { + protected: + unsigned char* mData; + /** See HardwareBuffer. */ void* lockImpl(size_t offset, size_t length, LockOptions options); /** See HardwareBuffer. */ - void unlockImpl(void); - /** */ - //bool updateStructure(const Any& renderSystemInfo); + void unlockImpl(void); + /** */ + //bool updateStructure(const Any& renderSystemInfo); - public: - DefaultHardwareCounterBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer = false, const String& name = ""); - ~DefaultHardwareCounterBuffer(); - /** See HardwareBuffer. */ + public: + DefaultHardwareCounterBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer = false, const String& name = ""); + ~DefaultHardwareCounterBuffer(); + /** See HardwareBuffer. */ void readData(size_t offset, size_t length, void* pDest); /** See HardwareBuffer. */ void writeData(size_t offset, size_t length, const void* pSource, @@ -144,58 +144,58 @@ namespace Ogre { /** Override HardwareBuffer to turn off all shadowing. */ void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); /** Override HardwareBuffer to turn off all shadowing. */ - void unlock(void); - }; - - /** Specialisation of HardwareBufferManagerBase to emulate hardware buffers. - @remarks - You might want to instantiate this class if you want to utilise - classes like MeshSerializer without having initialised the - rendering system (which is required to create a 'real' hardware - buffer manager). - */ - class _OgreExport DefaultHardwareBufferManagerBase : public HardwareBufferManagerBase - { + void unlock(void); + }; + + /** Specialisation of HardwareBufferManagerBase to emulate hardware buffers. + @remarks + You might want to instantiate this class if you want to utilise + classes like MeshSerializer without having initialised the + rendering system (which is required to create a 'real' hardware + buffer manager). + */ + class _OgreExport DefaultHardwareBufferManagerBase : public HardwareBufferManagerBase + { public: DefaultHardwareBufferManagerBase(); ~DefaultHardwareBufferManagerBase(); /// Creates a vertex buffer - HardwareVertexBufferSharedPtr + HardwareVertexBufferSharedPtr createVertexBuffer(size_t vertexSize, size_t numVerts, - HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// Create a hardware index buffer - HardwareIndexBufferSharedPtr + HardwareBuffer::Usage usage, bool useShadowBuffer = false); + /// Create a hardware index buffer + HardwareIndexBufferSharedPtr createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, - HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// Create a hardware vertex buffer - RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); - /// Create a hardware uniform buffer - HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, - HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, - bool useShadowBuffer = false, const String& name = ""); - /// Create a hardware counter buffer - HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, + HardwareBuffer::Usage usage, bool useShadowBuffer = false); + /// Create a hardware vertex buffer + RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); + /// Create a hardware uniform buffer + HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, + HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, + bool useShadowBuffer = false, const String& name = ""); + /// Create a hardware counter buffer + HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, bool useShadowBuffer = false, const String& name = ""); }; - /// DefaultHardwareBufferManager as a Singleton - class _OgreExport DefaultHardwareBufferManager : public HardwareBufferManager - { - public: - DefaultHardwareBufferManager() - : HardwareBufferManager(OGRE_NEW DefaultHardwareBufferManagerBase()) - { - - } - ~DefaultHardwareBufferManager() - { - OGRE_DELETE mImpl; - } - }; - - /** @} */ - /** @} */ + /// DefaultHardwareBufferManager as a Singleton + class _OgreExport DefaultHardwareBufferManager : public HardwareBufferManager + { + public: + DefaultHardwareBufferManager() + : HardwareBufferManager(OGRE_NEW DefaultHardwareBufferManagerBase()) + { + + } + ~DefaultHardwareBufferManager() + { + OGRE_DELETE mImpl; + } + }; + + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreDeflate.h b/OgreMain/include/OgreDeflate.h index 0699ab31d21..d4106a4087a 100644 --- a/OgreMain/include/OgreDeflate.h +++ b/OgreMain/include/OgreDeflate.h @@ -38,104 +38,104 @@ typedef struct z_stream_s z_stream; namespace Ogre { - /** Stream which compresses / uncompresses data using the 'deflate' compression - algorithm. - @remarks - This stream is designed to wrap another stream for the actual source / destination - of the compressed data, it has no concrete source / data itself. The idea is - that you pass uncompressed data through this stream, and the underlying - stream reads/writes compressed data to the final source. - @note - This is an alternative to using a compressed archive since it is able to - compress & decompress regardless of the actual source of the stream. - You should avoid using this with already compressed archives. - Also note that this cannot be used as a read / write stream, only a read-only - or write-only stream. - */ - class _OgreExport DeflateStream : public DataStream - { - protected: - DataStreamPtr mCompressedStream; - DataStreamPtr mTmpWriteStream; - String mTempFileName; - z_stream* mZStream; - size_t mCurrentPos; - size_t mAvailIn; - - /// Cache for read data in case skipping around - StaticCache<16 * OGRE_STREAM_TEMP_SIZE> mReadCache; - - /// Intermediate buffer for read / write - unsigned char *mTmp; - - /// Whether the underlying stream is valid compressed data - bool mIsCompressedValid; - - void init(); - void destroy(); - void compressFinal(); + /** Stream which compresses / uncompresses data using the 'deflate' compression + algorithm. + @remarks + This stream is designed to wrap another stream for the actual source / destination + of the compressed data, it has no concrete source / data itself. The idea is + that you pass uncompressed data through this stream, and the underlying + stream reads/writes compressed data to the final source. + @note + This is an alternative to using a compressed archive since it is able to + compress & decompress regardless of the actual source of the stream. + You should avoid using this with already compressed archives. + Also note that this cannot be used as a read / write stream, only a read-only + or write-only stream. + */ + class _OgreExport DeflateStream : public DataStream + { + protected: + DataStreamPtr mCompressedStream; + DataStreamPtr mTmpWriteStream; + String mTempFileName; + z_stream* mZStream; + size_t mCurrentPos; + size_t mAvailIn; + + /// Cache for read data in case skipping around + StaticCache<16 * OGRE_STREAM_TEMP_SIZE> mReadCache; + + /// Intermediate buffer for read / write + unsigned char *mTmp; + + /// Whether the underlying stream is valid compressed data + bool mIsCompressedValid; + + void init(); + void destroy(); + void compressFinal(); - size_t getAvailInForSinglePass(); - public: - /** Constructor for creating unnamed stream wrapping another stream. - @param compressedStream The stream that this stream will use when reading / - writing compressed data. The access mode from this stream will be matched. - @param tmpFileName Path/Filename to be used for temporary storage of incoming data - @param avail_in Available data length to be uncompressed. With it we can uncompress - DataStream partly. - */ + size_t getAvailInForSinglePass(); + public: + /** Constructor for creating unnamed stream wrapping another stream. + @param compressedStream The stream that this stream will use when reading / + writing compressed data. The access mode from this stream will be matched. + @param tmpFileName Path/Filename to be used for temporary storage of incoming data + @param avail_in Available data length to be uncompressed. With it we can uncompress + DataStream partly. + */ DeflateStream(const DataStreamPtr& compressedStream, const String& tmpFileName = "", - size_t avail_in = 0); - /** Constructor for creating named stream wrapping another stream. - @param name The name to give this stream - @param compressedStream The stream that this stream will use when reading / - writing compressed data. The access mode from this stream will be matched. - @param tmpFileName Path/Filename to be used for temporary storage of incoming data - @param avail_in Available data length to be uncompressed. With it we can uncompress - DataStream partly. - */ - DeflateStream(const String& name, const DataStreamPtr& compressedStream, const String& tmpFileName="", - size_t avail_in = 0); - - ~DeflateStream(); - - /** Returns whether the compressed stream is valid deflated data. - @remarks - If you pass this class a READ stream which is not compressed with the - deflate algorithm, this method returns false and all read commands - will actually be executed as passthroughs as a fallback. - */ - bool isCompressedStreamValid() const { return mIsCompressedValid; } - - /** @copydoc DataStream::read - */ - size_t read(void* buf, size_t count); - - /** @copydoc DataStream::write - */ - size_t write(const void* buf, size_t count); - - /** @copydoc DataStream::skip - */ - void skip(long count); - - /** @copydoc DataStream::seek - */ - void seek( size_t pos ); - - /** @copydoc DataStream::tell - */ - size_t tell(void) const; - - /** @copydoc DataStream::eof - */ - bool eof(void) const; - + size_t avail_in = 0); + /** Constructor for creating named stream wrapping another stream. + @param name The name to give this stream + @param compressedStream The stream that this stream will use when reading / + writing compressed data. The access mode from this stream will be matched. + @param tmpFileName Path/Filename to be used for temporary storage of incoming data + @param avail_in Available data length to be uncompressed. With it we can uncompress + DataStream partly. + */ + DeflateStream(const String& name, const DataStreamPtr& compressedStream, const String& tmpFileName="", + size_t avail_in = 0); + + ~DeflateStream(); + + /** Returns whether the compressed stream is valid deflated data. + @remarks + If you pass this class a READ stream which is not compressed with the + deflate algorithm, this method returns false and all read commands + will actually be executed as passthroughs as a fallback. + */ + bool isCompressedStreamValid() const { return mIsCompressedValid; } + + /** @copydoc DataStream::read + */ + size_t read(void* buf, size_t count); + + /** @copydoc DataStream::write + */ + size_t write(const void* buf, size_t count); + + /** @copydoc DataStream::skip + */ + void skip(long count); + + /** @copydoc DataStream::seek + */ + void seek( size_t pos ); + + /** @copydoc DataStream::tell + */ + size_t tell(void) const; + + /** @copydoc DataStream::eof + */ + bool eof(void) const; + /** @copydoc DataStream::close - */ + */ void close(void); - - }; + + }; } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreDepthBuffer.h b/OgreMain/include/OgreDepthBuffer.h index 847ef30e4af..213ce35dd0e 100644 --- a/OgreMain/include/OgreDepthBuffer.h +++ b/OgreMain/include/OgreDepthBuffer.h @@ -33,124 +33,124 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - - /** An abstract class that contains a depth/stencil buffer. - Depth Buffers can be attached to render targets. Note we handle Depth & Stencil together. - DepthBuffer sharing is handled automatically for you. However, there are times where you want - to specifically control depth buffers to achieve certain effects or increase performance. - You can control this by hinting Ogre with POOL IDs. Created depth buffers can live in different - pools, or all together in the same one. - Usually, a depth buffer can only be attached to a RenderTarget if it's dimensions are bigger - and have the same bit depth and same multisample settings. Depth Buffers are created automatically - for new RTs when needed, and stored in the pool where the RenderTarget should have drawn from. - By default, all RTs have the Id POOL_DEFAULT, which means all depth buffers are stored by default - in that pool. By choosing a different Pool Id for a specific RenderTarget, that RT will only - retrieve depth buffers from _that_ pool, therefore not conflicting with sharing depth buffers - with other RTs (such as shadows maps). - Setting an RT to POOL_MANUAL_USAGE means Ogre won't manage the DepthBuffer for you (not recommended) - RTs with POOL_NO_DEPTH are very useful when you don't want to create a DepthBuffer for it. You can - still manually attach a depth buffer though as internally POOL_NO_DEPTH & POOL_MANUAL_USAGE are - handled in the same way. - - Behavior is consistent across all render systems, if, and only if, the same RSC flags are set - RSC flags that affect this class are: - * RSC_RTT_SEPARATE_DEPTHBUFFER: - The RTT can create a custom depth buffer different from the main depth buffer. This means, - an RTT is able to not share it's depth buffer with the main window if it wants to. - * RSC_RTT_MAIN_DEPTHBUFFER_ATTACHABLE: - When RSC_RTT_SEPARATE_DEPTHBUFFER is set, some APIs (ie. OpenGL w/ FBO) don't allow using - the main depth buffer for offscreen RTTs. When this flag is set, the depth buffer can be - shared between the main window and an RTT. - * RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL: - When this flag isn't set, the depth buffer can only be shared across RTTs who have the EXACT - same resolution. When it's set, it can be shared with RTTs as long as they have a - resolution less or equal than the depth buffer's. + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + + /** An abstract class that contains a depth/stencil buffer. + Depth Buffers can be attached to render targets. Note we handle Depth & Stencil together. + DepthBuffer sharing is handled automatically for you. However, there are times where you want + to specifically control depth buffers to achieve certain effects or increase performance. + You can control this by hinting Ogre with POOL IDs. Created depth buffers can live in different + pools, or all together in the same one. + Usually, a depth buffer can only be attached to a RenderTarget if it's dimensions are bigger + and have the same bit depth and same multisample settings. Depth Buffers are created automatically + for new RTs when needed, and stored in the pool where the RenderTarget should have drawn from. + By default, all RTs have the Id POOL_DEFAULT, which means all depth buffers are stored by default + in that pool. By choosing a different Pool Id for a specific RenderTarget, that RT will only + retrieve depth buffers from _that_ pool, therefore not conflicting with sharing depth buffers + with other RTs (such as shadows maps). + Setting an RT to POOL_MANUAL_USAGE means Ogre won't manage the DepthBuffer for you (not recommended) + RTs with POOL_NO_DEPTH are very useful when you don't want to create a DepthBuffer for it. You can + still manually attach a depth buffer though as internally POOL_NO_DEPTH & POOL_MANUAL_USAGE are + handled in the same way. + + Behavior is consistent across all render systems, if, and only if, the same RSC flags are set + RSC flags that affect this class are: + * RSC_RTT_SEPARATE_DEPTHBUFFER: + The RTT can create a custom depth buffer different from the main depth buffer. This means, + an RTT is able to not share it's depth buffer with the main window if it wants to. + * RSC_RTT_MAIN_DEPTHBUFFER_ATTACHABLE: + When RSC_RTT_SEPARATE_DEPTHBUFFER is set, some APIs (ie. OpenGL w/ FBO) don't allow using + the main depth buffer for offscreen RTTs. When this flag is set, the depth buffer can be + shared between the main window and an RTT. + * RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL: + When this flag isn't set, the depth buffer can only be shared across RTTs who have the EXACT + same resolution. When it's set, it can be shared with RTTs as long as they have a + resolution less or equal than the depth buffer's. @remarks - Design discussion http://www.ogre3d.org/forums/viewtopic.php?f=4&t=53534&p=365582 + Design discussion http://www.ogre3d.org/forums/viewtopic.php?f=4&t=53534&p=365582 @author Matias N. Goldberg @version 1.0 */ - class _OgreExport DepthBuffer : public RenderSysAlloc - { - public: - enum PoolId - { - POOL_NO_DEPTH = 0, - POOL_MANUAL_USAGE = 0, - POOL_DEFAULT = 1 - }; - - DepthBuffer( uint16 poolId, uint16 bitDepth, uint32 width, uint32 height, - uint32 fsaa, const String &fsaaHint, bool manual ); - virtual ~DepthBuffer(); - - /** Sets the pool id in which this DepthBuffer lives. + class _OgreExport DepthBuffer : public RenderSysAlloc + { + public: + enum PoolId + { + POOL_NO_DEPTH = 0, + POOL_MANUAL_USAGE = 0, + POOL_DEFAULT = 1 + }; + + DepthBuffer( uint16 poolId, uint16 bitDepth, uint32 width, uint32 height, + uint32 fsaa, const String &fsaaHint, bool manual ); + virtual ~DepthBuffer(); + + /** Sets the pool id in which this DepthBuffer lives. Note this will detach any render target from this depth buffer */ - void _setPoolId( uint16 poolId ); + void _setPoolId( uint16 poolId ); - /// Gets the pool id in which this DepthBuffer lives - virtual uint16 getPoolId() const; - virtual uint16 getBitDepth() const; - virtual uint32 getWidth() const; - virtual uint32 getHeight() const; - virtual uint32 getFsaa() const; - virtual const String& getFsaaHint() const; + /// Gets the pool id in which this DepthBuffer lives + virtual uint16 getPoolId() const; + virtual uint16 getBitDepth() const; + virtual uint32 getWidth() const; + virtual uint32 getHeight() const; + virtual uint32 getFsaa() const; + virtual const String& getFsaaHint() const; - /** Manual DepthBuffers are cleared in RenderSystem's destructor. Non-manual ones are released + /** Manual DepthBuffers are cleared in RenderSystem's destructor. Non-manual ones are released with it's render target (aka, a backbuffer or similar) */ - bool isManual() const; + bool isManual() const; - /** Returns whether the specified RenderTarget is compatible with this DepthBuffer - That is, this DepthBuffer can be attached to that RenderTarget + /** Returns whether the specified RenderTarget is compatible with this DepthBuffer + That is, this DepthBuffer can be attached to that RenderTarget @remarks Most APIs impose the following restrictions: - Width & height must be equal or higher than the render target's - They must be of the same bit depth. - They need to have the same FSAA setting - @param renderTarget The render target to test against + Width & height must be equal or higher than the render target's + They must be of the same bit depth. + They need to have the same FSAA setting + @param renderTarget The render target to test against */ - virtual bool isCompatible( RenderTarget *renderTarget ) const; + virtual bool isCompatible( RenderTarget *renderTarget ) const; - /** Called when a RenderTarget is attaches this DepthBuffer + /** Called when a RenderTarget is attaches this DepthBuffer @remarks This function doesn't actually attach. It merely informs the DepthBuffer - which RenderTarget did attach. The real attachment happens in - RenderTarget::attachDepthBuffer() - @param renderTarget The RenderTarget that has just been attached + which RenderTarget did attach. The real attachment happens in + RenderTarget::attachDepthBuffer() + @param renderTarget The RenderTarget that has just been attached */ - virtual void _notifyRenderTargetAttached( RenderTarget *renderTarget ); + virtual void _notifyRenderTargetAttached( RenderTarget *renderTarget ); - /** Called when a RenderTarget is detaches from this DepthBuffer + /** Called when a RenderTarget is detaches from this DepthBuffer @remarks Same as DepthBuffer::_notifyRenderTargetAttached() - @param renderTarget The RenderTarget that has just been detached + @param renderTarget The RenderTarget that has just been detached */ - virtual void _notifyRenderTargetDetached( RenderTarget *renderTarget ); + virtual void _notifyRenderTargetDetached( RenderTarget *renderTarget ); - protected: - typedef set::type RenderTargetSet; + protected: + typedef set::type RenderTargetSet; - uint16 mPoolId; - uint16 mBitDepth; - uint32 mWidth; - uint32 mHeight; - uint32 mFsaa; - String mFsaaHint; + uint16 mPoolId; + uint16 mBitDepth; + uint32 mWidth; + uint32 mHeight; + uint32 mFsaa; + String mFsaaHint; - bool mManual; //We don't Release manual surfaces on destruction - RenderTargetSet mAttachedRenderTargets; + bool mManual; //We don't Release manual surfaces on destruction + RenderTargetSet mAttachedRenderTargets; - void detachFromAllRenderTargets(); - }; + void detachFromAllRenderTargets(); + }; } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreDistanceLodStrategy.h b/OgreMain/include/OgreDistanceLodStrategy.h index d9ebe0840be..4c283b89576 100644 --- a/OgreMain/include/OgreDistanceLodStrategy.h +++ b/OgreMain/include/OgreDistanceLodStrategy.h @@ -34,16 +34,16 @@ THE SOFTWARE. #include "OgreSingleton.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup LOD - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup LOD + * @{ + */ - class DistanceLodBoxStrategy; - /// Backward compatible name for Distance_Box strategy. - typedef DistanceLodBoxStrategy DistanceLodStrategy; + class DistanceLodBoxStrategy; + /// Backward compatible name for Distance_Box strategy. + typedef DistanceLodBoxStrategy DistanceLodStrategy; /** Level of detail strategy based on distance from camera. This is an abstract base class for DistanceLodBoxStrategy and DistanceLodSphereStrategy. @remarks @@ -111,15 +111,15 @@ namespace Ogre { Real mReferenceViewValue; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ /** \addtogroup Core - * @{ - */ - /** \addtogroup LOD - * @{ - */ + * @{ + */ + /** \addtogroup LOD + * @{ + */ /** Level of detail strategy based on distance from camera to an object's bounding sphere. @remarks @@ -177,11 +177,11 @@ namespace Ogre { /** @} */ /** \addtogroup Core - * @{ - */ - /** \addtogroup LOD - * @{ - */ + * @{ + */ + /** \addtogroup LOD + * @{ + */ /** Level of detail strategy based on distance from camera to an object's bounding box. @remarks diff --git a/OgreMain/include/OgreDualQuaternion.h b/OgreMain/include/OgreDualQuaternion.h index a96ad137e33..f59f07d69a0 100644 --- a/OgreMain/include/OgreDualQuaternion.h +++ b/OgreMain/include/OgreDualQuaternion.h @@ -34,150 +34,150 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Implementation of a dual quaternion, i.e. a rotation around an axis and a translation. - This implementation may note be appropriate as a general implementation, but is intended for use with - dual quaternion skinning. - */ - class _OgreExport DualQuaternion - { - public: - /// Default constructor, initializes to identity rotation (aka 0°), and zero translation (0,0,0) - inline DualQuaternion () - : w(1), x(0), y(0), z(0), dw(1), dx(0), dy(0), dz(0) - { - } - - /// Construct from an explicit list of values - inline DualQuaternion (Real fW, Real fX, Real fY, Real fZ, - Real fdW, Real fdX, Real fdY, Real fdZ) - : w(fW), x(fX), y(fY), z(fZ), dw(fdW), dx(fdX), dy(fdY), dz(fdZ) - { - } + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Implementation of a dual quaternion, i.e. a rotation around an axis and a translation. + This implementation may note be appropriate as a general implementation, but is intended for use with + dual quaternion skinning. + */ + class _OgreExport DualQuaternion + { + public: + /// Default constructor, initializes to identity rotation (aka 0°), and zero translation (0,0,0) + inline DualQuaternion () + : w(1), x(0), y(0), z(0), dw(1), dx(0), dy(0), dz(0) + { + } - /// Construct a dual quaternion from a transformation matrix - inline DualQuaternion(const Matrix4& rot) - { - this->fromTransformationMatrix(rot); - } - - /// Construct a dual quaternion from a unit quaternion and a translation vector - inline DualQuaternion(const Quaternion& q, const Vector3& trans) - { - this->fromRotationTranslation(q, trans); - } - - /// Construct a dual quaternion from 8 manual w/x/y/z/dw/dx/dy/dz values - inline DualQuaternion(Real* valptr) - { - memcpy(&w, valptr, sizeof(Real)*8); - } - - /// Array accessor operator - inline Real operator [] ( const size_t i ) const - { - assert( i < 8 ); - - return *(&w+i); - } - - /// Array accessor operator - inline Real& operator [] ( const size_t i ) - { - assert( i < 8 ); - - return *(&w+i); - } - - inline DualQuaternion& operator= (const DualQuaternion& rkQ) - { - w = rkQ.w; - x = rkQ.x; - y = rkQ.y; - z = rkQ.z; - dw = rkQ.dw; - dx = rkQ.dx; - dy = rkQ.dy; - dz = rkQ.dz; - - return *this; - } - - inline bool operator== (const DualQuaternion& rhs) const - { - return (rhs.w == w) && (rhs.x == x) && (rhs.y == y) && (rhs.z == z) && - (rhs.dw == dw) && (rhs.dx == dx) && (rhs.dy == dy) && (rhs.dz == dz); - } - - inline bool operator!= (const DualQuaternion& rhs) const - { - return !operator==(rhs); - } - - /// Pointer accessor for direct copying - inline Real* ptr() - { - return &w; - } - - /// Pointer accessor for direct copying - inline const Real* ptr() const - { - return &w; - } - - /// Exchange the contents of this dual quaternion with another. - inline void swap(DualQuaternion& other) - { - std::swap(w, other.w); - std::swap(x, other.x); - std::swap(y, other.y); - std::swap(z, other.z); - std::swap(dw, other.dw); - std::swap(dx, other.dx); - std::swap(dy, other.dy); - std::swap(dz, other.dz); - } - - /// Check whether this dual quaternion contains valid values - inline bool isNaN() const - { - return Math::isNaN(w) || Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z) || - Math::isNaN(dw) || Math::isNaN(dx) || Math::isNaN(dy) || Math::isNaN(dz); - } - - /// Construct a dual quaternion from a rotation described by a Quaternion and a translation described by a Vector3 - void fromRotationTranslation (const Quaternion& q, const Vector3& trans); - - /// Convert a dual quaternion into its two components, a Quaternion representing the rotation and a Vector3 representing the translation - void toRotationTranslation (Quaternion& q, Vector3& translation) const; - - /// Construct a dual quaternion from a 4x4 transformation matrix - void fromTransformationMatrix (const Matrix4& kTrans); - - /// Convert a dual quaternion to a 4x4 transformation matrix - void toTransformationMatrix (Matrix4& kTrans) const; - - Real w, x, y, z, dw, dx, dy, dz; - - /** - Function for writing to a stream. Outputs "DualQuaternion(w, x, y, z, dw, dx, dy, dz)" with w, x, y, z, dw, dx, dy, dz - being the member values of the dual quaternion. - */ - inline _OgreExport friend std::ostream& operator << - ( std::ostream& o, const DualQuaternion& q ) - { - o << "DualQuaternion(" << q.w << ", " << q.x << ", " << q.y << ", " << q.z << ", " << q.dw << ", " << q.dx << ", " << q.dy << ", " << q.dz << ")"; - return o; - } - }; - /** @} */ - /** @} */ + /// Construct from an explicit list of values + inline DualQuaternion (Real fW, Real fX, Real fY, Real fZ, + Real fdW, Real fdX, Real fdY, Real fdZ) + : w(fW), x(fX), y(fY), z(fZ), dw(fdW), dx(fdX), dy(fdY), dz(fdZ) + { + } + + /// Construct a dual quaternion from a transformation matrix + inline DualQuaternion(const Matrix4& rot) + { + this->fromTransformationMatrix(rot); + } + + /// Construct a dual quaternion from a unit quaternion and a translation vector + inline DualQuaternion(const Quaternion& q, const Vector3& trans) + { + this->fromRotationTranslation(q, trans); + } + + /// Construct a dual quaternion from 8 manual w/x/y/z/dw/dx/dy/dz values + inline DualQuaternion(Real* valptr) + { + memcpy(&w, valptr, sizeof(Real)*8); + } + + /// Array accessor operator + inline Real operator [] ( const size_t i ) const + { + assert( i < 8 ); + + return *(&w+i); + } + + /// Array accessor operator + inline Real& operator [] ( const size_t i ) + { + assert( i < 8 ); + + return *(&w+i); + } + + inline DualQuaternion& operator= (const DualQuaternion& rkQ) + { + w = rkQ.w; + x = rkQ.x; + y = rkQ.y; + z = rkQ.z; + dw = rkQ.dw; + dx = rkQ.dx; + dy = rkQ.dy; + dz = rkQ.dz; + + return *this; + } + + inline bool operator== (const DualQuaternion& rhs) const + { + return (rhs.w == w) && (rhs.x == x) && (rhs.y == y) && (rhs.z == z) && + (rhs.dw == dw) && (rhs.dx == dx) && (rhs.dy == dy) && (rhs.dz == dz); + } + + inline bool operator!= (const DualQuaternion& rhs) const + { + return !operator==(rhs); + } + + /// Pointer accessor for direct copying + inline Real* ptr() + { + return &w; + } + + /// Pointer accessor for direct copying + inline const Real* ptr() const + { + return &w; + } + + /// Exchange the contents of this dual quaternion with another. + inline void swap(DualQuaternion& other) + { + std::swap(w, other.w); + std::swap(x, other.x); + std::swap(y, other.y); + std::swap(z, other.z); + std::swap(dw, other.dw); + std::swap(dx, other.dx); + std::swap(dy, other.dy); + std::swap(dz, other.dz); + } + + /// Check whether this dual quaternion contains valid values + inline bool isNaN() const + { + return Math::isNaN(w) || Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z) || + Math::isNaN(dw) || Math::isNaN(dx) || Math::isNaN(dy) || Math::isNaN(dz); + } + + /// Construct a dual quaternion from a rotation described by a Quaternion and a translation described by a Vector3 + void fromRotationTranslation (const Quaternion& q, const Vector3& trans); + + /// Convert a dual quaternion into its two components, a Quaternion representing the rotation and a Vector3 representing the translation + void toRotationTranslation (Quaternion& q, Vector3& translation) const; + + /// Construct a dual quaternion from a 4x4 transformation matrix + void fromTransformationMatrix (const Matrix4& kTrans); + + /// Convert a dual quaternion to a 4x4 transformation matrix + void toTransformationMatrix (Matrix4& kTrans) const; + + Real w, x, y, z, dw, dx, dy, dz; + + /** + Function for writing to a stream. Outputs "DualQuaternion(w, x, y, z, dw, dx, dy, dz)" with w, x, y, z, dw, dx, dy, dz + being the member values of the dual quaternion. + */ + inline _OgreExport friend std::ostream& operator << + ( std::ostream& o, const DualQuaternion& q ) + { + o << "DualQuaternion(" << q.w << ", " << q.x << ", " << q.y << ", " << q.z << ", " << q.dw << ", " << q.dx << ", " << q.dy << ", " << q.dz << ")"; + return o; + } + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreDynLib.h b/OgreMain/include/OgreDynLib.h index f830a44616b..22dcd2bb046 100644 --- a/OgreMain/include/OgreDynLib.h +++ b/OgreMain/include/OgreDynLib.h @@ -65,12 +65,12 @@ typedef struct HINSTANCE__* hInstance; #endif namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ /** Resource holding data about a dynamic library. @remarks @@ -81,10 +81,10 @@ namespace Ogre { @since 27 January 2002 */ - class _OgreExport DynLib : public DynLibAlloc + class _OgreExport DynLib : public DynLibAlloc { - protected: - String mName; + protected: + String mName; /// Gets the last loading error String dynlibError(void); public: @@ -104,8 +104,8 @@ namespace Ogre { /** Unload the library */ void unload(); - /// Get the name of the library - const String& getName(void) const { return mName; } + /// Get the name of the library + const String& getName(void) const { return mName; } /** Returns the address of the given symbol from the loaded library. @@ -125,8 +125,8 @@ namespace Ogre { /// Handle to the loaded library. DYNLIB_HANDLE mInst; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreETCCodec.h b/OgreMain/include/OgreETCCodec.h index b343b63f1af..cca82aa0012 100644 --- a/OgreMain/include/OgreETCCodec.h +++ b/OgreMain/include/OgreETCCodec.h @@ -31,17 +31,17 @@ THE SOFTWARE. #include "OgreImageCodec.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Image - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Image + * @{ + */ /** Codec specialized in loading ETC (Ericsson Texture Compression) images. - @remarks - We implement our own codec here since we need to be able to keep ETC - data compressed if the card supports it. + @remarks + We implement our own codec here since we need to be able to keep ETC + data compressed if the card supports it. */ class _OgreExport ETCCodec : public ImageCodec { @@ -49,13 +49,13 @@ namespace Ogre { String mType; void flipEndian(void * pData, size_t size, size_t count) const; - void flipEndian(void * pData, size_t size) const; + void flipEndian(void * pData, size_t size) const; - /// Single registered codec instance + /// Single registered codec instance static ETCCodec* msPKMInstance; static ETCCodec* msKTXInstance; - public: + public: ETCCodec(const String &type); virtual ~ETCCodec() { } @@ -65,22 +65,22 @@ namespace Ogre { void encodeToFile(MemoryDataStreamPtr& input, const String& outFileName, CodecDataPtr& pData) const; /// @copydoc Codec::decode DecodeResult decode(DataStreamPtr& input) const; - /// @copydoc Codec::magicNumberToFileExt - String magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const; + /// @copydoc Codec::magicNumberToFileExt + String magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const; virtual String getType() const; - /// Static method to startup and register the ETC codec - static void startup(void); - /// Static method to shutdown and unregister the ETC codec - static void shutdown(void); + /// Static method to startup and register the ETC codec + static void startup(void); + /// Static method to shutdown and unregister the ETC codec + static void shutdown(void); private: bool decodePKM(DataStreamPtr& input, DecodeResult& result) const; bool decodeKTX(DataStreamPtr& input, DecodeResult& result) const; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreEdgeListBuilder.h b/OgreMain/include/OgreEdgeListBuilder.h index 461f4bd13e7..4349ec55b01 100644 --- a/OgreMain/include/OgreEdgeListBuilder.h +++ b/OgreMain/include/OgreEdgeListBuilder.h @@ -36,12 +36,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ /** This class contains the information required to describe the edge connectivity of a @@ -50,12 +50,12 @@ namespace Ogre { This information is built using the EdgeListBuilder class. Note that for a given mesh, which can be made up of multiple submeshes, there are separate edge lists for when */ - class _OgreExport EdgeData : public EdgeDataAlloc + class _OgreExport EdgeData : public EdgeDataAlloc { public: - - EdgeData(); - + + EdgeData(); + /** Basic triangle structure. */ struct Triangle { /** The set of indexes this triangle came from (NB it is possible that the triangles on @@ -69,7 +69,7 @@ namespace Ogre { duplicates eliminated (this buffer is not exposed) */ size_t sharedVertIndex[3]; - Triangle() :indexSet(0), vertexSet(0) {} + Triangle() :indexSet(0), vertexSet(0) {} }; /** Edge data. */ struct Edge { @@ -151,7 +151,7 @@ namespace Ogre { */ void updateFaceNormals(size_t vertexSet, const HardwareVertexBufferSharedPtr& positionBuffer); - EdgeData* clone(); + EdgeData* clone(); /// Debugging method @@ -204,13 +204,13 @@ namespace Ogre { protected: /** A vertex can actually represent several vertices in the final model, because - vertices along texture seams etc will have been duplicated. In order to properly - evaluate the surface properties, a single common vertex is used for these duplicates, - and the faces hold the detail of the duplicated vertices. - */ + vertices along texture seams etc will have been duplicated. In order to properly + evaluate the surface properties, a single common vertex is used for these duplicates, + and the faces hold the detail of the duplicated vertices. + */ struct CommonVertex { Vector3 position; /// Location of point in euclidean space - size_t index; /// Place of vertex in common vertex list + size_t index; /// Place of vertex in common vertex list size_t vertexSet; /// The vertex set this came from size_t indexSet; /// The index set this was referenced (first) from size_t originalIndex; /// Place of vertex in original vertex set @@ -251,9 +251,9 @@ namespace Ogre { VertexDataList mVertexDataList; CommonVertexList mVertices; EdgeData* mEdgeData; - /// Map for identifying common vertices - typedef map::type CommonVertexMap; - CommonVertexMap mCommonVertexMap; + /// Map for identifying common vertices + typedef map::type CommonVertexMap; + CommonVertexMap mCommonVertexMap; /** Edge map, used to connect edges. Note we allow many triangles on an edge, after connected an existing edge, we will remove it and never used again. */ @@ -269,8 +269,8 @@ namespace Ogre { void connectOrCreateEdge(size_t vertexSet, size_t triangleIndex, size_t vertIndex0, size_t vertIndex1, size_t sharedVertIndex0, size_t sharedVertIndex1); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreEntity.h b/OgreMain/include/OgreEntity.h index 16d17d07043..2640150e786 100644 --- a/OgreMain/include/OgreEntity.h +++ b/OgreMain/include/OgreEntity.h @@ -254,14 +254,14 @@ namespace Ogre { typedef vector::type LODEntityList; LODEntityList mLodEntityList; #else - const ushort mMeshLodIndex; - const Real mMeshLodFactorTransformed; - const ushort mMinMeshLodIndex; - const ushort mMaxMeshLodIndex; - const Real mMaterialLodFactor; - const Real mMaterialLodFactorTransformed; - const ushort mMinMaterialLodIndex; - const ushort mMaxMaterialLodIndex; + const ushort mMeshLodIndex; + const Real mMeshLodFactorTransformed; + const ushort mMinMeshLodIndex; + const ushort mMaxMeshLodIndex; + const Real mMaterialLodFactor; + const Real mMaterialLodFactorTransformed; + const ushort mMinMaterialLodIndex; + const ushort mMaxMaterialLodIndex; #endif /** This Entity's personal copy of the skeleton, if skeletally animated. */ diff --git a/OgreMain/include/OgreException.h b/OgreMain/include/OgreException.h index b568fd7c02e..767d63ff53a 100644 --- a/OgreMain/include/OgreException.h +++ b/OgreMain/include/OgreException.h @@ -63,13 +63,13 @@ THE SOFTWARE. namespace Ogre { typedef _StringBase String; - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** When thrown, provides information about an error that has occurred inside the engine. + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** When thrown, provides information about an error that has occurred inside the engine. @remarks OGRE never uses return values to indicate errors. Instead, if an error occurs, an exception is thrown, and this is the object that @@ -82,16 +82,16 @@ namespace Ogre { object unless it wishes to unify its error handling using the same object. */ - class _OgreExport Exception : public std::exception + class _OgreExport Exception : public std::exception { protected: long line; int number; - String typeName; + String typeName; String description; String source; String file; - mutable String fullDesc; + mutable String fullDesc; public: /** Static definitions of error codes. @todo @@ -123,8 +123,8 @@ namespace Ogre { */ Exception(const Exception& rhs); - /// Needed for compatibility with std::exception - ~Exception() throw() {} + /// Needed for compatibility with std::exception + ~Exception() throw() {} /** Assignment operator. */ @@ -158,185 +158,185 @@ namespace Ogre { */ virtual long getLine() const { return line; } - /** Returns a string with only the 'description' field of this exception. Use - getFullDescriptionto get a full description of the error including line number, - error number and what function threw the exception. + /** Returns a string with only the 'description' field of this exception. Use + getFullDescriptionto get a full description of the error including line number, + error number and what function threw the exception. */ - virtual const String &getDescription(void) const { return description; } + virtual const String &getDescription(void) const { return description; } - /// Override std::exception::what - const char* what() const throw() { return getFullDescription().c_str(); } + /// Override std::exception::what + const char* what() const throw() { return getFullDescription().c_str(); } }; - /** Template struct which creates a distinct type for each exception code. - @note - This is useful because it allows us to create an overloaded method - for returning different exception types by value without ambiguity. - From 'Modern C++ Design' (Alexandrescu 2001). - */ - template - struct ExceptionCodeType - { - enum { number = num }; - }; - - // Specialised exceptions allowing each to be caught specifically - // backwards-compatible since exception codes still used - - class _OgreExport UnimplementedException : public Exception - { - public: - UnimplementedException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) - : Exception(inNumber, inDescription, inSource, "UnimplementedException", inFile, inLine) {} - }; - class _OgreExport FileNotFoundException : public Exception - { - public: - FileNotFoundException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) - : Exception(inNumber, inDescription, inSource, "FileNotFoundException", inFile, inLine) {} - }; - class _OgreExport IOException : public Exception - { - public: - IOException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) - : Exception(inNumber, inDescription, inSource, "IOException", inFile, inLine) {} - }; - class _OgreExport InvalidStateException : public Exception - { - public: - InvalidStateException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) - : Exception(inNumber, inDescription, inSource, "InvalidStateException", inFile, inLine) {} - }; - class _OgreExport InvalidParametersException : public Exception - { - public: - InvalidParametersException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) - : Exception(inNumber, inDescription, inSource, "InvalidParametersException", inFile, inLine) {} - }; - class _OgreExport ItemIdentityException : public Exception - { - public: - ItemIdentityException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) - : Exception(inNumber, inDescription, inSource, "ItemIdentityException", inFile, inLine) {} - }; - class _OgreExport InternalErrorException : public Exception - { - public: - InternalErrorException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) - : Exception(inNumber, inDescription, inSource, "InternalErrorException", inFile, inLine) {} - }; - class _OgreExport RenderingAPIException : public Exception - { - public: - RenderingAPIException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) - : Exception(inNumber, inDescription, inSource, "RenderingAPIException", inFile, inLine) {} - }; - class _OgreExport RuntimeAssertionException : public Exception - { - public: - RuntimeAssertionException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) - : Exception(inNumber, inDescription, inSource, "RuntimeAssertionException", inFile, inLine) {} - }; - - - /** Class implementing dispatch methods in order to construct by-value - exceptions of a derived type based just on an exception code. - @remarks - This nicely handles construction of derived Exceptions by value (needed - for throwing) without suffering from ambiguity - each code is turned into - a distinct type so that methods can be overloaded. This allows OGRE_EXCEPT - to stay small in implementation (desirable since it is embedded) whilst - still performing rich code-to-type mapping. - */ - class ExceptionFactory - { - private: - /// Private constructor, no construction - ExceptionFactory() {} - public: - static UnimplementedException create( - ExceptionCodeType /*code*/, - const String& desc, - const String& src, const char* file, long line) - { - return UnimplementedException(Exception::ERR_NOT_IMPLEMENTED, desc, src, file, line); - } - static FileNotFoundException create( - ExceptionCodeType /*code*/, - const String& desc, - const String& src, const char* file, long line) - { - return FileNotFoundException(Exception::ERR_FILE_NOT_FOUND, desc, src, file, line); - } - static IOException create( - ExceptionCodeType /*code*/, - const String& desc, - const String& src, const char* file, long line) - { - return IOException(Exception::ERR_CANNOT_WRITE_TO_FILE, desc, src, file, line); - } - static InvalidStateException create( - ExceptionCodeType /*code*/, - const String& desc, - const String& src, const char* file, long line) - { - return InvalidStateException(Exception::ERR_INVALID_STATE, desc, src, file, line); - } - static InvalidParametersException create( - ExceptionCodeType /*code*/, - const String& desc, - const String& src, const char* file, long line) - { - return InvalidParametersException(Exception::ERR_INVALIDPARAMS, desc, src, file, line); - } - static ItemIdentityException create( - ExceptionCodeType /*code*/, - const String& desc, - const String& src, const char* file, long line) - { - return ItemIdentityException(Exception::ERR_ITEM_NOT_FOUND, desc, src, file, line); - } - static ItemIdentityException create( - ExceptionCodeType /*code*/, - const String& desc, - const String& src, const char* file, long line) - { - return ItemIdentityException(Exception::ERR_DUPLICATE_ITEM, desc, src, file, line); - } - static InternalErrorException create( - ExceptionCodeType /*code*/, - const String& desc, - const String& src, const char* file, long line) - { - return InternalErrorException(Exception::ERR_INTERNAL_ERROR, desc, src, file, line); - } - static RenderingAPIException create( - ExceptionCodeType /*code*/, - const String& desc, - const String& src, const char* file, long line) - { - return RenderingAPIException(Exception::ERR_RENDERINGAPI_ERROR, desc, src, file, line); - } - static RuntimeAssertionException create( - ExceptionCodeType /*code*/, - const String& desc, - const String& src, const char* file, long line) - { - return RuntimeAssertionException(Exception::ERR_RT_ASSERTION_FAILED, desc, src, file, line); - } - - }; - - - + /** Template struct which creates a distinct type for each exception code. + @note + This is useful because it allows us to create an overloaded method + for returning different exception types by value without ambiguity. + From 'Modern C++ Design' (Alexandrescu 2001). + */ + template + struct ExceptionCodeType + { + enum { number = num }; + }; + + // Specialised exceptions allowing each to be caught specifically + // backwards-compatible since exception codes still used + + class _OgreExport UnimplementedException : public Exception + { + public: + UnimplementedException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) + : Exception(inNumber, inDescription, inSource, "UnimplementedException", inFile, inLine) {} + }; + class _OgreExport FileNotFoundException : public Exception + { + public: + FileNotFoundException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) + : Exception(inNumber, inDescription, inSource, "FileNotFoundException", inFile, inLine) {} + }; + class _OgreExport IOException : public Exception + { + public: + IOException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) + : Exception(inNumber, inDescription, inSource, "IOException", inFile, inLine) {} + }; + class _OgreExport InvalidStateException : public Exception + { + public: + InvalidStateException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) + : Exception(inNumber, inDescription, inSource, "InvalidStateException", inFile, inLine) {} + }; + class _OgreExport InvalidParametersException : public Exception + { + public: + InvalidParametersException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) + : Exception(inNumber, inDescription, inSource, "InvalidParametersException", inFile, inLine) {} + }; + class _OgreExport ItemIdentityException : public Exception + { + public: + ItemIdentityException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) + : Exception(inNumber, inDescription, inSource, "ItemIdentityException", inFile, inLine) {} + }; + class _OgreExport InternalErrorException : public Exception + { + public: + InternalErrorException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) + : Exception(inNumber, inDescription, inSource, "InternalErrorException", inFile, inLine) {} + }; + class _OgreExport RenderingAPIException : public Exception + { + public: + RenderingAPIException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) + : Exception(inNumber, inDescription, inSource, "RenderingAPIException", inFile, inLine) {} + }; + class _OgreExport RuntimeAssertionException : public Exception + { + public: + RuntimeAssertionException(int inNumber, const String& inDescription, const String& inSource, const char* inFile, long inLine) + : Exception(inNumber, inDescription, inSource, "RuntimeAssertionException", inFile, inLine) {} + }; + + + /** Class implementing dispatch methods in order to construct by-value + exceptions of a derived type based just on an exception code. + @remarks + This nicely handles construction of derived Exceptions by value (needed + for throwing) without suffering from ambiguity - each code is turned into + a distinct type so that methods can be overloaded. This allows OGRE_EXCEPT + to stay small in implementation (desirable since it is embedded) whilst + still performing rich code-to-type mapping. + */ + class ExceptionFactory + { + private: + /// Private constructor, no construction + ExceptionFactory() {} + public: + static UnimplementedException create( + ExceptionCodeType /*code*/, + const String& desc, + const String& src, const char* file, long line) + { + return UnimplementedException(Exception::ERR_NOT_IMPLEMENTED, desc, src, file, line); + } + static FileNotFoundException create( + ExceptionCodeType /*code*/, + const String& desc, + const String& src, const char* file, long line) + { + return FileNotFoundException(Exception::ERR_FILE_NOT_FOUND, desc, src, file, line); + } + static IOException create( + ExceptionCodeType /*code*/, + const String& desc, + const String& src, const char* file, long line) + { + return IOException(Exception::ERR_CANNOT_WRITE_TO_FILE, desc, src, file, line); + } + static InvalidStateException create( + ExceptionCodeType /*code*/, + const String& desc, + const String& src, const char* file, long line) + { + return InvalidStateException(Exception::ERR_INVALID_STATE, desc, src, file, line); + } + static InvalidParametersException create( + ExceptionCodeType /*code*/, + const String& desc, + const String& src, const char* file, long line) + { + return InvalidParametersException(Exception::ERR_INVALIDPARAMS, desc, src, file, line); + } + static ItemIdentityException create( + ExceptionCodeType /*code*/, + const String& desc, + const String& src, const char* file, long line) + { + return ItemIdentityException(Exception::ERR_ITEM_NOT_FOUND, desc, src, file, line); + } + static ItemIdentityException create( + ExceptionCodeType /*code*/, + const String& desc, + const String& src, const char* file, long line) + { + return ItemIdentityException(Exception::ERR_DUPLICATE_ITEM, desc, src, file, line); + } + static InternalErrorException create( + ExceptionCodeType /*code*/, + const String& desc, + const String& src, const char* file, long line) + { + return InternalErrorException(Exception::ERR_INTERNAL_ERROR, desc, src, file, line); + } + static RenderingAPIException create( + ExceptionCodeType /*code*/, + const String& desc, + const String& src, const char* file, long line) + { + return RenderingAPIException(Exception::ERR_RENDERINGAPI_ERROR, desc, src, file, line); + } + static RuntimeAssertionException create( + ExceptionCodeType /*code*/, + const String& desc, + const String& src, const char* file, long line) + { + return RuntimeAssertionException(Exception::ERR_RT_ASSERTION_FAILED, desc, src, file, line); + } + + }; + + + #ifndef OGRE_EXCEPT #define OGRE_EXCEPT(num, desc, src) throw Ogre::ExceptionFactory::create( \ - Ogre::ExceptionCodeType(), desc, src, __FILE__, __LINE__ ); + Ogre::ExceptionCodeType(), desc, src, __FILE__, __LINE__ ); #endif - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // Namespace Ogre diff --git a/OgreMain/include/OgreExternalTextureSource.h b/OgreMain/include/OgreExternalTextureSource.h index 5e8830de260..49b309222a5 100644 --- a/OgreMain/include/OgreExternalTextureSource.h +++ b/OgreMain/include/OgreExternalTextureSource.h @@ -30,14 +30,14 @@ THE SOFTWARE. /*************************************************************************** OgreExternalTextureSource.h - - Base class that texture plugins need to derive from. This provides the hooks - necessary for a plugin developer to easily extend the functionality of dynamic textures. - It makes creation/destruction of dynamic textures more streamlined. While the plugin - will need to talk with Ogre for the actual modification of textures, this class allows - easy integration with Ogre apps. Material script files can be used to aid in the - creation of dynamic textures. Functionality can be added that is not defined here - through the use of the base dictionary. For an example of how to use this class and the - string interface see ffmpegVideoPlugIn. + Base class that texture plugins need to derive from. This provides the hooks + necessary for a plugin developer to easily extend the functionality of dynamic textures. + It makes creation/destruction of dynamic textures more streamlined. While the plugin + will need to talk with Ogre for the actual modification of textures, this class allows + easy integration with Ogre apps. Material script files can be used to aid in the + creation of dynamic textures. Functionality can be added that is not defined here + through the use of the base dictionary. For an example of how to use this class and the + string interface see ffmpegVideoPlugIn. ------------------- date : Jan 1 2004 @@ -50,143 +50,143 @@ email : pjcast@yahoo.com namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Materials - * @{ - */ - /** Enum for type of texture play mode */ - enum eTexturePlayMode - { - TextureEffectPause = 0, /// Video starts out paused - TextureEffectPlay_ASAP = 1, /// Video starts playing as soon as possible - TextureEffectPlay_Looping = 2 /// Video Plays Instantly && Loops - }; - - /** IMPORTANT: **Plugins must override default dictionary name!** - Base class that texture plugins derive from. Any specific - requirements that the plugin needs to have defined before - texture/material creation must be define using the stringinterface - before calling create defined texture... or it will fail, though, it - is up to the plugin to report errors to the log file, or raise an - exception if need be. */ - class _OgreExport ExternalTextureSource : public StringInterface - { - public: - /** Constructor */ - ExternalTextureSource(); - /** Virtual destructor */ - virtual ~ExternalTextureSource() {} - - //------------------------------------------------------------------------------// - /* Command objects for specifying some base features */ - /* Any Plugins wishing to add more specific params to "ExternalTextureSourcePlugins"*/ - /* dictionary, feel free to do so, that's why this is here */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Materials + * @{ + */ + /** Enum for type of texture play mode */ + enum eTexturePlayMode + { + TextureEffectPause = 0, /// Video starts out paused + TextureEffectPlay_ASAP = 1, /// Video starts playing as soon as possible + TextureEffectPlay_Looping = 2 /// Video Plays Instantly && Loops + }; + + /** IMPORTANT: **Plugins must override default dictionary name!** + Base class that texture plugins derive from. Any specific + requirements that the plugin needs to have defined before + texture/material creation must be define using the stringinterface + before calling create defined texture... or it will fail, though, it + is up to the plugin to report errors to the log file, or raise an + exception if need be. */ + class _OgreExport ExternalTextureSource : public StringInterface + { + public: + /** Constructor */ + ExternalTextureSource(); + /** Virtual destructor */ + virtual ~ExternalTextureSource() {} + + //------------------------------------------------------------------------------// + /* Command objects for specifying some base features */ + /* Any Plugins wishing to add more specific params to "ExternalTextureSourcePlugins"*/ + /* dictionary, feel free to do so, that's why this is here */ class _OgrePrivate CmdInputFileName : public ParamCommand { public: - String doGet(const void* target) const; + String doGet(const void* target) const; void doSet(void* target, const String& val); }; class _OgrePrivate CmdFPS : public ParamCommand { public: - String doGet(const void* target) const; + String doGet(const void* target) const; void doSet(void* target, const String& val); }; class _OgrePrivate CmdPlayMode : public ParamCommand { public: - String doGet(const void* target) const; + String doGet(const void* target) const; void doSet(void* target, const String& val); }; class _OgrePrivate CmdTecPassState : public ParamCommand { public: - String doGet(const void* target) const; + String doGet(const void* target) const; void doSet(void* target, const String& val); }; - //--------------------------------------------------------// - //Base Functions that work with Command String Interface... Or can be called - //manually to create video through code - - /// Sets an input file name - if needed by plugin - void setInputName( const String &sIN ) { mInputFileName = sIN; } - /// Gets currently set input file name - const String& getInputName( ) const { return mInputFileName; } - /// Sets the frames per second - plugin may or may not use this - void setFPS( int iFPS ) { mFramesPerSecond = iFPS; } - /// Gets currently set frames per second - int getFPS( ) const { return mFramesPerSecond; } - /// Sets a play mode - void setPlayMode( eTexturePlayMode eMode ) { mMode = eMode; } - /// Gets currently set play mode - eTexturePlayMode getPlayMode() const { return mMode; } - - /// Used for attaching texture to Technique, State, and texture unit layer - void setTextureTecPassStateLevel( int t, int p, int s ) - { mTechniqueLevel = t;mPassLevel = p;mStateLevel = s; } - /// Get currently selected Texture attribs. - void getTextureTecPassStateLevel( int& t, int& p, int& s ) const - {t = mTechniqueLevel; p = mPassLevel; s = mStateLevel;} - - /** Call from derived classes to ensure the dictionary is setup */ - void addBaseParams(); - - /** Returns the string name of this Plugin (as set by the Plugin)*/ - const String& getPluginStringName( void ) const { return mPluginName; } - /** Returns dictionary name */ - const String& getDictionaryStringName( void ) const { return mDictionaryName; } - - //Pure virtual functions that plugins must Override - /** Call this function from manager to init system */ - virtual bool initialise() = 0; - /** Shuts down Plugin */ - virtual void shutDown() = 0; - - /** Creates a texture into an already defined material or one that is created new - (it's up to plugin to use a material or create one) - Before calling, ensure that needed params have been defined via the stringInterface - or regular methods */ - virtual void createDefinedTexture( const String& sMaterialName, - const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) = 0; - /** What this destroys is dependent on the plugin... See specific plugin - doc to know what is all destroyed (normally, plugins will destroy only - what they created, or used directly - ie. just texture unit) */ - virtual void destroyAdvancedTexture( const String& sTextureName, - const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) = 0; - - protected: - static CmdInputFileName msCmdInputFile; /// Command for setting input file name - static CmdFPS msCmdFramesPerSecond; /// Command for setting frames per second - static CmdPlayMode msCmdPlayMode; /// Command for setting play mode - static CmdTecPassState msCmdTecPassState; /// Command for setting the technique, pass, & state level - - - /// String Name of this Plugin - String mPluginName; - - //------ Vars used for setting/getting dictionary stuff -----------// - eTexturePlayMode mMode; - - String mInputFileName; - - bool mUpdateEveryFrame; - - int mFramesPerSecond, - mTechniqueLevel, - mPassLevel, - mStateLevel; - //------------------------------------------------------------------// - - protected: - /** The string name of the dictionary name - each plugin - must override default name */ - String mDictionaryName; - }; - /** @} */ - /** @} */ + //--------------------------------------------------------// + //Base Functions that work with Command String Interface... Or can be called + //manually to create video through code + + /// Sets an input file name - if needed by plugin + void setInputName( const String &sIN ) { mInputFileName = sIN; } + /// Gets currently set input file name + const String& getInputName( ) const { return mInputFileName; } + /// Sets the frames per second - plugin may or may not use this + void setFPS( int iFPS ) { mFramesPerSecond = iFPS; } + /// Gets currently set frames per second + int getFPS( ) const { return mFramesPerSecond; } + /// Sets a play mode + void setPlayMode( eTexturePlayMode eMode ) { mMode = eMode; } + /// Gets currently set play mode + eTexturePlayMode getPlayMode() const { return mMode; } + + /// Used for attaching texture to Technique, State, and texture unit layer + void setTextureTecPassStateLevel( int t, int p, int s ) + { mTechniqueLevel = t;mPassLevel = p;mStateLevel = s; } + /// Get currently selected Texture attribs. + void getTextureTecPassStateLevel( int& t, int& p, int& s ) const + {t = mTechniqueLevel; p = mPassLevel; s = mStateLevel;} + + /** Call from derived classes to ensure the dictionary is setup */ + void addBaseParams(); + + /** Returns the string name of this Plugin (as set by the Plugin)*/ + const String& getPluginStringName( void ) const { return mPluginName; } + /** Returns dictionary name */ + const String& getDictionaryStringName( void ) const { return mDictionaryName; } + + //Pure virtual functions that plugins must Override + /** Call this function from manager to init system */ + virtual bool initialise() = 0; + /** Shuts down Plugin */ + virtual void shutDown() = 0; + + /** Creates a texture into an already defined material or one that is created new + (it's up to plugin to use a material or create one) + Before calling, ensure that needed params have been defined via the stringInterface + or regular methods */ + virtual void createDefinedTexture( const String& sMaterialName, + const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) = 0; + /** What this destroys is dependent on the plugin... See specific plugin + doc to know what is all destroyed (normally, plugins will destroy only + what they created, or used directly - ie. just texture unit) */ + virtual void destroyAdvancedTexture( const String& sTextureName, + const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) = 0; + + protected: + static CmdInputFileName msCmdInputFile; /// Command for setting input file name + static CmdFPS msCmdFramesPerSecond; /// Command for setting frames per second + static CmdPlayMode msCmdPlayMode; /// Command for setting play mode + static CmdTecPassState msCmdTecPassState; /// Command for setting the technique, pass, & state level + + + /// String Name of this Plugin + String mPluginName; + + //------ Vars used for setting/getting dictionary stuff -----------// + eTexturePlayMode mMode; + + String mInputFileName; + + bool mUpdateEveryFrame; + + int mFramesPerSecond, + mTechniqueLevel, + mPassLevel, + mStateLevel; + //------------------------------------------------------------------// + + protected: + /** The string name of the dictionary name - each plugin + must override default name */ + String mDictionaryName; + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreExternalTextureSourceManager.h b/OgreMain/include/OgreExternalTextureSourceManager.h index bf477d29dec..7e40fb61068 100644 --- a/OgreMain/include/OgreExternalTextureSourceManager.h +++ b/OgreMain/include/OgreExternalTextureSourceManager.h @@ -30,7 +30,7 @@ THE SOFTWARE. /*************************************************************************** OgreExternalTextureSourceManager.h - - Handles the registering / unregistering of texture modifier plugins + Handles the registering / unregistering of texture modifier plugins ------------------- date : Jan 1 2004 @@ -43,40 +43,40 @@ email : pjcast@yahoo.com namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Materials - * @{ - */ - /** - Singleton Class which handles the registering and control of texture plugins. The plugins - will be mostly controlled via a string interface. */ - class _OgreExport ExternalTextureSourceManager : public Singleton, public ResourceAlloc - { - public: - /** Constructor */ - ExternalTextureSourceManager(); - /** Destructor */ - ~ExternalTextureSourceManager(); + /** \addtogroup Core + * @{ + */ + /** \addtogroup Materials + * @{ + */ + /** + Singleton Class which handles the registering and control of texture plugins. The plugins + will be mostly controlled via a string interface. */ + class _OgreExport ExternalTextureSourceManager : public Singleton, public ResourceAlloc + { + public: + /** Constructor */ + ExternalTextureSourceManager(); + /** Destructor */ + ~ExternalTextureSourceManager(); - /** Sets active plugin (ie. "video", "effect", "generic", etc..) */ - void setCurrentPlugIn( const String& sTexturePlugInType ); + /** Sets active plugin (ie. "video", "effect", "generic", etc..) */ + void setCurrentPlugIn( const String& sTexturePlugInType ); - /** Returns currently selected plugin, may be null if none selected */ - ExternalTextureSource* getCurrentPlugIn( void ) const { return mCurrExternalTextureSource; } - - /** Calls the destroy method of all registered plugins... - Only the owner plugin should perform the destroy action. */ - void destroyAdvancedTexture( const String& sTextureName, - const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + /** Returns currently selected plugin, may be null if none selected */ + ExternalTextureSource* getCurrentPlugIn( void ) const { return mCurrExternalTextureSource; } + + /** Calls the destroy method of all registered plugins... + Only the owner plugin should perform the destroy action. */ + void destroyAdvancedTexture( const String& sTextureName, + const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - /** Returns the plugin which registered itself with a specific name - (eg. "video"), or null if specified plugin not found */ - ExternalTextureSource* getExternalTextureSource( const String& sTexturePlugInType ); + /** Returns the plugin which registered itself with a specific name + (eg. "video"), or null if specified plugin not found */ + ExternalTextureSource* getExternalTextureSource( const String& sTexturePlugInType ); - /** Called from plugin to register itself */ - void setExternalTextureSource( const String& sTexturePlugInType, ExternalTextureSource* pTextureSystem ); + /** Called from plugin to register itself */ + void setExternalTextureSource( const String& sTexturePlugInType, ExternalTextureSource* pTextureSystem ); /** Override standard Singleton retrieval. @remarks @@ -110,16 +110,16 @@ namespace Ogre preventing link errors. */ static ExternalTextureSourceManager* getSingletonPtr(void); - protected: - /// The current texture controller selected - ExternalTextureSource* mCurrExternalTextureSource; - + protected: + /// The current texture controller selected + ExternalTextureSource* mCurrExternalTextureSource; + // Collection of loaded texture System PlugIns, keyed by registered type typedef map< String, ExternalTextureSource*>::type TextureSystemList; TextureSystemList mTextureSystems; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreFileSystemLayer.h b/OgreMain/include/OgreFileSystemLayer.h index 5e63839e9fb..a5e087bc704 100644 --- a/OgreMain/include/OgreFileSystemLayer.h +++ b/OgreMain/include/OgreFileSystemLayer.h @@ -33,36 +33,36 @@ namespace Ogre { - /** Provides methods to find out where the Ogre config files are stored - and where logs and settings files should be written to. - @remarks - In modern multi-user OS, a standard user account will often not - have write access to the path where the SampleBrowser is stored. - In order to still be able to store graphics settings and log - output and for the user to overwrite the default Ogre config files, - this class tries to create a folder inside the user's home directory. - Specialised implementations for each individual platform must - subclass this abstract interface. - */ + /** Provides methods to find out where the Ogre config files are stored + and where logs and settings files should be written to. + @remarks + In modern multi-user OS, a standard user account will often not + have write access to the path where the SampleBrowser is stored. + In order to still be able to store graphics settings and log + output and for the user to overwrite the default Ogre config files, + this class tries to create a folder inside the user's home directory. + Specialised implementations for each individual platform must + subclass this abstract interface. + */ /** Implementation for the FileSystemLayer interface. */ - class _OgreExport FileSystemLayer : public FileSystemLayerAlloc - { - public: - /** Creates a concrete platform-dependent implementation of FileSystemLayer. + class _OgreExport FileSystemLayer : public FileSystemLayerAlloc + { + public: + /** Creates a concrete platform-dependent implementation of FileSystemLayer. @param subdir A subdirectory inside the user's path to distinguish between different Ogre releases. - */ - FileSystemLayer(const Ogre::String& subdir) - { - // determine directories to search for config files - getConfigPaths(); - // prepare write location in user directory - prepareUserHome(subdir); - } + */ + FileSystemLayer(const Ogre::String& subdir) + { + // determine directories to search for config files + getConfigPaths(); + // prepare write location in user directory + prepareUserHome(subdir); + } - /** Search for the given config file in the user's home path. If it can't + /** Search for the given config file in the user's home path. If it can't be found there, the function falls back to the system-wide install path for Ogre config files. (Usually the same place where the SampleBrowser resides, or a special config path above that path.) @@ -70,72 +70,72 @@ namespace Ogre The config file name (without path) @return The full path to the config file. - */ - const Ogre::String getConfigFilePath(Ogre::String filename) const - { + */ + const Ogre::String getConfigFilePath(Ogre::String filename) const + { #if OGRE_DEBUG_MODE == 1 && (OGRE_PLATFORM != OGRE_PLATFORM_APPLE && OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) - // add OGRE_BUILD_SUFFIX (default: "_d") to config file names - Ogre::String::size_type pos = filename.rfind('.'); - if (pos != Ogre::String::npos) - filename = filename.substr(0, pos) + OGRE_BUILD_SUFFIX + filename.substr(pos); + // add OGRE_BUILD_SUFFIX (default: "_d") to config file names + Ogre::String::size_type pos = filename.rfind('.'); + if (pos != Ogre::String::npos) + filename = filename.substr(0, pos) + OGRE_BUILD_SUFFIX + filename.substr(pos); #endif - // look for the requested file in several locations: + // look for the requested file in several locations: - // 1. in the writable path (so user can provide custom files) - Ogre::String path = getWritablePath(filename); - if (fileExists(path)) - return path; + // 1. in the writable path (so user can provide custom files) + Ogre::String path = getWritablePath(filename); + if (fileExists(path)) + return path; - // 2. in the config file search paths - for (size_t i = 0; i < mConfigPaths.size(); ++i) - { - path = mConfigPaths[i] + filename; - if (fileExists(path)) - return path; - } + // 2. in the config file search paths + for (size_t i = 0; i < mConfigPaths.size(); ++i) + { + path = mConfigPaths[i] + filename; + if (fileExists(path)) + return path; + } - // 3. fallback to current working dir - return filename; - } + // 3. fallback to current working dir + return filename; + } - /** Find a path where the given filename can be written to. This path + /** Find a path where the given filename can be written to. This path will usually be in the user's home directory. This function should be used for any output like logs and graphics settings. @param filename Name of the file. @return The full path to a writable location for the given filename. - */ - const Ogre::String getWritablePath(const Ogre::String& filename) const - { - return mHomePath + filename; - } - - void setConfigPaths(const Ogre::StringVector &paths){ - mConfigPaths = paths; - } - - void setHomePath(const Ogre::String &path){ - mHomePath = path; - } + */ + const Ogre::String getWritablePath(const Ogre::String& filename) const + { + return mHomePath + filename; + } - /** Create a directory */ - bool createDirectory(const Ogre::String& name); + void setConfigPaths(const Ogre::StringVector &paths){ + mConfigPaths = paths; + } - private: - Ogre::StringVector mConfigPaths; - Ogre::String mHomePath; + void setHomePath(const Ogre::String &path){ + mHomePath = path; + } - /** Determine config search paths. */ - void getConfigPaths(); + /** Create a directory */ + bool createDirectory(const Ogre::String& name); - /** Create an Ogre directory and the given subdir in the user's home. */ - void prepareUserHome(const Ogre::String& subdir); + private: + Ogre::StringVector mConfigPaths; + Ogre::String mHomePath; - /** Test if the given file exists. */ - bool fileExists(const Ogre::String& path) const; - }; + /** Determine config search paths. */ + void getConfigPaths(); + + /** Create an Ogre directory and the given subdir in the user's home. */ + void prepareUserHome(const Ogre::String& subdir); + + /** Test if the given file exists. */ + bool fileExists(const Ogre::String& path) const; + }; } diff --git a/OgreMain/include/OgreFrameListener.h b/OgreMain/include/OgreFrameListener.h index 63d77429738..9b633162795 100644 --- a/OgreMain/include/OgreFrameListener.h +++ b/OgreMain/include/OgreFrameListener.h @@ -33,13 +33,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** Struct containing information about a frame event. + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** Struct containing information about a frame event. */ struct FrameEvent { @@ -88,38 +88,38 @@ namespace Ogre { */ public: /** Called when a frame is about to begin rendering. - @remarks - This event happens before any render targets have begun updating. + @remarks + This event happens before any render targets have begun updating. @return True to go ahead, false to abort rendering and drop out of the rendering loop. */ virtual bool frameStarted(const FrameEvent& evt) { (void)evt; return true; } - - /** Called after all render targets have had their rendering commands - issued, but before render windows have been asked to flip their - buffers over. - @remarks - The usefulness of this event comes from the fact that rendering - commands are queued for the GPU to process. These can take a little - while to finish, and so while that is happening the CPU can be doing - useful things. Once the request to 'flip buffers' happens, the thread - requesting it will block until the GPU is ready, which can waste CPU - cycles. Therefore, it is often a good idea to use this callback to - perform per-frame processing. Of course because the frame's rendering - commands have already been issued, any changes you make will only - take effect from the next frame, but in most cases that's not noticeable. - @return - True to continue rendering, false to drop out of the rendering loop. - */ - virtual bool frameRenderingQueued(const FrameEvent& evt) + + /** Called after all render targets have had their rendering commands + issued, but before render windows have been asked to flip their + buffers over. + @remarks + The usefulness of this event comes from the fact that rendering + commands are queued for the GPU to process. These can take a little + while to finish, and so while that is happening the CPU can be doing + useful things. Once the request to 'flip buffers' happens, the thread + requesting it will block until the GPU is ready, which can waste CPU + cycles. Therefore, it is often a good idea to use this callback to + perform per-frame processing. Of course because the frame's rendering + commands have already been issued, any changes you make will only + take effect from the next frame, but in most cases that's not noticeable. + @return + True to continue rendering, false to drop out of the rendering loop. + */ + virtual bool frameRenderingQueued(const FrameEvent& evt) { (void)evt; return true; } /** Called just after a frame has been rendered. - @remarks - This event happens after all render targets have been fully updated - and the buffers switched. + @remarks + This event happens after all render targets have been fully updated + and the buffers switched. @return True to continue with the next frame, false to drop out of the rendering loop. @@ -127,11 +127,11 @@ namespace Ogre { virtual bool frameEnded(const FrameEvent& evt) { (void)evt; return true; } - virtual ~FrameListener() {} - + virtual ~FrameListener() {} + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreFreeImageCodec.h b/OgreMain/include/OgreFreeImageCodec.h index 4eeb29d68b1..74a05424228 100644 --- a/OgreMain/include/OgreFreeImageCodec.h +++ b/OgreMain/include/OgreFreeImageCodec.h @@ -34,13 +34,13 @@ struct FIBITMAP; namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Image - * @{ - */ - /** Codec specialized in images loaded using FreeImage. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Image + * @{ + */ + /** Codec specialized in images loaded using FreeImage. @remarks The users implementing subclasses of ImageCodec are required to return a valid pointer to a ImageData class from the decode(...) function. @@ -51,11 +51,11 @@ namespace Ogre { String mType; unsigned int mFreeImageType; - typedef list::type RegisteredCodecList; - static RegisteredCodecList msCodecList; + typedef list::type RegisteredCodecList; + static RegisteredCodecList msCodecList; - /** Common encoding routine. */ - FIBITMAP* encodeBitmap(MemoryDataStreamPtr& input, CodecDataPtr& pData) const; + /** Common encoding routine. */ + FIBITMAP* encodeBitmap(MemoryDataStreamPtr& input, CodecDataPtr& pData) const; public: FreeImageCodec(const String &type, unsigned int fiType); @@ -71,16 +71,16 @@ namespace Ogre { virtual String getType() const; - /// @copydoc Codec::magicNumberToFileExt - String magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const; + /// @copydoc Codec::magicNumberToFileExt + String magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const; - /// Static method to startup FreeImage and register the FreeImage codecs - static void startup(void); - /// Static method to shutdown FreeImage and unregister the FreeImage codecs - static void shutdown(void); + /// Static method to startup FreeImage and register the FreeImage codecs + static void startup(void); + /// Static method to shutdown FreeImage and unregister the FreeImage codecs + static void shutdown(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreGpuProgramManager.h b/OgreMain/include/OgreGpuProgramManager.h index a36d90e7067..9a7a0610e70 100644 --- a/OgreMain/include/OgreGpuProgramManager.h +++ b/OgreMain/include/OgreGpuProgramManager.h @@ -39,81 +39,81 @@ namespace Ogre { //TODO Add documentation and explain rationale of this class. - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - class _OgreExport GpuProgramManager : public ResourceManager, public Singleton - { - public: - - typedef set::type SyntaxCodes; - typedef map::type SharedParametersMap; - - typedef MemoryDataStreamPtr Microcode; - typedef map::type MicrocodeMap; - - protected: - - SharedParametersMap mSharedParametersMap; - MicrocodeMap mMicrocodeCache; - bool mSaveMicrocodesToCache; - bool mCacheDirty; // When this is true the cache is 'dirty' and should be resaved to disk. - - static String addRenderSystemToName( const String & name ); + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + class _OgreExport GpuProgramManager : public ResourceManager, public Singleton + { + public: + + typedef set::type SyntaxCodes; + typedef map::type SharedParametersMap; + + typedef MemoryDataStreamPtr Microcode; + typedef map::type MicrocodeMap; + + protected: + + SharedParametersMap mSharedParametersMap; + MicrocodeMap mMicrocodeCache; + bool mSaveMicrocodesToCache; + bool mCacheDirty; // When this is true the cache is 'dirty' and should be resaved to disk. + + static String addRenderSystemToName( const String & name ); /// Specialised create method with specific parameters virtual Resource* createImpl(const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader, GpuProgramType gptype, const String& syntaxCode) = 0; - public: - GpuProgramManager(); - virtual ~GpuProgramManager(); + public: + GpuProgramManager(); + virtual ~GpuProgramManager(); - /// Get a resource by name - /// @see GpuProgramManager::getResourceByName - GpuProgramPtr getByName(const String& name, bool preferHighLevelPrograms = true); + /// Get a resource by name + /// @see GpuProgramManager::getResourceByName + GpuProgramPtr getByName(const String& name, bool preferHighLevelPrograms = true); /** Loads a GPU program from a file of assembly. - @remarks - This method creates a new program of the type specified as the second parameter. - As with all types of ResourceManager, this class will search for the file in - all resource locations it has been configured to look in. - @param name The name of the GpuProgram - @param groupName The name of the resource group - @param filename The file to load - @param gptype The type of program to create + @remarks + This method creates a new program of the type specified as the second parameter. + As with all types of ResourceManager, this class will search for the file in + all resource locations it has been configured to look in. + @param name The name of the GpuProgram + @param groupName The name of the resource group + @param filename The file to load + @param gptype The type of program to create @param syntaxCode The name of the syntax to be used for this program e.g. arbvp1, vs_1_1 - */ - virtual GpuProgramPtr load(const String& name, const String& groupName, - const String& filename, GpuProgramType gptype, + */ + virtual GpuProgramPtr load(const String& name, const String& groupName, + const String& filename, GpuProgramType gptype, const String& syntaxCode); - /** Loads a GPU program from a string of assembly code. - @remarks - The assembly code must be compatible with this manager - call the - getSupportedSyntax method for details of the supported syntaxes - @param name The identifying name to give this program, which can be used to - retrieve this program later with getByName. - @param groupName The name of the resource group - @param code A string of assembly code which will form the program to run - @param gptype The type of program to create. + /** Loads a GPU program from a string of assembly code. + @remarks + The assembly code must be compatible with this manager - call the + getSupportedSyntax method for details of the supported syntaxes + @param name The identifying name to give this program, which can be used to + retrieve this program later with getByName. + @param groupName The name of the resource group + @param code A string of assembly code which will form the program to run + @param gptype The type of program to create. @param syntaxCode The name of the syntax to be used for this program e.g. arbvp1, vs_1_1 - */ - virtual GpuProgramPtr loadFromString(const String& name, const String& groupName, - const String& code, GpuProgramType gptype, + */ + virtual GpuProgramPtr loadFromString(const String& name, const String& groupName, + const String& code, GpuProgramType gptype, const String& syntaxCode); - /** Returns the syntaxes that this manager supports. */ - virtual const SyntaxCodes& getSupportedSyntax(void) const; - + /** Returns the syntaxes that this manager supports. */ + virtual const SyntaxCodes& getSupportedSyntax(void) const; + /** Returns whether a given syntax code (e.g. "ps_1_3", "fp20", "arbvp1") is supported. */ virtual bool isSyntaxSupported(const String& syntaxCode) const; - - /** Creates a new GpuProgramParameters instance which can be used to bind + + /** Creates a new GpuProgramParameters instance which can be used to bind parameters to your programs. @remarks Program parameters can be shared between multiple programs if you wish. @@ -124,36 +124,36 @@ namespace Ogre { @remarks Use this method in preference to the 'load' methods if you wish to define a GpuProgram, but not load it yet; useful for saving memory. - @par - This method creates a new program of the type specified as the second parameter. - As with all types of ResourceManager, this class will search for the file in - all resource locations it has been configured to look in. - @param name The name of the program - @param groupName The name of the resource group - @param filename The file to load + @par + This method creates a new program of the type specified as the second parameter. + As with all types of ResourceManager, this class will search for the file in + all resource locations it has been configured to look in. + @param name The name of the program + @param groupName The name of the resource group + @param filename The file to load @param syntaxCode The name of the syntax to be used for this program e.g. arbvp1, vs_1_1 - @param gptype The type of program to create - */ - virtual GpuProgramPtr createProgram(const String& name, - const String& groupName, const String& filename, - GpuProgramType gptype, const String& syntaxCode); + @param gptype The type of program to create + */ + virtual GpuProgramPtr createProgram(const String& name, + const String& groupName, const String& filename, + GpuProgramType gptype, const String& syntaxCode); - /** Create a GPU program from a string of assembly code. + /** Create a GPU program from a string of assembly code. @remarks Use this method in preference to the 'load' methods if you wish to define a GpuProgram, but not load it yet; useful for saving memory. - @par - The assembly code must be compatible with this manager - call the - getSupportedSyntax method for details of the supported syntaxes - @param name The identifying name to give this program, which can be used to - retrieve this program later with getByName. - @param groupName The name of the resource group - @param code A string of assembly code which will form the program to run - @param gptype The type of program to create. + @par + The assembly code must be compatible with this manager - call the + getSupportedSyntax method for details of the supported syntaxes + @param name The identifying name to give this program, which can be used to + retrieve this program later with getByName. + @param groupName The name of the resource group + @param code A string of assembly code which will form the program to run + @param gptype The type of program to create. @param syntaxCode The name of the syntax to be used for this program e.g. arbvp1, vs_1_1 - */ - virtual GpuProgramPtr createProgramFromString(const String& name, - const String& groupName, const String& code, + */ + virtual GpuProgramPtr createProgramFromString(const String& name, + const String& groupName, const String& code, GpuProgramType gptype, const String& syntaxCode); /** General create method, using specific create parameters @@ -171,67 +171,67 @@ namespace Ogre { ResourcePtr getResourceByName(const String& name, bool preferHighLevelPrograms = true); - /** Create a new set of shared parameters, which can be used across many - GpuProgramParameters objects of different structures. - @param name The name to give the shared parameters so you can refer to them - later. - */ - virtual GpuSharedParametersPtr createSharedParameters(const String& name); + /** Create a new set of shared parameters, which can be used across many + GpuProgramParameters objects of different structures. + @param name The name to give the shared parameters so you can refer to them + later. + */ + virtual GpuSharedParametersPtr createSharedParameters(const String& name); - /** Retrieve a set of shared parameters, which can be used across many - GpuProgramParameters objects of different structures. - */ - virtual GpuSharedParametersPtr getSharedParameters(const String& name) const; + /** Retrieve a set of shared parameters, which can be used across many + GpuProgramParameters objects of different structures. + */ + virtual GpuSharedParametersPtr getSharedParameters(const String& name) const; - /** Get (const) access to the available shared parameter sets. - */ - virtual const SharedParametersMap& getAvailableSharedParameters() const; + /** Get (const) access to the available shared parameter sets. + */ + virtual const SharedParametersMap& getAvailableSharedParameters() const; /** Get if the microcode of a shader should be saved to a cache */ - bool getSaveMicrocodesToCache(); + bool getSaveMicrocodesToCache(); /** Set if the microcode of a shader should be saved to a cache */ - void setSaveMicrocodesToCache( const bool val ); + void setSaveMicrocodesToCache( const bool val ); - /** Returns true if the microcodecache changed during the run. - */ - bool isCacheDirty(void) const; + /** Returns true if the microcodecache changed during the run. + */ + bool isCacheDirty(void) const; - bool canGetCompiledShaderBuffer(); + bool canGetCompiledShaderBuffer(); /** Check if a microcode is available for a program in the microcode cache. @param name The name of the program. */ - virtual bool isMicrocodeAvailableInCache( const String & name ) const; + virtual bool isMicrocodeAvailableInCache( const String & name ) const; /** Returns a microcode for a program from the microcode cache. @param name The name of the program. */ - virtual const Microcode & getMicrocodeFromCache( const String & name ) const; + virtual const Microcode & getMicrocodeFromCache( const String & name ) const; /** Creates a microcode to be later added to the cache. - @param size The size of the microcode in bytes + @param size The size of the microcode in bytes */ - virtual Microcode createMicrocode( const uint32 size ) const; + virtual Microcode createMicrocode( const uint32 size ) const; /** Adds a microcode for a program to the microcode cache. @param name The name of the program. */ - virtual void addMicrocodeToCache( const String & name, const Microcode & microcode ); + virtual void addMicrocodeToCache( const String & name, const Microcode & microcode ); - /** Removes a microcode for a program from the microcode cache. + /** Removes a microcode for a program from the microcode cache. @param name The name of the program. */ - virtual void removeMicrocodeFromCache( const String & name ); + virtual void removeMicrocodeFromCache( const String & name ); /** Saves the microcode cache to disk. @param stream The destination stream */ - virtual void saveMicrocodeCache( DataStreamPtr stream ) const; + virtual void saveMicrocodeCache( DataStreamPtr stream ) const; /** Loads the microcode cache from disk. @param stream The source stream */ - virtual void loadMicrocodeCache( DataStreamPtr stream ); - + virtual void loadMicrocodeCache( DataStreamPtr stream ); + /** Override standard Singleton retrieval. @@ -269,10 +269,10 @@ namespace Ogre { - }; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreGpuProgramParams.h b/OgreMain/include/OgreGpuProgramParams.h index c246ed58ddc..056f5e48505 100644 --- a/OgreMain/include/OgreGpuProgramParams.h +++ b/OgreMain/include/OgreGpuProgramParams.h @@ -112,11 +112,11 @@ namespace Ogre { GCT_BOOL2 = 45, GCT_BOOL3 = 46, GCT_BOOL4 = 47, - GCT_SAMPLER_WRAPPER1D = 48, - GCT_SAMPLER_WRAPPER2D = 49, - GCT_SAMPLER_WRAPPER3D = 50, - GCT_SAMPLER_WRAPPERCUBE = 51, - GCT_SAMPLER_STATE = 52, //only for hlsl 4.0 + GCT_SAMPLER_WRAPPER1D = 48, + GCT_SAMPLER_WRAPPER2D = 49, + GCT_SAMPLER_WRAPPER3D = 50, + GCT_SAMPLER_WRAPPERCUBE = 51, + GCT_SAMPLER_STATE = 52, //only for hlsl 4.0 GCT_UNKNOWN = 99 }; @@ -1349,7 +1349,7 @@ namespace Ogre { */ ACT_LOD_CAMERA_POSITION_OBJECT_SPACE, /** Binds custom per-light constants to the shaders. */ - ACT_LIGHT_CUSTOM, + ACT_LIGHT_CUSTOM, ACT_UNKNOWN = 999 }; diff --git a/OgreMain/include/OgreGpuProgramUsage.h b/OgreMain/include/OgreGpuProgramUsage.h index c7985ddbfd7..42cef7b616f 100644 --- a/OgreMain/include/OgreGpuProgramUsage.h +++ b/OgreMain/include/OgreGpuProgramUsage.h @@ -34,15 +34,15 @@ THE SOFTWARE. namespace Ogre { - class Pass; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Materials - * @{ - */ - /** This class makes the usage of a vertex and fragment programs (low-level or high-level), + class Pass; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Materials + * @{ + */ + /** This class makes the usage of a vertex and fragment programs (low-level or high-level), with a given set of parameters, explicit. @remarks Using a vertex or fragment program can get fairly complex; besides the fairly rudimentary @@ -70,21 +70,21 @@ namespace Ogre Just incase it wasn't clear from the above, this class provides linkage to both GpuProgram and HighLevelGpuProgram, despite its name. */ - class _OgreExport GpuProgramUsage : public Resource::Listener, public PassAlloc + class _OgreExport GpuProgramUsage : public Resource::Listener, public PassAlloc { protected: GpuProgramType mType; - Pass* mParent; + Pass* mParent; /// The program link GpuProgramPtr mProgram; /// Program parameters GpuProgramParametersSharedPtr mParameters; - - /// Whether to recreate parameters next load - bool mRecreateParams; + + /// Whether to recreate parameters next load + bool mRecreateParams; - void recreateParameters(); + void recreateParameters(); public: /** Default constructor. @@ -92,15 +92,15 @@ namespace Ogre */ GpuProgramUsage(GpuProgramType gptype, Pass* parent); - /** Copy constructor */ - GpuProgramUsage(const GpuProgramUsage& rhs, Pass* newparent); + /** Copy constructor */ + GpuProgramUsage(const GpuProgramUsage& rhs, Pass* newparent); - ~GpuProgramUsage(); + ~GpuProgramUsage(); /** Gets the type of program we're trying to link to. */ GpuProgramType getType(void) const { return mType; } - /** Sets the name of the program to use. + /** Sets the name of the program to use. @param name The name of the program to use @param resetParams If true, this will create a fresh set of parameters from the @@ -110,17 +110,17 @@ namespace Ogre case of named parameters refers to the indexes underlying them, not just the names. */ - void setProgramName(const String& name, bool resetParams = true); - /** Sets the program to use. + void setProgramName(const String& name, bool resetParams = true); + /** Sets the program to use. @remarks Note that this will create a fresh set of parameters from the new program being linked, so if you had previously set parameters you will have to set them again. */ void setProgram(GpuProgramPtr& prog); - /** Gets the program being used. */ + /** Gets the program being used. */ const GpuProgramPtr& getProgram() const { return mProgram; } - /** Gets the program being used. */ + /** Gets the program being used. */ const String& getProgramName(void) const { return mProgram->getName(); } /** Sets the program parameters that should be used; because parameters can be @@ -140,13 +140,13 @@ namespace Ogre size_t calculateSize(void) const; - // Resource Listener - void unloadingComplete(Resource* prog); - void loadingComplete(Resource* prog); + // Resource Listener + void unloadingComplete(Resource* prog); + void loadingComplete(Resource* prog); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreHardwareBuffer.h b/OgreMain/include/OgreHardwareBuffer.h index 7041bf0d7f0..431ec27b4de 100644 --- a/OgreMain/include/OgreHardwareBuffer.h +++ b/OgreMain/include/OgreHardwareBuffer.h @@ -34,67 +34,67 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Abstract class defining common features of hardware buffers. + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Abstract class defining common features of hardware buffers. @remarks - A 'hardware buffer' is any area of memory held outside of core system ram, - and in our case refers mostly to video ram, although in theory this class - could be used with other memory areas such as sound card memory, custom - coprocessor memory etc. + A 'hardware buffer' is any area of memory held outside of core system ram, + and in our case refers mostly to video ram, although in theory this class + could be used with other memory areas such as sound card memory, custom + coprocessor memory etc. + @par + This reflects the fact that memory held outside of main system RAM must + be interacted with in a more formal fashion in order to promote + cooperative and optimal usage of the buffers between the various + processing units which manipulate them. @par - This reflects the fact that memory held outside of main system RAM must - be interacted with in a more formal fashion in order to promote - cooperative and optimal usage of the buffers between the various - processing units which manipulate them. + This abstract class defines the core interface which is common to all + buffers, whether it be vertex buffers, index buffers, texture memory + or framebuffer memory etc. @par - This abstract class defines the core interface which is common to all - buffers, whether it be vertex buffers, index buffers, texture memory - or framebuffer memory etc. - @par - Buffers have the ability to be 'shadowed' in system memory, this is because - the kinds of access allowed on hardware buffers is not always as flexible as - that allowed for areas of system memory - for example it is often either - impossible, or extremely undesirable from a performance standpoint to read from - a hardware buffer; when writing to hardware buffers, you should also write every - byte and do it sequentially. In situations where this is too restrictive, - it is possible to create a hardware, write-only buffer (the most efficient kind) - and to back it with a system memory 'shadow' copy which can be read and updated arbitrarily. - Ogre handles synchronising this buffer with the real hardware buffer (which should still be - created with the HBU_DYNAMIC flag if you intend to update it very frequently). Whilst this - approach does have its own costs, such as increased memory overhead, these costs can - often be outweighed by the performance benefits of using a more hardware efficient buffer. - You should look for the 'useShadowBuffer' parameter on the creation methods used to create - the buffer of the type you require (see HardwareBufferManager) to enable this feature. + Buffers have the ability to be 'shadowed' in system memory, this is because + the kinds of access allowed on hardware buffers is not always as flexible as + that allowed for areas of system memory - for example it is often either + impossible, or extremely undesirable from a performance standpoint to read from + a hardware buffer; when writing to hardware buffers, you should also write every + byte and do it sequentially. In situations where this is too restrictive, + it is possible to create a hardware, write-only buffer (the most efficient kind) + and to back it with a system memory 'shadow' copy which can be read and updated arbitrarily. + Ogre handles synchronising this buffer with the real hardware buffer (which should still be + created with the HBU_DYNAMIC flag if you intend to update it very frequently). Whilst this + approach does have its own costs, such as increased memory overhead, these costs can + often be outweighed by the performance benefits of using a more hardware efficient buffer. + You should look for the 'useShadowBuffer' parameter on the creation methods used to create + the buffer of the type you require (see HardwareBufferManager) to enable this feature. */ - class _OgreExport HardwareBuffer : public BufferAlloc + class _OgreExport HardwareBuffer : public BufferAlloc { - public: - /// Enums describing buffer usage; not mutually exclusive - enum Usage - { + public: + /// Enums describing buffer usage; not mutually exclusive + enum Usage + { /** Static buffer which the application rarely modifies once created. Modifying the contents of this buffer will involve a performance hit. */ HBU_STATIC = 1, - /** Indicates the application would like to modify this buffer with the CPU - fairly often. - Buffers created with this flag will typically end up in AGP memory rather - than video memory. - */ - HBU_DYNAMIC = 2, - /** Indicates the application will never read the contents of the buffer back, - it will only ever write data. Locking a buffer with this flag will ALWAYS - return a pointer to new, blank memory rather than the memory associated - with the contents of the buffer; this avoids DMA stalls because you can - write to a new memory area while the previous one is being used. - */ - HBU_WRITE_ONLY = 4, + /** Indicates the application would like to modify this buffer with the CPU + fairly often. + Buffers created with this flag will typically end up in AGP memory rather + than video memory. + */ + HBU_DYNAMIC = 2, + /** Indicates the application will never read the contents of the buffer back, + it will only ever write data. Locking a buffer with this flag will ALWAYS + return a pointer to new, blank memory rather than the memory associated + with the contents of the buffer; this avoids DMA stalls because you can + write to a new memory area while the previous one is being used. + */ + HBU_WRITE_ONLY = 4, /** Indicates that the application will be refilling the contents of the buffer regularly (not just updating, but generating the contents from scratch), and therefore does not mind if the contents @@ -104,41 +104,41 @@ namespace Ogre { HBU_DYNAMIC_WRITE_ONLY. */ HBU_DISCARDABLE = 8, - /// Combination of HBU_STATIC and HBU_WRITE_ONLY - HBU_STATIC_WRITE_ONLY = 5, - /** Combination of HBU_DYNAMIC and HBU_WRITE_ONLY. If you use + /// Combination of HBU_STATIC and HBU_WRITE_ONLY + HBU_STATIC_WRITE_ONLY = 5, + /** Combination of HBU_DYNAMIC and HBU_WRITE_ONLY. If you use this, strongly consider using HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE instead if you update the entire contents of the buffer very regularly. */ - HBU_DYNAMIC_WRITE_ONLY = 6, + HBU_DYNAMIC_WRITE_ONLY = 6, /// Combination of HBU_DYNAMIC, HBU_WRITE_ONLY and HBU_DISCARDABLE HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE = 14 - }; - /// Locking options - enum LockOptions - { + }; + /// Locking options + enum LockOptions + { /** Normal mode, ie allows read/write and contents are preserved. */ HBL_NORMAL, - /** Discards the entire buffer while locking; this allows optimisation to be - performed because synchronisation issues are relaxed. Only allowed on buffers - created with the HBU_DYNAMIC flag. - */ - HBL_DISCARD, - /** Lock the buffer for reading only. Not allowed in buffers which are created with HBU_WRITE_ONLY. - Mandatory on static buffers, i.e. those created without the HBU_DYNAMIC flag. - */ - HBL_READ_ONLY, + /** Discards the entire buffer while locking; this allows optimisation to be + performed because synchronisation issues are relaxed. Only allowed on buffers + created with the HBU_DYNAMIC flag. + */ + HBL_DISCARD, + /** Lock the buffer for reading only. Not allowed in buffers which are created with HBU_WRITE_ONLY. + Mandatory on static buffers, i.e. those created without the HBU_DYNAMIC flag. + */ + HBL_READ_ONLY, /** As HBL_DISCARD, except the application guarantees not to overwrite any region of the buffer which has already been used in this frame, can allow some optimisation on some APIs. */ HBL_NO_OVERWRITE, - /** Lock the buffer for writing only.*/ - HBL_WRITE_ONLY - - }; + /** Lock the buffer for writing only.*/ + HBL_WRITE_ONLY + + }; /// Device load options /// The following enum is used to controls how data is loaded to devices in a multi device environment @@ -156,28 +156,28 @@ namespace Ogre { HBU_ON_DEMAND = 0x0001 }; - protected: - size_t mSizeInBytes; - Usage mUsage; - bool mIsLocked; - size_t mLockStart; - size_t mLockSize; + protected: + size_t mSizeInBytes; + Usage mUsage; + bool mIsLocked; + size_t mLockStart; + size_t mLockSize; UploadOptions mLockUploadOption; - bool mSystemMemory; + bool mSystemMemory; bool mUseShadowBuffer; HardwareBuffer* mShadowBuffer; bool mShadowUpdated; bool mSuppressHardwareUpdate; - + /// Internal implementation of lock() - virtual void* lockImpl(size_t offset, size_t length, LockOptions options) = 0; + virtual void* lockImpl(size_t offset, size_t length, LockOptions options) = 0; /// Internal implementation of unlock() - virtual void unlockImpl(void) = 0; + virtual void unlockImpl(void) = 0; public: - /// Constructor, to be called by HardwareBufferManager only + /// Constructor, to be called by HardwareBufferManager only HardwareBuffer(Usage usage, bool systemMemory, bool useShadowBuffer) - : mSizeInBytes(0), mUsage(usage), mIsLocked(false), mLockStart(0), mLockSize(0), mSystemMemory(systemMemory), + : mSizeInBytes(0), mUsage(usage), mIsLocked(false), mLockStart(0), mLockSize(0), mSystemMemory(systemMemory), mUseShadowBuffer(useShadowBuffer), mShadowBuffer(NULL), mShadowUpdated(false), mSuppressHardwareUpdate(false) { @@ -192,29 +192,29 @@ namespace Ogre { } } virtual ~HardwareBuffer() {} - /** Lock the buffer for (potentially) reading / writing. - @param offset The byte offset from the start of the buffer to lock - @param length The size of the area to lock, in bytes - @param options Locking options - @return Pointer to the locked memory - */ - virtual void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT) + /** Lock the buffer for (potentially) reading / writing. + @param offset The byte offset from the start of the buffer to lock + @param length The size of the area to lock, in bytes + @param options Locking options + @return Pointer to the locked memory + */ + virtual void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT) { assert(!isLocked() && "Cannot lock this buffer, it is already locked!"); - void* ret = NULL; - if ((length + offset) > mSizeInBytes) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Lock request out of bounds.", - "HardwareBuffer::lock"); - } - else if (mUseShadowBuffer) + void* ret = NULL; + if ((length + offset) > mSizeInBytes) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Lock request out of bounds.", + "HardwareBuffer::lock"); + } + else if (mUseShadowBuffer) { - if (options != HBL_READ_ONLY) - { - // we have to assume a read / write lock so we use the shadow buffer - // and tag for sync on unlock() + if (options != HBL_READ_ONLY) + { + // we have to assume a read / write lock so we use the shadow buffer + // and tag for sync on unlock() mShadowUpdated = true; } @@ -222,25 +222,25 @@ namespace Ogre { } else { - // Lock the real buffer if there is no shadow buffer + // Lock the real buffer if there is no shadow buffer ret = lockImpl(offset, length, options); mIsLocked = true; } - mLockStart = offset; - mLockSize = length; - mLockUploadOption = uploadOpt; + mLockStart = offset; + mLockSize = length; + mLockUploadOption = uploadOpt; return ret; } /** Lock the entire buffer for (potentially) reading / writing. - @param options Locking options - @return Pointer to the locked memory + @param options Locking options + @return Pointer to the locked memory */ - void* lock(LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT) + void* lock(LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT) { return this->lock(0, mSizeInBytes, options, uploadOpt); } - /** Releases the lock on this buffer. + /** Releases the lock on this buffer. @remarks Locking and unlocking a buffer can, in some rare circumstances such as switching video modes whilst the buffer is locked, corrupt the @@ -252,11 +252,11 @@ namespace Ogre { suffer from this problem, so if you want to be 100% sure your data will not be lost, use the 'read' and 'write' forms instead. */ - virtual void unlock(void) + virtual void unlock(void) { assert(isLocked() && "Cannot unlock this buffer, it is not locked!"); - // If we used the shadow buffer this time... + // If we used the shadow buffer this time... if (mUseShadowBuffer && mShadowBuffer->isLocked()) { mShadowBuffer->unlock(); @@ -265,7 +265,7 @@ namespace Ogre { } else { - // Otherwise, unlock the real one + // Otherwise, unlock the real one unlockImpl(); mIsLocked = false; } @@ -273,71 +273,71 @@ namespace Ogre { } /** Reads data from the buffer and places it in the memory pointed to by pDest. - @param offset The byte offset from the start of the buffer to read - @param length The size of the area to read, in bytes + @param offset The byte offset from the start of the buffer to read + @param length The size of the area to read, in bytes @param pDest The area of memory in which to place the data, must be large enough to accommodate the data! */ virtual void readData(size_t offset, size_t length, void* pDest) = 0; /** Writes data to the buffer from an area of system memory; note that you must ensure that your buffer is big enough. - @param offset The byte offset from the start of the buffer to start writing - @param length The size of the data to write to, in bytes + @param offset The byte offset from the start of the buffer to start writing + @param length The size of the data to write to, in bytes @param pSource The source of the data to be written - @param discardWholeBuffer If true, this allows the driver to discard the entire buffer when writing, - such that DMA stalls can be avoided; use if you can. + @param discardWholeBuffer If true, this allows the driver to discard the entire buffer when writing, + such that DMA stalls can be avoided; use if you can. */ virtual void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false) = 0; + bool discardWholeBuffer = false) = 0; - /** Copy data from another buffer into this one. - @remarks - Note that the source buffer must not be created with the + /** Copy data from another buffer into this one. + @remarks + Note that the source buffer must not be created with the usage HBU_WRITE_ONLY otherwise this will fail. - @param srcBuffer The buffer from which to read the copied data - @param srcOffset Offset in the source buffer at which to start reading - @param dstOffset Offset in the destination buffer to start writing - @param length Length of the data to copy, in bytes. - @param discardWholeBuffer If true, will discard the entire contents of this buffer before copying - */ - virtual void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, - size_t dstOffset, size_t length, bool discardWholeBuffer = false) - { - const void *srcData = srcBuffer.lock( - srcOffset, length, HBL_READ_ONLY); - this->writeData(dstOffset, length, srcData, discardWholeBuffer); - srcBuffer.unlock(); - } + @param srcBuffer The buffer from which to read the copied data + @param srcOffset Offset in the source buffer at which to start reading + @param dstOffset Offset in the destination buffer to start writing + @param length Length of the data to copy, in bytes. + @param discardWholeBuffer If true, will discard the entire contents of this buffer before copying + */ + virtual void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, + size_t dstOffset, size_t length, bool discardWholeBuffer = false) + { + const void *srcData = srcBuffer.lock( + srcOffset, length, HBL_READ_ONLY); + this->writeData(dstOffset, length, srcData, discardWholeBuffer); + srcBuffer.unlock(); + } - /** Copy all data from another buffer into this one. - @remarks - Normally these buffers should be of identical size, but if they're - not, the routine will use the smallest of the two sizes. - */ - virtual void copyData(HardwareBuffer& srcBuffer) - { - size_t sz = std::min(getSizeInBytes(), srcBuffer.getSizeInBytes()); - copyData(srcBuffer, 0, 0, sz, true); - } - - /// Updates the real buffer from the shadow buffer, if required + /** Copy all data from another buffer into this one. + @remarks + Normally these buffers should be of identical size, but if they're + not, the routine will use the smallest of the two sizes. + */ + virtual void copyData(HardwareBuffer& srcBuffer) + { + size_t sz = std::min(getSizeInBytes(), srcBuffer.getSizeInBytes()); + copyData(srcBuffer, 0, 0, sz, true); + } + + /// Updates the real buffer from the shadow buffer, if required virtual void _updateFromShadow(void) { if (mUseShadowBuffer && mShadowUpdated && !mSuppressHardwareUpdate) { // Do this manually to avoid locking problems const void *srcData = mShadowBuffer->lockImpl( - mLockStart, mLockSize, HBL_READ_ONLY); - // Lock with discard if the whole buffer was locked, otherwise normal - LockOptions lockOpt; - if (mLockStart == 0 && mLockSize == mSizeInBytes) - lockOpt = HBL_DISCARD; - else - lockOpt = HBL_NORMAL; - + mLockStart, mLockSize, HBL_READ_ONLY); + // Lock with discard if the whole buffer was locked, otherwise normal + LockOptions lockOpt; + if (mLockStart == 0 && mLockSize == mSizeInBytes) + lockOpt = HBL_DISCARD; + else + lockOpt = HBL_NORMAL; + void *destData = this->lockImpl( - mLockStart, mLockSize, lockOpt); - // Copy shadow to real + mLockStart, mLockSize, lockOpt); + // Copy shadow to real memcpy(destData, srcData, mLockSize); this->unlockImpl(); mShadowBuffer->unlockImpl(); @@ -349,10 +349,10 @@ namespace Ogre { size_t getSizeInBytes(void) const { return mSizeInBytes; } /// Returns the Usage flags with which this buffer was created Usage getUsage(void) const { return mUsage; } - /// Returns whether this buffer is held in system memory - bool isSystemMemory(void) const { return mSystemMemory; } - /// Returns whether this buffer has a system memory shadow for quicker reading - bool hasShadowBuffer(void) const { return mUseShadowBuffer; } + /// Returns whether this buffer is held in system memory + bool isSystemMemory(void) const { return mSystemMemory; } + /// Returns whether this buffer has a system memory shadow for quicker reading + bool hasShadowBuffer(void) const { return mUseShadowBuffer; } /// Returns whether or not this buffer is currently locked. bool isLocked(void) const { return mIsLocked || (mUseShadowBuffer && mShadowBuffer->isLocked()); @@ -367,12 +367,12 @@ namespace Ogre { - + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ - /** Locking helper. Guaranteed unlocking even in case of exception. */ + /** Locking helper. Guaranteed unlocking even in case of exception. */ template struct HardwareBufferLockGuard { HardwareBufferLockGuard(const T& p, HardwareBuffer::LockOptions options) @@ -384,7 +384,7 @@ namespace Ogre { : pBuf(p) { pData = pBuf->lock(offset, length, options); - } + } ~HardwareBufferLockGuard() { pBuf->unlock(); diff --git a/OgreMain/include/OgreHardwareBufferManager.h b/OgreMain/include/OgreHardwareBufferManager.h index 25609b2e25a..7c2904830d7 100644 --- a/OgreMain/include/OgreHardwareBufferManager.h +++ b/OgreMain/include/OgreHardwareBufferManager.h @@ -122,12 +122,12 @@ namespace Ogre { */ typedef set::type VertexBufferList; typedef set::type IndexBufferList; - typedef set::type UniformBufferList; - typedef set::type CounterBufferList; + typedef set::type UniformBufferList; + typedef set::type CounterBufferList; VertexBufferList mVertexBuffers; IndexBufferList mIndexBuffers; - UniformBufferList mUniformBuffers; - CounterBufferList mCounterBuffers; + UniformBufferList mUniformBuffers; + CounterBufferList mCounterBuffers; typedef set::type VertexDeclarationList; @@ -284,20 +284,20 @@ namespace Ogre { */ virtual RenderToVertexBufferSharedPtr createRenderToVertexBuffer() = 0; - /** - * Create uniform buffer. This type of buffer allows the upload of shader constants once, - * and sharing between shader stages or even shaders from another materials. - * The update shall be triggered by GpuProgramParameters, if is dirty - */ - virtual HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, - HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, - bool useShadowBuffer = false, const String& name = "") = 0; + /** + * Create uniform buffer. This type of buffer allows the upload of shader constants once, + * and sharing between shader stages or even shaders from another materials. + * The update shall be triggered by GpuProgramParameters, if is dirty + */ + virtual HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, + HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, + bool useShadowBuffer = false, const String& name = "") = 0; /** - * Create counter buffer. - * The update shall be triggered by GpuProgramParameters, if is dirty - */ - virtual HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, + * Create counter buffer. + * The update shall be triggered by GpuProgramParameters, if is dirty + */ + virtual HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, bool useShadowBuffer = false, const String& name = "") = 0; @@ -419,10 +419,10 @@ namespace Ogre { void _notifyVertexBufferDestroyed(HardwareVertexBuffer* buf); /// Notification that a hardware index buffer has been destroyed. void _notifyIndexBufferDestroyed(HardwareIndexBuffer* buf); - /// Notification that at hardware uniform buffer has been destroyed - void _notifyUniformBufferDestroyed(HardwareUniformBuffer* buf); - /// Notification that at hardware counter buffer has been destroyed - void _notifyCounterBufferDestroyed(HardwareCounterBuffer* buf); + /// Notification that at hardware uniform buffer has been destroyed + void _notifyUniformBufferDestroyed(HardwareUniformBuffer* buf); + /// Notification that at hardware counter buffer has been destroyed + void _notifyCounterBufferDestroyed(HardwareCounterBuffer* buf); }; /** Singleton wrapper for hardware buffer manager. */ @@ -458,20 +458,20 @@ namespace Ogre { } /** @copydoc HardwareBufferManagerBase::createUniformBuffer */ - HardwareUniformBufferSharedPtr - createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name = "") - { - return mImpl->createUniformBuffer(sizeBytes, usage, useShadowBuffer, name); - } + HardwareUniformBufferSharedPtr + createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name = "") + { + return mImpl->createUniformBuffer(sizeBytes, usage, useShadowBuffer, name); + } /** @copydoc HardwareBufferManagerBase::createCounterBuffer */ - HardwareCounterBufferSharedPtr + HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name = "") - { - return mImpl->createCounterBuffer(sizeBytes, usage, useShadowBuffer, name); - } + { + return mImpl->createCounterBuffer(sizeBytes, usage, useShadowBuffer, name); + } - /** @copydoc HardwareBufferManagerInterface::createVertexDeclaration */ + /** @copydoc HardwareBufferManagerInterface::createVertexDeclaration */ virtual VertexDeclaration* createVertexDeclaration(void) { return mImpl->createVertexDeclaration(); @@ -553,16 +553,16 @@ namespace Ogre { { mImpl->_notifyIndexBufferDestroyed(buf); } - /** @copydoc HardwareBufferManagerInterface::_notifyUniformBufferDestroyed */ - void _notifyUniformBufferDestroyed(HardwareUniformBuffer* buf) - { - mImpl->_notifyUniformBufferDestroyed(buf); - } - /** @copydoc HardwareBufferManagerInterface::_notifyCounterBufferDestroyed */ - void _notifyConterBufferDestroyed(HardwareCounterBuffer* buf) - { - mImpl->_notifyCounterBufferDestroyed(buf); - } + /** @copydoc HardwareBufferManagerInterface::_notifyUniformBufferDestroyed */ + void _notifyUniformBufferDestroyed(HardwareUniformBuffer* buf) + { + mImpl->_notifyUniformBufferDestroyed(buf); + } + /** @copydoc HardwareBufferManagerInterface::_notifyCounterBufferDestroyed */ + void _notifyConterBufferDestroyed(HardwareCounterBuffer* buf) + { + mImpl->_notifyCounterBufferDestroyed(buf); + } /** Override standard Singleton retrieval. @remarks diff --git a/OgreMain/include/OgreHardwareCounterBuffer.h b/OgreMain/include/OgreHardwareCounterBuffer.h index 0bc27da61fa..13f2d6f48fe 100644 --- a/OgreMain/include/OgreHardwareCounterBuffer.h +++ b/OgreMain/include/OgreHardwareCounterBuffer.h @@ -35,30 +35,30 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - class HardwareBufferManagerBase; + class HardwareBufferManagerBase; - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Specialisation of HardwareBuffer for a counter buffer. */ - class _OgreExport HardwareCounterBuffer : public HardwareBuffer + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Specialisation of HardwareBuffer for a counter buffer. */ + class _OgreExport HardwareCounterBuffer : public HardwareBuffer { - protected: - HardwareBufferManagerBase* mMgr; - String mName; + protected: + HardwareBufferManagerBase* mMgr; + String mName; - public: - /// Should be called by HardwareBufferManager - HardwareCounterBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, - HardwareBuffer::Usage usage, bool useShadowBuffer = false, const String& name = ""); - ~HardwareCounterBuffer(); - /// Return the manager of this buffer, if any - HardwareBufferManagerBase* getManager() const { return mMgr; } + public: + /// Should be called by HardwareBufferManager + HardwareCounterBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, + HardwareBuffer::Usage usage, bool useShadowBuffer = false, const String& name = ""); + ~HardwareCounterBuffer(); + /// Return the manager of this buffer, if any + HardwareBufferManagerBase* getManager() const { return mMgr; } - const String& getName() const { return mName; } + const String& getName() const { return mName; } }; diff --git a/OgreMain/include/OgreHardwareIndexBuffer.h b/OgreMain/include/OgreHardwareIndexBuffer.h index d6ebff4a95b..61c221d4fe1 100644 --- a/OgreMain/include/OgreHardwareIndexBuffer.h +++ b/OgreMain/include/OgreHardwareIndexBuffer.h @@ -34,44 +34,44 @@ THE SOFTWARE. #include "OgreSharedPtr.h" namespace Ogre { - class HardwareBufferManagerBase; + class HardwareBufferManagerBase; - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Specialisation of HardwareBuffer for vertex index buffers, still abstract. */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Specialisation of HardwareBuffer for vertex index buffers, still abstract. */ class _OgreExport HardwareIndexBuffer : public HardwareBuffer { - public: - enum IndexType { - IT_16BIT, - IT_32BIT - }; + public: + enum IndexType { + IT_16BIT, + IT_32BIT + }; - protected: - HardwareBufferManagerBase* mMgr; - IndexType mIndexType; - size_t mNumIndexes; + protected: + HardwareBufferManagerBase* mMgr; + IndexType mIndexType; + size_t mNumIndexes; size_t mIndexSize; - public: - /// Should be called by HardwareBufferManager - HardwareIndexBuffer(HardwareBufferManagerBase* mgr, IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage, + public: + /// Should be called by HardwareBufferManager + HardwareIndexBuffer(HardwareBufferManagerBase* mgr, IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage, bool useSystemMemory, bool useShadowBuffer); ~HardwareIndexBuffer(); - /// Return the manager of this buffer, if any - HardwareBufferManagerBase* getManager() const { return mMgr; } - /// Get the type of indexes used in this buffer + /// Return the manager of this buffer, if any + HardwareBufferManagerBase* getManager() const { return mMgr; } + /// Get the type of indexes used in this buffer IndexType getType(void) const { return mIndexType; } /// Get the number of indexes in this buffer size_t getNumIndexes(void) const { return mNumIndexes; } /// Get the size in bytes of each index size_t getIndexSize(void) const { return mIndexSize; } - // NB subclasses should override lock, unlock, readData, writeData + // NB subclasses should override lock, unlock, readData, writeData }; @@ -86,8 +86,8 @@ namespace Ogre { /** Locking helper. */ typedef HardwareBufferLockGuard HardwareIndexBufferLockGuard; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreHardwareOcclusionQuery.h b/OgreMain/include/OgreHardwareOcclusionQuery.h index 2cd445f1e03..927883d1069 100644 --- a/OgreMain/include/OgreHardwareOcclusionQuery.h +++ b/OgreMain/include/OgreHardwareOcclusionQuery.h @@ -35,12 +35,12 @@ namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ /** * This is a abstract class that that provides the interface for the query class for * hardware occlusion. @@ -48,71 +48,71 @@ namespace Ogre { * @author Lee Sandberg * Updated on 13/8/2005 by Tuan Kuranes email: tuan.kuranes@free.fr */ - class _OgreExport HardwareOcclusionQuery : public RenderSysAlloc + class _OgreExport HardwareOcclusionQuery : public RenderSysAlloc { //---------------------------------------------------------------------- // Public methods //-- public: - /** - * Object public member functions - */ - - /** - * Default object constructor - * - */ - HardwareOcclusionQuery(); - - /** - * Object destructor - */ - virtual ~HardwareOcclusionQuery(); - - /** - * Starts the hardware occlusion query - * @remarks Simple usage: Create one or more OcclusionQuery object one per outstanding query or one per tested object - * OcclusionQuery* mOcclusionQuery; - * createOcclusionQuery( &mOcclusionQuery ); - * In the rendering loop: - * Draw all occluders - * mOcclusionQuery->startOcclusionQuery(); - * Draw the polygons to be tested - * mOcclusionQuery->endOcclusionQuery(); - * - * Results must be pulled using: - * UINT mNumberOfPixelsVisable; - * pullOcclusionQuery( &mNumberOfPixelsVisable ); - * - */ - virtual void beginOcclusionQuery() = 0; - - /** - * Ends the hardware occlusion test - */ - virtual void endOcclusionQuery() = 0; - - /** + /** + * Object public member functions + */ + + /** + * Default object constructor + * + */ + HardwareOcclusionQuery(); + + /** + * Object destructor + */ + virtual ~HardwareOcclusionQuery(); + + /** + * Starts the hardware occlusion query + * @remarks Simple usage: Create one or more OcclusionQuery object one per outstanding query or one per tested object + * OcclusionQuery* mOcclusionQuery; + * createOcclusionQuery( &mOcclusionQuery ); + * In the rendering loop: + * Draw all occluders + * mOcclusionQuery->startOcclusionQuery(); + * Draw the polygons to be tested + * mOcclusionQuery->endOcclusionQuery(); + * + * Results must be pulled using: + * UINT mNumberOfPixelsVisable; + * pullOcclusionQuery( &mNumberOfPixelsVisable ); + * + */ + virtual void beginOcclusionQuery() = 0; + + /** + * Ends the hardware occlusion test + */ + virtual void endOcclusionQuery() = 0; + + /** * Pulls the hardware occlusion query. - * @note Waits until the query result is available; use isStillOutstanding - * if just want to test if the result is available. + * @note Waits until the query result is available; use isStillOutstanding + * if just want to test if the result is available. * @retval NumOfFragments will get the resulting number of fragments. * @return True if success or false if not. */ - virtual bool pullOcclusionQuery(unsigned int* NumOfFragments) = 0; + virtual bool pullOcclusionQuery(unsigned int* NumOfFragments) = 0; - /** - * Let's you get the last pixel count with out doing the hardware occlusion test - * @return The last fragment count from the last test. - * Remarks This function won't give you new values, just the old value. - */ - unsigned int getLastQuerysPixelcount() const { return mPixelCount; } + /** + * Let's you get the last pixel count with out doing the hardware occlusion test + * @return The last fragment count from the last test. + * Remarks This function won't give you new values, just the old value. + */ + unsigned int getLastQuerysPixelcount() const { return mPixelCount; } - /** - * Lets you know when query is done, or still be processed by the Hardware - * @return true if query isn't finished. - */ - virtual bool isStillOutstanding(void) = 0; + /** + * Lets you know when query is done, or still be processed by the Hardware + * @return true if query isn't finished. + */ + virtual bool isStillOutstanding(void) = 0; //---------------------------------------------------------------------- @@ -122,11 +122,11 @@ namespace Ogre { /// Number of visible pixels determined by last query unsigned int mPixelCount; /// Has the query returned a result yet? - bool mIsQueryResultStillOutstanding; + bool mIsQueryResultStillOutstanding; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreHardwarePixelBuffer.h b/OgreMain/include/OgreHardwarePixelBuffer.h index d5a1480a16a..4e1700f275f 100644 --- a/OgreMain/include/OgreHardwarePixelBuffer.h +++ b/OgreMain/include/OgreHardwarePixelBuffer.h @@ -37,17 +37,17 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Specialisation of HardwareBuffer for a pixel buffer. The - HardwarePixelbuffer abstracts an 1D, 2D or 3D quantity of pixels - stored by the rendering API. The buffer can be located on the card - or in main memory depending on its usage. One mipmap level of a - texture is an example of a HardwarePixelBuffer. + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Specialisation of HardwareBuffer for a pixel buffer. The + HardwarePixelbuffer abstracts an 1D, 2D or 3D quantity of pixels + stored by the rendering API. The buffer can be located on the card + or in main memory depending on its usage. One mipmap level of a + texture is an example of a HardwarePixelBuffer. */ class _OgreExport HardwarePixelBuffer : public HardwareBuffer { @@ -60,8 +60,8 @@ namespace Ogre { PixelFormat mFormat; /// Currently locked region (local coords) PixelBox mCurrentLock; - /// The current locked box of this surface (entire surface coords) - Image::Box mLockedBox; + /// The current locked box of this surface (entire surface coords) + Image::Box mLockedBox; /// Internal implementation of lock(), must be overridden in subclasses @@ -71,11 +71,11 @@ namespace Ogre { for HardwarePixelBuffer implementations, but override the previous method */ virtual void* lockImpl(size_t offset, size_t length, LockOptions options); - /** Notify TextureBuffer of destruction of render target. - Called by RenderTexture when destroyed. - */ - virtual void _clearSliceRTT(size_t zoffset); - friend class RenderTexture; + /** Notify TextureBuffer of destruction of render target. + Called by RenderTexture when destroyed. + */ + virtual void _clearSliceRTT(size_t zoffset); + friend class RenderTexture; public: /// Should be called by HardwareBufferManager HardwarePixelBuffer(uint32 mWidth, uint32 mHeight, uint32 mDepth, @@ -86,88 +86,88 @@ namespace Ogre { /** Make every lock method from HardwareBuffer available. See http://www.research.att.com/~bs/bs_faq2.html#overloadderived */ - using HardwareBuffer::lock; + using HardwareBuffer::lock; /** Lock the buffer for (potentially) reading / writing. - @param lockBox Region of the buffer to lock - @param options Locking options - @return PixelBox containing the locked region, the pitches and - the pixel format - */ - virtual const PixelBox& lock(const Image::Box& lockBox, LockOptions options); - /// @copydoc HardwareBuffer::lock + @param lockBox Region of the buffer to lock + @param options Locking options + @return PixelBox containing the locked region, the pitches and + the pixel format + */ + virtual const PixelBox& lock(const Image::Box& lockBox, LockOptions options); + /// @copydoc HardwareBuffer::lock virtual void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); - /** Get the current locked region. This is the same value as returned - by lock(const Image::Box, LockOptions) - @return PixelBox containing the locked region - */ + /** Get the current locked region. This is the same value as returned + by lock(const Image::Box, LockOptions) + @return PixelBox containing the locked region + */ const PixelBox& getCurrentLock(); - - /// @copydoc HardwareBuffer::readData - virtual void readData(size_t offset, size_t length, void* pDest); - /// @copydoc HardwareBuffer::writeData - virtual void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); + + /// @copydoc HardwareBuffer::readData + virtual void readData(size_t offset, size_t length, void* pDest); + /// @copydoc HardwareBuffer::writeData + virtual void writeData(size_t offset, size_t length, const void* pSource, + bool discardWholeBuffer = false); /** Copies a box from another PixelBuffer to a region of the - this PixelBuffer. - @param src Source pixel buffer - @param srcBox Image::Box describing the source region in src - @param dstBox Image::Box describing the destination region in this buffer - @remarks The source and destination regions dimensions don't have to match, in which - case scaling is done. This scaling is generally done using a bilinear filter in hardware, + this PixelBuffer. + @param src Source pixel buffer + @param srcBox Image::Box describing the source region in src + @param dstBox Image::Box describing the destination region in this buffer + @remarks The source and destination regions dimensions don't have to match, in which + case scaling is done. This scaling is generally done using a bilinear filter in hardware, but it is faster to pass the source image in the right dimensions. - @note Only call this function when both buffers are unlocked. + @note Only call this function when both buffers are unlocked. */ virtual void blit(const HardwarePixelBufferSharedPtr &src, const Image::Box &srcBox, const Image::Box &dstBox); - /** Convenience function that blits the entire source pixel buffer to this buffer. - If source and destination dimensions don't match, scaling is done. - @param src PixelBox containing the source pixels and format in memory - @note Only call this function when the buffer is unlocked. - */ - void blit(const HardwarePixelBufferSharedPtr &src); - - /** Copies a region from normal memory to a region of this pixelbuffer. The source - image can be in any pixel format supported by OGRE, and in any size. - @param src PixelBox containing the source pixels and format in memory - @param dstBox Image::Box describing the destination region in this buffer + /** Convenience function that blits the entire source pixel buffer to this buffer. + If source and destination dimensions don't match, scaling is done. + @param src PixelBox containing the source pixels and format in memory + @note Only call this function when the buffer is unlocked. + */ + void blit(const HardwarePixelBufferSharedPtr &src); + + /** Copies a region from normal memory to a region of this pixelbuffer. The source + image can be in any pixel format supported by OGRE, and in any size. + @param src PixelBox containing the source pixels and format in memory + @param dstBox Image::Box describing the destination region in this buffer @remarks The source and destination regions dimensions don't have to match, in which case scaling is done. This scaling is generally done using a bilinear filter in hardware, but it is faster to pass the source image in the right dimensions. - @note Only call this function when the buffer is unlocked. - */ - virtual void blitFromMemory(const PixelBox &src, const Image::Box &dstBox) = 0; - - /** Convenience function that blits a pixelbox from memory to the entire - buffer. The source image is scaled as needed. - @param src PixelBox containing the source pixels and format in memory - @note Only call this function when the buffer is unlocked. - */ - void blitFromMemory(const PixelBox &src) - { - blitFromMemory(src, Box(0,0,0,mWidth,mHeight,mDepth)); - } - - /** Copies a region of this pixelbuffer to normal memory. - @param srcBox Image::Box describing the source region of this buffer - @param dst PixelBox describing the destination pixels and format in memory - @remarks The source and destination regions don't have to match, in which - case scaling is done. - @note Only call this function when the buffer is unlocked. - */ - virtual void blitToMemory(const Image::Box &srcBox, const PixelBox &dst) = 0; - - /** Convenience function that blits this entire buffer to a pixelbox. - The image is scaled as needed. - @param dst PixelBox describing the destination pixels and format in memory - @note Only call this function when the buffer is unlocked. - */ - void blitToMemory(const PixelBox &dst) - { - blitToMemory(Box(0,0,0,mWidth,mHeight,mDepth), dst); - } + @note Only call this function when the buffer is unlocked. + */ + virtual void blitFromMemory(const PixelBox &src, const Image::Box &dstBox) = 0; + + /** Convenience function that blits a pixelbox from memory to the entire + buffer. The source image is scaled as needed. + @param src PixelBox containing the source pixels and format in memory + @note Only call this function when the buffer is unlocked. + */ + void blitFromMemory(const PixelBox &src) + { + blitFromMemory(src, Box(0,0,0,mWidth,mHeight,mDepth)); + } + + /** Copies a region of this pixelbuffer to normal memory. + @param srcBox Image::Box describing the source region of this buffer + @param dst PixelBox describing the destination pixels and format in memory + @remarks The source and destination regions don't have to match, in which + case scaling is done. + @note Only call this function when the buffer is unlocked. + */ + virtual void blitToMemory(const Image::Box &srcBox, const PixelBox &dst) = 0; + + /** Convenience function that blits this entire buffer to a pixelbox. + The image is scaled as needed. + @param dst PixelBox describing the destination pixels and format in memory + @note Only call this function when the buffer is unlocked. + */ + void blitToMemory(const PixelBox &dst) + { + blitToMemory(Box(0,0,0,mWidth,mHeight,mDepth), dst); + } /** Get a render target for this PixelBuffer, or a slice of it. The texture this was acquired from must have TU_RENDERTARGET set, otherwise it is possible to @@ -198,8 +198,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreHardwareUniformBuffer.h b/OgreMain/include/OgreHardwareUniformBuffer.h index b9b58e5b704..d31ecf2cf57 100644 --- a/OgreMain/include/OgreHardwareUniformBuffer.h +++ b/OgreMain/include/OgreHardwareUniformBuffer.h @@ -35,30 +35,30 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - class HardwareBufferManagerBase; + class HardwareBufferManagerBase; - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Specialisation of HardwareBuffer for a uniform buffer. */ - class _OgreExport HardwareUniformBuffer : public HardwareBuffer + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Specialisation of HardwareBuffer for a uniform buffer. */ + class _OgreExport HardwareUniformBuffer : public HardwareBuffer { - protected: - HardwareBufferManagerBase* mMgr; - String mName; + protected: + HardwareBufferManagerBase* mMgr; + String mName; - public: - /// Should be called by HardwareBufferManager - HardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, - HardwareBuffer::Usage usage, bool useShadowBuffer = false, const String& name = ""); - ~HardwareUniformBuffer(); - /// Return the manager of this buffer, if any - HardwareBufferManagerBase* getManager() const { return mMgr; } + public: + /// Should be called by HardwareBufferManager + HardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, + HardwareBuffer::Usage usage, bool useShadowBuffer = false, const String& name = ""); + ~HardwareUniformBuffer(); + /// Return the manager of this buffer, if any + HardwareBufferManagerBase* getManager() const { return mMgr; } - const String& getName() const { return mName; } + const String& getName() const { return mName; } }; diff --git a/OgreMain/include/OgreHardwareVertexBuffer.h b/OgreMain/include/OgreHardwareVertexBuffer.h index 9c5149ffa2d..2b4d1b9cb50 100644 --- a/OgreMain/include/OgreHardwareVertexBuffer.h +++ b/OgreMain/include/OgreHardwareVertexBuffer.h @@ -36,49 +36,49 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - class HardwareBufferManagerBase; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Specialisation of HardwareBuffer for a vertex buffer. */ + class HardwareBufferManagerBase; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Specialisation of HardwareBuffer for a vertex buffer. */ class _OgreExport HardwareVertexBuffer : public HardwareBuffer { - protected: - - HardwareBufferManagerBase* mMgr; - size_t mNumVertices; - size_t mVertexSize; - bool mIsInstanceData; - size_t mInstanceDataStepRate; - /// Checks if vertex instance data is supported by the render system - virtual bool checkIfVertexInstanceDataIsSupported(); - - public: - /// Should be called by HardwareBufferManager - HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, - HardwareBuffer::Usage usage, bool useSystemMemory, bool useShadowBuffer); - ~HardwareVertexBuffer(); - /// Return the manager of this buffer, if any - HardwareBufferManagerBase* getManager() const { return mMgr; } - /// Gets the size in bytes of a single vertex in this buffer - size_t getVertexSize(void) const { return mVertexSize; } - /// Get the number of vertices in this buffer - size_t getNumVertices(void) const { return mNumVertices; } - /// Get if this vertex buffer is an "instance data" buffer (per instance) - bool getIsInstanceData() const { return mIsInstanceData; } - /// Set if this vertex buffer is an "instance data" buffer (per instance) - void setIsInstanceData(const bool val); - /// Get the number of instances to draw using the same per-instance data before advancing in the buffer by one element. - size_t getInstanceDataStepRate() const; - /// Set the number of instances to draw using the same per-instance data before advancing in the buffer by one element. - void setInstanceDataStepRate(const size_t val); - - - // NB subclasses should override lock, unlock, readData, writeData + protected: + + HardwareBufferManagerBase* mMgr; + size_t mNumVertices; + size_t mVertexSize; + bool mIsInstanceData; + size_t mInstanceDataStepRate; + /// Checks if vertex instance data is supported by the render system + virtual bool checkIfVertexInstanceDataIsSupported(); + + public: + /// Should be called by HardwareBufferManager + HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, + HardwareBuffer::Usage usage, bool useSystemMemory, bool useShadowBuffer); + ~HardwareVertexBuffer(); + /// Return the manager of this buffer, if any + HardwareBufferManagerBase* getManager() const { return mMgr; } + /// Gets the size in bytes of a single vertex in this buffer + size_t getVertexSize(void) const { return mVertexSize; } + /// Get the number of vertices in this buffer + size_t getNumVertices(void) const { return mNumVertices; } + /// Get if this vertex buffer is an "instance data" buffer (per instance) + bool getIsInstanceData() const { return mIsInstanceData; } + /// Set if this vertex buffer is an "instance data" buffer (per instance) + void setIsInstanceData(const bool val); + /// Get the number of instances to draw using the same per-instance data before advancing in the buffer by one element. + size_t getInstanceDataStepRate() const; + /// Set the number of instances to draw using the same per-instance data before advancing in the buffer by one element. + void setInstanceDataStepRate(const size_t val); + + + // NB subclasses should override lock, unlock, readData, writeData }; @@ -96,48 +96,48 @@ namespace Ogre { typedef HardwareBufferLockGuard HardwareVertexBufferLockGuard; /// Vertex element semantics, used to identify the meaning of vertex buffer contents - enum VertexElementSemantic { - /// Position, 3 reals per vertex - VES_POSITION = 1, - /// Blending weights - VES_BLEND_WEIGHTS = 2, + enum VertexElementSemantic { + /// Position, 3 reals per vertex + VES_POSITION = 1, + /// Blending weights + VES_BLEND_WEIGHTS = 2, /// Blending indices VES_BLEND_INDICES = 3, - /// Normal, 3 reals per vertex - VES_NORMAL = 4, - /// Diffuse colours - VES_DIFFUSE = 5, - /// Specular colours - VES_SPECULAR = 6, - /// Texture coordinates - VES_TEXTURE_COORDINATES = 7, + /// Normal, 3 reals per vertex + VES_NORMAL = 4, + /// Diffuse colours + VES_DIFFUSE = 5, + /// Specular colours + VES_SPECULAR = 6, + /// Texture coordinates + VES_TEXTURE_COORDINATES = 7, /// Binormal (Y axis if normal is Z) VES_BINORMAL = 8, /// Tangent (X axis if normal is Z) VES_TANGENT = 9, /// The number of VertexElementSemantic elements (note - the first value VES_POSITION is 1) VES_COUNT = 9 - }; + }; - /// Vertex element type, used to identify the base types of the vertex contents - enum VertexElementType + /// Vertex element type, used to identify the base types of the vertex contents + enum VertexElementType { VET_FLOAT1 = 0, VET_FLOAT2 = 1, VET_FLOAT3 = 2, VET_FLOAT4 = 3, /// alias to more specific colour type - use the current rendersystem's colour packing - VET_COLOUR = 4, - VET_SHORT1 = 5, - VET_SHORT2 = 6, - VET_SHORT3 = 7, - VET_SHORT4 = 8, + VET_COLOUR = 4, + VET_SHORT1 = 5, + VET_SHORT2 = 6, + VET_SHORT3 = 7, + VET_SHORT4 = 8, VET_UBYTE4 = 9, /// D3D style compact colour VET_COLOUR_ARGB = 10, /// GL style compact colour VET_COLOUR_ABGR = 11, - VET_DOUBLE1 = 12, + VET_DOUBLE1 = 12, VET_DOUBLE2 = 13, VET_DOUBLE3 = 14, VET_DOUBLE4 = 15, @@ -164,7 +164,7 @@ namespace Ogre { define the semantics (position, normal etc), the VertexElement class does. */ - class _OgreExport VertexElement : public VertexDataAlloc + class _OgreExport VertexElement : public VertexDataAlloc { protected: /// The source vertex buffer, as bound to an index using VertexBufferBinding @@ -178,8 +178,8 @@ namespace Ogre { /// Index of the item, only applicable for some elements like texture coords unsigned short mIndex; public: - /// Constructor, should not be called directly, only needed because of list - VertexElement() {} + /// Constructor, should not be called directly, only needed because of list + VertexElement() {} /// Constructor, should not be called directly, call VertexDeclaration::addElement VertexElement(unsigned short source, size_t offset, VertexElementType theType, VertexElementSemantic semantic, unsigned short index = 0); @@ -193,40 +193,40 @@ namespace Ogre { VertexElementSemantic getSemantic(void) const { return mSemantic; } /// Gets the index of this element, only applicable for repeating elements unsigned short getIndex(void) const { return mIndex; } - /// Gets the size of this element in bytes - size_t getSize(void) const; - /// Utility method for helping to calculate offsets - static size_t getTypeSize(VertexElementType etype); - /// Utility method which returns the count of values in a given type - static unsigned short getTypeCount(VertexElementType etype); - /** Simple converter function which will turn a single-value type into a - multi-value type based on a parameter. - */ - static VertexElementType multiplyTypeCount(VertexElementType baseType, unsigned short count); - /** Simple converter function which will a type into it's single-value - equivalent - makes switches on type easier. - */ - static VertexElementType getBaseType(VertexElementType multiType); - - /** Utility method for converting colour from - one packed 32-bit colour type to another. - @param srcType The source type - @param dstType The destination type - @param ptr Read / write value to change - */ - static void convertColourValue(VertexElementType srcType, - VertexElementType dstType, uint32* ptr); - - /** Utility method for converting colour to - a packed 32-bit colour type. - @param src source colour - @param dst The destination type - */ - static uint32 convertColourValue(const ColourValue& src, - VertexElementType dst); - - /** Utility method to get the most appropriate packed colour vertex element format. */ - static VertexElementType getBestColourVertexElementType(void); + /// Gets the size of this element in bytes + size_t getSize(void) const; + /// Utility method for helping to calculate offsets + static size_t getTypeSize(VertexElementType etype); + /// Utility method which returns the count of values in a given type + static unsigned short getTypeCount(VertexElementType etype); + /** Simple converter function which will turn a single-value type into a + multi-value type based on a parameter. + */ + static VertexElementType multiplyTypeCount(VertexElementType baseType, unsigned short count); + /** Simple converter function which will a type into it's single-value + equivalent - makes switches on type easier. + */ + static VertexElementType getBaseType(VertexElementType multiType); + + /** Utility method for converting colour from + one packed 32-bit colour type to another. + @param srcType The source type + @param dstType The destination type + @param ptr Read / write value to change + */ + static void convertColourValue(VertexElementType srcType, + VertexElementType dstType, uint32* ptr); + + /** Utility method for converting colour to + a packed 32-bit colour type. + @param src source colour + @param dst The destination type + */ + static uint32 convertColourValue(const ColourValue& src, + VertexElementType dst); + + /** Utility method to get the most appropriate packed colour vertex element format. */ + static VertexElementType getBestColourVertexElementType(void); inline bool operator== (const VertexElement& rhs) const { @@ -252,7 +252,7 @@ namespace Ogre { // The only way we can do this is to cast to char* in order to use byte offset // then cast back to void*. *pElem = static_cast( - static_cast(pBase) + mOffset); + static_cast(pBase) + mOffset); } /** Adjusts a pointer to the base of a vertex to point at this element. @remarks @@ -305,39 +305,39 @@ namespace Ogre { */ inline void baseVertexPointerToElement(void* pBase, unsigned short** pElem) const { - *pElem = static_cast( - static_cast( - static_cast(pBase) + mOffset)); + *pElem = static_cast( + static_cast( + static_cast(pBase) + mOffset)); } }; /** This class declares the format of a set of vertex inputs, which can be issued to the rendering API through a RenderOperation. - @remarks - You should be aware that the ordering and structure of the - VertexDeclaration can be very important on DirectX with older - cards,so if you want to maintain maximum compatibility with - all render systems and all cards you should be careful to follow these - rules:
        -
      1. VertexElements should be added in the following order, and the order of the - elements within a shared buffer should be as follows: - position, blending weights, normals, diffuse colours, specular colours, + @remarks + You should be aware that the ordering and structure of the + VertexDeclaration can be very important on DirectX with older + cards,so if you want to maintain maximum compatibility with + all render systems and all cards you should be careful to follow these + rules:
          +
        1. VertexElements should be added in the following order, and the order of the + elements within a shared buffer should be as follows: + position, blending weights, normals, diffuse colours, specular colours, texture coordinates (in order, with no gaps)
        2. -
        3. You must not have unused gaps in your buffers which are not referenced - by any VertexElement
        4. -
        5. You must not cause the buffer & offset settings of 2 VertexElements to overlap
        6. -
        - Whilst GL and more modern graphics cards in D3D will allow you to defy these rules, - sticking to them will ensure that your buffers have the maximum compatibility. - @par - Like the other classes in this functional area, these declarations should be created and - destroyed using the HardwareBufferManager. +
      2. You must not have unused gaps in your buffers which are not referenced + by any VertexElement
      3. +
      4. You must not cause the buffer & offset settings of 2 VertexElements to overlap
      5. +
      + Whilst GL and more modern graphics cards in D3D will allow you to defy these rules, + sticking to them will ensure that your buffers have the maximum compatibility. + @par + Like the other classes in this functional area, these declarations should be created and + destroyed using the HardwareBufferManager. */ - class _OgreExport VertexDeclaration : public VertexDataAlloc + class _OgreExport VertexDeclaration : public VertexDataAlloc { public: - /// Defines the list of vertex elements that makes up this declaration + /// Defines the list of vertex elements that makes up this declaration typedef list::type VertexElementList; /// Sort routine for vertex elements static bool vertexElementLess(const VertexElement& e1, const VertexElement& e2); @@ -380,16 +380,16 @@ namespace Ogre { /** Generates a new VertexDeclaration for optimal usage based on the current vertex declaration, which can be used with VertexData::reorganiseBuffers later if you wish, or simply used as a template. - @remarks - Different buffer organisations and buffer usages will be returned + @remarks + Different buffer organisations and buffer usages will be returned depending on the parameters passed to this method. @param skeletalAnimation Whether this vertex data is going to be - skeletally animated - @param vertexAnimation Whether this vertex data is going to be vertex animated - @param vertexAnimationNormals Whether vertex data animation is going to include normals animation + skeletally animated + @param vertexAnimation Whether this vertex data is going to be vertex animated + @param vertexAnimationNormals Whether vertex data animation is going to include normals animation */ VertexDeclaration* getAutoOrganisedDeclaration(bool skeletalAnimation, - bool vertexAnimation, bool vertexAnimationNormals) const; + bool vertexAnimation, bool vertexAnimationNormals) const; /** Gets the index of the highest source value referenced by this declaration. */ unsigned short getMaxSource(void) const; @@ -400,14 +400,14 @@ namespace Ogre { @remarks This method adds a single element (positions, normals etc) to the end of the vertex declaration. Please read the information in VertexDeclaration about - the importance of ordering and structure for compatibility with older D3D drivers. - @param source The binding index of HardwareVertexBuffer which will provide the source for this element. - See VertexBufferBinding for full information. + the importance of ordering and structure for compatibility with older D3D drivers. + @param source The binding index of HardwareVertexBuffer which will provide the source for this element. + See VertexBufferBinding for full information. @param offset The offset in bytes where this element is located in the buffer @param theType The data format of the element (3 floats, a colour etc) @param semantic The meaning of the data (position, normal, diffuse colour etc) @param index Optional index for multi-input elements like texture coordinates - @return A reference to the VertexElement added. + @return A reference to the VertexElement added. */ virtual const VertexElement& addElement(unsigned short source, size_t offset, VertexElementType theType, VertexElementSemantic semantic, unsigned short index = 0); @@ -439,46 +439,46 @@ namespace Ogre { */ virtual void removeElement(VertexElementSemantic semantic, unsigned short index = 0); - /** Remove all elements. */ - virtual void removeAllElements(void); + /** Remove all elements. */ + virtual void removeAllElements(void); /** Modify an element in-place, params as addElement. - @remarks - Please read the information in VertexDeclaration about - the importance of ordering and structure for compatibility with older D3D drivers. - */ + @remarks + Please read the information in VertexDeclaration about + the importance of ordering and structure for compatibility with older D3D drivers. + */ virtual void modifyElement(unsigned short elem_index, unsigned short source, size_t offset, VertexElementType theType, VertexElementSemantic semantic, unsigned short index = 0); - /** Finds a VertexElement with the given semantic, and index if there is more than - one element with the same semantic. + /** Finds a VertexElement with the given semantic, and index if there is more than + one element with the same semantic. @remarks If the element is not found, this method returns null. - */ - virtual const VertexElement* findElementBySemantic(VertexElementSemantic sem, unsigned short index = 0) const; - /** Based on the current elements, gets the size of the vertex for a given buffer source. - @param source The buffer binding index for which to get the vertex size. - */ - - /** Gets a list of elements which use a given source. - @remarks - Note that the list of elements is returned by value therefore is separate from - the declaration as soon as this method returns. - */ - virtual VertexElementList findElementsBySource(unsigned short source) const; - - /** Gets the vertex size defined by this declaration for a given source. */ + */ + virtual const VertexElement* findElementBySemantic(VertexElementSemantic sem, unsigned short index = 0) const; + /** Based on the current elements, gets the size of the vertex for a given buffer source. + @param source The buffer binding index for which to get the vertex size. + */ + + /** Gets a list of elements which use a given source. + @remarks + Note that the list of elements is returned by value therefore is separate from + the declaration as soon as this method returns. + */ + virtual VertexElementList findElementsBySource(unsigned short source) const; + + /** Gets the vertex size defined by this declaration for a given source. */ virtual size_t getVertexSize(unsigned short source) const; - - /** Return the index of the next free texture coordinate set which may be added - to this declaration. - */ - virtual unsigned short getNextFreeTextureCoordinate() const; + + /** Return the index of the next free texture coordinate set which may be added + to this declaration. + */ + virtual unsigned short getNextFreeTextureCoordinate() const; /** Clones this declaration. - @param mgr Optional HardwareBufferManager to use for creating the clone - (if null, use the current default). - */ + @param mgr Optional HardwareBufferManager to use for creating the clone + (if null, use the current default). + */ virtual VertexDeclaration* clone(HardwareBufferManagerBase* mgr = 0) const; inline bool operator== (const VertexDeclaration& rhs) const @@ -505,62 +505,62 @@ namespace Ogre { }; - /** Records the state of all the vertex buffer bindings required to provide a vertex declaration - with the input data it needs for the vertex elements. - @remarks - Why do we have this binding list rather than just have VertexElement referring to the - vertex buffers direct? Well, in the underlying APIs, binding the vertex buffers to an - index (or 'stream') is the way that vertex data is linked, so this structure better - reflects the realities of that. In addition, by separating the vertex declaration from - the list of vertex buffer bindings, it becomes possible to reuse bindings between declarations - and vice versa, giving opportunities to reduce the state changes required to perform rendering. - @par - Like the other classes in this functional area, these binding maps should be created and - destroyed using the HardwareBufferManager. - */ - class _OgreExport VertexBufferBinding : public VertexDataAlloc - { - public: - /// Defines the vertex buffer bindings used as source for vertex declarations - typedef map::type VertexBufferBindingMap; - protected: - VertexBufferBindingMap mBindingMap; - mutable unsigned short mHighIndex; - public: - /// Constructor, should not be called direct, use HardwareBufferManager::createVertexBufferBinding - VertexBufferBinding(); - virtual ~VertexBufferBinding(); - /** Set a binding, associating a vertex buffer with a given index. - @remarks - If the index is already associated with a vertex buffer, + /** Records the state of all the vertex buffer bindings required to provide a vertex declaration + with the input data it needs for the vertex elements. + @remarks + Why do we have this binding list rather than just have VertexElement referring to the + vertex buffers direct? Well, in the underlying APIs, binding the vertex buffers to an + index (or 'stream') is the way that vertex data is linked, so this structure better + reflects the realities of that. In addition, by separating the vertex declaration from + the list of vertex buffer bindings, it becomes possible to reuse bindings between declarations + and vice versa, giving opportunities to reduce the state changes required to perform rendering. + @par + Like the other classes in this functional area, these binding maps should be created and + destroyed using the HardwareBufferManager. + */ + class _OgreExport VertexBufferBinding : public VertexDataAlloc + { + public: + /// Defines the vertex buffer bindings used as source for vertex declarations + typedef map::type VertexBufferBindingMap; + protected: + VertexBufferBindingMap mBindingMap; + mutable unsigned short mHighIndex; + public: + /// Constructor, should not be called direct, use HardwareBufferManager::createVertexBufferBinding + VertexBufferBinding(); + virtual ~VertexBufferBinding(); + /** Set a binding, associating a vertex buffer with a given index. + @remarks + If the index is already associated with a vertex buffer, the association will be replaced. This may cause the old buffer to be destroyed if nothing else is referring to it. - You should assign bindings from 0 and not leave gaps, although you can - bind them in any order. - */ - virtual void setBinding(unsigned short index, const HardwareVertexBufferSharedPtr& buffer); - /** Removes an existing binding. */ - virtual void unsetBinding(unsigned short index); + You should assign bindings from 0 and not leave gaps, although you can + bind them in any order. + */ + virtual void setBinding(unsigned short index, const HardwareVertexBufferSharedPtr& buffer); + /** Removes an existing binding. */ + virtual void unsetBinding(unsigned short index); /** Removes all the bindings. */ virtual void unsetAllBindings(void); - /// Gets a read-only version of the buffer bindings - virtual const VertexBufferBindingMap& getBindings(void) const; + /// Gets a read-only version of the buffer bindings + virtual const VertexBufferBindingMap& getBindings(void) const; - /// Gets the buffer bound to the given source index - virtual const HardwareVertexBufferSharedPtr& getBuffer(unsigned short index) const; - /// Gets whether a buffer is bound to the given source index - virtual bool isBufferBound(unsigned short index) const; + /// Gets the buffer bound to the given source index + virtual const HardwareVertexBufferSharedPtr& getBuffer(unsigned short index) const; + /// Gets whether a buffer is bound to the given source index + virtual bool isBufferBound(unsigned short index) const; virtual size_t getBufferCount(void) const { return mBindingMap.size(); } - /** Gets the highest index which has already been set, plus 1. - @remarks - This is to assist in binding the vertex buffers such that there are - not gaps in the list. - */ - virtual unsigned short getNextIndex(void) const { return mHighIndex++; } + /** Gets the highest index which has already been set, plus 1. + @remarks + This is to assist in binding the vertex buffers such that there are + not gaps in the list. + */ + virtual unsigned short getNextIndex(void) const { return mHighIndex++; } /** Gets the last bound index. */ @@ -590,9 +590,9 @@ namespace Ogre { virtual bool getHasInstanceData() const; - }; - /** @} */ - /** @} */ + }; + /** @} */ + /** @} */ diff --git a/OgreMain/include/OgreHeaderPrefix.h b/OgreMain/include/OgreHeaderPrefix.h index aea1ed43f9d..30e860dd079 100644 --- a/OgreMain/include/OgreHeaderPrefix.h +++ b/OgreMain/include/OgreHeaderPrefix.h @@ -64,7 +64,7 @@ THE SOFTWARE // the warnings with things we may not be able to do anything about (e.g. // generated code from nvparse etc). I doubt very much that these calls // will ever be actually removed from VC anyway, it would break too much code. -# pragma warning( disable: 4996) +# pragma warning( disable: 4996) // disable: "conditional expression constant", always occurs on // OGRE_MUTEX_CONDITIONAL when no threading enabled diff --git a/OgreMain/include/OgreHighLevelGpuProgram.h b/OgreMain/include/OgreHighLevelGpuProgram.h index 5a80b3465af..9b1f01225cb 100644 --- a/OgreMain/include/OgreHighLevelGpuProgram.h +++ b/OgreMain/include/OgreHighLevelGpuProgram.h @@ -33,13 +33,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Abstract base class representing a high-level program (a vertex or + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Abstract base class representing a high-level program (a vertex or fragment program). @remarks High-level programs are vertex and fragment programs written in a high-level @@ -67,8 +67,8 @@ namespace Ogre { bool mHighLevelLoaded; /// The underlying assembler program GpuProgramPtr mAssemblerProgram; - /// Have we built the name->index parameter map yet? - mutable bool mConstantDefsBuilt; + /// Have we built the name->index parameter map yet? + mutable bool mConstantDefsBuilt; /// Internal load high-level portion if not loaded virtual void loadHighLevel(void); @@ -85,13 +85,13 @@ namespace Ogre { virtual void unloadHighLevelImpl(void) = 0; /// Populate the passed parameters with name->index map virtual void populateParameterNames(GpuProgramParametersSharedPtr params); - /** Build the constant definition map, must be overridden. - @note The implementation must fill in the (inherited) mConstantDefs field at a minimum, - and if the program requires that parameters are bound using logical - parameter indexes then the mFloatLogicalToPhysical and mIntLogicalToPhysical - maps must also be populated. - */ - virtual void buildConstantDefinitions() const = 0; + /** Build the constant definition map, must be overridden. + @note The implementation must fill in the (inherited) mConstantDefs field at a minimum, + and if the program requires that parameters are bound using logical + parameter indexes then the mFloatLogicalToPhysical and mIntLogicalToPhysical + maps must also be populated. + */ + virtual void buildConstantDefinitions() const = 0; /** @copydoc Resource::loadImpl */ void loadImpl(); @@ -115,20 +115,20 @@ namespace Ogre { /** @copydoc GpuProgram::_getBindingDelegate */ GpuProgram* _getBindingDelegate(void) { return mAssemblerProgram.getPointer(); } - /** Get the full list of GpuConstantDefinition instances. - @note - Only available if this parameters object has named parameters. - */ - const GpuNamedConstants& getConstantDefinitions() const; + /** Get the full list of GpuConstantDefinition instances. + @note + Only available if this parameters object has named parameters. + */ + const GpuNamedConstants& getConstantDefinitions() const; - virtual size_t calculateSize(void) const; + virtual size_t calculateSize(void) const; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreHighLevelGpuProgramManager.h b/OgreMain/include/OgreHighLevelGpuProgramManager.h index 0a6edf75388..d1beac6b9f1 100644 --- a/OgreMain/include/OgreHighLevelGpuProgramManager.h +++ b/OgreMain/include/OgreHighLevelGpuProgramManager.h @@ -36,87 +36,87 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Interface definition for factories of HighLevelGpuProgram. */ - class _OgreExport HighLevelGpuProgramFactory : public FactoryAlloc - { - public: + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Interface definition for factories of HighLevelGpuProgram. */ + class _OgreExport HighLevelGpuProgramFactory : public FactoryAlloc + { + public: HighLevelGpuProgramFactory() {} virtual ~HighLevelGpuProgramFactory(); - /// Get the name of the language this factory creates programs for - virtual const String& getLanguage(void) const = 0; + /// Get the name of the language this factory creates programs for + virtual const String& getLanguage(void) const = 0; virtual HighLevelGpuProgram* create(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) = 0; - virtual void destroy(HighLevelGpuProgram* prog) = 0; - }; - - /** This ResourceManager manages high-level vertex and fragment programs. - @remarks - High-level vertex and fragment programs can be used instead of assembler programs - as managed by GpuProgramManager; however they typically result in a GpuProgram - being created as a derivative of the high-level program. High-level programs are - easier to write, and can often be API-independent, unlike assembler programs. - @par - This class not only manages the programs themselves, it also manages the factory - classes which allow the creation of high-level programs using a variety of high-level - syntaxes. Plugins can be created which register themselves as high-level program - factories and as such the engine can be extended to accept virtually any kind of - program provided a plugin is written. - */ - class _OgreExport HighLevelGpuProgramManager - : public ResourceManager, public Singleton - { - public: - typedef map::type FactoryMap; - protected: - /// Factories capable of creating HighLevelGpuProgram instances - FactoryMap mFactories; - - /// Factory for dealing with programs for languages we can't create - HighLevelGpuProgramFactory* mNullFactory; - /// Factory for unified high-level programs - HighLevelGpuProgramFactory* mUnifiedFactory; - - HighLevelGpuProgramFactory* getFactory(const String& language); + virtual void destroy(HighLevelGpuProgram* prog) = 0; + }; + + /** This ResourceManager manages high-level vertex and fragment programs. + @remarks + High-level vertex and fragment programs can be used instead of assembler programs + as managed by GpuProgramManager; however they typically result in a GpuProgram + being created as a derivative of the high-level program. High-level programs are + easier to write, and can often be API-independent, unlike assembler programs. + @par + This class not only manages the programs themselves, it also manages the factory + classes which allow the creation of high-level programs using a variety of high-level + syntaxes. Plugins can be created which register themselves as high-level program + factories and as such the engine can be extended to accept virtually any kind of + program provided a plugin is written. + */ + class _OgreExport HighLevelGpuProgramManager + : public ResourceManager, public Singleton + { + public: + typedef map::type FactoryMap; + protected: + /// Factories capable of creating HighLevelGpuProgram instances + FactoryMap mFactories; + + /// Factory for dealing with programs for languages we can't create + HighLevelGpuProgramFactory* mNullFactory; + /// Factory for unified high-level programs + HighLevelGpuProgramFactory* mUnifiedFactory; + + HighLevelGpuProgramFactory* getFactory(const String& language); /// @copydoc ResourceManager::createImpl Resource* createImpl(const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* createParams); - public: - HighLevelGpuProgramManager(); - ~HighLevelGpuProgramManager(); - /** Add a new factory object for high-level programs of a given language. */ - void addFactory(HighLevelGpuProgramFactory* factory); - /** Remove a factory object for high-level programs of a given language. */ - void removeFactory(HighLevelGpuProgramFactory* factory); + public: + HighLevelGpuProgramManager(); + ~HighLevelGpuProgramManager(); + /** Add a new factory object for high-level programs of a given language. */ + void addFactory(HighLevelGpuProgramFactory* factory); + /** Remove a factory object for high-level programs of a given language. */ + void removeFactory(HighLevelGpuProgramFactory* factory); - /** Returns whether a given high-level language is supported. */ - bool isLanguageSupported(const String& lang); + /** Returns whether a given high-level language is supported. */ + bool isLanguageSupported(const String& lang); - /// Get a resource by name - /// @see ResourceManager::getResourceByName - HighLevelGpuProgramPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + /// Get a resource by name + /// @see ResourceManager::getResourceByName + HighLevelGpuProgramPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); /** Create a new, unloaded HighLevelGpuProgram. - @par - This method creates a new program of the type specified as the second and third parameters. - You will have to call further methods on the returned program in order to - define the program fully before you can load it. - @param name The identifying name of the program + @par + This method creates a new program of the type specified as the second and third parameters. + You will have to call further methods on the returned program in order to + define the program fully before you can load it. + @param name The identifying name of the program @param groupName The name of the resource group which this program is to be a member of - @param language Code of the language to use (e.g. "cg") - @param gptype The type of program to create - */ - HighLevelGpuProgramPtr createProgram( - const String& name, const String& groupName, + @param language Code of the language to use (e.g. "cg") + @param gptype The type of program to create + */ + HighLevelGpuProgramPtr createProgram( + const String& name, const String& groupName, const String& language, GpuProgramType gptype); /** Override standard Singleton retrieval. @@ -153,9 +153,9 @@ namespace Ogre { static HighLevelGpuProgramManager* getSingletonPtr(void); - }; - /** @} */ - /** @} */ + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreImage.h b/OgreMain/include/OgreImage.h index 0948f25b6e5..f0ef41f929e 100644 --- a/OgreMain/include/OgreImage.h +++ b/OgreMain/include/OgreImage.h @@ -33,12 +33,12 @@ THE SOFTWARE. #include "OgrePixelFormat.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Image - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Image + * @{ + */ enum ImageFlags { @@ -57,11 +57,11 @@ namespace Ogre { when extra processing needs to be done on an image before it is loaded or when you want to blit to an existing texture. */ - class _OgreExport Image : public ImageAlloc + class _OgreExport Image : public ImageAlloc { public: - typedef Ogre::Box Box; - typedef Ogre::Rect Rect; + typedef Ogre::Box Box; + typedef Ogre::Rect Rect; public: /** Standard constructor. */ @@ -122,147 +122,147 @@ namespace Ogre { Alpha component. The type can be determined by calling getFormat(). @note - Whilst typically your image is likely to be a simple 2D image, - you can define complex images including cube maps, volume maps, - and images including custom mip levels. The layout of the - internal memory should be: -
      • face 0, mip 0 (top), width x height (x depth)
      • -
      • face 0, mip 1, width/2 x height/2 (x depth/2)
      • -
      • face 0, mip 2, width/4 x height/4 (x depth/4)
      • -
      • .. remaining mips for face 0 ..
      • -
      • face 1, mip 0 (top), width x height (x depth)
      • .. and so on. -
      - Of course, you will never have multiple faces (cube map) and - depth too. - @param data + Whilst typically your image is likely to be a simple 2D image, + you can define complex images including cube maps, volume maps, + and images including custom mip levels. The layout of the + internal memory should be: +
      • face 0, mip 0 (top), width x height (x depth)
      • +
      • face 0, mip 1, width/2 x height/2 (x depth/2)
      • +
      • face 0, mip 2, width/4 x height/4 (x depth/4)
      • +
      • .. remaining mips for face 0 ..
      • +
      • face 1, mip 0 (top), width x height (x depth)
      • .. and so on. +
      + Of course, you will never have multiple faces (cube map) and + depth too. + @param data The data pointer @param width - Width of image + Width of image @param height - Height of image - @param depth + Height of image + @param depth Image Depth (in 3d images, numbers of layers, otherwise 1) @param format - Pixel Format + Pixel Format @param autoDelete If memory associated with this buffer is to be destroyed - with the Image object. Note: it's important that if you set - this option to true, that you allocated the memory using OGRE_ALLOC_T - with a category of MEMCATEGORY_GENERAL to ensure the freeing of memory - matches up. - @param numFaces - The number of faces the image data has inside (6 for cubemaps, 1 otherwise) + with the Image object. Note: it's important that if you set + this option to true, that you allocated the memory using OGRE_ALLOC_T + with a category of MEMCATEGORY_GENERAL to ensure the freeing of memory + matches up. + @param numFaces + The number of faces the image data has inside (6 for cubemaps, 1 otherwise) @param numMipMaps The number of mipmaps the image data has inside @note The memory associated with this buffer is NOT destroyed with the Image object, unless autoDelete is set to true. - @remarks - The size of the buffer must be numFaces*PixelUtil::getMemorySize(width, height, depth, format) + @remarks + The size of the buffer must be numFaces*PixelUtil::getMemorySize(width, height, depth, format) */ - Image& loadDynamicImage( uchar* data, uint32 width, uint32 height, - uint32 depth, - PixelFormat format, bool autoDelete = false, - size_t numFaces = 1, uint8 numMipMaps = 0); - - /** Stores a pointer to raw data in memory. The pixel format has to be specified. + Image& loadDynamicImage( uchar* data, uint32 width, uint32 height, + uint32 depth, + PixelFormat format, bool autoDelete = false, + size_t numFaces = 1, uint8 numMipMaps = 0); + + /** Stores a pointer to raw data in memory. The pixel format has to be specified. @remarks This method loads an image into memory held in the object. The pixel format will be either greyscale or RGB with an optional Alpha component. The type can be determined by calling getFormat(). @note - Whilst typically your image is likely to be a simple 2D image, - you can define complex images including cube maps - and images including custom mip levels. The layout of the - internal memory should be: -
      • face 0, mip 0 (top), width x height
      • -
      • face 0, mip 1, width/2 x height/2
      • -
      • face 0, mip 2, width/4 x height/4
      • -
      • .. remaining mips for face 0 ..
      • -
      • face 1, mip 0 (top), width x height (x depth)
      • .. and so on. -
      - Of course, you will never have multiple faces (cube map) and - depth too. + Whilst typically your image is likely to be a simple 2D image, + you can define complex images including cube maps + and images including custom mip levels. The layout of the + internal memory should be: +
      • face 0, mip 0 (top), width x height
      • +
      • face 0, mip 1, width/2 x height/2
      • +
      • face 0, mip 2, width/4 x height/4
      • +
      • .. remaining mips for face 0 ..
      • +
      • face 1, mip 0 (top), width x height (x depth)
      • .. and so on. +
      + Of course, you will never have multiple faces (cube map) and + depth too. @param data The data pointer @param width - Width of image + Width of image @param height - Height of image + Height of image @param format - Pixel Format + Pixel Format @note The memory associated with this buffer is NOT destroyed with the Image object. - @remarks This function is deprecated; one should really use the - Image::loadDynamicImage(data, width, height, depth, format, ...) to be compatible - with future Ogre versions. + @remarks This function is deprecated; one should really use the + Image::loadDynamicImage(data, width, height, depth, format, ...) to be compatible + with future Ogre versions. */ - Image& loadDynamicImage( uchar* data, uint32 width, - uint32 height, PixelFormat format) - { - return loadDynamicImage(data, width, height, 1, format); - } - /** Loads raw data from a stream. See the function - loadDynamicImage for a description of the parameters. - @remarks - The size of the buffer must be numFaces*PixelUtil::getMemorySize(width, height, depth, format) + Image& loadDynamicImage( uchar* data, uint32 width, + uint32 height, PixelFormat format) + { + return loadDynamicImage(data, width, height, 1, format); + } + /** Loads raw data from a stream. See the function + loadDynamicImage for a description of the parameters. + @remarks + The size of the buffer must be numFaces*PixelUtil::getMemorySize(width, height, depth, format) @note - Whilst typically your image is likely to be a simple 2D image, - you can define complex images including cube maps - and images including custom mip levels. The layout of the - internal memory should be: -
      • face 0, mip 0 (top), width x height (x depth)
      • -
      • face 0, mip 1, width/2 x height/2 (x depth/2)
      • -
      • face 0, mip 2, width/4 x height/4 (x depth/4)
      • -
      • .. remaining mips for face 0 ..
      • -
      • face 1, mip 0 (top), width x height (x depth)
      • .. and so on. -
      - Of course, you will never have multiple faces (cube map) and - depth too. + Whilst typically your image is likely to be a simple 2D image, + you can define complex images including cube maps + and images including custom mip levels. The layout of the + internal memory should be: +
      • face 0, mip 0 (top), width x height (x depth)
      • +
      • face 0, mip 1, width/2 x height/2 (x depth/2)
      • +
      • face 0, mip 2, width/4 x height/4 (x depth/4)
      • +
      • .. remaining mips for face 0 ..
      • +
      • face 1, mip 0 (top), width x height (x depth)
      • .. and so on. +
      + Of course, you will never have multiple faces (cube map) and + depth too. */ Image & loadRawData( DataStreamPtr& stream, uint32 width, uint32 height, uint32 depth, PixelFormat format, - size_t numFaces = 1, size_t numMipMaps = 0); + size_t numFaces = 1, size_t numMipMaps = 0); /** Loads raw data from a stream. The pixel format has to be specified. - @remarks This function is deprecated; one should really use the - Image::loadRawData(stream, width, height, depth, format, ...) to be compatible - with future Ogre versions. + @remarks This function is deprecated; one should really use the + Image::loadRawData(stream, width, height, depth, format, ...) to be compatible + with future Ogre versions. @note - Whilst typically your image is likely to be a simple 2D image, - you can define complex images including cube maps - and images including custom mip levels. The layout of the - internal memory should be: -
      • face 0, mip 0 (top), width x height
      • -
      • face 0, mip 1, width/2 x height/2
      • -
      • face 0, mip 2, width/4 x height/4
      • -
      • .. remaining mips for face 0 ..
      • -
      • face 1, mip 0 (top), width x height (x depth)
      • .. and so on. -
      - Of course, you will never have multiple faces (cube map) and - depth too. + Whilst typically your image is likely to be a simple 2D image, + you can define complex images including cube maps + and images including custom mip levels. The layout of the + internal memory should be: +
      • face 0, mip 0 (top), width x height
      • +
      • face 0, mip 1, width/2 x height/2
      • +
      • face 0, mip 2, width/4 x height/4
      • +
      • .. remaining mips for face 0 ..
      • +
      • face 1, mip 0 (top), width x height (x depth)
      • .. and so on. +
      + Of course, you will never have multiple faces (cube map) and + depth too. */ Image & loadRawData( DataStreamPtr& stream, uint32 width, uint32 height, PixelFormat format ) - { - return loadRawData(stream, width, height, 1, format); - } + { + return loadRawData(stream, width, height, 1, format); + } /** Loads an image file. @remarks This method loads an image into memory. Any format for which - an associated ImageCodec is registered can be loaded. - This can include complex formats like DDS with embedded custom - mipmaps, cube faces and volume textures. + an associated ImageCodec is registered can be loaded. + This can include complex formats like DDS with embedded custom + mipmaps, cube faces and volume textures. The type can be determined by calling getFormat(). @param filename Name of an image file to load. @@ -278,97 +278,97 @@ namespace Ogre { @remarks This method works in the same way as the filename-based load method except it loads the image from a DataStream object. - This DataStream is expected to contain the + This DataStream is expected to contain the encoded data as it would be held in a file. Any format for which an associated ImageCodec is registered - can be loaded. - This can include complex formats like DDS with embedded custom - mipmaps, cube faces and volume textures. + can be loaded. + This can include complex formats like DDS with embedded custom + mipmaps, cube faces and volume textures. The type can be determined by calling getFormat(). @param stream The source data. @param type The type of the image. Used to decide what decompression codec to use. Can be left blank if the stream data includes - a header to identify the data. + a header to identify the data. @see Image::load( const String& filename ) */ - Image & load(DataStreamPtr& stream, const String& type = BLANKSTRING ); - - /** Utility method to combine 2 separate images into this one, with the first - image source supplying the RGB channels, and the second image supplying the - alpha channel (as luminance or separate alpha). - @param rgbFilename Filename of image supplying the RGB channels (any alpha is ignored) - @param alphaFilename Filename of image supplying the alpha channel. If a luminance image the - single channel is used directly, if an RGB image then the values are - converted to greyscale. - @param groupName The resource group from which to load the images - @param format The destination format - */ - Image & loadTwoImagesAsRGBA(const String& rgbFilename, const String& alphaFilename, - const String& groupName, PixelFormat format = PF_BYTE_RGBA); - - /** Utility method to combine 2 separate images into this one, with the first - image source supplying the RGB channels, and the second image supplying the - alpha channel (as luminance or separate alpha). - @param rgbStream Stream of image supplying the RGB channels (any alpha is ignored) - @param alphaStream Stream of image supplying the alpha channel. If a luminance image the - single channel is used directly, if an RGB image then the values are - converted to greyscale. - @param format The destination format - @param rgbType The type of the RGB image. Used to decide what decompression - codec to use. Can be left blank if the stream data includes - a header to identify the data. - @param alphaType The type of the alpha image. Used to decide what decompression - codec to use. Can be left blank if the stream data includes - a header to identify the data. - */ - Image & loadTwoImagesAsRGBA(DataStreamPtr& rgbStream, DataStreamPtr& alphaStream, PixelFormat format = PF_BYTE_RGBA, - const String& rgbType = BLANKSTRING, const String& alphaType = BLANKSTRING); - - /** Utility method to combine 2 separate images into this one, with the first - image source supplying the RGB channels, and the second image supplying the - alpha channel (as luminance or separate alpha). - @param rgb Image supplying the RGB channels (any alpha is ignored) - @param alpha Image supplying the alpha channel. If a luminance image the - single channel is used directly, if an RGB image then the values are - converted to greyscale. - @param format The destination format - */ - Image & combineTwoImagesAsRGBA(const Image& rgb, const Image& alpha, PixelFormat format = PF_BYTE_RGBA); + Image & load(DataStreamPtr& stream, const String& type = BLANKSTRING ); + + /** Utility method to combine 2 separate images into this one, with the first + image source supplying the RGB channels, and the second image supplying the + alpha channel (as luminance or separate alpha). + @param rgbFilename Filename of image supplying the RGB channels (any alpha is ignored) + @param alphaFilename Filename of image supplying the alpha channel. If a luminance image the + single channel is used directly, if an RGB image then the values are + converted to greyscale. + @param groupName The resource group from which to load the images + @param format The destination format + */ + Image & loadTwoImagesAsRGBA(const String& rgbFilename, const String& alphaFilename, + const String& groupName, PixelFormat format = PF_BYTE_RGBA); + + /** Utility method to combine 2 separate images into this one, with the first + image source supplying the RGB channels, and the second image supplying the + alpha channel (as luminance or separate alpha). + @param rgbStream Stream of image supplying the RGB channels (any alpha is ignored) + @param alphaStream Stream of image supplying the alpha channel. If a luminance image the + single channel is used directly, if an RGB image then the values are + converted to greyscale. + @param format The destination format + @param rgbType The type of the RGB image. Used to decide what decompression + codec to use. Can be left blank if the stream data includes + a header to identify the data. + @param alphaType The type of the alpha image. Used to decide what decompression + codec to use. Can be left blank if the stream data includes + a header to identify the data. + */ + Image & loadTwoImagesAsRGBA(DataStreamPtr& rgbStream, DataStreamPtr& alphaStream, PixelFormat format = PF_BYTE_RGBA, + const String& rgbType = BLANKSTRING, const String& alphaType = BLANKSTRING); + + /** Utility method to combine 2 separate images into this one, with the first + image source supplying the RGB channels, and the second image supplying the + alpha channel (as luminance or separate alpha). + @param rgb Image supplying the RGB channels (any alpha is ignored) + @param alpha Image supplying the alpha channel. If a luminance image the + single channel is used directly, if an RGB image then the values are + converted to greyscale. + @param format The destination format + */ + Image & combineTwoImagesAsRGBA(const Image& rgb, const Image& alpha, PixelFormat format = PF_BYTE_RGBA); /** Save the image as a file. - @remarks - Saving and loading are implemented by back end (sometimes third - party) codecs. Implemented saving functionality is more limited - than loading in some cases. Particularly DDS file format support - is currently limited to true colour or single channel float32, - square, power of two textures with no mipmaps. Volumetric support - is currently limited to DDS files. - */ + @remarks + Saving and loading are implemented by back end (sometimes third + party) codecs. Implemented saving functionality is more limited + than loading in some cases. Particularly DDS file format support + is currently limited to true colour or single channel float32, + square, power of two textures with no mipmaps. Volumetric support + is currently limited to DDS files. + */ void save(const String& filename); - /** Encode the image and return a stream to the data. - @param formatextension An extension to identify the image format - to encode into, e.g. "jpg" or "png" - */ - DataStreamPtr encode(const String& formatextension); - - /** Returns a pointer to the internal image buffer. - @remarks - Be careful with this method. You will almost certainly - prefer to use getPixelBox, especially with complex images - which include many faces or custom mipmaps. + /** Encode the image and return a stream to the data. + @param formatextension An extension to identify the image format + to encode into, e.g. "jpg" or "png" + */ + DataStreamPtr encode(const String& formatextension); + + /** Returns a pointer to the internal image buffer. + @remarks + Be careful with this method. You will almost certainly + prefer to use getPixelBox, especially with complex images + which include many faces or custom mipmaps. */ uchar* getData(void); /** Returns a const pointer to the internal image buffer. - @remarks - Be careful with this method. You will almost certainly - prefer to use getPixelBox, especially with complex images - which include many faces or custom mipmaps. + @remarks + Be careful with this method. You will almost certainly + prefer to use getPixelBox, especially with complex images + which include many faces or custom mipmaps. */ const uchar * getData() const; @@ -395,11 +395,11 @@ namespace Ogre { /** Gets the depth of the image. */ uint32 getDepth(void) const; - - /** Get the number of faces of the image. This is usually 6 for a cubemap, and - 1 for a normal image. - */ - size_t getNumFaces(void) const; + + /** Get the number of faces of the image. This is usually 6 for a cubemap, and + 1 for a normal image. + */ + size_t getNumFaces(void) const; /** Gets the physical width in bytes of each row of pixels. */ @@ -416,8 +416,8 @@ namespace Ogre { /** Returns true if the image has an alpha component. */ bool getHasAlpha() const; - - /** Does gamma adjustment. + + /** Does gamma adjustment. @note Basic algo taken from Titan Engine, copyright (c) 2000 Ignacio Castano Iguado @@ -443,66 +443,66 @@ namespace Ogre { */ PixelBox getPixelBox(size_t face = 0, size_t mipmap = 0) const; - /// Delete all the memory held by this image, if owned by this image (not dynamic) - void freeMemory(); - - enum Filter - { - FILTER_NEAREST, - FILTER_LINEAR, - FILTER_BILINEAR, - FILTER_BOX, - FILTER_TRIANGLE, - FILTER_BICUBIC - }; - /** Scale a 1D, 2D or 3D image volume. - @param src PixelBox containing the source pointer, dimensions and format - @param dst PixelBox containing the destination pointer, dimensions and format - @param filter Which filter to use - @remarks This function can do pixel format conversion in the process. - @note dst and src can point to the same PixelBox object without any problem - */ - static void scale(const PixelBox &src, const PixelBox &dst, Filter filter = FILTER_BILINEAR); - - /** Resize a 2D image, applying the appropriate filter. */ - void resize(ushort width, ushort height, Filter filter = FILTER_BILINEAR); - + /// Delete all the memory held by this image, if owned by this image (not dynamic) + void freeMemory(); + + enum Filter + { + FILTER_NEAREST, + FILTER_LINEAR, + FILTER_BILINEAR, + FILTER_BOX, + FILTER_TRIANGLE, + FILTER_BICUBIC + }; + /** Scale a 1D, 2D or 3D image volume. + @param src PixelBox containing the source pointer, dimensions and format + @param dst PixelBox containing the destination pointer, dimensions and format + @param filter Which filter to use + @remarks This function can do pixel format conversion in the process. + @note dst and src can point to the same PixelBox object without any problem + */ + static void scale(const PixelBox &src, const PixelBox &dst, Filter filter = FILTER_BILINEAR); + + /** Resize a 2D image, applying the appropriate filter. */ + void resize(ushort width, ushort height, Filter filter = FILTER_BILINEAR); + /// Static function to calculate size in bytes from the number of mipmaps, faces and the dimensions static size_t calculateSize(size_t mipmaps, size_t faces, uint32 width, uint32 height, uint32 depth, PixelFormat format); - /// Static function to get an image type string from a stream via magic numbers - static String getFileExtFromMagic(DataStreamPtr stream); + /// Static function to get an image type string from a stream via magic numbers + static String getFileExtFromMagic(DataStreamPtr stream); protected: /// The width of the image in pixels - uint32 mWidth; + uint32 mWidth; /// The height of the image in pixels - uint32 mHeight; + uint32 mHeight; /// The depth of the image - uint32 mDepth; + uint32 mDepth; /// The size of the image buffer - size_t mBufSize; + size_t mBufSize; /// The number of mipmaps the image contains - uint8 mNumMipmaps; + uint8 mNumMipmaps; /// Image specific flags. - int mFlags; + int mFlags; /// The pixel format of the image - PixelFormat mFormat; + PixelFormat mFormat; /// The number of bytes per pixel - uchar mPixelSize; - uchar* mBuffer; + uchar mPixelSize; + uchar* mBuffer; - /// A bool to determine if we delete the buffer or the calling app does - bool mAutoDelete; + /// A bool to determine if we delete the buffer or the calling app does + bool mAutoDelete; }; - typedef vector::type ImagePtrList; - typedef vector::type ConstImagePtrList; + typedef vector::type ImagePtrList; + typedef vector::type ConstImagePtrList; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreImageCodec.h b/OgreMain/include/OgreImageCodec.h index c61f9491bda..acb7ec40afb 100644 --- a/OgreMain/include/OgreImageCodec.h +++ b/OgreMain/include/OgreImageCodec.h @@ -33,13 +33,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Image - * @{ - */ - /** Codec specialized in images. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Image + * @{ + */ + /** Codec specialized in images. @remarks The users implementing subclasses of ImageCodec are required to return a valid pointer to a ImageData class from the decode(...) function. @@ -53,14 +53,14 @@ namespace Ogre { class _OgrePrivate ImageData : public Codec::CodecData { public: - ImageData(): - height(0), width(0), depth(1), size(0), - num_mipmaps(0), flags(0), format(PF_UNKNOWN) - { - } + ImageData(): + height(0), width(0), depth(1), size(0), + num_mipmaps(0), flags(0), format(PF_UNKNOWN) + { + } uint32 height; uint32 width; - uint32 depth; + uint32 depth; size_t size; uint8 num_mipmaps; @@ -82,8 +82,8 @@ namespace Ogre { } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace #endif diff --git a/OgreMain/include/OgreInstanceBatch.h b/OgreMain/include/OgreInstanceBatch.h index f665169adba..c8884fe5c89 100644 --- a/OgreMain/include/OgreInstanceBatch.h +++ b/OgreMain/include/OgreInstanceBatch.h @@ -111,7 +111,7 @@ namespace Ogre ///@see InstanceManager::setNumCustomParams(). Because this may not even be used, ///our implementations keep the params separate from the InstancedEntity to lower ///the memory overhead. They default to Vector4::ZERO - CustomParamsVec mCustomParams; + CustomParamsVec mCustomParams; /// This bbox contains all (visible) instanced entities AxisAlignedBox mFullBoundingBox; @@ -249,7 +249,7 @@ namespace Ogre /** Fills the input vector with the instances that are currently being used or were requested. Used for defragmentation, @see InstanceManager::defragmentBatches */ - void getInstancedEntitiesInUse( InstancedEntityVec &outEntities, CustomParamsVec &outParams ); + void getInstancedEntitiesInUse( InstancedEntityVec &outEntities, CustomParamsVec &outParams ); /** @see InstanceManager::defragmentBatches This function takes InstancedEntities and pushes back all entities it can fit here @@ -259,104 +259,104 @@ namespace Ogre @param usedEntities Array of InstancedEntities to parent with this batch. Those reparented are removed from this input vector @param usedParams Array of Custom parameters correlated with the InstancedEntities in usedEntities. - They follow the fate of the entities in that vector. - @remarks: - This function assumes caller holds data to mInstancedEntities! Otherwise - you can get memory leaks. Don't call this directly if you don't know what you're doing! - */ - void _defragmentBatch( bool optimizeCulling, InstancedEntityVec &usedEntities, - CustomParamsVec &usedParams ); - - /** @see InstanceManager::_defragmentBatchDiscard - Destroys unused entities and clears the mInstancedEntity container which avoids leaving - dangling pointers from reparented InstancedEntities - Usually called before deleting this pointer. Don't call directly! - */ - void _defragmentBatchDiscard(void); - - /** Called by InstancedEntity(s) to tell us we need to update the bounds - (we touch the SceneNode so the SceneManager aknowledges such change) + They follow the fate of the entities in that vector. + @remarks: + This function assumes caller holds data to mInstancedEntities! Otherwise + you can get memory leaks. Don't call this directly if you don't know what you're doing! */ - virtual void _boundsDirty(void); - - /** Tells this batch to stop updating animations, positions, rotations, and display - all it's active instances. Currently only InstanceBatchHW & InstanceBatchHW_VTF support it. - This option makes the batch behave pretty much like Static Geometry, but with the GPU RAM - memory advantages (less VRAM, less bandwidth) and not LOD support. Very useful for - billboards of trees, repeating vegetation, etc. - @remarks - This function moves a lot of processing time from the CPU to the GPU. If the GPU - is already a bottleneck, you may see a decrease in performance instead! - Call this function again (with bStatic=true) if you've made a change to an - InstancedEntity and wish this change to take effect. - Be sure to call this after you've set all your instances - @see InstanceBatchHW::setStaticAndUpdate - */ - virtual void setStaticAndUpdate( bool bStatic ) {} - - /** Returns true if this batch was set as static. @see setStaticAndUpdate - */ - virtual bool isStatic() const { return false; } - - /** Returns a pointer to a new InstancedEntity ready to use - Note it's actually preallocated, so no memory allocation happens at - this point. - @remarks - Returns NULL if all instances are being used + void _defragmentBatch( bool optimizeCulling, InstancedEntityVec &usedEntities, + CustomParamsVec &usedParams ); + + /** @see InstanceManager::_defragmentBatchDiscard + Destroys unused entities and clears the mInstancedEntity container which avoids leaving + dangling pointers from reparented InstancedEntities + Usually called before deleting this pointer. Don't call directly! + */ + void _defragmentBatchDiscard(void); + + /** Called by InstancedEntity(s) to tell us we need to update the bounds + (we touch the SceneNode so the SceneManager aknowledges such change) + */ + virtual void _boundsDirty(void); + + /** Tells this batch to stop updating animations, positions, rotations, and display + all it's active instances. Currently only InstanceBatchHW & InstanceBatchHW_VTF support it. + This option makes the batch behave pretty much like Static Geometry, but with the GPU RAM + memory advantages (less VRAM, less bandwidth) and not LOD support. Very useful for + billboards of trees, repeating vegetation, etc. + @remarks + This function moves a lot of processing time from the CPU to the GPU. If the GPU + is already a bottleneck, you may see a decrease in performance instead! + Call this function again (with bStatic=true) if you've made a change to an + InstancedEntity and wish this change to take effect. + Be sure to call this after you've set all your instances + @see InstanceBatchHW::setStaticAndUpdate + */ + virtual void setStaticAndUpdate( bool bStatic ) {} + + /** Returns true if this batch was set as static. @see setStaticAndUpdate + */ + virtual bool isStatic() const { return false; } + + /** Returns a pointer to a new InstancedEntity ready to use + Note it's actually preallocated, so no memory allocation happens at + this point. + @remarks + Returns NULL if all instances are being used */ - InstancedEntity* createInstancedEntity(); + InstancedEntity* createInstancedEntity(); - /** Removes an InstancedEntity from the scene retrieved with - getNewInstancedEntity, putting back into a queue - @remarks - Throws an exception if the instanced entity wasn't created by this batch - Removed instanced entities save little CPU time, but _not_ GPU + /** Removes an InstancedEntity from the scene retrieved with + getNewInstancedEntity, putting back into a queue + @remarks + Throws an exception if the instanced entity wasn't created by this batch + Removed instanced entities save little CPU time, but _not_ GPU */ - void removeInstancedEntity( InstancedEntity *instancedEntity ); + void removeInstancedEntity( InstancedEntity *instancedEntity ); - /** Tells whether world bone matrices need to be calculated. - This does not include bone matrices which are calculated regardless + /** Tells whether world bone matrices need to be calculated. + This does not include bone matrices which are calculated regardless */ - virtual bool useBoneWorldMatrices() const { return true; } + virtual bool useBoneWorldMatrices() const { return true; } - /** Tells that the list of entity instances with shared transforms has changed */ - void _markTransformSharingDirty() { mTransformSharingDirty = true; } + /** Tells that the list of entity instances with shared transforms has changed */ + void _markTransformSharingDirty() { mTransformSharingDirty = true; } - /** @see InstancedEntity::setCustomParam */ - void _setCustomParam( InstancedEntity *instancedEntity, unsigned char idx, const Vector4 &newParam ); + /** @see InstancedEntity::setCustomParam */ + void _setCustomParam( InstancedEntity *instancedEntity, unsigned char idx, const Vector4 &newParam ); - /** @see InstancedEntity::getCustomParam */ - const Vector4& _getCustomParam( InstancedEntity *instancedEntity, unsigned char idx ); + /** @see InstancedEntity::getCustomParam */ + const Vector4& _getCustomParam( InstancedEntity *instancedEntity, unsigned char idx ); - //Renderable overloads + //Renderable overloads /** @copydoc Renderable::getMaterial. */ - const MaterialPtr& getMaterial(void) const { return mMaterial; } + const MaterialPtr& getMaterial(void) const { return mMaterial; } /** @copydoc Renderable::getRenderOperation. */ - void getRenderOperation( RenderOperation& op ) { op = mRenderOperation; } + void getRenderOperation( RenderOperation& op ) { op = mRenderOperation; } /** @copydoc Renderable::getSquaredViewDepth. */ - Real getSquaredViewDepth( const Camera* cam ) const; + Real getSquaredViewDepth( const Camera* cam ) const; /** @copydoc Renderable::getLights. */ const LightList& getLights( void ) const; /** @copydoc Renderable::getTechnique. */ - Technique* getTechnique(void) const; + Technique* getTechnique(void) const; /** @copydoc MovableObject::getMovableType. */ - const String& getMovableType(void) const; + const String& getMovableType(void) const; /** @copydoc MovableObject::_notifyCurrentCamera. */ - void _notifyCurrentCamera( Camera* cam ); + void _notifyCurrentCamera( Camera* cam ); /** @copydoc MovableObject::getBoundingBox. */ - const AxisAlignedBox& getBoundingBox(void) const; + const AxisAlignedBox& getBoundingBox(void) const; /** @copydoc MovableObject::getBoundingRadius. */ - Real getBoundingRadius(void) const; + Real getBoundingRadius(void) const; - virtual void _updateRenderQueue(RenderQueue* queue); - void visitRenderables( Renderable::Visitor* visitor, bool debugRenderables = false ); + virtual void _updateRenderQueue(RenderQueue* queue); + void visitRenderables( Renderable::Visitor* visitor, bool debugRenderables = false ); // resolve ambiguity of get/setUserAny due to inheriting from Renderable and MovableObject using Renderable::getUserAny; using Renderable::setUserAny; - }; + }; } // namespace Ogre #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreInstanceBatchHW.h b/OgreMain/include/OgreInstanceBatchHW.h index c317a720a6b..853b16d338c 100644 --- a/OgreMain/include/OgreInstanceBatchHW.h +++ b/OgreMain/include/OgreInstanceBatchHW.h @@ -32,79 +32,79 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - - /** This is technique requires true instancing hardware support. - Basically it creates a cloned vertex buffer from the original, with an extra buffer containing - 3 additional TEXCOORDS (12 bytes) repeated as much as the instance count. - That will be used for each instance data. - @par - The main advantage of this technique is that it's VERY fast; but it doesn't support - skeletal animation at all. Very reduced memory consumption and bandwidth. Great for particles, - debris, bricks, trees, sprites. - This batch is one of the few (if not the only) techniques that allows culling on an individual - basis. This means we can save vertex shader performance for instances that aren't in scene or - just not focused by the camera. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + + /** This is technique requires true instancing hardware support. + Basically it creates a cloned vertex buffer from the original, with an extra buffer containing + 3 additional TEXCOORDS (12 bytes) repeated as much as the instance count. + That will be used for each instance data. + @par + The main advantage of this technique is that it's VERY fast; but it doesn't support + skeletal animation at all. Very reduced memory consumption and bandwidth. Great for particles, + debris, bricks, trees, sprites. + This batch is one of the few (if not the only) techniques that allows culling on an individual + basis. This means we can save vertex shader performance for instances that aren't in scene or + just not focused by the camera. @remarks - Design discussion webpage: http://www.ogre3d.org/forums/viewtopic.php?f=4&t=59902 + Design discussion webpage: http://www.ogre3d.org/forums/viewtopic.php?f=4&t=59902 @author Matias N. Goldberg ("dark_sylinc") @version 1.1 */ - class _OgreExport InstanceBatchHW : public InstanceBatch - { - bool mKeepStatic; + class _OgreExport InstanceBatchHW : public InstanceBatch + { + bool mKeepStatic; - void setupVertices( const SubMesh* baseSubMesh ); - void setupIndices( const SubMesh* baseSubMesh ); + void setupVertices( const SubMesh* baseSubMesh ); + void setupIndices( const SubMesh* baseSubMesh ); - void removeBlendData(); - virtual bool checkSubMeshCompatibility( const SubMesh* baseSubMesh ); + void removeBlendData(); + virtual bool checkSubMeshCompatibility( const SubMesh* baseSubMesh ); - size_t updateVertexBuffer( Camera *currentCamera ); + size_t updateVertexBuffer( Camera *currentCamera ); - public: - InstanceBatchHW( InstanceManager *creator, MeshPtr &meshReference, const MaterialPtr &material, - size_t instancesPerBatch, const Mesh::IndexMap *indexToBoneMap, - const String &batchName ); - virtual ~InstanceBatchHW(); + public: + InstanceBatchHW( InstanceManager *creator, MeshPtr &meshReference, const MaterialPtr &material, + size_t instancesPerBatch, const Mesh::IndexMap *indexToBoneMap, + const String &batchName ); + virtual ~InstanceBatchHW(); - /** @see InstanceBatch::calculateMaxNumInstances */ - size_t calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const; + /** @see InstanceBatch::calculateMaxNumInstances */ + size_t calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const; - /** @see InstanceBatch::buildFrom */ - void buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ); + /** @see InstanceBatch::buildFrom */ + void buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ); - /** Overloaded so that we don't perform needless updates when in static mode. Also doing that - could cause glitches with shadow mapping (since Ogre thinks we're small/bigger than we - really are when displaying, or that we're somewhere else) + /** Overloaded so that we don't perform needless updates when in static mode. Also doing that + could cause glitches with shadow mapping (since Ogre thinks we're small/bigger than we + really are when displaying, or that we're somewhere else) */ - void _boundsDirty(void); + void _boundsDirty(void); - /** @see InstanceBatch::setStaticAndUpdate. While this flag is true, no individual per-entity - cull check is made. This means if the camera is looking at only one instance, all instances - are sent to the vertex shader (unlike when this flag is false). This saves a lot of CPU - power and a bit of bus bandwidth. - */ - void setStaticAndUpdate( bool bStatic ); + /** @see InstanceBatch::setStaticAndUpdate. While this flag is true, no individual per-entity + cull check is made. This means if the camera is looking at only one instance, all instances + are sent to the vertex shader (unlike when this flag is false). This saves a lot of CPU + power and a bit of bus bandwidth. + */ + void setStaticAndUpdate( bool bStatic ); - bool isStatic() const { return mKeepStatic; } + bool isStatic() const { return mKeepStatic; } - //Renderable overloads - void getWorldTransforms( Matrix4* xform ) const; - unsigned short getNumWorldTransforms(void) const; + //Renderable overloads + void getWorldTransforms( Matrix4* xform ) const; + unsigned short getNumWorldTransforms(void) const; - /** Overloaded to avoid updating skeletons (which we don't support), check visibility on a - per unit basis and finally updated the vertex buffer */ - virtual void _updateRenderQueue( RenderQueue* queue ); - }; + /** Overloaded to avoid updating skeletons (which we don't support), check visibility on a + per unit basis and finally updated the vertex buffer */ + virtual void _updateRenderQueue( RenderQueue* queue ); + }; } #endif diff --git a/OgreMain/include/OgreInstanceBatchHW_VTF.h b/OgreMain/include/OgreInstanceBatchHW_VTF.h index 7248a221b73..642b204de26 100644 --- a/OgreMain/include/OgreInstanceBatchHW_VTF.h +++ b/OgreMain/include/OgreInstanceBatchHW_VTF.h @@ -32,80 +32,80 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ - /** Instancing implementation using vertex texture through Vertex Texture Fetch (VTF) and - hardware instancing. - @see BaseInstanceBatchVTF and @see InstanceBatchHW + /** Instancing implementation using vertex texture through Vertex Texture Fetch (VTF) and + hardware instancing. + @see BaseInstanceBatchVTF and @see InstanceBatchHW - The advantage over TextureVTF technique, is that this implements a basic culling algorithm - to avoid useless processing in vertex shader and uses a lot less VRAM and memory bandwidth + The advantage over TextureVTF technique, is that this implements a basic culling algorithm + to avoid useless processing in vertex shader and uses a lot less VRAM and memory bandwidth - Basically it has the benefits of both TextureVTF (skeleton animations) and HWInstancingBasic - (lower memory consumption and basic culling) techniques + Basically it has the benefits of both TextureVTF (skeleton animations) and HWInstancingBasic + (lower memory consumption and basic culling) techniques @remarks - Design discussion webpage: http://www.ogre3d.org/forums/viewtopic.php?f=4&t=59902 + Design discussion webpage: http://www.ogre3d.org/forums/viewtopic.php?f=4&t=59902 @author Matias N. Goldberg ("dark_sylinc") @version 1.2 */ - class _OgreExport InstanceBatchHW_VTF : public BaseInstanceBatchVTF - { - protected: - bool mKeepStatic; + class _OgreExport InstanceBatchHW_VTF : public BaseInstanceBatchVTF + { + protected: + bool mKeepStatic; - //Pointer to the buffer containing the per instance vertex data - HardwareVertexBufferSharedPtr mInstanceVertexBuffer; + //Pointer to the buffer containing the per instance vertex data + HardwareVertexBufferSharedPtr mInstanceVertexBuffer; - void setupVertices( const SubMesh* baseSubMesh ); - void setupIndices( const SubMesh* baseSubMesh ); + void setupVertices( const SubMesh* baseSubMesh ); + void setupIndices( const SubMesh* baseSubMesh ); - /** Creates 2 TEXCOORD semantics that will be used to sample the vertex texture */ - void createVertexSemantics( VertexData *thisVertexData, VertexData *baseVertexData, - const HWBoneIdxVec &hwBoneIdx, const HWBoneWgtVec& hwBoneWgt ); + /** Creates 2 TEXCOORD semantics that will be used to sample the vertex texture */ + void createVertexSemantics( VertexData *thisVertexData, VertexData *baseVertexData, + const HWBoneIdxVec &hwBoneIdx, const HWBoneWgtVec& hwBoneWgt ); - /** updates the vertex buffer containing the per instance data - @param[in] isFirstTime Tells if this is the first time the buffer is being updated - @param[in] currentCamera The camera being used for render (valid when using bone matrix lookup) - @return The number of instances to be rendered - */ - virtual size_t updateInstanceDataBuffer(bool isFirstTime, Camera* currentCamera); + /** updates the vertex buffer containing the per instance data + @param[in] isFirstTime Tells if this is the first time the buffer is being updated + @param[in] currentCamera The camera being used for render (valid when using bone matrix lookup) + @return The number of instances to be rendered + */ + virtual size_t updateInstanceDataBuffer(bool isFirstTime, Camera* currentCamera); - virtual bool checkSubMeshCompatibility( const SubMesh* baseSubMesh ); + virtual bool checkSubMeshCompatibility( const SubMesh* baseSubMesh ); - /** Keeps filling the VTF with world matrix data. Overloaded to avoid culled objects - and update visible instances' animation - */ - size_t updateVertexTexture( Camera *currentCamera ); + /** Keeps filling the VTF with world matrix data. Overloaded to avoid culled objects + and update visible instances' animation + */ + size_t updateVertexTexture( Camera *currentCamera ); - virtual bool matricesTogetherPerRow() const { return true; } - public: - InstanceBatchHW_VTF( InstanceManager *creator, MeshPtr &meshReference, const MaterialPtr &material, - size_t instancesPerBatch, const Mesh::IndexMap *indexToBoneMap, - const String &batchName ); - virtual ~InstanceBatchHW_VTF(); - /** @see InstanceBatch::calculateMaxNumInstances */ - size_t calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const; + virtual bool matricesTogetherPerRow() const { return true; } + public: + InstanceBatchHW_VTF( InstanceManager *creator, MeshPtr &meshReference, const MaterialPtr &material, + size_t instancesPerBatch, const Mesh::IndexMap *indexToBoneMap, + const String &batchName ); + virtual ~InstanceBatchHW_VTF(); + /** @see InstanceBatch::calculateMaxNumInstances */ + size_t calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const; - /** @copydoc InstanceBatchHW::_boundsDirty */ - void _boundsDirty(void); + /** @copydoc InstanceBatchHW::_boundsDirty */ + void _boundsDirty(void); - /** @copydoc InstanceBatchHW::setStaticAndUpdate */ - void setStaticAndUpdate( bool bStatic ); + /** @copydoc InstanceBatchHW::setStaticAndUpdate */ + void setStaticAndUpdate( bool bStatic ); - bool isStatic() const { return mKeepStatic; } + bool isStatic() const { return mKeepStatic; } - /** Overloaded to visibility on a per unit basis and finally updated the vertex texture */ - virtual void _updateRenderQueue( RenderQueue* queue ); - }; + /** Overloaded to visibility on a per unit basis and finally updated the vertex texture */ + virtual void _updateRenderQueue( RenderQueue* queue ); + }; } diff --git a/OgreMain/include/OgreInstanceBatchShader.h b/OgreMain/include/OgreInstanceBatchShader.h index 356f8ea2742..8ef2bed322d 100644 --- a/OgreMain/include/OgreInstanceBatchShader.h +++ b/OgreMain/include/OgreInstanceBatchShader.h @@ -32,68 +32,68 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ - /** This is the same technique the old "InstancedGeometry" implementation used (with improvements). - Basically it creates a large vertex buffer with many repeating entities, and sends per instance - data through shader constants. Because SM 2.0 & 3.0 have up to 256 shader constant registers, - this means there can be approx up to 84 instances per batch, assuming they're not skinned - But using shader constants for other stuff (i.e. lighting) also affects negatively this number - A mesh with skeletally animated 2 bones reduces the number 84 to 42 instances per batch. - @par - The main advantage of this technique is that it's supported on a high variety of hardware - (SM 2.0 cards are required) and the same shader can be used for both skeletally animated - normal entities and instanced entities without a single change required. - @par - Unlike the old InstancedGeometry implementation, the developer doesn't need to worry about - reaching the 84 instances limit, the InstanceManager automatically takes care of splitting - and creating new batches. But beware internally, this means less performance improvement. - Another improvement is that vertex buffers are shared between batches, which significantly - reduces GPU VRAM usage. + /** This is the same technique the old "InstancedGeometry" implementation used (with improvements). + Basically it creates a large vertex buffer with many repeating entities, and sends per instance + data through shader constants. Because SM 2.0 & 3.0 have up to 256 shader constant registers, + this means there can be approx up to 84 instances per batch, assuming they're not skinned + But using shader constants for other stuff (i.e. lighting) also affects negatively this number + A mesh with skeletally animated 2 bones reduces the number 84 to 42 instances per batch. + @par + The main advantage of this technique is that it's supported on a high variety of hardware + (SM 2.0 cards are required) and the same shader can be used for both skeletally animated + normal entities and instanced entities without a single change required. + @par + Unlike the old InstancedGeometry implementation, the developer doesn't need to worry about + reaching the 84 instances limit, the InstanceManager automatically takes care of splitting + and creating new batches. But beware internally, this means less performance improvement. + Another improvement is that vertex buffers are shared between batches, which significantly + reduces GPU VRAM usage. @remarks - Design discussion webpage: http://www.ogre3d.org/forums/viewtopic.php?f=4&t=59902 + Design discussion webpage: http://www.ogre3d.org/forums/viewtopic.php?f=4&t=59902 @author Matias N. Goldberg ("dark_sylinc") @version 1.0 */ - class _OgreExport InstanceBatchShader : public InstanceBatch - { - unsigned short mNumWorldMatrices; + class _OgreExport InstanceBatchShader : public InstanceBatch + { + unsigned short mNumWorldMatrices; - void setupVertices( const SubMesh* baseSubMesh ); - void setupIndices( const SubMesh* baseSubMesh ); + void setupVertices( const SubMesh* baseSubMesh ); + void setupIndices( const SubMesh* baseSubMesh ); - /** When the mesh is (hardware) skinned, a different code path is called so that - we reuse the index buffers and modify them in place. For example Instance #2 - with reference to bone #5 would have BlendIndex = 2 + 5 = 7 - Everything is copied identically except the VES_BLEND_INDICES semantic - */ - void setupHardwareSkinned( const SubMesh* baseSubMesh, VertexData *thisVertexData, - VertexData *baseVertexData ); + /** When the mesh is (hardware) skinned, a different code path is called so that + we reuse the index buffers and modify them in place. For example Instance #2 + with reference to bone #5 would have BlendIndex = 2 + 5 = 7 + Everything is copied identically except the VES_BLEND_INDICES semantic + */ + void setupHardwareSkinned( const SubMesh* baseSubMesh, VertexData *thisVertexData, + VertexData *baseVertexData ); - public: - InstanceBatchShader( InstanceManager *creator, MeshPtr &meshReference, const MaterialPtr &material, - size_t instancesPerBatch, const Mesh::IndexMap *indexToBoneMap, - const String &batchName ); - virtual ~InstanceBatchShader(); + public: + InstanceBatchShader( InstanceManager *creator, MeshPtr &meshReference, const MaterialPtr &material, + size_t instancesPerBatch, const Mesh::IndexMap *indexToBoneMap, + const String &batchName ); + virtual ~InstanceBatchShader(); - /** @see InstanceBatch::calculateMaxNumInstances */ - size_t calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const; + /** @see InstanceBatch::calculateMaxNumInstances */ + size_t calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const; - /** @see InstanceBatch::buildFrom */ - void buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ); + /** @see InstanceBatch::buildFrom */ + void buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ); - //Renderable overloads - void getWorldTransforms( Matrix4* xform ) const; - unsigned short getNumWorldTransforms(void) const; - }; + //Renderable overloads + void getWorldTransforms( Matrix4* xform ) const; + unsigned short getNumWorldTransforms(void) const; + }; } #endif diff --git a/OgreMain/include/OgreInstanceBatchVTF.h b/OgreMain/include/OgreInstanceBatchVTF.h index 7970d3b3afc..a259cdc62f5 100644 --- a/OgreMain/include/OgreInstanceBatchVTF.h +++ b/OgreMain/include/OgreInstanceBatchVTF.h @@ -33,194 +33,194 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - - /** Instancing implementation using vertex texture through Vertex Texture Fetch (VTF) - This implementation has the following advantages: - * Supports huge amount of instances per batch - * Supports skinning even with huge ammounts of instances per batch - * Doesn't need shader constants registers. - * Best suited for skinned entities - - But beware the disadvantages: - * VTF is only fast on modern GPUs (ATI Radeon HD 2000+, GeForce 8+ series onwards) - * On GeForce 6/7 series VTF is too slow - * VTF isn't (controversely) supported on old ATI X1800 hardware - * Only one bone weight per vertex is supported - * GPUs with low memory bandwidth (i.e. laptops and integrated GPUs) - may perform even worse than no instancing - - Whether this performs great or bad depends on the hardware. It improved up to 4x performance on - a Intel Core 2 Quad Core X9650 GeForce 8600 GTS, and in an Intel Core 2 Duo P7350 ATI - Mobility Radeon HD 4650, but went 0.75x slower on an AthlonX2 5000+ integrated nForce 6150 SE - Each BaseInstanceBatchVTF has it's own texture, which occupies memory in VRAM. - Approx VRAM usage can be computed by doing 12 bytes * 3 * numInstances * numBones - Use flag IM_VTFBESTFIT to avoid wasting VRAM (but may reduce amount of instances per batch). - @par - The material requires at least a texture unit stage named "InstancingVTF" + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + + /** Instancing implementation using vertex texture through Vertex Texture Fetch (VTF) + This implementation has the following advantages: + * Supports huge amount of instances per batch + * Supports skinning even with huge ammounts of instances per batch + * Doesn't need shader constants registers. + * Best suited for skinned entities + + But beware the disadvantages: + * VTF is only fast on modern GPUs (ATI Radeon HD 2000+, GeForce 8+ series onwards) + * On GeForce 6/7 series VTF is too slow + * VTF isn't (controversely) supported on old ATI X1800 hardware + * Only one bone weight per vertex is supported + * GPUs with low memory bandwidth (i.e. laptops and integrated GPUs) + may perform even worse than no instancing + + Whether this performs great or bad depends on the hardware. It improved up to 4x performance on + a Intel Core 2 Quad Core X9650 GeForce 8600 GTS, and in an Intel Core 2 Duo P7350 ATI + Mobility Radeon HD 4650, but went 0.75x slower on an AthlonX2 5000+ integrated nForce 6150 SE + Each BaseInstanceBatchVTF has it's own texture, which occupies memory in VRAM. + Approx VRAM usage can be computed by doing 12 bytes * 3 * numInstances * numBones + Use flag IM_VTFBESTFIT to avoid wasting VRAM (but may reduce amount of instances per batch). + @par + The material requires at least a texture unit stage named "InstancingVTF" @remarks - Design discussion webpage: http://www.ogre3d.org/forums/viewtopic.php?f=4&t=59902 + Design discussion webpage: http://www.ogre3d.org/forums/viewtopic.php?f=4&t=59902 @author Matias N. Goldberg ("dark_sylinc") @version 1.0 */ - class _OgreExport BaseInstanceBatchVTF : public InstanceBatch - { - protected: - typedef vector::type HWBoneIdxVec; - typedef vector::type HWBoneWgtVec; - typedef vector::type Matrix4Vec; - - size_t mMatricesPerInstance; //number of bone matrices per instance - size_t mNumWorldMatrices; //Num bones * num instances - TexturePtr mMatrixTexture; //The VTF - - //Used when all matrices from each instance must be in the same row (i.e. HW Instancing). - //A few pixels are wasted, but resizing the texture puts the danger of not sampling the - //right pixel... (in theory it should work, but in practice doesn't) - size_t mWidthFloatsPadding; - size_t mMaxFloatsPerLine; - - size_t mRowLength; - size_t mWeightCount; - //Temporary array used to store 3x4 matrices before they are converted to dual quaternions - float* mTempTransformsArray3x4; - - // The state of the usage of bone matrix lookup - bool mUseBoneMatrixLookup; - size_t mMaxLookupTableInstances; - - bool mUseBoneDualQuaternions; - bool mForceOneWeight; - bool mUseOneWeight; - - /** Clones the base material so it can have it's own vertex texture, and also - clones it's shadow caster materials, if it has any - */ - void cloneMaterial( const MaterialPtr &material ); - - /** Retrieves bone data from the original sub mesh and puts it into an appropriate buffer, - later to be read when creating the vertex semantics. - Assumes outBoneIdx has enough space (base submesh vertex count) - */ - void retrieveBoneIdx( VertexData *baseVertexData, HWBoneIdxVec &outBoneIdx ); - - /** @see retrieveBoneIdx() - Assumes outBoneIdx has enough space (twice the base submesh vertex count, one for each weight) - Assumes outBoneWgt has enough space (twice the base submesh vertex count, one for each weight) - */ - void retrieveBoneIdxWithWeights(VertexData *baseVertexData, HWBoneIdxVec &outBoneIdx, HWBoneWgtVec &outBoneWgt); - - /** Setups the material to use a vertex texture */ - void setupMaterialToUseVTF( TextureType textureType, MaterialPtr &material ); - - /** Creates the vertex texture */ - void createVertexTexture( const SubMesh* baseSubMesh ); - - /** Creates 2 TEXCOORD semantics that will be used to sample the vertex texture */ - virtual void createVertexSemantics( VertexData *thisVertexData, VertexData *baseVertexData, - const HWBoneIdxVec &hwBoneIdx, const HWBoneWgtVec &hwBoneWgt) = 0; - - size_t convert3x4MatricesToDualQuaternions(float* matrices, size_t numOfMatrices, float* outDualQuaternions); - - /** Keeps filling the VTF with world matrix data */ - void updateVertexTexture(void); - - /** Affects VTF texture's width dimension */ - virtual bool matricesTogetherPerRow() const = 0; - - /** update the lookup numbers for entities with shared transforms */ - virtual void updateSharedLookupIndexes(); - - /** @see InstanceBatch::generateInstancedEntity() */ - virtual InstancedEntity* generateInstancedEntity(size_t num); - - public: - BaseInstanceBatchVTF( InstanceManager *creator, MeshPtr &meshReference, const MaterialPtr &material, - size_t instancesPerBatch, const Mesh::IndexMap *indexToBoneMap, - const String &batchName); - virtual ~BaseInstanceBatchVTF(); - - /** @see InstanceBatch::buildFrom */ - void buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ); - - //Renderable overloads - void getWorldTransforms( Matrix4* xform ) const; - unsigned short getNumWorldTransforms(void) const; - - /** Overloaded to be able to updated the vertex texture */ - void _updateRenderQueue(RenderQueue* queue); - - /** Sets the state of the usage of bone matrix lookup - - Under default condition each instance entity is assigned a specific area in the vertex - texture for bone matrix data. When turned on the amount of area in the vertex texture - assigned for bone matrix data will be relative to the amount of unique animation states. - Instanced entities sharing the same animation state will share the same area in the matrix. - The specific position of each entity is placed in the vertex data and added in a second phase - in the shader. - - Note this feature only works in VTF_HW for now. - This value needs to be set before adding any instanced entities - */ - void setBoneMatrixLookup(bool enable, size_t maxLookupTableInstances) { assert(mInstancedEntities.empty()); - mUseBoneMatrixLookup = enable; mMaxLookupTableInstances = maxLookupTableInstances; } - - /** Tells whether to use bone matrix lookup - @see setBoneMatrixLookup() - */ - bool useBoneMatrixLookup() const { return mUseBoneMatrixLookup; } - - void setBoneDualQuaternions(bool enable) { assert(mInstancedEntities.empty()); - mUseBoneDualQuaternions = enable; mRowLength = (mUseBoneDualQuaternions ? 2 : 3); } - - bool useBoneDualQuaternions() const { return mUseBoneDualQuaternions; } - - void setForceOneWeight(bool enable) { assert(mInstancedEntities.empty()); - mForceOneWeight = enable; } - - bool forceOneWeight() const { return mForceOneWeight; } - - void setUseOneWeight(bool enable) { assert(mInstancedEntities.empty()); - mUseOneWeight = enable; } - - bool useOneWeight() const { return mUseOneWeight; } - - /** @see InstanceBatch::useBoneWorldMatrices() */ - virtual bool useBoneWorldMatrices() const { return !mUseBoneMatrixLookup; } - - /** @return the maximum amount of shared transform entities when using lookup table*/ - virtual size_t getMaxLookupTableInstances() const { return mMaxLookupTableInstances; } - - }; - - class _OgreExport InstanceBatchVTF : public BaseInstanceBatchVTF - { - - void setupVertices( const SubMesh* baseSubMesh ); - void setupIndices( const SubMesh* baseSubMesh ); - - /** Creates 2 TEXCOORD semantics that will be used to sample the vertex texture */ - void createVertexSemantics( VertexData *thisVertexData, VertexData *baseVertexData, - const HWBoneIdxVec &hwBoneIdx, const HWBoneWgtVec &hwBoneWgt ); + class _OgreExport BaseInstanceBatchVTF : public InstanceBatch + { + protected: + typedef vector::type HWBoneIdxVec; + typedef vector::type HWBoneWgtVec; + typedef vector::type Matrix4Vec; + + size_t mMatricesPerInstance; //number of bone matrices per instance + size_t mNumWorldMatrices; //Num bones * num instances + TexturePtr mMatrixTexture; //The VTF + + //Used when all matrices from each instance must be in the same row (i.e. HW Instancing). + //A few pixels are wasted, but resizing the texture puts the danger of not sampling the + //right pixel... (in theory it should work, but in practice doesn't) + size_t mWidthFloatsPadding; + size_t mMaxFloatsPerLine; + + size_t mRowLength; + size_t mWeightCount; + //Temporary array used to store 3x4 matrices before they are converted to dual quaternions + float* mTempTransformsArray3x4; + + // The state of the usage of bone matrix lookup + bool mUseBoneMatrixLookup; + size_t mMaxLookupTableInstances; + + bool mUseBoneDualQuaternions; + bool mForceOneWeight; + bool mUseOneWeight; + + /** Clones the base material so it can have it's own vertex texture, and also + clones it's shadow caster materials, if it has any + */ + void cloneMaterial( const MaterialPtr &material ); + + /** Retrieves bone data from the original sub mesh and puts it into an appropriate buffer, + later to be read when creating the vertex semantics. + Assumes outBoneIdx has enough space (base submesh vertex count) + */ + void retrieveBoneIdx( VertexData *baseVertexData, HWBoneIdxVec &outBoneIdx ); + + /** @see retrieveBoneIdx() + Assumes outBoneIdx has enough space (twice the base submesh vertex count, one for each weight) + Assumes outBoneWgt has enough space (twice the base submesh vertex count, one for each weight) + */ + void retrieveBoneIdxWithWeights(VertexData *baseVertexData, HWBoneIdxVec &outBoneIdx, HWBoneWgtVec &outBoneWgt); + + /** Setups the material to use a vertex texture */ + void setupMaterialToUseVTF( TextureType textureType, MaterialPtr &material ); + + /** Creates the vertex texture */ + void createVertexTexture( const SubMesh* baseSubMesh ); + + /** Creates 2 TEXCOORD semantics that will be used to sample the vertex texture */ + virtual void createVertexSemantics( VertexData *thisVertexData, VertexData *baseVertexData, + const HWBoneIdxVec &hwBoneIdx, const HWBoneWgtVec &hwBoneWgt) = 0; + + size_t convert3x4MatricesToDualQuaternions(float* matrices, size_t numOfMatrices, float* outDualQuaternions); + + /** Keeps filling the VTF with world matrix data */ + void updateVertexTexture(void); + + /** Affects VTF texture's width dimension */ + virtual bool matricesTogetherPerRow() const = 0; + + /** update the lookup numbers for entities with shared transforms */ + virtual void updateSharedLookupIndexes(); + + /** @see InstanceBatch::generateInstancedEntity() */ + virtual InstancedEntity* generateInstancedEntity(size_t num); + + public: + BaseInstanceBatchVTF( InstanceManager *creator, MeshPtr &meshReference, const MaterialPtr &material, + size_t instancesPerBatch, const Mesh::IndexMap *indexToBoneMap, + const String &batchName); + virtual ~BaseInstanceBatchVTF(); + + /** @see InstanceBatch::buildFrom */ + void buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ); + + //Renderable overloads + void getWorldTransforms( Matrix4* xform ) const; + unsigned short getNumWorldTransforms(void) const; + + /** Overloaded to be able to updated the vertex texture */ + void _updateRenderQueue(RenderQueue* queue); + + /** Sets the state of the usage of bone matrix lookup + + Under default condition each instance entity is assigned a specific area in the vertex + texture for bone matrix data. When turned on the amount of area in the vertex texture + assigned for bone matrix data will be relative to the amount of unique animation states. + Instanced entities sharing the same animation state will share the same area in the matrix. + The specific position of each entity is placed in the vertex data and added in a second phase + in the shader. + + Note this feature only works in VTF_HW for now. + This value needs to be set before adding any instanced entities + */ + void setBoneMatrixLookup(bool enable, size_t maxLookupTableInstances) { assert(mInstancedEntities.empty()); + mUseBoneMatrixLookup = enable; mMaxLookupTableInstances = maxLookupTableInstances; } + + /** Tells whether to use bone matrix lookup + @see setBoneMatrixLookup() + */ + bool useBoneMatrixLookup() const { return mUseBoneMatrixLookup; } + + void setBoneDualQuaternions(bool enable) { assert(mInstancedEntities.empty()); + mUseBoneDualQuaternions = enable; mRowLength = (mUseBoneDualQuaternions ? 2 : 3); } + + bool useBoneDualQuaternions() const { return mUseBoneDualQuaternions; } + + void setForceOneWeight(bool enable) { assert(mInstancedEntities.empty()); + mForceOneWeight = enable; } + + bool forceOneWeight() const { return mForceOneWeight; } + + void setUseOneWeight(bool enable) { assert(mInstancedEntities.empty()); + mUseOneWeight = enable; } + + bool useOneWeight() const { return mUseOneWeight; } + + /** @see InstanceBatch::useBoneWorldMatrices() */ + virtual bool useBoneWorldMatrices() const { return !mUseBoneMatrixLookup; } + + /** @return the maximum amount of shared transform entities when using lookup table*/ + virtual size_t getMaxLookupTableInstances() const { return mMaxLookupTableInstances; } + + }; + + class _OgreExport InstanceBatchVTF : public BaseInstanceBatchVTF + { + + void setupVertices( const SubMesh* baseSubMesh ); + void setupIndices( const SubMesh* baseSubMesh ); + + /** Creates 2 TEXCOORD semantics that will be used to sample the vertex texture */ + void createVertexSemantics( VertexData *thisVertexData, VertexData *baseVertexData, + const HWBoneIdxVec &hwBoneIdx, const HWBoneWgtVec &hwBoneWgt ); - virtual bool matricesTogetherPerRow() const { return false; } - public: - InstanceBatchVTF( InstanceManager *creator, MeshPtr &meshReference, const MaterialPtr &material, - size_t instancesPerBatch, const Mesh::IndexMap *indexToBoneMap, - const String &batchName); - virtual ~InstanceBatchVTF(); + virtual bool matricesTogetherPerRow() const { return false; } + public: + InstanceBatchVTF( InstanceManager *creator, MeshPtr &meshReference, const MaterialPtr &material, + size_t instancesPerBatch, const Mesh::IndexMap *indexToBoneMap, + const String &batchName); + virtual ~InstanceBatchVTF(); - /** @see InstanceBatch::calculateMaxNumInstances */ - size_t calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const; - }; + /** @see InstanceBatch::calculateMaxNumInstances */ + size_t calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const; + }; } #endif diff --git a/OgreMain/include/OgreInstanceManager.h b/OgreMain/include/OgreInstanceManager.h index fa7bf9881b4..7e8f19135f9 100644 --- a/OgreMain/include/OgreInstanceManager.h +++ b/OgreMain/include/OgreInstanceManager.h @@ -118,7 +118,7 @@ namespace Ogre SceneManager* mSceneManager; size_t mMaxLookupTableInstances; - unsigned char mNumCustomParams; //Number of custom params per instance. + unsigned char mNumCustomParams; //Number of custom params per instance. /** Finds a batch with at least one free instanced entity we can use. If none found, creates one. @@ -139,18 +139,18 @@ namespace Ogre /** @see defragmentBatches overload, this takes care of an array of batches for a specific material */ void defragmentBatches( bool optimizeCull, vector::type &entities, - vector::type &usedParams, - InstanceBatchVec &fragmentedBatches ); + vector::type &usedParams, + InstanceBatchVec &fragmentedBatches ); /** @see setSetting. This function helps it by setting the given parameter to all batches in container. */ void applySettingToBatches( BatchSettingId id, bool value, const InstanceBatchVec &container ); - /** Called when we you use a mesh which has shared vertices, the function creates separate - vertex/index buffers and also recreates the bone assignments. - */ - void unshareVertices(const Ogre::MeshPtr &mesh); + /** Called when we you use a mesh which has shared vertices, the function creates separate + vertex/index buffers and also recreates the bone assignments. + */ + void unshareVertices(const Ogre::MeshPtr &mesh); public: InstanceManager( const String &customName, SceneManager *sceneManager, @@ -180,28 +180,28 @@ namespace Ogre */ void setMaxLookupTableInstances( size_t maxLookupTableInstances ); - /** Sets the number of custom parameters per instance. Some techniques (i.e. HWInstancingBasic) - support this, but not all of them. They also may have limitations to the max number. All - instancing implementations assume each instance param is a Vector4 (4 floats). - @remarks - This function cannot be called after the first batch has been created. Otherwise - it will raise an exception. If the technique doesn't support custom params, it will - raise an exception at the time of building the first InstanceBatch. - - HWInstancingBasic: - * Each custom params adds an additional float4 TEXCOORD. - HWInstancingVTF: - * Not implemented. (Recommendation: Implement this as an additional float4 VTF fetch) - TextureVTF: - * Not implemented. (see HWInstancingVTF's recommendation) - ShaderBased: - * Not supported. - @param numCustomParams Number of custom parameters each instance will have. Default: 0 - */ - void setNumCustomParams( unsigned char numCustomParams ); - - unsigned char getNumCustomParams() const - { return mNumCustomParams; } + /** Sets the number of custom parameters per instance. Some techniques (i.e. HWInstancingBasic) + support this, but not all of them. They also may have limitations to the max number. All + instancing implementations assume each instance param is a Vector4 (4 floats). + @remarks + This function cannot be called after the first batch has been created. Otherwise + it will raise an exception. If the technique doesn't support custom params, it will + raise an exception at the time of building the first InstanceBatch. + + HWInstancingBasic: + * Each custom params adds an additional float4 TEXCOORD. + HWInstancingVTF: + * Not implemented. (Recommendation: Implement this as an additional float4 VTF fetch) + TextureVTF: + * Not implemented. (see HWInstancingVTF's recommendation) + ShaderBased: + * Not supported. + @param numCustomParams Number of custom parameters each instance will have. Default: 0 + */ + void setNumCustomParams( unsigned char numCustomParams ); + + unsigned char getNumCustomParams() const + { return mNumCustomParams; } /** @return Instancing technique this manager was created for. Can't be changed after creation */ InstancingTechnique getInstancingTechnique() const diff --git a/OgreMain/include/OgreInstancedEntity.h b/OgreMain/include/OgreInstancedEntity.h index a33d57e483e..2cf3e0df5d1 100644 --- a/OgreMain/include/OgreInstancedEntity.h +++ b/OgreMain/include/OgreInstancedEntity.h @@ -34,260 +34,260 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - - /** @see InstanceBatch to understand how instancing works. - - Instanced entities work in a very similar way as how an Entity works, as this interface - tries to mimic it as most as possible to make the transition between Entity and InstancedEntity - as straightforward and simple as possible. - There are a couple inherent limitations, for example setRenderQueueGroup only works on - the InstanceBatch level, not the individual instance. This limits Z sorting for alpha blending - quite significantly - An InstancedEntity won't appear in scene until a SceneNode is attached to them. Once the - InstancedEntity is no longer needed, call InstanceBatch::removeInstancedEntity to put them - back into a queue so the batch can return it back again when a new instance is requested. - @par - Internally, instanced entities that are not visible (i.e. by setting setVisible(false) or - when they don't have a SceneNode attached to them) a Zero world matrix is sent to the vertex shader - which in turn causes a zero area triangle. - This obviously means no Vertex shader benefit, but saves a bit of pixel shader processing power. - Also this means this object won't be considered when sizing the InstanceBatch's bounding box. - @par - Each instance has an instance ID unique within the batch, which matches the ID sent to the vertex - shader by some techniques (like InstanceBatchShader). - @par - Differences between Entity and InstancedEntity: - * Setting RenderQueueGroup and other Renderable stuff works at InstanceBatch level, not - InstancedEntity. This is obviously a limitation from instancing in general, not this particular - implementation + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + + /** @see InstanceBatch to understand how instancing works. + + Instanced entities work in a very similar way as how an Entity works, as this interface + tries to mimic it as most as possible to make the transition between Entity and InstancedEntity + as straightforward and simple as possible. + There are a couple inherent limitations, for example setRenderQueueGroup only works on + the InstanceBatch level, not the individual instance. This limits Z sorting for alpha blending + quite significantly + An InstancedEntity won't appear in scene until a SceneNode is attached to them. Once the + InstancedEntity is no longer needed, call InstanceBatch::removeInstancedEntity to put them + back into a queue so the batch can return it back again when a new instance is requested. + @par + Internally, instanced entities that are not visible (i.e. by setting setVisible(false) or + when they don't have a SceneNode attached to them) a Zero world matrix is sent to the vertex shader + which in turn causes a zero area triangle. + This obviously means no Vertex shader benefit, but saves a bit of pixel shader processing power. + Also this means this object won't be considered when sizing the InstanceBatch's bounding box. + @par + Each instance has an instance ID unique within the batch, which matches the ID sent to the vertex + shader by some techniques (like InstanceBatchShader). + @par + Differences between Entity and InstancedEntity: + * Setting RenderQueueGroup and other Renderable stuff works at InstanceBatch level, not + InstancedEntity. This is obviously a limitation from instancing in general, not this particular + implementation @remarks - Design discussion webpage + Design discussion webpage @author Matias N. Goldberg ("dark_sylinc") @version 1.0 */ - class _OgreExport InstancedEntity : public Ogre::MovableObject - { - friend class InstanceBatch; - friend class InstanceBatchShader; - friend class InstanceBatchHW; - friend class InstanceBatchHW_VTF; - friend class BaseInstanceBatchVTF; - protected: - uint16 mInstanceId; //Note it may change after defragmenting! - bool mInUse; - InstanceBatch *mBatchOwner; - - AnimationStateSet *mAnimationState; - SkeletonInstance *mSkeletonInstance; - Matrix4 *mBoneMatrices; //Local space - Matrix4 *mBoneWorldMatrices; //World space - unsigned long mFrameAnimationLastUpdated; - - InstancedEntity* mSharedTransformEntity; //When not null, another InstancedEntity controls the skeleton - - /** Used in conjunction with bone matrix lookup. Tells the number of the transform for + class _OgreExport InstancedEntity : public Ogre::MovableObject + { + friend class InstanceBatch; + friend class InstanceBatchShader; + friend class InstanceBatchHW; + friend class InstanceBatchHW_VTF; + friend class BaseInstanceBatchVTF; + protected: + uint16 mInstanceId; //Note it may change after defragmenting! + bool mInUse; + InstanceBatch *mBatchOwner; + + AnimationStateSet *mAnimationState; + SkeletonInstance *mSkeletonInstance; + Matrix4 *mBoneMatrices; //Local space + Matrix4 *mBoneWorldMatrices; //World space + unsigned long mFrameAnimationLastUpdated; + + InstancedEntity* mSharedTransformEntity; //When not null, another InstancedEntity controls the skeleton + + /** Used in conjunction with bone matrix lookup. Tells the number of the transform for as arranged in the vertex texture */ - uint16 mTransformLookupNumber; - - /// Stores the master when we're the slave, store our slaves when we're the master - typedef vector::type InstancedEntityVec; - InstancedEntityVec mSharingPartners; - - ////////////////////////////////////////////////////////////////////////// - // Parameters used for local transformation offset information - // The - ////////////////////////////////////////////////////////////////////////// - - /// Object position - Vector3 mPosition; - Vector3 mDerivedLocalPosition; - /// Object orientation - Quaternion mOrientation; - /// Object scale - Vector3 mScale; - /// The maximum absolute scale for all dimension - Real mMaxScaleLocal; - /// Full world transform - Matrix4 mFullLocalTransform; - /// Tells if mFullTransform needs an updated - bool mNeedTransformUpdate; - /// Tells if the animation world transform needs an update - bool mNeedAnimTransformUpdate; - /// Tells whether to use the local transform parameters - bool mUseLocalTransform; - - - /// Returns number of matrices written to transform, assumes transform has enough space - size_t getTransforms( Matrix4 *xform ) const; - /// Returns number of 32-bit values written - size_t getTransforms3x4( float *xform ) const; - - /// Returns true if this InstancedObject is visible to the current camera - bool findVisible( Camera *camera ) const; - - /// Creates/destroys our own skeleton, also tells slaves to unlink if we're destroying - void createSkeletonInstance(); - void destroySkeletonInstance(); - - /// When this entity is a slave, stopSharingTransform delegates to this function. - /// nofityMaster = false is used to prevent iterator invalidation in specific cases. - void stopSharingTransformAsSlave( bool notifyMaster ); - - /// Just unlinks, and tells our master we're no longer sharing - void unlinkTransform( bool notifyMaster=true ); - - /// Called when a slave has unlinked from us - void notifyUnlink( const InstancedEntity *slave ); - - /// Mark the transformation matrixes as dirty - inline void markTransformDirty(); - - /// Incremented count for next name extension + uint16 mTransformLookupNumber; + + /// Stores the master when we're the slave, store our slaves when we're the master + typedef vector::type InstancedEntityVec; + InstancedEntityVec mSharingPartners; + + ////////////////////////////////////////////////////////////////////////// + // Parameters used for local transformation offset information + // The + ////////////////////////////////////////////////////////////////////////// + + /// Object position + Vector3 mPosition; + Vector3 mDerivedLocalPosition; + /// Object orientation + Quaternion mOrientation; + /// Object scale + Vector3 mScale; + /// The maximum absolute scale for all dimension + Real mMaxScaleLocal; + /// Full world transform + Matrix4 mFullLocalTransform; + /// Tells if mFullTransform needs an updated + bool mNeedTransformUpdate; + /// Tells if the animation world transform needs an update + bool mNeedAnimTransformUpdate; + /// Tells whether to use the local transform parameters + bool mUseLocalTransform; + + + /// Returns number of matrices written to transform, assumes transform has enough space + size_t getTransforms( Matrix4 *xform ) const; + /// Returns number of 32-bit values written + size_t getTransforms3x4( float *xform ) const; + + /// Returns true if this InstancedObject is visible to the current camera + bool findVisible( Camera *camera ) const; + + /// Creates/destroys our own skeleton, also tells slaves to unlink if we're destroying + void createSkeletonInstance(); + void destroySkeletonInstance(); + + /// When this entity is a slave, stopSharingTransform delegates to this function. + /// nofityMaster = false is used to prevent iterator invalidation in specific cases. + void stopSharingTransformAsSlave( bool notifyMaster ); + + /// Just unlinks, and tells our master we're no longer sharing + void unlinkTransform( bool notifyMaster=true ); + + /// Called when a slave has unlinked from us + void notifyUnlink( const InstancedEntity *slave ); + + /// Mark the transformation matrixes as dirty + inline void markTransformDirty(); + + /// Incremented count for next name extension static NameGenerator msNameGenerator; - public: - InstancedEntity( InstanceBatch *batchOwner, uint32 instanceID, InstancedEntity* sharedTransformEntity = NULL); - virtual ~InstancedEntity(); - - /** Shares the entire transformation with another InstancedEntity. This is useful when a mesh - has more than one submeshes, therefore creating multiple InstanceManagers (one for each - submesh). With this function, sharing makes the skeleton to be shared (less memory) and - updated once (performance optimization). - Note that one InstancedEntity (i.e. submesh 0) must be chosen as "master" which will share - with the other instanced entities (i.e. submeshes 1-N) which are called "slaves" - @par - Requirements to share trasnformations: - * Both InstancedEntities must have use the same skeleton - * An InstancedEntity can't be both "master" and "slave" at the same time - @remarks - Sharing does nothing if the original mesh doesn't have a skeleton - When an InstancedEntity is removed (@see InstanceBatch::removeInstancedEntity), it stops - sharing the transform. If the instanced entity was the master one, all it's slaves stop - sharing and start having their own transform too. - @param slave The InstancedEntity that should share with us and become our slave - @return true if successfully shared (may fail if they aren't skeletally animated) - */ - bool shareTransformWith( InstancedEntity *slave ); - - /** @see shareTransformWith - Stops sharing the transform if this is a slave, and notifies the master we're no longer - a slave. - If this is a master, tells all it's slave to stop sharing - @remarks - This function is automatically called in InstanceBatch::removeInstancedEntity - */ - void stopSharingTransform(); - - InstanceBatch* _getOwner() const { return mBatchOwner; } - - const String& getMovableType(void) const; - - const AxisAlignedBox& getBoundingBox(void) const; - Real getBoundingRadius(void) const; - - /** This is used by our batch owner to get the closest entity's depth, returns infinity + public: + InstancedEntity( InstanceBatch *batchOwner, uint32 instanceID, InstancedEntity* sharedTransformEntity = NULL); + virtual ~InstancedEntity(); + + /** Shares the entire transformation with another InstancedEntity. This is useful when a mesh + has more than one submeshes, therefore creating multiple InstanceManagers (one for each + submesh). With this function, sharing makes the skeleton to be shared (less memory) and + updated once (performance optimization). + Note that one InstancedEntity (i.e. submesh 0) must be chosen as "master" which will share + with the other instanced entities (i.e. submeshes 1-N) which are called "slaves" + @par + Requirements to share trasnformations: + * Both InstancedEntities must have use the same skeleton + * An InstancedEntity can't be both "master" and "slave" at the same time + @remarks + Sharing does nothing if the original mesh doesn't have a skeleton + When an InstancedEntity is removed (@see InstanceBatch::removeInstancedEntity), it stops + sharing the transform. If the instanced entity was the master one, all it's slaves stop + sharing and start having their own transform too. + @param slave The InstancedEntity that should share with us and become our slave + @return true if successfully shared (may fail if they aren't skeletally animated) + */ + bool shareTransformWith( InstancedEntity *slave ); + + /** @see shareTransformWith + Stops sharing the transform if this is a slave, and notifies the master we're no longer + a slave. + If this is a master, tells all it's slave to stop sharing + @remarks + This function is automatically called in InstanceBatch::removeInstancedEntity + */ + void stopSharingTransform(); + + InstanceBatch* _getOwner() const { return mBatchOwner; } + + const String& getMovableType(void) const; + + const AxisAlignedBox& getBoundingBox(void) const; + Real getBoundingRadius(void) const; + + /** This is used by our batch owner to get the closest entity's depth, returns infinity when not attached to a scene node */ - Real getSquaredViewDepth( const Camera* cam ) const; - - /// Overridden so we can tell the InstanceBatch it needs to update it's bounds - void _notifyMoved(void); - void _notifyAttached( Node* parent, bool isTagPoint = false ); - - /// Do nothing, InstanceBatch takes care of this. - void _updateRenderQueue( RenderQueue* queue ) {} - void visitRenderables( Renderable::Visitor* visitor, bool debugRenderables = false ) {} - - /** @see Entity::hasSkeleton */ - bool hasSkeleton(void) const { return mSkeletonInstance != 0; } - /** @see Entity::getSkeleton */ - SkeletonInstance* getSkeleton(void) const { return mSkeletonInstance; } - - /** @see Entity::getAnimationState */ - AnimationState* getAnimationState(const String& name) const; - /** @see Entity::getAllAnimationStates */ - AnimationStateSet* getAllAnimationStates(void) const; - - /** Called by InstanceBatch in his _updateRenderQueue to tell us we need - to calculate our bone matrices. - @remarks Assumes it has a skeleton (mSkeletonInstance != 0) - @return true if something was actually updated - */ - virtual bool _updateAnimation(void); - - /** Sets the transformation look up number */ - void setTransformLookupNumber(uint16 num) { mTransformLookupNumber = num;} - - /** Retrieve the position */ - const Vector3& getPosition() const { return mPosition; } - /** Set the position or the offset from the parent node if a parent node exists */ - void setPosition(const Vector3& position, bool doUpdate = true); - - /** Retrieve the orientation */ - const Quaternion& getOrientation() const { return mOrientation; } - /** Set the orientation or the offset from the parent node if a parent node exists */ - void setOrientation(const Quaternion& orientation, bool doUpdate = true); - - /** Retrieve the local scale */ - const Vector3& getScale() const { return mScale; } - /** Set the scale or the offset from the parent node if a parent node exists */ - void setScale(const Vector3& scale, bool doUpdate = true); - - /** Returns the maximum derived scale coefficient among the xyz values */ - Real getMaxScaleCoef() const; - - /** Update the world transform and derived values */ - void updateTransforms(); - - /** Tells if the entity is in use. */ - bool isInUse() const { return mInUse; } - /** Sets whether the entity is in use. */ - void setInUse(bool used); - - /** Returns the world transform of the instanced entity including local transform */ - virtual const Matrix4& _getParentNodeFullTransform(void) const { - assert((!mNeedTransformUpdate || !mUseLocalTransform) && "Transform data should be updated at this point"); - return mUseLocalTransform ? mFullLocalTransform : - mParentNode ? mParentNode->_getFullTransform() : Matrix4::IDENTITY; - } - - /** Returns the derived position of the instanced entity including local transform */ - const Vector3& _getDerivedPosition() const { - assert((!mNeedTransformUpdate || !mUseLocalTransform) && "Transform data should be updated at this point"); - return mUseLocalTransform ? mDerivedLocalPosition : - mParentNode ? mParentNode->_getDerivedPosition() : Vector3::ZERO; - } - - /** @copydoc MovableObject::isInScene. */ - virtual bool isInScene(void) const - { - //We assume that the instanced entity is in the scene if it is in use - //It is in the scene whether it has a parent node or not - return mInUse; - } - - /** Sets the custom parameter for this instance @see InstanceManager::setNumCustomParams - Because not all techniques support custom params, and some users may not need it while - using millions of InstancedEntities, the params have been detached from InstancedEntity - and stored in it's InstanceBatch instead, to reduce memory overhead. - @remarks - If this function is never called, all instances default to Vector4::ZERO. Watch out! - If you destroy an instanced entity and then create it again (remember! Instanced entities - are pre-allocated) it's custom param will contain the old value when it was destroyed. - @param idx of the param. In the range [0; InstanceManager::getNumCustomParams()) - @param newParam New parameter - */ - void setCustomParam( unsigned char idx, const Vector4 &newParam ); - const Vector4& getCustomParam( unsigned char idx ); - }; + Real getSquaredViewDepth( const Camera* cam ) const; + + /// Overridden so we can tell the InstanceBatch it needs to update it's bounds + void _notifyMoved(void); + void _notifyAttached( Node* parent, bool isTagPoint = false ); + + /// Do nothing, InstanceBatch takes care of this. + void _updateRenderQueue( RenderQueue* queue ) {} + void visitRenderables( Renderable::Visitor* visitor, bool debugRenderables = false ) {} + + /** @see Entity::hasSkeleton */ + bool hasSkeleton(void) const { return mSkeletonInstance != 0; } + /** @see Entity::getSkeleton */ + SkeletonInstance* getSkeleton(void) const { return mSkeletonInstance; } + + /** @see Entity::getAnimationState */ + AnimationState* getAnimationState(const String& name) const; + /** @see Entity::getAllAnimationStates */ + AnimationStateSet* getAllAnimationStates(void) const; + + /** Called by InstanceBatch in his _updateRenderQueue to tell us we need + to calculate our bone matrices. + @remarks Assumes it has a skeleton (mSkeletonInstance != 0) + @return true if something was actually updated + */ + virtual bool _updateAnimation(void); + + /** Sets the transformation look up number */ + void setTransformLookupNumber(uint16 num) { mTransformLookupNumber = num;} + + /** Retrieve the position */ + const Vector3& getPosition() const { return mPosition; } + /** Set the position or the offset from the parent node if a parent node exists */ + void setPosition(const Vector3& position, bool doUpdate = true); + + /** Retrieve the orientation */ + const Quaternion& getOrientation() const { return mOrientation; } + /** Set the orientation or the offset from the parent node if a parent node exists */ + void setOrientation(const Quaternion& orientation, bool doUpdate = true); + + /** Retrieve the local scale */ + const Vector3& getScale() const { return mScale; } + /** Set the scale or the offset from the parent node if a parent node exists */ + void setScale(const Vector3& scale, bool doUpdate = true); + + /** Returns the maximum derived scale coefficient among the xyz values */ + Real getMaxScaleCoef() const; + + /** Update the world transform and derived values */ + void updateTransforms(); + + /** Tells if the entity is in use. */ + bool isInUse() const { return mInUse; } + /** Sets whether the entity is in use. */ + void setInUse(bool used); + + /** Returns the world transform of the instanced entity including local transform */ + virtual const Matrix4& _getParentNodeFullTransform(void) const { + assert((!mNeedTransformUpdate || !mUseLocalTransform) && "Transform data should be updated at this point"); + return mUseLocalTransform ? mFullLocalTransform : + mParentNode ? mParentNode->_getFullTransform() : Matrix4::IDENTITY; + } + + /** Returns the derived position of the instanced entity including local transform */ + const Vector3& _getDerivedPosition() const { + assert((!mNeedTransformUpdate || !mUseLocalTransform) && "Transform data should be updated at this point"); + return mUseLocalTransform ? mDerivedLocalPosition : + mParentNode ? mParentNode->_getDerivedPosition() : Vector3::ZERO; + } + + /** @copydoc MovableObject::isInScene. */ + virtual bool isInScene(void) const + { + //We assume that the instanced entity is in the scene if it is in use + //It is in the scene whether it has a parent node or not + return mInUse; + } + + /** Sets the custom parameter for this instance @see InstanceManager::setNumCustomParams + Because not all techniques support custom params, and some users may not need it while + using millions of InstancedEntities, the params have been detached from InstancedEntity + and stored in it's InstanceBatch instead, to reduce memory overhead. + @remarks + If this function is never called, all instances default to Vector4::ZERO. Watch out! + If you destroy an instanced entity and then create it again (remember! Instanced entities + are pre-allocated) it's custom param will contain the old value when it was destroyed. + @param idx of the param. In the range [0; InstanceManager::getNumCustomParams()) + @param newParam New parameter + */ + void setCustomParam( unsigned char idx, const Vector4 &newParam ); + const Vector4& getCustomParam( unsigned char idx ); + }; } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreInstancedGeometry.h b/OgreMain/include/OgreInstancedGeometry.h index 9a0e0708ee4..fc4278a8f64 100644 --- a/OgreMain/include/OgreInstancedGeometry.h +++ b/OgreMain/include/OgreInstancedGeometry.h @@ -38,227 +38,227 @@ namespace Ogre { class SkeletonInstance; - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Pre-transforms and batches up meshes for efficient use as instanced geometry - in a scene - @remarks - Shader instancing allows to save both memory and draw calls. While - StaticGeometry stores 500 times the same object in a batch to display 500 - objects, this shader instancing implementation stores only 80 times the object, - and then re-uses the vertex data with different shader parameter. - Although you save memory, you make more draw call. However, you still - make less draw calls than if you were rendering each object independently. - Plus, you can move the batched objects independently of one another which - you cannot do with StaticGeometry. - @par - Therefore it is important when you are rendering a lot of geometry to - batch things up into as few rendering calls as possible. This - class allows you to build a batched object from a series of entities - in order to benefit from this behaviour. - Batching has implications of it's own though: - @li Batched geometry cannot be subdivided; that means that the whole - group will be displayed, or none of it will. This obivously has - culling issues. - @li A single material must apply for each batch. In fact this class - allows you to use multiple materials, but you should be aware that - internally this means that there is one batch per material. - Therefore you won't gain as much benefit from the batching if you - use many different materials; try to keep the number down. - @par - The bounding box information is computed with object position only. - It doesn't take account of the object orientation. - @par - The LOD settings of both the Mesh and the Materials used in - constructing this instanced geometry will be respected. This means that - if you use meshes/materials which have LOD, batches in the distance - will have a lower polygon count or material detail to those in the - foreground. Since each mesh might have different LOD distances, during - build the furthest distance at each LOD level from all meshes - in that BatchInstance is used. This means all the LOD levels change at the - same time, but at the furthest distance of any of them (so quality is - not degraded). Be aware that using Mesh LOD in this class will - further increase the memory required. Only generated LOD - is supported for meshes. - @par - There are 2 ways you can add geometry to this class; you can add - Entity objects directly with predetermined positions, scales and - orientations, or you can add an entire SceneNode and it's subtree, - including all the objects attached to it. Once you've added everything - you need to, you have to call build() the fix the geometry in place. - @par - You should not construct instances of this class directly; instead, call - SceneManager::createInstancedGeometry, which gives the SceneManager the - option of providing you with a specialised version of this class if it - wishes, and also handles the memory management for you like other - classes. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Pre-transforms and batches up meshes for efficient use as instanced geometry + in a scene + @remarks + Shader instancing allows to save both memory and draw calls. While + StaticGeometry stores 500 times the same object in a batch to display 500 + objects, this shader instancing implementation stores only 80 times the object, + and then re-uses the vertex data with different shader parameter. + Although you save memory, you make more draw call. However, you still + make less draw calls than if you were rendering each object independently. + Plus, you can move the batched objects independently of one another which + you cannot do with StaticGeometry. + @par + Therefore it is important when you are rendering a lot of geometry to + batch things up into as few rendering calls as possible. This + class allows you to build a batched object from a series of entities + in order to benefit from this behaviour. + Batching has implications of it's own though: + @li Batched geometry cannot be subdivided; that means that the whole + group will be displayed, or none of it will. This obivously has + culling issues. + @li A single material must apply for each batch. In fact this class + allows you to use multiple materials, but you should be aware that + internally this means that there is one batch per material. + Therefore you won't gain as much benefit from the batching if you + use many different materials; try to keep the number down. + @par + The bounding box information is computed with object position only. + It doesn't take account of the object orientation. + @par + The LOD settings of both the Mesh and the Materials used in + constructing this instanced geometry will be respected. This means that + if you use meshes/materials which have LOD, batches in the distance + will have a lower polygon count or material detail to those in the + foreground. Since each mesh might have different LOD distances, during + build the furthest distance at each LOD level from all meshes + in that BatchInstance is used. This means all the LOD levels change at the + same time, but at the furthest distance of any of them (so quality is + not degraded). Be aware that using Mesh LOD in this class will + further increase the memory required. Only generated LOD + is supported for meshes. + @par + There are 2 ways you can add geometry to this class; you can add + Entity objects directly with predetermined positions, scales and + orientations, or you can add an entire SceneNode and it's subtree, + including all the objects attached to it. Once you've added everything + you need to, you have to call build() the fix the geometry in place. + @par + You should not construct instances of this class directly; instead, call + SceneManager::createInstancedGeometry, which gives the SceneManager the + option of providing you with a specialised version of this class if it + wishes, and also handles the memory management for you like other + classes. @note - Warning: this class only works with indexed triangle lists at the moment, do not pass it triangle strips, fans or lines / points, or unindexed geometry. - */ - class _OgreExport InstancedGeometry : public BatchedGeometryAlloc - { - public: - /** Struct holding geometry optimised per SubMesh / LOD level, ready - for copying to instances. - @remarks - Since we're going to be duplicating geometry lots of times, it's - far more important that we don't have redundant vertex data. If a - SubMesh uses shared geometry, or we're looking at a lower LOD, not - all the vertices are being referenced by faces on that submesh. - Therefore to duplicate them, potentially hundreds or even thousands - of times, would be extremely wasteful. Therefore, if a SubMesh at - a given LOD has wastage, we create an optimised version of it's - geometry which is ready for copying with no wastage. - */ - class _OgrePrivate OptimisedSubMeshGeometry : public BatchedGeometryAlloc - { - public: - OptimisedSubMeshGeometry() :vertexData(0), indexData(0) {} - ~OptimisedSubMeshGeometry() - { - delete vertexData; - delete indexData; - } - VertexData *vertexData; - IndexData *indexData; - }; - typedef list::type OptimisedSubMeshGeometryList; - /// Saved link between SubMesh at a LOD and vertex/index data - /// May point to original or optimised geometry - struct SubMeshLodGeometryLink - { - VertexData* vertexData; - IndexData* indexData; - }; - typedef vector::type SubMeshLodGeometryLinkList; - typedef map::type SubMeshGeometryLookup; - /// Structure recording a queued submesh for the build - struct QueuedSubMesh : public BatchedGeometryAlloc - { - SubMesh* submesh; - /// Link to LOD list of geometry, potentially optimised - SubMeshLodGeometryLinkList* geometryLodList; - String materialName; - Vector3 position; - Quaternion orientation; - Vector3 scale; - /// Pre-transformed world AABB - AxisAlignedBox worldBounds; - unsigned int ID; - }; - typedef vector::type QueuedSubMeshList; - typedef vector::type QueuedSubMeshOriginList; - /// Structure recording a queued geometry for low level builds - struct QueuedGeometry : public BatchedGeometryAlloc - { - SubMeshLodGeometryLink* geometry; - Vector3 position; - Quaternion orientation; - Vector3 scale; - unsigned int ID; - }; - typedef vector::type QueuedGeometryList; - - // forward declarations - class LODBucket; - class MaterialBucket; - class BatchInstance; - - /** A GeometryBucket is a the lowest level bucket where geometry with - the same vertex & index format is stored. It also acts as the - renderable. - */ - class _OgreExport GeometryBucket : public SimpleRenderable - { - protected: - - /// Geometry which has been queued up pre-build (not for deallocation) - QueuedGeometryList mQueuedGeometry; - /// Pointer to the Batch - InstancedGeometry*mBatch; - /// Pointer to parent bucket - MaterialBucket* mParent; - /// String identifying the vertex / index format - String mFormatString; - /// Vertex information, includes current number of vertices - /// committed to be a part of this bucket - VertexData* mVertexData; - /// Index information, includes index type which limits the max - /// number of vertices which are allowed in one bucket - IndexData* mIndexData; - /// Size of indexes - HardwareIndexBuffer::IndexType mIndexType; - /// Maximum vertex indexable - size_t mMaxVertexIndex; - /// Index of the Texcoord where the index is stored - unsigned short mTexCoordIndex; - AxisAlignedBox mAABB; - - template - void copyIndexes(const T* src, T* dst, size_t count, size_t indexOffset) - { - if (indexOffset == 0) - { - memcpy(dst, src, sizeof(T) * count); - } - else - { - while(count--) - { - *dst++ = static_cast(*src++ + indexOffset); - } - } - } - - void _initGeometryBucket(const VertexData* vData, const IndexData* iData); - void _initGeometryBucket(GeometryBucket* bucket); - - public: - GeometryBucket(MaterialBucket* parent, const String& formatString, - const VertexData* vData, const IndexData* iData); - GeometryBucket(const String& name, MaterialBucket* parent, const String& formatString, - const VertexData* vData, const IndexData* iData); - GeometryBucket(MaterialBucket* parent,const String& formatString,GeometryBucket*bucket); - GeometryBucket(const String& name, MaterialBucket* parent,const String& formatString,GeometryBucket*bucket); - virtual ~GeometryBucket(); - MaterialBucket* getParent(void) { return mParent; } - Real getBoundingRadius(void) const; - /// Get the vertex data for this geometry - const VertexData* getVertexData(void) const { return mVertexData; } - /// Get the index data for this geometry - const IndexData* getIndexData(void) const { return mIndexData; } - /// @copydoc Renderable::getMaterial - const MaterialPtr& getMaterial(void) const; - Technique* getTechnique(void) const; - void getWorldTransforms(Matrix4* xform) const; - virtual unsigned short getNumWorldTransforms(void) const ; - Real getSquaredViewDepth(const Camera* cam) const; - const LightList& getLights(void) const; - bool getCastsShadows(void) const; - String getFormatString(void) const; - /** Try to assign geometry to this bucket. - @return false if there is no room left in this bucket - */ - bool assign(QueuedGeometry* qsm); - /// Build - void build(); - /// Dump contents for diagnostics - void dump(std::ofstream& of) const; - /// Return the BoundingBox information. Useful when cloning the batch instance. - AxisAlignedBox & getAABB(void){return mAABB;} - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); - - }; - class _OgreExport InstancedObject : public BatchedGeometryAlloc - { - friend class GeometryBucket; - public: - enum TransformSpace + Warning: this class only works with indexed triangle lists at the moment, do not pass it triangle strips, fans or lines / points, or unindexed geometry. + */ + class _OgreExport InstancedGeometry : public BatchedGeometryAlloc + { + public: + /** Struct holding geometry optimised per SubMesh / LOD level, ready + for copying to instances. + @remarks + Since we're going to be duplicating geometry lots of times, it's + far more important that we don't have redundant vertex data. If a + SubMesh uses shared geometry, or we're looking at a lower LOD, not + all the vertices are being referenced by faces on that submesh. + Therefore to duplicate them, potentially hundreds or even thousands + of times, would be extremely wasteful. Therefore, if a SubMesh at + a given LOD has wastage, we create an optimised version of it's + geometry which is ready for copying with no wastage. + */ + class _OgrePrivate OptimisedSubMeshGeometry : public BatchedGeometryAlloc + { + public: + OptimisedSubMeshGeometry() :vertexData(0), indexData(0) {} + ~OptimisedSubMeshGeometry() + { + delete vertexData; + delete indexData; + } + VertexData *vertexData; + IndexData *indexData; + }; + typedef list::type OptimisedSubMeshGeometryList; + /// Saved link between SubMesh at a LOD and vertex/index data + /// May point to original or optimised geometry + struct SubMeshLodGeometryLink + { + VertexData* vertexData; + IndexData* indexData; + }; + typedef vector::type SubMeshLodGeometryLinkList; + typedef map::type SubMeshGeometryLookup; + /// Structure recording a queued submesh for the build + struct QueuedSubMesh : public BatchedGeometryAlloc + { + SubMesh* submesh; + /// Link to LOD list of geometry, potentially optimised + SubMeshLodGeometryLinkList* geometryLodList; + String materialName; + Vector3 position; + Quaternion orientation; + Vector3 scale; + /// Pre-transformed world AABB + AxisAlignedBox worldBounds; + unsigned int ID; + }; + typedef vector::type QueuedSubMeshList; + typedef vector::type QueuedSubMeshOriginList; + /// Structure recording a queued geometry for low level builds + struct QueuedGeometry : public BatchedGeometryAlloc + { + SubMeshLodGeometryLink* geometry; + Vector3 position; + Quaternion orientation; + Vector3 scale; + unsigned int ID; + }; + typedef vector::type QueuedGeometryList; + + // forward declarations + class LODBucket; + class MaterialBucket; + class BatchInstance; + + /** A GeometryBucket is a the lowest level bucket where geometry with + the same vertex & index format is stored. It also acts as the + renderable. + */ + class _OgreExport GeometryBucket : public SimpleRenderable + { + protected: + + /// Geometry which has been queued up pre-build (not for deallocation) + QueuedGeometryList mQueuedGeometry; + /// Pointer to the Batch + InstancedGeometry*mBatch; + /// Pointer to parent bucket + MaterialBucket* mParent; + /// String identifying the vertex / index format + String mFormatString; + /// Vertex information, includes current number of vertices + /// committed to be a part of this bucket + VertexData* mVertexData; + /// Index information, includes index type which limits the max + /// number of vertices which are allowed in one bucket + IndexData* mIndexData; + /// Size of indexes + HardwareIndexBuffer::IndexType mIndexType; + /// Maximum vertex indexable + size_t mMaxVertexIndex; + /// Index of the Texcoord where the index is stored + unsigned short mTexCoordIndex; + AxisAlignedBox mAABB; + + template + void copyIndexes(const T* src, T* dst, size_t count, size_t indexOffset) + { + if (indexOffset == 0) + { + memcpy(dst, src, sizeof(T) * count); + } + else + { + while(count--) + { + *dst++ = static_cast(*src++ + indexOffset); + } + } + } + + void _initGeometryBucket(const VertexData* vData, const IndexData* iData); + void _initGeometryBucket(GeometryBucket* bucket); + + public: + GeometryBucket(MaterialBucket* parent, const String& formatString, + const VertexData* vData, const IndexData* iData); + GeometryBucket(const String& name, MaterialBucket* parent, const String& formatString, + const VertexData* vData, const IndexData* iData); + GeometryBucket(MaterialBucket* parent,const String& formatString,GeometryBucket*bucket); + GeometryBucket(const String& name, MaterialBucket* parent,const String& formatString,GeometryBucket*bucket); + virtual ~GeometryBucket(); + MaterialBucket* getParent(void) { return mParent; } + Real getBoundingRadius(void) const; + /// Get the vertex data for this geometry + const VertexData* getVertexData(void) const { return mVertexData; } + /// Get the index data for this geometry + const IndexData* getIndexData(void) const { return mIndexData; } + /// @copydoc Renderable::getMaterial + const MaterialPtr& getMaterial(void) const; + Technique* getTechnique(void) const; + void getWorldTransforms(Matrix4* xform) const; + virtual unsigned short getNumWorldTransforms(void) const ; + Real getSquaredViewDepth(const Camera* cam) const; + const LightList& getLights(void) const; + bool getCastsShadows(void) const; + String getFormatString(void) const; + /** Try to assign geometry to this bucket. + @return false if there is no room left in this bucket + */ + bool assign(QueuedGeometry* qsm); + /// Build + void build(); + /// Dump contents for diagnostics + void dump(std::ofstream& of) const; + /// Return the BoundingBox information. Useful when cloning the batch instance. + AxisAlignedBox & getAABB(void){return mAABB;} + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); + + }; + class _OgreExport InstancedObject : public BatchedGeometryAlloc + { + friend class GeometryBucket; + public: + enum TransformSpace { /// Transform is relative to the local space TS_LOCAL, @@ -267,559 +267,559 @@ namespace Ogre { /// Transform is relative to world space TS_WORLD }; - /// list of Geometry Buckets that contains the instanced object - typedef vector::type GeometryBucketList; - protected: - GeometryBucketList mGeometryBucketList; - unsigned short mIndex; - Matrix4 mTransformation; - Quaternion mOrientation; - Vector3 mScale; - Vector3 mPosition; - SkeletonInstance* mSkeletonInstance; - /// Cached bone matrices, including any world transform - Matrix4 *mBoneWorldMatrices; - /// Cached bone matrices in skeleton local space - Matrix4 *mBoneMatrices; - /// State of animation for animable meshes - AnimationStateSet* mAnimationState; - unsigned short mNumBoneMatrices; - /// Records the last frame in which animation was updated - unsigned long mFrameAnimationLastUpdated; - public: - InstancedObject(unsigned short index); - InstancedObject(unsigned short index,SkeletonInstance *skeleton,AnimationStateSet*animations); - ~InstancedObject(); - void setPosition( const Vector3 &position); - const Vector3& getPosition(void) const; - void yaw(const Radian& angle); - void pitch(const Radian& angle); - void roll(const Radian& angle); - void rotate(const Quaternion& q); - void setScale(const Vector3& scale); - const Vector3& getScale() const; - void setOrientation(const Quaternion& q); - void setPositionAndOrientation(const Vector3 &p, const Quaternion& q); + /// list of Geometry Buckets that contains the instanced object + typedef vector::type GeometryBucketList; + protected: + GeometryBucketList mGeometryBucketList; + unsigned short mIndex; + Matrix4 mTransformation; + Quaternion mOrientation; + Vector3 mScale; + Vector3 mPosition; + SkeletonInstance* mSkeletonInstance; + /// Cached bone matrices, including any world transform + Matrix4 *mBoneWorldMatrices; + /// Cached bone matrices in skeleton local space + Matrix4 *mBoneMatrices; + /// State of animation for animable meshes + AnimationStateSet* mAnimationState; + unsigned short mNumBoneMatrices; + /// Records the last frame in which animation was updated + unsigned long mFrameAnimationLastUpdated; + public: + InstancedObject(unsigned short index); + InstancedObject(unsigned short index,SkeletonInstance *skeleton,AnimationStateSet*animations); + ~InstancedObject(); + void setPosition( const Vector3 &position); + const Vector3& getPosition(void) const; + void yaw(const Radian& angle); + void pitch(const Radian& angle); + void roll(const Radian& angle); + void rotate(const Quaternion& q); + void setScale(const Vector3& scale); + const Vector3& getScale() const; + void setOrientation(const Quaternion& q); + void setPositionAndOrientation(const Vector3 &p, const Quaternion& q); Quaternion & getOrientation(void); - void addBucketToList(GeometryBucket* bucket); - void needUpdate(); - GeometryBucketList&getGeometryBucketList(void){return mGeometryBucketList;} - void translate(const Matrix3& axes, const Vector3& move); - void translate(const Vector3& d); - Matrix3 getLocalAxes(void) const; - void updateAnimation(void); - AnimationState* getAnimationState(const String& name) const; - SkeletonInstance*getSkeletonInstance(void){return mSkeletonInstance;} - - }; - /** A MaterialBucket is a collection of smaller buckets with the same - Material (and implicitly the same LOD). */ - class _OgreExport MaterialBucket : public BatchedGeometryAlloc - { - public: - /// list of Geometry Buckets in this BatchInstance - typedef vector::type GeometryBucketList; - protected: - /// Pointer to parent LODBucket - LODBucket* mParent; - /// Material being used - String mMaterialName; - /// Pointer to material being used - MaterialPtr mMaterial; - /// Active technique - Technique* mTechnique; - int mLastIndex; - /// list of Geometry Buckets in this BatchInstance - GeometryBucketList mGeometryBucketList; - // index to current Geometry Buckets for a given geometry format - typedef map::type CurrentGeometryMap; - CurrentGeometryMap mCurrentGeometryMap; - /// Get a packed string identifying the geometry format - String getGeometryFormatString(SubMeshLodGeometryLink* geom); - - public: - MaterialBucket(LODBucket* parent, const String& materialName); - virtual ~MaterialBucket(); - LODBucket* getParent(void) { return mParent; } - /// Get the material name - const String& getMaterialName(void) const { return mMaterialName; } - /// Assign geometry to this bucket - void assign(QueuedGeometry* qsm); - /// Build - void build(); - /// Add children to the render queue - void addRenderables(RenderQueue* queue, uint8 group, - Real lodValue); - /// Get the material for this bucket - const MaterialPtr& getMaterial(void) const { return mMaterial; } - /// Iterator over geometry - typedef VectorIterator GeometryIterator; - /// Get an iterator over the contained geometry - GeometryIterator getGeometryIterator(void); - /// Get the current Technique - Technique* getCurrentTechnique(void) const { return mTechnique; } - /// Dump contents for diagnostics - void dump(std::ofstream& of) const; - /// Return the geometry map - MaterialBucket::CurrentGeometryMap* getMaterialBucketMap(void) const; - /// Return the geometry list - MaterialBucket::GeometryBucketList*getGeometryBucketList(void) const; - /// fill in the map and the list - void updateContainers(GeometryBucket* bucket, const String &format); - void setLastIndex(int index){mLastIndex=index;} - int getLastIndex(){return mLastIndex;} - void setMaterial(const String & name); - void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); - - }; - /** A LODBucket is a collection of smaller buckets with the same LOD. - @remarks - LOD refers to Mesh LOD here. Material LOD can change separately - at the next bucket down from this. - */ - class _OgreExport LODBucket : public BatchedGeometryAlloc - { - public: - /// Lookup of Material Buckets in this BatchInstance - typedef map::type MaterialBucketMap; - protected: - /// Pointer to parent BatchInstance - BatchInstance* mParent; - /// LOD level (0 == full LOD) - unsigned short mLod; - /// LOD value at which this LOD starts to apply (squared) - Real mLodValue; - /// Lookup of Material Buckets in this BatchInstance - MaterialBucketMap mMaterialBucketMap; - /// Geometry queued for a single LOD (deallocated here) - QueuedGeometryList mQueuedGeometryList; - public: - LODBucket(BatchInstance* parent, unsigned short lod, Real lodValue); - virtual ~LODBucket(); - BatchInstance* getParent(void) { return mParent; } - /// Get the LOD index - ushort getLod(void) const { return mLod; } - /// Get the LOD value - Real getLodValue(void) const { return mLodValue; } - /// Assign a queued submesh to this bucket, using specified mesh LOD - void assign(QueuedSubMesh* qsm, ushort atLod); - /// Build - void build(); - /// Add children to the render queue - void addRenderables(RenderQueue* queue, uint8 group, - Real lodValue); - /// Iterator over the materials in this LOD - typedef MapIterator MaterialIterator; - /// Get an iterator over the materials in this LOD - MaterialIterator getMaterialIterator(void); - /// Dump contents for diagnostics - void dump(std::ofstream& of) const; - /// fill the map - void updateContainers(MaterialBucket* bucket, String& name ); - void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); - - }; - /** The details of a topological BatchInstance which is the highest level of - partitioning for this class. - @remarks - The size & shape of BatchInstances entirely depends on the SceneManager - specific implementation. It is a MovableObject since it will be - attached to a node based on the local centre - in practice it - won't actually move (although in theory it could). - */ - class _OgreExport BatchInstance : public MovableObject - { + void addBucketToList(GeometryBucket* bucket); + void needUpdate(); + GeometryBucketList&getGeometryBucketList(void){return mGeometryBucketList;} + void translate(const Matrix3& axes, const Vector3& move); + void translate(const Vector3& d); + Matrix3 getLocalAxes(void) const; + void updateAnimation(void); + AnimationState* getAnimationState(const String& name) const; + SkeletonInstance*getSkeletonInstance(void){return mSkeletonInstance;} + + }; + /** A MaterialBucket is a collection of smaller buckets with the same + Material (and implicitly the same LOD). */ + class _OgreExport MaterialBucket : public BatchedGeometryAlloc + { + public: + /// list of Geometry Buckets in this BatchInstance + typedef vector::type GeometryBucketList; + protected: + /// Pointer to parent LODBucket + LODBucket* mParent; + /// Material being used + String mMaterialName; + /// Pointer to material being used + MaterialPtr mMaterial; + /// Active technique + Technique* mTechnique; + int mLastIndex; + /// list of Geometry Buckets in this BatchInstance + GeometryBucketList mGeometryBucketList; + // index to current Geometry Buckets for a given geometry format + typedef map::type CurrentGeometryMap; + CurrentGeometryMap mCurrentGeometryMap; + /// Get a packed string identifying the geometry format + String getGeometryFormatString(SubMeshLodGeometryLink* geom); + + public: + MaterialBucket(LODBucket* parent, const String& materialName); + virtual ~MaterialBucket(); + LODBucket* getParent(void) { return mParent; } + /// Get the material name + const String& getMaterialName(void) const { return mMaterialName; } + /// Assign geometry to this bucket + void assign(QueuedGeometry* qsm); + /// Build + void build(); + /// Add children to the render queue + void addRenderables(RenderQueue* queue, uint8 group, + Real lodValue); + /// Get the material for this bucket + const MaterialPtr& getMaterial(void) const { return mMaterial; } + /// Iterator over geometry + typedef VectorIterator GeometryIterator; + /// Get an iterator over the contained geometry + GeometryIterator getGeometryIterator(void); + /// Get the current Technique + Technique* getCurrentTechnique(void) const { return mTechnique; } + /// Dump contents for diagnostics + void dump(std::ofstream& of) const; + /// Return the geometry map + MaterialBucket::CurrentGeometryMap* getMaterialBucketMap(void) const; + /// Return the geometry list + MaterialBucket::GeometryBucketList*getGeometryBucketList(void) const; + /// fill in the map and the list + void updateContainers(GeometryBucket* bucket, const String &format); + void setLastIndex(int index){mLastIndex=index;} + int getLastIndex(){return mLastIndex;} + void setMaterial(const String & name); + void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); + + }; + /** A LODBucket is a collection of smaller buckets with the same LOD. + @remarks + LOD refers to Mesh LOD here. Material LOD can change separately + at the next bucket down from this. + */ + class _OgreExport LODBucket : public BatchedGeometryAlloc + { + public: + /// Lookup of Material Buckets in this BatchInstance + typedef map::type MaterialBucketMap; + protected: + /// Pointer to parent BatchInstance + BatchInstance* mParent; + /// LOD level (0 == full LOD) + unsigned short mLod; + /// LOD value at which this LOD starts to apply (squared) + Real mLodValue; + /// Lookup of Material Buckets in this BatchInstance + MaterialBucketMap mMaterialBucketMap; + /// Geometry queued for a single LOD (deallocated here) + QueuedGeometryList mQueuedGeometryList; + public: + LODBucket(BatchInstance* parent, unsigned short lod, Real lodValue); + virtual ~LODBucket(); + BatchInstance* getParent(void) { return mParent; } + /// Get the LOD index + ushort getLod(void) const { return mLod; } + /// Get the LOD value + Real getLodValue(void) const { return mLodValue; } + /// Assign a queued submesh to this bucket, using specified mesh LOD + void assign(QueuedSubMesh* qsm, ushort atLod); + /// Build + void build(); + /// Add children to the render queue + void addRenderables(RenderQueue* queue, uint8 group, + Real lodValue); + /// Iterator over the materials in this LOD + typedef MapIterator MaterialIterator; + /// Get an iterator over the materials in this LOD + MaterialIterator getMaterialIterator(void); + /// Dump contents for diagnostics + void dump(std::ofstream& of) const; + /// fill the map + void updateContainers(MaterialBucket* bucket, String& name ); + void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); + + }; + /** The details of a topological BatchInstance which is the highest level of + partitioning for this class. + @remarks + The size & shape of BatchInstances entirely depends on the SceneManager + specific implementation. It is a MovableObject since it will be + attached to a node based on the local centre - in practice it + won't actually move (although in theory it could). + */ + class _OgreExport BatchInstance : public MovableObject + { friend class MaterialBucket; - public: - - - /// list of LOD Buckets in this BatchInstance - typedef vector::type LODBucketList; - typedef map::type ObjectsMap; - typedef MapIterator InstancedObjectIterator; - protected: - - /// Parent static geometry - InstancedGeometry* mParent; - /// Scene manager link - SceneManager* mSceneMgr; - /// Scene node - SceneNode* mNode; - /// Local list of queued meshes (not used for deallocation) - QueuedSubMeshList mQueuedSubMeshes; - /// Unique identifier for the BatchInstance - uint32 mBatchInstanceID; - - ObjectsMap mInstancesMap; - public: - /// LOD values as built up - use the max at each level - Mesh::LodValueList mLodValues; - /// Local AABB relative to BatchInstance centre - AxisAlignedBox mAABB; - /// Local bounding radius - Real mBoundingRadius; - /// The current LOD level, as determined from the last camera - ushort mCurrentLod; - /// Current LOD value, passed on to do material LOD later - Real mLodValue; + public: + + + /// list of LOD Buckets in this BatchInstance + typedef vector::type LODBucketList; + typedef map::type ObjectsMap; + typedef MapIterator InstancedObjectIterator; + protected: + + /// Parent static geometry + InstancedGeometry* mParent; + /// Scene manager link + SceneManager* mSceneMgr; + /// Scene node + SceneNode* mNode; + /// Local list of queued meshes (not used for deallocation) + QueuedSubMeshList mQueuedSubMeshes; + /// Unique identifier for the BatchInstance + uint32 mBatchInstanceID; + + ObjectsMap mInstancesMap; + public: + /// LOD values as built up - use the max at each level + Mesh::LodValueList mLodValues; + /// Local AABB relative to BatchInstance centre + AxisAlignedBox mAABB; + /// Local bounding radius + Real mBoundingRadius; + /// The current LOD level, as determined from the last camera + ushort mCurrentLod; + /// Current LOD value, passed on to do material LOD later + Real mLodValue; /// Current camera, passed on to do material LOD later Camera *mCamera; /// Cached squared view depth value to avoid recalculation by GeometryBucket Real mSquaredViewDepth; - protected: - /// List of LOD buckets - LODBucketList mLodBucketList; + protected: + /// List of LOD buckets + LODBucketList mLodBucketList; /// LOD strategy reference const LodStrategy *mLodStrategy; - public: - BatchInstance(InstancedGeometry* parent, const String& name, SceneManager* mgr, - uint32 BatchInstanceID); - virtual ~BatchInstance(); - // more fields can be added in subclasses - InstancedGeometry* getParent(void) const { return mParent;} - /// Assign a queued mesh to this BatchInstance, read for final build - void assign(QueuedSubMesh* qmesh); - /// Build this BatchInstance - void build(); - /// Get the BatchInstance ID of this BatchInstance - uint32 getID(void) const { return mBatchInstanceID; } - /// Get the centre point of the BatchInstance -// const Vector3& getCentre(void) const { return mCentre; } - const String& getMovableType(void) const; - void _notifyCurrentCamera(Camera* cam); - const AxisAlignedBox& getBoundingBox(void) const; - void setBoundingBox(AxisAlignedBox& box); - Real getBoundingRadius(void) const; - void _updateRenderQueue(RenderQueue* queue); - bool isVisible(void) const; - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false); - - // uint32 getTypeFlags(void) const; - - typedef VectorIterator LODIterator; - /// Get an iterator over the LODs in this BatchInstance - LODIterator getLODIterator(void); - /// Shared set of lights for all GeometryBuckets - const LightList& getLights(void) const; - - /// update the bounding box of the BatchInstance according to the positions of the objects - void updateBoundingBox(); - - /// Dump contents for diagnostics - void dump(std::ofstream& of) const; - /// fill in the list - void updateContainers(LODBucket* bucket ); - /// attach the BatchInstance to the scene - void attachToScene(); - void addInstancedObject(unsigned short index, InstancedObject* object); - InstancedObject* isInstancedObjectPresent(unsigned short index); - InstancedObjectIterator getObjectIterator(); - SceneNode*getSceneNode(void){return mNode;} - ObjectsMap& getInstancesMap(void){return mInstancesMap;} - /// change the shader used to render the batch instance - - }; - /** Indexed BatchInstance map based on packed x/y/z BatchInstance index, 10 bits for - each axis. - */ - typedef map::type BatchInstanceMap; - /** Simple vectors where are stored all the render operations of the Batch. - This vector is used when we want to delete the batch, in order to delete only one time each - render operation. - - */ - typedef vector::type RenderOperationVector; - protected: - // General state & settings - SceneManager* mOwner; - String mName; - bool mBuilt; - Real mUpperDistance; - Real mSquaredUpperDistance; - bool mCastShadows; - Vector3 mBatchInstanceDimensions; - Vector3 mHalfBatchInstanceDimensions; - Vector3 mOrigin; - bool mVisible; + public: + BatchInstance(InstancedGeometry* parent, const String& name, SceneManager* mgr, + uint32 BatchInstanceID); + virtual ~BatchInstance(); + // more fields can be added in subclasses + InstancedGeometry* getParent(void) const { return mParent;} + /// Assign a queued mesh to this BatchInstance, read for final build + void assign(QueuedSubMesh* qmesh); + /// Build this BatchInstance + void build(); + /// Get the BatchInstance ID of this BatchInstance + uint32 getID(void) const { return mBatchInstanceID; } + /// Get the centre point of the BatchInstance +// const Vector3& getCentre(void) const { return mCentre; } + const String& getMovableType(void) const; + void _notifyCurrentCamera(Camera* cam); + const AxisAlignedBox& getBoundingBox(void) const; + void setBoundingBox(AxisAlignedBox& box); + Real getBoundingRadius(void) const; + void _updateRenderQueue(RenderQueue* queue); + bool isVisible(void) const; + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false); + + // uint32 getTypeFlags(void) const; + + typedef VectorIterator LODIterator; + /// Get an iterator over the LODs in this BatchInstance + LODIterator getLODIterator(void); + /// Shared set of lights for all GeometryBuckets + const LightList& getLights(void) const; + + /// update the bounding box of the BatchInstance according to the positions of the objects + void updateBoundingBox(); + + /// Dump contents for diagnostics + void dump(std::ofstream& of) const; + /// fill in the list + void updateContainers(LODBucket* bucket ); + /// attach the BatchInstance to the scene + void attachToScene(); + void addInstancedObject(unsigned short index, InstancedObject* object); + InstancedObject* isInstancedObjectPresent(unsigned short index); + InstancedObjectIterator getObjectIterator(); + SceneNode*getSceneNode(void){return mNode;} + ObjectsMap& getInstancesMap(void){return mInstancesMap;} + /// change the shader used to render the batch instance + + }; + /** Indexed BatchInstance map based on packed x/y/z BatchInstance index, 10 bits for + each axis. + */ + typedef map::type BatchInstanceMap; + /** Simple vectors where are stored all the render operations of the Batch. + This vector is used when we want to delete the batch, in order to delete only one time each + render operation. + + */ + typedef vector::type RenderOperationVector; + protected: + // General state & settings + SceneManager* mOwner; + String mName; + bool mBuilt; + Real mUpperDistance; + Real mSquaredUpperDistance; + bool mCastShadows; + Vector3 mBatchInstanceDimensions; + Vector3 mHalfBatchInstanceDimensions; + Vector3 mOrigin; + bool mVisible; /// Flags to indicate whether the World Transform Inverse matrices are passed to the shaders bool mProvideWorldInverses; /// The render queue to use when rendering this object uint8 mRenderQueueID; - /// Flags whether the RenderQueue's default should be used. - bool mRenderQueueIDSet; - /// number of objects in the batch - unsigned int mObjectCount; - QueuedSubMeshList mQueuedSubMeshes; - BatchInstance*mInstancedGeometryInstance; - /**this is just a pointer to the base skeleton that will be used for each animated object in the batches - This pointer has a value only during the creation of the InstancedGeometry - */ - SkeletonPtr mBaseSkeleton; - SkeletonInstance *mSkeletonInstance; - /**This is the main animation state. All "objects" in the batch will use an instance of this animation - state - */ - AnimationStateSet* mAnimationState; - /// List of geometry which has been optimised for SubMesh use - /// This is the primary storage used for cleaning up later - OptimisedSubMeshGeometryList mOptimisedSubMeshGeometryList; - - /** Cached links from SubMeshes to (potentially optimised) geometry - This is not used for deletion since the lookup may reference - original vertex data - */ - SubMeshGeometryLookup mSubMeshGeometryLookup; - - /// Map of BatchInstances - BatchInstanceMap mBatchInstanceMap; - /** This vector stores all the renderOperation used in the batch. - See the type definition for more details. - */ - RenderOperationVector mRenderOps; - /** Virtual method for getting a BatchInstance most suitable for the - passed in bounds. Can be overridden by subclasses. - */ - virtual BatchInstance* getBatchInstance(const AxisAlignedBox& bounds, bool autoCreate); - /** Get the BatchInstance within which a point lies */ - virtual BatchInstance* getBatchInstance(const Vector3& point, bool autoCreate); - /** Get the BatchInstance using indexes */ - virtual BatchInstance* getBatchInstance(ushort x, ushort y, ushort z, bool autoCreate); - /** Get the BatchInstance using a packed index, returns null if it doesn't exist. */ - virtual BatchInstance* getBatchInstance(uint32 index); - /** Get the BatchInstance indexes for a point. - */ - virtual void getBatchInstanceIndexes(const Vector3& point, - ushort& x, ushort& y, ushort& z); - /** get the first BatchInstance or create on if it does not exists. - */ - virtual BatchInstance* getInstancedGeometryInstance(void); - /** Pack 3 indexes into a single index value - */ - virtual uint32 packIndex(ushort x, ushort y, ushort z); - /** Get the volume intersection for an indexed BatchInstance with some bounds. - */ - virtual Real getVolumeIntersection(const AxisAlignedBox& box, - ushort x, ushort y, ushort z); - /** Get the bounds of an indexed BatchInstance. - */ - virtual AxisAlignedBox getBatchInstanceBounds(ushort x, ushort y, ushort z); - /** Get the centre of an indexed BatchInstance. - */ - virtual Vector3 getBatchInstanceCentre(ushort x, ushort y, ushort z); - /** Calculate world bounds from a set of vertex data. */ - virtual AxisAlignedBox calculateBounds(VertexData* vertexData, - const Vector3& position, const Quaternion& orientation, - const Vector3& scale); - /** Look up or calculate the geometry data to use for this SubMesh */ - SubMeshLodGeometryLinkList* determineGeometry(SubMesh* sm); - /** Split some shared geometry into dedicated geometry. */ - void splitGeometry(VertexData* vd, IndexData* id, - SubMeshLodGeometryLink* targetGeomLink); - - typedef map::type IndexRemap; - /** Method for figuring out which vertices are used by an index buffer - and calculating a remap lookup for a vertex buffer just containing - those vertices. - */ - template - void buildIndexRemap(T* pBuffer, size_t numIndexes, IndexRemap& remap) - { - remap.clear(); - for (size_t i = 0; i < numIndexes; ++i) - { - // use insert since duplicates are silently discarded - remap.insert(IndexRemap::value_type(*pBuffer++, remap.size())); - // this will have mapped oldindex -> new index IF oldindex - // wasn't already there - } - } - /** Method for altering indexes based on a remap. */ - template - void remapIndexes(T* src, T* dst, const IndexRemap& remap, - size_t numIndexes) - { - for (size_t i = 0; i < numIndexes; ++i) - { - // look up original and map to target - IndexRemap::const_iterator ix = remap.find(*src++); - assert(ix != remap.end()); - *dst++ = static_cast(ix->second); - } - } - - public: - /// Constructor; do not use directly (@see SceneManager::createInstancedGeometry) - InstancedGeometry(SceneManager* owner, const String& name); - /// Destructor - virtual ~InstancedGeometry(); - - /// Get the name of this object - const String& getName(void) const { return mName; } - /** Adds an Entity to the static geometry. - @remarks - This method takes an existing Entity and adds its details to the - list of elements to include when building. Note that the Entity - itself is not copied or referenced in this method; an Entity is - passed simply so that you can change the materials of attached - SubEntity objects if you want. You can add the same Entity - instance multiple times with different material settings - completely safely, and destroy the Entity before destroying - this InstancedGeometry if you like. The Entity passed in is simply - used as a definition. - @note Must be called before 'build'. + /// Flags whether the RenderQueue's default should be used. + bool mRenderQueueIDSet; + /// number of objects in the batch + unsigned int mObjectCount; + QueuedSubMeshList mQueuedSubMeshes; + BatchInstance*mInstancedGeometryInstance; + /**this is just a pointer to the base skeleton that will be used for each animated object in the batches + This pointer has a value only during the creation of the InstancedGeometry + */ + SkeletonPtr mBaseSkeleton; + SkeletonInstance *mSkeletonInstance; + /**This is the main animation state. All "objects" in the batch will use an instance of this animation + state + */ + AnimationStateSet* mAnimationState; + /// List of geometry which has been optimised for SubMesh use + /// This is the primary storage used for cleaning up later + OptimisedSubMeshGeometryList mOptimisedSubMeshGeometryList; + + /** Cached links from SubMeshes to (potentially optimised) geometry + This is not used for deletion since the lookup may reference + original vertex data + */ + SubMeshGeometryLookup mSubMeshGeometryLookup; + + /// Map of BatchInstances + BatchInstanceMap mBatchInstanceMap; + /** This vector stores all the renderOperation used in the batch. + See the type definition for more details. + */ + RenderOperationVector mRenderOps; + /** Virtual method for getting a BatchInstance most suitable for the + passed in bounds. Can be overridden by subclasses. + */ + virtual BatchInstance* getBatchInstance(const AxisAlignedBox& bounds, bool autoCreate); + /** Get the BatchInstance within which a point lies */ + virtual BatchInstance* getBatchInstance(const Vector3& point, bool autoCreate); + /** Get the BatchInstance using indexes */ + virtual BatchInstance* getBatchInstance(ushort x, ushort y, ushort z, bool autoCreate); + /** Get the BatchInstance using a packed index, returns null if it doesn't exist. */ + virtual BatchInstance* getBatchInstance(uint32 index); + /** Get the BatchInstance indexes for a point. + */ + virtual void getBatchInstanceIndexes(const Vector3& point, + ushort& x, ushort& y, ushort& z); + /** get the first BatchInstance or create on if it does not exists. + */ + virtual BatchInstance* getInstancedGeometryInstance(void); + /** Pack 3 indexes into a single index value + */ + virtual uint32 packIndex(ushort x, ushort y, ushort z); + /** Get the volume intersection for an indexed BatchInstance with some bounds. + */ + virtual Real getVolumeIntersection(const AxisAlignedBox& box, + ushort x, ushort y, ushort z); + /** Get the bounds of an indexed BatchInstance. + */ + virtual AxisAlignedBox getBatchInstanceBounds(ushort x, ushort y, ushort z); + /** Get the centre of an indexed BatchInstance. + */ + virtual Vector3 getBatchInstanceCentre(ushort x, ushort y, ushort z); + /** Calculate world bounds from a set of vertex data. */ + virtual AxisAlignedBox calculateBounds(VertexData* vertexData, + const Vector3& position, const Quaternion& orientation, + const Vector3& scale); + /** Look up or calculate the geometry data to use for this SubMesh */ + SubMeshLodGeometryLinkList* determineGeometry(SubMesh* sm); + /** Split some shared geometry into dedicated geometry. */ + void splitGeometry(VertexData* vd, IndexData* id, + SubMeshLodGeometryLink* targetGeomLink); + + typedef map::type IndexRemap; + /** Method for figuring out which vertices are used by an index buffer + and calculating a remap lookup for a vertex buffer just containing + those vertices. + */ + template + void buildIndexRemap(T* pBuffer, size_t numIndexes, IndexRemap& remap) + { + remap.clear(); + for (size_t i = 0; i < numIndexes; ++i) + { + // use insert since duplicates are silently discarded + remap.insert(IndexRemap::value_type(*pBuffer++, remap.size())); + // this will have mapped oldindex -> new index IF oldindex + // wasn't already there + } + } + /** Method for altering indexes based on a remap. */ + template + void remapIndexes(T* src, T* dst, const IndexRemap& remap, + size_t numIndexes) + { + for (size_t i = 0; i < numIndexes; ++i) + { + // look up original and map to target + IndexRemap::const_iterator ix = remap.find(*src++); + assert(ix != remap.end()); + *dst++ = static_cast(ix->second); + } + } + + public: + /// Constructor; do not use directly (@see SceneManager::createInstancedGeometry) + InstancedGeometry(SceneManager* owner, const String& name); + /// Destructor + virtual ~InstancedGeometry(); + + /// Get the name of this object + const String& getName(void) const { return mName; } + /** Adds an Entity to the static geometry. + @remarks + This method takes an existing Entity and adds its details to the + list of elements to include when building. Note that the Entity + itself is not copied or referenced in this method; an Entity is + passed simply so that you can change the materials of attached + SubEntity objects if you want. You can add the same Entity + instance multiple times with different material settings + completely safely, and destroy the Entity before destroying + this InstancedGeometry if you like. The Entity passed in is simply + used as a definition. + @note Must be called before 'build'. @note All added entities must use the same LOD strategy. - @param ent The Entity to use as a definition (the Mesh and Materials - referenced will be recorded for the build call). - @param position The world position at which to add this Entity - @param orientation The world orientation at which to add this Entity - @param scale The scale at which to add this entity - */ - virtual void addEntity(Entity* ent, const Vector3& position, - const Quaternion& orientation = Quaternion::IDENTITY, - const Vector3& scale = Vector3::UNIT_SCALE); - - /** Adds all the Entity objects attached to a SceneNode and all it's - children to the static geometry. - @remarks - This method performs just like addEntity, except it adds all the - entities attached to an entire sub-tree to the geometry. - The position / orientation / scale parameters are taken from the - node structure instead of being specified manually. - @note - The SceneNode you pass in will not be automatically detached from - it's parent, so if you have this node already attached to the scene - graph, you will need to remove it if you wish to avoid the overhead - of rendering both the original objects and their new static - versions! We don't do this for you incase you are preparing this - in advance and so don't want the originals detached yet. - @note Must be called before 'build'. + @param ent The Entity to use as a definition (the Mesh and Materials + referenced will be recorded for the build call). + @param position The world position at which to add this Entity + @param orientation The world orientation at which to add this Entity + @param scale The scale at which to add this entity + */ + virtual void addEntity(Entity* ent, const Vector3& position, + const Quaternion& orientation = Quaternion::IDENTITY, + const Vector3& scale = Vector3::UNIT_SCALE); + + /** Adds all the Entity objects attached to a SceneNode and all it's + children to the static geometry. + @remarks + This method performs just like addEntity, except it adds all the + entities attached to an entire sub-tree to the geometry. + The position / orientation / scale parameters are taken from the + node structure instead of being specified manually. + @note + The SceneNode you pass in will not be automatically detached from + it's parent, so if you have this node already attached to the scene + graph, you will need to remove it if you wish to avoid the overhead + of rendering both the original objects and their new static + versions! We don't do this for you incase you are preparing this + in advance and so don't want the originals detached yet. + @note Must be called before 'build'. @note All added entities must use the same LOD strategy. - @param node Pointer to the node to use to provide a set of Entity - templates - */ - virtual void addSceneNode(const SceneNode* node); - - /** Build the geometry. - @remarks - Based on all the entities which have been added, and the batching - options which have been set, this method constructs the batched - geometry structures required. The batches are added to the scene - and will be rendered unless you specifically hide them. - @note - Once you have called this method, you can no longer add any more - entities. - */ - virtual void build(void); - /** Add a new batch instance - @remarks - This method add a new instance of the whole batch, by creating a new - BatchInstance, containing new LOD buckets, material buckets and geometry buckets. - The new geometry buckets will use the same buffers as the base bucket. - @note - no note - */ - void addBatchInstance(void); - /** Destroys all the built geometry state (reverse of build). - @remarks - You can call build() again after this and it will pick up all the - same entities / nodes you queued last time. - */ - virtual void destroy(void); - - /** Clears any of the entities / nodes added to this geometry and - destroys anything which has already been built. - */ - virtual void reset(void); - - /** Sets the distance at which batches are no longer rendered. - @remarks - This lets you turn off batches at a given distance. This can be - useful for things like detail meshes (grass, foliage etc) and could - be combined with a shader which fades the geometry out beforehand - to lessen the effect. - @param dist Distance beyond which the batches will not be rendered - (the default is 0, which means batches are always rendered). - */ - virtual void setRenderingDistance(Real dist) { - mUpperDistance = dist; - mSquaredUpperDistance = mUpperDistance * mUpperDistance; - } - - /** Gets the distance at which batches are no longer rendered. */ - virtual Real getRenderingDistance(void) const { return mUpperDistance; } - - /** Gets the squared distance at which batches are no longer rendered. */ - virtual Real getSquaredRenderingDistance(void) const - { return mSquaredUpperDistance; } - - /** Hides or shows all the batches. */ - virtual void setVisible(bool visible); - - /** Are the batches visible? */ - virtual bool isVisible(void) const { return mVisible; } - - /** Sets whether this geometry should cast shadows. - @remarks - No matter what the settings on the original entities, - the InstancedGeometry class defaults to not casting shadows. - This is because, being static, unless you have moving lights - you'd be better to use precalculated shadows of some sort. - However, if you need them, you can enable them using this - method. If the SceneManager is set up to use stencil shadows, - edge lists will be copied from the underlying meshes on build. - It is essential that all meshes support stencil shadows in this - case. - @note If you intend to use stencil shadows, you must set this to - true before calling 'build' as well as making sure you set the - scene's shadow type (that should always be the first thing you do - anyway). You can turn shadows off temporarily but they can never - be turned on if they were not at the time of the build. - */ - virtual void setCastShadows(bool castShadows); - /// Will the geometry from this object cast shadows? - virtual bool getCastShadows(void) { return mCastShadows; } - - /** Sets the size of a single BatchInstance of geometry. - @remarks - This method allows you to configure the physical world size of - each BatchInstance, so you can balance culling against batch size. Entities - will be fitted within the batch they most closely fit, and the - eventual bounds of each batch may well be slightly larger than this - if they overlap a little. The default is Vector3(1000, 1000, 1000). - @note Must be called before 'build'. - @param size Vector3 expressing the 3D size of each BatchInstance. - */ - virtual void setBatchInstanceDimensions(const Vector3& size) { - mBatchInstanceDimensions = size; - mHalfBatchInstanceDimensions = size * 0.5; - } - /** Gets the size of a single batch of geometry. */ - virtual const Vector3& getBatchInstanceDimensions(void) const { return mBatchInstanceDimensions; } - /** Sets the origin of the geometry. - @remarks - This method allows you to configure the world centre of the geometry, - thus the place which all BatchInstances surround. You probably don't need - to mess with this unless you have a seriously large world, since the - default set up can handle an area 1024 * mBatchInstanceDimensions, and - the sparseness of population is no issue when it comes to rendering. - The default is Vector3(0,0,0). - @note Must be called before 'build'. - @param origin Vector3 expressing the 3D origin of the geometry. - */ - virtual void setOrigin(const Vector3& origin) { mOrigin = origin; } - /** Gets the origin of this geometry. */ - virtual const Vector3& getOrigin(void) const { return mOrigin; } + @param node Pointer to the node to use to provide a set of Entity + templates + */ + virtual void addSceneNode(const SceneNode* node); + + /** Build the geometry. + @remarks + Based on all the entities which have been added, and the batching + options which have been set, this method constructs the batched + geometry structures required. The batches are added to the scene + and will be rendered unless you specifically hide them. + @note + Once you have called this method, you can no longer add any more + entities. + */ + virtual void build(void); + /** Add a new batch instance + @remarks + This method add a new instance of the whole batch, by creating a new + BatchInstance, containing new LOD buckets, material buckets and geometry buckets. + The new geometry buckets will use the same buffers as the base bucket. + @note + no note + */ + void addBatchInstance(void); + /** Destroys all the built geometry state (reverse of build). + @remarks + You can call build() again after this and it will pick up all the + same entities / nodes you queued last time. + */ + virtual void destroy(void); + + /** Clears any of the entities / nodes added to this geometry and + destroys anything which has already been built. + */ + virtual void reset(void); + + /** Sets the distance at which batches are no longer rendered. + @remarks + This lets you turn off batches at a given distance. This can be + useful for things like detail meshes (grass, foliage etc) and could + be combined with a shader which fades the geometry out beforehand + to lessen the effect. + @param dist Distance beyond which the batches will not be rendered + (the default is 0, which means batches are always rendered). + */ + virtual void setRenderingDistance(Real dist) { + mUpperDistance = dist; + mSquaredUpperDistance = mUpperDistance * mUpperDistance; + } + + /** Gets the distance at which batches are no longer rendered. */ + virtual Real getRenderingDistance(void) const { return mUpperDistance; } + + /** Gets the squared distance at which batches are no longer rendered. */ + virtual Real getSquaredRenderingDistance(void) const + { return mSquaredUpperDistance; } + + /** Hides or shows all the batches. */ + virtual void setVisible(bool visible); + + /** Are the batches visible? */ + virtual bool isVisible(void) const { return mVisible; } + + /** Sets whether this geometry should cast shadows. + @remarks + No matter what the settings on the original entities, + the InstancedGeometry class defaults to not casting shadows. + This is because, being static, unless you have moving lights + you'd be better to use precalculated shadows of some sort. + However, if you need them, you can enable them using this + method. If the SceneManager is set up to use stencil shadows, + edge lists will be copied from the underlying meshes on build. + It is essential that all meshes support stencil shadows in this + case. + @note If you intend to use stencil shadows, you must set this to + true before calling 'build' as well as making sure you set the + scene's shadow type (that should always be the first thing you do + anyway). You can turn shadows off temporarily but they can never + be turned on if they were not at the time of the build. + */ + virtual void setCastShadows(bool castShadows); + /// Will the geometry from this object cast shadows? + virtual bool getCastShadows(void) { return mCastShadows; } + + /** Sets the size of a single BatchInstance of geometry. + @remarks + This method allows you to configure the physical world size of + each BatchInstance, so you can balance culling against batch size. Entities + will be fitted within the batch they most closely fit, and the + eventual bounds of each batch may well be slightly larger than this + if they overlap a little. The default is Vector3(1000, 1000, 1000). + @note Must be called before 'build'. + @param size Vector3 expressing the 3D size of each BatchInstance. + */ + virtual void setBatchInstanceDimensions(const Vector3& size) { + mBatchInstanceDimensions = size; + mHalfBatchInstanceDimensions = size * 0.5; + } + /** Gets the size of a single batch of geometry. */ + virtual const Vector3& getBatchInstanceDimensions(void) const { return mBatchInstanceDimensions; } + /** Sets the origin of the geometry. + @remarks + This method allows you to configure the world centre of the geometry, + thus the place which all BatchInstances surround. You probably don't need + to mess with this unless you have a seriously large world, since the + default set up can handle an area 1024 * mBatchInstanceDimensions, and + the sparseness of population is no issue when it comes to rendering. + The default is Vector3(0,0,0). + @note Must be called before 'build'. + @param origin Vector3 expressing the 3D origin of the geometry. + */ + virtual void setOrigin(const Vector3& origin) { mOrigin = origin; } + /** Gets the origin of this geometry. */ + virtual const Vector3& getOrigin(void) const { return mOrigin; } /** Sets the render queue group this object will be rendered through. @remarks Render queues are grouped to allow you to more tightly control the ordering of rendered objects. If you do not call this method, all objects default to the default queue (RenderQueue::getDefaultQueueGroup), which is fine for - most objects. You may want to alter this if you want to perform more complex - rendering. + most objects. You may want to alter this if you want to perform more complex + rendering. @par See RenderQueue for more details. @param queueID Enumerated value of the queue group to use. @@ -828,46 +828,46 @@ namespace Ogre { /** Gets the queue group for this entity, see setRenderQueueGroup for full details. */ virtual uint8 getRenderQueueGroup(void) const; - /// Iterator for iterating over contained BatchInstances - typedef MapIterator BatchInstanceIterator; - /// Get an iterator over the BatchInstances in this geometry - BatchInstanceIterator getBatchInstanceIterator(void); - /// get the mRenderOps vector. - RenderOperationVector& getRenderOperationVector(){return mRenderOps;} - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false); - - /** Dump the contents of this InstancedGeometry to a file for diagnostic - purposes. - */ - virtual void dump(const String& filename) const; - /** - @remarks - Return the skeletonInstance that will be used - */ - SkeletonInstance *getBaseSkeletonInstance(void){return mSkeletonInstance;} - /** - @remarks - Return the skeleton that is shared by all instanced objects. - */ - SkeletonPtr getBaseSkeleton(void){return mBaseSkeleton;} - /** - @remarks - Return the animation state that will be cloned each time an InstancedObject is made - */ - AnimationStateSet* getBaseAnimationState(void){return mAnimationState;} - /** - @remarks - return the total number of object that are in all the batches - */ - unsigned int getObjectCount(void){return mObjectCount;} + /// Iterator for iterating over contained BatchInstances + typedef MapIterator BatchInstanceIterator; + /// Get an iterator over the BatchInstances in this geometry + BatchInstanceIterator getBatchInstanceIterator(void); + /// get the mRenderOps vector. + RenderOperationVector& getRenderOperationVector(){return mRenderOps;} + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false); + + /** Dump the contents of this InstancedGeometry to a file for diagnostic + purposes. + */ + virtual void dump(const String& filename) const; + /** + @remarks + Return the skeletonInstance that will be used + */ + SkeletonInstance *getBaseSkeletonInstance(void){return mSkeletonInstance;} + /** + @remarks + Return the skeleton that is shared by all instanced objects. + */ + SkeletonPtr getBaseSkeleton(void){return mBaseSkeleton;} + /** + @remarks + Return the animation state that will be cloned each time an InstancedObject is made + */ + AnimationStateSet* getBaseAnimationState(void){return mAnimationState;} + /** + @remarks + return the total number of object that are in all the batches + */ + unsigned int getObjectCount(void){return mObjectCount;} /** @remarks Allows World Transform Inverse matrices to be passed as shader constants along with the world transform matrix list. Reduces the number of usable geometries in an instance to 40 instead of 80. - The inverse matrices are interleaved with the world matrices at n+1. + The inverse matrices are interleaved with the world matrices at n+1. */ virtual void setProvideWorldInverses(bool flag); @@ -877,10 +877,10 @@ namespace Ogre { be passed to the shaders. */ virtual bool getProvideWorldInverses(void) const { return mProvideWorldInverses; } - }; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreIteratorRange.h b/OgreMain/include/OgreIteratorRange.h index 5d14c39ccb9..57f8b0cf82e 100644 --- a/OgreMain/include/OgreIteratorRange.h +++ b/OgreMain/include/OgreIteratorRange.h @@ -69,62 +69,62 @@ template class iterator_range{ #if !OGRE_USE_BOOST - - T mBegin, mEnd; - - public : - + + T mBegin, mEnd; + + public : + /** Constructor. @remarks Provide a start and end iterator to initialise. */ - iterator_range( T b , T e ) : mBegin(b) , mEnd(e){} - - ///access to the begin of the range - T begin() const { return mBegin; } - - ///access to the end of the range - T end() const { return mEnd; } - - ///informs if there are any elements in the range - bool empty() const { return mBegin = mEnd ; } - - ///comparison for equality - bool equal( const iterator_range& other ) const - {return mBegin == other.mBegin && mEnd == other.mEnd;} - - ///comparison operator for equality - bool operator==( const iterator_range& rhs ) const - {return equal( rhs ) ;} - - ///comparison operator for inequality - bool operator!=( const iterator_range& rhs ) const { return !operator==(rhs); } - - /** - @brief typedef to fulfill container interface - - @note there is no distinction between const_iterator and iterator. - - */ - typedef T iterator; - - /** - @brief typedef to fulfill container interface - - @note there is no distinction between const_iterator and iterator. - - */ - typedef T const_iterator; - - /// defines the real used type - /** - type will be defined as Ogre::iterator_range if not used with boost - \n otherwise the type will be boost::iterator_range - */ - typedef iterator_range type; + iterator_range( T b , T e ) : mBegin(b) , mEnd(e){} + + ///access to the begin of the range + T begin() const { return mBegin; } + + ///access to the end of the range + T end() const { return mEnd; } + + ///informs if there are any elements in the range + bool empty() const { return mBegin = mEnd ; } + + ///comparison for equality + bool equal( const iterator_range& other ) const + {return mBegin == other.mBegin && mEnd == other.mEnd;} + + ///comparison operator for equality + bool operator==( const iterator_range& rhs ) const + {return equal( rhs ) ;} + + ///comparison operator for inequality + bool operator!=( const iterator_range& rhs ) const { return !operator==(rhs); } + + /** + @brief typedef to fulfill container interface + + @note there is no distinction between const_iterator and iterator. + + */ + typedef T iterator; + + /** + @brief typedef to fulfill container interface + + @note there is no distinction between const_iterator and iterator. + + */ + typedef T const_iterator; + + /// defines the real used type + /** + type will be defined as Ogre::iterator_range if not used with boost + \n otherwise the type will be boost::iterator_range + */ + typedef iterator_range type; #else - /// defines (this) type as boost::iterator_range - public: typedef boost::iterator_range type ; + /// defines (this) type as boost::iterator_range + public: typedef boost::iterator_range type ; #endif }; @@ -142,35 +142,35 @@ template struct VectorRange : public iterator_range::type { - /** Constructor. - @remarks - Provide a container to initialise. - */ - VectorRange( T& c ) - : iterator_range::type( c.begin(), c.end() ) - {} + /** Constructor. + @remarks + Provide a container to initialise. + */ + VectorRange( T& c ) + : iterator_range::type( c.begin(), c.end() ) + {} - /** Constructor. - @remarks - Provide a start and end iterator to initialise. - */ - VectorRange( typename T::iterator b, typename T::iterator e ) - : iterator_range::type( b, e ) - {} + /** Constructor. + @remarks + Provide a start and end iterator to initialise. + */ + VectorRange( typename T::iterator b, typename T::iterator e ) + : iterator_range::type( b, e ) + {} - ///comparison operator for equality - bool operator==( const VectorRange& rhs ) const { return equal( rhs) ; } - ///comparison operator for inequality - bool operator!=( const VectorRange& rhs ) const { return !equal( rhs) ; } + ///comparison operator for equality + bool operator==( const VectorRange& rhs ) const { return equal( rhs) ; } + ///comparison operator for inequality + bool operator!=( const VectorRange& rhs ) const { return !equal( rhs) ; } #ifdef __Ogre_Iterator_Wrapper_H__ - ///cast operator to a VectorIterator - operator VectorIterator(){return VectorIterator( this->begin(), this->end());} - ///cast operator to a ConstVectorIterator - operator ConstVectorIterator(){return ConstVectorIterator( this->begin(), this->end());} + ///cast operator to a VectorIterator + operator VectorIterator(){return VectorIterator( this->begin(), this->end());} + ///cast operator to a ConstVectorIterator + operator ConstVectorIterator(){return ConstVectorIterator( this->begin(), this->end());} #endif - + }; /** @@ -185,51 +185,51 @@ template struct ConstVectorRange : public iterator_range::type { - /** Constructor. - @remarks - Provide a container to initialise. - */ - ConstVectorRange( const T& c ) - : iterator_range::type( c.begin(), c.end() ) - {} - - /** Constructor. - @remarks - Provide a start and end iterator to initialise. - */ - ConstVectorRange( typename T::iterator b, typename T::iterator e ) - : iterator_range::type( b, e ) - {} - - /** Constructor. - @remarks - Provide a start and end const_iterator to initialise. - */ - ConstVectorRange( typename T::const_iterator b, typename T::const_iterator e ) - : iterator_range::type( b, e ) - {} - - /** Constructor. - @remarks - Provide a VectorRange to initialise. - */ - ConstVectorRange( const VectorRange& rhs ) - : iterator_range::type( rhs.begin(), rhs.end() ) - {} - - ///comparison operator for equality - bool operator==( const ConstVectorRange& rhs ) const { return equal( rhs) ; } - ///comparison operator for inequality - bool operator!=( const ConstVectorRange& rhs ) const { return !equal( rhs) ; } - - + /** Constructor. + @remarks + Provide a container to initialise. + */ + ConstVectorRange( const T& c ) + : iterator_range::type( c.begin(), c.end() ) + {} + + /** Constructor. + @remarks + Provide a start and end iterator to initialise. + */ + ConstVectorRange( typename T::iterator b, typename T::iterator e ) + : iterator_range::type( b, e ) + {} + + /** Constructor. + @remarks + Provide a start and end const_iterator to initialise. + */ + ConstVectorRange( typename T::const_iterator b, typename T::const_iterator e ) + : iterator_range::type( b, e ) + {} + + /** Constructor. + @remarks + Provide a VectorRange to initialise. + */ + ConstVectorRange( const VectorRange& rhs ) + : iterator_range::type( rhs.begin(), rhs.end() ) + {} + + ///comparison operator for equality + bool operator==( const ConstVectorRange& rhs ) const { return equal( rhs) ; } + ///comparison operator for inequality + bool operator!=( const ConstVectorRange& rhs ) const { return !equal( rhs) ; } + + #ifdef __Ogre_Iterator_Wrapper_H__ - ///cast operator to a ConstVectorIterator - operator ConstVectorIterator(){return ConstVectorIterator( this->begin(),this->end());} + ///cast operator to a ConstVectorIterator + operator ConstVectorIterator(){return ConstVectorIterator( this->begin(),this->end());} #endif - + }; @@ -245,35 +245,35 @@ struct ConstVectorRange : public iterator_range::typ template struct MapRange : public iterator_range::type { - /** Constructor. - @remarks - Provide a container to initialise. - */ - MapRange( T& c ) - : iterator_range::type( c.begin(), c.end() ) - {} - - /** Constructor. - @remarks - Provide a start and end iterator to initialise. - */ - MapRange( typename T::iterator b, typename T::iterator e ) - : iterator_range::type( b, e ) - {} - - ///comparison operator for equality - bool operator==( const MapRange& rhs ) const { return equal( rhs) ; } - ///comparison operator for inequality - bool operator!=( const MapRange& rhs ) const { return !equal( rhs) ; } + /** Constructor. + @remarks + Provide a container to initialise. + */ + MapRange( T& c ) + : iterator_range::type( c.begin(), c.end() ) + {} + + /** Constructor. + @remarks + Provide a start and end iterator to initialise. + */ + MapRange( typename T::iterator b, typename T::iterator e ) + : iterator_range::type( b, e ) + {} + + ///comparison operator for equality + bool operator==( const MapRange& rhs ) const { return equal( rhs) ; } + ///comparison operator for inequality + bool operator!=( const MapRange& rhs ) const { return !equal( rhs) ; } #ifdef __Ogre_Iterator_Wrapper_H__ - ///cast operator to a MapIterator - operator MapIterator(){return MapIterator( this->begin(), this->end());} - ///cast operator to a ConstMapIterator - operator ConstMapIterator(){return ConstMapIterator( this->begin(), this->end());} + ///cast operator to a MapIterator + operator MapIterator(){return MapIterator( this->begin(), this->end());} + ///cast operator to a ConstMapIterator + operator ConstMapIterator(){return ConstMapIterator( this->begin(), this->end());} #endif - + }; /** @@ -288,49 +288,49 @@ template struct ConstMapRange : public iterator_range::type { - /** Constructor. - @remarks - Provide a container to initialise. - */ - ConstMapRange( const T& c ) - : iterator_range::type( c.begin(), c.end() ) - {} - - /** Constructor. - @remarks - Provide a start and end iterator to initialise. - */ - ConstMapRange( typename T::iterator b, typename T::iterator e ) - : iterator_range::type( b, e ) - {} - - /** Constructor. - @remarks - Provide a start and end const_iterator to initialise. - */ - ConstMapRange( typename T::const_iterator b, typename T::const_iterator e ) - : iterator_range::type( b, e ) - {} - - /** Constructor. - @remarks - Provide a MapRange to initialise. - */ - ConstMapRange( const MapRange& rhs ) - : iterator_range::type( rhs.begin(), rhs.end() ) - {} - - ///comparison operator for equality - bool operator==( const ConstMapRange& rhs ) const { return equal( rhs) ; } - ///comparison operator for inequality - bool operator!=( const ConstMapRange& rhs ) const { return !equal( rhs) ; } + /** Constructor. + @remarks + Provide a container to initialise. + */ + ConstMapRange( const T& c ) + : iterator_range::type( c.begin(), c.end() ) + {} + + /** Constructor. + @remarks + Provide a start and end iterator to initialise. + */ + ConstMapRange( typename T::iterator b, typename T::iterator e ) + : iterator_range::type( b, e ) + {} + + /** Constructor. + @remarks + Provide a start and end const_iterator to initialise. + */ + ConstMapRange( typename T::const_iterator b, typename T::const_iterator e ) + : iterator_range::type( b, e ) + {} + + /** Constructor. + @remarks + Provide a MapRange to initialise. + */ + ConstMapRange( const MapRange& rhs ) + : iterator_range::type( rhs.begin(), rhs.end() ) + {} + + ///comparison operator for equality + bool operator==( const ConstMapRange& rhs ) const { return equal( rhs) ; } + ///comparison operator for inequality + bool operator!=( const ConstMapRange& rhs ) const { return !equal( rhs) ; } #ifdef __Ogre_Iterator_Wrapper_H__ - ///cast operator to a ConstMapIterator - operator ConstMapIterator(){return ConstMapIterator( this->begin(),this->end());} + ///cast operator to a ConstMapIterator + operator ConstMapIterator(){return ConstMapIterator( this->begin(),this->end());} #endif - + }; #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreIteratorWrapper.h b/OgreMain/include/OgreIteratorWrapper.h index 69d3efb70bd..e7bb3835c2d 100644 --- a/OgreMain/include/OgreIteratorWrapper.h +++ b/OgreMain/include/OgreIteratorWrapper.h @@ -47,75 +47,75 @@ template class IteratorWrapper { - private: - /// Private constructor since only the parameterised constructor should be used - IteratorWrapper(); - - protected: - IteratorType mBegin; - IteratorType mCurrent; - IteratorType mEnd; - - - public: - - /// Type you expect to get by funktions like peekNext(Value) - typedef ValType ValueType; - /// Type you expect to get by funktions like peekNext(Value)Ptr - typedef ValType* PointerType; - - /** - @brief Typedef to fulfill container interface - - Useful if you want to use BOOST_FOREACH - @note there is no distinction between const_iterator and iterator. - \n keep this in mind if you want to derivate from this class. - */ - typedef IteratorType iterator; - - /** - @brief Typedef to fulfill container interface - - Useful if you want to use BOOST_FOREACH - @note there is no distinction between const_iterator and iterator. - \n keep this in mind if you want to derivate from this class. - */ - typedef IteratorType const_iterator; - - + private: + /// Private constructor since only the parameterised constructor should be used + IteratorWrapper(); + + protected: + IteratorType mBegin; + IteratorType mCurrent; + IteratorType mEnd; + + + public: + + /// Type you expect to get by funktions like peekNext(Value) + typedef ValType ValueType; + /// Type you expect to get by funktions like peekNext(Value)Ptr + typedef ValType* PointerType; + + /** + @brief Typedef to fulfill container interface + + Useful if you want to use BOOST_FOREACH + @note there is no distinction between const_iterator and iterator. + \n keep this in mind if you want to derivate from this class. + */ + typedef IteratorType iterator; + + /** + @brief Typedef to fulfill container interface + + Useful if you want to use BOOST_FOREACH + @note there is no distinction between const_iterator and iterator. + \n keep this in mind if you want to derivate from this class. + */ + typedef IteratorType const_iterator; + + /** Constructor. @remarks Provide a start and end iterator to initialise. */ - IteratorWrapper ( IteratorType start, IteratorType last ) - : mBegin( start ), mCurrent ( start ), mEnd ( last ) - { - } - - - /** Returns true if there are more items in the collection. */ - bool hasMoreElements ( ) const - { - return mCurrent != mEnd; - } - - - /** Moves the iterator on one element. */ - void moveNext ( ) - { - ++mCurrent; - } - - /** Bookmark to the begin of the underlying collection */ - const IteratorType& begin() {return mBegin;} - - - /** Full access to the current iterator */ - IteratorType& current(){return mCurrent;} - - /** Bookmark to the end (one behind the last element) of the underlying collection */ - const IteratorType& end() {return mEnd;} - + IteratorWrapper ( IteratorType start, IteratorType last ) + : mBegin( start ), mCurrent ( start ), mEnd ( last ) + { + } + + + /** Returns true if there are more items in the collection. */ + bool hasMoreElements ( ) const + { + return mCurrent != mEnd; + } + + + /** Moves the iterator on one element. */ + void moveNext ( ) + { + ++mCurrent; + } + + /** Bookmark to the begin of the underlying collection */ + const IteratorType& begin() {return mBegin;} + + + /** Full access to the current iterator */ + IteratorType& current(){return mCurrent;} + + /** Bookmark to the end (one behind the last element) of the underlying collection */ + const IteratorType& end() {return mEnd;} + }; @@ -135,42 +135,42 @@ template class VectorIteratorWrapper : public IteratorWrapper { - public: - typedef typename IteratorWrapper::ValueType ValueType ; - typedef typename IteratorWrapper::PointerType PointerType ; - - - /** - * @brief c'tor - * - * Constructor that provide a start and end iterator to initialise. - * - * @param start Start iterator - * @param last End iterator - */ - VectorIteratorWrapper ( IteratorType start, IteratorType last ) - : IteratorWrapper( start, last ) - { - } - - - /** Returns the next(=current) element in the collection, without advancing to the next. */ - ValueType peekNext ( ) const - { - return *(this->mCurrent); - } - - /** Returns a pointer to the next(=current) element in the collection, without advancing to the next afterwards. */ - PointerType peekNextPtr ( ) const - { - return &(*(this->mCurrent) ); - } - - /** Returns the next(=current) value element in the collection, and advances to the next. */ - ValueType getNext ( ) - { - return *(this->mCurrent++); - } + public: + typedef typename IteratorWrapper::ValueType ValueType ; + typedef typename IteratorWrapper::PointerType PointerType ; + + + /** + * @brief c'tor + * + * Constructor that provide a start and end iterator to initialise. + * + * @param start Start iterator + * @param last End iterator + */ + VectorIteratorWrapper ( IteratorType start, IteratorType last ) + : IteratorWrapper( start, last ) + { + } + + + /** Returns the next(=current) element in the collection, without advancing to the next. */ + ValueType peekNext ( ) const + { + return *(this->mCurrent); + } + + /** Returns a pointer to the next(=current) element in the collection, without advancing to the next afterwards. */ + PointerType peekNextPtr ( ) const + { + return &(*(this->mCurrent) ); + } + + /** Returns the next(=current) value element in the collection, and advances to the next. */ + ValueType getNext ( ) + { + return *(this->mCurrent++); + } }; @@ -184,25 +184,25 @@ class VectorIteratorWrapper : public IteratorWrapper class VectorIterator : public VectorIteratorWrapper{ - public: + public: /** Constructor. @remarks Provide a start and end iterator to initialise. - */ - VectorIterator( typename T::iterator start, typename T::iterator last ) - : VectorIteratorWrapper(start , last ) - { - } + */ + VectorIterator( typename T::iterator start, typename T::iterator last ) + : VectorIteratorWrapper(start , last ) + { + } /** Constructor. @remarks Provide a container to initialise. */ - explicit VectorIterator( T& c ) - : VectorIteratorWrapper ( c.begin(), c.end() ) - { - } - + explicit VectorIterator( T& c ) + : VectorIteratorWrapper ( c.begin(), c.end() ) + { + } + }; /** @@ -215,24 +215,24 @@ class VectorIterator : public VectorIteratorWrapper{ */ template class ConstVectorIterator : public VectorIteratorWrapper{ - public: + public: /** Constructor. @remarks Provide a start and end iterator to initialise. - */ - ConstVectorIterator( typename T::const_iterator start, typename T::const_iterator last ) - : VectorIteratorWrapper (start , last ) - { - } + */ + ConstVectorIterator( typename T::const_iterator start, typename T::const_iterator last ) + : VectorIteratorWrapper (start , last ) + { + } /** Constructor. @remarks Provide a container to initialise. */ - explicit ConstVectorIterator ( const T& c ) - : VectorIteratorWrapper (c.begin() , c.end() ) - { - } + explicit ConstVectorIterator ( const T& c ) + : VectorIteratorWrapper (c.begin() , c.end() ) + { + } }; @@ -253,25 +253,25 @@ template class MapIteratorWrapper : public IteratorWrapper { - public: - /// Redefined ValueType for a map/set - typedef typename IteratorWrapper::ValueType ValueType ; - /// Redefined PointerType for a map/set - typedef typename IteratorWrapper::PointerType PointerType ; - - /// Unused, just to make it clear that map/set::value_type is not a ValueType - typedef typename T::value_type PairType ; - /// Type you expect to get by funktions like peekNextKey - typedef typename T::key_type KeyType; + public: + /// Redefined ValueType for a map/set + typedef typename IteratorWrapper::ValueType ValueType ; + /// Redefined PointerType for a map/set + typedef typename IteratorWrapper::PointerType PointerType ; + + /// Unused, just to make it clear that map/set::value_type is not a ValueType + typedef typename T::value_type PairType ; + /// Type you expect to get by funktions like peekNextKey + typedef typename T::key_type KeyType; /** Constructor. @remarks Provide a start and end iterator to initialise. */ - MapIteratorWrapper ( IteratorType start, IteratorType last ) - : IteratorWrapper( start, last ) - { - } + MapIteratorWrapper ( IteratorType start, IteratorType last ) + : IteratorWrapper( start, last ) + { + } /** Returns the next(=current) key element in the collection, without advancing to the next. */ KeyType peekNextKey(void) const @@ -280,27 +280,27 @@ class MapIteratorWrapper : public IteratorWrappermCurrent->second; - } + /** Returns the next(=current) value element in the collection, without advancing to the next. */ + ValueType peekNextValue ( ) const + { + return this->mCurrent->second; + } /** Returns a pointer to the next/current value element in the collection, without advancing to the next afterwards. */ - const PointerType peekNextValuePtr ( ) const - { - return &(this->mCurrent->second); - } + const PointerType peekNextValuePtr ( ) const + { + return &(this->mCurrent->second); + } /** Returns the next(=current) value element in the collection, and advances to the next. */ ValueType getNext() { return ((this->mCurrent++)->second) ; - } - + } + }; @@ -317,26 +317,26 @@ class MapIteratorWrapper : public IteratorWrapper class MapIterator : public MapIteratorWrapper{ - public: - + public: + /** Constructor. @remarks Provide a start and end iterator to initialise. - */ - MapIterator( typename T::iterator start, typename T::iterator last ) - : MapIteratorWrapper(start , last ) - { - } - + */ + MapIterator( typename T::iterator start, typename T::iterator last ) + : MapIteratorWrapper(start , last ) + { + } + /** Constructor. @remarks Provide a container to initialise. */ - explicit MapIterator( T& c ) - : MapIteratorWrapper ( c.begin(), c.end() ) - { - } - + explicit MapIterator( T& c ) + : MapIteratorWrapper ( c.begin(), c.end() ) + { + } + }; @@ -350,25 +350,25 @@ class MapIterator : public MapIteratorWrapper{ */ template class ConstMapIterator : public MapIteratorWrapper{ - public: - + public: + /** Constructor. @remarks Provide a start and end iterator to initialise. - */ - ConstMapIterator( typename T::const_iterator start, typename T::const_iterator last ) - : MapIteratorWrapper (start , last ) - { - } + */ + ConstMapIterator( typename T::const_iterator start, typename T::const_iterator last ) + : MapIteratorWrapper (start , last ) + { + } /** Constructor. @remarks Provide a container to initialise. */ - explicit ConstMapIterator ( const T& c ) - : MapIteratorWrapper (c.begin() , c.end() ) - { - } + explicit ConstMapIterator ( const T& c ) + : MapIteratorWrapper (c.begin() , c.end() ) + { + } }; diff --git a/OgreMain/include/OgreKeyFrame.h b/OgreMain/include/OgreKeyFrame.h index c3172eb52f9..409a0475df1 100644 --- a/OgreMain/include/OgreKeyFrame.h +++ b/OgreMain/include/OgreKeyFrame.h @@ -39,33 +39,33 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ - /** A key frame in an animation sequence defined by an AnimationTrack. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ + /** A key frame in an animation sequence defined by an AnimationTrack. @remarks This class can be used as a basis for all kinds of key frames. The unifying principle is that multiple KeyFrames define an animation sequence, with the exact state of the animation being an interpolation between these key frames. */ - class _OgreExport KeyFrame : public AnimationAlloc + class _OgreExport KeyFrame : public AnimationAlloc { public: /** Default constructor, you should not call this but use AnimationTrack::createKeyFrame instead. */ KeyFrame(const AnimationTrack* parent, Real time); - virtual ~KeyFrame() {} + virtual ~KeyFrame() {} /** Gets the time of this keyframe in the animation sequence. */ Real getTime(void) const { return mTime; } - /** Clone a keyframe (internal use only) */ - virtual KeyFrame* _clone(AnimationTrack* newParent) const; + /** Clone a keyframe (internal use only) */ + virtual KeyFrame* _clone(AnimationTrack* newParent) const; protected: @@ -74,181 +74,181 @@ namespace Ogre }; - /** Specialised KeyFrame which stores any numeric value. - */ - class _OgreExport NumericKeyFrame : public KeyFrame - { - public: - /** Default constructor, you should not call this but use AnimationTrack::createKeyFrame instead. */ - NumericKeyFrame(const AnimationTrack* parent, Real time); - ~NumericKeyFrame() {} - - /** Get the value at this keyframe. */ - virtual const AnyNumeric& getValue(void) const; - /** Set the value at this keyframe. - @remarks - All keyframe values must have a consistent type. - */ - virtual void setValue(const AnyNumeric& val); - - /** Clone a keyframe (internal use only) */ - KeyFrame* _clone(AnimationTrack* newParent) const; - protected: - AnyNumeric mValue; - }; - - - /** Specialised KeyFrame which stores a full transform. */ - class _OgreExport TransformKeyFrame : public KeyFrame - { - public: - /** Default constructor, you should not call this but use AnimationTrack::createKeyFrame instead. */ - TransformKeyFrame(const AnimationTrack* parent, Real time); - ~TransformKeyFrame() {} - /** Sets the translation associated with this keyframe. - @remarks - The translation factor affects how much the keyframe translates (moves) it's animable - object at it's time index. - @param trans The vector to translate by - */ - virtual void setTranslate(const Vector3& trans); - - /** Gets the translation applied by this keyframe. */ - const Vector3& getTranslate(void) const; - - /** Sets the scaling factor applied by this keyframe to the animable - object at it's time index. - @param scale The vector to scale by (beware of supplying zero values for any component of this - vector, it will scale the object to zero dimensions) - */ - virtual void setScale(const Vector3& scale); - - /** Gets the scaling factor applied by this keyframe. */ - virtual const Vector3& getScale(void) const; - - /** Sets the rotation applied by this keyframe. - @param rot The rotation applied; use Quaternion methods to convert from angle/axis or Matrix3 if - you don't like using Quaternions directly. - */ - virtual void setRotation(const Quaternion& rot); - - /** Gets the rotation applied by this keyframe. */ - virtual const Quaternion& getRotation(void) const; - - /** Clone a keyframe (internal use only) */ - KeyFrame* _clone(AnimationTrack* newParent) const; - protected: - Vector3 mTranslate; - Vector3 mScale; - Quaternion mRotate; - - - }; - - - - /** Specialised KeyFrame which stores absolute vertex positions for a complete - buffer, designed to be interpolated with other keys in the same track. - */ - class _OgreExport VertexMorphKeyFrame : public KeyFrame - { - public: - /** Default constructor, you should not call this but use AnimationTrack::createKeyFrame instead. */ - VertexMorphKeyFrame(const AnimationTrack* parent, Real time); - ~VertexMorphKeyFrame() {} - /** Sets the vertex buffer containing the source positions for this keyframe. - @remarks - We assume that positions are the first 3 float elements in this buffer, - although we don't necessarily assume they're the only ones in there. - @param buf Vertex buffer link; will not be modified so can be shared - read-only data - */ - void setVertexBuffer(const HardwareVertexBufferSharedPtr& buf); - - /** Gets the vertex buffer containing positions for this keyframe. */ - const HardwareVertexBufferSharedPtr& getVertexBuffer(void) const; - - /** Clone a keyframe (internal use only) */ - KeyFrame* _clone(AnimationTrack* newParent) const; - - protected: - HardwareVertexBufferSharedPtr mBuffer; - - }; - - /** Specialised KeyFrame which references a Mesh::Pose at a certain influence - level, which stores offsets for a subset of the vertices - in a buffer to provide a blendable pose. - */ - class _OgreExport VertexPoseKeyFrame : public KeyFrame - { - public: - /** Default constructor, you should not call this but use AnimationTrack::createKeyFrame instead. */ - VertexPoseKeyFrame(const AnimationTrack* parent, Real time); - ~VertexPoseKeyFrame() {} - - /** Reference to a pose at a given influence level - @remarks - Each keyframe can refer to many poses each at a given influence level. - **/ - struct PoseRef - { - /** The linked pose index. - @remarks - The Mesh contains all poses for all vertex data in one list, both - for the shared vertex data and the dedicated vertex data on submeshes. - The 'target' on the parent track must match the 'target' on the - linked pose. - */ - ushort poseIndex; - /** Influence level of the linked pose. - 1.0 for full influence (full offset), 0.0 for no influence. - */ - Real influence; - - PoseRef(ushort p, Real i) : poseIndex(p), influence(i) {} - }; - typedef vector::type PoseRefList; - - /** Add a new pose reference. - @see PoseRef - */ - void addPoseReference(ushort poseIndex, Real influence); - /** Update the influence of a pose reference. - @see PoseRef - */ - void updatePoseReference(ushort poseIndex, Real influence); - /** Remove reference to a given pose. - @param poseIndex The pose index (not the index of the reference) - */ - void removePoseReference(ushort poseIndex); - /** Remove all pose references. */ - void removeAllPoseReferences(void); - - - /** Get a const reference to the list of pose references. */ - const PoseRefList& getPoseReferences(void) const; - - typedef VectorIterator PoseRefIterator; - typedef ConstVectorIterator ConstPoseRefIterator; - - /** Get an iterator over the pose references. */ - PoseRefIterator getPoseReferenceIterator(void); - - /** Get a const iterator over the pose references. */ - ConstPoseRefIterator getPoseReferenceIterator(void) const; - - /** Clone a keyframe (internal use only) */ - KeyFrame* _clone(AnimationTrack* newParent) const; - - void _applyBaseKeyFrame(const VertexPoseKeyFrame* base); - - protected: - PoseRefList mPoseRefs; - - }; - /** @} */ - /** @} */ + /** Specialised KeyFrame which stores any numeric value. + */ + class _OgreExport NumericKeyFrame : public KeyFrame + { + public: + /** Default constructor, you should not call this but use AnimationTrack::createKeyFrame instead. */ + NumericKeyFrame(const AnimationTrack* parent, Real time); + ~NumericKeyFrame() {} + + /** Get the value at this keyframe. */ + virtual const AnyNumeric& getValue(void) const; + /** Set the value at this keyframe. + @remarks + All keyframe values must have a consistent type. + */ + virtual void setValue(const AnyNumeric& val); + + /** Clone a keyframe (internal use only) */ + KeyFrame* _clone(AnimationTrack* newParent) const; + protected: + AnyNumeric mValue; + }; + + + /** Specialised KeyFrame which stores a full transform. */ + class _OgreExport TransformKeyFrame : public KeyFrame + { + public: + /** Default constructor, you should not call this but use AnimationTrack::createKeyFrame instead. */ + TransformKeyFrame(const AnimationTrack* parent, Real time); + ~TransformKeyFrame() {} + /** Sets the translation associated with this keyframe. + @remarks + The translation factor affects how much the keyframe translates (moves) it's animable + object at it's time index. + @param trans The vector to translate by + */ + virtual void setTranslate(const Vector3& trans); + + /** Gets the translation applied by this keyframe. */ + const Vector3& getTranslate(void) const; + + /** Sets the scaling factor applied by this keyframe to the animable + object at it's time index. + @param scale The vector to scale by (beware of supplying zero values for any component of this + vector, it will scale the object to zero dimensions) + */ + virtual void setScale(const Vector3& scale); + + /** Gets the scaling factor applied by this keyframe. */ + virtual const Vector3& getScale(void) const; + + /** Sets the rotation applied by this keyframe. + @param rot The rotation applied; use Quaternion methods to convert from angle/axis or Matrix3 if + you don't like using Quaternions directly. + */ + virtual void setRotation(const Quaternion& rot); + + /** Gets the rotation applied by this keyframe. */ + virtual const Quaternion& getRotation(void) const; + + /** Clone a keyframe (internal use only) */ + KeyFrame* _clone(AnimationTrack* newParent) const; + protected: + Vector3 mTranslate; + Vector3 mScale; + Quaternion mRotate; + + + }; + + + + /** Specialised KeyFrame which stores absolute vertex positions for a complete + buffer, designed to be interpolated with other keys in the same track. + */ + class _OgreExport VertexMorphKeyFrame : public KeyFrame + { + public: + /** Default constructor, you should not call this but use AnimationTrack::createKeyFrame instead. */ + VertexMorphKeyFrame(const AnimationTrack* parent, Real time); + ~VertexMorphKeyFrame() {} + /** Sets the vertex buffer containing the source positions for this keyframe. + @remarks + We assume that positions are the first 3 float elements in this buffer, + although we don't necessarily assume they're the only ones in there. + @param buf Vertex buffer link; will not be modified so can be shared + read-only data + */ + void setVertexBuffer(const HardwareVertexBufferSharedPtr& buf); + + /** Gets the vertex buffer containing positions for this keyframe. */ + const HardwareVertexBufferSharedPtr& getVertexBuffer(void) const; + + /** Clone a keyframe (internal use only) */ + KeyFrame* _clone(AnimationTrack* newParent) const; + + protected: + HardwareVertexBufferSharedPtr mBuffer; + + }; + + /** Specialised KeyFrame which references a Mesh::Pose at a certain influence + level, which stores offsets for a subset of the vertices + in a buffer to provide a blendable pose. + */ + class _OgreExport VertexPoseKeyFrame : public KeyFrame + { + public: + /** Default constructor, you should not call this but use AnimationTrack::createKeyFrame instead. */ + VertexPoseKeyFrame(const AnimationTrack* parent, Real time); + ~VertexPoseKeyFrame() {} + + /** Reference to a pose at a given influence level + @remarks + Each keyframe can refer to many poses each at a given influence level. + **/ + struct PoseRef + { + /** The linked pose index. + @remarks + The Mesh contains all poses for all vertex data in one list, both + for the shared vertex data and the dedicated vertex data on submeshes. + The 'target' on the parent track must match the 'target' on the + linked pose. + */ + ushort poseIndex; + /** Influence level of the linked pose. + 1.0 for full influence (full offset), 0.0 for no influence. + */ + Real influence; + + PoseRef(ushort p, Real i) : poseIndex(p), influence(i) {} + }; + typedef vector::type PoseRefList; + + /** Add a new pose reference. + @see PoseRef + */ + void addPoseReference(ushort poseIndex, Real influence); + /** Update the influence of a pose reference. + @see PoseRef + */ + void updatePoseReference(ushort poseIndex, Real influence); + /** Remove reference to a given pose. + @param poseIndex The pose index (not the index of the reference) + */ + void removePoseReference(ushort poseIndex); + /** Remove all pose references. */ + void removeAllPoseReferences(void); + + + /** Get a const reference to the list of pose references. */ + const PoseRefList& getPoseReferences(void) const; + + typedef VectorIterator PoseRefIterator; + typedef ConstVectorIterator ConstPoseRefIterator; + + /** Get an iterator over the pose references. */ + PoseRefIterator getPoseReferenceIterator(void); + + /** Get a const iterator over the pose references. */ + ConstPoseRefIterator getPoseReferenceIterator(void) const; + + /** Clone a keyframe (internal use only) */ + KeyFrame* _clone(AnimationTrack* newParent) const; + + void _applyBaseKeyFrame(const VertexPoseKeyFrame* base); + + protected: + PoseRefList mPoseRefs; + + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreLight.h b/OgreMain/include/OgreLight.h index a9628504fb9..0e2f3f9f713 100644 --- a/OgreMain/include/OgreLight.h +++ b/OgreMain/include/OgreLight.h @@ -541,7 +541,7 @@ namespace Ogre { */ bool isInLightRange(const Ogre::Sphere& sphere) const; - /** Check whether a bounding box is included in the lighted area of the light + /** Check whether a bounding box is included in the lighted area of the light @note The function trades accuracy for efficiency. As a result you may get false-positives (The function should not return any false-negatives). diff --git a/OgreMain/include/OgreLodListener.h b/OgreMain/include/OgreLodListener.h index 054e0f9647a..1f91d8d57f0 100644 --- a/OgreMain/include/OgreLodListener.h +++ b/OgreMain/include/OgreLodListener.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup LOD - * @{ - */ - /// Struct containing information about a LOD change event for movable objects. + /** \addtogroup Core + * @{ + */ + /** \addtogroup LOD + * @{ + */ + /// Struct containing information about a LOD change event for movable objects. struct MovableObjectLodChangedEvent { /// The movable object whose level of detail has changed. @@ -200,8 +200,8 @@ namespace Ogre { { (void)evt; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreLodStrategy.h b/OgreMain/include/OgreLodStrategy.h index 8dd475710e0..933054af880 100755 --- a/OgreMain/include/OgreLodStrategy.h +++ b/OgreMain/include/OgreLodStrategy.h @@ -37,20 +37,20 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup LOD - * @{ - */ - /** Strategy for determining level of detail. + /** \addtogroup Core + * @{ + */ + /** \addtogroup LOD + * @{ + */ + /** Strategy for determining level of detail. @remarks Generally, to create a new LOD strategy, all of the following will need to be implemented: getValueImpl, getBaseValue, transformBias, getIndex, sort, and isSorted. In addition, transformUserValue may be overridden. */ - class _OgreExport LodStrategy : public LodAlloc + class _OgreExport LodStrategy : public LodAlloc { protected: /** Name of this strategy. */ @@ -124,8 +124,8 @@ namespace Ogre { static ushort getIndexDescending(Real value, const Material::LodValueList& materialLodValueList); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreLodStrategyManager.h b/OgreMain/include/OgreLodStrategyManager.h index ec934a102fe..47777a24765 100644 --- a/OgreMain/include/OgreLodStrategyManager.h +++ b/OgreMain/include/OgreLodStrategyManager.h @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup LOD - * @{ - */ - /** Manager for LOD strategies. */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup LOD + * @{ + */ + /** Manager for LOD strategies. */ class _OgreExport LodStrategyManager : public Singleton, public LodAlloc { /** Map of strategies. */ @@ -125,8 +125,8 @@ namespace Ogre { */ static LodStrategyManager* getSingletonPtr(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreLog.h b/OgreMain/include/OgreLog.h index dc8f650f331..df4a85d63e6 100644 --- a/OgreMain/include/OgreLog.h +++ b/OgreMain/include/OgreLog.h @@ -43,13 +43,13 @@ namespace pp namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - // LogMessageLevel + LoggingLevel > OGRE_LOG_THRESHOLD = message logged + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + // LogMessageLevel + LoggingLevel > OGRE_LOG_THRESHOLD = message logged #define OGRE_LOG_THRESHOLD 4 /** The level of detail to which the log will go into. @@ -73,7 +73,7 @@ namespace Ogre { /** @remarks Pure Abstract class, derive this class and register to the Log to listen to log messages */ class LogListener { - public: + public: virtual ~LogListener() {} /** @@ -87,8 +87,8 @@ namespace Ogre { If we are printing to the console or not @param logName The name of this log (so you can have several listeners for different logs, and identify them) - @param skipThisMessage - If set to true by the messageLogged() implementation message will not be logged + @param skipThisMessage + If set to true by the messageLogged() implementation message will not be logged */ virtual void messageLogged( const String& message, LogMessageLevel lml, bool maskDebug, const String &logName, bool& skipThisMessage ) = 0; }; @@ -100,23 +100,23 @@ namespace Ogre { @note
      Should not be used directly, but trough the LogManager class. */ - class _OgreExport Log : public LogAlloc + class _OgreExport Log : public LogAlloc { protected: - std::ofstream mLog; - LoggingLevel mLogLevel; - bool mDebugOut; - bool mSuppressFile; - bool mTimeStamp; - String mLogName; + std::ofstream mLog; + LoggingLevel mLogLevel; + bool mDebugOut; + bool mSuppressFile; + bool mTimeStamp; + String mLogName; typedef vector::type mtLogListener; mtLogListener mListeners; public: - class Stream; + class Stream; - OGRE_AUTO_MUTEX; // public to allow external locking + OGRE_AUTO_MUTEX; // public to allow external locking /** @remarks Usual constructor - called by LogManager. @@ -129,29 +129,29 @@ namespace Ogre { */ ~Log(); - /// Return the name of the log - const String& getName() const { return mLogName; } - /// Get whether debug output is enabled for this log - bool isDebugOutputEnabled() const { return mDebugOut; } - /// Get whether file output is suppressed for this log - bool isFileOutputSuppressed() const { return mSuppressFile; } - /// Get whether time stamps are printed for this log - bool isTimeStampEnabled() const { return mTimeStamp; } + /// Return the name of the log + const String& getName() const { return mLogName; } + /// Get whether debug output is enabled for this log + bool isDebugOutputEnabled() const { return mDebugOut; } + /// Get whether file output is suppressed for this log + bool isFileOutputSuppressed() const { return mSuppressFile; } + /// Get whether time stamps are printed for this log + bool isTimeStampEnabled() const { return mTimeStamp; } /** Log a message to the debugger and to log file (the default is "OGRE.log"), */ void logMessage( const String& message, LogMessageLevel lml = LML_NORMAL, bool maskDebug = false ); - /** Get a stream object targeting this log. */ - Stream stream(LogMessageLevel lml = LML_NORMAL, bool maskDebug = false); + /** Get a stream object targeting this log. */ + Stream stream(LogMessageLevel lml = LML_NORMAL, bool maskDebug = false); /** @remarks Enable or disable outputting log messages to the debugger. */ void setDebugOutputEnabled(bool debugOutput); - /** + /** @remarks Sets the level of the log detail. */ @@ -161,9 +161,9 @@ namespace Ogre { Enable or disable time stamps. */ void setTimeStampEnabled(bool timeStamp); - /** Gets the level of the log detail. - */ - LoggingLevel getLogDetail() const { return mLogLevel; } + /** Gets the level of the log detail. + */ + LoggingLevel getLogDetail() const { return mLogLevel; } /** @remarks Register a listener to this log @@ -180,76 +180,76 @@ namespace Ogre { */ void removeListener(LogListener* listener); - /** Stream object which targets a log. - @remarks - A stream logger object makes it simpler to send various things to - a log. You can just use the operator<< implementation to stream - anything to the log, which is cached until a Stream::Flush is - encountered, or the stream itself is destroyed, at which point the - cached contents are sent to the underlying log. You can use Log::stream() - directly without assigning it to a local variable and as soon as the - streaming is finished, the object will be destroyed and the message - logged. - @par - You can stream control operations to this object too, such as - std::setw() and std::setfill() to control formatting. - @note - Each Stream object is not thread safe, so do not pass it between - threads. Multiple threads can hold their own Stream instances pointing - at the same Log though and that is threadsafe. - */ - class _OgrePrivate Stream - { - protected: - Log* mTarget; - LogMessageLevel mLevel; - bool mMaskDebug; - typedef StringStream BaseStream; - BaseStream mCache; - - public: - - /// Simple type to indicate a flush of the stream to the log - struct Flush {}; - - Stream(Log* target, LogMessageLevel lml, bool maskDebug) - :mTarget(target), mLevel(lml), mMaskDebug(maskDebug) - { - - } - // copy constructor - Stream(const Stream& rhs) - : mTarget(rhs.mTarget), mLevel(rhs.mLevel), mMaskDebug(rhs.mMaskDebug) - { - // explicit copy of stream required, gcc doesn't like implicit - mCache.str(rhs.mCache.str()); - } - ~Stream() - { - // flush on destroy - if (mCache.tellp() > 0) - { - mTarget->logMessage(mCache.str(), mLevel, mMaskDebug); - } - } - - template - Stream& operator<< (const T& v) - { - mCache << v; - return *this; - } - - Stream& operator<< (const Flush& v) - { + /** Stream object which targets a log. + @remarks + A stream logger object makes it simpler to send various things to + a log. You can just use the operator<< implementation to stream + anything to the log, which is cached until a Stream::Flush is + encountered, or the stream itself is destroyed, at which point the + cached contents are sent to the underlying log. You can use Log::stream() + directly without assigning it to a local variable and as soon as the + streaming is finished, the object will be destroyed and the message + logged. + @par + You can stream control operations to this object too, such as + std::setw() and std::setfill() to control formatting. + @note + Each Stream object is not thread safe, so do not pass it between + threads. Multiple threads can hold their own Stream instances pointing + at the same Log though and that is threadsafe. + */ + class _OgrePrivate Stream + { + protected: + Log* mTarget; + LogMessageLevel mLevel; + bool mMaskDebug; + typedef StringStream BaseStream; + BaseStream mCache; + + public: + + /// Simple type to indicate a flush of the stream to the log + struct Flush {}; + + Stream(Log* target, LogMessageLevel lml, bool maskDebug) + :mTarget(target), mLevel(lml), mMaskDebug(maskDebug) + { + + } + // copy constructor + Stream(const Stream& rhs) + : mTarget(rhs.mTarget), mLevel(rhs.mLevel), mMaskDebug(rhs.mMaskDebug) + { + // explicit copy of stream required, gcc doesn't like implicit + mCache.str(rhs.mCache.str()); + } + ~Stream() + { + // flush on destroy + if (mCache.tellp() > 0) + { + mTarget->logMessage(mCache.str(), mLevel, mMaskDebug); + } + } + + template + Stream& operator<< (const T& v) + { + mCache << v; + return *this; + } + + Stream& operator<< (const Flush& v) + { (void)v; - mTarget->logMessage(mCache.str(), mLevel, mMaskDebug); - mCache.str(BLANKSTRING); - return *this; - } + mTarget->logMessage(mCache.str(), mLevel, mMaskDebug); + mCache.str(BLANKSTRING); + return *this; + } - }; + }; #if OGRE_PLATFORM == OGRE_PLATFORM_NACL protected: static pp::Instance* mInstance; @@ -258,8 +258,8 @@ namespace Ogre { #endif }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreLogManager.h b/OgreMain/include/OgreLogManager.h index 59a9a70ce61..c178724d0bc 100644 --- a/OgreMain/include/OgreLogManager.h +++ b/OgreMain/include/OgreLogManager.h @@ -37,13 +37,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** The log manager handles the creation and retrieval of logs for the + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** The log manager handles the creation and retrieval of logs for the application. @remarks This class will create new log files and will retrieve instances @@ -51,20 +51,20 @@ namespace Ogre create a fresh log or retrieve an existing one to output to. One log is the default log, and is the one written to when the logging methods of this class are called. - @par - By default, Root will instantiate a LogManager (which becomes the - Singleton instance) on construction, and will create a default log - based on the Root construction parameters. If you want more control, - for example redirecting log output right from the start or suppressing - debug output, you need to create a LogManager yourself before creating - a Root instance, then create a default log. Root will detect that - you've created one yourself and won't create one of its own, thus - using all your logging preferences from the first instance. + @par + By default, Root will instantiate a LogManager (which becomes the + Singleton instance) on construction, and will create a default log + based on the Root construction parameters. If you want more control, + for example redirecting log output right from the start or suppressing + debug output, you need to create a LogManager yourself before creating + a Root instance, then create a default log. Root will detect that + you've created one yourself and won't create one of its own, thus + using all your logging preferences from the first instance. */ class _OgreExport LogManager : public Singleton, public LogAlloc { - protected: - typedef map::type LogList; + protected: + typedef map::type LogList; /// A list of all the logs the manager can access LogList mLogs; @@ -91,11 +91,11 @@ namespace Ogre routed to the debugger's output window. @param suppressFileOutput If true, this is a logical rather than a physical - log and no file output will be written. If you do this you should - register a LogListener so log output is not lost. + log and no file output will be written. If you do this you should + register a LogListener so log output is not lost. */ Log* createLog( const String& name, bool defaultLog = false, bool debuggerOutput = true, - bool suppressFileOutput = false); + bool suppressFileOutput = false); /** Retrieves a log managed by this class. */ @@ -105,12 +105,12 @@ namespace Ogre */ Log* getDefaultLog(); - /** Closes and removes a named log. */ - void destroyLog(const String& name); - /** Closes and removes a log. */ - void destroyLog(Log* log); + /** Closes and removes a named log. */ + void destroyLog(const String& name); + /** Closes and removes a log. */ + void destroyLog(Log* log); - /** Sets the passed in log as the default log. + /** Sets the passed in log as the default log. @return The previous default log. */ Log* setDefaultLog(Log* newLog); @@ -123,13 +123,13 @@ namespace Ogre /** Log a message to the default log (signature for backward compatibility). */ void logMessage( LogMessageLevel lml, const String& message, - bool maskDebug = false) { logMessage(message, lml, maskDebug); } + bool maskDebug = false) { logMessage(message, lml, maskDebug); } - /** Get a stream on the default log. */ - Log::Stream stream(LogMessageLevel lml = LML_NORMAL, - bool maskDebug = false); + /** Get a stream on the default log. */ + Log::Stream stream(LogMessageLevel lml = LML_NORMAL, + bool maskDebug = false); - /** Sets the level of detail of the default log. + /** Sets the level of detail of the default log. */ void setLogDetail(LoggingLevel ll); /** Override standard Singleton retrieval. @@ -168,8 +168,8 @@ namespace Ogre }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreManualObject.h b/OgreMain/include/OgreManualObject.h index 026bf189fd4..68a6ac0dd99 100644 --- a/OgreMain/include/OgreManualObject.h +++ b/OgreMain/include/OgreManualObject.h @@ -37,534 +37,534 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Class providing a much simplified interface to generating manual - objects with custom geometry. - @remarks - Building one-off geometry objects manually usually requires getting - down and dirty with the vertex buffer and vertex declaration API, - which some people find a steep learning curve. This class gives you - a simpler interface specifically for the purpose of building a - 3D object simply and quickly. Note that if you intend to instance your - object you will still need to become familiar with the Mesh class. - @par - This class draws heavily on the interface for OpenGL - immediate-mode (glBegin, glVertex, glNormal etc), since this - is generally well-liked by people. There are a couple of differences - in the results though - internally this class still builds hardware - buffers which can be re-used, so you can render the resulting object - multiple times without re-issuing all the same commands again. - Secondly, the rendering is not immediate, it is still queued just like - all OGRE objects. This makes this object more efficient than the - equivalent GL immediate-mode commands, so it's feasible to use it for - large objects if you really want to. - @par - To construct some geometry with this object: - -# If you know roughly how many vertices (and indices, if you use them) - you're going to submit, call estimateVertexCount and estimateIndexCount. - This is not essential but will make the process more efficient by saving - memory reallocations. - -# Call begin() to begin entering data - -# For each vertex, call position(), normal(), textureCoord(), colour() - to define your vertex data. Note that each time you call position() - you start a new vertex. Note that the first vertex defines the - components of the vertex - you can't add more after that. For example - if you didn't call normal() in the first vertex, you cannot call it - in any others. You ought to call the same combination of methods per - vertex. - -# If you want to define triangles (or lines/points) by indexing into the vertex list, - you can call index() as many times as you need to define them. - If you don't do this, the class will assume you want triangles drawn - directly as defined by the vertex list, i.e. non-indexed geometry. Note - that stencil shadows are only supported on indexed geometry, and that - indexed geometry is a little faster; so you should try to use it. - -# Call end() to finish entering data. - -# Optionally repeat the begin-end cycle if you want more geometry - using different rendering operation types, or different materials - After calling end(), the class will organise the data for that section - internally and make it ready to render with. Like any other - MovableObject you should attach the object to a SceneNode to make it - visible. Other aspects like the relative render order can be controlled - using standard MovableObject methods like setRenderQueueGroup. - @par - You can also use beginUpdate() to alter the geometry later on if you wish. - If you do this, you should call setDynamic(true) before your first call - to begin(), and also consider using estimateVertexCount / estimateIndexCount - if your geometry is going to be growing, to avoid buffer recreation during - growth. - @par - Note that like all OGRE geometry, triangles should be specified in - anti-clockwise winding order (whether you're doing it with just - vertices, or using indexes too). That is to say that the front of the - face is the one where the vertices are listed in anti-clockwise order. - */ - class _OgreExport ManualObject : public MovableObject - { - public: - ManualObject(const String& name); - virtual ~ManualObject(); - - //pre-declare ManualObjectSection - class ManualObjectSection; - - /** Completely clear the contents of the object. - @remarks - Clearing the contents of this object and rebuilding from scratch - is not the optimal way to manage dynamic vertex data, since the - buffers are recreated. If you want to keep the same structure but - update the content within that structure, use beginUpdate() instead - of clear() begin(). However if you do want to modify the structure - from time to time you can do so by clearing and re-specifying the data. - */ - virtual void clear(void); - - /** Estimate the number of vertices ahead of time. - @remarks - Calling this helps to avoid memory reallocation when you define - vertices. Also very handy when using beginUpdate() to manage dynamic - data - you can make the vertex buffers a little larger than their - initial needs to allow for growth later with this method. - */ - virtual void estimateVertexCount(size_t vcount); - - /** Estimate the number of indices ahead of time. - @remarks - Calling this helps to avoid memory reallocation when you define - indices. Also very handy when using beginUpdate() to manage dynamic - data - you can make the index buffer a little larger than the - initial need to allow for growth later with this method. - */ - virtual void estimateIndexCount(size_t icount); - - /** Start defining a part of the object. - @remarks - Each time you call this method, you start a new section of the - object with its own material and potentially its own type of - rendering operation (triangles, points or lines for example). - @param materialName The name of the material to render this part of the - object with. - @param opType The type of operation to use to render. - */ - virtual void begin(const String& materialName, - RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST, const String & groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - /** Use before defining geometry to indicate that you intend to update the - geometry regularly and want the internal structure to reflect that. - */ - virtual void setDynamic(bool dyn) { mDynamic = dyn; } - /** Gets whether this object is marked as dynamic */ - virtual bool getDynamic() const { return mDynamic; } - - /** Start the definition of an update to a part of the object. - @remarks - Using this method, you can update an existing section of the object - efficiently. You do not have the option of changing the operation type - obviously, since it must match the one that was used before. - @note If your sections are changing size, particularly growing, use - estimateVertexCount and estimateIndexCount to pre-size the buffers a little - larger than the initial needs to avoid buffer reconstruction. - @param sectionIndex The index of the section you want to update. The first - call to begin() would have created section 0, the second section 1, etc. - */ - virtual void beginUpdate(size_t sectionIndex); - /** Add a vertex position, starting a new vertex at the same time. - @remarks A vertex position is slightly special among the other vertex data - methods like normal() and textureCoord(), since calling it indicates - the start of a new vertex. All other vertex data methods you call - after this are assumed to be adding more information (like normals or - texture coordinates) to the last vertex started with position(). - */ - virtual void position(const Vector3& pos); - /// @copydoc ManualObject::position(const Vector3&) - virtual void position(Real x, Real y, Real z); - - /** Add a vertex normal to the current vertex. - @remarks - Vertex normals are most often used for dynamic lighting, and - their components should be normalised. - */ - virtual void normal(const Vector3& norm); - /// @copydoc ManualObject::normal(const Vector3&) - virtual void normal(Real x, Real y, Real z); - - /** Add a vertex tangent to the current vertex. - @remarks - Vertex tangents are most often used for dynamic lighting, and - their components should be normalised. - Also, using tangent() you enable VES_TANGENT vertex semantic, which is not - supported on old non-SM2 cards. - */ - virtual void tangent(const Vector3& tan); - /// @copydoc ManualObject::tangent(const Vector3&) - virtual void tangent(Real x, Real y, Real z); - - /** Add a texture coordinate to the current vertex. - @remarks - You can call this method multiple times between position() calls - to add multiple texture coordinates to a vertex. Each one can have - between 1 and 3 dimensions, depending on your needs, although 2 is - most common. There are several versions of this method for the - variations in number of dimensions. - */ - virtual void textureCoord(Real u); - /// @copydoc ManualObject::textureCoord(Real) - virtual void textureCoord(Real u, Real v); - /// @copydoc ManualObject::textureCoord(Real) - virtual void textureCoord(Real u, Real v, Real w); - /// @copydoc ManualObject::textureCoord(Real) - virtual void textureCoord(Real x, Real y, Real z, Real w); - /// @copydoc ManualObject::textureCoord(Real) - virtual void textureCoord(const Vector2& uv); - /// @copydoc ManualObject::textureCoord(Real) - virtual void textureCoord(const Vector3& uvw); - /// @copydoc ManualObject::textureCoord(Real) - virtual void textureCoord(const Vector4& xyzw); - - /** Add a vertex colour to a vertex. - */ - virtual void colour(const ColourValue& col); - /** Add a vertex colour to a vertex. - @param r,g,b,a Colour components expressed as floating point numbers from 0-1 - */ - virtual void colour(Real r, Real g, Real b, Real a = 1.0f); - - /** Add a vertex index to construct faces / lines / points via indexing - rather than just by a simple list of vertices. - @remarks - You will have to call this 3 times for each face for a triangle list, - or use the alternative 3-parameter version. Other operation types - require different numbers of indexes, @see RenderOperation::OperationType. - @note - 32-bit indexes are not supported on all cards and will only be used + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Class providing a much simplified interface to generating manual + objects with custom geometry. + @remarks + Building one-off geometry objects manually usually requires getting + down and dirty with the vertex buffer and vertex declaration API, + which some people find a steep learning curve. This class gives you + a simpler interface specifically for the purpose of building a + 3D object simply and quickly. Note that if you intend to instance your + object you will still need to become familiar with the Mesh class. + @par + This class draws heavily on the interface for OpenGL + immediate-mode (glBegin, glVertex, glNormal etc), since this + is generally well-liked by people. There are a couple of differences + in the results though - internally this class still builds hardware + buffers which can be re-used, so you can render the resulting object + multiple times without re-issuing all the same commands again. + Secondly, the rendering is not immediate, it is still queued just like + all OGRE objects. This makes this object more efficient than the + equivalent GL immediate-mode commands, so it's feasible to use it for + large objects if you really want to. + @par + To construct some geometry with this object: + -# If you know roughly how many vertices (and indices, if you use them) + you're going to submit, call estimateVertexCount and estimateIndexCount. + This is not essential but will make the process more efficient by saving + memory reallocations. + -# Call begin() to begin entering data + -# For each vertex, call position(), normal(), textureCoord(), colour() + to define your vertex data. Note that each time you call position() + you start a new vertex. Note that the first vertex defines the + components of the vertex - you can't add more after that. For example + if you didn't call normal() in the first vertex, you cannot call it + in any others. You ought to call the same combination of methods per + vertex. + -# If you want to define triangles (or lines/points) by indexing into the vertex list, + you can call index() as many times as you need to define them. + If you don't do this, the class will assume you want triangles drawn + directly as defined by the vertex list, i.e. non-indexed geometry. Note + that stencil shadows are only supported on indexed geometry, and that + indexed geometry is a little faster; so you should try to use it. + -# Call end() to finish entering data. + -# Optionally repeat the begin-end cycle if you want more geometry + using different rendering operation types, or different materials + After calling end(), the class will organise the data for that section + internally and make it ready to render with. Like any other + MovableObject you should attach the object to a SceneNode to make it + visible. Other aspects like the relative render order can be controlled + using standard MovableObject methods like setRenderQueueGroup. + @par + You can also use beginUpdate() to alter the geometry later on if you wish. + If you do this, you should call setDynamic(true) before your first call + to begin(), and also consider using estimateVertexCount / estimateIndexCount + if your geometry is going to be growing, to avoid buffer recreation during + growth. + @par + Note that like all OGRE geometry, triangles should be specified in + anti-clockwise winding order (whether you're doing it with just + vertices, or using indexes too). That is to say that the front of the + face is the one where the vertices are listed in anti-clockwise order. + */ + class _OgreExport ManualObject : public MovableObject + { + public: + ManualObject(const String& name); + virtual ~ManualObject(); + + //pre-declare ManualObjectSection + class ManualObjectSection; + + /** Completely clear the contents of the object. + @remarks + Clearing the contents of this object and rebuilding from scratch + is not the optimal way to manage dynamic vertex data, since the + buffers are recreated. If you want to keep the same structure but + update the content within that structure, use beginUpdate() instead + of clear() begin(). However if you do want to modify the structure + from time to time you can do so by clearing and re-specifying the data. + */ + virtual void clear(void); + + /** Estimate the number of vertices ahead of time. + @remarks + Calling this helps to avoid memory reallocation when you define + vertices. Also very handy when using beginUpdate() to manage dynamic + data - you can make the vertex buffers a little larger than their + initial needs to allow for growth later with this method. + */ + virtual void estimateVertexCount(size_t vcount); + + /** Estimate the number of indices ahead of time. + @remarks + Calling this helps to avoid memory reallocation when you define + indices. Also very handy when using beginUpdate() to manage dynamic + data - you can make the index buffer a little larger than the + initial need to allow for growth later with this method. + */ + virtual void estimateIndexCount(size_t icount); + + /** Start defining a part of the object. + @remarks + Each time you call this method, you start a new section of the + object with its own material and potentially its own type of + rendering operation (triangles, points or lines for example). + @param materialName The name of the material to render this part of the + object with. + @param opType The type of operation to use to render. + */ + virtual void begin(const String& materialName, + RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST, const String & groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + /** Use before defining geometry to indicate that you intend to update the + geometry regularly and want the internal structure to reflect that. + */ + virtual void setDynamic(bool dyn) { mDynamic = dyn; } + /** Gets whether this object is marked as dynamic */ + virtual bool getDynamic() const { return mDynamic; } + + /** Start the definition of an update to a part of the object. + @remarks + Using this method, you can update an existing section of the object + efficiently. You do not have the option of changing the operation type + obviously, since it must match the one that was used before. + @note If your sections are changing size, particularly growing, use + estimateVertexCount and estimateIndexCount to pre-size the buffers a little + larger than the initial needs to avoid buffer reconstruction. + @param sectionIndex The index of the section you want to update. The first + call to begin() would have created section 0, the second section 1, etc. + */ + virtual void beginUpdate(size_t sectionIndex); + /** Add a vertex position, starting a new vertex at the same time. + @remarks A vertex position is slightly special among the other vertex data + methods like normal() and textureCoord(), since calling it indicates + the start of a new vertex. All other vertex data methods you call + after this are assumed to be adding more information (like normals or + texture coordinates) to the last vertex started with position(). + */ + virtual void position(const Vector3& pos); + /// @copydoc ManualObject::position(const Vector3&) + virtual void position(Real x, Real y, Real z); + + /** Add a vertex normal to the current vertex. + @remarks + Vertex normals are most often used for dynamic lighting, and + their components should be normalised. + */ + virtual void normal(const Vector3& norm); + /// @copydoc ManualObject::normal(const Vector3&) + virtual void normal(Real x, Real y, Real z); + + /** Add a vertex tangent to the current vertex. + @remarks + Vertex tangents are most often used for dynamic lighting, and + their components should be normalised. + Also, using tangent() you enable VES_TANGENT vertex semantic, which is not + supported on old non-SM2 cards. + */ + virtual void tangent(const Vector3& tan); + /// @copydoc ManualObject::tangent(const Vector3&) + virtual void tangent(Real x, Real y, Real z); + + /** Add a texture coordinate to the current vertex. + @remarks + You can call this method multiple times between position() calls + to add multiple texture coordinates to a vertex. Each one can have + between 1 and 3 dimensions, depending on your needs, although 2 is + most common. There are several versions of this method for the + variations in number of dimensions. + */ + virtual void textureCoord(Real u); + /// @copydoc ManualObject::textureCoord(Real) + virtual void textureCoord(Real u, Real v); + /// @copydoc ManualObject::textureCoord(Real) + virtual void textureCoord(Real u, Real v, Real w); + /// @copydoc ManualObject::textureCoord(Real) + virtual void textureCoord(Real x, Real y, Real z, Real w); + /// @copydoc ManualObject::textureCoord(Real) + virtual void textureCoord(const Vector2& uv); + /// @copydoc ManualObject::textureCoord(Real) + virtual void textureCoord(const Vector3& uvw); + /// @copydoc ManualObject::textureCoord(Real) + virtual void textureCoord(const Vector4& xyzw); + + /** Add a vertex colour to a vertex. + */ + virtual void colour(const ColourValue& col); + /** Add a vertex colour to a vertex. + @param r,g,b,a Colour components expressed as floating point numbers from 0-1 + */ + virtual void colour(Real r, Real g, Real b, Real a = 1.0f); + + /** Add a vertex index to construct faces / lines / points via indexing + rather than just by a simple list of vertices. + @remarks + You will have to call this 3 times for each face for a triangle list, + or use the alternative 3-parameter version. Other operation types + require different numbers of indexes, @see RenderOperation::OperationType. + @note + 32-bit indexes are not supported on all cards and will only be used when required, if an index is > 65535. - @param idx A vertex index from 0 to 4294967295. - */ - virtual void index(uint32 idx); - /** Add a set of 3 vertex indices to construct a triangle; this is a - shortcut to calling index() 3 times. It is only valid for triangle - lists. - @note - 32-bit indexes are not supported on all cards and will only be used + @param idx A vertex index from 0 to 4294967295. + */ + virtual void index(uint32 idx); + /** Add a set of 3 vertex indices to construct a triangle; this is a + shortcut to calling index() 3 times. It is only valid for triangle + lists. + @note + 32-bit indexes are not supported on all cards and will only be used when required, if an index is > 65535. - @param i1, i2, i3 3 vertex indices from 0 to 4294967295 defining a face. - */ - virtual void triangle(uint32 i1, uint32 i2, uint32 i3); - /** Add a set of 4 vertex indices to construct a quad (out of 2 - triangles); this is a shortcut to calling index() 6 times, - or triangle() twice. It's only valid for triangle list operations. - @note - 32-bit indexes are not supported on all cards and will only be used + @param i1, i2, i3 3 vertex indices from 0 to 4294967295 defining a face. + */ + virtual void triangle(uint32 i1, uint32 i2, uint32 i3); + /** Add a set of 4 vertex indices to construct a quad (out of 2 + triangles); this is a shortcut to calling index() 6 times, + or triangle() twice. It's only valid for triangle list operations. + @note + 32-bit indexes are not supported on all cards and will only be used when required, if an index is > 65535. - @param i1, i2, i3, i4 4 vertex indices from 0 to 4294967295 defining a quad. - */ - virtual void quad(uint32 i1, uint32 i2, uint32 i3, uint32 i4); - - /// Get the number of vertices in the section currently being defined (returns 0 if no section is in progress). - virtual size_t getCurrentVertexCount() const; - - /// Get the number of indices in the section currently being defined (returns 0 if no section is in progress). - virtual size_t getCurrentIndexCount() const; - - /** Finish defining the object and compile the final renderable version. - @note - Will return a pointer to the finished section or NULL if the section was discarded (i.e. has zero vertices/indices). - */ - virtual ManualObjectSection* end(void); - - /** Alter the material for a subsection of this object after it has been - specified. - @remarks - You specify the material to use on a section of this object during the - call to begin(), however if you want to change the material afterwards - you can do so by calling this method. - @param subIndex The index of the subsection to alter - @param name The name of the new material to use - */ - virtual void setMaterialName(size_t subIndex, const String& name, const String & group = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - /** Convert this object to a Mesh. - @remarks - After you've finished building this object, you may convert it to - a Mesh if you want in order to be able to create many instances of - it in the world (via Entity). This is optional, since this instance - can be directly attached to a SceneNode itself, but of course only - one instance of it can exist that way. - @note Only objects which use indexed geometry may be converted to a mesh. - @param meshName The name to give the mesh - @param groupName The resource group to create the mesh in - */ - virtual MeshPtr convertToMesh(const String& meshName, - const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - /** Sets whether or not to use an 'identity' projection. - @remarks - Usually ManualObjects will use a projection matrix as determined - by the active camera. However, if they want they can cancel this out - and use an identity projection, which effectively projects in 2D using - a {-1, 1} view space. Useful for overlay rendering. Normally you don't - need to change this. The default is false. - @see ManualObject::getUseIdentityProjection - */ - void setUseIdentityProjection(bool useIdentityProjection); - - /** Returns whether or not to use an 'identity' projection. - @remarks - Usually ManualObjects will use a projection matrix as determined - by the active camera. However, if they want they can cancel this out - and use an identity projection, which effectively projects in 2D using - a {-1, 1} view space. Useful for overlay rendering. Normally you don't - need to change this. - @see ManualObject::setUseIdentityProjection - */ - bool getUseIdentityProjection(void) const { return mUseIdentityProjection; } - - /** Sets whether or not to use an 'identity' view. - @remarks - Usually ManualObjects will use a view matrix as determined - by the active camera. However, if they want they can cancel this out - and use an identity matrix, which means all geometry is assumed - to be relative to camera space already. Useful for overlay rendering. - Normally you don't need to change this. The default is false. - @see ManualObject::getUseIdentityView - */ - void setUseIdentityView(bool useIdentityView); - - /** Returns whether or not to use an 'identity' view. - @remarks - Usually ManualObjects will use a view matrix as determined - by the active camera. However, if they want they can cancel this out - and use an identity matrix, which means all geometry is assumed - to be relative to camera space already. Useful for overlay rendering. - Normally you don't need to change this. - @see ManualObject::setUseIdentityView - */ - bool getUseIdentityView(void) const { return mUseIdentityView; } - - /** Sets the bounding box. - @remarks Call this after having finished creating sections to modify the - bounding box. E.g. if you're using ManualObject to create 2D overlays - you can call things function to set an infinite bounding box so that - the object always stays visible when attached. - @see ManualObject::setUseIdentityProjection, ManualObject::setUseIdentityView, - AxisAlignedBox::setInfinite */ - void setBoundingBox(const AxisAlignedBox& box) { mAABB = box; } - - /** Gets a pointer to a ManualObjectSection, i.e. a part of a ManualObject. - */ - ManualObjectSection* getSection(unsigned int index) const; - - /** Retrieves the number of ManualObjectSection objects making up this ManualObject. - */ - unsigned int getNumSections(void) const; - /** Sets whether or not to keep the original declaration order when - queuing the renderables. - @remarks - This overrides the default behavior of the rendering queue, - specifically stating the desired order of rendering. Might result in a - performance loss, but lets the user to have more direct control when - creating geometry through this class. - @param keepOrder Whether to keep the declaration order or not. - */ - void setKeepDeclarationOrder(bool keepOrder) { mKeepDeclarationOrder = keepOrder; } - - /** Gets whether or not the declaration order is to be kept or not. - @return A flag indication if the declaration order will be kept when - queuing the renderables. - */ - bool getKeepDeclarationOrder() const { return mKeepDeclarationOrder; } - // MovableObject overrides - - /** @copydoc MovableObject::getMovableType. */ - const String& getMovableType(void) const; - /** @copydoc MovableObject::getBoundingBox. */ - const AxisAlignedBox& getBoundingBox(void) const; - /** @copydoc MovableObject::getBoundingRadius. */ - Real getBoundingRadius(void) const; - /** @copydoc MovableObject::_updateRenderQueue. */ - void _updateRenderQueue(RenderQueue* queue); - /** Implement this method to enable stencil shadows. */ - EdgeData* getEdgeList(void); - /** Overridden member from ShadowCaster. */ - bool hasEdgeList(void); - /** Implement this method to enable stencil shadows. */ - ShadowRenderableListIterator getShadowVolumeRenderableIterator( - ShadowTechnique shadowTechnique, const Light* light, - HardwareIndexBufferSharedPtr* indexBuffer, size_t* indexBufferUsedSize, - bool extrudeVertices, Real extrusionDist, unsigned long flags = 0); - - - /// Built, renderable section of geometry - class _OgreExport ManualObjectSection : public Renderable, public MovableAlloc - { - protected: - ManualObject* mParent; - String mMaterialName; - String mGroupName; - mutable MaterialPtr mMaterial; - RenderOperation mRenderOperation; - bool m32BitIndices; - - - public: - ManualObjectSection(ManualObject* parent, const String& materialName, - RenderOperation::OperationType opType, const String & groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - virtual ~ManualObjectSection(); - - /// Retrieve render operation for manipulation - RenderOperation* getRenderOperation(void); - /// Retrieve the material name in use - const String& getMaterialName(void) const { return mMaterialName; } - /// Retrieve the material group in use - const String& getMaterialGroup(void) const { return mGroupName; } - /// update the material name in use - void setMaterialName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME ); - /// Set whether we need 32-bit indices - void set32BitIndices(bool n32) { m32BitIndices = n32; } - /// Get whether we need 32-bit indices - bool get32BitIndices() const { return m32BitIndices; } - - // Renderable overrides - /** @copydoc Renderable::getMaterial. */ - const MaterialPtr& getMaterial(void) const; - /** @copydoc Renderable::getRenderOperation. */ - void getRenderOperation(RenderOperation& op); - /** @copydoc Renderable::getWorldTransforms. */ - void getWorldTransforms(Matrix4* xform) const; - /** @copydoc Renderable::getSquaredViewDepth. */ - Real getSquaredViewDepth(const Ogre::Camera *) const; - /** @copydoc Renderable::getLights. */ - const LightList &getLights(void) const; - - - - }; - /** Nested class to allow shadows. */ - class _OgreExport ManualObjectSectionShadowRenderable : public ShadowRenderable - { - protected: - ManualObject* mParent; - // Shared link to position buffer - HardwareVertexBufferSharedPtr mPositionBuffer; - // Shared link to w-coord buffer (optional) - HardwareVertexBufferSharedPtr mWBuffer; - - public: - ManualObjectSectionShadowRenderable(ManualObject* parent, - HardwareIndexBufferSharedPtr* indexBuffer, const VertexData* vertexData, - bool createSeparateLightCap, bool isLightCap = false); - ~ManualObjectSectionShadowRenderable(); - /// Overridden from ShadowRenderable - void getWorldTransforms(Matrix4* xform) const; - HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; } - HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; } - /// Overridden from ShadowRenderable - virtual void rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer); - - - - }; - - typedef vector::type SectionList; - - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false); - - - protected: - /// Dynamic? - bool mDynamic; - /// List of subsections - SectionList mSectionList; - /// Current section - ManualObjectSection* mCurrentSection; - /// Are we updating? - bool mCurrentUpdating; - /// Temporary vertex structure - struct TempVertex - { - Vector3 position; - Vector3 normal; - Vector3 tangent; - Vector4 texCoord[OGRE_MAX_TEXTURE_COORD_SETS]; - ushort texCoordDims[OGRE_MAX_TEXTURE_COORD_SETS]; - ColourValue colour; - }; - /// Temp storage - TempVertex mTempVertex; - /// First vertex indicator - bool mFirstVertex; - /// Temp vertex data to copy? - bool mTempVertexPending; - /// System-memory buffer whilst we establish the size required - char* mTempVertexBuffer; - /// System memory allocation size, in bytes - size_t mTempVertexSize; - /// System-memory buffer whilst we establish the size required - uint32* mTempIndexBuffer; - /// System memory allocation size, in bytes - size_t mTempIndexSize; - /// Current declaration vertex size - size_t mDeclSize; - /// Estimated vertex count - size_t mEstVertexCount; - /// Estimated index count - size_t mEstIndexCount; - /// Current texture coordinate - ushort mTexCoordIndex; - /// Bounding box - AxisAlignedBox mAABB; - /// Bounding sphere - Real mRadius; - /// Any indexed geometry on any sections? - bool mAnyIndexed; - /// Edge list, used if stencil shadow casting is enabled - EdgeData* mEdgeList; - /// List of shadow renderables - ShadowRenderableList mShadowRenderables; - /// Whether to use identity projection for sections - bool mUseIdentityProjection; - /// Whether to use identity view for sections - bool mUseIdentityView; - /// Keep declaration order or let the queue optimize it - bool mKeepDeclarationOrder; - - - /// Delete temp buffers and reset init counts - virtual void resetTempAreas(void); - /// Resize the temp vertex buffer? - virtual void resizeTempVertexBufferIfNeeded(size_t numVerts); - /// Resize the temp index buffer? - virtual void resizeTempIndexBufferIfNeeded(size_t numInds); - - /// Copy current temp vertex into buffer - virtual void copyTempVertexToBuffer(void); - - }; - - - /** Factory object for creating ManualObject instances */ - class _OgreExport ManualObjectFactory : public MovableObjectFactory - { - protected: - MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params); - public: - ManualObjectFactory() {} - ~ManualObjectFactory() {} - - static String FACTORY_TYPE_NAME; - - const String& getType(void) const; - void destroyInstance( MovableObject* obj); - - }; - /** @} */ - /** @} */ + @param i1, i2, i3, i4 4 vertex indices from 0 to 4294967295 defining a quad. + */ + virtual void quad(uint32 i1, uint32 i2, uint32 i3, uint32 i4); + + /// Get the number of vertices in the section currently being defined (returns 0 if no section is in progress). + virtual size_t getCurrentVertexCount() const; + + /// Get the number of indices in the section currently being defined (returns 0 if no section is in progress). + virtual size_t getCurrentIndexCount() const; + + /** Finish defining the object and compile the final renderable version. + @note + Will return a pointer to the finished section or NULL if the section was discarded (i.e. has zero vertices/indices). + */ + virtual ManualObjectSection* end(void); + + /** Alter the material for a subsection of this object after it has been + specified. + @remarks + You specify the material to use on a section of this object during the + call to begin(), however if you want to change the material afterwards + you can do so by calling this method. + @param subIndex The index of the subsection to alter + @param name The name of the new material to use + */ + virtual void setMaterialName(size_t subIndex, const String& name, const String & group = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + /** Convert this object to a Mesh. + @remarks + After you've finished building this object, you may convert it to + a Mesh if you want in order to be able to create many instances of + it in the world (via Entity). This is optional, since this instance + can be directly attached to a SceneNode itself, but of course only + one instance of it can exist that way. + @note Only objects which use indexed geometry may be converted to a mesh. + @param meshName The name to give the mesh + @param groupName The resource group to create the mesh in + */ + virtual MeshPtr convertToMesh(const String& meshName, + const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + /** Sets whether or not to use an 'identity' projection. + @remarks + Usually ManualObjects will use a projection matrix as determined + by the active camera. However, if they want they can cancel this out + and use an identity projection, which effectively projects in 2D using + a {-1, 1} view space. Useful for overlay rendering. Normally you don't + need to change this. The default is false. + @see ManualObject::getUseIdentityProjection + */ + void setUseIdentityProjection(bool useIdentityProjection); + + /** Returns whether or not to use an 'identity' projection. + @remarks + Usually ManualObjects will use a projection matrix as determined + by the active camera. However, if they want they can cancel this out + and use an identity projection, which effectively projects in 2D using + a {-1, 1} view space. Useful for overlay rendering. Normally you don't + need to change this. + @see ManualObject::setUseIdentityProjection + */ + bool getUseIdentityProjection(void) const { return mUseIdentityProjection; } + + /** Sets whether or not to use an 'identity' view. + @remarks + Usually ManualObjects will use a view matrix as determined + by the active camera. However, if they want they can cancel this out + and use an identity matrix, which means all geometry is assumed + to be relative to camera space already. Useful for overlay rendering. + Normally you don't need to change this. The default is false. + @see ManualObject::getUseIdentityView + */ + void setUseIdentityView(bool useIdentityView); + + /** Returns whether or not to use an 'identity' view. + @remarks + Usually ManualObjects will use a view matrix as determined + by the active camera. However, if they want they can cancel this out + and use an identity matrix, which means all geometry is assumed + to be relative to camera space already. Useful for overlay rendering. + Normally you don't need to change this. + @see ManualObject::setUseIdentityView + */ + bool getUseIdentityView(void) const { return mUseIdentityView; } + + /** Sets the bounding box. + @remarks Call this after having finished creating sections to modify the + bounding box. E.g. if you're using ManualObject to create 2D overlays + you can call things function to set an infinite bounding box so that + the object always stays visible when attached. + @see ManualObject::setUseIdentityProjection, ManualObject::setUseIdentityView, + AxisAlignedBox::setInfinite */ + void setBoundingBox(const AxisAlignedBox& box) { mAABB = box; } + + /** Gets a pointer to a ManualObjectSection, i.e. a part of a ManualObject. + */ + ManualObjectSection* getSection(unsigned int index) const; + + /** Retrieves the number of ManualObjectSection objects making up this ManualObject. + */ + unsigned int getNumSections(void) const; + /** Sets whether or not to keep the original declaration order when + queuing the renderables. + @remarks + This overrides the default behavior of the rendering queue, + specifically stating the desired order of rendering. Might result in a + performance loss, but lets the user to have more direct control when + creating geometry through this class. + @param keepOrder Whether to keep the declaration order or not. + */ + void setKeepDeclarationOrder(bool keepOrder) { mKeepDeclarationOrder = keepOrder; } + + /** Gets whether or not the declaration order is to be kept or not. + @return A flag indication if the declaration order will be kept when + queuing the renderables. + */ + bool getKeepDeclarationOrder() const { return mKeepDeclarationOrder; } + // MovableObject overrides + + /** @copydoc MovableObject::getMovableType. */ + const String& getMovableType(void) const; + /** @copydoc MovableObject::getBoundingBox. */ + const AxisAlignedBox& getBoundingBox(void) const; + /** @copydoc MovableObject::getBoundingRadius. */ + Real getBoundingRadius(void) const; + /** @copydoc MovableObject::_updateRenderQueue. */ + void _updateRenderQueue(RenderQueue* queue); + /** Implement this method to enable stencil shadows. */ + EdgeData* getEdgeList(void); + /** Overridden member from ShadowCaster. */ + bool hasEdgeList(void); + /** Implement this method to enable stencil shadows. */ + ShadowRenderableListIterator getShadowVolumeRenderableIterator( + ShadowTechnique shadowTechnique, const Light* light, + HardwareIndexBufferSharedPtr* indexBuffer, size_t* indexBufferUsedSize, + bool extrudeVertices, Real extrusionDist, unsigned long flags = 0); + + + /// Built, renderable section of geometry + class _OgreExport ManualObjectSection : public Renderable, public MovableAlloc + { + protected: + ManualObject* mParent; + String mMaterialName; + String mGroupName; + mutable MaterialPtr mMaterial; + RenderOperation mRenderOperation; + bool m32BitIndices; + + + public: + ManualObjectSection(ManualObject* parent, const String& materialName, + RenderOperation::OperationType opType, const String & groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + virtual ~ManualObjectSection(); + + /// Retrieve render operation for manipulation + RenderOperation* getRenderOperation(void); + /// Retrieve the material name in use + const String& getMaterialName(void) const { return mMaterialName; } + /// Retrieve the material group in use + const String& getMaterialGroup(void) const { return mGroupName; } + /// update the material name in use + void setMaterialName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME ); + /// Set whether we need 32-bit indices + void set32BitIndices(bool n32) { m32BitIndices = n32; } + /// Get whether we need 32-bit indices + bool get32BitIndices() const { return m32BitIndices; } + + // Renderable overrides + /** @copydoc Renderable::getMaterial. */ + const MaterialPtr& getMaterial(void) const; + /** @copydoc Renderable::getRenderOperation. */ + void getRenderOperation(RenderOperation& op); + /** @copydoc Renderable::getWorldTransforms. */ + void getWorldTransforms(Matrix4* xform) const; + /** @copydoc Renderable::getSquaredViewDepth. */ + Real getSquaredViewDepth(const Ogre::Camera *) const; + /** @copydoc Renderable::getLights. */ + const LightList &getLights(void) const; + + + + }; + /** Nested class to allow shadows. */ + class _OgreExport ManualObjectSectionShadowRenderable : public ShadowRenderable + { + protected: + ManualObject* mParent; + // Shared link to position buffer + HardwareVertexBufferSharedPtr mPositionBuffer; + // Shared link to w-coord buffer (optional) + HardwareVertexBufferSharedPtr mWBuffer; + + public: + ManualObjectSectionShadowRenderable(ManualObject* parent, + HardwareIndexBufferSharedPtr* indexBuffer, const VertexData* vertexData, + bool createSeparateLightCap, bool isLightCap = false); + ~ManualObjectSectionShadowRenderable(); + /// Overridden from ShadowRenderable + void getWorldTransforms(Matrix4* xform) const; + HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; } + HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; } + /// Overridden from ShadowRenderable + virtual void rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer); + + + + }; + + typedef vector::type SectionList; + + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false); + + + protected: + /// Dynamic? + bool mDynamic; + /// List of subsections + SectionList mSectionList; + /// Current section + ManualObjectSection* mCurrentSection; + /// Are we updating? + bool mCurrentUpdating; + /// Temporary vertex structure + struct TempVertex + { + Vector3 position; + Vector3 normal; + Vector3 tangent; + Vector4 texCoord[OGRE_MAX_TEXTURE_COORD_SETS]; + ushort texCoordDims[OGRE_MAX_TEXTURE_COORD_SETS]; + ColourValue colour; + }; + /// Temp storage + TempVertex mTempVertex; + /// First vertex indicator + bool mFirstVertex; + /// Temp vertex data to copy? + bool mTempVertexPending; + /// System-memory buffer whilst we establish the size required + char* mTempVertexBuffer; + /// System memory allocation size, in bytes + size_t mTempVertexSize; + /// System-memory buffer whilst we establish the size required + uint32* mTempIndexBuffer; + /// System memory allocation size, in bytes + size_t mTempIndexSize; + /// Current declaration vertex size + size_t mDeclSize; + /// Estimated vertex count + size_t mEstVertexCount; + /// Estimated index count + size_t mEstIndexCount; + /// Current texture coordinate + ushort mTexCoordIndex; + /// Bounding box + AxisAlignedBox mAABB; + /// Bounding sphere + Real mRadius; + /// Any indexed geometry on any sections? + bool mAnyIndexed; + /// Edge list, used if stencil shadow casting is enabled + EdgeData* mEdgeList; + /// List of shadow renderables + ShadowRenderableList mShadowRenderables; + /// Whether to use identity projection for sections + bool mUseIdentityProjection; + /// Whether to use identity view for sections + bool mUseIdentityView; + /// Keep declaration order or let the queue optimize it + bool mKeepDeclarationOrder; + + + /// Delete temp buffers and reset init counts + virtual void resetTempAreas(void); + /// Resize the temp vertex buffer? + virtual void resizeTempVertexBufferIfNeeded(size_t numVerts); + /// Resize the temp index buffer? + virtual void resizeTempIndexBufferIfNeeded(size_t numInds); + + /// Copy current temp vertex into buffer + virtual void copyTempVertexToBuffer(void); + + }; + + + /** Factory object for creating ManualObject instances */ + class _OgreExport ManualObjectFactory : public MovableObjectFactory + { + protected: + MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params); + public: + ManualObjectFactory() {} + ~ManualObjectFactory() {} + + static String FACTORY_TYPE_NAME; + + const String& getType(void) const; + void destroyInstance( MovableObject* obj); + + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreMaterial.h b/OgreMain/include/OgreMaterial.h index 8ee4137883c..867e2525dd1 100644 --- a/OgreMain/include/OgreMaterial.h +++ b/OgreMain/include/OgreMaterial.h @@ -39,16 +39,16 @@ THE SOFTWARE. namespace Ogre { - // Forward declaration + // Forward declaration class LodStrategy; - /** \addtogroup Core - * @{ - */ - /** \addtogroup Materials - * @{ - */ - /** Class encapsulates rendering properties of an object. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Materials + * @{ + */ + /** Class encapsulates rendering properties of an object. @remarks Ogre's material class encapsulates ALL aspects of the visual appearance, of an object. It also includes other flags which @@ -92,7 +92,7 @@ namespace Ogre { public: /// distance list used to specify LOD - typedef vector::type LodValueList; + typedef vector::type LodValueList; typedef ConstVectorIterator LodValueIterator; protected: @@ -102,60 +102,60 @@ namespace Ogre { void applyDefaults(void); typedef vector::type Techniques; - /// All techniques, supported and unsupported + /// All techniques, supported and unsupported Techniques mTechniques; - /// Supported techniques of any sort + /// Supported techniques of any sort Techniques mSupportedTechniques; - typedef map::type LodTechniques; + typedef map::type LodTechniques; typedef map::type BestTechniquesBySchemeList; - /** Map of scheme -> list of LOD techniques. - Current scheme is set on MaterialManager, - and can be set per Viewport for auto activation. - */ + /** Map of scheme -> list of LOD techniques. + Current scheme is set on MaterialManager, + and can be set per Viewport for auto activation. + */ BestTechniquesBySchemeList mBestTechniquesBySchemeList; LodValueList mUserLodValues; LodValueList mLodValues; const LodStrategy *mLodStrategy; bool mReceiveShadows; - bool mTransparencyCastsShadows; + bool mTransparencyCastsShadows; /// Does this material require compilation? bool mCompilationRequired; - /// Text description of why any techniques are not supported - String mUnsupportedReasons; - - /** Insert a supported technique into the local collections. */ - void insertSupportedTechnique(Technique* t); - - /** Clear the best technique list. - */ - void clearBestTechniqueList(void); - - /** Overridden from Resource. - */ - void prepareImpl(void); - - /** Overridden from Resource. - */ - void unprepareImpl(void); - - /** Overridden from Resource. - */ - void loadImpl(void); - - /** Unloads the material, frees resources etc. - @see - Resource - */ - void unloadImpl(void); - /// @copydoc Resource::calculateSize - size_t calculateSize(void) const; + /// Text description of why any techniques are not supported + String mUnsupportedReasons; + + /** Insert a supported technique into the local collections. */ + void insertSupportedTechnique(Technique* t); + + /** Clear the best technique list. + */ + void clearBestTechniqueList(void); + + /** Overridden from Resource. + */ + void prepareImpl(void); + + /** Overridden from Resource. + */ + void unprepareImpl(void); + + /** Overridden from Resource. + */ + void loadImpl(void); + + /** Unloads the material, frees resources etc. + @see + Resource + */ + void unloadImpl(void); + /// @copydoc Resource::calculateSize + size_t calculateSize(void) const; public: /** Constructor - use resource manager's create method rather than this. */ - Material(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual = false, ManualResourceLoader* loader = 0); + Material(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual = false, ManualResourceLoader* loader = 0); ~Material(); /** Assignment operator to allow easy copying between materials. @@ -184,17 +184,17 @@ namespace Ogre { /** Returns whether or not objects using this material will receive shadows. */ bool getReceiveShadows(void) const { return mReceiveShadows; } - /** Sets whether objects using this material be classified as opaque to the shadow caster system. - @remarks - This method allows a material to cast a shadow, even if it is transparent. - By default, transparent materials neither cast nor receive shadows. Shadows - will not be cast on any objects unless the scene is set up to support shadows - (@see SceneManager::setShadowTechnique), and not all techniques cast - shadows on all objects. - */ - void setTransparencyCastsShadows(bool enabled) { mTransparencyCastsShadows = enabled; } - /** Returns whether or not objects using this material be classified as opaque to the shadow caster system. */ - bool getTransparencyCastsShadows(void) const { return mTransparencyCastsShadows; } + /** Sets whether objects using this material be classified as opaque to the shadow caster system. + @remarks + This method allows a material to cast a shadow, even if it is transparent. + By default, transparent materials neither cast nor receive shadows. Shadows + will not be cast on any objects unless the scene is set up to support shadows + (@see SceneManager::setShadowTechnique), and not all techniques cast + shadows on all objects. + */ + void setTransparencyCastsShadows(bool enabled) { mTransparencyCastsShadows = enabled; } + /** Returns whether or not objects using this material be classified as opaque to the shadow caster system. */ + bool getTransparencyCastsShadows(void) const { return mTransparencyCastsShadows; } /** Creates a new Technique for this Material. @remarks @@ -217,10 +217,10 @@ namespace Ogre { Return 0 if technique with name is not found */ Technique* getTechnique(const String& name); - /** Retrieves the number of techniques. */ + /** Retrieves the number of techniques. */ unsigned short getNumTechniques(void) const; - /** Removes the technique at the given index. */ - void removeTechnique(unsigned short index); + /** Removes the technique at the given index. */ + void removeTechnique(unsigned short index); /** Removes all the techniques in this Material. */ void removeAllTechniques(void); typedef VectorIterator TechniqueIterator; @@ -233,22 +233,22 @@ namespace Ogre { an empty list, try calling Material::load. */ TechniqueIterator getSupportedTechniqueIterator(void); - - /** Gets the indexed supported technique. */ + + /** Gets the indexed supported technique. */ Technique* getSupportedTechnique(unsigned short index); - /** Retrieves the number of supported techniques. */ + /** Retrieves the number of supported techniques. */ unsigned short getNumSupportedTechniques(void) const; - /** Gets a string explaining why any techniques are not supported. */ - const String& getUnsupportedTechniquesExplanation() const { return mUnsupportedReasons; } + /** Gets a string explaining why any techniques are not supported. */ + const String& getUnsupportedTechniquesExplanation() const { return mUnsupportedReasons; } /** Gets the number of levels-of-detail this material has in the - given scheme, based on Technique::setLodIndex. + given scheme, based on Technique::setLodIndex. @remarks Note that this will not be up to date until the material has been compiled. */ unsigned short getNumLodLevels(unsigned short schemeIndex) const; /** Gets the number of levels-of-detail this material has in the - given scheme, based on Technique::setLodIndex. + given scheme, based on Technique::setLodIndex. @remarks Note that this will not be up to date until the material has been compiled. */ @@ -263,22 +263,22 @@ namespace Ogre { The best supported technique is only available after this material has been compiled, which typically happens on loading the material. Therefore, if this method returns NULL, try calling Material::load. - @param lodIndex The material LOD index to use - @param rend Optional parameter specifying the Renderable that is requesting - this technique. Only used if no valid technique for the active material - scheme is found, at which point it is passed to - MaterialManager::Listener::handleSchemeNotFound as information. + @param lodIndex The material LOD index to use + @param rend Optional parameter specifying the Renderable that is requesting + this technique. Only used if no valid technique for the active material + scheme is found, at which point it is passed to + MaterialManager::Listener::handleSchemeNotFound as information. */ Technique* getBestTechnique(unsigned short lodIndex = 0, const Renderable* rend = 0); /** Creates a new copy of this material with the same settings but a new name. - @param newName The name for the cloned material - @param changeGroup If true, the resource group of the clone is changed - @param newGroup Only required if changeGroup is true; the new group to assign + @param newName The name for the cloned material + @param changeGroup If true, the resource group of the clone is changed + @param newGroup Only required if changeGroup is true; the new group to assign */ MaterialPtr clone(const String& newName, bool changeGroup = false, - const String& newGroup = BLANKSTRING) const; + const String& newGroup = BLANKSTRING) const; /** Copies the details of this material into another, preserving the target's handle and name (unlike operator=) but copying everything else. @@ -418,7 +418,7 @@ namespace Ogre { */ void setSelfIllumination(const ColourValue& selfIllum); - /** Sets whether or not each Pass renders with depth-buffer checking on or not. + /** Sets whether or not each Pass renders with depth-buffer checking on or not. @note This property has been moved to the Pass class, which is accessible via the Technique. For simplicity, this method allows you to set these properties for @@ -451,7 +451,7 @@ namespace Ogre { */ void setDepthFunction( CompareFunction func ); - /** Sets whether or not colour buffer writing is enabled for each Pass. + /** Sets whether or not colour buffer writing is enabled for each Pass. @note This property has been moved to the Pass class, which is accessible via the Technique. For simplicity, this method allows you to set these properties for @@ -459,8 +459,8 @@ namespace Ogre { you need more precision, retrieve the Technique and Pass instances and set the property there. @see Pass::setColourWriteEnabled - */ - void setColourWriteEnabled(bool enabled); + */ + void setColourWriteEnabled(bool enabled); /** Sets the culling mode for each pass based on the 'vertex winding'. @note @@ -609,8 +609,8 @@ namespace Ogre { switch to lower details. They are listed in LOD index order, starting at index 1 (ie the first level down from the highest level 0, which automatically applies from a value of 0). These are 'user values', before being potentially - transformed by the strategy, so for the distance strategy this is an - unsquared distance for example. + transformed by the strategy, so for the distance strategy this is an + unsquared distance for example. */ void setLodLevels(const LodValueList& lodValues); @@ -619,7 +619,7 @@ namespace Ogre { Note that the iterator returned from this method is not totally analogous to the one passed in by calling setLodLevels - the list includes a zero entry at the start (since the highest LOD starts at value 0). Also, the - values returned are after being transformed by LodStrategy::transformUserValue. + values returned are after being transformed by LodStrategy::transformUserValue. */ LodValueIterator getLodValueIterator(void) const; @@ -628,15 +628,15 @@ namespace Ogre { Note that the iterator returned from this method is not totally analogous to the one passed in by calling setLodLevels - the list includes a zero entry at the start (since the highest LOD starts at value 0). Also, the - values returned are after being transformed by LodStrategy::transformUserValue. + values returned are after being transformed by LodStrategy::transformUserValue. */ LodValueIterator getUserLodValueIterator(void) const; /** Gets the LOD index to use at the given value. - @note The value passed in is the 'transformed' value. If you are dealing with - an original source value (e.g. distance), use LodStrategy::transformUserValue - to turn this into a lookup value. - */ + @note The value passed in is the 'transformed' value. If you are dealing with + an original source value (e.g. distance), use LodStrategy::transformUserValue + to turn this into a lookup value. + */ ushort getLodIndex(Real value) const; /** Get LOD strategy used by this material. */ @@ -667,18 +667,18 @@ namespace Ogre { */ bool applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply = true) const; - /** Gets the compilation status of the material. + /** Gets the compilation status of the material. @return True if the material needs recompilation. */ - bool getCompilationRequired() const - { - return mCompilationRequired; - } + bool getCompilationRequired() const + { + return mCompilationRequired; + } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } //namespace diff --git a/OgreMain/include/OgreMaterialManager.h b/OgreMain/include/OgreMaterialManager.h index 8a1be1b1ba6..7055d5fe508 100644 --- a/OgreMain/include/OgreMaterialManager.h +++ b/OgreMain/include/OgreMaterialManager.h @@ -36,16 +36,16 @@ THE SOFTWARE. namespace Ogre { - class MaterialSerializer; + class MaterialSerializer; - /** \addtogroup Core - * @{ - */ - /** \addtogroup Materials - * @{ - */ - /** Class for managing Material settings for Ogre. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Materials + * @{ + */ + /** Class for managing Material settings for Ogre. @remarks Materials control the eventual surface rendering properties of geometry. This class manages the library of materials, dealing with programmatic registrations and lookups, @@ -62,49 +62,49 @@ namespace Ogre { */ class _OgreExport MaterialManager : public ResourceManager, public Singleton { - public: - /** Listener on any general material events. - @see MaterialManager::addListener - */ - class Listener - { - public: + public: + /** Listener on any general material events. + @see MaterialManager::addListener + */ + class Listener + { + public: /** Virtual destructor needed as class has virtual methods. */ virtual ~Listener() { } - /** Called if a technique for a given scheme is not found within a material, - allows the application to specify a Technique instance manually. - @remarks - Material schemes allow you to switch wholesale between families of - techniques on a material. However they require you to define those - schemes on the materials up-front, which might not be possible or - desirable for all materials, particular if, for example, you wanted - a simple way to replace all materials with another using a scheme. - @par - This callback allows you to handle the case where a scheme is requested - but the material doesn't have an entry for it. You can return a - Technique pointer from this method to specify the material technique - you'd like to be applied instead, which can be from another material - entirely (and probably will be). Note that it is critical that you - only return a Technique that is supported on this hardware; there are - utility methods like Material::getBestTechnique to help you with this. - @param schemeIndex The index of the scheme that was requested - all - schemes have a unique index when created that does not alter. - @param schemeName The friendly name of the scheme being requested - @param originalMaterial The material that is being processed, that - didn't have a specific technique for this scheme - @param lodIndex The material level-of-detail that was being asked for, - in case you need to use it to determine a technique. - @param rend Pointer to the Renderable that is requesting this technique - to be used, so this may influence your choice of Technique. May be - null if the technique isn't being requested in that context. - @return A pointer to the technique to be used, or NULL if you wish to - use the default technique for this material - */ - virtual Technique* handleSchemeNotFound(unsigned short schemeIndex, - const String& schemeName, Material* originalMaterial, unsigned short lodIndex, - const Renderable* rend) = 0; - - }; + /** Called if a technique for a given scheme is not found within a material, + allows the application to specify a Technique instance manually. + @remarks + Material schemes allow you to switch wholesale between families of + techniques on a material. However they require you to define those + schemes on the materials up-front, which might not be possible or + desirable for all materials, particular if, for example, you wanted + a simple way to replace all materials with another using a scheme. + @par + This callback allows you to handle the case where a scheme is requested + but the material doesn't have an entry for it. You can return a + Technique pointer from this method to specify the material technique + you'd like to be applied instead, which can be from another material + entirely (and probably will be). Note that it is critical that you + only return a Technique that is supported on this hardware; there are + utility methods like Material::getBestTechnique to help you with this. + @param schemeIndex The index of the scheme that was requested - all + schemes have a unique index when created that does not alter. + @param schemeName The friendly name of the scheme being requested + @param originalMaterial The material that is being processed, that + didn't have a specific technique for this scheme + @param lodIndex The material level-of-detail that was being asked for, + in case you need to use it to determine a technique. + @param rend Pointer to the Renderable that is requesting this technique + to be used, so this may influence your choice of Technique. May be + null if the technique isn't being requested in that context. + @return A pointer to the technique to be used, or NULL if you wish to + use the default technique for this material + */ + virtual Technique* handleSchemeNotFound(unsigned short schemeIndex, + const String& schemeName, Material* originalMaterial, unsigned short lodIndex, + const Renderable* rend) = 0; + + }; protected: @@ -114,51 +114,51 @@ namespace Ogre { FilterOptions mDefaultMagFilter; /// Default Texture filtering - mipmapping FilterOptions mDefaultMipFilter; - /// Default Texture filtering - comparison - FilterOptions mDefaultCompare; + /// Default Texture filtering - comparison + FilterOptions mDefaultCompare; - bool mDefaultCompareEnabled; - CompareFunction mDefaultCompareFunction; + bool mDefaultCompareEnabled; + CompareFunction mDefaultCompareFunction; /// Default Texture anisotropy unsigned int mDefaultMaxAniso; /// Serializer - Hold instance per thread if necessary OGRE_THREAD_POINTER(MaterialSerializer, mSerializer); - /// Default settings - MaterialPtr mDefaultSettings; + /// Default settings + MaterialPtr mDefaultSettings; - /// Overridden from ResourceManager - Resource* createImpl(const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, + /// Overridden from ResourceManager + Resource* createImpl(const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* params); - /// Scheme name -> index. Never shrinks! Should be pretty static anyway - typedef map::type SchemeMap; - /// List of material schemes - SchemeMap mSchemes; - /// Current material scheme - String mActiveSchemeName; - /// Current material scheme - unsigned short mActiveSchemeIndex; + /// Scheme name -> index. Never shrinks! Should be pretty static anyway + typedef map::type SchemeMap; + /// List of material schemes + SchemeMap mSchemes; + /// Current material scheme + String mActiveSchemeName; + /// Current material scheme + unsigned short mActiveSchemeIndex; - /// The list of per-scheme (and general) material listeners - typedef list::type ListenerList; - typedef map::type ListenerMap; - ListenerMap mListenerMap; + /// The list of per-scheme (and general) material listeners + typedef list::type ListenerList; + typedef map::type ListenerMap; + ListenerMap mListenerMap; public: - /// Default material scheme - static String DEFAULT_SCHEME_NAME; - - /// Create a new material - /// @see ResourceManager::createResource - MaterialPtr create (const String& name, const String& group, - bool isManual = false, ManualResourceLoader* loader = 0, - const NameValuePairList* createParams = 0); - - /// Get a resource by name - /// @see ResourceManager::getResourceByName - MaterialPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + /// Default material scheme + static String DEFAULT_SCHEME_NAME; + + /// Create a new material + /// @see ResourceManager::createResource + MaterialPtr create (const String& name, const String& group, + bool isManual = false, ManualResourceLoader* loader = 0, + const NameValuePairList* createParams = 0); + + /// Get a resource by name + /// @see ResourceManager::getResourceByName + MaterialPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); /** Default constructor. */ @@ -168,11 +168,11 @@ namespace Ogre { */ virtual ~MaterialManager(); - /** Initialises the material manager, which also triggers it to - * parse all available .program and .material scripts. */ - void initialise(void); + /** Initialises the material manager, which also triggers it to + * parse all available .program and .material scripts. */ + void initialise(void); - /** @see ScriptLoader::parseScript + /** @see ScriptLoader::parseScript */ void parseScript(DataStreamPtr& stream, const String& groupName); @@ -195,7 +195,7 @@ namespace Ogre { */ virtual void setDefaultTextureFiltering(FilterOptions minFilter, FilterOptions magFilter, FilterOptions mipFilter); - /// Get the default texture filtering + /// Get the default texture filtering virtual FilterOptions getDefaultTextureFiltering(FilterType ftype) const; /** Sets the default anisotropy level to be used for loaded textures, for when textures are @@ -204,9 +204,9 @@ namespace Ogre { @note The default value is 1 (no anisotropy). */ - void setDefaultAnisotropy(unsigned int maxAniso); - /// Get the default maxAnisotropy - unsigned int getDefaultAnisotropy() const; + void setDefaultAnisotropy(unsigned int maxAniso); + /// Get the default maxAnisotropy + unsigned int getDefaultAnisotropy() const; /** Returns a pointer to the default Material settings. @remarks @@ -238,46 +238,46 @@ namespace Ogre {
    4. Bilinear texture filtering
    5. */ - virtual MaterialPtr getDefaultSettings(void) const { return mDefaultSettings; } - - /** Internal method - returns index for a given material scheme name. - @see Technique::setSchemeName - */ - virtual unsigned short _getSchemeIndex(const String& name); - /** Internal method - returns name for a given material scheme index. - @see Technique::setSchemeName - */ - virtual const String& _getSchemeName(unsigned short index); - /** Internal method - returns the active scheme index. - @see Technique::setSchemeName - */ - virtual unsigned short _getActiveSchemeIndex(void) const; - - /** Returns the name of the active material scheme. - @see Technique::setSchemeName - */ - virtual const String& getActiveScheme(void) const; - - /** Sets the name of the active material scheme. - @see Technique::setSchemeName - */ - virtual void setActiveScheme(const String& schemeName); - - /** - Add a listener to handle material events. - If schemeName is supplied, the listener will only receive events for that certain scheme. - */ - virtual void addListener(Listener* l, const Ogre::String& schemeName = BLANKSTRING); - - /** - Remove a listener handling material events. - If the listener was added with a custom scheme name, it needs to be supplied here as well. - */ - virtual void removeListener(Listener* l, const Ogre::String& schemeName = BLANKSTRING); - - /// Internal method for sorting out missing technique for a scheme - virtual Technique* _arbitrateMissingTechniqueForActiveScheme( - Material* mat, unsigned short lodIndex, const Renderable* rend); + virtual MaterialPtr getDefaultSettings(void) const { return mDefaultSettings; } + + /** Internal method - returns index for a given material scheme name. + @see Technique::setSchemeName + */ + virtual unsigned short _getSchemeIndex(const String& name); + /** Internal method - returns name for a given material scheme index. + @see Technique::setSchemeName + */ + virtual const String& _getSchemeName(unsigned short index); + /** Internal method - returns the active scheme index. + @see Technique::setSchemeName + */ + virtual unsigned short _getActiveSchemeIndex(void) const; + + /** Returns the name of the active material scheme. + @see Technique::setSchemeName + */ + virtual const String& getActiveScheme(void) const; + + /** Sets the name of the active material scheme. + @see Technique::setSchemeName + */ + virtual void setActiveScheme(const String& schemeName); + + /** + Add a listener to handle material events. + If schemeName is supplied, the listener will only receive events for that certain scheme. + */ + virtual void addListener(Listener* l, const Ogre::String& schemeName = BLANKSTRING); + + /** + Remove a listener handling material events. + If the listener was added with a custom scheme name, it needs to be supplied here as well. + */ + virtual void removeListener(Listener* l, const Ogre::String& schemeName = BLANKSTRING); + + /// Internal method for sorting out missing technique for a scheme + virtual Technique* _arbitrateMissingTechniqueForActiveScheme( + Material* mat, unsigned short lodIndex, const Renderable* rend); /** Override standard Singleton retrieval. @remarks @@ -313,8 +313,8 @@ namespace Ogre { static MaterialManager* getSingletonPtr(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreMaterialSerializer.h b/OgreMain/include/OgreMaterialSerializer.h index e50c7556ec0..3136c420892 100644 --- a/OgreMain/include/OgreMaterialSerializer.h +++ b/OgreMain/include/OgreMaterialSerializer.h @@ -36,13 +36,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Materials - * @{ - */ - /** Enum to identify material sections. */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Materials + * @{ + */ + /** Enum to identify material sections. */ enum MaterialScriptSection { MSS_NONE, @@ -51,29 +51,29 @@ namespace Ogre { MSS_PASS, MSS_TEXTUREUNIT, MSS_PROGRAM_REF, - MSS_PROGRAM, + MSS_PROGRAM, MSS_DEFAULT_PARAMETERS, - MSS_TEXTURESOURCE + MSS_TEXTURESOURCE }; - /** Struct for holding a program definition which is in progress. */ - struct MaterialScriptProgramDefinition - { - String name; - GpuProgramType progType; + /** Struct for holding a program definition which is in progress. */ + struct MaterialScriptProgramDefinition + { + String name; + GpuProgramType progType; String language; - String source; - String syntax; + String source; + String syntax; bool supportsSkeletalAnimation; - bool supportsMorphAnimation; - ushort supportsPoseAnimation; // number of simultaneous poses supported - bool usesVertexTextureFetch; - vector >::type customParameters; - }; + bool supportsMorphAnimation; + ushort supportsPoseAnimation; // number of simultaneous poses supported + bool usesVertexTextureFetch; + vector >::type customParameters; + }; /** Struct for holding the script context while parsing. */ struct MaterialScriptContext { MaterialScriptSection section; - String groupName; + String groupName; MaterialPtr material; Technique* technique; Pass* pass; @@ -82,17 +82,17 @@ namespace Ogre { bool isVertexProgramShadowCaster; /// When referencing, are we in context of shadow caster bool isFragmentProgramShadowCaster; /// When referencing, are we in context of shadow caster bool isVertexProgramShadowReceiver; /// When referencing, are we in context of shadow caster - bool isFragmentProgramShadowReceiver; /// When referencing, are we in context of shadow caster + bool isFragmentProgramShadowReceiver; /// When referencing, are we in context of shadow caster GpuProgramParametersSharedPtr programParams; - ushort numAnimationParametrics; - MaterialScriptProgramDefinition* programDef; /// This is used while defining a program + ushort numAnimationParametrics; + MaterialScriptProgramDefinition* programDef; /// This is used while defining a program - int techLev, //Keep track of what tech, pass, and state level we are in - passLev, - stateLev; + int techLev, //Keep track of what tech, pass, and state level we are in + passLev, + stateLev; StringVector defaultParamLines; - /// Error reporting state + /// Error reporting state size_t lineNo; String filename; AliasTextureNamePairList textureAliases; @@ -101,76 +101,76 @@ namespace Ogre { typedef bool (*ATTRIBUTE_PARSER)(String& params, MaterialScriptContext& context); /** Class for serializing Materials to / from a .material script.*/ - class _OgreExport MaterialSerializer : public SerializerAlloc - { - public: - - // Material serialize event. - enum SerializeEvent - { - MSE_PRE_WRITE, - MSE_WRITE_BEGIN, - MSE_WRITE_END, - MSE_POST_WRITE - }; - - /** Class that allows listening in on the various stages of material serialization process. - Sub-classing it enable extending the attribute set of any part in the material. - */ - class Listener - { - public: - virtual ~Listener() {} - - /** Called when material section event raised. - @param ser The MaterialSerializer instance that writes the given material. - @param event The current section writing stage. - @param skip May set to true by sub-class instances in order to skip the following section write. - This parameter relevant only when stage equals MSE_PRE_WRITE. - @param mat The material that is being written. - */ - virtual void materialEventRaised(MaterialSerializer* ser, - SerializeEvent event, bool& skip, const Material* mat) + class _OgreExport MaterialSerializer : public SerializerAlloc + { + public: + + // Material serialize event. + enum SerializeEvent + { + MSE_PRE_WRITE, + MSE_WRITE_BEGIN, + MSE_WRITE_END, + MSE_POST_WRITE + }; + + /** Class that allows listening in on the various stages of material serialization process. + Sub-classing it enable extending the attribute set of any part in the material. + */ + class Listener + { + public: + virtual ~Listener() {} + + /** Called when material section event raised. + @param ser The MaterialSerializer instance that writes the given material. + @param event The current section writing stage. + @param skip May set to true by sub-class instances in order to skip the following section write. + This parameter relevant only when stage equals MSE_PRE_WRITE. + @param mat The material that is being written. + */ + virtual void materialEventRaised(MaterialSerializer* ser, + SerializeEvent event, bool& skip, const Material* mat) { (void)ser; (void)event; (void)skip; (void)mat; } - - /** Called when technique section event raised. - @param ser The MaterialSerializer instance that writes the given material. - @param event The current section writing stage. - @param skip May set to true by sub-class instances in order to skip the following section write. - This parameter relevant only when stage equals MSE_PRE_WRITE. - @param tech The technique that is being written. - */ - virtual void techniqueEventRaised(MaterialSerializer* ser, - SerializeEvent event, bool& skip, const Technique* tech) + + /** Called when technique section event raised. + @param ser The MaterialSerializer instance that writes the given material. + @param event The current section writing stage. + @param skip May set to true by sub-class instances in order to skip the following section write. + This parameter relevant only when stage equals MSE_PRE_WRITE. + @param tech The technique that is being written. + */ + virtual void techniqueEventRaised(MaterialSerializer* ser, + SerializeEvent event, bool& skip, const Technique* tech) { (void)ser; (void)event; (void)skip; (void)tech; } - - /** Called when pass section event raised. - @param ser The MaterialSerializer instance that writes the given material. - @param event The current section writing stage. - @param skip May set to true by sub-class instances in order to skip the following section write. - This parameter relevant only when stage equals MSE_PRE_WRITE. - @param pass The pass that is being written. - */ - virtual void passEventRaised(MaterialSerializer* ser, - SerializeEvent event, bool& skip, const Pass* pass) + + /** Called when pass section event raised. + @param ser The MaterialSerializer instance that writes the given material. + @param event The current section writing stage. + @param skip May set to true by sub-class instances in order to skip the following section write. + This parameter relevant only when stage equals MSE_PRE_WRITE. + @param pass The pass that is being written. + */ + virtual void passEventRaised(MaterialSerializer* ser, + SerializeEvent event, bool& skip, const Pass* pass) { (void)ser; (void)event; (void)skip; (void)pass; } - /** Called when GPU program reference section event raised. - @param ser The MaterialSerializer instance that writes the given material. - @param event The current section writing stage. - @param skip May set to true by sub-class instances in order to skip the following section write. - This parameter relevant only when stage equals MSE_PRE_WRITE. - @param attrib The GPU program reference description (vertex_program_ref, fragment_program_ref, etc). - @param program The program being written. - @param params The program parameters. - @param defaultParams The default program parameters. - */ - void gpuProgramRefEventRaised(MaterialSerializer* ser, - SerializeEvent event, bool& skip, - const String& attrib, - const GpuProgramPtr& program, - const GpuProgramParametersSharedPtr& params, - GpuProgramParameters* defaultParams) + /** Called when GPU program reference section event raised. + @param ser The MaterialSerializer instance that writes the given material. + @param event The current section writing stage. + @param skip May set to true by sub-class instances in order to skip the following section write. + This parameter relevant only when stage equals MSE_PRE_WRITE. + @param attrib The GPU program reference description (vertex_program_ref, fragment_program_ref, etc). + @param program The program being written. + @param params The program parameters. + @param defaultParams The default program parameters. + */ + void gpuProgramRefEventRaised(MaterialSerializer* ser, + SerializeEvent event, bool& skip, + const String& attrib, + const GpuProgramPtr& program, + const GpuProgramParametersSharedPtr& params, + GpuProgramParameters* defaultParams) { (void)ser; (void)event; @@ -181,22 +181,22 @@ namespace Ogre { (void)defaultParams; } - /** Called when texture unit state section event raised. - @param ser The MaterialSerializer instance that writes the given material. - @param event The current section writing stage. - @param skip May set to true by sub-class instances in order to skip the following section write. - This parameter relevant only when stage equals MSE_PRE_WRITE. - @param textureUnit The texture unit state that is being written. - */ - virtual void textureUnitStateEventRaised(MaterialSerializer* ser, - SerializeEvent event, bool& skip, const TextureUnitState* textureUnit) + /** Called when texture unit state section event raised. + @param ser The MaterialSerializer instance that writes the given material. + @param event The current section writing stage. + @param skip May set to true by sub-class instances in order to skip the following section write. + This parameter relevant only when stage equals MSE_PRE_WRITE. + @param textureUnit The texture unit state that is being written. + */ + virtual void textureUnitStateEventRaised(MaterialSerializer* ser, + SerializeEvent event, bool& skip, const TextureUnitState* textureUnit) { (void)ser; (void)event; (void)skip; (void)textureUnit; - } - }; + } + }; protected: /// Keyword-mapped attribute parsers. @@ -210,10 +210,10 @@ namespace Ogre { bool parseScriptLine(String& line); /** internal method for finding & invoking an attribute parser. */ bool invokeParser(String& line, AttribParserList& parsers); - /** Internal method for saving a program definition which has been - built up. - */ - void finishProgramDefinition(void); + /** Internal method for saving a program definition which has been + built up. + */ + void finishProgramDefinition(void); /// Parsers for the root of the material script AttribParserList mRootAttribParsers; /// Parsers for the material section of a script @@ -231,11 +231,11 @@ namespace Ogre { /// Parsers for the program definition section of a script AttribParserList mProgramDefaultParamAttribParsers; - /// Listeners list of this Serializer. - typedef vector::type ListenerList; - typedef ListenerList::iterator ListenerListIterator; - typedef ListenerList::const_iterator ListenerListConstIterator; - ListenerList mListeners; + /// Listeners list of this Serializer. + typedef vector::type ListenerList; + typedef ListenerList::iterator ListenerListIterator; + typedef ListenerList::const_iterator ListenerListConstIterator; + ListenerList mListeners; void writeMaterial(const MaterialPtr& pMat, const String& materialName = ""); @@ -275,7 +275,7 @@ namespace Ogre { void writeColourValue(const ColourValue &colour, bool writeAlpha = false); void writeLayerBlendOperationEx(const LayerBlendOperationEx op); void writeLayerBlendSource(const LayerBlendSource lbs); - + typedef multimap::type EffectMap; void writeRotationEffect(const TextureUnitState::TextureEffect& effect, const TextureUnitState *pTex); @@ -285,63 +285,63 @@ namespace Ogre { String convertFiltering(FilterOptions fo); - - /** Internal methods that invokes registered listeners callback. - @see Listener::materialEventRaised. - */ - void fireMaterialEvent(SerializeEvent event, bool& skip, const Material* mat); - - /** Internal methods that invokes registered listeners callback. - @see Listener::techniqueEventRaised. - */ - void fireTechniqueEvent(SerializeEvent event, bool& skip, const Technique* tech); - - /** Internal methods that invokes registered listeners callback. - @see Listener::passEventRaised. - */ - void firePassEvent(SerializeEvent event, bool& skip, const Pass* pass); - - /** Internal methods that invokes registered listeners callback. - @see Listener::gpuProgramRefEventRaised. - */ - void fireGpuProgramRefEvent(SerializeEvent event, bool& skip, - const String& attrib, - const GpuProgramPtr& program, - const GpuProgramParametersSharedPtr& params, - GpuProgramParameters* defaultParams); - - - /** Internal methods that invokes registered listeners callback. - @see Listener::textureUnitStateEventRaised. - */ - void fireTextureUnitStateEvent(SerializeEvent event, bool& skip, const TextureUnitState* textureUnit); - - public: - /** default constructor*/ - MaterialSerializer(); - /** default destructor*/ - virtual ~MaterialSerializer() {} - - /** Queue an in-memory Material to the internal buffer for export. - @param pMat Material pointer - @param clearQueued If true, any materials already queued will be removed - @param exportDefaults If true, attributes which are defaulted will be - included in the script exported, otherwise they will be omitted - @param materialName Allow exporting the given material under a different name. - In case of empty string the original material name will be used. - */ + + /** Internal methods that invokes registered listeners callback. + @see Listener::materialEventRaised. + */ + void fireMaterialEvent(SerializeEvent event, bool& skip, const Material* mat); + + /** Internal methods that invokes registered listeners callback. + @see Listener::techniqueEventRaised. + */ + void fireTechniqueEvent(SerializeEvent event, bool& skip, const Technique* tech); + + /** Internal methods that invokes registered listeners callback. + @see Listener::passEventRaised. + */ + void firePassEvent(SerializeEvent event, bool& skip, const Pass* pass); + + /** Internal methods that invokes registered listeners callback. + @see Listener::gpuProgramRefEventRaised. + */ + void fireGpuProgramRefEvent(SerializeEvent event, bool& skip, + const String& attrib, + const GpuProgramPtr& program, + const GpuProgramParametersSharedPtr& params, + GpuProgramParameters* defaultParams); + + + /** Internal methods that invokes registered listeners callback. + @see Listener::textureUnitStateEventRaised. + */ + void fireTextureUnitStateEvent(SerializeEvent event, bool& skip, const TextureUnitState* textureUnit); + + public: + /** default constructor*/ + MaterialSerializer(); + /** default destructor*/ + virtual ~MaterialSerializer() {} + + /** Queue an in-memory Material to the internal buffer for export. + @param pMat Material pointer + @param clearQueued If true, any materials already queued will be removed + @param exportDefaults If true, attributes which are defaulted will be + included in the script exported, otherwise they will be omitted + @param materialName Allow exporting the given material under a different name. + In case of empty string the original material name will be used. + */ void queueForExport(const MaterialPtr& pMat, bool clearQueued = false, - bool exportDefaults = false, const String& materialName = ""); + bool exportDefaults = false, const String& materialName = ""); /** Exports queued material(s) to a named material script file. @param filename the file name of the material script to be exported - @param includeProgDef If true, vertex program and fragment program - definitions will be written at the top of the material script + @param includeProgDef If true, vertex program and fragment program + definitions will be written at the top of the material script @param programFilename the file name of the vertex / fragment program - script to be exported. This is only used if there are program definitions + script to be exported. This is only used if there are program definitions to be exported and includeProgDef is false - when calling queueForExport. + when calling queueForExport. */ - void exportQueued(const String& filename, const bool includeProgDef = false, const String& programFilename = ""); + void exportQueued(const String& filename, const bool includeProgDef = false, const String& programFilename = ""); /** Exports a single in-memory Material to the named material script file. @param exportDefaults if true then exports all values including defaults @param includeProgDef if true includes Gpu shader program definitions in the @@ -349,103 +349,103 @@ namespace Ogre { be exported to a separate file with name programFilename if programFilename is not empty @param programFilename the file name of the vertex / fragment program - script to be exported. This is only used if includeProgDef is false. - @param materialName Allow exporting the given material under a different name. - In case of empty string the original material name will be used. + script to be exported. This is only used if includeProgDef is false. + @param materialName Allow exporting the given material under a different name. + In case of empty string the original material name will be used. */ void exportMaterial(const MaterialPtr& pMat, const String& filename, bool exportDefaults = false, const bool includeProgDef = false, const String& programFilename = "", - const String& materialName = ""); - /** Returns a string representing the parsed material(s) */ - const String &getQueuedAsString() const; - /** Clears the internal buffer */ - void clearQueue(); + const String& materialName = ""); + /** Returns a string representing the parsed material(s) */ + const String &getQueuedAsString() const; + /** Clears the internal buffer */ + void clearQueue(); /** Parses a Material script file passed as a stream. */ void parseScript(DataStreamPtr& stream, const String& groupName); - /** Register a listener to this Serializer. - @see MaterialSerializer::Listener - */ - void addListener(Listener* listener); + /** Register a listener to this Serializer. + @see MaterialSerializer::Listener + */ + void addListener(Listener* listener); - /** Remove a listener from this Serializer. - @see MaterialSerializer::Listener - */ - void removeListener(Listener* listener); + /** Remove a listener from this Serializer. + @see MaterialSerializer::Listener + */ + void removeListener(Listener* listener); - private: - String mBuffer; + private: + String mBuffer; String mGpuProgramBuffer; typedef set::type GpuProgramDefinitionContainer; typedef GpuProgramDefinitionContainer::iterator GpuProgramDefIterator; GpuProgramDefinitionContainer mGpuProgramDefinitionContainer; - bool mDefaults; - - public: + bool mDefaults; + + public: void beginSection(unsigned short level, const bool useMainBuffer = true) - { + { String& buffer = (useMainBuffer ? mBuffer : mGpuProgramBuffer); - buffer += "\n"; + buffer += "\n"; for (unsigned short i = 0; i < level; ++i) { buffer += "\t"; } buffer += "{"; - } - void endSection(unsigned short level, const bool useMainBuffer = true) - { + } + void endSection(unsigned short level, const bool useMainBuffer = true) + { String& buffer = (useMainBuffer ? mBuffer : mGpuProgramBuffer); - buffer += "\n"; + buffer += "\n"; for (unsigned short i = 0; i < level; ++i) { buffer += "\t"; } buffer += "}"; - } + } - void writeAttribute(unsigned short level, const String& att, const bool useMainBuffer = true) - { + void writeAttribute(unsigned short level, const String& att, const bool useMainBuffer = true) + { String& buffer = (useMainBuffer ? mBuffer : mGpuProgramBuffer); - buffer += "\n"; + buffer += "\n"; for (unsigned short i = 0; i < level; ++i) { buffer += "\t"; } buffer += att; - } + } - void writeValue(const String& val, const bool useMainBuffer = true) - { + void writeValue(const String& val, const bool useMainBuffer = true) + { String& buffer = (useMainBuffer ? mBuffer : mGpuProgramBuffer); - buffer += (" " + val); - } + buffer += (" " + val); + } - String quoteWord(const String& val) - { - if (val.find_first_of(" \t") != String::npos) - return ("\"" + val + "\""); - else return val; - } + String quoteWord(const String& val) + { + if (val.find_first_of(" \t") != String::npos) + return ("\"" + val + "\""); + else return val; + } - void writeComment(unsigned short level, const String& comment, const bool useMainBuffer = true) - { + void writeComment(unsigned short level, const String& comment, const bool useMainBuffer = true) + { String& buffer = (useMainBuffer ? mBuffer : mGpuProgramBuffer); - buffer += "\n"; + buffer += "\n"; for (unsigned short i = 0; i < level; ++i) { buffer += "\t"; } buffer += "// " + comment; - } + } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreMath.h b/OgreMain/include/OgreMath.h index 5c812d96b77..851a75ea1fb 100644 --- a/OgreMain/include/OgreMath.h +++ b/OgreMain/include/OgreMath.h @@ -33,113 +33,113 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Wrapper class which indicates a given angle value is in Radians. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Wrapper class which indicates a given angle value is in Radians. @remarks Radian values are interchangeable with Degree values, and conversions will be done automatically between them. */ - class Radian - { - Real mRad; + class Radian + { + Real mRad; - public: - explicit Radian ( Real r=0 ) : mRad(r) {} - Radian ( const Degree& d ); - Radian& operator = ( const Real& f ) { mRad = f; return *this; } - Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; } - Radian& operator = ( const Degree& d ); + public: + explicit Radian ( Real r=0 ) : mRad(r) {} + Radian ( const Degree& d ); + Radian& operator = ( const Real& f ) { mRad = f; return *this; } + Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; } + Radian& operator = ( const Degree& d ); - Real valueDegrees() const; // see bottom of this file - Real valueRadians() const { return mRad; } - Real valueAngleUnits() const; + Real valueDegrees() const; // see bottom of this file + Real valueRadians() const { return mRad; } + Real valueAngleUnits() const; const Radian& operator + () const { return *this; } - Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); } - Radian operator + ( const Degree& d ) const; - Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; } - Radian& operator += ( const Degree& d ); - Radian operator - () const { return Radian(-mRad); } - Radian operator - ( const Radian& r ) const { return Radian ( mRad - r.mRad ); } - Radian operator - ( const Degree& d ) const; - Radian& operator -= ( const Radian& r ) { mRad -= r.mRad; return *this; } - Radian& operator -= ( const Degree& d ); - Radian operator * ( Real f ) const { return Radian ( mRad * f ); } + Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); } + Radian operator + ( const Degree& d ) const; + Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; } + Radian& operator += ( const Degree& d ); + Radian operator - () const { return Radian(-mRad); } + Radian operator - ( const Radian& r ) const { return Radian ( mRad - r.mRad ); } + Radian operator - ( const Degree& d ) const; + Radian& operator -= ( const Radian& r ) { mRad -= r.mRad; return *this; } + Radian& operator -= ( const Degree& d ); + Radian operator * ( Real f ) const { return Radian ( mRad * f ); } Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); } - Radian& operator *= ( Real f ) { mRad *= f; return *this; } - Radian operator / ( Real f ) const { return Radian ( mRad / f ); } - Radian& operator /= ( Real f ) { mRad /= f; return *this; } - - bool operator < ( const Radian& r ) const { return mRad < r.mRad; } - bool operator <= ( const Radian& r ) const { return mRad <= r.mRad; } - bool operator == ( const Radian& r ) const { return mRad == r.mRad; } - bool operator != ( const Radian& r ) const { return mRad != r.mRad; } - bool operator >= ( const Radian& r ) const { return mRad >= r.mRad; } - bool operator > ( const Radian& r ) const { return mRad > r.mRad; } - - inline _OgreExport friend std::ostream& operator << - ( std::ostream& o, const Radian& v ) - { - o << "Radian(" << v.valueRadians() << ")"; - return o; - } - }; + Radian& operator *= ( Real f ) { mRad *= f; return *this; } + Radian operator / ( Real f ) const { return Radian ( mRad / f ); } + Radian& operator /= ( Real f ) { mRad /= f; return *this; } + + bool operator < ( const Radian& r ) const { return mRad < r.mRad; } + bool operator <= ( const Radian& r ) const { return mRad <= r.mRad; } + bool operator == ( const Radian& r ) const { return mRad == r.mRad; } + bool operator != ( const Radian& r ) const { return mRad != r.mRad; } + bool operator >= ( const Radian& r ) const { return mRad >= r.mRad; } + bool operator > ( const Radian& r ) const { return mRad > r.mRad; } + + inline _OgreExport friend std::ostream& operator << + ( std::ostream& o, const Radian& v ) + { + o << "Radian(" << v.valueRadians() << ")"; + return o; + } + }; /** Wrapper class which indicates a given angle value is in Degrees. @remarks Degree values are interchangeable with Radian values, and conversions will be done automatically between them. */ - class Degree - { - Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first - - public: - explicit Degree ( Real d=0 ) : mDeg(d) {} - Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {} - Degree& operator = ( const Real& f ) { mDeg = f; return *this; } - Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; } - Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; } - - Real valueDegrees() const { return mDeg; } - Real valueRadians() const; // see bottom of this file - Real valueAngleUnits() const; - - const Degree& operator + () const { return *this; } - Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); } - Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); } - Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; } - Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; } - Degree operator - () const { return Degree(-mDeg); } - Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); } - Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); } - Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; } - Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; } - Degree operator * ( Real f ) const { return Degree ( mDeg * f ); } + class Degree + { + Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first + + public: + explicit Degree ( Real d=0 ) : mDeg(d) {} + Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {} + Degree& operator = ( const Real& f ) { mDeg = f; return *this; } + Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; } + Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; } + + Real valueDegrees() const { return mDeg; } + Real valueRadians() const; // see bottom of this file + Real valueAngleUnits() const; + + const Degree& operator + () const { return *this; } + Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); } + Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); } + Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; } + Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; } + Degree operator - () const { return Degree(-mDeg); } + Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); } + Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); } + Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; } + Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; } + Degree operator * ( Real f ) const { return Degree ( mDeg * f ); } Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); } - Degree& operator *= ( Real f ) { mDeg *= f; return *this; } - Degree operator / ( Real f ) const { return Degree ( mDeg / f ); } - Degree& operator /= ( Real f ) { mDeg /= f; return *this; } - - bool operator < ( const Degree& d ) const { return mDeg < d.mDeg; } - bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; } - bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; } - bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; } - bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; } - bool operator > ( const Degree& d ) const { return mDeg > d.mDeg; } - - inline _OgreExport friend std::ostream& operator << - ( std::ostream& o, const Degree& v ) - { - o << "Degree(" << v.valueDegrees() << ")"; - return o; - } - }; + Degree& operator *= ( Real f ) { mDeg *= f; return *this; } + Degree operator / ( Real f ) const { return Degree ( mDeg / f ); } + Degree& operator /= ( Real f ) { mDeg /= f; return *this; } + + bool operator < ( const Degree& d ) const { return mDeg < d.mDeg; } + bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; } + bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; } + bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; } + bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; } + bool operator > ( const Degree& d ) const { return mDeg > d.mDeg; } + + inline _OgreExport friend std::ostream& operator << + ( std::ostream& o, const Degree& v ) + { + o << "Degree(" << v.valueDegrees() << ")"; + return o; + } + }; /** Wrapper class which identifies a value as the currently default angle type, as defined by Math::setAngleUnit. @@ -147,36 +147,36 @@ namespace Ogre Angle values will be automatically converted between radians and degrees, as appropriate. */ - class Angle - { - Real mAngle; - public: - explicit Angle ( Real angle ) : mAngle(angle) {} - operator Radian() const; - operator Degree() const; - }; - - // these functions could not be defined within the class definition of class - // Radian because they required class Degree to be defined - inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) { - } - inline Radian& Radian::operator = ( const Degree& d ) { - mRad = d.valueRadians(); return *this; - } - inline Radian Radian::operator + ( const Degree& d ) const { - return Radian ( mRad + d.valueRadians() ); - } - inline Radian& Radian::operator += ( const Degree& d ) { - mRad += d.valueRadians(); - return *this; - } - inline Radian Radian::operator - ( const Degree& d ) const { - return Radian ( mRad - d.valueRadians() ); - } - inline Radian& Radian::operator -= ( const Degree& d ) { - mRad -= d.valueRadians(); - return *this; - } + class Angle + { + Real mAngle; + public: + explicit Angle ( Real angle ) : mAngle(angle) {} + operator Radian() const; + operator Degree() const; + }; + + // these functions could not be defined within the class definition of class + // Radian because they required class Degree to be defined + inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) { + } + inline Radian& Radian::operator = ( const Degree& d ) { + mRad = d.valueRadians(); return *this; + } + inline Radian Radian::operator + ( const Degree& d ) const { + return Radian ( mRad + d.valueRadians() ); + } + inline Radian& Radian::operator += ( const Degree& d ) { + mRad += d.valueRadians(); + return *this; + } + inline Radian Radian::operator - ( const Degree& d ) const { + return Radian ( mRad - d.valueRadians() ); + } + inline Radian& Radian::operator -= ( const Degree& d ) { + mRad -= d.valueRadians(); + return *this; + } /** Class to provide access to common mathematical functions. @remarks @@ -190,11 +190,11 @@ namespace Ogre */ class _OgreExport Math { - public: + public: /** The angular units used by the API. This functionality is now deprecated in favor - of discreet angular unit types ( see Degree and Radian above ). The only place - this functionality is actually still used is when parsing files. Search for - usage of the Angle class for those instances + of discreet angular unit types ( see Degree and Radian above ). The only place + this functionality is actually still used is when parsing files. Search for + usage of the Angle class for those instances */ enum AngleUnit { @@ -246,22 +246,22 @@ namespace Ogre */ ~Math(); - static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); } - static inline int ICeil (float fValue) { return int(ceil(fValue)); } - static inline int IFloor (float fValue) { return int(floor(fValue)); } + static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); } + static inline int ICeil (float fValue) { return int(ceil(fValue)); } + static inline int IFloor (float fValue) { return int(floor(fValue)); } static int ISign (int iValue); /** Absolute value function @param fValue The value whose absolute value will be returned. */ - static inline Real Abs (Real fValue) { return Real(fabs(fValue)); } + static inline Real Abs (Real fValue) { return Real(fabs(fValue)); } /** Absolute value function @param dValue The value, in degrees, whose absolute value will be returned. */ - static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); } + static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); } /** Absolute value function @param rValue @@ -273,19 +273,19 @@ namespace Ogre @param fValue The value whose arc cosine will be returned. */ - static Radian ACos (Real fValue); + static Radian ACos (Real fValue); /** Arc sine function @param fValue The value whose arc sine will be returned. */ - static Radian ASin (Real fValue); + static Radian ASin (Real fValue); /** Arc tangent function @param fValue The value whose arc tangent will be returned. */ - static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); } + static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); } /** Arc tangent between two values function @param fY @@ -293,7 +293,7 @@ namespace Ogre @param fX The second value to calculate the arc tangent with. */ - static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); } + static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); } /** Ceiling function Returns the smallest following integer. (example: Ceil(1.1) = 2) @@ -301,13 +301,13 @@ namespace Ogre @param fValue The value to round up to the nearest integer. */ - static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); } - static inline bool isNaN(Real f) - { - // std::isnan() is C99, not supported by all compilers - // However NaN always fails this next test, no other number does. - return f != f; - } + static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); } + static inline bool isNaN(Real f) + { + // std::isnan() is C99, not supported by all compilers + // However NaN always fails this next test, no other number does. + return f != f; + } /** Cosine function. @param fValue @@ -317,8 +317,8 @@ namespace Ogre calculation - faster but less accurate. */ static inline Real Cos (const Radian& fValue, bool useTables = false) { - return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI); - } + return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI); + } /** Cosine function. @param fValue Angle in radians @@ -327,10 +327,10 @@ namespace Ogre calculation - faster but less accurate. */ static inline Real Cos (Real fValue, bool useTables = false) { - return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI); - } + return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI); + } - static inline Real Exp (Real fValue) { return Real(exp(fValue)); } + static inline Real Exp (Real fValue) { return Real(exp(fValue)); } /** Floor function Returns the largest previous integer. (example: Floor(1.9) = 1) @@ -379,8 +379,8 @@ namespace Ogre calculation - faster but less accurate. */ static inline Real Sin (const Radian& fValue, bool useTables = false) { - return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians()); - } + return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians()); + } /** Sine function. @param fValue Angle in radians @@ -389,20 +389,20 @@ namespace Ogre calculation - faster but less accurate. */ static inline Real Sin (Real fValue, bool useTables = false) { - return (!useTables) ? Real(sin(fValue)) : SinTable(fValue); - } + return (!useTables) ? Real(sin(fValue)) : SinTable(fValue); + } /** Squared function. @param fValue The value to be squared (fValue^2) */ - static inline Real Sqr (Real fValue) { return fValue*fValue; } + static inline Real Sqr (Real fValue) { return fValue*fValue; } /** Square root function. @param fValue The value whose square root will be calculated. */ - static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); } + static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); } /** Square root function. @param fValue @@ -425,7 +425,7 @@ namespace Ogre @param fValue The value whose inverse square root will be calculated. */ - static Real InvSqrt (Real fValue); + static Real InvSqrt (Real fValue); /** Generate a random number of unit length. @return @@ -458,9 +458,9 @@ namespace Ogre If true, uses lookup tables rather than calculation - faster but less accurate. */ - static inline Real Tan (const Radian& fValue, bool useTables = false) { - return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians()); - } + static inline Real Tan (const Radian& fValue, bool useTables = false) { + return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians()); + } /** Tangent function. @param fValue Angle in radians @@ -468,11 +468,11 @@ namespace Ogre If true, uses lookup tables rather than calculation - faster but less accurate. */ - static inline Real Tan (Real fValue, bool useTables = false) { - return (!useTables) ? Real(tan(fValue)) : TanTable(fValue); - } + static inline Real Tan (Real fValue, bool useTables = false) { + return (!useTables) ? Real(tan(fValue)) : TanTable(fValue); + } - static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; } + static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; } static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; } /** These functions used to set the assumed angle units (radians or degrees) @@ -516,14 +516,14 @@ namespace Ogre returned. */ static bool pointInTri2D(const Vector2& p, const Vector2& a, - const Vector2& b, const Vector2& c); + const Vector2& b, const Vector2& c); /** Checks whether a given 3D point is inside a triangle. @remarks The vertices of the triangle must be given in either trigonometrical (anticlockwise) or inverse trigonometrical (clockwise) order, and the point must be guaranteed to be in the - same plane as the triangle + same plane as the triangle @param p p The point. @param a @@ -532,9 +532,9 @@ namespace Ogre The triangle's second vertex. @param c The triangle's third vertex. - @param normal - The triangle plane's normal (passed in rather than calculated - on demand since the caller may already have it) + @param normal + The triangle plane's normal (passed in rather than calculated + on demand since the caller may already have it) @return If the point resides in the triangle, true is returned. @@ -543,7 +543,7 @@ namespace Ogre returned. */ static bool pointInTri3D(const Vector3& p, const Vector3& a, - const Vector3& b, const Vector3& c, const Vector3& normal); + const Vector3& b, const Vector3& c, const Vector3& normal); /** Ray / plane intersection, returns boolean result and distance. */ static std::pair intersects(const Ray& ray, const Plane& plane); @@ -588,9 +588,9 @@ namespace Ogre The triangle's second vertex. @param c The triangle's third vertex. - @param normal - The triangle plane's normal (passed in rather than calculated - on demand since the caller may already have it), doesn't need + @param normal + The triangle plane's normal (passed in rather than calculated + on demand since the caller may already have it), doesn't need normalised since we don't care. @param positiveSide Intersect with "positive side" of the triangle @@ -680,24 +680,24 @@ namespace Ogre /** Calculate a face normal without normalize, no w-information. */ static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); - /** Generates a value based on the Gaussian (normal) distribution function - with the given offset and scale parameters. - */ - static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f); + /** Generates a value based on the Gaussian (normal) distribution function + with the given offset and scale parameters. + */ + static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f); - /** Clamp a value within an inclusive range. */ - template - static T Clamp(T val, T minval, T maxval) - { - assert (minval <= maxval && "Invalid clamp range"); - return std::max(std::min(val, maxval), minval); - } + /** Clamp a value within an inclusive range. */ + template + static T Clamp(T val, T minval, T maxval) + { + assert (minval <= maxval && "Invalid clamp range"); + return std::max(std::min(val, maxval), minval); + } - static Matrix4 makeViewMatrix(const Vector3& position, const Quaternion& orientation, - const Matrix4* reflectMatrix = 0); + static Matrix4 makeViewMatrix(const Vector3& position, const Quaternion& orientation, + const Matrix4* reflectMatrix = 0); - /** Get a bounding radius value from a bounding box. */ - static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb); + /** Get a bounding radius value from a bounding box. */ + static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb); @@ -706,65 +706,65 @@ namespace Ogre static const Real PI; static const Real TWO_PI; static const Real HALF_PI; - static const Real fDeg2Rad; - static const Real fRad2Deg; + static const Real fDeg2Rad; + static const Real fRad2Deg; }; - // these functions must be defined down here, because they rely on the - // angle unit conversion functions in class Math: - - inline Real Radian::valueDegrees() const - { - return Math::RadiansToDegrees ( mRad ); - } - - inline Real Radian::valueAngleUnits() const - { - return Math::RadiansToAngleUnits ( mRad ); - } - - inline Real Degree::valueRadians() const - { - return Math::DegreesToRadians ( mDeg ); - } - - inline Real Degree::valueAngleUnits() const - { - return Math::DegreesToAngleUnits ( mDeg ); - } - - inline Angle::operator Radian() const - { - return Radian(Math::AngleUnitsToRadians(mAngle)); - } - - inline Angle::operator Degree() const - { - return Degree(Math::AngleUnitsToDegrees(mAngle)); - } - - inline Radian operator * ( Real a, const Radian& b ) - { - return Radian ( a * b.valueRadians() ); - } - - inline Radian operator / ( Real a, const Radian& b ) - { - return Radian ( a / b.valueRadians() ); - } - - inline Degree operator * ( Real a, const Degree& b ) - { - return Degree ( a * b.valueDegrees() ); - } - - inline Degree operator / ( Real a, const Degree& b ) - { - return Degree ( a / b.valueDegrees() ); - } - /** @} */ - /** @} */ + // these functions must be defined down here, because they rely on the + // angle unit conversion functions in class Math: + + inline Real Radian::valueDegrees() const + { + return Math::RadiansToDegrees ( mRad ); + } + + inline Real Radian::valueAngleUnits() const + { + return Math::RadiansToAngleUnits ( mRad ); + } + + inline Real Degree::valueRadians() const + { + return Math::DegreesToRadians ( mDeg ); + } + + inline Real Degree::valueAngleUnits() const + { + return Math::DegreesToAngleUnits ( mDeg ); + } + + inline Angle::operator Radian() const + { + return Radian(Math::AngleUnitsToRadians(mAngle)); + } + + inline Angle::operator Degree() const + { + return Degree(Math::AngleUnitsToDegrees(mAngle)); + } + + inline Radian operator * ( Real a, const Radian& b ) + { + return Radian ( a * b.valueRadians() ); + } + + inline Radian operator / ( Real a, const Radian& b ) + { + return Radian ( a / b.valueRadians() ); + } + + inline Degree operator * ( Real a, const Degree& b ) + { + return Degree ( a * b.valueDegrees() ); + } + + inline Degree operator / ( Real a, const Degree& b ) + { + return Degree ( a / b.valueDegrees() ); + } + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreMatrix3.h b/OgreMain/include/OgreMatrix3.h index a5463294dda..c7e906aea0f 100644 --- a/OgreMain/include/OgreMatrix3.h +++ b/OgreMain/include/OgreMatrix3.h @@ -52,13 +52,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** A 3x3 matrix which can represent rotations around axes. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** A 3x3 matrix which can represent rotations around axes. @note All the code is adapted from the Wild Magic 0.2 Matrix library (http://www.geometrictools.com/). @@ -72,44 +72,44 @@ namespace Ogre @note It does NOT initialize the matrix for efficiency. */ - inline Matrix3 () {} + inline Matrix3 () {} inline explicit Matrix3 (const Real arr[3][3]) - { - memcpy(m,arr,9*sizeof(Real)); - } + { + memcpy(m,arr,9*sizeof(Real)); + } inline Matrix3 (const Matrix3& rkMatrix) - { - memcpy(m,rkMatrix.m,9*sizeof(Real)); - } + { + memcpy(m,rkMatrix.m,9*sizeof(Real)); + } Matrix3 (Real fEntry00, Real fEntry01, Real fEntry02, Real fEntry10, Real fEntry11, Real fEntry12, Real fEntry20, Real fEntry21, Real fEntry22) - { - m[0][0] = fEntry00; - m[0][1] = fEntry01; - m[0][2] = fEntry02; - m[1][0] = fEntry10; - m[1][1] = fEntry11; - m[1][2] = fEntry12; - m[2][0] = fEntry20; - m[2][1] = fEntry21; - m[2][2] = fEntry22; - } - - /** Exchange the contents of this matrix with another. - */ - inline void swap(Matrix3& other) - { - std::swap(m[0][0], other.m[0][0]); - std::swap(m[0][1], other.m[0][1]); - std::swap(m[0][2], other.m[0][2]); - std::swap(m[1][0], other.m[1][0]); - std::swap(m[1][1], other.m[1][1]); - std::swap(m[1][2], other.m[1][2]); - std::swap(m[2][0], other.m[2][0]); - std::swap(m[2][1], other.m[2][1]); - std::swap(m[2][2], other.m[2][2]); - } + { + m[0][0] = fEntry00; + m[0][1] = fEntry01; + m[0][2] = fEntry02; + m[1][0] = fEntry10; + m[1][1] = fEntry11; + m[1][2] = fEntry12; + m[2][0] = fEntry20; + m[2][1] = fEntry21; + m[2][2] = fEntry22; + } + + /** Exchange the contents of this matrix with another. + */ + inline void swap(Matrix3& other) + { + std::swap(m[0][0], other.m[0][0]); + std::swap(m[0][1], other.m[0][1]); + std::swap(m[0][2], other.m[0][2]); + std::swap(m[1][0], other.m[1][0]); + std::swap(m[1][1], other.m[1][1]); + std::swap(m[1][2], other.m[1][2]); + std::swap(m[2][0], other.m[2][0]); + std::swap(m[2][1], other.m[2][1]); + std::swap(m[2][2], other.m[2][2]); + } /// Member access, allows use of construct mat[r][c] inline const Real* operator[] (size_t iRow) const @@ -125,19 +125,19 @@ namespace Ogre /*inline operator Real* () - { - return (Real*)m[0]; - }*/ + { + return (Real*)m[0]; + }*/ Vector3 GetColumn (size_t iCol) const; void SetColumn(size_t iCol, const Vector3& vec); void FromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis); /// Assignment and comparison inline Matrix3& operator= (const Matrix3& rkMatrix) - { - memcpy(m,rkMatrix.m,9*sizeof(Real)); - return *this; - } + { + memcpy(m,rkMatrix.m,9*sizeof(Real)); + return *this; + } /** Tests 2 matrices for equality. */ @@ -146,9 +146,9 @@ namespace Ogre /** Tests 2 matrices for inequality. */ inline bool operator!= (const Matrix3& rkMatrix) const - { - return !operator==(rkMatrix); - } + { + return !operator==(rkMatrix); + } // arithmetic operations /** Matrix addition. @@ -200,11 +200,11 @@ namespace Ogre /// Note: Matrix must be orthonormal void ToAngleAxis (Vector3& rkAxis, Radian& rfAngle) const; - inline void ToAngleAxis (Vector3& rkAxis, Degree& rfAngle) const { - Radian r; - ToAngleAxis ( rkAxis, r ); - rfAngle = r; - } + inline void ToAngleAxis (Vector3& rkAxis, Degree& rfAngle) const { + Radian r; + ToAngleAxis ( rkAxis, r ); + rfAngle = r; + } void FromAngleAxis (const Vector3& rkAxis, const Radian& fRadians); /** The matrix must be orthonormal. The decomposition is yaw*pitch*roll @@ -235,33 +235,33 @@ namespace Ogre static void TensorProduct (const Vector3& rkU, const Vector3& rkV, Matrix3& rkProduct); - /** Determines if this matrix involves a scaling. */ - inline bool hasScale() const - { - // check magnitude of column vectors (==local axes) - Real t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0]; - if (!Math::RealEqual(t, 1.0, (Real)1e-04)) - return true; - t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1]; - if (!Math::RealEqual(t, 1.0, (Real)1e-04)) - return true; - t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2]; - if (!Math::RealEqual(t, 1.0, (Real)1e-04)) - return true; - - return false; - } - - /** Function for writing to a stream. - */ - inline _OgreExport friend std::ostream& operator << - ( std::ostream& o, const Matrix3& mat ) - { - o << "Matrix3(" << mat[0][0] << ", " << mat[0][1] << ", " << mat[0][2] << ", " + /** Determines if this matrix involves a scaling. */ + inline bool hasScale() const + { + // check magnitude of column vectors (==local axes) + Real t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0]; + if (!Math::RealEqual(t, 1.0, (Real)1e-04)) + return true; + t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1]; + if (!Math::RealEqual(t, 1.0, (Real)1e-04)) + return true; + t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2]; + if (!Math::RealEqual(t, 1.0, (Real)1e-04)) + return true; + + return false; + } + + /** Function for writing to a stream. + */ + inline _OgreExport friend std::ostream& operator << + ( std::ostream& o, const Matrix3& mat ) + { + o << "Matrix3(" << mat[0][0] << ", " << mat[0][1] << ", " << mat[0][2] << ", " << mat[1][0] << ", " << mat[1][1] << ", " << mat[1][2] << ", " << mat[2][0] << ", " << mat[2][1] << ", " << mat[2][2] << ")"; - return o; - } + return o; + } static const Real EPSILON; static const Matrix3 ZERO; @@ -288,7 +288,7 @@ namespace Ogre // for faster access friend class Matrix4; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreMatrix4.h b/OgreMain/include/OgreMatrix4.h index 4fa10b9e8f6..55d3a52cde2 100644 --- a/OgreMain/include/OgreMatrix4.h +++ b/OgreMain/include/OgreMatrix4.h @@ -36,13 +36,13 @@ THE SOFTWARE. #include "OgrePlane.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Class encapsulating a standard 4x4 homogeneous matrix. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Class encapsulating a standard 4x4 homogeneous matrix. @remarks OGRE uses column vectors when applying matrix multiplications, This means a vector is represented as a single column, 4-row @@ -136,29 +136,29 @@ namespace Ogre } - /** Exchange the contents of this matrix with another. - */ - inline void swap(Matrix4& other) - { - std::swap(m[0][0], other.m[0][0]); - std::swap(m[0][1], other.m[0][1]); - std::swap(m[0][2], other.m[0][2]); - std::swap(m[0][3], other.m[0][3]); - std::swap(m[1][0], other.m[1][0]); - std::swap(m[1][1], other.m[1][1]); - std::swap(m[1][2], other.m[1][2]); - std::swap(m[1][3], other.m[1][3]); - std::swap(m[2][0], other.m[2][0]); - std::swap(m[2][1], other.m[2][1]); - std::swap(m[2][2], other.m[2][2]); - std::swap(m[2][3], other.m[2][3]); - std::swap(m[3][0], other.m[3][0]); - std::swap(m[3][1], other.m[3][1]); - std::swap(m[3][2], other.m[3][2]); - std::swap(m[3][3], other.m[3][3]); - } - - inline Real* operator [] ( size_t iRow ) + /** Exchange the contents of this matrix with another. + */ + inline void swap(Matrix4& other) + { + std::swap(m[0][0], other.m[0][0]); + std::swap(m[0][1], other.m[0][1]); + std::swap(m[0][2], other.m[0][2]); + std::swap(m[0][3], other.m[0][3]); + std::swap(m[1][0], other.m[1][0]); + std::swap(m[1][1], other.m[1][1]); + std::swap(m[1][2], other.m[1][2]); + std::swap(m[1][3], other.m[1][3]); + std::swap(m[2][0], other.m[2][0]); + std::swap(m[2][1], other.m[2][1]); + std::swap(m[2][2], other.m[2][2]); + std::swap(m[2][3], other.m[2][3]); + std::swap(m[3][0], other.m[3][0]); + std::swap(m[3][1], other.m[3][1]); + std::swap(m[3][2], other.m[3][2]); + std::swap(m[3][3], other.m[3][3]); + } + + inline Real* operator [] ( size_t iRow ) { assert( iRow < 4 ); return m[iRow]; @@ -236,13 +236,13 @@ namespace Ogre inline Plane operator * (const Plane& p) const { Plane ret; - Matrix4 invTrans = inverse().transpose(); - Vector4 v4( p.normal.x, p.normal.y, p.normal.z, p.d ); - v4 = invTrans * v4; - ret.normal.x = v4.x; - ret.normal.y = v4.y; - ret.normal.z = v4.z; - ret.d = v4.w / ret.normal.normalise(); + Matrix4 invTrans = inverse().transpose(); + Vector4 v4( p.normal.x, p.normal.y, p.normal.z, p.d ); + v4 = invTrans * v4; + ret.normal.x = v4.x; + ret.normal.y = v4.y; + ret.normal.z = v4.z; + ret.d = v4.w / ret.normal.normalise(); return ret; } @@ -473,30 +473,30 @@ namespace Ogre } - /** Determines if this matrix involves a scaling. */ - inline bool hasScale() const - { - // check magnitude of column vectors (==local axes) - Real t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0]; - if (!Math::RealEqual(t, 1.0, (Real)1e-04)) - return true; - t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1]; - if (!Math::RealEqual(t, 1.0, (Real)1e-04)) - return true; - t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2]; - if (!Math::RealEqual(t, 1.0, (Real)1e-04)) - return true; + /** Determines if this matrix involves a scaling. */ + inline bool hasScale() const + { + // check magnitude of column vectors (==local axes) + Real t = m[0][0] * m[0][0] + m[1][0] * m[1][0] + m[2][0] * m[2][0]; + if (!Math::RealEqual(t, 1.0, (Real)1e-04)) + return true; + t = m[0][1] * m[0][1] + m[1][1] * m[1][1] + m[2][1] * m[2][1]; + if (!Math::RealEqual(t, 1.0, (Real)1e-04)) + return true; + t = m[0][2] * m[0][2] + m[1][2] * m[1][2] + m[2][2] * m[2][2]; + if (!Math::RealEqual(t, 1.0, (Real)1e-04)) + return true; - return false; - } + return false; + } - /** Determines if this matrix involves a negative scaling. */ - inline bool hasNegativeScale() const - { - return determinant() < 0; - } + /** Determines if this matrix involves a negative scaling. */ + inline bool hasNegativeScale() const + { + return determinant() < 0; + } - /** Extracts the rotation / scaling part as a quaternion from the Matrix. + /** Extracts the rotation / scaling part as a quaternion from the Matrix. */ inline Quaternion extractQuaternion() const { @@ -505,9 +505,9 @@ namespace Ogre return Quaternion(m3x3); } - static const Matrix4 ZERO; - static const Matrix4 ZEROAFFINE; - static const Matrix4 IDENTITY; + static const Matrix4 ZERO; + static const Matrix4 ZEROAFFINE; + static const Matrix4 IDENTITY; /** Useful little matrix which takes 2D clipspace {-1, 1} to {0,1} and inverts the Y. */ static const Matrix4 CLIPSPACE2DTOIMAGESPACE; @@ -527,7 +527,7 @@ namespace Ogre ( std::ostream& o, const Matrix4& mat ) { o << "Matrix4("; - for (size_t i = 0; i < 4; ++i) + for (size_t i = 0; i < 4; ++i) { o << " row" << (unsigned)i << "{"; for(size_t j = 0; j < 4; ++j) @@ -539,10 +539,10 @@ namespace Ogre o << ")"; return o; } - - Matrix4 adjoint() const; - Real determinant() const; - Matrix4 inverse() const; + + Matrix4 adjoint() const; + Real determinant() const; + Matrix4 inverse() const; /** Building a Matrix4 from orientation / scale / position. @remarks @@ -652,8 +652,8 @@ namespace Ogre v.x*mat[0][3] + v.y*mat[1][3] + v.z*mat[2][3] + v.w*mat[3][3] ); } - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreMemoryAllocatedObject.h b/OgreMain/include/OgreMemoryAllocatedObject.h index 2dad7d5a373..779c4473807 100644 --- a/OgreMain/include/OgreMemoryAllocatedObject.h +++ b/OgreMain/include/OgreMemoryAllocatedObject.h @@ -43,88 +43,88 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Memory - * @{ - */ - /** Superclass for all objects that wish to use custom memory allocators - when their new / delete operators are called. - Requires a template parameter identifying the memory allocator policy - to use (e.g. see StdAllocPolicy). - */ - template - class _OgreExport AllocatedObject - { - public: - explicit AllocatedObject() - { } - - ~AllocatedObject() - { } - - /// operator new, with debug line info - void* operator new(size_t sz, const char* file, int line, const char* func) - { - return Alloc::allocateBytes(sz, file, line, func); - } - - void* operator new(size_t sz) - { - return Alloc::allocateBytes(sz); - } - - /// placement operator new - void* operator new(size_t sz, void* ptr) - { - (void) sz; - return ptr; - } - - /// array operator new, with debug line info - void* operator new[] ( size_t sz, const char* file, int line, const char* func ) - { - return Alloc::allocateBytes(sz, file, line, func); - } - - void* operator new[] ( size_t sz ) - { - return Alloc::allocateBytes(sz); - } - - void operator delete( void* ptr ) - { - Alloc::deallocateBytes(ptr); - } - - // Corresponding operator for placement delete (second param same as the first) - void operator delete( void* ptr, void* ) - { - Alloc::deallocateBytes(ptr); - } - - // only called if there is an exception in corresponding 'new' - void operator delete( void* ptr, const char* , int , const char* ) - { - Alloc::deallocateBytes(ptr); - } - - void operator delete[] ( void* ptr ) - { - Alloc::deallocateBytes(ptr); - } - - - void operator delete[] ( void* ptr, const char* , int , const char* ) - { - Alloc::deallocateBytes(ptr); - } - }; - - - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Memory + * @{ + */ + /** Superclass for all objects that wish to use custom memory allocators + when their new / delete operators are called. + Requires a template parameter identifying the memory allocator policy + to use (e.g. see StdAllocPolicy). + */ + template + class _OgreExport AllocatedObject + { + public: + explicit AllocatedObject() + { } + + ~AllocatedObject() + { } + + /// operator new, with debug line info + void* operator new(size_t sz, const char* file, int line, const char* func) + { + return Alloc::allocateBytes(sz, file, line, func); + } + + void* operator new(size_t sz) + { + return Alloc::allocateBytes(sz); + } + + /// placement operator new + void* operator new(size_t sz, void* ptr) + { + (void) sz; + return ptr; + } + + /// array operator new, with debug line info + void* operator new[] ( size_t sz, const char* file, int line, const char* func ) + { + return Alloc::allocateBytes(sz, file, line, func); + } + + void* operator new[] ( size_t sz ) + { + return Alloc::allocateBytes(sz); + } + + void operator delete( void* ptr ) + { + Alloc::deallocateBytes(ptr); + } + + // Corresponding operator for placement delete (second param same as the first) + void operator delete( void* ptr, void* ) + { + Alloc::deallocateBytes(ptr); + } + + // only called if there is an exception in corresponding 'new' + void operator delete( void* ptr, const char* , int , const char* ) + { + Alloc::deallocateBytes(ptr); + } + + void operator delete[] ( void* ptr ) + { + Alloc::deallocateBytes(ptr); + } + + + void operator delete[] ( void* ptr, const char* , int , const char* ) + { + Alloc::deallocateBytes(ptr); + } + }; + + + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreMemoryAllocatorConfig.h b/OgreMain/include/OgreMemoryAllocatorConfig.h index bf3375a0348..f4c199c15bd 100644 --- a/OgreMain/include/OgreMemoryAllocatorConfig.h +++ b/OgreMain/include/OgreMemoryAllocatorConfig.h @@ -40,147 +40,147 @@ THE SOFTWARE. */ /** @file - This file configures Ogre's memory allocators. You can modify this - file to alter the allocation routines used for Ogre's main objects. - - When customising memory allocation, all you need to do is provide one or - more custom allocation policy classes. These classes need to implement: - - @code - // Allocate bytes - file/line/func information should be optional, - // will be provided when available but not everywhere (e.g. release mode, STL allocations) - static inline void* allocateBytes(size_t count, const char* file = 0, int line = 0, const char* func = 0); - // Free bytes - static inline void deallocateBytes(void* ptr); - // Return the max number of bytes available to be allocated in a single allocation - static inline size_t getMaxAllocationSize(); - @endcode - - Policies are then used as implementations for the wrapper classes and macros - which call them. AllocatedObject for example provides the hooks to override - the new and delete operators for a class and redirect the functionality to the - policy. STLAllocator is a class which is provided to STL containers in order - to hook up allocation of the containers members to the allocation policy. - @par - In addition to linking allocations to policies, this class also defines - a number of macros to allow debugging information to be passed along with - allocations, such as the file and line number they originate from. It's - important to realise that we do not redefine the 'new' and 'delete' symbols - with macros, because that's very difficult to consistently do when other - libraries are also trying to do the same thing; instead we use dedicated - 'OGRE_' prefixed macros. See OGRE_NEW and related items. - @par - The base macros you can use are listed below, in order of preference and - with their conditions stated: -
        -
      • OGRE_NEW - use to allocate an object which have custom new/delete operators - to handle custom allocations, usually this means it's derived from Ogre::AllocatedObject. - Free the memory using OGRE_DELETE. You can in fact use the regular new/delete - for these classes but you won't get any line number debugging if you do. - The memory category is automatically derived for these classes; for all other - allocations you have to specify it. -
      • -
      • OGRE_NEW_T - use to allocate a single class / struct that does not have custom - new/delete operators, either because it is non-virtual (Vector3, Quaternion), - or because it is from an external library (e.g. STL). You must - deallocate with OGRE_DELETE_T if you expect the destructor to be called. - You may free the memory using OGRE_FREE if you are absolutely sure there - is no destructor to be called. - These macros ensure that constructors and destructors are called correctly - even though the memory originates externally (via placement new). Also note - that you have to specify the type and memory category so that the correct - allocator can be derived, when both allocating - and freeing. -
      • -
      • OGRE_NEW_ARRAY_T - as OGRE_NEW_T except with an extra parameter to construct - multiple instances in contiguous memory. Again constructors and destructors - are called. Free with OGRE_DELETE_ARRAY_T. -
      • -
      • OGRE_ALLOC_T - use to allocate a set of primitive types conveniently with type safety. - This can also be used for classes and structs but it is imperative that - you understand that neither the constructor nor the destructor will be called. - Sometimes you want this because it's more efficient just to grab/free a chunk of - memory without having to iterate over each element constructing / destructing. - Free the memory with OGRE_FREE.
      • -
      • OGRE_MALLOC - the most raw form of allocation, just a set of bytes. - Use OGRE_FREE to release.
      • -
      • _SIMD and _ALIGN variants - all of the above have variations which allow - aligned memory allocations. The _SIMD versions align automatically to the - SIMD requirements of your platform, the _ALIGN variants allow user-defined - alignment to be specified.
      • -
      - Here are some examples: - @code - /// AllocatedObject subclass, with custom operator new / delete - AllocatedClass* obj = OGRE_NEW AllocatedClass(); - OGRE_DELETE obj; - AllocatedClass* array = OGRE_NEW AllocatedClass[10]; - OGRE_DELETE [] obj; - /// Non-virtual or external class, constructors / destructors called - ExternalClass* obj = OGRE_NEW_T(ExternalClass, MEMCATEGORY_GENERAL)(constructorArgs); - OGRE_DELETE_T(obj, ExternalClass, MEMCATEGORY_GENERAL); - ExternalClass* obj = OGRE_NEW_ARRAY_T(ExternalClass, 10, MEMCATEGORY_GENERAL); - OGRE_DELETE_ARRAY_T(obj, NonVirtualClass, 10, MEMCATEGORY_GENERAL); - /// Primitive types - long* pLong = OGRE_ALLOC_T(long, 10, MEMCATEGORY_GENERAL); - OGRE_FREE(pLong, MEMCATEGORY_GENERAL); - /// Primitive type with constructor (you can mismatch OGRE_NEW_T and OGRE_FREE because no destructor) - long* pLong = OGRE_NEW_T(long, MEMCATEGORY_GENERAL)(0); - OGRE_FREE(pLong, MEMCATEGORY_GENERAL); - /// Raw memory - void* pVoid = OGRE_MALLOC(1024, MEMCATEGORY_GENERAL); - OGRE_FREE(pVoid, MEMCATEGORY_GENERAL); - @endcode - OGRE_ALLOC_T is also the route to go for allocating real primitive types like - int & float. You free the memory using OGRE_FREE, and both variants have SIMD - and custom alignment variants. + This file configures Ogre's memory allocators. You can modify this + file to alter the allocation routines used for Ogre's main objects. + + When customising memory allocation, all you need to do is provide one or + more custom allocation policy classes. These classes need to implement: + + @code + // Allocate bytes - file/line/func information should be optional, + // will be provided when available but not everywhere (e.g. release mode, STL allocations) + static inline void* allocateBytes(size_t count, const char* file = 0, int line = 0, const char* func = 0); + // Free bytes + static inline void deallocateBytes(void* ptr); + // Return the max number of bytes available to be allocated in a single allocation + static inline size_t getMaxAllocationSize(); + @endcode + + Policies are then used as implementations for the wrapper classes and macros + which call them. AllocatedObject for example provides the hooks to override + the new and delete operators for a class and redirect the functionality to the + policy. STLAllocator is a class which is provided to STL containers in order + to hook up allocation of the containers members to the allocation policy. + @par + In addition to linking allocations to policies, this class also defines + a number of macros to allow debugging information to be passed along with + allocations, such as the file and line number they originate from. It's + important to realise that we do not redefine the 'new' and 'delete' symbols + with macros, because that's very difficult to consistently do when other + libraries are also trying to do the same thing; instead we use dedicated + 'OGRE_' prefixed macros. See OGRE_NEW and related items. + @par + The base macros you can use are listed below, in order of preference and + with their conditions stated: +
        +
      • OGRE_NEW - use to allocate an object which have custom new/delete operators + to handle custom allocations, usually this means it's derived from Ogre::AllocatedObject. + Free the memory using OGRE_DELETE. You can in fact use the regular new/delete + for these classes but you won't get any line number debugging if you do. + The memory category is automatically derived for these classes; for all other + allocations you have to specify it. +
      • +
      • OGRE_NEW_T - use to allocate a single class / struct that does not have custom + new/delete operators, either because it is non-virtual (Vector3, Quaternion), + or because it is from an external library (e.g. STL). You must + deallocate with OGRE_DELETE_T if you expect the destructor to be called. + You may free the memory using OGRE_FREE if you are absolutely sure there + is no destructor to be called. + These macros ensure that constructors and destructors are called correctly + even though the memory originates externally (via placement new). Also note + that you have to specify the type and memory category so that the correct + allocator can be derived, when both allocating + and freeing. +
      • +
      • OGRE_NEW_ARRAY_T - as OGRE_NEW_T except with an extra parameter to construct + multiple instances in contiguous memory. Again constructors and destructors + are called. Free with OGRE_DELETE_ARRAY_T. +
      • +
      • OGRE_ALLOC_T - use to allocate a set of primitive types conveniently with type safety. + This can also be used for classes and structs but it is imperative that + you understand that neither the constructor nor the destructor will be called. + Sometimes you want this because it's more efficient just to grab/free a chunk of + memory without having to iterate over each element constructing / destructing. + Free the memory with OGRE_FREE.
      • +
      • OGRE_MALLOC - the most raw form of allocation, just a set of bytes. + Use OGRE_FREE to release.
      • +
      • _SIMD and _ALIGN variants - all of the above have variations which allow + aligned memory allocations. The _SIMD versions align automatically to the + SIMD requirements of your platform, the _ALIGN variants allow user-defined + alignment to be specified.
      • +
      + Here are some examples: + @code + /// AllocatedObject subclass, with custom operator new / delete + AllocatedClass* obj = OGRE_NEW AllocatedClass(); + OGRE_DELETE obj; + AllocatedClass* array = OGRE_NEW AllocatedClass[10]; + OGRE_DELETE [] obj; + /// Non-virtual or external class, constructors / destructors called + ExternalClass* obj = OGRE_NEW_T(ExternalClass, MEMCATEGORY_GENERAL)(constructorArgs); + OGRE_DELETE_T(obj, ExternalClass, MEMCATEGORY_GENERAL); + ExternalClass* obj = OGRE_NEW_ARRAY_T(ExternalClass, 10, MEMCATEGORY_GENERAL); + OGRE_DELETE_ARRAY_T(obj, NonVirtualClass, 10, MEMCATEGORY_GENERAL); + /// Primitive types + long* pLong = OGRE_ALLOC_T(long, 10, MEMCATEGORY_GENERAL); + OGRE_FREE(pLong, MEMCATEGORY_GENERAL); + /// Primitive type with constructor (you can mismatch OGRE_NEW_T and OGRE_FREE because no destructor) + long* pLong = OGRE_NEW_T(long, MEMCATEGORY_GENERAL)(0); + OGRE_FREE(pLong, MEMCATEGORY_GENERAL); + /// Raw memory + void* pVoid = OGRE_MALLOC(1024, MEMCATEGORY_GENERAL); + OGRE_FREE(pVoid, MEMCATEGORY_GENERAL); + @endcode + OGRE_ALLOC_T is also the route to go for allocating real primitive types like + int & float. You free the memory using OGRE_FREE, and both variants have SIMD + and custom alignment variants. */ /** @} */ /** @} */ namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Memory - * @{ - */ - - /** A set of categories that indicate the purpose of a chunk of memory - being allocated. - These categories will be provided at allocation time in order to allow - the allocation policy to vary its behaviour if it wishes. This allows you - to use a single policy but still have variant behaviour. The level of - control it gives you is at a higher level than assigning different - policies to different classes, but is the only control you have over - general allocations that are primitive types. - */ - enum MemoryCategory - { - /// General purpose - MEMCATEGORY_GENERAL = 0, - /// Geometry held in main memory - MEMCATEGORY_GEOMETRY = 1, - /// Animation data like tracks, bone matrices - MEMCATEGORY_ANIMATION = 2, - /// Nodes, control data - MEMCATEGORY_SCENE_CONTROL = 3, - /// Scene object instances - MEMCATEGORY_SCENE_OBJECTS = 4, - /// Other resources - MEMCATEGORY_RESOURCE = 5, - /// Scripting - MEMCATEGORY_SCRIPTING = 6, - /// Rendersystem structures - MEMCATEGORY_RENDERSYS = 7, - - - // sentinel value, do not use - MEMCATEGORY_COUNT = 8 - }; - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Memory + * @{ + */ + + /** A set of categories that indicate the purpose of a chunk of memory + being allocated. + These categories will be provided at allocation time in order to allow + the allocation policy to vary its behaviour if it wishes. This allows you + to use a single policy but still have variant behaviour. The level of + control it gives you is at a higher level than assigning different + policies to different classes, but is the only control you have over + general allocations that are primitive types. + */ + enum MemoryCategory + { + /// General purpose + MEMCATEGORY_GENERAL = 0, + /// Geometry held in main memory + MEMCATEGORY_GEOMETRY = 1, + /// Animation data like tracks, bone matrices + MEMCATEGORY_ANIMATION = 2, + /// Nodes, control data + MEMCATEGORY_SCENE_CONTROL = 3, + /// Scene object instances + MEMCATEGORY_SCENE_OBJECTS = 4, + /// Other resources + MEMCATEGORY_RESOURCE = 5, + /// Scripting + MEMCATEGORY_SCRIPTING = 6, + /// Rendersystem structures + MEMCATEGORY_RENDERSYS = 7, + + + // sentinel value, do not use + MEMCATEGORY_COUNT = 8 + }; + /** @} */ + /** @} */ } @@ -192,14 +192,14 @@ namespace Ogre # include "OgreMemoryNedPooling.h" namespace Ogre { - // configure default allocators based on the options above - // notice how we're not using the memory categories here but still roughing them out - // in your allocators you might choose to create different policies per category - - // configurable category, for general malloc - // notice how we ignore the category here, you could specialise - template class CategorisedAllocPolicy : public NedPoolingPolicy{}; - template class CategorisedAlignAllocPolicy : public NedPoolingAlignedPolicy{}; + // configure default allocators based on the options above + // notice how we're not using the memory categories here but still roughing them out + // in your allocators you might choose to create different policies per category + + // configurable category, for general malloc + // notice how we ignore the category here, you could specialise + template class CategorisedAllocPolicy : public NedPoolingPolicy{}; + template class CategorisedAlignAllocPolicy : public NedPoolingAlignedPolicy{}; } #elif OGRE_MEMORY_ALLOCATOR == OGRE_MEMORY_ALLOCATOR_NED @@ -207,14 +207,14 @@ namespace Ogre # include "OgreMemoryNedAlloc.h" namespace Ogre { - // configure default allocators based on the options above - // notice how we're not using the memory categories here but still roughing them out - // in your allocators you might choose to create different policies per category - - // configurable category, for general malloc - // notice how we ignore the category here, you could specialise - template class CategorisedAllocPolicy : public NedAllocPolicy{}; - template class CategorisedAlignAllocPolicy : public NedAlignedAllocPolicy{}; + // configure default allocators based on the options above + // notice how we're not using the memory categories here but still roughing them out + // in your allocators you might choose to create different policies per category + + // configurable category, for general malloc + // notice how we ignore the category here, you could specialise + template class CategorisedAllocPolicy : public NedAllocPolicy{}; + template class CategorisedAlignAllocPolicy : public NedAlignedAllocPolicy{}; } #elif OGRE_MEMORY_ALLOCATOR == OGRE_MEMORY_ALLOCATOR_STD @@ -222,108 +222,108 @@ namespace Ogre # include "OgreMemoryStdAlloc.h" namespace Ogre { - // configure default allocators based on the options above - // notice how we're not using the memory categories here but still roughing them out - // in your allocators you might choose to create different policies per category - - // configurable category, for general malloc - // notice how we ignore the category here - template class CategorisedAllocPolicy : public StdAllocPolicy{}; - template class CategorisedAlignAllocPolicy : public StdAlignedAllocPolicy{}; - - // if you wanted to specialise the allocation per category, here's how it might work: - // template <> class CategorisedAllocPolicy : public YourSceneObjectAllocPolicy{}; - // template class CategorisedAlignAllocPolicy : public YourSceneObjectAllocPolicy{}; - - + // configure default allocators based on the options above + // notice how we're not using the memory categories here but still roughing them out + // in your allocators you might choose to create different policies per category + + // configurable category, for general malloc + // notice how we ignore the category here + template class CategorisedAllocPolicy : public StdAllocPolicy{}; + template class CategorisedAlignAllocPolicy : public StdAlignedAllocPolicy{}; + + // if you wanted to specialise the allocation per category, here's how it might work: + // template <> class CategorisedAllocPolicy : public YourSceneObjectAllocPolicy{}; + // template class CategorisedAlignAllocPolicy : public YourSceneObjectAllocPolicy{}; + + } #else - + // your allocators here? #endif namespace Ogre { - // Useful shortcuts - typedef CategorisedAllocPolicy GeneralAllocPolicy; - typedef CategorisedAllocPolicy GeometryAllocPolicy; - typedef CategorisedAllocPolicy AnimationAllocPolicy; - typedef CategorisedAllocPolicy SceneCtlAllocPolicy; - typedef CategorisedAllocPolicy SceneObjAllocPolicy; - typedef CategorisedAllocPolicy ResourceAllocPolicy; - typedef CategorisedAllocPolicy ScriptingAllocPolicy; - typedef CategorisedAllocPolicy RenderSysAllocPolicy; - - // Now define all the base classes for each allocation - typedef AllocatedObject GeneralAllocatedObject; - typedef AllocatedObject GeometryAllocatedObject; - typedef AllocatedObject AnimationAllocatedObject; - typedef AllocatedObject SceneCtlAllocatedObject; - typedef AllocatedObject SceneObjAllocatedObject; - typedef AllocatedObject ResourceAllocatedObject; - typedef AllocatedObject ScriptingAllocatedObject; - typedef AllocatedObject RenderSysAllocatedObject; - - - // Per-class allocators defined here - // NOTE: small, non-virtual classes should not subclass an allocator - // the virtual function table could double their size and make them less efficient - // use primitive or STL allocators / deallocators for those - typedef ScriptingAllocatedObject AbstractNodeAlloc; - typedef AnimationAllocatedObject AnimableAlloc; - typedef AnimationAllocatedObject AnimationAlloc; - typedef GeneralAllocatedObject ArchiveAlloc; - typedef GeometryAllocatedObject BatchedGeometryAlloc; - typedef RenderSysAllocatedObject BufferAlloc; - typedef GeneralAllocatedObject CodecAlloc; - typedef ResourceAllocatedObject CompositorInstAlloc; - typedef GeneralAllocatedObject ConfigAlloc; - typedef GeneralAllocatedObject ControllerAlloc; - typedef GeometryAllocatedObject DebugGeomAlloc; - typedef GeneralAllocatedObject DynLibAlloc; - typedef GeometryAllocatedObject EdgeDataAlloc; - typedef GeneralAllocatedObject FactoryAlloc; - typedef SceneObjAllocatedObject FXAlloc; - typedef GeneralAllocatedObject ImageAlloc; - typedef GeometryAllocatedObject IndexDataAlloc; - typedef GeneralAllocatedObject LogAlloc; - typedef SceneObjAllocatedObject MovableAlloc; - typedef SceneCtlAllocatedObject NodeAlloc; - typedef SceneObjAllocatedObject OverlayAlloc; - typedef RenderSysAllocatedObject GpuParamsAlloc; - typedef ResourceAllocatedObject PassAlloc; - typedef GeometryAllocatedObject PatchAlloc; - typedef GeneralAllocatedObject PluginAlloc; - typedef GeneralAllocatedObject ProfilerAlloc; - typedef GeometryAllocatedObject ProgMeshAlloc; - typedef SceneCtlAllocatedObject RenderQueueAlloc; - typedef RenderSysAllocatedObject RenderSysAlloc; - typedef GeneralAllocatedObject RootAlloc; - typedef ResourceAllocatedObject ResourceAlloc; - typedef GeneralAllocatedObject SerializerAlloc; - typedef SceneCtlAllocatedObject SceneMgtAlloc; - typedef ScriptingAllocatedObject ScriptCompilerAlloc; - typedef ScriptingAllocatedObject ScriptTranslatorAlloc; - typedef SceneCtlAllocatedObject ShadowDataAlloc; - typedef GeneralAllocatedObject StreamAlloc; - typedef SceneObjAllocatedObject SubEntityAlloc; - typedef ResourceAllocatedObject SubMeshAlloc; - typedef ResourceAllocatedObject TechniqueAlloc; - typedef GeneralAllocatedObject TimerAlloc; - typedef ResourceAllocatedObject TextureUnitStateAlloc; - typedef GeneralAllocatedObject UtilityAlloc; - typedef GeometryAllocatedObject VertexDataAlloc; - typedef RenderSysAllocatedObject ViewportAlloc; - typedef SceneCtlAllocatedObject LodAlloc; + // Useful shortcuts + typedef CategorisedAllocPolicy GeneralAllocPolicy; + typedef CategorisedAllocPolicy GeometryAllocPolicy; + typedef CategorisedAllocPolicy AnimationAllocPolicy; + typedef CategorisedAllocPolicy SceneCtlAllocPolicy; + typedef CategorisedAllocPolicy SceneObjAllocPolicy; + typedef CategorisedAllocPolicy ResourceAllocPolicy; + typedef CategorisedAllocPolicy ScriptingAllocPolicy; + typedef CategorisedAllocPolicy RenderSysAllocPolicy; + + // Now define all the base classes for each allocation + typedef AllocatedObject GeneralAllocatedObject; + typedef AllocatedObject GeometryAllocatedObject; + typedef AllocatedObject AnimationAllocatedObject; + typedef AllocatedObject SceneCtlAllocatedObject; + typedef AllocatedObject SceneObjAllocatedObject; + typedef AllocatedObject ResourceAllocatedObject; + typedef AllocatedObject ScriptingAllocatedObject; + typedef AllocatedObject RenderSysAllocatedObject; + + + // Per-class allocators defined here + // NOTE: small, non-virtual classes should not subclass an allocator + // the virtual function table could double their size and make them less efficient + // use primitive or STL allocators / deallocators for those + typedef ScriptingAllocatedObject AbstractNodeAlloc; + typedef AnimationAllocatedObject AnimableAlloc; + typedef AnimationAllocatedObject AnimationAlloc; + typedef GeneralAllocatedObject ArchiveAlloc; + typedef GeometryAllocatedObject BatchedGeometryAlloc; + typedef RenderSysAllocatedObject BufferAlloc; + typedef GeneralAllocatedObject CodecAlloc; + typedef ResourceAllocatedObject CompositorInstAlloc; + typedef GeneralAllocatedObject ConfigAlloc; + typedef GeneralAllocatedObject ControllerAlloc; + typedef GeometryAllocatedObject DebugGeomAlloc; + typedef GeneralAllocatedObject DynLibAlloc; + typedef GeometryAllocatedObject EdgeDataAlloc; + typedef GeneralAllocatedObject FactoryAlloc; + typedef SceneObjAllocatedObject FXAlloc; + typedef GeneralAllocatedObject ImageAlloc; + typedef GeometryAllocatedObject IndexDataAlloc; + typedef GeneralAllocatedObject LogAlloc; + typedef SceneObjAllocatedObject MovableAlloc; + typedef SceneCtlAllocatedObject NodeAlloc; + typedef SceneObjAllocatedObject OverlayAlloc; + typedef RenderSysAllocatedObject GpuParamsAlloc; + typedef ResourceAllocatedObject PassAlloc; + typedef GeometryAllocatedObject PatchAlloc; + typedef GeneralAllocatedObject PluginAlloc; + typedef GeneralAllocatedObject ProfilerAlloc; + typedef GeometryAllocatedObject ProgMeshAlloc; + typedef SceneCtlAllocatedObject RenderQueueAlloc; + typedef RenderSysAllocatedObject RenderSysAlloc; + typedef GeneralAllocatedObject RootAlloc; + typedef ResourceAllocatedObject ResourceAlloc; + typedef GeneralAllocatedObject SerializerAlloc; + typedef SceneCtlAllocatedObject SceneMgtAlloc; + typedef ScriptingAllocatedObject ScriptCompilerAlloc; + typedef ScriptingAllocatedObject ScriptTranslatorAlloc; + typedef SceneCtlAllocatedObject ShadowDataAlloc; + typedef GeneralAllocatedObject StreamAlloc; + typedef SceneObjAllocatedObject SubEntityAlloc; + typedef ResourceAllocatedObject SubMeshAlloc; + typedef ResourceAllocatedObject TechniqueAlloc; + typedef GeneralAllocatedObject TimerAlloc; + typedef ResourceAllocatedObject TextureUnitStateAlloc; + typedef GeneralAllocatedObject UtilityAlloc; + typedef GeometryAllocatedObject VertexDataAlloc; + typedef RenderSysAllocatedObject ViewportAlloc; + typedef SceneCtlAllocatedObject LodAlloc; typedef GeneralAllocatedObject FileSystemLayerAlloc; - // Containers (by-value only) - // Will be of the form: - // typedef STLAllocator TAlloc; - // for use in vector::type - + // Containers (by-value only) + // Will be of the form: + // typedef STLAllocator TAlloc; + // for use in vector::type + } @@ -331,28 +331,28 @@ namespace Ogre // Util functions namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Memory - * @{ - */ - - /** Utility function for constructing an array of objects with placement new, - without using new[] (which allocates an undocumented amount of extra memory - and so isn't appropriate for custom allocators). - */ - template - T* constructN(T* basePtr, size_t count) - { - for (size_t i = 0; i < count; ++i) - { - new ((void*)(basePtr+i)) T(); - } - return basePtr; - } - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Memory + * @{ + */ + + /** Utility function for constructing an array of objects with placement new, + without using new[] (which allocates an undocumented amount of extra memory + and so isn't appropriate for custom allocators). + */ + template + T* constructN(T* basePtr, size_t count) + { + for (size_t i = 0; i < count; ++i) + { + new ((void*)(basePtr+i)) T(); + } + return basePtr; + } + /** @} */ + /** @} */ } // define macros @@ -367,126 +367,126 @@ namespace Ogre #if OGRE_DEBUG_MODE /// Allocate a block of raw memory, and indicate the category of usage -# define OGRE_MALLOC(bytes, category) ::Ogre::CategorisedAllocPolicy::allocateBytes(bytes, __FILE__, __LINE__, __FUNCTION__) +# define OGRE_MALLOC(bytes, category) ::Ogre::CategorisedAllocPolicy::allocateBytes(bytes, __FILE__, __LINE__, __FUNCTION__) /// Allocate a block of memory for a primitive type, and indicate the category of usage -# define OGRE_ALLOC_T(T, count, category) static_cast(::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)) +# define OGRE_ALLOC_T(T, count, category) static_cast(::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)) /// Free the memory allocated with OGRE_MALLOC or OGRE_ALLOC_T. Category is required to be restated to ensure the matching policy is used -# define OGRE_FREE(ptr, category) ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr) +# define OGRE_FREE(ptr, category) ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr) /// Allocate space for one primitive type, external type or non-virtual type with constructor parameters -# define OGRE_NEW_T(T, category) new (::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T), __FILE__, __LINE__, __FUNCTION__)) T +# define OGRE_NEW_T(T, category) new (::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T), __FILE__, __LINE__, __FUNCTION__)) T /// Allocate a block of memory for 'count' primitive types - do not use for classes that inherit from AllocatedObject -# define OGRE_NEW_ARRAY_T(T, count, category) ::Ogre::constructN(static_cast(::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)), count) +# define OGRE_NEW_ARRAY_T(T, count, category) ::Ogre::constructN(static_cast(::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)), count) /// Free the memory allocated with OGRE_NEW_T. Category is required to be restated to ensure the matching policy is used -# define OGRE_DELETE_T(ptr, T, category) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr);} +# define OGRE_DELETE_T(ptr, T, category) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr);} /// Free the memory allocated with OGRE_NEW_ARRAY_T. Category is required to be restated to ensure the matching policy is used, count and type to call destructor -# define OGRE_DELETE_ARRAY_T(ptr, T, count, category) if(ptr){for (size_t b = 0; b < count; ++b) { (ptr)[b].~T();} ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr);} +# define OGRE_DELETE_ARRAY_T(ptr, T, count, category) if(ptr){for (size_t b = 0; b < count; ++b) { (ptr)[b].~T();} ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr);} // aligned allocation /// Allocate a block of raw memory aligned to SIMD boundaries, and indicate the category of usage -# define OGRE_MALLOC_SIMD(bytes, category) ::Ogre::CategorisedAlignAllocPolicy::allocateBytes(bytes, __FILE__, __LINE__, __FUNCTION__) +# define OGRE_MALLOC_SIMD(bytes, category) ::Ogre::CategorisedAlignAllocPolicy::allocateBytes(bytes, __FILE__, __LINE__, __FUNCTION__) /// Allocate a block of raw memory aligned to user defined boundaries, and indicate the category of usage -# define OGRE_MALLOC_ALIGN(bytes, category, align) ::Ogre::CategorisedAlignAllocPolicy::allocateBytes(bytes, __FILE__, __LINE__, __FUNCTION__) +# define OGRE_MALLOC_ALIGN(bytes, category, align) ::Ogre::CategorisedAlignAllocPolicy::allocateBytes(bytes, __FILE__, __LINE__, __FUNCTION__) /// Allocate a block of memory for a primitive type aligned to SIMD boundaries, and indicate the category of usage -# define OGRE_ALLOC_T_SIMD(T, count, category) static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)) +# define OGRE_ALLOC_T_SIMD(T, count, category) static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)) /// Allocate a block of memory for a primitive type aligned to user defined boundaries, and indicate the category of usage -# define OGRE_ALLOC_T_ALIGN(T, count, category, align) static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)) +# define OGRE_ALLOC_T_ALIGN(T, count, category, align) static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)) /// Free the memory allocated with either OGRE_MALLOC_SIMD or OGRE_ALLOC_T_SIMD. Category is required to be restated to ensure the matching policy is used -# define OGRE_FREE_SIMD(ptr, category) ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr) +# define OGRE_FREE_SIMD(ptr, category) ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr) /// Free the memory allocated with either OGRE_MALLOC_ALIGN or OGRE_ALLOC_T_ALIGN. Category is required to be restated to ensure the matching policy is used -# define OGRE_FREE_ALIGN(ptr, category, align) ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr) +# define OGRE_FREE_ALIGN(ptr, category, align) ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr) /// Allocate space for one primitive type, external type or non-virtual type aligned to SIMD boundaries -# define OGRE_NEW_T_SIMD(T, category) new (::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T), __FILE__, __LINE__, __FUNCTION__)) T +# define OGRE_NEW_T_SIMD(T, category) new (::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T), __FILE__, __LINE__, __FUNCTION__)) T /// Allocate a block of memory for 'count' primitive types aligned to SIMD boundaries - do not use for classes that inherit from AllocatedObject -# define OGRE_NEW_ARRAY_T_SIMD(T, count, category) ::Ogre::constructN(static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)), count) +# define OGRE_NEW_ARRAY_T_SIMD(T, count, category) ::Ogre::constructN(static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)), count) /// Free the memory allocated with OGRE_NEW_T_SIMD. Category is required to be restated to ensure the matching policy is used -# define OGRE_DELETE_T_SIMD(ptr, T, category) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr);} +# define OGRE_DELETE_T_SIMD(ptr, T, category) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr);} /// Free the memory allocated with OGRE_NEW_ARRAY_T_SIMD. Category is required to be restated to ensure the matching policy is used, count and type to call destructor -# define OGRE_DELETE_ARRAY_T_SIMD(ptr, T, count, category) if(ptr){for (size_t b = 0; b < count; ++b) { (ptr)[b].~T();} ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr);} +# define OGRE_DELETE_ARRAY_T_SIMD(ptr, T, count, category) if(ptr){for (size_t b = 0; b < count; ++b) { (ptr)[b].~T();} ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr);} /// Allocate space for one primitive type, external type or non-virtual type aligned to user defined boundaries -# define OGRE_NEW_T_ALIGN(T, category, align) new (::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T), __FILE__, __LINE__, __FUNCTION__)) T +# define OGRE_NEW_T_ALIGN(T, category, align) new (::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T), __FILE__, __LINE__, __FUNCTION__)) T /// Allocate a block of memory for 'count' primitive types aligned to user defined boundaries - do not use for classes that inherit from AllocatedObject -# define OGRE_NEW_ARRAY_T_ALIGN(T, count, category, align) ::Ogre::constructN(static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)), count) +# define OGRE_NEW_ARRAY_T_ALIGN(T, count, category, align) ::Ogre::constructN(static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count), __FILE__, __LINE__, __FUNCTION__)), count) /// Free the memory allocated with OGRE_NEW_T_ALIGN. Category is required to be restated to ensure the matching policy is used -# define OGRE_DELETE_T_ALIGN(ptr, T, category, align) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr);} +# define OGRE_DELETE_T_ALIGN(ptr, T, category, align) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr);} /// Free the memory allocated with OGRE_NEW_ARRAY_T_ALIGN. Category is required to be restated to ensure the matching policy is used, count and type to call destructor -# define OGRE_DELETE_ARRAY_T_ALIGN(ptr, T, count, category, align) if(ptr){for (size_t _b = 0; _b < count; ++_b) { (ptr)[_b].~T();} ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr);} +# define OGRE_DELETE_ARRAY_T_ALIGN(ptr, T, count, category, align) if(ptr){for (size_t _b = 0; _b < count; ++_b) { (ptr)[_b].~T();} ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes(ptr);} // new / delete for classes deriving from AllocatedObject (alignment determined by per-class policy) // Also hooks up the file/line/function params // Can only be used with classes that derive from AllocatedObject since customised new/delete needed -# define OGRE_NEW new (__FILE__, __LINE__, __FUNCTION__) -# define OGRE_DELETE delete +# define OGRE_NEW new (__FILE__, __LINE__, __FUNCTION__) +# define OGRE_DELETE delete #else // !OGRE_DEBUG_MODE /// Allocate a block of raw memory, and indicate the category of usage -# define OGRE_MALLOC(bytes, category) ::Ogre::CategorisedAllocPolicy::allocateBytes(bytes) +# define OGRE_MALLOC(bytes, category) ::Ogre::CategorisedAllocPolicy::allocateBytes(bytes) /// Allocate a block of memory for a primitive type, and indicate the category of usage -# define OGRE_ALLOC_T(T, count, category) static_cast(::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T)*(count))) +# define OGRE_ALLOC_T(T, count, category) static_cast(::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T)*(count))) /// Free the memory allocated with OGRE_MALLOC or OGRE_ALLOC_T. Category is required to be restated to ensure the matching policy is used -# define OGRE_FREE(ptr, category) ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr) +# define OGRE_FREE(ptr, category) ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr) /// Allocate space for one primitive type, external type or non-virtual type with constructor parameters -# define OGRE_NEW_T(T, category) new (::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T))) T +# define OGRE_NEW_T(T, category) new (::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T))) T /// Allocate a block of memory for 'count' primitive types - do not use for classes that inherit from AllocatedObject -# define OGRE_NEW_ARRAY_T(T, count, category) ::Ogre::constructN(static_cast(::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T)*(count))), count) +# define OGRE_NEW_ARRAY_T(T, count, category) ::Ogre::constructN(static_cast(::Ogre::CategorisedAllocPolicy::allocateBytes(sizeof(T)*(count))), count) /// Free the memory allocated with OGRE_NEW_T. Category is required to be restated to ensure the matching policy is used -# define OGRE_DELETE_T(ptr, T, category) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr);} +# define OGRE_DELETE_T(ptr, T, category) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr);} /// Free the memory allocated with OGRE_NEW_ARRAY_T. Category is required to be restated to ensure the matching policy is used, count and type to call destructor -# define OGRE_DELETE_ARRAY_T(ptr, T, count, category) if(ptr){for (size_t b = 0; b < count; ++b) { (ptr)[b].~T();} ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr);} +# define OGRE_DELETE_ARRAY_T(ptr, T, count, category) if(ptr){for (size_t b = 0; b < count; ++b) { (ptr)[b].~T();} ::Ogre::CategorisedAllocPolicy::deallocateBytes((void*)ptr);} // aligned allocation /// Allocate a block of raw memory aligned to SIMD boundaries, and indicate the category of usage -# define OGRE_MALLOC_SIMD(bytes, category) ::Ogre::CategorisedAlignAllocPolicy::allocateBytes(bytes) +# define OGRE_MALLOC_SIMD(bytes, category) ::Ogre::CategorisedAlignAllocPolicy::allocateBytes(bytes) /// Allocate a block of raw memory aligned to user defined boundaries, and indicate the category of usage -# define OGRE_MALLOC_ALIGN(bytes, category, align) ::Ogre::CategorisedAlignAllocPolicy::allocateBytes(bytes) +# define OGRE_MALLOC_ALIGN(bytes, category, align) ::Ogre::CategorisedAlignAllocPolicy::allocateBytes(bytes) /// Allocate a block of memory for a primitive type aligned to SIMD boundaries, and indicate the category of usage -# define OGRE_ALLOC_T_SIMD(T, count, category) static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count))) +# define OGRE_ALLOC_T_SIMD(T, count, category) static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count))) /// Allocate a block of memory for a primitive type aligned to user defined boundaries, and indicate the category of usage -# define OGRE_ALLOC_T_ALIGN(T, count, category, align) static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count))) +# define OGRE_ALLOC_T_ALIGN(T, count, category, align) static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count))) /// Free the memory allocated with either OGRE_MALLOC_SIMD or OGRE_ALLOC_T_SIMD. Category is required to be restated to ensure the matching policy is used -# define OGRE_FREE_SIMD(ptr, category) ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr) +# define OGRE_FREE_SIMD(ptr, category) ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr) /// Free the memory allocated with either OGRE_MALLOC_ALIGN or OGRE_ALLOC_T_ALIGN. Category is required to be restated to ensure the matching policy is used -# define OGRE_FREE_ALIGN(ptr, category, align) ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr) +# define OGRE_FREE_ALIGN(ptr, category, align) ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr) /// Allocate space for one primitive type, external type or non-virtual type aligned to SIMD boundaries -# define OGRE_NEW_T_SIMD(T, category) new (::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T))) T +# define OGRE_NEW_T_SIMD(T, category) new (::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T))) T /// Allocate a block of memory for 'count' primitive types aligned to SIMD boundaries - do not use for classes that inherit from AllocatedObject -# define OGRE_NEW_ARRAY_T_SIMD(T, count, category) ::Ogre::constructN(static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count))), count) +# define OGRE_NEW_ARRAY_T_SIMD(T, count, category) ::Ogre::constructN(static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count))), count) /// Free the memory allocated with OGRE_NEW_T_SIMD. Category is required to be restated to ensure the matching policy is used -# define OGRE_DELETE_T_SIMD(ptr, T, category) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr);} +# define OGRE_DELETE_T_SIMD(ptr, T, category) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr);} /// Free the memory allocated with OGRE_NEW_ARRAY_T_SIMD. Category is required to be restated to ensure the matching policy is used, count and type to call destructor -# define OGRE_DELETE_ARRAY_T_SIMD(ptr, T, count, category) if(ptr){for (size_t b = 0; b < count; ++b) { (ptr)[b].~T();} ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr);} +# define OGRE_DELETE_ARRAY_T_SIMD(ptr, T, count, category) if(ptr){for (size_t b = 0; b < count; ++b) { (ptr)[b].~T();} ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr);} /// Allocate space for one primitive type, external type or non-virtual type aligned to user defined boundaries -# define OGRE_NEW_T_ALIGN(T, category, align) new (::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T))) T +# define OGRE_NEW_T_ALIGN(T, category, align) new (::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T))) T /// Allocate a block of memory for 'count' primitive types aligned to user defined boundaries - do not use for classes that inherit from AllocatedObject -# define OGRE_NEW_ARRAY_T_ALIGN(T, count, category, align) ::Ogre::constructN(static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count))), count) +# define OGRE_NEW_ARRAY_T_ALIGN(T, count, category, align) ::Ogre::constructN(static_cast(::Ogre::CategorisedAlignAllocPolicy::allocateBytes(sizeof(T)*(count))), count) /// Free the memory allocated with OGRE_NEW_T_ALIGN. Category is required to be restated to ensure the matching policy is used -# define OGRE_DELETE_T_ALIGN(ptr, T, category, align) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr);} +# define OGRE_DELETE_T_ALIGN(ptr, T, category, align) if(ptr){(ptr)->~T(); ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr);} /// Free the memory allocated with OGRE_NEW_ARRAY_T_ALIGN. Category is required to be restated to ensure the matching policy is used, count and type to call destructor -# define OGRE_DELETE_ARRAY_T_ALIGN(ptr, T, count, category, align) if(ptr){for (size_t _b = 0; _b < count; ++_b) { (ptr)[_b].~T();} ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr);} +# define OGRE_DELETE_ARRAY_T_ALIGN(ptr, T, count, category, align) if(ptr){for (size_t _b = 0; _b < count; ++_b) { (ptr)[_b].~T();} ::Ogre::CategorisedAlignAllocPolicy::deallocateBytes((void*)ptr);} // new / delete for classes deriving from AllocatedObject (alignment determined by per-class policy) -# define OGRE_NEW new -# define OGRE_DELETE delete +# define OGRE_NEW new +# define OGRE_DELETE delete #endif // OGRE_DEBUG_MODE namespace Ogre { - /** Function which invokes OGRE_DELETE on a given pointer. - @remarks - Useful to pass custom deletion policies to external libraries (e. g. boost). - */ - template - void deletePtr(T* ptr) - { - OGRE_DELETE ptr; - } + /** Function which invokes OGRE_DELETE on a given pointer. + @remarks + Useful to pass custom deletion policies to external libraries (e. g. boost). + */ + template + void deletePtr(T* ptr) + { + OGRE_DELETE ptr; + } } /** @} */ diff --git a/OgreMain/include/OgreMemoryNedAlloc.h b/OgreMain/include/OgreMemoryNedAlloc.h index 81fc4d6ca50..f9f35915605 100644 --- a/OgreMain/include/OgreMemoryNedAlloc.h +++ b/OgreMain/include/OgreMemoryNedAlloc.h @@ -35,104 +35,104 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Memory - * @{ - */ - /** Non-templated utility class just to hide nedmalloc. - */ - class _OgreExport NedAllocImpl - { - public: - static void* allocBytes(size_t count, - const char* file, int line, const char* func); - static void deallocBytes(void* ptr); - static void* allocBytesAligned(size_t align, size_t count, - const char* file, int line, const char* func); - static void deallocBytesAligned(size_t align, void* ptr); - - }; - - /** An allocation policy for use with AllocatedObject and - STLAllocator. This is the class that actually does the allocation - and deallocation of physical memory, and is what you will want to - provide a custom version of if you wish to change how memory is allocated. - @par - This allocation policy uses nedmalloc - (http://nedprod.com/programs/portable/nedmalloc/index.html). - */ - class _OgreExport NedAllocPolicy - { - public: - static inline void* allocateBytes(size_t count, - const char* file = 0, int line = 0, const char* func = 0) - { - return NedAllocImpl::allocBytes(count, file, line, func); - } - static inline void deallocateBytes(void* ptr) - { - NedAllocImpl::deallocBytes(ptr); - } - /// Get the maximum size of a single allocation - static inline size_t getMaxAllocationSize() - { - return std::numeric_limits::max(); - } - private: - // No instantiation - NedAllocPolicy() - { } - }; - - - /** An allocation policy for use with AllocatedObject and - STLAllocator, which aligns memory at a given boundary (which should be - a power of 2). This is the class that actually does the allocation - and deallocation of physical memory, and is what you will want to - provide a custom version of if you wish to change how memory is allocated. - @par - This allocation policy uses nedmalloc - (http://nedprod.com/programs/portable/nedmalloc/index.html). - @note - template parameter Alignment equal to zero means use default - platform dependent alignment. - */ - template - class NedAlignedAllocPolicy - { - public: - // compile-time check alignment is available. - typedef int IsValidAlignment - [Alignment <= 128 && ((Alignment & (Alignment-1)) == 0) ? +1 : -1]; - - static inline void* allocateBytes(size_t count, - const char* file = 0, int line = 0, const char* func = 0) - { - return NedAllocImpl::allocBytesAligned(Alignment, count, file, line, func); - } - - static inline void deallocateBytes(void* ptr) - { - NedAllocImpl::deallocBytesAligned(Alignment, ptr); - } - - /// Get the maximum size of a single allocation - static inline size_t getMaxAllocationSize() - { - return std::numeric_limits::max(); - } - private: - // no instantiation allowed - NedAlignedAllocPolicy() - { } - }; - - - - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Memory + * @{ + */ + /** Non-templated utility class just to hide nedmalloc. + */ + class _OgreExport NedAllocImpl + { + public: + static void* allocBytes(size_t count, + const char* file, int line, const char* func); + static void deallocBytes(void* ptr); + static void* allocBytesAligned(size_t align, size_t count, + const char* file, int line, const char* func); + static void deallocBytesAligned(size_t align, void* ptr); + + }; + + /** An allocation policy for use with AllocatedObject and + STLAllocator. This is the class that actually does the allocation + and deallocation of physical memory, and is what you will want to + provide a custom version of if you wish to change how memory is allocated. + @par + This allocation policy uses nedmalloc + (http://nedprod.com/programs/portable/nedmalloc/index.html). + */ + class _OgreExport NedAllocPolicy + { + public: + static inline void* allocateBytes(size_t count, + const char* file = 0, int line = 0, const char* func = 0) + { + return NedAllocImpl::allocBytes(count, file, line, func); + } + static inline void deallocateBytes(void* ptr) + { + NedAllocImpl::deallocBytes(ptr); + } + /// Get the maximum size of a single allocation + static inline size_t getMaxAllocationSize() + { + return std::numeric_limits::max(); + } + private: + // No instantiation + NedAllocPolicy() + { } + }; + + + /** An allocation policy for use with AllocatedObject and + STLAllocator, which aligns memory at a given boundary (which should be + a power of 2). This is the class that actually does the allocation + and deallocation of physical memory, and is what you will want to + provide a custom version of if you wish to change how memory is allocated. + @par + This allocation policy uses nedmalloc + (http://nedprod.com/programs/portable/nedmalloc/index.html). + @note + template parameter Alignment equal to zero means use default + platform dependent alignment. + */ + template + class NedAlignedAllocPolicy + { + public: + // compile-time check alignment is available. + typedef int IsValidAlignment + [Alignment <= 128 && ((Alignment & (Alignment-1)) == 0) ? +1 : -1]; + + static inline void* allocateBytes(size_t count, + const char* file = 0, int line = 0, const char* func = 0) + { + return NedAllocImpl::allocBytesAligned(Alignment, count, file, line, func); + } + + static inline void deallocateBytes(void* ptr) + { + NedAllocImpl::deallocBytesAligned(Alignment, ptr); + } + + /// Get the maximum size of a single allocation + static inline size_t getMaxAllocationSize() + { + return std::numeric_limits::max(); + } + private: + // no instantiation allowed + NedAlignedAllocPolicy() + { } + }; + + + + /** @} */ + /** @} */ }// namespace Ogre diff --git a/OgreMain/include/OgreMemoryNedPooling.h b/OgreMain/include/OgreMemoryNedPooling.h index 124b1bc29db..2147827f5ab 100644 --- a/OgreMain/include/OgreMemoryNedPooling.h +++ b/OgreMain/include/OgreMemoryNedPooling.h @@ -36,106 +36,106 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Memory - * @{ - */ - /** Non-templated utility class just to hide nedmalloc. - */ - class _OgreExport NedPoolingImpl - { - public: - static void* allocBytes(size_t count, - const char* file, int line, const char* func); - static void deallocBytes(void* ptr); - static void* allocBytesAligned(size_t align, size_t count, - const char* file, int line, const char* func); - static void deallocBytesAligned(size_t align, void* ptr); - - }; - - /** An allocation policy for use with AllocatedObject and - STLAllocator. This is the class that actually does the allocation - and deallocation of physical memory, and is what you will want to - provide a custom version of if you wish to change how memory is allocated. - @par - This allocation policy uses nedmalloc - (http://nedprod.com/programs/portable/nedmalloc/index.html). - */ - class _OgreExport NedPoolingPolicy - { - public: - static inline void* allocateBytes(size_t count, - const char* file = 0, int line = 0, const char* func = 0) - { - return NedPoolingImpl::allocBytes(count, file, line, func); - } - static inline void deallocateBytes(void* ptr) - { - NedPoolingImpl::deallocBytes(ptr); - } - /// Get the maximum size of a single allocation - static inline size_t getMaxAllocationSize() - { - return std::numeric_limits::max(); - } - - private: - // No instantiation - NedPoolingPolicy() - { } - }; - - - /** An allocation policy for use with AllocatedObject and - STLAllocator, which aligns memory at a given boundary (which should be - a power of 2). This is the class that actually does the allocation - and deallocation of physical memory, and is what you will want to - provide a custom version of if you wish to change how memory is allocated. - @par - This allocation policy uses nedmalloc - (http://nedprod.com/programs/portable/nedmalloc/index.html). - @note - template parameter Alignment equal to zero means use default - platform dependent alignment. - */ - template - class NedPoolingAlignedPolicy - { - public: - // compile-time check alignment is available. - typedef int IsValidAlignment - [Alignment <= 128 && ((Alignment & (Alignment-1)) == 0) ? +1 : -1]; - - static inline void* allocateBytes(size_t count, - const char* file = 0, int line = 0, const char* func = 0) - { - return NedPoolingImpl::allocBytesAligned(Alignment, count, file, line, func); - } - - static inline void deallocateBytes(void* ptr) - { - NedPoolingImpl::deallocBytesAligned(Alignment, ptr); - } - - /// Get the maximum size of a single allocation - static inline size_t getMaxAllocationSize() - { - return std::numeric_limits::max(); - } - private: - // no instantiation allowed - NedPoolingAlignedPolicy() - { } - }; - - - - - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Memory + * @{ + */ + /** Non-templated utility class just to hide nedmalloc. + */ + class _OgreExport NedPoolingImpl + { + public: + static void* allocBytes(size_t count, + const char* file, int line, const char* func); + static void deallocBytes(void* ptr); + static void* allocBytesAligned(size_t align, size_t count, + const char* file, int line, const char* func); + static void deallocBytesAligned(size_t align, void* ptr); + + }; + + /** An allocation policy for use with AllocatedObject and + STLAllocator. This is the class that actually does the allocation + and deallocation of physical memory, and is what you will want to + provide a custom version of if you wish to change how memory is allocated. + @par + This allocation policy uses nedmalloc + (http://nedprod.com/programs/portable/nedmalloc/index.html). + */ + class _OgreExport NedPoolingPolicy + { + public: + static inline void* allocateBytes(size_t count, + const char* file = 0, int line = 0, const char* func = 0) + { + return NedPoolingImpl::allocBytes(count, file, line, func); + } + static inline void deallocateBytes(void* ptr) + { + NedPoolingImpl::deallocBytes(ptr); + } + /// Get the maximum size of a single allocation + static inline size_t getMaxAllocationSize() + { + return std::numeric_limits::max(); + } + + private: + // No instantiation + NedPoolingPolicy() + { } + }; + + + /** An allocation policy for use with AllocatedObject and + STLAllocator, which aligns memory at a given boundary (which should be + a power of 2). This is the class that actually does the allocation + and deallocation of physical memory, and is what you will want to + provide a custom version of if you wish to change how memory is allocated. + @par + This allocation policy uses nedmalloc + (http://nedprod.com/programs/portable/nedmalloc/index.html). + @note + template parameter Alignment equal to zero means use default + platform dependent alignment. + */ + template + class NedPoolingAlignedPolicy + { + public: + // compile-time check alignment is available. + typedef int IsValidAlignment + [Alignment <= 128 && ((Alignment & (Alignment-1)) == 0) ? +1 : -1]; + + static inline void* allocateBytes(size_t count, + const char* file = 0, int line = 0, const char* func = 0) + { + return NedPoolingImpl::allocBytesAligned(Alignment, count, file, line, func); + } + + static inline void deallocateBytes(void* ptr) + { + NedPoolingImpl::deallocBytesAligned(Alignment, ptr); + } + + /// Get the maximum size of a single allocation + static inline size_t getMaxAllocationSize() + { + return std::numeric_limits::max(); + } + private: + // no instantiation allowed + NedPoolingAlignedPolicy() + { } + }; + + + + + /** @} */ + /** @} */ }// namespace Ogre diff --git a/OgreMain/include/OgreMemorySTLAllocator.h b/OgreMain/include/OgreMemorySTLAllocator.h index 81fc99275ad..cf12b49003f 100644 --- a/OgreMain/include/OgreMemorySTLAllocator.h +++ b/OgreMain/include/OgreMemorySTLAllocator.h @@ -36,188 +36,188 @@ namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Memory - * @{ - */ - /** - Wrapper class for operating as an STL container allocator. - This class acts as the host for a configured allocation policy. - - It takes the following template parameters:- -
        -
      • T : the type we will be allocating (see rebind later)
      • -
      • AllocPolicy : a memory allocator policy
      • -
      - - See StdAllocPolicy for an example of implementing a Policy. The reason for - implementing the allocation in a policy is that it makes implementing - a custom allocator easier - you just have to provide an alternative - policy with just allocate/deallocate implementations; this class does all the - housekeeping associated with keeping the STL happy. - */ - - // Base STL allocator class. - template - struct STLAllocatorBase - { // base class for generic allocators - typedef T value_type; - }; - - // Base STL allocator class. (const T version). - template - struct STLAllocatorBase - { // base class for generic allocators for const T - typedef T value_type; - }; - - template - < - typename T, - typename AllocPolicy - > - class STLAllocator : public STLAllocatorBase - { - public : - /// define our types, as per ISO C++ - typedef STLAllocatorBase Base; - typedef typename Base::value_type value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - - /// the standard rebind mechanism - template - struct rebind - { - typedef STLAllocator other; - }; - - /// ctor - inline explicit STLAllocator() - { } - - /// dtor - virtual ~STLAllocator() - { } - - /// copy ctor - done component wise - inline STLAllocator( STLAllocator const& ) - { } - - /// cast - template - inline STLAllocator( STLAllocator const& ) - { } - - /// cast - template - inline STLAllocator( STLAllocator const& ) - { } - - /// memory allocation (elements, used by STL) - inline pointer allocate( size_type count, - typename std::allocator::const_pointer ptr = 0 ) - { + /** \addtogroup Core + * @{ + */ + /** \addtogroup Memory + * @{ + */ + /** + Wrapper class for operating as an STL container allocator. + This class acts as the host for a configured allocation policy. + + It takes the following template parameters:- +
        +
      • T : the type we will be allocating (see rebind later)
      • +
      • AllocPolicy : a memory allocator policy
      • +
      + + See StdAllocPolicy for an example of implementing a Policy. The reason for + implementing the allocation in a policy is that it makes implementing + a custom allocator easier - you just have to provide an alternative + policy with just allocate/deallocate implementations; this class does all the + housekeeping associated with keeping the STL happy. + */ + + // Base STL allocator class. + template + struct STLAllocatorBase + { // base class for generic allocators + typedef T value_type; + }; + + // Base STL allocator class. (const T version). + template + struct STLAllocatorBase + { // base class for generic allocators for const T + typedef T value_type; + }; + + template + < + typename T, + typename AllocPolicy + > + class STLAllocator : public STLAllocatorBase + { + public : + /// define our types, as per ISO C++ + typedef STLAllocatorBase Base; + typedef typename Base::value_type value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + + /// the standard rebind mechanism + template + struct rebind + { + typedef STLAllocator other; + }; + + /// ctor + inline explicit STLAllocator() + { } + + /// dtor + virtual ~STLAllocator() + { } + + /// copy ctor - done component wise + inline STLAllocator( STLAllocator const& ) + { } + + /// cast + template + inline STLAllocator( STLAllocator const& ) + { } + + /// cast + template + inline STLAllocator( STLAllocator const& ) + { } + + /// memory allocation (elements, used by STL) + inline pointer allocate( size_type count, + typename std::allocator::const_pointer ptr = 0 ) + { (void)ptr; - // convert request to bytes - register size_type sz = count*sizeof( T ); - pointer p = static_cast(AllocPolicy::allocateBytes(sz)); - return p; - } - - /// memory deallocation (elements, used by STL) - inline void deallocate( pointer ptr, size_type ) - { - // convert request to bytes, but we can't use this? - // register size_type sz = count*sizeof( T ); - AllocPolicy::deallocateBytes(ptr); - } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - size_type max_size() const throw() - { - // maximum size this can handle, delegate - return AllocPolicy::getMaxAllocationSize(); - } + // convert request to bytes + register size_type sz = count*sizeof( T ); + pointer p = static_cast(AllocPolicy::allocateBytes(sz)); + return p; + } + + /// memory deallocation (elements, used by STL) + inline void deallocate( pointer ptr, size_type ) + { + // convert request to bytes, but we can't use this? + // register size_type sz = count*sizeof( T ); + AllocPolicy::deallocateBytes(ptr); + } + + pointer address(reference x) const + { + return &x; + } + + const_pointer address(const_reference x) const + { + return &x; + } + + size_type max_size() const throw() + { + // maximum size this can handle, delegate + return AllocPolicy::getMaxAllocationSize(); + } #if __cplusplus < 201103L - void construct(pointer p) - { - // call placement new - new(static_cast(p)) T(); - } + void construct(pointer p) + { + // call placement new + new(static_cast(p)) T(); + } #endif - void construct(pointer p, const T& val) - { - // call placement new - new(static_cast(p)) T(val); - } - - void destroy(pointer p) - { - // do we have to protect against non-classes here? - // some articles suggest yes, some no - p->~T(); - } - }; - - /// determine equality, can memory from another allocator - /// be released by this allocator, (ISO C++) - template - inline bool operator==(STLAllocator const&, - STLAllocator const&) - { - // same alloc policy (P), memory can be freed - return true; - } - - /// determine equality, can memory from another allocator - /// be released by this allocator, (ISO C++) - template - inline bool operator==(STLAllocator const&, - OtherAllocator const&) - { - return false; - } - /// determine equality, can memory from another allocator - /// be released by this allocator, (ISO C++) - template - inline bool operator!=(STLAllocator const&, - STLAllocator const&) - { - // same alloc policy (P), memory can be freed - return false; - } - - /// determine equality, can memory from another allocator - /// be released by this allocator, (ISO C++) - template - inline bool operator!=(STLAllocator const&, - OtherAllocator const&) - { - return true; - } - - - /** @} */ - /** @} */ + void construct(pointer p, const T& val) + { + // call placement new + new(static_cast(p)) T(val); + } + + void destroy(pointer p) + { + // do we have to protect against non-classes here? + // some articles suggest yes, some no + p->~T(); + } + }; + + /// determine equality, can memory from another allocator + /// be released by this allocator, (ISO C++) + template + inline bool operator==(STLAllocator const&, + STLAllocator const&) + { + // same alloc policy (P), memory can be freed + return true; + } + + /// determine equality, can memory from another allocator + /// be released by this allocator, (ISO C++) + template + inline bool operator==(STLAllocator const&, + OtherAllocator const&) + { + return false; + } + /// determine equality, can memory from another allocator + /// be released by this allocator, (ISO C++) + template + inline bool operator!=(STLAllocator const&, + STLAllocator const&) + { + // same alloc policy (P), memory can be freed + return false; + } + + /// determine equality, can memory from another allocator + /// be released by this allocator, (ISO C++) + template + inline bool operator!=(STLAllocator const&, + OtherAllocator const&) + { + return true; + } + + + /** @} */ + /** @} */ }// namespace Ogre diff --git a/OgreMain/include/OgreMemoryStdAlloc.h b/OgreMain/include/OgreMemoryStdAlloc.h index ef8cb7256b4..8d28e6e0deb 100644 --- a/OgreMain/include/OgreMemoryStdAlloc.h +++ b/OgreMain/include/OgreMemoryStdAlloc.h @@ -40,116 +40,116 @@ namespace Ogre { #if OGRE_MEMORY_ALLOCATOR == OGRE_MEMORY_ALLOCATOR_STD - /** \addtogroup Core - * @{ - */ - /** \addtogroup Memory - * @{ - */ - /** A "standard" allocation policy for use with AllocatedObject and - STLAllocator. This is the class that actually does the allocation - and deallocation of physical memory, and is what you will want to - provide a custom version of if you wish to change how memory is allocated. - @par - This class just delegates to the global malloc/free. - */ - class _OgreExport StdAllocPolicy - { - public: - static inline void* allocateBytes(size_t count, + /** \addtogroup Core + * @{ + */ + /** \addtogroup Memory + * @{ + */ + /** A "standard" allocation policy for use with AllocatedObject and + STLAllocator. This is the class that actually does the allocation + and deallocation of physical memory, and is what you will want to + provide a custom version of if you wish to change how memory is allocated. + @par + This class just delegates to the global malloc/free. + */ + class _OgreExport StdAllocPolicy + { + public: + static inline void* allocateBytes(size_t count, #if OGRE_MEMORY_TRACKER - const char* file = 0, int line = 0, const char* func = 0 + const char* file = 0, int line = 0, const char* func = 0 #else - const char* = 0, int = 0, const char* = 0 + const char* = 0, int = 0, const char* = 0 #endif ) - { - void* ptr = malloc(count); + { + void* ptr = malloc(count); #if OGRE_MEMORY_TRACKER - // this alloc policy doesn't do pools - MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); + // this alloc policy doesn't do pools + MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); #endif - return ptr; - } + return ptr; + } - static inline void deallocateBytes(void* ptr) - { + static inline void deallocateBytes(void* ptr) + { #if OGRE_MEMORY_TRACKER - MemoryTracker::get()._recordDealloc(ptr); + MemoryTracker::get()._recordDealloc(ptr); #endif - free(ptr); - } - - /// Get the maximum size of a single allocation - static inline size_t getMaxAllocationSize() - { - return std::numeric_limits::max(); - } - private: - // no instantiation - StdAllocPolicy() - { } - }; - - /** A "standard" allocation policy for use with AllocatedObject and - STLAllocator, which aligns memory at a given boundary (which should be - a power of 2). This is the class that actually does the allocation - and deallocation of physical memory, and is what you will want to - provide a custom version of if you wish to change how memory is allocated. - @par - This class just delegates to the global malloc/free, via AlignedMemory. - @note - template parameter Alignment equal to zero means use default - platform dependent alignment. - - */ - template - class StdAlignedAllocPolicy - { - public: - // compile-time check alignment is available. - typedef int IsValidAlignment - [Alignment <= 128 && ((Alignment & (Alignment-1)) == 0) ? +1 : -1]; - - static inline void* allocateBytes(size_t count, + free(ptr); + } + + /// Get the maximum size of a single allocation + static inline size_t getMaxAllocationSize() + { + return std::numeric_limits::max(); + } + private: + // no instantiation + StdAllocPolicy() + { } + }; + + /** A "standard" allocation policy for use with AllocatedObject and + STLAllocator, which aligns memory at a given boundary (which should be + a power of 2). This is the class that actually does the allocation + and deallocation of physical memory, and is what you will want to + provide a custom version of if you wish to change how memory is allocated. + @par + This class just delegates to the global malloc/free, via AlignedMemory. + @note + template parameter Alignment equal to zero means use default + platform dependent alignment. + + */ + template + class StdAlignedAllocPolicy + { + public: + // compile-time check alignment is available. + typedef int IsValidAlignment + [Alignment <= 128 && ((Alignment & (Alignment-1)) == 0) ? +1 : -1]; + + static inline void* allocateBytes(size_t count, #if OGRE_MEMORY_TRACKER - const char* file = 0, int line = 0, const char* func = 0 + const char* file = 0, int line = 0, const char* func = 0 #else - const char* = 0, int = 0, const char* = 0 + const char* = 0, int = 0, const char* = 0 #endif ) - { - void* ptr = Alignment ? AlignedMemory::allocate(count, Alignment) - : AlignedMemory::allocate(count); + { + void* ptr = Alignment ? AlignedMemory::allocate(count, Alignment) + : AlignedMemory::allocate(count); #if OGRE_MEMORY_TRACKER - // this alloc policy doesn't do pools - MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); + // this alloc policy doesn't do pools + MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); #endif - return ptr; - } + return ptr; + } - static inline void deallocateBytes(void* ptr) - { + static inline void deallocateBytes(void* ptr) + { #if OGRE_MEMORY_TRACKER - MemoryTracker::get()._recordDealloc(ptr); + MemoryTracker::get()._recordDealloc(ptr); #endif - AlignedMemory::deallocate(ptr); - } - - /// Get the maximum size of a single allocation - static inline size_t getMaxAllocationSize() - { - return std::numeric_limits::max(); - } - private: - // No instantiation - StdAlignedAllocPolicy() - { } - }; + AlignedMemory::deallocate(ptr); + } + + /// Get the maximum size of a single allocation + static inline size_t getMaxAllocationSize() + { + return std::numeric_limits::max(); + } + private: + // No instantiation + StdAlignedAllocPolicy() + { } + }; #endif - /** @} */ - /** @} */ + /** @} */ + /** @} */ }// namespace Ogre diff --git a/OgreMain/include/OgreMemoryTracker.h b/OgreMain/include/OgreMemoryTracker.h index f81623898d9..514114b6e3b 100644 --- a/OgreMain/include/OgreMemoryTracker.h +++ b/OgreMain/include/OgreMemoryTracker.h @@ -35,7 +35,7 @@ THE SOFTWARE. // This file must be included within another file which already has the prerequisites in it //#include "OgrePrerequisites.h" #ifndef OGRE_COMPILER -# pragma message "MemoryTracker included somewhere OgrePrerequisites.h wasn't!" +# pragma message "MemoryTracker included somewhere OgrePrerequisites.h wasn't!" #endif // If we're using the GCC 3.1 C++ Std lib @@ -48,13 +48,13 @@ THE SOFTWARE. # include namespace __gnu_cxx { - template <> struct hash< void* > - { - size_t operator()( void* const & ptr ) const - { - return (size_t)ptr; - } - }; + template <> struct hash< void* > + { + size_t operator()( void* const & ptr ) const + { + return (size_t)ptr; + } + }; } # endif @@ -66,136 +66,136 @@ namespace __gnu_cxx namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Memory - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Memory + * @{ + */ #if OGRE_MEMORY_TRACKER - /** This class tracks the allocations and deallocations made, and - is able to report memory statistics and leaks. - @note - This class is only available in debug builds. - */ - class _OgreExport MemoryTracker - { - protected: + /** This class tracks the allocations and deallocations made, and + is able to report memory statistics and leaks. + @note + This class is only available in debug builds. + */ + class _OgreExport MemoryTracker + { + protected: OGRE_AUTO_MUTEX; - // Allocation record - struct Alloc - { - size_t bytes; - unsigned int pool; - std::string filename; - size_t line; - std::string function; - - Alloc() :bytes(0), line(0) {} - Alloc(size_t sz, unsigned int p, const char* file, size_t ln, const char* func) - :bytes(sz), pool(p), line(ln) - { - if (file) - filename = file; - if (func) - function = func; - } - }; - - std::string mLeakFileName; - bool mDumpToStdOut; - typedef HashMap AllocationMap; - AllocationMap mAllocations; - - size_t mTotalAllocations; - typedef std::vector AllocationsByPool; - AllocationsByPool mAllocationsByPool; - bool mRecordEnable; - - void reportLeaks(); - - // protected ctor - MemoryTracker() - : mLeakFileName("OgreLeaks.log"), mDumpToStdOut(true), - mTotalAllocations(0), mRecordEnable(true) - { - } - public: - - /** Set the name of the report file that will be produced on exit. */ - void setReportFileName(const std::string& name) - { - mLeakFileName = name; - } - /// Return the name of the file which will contain the report at exit - const std::string& getReportFileName() const - { - return mLeakFileName; - } - /// Sets whether the memory report should be sent to stdout - void setReportToStdOut(bool rep) - { - mDumpToStdOut = rep; - } - /// Gets whether the memory report should be sent to stdout - bool getReportToStdOut() const - { - return mDumpToStdOut; - } - - - - /// Get the total amount of memory allocated currently. - size_t getTotalMemoryAllocated() const; - /// Get the amount of memory allocated in a given pool - size_t getMemoryAllocatedForPool(unsigned int pool) const; - - - /** Record an allocation that has been made. Only to be called by - the memory management subsystem. - @param ptr The pointer to the memory - @param sz The size of the memory in bytes - @param pool The memory pool this allocation is occurring from - @param file The file in which the allocation is being made - @param ln The line on which the allocation is being made - @param func The function in which the allocation is being made - */ - void _recordAlloc(void* ptr, size_t sz, unsigned int pool = 0, - const char* file = 0, size_t ln = 0, const char* func = 0); - /** Record the deallocation of memory. */ - void _recordDealloc(void* ptr); - - /// Sets whether the record alloc/dealloc enabled. - void setRecordEnable(bool recordEnable) - { - mRecordEnable = recordEnable; - } - - /// Gets whether the record alloc/dealloc enabled. - bool getRecordEnable() const - { - return mRecordEnable; - } - - ~MemoryTracker() - { - reportLeaks(); - } - - /// Static utility method to get the memory tracker instance - static MemoryTracker& get(); - - - }; + // Allocation record + struct Alloc + { + size_t bytes; + unsigned int pool; + std::string filename; + size_t line; + std::string function; + + Alloc() :bytes(0), line(0) {} + Alloc(size_t sz, unsigned int p, const char* file, size_t ln, const char* func) + :bytes(sz), pool(p), line(ln) + { + if (file) + filename = file; + if (func) + function = func; + } + }; + + std::string mLeakFileName; + bool mDumpToStdOut; + typedef HashMap AllocationMap; + AllocationMap mAllocations; + + size_t mTotalAllocations; + typedef std::vector AllocationsByPool; + AllocationsByPool mAllocationsByPool; + bool mRecordEnable; + + void reportLeaks(); + + // protected ctor + MemoryTracker() + : mLeakFileName("OgreLeaks.log"), mDumpToStdOut(true), + mTotalAllocations(0), mRecordEnable(true) + { + } + public: + + /** Set the name of the report file that will be produced on exit. */ + void setReportFileName(const std::string& name) + { + mLeakFileName = name; + } + /// Return the name of the file which will contain the report at exit + const std::string& getReportFileName() const + { + return mLeakFileName; + } + /// Sets whether the memory report should be sent to stdout + void setReportToStdOut(bool rep) + { + mDumpToStdOut = rep; + } + /// Gets whether the memory report should be sent to stdout + bool getReportToStdOut() const + { + return mDumpToStdOut; + } + + + + /// Get the total amount of memory allocated currently. + size_t getTotalMemoryAllocated() const; + /// Get the amount of memory allocated in a given pool + size_t getMemoryAllocatedForPool(unsigned int pool) const; + + + /** Record an allocation that has been made. Only to be called by + the memory management subsystem. + @param ptr The pointer to the memory + @param sz The size of the memory in bytes + @param pool The memory pool this allocation is occurring from + @param file The file in which the allocation is being made + @param ln The line on which the allocation is being made + @param func The function in which the allocation is being made + */ + void _recordAlloc(void* ptr, size_t sz, unsigned int pool = 0, + const char* file = 0, size_t ln = 0, const char* func = 0); + /** Record the deallocation of memory. */ + void _recordDealloc(void* ptr); + + /// Sets whether the record alloc/dealloc enabled. + void setRecordEnable(bool recordEnable) + { + mRecordEnable = recordEnable; + } + + /// Gets whether the record alloc/dealloc enabled. + bool getRecordEnable() const + { + return mRecordEnable; + } + + ~MemoryTracker() + { + reportLeaks(); + } + + /// Static utility method to get the memory tracker instance + static MemoryTracker& get(); + + + }; #endif - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreMesh.h b/OgreMain/include/OgreMesh.h index 11ad1e6eaaf..48b521b7aaa 100644 --- a/OgreMain/include/OgreMesh.h +++ b/OgreMain/include/OgreMesh.h @@ -89,7 +89,7 @@ namespace Ogre { friend class MeshSerializerImpl; friend class MeshSerializerImpl_v1_8; friend class MeshSerializerImpl_v1_4; - friend class MeshSerializerImpl_v1_3; + friend class MeshSerializerImpl_v1_3; friend class MeshSerializerImpl_v1_2; friend class MeshSerializerImpl_v1_1; @@ -156,14 +156,14 @@ namespace Ogre { VertexData* targetVertexData); #if !OGRE_NO_MESHLOD const LodStrategy *mLodStrategy; - bool mHasManualLodLevel; + bool mHasManualLodLevel; ushort mNumLods; MeshLodUsageList mMeshLodUsageList; #else - const LodStrategy *mLodStrategy; - const bool mHasManualLodLevel; - const ushort mNumLods; - MeshLodUsageList mMeshLodUsageList; + const LodStrategy *mLodStrategy; + const bool mHasManualLodLevel; + const ushort mNumLods; + MeshLodUsageList mMeshLodUsageList; #endif HardwareBuffer::Usage mVertexBufferUsage; HardwareBuffer::Usage mIndexBufferUsage; @@ -208,8 +208,8 @@ namespace Ogre { /// @copydoc Resource::calculateSize size_t calculateSize(void) const; - void mergeAdjacentTexcoords( unsigned short finalTexCoordSet, - unsigned short texCoordSetToDestroy, VertexData *vertexData ); + void mergeAdjacentTexcoords( unsigned short finalTexCoordSet, + unsigned short texCoordSetToDestroy, VertexData *vertexData ); public: @@ -371,22 +371,22 @@ namespace Ogre { */ void _computeBoneBoundingRadius(); - /** Automatically update the bounding radius and bounding box for this Mesh. - @remarks - Calling this method is required when building manual meshes. However it is recommended to - use _setBounds and _setBoundingSphereRadius instead, because the vertex buffer may not have - a shadow copy in the memory. Reading back the buffer from video memory is very slow! - @param pad If true, a certain padding will be added to the bounding box to separate it from the mesh - */ - void _updateBoundsFromVertexBuffers(bool pad = false); - - /** Calculates - @remarks - Calling this method is required when building manual meshes. However it is recommended to - use _setBounds and _setBoundingSphereRadius instead, because the vertex buffer may not have - a shadow copy in the memory. Reading back the buffer from video memory is very slow! - */ - void _calcBoundsFromVertexBuffer(VertexData* vertexData, AxisAlignedBox& outAABB, Real& outRadius, bool updateOnly = false); + /** Automatically update the bounding radius and bounding box for this Mesh. + @remarks + Calling this method is required when building manual meshes. However it is recommended to + use _setBounds and _setBoundingSphereRadius instead, because the vertex buffer may not have + a shadow copy in the memory. Reading back the buffer from video memory is very slow! + @param pad If true, a certain padding will be added to the bounding box to separate it from the mesh + */ + void _updateBoundsFromVertexBuffers(bool pad = false); + + /** Calculates + @remarks + Calling this method is required when building manual meshes. However it is recommended to + use _setBounds and _setBoundingSphereRadius instead, because the vertex buffer may not have + a shadow copy in the memory. Reading back the buffer from video memory is very slow! + */ + void _calcBoundsFromVertexBuffer(VertexData* vertexData, AxisAlignedBox& outAABB, Real& outRadius, bool updateOnly = false); /** Sets the name of the skeleton this Mesh uses for animation. @remarks Meshes can optionally be assigned a skeleton which can be used to animate @@ -480,12 +480,12 @@ namespace Ogre { */ ushort getLodIndex(Real value) const; - /** Returns true if this mesh has a manual LOD level. - @remarks - A mesh can either use automatically generated LOD, or it can use alternative - meshes as provided by an artist. - */ - bool hasManualLodLevel(void) const { return mHasManualLodLevel; } + /** Returns true if this mesh has a manual LOD level. + @remarks + A mesh can either use automatically generated LOD, or it can use alternative + meshes as provided by an artist. + */ + bool hasManualLodLevel(void) const { return mHasManualLodLevel; } #if !OGRE_NO_MESHLOD /** Changes the alternate mesh to use as a manual LOD at the given index. @remarks @@ -606,22 +606,22 @@ namespace Ogre { */ void _updateCompiledBoneAssignments(void); - /** This method collapses two texcoords into one for all submeshes where this is possible. + /** This method collapses two texcoords into one for all submeshes where this is possible. @remarks - Often a submesh can have two tex. coords. (i.e. TEXCOORD0 & TEXCOORD1), being both - composed of two floats. There are many practical reasons why it would be more convenient - to merge both of them into one TEXCOORD0 of 4 floats. This function does exactly that - The finalTexCoordSet must have enough space for the merge, or else the submesh will be - skipped. (i.e. you can't merge a tex. coord with 3 floats with one having 2 floats) + Often a submesh can have two tex. coords. (i.e. TEXCOORD0 & TEXCOORD1), being both + composed of two floats. There are many practical reasons why it would be more convenient + to merge both of them into one TEXCOORD0 of 4 floats. This function does exactly that + The finalTexCoordSet must have enough space for the merge, or else the submesh will be + skipped. (i.e. you can't merge a tex. coord with 3 floats with one having 2 floats) - finalTexCoordSet & texCoordSetToDestroy must be in the same buffer source, and must - be adjacent. - @param finalTexCoordSet The tex. coord index to merge to. Should have enough space to - actually work. + finalTexCoordSet & texCoordSetToDestroy must be in the same buffer source, and must + be adjacent. + @param finalTexCoordSet The tex. coord index to merge to. Should have enough space to + actually work. @param texCoordSetToDestroy The texture coordinate index that will disappear on - successful merges. + successful merges. */ - void mergeAdjacentTexcoords( unsigned short finalTexCoordSet, unsigned short texCoordSetToDestroy ); + void mergeAdjacentTexcoords( unsigned short finalTexCoordSet, unsigned short texCoordSetToDestroy ); /** This method builds a set of tangent vectors for a given mesh into a 3D texture coordinate buffer. @remarks diff --git a/OgreMain/include/OgreMeshFileFormat.h b/OgreMain/include/OgreMeshFileFormat.h index 312cb7623ba..be213bff2c9 100644 --- a/OgreMain/include/OgreMeshFileFormat.h +++ b/OgreMain/include/OgreMeshFileFormat.h @@ -32,12 +32,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ /** Definition of the OGRE .mesh file format .mesh files are binary files (for read efficiency at runtime) and are arranged into chunks @@ -55,11 +55,11 @@ namespace Ogre { */ - enum MeshChunkID { + enum MeshChunkID { M_HEADER = 0x1000, // char* version : Version number check M_MESH = 0x3000, - // bool skeletallyAnimated // important flag which affects h/w buffer policies + // bool skeletallyAnimated // important flag which affects h/w buffer policies // Optional M_GEOMETRY chunk M_SUBMESH = 0x4000, // char* materialName @@ -77,7 +77,7 @@ namespace Ogre { // unsigned int vertexIndex; // unsigned short boneIndex; // float weight; - // Optional chunk that matches a texture name to an alias + // Optional chunk that matches a texture name to an alias // a texture alias is sent to the submesh material to use this texture name // instead of the one in the texture unit with a matching alias name M_SUBMESH_TEXTURE_ALIAS = 0x4200, // Repeating section @@ -86,18 +86,18 @@ namespace Ogre { M_GEOMETRY = 0x5000, // NB this chunk is embedded within M_MESH and M_SUBMESH // unsigned int vertexCount - M_GEOMETRY_VERTEX_DECLARATION = 0x5100, - M_GEOMETRY_VERTEX_ELEMENT = 0x5110, // Repeating section - // unsigned short source; // buffer bind source - // unsigned short type; // VertexElementType - // unsigned short semantic; // VertexElementSemantic - // unsigned short offset; // start offset in buffer in bytes - // unsigned short index; // index of the semantic (for colours and texture coords) - M_GEOMETRY_VERTEX_BUFFER = 0x5200, // Repeating section - // unsigned short bindIndex; // Index to bind this buffer to - // unsigned short vertexSize; // Per-vertex size, must agree with declaration at this index - M_GEOMETRY_VERTEX_BUFFER_DATA = 0x5210, - // raw buffer data + M_GEOMETRY_VERTEX_DECLARATION = 0x5100, + M_GEOMETRY_VERTEX_ELEMENT = 0x5110, // Repeating section + // unsigned short source; // buffer bind source + // unsigned short type; // VertexElementType + // unsigned short semantic; // VertexElementSemantic + // unsigned short offset; // start offset in buffer in bytes + // unsigned short index; // index of the semantic (for colours and texture coords) + M_GEOMETRY_VERTEX_BUFFER = 0x5200, // Repeating section + // unsigned short bindIndex; // Index to bind this buffer to + // unsigned short vertexSize; // Per-vertex size, must agree with declaration at this index + M_GEOMETRY_VERTEX_BUFFER_DATA = 0x5210, + // raw buffer data M_MESH_SKELETON_LINK = 0x6000, // Optional link to skeleton // char* skeletonName : name of .skeleton to use @@ -113,15 +113,15 @@ namespace Ogre { // bool manual; (true for manual alternate meshes, false for generated) M_MESH_LOD_USAGE = 0x8100, // Repeating section, ordered in increasing depth - // NB LOD 0 (full detail from 0 depth) is omitted - // LOD value - this is a distance, a pixel count etc, based on strategy + // NB LOD 0 (full detail from 0 depth) is omitted + // LOD value - this is a distance, a pixel count etc, based on strategy // float lodValue; M_MESH_LOD_MANUAL = 0x8110, // Required if M_MESH_LOD section manual = true // String manualMeshName; M_MESH_LOD_GENERATED = 0x8120, // Required if M_MESH_LOD section manual = false - // Repeating section (1 per submesh) + // Repeating section (1 per submesh) // unsigned int indexCount; // bool indexes32Bit // unsigned short* faceIndexes; (indexCount) @@ -132,25 +132,25 @@ namespace Ogre { // float maxx, maxy, maxz // float radius - // Added By DrEvil - // optional chunk that contains a table of submesh indexes and the names of - // the sub-meshes. - M_SUBMESH_NAME_TABLE = 0xA000, - // Subchunks of the name table. Each chunk contains an index & string - M_SUBMESH_NAME_TABLE_ELEMENT = 0xA100, - // short index + // Added By DrEvil + // optional chunk that contains a table of submesh indexes and the names of + // the sub-meshes. + M_SUBMESH_NAME_TABLE = 0xA000, + // Subchunks of the name table. Each chunk contains an index & string + M_SUBMESH_NAME_TABLE_ELEMENT = 0xA100, + // short index // char* name - - // Optional chunk which stores precomputed edge data - M_EDGE_LISTS = 0xB000, - // Each LOD has a separate edge list - M_EDGE_LIST_LOD = 0xB100, - // unsigned short lodIndex - // bool isManual // If manual, no edge data here, loaded from manual mesh + + // Optional chunk which stores precomputed edge data + M_EDGE_LISTS = 0xB000, + // Each LOD has a separate edge list + M_EDGE_LIST_LOD = 0xB100, + // unsigned short lodIndex + // bool isManual // If manual, no edge data here, loaded from manual mesh // bool isClosed // unsigned long numTriangles // unsigned long numEdgeGroups - // Triangle* triangleList + // Triangle* triangleList // unsigned long indexSet // unsigned long vertexSet // unsigned long vertIndex[3] @@ -162,58 +162,58 @@ namespace Ogre { // unsigned long triStart // unsigned long triCount // unsigned long numEdges - // Edge* edgeList + // Edge* edgeList // unsigned long triIndex[2] // unsigned long vertIndex[2] // unsigned long sharedVertIndex[2] // bool degenerate - // Optional poses section, referred to by pose keyframes - M_POSES = 0xC000, - M_POSE = 0xC100, - // char* name (may be blank) - // unsigned short target // 0 for shared geometry, - // 1+ for submesh index + 1 - // bool includesNormals [1.8+] - M_POSE_VERTEX = 0xC111, - // unsigned long vertexIndex - // float xoffset, yoffset, zoffset - // float xnormal, ynormal, znormal (optional, 1.8+) - // Optional vertex animation chunk - M_ANIMATIONS = 0xD000, - M_ANIMATION = 0xD100, - // char* name - // float length - M_ANIMATION_BASEINFO = 0xD105, - // [Optional] base keyframe information (pose animation only) - // char* baseAnimationName (blank for self) - // float baseKeyFrameTime - - M_ANIMATION_TRACK = 0xD110, - // unsigned short type // 1 == morph, 2 == pose - // unsigned short target // 0 for shared geometry, - // 1+ for submesh index + 1 - M_ANIMATION_MORPH_KEYFRAME = 0xD111, - // float time - // bool includesNormals [1.8+] - // float x,y,z // repeat by number of vertices in original geometry - M_ANIMATION_POSE_KEYFRAME = 0xD112, - // float time - M_ANIMATION_POSE_REF = 0xD113, // repeat for number of referenced poses - // unsigned short poseIndex - // float influence + // Optional poses section, referred to by pose keyframes + M_POSES = 0xC000, + M_POSE = 0xC100, + // char* name (may be blank) + // unsigned short target // 0 for shared geometry, + // 1+ for submesh index + 1 + // bool includesNormals [1.8+] + M_POSE_VERTEX = 0xC111, + // unsigned long vertexIndex + // float xoffset, yoffset, zoffset + // float xnormal, ynormal, znormal (optional, 1.8+) + // Optional vertex animation chunk + M_ANIMATIONS = 0xD000, + M_ANIMATION = 0xD100, + // char* name + // float length + M_ANIMATION_BASEINFO = 0xD105, + // [Optional] base keyframe information (pose animation only) + // char* baseAnimationName (blank for self) + // float baseKeyFrameTime + + M_ANIMATION_TRACK = 0xD110, + // unsigned short type // 1 == morph, 2 == pose + // unsigned short target // 0 for shared geometry, + // 1+ for submesh index + 1 + M_ANIMATION_MORPH_KEYFRAME = 0xD111, + // float time + // bool includesNormals [1.8+] + // float x,y,z // repeat by number of vertices in original geometry + M_ANIMATION_POSE_KEYFRAME = 0xD112, + // float time + M_ANIMATION_POSE_REF = 0xD113, // repeat for number of referenced poses + // unsigned short poseIndex + // float influence - // Optional submesh extreme vertex list chink - M_TABLE_EXTREMES = 0xE000, - // unsigned short submesh_index; - // float extremes [n_extremes][3]; + // Optional submesh extreme vertex list chink + M_TABLE_EXTREMES = 0xE000, + // unsigned short submesh_index; + // float extremes [n_extremes][3]; - /* Version 1.2 of the .mesh format (deprecated) - enum MeshChunkID { + /* Version 1.2 of the .mesh format (deprecated) + enum MeshChunkID { M_HEADER = 0x1000, // char* version : Version number check M_MESH = 0x3000, - // bool skeletallyAnimated // important flag which affects h/w buffer policies + // bool skeletallyAnimated // important flag which affects h/w buffer policies // Optional M_GEOMETRY chunk M_SUBMESH = 0x4000, // char* materialName @@ -232,7 +232,7 @@ namespace Ogre { // unsigned short boneIndex; // float weight; M_GEOMETRY = 0x5000, // NB this chunk is embedded within M_MESH and M_SUBMESH - */ + */ // unsigned int vertexCount // float* pVertices (x, y, z order x numVertices) M_GEOMETRY_NORMALS = 0x5100, //(Optional) @@ -242,7 +242,7 @@ namespace Ogre { M_GEOMETRY_TEXCOORDS = 0x5300 //(Optional, REPEATABLE, each one adds an extra set) // unsigned short dimensions (1 for 1D, 2 for 2D, 3 for 3D) // float* pTexCoords (u [v] [w] order, dimensions x numVertices) - /* + /* M_MESH_SKELETON_LINK = 0x6000, // Optional link to skeleton // char* skeletonName : name of .skeleton to use @@ -257,14 +257,14 @@ namespace Ogre { // bool manual; (true for manual alternate meshes, false for generated) M_MESH_LOD_USAGE = 0x8100, // Repeating section, ordered in increasing depth - // NB LOD 0 (full detail from 0 depth) is omitted + // NB LOD 0 (full detail from 0 depth) is omitted // float fromSquaredDepth; M_MESH_LOD_MANUAL = 0x8110, // Required if M_MESH_LOD section manual = true // String manualMeshName; M_MESH_LOD_GENERATED = 0x8120, // Required if M_MESH_LOD section manual = false - // Repeating section (1 per submesh) + // Repeating section (1 per submesh) // unsigned int indexCount; // bool indexes32Bit // unsigned short* faceIndexes; (indexCount) @@ -275,19 +275,19 @@ namespace Ogre { // float maxx, maxy, maxz // float radius - // Added By DrEvil - // optional chunk that contains a table of submesh indexes and the names of - // the sub-meshes. - M_SUBMESH_NAME_TABLE, - // Subchunks of the name table. Each chunk contains an index & string - M_SUBMESH_NAME_TABLE_ELEMENT, - // short index + // Added By DrEvil + // optional chunk that contains a table of submesh indexes and the names of + // the sub-meshes. + M_SUBMESH_NAME_TABLE, + // Subchunks of the name table. Each chunk contains an index & string + M_SUBMESH_NAME_TABLE_ELEMENT, + // short index // char* name - */ + */ }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreMeshManager.h b/OgreMain/include/OgreMeshManager.h index b0b97623e16..c8bd19232d1 100644 --- a/OgreMain/include/OgreMeshManager.h +++ b/OgreMain/include/OgreMeshManager.h @@ -39,15 +39,15 @@ THE SOFTWARE. namespace Ogre { - class MeshSerializerListener; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Handles the management of mesh resources. + class MeshSerializerListener; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Handles the management of mesh resources. @remarks This class deals with the runtime management of mesh data; like other resource managers it handles @@ -64,16 +64,16 @@ namespace Ogre { /** Initialises the manager, only to be called by OGRE internally. */ void _initialise(void); - /// Get a resource by name - /// @see ResourceManager::getResourceByName - MeshPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + /// Get a resource by name + /// @see ResourceManager::getResourceByName + MeshPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); - /// Create a new mesh - /// @see ResourceManager::createResource - MeshPtr create (const String& name, const String& group, - bool isManual = false, ManualResourceLoader* loader = 0, - const NameValuePairList* createParams = 0); + /// Create a new mesh + /// @see ResourceManager::createResource + MeshPtr create (const String& name, const String& group, + bool isManual = false, ManualResourceLoader* loader = 0, + const NameValuePairList* createParams = 0); /** Create a new mesh, or retrieve an existing one with the same name if it already exists. @@ -92,9 +92,9 @@ namespace Ogre { const String& group, bool isManual=false, ManualResourceLoader* loader=0, const NameValuePairList* params=0, - HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - bool vertexBufferShadowed = true, bool indexBufferShadowed = true); + HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + bool vertexBufferShadowed = true, bool indexBufferShadowed = true); /** Prepares a mesh for loading from a file. This does the IO in advance of the call to load(). @note @@ -106,21 +106,21 @@ namespace Ogre { format is better for runtime performance, and we also have control over pre-processed data (such as collision boxes, LOD reductions etc). - @param filename The name of the .mesh file + @param filename The name of the .mesh file @param groupName The name of the resource group to assign the mesh to - @param vertexBufferUsage The usage flags with which the vertex buffer(s) - will be created - @param indexBufferUsage The usage flags with which the index buffer(s) created for - this mesh will be created with. - @param vertexBufferShadowed If true, the vertex buffers will be shadowed by system memory + @param vertexBufferUsage The usage flags with which the vertex buffer(s) + will be created + @param indexBufferUsage The usage flags with which the index buffer(s) created for + this mesh will be created with. + @param vertexBufferShadowed If true, the vertex buffers will be shadowed by system memory copies for faster read access - @param indexBufferShadowed If true, the index buffers will be shadowed by system memory + @param indexBufferShadowed If true, the index buffers will be shadowed by system memory copies for faster read access */ MeshPtr prepare( const String& filename, const String& groupName, - HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - bool vertexBufferShadowed = true, bool indexBufferShadowed = true); + HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + bool vertexBufferShadowed = true, bool indexBufferShadowed = true); /** Loads a mesh from a file, making it immediately available for use. @note @@ -132,27 +132,27 @@ namespace Ogre { format is better for runtime performance, and we also have control over pre-processed data (such as collision boxes, LOD reductions etc). - @param filename The name of the .mesh file + @param filename The name of the .mesh file @param groupName The name of the resource group to assign the mesh to - @param vertexBufferUsage The usage flags with which the vertex buffer(s) - will be created - @param indexBufferUsage The usage flags with which the index buffer(s) created for - this mesh will be created with. - @param vertexBufferShadowed If true, the vertex buffers will be shadowed by system memory + @param vertexBufferUsage The usage flags with which the vertex buffer(s) + will be created + @param indexBufferUsage The usage flags with which the index buffer(s) created for + this mesh will be created with. + @param vertexBufferShadowed If true, the vertex buffers will be shadowed by system memory copies for faster read access - @param indexBufferShadowed If true, the index buffers will be shadowed by system memory + @param indexBufferShadowed If true, the index buffers will be shadowed by system memory copies for faster read access */ MeshPtr load( const String& filename, const String& groupName, - HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - bool vertexBufferShadowed = true, bool indexBufferShadowed = true); + HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + bool vertexBufferShadowed = true, bool indexBufferShadowed = true); /** Creates a new Mesh specifically for manual definition rather than loading from an object file. - @remarks - Note that once you've defined your mesh, you must call Mesh::_setBounds and + @remarks + Note that once you've defined your mesh, you must call Mesh::_setBounds and Mesh::_setBoundingRadius in order to define the bounds of your mesh. In previous versions of OGRE you could call Mesh::_updateBounds, but OGRE's support of write-only vertex buffers makes this no longer appropriate. @@ -191,18 +191,18 @@ namespace Ogre { vTile The number of times the texture should be repeated in the v direction @param upVector The 'Up' direction of the plane texture coordinates. - @param - vertexBufferUsage The usage flag with which the vertex buffer for this plane will be created - @param - indexBufferUsage The usage flag with which the index buffer for this plane will be created - @param - vertexShadowBuffer If this flag is set to true, the vertex buffer will be created - with a system memory shadow buffer, - allowing you to read it back more efficiently than if it is in hardware - @param - indexShadowBuffer If this flag is set to true, the index buffer will be - created with a system memory shadow buffer, - allowing you to read it back more efficiently than if it is in hardware + @param + vertexBufferUsage The usage flag with which the vertex buffer for this plane will be created + @param + indexBufferUsage The usage flag with which the index buffer for this plane will be created + @param + vertexShadowBuffer If this flag is set to true, the vertex buffer will be created + with a system memory shadow buffer, + allowing you to read it back more efficiently than if it is in hardware + @param + indexShadowBuffer If this flag is set to true, the index buffer will be + created with a system memory shadow buffer, + allowing you to read it back more efficiently than if it is in hardware */ MeshPtr createPlane( const String& name, const String& groupName, const Plane& plane, @@ -210,13 +210,13 @@ namespace Ogre { int xsegments = 1, int ysegments = 1, bool normals = true, unsigned short numTexCoordSets = 1, Real uTile = 1.0f, Real vTile = 1.0f, const Vector3& upVector = Vector3::UNIT_Y, - HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - bool vertexShadowBuffer = true, bool indexShadowBuffer = true); + HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + bool vertexShadowBuffer = true, bool indexShadowBuffer = true); /** Creates a plane, which because of it's texture coordinates looks like a curved - surface, useful for skies in a skybox. + surface, useful for skies in a skybox. @param name The name to give the resulting mesh @param groupName @@ -228,11 +228,11 @@ namespace Ogre { @param height The height of the plane in world coordinates @param curvature - The curvature of the plane. Good values are + The curvature of the plane. Good values are between 2 and 65. Higher values are more curved leading to a smoother effect, lower values are less curved meaning more distortion at the horizons but a better distance effect. - @param xsegments + @param xsegments The number of segments to the plane in the x direction @param ysegments The number of segments to the plane in the y direction @@ -249,35 +249,35 @@ namespace Ogre { The 'Up' direction of the plane. @param orientation The orientation of the overall sphere that's used to create the illusion - @param vertexBufferUsage - The usage flag with which the vertex buffer for this plane will be created - @param indexBufferUsage - The usage flag with which the index buffer for this plane will be created - @param vertexShadowBuffer - If this flag is set to true, the vertex buffer will be created - with a system memory shadow buffer, - allowing you to read it back more efficiently than if it is in hardware - @param indexShadowBuffer - If this flag is set to true, the index buffer will be - created with a system memory shadow buffer, - allowing you to read it back more efficiently than if it is in hardware + @param vertexBufferUsage + The usage flag with which the vertex buffer for this plane will be created + @param indexBufferUsage + The usage flag with which the index buffer for this plane will be created + @param vertexShadowBuffer + If this flag is set to true, the vertex buffer will be created + with a system memory shadow buffer, + allowing you to read it back more efficiently than if it is in hardware + @param indexShadowBuffer + If this flag is set to true, the index buffer will be + created with a system memory shadow buffer, + allowing you to read it back more efficiently than if it is in hardware @param ySegmentsToKeep The number of segments from the top of the dome downwards to keep. -1 keeps all of them. This can save fillrate if you cannot see much of the sky lower down. */ - MeshPtr createCurvedIllusionPlane( + MeshPtr createCurvedIllusionPlane( const String& name, const String& groupName, const Plane& plane, Real width, Real height, Real curvature, int xsegments = 1, int ysegments = 1, bool normals = true, unsigned short numTexCoordSets = 1, Real uTile = 1.0f, Real vTile = 1.0f, const Vector3& upVector = Vector3::UNIT_Y, const Quaternion& orientation = Quaternion::IDENTITY, - HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - bool vertexShadowBuffer = true, bool indexShadowBuffer = true, + HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + bool vertexShadowBuffer = true, bool indexShadowBuffer = true, int ySegmentsToKeep = -1); - /** Creates a genuinely curved plane, by default majoring on the x/y axes facing positive Z. + /** Creates a genuinely curved plane, by default majoring on the x/y axes facing positive Z. @param name The name to give the resulting mesh @param groupName @@ -288,8 +288,8 @@ namespace Ogre { The width of the plane in world coordinates @param height The height of the plane in world coordinates - @param bow - The amount of 'bow' in the curved plane. (Could also be considered the depth.) + @param bow + The amount of 'bow' in the curved plane. (Could also be considered the depth.) @param xsegments The number of segments to the plane in the x direction @param ysegments @@ -305,28 +305,28 @@ namespace Ogre { The number of times the texture should be repeated in the v direction @param upVector The 'Up' direction of the plane. - @param vertexBufferUsage - The usage flag with which the vertex buffer for this plane will be created - @param indexBufferUsage - The usage flag with which the index buffer for this plane will be created - @param vertexShadowBuffer - If this flag is set to true, the vertex buffer will be created - with a system memory shadow buffer, - allowing you to read it back more efficiently than if it is in hardware - @param indexShadowBuffer - If this flag is set to true, the index buffer will be - created with a system memory shadow buffer, - allowing you to read it back more efficiently than if it is in hardware + @param vertexBufferUsage + The usage flag with which the vertex buffer for this plane will be created + @param indexBufferUsage + The usage flag with which the index buffer for this plane will be created + @param vertexShadowBuffer + If this flag is set to true, the vertex buffer will be created + with a system memory shadow buffer, + allowing you to read it back more efficiently than if it is in hardware + @param indexShadowBuffer + If this flag is set to true, the index buffer will be + created with a system memory shadow buffer, + allowing you to read it back more efficiently than if it is in hardware */ - MeshPtr createCurvedPlane( - const String& name, const String& groupName, const Plane& plane, - Real width, Real height, Real bow = 0.5f, - int xsegments = 1, int ysegments = 1, - bool normals = false, unsigned short numTexCoordSets = 1, - Real uTile = 1.0f, Real vTile = 1.0f, const Vector3& upVector = Vector3::UNIT_Y, - HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - bool vertexShadowBuffer = true, bool indexShadowBuffer = true); + MeshPtr createCurvedPlane( + const String& name, const String& groupName, const Plane& plane, + Real width, Real height, Real bow = 0.5f, + int xsegments = 1, int ysegments = 1, + bool normals = false, unsigned short numTexCoordSets = 1, + Real uTile = 1.0f, Real vTile = 1.0f, const Vector3& upVector = Vector3::UNIT_Y, + HardwareBuffer::Usage vertexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + bool vertexShadowBuffer = true, bool indexShadowBuffer = true); /** Creates a Bezier patch based on an array of control vertices. @param name @@ -414,22 +414,22 @@ namespace Ogre { */ static MeshManager* getSingletonPtr(void); - /** Gets the factor by which the bounding box of an entity is padded. - Default is 0.01 - */ + /** Gets the factor by which the bounding box of an entity is padded. + Default is 0.01 + */ Real getBoundsPaddingFactor(void); - - /** Sets the factor by which the bounding box of an entity is padded - */ + + /** Sets the factor by which the bounding box of an entity is padded + */ void setBoundsPaddingFactor(Real paddingFactor); - /** Sets the listener used to control mesh loading through the serializer. - */ - void setListener(MeshSerializerListener *listener); - - /** Gets the listener used to control mesh loading through the serializer. - */ - MeshSerializerListener *getListener(); + /** Sets the listener used to control mesh loading through the serializer. + */ + void setListener(MeshSerializerListener *listener); + + /** Gets the listener used to control mesh loading through the serializer. + */ + MeshSerializerListener *getListener(); /** @see ManualResourceLoader::loadResource */ void loadResource(Resource* res); @@ -443,13 +443,13 @@ namespace Ogre { /** Utility method for tessellating 2D meshes. */ void tesselate2DMesh(SubMesh* pSub, unsigned short meshWidth, unsigned short meshHeight, - bool doubleSided = false, - HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, - bool indexSysMem = false); + bool doubleSided = false, + HardwareBuffer::Usage indexBufferUsage = HardwareBuffer::HBU_STATIC_WRITE_ONLY, + bool indexSysMem = false); void createPrefabPlane(void); - void createPrefabCube(void); - void createPrefabSphere(void); + void createPrefabCube(void); + void createPrefabSphere(void); /** Enum identifying the types of manual mesh built by this manager */ enum MeshBuildType @@ -492,16 +492,16 @@ namespace Ogre { void loadManualCurvedIllusionPlane(Mesh* pMesh, MeshBuildParams& params); bool mPrepAllMeshesForShadowVolumes; - - //the factor by which the bounding box of an entity is padded - Real mBoundsPaddingFactor; + + //the factor by which the bounding box of an entity is padded + Real mBoundsPaddingFactor; - // The listener to pass to serializers - MeshSerializerListener *mListener; + // The listener to pass to serializers + MeshSerializerListener *mListener; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } //namespace diff --git a/OgreMain/include/OgreMeshSerializer.h b/OgreMain/include/OgreMeshSerializer.h index fcea3ded5d5..6c5c9f83cbf 100644 --- a/OgreMain/include/OgreMeshSerializer.h +++ b/OgreMain/include/OgreMeshSerializer.h @@ -35,37 +35,37 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - - class MeshSerializerListener; - - /// Mesh compatibility versions - enum MeshVersion - { - /// Latest version available - MESH_VERSION_LATEST, - - /// OGRE version v1.10+ - MESH_VERSION_1_10, - /// OGRE version v1.8+ - MESH_VERSION_1_8, - /// OGRE version v1.7+ - MESH_VERSION_1_7, - /// OGRE version v1.4+ - MESH_VERSION_1_4, - /// OGRE version v1.0+ - MESH_VERSION_1_0, - - /// Legacy versions, DO NOT USE for writing - MESH_VERSION_LEGACY - }; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Class for serialising mesh data to/from an OGRE .mesh file. + + class MeshSerializerListener; + + /// Mesh compatibility versions + enum MeshVersion + { + /// Latest version available + MESH_VERSION_LATEST, + + /// OGRE version v1.10+ + MESH_VERSION_1_10, + /// OGRE version v1.8+ + MESH_VERSION_1_8, + /// OGRE version v1.7+ + MESH_VERSION_1_7, + /// OGRE version v1.4+ + MESH_VERSION_1_4, + /// OGRE version v1.0+ + MESH_VERSION_1_0, + + /// Legacy versions, DO NOT USE for writing + MESH_VERSION_LEGACY + }; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Class for serialising mesh data to/from an OGRE .mesh file. @remarks This class allows exporters to write OGRE .mesh files easily, and allows the OGRE engine to import .mesh files into instantiated OGRE Meshes. @@ -101,53 +101,53 @@ namespace Ogre { to a .mesh file in the latest format version available. @param pMesh Pointer to the Mesh to export @param filename The destination filename - @param endianMode The endian mode of the written file + @param endianMode The endian mode of the written file */ void exportMesh(const Mesh* pMesh, const String& filename, - Endian endianMode = ENDIAN_NATIVE); + Endian endianMode = ENDIAN_NATIVE); /** Exports a mesh to the file specified, in a specific version format. - @remarks - This method takes an externally created Mesh object, and exports it - to a .mesh file in the specified format version. Note that picking a - format version other that the latest will cause some information to be - lost. - @param pMesh Pointer to the Mesh to export - @param filename The destination filename - @param version Mesh version to write - @param endianMode The endian mode of the written file - */ + @remarks + This method takes an externally created Mesh object, and exports it + to a .mesh file in the specified format version. Note that picking a + format version other that the latest will cause some information to be + lost. + @param pMesh Pointer to the Mesh to export + @param filename The destination filename + @param version Mesh version to write + @param endianMode The endian mode of the written file + */ void exportMesh(const Mesh* pMesh, const String& filename, - MeshVersion version, - Endian endianMode = ENDIAN_NATIVE); + MeshVersion version, + Endian endianMode = ENDIAN_NATIVE); /** Exports a mesh to the stream specified, in the latest format. @remarks - This method takes an externally created Mesh object, and exports it - to a .mesh file in the latest format version. + This method takes an externally created Mesh object, and exports it + to a .mesh file in the latest format version. @param pMesh Pointer to the Mesh to export @param stream Writeable stream - @param endianMode The endian mode of the written file + @param endianMode The endian mode of the written file */ void exportMesh(const Mesh* pMesh, DataStreamPtr stream, - Endian endianMode = ENDIAN_NATIVE); + Endian endianMode = ENDIAN_NATIVE); /** Exports a mesh to the stream specified, in a specific version format. - @remarks - This method takes an externally created Mesh object, and exports it - to a .mesh file in the specified format version. Note that picking a - format version other that the latest will cause some information to be - lost. - @param pMesh Pointer to the Mesh to export - @param stream Writeable stream - @param version Mesh version to write - @param endianMode The endian mode of the written file - */ + @remarks + This method takes an externally created Mesh object, and exports it + to a .mesh file in the specified format version. Note that picking a + format version other that the latest will cause some information to be + lost. + @param pMesh Pointer to the Mesh to export + @param stream Writeable stream + @param version Mesh version to write + @param endianMode The endian mode of the written file + */ void exportMesh(const Mesh* pMesh, DataStreamPtr stream, - MeshVersion version, - Endian endianMode = ENDIAN_NATIVE); + MeshVersion version, + Endian endianMode = ENDIAN_NATIVE); - /** Imports Mesh and (optionally) Material data from a .mesh file DataStream. + /** Imports Mesh and (optionally) Material data from a .mesh file DataStream. @remarks This method imports data from a DataStream opened from a .mesh file and places it's contents into the Mesh object which is passed in. @@ -156,54 +156,54 @@ namespace Ogre { */ void importMesh(DataStreamPtr& stream, Mesh* pDest); - /// Sets the listener for this serializer - void setListener(MeshSerializerListener *listener); - /// Returns the current listener - MeshSerializerListener *getListener(); - + /// Sets the listener for this serializer + void setListener(MeshSerializerListener *listener); + /// Returns the current listener + MeshSerializerListener *getListener(); + protected: - - class MeshVersionData : public SerializerAlloc - { - public: - MeshVersion version; - String versionString; - MeshSerializerImpl* impl; - - MeshVersionData(MeshVersion _ver, const String& _string, MeshSerializerImpl* _impl) - : version(_ver), versionString(_string), impl(_impl) {} - - ~MeshVersionData() { OGRE_DELETE impl; } - - }; + + class MeshVersionData : public SerializerAlloc + { + public: + MeshVersion version; + String versionString; + MeshSerializerImpl* impl; + + MeshVersionData(MeshVersion _ver, const String& _string, MeshSerializerImpl* _impl) + : version(_ver), versionString(_string), impl(_impl) {} + + ~MeshVersionData() { OGRE_DELETE impl; } + + }; typedef vector::type MeshVersionDataList; MeshVersionDataList mVersionData; - MeshSerializerListener *mListener; + MeshSerializerListener *mListener; }; - /** - @remarks - This class allows users to hook into the mesh loading process and - modify references within the mesh as they are loading. Material and - skeletal references can be processed using this interface which allows - finer control over resources. - */ - class MeshSerializerListener - { - public: - virtual ~MeshSerializerListener() {} - /// Called to override the loading of the given named material - virtual void processMaterialName(Mesh *mesh, String *name) = 0; - /// Called to override the reference to a skeleton - virtual void processSkeletonName(Mesh *mesh, String *name) = 0; - /// Allows to do changes on mesh after it's completely loaded. For example you can generate LOD levels here. - virtual void processMeshCompleted(Mesh *mesh) = 0; - }; - /** @} */ - /** @} */ + /** + @remarks + This class allows users to hook into the mesh loading process and + modify references within the mesh as they are loading. Material and + skeletal references can be processed using this interface which allows + finer control over resources. + */ + class MeshSerializerListener + { + public: + virtual ~MeshSerializerListener() {} + /// Called to override the loading of the given named material + virtual void processMaterialName(Mesh *mesh, String *name) = 0; + /// Called to override the reference to a skeleton + virtual void processSkeletonName(Mesh *mesh, String *name) = 0; + /// Allows to do changes on mesh after it's completely loaded. For example you can generate LOD levels here. + virtual void processMeshCompleted(Mesh *mesh) = 0; + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreMeshSerializerImpl.h b/OgreMain/include/OgreMeshSerializerImpl.h index fb219d52679..dbb42ebc2b8 100644 --- a/OgreMain/include/OgreMeshSerializerImpl.h +++ b/OgreMain/include/OgreMeshSerializerImpl.h @@ -36,25 +36,25 @@ THE SOFTWARE. #include "OgreVertexBoneAssignment.h" namespace Ogre { - - class MeshSerializerListener; + + class MeshSerializerListener; struct MeshLodUsage; - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Internal implementation of Mesh reading / writing for the latest version of the + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Internal implementation of Mesh reading / writing for the latest version of the .mesh format. @remarks In order to maintain compatibility with older versions of the .mesh format, there will be alternative subclasses of this class to load older versions, whilst this class will remain to load the latest version. - @note - This mesh format was used from Ogre v1.10. + @note + This mesh format was used from Ogre v1.10. */ class _OgrePrivate MeshSerializerImpl : public Serializer @@ -68,10 +68,10 @@ namespace Ogre { and optionally the Materials it uses to a .mesh file. @param pMesh Pointer to the Mesh to export @param stream The destination stream - @param endianMode The endian mode for the written file + @param endianMode The endian mode for the written file */ void exportMesh(const Mesh* pMesh, DataStreamPtr stream, - Endian endianMode = ENDIAN_NATIVE); + Endian endianMode = ENDIAN_NATIVE); /** Imports Mesh and (optionally) Material data from a .mesh file DataStream. @remarks @@ -102,14 +102,14 @@ namespace Ogre { #endif virtual void writeBoundsInfo(const Mesh* pMesh); virtual void writeEdgeList(const Mesh* pMesh); - virtual void writeAnimations(const Mesh* pMesh); - virtual void writeAnimation(const Animation* anim); - virtual void writePoses(const Mesh* pMesh); - virtual void writePose(const Pose* pose); - virtual void writeAnimationTrack(const VertexAnimationTrack* track); - virtual void writeMorphKeyframe(const VertexMorphKeyFrame* kf, size_t vertexCount); - virtual void writePoseKeyframe(const VertexPoseKeyFrame* kf); - virtual void writePoseKeyframePoseRef(const VertexPoseKeyFrame::PoseRef& poseRef); + virtual void writeAnimations(const Mesh* pMesh); + virtual void writeAnimation(const Animation* anim); + virtual void writePoses(const Mesh* pMesh); + virtual void writePose(const Pose* pose); + virtual void writeAnimationTrack(const VertexAnimationTrack* track); + virtual void writeMorphKeyframe(const VertexMorphKeyFrame* kf, size_t vertexCount); + virtual void writePoseKeyframe(const VertexPoseKeyFrame* kf); + virtual void writePoseKeyframePoseRef(const VertexPoseKeyFrame::PoseRef& poseRef); virtual void writeExtremes(const Mesh *pMesh); virtual void writeSubMeshExtremes(unsigned short idx, const SubMesh* s); @@ -120,26 +120,26 @@ namespace Ogre { virtual size_t calcBoneAssignmentSize(void); virtual size_t calcSubMeshOperationSize(const SubMesh* pSub); virtual size_t calcSubMeshNameTableSize(const Mesh* pMesh); - virtual size_t calcLodLevelSize(const Mesh* pMesh); - virtual size_t calcLodUsageManualSize(const MeshLodUsage& usage); - virtual size_t calcLodUsageGeneratedSize(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum); - virtual size_t calcLodUsageGeneratedSubmeshSize(const SubMesh* submesh, unsigned short lodNum); + virtual size_t calcLodLevelSize(const Mesh* pMesh); + virtual size_t calcLodUsageManualSize(const MeshLodUsage& usage); + virtual size_t calcLodUsageGeneratedSize(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum); + virtual size_t calcLodUsageGeneratedSubmeshSize(const SubMesh* submesh, unsigned short lodNum); virtual size_t calcEdgeListSize(const Mesh* pMesh); virtual size_t calcEdgeListLodSize(const EdgeData* data, bool isManual); virtual size_t calcEdgeGroupSize(const EdgeData::EdgeGroup& group); - virtual size_t calcPosesSize(const Mesh* pMesh); - virtual size_t calcPoseSize(const Pose* pose); - virtual size_t calcAnimationsSize(const Mesh* pMesh); - virtual size_t calcAnimationSize(const Animation* anim); - virtual size_t calcAnimationTrackSize(const VertexAnimationTrack* track); - virtual size_t calcMorphKeyframeSize(const VertexMorphKeyFrame* kf, size_t vertexCount); - virtual size_t calcPoseKeyframeSize(const VertexPoseKeyFrame* kf); - virtual size_t calcPoseKeyframePoseRefSize(void); - virtual size_t calcPoseVertexSize(const Pose* pose); + virtual size_t calcPosesSize(const Mesh* pMesh); + virtual size_t calcPoseSize(const Pose* pose); + virtual size_t calcAnimationsSize(const Mesh* pMesh); + virtual size_t calcAnimationSize(const Animation* anim); + virtual size_t calcAnimationTrackSize(const VertexAnimationTrack* track); + virtual size_t calcMorphKeyframeSize(const VertexMorphKeyFrame* kf, size_t vertexCount); + virtual size_t calcPoseKeyframeSize(const VertexPoseKeyFrame* kf); + virtual size_t calcPoseKeyframePoseRefSize(void); + virtual size_t calcPoseVertexSize(const Pose* pose); virtual size_t calcSubMeshTextureAliasesSize(const SubMesh* pSub); - virtual size_t calcBoundsInfoSize(const Mesh* pMesh); - virtual size_t calcExtremesSize(const Mesh* pMesh); - virtual size_t calcSubMeshExtremesSize(unsigned short idx, const SubMesh* s); + virtual size_t calcBoundsInfoSize(const Mesh* pMesh); + virtual size_t calcExtremesSize(const Mesh* pMesh); + virtual size_t calcSubMeshExtremesSize(unsigned short idx, const SubMesh* s); virtual void readTextureLayer(DataStreamPtr& stream, Mesh* pMesh, MaterialPtr& pMat); virtual void readSubMeshNameTable(DataStreamPtr& stream, Mesh* pMesh); @@ -158,21 +158,21 @@ namespace Ogre { SubMesh* sub); virtual void readMeshLodLevel(DataStreamPtr& stream, Mesh* pMesh); #if !OGRE_NO_MESHLOD - virtual void readMeshLodUsageManual(DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage); - virtual void readMeshLodUsageGenerated(DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage); + virtual void readMeshLodUsageManual(DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage); + virtual void readMeshLodUsageGenerated(DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage); #endif virtual void readBoundsInfo(DataStreamPtr& stream, Mesh* pMesh); virtual void readEdgeList(DataStreamPtr& stream, Mesh* pMesh); virtual void readEdgeListLodInfo(DataStreamPtr& stream, EdgeData* edgeData); - virtual void readPoses(DataStreamPtr& stream, Mesh* pMesh); - virtual void readPose(DataStreamPtr& stream, Mesh* pMesh); - virtual void readAnimations(DataStreamPtr& stream, Mesh* pMesh); - virtual void readAnimation(DataStreamPtr& stream, Mesh* pMesh); - virtual void readAnimationTrack(DataStreamPtr& stream, Animation* anim, - Mesh* pMesh); - virtual void readMorphKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track); - virtual void readPoseKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track); - virtual void readExtremes(DataStreamPtr& stream, Mesh *pMesh); + virtual void readPoses(DataStreamPtr& stream, Mesh* pMesh); + virtual void readPose(DataStreamPtr& stream, Mesh* pMesh); + virtual void readAnimations(DataStreamPtr& stream, Mesh* pMesh); + virtual void readAnimation(DataStreamPtr& stream, Mesh* pMesh); + virtual void readAnimationTrack(DataStreamPtr& stream, Animation* anim, + Mesh* pMesh); + virtual void readMorphKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track); + virtual void readPoseKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track); + virtual void readExtremes(DataStreamPtr& stream, Mesh *pMesh); /// Flip an entire vertex buffer from little endian @@ -182,82 +182,82 @@ namespace Ogre { /// Flip the endianness of an entire vertex buffer, passed in as a /// pointer to locked or temporary memory virtual void flipEndian(void* pData, size_t vertexCount, size_t vertexSize, const VertexDeclaration::VertexElementList& elems); - - /// This function can be overloaded to disable validation in debug builds. - virtual void enableValidation(); + + /// This function can be overloaded to disable validation in debug builds. + virtual void enableValidation(); - ushort exportedLodCount; // Needed to limit exported Edge data, when exporting - }; + ushort exportedLodCount; // Needed to limit exported Edge data, when exporting + }; - /** Class for providing backwards-compatibility for loading version 1.8 of the .mesh format. - This mesh format was used from Ogre v1.8. - */ + /** Class for providing backwards-compatibility for loading version 1.8 of the .mesh format. + This mesh format was used from Ogre v1.8. + */ class _OgrePrivate MeshSerializerImpl_v1_8 : public MeshSerializerImpl { public: MeshSerializerImpl_v1_8(); ~MeshSerializerImpl_v1_8(); protected: - // In the past we could select to use manual or automatic generated Lod levels, - // but now we can mix them. If it is mixed, we can't export it to older mesh formats. - virtual bool isLodMixed(const Mesh* pMesh); - virtual size_t calcLodLevelSize(const Mesh* pMesh); - virtual size_t calcLodUsageManualSize(const MeshLodUsage& usage); - virtual size_t calcLodUsageGeneratedSize(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum); - virtual size_t calcLodUsageGeneratedSubmeshSize(const SubMesh* submesh, unsigned short lodNum); + // In the past we could select to use manual or automatic generated Lod levels, + // but now we can mix them. If it is mixed, we can't export it to older mesh formats. + virtual bool isLodMixed(const Mesh* pMesh); + virtual size_t calcLodLevelSize(const Mesh* pMesh); + virtual size_t calcLodUsageManualSize(const MeshLodUsage& usage); + virtual size_t calcLodUsageGeneratedSize(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum); + virtual size_t calcLodUsageGeneratedSubmeshSize(const SubMesh* submesh, unsigned short lodNum); #if !OGRE_NO_MESHLOD - virtual void writeLodLevel(const Mesh* pMesh); - virtual void writeLodUsageGenerated(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum); - virtual void writeLodUsageGeneratedSubmesh(const SubMesh* submesh, unsigned short lodNum); - virtual void writeLodUsageManual(const MeshLodUsage& usage); + virtual void writeLodLevel(const Mesh* pMesh); + virtual void writeLodUsageGenerated(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum); + virtual void writeLodUsageGeneratedSubmesh(const SubMesh* submesh, unsigned short lodNum); + virtual void writeLodUsageManual(const MeshLodUsage& usage); - virtual void readMeshLodUsageGenerated(DataStreamPtr& stream, Mesh* pMesh, - unsigned short lodNum, MeshLodUsage& usage); - virtual void readMeshLodUsageManual(DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage); + virtual void readMeshLodUsageGenerated(DataStreamPtr& stream, Mesh* pMesh, + unsigned short lodNum, MeshLodUsage& usage); + virtual void readMeshLodUsageManual(DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage); #endif - virtual void readMeshLodLevel(DataStreamPtr& stream, Mesh* pMesh); - virtual void enableValidation(); - }; + virtual void readMeshLodLevel(DataStreamPtr& stream, Mesh* pMesh); + virtual void enableValidation(); + }; /** Class for providing backwards-compatibility for loading version 1.41 of the .mesh format. - This mesh format was used from Ogre v1.7. - */ + This mesh format was used from Ogre v1.7. + */ class _OgrePrivate MeshSerializerImpl_v1_41 : public MeshSerializerImpl_v1_8 { public: MeshSerializerImpl_v1_41(); ~MeshSerializerImpl_v1_41(); protected: - void writeMorphKeyframe(const VertexMorphKeyFrame* kf, size_t vertexCount); - void readMorphKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track); - void writePose(const Pose* pose); - void readPose(DataStreamPtr& stream, Mesh* pMesh); - size_t calcMorphKeyframeSize(const VertexMorphKeyFrame* kf, size_t vertexCount); - size_t calcPoseSize(const Pose* pose); - size_t calcPoseVertexSize(void); + void writeMorphKeyframe(const VertexMorphKeyFrame* kf, size_t vertexCount); + void readMorphKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track); + void writePose(const Pose* pose); + void readPose(DataStreamPtr& stream, Mesh* pMesh); + size_t calcMorphKeyframeSize(const VertexMorphKeyFrame* kf, size_t vertexCount); + size_t calcPoseSize(const Pose* pose); + size_t calcPoseVertexSize(void); }; /** Class for providing backwards-compatibility for loading version 1.4 of the .mesh format. - This mesh format was used from Ogre v1.4. - */ + This mesh format was used from Ogre v1.4. + */ class _OgrePrivate MeshSerializerImpl_v1_4 : public MeshSerializerImpl_v1_41 { public: MeshSerializerImpl_v1_4(); ~MeshSerializerImpl_v1_4(); protected: - virtual size_t calcLodLevelSize(const Mesh* pMesh); - virtual void readMeshLodLevel(DataStreamPtr& stream, Mesh* pMesh); + virtual size_t calcLodLevelSize(const Mesh* pMesh); + virtual void readMeshLodLevel(DataStreamPtr& stream, Mesh* pMesh); #if !OGRE_NO_MESHLOD - virtual void writeLodLevel(const Mesh* pMesh); - virtual void writeLodUsageGenerated(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum); + virtual void writeLodLevel(const Mesh* pMesh); + virtual void writeLodUsageGenerated(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum); #endif - }; + }; /** Class for providing backwards-compatibility for loading version 1.3 of the .mesh format. - This mesh format was used from Ogre v1.0 (and some pre-releases) - */ + This mesh format was used from Ogre v1.0 (and some pre-releases) + */ class _OgrePrivate MeshSerializerImpl_v1_3 : public MeshSerializerImpl_v1_4 { public: @@ -268,15 +268,15 @@ namespace Ogre { /// Reorganise triangles of the edge list to group by vertex set virtual void reorganiseTriangles(EdgeData* edgeData); - - virtual void writeEdgeList(const Mesh* pMesh); - virtual size_t calcEdgeListLodSize(const EdgeData* edgeData, bool isManual); - virtual size_t calcEdgeGroupSize(const EdgeData::EdgeGroup& group); + + virtual void writeEdgeList(const Mesh* pMesh); + virtual size_t calcEdgeListLodSize(const EdgeData* edgeData, bool isManual); + virtual size_t calcEdgeGroupSize(const EdgeData::EdgeGroup& group); }; /** Class for providing backwards-compatibility for loading version 1.2 of the .mesh format. - This is a LEGACY FORMAT that pre-dates version Ogre 1.0 - */ + This is a LEGACY FORMAT that pre-dates version Ogre 1.0 + */ class _OgrePrivate MeshSerializerImpl_v1_2 : public MeshSerializerImpl_v1_3 { public: @@ -296,8 +296,8 @@ namespace Ogre { }; /** Class for providing backwards-compatibility for loading version 1.1 of the .mesh format. - This is a LEGACY FORMAT that pre-dates version Ogre 1.0 - */ + This is a LEGACY FORMAT that pre-dates version Ogre 1.0 + */ class _OgrePrivate MeshSerializerImpl_v1_1 : public MeshSerializerImpl_v1_2 { public: @@ -308,8 +308,8 @@ namespace Ogre { Mesh* pMesh, VertexData* dest, unsigned short set); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreMovableObject.h b/OgreMain/include/OgreMovableObject.h index 5a7d9f05258..35840d1ec9a 100644 --- a/OgreMain/include/OgreMovableObject.h +++ b/OgreMain/include/OgreMovableObject.h @@ -39,16 +39,16 @@ THE SOFTWARE. namespace Ogre { - // Forward declaration - class MovableObjectFactory; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Abstract class defining a movable object in a scene. + // Forward declaration + class MovableObjectFactory; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Abstract class defining a movable object in a scene. @remarks Instances of this class are discrete, relatively small, movable objects which are attached to SceneNode objects to define their position. @@ -79,21 +79,21 @@ namespace Ogre { /** Called when the movable object needs to query a light list. @remarks If you want to customize light finding for this object, you should override - this method and hook into MovableObject via MovableObject::setListener. - Be aware that the default method caches results within a frame to - prevent unnecessary recalculation, so if you override this you - should provide your own caching to maintain performance. - @note - If you use texture shadows, there is an additional restriction - - since the lights which should have shadow textures rendered for - them are determined based on the entire frustum, and not per-object, - it is important that the lights returned at the start of this - list (up to the number of shadow textures available) are the same - lights that were used to generate the shadow textures, - and they are in the same order (particularly for additive effects). - @note - This method will not be called for additive stencil shadows since the - light list cannot be varied per object with this technique. + this method and hook into MovableObject via MovableObject::setListener. + Be aware that the default method caches results within a frame to + prevent unnecessary recalculation, so if you override this you + should provide your own caching to maintain performance. + @note + If you use texture shadows, there is an additional restriction - + since the lights which should have shadow textures rendered for + them are determined based on the entire frustum, and not per-object, + it is important that the lights returned at the start of this + list (up to the number of shadow textures available) are the same + lights that were used to generate the shadow textures, + and they are in the same order (particularly for additive effects). + @note + This method will not be called for additive stencil shadows since the + light list cannot be varied per object with this technique. @return A pointer to a light list if you populated the light list yourself, or NULL to fall back on the default finding process. @@ -102,44 +102,44 @@ namespace Ogre { }; protected: - /// Name of this object - String mName; - /// Creator of this object (if created by a factory) - MovableObjectFactory* mCreator; - /// SceneManager holding this object (if applicable) - SceneManager* mManager; + /// Name of this object + String mName; + /// Creator of this object (if created by a factory) + MovableObjectFactory* mCreator; + /// SceneManager holding this object (if applicable) + SceneManager* mManager; /// node to which this object is attached Node* mParentNode; bool mParentIsTagPoint; /// Is this object visible? bool mVisible; - /// Is debug display enabled? - bool mDebugDisplay; - /// Upper distance to still render - Real mUpperDistance; - Real mSquaredUpperDistance; - // Minimum pixel size to still render - Real mMinPixelSize; - /// Hidden because of distance? - bool mBeyondFarDistance; - /// User objects binding. - UserObjectBindings mUserObjectBindings; + /// Is debug display enabled? + bool mDebugDisplay; + /// Upper distance to still render + Real mUpperDistance; + Real mSquaredUpperDistance; + // Minimum pixel size to still render + Real mMinPixelSize; + /// Hidden because of distance? + bool mBeyondFarDistance; + /// User objects binding. + UserObjectBindings mUserObjectBindings; /// The render queue to use when rendering this object uint8 mRenderQueueID; - /// Flags whether the RenderQueue's default should be used. - bool mRenderQueueIDSet; - /// The render queue group to use when rendering this object - ushort mRenderQueuePriority; - /// Flags whether the RenderQueue's default should be used. - bool mRenderQueuePrioritySet; + /// Flags whether the RenderQueue's default should be used. + bool mRenderQueueIDSet; + /// The render queue group to use when rendering this object + ushort mRenderQueuePriority; + /// Flags whether the RenderQueue's default should be used. + bool mRenderQueuePrioritySet; /// Flags determining whether this object is included / excluded from scene queries uint32 mQueryFlags; /// Flags determining whether this object is visible (compared to SceneManager mask) uint32 mVisibilityFlags; /// Cached world AABB of this object mutable AxisAlignedBox mWorldAABB; - // Cached world bounding sphere - mutable Sphere mWorldBoundingSphere; + // Cached world bounding sphere + mutable Sphere mWorldBoundingSphere; /// World space AABB of this object's dark cap mutable AxisAlignedBox mWorldDarkCapBounds; /// Does this object cast shadows? @@ -155,14 +155,14 @@ namespace Ogre { /// The last frame that this light list was updated in mutable ulong mLightListUpdated; - /// the light mask defined for this movable. This will be taken into consideration when deciding which light should affect this movable - uint32 mLightMask; + /// the light mask defined for this movable. This will be taken into consideration when deciding which light should affect this movable + uint32 mLightMask; - // Static members - /// Default query flags - static uint32 msDefaultQueryFlags; - /// Default visibility flags - static uint32 msDefaultVisibilityFlags; + // Static members + /// Default query flags + static uint32 msDefaultQueryFlags; + /// Default visibility flags + static uint32 msDefaultVisibilityFlags; @@ -170,23 +170,23 @@ namespace Ogre { /// Constructor MovableObject(); - /// Named constructor - MovableObject(const String& name); + /// Named constructor + MovableObject(const String& name); /** Virtual destructor - read Scott Meyers if you don't know why this is needed. */ virtual ~MovableObject(); - /** Notify the object of it's creator (internal use only) */ - virtual void _notifyCreator(MovableObjectFactory* fact) { mCreator = fact; } - /** Get the creator of this object, if any (internal use only) */ - virtual MovableObjectFactory* _getCreator(void) const { return mCreator; } - /** Notify the object of it's manager (internal use only) */ - virtual void _notifyManager(SceneManager* man) { mManager = man; } - /** Get the manager of this object, if any (internal use only) */ - virtual SceneManager* _getManager(void) const { return mManager; } + /** Notify the object of it's creator (internal use only) */ + virtual void _notifyCreator(MovableObjectFactory* fact) { mCreator = fact; } + /** Get the creator of this object, if any (internal use only) */ + virtual MovableObjectFactory* _getCreator(void) const { return mCreator; } + /** Notify the object of it's manager (internal use only) */ + virtual void _notifyManager(SceneManager* man) { mManager = man; } + /** Get the manager of this object, if any (internal use only) */ + virtual SceneManager* _getManager(void) const { return mManager; } /** Returns the name of this object. */ - virtual const String& getName(void) const { return mName; } + virtual const String& getName(void) const { return mName; } /** Returns the type name of this object. */ virtual const String& getMovableType(void) const = 0; @@ -208,8 +208,8 @@ namespace Ogre { */ virtual SceneNode* getParentSceneNode(void) const; - /// Gets whether the parent node is a TagPoint (or a SceneNode) - virtual bool isParentTagPoint() const { return mParentIsTagPoint; } + /// Gets whether the parent node is a TagPoint (or a SceneNode) + virtual bool isParentTagPoint() const { return mParentIsTagPoint; } /** Internal method called to notify the object that it has been attached to a node. */ @@ -218,19 +218,19 @@ namespace Ogre { /** Returns true if this object is attached to a SceneNode or TagPoint. */ virtual bool isAttached(void) const; - /** Detaches an object from a parent SceneNode or TagPoint, if attached. */ - virtual void detachFromParent(void); + /** Detaches an object from a parent SceneNode or TagPoint, if attached. */ + virtual void detachFromParent(void); /** Returns true if this object is attached to a SceneNode or TagPoint, - and this SceneNode / TagPoint is currently in an active part of the - scene graph. */ + and this SceneNode / TagPoint is currently in an active part of the + scene graph. */ virtual bool isInScene(void) const; /** Internal method called to notify the object that it has been moved. */ virtual void _notifyMoved(void); - /** Internal method to notify the object of the camera to be used for the next rendering operation. + /** Internal method to notify the object of the camera to be used for the next rendering operation. @remarks Certain objects may want to do specific processing based on the camera position. This method notifies them in case they wish to do this. @@ -243,14 +243,14 @@ namespace Ogre { */ virtual const AxisAlignedBox& getBoundingBox(void) const = 0; - /** Retrieves the radius of the origin-centered bounding sphere - for this object. - */ - virtual Real getBoundingRadius(void) const = 0; + /** Retrieves the radius of the origin-centered bounding sphere + for this object. + */ + virtual Real getBoundingRadius(void) const = 0; /** Retrieves the axis-aligned bounding box for this object in world coordinates. */ virtual const AxisAlignedBox& getWorldBoundingBox(bool derive = false) const; - /** Retrieves the worldspace bounding sphere for this object. */ + /** Retrieves the worldspace bounding sphere for this object. */ virtual const Sphere& getWorldBoundingSphere(bool derive = false) const; /** Internal method by which the movable object must add Renderable subclass instances to the rendering queue. @remarks @@ -260,19 +260,19 @@ namespace Ogre { virtual void _updateRenderQueue(RenderQueue* queue) = 0; /** Tells this object whether to be visible or not, if it has a renderable component. - @note An alternative approach of making an object invisible is to detach it - from it's SceneNode, or to remove the SceneNode entirely. - Detaching a node means that structurally the scene graph changes. - Once this change has taken place, the objects / nodes that have been - removed have less overhead to the visibility detection pass than simply - making the object invisible, so if you do this and leave the objects - out of the tree for a long time, it's faster. However, the act of - detaching / reattaching nodes is in itself more expensive than - setting an object visibility flag, since in the latter case - structural changes are not made. Therefore, small or frequent visibility - changes are best done using this method; large or more longer term - changes are best done by detaching. - */ + @note An alternative approach of making an object invisible is to detach it + from it's SceneNode, or to remove the SceneNode entirely. + Detaching a node means that structurally the scene graph changes. + Once this change has taken place, the objects / nodes that have been + removed have less overhead to the visibility detection pass than simply + making the object invisible, so if you do this and leave the objects + out of the tree for a long time, it's faster. However, the act of + detaching / reattaching nodes is in itself more expensive than + setting an object visibility flag, since in the latter case + structural changes are not made. Therefore, small or frequent visibility + changes are best done using this method; large or more longer term + changes are best done by detaching. + */ virtual void setVisible(bool visible); /** Gets this object whether to be visible or not, if it has a renderable component. @@ -282,64 +282,64 @@ namespace Ogre { virtual bool getVisible(void) const; /** Returns whether or not this object is supposed to be visible or not. - @remarks - Takes into account both upper rendering distance and visible flag. - */ + @remarks + Takes into account both upper rendering distance and visible flag. + */ virtual bool isVisible(void) const; - /** Sets the distance at which the object is no longer rendered. - @note Camera::setUseRenderingDistance() needs to be called for this parameter to be used. - @param dist Distance beyond which the object will not be rendered - (the default is 0, which means objects are always rendered). - */ - virtual void setRenderingDistance(Real dist) { - mUpperDistance = dist; - mSquaredUpperDistance = mUpperDistance * mUpperDistance; - } - - /** Gets the distance at which batches are no longer rendered. */ - virtual Real getRenderingDistance(void) const { return mUpperDistance; } - - /** Sets the minimum pixel size an object needs to be in both screen axes in order to be rendered - @note Camera::setUseMinPixelSize() needs to be called for this parameter to be used. - @param pixelSize Number of minimum pixels - (the default is 0, which means objects are always rendered). - */ - virtual void setRenderingMinPixelSize(Real pixelSize) { - mMinPixelSize = pixelSize; - } - - /** Returns the minimum pixel size an object needs to be in both screen axes in order to be rendered - */ - virtual Real getRenderingMinPixelSize() const { - return mMinPixelSize; - } - - /** @deprecated use UserObjectBindings::setUserAny via getUserObjectBindings() instead. - Sets any kind of user value on this object. - @remarks - This method allows you to associate any user value you like with - this MovableObject. This can be a pointer back to one of your own - classes for instance. - */ - OGRE_DEPRECATED virtual void setUserAny(const Any& anything) { getUserObjectBindings().setUserAny(anything); } - - /** @deprecated use UserObjectBindings::getUserAny via getUserObjectBindings() instead. - Retrieves the custom user value associated with this object. - */ - OGRE_DEPRECATED virtual const Any& getUserAny(void) const { return getUserObjectBindings().getUserAny(); } - - /** Return an instance of user objects binding associated with this class. - You can use it to associate one or more custom objects with this class instance. - @see UserObjectBindings::setUserAny. - */ - UserObjectBindings& getUserObjectBindings() { return mUserObjectBindings; } - - /** Return an instance of user objects binding associated with this class. - You can use it to associate one or more custom objects with this class instance. - @see UserObjectBindings::setUserAny. - */ - const UserObjectBindings& getUserObjectBindings() const { return mUserObjectBindings; } + /** Sets the distance at which the object is no longer rendered. + @note Camera::setUseRenderingDistance() needs to be called for this parameter to be used. + @param dist Distance beyond which the object will not be rendered + (the default is 0, which means objects are always rendered). + */ + virtual void setRenderingDistance(Real dist) { + mUpperDistance = dist; + mSquaredUpperDistance = mUpperDistance * mUpperDistance; + } + + /** Gets the distance at which batches are no longer rendered. */ + virtual Real getRenderingDistance(void) const { return mUpperDistance; } + + /** Sets the minimum pixel size an object needs to be in both screen axes in order to be rendered + @note Camera::setUseMinPixelSize() needs to be called for this parameter to be used. + @param pixelSize Number of minimum pixels + (the default is 0, which means objects are always rendered). + */ + virtual void setRenderingMinPixelSize(Real pixelSize) { + mMinPixelSize = pixelSize; + } + + /** Returns the minimum pixel size an object needs to be in both screen axes in order to be rendered + */ + virtual Real getRenderingMinPixelSize() const { + return mMinPixelSize; + } + + /** @deprecated use UserObjectBindings::setUserAny via getUserObjectBindings() instead. + Sets any kind of user value on this object. + @remarks + This method allows you to associate any user value you like with + this MovableObject. This can be a pointer back to one of your own + classes for instance. + */ + OGRE_DEPRECATED virtual void setUserAny(const Any& anything) { getUserObjectBindings().setUserAny(anything); } + + /** @deprecated use UserObjectBindings::getUserAny via getUserObjectBindings() instead. + Retrieves the custom user value associated with this object. + */ + OGRE_DEPRECATED virtual const Any& getUserAny(void) const { return getUserObjectBindings().getUserAny(); } + + /** Return an instance of user objects binding associated with this class. + You can use it to associate one or more custom objects with this class instance. + @see UserObjectBindings::setUserAny. + */ + UserObjectBindings& getUserObjectBindings() { return mUserObjectBindings; } + + /** Return an instance of user objects binding associated with this class. + You can use it to associate one or more custom objects with this class instance. + @see UserObjectBindings::setUserAny. + */ + const UserObjectBindings& getUserObjectBindings() const { return mUserObjectBindings; } /** Sets the render queue group this entity will be rendered through. @remarks @@ -351,32 +351,32 @@ namespace Ogre { @par See RenderQueue for more details. @param queueID Enumerated value of the queue group to use. See the - enum RenderQueueGroupID for what kind of values can be used here. + enum RenderQueueGroupID for what kind of values can be used here. */ virtual void setRenderQueueGroup(uint8 queueID); - /** Sets the render queue group and group priority this entity will be rendered through. - @remarks - Render queues are grouped to allow you to more tightly control the ordering - of rendered objects. Within a single render group there another type of grouping - called priority which allows further control. If you do not call this method, - all Entity objects default to the default queue and priority - (RenderQueue::getDefaultQueueGroup, RenderQueue::getDefaultRenderablePriority), - which is fine for most objects. You may want to alter this if you want this entity - to always appear in front of other objects, e.g. for a 3D menu system or such. - @par - See RenderQueue for more details. - @param queueID Enumerated value of the queue group to use. See the - enum RenderQueueGroupID for what kind of values can be used here. - @param priority The priority within a group to use. - */ - virtual void setRenderQueueGroupAndPriority(uint8 queueID, ushort priority); + /** Sets the render queue group and group priority this entity will be rendered through. + @remarks + Render queues are grouped to allow you to more tightly control the ordering + of rendered objects. Within a single render group there another type of grouping + called priority which allows further control. If you do not call this method, + all Entity objects default to the default queue and priority + (RenderQueue::getDefaultQueueGroup, RenderQueue::getDefaultRenderablePriority), + which is fine for most objects. You may want to alter this if you want this entity + to always appear in front of other objects, e.g. for a 3D menu system or such. + @par + See RenderQueue for more details. + @param queueID Enumerated value of the queue group to use. See the + enum RenderQueueGroupID for what kind of values can be used here. + @param priority The priority within a group to use. + */ + virtual void setRenderQueueGroupAndPriority(uint8 queueID, ushort priority); /** Gets the queue group for this entity, see setRenderQueueGroup for full details. */ virtual uint8 getRenderQueueGroup(void) const; - /// Return the full transformation of the parent sceneNode or the attachingPoint node - virtual const Matrix4& _getParentNodeFullTransform(void) const; + /// Return the full transformation of the parent sceneNode or the attachingPoint node + virtual const Matrix4& _getParentNodeFullTransform(void) const; /** Sets the query flags for this object. @remarks @@ -398,20 +398,20 @@ namespace Ogre { /// Returns the query flags relevant for this object virtual uint32 getQueryFlags(void) const { return mQueryFlags; } - /** Set the default query flags for all future MovableObject instances. - */ - static void setDefaultQueryFlags(uint32 flags) { msDefaultQueryFlags = flags; } + /** Set the default query flags for all future MovableObject instances. + */ + static void setDefaultQueryFlags(uint32 flags) { msDefaultQueryFlags = flags; } - /** Get the default query flags for all future MovableObject instances. - */ - static uint32 getDefaultQueryFlags() { return msDefaultQueryFlags; } + /** Get the default query flags for all future MovableObject instances. + */ + static uint32 getDefaultQueryFlags() { return msDefaultQueryFlags; } - + /** Sets the visibility flags for this object. @remarks - As well as a simple true/false value for visibility (as seen in setVisible), - you can also set visibility flags which when 'and'ed with the SceneManager's - visibility mask can also make an object invisible. + As well as a simple true/false value for visibility (as seen in setVisible), + you can also set visibility flags which when 'and'ed with the SceneManager's + visibility mask can also make an object invisible. */ virtual void setVisibilityFlags(uint32 flags) { mVisibilityFlags = flags; } @@ -426,13 +426,13 @@ namespace Ogre { /// Returns the visibility flags relevant for this object virtual uint32 getVisibilityFlags(void) const { return mVisibilityFlags; } - /** Set the default visibility flags for all future MovableObject instances. - */ - static void setDefaultVisibilityFlags(uint32 flags) { msDefaultVisibilityFlags = flags; } - - /** Get the default visibility flags for all future MovableObject instances. - */ - static uint32 getDefaultVisibilityFlags() { return msDefaultVisibilityFlags; } + /** Set the default visibility flags for all future MovableObject instances. + */ + static void setDefaultVisibilityFlags(uint32 flags) { msDefaultVisibilityFlags = flags; } + + /** Get the default visibility flags for all future MovableObject instances. + */ + static uint32 getDefaultVisibilityFlags() { return msDefaultVisibilityFlags; } /** Sets a listener for this object. @remarks @@ -454,10 +454,10 @@ namespace Ogre { an empty list. @par The object internally caches the light list, so it will recalculate - it only when object is moved, or lights that affect the frustum have - been changed (@see SceneManager::_getLightsDirtyCounter), + it only when object is moved, or lights that affect the frustum have + been changed (@see SceneManager::_getLightsDirtyCounter), but if listener exists, it will be called each time, so the listener - should implement their own cache mechanism to optimise performance. + should implement their own cache mechanism to optimise performance. @par This method can be useful when implementing Renderable::getLights in case the renderable is a part of the movable. @@ -465,37 +465,37 @@ namespace Ogre { */ virtual const LightList& queryLights(void) const; - /** Get a bitwise mask which will filter the lights affecting this object - @remarks - By default, this mask is fully set meaning all lights will affect this object - */ - virtual uint32 getLightMask()const { return mLightMask; } - /** Set a bitwise mask which will filter the lights affecting this object - @remarks - This mask will be compared against the mask held against Light to determine - if a light should affect a given object. - By default, this mask is fully set meaning all lights will affect this object - */ - virtual void setLightMask(uint32 lightMask); - - /** Returns a pointer to the current list of lights for this object. - @remarks - You should not modify this list outside of MovableObject::Listener::objectQueryLights - (say if you want to use it to implement this method, and use the pointer - as a return value) and for reading it's only accurate as at the last frame. - */ - virtual LightList* _getLightList() { return &mLightList; } - - /// Returns details of the edges which might be used to determine a silhouette + /** Get a bitwise mask which will filter the lights affecting this object + @remarks + By default, this mask is fully set meaning all lights will affect this object + */ + virtual uint32 getLightMask()const { return mLightMask; } + /** Set a bitwise mask which will filter the lights affecting this object + @remarks + This mask will be compared against the mask held against Light to determine + if a light should affect a given object. + By default, this mask is fully set meaning all lights will affect this object + */ + virtual void setLightMask(uint32 lightMask); + + /** Returns a pointer to the current list of lights for this object. + @remarks + You should not modify this list outside of MovableObject::Listener::objectQueryLights + (say if you want to use it to implement this method, and use the pointer + as a return value) and for reading it's only accurate as at the last frame. + */ + virtual LightList* _getLightList() { return &mLightList; } + + /// Returns details of the edges which might be used to determine a silhouette EdgeData* getEdgeList(void) { return NULL; } - /// Returns whether the object has a valid edge list. - bool hasEdgeList(void) { return false; } + /// Returns whether the object has a valid edge list. + bool hasEdgeList(void) { return false; } /// Define a default implementation of method from ShadowCaster which implements no shadows ShadowRenderableListIterator getShadowVolumeRenderableIterator( ShadowTechnique shadowTechnique, const Light* light, HardwareIndexBufferSharedPtr* indexBuffer, size_t* indexBufferUsedSize, bool extrudeVertices, Real extrusionDist, unsigned long flags = 0); - + /** Overridden member from ShadowCaster. */ const AxisAlignedBox& getLightCapBounds(void) const; /** Overridden member from ShadowCaster. */ @@ -515,50 +515,50 @@ namespace Ogre { void setCastShadows(bool enabled) { mCastShadows = enabled; } /** Returns whether shadow casting is enabled for this object. */ bool getCastShadows(void) const { return mCastShadows; } - /** Returns whether the Material of any Renderable that this MovableObject will add to - the render queue will receive shadows. - */ - bool getReceivesShadows(); - + /** Returns whether the Material of any Renderable that this MovableObject will add to + the render queue will receive shadows. + */ + bool getReceivesShadows(); + /** Get the distance to extrude for a point/spot light */ Real getPointExtrusionDistance(const Light* l) const; - /** Get the 'type flags' for this MovableObject. - @remarks - A type flag identifies the type of the MovableObject as a bitpattern. - This is used for categorical inclusion / exclusion in SceneQuery - objects. By default, this method returns all ones for objects not - created by a MovableObjectFactory (hence always including them); - otherwise it returns the value assigned to the MovableObjectFactory. - Custom objects which don't use MovableObjectFactory will need to - override this if they want to be included in queries. - */ - virtual uint32 getTypeFlags(void) const; - - /** Method to allow a caller to abstractly iterate over the Renderable - instances that this MovableObject will add to the render queue when - asked, if any. - @param visitor Pointer to a class implementing the Renderable::Visitor - interface which will be called back for each Renderable which will - be queued. Bear in mind that the state of the Renderable instances - may not be finalised depending on when you call this. - @param debugRenderables If false, only regular renderables will be visited - (those for normal display). If true, debug renderables will be - included too. - */ - virtual void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false) = 0; - - /** Sets whether or not the debug display of this object is enabled. - @remarks - Some objects aren't visible themselves but it can be useful to display - a debug representation of them. Or, objects may have an additional - debug display on top of their regular display. This option enables / - disables that debug display. Objects that are not visible never display - debug geometry regardless of this setting. - */ - virtual void setDebugDisplayEnabled(bool enabled) { mDebugDisplay = enabled; } - /// Gets whether debug display of this object is enabled. - virtual bool isDebugDisplayEnabled(void) const { return mDebugDisplay; } + /** Get the 'type flags' for this MovableObject. + @remarks + A type flag identifies the type of the MovableObject as a bitpattern. + This is used for categorical inclusion / exclusion in SceneQuery + objects. By default, this method returns all ones for objects not + created by a MovableObjectFactory (hence always including them); + otherwise it returns the value assigned to the MovableObjectFactory. + Custom objects which don't use MovableObjectFactory will need to + override this if they want to be included in queries. + */ + virtual uint32 getTypeFlags(void) const; + + /** Method to allow a caller to abstractly iterate over the Renderable + instances that this MovableObject will add to the render queue when + asked, if any. + @param visitor Pointer to a class implementing the Renderable::Visitor + interface which will be called back for each Renderable which will + be queued. Bear in mind that the state of the Renderable instances + may not be finalised depending on when you call this. + @param debugRenderables If false, only regular renderables will be visited + (those for normal display). If true, debug renderables will be + included too. + */ + virtual void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false) = 0; + + /** Sets whether or not the debug display of this object is enabled. + @remarks + Some objects aren't visible themselves but it can be useful to display + a debug representation of them. Or, objects may have an additional + debug display on top of their regular display. This option enables / + disables that debug display. Objects that are not visible never display + debug geometry regardless of this setting. + */ + virtual void setDebugDisplayEnabled(bool enabled) { mDebugDisplay = enabled; } + /// Gets whether debug display of this object is enabled. + virtual bool isDebugDisplayEnabled(void) const { return mDebugDisplay; } @@ -566,73 +566,73 @@ namespace Ogre { }; - /** Interface definition for a factory class which produces a certain - kind of MovableObject, and can be registered with Root in order - to allow all clients to produce new instances of this object, integrated - with the standard Ogre processing. - */ - class _OgreExport MovableObjectFactory : public MovableAlloc - { - protected: - /// Type flag, allocated if requested - uint32 mTypeFlag; - - /// Internal implementation of create method - must be overridden - virtual MovableObject* createInstanceImpl( - const String& name, const NameValuePairList* params = 0) = 0; - public: - MovableObjectFactory() : mTypeFlag(0xFFFFFFFF) {} - virtual ~MovableObjectFactory() {} - /// Get the type of the object to be created - virtual const String& getType(void) const = 0; - - /** Create a new instance of the object. - @param name The name of the new object - @param manager The SceneManager instance that will be holding the - instance once created. - @param params Name/value pair list of additional parameters required to - construct the object (defined per subtype). Optional. - */ - virtual MovableObject* createInstance( - const String& name, SceneManager* manager, - const NameValuePairList* params = 0); - /** Destroy an instance of the object */ - virtual void destroyInstance(MovableObject* obj) = 0; - - /** Does this factory require the allocation of a 'type flag', used to - selectively include / exclude this type from scene queries? - @remarks - The default implementation here is to return 'false', ie not to - request a unique type mask from Root. For objects that - never need to be excluded in SceneQuery results, that's fine, since - the default implementation of MovableObject::getTypeFlags is to return - all ones, hence matching any query type mask. However, if you want the - objects created by this factory to be filterable by queries using a - broad type, you have to give them a (preferably unique) type mask - - and given that you don't know what other MovableObject types are - registered, Root will allocate you one. - */ - virtual bool requestTypeFlags(void) const { return false; } - /** Notify this factory of the type mask to apply. - @remarks - This should normally only be called by Root in response to - a 'true' result from requestTypeMask. However, you can actually use - it yourself if you're careful; for example to assign the same mask - to a number of different types of object, should you always wish them - to be treated the same in queries. - */ - void _notifyTypeFlags(uint32 flag) { mTypeFlag = flag; } - - /** Gets the type flag for this factory. - @remarks - A type flag is like a query flag, except that it applies to all instances - of a certain type of object. - */ - uint32 getTypeFlags(void) const { return mTypeFlag; } - - }; - /** @} */ - /** @} */ + /** Interface definition for a factory class which produces a certain + kind of MovableObject, and can be registered with Root in order + to allow all clients to produce new instances of this object, integrated + with the standard Ogre processing. + */ + class _OgreExport MovableObjectFactory : public MovableAlloc + { + protected: + /// Type flag, allocated if requested + uint32 mTypeFlag; + + /// Internal implementation of create method - must be overridden + virtual MovableObject* createInstanceImpl( + const String& name, const NameValuePairList* params = 0) = 0; + public: + MovableObjectFactory() : mTypeFlag(0xFFFFFFFF) {} + virtual ~MovableObjectFactory() {} + /// Get the type of the object to be created + virtual const String& getType(void) const = 0; + + /** Create a new instance of the object. + @param name The name of the new object + @param manager The SceneManager instance that will be holding the + instance once created. + @param params Name/value pair list of additional parameters required to + construct the object (defined per subtype). Optional. + */ + virtual MovableObject* createInstance( + const String& name, SceneManager* manager, + const NameValuePairList* params = 0); + /** Destroy an instance of the object */ + virtual void destroyInstance(MovableObject* obj) = 0; + + /** Does this factory require the allocation of a 'type flag', used to + selectively include / exclude this type from scene queries? + @remarks + The default implementation here is to return 'false', ie not to + request a unique type mask from Root. For objects that + never need to be excluded in SceneQuery results, that's fine, since + the default implementation of MovableObject::getTypeFlags is to return + all ones, hence matching any query type mask. However, if you want the + objects created by this factory to be filterable by queries using a + broad type, you have to give them a (preferably unique) type mask - + and given that you don't know what other MovableObject types are + registered, Root will allocate you one. + */ + virtual bool requestTypeFlags(void) const { return false; } + /** Notify this factory of the type mask to apply. + @remarks + This should normally only be called by Root in response to + a 'true' result from requestTypeMask. However, you can actually use + it yourself if you're careful; for example to assign the same mask + to a number of different types of object, should you always wish them + to be treated the same in queries. + */ + void _notifyTypeFlags(uint32 flag) { mTypeFlag = flag; } + + /** Gets the type flag for this factory. + @remarks + A type flag is like a query flag, except that it applies to all instances + of a certain type of object. + */ + uint32 getTypeFlags(void) const { return mTypeFlag; } + + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreMovablePlane.h b/OgreMain/include/OgreMovablePlane.h index ebc4f243f04..baa764eddd8 100644 --- a/OgreMain/include/OgreMovablePlane.h +++ b/OgreMain/include/OgreMovablePlane.h @@ -37,13 +37,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Definition of a Plane that may be attached to a node, and the derived + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Definition of a Plane that may be attached to a node, and the derived details of it retrieved simply. @remarks This plane is not here for rendering purposes, it's to allow you to attach @@ -82,9 +82,9 @@ namespace Ogre { const String& getMovableType(void) const; /// Get the derived plane as transformed by its parent node. const Plane& _getDerivedPlane(void) const; - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false) + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false) { /* do nothing */ (void)visitor; @@ -92,8 +92,8 @@ namespace Ogre { } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreNode.h b/OgreMain/include/OgreNode.h index 9efbc9b5b30..eaa0edafeea 100644 --- a/OgreMain/include/OgreNode.h +++ b/OgreMain/include/OgreNode.h @@ -757,7 +757,7 @@ namespace Ogre { You can use it to associate one or more custom objects with this class instance. @see UserObjectBindings::setUserAny. */ - UserObjectBindings& getUserObjectBindings() { return mUserObjectBindings; } + UserObjectBindings& getUserObjectBindings() { return mUserObjectBindings; } /** Return an instance of user objects binding associated with this class. You can use it to associate one or more custom objects with this class instance. diff --git a/OgreMain/include/OgreNumerics.h b/OgreMain/include/OgreNumerics.h index 85fdb956eba..0da55603a12 100644 --- a/OgreMain/include/OgreNumerics.h +++ b/OgreMain/include/OgreNumerics.h @@ -34,32 +34,32 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Real type for numeric solvers */ - typedef double PreciseReal; + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Real type for numeric solvers */ + typedef double PreciseReal; /** Provides numeric solvers for Ogre @remarks Handles linear algebra numerics. */ - class _OgreExport NumericSolver - { - public: - /** Solves a full rank NxN linear system of equations - @remarks - This implements a naive Gaussian elimination algorithm. - The algorithm is destructive, so there are side effects in coeff and col. - */ - static bool solveNxNLinearSysDestr(int n, PreciseReal **coeff, PreciseReal *col); - }; - /** @} */ - /** @} */ + class _OgreExport NumericSolver + { + public: + /** Solves a full rank NxN linear system of equations + @remarks + This implements a naive Gaussian elimination algorithm. + The algorithm is destructive, so there are side effects in coeff and col. + */ + static bool solveNxNLinearSysDestr(int n, PreciseReal **coeff, PreciseReal *col); + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreOptimisedUtil.h b/OgreMain/include/OgreOptimisedUtil.h index 190ac05d7d9..ce340f3d85d 100644 --- a/OgreMain/include/OgreOptimisedUtil.h +++ b/OgreMain/include/OgreOptimisedUtil.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Utility class for provides optimised functions. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Utility class for provides optimised functions. @note This class are supposed used by internal engine only. */ @@ -116,7 +116,7 @@ namespace Ogre { @param srcPos1 Pointer to buffer for the start positions @param srcPos2 Pointer to buffer for the end positions @param dstPos Pointer to buffer for the destination positions - @param pos1VSize, pos2VSize, dstVSize Vertex sizes in bytes of each of the 3 buffers referenced + @param pos1VSize, pos2VSize, dstVSize Vertex sizes in bytes of each of the 3 buffers referenced @param numVertices Number of vertices to morph, which agree with the number in start, end and destination buffer. Bear in mind three floating-point values per vertex @@ -125,9 +125,9 @@ namespace Ogre { Real t, const float *srcPos1, const float *srcPos2, float *dstPos, - size_t pos1VSize, size_t pos2VSize, size_t dstVSize, + size_t pos1VSize, size_t pos2VSize, size_t dstVSize, size_t numVertices, - bool morphNormals) = 0; + bool morphNormals) = 0; /** Concatenate an affine matrix to an array of affine matrices. @note @@ -236,8 +236,8 @@ namespace Ogre { { ptr = rawOffsetPointer(ptr, offset); } - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePVRTCCodec.h b/OgreMain/include/OgrePVRTCCodec.h index b7ba6eb457f..62cd73faa80 100644 --- a/OgreMain/include/OgrePVRTCCodec.h +++ b/OgreMain/include/OgrePVRTCCodec.h @@ -31,30 +31,30 @@ THE SOFTWARE. #include "OgreImageCodec.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Image - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Image + * @{ + */ /** Codec specialized in loading PVRTC (PowerVR) images. - @remarks - We implement our own codec here since we need to be able to keep PVRTC - data compressed if the card supports it. + @remarks + We implement our own codec here since we need to be able to keep PVRTC + data compressed if the card supports it. */ class _OgreExport PVRTCCodec : public ImageCodec { protected: String mType; - void flipEndian(void * pData, size_t size, size_t count) const; - void flipEndian(void * pData, size_t size) const; + void flipEndian(void * pData, size_t size, size_t count) const; + void flipEndian(void * pData, size_t size) const; - /// Single registered codec instance - static PVRTCCodec* msInstance; + /// Single registered codec instance + static PVRTCCodec* msInstance; - public: + public: PVRTCCodec(); virtual ~PVRTCCodec() { } @@ -64,25 +64,25 @@ namespace Ogre { void encodeToFile(MemoryDataStreamPtr& input, const String& outFileName, CodecDataPtr& pData) const; /// @copydoc Codec::decode DecodeResult decode(DataStreamPtr& input) const; - /// @copydoc Codec::magicNumberToFileExt - String magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const; + /// @copydoc Codec::magicNumberToFileExt + String magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const; virtual String getType() const; - /// Static method to startup and register the PVRTC codec - static void startup(void); - /// Static method to shutdown and unregister the PVRTC codec - static void shutdown(void); + /// Static method to startup and register the PVRTC codec + static void startup(void); + /// Static method to shutdown and unregister the PVRTC codec + static void shutdown(void); - private: - /// Decode PVRTCV2 image format - DecodeResult decodeV2(DataStreamPtr& stream) const; + private: + /// Decode PVRTCV2 image format + DecodeResult decodeV2(DataStreamPtr& stream) const; - /// Decode PVRTCV3 image format - DecodeResult decodeV3(DataStreamPtr& stream) const; + /// Decode PVRTCV3 image format + DecodeResult decodeV3(DataStreamPtr& stream) const; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreParticle.h b/OgreMain/include/OgreParticle.h index ada7dfb47be..06d0e9b7f3b 100644 --- a/OgreMain/include/OgreParticle.h +++ b/OgreMain/include/OgreParticle.h @@ -33,31 +33,31 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Abstract class containing any additional data required to be associated - with a particle to perform the required rendering. - @remarks - Because you can specialise the way that particles are rendered by supplying - custom ParticleSystemRenderer classes, you might well need some additional - data for your custom rendering routine which is not held on the default particle - class. If that's the case, then you should define a subclass of this class, - and construct it when asked in your custom ParticleSystemRenderer class. - */ - class _OgreExport ParticleVisualData : public FXAlloc - { - public: - ParticleVisualData() {} - virtual ~ParticleVisualData() {} - - }; - - /** Class representing a single particle instance. */ - class _OgreExport Particle : public FXAlloc + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Abstract class containing any additional data required to be associated + with a particle to perform the required rendering. + @remarks + Because you can specialise the way that particles are rendered by supplying + custom ParticleSystemRenderer classes, you might well need some additional + data for your custom rendering routine which is not held on the default particle + class. If that's the case, then you should define a subclass of this class, + and construct it when asked in your custom ParticleSystemRenderer class. + */ + class _OgreExport ParticleVisualData : public FXAlloc + { + public: + ParticleVisualData() {} + virtual ~ParticleVisualData() {} + + }; + + /** Class representing a single particle instance. */ + class _OgreExport Particle : public FXAlloc { protected: /// Parent ParticleSystem @@ -138,16 +138,16 @@ namespace Ogre { /** Internal method for notifying the particle of it's optional visual data. */ - void _notifyVisualData(ParticleVisualData* vis) { mVisual = vis; } + void _notifyVisualData(ParticleVisualData* vis) { mVisual = vis; } - /// Get the optional visual data associated with the class - ParticleVisualData* getVisualData(void) const { return mVisual; } + /// Get the optional visual data associated with the class + ParticleVisualData* getVisualData(void) const { return mVisual; } /// Utility method to reset this particle void resetDimensions(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreParticleAffector.h b/OgreMain/include/OgreParticleAffector.h index 6bcd9752b04..acc74408529 100644 --- a/OgreMain/include/OgreParticleAffector.h +++ b/OgreMain/include/OgreParticleAffector.h @@ -36,12 +36,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ /** Abstract class defining the interface to be implemented by particle affectors. @remarks Particle affectors modify particles in a particle system over their lifetime. They can be @@ -92,7 +92,7 @@ namespace Ogre { @param pParticle Pointer to a Particle to initialize. */ - virtual void _initParticle(Particle* pParticle) + virtual void _initParticle(Particle* pParticle) { /* by default do nothing */ (void)pParticle; @@ -118,8 +118,8 @@ namespace Ogre { const String &getType(void) const { return mType; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreParticleAffectorFactory.h b/OgreMain/include/OgreParticleAffectorFactory.h index 01db762eb1e..77228b5c4ec 100644 --- a/OgreMain/include/OgreParticleAffectorFactory.h +++ b/OgreMain/include/OgreParticleAffectorFactory.h @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Abstract class defining the interface to be implemented by creators of ParticleAffector subclasses. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Abstract class defining the interface to be implemented by creators of ParticleAffector subclasses. @remarks Plugins or 3rd party applications can add new types of particle affectors to Ogre by creating subclasses of the ParticleAffector class. Because multiple instances of these affectors may be @@ -52,7 +52,7 @@ namespace Ogre { a name which identifies them, examples might be 'force_vector', 'attractor', or 'fader', and these can be also be used from particle system scripts. */ - class _OgreExport ParticleAffectorFactory : public FXAlloc + class _OgreExport ParticleAffectorFactory : public FXAlloc { protected: vector::type mAffectors; @@ -72,8 +72,8 @@ namespace Ogre { virtual void destroyAffector(ParticleAffector* e); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreParticleEmitter.h b/OgreMain/include/OgreParticleEmitter.h index 5b5fa8aafad..f2b72d1b512 100644 --- a/OgreMain/include/OgreParticleEmitter.h +++ b/OgreMain/include/OgreParticleEmitter.h @@ -40,13 +40,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Abstract class defining the interface to be implemented by particle emitters. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Abstract class defining the interface to be implemented by particle emitters. @remarks Particle emitters are the sources of particles in a particle system. This class defines the ParticleEmitter interface, and provides a basic implementation @@ -79,7 +79,7 @@ namespace Ogre { static EmitterCommands::CmdColourRangeEnd msColourRangeEndCmd; static EmitterCommands::CmdDirection msDirectionCmd; static EmitterCommands::CmdUp msUpCmd; - static EmitterCommands::CmdDirPositionRef msDirPositionRefCmd; + static EmitterCommands::CmdDirPositionRef msDirPositionRefCmd; static EmitterCommands::CmdEmissionRate msEmissionRateCmd; static EmitterCommands::CmdMaxTTL msMaxTTLCmd; static EmitterCommands::CmdMaxVelocity msMaxVelocityCmd; @@ -94,8 +94,8 @@ namespace Ogre { static EmitterCommands::CmdRepeatDelay msRepeatDelayCmd; static EmitterCommands::CmdMinRepeatDelay msMinRepeatDelayCmd; static EmitterCommands::CmdMaxRepeatDelay msMaxRepeatDelayCmd; - static EmitterCommands::CmdName msNameCmd; - static EmitterCommands::CmdEmittedEmitter msEmittedEmitterCmd; + static EmitterCommands::CmdName msNameCmd; + static EmitterCommands::CmdEmittedEmitter msEmittedEmitterCmd; /// Parent particle system @@ -110,9 +110,9 @@ namespace Ogre { Vector3 mDirection; /// Notional up vector, used to speed up generation of variant directions, and also to orient some emitters. Vector3 mUp; - /// When true, mDirPositionRef is used instead of mDirection to generate particles - bool mUseDirPositionRef; - /* Center position to tell in which direction will particles be emitted according to their position, + /// When true, mDirPositionRef is used instead of mDirection to generate particles + bool mUseDirPositionRef; + /* Center position to tell in which direction will particles be emitted according to their position, useful for explosions & implosions, some emitters (i.e. point emitter) may not need it. */ Vector3 mDirPositionRef; /// Angle around direction which particles may be emitted, internally radians but angleunits for interface @@ -148,20 +148,20 @@ namespace Ogre { /// Repeat delay left Real mRepeatDelayRemain; - // Fractions of particles wanted to be emitted last time - Real mRemainder; + // Fractions of particles wanted to be emitted last time + Real mRemainder; /// The name of the emitter. The name is optional unless it is used as an emitter that is emitted itself. String mName; - /// The name of the emitter to be emitted (optional) + /// The name of the emitter to be emitted (optional) String mEmittedEmitter; - // If 'true', this emitter is emitted by another emitter. - // NB. That doesn't imply that the emitter itself emits other emitters (that could or could not be the case) - bool mEmitted; + // If 'true', this emitter is emitted by another emitter. + // NB. That doesn't imply that the emitter itself emits other emitters (that could or could not be the case) + bool mEmitted; - // NB Method below here are to help out people implementing emitters by providing the + // NB Method below here are to help out people implementing emitters by providing the // most commonly used approaches as piecemeal methods /** Internal utility method for generating particle exit direction @@ -203,7 +203,7 @@ namespace Ogre { /** Virtual destructor essential. */ virtual ~ParticleEmitter(); - /** Sets the position of this emitter relative to the particle system center. */ + /** Sets the position of this emitter relative to the particle system center. */ virtual void setPosition(const Vector3& pos); /** Returns the position of this emitter relative to the center of the particle system. */ @@ -216,7 +216,7 @@ namespace Ogre { vector for every particle, many will introduce a random scatter around this vector using the angle property. @note - This resets the up vector. + This resets the up vector. @param direction The base direction for particles emitted. */ @@ -227,9 +227,9 @@ namespace Ogre { /** Sets the notional up vector of the emitter @remarks - Many emitters emit particles from within a region, and for some that region is not - circularly symmetric about the emitter direction. The up vector allows such emitters - to be orientated about the direction vector. + Many emitters emit particles from within a region, and for some that region is not + circularly symmetric about the emitter direction. The up vector allows such emitters + to be orientated about the direction vector. @param up The base direction for particles emitted. It must be perpendicular to the direction vector. */ @@ -238,26 +238,26 @@ namespace Ogre { /** Returns the up vector of the emitter. */ virtual const Vector3& getUp(void) const; - /** Sets the direction of the emitter. - Some particle effects need to emit particles in many random directions, but still - following some rules; like not having them collide against each other. Very useful - for explosions and implosions (when velocity is negative) - @note - Although once enabled mDirPositionRef will supersede mDirection; calling setDirection() - may still be needed to setup a custom up vector. - @param position + /** Sets the direction of the emitter. + Some particle effects need to emit particles in many random directions, but still + following some rules; like not having them collide against each other. Very useful + for explosions and implosions (when velocity is negative) + @note + Although once enabled mDirPositionRef will supersede mDirection; calling setDirection() + may still be needed to setup a custom up vector. + @param position The reference position in which the direction of the particles will be calculated from, - also taking into account the particle's position at the time of emission. - @param enable + also taking into account the particle's position at the time of emission. + @param enable True to use mDirPositionRef, false to use the default behaviour with mDirection - */ - virtual void setDirPositionReference( const Vector3& position, bool enable ); + */ + virtual void setDirPositionReference( const Vector3& position, bool enable ); - /** Returns the position reference to generate direction of emitted particles */ - virtual const Vector3& getDirPositionReference() const; + /** Returns the position reference to generate direction of emitted particles */ + virtual const Vector3& getDirPositionReference() const; - /** Returns whether direction or position reference is used */ - virtual bool getDirPositionReferenceEnabled() const; + /** Returns whether direction or position reference is used */ + virtual bool getDirPositionReferenceEnabled() const; /** Sets the maximum angle away from the emitter direction which particle will be emitted. @remarks @@ -521,28 +521,28 @@ namespace Ogre { /** Gets the maximum duration of this emitter in seconds (see setRepeatDelay for more details) */ virtual Real getMaxRepeatDelay(void) const; - /** Returns the name of the emitter */ - const String &getName(void) const; + /** Returns the name of the emitter */ + const String &getName(void) const; - /** Sets the name of the emitter */ - virtual void setName(const String& newName); + /** Sets the name of the emitter */ + virtual void setName(const String& newName); - /** Returns the name of the emitter to be emitted */ - const String &getEmittedEmitter(void) const; + /** Returns the name of the emitter to be emitted */ + const String &getEmittedEmitter(void) const; - /** Sets the name of the emitter to be emitted*/ - virtual void setEmittedEmitter(const String& emittedEmitter); + /** Sets the name of the emitter to be emitted*/ + virtual void setEmittedEmitter(const String& emittedEmitter); - /** Return true if the emitter is emitted by another emitter */ - virtual bool isEmitted(void) const; + /** Return true if the emitter is emitted by another emitter */ + virtual bool isEmitted(void) const; - /** Set the indication (true/false) to indicate that the emitter is emitted by another emitter */ - virtual void setEmitted(bool emitted); + /** Set the indication (true/false) to indicate that the emitter is emitted by another emitter */ + virtual void setEmitted(bool emitted); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreParticleEmitterCommands.h b/OgreMain/include/OgreParticleEmitterCommands.h index cc0ce401101..dcd51eadc1e 100644 --- a/OgreMain/include/OgreParticleEmitterCommands.h +++ b/OgreMain/include/OgreParticleEmitterCommands.h @@ -33,12 +33,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ namespace EmitterCommands { /// Command object for ParticleEmitter - see ParamCommand @@ -87,7 +87,7 @@ namespace Ogre { void doSet(void* target, const String& val); }; - /// Command object for particle emitter - see ParamCommand + /// Command object for particle emitter - see ParamCommand class _OgreExport CmdDirPositionRef : public ParamCommand { public: @@ -193,7 +193,7 @@ namespace Ogre { String doGet(const void* target) const; void doSet(void* target, const String& val); }; - /// Command object for particle emitter - see ParamCommand + /// Command object for particle emitter - see ParamCommand class _OgreExport CmdName : public ParamCommand { public: @@ -201,7 +201,7 @@ namespace Ogre { void doSet(void* target, const String& val); }; - /// Command object for particle emitter - see ParamCommand + /// Command object for particle emitter - see ParamCommand class _OgreExport CmdEmittedEmitter : public ParamCommand { public: @@ -210,8 +210,8 @@ namespace Ogre { }; } - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreParticleEmitterFactory.h b/OgreMain/include/OgreParticleEmitterFactory.h index 439f73f0104..a5b04a4122b 100644 --- a/OgreMain/include/OgreParticleEmitterFactory.h +++ b/OgreMain/include/OgreParticleEmitterFactory.h @@ -36,13 +36,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Abstract class defining the interface to be implemented by creators of ParticleEmitter subclasses. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Abstract class defining the interface to be implemented by creators of ParticleEmitter subclasses. @remarks Plugins or 3rd party applications can add new types of particle emitters to Ogre by creating subclasses of the ParticleEmitter class. Because multiple instances of these emitters may be @@ -53,7 +53,7 @@ namespace Ogre { a name which identifies them, examples might be 'point', 'cone', or 'box', and these can be also be used from particle system scripts. */ - class _OgreExport ParticleEmitterFactory : public FXAlloc + class _OgreExport ParticleEmitterFactory : public FXAlloc { protected: vector::type mEmitters; @@ -75,8 +75,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreParticleIterator.h b/OgreMain/include/OgreParticleIterator.h index 88ce387fa1a..205fb93e519 100644 --- a/OgreMain/include/OgreParticleIterator.h +++ b/OgreMain/include/OgreParticleIterator.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Convenience class to make it easy to step through all particles in a ParticleSystem. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Convenience class to make it easy to step through all particles in a ParticleSystem. */ class _OgreExport ParticleIterator { @@ -60,8 +60,8 @@ namespace Ogre { /** Returns a pointer to the next particle, and moves the iterator on by 1 element. */ Particle* getNext(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreParticleSystem.h b/OgreMain/include/OgreParticleSystem.h index c09c36607f1..f39c9d6578b 100644 --- a/OgreMain/include/OgreParticleSystem.h +++ b/OgreMain/include/OgreParticleSystem.h @@ -41,13 +41,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Class defining particle system based special effects. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Class defining particle system based special effects. @remarks Particle systems are special effects generators which are based on a number of moving points to create the impression of things like like @@ -59,8 +59,8 @@ namespace Ogre { @par Particle systems are created using the SceneManager, never directly. In addition, like all subclasses of MovableObject, the ParticleSystem - will only be considered for rendering once it has been attached to a - SceneNode. + will only be considered for rendering once it has been attached to a + SceneNode. */ class _OgreExport ParticleSystem : public StringInterface, public MovableObject { @@ -115,34 +115,34 @@ namespace Ogre { String doGet(const void* target) const; void doSet(void* target, const String& val); }; - /** Command object for sorting (see ParamCommand).*/ - class CmdSorted : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /** Command object for local space (see ParamCommand).*/ - class CmdLocalSpace : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /** Command object for iteration interval(see ParamCommand).*/ - class CmdIterationInterval : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /** Command object for nonvisible timeout (see ParamCommand).*/ - class CmdNonvisibleTimeout : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; + /** Command object for sorting (see ParamCommand).*/ + class CmdSorted : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /** Command object for local space (see ParamCommand).*/ + class CmdLocalSpace : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /** Command object for iteration interval(see ParamCommand).*/ + class CmdIterationInterval : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /** Command object for nonvisible timeout (see ParamCommand).*/ + class CmdNonvisibleTimeout : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; /// Default constructor required for STL creation in manager ParticleSystem(); @@ -160,9 +160,9 @@ namespace Ogre { The main ParticleSystem just manages the creation and movement of particles; they are rendered using functions in ParticleRenderer and the ParticleVisual instances they create. - @param typeName String identifying the type of renderer to use; a new - instance of this type will be created; a factory must have been registered - with ParticleSystemManager. + @param typeName String identifying the type of renderer to use; a new + instance of this type will be created; a factory must have been registered + with ParticleSystemManager. */ void setRenderer(const String& typeName); @@ -261,37 +261,37 @@ namespace Ogre { */ size_t getNumParticles(void) const; - /** Manually add a particle to the system. - @remarks - Instead of using an emitter, you can manually add a particle to the system. - You must initialise the returned particle instance immediately with the - 'emission' state. - @note - There is no corresponding 'destroyParticle' method - if you want to dispose of a - particle manually (say, if you've used setSpeedFactor(0) to make particles live forever) - you should use getParticle() and modify it's timeToLive to zero, meaning that it will - get cleaned up in the next update. - */ - Particle* createParticle(void); - - /** Manually add an emitter particle to the system. - @remarks - The purpose of a particle emitter is to emit particles. Besides visual particles, also other other - particle types can be emitted, other emitters for example. The emitted emitters have a double role; - they behave as particles and can be influenced by affectors, but they are still emitters and capable - to emit other particles (or emitters). It is possible to create a chain of emitters - emitters - emitting other emitters, which also emit emitters. - @param emitterName The name of a particle emitter that must be emitted. - */ - Particle* createEmitterParticle(const String& emitterName); - - /** Retrieve a particle from the system for manual tweaking. - @remarks - Normally you use an affector to alter particles in flight, but - for small manually controlled particle systems you might want to use - this method. - */ - Particle* getParticle(size_t index); + /** Manually add a particle to the system. + @remarks + Instead of using an emitter, you can manually add a particle to the system. + You must initialise the returned particle instance immediately with the + 'emission' state. + @note + There is no corresponding 'destroyParticle' method - if you want to dispose of a + particle manually (say, if you've used setSpeedFactor(0) to make particles live forever) + you should use getParticle() and modify it's timeToLive to zero, meaning that it will + get cleaned up in the next update. + */ + Particle* createParticle(void); + + /** Manually add an emitter particle to the system. + @remarks + The purpose of a particle emitter is to emit particles. Besides visual particles, also other other + particle types can be emitted, other emitters for example. The emitted emitters have a double role; + they behave as particles and can be influenced by affectors, but they are still emitters and capable + to emit other particles (or emitters). It is possible to create a chain of emitters - emitters + emitting other emitters, which also emit emitters. + @param emitterName The name of a particle emitter that must be emitted. + */ + Particle* createEmitterParticle(const String& emitterName); + + /** Retrieve a particle from the system for manual tweaking. + @remarks + Normally you use an affector to alter particles in flight, but + for small manually controlled particle systems you might want to use + this method. + */ + Particle* getParticle(size_t index); /** Returns the maximum number of particles this system is allowed to have active at once. @remarks @@ -325,7 +325,7 @@ namespace Ogre { */ void setEmittedEmitterQuota(size_t quota); - /** Assignment operator for copying. + /** Assignment operator for copying. @remarks This operator deep copies all particle emitters and effectors, but not particles. The system's name is also not copied. @@ -389,9 +389,9 @@ namespace Ogre { */ virtual void _updateRenderQueue(RenderQueue* queue); - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false); + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false); /** Fast-forwards this system by the required number of seconds. @remarks @@ -407,32 +407,32 @@ namespace Ogre { */ void fastForward(Real time, Real interval = 0.1); - /** Sets a 'speed factor' on this particle system, which means it scales the elapsed - real time which has passed by this factor before passing it to the emitters, affectors, - and the particle life calculation. - @remarks - An interesting side effect - if you want to create a completely manual particle system - where you control the emission and life of particles yourself, you can set the speed - factor to 0.0f, thus disabling normal particle emission, alteration, and death. - */ - void setSpeedFactor(Real speedFactor) { mSpeedFactor = speedFactor; } + /** Sets a 'speed factor' on this particle system, which means it scales the elapsed + real time which has passed by this factor before passing it to the emitters, affectors, + and the particle life calculation. + @remarks + An interesting side effect - if you want to create a completely manual particle system + where you control the emission and life of particles yourself, you can set the speed + factor to 0.0f, thus disabling normal particle emission, alteration, and death. + */ + void setSpeedFactor(Real speedFactor) { mSpeedFactor = speedFactor; } - /** Gets the 'speed factor' on this particle system. - */ - Real getSpeedFactor(void) const { return mSpeedFactor; } + /** Gets the 'speed factor' on this particle system. + */ + Real getSpeedFactor(void) const { return mSpeedFactor; } /** Sets a 'iteration interval' on this particle system. @remarks The default Particle system update interval, based on elapsed frame time, - will cause different behavior between low frame-rate and high frame-rate. - By using this option, you can make the particle system update at - a fixed interval, keeping the behavior the same no matter what frame-rate - is. + will cause different behavior between low frame-rate and high frame-rate. + By using this option, you can make the particle system update at + a fixed interval, keeping the behavior the same no matter what frame-rate + is. @par When iteration interval is set to zero, it means the update occurs based - on an elapsed frame time, otherwise each iteration will take place - at the given interval, repeating until it has used up all the elapsed - frame time. + on an elapsed frame time, otherwise each iteration will take place + at the given interval, repeating until it has used up all the elapsed + frame time. @param iterationInterval The iteration interval, default to zero. */ @@ -442,44 +442,44 @@ namespace Ogre { */ Real getIterationInterval(void) const { return mIterationInterval; } - /** Set the default iteration interval for all ParticleSystem instances. - */ + /** Set the default iteration interval for all ParticleSystem instances. + */ static void setDefaultIterationInterval(Real iterationInterval) { msDefaultIterationInterval = iterationInterval; } - /** Get the default iteration interval for all ParticleSystem instances. - */ + /** Get the default iteration interval for all ParticleSystem instances. + */ static Real getDefaultIterationInterval(void) { return msDefaultIterationInterval; } - /** Sets when the particle system should stop updating after it hasn't been - visible for a while. - @remarks - By default, visible particle systems update all the time, even when - not in view. This means that they are guaranteed to be consistent when - they do enter view. However, this comes at a cost, updating particle - systems can be expensive, especially if they are perpetual. - @par - This option lets you set a 'timeout' on the particle system, so that - if it isn't visible for this amount of time, it will stop updating - until it is next visible. - @param timeout The time after which the particle system will be disabled - if it is no longer visible. 0 to disable the timeout and always update. - */ - void setNonVisibleUpdateTimeout(Real timeout); - /** Gets when the particle system should stop updating after it hasn't been - visible for a while. - */ - Real getNonVisibleUpdateTimeout(void) const { return mNonvisibleTimeout; } - - /** Set the default nonvisible timeout for all ParticleSystem instances. - */ - static void setDefaultNonVisibleUpdateTimeout(Real timeout) - { msDefaultNonvisibleTimeout = timeout; } - - /** Get the default nonvisible timeout for all ParticleSystem instances. - */ - static Real getDefaultNonVisibleUpdateTimeout(void) { return msDefaultNonvisibleTimeout; } - - /** Overridden from MovableObject */ + /** Sets when the particle system should stop updating after it hasn't been + visible for a while. + @remarks + By default, visible particle systems update all the time, even when + not in view. This means that they are guaranteed to be consistent when + they do enter view. However, this comes at a cost, updating particle + systems can be expensive, especially if they are perpetual. + @par + This option lets you set a 'timeout' on the particle system, so that + if it isn't visible for this amount of time, it will stop updating + until it is next visible. + @param timeout The time after which the particle system will be disabled + if it is no longer visible. 0 to disable the timeout and always update. + */ + void setNonVisibleUpdateTimeout(Real timeout); + /** Gets when the particle system should stop updating after it hasn't been + visible for a while. + */ + Real getNonVisibleUpdateTimeout(void) const { return mNonvisibleTimeout; } + + /** Set the default nonvisible timeout for all ParticleSystem instances. + */ + static void setDefaultNonVisibleUpdateTimeout(Real timeout) + { msDefaultNonvisibleTimeout = timeout; } + + /** Get the default nonvisible timeout for all ParticleSystem instances. + */ + static Real getDefaultNonVisibleUpdateTimeout(void) { return msDefaultNonvisibleTimeout; } + + /** Overridden from MovableObject */ const String& getMovableType(void) const; /** Internal callback used by Particles to notify their parent that they have been resized. @@ -535,30 +535,30 @@ namespace Ogre { virtual void setCullIndividually(bool cullIndividual); /// Return the resource group to be used to load dependent resources virtual const String& getResourceGroupName(void) const { return mResourceGroupName; } - /** Get the origin of this particle system, e.g. a script file name. - @remarks - This property will only contain something if the creator of - this particle system chose to populate it. Script loaders are advised - to populate it. - */ - const String& getOrigin(void) const { return mOrigin; } - /// Notify this particle system of it's origin - void _notifyOrigin(const String& origin) { mOrigin = origin; } - - /** @copydoc MovableObject::setRenderQueueGroup */ - void setRenderQueueGroup(uint8 queueID); - /** @copydoc MovableObject::setRenderQueueGroupAndPriority */ - void setRenderQueueGroupAndPriority(uint8 queueID, ushort priority); - - /** Set whether or not particles are sorted according to the camera. - @remarks - Enabling sorting alters the order particles are sent to the renderer. - When enabled, particles are sent to the renderer in order of - furthest distance from the camera. - */ - void setSortingEnabled(bool enabled) { mSorted = enabled; } - /// Gets whether particles are sorted relative to the camera. - bool getSortingEnabled(void) const { return mSorted; } + /** Get the origin of this particle system, e.g. a script file name. + @remarks + This property will only contain something if the creator of + this particle system chose to populate it. Script loaders are advised + to populate it. + */ + const String& getOrigin(void) const { return mOrigin; } + /// Notify this particle system of it's origin + void _notifyOrigin(const String& origin) { mOrigin = origin; } + + /** @copydoc MovableObject::setRenderQueueGroup */ + void setRenderQueueGroup(uint8 queueID); + /** @copydoc MovableObject::setRenderQueueGroupAndPriority */ + void setRenderQueueGroupAndPriority(uint8 queueID, ushort priority); + + /** Set whether or not particles are sorted according to the camera. + @remarks + Enabling sorting alters the order particles are sent to the renderer. + When enabled, particles are sent to the renderer in order of + furthest distance from the camera. + */ + void setSortingEnabled(bool enabled) { mSorted = enabled; } + /// Gets whether particles are sorted relative to the camera. + bool getSortingEnabled(void) const { return mSorted; } /** Set the (initial) bounds of the particle system manually. @remarks @@ -589,21 +589,21 @@ namespace Ogre { */ void setBoundsAutoUpdated(bool autoUpdate, Real stopIn = 0.0f); - /** Sets whether particles (and any affector effects) remain relative - to the node the particle system is attached to. - @remarks - By default particles are in world space once emitted, so they are not - affected by movement in the parent node of the particle system. This - makes the most sense when dealing with completely independent particles, - but if you want to constrain them to follow local motion too, you - can set this to true. - */ - void setKeepParticlesInLocalSpace(bool keepLocal); - - /** Gets whether particles (and any affector effects) remain relative - to the node the particle system is attached to. - */ - bool getKeepParticlesInLocalSpace(void) const { return mLocalSpace; } + /** Sets whether particles (and any affector effects) remain relative + to the node the particle system is attached to. + @remarks + By default particles are in world space once emitted, so they are not + affected by movement in the parent node of the particle system. This + makes the most sense when dealing with completely independent particles, + but if you want to constrain them to follow local motion too, you + can set this to true. + */ + void setKeepParticlesInLocalSpace(bool keepLocal); + + /** Gets whether particles (and any affector effects) remain relative + to the node the particle system is attached to. + */ + bool getKeepParticlesInLocalSpace(void) const { return mLocalSpace; } /** Internal method for updating the bounds of the particle system. @remarks @@ -620,26 +620,26 @@ namespace Ogre { */ void _updateBounds(void); - /** This is used to turn on or off particle emission for this system. - @remarks - By default particle system is always emitting particles (if a emitters exists) - and this can be used to stop the emission for all emitters. To turn it on again, - call it passing true. - - Note that this does not detach the particle system from the scene node, it will - still use some CPU. - */ - void setEmitting(bool v); - - /** Returns true if the particle system emitting flag is turned on. - @remarks - This function will not actually return whether the particles are being emitted. - It only returns the value of emitting flag. - */ - bool getEmitting() const; - - /// Override to return specific type flag - uint32 getTypeFlags(void) const; + /** This is used to turn on or off particle emission for this system. + @remarks + By default particle system is always emitting particles (if a emitters exists) + and this can be used to stop the emission for all emitters. To turn it on again, + call it passing true. + + Note that this does not detach the particle system from the scene node, it will + still use some CPU. + */ + void setEmitting(bool v); + + /** Returns true if the particle system emitting flag is turned on. + @remarks + This function will not actually return whether the particles are being emitted. + It only returns the value of emitting flag. + */ + bool getEmitting() const; + + /// Override to return specific type flag + uint32 getTypeFlags(void) const; protected: /// Command objects @@ -647,13 +647,13 @@ namespace Ogre { static CmdHeight msHeightCmd; static CmdMaterial msMaterialCmd; static CmdQuota msQuotaCmd; - static CmdEmittedEmitterQuota msEmittedEmitterQuotaCmd; + static CmdEmittedEmitterQuota msEmittedEmitterQuotaCmd; static CmdWidth msWidthCmd; static CmdRenderer msRendererCmd; - static CmdSorted msSortedCmd; - static CmdLocalSpace msLocalSpaceCmd; - static CmdIterationInterval msIterationIntervalCmd; - static CmdNonvisibleTimeout msNonvisibleTimeoutCmd; + static CmdSorted msSortedCmd; + static CmdLocalSpace msLocalSpaceCmd; + static CmdIterationInterval msIterationIntervalCmd; + static CmdNonvisibleTimeout msNonvisibleTimeoutCmd; AxisAlignedBox mAABB; @@ -674,30 +674,30 @@ namespace Ogre { Real mDefaultWidth; /// Default height of each particle Real mDefaultHeight; - /// Speed factor - Real mSpeedFactor; + /// Speed factor + Real mSpeedFactor; /// Iteration interval Real mIterationInterval; /// Iteration interval set? Otherwise track default bool mIterationIntervalSet; - /// Particles sorted according to camera? - bool mSorted; - /// Particles in local space? - bool mLocalSpace; - /// Update timeout when nonvisible (0 for no timeout) - Real mNonvisibleTimeout; - /// Update timeout when nonvisible set? Otherwise track default - bool mNonvisibleTimeoutSet; - /// Amount of time non-visible so far - Real mTimeSinceLastVisible; - /// Last frame in which known to be visible - unsigned long mLastVisibleFrame; - /// Controller for time update - Controller* mTimeController; + /// Particles sorted according to camera? + bool mSorted; + /// Particles in local space? + bool mLocalSpace; + /// Update timeout when nonvisible (0 for no timeout) + Real mNonvisibleTimeout; + /// Update timeout when nonvisible set? Otherwise track default + bool mNonvisibleTimeoutSet; + /// Amount of time non-visible so far + Real mTimeSinceLastVisible; + /// Last frame in which known to be visible + unsigned long mLastVisibleFrame; + /// Controller for time update + Controller* mTimeController; /// Indication whether the emitted emitter pool (= pool with particle emitters that are emitted) is initialised - bool mEmittedEmitterPoolInitialised; - /// Used to control if the particle system should emit particles or not. - bool mIsEmitting; + bool mEmittedEmitterPoolInitialised; + /// Used to control if the particle system should emit particles or not. + bool mIsEmitting; typedef list::type ActiveParticleList; typedef list::type FreeParticleList; @@ -723,9 +723,9 @@ namespace Ogre { float operator()(Particle* p) const; }; - static RadixSort mRadixSorter; + static RadixSort mRadixSorter; - /** Active particle list. + /** Active particle list. @remarks This is a linked list of pointers to particles in the particle pool. @par @@ -743,7 +743,7 @@ namespace Ogre { to the estimated size in the mParticlePool vector and are referenced on this deque at startup. As they get used this list reduces, as they get released back to to the set they get added - back to the list. + back to the list. */ FreeParticleList mFreeParticles; @@ -753,21 +753,21 @@ namespace Ogre { */ ParticlePool mParticlePool; - typedef list::type FreeEmittedEmitterList; - typedef list::type ActiveEmittedEmitterList; - typedef vector::type EmittedEmitterList; - typedef map::type FreeEmittedEmitterMap; - typedef map::type EmittedEmitterPool; + typedef list::type FreeEmittedEmitterList; + typedef list::type ActiveEmittedEmitterList; + typedef vector::type EmittedEmitterList; + typedef map::type FreeEmittedEmitterMap; + typedef map::type EmittedEmitterPool; - /** Pool of emitted emitters for use and reuse in the active emitted emitter list. + /** Pool of emitted emitters for use and reuse in the active emitted emitter list. @remarks - The emitters in this pool act as particles and as emitters. The pool is a map containing lists - of emitters, identified by their name. + The emitters in this pool act as particles and as emitters. The pool is a map containing lists + of emitters, identified by their name. @par The emitters in this pool are cloned using emitters that are kept in the main emitter list - of the ParticleSystem. + of the ParticleSystem. */ - EmittedEmitterPool mEmittedEmitterPool; + EmittedEmitterPool mEmittedEmitterPool; /** Free emitted emitter list. @remarks @@ -775,14 +775,14 @@ namespace Ogre { */ FreeEmittedEmitterMap mFreeEmittedEmitters; - /** Active emitted emitter list. + /** Active emitted emitter list. @remarks This is a linked list of pointers to emitters in the emitted emitter pool. - Emitters that are used are stored (their pointers) in both the list with active particles and in - the list with active emitted emitters. */ + Emitters that are used are stored (their pointers) in both the list with active particles and in + the list with active emitted emitters. */ ActiveEmittedEmitterList mActiveEmittedEmitters; - typedef vector::type ParticleEmitterList; + typedef vector::type ParticleEmitterList; typedef vector::type ParticleAffectorList; /// List of particle emitters, ie sources of particles @@ -805,8 +805,8 @@ namespace Ogre { /// The number of emitted emitters in the pool. size_t mEmittedEmitterPoolSize; - /// Optional origin of this particle system (eg script name) - String mOrigin; + /// Optional origin of this particle system (eg script name) + String mOrigin; /// Default iteration interval static Real msDefaultIterationInterval; @@ -819,90 +819,90 @@ namespace Ogre { /** Spawn new particles based on free quota and emitter requirements. */ void _triggerEmitters(Real timeElapsed); - /** Helper function that actually performs the emission of particles + /** Helper function that actually performs the emission of particles */ - void _executeTriggerEmitters(ParticleEmitter* emitter, unsigned requested, Real timeElapsed); + void _executeTriggerEmitters(ParticleEmitter* emitter, unsigned requested, Real timeElapsed); - /** Updates existing particle based on their momentum. */ + /** Updates existing particle based on their momentum. */ void _applyMotion(Real timeElapsed); /** Applies the effects of affectors. */ void _triggerAffectors(Real timeElapsed); - /** Sort the particles in the system **/ - void _sortParticles(Camera* cam); + /** Sort the particles in the system **/ + void _sortParticles(Camera* cam); /** Resize the internal pool of particles. */ void increasePool(size_t size); - /** Resize the internal pool of emitted emitters. + /** Resize the internal pool of emitted emitters. @remarks The pool consists of multiple vectors containing pointers to particle emitters. Increasing the - pool with size implies that the vectors are equally increased. The quota of emitted emitters is - defined on a particle system level and not on a particle emitter level. This is to prevent that - the number of created emitters becomes too high; the quota is shared amongst the emitted emitters. - */ - void increaseEmittedEmitterPool(size_t size); + pool with size implies that the vectors are equally increased. The quota of emitted emitters is + defined on a particle system level and not on a particle emitter level. This is to prevent that + the number of created emitters becomes too high; the quota is shared amongst the emitted emitters. + */ + void increaseEmittedEmitterPool(size_t size); - /** Internal method for initialising string interface. */ + /** Internal method for initialising string interface. */ void initParameters(void); /** Internal method to configure the renderer. */ void configureRenderer(void); - /// Internal method for creating ParticleVisualData instances for the pool - void createVisualParticles(size_t poolstart, size_t poolend); - /// Internal method for destroying ParticleVisualData instances for the pool - void destroyVisualParticles(size_t poolstart, size_t poolend); + /// Internal method for creating ParticleVisualData instances for the pool + void createVisualParticles(size_t poolstart, size_t poolend); + /// Internal method for destroying ParticleVisualData instances for the pool + void destroyVisualParticles(size_t poolstart, size_t poolend); - /** Create a pool of emitted emitters and assign them to the free emitter list. + /** Create a pool of emitted emitters and assign them to the free emitter list. @remarks The emitters in the pool are grouped by name. This name is the name of the base emitter in the - main list with particle emitters, which forms the template of the created emitted emitters. + main list with particle emitters, which forms the template of the created emitted emitters. */ - void initialiseEmittedEmitters(void); + void initialiseEmittedEmitters(void); - /** Determine which emitters in the Particle Systems main emitter become a template for creating an - pool of emitters that can be emitted. + /** Determine which emitters in the Particle Systems main emitter become a template for creating an + pool of emitters that can be emitted. */ - void initialiseEmittedEmitterPool(void); + void initialiseEmittedEmitterPool(void); - /** Add emitters from the pool to the free emitted emitter queue. */ - void addFreeEmittedEmitters(void); + /** Add emitters from the pool to the free emitted emitter queue. */ + void addFreeEmittedEmitters(void); - /** Removes all emitted emitters from this system. */ - void removeAllEmittedEmitters(void); + /** Removes all emitted emitters from this system. */ + void removeAllEmittedEmitters(void); - /** Find the list with free emitted emitters. + /** Find the list with free emitted emitters. @param name The name that identifies the list with free emitted emitters. */ - FreeEmittedEmitterList* findFreeEmittedEmitter (const String& name); + FreeEmittedEmitterList* findFreeEmittedEmitter (const String& name); - /** Removes an emitter from the active emitted emitter list. + /** Removes an emitter from the active emitted emitter list. @remarks The emitter will not be destroyed! @param emitter Pointer to a particle emitter. */ - void removeFromActiveEmittedEmitters (ParticleEmitter* emitter); + void removeFromActiveEmittedEmitters (ParticleEmitter* emitter); - /** Moves all emitted emitters from the active list to the free list + /** Moves all emitted emitters from the active list to the free list @remarks The active emitted emitter list will not be cleared and still keeps references to the emitters! */ - void addActiveEmittedEmittersToFreeList (void); + void addActiveEmittedEmittersToFreeList (void); - /** This function clears all data structures that are used in combination with emitted emitters and - sets the flag to indicate that the emitted emitter pool must be initialised again. + /** This function clears all data structures that are used in combination with emitted emitters and + sets the flag to indicate that the emitted emitter pool must be initialised again. @remarks This function should be called if new emitters are added to a ParticleSystem or deleted from a - ParticleSystem. The emitted emitter data structures become out of sync and need to be build up - again. The data structures are not reorganised in this function, but by setting a flag, - they are rebuild in the regular process flow. + ParticleSystem. The emitted emitter data structures become out of sync and need to be build up + again. The data structures are not reorganised in this function, but by setting a flag, + they are rebuild in the regular process flow. */ - void _notifyReorganiseEmittedEmitterData (void); + void _notifyReorganiseEmittedEmitterData (void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreParticleSystemManager.h b/OgreMain/include/OgreParticleSystemManager.h index add49e6fd3d..99c254fad65 100644 --- a/OgreMain/include/OgreParticleSystemManager.h +++ b/OgreMain/include/OgreParticleSystemManager.h @@ -36,52 +36,52 @@ THE SOFTWARE. namespace Ogre { - // Forward decl - class ParticleSystemFactory; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Manages particle systems, particle system scripts (templates) and the - available emitter & affector factories. + // Forward decl + class ParticleSystemFactory; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Manages particle systems, particle system scripts (templates) and the + available emitter & affector factories. @remarks This singleton class is responsible for creating and managing particle - systems. All particle systems must be created and destroyed using this - object, although the user interface to creating them is via - SceneManager. Remember that like all other MovableObject + systems. All particle systems must be created and destroyed using this + object, although the user interface to creating them is via + SceneManager. Remember that like all other MovableObject subclasses, ParticleSystems do not get rendered until they are - attached to a SceneNode object. + attached to a SceneNode object. @par This class also manages factories for ParticleEmitter and - ParticleAffector classes. To enable easy extensions to the types of - emitters (particle sources) and affectors (particle modifiers), the + ParticleAffector classes. To enable easy extensions to the types of + emitters (particle sources) and affectors (particle modifiers), the ParticleSystemManager lets plugins or applications register factory - classes which submit new subclasses to ParticleEmitter and - ParticleAffector. Ogre comes with a number of them already provided, + classes which submit new subclasses to ParticleEmitter and + ParticleAffector. Ogre comes with a number of them already provided, such as cone, sphere and box-shaped emitters, and simple affectors such - as constant directional force and colour faders. However using this - registration process, a plugin can create any behaviour required. + as constant directional force and colour faders. However using this + registration process, a plugin can create any behaviour required. @par This class also manages the loading and parsing of particle system - scripts, which are text files describing named particle system - templates. Instances of particle systems using these templates can + scripts, which are text files describing named particle system + templates. Instances of particle systems using these templates can then be created easily through the createParticleSystem method. */ class _OgreExport ParticleSystemManager: - public Singleton, public ScriptLoader, public FXAlloc + public Singleton, public ScriptLoader, public FXAlloc { - friend class ParticleSystemFactory; - public: + friend class ParticleSystemFactory; + public: typedef map::type ParticleTemplateMap; - typedef map::type ParticleAffectorFactoryMap; - typedef map::type ParticleEmitterFactoryMap; - typedef map::type ParticleSystemRendererFactoryMap; + typedef map::type ParticleAffectorFactoryMap; + typedef map::type ParticleEmitterFactoryMap; + typedef map::type ParticleSystemRendererFactoryMap; protected: - OGRE_AUTO_MUTEX; - + OGRE_AUTO_MUTEX; + /// Templates based on scripts ParticleTemplateMap mSystemTemplates; @@ -91,13 +91,13 @@ namespace Ogre { /// Factories for named affector types (can be extended using plugins) ParticleAffectorFactoryMap mAffectorFactories; - /// Map of renderer types to factories - ParticleSystemRendererFactoryMap mRendererFactories; + /// Map of renderer types to factories + ParticleSystemRendererFactoryMap mRendererFactories; StringVector mScriptPatterns; - // Factory instance - ParticleSystemFactory* mFactory; + // Factory instance + ParticleSystemFactory* mFactory; /** Internal script parsing method. */ void parseNewEmitter(const String& type, DataStreamPtr& chunk, ParticleSystem* sys); @@ -114,15 +114,15 @@ namespace Ogre { /** Internal script parsing method. */ void skipToNextOpenBrace(DataStreamPtr& chunk); - /// Internal implementation of createSystem + /// Internal implementation of createSystem ParticleSystem* createSystemImpl(const String& name, size_t quota, - const String& resourceGroup); - /// Internal implementation of createSystem + const String& resourceGroup); + /// Internal implementation of createSystem ParticleSystem* createSystemImpl(const String& name, const String& templateName); - /// Internal implementation of destroySystem + /// Internal implementation of destroySystem void destroySystemImpl(ParticleSystem* sys); - - + + public: ParticleSystemManager(); @@ -166,15 +166,15 @@ namespace Ogre { */ void addAffectorFactory(ParticleAffectorFactory* factory); - /** Registers a factory class for creating ParticleSystemRenderer instances. + /** Registers a factory class for creating ParticleSystemRenderer instances. @par Note that the object passed to this function will not be destroyed by the ParticleSystemManager, since it may have been allocated on a different heap in the case of plugins. The caller must destroy the object later on, probably on plugin shutdown. @param factory Pointer to a ParticleSystemRendererFactory subclass created by the plugin or application code. - */ - void addRendererFactory(ParticleSystemRendererFactory* factory); + */ + void addRendererFactory(ParticleSystemRendererFactory* factory); /** Adds a new particle system template to the list of available templates. @remarks @@ -322,15 +322,15 @@ namespace Ogre { /// @copydoc ScriptLoader::getLoadingOrder Real getLoadingOrder(void) const; - typedef MapIterator ParticleAffectorFactoryIterator; - typedef MapIterator ParticleEmitterFactoryIterator; - typedef MapIterator ParticleRendererFactoryIterator; - /** Return an iterator over the affector factories currently registered */ - ParticleAffectorFactoryIterator getAffectorFactoryIterator(void); - /** Return an iterator over the emitter factories currently registered */ - ParticleEmitterFactoryIterator getEmitterFactoryIterator(void); - /** Return an iterator over the renderer factories currently registered */ - ParticleRendererFactoryIterator getRendererFactoryIterator(void); + typedef MapIterator ParticleAffectorFactoryIterator; + typedef MapIterator ParticleEmitterFactoryIterator; + typedef MapIterator ParticleRendererFactoryIterator; + /** Return an iterator over the affector factories currently registered */ + ParticleAffectorFactoryIterator getAffectorFactoryIterator(void); + /** Return an iterator over the emitter factories currently registered */ + ParticleEmitterFactoryIterator getEmitterFactoryIterator(void); + /** Return an iterator over the renderer factories currently registered */ + ParticleRendererFactoryIterator getRendererFactoryIterator(void); typedef MapIterator ParticleSystemTemplateIterator; @@ -342,9 +342,9 @@ namespace Ogre { } /** Get an instance of ParticleSystemFactory (internal use). */ - ParticleSystemFactory* _getFactory(void) { return mFactory; } - - /** Override standard Singleton retrieval. + ParticleSystemFactory* _getFactory(void) { return mFactory; } + + /** Override standard Singleton retrieval. @remarks Why do we do this? Well, it's because the Singleton implementation is in a .h file, which means it gets compiled @@ -379,23 +379,23 @@ namespace Ogre { }; - /** Factory object for creating ParticleSystem instances */ - class _OgreExport ParticleSystemFactory : public MovableObjectFactory - { - protected: - MovableObject* createInstanceImpl(const String& name, const NameValuePairList* params); - public: - ParticleSystemFactory() {} - ~ParticleSystemFactory() {} - - static String FACTORY_TYPE_NAME; - - const String& getType(void) const; - void destroyInstance( MovableObject* obj); - - }; - /** @} */ - /** @} */ + /** Factory object for creating ParticleSystem instances */ + class _OgreExport ParticleSystemFactory : public MovableObjectFactory + { + protected: + MovableObject* createInstanceImpl(const String& name, const NameValuePairList* params); + public: + ParticleSystemFactory() {} + ~ParticleSystemFactory() {} + + static String FACTORY_TYPE_NAME; + + const String& getType(void) const; + void destroyInstance( MovableObject* obj); + + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreParticleSystemRenderer.h b/OgreMain/include/OgreParticleSystemRenderer.h index eefd39d511a..3c2b22ccdab 100644 --- a/OgreMain/include/OgreParticleSystemRenderer.h +++ b/OgreMain/include/OgreParticleSystemRenderer.h @@ -37,13 +37,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Abstract class defining the interface required to be implemented + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Abstract class defining the interface required to be implemented by classes which provide rendering capability to ParticleSystem instances. */ class _OgreExport ParticleSystemRenderer : public StringInterface, public FXAlloc @@ -55,9 +55,9 @@ namespace Ogre { virtual ~ParticleSystemRenderer() {} /** Gets the type of this renderer - must be implemented by subclasses */ - virtual const String& getType(void) const = 0; + virtual const String& getType(void) const = 0; - /** Delegated to by ParticleSystem::_updateRenderQueue + /** Delegated to by ParticleSystem::_updateRenderQueue @remarks The subclass must update the render queue using whichever Renderable instance(s) it wishes. @@ -87,45 +87,45 @@ namespace Ogre { virtual void _notifyParticleMoved(list::type& currentParticles) {} /** Optional callback notified when particles cleared */ virtual void _notifyParticleCleared(list::type& currentParticles) {} - /** Create a new ParticleVisualData instance for attachment to a particle. - @remarks - If this renderer needs additional data in each particle, then this should - be held in an instance of a subclass of ParticleVisualData, and this method - should be overridden to return a new instance of it. The default - behaviour is to return null. - */ - virtual ParticleVisualData* _createVisualData(void) { return 0; } - /** Destroy a ParticleVisualData instance. - @remarks - If this renderer needs additional data in each particle, then this should - be held in an instance of a subclass of ParticleVisualData, and this method - should be overridden to destroy an instance of it. The default - behaviour is to do nothing. - */ - virtual void _destroyVisualData(ParticleVisualData* vis) { assert (vis == 0); } - - /** Sets which render queue group this renderer should target with it's - output. - */ - virtual void setRenderQueueGroup(uint8 queueID) = 0; - /** Sets which render queue group and priority this renderer should target with it's - output. - */ - virtual void setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) = 0; - - /** Setting carried over from ParticleSystem. - */ - virtual void setKeepParticlesInLocalSpace(bool keepLocal) = 0; + /** Create a new ParticleVisualData instance for attachment to a particle. + @remarks + If this renderer needs additional data in each particle, then this should + be held in an instance of a subclass of ParticleVisualData, and this method + should be overridden to return a new instance of it. The default + behaviour is to return null. + */ + virtual ParticleVisualData* _createVisualData(void) { return 0; } + /** Destroy a ParticleVisualData instance. + @remarks + If this renderer needs additional data in each particle, then this should + be held in an instance of a subclass of ParticleVisualData, and this method + should be overridden to destroy an instance of it. The default + behaviour is to do nothing. + */ + virtual void _destroyVisualData(ParticleVisualData* vis) { assert (vis == 0); } + + /** Sets which render queue group this renderer should target with it's + output. + */ + virtual void setRenderQueueGroup(uint8 queueID) = 0; + /** Sets which render queue group and priority this renderer should target with it's + output. + */ + virtual void setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) = 0; + + /** Setting carried over from ParticleSystem. + */ + virtual void setKeepParticlesInLocalSpace(bool keepLocal) = 0; /** Gets the desired particles sort mode of this renderer */ virtual SortMode _getSortMode(void) const = 0; - /** Required method to allow the renderer to communicate the Renderables - it will be using to render the system to a visitor. - @see MovableObject::visitRenderables - */ - virtual void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false) = 0; + /** Required method to allow the renderer to communicate the Renderables + it will be using to render the system to a visitor. + @see MovableObject::visitRenderables + */ + virtual void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false) = 0; }; @@ -135,8 +135,8 @@ namespace Ogre { public: // No methods, must just override all methods inherited from FactoryObj }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePass.h b/OgreMain/include/OgrePass.h index 602285fe555..501a0180e53 100644 --- a/OgreMain/include/OgrePass.h +++ b/OgreMain/include/OgrePass.h @@ -210,10 +210,10 @@ namespace Ogre { GpuProgramUsage *mShadowReceiverFragmentProgramUsage; /// Geometry program details GpuProgramUsage *mGeometryProgramUsage; - /// Tessellation hull program details - GpuProgramUsage *mTessellationHullProgramUsage; - /// Tessellation domain program details - GpuProgramUsage *mTessellationDomainProgramUsage; + /// Tessellation hull program details + GpuProgramUsage *mTessellationHullProgramUsage; + /// Tessellation domain program details + GpuProgramUsage *mTessellationDomainProgramUsage; /// Compute program details GpuProgramUsage *mComputeProgramUsage; /// Is this pass queued for deletion? @@ -269,7 +269,7 @@ namespace Ogre { /// Returns true if this pass is programmable i.e. includes either a vertex or fragment program. bool isProgrammable(void) const { return mVertexProgramUsage || mFragmentProgramUsage || mGeometryProgramUsage || - mTessellationHullProgramUsage || mTessellationDomainProgramUsage || mComputeProgramUsage; } + mTessellationHullProgramUsage || mTessellationDomainProgramUsage || mComputeProgramUsage; } /// Returns true if this pass uses a programmable vertex pipeline bool hasVertexProgram(void) const { return mVertexProgramUsage != NULL; } @@ -277,9 +277,9 @@ namespace Ogre { bool hasFragmentProgram(void) const { return mFragmentProgramUsage != NULL; } /// Returns true if this pass uses a programmable geometry pipeline bool hasGeometryProgram(void) const { return mGeometryProgramUsage != NULL; } - /// Returns true if this pass uses a programmable tessellation control pipeline + /// Returns true if this pass uses a programmable tessellation control pipeline bool hasTessellationHullProgram(void) const { return mTessellationHullProgramUsage != NULL; } - /// Returns true if this pass uses a programmable tessellation control pipeline + /// Returns true if this pass uses a programmable tessellation control pipeline bool hasTessellationDomainProgram(void) const { return mTessellationDomainProgramUsage != NULL; } /// Returns true if this pass uses a programmable compute pipeline bool hasComputeProgram(void) const { return mComputeProgramUsage != NULL; } @@ -471,24 +471,24 @@ namespace Ogre { */ bool getPointSpritesEnabled(void) const; - /** Sets how points are attenuated with distance. - @remarks - When performing point rendering or point sprite rendering, - point size can be attenuated with distance. The equation for - doing this is attenuation = 1 / (constant + linear * dist + quadratic * d^2). - @par - For example, to disable distance attenuation (constant screensize) - you would set constant to 1, and linear and quadratic to 0. A - standard perspective attenuation would be 0, 1, 0 respectively. - @note - The resulting size is clamped to the minimum and maximum point - size. - @param enabled Whether point attenuation is enabled - @param constant, linear, quadratic Parameters to the attenuation - function defined above - */ - void setPointAttenuation(bool enabled, - Real constant = 0.0f, Real linear = 1.0f, Real quadratic = 0.0f); + /** Sets how points are attenuated with distance. + @remarks + When performing point rendering or point sprite rendering, + point size can be attenuated with distance. The equation for + doing this is attenuation = 1 / (constant + linear * dist + quadratic * d^2). + @par + For example, to disable distance attenuation (constant screensize) + you would set constant to 1, and linear and quadratic to 0. A + standard perspective attenuation would be 0, 1, 0 respectively. + @note + The resulting size is clamped to the minimum and maximum point + size. + @param enabled Whether point attenuation is enabled + @param constant, linear, quadratic Parameters to the attenuation + function defined above + */ + void setPointAttenuation(bool enabled, + Real constant = 0.0f, Real linear = 1.0f, Real quadratic = 0.0f); /** Returns whether points are attenuated with distance. */ bool isPointAttenuationEnabled(void) const; @@ -1756,14 +1756,14 @@ namespace Ogre { const UserObjectBindings& getUserObjectBindings() const { return mUserObjectBindings; } /// Support for shader model 5.0, hull and domain shaders - /** Sets the details of the tessellation control program to use. + /** Sets the details of the tessellation control program to use. @remarks Only applicable to programmable passes, this sets the details of - the Tessellation Hull program to use in this pass. The program will not be + the Tessellation Hull program to use in this pass. The program will not be loaded until the parent Material is loaded. @param name The name of the program - this must have been created using GpuProgramManager by the time that this Pass - is loaded. If this parameter is blank, any Tessellation Hull program in this pass is disabled. + is loaded. If this parameter is blank, any Tessellation Hull program in this pass is disabled. @param resetParams If true, this will create a fresh set of parameters from the new program being linked, so if you had previously set parameters @@ -1772,27 +1772,27 @@ namespace Ogre { case of named parameters refers to the indexes underlying them, not just the names. */ - void setTessellationHullProgram(const String& name, bool resetParams = true); - /** Sets the Tessellation Hull program parameters. + void setTessellationHullProgram(const String& name, bool resetParams = true); + /** Sets the Tessellation Hull program parameters. @remarks Only applicable to programmable passes. */ - void setTessellationHullProgramParameters(GpuProgramParametersSharedPtr params); - /** Gets the name of the Tessellation Hull program used by this pass. */ - const String& getTessellationHullProgramName(void) const; - /** Gets the Tessellation Hull program parameters used by this pass. */ - GpuProgramParametersSharedPtr getTessellationHullProgramParameters(void) const; - /** Gets the Tessellation Hull program used by this pass, only available after _load(). */ - const GpuProgramPtr& getTessellationHullProgram(void) const; + void setTessellationHullProgramParameters(GpuProgramParametersSharedPtr params); + /** Gets the name of the Tessellation Hull program used by this pass. */ + const String& getTessellationHullProgramName(void) const; + /** Gets the Tessellation Hull program parameters used by this pass. */ + GpuProgramParametersSharedPtr getTessellationHullProgramParameters(void) const; + /** Gets the Tessellation Hull program used by this pass, only available after _load(). */ + const GpuProgramPtr& getTessellationHullProgram(void) const; - /** Sets the details of the tessellation domain program to use. + /** Sets the details of the tessellation domain program to use. @remarks Only applicable to programmable passes, this sets the details of - the Tessellation domain program to use in this pass. The program will not be + the Tessellation domain program to use in this pass. The program will not be loaded until the parent Material is loaded. @param name The name of the program - this must have been created using GpuProgramManager by the time that this Pass - is loaded. If this parameter is blank, any Tessellation domain program in this pass is disabled. + is loaded. If this parameter is blank, any Tessellation domain program in this pass is disabled. @param resetParams If true, this will create a fresh set of parameters from the new program being linked, so if you had previously set parameters @@ -1801,18 +1801,18 @@ namespace Ogre { case of named parameters refers to the indexes underlying them, not just the names. */ - void setTessellationDomainProgram(const String& name, bool resetParams = true); - /** Sets the Tessellation Domain program parameters. + void setTessellationDomainProgram(const String& name, bool resetParams = true); + /** Sets the Tessellation Domain program parameters. @remarks Only applicable to programmable passes. */ - void setTessellationDomainProgramParameters(GpuProgramParametersSharedPtr params); + void setTessellationDomainProgramParameters(GpuProgramParametersSharedPtr params); /** Gets the name of the Domain Evaluation program used by this pass. */ - const String& getTessellationDomainProgramName(void) const; - /** Gets the Tessellation Domain program parameters used by this pass. */ - GpuProgramParametersSharedPtr getTessellationDomainProgramParameters(void) const; - /** Gets the Tessellation Domain program used by this pass, only available after _load(). */ - const GpuProgramPtr& getTessellationDomainProgram(void) const; + const String& getTessellationDomainProgramName(void) const; + /** Gets the Tessellation Domain program parameters used by this pass. */ + GpuProgramParametersSharedPtr getTessellationDomainProgramParameters(void) const; + /** Gets the Tessellation Domain program used by this pass, only available after _load(). */ + const GpuProgramPtr& getTessellationDomainProgram(void) const; /** Sets the details of the compute program to use. @remarks @@ -1831,16 +1831,16 @@ namespace Ogre { not just the names. */ void setComputeProgram(const String& name, bool resetParams = true); - /** Sets the Tessellation Evaluation program parameters. + /** Sets the Tessellation Evaluation program parameters. @remarks Only applicable to programmable passes. */ void setComputeProgramParameters(GpuProgramParametersSharedPtr params); - /** Gets the name of the Tessellation Hull program used by this pass. */ + /** Gets the name of the Tessellation Hull program used by this pass. */ const String& getComputeProgramName(void) const; - /** Gets the Tessellation Hull program parameters used by this pass. */ + /** Gets the Tessellation Hull program parameters used by this pass. */ GpuProgramParametersSharedPtr getComputeProgramParameters(void) const; - /** Gets the Tessellation EHull program used by this pass, only available after _load(). */ + /** Gets the Tessellation EHull program used by this pass, only available after _load(). */ const GpuProgramPtr& getComputeProgram(void) const; }; diff --git a/OgreMain/include/OgrePatchMesh.h b/OgreMain/include/OgrePatchMesh.h index b90c4810aad..ee01f6b52fa 100644 --- a/OgreMain/include/OgrePatchMesh.h +++ b/OgreMain/include/OgrePatchMesh.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup LOD - * @{ - */ - /** Patch specialisation of Mesh. + /** \addtogroup Core + * @{ + */ + /** \addtogroup LOD + * @{ + */ + /** Patch specialisation of Mesh. @remarks Instances of this class should be created by calling MeshManager::createBezierPatch. */ @@ -56,7 +56,7 @@ namespace Ogre { PatchMesh(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group); /// Update the mesh with new control points positions. - void update(void* controlPointBuffer, size_t width, size_t height, + void update(void* controlPointBuffer, size_t width, size_t height, size_t uMaxSubdivisionLevel, size_t vMaxSubdivisionLevel, PatchSurface::VisibleSide visibleSide); /// Define the patch, as defined in MeshManager::createBezierPatch @@ -76,12 +76,12 @@ namespace Ogre { protected: /// Overridden from Resource void loadImpl(void); - /// Overridden from Resource - do nothing (no disk caching) - void prepareImpl(void) {} + /// Overridden from Resource - do nothing (no disk caching) + void prepareImpl(void) {} }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePatchSurface.h b/OgreMain/include/OgrePatchSurface.h index 1cc68d7cfe3..06d6df1849e 100644 --- a/OgreMain/include/OgrePatchSurface.h +++ b/OgreMain/include/OgrePatchSurface.h @@ -37,19 +37,19 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup LOD - * @{ - */ - /** A surface which is defined by curves of some kind to form a patch, e.g. a Bezier patch. + /** \addtogroup Core + * @{ + */ + /** \addtogroup LOD + * @{ + */ + /** A surface which is defined by curves of some kind to form a patch, e.g. a Bezier patch. @remarks This object will take a list of control points with various assorted data, and will subdivide it into a patch mesh. Currently only Bezier curves are supported for defining the surface, but other techniques such as NURBS would follow the same basic approach. */ - class _OgreExport PatchSurface : public PatchAlloc + class _OgreExport PatchSurface : public PatchAlloc { public: PatchSurface(); @@ -232,8 +232,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgrePixelCountLodStrategy.h b/OgreMain/include/OgrePixelCountLodStrategy.h index 9cf2da2b8d1..bfb11b2cb5b 100644 --- a/OgreMain/include/OgrePixelCountLodStrategy.h +++ b/OgreMain/include/OgrePixelCountLodStrategy.h @@ -35,18 +35,18 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup LOD - * @{ - */ - - class AbsolutePixelCountLodStrategy; - /// Backward compatible name for Distance_Box strategy. - typedef AbsolutePixelCountLodStrategy PixelCountLodStrategy; - - /** Abstract base class for level of detail strategy based on pixel count approximations from bounding sphere projection. */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup LOD + * @{ + */ + + class AbsolutePixelCountLodStrategy; + /// Backward compatible name for Distance_Box strategy. + typedef AbsolutePixelCountLodStrategy PixelCountLodStrategy; + + /** Abstract base class for level of detail strategy based on pixel count approximations from bounding sphere projection. */ class _OgreExport PixelCountLodStrategyBase : public LodStrategy { protected: @@ -75,8 +75,8 @@ namespace Ogre { /// @copydoc LodStrategy::isSorted virtual bool isSorted(const Mesh::LodValueList& values) const; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ class _OgreExport AbsolutePixelCountLodStrategy : public PixelCountLodStrategyBase, public Singleton { diff --git a/OgreMain/include/OgrePixelFormat.h b/OgreMain/include/OgrePixelFormat.h index 8d2a56a7a58..89a7e10c2c7 100644 --- a/OgreMain/include/OgrePixelFormat.h +++ b/OgreMain/include/OgrePixelFormat.h @@ -33,33 +33,33 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Image - * @{ - */ - /** The pixel format used for images, textures, and render surfaces */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Image + * @{ + */ + /** The pixel format used for images, textures, and render surfaces */ enum PixelFormat { /// Unknown pixel format. PF_UNKNOWN = 0, /// 8-bit pixel format, all bits luminance. PF_L8 = 1, - PF_BYTE_L = PF_L8, + PF_BYTE_L = PF_L8, /// 16-bit pixel format, all bits luminance. PF_L16 = 2, - PF_SHORT_L = PF_L16, + PF_SHORT_L = PF_L16, /// 8-bit pixel format, all bits alpha. PF_A8 = 3, - PF_BYTE_A = PF_A8, + PF_BYTE_A = PF_A8, /// 8-bit pixel format, 4 bits alpha, 4 bits luminance. PF_A4L4 = 4, - /// 2 byte pixel format, 1 byte luminance, 1 byte alpha - PF_BYTE_LA = 5, + /// 2 byte pixel format, 1 byte luminance, 1 byte alpha + PF_BYTE_LA = 5, /// 16-bit pixel format, 5 bits red, 6 bits green, 5 bits blue. PF_R5G6B5 = 6, - /// 16-bit pixel format, 5 bits red, 6 bits green, 5 bits blue. + /// 16-bit pixel format, 5 bits red, 6 bits green, 5 bits blue. PF_B5G6R5 = 7, /// 8-bit pixel format, 2 bits blue, 3 bits green, 3 bits red. PF_R3G3B2 = 31, @@ -77,8 +77,8 @@ namespace Ogre { PF_A8B8G8R8 = 13, /// 32-bit pixel format, 8 bits for blue, green, red and alpha. PF_B8G8R8A8 = 14, - /// 32-bit pixel format, 8 bits for red, green, blue and alpha. - PF_R8G8B8A8 = 28, + /// 32-bit pixel format, 8 bits for red, green, blue and alpha. + PF_R8G8B8A8 = 28, /// 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue /// like PF_A8R8G8B8, but alpha will get discarded PF_X8R8G8B8 = 26, @@ -86,23 +86,23 @@ namespace Ogre { /// like PF_A8B8G8R8, but alpha will get discarded PF_X8B8G8R8 = 27, #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - /// 3 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue - PF_BYTE_RGB = PF_R8G8B8, - /// 3 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red - PF_BYTE_BGR = PF_B8G8R8, - /// 4 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red and one byte for alpha - PF_BYTE_BGRA = PF_B8G8R8A8, - /// 4 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue, and one byte for alpha - PF_BYTE_RGBA = PF_R8G8B8A8, + /// 3 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue + PF_BYTE_RGB = PF_R8G8B8, + /// 3 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red + PF_BYTE_BGR = PF_B8G8R8, + /// 4 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red and one byte for alpha + PF_BYTE_BGRA = PF_B8G8R8A8, + /// 4 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue, and one byte for alpha + PF_BYTE_RGBA = PF_R8G8B8A8, #else - /// 3 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue - PF_BYTE_RGB = PF_B8G8R8, - /// 3 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red - PF_BYTE_BGR = PF_R8G8B8, - /// 4 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red and one byte for alpha - PF_BYTE_BGRA = PF_A8R8G8B8, - /// 4 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue, and one byte for alpha - PF_BYTE_RGBA = PF_A8B8G8R8, + /// 3 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue + PF_BYTE_RGB = PF_B8G8R8, + /// 3 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red + PF_BYTE_BGR = PF_R8G8B8, + /// 4 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red and one byte for alpha + PF_BYTE_BGRA = PF_A8R8G8B8, + /// 4 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue, and one byte for alpha + PF_BYTE_RGBA = PF_A8B8G8R8, #endif /// 32-bit pixel format, 2 bits for alpha, 10 bits for red, green and blue. PF_A2R10G10B10 = 15, @@ -118,30 +118,30 @@ namespace Ogre { PF_DXT4 = 20, /// DDS (DirectDraw Surface) DXT5 format PF_DXT5 = 21, - /// 16-bit pixel format, 16 bits (float) for red + /// 16-bit pixel format, 16 bits (float) for red PF_FLOAT16_R = 32, /// 48-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue PF_FLOAT16_RGB = 22, /// 64-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue, 16 bits (float) for alpha PF_FLOAT16_RGBA = 23, - // 32-bit pixel format, 32 bits (float) for red + // 32-bit pixel format, 32 bits (float) for red PF_FLOAT32_R = 33, /// 96-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue PF_FLOAT32_RGB = 24, /// 128-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue, 32 bits (float) for alpha PF_FLOAT32_RGBA = 25, - /// 32-bit, 2-channel s10e5 floating point pixel format, 16-bit green, 16-bit red - PF_FLOAT16_GR = 35, - /// 64-bit, 2-channel floating point pixel format, 32-bit green, 32-bit red - PF_FLOAT32_GR = 36, - /// Depth texture format - PF_DEPTH = 29, - /// 64-bit pixel format, 16 bits for red, green, blue and alpha - PF_SHORT_RGBA = 30, - /// 32-bit pixel format, 16-bit green, 16-bit red - PF_SHORT_GR = 34, - /// 48-bit pixel format, 16 bits for red, green and blue - PF_SHORT_RGB = 37, + /// 32-bit, 2-channel s10e5 floating point pixel format, 16-bit green, 16-bit red + PF_FLOAT16_GR = 35, + /// 64-bit, 2-channel floating point pixel format, 32-bit green, 32-bit red + PF_FLOAT32_GR = 36, + /// Depth texture format + PF_DEPTH = 29, + /// 64-bit pixel format, 16 bits for red, green, blue and alpha + PF_SHORT_RGBA = 30, + /// 32-bit pixel format, 16-bit green, 16-bit red + PF_SHORT_GR = 34, + /// 48-bit pixel format, 16 bits for red, green and blue + PF_SHORT_RGB = 37, /// PVRTC (PowerVR) RGB 2 bpp PF_PVRTC_RGB2 = 38, /// PVRTC (PowerVR) RGBA 2 bpp @@ -154,7 +154,7 @@ namespace Ogre { PF_PVRTC2_2BPP = 42, /// PVRTC (PowerVR) Version 2, 4 bpp PF_PVRTC2_4BPP = 43, - /// 32-bit pixel format, 11 bits (float) for red, 11 bits (float) for green, 10 bits (float) for blue + /// 32-bit pixel format, 11 bits (float) for red, 11 bits (float) for green, 10 bits (float) for blue PF_R11G11B10_FLOAT = 44, /// 8-bit pixel format, 8 bits red (unsigned int). PF_R8_UINT = 45, @@ -250,16 +250,16 @@ namespace Ogre { PF_ETC2_RGBA8 = 90, /// ETC2 (Ericsson Texture Compression) PF_ETC2_RGB8A1 = 91, - /// ATC (AMD_compressed_ATC_texture) - PF_ATC_RGB = 92, - /// ATC (AMD_compressed_ATC_texture) - PF_ATC_RGBA_EXPLICIT_ALPHA = 93, - /// ATC (AMD_compressed_ATC_texture) - PF_ATC_RGBA_INTERPOLATED_ALPHA = 94, - // Number of pixel formats currently defined + /// ATC (AMD_compressed_ATC_texture) + PF_ATC_RGB = 92, + /// ATC (AMD_compressed_ATC_texture) + PF_ATC_RGBA_EXPLICIT_ALPHA = 93, + /// ATC (AMD_compressed_ATC_texture) + PF_ATC_RGBA_INTERPOLATED_ALPHA = 94, + // Number of pixel formats currently defined PF_COUNT = 95 }; - typedef vector::type PixelFormatList; + typedef vector::type PixelFormatList; /** * Flags defining some on/off properties of pixel formats @@ -296,101 +296,101 @@ namespace Ogre { PCT_COUNT = 6 /// Number of pixel types }; - /** A primitive describing a volume (3D), image (2D) or line (1D) of pixels in memory. - In case of a rectangle, depth must be 1. - Pixels are stored as a succession of "depth" slices, each containing "height" rows of - "width" pixels. + /** A primitive describing a volume (3D), image (2D) or line (1D) of pixels in memory. + In case of a rectangle, depth must be 1. + Pixels are stored as a succession of "depth" slices, each containing "height" rows of + "width" pixels. */ class _OgreExport PixelBox: public Box, public ImageAlloc { public: - /// Parameter constructor for setting the members manually - PixelBox() {} - ~PixelBox() {} - /** Constructor providing extents in the form of a Box object. This constructor - assumes the pixel data is laid out consecutively in memory. (this - means row after row, slice after slice, with no space in between) - @param extents Extents of the region defined by data - @param pixelFormat Format of this buffer - @param pixelData Pointer to the actual data - */ - PixelBox(const Box &extents, PixelFormat pixelFormat, void *pixelData=0): - Box(extents), data(pixelData), format(pixelFormat) - { - setConsecutive(); - } - /** Constructor providing width, height and depth. This constructor - assumes the pixel data is laid out consecutively in memory. (this - means row after row, slice after slice, with no space in between) - @param width Width of the region - @param height Height of the region - @param depth Depth of the region - @param pixelFormat Format of this buffer - @param pixelData Pointer to the actual data - */ - PixelBox(uint32 width, uint32 height, uint32 depth, PixelFormat pixelFormat, void *pixelData=0): - Box(0, 0, 0, width, height, depth), - data(pixelData), format(pixelFormat) - { - setConsecutive(); - } - + /// Parameter constructor for setting the members manually + PixelBox() {} + ~PixelBox() {} + /** Constructor providing extents in the form of a Box object. This constructor + assumes the pixel data is laid out consecutively in memory. (this + means row after row, slice after slice, with no space in between) + @param extents Extents of the region defined by data + @param pixelFormat Format of this buffer + @param pixelData Pointer to the actual data + */ + PixelBox(const Box &extents, PixelFormat pixelFormat, void *pixelData=0): + Box(extents), data(pixelData), format(pixelFormat) + { + setConsecutive(); + } + /** Constructor providing width, height and depth. This constructor + assumes the pixel data is laid out consecutively in memory. (this + means row after row, slice after slice, with no space in between) + @param width Width of the region + @param height Height of the region + @param depth Depth of the region + @param pixelFormat Format of this buffer + @param pixelData Pointer to the actual data + */ + PixelBox(uint32 width, uint32 height, uint32 depth, PixelFormat pixelFormat, void *pixelData=0): + Box(0, 0, 0, width, height, depth), + data(pixelData), format(pixelFormat) + { + setConsecutive(); + } + /// The data pointer void *data; /// The pixel format PixelFormat format; /** Number of elements between the leftmost pixel of one row and the left - pixel of the next. This value must always be equal to getWidth() (consecutive) - for compressed formats. + pixel of the next. This value must always be equal to getWidth() (consecutive) + for compressed formats. */ size_t rowPitch; /** Number of elements between the top left pixel of one (depth) slice and - the top left pixel of the next. This can be a negative value. Must be a multiple of - rowPitch. This value must always be equal to getWidth()*getHeight() (consecutive) - for compressed formats. + the top left pixel of the next. This can be a negative value. Must be a multiple of + rowPitch. This value must always be equal to getWidth()*getHeight() (consecutive) + for compressed formats. */ size_t slicePitch; /** Set the rowPitch and slicePitch so that the buffer is laid out consecutive - in memory. + in memory. */ void setConsecutive() { rowPitch = getWidth(); slicePitch = getWidth()*getHeight(); } - /** Get the number of elements between one past the rightmost pixel of - one row and the leftmost pixel of the next row. (IE this is zero if rows - are consecutive). + /** Get the number of elements between one past the rightmost pixel of + one row and the leftmost pixel of the next row. (IE this is zero if rows + are consecutive). */ size_t getRowSkip() const { return rowPitch - getWidth(); } /** Get the number of elements between one past the right bottom pixel of - one slice and the left top pixel of the next slice. (IE this is zero if slices - are consecutive). + one slice and the left top pixel of the next slice. (IE this is zero if slices + are consecutive). */ size_t getSliceSkip() const { return slicePitch - (getHeight() * rowPitch); } /** Return whether this buffer is laid out consecutive in memory (ie the pitches - are equal to the dimensions) + are equal to the dimensions) */ bool isConsecutive() const - { - return rowPitch == getWidth() && slicePitch == getWidth()*getHeight(); - } + { + return rowPitch == getWidth() && slicePitch == getWidth()*getHeight(); + } /** Return the size (in bytes) this image would take if it was - laid out consecutive in memory - */ - size_t getConsecutiveSize() const; - /** Return a subvolume of this PixelBox. - @param def Defines the bounds of the subregion to return - @return A pixel box describing the region and the data in it - @remarks This function does not copy any data, it just returns - a PixelBox object with a data pointer pointing somewhere inside - the data of object. - @throws Exception(ERR_INVALIDPARAMS) if def is not fully contained - */ - PixelBox getSubVolume(const Box &def) const; + laid out consecutive in memory + */ + size_t getConsecutiveSize() const; + /** Return a subvolume of this PixelBox. + @param def Defines the bounds of the subregion to return + @return A pixel box describing the region and the data in it + @remarks This function does not copy any data, it just returns + a PixelBox object with a data pointer pointing somewhere inside + the data of object. + @throws Exception(ERR_INVALIDPARAMS) if def is not fully contained + */ + PixelBox getSubVolume(const Box &def) const; - /** Return a data pointer pointing to top left front pixel of the pixel box. + /** Return a data pointer pointing to top left front pixel of the pixel box. @remarks Non consecutive pixel boxes are supported. */ void* getTopLeftFrontPixelPtr() const; @@ -432,25 +432,25 @@ namespace Ogre { */ static size_t getNumElemBits( PixelFormat format ); - /** Returns the size in memory of a region with the given extents and pixel - format with consecutive memory layout. - @param width - The width of the area - @param height - The height of the area - @param depth - The depth of the area - @param format - The format of the area - @return - The size in bytes - @remarks - In case that the format is non-compressed, this simply returns - width*height*depth*PixelUtil::getNumElemBytes(format). In the compressed - case, this does serious magic. - */ - static size_t getMemorySize(uint32 width, uint32 height, uint32 depth, PixelFormat format); - + /** Returns the size in memory of a region with the given extents and pixel + format with consecutive memory layout. + @param width + The width of the area + @param height + The height of the area + @param depth + The depth of the area + @param format + The format of the area + @return + The size in bytes + @remarks + In case that the format is non-compressed, this simply returns + width*height*depth*PixelUtil::getNumElemBytes(format). In the compressed + case, this does serious magic. + */ + static size_t getMemorySize(uint32 width, uint32 height, uint32 depth, PixelFormat format); + /** Returns the property flags for this pixel format @return A bitfield combination of PFF_HASALPHA, PFF_ISCOMPRESSED, @@ -474,35 +474,35 @@ namespace Ogre { static bool isNativeEndian(PixelFormat format); /** Shortcut method to determine if the format is a luminance format. */ static bool isLuminance(PixelFormat format); - - /** Return whether a certain image extent is valid for this image format. - @param width - The width of the area - @param height - The height of the area - @param depth - The depth of the area - @param format - The format of the area - @remarks For non-compressed formats, this is always true. For DXT formats, - only sizes with a width and height multiple of 4 and depth 1 are allowed. - */ - static bool isValidExtent(size_t width, size_t height, size_t depth, PixelFormat format); + + /** Return whether a certain image extent is valid for this image format. + @param width + The width of the area + @param height + The height of the area + @param depth + The depth of the area + @param format + The format of the area + @remarks For non-compressed formats, this is always true. For DXT formats, + only sizes with a width and height multiple of 4 and depth 1 are allowed. + */ + static bool isValidExtent(size_t width, size_t height, size_t depth, PixelFormat format); /** Gives the number of bits (RGBA) for a format. See remarks. @remarks For non-colour formats (dxt, depth) this returns [0,0,0,0]. */ static void getBitDepths(PixelFormat format, int rgba[4]); - /** Gives the masks for the R, G, B and A component - @note Only valid for native endian formats + /** Gives the masks for the R, G, B and A component + @note Only valid for native endian formats */ static void getBitMasks(PixelFormat format, uint64 rgba[4]); - /** Gives the bit shifts for R, G, B and A component - @note Only valid for native endian formats - */ - static void getBitShifts(PixelFormat format, unsigned char rgba[4]); + /** Gives the bit shifts for R, G, B and A component + @note Only valid for native endian formats + */ + static void getBitShifts(PixelFormat format, unsigned char rgba[4]); /** Gets the name of an image format */ @@ -558,44 +558,44 @@ namespace Ogre { static PixelFormat getFormatForBitDepths(PixelFormat fmt, ushort integerBits, ushort floatBits); /** Pack a colour value to memory - @param colour The colour - @param pf Pixelformat in which to write the colour - @param dest Destination memory location + @param colour The colour + @param pf Pixelformat in which to write the colour + @param dest Destination memory location */ static void packColour(const ColourValue &colour, const PixelFormat pf, void* dest); /** Pack a colour value to memory - @param r,g,b,a The four colour components, range 0.0f to 1.0f + @param r,g,b,a The four colour components, range 0.0f to 1.0f (an exception to this case exists for floating point pixel formats, which don't clamp to 0.0f..1.0f) - @param pf Pixelformat in which to write the colour - @param dest Destination memory location + @param pf Pixelformat in which to write the colour + @param dest Destination memory location */ static void packColour(const uint8 r, const uint8 g, const uint8 b, const uint8 a, const PixelFormat pf, void* dest); /** Pack a colour value to memory - @param r,g,b,a The four colour components, range 0.0f to 1.0f - (an exception to this case exists for floating point pixel - formats, which don't clamp to 0.0f..1.0f) - @param pf Pixelformat in which to write the colour - @param dest Destination memory location + @param r,g,b,a The four colour components, range 0.0f to 1.0f + (an exception to this case exists for floating point pixel + formats, which don't clamp to 0.0f..1.0f) + @param pf Pixelformat in which to write the colour + @param dest Destination memory location */ static void packColour(const float r, const float g, const float b, const float a, const PixelFormat pf, void* dest); /** Unpack a colour value from memory - @param colour The colour is returned here - @param pf Pixelformat in which to read the colour - @param src Source memory location + @param colour The colour is returned here + @param pf Pixelformat in which to read the colour + @param src Source memory location */ static void unpackColour(ColourValue *colour, PixelFormat pf, const void* src); /** Unpack a colour value from memory - @param r The red channel is returned here (as byte) + @param r The red channel is returned here (as byte) @param g The blue channel is returned here (as byte) @param b The green channel is returned here (as byte) @param a The alpha channel is returned here (as byte) - @param pf Pixelformat in which to read the colour - @param src Source memory location - @remarks This function returns the colour components in 8 bit precision, - this will lose precision when coming from PF_A2R10G10B10 or floating - point formats. + @param pf Pixelformat in which to read the colour + @param src Source memory location + @remarks This function returns the colour components in 8 bit precision, + this will lose precision when coming from PF_A2R10G10B10 or floating + point formats. */ static void unpackColour(uint8 *r, uint8 *g, uint8 *b, uint8 *a, PixelFormat pf, const void* src); /** Unpack a colour value from memory @@ -603,38 +603,38 @@ namespace Ogre { @param g The blue channel is returned here (as float) @param b The green channel is returned here (as float) @param a The alpha channel is returned here (as float) - @param pf Pixelformat in which to read the colour - @param src Source memory location + @param pf Pixelformat in which to read the colour + @param src Source memory location */ static void unpackColour(float *r, float *g, float *b, float *a, PixelFormat pf, const void* src); /** Convert consecutive pixels from one format to another. No dithering or filtering is being done. - Converting from RGB to luminance takes the R channel. In case the source and destination format match, - just a copy is done. - @param src Pointer to source region - @param srcFormat Pixel format of source region - @param dst Pointer to destination region - @param dstFormat Pixel format of destination region + Converting from RGB to luminance takes the R channel. In case the source and destination format match, + just a copy is done. + @param src Pointer to source region + @param srcFormat Pixel format of source region + @param dst Pointer to destination region + @param dstFormat Pixel format of destination region */ static void bulkPixelConversion(void *src, PixelFormat srcFormat, void *dst, PixelFormat dstFormat, unsigned int count); - /** Convert pixels from one format to another. No dithering or filtering is being done. Converting - from RGB to luminance takes the R channel. - @param src PixelBox containing the source pixels, pitches and format - @param dst PixelBox containing the destination pixels, pitches and format - @remarks The source and destination boxes must have the same - dimensions. In case the source and destination format match, a plain copy is done. + /** Convert pixels from one format to another. No dithering or filtering is being done. Converting + from RGB to luminance takes the R channel. + @param src PixelBox containing the source pixels, pitches and format + @param dst PixelBox containing the destination pixels, pitches and format + @remarks The source and destination boxes must have the same + dimensions. In case the source and destination format match, a plain copy is done. */ static void bulkPixelConversion(const PixelBox &src, const PixelBox &dst); - /** Flips pixels inplace in vertical direction. - @param box PixelBox containing pixels, pitches and format + /** Flips pixels inplace in vertical direction. + @param box PixelBox containing pixels, pitches and format @remarks Non consecutive pixel boxes are supported. */ static void bulkPixelVerticalFlip(const PixelBox &box); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePixelFormatDescriptions.h b/OgreMain/include/OgrePixelFormatDescriptions.h index ceece0f1099..a2f4e5972ce 100644 --- a/OgreMain/include/OgrePixelFormatDescriptions.h +++ b/OgreMain/include/OgrePixelFormatDescriptions.h @@ -1352,8 +1352,8 @@ namespace Ogre { 0, 0, 0, 0, 0, 0, 0, 0 } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePlane.h b/OgreMain/include/OgrePlane.h index 25bc8fb0f27..2e6783d21e3 100644 --- a/OgreMain/include/OgrePlane.h +++ b/OgreMain/include/OgrePlane.h @@ -42,13 +42,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Defines a plane in 3D space. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Defines a plane in 3D space. @remarks A plane is defined in 3D space by the equation Ax + By + Cz + D = 0 @@ -67,8 +67,8 @@ namespace Ogre { Plane (const Plane& rhs); /** Construct a plane through a normal, and a distance to move the plane along the normal.*/ Plane (const Vector3& rkNormal, Real fConstant); - /** Construct a plane using the 4 constants directly **/ - Plane (Real a, Real b, Real c, Real d); + /** Construct a plane using the 4 constants directly **/ + Plane (Real a, Real b, Real c, Real d); Plane (const Vector3& rkNormal, const Vector3& rkPoint); Plane (const Vector3& rkPoint0, const Vector3& rkPoint1, const Vector3& rkPoint2); @@ -118,17 +118,17 @@ namespace Ogre { void redefine(const Vector3& rkPoint0, const Vector3& rkPoint1, const Vector3& rkPoint2); - /** Redefine this plane based on a normal and a point. */ - void redefine(const Vector3& rkNormal, const Vector3& rkPoint); + /** Redefine this plane based on a normal and a point. */ + void redefine(const Vector3& rkNormal, const Vector3& rkPoint); - /** Project a vector onto the plane. - @remarks This gives you the element of the input vector that is perpendicular - to the normal of the plane. You can get the element which is parallel - to the normal of the plane by subtracting the result of this method - from the original vector, since parallel + perpendicular = original. - @param v The input vector - */ - Vector3 projectVector(const Vector3& v) const; + /** Project a vector onto the plane. + @remarks This gives you the element of the input vector that is perpendicular + to the normal of the plane. You can get the element which is parallel + to the normal of the plane by subtracting the result of this method + from the original vector, since parallel + perpendicular = original. + @param v The input vector + */ + Vector3 projectVector(const Vector3& v) const; /** Normalises the plane. @remarks @@ -141,7 +141,7 @@ namespace Ogre { */ Real normalise(void); - Vector3 normal; + Vector3 normal; Real d; /// Comparison operator @@ -158,8 +158,8 @@ namespace Ogre { }; typedef vector::type PlaneList; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace Ogre diff --git a/OgreMain/include/OgrePlaneBoundedVolume.h b/OgreMain/include/OgrePlaneBoundedVolume.h index 72dc202b363..488a5284197 100644 --- a/OgreMain/include/OgrePlaneBoundedVolume.h +++ b/OgreMain/include/OgrePlaneBoundedVolume.h @@ -38,13 +38,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Represents a convex volume bounded by planes. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Represents a convex volume bounded by planes. */ class _OgreExport PlaneBoundedVolume { @@ -127,8 +127,8 @@ namespace Ogre { typedef vector::type PlaneBoundedVolumeList; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePlatform.h b/OgreMain/include/OgrePlatform.h index 2f4a869207d..b8dde4305ce 100644 --- a/OgreMain/include/OgrePlatform.h +++ b/OgreMain/include/OgrePlatform.h @@ -63,7 +63,7 @@ namespace Ogre { #elif defined( __GCCE__ ) # define OGRE_COMPILER OGRE_COMPILER_GCCE # define OGRE_COMP_VER _MSC_VER -//# include // This is a GCCE toolchain workaround needed when compiling with GCCE +//# include // This is a GCCE toolchain workaround needed when compiling with GCCE #elif defined( __WINSCW__ ) # define OGRE_COMPILER OGRE_COMPILER_WINSCW # define OGRE_COMP_VER _MSC_VER @@ -104,33 +104,33 @@ namespace Ogre { /* Finds the current platform */ #if (defined( __WIN32__ ) || defined( _WIN32 )) && !defined(__ANDROID__) -# if defined(WINAPI_FAMILY) -# define __OGRE_HAVE_DIRECTXMATH 1 -# include -# if WINAPI_FAMILY == WINAPI_FAMILY_APP|| WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP -# define DESKTOP_APP 1 -# define PHONE 2 -# define OGRE_PLATFORM OGRE_PLATFORM_WINRT +# if defined(WINAPI_FAMILY) +# define __OGRE_HAVE_DIRECTXMATH 1 +# include +# if WINAPI_FAMILY == WINAPI_FAMILY_APP|| WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +# define DESKTOP_APP 1 +# define PHONE 2 +# define OGRE_PLATFORM OGRE_PLATFORM_WINRT # ifndef _CRT_SECURE_NO_WARNINGS # define _CRT_SECURE_NO_WARNINGS # endif # ifndef _SCL_SECURE_NO_WARNINGS # define _SCL_SECURE_NO_WARNINGS # endif -# if WINAPI_FAMILY == WINAPI_FAMILY_APP -# define OGRE_WINRT_TARGET_TYPE DESKTOP_APP -# endif -# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP -# define OGRE_WINRT_TARGET_TYPE PHONE -# endif -# else -# define OGRE_PLATFORM OGRE_PLATFORM_WIN32 -# endif -# else -# define OGRE_PLATFORM OGRE_PLATFORM_WIN32 -# endif +# if WINAPI_FAMILY == WINAPI_FAMILY_APP +# define OGRE_WINRT_TARGET_TYPE DESKTOP_APP +# endif +# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +# define OGRE_WINRT_TARGET_TYPE PHONE +# endif +# else +# define OGRE_PLATFORM OGRE_PLATFORM_WIN32 +# endif +# else +# define OGRE_PLATFORM OGRE_PLATFORM_WIN32 +# endif #elif defined(__FLASHCC__) -# define OGRE_PLATFORM OGRE_PLATFORM_FLASHCC +# define OGRE_PLATFORM OGRE_PLATFORM_FLASHCC #elif defined( __APPLE_CC__) // Device Simulator // Both requiring OS version 6.0 or greater @@ -140,7 +140,7 @@ namespace Ogre { # define OGRE_PLATFORM OGRE_PLATFORM_APPLE # endif #elif defined(__ANDROID__) -# define OGRE_PLATFORM OGRE_PLATFORM_ANDROID +# define OGRE_PLATFORM OGRE_PLATFORM_ANDROID #elif defined( __native_client__ ) # define OGRE_PLATFORM OGRE_PLATFORM_NACL # ifndef OGRE_STATIC_LIB @@ -189,22 +189,22 @@ namespace Ogre { // If we're not including this from a client build, specify that the stuff // should get exported. Otherwise, import it. -# if defined( OGRE_STATIC_LIB ) - // Linux compilers don't have symbol import/export directives. -# define _OgreExport -# define _OgrePrivate +# if defined( OGRE_STATIC_LIB ) + // Linux compilers don't have symbol import/export directives. +# define _OgreExport +# define _OgrePrivate # else -# if defined( OGRE_NONCLIENT_BUILD ) -# define _OgreExport __declspec( dllexport ) -# else +# if defined( OGRE_NONCLIENT_BUILD ) +# define _OgreExport __declspec( dllexport ) +# else # if defined( __MINGW32__ ) # define _OgreExport # else -# define _OgreExport __declspec( dllimport ) +# define _OgreExport __declspec( dllimport ) # endif -# endif -# define _OgrePrivate -# endif +# endif +# define _OgrePrivate +# endif // Win32 compilers use _DEBUG for specifying debug builds. // for MinGW, we set DEBUG # if defined(_DEBUG) || defined(DEBUG) @@ -273,7 +273,7 @@ namespace Ogre { # ifdef OGRE_UNICODE_SUPPORT # undef OGRE_UNICODE_SUPPORT # endif -# define OGRE_UNICODE_SUPPORT 1 +# define OGRE_UNICODE_SUPPORT 1 // A quick define to overcome different names for the same function # define stricmp strcasecmp # ifdef DEBUG @@ -282,7 +282,7 @@ namespace Ogre { # define OGRE_DEBUG_MODE 0 # endif # ifndef CLOCKS_PER_SEC -# define CLOCKS_PER_SEC 1000 +# define CLOCKS_PER_SEC 1000 # endif #endif @@ -292,7 +292,7 @@ namespace Ogre { # ifdef OGRE_UNICODE_SUPPORT # undef OGRE_UNICODE_SUPPORT # endif -# define OGRE_UNICODE_SUPPORT 0 +# define OGRE_UNICODE_SUPPORT 0 # ifdef DEBUG # define OGRE_DEBUG_MODE 1 # else @@ -316,26 +316,26 @@ namespace Ogre { //---------------------------------------------------------------------------- // Set the default locale for strings #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID -// Locales are not supported by the C lib you have to go through JNI. -# define OGRE_DEFAULT_LOCALE "" +// Locales are not supported by the C lib you have to go through JNI. +# define OGRE_DEFAULT_LOCALE "" #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS -# define OGRE_DEFAULT_LOCALE "C" +# define OGRE_DEFAULT_LOCALE "C" #elif defined(__MINGW32__) -# define OGRE_DEFAULT_LOCALE "C" +# define OGRE_DEFAULT_LOCALE "C" #else -# if OGRE_COMPILER == OGRE_COMPILER_MSVC -# if _MSC_VER >= 1700 -# define OGRE_DEFAULT_LOCALE "en-GB" -# else -// http://msdn.microsoft.com/en-us/library/39cwe7zf%28v=vs.90%29.aspx -# define OGRE_DEFAULT_LOCALE "uk" -# endif -# elif OGRE_COMPILER == OGRE_COMPILER_GCCE -// http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html -# define OGRE_DEFAULT_LOCALE "en_GB.UTF8" -# else +# if OGRE_COMPILER == OGRE_COMPILER_MSVC +# if _MSC_VER >= 1700 +# define OGRE_DEFAULT_LOCALE "en-GB" +# else +// http://msdn.microsoft.com/en-us/library/39cwe7zf%28v=vs.90%29.aspx +# define OGRE_DEFAULT_LOCALE "uk" +# endif +# elif OGRE_COMPILER == OGRE_COMPILER_GCCE +// http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html +# define OGRE_DEFAULT_LOCALE "en_GB.UTF8" +# else # define OGRE_DEFAULT_LOCALE "en_GB.UTF-8" -# endif +# endif #endif //---------------------------------------------------------------------------- @@ -356,11 +356,11 @@ typedef short int16; typedef signed char int8; // define uint64 type #if OGRE_COMPILER == OGRE_COMPILER_MSVC - typedef unsigned __int64 uint64; - typedef __int64 int64; + typedef unsigned __int64 uint64; + typedef __int64 int64; #else - typedef unsigned long long uint64; - typedef long long int64; + typedef unsigned long long uint64; + typedef long long int64; #endif // Disable these warnings (too much noise) diff --git a/OgreMain/include/OgrePlatformInformation.h b/OgreMain/include/OgrePlatformInformation.h index c018bab63cf..81a379256b0 100644 --- a/OgreMain/include/OgrePlatformInformation.h +++ b/OgreMain/include/OgrePlatformInformation.h @@ -52,13 +52,13 @@ namespace Ogre { #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && defined(__BIG_ENDIAN__) # define OGRE_CPU OGRE_CPU_PPC #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE -# define OGRE_CPU OGRE_CPU_X86 +# define OGRE_CPU OGRE_CPU_X86 #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS && (defined(__i386__) || defined(__x86_64__)) -# define OGRE_CPU OGRE_CPU_X86 +# define OGRE_CPU OGRE_CPU_X86 #elif defined(__arm__) || defined(_M_ARM) || defined(__arm64__) || defined(_aarch64_) -# define OGRE_CPU OGRE_CPU_ARM +# define OGRE_CPU OGRE_CPU_ARM #elif defined(__mips64) || defined(__mips64_) -# define OGRE_CPU OGRE_CPU_MIPS +# define OGRE_CPU OGRE_CPU_MIPS #else # define OGRE_CPU OGRE_CPU_UNKNOWN #endif @@ -132,12 +132,12 @@ namespace Ogre { # define __OGRE_HAVE_MSA 0 #endif - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ /** Class which provides the run-time platform information Ogre runs on. @@ -197,20 +197,20 @@ namespace Ogre { */ static uint getCpuFeatures(void); - /** Gets whether a specific feature is supported by the CPU. - @note - Actual detecting are performs in the first time call to this function, - and then all future calls with return internal cached value. - */ - static bool hasCpuFeature(CpuFeatures feature); + /** Gets whether a specific feature is supported by the CPU. + @note + Actual detecting are performs in the first time call to this function, + and then all future calls with return internal cached value. + */ + static bool hasCpuFeature(CpuFeatures feature); - /** Write the CPU information to the passed in Log */ - static void log(Log* pLog); + /** Write the CPU information to the passed in Log */ + static void log(Log* pLog); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePlugin.h b/OgreMain/include/OgrePlugin.h index e606a10b945..811e36be416 100644 --- a/OgreMain/include/OgrePlugin.h +++ b/OgreMain/include/OgrePlugin.h @@ -32,105 +32,105 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** Class defining a generic OGRE plugin. - @remarks - OGRE is very plugin-oriented and you can customise much of its behaviour - by registering new plugins, dynamically if you are using dynamic linking. - This class abstracts the generic interface that all plugins must support. - Within the implementations of this interface, the plugin must call other - OGRE classes in order to register the detailed customisations it is - providing, e.g. registering a new SceneManagerFactory, a new - MovableObjectFactory, or a new RenderSystem. - @par - Plugins can be linked statically or dynamically. If they are linked - dynamically (ie the plugin is in a DLL or Shared Object file), then you - load the plugin by calling the Root::loadPlugin method (or some other - mechanism which leads to that call, e.g. plugins.cfg), passing the name of - the DLL. OGRE will then call a global init function on that DLL, and it - will be expected to register one or more Plugin implementations using - Root::installPlugin. The procedure is very similar if you use a static - linked plugin, except that you simply instantiate the Plugin implementation - yourself and pass it to Root::installPlugin. - @note - Lifecycle of a Plugin instance is very important. The Plugin instance must - remain valid until the Plugin is uninstalled. Here are the things you - must bear in mind: -
      • If your plugin is in a DLL: -
        • Create the Plugin instance and call Root::installPlugin in dllStartPlugin
        • -
        • Call Root::uninstallPlugin, then delete it in dllStopPlugin
        -
      • If your plugin is statically linked in your app: -
        • Create the Plugin anytime you like
        • -
        • Call Root::installPlugin any time whilst Root is valid
        • -
        • Call Root::uninstallPlugin if you like so long as Root is valid. However, - it will be done for you when Root is destroyed, so the Plugin instance must - still be valid at that point if you haven't manually uninstalled it.
        -
      - The install and uninstall methods will be called when the plugin is - installed or uninstalled. The initialise and shutdown will be called when - there is a system initialisation or shutdown, e.g. when Root::initialise - or Root::shutdown are called. - */ - class _OgreExport Plugin : public PluginAlloc - { - public: - Plugin() {} - virtual ~Plugin() {} + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** Class defining a generic OGRE plugin. + @remarks + OGRE is very plugin-oriented and you can customise much of its behaviour + by registering new plugins, dynamically if you are using dynamic linking. + This class abstracts the generic interface that all plugins must support. + Within the implementations of this interface, the plugin must call other + OGRE classes in order to register the detailed customisations it is + providing, e.g. registering a new SceneManagerFactory, a new + MovableObjectFactory, or a new RenderSystem. + @par + Plugins can be linked statically or dynamically. If they are linked + dynamically (ie the plugin is in a DLL or Shared Object file), then you + load the plugin by calling the Root::loadPlugin method (or some other + mechanism which leads to that call, e.g. plugins.cfg), passing the name of + the DLL. OGRE will then call a global init function on that DLL, and it + will be expected to register one or more Plugin implementations using + Root::installPlugin. The procedure is very similar if you use a static + linked plugin, except that you simply instantiate the Plugin implementation + yourself and pass it to Root::installPlugin. + @note + Lifecycle of a Plugin instance is very important. The Plugin instance must + remain valid until the Plugin is uninstalled. Here are the things you + must bear in mind: +
      • If your plugin is in a DLL: +
        • Create the Plugin instance and call Root::installPlugin in dllStartPlugin
        • +
        • Call Root::uninstallPlugin, then delete it in dllStopPlugin
        +
      • If your plugin is statically linked in your app: +
        • Create the Plugin anytime you like
        • +
        • Call Root::installPlugin any time whilst Root is valid
        • +
        • Call Root::uninstallPlugin if you like so long as Root is valid. However, + it will be done for you when Root is destroyed, so the Plugin instance must + still be valid at that point if you haven't manually uninstalled it.
        +
      + The install and uninstall methods will be called when the plugin is + installed or uninstalled. The initialise and shutdown will be called when + there is a system initialisation or shutdown, e.g. when Root::initialise + or Root::shutdown are called. + */ + class _OgreExport Plugin : public PluginAlloc + { + public: + Plugin() {} + virtual ~Plugin() {} - /** Get the name of the plugin. - @remarks An implementation must be supplied for this method to uniquely - identify the plugin. - */ - virtual const String& getName() const = 0; + /** Get the name of the plugin. + @remarks An implementation must be supplied for this method to uniquely + identify the plugin. + */ + virtual const String& getName() const = 0; - /** Perform the plugin initial installation sequence. - @remarks An implementation must be supplied for this method. It must perform - the startup tasks necessary to install any rendersystem customisations - or anything else that is not dependent on system initialisation, ie - only dependent on the core of Ogre. It must not perform any - operations that would create rendersystem-specific objects at this stage, - that should be done in initialise(). - */ - virtual void install() = 0; + /** Perform the plugin initial installation sequence. + @remarks An implementation must be supplied for this method. It must perform + the startup tasks necessary to install any rendersystem customisations + or anything else that is not dependent on system initialisation, ie + only dependent on the core of Ogre. It must not perform any + operations that would create rendersystem-specific objects at this stage, + that should be done in initialise(). + */ + virtual void install() = 0; - /** Perform any tasks the plugin needs to perform on full system - initialisation. - @remarks An implementation must be supplied for this method. It is called - just after the system is fully initialised (either after Root::initialise - if a window is created then, or after the first window is created) - and therefore all rendersystem functionality is available at this - time. You can use this hook to create any resources which are - dependent on a rendersystem or have rendersystem-specific implementations. - */ - virtual void initialise() = 0; + /** Perform any tasks the plugin needs to perform on full system + initialisation. + @remarks An implementation must be supplied for this method. It is called + just after the system is fully initialised (either after Root::initialise + if a window is created then, or after the first window is created) + and therefore all rendersystem functionality is available at this + time. You can use this hook to create any resources which are + dependent on a rendersystem or have rendersystem-specific implementations. + */ + virtual void initialise() = 0; - /** Perform any tasks the plugin needs to perform when the system is shut down. - @remarks An implementation must be supplied for this method. - This method is called just before key parts of the system are unloaded, - such as rendersystems being shut down. You should use this hook to free up - resources and decouple custom objects from the OGRE system, whilst all the - instances of other plugins (e.g. rendersystems) still exist. - */ - virtual void shutdown() = 0; + /** Perform any tasks the plugin needs to perform when the system is shut down. + @remarks An implementation must be supplied for this method. + This method is called just before key parts of the system are unloaded, + such as rendersystems being shut down. You should use this hook to free up + resources and decouple custom objects from the OGRE system, whilst all the + instances of other plugins (e.g. rendersystems) still exist. + */ + virtual void shutdown() = 0; - /** Perform the final plugin uninstallation sequence. - @remarks An implementation must be supplied for this method. It must perform - the cleanup tasks which haven't already been performed in shutdown() - (e.g. final deletion of custom instances, if you kept them around incase - the system was reinitialised). At this stage you cannot be sure what other - plugins are still loaded or active. It must therefore not perform any - operations that would reference any rendersystem-specific objects - those - should have been sorted out in the 'shutdown' method. - */ - virtual void uninstall() = 0; - }; - /** @} */ - /** @} */ + /** Perform the final plugin uninstallation sequence. + @remarks An implementation must be supplied for this method. It must perform + the cleanup tasks which haven't already been performed in shutdown() + (e.g. final deletion of custom instances, if you kept them around incase + the system was reinitialised). At this stage you cannot be sure what other + plugins are still loaded or active. It must therefore not perform any + operations that would reference any rendersystem-specific objects - those + should have been sorted out in the 'shutdown' method. + */ + virtual void uninstall() = 0; + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePolygon.h b/OgreMain/include/OgrePolygon.h index 211fc116560..a87717adcda 100644 --- a/OgreMain/include/OgrePolygon.h +++ b/OgreMain/include/OgrePolygon.h @@ -5,7 +5,7 @@ This source file is part of OGRE For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd -Copyright (c) 2006 Matthias Fink, netAllied GmbH +Copyright (c) 2006 Matthias Fink, netAllied GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -38,108 +38,108 @@ namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** The class represents a polygon in 3D space. - @remarks - It is made up of 3 or more vertices in a single plane, listed in - counter-clockwise order. - */ - class _OgreExport Polygon - { - - public: - typedef vector::type VertexList; - - typedef multimap::type EdgeMap; - typedef std::pair< Vector3, Vector3> Edge; - - protected: - VertexList mVertexList; - mutable Vector3 mNormal; - mutable bool mIsNormalSet; - /** Updates the normal. - */ - void updateNormal(void) const; - - - public: - Polygon(); - ~Polygon(); - Polygon( const Polygon& cpy ); - - /** Inserts a vertex at a specific position. - @note Vertices must be coplanar. - */ - void insertVertex(const Vector3& vdata, size_t vertexIndex); - /** Inserts a vertex at the end of the polygon. - @note Vertices must be coplanar. - */ - void insertVertex(const Vector3& vdata); - - /** Returns a vertex. - */ - const Vector3& getVertex(size_t vertex) const; - - /** Sets a specific vertex of a polygon. - @note Vertices must be coplanar. - */ - void setVertex(const Vector3& vdata, size_t vertexIndex); - - /** Removes duplicate vertices from a polygon. - */ - void removeDuplicates(void); - - /** Vertex count. - */ - size_t getVertexCount(void) const; - - /** Returns the polygon normal. - */ - const Vector3& getNormal(void) const; - - /** Deletes a specific vertex. - */ - void deleteVertex(size_t vertex); - - /** Determines if a point is inside the polygon. - @remarks - A point is inside a polygon if it is both on the polygon's plane, - and within the polygon's bounds. Polygons are assumed to be convex - and planar. - */ - bool isPointInside(const Vector3& point) const; - - /** Stores the edges of the polygon in ccw order. - The vertices are copied so the user has to take the - deletion into account. - */ - void storeEdges(EdgeMap *edgeMap) const; - - /** Resets the object. - */ - void reset(void); - - /** Determines if the current object is equal to the compared one. - */ - bool operator == (const Polygon& rhs) const; - - /** Determines if the current object is not equal to the compared one. - */ - bool operator != (const Polygon& rhs) const - { return !( *this == rhs ); } - - /** Prints out the polygon data. - */ - _OgreExport friend std::ostream& operator<< ( std::ostream& strm, const Polygon& poly ); - - }; - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** The class represents a polygon in 3D space. + @remarks + It is made up of 3 or more vertices in a single plane, listed in + counter-clockwise order. + */ + class _OgreExport Polygon + { + + public: + typedef vector::type VertexList; + + typedef multimap::type EdgeMap; + typedef std::pair< Vector3, Vector3> Edge; + + protected: + VertexList mVertexList; + mutable Vector3 mNormal; + mutable bool mIsNormalSet; + /** Updates the normal. + */ + void updateNormal(void) const; + + + public: + Polygon(); + ~Polygon(); + Polygon( const Polygon& cpy ); + + /** Inserts a vertex at a specific position. + @note Vertices must be coplanar. + */ + void insertVertex(const Vector3& vdata, size_t vertexIndex); + /** Inserts a vertex at the end of the polygon. + @note Vertices must be coplanar. + */ + void insertVertex(const Vector3& vdata); + + /** Returns a vertex. + */ + const Vector3& getVertex(size_t vertex) const; + + /** Sets a specific vertex of a polygon. + @note Vertices must be coplanar. + */ + void setVertex(const Vector3& vdata, size_t vertexIndex); + + /** Removes duplicate vertices from a polygon. + */ + void removeDuplicates(void); + + /** Vertex count. + */ + size_t getVertexCount(void) const; + + /** Returns the polygon normal. + */ + const Vector3& getNormal(void) const; + + /** Deletes a specific vertex. + */ + void deleteVertex(size_t vertex); + + /** Determines if a point is inside the polygon. + @remarks + A point is inside a polygon if it is both on the polygon's plane, + and within the polygon's bounds. Polygons are assumed to be convex + and planar. + */ + bool isPointInside(const Vector3& point) const; + + /** Stores the edges of the polygon in ccw order. + The vertices are copied so the user has to take the + deletion into account. + */ + void storeEdges(EdgeMap *edgeMap) const; + + /** Resets the object. + */ + void reset(void); + + /** Determines if the current object is equal to the compared one. + */ + bool operator == (const Polygon& rhs) const; + + /** Determines if the current object is not equal to the compared one. + */ + bool operator != (const Polygon& rhs) const + { return !( *this == rhs ); } + + /** Prints out the polygon data. + */ + _OgreExport friend std::ostream& operator<< ( std::ostream& strm, const Polygon& poly ); + + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePose.h b/OgreMain/include/OgrePose.h index 2ee203973c1..17cbc9fe37e 100644 --- a/OgreMain/include/OgrePose.h +++ b/OgreMain/include/OgrePose.h @@ -36,105 +36,105 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ - /** A pose is a linked set of vertex offsets applying to one set of vertex - data. - @remarks - The target index referred to by the pose has a meaning set by the user - of this class; but for example when used by Mesh it refers to either the - Mesh shared geometry (0) or a SubMesh dedicated geometry (1+). - Pose instances can be referred to by keyframes in VertexAnimationTrack in - order to animate based on blending poses together. - */ - class _OgreExport Pose : public AnimationAlloc - { - public: - /** Constructor - @param target The target vertexdata index (0 for shared, 1+ for - dedicated at the submesh index + 1) - @param name Optional name - */ - Pose(ushort target, const String& name = BLANKSTRING); - virtual ~Pose(); - /// Return the name of the pose (may be blank) - const String& getName(void) const { return mName; } - /// Return the target geometry index of the pose - ushort getTarget(void) const { return mTarget; } - /// A collection of vertex offsets based on the vertex index - typedef map::type VertexOffsetMap; - /// An iterator over the vertex offsets - typedef MapIterator VertexOffsetIterator; - /// An iterator over the vertex offsets - typedef ConstMapIterator ConstVertexOffsetIterator; - /// A collection of normals based on the vertex index - typedef map::type NormalsMap; - /// An iterator over the vertex offsets - typedef MapIterator NormalsIterator; - /// An iterator over the vertex offsets - typedef ConstMapIterator ConstNormalsIterator; - /// Return whether the pose vertices include normals - bool getIncludesNormals() const { return !mNormalsMap.empty(); } - - /** Adds an offset to a vertex for this pose. - @param index The vertex index - @param offset The position offset for this pose - */ - void addVertex(size_t index, const Vector3& offset); - - /** Adds an offset to a vertex and a new normal for this pose. - @param index The vertex index - @param offset The position offset for this pose - */ - void addVertex(size_t index, const Vector3& offset, const Vector3& normal); - - /** Remove a vertex offset. */ - void removeVertex(size_t index); - - /** Clear all vertices. */ - void clearVertices(void); - - /** Gets an iterator over all the vertex offsets. */ - ConstVertexOffsetIterator getVertexOffsetIterator(void) const; - /** Gets an iterator over all the vertex offsets. */ - VertexOffsetIterator getVertexOffsetIterator(void); - /** Gets a const reference to the vertex offsets. */ - const VertexOffsetMap& getVertexOffsets(void) const { return mVertexOffsetMap; } - - /** Gets an iterator over all the vertex offsets. */ - ConstNormalsIterator getNormalsIterator(void) const; - /** Gets an iterator over all the vertex offsets. */ - NormalsIterator getNormalsIterator(void); - /** Gets a const reference to the vertex offsets. */ - const NormalsMap& getNormals(void) const { return mNormalsMap; } - - /** Get a hardware vertex buffer version of the vertex offsets. */ - const HardwareVertexBufferSharedPtr& _getHardwareVertexBuffer(const VertexData* origData) const; - - /** Clone this pose and create another one configured exactly the same - way (only really useful for cloning holders of this class). - */ - Pose* clone(void) const; - protected: - /// Target geometry index - ushort mTarget; - /// Optional name - String mName; - /// Primary storage, sparse vertex use - VertexOffsetMap mVertexOffsetMap; - /// Primary storage, sparse vertex use - NormalsMap mNormalsMap; - /// Derived hardware buffer, covers all vertices - mutable HardwareVertexBufferSharedPtr mBuffer; - }; - typedef vector::type PoseList; - - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ + /** A pose is a linked set of vertex offsets applying to one set of vertex + data. + @remarks + The target index referred to by the pose has a meaning set by the user + of this class; but for example when used by Mesh it refers to either the + Mesh shared geometry (0) or a SubMesh dedicated geometry (1+). + Pose instances can be referred to by keyframes in VertexAnimationTrack in + order to animate based on blending poses together. + */ + class _OgreExport Pose : public AnimationAlloc + { + public: + /** Constructor + @param target The target vertexdata index (0 for shared, 1+ for + dedicated at the submesh index + 1) + @param name Optional name + */ + Pose(ushort target, const String& name = BLANKSTRING); + virtual ~Pose(); + /// Return the name of the pose (may be blank) + const String& getName(void) const { return mName; } + /// Return the target geometry index of the pose + ushort getTarget(void) const { return mTarget; } + /// A collection of vertex offsets based on the vertex index + typedef map::type VertexOffsetMap; + /// An iterator over the vertex offsets + typedef MapIterator VertexOffsetIterator; + /// An iterator over the vertex offsets + typedef ConstMapIterator ConstVertexOffsetIterator; + /// A collection of normals based on the vertex index + typedef map::type NormalsMap; + /// An iterator over the vertex offsets + typedef MapIterator NormalsIterator; + /// An iterator over the vertex offsets + typedef ConstMapIterator ConstNormalsIterator; + /// Return whether the pose vertices include normals + bool getIncludesNormals() const { return !mNormalsMap.empty(); } + + /** Adds an offset to a vertex for this pose. + @param index The vertex index + @param offset The position offset for this pose + */ + void addVertex(size_t index, const Vector3& offset); + + /** Adds an offset to a vertex and a new normal for this pose. + @param index The vertex index + @param offset The position offset for this pose + */ + void addVertex(size_t index, const Vector3& offset, const Vector3& normal); + + /** Remove a vertex offset. */ + void removeVertex(size_t index); + + /** Clear all vertices. */ + void clearVertices(void); + + /** Gets an iterator over all the vertex offsets. */ + ConstVertexOffsetIterator getVertexOffsetIterator(void) const; + /** Gets an iterator over all the vertex offsets. */ + VertexOffsetIterator getVertexOffsetIterator(void); + /** Gets a const reference to the vertex offsets. */ + const VertexOffsetMap& getVertexOffsets(void) const { return mVertexOffsetMap; } + + /** Gets an iterator over all the vertex offsets. */ + ConstNormalsIterator getNormalsIterator(void) const; + /** Gets an iterator over all the vertex offsets. */ + NormalsIterator getNormalsIterator(void); + /** Gets a const reference to the vertex offsets. */ + const NormalsMap& getNormals(void) const { return mNormalsMap; } + + /** Get a hardware vertex buffer version of the vertex offsets. */ + const HardwareVertexBufferSharedPtr& _getHardwareVertexBuffer(const VertexData* origData) const; + + /** Clone this pose and create another one configured exactly the same + way (only really useful for cloning holders of this class). + */ + Pose* clone(void) const; + protected: + /// Target geometry index + ushort mTarget; + /// Optional name + String mName; + /// Primary storage, sparse vertex use + VertexOffsetMap mVertexOffsetMap; + /// Primary storage, sparse vertex use + NormalsMap mNormalsMap; + /// Derived hardware buffer, covers all vertices + mutable HardwareVertexBufferSharedPtr mBuffer; + }; + typedef vector::type PoseList; + + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePredefinedControllers.h b/OgreMain/include/OgrePredefinedControllers.h index 3af3e9ff622..b14124c998e 100644 --- a/OgreMain/include/OgrePredefinedControllers.h +++ b/OgreMain/include/OgrePredefinedControllers.h @@ -37,13 +37,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - //----------------------------------------------------------------------- + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + //----------------------------------------------------------------------- // Controller Values //----------------------------------------------------------------------- /** Predefined controller value for getting the latest frame time. @@ -52,9 +52,9 @@ namespace Ogre { { protected: Real mFrameTime; - Real mTimeFactor; - Real mElapsedTime; - Real mFrameDelay; + Real mTimeFactor; + Real mElapsedTime; + Real mFrameDelay; public: FrameTimeControllerValue(); @@ -62,12 +62,12 @@ namespace Ogre { bool frameStarted(const FrameEvent &evt); Real getValue(void) const; void setValue(Real value); - Real getTimeFactor(void) const; - void setTimeFactor(Real tf); - Real getFrameDelay(void) const; - void setFrameDelay(Real fd); - Real getElapsedTime(void) const; - void setElapsedTime(Real elapsedTime); + Real getTimeFactor(void) const; + void setTimeFactor(Real tf); + Real getFrameDelay(void) const; + void setFrameDelay(Real fd); + Real getElapsedTime(void) const; + void setElapsedTime(Real elapsedTime); }; //----------------------------------------------------------------------- @@ -129,33 +129,33 @@ namespace Ogre { //----------------------------------------------------------------------- /** Predefined controller value for setting a single floating- - point value in a constant parameter of a vertex or fragment program. + point value in a constant parameter of a vertex or fragment program. @remarks - Any value is accepted, it is propagated into the 'x' - component of the constant register identified by the index. If you - need to use named parameters, retrieve the index from the param - object before setting this controller up. - @note - Retrieving a value from the program parameters is not currently - supported, therefore do not use this controller value as a source, - only as a target. + Any value is accepted, it is propagated into the 'x' + component of the constant register identified by the index. If you + need to use named parameters, retrieve the index from the param + object before setting this controller up. + @note + Retrieving a value from the program parameters is not currently + supported, therefore do not use this controller value as a source, + only as a target. */ class _OgreExport FloatGpuParameterControllerValue : public ControllerValue { protected: - /// The parameters to access - GpuProgramParametersSharedPtr mParams; - /// The index of the parameter to be read or set - size_t mParamIndex; + /// The parameters to access + GpuProgramParametersSharedPtr mParams; + /// The index of the parameter to be read or set + size_t mParamIndex; public: /** Constructor. - @param - params The parameters object to access + @param + params The parameters object to access @param index The index of the parameter to be set */ FloatGpuParameterControllerValue(GpuProgramParametersSharedPtr params, - size_t index ); + size_t index ); ~FloatGpuParameterControllerValue() {} @@ -167,25 +167,25 @@ namespace Ogre { // Controller functions //----------------------------------------------------------------------- - /** Predefined controller function which just passes through the original source - directly to dest. - */ - class _OgreExport PassthroughControllerFunction : public ControllerFunction - { - public: - /** Constructor. + /** Predefined controller function which just passes through the original source + directly to dest. + */ + class _OgreExport PassthroughControllerFunction : public ControllerFunction + { + public: + /** Constructor. @param deltaInput If true, signifies that the input will be a delta value such that the function should add it to an internal counter before calculating the output. - */ - PassthroughControllerFunction(bool deltaInput = false); + */ + PassthroughControllerFunction(bool deltaInput = false); - /** Overridden function. - */ - Real calculate(Real source); - }; + /** Overridden function. + */ + Real calculate(Real source); + }; - /** Predefined controller function for dealing with animation. + /** Predefined controller function for dealing with animation. */ class _OgreExport AnimationControllerFunction : public ControllerFunction { @@ -205,13 +205,13 @@ namespace Ogre { */ Real calculate(Real source); - /** Set the time value manually. */ - void setTime(Real timeVal); - /** Set the sequence duration value manually. */ - void setSequenceTime(Real seqVal); + /** Set the time value manually. */ + void setTime(Real timeVal); + /** Set the sequence duration value manually. */ + void setSequenceTime(Real seqVal); }; - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- /** Predefined controller function which simply scales an input to an output value. */ class _OgreExport ScaleControllerFunction : public ControllerFunction @@ -244,7 +244,7 @@ namespace Ogre { - frequency - the speed of the wave in cycles per second - phase - the offset of the start of the wave, e.g. 0.5 to start half-way through the wave - amplitude - scales the output so that instead of lying within [0,1] it lies within [0,1] * amplitude - - duty cycle - the active width of a PWM signal + - duty cycle - the active width of a PWM signal @par Note that for simplicity of integration with the rest of the controller insfrastructure, the output of the wave is parametric i.e. 0..1, rather than the typical wave output of [-1,1]. To compensate for this, the @@ -262,7 +262,7 @@ namespace Ogre { Real mFrequency; Real mPhase; Real mAmplitude; - Real mDutyCycle; + Real mDutyCycle; /** Overridden from ControllerFunction. */ Real getAdjustedInput(Real input); @@ -272,8 +272,8 @@ namespace Ogre { @param deltaInput If true, signifies that the input will be a delta value such that the function should add it to an internal counter before calculating the output. - @param - dutyCycle Used in PWM mode to specify the pulse width. + @param + dutyCycle Used in PWM mode to specify the pulse width. */ WaveformControllerFunction(WaveformType wType, Real base = 0, Real frequency = 1, Real phase = 0, Real amplitude = 1, bool deltaInput = true, Real dutyCycle = 0.5); @@ -283,8 +283,8 @@ namespace Ogre { }; //----------------------------------------------------------------------- - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgrePrefabFactory.h b/OgreMain/include/OgrePrefabFactory.h index eb18157b678..53ea28659e6 100644 --- a/OgreMain/include/OgrePrefabFactory.h +++ b/OgreMain/include/OgrePrefabFactory.h @@ -33,40 +33,40 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** A factory class that can create various mesh prefabs. - @remarks - This class is used by OgreMeshManager to offload the loading of various prefab types - to a central location. - */ - class _OgreExport PrefabFactory - { - public: - /** If the given mesh has a known prefab resource name (e.g "Prefab_Plane") - then this prefab will be created as a submesh of the given mesh. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** A factory class that can create various mesh prefabs. + @remarks + This class is used by OgreMeshManager to offload the loading of various prefab types + to a central location. + */ + class _OgreExport PrefabFactory + { + public: + /** If the given mesh has a known prefab resource name (e.g "Prefab_Plane") + then this prefab will be created as a submesh of the given mesh. - @param mesh The mesh that the potential prefab will be created in. - @return true if a prefab has been created, otherwise false. - */ - static bool createPrefab(Mesh* mesh); + @param mesh The mesh that the potential prefab will be created in. + @return true if a prefab has been created, otherwise false. + */ + static bool createPrefab(Mesh* mesh); - private: - /// Creates a plane as a submesh of the given mesh - static void createPlane(Mesh* mesh); + private: + /// Creates a plane as a submesh of the given mesh + static void createPlane(Mesh* mesh); - /// Creates a 100x100x100 cube as a submesh of the given mesh - static void createCube(Mesh* mesh); + /// Creates a 100x100x100 cube as a submesh of the given mesh + static void createCube(Mesh* mesh); - /// Creates a sphere with a diameter of 100 units as a submesh of the given mesh - static void createSphere(Mesh* mesh); - }; - /** @} */ - /** @} */ + /// Creates a sphere with a diameter of 100 units as a submesh of the given mesh + static void createSphere(Mesh* mesh); + }; + /** @} */ + /** @} */ } // namespace Ogre diff --git a/OgreMain/include/OgrePrerequisites.h b/OgreMain/include/OgrePrerequisites.h index a259471f335..4a0696892cf 100644 --- a/OgreMain/include/OgrePrerequisites.h +++ b/OgreMain/include/OgrePrerequisites.h @@ -33,17 +33,17 @@ THE SOFTWARE // configure memory tracking #if OGRE_DEBUG_MODE -# if OGRE_MEMORY_TRACKER_DEBUG_MODE +# if OGRE_MEMORY_TRACKER_DEBUG_MODE # define OGRE_MEMORY_TRACKER 1 -# else +# else # define OGRE_MEMORY_TRACKER 0 -# endif +# endif #else -# if OGRE_MEMORY_TRACKER_RELEASE_MODE +# if OGRE_MEMORY_TRACKER_RELEASE_MODE # define OGRE_MEMORY_TRACKER 1 -# else +# else # define OGRE_MEMORY_TRACKER 0 -# endif +# endif #endif namespace Ogre { @@ -51,7 +51,7 @@ namespace Ogre { #define OGRE_VERSION_MAJOR 1 #define OGRE_VERSION_MINOR 10 #define OGRE_VERSION_PATCH 0 - #define OGRE_VERSION_SUFFIX "unstable" + #define OGRE_VERSION_SUFFIX "unstable" #define OGRE_VERSION_NAME "Xalafu" #define OGRE_VERSION ((OGRE_VERSION_MAJOR << 16) | (OGRE_VERSION_MINOR << 8) | OGRE_VERSION_PATCH) @@ -98,9 +98,9 @@ namespace Ogre { # if OGRE_COMPILER == OGRE_COMPILER_MSVC && !defined(_STLP_MSVC) # if _MSC_FULL_VER >= 150030729 // VC++ 9.0 SP1+ # define HashMap ::std::tr1::unordered_map - # define HashMultiMap ::std::tr1::unordered_multimap + # define HashMultiMap ::std::tr1::unordered_multimap # define HashSet ::std::tr1::unordered_set - # define HashMultiSet ::std::tr1::unordered_multiset + # define HashMultiSet ::std::tr1::unordered_multiset # elif OGRE_THREAD_PROVIDER == 1 # define HashMap ::boost::unordered_map # define HashMultiMap ::boost::unordered_multimap @@ -128,7 +128,7 @@ namespace Ogre { typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; - typedef unsigned long ulong; + typedef unsigned long ulong; #if __cplusplus >= 201103L #define register @@ -160,10 +160,10 @@ namespace Ogre { template class ControllerFunction; class ControllerManager; template class ControllerValue; - class DataStream; - class DefaultWorkQueue; + class DataStream; + class DefaultWorkQueue; class Degree; - class DepthBuffer; + class DepthBuffer; class DynLib; class DynLibManager; class EdgeData; @@ -181,23 +181,23 @@ namespace Ogre { class GpuSharedParameters; class GpuProgram; class GpuProgramManager; - class GpuProgramUsage; + class GpuProgramUsage; class HardwareIndexBuffer; class HardwareOcclusionQuery; class HardwareVertexBuffer; - class HardwarePixelBuffer; + class HardwarePixelBuffer; class HardwarePixelBufferSharedPtr; - class HighLevelGpuProgram; - class HighLevelGpuProgramManager; - class HighLevelGpuProgramFactory; + class HighLevelGpuProgram; + class HighLevelGpuProgramManager; + class HighLevelGpuProgramFactory; class IndexData; - class InstanceBatch; - class InstanceBatchHW; - class InstanceBatchHW_VTF; - class InstanceBatchShader; - class InstanceBatchVTF; - class InstanceManager; - class InstancedEntity; + class InstanceBatch; + class InstanceBatchHW; + class InstanceBatchHW_VTF; + class InstanceBatchShader; + class InstanceBatchVTF; + class InstanceManager; + class InstancedEntity; class IntersectionSceneQuery; class IntersectionSceneQueryListener; class Image; @@ -205,10 +205,10 @@ namespace Ogre { class Light; class Log; class LogManager; - class LodStrategy; - class LodStrategyManager; - class ManualResourceLoader; - class ManualObject; + class LodStrategy; + class LodStrategyManager; + class ManualResourceLoader; + class ManualObject; class Material; class MaterialManager; class Math; @@ -223,10 +223,10 @@ namespace Ogre { class MovableObject; class MovablePlane; class Node; - class NodeAnimationTrack; - class NodeKeyFrame; - class NumericAnimationTrack; - class NumericKeyFrame; + class NodeAnimationTrack; + class NodeKeyFrame; + class NumericAnimationTrack; + class NumericKeyFrame; class Particle; class ParticleAffector; class ParticleAffectorFactory; @@ -245,9 +245,9 @@ namespace Ogre { class Plugin; class Pose; class Profile; - class Profiler; + class Profiler; class Quaternion; - class Radian; + class Radian; class Ray; class RaySceneQuery; class RaySceneQueryListener; @@ -255,10 +255,10 @@ namespace Ogre { class RenderPriorityGroup; class RenderQueue; class RenderQueueGroup; - class RenderQueueInvocation; - class RenderQueueInvocationSequence; + class RenderQueueInvocation; + class RenderQueueInvocationSequence; class RenderQueueListener; - class RenderObjectListener; + class RenderObjectListener; class RenderSystem; class RenderSystemCapabilities; class RenderSystemCapabilitiesManager; @@ -267,28 +267,28 @@ namespace Ogre { class RenderTargetListener; class RenderTexture; class RenderToVertexBuffer; - class MultiRenderTarget; + class MultiRenderTarget; class RenderWindow; class RenderOperation; class Resource; - class ResourceBackgroundQueue; - class ResourceGroupManager; + class ResourceBackgroundQueue; + class ResourceGroupManager; class ResourceManager; class RibbonTrail; - class Root; + class Root; class SceneManager; class SceneManagerEnumerator; class SceneNode; class SceneQuery; class SceneQueryListener; - class ScriptCompiler; - class ScriptCompilerManager; - class ScriptLoader; + class ScriptCompiler; + class ScriptCompilerManager; + class ScriptLoader; class Serializer; class ShadowCameraSetup; class ShadowCaster; class ShadowRenderable; - class ShadowTextureManager; + class ShadowTextureManager; class SimpleRenderable; class SimpleSpline; class Skeleton; @@ -296,47 +296,47 @@ namespace Ogre { class SkeletonManager; class Sphere; class SphereSceneQuery; - class StaticGeometry; - class StreamSerialiser; + class StaticGeometry; + class StreamSerialiser; class StringConverter; class StringInterface; class SubEntity; class SubMesh; - class TagPoint; + class TagPoint; class Technique; - class TempBlendedBufferInfo; - class ExternalTextureSource; + class TempBlendedBufferInfo; + class ExternalTextureSource; class TextureUnitState; class Texture; class TextureManager; class TransformKeyFrame; - class Timer; - class UserObjectBindings; + class Timer; + class UserObjectBindings; class Vector2; class Vector3; class Vector4; class Viewport; - class VertexAnimationTrack; + class VertexAnimationTrack; class VertexBufferBinding; class VertexData; class VertexDeclaration; - class VertexMorphKeyFrame; + class VertexMorphKeyFrame; class WireBoundingBox; - class WorkQueue; + class WorkQueue; class Compositor; class CompositorManager; class CompositorChain; class CompositorInstance; - class CompositorLogic; + class CompositorLogic; class CompositionTechnique; class CompositionPass; class CompositionTargetPass; - class CustomCompositionPass; + class CustomCompositionPass; template class SharedPtr; - typedef SharedPtr AnimableValuePtr; + typedef SharedPtr AnimableValuePtr; typedef SharedPtr CompositorPtr; - typedef SharedPtr DataStreamPtr; + typedef SharedPtr DataStreamPtr; typedef SharedPtr GpuProgramPtr; typedef SharedPtr GpuNamedConstantsPtr; typedef SharedPtr GpuLogicalBufferStructPtr; @@ -349,7 +349,7 @@ namespace Ogre { typedef SharedPtr PatchMeshPtr; typedef SharedPtr RenderToVertexBufferSharedPtr; typedef SharedPtr ResourcePtr; - typedef SharedPtr ShadowCameraSetupPtr; + typedef SharedPtr ShadowCameraSetupPtr; typedef SharedPtr SkeletonPtr; typedef SharedPtr TexturePtr; } @@ -364,134 +364,134 @@ settings have been made. namespace Ogre { #if OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR - #if OGRE_WCHAR_T_STRINGS - typedef std::basic_string, STLAllocator > _StringBase; - #else - typedef std::basic_string, STLAllocator > _StringBase; - #endif - - #if OGRE_WCHAR_T_STRINGS - typedef std::basic_stringstream,STLAllocator> _StringStreamBase; - #else - typedef std::basic_stringstream,STLAllocator > _StringStreamBase; - #endif - - #define StdStringT(T) std::basic_string, std::allocator > - #define CustomMemoryStringT(T) std::basic_string, STLAllocator > - - template - bool operator <(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) - { + #if OGRE_WCHAR_T_STRINGS + typedef std::basic_string, STLAllocator > _StringBase; + #else + typedef std::basic_string, STLAllocator > _StringBase; + #endif + + #if OGRE_WCHAR_T_STRINGS + typedef std::basic_stringstream,STLAllocator> _StringStreamBase; + #else + typedef std::basic_stringstream,STLAllocator > _StringStreamBase; + #endif + + #define StdStringT(T) std::basic_string, std::allocator > + #define CustomMemoryStringT(T) std::basic_string, STLAllocator > + + template + bool operator <(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())<0; - } - template - bool operator <(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) - { + } + template + bool operator <(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())<0; - } - template - bool operator <=(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) - { + } + template + bool operator <=(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())<=0; - } - template - bool operator <=(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) - { + } + template + bool operator <=(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())<=0; - } - template - bool operator >(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) - { + } + template + bool operator >(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())>0; - } - template - bool operator >(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) - { + } + template + bool operator >(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())>0; - } - template - bool operator >=(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) - { + } + template + bool operator >=(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())>=0; - } - template - bool operator >=(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) - { + } + template + bool operator >=(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())>=0; - } + } - template - bool operator ==(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) - { + template + bool operator ==(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())==0; - } - template - bool operator ==(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) - { + } + template + bool operator ==(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())==0; - } + } - template - bool operator !=(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) - { + template + bool operator !=(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())!=0; - } - template - bool operator !=(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) - { + } + template + bool operator !=(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) + { return l.compare(0,l.length(),o.c_str(),o.length())!=0; - } + } - template - CustomMemoryStringT(T) operator +=(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) - { + template + CustomMemoryStringT(T) operator +=(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) + { return CustomMemoryStringT(T)(l)+=o.c_str(); - } - template - CustomMemoryStringT(T) operator +=(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) - { + } + template + CustomMemoryStringT(T) operator +=(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) + { return CustomMemoryStringT(T)(l.c_str())+=o.c_str(); - } + } - template - CustomMemoryStringT(T) operator +(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) - { + template + CustomMemoryStringT(T) operator +(const CustomMemoryStringT(T)& l,const StdStringT(T)& o) + { return CustomMemoryStringT(T)(l)+=o.c_str(); - } + } - template - CustomMemoryStringT(T) operator +(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) - { + template + CustomMemoryStringT(T) operator +(const StdStringT(T)& l,const CustomMemoryStringT(T)& o) + { return CustomMemoryStringT(T)(l.c_str())+=o.c_str(); - } + } - template - CustomMemoryStringT(T) operator +(const T* l,const CustomMemoryStringT(T)& o) - { + template + CustomMemoryStringT(T) operator +(const T* l,const CustomMemoryStringT(T)& o) + { return CustomMemoryStringT(T)(l)+=o; - } + } - #undef StdStringT - #undef CustomMemoryStringT + #undef StdStringT + #undef CustomMemoryStringT #else - #if OGRE_WCHAR_T_STRINGS - typedef std::wstring _StringBase; - #else - typedef std::string _StringBase; - #endif - - #if OGRE_WCHAR_T_STRINGS - typedef std::basic_stringstream,std::allocator > _StringStreamBase; - #else - typedef std::basic_stringstream,std::allocator > _StringStreamBase; - #endif + #if OGRE_WCHAR_T_STRINGS + typedef std::wstring _StringBase; + #else + typedef std::string _StringBase; + #endif + + #if OGRE_WCHAR_T_STRINGS + typedef std::basic_stringstream,std::allocator > _StringStreamBase; + #else + typedef std::basic_stringstream,std::allocator > _StringStreamBase; + #endif #endif - typedef _StringBase String; - typedef _StringStreamBase StringStream; - typedef StringStream stringstream; + typedef _StringBase String; + typedef _StringStreamBase StringStream; + typedef StringStream stringstream; } @@ -499,26 +499,26 @@ namespace Ogre namespace std { #if (OGRE_COMPILER == OGRE_COMPILER_GNUC && OGRE_COMP_VER >= 430) || OGRE_COMPILER == OGRE_COMPILER_CLANG && !defined(STLPORT) && __cplusplus < 201103L - namespace tr1 - { + namespace tr1 + { #endif template <> struct hash - { + { public : size_t operator()(const Ogre::String &str ) const { - size_t _Val = 2166136261U; - size_t _First = 0; - size_t _Last = str.size(); - size_t _Stride = 1 + _Last / 10; + size_t _Val = 2166136261U; + size_t _First = 0; + size_t _Last = str.size(); + size_t _Stride = 1 + _Last / 10; - for(; _First < _Last; _First += _Stride) + for(; _First < _Last; _First += _Stride) _Val = 16777619U * _Val ^ (size_t)str[_First]; - return (_Val); + return (_Val); } }; #if (OGRE_COMPILER == OGRE_COMPILER_GNUC && OGRE_COMP_VER >= 430) || OGRE_COMPILER == OGRE_COMPILER_CLANG && !defined(STLPORT) && __cplusplus < 201103L - } + } #endif } #endif @@ -526,9 +526,9 @@ namespace std //for stl container namespace Ogre { - template > - struct deque - { + template > + struct deque + { #if OGRE_CONTAINERS_USE_CUSTOM_MEMORY_ALLOCATOR typedef typename std::deque type; typedef typename std::deque::iterator iterator; @@ -538,11 +538,11 @@ namespace Ogre typedef typename std::deque::iterator iterator; typedef typename std::deque::const_iterator const_iterator; #endif - }; + }; - template > - struct vector - { + template > + struct vector + { #if OGRE_CONTAINERS_USE_CUSTOM_MEMORY_ALLOCATOR typedef typename std::vector type; typedef typename std::vector::iterator iterator; @@ -552,11 +552,11 @@ namespace Ogre typedef typename std::vector::iterator iterator; typedef typename std::vector::const_iterator const_iterator; #endif - }; + }; - template > - struct list - { + template > + struct list + { #if OGRE_CONTAINERS_USE_CUSTOM_MEMORY_ALLOCATOR typedef typename std::list type; typedef typename std::list::iterator iterator; @@ -566,11 +566,11 @@ namespace Ogre typedef typename std::list::iterator iterator; typedef typename std::list::const_iterator const_iterator; #endif - }; + }; - template , typename A = STLAllocator > - struct set - { + template , typename A = STLAllocator > + struct set + { #if OGRE_CONTAINERS_USE_CUSTOM_MEMORY_ALLOCATOR typedef typename std::set type; typedef typename std::set::iterator iterator; @@ -580,11 +580,11 @@ namespace Ogre typedef typename std::set::iterator iterator; typedef typename std::set::const_iterator const_iterator; #endif - }; + }; - template , typename A = STLAllocator, GeneralAllocPolicy> > - struct map - { + template , typename A = STLAllocator, GeneralAllocPolicy> > + struct map + { #if OGRE_CONTAINERS_USE_CUSTOM_MEMORY_ALLOCATOR typedef typename std::map type; typedef typename std::map::iterator iterator; @@ -594,11 +594,11 @@ namespace Ogre typedef typename std::map::iterator iterator; typedef typename std::map::const_iterator const_iterator; #endif - }; + }; - template , typename A = STLAllocator, GeneralAllocPolicy> > - struct multimap - { + template , typename A = STLAllocator, GeneralAllocPolicy> > + struct multimap + { #if OGRE_CONTAINERS_USE_CUSTOM_MEMORY_ALLOCATOR typedef typename std::multimap type; typedef typename std::multimap::iterator iterator; @@ -608,7 +608,7 @@ namespace Ogre typedef typename std::multimap::iterator iterator; typedef typename std::multimap::const_iterator const_iterator; #endif - }; + }; } // Ogre diff --git a/OgreMain/include/OgreProfiler.h b/OgreMain/include/OgreProfiler.h index 38a7290c00b..63ebb42af7e 100644 --- a/OgreMain/include/OgreProfiler.h +++ b/OgreMain/include/OgreProfiler.h @@ -46,49 +46,49 @@ Ogre-dependent is in the visualization/logging routines and the use of the Timer #include "OgreHeaderPrefix.h" #if OGRE_PROFILING == 1 -# define OgreProfile( a ) Ogre::Profile _OgreProfileInstance( (a) ) -# define OgreProfileBegin( a ) Ogre::Profiler::getSingleton().beginProfile( (a) ) -# define OgreProfileEnd( a ) Ogre::Profiler::getSingleton().endProfile( (a) ) -# define OgreProfileGroup( a, g ) Ogre::Profile _OgreProfileInstance( (a), (g) ) -# define OgreProfileBeginGroup( a, g ) Ogre::Profiler::getSingleton().beginProfile( (a), (g) ) -# define OgreProfileEndGroup( a, g ) Ogre::Profiler::getSingleton().endProfile( (a), (g) ) -# define OgreProfileBeginGPUEvent( g ) Ogre::Profiler::getSingleton().beginGPUEvent(g) -# define OgreProfileEndGPUEvent( g ) Ogre::Profiler::getSingleton().endGPUEvent(g) -# define OgreProfileMarkGPUEvent( e ) Ogre::Profiler::getSingleton().markGPUEvent(e) +# define OgreProfile( a ) Ogre::Profile _OgreProfileInstance( (a) ) +# define OgreProfileBegin( a ) Ogre::Profiler::getSingleton().beginProfile( (a) ) +# define OgreProfileEnd( a ) Ogre::Profiler::getSingleton().endProfile( (a) ) +# define OgreProfileGroup( a, g ) Ogre::Profile _OgreProfileInstance( (a), (g) ) +# define OgreProfileBeginGroup( a, g ) Ogre::Profiler::getSingleton().beginProfile( (a), (g) ) +# define OgreProfileEndGroup( a, g ) Ogre::Profiler::getSingleton().endProfile( (a), (g) ) +# define OgreProfileBeginGPUEvent( g ) Ogre::Profiler::getSingleton().beginGPUEvent(g) +# define OgreProfileEndGPUEvent( g ) Ogre::Profiler::getSingleton().endGPUEvent(g) +# define OgreProfileMarkGPUEvent( e ) Ogre::Profiler::getSingleton().markGPUEvent(e) #else # define OgreProfile( a ) # define OgreProfileBegin( a ) # define OgreProfileEnd( a ) -# define OgreProfileGroup( a, g ) -# define OgreProfileBeginGroup( a, g ) -# define OgreProfileEndGroup( a, g ) -# define OgreProfileBeginGPUEvent( e ) -# define OgreProfileEndGPUEvent( e ) -# define OgreProfileMarkGPUEvent( e ) +# define OgreProfileGroup( a, g ) +# define OgreProfileBeginGroup( a, g ) +# define OgreProfileEndGroup( a, g ) +# define OgreProfileBeginGPUEvent( e ) +# define OgreProfileEndGPUEvent( e ) +# define OgreProfileMarkGPUEvent( e ) #endif namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** List of reserved profiling masks - */ - enum ProfileGroupMask - { - /// User default profile - OGREPROF_USER_DEFAULT = 0x00000001, - /// All in-built Ogre profiling will match this mask - OGREPROF_ALL = 0xFF000000, - /// General processing - OGREPROF_GENERAL = 0x80000000, - /// Culling - OGREPROF_CULLING = 0x40000000, - /// Rendering - OGREPROF_RENDERING = 0x20000000 - }; + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** List of reserved profiling masks + */ + enum ProfileGroupMask + { + /// User default profile + OGREPROF_USER_DEFAULT = 0x00000001, + /// All in-built Ogre profiling will match this mask + OGREPROF_ALL = 0xFF000000, + /// General processing + OGREPROF_GENERAL = 0x80000000, + /// Culling + OGREPROF_CULLING = 0x40000000, + /// Rendering + OGREPROF_RENDERING = 0x20000000 + }; /** An individual profile that will be processed by the Profiler @remarks @@ -100,9 +100,9 @@ namespace Ogre { outside of a scope (i.e. the main game loop). @author Amit Mathew (amitmathew (at) yahoo (dot) com) */ - class _OgreExport Profile : - public ProfilerAlloc - { + class _OgreExport Profile : + public ProfilerAlloc + { public: Profile(const String& profileName, uint32 groupID = (uint32)OGREPROF_USER_DEFAULT); @@ -112,158 +112,158 @@ namespace Ogre { /// The name of this profile String mName; - /// The group ID - uint32 mGroupID; - + /// The group ID + uint32 mGroupID; + }; - /** Represents the total timing information of a profile - since profiles can be called more than once each frame - */ + /** Represents the total timing information of a profile + since profiles can be called more than once each frame + */ struct ProfileFrame - { + { /// The total time this profile has taken this frame - ulong frameTime; + ulong frameTime; /// The number of times this profile was called this frame - uint calls; + uint calls; /// The hierarchical level of this profile, 0 being the main loop - uint hierarchicalLvl; + uint hierarchicalLvl; }; - /// Represents a history of each profile during the duration of the app + /// Represents a history of each profile during the duration of the app struct ProfileHistory - { + { /// The current percentage of frame time this profile has taken - Real currentTimePercent; - /// The current frame time this profile has taken in milliseconds - Real currentTimeMillisecs; + Real currentTimePercent; + /// The current frame time this profile has taken in milliseconds + Real currentTimeMillisecs; /// The maximum percentage of frame time this profile has taken - Real maxTimePercent; - /// The maximum frame time this profile has taken in milliseconds - Real maxTimeMillisecs; + Real maxTimePercent; + /// The maximum frame time this profile has taken in milliseconds + Real maxTimeMillisecs; /// The minimum percentage of frame time this profile has taken - Real minTimePercent; - /// The minimum frame time this profile has taken in milliseconds - Real minTimeMillisecs; + Real minTimePercent; + /// The minimum frame time this profile has taken in milliseconds + Real minTimeMillisecs; /// The number of times this profile has been called each frame - uint numCallsThisFrame; + uint numCallsThisFrame; /// The total percentage of frame time this profile has taken - Real totalTimePercent; - /// The total frame time this profile has taken in milliseconds - Real totalTimeMillisecs; + Real totalTimePercent; + /// The total frame time this profile has taken in milliseconds + Real totalTimeMillisecs; /// The total number of times this profile was called /// (used to calculate average) - ulong totalCalls; + ulong totalCalls; /// The hierarchical level of this profile, 0 being the root profile - uint hierarchicalLvl; - - }; - - /// Represents an individual profile call - class ProfileInstance : public ProfilerAlloc - { - friend class Profiler; - public: - ProfileInstance(void); - virtual ~ProfileInstance(void); - - typedef Ogre::map::type ProfileChildren; - - void logResults(); - void reset(); - - inline bool watchForMax(void) { return history.currentTimePercent == history.maxTimePercent; } - inline bool watchForMin(void) { return history.currentTimePercent == history.minTimePercent; } - inline bool watchForLimit(Real limit, bool greaterThan = true) - { - if (greaterThan) - return history.currentTimePercent > limit; - else - return history.currentTimePercent < limit; - } - - bool watchForMax(const String& profileName); - bool watchForMin(const String& profileName); - bool watchForLimit(const String& profileName, Real limit, bool greaterThan = true); + uint hierarchicalLvl; + + }; + + /// Represents an individual profile call + class ProfileInstance : public ProfilerAlloc + { + friend class Profiler; + public: + ProfileInstance(void); + virtual ~ProfileInstance(void); + + typedef Ogre::map::type ProfileChildren; + + void logResults(); + void reset(); + + inline bool watchForMax(void) { return history.currentTimePercent == history.maxTimePercent; } + inline bool watchForMin(void) { return history.currentTimePercent == history.minTimePercent; } + inline bool watchForLimit(Real limit, bool greaterThan = true) + { + if (greaterThan) + return history.currentTimePercent > limit; + else + return history.currentTimePercent < limit; + } + + bool watchForMax(const String& profileName); + bool watchForMin(const String& profileName); + bool watchForLimit(const String& profileName, Real limit, bool greaterThan = true); - /// The name of the profile - String name; + /// The name of the profile + String name; - /// The name of the parent, null if root - ProfileInstance* parent; + /// The name of the parent, null if root + ProfileInstance* parent; - ProfileChildren children; + ProfileChildren children; - ProfileFrame frame; - ulong frameNumber; + ProfileFrame frame; + ulong frameNumber; - ProfileHistory history; + ProfileHistory history; - /// The time this profile was started - ulong currTime; + /// The time this profile was started + ulong currTime; - /// Represents the total time of all child profiles to subtract - /// from this profile - ulong accum; + /// Represents the total time of all child profiles to subtract + /// from this profile + ulong accum; - /// The hierarchical level of this profile, 0 being the root profile - uint hierarchicalLvl; - }; + /// The hierarchical level of this profile, 0 being the root profile + uint hierarchicalLvl; + }; - /** ProfileSessionListener should be used to visualize profile results. - Concrete impl. could be done using Overlay's but its not limited to - them you can also create a custom listener which sends the profile - informtaion over a network. + /** ProfileSessionListener should be used to visualize profile results. + Concrete impl. could be done using Overlay's but its not limited to + them you can also create a custom listener which sends the profile + informtaion over a network. */ - class _OgreExport ProfileSessionListener - { - public: - enum DisplayMode - { - /// Display % frame usage on the overlay - DISPLAY_PERCENTAGE, - /// Display milliseconds on the overlay - DISPLAY_MILLISECONDS - }; - - ProfileSessionListener() : mDisplayMode(DISPLAY_MILLISECONDS) {} - virtual ~ProfileSessionListener() {} - - /// Create the internal resources - virtual void initializeSession() = 0; - - /// All internal resources should be deleted here - virtual void finializeSession() = 0; - - /** If the profiler disables this listener then it - should hide its panels (if any exists) or stop - sending data over the network - */ - virtual void changeEnableState(bool enabled) {}; - - /// Here we get the real profiling information which we can use - virtual void displayResults(const ProfileInstance& instance, ulong maxTotalFrameTime) {}; - - /// Set the display mode for the overlay. - void setDisplayMode(DisplayMode d) { mDisplayMode = d; } - - /// Get the display mode for the overlay. - DisplayMode getDisplayMode() const { return mDisplayMode; } - - protected: - /// How to display the overlay - DisplayMode mDisplayMode; - }; + class _OgreExport ProfileSessionListener + { + public: + enum DisplayMode + { + /// Display % frame usage on the overlay + DISPLAY_PERCENTAGE, + /// Display milliseconds on the overlay + DISPLAY_MILLISECONDS + }; + + ProfileSessionListener() : mDisplayMode(DISPLAY_MILLISECONDS) {} + virtual ~ProfileSessionListener() {} + + /// Create the internal resources + virtual void initializeSession() = 0; + + /// All internal resources should be deleted here + virtual void finializeSession() = 0; + + /** If the profiler disables this listener then it + should hide its panels (if any exists) or stop + sending data over the network + */ + virtual void changeEnableState(bool enabled) {}; + + /// Here we get the real profiling information which we can use + virtual void displayResults(const ProfileInstance& instance, ulong maxTotalFrameTime) {}; + + /// Set the display mode for the overlay. + void setDisplayMode(DisplayMode d) { mDisplayMode = d; } + + /// Get the display mode for the overlay. + DisplayMode getDisplayMode() const { return mDisplayMode; } + + protected: + /// How to display the overlay + DisplayMode mDisplayMode; + }; /** The profiler allows you to measure the performance of your code @remarks @@ -277,9 +277,9 @@ namespace Ogre { @todo fix display ordering of profiles not called every frame */ class _OgreExport Profiler : - public Singleton, - public ProfilerAlloc - { + public Singleton, + public ProfilerAlloc + { public: Profiler(); ~Profiler(); @@ -301,7 +301,7 @@ namespace Ogre { OgreProfile(name). This function will be ignored for a profile that has been disabled or if the profiler is disabled. @param profileName Must be unique and must not be an empty string - @param groupID A profile group identifier, which can allow you to mask profiles + @param groupID A profile group identifier, which can allow you to mask profiles */ void beginProfile(const String& profileName, uint32 groupID = (uint32)OGREPROF_USER_DEFAULT); @@ -316,8 +316,8 @@ namespace Ogre { sure the name of this profile matches its corresponding beginProfile name. This function will be ignored for a profile that has been disabled or if the profiler is disabled. - @param profileName Must be unique and must not be an empty string - @param groupID A profile group identifier, which can allow you to mask profiles + @param profileName Must be unique and must not be an empty string + @param groupID A profile group identifier, which can allow you to mask profiles */ void endProfile(const String& profileName, uint32 groupID = (uint32)OGREPROF_USER_DEFAULT); @@ -356,12 +356,12 @@ namespace Ogre { */ void disableProfile(const String& profileName); - /** Set the mask which all profiles must pass to be enabled. - */ - void setProfileGroupMask(uint32 mask) { mProfileMask = mask; } - /** Get the mask which all profiles must pass to be enabled. - */ - uint32 getProfileGroupMask() const { return mProfileMask; } + /** Set the mask which all profiles must pass to be enabled. + */ + void setProfileGroupMask(uint32 mask) { mProfileMask = mask; } + /** Get the mask which all profiles must pass to be enabled. + */ + uint32 getProfileGroupMask() const { return mProfileMask; } /** Returns true if the specified profile reaches a new frame time maximum @remarks If this is called during a frame, it will be reading the results @@ -400,21 +400,21 @@ namespace Ogre { /** Gets the frequency that the Profiler display is updated */ uint getUpdateDisplayFrequency() const; - /** - @remarks - Register a ProfileSessionListener from the Profiler - @param listener - A valid listener derived class - */ - void addListener(ProfileSessionListener* listener); - - /** - @remarks - Unregister a ProfileSessionListener from the Profiler - @param listener - A valid listener derived class - */ - void removeListener(ProfileSessionListener* listener); + /** + @remarks + Register a ProfileSessionListener from the Profiler + @param listener + A valid listener derived class + */ + void addListener(ProfileSessionListener* listener); + + /** + @remarks + Unregister a ProfileSessionListener from the Profiler + @param listener + A valid listener derived class + */ + void removeListener(ProfileSessionListener* listener); /** Override standard Singleton retrieval. @remarks @@ -450,31 +450,31 @@ namespace Ogre { static Profiler* getSingletonPtr(void); protected: - friend class ProfileInstance; + friend class ProfileInstance; - typedef vector::type TProfileSessionListener; - TProfileSessionListener mListeners; + typedef vector::type TProfileSessionListener; + TProfileSessionListener mListeners; /** Initializes the profiler's GUI elements */ void initialize(); - void displayResults(); + void displayResults(); - /** Processes frame stats for all of the mRoot's children */ - void processFrameStats(void); + /** Processes frame stats for all of the mRoot's children */ + void processFrameStats(void); /** Processes specific ProfileInstance and it's children recursively.*/ void processFrameStats(ProfileInstance* instance, Real& maxFrameTime); /** Handles a change of the profiler's enabled state*/ void changeEnableState(); - // lol. Uses typedef; put's original container type in name. + // lol. Uses typedef; put's original container type in name. typedef set::type DisabledProfileMap; - typedef ProfileInstance::ProfileChildren ProfileChildren; + typedef ProfileInstance::ProfileChildren ProfileChildren; - ProfileInstance* mCurrent; - ProfileInstance* mLast; - ProfileInstance mRoot; + ProfileInstance* mCurrent; + ProfileInstance* mLast; + ProfileInstance mRoot; /// Holds the names of disabled profiles DisabledProfileMap mDisabledProfiles; @@ -502,20 +502,20 @@ namespace Ogre { /// which will be applied after the frame ends bool mNewEnableState; - /// Mask to decide whether a type of profile is enabled or not - uint32 mProfileMask; + /// Mask to decide whether a type of profile is enabled or not + uint32 mProfileMask; - /// The max frame time recorded - ulong mMaxTotalFrameTime; + /// The max frame time recorded + ulong mMaxTotalFrameTime; - /// Rolling average of millisecs - Real mAverageFrameTime; - bool mResetExtents; + /// Rolling average of millisecs + Real mAverageFrameTime; + bool mResetExtents; }; // end class - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // end namespace diff --git a/OgreMain/include/OgreQuaternion.h b/OgreMain/include/OgreQuaternion.h index e21df26d142..af4c0b82563 100644 --- a/OgreMain/include/OgreQuaternion.h +++ b/OgreMain/include/OgreQuaternion.h @@ -41,34 +41,34 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Implementation of a Quaternion, i.e. a rotation around an axis. - For more information about Quaternions and the theory behind it, we recommend reading: - http://www.ogre3d.org/tikiwiki/Quaternion+and+Rotation+Primer - http://www.cprogramming.com/tutorial/3d/quaternions.html - http://www.gamedev.net/page/resources/_/reference/programming/math-and-physics/ - quaternions/quaternion-powers-r1095 + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Implementation of a Quaternion, i.e. a rotation around an axis. + For more information about Quaternions and the theory behind it, we recommend reading: + http://www.ogre3d.org/tikiwiki/Quaternion+and+Rotation+Primer + http://www.cprogramming.com/tutorial/3d/quaternions.html + http://www.gamedev.net/page/resources/_/reference/programming/math-and-physics/ + quaternions/quaternion-powers-r1095 */ class _OgreExport Quaternion { public: - /// Default constructor, initializes to identity rotation (aka 0°) - inline Quaternion () - : w(1), x(0), y(0), z(0) - { - } - /// Construct from an explicit list of values - inline Quaternion ( - Real fW, - Real fX, Real fY, Real fZ) - : w(fW), x(fX), y(fY), z(fZ) - { - } + /// Default constructor, initializes to identity rotation (aka 0°) + inline Quaternion () + : w(1), x(0), y(0), z(0) + { + } + /// Construct from an explicit list of values + inline Quaternion ( + Real fW, + Real fX, Real fY, Real fZ) + : w(fW), x(fX), y(fY), z(fZ) + { + } /// Construct a quaternion from a rotation matrix inline Quaternion(const Matrix3& rot) { @@ -89,55 +89,55 @@ namespace Ogre { { this->FromAxes(akAxis); } - /// Construct a quaternion from 4 manual w/x/y/z values - inline Quaternion(Real* valptr) - { - memcpy(&w, valptr, sizeof(Real)*4); - } - - /** Exchange the contents of this quaternion with another. - */ - inline void swap(Quaternion& other) - { - std::swap(w, other.w); - std::swap(x, other.x); - std::swap(y, other.y); - std::swap(z, other.z); - } - - /// Array accessor operator - inline Real operator [] ( const size_t i ) const - { - assert( i < 4 ); - - return *(&w+i); - } - - /// Array accessor operator - inline Real& operator [] ( const size_t i ) - { - assert( i < 4 ); - - return *(&w+i); - } - - /// Pointer accessor for direct copying - inline Real* ptr() - { - return &w; - } - - /// Pointer accessor for direct copying - inline const Real* ptr() const - { - return &w; - } - - void FromRotationMatrix (const Matrix3& kRot); + /// Construct a quaternion from 4 manual w/x/y/z values + inline Quaternion(Real* valptr) + { + memcpy(&w, valptr, sizeof(Real)*4); + } + + /** Exchange the contents of this quaternion with another. + */ + inline void swap(Quaternion& other) + { + std::swap(w, other.w); + std::swap(x, other.x); + std::swap(y, other.y); + std::swap(z, other.z); + } + + /// Array accessor operator + inline Real operator [] ( const size_t i ) const + { + assert( i < 4 ); + + return *(&w+i); + } + + /// Array accessor operator + inline Real& operator [] ( const size_t i ) + { + assert( i < 4 ); + + return *(&w+i); + } + + /// Pointer accessor for direct copying + inline Real* ptr() + { + return &w; + } + + /// Pointer accessor for direct copying + inline const Real* ptr() const + { + return &w; + } + + void FromRotationMatrix (const Matrix3& kRot); void ToRotationMatrix (Matrix3& kRot) const; - /** Setups the quaternion using the supplied vector, and "roll" around - that vector by the specified radians. - */ + /** Setups the quaternion using the supplied vector, and "roll" around + that vector by the specified radians. + */ void FromAngleAxis (const Radian& rfAngle, const Vector3& rkAxis); void ToAngleAxis (Radian& rfAngle, Vector3& rkAxis) const; inline void ToAngleAxis (Degree& dAngle, Vector3& rkAxis) const { @@ -145,38 +145,38 @@ namespace Ogre { ToAngleAxis ( rAngle, rkAxis ); dAngle = rAngle; } - /** Constructs the quaternion using 3 axes, the axes are assumed to be orthonormal - @see FromAxes - */ + /** Constructs the quaternion using 3 axes, the axes are assumed to be orthonormal + @see FromAxes + */ void FromAxes (const Vector3* akAxis); void FromAxes (const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis); - /** Gets the 3 orthonormal axes defining the quaternion. @see FromAxes */ + /** Gets the 3 orthonormal axes defining the quaternion. @see FromAxes */ void ToAxes (Vector3* akAxis) const; void ToAxes (Vector3& xAxis, Vector3& yAxis, Vector3& zAxis) const; - /** Returns the X orthonormal axis defining the quaternion. Same as doing - xAxis = Vector3::UNIT_X * this. Also called the local X-axis - */ + /** Returns the X orthonormal axis defining the quaternion. Same as doing + xAxis = Vector3::UNIT_X * this. Also called the local X-axis + */ Vector3 xAxis(void) const; /** Returns the Y orthonormal axis defining the quaternion. Same as doing - yAxis = Vector3::UNIT_Y * this. Also called the local Y-axis - */ + yAxis = Vector3::UNIT_Y * this. Also called the local Y-axis + */ Vector3 yAxis(void) const; - /** Returns the Z orthonormal axis defining the quaternion. Same as doing - zAxis = Vector3::UNIT_Z * this. Also called the local Z-axis - */ + /** Returns the Z orthonormal axis defining the quaternion. Same as doing + zAxis = Vector3::UNIT_Z * this. Also called the local Z-axis + */ Vector3 zAxis(void) const; inline Quaternion& operator= (const Quaternion& rkQ) - { - w = rkQ.w; - x = rkQ.x; - y = rkQ.y; - z = rkQ.z; - return *this; - } + { + w = rkQ.w; + x = rkQ.x; + y = rkQ.y; + z = rkQ.z; + return *this; + } Quaternion operator+ (const Quaternion& rkQ) const; Quaternion operator- (const Quaternion& rkQ) const; Quaternion operator* (const Quaternion& rkQ) const; @@ -185,14 +185,14 @@ namespace Ogre { const Quaternion& rkQ); Quaternion operator- () const; inline bool operator== (const Quaternion& rhs) const - { - return (rhs.x == x) && (rhs.y == y) && - (rhs.z == z) && (rhs.w == w); - } + { + return (rhs.x == x) && (rhs.y == y) && + (rhs.z == z) && (rhs.w == w); + } inline bool operator!= (const Quaternion& rhs) const - { - return !operator==(rhs); - } + { + return !operator==(rhs); + } // functions of a quaternion /// Returns the dot product of the quaternion Real Dot (const Quaternion& rkQ) const; @@ -210,58 +210,58 @@ namespace Ogre { /// Rotation of a vector by a quaternion Vector3 operator* (const Vector3& rkVector) const; - /** Calculate the local roll element of this quaternion. - @param reprojectAxis By default the method returns the 'intuitive' result - that is, if you projected the local Y of the quaternion onto the X and - Y axes, the angle between them is returned. If set to false though, the - result is the actual yaw that will be used to implement the quaternion, - which is the shortest possible path to get to the same orientation and + /** Calculate the local roll element of this quaternion. + @param reprojectAxis By default the method returns the 'intuitive' result + that is, if you projected the local Y of the quaternion onto the X and + Y axes, the angle between them is returned. If set to false though, the + result is the actual yaw that will be used to implement the quaternion, + which is the shortest possible path to get to the same orientation and may involve less axial rotation. The co-domain of the returned value is from -180 to 180 degrees. - */ - Radian getRoll(bool reprojectAxis = true) const; - /** Calculate the local pitch element of this quaternion - @param reprojectAxis By default the method returns the 'intuitive' result - that is, if you projected the local Z of the quaternion onto the X and - Y axes, the angle between them is returned. If set to true though, the - result is the actual yaw that will be used to implement the quaternion, - which is the shortest possible path to get to the same orientation and + */ + Radian getRoll(bool reprojectAxis = true) const; + /** Calculate the local pitch element of this quaternion + @param reprojectAxis By default the method returns the 'intuitive' result + that is, if you projected the local Z of the quaternion onto the X and + Y axes, the angle between them is returned. If set to true though, the + result is the actual yaw that will be used to implement the quaternion, + which is the shortest possible path to get to the same orientation and may involve less axial rotation. The co-domain of the returned value is from -180 to 180 degrees. - */ - Radian getPitch(bool reprojectAxis = true) const; - /** Calculate the local yaw element of this quaternion - @param reprojectAxis By default the method returns the 'intuitive' result - that is, if you projected the local Y of the quaternion onto the X and - Z axes, the angle between them is returned. If set to true though, the - result is the actual yaw that will be used to implement the quaternion, - which is the shortest possible path to get to the same orientation and - may involve less axial rotation. The co-domain of the returned value is + */ + Radian getPitch(bool reprojectAxis = true) const; + /** Calculate the local yaw element of this quaternion + @param reprojectAxis By default the method returns the 'intuitive' result + that is, if you projected the local Y of the quaternion onto the X and + Z axes, the angle between them is returned. If set to true though, the + result is the actual yaw that will be used to implement the quaternion, + which is the shortest possible path to get to the same orientation and + may involve less axial rotation. The co-domain of the returned value is from -180 to 180 degrees. - */ - Radian getYaw(bool reprojectAxis = true) const; - /// Equality with tolerance (tolerance is max angle difference) - bool equals(const Quaternion& rhs, const Radian& tolerance) const; - - /** Performs Spherical linear interpolation between two quaternions, and returns the result. - Slerp ( 0.0f, A, B ) = A - Slerp ( 1.0f, A, B ) = B - @return Interpolated quaternion - @remarks - Slerp has the proprieties of performing the interpolation at constant - velocity, and being torque-minimal (unless shortestPath=false). - However, it's NOT commutative, which means - Slerp ( 0.75f, A, B ) != Slerp ( 0.25f, B, A ); - therefore be careful if your code relies in the order of the operands. - This is specially important in IK animation. - */ + */ + Radian getYaw(bool reprojectAxis = true) const; + /// Equality with tolerance (tolerance is max angle difference) + bool equals(const Quaternion& rhs, const Radian& tolerance) const; + + /** Performs Spherical linear interpolation between two quaternions, and returns the result. + Slerp ( 0.0f, A, B ) = A + Slerp ( 1.0f, A, B ) = B + @return Interpolated quaternion + @remarks + Slerp has the proprieties of performing the interpolation at constant + velocity, and being torque-minimal (unless shortestPath=false). + However, it's NOT commutative, which means + Slerp ( 0.75f, A, B ) != Slerp ( 0.25f, B, A ); + therefore be careful if your code relies in the order of the operands. + This is specially important in IK animation. + */ static Quaternion Slerp (Real fT, const Quaternion& rkP, const Quaternion& rkQ, bool shortestPath = false); - /** @see Slerp. It adds extra "spins" (i.e. rotates several times) specified - by parameter 'iExtraSpins' while interpolating before arriving to the - final values - */ + /** @see Slerp. It adds extra "spins" (i.e. rotates several times) specified + by parameter 'iExtraSpins' while interpolating before arriving to the + final values + */ static Quaternion SlerpExtraSpins (Real fT, const Quaternion& rkP, const Quaternion& rkQ, int iExtraSpins); @@ -277,19 +277,19 @@ namespace Ogre { const Quaternion& rkQ, bool shortestPath = false); /** Performs Normalised linear interpolation between two quaternions, and returns the result. - nlerp ( 0.0f, A, B ) = A - nlerp ( 1.0f, A, B ) = B - @remarks - Nlerp is faster than Slerp. - Nlerp has the proprieties of being commutative (@see Slerp; - commutativity is desired in certain places, like IK animation), and - being torque-minimal (unless shortestPath=false). However, it's performing - the interpolation at non-constant velocity; sometimes this is desired, - sometimes it is not. Having a non-constant velocity can produce a more - natural rotation feeling without the need of tweaking the weights; however - if your scene relies on the timing of the rotation or assumes it will point - at a specific angle at a specific weight value, Slerp is a better choice. - */ + nlerp ( 0.0f, A, B ) = A + nlerp ( 1.0f, A, B ) = B + @remarks + Nlerp is faster than Slerp. + Nlerp has the proprieties of being commutative (@see Slerp; + commutativity is desired in certain places, like IK animation), and + being torque-minimal (unless shortestPath=false). However, it's performing + the interpolation at non-constant velocity; sometimes this is desired, + sometimes it is not. Having a non-constant velocity can produce a more + natural rotation feeling without the need of tweaking the weights; however + if your scene relies on the timing of the rotation or assumes it will point + at a specific angle at a specific weight value, Slerp is a better choice. + */ static Quaternion nlerp(Real fT, const Quaternion& rkP, const Quaternion& rkQ, bool shortestPath = false); @@ -300,13 +300,13 @@ namespace Ogre { static const Quaternion ZERO; static const Quaternion IDENTITY; - Real w, x, y, z; + Real w, x, y, z; - /// Check whether this quaternion contains valid values - inline bool isNaN() const - { - return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z) || Math::isNaN(w); - } + /// Check whether this quaternion contains valid values + inline bool isNaN() const + { + return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z) || Math::isNaN(w); + } /** Function for writing to a stream. Outputs "Quaternion(w, x, y, z)" with w,x,y,z being the member values of the quaternion. @@ -319,8 +319,8 @@ namespace Ogre { } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreRadixSort.h b/OgreMain/include/OgreRadixSort.h index 30f81e5d322..63c4701d212 100644 --- a/OgreMain/include/OgreRadixSort.h +++ b/OgreMain/include/OgreRadixSort.h @@ -32,298 +32,298 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** Class for performing a radix sort (fast comparison-less sort based on - byte value) on various standard STL containers. - @remarks - A radix sort is a very fast sort algorithm. It doesn't use comparisons - and thus is able to break the theoretical minimum O(N*logN) complexity. - Radix sort is complexity O(k*N), where k is a constant. Note that radix - sorting is not in-place, it requires additional storage, so it trades - memory for speed. The overhead of copying means that it is only faster - for fairly large datasets, so you are advised to only use it for collections - of at least a few hundred items. - @par - This is a template class to allow it to deal with a variety of containers, - and a variety of value types to sort on. In addition to providing the - container and value type on construction, you also need to supply a - functor object which will retrieve the value to compare on for each item - in the list. For example, if you had an std::vector of by-value instances - of an object of class 'Bibble', and you wanted to sort on - Bibble::getDoobrie(), you'd have to firstly create a functor - like this: - @code - struct BibbleSortFunctor - { - float operator()(const Bibble& val) const - { - return val.getDoobrie(); - } - } - @endcode - Then, you need to declare a RadixSort class which names the container type, - the value type in the container, and the type of the value you want to - sort by. You can then call the sort function. E.g. - @code - RadixSort radixSorter; - BibbleSortFunctor functor; - - radixSorter.sort(myBibbleList, functor); - @endcode - You should try to reuse RadixSort instances, since repeated allocation of the - internal storage is then avoided. - @note - Radix sorting is often associated with just unsigned integer values. Our - implementation can handle both unsigned and signed integers, as well as - floats (which are often not supported by other radix sorters). doubles - are not supported; you will need to implement your functor object to convert - to float if you wish to use this sort routine. - */ - template - class RadixSort - { - public: - typedef typename TContainer::iterator ContainerIter; - protected: - /// Alpha-pass counters of values (histogram) - /// 4 of them so we can radix sort a maximum of a 32bit value - int mCounters[4][256]; - /// Beta-pass offsets - int mOffsets[256]; - /// Sort area size - int mSortSize; - /// Number of passes for this type - int mNumPasses; - - struct SortEntry - { - TCompValueType key; - ContainerIter iter; - SortEntry() {} - SortEntry(TCompValueType k, ContainerIter it) - : key(k), iter(it) {} - - }; - /// Temp sort storage - typedef std::vector > SortVector; - SortVector mSortArea1; - SortVector mSortArea2; - SortVector* mSrc; - SortVector* mDest; - TContainer mTmpContainer; // initial copy - - - void sortPass(int byteIndex) - { - // Calculate offsets - // Basically this just leaves gaps for duplicate entries to fill - mOffsets[0] = 0; - for (int i = 1; i < 256; ++i) - { - mOffsets[i] = mOffsets[i-1] + mCounters[byteIndex][i-1]; - } - - // Sort pass - for (int i = 0; i < mSortSize; ++i) - { - unsigned char byteVal = getByte(byteIndex, (*mSrc)[i].key); - (*mDest)[mOffsets[byteVal]++] = (*mSrc)[i]; - } - - } - template - void finalPass(int byteIndex, T val) - { - // default is to do normal pass - sortPass(byteIndex); - } - - // special case signed int - void finalPass(int byteIndex, int val) - { - int numNeg = 0; - // all negative values are in entries 128+ in most significant byte - for (int i = 128; i < 256; ++i) - { - numNeg += mCounters[byteIndex][i]; - } - // Calculate offsets - positive ones start at the number of negatives - // do positive numbers - mOffsets[0] = numNeg; - for (int i = 1; i < 128; ++i) - { - mOffsets[i] = mOffsets[i-1] + mCounters[byteIndex][i-1]; - } - // Do negative numbers (must start at zero) - // No need to invert ordering, already correct (-1 is highest number) - mOffsets[128] = 0; - for (int i = 129; i < 256; ++i) - { - mOffsets[i] = mOffsets[i-1] + mCounters[byteIndex][i-1]; - } - - // Sort pass - for (int i = 0; i < mSortSize; ++i) - { - unsigned char byteVal = getByte(byteIndex, (*mSrc)[i].key); - (*mDest)[mOffsets[byteVal]++] = (*mSrc)[i]; - } - } - - - // special case float - void finalPass(int byteIndex, float val) - { - // floats need to be special cased since negative numbers will come - // after positives (high bit = sign) and will be in reverse order - // (no ones-complement of the +ve value) - int numNeg = 0; - // all negative values are in entries 128+ in most significant byte - for (int i = 128; i < 256; ++i) - { - numNeg += mCounters[byteIndex][i]; - } - // Calculate offsets - positive ones start at the number of negatives - // do positive numbers normally - mOffsets[0] = numNeg; - for (int i = 1; i < 128; ++i) - { - mOffsets[i] = mOffsets[i-1] + mCounters[byteIndex][i-1]; - } - // Do negative numbers (must start at zero) - // Also need to invert ordering - // In order to preserve the stability of the sort (essential since - // we rely on previous bytes already being sorted) we have to count - // backwards in our offsets from - mOffsets[255] = mCounters[byteIndex][255]; - for (int i = 254; i > 127; --i) - { - mOffsets[i] = mOffsets[i+1] + mCounters[byteIndex][i]; - } - - // Sort pass - for (int i = 0; i < mSortSize; ++i) - { - unsigned char byteVal = getByte(byteIndex, (*mSrc)[i].key); - if (byteVal > 127) - { - // -ve; pre-decrement since offsets set to count - (*mDest)[--mOffsets[byteVal]] = (*mSrc)[i]; - } - else - { - // +ve - (*mDest)[mOffsets[byteVal]++] = (*mSrc)[i]; - } - } - } - - inline unsigned char getByte(int byteIndex, TCompValueType val) - { + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** Class for performing a radix sort (fast comparison-less sort based on + byte value) on various standard STL containers. + @remarks + A radix sort is a very fast sort algorithm. It doesn't use comparisons + and thus is able to break the theoretical minimum O(N*logN) complexity. + Radix sort is complexity O(k*N), where k is a constant. Note that radix + sorting is not in-place, it requires additional storage, so it trades + memory for speed. The overhead of copying means that it is only faster + for fairly large datasets, so you are advised to only use it for collections + of at least a few hundred items. + @par + This is a template class to allow it to deal with a variety of containers, + and a variety of value types to sort on. In addition to providing the + container and value type on construction, you also need to supply a + functor object which will retrieve the value to compare on for each item + in the list. For example, if you had an std::vector of by-value instances + of an object of class 'Bibble', and you wanted to sort on + Bibble::getDoobrie(), you'd have to firstly create a functor + like this: + @code + struct BibbleSortFunctor + { + float operator()(const Bibble& val) const + { + return val.getDoobrie(); + } + } + @endcode + Then, you need to declare a RadixSort class which names the container type, + the value type in the container, and the type of the value you want to + sort by. You can then call the sort function. E.g. + @code + RadixSort radixSorter; + BibbleSortFunctor functor; + + radixSorter.sort(myBibbleList, functor); + @endcode + You should try to reuse RadixSort instances, since repeated allocation of the + internal storage is then avoided. + @note + Radix sorting is often associated with just unsigned integer values. Our + implementation can handle both unsigned and signed integers, as well as + floats (which are often not supported by other radix sorters). doubles + are not supported; you will need to implement your functor object to convert + to float if you wish to use this sort routine. + */ + template + class RadixSort + { + public: + typedef typename TContainer::iterator ContainerIter; + protected: + /// Alpha-pass counters of values (histogram) + /// 4 of them so we can radix sort a maximum of a 32bit value + int mCounters[4][256]; + /// Beta-pass offsets + int mOffsets[256]; + /// Sort area size + int mSortSize; + /// Number of passes for this type + int mNumPasses; + + struct SortEntry + { + TCompValueType key; + ContainerIter iter; + SortEntry() {} + SortEntry(TCompValueType k, ContainerIter it) + : key(k), iter(it) {} + + }; + /// Temp sort storage + typedef std::vector > SortVector; + SortVector mSortArea1; + SortVector mSortArea2; + SortVector* mSrc; + SortVector* mDest; + TContainer mTmpContainer; // initial copy + + + void sortPass(int byteIndex) + { + // Calculate offsets + // Basically this just leaves gaps for duplicate entries to fill + mOffsets[0] = 0; + for (int i = 1; i < 256; ++i) + { + mOffsets[i] = mOffsets[i-1] + mCounters[byteIndex][i-1]; + } + + // Sort pass + for (int i = 0; i < mSortSize; ++i) + { + unsigned char byteVal = getByte(byteIndex, (*mSrc)[i].key); + (*mDest)[mOffsets[byteVal]++] = (*mSrc)[i]; + } + + } + template + void finalPass(int byteIndex, T val) + { + // default is to do normal pass + sortPass(byteIndex); + } + + // special case signed int + void finalPass(int byteIndex, int val) + { + int numNeg = 0; + // all negative values are in entries 128+ in most significant byte + for (int i = 128; i < 256; ++i) + { + numNeg += mCounters[byteIndex][i]; + } + // Calculate offsets - positive ones start at the number of negatives + // do positive numbers + mOffsets[0] = numNeg; + for (int i = 1; i < 128; ++i) + { + mOffsets[i] = mOffsets[i-1] + mCounters[byteIndex][i-1]; + } + // Do negative numbers (must start at zero) + // No need to invert ordering, already correct (-1 is highest number) + mOffsets[128] = 0; + for (int i = 129; i < 256; ++i) + { + mOffsets[i] = mOffsets[i-1] + mCounters[byteIndex][i-1]; + } + + // Sort pass + for (int i = 0; i < mSortSize; ++i) + { + unsigned char byteVal = getByte(byteIndex, (*mSrc)[i].key); + (*mDest)[mOffsets[byteVal]++] = (*mSrc)[i]; + } + } + + + // special case float + void finalPass(int byteIndex, float val) + { + // floats need to be special cased since negative numbers will come + // after positives (high bit = sign) and will be in reverse order + // (no ones-complement of the +ve value) + int numNeg = 0; + // all negative values are in entries 128+ in most significant byte + for (int i = 128; i < 256; ++i) + { + numNeg += mCounters[byteIndex][i]; + } + // Calculate offsets - positive ones start at the number of negatives + // do positive numbers normally + mOffsets[0] = numNeg; + for (int i = 1; i < 128; ++i) + { + mOffsets[i] = mOffsets[i-1] + mCounters[byteIndex][i-1]; + } + // Do negative numbers (must start at zero) + // Also need to invert ordering + // In order to preserve the stability of the sort (essential since + // we rely on previous bytes already being sorted) we have to count + // backwards in our offsets from + mOffsets[255] = mCounters[byteIndex][255]; + for (int i = 254; i > 127; --i) + { + mOffsets[i] = mOffsets[i+1] + mCounters[byteIndex][i]; + } + + // Sort pass + for (int i = 0; i < mSortSize; ++i) + { + unsigned char byteVal = getByte(byteIndex, (*mSrc)[i].key); + if (byteVal > 127) + { + // -ve; pre-decrement since offsets set to count + (*mDest)[--mOffsets[byteVal]] = (*mSrc)[i]; + } + else + { + // +ve + (*mDest)[mOffsets[byteVal]++] = (*mSrc)[i]; + } + } + } + + inline unsigned char getByte(int byteIndex, TCompValueType val) + { #if OGRE_ENDIAN == OGRE_ENDIAN_LITTLE - return ((unsigned char*)(&val))[byteIndex]; + return ((unsigned char*)(&val))[byteIndex]; #else - return ((unsigned char*)(&val))[mNumPasses - byteIndex - 1]; + return ((unsigned char*)(&val))[mNumPasses - byteIndex - 1]; #endif - } - - public: - - RadixSort() {} - ~RadixSort() {} - - /** Main sort function - @param container A container of the type you declared when declaring - @param func A functor which returns the value for comparison when given - a container value - */ - template - void sort(TContainer& container, TFunction func) - { - if (container.empty()) - return; - - // Set up the sort areas - mSortSize = static_cast(container.size()); - mSortArea1.resize(container.size()); - mSortArea2.resize(container.size()); - - // Copy data now (we need constant iterators for sorting) - mTmpContainer = container; - - mNumPasses = sizeof(TCompValueType); - - // Counter pass - // Initialise the counts - int p; - for (p = 0; p < mNumPasses; ++p) - memset(mCounters[p], 0, sizeof(int) * 256); - - // Perform alpha pass to count - ContainerIter i = mTmpContainer.begin(); - TCompValueType prevValue = func.operator()(*i); - bool needsSorting = false; - for (int u = 0; i != mTmpContainer.end(); ++i, ++u) - { - // get sort value - TCompValueType val = func.operator()(*i); - // cheap check to see if needs sorting (temporal coherence) - if (!needsSorting && val < prevValue) - needsSorting = true; - - // Create a sort entry - mSortArea1[u].key = val; - mSortArea1[u].iter = i; - - // increase counters - for (p = 0; p < mNumPasses; ++p) - { - unsigned char byteVal = getByte(p, val); - mCounters[p][byteVal]++; - } - - prevValue = val; - - } - - // early exit if already sorted - if (!needsSorting) - return; - - - // Sort passes - mSrc = &mSortArea1; - mDest = &mSortArea2; - - for (p = 0; p < mNumPasses - 1; ++p) - { - sortPass(p); - // flip src/dst - SortVector* tmp = mSrc; - mSrc = mDest; - mDest = tmp; - } - // Final pass may differ, make polymorphic - finalPass(p, prevValue); - - // Copy everything back - int c = 0; - for (i = container.begin(); - i != container.end(); ++i, ++c) - { - *i = *((*mDest)[c].iter); - } - } - - }; - - /** @} */ - /** @} */ + } + + public: + + RadixSort() {} + ~RadixSort() {} + + /** Main sort function + @param container A container of the type you declared when declaring + @param func A functor which returns the value for comparison when given + a container value + */ + template + void sort(TContainer& container, TFunction func) + { + if (container.empty()) + return; + + // Set up the sort areas + mSortSize = static_cast(container.size()); + mSortArea1.resize(container.size()); + mSortArea2.resize(container.size()); + + // Copy data now (we need constant iterators for sorting) + mTmpContainer = container; + + mNumPasses = sizeof(TCompValueType); + + // Counter pass + // Initialise the counts + int p; + for (p = 0; p < mNumPasses; ++p) + memset(mCounters[p], 0, sizeof(int) * 256); + + // Perform alpha pass to count + ContainerIter i = mTmpContainer.begin(); + TCompValueType prevValue = func.operator()(*i); + bool needsSorting = false; + for (int u = 0; i != mTmpContainer.end(); ++i, ++u) + { + // get sort value + TCompValueType val = func.operator()(*i); + // cheap check to see if needs sorting (temporal coherence) + if (!needsSorting && val < prevValue) + needsSorting = true; + + // Create a sort entry + mSortArea1[u].key = val; + mSortArea1[u].iter = i; + + // increase counters + for (p = 0; p < mNumPasses; ++p) + { + unsigned char byteVal = getByte(p, val); + mCounters[p][byteVal]++; + } + + prevValue = val; + + } + + // early exit if already sorted + if (!needsSorting) + return; + + + // Sort passes + mSrc = &mSortArea1; + mDest = &mSortArea2; + + for (p = 0; p < mNumPasses - 1; ++p) + { + sortPass(p); + // flip src/dst + SortVector* tmp = mSrc; + mSrc = mDest; + mDest = tmp; + } + // Final pass may differ, make polymorphic + finalPass(p, prevValue); + + // Copy everything back + int c = 0; + for (i = container.begin(); + i != container.end(); ++i, ++c) + { + *i = *((*mDest)[c].iter); + } + } + + }; + + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreRay.h b/OgreMain/include/OgreRay.h index 79efebfbd21..e7c989193b7 100644 --- a/OgreMain/include/OgreRay.h +++ b/OgreMain/include/OgreRay.h @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Representation of a ray in space, i.e. a line with an origin and direction. */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Representation of a ray in space, i.e. a line with an origin and direction. */ class _OgreExport Ray { protected: @@ -62,26 +62,26 @@ namespace Ogre { /** Gets the direction of the ray. */ const Vector3& getDirection(void) const {return mDirection;} - /** Gets the position of a point t units along the ray. */ - Vector3 getPoint(Real t) const { - return Vector3(mOrigin + (mDirection * t)); - } - - /** Gets the position of a point t units along the ray. */ - Vector3 operator*(Real t) const { - return getPoint(t); - } + /** Gets the position of a point t units along the ray. */ + Vector3 getPoint(Real t) const { + return Vector3(mOrigin + (mDirection * t)); + } + + /** Gets the position of a point t units along the ray. */ + Vector3 operator*(Real t) const { + return getPoint(t); + } - /** Tests whether this ray intersects the given plane. - @return A pair structure where the first element indicates whether - an intersection occurs, and if true, the second element will - indicate the distance along the ray at which it intersects. - This can be converted to a point in space by calling getPoint(). - */ - std::pair intersects(const Plane& p) const - { - return Math::intersects(*this, p); - } + /** Tests whether this ray intersects the given plane. + @return A pair structure where the first element indicates whether + an intersection occurs, and if true, the second element will + indicate the distance along the ray at which it intersects. + This can be converted to a point in space by calling getPoint(). + */ + std::pair intersects(const Plane& p) const + { + return Math::intersects(*this, p); + } /** Tests whether this ray intersects the given plane bounded volume. @return A pair structure where the first element indicates whether an intersection occurs, and if true, the second element will @@ -92,30 +92,30 @@ namespace Ogre { { return Math::intersects(*this, p.planes, p.outside == Plane::POSITIVE_SIDE); } - /** Tests whether this ray intersects the given sphere. - @return A pair structure where the first element indicates whether - an intersection occurs, and if true, the second element will - indicate the distance along the ray at which it intersects. - This can be converted to a point in space by calling getPoint(). - */ - std::pair intersects(const Sphere& s) const - { - return Math::intersects(*this, s); - } - /** Tests whether this ray intersects the given box. - @return A pair structure where the first element indicates whether - an intersection occurs, and if true, the second element will - indicate the distance along the ray at which it intersects. - This can be converted to a point in space by calling getPoint(). - */ - std::pair intersects(const AxisAlignedBox& box) const - { - return Math::intersects(*this, box); - } + /** Tests whether this ray intersects the given sphere. + @return A pair structure where the first element indicates whether + an intersection occurs, and if true, the second element will + indicate the distance along the ray at which it intersects. + This can be converted to a point in space by calling getPoint(). + */ + std::pair intersects(const Sphere& s) const + { + return Math::intersects(*this, s); + } + /** Tests whether this ray intersects the given box. + @return A pair structure where the first element indicates whether + an intersection occurs, and if true, the second element will + indicate the distance along the ray at which it intersects. + This can be converted to a point in space by calling getPoint(). + */ + std::pair intersects(const AxisAlignedBox& box) const + { + return Math::intersects(*this, box); + } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreRectangle2D.h b/OgreMain/include/OgreRectangle2D.h index 6e31010cf7b..04ba2aeeabc 100644 --- a/OgreMain/include/OgreRectangle2D.h +++ b/OgreMain/include/OgreRectangle2D.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Allows the rendering of a simple 2D rectangle + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Allows the rendering of a simple 2D rectangle This class renders a simple 2D rectangle; this rectangle has no depth and therefore is best used with specific render queue and depth settings, like RENDER_QUEUE_BACKGROUND and 'depth_write off' for backdrops, and @@ -67,23 +67,23 @@ namespace Ogre { @param top Top position in screen relative coordinates, 1 = top edge, -1 = bottom edge @param right Right position in screen relative coordinates @param bottom Bottom position in screen relative coordinates - @param updateAABB Tells if you want to recalculate the AABB according to - the new corners. If false, the axis aligned bounding box will remain identical. + @param updateAABB Tells if you want to recalculate the AABB according to + the new corners. If false, the axis aligned bounding box will remain identical. */ void setCorners(Real left, Real top, Real right, Real bottom, bool updateAABB = true); - /** Sets the normals of the rectangle - */ - void setNormals(const Ogre::Vector3 &topLeft, const Ogre::Vector3 &bottomLeft, const Ogre::Vector3 &topRight, const Ogre::Vector3 &bottomRight); + /** Sets the normals of the rectangle + */ + void setNormals(const Ogre::Vector3 &topLeft, const Ogre::Vector3 &bottomLeft, const Ogre::Vector3 &topRight, const Ogre::Vector3 &bottomRight); - /** Sets the UVs of the rectangle - @remarks - Doesn't do anything if the rectangle wasn't built with texture coordinates - */ - void setUVs( const Ogre::Vector2 &topLeft, const Ogre::Vector2 &bottomLeft, - const Ogre::Vector2 &topRight, const Ogre::Vector2 &bottomRight); + /** Sets the UVs of the rectangle + @remarks + Doesn't do anything if the rectangle wasn't built with texture coordinates + */ + void setUVs( const Ogre::Vector2 &topLeft, const Ogre::Vector2 &bottomLeft, + const Ogre::Vector2 &topRight, const Ogre::Vector2 &bottomRight); - void setDefaultUVs(); + void setDefaultUVs(); Real getSquaredViewDepth(const Camera* cam) const { (void)cam; return 0; } @@ -91,8 +91,8 @@ namespace Ogre { Real getBoundingRadius(void) const { return 0; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ }// namespace diff --git a/OgreMain/include/OgreRenderQueue.h b/OgreMain/include/OgreRenderQueue.h index 951a2bb60c1..e2dcec2b713 100644 --- a/OgreMain/include/OgreRenderQueue.h +++ b/OgreMain/include/OgreRenderQueue.h @@ -34,21 +34,21 @@ THE SOFTWARE. namespace Ogre { - class Camera; - class MovableObject; - struct VisibleObjectsBoundsInfo; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Enumeration of queue groups, by which the application may group queued renderables + class Camera; + class MovableObject; + struct VisibleObjectsBoundsInfo; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Enumeration of queue groups, by which the application may group queued renderables so that they are rendered together with events in between - @remarks - When passed into methods these are actually passed as a uint8 to allow you - to use values in between if you want to. + @remarks + When passed into methods these are actually passed as a uint8 to allow you + to use values in between if you want to. */ enum RenderQueueGroupID { @@ -58,22 +58,22 @@ namespace Ogre { RENDER_QUEUE_SKIES_EARLY = 5, RENDER_QUEUE_1 = 10, RENDER_QUEUE_2 = 20, - RENDER_QUEUE_WORLD_GEOMETRY_1 = 25, + RENDER_QUEUE_WORLD_GEOMETRY_1 = 25, RENDER_QUEUE_3 = 30, RENDER_QUEUE_4 = 40, - /// The default render queue + /// The default render queue RENDER_QUEUE_MAIN = 50, RENDER_QUEUE_6 = 60, RENDER_QUEUE_7 = 70, - RENDER_QUEUE_WORLD_GEOMETRY_2 = 75, + RENDER_QUEUE_WORLD_GEOMETRY_2 = 75, RENDER_QUEUE_8 = 80, RENDER_QUEUE_9 = 90, /// Penultimate queue(before overlays), used for skyboxes if rendered last RENDER_QUEUE_SKIES_LATE = 95, /// Use this queue for objects which must be rendered last e.g. overlays RENDER_QUEUE_OVERLAY = 100, - /// Final possible render queue, don't exceed this - RENDER_QUEUE_MAX = 105 + /// Final possible render queue, don't exceed this + RENDER_QUEUE_MAX = 105 }; #define OGRE_RENDERABLE_DEFAULT_PRIORITY 100 @@ -98,39 +98,39 @@ namespace Ogre { typedef MapIterator QueueGroupIterator; typedef ConstMapIterator ConstQueueGroupIterator; - /** Class to listen in on items being added to the render queue. - @remarks - Use RenderQueue::setRenderableListener to get callbacks when an item - is added to the render queue. - */ - class _OgreExport RenderableListener - { - public: - RenderableListener() {} - virtual ~RenderableListener() {} - - /** Method called when a Renderable is added to the queue. - @remarks - You can use this event hook to alter the Technique used to - render a Renderable as the item is added to the queue. This is - a low-level way to override the material settings for a given - Renderable on the fly. - @param rend The Renderable being added to the queue - @param groupID The render queue group this Renderable is being added to - @param priority The priority the Renderable has been given - @param ppTech A pointer to the pointer to the Technique that is - intended to be used; you can alter this to an alternate Technique - if you so wish (the Technique doesn't have to be from the same - Material either). - @param pQueue Pointer to the render queue that this object is being - added to. You can for example call this back to duplicate the - object with a different technique - @return true to allow the Renderable to be added to the queue, - false if you want to prevent it being added - */ - virtual bool renderableQueued(Renderable* rend, uint8 groupID, - ushort priority, Technique** ppTech, RenderQueue* pQueue) = 0; - }; + /** Class to listen in on items being added to the render queue. + @remarks + Use RenderQueue::setRenderableListener to get callbacks when an item + is added to the render queue. + */ + class _OgreExport RenderableListener + { + public: + RenderableListener() {} + virtual ~RenderableListener() {} + + /** Method called when a Renderable is added to the queue. + @remarks + You can use this event hook to alter the Technique used to + render a Renderable as the item is added to the queue. This is + a low-level way to override the material settings for a given + Renderable on the fly. + @param rend The Renderable being added to the queue + @param groupID The render queue group this Renderable is being added to + @param priority The priority the Renderable has been given + @param ppTech A pointer to the pointer to the Technique that is + intended to be used; you can alter this to an alternate Technique + if you so wish (the Technique doesn't have to be from the same + Material either). + @param pQueue Pointer to the render queue that this object is being + added to. You can for example call this back to duplicate the + object with a different technique + @return true to allow the Renderable to be added to the queue, + false if you want to prevent it being added + */ + virtual bool renderableQueued(Renderable* rend, uint8 groupID, + ushort priority, Technique** ppTech, RenderQueue* pQueue) = 0; + }; protected: RenderQueueGroupMap mGroups; /// The current default queue group @@ -140,25 +140,25 @@ namespace Ogre { bool mSplitPassesByLightingType; bool mSplitNoShadowPasses; - bool mShadowCastersCannotBeReceivers; + bool mShadowCastersCannotBeReceivers; - RenderableListener* mRenderableListener; + RenderableListener* mRenderableListener; public: RenderQueue(); virtual ~RenderQueue(); /** Empty the queue - should only be called by SceneManagers. - @param destroyPassMaps Set to true to destroy all pass maps so that - the queue is completely clean (useful when switching scene managers) + @param destroyPassMaps Set to true to destroy all pass maps so that + the queue is completely clean (useful when switching scene managers) */ void clear(bool destroyPassMaps = false); - /** Get a render queue group. - @remarks - OGRE registers new queue groups as they are requested, - therefore this method will always return a valid group. - */ - RenderQueueGroup* getQueueGroup(uint8 qid); + /** Get a render queue group. + @remarks + OGRE registers new queue groups as they are requested, + therefore this method will always return a valid group. + */ + RenderQueueGroup* getQueueGroup(uint8 qid); /** Add a renderable object to the queue. @remarks @@ -194,7 +194,7 @@ namespace Ogre { Called by implementation of MovableObject::_updateRenderQueue. @param pRend Pointer to the Renderable to be added to the queue - @param groupId + @param groupId The group the renderable is to be added to. This can be used to schedule renderable objects in separate groups such that the SceneManager respects the divisions between the groupings and does not reorder them outside these @@ -235,7 +235,7 @@ namespace Ogre { /** Sets the current default queue group, which will be used for all renderable which do not specify which group they wish to be on. See the enum RenderQueueGroupID for what kind of - values can be used here. + values can be used here. */ void setDefaultQueueGroup(uint8 grp); @@ -265,44 +265,44 @@ namespace Ogre { */ bool getSplitNoShadowPasses(void) const; - /** Sets whether or not objects which cast shadows should be treated as - never receiving shadows. - */ - void setShadowCastersCannotBeReceivers(bool ind); - - /** Gets whether or not objects which cast shadows should be treated as - never receiving shadows. - */ - bool getShadowCastersCannotBeReceivers(void) const; - - /** Set a renderable listener on the queue. - @remarks - There can only be a single renderable listener on the queue, since - that listener has complete control over the techniques in use. - */ - void setRenderableListener(RenderableListener* listener) - { mRenderableListener = listener; } - - RenderableListener* getRenderableListener(void) const - { return mRenderableListener; } - - /** Merge render queue. - */ - void merge( const RenderQueue* rhs ); - /** Utility method to perform the standard actions associated with - getting a visible object to add itself to the queue. This is - a replacement for SceneManager implementations of the associated - tasks related to calling MovableObject::_updateRenderQueue. - */ - void processVisibleObject(MovableObject* mo, - Camera* cam, - bool onlyShadowCasters, - VisibleObjectsBoundsInfo* visibleBounds); + /** Sets whether or not objects which cast shadows should be treated as + never receiving shadows. + */ + void setShadowCastersCannotBeReceivers(bool ind); + + /** Gets whether or not objects which cast shadows should be treated as + never receiving shadows. + */ + bool getShadowCastersCannotBeReceivers(void) const; + + /** Set a renderable listener on the queue. + @remarks + There can only be a single renderable listener on the queue, since + that listener has complete control over the techniques in use. + */ + void setRenderableListener(RenderableListener* listener) + { mRenderableListener = listener; } + + RenderableListener* getRenderableListener(void) const + { return mRenderableListener; } + + /** Merge render queue. + */ + void merge( const RenderQueue* rhs ); + /** Utility method to perform the standard actions associated with + getting a visible object to add itself to the queue. This is + a replacement for SceneManager implementations of the associated + tasks related to calling MovableObject::_updateRenderQueue. + */ + void processVisibleObject(MovableObject* mo, + Camera* cam, + bool onlyShadowCasters, + VisibleObjectsBoundsInfo* visibleBounds); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreRenderQueueInvocation.h b/OgreMain/include/OgreRenderQueueInvocation.h index 22136f8f729..651fd5f5118 100644 --- a/OgreMain/include/OgreRenderQueueInvocation.h +++ b/OgreMain/include/OgreRenderQueueInvocation.h @@ -33,190 +33,190 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Class representing the invocation of queue groups in a RenderQueue. - @remarks - The default behaviour for OGRE's render queue is to render each queue - group in turn, dealing with shadows automatically, and rendering solids - in grouped passes, followed by transparent objects in descending order. - This class, together with RenderQueueInvocationSequence and the ability - to associate one with a Viewport, allows you to change that behaviour - and render queue groups in arbitrary sequence, repeatedly, and to skip - shadows, change the ordering of solids, or even prevent OGRE controlling - the render state during a particular invocation for special effects. - @par - Note that whilst you can change the ordering of rendering solids, you - can't change the ordering on transparent objects, since to do this would - cause them to render incorrectly. - @par - As well as using this class directly and using the options it provides you - with, you can also provide subclasses of it to a - RenderQueueInvocationSequence instance if you want to gain ultimate control. - @note - Invocations will be skipped if there are scene-level options preventing - them being rendered - for example special-case render queues and - render queue listeners that dictate this. - */ - class _OgreExport RenderQueueInvocation : public RenderQueueAlloc - { - protected: - /// Target queue group - uint8 mRenderQueueGroupID; - /// Invocation identifier - used in listeners - String mInvocationName; - /// Solids ordering mode - QueuedRenderableCollection::OrganisationMode mSolidsOrganisation; - /// Suppress shadows processing in this invocation? - bool mSuppressShadows; - /// Suppress OGRE's render state management? - bool mSuppressRenderStateChanges; - public: - /** Constructor - @param renderQueueGroupID ID of the queue this will target - @param invocationName Optional name to uniquely identify this - invocation from others in a RenderQueueListener - */ - RenderQueueInvocation(uint8 renderQueueGroupID, - const String& invocationName = BLANKSTRING); - virtual ~RenderQueueInvocation(); - - /// Get the render queue group id - virtual uint8 getRenderQueueGroupID(void) const { return mRenderQueueGroupID; } - - /// Get the invocation name (may be blank if not set by creator) - virtual const String& getInvocationName(void) const { return mInvocationName; } - - /** Set the organisation mode being used for solids in this queue group - invocation. - */ - virtual void setSolidsOrganisation( - QueuedRenderableCollection::OrganisationMode org) - { mSolidsOrganisation = org; } - - /** Get the organisation mode being used for solids in this queue group - invocation. - */ - virtual QueuedRenderableCollection::OrganisationMode - getSolidsOrganisation(void) const { return mSolidsOrganisation; } - - /** Sets whether shadows are suppressed when invoking this queue. - @remarks - When doing effects you often will want to suppress shadow processing - if shadows will already have been done by a previous render. - */ - virtual void setSuppressShadows(bool suppress) - { mSuppressShadows = suppress; } - - /** Gets whether shadows are suppressed when invoking this queue. - */ - virtual bool getSuppressShadows(void) const { return mSuppressShadows; } - - /** Sets whether render state changes are suppressed when invoking this queue. - @remarks - When doing special effects you may want to set up render state yourself - and have it apply for the entire rendering of a queue. In that case, - you should call this method with a parameter of 'true', and use a - RenderQueueListener to set the render state directly on RenderSystem - yourself before the invocation. - @par - Suppressing render state changes is only intended for advanced use, - don't use it if you're unsure of the effect. The only RenderSystem - calls made are to set the world matrix for each object (note - - view an projection matrices are NOT SET - they are under your control) - and to render the object; it is up to the caller to do everything else, - including enabling any vertex / fragment programs and updating their - parameter state, and binding parameters to the RenderSystem. - We advise you use a RenderQueueListener in order to get a notification - when this invocation is going to happen (use an invocation name to - identify it if you like), at which point you can set the state you - need to apply before the objects are rendered. - */ - virtual void setSuppressRenderStateChanges(bool suppress) - { mSuppressRenderStateChanges = suppress; } - - /** Gets whether shadows are suppressed when invoking this queue. - */ - virtual bool getSuppressRenderStateChanges(void) const { return mSuppressRenderStateChanges; } - - /** Invoke this class on a concrete queue group. - @remarks - Implementation will send the queue group to the target scene manager - after doing what it needs to do. - */ - virtual void invoke(RenderQueueGroup* group, SceneManager* targetSceneManager); - - /// Invocation identifier for shadows - static String RENDER_QUEUE_INVOCATION_SHADOWS; - }; - - - /// List of RenderQueueInvocations - typedef vector::type RenderQueueInvocationList; - typedef VectorIterator RenderQueueInvocationIterator; - - /** Class to hold a linear sequence of RenderQueueInvocation objects. - @remarks - This is just a simple data holder class which contains a list of - RenderQueueInvocation objects representing the sequence of invocations - made for a viewport. It's only real purpose is to ensure that - RenderQueueInvocation instances are deleted on shutdown, since you can - provide your own subclass instances on RenderQueueInvocation. Remember - that any invocation instances you give to this class will be deleted - by it when it is cleared / destroyed. - */ - class _OgreExport RenderQueueInvocationSequence : public RenderQueueAlloc - { - protected: - String mName; - RenderQueueInvocationList mInvocations; - public: - RenderQueueInvocationSequence(const String& name); - virtual ~RenderQueueInvocationSequence(); - - /** Get the name of this sequence. */ - const String& getName(void) const { return mName; } - - /** Add a standard invocation to the sequence. - @param renderQueueGroupID The ID of the render queue group - @param invocationName Optional name to identify the invocation, useful - for listeners if a single queue group is invoked more than once - @return A new RenderQueueInvocatin instance which you may customise - */ - RenderQueueInvocation* add(uint8 renderQueueGroupID, - const String& invocationName); - - /** Add a custom invocation to the sequence. - @remarks - Use this to add your own custom subclasses of RenderQueueInvocation - to the sequence; just remember that this class takes ownership of - deleting this pointer when it is cleared / destroyed. - */ - void add(RenderQueueInvocation* i); - - /** Get the number of invocations in this sequence. */ - size_t size(void) const { return mInvocations.size(); } - - /** Clear and delete all invocations in this sequence. */ - void clear(void); - - /** Gets the details of an invocation at a given index. */ - RenderQueueInvocation* get(size_t index); - - /** Removes (and deletes) an invocation by index. */ - void remove(size_t index); - - /** Get an iterator over the invocations. */ - RenderQueueInvocationIterator iterator(void); - - - }; - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Class representing the invocation of queue groups in a RenderQueue. + @remarks + The default behaviour for OGRE's render queue is to render each queue + group in turn, dealing with shadows automatically, and rendering solids + in grouped passes, followed by transparent objects in descending order. + This class, together with RenderQueueInvocationSequence and the ability + to associate one with a Viewport, allows you to change that behaviour + and render queue groups in arbitrary sequence, repeatedly, and to skip + shadows, change the ordering of solids, or even prevent OGRE controlling + the render state during a particular invocation for special effects. + @par + Note that whilst you can change the ordering of rendering solids, you + can't change the ordering on transparent objects, since to do this would + cause them to render incorrectly. + @par + As well as using this class directly and using the options it provides you + with, you can also provide subclasses of it to a + RenderQueueInvocationSequence instance if you want to gain ultimate control. + @note + Invocations will be skipped if there are scene-level options preventing + them being rendered - for example special-case render queues and + render queue listeners that dictate this. + */ + class _OgreExport RenderQueueInvocation : public RenderQueueAlloc + { + protected: + /// Target queue group + uint8 mRenderQueueGroupID; + /// Invocation identifier - used in listeners + String mInvocationName; + /// Solids ordering mode + QueuedRenderableCollection::OrganisationMode mSolidsOrganisation; + /// Suppress shadows processing in this invocation? + bool mSuppressShadows; + /// Suppress OGRE's render state management? + bool mSuppressRenderStateChanges; + public: + /** Constructor + @param renderQueueGroupID ID of the queue this will target + @param invocationName Optional name to uniquely identify this + invocation from others in a RenderQueueListener + */ + RenderQueueInvocation(uint8 renderQueueGroupID, + const String& invocationName = BLANKSTRING); + virtual ~RenderQueueInvocation(); + + /// Get the render queue group id + virtual uint8 getRenderQueueGroupID(void) const { return mRenderQueueGroupID; } + + /// Get the invocation name (may be blank if not set by creator) + virtual const String& getInvocationName(void) const { return mInvocationName; } + + /** Set the organisation mode being used for solids in this queue group + invocation. + */ + virtual void setSolidsOrganisation( + QueuedRenderableCollection::OrganisationMode org) + { mSolidsOrganisation = org; } + + /** Get the organisation mode being used for solids in this queue group + invocation. + */ + virtual QueuedRenderableCollection::OrganisationMode + getSolidsOrganisation(void) const { return mSolidsOrganisation; } + + /** Sets whether shadows are suppressed when invoking this queue. + @remarks + When doing effects you often will want to suppress shadow processing + if shadows will already have been done by a previous render. + */ + virtual void setSuppressShadows(bool suppress) + { mSuppressShadows = suppress; } + + /** Gets whether shadows are suppressed when invoking this queue. + */ + virtual bool getSuppressShadows(void) const { return mSuppressShadows; } + + /** Sets whether render state changes are suppressed when invoking this queue. + @remarks + When doing special effects you may want to set up render state yourself + and have it apply for the entire rendering of a queue. In that case, + you should call this method with a parameter of 'true', and use a + RenderQueueListener to set the render state directly on RenderSystem + yourself before the invocation. + @par + Suppressing render state changes is only intended for advanced use, + don't use it if you're unsure of the effect. The only RenderSystem + calls made are to set the world matrix for each object (note - + view an projection matrices are NOT SET - they are under your control) + and to render the object; it is up to the caller to do everything else, + including enabling any vertex / fragment programs and updating their + parameter state, and binding parameters to the RenderSystem. + We advise you use a RenderQueueListener in order to get a notification + when this invocation is going to happen (use an invocation name to + identify it if you like), at which point you can set the state you + need to apply before the objects are rendered. + */ + virtual void setSuppressRenderStateChanges(bool suppress) + { mSuppressRenderStateChanges = suppress; } + + /** Gets whether shadows are suppressed when invoking this queue. + */ + virtual bool getSuppressRenderStateChanges(void) const { return mSuppressRenderStateChanges; } + + /** Invoke this class on a concrete queue group. + @remarks + Implementation will send the queue group to the target scene manager + after doing what it needs to do. + */ + virtual void invoke(RenderQueueGroup* group, SceneManager* targetSceneManager); + + /// Invocation identifier for shadows + static String RENDER_QUEUE_INVOCATION_SHADOWS; + }; + + + /// List of RenderQueueInvocations + typedef vector::type RenderQueueInvocationList; + typedef VectorIterator RenderQueueInvocationIterator; + + /** Class to hold a linear sequence of RenderQueueInvocation objects. + @remarks + This is just a simple data holder class which contains a list of + RenderQueueInvocation objects representing the sequence of invocations + made for a viewport. It's only real purpose is to ensure that + RenderQueueInvocation instances are deleted on shutdown, since you can + provide your own subclass instances on RenderQueueInvocation. Remember + that any invocation instances you give to this class will be deleted + by it when it is cleared / destroyed. + */ + class _OgreExport RenderQueueInvocationSequence : public RenderQueueAlloc + { + protected: + String mName; + RenderQueueInvocationList mInvocations; + public: + RenderQueueInvocationSequence(const String& name); + virtual ~RenderQueueInvocationSequence(); + + /** Get the name of this sequence. */ + const String& getName(void) const { return mName; } + + /** Add a standard invocation to the sequence. + @param renderQueueGroupID The ID of the render queue group + @param invocationName Optional name to identify the invocation, useful + for listeners if a single queue group is invoked more than once + @return A new RenderQueueInvocatin instance which you may customise + */ + RenderQueueInvocation* add(uint8 renderQueueGroupID, + const String& invocationName); + + /** Add a custom invocation to the sequence. + @remarks + Use this to add your own custom subclasses of RenderQueueInvocation + to the sequence; just remember that this class takes ownership of + deleting this pointer when it is cleared / destroyed. + */ + void add(RenderQueueInvocation* i); + + /** Get the number of invocations in this sequence. */ + size_t size(void) const { return mInvocations.size(); } + + /** Clear and delete all invocations in this sequence. */ + void clear(void); + + /** Gets the details of an invocation at a given index. */ + RenderQueueInvocation* get(size_t index); + + /** Removes (and deletes) an invocation by index. */ + void remove(size_t index); + + /** Get an iterator over the invocations. */ + RenderQueueInvocationIterator iterator(void); + + + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreRenderQueueListener.h b/OgreMain/include/OgreRenderQueueListener.h index 346b743e005..5b905791aba 100644 --- a/OgreMain/include/OgreRenderQueueListener.h +++ b/OgreMain/include/OgreRenderQueueListener.h @@ -33,13 +33,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Abstract interface which classes must implement if they wish to receive + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Abstract interface which classes must implement if they wish to receive events from the render queue. @remarks The OGRE render queue is divided into several queue groups, as defined by @@ -56,29 +56,29 @@ namespace Ogre { class _OgreExport RenderQueueListener { public: - virtual ~RenderQueueListener() {} + virtual ~RenderQueueListener() {} - /** Event raised before all render queues are processed. - */ - virtual void preRenderQueues() {} - /** Event raised after all render queues are processed. - */ - virtual void postRenderQueues() {} + /** Event raised before all render queues are processed. + */ + virtual void preRenderQueues() {} + /** Event raised after all render queues are processed. + */ + virtual void postRenderQueues() {} /** Event raised before a queue group is rendered. @remarks This method is called by the SceneManager before each queue group is rendered. @param queueGroupId The id of the queue group which is about to be rendered - @param invocation Name of the invocation which is causing this to be - called (@see RenderQueueInvocation) - @param skipThisInvocation A boolean passed by reference which is by default set to - false. If the event sets this to true, the queue will be skipped and not - rendered. Note that in this case the renderQueueEnded event will not be raised - for this queue group. + @param invocation Name of the invocation which is causing this to be + called (@see RenderQueueInvocation) + @param skipThisInvocation A boolean passed by reference which is by default set to + false. If the event sets this to true, the queue will be skipped and not + rendered. Note that in this case the renderQueueEnded event will not be raised + for this queue group. */ virtual void renderQueueStarted(uint8 queueGroupId, const String& invocation, - bool& skipThisInvocation) + bool& skipThisInvocation) { (void)queueGroupId; (void)invocation; (void)skipThisInvocation; } /** Event raised after a queue group is rendered. @@ -86,19 +86,19 @@ namespace Ogre { This method is called by the SceneManager after each queue group is rendered. @param queueGroupId The id of the queue group which has just been rendered - @param invocation Name of the invocation which is causing this to be - called (@see RenderQueueInvocation) - @param repeatThisInvocation A boolean passed by reference which is by default set to - false. If the event sets this to true, the queue which has just been - rendered will be repeated, and the renderQueueStarted and renderQueueEnded - events will also be fired for it again. + @param invocation Name of the invocation which is causing this to be + called (@see RenderQueueInvocation) + @param repeatThisInvocation A boolean passed by reference which is by default set to + false. If the event sets this to true, the queue which has just been + rendered will be repeated, and the renderQueueStarted and renderQueueEnded + events will also be fired for it again. */ virtual void renderQueueEnded(uint8 queueGroupId, const String& invocation, - bool& repeatThisInvocation) + bool& repeatThisInvocation) { (void)queueGroupId; (void)invocation; (void)repeatThisInvocation; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreRenderQueueSortingGrouping.h b/OgreMain/include/OgreRenderQueueSortingGrouping.h index 62c84abb1ef..91150cecba5 100644 --- a/OgreMain/include/OgreRenderQueueSortingGrouping.h +++ b/OgreMain/include/OgreRenderQueueSortingGrouping.h @@ -35,102 +35,102 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Struct associating a single Pass with a single Renderable. - This is used to for objects sorted by depth and thus not - grouped by pass. - */ - struct RenderablePass - { - /// Pointer to the Renderable details - Renderable* renderable; - /// Pointer to the Pass - Pass* pass; - - RenderablePass(Renderable* rend, Pass* p) :renderable(rend), pass(p) {} - }; - - - /** Visitor interface for items in a QueuedRenderableCollection. - @remarks - Those wishing to iterate over the items in a - QueuedRenderableCollection should implement this visitor pattern, - since internal organisation of the collection depends on the - sorting method in use. - */ - class _OgreExport QueuedRenderableVisitor - { - public: - QueuedRenderableVisitor() {} - virtual ~QueuedRenderableVisitor() {} - - /** Called when visiting a RenderablePass, i.e. items in a - sorted collection where items are not grouped by pass. - @remarks - If this is called, neither of the other 2 visit methods - will be called. - */ - virtual void visit(RenderablePass* rp) = 0; - - /* When visiting a collection grouped by pass, this is - called when the grouping pass changes. - @remarks - If this method is called, the RenderablePass visit - method will not be called for this collection. The - Renderable visit method will be called for each item - underneath the pass grouping level. - @return True to continue, false to skip the Renderables underneath - */ - virtual bool visit(const Pass* p) = 0; - /** Visit method called once per Renderable on a grouped - collection. - @remarks - If this method is called, the RenderablePass visit - method will not be called for this collection. - */ - virtual void visit(Renderable* r) = 0; - - - }; - - /** Lowest level collection of renderables. - @remarks - To iterate over items in this collection, you must call - the accept method and supply a QueuedRenderableVisitor. - The order of the iteration, and whether that iteration is - over a RenderablePass list or a 2-level grouped list which - causes a visit call at the Pass level, and a call for each - Renderable underneath. - */ - class _OgreExport QueuedRenderableCollection : public RenderQueueAlloc - { - public: - /** Organisation modes required for this collection. - @remarks - This affects the internal placement of the items added to this collection; - if only one type of sorting / grouping is to be required, then renderables - can be stored only once, whilst if multiple types are going to be needed - then internally there will be multiple organisations. Changing the organisation - needs to be done when the collection is empty. - */ - enum OrganisationMode - { - /// Group by pass - OM_PASS_GROUP = 1, - /// Sort descending camera distance - OM_SORT_DESCENDING = 2, - /** Sort ascending camera distance - Note value overlaps with descending since both use same sort - */ - OM_SORT_ASCENDING = 6 - }; - - protected: + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Struct associating a single Pass with a single Renderable. + This is used to for objects sorted by depth and thus not + grouped by pass. + */ + struct RenderablePass + { + /// Pointer to the Renderable details + Renderable* renderable; + /// Pointer to the Pass + Pass* pass; + + RenderablePass(Renderable* rend, Pass* p) :renderable(rend), pass(p) {} + }; + + + /** Visitor interface for items in a QueuedRenderableCollection. + @remarks + Those wishing to iterate over the items in a + QueuedRenderableCollection should implement this visitor pattern, + since internal organisation of the collection depends on the + sorting method in use. + */ + class _OgreExport QueuedRenderableVisitor + { + public: + QueuedRenderableVisitor() {} + virtual ~QueuedRenderableVisitor() {} + + /** Called when visiting a RenderablePass, i.e. items in a + sorted collection where items are not grouped by pass. + @remarks + If this is called, neither of the other 2 visit methods + will be called. + */ + virtual void visit(RenderablePass* rp) = 0; + + /* When visiting a collection grouped by pass, this is + called when the grouping pass changes. + @remarks + If this method is called, the RenderablePass visit + method will not be called for this collection. The + Renderable visit method will be called for each item + underneath the pass grouping level. + @return True to continue, false to skip the Renderables underneath + */ + virtual bool visit(const Pass* p) = 0; + /** Visit method called once per Renderable on a grouped + collection. + @remarks + If this method is called, the RenderablePass visit + method will not be called for this collection. + */ + virtual void visit(Renderable* r) = 0; + + + }; + + /** Lowest level collection of renderables. + @remarks + To iterate over items in this collection, you must call + the accept method and supply a QueuedRenderableVisitor. + The order of the iteration, and whether that iteration is + over a RenderablePass list or a 2-level grouped list which + causes a visit call at the Pass level, and a call for each + Renderable underneath. + */ + class _OgreExport QueuedRenderableCollection : public RenderQueueAlloc + { + public: + /** Organisation modes required for this collection. + @remarks + This affects the internal placement of the items added to this collection; + if only one type of sorting / grouping is to be required, then renderables + can be stored only once, whilst if multiple types are going to be needed + then internally there will be multiple organisations. Changing the organisation + needs to be done when the collection is empty. + */ + enum OrganisationMode + { + /// Group by pass + OM_PASS_GROUP = 1, + /// Sort descending camera distance + OM_SORT_DESCENDING = 2, + /** Sort ascending camera distance + Note value overlaps with descending since both use same sort + */ + OM_SORT_ASCENDING = 6 + }; + + protected: /// Comparator to order pass groups struct PassGroupLess { @@ -151,7 +151,7 @@ namespace Ogre { } }; /// Comparator to order objects by descending camera distance - struct DepthSortDescendingLess + struct DepthSortDescendingLess { const Camera* camera; @@ -172,16 +172,16 @@ namespace Ogre { // Different renderables, sort by depth Real adepth = a.renderable->getSquaredViewDepth(camera); Real bdepth = b.renderable->getSquaredViewDepth(camera); - if (Math::RealEqual(adepth, bdepth)) - { + if (Math::RealEqual(adepth, bdepth)) + { // Must return deterministic result, doesn't matter what return a.pass < b.pass; - } - else - { - // Sort DESCENDING by depth (i.e. far objects first) - return (adepth > bdepth); - } + } + else + { + // Sort DESCENDING by depth (i.e. far objects first) + return (adepth > bdepth); + } } } @@ -195,110 +195,110 @@ namespace Ogre { /** Map of pass to renderable lists, this is a grouping by pass. */ typedef map::type PassGroupRenderableMap; - /// Functor for accessing sort value 1 for radix sort (Pass) - struct RadixSortFunctorPass - { - uint32 operator()(const RenderablePass& p) const + /// Functor for accessing sort value 1 for radix sort (Pass) + struct RadixSortFunctorPass + { + uint32 operator()(const RenderablePass& p) const { return p.pass->getHash(); } - }; + }; /// Radix sorter for accessing sort value 1 (Pass) - static RadixSort msRadixSorter1; + static RadixSort msRadixSorter1; - /// Functor for descending sort value 2 for radix sort (distance) - struct RadixSortFunctorDistance - { - const Camera* camera; + /// Functor for descending sort value 2 for radix sort (distance) + struct RadixSortFunctorDistance + { + const Camera* camera; RadixSortFunctorDistance(const Camera* cam) : camera(cam) { } - float operator()(const RenderablePass& p) const + float operator()(const RenderablePass& p) const { // Sort DESCENDING by depth (ie far objects first), use negative distance // here because radix sorter always dealing with accessing sort return static_cast(- p.renderable->getSquaredViewDepth(camera)); } - }; + }; /// Radix sorter for sort value 2 (distance) - static RadixSort msRadixSorter2; - - /// Bitmask of the organisation modes requested - uint8 mOrganisationMode; - - /// Grouped - PassGroupRenderableMap mGrouped; - /// Sorted descending (can iterate backwards to get ascending) - RenderablePassList mSortedDescending; - - /// Internal visitor implementation - void acceptVisitorGrouped(QueuedRenderableVisitor* visitor) const; - /// Internal visitor implementation - void acceptVisitorDescending(QueuedRenderableVisitor* visitor) const; - /// Internal visitor implementation - void acceptVisitorAscending(QueuedRenderableVisitor* visitor) const; - - public: - QueuedRenderableCollection(); - ~QueuedRenderableCollection(); - - /// Empty the collection - void clear(void); - - /** Remove the group entry (if any) for a given Pass. - @remarks - To be used when a pass is destroyed, such that any - grouping level for it becomes useless. - */ - void removePassGroup(Pass* p); - - /** Reset the organisation modes required for this collection. - @remarks - You can only do this when the collection is empty. - @see OrganisationMode - */ - void resetOrganisationModes(void) - { - mOrganisationMode = 0; - } - - /** Add a required sorting / grouping mode to this collection when next used. - @remarks - You can only do this when the collection is empty. - @see OrganisationMode - */ - void addOrganisationMode(OrganisationMode om) - { - mOrganisationMode |= om; - } + static RadixSort msRadixSorter2; + + /// Bitmask of the organisation modes requested + uint8 mOrganisationMode; + + /// Grouped + PassGroupRenderableMap mGrouped; + /// Sorted descending (can iterate backwards to get ascending) + RenderablePassList mSortedDescending; + + /// Internal visitor implementation + void acceptVisitorGrouped(QueuedRenderableVisitor* visitor) const; + /// Internal visitor implementation + void acceptVisitorDescending(QueuedRenderableVisitor* visitor) const; + /// Internal visitor implementation + void acceptVisitorAscending(QueuedRenderableVisitor* visitor) const; + + public: + QueuedRenderableCollection(); + ~QueuedRenderableCollection(); + + /// Empty the collection + void clear(void); + + /** Remove the group entry (if any) for a given Pass. + @remarks + To be used when a pass is destroyed, such that any + grouping level for it becomes useless. + */ + void removePassGroup(Pass* p); + + /** Reset the organisation modes required for this collection. + @remarks + You can only do this when the collection is empty. + @see OrganisationMode + */ + void resetOrganisationModes(void) + { + mOrganisationMode = 0; + } + + /** Add a required sorting / grouping mode to this collection when next used. + @remarks + You can only do this when the collection is empty. + @see OrganisationMode + */ + void addOrganisationMode(OrganisationMode om) + { + mOrganisationMode |= om; + } /// Add a renderable to the collection using a given pass void addRenderable(Pass* pass, Renderable* rend); - - /** Perform any sorting that is required on this collection. - @param cam The camera - */ - void sort(const Camera* cam); - - /** Accept a visitor over the collection contents. - @param visitor Visitor class which should be called back - @param om The organisation mode which you want to iterate over. - Note that this must have been included in an addOrganisationMode - call before any renderables were added. - */ - void acceptVisitor(QueuedRenderableVisitor* visitor, OrganisationMode om) const; - - /** Merge renderable collection. - */ - void merge( const QueuedRenderableCollection& rhs ); - }; - - /** Collection of renderables by priority. + + /** Perform any sorting that is required on this collection. + @param cam The camera + */ + void sort(const Camera* cam); + + /** Accept a visitor over the collection contents. + @param visitor Visitor class which should be called back + @param om The organisation mode which you want to iterate over. + Note that this must have been included in an addOrganisationMode + call before any renderables were added. + */ + void acceptVisitor(QueuedRenderableVisitor* visitor, OrganisationMode om) const; + + /** Merge renderable collection. + */ + void merge( const QueuedRenderableCollection& rhs ); + }; + + /** Collection of renderables by priority. @remarks This class simply groups renderables for rendering. All the renderables contained in this class are destined for the same @@ -307,37 +307,37 @@ namespace Ogre { for detailed overlap control). @par This class can order solid renderables by a number of criteria; - it can optimise them into groups based on pass to reduce render - state changes, or can sort them by ascending or descending view - depth. Transparent objects are always ordered by descending depth. - @par - To iterate over items in the collections held by this object - you should retrieve the collection in use (e.g. solids, solids with - no shadows, transparents) and use the accept() method, providing - a class implementing QueuedRenderableVisitor. - + it can optimise them into groups based on pass to reduce render + state changes, or can sort them by ascending or descending view + depth. Transparent objects are always ordered by descending depth. + @par + To iterate over items in the collections held by this object + you should retrieve the collection in use (e.g. solids, solids with + no shadows, transparents) and use the accept() method, providing + a class implementing QueuedRenderableVisitor. + */ class _OgreExport RenderPriorityGroup : public RenderQueueAlloc { - protected: + protected: - /// Parent queue group + /// Parent queue group RenderQueueGroup* mParent; bool mSplitPassesByLightingType; bool mSplitNoShadowPasses; - bool mShadowCastersNotReceivers; + bool mShadowCastersNotReceivers; /// Solid pass list, used when no shadows, modulative shadows, or ambient passes for additive - QueuedRenderableCollection mSolidsBasic; + QueuedRenderableCollection mSolidsBasic; /// Solid per-light pass list, used with additive shadows QueuedRenderableCollection mSolidsDiffuseSpecular; /// Solid decal (texture) pass list, used with additive shadows QueuedRenderableCollection mSolidsDecal; /// Solid pass list, used when shadows are enabled but shadow receive is turned off for these passes QueuedRenderableCollection mSolidsNoShadowReceive; - /// Unsorted transparent list - QueuedRenderableCollection mTransparentsUnsorted; - /// Transparent list - QueuedRenderableCollection mTransparents; + /// Unsorted transparent list + QueuedRenderableCollection mTransparentsUnsorted; + /// Transparent list + QueuedRenderableCollection mTransparents; /// remove a pass entry from all collections void removePassEntry(Pass* p); @@ -355,26 +355,26 @@ namespace Ogre { RenderPriorityGroup(RenderQueueGroup* parent, bool splitPassesByLightingType, bool splitNoShadowPasses, - bool shadowCastersNotReceivers); + bool shadowCastersNotReceivers); ~RenderPriorityGroup() { } /** Get the collection of basic solids currently queued, this includes - all solids when there are no shadows, or all solids which have shadow - receiving enabled when using modulative shadows, or all ambient passes - of solids which have shadow receive enabled for additive shadows. */ + all solids when there are no shadows, or all solids which have shadow + receiving enabled when using modulative shadows, or all ambient passes + of solids which have shadow receive enabled for additive shadows. */ const QueuedRenderableCollection& getSolidsBasic(void) const { return mSolidsBasic; } /** Get the collection of solids currently queued per light (only applicable in - additive shadow modes). */ + additive shadow modes). */ const QueuedRenderableCollection& getSolidsDiffuseSpecular(void) const { return mSolidsDiffuseSpecular; } /** Get the collection of solids currently queued for decal passes (only - applicable in additive shadow modes). */ + applicable in additive shadow modes). */ const QueuedRenderableCollection& getSolidsDecal(void) const { return mSolidsDecal; } /** Get the collection of solids for which shadow receipt is disabled (only - applicable when shadows are enabled). */ + applicable when shadows are enabled). */ const QueuedRenderableCollection& getSolidsNoShadowReceive(void) const { return mSolidsNoShadowReceive; } /** Get the collection of transparent objects currently queued */ @@ -385,36 +385,36 @@ namespace Ogre { { return mTransparents; } - /** Reset the organisation modes required for the solids in this group. - @remarks - You can only do this when the group is empty, i.e. after clearing the - queue. - @see QueuedRenderableCollection::OrganisationMode - */ - void resetOrganisationModes(void); - - /** Add a required sorting / grouping mode for the solids in this group. - @remarks - You can only do this when the group is empty, i.e. after clearing the - queue. - @see QueuedRenderableCollection::OrganisationMode - */ - void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om); - - /** Set the sorting / grouping mode for the solids in this group to the default. - @remarks - You can only do this when the group is empty, i.e. after clearing the - queue. - @see QueuedRenderableCollection::OrganisationMode - */ - void defaultOrganisationMode(void); - - /** Add a renderable to this group. */ + /** Reset the organisation modes required for the solids in this group. + @remarks + You can only do this when the group is empty, i.e. after clearing the + queue. + @see QueuedRenderableCollection::OrganisationMode + */ + void resetOrganisationModes(void); + + /** Add a required sorting / grouping mode for the solids in this group. + @remarks + You can only do this when the group is empty, i.e. after clearing the + queue. + @see QueuedRenderableCollection::OrganisationMode + */ + void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om); + + /** Set the sorting / grouping mode for the solids in this group to the default. + @remarks + You can only do this when the group is empty, i.e. after clearing the + queue. + @see QueuedRenderableCollection::OrganisationMode + */ + void defaultOrganisationMode(void); + + /** Add a renderable to this group. */ void addRenderable(Renderable* pRend, Technique* pTech); - /** Sorts the objects which have been added to the queue; transparent objects by their + /** Sorts the objects which have been added to the queue; transparent objects by their depth in relation to the passed in Camera. */ - void sort(const Camera* cam); + void sort(const Camera* cam); /** Clears this group of renderables. */ @@ -436,17 +436,17 @@ namespace Ogre { mSplitNoShadowPasses = split; } - /** Sets whether or not objects which cast shadows should be treated as - never receiving shadows. - */ - void setShadowCastersCannotBeReceivers(bool ind) - { - mShadowCastersNotReceivers = ind; - } + /** Sets whether or not objects which cast shadows should be treated as + never receiving shadows. + */ + void setShadowCastersCannotBeReceivers(bool ind) + { + mShadowCastersNotReceivers = ind; + } - /** Merge group of renderables. - */ - void merge( const RenderPriorityGroup* rhs ); + /** Merge group of renderables. + */ + void merge( const RenderPriorityGroup* rhs ); }; @@ -469,17 +469,17 @@ namespace Ogre { RenderQueue* mParent; bool mSplitPassesByLightingType; bool mSplitNoShadowPasses; - bool mShadowCastersNotReceivers; + bool mShadowCastersNotReceivers; /// Map of RenderPriorityGroup objects PriorityMap mPriorityGroups; - /// Whether shadows are enabled for this queue - bool mShadowsEnabled; - /// Bitmask of the organisation modes requested (for new priority groups) - uint8 mOrganisationMode; + /// Whether shadows are enabled for this queue + bool mShadowsEnabled; + /// Bitmask of the organisation modes requested (for new priority groups) + uint8 mOrganisationMode; public: - RenderQueueGroup(RenderQueue* parent, + RenderQueueGroup(RenderQueue* parent, bool splitPassesByLightingType, bool splitNoShadowPasses, bool shadowCastersNotReceivers) @@ -488,7 +488,7 @@ namespace Ogre { , mSplitNoShadowPasses(splitNoShadowPasses) , mShadowCastersNotReceivers(shadowCastersNotReceivers) , mShadowsEnabled(true) - , mOrganisationMode(0) + , mOrganisationMode(0) { } @@ -525,12 +525,12 @@ namespace Ogre { pPriorityGrp = OGRE_NEW RenderPriorityGroup(this, mSplitPassesByLightingType, mSplitNoShadowPasses, - mShadowCastersNotReceivers); - if (mOrganisationMode) - { - pPriorityGrp->resetOrganisationModes(); - pPriorityGrp->addOrganisationMode((QueuedRenderableCollection::OrganisationMode)mOrganisationMode); - } + mShadowCastersNotReceivers); + if (mOrganisationMode) + { + pPriorityGrp->resetOrganisationModes(); + pPriorityGrp->addOrganisationMode((QueuedRenderableCollection::OrganisationMode)mOrganisationMode); + } mPriorityGroups.insert(PriorityMap::value_type(priority, pPriorityGrp)); } @@ -549,7 +549,7 @@ namespace Ogre { If false, doesn't delete any priority groups, just empties them. Saves on memory deallocations since the chances are roughly the same kinds of renderables are going to be sent to the queue again next time. If - true, completely destroys. + true, completely destroys. */ void clear(bool destroy = false) { @@ -557,33 +557,33 @@ namespace Ogre { iend = mPriorityGroups.end(); for (i = mPriorityGroups.begin(); i != iend; ++i) { - if (destroy) - OGRE_DELETE i->second; - else - i->second->clear(); + if (destroy) + OGRE_DELETE i->second; + else + i->second->clear(); } - if (destroy) - mPriorityGroups.clear(); + if (destroy) + mPriorityGroups.clear(); } - /** Indicate whether a given queue group will be doing any - shadow setup. - @remarks - This method allows you to inform the queue about a queue group, and to - indicate whether this group will require shadow processing of any sort. - In order to preserve rendering order, OGRE has to treat queue groups - as very separate elements of the scene, and this can result in it - having to duplicate shadow setup for each group. Therefore, if you - know that a group which you are using will never need shadows, you - should preregister the group using this method in order to improve - the performance. - */ - void setShadowsEnabled(bool enabled) { mShadowsEnabled = enabled; } - - /** Are shadows enabled for this queue? */ - bool getShadowsEnabled(void) const { return mShadowsEnabled; } + /** Indicate whether a given queue group will be doing any + shadow setup. + @remarks + This method allows you to inform the queue about a queue group, and to + indicate whether this group will require shadow processing of any sort. + In order to preserve rendering order, OGRE has to treat queue groups + as very separate elements of the scene, and this can result in it + having to duplicate shadow setup for each group. Therefore, if you + know that a group which you are using will never need shadows, you + should preregister the group using this method in order to improve + the performance. + */ + void setShadowsEnabled(bool enabled) { mShadowsEnabled = enabled; } + + /** Are shadows enabled for this queue? */ + bool getShadowsEnabled(void) const { return mShadowsEnabled; } /** Sets whether or not the queue will split passes by their lighting type, ie ambient, per-light and decal. @@ -612,115 +612,115 @@ namespace Ogre { i->second->setSplitNoShadowPasses(split); } } - /** Sets whether or not objects which cast shadows should be treated as - never receiving shadows. - */ - void setShadowCastersCannotBeReceivers(bool ind) - { - mShadowCastersNotReceivers = ind; - PriorityMap::iterator i, iend; - iend = mPriorityGroups.end(); - for (i = mPriorityGroups.begin(); i != iend; ++i) - { - i->second->setShadowCastersCannotBeReceivers(ind); - } - } - /** Reset the organisation modes required for the solids in this group. - @remarks - You can only do this when the group is empty, ie after clearing the - queue. - @see QueuedRenderableCollection::OrganisationMode - */ - void resetOrganisationModes(void) - { - mOrganisationMode = 0; - - PriorityMap::iterator i, iend; - iend = mPriorityGroups.end(); - for (i = mPriorityGroups.begin(); i != iend; ++i) - { - i->second->resetOrganisationModes(); - } - } - - /** Add a required sorting / grouping mode for the solids in this group. - @remarks - You can only do this when the group is empty, ie after clearing the - queue. - @see QueuedRenderableCollection::OrganisationMode - */ - void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om) - { - mOrganisationMode |= om; - - PriorityMap::iterator i, iend; - iend = mPriorityGroups.end(); - for (i = mPriorityGroups.begin(); i != iend; ++i) - { - i->second->addOrganisationMode(om); - } - } - - /** Setthe sorting / grouping mode for the solids in this group to the default. - @remarks - You can only do this when the group is empty, ie after clearing the - queue. - @see QueuedRenderableCollection::OrganisationMode - */ - void defaultOrganisationMode(void) - { - mOrganisationMode = 0; - - PriorityMap::iterator i, iend; - iend = mPriorityGroups.end(); - for (i = mPriorityGroups.begin(); i != iend; ++i) - { - i->second->defaultOrganisationMode(); - } - } - - /** Merge group of renderables. - */ - void merge( const RenderQueueGroup* rhs ) - { - ConstPriorityMapIterator it = rhs->getIterator(); - - while( it.hasMoreElements() ) - { - ushort priority = it.peekNextKey(); - RenderPriorityGroup* pSrcPriorityGrp = it.getNext(); - RenderPriorityGroup* pDstPriorityGrp; - - // Check if priority group is there - PriorityMap::iterator i = mPriorityGroups.find(priority); - if (i == mPriorityGroups.end()) - { - // Missing, create - pDstPriorityGrp = OGRE_NEW RenderPriorityGroup(this, - mSplitPassesByLightingType, - mSplitNoShadowPasses, - mShadowCastersNotReceivers); - if (mOrganisationMode) - { - pDstPriorityGrp->resetOrganisationModes(); - pDstPriorityGrp->addOrganisationMode((QueuedRenderableCollection::OrganisationMode)mOrganisationMode); - } - - mPriorityGroups.insert(PriorityMap::value_type(priority, pDstPriorityGrp)); - } - else - { - pDstPriorityGrp = i->second; - } - - // merge - pDstPriorityGrp->merge( pSrcPriorityGrp ); - } - } + /** Sets whether or not objects which cast shadows should be treated as + never receiving shadows. + */ + void setShadowCastersCannotBeReceivers(bool ind) + { + mShadowCastersNotReceivers = ind; + PriorityMap::iterator i, iend; + iend = mPriorityGroups.end(); + for (i = mPriorityGroups.begin(); i != iend; ++i) + { + i->second->setShadowCastersCannotBeReceivers(ind); + } + } + /** Reset the organisation modes required for the solids in this group. + @remarks + You can only do this when the group is empty, ie after clearing the + queue. + @see QueuedRenderableCollection::OrganisationMode + */ + void resetOrganisationModes(void) + { + mOrganisationMode = 0; + + PriorityMap::iterator i, iend; + iend = mPriorityGroups.end(); + for (i = mPriorityGroups.begin(); i != iend; ++i) + { + i->second->resetOrganisationModes(); + } + } + + /** Add a required sorting / grouping mode for the solids in this group. + @remarks + You can only do this when the group is empty, ie after clearing the + queue. + @see QueuedRenderableCollection::OrganisationMode + */ + void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om) + { + mOrganisationMode |= om; + + PriorityMap::iterator i, iend; + iend = mPriorityGroups.end(); + for (i = mPriorityGroups.begin(); i != iend; ++i) + { + i->second->addOrganisationMode(om); + } + } + + /** Setthe sorting / grouping mode for the solids in this group to the default. + @remarks + You can only do this when the group is empty, ie after clearing the + queue. + @see QueuedRenderableCollection::OrganisationMode + */ + void defaultOrganisationMode(void) + { + mOrganisationMode = 0; + + PriorityMap::iterator i, iend; + iend = mPriorityGroups.end(); + for (i = mPriorityGroups.begin(); i != iend; ++i) + { + i->second->defaultOrganisationMode(); + } + } + + /** Merge group of renderables. + */ + void merge( const RenderQueueGroup* rhs ) + { + ConstPriorityMapIterator it = rhs->getIterator(); + + while( it.hasMoreElements() ) + { + ushort priority = it.peekNextKey(); + RenderPriorityGroup* pSrcPriorityGrp = it.getNext(); + RenderPriorityGroup* pDstPriorityGrp; + + // Check if priority group is there + PriorityMap::iterator i = mPriorityGroups.find(priority); + if (i == mPriorityGroups.end()) + { + // Missing, create + pDstPriorityGrp = OGRE_NEW RenderPriorityGroup(this, + mSplitPassesByLightingType, + mSplitNoShadowPasses, + mShadowCastersNotReceivers); + if (mOrganisationMode) + { + pDstPriorityGrp->resetOrganisationModes(); + pDstPriorityGrp->addOrganisationMode((QueuedRenderableCollection::OrganisationMode)mOrganisationMode); + } + + mPriorityGroups.insert(PriorityMap::value_type(priority, pDstPriorityGrp)); + } + else + { + pDstPriorityGrp = i->second; + } + + // merge + pDstPriorityGrp->merge( pSrcPriorityGrp ); + } + } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreRenderSystem.h b/OgreMain/include/OgreRenderSystem.h index 08dc93b5d04..e84fdde2556 100644 --- a/OgreMain/include/OgreRenderSystem.h +++ b/OgreMain/include/OgreRenderSystem.h @@ -43,361 +43,361 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - - typedef vector::type DepthBufferVec; - typedef map< uint16, DepthBufferVec >::type DepthBufferMap; - typedef map< String, RenderTarget * >::type RenderTargetMap; - typedef multimap::type RenderTargetPriorityMap; - - class TextureManager; - /// Enum describing the ways to generate texture coordinates - enum TexCoordCalcMethod - { - /// No calculated texture coordinates - TEXCALC_NONE, - /// Environment map based on vertex normals - TEXCALC_ENVIRONMENT_MAP, - /// Environment map based on vertex positions - TEXCALC_ENVIRONMENT_MAP_PLANAR, - TEXCALC_ENVIRONMENT_MAP_REFLECTION, - TEXCALC_ENVIRONMENT_MAP_NORMAL, - /// Projective texture - TEXCALC_PROJECTIVE_TEXTURE - }; - /// Enum describing the various actions which can be taken on the stencil buffer - enum StencilOperation - { - /// Leave the stencil buffer unchanged - SOP_KEEP, - /// Set the stencil value to zero - SOP_ZERO, - /// Set the stencil value to the reference value - SOP_REPLACE, - /// Increase the stencil value by 1, clamping at the maximum value - SOP_INCREMENT, - /// Decrease the stencil value by 1, clamping at 0 - SOP_DECREMENT, - /// Increase the stencil value by 1, wrapping back to 0 when incrementing the maximum value - SOP_INCREMENT_WRAP, - /// Decrease the stencil value by 1, wrapping when decrementing 0 - SOP_DECREMENT_WRAP, - /// Invert the bits of the stencil buffer - SOP_INVERT - }; - - - /** Defines the functionality of a 3D API - @remarks - The RenderSystem class provides a base interface - which abstracts the general functionality of the 3D API - e.g. Direct3D or OpenGL. Whilst a few of the general - methods have implementations, most of this class is - abstract, requiring a subclass based on a specific API - to be constructed to provide the full functionality. - Note there are 2 levels to the interface - one which - will be used often by the caller of the Ogre library, - and one which is at a lower level and will be used by the - other classes provided by Ogre. These lower level - methods are prefixed with '_' to differentiate them. - The advanced user of the library may use these lower - level methods to access the 3D API at a more fundamental - level (dealing direct with render states and rendering - primitives), but still benefiting from Ogre's abstraction - of exactly which 3D API is in use. - @author - Steven Streeting - @version - 1.0 - */ - class _OgreExport RenderSystem : public RenderSysAlloc - { - public: - /** Default Constructor. - */ - RenderSystem(); - - /** Destructor. - */ - virtual ~RenderSystem(); - - /** Returns the name of the rendering system. - */ - virtual const String& getName(void) const = 0; - - /** Returns the details of this API's configuration options - @remarks - Each render system must be able to inform the world - of what options must/can be specified for it's - operation. - @par - These are passed as strings for portability, but - grouped into a structure (_ConfigOption) which includes - both options and current value. - @par - Note that the settings returned from this call are - affected by the options that have been set so far, - since some options are interdependent. - @par - This routine is called automatically by the default - configuration dialogue produced by Root::showConfigDialog - or may be used by the caller for custom settings dialogs - @return - A 'map' of options, i.e. a list of options which is also - indexed by option name. - */ - virtual ConfigOptionMap& getConfigOptions(void) = 0; - - /** Sets an option for this API - @remarks - Used to confirm the settings (normally chosen by the user) in - order to make the renderer able to initialise with the settings as required. - This may be video mode, D3D driver, full screen / windowed etc. - Called automatically by the default configuration - dialog, and by the restoration of saved settings. - These settings are stored and only activated when - RenderSystem::initialise or RenderSystem::reinitialise - are called. - @par - If using a custom configuration dialog, it is advised that the - caller calls RenderSystem::getConfigOptions - again, since some options can alter resulting from a selection. - @param - name The name of the option to alter. - @param - value The value to set the option to. - */ - virtual void setConfigOption(const String &name, const String &value) = 0; - - /** Create an object for performing hardware occlusion queries. - */ - virtual HardwareOcclusionQuery* createHardwareOcclusionQuery(void) = 0; - - /** Destroy a hardware occlusion query object. - */ - virtual void destroyHardwareOcclusionQuery(HardwareOcclusionQuery *hq); - - /** Validates the options set for the rendering system, returning a message if there are problems. - @note - If the returned string is empty, there are no problems. - */ - virtual String validateConfigOptions(void) = 0; - - /** Start up the renderer using the settings selected (Or the defaults if none have been selected). - @remarks - Called by Root::setRenderSystem. Shouldn't really be called - directly, although this can be done if the app wants to. - @param - autoCreateWindow If true, creates a render window - automatically, based on settings chosen so far. This saves - an extra call to _createRenderWindow - for the main render window. - @param - windowTitle Sets the app window title - @return - A pointer to the automatically created window, if requested, otherwise null. - */ - virtual RenderWindow* _initialise(bool autoCreateWindow, const String& windowTitle = "OGRE Render Window"); - - /* - Returns whether under the current render system buffers marked as TU_STATIC can be locked for update - @remarks - Needed in the implementation of DirectX9 with DirectX9Ex driver - */ - virtual bool isStaticBufferLockable() const { return true; } - - /** Query the real capabilities of the GPU and driver in the RenderSystem*/ - virtual RenderSystemCapabilities* createRenderSystemCapabilities() const = 0; + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + + typedef vector::type DepthBufferVec; + typedef map< uint16, DepthBufferVec >::type DepthBufferMap; + typedef map< String, RenderTarget * >::type RenderTargetMap; + typedef multimap::type RenderTargetPriorityMap; + + class TextureManager; + /// Enum describing the ways to generate texture coordinates + enum TexCoordCalcMethod + { + /// No calculated texture coordinates + TEXCALC_NONE, + /// Environment map based on vertex normals + TEXCALC_ENVIRONMENT_MAP, + /// Environment map based on vertex positions + TEXCALC_ENVIRONMENT_MAP_PLANAR, + TEXCALC_ENVIRONMENT_MAP_REFLECTION, + TEXCALC_ENVIRONMENT_MAP_NORMAL, + /// Projective texture + TEXCALC_PROJECTIVE_TEXTURE + }; + /// Enum describing the various actions which can be taken on the stencil buffer + enum StencilOperation + { + /// Leave the stencil buffer unchanged + SOP_KEEP, + /// Set the stencil value to zero + SOP_ZERO, + /// Set the stencil value to the reference value + SOP_REPLACE, + /// Increase the stencil value by 1, clamping at the maximum value + SOP_INCREMENT, + /// Decrease the stencil value by 1, clamping at 0 + SOP_DECREMENT, + /// Increase the stencil value by 1, wrapping back to 0 when incrementing the maximum value + SOP_INCREMENT_WRAP, + /// Decrease the stencil value by 1, wrapping when decrementing 0 + SOP_DECREMENT_WRAP, + /// Invert the bits of the stencil buffer + SOP_INVERT + }; + + + /** Defines the functionality of a 3D API + @remarks + The RenderSystem class provides a base interface + which abstracts the general functionality of the 3D API + e.g. Direct3D or OpenGL. Whilst a few of the general + methods have implementations, most of this class is + abstract, requiring a subclass based on a specific API + to be constructed to provide the full functionality. + Note there are 2 levels to the interface - one which + will be used often by the caller of the Ogre library, + and one which is at a lower level and will be used by the + other classes provided by Ogre. These lower level + methods are prefixed with '_' to differentiate them. + The advanced user of the library may use these lower + level methods to access the 3D API at a more fundamental + level (dealing direct with render states and rendering + primitives), but still benefiting from Ogre's abstraction + of exactly which 3D API is in use. + @author + Steven Streeting + @version + 1.0 + */ + class _OgreExport RenderSystem : public RenderSysAlloc + { + public: + /** Default Constructor. + */ + RenderSystem(); + + /** Destructor. + */ + virtual ~RenderSystem(); + + /** Returns the name of the rendering system. + */ + virtual const String& getName(void) const = 0; + + /** Returns the details of this API's configuration options + @remarks + Each render system must be able to inform the world + of what options must/can be specified for it's + operation. + @par + These are passed as strings for portability, but + grouped into a structure (_ConfigOption) which includes + both options and current value. + @par + Note that the settings returned from this call are + affected by the options that have been set so far, + since some options are interdependent. + @par + This routine is called automatically by the default + configuration dialogue produced by Root::showConfigDialog + or may be used by the caller for custom settings dialogs + @return + A 'map' of options, i.e. a list of options which is also + indexed by option name. + */ + virtual ConfigOptionMap& getConfigOptions(void) = 0; + + /** Sets an option for this API + @remarks + Used to confirm the settings (normally chosen by the user) in + order to make the renderer able to initialise with the settings as required. + This may be video mode, D3D driver, full screen / windowed etc. + Called automatically by the default configuration + dialog, and by the restoration of saved settings. + These settings are stored and only activated when + RenderSystem::initialise or RenderSystem::reinitialise + are called. + @par + If using a custom configuration dialog, it is advised that the + caller calls RenderSystem::getConfigOptions + again, since some options can alter resulting from a selection. + @param + name The name of the option to alter. + @param + value The value to set the option to. + */ + virtual void setConfigOption(const String &name, const String &value) = 0; + + /** Create an object for performing hardware occlusion queries. + */ + virtual HardwareOcclusionQuery* createHardwareOcclusionQuery(void) = 0; + + /** Destroy a hardware occlusion query object. + */ + virtual void destroyHardwareOcclusionQuery(HardwareOcclusionQuery *hq); + + /** Validates the options set for the rendering system, returning a message if there are problems. + @note + If the returned string is empty, there are no problems. + */ + virtual String validateConfigOptions(void) = 0; + + /** Start up the renderer using the settings selected (Or the defaults if none have been selected). + @remarks + Called by Root::setRenderSystem. Shouldn't really be called + directly, although this can be done if the app wants to. + @param + autoCreateWindow If true, creates a render window + automatically, based on settings chosen so far. This saves + an extra call to _createRenderWindow + for the main render window. + @param + windowTitle Sets the app window title + @return + A pointer to the automatically created window, if requested, otherwise null. + */ + virtual RenderWindow* _initialise(bool autoCreateWindow, const String& windowTitle = "OGRE Render Window"); + + /* + Returns whether under the current render system buffers marked as TU_STATIC can be locked for update + @remarks + Needed in the implementation of DirectX9 with DirectX9Ex driver + */ + virtual bool isStaticBufferLockable() const { return true; } + + /** Query the real capabilities of the GPU and driver in the RenderSystem*/ + virtual RenderSystemCapabilities* createRenderSystemCapabilities() const = 0; - /** Get a pointer to the current capabilities being used by the RenderSystem. - @remarks - The capabilities may be modified using this pointer, this will only have an effect - before the RenderSystem has been initialised. It's intended use is to allow a - listener of the RenderSystemCapabilitiesCreated event to customise the capabilities - on the fly before the RenderSystem is initialised. - */ - RenderSystemCapabilities* getMutableCapabilities(){ return mCurrentCapabilities; } - - /** Force the render system to use the special capabilities. Can only be called - * before the render system has been fully initializer (before createWindow is called) - * @param - * capabilities has to be a subset of the real capabilities and the caller is - * responsible for deallocating capabilities. - */ - virtual void useCustomRenderSystemCapabilities(RenderSystemCapabilities* capabilities); - - /** Restart the renderer (normally following a change in settings). - */ - virtual void reinitialise(void) = 0; - - /** Shutdown the renderer and cleanup resources. - */ - virtual void shutdown(void); - - - /** Sets the colour & strength of the ambient (global directionless) light in the world. - */ - virtual void setAmbientLight(float r, float g, float b) = 0; - - /** Sets the type of light shading required (default = Gouraud). - */ - virtual void setShadingType(ShadeOptions so) = 0; - - /** Sets whether or not dynamic lighting is enabled. - @param - enabled If true, dynamic lighting is performed on geometry with normals supplied, geometry without - normals will not be displayed. If false, no lighting is applied and all geometry will be full brightness. - */ - virtual void setLightingEnabled(bool enabled) = 0; - - /** Sets whether or not W-buffers are enabled if they are available for this renderer. - @param - enabled If true and the renderer supports them W-buffers will be used. If false - W-buffers will not be used even if available. W-buffers are enabled by default - for 16bit depth buffers and disabled for all other depths. - */ - void setWBufferEnabled(bool enabled); - - /** Returns true if the renderer will try to use W-buffers when available. - */ - bool getWBufferEnabled(void) const; - - /** Creates a new rendering window. - @remarks - This method creates a new rendering window as specified - by the paramteters. The rendering system could be - responible for only a single window (e.g. in the case - of a game), or could be in charge of multiple ones (in the - case of a level editor). The option to create the window - as a child of another is therefore given. - This method will create an appropriate subclass of - RenderWindow depending on the API and platform implementation. - @par - After creation, this window can be retrieved using getRenderTarget(). - @param - name The name of the window. Used in other methods - later like setRenderTarget and getRenderTarget. - @param - width The width of the new window. - @param - height The height of the new window. - @param - fullScreen Specify true to make the window full screen - without borders, title bar or menu bar. - @param - miscParams A NameValuePairList describing the other parameters for the new rendering window. - Options are case sensitive. Unrecognised parameters will be ignored silently. - These values might be platform dependent, but these are present for all platforms unless - indicated otherwise: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      KeyType/ValuesDefaultDescriptionNotes
      titleAny stringRenderTarget nameThe title of the window that will appear in the title bar 
      colourDepth16, 32Desktop depthColour depth of the resulting rendering window; only applies if fullScreenWin32 Specific
      leftPositive integersCentredScreen x coordinate from left 
      topPositive integersCentredScreen y coordinate from left 
      depthBuffertrue, falsetrueUse depth bufferDirectX9 specific
      externalWindowHandleWin32: HWND as integer
      - GLX: poslong:posint:poslong (display*:screen:windowHandle) or poslong:posint:poslong:poslong (display*:screen:windowHandle:XVisualInfo*)
      + /** Get a pointer to the current capabilities being used by the RenderSystem. + @remarks + The capabilities may be modified using this pointer, this will only have an effect + before the RenderSystem has been initialised. It's intended use is to allow a + listener of the RenderSystemCapabilitiesCreated event to customise the capabilities + on the fly before the RenderSystem is initialised. + */ + RenderSystemCapabilities* getMutableCapabilities(){ return mCurrentCapabilities; } + + /** Force the render system to use the special capabilities. Can only be called + * before the render system has been fully initializer (before createWindow is called) + * @param + * capabilities has to be a subset of the real capabilities and the caller is + * responsible for deallocating capabilities. + */ + virtual void useCustomRenderSystemCapabilities(RenderSystemCapabilities* capabilities); + + /** Restart the renderer (normally following a change in settings). + */ + virtual void reinitialise(void) = 0; + + /** Shutdown the renderer and cleanup resources. + */ + virtual void shutdown(void); + + + /** Sets the colour & strength of the ambient (global directionless) light in the world. + */ + virtual void setAmbientLight(float r, float g, float b) = 0; + + /** Sets the type of light shading required (default = Gouraud). + */ + virtual void setShadingType(ShadeOptions so) = 0; + + /** Sets whether or not dynamic lighting is enabled. + @param + enabled If true, dynamic lighting is performed on geometry with normals supplied, geometry without + normals will not be displayed. If false, no lighting is applied and all geometry will be full brightness. + */ + virtual void setLightingEnabled(bool enabled) = 0; + + /** Sets whether or not W-buffers are enabled if they are available for this renderer. + @param + enabled If true and the renderer supports them W-buffers will be used. If false + W-buffers will not be used even if available. W-buffers are enabled by default + for 16bit depth buffers and disabled for all other depths. + */ + void setWBufferEnabled(bool enabled); + + /** Returns true if the renderer will try to use W-buffers when available. + */ + bool getWBufferEnabled(void) const; + + /** Creates a new rendering window. + @remarks + This method creates a new rendering window as specified + by the paramteters. The rendering system could be + responible for only a single window (e.g. in the case + of a game), or could be in charge of multiple ones (in the + case of a level editor). The option to create the window + as a child of another is therefore given. + This method will create an appropriate subclass of + RenderWindow depending on the API and platform implementation. + @par + After creation, this window can be retrieved using getRenderTarget(). + @param + name The name of the window. Used in other methods + later like setRenderTarget and getRenderTarget. + @param + width The width of the new window. + @param + height The height of the new window. + @param + fullScreen Specify true to make the window full screen + without borders, title bar or menu bar. + @param + miscParams A NameValuePairList describing the other parameters for the new rendering window. + Options are case sensitive. Unrecognised parameters will be ignored silently. + These values might be platform dependent, but these are present for all platforms unless + indicated otherwise: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - + + @@ -409,7 +409,7 @@ namespace Ogre - + @@ -443,792 +443,792 @@ namespace Ogre - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - virtual RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0) = 0; - - /** Creates multiple rendering windows. - @param - renderWindowDescriptions Array of structures containing the descriptions of each render window. - The structure's members are the same as the parameters of _createRenderWindow: - * name - * width - * height - * fullScreen - * miscParams - See _createRenderWindow for details about each member. - @param - createdWindows This array will hold the created render windows. - @return - true on success. - */ - virtual bool _createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, - RenderWindowList& createdWindows); - - - /** Create a MultiRenderTarget, which is a render target that renders to multiple RenderTextures - at once. Surfaces can be bound and unbound at will. - This fails if mCapabilities->getNumMultiRenderTargets() is smaller than 2. - */ - virtual MultiRenderTarget * createMultiRenderTarget(const String & name) = 0; - - /** Destroys a render window */ - virtual void destroyRenderWindow(const String& name); - /** Destroys a render texture */ - virtual void destroyRenderTexture(const String& name); - /** Destroys a render target of any sort */ - virtual void destroyRenderTarget(const String& name); - - /** Attaches the passed render target to the render system. - */ - virtual void attachRenderTarget( RenderTarget &target ); - /** Returns a pointer to the render target with the passed name, or NULL if that - render target cannot be found. - */ - virtual RenderTarget * getRenderTarget( const String &name ); - /** Detaches the render target with the passed name from the render system and - returns a pointer to it. - @note - If the render target cannot be found, NULL is returned. - */ - virtual RenderTarget * detachRenderTarget( const String &name ); - - /// Iterator over RenderTargets - typedef MapIterator RenderTargetIterator; - - /** Returns a specialised MapIterator over all render targets attached to the RenderSystem. */ - virtual RenderTargetIterator getRenderTargetIterator(void) { - return RenderTargetIterator( mRenderTargets.begin(), mRenderTargets.end() ); - } - /** Returns a description of an error code. - */ - virtual String getErrorDescription(long errorNumber) const = 0; - - /** Returns the global instance vertex buffer. - */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + */ + virtual RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0) = 0; + + /** Creates multiple rendering windows. + @param + renderWindowDescriptions Array of structures containing the descriptions of each render window. + The structure's members are the same as the parameters of _createRenderWindow: + * name + * width + * height + * fullScreen + * miscParams + See _createRenderWindow for details about each member. + @param + createdWindows This array will hold the created render windows. + @return + true on success. + */ + virtual bool _createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, + RenderWindowList& createdWindows); + + + /** Create a MultiRenderTarget, which is a render target that renders to multiple RenderTextures + at once. Surfaces can be bound and unbound at will. + This fails if mCapabilities->getNumMultiRenderTargets() is smaller than 2. + */ + virtual MultiRenderTarget * createMultiRenderTarget(const String & name) = 0; + + /** Destroys a render window */ + virtual void destroyRenderWindow(const String& name); + /** Destroys a render texture */ + virtual void destroyRenderTexture(const String& name); + /** Destroys a render target of any sort */ + virtual void destroyRenderTarget(const String& name); + + /** Attaches the passed render target to the render system. + */ + virtual void attachRenderTarget( RenderTarget &target ); + /** Returns a pointer to the render target with the passed name, or NULL if that + render target cannot be found. + */ + virtual RenderTarget * getRenderTarget( const String &name ); + /** Detaches the render target with the passed name from the render system and + returns a pointer to it. + @note + If the render target cannot be found, NULL is returned. + */ + virtual RenderTarget * detachRenderTarget( const String &name ); + + /// Iterator over RenderTargets + typedef MapIterator RenderTargetIterator; + + /** Returns a specialised MapIterator over all render targets attached to the RenderSystem. */ + virtual RenderTargetIterator getRenderTargetIterator(void) { + return RenderTargetIterator( mRenderTargets.begin(), mRenderTargets.end() ); + } + /** Returns a description of an error code. + */ + virtual String getErrorDescription(long errorNumber) const = 0; + + /** Returns the global instance vertex buffer. + */ HardwareVertexBufferSharedPtr getGlobalInstanceVertexBuffer() const; - /** Sets the global instance vertex buffer. - */ + /** Sets the global instance vertex buffer. + */ void setGlobalInstanceVertexBuffer(const HardwareVertexBufferSharedPtr &val); - /** Gets vertex declaration for the global vertex buffer for the global instancing - */ + /** Gets vertex declaration for the global vertex buffer for the global instancing + */ VertexDeclaration* getGlobalInstanceVertexBufferVertexDeclaration() const; - /** Sets vertex declaration for the global vertex buffer for the global instancing - */ + /** Sets vertex declaration for the global vertex buffer for the global instancing + */ void setGlobalInstanceVertexBufferVertexDeclaration( VertexDeclaration* val); - /** Gets the global number of instances. - */ + /** Gets the global number of instances. + */ size_t getGlobalNumberOfInstances() const; - /** Sets the global number of instances. - */ + /** Sets the global number of instances. + */ void setGlobalNumberOfInstances(const size_t val); - /** Sets if fixed pipeline rendering is enabled on the system. - */ - void setFixedPipelineEnabled(bool enabled); - - /** Returns true if fixed pipeline rendering is enabled on the system. - */ - bool getFixedPipelineEnabled(void) const; - - /** Retrieves an existing DepthBuffer or creates a new one suited for the given RenderTarget - and sets it. - @remarks - RenderTarget's pool ID is respected. @see RenderTarget::setDepthBufferPool() - */ - virtual void setDepthBufferFor( RenderTarget *renderTarget ); - - // ------------------------------------------------------------------------ - // Internal Rendering Access - // All methods below here are normally only called by other OGRE classes - // They can be called by library user if required - // ------------------------------------------------------------------------ - - - /** Tells the rendersystem to use the attached set of lights (and no others) - up to the number specified (this allows the same list to be used with different - count limits) */ - virtual void _useLights(const LightList& lights, unsigned short limit) = 0; - /** Are fixed-function lights provided in view space? Affects optimisation. - */ - virtual bool areFixedFunctionLightsInViewSpace() const { return false; } - /** Sets the world transform matrix. */ - virtual void _setWorldMatrix(const Matrix4 &m) = 0; - /** Sets multiple world matrices (vertex blending). */ - virtual void _setWorldMatrices(const Matrix4* m, unsigned short count); - /** Sets the view transform matrix */ - virtual void _setViewMatrix(const Matrix4 &m) = 0; - /** Sets the projection transform matrix */ - virtual void _setProjectionMatrix(const Matrix4 &m) = 0; - /** Utility function for setting all the properties of a texture unit at once. - This method is also worth using over the individual texture unit settings because it - only sets those settings which are different from the current settings for this - unit, thus minimising render state changes. - */ - virtual void _setTextureUnitSettings(size_t texUnit, TextureUnitState& tl); - /** Set texture unit binding type */ - virtual void _setBindingType(TextureUnitState::BindingType bindigType); - /** Turns off a texture unit. */ - virtual void _disableTextureUnit(size_t texUnit); - /** Disables all texture units from the given unit upwards */ - virtual void _disableTextureUnitsFrom(size_t texUnit); - /** Sets the surface properties to be used for future rendering. - - This method sets the the properties of the surfaces of objects - to be rendered after it. In this context these surface properties - are the amount of each type of light the object reflects (determining - it's colour under different types of light), whether it emits light - itself, and how shiny it is. Textures are not dealt with here, - see the _setTetxure method for details. - This method is used by _setMaterial so does not need to be called - direct if that method is being used. - - @param ambient The amount of ambient (sourceless and directionless) - light an object reflects. Affected by the colour/amount of ambient light in the scene. - @param diffuse The amount of light from directed sources that is - reflected (affected by colour/amount of point, directed and spot light sources) - @param specular The amount of specular light reflected. This is also - affected by directed light sources but represents the colour at the - highlights of the object. - @param emissive The colour of light emitted from the object. Note that - this will make an object seem brighter and not dependent on lights in - the scene, but it will not act as a light, so will not illuminate other - objects. Use a light attached to the same SceneNode as the object for this purpose. - @param shininess A value which only has an effect on specular highlights (so - specular must be non-black). The higher this value, the smaller and crisper the - specular highlights will be, imitating a more highly polished surface. - This value is not constrained to 0.0-1.0, in fact it is likely to - be more (10.0 gives a modest sheen to an object). - @param tracking A bit field that describes which of the ambient, diffuse, specular - and emissive colours follow the vertex colour of the primitive. When a bit in this field is set - its ColourValue is ignored. This is a combination of TVC_AMBIENT, TVC_DIFFUSE, TVC_SPECULAR(note that the shininess value is still - taken from shininess) and TVC_EMISSIVE. TVC_NONE means that there will be no material property - tracking the vertex colours. - */ - virtual void _setSurfaceParams(const ColourValue &ambient, - const ColourValue &diffuse, const ColourValue &specular, - const ColourValue &emissive, Real shininess, - TrackVertexColourType tracking = TVC_NONE) = 0; - - /** Sets whether or not rendering points using OT_POINT_LIST will - render point sprites (textured quads) or plain points. - @param enabled True enables point sprites, false returns to normal - point rendering. - */ - virtual void _setPointSpritesEnabled(bool enabled) = 0; - - /** Sets the size of points and how they are attenuated with distance. - @remarks - When performing point rendering or point sprite rendering, - point size can be attenuated with distance. The equation for - doing this is attenuation = 1 / (constant + linear * dist + quadratic * d^2) . - @par - For example, to disable distance attenuation (constant screensize) - you would set constant to 1, and linear and quadratic to 0. A - standard perspective attenuation would be 0, 1, 0 respectively. - */ - virtual void _setPointParameters(Real size, bool attenuationEnabled, - Real constant, Real linear, Real quadratic, Real minSize, Real maxSize) = 0; - - - /** - Sets the texture to bind to a given texture unit. - - User processes would not normally call this direct unless rendering - primitives themselves. - - @param unit The index of the texture unit to modify. Multitexturing - hardware can support multiple units (see - RenderSystemCapabilites::getNumTextureUnits) - @param enabled Boolean to turn the unit on/off - @param texPtr Pointer to the texture to use. - */ - virtual void _setTexture(size_t unit, bool enabled, - const TexturePtr &texPtr) = 0; - /** - Sets the texture to bind to a given texture unit. - - User processes would not normally call this direct unless rendering - primitives themselves. - - @param unit The index of the texture unit to modify. Multitexturing - hardware can support multiple units (see - RenderSystemCapabilites::getNumTextureUnits) - @param enabled Boolean to turn the unit on/off - @param texname The name of the texture to use - this should have - already been loaded with TextureManager::load. - */ - virtual void _setTexture(size_t unit, bool enabled, const String &texname); - - /** Binds a texture to a vertex, geometry, compute, tesselation hull - or tessellation domain sampler. - @remarks - Not all rendersystems support separate vertex samplers. For those that - do, you can set a texture for them, separate to the regular texture - samplers, using this method. For those that don't, you should use the - regular texture samplers which are shared between the vertex and - fragment units; calling this method will throw an exception. - @see RenderSystemCapabilites::getVertexTextureUnitsShared - */ - virtual void _setVertexTexture(size_t unit, const TexturePtr& tex); - virtual void _setGeometryTexture(size_t unit, const TexturePtr& tex); - virtual void _setComputeTexture(size_t unit, const TexturePtr& tex); - virtual void _setTesselationHullTexture(size_t unit, const TexturePtr& tex); - virtual void _setTesselationDomainTexture(size_t unit, const TexturePtr& tex); - - /** - Sets the texture coordinate set to use for a texture unit. - - Meant for use internally - not generally used directly by apps - the Material and TextureUnitState - classes let you manage textures far more easily. - - @param unit Texture unit as above - @param index The index of the texture coordinate set to use. - */ - virtual void _setTextureCoordSet(size_t unit, size_t index) = 0; - - /** - Sets a method for automatically calculating texture coordinates for a stage. - Should not be used by apps - for use by Ogre only. - @param unit Texture unit as above - @param m Calculation method to use - @param frustum Optional Frustum param, only used for projective effects - */ - virtual void _setTextureCoordCalculation(size_t unit, TexCoordCalcMethod m, - const Frustum* frustum = 0) = 0; - - /** Sets the texture blend modes from a TextureUnitState record. - Meant for use internally only - apps should use the Material - and TextureUnitState classes. - @param unit Texture unit as above - @param bm Details of the blending mode - */ - virtual void _setTextureBlendMode(size_t unit, const LayerBlendModeEx& bm) = 0; - - /** Sets the filtering options for a given texture unit. - @param unit The texture unit to set the filtering options for - @param minFilter The filter used when a texture is reduced in size - @param magFilter The filter used when a texture is magnified - @param mipFilter The filter used between mipmap levels, FO_NONE disables mipmapping - */ - virtual void _setTextureUnitFiltering(size_t unit, FilterOptions minFilter, - FilterOptions magFilter, FilterOptions mipFilter); - - /** Sets a single filter for a given texture unit. - @param unit The texture unit to set the filtering options for - @param ftype The filter type - @param filter The filter to be used - */ - virtual void _setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions filter) = 0; - - /** Sets whether the compare func is enabled or not for this texture unit - @param unit The texture unit to set the filtering options for - @param compare The state (enabled/disabled) - */ - virtual void _setTextureUnitCompareEnabled(size_t unit, bool compare) = 0; - - - /** Sets the compare function to use for a given texture unit - @param unit The texture unit to set the filtering options for - @param function The comparison function - */ - virtual void _setTextureUnitCompareFunction(size_t unit, CompareFunction function) = 0; - - - /** Sets the maximal anisotropy for the specified texture unit.*/ - virtual void _setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) = 0; - - /** Sets the texture addressing mode for a texture unit.*/ - virtual void _setTextureAddressingMode(size_t unit, const TextureUnitState::UVWAddressingMode& uvw) = 0; - - /** Sets the texture border colour for a texture unit.*/ - virtual void _setTextureBorderColour(size_t unit, const ColourValue& colour) = 0; - - /** Sets the mipmap bias value for a given texture unit. - @remarks - This allows you to adjust the mipmap calculation up or down for a - given texture unit. Negative values force a larger mipmap to be used, - positive values force a smaller mipmap to be used. Units are in numbers - of levels, so +1 forces the mipmaps to one smaller level. - @note Only does something if render system has capability RSC_MIPMAP_LOD_BIAS. - */ - virtual void _setTextureMipmapBias(size_t unit, float bias) = 0; - - /** Sets the texture coordinate transformation matrix for a texture unit. - @param unit Texture unit to affect - @param xform The 4x4 matrix - */ - virtual void _setTextureMatrix(size_t unit, const Matrix4& xform) = 0; - - /** Sets the global blending factors for combining subsequent renders with the existing frame contents. - The result of the blending operation is: -

      final = (texture * sourceFactor) + (pixel * destFactor)

      - Each of the factors is specified as one of a number of options, as specified in the SceneBlendFactor - enumerated type. - By changing the operation you can change addition between the source and destination pixels to a different operator. - @param sourceFactor The source factor in the above calculation, i.e. multiplied by the texture colour components. - @param destFactor The destination factor in the above calculation, i.e. multiplied by the pixel colour components. - @param op The blend operation mode for combining pixels - */ - virtual void _setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op = SBO_ADD) = 0; - - /** Sets the global blending factors for combining subsequent renders with the existing frame contents. - The result of the blending operation is: -

      final = (texture * sourceFactor) + (pixel * destFactor)

      - Each of the factors is specified as one of a number of options, as specified in the SceneBlendFactor - enumerated type. - @param sourceFactor The source factor in the above calculation, i.e. multiplied by the texture colour components. - @param destFactor The destination factor in the above calculation, i.e. multiplied by the pixel colour components. - @param sourceFactorAlpha The source factor in the above calculation for the alpha channel, i.e. multiplied by the texture alpha components. - @param destFactorAlpha The destination factor in the above calculation for the alpha channel, i.e. multiplied by the pixel alpha components. - @param op The blend operation mode for combining pixels - @param alphaOp The blend operation mode for combining pixel alpha values - */ - virtual void _setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, - SceneBlendFactor destFactorAlpha, SceneBlendOperation op = SBO_ADD, SceneBlendOperation alphaOp = SBO_ADD) = 0; - - /** Sets the global alpha rejection approach for future renders. - By default images are rendered regardless of texture alpha. This method lets you change that. - @param func The comparison function which must pass for a pixel to be written. - @param value The value to compare each pixels alpha value to (0-255) - @param alphaToCoverage Whether to enable alpha to coverage, if supported - */ - virtual void _setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage) = 0; - - /** Notify the rendersystem that it should adjust texture projection to be - relative to a different origin. - */ - virtual void _setTextureProjectionRelativeTo(bool enabled, const Vector3& pos); - - /** Creates a DepthBuffer that can be attached to the specified RenderTarget - @remarks - It doesn't attach anything, it just returns a pointer to a new DepthBuffer - Caller is responsible for putting this buffer into the right pool, for - attaching, and deleting it. Here's where API-specific magic happens. - Don't call this directly unless you know what you're doing. - */ - virtual DepthBuffer* _createDepthBufferFor( RenderTarget *renderTarget ) = 0; - - /** Removes all depth buffers. Should be called on device lost and shutdown - @remarks - Advanced users can call this directly with bCleanManualBuffers=false to - remove all depth buffers created for RTTs; when they think the pool has - grown too big or they've used lots of depth buffers they don't need anymore, - freeing GPU RAM. - */ - void _cleanupDepthBuffers( bool bCleanManualBuffers=true ); - - /** - * Signifies the beginning of a frame, i.e. the start of rendering on a single viewport. Will occur - * several times per complete frame if multiple viewports exist. - */ - virtual void _beginFrame(void) = 0; - - //Dummy structure for render system contexts - implementing RenderSystems can extend - //as needed - struct RenderSystemContext { }; - /** - * Pause rendering for a frame. This has to be called after _beginFrame and before _endFrame. - * Will usually be called by the SceneManager, don't use this manually unless you know what - * you are doing. - */ - virtual RenderSystemContext* _pauseFrame(void); - /** - * Resume rendering for a frame. This has to be called after a _pauseFrame call - * Will usually be called by the SceneManager, don't use this manually unless you know what - * you are doing. - * @param context the render system context, as returned by _pauseFrame - */ - virtual void _resumeFrame(RenderSystemContext* context); - - /** - * Ends rendering of a frame to the current viewport. - */ - virtual void _endFrame(void) = 0; - /** - Sets the provided viewport as the active one for future - rendering operations. This viewport is aware of it's own - camera and render target. Must be implemented by subclass. - - @param vp Pointer to the appropriate viewport. - */ - virtual void _setViewport(Viewport *vp) = 0; - /** Get the current active viewport for rendering. */ - virtual Viewport* _getViewport(void); - - /** Sets the culling mode for the render system based on the 'vertex winding'. - A typical way for the rendering engine to cull triangles is based on the - 'vertex winding' of triangles. Vertex winding refers to the direction in - which the vertices are passed or indexed to in the rendering operation as viewed - from the camera, and will wither be clockwise or anticlockwise (that's 'counterclockwise' for - you Americans out there ;) The default is CULL_CLOCKWISE i.e. that only triangles whose vertices - are passed/indexed in anticlockwise order are rendered - this is a common approach and is used in 3D studio models - for example. You can alter this culling mode if you wish but it is not advised unless you know what you are doing. - You may wish to use the CULL_NONE option for mesh data that you cull yourself where the vertex - winding is uncertain. - */ - virtual void _setCullingMode(CullingMode mode) = 0; - - virtual CullingMode _getCullingMode(void) const; - - /** Sets the mode of operation for depth buffer tests from this point onwards. - Sometimes you may wish to alter the behaviour of the depth buffer to achieve - special effects. Because it's unlikely that you'll set these options for an entire frame, - but rather use them to tweak settings between rendering objects, this is an internal - method (indicated by the '_' prefix) which will be used by a SceneManager implementation - rather than directly from the client application. - If this method is never called the settings are automatically the same as the default parameters. - @param depthTest If true, the depth buffer is tested for each pixel and the frame buffer is only updated - if the depth function test succeeds. If false, no test is performed and pixels are always written. - @param depthWrite If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds. - If false, the depth buffer is left unchanged even if a new pixel is written. - @param depthFunction Sets the function required for the depth test. - */ - virtual void _setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL) = 0; - - /** Sets whether or not the depth buffer check is performed before a pixel write. - @param enabled If true, the depth buffer is tested for each pixel and the frame buffer is only updated - if the depth function test succeeds. If false, no test is performed and pixels are always written. - */ - virtual void _setDepthBufferCheckEnabled(bool enabled = true) = 0; - /** Sets whether or not the depth buffer is updated after a pixel write. - @param enabled If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds. - If false, the depth buffer is left unchanged even if a new pixel is written. - */ - virtual void _setDepthBufferWriteEnabled(bool enabled = true) = 0; - /** Sets the comparison function for the depth buffer check. - Advanced use only - allows you to choose the function applied to compare the depth values of - new and existing pixels in the depth buffer. Only an issue if the deoth buffer check is enabled - (see _setDepthBufferCheckEnabled) - @param func The comparison between the new depth and the existing depth which must return true - for the new pixel to be written. - */ - virtual void _setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL) = 0; - /** Sets whether or not colour buffer writing is enabled, and for which channels. - @remarks - For some advanced effects, you may wish to turn off the writing of certain colour - channels, or even all of the colour channels so that only the depth buffer is updated - in a rendering pass. However, the chances are that you really want to use this option - through the Material class. - @param red, green, blue, alpha Whether writing is enabled for each of the 4 colour channels. */ - virtual void _setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha) = 0; - /** Sets the depth bias, NB you should use the Material version of this. - @remarks - When polygons are coplanar, you can get problems with 'depth fighting' where - the pixels from the two polys compete for the same screen pixel. This is particularly - a problem for decals (polys attached to another surface to represent details such as - bulletholes etc.). - @par - A way to combat this problem is to use a depth bias to adjust the depth buffer value - used for the decal such that it is slightly higher than the true value, ensuring that - the decal appears on top. - @note - The final bias value is a combination of a constant bias and a bias proportional - to the maximum depth slope of the polygon being rendered. The final bias - is constantBias + slopeScaleBias * maxslope. Slope scale biasing is - generally preferable but is not available on older hardware. - @param constantBias The constant bias value, expressed as a value in - homogeneous depth coordinates. - @param slopeScaleBias The bias value which is factored by the maximum slope - of the polygon, see the description above. This is not supported by all - cards. - - */ - virtual void _setDepthBias(float constantBias, float slopeScaleBias = 0.0f) = 0; - /** Sets the fogging mode for future geometry. - @param mode Set up the mode of fog as described in the FogMode enum, or set to FOG_NONE to turn off. - @param colour The colour of the fog. Either set this to the same as your viewport background colour, - or to blend in with a skydome or skybox. - @param expDensity The density of the fog in FOG_EXP or FOG_EXP2 mode, as a value between 0 and 1. The default is 1. i.e. completely opaque, lower values can mean - that fog never completely obscures the scene. - @param linearStart Distance at which linear fog starts to encroach. The distance must be passed - as a parametric value between 0 and 1, with 0 being the near clipping plane, and 1 being the far clipping plane. Only applicable if mode is FOG_LINEAR. - @param linearEnd Distance at which linear fog becomes completely opaque.The distance must be passed - as a parametric value between 0 and 1, with 0 being the near clipping plane, and 1 being the far clipping plane. Only applicable if mode is FOG_LINEAR. - */ - virtual void _setFog(FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 1.0, Real linearStart = 0.0, Real linearEnd = 1.0) = 0; - - - /** The RenderSystem will keep a count of tris rendered, this resets the count. */ - virtual void _beginGeometryCount(void); - /** Reports the number of tris rendered since the last _beginGeometryCount call. */ - virtual unsigned int _getFaceCount(void) const; - /** Reports the number of batches rendered since the last _beginGeometryCount call. */ - virtual unsigned int _getBatchCount(void) const; - /** Reports the number of vertices passed to the renderer since the last _beginGeometryCount call. */ - virtual unsigned int _getVertexCount(void) const; - - /** Generates a packed data version of the passed in ColourValue suitable for - use as with this RenderSystem. - @remarks - Since different render systems have different colour data formats (eg - RGBA for GL, ARGB for D3D) this method allows you to use 1 method for all. - @param colour The colour to convert - @param pDest Pointer to location to put the result. - */ - virtual void convertColourValue(const ColourValue& colour, uint32* pDest); - /** Get the native VertexElementType for a compact 32-bit colour value - for this rendersystem. - */ - virtual VertexElementType getColourVertexElementType(void) const = 0; - - /** Converts a uniform projection matrix to suitable for this render system. - @remarks - Because different APIs have different requirements (some incompatible) for the - projection matrix, this method allows each to implement their own correctly and pass - back a generic OGRE matrix for storage in the engine. - */ - virtual void _convertProjectionMatrix(const Matrix4& matrix, - Matrix4& dest, bool forGpuProgram = false) = 0; - - /** Builds a perspective projection matrix suitable for this render system. - @remarks - Because different APIs have different requirements (some incompatible) for the - projection matrix, this method allows each to implement their own correctly and pass - back a generic OGRE matrix for storage in the engine. - */ - virtual void _makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, - Matrix4& dest, bool forGpuProgram = false) = 0; - - /** Builds a perspective projection matrix for the case when frustum is - not centered around camera. - @remarks - Viewport coordinates are in camera coordinate frame, i.e. camera is - at the origin. - */ - virtual void _makeProjectionMatrix(Real left, Real right, Real bottom, Real top, - Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram = false) = 0; - /** Builds an orthographic projection matrix suitable for this render system. - @remarks - Because different APIs have different requirements (some incompatible) for the - projection matrix, this method allows each to implement their own correctly and pass - back a generic OGRE matrix for storage in the engine. - */ - virtual void _makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, - Matrix4& dest, bool forGpuProgram = false) = 0; - - /** Update a perspective projection matrix to use 'oblique depth projection'. - @remarks - This method can be used to change the nature of a perspective - transform in order to make the near plane not perpendicular to the - camera view direction, but to be at some different orientation. - This can be useful for performing arbitrary clipping (e.g. to a - reflection plane) which could otherwise only be done using user - clip planes, which are more expensive, and not necessarily supported - on all cards. - @param matrix The existing projection matrix. Note that this must be a - perspective transform (not orthographic), and must not have already - been altered by this method. The matrix will be altered in-place. - @param plane The plane which is to be used as the clipping plane. This - plane must be in CAMERA (view) space. - @param forGpuProgram Is this for use with a Gpu program or fixed-function - */ - virtual void _applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane, - bool forGpuProgram) = 0; - - /** Sets how to rasterise triangles, as points, wireframe or solid polys. */ - virtual void _setPolygonMode(PolygonMode level) = 0; - - /** Turns depth-stencil buffer checking on or off. - @remarks - An inactive depth-stencil buffer can be read by a shader as a texture. An - application that reads a depth-stencil buffer as a texture renders in two - passes, the first pass writes to the depth-stencil buffer and the second - pass reads from the buffer. This allows a shader to compare depth or - stencil values previously written to the buffer against the value for - the pixel currrently being rendered. The result of the comparison can - be used to create effects such as shadow mapping or soft particles - in a particle system. - */ - // virtual void setDepthCheckEnabled(bool enabled) = 0; - - /** Turns stencil buffer checking on or off. - @remarks - Stencilling (masking off areas of the rendering target based on the stencil - buffer) can be turned on or off using this method. By default, stencilling is - disabled. - */ - virtual void setStencilCheckEnabled(bool enabled) = 0; - /** Determines if this system supports hardware accelerated stencil buffer. - @remarks - Note that the lack of this function doesn't mean you can't do stencilling, but - the stencilling operations will be provided in software, which will NOT be - fast. - @par - Generally hardware stencils are only supported in 32-bit colour modes, because - the stencil buffer shares the memory of the z-buffer, and in most cards the - z-buffer has to be the same depth as the colour buffer. This means that in 32-bit - mode, 24 bits of the z-buffer are depth and 8 bits are stencil. In 16-bit mode there - is no room for a stencil (although some cards support a 15:1 depth:stencil option, - this isn't useful for very much) so 8 bits of stencil are provided in software. - This can mean that if you use stencilling, your applications may be faster in - 32-but colour than in 16-bit, which may seem odd to some people. - */ - /*virtual bool hasHardwareStencil(void) = 0;*/ - - /** This method allows you to set all the stencil buffer parameters in one call. - @remarks - The stencil buffer is used to mask out pixels in the render target, allowing - you to do effects like mirrors, cut-outs, stencil shadows and more. Each of - your batches of rendering is likely to ignore the stencil buffer, - update it with new values, or apply it to mask the output of the render. - The stencil test is:
      -		(Reference Value & Mask) CompareFunction (Stencil Buffer Value & Mask)
      - The result of this will cause one of 3 actions depending on whether the test fails, - succeeds but with the depth buffer check still failing, or succeeds with the - depth buffer check passing too. - @par - Unlike other render states, stencilling is left for the application to turn - on and off when it requires. This is because you are likely to want to change - parameters between batches of arbitrary objects and control the ordering yourself. - In order to batch things this way, you'll want to use OGRE's separate render queue - groups (see RenderQueue) and register a RenderQueueListener to get notifications - between batches. - @par - There are individual state change methods for each of the parameters set using - this method. - Note that the default values in this method represent the defaults at system - start up too. - @param func The comparison function applied. - @param refValue The reference value used in the comparison - @param compareMask The bitmask applied to both the stencil value and the reference value - before comparison - @param writeMask The bitmask the controls which bits from refValue will be written to - stencil buffer (valid for operations such as SOP_REPLACE). - the stencil - @param stencilFailOp The action to perform when the stencil check fails - @param depthFailOp The action to perform when the stencil check passes, but the - depth buffer check still fails - @param passOp The action to take when both the stencil and depth check pass. - @param twoSidedOperation If set to true, then if you render both back and front faces - (you'll have to turn off culling) then these parameters will apply for front faces, - and the inverse of them will happen for back faces (keep remains the same). - */ - virtual void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, - uint32 refValue = 0, uint32 compareMask = 0xFFFFFFFF, uint32 writeMask = 0xFFFFFFFF, - StencilOperation stencilFailOp = SOP_KEEP, - StencilOperation depthFailOp = SOP_KEEP, - StencilOperation passOp = SOP_KEEP, - bool twoSidedOperation = false, + /** Sets if fixed pipeline rendering is enabled on the system. + */ + void setFixedPipelineEnabled(bool enabled); + + /** Returns true if fixed pipeline rendering is enabled on the system. + */ + bool getFixedPipelineEnabled(void) const; + + /** Retrieves an existing DepthBuffer or creates a new one suited for the given RenderTarget + and sets it. + @remarks + RenderTarget's pool ID is respected. @see RenderTarget::setDepthBufferPool() + */ + virtual void setDepthBufferFor( RenderTarget *renderTarget ); + + // ------------------------------------------------------------------------ + // Internal Rendering Access + // All methods below here are normally only called by other OGRE classes + // They can be called by library user if required + // ------------------------------------------------------------------------ + + + /** Tells the rendersystem to use the attached set of lights (and no others) + up to the number specified (this allows the same list to be used with different + count limits) */ + virtual void _useLights(const LightList& lights, unsigned short limit) = 0; + /** Are fixed-function lights provided in view space? Affects optimisation. + */ + virtual bool areFixedFunctionLightsInViewSpace() const { return false; } + /** Sets the world transform matrix. */ + virtual void _setWorldMatrix(const Matrix4 &m) = 0; + /** Sets multiple world matrices (vertex blending). */ + virtual void _setWorldMatrices(const Matrix4* m, unsigned short count); + /** Sets the view transform matrix */ + virtual void _setViewMatrix(const Matrix4 &m) = 0; + /** Sets the projection transform matrix */ + virtual void _setProjectionMatrix(const Matrix4 &m) = 0; + /** Utility function for setting all the properties of a texture unit at once. + This method is also worth using over the individual texture unit settings because it + only sets those settings which are different from the current settings for this + unit, thus minimising render state changes. + */ + virtual void _setTextureUnitSettings(size_t texUnit, TextureUnitState& tl); + /** Set texture unit binding type */ + virtual void _setBindingType(TextureUnitState::BindingType bindigType); + /** Turns off a texture unit. */ + virtual void _disableTextureUnit(size_t texUnit); + /** Disables all texture units from the given unit upwards */ + virtual void _disableTextureUnitsFrom(size_t texUnit); + /** Sets the surface properties to be used for future rendering. + + This method sets the the properties of the surfaces of objects + to be rendered after it. In this context these surface properties + are the amount of each type of light the object reflects (determining + it's colour under different types of light), whether it emits light + itself, and how shiny it is. Textures are not dealt with here, + see the _setTetxure method for details. + This method is used by _setMaterial so does not need to be called + direct if that method is being used. + + @param ambient The amount of ambient (sourceless and directionless) + light an object reflects. Affected by the colour/amount of ambient light in the scene. + @param diffuse The amount of light from directed sources that is + reflected (affected by colour/amount of point, directed and spot light sources) + @param specular The amount of specular light reflected. This is also + affected by directed light sources but represents the colour at the + highlights of the object. + @param emissive The colour of light emitted from the object. Note that + this will make an object seem brighter and not dependent on lights in + the scene, but it will not act as a light, so will not illuminate other + objects. Use a light attached to the same SceneNode as the object for this purpose. + @param shininess A value which only has an effect on specular highlights (so + specular must be non-black). The higher this value, the smaller and crisper the + specular highlights will be, imitating a more highly polished surface. + This value is not constrained to 0.0-1.0, in fact it is likely to + be more (10.0 gives a modest sheen to an object). + @param tracking A bit field that describes which of the ambient, diffuse, specular + and emissive colours follow the vertex colour of the primitive. When a bit in this field is set + its ColourValue is ignored. This is a combination of TVC_AMBIENT, TVC_DIFFUSE, TVC_SPECULAR(note that the shininess value is still + taken from shininess) and TVC_EMISSIVE. TVC_NONE means that there will be no material property + tracking the vertex colours. + */ + virtual void _setSurfaceParams(const ColourValue &ambient, + const ColourValue &diffuse, const ColourValue &specular, + const ColourValue &emissive, Real shininess, + TrackVertexColourType tracking = TVC_NONE) = 0; + + /** Sets whether or not rendering points using OT_POINT_LIST will + render point sprites (textured quads) or plain points. + @param enabled True enables point sprites, false returns to normal + point rendering. + */ + virtual void _setPointSpritesEnabled(bool enabled) = 0; + + /** Sets the size of points and how they are attenuated with distance. + @remarks + When performing point rendering or point sprite rendering, + point size can be attenuated with distance. The equation for + doing this is attenuation = 1 / (constant + linear * dist + quadratic * d^2) . + @par + For example, to disable distance attenuation (constant screensize) + you would set constant to 1, and linear and quadratic to 0. A + standard perspective attenuation would be 0, 1, 0 respectively. + */ + virtual void _setPointParameters(Real size, bool attenuationEnabled, + Real constant, Real linear, Real quadratic, Real minSize, Real maxSize) = 0; + + + /** + Sets the texture to bind to a given texture unit. + + User processes would not normally call this direct unless rendering + primitives themselves. + + @param unit The index of the texture unit to modify. Multitexturing + hardware can support multiple units (see + RenderSystemCapabilites::getNumTextureUnits) + @param enabled Boolean to turn the unit on/off + @param texPtr Pointer to the texture to use. + */ + virtual void _setTexture(size_t unit, bool enabled, + const TexturePtr &texPtr) = 0; + /** + Sets the texture to bind to a given texture unit. + + User processes would not normally call this direct unless rendering + primitives themselves. + + @param unit The index of the texture unit to modify. Multitexturing + hardware can support multiple units (see + RenderSystemCapabilites::getNumTextureUnits) + @param enabled Boolean to turn the unit on/off + @param texname The name of the texture to use - this should have + already been loaded with TextureManager::load. + */ + virtual void _setTexture(size_t unit, bool enabled, const String &texname); + + /** Binds a texture to a vertex, geometry, compute, tesselation hull + or tessellation domain sampler. + @remarks + Not all rendersystems support separate vertex samplers. For those that + do, you can set a texture for them, separate to the regular texture + samplers, using this method. For those that don't, you should use the + regular texture samplers which are shared between the vertex and + fragment units; calling this method will throw an exception. + @see RenderSystemCapabilites::getVertexTextureUnitsShared + */ + virtual void _setVertexTexture(size_t unit, const TexturePtr& tex); + virtual void _setGeometryTexture(size_t unit, const TexturePtr& tex); + virtual void _setComputeTexture(size_t unit, const TexturePtr& tex); + virtual void _setTesselationHullTexture(size_t unit, const TexturePtr& tex); + virtual void _setTesselationDomainTexture(size_t unit, const TexturePtr& tex); + + /** + Sets the texture coordinate set to use for a texture unit. + + Meant for use internally - not generally used directly by apps - the Material and TextureUnitState + classes let you manage textures far more easily. + + @param unit Texture unit as above + @param index The index of the texture coordinate set to use. + */ + virtual void _setTextureCoordSet(size_t unit, size_t index) = 0; + + /** + Sets a method for automatically calculating texture coordinates for a stage. + Should not be used by apps - for use by Ogre only. + @param unit Texture unit as above + @param m Calculation method to use + @param frustum Optional Frustum param, only used for projective effects + */ + virtual void _setTextureCoordCalculation(size_t unit, TexCoordCalcMethod m, + const Frustum* frustum = 0) = 0; + + /** Sets the texture blend modes from a TextureUnitState record. + Meant for use internally only - apps should use the Material + and TextureUnitState classes. + @param unit Texture unit as above + @param bm Details of the blending mode + */ + virtual void _setTextureBlendMode(size_t unit, const LayerBlendModeEx& bm) = 0; + + /** Sets the filtering options for a given texture unit. + @param unit The texture unit to set the filtering options for + @param minFilter The filter used when a texture is reduced in size + @param magFilter The filter used when a texture is magnified + @param mipFilter The filter used between mipmap levels, FO_NONE disables mipmapping + */ + virtual void _setTextureUnitFiltering(size_t unit, FilterOptions minFilter, + FilterOptions magFilter, FilterOptions mipFilter); + + /** Sets a single filter for a given texture unit. + @param unit The texture unit to set the filtering options for + @param ftype The filter type + @param filter The filter to be used + */ + virtual void _setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions filter) = 0; + + /** Sets whether the compare func is enabled or not for this texture unit + @param unit The texture unit to set the filtering options for + @param compare The state (enabled/disabled) + */ + virtual void _setTextureUnitCompareEnabled(size_t unit, bool compare) = 0; + + + /** Sets the compare function to use for a given texture unit + @param unit The texture unit to set the filtering options for + @param function The comparison function + */ + virtual void _setTextureUnitCompareFunction(size_t unit, CompareFunction function) = 0; + + + /** Sets the maximal anisotropy for the specified texture unit.*/ + virtual void _setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) = 0; + + /** Sets the texture addressing mode for a texture unit.*/ + virtual void _setTextureAddressingMode(size_t unit, const TextureUnitState::UVWAddressingMode& uvw) = 0; + + /** Sets the texture border colour for a texture unit.*/ + virtual void _setTextureBorderColour(size_t unit, const ColourValue& colour) = 0; + + /** Sets the mipmap bias value for a given texture unit. + @remarks + This allows you to adjust the mipmap calculation up or down for a + given texture unit. Negative values force a larger mipmap to be used, + positive values force a smaller mipmap to be used. Units are in numbers + of levels, so +1 forces the mipmaps to one smaller level. + @note Only does something if render system has capability RSC_MIPMAP_LOD_BIAS. + */ + virtual void _setTextureMipmapBias(size_t unit, float bias) = 0; + + /** Sets the texture coordinate transformation matrix for a texture unit. + @param unit Texture unit to affect + @param xform The 4x4 matrix + */ + virtual void _setTextureMatrix(size_t unit, const Matrix4& xform) = 0; + + /** Sets the global blending factors for combining subsequent renders with the existing frame contents. + The result of the blending operation is: +

      final = (texture * sourceFactor) + (pixel * destFactor)

      + Each of the factors is specified as one of a number of options, as specified in the SceneBlendFactor + enumerated type. + By changing the operation you can change addition between the source and destination pixels to a different operator. + @param sourceFactor The source factor in the above calculation, i.e. multiplied by the texture colour components. + @param destFactor The destination factor in the above calculation, i.e. multiplied by the pixel colour components. + @param op The blend operation mode for combining pixels + */ + virtual void _setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op = SBO_ADD) = 0; + + /** Sets the global blending factors for combining subsequent renders with the existing frame contents. + The result of the blending operation is: +

      final = (texture * sourceFactor) + (pixel * destFactor)

      + Each of the factors is specified as one of a number of options, as specified in the SceneBlendFactor + enumerated type. + @param sourceFactor The source factor in the above calculation, i.e. multiplied by the texture colour components. + @param destFactor The destination factor in the above calculation, i.e. multiplied by the pixel colour components. + @param sourceFactorAlpha The source factor in the above calculation for the alpha channel, i.e. multiplied by the texture alpha components. + @param destFactorAlpha The destination factor in the above calculation for the alpha channel, i.e. multiplied by the pixel alpha components. + @param op The blend operation mode for combining pixels + @param alphaOp The blend operation mode for combining pixel alpha values + */ + virtual void _setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, + SceneBlendFactor destFactorAlpha, SceneBlendOperation op = SBO_ADD, SceneBlendOperation alphaOp = SBO_ADD) = 0; + + /** Sets the global alpha rejection approach for future renders. + By default images are rendered regardless of texture alpha. This method lets you change that. + @param func The comparison function which must pass for a pixel to be written. + @param value The value to compare each pixels alpha value to (0-255) + @param alphaToCoverage Whether to enable alpha to coverage, if supported + */ + virtual void _setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage) = 0; + + /** Notify the rendersystem that it should adjust texture projection to be + relative to a different origin. + */ + virtual void _setTextureProjectionRelativeTo(bool enabled, const Vector3& pos); + + /** Creates a DepthBuffer that can be attached to the specified RenderTarget + @remarks + It doesn't attach anything, it just returns a pointer to a new DepthBuffer + Caller is responsible for putting this buffer into the right pool, for + attaching, and deleting it. Here's where API-specific magic happens. + Don't call this directly unless you know what you're doing. + */ + virtual DepthBuffer* _createDepthBufferFor( RenderTarget *renderTarget ) = 0; + + /** Removes all depth buffers. Should be called on device lost and shutdown + @remarks + Advanced users can call this directly with bCleanManualBuffers=false to + remove all depth buffers created for RTTs; when they think the pool has + grown too big or they've used lots of depth buffers they don't need anymore, + freeing GPU RAM. + */ + void _cleanupDepthBuffers( bool bCleanManualBuffers=true ); + + /** + * Signifies the beginning of a frame, i.e. the start of rendering on a single viewport. Will occur + * several times per complete frame if multiple viewports exist. + */ + virtual void _beginFrame(void) = 0; + + //Dummy structure for render system contexts - implementing RenderSystems can extend + //as needed + struct RenderSystemContext { }; + /** + * Pause rendering for a frame. This has to be called after _beginFrame and before _endFrame. + * Will usually be called by the SceneManager, don't use this manually unless you know what + * you are doing. + */ + virtual RenderSystemContext* _pauseFrame(void); + /** + * Resume rendering for a frame. This has to be called after a _pauseFrame call + * Will usually be called by the SceneManager, don't use this manually unless you know what + * you are doing. + * @param context the render system context, as returned by _pauseFrame + */ + virtual void _resumeFrame(RenderSystemContext* context); + + /** + * Ends rendering of a frame to the current viewport. + */ + virtual void _endFrame(void) = 0; + /** + Sets the provided viewport as the active one for future + rendering operations. This viewport is aware of it's own + camera and render target. Must be implemented by subclass. + + @param vp Pointer to the appropriate viewport. + */ + virtual void _setViewport(Viewport *vp) = 0; + /** Get the current active viewport for rendering. */ + virtual Viewport* _getViewport(void); + + /** Sets the culling mode for the render system based on the 'vertex winding'. + A typical way for the rendering engine to cull triangles is based on the + 'vertex winding' of triangles. Vertex winding refers to the direction in + which the vertices are passed or indexed to in the rendering operation as viewed + from the camera, and will wither be clockwise or anticlockwise (that's 'counterclockwise' for + you Americans out there ;) The default is CULL_CLOCKWISE i.e. that only triangles whose vertices + are passed/indexed in anticlockwise order are rendered - this is a common approach and is used in 3D studio models + for example. You can alter this culling mode if you wish but it is not advised unless you know what you are doing. + You may wish to use the CULL_NONE option for mesh data that you cull yourself where the vertex + winding is uncertain. + */ + virtual void _setCullingMode(CullingMode mode) = 0; + + virtual CullingMode _getCullingMode(void) const; + + /** Sets the mode of operation for depth buffer tests from this point onwards. + Sometimes you may wish to alter the behaviour of the depth buffer to achieve + special effects. Because it's unlikely that you'll set these options for an entire frame, + but rather use them to tweak settings between rendering objects, this is an internal + method (indicated by the '_' prefix) which will be used by a SceneManager implementation + rather than directly from the client application. + If this method is never called the settings are automatically the same as the default parameters. + @param depthTest If true, the depth buffer is tested for each pixel and the frame buffer is only updated + if the depth function test succeeds. If false, no test is performed and pixels are always written. + @param depthWrite If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds. + If false, the depth buffer is left unchanged even if a new pixel is written. + @param depthFunction Sets the function required for the depth test. + */ + virtual void _setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL) = 0; + + /** Sets whether or not the depth buffer check is performed before a pixel write. + @param enabled If true, the depth buffer is tested for each pixel and the frame buffer is only updated + if the depth function test succeeds. If false, no test is performed and pixels are always written. + */ + virtual void _setDepthBufferCheckEnabled(bool enabled = true) = 0; + /** Sets whether or not the depth buffer is updated after a pixel write. + @param enabled If true, the depth buffer is updated with the depth of the new pixel if the depth test succeeds. + If false, the depth buffer is left unchanged even if a new pixel is written. + */ + virtual void _setDepthBufferWriteEnabled(bool enabled = true) = 0; + /** Sets the comparison function for the depth buffer check. + Advanced use only - allows you to choose the function applied to compare the depth values of + new and existing pixels in the depth buffer. Only an issue if the deoth buffer check is enabled + (see _setDepthBufferCheckEnabled) + @param func The comparison between the new depth and the existing depth which must return true + for the new pixel to be written. + */ + virtual void _setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL) = 0; + /** Sets whether or not colour buffer writing is enabled, and for which channels. + @remarks + For some advanced effects, you may wish to turn off the writing of certain colour + channels, or even all of the colour channels so that only the depth buffer is updated + in a rendering pass. However, the chances are that you really want to use this option + through the Material class. + @param red, green, blue, alpha Whether writing is enabled for each of the 4 colour channels. */ + virtual void _setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha) = 0; + /** Sets the depth bias, NB you should use the Material version of this. + @remarks + When polygons are coplanar, you can get problems with 'depth fighting' where + the pixels from the two polys compete for the same screen pixel. This is particularly + a problem for decals (polys attached to another surface to represent details such as + bulletholes etc.). + @par + A way to combat this problem is to use a depth bias to adjust the depth buffer value + used for the decal such that it is slightly higher than the true value, ensuring that + the decal appears on top. + @note + The final bias value is a combination of a constant bias and a bias proportional + to the maximum depth slope of the polygon being rendered. The final bias + is constantBias + slopeScaleBias * maxslope. Slope scale biasing is + generally preferable but is not available on older hardware. + @param constantBias The constant bias value, expressed as a value in + homogeneous depth coordinates. + @param slopeScaleBias The bias value which is factored by the maximum slope + of the polygon, see the description above. This is not supported by all + cards. + + */ + virtual void _setDepthBias(float constantBias, float slopeScaleBias = 0.0f) = 0; + /** Sets the fogging mode for future geometry. + @param mode Set up the mode of fog as described in the FogMode enum, or set to FOG_NONE to turn off. + @param colour The colour of the fog. Either set this to the same as your viewport background colour, + or to blend in with a skydome or skybox. + @param expDensity The density of the fog in FOG_EXP or FOG_EXP2 mode, as a value between 0 and 1. The default is 1. i.e. completely opaque, lower values can mean + that fog never completely obscures the scene. + @param linearStart Distance at which linear fog starts to encroach. The distance must be passed + as a parametric value between 0 and 1, with 0 being the near clipping plane, and 1 being the far clipping plane. Only applicable if mode is FOG_LINEAR. + @param linearEnd Distance at which linear fog becomes completely opaque.The distance must be passed + as a parametric value between 0 and 1, with 0 being the near clipping plane, and 1 being the far clipping plane. Only applicable if mode is FOG_LINEAR. + */ + virtual void _setFog(FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 1.0, Real linearStart = 0.0, Real linearEnd = 1.0) = 0; + + + /** The RenderSystem will keep a count of tris rendered, this resets the count. */ + virtual void _beginGeometryCount(void); + /** Reports the number of tris rendered since the last _beginGeometryCount call. */ + virtual unsigned int _getFaceCount(void) const; + /** Reports the number of batches rendered since the last _beginGeometryCount call. */ + virtual unsigned int _getBatchCount(void) const; + /** Reports the number of vertices passed to the renderer since the last _beginGeometryCount call. */ + virtual unsigned int _getVertexCount(void) const; + + /** Generates a packed data version of the passed in ColourValue suitable for + use as with this RenderSystem. + @remarks + Since different render systems have different colour data formats (eg + RGBA for GL, ARGB for D3D) this method allows you to use 1 method for all. + @param colour The colour to convert + @param pDest Pointer to location to put the result. + */ + virtual void convertColourValue(const ColourValue& colour, uint32* pDest); + /** Get the native VertexElementType for a compact 32-bit colour value + for this rendersystem. + */ + virtual VertexElementType getColourVertexElementType(void) const = 0; + + /** Converts a uniform projection matrix to suitable for this render system. + @remarks + Because different APIs have different requirements (some incompatible) for the + projection matrix, this method allows each to implement their own correctly and pass + back a generic OGRE matrix for storage in the engine. + */ + virtual void _convertProjectionMatrix(const Matrix4& matrix, + Matrix4& dest, bool forGpuProgram = false) = 0; + + /** Builds a perspective projection matrix suitable for this render system. + @remarks + Because different APIs have different requirements (some incompatible) for the + projection matrix, this method allows each to implement their own correctly and pass + back a generic OGRE matrix for storage in the engine. + */ + virtual void _makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, + Matrix4& dest, bool forGpuProgram = false) = 0; + + /** Builds a perspective projection matrix for the case when frustum is + not centered around camera. + @remarks + Viewport coordinates are in camera coordinate frame, i.e. camera is + at the origin. + */ + virtual void _makeProjectionMatrix(Real left, Real right, Real bottom, Real top, + Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram = false) = 0; + /** Builds an orthographic projection matrix suitable for this render system. + @remarks + Because different APIs have different requirements (some incompatible) for the + projection matrix, this method allows each to implement their own correctly and pass + back a generic OGRE matrix for storage in the engine. + */ + virtual void _makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, + Matrix4& dest, bool forGpuProgram = false) = 0; + + /** Update a perspective projection matrix to use 'oblique depth projection'. + @remarks + This method can be used to change the nature of a perspective + transform in order to make the near plane not perpendicular to the + camera view direction, but to be at some different orientation. + This can be useful for performing arbitrary clipping (e.g. to a + reflection plane) which could otherwise only be done using user + clip planes, which are more expensive, and not necessarily supported + on all cards. + @param matrix The existing projection matrix. Note that this must be a + perspective transform (not orthographic), and must not have already + been altered by this method. The matrix will be altered in-place. + @param plane The plane which is to be used as the clipping plane. This + plane must be in CAMERA (view) space. + @param forGpuProgram Is this for use with a Gpu program or fixed-function + */ + virtual void _applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane, + bool forGpuProgram) = 0; + + /** Sets how to rasterise triangles, as points, wireframe or solid polys. */ + virtual void _setPolygonMode(PolygonMode level) = 0; + + /** Turns depth-stencil buffer checking on or off. + @remarks + An inactive depth-stencil buffer can be read by a shader as a texture. An + application that reads a depth-stencil buffer as a texture renders in two + passes, the first pass writes to the depth-stencil buffer and the second + pass reads from the buffer. This allows a shader to compare depth or + stencil values previously written to the buffer against the value for + the pixel currrently being rendered. The result of the comparison can + be used to create effects such as shadow mapping or soft particles + in a particle system. + */ + // virtual void setDepthCheckEnabled(bool enabled) = 0; + + /** Turns stencil buffer checking on or off. + @remarks + Stencilling (masking off areas of the rendering target based on the stencil + buffer) can be turned on or off using this method. By default, stencilling is + disabled. + */ + virtual void setStencilCheckEnabled(bool enabled) = 0; + /** Determines if this system supports hardware accelerated stencil buffer. + @remarks + Note that the lack of this function doesn't mean you can't do stencilling, but + the stencilling operations will be provided in software, which will NOT be + fast. + @par + Generally hardware stencils are only supported in 32-bit colour modes, because + the stencil buffer shares the memory of the z-buffer, and in most cards the + z-buffer has to be the same depth as the colour buffer. This means that in 32-bit + mode, 24 bits of the z-buffer are depth and 8 bits are stencil. In 16-bit mode there + is no room for a stencil (although some cards support a 15:1 depth:stencil option, + this isn't useful for very much) so 8 bits of stencil are provided in software. + This can mean that if you use stencilling, your applications may be faster in + 32-but colour than in 16-bit, which may seem odd to some people. + */ + /*virtual bool hasHardwareStencil(void) = 0;*/ + + /** This method allows you to set all the stencil buffer parameters in one call. + @remarks + The stencil buffer is used to mask out pixels in the render target, allowing + you to do effects like mirrors, cut-outs, stencil shadows and more. Each of + your batches of rendering is likely to ignore the stencil buffer, + update it with new values, or apply it to mask the output of the render. + The stencil test is:
      +        (Reference Value & Mask) CompareFunction (Stencil Buffer Value & Mask)
      + The result of this will cause one of 3 actions depending on whether the test fails, + succeeds but with the depth buffer check still failing, or succeeds with the + depth buffer check passing too. + @par + Unlike other render states, stencilling is left for the application to turn + on and off when it requires. This is because you are likely to want to change + parameters between batches of arbitrary objects and control the ordering yourself. + In order to batch things this way, you'll want to use OGRE's separate render queue + groups (see RenderQueue) and register a RenderQueueListener to get notifications + between batches. + @par + There are individual state change methods for each of the parameters set using + this method. + Note that the default values in this method represent the defaults at system + start up too. + @param func The comparison function applied. + @param refValue The reference value used in the comparison + @param compareMask The bitmask applied to both the stencil value and the reference value + before comparison + @param writeMask The bitmask the controls which bits from refValue will be written to + stencil buffer (valid for operations such as SOP_REPLACE). + the stencil + @param stencilFailOp The action to perform when the stencil check fails + @param depthFailOp The action to perform when the stencil check passes, but the + depth buffer check still fails + @param passOp The action to take when both the stencil and depth check pass. + @param twoSidedOperation If set to true, then if you render both back and front faces + (you'll have to turn off culling) then these parameters will apply for front faces, + and the inverse of them will happen for back faces (keep remains the same). + */ + virtual void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, + uint32 refValue = 0, uint32 compareMask = 0xFFFFFFFF, uint32 writeMask = 0xFFFFFFFF, + StencilOperation stencilFailOp = SOP_KEEP, + StencilOperation depthFailOp = SOP_KEEP, + StencilOperation passOp = SOP_KEEP, + bool twoSidedOperation = false, bool readBackAsTexture = false) {}; - /** Sets the current vertex declaration, ie the source of vertex data. */ - virtual void setVertexDeclaration(VertexDeclaration* decl) = 0; - /** Sets the current vertex buffer binding state. */ - virtual void setVertexBufferBinding(VertexBufferBinding* binding) = 0; + /** Sets the current vertex declaration, ie the source of vertex data. */ + virtual void setVertexDeclaration(VertexDeclaration* decl) = 0; + /** Sets the current vertex buffer binding state. */ + virtual void setVertexBufferBinding(VertexBufferBinding* binding) = 0; - /** Sets whether or not normals are to be automatically normalised. - @remarks - This is useful when, for example, you are scaling SceneNodes such that - normals may not be unit-length anymore. Note though that this has an - overhead so should not be turn on unless you really need it. - @par - You should not normally call this direct unless you are rendering - world geometry; set it on the Renderable because otherwise it will be - overridden by material settings. - */ - virtual void setNormaliseNormals(bool normalise) = 0; + /** Sets whether or not normals are to be automatically normalised. + @remarks + This is useful when, for example, you are scaling SceneNodes such that + normals may not be unit-length anymore. Note though that this has an + overhead so should not be turn on unless you really need it. + @par + You should not normally call this direct unless you are rendering + world geometry; set it on the Renderable because otherwise it will be + overridden by material settings. + */ + virtual void setNormaliseNormals(bool normalise) = 0; - /** - Render something to the active viewport. + /** + Render something to the active viewport. - Low-level rendering interface to perform rendering - operations. Unlikely to be used directly by client - applications, since the SceneManager and various support - classes will be responsible for calling this method. - Can only be called between _beginScene and _endScene + Low-level rendering interface to perform rendering + operations. Unlikely to be used directly by client + applications, since the SceneManager and various support + classes will be responsible for calling this method. + Can only be called between _beginScene and _endScene - @param op A rendering operation instance, which contains - details of the operation to be performed. - */ - virtual void _render(const RenderOperation& op); + @param op A rendering operation instance, which contains + details of the operation to be performed. + */ + virtual void _render(const RenderOperation& op); - virtual void _renderUsingReadBackAsTexture(unsigned int secondPass,Ogre::String variableName,unsigned int StartSlot); + virtual void _renderUsingReadBackAsTexture(unsigned int secondPass,Ogre::String variableName,unsigned int StartSlot); - /** Gets the capabilities of the render system. */ - const RenderSystemCapabilities* getCapabilities(void) const { return mCurrentCapabilities; } + /** Gets the capabilities of the render system. */ + const RenderSystemCapabilities* getCapabilities(void) const { return mCurrentCapabilities; } - /** Returns the driver version. - */ - virtual const DriverVersion& getDriverVersion(void) const { return mDriverVersion; } + /** Returns the driver version. + */ + virtual const DriverVersion& getDriverVersion(void) const { return mDriverVersion; } /** Returns the default material scheme used by the render system. Systems that use the RTSS to emulate a fixed function pipeline @@ -1238,34 +1238,34 @@ namespace Ogre This is currently only used to set the default material scheme for viewports. It is a necessary step on these render systems for render textures to be rendered into properly. - */ - virtual const String& _getDefaultViewportMaterialScheme(void) const; - - /** Binds a given GpuProgram (but not the parameters). - @remarks Only one GpuProgram of each type can be bound at once, binding another - one will simply replace the existing one. - */ - virtual void bindGpuProgram(GpuProgram* prg); - - /** Bind Gpu program parameters. - @param gptype The type of program to bind the parameters to - @param params The parameters to bind - @param variabilityMask A mask of GpuParamVariability identifying which params need binding - */ - virtual void bindGpuProgramParameters(GpuProgramType gptype, - GpuProgramParametersSharedPtr params, uint16 variabilityMask) = 0; - - /** Only binds Gpu program parameters used for passes that have more than one iteration rendering - */ - virtual void bindGpuProgramPassIterationParameters(GpuProgramType gptype) = 0; - /** Unbinds GpuPrograms of a given GpuProgramType. - @remarks - This returns the pipeline to fixed-function processing for this type. - */ - virtual void unbindGpuProgram(GpuProgramType gptype); - - /** Returns whether or not a Gpu program of the given type is currently bound. */ - virtual bool isGpuProgramBound(GpuProgramType gptype); + */ + virtual const String& _getDefaultViewportMaterialScheme(void) const; + + /** Binds a given GpuProgram (but not the parameters). + @remarks Only one GpuProgram of each type can be bound at once, binding another + one will simply replace the existing one. + */ + virtual void bindGpuProgram(GpuProgram* prg); + + /** Bind Gpu program parameters. + @param gptype The type of program to bind the parameters to + @param params The parameters to bind + @param variabilityMask A mask of GpuParamVariability identifying which params need binding + */ + virtual void bindGpuProgramParameters(GpuProgramType gptype, + GpuProgramParametersSharedPtr params, uint16 variabilityMask) = 0; + + /** Only binds Gpu program parameters used for passes that have more than one iteration rendering + */ + virtual void bindGpuProgramPassIterationParameters(GpuProgramType gptype) = 0; + /** Unbinds GpuPrograms of a given GpuProgramType. + @remarks + This returns the pipeline to fixed-function processing for this type. + */ + virtual void unbindGpuProgram(GpuProgramType gptype); + + /** Returns whether or not a Gpu program of the given type is currently bound. */ + virtual bool isGpuProgramBound(GpuProgramType gptype); /** * Gets the native shading language version for this render system. @@ -1274,225 +1274,225 @@ namespace Ogre */ uint16 getNativeShadingLanguageVersion() const { return mNativeShadingLanguageVersion; } - /** Sets the user clipping region. - */ - virtual void setClipPlanes(const PlaneList& clipPlanes); - - /** Add a user clipping plane. */ - virtual void addClipPlane (const Plane &p); - /** Add a user clipping plane. */ - virtual void addClipPlane (Real A, Real B, Real C, Real D); - - /** Clears the user clipping region. - */ - virtual void resetClipPlanes(); - - /** Utility method for initialising all render targets attached to this rendering system. */ - virtual void _initRenderTargets(void); - - /** Utility method to notify all render targets that a camera has been removed, - in case they were referring to it as their viewer. - */ - virtual void _notifyCameraRemoved(const Camera* cam); - - /** Internal method for updating all render targets attached to this rendering system. */ - virtual void _updateAllRenderTargets(bool swapBuffers = true); - /** Internal method for swapping all the buffers on all render targets, - if _updateAllRenderTargets was called with a 'false' parameter. */ - virtual void _swapAllRenderTargetBuffers(); - - /** Sets whether or not vertex windings set should be inverted; this can be important - for rendering reflections. */ - virtual void setInvertVertexWinding(bool invert); - - /** Indicates whether or not the vertex windings set will be inverted for the current render (e.g. reflections) - @see RenderSystem::setInvertVertexWinding - */ - virtual bool getInvertVertexWinding(void) const; - - /** Sets the 'scissor region' i.e. the region of the target in which rendering can take place. - @remarks - This method allows you to 'mask off' rendering in all but a given rectangular area - as identified by the parameters to this method. - @note - Not all systems support this method. Check the RenderSystemCapabilities for the - RSC_SCISSOR_TEST capability to see if it is supported. - @param enabled True to enable the scissor test, false to disable it. - @param left, top, right, bottom The location of the corners of the rectangle, expressed in - pixels. - */ - virtual void setScissorTest(bool enabled, size_t left = 0, size_t top = 0, - size_t right = 800, size_t bottom = 600) = 0; - - /** Clears one or more frame buffers on the active render target. - @param buffers Combination of one or more elements of FrameBufferType - denoting which buffers are to be cleared - @param colour The colour to clear the colour buffer with, if enabled - @param depth The value to initialise the depth buffer with, if enabled - @param stencil The value to initialise the stencil buffer with, if enabled. - */ - virtual void clearFrameBuffer(unsigned int buffers, - const ColourValue& colour = ColourValue::Black, - Real depth = 1.0f, unsigned short stencil = 0) = 0; - /** Returns the horizontal texel offset value required for mapping - texel origins to pixel origins in this rendersystem. - @remarks - Since rendersystems sometimes disagree on the origin of a texel, - mapping from texels to pixels can sometimes be problematic to - implement generically. This method allows you to retrieve the offset - required to map the origin of a texel to the origin of a pixel in - the horizontal direction. - */ - virtual Real getHorizontalTexelOffset(void) = 0; - /** Returns the vertical texel offset value required for mapping - texel origins to pixel origins in this rendersystem. - @remarks - Since rendersystems sometimes disagree on the origin of a texel, - mapping from texels to pixels can sometimes be problematic to - implement generically. This method allows you to retrieve the offset - required to map the origin of a texel to the origin of a pixel in - the vertical direction. - */ - virtual Real getVerticalTexelOffset(void) = 0; - - /** Gets the minimum (closest) depth value to be used when rendering - using identity transforms. - @remarks - When using identity transforms you can manually set the depth - of a vertex; however the input values required differ per - rendersystem. This method lets you retrieve the correct value. - @see Renderable::getUseIdentityView, Renderable::getUseIdentityProjection - */ - virtual Real getMinimumDepthInputValue(void) = 0; - /** Gets the maximum (farthest) depth value to be used when rendering - using identity transforms. - @remarks - When using identity transforms you can manually set the depth - of a vertex; however the input values required differ per - rendersystem. This method lets you retrieve the correct value. - @see Renderable::getUseIdentityView, Renderable::getUseIdentityProjection - */ - virtual Real getMaximumDepthInputValue(void) = 0; - /** set the current multi pass count value. This must be set prior to - calling _render() if multiple renderings of the same pass state are - required. - @param count Number of times to render the current state. - */ - virtual void setCurrentPassIterationCount(const size_t count) { mCurrentPassIterationCount = count; } - - /** Tell the render system whether to derive a depth bias on its own based on - the values passed to it in setCurrentPassIterationCount. - The depth bias set will be baseValue + iteration * multiplier - @param derive True to tell the RS to derive this automatically - @param baseValue The base value to which the multiplier should be - added - @param multiplier The amount of depth bias to apply per iteration - @param slopeScale The constant slope scale bias for completeness - */ - virtual void setDeriveDepthBias(bool derive, float baseValue = 0.0f, - float multiplier = 0.0f, float slopeScale = 0.0f) - { - mDerivedDepthBias = derive; - mDerivedDepthBiasBase = baseValue; - mDerivedDepthBiasMultiplier = multiplier; - mDerivedDepthBiasSlopeScale = slopeScale; - } - - /** + /** Sets the user clipping region. + */ + virtual void setClipPlanes(const PlaneList& clipPlanes); + + /** Add a user clipping plane. */ + virtual void addClipPlane (const Plane &p); + /** Add a user clipping plane. */ + virtual void addClipPlane (Real A, Real B, Real C, Real D); + + /** Clears the user clipping region. + */ + virtual void resetClipPlanes(); + + /** Utility method for initialising all render targets attached to this rendering system. */ + virtual void _initRenderTargets(void); + + /** Utility method to notify all render targets that a camera has been removed, + in case they were referring to it as their viewer. + */ + virtual void _notifyCameraRemoved(const Camera* cam); + + /** Internal method for updating all render targets attached to this rendering system. */ + virtual void _updateAllRenderTargets(bool swapBuffers = true); + /** Internal method for swapping all the buffers on all render targets, + if _updateAllRenderTargets was called with a 'false' parameter. */ + virtual void _swapAllRenderTargetBuffers(); + + /** Sets whether or not vertex windings set should be inverted; this can be important + for rendering reflections. */ + virtual void setInvertVertexWinding(bool invert); + + /** Indicates whether or not the vertex windings set will be inverted for the current render (e.g. reflections) + @see RenderSystem::setInvertVertexWinding + */ + virtual bool getInvertVertexWinding(void) const; + + /** Sets the 'scissor region' i.e. the region of the target in which rendering can take place. + @remarks + This method allows you to 'mask off' rendering in all but a given rectangular area + as identified by the parameters to this method. + @note + Not all systems support this method. Check the RenderSystemCapabilities for the + RSC_SCISSOR_TEST capability to see if it is supported. + @param enabled True to enable the scissor test, false to disable it. + @param left, top, right, bottom The location of the corners of the rectangle, expressed in + pixels. + */ + virtual void setScissorTest(bool enabled, size_t left = 0, size_t top = 0, + size_t right = 800, size_t bottom = 600) = 0; + + /** Clears one or more frame buffers on the active render target. + @param buffers Combination of one or more elements of FrameBufferType + denoting which buffers are to be cleared + @param colour The colour to clear the colour buffer with, if enabled + @param depth The value to initialise the depth buffer with, if enabled + @param stencil The value to initialise the stencil buffer with, if enabled. + */ + virtual void clearFrameBuffer(unsigned int buffers, + const ColourValue& colour = ColourValue::Black, + Real depth = 1.0f, unsigned short stencil = 0) = 0; + /** Returns the horizontal texel offset value required for mapping + texel origins to pixel origins in this rendersystem. + @remarks + Since rendersystems sometimes disagree on the origin of a texel, + mapping from texels to pixels can sometimes be problematic to + implement generically. This method allows you to retrieve the offset + required to map the origin of a texel to the origin of a pixel in + the horizontal direction. + */ + virtual Real getHorizontalTexelOffset(void) = 0; + /** Returns the vertical texel offset value required for mapping + texel origins to pixel origins in this rendersystem. + @remarks + Since rendersystems sometimes disagree on the origin of a texel, + mapping from texels to pixels can sometimes be problematic to + implement generically. This method allows you to retrieve the offset + required to map the origin of a texel to the origin of a pixel in + the vertical direction. + */ + virtual Real getVerticalTexelOffset(void) = 0; + + /** Gets the minimum (closest) depth value to be used when rendering + using identity transforms. + @remarks + When using identity transforms you can manually set the depth + of a vertex; however the input values required differ per + rendersystem. This method lets you retrieve the correct value. + @see Renderable::getUseIdentityView, Renderable::getUseIdentityProjection + */ + virtual Real getMinimumDepthInputValue(void) = 0; + /** Gets the maximum (farthest) depth value to be used when rendering + using identity transforms. + @remarks + When using identity transforms you can manually set the depth + of a vertex; however the input values required differ per + rendersystem. This method lets you retrieve the correct value. + @see Renderable::getUseIdentityView, Renderable::getUseIdentityProjection + */ + virtual Real getMaximumDepthInputValue(void) = 0; + /** set the current multi pass count value. This must be set prior to + calling _render() if multiple renderings of the same pass state are + required. + @param count Number of times to render the current state. + */ + virtual void setCurrentPassIterationCount(const size_t count) { mCurrentPassIterationCount = count; } + + /** Tell the render system whether to derive a depth bias on its own based on + the values passed to it in setCurrentPassIterationCount. + The depth bias set will be baseValue + iteration * multiplier + @param derive True to tell the RS to derive this automatically + @param baseValue The base value to which the multiplier should be + added + @param multiplier The amount of depth bias to apply per iteration + @param slopeScale The constant slope scale bias for completeness + */ + virtual void setDeriveDepthBias(bool derive, float baseValue = 0.0f, + float multiplier = 0.0f, float slopeScale = 0.0f) + { + mDerivedDepthBias = derive; + mDerivedDepthBiasBase = baseValue; + mDerivedDepthBiasMultiplier = multiplier; + mDerivedDepthBiasSlopeScale = slopeScale; + } + + /** * Set current render target to target, enabling its device context if needed */ virtual void _setRenderTarget(RenderTarget *target) = 0; - /** Defines a listener on the custom events that this render system - can raise. - @see RenderSystem::addListener - */ - class _OgreExport Listener - { - public: - Listener() {} - virtual ~Listener() {} - - /** A rendersystem-specific event occurred. - @param eventName The name of the event which has occurred - @param parameters A list of parameters that may belong to this event, - may be null if there are no parameters - */ - virtual void eventOccurred(const String& eventName, - const NameValuePairList* parameters = 0) = 0; - }; - /** Adds a listener to the custom events that this render system can raise. - @remarks - Some render systems have quite specific, internally generated events - that the application may wish to be notified of. Many applications - don't have to worry about these events, and can just trust OGRE to - handle them, but if you want to know, you can add a listener here. - @par - Events are raised very generically by string name. Perhaps the most - common example of a render system specific event is the loss and - restoration of a device in DirectX; which OGRE deals with, but you - may wish to know when it happens. - @see RenderSystem::getRenderSystemEvents - */ - virtual void addListener(Listener* l); - /** Remove a listener to the custom events that this render system can raise. - */ - virtual void removeListener(Listener* l); - - /** Gets a list of the rendersystem specific events that this rendersystem - can raise. - @see RenderSystem::addListener - */ - virtual const StringVector& getRenderSystemEvents(void) const { return mEventNames; } - - /** Tell the rendersystem to perform any prep tasks it needs to directly - before other threads which might access the rendering API are registered. - @remarks - Call this from your main thread before starting your other threads - (which themselves should call registerThread()). Note that if you - start your own threads, there is a specific startup sequence which - must be respected and requires synchronisation between the threads: -
        -
      1. [Main thread]Call preExtraThreadsStarted
      2. -
      3. [Main thread]Start other thread, wait
      4. -
      5. [Other thread]Call registerThread, notify main thread & continue
      6. -
      7. [Main thread]Wake up & call postExtraThreadsStarted
      8. -
      - Once this init sequence is completed the threads are independent but - this startup sequence must be respected. - */ - virtual void preExtraThreadsStarted() = 0; - - /* Tell the rendersystem to perform any tasks it needs to directly - after other threads which might access the rendering API are registered. - @see RenderSystem::preExtraThreadsStarted - */ - virtual void postExtraThreadsStarted() = 0; - - /** Register the an additional thread which may make calls to rendersystem-related - objects. - @remarks - This method should only be called by additional threads during their - initialisation. If they intend to use hardware rendering system resources - they should call this method before doing anything related to the render system. - Some rendering APIs require a per-thread setup and this method will sort that - out. It is also necessary to call unregisterThread before the thread shuts down. - @note - This method takes no parameters - it must be called from the thread being - registered and that context is enough. - */ - virtual void registerThread() = 0; - - /** Unregister an additional thread which may make calls to rendersystem-related objects. - @see RenderSystem::registerThread - */ - virtual void unregisterThread() = 0; - - /** - * Gets the number of display monitors. - @see Root::getDisplayMonitorCount - */ - virtual unsigned int getDisplayMonitorCount() const = 0; + /** Defines a listener on the custom events that this render system + can raise. + @see RenderSystem::addListener + */ + class _OgreExport Listener + { + public: + Listener() {} + virtual ~Listener() {} + + /** A rendersystem-specific event occurred. + @param eventName The name of the event which has occurred + @param parameters A list of parameters that may belong to this event, + may be null if there are no parameters + */ + virtual void eventOccurred(const String& eventName, + const NameValuePairList* parameters = 0) = 0; + }; + /** Adds a listener to the custom events that this render system can raise. + @remarks + Some render systems have quite specific, internally generated events + that the application may wish to be notified of. Many applications + don't have to worry about these events, and can just trust OGRE to + handle them, but if you want to know, you can add a listener here. + @par + Events are raised very generically by string name. Perhaps the most + common example of a render system specific event is the loss and + restoration of a device in DirectX; which OGRE deals with, but you + may wish to know when it happens. + @see RenderSystem::getRenderSystemEvents + */ + virtual void addListener(Listener* l); + /** Remove a listener to the custom events that this render system can raise. + */ + virtual void removeListener(Listener* l); + + /** Gets a list of the rendersystem specific events that this rendersystem + can raise. + @see RenderSystem::addListener + */ + virtual const StringVector& getRenderSystemEvents(void) const { return mEventNames; } + + /** Tell the rendersystem to perform any prep tasks it needs to directly + before other threads which might access the rendering API are registered. + @remarks + Call this from your main thread before starting your other threads + (which themselves should call registerThread()). Note that if you + start your own threads, there is a specific startup sequence which + must be respected and requires synchronisation between the threads: +
        +
      1. [Main thread]Call preExtraThreadsStarted
      2. +
      3. [Main thread]Start other thread, wait
      4. +
      5. [Other thread]Call registerThread, notify main thread & continue
      6. +
      7. [Main thread]Wake up & call postExtraThreadsStarted
      8. +
      + Once this init sequence is completed the threads are independent but + this startup sequence must be respected. + */ + virtual void preExtraThreadsStarted() = 0; + + /* Tell the rendersystem to perform any tasks it needs to directly + after other threads which might access the rendering API are registered. + @see RenderSystem::preExtraThreadsStarted + */ + virtual void postExtraThreadsStarted() = 0; + + /** Register the an additional thread which may make calls to rendersystem-related + objects. + @remarks + This method should only be called by additional threads during their + initialisation. If they intend to use hardware rendering system resources + they should call this method before doing anything related to the render system. + Some rendering APIs require a per-thread setup and this method will sort that + out. It is also necessary to call unregisterThread before the thread shuts down. + @note + This method takes no parameters - it must be called from the thread being + registered and that context is enough. + */ + virtual void registerThread() = 0; + + /** Unregister an additional thread which may make calls to rendersystem-related objects. + @see RenderSystem::registerThread + */ + virtual void unregisterThread() = 0; + + /** + * Gets the number of display monitors. + @see Root::getDisplayMonitorCount + */ + virtual unsigned int getDisplayMonitorCount() const = 0; /** * This marks the beginning of an event for GPU profiling. @@ -1510,70 +1510,70 @@ namespace Ogre */ virtual void markProfileEvent( const String &event ) = 0; - /** Determines if the system has anisotropic mip map filter support - */ - virtual bool hasAnisotropicMipMapFilter() const = 0; + /** Determines if the system has anisotropic mip map filter support + */ + virtual bool hasAnisotropicMipMapFilter() const = 0; - /** Gets a custom (maybe platform-specific) attribute. + /** Gets a custom (maybe platform-specific) attribute. @remarks This is a nasty way of satisfying any API's need to see platform-specific details. @param name The name of the attribute. @param pData Pointer to memory of the right kind of structure to receive the info. */ - virtual void getCustomAttribute(const String& name, void* pData); + virtual void getCustomAttribute(const String& name, void* pData); - protected: + protected: - /** DepthBuffers to be attached to render targets */ - DepthBufferMap mDepthBufferPool; + /** DepthBuffers to be attached to render targets */ + DepthBufferMap mDepthBufferPool; - /** The render targets. */ - RenderTargetMap mRenderTargets; - /** The render targets, ordered by priority. */ - RenderTargetPriorityMap mPrioritisedRenderTargets; - /** The Active render target. */ - RenderTarget * mActiveRenderTarget; + /** The render targets. */ + RenderTargetMap mRenderTargets; + /** The render targets, ordered by priority. */ + RenderTargetPriorityMap mPrioritisedRenderTargets; + /** The Active render target. */ + RenderTarget * mActiveRenderTarget; - /** The Active GPU programs and gpu program parameters*/ - GpuProgramParametersSharedPtr mActiveVertexGpuProgramParameters; - GpuProgramParametersSharedPtr mActiveGeometryGpuProgramParameters; - GpuProgramParametersSharedPtr mActiveFragmentGpuProgramParameters; - GpuProgramParametersSharedPtr mActiveTessellationHullGpuProgramParameters; - GpuProgramParametersSharedPtr mActiveTessellationDomainGpuProgramParameters; - GpuProgramParametersSharedPtr mActiveComputeGpuProgramParameters; + /** The Active GPU programs and gpu program parameters*/ + GpuProgramParametersSharedPtr mActiveVertexGpuProgramParameters; + GpuProgramParametersSharedPtr mActiveGeometryGpuProgramParameters; + GpuProgramParametersSharedPtr mActiveFragmentGpuProgramParameters; + GpuProgramParametersSharedPtr mActiveTessellationHullGpuProgramParameters; + GpuProgramParametersSharedPtr mActiveTessellationDomainGpuProgramParameters; + GpuProgramParametersSharedPtr mActiveComputeGpuProgramParameters; - // Texture manager - // A concrete class of this will be created and - // made available under the TextureManager singleton, - // managed by the RenderSystem - TextureManager* mTextureManager; + // Texture manager + // A concrete class of this will be created and + // made available under the TextureManager singleton, + // managed by the RenderSystem + TextureManager* mTextureManager; - // Active viewport (dest for future rendering operations) - Viewport* mActiveViewport; + // Active viewport (dest for future rendering operations) + Viewport* mActiveViewport; - CullingMode mCullingMode; + CullingMode mCullingMode; - bool mWBuffer; + bool mWBuffer; - size_t mBatchCount; - size_t mFaceCount; - size_t mVertexCount; + size_t mBatchCount; + size_t mFaceCount; + size_t mVertexCount; - /// Saved manual colour blends - ColourValue mManualBlendColours[OGRE_MAX_TEXTURE_LAYERS][2]; + /// Saved manual colour blends + ColourValue mManualBlendColours[OGRE_MAX_TEXTURE_LAYERS][2]; - bool mInvertVertexWinding; + bool mInvertVertexWinding; - /// Texture units from this upwards are disabled - size_t mDisabledTexUnitsFrom; + /// Texture units from this upwards are disabled + size_t mDisabledTexUnitsFrom; - /// number of times to render the current state - size_t mCurrentPassIterationCount; - size_t mCurrentPassIterationNum; - /// Whether to update the depth bias per render call - bool mDerivedDepthBias; - float mDerivedDepthBiasBase; - float mDerivedDepthBiasMultiplier; - float mDerivedDepthBiasSlopeScale; + /// number of times to render the current state + size_t mCurrentPassIterationCount; + size_t mCurrentPassIterationNum; + /// Whether to update the depth bias per render call + bool mDerivedDepthBias; + float mDerivedDepthBiasBase; + float mDerivedDepthBiasMultiplier; + float mDerivedDepthBiasSlopeScale; /// a global vertex buffer for global instancing HardwareVertexBufferSharedPtr mGlobalInstanceVertexBuffer; @@ -1582,62 +1582,62 @@ namespace Ogre /// the number of global instances (this number will be multiply by the render op instance number) size_t mGlobalNumberOfInstances; - /// is fixed pipeline enabled - bool mEnableFixedPipeline; + /// is fixed pipeline enabled + bool mEnableFixedPipeline; - /** updates pass iteration rendering state including bound gpu program parameter - pass iteration auto constant entry - @return True if more iterations are required - */ - bool updatePassIterationRenderState(void); + /** updates pass iteration rendering state including bound gpu program parameter + pass iteration auto constant entry + @return True if more iterations are required + */ + bool updatePassIterationRenderState(void); - /// List of names of events this rendersystem may raise - StringVector mEventNames; + /// List of names of events this rendersystem may raise + StringVector mEventNames; - /// Internal method for firing a rendersystem event - virtual void fireEvent(const String& name, const NameValuePairList* params = 0); + /// Internal method for firing a rendersystem event + virtual void fireEvent(const String& name, const NameValuePairList* params = 0); - typedef list::type ListenerList; - ListenerList mEventListeners; + typedef list::type ListenerList; + ListenerList mEventListeners; - typedef list::type HardwareOcclusionQueryList; - HardwareOcclusionQueryList mHwOcclusionQueries; + typedef list::type HardwareOcclusionQueryList; + HardwareOcclusionQueryList mHwOcclusionQueries; - bool mVertexProgramBound; - bool mGeometryProgramBound; - bool mFragmentProgramBound; - bool mTessellationHullProgramBound; - bool mTessellationDomainProgramBound; - bool mComputeProgramBound; + bool mVertexProgramBound; + bool mGeometryProgramBound; + bool mFragmentProgramBound; + bool mTessellationHullProgramBound; + bool mTessellationDomainProgramBound; + bool mComputeProgramBound; - // Recording user clip planes - PlaneList mClipPlanes; - // Indicator that we need to re-set the clip planes on next render call - bool mClipPlanesDirty; + // Recording user clip planes + PlaneList mClipPlanes; + // Indicator that we need to re-set the clip planes on next render call + bool mClipPlanesDirty; - /// Used to store the capabilities of the graphics card - RenderSystemCapabilities* mRealCapabilities; - RenderSystemCapabilities* mCurrentCapabilities; - bool mUseCustomCapabilities; + /// Used to store the capabilities of the graphics card + RenderSystemCapabilities* mRealCapabilities; + RenderSystemCapabilities* mCurrentCapabilities; + bool mUseCustomCapabilities; - /// Internal method used to set the underlying clip planes when needed - virtual void setClipPlanesImpl(const PlaneList& clipPlanes) = 0; + /// Internal method used to set the underlying clip planes when needed + virtual void setClipPlanesImpl(const PlaneList& clipPlanes) = 0; - /** Initialize the render system from the capabilities*/ - virtual void initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary) = 0; + /** Initialize the render system from the capabilities*/ + virtual void initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary) = 0; - DriverVersion mDriverVersion; + DriverVersion mDriverVersion; uint16 mNativeShadingLanguageVersion; - bool mTexProjRelative; - Vector3 mTexProjRelativeOrigin; + bool mTexProjRelative; + Vector3 mTexProjRelativeOrigin; - }; - /** @} */ - /** @} */ + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreRenderSystemCapabilities.h b/OgreMain/include/OgreRenderSystemCapabilities.h index 8dccff40f16..b9edbf3c698 100644 --- a/OgreMain/include/OgreRenderSystemCapabilities.h +++ b/OgreMain/include/OgreRenderSystemCapabilities.h @@ -49,839 +49,839 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - - /// Enumerates the categories of capabilities - enum CapabilitiesCategory - { - CAPS_CATEGORY_COMMON = 0, - CAPS_CATEGORY_COMMON_2 = 1, - CAPS_CATEGORY_D3D9 = 2, - CAPS_CATEGORY_GL = 3, - /// Placeholder for max value - CAPS_CATEGORY_COUNT = 4 - }; - - /// Enum describing the different hardware capabilities we want to check for - /// OGRE_CAPS_VALUE(a, b) defines each capability - // a is the category (which can be from 0 to 15) - // b is the value (from 0 to 27) - enum Capabilities - { - /// Supports generating mipmaps in hardware - RSC_AUTOMIPMAP = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 0), - RSC_BLENDING = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 1), - /// Supports anisotropic texture filtering - RSC_ANISOTROPY = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 2), - /// Supports fixed-function DOT3 texture blend - RSC_DOT3 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 3), - /// Supports cube mapping - RSC_CUBEMAPPING = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 4), - /// Supports hardware stencil buffer - RSC_HWSTENCIL = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 5), - /// Supports hardware vertex and index buffers - RSC_VBO = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 7), - /// Supports 32bit hardware index buffers - RSC_32BIT_INDEX = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 8), - /// Supports vertex programs (vertex shaders) - RSC_VERTEX_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 9), - /// Supports fragment programs (pixel shaders) - RSC_FRAGMENT_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 10), - /// Supports performing a scissor test to exclude areas of the screen - RSC_SCISSOR_TEST = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 11), - /// Supports separate stencil updates for both front and back faces - RSC_TWO_SIDED_STENCIL = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 12), - /// Supports wrapping the stencil value at the range extremeties - RSC_STENCIL_WRAP = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 13), - /// Supports hardware occlusion queries - RSC_HWOCCLUSION = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 14), - /// Supports user clipping planes - RSC_USER_CLIP_PLANES = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 15), - /// Supports the VET_UBYTE4 vertex element type - RSC_VERTEX_FORMAT_UBYTE4 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 16), - /// Supports infinite far plane projection - RSC_INFINITE_FAR_PLANE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 17), - /// Supports hardware render-to-texture (bigger than framebuffer) - RSC_HWRENDER_TO_TEXTURE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 18), - /// Supports float textures and render targets - RSC_TEXTURE_FLOAT = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 19), - /// Supports non-power of two textures - RSC_NON_POWER_OF_2_TEXTURES = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 20), - /// Supports 3d (volume) textures - RSC_TEXTURE_3D = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 21), - /// Supports basic point sprite rendering - RSC_POINT_SPRITES = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 22), - /// Supports extra point parameters (minsize, maxsize, attenuation) - RSC_POINT_EXTENDED_PARAMETERS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 23), - /// Supports vertex texture fetch - RSC_VERTEX_TEXTURE_FETCH = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 24), - /// Supports mipmap LOD biasing - RSC_MIPMAP_LOD_BIAS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 25), - /// Supports hardware geometry programs - RSC_GEOMETRY_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 26), - /// Supports rendering to vertex buffers - RSC_HWRENDER_TO_VERTEX_BUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 27), - /// Supports different texture bindings - RSC_COMPLETE_TEXTURE_BINDING = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 28), - - /// Supports compressed textures - RSC_TEXTURE_COMPRESSION = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 0), - /// Supports compressed textures in the DXT/ST3C formats - RSC_TEXTURE_COMPRESSION_DXT = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 1), - /// Supports compressed textures in the VTC format - RSC_TEXTURE_COMPRESSION_VTC = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 2), - /// Supports compressed textures in the PVRTC format - RSC_TEXTURE_COMPRESSION_PVRTC = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 3), - /// Supports compressed textures in the ATC format - RSC_TEXTURE_COMPRESSION_ATC = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 4), - /// Supports compressed textures in the ETC1 format - RSC_TEXTURE_COMPRESSION_ETC1 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 5), - /// Supports compressed textures in the ETC2 format - RSC_TEXTURE_COMPRESSION_ETC2 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 6), - /// Supports compressed textures in BC4 and BC5 format (DirectX feature level 10_0) - RSC_TEXTURE_COMPRESSION_BC4_BC5 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 7), - /// Supports compressed textures in BC6H and BC7 format (DirectX feature level 11_0) - RSC_TEXTURE_COMPRESSION_BC6H_BC7 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 8), - /// Supports fixed-function pipeline - RSC_FIXED_FUNCTION = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 9), - /// Supports MRTs with different bit depths - RSC_MRT_DIFFERENT_BIT_DEPTHS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 10), - /// Supports Alpha to Coverage (A2C) - RSC_ALPHA_TO_COVERAGE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 11), - /// Supports Blending operations other than + - RSC_ADVANCED_BLEND_OPERATIONS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 12), - /// Supports a separate depth buffer for RTTs. D3D 9 & 10, OGL w/FBO (RSC_FBO implies this flag) - RSC_RTT_SEPARATE_DEPTHBUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 13), - /// Supports using the MAIN depth buffer for RTTs. D3D 9&10, OGL w/FBO support unknown - /// (undefined behavior?), OGL w/ copy supports it - RSC_RTT_MAIN_DEPTHBUFFER_ATTACHABLE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 14), - /// Supports attaching a depth buffer to an RTT that has width & height less or equal than RTT's. - /// Otherwise must be of _exact_ same resolution. D3D 9, OGL 3.0 (not 2.0, not D3D10) - RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 15), - /// Supports using vertex buffers for instance data - RSC_VERTEX_BUFFER_INSTANCE_DATA = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 16), - /// Supports using vertex buffers for instance data - RSC_CAN_GET_COMPILED_SHADER_BUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 17), - /// Supports dynamic linkage/shader subroutine - RSC_SHADER_SUBROUTINE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 18), - - RSC_HWRENDER_TO_TEXTURE_3D = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 19), - /// Supports 1d textures - RSC_TEXTURE_1D = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 20), - /// Supports hardware tessellation hull programs - RSC_TESSELLATION_HULL_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 21), - /// Supports hardware tessellation domain programs - RSC_TESSELLATION_DOMAIN_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 22), - /// Supports hardware compute programs - RSC_COMPUTE_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 23), - /// Supports asynchronous hardware occlusion queries - RSC_HWOCCLUSION_ASYNCHRONOUS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 24), - /// Supports asynchronous hardware occlusion queries - RSC_ATOMIC_COUNTERS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 25), - /// Supports reading back the inactive depth-stencil buffer as texture - RSC_READ_BACK_AS_TEXTURE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 26), - // ***** DirectX specific caps ***** - /// Is DirectX feature "per stage constants" supported - RSC_PERSTAGECONSTANT = OGRE_CAPS_VALUE(CAPS_CATEGORY_D3D9, 0), - - // ***** GL Specific Caps ***** - /// Supports OpenGL version 1.5 - RSC_GL1_5_NOVBO = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 1), - /// Support for Frame Buffer Objects (FBOs) - RSC_FBO = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 2), - /// Support for Frame Buffer Objects ARB implementation (regular FBO is higher precedence) - RSC_FBO_ARB = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 3), - /// Support for Frame Buffer Objects ATI implementation (ARB FBO is higher precedence) - RSC_FBO_ATI = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 4), - /// Support for PBuffer - RSC_PBUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 5), - /// Support for GL 1.5 but without HW occlusion workaround - RSC_GL1_5_NOHWOCCLUSION = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 6), - /// Support for point parameters ARB implementation - RSC_POINT_EXTENDED_PARAMETERS_ARB = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 7), - /// Support for point parameters EXT implementation - RSC_POINT_EXTENDED_PARAMETERS_EXT = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 8), - /// Support for Separate Shader Objects - RSC_SEPARATE_SHADER_OBJECTS = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 9), - /// Support for Vertex Array Objects (VAOs) + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + + /// Enumerates the categories of capabilities + enum CapabilitiesCategory + { + CAPS_CATEGORY_COMMON = 0, + CAPS_CATEGORY_COMMON_2 = 1, + CAPS_CATEGORY_D3D9 = 2, + CAPS_CATEGORY_GL = 3, + /// Placeholder for max value + CAPS_CATEGORY_COUNT = 4 + }; + + /// Enum describing the different hardware capabilities we want to check for + /// OGRE_CAPS_VALUE(a, b) defines each capability + // a is the category (which can be from 0 to 15) + // b is the value (from 0 to 27) + enum Capabilities + { + /// Supports generating mipmaps in hardware + RSC_AUTOMIPMAP = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 0), + RSC_BLENDING = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 1), + /// Supports anisotropic texture filtering + RSC_ANISOTROPY = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 2), + /// Supports fixed-function DOT3 texture blend + RSC_DOT3 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 3), + /// Supports cube mapping + RSC_CUBEMAPPING = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 4), + /// Supports hardware stencil buffer + RSC_HWSTENCIL = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 5), + /// Supports hardware vertex and index buffers + RSC_VBO = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 7), + /// Supports 32bit hardware index buffers + RSC_32BIT_INDEX = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 8), + /// Supports vertex programs (vertex shaders) + RSC_VERTEX_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 9), + /// Supports fragment programs (pixel shaders) + RSC_FRAGMENT_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 10), + /// Supports performing a scissor test to exclude areas of the screen + RSC_SCISSOR_TEST = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 11), + /// Supports separate stencil updates for both front and back faces + RSC_TWO_SIDED_STENCIL = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 12), + /// Supports wrapping the stencil value at the range extremeties + RSC_STENCIL_WRAP = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 13), + /// Supports hardware occlusion queries + RSC_HWOCCLUSION = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 14), + /// Supports user clipping planes + RSC_USER_CLIP_PLANES = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 15), + /// Supports the VET_UBYTE4 vertex element type + RSC_VERTEX_FORMAT_UBYTE4 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 16), + /// Supports infinite far plane projection + RSC_INFINITE_FAR_PLANE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 17), + /// Supports hardware render-to-texture (bigger than framebuffer) + RSC_HWRENDER_TO_TEXTURE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 18), + /// Supports float textures and render targets + RSC_TEXTURE_FLOAT = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 19), + /// Supports non-power of two textures + RSC_NON_POWER_OF_2_TEXTURES = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 20), + /// Supports 3d (volume) textures + RSC_TEXTURE_3D = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 21), + /// Supports basic point sprite rendering + RSC_POINT_SPRITES = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 22), + /// Supports extra point parameters (minsize, maxsize, attenuation) + RSC_POINT_EXTENDED_PARAMETERS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 23), + /// Supports vertex texture fetch + RSC_VERTEX_TEXTURE_FETCH = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 24), + /// Supports mipmap LOD biasing + RSC_MIPMAP_LOD_BIAS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 25), + /// Supports hardware geometry programs + RSC_GEOMETRY_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 26), + /// Supports rendering to vertex buffers + RSC_HWRENDER_TO_VERTEX_BUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 27), + /// Supports different texture bindings + RSC_COMPLETE_TEXTURE_BINDING = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 28), + + /// Supports compressed textures + RSC_TEXTURE_COMPRESSION = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 0), + /// Supports compressed textures in the DXT/ST3C formats + RSC_TEXTURE_COMPRESSION_DXT = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 1), + /// Supports compressed textures in the VTC format + RSC_TEXTURE_COMPRESSION_VTC = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 2), + /// Supports compressed textures in the PVRTC format + RSC_TEXTURE_COMPRESSION_PVRTC = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 3), + /// Supports compressed textures in the ATC format + RSC_TEXTURE_COMPRESSION_ATC = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 4), + /// Supports compressed textures in the ETC1 format + RSC_TEXTURE_COMPRESSION_ETC1 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 5), + /// Supports compressed textures in the ETC2 format + RSC_TEXTURE_COMPRESSION_ETC2 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 6), + /// Supports compressed textures in BC4 and BC5 format (DirectX feature level 10_0) + RSC_TEXTURE_COMPRESSION_BC4_BC5 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 7), + /// Supports compressed textures in BC6H and BC7 format (DirectX feature level 11_0) + RSC_TEXTURE_COMPRESSION_BC6H_BC7 = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 8), + /// Supports fixed-function pipeline + RSC_FIXED_FUNCTION = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 9), + /// Supports MRTs with different bit depths + RSC_MRT_DIFFERENT_BIT_DEPTHS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 10), + /// Supports Alpha to Coverage (A2C) + RSC_ALPHA_TO_COVERAGE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 11), + /// Supports Blending operations other than + + RSC_ADVANCED_BLEND_OPERATIONS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 12), + /// Supports a separate depth buffer for RTTs. D3D 9 & 10, OGL w/FBO (RSC_FBO implies this flag) + RSC_RTT_SEPARATE_DEPTHBUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 13), + /// Supports using the MAIN depth buffer for RTTs. D3D 9&10, OGL w/FBO support unknown + /// (undefined behavior?), OGL w/ copy supports it + RSC_RTT_MAIN_DEPTHBUFFER_ATTACHABLE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 14), + /// Supports attaching a depth buffer to an RTT that has width & height less or equal than RTT's. + /// Otherwise must be of _exact_ same resolution. D3D 9, OGL 3.0 (not 2.0, not D3D10) + RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 15), + /// Supports using vertex buffers for instance data + RSC_VERTEX_BUFFER_INSTANCE_DATA = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 16), + /// Supports using vertex buffers for instance data + RSC_CAN_GET_COMPILED_SHADER_BUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 17), + /// Supports dynamic linkage/shader subroutine + RSC_SHADER_SUBROUTINE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 18), + + RSC_HWRENDER_TO_TEXTURE_3D = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 19), + /// Supports 1d textures + RSC_TEXTURE_1D = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 20), + /// Supports hardware tessellation hull programs + RSC_TESSELLATION_HULL_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 21), + /// Supports hardware tessellation domain programs + RSC_TESSELLATION_DOMAIN_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 22), + /// Supports hardware compute programs + RSC_COMPUTE_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 23), + /// Supports asynchronous hardware occlusion queries + RSC_HWOCCLUSION_ASYNCHRONOUS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 24), + /// Supports asynchronous hardware occlusion queries + RSC_ATOMIC_COUNTERS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 25), + /// Supports reading back the inactive depth-stencil buffer as texture + RSC_READ_BACK_AS_TEXTURE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 26), + // ***** DirectX specific caps ***** + /// Is DirectX feature "per stage constants" supported + RSC_PERSTAGECONSTANT = OGRE_CAPS_VALUE(CAPS_CATEGORY_D3D9, 0), + + // ***** GL Specific Caps ***** + /// Supports OpenGL version 1.5 + RSC_GL1_5_NOVBO = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 1), + /// Support for Frame Buffer Objects (FBOs) + RSC_FBO = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 2), + /// Support for Frame Buffer Objects ARB implementation (regular FBO is higher precedence) + RSC_FBO_ARB = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 3), + /// Support for Frame Buffer Objects ATI implementation (ARB FBO is higher precedence) + RSC_FBO_ATI = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 4), + /// Support for PBuffer + RSC_PBUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 5), + /// Support for GL 1.5 but without HW occlusion workaround + RSC_GL1_5_NOHWOCCLUSION = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 6), + /// Support for point parameters ARB implementation + RSC_POINT_EXTENDED_PARAMETERS_ARB = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 7), + /// Support for point parameters EXT implementation + RSC_POINT_EXTENDED_PARAMETERS_EXT = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 8), + /// Support for Separate Shader Objects + RSC_SEPARATE_SHADER_OBJECTS = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 9), + /// Support for Vertex Array Objects (VAOs) RSC_VAO = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 10) - }; - - /// DriverVersion is used by RenderSystemCapabilities and both GL and D3D9 - /// to store the version of the current GPU driver - struct _OgreExport DriverVersion - { - int major; - int minor; - int release; - int build; - - DriverVersion() - { - major = minor = release = build = 0; - } - - String toString() const - { - StringStream str; - str << major << "." << minor << "." << release << "." << build; - return str.str(); - } - - void fromString(const String& versionString) - { - StringVector tokens = StringUtil::split(versionString, "."); - if(!tokens.empty()) - { - major = StringConverter::parseInt(tokens[0]); - if (tokens.size() > 1) - minor = StringConverter::parseInt(tokens[1]); - if (tokens.size() > 2) - release = StringConverter::parseInt(tokens[2]); - if (tokens.size() > 3) - build = StringConverter::parseInt(tokens[3]); - } - - } - }; - - /** Enumeration of GPU vendors. */ - enum GPUVendor - { - GPU_UNKNOWN = 0, - GPU_NVIDIA = 1, - GPU_AMD = 2, - GPU_INTEL = 3, - GPU_S3 = 4, - GPU_MATROX = 5, - GPU_3DLABS = 6, - GPU_SIS = 7, + }; + + /// DriverVersion is used by RenderSystemCapabilities and both GL and D3D9 + /// to store the version of the current GPU driver + struct _OgreExport DriverVersion + { + int major; + int minor; + int release; + int build; + + DriverVersion() + { + major = minor = release = build = 0; + } + + String toString() const + { + StringStream str; + str << major << "." << minor << "." << release << "." << build; + return str.str(); + } + + void fromString(const String& versionString) + { + StringVector tokens = StringUtil::split(versionString, "."); + if(!tokens.empty()) + { + major = StringConverter::parseInt(tokens[0]); + if (tokens.size() > 1) + minor = StringConverter::parseInt(tokens[1]); + if (tokens.size() > 2) + release = StringConverter::parseInt(tokens[2]); + if (tokens.size() > 3) + build = StringConverter::parseInt(tokens[3]); + } + + } + }; + + /** Enumeration of GPU vendors. */ + enum GPUVendor + { + GPU_UNKNOWN = 0, + GPU_NVIDIA = 1, + GPU_AMD = 2, + GPU_INTEL = 3, + GPU_S3 = 4, + GPU_MATROX = 5, + GPU_3DLABS = 6, + GPU_SIS = 7, GPU_IMAGINATION_TECHNOLOGIES = 8, GPU_APPLE = 9, // Apple Software Renderer GPU_NOKIA = 10, - GPU_MS_SOFTWARE = 11, // Microsoft software device - GPU_MS_WARP = 12, // Microsoft WARP (Windows Advanced Rasterization Platform) software device - http://msdn.microsoft.com/en-us/library/dd285359.aspx + GPU_MS_SOFTWARE = 11, // Microsoft software device + GPU_MS_WARP = 12, // Microsoft WARP (Windows Advanced Rasterization Platform) software device - http://msdn.microsoft.com/en-us/library/dd285359.aspx GPU_ARM = 13, // For the Mali chipsets GPU_QUALCOMM = 14, - /// placeholder - GPU_VENDOR_COUNT = 15 - }; - - /** singleton class for storing the capabilities of the graphics card. - @remarks - This class stores the capabilities of the graphics card. This - information is set by the individual render systems. - */ - class _OgreExport RenderSystemCapabilities : public RenderSysAlloc - { - - public: - - typedef set::type ShaderProfiles; - private: - /// This is used to build a database of RSC's - /// if a RSC with same name, but newer version is introduced, the older one - /// will be removed - DriverVersion mDriverVersion; - /// GPU Vendor - GPUVendor mVendor; - - static StringVector msGPUVendorStrings; - static void initVendorStrings(); - - /// The number of world matrices available - ushort mNumWorldMatrices; - /// The number of texture units available - ushort mNumTextureUnits; - /// The stencil buffer bit depth - ushort mStencilBufferBitDepth; - /// The number of matrices available for hardware blending - ushort mNumVertexBlendMatrices; - /// Stores the capabilities flags. - int mCapabilities[CAPS_CATEGORY_COUNT]; - /// Which categories are relevant - bool mCategoryRelevant[CAPS_CATEGORY_COUNT]; - /// The name of the device as reported by the render system - String mDeviceName; - /// The identifier associated with the render system for which these capabilities are valid - String mRenderSystemName; - - /// The number of floating-point constants vertex programs support - ushort mVertexProgramConstantFloatCount; - /// The number of integer constants vertex programs support - ushort mVertexProgramConstantIntCount; - /// The number of boolean constants vertex programs support - ushort mVertexProgramConstantBoolCount; - /// The number of floating-point constants geometry programs support - ushort mGeometryProgramConstantFloatCount; - /// The number of integer constants vertex geometry support - ushort mGeometryProgramConstantIntCount; - /// The number of boolean constants vertex geometry support - ushort mGeometryProgramConstantBoolCount; - /// The number of floating-point constants fragment programs support - ushort mFragmentProgramConstantFloatCount; - /// The number of integer constants fragment programs support - ushort mFragmentProgramConstantIntCount; - /// The number of boolean constants fragment programs support - ushort mFragmentProgramConstantBoolCount; - /// The number of simultaneous render targets supported - ushort mNumMultiRenderTargets; - /// The maximum point size - Real mMaxPointSize; - /// Are non-POW2 textures feature-limited? - bool mNonPOW2TexturesLimited; - /// The maximum supported anisotropy - Real mMaxSupportedAnisotropy; - /// The number of vertex texture units supported - ushort mNumVertexTextureUnits; - /// Are vertex texture units shared with fragment processor? - bool mVertexTextureUnitsShared; - /// The number of vertices a geometry program can emit in a single run - int mGeometryProgramNumOutputVertices; - - - /// The list of supported shader profiles - ShaderProfiles mSupportedShaderProfiles; - - // Support for new shader stages in shader model 5.0 - /// The number of floating-point constants tessellation Hull programs support - ushort mTessellationHullProgramConstantFloatCount; - /// The number of integer constants tessellation Hull programs support - ushort mTessellationHullProgramConstantIntCount; - /// The number of boolean constants tessellation Hull programs support - ushort mTessellationHullProgramConstantBoolCount; - /// The number of floating-point constants tessellation Domain programs support - ushort mTessellationDomainProgramConstantFloatCount; - /// The number of integer constants tessellation Domain programs support - ushort mTessellationDomainProgramConstantIntCount; - /// The number of boolean constants tessellation Domain programs support - ushort mTessellationDomainProgramConstantBoolCount; - /// The number of floating-point constants compute programs support - ushort mComputeProgramConstantFloatCount; - /// The number of integer constants compute programs support - ushort mComputeProgramConstantIntCount; - /// The number of boolean constants compute programs support - ushort mComputeProgramConstantBoolCount; - - - - public: - RenderSystemCapabilities (); - virtual ~RenderSystemCapabilities (); - - virtual size_t calculateSize() const {return 0;} - - /** Set the driver version. */ - void setDriverVersion(const DriverVersion& version) - { - mDriverVersion = version; - } - - void parseDriverVersionFromString(const String& versionString) - { - DriverVersion version; - version.fromString(versionString); - setDriverVersion(version); - } - - - DriverVersion getDriverVersion() const - { - return mDriverVersion; - } - - GPUVendor getVendor() const - { - return mVendor; - } - - void setVendor(GPUVendor v) - { - mVendor = v; - } - - /// Parse and set vendor - void parseVendorFromString(const String& vendorString) - { - setVendor(vendorFromString(vendorString)); - } - - /// Convert a vendor string to an enum - static GPUVendor vendorFromString(const String& vendorString); - /// Convert a vendor enum to a string - static String vendorToString(GPUVendor v); - - bool isDriverOlderThanVersion(const DriverVersion &v) const - { - if (mDriverVersion.major < v.major) - return true; - else if (mDriverVersion.major == v.major && - mDriverVersion.minor < v.minor) - return true; - else if (mDriverVersion.major == v.major && - mDriverVersion.minor == v.minor && - mDriverVersion.release < v.release) - return true; - else if (mDriverVersion.major == v.major && - mDriverVersion.minor == v.minor && - mDriverVersion.release == v.release && - mDriverVersion.build < v.build) - return true; - return false; - } - - void setNumWorldMatrices(ushort num) - { - mNumWorldMatrices = num; - } - - void setNumTextureUnits(ushort num) - { - mNumTextureUnits = num; - } - - void setStencilBufferBitDepth(ushort num) - { - mStencilBufferBitDepth = num; - } - - void setNumVertexBlendMatrices(ushort num) - { - mNumVertexBlendMatrices = num; - } - - /// The number of simultaneous render targets supported - void setNumMultiRenderTargets(ushort num) - { - mNumMultiRenderTargets = num; - } - - ushort getNumWorldMatrices(void) const - { - return mNumWorldMatrices; - } - - /** Returns the number of texture units the current output hardware - supports. - - For use in rendering, this determines how many texture units the - are available for multitexturing (i.e. rendering multiple - textures in a single pass). Where a Material has multiple - texture layers, it will try to use multitexturing where - available, and where it is not available, will perform multipass - rendering to achieve the same effect. This property only applies - to the fixed-function pipeline, the number available to the - programmable pipeline depends on the shader model in use. - */ - ushort getNumTextureUnits(void) const - { - return mNumTextureUnits; - } - - /** Determines the bit depth of the hardware accelerated stencil - buffer, if supported. - @remarks - If hardware stencilling is not supported, the software will - provide an 8-bit software stencil. - */ - ushort getStencilBufferBitDepth(void) const - { - return mStencilBufferBitDepth; - } - - /** Returns the number of matrices available to hardware vertex - blending for this rendering system. */ - ushort getNumVertexBlendMatrices(void) const - { - return mNumVertexBlendMatrices; - } - - /// The number of simultaneous render targets supported - ushort getNumMultiRenderTargets(void) const - { - return mNumMultiRenderTargets; - } - - /** Returns true if capability is render system specific - */ - bool isCapabilityRenderSystemSpecific(const Capabilities c) const - { - int cat = c >> OGRE_CAPS_BITSHIFT; - if(cat == CAPS_CATEGORY_GL || cat == CAPS_CATEGORY_D3D9) - return true; - return false; - } - - /** Adds a capability flag - */ - void setCapability(const Capabilities c) - { - int index = (CAPS_CATEGORY_MASK & c) >> OGRE_CAPS_BITSHIFT; - // zero out the index from the stored capability - mCapabilities[index] |= (c & ~CAPS_CATEGORY_MASK); - } - - /** Remove a capability flag - */ - void unsetCapability(const Capabilities c) - { - int index = (CAPS_CATEGORY_MASK & c) >> OGRE_CAPS_BITSHIFT; - // zero out the index from the stored capability - mCapabilities[index] &= (~c | CAPS_CATEGORY_MASK); - } - - /** Checks for a capability - */ - bool hasCapability(const Capabilities c) const - { - int index = (CAPS_CATEGORY_MASK & c) >> OGRE_CAPS_BITSHIFT; - // test against - if(mCapabilities[index] & (c & ~CAPS_CATEGORY_MASK)) - { - return true; - } - else - { - return false; - } - } - - /** Adds the profile to the list of supported profiles - */ - void addShaderProfile(const String& profile) - { - mSupportedShaderProfiles.insert(profile); - - } - - /** Remove a given shader profile, if present. - */ - void removeShaderProfile(const String& profile) - { - mSupportedShaderProfiles.erase(profile); - } - - /** Returns true if profile is in the list of supported profiles - */ - bool isShaderProfileSupported(const String& profile) const - { - return (mSupportedShaderProfiles.end() != mSupportedShaderProfiles.find(profile)); - } - - - /** Returns a set of all supported shader profiles - * */ - const ShaderProfiles& getSupportedShaderProfiles() const - { - return mSupportedShaderProfiles; - } - - - /// The number of floating-point constants vertex programs support - ushort getVertexProgramConstantFloatCount(void) const - { - return mVertexProgramConstantFloatCount; - } - /// The number of integer constants vertex programs support - ushort getVertexProgramConstantIntCount(void) const - { - return mVertexProgramConstantIntCount; - } - /// The number of boolean constants vertex programs support - ushort getVertexProgramConstantBoolCount(void) const - { - return mVertexProgramConstantBoolCount; - } - /// The number of floating-point constants geometry programs support - ushort getGeometryProgramConstantFloatCount(void) const - { - return mGeometryProgramConstantFloatCount; - } - /// The number of integer constants geometry programs support - ushort getGeometryProgramConstantIntCount(void) const - { - return mGeometryProgramConstantIntCount; - } - /// The number of boolean constants geometry programs support - ushort getGeometryProgramConstantBoolCount(void) const - { - return mGeometryProgramConstantBoolCount; - } - /// The number of floating-point constants fragment programs support - ushort getFragmentProgramConstantFloatCount(void) const - { - return mFragmentProgramConstantFloatCount; - } - /// The number of integer constants fragment programs support - ushort getFragmentProgramConstantIntCount(void) const - { - return mFragmentProgramConstantIntCount; - } - /// The number of boolean constants fragment programs support - ushort getFragmentProgramConstantBoolCount(void) const - { - return mFragmentProgramConstantBoolCount; - } - - /// sets the device name for Render system - void setDeviceName(const String& name) - { - mDeviceName = name; - } - - /// gets the device name for render system - String getDeviceName() const - { - return mDeviceName; - } - - /// The number of floating-point constants vertex programs support - void setVertexProgramConstantFloatCount(ushort c) - { - mVertexProgramConstantFloatCount = c; - } - /// The number of integer constants vertex programs support - void setVertexProgramConstantIntCount(ushort c) - { - mVertexProgramConstantIntCount = c; - } - /// The number of boolean constants vertex programs support - void setVertexProgramConstantBoolCount(ushort c) - { - mVertexProgramConstantBoolCount = c; - } - /// The number of floating-point constants geometry programs support - void setGeometryProgramConstantFloatCount(ushort c) - { - mGeometryProgramConstantFloatCount = c; - } - /// The number of integer constants geometry programs support - void setGeometryProgramConstantIntCount(ushort c) - { - mGeometryProgramConstantIntCount = c; - } - /// The number of boolean constants geometry programs support - void setGeometryProgramConstantBoolCount(ushort c) - { - mGeometryProgramConstantBoolCount = c; - } - /// The number of floating-point constants fragment programs support - void setFragmentProgramConstantFloatCount(ushort c) - { - mFragmentProgramConstantFloatCount = c; - } - /// The number of integer constants fragment programs support - void setFragmentProgramConstantIntCount(ushort c) - { - mFragmentProgramConstantIntCount = c; - } - /// The number of boolean constants fragment programs support - void setFragmentProgramConstantBoolCount(ushort c) - { - mFragmentProgramConstantBoolCount = c; - } - /// Maximum point screen size in pixels - void setMaxPointSize(Real s) - { - mMaxPointSize = s; - } - /// Maximum point screen size in pixels - Real getMaxPointSize(void) const - { - return mMaxPointSize; - } - /// Non-POW2 textures limited - void setNonPOW2TexturesLimited(bool l) - { - mNonPOW2TexturesLimited = l; - } - /** Are non-power of two textures limited in features? - @remarks - If the RSC_NON_POWER_OF_2_TEXTURES capability is set, but this - method returns true, you can use non power of 2 textures only if: -
      • You load them explicitly with no mip maps
      • -
      • You don't use DXT texture compression
      • -
      • You use clamp texture addressing
      - */ - bool getNonPOW2TexturesLimited(void) const - { - return mNonPOW2TexturesLimited; - } - /// Set the maximum supported anisotropic filtering - void setMaxSupportedAnisotropy(Real s) - { - mMaxSupportedAnisotropy = s; - } - /// Get the maximum supported anisotropic filtering - Real getMaxSupportedAnisotropy() - { - return mMaxSupportedAnisotropy; - } - - /// Set the number of vertex texture units supported - void setNumVertexTextureUnits(ushort n) - { - mNumVertexTextureUnits = n; - } - /// Get the number of vertex texture units supported - ushort getNumVertexTextureUnits(void) const - { - return mNumVertexTextureUnits; - } - /// Set whether the vertex texture units are shared with the fragment processor - void setVertexTextureUnitsShared(bool shared) - { - mVertexTextureUnitsShared = shared; - } - /// Get whether the vertex texture units are shared with the fragment processor - bool getVertexTextureUnitsShared(void) const - { - return mVertexTextureUnitsShared; - } - - /// Set the number of vertices a single geometry program run can emit - void setGeometryProgramNumOutputVertices(int numOutputVertices) - { - mGeometryProgramNumOutputVertices = numOutputVertices; - } - /// Get the number of vertices a single geometry program run can emit - int getGeometryProgramNumOutputVertices(void) const - { - return mGeometryProgramNumOutputVertices; - } - - /// Get the identifier of the rendersystem from which these capabilities were generated - String getRenderSystemName(void) const - { - return mRenderSystemName; - } - /// Set the identifier of the rendersystem from which these capabilities were generated - void setRenderSystemName(const String& rs) - { - mRenderSystemName = rs; - } - - /// Mark a category as 'relevant' or not, ie will it be reported - void setCategoryRelevant(CapabilitiesCategory cat, bool relevant) - { - mCategoryRelevant[cat] = relevant; - } - - /// Return whether a category is 'relevant' or not, ie will it be reported - bool isCategoryRelevant(CapabilitiesCategory cat) - { - return mCategoryRelevant[cat]; - } - - - - /** Write the capabilities to the pass in Log */ - void log(Log* pLog); - - // Support for new shader stages in shader model 5.0 - /// The number of floating-point constants tessellation Hull programs support - void setTessellationHullProgramConstantFloatCount(ushort c) - { - mTessellationHullProgramConstantFloatCount = c; - } - /// The number of integer constants tessellation Domain programs support - void setTessellationHullProgramConstantIntCount(ushort c) - { - mTessellationHullProgramConstantIntCount = c; - } - /// The number of boolean constants tessellation Domain programs support - void setTessellationHullProgramConstantBoolCount(ushort c) - { - mTessellationHullProgramConstantBoolCount = c; - } - /// The number of floating-point constants fragment programs support - ushort getTessellationHullProgramConstantFloatCount(void) const - { - return mTessellationHullProgramConstantFloatCount; - } - /// The number of integer constants fragment programs support - ushort getTessellationHullProgramConstantIntCount(void) const - { - return mTessellationHullProgramConstantIntCount; - } - /// The number of boolean constants fragment programs support - ushort getTessellationHullProgramConstantBoolCount(void) const - { - return mTessellationHullProgramConstantBoolCount; - } - - /// The number of floating-point constants tessellation Domain programs support - void setTessellationDomainProgramConstantFloatCount(ushort c) - { - mTessellationDomainProgramConstantFloatCount = c; - } - /// The number of integer constants tessellation Domain programs support - void setTessellationDomainProgramConstantIntCount(ushort c) - { - mTessellationDomainProgramConstantIntCount = c; - } - /// The number of boolean constants tessellation Domain programs support - void setTessellationDomainProgramConstantBoolCount(ushort c) - { - mTessellationDomainProgramConstantBoolCount = c; - } - /// The number of floating-point constants fragment programs support - ushort getTessellationDomainProgramConstantFloatCount(void) const - { - return mTessellationDomainProgramConstantFloatCount; - } - /// The number of integer constants fragment programs support - ushort getTessellationDomainProgramConstantIntCount(void) const - { - return mTessellationDomainProgramConstantIntCount; - } - /// The number of boolean constants fragment programs support - ushort getTessellationDomainProgramConstantBoolCount(void) const - { - return mTessellationDomainProgramConstantBoolCount; - } - - /// The number of floating-point constants compute programs support - void setComputeProgramConstantFloatCount(ushort c) - { - mComputeProgramConstantFloatCount = c; - } - /// The number of integer constants compute programs support - void setComputeProgramConstantIntCount(ushort c) - { - mComputeProgramConstantIntCount = c; - } - /// The number of boolean constants compute programs support - void setComputeProgramConstantBoolCount(ushort c) - { - mComputeProgramConstantBoolCount = c; - } - /// The number of floating-point constants fragment programs support - ushort getComputeProgramConstantFloatCount(void) const - { - return mComputeProgramConstantFloatCount; - } - /// The number of integer constants fragment programs support - ushort getComputeProgramConstantIntCount(void) const - { - return mComputeProgramConstantIntCount; - } - /// The number of boolean constants fragment programs support - ushort getComputeProgramConstantBoolCount(void) const - { - return mComputeProgramConstantBoolCount; - } - - }; - - /** @} */ - /** @} */ + /// placeholder + GPU_VENDOR_COUNT = 15 + }; + + /** singleton class for storing the capabilities of the graphics card. + @remarks + This class stores the capabilities of the graphics card. This + information is set by the individual render systems. + */ + class _OgreExport RenderSystemCapabilities : public RenderSysAlloc + { + + public: + + typedef set::type ShaderProfiles; + private: + /// This is used to build a database of RSC's + /// if a RSC with same name, but newer version is introduced, the older one + /// will be removed + DriverVersion mDriverVersion; + /// GPU Vendor + GPUVendor mVendor; + + static StringVector msGPUVendorStrings; + static void initVendorStrings(); + + /// The number of world matrices available + ushort mNumWorldMatrices; + /// The number of texture units available + ushort mNumTextureUnits; + /// The stencil buffer bit depth + ushort mStencilBufferBitDepth; + /// The number of matrices available for hardware blending + ushort mNumVertexBlendMatrices; + /// Stores the capabilities flags. + int mCapabilities[CAPS_CATEGORY_COUNT]; + /// Which categories are relevant + bool mCategoryRelevant[CAPS_CATEGORY_COUNT]; + /// The name of the device as reported by the render system + String mDeviceName; + /// The identifier associated with the render system for which these capabilities are valid + String mRenderSystemName; + + /// The number of floating-point constants vertex programs support + ushort mVertexProgramConstantFloatCount; + /// The number of integer constants vertex programs support + ushort mVertexProgramConstantIntCount; + /// The number of boolean constants vertex programs support + ushort mVertexProgramConstantBoolCount; + /// The number of floating-point constants geometry programs support + ushort mGeometryProgramConstantFloatCount; + /// The number of integer constants vertex geometry support + ushort mGeometryProgramConstantIntCount; + /// The number of boolean constants vertex geometry support + ushort mGeometryProgramConstantBoolCount; + /// The number of floating-point constants fragment programs support + ushort mFragmentProgramConstantFloatCount; + /// The number of integer constants fragment programs support + ushort mFragmentProgramConstantIntCount; + /// The number of boolean constants fragment programs support + ushort mFragmentProgramConstantBoolCount; + /// The number of simultaneous render targets supported + ushort mNumMultiRenderTargets; + /// The maximum point size + Real mMaxPointSize; + /// Are non-POW2 textures feature-limited? + bool mNonPOW2TexturesLimited; + /// The maximum supported anisotropy + Real mMaxSupportedAnisotropy; + /// The number of vertex texture units supported + ushort mNumVertexTextureUnits; + /// Are vertex texture units shared with fragment processor? + bool mVertexTextureUnitsShared; + /// The number of vertices a geometry program can emit in a single run + int mGeometryProgramNumOutputVertices; + + + /// The list of supported shader profiles + ShaderProfiles mSupportedShaderProfiles; + + // Support for new shader stages in shader model 5.0 + /// The number of floating-point constants tessellation Hull programs support + ushort mTessellationHullProgramConstantFloatCount; + /// The number of integer constants tessellation Hull programs support + ushort mTessellationHullProgramConstantIntCount; + /// The number of boolean constants tessellation Hull programs support + ushort mTessellationHullProgramConstantBoolCount; + /// The number of floating-point constants tessellation Domain programs support + ushort mTessellationDomainProgramConstantFloatCount; + /// The number of integer constants tessellation Domain programs support + ushort mTessellationDomainProgramConstantIntCount; + /// The number of boolean constants tessellation Domain programs support + ushort mTessellationDomainProgramConstantBoolCount; + /// The number of floating-point constants compute programs support + ushort mComputeProgramConstantFloatCount; + /// The number of integer constants compute programs support + ushort mComputeProgramConstantIntCount; + /// The number of boolean constants compute programs support + ushort mComputeProgramConstantBoolCount; + + + + public: + RenderSystemCapabilities (); + virtual ~RenderSystemCapabilities (); + + virtual size_t calculateSize() const {return 0;} + + /** Set the driver version. */ + void setDriverVersion(const DriverVersion& version) + { + mDriverVersion = version; + } + + void parseDriverVersionFromString(const String& versionString) + { + DriverVersion version; + version.fromString(versionString); + setDriverVersion(version); + } + + + DriverVersion getDriverVersion() const + { + return mDriverVersion; + } + + GPUVendor getVendor() const + { + return mVendor; + } + + void setVendor(GPUVendor v) + { + mVendor = v; + } + + /// Parse and set vendor + void parseVendorFromString(const String& vendorString) + { + setVendor(vendorFromString(vendorString)); + } + + /// Convert a vendor string to an enum + static GPUVendor vendorFromString(const String& vendorString); + /// Convert a vendor enum to a string + static String vendorToString(GPUVendor v); + + bool isDriverOlderThanVersion(const DriverVersion &v) const + { + if (mDriverVersion.major < v.major) + return true; + else if (mDriverVersion.major == v.major && + mDriverVersion.minor < v.minor) + return true; + else if (mDriverVersion.major == v.major && + mDriverVersion.minor == v.minor && + mDriverVersion.release < v.release) + return true; + else if (mDriverVersion.major == v.major && + mDriverVersion.minor == v.minor && + mDriverVersion.release == v.release && + mDriverVersion.build < v.build) + return true; + return false; + } + + void setNumWorldMatrices(ushort num) + { + mNumWorldMatrices = num; + } + + void setNumTextureUnits(ushort num) + { + mNumTextureUnits = num; + } + + void setStencilBufferBitDepth(ushort num) + { + mStencilBufferBitDepth = num; + } + + void setNumVertexBlendMatrices(ushort num) + { + mNumVertexBlendMatrices = num; + } + + /// The number of simultaneous render targets supported + void setNumMultiRenderTargets(ushort num) + { + mNumMultiRenderTargets = num; + } + + ushort getNumWorldMatrices(void) const + { + return mNumWorldMatrices; + } + + /** Returns the number of texture units the current output hardware + supports. + + For use in rendering, this determines how many texture units the + are available for multitexturing (i.e. rendering multiple + textures in a single pass). Where a Material has multiple + texture layers, it will try to use multitexturing where + available, and where it is not available, will perform multipass + rendering to achieve the same effect. This property only applies + to the fixed-function pipeline, the number available to the + programmable pipeline depends on the shader model in use. + */ + ushort getNumTextureUnits(void) const + { + return mNumTextureUnits; + } + + /** Determines the bit depth of the hardware accelerated stencil + buffer, if supported. + @remarks + If hardware stencilling is not supported, the software will + provide an 8-bit software stencil. + */ + ushort getStencilBufferBitDepth(void) const + { + return mStencilBufferBitDepth; + } + + /** Returns the number of matrices available to hardware vertex + blending for this rendering system. */ + ushort getNumVertexBlendMatrices(void) const + { + return mNumVertexBlendMatrices; + } + + /// The number of simultaneous render targets supported + ushort getNumMultiRenderTargets(void) const + { + return mNumMultiRenderTargets; + } + + /** Returns true if capability is render system specific + */ + bool isCapabilityRenderSystemSpecific(const Capabilities c) const + { + int cat = c >> OGRE_CAPS_BITSHIFT; + if(cat == CAPS_CATEGORY_GL || cat == CAPS_CATEGORY_D3D9) + return true; + return false; + } + + /** Adds a capability flag + */ + void setCapability(const Capabilities c) + { + int index = (CAPS_CATEGORY_MASK & c) >> OGRE_CAPS_BITSHIFT; + // zero out the index from the stored capability + mCapabilities[index] |= (c & ~CAPS_CATEGORY_MASK); + } + + /** Remove a capability flag + */ + void unsetCapability(const Capabilities c) + { + int index = (CAPS_CATEGORY_MASK & c) >> OGRE_CAPS_BITSHIFT; + // zero out the index from the stored capability + mCapabilities[index] &= (~c | CAPS_CATEGORY_MASK); + } + + /** Checks for a capability + */ + bool hasCapability(const Capabilities c) const + { + int index = (CAPS_CATEGORY_MASK & c) >> OGRE_CAPS_BITSHIFT; + // test against + if(mCapabilities[index] & (c & ~CAPS_CATEGORY_MASK)) + { + return true; + } + else + { + return false; + } + } + + /** Adds the profile to the list of supported profiles + */ + void addShaderProfile(const String& profile) + { + mSupportedShaderProfiles.insert(profile); + + } + + /** Remove a given shader profile, if present. + */ + void removeShaderProfile(const String& profile) + { + mSupportedShaderProfiles.erase(profile); + } + + /** Returns true if profile is in the list of supported profiles + */ + bool isShaderProfileSupported(const String& profile) const + { + return (mSupportedShaderProfiles.end() != mSupportedShaderProfiles.find(profile)); + } + + + /** Returns a set of all supported shader profiles + * */ + const ShaderProfiles& getSupportedShaderProfiles() const + { + return mSupportedShaderProfiles; + } + + + /// The number of floating-point constants vertex programs support + ushort getVertexProgramConstantFloatCount(void) const + { + return mVertexProgramConstantFloatCount; + } + /// The number of integer constants vertex programs support + ushort getVertexProgramConstantIntCount(void) const + { + return mVertexProgramConstantIntCount; + } + /// The number of boolean constants vertex programs support + ushort getVertexProgramConstantBoolCount(void) const + { + return mVertexProgramConstantBoolCount; + } + /// The number of floating-point constants geometry programs support + ushort getGeometryProgramConstantFloatCount(void) const + { + return mGeometryProgramConstantFloatCount; + } + /// The number of integer constants geometry programs support + ushort getGeometryProgramConstantIntCount(void) const + { + return mGeometryProgramConstantIntCount; + } + /// The number of boolean constants geometry programs support + ushort getGeometryProgramConstantBoolCount(void) const + { + return mGeometryProgramConstantBoolCount; + } + /// The number of floating-point constants fragment programs support + ushort getFragmentProgramConstantFloatCount(void) const + { + return mFragmentProgramConstantFloatCount; + } + /// The number of integer constants fragment programs support + ushort getFragmentProgramConstantIntCount(void) const + { + return mFragmentProgramConstantIntCount; + } + /// The number of boolean constants fragment programs support + ushort getFragmentProgramConstantBoolCount(void) const + { + return mFragmentProgramConstantBoolCount; + } + + /// sets the device name for Render system + void setDeviceName(const String& name) + { + mDeviceName = name; + } + + /// gets the device name for render system + String getDeviceName() const + { + return mDeviceName; + } + + /// The number of floating-point constants vertex programs support + void setVertexProgramConstantFloatCount(ushort c) + { + mVertexProgramConstantFloatCount = c; + } + /// The number of integer constants vertex programs support + void setVertexProgramConstantIntCount(ushort c) + { + mVertexProgramConstantIntCount = c; + } + /// The number of boolean constants vertex programs support + void setVertexProgramConstantBoolCount(ushort c) + { + mVertexProgramConstantBoolCount = c; + } + /// The number of floating-point constants geometry programs support + void setGeometryProgramConstantFloatCount(ushort c) + { + mGeometryProgramConstantFloatCount = c; + } + /// The number of integer constants geometry programs support + void setGeometryProgramConstantIntCount(ushort c) + { + mGeometryProgramConstantIntCount = c; + } + /// The number of boolean constants geometry programs support + void setGeometryProgramConstantBoolCount(ushort c) + { + mGeometryProgramConstantBoolCount = c; + } + /// The number of floating-point constants fragment programs support + void setFragmentProgramConstantFloatCount(ushort c) + { + mFragmentProgramConstantFloatCount = c; + } + /// The number of integer constants fragment programs support + void setFragmentProgramConstantIntCount(ushort c) + { + mFragmentProgramConstantIntCount = c; + } + /// The number of boolean constants fragment programs support + void setFragmentProgramConstantBoolCount(ushort c) + { + mFragmentProgramConstantBoolCount = c; + } + /// Maximum point screen size in pixels + void setMaxPointSize(Real s) + { + mMaxPointSize = s; + } + /// Maximum point screen size in pixels + Real getMaxPointSize(void) const + { + return mMaxPointSize; + } + /// Non-POW2 textures limited + void setNonPOW2TexturesLimited(bool l) + { + mNonPOW2TexturesLimited = l; + } + /** Are non-power of two textures limited in features? + @remarks + If the RSC_NON_POWER_OF_2_TEXTURES capability is set, but this + method returns true, you can use non power of 2 textures only if: +
      • You load them explicitly with no mip maps
      • +
      • You don't use DXT texture compression
      • +
      • You use clamp texture addressing
      + */ + bool getNonPOW2TexturesLimited(void) const + { + return mNonPOW2TexturesLimited; + } + /// Set the maximum supported anisotropic filtering + void setMaxSupportedAnisotropy(Real s) + { + mMaxSupportedAnisotropy = s; + } + /// Get the maximum supported anisotropic filtering + Real getMaxSupportedAnisotropy() + { + return mMaxSupportedAnisotropy; + } + + /// Set the number of vertex texture units supported + void setNumVertexTextureUnits(ushort n) + { + mNumVertexTextureUnits = n; + } + /// Get the number of vertex texture units supported + ushort getNumVertexTextureUnits(void) const + { + return mNumVertexTextureUnits; + } + /// Set whether the vertex texture units are shared with the fragment processor + void setVertexTextureUnitsShared(bool shared) + { + mVertexTextureUnitsShared = shared; + } + /// Get whether the vertex texture units are shared with the fragment processor + bool getVertexTextureUnitsShared(void) const + { + return mVertexTextureUnitsShared; + } + + /// Set the number of vertices a single geometry program run can emit + void setGeometryProgramNumOutputVertices(int numOutputVertices) + { + mGeometryProgramNumOutputVertices = numOutputVertices; + } + /// Get the number of vertices a single geometry program run can emit + int getGeometryProgramNumOutputVertices(void) const + { + return mGeometryProgramNumOutputVertices; + } + + /// Get the identifier of the rendersystem from which these capabilities were generated + String getRenderSystemName(void) const + { + return mRenderSystemName; + } + /// Set the identifier of the rendersystem from which these capabilities were generated + void setRenderSystemName(const String& rs) + { + mRenderSystemName = rs; + } + + /// Mark a category as 'relevant' or not, ie will it be reported + void setCategoryRelevant(CapabilitiesCategory cat, bool relevant) + { + mCategoryRelevant[cat] = relevant; + } + + /// Return whether a category is 'relevant' or not, ie will it be reported + bool isCategoryRelevant(CapabilitiesCategory cat) + { + return mCategoryRelevant[cat]; + } + + + + /** Write the capabilities to the pass in Log */ + void log(Log* pLog); + + // Support for new shader stages in shader model 5.0 + /// The number of floating-point constants tessellation Hull programs support + void setTessellationHullProgramConstantFloatCount(ushort c) + { + mTessellationHullProgramConstantFloatCount = c; + } + /// The number of integer constants tessellation Domain programs support + void setTessellationHullProgramConstantIntCount(ushort c) + { + mTessellationHullProgramConstantIntCount = c; + } + /// The number of boolean constants tessellation Domain programs support + void setTessellationHullProgramConstantBoolCount(ushort c) + { + mTessellationHullProgramConstantBoolCount = c; + } + /// The number of floating-point constants fragment programs support + ushort getTessellationHullProgramConstantFloatCount(void) const + { + return mTessellationHullProgramConstantFloatCount; + } + /// The number of integer constants fragment programs support + ushort getTessellationHullProgramConstantIntCount(void) const + { + return mTessellationHullProgramConstantIntCount; + } + /// The number of boolean constants fragment programs support + ushort getTessellationHullProgramConstantBoolCount(void) const + { + return mTessellationHullProgramConstantBoolCount; + } + + /// The number of floating-point constants tessellation Domain programs support + void setTessellationDomainProgramConstantFloatCount(ushort c) + { + mTessellationDomainProgramConstantFloatCount = c; + } + /// The number of integer constants tessellation Domain programs support + void setTessellationDomainProgramConstantIntCount(ushort c) + { + mTessellationDomainProgramConstantIntCount = c; + } + /// The number of boolean constants tessellation Domain programs support + void setTessellationDomainProgramConstantBoolCount(ushort c) + { + mTessellationDomainProgramConstantBoolCount = c; + } + /// The number of floating-point constants fragment programs support + ushort getTessellationDomainProgramConstantFloatCount(void) const + { + return mTessellationDomainProgramConstantFloatCount; + } + /// The number of integer constants fragment programs support + ushort getTessellationDomainProgramConstantIntCount(void) const + { + return mTessellationDomainProgramConstantIntCount; + } + /// The number of boolean constants fragment programs support + ushort getTessellationDomainProgramConstantBoolCount(void) const + { + return mTessellationDomainProgramConstantBoolCount; + } + + /// The number of floating-point constants compute programs support + void setComputeProgramConstantFloatCount(ushort c) + { + mComputeProgramConstantFloatCount = c; + } + /// The number of integer constants compute programs support + void setComputeProgramConstantIntCount(ushort c) + { + mComputeProgramConstantIntCount = c; + } + /// The number of boolean constants compute programs support + void setComputeProgramConstantBoolCount(ushort c) + { + mComputeProgramConstantBoolCount = c; + } + /// The number of floating-point constants fragment programs support + ushort getComputeProgramConstantFloatCount(void) const + { + return mComputeProgramConstantFloatCount; + } + /// The number of integer constants fragment programs support + ushort getComputeProgramConstantIntCount(void) const + { + return mComputeProgramConstantIntCount; + } + /// The number of boolean constants fragment programs support + ushort getComputeProgramConstantBoolCount(void) const + { + return mComputeProgramConstantBoolCount; + } + + }; + + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreRenderSystemCapabilitiesManager.h b/OgreMain/include/OgreRenderSystemCapabilitiesManager.h index 5391c5875af..be96f9cbe71 100644 --- a/OgreMain/include/OgreRenderSystemCapabilitiesManager.h +++ b/OgreMain/include/OgreRenderSystemCapabilitiesManager.h @@ -36,15 +36,15 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Class for managing RenderSystemCapabilities database for Ogre. + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Class for managing RenderSystemCapabilities database for Ogre. @remarks This class behaves similarly to other ResourceManager, although .rendercaps are not resources. - It contains and abstract a .rendercaps Serializer + It contains and abstract a .rendercaps Serializer */ class _OgreExport RenderSystemCapabilitiesManager : public Singleton, public RenderSysAlloc { @@ -63,14 +63,14 @@ namespace Ogre { /** @see ScriptLoader::parseScript */ void parseCapabilitiesFromArchive(const String& filename, const String& archiveType, bool recursive = true); - - /** Returns a capability loaded with RenderSystemCapabilitiesManager::parseCapabilitiesFromArchive method - * @return NULL if the name is invalid, a parsed RenderSystemCapabilities otherwise. - */ + + /** Returns a capability loaded with RenderSystemCapabilitiesManager::parseCapabilitiesFromArchive method + * @return NULL if the name is invalid, a parsed RenderSystemCapabilities otherwise. + */ RenderSystemCapabilities* loadParsedCapabilities(const String& name); - /** Access to the internal map of loaded capabilities */ - const map::type &getCapabilities() const; + /** Access to the internal map of loaded capabilities */ + const map::type &getCapabilities() const; /** Method used by RenderSystemCapabilitiesSerializer::parseScript */ void _addRenderSystemCapabilities(const String& name, RenderSystemCapabilities* caps); @@ -119,8 +119,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreRenderSystemCapabilitiesSerializer.h b/OgreMain/include/OgreRenderSystemCapabilitiesSerializer.h index 6750f19dea9..b2928ce3959 100644 --- a/OgreMain/include/OgreRenderSystemCapabilitiesSerializer.h +++ b/OgreMain/include/OgreRenderSystemCapabilitiesSerializer.h @@ -36,14 +36,14 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Class for serializing RenderSystemCapabilities to / from a .rendercaps script.*/ - class _OgreExport RenderSystemCapabilitiesSerializer : public RenderSysAlloc + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Class for serializing RenderSystemCapabilities to / from a .rendercaps script.*/ + class _OgreExport RenderSystemCapabilitiesSerializer : public RenderSysAlloc { public: @@ -54,9 +54,9 @@ namespace Ogre { /** Writes a RenderSystemCapabilities object to a data stream */ void writeScript(const RenderSystemCapabilities* caps, const String &name, String filename); - - /** Writes a RenderSystemCapabilities object to a string */ - String writeString(const RenderSystemCapabilities* caps, const String &name); + + /** Writes a RenderSystemCapabilities object to a string */ + String writeString(const RenderSystemCapabilities* caps, const String &name); /** Parses a RenderSystemCapabilities script file passed as a stream. Adds it to RenderSystemCapabilitiesManager::_addRenderSystemCapabilities @@ -122,14 +122,14 @@ namespace Ogre { inline CapabilityKeywordType getKeywordType(const String& keyword) const { - KeywordTypeMap::const_iterator it = mKeywordTypeMap.find(keyword); + KeywordTypeMap::const_iterator it = mKeywordTypeMap.find(keyword); if(it != mKeywordTypeMap.end()) - return (*it).second; - else - { - logParseError("Can't find the type for keyword: " + keyword); - return UNDEFINED_CAPABILITY_TYPE; - } + return (*it).second; + else + { + logParseError("Can't find the type for keyword: " + keyword); + return UNDEFINED_CAPABILITY_TYPE; + } } inline void addSetStringMethod(String keyword, SetStringMethod method) @@ -142,7 +142,7 @@ namespace Ogre { SetStringMethodDispatchTable::iterator methodIter = mSetStringMethodDispatchTable.find(keyword); if (methodIter != mSetStringMethodDispatchTable.end()) { - SetStringMethod m = (*methodIter).second; + SetStringMethod m = (*methodIter).second; (mCurrentCapabilities->*m)(val); } else @@ -162,7 +162,7 @@ namespace Ogre { SetIntMethodDispatchTable::iterator methodIter = mSetIntMethodDispatchTable.find(keyword); if (methodIter != mSetIntMethodDispatchTable.end()) { - SetIntMethod m = (*methodIter).second; + SetIntMethod m = (*methodIter).second; (mCurrentCapabilities->*m)(val); } else @@ -182,13 +182,13 @@ namespace Ogre { SetBoolMethodDispatchTable::iterator methodIter = mSetBoolMethodDispatchTable.find(keyword); if (methodIter != mSetBoolMethodDispatchTable.end()) { - SetBoolMethod m = (*methodIter).second; + SetBoolMethod m = (*methodIter).second; (mCurrentCapabilities->*m)(val); } else { logParseError("undefined keyword: " + keyword); - } + } } @@ -202,13 +202,13 @@ namespace Ogre { SetRealMethodDispatchTable::iterator methodIter = mSetRealMethodDispatchTable.find(keyword); if (methodIter != mSetRealMethodDispatchTable.end()) { - SetRealMethod m = (*methodIter).second; + SetRealMethod m = (*methodIter).second; (mCurrentCapabilities->*m)(val); } else { logParseError("undefined keyword: " + keyword); - } + } } inline void addShaderProfile(String& val) @@ -239,8 +239,8 @@ namespace Ogre { void logParseError(const String& error) const; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreRenderTarget.h b/OgreMain/include/OgreRenderTarget.h index 253d9c3999a..47d3110ddc1 100644 --- a/OgreMain/include/OgreRenderTarget.h +++ b/OgreMain/include/OgreRenderTarget.h @@ -35,20 +35,20 @@ THE SOFTWARE. /* Define the number of priority groups for the render system's render targets. */ #ifndef OGRE_NUM_RENDERTARGET_GROUPS - #define OGRE_NUM_RENDERTARGET_GROUPS 10 - #define OGRE_DEFAULT_RT_GROUP 4 - #define OGRE_REND_TO_TEX_RT_GROUP 2 + #define OGRE_NUM_RENDERTARGET_GROUPS 10 + #define OGRE_DEFAULT_RT_GROUP 4 + #define OGRE_REND_TO_TEX_RT_GROUP 2 #endif namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** A 'canvas' which can receive the results of a rendering + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** A 'canvas' which can receive the results of a rendering operation. @remarks This abstract class defines a common root to all targets of rendering operations. A @@ -83,15 +83,15 @@ namespace Ogre { unsigned long worstFrameTime; size_t triangleCount; size_t batchCount; - int vBlankMissCount; // -1 means that the value is not applicable + int vBlankMissCount; // -1 means that the value is not applicable }; - enum FrameBuffer - { - FB_FRONT, - FB_BACK, - FB_AUTO - }; + enum FrameBuffer + { + FB_FRONT, + FB_BACK, + FB_AUTO + }; RenderTarget(); virtual ~RenderTarget(); @@ -106,30 +106,30 @@ namespace Ogre { virtual uint32 getHeight(void) const; virtual uint32 getColourDepth(void) const; - /** - * Sets the pool ID this RenderTarget should query from. Default value is POOL_DEFAULT. - * Set to POOL_NO_DEPTH to avoid using a DepthBuffer (or manually controlling it) @see DepthBuffer - * @remarks - * Changing the pool Id will cause the current depth buffer to be detached unless the old - * id and the new one are the same - */ - void setDepthBufferPool( uint16 poolId ); + /** + * Sets the pool ID this RenderTarget should query from. Default value is POOL_DEFAULT. + * Set to POOL_NO_DEPTH to avoid using a DepthBuffer (or manually controlling it) @see DepthBuffer + * @remarks + * Changing the pool Id will cause the current depth buffer to be detached unless the old + * id and the new one are the same + */ + void setDepthBufferPool( uint16 poolId ); - //Returns the pool ID this RenderTarget should query from. @see DepthBuffer - uint16 getDepthBufferPool() const; + //Returns the pool ID this RenderTarget should query from. @see DepthBuffer + uint16 getDepthBufferPool() const; - DepthBuffer* getDepthBuffer() const; + DepthBuffer* getDepthBuffer() const; - //Returns false if couldn't attach - virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); + //Returns false if couldn't attach + virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); - virtual void detachDepthBuffer(); + virtual void detachDepthBuffer(); - /** Detaches DepthBuffer without notifying it from the detach. - Useful when called from the DepthBuffer while it iterates through attached - RenderTargets (@see DepthBuffer::_setPoolId()) - */ - virtual void _detachDepthBuffer(); + /** Detaches DepthBuffer without notifying it from the detach. + Useful when called from the DepthBuffer while it iterates through attached + RenderTargets (@see DepthBuffer::_setPoolId()) + */ + virtual void _detachDepthBuffer(); /** Tells the target to update it's contents. @remarks @@ -143,15 +143,15 @@ namespace Ogre { This allows OGRE to be used in multi-windowed utilities and for contents to be refreshed only when required, rather than constantly as with the automatic rendering loop. - @param swapBuffers For targets that support double-buffering, if set - to true, the target will immediately - swap it's buffers after update. Otherwise, the buffers are - not swapped, and you have to call swapBuffers yourself sometime - later. You might want to do this on some rendersystems which - pause for queued rendering commands to complete before accepting - swap buffers calls - so you could do other CPU tasks whilst the - queued commands complete. Or, you might do this if you want custom - control over your windows, such as for externally created windows. + @param swapBuffers For targets that support double-buffering, if set + to true, the target will immediately + swap it's buffers after update. Otherwise, the buffers are + not swapped, and you have to call swapBuffers yourself sometime + later. You might want to do this on some rendersystems which + pause for queued rendering commands to complete before accepting + swap buffers calls - so you could do other CPU tasks whilst the + queued commands complete. Or, you might do this if you want custom + control over your windows, such as for externally created windows. */ virtual void update(bool swapBuffers = true); /** Swaps the frame buffers to display the next frame. @@ -196,13 +196,13 @@ namespace Ogre { /** Retrieves a pointer to the viewport with the given index. */ virtual Viewport* getViewport(unsigned short index); - /** Retrieves a pointer to the viewport with the given Z-order. - @remarks throws if not found. - */ + /** Retrieves a pointer to the viewport with the given Z-order. + @remarks throws if not found. + */ virtual Viewport* getViewportByZOrder(int ZOrder); - /** Returns true if and only if a viewport exists at the given Z-order. */ - virtual bool hasViewportWithZOrder(int ZOrder); + /** Returns true if and only if a viewport exists at the given Z-order. */ + virtual bool hasViewportWithZOrder(int ZOrder); /** Removes a viewport at a given Z-order. */ @@ -288,7 +288,7 @@ namespace Ogre { /** Removes all listeners from this instance. */ virtual void removeAllListeners(void); - /** Sets the priority of this render target in relation to the others. + /** Sets the priority of this render target in relation to the others. @remarks This can be used in order to schedule render target updates. Lower priorities will be rendered first. Note that the priority must be set @@ -297,7 +297,7 @@ namespace Ogre { */ virtual void setPriority( uchar priority ) { mPriority = priority; } /** Gets the priority of a render target. */ - virtual uchar getPriority() const { return mPriority; } + virtual uchar getPriority() const { return mPriority; } /** Used to retrieve or set the active state of the render target. */ @@ -324,31 +324,31 @@ namespace Ogre { */ virtual bool isAutoUpdated(void) const; - /** Copies the current contents of the render target to a pixelbox. - @remarks See suggestPixelFormat for a tip as to the best pixel format to - extract into, although you can use whatever format you like and the - results will be converted. - */ - virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer = FB_AUTO) = 0; - - /** Suggests a pixel format to use for extracting the data in this target, - when calling copyContentsToMemory. - */ - virtual PixelFormat suggestPixelFormat() const { return PF_BYTE_RGBA; } - + /** Copies the current contents of the render target to a pixelbox. + @remarks See suggestPixelFormat for a tip as to the best pixel format to + extract into, although you can use whatever format you like and the + results will be converted. + */ + virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer = FB_AUTO) = 0; + + /** Suggests a pixel format to use for extracting the data in this target, + when calling copyContentsToMemory. + */ + virtual PixelFormat suggestPixelFormat() const { return PF_BYTE_RGBA; } + /** Writes the current contents of the render target to the named file. */ void writeContentsToFile(const String& filename); - /** Writes the current contents of the render target to the (PREFIX)(time-stamp)(SUFFIX) file. - @return the name of the file used.*/ - virtual String writeContentsToTimestampedFile(const String& filenamePrefix, const String& filenameSuffix); + /** Writes the current contents of the render target to the (PREFIX)(time-stamp)(SUFFIX) file. + @return the name of the file used.*/ + virtual String writeContentsToTimestampedFile(const String& filenamePrefix, const String& filenameSuffix); - virtual bool requiresTextureFlipping() const = 0; + virtual bool requiresTextureFlipping() const = 0; - /** Gets the number of triangles rendered in the last update() call. */ - virtual size_t getTriangleCount(void) const; + /** Gets the number of triangles rendered in the last update() call. */ + virtual size_t getTriangleCount(void) const; /** Gets the number of batches rendered in the last update() call. */ - virtual size_t getBatchCount(void) const; + virtual size_t getBatchCount(void) const; /** Utility method to notify a render target that a camera has been removed, incase it was referring to it as a viewer. */ @@ -362,22 +362,22 @@ namespace Ogre { */ virtual bool isPrimary(void) const; - /** Indicates whether on rendering, linear colour space is converted to - sRGB gamma colour space. This is the exact opposite conversion of - what is indicated by Texture::isHardwareGammaEnabled, and can only - be enabled on creation of the render target. For render windows, it's - enabled through the 'gamma' creation misc parameter. For textures, - it is enabled through the hwGamma parameter to the create call. - */ - virtual bool isHardwareGammaEnabled() const { return mHwGamma; } + /** Indicates whether on rendering, linear colour space is converted to + sRGB gamma colour space. This is the exact opposite conversion of + what is indicated by Texture::isHardwareGammaEnabled, and can only + be enabled on creation of the render target. For render windows, it's + enabled through the 'gamma' creation misc parameter. For textures, + it is enabled through the hwGamma parameter to the create call. + */ + virtual bool isHardwareGammaEnabled() const { return mHwGamma; } - /** Indicates whether multisampling is performed on rendering and at what level. - */ - virtual uint getFSAA() const { return mFSAA; } + /** Indicates whether multisampling is performed on rendering and at what level. + */ + virtual uint getFSAA() const { return mFSAA; } - /** Gets the FSAA hint (@see Root::createRenderWindow) - */ - virtual const String& getFSAAHint() const { return mFSAAHint; } + /** Gets the FSAA hint (@see Root::createRenderWindow) + */ + virtual const String& getFSAAHint() const { return mFSAAHint; } /** RenderSystem specific interface for a RenderTarget; this should be subclassed by RenderSystems. @@ -394,84 +394,84 @@ namespace Ogre { */ virtual Impl *_getImpl(); - /** Method for manual management of rendering : fires 'preRenderTargetUpdate' - and initialises statistics etc. - @remarks -
        -
      • _beginUpdate resets statistics and fires 'preRenderTargetUpdate'.
      • -
      • _updateViewport renders the given viewport (even if it is not autoupdated), - fires preViewportUpdate and postViewportUpdate and manages statistics.
      • -
      • _updateAutoUpdatedViewports renders only viewports that are auto updated, - fires preViewportUpdate and postViewportUpdate and manages statistics.
      • -
      • _endUpdate() ends statistics calculation and fires postRenderTargetUpdate.
      • -
      - you can use it like this for example : -
      -			renderTarget->_beginUpdate();
      -			renderTarget->_updateViewport(1); // which is not auto updated
      -			renderTarget->_updateViewport(2); // which is not auto updated
      -			renderTarget->_updateAutoUpdatedViewports();
      -			renderTarget->_endUpdate();
      -			renderTarget->swapBuffers();
      -		
      - Please note that in that case, the zorder may not work as you expect, - since you are responsible for calling _updateViewport in the correct order. - */ - virtual void _beginUpdate(); - - /** Method for manual management of rendering - renders the given - viewport (even if it is not autoupdated) - @remarks - This also fires preViewportUpdate and postViewportUpdate, and manages statistics. - You should call it between _beginUpdate() and _endUpdate(). - @see _beginUpdate for more details. - @param zorder The zorder of the viewport to update. - @param updateStatistics Whether you want to update statistics or not. - */ - virtual void _updateViewport(int zorder, bool updateStatistics = true); - - /** Method for manual management of rendering - renders the given viewport (even if it is not autoupdated) - @remarks - This also fires preViewportUpdate and postViewportUpdate, and manages statistics - if needed. You should call it between _beginUpdate() and _endUpdate(). - @see _beginUpdate for more details. - @param viewport The viewport you want to update, it must be bound to the rendertarget. - @param updateStatistics Whether you want to update statistics or not. - */ - virtual void _updateViewport(Viewport* viewport, bool updateStatistics = true); - - /** Method for manual management of rendering - renders only viewports that are auto updated - @remarks - This also fires preViewportUpdate and postViewportUpdate, and manages statistics. - You should call it between _beginUpdate() and _endUpdate(). - See _beginUpdate for more details. - @param updateStatistics Whether you want to update statistics or not. - @see _beginUpdate() - */ - virtual void _updateAutoUpdatedViewports(bool updateStatistics = true); - - /** Method for manual management of rendering - finishes statistics calculation - and fires 'postRenderTargetUpdate'. - @remarks - You should call it after a _beginUpdate - @see _beginUpdate for more details. - */ - virtual void _endUpdate(); + /** Method for manual management of rendering : fires 'preRenderTargetUpdate' + and initialises statistics etc. + @remarks +
        +
      • _beginUpdate resets statistics and fires 'preRenderTargetUpdate'.
      • +
      • _updateViewport renders the given viewport (even if it is not autoupdated), + fires preViewportUpdate and postViewportUpdate and manages statistics.
      • +
      • _updateAutoUpdatedViewports renders only viewports that are auto updated, + fires preViewportUpdate and postViewportUpdate and manages statistics.
      • +
      • _endUpdate() ends statistics calculation and fires postRenderTargetUpdate.
      • +
      + you can use it like this for example : +
      +            renderTarget->_beginUpdate();
      +            renderTarget->_updateViewport(1); // which is not auto updated
      +            renderTarget->_updateViewport(2); // which is not auto updated
      +            renderTarget->_updateAutoUpdatedViewports();
      +            renderTarget->_endUpdate();
      +            renderTarget->swapBuffers();
      +        
      + Please note that in that case, the zorder may not work as you expect, + since you are responsible for calling _updateViewport in the correct order. + */ + virtual void _beginUpdate(); + + /** Method for manual management of rendering - renders the given + viewport (even if it is not autoupdated) + @remarks + This also fires preViewportUpdate and postViewportUpdate, and manages statistics. + You should call it between _beginUpdate() and _endUpdate(). + @see _beginUpdate for more details. + @param zorder The zorder of the viewport to update. + @param updateStatistics Whether you want to update statistics or not. + */ + virtual void _updateViewport(int zorder, bool updateStatistics = true); + + /** Method for manual management of rendering - renders the given viewport (even if it is not autoupdated) + @remarks + This also fires preViewportUpdate and postViewportUpdate, and manages statistics + if needed. You should call it between _beginUpdate() and _endUpdate(). + @see _beginUpdate for more details. + @param viewport The viewport you want to update, it must be bound to the rendertarget. + @param updateStatistics Whether you want to update statistics or not. + */ + virtual void _updateViewport(Viewport* viewport, bool updateStatistics = true); + + /** Method for manual management of rendering - renders only viewports that are auto updated + @remarks + This also fires preViewportUpdate and postViewportUpdate, and manages statistics. + You should call it between _beginUpdate() and _endUpdate(). + See _beginUpdate for more details. + @param updateStatistics Whether you want to update statistics or not. + @see _beginUpdate() + */ + virtual void _updateAutoUpdatedViewports(bool updateStatistics = true); + + /** Method for manual management of rendering - finishes statistics calculation + and fires 'postRenderTargetUpdate'. + @remarks + You should call it after a _beginUpdate + @see _beginUpdate for more details. + */ + virtual void _endUpdate(); protected: /// The name of this target. String mName; - /// The priority of the render target. - uchar mPriority; + /// The priority of the render target. + uchar mPriority; uint32 mWidth; uint32 mHeight; uint32 mColourDepth; - uint16 mDepthBufferPoolId; - DepthBuffer *mDepthBuffer; + uint16 mDepthBufferPoolId; + DepthBuffer *mDepthBuffer; // Stats - FrameStats mStats; + FrameStats mStats; Timer* mTimer ; unsigned long mLastSecond; @@ -480,21 +480,21 @@ namespace Ogre { bool mActive; bool mAutoUpdate; - // Hardware sRGB gamma conversion done on write? - bool mHwGamma; - // FSAA performed? - uint mFSAA; - String mFSAAHint; + // Hardware sRGB gamma conversion done on write? + bool mHwGamma; + // FSAA performed? + uint mFSAA; + String mFSAAHint; virtual void updateStats(void); - typedef map::type ViewportList; + typedef map::type ViewportList; /// List of viewports, map on Z-order ViewportList mViewportList; typedef vector::type RenderTargetListenerList; RenderTargetListenerList mListeners; - + /// internal method for firing events virtual void firePreUpdate(void); @@ -504,16 +504,16 @@ namespace Ogre { virtual void fireViewportPreUpdate(Viewport* vp); /// internal method for firing events virtual void fireViewportPostUpdate(Viewport* vp); - /// internal method for firing events - virtual void fireViewportAdded(Viewport* vp); - /// internal method for firing events - virtual void fireViewportRemoved(Viewport* vp); - - /// Internal implementation of update() - virtual void updateImpl(); + /// internal method for firing events + virtual void fireViewportAdded(Viewport* vp); + /// internal method for firing events + virtual void fireViewportRemoved(Viewport* vp); + + /// Internal implementation of update() + virtual void updateImpl(); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // Namespace diff --git a/OgreMain/include/OgreRenderTargetListener.h b/OgreMain/include/OgreRenderTargetListener.h index 02fafe9652c..e98a3e8c7fc 100644 --- a/OgreMain/include/OgreRenderTargetListener.h +++ b/OgreMain/include/OgreRenderTargetListener.h @@ -33,13 +33,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Struct containing information about a RenderTarget event. + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Struct containing information about a RenderTarget event. */ struct RenderTargetEvent { @@ -85,7 +85,7 @@ namespace Ogre { the 'Adapter' classes in Java rather than pure interfaces. */ public: - virtual ~RenderTargetListener() {} + virtual ~RenderTargetListener() {} /** Called just before a RenderTarget is about to be rendered into. @remarks This event is raised just before any of the viewports on the target @@ -128,19 +128,19 @@ namespace Ogre { virtual void postViewportUpdate(const RenderTargetViewportEvent& evt) { (void)evt; } - /** Called to notify listener that a Viewport has been added to the - target in question. - */ - virtual void viewportAdded(const RenderTargetViewportEvent& evt) + /** Called to notify listener that a Viewport has been added to the + target in question. + */ + virtual void viewportAdded(const RenderTargetViewportEvent& evt) { (void)evt; } - /** Called to notify listener that a Viewport has been removed from the - target in question. - */ - virtual void viewportRemoved(const RenderTargetViewportEvent& evt) + /** Called to notify listener that a Viewport has been removed from the + target in question. + */ + virtual void viewportRemoved(const RenderTargetViewportEvent& evt) { (void)evt; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreRenderTexture.h b/OgreMain/include/OgreRenderTexture.h index 491d92c97bb..a4b58153dd8 100644 --- a/OgreMain/include/OgreRenderTexture.h +++ b/OgreMain/include/OgreRenderTexture.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** This class represents a RenderTarget that renders to a Texture. There is no 1 on 1 + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** This class represents a RenderTarget that renders to a Texture. There is no 1 on 1 relation between Textures and RenderTextures, as there can be multiple RenderTargets rendering to different mipmaps, faces (for cubemaps) or slices (for 3D textures) of the same Texture. @@ -51,90 +51,90 @@ namespace Ogre RenderTexture(HardwarePixelBuffer *buffer, uint32 zoffset); virtual ~RenderTexture(); - virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); - PixelFormat suggestPixelFormat() const; + virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); + PixelFormat suggestPixelFormat() const; - protected: - HardwarePixelBuffer *mBuffer; - uint32 mZOffset; + protected: + HardwarePixelBuffer *mBuffer; + uint32 mZOffset; }; - /** This class represents a render target that renders to multiple RenderTextures - at once. Surfaces can be bound and unbound at will, as long as the following constraints - are met: - - All bound surfaces have the same size - - All bound surfaces have the same bit depth - - Target 0 is bound - */ - class _OgreExport MultiRenderTarget: public RenderTarget - { - public: - MultiRenderTarget(const String &name); - - /** Bind a surface to a certain attachment point. - @param attachment 0 .. mCapabilities->getNumMultiRenderTargets()-1 - @param target RenderTexture to bind. - - It does not bind the surface and fails with an exception (ERR_INVALIDPARAMS) if: - - Not all bound surfaces have the same size - - Not all bound surfaces have the same internal format - */ - - virtual void bindSurface(size_t attachment, RenderTexture *target) - { - for (size_t i = mBoundSurfaces.size(); i <= attachment; ++i) - { - mBoundSurfaces.push_back(0); - } - mBoundSurfaces[attachment] = target; - - bindSurfaceImpl(attachment, target); - } - - - - /** Unbind attachment. - */ - - virtual void unbindSurface(size_t attachment) - { - if (attachment < mBoundSurfaces.size()) - mBoundSurfaces[attachment] = 0; - unbindSurfaceImpl(attachment); - } - - /** Error throwing implementation, it's not possible to write a MultiRenderTarget - to disk. - */ - virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); - - /// Irrelevant implementation since cannot copy - PixelFormat suggestPixelFormat() const { return PF_UNKNOWN; } - - typedef vector::type BoundSufaceList; - /// Get a list of the surfaces which have been bound - const BoundSufaceList& getBoundSurfaceList() const { return mBoundSurfaces; } - - /** Get a pointer to a bound surface */ - RenderTexture* getBoundSurface(size_t index) - { - assert (index < mBoundSurfaces.size()); - return mBoundSurfaces[index]; - } - - - protected: - BoundSufaceList mBoundSurfaces; - - /// Implementation of bindSurface, must be provided - virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target) = 0; - /// Implementation of unbindSurface, must be provided - virtual void unbindSurfaceImpl(size_t attachment) = 0; - - - }; - /** @} */ - /** @} */ + /** This class represents a render target that renders to multiple RenderTextures + at once. Surfaces can be bound and unbound at will, as long as the following constraints + are met: + - All bound surfaces have the same size + - All bound surfaces have the same bit depth + - Target 0 is bound + */ + class _OgreExport MultiRenderTarget: public RenderTarget + { + public: + MultiRenderTarget(const String &name); + + /** Bind a surface to a certain attachment point. + @param attachment 0 .. mCapabilities->getNumMultiRenderTargets()-1 + @param target RenderTexture to bind. + + It does not bind the surface and fails with an exception (ERR_INVALIDPARAMS) if: + - Not all bound surfaces have the same size + - Not all bound surfaces have the same internal format + */ + + virtual void bindSurface(size_t attachment, RenderTexture *target) + { + for (size_t i = mBoundSurfaces.size(); i <= attachment; ++i) + { + mBoundSurfaces.push_back(0); + } + mBoundSurfaces[attachment] = target; + + bindSurfaceImpl(attachment, target); + } + + + + /** Unbind attachment. + */ + + virtual void unbindSurface(size_t attachment) + { + if (attachment < mBoundSurfaces.size()) + mBoundSurfaces[attachment] = 0; + unbindSurfaceImpl(attachment); + } + + /** Error throwing implementation, it's not possible to write a MultiRenderTarget + to disk. + */ + virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); + + /// Irrelevant implementation since cannot copy + PixelFormat suggestPixelFormat() const { return PF_UNKNOWN; } + + typedef vector::type BoundSufaceList; + /// Get a list of the surfaces which have been bound + const BoundSufaceList& getBoundSurfaceList() const { return mBoundSurfaces; } + + /** Get a pointer to a bound surface */ + RenderTexture* getBoundSurface(size_t index) + { + assert (index < mBoundSurfaces.size()); + return mBoundSurfaces[index]; + } + + + protected: + BoundSufaceList mBoundSurfaces; + + /// Implementation of bindSurface, must be provided + virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target) = 0; + /// Implementation of unbindSurface, must be provided + virtual void unbindSurfaceImpl(size_t attachment) = 0; + + + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreRenderWindow.h b/OgreMain/include/OgreRenderWindow.h index ec667487053..a37ed855ec6 100644 --- a/OgreMain/include/OgreRenderWindow.h +++ b/OgreMain/include/OgreRenderWindow.h @@ -32,13 +32,13 @@ THE SOFTWARE namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** Manages the target rendering window. + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** Manages the target rendering window. @remarks This class handles a window into which the contents of a scene are rendered. There is a many-to-1 relationship @@ -79,17 +79,17 @@ namespace Ogre miscParams A variable number of pointers to platform-specific arguments. The actual requirements must be defined by the implementing subclasses. */ - virtual void create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) = 0; - - /** Alter fullscreen mode options. - @note Nothing will happen unless the settings here are different from the - current settings. - @param fullScreen Whether to use fullscreen mode or not. - @param width The new width to use - @param height The new height to use - */ - virtual void setFullscreen(bool fullScreen, unsigned int width, unsigned int height) + virtual void create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams) = 0; + + /** Alter fullscreen mode options. + @note Nothing will happen unless the settings here are different from the + current settings. + @param fullScreen Whether to use fullscreen mode or not. + @param width The new width to use + @param height The new height to use + */ + virtual void setFullscreen(bool fullScreen, unsigned int width, unsigned int height) { (void)fullScreen; (void)width; (void)height; } /** Destroys the window. @@ -119,40 +119,40 @@ namespace Ogre virtual void setVisible(bool visible) { (void)visible; } - /** Indicates whether the window was set to hidden (not displayed) - */ - virtual bool isHidden(void) const { return false; } - - /** Hide (or show) the window. If called with hidden=true, this - will make the window completely invisible to the user. - @remarks - Setting a window to hidden is useful to create a dummy primary - RenderWindow hidden from the user so that you can create and - recreate your actual RenderWindows without having to recreate - all your resources. - */ - virtual void setHidden(bool hidden) - { (void)hidden; } - - /** Enable or disable vertical sync for the RenderWindow. - */ - virtual void setVSyncEnabled(bool vsync) - { (void)vsync; } - - /** Indicates whether vertical sync is activated for the window. - */ - virtual bool isVSyncEnabled() const { return false; } - - /** Set the vertical sync interval. This indicates the number of vertical retraces to wait for - before swapping buffers. A value of 1 is the default. - */ - virtual void setVSyncInterval(unsigned int interval) - { (void)interval; } - - /** Returns the vertical sync interval. - */ - virtual unsigned int getVSyncInterval() const { return 1; } - + /** Indicates whether the window was set to hidden (not displayed) + */ + virtual bool isHidden(void) const { return false; } + + /** Hide (or show) the window. If called with hidden=true, this + will make the window completely invisible to the user. + @remarks + Setting a window to hidden is useful to create a dummy primary + RenderWindow hidden from the user so that you can create and + recreate your actual RenderWindows without having to recreate + all your resources. + */ + virtual void setHidden(bool hidden) + { (void)hidden; } + + /** Enable or disable vertical sync for the RenderWindow. + */ + virtual void setVSyncEnabled(bool vsync) + { (void)vsync; } + + /** Indicates whether vertical sync is activated for the window. + */ + virtual bool isVSyncEnabled() const { return false; } + + /** Set the vertical sync interval. This indicates the number of vertical retraces to wait for + before swapping buffers. A value of 1 is the default. + */ + virtual void setVSyncInterval(unsigned int interval) + { (void)interval; } + + /** Returns the vertical sync interval. + */ + virtual unsigned int getVSyncInterval() const { return 1; } + /** Overridden from RenderTarget, flags invisible windows as inactive */ @@ -163,10 +163,10 @@ namespace Ogre virtual bool isClosed(void) const = 0; /** Indicates whether the window is the primary window. The - primary window is special in that it is destroyed when - ogre is shut down, and cannot be destroyed directly. - This is the case because it holds the context for vertex, - index buffers and textures. + primary window is special in that it is destroyed when + ogre is shut down, and cannot be destroyed directly. + This is the case because it holds the context for vertex, + index buffers and textures. */ virtual bool isPrimary(void) const; @@ -178,10 +178,10 @@ namespace Ogre specific to windowing systems. */ virtual void getMetrics(unsigned int& width, unsigned int& height, unsigned int& colourDepth, - int& left, int& top) const; + int& left, int& top) const; - /// Override since windows don't usually have alpha - PixelFormat suggestPixelFormat() const { return PF_BYTE_RGB; } + /// Override since windows don't usually have alpha + PixelFormat suggestPixelFormat() const { return PF_BYTE_RGB; } /** Returns true if the window will automatically de-activate itself when it loses focus. */ @@ -207,8 +207,8 @@ namespace Ogre friend class Root; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // Namespace #endif diff --git a/OgreMain/include/OgreRenderable.h b/OgreMain/include/OgreRenderable.h index 99f0539d5de..d6ac2759ccb 100644 --- a/OgreMain/include/OgreRenderable.h +++ b/OgreMain/include/OgreRenderable.h @@ -352,7 +352,7 @@ namespace Ogre { You can use it to associate one or more custom objects with this class instance. @see UserObjectBindings::setUserAny. */ - UserObjectBindings& getUserObjectBindings() { return mUserObjectBindings; } + UserObjectBindings& getUserObjectBindings() { return mUserObjectBindings; } /** Return an instance of user objects binding associated with this class. You can use it to associate one or more custom objects with this class instance. diff --git a/OgreMain/include/OgreResource.h b/OgreMain/include/OgreResource.h index dee5c03ccb4..bb3ebe6aa05 100644 --- a/OgreMain/include/OgreResource.h +++ b/OgreMain/include/OgreResource.h @@ -39,91 +39,91 @@ namespace Ogre { typedef unsigned long long int ResourceHandle; - // Forward declaration - class ManualResourceLoader; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Abstract class representing a loadable resource (e.g. textures, sounds etc) + // Forward declaration + class ManualResourceLoader; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Abstract class representing a loadable resource (e.g. textures, sounds etc) @remarks Resources are data objects that must be loaded and managed throughout - an application. A resource might be a mesh, a texture, or any other - piece of data - the key thing is that they must be identified by - a name which is unique, must be loaded only once, - must be managed efficiently in terms of retrieval, and they may - also be unloadable to free memory up when they have not been used for - a while and the memory budget is under stress. - @par - All Resource instances must be a member of a resource group; see - ResourceGroupManager for full details. + an application. A resource might be a mesh, a texture, or any other + piece of data - the key thing is that they must be identified by + a name which is unique, must be loaded only once, + must be managed efficiently in terms of retrieval, and they may + also be unloadable to free memory up when they have not been used for + a while and the memory budget is under stress. + @par + All Resource instances must be a member of a resource group; see + ResourceGroupManager for full details. @par Subclasses must implement: -
        -
      1. A constructor, overriding the same parameters as the constructor - defined by this class. Subclasses are not allowed to define - constructors with other parameters; other settings must be - settable through accessor methods before loading.
      2. +
          +
        1. A constructor, overriding the same parameters as the constructor + defined by this class. Subclasses are not allowed to define + constructors with other parameters; other settings must be + settable through accessor methods before loading.
        2. The loadImpl() and unloadImpl() methods - mSize must be set - after loadImpl()
        3. -
        4. StringInterface ParamCommand and ParamDictionary setups - in order to allow setting of core parameters (prior to load) - through a generic interface.
        5. -
        + after loadImpl() +
      3. StringInterface ParamCommand and ParamDictionary setups + in order to allow setting of core parameters (prior to load) + through a generic interface.
      4. +
      */ - class _OgreExport Resource : public StringInterface, public ResourceAlloc + class _OgreExport Resource : public StringInterface, public ResourceAlloc { - public: + public: OGRE_AUTO_MUTEX; // public to allow external locking - class Listener - { - public: - Listener() {} - virtual ~Listener() {} - - /** Callback to indicate that background loading has completed. - @deprecated - Use loadingComplete instead. - */ - OGRE_DEPRECATED virtual void backgroundLoadingComplete(Resource*) {} - - /** Callback to indicate that background preparing has completed. - @deprecated - Use preparingComplete instead. - */ - OGRE_DEPRECATED virtual void backgroundPreparingComplete(Resource*) {} - - /** Called whenever the resource finishes loading. - @remarks - If a Resource has been marked as background loaded (@see Resource::setBackgroundLoaded), - the call does not itself occur in the thread which is doing the loading; - when loading is complete a response indicator is placed with the - ResourceGroupManager, which will then be sent back to the - listener as part of the application's primary frame loop thread. - */ - virtual void loadingComplete(Resource*) {} - - - /** Called whenever the resource finishes preparing (paging into memory). - @remarks - If a Resource has been marked as background loaded (@see Resource::setBackgroundLoaded) - the call does not itself occur in the thread which is doing the preparing; - when preparing is complete a response indicator is placed with the - ResourceGroupManager, which will then be sent back to the - listener as part of the application's primary frame loop thread. - */ - virtual void preparingComplete(Resource*) {} - - /** Called whenever the resource has been unloaded. */ - virtual void unloadingComplete(Resource*) {} - }; - - /// Enum identifying the loading state of the resource - enum LoadingState - { + class Listener + { + public: + Listener() {} + virtual ~Listener() {} + + /** Callback to indicate that background loading has completed. + @deprecated + Use loadingComplete instead. + */ + OGRE_DEPRECATED virtual void backgroundLoadingComplete(Resource*) {} + + /** Callback to indicate that background preparing has completed. + @deprecated + Use preparingComplete instead. + */ + OGRE_DEPRECATED virtual void backgroundPreparingComplete(Resource*) {} + + /** Called whenever the resource finishes loading. + @remarks + If a Resource has been marked as background loaded (@see Resource::setBackgroundLoaded), + the call does not itself occur in the thread which is doing the loading; + when loading is complete a response indicator is placed with the + ResourceGroupManager, which will then be sent back to the + listener as part of the application's primary frame loop thread. + */ + virtual void loadingComplete(Resource*) {} + + + /** Called whenever the resource finishes preparing (paging into memory). + @remarks + If a Resource has been marked as background loaded (@see Resource::setBackgroundLoaded) + the call does not itself occur in the thread which is doing the preparing; + when preparing is complete a response indicator is placed with the + ResourceGroupManager, which will then be sent back to the + listener as part of the application's primary frame loop thread. + */ + virtual void preparingComplete(Resource*) {} + + /** Called whenever the resource has been unloaded. */ + virtual void unloadingComplete(Resource*) {} + }; + + /// Enum identifying the loading state of the resource + enum LoadingState + { /// Not loaded LOADSTATE_UNLOADED, /// Loading is in progress @@ -136,67 +136,67 @@ namespace Ogre { LOADSTATE_PREPARED, /// Preparing is in progress LOADSTATE_PREPARING - }; + }; protected: - /// Creator - ResourceManager* mCreator; - /// Unique name of the resource + /// Creator + ResourceManager* mCreator; + /// Unique name of the resource String mName; - /// The name of the resource group - String mGroup; - /// Numeric handle for more efficient look up than name + /// The name of the resource group + String mGroup; + /// Numeric handle for more efficient look up than name ResourceHandle mHandle; - /// Is the resource currently loaded? + /// Is the resource currently loaded? AtomicScalar mLoadingState; - /// Is this resource going to be background loaded? Only applicable for multithreaded - volatile bool mIsBackgroundLoaded; - /// The size of the resource in bytes + /// Is this resource going to be background loaded? Only applicable for multithreaded + volatile bool mIsBackgroundLoaded; + /// The size of the resource in bytes size_t mSize; - /// Is this file manually loaded? - bool mIsManual; - /// Origin of this resource (e.g. script name) - optional - String mOrigin; - /// Optional manual loader; if provided, data is loaded from here instead of a file - ManualResourceLoader* mLoader; - /// State count, the number of times this resource has changed state - size_t mStateCount; - - typedef set::type ListenerList; - ListenerList mListenerList; - OGRE_MUTEX(mListenerListMutex); - - /** Protected unnamed constructor to prevent default construction. - */ - Resource() - : mCreator(0), mHandle(0), mLoadingState(LOADSTATE_UNLOADED), - mIsBackgroundLoaded(false), mSize(0), mIsManual(0), mLoader(0), mStateCount(0) - { - } - - /** Internal hook to perform actions before the load process, but - after the resource has been marked as 'loading'. - @note Mutex will have already been acquired by the loading thread. - Also, this call will occur even when using a ManualResourceLoader - (when loadImpl is not actually called) - */ - virtual void preLoadImpl(void) {} - /** Internal hook to perform actions after the load process, but - before the resource has been marked as fully loaded. - @note Mutex will have already been acquired by the loading thread. - Also, this call will occur even when using a ManualResourceLoader - (when loadImpl is not actually called) - */ - virtual void postLoadImpl(void) {} - - /** Internal hook to perform actions before the unload process. - @note Mutex will have already been acquired by the unloading thread. - */ - virtual void preUnloadImpl(void) {} - /** Internal hook to perform actions after the unload process, but - before the resource has been marked as fully unloaded. - @note Mutex will have already been acquired by the unloading thread. - */ - virtual void postUnloadImpl(void) {} + /// Is this file manually loaded? + bool mIsManual; + /// Origin of this resource (e.g. script name) - optional + String mOrigin; + /// Optional manual loader; if provided, data is loaded from here instead of a file + ManualResourceLoader* mLoader; + /// State count, the number of times this resource has changed state + size_t mStateCount; + + typedef set::type ListenerList; + ListenerList mListenerList; + OGRE_MUTEX(mListenerListMutex); + + /** Protected unnamed constructor to prevent default construction. + */ + Resource() + : mCreator(0), mHandle(0), mLoadingState(LOADSTATE_UNLOADED), + mIsBackgroundLoaded(false), mSize(0), mIsManual(0), mLoader(0), mStateCount(0) + { + } + + /** Internal hook to perform actions before the load process, but + after the resource has been marked as 'loading'. + @note Mutex will have already been acquired by the loading thread. + Also, this call will occur even when using a ManualResourceLoader + (when loadImpl is not actually called) + */ + virtual void preLoadImpl(void) {} + /** Internal hook to perform actions after the load process, but + before the resource has been marked as fully loaded. + @note Mutex will have already been acquired by the loading thread. + Also, this call will occur even when using a ManualResourceLoader + (when loadImpl is not actually called) + */ + virtual void postLoadImpl(void) {} + + /** Internal hook to perform actions before the unload process. + @note Mutex will have already been acquired by the unloading thread. + */ + virtual void preUnloadImpl(void) {} + /** Internal hook to perform actions after the unload process, but + before the resource has been marked as fully unloaded. + @note Mutex will have already been acquired by the unloading thread. + */ + virtual void postUnloadImpl(void) {} /** Internal implementation of the meat of the 'prepare' action. */ @@ -206,32 +206,32 @@ namespace Ogre { are prepared but not yet loaded. */ virtual void unprepareImpl(void) {} - /** Internal implementation of the meat of the 'load' action, only called if this - resource is not being loaded from a ManualResourceLoader. - */ - virtual void loadImpl(void) = 0; - /** Internal implementation of the 'unload' action; called regardless of - whether this resource is being loaded from a ManualResourceLoader. - */ - virtual void unloadImpl(void) = 0; + /** Internal implementation of the meat of the 'load' action, only called if this + resource is not being loaded from a ManualResourceLoader. + */ + virtual void loadImpl(void) = 0; + /** Internal implementation of the 'unload' action; called regardless of + whether this resource is being loaded from a ManualResourceLoader. + */ + virtual void unloadImpl(void) = 0; public: - /** Standard constructor. - @param creator Pointer to the ResourceManager that is creating this resource - @param name The unique name of the resource - @param group The name of the resource group to which this resource belongs - @param isManual Is this resource manually loaded? If so, you should really - populate the loader parameter in order that the load process - can call the loader back when loading is required. - @param loader Pointer to a ManualResourceLoader implementation which will be called - when the Resource wishes to load (should be supplied if you set - isManual to true). You can in fact leave this parameter null - if you wish, but the Resource will never be able to reload if - anything ever causes it to unload. Therefore provision of a proper - ManualResourceLoader instance is strongly recommended. - */ - Resource(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual = false, ManualResourceLoader* loader = 0); + /** Standard constructor. + @param creator Pointer to the ResourceManager that is creating this resource + @param name The unique name of the resource + @param group The name of the resource group to which this resource belongs + @param isManual Is this resource manually loaded? If so, you should really + populate the loader parameter in order that the load process + can call the loader back when loading is required. + @param loader Pointer to a ManualResourceLoader implementation which will be called + when the Resource wishes to load (should be supplied if you set + isManual to true). You can in fact leave this parameter null + if you wish, but the Resource will never be able to reload if + anything ever causes it to unload. Therefore provision of a proper + ManualResourceLoader instance is strongly recommended. + */ + Resource(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual = false, ManualResourceLoader* loader = 0); /** Virtual destructor. Shouldn't need to be overloaded, as the resource deallocation code should reside in unload() @@ -252,28 +252,28 @@ namespace Ogre { loading a resource between load() and prepare(). It is best to try and do as much work in prepare(), however, since this will leave less work for the main render thread to do and thus increase FPS. - @param backgroundThread Whether this is occurring in a background thread + @param backgroundThread Whether this is occurring in a background thread */ virtual void prepare(bool backgroundThread = false); /** Loads the resource, if it is not already. - @remarks - If the resource is loaded from a file, loading is automatic. If not, - if for example this resource gained it's data from procedural calls - rather than loading from a file, then this resource will not reload - on it's own. - @param backgroundThread Indicates whether the caller of this method is - the background resource loading thread. - + @remarks + If the resource is loaded from a file, loading is automatic. If not, + if for example this resource gained it's data from procedural calls + rather than loading from a file, then this resource will not reload + on it's own. + @param backgroundThread Indicates whether the caller of this method is + the background resource loading thread. + */ virtual void load(bool backgroundThread = false); - /** Reloads the resource, if it is already loaded. - @remarks - Calls unload() and then load() again, if the resource is already - loaded. If it is not loaded already, then nothing happens. - */ - virtual void reload(void); + /** Reloads the resource, if it is already loaded. + @remarks + Calls unload() and then load() again, if the resource is already + loaded. If it is not loaded already, then nothing happens. + */ + virtual void reload(void); /** Returns true if the Resource is reloadable, false otherwise. */ @@ -283,24 +283,24 @@ namespace Ogre { } /** Is this resource manually loaded? - */ - virtual bool isManuallyLoaded(void) const - { - return mIsManual; - } + */ + virtual bool isManuallyLoaded(void) const + { + return mIsManual; + } - /** Set "Is this resource manually loaded?" - */ - virtual void setManuallyLoaded(bool isManual) - { - mIsManual = isManual; - } + /** Set "Is this resource manually loaded?" + */ + virtual void setManuallyLoaded(bool isManual) + { + mIsManual = isManual; + } - /** Unloads the resource; this is not permanent, the resource can be - reloaded later if required. + /** Unloads the resource; this is not permanent, the resource can be + reloaded later if required. */ - virtual void unload(void); + virtual void unload(void); /** Retrieves info about the size of the resource. */ @@ -329,7 +329,7 @@ namespace Ogre { */ virtual bool isPrepared(void) const { - // No lock required to read this state since no modify + // No lock required to read this state since no modify return (mLoadingState.get() == LOADSTATE_PREPARED); } @@ -337,196 +337,196 @@ namespace Ogre { */ virtual bool isLoaded(void) const { - // No lock required to read this state since no modify + // No lock required to read this state since no modify return (mLoadingState.get() == LOADSTATE_LOADED); } - /** Change the Resource loading state to loaded. + /** Change the Resource loading state to loaded. */ virtual void setToLoaded(void) { - // No lock required to read this state since no modify + // No lock required to read this state since no modify mLoadingState.set(LOADSTATE_LOADED); } - /** Returns whether the resource is currently in the process of - background loading. - */ - virtual bool isLoading() const - { - return (mLoadingState.get() == LOADSTATE_LOADING); - } - - /** Returns the current loading state. - */ - virtual LoadingState getLoadingState() const - { - return mLoadingState.get(); - } - - - - /** Returns whether this Resource has been earmarked for background loading. - @remarks - This option only makes sense when you have built Ogre with - thread support (OGRE_THREAD_SUPPORT). If a resource has been marked - for background loading, then it won't load on demand like normal - when load() is called. Instead, it will ignore request to load() - except if the caller indicates it is the background loader. Any - other users of this resource should check isLoaded(), and if that - returns false, don't use the resource and come back later. - */ - virtual bool isBackgroundLoaded(void) const { return mIsBackgroundLoaded; } - - /** Tells the resource whether it is background loaded or not. + /** Returns whether the resource is currently in the process of + background loading. + */ + virtual bool isLoading() const + { + return (mLoadingState.get() == LOADSTATE_LOADING); + } + + /** Returns the current loading state. + */ + virtual LoadingState getLoadingState() const + { + return mLoadingState.get(); + } + + + + /** Returns whether this Resource has been earmarked for background loading. + @remarks + This option only makes sense when you have built Ogre with + thread support (OGRE_THREAD_SUPPORT). If a resource has been marked + for background loading, then it won't load on demand like normal + when load() is called. Instead, it will ignore request to load() + except if the caller indicates it is the background loader. Any + other users of this resource should check isLoaded(), and if that + returns false, don't use the resource and come back later. + */ + virtual bool isBackgroundLoaded(void) const { return mIsBackgroundLoaded; } + + /** Tells the resource whether it is background loaded or not. @see Resource::isBackgroundLoaded. Note that calling this only - defers the normal on-demand loading behaviour of a resource, it - does not actually set up a thread to make sure the resource gets - loaded in the background. You should use ResourceBackgroundLoadingQueue - to manage the actual loading (which will call this method itself). - */ - virtual void setBackgroundLoaded(bool bl) { mIsBackgroundLoaded = bl; } - - /** Escalates the loading of a background loaded resource. - @remarks - If a resource is set to load in the background, but something needs - it before it's been loaded, there could be a problem. If the user - of this resource really can't wait, they can escalate the loading - which basically pulls the loading into the current thread immediately. - If the resource is already being loaded but just hasn't quite finished - then this method will simply wait until the background load is complete. - */ - virtual void escalateLoading(); - - /** Register a listener on this resource. - @see Resource::Listener - */ - virtual void addListener(Listener* lis); - - /** Remove a listener on this resource. - @see Resource::Listener - */ - virtual void removeListener(Listener* lis); - - /// Gets the group which this resource is a member of - virtual const String& getGroup(void) const { return mGroup; } - - /** Change the resource group ownership of a Resource. - @remarks - This method is generally reserved for internal use, although - if you really know what you're doing you can use it to move - this resource from one group to another. - @param newGroup Name of the new group - */ - virtual void changeGroupOwnership(const String& newGroup); - - /// Gets the manager which created this resource - virtual ResourceManager* getCreator(void) { return mCreator; } - /** Get the origin of this resource, e.g. a script file name. - @remarks - This property will only contain something if the creator of - this resource chose to populate it. Script loaders are advised - to populate it. - */ - virtual const String& getOrigin(void) const { return mOrigin; } - /// Notify this resource of it's origin - virtual void _notifyOrigin(const String& origin) { mOrigin = origin; } - - /** Returns the number of times this resource has changed state, which - generally means the number of times it has been loaded. Objects that - build derived data based on the resource can check this value against - a copy they kept last time they built this derived data, in order to - know whether it needs rebuilding. This is a nice way of monitoring - changes without having a tightly-bound callback. - */ - virtual size_t getStateCount() const { return mStateCount; } - - /** Manually mark the state of this resource as having been changed. - @remarks - You only need to call this from outside if you explicitly want derived - objects to think this object has changed. @see getStateCount. - */ - virtual void _dirtyState(); - - - /** Firing of loading complete event - @remarks - You should call this from the thread that runs the main frame loop - to avoid having to make the receivers of this event thread-safe. - If you use Ogre's built in frame loop you don't need to call this - yourself. - @param wasBackgroundLoaded Whether this was a background loaded event - */ - virtual void _fireLoadingComplete(bool wasBackgroundLoaded); - - /** Firing of preparing complete event - @remarks - You should call this from the thread that runs the main frame loop - to avoid having to make the receivers of this event thread-safe. - If you use Ogre's built in frame loop you don't need to call this - yourself. - @param wasBackgroundLoaded Whether this was a background loaded event - */ - virtual void _firePreparingComplete(bool wasBackgroundLoaded); - - /** Firing of unloading complete event - @remarks - You should call this from the thread that runs the main frame loop - to avoid having to make the receivers of this event thread-safe. - If you use Ogre's built in frame loop you don't need to call this - yourself. - */ - virtual void _fireUnloadingComplete(void); - - /** Calculate the size of a resource; this will only be called after 'load' */ - virtual size_t calculateSize(void) const; + defers the normal on-demand loading behaviour of a resource, it + does not actually set up a thread to make sure the resource gets + loaded in the background. You should use ResourceBackgroundLoadingQueue + to manage the actual loading (which will call this method itself). + */ + virtual void setBackgroundLoaded(bool bl) { mIsBackgroundLoaded = bl; } + + /** Escalates the loading of a background loaded resource. + @remarks + If a resource is set to load in the background, but something needs + it before it's been loaded, there could be a problem. If the user + of this resource really can't wait, they can escalate the loading + which basically pulls the loading into the current thread immediately. + If the resource is already being loaded but just hasn't quite finished + then this method will simply wait until the background load is complete. + */ + virtual void escalateLoading(); + + /** Register a listener on this resource. + @see Resource::Listener + */ + virtual void addListener(Listener* lis); + + /** Remove a listener on this resource. + @see Resource::Listener + */ + virtual void removeListener(Listener* lis); + + /// Gets the group which this resource is a member of + virtual const String& getGroup(void) const { return mGroup; } + + /** Change the resource group ownership of a Resource. + @remarks + This method is generally reserved for internal use, although + if you really know what you're doing you can use it to move + this resource from one group to another. + @param newGroup Name of the new group + */ + virtual void changeGroupOwnership(const String& newGroup); + + /// Gets the manager which created this resource + virtual ResourceManager* getCreator(void) { return mCreator; } + /** Get the origin of this resource, e.g. a script file name. + @remarks + This property will only contain something if the creator of + this resource chose to populate it. Script loaders are advised + to populate it. + */ + virtual const String& getOrigin(void) const { return mOrigin; } + /// Notify this resource of it's origin + virtual void _notifyOrigin(const String& origin) { mOrigin = origin; } + + /** Returns the number of times this resource has changed state, which + generally means the number of times it has been loaded. Objects that + build derived data based on the resource can check this value against + a copy they kept last time they built this derived data, in order to + know whether it needs rebuilding. This is a nice way of monitoring + changes without having a tightly-bound callback. + */ + virtual size_t getStateCount() const { return mStateCount; } + + /** Manually mark the state of this resource as having been changed. + @remarks + You only need to call this from outside if you explicitly want derived + objects to think this object has changed. @see getStateCount. + */ + virtual void _dirtyState(); + + + /** Firing of loading complete event + @remarks + You should call this from the thread that runs the main frame loop + to avoid having to make the receivers of this event thread-safe. + If you use Ogre's built in frame loop you don't need to call this + yourself. + @param wasBackgroundLoaded Whether this was a background loaded event + */ + virtual void _fireLoadingComplete(bool wasBackgroundLoaded); + + /** Firing of preparing complete event + @remarks + You should call this from the thread that runs the main frame loop + to avoid having to make the receivers of this event thread-safe. + If you use Ogre's built in frame loop you don't need to call this + yourself. + @param wasBackgroundLoaded Whether this was a background loaded event + */ + virtual void _firePreparingComplete(bool wasBackgroundLoaded); + + /** Firing of unloading complete event + @remarks + You should call this from the thread that runs the main frame loop + to avoid having to make the receivers of this event thread-safe. + If you use Ogre's built in frame loop you don't need to call this + yourself. + */ + virtual void _fireUnloadingComplete(void); + + /** Calculate the size of a resource; this will only be called after 'load' */ + virtual size_t calculateSize(void) const; }; - /** Interface describing a manual resource loader. - @remarks - Resources are usually loaded from files; however in some cases you - want to be able to set the data up manually instead. This provides - some problems, such as how to reload a Resource if it becomes - unloaded for some reason, either because of memory constraints, or - because a device fails and some or all of the data is lost. - @par - This interface should be implemented by all classes which wish to - provide manual data to a resource. They provide a pointer to themselves - when defining the resource (via the appropriate ResourceManager), - and will be called when the Resource tries to load. - They should implement the loadResource method such that the Resource - is in the end set up exactly as if it had loaded from a file, - although the implementations will likely differ between subclasses - of Resource, which is why no generic algorithm can be stated here. - @note - The loader must remain valid for the entire life of the resource, - so that if need be it can be called upon to re-load the resource - at any time. - */ - class _OgreExport ManualResourceLoader - { - public: - ManualResourceLoader() {} - virtual ~ManualResourceLoader() {} + /** Interface describing a manual resource loader. + @remarks + Resources are usually loaded from files; however in some cases you + want to be able to set the data up manually instead. This provides + some problems, such as how to reload a Resource if it becomes + unloaded for some reason, either because of memory constraints, or + because a device fails and some or all of the data is lost. + @par + This interface should be implemented by all classes which wish to + provide manual data to a resource. They provide a pointer to themselves + when defining the resource (via the appropriate ResourceManager), + and will be called when the Resource tries to load. + They should implement the loadResource method such that the Resource + is in the end set up exactly as if it had loaded from a file, + although the implementations will likely differ between subclasses + of Resource, which is why no generic algorithm can be stated here. + @note + The loader must remain valid for the entire life of the resource, + so that if need be it can be called upon to re-load the resource + at any time. + */ + class _OgreExport ManualResourceLoader + { + public: + ManualResourceLoader() {} + virtual ~ManualResourceLoader() {} /** Called when a resource wishes to load. Note that this could get * called in a background thread even in just a semithreaded ogre * (OGRE_THREAD_SUPPORT==2). Thus, you must not access the rendersystem from * this callback. Do that stuff in loadResource. - @param resource The resource which wishes to load - */ - virtual void prepareResource(Resource* resource) + @param resource The resource which wishes to load + */ + virtual void prepareResource(Resource* resource) { (void)resource; } - /** Called when a resource wishes to prepare. - @param resource The resource which wishes to prepare - */ - virtual void loadResource(Resource* resource) = 0; - }; - /** @} */ - /** @} */ + /** Called when a resource wishes to prepare. + @param resource The resource which wishes to prepare + */ + virtual void loadResource(Resource* resource) = 0; + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreResourceBackgroundQueue.h b/OgreMain/include/OgreResourceBackgroundQueue.h index 6b4c97b3d46..d8dc362b1c8 100644 --- a/OgreMain/include/OgreResourceBackgroundQueue.h +++ b/OgreMain/include/OgreResourceBackgroundQueue.h @@ -37,286 +37,286 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - - /// Identifier of a background process - typedef WorkQueue::RequestID BackgroundProcessTicket; - - /** Encapsulates the result of a background queue request */ - struct BackgroundProcessResult - { - /// Whether an error occurred - bool error; - /// Any messages from the process - String message; - - BackgroundProcessResult() : error(false) {} - }; - - - /** This class is used to perform Resource operations in a - background thread. - @remarks - All these requests are now queued via Root::getWorkQueue in order - to share the thread pool amongst all background tasks. You should therefore - refer to that class for configuring the behaviour of the threads - themselves, this class merely provides an interface that is specific - to resource loading around this common functionality. - @par - The general approach here is that on requesting a background resource - process, your request is placed on a queue ready for the background - thread to be picked up, and you will get a 'ticket' back, identifying - the request. Your call will then return and your thread can - proceed, knowing that at some point in the background the operation will - be performed. In it's own thread, the resource operation will be - performed, and once finished the ticket will be marked as complete. - You can check the status of tickets by calling isProcessComplete() - from your queueing thread. - */ - class _OgreExport ResourceBackgroundQueue : public Singleton, public ResourceAlloc, - public WorkQueue::RequestHandler, public WorkQueue::ResponseHandler - { - public: - /** This abstract listener interface lets you get notifications of - completed background processes instead of having to poll ticket - statuses. - @note - For simplicity, these callbacks are not issued direct from the background - loading thread, they are queued themselves to be sent from the main thread - so that you don't have to be concerned about thread safety. - */ - class _OgreExport Listener - { - public: - /** Called when a requested operation completes, queued into main thread. - @note - For simplicity, this callback is not issued direct from the background - loading thread, it is queued to be sent from the main thread - so that you don't have to be concerned about thread safety. - */ - virtual void operationCompleted(BackgroundProcessTicket ticket, const BackgroundProcessResult& result) = 0; - /// Need virtual destructor in case subclasses use it - virtual ~Listener() {} - - }; - - protected: - - uint16 mWorkQueueChannel; - /** Enumerates the type of requests */ - enum RequestType - { - RT_INITIALISE_GROUP = 0, - RT_INITIALISE_ALL_GROUPS = 1, - RT_PREPARE_GROUP = 2, - RT_PREPARE_RESOURCE = 3, - RT_LOAD_GROUP = 4, - RT_LOAD_RESOURCE = 5, - RT_UNLOAD_GROUP = 6, - RT_UNLOAD_RESOURCE = 7 - }; - /** Encapsulates a queued request for the background queue */ - struct ResourceRequest - { - RequestType type; - String resourceName; - ResourceHandle resourceHandle; - String resourceType; - String groupName; - bool isManual; - ManualResourceLoader* loader; - NameValuePairList* loadParams; - Listener* listener; - BackgroundProcessResult result; - - _OgreExport friend std::ostream& operator<<(std::ostream& o, const ResourceRequest& r) - { (void)r; return o; } - }; - - typedef set::type OutstandingRequestSet; - OutstandingRequestSet mOutstandingRequestSet; - - /// Struct that holds details of queued notifications - struct ResourceResponse - { - ResourceResponse(ResourcePtr r, const ResourceRequest& req) - : resource(r), request(req) - {} - - ResourcePtr resource; - ResourceRequest request; - - _OgreExport friend std::ostream& operator<<(std::ostream& o, const ResourceResponse& r) - { (void)r; return o; } - }; - - BackgroundProcessTicket addRequest(ResourceRequest& req); - - public: - ResourceBackgroundQueue(); - virtual ~ResourceBackgroundQueue(); - - /** Initialise the background queue system. - @note Called automatically by Root::initialise. - */ - virtual void initialise(void); - - /** Shut down the background queue system. - @note Called automatically by Root::shutdown. - */ - virtual void shutdown(void); - - /** Initialise a resource group in the background. - @see ResourceGroupManager::initialiseResourceGroup - @param name The name of the resource group to initialise - @param listener Optional callback interface, take note of warnings in - the header and only use if you understand them. - @return Ticket identifying the request, use isProcessComplete() to - determine if completed if not using listener - */ - virtual BackgroundProcessTicket initialiseResourceGroup( - const String& name, Listener* listener = 0); - - /** Initialise all resource groups which are yet to be initialised in - the background. - @see ResourceGroupManager::intialiseResourceGroup - @param listener Optional callback interface, take note of warnings in - the header and only use if you understand them. - @return Ticket identifying the request, use isProcessComplete() to - determine if completed if not using listener - */ - virtual BackgroundProcessTicket initialiseAllResourceGroups( - Listener* listener = 0); - /** Prepares a resource group in the background. - @see ResourceGroupManager::prepareResourceGroup - @param name The name of the resource group to prepare - @param listener Optional callback interface, take note of warnings in - the header and only use if you understand them. - @return Ticket identifying the request, use isProcessComplete() to - determine if completed if not using listener - */ - virtual BackgroundProcessTicket prepareResourceGroup(const String& name, - Listener* listener = 0); - - /** Loads a resource group in the background. - @see ResourceGroupManager::loadResourceGroup - @param name The name of the resource group to load - @param listener Optional callback interface, take note of warnings in - the header and only use if you understand them. - @return Ticket identifying the request, use isProcessComplete() to - determine if completed if not using listener - */ - virtual BackgroundProcessTicket loadResourceGroup(const String& name, - Listener* listener = 0); - - - /** Unload a single resource in the background. - @see ResourceManager::unload - @param resType The type of the resource - (from ResourceManager::getResourceType()) - @param name The name of the Resource - */ - virtual BackgroundProcessTicket unload( - const String& resType, const String& name, - Listener* listener = 0); - - /** Unload a single resource in the background. - @see ResourceManager::unload - @param resType The type of the resource - (from ResourceManager::getResourceType()) - @param handle Handle to the resource - */ - virtual BackgroundProcessTicket unload( - const String& resType, ResourceHandle handle, - Listener* listener = 0); - - /** Unloads a resource group in the background. - @see ResourceGroupManager::unloadResourceGroup - @param name The name of the resource group to load - @return Ticket identifying the request, use isProcessComplete() to - determine if completed if not using listener - */ - virtual BackgroundProcessTicket unloadResourceGroup(const String& name, - Listener* listener = 0); - - - /** Prepare a single resource in the background. - @see ResourceManager::prepare - @param resType The type of the resource - (from ResourceManager::getResourceType()) - @param name The name of the Resource - @param group The resource group to which this resource will belong - @param isManual Is the resource to be manually loaded? If so, you should - provide a value for the loader parameter - @param loader The manual loader which is to perform the required actions - when this resource is loaded; only applicable when you specify true - for the previous parameter. NOTE: must be thread safe!! + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + + /// Identifier of a background process + typedef WorkQueue::RequestID BackgroundProcessTicket; + + /** Encapsulates the result of a background queue request */ + struct BackgroundProcessResult + { + /// Whether an error occurred + bool error; + /// Any messages from the process + String message; + + BackgroundProcessResult() : error(false) {} + }; + + + /** This class is used to perform Resource operations in a + background thread. + @remarks + All these requests are now queued via Root::getWorkQueue in order + to share the thread pool amongst all background tasks. You should therefore + refer to that class for configuring the behaviour of the threads + themselves, this class merely provides an interface that is specific + to resource loading around this common functionality. + @par + The general approach here is that on requesting a background resource + process, your request is placed on a queue ready for the background + thread to be picked up, and you will get a 'ticket' back, identifying + the request. Your call will then return and your thread can + proceed, knowing that at some point in the background the operation will + be performed. In it's own thread, the resource operation will be + performed, and once finished the ticket will be marked as complete. + You can check the status of tickets by calling isProcessComplete() + from your queueing thread. + */ + class _OgreExport ResourceBackgroundQueue : public Singleton, public ResourceAlloc, + public WorkQueue::RequestHandler, public WorkQueue::ResponseHandler + { + public: + /** This abstract listener interface lets you get notifications of + completed background processes instead of having to poll ticket + statuses. + @note + For simplicity, these callbacks are not issued direct from the background + loading thread, they are queued themselves to be sent from the main thread + so that you don't have to be concerned about thread safety. + */ + class _OgreExport Listener + { + public: + /** Called when a requested operation completes, queued into main thread. + @note + For simplicity, this callback is not issued direct from the background + loading thread, it is queued to be sent from the main thread + so that you don't have to be concerned about thread safety. + */ + virtual void operationCompleted(BackgroundProcessTicket ticket, const BackgroundProcessResult& result) = 0; + /// Need virtual destructor in case subclasses use it + virtual ~Listener() {} + + }; + + protected: + + uint16 mWorkQueueChannel; + /** Enumerates the type of requests */ + enum RequestType + { + RT_INITIALISE_GROUP = 0, + RT_INITIALISE_ALL_GROUPS = 1, + RT_PREPARE_GROUP = 2, + RT_PREPARE_RESOURCE = 3, + RT_LOAD_GROUP = 4, + RT_LOAD_RESOURCE = 5, + RT_UNLOAD_GROUP = 6, + RT_UNLOAD_RESOURCE = 7 + }; + /** Encapsulates a queued request for the background queue */ + struct ResourceRequest + { + RequestType type; + String resourceName; + ResourceHandle resourceHandle; + String resourceType; + String groupName; + bool isManual; + ManualResourceLoader* loader; + NameValuePairList* loadParams; + Listener* listener; + BackgroundProcessResult result; + + _OgreExport friend std::ostream& operator<<(std::ostream& o, const ResourceRequest& r) + { (void)r; return o; } + }; + + typedef set::type OutstandingRequestSet; + OutstandingRequestSet mOutstandingRequestSet; + + /// Struct that holds details of queued notifications + struct ResourceResponse + { + ResourceResponse(ResourcePtr r, const ResourceRequest& req) + : resource(r), request(req) + {} + + ResourcePtr resource; + ResourceRequest request; + + _OgreExport friend std::ostream& operator<<(std::ostream& o, const ResourceResponse& r) + { (void)r; return o; } + }; + + BackgroundProcessTicket addRequest(ResourceRequest& req); + + public: + ResourceBackgroundQueue(); + virtual ~ResourceBackgroundQueue(); + + /** Initialise the background queue system. + @note Called automatically by Root::initialise. + */ + virtual void initialise(void); + + /** Shut down the background queue system. + @note Called automatically by Root::shutdown. + */ + virtual void shutdown(void); + + /** Initialise a resource group in the background. + @see ResourceGroupManager::initialiseResourceGroup + @param name The name of the resource group to initialise + @param listener Optional callback interface, take note of warnings in + the header and only use if you understand them. + @return Ticket identifying the request, use isProcessComplete() to + determine if completed if not using listener + */ + virtual BackgroundProcessTicket initialiseResourceGroup( + const String& name, Listener* listener = 0); + + /** Initialise all resource groups which are yet to be initialised in + the background. + @see ResourceGroupManager::intialiseResourceGroup + @param listener Optional callback interface, take note of warnings in + the header and only use if you understand them. + @return Ticket identifying the request, use isProcessComplete() to + determine if completed if not using listener + */ + virtual BackgroundProcessTicket initialiseAllResourceGroups( + Listener* listener = 0); + /** Prepares a resource group in the background. + @see ResourceGroupManager::prepareResourceGroup + @param name The name of the resource group to prepare + @param listener Optional callback interface, take note of warnings in + the header and only use if you understand them. + @return Ticket identifying the request, use isProcessComplete() to + determine if completed if not using listener + */ + virtual BackgroundProcessTicket prepareResourceGroup(const String& name, + Listener* listener = 0); + + /** Loads a resource group in the background. + @see ResourceGroupManager::loadResourceGroup + @param name The name of the resource group to load + @param listener Optional callback interface, take note of warnings in + the header and only use if you understand them. + @return Ticket identifying the request, use isProcessComplete() to + determine if completed if not using listener + */ + virtual BackgroundProcessTicket loadResourceGroup(const String& name, + Listener* listener = 0); + + + /** Unload a single resource in the background. + @see ResourceManager::unload + @param resType The type of the resource + (from ResourceManager::getResourceType()) + @param name The name of the Resource + */ + virtual BackgroundProcessTicket unload( + const String& resType, const String& name, + Listener* listener = 0); + + /** Unload a single resource in the background. + @see ResourceManager::unload + @param resType The type of the resource + (from ResourceManager::getResourceType()) + @param handle Handle to the resource + */ + virtual BackgroundProcessTicket unload( + const String& resType, ResourceHandle handle, + Listener* listener = 0); + + /** Unloads a resource group in the background. + @see ResourceGroupManager::unloadResourceGroup + @param name The name of the resource group to load + @return Ticket identifying the request, use isProcessComplete() to + determine if completed if not using listener + */ + virtual BackgroundProcessTicket unloadResourceGroup(const String& name, + Listener* listener = 0); + + + /** Prepare a single resource in the background. + @see ResourceManager::prepare + @param resType The type of the resource + (from ResourceManager::getResourceType()) + @param name The name of the Resource + @param group The resource group to which this resource will belong + @param isManual Is the resource to be manually loaded? If so, you should + provide a value for the loader parameter + @param loader The manual loader which is to perform the required actions + when this resource is loaded; only applicable when you specify true + for the previous parameter. NOTE: must be thread safe!! @param loadParams Optional pointer to a list of name/value pairs containing loading parameters for this type of resource. Remember - that this must have a lifespan longer than the return of this call! - */ - virtual BackgroundProcessTicket prepare( - const String& resType, const String& name, + that this must have a lifespan longer than the return of this call! + */ + virtual BackgroundProcessTicket prepare( + const String& resType, const String& name, const String& group, bool isManual = false, - ManualResourceLoader* loader = 0, - const NameValuePairList* loadParams = 0, - Listener* listener = 0); - - /** Load a single resource in the background. - @see ResourceManager::load - @param resType The type of the resource - (from ResourceManager::getResourceType()) - @param name The name of the Resource - @param group The resource group to which this resource will belong - @param isManual Is the resource to be manually loaded? If so, you should - provide a value for the loader parameter - @param loader The manual loader which is to perform the required actions - when this resource is loaded; only applicable when you specify true - for the previous parameter. NOTE: must be thread safe!! + ManualResourceLoader* loader = 0, + const NameValuePairList* loadParams = 0, + Listener* listener = 0); + + /** Load a single resource in the background. + @see ResourceManager::load + @param resType The type of the resource + (from ResourceManager::getResourceType()) + @param name The name of the Resource + @param group The resource group to which this resource will belong + @param isManual Is the resource to be manually loaded? If so, you should + provide a value for the loader parameter + @param loader The manual loader which is to perform the required actions + when this resource is loaded; only applicable when you specify true + for the previous parameter. NOTE: must be thread safe!! @param loadParams Optional pointer to a list of name/value pairs containing loading parameters for this type of resource. Remember - that this must have a lifespan longer than the return of this call! - */ - virtual BackgroundProcessTicket load( - const String& resType, const String& name, + that this must have a lifespan longer than the return of this call! + */ + virtual BackgroundProcessTicket load( + const String& resType, const String& name, const String& group, bool isManual = false, - ManualResourceLoader* loader = 0, - const NameValuePairList* loadParams = 0, - Listener* listener = 0); - /** Returns whether a previously queued process has completed or not. - @remarks - This method of checking that a background process has completed is - the 'polling' approach. Each queued method takes an optional listener - parameter to allow you to register a callback instead, which is - arguably more efficient. - @param ticket The ticket which was returned when the process was queued - @return true if process has completed (or if the ticket is - unrecognised), false otherwise - @note Tickets are not stored once complete so do not accumulate over - time. - This is why a non-existent ticket will return 'true'. - */ - virtual bool isProcessComplete(BackgroundProcessTicket ticket); - - /** Aborts background process. - */ - void abortRequest( BackgroundProcessTicket ticket ); - - /// Implementation for WorkQueue::RequestHandler - bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); - /// Implementation for WorkQueue::RequestHandler - WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); - /// Implementation for WorkQueue::ResponseHandler - bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - /// Implementation for WorkQueue::ResponseHandler - void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); - - /** Override standard Singleton retrieval. + ManualResourceLoader* loader = 0, + const NameValuePairList* loadParams = 0, + Listener* listener = 0); + /** Returns whether a previously queued process has completed or not. + @remarks + This method of checking that a background process has completed is + the 'polling' approach. Each queued method takes an optional listener + parameter to allow you to register a callback instead, which is + arguably more efficient. + @param ticket The ticket which was returned when the process was queued + @return true if process has completed (or if the ticket is + unrecognised), false otherwise + @note Tickets are not stored once complete so do not accumulate over + time. + This is why a non-existent ticket will return 'true'. + */ + virtual bool isProcessComplete(BackgroundProcessTicket ticket); + + /** Aborts background process. + */ + void abortRequest( BackgroundProcessTicket ticket ); + + /// Implementation for WorkQueue::RequestHandler + bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + /// Implementation for WorkQueue::RequestHandler + WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ); + /// Implementation for WorkQueue::ResponseHandler + bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + /// Implementation for WorkQueue::ResponseHandler + void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ); + + /** Override standard Singleton retrieval. @remarks Why do we do this? Well, it's because the Singleton implementation is in a .h file, which means it gets compiled @@ -349,10 +349,10 @@ namespace Ogre { */ static ResourceBackgroundQueue* getSingletonPtr(void); - }; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreResourceGroupManager.h b/OgreMain/include/OgreResourceGroupManager.h index 662f8366fb4..5c1a6b2bba7 100644 --- a/OgreMain/include/OgreResourceGroupManager.h +++ b/OgreMain/include/OgreResourceGroupManager.h @@ -47,38 +47,38 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** This abstract class defines an interface which is called back during + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** This abstract class defines an interface which is called back during resource group loading to indicate the progress of the load. - @remarks - Resource group loading is in 2 phases - creating resources from - declarations (which includes parsing scripts), and loading - resources. Note that you don't necessarily have to have both; it - is quite possible to just parse all the scripts for a group (see - ResourceGroupManager::initialiseResourceGroup, but not to - load the resource group. - The sequence of events is (* signifies a repeating item): -
        -
      • resourceGroupScriptingStarted
      • -
      • scriptParseStarted (*)
      • + @remarks + Resource group loading is in 2 phases - creating resources from + declarations (which includes parsing scripts), and loading + resources. Note that you don't necessarily have to have both; it + is quite possible to just parse all the scripts for a group (see + ResourceGroupManager::initialiseResourceGroup, but not to + load the resource group. + The sequence of events is (* signifies a repeating item): +
          +
        • resourceGroupScriptingStarted
        • +
        • scriptParseStarted (*)
        • scriptParseEnded (*)
        • -
        • resourceGroupScriptingEnded
        • -
        • resourceGroupLoadStarted
        • -
        • resourceLoadStarted (*)
        • +
        • resourceGroupScriptingEnded
        • +
        • resourceGroupLoadStarted
        • +
        • resourceLoadStarted (*)
        • resourceLoadEnded (*)
        • worldGeometryStageStarted (*)
        • worldGeometryStageEnded (*)
        • -
        • resourceGroupLoadEnded
        • -
        • resourceGroupPrepareStarted
        • -
        • resourcePrepareStarted (*)
        • +
        • resourceGroupLoadEnded
        • +
        • resourceGroupPrepareStarted
        • +
        • resourcePrepareStarted (*)
        • resourcePrepareEnded (*)
        • -
        • resourceGroupPrepareEnded
        • -
        +
      • resourceGroupPrepareEnded
      • +
      @note If OGRE_THREAD_SUPPORT is 1, this class is thread-safe. @@ -88,43 +88,43 @@ namespace Ogre { public: virtual ~ResourceGroupListener() {} - /** This event is fired when a resource group begins parsing scripts. - @note - Remember that if you are loading resources through ResourceBackgroundQueue, - these callbacks will occur in the background thread, so you should - not perform any thread-unsafe actions in this callback if that's the - case (check the group name / script name). - @param groupName The name of the group - @param scriptCount The number of scripts which will be parsed - */ - virtual void resourceGroupScriptingStarted(const String& groupName, size_t scriptCount) = 0; - /** This event is fired when a script is about to be parsed. - @param scriptName Name of the to be parsed - @param skipThisScript A boolean passed by reference which is by default set to - false. If the event sets this to true, the script will be skipped and not - parsed. Note that in this case the scriptParseEnded event will not be raised - for this script. - */ - virtual void scriptParseStarted(const String& scriptName, bool& skipThisScript) = 0; - - /** This event is fired when the script has been fully parsed. - */ - virtual void scriptParseEnded(const String& scriptName, bool skipped) = 0; - /** This event is fired when a resource group finished parsing scripts. */ - virtual void resourceGroupScriptingEnded(const String& groupName) = 0; - - /** This event is fired when a resource group begins preparing. - @param groupName The name of the group being prepared - @param resourceCount The number of resources which will be prepared, including + /** This event is fired when a resource group begins parsing scripts. + @note + Remember that if you are loading resources through ResourceBackgroundQueue, + these callbacks will occur in the background thread, so you should + not perform any thread-unsafe actions in this callback if that's the + case (check the group name / script name). + @param groupName The name of the group + @param scriptCount The number of scripts which will be parsed + */ + virtual void resourceGroupScriptingStarted(const String& groupName, size_t scriptCount) = 0; + /** This event is fired when a script is about to be parsed. + @param scriptName Name of the to be parsed + @param skipThisScript A boolean passed by reference which is by default set to + false. If the event sets this to true, the script will be skipped and not + parsed. Note that in this case the scriptParseEnded event will not be raised + for this script. + */ + virtual void scriptParseStarted(const String& scriptName, bool& skipThisScript) = 0; + + /** This event is fired when the script has been fully parsed. + */ + virtual void scriptParseEnded(const String& scriptName, bool skipped) = 0; + /** This event is fired when a resource group finished parsing scripts. */ + virtual void resourceGroupScriptingEnded(const String& groupName) = 0; + + /** This event is fired when a resource group begins preparing. + @param groupName The name of the group being prepared + @param resourceCount The number of resources which will be prepared, including a number of stages required to prepare any linked world geometry - */ - virtual void resourceGroupPrepareStarted(const String& groupName, size_t resourceCount) + */ + virtual void resourceGroupPrepareStarted(const String& groupName, size_t resourceCount) { (void)groupName; (void)resourceCount; } - /** This event is fired when a declared resource is about to be prepared. - @param resource Weak reference to the resource prepared. - */ - virtual void resourcePrepareStarted(const ResourcePtr& resource) + /** This event is fired when a declared resource is about to be prepared. + @param resource Weak reference to the resource prepared. + */ + virtual void resourcePrepareStarted(const ResourcePtr& resource) { (void)resource; } /** This event is fired when the resource has been prepared. @@ -147,16 +147,16 @@ namespace Ogre { virtual void resourceGroupPrepareEnded(const String& groupName) { (void)groupName; } - /** This event is fired when a resource group begins loading. - @param groupName The name of the group being loaded - @param resourceCount The number of resources which will be loaded, including + /** This event is fired when a resource group begins loading. + @param groupName The name of the group being loaded + @param resourceCount The number of resources which will be loaded, including a number of stages required to load any linked world geometry - */ - virtual void resourceGroupLoadStarted(const String& groupName, size_t resourceCount) = 0; - /** This event is fired when a declared resource is about to be loaded. - @param resource Weak reference to the resource loaded. - */ - virtual void resourceLoadStarted(const ResourcePtr& resource) = 0; + */ + virtual void resourceGroupLoadStarted(const String& groupName, size_t resourceCount) = 0; + /** This event is fired when a declared resource is about to be loaded. + @param resource Weak reference to the resource loaded. + */ + virtual void resourceLoadStarted(const ResourcePtr& resource) = 0; /** This event is fired when the resource has been loaded. */ virtual void resourceLoadEnded(void) = 0; @@ -172,43 +172,43 @@ namespace Ogre { */ virtual void worldGeometryStageEnded(void) = 0; /** This event is fired when a resource group finished loading. */ - virtual void resourceGroupLoadEnded(const String& groupName) = 0; - /** This event is fired when a resource was just created. - @param resource Weak reference to the resource created. - */ - virtual void resourceCreated(const ResourcePtr& resource) - { (void)resource; } - /** This event is fired when a resource is about to be removed. - @param resource Weak reference to the resource removed. - */ - virtual void resourceRemove(const ResourcePtr& resource) - { (void)resource; } + virtual void resourceGroupLoadEnded(const String& groupName) = 0; + /** This event is fired when a resource was just created. + @param resource Weak reference to the resource created. + */ + virtual void resourceCreated(const ResourcePtr& resource) + { (void)resource; } + /** This event is fired when a resource is about to be removed. + @param resource Weak reference to the resource removed. + */ + virtual void resourceRemove(const ResourcePtr& resource) + { (void)resource; } }; - /** - @remarks This class allows users to override resource loading behavior. - By overriding this class' methods, you can change how resources - are loaded and the behavior for resource name collisions. - */ - class ResourceLoadingListener - { - public: - virtual ~ResourceLoadingListener() {} - - /** This event is called when a resource beings loading. */ - virtual DataStreamPtr resourceLoading(const String &name, const String &group, Resource *resource) = 0; - - /** This event is called when a resource stream has been opened, but not processed yet. - @remarks - You may alter the stream if you wish or alter the incoming pointer to point at - another stream if you wish. - */ - virtual void resourceStreamOpened(const String &name, const String &group, Resource *resource, DataStreamPtr& dataStream) = 0; - - /** This event is called when a resource collides with another existing one in a resource manager - */ - virtual bool resourceCollision(Resource *resource, ResourceManager *resourceManager) = 0; - }; + /** + @remarks This class allows users to override resource loading behavior. + By overriding this class' methods, you can change how resources + are loaded and the behavior for resource name collisions. + */ + class ResourceLoadingListener + { + public: + virtual ~ResourceLoadingListener() {} + + /** This event is called when a resource beings loading. */ + virtual DataStreamPtr resourceLoading(const String &name, const String &group, Resource *resource) = 0; + + /** This event is called when a resource stream has been opened, but not processed yet. + @remarks + You may alter the stream if you wish or alter the incoming pointer to point at + another stream if you wish. + */ + virtual void resourceStreamOpened(const String &name, const String &group, Resource *resource, DataStreamPtr& dataStream) = 0; + + /** This event is called when a resource collides with another existing one in a resource manager + */ + virtual bool resourceCollision(Resource *resource, ResourceManager *resourceManager) = 0; + }; /** This singleton class manages the list of resource groups, and notifying the various resource managers of their obligations to load / unload @@ -218,143 +218,143 @@ namespace Ogre { @par Defining new resource groups, and declaring the resources you intend to use in advance is optional, however it is a very useful feature. In addition, - if a ResourceManager supports the definition of resources through scripts, - then this is the class which drives the locating of the scripts and telling - the ResourceManager to parse them. - @par - There are several states that a resource can be in (the concept, not the - object instance in this case): -
        -
      1. Undefined. Nobody knows about this resource yet. It might be - in the filesystem, but Ogre is oblivious to it at the moment - there - is no Resource instance. This might be because it's never been declared - (either in a script, or using ResourceGroupManager::declareResource), or - it may have previously been a valid Resource instance but has been - removed, either individually through ResourceManager::remove or as a group - through ResourceGroupManager::clearResourceGroup.
      2. -
      3. Declared. Ogre has some forewarning of this resource, either - through calling ResourceGroupManager::declareResource, or by declaring - the resource in a script file which is on one of the resource locations - which has been defined for a group. There is still no instance of Resource, - but Ogre will know to create this resource when - ResourceGroupManager::initialiseResourceGroup is called (which is automatic - if you declare the resource group before Root::initialise).
      4. -
      5. Unloaded. There is now a Resource instance for this resource, - although it is not loaded. This means that code which looks for this - named resource will find it, but the Resource is not using a lot of memory - because it is in an unloaded state. A Resource can get into this state - by having just been created by ResourceGroupManager::initialiseResourceGroup - (either from a script, or from a call to declareResource), by - being created directly from code (ResourceManager::create), or it may - have previously been loaded and has been unloaded, either individually - through Resource::unload, or as a group through ResourceGroupManager::unloadResourceGroup.
      6. -
      7. LoadedThe Resource instance is fully loaded. This may have - happened implicitly because something used it, or it may have been - loaded as part of a group.
      8. -
      - @see ResourceGroupManager::declareResource - @see ResourceGroupManager::initialiseResourceGroup - @see ResourceGroupManager::loadResourceGroup - @see ResourceGroupManager::unloadResourceGroup - @see ResourceGroupManager::clearResourceGroup + if a ResourceManager supports the definition of resources through scripts, + then this is the class which drives the locating of the scripts and telling + the ResourceManager to parse them. + @par + There are several states that a resource can be in (the concept, not the + object instance in this case): +
        +
      1. Undefined. Nobody knows about this resource yet. It might be + in the filesystem, but Ogre is oblivious to it at the moment - there + is no Resource instance. This might be because it's never been declared + (either in a script, or using ResourceGroupManager::declareResource), or + it may have previously been a valid Resource instance but has been + removed, either individually through ResourceManager::remove or as a group + through ResourceGroupManager::clearResourceGroup.
      2. +
      3. Declared. Ogre has some forewarning of this resource, either + through calling ResourceGroupManager::declareResource, or by declaring + the resource in a script file which is on one of the resource locations + which has been defined for a group. There is still no instance of Resource, + but Ogre will know to create this resource when + ResourceGroupManager::initialiseResourceGroup is called (which is automatic + if you declare the resource group before Root::initialise).
      4. +
      5. Unloaded. There is now a Resource instance for this resource, + although it is not loaded. This means that code which looks for this + named resource will find it, but the Resource is not using a lot of memory + because it is in an unloaded state. A Resource can get into this state + by having just been created by ResourceGroupManager::initialiseResourceGroup + (either from a script, or from a call to declareResource), by + being created directly from code (ResourceManager::create), or it may + have previously been loaded and has been unloaded, either individually + through Resource::unload, or as a group through ResourceGroupManager::unloadResourceGroup.
      6. +
      7. LoadedThe Resource instance is fully loaded. This may have + happened implicitly because something used it, or it may have been + loaded as part of a group.
      8. +
      + @see ResourceGroupManager::declareResource + @see ResourceGroupManager::initialiseResourceGroup + @see ResourceGroupManager::loadResourceGroup + @see ResourceGroupManager::unloadResourceGroup + @see ResourceGroupManager::clearResourceGroup */ class _OgreExport ResourceGroupManager : public Singleton, public ResourceAlloc { public: OGRE_AUTO_MUTEX; // public to allow external locking - /// Default resource group name - static String DEFAULT_RESOURCE_GROUP_NAME; + /// Default resource group name + static String DEFAULT_RESOURCE_GROUP_NAME; /// Internal resource group name (should be used by OGRE internal only) static String INTERNAL_RESOURCE_GROUP_NAME; - /// Special resource group name which causes resource group to be automatically determined based on searching for the resource in all groups. - static String AUTODETECT_RESOURCE_GROUP_NAME; - /// The number of reference counts held per resource by the resource system - static size_t RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS; + /// Special resource group name which causes resource group to be automatically determined based on searching for the resource in all groups. + static String AUTODETECT_RESOURCE_GROUP_NAME; + /// The number of reference counts held per resource by the resource system + static size_t RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS; /// Nested struct defining a resource declaration struct ResourceDeclaration { String resourceName; String resourceType; ManualResourceLoader* loader; - NameValuePairList parameters; + NameValuePairList parameters; }; /// List of resource declarations typedef list::type ResourceDeclarationList; - typedef map::type ResourceManagerMap; - typedef MapIterator ResourceManagerIterator; - /// Resource location entry - struct ResourceLocation - { - /// Pointer to the archive which is the destination - Archive* archive; - /// Whether this location was added recursively - bool recursive; - }; - /// List of possible file locations - typedef list::type LocationList; + typedef map::type ResourceManagerMap; + typedef MapIterator ResourceManagerIterator; + /// Resource location entry + struct ResourceLocation + { + /// Pointer to the archive which is the destination + Archive* archive; + /// Whether this location was added recursively + bool recursive; + }; + /// List of possible file locations + typedef list::type LocationList; protected: - /// Map of resource types (strings) to ResourceManagers, used to notify them to load / unload group contents + /// Map of resource types (strings) to ResourceManagers, used to notify them to load / unload group contents ResourceManagerMap mResourceManagerMap; - /// Map of loading order (Real) to ScriptLoader, used to order script parsing - typedef multimap::type ScriptLoaderOrderMap; - ScriptLoaderOrderMap mScriptLoaderOrderMap; + /// Map of loading order (Real) to ScriptLoader, used to order script parsing + typedef multimap::type ScriptLoaderOrderMap; + ScriptLoaderOrderMap mScriptLoaderOrderMap; - typedef vector::type ResourceGroupListenerList; + typedef vector::type ResourceGroupListenerList; ResourceGroupListenerList mResourceGroupListenerList; - ResourceLoadingListener *mLoadingListener; + ResourceLoadingListener *mLoadingListener; /// Resource index entry, resourcename->location typedef map::type ResourceLocationIndex; - /// List of resources which can be loaded / unloaded - typedef list::type LoadUnloadResourceList; - /// Resource group entry - struct ResourceGroup - { - enum Status - { - UNINITIALSED = 0, - INITIALISING = 1, - INITIALISED = 2, - LOADING = 3, - LOADED = 4 - }; - /// General mutex for dealing with group content + /// List of resources which can be loaded / unloaded + typedef list::type LoadUnloadResourceList; + /// Resource group entry + struct ResourceGroup + { + enum Status + { + UNINITIALSED = 0, + INITIALISING = 1, + INITIALISED = 2, + LOADING = 3, + LOADED = 4 + }; + /// General mutex for dealing with group content OGRE_AUTO_MUTEX; - /// Status-specific mutex, separate from content-changing mutex + /// Status-specific mutex, separate from content-changing mutex OGRE_MUTEX(statusMutex); - /// Group name - String name; - /// Group status - Status groupStatus; - /// List of possible locations to search - LocationList locationList; - /// Index of resource names to locations, built for speedy access (case sensitive archives) - ResourceLocationIndex resourceIndexCaseSensitive; + /// Group name + String name; + /// Group status + Status groupStatus; + /// List of possible locations to search + LocationList locationList; + /// Index of resource names to locations, built for speedy access (case sensitive archives) + ResourceLocationIndex resourceIndexCaseSensitive; /// Index of resource names to locations, built for speedy access (case insensitive archives) ResourceLocationIndex resourceIndexCaseInsensitive; - /// Pre-declared resources, ready to be created - ResourceDeclarationList resourceDeclarations; - /// Created resources which are ready to be loaded / unloaded - // Group by loading order of the type (defined by ResourceManager) - // (e.g. skeletons and materials before meshes) - typedef map::type LoadResourceOrderMap; - LoadResourceOrderMap loadResourceOrderMap; + /// Pre-declared resources, ready to be created + ResourceDeclarationList resourceDeclarations; + /// Created resources which are ready to be loaded / unloaded + // Group by loading order of the type (defined by ResourceManager) + // (e.g. skeletons and materials before meshes) + typedef map::type LoadResourceOrderMap; + LoadResourceOrderMap loadResourceOrderMap; /// Linked world geometry, as passed to setWorldGeometry String worldGeometry; /// Scene manager to use with linked world geometry SceneManager* worldGeometrySceneManager; - // in global pool flag - if true the resource will be loaded even a different group was requested in the load method as a parameter. - bool inGlobalPool; + // in global pool flag - if true the resource will be loaded even a different group was requested in the load method as a parameter. + bool inGlobalPool; - void addToIndex(const String& filename, Archive* arch); - void removeFromIndex(const String& filename, Archive* arch); - void removeFromIndex(Archive* arch); + void addToIndex(const String& filename, Archive* arch); + void removeFromIndex(const String& filename, Archive* arch); + void removeFromIndex(Archive* arch); - }; + }; /// Map from resource group names to groups typedef map::type ResourceGroupMap; ResourceGroupMap mResourceGroupMap; @@ -362,57 +362,57 @@ namespace Ogre { /// Group name for world resources String mWorldGroupName; - /** Parses all the available scripts found in the resource locations - for the given group, for all ResourceManagers. - @remarks - Called as part of initialiseResourceGroup - */ - void parseResourceGroupScripts(ResourceGroup* grp); - /** Create all the pre-declared resources. - @remarks - Called as part of initialiseResourceGroup - */ - void createDeclaredResources(ResourceGroup* grp); - /** Adds a created resource to a group. */ - void addCreatedResource(ResourcePtr& res, ResourceGroup& group); - /** Get resource group */ - ResourceGroup* getResourceGroup(const String& name); - /** Drops contents of a group, leave group there, notify ResourceManagers. */ - void dropGroupContents(ResourceGroup* grp); - /** Delete a group for shutdown - don't notify ResourceManagers. */ - void deleteGroup(ResourceGroup* grp); - /// Internal find method for auto groups - ResourceGroup* findGroupContainingResourceImpl(const String& filename); - /// Internal event firing method - void fireResourceGroupScriptingStarted(const String& groupName, size_t scriptCount); - /// Internal event firing method - void fireScriptStarted(const String& scriptName, bool &skipScript); + /** Parses all the available scripts found in the resource locations + for the given group, for all ResourceManagers. + @remarks + Called as part of initialiseResourceGroup + */ + void parseResourceGroupScripts(ResourceGroup* grp); + /** Create all the pre-declared resources. + @remarks + Called as part of initialiseResourceGroup + */ + void createDeclaredResources(ResourceGroup* grp); + /** Adds a created resource to a group. */ + void addCreatedResource(ResourcePtr& res, ResourceGroup& group); + /** Get resource group */ + ResourceGroup* getResourceGroup(const String& name); + /** Drops contents of a group, leave group there, notify ResourceManagers. */ + void dropGroupContents(ResourceGroup* grp); + /** Delete a group for shutdown - don't notify ResourceManagers. */ + void deleteGroup(ResourceGroup* grp); + /// Internal find method for auto groups + ResourceGroup* findGroupContainingResourceImpl(const String& filename); + /// Internal event firing method + void fireResourceGroupScriptingStarted(const String& groupName, size_t scriptCount); + /// Internal event firing method + void fireScriptStarted(const String& scriptName, bool &skipScript); /// Internal event firing method void fireScriptEnded(const String& scriptName, bool skipped); - /// Internal event firing method - void fireResourceGroupScriptingEnded(const String& groupName); /// Internal event firing method - void fireResourceGroupLoadStarted(const String& groupName, size_t resourceCount); + void fireResourceGroupScriptingEnded(const String& groupName); + /// Internal event firing method + void fireResourceGroupLoadStarted(const String& groupName, size_t resourceCount); /// Internal event firing method void fireResourceLoadStarted(const ResourcePtr& resource); - /// Internal event firing method - void fireResourceLoadEnded(void); - /// Internal event firing method - void fireResourceGroupLoadEnded(const String& groupName); /// Internal event firing method - void fireResourceGroupPrepareStarted(const String& groupName, size_t resourceCount); + void fireResourceLoadEnded(void); + /// Internal event firing method + void fireResourceGroupLoadEnded(const String& groupName); + /// Internal event firing method + void fireResourceGroupPrepareStarted(const String& groupName, size_t resourceCount); /// Internal event firing method void fireResourcePrepareStarted(const ResourcePtr& resource); - /// Internal event firing method - void fireResourcePrepareEnded(void); - /// Internal event firing method - void fireResourceGroupPrepareEnded(const String& groupName); - /// Internal event firing method - void fireResourceCreated(const ResourcePtr& resource); - /// Internal event firing method - void fireResourceRemove(const ResourcePtr& resource); - /** Internal modification time retrieval */ - time_t resourceModifiedTime(ResourceGroup* group, const String& filename); + /// Internal event firing method + void fireResourcePrepareEnded(void); + /// Internal event firing method + void fireResourceGroupPrepareEnded(const String& groupName); + /// Internal event firing method + void fireResourceCreated(const ResourcePtr& resource); + /// Internal event firing method + void fireResourceRemove(const ResourcePtr& resource); + /** Internal modification time retrieval */ + time_t resourceModifiedTime(ResourceGroup* group, const String& filename); /** Find out if the named file exists in a group. Internal use only @param group Pointer to the resource group @@ -420,8 +420,8 @@ namespace Ogre { */ bool resourceExists(ResourceGroup* group, const String& filename); - /// Stored current group - optimisation for when bulk loading a group - ResourceGroup* mCurrentGroup; + /// Stored current group - optimisation for when bulk loading a group + ResourceGroup* mCurrentGroup; public: ResourceGroupManager(); virtual ~ResourceGroupManager(); @@ -432,125 +432,125 @@ namespace Ogre { be loaded / unloaded as a unit. For example, it might be all the resources used for the level of a game. There is always one predefined resource group called ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - which is typically used to hold all resources which do not need to - be unloaded until shutdown. There is another predefined resource + which is typically used to hold all resources which do not need to + be unloaded until shutdown. There is another predefined resource group called ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME too, which should be used by OGRE internal only, the resources created in this group aren't supposed to modify, unload or remove by user. You can create additional ones so that you can control the life of your resources in whichever way you wish. - There is one other predefined value, - ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; using this - causes the group name to be derived at load time by searching for - the resource in the resource locations of each group in turn. + There is one other predefined value, + ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; using this + causes the group name to be derived at load time by searching for + the resource in the resource locations of each group in turn. @par Once you have defined a resource group, resources which will be loaded - as part of it are defined in one of 3 ways: -
        -
      1. Manually through declareResource(); this is useful for scripted - declarations since it is entirely generalised, and does not - create Resource instances right away
      2. -
      3. Through the use of scripts; some ResourceManager subtypes have - script formats (e.g. .material, .overlay) which can be used - to declare resources
      4. -
      5. By calling ResourceManager::create to create a resource manually. - This resource will go on the list for it's group and will be loaded - and unloaded with that group
      6. -
      - You must remember to call initialiseResourceGroup if you intend to use - the first 2 types. + as part of it are defined in one of 3 ways: +
        +
      1. Manually through declareResource(); this is useful for scripted + declarations since it is entirely generalised, and does not + create Resource instances right away
      2. +
      3. Through the use of scripts; some ResourceManager subtypes have + script formats (e.g. .material, .overlay) which can be used + to declare resources
      4. +
      5. By calling ResourceManager::create to create a resource manually. + This resource will go on the list for it's group and will be loaded + and unloaded with that group
      6. +
      + You must remember to call initialiseResourceGroup if you intend to use + the first 2 types. @param name The name to give the resource group. - @param inGlobalPool if true the resource will be loaded even a different - group was requested in the load method as a parameter. + @param inGlobalPool if true the resource will be loaded even a different + group was requested in the load method as a parameter. */ void createResourceGroup(const String& name, const bool inGlobalPool = true); /** Initialises a resource group. - @remarks - After creating a resource group, adding some resource locations, and - perhaps pre-declaring some resources using declareResource(), but - before you need to use the resources in the group, you - should call this method to initialise the group. By calling this, - you are triggering the following processes: -
        -
      1. Scripts for all resource types which support scripting are - parsed from the resource locations, and resources within them are - created (but not loaded yet).
      2. -
      3. Creates all the resources which have just pre-declared using - declareResource (again, these are not loaded yet)
      4. -
      - So what this essentially does is create a bunch of unloaded Resource entries - in the respective ResourceManagers based on scripts, and resources - you've pre-declared. That means that code looking for these resources - will find them, but they won't be taking up much memory yet, until - they are either used, or they are loaded in bulk using loadResourceGroup. - Loading the resource group in bulk is entirely optional, but has the - advantage of coming with progress reporting as resources are loaded. - @par - Failure to call this method means that loadResourceGroup will do - nothing, and any resources you define in scripts will not be found. - Similarly, once you have called this method you won't be able to - pick up any new scripts or pre-declared resources, unless you - call clearResourceGroup, set up declared resources, and call this - method again. - @note - When you call Root::initialise, all resource groups that have already been - created are automatically initialised too. Therefore you do not need to - call this method for groups you define and set up before you call - Root::initialise. However, since one of the most useful features of - resource groups is to set them up after the main system initialisation - has occurred (e.g. a group per game level), you must remember to call this - method for the groups you create after this. - - @param name The name of the resource group to initialise - */ - void initialiseResourceGroup(const String& name); - - /** Initialise all resource groups which are yet to be initialised. - @see ResourceGroupManager::intialiseResourceGroup - */ - void initialiseAllResourceGroups(void); - - /** Prepares a resource group. @remarks - Prepares any created resources which are part of the named group. - Note that resources must have already been created by calling - ResourceManager::create, or declared using declareResource() or - in a script (such as .material and .overlay). The latter requires - that initialiseResourceGroup has been called. - - When this method is called, this class will callback any ResourceGroupListeners - which have been registered to update them on progress. + After creating a resource group, adding some resource locations, and + perhaps pre-declaring some resources using declareResource(), but + before you need to use the resources in the group, you + should call this method to initialise the group. By calling this, + you are triggering the following processes: +
        +
      1. Scripts for all resource types which support scripting are + parsed from the resource locations, and resources within them are + created (but not loaded yet).
      2. +
      3. Creates all the resources which have just pre-declared using + declareResource (again, these are not loaded yet)
      4. +
      + So what this essentially does is create a bunch of unloaded Resource entries + in the respective ResourceManagers based on scripts, and resources + you've pre-declared. That means that code looking for these resources + will find them, but they won't be taking up much memory yet, until + they are either used, or they are loaded in bulk using loadResourceGroup. + Loading the resource group in bulk is entirely optional, but has the + advantage of coming with progress reporting as resources are loaded. + @par + Failure to call this method means that loadResourceGroup will do + nothing, and any resources you define in scripts will not be found. + Similarly, once you have called this method you won't be able to + pick up any new scripts or pre-declared resources, unless you + call clearResourceGroup, set up declared resources, and call this + method again. + @note + When you call Root::initialise, all resource groups that have already been + created are automatically initialised too. Therefore you do not need to + call this method for groups you define and set up before you call + Root::initialise. However, since one of the most useful features of + resource groups is to set them up after the main system initialisation + has occurred (e.g. a group per game level), you must remember to call this + method for the groups you create after this. + + @param name The name of the resource group to initialise + */ + void initialiseResourceGroup(const String& name); + + /** Initialise all resource groups which are yet to be initialised. + @see ResourceGroupManager::intialiseResourceGroup + */ + void initialiseAllResourceGroups(void); + + /** Prepares a resource group. + @remarks + Prepares any created resources which are part of the named group. + Note that resources must have already been created by calling + ResourceManager::create, or declared using declareResource() or + in a script (such as .material and .overlay). The latter requires + that initialiseResourceGroup has been called. + + When this method is called, this class will callback any ResourceGroupListeners + which have been registered to update them on progress. @param name The name of the resource group to prepare. - @param prepareMainResources If true, prepares normal resources associated - with the group (you might want to set this to false if you wanted - to just prepare world geometry in bulk) - @param prepareWorldGeom If true, prepares any linked world geometry - @see ResourceGroupManager::linkWorldGeometryToResourceGroup + @param prepareMainResources If true, prepares normal resources associated + with the group (you might want to set this to false if you wanted + to just prepare world geometry in bulk) + @param prepareWorldGeom If true, prepares any linked world geometry + @see ResourceGroupManager::linkWorldGeometryToResourceGroup */ void prepareResourceGroup(const String& name, bool prepareMainResources = true, - bool prepareWorldGeom = true); + bool prepareWorldGeom = true); - /** Loads a resource group. + /** Loads a resource group. @remarks - Loads any created resources which are part of the named group. - Note that resources must have already been created by calling - ResourceManager::create, or declared using declareResource() or - in a script (such as .material and .overlay). The latter requires - that initialiseResourceGroup has been called. - - When this method is called, this class will callback any ResourceGroupListeners - which have been registered to update them on progress. + Loads any created resources which are part of the named group. + Note that resources must have already been created by calling + ResourceManager::create, or declared using declareResource() or + in a script (such as .material and .overlay). The latter requires + that initialiseResourceGroup has been called. + + When this method is called, this class will callback any ResourceGroupListeners + which have been registered to update them on progress. @param name The name of the resource group to load. - @param loadMainResources If true, loads normal resources associated - with the group (you might want to set this to false if you wanted - to just load world geometry in bulk) - @param loadWorldGeom If true, loads any linked world geometry - @see ResourceGroupManager::linkWorldGeometryToResourceGroup + @param loadMainResources If true, loads normal resources associated + with the group (you might want to set this to false if you wanted + to just load world geometry in bulk) + @param loadWorldGeom If true, loads any linked world geometry + @see ResourceGroupManager::linkWorldGeometryToResourceGroup */ void loadResourceGroup(const String& name, bool loadMainResources = true, - bool loadWorldGeom = true); + bool loadWorldGeom = true); /** Unloads a resource group. @remarks @@ -569,30 +569,30 @@ namespace Ogre { */ void unloadResourceGroup(const String& name, bool reloadableOnly = true); - /** Unload all resources which are not referenced by any other object. - @remarks - This method behaves like unloadResourceGroup, except that it only - unloads resources in the group which are not in use, ie not referenced - by other objects. This allows you to free up some memory selectively - whilst still keeping the group around (and the resources present, - just not using much memory). - @param name The name of the group to check for unreferenced resources - @param reloadableOnly If true (the default), only unloads resources - which can be subsequently automatically reloaded - */ - void unloadUnreferencedResourcesInGroup(const String& name, - bool reloadableOnly = true); - - /** Clears a resource group. - @remarks - This method unloads all resources in the group, but in addition it - removes all those resources from their ResourceManagers, and then - clears all the members from the list. That means after calling this - method, there are no resources declared as part of the named group - any more. Resource locations still persist though. + /** Unload all resources which are not referenced by any other object. + @remarks + This method behaves like unloadResourceGroup, except that it only + unloads resources in the group which are not in use, ie not referenced + by other objects. This allows you to free up some memory selectively + whilst still keeping the group around (and the resources present, + just not using much memory). + @param name The name of the group to check for unreferenced resources + @param reloadableOnly If true (the default), only unloads resources + which can be subsequently automatically reloaded + */ + void unloadUnreferencedResourcesInGroup(const String& name, + bool reloadableOnly = true); + + /** Clears a resource group. + @remarks + This method unloads all resources in the group, but in addition it + removes all those resources from their ResourceManagers, and then + clears all the members from the list. That means after calling this + method, there are no resources declared as part of the named group + any more. Resource locations still persist though. @param name The name to of the resource group to clear. - */ - void clearResourceGroup(const String& name); + */ + void clearResourceGroup(const String& name); /** Destroys a resource group, clearing it first, destroying the resources which are part of it, and then removing it from @@ -601,28 +601,28 @@ namespace Ogre { */ void destroyResourceGroup(const String& name); - /** Checks the status of a resource group. - @remarks - Looks at the state of a resource group. - If initialiseResourceGroup has been called for the resource - group return true, otherwise return false. - @param name The name to of the resource group to access. - */ - bool isResourceGroupInitialised(const String& name); - - /** Checks the status of a resource group. - @remarks - Looks at the state of a resource group. - If loadResourceGroup has been called for the resource - group return true, otherwise return false. - @param name The name to of the resource group to access. - */ - bool isResourceGroupLoaded(const String& name); - - /*** Verify if a resource group exists - @param name The name of the resource group to look for - */ - bool resourceGroupExists(const String& name); + /** Checks the status of a resource group. + @remarks + Looks at the state of a resource group. + If initialiseResourceGroup has been called for the resource + group return true, otherwise return false. + @param name The name to of the resource group to access. + */ + bool isResourceGroupInitialised(const String& name); + + /** Checks the status of a resource group. + @remarks + Looks at the state of a resource group. + If loadResourceGroup has been called for the resource + group return true, otherwise return false. + @param name The name to of the resource group to access. + */ + bool isResourceGroupLoaded(const String& name); + + /*** Verify if a resource group exists + @param name The name of the resource group to look for + */ + bool resourceGroupExists(const String& name); /** Method to add a resource location to for a given resource group. @remarks @@ -634,25 +634,25 @@ namespace Ogre { Archive factory which is providing the implementation. @param resGroup The name of the resource group for which this location is to apply. ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME is the - default group which always exists, and can + default group which always exists, and can be used for resources which are unlikely to be unloaded until application shutdown. Otherwise it must be the name of a group; if it has not already been created with createResourceGroup then it is created automatically. @param recursive Whether subdirectories will be searched for files when using - a pattern match (such as *.material), and whether subdirectories will be - indexed. This can slow down initial loading of the archive and searches. - When opening a resource you still need to use the fully qualified name, - this allows duplicate names in alternate paths. + a pattern match (such as *.material), and whether subdirectories will be + indexed. This can slow down initial loading of the archive and searches. + When opening a resource you still need to use the fully qualified name, + this allows duplicate names in alternate paths. */ void addResourceLocation(const String& name, const String& locType, const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME, bool recursive = false, bool readOnly = true); /** Removes a resource location from the search path. */ void removeResourceLocation(const String& name, - const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME); + const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME); /** Verify if a resource location exists for the given group. */ - bool resourceLocationExists(const String& name, - const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME); + bool resourceLocationExists(const String& name, + const String& resGroup = DEFAULT_RESOURCE_GROUP_NAME); /** Declares a resource to be a part of a resource group, allowing you to load and unload it as part of the group. @@ -662,14 +662,14 @@ namespace Ogre { by their group. Declaring them also allows them to be enumerated, which means events can be raised to indicate the loading progress (@see ResourceGroupListener). Note that another way of declaring - resources is to use a script specific to the resource type, if - available (e.g. .material). - @par - Declared resources are not created as Resource instances (and thus - are not available through their ResourceManager) until initialiseResourceGroup - is called, at which point all declared resources will become created - (but unloaded) Resource instances, along with any resources declared - in scripts in resource locations associated with the group. + resources is to use a script specific to the resource type, if + available (e.g. .material). + @par + Declared resources are not created as Resource instances (and thus + are not available through their ResourceManager) until initialiseResourceGroup + is called, at which point all declared resources will become created + (but unloaded) Resource instances, along with any resources declared + in scripts in resource locations associated with the group. @param name The resource name. @param resourceType The type of the resource. Ogre comes preconfigured with a number of resource types: @@ -684,13 +684,13 @@ namespace Ogre { .. but more can be added by plugin ResourceManager classes. @param groupName The name of the group to which it will belong. - @param loadParameters A list of name / value pairs which supply custom - parameters to the resource which will be required before it can - be loaded. These are specific to the resource type. + @param loadParameters A list of name / value pairs which supply custom + parameters to the resource which will be required before it can + be loaded. These are specific to the resource type. */ void declareResource(const String& name, const String& resourceType, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, - const NameValuePairList& loadParameters = NameValuePairList()); + const NameValuePairList& loadParameters = NameValuePairList()); /** Declares a resource to be a part of a resource group, allowing you to load and unload it as part of the group. @remarks @@ -734,54 +734,54 @@ namespace Ogre { const String& groupName, ManualResourceLoader* loader, const NameValuePairList& loadParameters = NameValuePairList()); /** Undeclare a resource. - @remarks - Note that this will not cause it to be unloaded + @remarks + Note that this will not cause it to be unloaded if it is already loaded, nor will it destroy a resource which has - already been created if initialiseResourceGroup has been called already. - Only unloadResourceGroup / clearResourceGroup / destroyResourceGroup - will do that. + already been created if initialiseResourceGroup has been called already. + Only unloadResourceGroup / clearResourceGroup / destroyResourceGroup + will do that. @param name The name of the resource. - @param groupName The name of the group this resource was declared in. + @param groupName The name of the group this resource was declared in. */ void undeclareResource(const String& name, const String& groupName); - /** Open a single resource by name and return a DataStream - pointing at the source of the data. - @param resourceName The name of the resource to locate. - Even if resource locations are added recursively, you - must provide a fully qualified name to this method. You - can find out the matching fully qualified names by using the - find() method if you need to. - @param groupName The name of the resource group; this determines which - locations are searched. - @param searchGroupsIfNotFound If true, if the resource is not found in - the group specified, other groups will be searched. If you're - loading a real Resource using this option, you must - also provide the resourceBeingLoaded parameter to enable the - group membership to be changed - @param resourceBeingLoaded Optional pointer to the resource being - loaded, which you should supply if you want - @return Shared pointer to data stream containing the data, will be - destroyed automatically when no longer referenced - */ - DataStreamPtr openResource(const String& resourceName, - const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, - bool searchGroupsIfNotFound = true, Resource* resourceBeingLoaded = 0); - - /** Open all resources matching a given pattern (which can contain - the character '*' as a wildcard), and return a collection of - DataStream objects on them. - @param pattern The pattern to look for. If resource locations have been - added recursively, subdirectories will be searched too so this - does not need to be fully qualified. - @param groupName The resource group; this determines which locations - are searched. - @return Shared pointer to a data stream list , will be - destroyed automatically when no longer referenced - */ - DataStreamListPtr openResources(const String& pattern, - const String& groupName = DEFAULT_RESOURCE_GROUP_NAME); - + /** Open a single resource by name and return a DataStream + pointing at the source of the data. + @param resourceName The name of the resource to locate. + Even if resource locations are added recursively, you + must provide a fully qualified name to this method. You + can find out the matching fully qualified names by using the + find() method if you need to. + @param groupName The name of the resource group; this determines which + locations are searched. + @param searchGroupsIfNotFound If true, if the resource is not found in + the group specified, other groups will be searched. If you're + loading a real Resource using this option, you must + also provide the resourceBeingLoaded parameter to enable the + group membership to be changed + @param resourceBeingLoaded Optional pointer to the resource being + loaded, which you should supply if you want + @return Shared pointer to data stream containing the data, will be + destroyed automatically when no longer referenced + */ + DataStreamPtr openResource(const String& resourceName, + const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, + bool searchGroupsIfNotFound = true, Resource* resourceBeingLoaded = 0); + + /** Open all resources matching a given pattern (which can contain + the character '*' as a wildcard), and return a collection of + DataStream objects on them. + @param pattern The pattern to look for. If resource locations have been + added recursively, subdirectories will be searched too so this + does not need to be fully qualified. + @param groupName The resource group; this determines which locations + are searched. + @return Shared pointer to a data stream list , will be + destroyed automatically when no longer referenced + */ + DataStreamListPtr openResources(const String& pattern, + const String& groupName = DEFAULT_RESOURCE_GROUP_NAME); + /** List all file or directory names in a resource group. @note This method only returns filenames, you can also retrieve other @@ -819,19 +819,19 @@ namespace Ogre { @param filename Fully qualified name of the file to test for */ bool resourceExists(const String& group, const String& filename); - + /** Find out if the named file exists in any group. @param filename Fully qualified name of the file to test for */ bool resourceExistsInAnyGroup(const String& filename); - /** Find the group in which a resource exists. - @param filename Fully qualified name of the file the resource should be - found as - @return Name of the resource group the resource was found in. An - exception is thrown if the group could not be determined. - */ - const String& findGroupContainingResource(const String& filename); + /** Find the group in which a resource exists. + @param filename Fully qualified name of the file the resource should be + found as + @return Name of the resource group the resource was found in. An + exception is thrown if the group could not be determined. + */ + const String& findGroupContainingResource(const String& filename); /** Find all files or directories matching a given pattern in a group and get some detailed information about them. @@ -845,8 +845,8 @@ namespace Ogre { FileInfoListPtr findResourceFileInfo(const String& group, const String& pattern, bool dirs = false); - /** Retrieve the modification time of a given file */ - time_t resourceModifiedTime(const String& group, const String& filename); + /** Retrieve the modification time of a given file */ + time_t resourceModifiedTime(const String& group, const String& filename); /** List all resource locations in a resource group. @param groupName The name of the group @return A list of resource locations matching the criteria @@ -861,48 +861,48 @@ namespace Ogre { */ StringVectorPtr findResourceLocation(const String& groupName, const String& pattern); - /** Create a new resource file in a given group. - @remarks - This method creates a new file in a resource group and passes you back a - writeable stream. - @param filename The name of the file to create - @param groupName The name of the group in which to create the file - @param overwrite If true, an existing file will be overwritten, if false - an error will occur if the file already exists - @param locationPattern If the resource group contains multiple locations, - then usually the file will be created in the first writable location. If you - want to be more specific, you can include a location pattern here and - only locations which match that pattern (as determined by StringUtil::match) - will be considered candidates for creation. - */ - DataStreamPtr createResource(const String& filename, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, - bool overwrite = false, const String& locationPattern = BLANKSTRING); - - /** Delete a single resource file. - @param filename The name of the file to delete. - @param groupName The name of the group in which to search - @param locationPattern If the resource group contains multiple locations, - then usually first matching file found in any location will be deleted. If you - want to be more specific, you can include a location pattern here and - only locations which match that pattern (as determined by StringUtil::match) - will be considered candidates for deletion. - */ - void deleteResource(const String& filename, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, - const String& locationPattern = BLANKSTRING); - - /** Delete all matching resource files. - @param filePattern The pattern (see StringUtil::match) of the files to delete. - @param groupName The name of the group in which to search - @param locationPattern If the resource group contains multiple locations, - then usually all matching files in any location will be deleted. If you - want to be more specific, you can include a location pattern here and - only locations which match that pattern (as determined by StringUtil::match) - will be considered candidates for deletion. - */ - void deleteMatchingResources(const String& filePattern, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, - const String& locationPattern = BLANKSTRING); - - /** Adds a ResourceGroupListener which will be called back during + /** Create a new resource file in a given group. + @remarks + This method creates a new file in a resource group and passes you back a + writeable stream. + @param filename The name of the file to create + @param groupName The name of the group in which to create the file + @param overwrite If true, an existing file will be overwritten, if false + an error will occur if the file already exists + @param locationPattern If the resource group contains multiple locations, + then usually the file will be created in the first writable location. If you + want to be more specific, you can include a location pattern here and + only locations which match that pattern (as determined by StringUtil::match) + will be considered candidates for creation. + */ + DataStreamPtr createResource(const String& filename, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, + bool overwrite = false, const String& locationPattern = BLANKSTRING); + + /** Delete a single resource file. + @param filename The name of the file to delete. + @param groupName The name of the group in which to search + @param locationPattern If the resource group contains multiple locations, + then usually first matching file found in any location will be deleted. If you + want to be more specific, you can include a location pattern here and + only locations which match that pattern (as determined by StringUtil::match) + will be considered candidates for deletion. + */ + void deleteResource(const String& filename, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, + const String& locationPattern = BLANKSTRING); + + /** Delete all matching resource files. + @param filePattern The pattern (see StringUtil::match) of the files to delete. + @param groupName The name of the group in which to search + @param locationPattern If the resource group contains multiple locations, + then usually all matching files in any location will be deleted. If you + want to be more specific, you can include a location pattern here and + only locations which match that pattern (as determined by StringUtil::match) + will be considered candidates for deletion. + */ + void deleteMatchingResources(const String& filePattern, const String& groupName = DEFAULT_RESOURCE_GROUP_NAME, + const String& locationPattern = BLANKSTRING); + + /** Adds a ResourceGroupListener which will be called back during resource loading events. */ void addResourceGroupListener(ResourceGroupListener* l); @@ -942,14 +942,14 @@ namespace Ogre { */ void unlinkWorldGeometryFromResourceGroup(const String& group); - /** Checks the status of a resource group. - @remarks - Looks at the state of a resource group. - If loadResourceGroup has been called for the resource - group return true, otherwise return false. - @param name The name to of the resource group to access. - */ - bool isResourceGroupInGlobalPool(const String& name); + /** Checks the status of a resource group. + @remarks + Looks at the state of a resource group. + If loadResourceGroup has been called for the resource + group return true, otherwise return false. + @param name The name to of the resource group to access. + */ + bool isResourceGroupInGlobalPool(const String& name); /** Shutdown all ResourceManagers, performed as part of clean-up. */ void shutdownAll(void); @@ -958,30 +958,30 @@ namespace Ogre { /** Internal method for registering a ResourceManager (which should be a singleton). Creators of plugins can register new ResourceManagers this way if they wish. - @remarks - ResourceManagers that wish to parse scripts must also call - _registerScriptLoader. + @remarks + ResourceManagers that wish to parse scripts must also call + _registerScriptLoader. @param resourceType String identifying the resource type, must be unique. @param rm Pointer to the ResourceManager instance. */ void _registerResourceManager(const String& resourceType, ResourceManager* rm); /** Internal method for unregistering a ResourceManager. - @remarks - ResourceManagers that wish to parse scripts must also call - _unregisterScriptLoader. + @remarks + ResourceManagers that wish to parse scripts must also call + _unregisterScriptLoader. @param resourceType String identifying the resource type. */ void _unregisterResourceManager(const String& resourceType); - /** Get an iterator over the registered resource managers. - */ - ResourceManagerIterator getResourceManagerIterator() - { return ResourceManagerIterator( - mResourceManagerMap.begin(), mResourceManagerMap.end()); } + /** Get an iterator over the registered resource managers. + */ + ResourceManagerIterator getResourceManagerIterator() + { return ResourceManagerIterator( + mResourceManagerMap.begin(), mResourceManagerMap.end()); } /** Internal method for registering a ScriptLoader. - @remarks ScriptLoaders parse scripts when resource groups are initialised. + @remarks ScriptLoaders parse scripts when resource groups are initialised. @param su Pointer to the ScriptLoader instance. */ void _registerScriptLoader(ScriptLoader* su); @@ -991,35 +991,35 @@ namespace Ogre { */ void _unregisterScriptLoader(ScriptLoader* su); - /** Method used to directly query for registered script loaders. - @param pattern The specific script pattern (e.g. *.material) the script loader handles - */ - ScriptLoader *_findScriptLoader(const String &pattern); + /** Method used to directly query for registered script loaders. + @param pattern The specific script pattern (e.g. *.material) the script loader handles + */ + ScriptLoader *_findScriptLoader(const String &pattern); - /** Internal method for getting a registered ResourceManager. - @param resourceType String identifying the resource type. - */ - ResourceManager* _getResourceManager(const String& resourceType); + /** Internal method for getting a registered ResourceManager. + @param resourceType String identifying the resource type. + */ + ResourceManager* _getResourceManager(const String& resourceType); - /** Internal method called by ResourceManager when a resource is created. - @param res Weak reference to resource - */ - void _notifyResourceCreated(ResourcePtr& res); + /** Internal method called by ResourceManager when a resource is created. + @param res Weak reference to resource + */ + void _notifyResourceCreated(ResourcePtr& res); - /** Internal method called by ResourceManager when a resource is removed. - @param res Weak reference to resource - */ - void _notifyResourceRemoved(ResourcePtr& res); + /** Internal method called by ResourceManager when a resource is removed. + @param res Weak reference to resource + */ + void _notifyResourceRemoved(ResourcePtr& res); - /** Internal method to notify the group manager that a resource has - changed group (only applicable for autodetect group) */ - void _notifyResourceGroupChanged(const String& oldGroup, Resource* res); + /** Internal method to notify the group manager that a resource has + changed group (only applicable for autodetect group) */ + void _notifyResourceGroupChanged(const String& oldGroup, Resource* res); - /** Internal method called by ResourceManager when all resources - for that manager are removed. - @param manager Pointer to the manager for which all resources are being removed - */ - void _notifyAllResourcesRemoved(ResourceManager* manager); + /** Internal method called by ResourceManager when all resources + for that manager are removed. + @param manager Pointer to the manager for which all resources are being removed + */ + void _notifyAllResourcesRemoved(ResourceManager* manager); /** Notify this manager that one stage of world geometry loading has been started. @@ -1038,32 +1038,32 @@ namespace Ogre { */ void _notifyWorldGeometryStageEnded(void); - /** Get a list of the currently defined resource groups. - @note This method intentionally returns a copy rather than a reference in - order to avoid any contention issues in multithreaded applications. - @return A copy of list of currently defined groups. - */ - StringVector getResourceGroups(void); - /** Get the list of resource declarations for the specified group name. - @note This method intentionally returns a copy rather than a reference in - order to avoid any contention issues in multithreaded applications. - @param groupName The name of the group - @return A copy of list of currently defined resources. - */ - ResourceDeclarationList getResourceDeclarationList(const String& groupName); - - /** Get the list of resource locations for the specified group name. - @param groupName The name of the group - @return The list of resource locations associated with the given group. - */ - const LocationList& getResourceLocationList(const String& groupName); - - /// Sets a new loading listener - void setLoadingListener(ResourceLoadingListener *listener); - /// Returns the current loading listener - ResourceLoadingListener *getLoadingListener(); - - /** Override standard Singleton retrieval. + /** Get a list of the currently defined resource groups. + @note This method intentionally returns a copy rather than a reference in + order to avoid any contention issues in multithreaded applications. + @return A copy of list of currently defined groups. + */ + StringVector getResourceGroups(void); + /** Get the list of resource declarations for the specified group name. + @note This method intentionally returns a copy rather than a reference in + order to avoid any contention issues in multithreaded applications. + @param groupName The name of the group + @return A copy of list of currently defined resources. + */ + ResourceDeclarationList getResourceDeclarationList(const String& groupName); + + /** Get the list of resource locations for the specified group name. + @param groupName The name of the group + @return The list of resource locations associated with the given group. + */ + const LocationList& getResourceLocationList(const String& groupName); + + /// Sets a new loading listener + void setLoadingListener(ResourceLoadingListener *listener); + /// Returns the current loading listener + ResourceLoadingListener *getLoadingListener(); + + /** Override standard Singleton retrieval. @remarks Why do we do this? Well, it's because the Singleton implementation is in a .h file, which means it gets compiled @@ -1097,8 +1097,8 @@ namespace Ogre { static ResourceGroupManager* getSingletonPtr(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreResourceManager.h b/OgreMain/include/OgreResourceManager.h index e1fecd31833..c340d7820ca 100644 --- a/OgreMain/include/OgreResourceManager.h +++ b/OgreMain/include/OgreResourceManager.h @@ -41,59 +41,59 @@ namespace Ogre { /** Template class describing a simple pool of items. */ - template - class Pool - { - protected: - typedef typename list::type ItemList; - ItemList mItems; - OGRE_AUTO_MUTEX; - public: - Pool() {} - virtual ~Pool() {} - - /** Get the next item from the pool. + template + class Pool + { + protected: + typedef typename list::type ItemList; + ItemList mItems; + OGRE_AUTO_MUTEX; + public: + Pool() {} + virtual ~Pool() {} + + /** Get the next item from the pool. @return pair indicating whether there was a free item, and the item if so */ - virtual std::pair removeItem() - { + virtual std::pair removeItem() + { OGRE_LOCK_AUTO_MUTEX; - std::pair ret; - if (mItems.empty()) - { - ret.first = false; - } - else - { - ret.first = true; - ret.second = mItems.front(); - mItems.pop_front(); - } - return ret; - } - - /** Add a new item to the pool. + std::pair ret; + if (mItems.empty()) + { + ret.first = false; + } + else + { + ret.first = true; + ret.second = mItems.front(); + mItems.pop_front(); + } + return ret; + } + + /** Add a new item to the pool. */ - virtual void addItem(const T& i) - { + virtual void addItem(const T& i) + { OGRE_LOCK_AUTO_MUTEX; - mItems.push_front(i); - } - /// Clear the pool - virtual void clear() - { + mItems.push_front(i); + } + /// Clear the pool + virtual void clear() + { OGRE_LOCK_AUTO_MUTEX; - mItems.clear(); - } - }; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Defines a generic resource handler. + mItems.clear(); + } + }; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Defines a generic resource handler. @remarks A resource manager is responsible for managing a pool of resources of a particular type. It must index them, look @@ -104,20 +104,20 @@ namespace Ogre { Resource managers use a priority system to determine what can be unloaded, and a Least Recently Used (LRU) policy within resources of the same priority. - @par - Resources can be loaded using the generalised load interface, - and they can be unloaded and removed. In addition, each - subclass of ResourceManager will likely define custom 'load' methods - which take explicit parameters depending on the kind of resource - being created. - @note - Resources can be loaded and unloaded through the Resource class, - but they can only be removed (and thus eventually destroyed) using - their parent ResourceManager. + @par + Resources can be loaded using the generalised load interface, + and they can be unloaded and removed. In addition, each + subclass of ResourceManager will likely define custom 'load' methods + which take explicit parameters depending on the kind of resource + being created. + @note + Resources can be loaded and unloaded through the Resource class, + but they can only be removed (and thus eventually destroyed) using + their parent ResourceManager. @note If OGRE_THREAD_SUPPORT is 1, this class is thread-safe. */ - class _OgreExport ResourceManager : public ScriptLoader, public ResourceAlloc + class _OgreExport ResourceManager : public ScriptLoader, public ResourceAlloc { public: OGRE_AUTO_MUTEX; // public to allow external locking @@ -127,19 +127,19 @@ namespace Ogre { /** Creates a new blank resource, but does not immediately load it. @remarks Resource managers handle disparate types of resources, so if you want - to get at the detailed interface of this resource, you'll have to - cast the result to the subclass you know you're creating. - @param name The unique name of the resource - @param group The name of the resource group to attach this new resource to - @param isManual Is this resource manually loaded? If so, you should really - populate the loader parameter in order that the load process - can call the loader back when loading is required. - @param loader Pointer to a ManualLoader implementation which will be called - when the Resource wishes to load (should be supplied if you set - isManual to true). You can in fact leave this parameter null - if you wish, but the Resource will never be able to reload if - anything ever causes it to unload. Therefore provision of a proper - ManualLoader instance is strongly recommended. + to get at the detailed interface of this resource, you'll have to + cast the result to the subclass you know you're creating. + @param name The unique name of the resource + @param group The name of the resource group to attach this new resource to + @param isManual Is this resource manually loaded? If so, you should really + populate the loader parameter in order that the load process + can call the loader back when loading is required. + @param loader Pointer to a ManualLoader implementation which will be called + when the Resource wishes to load (should be supplied if you set + isManual to true). You can in fact leave this parameter null + if you wish, but the Resource will never be able to reload if + anything ever causes it to unload. Therefore provision of a proper + ManualLoader instance is strongly recommended. @param createParams If any parameters are required to create an instance, they should be supplied here as name / value pairs */ @@ -147,25 +147,25 @@ namespace Ogre { bool isManual = false, ManualResourceLoader* loader = 0, const NameValuePairList* createParams = 0); - typedef std::pair ResourceCreateOrRetrieveResult; - /** Create a new resource, or retrieve an existing one with the same - name if it already exists. - @remarks - This method performs the same task as calling getByName() followed - by create() if that returns null. The advantage is that it does it - in one call so there are no race conditions if using multiple - threads that could cause getByName() to return null, but create() to - fail because another thread created a resource in between. - @see ResourceManager::createResource - @see ResourceManager::getResourceByName - @return A pair, the first element being the pointer, and the second being - an indicator specifying whether the resource was newly created. - */ - virtual ResourceCreateOrRetrieveResult createOrRetrieve(const String& name, - const String& group, bool isManual = false, - ManualResourceLoader* loader = 0, - const NameValuePairList* createParams = 0); - + typedef std::pair ResourceCreateOrRetrieveResult; + /** Create a new resource, or retrieve an existing one with the same + name if it already exists. + @remarks + This method performs the same task as calling getByName() followed + by create() if that returns null. The advantage is that it does it + in one call so there are no race conditions if using multiple + threads that could cause getByName() to return null, but create() to + fail because another thread created a resource in between. + @see ResourceManager::createResource + @see ResourceManager::getResourceByName + @return A pair, the first element being the pointer, and the second being + an indicator specifying whether the resource was newly created. + */ + virtual ResourceCreateOrRetrieveResult createOrRetrieve(const String& name, + const String& group, bool isManual = false, + ManualResourceLoader* loader = 0, + const NameValuePairList* createParams = 0); + /** Set a limit on the amount of memory this resource handler may use. @remarks If, when asked to load a new resource, the manager believes it will exceed this memory @@ -179,55 +179,55 @@ namespace Ogre { */ virtual size_t getMemoryBudget(void) const; - /** Gets the current memory usage, in bytes. */ - virtual size_t getMemoryUsage(void) const { return mMemoryUsage.get(); } - - /** Unloads a single resource by name. - @remarks - Unloaded resources are not removed, they simply free up their memory - as much as they can and wait to be reloaded. - @see ResourceGroupManager for unloading of resource groups. - */ - virtual void unload(const String& name); - - /** Unloads a single resource by handle. - @remarks - Unloaded resources are not removed, they simply free up their memory - as much as they can and wait to be reloaded. - @see ResourceGroupManager for unloading of resource groups. - */ - virtual void unload(ResourceHandle handle); - - /** Unloads all resources. - @remarks - Unloaded resources are not removed, they simply free up their memory - as much as they can and wait to be reloaded. - @see ResourceGroupManager for unloading of resource groups. - @param reloadableOnly If true (the default), only unload the resource that + /** Gets the current memory usage, in bytes. */ + virtual size_t getMemoryUsage(void) const { return mMemoryUsage.get(); } + + /** Unloads a single resource by name. + @remarks + Unloaded resources are not removed, they simply free up their memory + as much as they can and wait to be reloaded. + @see ResourceGroupManager for unloading of resource groups. + */ + virtual void unload(const String& name); + + /** Unloads a single resource by handle. + @remarks + Unloaded resources are not removed, they simply free up their memory + as much as they can and wait to be reloaded. + @see ResourceGroupManager for unloading of resource groups. + */ + virtual void unload(ResourceHandle handle); + + /** Unloads all resources. + @remarks + Unloaded resources are not removed, they simply free up their memory + as much as they can and wait to be reloaded. + @see ResourceGroupManager for unloading of resource groups. + @param reloadableOnly If true (the default), only unload the resource that is reloadable. Because some resources isn't reloadable, they will be - unloaded but can't load them later. Thus, you might not want to them - unloaded. Or, you might unload all of them, and then populate them - manually later. - @see Resource::isReloadable for resource is reloadable. - */ - virtual void unloadAll(bool reloadableOnly = true); - - /** Caused all currently loaded resources to be reloaded. - @remarks - All resources currently being held in this manager which are also - marked as currently loaded will be unloaded, then loaded again. - @param reloadableOnly If true (the default), only reload the resource that + unloaded but can't load them later. Thus, you might not want to them + unloaded. Or, you might unload all of them, and then populate them + manually later. + @see Resource::isReloadable for resource is reloadable. + */ + virtual void unloadAll(bool reloadableOnly = true); + + /** Caused all currently loaded resources to be reloaded. + @remarks + All resources currently being held in this manager which are also + marked as currently loaded will be unloaded, then loaded again. + @param reloadableOnly If true (the default), only reload the resource that is reloadable. Because some resources isn't reloadable, they will be - unloaded but can't loaded again. Thus, you might not want to them - unloaded. Or, you might unload all of them, and then populate them - manually later. - @see Resource::isReloadable for resource is reloadable. - */ - virtual void reloadAll(bool reloadableOnly = true); - - /** Unload all resources which are not referenced by any other object. - @remarks - This method behaves like unloadAll, except that it only unloads resources + unloaded but can't loaded again. Thus, you might not want to them + unloaded. Or, you might unload all of them, and then populate them + manually later. + @see Resource::isReloadable for resource is reloadable. + */ + virtual void reloadAll(bool reloadableOnly = true); + + /** Unload all resources which are not referenced by any other object. + @remarks + This method behaves like unloadAll, except that it only unloads resources which are not in use, ie not referenced by other objects. This allows you to free up some memory selectively whilst still keeping the group around (and the resources present, just not using much memory). @@ -236,35 +236,35 @@ namespace Ogre { (e.g. Entity held pointer to SubMesh), in this case, unload or reload that resource will cause dangerous pointer access. Use this function instead of unloadAll allows you avoid fail in those situations. - @param reloadableOnly If true (the default), only unloads resources - which can be subsequently automatically reloaded. - */ - virtual void unloadUnreferencedResources(bool reloadableOnly = true); + @param reloadableOnly If true (the default), only unloads resources + which can be subsequently automatically reloaded. + */ + virtual void unloadUnreferencedResources(bool reloadableOnly = true); - /** Caused all currently loaded but not referenced by any other object + /** Caused all currently loaded but not referenced by any other object resources to be reloaded. - @remarks - This method behaves like reloadAll, except that it only reloads resources + @remarks + This method behaves like reloadAll, except that it only reloads resources which are not in use, i.e. not referenced by other objects. @par Some referenced resource may exists 'weak' pointer to their sub-components (e.g. Entity held pointer to SubMesh), in this case, unload or reload that resource will cause dangerous pointer access. Use this function instead of reloadAll allows you avoid fail in those situations. - @param reloadableOnly If true (the default), only reloads resources - which can be subsequently automatically reloaded. - */ - virtual void reloadUnreferencedResources(bool reloadableOnly = true); - - /** Remove a single resource. - @remarks - Removes a single resource, meaning it will be removed from the list - of valid resources in this manager, also causing it to be unloaded. - @note - The word 'Destroy' is not used here, since - if any other pointers are referring to this resource, it will persist - until they have finished with it; however to all intents and purposes - it no longer exists and will likely get destroyed imminently. + @param reloadableOnly If true (the default), only reloads resources + which can be subsequently automatically reloaded. + */ + virtual void reloadUnreferencedResources(bool reloadableOnly = true); + + /** Remove a single resource. + @remarks + Removes a single resource, meaning it will be removed from the list + of valid resources in this manager, also causing it to be unloaded. + @note + The word 'Destroy' is not used here, since + if any other pointers are referring to this resource, it will persist + until they have finished with it; however to all intents and purposes + it no longer exists and will likely get destroyed imminently. @note If you do have shared pointers to resources hanging around after the ResourceManager is destroyed, you may get problems on destruction of @@ -272,18 +272,18 @@ namespace Ogre { it is a plugin). If you find you get problems on shutdown in the destruction of resources, try making sure you release all your shared pointers before you shutdown OGRE. - */ - virtual void remove(ResourcePtr& r); + */ + virtual void remove(ResourcePtr& r); /** Remove a single resource by name. - @remarks - Removes a single resource, meaning it will be removed from the list - of valid resources in this manager, also causing it to be unloaded. - @note - The word 'Destroy' is not used here, since - if any other pointers are referring to this resource, it will persist - until they have finished with it; however to all intents and purposes - it no longer exists and will likely get destroyed imminently. + @remarks + Removes a single resource, meaning it will be removed from the list + of valid resources in this manager, also causing it to be unloaded. + @note + The word 'Destroy' is not used here, since + if any other pointers are referring to this resource, it will persist + until they have finished with it; however to all intents and purposes + it no longer exists and will likely get destroyed imminently. @note If you do have shared pointers to resources hanging around after the ResourceManager is destroyed, you may get problems on destruction of @@ -291,18 +291,18 @@ namespace Ogre { it is a plugin). If you find you get problems on shutdown in the destruction of resources, try making sure you release all your shared pointers before you shutdown OGRE. - */ - virtual void remove(const String& name); - - /** Remove a single resource by handle. - @remarks - Removes a single resource, meaning it will be removed from the list - of valid resources in this manager, also causing it to be unloaded. - @note - The word 'Destroy' is not used here, since - if any other pointers are referring to this resource, it will persist - until they have finished with it; however to all intents and purposes - it no longer exists and will likely get destroyed imminently. + */ + virtual void remove(const String& name); + + /** Remove a single resource by handle. + @remarks + Removes a single resource, meaning it will be removed from the list + of valid resources in this manager, also causing it to be unloaded. + @note + The word 'Destroy' is not used here, since + if any other pointers are referring to this resource, it will persist + until they have finished with it; however to all intents and purposes + it no longer exists and will likely get destroyed imminently. @note If you do have shared pointers to resources hanging around after the ResourceManager is destroyed, you may get problems on destruction of @@ -310,14 +310,14 @@ namespace Ogre { it is a plugin). If you find you get problems on shutdown in the destruction of resources, try making sure you release all your shared pointers before you shutdown OGRE. - */ - virtual void remove(ResourceHandle handle); - /** Removes all resources. - @note - The word 'Destroy' is not used here, since - if any other pointers are referring to these resources, they will persist - until they have been finished with; however to all intents and purposes - the resources no longer exist and will get destroyed imminently. + */ + virtual void remove(ResourceHandle handle); + /** Removes all resources. + @note + The word 'Destroy' is not used here, since + if any other pointers are referring to these resources, they will persist + until they have been finished with; however to all intents and purposes + the resources no longer exist and will get destroyed imminently. @note If you do have shared pointers to resources hanging around after the ResourceManager is destroyed, you may get problems on destruction of @@ -328,9 +328,9 @@ namespace Ogre { */ virtual void removeAll(void); - /** Remove all resources which are not referenced by any other object. - @remarks - This method behaves like removeAll, except that it only removes resources + /** Remove all resources which are not referenced by any other object. + @remarks + This method behaves like removeAll, except that it only removes resources which are not in use, ie not referenced by other objects. This allows you to free up some memory selectively whilst still keeping the group around (and the resources present, just not using much memory). @@ -339,10 +339,10 @@ namespace Ogre { (e.g. Entity held pointer to SubMesh), in this case, remove or reload that resource will cause dangerous pointer access. Use this function instead of removeAll allows you avoid fail in those situations. - @param reloadableOnly If true (the default), only removes resources - which can be subsequently automatically reloaded. - */ - virtual void removeUnreferencedResources(bool reloadableOnly = true); + @param reloadableOnly If true (the default), only removes resources + which can be subsequently automatically reloaded. + */ + virtual void removeUnreferencedResources(bool reloadableOnly = true); /** Retrieves a pointer to a resource by name, or null if the resource does not exist. */ @@ -350,116 +350,116 @@ namespace Ogre { /** Retrieves a pointer to a resource by handle, or null if the resource does not exist. */ virtual ResourcePtr getByHandle(ResourceHandle handle); - - /// Returns whether the named resource exists in this manager - virtual bool resourceExists(const String& name) - { - return !getResourceByName(name).isNull(); - } - /// Returns whether a resource with the given handle exists in this manager - virtual bool resourceExists(ResourceHandle handle) - { - return !getByHandle(handle).isNull(); - } - - /** Notify this manager that a resource which it manages has been - 'touched', i.e. used. - */ - virtual void _notifyResourceTouched(Resource* res); - - /** Notify this manager that a resource which it manages has been - loaded. - */ - virtual void _notifyResourceLoaded(Resource* res); - - /** Notify this manager that a resource which it manages has been - unloaded. - */ - virtual void _notifyResourceUnloaded(Resource* res); - - /** Generic prepare method, used to create a Resource specific to this - ResourceManager without using one of the specialised 'prepare' methods - (containing per-Resource-type parameters). - @param name The name of the Resource - @param group The resource group to which this resource will belong - @param isManual Is the resource to be manually loaded? If so, you should - provide a value for the loader parameter - @param loader The manual loader which is to perform the required actions - when this resource is loaded; only applicable when you specify true - for the previous parameter + + /// Returns whether the named resource exists in this manager + virtual bool resourceExists(const String& name) + { + return !getResourceByName(name).isNull(); + } + /// Returns whether a resource with the given handle exists in this manager + virtual bool resourceExists(ResourceHandle handle) + { + return !getByHandle(handle).isNull(); + } + + /** Notify this manager that a resource which it manages has been + 'touched', i.e. used. + */ + virtual void _notifyResourceTouched(Resource* res); + + /** Notify this manager that a resource which it manages has been + loaded. + */ + virtual void _notifyResourceLoaded(Resource* res); + + /** Notify this manager that a resource which it manages has been + unloaded. + */ + virtual void _notifyResourceUnloaded(Resource* res); + + /** Generic prepare method, used to create a Resource specific to this + ResourceManager without using one of the specialised 'prepare' methods + (containing per-Resource-type parameters). + @param name The name of the Resource + @param group The resource group to which this resource will belong + @param isManual Is the resource to be manually loaded? If so, you should + provide a value for the loader parameter + @param loader The manual loader which is to perform the required actions + when this resource is loaded; only applicable when you specify true + for the previous parameter @param loadParams Optional pointer to a list of name/value pairs containing loading parameters for this type of resource. - @param backgroundThread Optional boolean which lets the load routine know if it - is being run on the background resource loading thread - */ - virtual ResourcePtr prepare(const String& name, + @param backgroundThread Optional boolean which lets the load routine know if it + is being run on the background resource loading thread + */ + virtual ResourcePtr prepare(const String& name, const String& group, bool isManual = false, - ManualResourceLoader* loader = 0, const NameValuePairList* loadParams = 0, - bool backgroundThread = false); - - /** Generic load method, used to create a Resource specific to this - ResourceManager without using one of the specialised 'load' methods - (containing per-Resource-type parameters). - @param name The name of the Resource - @param group The resource group to which this resource will belong - @param isManual Is the resource to be manually loaded? If so, you should - provide a value for the loader parameter - @param loader The manual loader which is to perform the required actions - when this resource is loaded; only applicable when you specify true - for the previous parameter + ManualResourceLoader* loader = 0, const NameValuePairList* loadParams = 0, + bool backgroundThread = false); + + /** Generic load method, used to create a Resource specific to this + ResourceManager without using one of the specialised 'load' methods + (containing per-Resource-type parameters). + @param name The name of the Resource + @param group The resource group to which this resource will belong + @param isManual Is the resource to be manually loaded? If so, you should + provide a value for the loader parameter + @param loader The manual loader which is to perform the required actions + when this resource is loaded; only applicable when you specify true + for the previous parameter @param loadParams Optional pointer to a list of name/value pairs containing loading parameters for this type of resource. - @param backgroundThread Optional boolean which lets the load routine know if it - is being run on the background resource loading thread - */ - virtual ResourcePtr load(const String& name, + @param backgroundThread Optional boolean which lets the load routine know if it + is being run on the background resource loading thread + */ + virtual ResourcePtr load(const String& name, const String& group, bool isManual = false, - ManualResourceLoader* loader = 0, const NameValuePairList* loadParams = 0, - bool backgroundThread = false); - - /** Gets the file patterns which should be used to find scripts for this - ResourceManager. - @remarks - Some resource managers can read script files in order to define - resources ahead of time. These resources are added to the available - list inside the manager, but none are loaded initially. This allows - you to load the items that are used on demand, or to load them all - as a group if you wish (through ResourceGroupManager). - @par - This method lets you determine the file pattern which will be used - to identify scripts intended for this manager. - @return - A list of file patterns, in the order they should be searched in. - @see isScriptingSupported, parseScript - */ - virtual const StringVector& getScriptPatterns(void) const { return mScriptPatterns; } - - /** Parse the definition of a set of resources from a script file. - @remarks - Some resource managers can read script files in order to define - resources ahead of time. These resources are added to the available - list inside the manager, but none are loaded initially. This allows - you to load the items that are used on demand, or to load them all - as a group if you wish (through ResourceGroupManager). - @param stream Weak reference to a data stream which is the source of the script - @param groupName The name of the resource group that resources which are - parsed are to become a member of. If this group is loaded or unloaded, - then the resources discovered in this script will be loaded / unloaded - with it. - */ - virtual void parseScript(DataStreamPtr& stream, const String& groupName) + ManualResourceLoader* loader = 0, const NameValuePairList* loadParams = 0, + bool backgroundThread = false); + + /** Gets the file patterns which should be used to find scripts for this + ResourceManager. + @remarks + Some resource managers can read script files in order to define + resources ahead of time. These resources are added to the available + list inside the manager, but none are loaded initially. This allows + you to load the items that are used on demand, or to load them all + as a group if you wish (through ResourceGroupManager). + @par + This method lets you determine the file pattern which will be used + to identify scripts intended for this manager. + @return + A list of file patterns, in the order they should be searched in. + @see isScriptingSupported, parseScript + */ + virtual const StringVector& getScriptPatterns(void) const { return mScriptPatterns; } + + /** Parse the definition of a set of resources from a script file. + @remarks + Some resource managers can read script files in order to define + resources ahead of time. These resources are added to the available + list inside the manager, but none are loaded initially. This allows + you to load the items that are used on demand, or to load them all + as a group if you wish (through ResourceGroupManager). + @param stream Weak reference to a data stream which is the source of the script + @param groupName The name of the resource group that resources which are + parsed are to become a member of. If this group is loaded or unloaded, + then the resources discovered in this script will be loaded / unloaded + with it. + */ + virtual void parseScript(DataStreamPtr& stream, const String& groupName) { (void)stream; (void)groupName; } - /** Gets the relative loading order of resources of this type. - @remarks - There are dependencies between some kinds of resource in terms of loading - order, and this value enumerates that. Higher values load later during - bulk loading tasks. - */ - virtual Real getLoadingOrder(void) const { return mLoadOrder; } + /** Gets the relative loading order of resources of this type. + @remarks + There are dependencies between some kinds of resource in terms of loading + order, and this value enumerates that. Higher values load later during + bulk loading tasks. + */ + virtual Real getLoadingOrder(void) const { return mLoadOrder; } - /** Gets a string identifying the type of resource this manager handles. */ - const String& getResourceType(void) const { return mResourceType; } + /** Gets a string identifying the type of resource this manager handles. */ + const String& getResourceType(void) const { return mResourceType; } /** Sets whether this manager and its resources habitually produce log output */ virtual void setVerbose(bool v) { mVerbose = v; } @@ -467,32 +467,32 @@ namespace Ogre { /** Gets whether this manager and its resources habitually produce log output */ virtual bool getVerbose(void) { return mVerbose; } - /** Definition of a pool of resources, which users can use to reuse similar - resources many times without destroying and recreating them. - @remarks - This is a simple utility class which allows the reuse of resources - between code which has a changing need for them. For example, - */ - class _OgreExport ResourcePool : public Pool, public ResourceAlloc - { - protected: - String mName; - public: - ResourcePool(const String& name); - ~ResourcePool(); - /// Get the name of the pool - const String& getName() const; - void clear(); - }; - - /// Create a resource pool, or reuse one that already exists - ResourcePool* getResourcePool(const String& name); - /// Destroy a resource pool - void destroyResourcePool(ResourcePool* pool); - /// Destroy a resource pool - void destroyResourcePool(const String& name); - /// destroy all pools - void destroyAllResourcePools(); + /** Definition of a pool of resources, which users can use to reuse similar + resources many times without destroying and recreating them. + @remarks + This is a simple utility class which allows the reuse of resources + between code which has a changing need for them. For example, + */ + class _OgreExport ResourcePool : public Pool, public ResourceAlloc + { + protected: + String mName; + public: + ResourcePool(const String& name); + ~ResourcePool(); + /// Get the name of the pool + const String& getName() const; + void clear(); + }; + + /// Create a resource pool, or reuse one that already exists + ResourcePool* getResourcePool(const String& name); + /// Destroy a resource pool + void destroyResourcePool(ResourcePool* pool); + /// Destroy a resource pool + void destroyResourcePool(const String& name); + /// destroy all pools + void destroyAllResourcePools(); @@ -502,61 +502,61 @@ namespace Ogre { /** Allocates the next handle. */ ResourceHandle getNextHandle(void); - /** Create a new resource instance compatible with this manager (no custom - parameters are populated at this point). - @remarks - Subclasses must override this method and create a subclass of Resource. - @param name The unique name of the resource - @param group The name of the resource group to attach this new resource to - @param isManual Is this resource manually loaded? If so, you should really - populate the loader parameter in order that the load process - can call the loader back when loading is required. - @param loader Pointer to a ManualLoader implementation which will be called - when the Resource wishes to load (should be supplied if you set - isManual to true). You can in fact leave this parameter null - if you wish, but the Resource will never be able to reload if - anything ever causes it to unload. Therefore provision of a proper - ManualLoader instance is strongly recommended. + /** Create a new resource instance compatible with this manager (no custom + parameters are populated at this point). + @remarks + Subclasses must override this method and create a subclass of Resource. + @param name The unique name of the resource + @param group The name of the resource group to attach this new resource to + @param isManual Is this resource manually loaded? If so, you should really + populate the loader parameter in order that the load process + can call the loader back when loading is required. + @param loader Pointer to a ManualLoader implementation which will be called + when the Resource wishes to load (should be supplied if you set + isManual to true). You can in fact leave this parameter null + if you wish, but the Resource will never be able to reload if + anything ever causes it to unload. Therefore provision of a proper + ManualLoader instance is strongly recommended. @param createParams If any parameters are required to create an instance, they should be supplied here as name / value pairs. These do not need to be set on the instance (handled elsewhere), just used if required to differentiate which concrete class is created. - */ - virtual Resource* createImpl(const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, + */ + virtual Resource* createImpl(const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* createParams) = 0; - /** Add a newly created resource to the manager (note weak reference) */ - virtual void addImpl( ResourcePtr& res ); - /** Remove a resource from this manager; remove it from the lists. */ - virtual void removeImpl( ResourcePtr& res ); - /** Checks memory usage and pages out if required. This is automatically done after a new resource is loaded. - */ - virtual void checkUsage(void); + /** Add a newly created resource to the manager (note weak reference) */ + virtual void addImpl( ResourcePtr& res ); + /** Remove a resource from this manager; remove it from the lists. */ + virtual void removeImpl( ResourcePtr& res ); + /** Checks memory usage and pages out if required. This is automatically done after a new resource is loaded. + */ + virtual void checkUsage(void); public: - typedef HashMap< String, ResourcePtr > ResourceMap; - typedef HashMap< String, ResourceMap > ResourceWithGroupMap; - typedef map::type ResourceHandleMap; + typedef HashMap< String, ResourcePtr > ResourceMap; + typedef HashMap< String, ResourceMap > ResourceWithGroupMap; + typedef map::type ResourceHandleMap; protected: ResourceHandleMap mResourcesByHandle; ResourceMap mResources; - ResourceWithGroupMap mResourcesWithGroup; + ResourceWithGroupMap mResourcesWithGroup; size_t mMemoryBudget; /// In bytes AtomicScalar mNextHandle; AtomicScalar mMemoryUsage; /// In bytes bool mVerbose; - // IMPORTANT - all subclasses must populate the fields below + // IMPORTANT - all subclasses must populate the fields below - /// Patterns to use to look for scripts if supported (e.g. *.overlay) - StringVector mScriptPatterns; - /// Loading order relative to other managers, higher is later - Real mLoadOrder; - /// String identifying the resource type this manager handles - String mResourceType; + /// Patterns to use to look for scripts if supported (e.g. *.overlay) + StringVector mScriptPatterns; + /// Loading order relative to other managers, higher is later + Real mLoadOrder; + /// String identifying the resource type this manager handles + String mResourceType; public: typedef MapIterator ResourceMapIterator; @@ -569,13 +569,13 @@ namespace Ogre { return ResourceMapIterator(mResourcesByHandle.begin(), mResourcesByHandle.end()); } - protected: - typedef map::type ResourcePoolMap; - ResourcePoolMap mResourcePoolMap; + protected: + typedef map::type ResourcePoolMap; + ResourcePoolMap mResourcePoolMap; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreRibbonTrail.h b/OgreMain/include/OgreRibbonTrail.h index 88d4bfb4e98..40e8e6baa3b 100644 --- a/OgreMain/include/OgreRibbonTrail.h +++ b/OgreMain/include/OgreRibbonTrail.h @@ -38,206 +38,206 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Effects - * @{ - */ - /** Subclass of BillboardChain which automatically leaves a trail behind - one or more Node instances. - @remarks - An instance of this class will watch one or more Node instances, and - automatically generate a trail behind them as they move. Because this - class can monitor multiple modes, it generates its own geometry in - world space and thus, even though it has to be attached to a SceneNode - to be visible, changing the position of the scene node it is attached to - makes no difference to the geometry rendered. - @par - The 'head' element grows smoothly in size until it reaches the required size, - then a new element is added. If the segment is full, the tail element - shrinks by the same proportion as the head grows before disappearing. - @par - Elements can be faded out on a time basis, either by altering their colour - or altering their alpha. The width can also alter over time. - @par - 'v' texture coordinates are fixed at 0.0 if used, meaning that you can - use a 1D texture to 'smear' a colour pattern along the ribbon if you wish. - The 'u' coordinates are by default (0.0, 1.0), but you can alter this - using setOtherTexCoordRange if you wish. - */ - class _OgreExport RibbonTrail : public BillboardChain, public Node::Listener - { - public: - /** Constructor (don't use directly, use factory) - @param name The name to give this object - @param maxElements The maximum number of elements per chain - @param numberOfChains The number of separate chain segments contained in this object, - ie the maximum number of nodes that can have trails attached - @param useTextureCoords If true, use texture coordinates from the chain elements - @param useVertexColours If true, use vertex colours from the chain elements (must - be true if you intend to use fading) - */ - RibbonTrail(const String& name, size_t maxElements = 20, size_t numberOfChains = 1, - bool useTextureCoords = true, bool useVertexColours = true); - /// destructor - virtual ~RibbonTrail(); - - typedef vector::type NodeList; - typedef ConstVectorIterator NodeIterator; - - /** Add a node to be tracked. - @param n The node that will be tracked. - */ - virtual void addNode(Node* n); - /** Remove tracking on a given node. */ - virtual void removeNode(Node* n); - /** Get an iterator over the nodes which are being tracked. */ - virtual NodeIterator getNodeIterator(void) const; - /** Get the chain index for a given Node being tracked. */ - virtual size_t getChainIndexForNode(const Node* n); - - /** Set the length of the trail. - @remarks - This sets the length of the trail, in world units. It also sets how - far apart each segment will be, ie length / max_elements. - @param len The length of the trail in world units - */ - virtual void setTrailLength(Real len); - /** Get the length of the trail. */ - virtual Real getTrailLength(void) const { return mTrailLength; } - - /** @copydoc BillboardChain::setMaxChainElements */ - void setMaxChainElements(size_t maxElements); - /** @copydoc BillboardChain::setNumberOfChains */ - void setNumberOfChains(size_t numChains); - /** @copydoc BillboardChain::clearChain */ - void clearChain(size_t chainIndex); - - /** Set the starting ribbon colour for a given segment. - @param chainIndex The index of the chain - @param col The initial colour - @note - Only used if this instance is using vertex colours. - */ - virtual void setInitialColour(size_t chainIndex, const ColourValue& col); - /** Set the starting ribbon colour. - @param chainIndex The index of the chain - @param r,b,g,a The initial colour - @note - Only used if this instance is using vertex colours. - */ - virtual void setInitialColour(size_t chainIndex, Real r, Real g, Real b, Real a = 1.0); - /** Get the starting ribbon colour. */ - virtual const ColourValue& getInitialColour(size_t chainIndex) const; - - /** Enables / disables fading the trail using colour. - @param chainIndex The index of the chain - @param valuePerSecond The amount to subtract from colour each second - */ - virtual void setColourChange(size_t chainIndex, const ColourValue& valuePerSecond); - - /** Set the starting ribbon width in world units. - @param chainIndex The index of the chain - @param width The initial width of the ribbon - */ - virtual void setInitialWidth(size_t chainIndex, Real width); - /** Get the starting ribbon width in world units. */ - virtual Real getInitialWidth(size_t chainIndex) const; - - /** Set the change in ribbon width per second. - @param chainIndex The index of the chain - @param widthDeltaPerSecond The amount the width will reduce by per second - */ - virtual void setWidthChange(size_t chainIndex, Real widthDeltaPerSecond); - /** Get the change in ribbon width per second. */ - virtual Real getWidthChange(size_t chainIndex) const; - - /** Enables / disables fading the trail using colour. - @param chainIndex The index of the chain - @param r,g,b,a The amount to subtract from each colour channel per second - */ - virtual void setColourChange(size_t chainIndex, Real r, Real g, Real b, Real a); - - /** Get the per-second fading amount */ - virtual const ColourValue& getColourChange(size_t chainIndex) const; - - /// @see Node::Listener::nodeUpdated - void nodeUpdated(const Node* node); - /// @see Node::Listener::nodeDestroyed - void nodeDestroyed(const Node* node); - - /// Perform any fading / width delta required; internal method - virtual void _timeUpdate(Real time); + /** \addtogroup Core + * @{ + */ + /** \addtogroup Effects + * @{ + */ + /** Subclass of BillboardChain which automatically leaves a trail behind + one or more Node instances. + @remarks + An instance of this class will watch one or more Node instances, and + automatically generate a trail behind them as they move. Because this + class can monitor multiple modes, it generates its own geometry in + world space and thus, even though it has to be attached to a SceneNode + to be visible, changing the position of the scene node it is attached to + makes no difference to the geometry rendered. + @par + The 'head' element grows smoothly in size until it reaches the required size, + then a new element is added. If the segment is full, the tail element + shrinks by the same proportion as the head grows before disappearing. + @par + Elements can be faded out on a time basis, either by altering their colour + or altering their alpha. The width can also alter over time. + @par + 'v' texture coordinates are fixed at 0.0 if used, meaning that you can + use a 1D texture to 'smear' a colour pattern along the ribbon if you wish. + The 'u' coordinates are by default (0.0, 1.0), but you can alter this + using setOtherTexCoordRange if you wish. + */ + class _OgreExport RibbonTrail : public BillboardChain, public Node::Listener + { + public: + /** Constructor (don't use directly, use factory) + @param name The name to give this object + @param maxElements The maximum number of elements per chain + @param numberOfChains The number of separate chain segments contained in this object, + ie the maximum number of nodes that can have trails attached + @param useTextureCoords If true, use texture coordinates from the chain elements + @param useVertexColours If true, use vertex colours from the chain elements (must + be true if you intend to use fading) + */ + RibbonTrail(const String& name, size_t maxElements = 20, size_t numberOfChains = 1, + bool useTextureCoords = true, bool useVertexColours = true); + /// destructor + virtual ~RibbonTrail(); + + typedef vector::type NodeList; + typedef ConstVectorIterator NodeIterator; + + /** Add a node to be tracked. + @param n The node that will be tracked. + */ + virtual void addNode(Node* n); + /** Remove tracking on a given node. */ + virtual void removeNode(Node* n); + /** Get an iterator over the nodes which are being tracked. */ + virtual NodeIterator getNodeIterator(void) const; + /** Get the chain index for a given Node being tracked. */ + virtual size_t getChainIndexForNode(const Node* n); + + /** Set the length of the trail. + @remarks + This sets the length of the trail, in world units. It also sets how + far apart each segment will be, ie length / max_elements. + @param len The length of the trail in world units + */ + virtual void setTrailLength(Real len); + /** Get the length of the trail. */ + virtual Real getTrailLength(void) const { return mTrailLength; } + + /** @copydoc BillboardChain::setMaxChainElements */ + void setMaxChainElements(size_t maxElements); + /** @copydoc BillboardChain::setNumberOfChains */ + void setNumberOfChains(size_t numChains); + /** @copydoc BillboardChain::clearChain */ + void clearChain(size_t chainIndex); + + /** Set the starting ribbon colour for a given segment. + @param chainIndex The index of the chain + @param col The initial colour + @note + Only used if this instance is using vertex colours. + */ + virtual void setInitialColour(size_t chainIndex, const ColourValue& col); + /** Set the starting ribbon colour. + @param chainIndex The index of the chain + @param r,b,g,a The initial colour + @note + Only used if this instance is using vertex colours. + */ + virtual void setInitialColour(size_t chainIndex, Real r, Real g, Real b, Real a = 1.0); + /** Get the starting ribbon colour. */ + virtual const ColourValue& getInitialColour(size_t chainIndex) const; + + /** Enables / disables fading the trail using colour. + @param chainIndex The index of the chain + @param valuePerSecond The amount to subtract from colour each second + */ + virtual void setColourChange(size_t chainIndex, const ColourValue& valuePerSecond); + + /** Set the starting ribbon width in world units. + @param chainIndex The index of the chain + @param width The initial width of the ribbon + */ + virtual void setInitialWidth(size_t chainIndex, Real width); + /** Get the starting ribbon width in world units. */ + virtual Real getInitialWidth(size_t chainIndex) const; + + /** Set the change in ribbon width per second. + @param chainIndex The index of the chain + @param widthDeltaPerSecond The amount the width will reduce by per second + */ + virtual void setWidthChange(size_t chainIndex, Real widthDeltaPerSecond); + /** Get the change in ribbon width per second. */ + virtual Real getWidthChange(size_t chainIndex) const; + + /** Enables / disables fading the trail using colour. + @param chainIndex The index of the chain + @param r,g,b,a The amount to subtract from each colour channel per second + */ + virtual void setColourChange(size_t chainIndex, Real r, Real g, Real b, Real a); + + /** Get the per-second fading amount */ + virtual const ColourValue& getColourChange(size_t chainIndex) const; + + /// @see Node::Listener::nodeUpdated + void nodeUpdated(const Node* node); + /// @see Node::Listener::nodeDestroyed + void nodeDestroyed(const Node* node); + + /// Perform any fading / width delta required; internal method + virtual void _timeUpdate(Real time); /** Overridden from MovableObject */ const String& getMovableType(void) const; - protected: - /// List of nodes being trailed - NodeList mNodeList; - /// Mapping of nodes to chain segments - typedef vector::type IndexVector; - /// Ordered like mNodeList, contains chain index - IndexVector mNodeToChainSegment; - // chains not in use - IndexVector mFreeChains; - - // fast lookup node->chain index - // we use positional map too because that can be useful - typedef map::type NodeToChainSegmentMap; - NodeToChainSegmentMap mNodeToSegMap; - - /// Total length of trail in world units - Real mTrailLength; - /// length of each element - Real mElemLength; - /// Squared length of each element - Real mSquaredElemLength; - typedef vector::type ColourValueList; - typedef vector::type RealList; - /// Initial colour of the ribbon - ColourValueList mInitialColour; - /// fade amount per second - ColourValueList mDeltaColour; - /// Initial width of the ribbon - RealList mInitialWidth; - /// Delta width of the ribbon - RealList mDeltaWidth; - /// controller used to hook up frame time to fader - Controller* mFadeController; - /// controller value for hooking up frame time to fader - ControllerValueRealPtr mTimeControllerValue; - - /// Manage updates to the time controller - virtual void manageController(void); - /// Node has changed position, update - virtual void updateTrail(size_t index, const Node* node); + protected: + /// List of nodes being trailed + NodeList mNodeList; + /// Mapping of nodes to chain segments + typedef vector::type IndexVector; + /// Ordered like mNodeList, contains chain index + IndexVector mNodeToChainSegment; + // chains not in use + IndexVector mFreeChains; + + // fast lookup node->chain index + // we use positional map too because that can be useful + typedef map::type NodeToChainSegmentMap; + NodeToChainSegmentMap mNodeToSegMap; + + /// Total length of trail in world units + Real mTrailLength; + /// length of each element + Real mElemLength; + /// Squared length of each element + Real mSquaredElemLength; + typedef vector::type ColourValueList; + typedef vector::type RealList; + /// Initial colour of the ribbon + ColourValueList mInitialColour; + /// fade amount per second + ColourValueList mDeltaColour; + /// Initial width of the ribbon + RealList mInitialWidth; + /// Delta width of the ribbon + RealList mDeltaWidth; + /// controller used to hook up frame time to fader + Controller* mFadeController; + /// controller value for hooking up frame time to fader + ControllerValueRealPtr mTimeControllerValue; + + /// Manage updates to the time controller + virtual void manageController(void); + /// Node has changed position, update + virtual void updateTrail(size_t index, const Node* node); /// Reset the tracked chain to initial state virtual void resetTrail(size_t index, const Node* node); /// Reset all tracked chains to initial state virtual void resetAllTrails(void); - }; + }; - /** Factory object for creating RibbonTrail instances */ - class _OgreExport RibbonTrailFactory : public MovableObjectFactory - { - protected: - MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params); - public: - RibbonTrailFactory() {} - ~RibbonTrailFactory() {} + /** Factory object for creating RibbonTrail instances */ + class _OgreExport RibbonTrailFactory : public MovableObjectFactory + { + protected: + MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params); + public: + RibbonTrailFactory() {} + ~RibbonTrailFactory() {} - static String FACTORY_TYPE_NAME; + static String FACTORY_TYPE_NAME; - const String& getType(void) const; - void destroyInstance( MovableObject* obj); + const String& getType(void) const; + void destroyInstance( MovableObject* obj); - }; - /** @} */ - /** @} */ + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreRoot.h b/OgreMain/include/OgreRoot.h index 5b88b20d92c..7c11cc32d7f 100644 --- a/OgreMain/include/OgreRoot.h +++ b/OgreMain/include/OgreRoot.h @@ -41,15 +41,15 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ typedef vector::type RenderSystemList; - + /** The root class of the Ogre system. @remarks The Ogre::Root class represents a starting point for the client @@ -68,12 +68,12 @@ namespace Ogre // To allow update of active renderer if // RenderSystem::initialise is used directly friend class RenderSystem; - protected: + protected: RenderSystemList mRenderers; RenderSystem* mActiveRenderer; String mVersion; - String mConfigFileName; - bool mQueuedEnd; + String mConfigFileName; + bool mQueuedEnd; /// In case multiple render windows are created, only once are the resources loaded. bool mFirstTimePostWindowInit; @@ -81,8 +81,8 @@ namespace Ogre LogManager* mLogManager; ControllerManager* mControllerManager; SceneManagerEnumerator* mSceneManagerEnum; - typedef deque::type SceneManagerStack; - SceneManagerStack mSceneManagerStack; + typedef deque::type SceneManagerStack; + SceneManagerStack mSceneManagerStack; DynLibManager* mDynLibManager; ArchiveManager* mArchiveManager; MaterialManager* mMaterialManager; @@ -98,10 +98,10 @@ namespace Ogre AndroidLogListener* mAndroidLogger; #endif - ResourceGroupManager* mResourceGroupManager; - ResourceBackgroundQueue* mResourceBackgroundQueue; - ShadowTextureManager* mShadowTextureManager; - RenderSystemCapabilitiesManager* mRenderSystemCapabilitiesManager; + ResourceGroupManager* mResourceGroupManager; + ResourceBackgroundQueue* mResourceBackgroundQueue; + ShadowTextureManager* mShadowTextureManager; + RenderSystemCapabilitiesManager* mRenderSystemCapabilitiesManager; ScriptCompilerManager *mCompilerManager; LodStrategyManager *mLodStrategyManager; @@ -109,46 +109,46 @@ namespace Ogre RenderWindow* mAutoWindow; Profiler* mProfiler; HighLevelGpuProgramManager* mHighLevelGpuProgramManager; - ExternalTextureSourceManager* mExternalTextureSourceManager; + ExternalTextureSourceManager* mExternalTextureSourceManager; CompositorManager* mCompositorManager; unsigned long mNextFrame; - Real mFrameSmoothingTime; - bool mRemoveQueueStructuresOnClear; - Real mDefaultMinPixelSize; - HardwareBuffer::UploadOptions mFreqUpdatedBuffersUploadOption; - - public: - typedef vector::type PluginLibList; - typedef vector::type PluginInstanceList; - protected: - /// List of plugin DLLs loaded + Real mFrameSmoothingTime; + bool mRemoveQueueStructuresOnClear; + Real mDefaultMinPixelSize; + HardwareBuffer::UploadOptions mFreqUpdatedBuffersUploadOption; + + public: + typedef vector::type PluginLibList; + typedef vector::type PluginInstanceList; + protected: + /// List of plugin DLLs loaded PluginLibList mPluginLibs; - /// List of Plugin instances registered - PluginInstanceList mPlugins; + /// List of Plugin instances registered + PluginInstanceList mPlugins; - typedef map::type MovableObjectFactoryMap; - MovableObjectFactoryMap mMovableObjectFactoryMap; - uint32 mNextMovableObjectTypeFlag; - // stock movable factories - MovableObjectFactory* mEntityFactory; - MovableObjectFactory* mLightFactory; - MovableObjectFactory* mBillboardSetFactory; - MovableObjectFactory* mManualObjectFactory; - MovableObjectFactory* mBillboardChainFactory; - MovableObjectFactory* mRibbonTrailFactory; + typedef map::type MovableObjectFactoryMap; + MovableObjectFactoryMap mMovableObjectFactoryMap; + uint32 mNextMovableObjectTypeFlag; + // stock movable factories + MovableObjectFactory* mEntityFactory; + MovableObjectFactory* mLightFactory; + MovableObjectFactory* mBillboardSetFactory; + MovableObjectFactory* mManualObjectFactory; + MovableObjectFactory* mBillboardChainFactory; + MovableObjectFactory* mRibbonTrailFactory; - typedef map::type RenderQueueInvocationSequenceMap; - RenderQueueInvocationSequenceMap mRQSequenceMap; + typedef map::type RenderQueueInvocationSequenceMap; + RenderQueueInvocationSequenceMap mRQSequenceMap; - /// Are we initialised yet? - bool mIsInitialised; + /// Are we initialised yet? + bool mIsInitialised; - WorkQueue* mWorkQueue; + WorkQueue* mWorkQueue; - ///Tells whether blend indices information needs to be passed to the GPU - bool mIsBlendIndicesGpuRedundant; - ///Tells whether blend weights information needs to be passed to the GPU - bool mIsBlendWeightsGpuRedundant; + ///Tells whether blend indices information needs to be passed to the GPU + bool mIsBlendIndicesGpuRedundant; + ///Tells whether blend weights information needs to be passed to the GPU + bool mIsBlendWeightsGpuRedundant; /** Method reads a plugins configuration file and instantiates all plugins. @@ -158,16 +158,16 @@ namespace Ogre in debug build. */ void loadPlugins(const String& pluginsfile = "plugins" OGRE_BUILD_SUFFIX ".cfg"); - /** Initialise all loaded plugins - allows plugins to perform actions - once the renderer is initialised. - */ - void initialisePlugins(); - /** Shuts down all loaded plugins - allows things to be tidied up whilst - all plugins are still loaded. - */ - void shutdownPlugins(); + /** Initialise all loaded plugins - allows plugins to perform actions + once the renderer is initialised. + */ + void initialisePlugins(); + /** Shuts down all loaded plugins - allows things to be tidied up whilst + all plugins are still loaded. + */ + void shutdownPlugins(); - /** Unloads all loaded plugins. + /** Unloads all loaded plugins. */ void unloadPlugins(); @@ -185,14 +185,14 @@ namespace Ogre /** Indicates the type of event to be considered by calculateEventTime(). */ enum FrameEventTimeType { FETT_ANY = 0, - FETT_STARTED = 1, - FETT_QUEUED = 2, - FETT_ENDED = 3, - FETT_COUNT = 4 + FETT_STARTED = 1, + FETT_QUEUED = 2, + FETT_ENDED = 3, + FETT_COUNT = 4 }; /// Contains the times of recently fired events - typedef deque::type EventTimesQueue; + typedef deque::type EventTimesQueue; EventTimesQueue mEventTimes[FETT_COUNT]; /** Internal method for calculating the average time between recently fired events. @@ -201,8 +201,8 @@ namespace Ogre */ Real calculateEventTime(unsigned long now, FrameEventTimeType type); - /** Update a set of event times (note, progressive, only call once for each type per frame) */ - void populateFrameEvent(FrameEventTimeType type, FrameEvent& evtToUpdate); + /** Update a set of event times (note, progressive, only call once for each type per frame) */ + void populateFrameEvent(FrameEventTimeType type, FrameEvent& evtToUpdate); public: @@ -210,14 +210,14 @@ namespace Ogre @param pluginFileName The file that contains plugins information. Defaults to "plugins.cfg" in release build and to "plugins_d.cfg" in debug build. May be left blank to ignore. - @param configFileName The file that contains the configuration to be loaded. - Defaults to "ogre.cfg", may be left blank to load nothing. - @param logFileName The logfile to create, defaults to Ogre.log, may be - left blank if you've already set up LogManager & Log yourself - */ + @param configFileName The file that contains the configuration to be loaded. + Defaults to "ogre.cfg", may be left blank to load nothing. + @param logFileName The logfile to create, defaults to Ogre.log, may be + left blank if you've already set up LogManager & Log yourself + */ Root(const String& pluginFileName = "plugins" OGRE_BUILD_SUFFIX ".cfg", - const String& configFileName = "ogre.cfg", - const String& logFileName = "Ogre.log"); + const String& configFileName = "ogre.cfg", + const String& logFileName = "Ogre.log"); ~Root(); /** Saves the details of the current configuration @@ -326,11 +326,11 @@ namespace Ogre A pointer to the automatically created window, if requested, otherwise NULL. */ - RenderWindow* initialise(bool autoCreateWindow, const String& windowTitle = "OGRE Render Window", + RenderWindow* initialise(bool autoCreateWindow, const String& windowTitle = "OGRE Render Window", const String& customCapabilitiesConfig = BLANKSTRING); - /** Returns whether the system is initialised or not. */ - bool isInitialised(void) const { return mIsInitialised; } + /** Returns whether the system is initialised or not. */ + bool isInitialised(void) const { return mIsInitialised; } /** Requests active RenderSystem to use custom RenderSystemCapabilities @remarks @@ -339,87 +339,87 @@ namespace Ogre */ void useCustomRenderSystemCapabilities(RenderSystemCapabilities* capabilities); - /** Get whether the entire render queue structure should be emptied on clearing, - or whether just the objects themselves should be cleared. - */ - bool getRemoveRenderQueueStructuresOnClear() const { return mRemoveQueueStructuresOnClear; } - - /** Set whether the entire render queue structure should be emptied on clearing, - or whether just the objects themselves should be cleared. - */ - void setRemoveRenderQueueStructuresOnClear(bool r) { mRemoveQueueStructuresOnClear = r; } - - /** Register a new SceneManagerFactory, a factory object for creating instances - of specific SceneManagers. - @remarks - Plugins should call this to register as new SceneManager providers. - */ - void addSceneManagerFactory(SceneManagerFactory* fact); - - /** Unregister a SceneManagerFactory. - */ - void removeSceneManagerFactory(SceneManagerFactory* fact); - - /** Get more information about a given type of SceneManager. - @remarks - The metadata returned tells you a few things about a given type - of SceneManager, which can be created using a factory that has been - registered already. - @param typeName The type name of the SceneManager you want to enquire on. - If you don't know the typeName already, you can iterate over the - metadata for all types using getMetaDataIterator. - */ - const SceneManagerMetaData* getSceneManagerMetaData(const String& typeName) const; - - /** Iterate over all types of SceneManager available for construction, - providing some information about each one. - */ - SceneManagerEnumerator::MetaDataIterator getSceneManagerMetaDataIterator(void) const; - - /** Create a SceneManager instance of a given type. - @remarks - You can use this method to create a SceneManager instance of a - given specific type. You may know this type already, or you may - have discovered it by looking at the results from getMetaDataIterator. - @note - This method throws an exception if the named type is not found. - @param typeName String identifying a unique SceneManager type - @param instanceName Optional name to given the new instance that is - created. If you leave this blank, an auto name will be assigned. - */ - SceneManager* createSceneManager(const String& typeName, - const String& instanceName = BLANKSTRING); - - /** Create a SceneManager instance based on scene type support. - @remarks - Creates an instance of a SceneManager which supports the scene types - identified in the parameter. If more than one type of SceneManager - has been registered as handling that combination of scene types, - in instance of the last one registered is returned. - @note This method always succeeds, if a specific scene manager is not - found, the default implementation is always returned. - @param typeMask A mask containing one or more SceneType flags - @param instanceName Optional name to given the new instance that is - created. If you leave this blank, an auto name will be assigned. - */ - SceneManager* createSceneManager(SceneTypeMask typeMask, - const String& instanceName = BLANKSTRING); - - /** Destroy an instance of a SceneManager. */ - void destroySceneManager(SceneManager* sm); - - /** Get an existing SceneManager instance that has already been created, - identified by the instance name. - @param instanceName The name of the instance to retrieve. - */ - SceneManager* getSceneManager(const String& instanceName) const; - - /** Determines if a given SceneManager already exists - @param instanceName The name of the instance to retrieve. - */ - bool hasSceneManager(const String& instanceName) const; - /** Get an iterator over all the existing SceneManager instances. */ - SceneManagerEnumerator::SceneManagerIterator getSceneManagerIterator(void); + /** Get whether the entire render queue structure should be emptied on clearing, + or whether just the objects themselves should be cleared. + */ + bool getRemoveRenderQueueStructuresOnClear() const { return mRemoveQueueStructuresOnClear; } + + /** Set whether the entire render queue structure should be emptied on clearing, + or whether just the objects themselves should be cleared. + */ + void setRemoveRenderQueueStructuresOnClear(bool r) { mRemoveQueueStructuresOnClear = r; } + + /** Register a new SceneManagerFactory, a factory object for creating instances + of specific SceneManagers. + @remarks + Plugins should call this to register as new SceneManager providers. + */ + void addSceneManagerFactory(SceneManagerFactory* fact); + + /** Unregister a SceneManagerFactory. + */ + void removeSceneManagerFactory(SceneManagerFactory* fact); + + /** Get more information about a given type of SceneManager. + @remarks + The metadata returned tells you a few things about a given type + of SceneManager, which can be created using a factory that has been + registered already. + @param typeName The type name of the SceneManager you want to enquire on. + If you don't know the typeName already, you can iterate over the + metadata for all types using getMetaDataIterator. + */ + const SceneManagerMetaData* getSceneManagerMetaData(const String& typeName) const; + + /** Iterate over all types of SceneManager available for construction, + providing some information about each one. + */ + SceneManagerEnumerator::MetaDataIterator getSceneManagerMetaDataIterator(void) const; + + /** Create a SceneManager instance of a given type. + @remarks + You can use this method to create a SceneManager instance of a + given specific type. You may know this type already, or you may + have discovered it by looking at the results from getMetaDataIterator. + @note + This method throws an exception if the named type is not found. + @param typeName String identifying a unique SceneManager type + @param instanceName Optional name to given the new instance that is + created. If you leave this blank, an auto name will be assigned. + */ + SceneManager* createSceneManager(const String& typeName, + const String& instanceName = BLANKSTRING); + + /** Create a SceneManager instance based on scene type support. + @remarks + Creates an instance of a SceneManager which supports the scene types + identified in the parameter. If more than one type of SceneManager + has been registered as handling that combination of scene types, + in instance of the last one registered is returned. + @note This method always succeeds, if a specific scene manager is not + found, the default implementation is always returned. + @param typeMask A mask containing one or more SceneType flags + @param instanceName Optional name to given the new instance that is + created. If you leave this blank, an auto name will be assigned. + */ + SceneManager* createSceneManager(SceneTypeMask typeMask, + const String& instanceName = BLANKSTRING); + + /** Destroy an instance of a SceneManager. */ + void destroySceneManager(SceneManager* sm); + + /** Get an existing SceneManager instance that has already been created, + identified by the instance name. + @param instanceName The name of the instance to retrieve. + */ + SceneManager* getSceneManager(const String& instanceName) const; + + /** Determines if a given SceneManager already exists + @param instanceName The name of the instance to retrieve. + */ + bool hasSceneManager(const String& instanceName) const; + /** Get an iterator over all the existing SceneManager instances. */ + SceneManagerEnumerator::SceneManagerIterator getSceneManagerIterator(void); /** Retrieves a reference to the current TextureManager. @remarks @@ -510,8 +510,8 @@ namespace Ogre rendering targets (e.g. an editor utility), it is better to manually refresh each render target only when required by calling RenderTarget::update, or if you want to run your own - render loop you can update all targets on demand using - Root::renderOneFrame. + render loop you can update all targets on demand using + Root::renderOneFrame. @note This frees up the CPU to do other things in between refreshes, since in this case frame rate is less important. @@ -528,13 +528,13 @@ namespace Ogre */ bool renderOneFrame(void); - /** Render one frame, with custom frame time information. - @remarks - Updates all the render targets automatically and then returns, - raising frame events before and after - all per-frame times are based on - the time value you pass in. - */ - bool renderOneFrame(Real timeSinceLastFrame); + /** Render one frame, with custom frame time information. + @remarks + Updates all the render targets automatically and then returns, + raising frame events before and after - all per-frame times are based on + the time value you pass in. + */ + bool renderOneFrame(Real timeSinceLastFrame); /** Shuts down the system manually. @remarks @@ -550,8 +550,8 @@ namespace Ogre @remarks Resource files (textures, models etc) need to be loaded from specific locations. By calling this method, you add another - search location to the list. Locations added first are preferred - over locations added later. + search location to the list. Locations added first are preferred + over locations added later. @par Locations can be folders, compressed archives, even perhaps remote locations. Facilities for loading from different @@ -563,13 +563,13 @@ namespace Ogre configured with the 'FileSystem' (folders) and 'Zip' (archive compressed with the pkzip / WinZip etc utilities) types. @par - You can also supply the name of a resource group which should - have this location applied to it. The - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME group is the - default, and one resource group which will always exist. You - should consider defining resource groups for your more specific - resources (e.g. per level) so that you can control loading / - unloading better. + You can also supply the name of a resource group which should + have this location applied to it. The + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME group is the + default, and one resource group which will always exist. You + should consider defining resource groups for your more specific + resources (e.g. per level) so that you can control loading / + unloading better. @param name The name of the location, e.g. './data' or '/compressed/gamedata.zip' @@ -580,70 +580,70 @@ namespace Ogre Zip should always be available) @param groupName Type of name of the resource group which this location - should apply to; defaults to the General group which applies to - all non-specific resources. - @param - recursive If the resource location has a concept of recursive - directory traversal, enabling this option will mean you can load - resources in subdirectories using only their unqualified name. - The default is to disable this so that resources in subdirectories - with the same name are still unique. + should apply to; defaults to the General group which applies to + all non-specific resources. + @param + recursive If the resource location has a concept of recursive + directory traversal, enabling this option will mean you can load + resources in subdirectories using only their unqualified name. + The default is to disable this so that resources in subdirectories + with the same name are still unique. @see Archive */ void addResourceLocation(const String& name, const String& locType, - const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - bool recursive = false); - - /** Removes a resource location from the list. - @see addResourceLocation - @param name The name of the resource location as specified in addResourceLocation - @param groupName The name of the resource group to which this location - was assigned. - */ - void removeResourceLocation(const String& name, - const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - /** Helper method to assist you in creating writeable file streams. - @remarks - This is a high-level utility method which you can use to find a place to - save a file more easily. If the filename you specify is either an - absolute or relative filename (ie it includes path separators), then - the file will be created in the normal filesystem using that specification. - If it doesn't, then the method will look for a writeable resource location - via ResourceGroupManager::createResource using the other params provided. - @param filename The name of the file to create. If it includes path separators, - the filesystem will be accessed direct. If no path separators are - present the resource system is used, falling back on the raw filesystem after. - @param groupName The name of the group in which to create the file, if the - resource system is used - @param overwrite If true, an existing file will be overwritten, if false - an error will occur if the file already exists - @param locationPattern If the resource group contains multiple locations, - then usually the file will be created in the first writable location. If you - want to be more specific, you can include a location pattern here and - only locations which match that pattern (as determined by StringUtil::match) - will be considered candidates for creation. - */ - DataStreamPtr createFileStream(const String& filename, const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - bool overwrite = false, const String& locationPattern = BLANKSTRING); - - /** Helper method to assist you in accessing readable file streams. - @remarks - This is a high-level utility method which you can use to find a place to - open a file more easily. It checks the resource system first, and if - that fails falls back on accessing the file system directly. - @param filename The name of the file to open. - @param groupName The name of the group in which to create the file, if the - resource system is used - @param locationPattern If the resource group contains multiple locations, - then usually the file will be created in the first writable location. If you - want to be more specific, you can include a location pattern here and - only locations which match that pattern (as determined by StringUtil::match) - will be considered candidates for creation. - */ - DataStreamPtr openFileStream(const String& filename, const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - const String& locationPattern = BLANKSTRING); + const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + bool recursive = false); + + /** Removes a resource location from the list. + @see addResourceLocation + @param name The name of the resource location as specified in addResourceLocation + @param groupName The name of the resource group to which this location + was assigned. + */ + void removeResourceLocation(const String& name, + const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + /** Helper method to assist you in creating writeable file streams. + @remarks + This is a high-level utility method which you can use to find a place to + save a file more easily. If the filename you specify is either an + absolute or relative filename (ie it includes path separators), then + the file will be created in the normal filesystem using that specification. + If it doesn't, then the method will look for a writeable resource location + via ResourceGroupManager::createResource using the other params provided. + @param filename The name of the file to create. If it includes path separators, + the filesystem will be accessed direct. If no path separators are + present the resource system is used, falling back on the raw filesystem after. + @param groupName The name of the group in which to create the file, if the + resource system is used + @param overwrite If true, an existing file will be overwritten, if false + an error will occur if the file already exists + @param locationPattern If the resource group contains multiple locations, + then usually the file will be created in the first writable location. If you + want to be more specific, you can include a location pattern here and + only locations which match that pattern (as determined by StringUtil::match) + will be considered candidates for creation. + */ + DataStreamPtr createFileStream(const String& filename, const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + bool overwrite = false, const String& locationPattern = BLANKSTRING); + + /** Helper method to assist you in accessing readable file streams. + @remarks + This is a high-level utility method which you can use to find a place to + open a file more easily. It checks the resource system first, and if + that fails falls back on accessing the file system directly. + @param filename The name of the file to open. + @param groupName The name of the group in which to create the file, if the + resource system is used + @param locationPattern If the resource group contains multiple locations, + then usually the file will be created in the first writable location. If you + want to be more specific, you can include a location pattern here and + only locations which match that pattern (as determined by StringUtil::match) + will be considered candidates for creation. + */ + DataStreamPtr openFileStream(const String& filename, const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + const String& locationPattern = BLANKSTRING); /** Generates a packed data version of the passed in ColourValue suitable for use with the current RenderSystem. @@ -667,14 +667,14 @@ namespace Ogre /** @copydoc RenderSystem::_createRenderWindow */ - RenderWindow* createRenderWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0) ; + RenderWindow* createRenderWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0) ; - /** @copydoc RenderSystem::_createRenderWindows - */ - bool createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, - RenderWindowList& createdWindows); - + /** @copydoc RenderSystem::_createRenderWindows + */ + bool createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, + RenderWindowList& createdWindows); + /** Detaches a RenderTarget from the active render system and returns a pointer to it. @note @@ -701,53 +701,53 @@ namespace Ogre */ RenderTarget * getRenderTarget(const String &name); - /** Manually load a Plugin contained in a DLL / DSO. - @remarks - Plugins embedded in DLLs can be loaded at startup using the plugin - configuration file specified when you create Root. - This method allows you to load plugin DLLs directly in code. - The DLL in question is expected to implement a dllStartPlugin - method which instantiates a Plugin subclass and calls Root::installPlugin. - It should also implement dllStopPlugin (see Root::unloadPlugin) - @param pluginName Name of the plugin library to load - */ - void loadPlugin(const String& pluginName); - - /** Manually unloads a Plugin contained in a DLL / DSO. - @remarks - Plugin DLLs are unloaded at shutdown automatically. This method - allows you to unload plugins in code, but make sure their - dependencies are decoupled first. This method will call the - dllStopPlugin method defined in the DLL, which in turn should call - Root::uninstallPlugin. - @param pluginName Name of the plugin library to unload - */ - void unloadPlugin(const String& pluginName); - - /** Install a new plugin. - @remarks - This installs a new extension to OGRE. The plugin itself may be loaded - from a DLL / DSO, or it might be statically linked into your own - application. Either way, something has to call this method to get - it registered and functioning. You should only call this method directly - if your plugin is not in a DLL that could otherwise be loaded with - loadPlugin, since the DLL function dllStartPlugin should call this - method when the DLL is loaded. - */ - void installPlugin(Plugin* plugin); - - /** Uninstall an existing plugin. - @remarks - This uninstalls an extension to OGRE. Plugins are automatically - uninstalled at shutdown but this lets you remove them early. - If the plugin was loaded from a DLL / DSO you should call unloadPlugin - which should result in this method getting called anyway (if the DLL - is well behaved). - */ - void uninstallPlugin(Plugin* plugin); - - /** Gets a read-only list of the currently installed plugins. */ - const PluginInstanceList& getInstalledPlugins() const { return mPlugins; } + /** Manually load a Plugin contained in a DLL / DSO. + @remarks + Plugins embedded in DLLs can be loaded at startup using the plugin + configuration file specified when you create Root. + This method allows you to load plugin DLLs directly in code. + The DLL in question is expected to implement a dllStartPlugin + method which instantiates a Plugin subclass and calls Root::installPlugin. + It should also implement dllStopPlugin (see Root::unloadPlugin) + @param pluginName Name of the plugin library to load + */ + void loadPlugin(const String& pluginName); + + /** Manually unloads a Plugin contained in a DLL / DSO. + @remarks + Plugin DLLs are unloaded at shutdown automatically. This method + allows you to unload plugins in code, but make sure their + dependencies are decoupled first. This method will call the + dllStopPlugin method defined in the DLL, which in turn should call + Root::uninstallPlugin. + @param pluginName Name of the plugin library to unload + */ + void unloadPlugin(const String& pluginName); + + /** Install a new plugin. + @remarks + This installs a new extension to OGRE. The plugin itself may be loaded + from a DLL / DSO, or it might be statically linked into your own + application. Either way, something has to call this method to get + it registered and functioning. You should only call this method directly + if your plugin is not in a DLL that could otherwise be loaded with + loadPlugin, since the DLL function dllStartPlugin should call this + method when the DLL is loaded. + */ + void installPlugin(Plugin* plugin); + + /** Uninstall an existing plugin. + @remarks + This uninstalls an extension to OGRE. Plugins are automatically + uninstalled at shutdown but this lets you remove them early. + If the plugin was loaded from a DLL / DSO you should call unloadPlugin + which should result in this method getting called anyway (if the DLL + is well behaved). + */ + void uninstallPlugin(Plugin* plugin); + + /** Gets a read-only list of the currently installed plugins. */ + const PluginInstanceList& getInstalledPlugins() const { return mPlugins; } /** Gets a pointer to the central timer used for all OGRE timings */ Timer* getTimer(void); @@ -777,9 +777,9 @@ namespace Ogre This method is only for internal use when you use OGRE's inbuilt rendering loop (Root::startRendering). However, if you run your own rendering loop then you should call this method too, to ensure that all state is updated - correctly. You should call it after the windows have been updated - but before the buffers are swapped, or if you are not separating the - update and buffer swap, then after the update just before _fireFrameEnded. + correctly. You should call it after the windows have been updated + but before the buffers are swapped, or if you are not separating the + update and buffer swap, then after the update just before _fireFrameEnded. */ bool _fireFrameRenderingQueued(FrameEvent& evt); @@ -823,10 +823,10 @@ namespace Ogre This method is only for internal use when you use OGRE's inbuilt rendering loop (Root::startRendering). However, if you run your own rendering loop then you you may want to call this method too, although nothing in OGRE relies on this - particular event. Really if you're running your own rendering loop at - this level of detail then you can get the same effect as doing your - updates in a frameRenderingQueued callback by just calling - RenderWindow::update with the 'swapBuffers' option set to false. + particular event. Really if you're running your own rendering loop at + this level of detail then you can get the same effect as doing your + updates in a frameRenderingQueued callback by just calling + RenderWindow::update with the 'swapBuffers' option set to false. */ bool _fireFrameRenderingQueued(); /** Method for raising frame ended events. @@ -846,13 +846,13 @@ namespace Ogre bool _fireFrameEnded(); /** Gets the number of the next frame to be rendered. - @remarks - Note that this is 'next frame' rather than 'current frame' because - it indicates the frame number that current changes made to the scene - will take effect. It is incremented after all rendering commands for - the current frame have been queued, thus reflecting that if you - start performing changes then, you will actually see them in the - next frame. */ + @remarks + Note that this is 'next frame' rather than 'current frame' because + it indicates the frame number that current changes made to the scene + will take effect. It is incremented after all rendering commands for + the current frame have been queued, thus reflecting that if you + start performing changes then, you will actually see them in the + next frame. */ unsigned long getNextFrameNumber(void) const { return mNextFrame; } /** Returns the scene manager currently being used to render a frame. @@ -866,11 +866,11 @@ namespace Ogre This is only intended for internal use. */ void _pushCurrentSceneManager(SceneManager* sm); - /** Pops the scene manager currently being used to render. - @remarks - This is only intended for internal use. - */ - void _popCurrentSceneManager(SceneManager* sm); + /** Pops the scene manager currently being used to render. + @remarks + This is only intended for internal use. + */ + void _popCurrentSceneManager(SceneManager* sm); /** Internal method used for updating all RenderTarget objects (windows, renderable textures etc) which are set to auto-update. @@ -880,49 +880,49 @@ namespace Ogre you may wish to call it to update all the render targets which are set to auto update (RenderTarget::setAutoUpdated). You can also update individual RenderTarget instances using their own update() method. - @return false if a FrameListener indicated it wishes to exit the render loop + @return false if a FrameListener indicated it wishes to exit the render loop */ bool _updateAllRenderTargets(void); /** Internal method used for updating all RenderTarget objects (windows, renderable textures etc) which are set to auto-update, with a custom time - passed to the frameRenderingQueued events. + passed to the frameRenderingQueued events. @remarks You don't need to use this method if you're using Ogre's own internal rendering loop (Root::startRendering). If you're running your own loop you may wish to call it to update all the render targets which are set to auto update (RenderTarget::setAutoUpdated). You can also update individual RenderTarget instances using their own update() method. - @return false if a FrameListener indicated it wishes to exit the render loop + @return false if a FrameListener indicated it wishes to exit the render loop */ bool _updateAllRenderTargets(FrameEvent& evt); - /** Create a new RenderQueueInvocationSequence, useful for linking to - Viewport instances to perform custom rendering. - @param name The name to give the new sequence - */ - RenderQueueInvocationSequence* createRenderQueueInvocationSequence( - const String& name); - - /** Get a RenderQueueInvocationSequence. - @param name The name to identify the sequence - */ - RenderQueueInvocationSequence* getRenderQueueInvocationSequence( - const String& name); - - /** Destroy a RenderQueueInvocationSequence. - @remarks - You must ensure that no Viewports are using this sequence. - @param name The name to identify the sequence - */ - void destroyRenderQueueInvocationSequence( - const String& name); - - /** Destroy all RenderQueueInvocationSequences. - @remarks - You must ensure that no Viewports are using custom sequences. - */ - void destroyAllRenderQueueInvocationSequences(void); + /** Create a new RenderQueueInvocationSequence, useful for linking to + Viewport instances to perform custom rendering. + @param name The name to give the new sequence + */ + RenderQueueInvocationSequence* createRenderQueueInvocationSequence( + const String& name); + + /** Get a RenderQueueInvocationSequence. + @param name The name to identify the sequence + */ + RenderQueueInvocationSequence* getRenderQueueInvocationSequence( + const String& name); + + /** Destroy a RenderQueueInvocationSequence. + @remarks + You must ensure that no Viewports are using this sequence. + @param name The name to identify the sequence + */ + void destroyRenderQueueInvocationSequence( + const String& name); + + /** Destroy all RenderQueueInvocationSequences. + @remarks + You must ensure that no Viewports are using custom sequences. + */ + void destroyAllRenderQueueInvocationSequences(void); /** Override standard Singleton retrieval. @remarks @@ -957,142 +957,142 @@ namespace Ogre */ static Root* getSingletonPtr(void); - /** Clears the history of all event times. - @remarks - OGRE stores a history of the last few event times in order to smooth - out any inaccuracies and temporary fluctuations. However, if you - pause or don't render for a little while this can cause a lurch, so - if you're resuming rendering after a break, call this method to reset - the stored times - */ - void clearEventTimes(void); - - /** Sets the period over which OGRE smooths out fluctuations in frame times. - @remarks - OGRE by default gives you the raw frame time, but can optionally - smooths it out over several frames, in order to reduce the - noticeable effect of occasional hiccups in framerate. - These smoothed values are passed back as parameters to FrameListener - calls. - @par - This method allow you to tweak the smoothing period, and is expressed - in seconds. Setting it to 0 will result in completely unsmoothed - frame times (the default). - */ - void setFrameSmoothingPeriod(Real period) { mFrameSmoothingTime = period; } - /** Gets the period over which OGRE smooths out fluctuations in frame times. */ - Real getFrameSmoothingPeriod(void) const { return mFrameSmoothingTime; } - - /** Register a new MovableObjectFactory which will create new MovableObject - instances of a particular type, as identified by the getType() method. - @remarks - Plugin creators can create subclasses of MovableObjectFactory which - construct custom subclasses of MovableObject for insertion in the - scene. This is the primary way that plugins can make custom objects - available. - @param fact Pointer to the factory instance - @param overrideExisting Set this to true to override any existing - factories which are registered for the same type. You should only - change this if you are very sure you know what you're doing. - */ - void addMovableObjectFactory(MovableObjectFactory* fact, - bool overrideExisting = false); - /** Removes a previously registered MovableObjectFactory. - @remarks - All instances of objects created by this factory will be destroyed - before removing the factory (by calling back the factories - 'destroyInstance' method). The plugin writer is responsible for actually - destroying the factory. - */ - void removeMovableObjectFactory(MovableObjectFactory* fact); - /// Checks whether a factory is registered for a given MovableObject type - bool hasMovableObjectFactory(const String& typeName) const; - /// Get a MovableObjectFactory for the given type - MovableObjectFactory* getMovableObjectFactory(const String& typeName); - /** Allocate the next MovableObject type flag. - @remarks - This is done automatically if MovableObjectFactory::requestTypeFlags - returns true; don't call this manually unless you're sure you need to. - */ - uint32 _allocateNextMovableObjectTypeFlag(void); - - typedef ConstMapIterator MovableObjectFactoryIterator; - /** Return an iterator over all the MovableObjectFactory instances currently - registered. - */ - MovableObjectFactoryIterator getMovableObjectFactoryIterator(void) const; - - /** - * Gets the number of display monitors. - */ - unsigned int getDisplayMonitorCount() const; - - /** Get the WorkQueue for processing background tasks. - You are free to add new requests and handlers to this queue to - process your custom background tasks using the shared thread pool. - However, you must remember to assign yourself a new channel through - which to process your tasks. - */ - WorkQueue* getWorkQueue() const { return mWorkQueue; } - - /** Replace the current work queue with an alternative. - You can use this method to replace the internal implementation of - WorkQueue with your own, e.g. to externalise the processing of - background events. Doing so will delete the existing queue and - replace it with this one. - @param queue The new WorkQueue instance. Root will delete this work queue - at shutdown, so do not destroy it yourself. - */ - void setWorkQueue(WorkQueue* queue); - - /** Sets whether blend indices information needs to be passed to the GPU. - When entities use software animation they remove blend information such as - indices and weights from the vertex buffers sent to the graphic card. This function - can be used to limit which information is removed. - @param redundant Set to true to remove blend indices information. - */ - void setBlendIndicesGpuRedundant(bool redundant) { mIsBlendIndicesGpuRedundant = redundant; } - /** Returns whether blend indices information needs to be passed to the GPU - see setBlendIndicesGpuRedundant() for more information - */ - bool isBlendIndicesGpuRedundant() const { return mIsBlendIndicesGpuRedundant; } - - /** Sets whether blend weights information needs to be passed to the GPU. - When entities use software animation they remove blend information such as - indices and weights from the vertex buffers sent to the graphic card. This function - can be used to limit which information is removed. - @param redundant Set to true to remove blend weights information. - */ - void setBlendWeightsGpuRedundant(bool redundant) { mIsBlendWeightsGpuRedundant = redundant; } - /** Returns whether blend weights information needs to be passed to the GPU - see setBlendWeightsGpuRedundant() for more information - */ - bool isBlendWeightsGpuRedundant() const { return mIsBlendWeightsGpuRedundant; } - - /** Set the default minimum pixel size for object to be rendered by - @note - To use this feature see Camera::setUseMinPixelSize() - */ - void setDefaultMinPixelSize(Real pixelSize) { mDefaultMinPixelSize = pixelSize; } - - /** Get the default minimum pixel size for object to be rendered by - */ - Real getDefaultMinPixelSize() { return mDefaultMinPixelSize; } - - /** Set the default upload option for buffers that frequently changed - Setting upload option to HBU_ON_DEMAND can increase the framerate in multi-device scenarios, - as it will upload frequently changing buffers to devices that require them. - However setting the HBU_ON_DEMAND may also introduce hiccups. - */ - void setFreqUpdatedBuffersUploadOption(HardwareBuffer::UploadOptions uploadOp) { mFreqUpdatedBuffersUploadOption = uploadOp; } - /** Get the default upload option for buffers that frequently changed - @note - To use this feature see Camera::setFreqUpdatedBuffersUploadOption() - */ - HardwareBuffer::UploadOptions getFreqUpdatedBuffersUploadOption() const { return mFreqUpdatedBuffersUploadOption; } + /** Clears the history of all event times. + @remarks + OGRE stores a history of the last few event times in order to smooth + out any inaccuracies and temporary fluctuations. However, if you + pause or don't render for a little while this can cause a lurch, so + if you're resuming rendering after a break, call this method to reset + the stored times + */ + void clearEventTimes(void); + + /** Sets the period over which OGRE smooths out fluctuations in frame times. + @remarks + OGRE by default gives you the raw frame time, but can optionally + smooths it out over several frames, in order to reduce the + noticeable effect of occasional hiccups in framerate. + These smoothed values are passed back as parameters to FrameListener + calls. + @par + This method allow you to tweak the smoothing period, and is expressed + in seconds. Setting it to 0 will result in completely unsmoothed + frame times (the default). + */ + void setFrameSmoothingPeriod(Real period) { mFrameSmoothingTime = period; } + /** Gets the period over which OGRE smooths out fluctuations in frame times. */ + Real getFrameSmoothingPeriod(void) const { return mFrameSmoothingTime; } + + /** Register a new MovableObjectFactory which will create new MovableObject + instances of a particular type, as identified by the getType() method. + @remarks + Plugin creators can create subclasses of MovableObjectFactory which + construct custom subclasses of MovableObject for insertion in the + scene. This is the primary way that plugins can make custom objects + available. + @param fact Pointer to the factory instance + @param overrideExisting Set this to true to override any existing + factories which are registered for the same type. You should only + change this if you are very sure you know what you're doing. + */ + void addMovableObjectFactory(MovableObjectFactory* fact, + bool overrideExisting = false); + /** Removes a previously registered MovableObjectFactory. + @remarks + All instances of objects created by this factory will be destroyed + before removing the factory (by calling back the factories + 'destroyInstance' method). The plugin writer is responsible for actually + destroying the factory. + */ + void removeMovableObjectFactory(MovableObjectFactory* fact); + /// Checks whether a factory is registered for a given MovableObject type + bool hasMovableObjectFactory(const String& typeName) const; + /// Get a MovableObjectFactory for the given type + MovableObjectFactory* getMovableObjectFactory(const String& typeName); + /** Allocate the next MovableObject type flag. + @remarks + This is done automatically if MovableObjectFactory::requestTypeFlags + returns true; don't call this manually unless you're sure you need to. + */ + uint32 _allocateNextMovableObjectTypeFlag(void); + + typedef ConstMapIterator MovableObjectFactoryIterator; + /** Return an iterator over all the MovableObjectFactory instances currently + registered. + */ + MovableObjectFactoryIterator getMovableObjectFactoryIterator(void) const; + + /** + * Gets the number of display monitors. + */ + unsigned int getDisplayMonitorCount() const; + + /** Get the WorkQueue for processing background tasks. + You are free to add new requests and handlers to this queue to + process your custom background tasks using the shared thread pool. + However, you must remember to assign yourself a new channel through + which to process your tasks. + */ + WorkQueue* getWorkQueue() const { return mWorkQueue; } + + /** Replace the current work queue with an alternative. + You can use this method to replace the internal implementation of + WorkQueue with your own, e.g. to externalise the processing of + background events. Doing so will delete the existing queue and + replace it with this one. + @param queue The new WorkQueue instance. Root will delete this work queue + at shutdown, so do not destroy it yourself. + */ + void setWorkQueue(WorkQueue* queue); + + /** Sets whether blend indices information needs to be passed to the GPU. + When entities use software animation they remove blend information such as + indices and weights from the vertex buffers sent to the graphic card. This function + can be used to limit which information is removed. + @param redundant Set to true to remove blend indices information. + */ + void setBlendIndicesGpuRedundant(bool redundant) { mIsBlendIndicesGpuRedundant = redundant; } + /** Returns whether blend indices information needs to be passed to the GPU + see setBlendIndicesGpuRedundant() for more information + */ + bool isBlendIndicesGpuRedundant() const { return mIsBlendIndicesGpuRedundant; } + + /** Sets whether blend weights information needs to be passed to the GPU. + When entities use software animation they remove blend information such as + indices and weights from the vertex buffers sent to the graphic card. This function + can be used to limit which information is removed. + @param redundant Set to true to remove blend weights information. + */ + void setBlendWeightsGpuRedundant(bool redundant) { mIsBlendWeightsGpuRedundant = redundant; } + /** Returns whether blend weights information needs to be passed to the GPU + see setBlendWeightsGpuRedundant() for more information + */ + bool isBlendWeightsGpuRedundant() const { return mIsBlendWeightsGpuRedundant; } + + /** Set the default minimum pixel size for object to be rendered by + @note + To use this feature see Camera::setUseMinPixelSize() + */ + void setDefaultMinPixelSize(Real pixelSize) { mDefaultMinPixelSize = pixelSize; } + + /** Get the default minimum pixel size for object to be rendered by + */ + Real getDefaultMinPixelSize() { return mDefaultMinPixelSize; } + + /** Set the default upload option for buffers that frequently changed + Setting upload option to HBU_ON_DEMAND can increase the framerate in multi-device scenarios, + as it will upload frequently changing buffers to devices that require them. + However setting the HBU_ON_DEMAND may also introduce hiccups. + */ + void setFreqUpdatedBuffersUploadOption(HardwareBuffer::UploadOptions uploadOp) { mFreqUpdatedBuffersUploadOption = uploadOp; } + /** Get the default upload option for buffers that frequently changed + @note + To use this feature see Camera::setFreqUpdatedBuffersUploadOption() + */ + HardwareBuffer::UploadOptions getFreqUpdatedBuffersUploadOption() const { return mFreqUpdatedBuffersUploadOption; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // Namespace Ogre #endif diff --git a/OgreMain/include/OgreRotationalSpline.h b/OgreMain/include/OgreRotationalSpline.h index 9958432a065..1b869350bd4 100644 --- a/OgreMain/include/OgreRotationalSpline.h +++ b/OgreMain/include/OgreRotationalSpline.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** This class interpolates orientations (rotations) along a spline using + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** This class interpolates orientations (rotations) along a spline using derivatives of quaternions. @remarks Like the SimpleSpline class, this class is about interpolating values @@ -55,7 +55,7 @@ namespace Ogre { generate an extra quaternion in between each actual quaternion which when take with the original quaternion forms the 'tangent' of that quaternion. */ - class _OgreExport RotationalSpline + class _OgreExport RotationalSpline { public: RotationalSpline(); @@ -84,14 +84,14 @@ namespace Ogre { Given a t value between 0 and 1 representing the parametric distance along the whole length of the spline, this method returns an interpolated point. @param t Parametric value. - @param useShortestPath Defines if rotation should take the shortest possible path + @param useShortestPath Defines if rotation should take the shortest possible path */ Quaternion interpolate(Real t, bool useShortestPath=true); /** Interpolates a single segment of the spline given a parametric value. @param fromIndex The point index to treat as t=0. fromIndex + 1 is deemed to be t=1 @param t Parametric value - @param useShortestPath Defines if rotation should take the shortest possible path + @param useShortestPath Defines if rotation should take the shortest possible path */ Quaternion interpolate(unsigned int fromIndex, Real t, bool useShortestPath=true); @@ -127,8 +127,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreSceneManager.h b/OgreMain/include/OgreSceneManager.h index ebe812cf010..31535d1a689 100644 --- a/OgreMain/include/OgreSceneManager.h +++ b/OgreMain/include/OgreSceneManager.h @@ -51,12 +51,12 @@ Torus Knot Software Ltd. #include "OgreNameGenerator.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ /** Structure for holding a position & orientation pair. */ struct ViewPoint @@ -65,8 +65,8 @@ namespace Ogre { Quaternion orientation; }; - // Forward declarations - class CompositorChain; + // Forward declarations + class CompositorChain; class InstancedGeometry; class Rectangle2D; class LodListener; @@ -74,83 +74,83 @@ namespace Ogre { struct EntityMeshLodChangedEvent; struct EntityMaterialLodChangedEvent; - /** Structure collecting together information about the visible objects - that have been discovered in a scene. - */ - struct _OgreExport VisibleObjectsBoundsInfo - { - /// The axis-aligned bounds of the visible objects - AxisAlignedBox aabb; - /// The axis-aligned bounds of the visible shadow receiver objects - AxisAlignedBox receiverAabb; - /// The closest a visible object is to the camera - Real minDistance; - /// The farthest a visible objects is from the camera - Real maxDistance; - /// The closest a object in the frustum regardless of visibility / shadow caster flags - Real minDistanceInFrustum; - /// The farthest object in the frustum regardless of visibility / shadow caster flags - Real maxDistanceInFrustum; - - VisibleObjectsBoundsInfo(); - void reset(); - void merge(const AxisAlignedBox& boxBounds, const Sphere& sphereBounds, - const Camera* cam, bool receiver=true); - /** Merge an object that is not being rendered because it's not a shadow caster, - but is a shadow receiver so should be included in the range. - */ - void mergeNonRenderedButInFrustum(const AxisAlignedBox& boxBounds, - const Sphere& sphereBounds, const Camera* cam); - - - }; + /** Structure collecting together information about the visible objects + that have been discovered in a scene. + */ + struct _OgreExport VisibleObjectsBoundsInfo + { + /// The axis-aligned bounds of the visible objects + AxisAlignedBox aabb; + /// The axis-aligned bounds of the visible shadow receiver objects + AxisAlignedBox receiverAabb; + /// The closest a visible object is to the camera + Real minDistance; + /// The farthest a visible objects is from the camera + Real maxDistance; + /// The closest a object in the frustum regardless of visibility / shadow caster flags + Real minDistanceInFrustum; + /// The farthest object in the frustum regardless of visibility / shadow caster flags + Real maxDistanceInFrustum; + + VisibleObjectsBoundsInfo(); + void reset(); + void merge(const AxisAlignedBox& boxBounds, const Sphere& sphereBounds, + const Camera* cam, bool receiver=true); + /** Merge an object that is not being rendered because it's not a shadow caster, + but is a shadow receiver so should be included in the range. + */ + void mergeNonRenderedButInFrustum(const AxisAlignedBox& boxBounds, + const Sphere& sphereBounds, const Camera* cam); + + + }; /** Manages the organisation and rendering of a 'scene' i.e. a collection - of objects and potentially world geometry. + of objects and potentially world geometry. @remarks - This class defines the interface and the basic behaviour of a - 'Scene Manager'. A SceneManager organises the culling and rendering of - the scene, in conjunction with the RenderQueue. This class is designed - to be extended through subclassing in order to provide more specialised - scene organisation structures for particular needs. The default - SceneManager culls based on a hierarchy of node bounding boxes, other - implementations can use an octree (@see OctreeSceneManager), a BSP - tree (@see BspSceneManager), and many other options. New SceneManager - implementations can be added at runtime by plugins, see - SceneManagerEnumerator for the interfaces for adding new SceneManager - types. - @par - There is a distinction between 'objects' (which subclass MovableObject, - and are movable, discrete objects in the world), and 'world geometry', - which is large, generally static geometry. World geometry tends to - influence the SceneManager organisational structure (e.g. lots of indoor - static geometry might result in a spatial tree structure) and as such - world geometry is generally tied to a given SceneManager implementation, - whilst MovableObject instances can be used with any SceneManager. - Subclasses are free to define world geometry however they please. - @par - Multiple SceneManager instances can exist at one time, each one with - a distinct scene. Which SceneManager is used to render a scene is - dependent on the Camera, which will always call back the SceneManager - which created it to render the scene. + This class defines the interface and the basic behaviour of a + 'Scene Manager'. A SceneManager organises the culling and rendering of + the scene, in conjunction with the RenderQueue. This class is designed + to be extended through subclassing in order to provide more specialised + scene organisation structures for particular needs. The default + SceneManager culls based on a hierarchy of node bounding boxes, other + implementations can use an octree (@see OctreeSceneManager), a BSP + tree (@see BspSceneManager), and many other options. New SceneManager + implementations can be added at runtime by plugins, see + SceneManagerEnumerator for the interfaces for adding new SceneManager + types. + @par + There is a distinction between 'objects' (which subclass MovableObject, + and are movable, discrete objects in the world), and 'world geometry', + which is large, generally static geometry. World geometry tends to + influence the SceneManager organisational structure (e.g. lots of indoor + static geometry might result in a spatial tree structure) and as such + world geometry is generally tied to a given SceneManager implementation, + whilst MovableObject instances can be used with any SceneManager. + Subclasses are free to define world geometry however they please. + @par + Multiple SceneManager instances can exist at one time, each one with + a distinct scene. Which SceneManager is used to render a scene is + dependent on the Camera, which will always call back the SceneManager + which created it to render the scene. */ - class _OgreExport SceneManager : public SceneMgtAlloc + class _OgreExport SceneManager : public SceneMgtAlloc { public: /// Query type mask which will be used for world geometry @see SceneQuery static uint32 WORLD_GEOMETRY_TYPE_MASK; - /// Query type mask which will be used for entities @see SceneQuery - static uint32 ENTITY_TYPE_MASK; - /// Query type mask which will be used for effects like billboardsets / particle systems @see SceneQuery - static uint32 FX_TYPE_MASK; - /// Query type mask which will be used for StaticGeometry @see SceneQuery - static uint32 STATICGEOMETRY_TYPE_MASK; - /// Query type mask which will be used for lights @see SceneQuery - static uint32 LIGHT_TYPE_MASK; - /// Query type mask which will be used for frusta and cameras @see SceneQuery - static uint32 FRUSTUM_TYPE_MASK; - /// User type mask limit - static uint32 USER_TYPE_MASK_LIMIT; + /// Query type mask which will be used for entities @see SceneQuery + static uint32 ENTITY_TYPE_MASK; + /// Query type mask which will be used for effects like billboardsets / particle systems @see SceneQuery + static uint32 FX_TYPE_MASK; + /// Query type mask which will be used for StaticGeometry @see SceneQuery + static uint32 STATICGEOMETRY_TYPE_MASK; + /// Query type mask which will be used for lights @see SceneQuery + static uint32 LIGHT_TYPE_MASK; + /// Query type mask which will be used for frusta and cameras @see SceneQuery + static uint32 FRUSTUM_TYPE_MASK; + /// User type mask limit + static uint32 USER_TYPE_MASK_LIMIT; /** Comparator for material map, for sorting materials into render order (e.g. transparent last). */ struct materialLess @@ -174,207 +174,207 @@ namespace Ogre { IRS_RENDER_RECEIVER_PASS }; - /** Enumeration of the possible modes allowed for processing the special case - render queue list. - @see SceneManager::setSpecialCaseRenderQueueMode - */ - enum SpecialCaseRenderQueueMode - { - /// Render only the queues in the special case list - SCRQM_INCLUDE, - /// Render all except the queues in the special case list - SCRQM_EXCLUDE - }; - - struct SkyDomeGenParameters - { - Real skyDomeCurvature; - Real skyDomeTiling; - Real skyDomeDistance; - int skyDomeXSegments; - int skyDomeYSegments; - int skyDomeYSegments_keep; - }; - - struct SkyPlaneGenParameters - { - Real skyPlaneScale; - Real skyPlaneTiling; - Real skyPlaneBow; - int skyPlaneXSegments; - int skyPlaneYSegments; - }; - - struct SkyBoxGenParameters - { - Real skyBoxDistance; - }; - - /** Class that allows listening in on the various stages of SceneManager - processing, so that custom behaviour can be implemented from outside. - */ - class Listener - { - public: - Listener() {} - virtual ~Listener() {} - - /** Called prior to updating the scene graph in this SceneManager. - @remarks - This is called before updating the scene graph for a camera. - @param source The SceneManager instance raising this event. - @param camera The camera being updated. - */ - virtual void preUpdateSceneGraph(SceneManager* source, Camera* camera) + /** Enumeration of the possible modes allowed for processing the special case + render queue list. + @see SceneManager::setSpecialCaseRenderQueueMode + */ + enum SpecialCaseRenderQueueMode + { + /// Render only the queues in the special case list + SCRQM_INCLUDE, + /// Render all except the queues in the special case list + SCRQM_EXCLUDE + }; + + struct SkyDomeGenParameters + { + Real skyDomeCurvature; + Real skyDomeTiling; + Real skyDomeDistance; + int skyDomeXSegments; + int skyDomeYSegments; + int skyDomeYSegments_keep; + }; + + struct SkyPlaneGenParameters + { + Real skyPlaneScale; + Real skyPlaneTiling; + Real skyPlaneBow; + int skyPlaneXSegments; + int skyPlaneYSegments; + }; + + struct SkyBoxGenParameters + { + Real skyBoxDistance; + }; + + /** Class that allows listening in on the various stages of SceneManager + processing, so that custom behaviour can be implemented from outside. + */ + class Listener + { + public: + Listener() {} + virtual ~Listener() {} + + /** Called prior to updating the scene graph in this SceneManager. + @remarks + This is called before updating the scene graph for a camera. + @param source The SceneManager instance raising this event. + @param camera The camera being updated. + */ + virtual void preUpdateSceneGraph(SceneManager* source, Camera* camera) { (void)source; (void)camera; } - /** Called after updating the scene graph in this SceneManager. - @remarks - This is called after updating the scene graph for a camera. - @param source The SceneManager instance raising this event. - @param camera The camera being updated. - */ - virtual void postUpdateSceneGraph(SceneManager* source, Camera* camera) + /** Called after updating the scene graph in this SceneManager. + @remarks + This is called after updating the scene graph for a camera. + @param source The SceneManager instance raising this event. + @param camera The camera being updated. + */ + virtual void postUpdateSceneGraph(SceneManager* source, Camera* camera) { (void)source; (void)camera; } - /** Called prior to searching for visible objects in this SceneManager. - @remarks - Note that the render queue at this stage will be full of the last - render's contents and will be cleared after this method is called. - @param source The SceneManager instance raising this event. - @param irs The stage of illumination being dealt with. IRS_NONE for - a regular render, IRS_RENDER_TO_TEXTURE for a shadow caster render. - @param v The viewport being updated. You can get the camera from here. - */ - virtual void preFindVisibleObjects(SceneManager* source, - IlluminationRenderStage irs, Viewport* v) + /** Called prior to searching for visible objects in this SceneManager. + @remarks + Note that the render queue at this stage will be full of the last + render's contents and will be cleared after this method is called. + @param source The SceneManager instance raising this event. + @param irs The stage of illumination being dealt with. IRS_NONE for + a regular render, IRS_RENDER_TO_TEXTURE for a shadow caster render. + @param v The viewport being updated. You can get the camera from here. + */ + virtual void preFindVisibleObjects(SceneManager* source, + IlluminationRenderStage irs, Viewport* v) { (void)source; (void)irs; (void)v; } - /** Called after searching for visible objects in this SceneManager. - @remarks - Note that the render queue at this stage will be full of the current - scenes contents, ready for rendering. You may manually add renderables - to this queue if you wish. - @param source The SceneManager instance raising this event. - @param irs The stage of illumination being dealt with. IRS_NONE for - a regular render, IRS_RENDER_TO_TEXTURE for a shadow caster render. - @param v The viewport being updated. You can get the camera from here. - */ - virtual void postFindVisibleObjects(SceneManager* source, - IlluminationRenderStage irs, Viewport* v) + /** Called after searching for visible objects in this SceneManager. + @remarks + Note that the render queue at this stage will be full of the current + scenes contents, ready for rendering. You may manually add renderables + to this queue if you wish. + @param source The SceneManager instance raising this event. + @param irs The stage of illumination being dealt with. IRS_NONE for + a regular render, IRS_RENDER_TO_TEXTURE for a shadow caster render. + @param v The viewport being updated. You can get the camera from here. + */ + virtual void postFindVisibleObjects(SceneManager* source, + IlluminationRenderStage irs, Viewport* v) { (void)source; (void)irs; (void)v; } - /** Event raised after all shadow textures have been rendered into for - all queues / targets but before any other geometry has been rendered - (including main scene geometry and any additional shadow receiver - passes). - @remarks - This callback is useful for those that wish to perform some - additional processing on shadow textures before they are used to - render shadows. For example you could perform some filtering by - rendering the existing shadow textures into another alternative - shadow texture with a shader.] - @note - This event will only be fired when texture shadows are in use. - @param numberOfShadowTextures The number of shadow textures in use - */ - virtual void shadowTexturesUpdated(size_t numberOfShadowTextures) + /** Event raised after all shadow textures have been rendered into for + all queues / targets but before any other geometry has been rendered + (including main scene geometry and any additional shadow receiver + passes). + @remarks + This callback is useful for those that wish to perform some + additional processing on shadow textures before they are used to + render shadows. For example you could perform some filtering by + rendering the existing shadow textures into another alternative + shadow texture with a shader.] + @note + This event will only be fired when texture shadows are in use. + @param numberOfShadowTextures The number of shadow textures in use + */ + virtual void shadowTexturesUpdated(size_t numberOfShadowTextures) { (void)numberOfShadowTextures; } - /** This event occurs just before the view & projection matrices are - set for rendering into a shadow texture. - @remarks - You can use this event hook to perform some custom processing, - such as altering the camera being used for rendering the light's - view, including setting custom view & projection matrices if you - want to perform an advanced shadow technique. - @note - This event will only be fired when texture shadows are in use. - @param light Pointer to the light for which shadows are being rendered - @param camera Pointer to the camera being used to render - @param iteration For lights that use multiple shadow textures, the iteration number - */ - virtual void shadowTextureCasterPreViewProj(Light* light, - Camera* camera, size_t iteration) + /** This event occurs just before the view & projection matrices are + set for rendering into a shadow texture. + @remarks + You can use this event hook to perform some custom processing, + such as altering the camera being used for rendering the light's + view, including setting custom view & projection matrices if you + want to perform an advanced shadow technique. + @note + This event will only be fired when texture shadows are in use. + @param light Pointer to the light for which shadows are being rendered + @param camera Pointer to the camera being used to render + @param iteration For lights that use multiple shadow textures, the iteration number + */ + virtual void shadowTextureCasterPreViewProj(Light* light, + Camera* camera, size_t iteration) { (void)light; (void)camera; (void)iteration; } - /** This event occurs just before the view & projection matrices are - set for re-rendering a shadow receiver. - @remarks - You can use this event hook to perform some custom processing, - such as altering the projection frustum being used for rendering - the shadow onto the receiver to perform an advanced shadow - technique. - @note - This event will only be fired when texture shadows are in use. - @param light Pointer to the light for which shadows are being rendered - @param frustum Pointer to the projection frustum being used to project - the shadow texture - */ - virtual void shadowTextureReceiverPreViewProj(Light* light, - Frustum* frustum) + /** This event occurs just before the view & projection matrices are + set for re-rendering a shadow receiver. + @remarks + You can use this event hook to perform some custom processing, + such as altering the projection frustum being used for rendering + the shadow onto the receiver to perform an advanced shadow + technique. + @note + This event will only be fired when texture shadows are in use. + @param light Pointer to the light for which shadows are being rendered + @param frustum Pointer to the projection frustum being used to project + the shadow texture + */ + virtual void shadowTextureReceiverPreViewProj(Light* light, + Frustum* frustum) { (void)light; (void)frustum; } - /** Hook to allow the listener to override the ordering of lights for - the entire frustum. - @remarks - Whilst ordinarily lights are sorted per rendered object - (@see MovableObject::queryLights), texture shadows adds another issue - in that, given there is a finite number of shadow textures, we must - choose which lights to render texture shadows from based on the entire - frustum. These lights should always be listed first in every objects - own list, followed by any other lights which will not cast texture - shadows (either because they have shadow casting off, or there aren't - enough shadow textures to service them). - @par - This hook allows you to override the detailed ordering of the lights - per frustum. The default ordering is shadow casters first (which you - must also respect if you override this method), and ordered - by distance from the camera within those 2 groups. Obviously the closest - lights with shadow casting enabled will be listed first. Only lights - within the range of the frustum will be in the list. - @param lightList The list of lights within range of the frustum which you - may sort. - @return true if you sorted the list, false otherwise. - */ - virtual bool sortLightsAffectingFrustum(LightList& lightList) + /** Hook to allow the listener to override the ordering of lights for + the entire frustum. + @remarks + Whilst ordinarily lights are sorted per rendered object + (@see MovableObject::queryLights), texture shadows adds another issue + in that, given there is a finite number of shadow textures, we must + choose which lights to render texture shadows from based on the entire + frustum. These lights should always be listed first in every objects + own list, followed by any other lights which will not cast texture + shadows (either because they have shadow casting off, or there aren't + enough shadow textures to service them). + @par + This hook allows you to override the detailed ordering of the lights + per frustum. The default ordering is shadow casters first (which you + must also respect if you override this method), and ordered + by distance from the camera within those 2 groups. Obviously the closest + lights with shadow casting enabled will be listed first. Only lights + within the range of the frustum will be in the list. + @param lightList The list of lights within range of the frustum which you + may sort. + @return true if you sorted the list, false otherwise. + */ + virtual bool sortLightsAffectingFrustum(LightList& lightList) { (void)lightList; return false; } - /** Event notifying the listener of the SceneManager's destruction. */ - virtual void sceneManagerDestroyed(SceneManager* source) + /** Event notifying the listener of the SceneManager's destruction. */ + virtual void sceneManagerDestroyed(SceneManager* source) { (void)source; } - }; - - /** Inner helper class to implement the visitor pattern for rendering objects - in a queue. - */ - class _OgreExport SceneMgrQueuedRenderableVisitor : public QueuedRenderableVisitor - { - protected: - /// Pass that was actually used at the grouping level - const Pass* mUsedPass; - public: - SceneMgrQueuedRenderableVisitor() - :transparentShadowCastersMode(false) {} - ~SceneMgrQueuedRenderableVisitor() {} - void visit(Renderable* r); - bool visit(const Pass* p); - void visit(RenderablePass* rp); - - /// Target SM to send renderables to - SceneManager* targetSceneMgr; - /// Are we in transparent shadow caster mode? - bool transparentShadowCastersMode; - /// Automatic light handling? - bool autoLights; - /// Manual light list - const LightList* manualLightList; - /// Scissoring if requested? - bool scissoring; - - }; - /// Allow visitor helper to access protected methods - friend class SceneMgrQueuedRenderableVisitor; + }; + + /** Inner helper class to implement the visitor pattern for rendering objects + in a queue. + */ + class _OgreExport SceneMgrQueuedRenderableVisitor : public QueuedRenderableVisitor + { + protected: + /// Pass that was actually used at the grouping level + const Pass* mUsedPass; + public: + SceneMgrQueuedRenderableVisitor() + :transparentShadowCastersMode(false) {} + ~SceneMgrQueuedRenderableVisitor() {} + void visit(Renderable* r); + bool visit(const Pass* p); + void visit(RenderablePass* rp); + + /// Target SM to send renderables to + SceneManager* targetSceneMgr; + /// Are we in transparent shadow caster mode? + bool transparentShadowCastersMode; + /// Automatic light handling? + bool autoLights; + /// Manual light list + const LightList* manualLightList; + /// Scissoring if requested? + bool scissoring; + + }; + /// Allow visitor helper to access protected methods + friend class SceneMgrQueuedRenderableVisitor; protected: @@ -383,12 +383,12 @@ namespace Ogre { /// Subclasses can override this to ensure their specialised SceneNode is used. virtual SceneNode* createSceneNodeImpl(const String& name); - /// Instance name - String mName; + /// Instance name + String mName; /// Queue of objects for rendering RenderQueue* mRenderQueue; - bool mLastRenderQueueInvocationCustom; + bool mLastRenderQueueInvocationCustom; /// Current ambient light, cached for RenderSystem ColourValue mAmbientLight; @@ -402,13 +402,13 @@ namespace Ogre { */ CameraList mCameras; - typedef map::type StaticGeometryList; - StaticGeometryList mStaticGeometryList; - typedef map::type InstancedGeometryList; - InstancedGeometryList mInstancedGeometryList; + typedef map::type StaticGeometryList; + StaticGeometryList mStaticGeometryList; + typedef map::type InstancedGeometryList; + InstancedGeometryList mInstancedGeometryList; - typedef map::type InstanceManagerMap; - InstanceManagerMap mInstanceManagerMap; + typedef map::type InstanceManagerMap; + InstanceManagerMap mInstanceManagerMap; typedef map::type SceneNodeList; @@ -465,41 +465,41 @@ namespace Ogre { Real mFogEnd; Real mFogDensity; - typedef set::type SpecialCaseRenderQueueList; - SpecialCaseRenderQueueList mSpecialCaseQueueList; - SpecialCaseRenderQueueMode mSpecialCaseQueueMode; - uint8 mWorldGeometryRenderQueue; - - unsigned long mLastFrameNumber; - Matrix4 mTempXform[256]; - bool mResetIdentityView; - bool mResetIdentityProj; - - bool mNormaliseNormalsOnScale; - bool mFlipCullingOnNegativeScale; - CullingMode mPassCullingMode; - - protected: - - /** Visible objects bounding box list. - @remarks - Holds an ABB for each camera that contains the physical extends of the visible - scene elements by each camera. The map is crucial for shadow algorithms which - have a focus step to limit the shadow sample distribution to only valid visible - scene elements. - */ - typedef map< const Camera*, VisibleObjectsBoundsInfo>::type CamVisibleObjectsMap; - CamVisibleObjectsMap mCamVisibleObjectsMap; - - /** ShadowCamera to light mapping */ - typedef map< const Camera*, const Light* >::type ShadowCamLightMapping; - ShadowCamLightMapping mShadowCamLightMapping; - - /// Array defining shadow count per light type. - size_t mShadowTextureCountPerType[3]; - - /// Array defining shadow texture index in light list. - vector::type mShadowTextureIndexLightList; + typedef set::type SpecialCaseRenderQueueList; + SpecialCaseRenderQueueList mSpecialCaseQueueList; + SpecialCaseRenderQueueMode mSpecialCaseQueueMode; + uint8 mWorldGeometryRenderQueue; + + unsigned long mLastFrameNumber; + Matrix4 mTempXform[256]; + bool mResetIdentityView; + bool mResetIdentityProj; + + bool mNormaliseNormalsOnScale; + bool mFlipCullingOnNegativeScale; + CullingMode mPassCullingMode; + + protected: + + /** Visible objects bounding box list. + @remarks + Holds an ABB for each camera that contains the physical extends of the visible + scene elements by each camera. The map is crucial for shadow algorithms which + have a focus step to limit the shadow sample distribution to only valid visible + scene elements. + */ + typedef map< const Camera*, VisibleObjectsBoundsInfo>::type CamVisibleObjectsMap; + CamVisibleObjectsMap mCamVisibleObjectsMap; + + /** ShadowCamera to light mapping */ + typedef map< const Camera*, const Light* >::type ShadowCamLightMapping; + ShadowCamLightMapping mShadowCamLightMapping; + + /// Array defining shadow count per light type. + size_t mShadowTextureCountPerType[3]; + + /// Array defining shadow texture index in light list. + vector::type mShadowTextureIndexLightList; /// Cached light information, used to tracking light's changes struct _OgreExport LightInfo @@ -508,7 +508,7 @@ namespace Ogre { int type; /// Use int instead of Light::LightTypes to avoid header file dependence Real range; /// Sets to zero if directional light Vector3 position; /// Sets to zero if directional light - uint32 lightMask; /// Light mask + uint32 lightMask; /// Light mask bool operator== (const LightInfo& rhs) const { @@ -526,32 +526,32 @@ namespace Ogre { LightList mLightsAffectingFrustum; LightInfoList mCachedLightInfos; - LightInfoList mTestLightInfos; // potentially new list + LightInfoList mTestLightInfos; // potentially new list ulong mLightsDirtyCounter; - LightList mShadowTextureCurrentCasterLightList; + LightList mShadowTextureCurrentCasterLightList; - typedef map::type MovableObjectMap; - /// Simple structure to hold MovableObject map and a mutex to go with it. - struct MovableObjectCollection - { + typedef map::type MovableObjectMap; + /// Simple structure to hold MovableObject map and a mutex to go with it. + struct MovableObjectCollection + { MovableObjectMap map; OGRE_MUTEX(mutex); - }; - typedef map::type MovableObjectCollectionMap; - MovableObjectCollectionMap mMovableObjectCollectionMap; - NameGenerator mMovableNameGenerator; - /** Gets the movable object collection for the given type name. - @remarks - This method create new collection if the collection does not exist. - */ - MovableObjectCollection* getMovableObjectCollection(const String& typeName); - /** Gets the movable object collection for the given type name. - @remarks - This method throw exception if the collection does not exist. - */ - const MovableObjectCollection* getMovableObjectCollection(const String& typeName) const; - /// Mutex over the collection of MovableObject types - OGRE_MUTEX(mMovableObjectCollectionMapMutex); + }; + typedef map::type MovableObjectCollectionMap; + MovableObjectCollectionMap mMovableObjectCollectionMap; + NameGenerator mMovableNameGenerator; + /** Gets the movable object collection for the given type name. + @remarks + This method create new collection if the collection does not exist. + */ + MovableObjectCollection* getMovableObjectCollection(const String& typeName); + /** Gets the movable object collection for the given type name. + @remarks + This method throw exception if the collection does not exist. + */ + const MovableObjectCollection* getMovableObjectCollection(const String& typeName) const; + /// Mutex over the collection of MovableObject types + OGRE_MUTEX(mMovableObjectCollectionMapMutex); /** Internal method for initialising the render queue. @remarks @@ -646,50 +646,50 @@ namespace Ogre { typedef vector::type RenderQueueListenerList; RenderQueueListenerList mRenderQueueListeners; - typedef vector::type RenderObjectListenerList; - RenderObjectListenerList mRenderObjectListeners; + typedef vector::type RenderObjectListenerList; + RenderObjectListenerList mRenderObjectListeners; typedef vector::type ListenerList; ListenerList mListeners; - /// Internal method for firing the queue start event - virtual void firePreRenderQueues(); - /// Internal method for firing the queue end event - virtual void firePostRenderQueues(); + /// Internal method for firing the queue start event + virtual void firePreRenderQueues(); + /// Internal method for firing the queue end event + virtual void firePostRenderQueues(); /// Internal method for firing the queue start event, returns true if queue is to be skipped virtual bool fireRenderQueueStarted(uint8 id, const String& invocation); /// Internal method for firing the queue end event, returns true if queue is to be repeated virtual bool fireRenderQueueEnded(uint8 id, const String& invocation); - /// Internal method for firing when rendering a single object. - virtual void fireRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, - const LightList* pLightList, bool suppressRenderStateChanges); + /// Internal method for firing when rendering a single object. + virtual void fireRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, + const LightList* pLightList, bool suppressRenderStateChanges); - /// Internal method for firing the texture shadows updated event + /// Internal method for firing the texture shadows updated event virtual void fireShadowTexturesUpdated(size_t numberOfShadowTextures); - /// Internal method for firing the pre caster texture shadows event + /// Internal method for firing the pre caster texture shadows event virtual void fireShadowTexturesPreCaster(Light* light, Camera* camera, size_t iteration); - /// Internal method for firing the pre receiver texture shadows event + /// Internal method for firing the pre receiver texture shadows event virtual void fireShadowTexturesPreReceiver(Light* light, Frustum* f); - /// Internal method for firing pre update scene graph event - virtual void firePreUpdateSceneGraph(Camera* camera); - /// Internal method for firing post update scene graph event - virtual void firePostUpdateSceneGraph(Camera* camera); - /// Internal method for firing find visible objects event - virtual void firePreFindVisibleObjects(Viewport* v); - /// Internal method for firing find visible objects event - virtual void firePostFindVisibleObjects(Viewport* v); - /// Internal method for firing destruction event - virtual void fireSceneManagerDestroyed(); + /// Internal method for firing pre update scene graph event + virtual void firePreUpdateSceneGraph(Camera* camera); + /// Internal method for firing post update scene graph event + virtual void firePostUpdateSceneGraph(Camera* camera); + /// Internal method for firing find visible objects event + virtual void firePreFindVisibleObjects(Viewport* v); + /// Internal method for firing find visible objects event + virtual void firePostFindVisibleObjects(Viewport* v); + /// Internal method for firing destruction event + virtual void fireSceneManagerDestroyed(); /** Internal method for setting the destination viewport for the next render. */ virtual void setViewport(Viewport *vp); - /** Flag that indicates if all of the scene node's bounding boxes should be shown as a wireframe. */ - bool mShowBoundingBoxes; + /** Flag that indicates if all of the scene node's bounding boxes should be shown as a wireframe. */ + bool mShowBoundingBoxes; - /** Internal method for rendering all objects using the default queue sequence. */ - virtual void renderVisibleObjectsDefaultSequence(void); - /** Internal method for rendering all objects using a custom queue sequence. */ - virtual void renderVisibleObjectsCustomSequence(RenderQueueInvocationSequence* s); - /** Internal method for preparing the render queue for use with each render. */ - virtual void prepareRenderQueue(void); + /** Internal method for rendering all objects using the default queue sequence. */ + virtual void renderVisibleObjectsDefaultSequence(void); + /** Internal method for rendering all objects using a custom queue sequence. */ + virtual void renderVisibleObjectsCustomSequence(RenderQueueInvocationSequence* s); + /** Internal method for preparing the render queue for use with each render. */ + virtual void prepareRenderQueue(void); /** Internal utility method for rendering a single object. @@ -697,9 +697,9 @@ namespace Ogre { Assumes that the pass has already been set up. @param rend The renderable to issue to the pipeline @param pass The pass which is being used - @param lightScissoringClipping If true, passes that have the getLightScissorEnabled - and/or getLightClipPlanesEnabled flags will cause calculation and setting of - scissor rectangle and user clip planes. + @param lightScissoringClipping If true, passes that have the getLightScissorEnabled + and/or getLightClipPlanesEnabled flags will cause calculation and setting of + scissor rectangle and user clip planes. @param doLightIteration If true, this method will issue the renderable to the pipeline possibly multiple times, if the pass indicates it should be done once per light @@ -708,19 +708,19 @@ namespace Ogre { which will be used for a single render of this object. */ virtual void renderSingleObject(Renderable* rend, const Pass* pass, - bool lightScissoringClipping, bool doLightIteration, const LightList* manualLightList = 0); + bool lightScissoringClipping, bool doLightIteration, const LightList* manualLightList = 0); - /** Internal method for creating the AutoParamDataSource instance. */ - virtual AutoParamDataSource* createAutoParamDataSource(void) const - { - return OGRE_NEW AutoParamDataSource(); - } + /** Internal method for creating the AutoParamDataSource instance. */ + virtual AutoParamDataSource* createAutoParamDataSource(void) const + { + return OGRE_NEW AutoParamDataSource(); + } /// Utility class for calculating automatic parameters for gpu programs AutoParamDataSource* mAutoParamDataSource; - CompositorChain* mActiveCompositorChain; - bool mLateMaterialResolving; + CompositorChain* mActiveCompositorChain; + bool mLateMaterialResolving; ShadowTechnique mShadowTechnique; bool mDebugShadows; @@ -728,52 +728,52 @@ namespace Ogre { Pass* mShadowDebugPass; Pass* mShadowStencilPass; Pass* mShadowModulativePass; - bool mShadowMaterialInitDone; + bool mShadowMaterialInitDone; HardwareIndexBufferSharedPtr mShadowIndexBuffer; - size_t mShadowIndexBufferSize; - size_t mShadowIndexBufferUsedSize; + size_t mShadowIndexBufferSize; + size_t mShadowIndexBufferUsedSize; Rectangle2D* mFullScreenQuad; Real mShadowDirLightExtrudeDist; IlluminationRenderStage mIlluminationStage; - ShadowTextureConfigList mShadowTextureConfigList; - bool mShadowTextureConfigDirty; + ShadowTextureConfigList mShadowTextureConfigList; + bool mShadowTextureConfigDirty; ShadowTextureList mShadowTextures; - TexturePtr mNullShadowTexture; - typedef vector::type ShadowTextureCameraList; - ShadowTextureCameraList mShadowTextureCameras; + TexturePtr mNullShadowTexture; + typedef vector::type ShadowTextureCameraList; + ShadowTextureCameraList mShadowTextureCameras; Texture* mCurrentShadowTexture; - bool mShadowUseInfiniteFarPlane; - bool mShadowCasterRenderBackFaces; - bool mShadowAdditiveLightClip; - /// Struct for caching light clipping information for re-use in a frame - struct LightClippingInfo - { - RealRect scissorRect; - PlaneList clipPlanes; - bool scissorValid; - unsigned long clipPlanesValid; - LightClippingInfo() : scissorValid(false), clipPlanesValid(false) {} - - }; - typedef map::type LightClippingInfoMap; - LightClippingInfoMap mLightClippingInfoMap; - unsigned long mLightClippingInfoMapFrameNumber; - - /// default shadow camera setup - ShadowCameraSetupPtr mDefaultShadowCameraSetup; - - /** Default sorting routine which sorts lights which cast shadows - to the front of a list, sub-sorting by distance. - @remarks - Since shadow textures are generated from lights based on the - frustum rather than individual objects, a shadow and camera-wise sort is - required to pick the best lights near the start of the list. Up to - the number of shadow textures will be generated from this. - */ - struct lightsForShadowTextureLess - { - _OgreExport bool operator()(const Light* l1, const Light* l2) const; - }; + bool mShadowUseInfiniteFarPlane; + bool mShadowCasterRenderBackFaces; + bool mShadowAdditiveLightClip; + /// Struct for caching light clipping information for re-use in a frame + struct LightClippingInfo + { + RealRect scissorRect; + PlaneList clipPlanes; + bool scissorValid; + unsigned long clipPlanesValid; + LightClippingInfo() : scissorValid(false), clipPlanesValid(false) {} + + }; + typedef map::type LightClippingInfoMap; + LightClippingInfoMap mLightClippingInfoMap; + unsigned long mLightClippingInfoMapFrameNumber; + + /// default shadow camera setup + ShadowCameraSetupPtr mDefaultShadowCameraSetup; + + /** Default sorting routine which sorts lights which cast shadows + to the front of a list, sub-sorting by distance. + @remarks + Since shadow textures are generated from lights based on the + frustum rather than individual objects, a shadow and camera-wise sort is + required to pick the best lights near the start of the list. Up to + the number of shadow textures will be generated from this. + */ + struct lightsForShadowTextureLess + { + _OgreExport bool operator()(const Light* l1, const Light* l2) const; + }; /** Internal method for locating a list of lights which could be affecting the frustum. @@ -790,48 +790,48 @@ namespace Ogre { /// Internal method for destroying shadow textures (texture-based shadows) virtual void destroyShadowTextures(void); - typedef vector::type InstanceManagerVec; - InstanceManagerVec mDirtyInstanceManagers; - InstanceManagerVec mDirtyInstanceMgrsTmp; + typedef vector::type InstanceManagerVec; + InstanceManagerVec mDirtyInstanceManagers; + InstanceManagerVec mDirtyInstanceMgrsTmp; - /** Updates all instance managaers with dirty instance batches. @see _addDirtyInstanceManager */ - void updateDirtyInstanceManagers(void); + /** Updates all instance managaers with dirty instance batches. @see _addDirtyInstanceManager */ + void updateDirtyInstanceManagers(void); - public: - /// Method for preparing shadow textures ready for use in a regular render - /// Do not call manually unless before frame start or rendering is paused - /// If lightList is not supplied, will render all lights in frustum + public: + /// Method for preparing shadow textures ready for use in a regular render + /// Do not call manually unless before frame start or rendering is paused + /// If lightList is not supplied, will render all lights in frustum virtual void prepareShadowTextures(Camera* cam, Viewport* vp, const LightList* lightList = 0); - //A render context, used to store internal data for pausing/resuming rendering - struct RenderContext - { - RenderQueue* renderQueue; - Viewport* viewport; - Camera* camera; - CompositorChain* activeChain; - RenderSystem::RenderSystemContext* rsContext; - }; - - /** Pause rendering of the frame. This has to be called when inside a renderScene call - (Usually using a listener of some sort) - */ - virtual RenderContext* _pauseRendering(); - /** Resume rendering of the frame. This has to be called after a _pauseRendering call - @param context The rendring context, as returned by the _pauseRendering call - */ - virtual void _resumeRendering(RenderContext* context); - - protected: + //A render context, used to store internal data for pausing/resuming rendering + struct RenderContext + { + RenderQueue* renderQueue; + Viewport* viewport; + Camera* camera; + CompositorChain* activeChain; + RenderSystem::RenderSystemContext* rsContext; + }; + + /** Pause rendering of the frame. This has to be called when inside a renderScene call + (Usually using a listener of some sort) + */ + virtual RenderContext* _pauseRendering(); + /** Resume rendering of the frame. This has to be called after a _pauseRendering call + @param context The rendring context, as returned by the _pauseRendering call + */ + virtual void _resumeRendering(RenderContext* context); + + protected: /** Internal method for rendering all the objects for a given light into the stencil buffer. @param light The light source @param cam The camera being viewed from - @param calcScissor Whether the method should set up any scissor state, or - false if that's already been done + @param calcScissor Whether the method should set up any scissor state, or + false if that's already been done */ virtual void renderShadowVolumesToStencil(const Light* light, const Camera* cam, - bool calcScissor); + bool calcScissor); /** Internal utility method for setting stencil state for rendering shadow volumes. @param secondpass Is this the second pass? @param zfail Should we be using the zfail method? @@ -843,9 +843,9 @@ namespace Ogre { Pass* pass, const LightList *manualLightList, unsigned long flags, bool secondpass, bool zfail, bool twosided); - /** render using the feature of reading back the inactive depth-stencil buffers as texture - only on DirectX 11 Render System*/ - void renderUsingReadBackAsTexture(unsigned int secondpass, Ogre::String variableName,unsigned int StartSlot); + /** render using the feature of reading back the inactive depth-stencil buffers as texture + only on DirectX 11 Render System*/ + void renderUsingReadBackAsTexture(unsigned int secondpass, Ogre::String variableName,unsigned int StartSlot); typedef vector::type ShadowCasterList; ShadowCasterList mShadowCasterList; @@ -856,26 +856,26 @@ namespace Ogre { Real mShadowTextureOffset; /// Proportion of texture offset in view direction e.g. 0.4 Real mShadowTextureFadeStart; /// As a proportion e.g. 0.6 Real mShadowTextureFadeEnd; /// As a proportion e.g. 0.9 - bool mShadowTextureSelfShadow; - Pass* mShadowTextureCustomCasterPass; - Pass* mShadowTextureCustomReceiverPass; - String mShadowTextureCustomCasterVertexProgram; - String mShadowTextureCustomCasterFragmentProgram; - String mShadowTextureCustomReceiverVertexProgram; - String mShadowTextureCustomReceiverFragmentProgram; - GpuProgramParametersSharedPtr mShadowTextureCustomCasterVPParams; - GpuProgramParametersSharedPtr mShadowTextureCustomCasterFPParams; - GpuProgramParametersSharedPtr mShadowTextureCustomReceiverVPParams; - GpuProgramParametersSharedPtr mShadowTextureCustomReceiverFPParams; - - /// Visibility mask used to show / hide objects - uint32 mVisibilityMask; - bool mFindVisibleObjects; - - /// Suppress render state changes? - bool mSuppressRenderStateChanges; - /// Suppress shadows? - bool mSuppressShadows; + bool mShadowTextureSelfShadow; + Pass* mShadowTextureCustomCasterPass; + Pass* mShadowTextureCustomReceiverPass; + String mShadowTextureCustomCasterVertexProgram; + String mShadowTextureCustomCasterFragmentProgram; + String mShadowTextureCustomReceiverVertexProgram; + String mShadowTextureCustomReceiverFragmentProgram; + GpuProgramParametersSharedPtr mShadowTextureCustomCasterVPParams; + GpuProgramParametersSharedPtr mShadowTextureCustomCasterFPParams; + GpuProgramParametersSharedPtr mShadowTextureCustomReceiverVPParams; + GpuProgramParametersSharedPtr mShadowTextureCustomReceiverFPParams; + + /// Visibility mask used to show / hide objects + uint32 mVisibilityMask; + bool mFindVisibleObjects; + + /// Suppress render state changes? + bool mSuppressRenderStateChanges; + /// Suppress shadows? + bool mSuppressShadows; GpuProgramParametersSharedPtr mInfiniteExtrusionParams; @@ -885,7 +885,7 @@ namespace Ogre { class _OgreExport ShadowCasterSceneQueryListener : public SceneQueryListener, public SceneMgtAlloc { protected: - SceneManager* mSceneMgr; + SceneManager* mSceneMgr; ShadowCasterList* mCasterList; bool mIsLightInFrustum; const PlaneBoundedVolumeList* mLightClipVolumeList; @@ -894,7 +894,7 @@ namespace Ogre { Real mFarDistSquared; public: ShadowCasterSceneQueryListener(SceneManager* sm) : mSceneMgr(sm), - mCasterList(0), mIsLightInFrustum(false), mLightClipVolumeList(0), + mCasterList(0), mIsLightInFrustum(false), mLightClipVolumeList(0), mCamera(0), mFarDistSquared(0) {} // Prepare the listener for use with a set of parameters void prepare(bool lightInFrustum, @@ -924,81 +924,81 @@ namespace Ogre { virtual const ShadowCasterList& findShadowCastersForLight(const Light* light, const Camera* camera); /** Render a group in the ordinary way */ - virtual void renderBasicQueueGroupObjects(RenderQueueGroup* pGroup, - QueuedRenderableCollection::OrganisationMode om); - /** Render a group with the added complexity of additive stencil shadows. */ - virtual void renderAdditiveStencilShadowedQueueGroupObjects(RenderQueueGroup* group, - QueuedRenderableCollection::OrganisationMode om); - /** Render a group with the added complexity of modulative stencil shadows. */ - virtual void renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* group, - QueuedRenderableCollection::OrganisationMode om); + virtual void renderBasicQueueGroupObjects(RenderQueueGroup* pGroup, + QueuedRenderableCollection::OrganisationMode om); + /** Render a group with the added complexity of additive stencil shadows. */ + virtual void renderAdditiveStencilShadowedQueueGroupObjects(RenderQueueGroup* group, + QueuedRenderableCollection::OrganisationMode om); + /** Render a group with the added complexity of modulative stencil shadows. */ + virtual void renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* group, + QueuedRenderableCollection::OrganisationMode om); /** Render a group rendering only shadow casters. */ - virtual void renderTextureShadowCasterQueueGroupObjects(RenderQueueGroup* group, - QueuedRenderableCollection::OrganisationMode om); + virtual void renderTextureShadowCasterQueueGroupObjects(RenderQueueGroup* group, + QueuedRenderableCollection::OrganisationMode om); /** Render a group rendering only shadow receivers. */ - virtual void renderTextureShadowReceiverQueueGroupObjects(RenderQueueGroup* group, - QueuedRenderableCollection::OrganisationMode om); + virtual void renderTextureShadowReceiverQueueGroupObjects(RenderQueueGroup* group, + QueuedRenderableCollection::OrganisationMode om); /** Render a group with the added complexity of modulative texture shadows. */ - virtual void renderModulativeTextureShadowedQueueGroupObjects(RenderQueueGroup* group, - QueuedRenderableCollection::OrganisationMode om); - - /** Render a group with additive texture shadows. */ - virtual void renderAdditiveTextureShadowedQueueGroupObjects(RenderQueueGroup* group, - QueuedRenderableCollection::OrganisationMode om); - /** Render a set of objects, see renderSingleObject for param definitions */ - virtual void renderObjects(const QueuedRenderableCollection& objs, - QueuedRenderableCollection::OrganisationMode om, bool lightScissoringClipping, + virtual void renderModulativeTextureShadowedQueueGroupObjects(RenderQueueGroup* group, + QueuedRenderableCollection::OrganisationMode om); + + /** Render a group with additive texture shadows. */ + virtual void renderAdditiveTextureShadowedQueueGroupObjects(RenderQueueGroup* group, + QueuedRenderableCollection::OrganisationMode om); + /** Render a set of objects, see renderSingleObject for param definitions */ + virtual void renderObjects(const QueuedRenderableCollection& objs, + QueuedRenderableCollection::OrganisationMode om, bool lightScissoringClipping, + bool doLightIteration, const LightList* manualLightList = 0); + /** Render those objects in the transparent pass list which have shadow casting forced on + @remarks + This function is intended to be used to render the shadows of transparent objects which have + transparency_casts_shadows set to 'on' in their material + */ + virtual void renderTransparentShadowCasterObjects(const QueuedRenderableCollection& objs, + QueuedRenderableCollection::OrganisationMode om, bool lightScissoringClipping, bool doLightIteration, const LightList* manualLightList = 0); - /** Render those objects in the transparent pass list which have shadow casting forced on - @remarks - This function is intended to be used to render the shadows of transparent objects which have - transparency_casts_shadows set to 'on' in their material - */ - virtual void renderTransparentShadowCasterObjects(const QueuedRenderableCollection& objs, - QueuedRenderableCollection::OrganisationMode om, bool lightScissoringClipping, - bool doLightIteration, const LightList* manualLightList = 0); - /** Update the state of the global render queue splitting based on a shadow - option change. */ - virtual void updateRenderQueueSplitOptions(void); - /** Update the state of the render queue group splitting based on a shadow - option change. */ - virtual void updateRenderQueueGroupSplitOptions(RenderQueueGroup* group, - bool suppressShadows, bool suppressRenderState); + /** Update the state of the global render queue splitting based on a shadow + option change. */ + virtual void updateRenderQueueSplitOptions(void); + /** Update the state of the render queue group splitting based on a shadow + option change. */ + virtual void updateRenderQueueGroupSplitOptions(RenderQueueGroup* group, + bool suppressShadows, bool suppressRenderState); - /// Set up a scissor rectangle from a group of lights - virtual ClipResult buildAndSetScissor(const LightList& ll, const Camera* cam); - /// Update a scissor rectangle from a single light - virtual void buildScissor(const Light* l, const Camera* cam, RealRect& rect); - virtual void resetScissor(); - /// Build a set of user clip planes from a single non-directional light - virtual ClipResult buildAndSetLightClip(const LightList& ll); - virtual void buildLightClip(const Light* l, PlaneList& planes); - virtual void resetLightClip(); - virtual void checkCachedLightClippingInfo(); + /// Set up a scissor rectangle from a group of lights + virtual ClipResult buildAndSetScissor(const LightList& ll, const Camera* cam); + /// Update a scissor rectangle from a single light + virtual void buildScissor(const Light* l, const Camera* cam, RealRect& rect); + virtual void resetScissor(); + /// Build a set of user clip planes from a single non-directional light + virtual ClipResult buildAndSetLightClip(const LightList& ll); + virtual void buildLightClip(const Light* l, PlaneList& planes); + virtual void resetLightClip(); + virtual void checkCachedLightClippingInfo(); - /// The active renderable visitor class - subclasses could override this - SceneMgrQueuedRenderableVisitor* mActiveQueuedRenderableVisitor; - /// Storage for default renderable visitor - SceneMgrQueuedRenderableVisitor mDefaultQueuedRenderableVisitor; + /// The active renderable visitor class - subclasses could override this + SceneMgrQueuedRenderableVisitor* mActiveQueuedRenderableVisitor; + /// Storage for default renderable visitor + SceneMgrQueuedRenderableVisitor mDefaultQueuedRenderableVisitor; - /// Whether to use camera-relative rendering - bool mCameraRelativeRendering; - Matrix4 mCachedViewMatrix; - Vector3 mCameraRelativePosition; + /// Whether to use camera-relative rendering + bool mCameraRelativeRendering; + Matrix4 mCachedViewMatrix; + Vector3 mCameraRelativePosition; - /// Last light sets - uint32 mLastLightHash; - unsigned short mLastLightLimit; - uint32 mLastLightHashGpuProgram; - /// Gpu params that need rebinding (mask of GpuParamVariability) - uint16 mGpuParamsDirty; + /// Last light sets + uint32 mLastLightHash; + unsigned short mLastLightLimit; + uint32 mLastLightHashGpuProgram; + /// Gpu params that need rebinding (mask of GpuParamVariability) + uint16 mGpuParamsDirty; - virtual void useLights(const LightList& lights, unsigned short limit); - virtual void setViewMatrix(const Matrix4& m); - virtual void useLightsGpuProgram(const Pass* pass, const LightList* lights); - virtual void bindGpuProgram(GpuProgram* prog); - virtual void updateGpuProgramParameters(const Pass* p); + virtual void useLights(const LightList& lights, unsigned short limit); + virtual void setViewMatrix(const Matrix4& m); + virtual void useLightsGpuProgram(const Pass* pass, const LightList* lights); + virtual void bindGpuProgram(GpuProgram* prog); + virtual void updateGpuProgramParameters(const Pass* p); @@ -1012,7 +1012,7 @@ namespace Ogre { LodListenerSet mLodListeners; /// List of movable object LOD changed events - typedef vector::type MovableObjectLodChangedEventList; + typedef vector::type MovableObjectLodChangedEventList; MovableObjectLodChangedEventList mMovableObjectLodChangedEvents; /// List of entity mesh LOD changed events @@ -1033,43 +1033,43 @@ namespace Ogre { virtual ~SceneManager(); - /** Mutex to protect the scene graph from simultaneous access from - multiple threads. - @remarks - If you are updating the scene in a separate thread from the rendering - thread, then you should lock this mutex before making any changes to - the scene graph - that means creating, modifying or deleting a - scene node, or attaching / detaching objects. It is your - responsibility to take out this lock, the detail methods on the nodes - will not do it for you (for the reasons discussed below). - @par - Note that locking this mutex will prevent the scene being rendered until - it is unlocked again. Therefore you should do this sparingly. Try - to create any objects you need separately and fully prepare them - before doing all your scene graph work in one go, thus keeping this - lock for the shortest time possible. - @note - A single global lock is used rather than a per-node lock since - it keeps the number of locks required during rendering down to a - minimum. Obtaining a lock, even if there is no contention, is not free - so for performance it is good to do it as little as possible. - Since modifying the scene in a separate thread is a fairly - rare occurrence (relative to rendering), it is better to keep the - locking required during rendering lower than to make update locks - more granular. - */ + /** Mutex to protect the scene graph from simultaneous access from + multiple threads. + @remarks + If you are updating the scene in a separate thread from the rendering + thread, then you should lock this mutex before making any changes to + the scene graph - that means creating, modifying or deleting a + scene node, or attaching / detaching objects. It is your + responsibility to take out this lock, the detail methods on the nodes + will not do it for you (for the reasons discussed below). + @par + Note that locking this mutex will prevent the scene being rendered until + it is unlocked again. Therefore you should do this sparingly. Try + to create any objects you need separately and fully prepare them + before doing all your scene graph work in one go, thus keeping this + lock for the shortest time possible. + @note + A single global lock is used rather than a per-node lock since + it keeps the number of locks required during rendering down to a + minimum. Obtaining a lock, even if there is no contention, is not free + so for performance it is good to do it as little as possible. + Since modifying the scene in a separate thread is a fairly + rare occurrence (relative to rendering), it is better to keep the + locking required during rendering lower than to make update locks + more granular. + */ OGRE_MUTEX(sceneGraphMutex); - /** Return the instance name of this SceneManager. */ - const String& getName(void) const { return mName; } + /** Return the instance name of this SceneManager. */ + const String& getName(void) const { return mName; } - /** Retrieve the type name of this scene manager. - @remarks - This method has to be implemented by subclasses. It should - return the type name of this SceneManager which agrees with - the type name of the SceneManagerFactory which created it. - */ - virtual const String& getTypeName(void) const = 0; + /** Retrieve the type name of this scene manager. + @remarks + This method has to be implemented by subclasses. It should + return the type name of this SceneManager which agrees with + the type name of the SceneManagerFactory which created it. + */ + virtual const String& getTypeName(void) const = 0; /** Creates a camera to be managed by this scene manager. @remarks @@ -1081,13 +1081,13 @@ namespace Ogre { virtual Camera* createCamera(const String& name); /** Retrieves a pointer to the named camera. - @note Throws an exception if the named instance does not exist + @note Throws an exception if the named instance does not exist */ virtual Camera* getCamera(const String& name) const; - /** Returns whether a camera with the given name exists. - */ - virtual bool hasCamera(const String& name) const; + /** Returns whether a camera with the given name exists. + */ + virtual bool hasCamera(const String& name) const; /** Removes a camera from the scene. @remarks @@ -1128,27 +1128,27 @@ namespace Ogre { */ virtual Light* createLight(const String& name); - /** Creates a light with a generated name. */ - virtual Light* createLight(); + /** Creates a light with a generated name. */ + virtual Light* createLight(); /** Returns a pointer to the named Light which has previously been added to the scene. - @note Throws an exception if the named instance does not exist + @note Throws an exception if the named instance does not exist */ virtual Light* getLight(const String& name) const; - /** Returns whether a light with the given name exists. - */ - virtual bool hasLight(const String& name) const; + /** Returns whether a light with the given name exists. + */ + virtual bool hasLight(const String& name) const; - /** Retrieve a set of clipping planes for a given light. - */ - virtual const PlaneList& getLightClippingPlanes(Light* l); + /** Retrieve a set of clipping planes for a given light. + */ + virtual const PlaneList& getLightClippingPlanes(Light* l); - /** Retrieve a scissor rectangle for a given light and camera. - */ - virtual const RealRect& getLightScissorRect(Light* l, const Camera* cam); + /** Retrieve a scissor rectangle for a given light and camera. + */ + virtual const RealRect& getLightScissorRect(Light* l, const Camera* cam); - /** Removes the named light from the scene and destroys it. + /** Removes the named light from the scene and destroys it. @remarks Any pointers held to this light after calling this method will be invalid. */ @@ -1193,7 +1193,7 @@ namespace Ogre { @remarks Note that default implementation of this method returns a cached light list, which is populated when rendering the scene. So by default the list of lights - is only available during scene rendering. + is only available during scene rendering. */ virtual const LightList& _getLightsAffectingFrustum(void) const; @@ -1217,17 +1217,17 @@ namespace Ogre { @param radius The bounding radius to test @param destList List to be populated with ordered set of lights; will be cleared by this method before population. - @param lightMask The mask with which to include / exclude lights + @param lightMask The mask with which to include / exclude lights */ virtual void _populateLightList(const Vector3& position, Real radius, LightList& destList, uint32 lightMask = 0xFFFFFFFF); - /** Populates a light list with an ordered set of the lights which are closest + /** Populates a light list with an ordered set of the lights which are closest to the position of the SceneNode given. @remarks Note that since directional lights have no position, they are always considered closer than any point lights and as such will always take precedence. - This overloaded version will take the SceneNode's position and use the second method - to populate the list. + This overloaded version will take the SceneNode's position and use the second method + to populate the list. @par Subclasses of the default SceneManager may wish to take into account other issues such as possible visibility of the light if that information is included in their @@ -1235,10 +1235,10 @@ namespace Ogre { those lights which are out of range or could not be affecting the frustum (i.e. only the lights returned by SceneManager::_getLightsAffectingFrustum are take into account). - @par - Also note that subclasses of the SceneNode might be used here to provide cached - scene related data, accelerating the list population (for example light lists for - SceneNodes could be cached inside subclassed SceneNode objects). + @par + Also note that subclasses of the SceneNode might be used here to provide cached + scene related data, accelerating the list population (for example light lists for + SceneNodes could be cached inside subclassed SceneNode objects). @par The number of items in the list may exceed the maximum number of lights supported by the renderer, but the extraneous ones will never be used. In fact the limit will @@ -1247,7 +1247,7 @@ namespace Ogre { @param radius The bounding radius to test @param destList List to be populated with ordered set of lights; will be cleared by this method before population. - @param lightMask The mask with which to include / exclude lights + @param lightMask The mask with which to include / exclude lights */ virtual void _populateLightList(const SceneNode* sn, Real radius, LightList& destList, uint32 lightMask = 0xFFFFFFFF); @@ -1322,13 +1322,13 @@ namespace Ogre { If you chose to name a SceneNode as you created it, or if you happened to make a note of the generated name, you can look it up wherever it is in the scene graph using this method. - @note Throws an exception if the named instance does not exist + @note Throws an exception if the named instance does not exist */ virtual SceneNode* getSceneNode(const String& name) const; - /** Returns whether a scene node with the given name exists. - */ - virtual bool hasSceneNode(const String& name) const; + /** Returns whether a scene node with the given name exists. + */ + virtual bool hasSceneNode(const String& name) const; /** Create an Entity (instance of a discrete mesh). @@ -1369,8 +1369,8 @@ namespace Ogre { */ enum PrefabType { PT_PLANE, - PT_CUBE, - PT_SPHERE + PT_CUBE, + PT_SPHERE }; /** Create an Entity (instance of a discrete mesh) from a range of prefab shapes. @@ -1386,12 +1386,12 @@ namespace Ogre { */ virtual Entity* createEntity(PrefabType ptype); /** Retrieves a pointer to the named Entity. - @note Throws an exception if the named instance does not exist - */ + @note Throws an exception if the named instance does not exist + */ virtual Entity* getEntity(const String& name) const; - /** Returns whether an entity with the given name exists. - */ - virtual bool hasEntity(const String& name) const; + /** Returns whether an entity with the given name exists. + */ + virtual bool hasEntity(const String& name) const; /** Removes & destroys an Entity from the SceneManager. @warning @@ -1425,91 +1425,91 @@ namespace Ogre { virtual void destroyAllEntities(void); /** Create a ManualObject, an object which you populate with geometry - manually through a GL immediate-mode style interface. + manually through a GL immediate-mode style interface. @param name The name to be given to the object (must be unique). */ virtual ManualObject* createManualObject(const String& name); - /** Create a ManualObject, an object which you populate with geometry - manually through a GL immediate-mode style interface, generating the name. - */ - virtual ManualObject* createManualObject(); + /** Create a ManualObject, an object which you populate with geometry + manually through a GL immediate-mode style interface, generating the name. + */ + virtual ManualObject* createManualObject(); /** Retrieves a pointer to the named ManualObject. - @note Throws an exception if the named instance does not exist - */ + @note Throws an exception if the named instance does not exist + */ virtual ManualObject* getManualObject(const String& name) const; - /** Returns whether a manual object with the given name exists. - */ - virtual bool hasManualObject(const String& name) const; + /** Returns whether a manual object with the given name exists. + */ + virtual bool hasManualObject(const String& name) const; /** Removes & destroys a ManualObject from the SceneManager. */ virtual void destroyManualObject(ManualObject* obj); - /** Removes & destroys a ManualObject from the SceneManager. - */ - virtual void destroyManualObject(const String& name); - /** Removes & destroys all ManualObjects from the SceneManager. - */ - virtual void destroyAllManualObjects(void); + /** Removes & destroys a ManualObject from the SceneManager. + */ + virtual void destroyManualObject(const String& name); + /** Removes & destroys all ManualObjects from the SceneManager. + */ + virtual void destroyAllManualObjects(void); /** Create a BillboardChain, an object which you can use to render a linked chain of billboards. @param name The name to be given to the object (must be unique). */ virtual BillboardChain* createBillboardChain(const String& name); - /** Create a BillboardChain, an object which you can use to render - a linked chain of billboards, with a generated name. - */ - virtual BillboardChain* createBillboardChain(); + /** Create a BillboardChain, an object which you can use to render + a linked chain of billboards, with a generated name. + */ + virtual BillboardChain* createBillboardChain(); /** Retrieves a pointer to the named BillboardChain. - @note Throws an exception if the named instance does not exist - */ + @note Throws an exception if the named instance does not exist + */ virtual BillboardChain* getBillboardChain(const String& name) const; - /** Returns whether a billboard chain with the given name exists. - */ - virtual bool hasBillboardChain(const String& name) const; + /** Returns whether a billboard chain with the given name exists. + */ + virtual bool hasBillboardChain(const String& name) const; /** Removes & destroys a BillboardChain from the SceneManager. */ virtual void destroyBillboardChain(BillboardChain* obj); - /** Removes & destroys a BillboardChain from the SceneManager. - */ - virtual void destroyBillboardChain(const String& name); - /** Removes & destroys all BillboardChains from the SceneManager. - */ - virtual void destroyAllBillboardChains(void); + /** Removes & destroys a BillboardChain from the SceneManager. + */ + virtual void destroyBillboardChain(const String& name); + /** Removes & destroys all BillboardChains from the SceneManager. + */ + virtual void destroyAllBillboardChains(void); /** Create a RibbonTrail, an object which you can use to render a linked chain of billboards which follows one or more nodes. @param name The name to be given to the object (must be unique). */ virtual RibbonTrail* createRibbonTrail(const String& name); - /** Create a RibbonTrail, an object which you can use to render - a linked chain of billboards which follows one or more nodes, generating the name. - */ - virtual RibbonTrail* createRibbonTrail(); + /** Create a RibbonTrail, an object which you can use to render + a linked chain of billboards which follows one or more nodes, generating the name. + */ + virtual RibbonTrail* createRibbonTrail(); /** Retrieves a pointer to the named RibbonTrail. - @note Throws an exception if the named instance does not exist - */ + @note Throws an exception if the named instance does not exist + */ virtual RibbonTrail* getRibbonTrail(const String& name) const; - /** Returns whether a ribbon trail with the given name exists. - */ - virtual bool hasRibbonTrail(const String& name) const; + /** Returns whether a ribbon trail with the given name exists. + */ + virtual bool hasRibbonTrail(const String& name) const; /** Removes & destroys a RibbonTrail from the SceneManager. */ virtual void destroyRibbonTrail(RibbonTrail* obj); - /** Removes & destroys a RibbonTrail from the SceneManager. - */ - virtual void destroyRibbonTrail(const String& name); - /** Removes & destroys all RibbonTrails from the SceneManager. - */ - virtual void destroyAllRibbonTrails(void); + /** Removes & destroys a RibbonTrail from the SceneManager. + */ + virtual void destroyRibbonTrail(const String& name); + /** Removes & destroys all RibbonTrails from the SceneManager. + */ + virtual void destroyAllRibbonTrails(void); /** Creates a particle system based on a template. @remarks This method creates a new ParticleSystem instance based on the named template - (defined through ParticleSystemManager::createTemplate) and returns a + (defined through ParticleSystemManager::createTemplate) and returns a pointer to the caller. The caller should not delete this object, it will be freed at system shutdown, or can be released earlier using the destroyParticleSystem method. @par @@ -1527,7 +1527,7 @@ namespace Ogre { templateName The name of the template to base the new instance on. */ virtual ParticleSystem* createParticleSystem(const String& name, - const String& templateName); + const String& templateName); /** Create a blank particle system. @remarks This method creates a new, blank ParticleSystem instance and returns a pointer to it. @@ -1548,7 +1548,7 @@ namespace Ogre { resourceGroup The resource group which will be used to load dependent resources */ virtual ParticleSystem* createParticleSystem(const String& name, - size_t quota = 500, + size_t quota = 500, const String& resourceGroup = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); /** Create a blank particle system with a generated name. @@ -1568,27 +1568,27 @@ namespace Ogre { @param resourceGroup The resource group which will be used to load dependent resources */ - virtual ParticleSystem* createParticleSystem(size_t quota = 500, - const String& resourceGroup = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + virtual ParticleSystem* createParticleSystem(size_t quota = 500, + const String& resourceGroup = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); /** Retrieves a pointer to the named ParticleSystem. - @note Throws an exception if the named instance does not exist - */ + @note Throws an exception if the named instance does not exist + */ virtual ParticleSystem* getParticleSystem(const String& name) const; - /** Returns whether a particle system with the given name exists. - */ - virtual bool hasParticleSystem(const String& name) const; + /** Returns whether a particle system with the given name exists. + */ + virtual bool hasParticleSystem(const String& name) const; /** Removes & destroys a ParticleSystem from the SceneManager. */ virtual void destroyParticleSystem(ParticleSystem* obj); - /** Removes & destroys a ParticleSystem from the SceneManager. - */ - virtual void destroyParticleSystem(const String& name); - /** Removes & destroys all ParticleSystems from the SceneManager. - */ - virtual void destroyAllParticleSystems(void); - - /** Empties the entire scene, inluding all SceneNodes, Entities, Lights, + /** Removes & destroys a ParticleSystem from the SceneManager. + */ + virtual void destroyParticleSystem(const String& name); + /** Removes & destroys all ParticleSystems from the SceneManager. + */ + virtual void destroyAllParticleSystems(void); + + /** Empties the entire scene, inluding all SceneNodes, Entities, Lights, BillboardSets etc. Cameras are not deleted at this stage since they are still referenced by viewports, which are not destroyed during this process. @@ -1631,24 +1631,24 @@ namespace Ogre { virtual void prepareWorldGeometry(const String& filename); /** Sets the source of the 'world' geometry, i.e. the large, mainly - static geometry making up the world e.g. rooms, landscape etc. + static geometry making up the world e.g. rooms, landscape etc. This function can be called before setWorldGeometry in a background thread, do to some slow tasks (e.g. IO) that do not involve the backend render system. @remarks Depending on the type of SceneManager (subclasses will be - specialised for particular world geometry types) you have - requested via the Root or SceneManagerEnumerator classes, you - can pass a stream to this method and it will attempt to load - the world-level geometry for use. If the manager can only - handle one input format the typeName parameter is not required. - The stream passed will be read (and it's state updated). - @param stream Data stream containing data to load - @param typeName String identifying the type of world geometry - contained in the stream - not required if this manager only - supports one type of world geometry. - */ - virtual void prepareWorldGeometry(DataStreamPtr& stream, - const String& typeName = BLANKSTRING); + specialised for particular world geometry types) you have + requested via the Root or SceneManagerEnumerator classes, you + can pass a stream to this method and it will attempt to load + the world-level geometry for use. If the manager can only + handle one input format the typeName parameter is not required. + The stream passed will be read (and it's state updated). + @param stream Data stream containing data to load + @param typeName String identifying the type of world geometry + contained in the stream - not required if this manager only + supports one type of world geometry. + */ + virtual void prepareWorldGeometry(DataStreamPtr& stream, + const String& typeName = BLANKSTRING); /** Sets the source of the 'world' geometry, i.e. the large, mainly static geometry making up the world e.g. rooms, landscape etc. @@ -1665,22 +1665,22 @@ namespace Ogre { virtual void setWorldGeometry(const String& filename); /** Sets the source of the 'world' geometry, i.e. the large, mainly - static geometry making up the world e.g. rooms, landscape etc. + static geometry making up the world e.g. rooms, landscape etc. @remarks Depending on the type of SceneManager (subclasses will be - specialised for particular world geometry types) you have - requested via the Root or SceneManagerEnumerator classes, you - can pass a stream to this method and it will attempt to load - the world-level geometry for use. If the manager can only - handle one input format the typeName parameter is not required. - The stream passed will be read (and it's state updated). - @param stream Data stream containing data to load - @param typeName String identifying the type of world geometry - contained in the stream - not required if this manager only - supports one type of world geometry. - */ - virtual void setWorldGeometry(DataStreamPtr& stream, - const String& typeName = BLANKSTRING); + specialised for particular world geometry types) you have + requested via the Root or SceneManagerEnumerator classes, you + can pass a stream to this method and it will attempt to load + the world-level geometry for use. If the manager can only + handle one input format the typeName parameter is not required. + The stream passed will be read (and it's state updated). + @param stream Data stream containing data to load + @param typeName String identifying the type of world geometry + contained in the stream - not required if this manager only + supports one type of world geometry. + */ + virtual void setWorldGeometry(DataStreamPtr& stream, + const String& typeName = BLANKSTRING); /** Estimate the number of loading stages required to load the named world geometry. @@ -1700,17 +1700,17 @@ namespace Ogre { /** Estimate the number of loading stages required to load the named world geometry. @remarks - Operates just like the version of this method which takes a - filename, but operates on a stream instead. Note that since the - stream is updated, you'll need to reset the stream or reopen it - when it comes to loading it for real. - @param stream Data stream containing data to load - @param typeName String identifying the type of world geometry - contained in the stream - not required if this manager only - supports one type of world geometry. - */ + Operates just like the version of this method which takes a + filename, but operates on a stream instead. Note that since the + stream is updated, you'll need to reset the stream or reopen it + when it comes to loading it for real. + @param stream Data stream containing data to load + @param typeName String identifying the type of world geometry + contained in the stream - not required if this manager only + supports one type of world geometry. + */ virtual size_t estimateWorldGeometry(DataStreamPtr& stream, - const String& typeName = BLANKSTRING) + const String& typeName = BLANKSTRING) { (void)stream; (void)typeName; return 0; } /** Asks the SceneManager to provide a suggested viewpoint from which the scene should be viewed. @@ -1904,11 +1904,11 @@ namespace Ogre { geometry which can be an optimisation - however you must ensure that the plane.d value is large enough that no objects will 'poke through' the sky plane when it is rendered. - @param - bow If zero, the plane will be completely flat (like previous - versions. If above zero, the plane will be curved, allowing - the sky to appear below camera level. Curved sky planes are - simular to skydomes, but are more compatible with fog. + @param + bow If zero, the plane will be completely flat (like previous + versions. If above zero, the plane will be curved, allowing + the sky to appear below camera level. Curved sky planes are + simular to skydomes, but are more compatible with fog. @param xsegments, ysegments Determines the number of segments the plane will have to it. This is most important when you are bowing the plane, but may also be useful @@ -1954,11 +1954,11 @@ namespace Ogre { the TextureUnitState texture coordinate transformation methods. @param renderQueue The render queue to use when rendering this object - @param - bow If zero, the plane will be completely flat (like previous - versions. If above zero, the plane will be curved, allowing - the sky to appear below camera level. Curved sky planes are - simular to skydomes, but are more compatible with fog. + @param + bow If zero, the plane will be completely flat (like previous + versions. If above zero, the plane will be curved, allowing + the sky to appear below camera level. Curved sky planes are + simular to skydomes, but are more compatible with fog. @param xsegments, ysegments Determines the number of segments the plane will have to it. This is most important when you are bowing the plane, but may also be useful @@ -1973,17 +1973,17 @@ namespace Ogre { int xsegments = 1, int ysegments = 1, const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - /** Enables / disables a 'sky plane' */ - virtual void setSkyPlaneEnabled(bool enable) { mSkyPlaneEnabled = enable; } + /** Enables / disables a 'sky plane' */ + virtual void setSkyPlaneEnabled(bool enable) { mSkyPlaneEnabled = enable; } - /** Return whether a key plane is enabled */ - virtual bool isSkyPlaneEnabled(void) const { return mSkyPlaneEnabled; } + /** Return whether a key plane is enabled */ + virtual bool isSkyPlaneEnabled(void) const { return mSkyPlaneEnabled; } - /** Get the sky plane node, if enabled. */ - virtual SceneNode* getSkyPlaneNode(void) const { return mSkyPlaneNode; } + /** Get the sky plane node, if enabled. */ + virtual SceneNode* getSkyPlaneNode(void) const { return mSkyPlaneNode; } - /** Get the parameters used to construct the SkyPlane, if any **/ - virtual const SkyPlaneGenParameters& getSkyPlaneGenParameters(void) const { return mSkyPlaneGenParameters; } + /** Get the parameters used to construct the SkyPlane, if any **/ + virtual const SkyPlaneGenParameters& getSkyPlaneGenParameters(void) const { return mSkyPlaneGenParameters; } /** Enables / disables a 'sky box' i.e. a 6-sided box at constant distance from the camera representing the sky. @@ -2068,19 +2068,19 @@ namespace Ogre { uint8 renderQueue = RENDER_QUEUE_SKIES_EARLY, const Quaternion& orientation = Quaternion::IDENTITY, const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - /** Enables / disables a 'sky box' */ - virtual void setSkyBoxEnabled(bool enable) { mSkyBoxEnabled = enable; } + /** Enables / disables a 'sky box' */ + virtual void setSkyBoxEnabled(bool enable) { mSkyBoxEnabled = enable; } - /** Return whether a skybox is enabled */ - virtual bool isSkyBoxEnabled(void) const { return mSkyBoxEnabled; } + /** Return whether a skybox is enabled */ + virtual bool isSkyBoxEnabled(void) const { return mSkyBoxEnabled; } - /** Get the skybox node, if enabled. */ - virtual SceneNode* getSkyBoxNode(void) const { return mSkyBoxNode; } + /** Get the skybox node, if enabled. */ + virtual SceneNode* getSkyBoxNode(void) const { return mSkyBoxNode; } - /** Get the parameters used to generate the current SkyBox, if any */ - virtual const SkyBoxGenParameters& getSkyBoxGenParameters(void) const { return mSkyBoxGenParameters; } + /** Get the parameters used to generate the current SkyBox, if any */ + virtual const SkyBoxGenParameters& getSkyBoxGenParameters(void) const { return mSkyBoxGenParameters; } - /** Enables / disables a 'sky dome' i.e. an illusion of a curved sky. + /** Enables / disables a 'sky dome' i.e. an illusion of a curved sky. @remarks A sky dome is actually formed by 5 sides of a cube, but with texture coordinates generated such that the surface appears @@ -2142,7 +2142,7 @@ namespace Ogre { int xsegments = 16, int ysegments = 16, int ysegments_keep = -1, const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - /** Enables / disables a 'sky dome' i.e. an illusion of a curved sky. + /** Enables / disables a 'sky dome' i.e. an illusion of a curved sky. @remarks A sky dome is actually formed by 5 sides of a cube, but with texture coordinates generated such that the surface appears @@ -2195,19 +2195,19 @@ namespace Ogre { int xsegments = 16, int ysegments = 16, int ysegments_keep = -1, const String& groupName = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - /** Enables / disables a 'sky dome' */ - virtual void setSkyDomeEnabled(bool enable) { mSkyDomeEnabled = enable; } + /** Enables / disables a 'sky dome' */ + virtual void setSkyDomeEnabled(bool enable) { mSkyDomeEnabled = enable; } - /** Return whether a skydome is enabled */ - virtual bool isSkyDomeEnabled(void) const { return mSkyDomeEnabled; } + /** Return whether a skydome is enabled */ + virtual bool isSkyDomeEnabled(void) const { return mSkyDomeEnabled; } - /** Get the sky dome node, if enabled. */ - virtual SceneNode* getSkyDomeNode(void) const { return mSkyDomeNode; } + /** Get the sky dome node, if enabled. */ + virtual SceneNode* getSkyDomeNode(void) const { return mSkyDomeNode; } - /** Get the parameters used to generate the current SkyDome, if any */ - virtual const SkyDomeGenParameters& getSkyDomeGenParameters(void) const { return mSkyDomeGenParameters; } + /** Get the parameters used to generate the current SkyDome, if any */ + virtual const SkyDomeGenParameters& getSkyDomeGenParameters(void) const { return mSkyDomeGenParameters; } - /** Sets the fogging mode applied to the scene. + /** Sets the fogging mode applied to the scene. @remarks This method sets up the scene-wide fogging effect. These settings apply to all geometry rendered, UNLESS the material with which it @@ -2283,12 +2283,12 @@ namespace Ogre { */ virtual BillboardSet* createBillboardSet(unsigned int poolSize = 20); /** Retrieves a pointer to the named BillboardSet. - @note Throws an exception if the named instance does not exist + @note Throws an exception if the named instance does not exist */ virtual BillboardSet* getBillboardSet(const String& name) const; - /** Returns whether a billboardset with the given name exists. - */ - virtual bool hasBillboardSet(const String& name) const; + /** Returns whether a billboardset with the given name exists. + */ + virtual bool hasBillboardSet(const String& name) const; /** Removes & destroys an BillboardSet from the SceneManager. @warning @@ -2351,12 +2351,12 @@ namespace Ogre { virtual Animation* createAnimation(const String& name, Real length); /** Looks up an Animation object previously created with createAnimation. - @note Throws an exception if the named instance does not exist - */ + @note Throws an exception if the named instance does not exist + */ virtual Animation* getAnimation(const String& name) const; - /** Returns whether an animation with the given name exists. - */ - virtual bool hasAnimation(const String& name) const; + /** Returns whether an animation with the given name exists. + */ + virtual bool hasAnimation(const String& name) const; /** Destroys an Animation. @remarks @@ -2389,21 +2389,21 @@ namespace Ogre { origin. If you want the base state of the SceneNode to be elsewhere, make your changes to the node using the standard transform methods, then call setInitialState to 'bake' this reference position into the node. - @par - If the target of your animation is to be a generic AnimableValue, you - should ensure that it has a base value set (unlike nodes this has no - default). @see AnimableValue::setAsBaseValue. + @par + If the target of your animation is to be a generic AnimableValue, you + should ensure that it has a base value set (unlike nodes this has no + default). @see AnimableValue::setAsBaseValue. @param animName The name of an animation created already with createAnimation. */ virtual AnimationState* createAnimationState(const String& animName); /** Retrieves animation state as previously created using createAnimationState. - @note Throws an exception if the named instance does not exist - */ + @note Throws an exception if the named instance does not exist + */ virtual AnimationState* getAnimationState(const String& animName) const; - /** Returns whether an animation state with the given name exists. - */ - virtual bool hasAnimationState(const String& name) const; + /** Returns whether an animation state with the given name exists. + */ + virtual bool hasAnimationState(const String& name) const; /** Destroys an AnimationState. @remarks @@ -2442,38 +2442,38 @@ namespace Ogre { const Matrix4& worldMatrix, const Matrix4& viewMatrix, const Matrix4& projMatrix, bool doBeginEndFrame = false) ; - /** Manual rendering method for rendering a single object. - @param rend The renderable to issue to the pipeline - @param pass The pass to use - @param vp Pointer to the viewport to render to, or 0 to use the existing viewport - @param doBeginEndFrame If true, beginFrame() and endFrame() are called, - otherwise not. You should leave this as false if you are calling - this within the main render loop. + /** Manual rendering method for rendering a single object. + @param rend The renderable to issue to the pipeline + @param pass The pass to use + @param vp Pointer to the viewport to render to, or 0 to use the existing viewport + @param doBeginEndFrame If true, beginFrame() and endFrame() are called, + otherwise not. You should leave this as false if you are calling + this within the main render loop. @param viewMatrix The transform to apply from world to view space @param projMatrix The transform to apply from view to screen space - @param lightScissoringClipping If true, passes that have the getLightScissorEnabled - and/or getLightClipPlanesEnabled flags will cause calculation and setting of - scissor rectangle and user clip planes. - @param doLightIteration If true, this method will issue the renderable to - the pipeline possibly multiple times, if the pass indicates it should be - done once per light - @param manualLightList Only applicable if doLightIteration is false, this - method allows you to pass in a previously determined set of lights - which will be used for a single render of this object. - */ - virtual void manualRender(Renderable* rend, const Pass* pass, Viewport* vp, - const Matrix4& viewMatrix, const Matrix4& projMatrix, bool doBeginEndFrame = false, bool lightScissoringClipping = true, - bool doLightIteration = true, const LightList* manualLightList = 0); - - /** Retrieves the internal render queue, for advanced users only. + @param lightScissoringClipping If true, passes that have the getLightScissorEnabled + and/or getLightClipPlanesEnabled flags will cause calculation and setting of + scissor rectangle and user clip planes. + @param doLightIteration If true, this method will issue the renderable to + the pipeline possibly multiple times, if the pass indicates it should be + done once per light + @param manualLightList Only applicable if doLightIteration is false, this + method allows you to pass in a previously determined set of lights + which will be used for a single render of this object. + */ + virtual void manualRender(Renderable* rend, const Pass* pass, Viewport* vp, + const Matrix4& viewMatrix, const Matrix4& projMatrix, bool doBeginEndFrame = false, bool lightScissoringClipping = true, + bool doLightIteration = true, const LightList* manualLightList = 0); + + /** Retrieves the internal render queue, for advanced users only. @remarks The render queue is mainly used internally to manage the scene object - rendering queue, it also exports some methods to allow advanced users - to configure the behavior of rendering process. + rendering queue, it also exports some methods to allow advanced users + to configure the behavior of rendering process. Most methods provided by RenderQueue are supposed to be used - internally only, you should reference to the RenderQueue API for - more information. Do not access this directly unless you know what - you are doing. + internally only, you should reference to the RenderQueue API for + more information. Do not access this directly unless you know what + you are doing. */ virtual RenderQueue* getRenderQueue(void); @@ -2484,85 +2484,85 @@ namespace Ogre { /** Removes a listener previously added with addRenderQueueListener. */ virtual void removeRenderQueueListener(RenderQueueListener* delListener); - - /** Registers a new Render Object Listener which will be notified when rendering an object. - */ - virtual void addRenderObjectListener(RenderObjectListener* newListener); - /** Removes a listener previously added with addRenderObjectListener. */ - virtual void removeRenderObjectListener(RenderObjectListener* delListener); - - /** Adds an item to the 'special case' render queue list. - @remarks - Normally all render queues are rendered, in their usual sequence, - only varying if a RenderQueueListener nominates for the queue to be - repeated or skipped. This method allows you to add a render queue to - a 'special case' list, which varies the behaviour. The effect of this - list depends on the 'mode' in which this list is in, which might be - to exclude these render queues, or to include them alone (excluding - all other queues). This allows you to perform broad selective - rendering without requiring a RenderQueueListener. - @param qid The identifier of the queue which should be added to the - special case list. Nothing happens if the queue is already in the list. - */ - virtual void addSpecialCaseRenderQueue(uint8 qid); - /** Removes an item to the 'special case' render queue list. - @see SceneManager::addSpecialCaseRenderQueue - @param qid The identifier of the queue which should be removed from the - special case list. Nothing happens if the queue is not in the list. - */ - virtual void removeSpecialCaseRenderQueue(uint8 qid); - /** Clears the 'special case' render queue list. - @see SceneManager::addSpecialCaseRenderQueue - */ - virtual void clearSpecialCaseRenderQueues(void); - /** Sets the way the special case render queue list is processed. - @see SceneManager::addSpecialCaseRenderQueue - @param mode The mode of processing - */ - virtual void setSpecialCaseRenderQueueMode(SpecialCaseRenderQueueMode mode); - /** Gets the way the special case render queue list is processed. */ - virtual SpecialCaseRenderQueueMode getSpecialCaseRenderQueueMode(void); - /** Returns whether or not the named queue will be rendered based on the - current 'special case' render queue list and mode. - @see SceneManager::addSpecialCaseRenderQueue - @param qid The identifier of the queue which should be tested - @return true if the queue will be rendered, false otherwise - */ - virtual bool isRenderQueueToBeProcessed(uint8 qid); - - /** Sets the render queue that the world geometry (if any) this SceneManager - renders will be associated with. - @remarks - SceneManagers which provide 'world geometry' should place it in a - specialised render queue in order to make it possible to enable / - disable it easily using the addSpecialCaseRenderQueue method. Even - if the SceneManager does not use the render queues to render the - world geometry, it should still pick a queue to represent it's manual - rendering, and check isRenderQueueToBeProcessed before rendering. - @note - Setting this may not affect the actual ordering of rendering the - world geometry, if the world geometry is being rendered manually - by the SceneManager. If the SceneManager feeds world geometry into - the queues, however, the ordering will be affected. - */ - virtual void setWorldGeometryRenderQueue(uint8 qid); - /** Gets the render queue that the world geometry (if any) this SceneManager - renders will be associated with. - @remarks - SceneManagers which provide 'world geometry' should place it in a - specialised render queue in order to make it possible to enable / - disable it easily using the addSpecialCaseRenderQueue method. Even - if the SceneManager does not use the render queues to render the - world geometry, it should still pick a queue to represent it's manual - rendering, and check isRenderQueueToBeProcessed before rendering. - */ - virtual uint8 getWorldGeometryRenderQueue(void); - - /** Allows all bounding boxes of scene nodes to be displayed. */ - virtual void showBoundingBoxes(bool bShow); - - /** Returns if all bounding boxes of scene nodes are to be displayed */ - virtual bool getShowBoundingBoxes() const; + + /** Registers a new Render Object Listener which will be notified when rendering an object. + */ + virtual void addRenderObjectListener(RenderObjectListener* newListener); + /** Removes a listener previously added with addRenderObjectListener. */ + virtual void removeRenderObjectListener(RenderObjectListener* delListener); + + /** Adds an item to the 'special case' render queue list. + @remarks + Normally all render queues are rendered, in their usual sequence, + only varying if a RenderQueueListener nominates for the queue to be + repeated or skipped. This method allows you to add a render queue to + a 'special case' list, which varies the behaviour. The effect of this + list depends on the 'mode' in which this list is in, which might be + to exclude these render queues, or to include them alone (excluding + all other queues). This allows you to perform broad selective + rendering without requiring a RenderQueueListener. + @param qid The identifier of the queue which should be added to the + special case list. Nothing happens if the queue is already in the list. + */ + virtual void addSpecialCaseRenderQueue(uint8 qid); + /** Removes an item to the 'special case' render queue list. + @see SceneManager::addSpecialCaseRenderQueue + @param qid The identifier of the queue which should be removed from the + special case list. Nothing happens if the queue is not in the list. + */ + virtual void removeSpecialCaseRenderQueue(uint8 qid); + /** Clears the 'special case' render queue list. + @see SceneManager::addSpecialCaseRenderQueue + */ + virtual void clearSpecialCaseRenderQueues(void); + /** Sets the way the special case render queue list is processed. + @see SceneManager::addSpecialCaseRenderQueue + @param mode The mode of processing + */ + virtual void setSpecialCaseRenderQueueMode(SpecialCaseRenderQueueMode mode); + /** Gets the way the special case render queue list is processed. */ + virtual SpecialCaseRenderQueueMode getSpecialCaseRenderQueueMode(void); + /** Returns whether or not the named queue will be rendered based on the + current 'special case' render queue list and mode. + @see SceneManager::addSpecialCaseRenderQueue + @param qid The identifier of the queue which should be tested + @return true if the queue will be rendered, false otherwise + */ + virtual bool isRenderQueueToBeProcessed(uint8 qid); + + /** Sets the render queue that the world geometry (if any) this SceneManager + renders will be associated with. + @remarks + SceneManagers which provide 'world geometry' should place it in a + specialised render queue in order to make it possible to enable / + disable it easily using the addSpecialCaseRenderQueue method. Even + if the SceneManager does not use the render queues to render the + world geometry, it should still pick a queue to represent it's manual + rendering, and check isRenderQueueToBeProcessed before rendering. + @note + Setting this may not affect the actual ordering of rendering the + world geometry, if the world geometry is being rendered manually + by the SceneManager. If the SceneManager feeds world geometry into + the queues, however, the ordering will be affected. + */ + virtual void setWorldGeometryRenderQueue(uint8 qid); + /** Gets the render queue that the world geometry (if any) this SceneManager + renders will be associated with. + @remarks + SceneManagers which provide 'world geometry' should place it in a + specialised render queue in order to make it possible to enable / + disable it easily using the addSpecialCaseRenderQueue method. Even + if the SceneManager does not use the render queues to render the + world geometry, it should still pick a queue to represent it's manual + rendering, and check isRenderQueueToBeProcessed before rendering. + */ + virtual uint8 getWorldGeometryRenderQueue(void); + + /** Allows all bounding boxes of scene nodes to be displayed. */ + virtual void showBoundingBoxes(bool bShow); + + /** Returns if all bounding boxes of scene nodes are to be displayed */ + virtual bool getShowBoundingBoxes() const; /** Internal method for notifying the manager that a SceneNode is autotracking. */ virtual void _notifyAutotrackingSceneNode(SceneNode* node, bool autoTrack); @@ -2648,20 +2648,20 @@ namespace Ogre { typedef MapIterator AnimationIterator; /** Returns a specialised MapIterator over all cameras in the scene. - */ + */ CameraIterator getCameraIterator(void) { return CameraIterator(mCameras.begin(), mCameras.end()); } - /** Returns a const version of the camera list. - */ - const CameraList& getCameras() const { return mCameras; } + /** Returns a const version of the camera list. + */ + const CameraList& getCameras() const { return mCameras; } /** Returns a specialised MapIterator over all animations in the scene. */ AnimationIterator getAnimationIterator(void) { return AnimationIterator(mAnimationsList.begin(), mAnimationsList.end()); } - /** Returns a const version of the animation list. - */ - const AnimationList& getAnimations() const { return mAnimationsList; } + /** Returns a const version of the animation list. + */ + const AnimationList& getAnimations() const { return mAnimationsList; } /** Returns a specialised MapIterator over all animation states in the scene. */ AnimationStateIterator getAnimationStateIterator(void) { return mAnimationStates.getAnimationStateIterator(); @@ -2763,77 +2763,77 @@ namespace Ogre { virtual Real getShadowFarDistanceSquared(void) const { return mDefaultShadowFarDistSquared; } - /** Sets the maximum size of the index buffer used to render shadow - primitives. - @remarks - This method allows you to tweak the size of the index buffer used - to render shadow primitives (including stencil shadow volumes). The - default size is 51,200 entries, which is 100k of GPU memory, or - enough to render approximately 17,000 triangles. You can reduce this - as long as you do not have any models / world geometry chunks which - could require more than the amount you set. - @par - The maximum number of triangles required to render a single shadow - volume (including light and dark caps when needed) will be 3x the - number of edges on the light silhouette, plus the number of - light-facing triangles. On average, half the - triangles will be facing toward the light, but the number of - triangles in the silhouette entirely depends on the mesh - - angular meshes will have a higher silhouette tris/mesh tris - ratio than a smooth mesh. You can estimate the requirements for - your particular mesh by rendering it alone in a scene with shadows - enabled and a single light - rotate it or the light and make a note - of how high the triangle count goes (remembering to subtract the - mesh triangle count) - @param size The number of indexes; divide this by 3 to determine the - number of triangles. - */ - virtual void setShadowIndexBufferSize(size_t size); + /** Sets the maximum size of the index buffer used to render shadow + primitives. + @remarks + This method allows you to tweak the size of the index buffer used + to render shadow primitives (including stencil shadow volumes). The + default size is 51,200 entries, which is 100k of GPU memory, or + enough to render approximately 17,000 triangles. You can reduce this + as long as you do not have any models / world geometry chunks which + could require more than the amount you set. + @par + The maximum number of triangles required to render a single shadow + volume (including light and dark caps when needed) will be 3x the + number of edges on the light silhouette, plus the number of + light-facing triangles. On average, half the + triangles will be facing toward the light, but the number of + triangles in the silhouette entirely depends on the mesh - + angular meshes will have a higher silhouette tris/mesh tris + ratio than a smooth mesh. You can estimate the requirements for + your particular mesh by rendering it alone in a scene with shadows + enabled and a single light - rotate it or the light and make a note + of how high the triangle count goes (remembering to subtract the + mesh triangle count) + @param size The number of indexes; divide this by 3 to determine the + number of triangles. + */ + virtual void setShadowIndexBufferSize(size_t size); /// Get the size of the shadow index buffer - virtual size_t getShadowIndexBufferSize(void) const - { return mShadowIndexBufferSize; } + virtual size_t getShadowIndexBufferSize(void) const + { return mShadowIndexBufferSize; } /** Set the size of the texture used for all texture-based shadows. @remarks The larger the shadow texture, the better the detail on texture based shadows, but obviously this takes more memory. The default size is 512. Sizes must be a power of 2. - @note This is the simple form, see setShadowTextureConfig for the more - complex form. + @note This is the simple form, see setShadowTextureConfig for the more + complex form. */ virtual void setShadowTextureSize(unsigned short size); - /** Set the detailed configuration for a shadow texture. - @param shadowIndex The index of the texture to configure, must be < the - number of shadow textures setting - @param width The width of the texture + /** Set the detailed configuration for a shadow texture. + @param shadowIndex The index of the texture to configure, must be < the + number of shadow textures setting + @param width The width of the texture @param height The height of the texture - @param format The pixel format of the texture + @param format The pixel format of the texture @param fsaa The level of multisampling to use. Ignored if the device does not support it. - @param depthBufferPoolId The pool # it should query the depth buffers from - */ - virtual void setShadowTextureConfig(size_t shadowIndex, unsigned short width, - unsigned short height, PixelFormat format, unsigned short fsaa = 0, uint16 depthBufferPoolId=1); - /** Set the detailed configuration for a shadow texture. - @param shadowIndex The index of the texture to configure, must be < the - number of shadow textures setting - @param config Configuration structure - */ - virtual void setShadowTextureConfig(size_t shadowIndex, - const ShadowTextureConfig& config); - - /** Get an iterator over the current shadow texture settings. */ - ConstShadowTextureConfigIterator getShadowTextureConfigIterator() const; + @param depthBufferPoolId The pool # it should query the depth buffers from + */ + virtual void setShadowTextureConfig(size_t shadowIndex, unsigned short width, + unsigned short height, PixelFormat format, unsigned short fsaa = 0, uint16 depthBufferPoolId=1); + /** Set the detailed configuration for a shadow texture. + @param shadowIndex The index of the texture to configure, must be < the + number of shadow textures setting + @param config Configuration structure + */ + virtual void setShadowTextureConfig(size_t shadowIndex, + const ShadowTextureConfig& config); + + /** Get an iterator over the current shadow texture settings. */ + ConstShadowTextureConfigIterator getShadowTextureConfigIterator() const; /** Set the pixel format of the textures used for texture-based shadows. @remarks - By default, a colour texture is used (PF_X8R8G8B8) for texture shadows, - but if you want to use more advanced texture shadow types you can - alter this. If you do, you will have to also call - setShadowTextureCasterMaterial and setShadowTextureReceiverMaterial - to provide shader-based materials to use these customised shadow - texture formats. - @note This is the simple form, see setShadowTextureConfig for the more - complex form. + By default, a colour texture is used (PF_X8R8G8B8) for texture shadows, + but if you want to use more advanced texture shadow types you can + alter this. If you do, you will have to also call + setShadowTextureCasterMaterial and setShadowTextureReceiverMaterial + to provide shader-based materials to use these customised shadow + texture formats. + @note This is the simple form, see setShadowTextureConfig for the more + complex form. */ virtual void setShadowTexturePixelFormat(PixelFormat fmt); /** Set the level of multisample AA of the textures used for texture-based shadows. @@ -2855,38 +2855,38 @@ namespace Ogre { /// Get the number of the textures allocated for texture based shadows size_t getShadowTextureCount(void) const {return mShadowTextureConfigList.size(); } - /** Set the number of shadow textures a light type uses. - @remarks - The default for all light types is 1. This means that each light uses only 1 shadow - texture. Call this if you need more than 1 shadow texture per light, E.G. PSSM. - @note - This feature only works with the Integrated shadow technique. - Also remember to increase the total number of shadow textures you request - appropriately (e.g. via setShadowTextureCount)!! - */ - void setShadowTextureCountPerLightType(Light::LightTypes type, size_t count) - { mShadowTextureCountPerType[type] = count; } - /// Get the number of shadow textures is assigned for the given light type. - size_t getShadowTextureCountPerLightType(Light::LightTypes type) const - {return mShadowTextureCountPerType[type]; } + /** Set the number of shadow textures a light type uses. + @remarks + The default for all light types is 1. This means that each light uses only 1 shadow + texture. Call this if you need more than 1 shadow texture per light, E.G. PSSM. + @note + This feature only works with the Integrated shadow technique. + Also remember to increase the total number of shadow textures you request + appropriately (e.g. via setShadowTextureCount)!! + */ + void setShadowTextureCountPerLightType(Light::LightTypes type, size_t count) + { mShadowTextureCountPerType[type] = count; } + /// Get the number of shadow textures is assigned for the given light type. + size_t getShadowTextureCountPerLightType(Light::LightTypes type) const + {return mShadowTextureCountPerType[type]; } /** Sets the size and count of textures used in texture-based shadows. @see setShadowTextureSize and setShadowTextureCount for details, this method just allows you to change both at once, which can save on reallocation if the textures have already been created. - @note This is the simple form, see setShadowTextureConfig for the more - complex form. + @note This is the simple form, see setShadowTextureConfig for the more + complex form. */ virtual void setShadowTextureSettings(unsigned short size, unsigned short count, - PixelFormat fmt = PF_X8R8G8B8, unsigned short fsaa = 0, uint16 depthBufferPoolId=1); + PixelFormat fmt = PF_X8R8G8B8, unsigned short fsaa = 0, uint16 depthBufferPoolId=1); - /** Get a reference to the shadow texture currently in use at the given index. - @note - If you change shadow settings, this reference may no longer - be correct, so be sure not to hold the returned reference over - texture shadow configuration changes. - */ - virtual const TexturePtr& getShadowTexture(size_t shadowIndex); + /** Get a reference to the shadow texture currently in use at the given index. + @note + If you change shadow settings, this reference may no longer + be correct, so be sure not to hold the returned reference over + texture shadow configuration changes. + */ + virtual const TexturePtr& getShadowTexture(size_t shadowIndex); /** Sets the proportional distance which a texture shadow which is generated from a directional light will be offset into the camera view to make best use of texture space. @@ -2903,10 +2903,10 @@ namespace Ogre { far distance, and the default is 0.6. */ virtual void setShadowDirLightTextureOffset(Real offset) { mShadowTextureOffset = offset;} - /** Gets the proportional distance which a texture shadow which is generated from a - directional light will be offset into the camera view to make best use of texture space. - */ - virtual Real getShadowDirLightTextureOffset(void) const { return mShadowTextureOffset; } + /** Gets the proportional distance which a texture shadow which is generated from a + directional light will be offset into the camera view to make best use of texture space. + */ + virtual Real getShadowDirLightTextureOffset(void) const { return mShadowTextureOffset; } /** Sets the proportional distance at which texture shadows begin to fade out. @remarks To hide the edges where texture shadows end (in directional lights) @@ -2926,601 +2926,601 @@ namespace Ogre { virtual void setShadowTextureFadeEnd(Real fadeEnd) { mShadowTextureFadeEnd = fadeEnd; } - /** Sets whether or not texture shadows should attempt to self-shadow. - @remarks - The default implementation of texture shadows uses a fixed-function - colour texture projection approach for maximum compatibility, and - as such cannot support self-shadowing. However, if you decide to - implement a more complex shadowing technique using the - setShadowTextureCasterMaterial and setShadowTextureReceiverMaterial - there is a possibility you may be able to support - self-shadowing (e.g by implementing a shader-based shadow map). In - this case you might want to enable this option. - @param selfShadow Whether to attempt self-shadowing with texture shadows - */ - virtual void setShadowTextureSelfShadow(bool selfShadow); - - /// Gets whether or not texture shadows attempt to self-shadow. - virtual bool getShadowTextureSelfShadow(void) const - { return mShadowTextureSelfShadow; } - /** Sets the default material to use for rendering shadow casters. - @remarks - By default shadow casters are rendered into the shadow texture using - an automatically generated fixed-function pass. This allows basic - projective texture shadows, but it's possible to use more advanced - shadow techniques by overriding the caster and receiver materials, for - example providing vertex and fragment programs to implement shadow - maps. - @par - You can rely on the ambient light in the scene being set to the - requested texture shadow colour, if that's useful. - @note - Individual objects may also override the vertex program in - your default material if their materials include - shadow_caster_vertex_program_ref, shadow_receiver_vertex_program_ref - shadow_caster_material entries, so if you use both make sure they are compatible. - @note - Only a single pass is allowed in your material, although multiple - techniques may be used for hardware fallback. - */ - virtual void setShadowTextureCasterMaterial(const String& name); - /** Sets the default material to use for rendering shadow receivers. - @remarks - By default shadow receivers are rendered as a post-pass using basic - modulation. This allows basic projective texture shadows, but it's - possible to use more advanced shadow techniques by overriding the - caster and receiver materials, for example providing vertex and - fragment programs to implement shadow maps. - @par - You can rely on texture unit 0 containing the shadow texture, and - for the unit to be set to use projective texturing from the light - (only useful if you're using fixed-function, which is unlikely; - otherwise you should rely on the texture_viewproj_matrix auto binding) - @note - Individual objects may also override the vertex program in - your default material if their materials include - shadow_caster_vertex_program_ref shadow_receiver_vertex_program_ref - shadow_receiver_material entries, so if you use both make sure they are compatible. - @note - Only a single pass is allowed in your material, although multiple - techniques may be used for hardware fallback. - */ - virtual void setShadowTextureReceiverMaterial(const String& name); - - /** Sets whether or not shadow casters should be rendered into shadow - textures using their back faces rather than their front faces. - @remarks - Rendering back faces rather than front faces into a shadow texture - can help minimise depth comparison issues, if you're using depth - shadowmapping. You will probably still need some biasing but you - won't need as much. For solid objects the result is the same anyway, - if you have objects with holes you may want to turn this option off. - The default is to enable this option. - */ - virtual void setShadowCasterRenderBackFaces(bool bf) { mShadowCasterRenderBackFaces = bf; } - - /** Gets whether or not shadow casters should be rendered into shadow - textures using their back faces rather than their front faces. - */ - virtual bool getShadowCasterRenderBackFaces() const { return mShadowCasterRenderBackFaces; } - - /** Set the shadow camera setup to use for all lights which don't have - their own shadow camera setup. - @see ShadowCameraSetup - */ - virtual void setShadowCameraSetup(const ShadowCameraSetupPtr& shadowSetup); - - /** Get the shadow camera setup in use for all lights which don't have - their own shadow camera setup. - @see ShadowCameraSetup - */ - virtual const ShadowCameraSetupPtr& getShadowCameraSetup() const; - - /** Sets whether we should use an inifinite camera far plane - when rendering stencil shadows. - @remarks - Stencil shadow coherency is very reliant on the shadow volume - not being clipped by the far plane. If this clipping happens, you - get a kind of 'negative' shadow effect. The best way to achieve - coherency is to move the far plane of the camera out to infinity, - thus preventing the far plane from clipping the shadow volumes. - When combined with vertex program extrusion of the volume to - infinity, which Ogre does when available, this results in very - robust shadow volumes. For this reason, when you enable stencil - shadows, Ogre automatically changes your camera settings to - project to infinity if the card supports it. You can disable this - behaviour if you like by calling this method; although you can - never enable infinite projection if the card does not support it. - @par - If you disable infinite projection, or it is not available, - you need to be far more careful with your light attenuation / - directional light extrusion distances to avoid clipping artefacts - at the far plane. - @note - Recent cards will generally support infinite far plane projection. - However, we have found some cases where they do not, especially - on Direct3D. There is no standard capability we can check to - validate this, so we use some heuristics based on experience: -
        -
      • OpenGL always seems to support it no matter what the card
      • -
      • Direct3D on non-vertex program capable systems (including - vertex program capable cards on Direct3D7) does not - support it
      • -
      • Direct3D on GeForce3 and GeForce4 Ti does not seem to support - infinite projection
      • -
      - Therefore in the RenderSystem implementation, we may veto the use - of an infinite far plane based on these heuristics. - */ + /** Sets whether or not texture shadows should attempt to self-shadow. + @remarks + The default implementation of texture shadows uses a fixed-function + colour texture projection approach for maximum compatibility, and + as such cannot support self-shadowing. However, if you decide to + implement a more complex shadowing technique using the + setShadowTextureCasterMaterial and setShadowTextureReceiverMaterial + there is a possibility you may be able to support + self-shadowing (e.g by implementing a shader-based shadow map). In + this case you might want to enable this option. + @param selfShadow Whether to attempt self-shadowing with texture shadows + */ + virtual void setShadowTextureSelfShadow(bool selfShadow); + + /// Gets whether or not texture shadows attempt to self-shadow. + virtual bool getShadowTextureSelfShadow(void) const + { return mShadowTextureSelfShadow; } + /** Sets the default material to use for rendering shadow casters. + @remarks + By default shadow casters are rendered into the shadow texture using + an automatically generated fixed-function pass. This allows basic + projective texture shadows, but it's possible to use more advanced + shadow techniques by overriding the caster and receiver materials, for + example providing vertex and fragment programs to implement shadow + maps. + @par + You can rely on the ambient light in the scene being set to the + requested texture shadow colour, if that's useful. + @note + Individual objects may also override the vertex program in + your default material if their materials include + shadow_caster_vertex_program_ref, shadow_receiver_vertex_program_ref + shadow_caster_material entries, so if you use both make sure they are compatible. + @note + Only a single pass is allowed in your material, although multiple + techniques may be used for hardware fallback. + */ + virtual void setShadowTextureCasterMaterial(const String& name); + /** Sets the default material to use for rendering shadow receivers. + @remarks + By default shadow receivers are rendered as a post-pass using basic + modulation. This allows basic projective texture shadows, but it's + possible to use more advanced shadow techniques by overriding the + caster and receiver materials, for example providing vertex and + fragment programs to implement shadow maps. + @par + You can rely on texture unit 0 containing the shadow texture, and + for the unit to be set to use projective texturing from the light + (only useful if you're using fixed-function, which is unlikely; + otherwise you should rely on the texture_viewproj_matrix auto binding) + @note + Individual objects may also override the vertex program in + your default material if their materials include + shadow_caster_vertex_program_ref shadow_receiver_vertex_program_ref + shadow_receiver_material entries, so if you use both make sure they are compatible. + @note + Only a single pass is allowed in your material, although multiple + techniques may be used for hardware fallback. + */ + virtual void setShadowTextureReceiverMaterial(const String& name); + + /** Sets whether or not shadow casters should be rendered into shadow + textures using their back faces rather than their front faces. + @remarks + Rendering back faces rather than front faces into a shadow texture + can help minimise depth comparison issues, if you're using depth + shadowmapping. You will probably still need some biasing but you + won't need as much. For solid objects the result is the same anyway, + if you have objects with holes you may want to turn this option off. + The default is to enable this option. + */ + virtual void setShadowCasterRenderBackFaces(bool bf) { mShadowCasterRenderBackFaces = bf; } + + /** Gets whether or not shadow casters should be rendered into shadow + textures using their back faces rather than their front faces. + */ + virtual bool getShadowCasterRenderBackFaces() const { return mShadowCasterRenderBackFaces; } + + /** Set the shadow camera setup to use for all lights which don't have + their own shadow camera setup. + @see ShadowCameraSetup + */ + virtual void setShadowCameraSetup(const ShadowCameraSetupPtr& shadowSetup); + + /** Get the shadow camera setup in use for all lights which don't have + their own shadow camera setup. + @see ShadowCameraSetup + */ + virtual const ShadowCameraSetupPtr& getShadowCameraSetup() const; + + /** Sets whether we should use an inifinite camera far plane + when rendering stencil shadows. + @remarks + Stencil shadow coherency is very reliant on the shadow volume + not being clipped by the far plane. If this clipping happens, you + get a kind of 'negative' shadow effect. The best way to achieve + coherency is to move the far plane of the camera out to infinity, + thus preventing the far plane from clipping the shadow volumes. + When combined with vertex program extrusion of the volume to + infinity, which Ogre does when available, this results in very + robust shadow volumes. For this reason, when you enable stencil + shadows, Ogre automatically changes your camera settings to + project to infinity if the card supports it. You can disable this + behaviour if you like by calling this method; although you can + never enable infinite projection if the card does not support it. + @par + If you disable infinite projection, or it is not available, + you need to be far more careful with your light attenuation / + directional light extrusion distances to avoid clipping artefacts + at the far plane. + @note + Recent cards will generally support infinite far plane projection. + However, we have found some cases where they do not, especially + on Direct3D. There is no standard capability we can check to + validate this, so we use some heuristics based on experience: +
        +
      • OpenGL always seems to support it no matter what the card
      • +
      • Direct3D on non-vertex program capable systems (including + vertex program capable cards on Direct3D7) does not + support it
      • +
      • Direct3D on GeForce3 and GeForce4 Ti does not seem to support + infinite projection
      • +
      + Therefore in the RenderSystem implementation, we may veto the use + of an infinite far plane based on these heuristics. + */ virtual void setShadowUseInfiniteFarPlane(bool enable) { mShadowUseInfiniteFarPlane = enable; } - /** Is there a stencil shadow based shadowing technique in use? */ - virtual bool isShadowTechniqueStencilBased(void) const - { return (mShadowTechnique & SHADOWDETAILTYPE_STENCIL) != 0; } - /** Is there a texture shadow based shadowing technique in use? */ - virtual bool isShadowTechniqueTextureBased(void) const - { return (mShadowTechnique & SHADOWDETAILTYPE_TEXTURE) != 0; } - /** Is there a modulative shadowing technique in use? */ - virtual bool isShadowTechniqueModulative(void) const - { return (mShadowTechnique & SHADOWDETAILTYPE_MODULATIVE) != 0; } - /** Is there an additive shadowing technique in use? */ - virtual bool isShadowTechniqueAdditive(void) const - { return (mShadowTechnique & SHADOWDETAILTYPE_ADDITIVE) != 0; } - /** Is the shadow technique integrated into primary materials? */ - virtual bool isShadowTechniqueIntegrated(void) const - { return (mShadowTechnique & SHADOWDETAILTYPE_INTEGRATED) != 0; } - /** Is there any shadowing technique in use? */ - virtual bool isShadowTechniqueInUse(void) const - { return mShadowTechnique != SHADOWTYPE_NONE; } - /** Sets whether when using a built-in additive shadow mode, user clip - planes should be used to restrict light rendering. - */ - virtual void setShadowUseLightClipPlanes(bool enabled) { mShadowAdditiveLightClip = enabled; } - /** Gets whether when using a built-in additive shadow mode, user clip - planes should be used to restrict light rendering. - */ - virtual bool getShadowUseLightClipPlanes() const { return mShadowAdditiveLightClip; } - - /** Sets the active compositor chain of the current scene being rendered. - @note CompositorChain does this automatically, no need to call manually. - */ - virtual void _setActiveCompositorChain(CompositorChain* chain) { mActiveCompositorChain = chain; } - - /** Sets whether to use late material resolving or not. If set, materials will be resolved - from the materials at the pass-setting stage and not at the render queue building stage. - This is useful when the active material scheme during the render queue building stage - is different from the one during the rendering stage. - */ - virtual void setLateMaterialResolving(bool isLate) { mLateMaterialResolving = isLate; } - - /** Gets whether using late material resolving or not. - @see setLateMaterialResolving */ - virtual bool isLateMaterialResolving() const { return mLateMaterialResolving; } - - /** Gets the active compositor chain of the current scene being rendered */ - virtual CompositorChain* _getActiveCompositorChain() const { return mActiveCompositorChain; } - - /** Add a listener which will get called back on scene manager events. - */ - virtual void addListener(Listener* s); - /** Remove a listener - */ - virtual void removeListener(Listener* s); - - /** Creates a StaticGeometry instance suitable for use with this - SceneManager. - @remarks - StaticGeometry is a way of batching up geometry into a more - efficient form at the expense of being able to move it. Please - read the StaticGeometry class documentation for full information. - @param name The name to give the new object - @return The new StaticGeometry instance - */ - virtual StaticGeometry* createStaticGeometry(const String& name); - /** Retrieve a previously created StaticGeometry instance. - @note Throws an exception if the named instance does not exist - */ - virtual StaticGeometry* getStaticGeometry(const String& name) const; - /** Returns whether a static geometry instance with the given name exists. */ - virtual bool hasStaticGeometry(const String& name) const; - /** Remove & destroy a StaticGeometry instance. */ - virtual void destroyStaticGeometry(StaticGeometry* geom); - /** Remove & destroy a StaticGeometry instance. */ - virtual void destroyStaticGeometry(const String& name); - /** Remove & destroy all StaticGeometry instances. */ - virtual void destroyAllStaticGeometry(void); - - /** Creates a InstancedGeometry instance suitable for use with this - SceneManager. - @remarks - InstancedGeometry is a way of batching up geometry into a more - efficient form, and still be able to move it. Please - read the InstancedGeometry class documentation for full information. - @param name The name to give the new object - @return The new InstancedGeometry instance - */ - virtual InstancedGeometry* createInstancedGeometry(const String& name); - /** Retrieve a previously created InstancedGeometry instance. */ - virtual InstancedGeometry* getInstancedGeometry(const String& name) const; - /** Remove & destroy a InstancedGeometry instance. */ - virtual void destroyInstancedGeometry(InstancedGeometry* geom); - /** Remove & destroy a InstancedGeometry instance. */ - virtual void destroyInstancedGeometry(const String& name); - /** Remove & destroy all InstancedGeometry instances. */ - virtual void destroyAllInstancedGeometry(void); - - /** Creates an InstanceManager interface to create & manipulate instanced entities - You need to call this function at least once before start calling createInstancedEntity - to build up an instance based on the given mesh. - @remarks - Instancing is a way of batching up geometry into a much more - efficient form, but with some limitations, and still be able to move & animate it. - Please @see InstanceManager class documentation for full information. - @param customName Custom name for referencing. Must be unique - @param meshName The mesh name the instances will be based upon - @param groupName The resource name where the mesh lives - @param technique Technique to use, which may be shader based, or hardware based. - @param numInstancesPerBatch Suggested number of instances per batch. The actual number - may end up being lower if the technique doesn't support having so many. It can't be zero - @param flags Flags to pass to the InstanceManager @see InstanceManagerFlags - @param subMeshIdx InstanceManager only supports using one submesh from the base mesh. This parameter - says which submesh to pick (must be <= Mesh::getNumSubMeshes()) - @return The new InstanceManager instance - */ - virtual InstanceManager* createInstanceManager( const String &customName, const String &meshName, - const String &groupName, - InstanceManager::InstancingTechnique technique, - size_t numInstancesPerBatch, uint16 flags=0, - unsigned short subMeshIdx=0 ); - - /** Retrieves an existing InstanceManager by it's name. - @note Throws an exception if the named InstanceManager does not exist - */ - virtual InstanceManager* getInstanceManager( const String &managerName ) const; + /** Is there a stencil shadow based shadowing technique in use? */ + virtual bool isShadowTechniqueStencilBased(void) const + { return (mShadowTechnique & SHADOWDETAILTYPE_STENCIL) != 0; } + /** Is there a texture shadow based shadowing technique in use? */ + virtual bool isShadowTechniqueTextureBased(void) const + { return (mShadowTechnique & SHADOWDETAILTYPE_TEXTURE) != 0; } + /** Is there a modulative shadowing technique in use? */ + virtual bool isShadowTechniqueModulative(void) const + { return (mShadowTechnique & SHADOWDETAILTYPE_MODULATIVE) != 0; } + /** Is there an additive shadowing technique in use? */ + virtual bool isShadowTechniqueAdditive(void) const + { return (mShadowTechnique & SHADOWDETAILTYPE_ADDITIVE) != 0; } + /** Is the shadow technique integrated into primary materials? */ + virtual bool isShadowTechniqueIntegrated(void) const + { return (mShadowTechnique & SHADOWDETAILTYPE_INTEGRATED) != 0; } + /** Is there any shadowing technique in use? */ + virtual bool isShadowTechniqueInUse(void) const + { return mShadowTechnique != SHADOWTYPE_NONE; } + /** Sets whether when using a built-in additive shadow mode, user clip + planes should be used to restrict light rendering. + */ + virtual void setShadowUseLightClipPlanes(bool enabled) { mShadowAdditiveLightClip = enabled; } + /** Gets whether when using a built-in additive shadow mode, user clip + planes should be used to restrict light rendering. + */ + virtual bool getShadowUseLightClipPlanes() const { return mShadowAdditiveLightClip; } + + /** Sets the active compositor chain of the current scene being rendered. + @note CompositorChain does this automatically, no need to call manually. + */ + virtual void _setActiveCompositorChain(CompositorChain* chain) { mActiveCompositorChain = chain; } + + /** Sets whether to use late material resolving or not. If set, materials will be resolved + from the materials at the pass-setting stage and not at the render queue building stage. + This is useful when the active material scheme during the render queue building stage + is different from the one during the rendering stage. + */ + virtual void setLateMaterialResolving(bool isLate) { mLateMaterialResolving = isLate; } + + /** Gets whether using late material resolving or not. + @see setLateMaterialResolving */ + virtual bool isLateMaterialResolving() const { return mLateMaterialResolving; } + + /** Gets the active compositor chain of the current scene being rendered */ + virtual CompositorChain* _getActiveCompositorChain() const { return mActiveCompositorChain; } + + /** Add a listener which will get called back on scene manager events. + */ + virtual void addListener(Listener* s); + /** Remove a listener + */ + virtual void removeListener(Listener* s); + + /** Creates a StaticGeometry instance suitable for use with this + SceneManager. + @remarks + StaticGeometry is a way of batching up geometry into a more + efficient form at the expense of being able to move it. Please + read the StaticGeometry class documentation for full information. + @param name The name to give the new object + @return The new StaticGeometry instance + */ + virtual StaticGeometry* createStaticGeometry(const String& name); + /** Retrieve a previously created StaticGeometry instance. + @note Throws an exception if the named instance does not exist + */ + virtual StaticGeometry* getStaticGeometry(const String& name) const; + /** Returns whether a static geometry instance with the given name exists. */ + virtual bool hasStaticGeometry(const String& name) const; + /** Remove & destroy a StaticGeometry instance. */ + virtual void destroyStaticGeometry(StaticGeometry* geom); + /** Remove & destroy a StaticGeometry instance. */ + virtual void destroyStaticGeometry(const String& name); + /** Remove & destroy all StaticGeometry instances. */ + virtual void destroyAllStaticGeometry(void); + + /** Creates a InstancedGeometry instance suitable for use with this + SceneManager. + @remarks + InstancedGeometry is a way of batching up geometry into a more + efficient form, and still be able to move it. Please + read the InstancedGeometry class documentation for full information. + @param name The name to give the new object + @return The new InstancedGeometry instance + */ + virtual InstancedGeometry* createInstancedGeometry(const String& name); + /** Retrieve a previously created InstancedGeometry instance. */ + virtual InstancedGeometry* getInstancedGeometry(const String& name) const; + /** Remove & destroy a InstancedGeometry instance. */ + virtual void destroyInstancedGeometry(InstancedGeometry* geom); + /** Remove & destroy a InstancedGeometry instance. */ + virtual void destroyInstancedGeometry(const String& name); + /** Remove & destroy all InstancedGeometry instances. */ + virtual void destroyAllInstancedGeometry(void); + + /** Creates an InstanceManager interface to create & manipulate instanced entities + You need to call this function at least once before start calling createInstancedEntity + to build up an instance based on the given mesh. + @remarks + Instancing is a way of batching up geometry into a much more + efficient form, but with some limitations, and still be able to move & animate it. + Please @see InstanceManager class documentation for full information. + @param customName Custom name for referencing. Must be unique + @param meshName The mesh name the instances will be based upon + @param groupName The resource name where the mesh lives + @param technique Technique to use, which may be shader based, or hardware based. + @param numInstancesPerBatch Suggested number of instances per batch. The actual number + may end up being lower if the technique doesn't support having so many. It can't be zero + @param flags Flags to pass to the InstanceManager @see InstanceManagerFlags + @param subMeshIdx InstanceManager only supports using one submesh from the base mesh. This parameter + says which submesh to pick (must be <= Mesh::getNumSubMeshes()) + @return The new InstanceManager instance + */ + virtual InstanceManager* createInstanceManager( const String &customName, const String &meshName, + const String &groupName, + InstanceManager::InstancingTechnique technique, + size_t numInstancesPerBatch, uint16 flags=0, + unsigned short subMeshIdx=0 ); + + /** Retrieves an existing InstanceManager by it's name. + @note Throws an exception if the named InstanceManager does not exist + */ + virtual InstanceManager* getInstanceManager( const String &managerName ) const; /** Returns whether an InstanceManager with the given name exists. */ virtual bool hasInstanceManager( const String &managerName ) const; - /** Destroys an InstanceManager if it was created with createInstanceManager() - @remarks - Be sure you don't have any InstancedEntity referenced somewhere which was created with - this manager, since it will become a dangling pointer. - @param name Name of the manager to remove - */ - virtual void destroyInstanceManager( const String &name ); - virtual void destroyInstanceManager( InstanceManager *instanceManager ); - - virtual void destroyAllInstanceManagers(void); - - /** @see InstanceManager::getMaxOrBestNumInstancesPerBatch - @remarks - If you've already created an InstanceManager, you can call it's - getMaxOrBestNumInstancesPerBatch() function directly. - Another (not recommended) way to know if the technique is unsupported is by creating - an InstanceManager and use createInstancedEntity, which will return null pointer. - The input parameter "numInstancesPerBatch" is a suggested value when using IM_VTFBESTFIT - flag (in that case it should be non-zero) - @return - The ideal (or maximum, depending on flags) number of instances per batch for - the given technique. Zero if technique is unsupported or errors were spotted - */ - virtual size_t getNumInstancesPerBatch( const String &meshName, const String &groupName, - const String &materialName, - InstanceManager::InstancingTechnique technique, - size_t numInstancesPerBatch, uint16 flags=0, - unsigned short subMeshIdx=0 ); - - /** Creates an InstancedEntity based on an existing InstanceManager (@see createInstanceManager) - @remarks - * Return value may be null if the InstanceManger technique isn't supported - * Try to keep the number of entities with different materials to a minimum - * For more information @see InstancedManager @see InstancedBatch, @see InstancedEntity - * Alternatively you can call InstancedManager::createInstanceEntity using the returned - pointer from createInstanceManager - @param materialName Material name - @param managerName Name of the instance manager - @return An InstancedEntity ready to be attached to a SceneNode - */ - virtual InstancedEntity* createInstancedEntity( const String &materialName, - const String &managerName ); - - /** Removes an InstancedEntity, @see SceneManager::createInstancedEntity & - @see InstanceBatch::removeInstancedEntity - @param instancedEntity Instance to remove - */ - virtual void destroyInstancedEntity( InstancedEntity *instancedEntity ); - - /** Called by an InstanceManager when it has at least one InstanceBatch that needs their bounds - to be updated for proper culling - @param dirtyManager The manager with dirty batches to update - */ - void _addDirtyInstanceManager( InstanceManager *dirtyManager ); - - /** Create a movable object of the type specified. - @remarks - This is the generalised form of MovableObject creation where you can - create a MovableObject of any specialised type generically, including - any new types registered using plugins. - @param name The name to give the object. Must be unique within type. - @param typeName The type of object to create - @param params Optional name/value pair list to give extra parameters to - the created object. - */ - virtual MovableObject* createMovableObject(const String& name, - const String& typeName, const NameValuePairList* params = 0); - /** Create a movable object of the type specified without a name. - @remarks - This is the generalised form of MovableObject creation where you can - create a MovableObject of any specialised type generically, including - any new types registered using plugins. The name is generated automatically. - @param typeName The type of object to create - @param params Optional name/value pair list to give extra parameters to - the created object. - */ - virtual MovableObject* createMovableObject(const String& typeName, const NameValuePairList* params = 0); - /** Destroys a MovableObject with the name specified, of the type specified. - @remarks - The MovableObject will automatically detach itself from any nodes - on destruction. - */ - virtual void destroyMovableObject(const String& name, const String& typeName); - /** Destroys a MovableObject. - @remarks - The MovableObject will automatically detach itself from any nodes - on destruction. - */ - virtual void destroyMovableObject(MovableObject* m); - /** Destroy all MovableObjects of a given type. */ - virtual void destroyAllMovableObjectsByType(const String& typeName); - /** Destroy all MovableObjects. */ - virtual void destroyAllMovableObjects(void); - /** Get a reference to a previously created MovableObject. - @note Throws an exception if the named instance does not exist - */ - virtual MovableObject* getMovableObject(const String& name, const String& typeName) const; - /** Returns whether a movable object instance with the given name exists. */ - virtual bool hasMovableObject(const String& name, const String& typeName) const; - typedef MapIterator MovableObjectIterator; - /** Get an iterator over all MovableObect instances of a given type. - @note - The iterator returned from this method is not thread safe, do not use this - if you are creating or deleting objects of this type in another thread. - */ - virtual MovableObjectIterator getMovableObjectIterator(const String& typeName); - /** Inject a MovableObject instance created externally. - @remarks - This method 'injects' a MovableObject instance created externally into - the MovableObject instance registry held in the SceneManager. You - might want to use this if you have a MovableObject which you don't - want to register a factory for; for example a MovableObject which - cannot be generally constructed by clients. - @note - It is important that the MovableObject has a unique name for the type, - and that its getMovableType() method returns a proper type name. - */ - virtual void injectMovableObject(MovableObject* m); - /** Extract a previously injected MovableObject. - @remarks - Essentially this does the same as destroyMovableObject, but only - removes the instance from the internal lists, it does not attempt - to destroy it. - */ - virtual void extractMovableObject(const String& name, const String& typeName); - /** Extract a previously injected MovableObject. - @remarks - Essentially this does the same as destroyMovableObject, but only - removes the instance from the internal lists, it does not attempt - to destroy it. - */ - virtual void extractMovableObject(MovableObject* m); - /** Extract all injected MovableObjects of a given type. - @remarks - Essentially this does the same as destroyAllMovableObjectsByType, - but only removes the instances from the internal lists, it does not - attempt to destroy them. - */ - virtual void extractAllMovableObjectsByType(const String& typeName); - - /** Sets a mask which is bitwise 'and'ed with objects own visibility masks - to determine if the object is visible. - @remarks - Note that this is combined with any per-viewport visibility mask - through an 'and' operation. @see Viewport::setVisibilityMask - */ - virtual void setVisibilityMask(uint32 vmask) { mVisibilityMask = vmask; } - - /** Gets a mask which is bitwise 'and'ed with objects own visibility masks - to determine if the object is visible. - */ - virtual uint32 getVisibilityMask(void) { return mVisibilityMask; } - - /** Internal method for getting the combination between the global visibility - mask and the per-viewport visibility mask. - */ - uint32 _getCombinedVisibilityMask(void) const; - - /** Sets whether the SceneManager should search for visible objects, or + /** Destroys an InstanceManager if it was created with createInstanceManager() + @remarks + Be sure you don't have any InstancedEntity referenced somewhere which was created with + this manager, since it will become a dangling pointer. + @param name Name of the manager to remove + */ + virtual void destroyInstanceManager( const String &name ); + virtual void destroyInstanceManager( InstanceManager *instanceManager ); + + virtual void destroyAllInstanceManagers(void); + + /** @see InstanceManager::getMaxOrBestNumInstancesPerBatch + @remarks + If you've already created an InstanceManager, you can call it's + getMaxOrBestNumInstancesPerBatch() function directly. + Another (not recommended) way to know if the technique is unsupported is by creating + an InstanceManager and use createInstancedEntity, which will return null pointer. + The input parameter "numInstancesPerBatch" is a suggested value when using IM_VTFBESTFIT + flag (in that case it should be non-zero) + @return + The ideal (or maximum, depending on flags) number of instances per batch for + the given technique. Zero if technique is unsupported or errors were spotted + */ + virtual size_t getNumInstancesPerBatch( const String &meshName, const String &groupName, + const String &materialName, + InstanceManager::InstancingTechnique technique, + size_t numInstancesPerBatch, uint16 flags=0, + unsigned short subMeshIdx=0 ); + + /** Creates an InstancedEntity based on an existing InstanceManager (@see createInstanceManager) + @remarks + * Return value may be null if the InstanceManger technique isn't supported + * Try to keep the number of entities with different materials to a minimum + * For more information @see InstancedManager @see InstancedBatch, @see InstancedEntity + * Alternatively you can call InstancedManager::createInstanceEntity using the returned + pointer from createInstanceManager + @param materialName Material name + @param managerName Name of the instance manager + @return An InstancedEntity ready to be attached to a SceneNode + */ + virtual InstancedEntity* createInstancedEntity( const String &materialName, + const String &managerName ); + + /** Removes an InstancedEntity, @see SceneManager::createInstancedEntity & + @see InstanceBatch::removeInstancedEntity + @param instancedEntity Instance to remove + */ + virtual void destroyInstancedEntity( InstancedEntity *instancedEntity ); + + /** Called by an InstanceManager when it has at least one InstanceBatch that needs their bounds + to be updated for proper culling + @param dirtyManager The manager with dirty batches to update + */ + void _addDirtyInstanceManager( InstanceManager *dirtyManager ); + + /** Create a movable object of the type specified. + @remarks + This is the generalised form of MovableObject creation where you can + create a MovableObject of any specialised type generically, including + any new types registered using plugins. + @param name The name to give the object. Must be unique within type. + @param typeName The type of object to create + @param params Optional name/value pair list to give extra parameters to + the created object. + */ + virtual MovableObject* createMovableObject(const String& name, + const String& typeName, const NameValuePairList* params = 0); + /** Create a movable object of the type specified without a name. + @remarks + This is the generalised form of MovableObject creation where you can + create a MovableObject of any specialised type generically, including + any new types registered using plugins. The name is generated automatically. + @param typeName The type of object to create + @param params Optional name/value pair list to give extra parameters to + the created object. + */ + virtual MovableObject* createMovableObject(const String& typeName, const NameValuePairList* params = 0); + /** Destroys a MovableObject with the name specified, of the type specified. + @remarks + The MovableObject will automatically detach itself from any nodes + on destruction. + */ + virtual void destroyMovableObject(const String& name, const String& typeName); + /** Destroys a MovableObject. + @remarks + The MovableObject will automatically detach itself from any nodes + on destruction. + */ + virtual void destroyMovableObject(MovableObject* m); + /** Destroy all MovableObjects of a given type. */ + virtual void destroyAllMovableObjectsByType(const String& typeName); + /** Destroy all MovableObjects. */ + virtual void destroyAllMovableObjects(void); + /** Get a reference to a previously created MovableObject. + @note Throws an exception if the named instance does not exist + */ + virtual MovableObject* getMovableObject(const String& name, const String& typeName) const; + /** Returns whether a movable object instance with the given name exists. */ + virtual bool hasMovableObject(const String& name, const String& typeName) const; + typedef MapIterator MovableObjectIterator; + /** Get an iterator over all MovableObect instances of a given type. + @note + The iterator returned from this method is not thread safe, do not use this + if you are creating or deleting objects of this type in another thread. + */ + virtual MovableObjectIterator getMovableObjectIterator(const String& typeName); + /** Inject a MovableObject instance created externally. + @remarks + This method 'injects' a MovableObject instance created externally into + the MovableObject instance registry held in the SceneManager. You + might want to use this if you have a MovableObject which you don't + want to register a factory for; for example a MovableObject which + cannot be generally constructed by clients. + @note + It is important that the MovableObject has a unique name for the type, + and that its getMovableType() method returns a proper type name. + */ + virtual void injectMovableObject(MovableObject* m); + /** Extract a previously injected MovableObject. + @remarks + Essentially this does the same as destroyMovableObject, but only + removes the instance from the internal lists, it does not attempt + to destroy it. + */ + virtual void extractMovableObject(const String& name, const String& typeName); + /** Extract a previously injected MovableObject. + @remarks + Essentially this does the same as destroyMovableObject, but only + removes the instance from the internal lists, it does not attempt + to destroy it. + */ + virtual void extractMovableObject(MovableObject* m); + /** Extract all injected MovableObjects of a given type. + @remarks + Essentially this does the same as destroyAllMovableObjectsByType, + but only removes the instances from the internal lists, it does not + attempt to destroy them. + */ + virtual void extractAllMovableObjectsByType(const String& typeName); + + /** Sets a mask which is bitwise 'and'ed with objects own visibility masks + to determine if the object is visible. + @remarks + Note that this is combined with any per-viewport visibility mask + through an 'and' operation. @see Viewport::setVisibilityMask + */ + virtual void setVisibilityMask(uint32 vmask) { mVisibilityMask = vmask; } + + /** Gets a mask which is bitwise 'and'ed with objects own visibility masks + to determine if the object is visible. + */ + virtual uint32 getVisibilityMask(void) { return mVisibilityMask; } + + /** Internal method for getting the combination between the global visibility + mask and the per-viewport visibility mask. + */ + uint32 _getCombinedVisibilityMask(void) const; + + /** Sets whether the SceneManager should search for visible objects, or whether they are being manually handled. @remarks This is an advanced function, you should not use this unless you know what you are doing. - */ - virtual void setFindVisibleObjects(bool find) { mFindVisibleObjects = find; } + */ + virtual void setFindVisibleObjects(bool find) { mFindVisibleObjects = find; } - /** Gets whether the SceneManager should search for visible objects, or + /** Gets whether the SceneManager should search for visible objects, or whether they are being manually handled. - */ - virtual bool getFindVisibleObjects(void) { return mFindVisibleObjects; } - - /** Set whether to automatically normalise normals on objects whenever they - are scaled. - @remarks - Scaling can distort normals so the default behaviour is to compensate - for this, but it has a cost. If you would prefer to manually manage - this, set this option to 'false' and use Pass::setNormaliseNormals - only when needed. - */ - virtual void setNormaliseNormalsOnScale(bool n) { mNormaliseNormalsOnScale = n; } - - /** Get whether to automatically normalise normals on objects whenever they - are scaled. - */ - virtual bool getNormaliseNormalsOnScale() const { return mNormaliseNormalsOnScale; } - - /** Set whether to automatically flip the culling mode on objects whenever they - are negatively scaled. - @remarks - Negativelyl scaling an object has the effect of flipping the triangles, - so the culling mode should probably be inverted to deal with this. - If you would prefer to manually manage this, set this option to 'false' - and use different materials with Pass::setCullingMode set manually as needed. - */ - virtual void setFlipCullingOnNegativeScale(bool n) { mFlipCullingOnNegativeScale = n; } - - /** Get whether to automatically flip the culling mode on objects whenever they - are negatively scaled. - */ - virtual bool getFlipCullingOnNegativeScale() const { return mFlipCullingOnNegativeScale; } - - /** Render something as if it came from the current queue. - @param pass Material pass to use for setting up this quad. - @param rend Renderable to render - @param shadowDerivation Whether passes should be replaced with shadow caster / receiver passes - */ - virtual void _injectRenderWithPass(Pass *pass, Renderable *rend, bool shadowDerivation = true, - bool doLightIteration = false, const LightList* manualLightList = 0); - - /** Indicates to the SceneManager whether it should suppress changing - the RenderSystem states when rendering objects. - @remarks - This method allows you to tell the SceneManager not to change any - RenderSystem state until you tell it to. This method is only - intended for advanced use, don't use it if you're unsure of the - effect. The only RenderSystems calls made are to set the world - matrix for each object (note - view an projection matrices are NOT - SET - they are under your control) and to render the object; it is up to - the caller to do everything else, including enabling any vertex / - fragment programs and updating their parameter state, and binding - parameters to the RenderSystem. - @note - Calling this implicitly disables shadow processing since no shadows - can be rendered without changing state. - @param suppress If true, no RenderSystem state changes will be issued - until this method is called again with a parameter of false. - */ - virtual void _suppressRenderStateChanges(bool suppress); - - /** Are render state changes suppressed? - @see _suppressRenderStateChanges - */ - virtual bool _areRenderStateChangesSuppressed(void) const - { return mSuppressRenderStateChanges; } + */ + virtual bool getFindVisibleObjects(void) { return mFindVisibleObjects; } + + /** Set whether to automatically normalise normals on objects whenever they + are scaled. + @remarks + Scaling can distort normals so the default behaviour is to compensate + for this, but it has a cost. If you would prefer to manually manage + this, set this option to 'false' and use Pass::setNormaliseNormals + only when needed. + */ + virtual void setNormaliseNormalsOnScale(bool n) { mNormaliseNormalsOnScale = n; } + + /** Get whether to automatically normalise normals on objects whenever they + are scaled. + */ + virtual bool getNormaliseNormalsOnScale() const { return mNormaliseNormalsOnScale; } + + /** Set whether to automatically flip the culling mode on objects whenever they + are negatively scaled. + @remarks + Negativelyl scaling an object has the effect of flipping the triangles, + so the culling mode should probably be inverted to deal with this. + If you would prefer to manually manage this, set this option to 'false' + and use different materials with Pass::setCullingMode set manually as needed. + */ + virtual void setFlipCullingOnNegativeScale(bool n) { mFlipCullingOnNegativeScale = n; } + + /** Get whether to automatically flip the culling mode on objects whenever they + are negatively scaled. + */ + virtual bool getFlipCullingOnNegativeScale() const { return mFlipCullingOnNegativeScale; } + + /** Render something as if it came from the current queue. + @param pass Material pass to use for setting up this quad. + @param rend Renderable to render + @param shadowDerivation Whether passes should be replaced with shadow caster / receiver passes + */ + virtual void _injectRenderWithPass(Pass *pass, Renderable *rend, bool shadowDerivation = true, + bool doLightIteration = false, const LightList* manualLightList = 0); + + /** Indicates to the SceneManager whether it should suppress changing + the RenderSystem states when rendering objects. + @remarks + This method allows you to tell the SceneManager not to change any + RenderSystem state until you tell it to. This method is only + intended for advanced use, don't use it if you're unsure of the + effect. The only RenderSystems calls made are to set the world + matrix for each object (note - view an projection matrices are NOT + SET - they are under your control) and to render the object; it is up to + the caller to do everything else, including enabling any vertex / + fragment programs and updating their parameter state, and binding + parameters to the RenderSystem. + @note + Calling this implicitly disables shadow processing since no shadows + can be rendered without changing state. + @param suppress If true, no RenderSystem state changes will be issued + until this method is called again with a parameter of false. + */ + virtual void _suppressRenderStateChanges(bool suppress); + + /** Are render state changes suppressed? + @see _suppressRenderStateChanges + */ + virtual bool _areRenderStateChangesSuppressed(void) const + { return mSuppressRenderStateChanges; } /** Internal method for setting up the renderstate for a rendering pass. @param pass The Pass details to set. - @param evenIfSuppressed Sets the pass details even if render state - changes are suppressed; if you are using this to manually set state - when render state changes are suppressed, you should set this to - true. - @param shadowDerivation If false, disables the derivation of shadow - passes from original passes + @param evenIfSuppressed Sets the pass details even if render state + changes are suppressed; if you are using this to manually set state + when render state changes are suppressed, you should set this to + true. + @param shadowDerivation If false, disables the derivation of shadow + passes from original passes @return A Pass object that was used instead of the one passed in, can happen when rendering shadow passes */ virtual const Pass* _setPass(const Pass* pass, - bool evenIfSuppressed = false, bool shadowDerivation = true); - - /** Method to allow you to mark gpu parameters as dirty, causing them to - be updated according to the mask that you set when updateGpuProgramParameters is - next called. Only really useful if you're controlling parameter state in - inner rendering loop callbacks. - @param mask Some combination of GpuParamVariability which is bitwise OR'ed with the - current dirty state. - */ - virtual void _markGpuParamsDirty(uint16 mask); - - - /** Indicates to the SceneManager whether it should suppress the - active shadow rendering technique until told otherwise. - @remarks - This is a temporary alternative to setShadowTechnique to suppress - the rendering of shadows and forcing all processing down the - standard rendering path. This is intended for internal use only. - @param suppress If true, no shadow rendering will occur until this - method is called again with a parameter of false. - */ - virtual void _suppressShadows(bool suppress); - - /** Are shadows suppressed? - @see _suppressShadows - */ - virtual bool _areShadowsSuppressed(void) const - { return mSuppressShadows; } - - /** Render the objects in a given queue group - @remarks You should only call this from a RenderQueueInvocation implementation - */ - virtual void _renderQueueGroupObjects(RenderQueueGroup* group, - QueuedRenderableCollection::OrganisationMode om); - - /** Advanced method for supplying an alternative visitor, used for parsing the - render queues and sending the results to the renderer. - @remarks - You can use this method to insert your own implementation of the - QueuedRenderableVisitor interface, which receives calls as the queued - renderables are parsed in a given order (determined by RenderQueueInvocationSequence) - and are sent to the renderer. If you provide your own implementation of - this visitor, you are responsible for either calling the rendersystem, - or passing the calls on to the base class implementation. - @note - Ownership is not taken of this pointer, you are still required to - delete it yourself once you're finished. - @param visitor Your implementation of SceneMgrQueuedRenderableVisitor. - If you pass 0, the default implementation will be used. - */ - void setQueuedRenderableVisitor(SceneMgrQueuedRenderableVisitor* visitor); - - /** Gets the current visitor object which processes queued renderables. */ - SceneMgrQueuedRenderableVisitor* getQueuedRenderableVisitor(void) const; - - - /** Get the rendersystem subclass to which the output of this Scene Manager - gets sent - */ - RenderSystem *getDestinationRenderSystem(); - - /** Gets the current viewport being rendered (advanced use only, only - valid during viewport update. */ - Viewport* getCurrentViewport(void) const { return mCurrentViewport; } - - /** Returns a visibility boundary box for a specific camera. */ - const VisibleObjectsBoundsInfo& getVisibleObjectsBoundsInfo(const Camera* cam) const; - - /** Returns the shadow caster AAB for a specific light-camera combination */ - const VisibleObjectsBoundsInfo& getShadowCasterBoundsInfo(const Light* light, size_t iteration = 0) const; - - /** Set whether to use camera-relative co-ordinates when rendering, ie - to always place the camera at the origin and move the world around it. - @remarks - This is a technique to alleviate some of the precision issues associated with - rendering far from the origin, where single-precision floats as used in most - GPUs begin to lose their precision. Instead of including the camera - translation in the view matrix, it only includes the rotation, and - the world matrices of objects must be expressed relative to this. - @note - If you need this option, you will probably also need to enable double-precision - mode in Ogre (OGRE_DOUBLE_PRECISION), since even though this will - alleviate the rendering precision, the source camera and object positions will still - suffer from precision issues leading to jerky movement. - */ - virtual void setCameraRelativeRendering(bool rel) { mCameraRelativeRendering = rel; } - - /** Get whether to use camera-relative co-ordinates when rendering, ie - to always place the camera at the origin and move the world around it. - */ - virtual bool getCameraRelativeRendering() const { return mCameraRelativeRendering; } + bool evenIfSuppressed = false, bool shadowDerivation = true); + + /** Method to allow you to mark gpu parameters as dirty, causing them to + be updated according to the mask that you set when updateGpuProgramParameters is + next called. Only really useful if you're controlling parameter state in + inner rendering loop callbacks. + @param mask Some combination of GpuParamVariability which is bitwise OR'ed with the + current dirty state. + */ + virtual void _markGpuParamsDirty(uint16 mask); + + + /** Indicates to the SceneManager whether it should suppress the + active shadow rendering technique until told otherwise. + @remarks + This is a temporary alternative to setShadowTechnique to suppress + the rendering of shadows and forcing all processing down the + standard rendering path. This is intended for internal use only. + @param suppress If true, no shadow rendering will occur until this + method is called again with a parameter of false. + */ + virtual void _suppressShadows(bool suppress); + + /** Are shadows suppressed? + @see _suppressShadows + */ + virtual bool _areShadowsSuppressed(void) const + { return mSuppressShadows; } + + /** Render the objects in a given queue group + @remarks You should only call this from a RenderQueueInvocation implementation + */ + virtual void _renderQueueGroupObjects(RenderQueueGroup* group, + QueuedRenderableCollection::OrganisationMode om); + + /** Advanced method for supplying an alternative visitor, used for parsing the + render queues and sending the results to the renderer. + @remarks + You can use this method to insert your own implementation of the + QueuedRenderableVisitor interface, which receives calls as the queued + renderables are parsed in a given order (determined by RenderQueueInvocationSequence) + and are sent to the renderer. If you provide your own implementation of + this visitor, you are responsible for either calling the rendersystem, + or passing the calls on to the base class implementation. + @note + Ownership is not taken of this pointer, you are still required to + delete it yourself once you're finished. + @param visitor Your implementation of SceneMgrQueuedRenderableVisitor. + If you pass 0, the default implementation will be used. + */ + void setQueuedRenderableVisitor(SceneMgrQueuedRenderableVisitor* visitor); + + /** Gets the current visitor object which processes queued renderables. */ + SceneMgrQueuedRenderableVisitor* getQueuedRenderableVisitor(void) const; + + + /** Get the rendersystem subclass to which the output of this Scene Manager + gets sent + */ + RenderSystem *getDestinationRenderSystem(); + + /** Gets the current viewport being rendered (advanced use only, only + valid during viewport update. */ + Viewport* getCurrentViewport(void) const { return mCurrentViewport; } + + /** Returns a visibility boundary box for a specific camera. */ + const VisibleObjectsBoundsInfo& getVisibleObjectsBoundsInfo(const Camera* cam) const; + + /** Returns the shadow caster AAB for a specific light-camera combination */ + const VisibleObjectsBoundsInfo& getShadowCasterBoundsInfo(const Light* light, size_t iteration = 0) const; + + /** Set whether to use camera-relative co-ordinates when rendering, ie + to always place the camera at the origin and move the world around it. + @remarks + This is a technique to alleviate some of the precision issues associated with + rendering far from the origin, where single-precision floats as used in most + GPUs begin to lose their precision. Instead of including the camera + translation in the view matrix, it only includes the rotation, and + the world matrices of objects must be expressed relative to this. + @note + If you need this option, you will probably also need to enable double-precision + mode in Ogre (OGRE_DOUBLE_PRECISION), since even though this will + alleviate the rendering precision, the source camera and object positions will still + suffer from precision issues leading to jerky movement. + */ + virtual void setCameraRelativeRendering(bool rel) { mCameraRelativeRendering = rel; } + + /** Get whether to use camera-relative co-ordinates when rendering, ie + to always place the camera at the origin and move the world around it. + */ + virtual bool getCameraRelativeRendering() const { return mCameraRelativeRendering; } /** Add a level of detail listener. */ @@ -3545,7 +3545,7 @@ namespace Ogre { /** Handle LOD events. */ void _handleLodEvents(); - IlluminationRenderStage _getCurrentRenderStage() {return mIlluminationStage;} + IlluminationRenderStage _getCurrentRenderStage() {return mIlluminationStage;} }; /** Default implementation of IntersectionSceneQuery. */ @@ -3561,7 +3561,7 @@ namespace Ogre { }; /** Default implementation of RaySceneQuery. */ - class _OgreExport DefaultRaySceneQuery : public RaySceneQuery + class _OgreExport DefaultRaySceneQuery : public RaySceneQuery { public: DefaultRaySceneQuery(SceneManager* creator); @@ -3571,7 +3571,7 @@ namespace Ogre { void execute(RaySceneQueryListener* listener); }; /** Default implementation of SphereSceneQuery. */ - class _OgreExport DefaultSphereSceneQuery : public SphereSceneQuery + class _OgreExport DefaultSphereSceneQuery : public SphereSceneQuery { public: DefaultSphereSceneQuery(SceneManager* creator); @@ -3591,7 +3591,7 @@ namespace Ogre { void execute(SceneQueryListener* listener); }; /** Default implementation of AxisAlignedBoxSceneQuery. */ - class _OgreExport DefaultAxisAlignedBoxSceneQuery : public AxisAlignedBoxSceneQuery + class _OgreExport DefaultAxisAlignedBoxSceneQuery : public AxisAlignedBoxSceneQuery { public: DefaultAxisAlignedBoxSceneQuery(SceneManager* creator); @@ -3602,69 +3602,69 @@ namespace Ogre { }; - /// Bitmask containing scene types - typedef uint16 SceneTypeMask; - - /** Classification of a scene to allow a decision of what type of - SceenManager to provide back to the application. - */ - enum SceneType - { - ST_GENERIC = 1, - ST_EXTERIOR_CLOSE = 2, - ST_EXTERIOR_FAR = 4, - ST_EXTERIOR_REAL_FAR = 8, - ST_INTERIOR = 16 - }; - - /** Structure containing information about a scene manager. */ - struct SceneManagerMetaData - { - /// A globally unique string identifying the scene manager type - String typeName; - /// A text description of the scene manager - String description; - /// A mask describing which sorts of scenes this manager can handle - SceneTypeMask sceneTypeMask; - /// Flag indicating whether world geometry is supported - bool worldGeometrySupported; - }; - - - - /** Class which will create instances of a given SceneManager. */ - class _OgreExport SceneManagerFactory : public SceneMgtAlloc - { - protected: - mutable SceneManagerMetaData mMetaData; - mutable bool mMetaDataInit; - /// Internal method to initialise the metadata, must be implemented - virtual void initMetaData(void) const = 0; - public: - SceneManagerFactory() : mMetaDataInit(true) {} - virtual ~SceneManagerFactory() {} - /** Get information about the SceneManager type created by this factory. */ - virtual const SceneManagerMetaData& getMetaData(void) const - { - if (mMetaDataInit) - { - initMetaData(); - mMetaDataInit = false; - } - return mMetaData; - } - /** Create a new instance of a SceneManager. - @remarks - Don't call directly, use SceneManagerEnumerator::createSceneManager. - */ - virtual SceneManager* createInstance(const String& instanceName) = 0; - /** Destroy an instance of a SceneManager. */ - virtual void destroyInstance(SceneManager* instance) = 0; - - }; - - /** @} */ - /** @} */ + /// Bitmask containing scene types + typedef uint16 SceneTypeMask; + + /** Classification of a scene to allow a decision of what type of + SceenManager to provide back to the application. + */ + enum SceneType + { + ST_GENERIC = 1, + ST_EXTERIOR_CLOSE = 2, + ST_EXTERIOR_FAR = 4, + ST_EXTERIOR_REAL_FAR = 8, + ST_INTERIOR = 16 + }; + + /** Structure containing information about a scene manager. */ + struct SceneManagerMetaData + { + /// A globally unique string identifying the scene manager type + String typeName; + /// A text description of the scene manager + String description; + /// A mask describing which sorts of scenes this manager can handle + SceneTypeMask sceneTypeMask; + /// Flag indicating whether world geometry is supported + bool worldGeometrySupported; + }; + + + + /** Class which will create instances of a given SceneManager. */ + class _OgreExport SceneManagerFactory : public SceneMgtAlloc + { + protected: + mutable SceneManagerMetaData mMetaData; + mutable bool mMetaDataInit; + /// Internal method to initialise the metadata, must be implemented + virtual void initMetaData(void) const = 0; + public: + SceneManagerFactory() : mMetaDataInit(true) {} + virtual ~SceneManagerFactory() {} + /** Get information about the SceneManager type created by this factory. */ + virtual const SceneManagerMetaData& getMetaData(void) const + { + if (mMetaDataInit) + { + initMetaData(); + mMetaDataInit = false; + } + return mMetaData; + } + /** Create a new instance of a SceneManager. + @remarks + Don't call directly, use SceneManagerEnumerator::createSceneManager. + */ + virtual SceneManager* createInstance(const String& instanceName) = 0; + /** Destroy an instance of a SceneManager. */ + virtual void destroyInstance(SceneManager* instance) = 0; + + }; + + /** @} */ + /** @} */ } // Namespace diff --git a/OgreMain/include/OgreSceneManagerEnumerator.h b/OgreMain/include/OgreSceneManagerEnumerator.h index 6824cd7fb23..a2c41eb34a9 100644 --- a/OgreMain/include/OgreSceneManagerEnumerator.h +++ b/OgreMain/include/OgreSceneManagerEnumerator.h @@ -36,33 +36,33 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /// Factory for default scene manager - class _OgreExport DefaultSceneManagerFactory : public SceneManagerFactory - { - protected: - void initMetaData(void) const; - public: - DefaultSceneManagerFactory() {} - ~DefaultSceneManagerFactory() {} - /// Factory type name - static const String FACTORY_TYPE_NAME; - SceneManager* createInstance(const String& instanceName); - void destroyInstance(SceneManager* instance); - }; - /// Default scene manager - class _OgreExport DefaultSceneManager : public SceneManager - { - public: - DefaultSceneManager(const String& name); - ~DefaultSceneManager(); - const String& getTypeName(void) const; - }; + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /// Factory for default scene manager + class _OgreExport DefaultSceneManagerFactory : public SceneManagerFactory + { + protected: + void initMetaData(void) const; + public: + DefaultSceneManagerFactory() {} + ~DefaultSceneManagerFactory() {} + /// Factory type name + static const String FACTORY_TYPE_NAME; + SceneManager* createInstance(const String& instanceName); + void destroyInstance(SceneManager* instance); + }; + /// Default scene manager + class _OgreExport DefaultSceneManager : public SceneManager + { + public: + DefaultSceneManager(const String& name); + ~DefaultSceneManager(); + const String& getTypeName(void) const; + }; /** Enumerates the SceneManager classes available to applications. @remarks @@ -75,114 +75,114 @@ namespace Ogre { In order to give applications easy access to these implementations, this class has a number of methods to create or retrieve a SceneManager which is appropriate to the scene type. - @par - SceneManagers are created by SceneManagerFactory instances. New factories - for new types of SceneManager can be registered with this class to make - them available to clients. - @par - Note that you can still plug in your own custom SceneManager without - using a factory, should you choose, it's just not as flexible that way. - Just instantiate your own SceneManager manually and use it directly. + @par + SceneManagers are created by SceneManagerFactory instances. New factories + for new types of SceneManager can be registered with this class to make + them available to clients. + @par + Note that you can still plug in your own custom SceneManager without + using a factory, should you choose, it's just not as flexible that way. + Just instantiate your own SceneManager manually and use it directly. */ class _OgreExport SceneManagerEnumerator : public Singleton, public SceneMgtAlloc { - public: - /// Scene manager instances, indexed by instance name - typedef map::type Instances; - /// List of available scene manager types as meta data - typedef vector::type MetaDataList; + public: + /// Scene manager instances, indexed by instance name + typedef map::type Instances; + /// List of available scene manager types as meta data + typedef vector::type MetaDataList; private: - /// Scene manager factories - typedef list::type Factories; - Factories mFactories; - Instances mInstances; - /// Stored separately to allow iteration - MetaDataList mMetaDataList; - /// Factory for default scene manager - DefaultSceneManagerFactory mDefaultFactory; - /// Count of creations for auto-naming - unsigned long mInstanceCreateCount; - /// Currently assigned render system - RenderSystem* mCurrentRenderSystem; + /// Scene manager factories + typedef list::type Factories; + Factories mFactories; + Instances mInstances; + /// Stored separately to allow iteration + MetaDataList mMetaDataList; + /// Factory for default scene manager + DefaultSceneManagerFactory mDefaultFactory; + /// Count of creations for auto-naming + unsigned long mInstanceCreateCount; + /// Currently assigned render system + RenderSystem* mCurrentRenderSystem; public: SceneManagerEnumerator(); ~SceneManagerEnumerator(); - /** Register a new SceneManagerFactory. - @remarks - Plugins should call this to register as new SceneManager providers. - */ - void addFactory(SceneManagerFactory* fact); - - /** Remove a SceneManagerFactory. - */ - void removeFactory(SceneManagerFactory* fact); - - /** Get more information about a given type of SceneManager. - @remarks - The metadata returned tells you a few things about a given type - of SceneManager, which can be created using a factory that has been - registered already. - @param typeName The type name of the SceneManager you want to enquire on. - If you don't know the typeName already, you can iterate over the - metadata for all types using getMetaDataIterator. - */ - const SceneManagerMetaData* getMetaData(const String& typeName) const; - - typedef ConstVectorIterator MetaDataIterator; - /** Iterate over all types of SceneManager available for construction, - providing some information about each one. - */ - MetaDataIterator getMetaDataIterator(void) const; - - /** Create a SceneManager instance of a given type. - @remarks - You can use this method to create a SceneManager instance of a - given specific type. You may know this type already, or you may - have discovered it by looking at the results from getMetaDataIterator. - @note - This method throws an exception if the named type is not found. - @param typeName String identifying a unique SceneManager type - @param instanceName Optional name to given the new instance that is - created. If you leave this blank, an auto name will be assigned. - */ - SceneManager* createSceneManager(const String& typeName, - const String& instanceName = BLANKSTRING); - - /** Create a SceneManager instance based on scene type support. - @remarks - Creates an instance of a SceneManager which supports the scene types - identified in the parameter. If more than one type of SceneManager - has been registered as handling that combination of scene types, - in instance of the last one registered is returned. - @note This method always succeeds, if a specific scene manager is not - found, the default implementation is always returned. - @param typeMask A mask containing one or more SceneType flags - @param instanceName Optional name to given the new instance that is - created. If you leave this blank, an auto name will be assigned. - */ - SceneManager* createSceneManager(SceneTypeMask typeMask, - const String& instanceName = BLANKSTRING); - - /** Destroy an instance of a SceneManager. */ - void destroySceneManager(SceneManager* sm); - - /** Get an existing SceneManager instance that has already been created, - identified by the instance name. - @param instanceName The name of the instance to retrieve. - */ - SceneManager* getSceneManager(const String& instanceName) const; - - /** Identify if a SceneManager instance already exists. - @param instanceName The name of the instance to retrieve. - */ - bool hasSceneManager(const String& instanceName) const; - - typedef MapIterator SceneManagerIterator; - /** Get an iterator over all the existing SceneManager instances. */ - SceneManagerIterator getSceneManagerIterator(void); + /** Register a new SceneManagerFactory. + @remarks + Plugins should call this to register as new SceneManager providers. + */ + void addFactory(SceneManagerFactory* fact); + + /** Remove a SceneManagerFactory. + */ + void removeFactory(SceneManagerFactory* fact); + + /** Get more information about a given type of SceneManager. + @remarks + The metadata returned tells you a few things about a given type + of SceneManager, which can be created using a factory that has been + registered already. + @param typeName The type name of the SceneManager you want to enquire on. + If you don't know the typeName already, you can iterate over the + metadata for all types using getMetaDataIterator. + */ + const SceneManagerMetaData* getMetaData(const String& typeName) const; + + typedef ConstVectorIterator MetaDataIterator; + /** Iterate over all types of SceneManager available for construction, + providing some information about each one. + */ + MetaDataIterator getMetaDataIterator(void) const; + + /** Create a SceneManager instance of a given type. + @remarks + You can use this method to create a SceneManager instance of a + given specific type. You may know this type already, or you may + have discovered it by looking at the results from getMetaDataIterator. + @note + This method throws an exception if the named type is not found. + @param typeName String identifying a unique SceneManager type + @param instanceName Optional name to given the new instance that is + created. If you leave this blank, an auto name will be assigned. + */ + SceneManager* createSceneManager(const String& typeName, + const String& instanceName = BLANKSTRING); + + /** Create a SceneManager instance based on scene type support. + @remarks + Creates an instance of a SceneManager which supports the scene types + identified in the parameter. If more than one type of SceneManager + has been registered as handling that combination of scene types, + in instance of the last one registered is returned. + @note This method always succeeds, if a specific scene manager is not + found, the default implementation is always returned. + @param typeMask A mask containing one or more SceneType flags + @param instanceName Optional name to given the new instance that is + created. If you leave this blank, an auto name will be assigned. + */ + SceneManager* createSceneManager(SceneTypeMask typeMask, + const String& instanceName = BLANKSTRING); + + /** Destroy an instance of a SceneManager. */ + void destroySceneManager(SceneManager* sm); + + /** Get an existing SceneManager instance that has already been created, + identified by the instance name. + @param instanceName The name of the instance to retrieve. + */ + SceneManager* getSceneManager(const String& instanceName) const; + + /** Identify if a SceneManager instance already exists. + @param instanceName The name of the instance to retrieve. + */ + bool hasSceneManager(const String& instanceName) const; + + typedef MapIterator SceneManagerIterator; + /** Get an iterator over all the existing SceneManager instances. */ + SceneManagerIterator getSceneManagerIterator(void); /** Notifies all SceneManagers of the destination rendering system. */ @@ -225,8 +225,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreSceneNode.h b/OgreMain/include/OgreSceneNode.h index a9cb415ddfa..e12c9c1ba14 100644 --- a/OgreMain/include/OgreSceneNode.h +++ b/OgreMain/include/OgreSceneNode.h @@ -36,16 +36,16 @@ THE SOFTWARE. namespace Ogre { - // forward decl - struct VisibleObjectsBoundsInfo; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Class representing a node in the scene graph. + // forward decl + struct VisibleObjectsBoundsInfo; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Class representing a node in the scene graph. @remarks A SceneNode is a type of Node which is used to organise objects in a scene. It has the same hierarchical transformation properties of the generic Node class, @@ -59,15 +59,15 @@ namespace Ogre { public: typedef HashMap ObjectMap; typedef MapIterator ObjectIterator; - typedef ConstMapIterator ConstObjectIterator; + typedef ConstMapIterator ConstObjectIterator; protected: ObjectMap mObjectsByName; - /// Pointer to a Wire Bounding Box for this Node - WireBoundingBox *mWireBoundingBox; - /// Flag that determines if the bounding box of the node should be displayed - bool mShowBoundingBox; + /// Pointer to a Wire Bounding Box for this Node + WireBoundingBox *mWireBoundingBox; + /// Flag that determines if the bounding box of the node should be displayed + bool mShowBoundingBox; bool mHideBoundingBox; /// SceneManager which created this node @@ -85,13 +85,13 @@ namespace Ogre { /** See Node. */ Node* createChildImpl(const String& name); - /** See Node */ - void setParent(Node* parent); + /** See Node */ + void setParent(Node* parent); - /** Internal method for setting whether the node is in the scene - graph. - */ - virtual void setInSceneGraph(bool inGraph); + /** Internal method for setting whether the node is in the scene + graph. + */ + virtual void setInSceneGraph(bool inGraph); /// Whether to yaw around a fixed axis. bool mYawFixed; @@ -104,8 +104,8 @@ namespace Ogre { Vector3 mAutoTrackOffset; /// Local 'normal' direction vector Vector3 mAutoTrackLocalDirection; - /// Is this node a current part of the scene graph? - bool mIsInSceneGraph; + /// Is this node a current part of the scene graph? + bool mIsInSceneGraph; public: /** Constructor, only to be called by the creator SceneManager. @remarks @@ -157,17 +157,17 @@ namespace Ogre { */ virtual void detachAllObjects(void); - /** Determines whether this node is in the scene graph, i.e. - whether it's ultimate ancestor is the root scene node. - */ - virtual bool isInSceneGraph(void) const { return mIsInSceneGraph; } + /** Determines whether this node is in the scene graph, i.e. + whether it's ultimate ancestor is the root scene node. + */ + virtual bool isInSceneGraph(void) const { return mIsInSceneGraph; } - /** Notifies this SceneNode that it is the root scene node. - @remarks - Only SceneManager should call this! - */ - virtual void _notifyRootNode(void) { mIsInSceneGraph = true; } - + /** Notifies this SceneNode that it is the root scene node. + @remarks + Only SceneManager should call this! + */ + virtual void _notifyRootNode(void) { mIsInSceneGraph = true; } + /** Internal method to update the Node. @note @@ -183,9 +183,9 @@ namespace Ogre { */ virtual void _update(bool updateChildren, bool parentHasChanged); - /** Tells the SceneNode to update the world bound info it stores. - */ - virtual void _updateBounds(void); + /** Tells the SceneNode to update the world bound info it stores. + */ + virtual void _updateBounds(void); /** Internal method which locates any visible objects attached to this node and adds them to the passed in queue. @remarks @@ -197,16 +197,16 @@ namespace Ogre { cam The active camera @param queue The SceneManager's rendering queue - @param - visibleBounds bounding information created on the fly containing all visible objects by the camera + @param + visibleBounds bounding information created on the fly containing all visible objects by the camera @param includeChildren If true, the call is cascaded down to all child nodes automatically. @param displayNodes If true, the nodes themselves are rendered as a set of 3 axes as well as the objects being rendered. For debugging purposes. */ - virtual void _findVisibleObjects(Camera* cam, RenderQueue* queue, - VisibleObjectsBoundsInfo* visibleBounds, + virtual void _findVisibleObjects(Camera* cam, RenderQueue* queue, + VisibleObjectsBoundsInfo* visibleBounds, bool includeChildren = true, bool displayNodes = false, bool onlyShadowCasters = false); /** Gets the axis-aligned bounding box of this node (and hence all subnodes). @@ -237,7 +237,7 @@ namespace Ogre { until the end, or retrieve a new iterator after making the change. Making changes to the object returned through the iterator is OK though. */ - virtual ConstObjectIterator getAttachedObjectIterator(void) const; + virtual ConstObjectIterator getAttachedObjectIterator(void) const; /** Gets the creator of this scene node. @remarks @@ -282,27 +282,27 @@ namespace Ogre { @remarks Use this to show or hide the bounding box of the node. */ - virtual void showBoundingBox(bool bShow); + virtual void showBoundingBox(bool bShow); /** Allows the overriding of the node's bounding box over the SceneManager's bounding box setting. @remarks Use this to override the bounding box setting of the node. */ - virtual void hideBoundingBox(bool bHide); + virtual void hideBoundingBox(bool bHide); /** Add the bounding box to the rendering queue. */ - virtual void _addBoundingBoxToQueue(RenderQueue* queue); + virtual void _addBoundingBoxToQueue(RenderQueue* queue); /** This allows scene managers to determine if the node's bounding box - should be added to the rendering queue. + should be added to the rendering queue. @remarks Scene Managers that implement their own _findVisibleObjects will have to - check this flag and then use _addBoundingBoxToQueue to add the bounding box - wireframe. + check this flag and then use _addBoundingBoxToQueue to add the bounding box + wireframe. */ - virtual bool getShowBoundingBox() const; + virtual bool getShowBoundingBox() const; /** Creates an unnamed new SceneNode as a child of this node. @param @@ -339,7 +339,7 @@ namespace Ogre { cleared by this method before population. @param radius Parameter to specify lights intersecting a given radius of this SceneNode's centre. - @param lightMask The mask with which to include / exclude lights + @param lightMask The mask with which to include / exclude lights */ virtual void findLights(LightList& destList, Real radius, uint32 lightMask = 0xFFFFFFFF) const; @@ -359,9 +359,9 @@ namespace Ogre { */ virtual void setFixedYawAxis( bool useFixed, const Vector3& fixedAxis = Vector3::UNIT_Y ); - /** Rotate the node around the Y-axis. - */ - virtual void yaw(const Radian& angle, TransformSpace relativeTo = TS_LOCAL); + /** Rotate the node around the Y-axis. + */ + virtual void yaw(const Radian& angle, TransformSpace relativeTo = TS_LOCAL); /** Sets the node's direction vector ie it's local -z. @remarks Note that the 'up' vector for the orientation will automatically be @@ -417,13 +417,13 @@ namespace Ogre { virtual void setAutoTracking(bool enabled, SceneNode* const target = 0, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z, const Vector3& offset = Vector3::ZERO); - /** Get the auto tracking target for this node, if any. */ + /** Get the auto tracking target for this node, if any. */ virtual SceneNode* getAutoTrackTarget(void) { return mAutoTrackTarget; } - /** Get the auto tracking offset for this node, if the node is auto tracking. */ - virtual const Vector3& getAutoTrackOffset(void) { return mAutoTrackOffset; } - /** Get the auto tracking local direction for this node, if it is auto tracking. */ - virtual const Vector3& getAutoTrackLocalDirection(void) { return mAutoTrackLocalDirection; } - /** Internal method used by OGRE to update auto-tracking cameras. */ + /** Get the auto tracking offset for this node, if the node is auto tracking. */ + virtual const Vector3& getAutoTrackOffset(void) { return mAutoTrackOffset; } + /** Get the auto tracking local direction for this node, if it is auto tracking. */ + virtual const Vector3& getAutoTrackLocalDirection(void) { return mAutoTrackLocalDirection; } + /** Internal method used by OGRE to update auto-tracking cameras. */ void _autoTrack(void); /** Gets the parent of this SceneNode. */ SceneNode* getParentSceneNode(void) const; @@ -446,7 +446,7 @@ namespace Ogre { virtual void flipVisibility(bool cascade = true); /** Tells all objects attached to this node whether to display their - debug information or not. + debug information or not. @remarks This is a shortcut to calling setDebugDisplayEnabled() on the objects attached to this node, and optionally to all objects attached to child @@ -456,15 +456,15 @@ namespace Ogre { */ virtual void setDebugDisplayEnabled(bool enabled, bool cascade = true); - /// As Node::getDebugRenderable, except scaling is automatically determined - virtual DebugRenderable* getDebugRenderable(); + /// As Node::getDebugRenderable, except scaling is automatically determined + virtual DebugRenderable* getDebugRenderable(); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ }// namespace diff --git a/OgreMain/include/OgreSceneQuery.h b/OgreMain/include/OgreSceneQuery.h index 763ad75c9a0..ffbb9c4704e 100644 --- a/OgreMain/include/OgreSceneQuery.h +++ b/OgreMain/include/OgreSceneQuery.h @@ -34,13 +34,13 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** A class for performing queries on a scene. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** A class for performing queries on a scene. @remarks This is an abstract class for performing a query on a scene, i.e. to retrieve a list of objects and/or world geometry sections which are potentially intersecting a @@ -65,7 +65,7 @@ namespace Ogre { using the SceneManager interfaces for the type of query required, e.g. SceneManager::createSphereSceneQuery. */ - class _OgreExport SceneQuery : public SceneMgtAlloc + class _OgreExport SceneQuery : public SceneMgtAlloc { public: /** This type can be used by collaborating applications & SceneManagers to @@ -116,7 +116,7 @@ namespace Ogre { protected: SceneManager* mParentSceneMgr; uint32 mQueryMask; - uint32 mQueryTypeMask; + uint32 mQueryTypeMask; set::type mSupportedWorldFragments; WorldFragmentType mWorldFragmentType; @@ -142,15 +142,15 @@ namespace Ogre { @remarks This method allows you to set a 'type mask' to limit the results of this query to certain types of objects. Whilst setQueryMask deals with flags - set per instance of object, this method deals with setting a mask on - flags set per type of object. Both may exclude an object from query - results. + set per instance of object, this method deals with setting a mask on + flags set per type of object. Both may exclude an object from query + results. */ virtual void setQueryTypeMask(uint32 mask); /** Returns the current mask for this query. */ virtual uint32 getQueryTypeMask(void) const; - /** Tells the query what kind of world geometry to return from queries; + /** Tells the query what kind of world geometry to return from queries; often the full renderable geometry is not what is needed. @remarks The application receiving the world geometry is expected to know @@ -200,12 +200,12 @@ namespace Ogre { typedef list::type SceneQueryResultMovableList; typedef list::type SceneQueryResultWorldFragmentList; /** Holds the results of a scene query. */ - struct _OgreExport SceneQueryResult : public SceneMgtAlloc + struct _OgreExport SceneQueryResult : public SceneMgtAlloc { /// List of movable objects in the query (entities, particle systems etc) SceneQueryResultMovableList movables; /// List of world fragments - SceneQueryResultWorldFragmentList worldFragments; + SceneQueryResultWorldFragmentList worldFragments; }; /** Abstract class defining a query which returns single results from a region. @@ -484,7 +484,7 @@ namespace Ogre { typedef list::type SceneQueryMovableIntersectionList; typedef list::type SceneQueryMovableWorldFragmentIntersectionList; /** Holds the results of an intersection scene query (pair values). */ - struct _OgreExport IntersectionSceneQueryResult : public SceneMgtAlloc + struct _OgreExport IntersectionSceneQueryResult : public SceneMgtAlloc { /// List of movable / movable intersections (entities, particle systems etc) SceneQueryMovableIntersectionList movables2movables; @@ -549,8 +549,8 @@ namespace Ogre { bool queryResult(MovableObject* movable, SceneQuery::WorldFragment* fragment); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreScriptCompiler.h b/OgreMain/include/OgreScriptCompiler.h index da23753d72f..b5b99a127c9 100644 --- a/OgreMain/include/OgreScriptCompiler.h +++ b/OgreMain/include/OgreScriptCompiler.h @@ -39,395 +39,395 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** These enums hold the types of the concrete parsed nodes */ - enum ConcreteNodeType - { - CNT_VARIABLE, - CNT_VARIABLE_ASSIGN, - CNT_WORD, - CNT_IMPORT, - CNT_QUOTE, - CNT_LBRACE, - CNT_RBRACE, - CNT_COLON - }; - - /** The ConcreteNode is the struct that holds an un-conditioned sub-tree of parsed input */ - struct ConcreteNode; - typedef SharedPtr ConcreteNodePtr; - typedef list::type ConcreteNodeList; - typedef SharedPtr ConcreteNodeListPtr; - struct ConcreteNode : public ScriptCompilerAlloc - { - String token, file; - unsigned int line; - ConcreteNodeType type; - ConcreteNodeList children; - ConcreteNode *parent; - }; - - /** This enum holds the types of the possible abstract nodes */ - enum AbstractNodeType - { - ANT_UNKNOWN, - ANT_ATOM, - ANT_OBJECT, - ANT_PROPERTY, - ANT_IMPORT, - ANT_VARIABLE_SET, - ANT_VARIABLE_ACCESS - }; - class AbstractNode; - typedef SharedPtr AbstractNodePtr; - typedef list::type AbstractNodeList; - typedef SharedPtr AbstractNodeListPtr; - - class _OgreExport AbstractNode : public AbstractNodeAlloc - { - public: - String file; - unsigned int line; - AbstractNodeType type; - AbstractNode *parent; - Any context; // A holder for translation context data - public: - AbstractNode(AbstractNode *ptr); - virtual ~AbstractNode(){} - /// Returns a new AbstractNode which is a replica of this one. - virtual AbstractNode *clone() const = 0; - /// Returns a string value depending on the type of the AbstractNode. - virtual String getValue() const = 0; - }; - - /** This is an abstract node which cannot be broken down further */ - class _OgreExport AtomAbstractNode : public AbstractNode - { - public: - String value; - uint32 id; - public: - AtomAbstractNode(AbstractNode *ptr); - AbstractNode *clone() const; - String getValue() const; - private: - void parseNumber() const; - }; - - /** This specific abstract node represents a script object */ - class _OgreExport ObjectAbstractNode : public AbstractNode - { - private: - map::type mEnv; - public: - String name, cls; - vector::type bases; - uint32 id; - bool abstract; - AbstractNodeList children; - AbstractNodeList values; - AbstractNodeList overrides; // For use when processing object inheritance and overriding - public: - ObjectAbstractNode(AbstractNode *ptr); - AbstractNode *clone() const; - String getValue() const; - - void addVariable(const String &name); - void setVariable(const String &name, const String &value); - std::pair getVariable(const String &name) const; - const map::type &getVariables() const; - }; - - /** This abstract node represents a script property */ - class _OgreExport PropertyAbstractNode : public AbstractNode - { - public: - String name; - uint32 id; - AbstractNodeList values; - public: - PropertyAbstractNode(AbstractNode *ptr); - AbstractNode *clone() const; - String getValue() const; - }; - - /** This abstract node represents an import statement */ - class _OgreExport ImportAbstractNode : public AbstractNode - { - public: - String target, source; - public: - ImportAbstractNode(); - AbstractNode *clone() const; - String getValue() const; - }; - - /** This abstract node represents a variable assignment */ - class _OgreExport VariableAccessAbstractNode : public AbstractNode - { - public: - String name; - public: - VariableAccessAbstractNode(AbstractNode *ptr); - AbstractNode *clone() const; - String getValue() const; - }; - - class ScriptCompilerEvent; - class ScriptCompilerListener; - - /** This is the main class for the compiler. It calls the parser - and processes the CST into an AST and then uses translators - to translate the AST into the final resources. - */ - class _OgreExport ScriptCompiler : public ScriptCompilerAlloc - { - public: // Externally accessible types - //typedef map::type IdMap; - typedef HashMap IdMap; - - // The container for errors - struct Error : public ScriptCompilerAlloc - { - String file, message; - int line; - uint32 code; - }; - typedef SharedPtr ErrorPtr; - typedef list::type ErrorList; - - // These are the built-in error codes - enum{ - CE_STRINGEXPECTED, - CE_NUMBEREXPECTED, - CE_FEWERPARAMETERSEXPECTED, - CE_VARIABLEEXPECTED, - CE_UNDEFINEDVARIABLE, - CE_OBJECTNAMEEXPECTED, - CE_OBJECTALLOCATIONERROR, - CE_INVALIDPARAMETERS, - CE_DUPLICATEOVERRIDE, - CE_UNEXPECTEDTOKEN, - CE_OBJECTBASENOTFOUND, - CE_UNSUPPORTEDBYRENDERSYSTEM, - CE_REFERENCETOANONEXISTINGOBJECT - }; - static String formatErrorCode(uint32 code); - public: - ScriptCompiler(); - virtual ~ScriptCompiler() {} - - /// Takes in a string of script code and compiles it into resources - /** - * @param str The script code - * @param source The source of the script code (e.g. a script file) - * @param group The resource group to place the compiled resources into - */ - bool compile(const String &str, const String &source, const String &group); - /// Compiles resources from the given concrete node list - bool compile(const ConcreteNodeListPtr &nodes, const String &group); - /// Generates the AST from the given string script - AbstractNodeListPtr _generateAST(const String &str, const String &source, bool doImports = false, bool doObjects = false, bool doVariables = false); - /// Compiles the given abstract syntax tree - bool _compile(AbstractNodeListPtr nodes, const String &group, bool doImports = true, bool doObjects = true, bool doVariables = true); - /// Adds the given error to the compiler's list of errors - void addError(uint32 code, const String &file, int line, const String &msg = ""); - /// Sets the listener used by the compiler - void setListener(ScriptCompilerListener *listener); - /// Returns the currently set listener - ScriptCompilerListener *getListener(); - /// Returns the resource group currently set for this compiler - const String &getResourceGroup() const; - /// Adds a name exclusion to the map - /** - * Name exclusions identify object types which cannot accept - * names. This means that excluded types will always have empty names. - * All values in the object header are stored as object values. - */ - void addNameExclusion(const String &type); - /// Removes a name exclusion - void removeNameExclusion(const String &type); - /// Internal method for firing the handleEvent method - bool _fireEvent(ScriptCompilerEvent *evt, void *retval); - private: // Tree processing - AbstractNodeListPtr convertToAST(const ConcreteNodeListPtr &nodes); - /// This built-in function processes import nodes - void processImports(AbstractNodeListPtr &nodes); - /// Loads the requested script and converts it to an AST - AbstractNodeListPtr loadImportPath(const String &name); - /// Returns the abstract nodes from the given tree which represent the target - AbstractNodeListPtr locateTarget(AbstractNodeList *nodes, const String &target); - /// Handles object inheritance and variable expansion - void processObjects(AbstractNodeList *nodes, const AbstractNodeListPtr &top); - /// Handles processing the variables - void processVariables(AbstractNodeList *nodes); - /// This function overlays the given object on the destination object following inheritance rules - void overlayObject(const AbstractNodePtr &source, ObjectAbstractNode *dest); - /// Returns true if the given class is name excluded - bool isNameExcluded(const String &cls, AbstractNode *parent); - /// This function sets up the initial values in word id map - void initWordMap(); - private: - // Resource group - String mGroup; - // The word -> id conversion table - IdMap mIds; - // This is an environment map - typedef map::type Environment; - Environment mEnv; - - typedef map::type ImportCacheMap; - ImportCacheMap mImports; // The set of imported scripts to avoid circular dependencies - typedef multimap::type ImportRequestMap; - ImportRequestMap mImportRequests; // This holds the target objects for each script to be imported - - // This stores the imports of the scripts, so they are separated and can be treated specially - AbstractNodeList mImportTable; - - // Error list - ErrorList mErrors; - - // The listener - ScriptCompilerListener *mListener; - private: // Internal helper classes and processors - class AbstractTreeBuilder - { - private: - AbstractNodeListPtr mNodes; - AbstractNode *mCurrent; - ScriptCompiler *mCompiler; - public: - AbstractTreeBuilder(ScriptCompiler *compiler); - const AbstractNodeListPtr &getResult() const; - void visit(ConcreteNode *node); - static void visit(AbstractTreeBuilder *visitor, const ConcreteNodeList &nodes); - }; - friend class AbstractTreeBuilder; - public: // Public translator definitions - // This enum are built-in word id values - enum - { - ID_ON = 1, - ID_OFF = 2, - ID_TRUE = 1, - ID_FALSE = 2, - ID_YES = 1, - ID_NO = 2 - }; - }; - - /** - * This struct is a base class for events which can be thrown by the compilers and caught by - * subscribers. There are a set number of standard events which are used by Ogre's core. - * New event types may be derived for more custom compiler processing. - */ - class ScriptCompilerEvent - { - public: - String mType; - - ScriptCompilerEvent(const String &type):mType(type){} - virtual ~ScriptCompilerEvent(){} - private: // Non-copyable - ScriptCompilerEvent(const ScriptCompilerEvent&); - ScriptCompilerEvent &operator = (const ScriptCompilerEvent&); - }; - - /** This is a listener for the compiler. The compiler can be customized with - this listener. It lets you listen in on events occurring during compilation, - hook them, and change the behavior. - */ - class _OgreExport ScriptCompilerListener - { - public: - ScriptCompilerListener(); - virtual ~ScriptCompilerListener() {} - - /// Returns the concrete node list from the given file - virtual ConcreteNodeListPtr importFile(ScriptCompiler *compiler, const String &name); - /// Allows for responding to and overriding behavior before a CST is translated into an AST - virtual void preConversion(ScriptCompiler *compiler, ConcreteNodeListPtr nodes); - /// Allows vetoing of continued compilation after the entire AST conversion process finishes - /** - @remarks Once the script is turned completely into an AST, including import - and override handling, this function allows a listener to exit - the compilation process. - @return True continues compilation, false aborts - */ - virtual bool postConversion(ScriptCompiler *compiler, const AbstractNodeListPtr&); - /// Called when an error occurred - virtual void handleError(ScriptCompiler *compiler, uint32 code, const String &file, int line, const String &msg); - /// Called when an event occurs during translation, return true if handled - /** - @remarks This function is called from the translators when an event occurs that - that can be responded to. Often this is overriding names, or it can be a request for - custom resource creation. - @arg compiler A reference to the compiler - @arg evt The event object holding information about the event to be processed - @arg retval A possible return value from handlers - @return True if the handler processed the event - */ - virtual bool handleEvent(ScriptCompiler *compiler, ScriptCompilerEvent *evt, void *retval); - }; - - class ScriptTranslator; - class ScriptTranslatorManager; - - /** Manages threaded compilation of scripts. This script loader forwards - scripts compilations to a specific compiler instance. - */ - class _OgreExport ScriptCompilerManager : public Singleton, public ScriptLoader, public ScriptCompilerAlloc - { - private: + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** These enums hold the types of the concrete parsed nodes */ + enum ConcreteNodeType + { + CNT_VARIABLE, + CNT_VARIABLE_ASSIGN, + CNT_WORD, + CNT_IMPORT, + CNT_QUOTE, + CNT_LBRACE, + CNT_RBRACE, + CNT_COLON + }; + + /** The ConcreteNode is the struct that holds an un-conditioned sub-tree of parsed input */ + struct ConcreteNode; + typedef SharedPtr ConcreteNodePtr; + typedef list::type ConcreteNodeList; + typedef SharedPtr ConcreteNodeListPtr; + struct ConcreteNode : public ScriptCompilerAlloc + { + String token, file; + unsigned int line; + ConcreteNodeType type; + ConcreteNodeList children; + ConcreteNode *parent; + }; + + /** This enum holds the types of the possible abstract nodes */ + enum AbstractNodeType + { + ANT_UNKNOWN, + ANT_ATOM, + ANT_OBJECT, + ANT_PROPERTY, + ANT_IMPORT, + ANT_VARIABLE_SET, + ANT_VARIABLE_ACCESS + }; + class AbstractNode; + typedef SharedPtr AbstractNodePtr; + typedef list::type AbstractNodeList; + typedef SharedPtr AbstractNodeListPtr; + + class _OgreExport AbstractNode : public AbstractNodeAlloc + { + public: + String file; + unsigned int line; + AbstractNodeType type; + AbstractNode *parent; + Any context; // A holder for translation context data + public: + AbstractNode(AbstractNode *ptr); + virtual ~AbstractNode(){} + /// Returns a new AbstractNode which is a replica of this one. + virtual AbstractNode *clone() const = 0; + /// Returns a string value depending on the type of the AbstractNode. + virtual String getValue() const = 0; + }; + + /** This is an abstract node which cannot be broken down further */ + class _OgreExport AtomAbstractNode : public AbstractNode + { + public: + String value; + uint32 id; + public: + AtomAbstractNode(AbstractNode *ptr); + AbstractNode *clone() const; + String getValue() const; + private: + void parseNumber() const; + }; + + /** This specific abstract node represents a script object */ + class _OgreExport ObjectAbstractNode : public AbstractNode + { + private: + map::type mEnv; + public: + String name, cls; + vector::type bases; + uint32 id; + bool abstract; + AbstractNodeList children; + AbstractNodeList values; + AbstractNodeList overrides; // For use when processing object inheritance and overriding + public: + ObjectAbstractNode(AbstractNode *ptr); + AbstractNode *clone() const; + String getValue() const; + + void addVariable(const String &name); + void setVariable(const String &name, const String &value); + std::pair getVariable(const String &name) const; + const map::type &getVariables() const; + }; + + /** This abstract node represents a script property */ + class _OgreExport PropertyAbstractNode : public AbstractNode + { + public: + String name; + uint32 id; + AbstractNodeList values; + public: + PropertyAbstractNode(AbstractNode *ptr); + AbstractNode *clone() const; + String getValue() const; + }; + + /** This abstract node represents an import statement */ + class _OgreExport ImportAbstractNode : public AbstractNode + { + public: + String target, source; + public: + ImportAbstractNode(); + AbstractNode *clone() const; + String getValue() const; + }; + + /** This abstract node represents a variable assignment */ + class _OgreExport VariableAccessAbstractNode : public AbstractNode + { + public: + String name; + public: + VariableAccessAbstractNode(AbstractNode *ptr); + AbstractNode *clone() const; + String getValue() const; + }; + + class ScriptCompilerEvent; + class ScriptCompilerListener; + + /** This is the main class for the compiler. It calls the parser + and processes the CST into an AST and then uses translators + to translate the AST into the final resources. + */ + class _OgreExport ScriptCompiler : public ScriptCompilerAlloc + { + public: // Externally accessible types + //typedef map::type IdMap; + typedef HashMap IdMap; + + // The container for errors + struct Error : public ScriptCompilerAlloc + { + String file, message; + int line; + uint32 code; + }; + typedef SharedPtr ErrorPtr; + typedef list::type ErrorList; + + // These are the built-in error codes + enum{ + CE_STRINGEXPECTED, + CE_NUMBEREXPECTED, + CE_FEWERPARAMETERSEXPECTED, + CE_VARIABLEEXPECTED, + CE_UNDEFINEDVARIABLE, + CE_OBJECTNAMEEXPECTED, + CE_OBJECTALLOCATIONERROR, + CE_INVALIDPARAMETERS, + CE_DUPLICATEOVERRIDE, + CE_UNEXPECTEDTOKEN, + CE_OBJECTBASENOTFOUND, + CE_UNSUPPORTEDBYRENDERSYSTEM, + CE_REFERENCETOANONEXISTINGOBJECT + }; + static String formatErrorCode(uint32 code); + public: + ScriptCompiler(); + virtual ~ScriptCompiler() {} + + /// Takes in a string of script code and compiles it into resources + /** + * @param str The script code + * @param source The source of the script code (e.g. a script file) + * @param group The resource group to place the compiled resources into + */ + bool compile(const String &str, const String &source, const String &group); + /// Compiles resources from the given concrete node list + bool compile(const ConcreteNodeListPtr &nodes, const String &group); + /// Generates the AST from the given string script + AbstractNodeListPtr _generateAST(const String &str, const String &source, bool doImports = false, bool doObjects = false, bool doVariables = false); + /// Compiles the given abstract syntax tree + bool _compile(AbstractNodeListPtr nodes, const String &group, bool doImports = true, bool doObjects = true, bool doVariables = true); + /// Adds the given error to the compiler's list of errors + void addError(uint32 code, const String &file, int line, const String &msg = ""); + /// Sets the listener used by the compiler + void setListener(ScriptCompilerListener *listener); + /// Returns the currently set listener + ScriptCompilerListener *getListener(); + /// Returns the resource group currently set for this compiler + const String &getResourceGroup() const; + /// Adds a name exclusion to the map + /** + * Name exclusions identify object types which cannot accept + * names. This means that excluded types will always have empty names. + * All values in the object header are stored as object values. + */ + void addNameExclusion(const String &type); + /// Removes a name exclusion + void removeNameExclusion(const String &type); + /// Internal method for firing the handleEvent method + bool _fireEvent(ScriptCompilerEvent *evt, void *retval); + private: // Tree processing + AbstractNodeListPtr convertToAST(const ConcreteNodeListPtr &nodes); + /// This built-in function processes import nodes + void processImports(AbstractNodeListPtr &nodes); + /// Loads the requested script and converts it to an AST + AbstractNodeListPtr loadImportPath(const String &name); + /// Returns the abstract nodes from the given tree which represent the target + AbstractNodeListPtr locateTarget(AbstractNodeList *nodes, const String &target); + /// Handles object inheritance and variable expansion + void processObjects(AbstractNodeList *nodes, const AbstractNodeListPtr &top); + /// Handles processing the variables + void processVariables(AbstractNodeList *nodes); + /// This function overlays the given object on the destination object following inheritance rules + void overlayObject(const AbstractNodePtr &source, ObjectAbstractNode *dest); + /// Returns true if the given class is name excluded + bool isNameExcluded(const String &cls, AbstractNode *parent); + /// This function sets up the initial values in word id map + void initWordMap(); + private: + // Resource group + String mGroup; + // The word -> id conversion table + IdMap mIds; + // This is an environment map + typedef map::type Environment; + Environment mEnv; + + typedef map::type ImportCacheMap; + ImportCacheMap mImports; // The set of imported scripts to avoid circular dependencies + typedef multimap::type ImportRequestMap; + ImportRequestMap mImportRequests; // This holds the target objects for each script to be imported + + // This stores the imports of the scripts, so they are separated and can be treated specially + AbstractNodeList mImportTable; + + // Error list + ErrorList mErrors; + + // The listener + ScriptCompilerListener *mListener; + private: // Internal helper classes and processors + class AbstractTreeBuilder + { + private: + AbstractNodeListPtr mNodes; + AbstractNode *mCurrent; + ScriptCompiler *mCompiler; + public: + AbstractTreeBuilder(ScriptCompiler *compiler); + const AbstractNodeListPtr &getResult() const; + void visit(ConcreteNode *node); + static void visit(AbstractTreeBuilder *visitor, const ConcreteNodeList &nodes); + }; + friend class AbstractTreeBuilder; + public: // Public translator definitions + // This enum are built-in word id values + enum + { + ID_ON = 1, + ID_OFF = 2, + ID_TRUE = 1, + ID_FALSE = 2, + ID_YES = 1, + ID_NO = 2 + }; + }; + + /** + * This struct is a base class for events which can be thrown by the compilers and caught by + * subscribers. There are a set number of standard events which are used by Ogre's core. + * New event types may be derived for more custom compiler processing. + */ + class ScriptCompilerEvent + { + public: + String mType; + + ScriptCompilerEvent(const String &type):mType(type){} + virtual ~ScriptCompilerEvent(){} + private: // Non-copyable + ScriptCompilerEvent(const ScriptCompilerEvent&); + ScriptCompilerEvent &operator = (const ScriptCompilerEvent&); + }; + + /** This is a listener for the compiler. The compiler can be customized with + this listener. It lets you listen in on events occurring during compilation, + hook them, and change the behavior. + */ + class _OgreExport ScriptCompilerListener + { + public: + ScriptCompilerListener(); + virtual ~ScriptCompilerListener() {} + + /// Returns the concrete node list from the given file + virtual ConcreteNodeListPtr importFile(ScriptCompiler *compiler, const String &name); + /// Allows for responding to and overriding behavior before a CST is translated into an AST + virtual void preConversion(ScriptCompiler *compiler, ConcreteNodeListPtr nodes); + /// Allows vetoing of continued compilation after the entire AST conversion process finishes + /** + @remarks Once the script is turned completely into an AST, including import + and override handling, this function allows a listener to exit + the compilation process. + @return True continues compilation, false aborts + */ + virtual bool postConversion(ScriptCompiler *compiler, const AbstractNodeListPtr&); + /// Called when an error occurred + virtual void handleError(ScriptCompiler *compiler, uint32 code, const String &file, int line, const String &msg); + /// Called when an event occurs during translation, return true if handled + /** + @remarks This function is called from the translators when an event occurs that + that can be responded to. Often this is overriding names, or it can be a request for + custom resource creation. + @arg compiler A reference to the compiler + @arg evt The event object holding information about the event to be processed + @arg retval A possible return value from handlers + @return True if the handler processed the event + */ + virtual bool handleEvent(ScriptCompiler *compiler, ScriptCompilerEvent *evt, void *retval); + }; + + class ScriptTranslator; + class ScriptTranslatorManager; + + /** Manages threaded compilation of scripts. This script loader forwards + scripts compilations to a specific compiler instance. + */ + class _OgreExport ScriptCompilerManager : public Singleton, public ScriptLoader, public ScriptCompilerAlloc + { + private: OGRE_AUTO_MUTEX; - // A list of patterns loaded by this compiler manager - StringVector mScriptPatterns; - - // A pointer to the listener used for compiling scripts - ScriptCompilerListener *mListener; - - // Stores a map from object types to the translators that handle them - vector::type mManagers; - - // A pointer to the built-in ScriptTranslatorManager - ScriptTranslatorManager *mBuiltinTranslatorManager; - - // A pointer to the specific compiler instance used - OGRE_THREAD_POINTER(ScriptCompiler, mScriptCompiler); - public: - ScriptCompilerManager(); - virtual ~ScriptCompilerManager(); - - /// Sets the listener used for compiler instances - void setListener(ScriptCompilerListener *listener); - /// Returns the currently set listener used for compiler instances - ScriptCompilerListener *getListener(); - - /// Adds the given translator manager to the list of managers - void addTranslatorManager(ScriptTranslatorManager *man); - /// Removes the given translator manager from the list of managers - void removeTranslatorManager(ScriptTranslatorManager *man); - /// Clears all translator managers - void clearTranslatorManagers(); - /// Retrieves a ScriptTranslator from the supported managers - ScriptTranslator *getTranslator(const AbstractNodePtr &node); - - /// Adds a script extension that can be handled (e.g. *.material, *.pu, etc.) - void addScriptPattern(const String &pattern); - /// @copydoc ScriptLoader::getScriptPatterns + // A list of patterns loaded by this compiler manager + StringVector mScriptPatterns; + + // A pointer to the listener used for compiling scripts + ScriptCompilerListener *mListener; + + // Stores a map from object types to the translators that handle them + vector::type mManagers; + + // A pointer to the built-in ScriptTranslatorManager + ScriptTranslatorManager *mBuiltinTranslatorManager; + + // A pointer to the specific compiler instance used + OGRE_THREAD_POINTER(ScriptCompiler, mScriptCompiler); + public: + ScriptCompilerManager(); + virtual ~ScriptCompilerManager(); + + /// Sets the listener used for compiler instances + void setListener(ScriptCompilerListener *listener); + /// Returns the currently set listener used for compiler instances + ScriptCompilerListener *getListener(); + + /// Adds the given translator manager to the list of managers + void addTranslatorManager(ScriptTranslatorManager *man); + /// Removes the given translator manager from the list of managers + void removeTranslatorManager(ScriptTranslatorManager *man); + /// Clears all translator managers + void clearTranslatorManagers(); + /// Retrieves a ScriptTranslator from the supported managers + ScriptTranslator *getTranslator(const AbstractNodePtr &node); + + /// Adds a script extension that can be handled (e.g. *.material, *.pu, etc.) + void addScriptPattern(const String &pattern); + /// @copydoc ScriptLoader::getScriptPatterns const StringVector& getScriptPatterns(void) const; /// @copydoc ScriptLoader::parseScript void parseScript(DataStreamPtr& stream, const String& groupName); /// @copydoc ScriptLoader::getLoadingOrder Real getLoadingOrder(void) const; - /** Override standard Singleton retrieval. + /** Override standard Singleton retrieval. @remarks Why do we do this? Well, it's because the Singleton implementation is in a .h file, which means it gets compiled @@ -459,417 +459,417 @@ namespace Ogre preventing link errors. */ static ScriptCompilerManager* getSingletonPtr(void); - }; - - // Standard event types - class _OgreExport PreApplyTextureAliasesScriptCompilerEvent : public ScriptCompilerEvent - { - public: - Material *mMaterial; - AliasTextureNamePairList *mAliases; - static String eventType; - - PreApplyTextureAliasesScriptCompilerEvent(Material *material, AliasTextureNamePairList *aliases) - :ScriptCompilerEvent(eventType), mMaterial(material), mAliases(aliases){} - }; - - class _OgreExport ProcessResourceNameScriptCompilerEvent : public ScriptCompilerEvent - { - public: - enum ResourceType - { - TEXTURE, - MATERIAL, - GPU_PROGRAM, - COMPOSITOR - }; - ResourceType mResourceType; - String mName; - static String eventType; - - ProcessResourceNameScriptCompilerEvent(ResourceType resourceType, const String &name) - :ScriptCompilerEvent(eventType), mResourceType(resourceType), mName(name){} - }; - - class _OgreExport ProcessNameExclusionScriptCompilerEvent : public ScriptCompilerEvent - { - public: - String mClass; - AbstractNode *mParent; - static String eventType; - - ProcessNameExclusionScriptCompilerEvent(const String &cls, AbstractNode *parent) - :ScriptCompilerEvent(eventType), mClass(cls), mParent(parent){} - }; - - class _OgreExport CreateMaterialScriptCompilerEvent : public ScriptCompilerEvent - { - public: - String mFile, mName, mResourceGroup; - static String eventType; - - CreateMaterialScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup) - :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup){} - }; - - class _OgreExport CreateGpuProgramScriptCompilerEvent : public ScriptCompilerEvent - { - public: - String mFile, mName, mResourceGroup, mSource, mSyntax; - GpuProgramType mProgramType; - static String eventType; - - CreateGpuProgramScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup, const String &source, - const String &syntax, GpuProgramType programType) - :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup), mSource(source), - mSyntax(syntax), mProgramType(programType) - {} - }; - - class _OgreExport CreateHighLevelGpuProgramScriptCompilerEvent : public ScriptCompilerEvent - { - public: - String mFile, mName, mResourceGroup, mSource, mLanguage; - GpuProgramType mProgramType; - static String eventType; - - CreateHighLevelGpuProgramScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup, const String &source, - const String &language, GpuProgramType programType) - :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup), mSource(source), - mLanguage(language), mProgramType(programType) - {} - }; - - class _OgreExport CreateGpuSharedParametersScriptCompilerEvent : public ScriptCompilerEvent - { - public: - String mFile, mName, mResourceGroup; - static String eventType; - - CreateGpuSharedParametersScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup) - :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup){} - }; - - class _OgreExport CreateParticleSystemScriptCompilerEvent : public ScriptCompilerEvent - { - public: - String mFile, mName, mResourceGroup; - static String eventType; - - CreateParticleSystemScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup) - :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup){} - }; - - class _OgreExport CreateCompositorScriptCompilerEvent : public ScriptCompilerEvent - { - public: - String mFile, mName, mResourceGroup; - static String eventType; - - CreateCompositorScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup) - :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup){} - }; - - /// This enum defines the integer ids for keywords this compiler handles - enum - { - ID_MATERIAL = 3, - ID_VERTEX_PROGRAM, - ID_GEOMETRY_PROGRAM, - ID_FRAGMENT_PROGRAM, - ID_TECHNIQUE, - ID_PASS, - ID_TEXTURE_UNIT, - ID_VERTEX_PROGRAM_REF, - ID_GEOMETRY_PROGRAM_REF, - ID_FRAGMENT_PROGRAM_REF, - ID_SHADOW_CASTER_VERTEX_PROGRAM_REF, - ID_SHADOW_CASTER_FRAGMENT_PROGRAM_REF, - ID_SHADOW_RECEIVER_VERTEX_PROGRAM_REF, - ID_SHADOW_RECEIVER_FRAGMENT_PROGRAM_REF, - ID_SHADOW_CASTER_MATERIAL, - ID_SHADOW_RECEIVER_MATERIAL, - + }; + + // Standard event types + class _OgreExport PreApplyTextureAliasesScriptCompilerEvent : public ScriptCompilerEvent + { + public: + Material *mMaterial; + AliasTextureNamePairList *mAliases; + static String eventType; + + PreApplyTextureAliasesScriptCompilerEvent(Material *material, AliasTextureNamePairList *aliases) + :ScriptCompilerEvent(eventType), mMaterial(material), mAliases(aliases){} + }; + + class _OgreExport ProcessResourceNameScriptCompilerEvent : public ScriptCompilerEvent + { + public: + enum ResourceType + { + TEXTURE, + MATERIAL, + GPU_PROGRAM, + COMPOSITOR + }; + ResourceType mResourceType; + String mName; + static String eventType; + + ProcessResourceNameScriptCompilerEvent(ResourceType resourceType, const String &name) + :ScriptCompilerEvent(eventType), mResourceType(resourceType), mName(name){} + }; + + class _OgreExport ProcessNameExclusionScriptCompilerEvent : public ScriptCompilerEvent + { + public: + String mClass; + AbstractNode *mParent; + static String eventType; + + ProcessNameExclusionScriptCompilerEvent(const String &cls, AbstractNode *parent) + :ScriptCompilerEvent(eventType), mClass(cls), mParent(parent){} + }; + + class _OgreExport CreateMaterialScriptCompilerEvent : public ScriptCompilerEvent + { + public: + String mFile, mName, mResourceGroup; + static String eventType; + + CreateMaterialScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup) + :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup){} + }; + + class _OgreExport CreateGpuProgramScriptCompilerEvent : public ScriptCompilerEvent + { + public: + String mFile, mName, mResourceGroup, mSource, mSyntax; + GpuProgramType mProgramType; + static String eventType; + + CreateGpuProgramScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup, const String &source, + const String &syntax, GpuProgramType programType) + :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup), mSource(source), + mSyntax(syntax), mProgramType(programType) + {} + }; + + class _OgreExport CreateHighLevelGpuProgramScriptCompilerEvent : public ScriptCompilerEvent + { + public: + String mFile, mName, mResourceGroup, mSource, mLanguage; + GpuProgramType mProgramType; + static String eventType; + + CreateHighLevelGpuProgramScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup, const String &source, + const String &language, GpuProgramType programType) + :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup), mSource(source), + mLanguage(language), mProgramType(programType) + {} + }; + + class _OgreExport CreateGpuSharedParametersScriptCompilerEvent : public ScriptCompilerEvent + { + public: + String mFile, mName, mResourceGroup; + static String eventType; + + CreateGpuSharedParametersScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup) + :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup){} + }; + + class _OgreExport CreateParticleSystemScriptCompilerEvent : public ScriptCompilerEvent + { + public: + String mFile, mName, mResourceGroup; + static String eventType; + + CreateParticleSystemScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup) + :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup){} + }; + + class _OgreExport CreateCompositorScriptCompilerEvent : public ScriptCompilerEvent + { + public: + String mFile, mName, mResourceGroup; + static String eventType; + + CreateCompositorScriptCompilerEvent(const String &file, const String &name, const String &resourceGroup) + :ScriptCompilerEvent(eventType), mFile(file), mName(name), mResourceGroup(resourceGroup){} + }; + + /// This enum defines the integer ids for keywords this compiler handles + enum + { + ID_MATERIAL = 3, + ID_VERTEX_PROGRAM, + ID_GEOMETRY_PROGRAM, + ID_FRAGMENT_PROGRAM, + ID_TECHNIQUE, + ID_PASS, + ID_TEXTURE_UNIT, + ID_VERTEX_PROGRAM_REF, + ID_GEOMETRY_PROGRAM_REF, + ID_FRAGMENT_PROGRAM_REF, + ID_SHADOW_CASTER_VERTEX_PROGRAM_REF, + ID_SHADOW_CASTER_FRAGMENT_PROGRAM_REF, + ID_SHADOW_RECEIVER_VERTEX_PROGRAM_REF, + ID_SHADOW_RECEIVER_FRAGMENT_PROGRAM_REF, + ID_SHADOW_CASTER_MATERIAL, + ID_SHADOW_RECEIVER_MATERIAL, + ID_LOD_VALUES, ID_LOD_STRATEGY, - ID_LOD_DISTANCES, - ID_RECEIVE_SHADOWS, - ID_TRANSPARENCY_CASTS_SHADOWS, - ID_SET_TEXTURE_ALIAS, - - ID_SOURCE, - ID_SYNTAX, - ID_DEFAULT_PARAMS, - ID_PARAM_INDEXED, - ID_PARAM_NAMED, - ID_PARAM_INDEXED_AUTO, - ID_PARAM_NAMED_AUTO, - - ID_SCHEME, - ID_LOD_INDEX, - ID_GPU_VENDOR_RULE, - ID_GPU_DEVICE_RULE, - ID_INCLUDE, - ID_EXCLUDE, - - ID_AMBIENT, - ID_DIFFUSE, - ID_SPECULAR, - ID_EMISSIVE, - ID_VERTEXCOLOUR, - ID_SCENE_BLEND, - ID_COLOUR_BLEND, - ID_ONE, - ID_ZERO, - ID_DEST_COLOUR, - ID_SRC_COLOUR, - ID_ONE_MINUS_DEST_COLOUR, - ID_ONE_MINUS_SRC_COLOUR, - ID_DEST_ALPHA, - ID_SRC_ALPHA, - ID_ONE_MINUS_DEST_ALPHA, - ID_ONE_MINUS_SRC_ALPHA, - ID_SEPARATE_SCENE_BLEND, - ID_SCENE_BLEND_OP, - ID_REVERSE_SUBTRACT, - ID_MIN, - ID_MAX, - ID_SEPARATE_SCENE_BLEND_OP, - ID_DEPTH_CHECK, - ID_DEPTH_WRITE, - ID_DEPTH_FUNC, - ID_DEPTH_BIAS, - ID_ITERATION_DEPTH_BIAS, - ID_ALWAYS_FAIL, - ID_ALWAYS_PASS, - ID_LESS_EQUAL, - ID_LESS, - ID_EQUAL, - ID_NOT_EQUAL, - ID_GREATER_EQUAL, - ID_GREATER, - ID_ALPHA_REJECTION, - ID_ALPHA_TO_COVERAGE, - ID_LIGHT_SCISSOR, - ID_LIGHT_CLIP_PLANES, - ID_TRANSPARENT_SORTING, - ID_ILLUMINATION_STAGE, - ID_DECAL, - ID_CULL_HARDWARE, - ID_CLOCKWISE, - ID_ANTICLOCKWISE, - ID_CULL_SOFTWARE, - ID_BACK, - ID_FRONT, - ID_NORMALISE_NORMALS, - ID_LIGHTING, - ID_SHADING, - ID_FLAT, - ID_GOURAUD, - ID_PHONG, - ID_POLYGON_MODE, - ID_SOLID, - ID_WIREFRAME, - ID_POINTS, - ID_POLYGON_MODE_OVERRIDEABLE, - ID_FOG_OVERRIDE, - ID_NONE, - ID_LINEAR, - ID_EXP, - ID_EXP2, - ID_COLOUR_WRITE, - ID_MAX_LIGHTS, - ID_START_LIGHT, - ID_ITERATION, - ID_ONCE, - ID_ONCE_PER_LIGHT, - ID_PER_LIGHT, - ID_PER_N_LIGHTS, - ID_POINT, - ID_SPOT, - ID_DIRECTIONAL, - ID_LIGHT_MASK, - ID_POINT_SIZE, - ID_POINT_SPRITES, - ID_POINT_SIZE_ATTENUATION, - ID_POINT_SIZE_MIN, - ID_POINT_SIZE_MAX, - - ID_TEXTURE_ALIAS, - ID_TEXTURE, - ID_1D, - ID_2D, - ID_3D, - ID_CUBIC, - ID_2DARRAY, - ID_UNLIMITED, - ID_ALPHA, - ID_GAMMA, - ID_ANIM_TEXTURE, - ID_CUBIC_TEXTURE, - ID_SEPARATE_UV, - ID_COMBINED_UVW, - ID_TEX_COORD_SET, - ID_TEX_ADDRESS_MODE, - ID_WRAP, - ID_CLAMP, - ID_BORDER, - ID_MIRROR, - ID_TEX_BORDER_COLOUR, - ID_FILTERING, - ID_BILINEAR, - ID_TRILINEAR, - ID_ANISOTROPIC, - ID_CMPTEST, - ID_ON, - ID_OFF, - ID_CMPFUNC, - ID_MAX_ANISOTROPY, - ID_MIPMAP_BIAS, - ID_COLOUR_OP, - ID_REPLACE, - ID_ADD, - ID_MODULATE, - ID_ALPHA_BLEND, - ID_COLOUR_OP_EX, - ID_SOURCE1, - ID_SOURCE2, - ID_MODULATE_X2, - ID_MODULATE_X4, - ID_ADD_SIGNED, - ID_ADD_SMOOTH, - ID_SUBTRACT, - ID_BLEND_DIFFUSE_COLOUR, - ID_BLEND_DIFFUSE_ALPHA, - ID_BLEND_TEXTURE_ALPHA, - ID_BLEND_CURRENT_ALPHA, - ID_BLEND_MANUAL, - ID_DOT_PRODUCT, - ID_SRC_CURRENT, - ID_SRC_TEXTURE, - ID_SRC_DIFFUSE, - ID_SRC_SPECULAR, - ID_SRC_MANUAL, - ID_COLOUR_OP_MULTIPASS_FALLBACK, - ID_ALPHA_OP_EX, - ID_ENV_MAP, - ID_SPHERICAL, - ID_PLANAR, - ID_CUBIC_REFLECTION, - ID_CUBIC_NORMAL, - ID_SCROLL, - ID_SCROLL_ANIM, - ID_ROTATE, - ID_ROTATE_ANIM, - ID_SCALE, - ID_WAVE_XFORM, - ID_SCROLL_X, - ID_SCROLL_Y, - ID_SCALE_X, - ID_SCALE_Y, - ID_SINE, - ID_TRIANGLE, - ID_SQUARE, - ID_SAWTOOTH, - ID_INVERSE_SAWTOOTH, - ID_TRANSFORM, - ID_BINDING_TYPE, - ID_VERTEX, - ID_FRAGMENT, - ID_CONTENT_TYPE, - ID_NAMED, - ID_SHADOW, - ID_TEXTURE_SOURCE, - ID_SHARED_PARAMS, - ID_SHARED_PARAM_NAMED, - ID_SHARED_PARAMS_REF, - - ID_PARTICLE_SYSTEM, - ID_EMITTER, - ID_AFFECTOR, - - ID_COMPOSITOR, - ID_TARGET, - ID_TARGET_OUTPUT, - - ID_INPUT, - ID_PREVIOUS, - ID_TARGET_WIDTH, - ID_TARGET_HEIGHT, - ID_TARGET_WIDTH_SCALED, - ID_TARGET_HEIGHT_SCALED, - ID_COMPOSITOR_LOGIC, - ID_TEXTURE_REF, - ID_SCOPE_LOCAL, - ID_SCOPE_CHAIN, - ID_SCOPE_GLOBAL, - ID_POOLED, - //ID_GAMMA, - already registered for material - ID_NO_FSAA, - ID_DEPTH_POOL, - ID_ONLY_INITIAL, - ID_VISIBILITY_MASK, - ID_LOD_BIAS, - ID_MATERIAL_SCHEME, - ID_SHADOWS_ENABLED, - - ID_CLEAR, - ID_STENCIL, - ID_RENDER_SCENE, - ID_RENDER_QUAD, - ID_IDENTIFIER, - ID_FIRST_RENDER_QUEUE, - ID_LAST_RENDER_QUEUE, - ID_QUAD_NORMALS, - ID_CAMERA_FAR_CORNERS_VIEW_SPACE, - ID_CAMERA_FAR_CORNERS_WORLD_SPACE, - - ID_BUFFERS, - ID_COLOUR, - ID_DEPTH, - ID_COLOUR_VALUE, - ID_DEPTH_VALUE, - ID_STENCIL_VALUE, - - ID_CHECK, - ID_COMP_FUNC, - ID_REF_VALUE, - ID_MASK, - ID_FAIL_OP, - ID_KEEP, - ID_INCREMENT, - ID_DECREMENT, - ID_INCREMENT_WRAP, - ID_DECREMENT_WRAP, - ID_INVERT, - ID_DEPTH_FAIL_OP, - ID_PASS_OP, - ID_TWO_SIDED, - ID_READ_BACK_AS_TEXTURE, + ID_LOD_DISTANCES, + ID_RECEIVE_SHADOWS, + ID_TRANSPARENCY_CASTS_SHADOWS, + ID_SET_TEXTURE_ALIAS, + + ID_SOURCE, + ID_SYNTAX, + ID_DEFAULT_PARAMS, + ID_PARAM_INDEXED, + ID_PARAM_NAMED, + ID_PARAM_INDEXED_AUTO, + ID_PARAM_NAMED_AUTO, + + ID_SCHEME, + ID_LOD_INDEX, + ID_GPU_VENDOR_RULE, + ID_GPU_DEVICE_RULE, + ID_INCLUDE, + ID_EXCLUDE, + + ID_AMBIENT, + ID_DIFFUSE, + ID_SPECULAR, + ID_EMISSIVE, + ID_VERTEXCOLOUR, + ID_SCENE_BLEND, + ID_COLOUR_BLEND, + ID_ONE, + ID_ZERO, + ID_DEST_COLOUR, + ID_SRC_COLOUR, + ID_ONE_MINUS_DEST_COLOUR, + ID_ONE_MINUS_SRC_COLOUR, + ID_DEST_ALPHA, + ID_SRC_ALPHA, + ID_ONE_MINUS_DEST_ALPHA, + ID_ONE_MINUS_SRC_ALPHA, + ID_SEPARATE_SCENE_BLEND, + ID_SCENE_BLEND_OP, + ID_REVERSE_SUBTRACT, + ID_MIN, + ID_MAX, + ID_SEPARATE_SCENE_BLEND_OP, + ID_DEPTH_CHECK, + ID_DEPTH_WRITE, + ID_DEPTH_FUNC, + ID_DEPTH_BIAS, + ID_ITERATION_DEPTH_BIAS, + ID_ALWAYS_FAIL, + ID_ALWAYS_PASS, + ID_LESS_EQUAL, + ID_LESS, + ID_EQUAL, + ID_NOT_EQUAL, + ID_GREATER_EQUAL, + ID_GREATER, + ID_ALPHA_REJECTION, + ID_ALPHA_TO_COVERAGE, + ID_LIGHT_SCISSOR, + ID_LIGHT_CLIP_PLANES, + ID_TRANSPARENT_SORTING, + ID_ILLUMINATION_STAGE, + ID_DECAL, + ID_CULL_HARDWARE, + ID_CLOCKWISE, + ID_ANTICLOCKWISE, + ID_CULL_SOFTWARE, + ID_BACK, + ID_FRONT, + ID_NORMALISE_NORMALS, + ID_LIGHTING, + ID_SHADING, + ID_FLAT, + ID_GOURAUD, + ID_PHONG, + ID_POLYGON_MODE, + ID_SOLID, + ID_WIREFRAME, + ID_POINTS, + ID_POLYGON_MODE_OVERRIDEABLE, + ID_FOG_OVERRIDE, + ID_NONE, + ID_LINEAR, + ID_EXP, + ID_EXP2, + ID_COLOUR_WRITE, + ID_MAX_LIGHTS, + ID_START_LIGHT, + ID_ITERATION, + ID_ONCE, + ID_ONCE_PER_LIGHT, + ID_PER_LIGHT, + ID_PER_N_LIGHTS, + ID_POINT, + ID_SPOT, + ID_DIRECTIONAL, + ID_LIGHT_MASK, + ID_POINT_SIZE, + ID_POINT_SPRITES, + ID_POINT_SIZE_ATTENUATION, + ID_POINT_SIZE_MIN, + ID_POINT_SIZE_MAX, + + ID_TEXTURE_ALIAS, + ID_TEXTURE, + ID_1D, + ID_2D, + ID_3D, + ID_CUBIC, + ID_2DARRAY, + ID_UNLIMITED, + ID_ALPHA, + ID_GAMMA, + ID_ANIM_TEXTURE, + ID_CUBIC_TEXTURE, + ID_SEPARATE_UV, + ID_COMBINED_UVW, + ID_TEX_COORD_SET, + ID_TEX_ADDRESS_MODE, + ID_WRAP, + ID_CLAMP, + ID_BORDER, + ID_MIRROR, + ID_TEX_BORDER_COLOUR, + ID_FILTERING, + ID_BILINEAR, + ID_TRILINEAR, + ID_ANISOTROPIC, + ID_CMPTEST, + ID_ON, + ID_OFF, + ID_CMPFUNC, + ID_MAX_ANISOTROPY, + ID_MIPMAP_BIAS, + ID_COLOUR_OP, + ID_REPLACE, + ID_ADD, + ID_MODULATE, + ID_ALPHA_BLEND, + ID_COLOUR_OP_EX, + ID_SOURCE1, + ID_SOURCE2, + ID_MODULATE_X2, + ID_MODULATE_X4, + ID_ADD_SIGNED, + ID_ADD_SMOOTH, + ID_SUBTRACT, + ID_BLEND_DIFFUSE_COLOUR, + ID_BLEND_DIFFUSE_ALPHA, + ID_BLEND_TEXTURE_ALPHA, + ID_BLEND_CURRENT_ALPHA, + ID_BLEND_MANUAL, + ID_DOT_PRODUCT, + ID_SRC_CURRENT, + ID_SRC_TEXTURE, + ID_SRC_DIFFUSE, + ID_SRC_SPECULAR, + ID_SRC_MANUAL, + ID_COLOUR_OP_MULTIPASS_FALLBACK, + ID_ALPHA_OP_EX, + ID_ENV_MAP, + ID_SPHERICAL, + ID_PLANAR, + ID_CUBIC_REFLECTION, + ID_CUBIC_NORMAL, + ID_SCROLL, + ID_SCROLL_ANIM, + ID_ROTATE, + ID_ROTATE_ANIM, + ID_SCALE, + ID_WAVE_XFORM, + ID_SCROLL_X, + ID_SCROLL_Y, + ID_SCALE_X, + ID_SCALE_Y, + ID_SINE, + ID_TRIANGLE, + ID_SQUARE, + ID_SAWTOOTH, + ID_INVERSE_SAWTOOTH, + ID_TRANSFORM, + ID_BINDING_TYPE, + ID_VERTEX, + ID_FRAGMENT, + ID_CONTENT_TYPE, + ID_NAMED, + ID_SHADOW, + ID_TEXTURE_SOURCE, + ID_SHARED_PARAMS, + ID_SHARED_PARAM_NAMED, + ID_SHARED_PARAMS_REF, + + ID_PARTICLE_SYSTEM, + ID_EMITTER, + ID_AFFECTOR, + + ID_COMPOSITOR, + ID_TARGET, + ID_TARGET_OUTPUT, + + ID_INPUT, + ID_PREVIOUS, + ID_TARGET_WIDTH, + ID_TARGET_HEIGHT, + ID_TARGET_WIDTH_SCALED, + ID_TARGET_HEIGHT_SCALED, + ID_COMPOSITOR_LOGIC, + ID_TEXTURE_REF, + ID_SCOPE_LOCAL, + ID_SCOPE_CHAIN, + ID_SCOPE_GLOBAL, + ID_POOLED, + //ID_GAMMA, - already registered for material + ID_NO_FSAA, + ID_DEPTH_POOL, + ID_ONLY_INITIAL, + ID_VISIBILITY_MASK, + ID_LOD_BIAS, + ID_MATERIAL_SCHEME, + ID_SHADOWS_ENABLED, + + ID_CLEAR, + ID_STENCIL, + ID_RENDER_SCENE, + ID_RENDER_QUAD, + ID_IDENTIFIER, + ID_FIRST_RENDER_QUEUE, + ID_LAST_RENDER_QUEUE, + ID_QUAD_NORMALS, + ID_CAMERA_FAR_CORNERS_VIEW_SPACE, + ID_CAMERA_FAR_CORNERS_WORLD_SPACE, + + ID_BUFFERS, + ID_COLOUR, + ID_DEPTH, + ID_COLOUR_VALUE, + ID_DEPTH_VALUE, + ID_STENCIL_VALUE, + + ID_CHECK, + ID_COMP_FUNC, + ID_REF_VALUE, + ID_MASK, + ID_FAIL_OP, + ID_KEEP, + ID_INCREMENT, + ID_DECREMENT, + ID_INCREMENT_WRAP, + ID_DECREMENT_WRAP, + ID_INVERT, + ID_DEPTH_FAIL_OP, + ID_PASS_OP, + ID_TWO_SIDED, + ID_READ_BACK_AS_TEXTURE, #ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS ID_RT_SHADER_SYSTEM, #endif - /// Suport for shader model 5.0 - // More program IDs - ID_TESSELLATION_HULL_PROGRAM, - ID_TESSELLATION_DOMAIN_PROGRAM, - ID_COMPUTE_PROGRAM, - ID_TESSELLATION_HULL_PROGRAM_REF, - ID_TESSELLATION_DOMAIN_PROGRAM_REF, - ID_COMPUTE_PROGRAM_REF, - // More binding IDs - ID_GEOMETRY, - ID_TESSELLATION_HULL, - ID_TESSELLATION_DOMAIN, - ID_COMPUTE, - - // Support for subroutine - ID_SUBROUTINE, - - ID_END_BUILTIN_IDS - }; - /** @} */ - /** @} */ + /// Suport for shader model 5.0 + // More program IDs + ID_TESSELLATION_HULL_PROGRAM, + ID_TESSELLATION_DOMAIN_PROGRAM, + ID_COMPUTE_PROGRAM, + ID_TESSELLATION_HULL_PROGRAM_REF, + ID_TESSELLATION_DOMAIN_PROGRAM_REF, + ID_COMPUTE_PROGRAM_REF, + // More binding IDs + ID_GEOMETRY, + ID_TESSELLATION_HULL, + ID_TESSELLATION_DOMAIN, + ID_COMPUTE, + + // Support for subroutine + ID_SUBROUTINE, + + ID_END_BUILTIN_IDS + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreScriptLexer.h b/OgreMain/include/OgreScriptLexer.h index ed7c9594341..21b1dfd2787 100644 --- a/OgreMain/include/OgreScriptLexer.h +++ b/OgreMain/include/OgreScriptLexer.h @@ -34,60 +34,60 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** These codes represent token IDs which are numerical translations of - specific lexemes. Specific compilers using the lexer can register their - own token IDs which are given precedence over these built-in ones. - */ - enum{ - TID_LBRACKET = 0, // { - TID_RBRACKET, // } - TID_COLON, // : - TID_VARIABLE, // $... - TID_WORD, // * - TID_QUOTE, // "*" - TID_NEWLINE, // \n - TID_UNKNOWN, - TID_END - }; + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** These codes represent token IDs which are numerical translations of + specific lexemes. Specific compilers using the lexer can register their + own token IDs which are given precedence over these built-in ones. + */ + enum{ + TID_LBRACKET = 0, // { + TID_RBRACKET, // } + TID_COLON, // : + TID_VARIABLE, // $... + TID_WORD, // * + TID_QUOTE, // "*" + TID_NEWLINE, // \n + TID_UNKNOWN, + TID_END + }; - /** This struct represents a token, which is an ID'd lexeme from the - parsing input stream. - */ - struct ScriptToken - { - /// This is the lexeme for this token - String lexeme, file; - /// This is the id associated with the lexeme, which comes from a lexeme-token id mapping - uint32 type; - /// This holds the line number of the input stream where the token was found. - uint32 line; - }; - typedef SharedPtr ScriptTokenPtr; - typedef vector::type ScriptTokenList; - typedef SharedPtr ScriptTokenListPtr; + /** This struct represents a token, which is an ID'd lexeme from the + parsing input stream. + */ + struct ScriptToken + { + /// This is the lexeme for this token + String lexeme, file; + /// This is the id associated with the lexeme, which comes from a lexeme-token id mapping + uint32 type; + /// This holds the line number of the input stream where the token was found. + uint32 line; + }; + typedef SharedPtr ScriptTokenPtr; + typedef vector::type ScriptTokenList; + typedef SharedPtr ScriptTokenListPtr; - class _OgreExport ScriptLexer : public ScriptCompilerAlloc - { - public: - ScriptLexer(); - virtual ~ScriptLexer() {} + class _OgreExport ScriptLexer : public ScriptCompilerAlloc + { + public: + ScriptLexer(); + virtual ~ScriptLexer() {} - /** Tokenizes the given input and returns the list of tokens found */ - ScriptTokenListPtr tokenize(const String &str, const String &source); - private: // Private utility operations - void setToken(const String &lexeme, uint32 line, const String &source, ScriptTokenList *tokens); - bool isWhitespace(Ogre::String::value_type c) const; - bool isNewline(Ogre::String::value_type c) const; - }; + /** Tokenizes the given input and returns the list of tokens found */ + ScriptTokenListPtr tokenize(const String &str, const String &source); + private: // Private utility operations + void setToken(const String &lexeme, uint32 line, const String &source, ScriptTokenList *tokens); + bool isWhitespace(Ogre::String::value_type c) const; + bool isNewline(Ogre::String::value_type c) const; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreScriptLoader.h b/OgreMain/include/OgreScriptLoader.h index 1d84fbebe99..74f8488c8b9 100644 --- a/OgreMain/include/OgreScriptLoader.h +++ b/OgreMain/include/OgreScriptLoader.h @@ -35,61 +35,61 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** Abstract class defining the interface used by classes which wish - to perform script loading to define instances of whatever they manage. - @remarks - Typically classes of this type wish to either parse individual script files - on demand, or be called with a group of files matching a certain pattern - at the appropriate time. Normally this will coincide with resource loading, - although the script use does not necessarily have to be a ResourceManager - (which subclasses from this class), it may be simply a script loader which - manages non-resources but needs to be synchronised at the same loading points. - @par - Subclasses should add themselves to the ResourceGroupManager as a script loader - if they wish to be called at the point a resource group is loaded, at which - point the parseScript method will be called with each file which matches a - the pattern returned from getScriptPatterns. - */ - class _OgreExport ScriptLoader - { - public: - virtual ~ScriptLoader(); - /** Gets the file patterns which should be used to find scripts for this - class. - @remarks - This method is called when a resource group is loaded if you use - ResourceGroupManager::_registerScriptLoader. - @return - A list of file patterns, in the order they should be searched in. - */ - virtual const StringVector& getScriptPatterns(void) const = 0; + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** Abstract class defining the interface used by classes which wish + to perform script loading to define instances of whatever they manage. + @remarks + Typically classes of this type wish to either parse individual script files + on demand, or be called with a group of files matching a certain pattern + at the appropriate time. Normally this will coincide with resource loading, + although the script use does not necessarily have to be a ResourceManager + (which subclasses from this class), it may be simply a script loader which + manages non-resources but needs to be synchronised at the same loading points. + @par + Subclasses should add themselves to the ResourceGroupManager as a script loader + if they wish to be called at the point a resource group is loaded, at which + point the parseScript method will be called with each file which matches a + the pattern returned from getScriptPatterns. + */ + class _OgreExport ScriptLoader + { + public: + virtual ~ScriptLoader(); + /** Gets the file patterns which should be used to find scripts for this + class. + @remarks + This method is called when a resource group is loaded if you use + ResourceGroupManager::_registerScriptLoader. + @return + A list of file patterns, in the order they should be searched in. + */ + virtual const StringVector& getScriptPatterns(void) const = 0; - /** Parse a script file. - @param stream Weak reference to a data stream which is the source of the script - @param groupName The name of a resource group which should be used if any resources - are created during the parse of this script. - */ - virtual void parseScript(DataStreamPtr& stream, const String& groupName) = 0; + /** Parse a script file. + @param stream Weak reference to a data stream which is the source of the script + @param groupName The name of a resource group which should be used if any resources + are created during the parse of this script. + */ + virtual void parseScript(DataStreamPtr& stream, const String& groupName) = 0; - /** Gets the relative loading order of scripts of this type. - @remarks - There are dependencies between some kinds of scripts, and to enforce - this all implementors of this interface must define a loading order. - @return A value representing the relative loading order of these scripts - compared to other script users, where higher values load later. - */ - virtual Real getLoadingOrder(void) const = 0; + /** Gets the relative loading order of scripts of this type. + @remarks + There are dependencies between some kinds of scripts, and to enforce + this all implementors of this interface must define a loading order. + @return A value representing the relative loading order of these scripts + compared to other script users, where higher values load later. + */ + virtual Real getLoadingOrder(void) const = 0; - }; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreScriptParser.h b/OgreMain/include/OgreScriptParser.h index e2f1647b28c..5044e814ad9 100644 --- a/OgreMain/include/OgreScriptParser.h +++ b/OgreMain/include/OgreScriptParser.h @@ -36,28 +36,28 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ - class _OgreExport ScriptParser : public ScriptCompilerAlloc - { - public: - ScriptParser(); - virtual ~ScriptParser() {} + class _OgreExport ScriptParser : public ScriptCompilerAlloc + { + public: + ScriptParser(); + virtual ~ScriptParser() {} - ConcreteNodeListPtr parse(const ScriptTokenListPtr &tokens); - ConcreteNodeListPtr parseChunk(const ScriptTokenListPtr &tokens); - private: - ScriptToken *getToken(ScriptTokenList::iterator i, ScriptTokenList::iterator end, int offset); - ScriptTokenList::iterator skipNewlines(ScriptTokenList::iterator i, ScriptTokenList::iterator end); - }; - - /** @} */ - /** @} */ + ConcreteNodeListPtr parse(const ScriptTokenListPtr &tokens); + ConcreteNodeListPtr parseChunk(const ScriptTokenListPtr &tokens); + private: + ScriptToken *getToken(ScriptTokenList::iterator i, ScriptTokenList::iterator end, int offset); + ScriptTokenList::iterator skipNewlines(ScriptTokenList::iterator i, ScriptTokenList::iterator end); + }; + + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreScriptTranslator.h b/OgreMain/include/OgreScriptTranslator.h index 05a046c5109..0039d990d4c 100644 --- a/OgreMain/include/OgreScriptTranslator.h +++ b/OgreMain/include/OgreScriptTranslator.h @@ -35,265 +35,265 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre{ - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** This class translates script AST (abstract syntax tree) into - * Ogre resources. It defines a common interface for subclasses - * which perform the actual translation. - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** This class translates script AST (abstract syntax tree) into + * Ogre resources. It defines a common interface for subclasses + * which perform the actual translation. + */ - class _OgreExport ScriptTranslator : public ScriptTranslatorAlloc - { - public: - /** - * This function translates the given node into Ogre resource(s). - * @param compiler The compiler invoking this translator - * @param node The current AST node to be translated - */ - virtual void translate(ScriptCompiler *compiler, const AbstractNodePtr &node) = 0; - protected: - // needs virtual destructor - virtual ~ScriptTranslator() {} - /// Retrieves a new translator from the factories and uses it to process the give node - void processNode(ScriptCompiler *compiler, const AbstractNodePtr &node); + class _OgreExport ScriptTranslator : public ScriptTranslatorAlloc + { + public: + /** + * This function translates the given node into Ogre resource(s). + * @param compiler The compiler invoking this translator + * @param node The current AST node to be translated + */ + virtual void translate(ScriptCompiler *compiler, const AbstractNodePtr &node) = 0; + protected: + // needs virtual destructor + virtual ~ScriptTranslator() {} + /// Retrieves a new translator from the factories and uses it to process the give node + void processNode(ScriptCompiler *compiler, const AbstractNodePtr &node); - /// Retrieves the node iterator at the given index - static AbstractNodeList::const_iterator getNodeAt(const AbstractNodeList &nodes, int index); - /// Converts the node to a boolean and returns true if successful - static bool getBoolean(const AbstractNodePtr &node, bool *result); - /// Converts the node to a string and returns true if successful - static bool getString(const AbstractNodePtr &node, String *result); - /// Converts the node to a Real and returns true if successful - static bool getReal(const AbstractNodePtr &node, Real *result); - /// Converts the node to a float and returns true if successful - static bool getFloat(const AbstractNodePtr &node, float *result); - /// Converts the node to a float and returns true if successful - static bool getDouble(const AbstractNodePtr &node, double *result); - /// Converts the node to an integer and returns true if successful - static bool getInt(const AbstractNodePtr &node, int *result); - /// Converts the node to an unsigned integer and returns true if successful - static bool getUInt(const AbstractNodePtr &node, uint32 *result); - /// Converts the range of nodes to a ColourValue and returns true if successful - static bool getColour(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, ColourValue *result, int maxEntries = 4); - /// Converts the node to a SceneBlendFactor enum and returns true if successful - static bool getSceneBlendFactor(const AbstractNodePtr &node, SceneBlendFactor *sbf); - /// Converts the node to a CompareFunction enum and returns true if successful - static bool getCompareFunction(const AbstractNodePtr &node, CompareFunction *func); - /// Converts the range of nodes to a Matrix4 and returns true if successful - static bool getMatrix4(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, Matrix4 *m); - /// Converts the range of nodes to an array of ints and returns true if successful - static bool getInts(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, int *vals, int count); - /// Converts the range of nodes to an array of floats and returns true if successful - static bool getFloats(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, float *vals, int count); - /// Converts the range of nodes to an array of floats and returns true if successful - static bool getDoubles(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, double *vals, int count); - /// Converts the range of nodes to an array of floats and returns true if successful - static bool getUInts(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, uint *vals, int count); - /// Converts the range of nodes to an array of uint-stored boolean values and returns true if successful - static bool getBooleans(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, uint *vals, int count); - /// Converts the node to a StencilOperation enum and returns true if successful - static bool getStencilOp(const AbstractNodePtr &node, StencilOperation *op); - /// Converts the node to a GpuConstantType enum and returns true if successful - static bool getConstantType(AbstractNodeList::const_iterator i, GpuConstantType *op); + /// Retrieves the node iterator at the given index + static AbstractNodeList::const_iterator getNodeAt(const AbstractNodeList &nodes, int index); + /// Converts the node to a boolean and returns true if successful + static bool getBoolean(const AbstractNodePtr &node, bool *result); + /// Converts the node to a string and returns true if successful + static bool getString(const AbstractNodePtr &node, String *result); + /// Converts the node to a Real and returns true if successful + static bool getReal(const AbstractNodePtr &node, Real *result); + /// Converts the node to a float and returns true if successful + static bool getFloat(const AbstractNodePtr &node, float *result); + /// Converts the node to a float and returns true if successful + static bool getDouble(const AbstractNodePtr &node, double *result); + /// Converts the node to an integer and returns true if successful + static bool getInt(const AbstractNodePtr &node, int *result); + /// Converts the node to an unsigned integer and returns true if successful + static bool getUInt(const AbstractNodePtr &node, uint32 *result); + /// Converts the range of nodes to a ColourValue and returns true if successful + static bool getColour(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, ColourValue *result, int maxEntries = 4); + /// Converts the node to a SceneBlendFactor enum and returns true if successful + static bool getSceneBlendFactor(const AbstractNodePtr &node, SceneBlendFactor *sbf); + /// Converts the node to a CompareFunction enum and returns true if successful + static bool getCompareFunction(const AbstractNodePtr &node, CompareFunction *func); + /// Converts the range of nodes to a Matrix4 and returns true if successful + static bool getMatrix4(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, Matrix4 *m); + /// Converts the range of nodes to an array of ints and returns true if successful + static bool getInts(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, int *vals, int count); + /// Converts the range of nodes to an array of floats and returns true if successful + static bool getFloats(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, float *vals, int count); + /// Converts the range of nodes to an array of floats and returns true if successful + static bool getDoubles(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, double *vals, int count); + /// Converts the range of nodes to an array of floats and returns true if successful + static bool getUInts(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, uint *vals, int count); + /// Converts the range of nodes to an array of uint-stored boolean values and returns true if successful + static bool getBooleans(AbstractNodeList::const_iterator i, AbstractNodeList::const_iterator end, uint *vals, int count); + /// Converts the node to a StencilOperation enum and returns true if successful + static bool getStencilOp(const AbstractNodePtr &node, StencilOperation *op); + /// Converts the node to a GpuConstantType enum and returns true if successful + static bool getConstantType(AbstractNodeList::const_iterator i, GpuConstantType *op); - }; + }; - /** The ScriptTranslatorManager manages the lifetime and access to - * script translators. You register these managers with the - * ScriptCompilerManager tied to specific object types. - * Each manager may manage multiple types. - */ - class ScriptTranslatorManager : public ScriptTranslatorAlloc - { - public: - // required - virtual destructor - virtual ~ScriptTranslatorManager() {} + /** The ScriptTranslatorManager manages the lifetime and access to + * script translators. You register these managers with the + * ScriptCompilerManager tied to specific object types. + * Each manager may manage multiple types. + */ + class ScriptTranslatorManager : public ScriptTranslatorAlloc + { + public: + // required - virtual destructor + virtual ~ScriptTranslatorManager() {} - /// Returns the number of translators being managed - virtual size_t getNumTranslators() const = 0; - /// Returns a manager for the given object abstract node, or null if it is not supported - virtual ScriptTranslator *getTranslator(const AbstractNodePtr&) = 0; - }; + /// Returns the number of translators being managed + virtual size_t getNumTranslators() const = 0; + /// Returns a manager for the given object abstract node, or null if it is not supported + virtual ScriptTranslator *getTranslator(const AbstractNodePtr&) = 0; + }; - /************************************************************************** - * Material compilation section - *************************************************************************/ - class _OgreExport MaterialTranslator : public ScriptTranslator - { - protected: - Material *mMaterial; - Ogre::AliasTextureNamePairList mTextureAliases; - public: - MaterialTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; - - class _OgreExport TechniqueTranslator : public ScriptTranslator - { - protected: - Technique *mTechnique; - public: - TechniqueTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; - - class _OgreExport PassTranslator : public ScriptTranslator - { - protected: - Pass *mPass; - public: - PassTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - protected: - void translateVertexProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); - void translateGeometryProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); - void translateFragmentProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); - void translateTessellationHullProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); - void translateTessellationDomainProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); - void translateComputeProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); - void translateShadowCasterVertexProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); - void translateShadowCasterFragmentProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); - void translateShadowReceiverVertexProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); - void translateShadowReceiverFragmentProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); - }; + /************************************************************************** + * Material compilation section + *************************************************************************/ + class _OgreExport MaterialTranslator : public ScriptTranslator + { + protected: + Material *mMaterial; + Ogre::AliasTextureNamePairList mTextureAliases; + public: + MaterialTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; + + class _OgreExport TechniqueTranslator : public ScriptTranslator + { + protected: + Technique *mTechnique; + public: + TechniqueTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; + + class _OgreExport PassTranslator : public ScriptTranslator + { + protected: + Pass *mPass; + public: + PassTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + protected: + void translateVertexProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); + void translateGeometryProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); + void translateFragmentProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); + void translateTessellationHullProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); + void translateTessellationDomainProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); + void translateComputeProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); + void translateShadowCasterVertexProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); + void translateShadowCasterFragmentProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); + void translateShadowReceiverVertexProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); + void translateShadowReceiverFragmentProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node); + }; - class _OgreExport TextureUnitTranslator : public ScriptTranslator - { - protected: - TextureUnitState *mUnit; - public: - TextureUnitTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; + class _OgreExport TextureUnitTranslator : public ScriptTranslator + { + protected: + TextureUnitState *mUnit; + public: + TextureUnitTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; - class _OgreExport TextureSourceTranslator : public ScriptTranslator - { - public: - TextureSourceTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; + class _OgreExport TextureSourceTranslator : public ScriptTranslator + { + public: + TextureSourceTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; - class _OgreExport GpuProgramTranslator : public ScriptTranslator - { - public: - GpuProgramTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - protected: - void translateGpuProgram(ScriptCompiler *compiler, ObjectAbstractNode *obj); - void translateHighLevelGpuProgram(ScriptCompiler *compiler, ObjectAbstractNode *obj); - void translateUnifiedGpuProgram(ScriptCompiler *compiler, ObjectAbstractNode *obj); - public: - static void translateProgramParameters(ScriptCompiler *compiler, GpuProgramParametersSharedPtr params, ObjectAbstractNode *obj); - }; + class _OgreExport GpuProgramTranslator : public ScriptTranslator + { + public: + GpuProgramTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + protected: + void translateGpuProgram(ScriptCompiler *compiler, ObjectAbstractNode *obj); + void translateHighLevelGpuProgram(ScriptCompiler *compiler, ObjectAbstractNode *obj); + void translateUnifiedGpuProgram(ScriptCompiler *compiler, ObjectAbstractNode *obj); + public: + static void translateProgramParameters(ScriptCompiler *compiler, GpuProgramParametersSharedPtr params, ObjectAbstractNode *obj); + }; - class _OgreExport SharedParamsTranslator : public ScriptTranslator - { - public: - SharedParamsTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + class _OgreExport SharedParamsTranslator : public ScriptTranslator + { + public: + SharedParamsTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); template void translateSharedParamNamed(ScriptCompiler *compiler, GpuSharedParameters *sharedParams, PropertyAbstractNode *prop, String pName, BaseConstantType baseType, GpuConstantType constType); - protected: - }; + protected: + }; - /************************************************************************** - * Particle System section - *************************************************************************/ - class _OgreExport ParticleSystemTranslator : public ScriptTranslator - { - protected: - Ogre::ParticleSystem *mSystem; - public: - ParticleSystemTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; - class _OgreExport ParticleEmitterTranslator : public ScriptTranslator - { - protected: - Ogre::ParticleEmitter *mEmitter; - public: - ParticleEmitterTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; - class _OgreExport ParticleAffectorTranslator : public ScriptTranslator - { - protected: - Ogre::ParticleAffector *mAffector; - public: - ParticleAffectorTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; + /************************************************************************** + * Particle System section + *************************************************************************/ + class _OgreExport ParticleSystemTranslator : public ScriptTranslator + { + protected: + Ogre::ParticleSystem *mSystem; + public: + ParticleSystemTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; + class _OgreExport ParticleEmitterTranslator : public ScriptTranslator + { + protected: + Ogre::ParticleEmitter *mEmitter; + public: + ParticleEmitterTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; + class _OgreExport ParticleAffectorTranslator : public ScriptTranslator + { + protected: + Ogre::ParticleAffector *mAffector; + public: + ParticleAffectorTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; - /************************************************************************** - * Compositor section - *************************************************************************/ - class _OgreExport CompositorTranslator : public ScriptTranslator - { - protected: - Compositor *mCompositor; - public: - CompositorTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; - class _OgreExport CompositionTechniqueTranslator : public ScriptTranslator - { - protected: - CompositionTechnique *mTechnique; - public: - CompositionTechniqueTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; - class _OgreExport CompositionTargetPassTranslator : public ScriptTranslator - { - protected: - CompositionTargetPass *mTarget; - public: - CompositionTargetPassTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; - class _OgreExport CompositionPassTranslator : public ScriptTranslator - { - protected: - CompositionPass *mPass; - public: - CompositionPassTranslator(); - void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); - }; + /************************************************************************** + * Compositor section + *************************************************************************/ + class _OgreExport CompositorTranslator : public ScriptTranslator + { + protected: + Compositor *mCompositor; + public: + CompositorTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; + class _OgreExport CompositionTechniqueTranslator : public ScriptTranslator + { + protected: + CompositionTechnique *mTechnique; + public: + CompositionTechniqueTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; + class _OgreExport CompositionTargetPassTranslator : public ScriptTranslator + { + protected: + CompositionTargetPass *mTarget; + public: + CompositionTargetPassTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; + class _OgreExport CompositionPassTranslator : public ScriptTranslator + { + protected: + CompositionPass *mPass; + public: + CompositionPassTranslator(); + void translate(ScriptCompiler *compiler, const AbstractNodePtr &node); + }; - /************************************************************************** - * BuiltinScriptTranslatorManager - *************************************************************************/ - /// This class manages the builtin translators - class _OgreExport BuiltinScriptTranslatorManager : public ScriptTranslatorManager - { - private: - MaterialTranslator mMaterialTranslator; - TechniqueTranslator mTechniqueTranslator; - PassTranslator mPassTranslator; - TextureUnitTranslator mTextureUnitTranslator; - TextureSourceTranslator mTextureSourceTranslator; - GpuProgramTranslator mGpuProgramTranslator; - SharedParamsTranslator mSharedParamsTranslator; - ParticleSystemTranslator mParticleSystemTranslator; - ParticleEmitterTranslator mParticleEmitterTranslator; - ParticleAffectorTranslator mParticleAffectorTranslator; - CompositorTranslator mCompositorTranslator; - CompositionTechniqueTranslator mCompositionTechniqueTranslator; - CompositionTargetPassTranslator mCompositionTargetPassTranslator; - CompositionPassTranslator mCompositionPassTranslator; - public: - BuiltinScriptTranslatorManager(); - /// Returns the number of translators being managed - virtual size_t getNumTranslators() const; - /// Returns a manager for the given object abstract node, or null if it is not supported - virtual ScriptTranslator *getTranslator(const AbstractNodePtr &node); - }; - /** @} */ - /** @} */ + /************************************************************************** + * BuiltinScriptTranslatorManager + *************************************************************************/ + /// This class manages the builtin translators + class _OgreExport BuiltinScriptTranslatorManager : public ScriptTranslatorManager + { + private: + MaterialTranslator mMaterialTranslator; + TechniqueTranslator mTechniqueTranslator; + PassTranslator mPassTranslator; + TextureUnitTranslator mTextureUnitTranslator; + TextureSourceTranslator mTextureSourceTranslator; + GpuProgramTranslator mGpuProgramTranslator; + SharedParamsTranslator mSharedParamsTranslator; + ParticleSystemTranslator mParticleSystemTranslator; + ParticleEmitterTranslator mParticleEmitterTranslator; + ParticleAffectorTranslator mParticleAffectorTranslator; + CompositorTranslator mCompositorTranslator; + CompositionTechniqueTranslator mCompositionTechniqueTranslator; + CompositionTargetPassTranslator mCompositionTargetPassTranslator; + CompositionPassTranslator mCompositionPassTranslator; + public: + BuiltinScriptTranslatorManager(); + /// Returns the number of translators being managed + virtual size_t getNumTranslators() const; + /// Returns a manager for the given object abstract node, or null if it is not supported + virtual ScriptTranslator *getTranslator(const AbstractNodePtr &node); + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreSerializer.h b/OgreMain/include/OgreSerializer.h index 48e4154a94e..d04a5f33c02 100644 --- a/OgreMain/include/OgreSerializer.h +++ b/OgreMain/include/OgreSerializer.h @@ -38,33 +38,33 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** Generic class for serialising data to / from binary stream-based files. + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** Generic class for serialising data to / from binary stream-based files. @remarks This class provides a number of useful methods for exporting / importing data from stream-oriented binary files (e.g. .mesh and .skeleton). */ - class _OgreExport Serializer : public SerializerAlloc + class _OgreExport Serializer : public SerializerAlloc { public: Serializer(); virtual ~Serializer(); - /// The endianness of written files - enum Endian - { - /// Use the platform native endian - ENDIAN_NATIVE, - /// Use big endian (0x1000 is serialised as 0x10 0x00) - ENDIAN_BIG, - /// Use little endian (0x1000 is serialised as 0x00 0x10) - ENDIAN_LITTLE - }; + /// The endianness of written files + enum Endian + { + /// Use the platform native endian + ENDIAN_NATIVE, + /// Use big endian (0x1000 is serialised as 0x10 0x00) + ENDIAN_BIG, + /// Use little endian (0x1000 is serialised as 0x00 0x10) + ENDIAN_LITTLE + }; protected: @@ -72,7 +72,7 @@ namespace Ogre { uint32 mCurrentstreamLen; DataStreamPtr mStream; String mVersion; - bool mFlipEndian; /// Default to native endian, derive from header + bool mFlipEndian; /// Default to native endian, derive from header // Internal methods virtual void writeFileHeader(void); @@ -111,22 +111,22 @@ namespace Ogre { virtual void flipEndian(void * pData, size_t size, size_t count); virtual void flipEndian(void * pData, size_t size); - /// Determine the endianness of the incoming stream compared to native - virtual void determineEndianness(DataStreamPtr& stream); - /// Determine the endianness to write with based on option - virtual void determineEndianness(Endian requestedEndian); + /// Determine the endianness of the incoming stream compared to native + virtual void determineEndianness(DataStreamPtr& stream); + /// Determine the endianness to write with based on option + virtual void determineEndianness(Endian requestedEndian); #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - typedef vector::type ChunkSizeStack; - ChunkSizeStack mChunkSizeStack; - bool mReportChunkErrors; + typedef vector::type ChunkSizeStack; + ChunkSizeStack mChunkSizeStack; + bool mReportChunkErrors; #endif - virtual void pushInnerChunk(const DataStreamPtr& stream); - virtual void popInnerChunk(const DataStreamPtr& stream); - virtual void backpedalChunkHeader(DataStreamPtr& stream); + virtual void pushInnerChunk(const DataStreamPtr& stream); + virtual void popInnerChunk(const DataStreamPtr& stream); + virtual void backpedalChunkHeader(DataStreamPtr& stream); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreShadowCameraSetup.h b/OgreMain/include/OgreShadowCameraSetup.h index 3a5fb6a263f..c48ba8573f7 100644 --- a/OgreMain/include/OgreShadowCameraSetup.h +++ b/OgreMain/include/OgreShadowCameraSetup.h @@ -33,69 +33,69 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** This class allows you to plug in new ways to define the camera setup when - rendering and projecting shadow textures. - @remarks - The default projection used when rendering shadow textures is a uniform - frustum. This is pretty straight forward but doesn't make the best use of - the space in the shadow map since texels closer to the camera will be larger, - resulting in 'jaggies'. There are several ways to distribute the texels - in the shadow texture differently, and this class allows you to override - that. - @par - Ogre is provided with several alternative shadow camera setups, including - LiSPSM (LiSPSMShadowCameraSetup) and Plane Optimal (PlaneOptimalShadowCameraSetup). - Others can of course be written to incorporate other algorithms. All you - have to do is instantiate one of these classes and enable it using - SceneManager::setShadowCameraSetup (global) or Light::setCustomShadowCameraSetup - (per light). In both cases the instance is wrapped in a SharedPtr which means - it will be deleted automatically when no more references to it exist. - @note + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** This class allows you to plug in new ways to define the camera setup when + rendering and projecting shadow textures. + @remarks + The default projection used when rendering shadow textures is a uniform + frustum. This is pretty straight forward but doesn't make the best use of + the space in the shadow map since texels closer to the camera will be larger, + resulting in 'jaggies'. There are several ways to distribute the texels + in the shadow texture differently, and this class allows you to override + that. + @par + Ogre is provided with several alternative shadow camera setups, including + LiSPSM (LiSPSMShadowCameraSetup) and Plane Optimal (PlaneOptimalShadowCameraSetup). + Others can of course be written to incorporate other algorithms. All you + have to do is instantiate one of these classes and enable it using + SceneManager::setShadowCameraSetup (global) or Light::setCustomShadowCameraSetup + (per light). In both cases the instance is wrapped in a SharedPtr which means + it will be deleted automatically when no more references to it exist. + @note Shadow map matrices, being projective matrices, have 15 degrees of freedom. - 3 of these degrees of freedom are fixed by the light's position. 4 are used to - affinely affect z values. 6 affinely affect u,v sampling. 2 are projective - degrees of freedom. This class is meant to allow custom methods for - handling optimization. + 3 of these degrees of freedom are fixed by the light's position. 4 are used to + affinely affect z values. 6 affinely affect u,v sampling. 2 are projective + degrees of freedom. This class is meant to allow custom methods for + handling optimization. */ - class _OgreExport ShadowCameraSetup : public ShadowDataAlloc - { - public: - /// Function to implement -- must set the shadow camera properties - virtual void getShadowCamera (const SceneManager *sm, const Camera *cam, - const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const = 0; - /// Need virtual destructor in case subclasses use it - virtual ~ShadowCameraSetup() {} + class _OgreExport ShadowCameraSetup : public ShadowDataAlloc + { + public: + /// Function to implement -- must set the shadow camera properties + virtual void getShadowCamera (const SceneManager *sm, const Camera *cam, + const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const = 0; + /// Need virtual destructor in case subclasses use it + virtual ~ShadowCameraSetup() {} - }; + }; - /** Implements default shadow camera setup + /** Implements default shadow camera setup @remarks This implements the default shadow camera setup algorithm. This is what might - be referred to as "normal" shadow mapping. + be referred to as "normal" shadow mapping. */ - class _OgreExport DefaultShadowCameraSetup : public ShadowCameraSetup - { - public: - /// Default constructor - DefaultShadowCameraSetup(); - /// Destructor - virtual ~DefaultShadowCameraSetup(); - - /// Default shadow camera setup - virtual void getShadowCamera (const SceneManager *sm, const Camera *cam, - const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const; - }; - - /** @} */ - /** @} */ + class _OgreExport DefaultShadowCameraSetup : public ShadowCameraSetup + { + public: + /// Default constructor + DefaultShadowCameraSetup(); + /// Destructor + virtual ~DefaultShadowCameraSetup(); + + /// Default shadow camera setup + virtual void getShadowCamera (const SceneManager *sm, const Camera *cam, + const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const; + }; + + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreShadowCameraSetupFocused.h b/OgreMain/include/OgreShadowCameraSetupFocused.h index 2506f12f90b..1f10bba7a19 100644 --- a/OgreMain/include/OgreShadowCameraSetupFocused.h +++ b/OgreMain/include/OgreShadowCameraSetupFocused.h @@ -115,7 +115,7 @@ namespace Ogre { /** Returns the bounding box representation. */ - const AxisAlignedBox& getAAB(void) const; + const AxisAlignedBox& getAAB(void) const; /** Adds a specific point to the body list. */ diff --git a/OgreMain/include/OgreShadowCameraSetupLiSPSM.h b/OgreMain/include/OgreShadowCameraSetupLiSPSM.h index b9cde619ea9..bc2b3c7561f 100644 --- a/OgreMain/include/OgreShadowCameraSetupLiSPSM.h +++ b/OgreMain/include/OgreShadowCameraSetupLiSPSM.h @@ -5,7 +5,7 @@ This source file is part of OGRE For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd -Copyright (c) 2006 Matthias Fink, netAllied GmbH +Copyright (c) 2006 Matthias Fink, netAllied GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -36,217 +36,217 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Implements the Light Space Perspective Shadow Mapping Algorithm. - @remarks - Implements the LiSPSM algorithm for an advanced shadow map generation. LiSPSM was - developed by Michael Wimmer, Daniel Scherzer and Werner Purgathofer of the TU Wien. - The algorithm was presented on the Eurographics Symposium on Rendering 2004. - @note - Shadow mapping was introduced by Williams in 1978. First a depth image is rendered - from the light's view and compared in a second pass with depth values of the normal - camera view. In case the depth camera's depth value is greater than the depth seen - by the light the fragment lies in the shadow. - The concept has a major draw back named perspective aliasing. The shadow map distri- - butes the samples uniformly meaning the position of the viewer is ignored. For the - viewer however the perspective projection affects near objects to be displayed - bigger than further away objects. The same thing happens with the shadow map texels: - Near shadows appear very coarse and far away shadows are perfectly sampled. - In 2002 Stamminger et al. presented an algorithm called Perspective Shadow Maps - (PSM). PSM battles the perspective aliasing by distributing 50% of the shadow map - texels for objects in the range of to - which inverts the problem: The shadows near the viewer are perfectly sampled, - however far away shadow may contain aliasing artefacts. A near clipping plane may be - a problem. But this is not the only one. In the post-perspective space the light - sources are non-intuitively mapped: Directional lights may become point light and - point lights may become directional lights. Also light sinks (opposite of a light - source) may appear. Another problem are shadow casters located behind the viewer. - In post-projective space objects behind the viewer are mapped in front of him with - a flipped up-vector. - LiSPSM battles the light source problem of the post-projective space by rearranging - the light space before transformation in such a way that no special cases appear. - This is done by converting point/spot lights into directional lights. The light - space is arranged in such a way that the light direction equals the inverse UNIT_Y. - In this combination the directional light will neither change its type nor its - direction. Furthermore all visible objects and shadow casters affecting the user's - visible area lie in front of the shadow camera: After building the intersection body - that contains all these objects (body intersection building was introduced with PSM; - have a look at the description for the method "calculateB" for further info) a - frustum around the body's light space bounding box is created. A parameter (called - 'n') automatically adjusts the shadow map sample distribution by specifying the - frustum's view point - near plane which affects the perspective warp. In case the - distance is small the perspecive warp will be strong. As a consequence near objects - will gain quality. - However there are still problems. PSM as well as LiSPSM only devote to minimize - perspective aliasing. Projection aliasing is still a problem, also 'swimming - artefacts' still occur. The LiSPSM quality distribution is very good but not the - best available: Some sources say logarithmic shadow mapping is the non plus ultra, - however others reject this thought. There is a research project on logarithmic shadow - maps. The web page url is http://gamma.cs.unc.edu/logsm/. However there is no techical - report available yet (Oct 23rd, 2006). - @note - More information can be found on the webpage of the TU Wien: - http://www.cg.tuwien.ac.at/research/vr/lispsm/ - @note - Original implementation by Matthias Fink , 2006. - */ - class _OgreExport LiSPSMShadowCameraSetup : public FocusedShadowCameraSetup - { - protected: - /// Warp factor adjustment - Real mOptAdjustFactor; - /// Use simple nopt derivation? - bool mUseSimpleNOpt; - /// Extra calculated warp factor - mutable Real mOptAdjustFactorTweak; - /// Threshold (cos angle) within which to start increasing the opt adjust as camera direction approaches light direction - Real mCosCamLightDirThreshold; + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Implements the Light Space Perspective Shadow Mapping Algorithm. + @remarks + Implements the LiSPSM algorithm for an advanced shadow map generation. LiSPSM was + developed by Michael Wimmer, Daniel Scherzer and Werner Purgathofer of the TU Wien. + The algorithm was presented on the Eurographics Symposium on Rendering 2004. + @note + Shadow mapping was introduced by Williams in 1978. First a depth image is rendered + from the light's view and compared in a second pass with depth values of the normal + camera view. In case the depth camera's depth value is greater than the depth seen + by the light the fragment lies in the shadow. + The concept has a major draw back named perspective aliasing. The shadow map distri- + butes the samples uniformly meaning the position of the viewer is ignored. For the + viewer however the perspective projection affects near objects to be displayed + bigger than further away objects. The same thing happens with the shadow map texels: + Near shadows appear very coarse and far away shadows are perfectly sampled. + In 2002 Stamminger et al. presented an algorithm called Perspective Shadow Maps + (PSM). PSM battles the perspective aliasing by distributing 50% of the shadow map + texels for objects in the range of to + which inverts the problem: The shadows near the viewer are perfectly sampled, + however far away shadow may contain aliasing artefacts. A near clipping plane may be + a problem. But this is not the only one. In the post-perspective space the light + sources are non-intuitively mapped: Directional lights may become point light and + point lights may become directional lights. Also light sinks (opposite of a light + source) may appear. Another problem are shadow casters located behind the viewer. + In post-projective space objects behind the viewer are mapped in front of him with + a flipped up-vector. + LiSPSM battles the light source problem of the post-projective space by rearranging + the light space before transformation in such a way that no special cases appear. + This is done by converting point/spot lights into directional lights. The light + space is arranged in such a way that the light direction equals the inverse UNIT_Y. + In this combination the directional light will neither change its type nor its + direction. Furthermore all visible objects and shadow casters affecting the user's + visible area lie in front of the shadow camera: After building the intersection body + that contains all these objects (body intersection building was introduced with PSM; + have a look at the description for the method "calculateB" for further info) a + frustum around the body's light space bounding box is created. A parameter (called + 'n') automatically adjusts the shadow map sample distribution by specifying the + frustum's view point - near plane which affects the perspective warp. In case the + distance is small the perspecive warp will be strong. As a consequence near objects + will gain quality. + However there are still problems. PSM as well as LiSPSM only devote to minimize + perspective aliasing. Projection aliasing is still a problem, also 'swimming + artefacts' still occur. The LiSPSM quality distribution is very good but not the + best available: Some sources say logarithmic shadow mapping is the non plus ultra, + however others reject this thought. There is a research project on logarithmic shadow + maps. The web page url is http://gamma.cs.unc.edu/logsm/. However there is no techical + report available yet (Oct 23rd, 2006). + @note + More information can be found on the webpage of the TU Wien: + http://www.cg.tuwien.ac.at/research/vr/lispsm/ + @note + Original implementation by Matthias Fink , 2006. + */ + class _OgreExport LiSPSMShadowCameraSetup : public FocusedShadowCameraSetup + { + protected: + /// Warp factor adjustment + Real mOptAdjustFactor; + /// Use simple nopt derivation? + bool mUseSimpleNOpt; + /// Extra calculated warp factor + mutable Real mOptAdjustFactorTweak; + /// Threshold (cos angle) within which to start increasing the opt adjust as camera direction approaches light direction + Real mCosCamLightDirThreshold; - /** Calculates the LiSPSM projection matrix P. - @remarks - The LiSPSM projection matrix will be built around the axis aligned bounding box - of the intersection body B in light space. The distance between the near plane - and the projection center is chosen in such a way (distance is set by the para- - meter n) that the perspective error is the same on the near and far plane. In - case P equals the identity matrix the algorithm falls back to a uniform shadow - mapping matrix. - @param lightSpace Matrix of the light space transformation - @param bodyB Intersection body B - @param bodyLVS Intersection body LVS (relevant space in front of the camera) - @param sm Scene manager - @param cam Currently active camera - @param light Currently active light - */ - Matrix4 calculateLiSPSM(const Matrix4& lightSpace, const PointListBody& bodyB, - const PointListBody& bodyLVS, const SceneManager& sm, - const Camera& cam, const Light& light) const; + /** Calculates the LiSPSM projection matrix P. + @remarks + The LiSPSM projection matrix will be built around the axis aligned bounding box + of the intersection body B in light space. The distance between the near plane + and the projection center is chosen in such a way (distance is set by the para- + meter n) that the perspective error is the same on the near and far plane. In + case P equals the identity matrix the algorithm falls back to a uniform shadow + mapping matrix. + @param lightSpace Matrix of the light space transformation + @param bodyB Intersection body B + @param bodyLVS Intersection body LVS (relevant space in front of the camera) + @param sm Scene manager + @param cam Currently active camera + @param light Currently active light + */ + Matrix4 calculateLiSPSM(const Matrix4& lightSpace, const PointListBody& bodyB, + const PointListBody& bodyLVS, const SceneManager& sm, + const Camera& cam, const Light& light) const; - /** Calculates the distance between camera position and near clipping plane. - @remarks - n_opt determines the distance between light space origin (shadow camera position) - and the near clipping plane to achieve an optimal perspective foreshortening effect. - In this way the texel distribution over the shadow map is controlled. + /** Calculates the distance between camera position and near clipping plane. + @remarks + n_opt determines the distance between light space origin (shadow camera position) + and the near clipping plane to achieve an optimal perspective foreshortening effect. + In this way the texel distribution over the shadow map is controlled. - Formula: - d - n_opt = --------------- - sqrt(z1/z0) - 1 + Formula: + d + n_opt = --------------- + sqrt(z1/z0) - 1 - Parameters: - d: distance between the near and the far clipping plane - z0: located on the near clipping plane of the intersection body b - z1: located on the far clipping plane with the same x/y values as z0 - @note - A positive value is applied as the distance between viewer and near clipping plane. - In case null is returned uniform shadow mapping will be applied. - @param lightSpace Matrix of the light space transformation - @param bodyBABB_ls Bounding box of the transformed (light space) bodyB - @param bodyLVS Point list of the bodyLVS which describes the scene space which is in - front of the light and the camera - @param cam Currently active camera - */ - Real calculateNOpt(const Matrix4& lightSpace, const AxisAlignedBox& bodyBABB_ls, - const PointListBody& bodyLVS, const Camera& cam) const; + Parameters: + d: distance between the near and the far clipping plane + z0: located on the near clipping plane of the intersection body b + z1: located on the far clipping plane with the same x/y values as z0 + @note + A positive value is applied as the distance between viewer and near clipping plane. + In case null is returned uniform shadow mapping will be applied. + @param lightSpace Matrix of the light space transformation + @param bodyBABB_ls Bounding box of the transformed (light space) bodyB + @param bodyLVS Point list of the bodyLVS which describes the scene space which is in + front of the light and the camera + @param cam Currently active camera + */ + Real calculateNOpt(const Matrix4& lightSpace, const AxisAlignedBox& bodyBABB_ls, + const PointListBody& bodyLVS, const Camera& cam) const; - /** Calculates a simpler version than the one above. - */ - Real calculateNOptSimple(const PointListBody& bodyLVS, - const Camera& cam) const; + /** Calculates a simpler version than the one above. + */ + Real calculateNOptSimple(const PointListBody& bodyLVS, + const Camera& cam) const; - /** Calculates the visible point on the near plane for the n_opt calculation - @remarks - z0 lies on the parallel plane to the near plane through e and on the near plane of - the frustum C (plane z = bodyB_zMax_ls) and on the line x = e.x. - @param lightSpace Matrix of the light space transformation - @param e The LiSPSM parameter e is located near or on the near clipping plane of the - LiSPSM frustum C - @param bodyB_zMax_ls Maximum z-value of the light space bodyB bounding box - @param cam Currently active camera - */ - Vector3 calculateZ0_ls(const Matrix4& lightSpace, const Vector3& e, Real bodyB_zMax_ls, - const Camera& cam) const; + /** Calculates the visible point on the near plane for the n_opt calculation + @remarks + z0 lies on the parallel plane to the near plane through e and on the near plane of + the frustum C (plane z = bodyB_zMax_ls) and on the line x = e.x. + @param lightSpace Matrix of the light space transformation + @param e The LiSPSM parameter e is located near or on the near clipping plane of the + LiSPSM frustum C + @param bodyB_zMax_ls Maximum z-value of the light space bodyB bounding box + @param cam Currently active camera + */ + Vector3 calculateZ0_ls(const Matrix4& lightSpace, const Vector3& e, Real bodyB_zMax_ls, + const Camera& cam) const; - /** Builds a frustum matrix. - @remarks - Builds a standard frustum matrix out of the distance info of the six frustum - clipping planes. - */ - Matrix4 buildFrustumProjection(Real left, Real right, Real bottom, - Real top, Real near, Real far) const; + /** Builds a frustum matrix. + @remarks + Builds a standard frustum matrix out of the distance info of the six frustum + clipping planes. + */ + Matrix4 buildFrustumProjection(Real left, Real right, Real bottom, + Real top, Real near, Real far) const; - public: - /** Default constructor. - @remarks - Nothing done here. - */ - LiSPSMShadowCameraSetup(void); + public: + /** Default constructor. + @remarks + Nothing done here. + */ + LiSPSMShadowCameraSetup(void); - /** Default destructor. - @remarks - Nothing done here. - */ - virtual ~LiSPSMShadowCameraSetup(void); + /** Default destructor. + @remarks + Nothing done here. + */ + virtual ~LiSPSMShadowCameraSetup(void); - /** Returns a LiSPSM shadow camera. - @remarks - Builds and returns a LiSPSM shadow camera. - More information can be found on the webpage of the TU Wien: - http://www.cg.tuwien.ac.at/research/vr/lispsm/ - */ - virtual void getShadowCamera(const SceneManager *sm, const Camera *cam, - const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const; + /** Returns a LiSPSM shadow camera. + @remarks + Builds and returns a LiSPSM shadow camera. + More information can be found on the webpage of the TU Wien: + http://www.cg.tuwien.ac.at/research/vr/lispsm/ + */ + virtual void getShadowCamera(const SceneManager *sm, const Camera *cam, + const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const; - /** Adjusts the parameter n to produce optimal shadows. - @remarks - The smaller the parameter n, the stronger the perspective warping effect. - The consequence of a stronger warping is that the near shadows will gain - quality while the far ones will lose it. Depending on your scene and light - types you may want to tweak this value - for example directional lights - tend to benefit from higher values of n than other types of light, - especially if you expect to see more distant shadows (say if the viewpoint is - higher above the ground plane). Remember that you can supply separate - ShadowCameraSetup instances configured differently per light if you wish. - @param n The adjustment factor - default is 0.1f. - */ - virtual void setOptimalAdjustFactor(Real n) { mOptAdjustFactor = n; } - /** Get the parameter n used to produce optimal shadows. - @see setOptimalAdjustFactor - */ - virtual Real getOptimalAdjustFactor() const { return mOptAdjustFactor; } - /** Sets whether or not to use a slightly simpler version of the - camera near point derivation (default is true) - */ - virtual void setUseSimpleOptimalAdjust(bool s) { mUseSimpleNOpt = s; } - /** Gets whether or not to use a slightly simpler version of the - camera near point derivation (default is true) - */ - virtual bool getUseSimpleOptimalAdjust() const { return mUseSimpleNOpt; } + /** Adjusts the parameter n to produce optimal shadows. + @remarks + The smaller the parameter n, the stronger the perspective warping effect. + The consequence of a stronger warping is that the near shadows will gain + quality while the far ones will lose it. Depending on your scene and light + types you may want to tweak this value - for example directional lights + tend to benefit from higher values of n than other types of light, + especially if you expect to see more distant shadows (say if the viewpoint is + higher above the ground plane). Remember that you can supply separate + ShadowCameraSetup instances configured differently per light if you wish. + @param n The adjustment factor - default is 0.1f. + */ + virtual void setOptimalAdjustFactor(Real n) { mOptAdjustFactor = n; } + /** Get the parameter n used to produce optimal shadows. + @see setOptimalAdjustFactor + */ + virtual Real getOptimalAdjustFactor() const { return mOptAdjustFactor; } + /** Sets whether or not to use a slightly simpler version of the + camera near point derivation (default is true) + */ + virtual void setUseSimpleOptimalAdjust(bool s) { mUseSimpleNOpt = s; } + /** Gets whether or not to use a slightly simpler version of the + camera near point derivation (default is true) + */ + virtual bool getUseSimpleOptimalAdjust() const { return mUseSimpleNOpt; } - /** Sets the threshold between the camera and the light direction below - which the LiSPSM projection is 'flattened', since coincident light - and camera projections cause problems with the perspective skew. - @remarks - For example, setting this to 20 degrees will mean that as the difference - between the light and camera direction reduces from 20 degrees to 0 - degrees, the perspective skew will be proportionately removed. - */ - virtual void setCameraLightDirectionThreshold(Degree angle); + /** Sets the threshold between the camera and the light direction below + which the LiSPSM projection is 'flattened', since coincident light + and camera projections cause problems with the perspective skew. + @remarks + For example, setting this to 20 degrees will mean that as the difference + between the light and camera direction reduces from 20 degrees to 0 + degrees, the perspective skew will be proportionately removed. + */ + virtual void setCameraLightDirectionThreshold(Degree angle); - /** Sets the threshold between the camera and the light direction below - which the LiSPSM projection is 'flattened', since coincident light - and camera projections cause problems with the perspective skew. - */ - virtual Degree getCameraLightDirectionThreshold() const; + /** Sets the threshold between the camera and the light direction below + which the LiSPSM projection is 'flattened', since coincident light + and camera projections cause problems with the perspective skew. + */ + virtual Degree getCameraLightDirectionThreshold() const; - }; - /** @} */ - /** @} */ + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreShadowCameraSetupPSSM.h b/OgreMain/include/OgreShadowCameraSetupPSSM.h index d9c2222aed2..1ca707a03f9 100644 --- a/OgreMain/include/OgreShadowCameraSetupPSSM.h +++ b/OgreMain/include/OgreShadowCameraSetupPSSM.h @@ -5,7 +5,7 @@ This source file is part of OGRE For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd -Copyright (c) 2006 Matthias Fink, netAllied GmbH +Copyright (c) 2006 Matthias Fink, netAllied GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -36,93 +36,93 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Parallel Split Shadow Map (PSSM) shadow camera setup. - @remarks - A PSSM shadow system uses multiple shadow maps per light and maps each - texture into a region of space, progressing away from the camera. As such - it is most appropriate for directional light setups. This particular version - also uses LiSPSM projection for each split to maximise the quality. - @note - Because PSSM uses multiple shadow maps per light, you will need to increase - the number of shadow textures available (via SceneManager) to match the - number of shadow maps required (default is 3 per light). - */ - class _OgreExport PSSMShadowCameraSetup : public Ogre::LiSPSMShadowCameraSetup - { - public: - typedef vector::type SplitPointList; - typedef vector::type OptimalAdjustFactorList; - - protected: - uint mSplitCount; - SplitPointList mSplitPoints; - OptimalAdjustFactorList mOptimalAdjustFactors; - Real mSplitPadding; - - mutable size_t mCurrentIteration; - - public: - /// Constructor, defaults to 3 splits - PSSMShadowCameraSetup(); - virtual ~PSSMShadowCameraSetup(); - - /** Calculate a new splitting scheme. - @param splitCount The number of splits to use - @param nearDist The near plane to use for the first split - @param farDist The far plane to use for the last split - @param lambda Factor to use to reduce the split size - */ - void calculateSplitPoints(uint splitCount, Real nearDist, Real farDist, Real lambda = 0.95); - - /** Manually configure a new splitting scheme. - @param newSplitPoints A list which is splitCount + 1 entries long, containing the - split points. The first value is the near point, the last value is the - far point, and each value in between is both a far point of the previous - split, and a near point for the next one. - */ - void setSplitPoints(const SplitPointList& newSplitPoints); - - /** Set the LiSPSM optimal adjust factor for a given split (call after - configuring splits). - */ - void setOptimalAdjustFactor(size_t splitIndex, Real factor); - - /** Set the padding factor to apply to the near & far distances when matching up - splits to one another, to avoid 'cracks'. - */ - void setSplitPadding(Real pad) { mSplitPadding = pad; } - - /** Get the padding factor to apply to the near & far distances when matching up - splits to one another, to avoid 'cracks'. - */ - Real getSplitPadding() const { return mSplitPadding; } - /// Get the number of splits. - uint getSplitCount() const { return mSplitCount; } - - /// Returns a LiSPSM shadow camera with PSSM splits base on iteration. - virtual void getShadowCamera(const Ogre::SceneManager *sm, const Ogre::Camera *cam, - const Ogre::Viewport *vp, const Ogre::Light *light, Ogre::Camera *texCam, size_t iteration) const; - - /// Returns the calculated split points. - inline const SplitPointList& getSplitPoints() const - { return mSplitPoints; } - - /// Returns the optimal adjust factor for a given split. - inline Real getOptimalAdjustFactor(size_t splitIndex) const - { return mOptimalAdjustFactors[splitIndex]; } - - /// Overridden, recommended internal use only since depends on current iteration - Real getOptimalAdjustFactor() const; - - }; - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Parallel Split Shadow Map (PSSM) shadow camera setup. + @remarks + A PSSM shadow system uses multiple shadow maps per light and maps each + texture into a region of space, progressing away from the camera. As such + it is most appropriate for directional light setups. This particular version + also uses LiSPSM projection for each split to maximise the quality. + @note + Because PSSM uses multiple shadow maps per light, you will need to increase + the number of shadow textures available (via SceneManager) to match the + number of shadow maps required (default is 3 per light). + */ + class _OgreExport PSSMShadowCameraSetup : public Ogre::LiSPSMShadowCameraSetup + { + public: + typedef vector::type SplitPointList; + typedef vector::type OptimalAdjustFactorList; + + protected: + uint mSplitCount; + SplitPointList mSplitPoints; + OptimalAdjustFactorList mOptimalAdjustFactors; + Real mSplitPadding; + + mutable size_t mCurrentIteration; + + public: + /// Constructor, defaults to 3 splits + PSSMShadowCameraSetup(); + virtual ~PSSMShadowCameraSetup(); + + /** Calculate a new splitting scheme. + @param splitCount The number of splits to use + @param nearDist The near plane to use for the first split + @param farDist The far plane to use for the last split + @param lambda Factor to use to reduce the split size + */ + void calculateSplitPoints(uint splitCount, Real nearDist, Real farDist, Real lambda = 0.95); + + /** Manually configure a new splitting scheme. + @param newSplitPoints A list which is splitCount + 1 entries long, containing the + split points. The first value is the near point, the last value is the + far point, and each value in between is both a far point of the previous + split, and a near point for the next one. + */ + void setSplitPoints(const SplitPointList& newSplitPoints); + + /** Set the LiSPSM optimal adjust factor for a given split (call after + configuring splits). + */ + void setOptimalAdjustFactor(size_t splitIndex, Real factor); + + /** Set the padding factor to apply to the near & far distances when matching up + splits to one another, to avoid 'cracks'. + */ + void setSplitPadding(Real pad) { mSplitPadding = pad; } + + /** Get the padding factor to apply to the near & far distances when matching up + splits to one another, to avoid 'cracks'. + */ + Real getSplitPadding() const { return mSplitPadding; } + /// Get the number of splits. + uint getSplitCount() const { return mSplitCount; } + + /// Returns a LiSPSM shadow camera with PSSM splits base on iteration. + virtual void getShadowCamera(const Ogre::SceneManager *sm, const Ogre::Camera *cam, + const Ogre::Viewport *vp, const Ogre::Light *light, Ogre::Camera *texCam, size_t iteration) const; + + /// Returns the calculated split points. + inline const SplitPointList& getSplitPoints() const + { return mSplitPoints; } + + /// Returns the optimal adjust factor for a given split. + inline Real getOptimalAdjustFactor(size_t splitIndex) const + { return mOptimalAdjustFactors[splitIndex]; } + + /// Overridden, recommended internal use only since depends on current iteration + Real getOptimalAdjustFactor() const; + + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreShadowCameraSetupPlaneOptimal.h b/OgreMain/include/OgreShadowCameraSetupPlaneOptimal.h index 5f15b4a929f..00072f1e4e3 100644 --- a/OgreMain/include/OgreShadowCameraSetupPlaneOptimal.h +++ b/OgreMain/include/OgreShadowCameraSetupPlaneOptimal.h @@ -35,54 +35,54 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Implements the plane optimal shadow camera algorithm. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Implements the plane optimal shadow camera algorithm. @remarks Given a plane of interest, it is possible to set up the shadow camera - matrix such that the mapping between screen and shadow map is the identity - (when restricted to pixels that view the plane of interest). Therefore, - if the shadow map resolution matches the screen space resolution (of the - seen planar receiver), we can get pixel perfect shadowing on the plane. - Off the plane, the shadowing is not guaranteed to be perfect and will - likely exhibit the usual sampling artifacts associated with shadow mapping. - @note Important: this routine requires double-precision calculations. When you - are running under Direct3D, you must ensure that you set the floating - point mode to 'Consistent' rather than 'Fastest' to ensure this precision. - This does allegedly come with some performance cost but when measuring - it appears to be negligible in modern systems for normal usage. - @note Second important note: this projection also only works for lights with - a finite position. Therefore you cannot use it for directional lights - at this time. + matrix such that the mapping between screen and shadow map is the identity + (when restricted to pixels that view the plane of interest). Therefore, + if the shadow map resolution matches the screen space resolution (of the + seen planar receiver), we can get pixel perfect shadowing on the plane. + Off the plane, the shadowing is not guaranteed to be perfect and will + likely exhibit the usual sampling artifacts associated with shadow mapping. + @note Important: this routine requires double-precision calculations. When you + are running under Direct3D, you must ensure that you set the floating + point mode to 'Consistent' rather than 'Fastest' to ensure this precision. + This does allegedly come with some performance cost but when measuring + it appears to be negligible in modern systems for normal usage. + @note Second important note: this projection also only works for lights with + a finite position. Therefore you cannot use it for directional lights + at this time. */ - class _OgreExport PlaneOptimalShadowCameraSetup : public ShadowCameraSetup - { - private: - MovablePlane* mPlane; ///< pointer to plane of interest - private: - PlaneOptimalShadowCameraSetup() {} ///< Default constructor is private + class _OgreExport PlaneOptimalShadowCameraSetup : public ShadowCameraSetup + { + private: + MovablePlane* mPlane; ///< pointer to plane of interest + private: + PlaneOptimalShadowCameraSetup() {} ///< Default constructor is private - /// helper function computing projection matrix given constraints - Matrix4 computeConstrainedProjection( const Vector4& pinhole, - const vector::type& fpoint, - const vector::type& constraint) const; + /// helper function computing projection matrix given constraints + Matrix4 computeConstrainedProjection( const Vector4& pinhole, + const vector::type& fpoint, + const vector::type& constraint) const; - public: - /// Constructor -- requires a plane of interest - PlaneOptimalShadowCameraSetup(MovablePlane *plane); - /// Destructor - virtual ~PlaneOptimalShadowCameraSetup(); + public: + /// Constructor -- requires a plane of interest + PlaneOptimalShadowCameraSetup(MovablePlane *plane); + /// Destructor + virtual ~PlaneOptimalShadowCameraSetup(); - /// Returns shadow camera configured to get 1-1 homography between screen and shadow map when restricted to plane - virtual void getShadowCamera (const SceneManager *sm, const Camera *cam, - const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const; - }; - /** @} */ - /** @} */ + /// Returns shadow camera configured to get 1-1 homography between screen and shadow map when restricted to plane + virtual void getShadowCamera (const SceneManager *sm, const Camera *cam, + const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const; + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreShadowTextureManager.h b/OgreMain/include/OgreShadowTextureManager.h index c44ce0078fb..ffa43d47251 100644 --- a/OgreMain/include/OgreShadowTextureManager.h +++ b/OgreMain/include/OgreShadowTextureManager.h @@ -38,77 +38,77 @@ Torus Knot Software Ltd. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - typedef vector::type ShadowTextureList; - - /** Structure containing the configuration for one shadow texture. */ - struct ShadowTextureConfig - { - unsigned int width; - unsigned int height; - PixelFormat format; + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + typedef vector::type ShadowTextureList; + + /** Structure containing the configuration for one shadow texture. */ + struct ShadowTextureConfig + { + unsigned int width; + unsigned int height; + PixelFormat format; unsigned int fsaa; - uint16 depthBufferPoolId; - - ShadowTextureConfig() - : width(512), height(512), format(PF_X8R8G8B8), fsaa(0), depthBufferPoolId(1) {} - }; - - typedef vector::type ShadowTextureConfigList; - typedef ConstVectorIterator ConstShadowTextureConfigIterator; - - inline _OgreExport bool operator== ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ); - inline _OgreExport bool operator!= ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ); - - - /** Class to manage the available shadow textures which may be shared between - many SceneManager instances if formats agree. - @remarks - The management of the list of shadow textures has been separated out into - a dedicated class to enable the clean management of shadow textures - across many scene manager instances. Where multiple scene managers are - used with shadow textures, the configuration of those shadows may or may - not be consistent - if it is, it is good to centrally manage the textures - so that creation and destruction responsibility is clear. - */ - class _OgreExport ShadowTextureManager : public Singleton, public ShadowDataAlloc - { - protected: - ShadowTextureList mTextureList; - ShadowTextureList mNullTextureList; - size_t mCount; - - public: - ShadowTextureManager(); - virtual ~ShadowTextureManager(); - - /** Populate an incoming list with shadow texture references as requested - in the configuration list. - */ - virtual void getShadowTextures(const ShadowTextureConfigList& config, - ShadowTextureList& listToPopulate); - - /** Get an appropriately defined 'null' texture, i.e. one which will always - result in no shadows. - */ - virtual TexturePtr getNullShadowTexture(PixelFormat format); - - /** Remove any shadow textures that are no longer being referenced. - @remarks - This should be called fairly regularly since references may take a - little while to disappear in some cases (if referenced by materials) - */ - virtual void clearUnused(); - /** Dereference all the shadow textures kept in this class and remove them - from TextureManager; note that it is up to the SceneManagers to clear - their local references. - */ - virtual void clear(); + uint16 depthBufferPoolId; + + ShadowTextureConfig() + : width(512), height(512), format(PF_X8R8G8B8), fsaa(0), depthBufferPoolId(1) {} + }; + + typedef vector::type ShadowTextureConfigList; + typedef ConstVectorIterator ConstShadowTextureConfigIterator; + + inline _OgreExport bool operator== ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ); + inline _OgreExport bool operator!= ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ); + + + /** Class to manage the available shadow textures which may be shared between + many SceneManager instances if formats agree. + @remarks + The management of the list of shadow textures has been separated out into + a dedicated class to enable the clean management of shadow textures + across many scene manager instances. Where multiple scene managers are + used with shadow textures, the configuration of those shadows may or may + not be consistent - if it is, it is good to centrally manage the textures + so that creation and destruction responsibility is clear. + */ + class _OgreExport ShadowTextureManager : public Singleton, public ShadowDataAlloc + { + protected: + ShadowTextureList mTextureList; + ShadowTextureList mNullTextureList; + size_t mCount; + + public: + ShadowTextureManager(); + virtual ~ShadowTextureManager(); + + /** Populate an incoming list with shadow texture references as requested + in the configuration list. + */ + virtual void getShadowTextures(const ShadowTextureConfigList& config, + ShadowTextureList& listToPopulate); + + /** Get an appropriately defined 'null' texture, i.e. one which will always + result in no shadows. + */ + virtual TexturePtr getNullShadowTexture(PixelFormat format); + + /** Remove any shadow textures that are no longer being referenced. + @remarks + This should be called fairly regularly since references may take a + little while to disappear in some cases (if referenced by materials) + */ + virtual void clearUnused(); + /** Dereference all the shadow textures kept in this class and remove them + from TextureManager; note that it is up to the SceneManagers to clear + their local references. + */ + virtual void clear(); /** Override standard Singleton retrieval. @remarks @@ -143,10 +143,10 @@ namespace Ogre */ static ShadowTextureManager* getSingletonPtr(void); - }; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreShadowVolumeExtrudeProgram.h b/OgreMain/include/OgreShadowVolumeExtrudeProgram.h index bc88764cb6e..c79e39dcb5a 100644 --- a/OgreMain/include/OgreShadowVolumeExtrudeProgram.h +++ b/OgreMain/include/OgreShadowVolumeExtrudeProgram.h @@ -34,13 +34,13 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Static class containing source for vertex programs for extruding shadow volumes + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Static class containing source for vertex programs for extruding shadow volumes @remarks This exists so we don't have to be dependent on an external media files. Assembler is used so we don't have to rely on particular plugins. @@ -48,10 +48,10 @@ namespace Ogre { @code // Point light shadow volume extrude void shadowVolumeExtrudePointLight_vp ( - float4 position : POSITION, - float wcoord : TEXCOORD0, + float4 position : POSITION, + float wcoord : TEXCOORD0, - out float4 oPosition : POSITION, + out float4 oPosition : POSITION, uniform float4x4 worldViewProjMatrix, uniform float4 lightPos // homogeneous, object space @@ -69,10 +69,10 @@ namespace Ogre { // Directional light extrude void shadowVolumeExtrudeDirLight_vp ( - float4 position : POSITION, - float wcoord : TEXCOORD0, + float4 position : POSITION, + float wcoord : TEXCOORD0, - out float4 oPosition : POSITION, + out float4 oPosition : POSITION, uniform float4x4 worldViewProjMatrix, uniform float4 lightPos // homogenous, object space @@ -88,21 +88,21 @@ namespace Ogre { } // Point light shadow volume extrude - FINITE void shadowVolumeExtrudePointLightFinite_vp ( - float4 position : POSITION, - float wcoord : TEXCOORD0, + float4 position : POSITION, + float wcoord : TEXCOORD0, - out float4 oPosition : POSITION, + out float4 oPosition : POSITION, uniform float4x4 worldViewProjMatrix, uniform float4 lightPos, // homogeneous, object space - uniform float extrusionDistance // how far to extrude + uniform float extrusionDistance // how far to extrude ) { // extrusion in object space // vertex unmodified if w==1, extruded if w==0 - float3 extrusionDir = position.xyz - lightPos.xyz; - extrusionDir = normalize(extrusionDir); - + float3 extrusionDir = position.xyz - lightPos.xyz; + extrusionDir = normalize(extrusionDir); + float4 newpos = float4(position.xyz + ((1 - wcoord.x) * extrusionDistance * extrusionDir), 1); @@ -112,81 +112,81 @@ namespace Ogre { // Directional light extrude - FINITE void shadowVolumeExtrudeDirLightFinite_vp ( - float4 position : POSITION, - float wcoord : TEXCOORD0, + float4 position : POSITION, + float wcoord : TEXCOORD0, - out float4 oPosition : POSITION, + out float4 oPosition : POSITION, uniform float4x4 worldViewProjMatrix, uniform float4 lightPos, // homogeneous, object space - uniform float extrusionDistance // how far to extrude + uniform float extrusionDistance // how far to extrude ) { // extrusion in object space // vertex unmodified if w==1, extruded if w==0 - // -ve lightPos is direction + // -ve lightPos is direction float4 newpos = float4(position.xyz - (wcoord.x * extrusionDistance * lightPos.xyz), 1); oPosition = mul(worldViewProjMatrix, newpos); - } + } @endcode */ - class _OgreExport ShadowVolumeExtrudeProgram : public ShadowDataAlloc + class _OgreExport ShadowVolumeExtrudeProgram : public ShadowDataAlloc { private: static String mPointArbvp1; static String mPointVs_1_1; - static String mPointVs_4_0; - static String mPointVs_glsl; - static String mPointVs_glsles; + static String mPointVs_4_0; + static String mPointVs_glsl; + static String mPointVs_glsles; static String mDirArbvp1; static String mDirVs_1_1; - static String mDirVs_4_0; - static String mDirVs_glsl; - static String mDirVs_glsles; + static String mDirVs_4_0; + static String mDirVs_glsl; + static String mDirVs_glsles; // same as above, except the color is set to 1 to enable debug volumes to be seen static String mPointArbvp1Debug; static String mPointVs_1_1Debug; - static String mPointVs_4_0Debug; - static String mPointVs_glslDebug; - static String mPointVs_glslesDebug; + static String mPointVs_4_0Debug; + static String mPointVs_glslDebug; + static String mPointVs_glslesDebug; static String mDirArbvp1Debug; static String mDirVs_1_1Debug; - static String mDirVs_4_0Debug; - static String mDirVs_glslDebug; - static String mDirVs_glslesDebug; - + static String mDirVs_4_0Debug; + static String mDirVs_glslDebug; + static String mDirVs_glslesDebug; + static String mPointArbvp1Finite; static String mPointVs_1_1Finite; - static String mPointVs_4_0Finite; - static String mPointVs_glslFinite; - static String mPointVs_glslesFinite; + static String mPointVs_4_0Finite; + static String mPointVs_glslFinite; + static String mPointVs_glslesFinite; static String mDirArbvp1Finite; static String mDirVs_1_1Finite; - static String mDirVs_4_0Finite; - static String mDirVs_glslFinite; - static String mDirVs_glslesFinite; + static String mDirVs_4_0Finite; + static String mDirVs_glslFinite; + static String mDirVs_glslesFinite; // same as above, except the color is set to 1 to enable debug volumes to be seen static String mPointArbvp1FiniteDebug; static String mPointVs_1_1FiniteDebug; - static String mPointVs_4_0FiniteDebug; - static String mPointVs_glslFiniteDebug; - static String mPointVs_glslesFiniteDebug; + static String mPointVs_4_0FiniteDebug; + static String mPointVs_glslFiniteDebug; + static String mPointVs_glslesFiniteDebug; static String mDirArbvp1FiniteDebug; static String mDirVs_1_1FiniteDebug; - static String mDirVs_4_0FiniteDebug; - static String mDirVs_glslFiniteDebug; - static String mDirVs_glslesFiniteDebug; + static String mDirVs_4_0FiniteDebug; + static String mDirVs_glslFiniteDebug; + static String mDirVs_glslesFiniteDebug; - static String mGeneralFs_4_0; - static String mGeneralFs_glsl; - static String mGeneralFs_glsles; + static String mGeneralFs_4_0; + static String mGeneralFs_glsl; + static String mGeneralFs_glsles; - static bool mInitialised; + static bool mInitialised; - public: + public: #define OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS 8 enum Programs { @@ -209,7 +209,7 @@ namespace Ogre { }; static const String programNames[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS]; - static String frgProgramName; + static String frgProgramName; /// Initialise the creation of these vertex programs static void initialise(void); @@ -219,43 +219,43 @@ namespace Ogre { static const String& getPointLightExtruderArbvp1(void) { return mPointArbvp1; } /// Get extruder program source for point lights, compatible with vs_1_1 static const String& getPointLightExtruderVs_1_1(void) { return mPointVs_1_1; } - /// Get extruder program source for point lights, compatible with vs_4_0 - static const String& getPointLightExtruderVs_4_0(void) { return mPointVs_4_0; } - /// Get extruder program source for point lights, compatible with glsl - static const String& getPointLightExtruderVs_glsl(void) { return mPointVs_glsl; } - /// Get extruder program source for point lights, compatible with glsles - static const String& getPointLightExtruderVs_glsles(void) { return mPointVs_glsles; } + /// Get extruder program source for point lights, compatible with vs_4_0 + static const String& getPointLightExtruderVs_4_0(void) { return mPointVs_4_0; } + /// Get extruder program source for point lights, compatible with glsl + static const String& getPointLightExtruderVs_glsl(void) { return mPointVs_glsl; } + /// Get extruder program source for point lights, compatible with glsles + static const String& getPointLightExtruderVs_glsles(void) { return mPointVs_glsles; } /// Get extruder program source for directional lights, compatible with arbvp1 static const String& getDirectionalLightExtruderArbvp1(void) { return mDirArbvp1; } /// Get extruder program source for directional lights, compatible with vs_1_1 static const String& getDirectionalLightExtruderVs_1_1(void) { return mDirVs_1_1; } - /// Get extruder program source for directional lights, compatible with vs_4_0 - static const String& getDirectionalLightExtruderVs_4_0(void) { return mDirVs_4_0; } - /// Get extruder program source for directional lights, compatible with glsl - static const String& getDirectionalLightExtruderVs_glsl(void) { return mDirVs_glsl; } - /// Get extruder program source for directional lights, compatible with glsles - static const String& getDirectionalLightExtruderVs_glsles(void) { return mDirVs_glsles; } + /// Get extruder program source for directional lights, compatible with vs_4_0 + static const String& getDirectionalLightExtruderVs_4_0(void) { return mDirVs_4_0; } + /// Get extruder program source for directional lights, compatible with glsl + static const String& getDirectionalLightExtruderVs_glsl(void) { return mDirVs_glsl; } + /// Get extruder program source for directional lights, compatible with glsles + static const String& getDirectionalLightExtruderVs_glsles(void) { return mDirVs_glsles; } /// Get extruder program source for debug point lights, compatible with arbvp1 static const String& getPointLightExtruderArbvp1Debug(void) { return mPointArbvp1Debug; } /// Get extruder program source for debug point lights, compatible with vs_1_1 static const String& getPointLightExtruderVs_1_1Debug(void) { return mPointVs_1_1Debug; } - /// Get extruder program source for debug point lights, compatible with vs_4_0 - static const String& getPointLightExtruderVs_4_0Debug(void) { return mPointVs_4_0Debug; } - /// Get extruder program source for debug point lights, compatible with glsl - static const String& getPointLightExtruderVs_glslDebug(void) { return mPointVs_glslDebug; } - /// Get extruder program source for debug point lights, compatible with glsles - static const String& getPointLightExtruderVs_glslesDebug(void) { return mPointVs_glslesDebug; } + /// Get extruder program source for debug point lights, compatible with vs_4_0 + static const String& getPointLightExtruderVs_4_0Debug(void) { return mPointVs_4_0Debug; } + /// Get extruder program source for debug point lights, compatible with glsl + static const String& getPointLightExtruderVs_glslDebug(void) { return mPointVs_glslDebug; } + /// Get extruder program source for debug point lights, compatible with glsles + static const String& getPointLightExtruderVs_glslesDebug(void) { return mPointVs_glslesDebug; } /// Get extruder program source for debug directional lights, compatible with arbvp1 static const String& getDirectionalLightExtruderArbvp1Debug(void) { return mDirArbvp1Debug; } /// Get extruder program source for debug directional lights, compatible with vs_1_1 static const String& getDirectionalLightExtruderVs_1_1Debug(void) { return mDirVs_1_1Debug; } - /// Get extruder program source for debug directional lights, compatible with vs_4_0 - static const String& getDirectionalLightExtruderVs_4_0Debug(void) { return mDirVs_4_0Debug; } - /// Get extruder program source for debug directional lights, compatible with glsl - static const String& getDirectionalLightExtruderVs_glslDebug(void) { return mDirVs_glslDebug; } - /// Get extruder program source for debug directional lights, compatible with glsles - static const String& getDirectionalLightExtruderVs_glslesDebug(void) { return mDirVs_glslesDebug; } + /// Get extruder program source for debug directional lights, compatible with vs_4_0 + static const String& getDirectionalLightExtruderVs_4_0Debug(void) { return mDirVs_4_0Debug; } + /// Get extruder program source for debug directional lights, compatible with glsl + static const String& getDirectionalLightExtruderVs_glslDebug(void) { return mDirVs_glslDebug; } + /// Get extruder program source for debug directional lights, compatible with glsles + static const String& getDirectionalLightExtruderVs_glslesDebug(void) { return mDirVs_glslesDebug; } /// General purpose method to get any of the program sources static const String& getProgramSource(Light::LightTypes lightType, const String &syntax, bool finite, bool debug); @@ -267,47 +267,47 @@ namespace Ogre { static const String& getPointLightExtruderArbvp1Finite(void) { return mPointArbvp1Finite; } /// Get FINITE extruder program source for point lights, compatible with vs_1_1 static const String& getPointLightExtruderVs_1_1Finite(void) { return mPointVs_1_1Finite; } - /// Get FINITE extruder program source for point lights, compatible with vs_4_0 - static const String& getPointLightExtruderVs_4_0Finite(void) { return mPointVs_4_0Finite; } - /// Get FINITE extruder program source for point lights, compatible with glsl - static const String& getPointLightExtruderVs_glslFinite(void) { return mPointVs_glslFinite; } - /// Get FINITE extruder program source for point lights, compatible with glsles - static const String& getPointLightExtruderVs_glslesFinite(void) { return mPointVs_glslesFinite; } + /// Get FINITE extruder program source for point lights, compatible with vs_4_0 + static const String& getPointLightExtruderVs_4_0Finite(void) { return mPointVs_4_0Finite; } + /// Get FINITE extruder program source for point lights, compatible with glsl + static const String& getPointLightExtruderVs_glslFinite(void) { return mPointVs_glslFinite; } + /// Get FINITE extruder program source for point lights, compatible with glsles + static const String& getPointLightExtruderVs_glslesFinite(void) { return mPointVs_glslesFinite; } /// Get FINITE extruder program source for directional lights, compatible with arbvp1 static const String& getDirectionalLightExtruderArbvp1Finite(void) { return mDirArbvp1Finite; } /// Get FINITE extruder program source for directional lights, compatible with vs_1_1 static const String& getDirectionalLightExtruderVs_1_1Finite(void) { return mDirVs_1_1Finite; } - /// Get FINITE extruder program source for directional lights, compatible with vs_4_0 - static const String& getDirectionalLightExtruderVs_4_0Finite(void) { return mDirVs_4_0Finite; } - /// Get FINITE extruder program source for directional lights, compatible with glsl - static const String& getDirectionalLightExtruderVs_glslFinite(void) { return mDirVs_glslFinite; } - /// Get FINITE extruder program source for directional lights, compatible with glsles - static const String& getDirectionalLightExtruderVs_glslesFinite(void) { return mDirVs_glslesFinite; } + /// Get FINITE extruder program source for directional lights, compatible with vs_4_0 + static const String& getDirectionalLightExtruderVs_4_0Finite(void) { return mDirVs_4_0Finite; } + /// Get FINITE extruder program source for directional lights, compatible with glsl + static const String& getDirectionalLightExtruderVs_glslFinite(void) { return mDirVs_glslFinite; } + /// Get FINITE extruder program source for directional lights, compatible with glsles + static const String& getDirectionalLightExtruderVs_glslesFinite(void) { return mDirVs_glslesFinite; } /// Get FINITE extruder program source for debug point lights, compatible with arbvp1 static const String& getPointLightExtruderArbvp1FiniteDebug(void) { return mPointArbvp1FiniteDebug; } /// Get extruder program source for debug point lights, compatible with vs_1_1 static const String& getPointLightExtruderVs_1_1FiniteDebug(void) { return mPointVs_1_1FiniteDebug; } - /// Get extruder program source for debug point lights, compatible with vs_4_0 - static const String& getPointLightExtruderVs_4_0FiniteDebug(void) { return mPointVs_4_0FiniteDebug; } - /// Get extruder program source for debug point lights, compatible with glsl - static const String& getPointLightExtruderVs_glslFiniteDebug(void) { return mPointVs_glslFiniteDebug; } - /// Get extruder program source for debug point lights, compatible with glsles - static const String& getPointLightExtruderVs_glslesFiniteDebug(void) { return mPointVs_glslesFiniteDebug; } + /// Get extruder program source for debug point lights, compatible with vs_4_0 + static const String& getPointLightExtruderVs_4_0FiniteDebug(void) { return mPointVs_4_0FiniteDebug; } + /// Get extruder program source for debug point lights, compatible with glsl + static const String& getPointLightExtruderVs_glslFiniteDebug(void) { return mPointVs_glslFiniteDebug; } + /// Get extruder program source for debug point lights, compatible with glsles + static const String& getPointLightExtruderVs_glslesFiniteDebug(void) { return mPointVs_glslesFiniteDebug; } /// Get FINITE extruder program source for debug directional lights, compatible with arbvp1 static const String& getDirectionalLightExtruderArbvp1FiniteDebug(void) { return mDirArbvp1FiniteDebug; } /// Get FINITE extruder program source for debug directional lights, compatible with vs_1_1 static const String& getDirectionalLightExtruderVs_1_1FiniteDebug(void) { return mDirVs_1_1FiniteDebug; } - /// Get FINITE extruder program source for debug directional lights, compatible with vs_4_0 - static const String& getDirectionalLightExtruderVs_4_0FiniteDebug(void) { return mDirVs_4_0FiniteDebug; } - /// Get FINITE extruder program source for debug directional lights, compatible with glsl - static const String& getDirectionalLightExtruderVs_glslFiniteDebug(void) { return mDirVs_glslFiniteDebug; } - /// Get FINITE extruder program source for debug directional lights, compatible with glsles - static const String& getDirectionalLightExtruderVs_glslesFiniteDebug(void) { return mDirVs_glslesFiniteDebug; } + /// Get FINITE extruder program source for debug directional lights, compatible with vs_4_0 + static const String& getDirectionalLightExtruderVs_4_0FiniteDebug(void) { return mDirVs_4_0FiniteDebug; } + /// Get FINITE extruder program source for debug directional lights, compatible with glsl + static const String& getDirectionalLightExtruderVs_glslFiniteDebug(void) { return mDirVs_glslFiniteDebug; } + /// Get FINITE extruder program source for debug directional lights, compatible with glsles + static const String& getDirectionalLightExtruderVs_glslesFiniteDebug(void) { return mDirVs_glslesFiniteDebug; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreSharedPtr.h b/OgreMain/include/OgreSharedPtr.h index 0ff59f60773..da76c4dbd7b 100644 --- a/OgreMain/include/OgreSharedPtr.h +++ b/OgreMain/include/OgreSharedPtr.h @@ -32,23 +32,23 @@ THE SOFTWARE. #include "OgreAtomicScalar.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - - /// The method to use to free memory on destruction - enum SharedPtrFreeMethod - { - /// Use OGRE_DELETE to free the memory - SPFM_DELETE, - /// Use OGRE_DELETE_T to free (only MEMCATEGORY_GENERAL supported) - SPFM_DELETE_T, - /// Use OGRE_FREE to free (only MEMCATEGORY_GENERAL supported) - SPFM_FREE - }; + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + + /// The method to use to free memory on destruction + enum SharedPtrFreeMethod + { + /// Use OGRE_DELETE to free the memory + SPFM_DELETE, + /// Use OGRE_DELETE_T to free (only MEMCATEGORY_GENERAL supported) + SPFM_DELETE_T, + /// Use OGRE_FREE to free (only MEMCATEGORY_GENERAL supported) + SPFM_FREE + }; struct SharedPtrInfo { inline SharedPtrInfo() @@ -60,58 +60,58 @@ namespace Ogre { AtomicScalar useCount; }; - template - class SharedPtrInfoDelete : public SharedPtrInfo - { + template + class SharedPtrInfoDelete : public SharedPtrInfo + { T* mObject; public: inline SharedPtrInfoDelete(T* o) : mObject(o) {} - virtual ~SharedPtrInfoDelete() - { - OGRE_DELETE mObject; - } - }; + virtual ~SharedPtrInfoDelete() + { + OGRE_DELETE mObject; + } + }; - template - class SharedPtrInfoDeleteT : public SharedPtrInfo - { + template + class SharedPtrInfoDeleteT : public SharedPtrInfo + { T* mObject; public: inline SharedPtrInfoDeleteT(T* o) : mObject(o) {} - virtual ~SharedPtrInfoDeleteT() - { - OGRE_DELETE_T(mObject, T, MEMCATEGORY_GENERAL); - } - }; + virtual ~SharedPtrInfoDeleteT() + { + OGRE_DELETE_T(mObject, T, MEMCATEGORY_GENERAL); + } + }; - template - class SharedPtrInfoFree : public SharedPtrInfo - { + template + class SharedPtrInfoFree : public SharedPtrInfo + { T* mObject; public: inline SharedPtrInfoFree(T* o) : mObject(o) {} - virtual ~SharedPtrInfoFree() - { - OGRE_FREE(mObject, MEMCATEGORY_GENERAL); - } - }; + virtual ~SharedPtrInfoFree() + { + OGRE_FREE(mObject, MEMCATEGORY_GENERAL); + } + }; - /** Reference-counted shared pointer, used for objects where implicit destruction is + /** Reference-counted shared pointer, used for objects where implicit destruction is required. @remarks This is a standard shared pointer implementation which uses a reference count to work out when to delete the object. - @par - If OGRE_THREAD_SUPPORT is defined to be 1, use of this class is thread-safe. + @par + If OGRE_THREAD_SUPPORT is defined to be 1, use of this class is thread-safe. */ - template class SharedPtr - { + template class SharedPtr + { template friend class SharedPtr; - protected: + protected: /* DO NOT ADD MEMBERS TO THIS CLASS! * * The average Ogre application has *thousands* of them. Every extra @@ -124,19 +124,19 @@ namespace Ogre { * There is no reason for this object to ever have more than two members. */ - T* pRep; + T* pRep; SharedPtrInfo* pInfo; SharedPtr(T* rep, SharedPtrInfo* info) : pRep(rep), pInfo(info) - { - } - - public: - /** Constructor, does not initialise the SharedPtr. - @remarks - Dangerous! You have to call bind() before using the SharedPtr. - */ - SharedPtr() : pRep(0), pInfo(0) + { + } + + public: + /** Constructor, does not initialise the SharedPtr. + @remarks + Dangerous! You have to call bind() before using the SharedPtr. + */ + SharedPtr() : pRep(0), pInfo(0) {} private: @@ -152,41 +152,41 @@ namespace Ogre { } public: - /** Constructor. - @param rep The pointer to take ownership of - @param inFreeMethod The mechanism to use to free the pointer - */ + /** Constructor. + @param rep The pointer to take ownership of + @param inFreeMethod The mechanism to use to free the pointer + */ template< class Y> - explicit SharedPtr(Y* rep, SharedPtrFreeMethod inFreeMethod = SPFM_DELETE) + explicit SharedPtr(Y* rep, SharedPtrFreeMethod inFreeMethod = SPFM_DELETE) : pRep(rep) , pInfo(rep ? createInfoForMethod(rep, inFreeMethod) : 0) - { - } + { + } - SharedPtr(const SharedPtr& r) + SharedPtr(const SharedPtr& r) : pRep(r.pRep) , pInfo(r.pInfo) - { + { if (pRep) { ++pInfo->useCount; } - } + } - SharedPtr& operator=(const SharedPtr& r) { - if (pRep == r.pRep) + SharedPtr& operator=(const SharedPtr& r) { + if (pRep == r.pRep) { assert(pInfo == r.pInfo); - return *this; + return *this; } - // Swap current data into a local copy - // this ensures we deal with rhs and this being dependent - SharedPtr tmp(r); - swap(tmp); - return *this; - } - - /* For C++11 compilers, use enable_if to only expose functions when viable + // Swap current data into a local copy + // this ensures we deal with rhs and this being dependent + SharedPtr tmp(r); + swap(tmp); + return *this; + } + + /* For C++11 compilers, use enable_if to only expose functions when viable * * MSVC 2012 and earlier only claim conformance to C++98. This is fortunate, * because they don't support default template parameters @@ -200,14 +200,14 @@ namespace Ogre { SharedPtr(const SharedPtr& r) : pRep(r.getPointer()) , pInfo(r.pInfo) - { + { if (pRep) { ++pInfo->useCount; } } - + #if __cplusplus >= 201103L template::value>::type> @@ -216,18 +216,18 @@ namespace Ogre { #endif SharedPtr& operator=(const SharedPtr& r) { - if (pRep == r.pRep) - return *this; - // Swap current data into a local copy - // this ensures we deal with rhs and this being dependent - SharedPtr tmp(r); - swap(tmp); - return *this; - } - - ~SharedPtr() { + if (pRep == r.pRep) + return *this; + // Swap current data into a local copy + // this ensures we deal with rhs and this being dependent + SharedPtr tmp(r); + swap(tmp); + return *this; + } + + ~SharedPtr() { release(); - } + } template @@ -235,7 +235,7 @@ namespace Ogre { { if(pRep) { ++pInfo->useCount; - return SharedPtr(static_cast(pRep), pInfo); + return SharedPtr(static_cast(pRep), pInfo); } else return SharedPtr(); } @@ -245,40 +245,40 @@ namespace Ogre { if(pRep) { Y* rep = dynamic_cast(pRep); ++pInfo->useCount; - return SharedPtr(rep, pInfo); + return SharedPtr(rep, pInfo); } else return SharedPtr(); } - inline T& operator*() const { assert(pRep); return *pRep; } - inline T* operator->() const { assert(pRep); return pRep; } - inline T* get() const { return pRep; } + inline T& operator*() const { assert(pRep); return *pRep; } + inline T* operator->() const { assert(pRep); return pRep; } + inline T* get() const { return pRep; } - /** Binds rep to the SharedPtr. - @remarks - Assumes that the SharedPtr is uninitialised! + /** Binds rep to the SharedPtr. + @remarks + Assumes that the SharedPtr is uninitialised! @warning The object must not be bound into a SharedPtr elsewhere - */ - void bind(T* rep, SharedPtrFreeMethod inFreeMethod = SPFM_DELETE) { - assert(!pRep && !pInfo); - pInfo = createInfoForMethod(rep, inFreeMethod); - pRep = rep; - } - - inline bool unique() const { assert(pInfo && pInfo->useCount.get()); return pInfo->useCount.get() == 1; } - inline unsigned int useCount() const { assert(pInfo && pInfo->useCount.get()); return pInfo->useCount.get(); } + */ + void bind(T* rep, SharedPtrFreeMethod inFreeMethod = SPFM_DELETE) { + assert(!pRep && !pInfo); + pInfo = createInfoForMethod(rep, inFreeMethod); + pRep = rep; + } + + inline bool unique() const { assert(pInfo && pInfo->useCount.get()); return pInfo->useCount.get() == 1; } + inline unsigned int useCount() const { assert(pInfo && pInfo->useCount.get()); return pInfo->useCount.get(); } inline void setUseCount(unsigned value) { assert(pInfo); pInfo->useCount = value; } - inline T* getPointer() const { return pRep; } + inline T* getPointer() const { return pRep; } - inline bool isNull(void) const { return pRep == 0; } + inline bool isNull(void) const { return pRep == 0; } inline void setNull(void) { - if (pRep) - { - release(); - } + if (pRep) + { + release(); + } } protected: @@ -306,29 +306,29 @@ namespace Ogre { OGRE_DELETE_T(pInfo, SharedPtrInfo, MEMCATEGORY_GENERAL); } - inline void swap(SharedPtr &other) - { - std::swap(pRep, other.pRep); - std::swap(pInfo, other.pInfo); - } - }; - - template inline bool operator==(SharedPtr const& a, SharedPtr const& b) - { - return a.get() == b.get(); - } - - template inline bool operator!=(SharedPtr const& a, SharedPtr const& b) - { - return a.get() != b.get(); - } - - template inline bool operator<(SharedPtr const& a, SharedPtr const& b) - { - return std::less()(a.get(), b.get()); - } - /** @} */ - /** @} */ + inline void swap(SharedPtr &other) + { + std::swap(pRep, other.pRep); + std::swap(pInfo, other.pInfo); + } + }; + + template inline bool operator==(SharedPtr const& a, SharedPtr const& b) + { + return a.get() == b.get(); + } + + template inline bool operator!=(SharedPtr const& a, SharedPtr const& b) + { + return a.get() != b.get(); + } + + template inline bool operator<(SharedPtr const& a, SharedPtr const& b) + { + return std::less()(a.get(), b.get()); + } + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreSimpleRenderable.h b/OgreMain/include/OgreSimpleRenderable.h index 3cfd7610cc2..865192f1675 100644 --- a/OgreMain/include/OgreSimpleRenderable.h +++ b/OgreMain/include/OgreSimpleRenderable.h @@ -38,16 +38,16 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Simple implementation of MovableObject and Renderable for single-part custom objects. - @see ManualObject for a simpler interface with more flexibility - */ - class _OgreExport SimpleRenderable : public MovableObject, public Renderable + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Simple implementation of MovableObject and Renderable for single-part custom objects. + @see ManualObject for a simpler interface with more flexibility + */ + class _OgreExport SimpleRenderable : public MovableObject, public Renderable { protected: RenderOperation mRenderOp; @@ -90,9 +90,9 @@ namespace Ogre { virtual const AxisAlignedBox& getBoundingBox(void) const; virtual void _updateRenderQueue(RenderQueue* queue); - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false); + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false); virtual ~SimpleRenderable(); @@ -104,8 +104,8 @@ namespace Ogre { const LightList& getLights(void) const; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreSimpleSpline.h b/OgreMain/include/OgreSimpleSpline.h index 292addef009..b11b1c82a10 100644 --- a/OgreMain/include/OgreSimpleSpline.h +++ b/OgreMain/include/OgreSimpleSpline.h @@ -36,13 +36,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** A very simple spline class which implements the Catmull-Rom class of splines. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** A very simple spline class which implements the Catmull-Rom class of splines. @remarks Splines are bendy lines. You define a series of points, and the spline forms a smoother line between the points to eliminate the sharp angles. @@ -53,7 +53,7 @@ namespace Ogre { this by just asking you to define a series of points, and the tangents are created for you. */ - class _OgreExport SimpleSpline + class _OgreExport SimpleSpline { public: SimpleSpline(); @@ -127,8 +127,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreSingleton.h b/OgreMain/include/OgreSingleton.h index a6635645309..e80552b4f2e 100644 --- a/OgreMain/include/OgreSingleton.h +++ b/OgreMain/include/OgreSingleton.h @@ -51,26 +51,26 @@ THE SOFTWARE. # pragma GCC visibility push(default) #endif namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ // End SJS additions /** Template class for creating single-instance global classes. */ template class Singleton { - private: - /** @brief Explicit private copy constructor. This is a forbidden operation.*/ - Singleton(const Singleton &); + private: + /** @brief Explicit private copy constructor. This is a forbidden operation.*/ + Singleton(const Singleton &); - /** @brief Private operator= . This is a forbidden operation. */ - Singleton& operator=(const Singleton &); + /** @brief Private operator= . This is a forbidden operation. */ + Singleton& operator=(const Singleton &); - protected: + protected: static T* msSingleton; @@ -78,22 +78,22 @@ namespace Ogre { Singleton( void ) { assert( !msSingleton ); -#if defined( _MSC_VER ) && _MSC_VER < 1200 +#if defined( _MSC_VER ) && _MSC_VER < 1200 int offset = (int)(T*)1 - (int)(Singleton *)(T*)1; msSingleton = (T*)((int)this + offset); #else - msSingleton = static_cast< T* >( this ); + msSingleton = static_cast< T* >( this ); #endif } ~Singleton( void ) { assert( msSingleton ); msSingleton = 0; } static T& getSingleton( void ) - { assert( msSingleton ); return ( *msSingleton ); } + { assert( msSingleton ); return ( *msSingleton ); } static T* getSingletonPtr( void ) - { return msSingleton; } + { return msSingleton; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #if defined ( OGRE_GCC_VISIBILITY ) diff --git a/OgreMain/include/OgreSkeleton.h b/OgreMain/include/OgreSkeleton.h index 27d924540a8..710c42e50fd 100644 --- a/OgreMain/include/OgreSkeleton.h +++ b/OgreMain/include/OgreSkeleton.h @@ -36,25 +36,25 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ /** */ enum SkeletonAnimationBlendMode { /// Animations are applied by calculating a weighted average of all animations - ANIMBLEND_AVERAGE = 0, + ANIMBLEND_AVERAGE = 0, /// Animations are applied by calculating a weighted cumulative total - ANIMBLEND_CUMULATIVE = 1 + ANIMBLEND_CUMULATIVE = 1 }; #define OGRE_MAX_NUM_BONES 256 - - struct LinkedSkeletonAnimationSource; + + struct LinkedSkeletonAnimationSource; /** A collection of Bone objects used to animate a skinned mesh. @remarks @@ -83,10 +83,10 @@ namespace Ogre { */ class _OgreExport Skeleton : public Resource, public AnimationContainer { - friend class SkeletonInstance; - protected: - /// Internal constructor for use by SkeletonInstance only - Skeleton(); + friend class SkeletonInstance; + protected: + /// Internal constructor for use by SkeletonInstance only + Skeleton(); public: /** Constructor, don't call directly, use SkeletonManager. @@ -102,8 +102,8 @@ namespace Ogre { /** Creates a brand new Bone owned by this Skeleton. @remarks This method creates an unattached new Bone for this skeleton. - Unless this is to be a root bone (there may be more than one of - these), you must attach it to another Bone in the skeleton using addChild for it to be any use. + Unless this is to be a root bone (there may be more than one of + these), you must attach it to another Bone in the skeleton using addChild for it to be any use. For this reason you will likely be better off creating child bones using the Bone::createChild method instead, once you have created the root bone. @par @@ -118,7 +118,7 @@ namespace Ogre { @remarks This method creates an unattached new Bone for this skeleton and assigns it a specific handle. Unless this is to be a root bone (there may be more than one of - these), you must attach it to another Bone in the skeleton using addChild for it to be any use. + these), you must attach it to another Bone in the skeleton using addChild for it to be any use. For this reason you will likely be better off creating child bones using the Bone::createChild method instead, once you have created a root bone. @param handle The handle to give to this new bone - must be unique within this skeleton. @@ -133,7 +133,7 @@ namespace Ogre { @remarks This method creates an unattached new Bone for this skeleton and assigns it a specific name.Unless this is to be a root bone (there may be more than one of - these), you must attach it to another Bone in the skeleton using addChild for it to be any use. + these), you must attach it to another Bone in the skeleton using addChild for it to be any use. For this reason you will likely be better off creating child bones using the Bone::createChild method instead, once you have created the root bone. @param name The name to give to this new bone - must be unique within this skeleton. @@ -148,7 +148,7 @@ namespace Ogre { @remarks This method creates an unattached new Bone for this skeleton and assigns it a specific name and handle. Unless this is to be a root bone (there may be more than one of - these), you must attach it to another Bone in the skeleton using addChild for it to be any use. + these), you must attach it to another Bone in the skeleton using addChild for it to be any use. For this reason you will likely be better off creating child bones using the Bone::createChild method instead, once you have created the root bone. @param name The name to give to this new bone - must be unique within this skeleton. @@ -185,7 +185,7 @@ namespace Ogre { /** Gets a bone by it's name. */ virtual Bone* getBone(const String& name) const; - /** Returns whether this skeleton contains the named bone. */ + /** Returns whether this skeleton contains the named bone. */ virtual bool hasBone(const String& name) const; /** Sets the current position / orientation to be the 'binding pose' i.e. the layout in which @@ -211,31 +211,31 @@ namespace Ogre { virtual Animation* createAnimation(const String& name, Real length); /** Returns the named Animation object. - @remarks - Will pick up animations in linked skeletons - (@see addLinkedSkeletonAnimationSource). - @param name The name of the animation - @param linker Optional pointer to a pointer to the linked skeleton animation - where this is coming from. - */ + @remarks + Will pick up animations in linked skeletons + (@see addLinkedSkeletonAnimationSource). + @param name The name of the animation + @param linker Optional pointer to a pointer to the linked skeleton animation + where this is coming from. + */ virtual Animation* getAnimation(const String& name, - const LinkedSkeletonAnimationSource** linker) const; + const LinkedSkeletonAnimationSource** linker) const; - /** Returns the named Animation object. - @remarks - Will pick up animations in linked skeletons - (@see addLinkedSkeletonAnimationSource). - @param name The name of the animation - */ - virtual Animation* getAnimation(const String& name) const; + /** Returns the named Animation object. + @remarks + Will pick up animations in linked skeletons + (@see addLinkedSkeletonAnimationSource). + @param name The name of the animation + */ + virtual Animation* getAnimation(const String& name) const; - /// Internal accessor for animations (returns null if animation does not exist) - virtual Animation* _getAnimationImpl(const String& name, - const LinkedSkeletonAnimationSource** linker = 0) const; + /// Internal accessor for animations (returns null if animation does not exist) + virtual Animation* _getAnimationImpl(const String& name, + const LinkedSkeletonAnimationSource** linker = 0) const; - /** Returns whether this skeleton contains the named animation. */ - virtual bool hasAnimation(const String& name) const; + /** Returns whether this skeleton contains the named animation. */ + virtual bool hasAnimation(const String& name) const; /** Removes an Animation from this skeleton. */ virtual void removeAnimation(const String& name); @@ -259,13 +259,13 @@ namespace Ogre { */ virtual void _initAnimationState(AnimationStateSet* animSet); - /** Refresh an animation set suitable for use with this skeleton. - @remarks - Only recommended for use inside the engine, not by applications. - */ - virtual void _refreshAnimationState(AnimationStateSet* animSet); + /** Refresh an animation set suitable for use with this skeleton. + @remarks + Only recommended for use inside the engine, not by applications. + */ + virtual void _refreshAnimationState(AnimationStateSet* animSet); - /** Populates the passed in array with the bone matrices based on the current position. + /** Populates the passed in array with the bone matrices based on the current position. @remarks Internal use only. The array pointed to by the passed in pointer must be at least as large as the number of bones. @@ -277,83 +277,83 @@ namespace Ogre { virtual unsigned short getNumAnimations(void) const; /** Gets a single animation by index. - @remarks - Will NOT pick up animations in linked skeletons - (@see addLinkedSkeletonAnimationSource). - */ + @remarks + Will NOT pick up animations in linked skeletons + (@see addLinkedSkeletonAnimationSource). + */ virtual Animation* getAnimation(unsigned short index) const; - /** Gets the animation blending mode which this skeleton will use. */ + /** Gets the animation blending mode which this skeleton will use. */ virtual SkeletonAnimationBlendMode getBlendMode() const; /** Sets the animation blending mode this skeleton will use. */ - virtual void setBlendMode(SkeletonAnimationBlendMode state); + virtual void setBlendMode(SkeletonAnimationBlendMode state); /// Updates all the derived transforms in the skeleton virtual void _updateTransforms(void); - /** Optimise all of this skeleton's animations. - @see Animation::optimise + /** Optimise all of this skeleton's animations. + @see Animation::optimise @param preservingIdentityNodeTracks If true, don't destroy identity node tracks. - */ - virtual void optimiseAllAnimations(bool preservingIdentityNodeTracks = false); - - /** Allows you to use the animations from another Skeleton object to animate - this skeleton. - @remarks - If you have skeletons of identical structure (that means identically - named bones with identical handles, and with the same hierarchy), but - slightly different proportions or binding poses, you can re-use animations - from one in the other. Because animations are actually stored as - changes to bones from their bind positions, it's possible to use the - same animation data for different skeletons, provided the skeletal - structure matches and the 'deltas' stored in the keyframes apply - equally well to the other skeletons bind position (so they must be - roughly similar, but don't have to be identical). You can use the - 'scale' option to adjust the translation and scale keyframes where - there are large differences in size between the skeletons. - @note - This method takes a skeleton name, rather than a more specific - animation name, for two reasons; firstly it allows some validation - of compatibility of skeletal structure, and secondly skeletons are - the unit of loading. Linking a skeleton to another in this way means - that the linkee will be prevented from being destroyed until the - linker is destroyed. - - You cannot set up cyclic relationships, e.g. SkeletonA uses SkeletonB's - animations, and SkeletonB uses SkeletonA's animations. This is because - it would set up a circular dependency which would prevent proper - unloading - make one of the skeletons the 'master' in this case. - @param skelName Name of the skeleton to link animations from. This - skeleton will be loaded immediately if this skeleton is already - loaded, otherwise it will be loaded when this skeleton is. - @param scale A scale factor to apply to translation and scaling elements - of the keyframes in the other skeleton when applying the animations - to this one. Compensates for skeleton size differences. - */ - virtual void addLinkedSkeletonAnimationSource(const String& skelName, - Real scale = 1.0f); - /// Remove all links to other skeletons for the purposes of sharing animation - virtual void removeAllLinkedSkeletonAnimationSources(void); - - typedef vector::type - LinkedSkeletonAnimSourceList; - typedef ConstVectorIterator - LinkedSkeletonAnimSourceIterator; - /// Get an iterator over the linked skeletons used as animation sources - virtual LinkedSkeletonAnimSourceIterator - getLinkedSkeletonAnimationSourceIterator(void) const; - - /// Internal method for marking the manual bones as dirty - virtual void _notifyManualBonesDirty(void); - /// Internal method for notifying that a bone is manual - virtual void _notifyManualBoneStateChange(Bone* bone); - - /// Have manual bones been modified since the skeleton was last updated? - virtual bool getManualBonesDirty(void) const { return mManualBonesDirty; } - /// Are there any manually controlled bones? - virtual bool hasManualBones(void) const { return !mManualBones.empty(); } + */ + virtual void optimiseAllAnimations(bool preservingIdentityNodeTracks = false); + + /** Allows you to use the animations from another Skeleton object to animate + this skeleton. + @remarks + If you have skeletons of identical structure (that means identically + named bones with identical handles, and with the same hierarchy), but + slightly different proportions or binding poses, you can re-use animations + from one in the other. Because animations are actually stored as + changes to bones from their bind positions, it's possible to use the + same animation data for different skeletons, provided the skeletal + structure matches and the 'deltas' stored in the keyframes apply + equally well to the other skeletons bind position (so they must be + roughly similar, but don't have to be identical). You can use the + 'scale' option to adjust the translation and scale keyframes where + there are large differences in size between the skeletons. + @note + This method takes a skeleton name, rather than a more specific + animation name, for two reasons; firstly it allows some validation + of compatibility of skeletal structure, and secondly skeletons are + the unit of loading. Linking a skeleton to another in this way means + that the linkee will be prevented from being destroyed until the + linker is destroyed. + + You cannot set up cyclic relationships, e.g. SkeletonA uses SkeletonB's + animations, and SkeletonB uses SkeletonA's animations. This is because + it would set up a circular dependency which would prevent proper + unloading - make one of the skeletons the 'master' in this case. + @param skelName Name of the skeleton to link animations from. This + skeleton will be loaded immediately if this skeleton is already + loaded, otherwise it will be loaded when this skeleton is. + @param scale A scale factor to apply to translation and scaling elements + of the keyframes in the other skeleton when applying the animations + to this one. Compensates for skeleton size differences. + */ + virtual void addLinkedSkeletonAnimationSource(const String& skelName, + Real scale = 1.0f); + /// Remove all links to other skeletons for the purposes of sharing animation + virtual void removeAllLinkedSkeletonAnimationSources(void); + + typedef vector::type + LinkedSkeletonAnimSourceList; + typedef ConstVectorIterator + LinkedSkeletonAnimSourceIterator; + /// Get an iterator over the linked skeletons used as animation sources + virtual LinkedSkeletonAnimSourceIterator + getLinkedSkeletonAnimationSourceIterator(void) const; + + /// Internal method for marking the manual bones as dirty + virtual void _notifyManualBonesDirty(void); + /// Internal method for notifying that a bone is manual + virtual void _notifyManualBoneStateChange(Bone* bone); + + /// Have manual bones been modified since the skeleton was last updated? + virtual bool getManualBonesDirty(void) const { return mManualBonesDirty; } + /// Are there any manually controlled bones? + virtual bool hasManualBones(void) const { return !mManualBones.empty(); } /// Map to translate bone handle from one skeleton to another skeleton. typedef vector::type BoneHandleMap; @@ -409,8 +409,8 @@ namespace Ogre { virtual void _buildMapBoneByName(const Skeleton* source, BoneHandleMap& boneHandleMap) const; - protected: - SkeletonAnimationBlendMode mBlendState; + protected: + SkeletonAnimationBlendMode mBlendState; /// Storage of bones, indexed by bone handle BoneList mBoneList; /// Lookup by bone name @@ -422,19 +422,19 @@ namespace Ogre { mutable BoneList mRootBones; /// Bone automatic handles unsigned short mNextAutoHandle; - typedef set::type BoneSet; - /// Manual bones - BoneSet mManualBones; - /// Manual bones dirty? - bool mManualBonesDirty; + typedef set::type BoneSet; + /// Manual bones + BoneSet mManualBones; + /// Manual bones dirty? + bool mManualBonesDirty; /// Storage of animations, lookup by name typedef map::type AnimationList; AnimationList mAnimationsList; - /// List of references to other skeletons to use animations from - mutable LinkedSkeletonAnimSourceList mLinkedSkeletonAnimSourceList; + /// List of references to other skeletons to use animations from + mutable LinkedSkeletonAnimSourceList mLinkedSkeletonAnimSourceList; /** Internal method which parses the bones to derive the root bone. @remarks @@ -453,25 +453,25 @@ namespace Ogre { /** @copydoc Resource::unloadImpl */ void unloadImpl(void); - /// @copydoc Resource::calculateSize - size_t calculateSize(void) const; + /// @copydoc Resource::calculateSize + size_t calculateSize(void) const; }; - /// Link to another skeleton to share animations - struct LinkedSkeletonAnimationSource - { - String skeletonName; - SkeletonPtr pSkeleton; - Real scale; - LinkedSkeletonAnimationSource(const String& skelName, Real scl) - : skeletonName(skelName), scale(scl) {} - LinkedSkeletonAnimationSource(const String& skelName, Real scl, - SkeletonPtr skelPtr) - : skeletonName(skelName), pSkeleton(skelPtr), scale(scl) {} - }; - /** @} */ - /** @} */ + /// Link to another skeleton to share animations + struct LinkedSkeletonAnimationSource + { + String skeletonName; + SkeletonPtr pSkeleton; + Real scale; + LinkedSkeletonAnimationSource(const String& skelName, Real scl) + : skeletonName(skelName), scale(scl) {} + LinkedSkeletonAnimationSource(const String& skelName, Real scl, + SkeletonPtr skelPtr) + : skeletonName(skelName), pSkeleton(skelPtr), scale(scl) {} + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreSkeletonFileFormat.h b/OgreMain/include/OgreSkeletonFileFormat.h index 698cb2766c3..bf5bcd70e15 100644 --- a/OgreMain/include/OgreSkeletonFileFormat.h +++ b/OgreMain/include/OgreSkeletonFileFormat.h @@ -32,12 +32,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ /** Definition of the OGRE .skeleton file format .skeleton files are binary files (for read efficiency at runtime) and are arranged into chunks @@ -55,9 +55,9 @@ namespace Ogre { enum SkeletonChunkID { SKELETON_HEADER = 0x1000, // char* version : Version number check - SKELETON_BLENDMODE = 0x1010, // optional - // unsigned short blendmode : SkeletonAnimationBlendMode - + SKELETON_BLENDMODE = 0x1010, // optional + // unsigned short blendmode : SkeletonAnimationBlendMode + SKELETON_BONE = 0x2000, // Repeating section defining each bone in the system. // Bones are assigned indexes automatically based on their order of declaration @@ -81,11 +81,11 @@ namespace Ogre { // char* name : Name of the animation // float length : Length of the animation in seconds - - SKELETON_ANIMATION_BASEINFO = 0x4010, - // [Optional] base keyframe information - // char* baseAnimationName (blank for self) - // float baseKeyFrameTime + + SKELETON_ANIMATION_BASEINFO = 0x4010, + // [Optional] base keyframe information + // char* baseAnimationName (blank for self) + // float baseKeyFrameTime SKELETON_ANIMATION_TRACK = 0x4100, // A single animation track (relates to a single bone) @@ -101,15 +101,15 @@ namespace Ogre { // Quaternion rotate : Rotation to apply at this keyframe // Vector3 translate : Translation to apply at this keyframe // Vector3 scale : Scale to apply at this keyframe - SKELETON_ANIMATION_LINK = 0x5000 - // Link to another skeleton, to re-use its animations + SKELETON_ANIMATION_LINK = 0x5000 + // Link to another skeleton, to re-use its animations - // char* skeletonName : name of skeleton to get animations from - // float scale : scale to apply to trans/scale keys + // char* skeletonName : name of skeleton to get animations from + // float scale : scale to apply to trans/scale keys }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreSkeletonInstance.h b/OgreMain/include/OgreSkeletonInstance.h index f16e0598127..c6d858d8949 100644 --- a/OgreMain/include/OgreSkeletonInstance.h +++ b/OgreMain/include/OgreSkeletonInstance.h @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** A SkeletonInstance is a single instance of a Skeleton used by a world object. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** A SkeletonInstance is a single instance of a Skeleton used by a world object. @remarks The difference between a Skeleton and a SkeletonInstance is that the Skeleton is the 'master' version much like Mesh is a 'master' version of @@ -64,9 +64,9 @@ namespace Ogre { /** Gets a single animation by index. */ Animation* getAnimation(unsigned short index) const; - /// Internal accessor for animations (returns null if animation does not exist) - Animation* _getAnimationImpl(const String& name, - const LinkedSkeletonAnimationSource** linker = 0) const; + /// Internal accessor for animations (returns null if animation does not exist) + Animation* _getAnimationImpl(const String& name, + const LinkedSkeletonAnimationSource** linker = 0) const; /** Creates a new Animation object for animating this skeleton. @remarks @@ -78,7 +78,7 @@ namespace Ogre { /** Returns the named Animation object. */ Animation* getAnimation(const String& name, - const LinkedSkeletonAnimationSource** linker = 0) const; + const LinkedSkeletonAnimationSource** linker = 0) const; /** Removes an Animation from this skeleton. @remarks @@ -95,27 +95,27 @@ namespace Ogre { /** Frees a TagPoint that already attached to a bone */ void freeTagPoint(TagPoint* tagPoint); - /// @copydoc Skeleton::addLinkedSkeletonAnimationSource - void addLinkedSkeletonAnimationSource(const String& skelName, - Real scale = 1.0f); - /// @copydoc Skeleton::removeAllLinkedSkeletonAnimationSources - void removeAllLinkedSkeletonAnimationSources(void); - /// @copydoc Skeleton::getLinkedSkeletonAnimationSourceIterator - LinkedSkeletonAnimSourceIterator - getLinkedSkeletonAnimationSourceIterator(void) const; + /// @copydoc Skeleton::addLinkedSkeletonAnimationSource + void addLinkedSkeletonAnimationSource(const String& skelName, + Real scale = 1.0f); + /// @copydoc Skeleton::removeAllLinkedSkeletonAnimationSources + void removeAllLinkedSkeletonAnimationSources(void); + /// @copydoc Skeleton::getLinkedSkeletonAnimationSourceIterator + LinkedSkeletonAnimSourceIterator + getLinkedSkeletonAnimationSourceIterator(void) const; - /// @copydoc Skeleton::_initAnimationState - void _initAnimationState(AnimationStateSet* animSet); + /// @copydoc Skeleton::_initAnimationState + void _initAnimationState(AnimationStateSet* animSet); - /// @copydoc Skeleton::_refreshAnimationState - void _refreshAnimationState(AnimationStateSet* animSet); + /// @copydoc Skeleton::_refreshAnimationState + void _refreshAnimationState(AnimationStateSet* animSet); - /// @copydoc Resource::getName - const String& getName(void) const; - /// @copydoc Resource::getHandle - ResourceHandle getHandle(void) const; - /// @copydoc Resource::getGroup - const String& getGroup(void); + /// @copydoc Resource::getName + const String& getName(void) const; + /// @copydoc Resource::getHandle + ResourceHandle getHandle(void) const; + /// @copydoc Resource::getGroup + const String& getGroup(void); protected: /// Pointer back to master Skeleton @@ -154,8 +154,8 @@ namespace Ogre { void unloadImpl(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreSkeletonManager.h b/OgreMain/include/OgreSkeletonManager.h index da6f69331dc..4444c4f24a7 100644 --- a/OgreMain/include/OgreSkeletonManager.h +++ b/OgreMain/include/OgreSkeletonManager.h @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ - /** Handles the management of skeleton resources. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ + /** Handles the management of skeleton resources. @remarks This class deals with the runtime management of skeleton data; like other resource managers it handles @@ -55,15 +55,15 @@ namespace Ogre { SkeletonManager(); ~SkeletonManager(); - /// Create a new skeleton - /// @see ResourceManager::createResource - SkeletonPtr create (const String& name, const String& group, - bool isManual = false, ManualResourceLoader* loader = 0, - const NameValuePairList* createParams = 0); + /// Create a new skeleton + /// @see ResourceManager::createResource + SkeletonPtr create (const String& name, const String& group, + bool isManual = false, ManualResourceLoader* loader = 0, + const NameValuePairList* createParams = 0); - /// Get a resource by name - /// @see ResourceManager::getResourceByName - SkeletonPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + /// Get a resource by name + /// @see ResourceManager::getResourceByName + SkeletonPtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); /** Override standard Singleton retrieval. @remarks @@ -106,8 +106,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreSkeletonSerializer.h b/OgreMain/include/OgreSkeletonSerializer.h index 76b558f118c..f6882c48be0 100644 --- a/OgreMain/include/OgreSkeletonSerializer.h +++ b/OgreMain/include/OgreSkeletonSerializer.h @@ -36,25 +36,25 @@ namespace Ogre { struct LinkedSkeletonAnimationSource; - /// Skeleton compatibility versions - enum SkeletonVersion - { - /// OGRE version v1.0+ - SKELETON_VERSION_1_0, - /// OGRE version v1.8+ - SKELETON_VERSION_1_8, - - /// Latest version available - SKELETON_VERSION_LATEST = 100 - }; - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ - /** Class for serialising skeleton data to/from an OGRE .skeleton file. + /// Skeleton compatibility versions + enum SkeletonVersion + { + /// OGRE version v1.0+ + SKELETON_VERSION_1_0, + /// OGRE version v1.8+ + SKELETON_VERSION_1_8, + + /// Latest version available + SKELETON_VERSION_LATEST = 100 + }; + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ + /** Class for serialising skeleton data to/from an OGRE .skeleton file. @remarks This class allows exporters to write OGRE .skeleton files easily, and allows the OGRE engine to import .skeleton files into instantiated OGRE Skeleton objects. @@ -68,8 +68,8 @@ namespace Ogre { */ class _OgreExport SkeletonSerializer : public Serializer { - - public: + + public: SkeletonSerializer(); virtual ~SkeletonSerializer(); @@ -80,10 +80,10 @@ namespace Ogre { and animations it uses to a .skeleton file. @param pSkeleton Weak reference to the Skeleton to export @param filename The destination filename - @param endianMode The endian mode to write in + @param endianMode The endian mode to write in */ void exportSkeleton(const Skeleton* pSkeleton, const String& filename, - SkeletonVersion ver = SKELETON_VERSION_LATEST, Endian endianMode = ENDIAN_NATIVE); + SkeletonVersion ver = SKELETON_VERSION_LATEST, Endian endianMode = ENDIAN_NATIVE); /** Exports a skeleton to the stream specified. @remarks @@ -91,10 +91,10 @@ namespace Ogre { and animations it uses to a .skeleton file. @param pSkeleton Weak reference to the Skeleton to export @param stream The destination stream - @param endianMode The endian mode to write in + @param endianMode The endian mode to write in */ void exportSkeleton(const Skeleton* pSkeleton, DataStreamPtr stream, - SkeletonVersion ver = SKELETON_VERSION_LATEST, Endian endianMode = ENDIAN_NATIVE); + SkeletonVersion ver = SKELETON_VERSION_LATEST, Endian endianMode = ENDIAN_NATIVE); /** Imports Skeleton and animation data from a .skeleton file DataStream. @remarks This method imports data from a DataStream opened from a .skeleton file and places it's @@ -107,27 +107,27 @@ namespace Ogre { // TODO: provide Cal3D importer? protected: - - void setWorkingVersion(SkeletonVersion ver); - - // Internal export methods - void writeSkeleton(const Skeleton* pSkel, SkeletonVersion ver); + + void setWorkingVersion(SkeletonVersion ver); + + // Internal export methods + void writeSkeleton(const Skeleton* pSkel, SkeletonVersion ver); void writeBone(const Skeleton* pSkel, const Bone* pBone); void writeBoneParent(const Skeleton* pSkel, unsigned short boneId, unsigned short parentId); - void writeAnimation(const Skeleton* pSkel, const Animation* anim, SkeletonVersion ver); + void writeAnimation(const Skeleton* pSkel, const Animation* anim, SkeletonVersion ver); void writeAnimationTrack(const Skeleton* pSkel, const NodeAnimationTrack* track); void writeKeyFrame(const Skeleton* pSkel, const TransformKeyFrame* key); - void writeSkeletonAnimationLink(const Skeleton* pSkel, - const LinkedSkeletonAnimationSource& link); + void writeSkeletonAnimationLink(const Skeleton* pSkel, + const LinkedSkeletonAnimationSource& link); // Internal import methods - void readFileHeader(DataStreamPtr& stream); - void readBone(DataStreamPtr& stream, Skeleton* pSkel); + void readFileHeader(DataStreamPtr& stream); + void readBone(DataStreamPtr& stream, Skeleton* pSkel); void readBoneParent(DataStreamPtr& stream, Skeleton* pSkel); void readAnimation(DataStreamPtr& stream, Skeleton* pSkel); void readAnimationTrack(DataStreamPtr& stream, Animation* anim, Skeleton* pSkel); void readKeyFrame(DataStreamPtr& stream, NodeAnimationTrack* track, Skeleton* pSkel); - void readSkeletonAnimationLink(DataStreamPtr& stream, Skeleton* pSkel); + void readSkeletonAnimationLink(DataStreamPtr& stream, Skeleton* pSkel); size_t calcBoneSize(const Skeleton* pSkel, const Bone* pBone); size_t calcBoneSizeWithoutScale(const Skeleton* pSkel, const Bone* pBone); @@ -136,15 +136,15 @@ namespace Ogre { size_t calcAnimationTrackSize(const Skeleton* pSkel, const NodeAnimationTrack* pTrack); size_t calcKeyFrameSize(const Skeleton* pSkel, const TransformKeyFrame* pKey); size_t calcKeyFrameSizeWithoutScale(const Skeleton* pSkel, const TransformKeyFrame* pKey); - size_t calcSkeletonAnimationLinkSize(const Skeleton* pSkel, - const LinkedSkeletonAnimationSource& link); + size_t calcSkeletonAnimationLinkSize(const Skeleton* pSkel, + const LinkedSkeletonAnimationSource& link); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreSphere.h b/OgreMain/include/OgreSphere.h index 853b09289e4..cfa72bf37e7 100644 --- a/OgreMain/include/OgreSphere.h +++ b/OgreMain/include/OgreSphere.h @@ -36,13 +36,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** A sphere primitive, mostly used for bounds checking. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** A sphere primitive, mostly used for bounds checking. @remarks A sphere in math texts is normally represented by the function x^2 + y^2 + z^2 = r^2 (for sphere's centered on the origin). Ogre stores spheres @@ -75,58 +75,58 @@ namespace Ogre { /** Sets the center point of the sphere. */ void setCenter(const Vector3& center) { mCenter = center; } - /** Returns whether or not this sphere intersects another sphere. */ - bool intersects(const Sphere& s) const - { + /** Returns whether or not this sphere intersects another sphere. */ + bool intersects(const Sphere& s) const + { return (s.mCenter - mCenter).squaredLength() <= Math::Sqr(s.mRadius + mRadius); - } - /** Returns whether or not this sphere intersects a box. */ - bool intersects(const AxisAlignedBox& box) const - { - return Math::intersects(*this, box); - } - /** Returns whether or not this sphere intersects a plane. */ - bool intersects(const Plane& plane) const - { - return Math::intersects(*this, plane); - } - /** Returns whether or not this sphere intersects a point. */ - bool intersects(const Vector3& v) const - { + } + /** Returns whether or not this sphere intersects a box. */ + bool intersects(const AxisAlignedBox& box) const + { + return Math::intersects(*this, box); + } + /** Returns whether or not this sphere intersects a plane. */ + bool intersects(const Plane& plane) const + { + return Math::intersects(*this, plane); + } + /** Returns whether or not this sphere intersects a point. */ + bool intersects(const Vector3& v) const + { return ((v - mCenter).squaredLength() <= Math::Sqr(mRadius)); - } - /** Merges another Sphere into the current sphere */ - void merge(const Sphere& oth) - { - Vector3 diff = oth.getCenter() - mCenter; - Real lengthSq = diff.squaredLength(); - Real radiusDiff = oth.getRadius() - mRadius; - - // Early-out - if (Math::Sqr(radiusDiff) >= lengthSq) - { - // One fully contains the other - if (radiusDiff <= 0.0f) - return; // no change - else - { - mCenter = oth.getCenter(); - mRadius = oth.getRadius(); - return; - } - } - - Real length = Math::Sqrt(lengthSq); + } + /** Merges another Sphere into the current sphere */ + void merge(const Sphere& oth) + { + Vector3 diff = oth.getCenter() - mCenter; + Real lengthSq = diff.squaredLength(); + Real radiusDiff = oth.getRadius() - mRadius; + + // Early-out + if (Math::Sqr(radiusDiff) >= lengthSq) + { + // One fully contains the other + if (radiusDiff <= 0.0f) + return; // no change + else + { + mCenter = oth.getCenter(); + mRadius = oth.getRadius(); + return; + } + } + + Real length = Math::Sqrt(lengthSq); Real t = (length + radiusDiff) / (2.0f * length); mCenter = mCenter + diff * t; - mRadius = 0.5f * (length + mRadius + oth.getRadius()); - } + mRadius = 0.5f * (length + mRadius + oth.getRadius()); + } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreStableHeaders.h b/OgreMain/include/OgreStableHeaders.h index 218cd5895cb..d2b1837e86e 100644 --- a/OgreMain/include/OgreStableHeaders.h +++ b/OgreMain/include/OgreStableHeaders.h @@ -73,7 +73,7 @@ THE SOFTWARE. #include "OgreVector4.h" #include "OgreWireBoundingBox.h" #if OGRE_NO_ZIP_ARCHIVE == 0 -# include "OgreZip.h" +# include "OgreZip.h" #endif #endif diff --git a/OgreMain/include/OgreStaticFaceGroup.h b/OgreMain/include/OgreStaticFaceGroup.h index 1ebe6b76c4b..2e259ca0f28 100644 --- a/OgreMain/include/OgreStaticFaceGroup.h +++ b/OgreMain/include/OgreStaticFaceGroup.h @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** A type of face group, i.e. face list of procedural etc */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** A type of face group, i.e. face list of procedural etc */ enum FaceGroupType { FGT_FACE_LIST, FGT_PATCH, @@ -133,8 +133,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreStaticGeometry.h b/OgreMain/include/OgreStaticGeometry.h index 4f6ffc010a0..3db96c596c3 100644 --- a/OgreMain/include/OgreStaticGeometry.h +++ b/OgreMain/include/OgreStaticGeometry.h @@ -36,394 +36,394 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Pre-transforms and batches up meshes for efficient use as static - geometry in a scene. - @remarks - Modern graphics cards (GPUs) prefer to receive geometry in large - batches. It is orders of magnitude faster to render 10 batches - of 10,000 triangles than it is to render 10,000 batches of 10 - triangles, even though both result in the same number of on-screen - triangles. - @par - Therefore it is important when you are rendering a lot of geometry to - batch things up into as few rendering calls as possible. This - class allows you to build a batched object from a series of entities - in order to benefit from this behaviour. - Batching has implications of it's own though: - @li Batched geometry cannot be subdivided; that means that the whole - group will be displayed, or none of it will. This obivously has - culling issues. - @li A single world transform must apply to the entire batch. Therefore - once you have batched things, you can't move them around relative to - each other. That's why this class is most useful when dealing with - static geometry (hence the name). In addition, geometry is - effectively duplicated, so if you add 3 entities based on the same - mesh in different positions, they will use 3 times the geometry - space than the movable version (which re-uses the same geometry). - So you trade memory and flexibility of movement for pure speed when - using this class. - @li A single material must apply for each batch. In fact this class - allows you to use multiple materials, but you should be aware that - internally this means that there is one batch per material. - Therefore you won't gain as much benefit from the batching if you - use many different materials; try to keep the number down. - @par - In order to retain some sort of culling, this class will batch up - meshes in localised regions. The size and shape of these blocks is - controlled by the SceneManager which constructs this object, since it - makes sense to batch things up in the most appropriate way given the - existing partitioning of the scene. - @par - The LOD settings of both the Mesh and the Materials used in - constructing this static geometry will be respected. This means that - if you use meshes/materials which have LOD, batches in the distance - will have a lower polygon count or material detail to those in the - foreground. Since each mesh might have different LOD distances, during - build the furthest distance at each LOD level from all meshes - in that region is used. This means all the LOD levels change at the - same time, but at the furthest distance of any of them (so quality is - not degraded). Be aware that using Mesh LOD in this class will - further increase the memory required. Only generated LOD - is supported for meshes. - @par - There are 2 ways you can add geometry to this class; you can add - Entity objects directly with predetermined positions, scales and - orientations, or you can add an entire SceneNode and it's subtree, - including all the objects attached to it. Once you've added everything - you need to, you have to call build() the fix the geometry in place. - @note - This class is not a replacement for world geometry (@see - SceneManager::setWorldGeometry). The single most efficient way to - render large amounts of static geometry is to use a SceneManager which - is specialised for dealing with that particular world structure. - However, this class does provide you with a good 'halfway house' - between generalised movable geometry (Entity) which works with all - SceneManagers but isn't efficient when using very large numbers, and - highly specialised world geometry which is extremely fast but not - generic and typically requires custom world editors. - @par - You should not construct instances of this class directly; instead, cal - SceneManager::createStaticGeometry, which gives the SceneManager the - option of providing you with a specialised version of this class if it - wishes, and also handles the memory management for you like other - classes. - @note - Warning: this class only works with indexed triangle lists at the moment, - do not pass it triangle strips, fans or lines / points, or unindexed geometry. - */ - class _OgreExport StaticGeometry : public BatchedGeometryAlloc - { - public: - /** Struct holding geometry optimised per SubMesh / LOD level, ready - for copying to instances. - @remarks - Since we're going to be duplicating geometry lots of times, it's - far more important that we don't have redundant vertex data. If a - SubMesh uses shared geometry, or we're looking at a lower LOD, not - all the vertices are being referenced by faces on that submesh. - Therefore to duplicate them, potentially hundreds or even thousands - of times, would be extremely wasteful. Therefore, if a SubMesh at - a given LOD has wastage, we create an optimised version of it's - geometry which is ready for copying with no wastage. - */ - class _OgrePrivate OptimisedSubMeshGeometry : public BatchedGeometryAlloc - { - public: - OptimisedSubMeshGeometry() :vertexData(0), indexData(0) {} - ~OptimisedSubMeshGeometry() - { - OGRE_DELETE vertexData; - OGRE_DELETE indexData; - } - VertexData *vertexData; - IndexData *indexData; - }; - typedef list::type OptimisedSubMeshGeometryList; - /// Saved link between SubMesh at a LOD and vertex/index data - /// May point to original or optimised geometry - struct SubMeshLodGeometryLink - { - VertexData* vertexData; - IndexData* indexData; - }; - typedef vector::type SubMeshLodGeometryLinkList; - typedef map::type SubMeshGeometryLookup; - /// Structure recording a queued submesh for the build - struct QueuedSubMesh : public BatchedGeometryAlloc - { - SubMesh* submesh; - /// Link to LOD list of geometry, potentially optimised - SubMeshLodGeometryLinkList* geometryLodList; - String materialName; - Vector3 position; - Quaternion orientation; - Vector3 scale; - /// Pre-transformed world AABB - AxisAlignedBox worldBounds; - }; - typedef vector::type QueuedSubMeshList; - /// Structure recording a queued geometry for low level builds - struct QueuedGeometry : public BatchedGeometryAlloc - { - SubMeshLodGeometryLink* geometry; - Vector3 position; - Quaternion orientation; - Vector3 scale; - }; - typedef vector::type QueuedGeometryList; - - // forward declarations - class LODBucket; - class MaterialBucket; - class Region; - - /** A GeometryBucket is a the lowest level bucket where geometry with - the same vertex & index format is stored. It also acts as the - renderable. - */ - class _OgreExport GeometryBucket : public Renderable, public BatchedGeometryAlloc - { - protected: - /// Geometry which has been queued up pre-build (not for deallocation) - QueuedGeometryList mQueuedGeometry; - /// Pointer to parent bucket - MaterialBucket* mParent; - /// String identifying the vertex / index format - String mFormatString; - /// Vertex information, includes current number of vertices - /// committed to be a part of this bucket - VertexData* mVertexData; - /// Index information, includes index type which limits the max - /// number of vertices which are allowed in one bucket - IndexData* mIndexData; - /// Size of indexes - HardwareIndexBuffer::IndexType mIndexType; - /// Maximum vertex indexable - size_t mMaxVertexIndex; - - template - void copyIndexes(const T* src, T* dst, size_t count, size_t indexOffset) - { - if (indexOffset == 0) - { - memcpy(dst, src, sizeof(T) * count); - } - else - { - while(count--) - { - *dst++ = static_cast(*src++ + indexOffset); - } - } - } - public: - GeometryBucket(MaterialBucket* parent, const String& formatString, - const VertexData* vData, const IndexData* iData); - virtual ~GeometryBucket(); - MaterialBucket* getParent(void) { return mParent; } - /// Get the vertex data for this geometry - const VertexData* getVertexData(void) const { return mVertexData; } - /// Get the index data for this geometry - const IndexData* getIndexData(void) const { return mIndexData; } - /// @copydoc Renderable::getMaterial - const MaterialPtr& getMaterial(void) const; - Technique* getTechnique(void) const; - void getRenderOperation(RenderOperation& op); - void getWorldTransforms(Matrix4* xform) const; - Real getSquaredViewDepth(const Camera* cam) const; - const LightList& getLights(void) const; - bool getCastsShadows(void) const; - - /** Try to assign geometry to this bucket. - @return false if there is no room left in this bucket - */ - bool assign(QueuedGeometry* qsm); - /// Build - void build(bool stencilShadows); - /// Dump contents for diagnostics - void dump(std::ofstream& of) const; - }; - /** A MaterialBucket is a collection of smaller buckets with the same - Material (and implicitly the same LOD). */ - class _OgreExport MaterialBucket : public BatchedGeometryAlloc - { - public: - /// list of Geometry Buckets in this region - typedef vector::type GeometryBucketList; - protected: - /// Pointer to parent LODBucket - LODBucket* mParent; - /// Material being used - String mMaterialName; - /// Pointer to material being used - MaterialPtr mMaterial; - /// Active technique - Technique* mTechnique; - - /// list of Geometry Buckets in this region - GeometryBucketList mGeometryBucketList; - // index to current Geometry Buckets for a given geometry format - typedef map::type CurrentGeometryMap; - CurrentGeometryMap mCurrentGeometryMap; - /// Get a packed string identifying the geometry format - String getGeometryFormatString(SubMeshLodGeometryLink* geom); - - public: - MaterialBucket(LODBucket* parent, const String& materialName); - virtual ~MaterialBucket(); - LODBucket* getParent(void) { return mParent; } - /// Get the material name - const String& getMaterialName(void) const { return mMaterialName; } - /// Assign geometry to this bucket - void assign(QueuedGeometry* qsm); - /// Build - void build(bool stencilShadows); - /// Add children to the render queue - void addRenderables(RenderQueue* queue, uint8 group, - Real lodValue); - /// Get the material for this bucket - const MaterialPtr& getMaterial(void) const { return mMaterial; } - /// Iterator over geometry - typedef VectorIterator GeometryIterator; - /// Get an iterator over the contained geometry - GeometryIterator getGeometryIterator(void); - /// Get the current Technique - Technique* getCurrentTechnique(void) const { return mTechnique; } - /// Dump contents for diagnostics - void dump(std::ofstream& of) const; - void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); - }; - /** A LODBucket is a collection of smaller buckets with the same LOD. - @remarks - LOD refers to Mesh LOD here. Material LOD can change separately - at the next bucket down from this. - */ - class _OgreExport LODBucket : public BatchedGeometryAlloc - { - public: - /// Lookup of Material Buckets in this region - typedef map::type MaterialBucketMap; - protected: - /** Nested class to allow shadows. */ - class _OgreExport LODShadowRenderable : public ShadowRenderable - { - protected: - LODBucket* mParent; - // Shared link to position buffer - HardwareVertexBufferSharedPtr mPositionBuffer; - // Shared link to w-coord buffer (optional) - HardwareVertexBufferSharedPtr mWBuffer; - - public: - LODShadowRenderable(LODBucket* parent, - HardwareIndexBufferSharedPtr* indexBuffer, const VertexData* vertexData, - bool createSeparateLightCap, bool isLightCap = false); - ~LODShadowRenderable(); - /// Overridden from ShadowRenderable - void getWorldTransforms(Matrix4* xform) const; - HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; } - HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; } - /// Overridden from ShadowRenderable - virtual void rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer); - - }; - /// Pointer to parent region - Region* mParent; - /// LOD level (0 == full LOD) - unsigned short mLod; - /// LOD value at which this LOD starts to apply (squared) - Real mLodValue; - /// Lookup of Material Buckets in this region - MaterialBucketMap mMaterialBucketMap; - /// Geometry queued for a single LOD (deallocated here) - QueuedGeometryList mQueuedGeometryList; - /// Edge list, used if stencil shadow casting is enabled - EdgeData* mEdgeList; - /// Is a vertex program in use somewhere in this group? - bool mVertexProgramInUse; - /// List of shadow renderables - ShadowCaster::ShadowRenderableList mShadowRenderables; - public: - LODBucket(Region* parent, unsigned short lod, Real lodValue); - virtual ~LODBucket(); - Region* getParent(void) { return mParent; } - /// Get the LOD index - ushort getLod(void) const { return mLod; } - /// Get the LOD value - Real getLodValue(void) const { return mLodValue; } - /// Assign a queued submesh to this bucket, using specified mesh LOD - void assign(QueuedSubMesh* qsm, ushort atLod); - /// Build - void build(bool stencilShadows); - /// Add children to the render queue - void addRenderables(RenderQueue* queue, uint8 group, - Real lodValue); - /// Iterator over the materials in this LOD - typedef MapIterator MaterialIterator; - /// Get an iterator over the materials in this LOD - MaterialIterator getMaterialIterator(void); - /// Dump contents for diagnostics - void dump(std::ofstream& of) const; - void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); - EdgeData* getEdgeList() const { return mEdgeList; } - ShadowCaster::ShadowRenderableList& getShadowRenderableList() { return mShadowRenderables; } - bool isVertexProgramInUse() const { return mVertexProgramInUse; } - void updateShadowRenderables( - ShadowTechnique shadowTechnique, const Vector4& lightPos, - HardwareIndexBufferSharedPtr* indexBuffer, - bool extrudeVertices, Real extrusionDistance, unsigned long flags = 0 ); - - }; - /** The details of a topological region which is the highest level of - partitioning for this class. - @remarks - The size & shape of regions entirely depends on the SceneManager - specific implementation. It is a MovableObject since it will be - attached to a node based on the local centre - in practice it - won't actually move (although in theory it could). - */ - class _OgreExport Region : public MovableObject - { + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Pre-transforms and batches up meshes for efficient use as static + geometry in a scene. + @remarks + Modern graphics cards (GPUs) prefer to receive geometry in large + batches. It is orders of magnitude faster to render 10 batches + of 10,000 triangles than it is to render 10,000 batches of 10 + triangles, even though both result in the same number of on-screen + triangles. + @par + Therefore it is important when you are rendering a lot of geometry to + batch things up into as few rendering calls as possible. This + class allows you to build a batched object from a series of entities + in order to benefit from this behaviour. + Batching has implications of it's own though: + @li Batched geometry cannot be subdivided; that means that the whole + group will be displayed, or none of it will. This obivously has + culling issues. + @li A single world transform must apply to the entire batch. Therefore + once you have batched things, you can't move them around relative to + each other. That's why this class is most useful when dealing with + static geometry (hence the name). In addition, geometry is + effectively duplicated, so if you add 3 entities based on the same + mesh in different positions, they will use 3 times the geometry + space than the movable version (which re-uses the same geometry). + So you trade memory and flexibility of movement for pure speed when + using this class. + @li A single material must apply for each batch. In fact this class + allows you to use multiple materials, but you should be aware that + internally this means that there is one batch per material. + Therefore you won't gain as much benefit from the batching if you + use many different materials; try to keep the number down. + @par + In order to retain some sort of culling, this class will batch up + meshes in localised regions. The size and shape of these blocks is + controlled by the SceneManager which constructs this object, since it + makes sense to batch things up in the most appropriate way given the + existing partitioning of the scene. + @par + The LOD settings of both the Mesh and the Materials used in + constructing this static geometry will be respected. This means that + if you use meshes/materials which have LOD, batches in the distance + will have a lower polygon count or material detail to those in the + foreground. Since each mesh might have different LOD distances, during + build the furthest distance at each LOD level from all meshes + in that region is used. This means all the LOD levels change at the + same time, but at the furthest distance of any of them (so quality is + not degraded). Be aware that using Mesh LOD in this class will + further increase the memory required. Only generated LOD + is supported for meshes. + @par + There are 2 ways you can add geometry to this class; you can add + Entity objects directly with predetermined positions, scales and + orientations, or you can add an entire SceneNode and it's subtree, + including all the objects attached to it. Once you've added everything + you need to, you have to call build() the fix the geometry in place. + @note + This class is not a replacement for world geometry (@see + SceneManager::setWorldGeometry). The single most efficient way to + render large amounts of static geometry is to use a SceneManager which + is specialised for dealing with that particular world structure. + However, this class does provide you with a good 'halfway house' + between generalised movable geometry (Entity) which works with all + SceneManagers but isn't efficient when using very large numbers, and + highly specialised world geometry which is extremely fast but not + generic and typically requires custom world editors. + @par + You should not construct instances of this class directly; instead, cal + SceneManager::createStaticGeometry, which gives the SceneManager the + option of providing you with a specialised version of this class if it + wishes, and also handles the memory management for you like other + classes. + @note + Warning: this class only works with indexed triangle lists at the moment, + do not pass it triangle strips, fans or lines / points, or unindexed geometry. + */ + class _OgreExport StaticGeometry : public BatchedGeometryAlloc + { + public: + /** Struct holding geometry optimised per SubMesh / LOD level, ready + for copying to instances. + @remarks + Since we're going to be duplicating geometry lots of times, it's + far more important that we don't have redundant vertex data. If a + SubMesh uses shared geometry, or we're looking at a lower LOD, not + all the vertices are being referenced by faces on that submesh. + Therefore to duplicate them, potentially hundreds or even thousands + of times, would be extremely wasteful. Therefore, if a SubMesh at + a given LOD has wastage, we create an optimised version of it's + geometry which is ready for copying with no wastage. + */ + class _OgrePrivate OptimisedSubMeshGeometry : public BatchedGeometryAlloc + { + public: + OptimisedSubMeshGeometry() :vertexData(0), indexData(0) {} + ~OptimisedSubMeshGeometry() + { + OGRE_DELETE vertexData; + OGRE_DELETE indexData; + } + VertexData *vertexData; + IndexData *indexData; + }; + typedef list::type OptimisedSubMeshGeometryList; + /// Saved link between SubMesh at a LOD and vertex/index data + /// May point to original or optimised geometry + struct SubMeshLodGeometryLink + { + VertexData* vertexData; + IndexData* indexData; + }; + typedef vector::type SubMeshLodGeometryLinkList; + typedef map::type SubMeshGeometryLookup; + /// Structure recording a queued submesh for the build + struct QueuedSubMesh : public BatchedGeometryAlloc + { + SubMesh* submesh; + /// Link to LOD list of geometry, potentially optimised + SubMeshLodGeometryLinkList* geometryLodList; + String materialName; + Vector3 position; + Quaternion orientation; + Vector3 scale; + /// Pre-transformed world AABB + AxisAlignedBox worldBounds; + }; + typedef vector::type QueuedSubMeshList; + /// Structure recording a queued geometry for low level builds + struct QueuedGeometry : public BatchedGeometryAlloc + { + SubMeshLodGeometryLink* geometry; + Vector3 position; + Quaternion orientation; + Vector3 scale; + }; + typedef vector::type QueuedGeometryList; + + // forward declarations + class LODBucket; + class MaterialBucket; + class Region; + + /** A GeometryBucket is a the lowest level bucket where geometry with + the same vertex & index format is stored. It also acts as the + renderable. + */ + class _OgreExport GeometryBucket : public Renderable, public BatchedGeometryAlloc + { + protected: + /// Geometry which has been queued up pre-build (not for deallocation) + QueuedGeometryList mQueuedGeometry; + /// Pointer to parent bucket + MaterialBucket* mParent; + /// String identifying the vertex / index format + String mFormatString; + /// Vertex information, includes current number of vertices + /// committed to be a part of this bucket + VertexData* mVertexData; + /// Index information, includes index type which limits the max + /// number of vertices which are allowed in one bucket + IndexData* mIndexData; + /// Size of indexes + HardwareIndexBuffer::IndexType mIndexType; + /// Maximum vertex indexable + size_t mMaxVertexIndex; + + template + void copyIndexes(const T* src, T* dst, size_t count, size_t indexOffset) + { + if (indexOffset == 0) + { + memcpy(dst, src, sizeof(T) * count); + } + else + { + while(count--) + { + *dst++ = static_cast(*src++ + indexOffset); + } + } + } + public: + GeometryBucket(MaterialBucket* parent, const String& formatString, + const VertexData* vData, const IndexData* iData); + virtual ~GeometryBucket(); + MaterialBucket* getParent(void) { return mParent; } + /// Get the vertex data for this geometry + const VertexData* getVertexData(void) const { return mVertexData; } + /// Get the index data for this geometry + const IndexData* getIndexData(void) const { return mIndexData; } + /// @copydoc Renderable::getMaterial + const MaterialPtr& getMaterial(void) const; + Technique* getTechnique(void) const; + void getRenderOperation(RenderOperation& op); + void getWorldTransforms(Matrix4* xform) const; + Real getSquaredViewDepth(const Camera* cam) const; + const LightList& getLights(void) const; + bool getCastsShadows(void) const; + + /** Try to assign geometry to this bucket. + @return false if there is no room left in this bucket + */ + bool assign(QueuedGeometry* qsm); + /// Build + void build(bool stencilShadows); + /// Dump contents for diagnostics + void dump(std::ofstream& of) const; + }; + /** A MaterialBucket is a collection of smaller buckets with the same + Material (and implicitly the same LOD). */ + class _OgreExport MaterialBucket : public BatchedGeometryAlloc + { + public: + /// list of Geometry Buckets in this region + typedef vector::type GeometryBucketList; + protected: + /// Pointer to parent LODBucket + LODBucket* mParent; + /// Material being used + String mMaterialName; + /// Pointer to material being used + MaterialPtr mMaterial; + /// Active technique + Technique* mTechnique; + + /// list of Geometry Buckets in this region + GeometryBucketList mGeometryBucketList; + // index to current Geometry Buckets for a given geometry format + typedef map::type CurrentGeometryMap; + CurrentGeometryMap mCurrentGeometryMap; + /// Get a packed string identifying the geometry format + String getGeometryFormatString(SubMeshLodGeometryLink* geom); + + public: + MaterialBucket(LODBucket* parent, const String& materialName); + virtual ~MaterialBucket(); + LODBucket* getParent(void) { return mParent; } + /// Get the material name + const String& getMaterialName(void) const { return mMaterialName; } + /// Assign geometry to this bucket + void assign(QueuedGeometry* qsm); + /// Build + void build(bool stencilShadows); + /// Add children to the render queue + void addRenderables(RenderQueue* queue, uint8 group, + Real lodValue); + /// Get the material for this bucket + const MaterialPtr& getMaterial(void) const { return mMaterial; } + /// Iterator over geometry + typedef VectorIterator GeometryIterator; + /// Get an iterator over the contained geometry + GeometryIterator getGeometryIterator(void); + /// Get the current Technique + Technique* getCurrentTechnique(void) const { return mTechnique; } + /// Dump contents for diagnostics + void dump(std::ofstream& of) const; + void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); + }; + /** A LODBucket is a collection of smaller buckets with the same LOD. + @remarks + LOD refers to Mesh LOD here. Material LOD can change separately + at the next bucket down from this. + */ + class _OgreExport LODBucket : public BatchedGeometryAlloc + { + public: + /// Lookup of Material Buckets in this region + typedef map::type MaterialBucketMap; + protected: + /** Nested class to allow shadows. */ + class _OgreExport LODShadowRenderable : public ShadowRenderable + { + protected: + LODBucket* mParent; + // Shared link to position buffer + HardwareVertexBufferSharedPtr mPositionBuffer; + // Shared link to w-coord buffer (optional) + HardwareVertexBufferSharedPtr mWBuffer; + + public: + LODShadowRenderable(LODBucket* parent, + HardwareIndexBufferSharedPtr* indexBuffer, const VertexData* vertexData, + bool createSeparateLightCap, bool isLightCap = false); + ~LODShadowRenderable(); + /// Overridden from ShadowRenderable + void getWorldTransforms(Matrix4* xform) const; + HardwareVertexBufferSharedPtr getPositionBuffer(void) { return mPositionBuffer; } + HardwareVertexBufferSharedPtr getWBuffer(void) { return mWBuffer; } + /// Overridden from ShadowRenderable + virtual void rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer); + + }; + /// Pointer to parent region + Region* mParent; + /// LOD level (0 == full LOD) + unsigned short mLod; + /// LOD value at which this LOD starts to apply (squared) + Real mLodValue; + /// Lookup of Material Buckets in this region + MaterialBucketMap mMaterialBucketMap; + /// Geometry queued for a single LOD (deallocated here) + QueuedGeometryList mQueuedGeometryList; + /// Edge list, used if stencil shadow casting is enabled + EdgeData* mEdgeList; + /// Is a vertex program in use somewhere in this group? + bool mVertexProgramInUse; + /// List of shadow renderables + ShadowCaster::ShadowRenderableList mShadowRenderables; + public: + LODBucket(Region* parent, unsigned short lod, Real lodValue); + virtual ~LODBucket(); + Region* getParent(void) { return mParent; } + /// Get the LOD index + ushort getLod(void) const { return mLod; } + /// Get the LOD value + Real getLodValue(void) const { return mLodValue; } + /// Assign a queued submesh to this bucket, using specified mesh LOD + void assign(QueuedSubMesh* qsm, ushort atLod); + /// Build + void build(bool stencilShadows); + /// Add children to the render queue + void addRenderables(RenderQueue* queue, uint8 group, + Real lodValue); + /// Iterator over the materials in this LOD + typedef MapIterator MaterialIterator; + /// Get an iterator over the materials in this LOD + MaterialIterator getMaterialIterator(void); + /// Dump contents for diagnostics + void dump(std::ofstream& of) const; + void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables); + EdgeData* getEdgeList() const { return mEdgeList; } + ShadowCaster::ShadowRenderableList& getShadowRenderableList() { return mShadowRenderables; } + bool isVertexProgramInUse() const { return mVertexProgramInUse; } + void updateShadowRenderables( + ShadowTechnique shadowTechnique, const Vector4& lightPos, + HardwareIndexBufferSharedPtr* indexBuffer, + bool extrudeVertices, Real extrusionDistance, unsigned long flags = 0 ); + + }; + /** The details of a topological region which is the highest level of + partitioning for this class. + @remarks + The size & shape of regions entirely depends on the SceneManager + specific implementation. It is a MovableObject since it will be + attached to a node based on the local centre - in practice it + won't actually move (although in theory it could). + */ + class _OgreExport Region : public MovableObject + { friend class MaterialBucket; friend class GeometryBucket; - public: - /// list of LOD Buckets in this region - typedef vector::type LODBucketList; - protected: - /// Parent static geometry - StaticGeometry* mParent; - /// Scene manager link - SceneManager* mSceneMgr; - /// Scene node - SceneNode* mNode; - /// Local list of queued meshes (not used for deallocation) - QueuedSubMeshList mQueuedSubMeshes; - /// Unique identifier for the region - uint32 mRegionID; - /// Center of the region - Vector3 mCentre; - /// LOD values as built up - use the max at each level - Mesh::LodValueList mLodValues; - /// Local AABB relative to region centre - AxisAlignedBox mAABB; - /// Local bounding radius - Real mBoundingRadius; - /// The current LOD level, as determined from the last camera - ushort mCurrentLod; - /// Current LOD value, passed on to do material LOD later - Real mLodValue; - /// List of LOD buckets - LODBucketList mLodBucketList; - /// List of lights for this region - mutable LightList mLightList; - /// The last frame that this light list was updated in - mutable ulong mLightListUpdated; + public: + /// list of LOD Buckets in this region + typedef vector::type LODBucketList; + protected: + /// Parent static geometry + StaticGeometry* mParent; + /// Scene manager link + SceneManager* mSceneMgr; + /// Scene node + SceneNode* mNode; + /// Local list of queued meshes (not used for deallocation) + QueuedSubMeshList mQueuedSubMeshes; + /// Unique identifier for the region + uint32 mRegionID; + /// Center of the region + Vector3 mCentre; + /// LOD values as built up - use the max at each level + Mesh::LodValueList mLodValues; + /// Local AABB relative to region centre + AxisAlignedBox mAABB; + /// Local bounding radius + Real mBoundingRadius; + /// The current LOD level, as determined from the last camera + ushort mCurrentLod; + /// Current LOD value, passed on to do material LOD later + Real mLodValue; + /// List of LOD buckets + LODBucketList mLodBucketList; + /// List of lights for this region + mutable LightList mLightList; + /// The last frame that this light list was updated in + mutable ulong mLightListUpdated; /// LOD strategy reference const LodStrategy *mLodStrategy; /// Current camera @@ -431,323 +431,323 @@ namespace Ogre { /// Cached squared view depth value to avoid recalculation by GeometryBucket Real mSquaredViewDepth; - public: - Region(StaticGeometry* parent, const String& name, SceneManager* mgr, - uint32 regionID, const Vector3& centre); - virtual ~Region(); - // more fields can be added in subclasses - StaticGeometry* getParent(void) const { return mParent;} - /// Assign a queued mesh to this region, read for final build - void assign(QueuedSubMesh* qmesh); - /// Build this region - void build(bool stencilShadows); - /// Get the region ID of this region - uint32 getID(void) const { return mRegionID; } - /// Get the centre point of the region - const Vector3& getCentre(void) const { return mCentre; } - const String& getMovableType(void) const; - void _notifyCurrentCamera(Camera* cam); - const AxisAlignedBox& getBoundingBox(void) const; - Real getBoundingRadius(void) const; - void _updateRenderQueue(RenderQueue* queue); - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false); - bool isVisible(void) const; - uint32 getTypeFlags(void) const; - - typedef VectorIterator LODIterator; - /// Get an iterator over the LODs in this region - LODIterator getLODIterator(void); - /// @copydoc ShadowCaster::getShadowVolumeRenderableIterator - ShadowRenderableListIterator getShadowVolumeRenderableIterator( - ShadowTechnique shadowTechnique, const Light* light, - HardwareIndexBufferSharedPtr* indexBuffer, size_t* indexBufferUsedSize, - bool extrudeVertices, Real extrusionDistance, unsigned long flags = 0 ); - /// Overridden from MovableObject - EdgeData* getEdgeList(void); - /** Overridden member from ShadowCaster. */ - bool hasEdgeList(void); - - /// Dump contents for diagnostics - void dump(std::ofstream& of) const; - - }; - /** Indexed region map based on packed x/y/z region index, 10 bits for - each axis. - @remarks - Regions are indexed 0-1023 in all axes, where for example region - 0 in the x axis begins at mOrigin.x + (mRegionDimensions.x * -512), - and region 1023 ends at mOrigin + (mRegionDimensions.x * 512). - */ - typedef map::type RegionMap; - protected: - // General state & settings - SceneManager* mOwner; - String mName; - bool mBuilt; - Real mUpperDistance; - Real mSquaredUpperDistance; - bool mCastShadows; - Vector3 mRegionDimensions; - Vector3 mHalfRegionDimensions; - Vector3 mOrigin; - bool mVisible; + public: + Region(StaticGeometry* parent, const String& name, SceneManager* mgr, + uint32 regionID, const Vector3& centre); + virtual ~Region(); + // more fields can be added in subclasses + StaticGeometry* getParent(void) const { return mParent;} + /// Assign a queued mesh to this region, read for final build + void assign(QueuedSubMesh* qmesh); + /// Build this region + void build(bool stencilShadows); + /// Get the region ID of this region + uint32 getID(void) const { return mRegionID; } + /// Get the centre point of the region + const Vector3& getCentre(void) const { return mCentre; } + const String& getMovableType(void) const; + void _notifyCurrentCamera(Camera* cam); + const AxisAlignedBox& getBoundingBox(void) const; + Real getBoundingRadius(void) const; + void _updateRenderQueue(RenderQueue* queue); + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false); + bool isVisible(void) const; + uint32 getTypeFlags(void) const; + + typedef VectorIterator LODIterator; + /// Get an iterator over the LODs in this region + LODIterator getLODIterator(void); + /// @copydoc ShadowCaster::getShadowVolumeRenderableIterator + ShadowRenderableListIterator getShadowVolumeRenderableIterator( + ShadowTechnique shadowTechnique, const Light* light, + HardwareIndexBufferSharedPtr* indexBuffer, size_t* indexBufferUsedSize, + bool extrudeVertices, Real extrusionDistance, unsigned long flags = 0 ); + /// Overridden from MovableObject + EdgeData* getEdgeList(void); + /** Overridden member from ShadowCaster. */ + bool hasEdgeList(void); + + /// Dump contents for diagnostics + void dump(std::ofstream& of) const; + + }; + /** Indexed region map based on packed x/y/z region index, 10 bits for + each axis. + @remarks + Regions are indexed 0-1023 in all axes, where for example region + 0 in the x axis begins at mOrigin.x + (mRegionDimensions.x * -512), + and region 1023 ends at mOrigin + (mRegionDimensions.x * 512). + */ + typedef map::type RegionMap; + protected: + // General state & settings + SceneManager* mOwner; + String mName; + bool mBuilt; + Real mUpperDistance; + Real mSquaredUpperDistance; + bool mCastShadows; + Vector3 mRegionDimensions; + Vector3 mHalfRegionDimensions; + Vector3 mOrigin; + bool mVisible; /// The render queue to use when rendering this object uint8 mRenderQueueID; - /// Flags whether the RenderQueue's default should be used. - bool mRenderQueueIDSet; - /// Stores the visibility flags for the regions - uint32 mVisibilityFlags; - - QueuedSubMeshList mQueuedSubMeshes; - - /// List of geometry which has been optimised for SubMesh use - /// This is the primary storage used for cleaning up later - OptimisedSubMeshGeometryList mOptimisedSubMeshGeometryList; - - /** Cached links from SubMeshes to (potentially optimised) geometry - This is not used for deletion since the lookup may reference - original vertex data - */ - SubMeshGeometryLookup mSubMeshGeometryLookup; - - /// Map of regions - RegionMap mRegionMap; - - /** Virtual method for getting a region most suitable for the - passed in bounds. Can be overridden by subclasses. - */ - virtual Region* getRegion(const AxisAlignedBox& bounds, bool autoCreate); - /** Get the region within which a point lies */ - virtual Region* getRegion(const Vector3& point, bool autoCreate); - /** Get the region using indexes */ - virtual Region* getRegion(ushort x, ushort y, ushort z, bool autoCreate); - /** Get the region using a packed index, returns null if it doesn't exist. */ - virtual Region* getRegion(uint32 index); - /** Get the region indexes for a point. - */ - virtual void getRegionIndexes(const Vector3& point, - ushort& x, ushort& y, ushort& z); - /** Pack 3 indexes into a single index value - */ - virtual uint32 packIndex(ushort x, ushort y, ushort z); - /** Get the volume intersection for an indexed region with some bounds. - */ - virtual Real getVolumeIntersection(const AxisAlignedBox& box, - ushort x, ushort y, ushort z); - /** Get the bounds of an indexed region. - */ - virtual AxisAlignedBox getRegionBounds(ushort x, ushort y, ushort z); - /** Get the centre of an indexed region. - */ - virtual Vector3 getRegionCentre(ushort x, ushort y, ushort z); - /** Calculate world bounds from a set of vertex data. */ - virtual AxisAlignedBox calculateBounds(VertexData* vertexData, - const Vector3& position, const Quaternion& orientation, - const Vector3& scale); - /** Look up or calculate the geometry data to use for this SubMesh */ - SubMeshLodGeometryLinkList* determineGeometry(SubMesh* sm); - /** Split some shared geometry into dedicated geometry. */ - void splitGeometry(VertexData* vd, IndexData* id, - SubMeshLodGeometryLink* targetGeomLink); - - typedef map::type IndexRemap; - /** Method for figuring out which vertices are used by an index buffer - and calculating a remap lookup for a vertex buffer just containing - those vertices. - */ - template - void buildIndexRemap(T* pBuffer, size_t numIndexes, IndexRemap& remap) - { - remap.clear(); - for (size_t i = 0; i < numIndexes; ++i) - { - // use insert since duplicates are silently discarded - remap.insert(IndexRemap::value_type(*pBuffer++, remap.size())); - // this will have mapped oldindex -> new index IF oldindex - // wasn't already there - } - } - /** Method for altering indexes based on a remap. */ - template - void remapIndexes(T* src, T* dst, const IndexRemap& remap, - size_t numIndexes) - { - for (size_t i = 0; i < numIndexes; ++i) - { - // look up original and map to target - IndexRemap::const_iterator ix = remap.find(*src++); - assert(ix != remap.end()); - *dst++ = static_cast(ix->second); - } - } - - public: - /// Constructor; do not use directly (@see SceneManager::createStaticGeometry) - StaticGeometry(SceneManager* owner, const String& name); - /// Destructor - virtual ~StaticGeometry(); - - /// Get the name of this object - const String& getName(void) const { return mName; } - /** Adds an Entity to the static geometry. - @remarks - This method takes an existing Entity and adds its details to the - list of elements to include when building. Note that the Entity - itself is not copied or referenced in this method; an Entity is - passed simply so that you can change the materials of attached - SubEntity objects if you want. You can add the same Entity - instance multiple times with different material settings - completely safely, and destroy the Entity before destroying - this StaticGeometry if you like. The Entity passed in is simply - used as a definition. - @note Must be called before 'build'. - @param ent The Entity to use as a definition (the Mesh and Materials - referenced will be recorded for the build call). - @param position The world position at which to add this Entity - @param orientation The world orientation at which to add this Entity - @param scale The scale at which to add this entity - */ - virtual void addEntity(Entity* ent, const Vector3& position, - const Quaternion& orientation = Quaternion::IDENTITY, - const Vector3& scale = Vector3::UNIT_SCALE); - - /** Adds all the Entity objects attached to a SceneNode and all it's - children to the static geometry. - @remarks - This method performs just like addEntity, except it adds all the - entities attached to an entire sub-tree to the geometry. - The position / orientation / scale parameters are taken from the - node structure instead of being specified manually. - @note - The SceneNode you pass in will not be automatically detached from - it's parent, so if you have this node already attached to the scene - graph, you will need to remove it if you wish to avoid the overhead - of rendering both the original objects and their new static - versions! We don't do this for you incase you are preparing this - in advance and so don't want the originals detached yet. - @note Must be called before 'build'. - @param node Pointer to the node to use to provide a set of Entity - templates - */ - virtual void addSceneNode(const SceneNode* node); - - /** Build the geometry. - @remarks - Based on all the entities which have been added, and the batching - options which have been set, this method constructs the batched - geometry structures required. The batches are added to the scene - and will be rendered unless you specifically hide them. - @note - Once you have called this method, you can no longer add any more - entities. - */ - virtual void build(void); - - /** Destroys all the built geometry state (reverse of build). - @remarks - You can call build() again after this and it will pick up all the - same entities / nodes you queued last time. - */ - virtual void destroy(void); - - /** Clears any of the entities / nodes added to this geometry and - destroys anything which has already been built. - */ - virtual void reset(void); - - /** Sets the distance at which batches are no longer rendered. - @remarks - This lets you turn off batches at a given distance. This can be - useful for things like detail meshes (grass, foliage etc) and could - be combined with a shader which fades the geometry out beforehand - to lessen the effect. - @param dist Distance beyond which the batches will not be rendered - (the default is 0, which means batches are always rendered). - */ - virtual void setRenderingDistance(Real dist) { - mUpperDistance = dist; - mSquaredUpperDistance = mUpperDistance * mUpperDistance; - } - - /** Gets the distance at which batches are no longer rendered. */ - virtual Real getRenderingDistance(void) const { return mUpperDistance; } - - /** Gets the squared distance at which batches are no longer rendered. */ - virtual Real getSquaredRenderingDistance(void) const - { return mSquaredUpperDistance; } - - /** Hides or shows all the batches. */ - virtual void setVisible(bool visible); - - /** Are the batches visible? */ - virtual bool isVisible(void) const { return mVisible; } - - /** Sets whether this geometry should cast shadows. - @remarks - No matter what the settings on the original entities, - the StaticGeometry class defaults to not casting shadows. - This is because, being static, unless you have moving lights - you'd be better to use precalculated shadows of some sort. - However, if you need them, you can enable them using this - method. If the SceneManager is set up to use stencil shadows, - edge lists will be copied from the underlying meshes on build. - It is essential that all meshes support stencil shadows in this - case. - @note If you intend to use stencil shadows, you must set this to - true before calling 'build' as well as making sure you set the - scene's shadow type (that should always be the first thing you do - anyway). You can turn shadows off temporarily but they can never - be turned on if they were not at the time of the build. - */ - virtual void setCastShadows(bool castShadows); - /// Will the geometry from this object cast shadows? - virtual bool getCastShadows(void) { return mCastShadows; } - - /** Sets the size of a single region of geometry. - @remarks - This method allows you to configure the physical world size of - each region, so you can balance culling against batch size. Entities - will be fitted within the batch they most closely fit, and the - eventual bounds of each batch may well be slightly larger than this - if they overlap a little. The default is Vector3(1000, 1000, 1000). - @note Must be called before 'build'. - @param size Vector3 expressing the 3D size of each region. - */ - virtual void setRegionDimensions(const Vector3& size) { - mRegionDimensions = size; - mHalfRegionDimensions = size * 0.5; - } - /** Gets the size of a single batch of geometry. */ - virtual const Vector3& getRegionDimensions(void) const { return mRegionDimensions; } - /** Sets the origin of the geometry. - @remarks - This method allows you to configure the world centre of the geometry, - thus the place which all regions surround. You probably don't need - to mess with this unless you have a seriously large world, since the - default set up can handle an area 1024 * mRegionDimensions, and - the sparseness of population is no issue when it comes to rendering. - The default is Vector3(0,0,0). - @note Must be called before 'build'. - @param origin Vector3 expressing the 3D origin of the geometry. - */ - virtual void setOrigin(const Vector3& origin) { mOrigin = origin; } - /** Gets the origin of this geometry. */ - virtual const Vector3& getOrigin(void) const { return mOrigin; } - - /// Sets the visibility flags of all the regions at once - void setVisibilityFlags(uint32 flags); - /// Returns the visibility flags of the regions - uint32 getVisibilityFlags() const; + /// Flags whether the RenderQueue's default should be used. + bool mRenderQueueIDSet; + /// Stores the visibility flags for the regions + uint32 mVisibilityFlags; + + QueuedSubMeshList mQueuedSubMeshes; + + /// List of geometry which has been optimised for SubMesh use + /// This is the primary storage used for cleaning up later + OptimisedSubMeshGeometryList mOptimisedSubMeshGeometryList; + + /** Cached links from SubMeshes to (potentially optimised) geometry + This is not used for deletion since the lookup may reference + original vertex data + */ + SubMeshGeometryLookup mSubMeshGeometryLookup; + + /// Map of regions + RegionMap mRegionMap; + + /** Virtual method for getting a region most suitable for the + passed in bounds. Can be overridden by subclasses. + */ + virtual Region* getRegion(const AxisAlignedBox& bounds, bool autoCreate); + /** Get the region within which a point lies */ + virtual Region* getRegion(const Vector3& point, bool autoCreate); + /** Get the region using indexes */ + virtual Region* getRegion(ushort x, ushort y, ushort z, bool autoCreate); + /** Get the region using a packed index, returns null if it doesn't exist. */ + virtual Region* getRegion(uint32 index); + /** Get the region indexes for a point. + */ + virtual void getRegionIndexes(const Vector3& point, + ushort& x, ushort& y, ushort& z); + /** Pack 3 indexes into a single index value + */ + virtual uint32 packIndex(ushort x, ushort y, ushort z); + /** Get the volume intersection for an indexed region with some bounds. + */ + virtual Real getVolumeIntersection(const AxisAlignedBox& box, + ushort x, ushort y, ushort z); + /** Get the bounds of an indexed region. + */ + virtual AxisAlignedBox getRegionBounds(ushort x, ushort y, ushort z); + /** Get the centre of an indexed region. + */ + virtual Vector3 getRegionCentre(ushort x, ushort y, ushort z); + /** Calculate world bounds from a set of vertex data. */ + virtual AxisAlignedBox calculateBounds(VertexData* vertexData, + const Vector3& position, const Quaternion& orientation, + const Vector3& scale); + /** Look up or calculate the geometry data to use for this SubMesh */ + SubMeshLodGeometryLinkList* determineGeometry(SubMesh* sm); + /** Split some shared geometry into dedicated geometry. */ + void splitGeometry(VertexData* vd, IndexData* id, + SubMeshLodGeometryLink* targetGeomLink); + + typedef map::type IndexRemap; + /** Method for figuring out which vertices are used by an index buffer + and calculating a remap lookup for a vertex buffer just containing + those vertices. + */ + template + void buildIndexRemap(T* pBuffer, size_t numIndexes, IndexRemap& remap) + { + remap.clear(); + for (size_t i = 0; i < numIndexes; ++i) + { + // use insert since duplicates are silently discarded + remap.insert(IndexRemap::value_type(*pBuffer++, remap.size())); + // this will have mapped oldindex -> new index IF oldindex + // wasn't already there + } + } + /** Method for altering indexes based on a remap. */ + template + void remapIndexes(T* src, T* dst, const IndexRemap& remap, + size_t numIndexes) + { + for (size_t i = 0; i < numIndexes; ++i) + { + // look up original and map to target + IndexRemap::const_iterator ix = remap.find(*src++); + assert(ix != remap.end()); + *dst++ = static_cast(ix->second); + } + } + + public: + /// Constructor; do not use directly (@see SceneManager::createStaticGeometry) + StaticGeometry(SceneManager* owner, const String& name); + /// Destructor + virtual ~StaticGeometry(); + + /// Get the name of this object + const String& getName(void) const { return mName; } + /** Adds an Entity to the static geometry. + @remarks + This method takes an existing Entity and adds its details to the + list of elements to include when building. Note that the Entity + itself is not copied or referenced in this method; an Entity is + passed simply so that you can change the materials of attached + SubEntity objects if you want. You can add the same Entity + instance multiple times with different material settings + completely safely, and destroy the Entity before destroying + this StaticGeometry if you like. The Entity passed in is simply + used as a definition. + @note Must be called before 'build'. + @param ent The Entity to use as a definition (the Mesh and Materials + referenced will be recorded for the build call). + @param position The world position at which to add this Entity + @param orientation The world orientation at which to add this Entity + @param scale The scale at which to add this entity + */ + virtual void addEntity(Entity* ent, const Vector3& position, + const Quaternion& orientation = Quaternion::IDENTITY, + const Vector3& scale = Vector3::UNIT_SCALE); + + /** Adds all the Entity objects attached to a SceneNode and all it's + children to the static geometry. + @remarks + This method performs just like addEntity, except it adds all the + entities attached to an entire sub-tree to the geometry. + The position / orientation / scale parameters are taken from the + node structure instead of being specified manually. + @note + The SceneNode you pass in will not be automatically detached from + it's parent, so if you have this node already attached to the scene + graph, you will need to remove it if you wish to avoid the overhead + of rendering both the original objects and their new static + versions! We don't do this for you incase you are preparing this + in advance and so don't want the originals detached yet. + @note Must be called before 'build'. + @param node Pointer to the node to use to provide a set of Entity + templates + */ + virtual void addSceneNode(const SceneNode* node); + + /** Build the geometry. + @remarks + Based on all the entities which have been added, and the batching + options which have been set, this method constructs the batched + geometry structures required. The batches are added to the scene + and will be rendered unless you specifically hide them. + @note + Once you have called this method, you can no longer add any more + entities. + */ + virtual void build(void); + + /** Destroys all the built geometry state (reverse of build). + @remarks + You can call build() again after this and it will pick up all the + same entities / nodes you queued last time. + */ + virtual void destroy(void); + + /** Clears any of the entities / nodes added to this geometry and + destroys anything which has already been built. + */ + virtual void reset(void); + + /** Sets the distance at which batches are no longer rendered. + @remarks + This lets you turn off batches at a given distance. This can be + useful for things like detail meshes (grass, foliage etc) and could + be combined with a shader which fades the geometry out beforehand + to lessen the effect. + @param dist Distance beyond which the batches will not be rendered + (the default is 0, which means batches are always rendered). + */ + virtual void setRenderingDistance(Real dist) { + mUpperDistance = dist; + mSquaredUpperDistance = mUpperDistance * mUpperDistance; + } + + /** Gets the distance at which batches are no longer rendered. */ + virtual Real getRenderingDistance(void) const { return mUpperDistance; } + + /** Gets the squared distance at which batches are no longer rendered. */ + virtual Real getSquaredRenderingDistance(void) const + { return mSquaredUpperDistance; } + + /** Hides or shows all the batches. */ + virtual void setVisible(bool visible); + + /** Are the batches visible? */ + virtual bool isVisible(void) const { return mVisible; } + + /** Sets whether this geometry should cast shadows. + @remarks + No matter what the settings on the original entities, + the StaticGeometry class defaults to not casting shadows. + This is because, being static, unless you have moving lights + you'd be better to use precalculated shadows of some sort. + However, if you need them, you can enable them using this + method. If the SceneManager is set up to use stencil shadows, + edge lists will be copied from the underlying meshes on build. + It is essential that all meshes support stencil shadows in this + case. + @note If you intend to use stencil shadows, you must set this to + true before calling 'build' as well as making sure you set the + scene's shadow type (that should always be the first thing you do + anyway). You can turn shadows off temporarily but they can never + be turned on if they were not at the time of the build. + */ + virtual void setCastShadows(bool castShadows); + /// Will the geometry from this object cast shadows? + virtual bool getCastShadows(void) { return mCastShadows; } + + /** Sets the size of a single region of geometry. + @remarks + This method allows you to configure the physical world size of + each region, so you can balance culling against batch size. Entities + will be fitted within the batch they most closely fit, and the + eventual bounds of each batch may well be slightly larger than this + if they overlap a little. The default is Vector3(1000, 1000, 1000). + @note Must be called before 'build'. + @param size Vector3 expressing the 3D size of each region. + */ + virtual void setRegionDimensions(const Vector3& size) { + mRegionDimensions = size; + mHalfRegionDimensions = size * 0.5; + } + /** Gets the size of a single batch of geometry. */ + virtual const Vector3& getRegionDimensions(void) const { return mRegionDimensions; } + /** Sets the origin of the geometry. + @remarks + This method allows you to configure the world centre of the geometry, + thus the place which all regions surround. You probably don't need + to mess with this unless you have a seriously large world, since the + default set up can handle an area 1024 * mRegionDimensions, and + the sparseness of population is no issue when it comes to rendering. + The default is Vector3(0,0,0). + @note Must be called before 'build'. + @param origin Vector3 expressing the 3D origin of the geometry. + */ + virtual void setOrigin(const Vector3& origin) { mOrigin = origin; } + /** Gets the origin of this geometry. */ + virtual const Vector3& getOrigin(void) const { return mOrigin; } + + /// Sets the visibility flags of all the regions at once + void setVisibilityFlags(uint32 flags); + /// Returns the visibility flags of the regions + uint32 getVisibilityFlags() const; /** Sets the render queue group this object will be rendered through. @remarks Render queues are grouped to allow you to more tightly control the ordering of rendered objects. If you do not call this method, all objects default to the default queue (RenderQueue::getDefaultQueueGroup), which is fine for - most objects. You may want to alter this if you want to perform more complex - rendering. + most objects. You may want to alter this if you want to perform more complex + rendering. @par See RenderQueue for more details. @param queueID Enumerated value of the queue group to use. @@ -756,24 +756,24 @@ namespace Ogre { /** Gets the queue group for this entity, see setRenderQueueGroup for full details. */ virtual uint8 getRenderQueueGroup(void) const; - /// @copydoc MovableObject::visitRenderables - void visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables = false); - - /// Iterator for iterating over contained regions - typedef MapIterator RegionIterator; - /// Get an iterator over the regions in this geometry - RegionIterator getRegionIterator(void); - - /** Dump the contents of this StaticGeometry to a file for diagnostic - purposes. - */ - virtual void dump(const String& filename) const; - - - }; - /** @} */ - /** @} */ + /// @copydoc MovableObject::visitRenderables + void visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables = false); + + /// Iterator for iterating over contained regions + typedef MapIterator RegionIterator; + /// Get an iterator over the regions in this geometry + RegionIterator getRegionIterator(void); + + /** Dump the contents of this StaticGeometry to a file for diagnostic + purposes. + */ + virtual void dump(const String& filename) const; + + + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreStdHeaders.h b/OgreMain/include/OgreStdHeaders.h index f98a38ea589..8a27280963b 100644 --- a/OgreMain/include/OgreStdHeaders.h +++ b/OgreMain/include/OgreStdHeaders.h @@ -57,14 +57,14 @@ # endif #elif !defined(STLPORT) # if (OGRE_COMPILER == OGRE_COMPILER_MSVC) && _MSC_FULL_VER >= 150030729 // VC++ 9.0 SP1+ -# include -# include +# include +# include # elif OGRE_THREAD_PROVIDER == 1 # include # include # else -# error "Your compiler doesn't support unordered_set and unordered_map. Try to compile Ogre with Boost or STLPort." -# endif +# error "Your compiler doesn't support unordered_set and unordered_map. Try to compile Ogre with Boost or STLPort." +# endif #endif // STL algorithms & functions diff --git a/OgreMain/include/OgreStreamSerialiser.h b/OgreMain/include/OgreStreamSerialiser.h index 6843c6418eb..e182bac9f28 100644 --- a/OgreMain/include/OgreStreamSerialiser.h +++ b/OgreMain/include/OgreStreamSerialiser.h @@ -35,360 +35,360 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - - /** Utility class providing helper methods for reading / writing - structured data held in a DataStream. - @remarks - The structure of a file read / written by this class is a series of - 'chunks'. A chunk-based format has the advantage of being extensible later, - and it's robust, in that a reader can skip chunks that they are not - able (or willing) to process. - @par - Chunks are contained serially in the file, but they can also be - nested in order both to provide context, and to group chunks together for - potential skipping. - @par - The data format of a chunk is as follows: - -# Chunk ID (32-bit uint). This can be any number unique in a context, except the numbers 0x0000, 0x0001 and 0x1000, which are reserved for Ogre's use - -# Chunk version (16-bit uint). Chunks can change over time so this version number reflects that - -# Length (32-bit uint). The length of the chunk data section, including nested chunks. Note that - this length excludes this header, but includes the header of any nested chunks. - -# Checksum (32-bit uint). Checksum value generated from the above - basically lets us check this is a valid chunk. - -# Chunk data - The 'Chunk data' section will contain chunk-specific data, which may include - other nested chunks. - */ - class _OgreExport StreamSerialiser : public StreamAlloc - { - public: - /// The endianness of files - enum Endian - { - /// Automatically determine endianness - ENDIAN_AUTO, - /// Use big endian (0x1000 is serialised as 0x10 0x00) - ENDIAN_BIG, - /// Use little endian (0x1000 is serialised as 0x00 0x10) - ENDIAN_LITTLE - }; - - /// The storage format of Real values - enum RealStorageFormat - { - /// Real is stored as float, reducing precision if you're using OGRE_DOUBLE_PRECISION - REAL_FLOAT, - /// Real as stored as double, not useful unless you're using OGRE_DOUBLE_PRECISION - REAL_DOUBLE - }; - - - /// Definition of a chunk of data in a file - struct Chunk : public StreamAlloc - { - /// Identifier of the chunk (for example from makeIdentifier) (stored) - uint32 id; - /// Version of the chunk (stored) - uint16 version; - /// Length of the chunk data in bytes, excluding the header of this chunk (stored) - uint32 length; - /// Location of the chunk (header) in bytes from the start of a stream (derived) - uint32 offset; - - Chunk() : id(0), version(1), length(0), offset(0) {} - }; - - /** Constructor. - @param stream The stream on which you will read / write data. - @param endianMode The endian mode in which to read / writedata. If left at - the default, when writing the endian mode will be the native platform mode, - and when reading it's expected that the first chunk encountered will be - the header chunk, which will determine the endian mode. - @param autoHeader If true, the first write or read to this stream will - automatically read / write the header too. This is required if you - set endianMode to ENDIAN_AUTO, but if you manually set the endian mode, - then you can skip writing / reading the header if you wish, if for example - this stream is midway through a file which has already included header - information. - @param realFormat Set the format you want to write reals in. Only useful for files that - you're writing (since when reading this is picked up from the file), - and can only be changed if autoHeader is true, since real format is stored in the header. - Defaults to float unless you're using OGRE_DOUBLE_PRECISION. - */ - StreamSerialiser(const DataStreamPtr& stream, Endian endianMode = ENDIAN_AUTO, - bool autoHeader = true, + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + + /** Utility class providing helper methods for reading / writing + structured data held in a DataStream. + @remarks + The structure of a file read / written by this class is a series of + 'chunks'. A chunk-based format has the advantage of being extensible later, + and it's robust, in that a reader can skip chunks that they are not + able (or willing) to process. + @par + Chunks are contained serially in the file, but they can also be + nested in order both to provide context, and to group chunks together for + potential skipping. + @par + The data format of a chunk is as follows: + -# Chunk ID (32-bit uint). This can be any number unique in a context, except the numbers 0x0000, 0x0001 and 0x1000, which are reserved for Ogre's use + -# Chunk version (16-bit uint). Chunks can change over time so this version number reflects that + -# Length (32-bit uint). The length of the chunk data section, including nested chunks. Note that + this length excludes this header, but includes the header of any nested chunks. + -# Checksum (32-bit uint). Checksum value generated from the above - basically lets us check this is a valid chunk. + -# Chunk data + The 'Chunk data' section will contain chunk-specific data, which may include + other nested chunks. + */ + class _OgreExport StreamSerialiser : public StreamAlloc + { + public: + /// The endianness of files + enum Endian + { + /// Automatically determine endianness + ENDIAN_AUTO, + /// Use big endian (0x1000 is serialised as 0x10 0x00) + ENDIAN_BIG, + /// Use little endian (0x1000 is serialised as 0x00 0x10) + ENDIAN_LITTLE + }; + + /// The storage format of Real values + enum RealStorageFormat + { + /// Real is stored as float, reducing precision if you're using OGRE_DOUBLE_PRECISION + REAL_FLOAT, + /// Real as stored as double, not useful unless you're using OGRE_DOUBLE_PRECISION + REAL_DOUBLE + }; + + + /// Definition of a chunk of data in a file + struct Chunk : public StreamAlloc + { + /// Identifier of the chunk (for example from makeIdentifier) (stored) + uint32 id; + /// Version of the chunk (stored) + uint16 version; + /// Length of the chunk data in bytes, excluding the header of this chunk (stored) + uint32 length; + /// Location of the chunk (header) in bytes from the start of a stream (derived) + uint32 offset; + + Chunk() : id(0), version(1), length(0), offset(0) {} + }; + + /** Constructor. + @param stream The stream on which you will read / write data. + @param endianMode The endian mode in which to read / writedata. If left at + the default, when writing the endian mode will be the native platform mode, + and when reading it's expected that the first chunk encountered will be + the header chunk, which will determine the endian mode. + @param autoHeader If true, the first write or read to this stream will + automatically read / write the header too. This is required if you + set endianMode to ENDIAN_AUTO, but if you manually set the endian mode, + then you can skip writing / reading the header if you wish, if for example + this stream is midway through a file which has already included header + information. + @param realFormat Set the format you want to write reals in. Only useful for files that + you're writing (since when reading this is picked up from the file), + and can only be changed if autoHeader is true, since real format is stored in the header. + Defaults to float unless you're using OGRE_DOUBLE_PRECISION. + */ + StreamSerialiser(const DataStreamPtr& stream, Endian endianMode = ENDIAN_AUTO, + bool autoHeader = true, #if OGRE_DOUBLE_PRECISION - RealStorageFormat realFormat = REAL_DOUBLE + RealStorageFormat realFormat = REAL_DOUBLE #else - RealStorageFormat realFormat = REAL_FLOAT + RealStorageFormat realFormat = REAL_FLOAT #endif - ); - virtual ~StreamSerialiser(); - - /** Get the endian mode. - @remarks - If the result is ENDIAN_AUTO, this mode will change when the first piece of - data is read / written. - */ - virtual Endian getEndian() const { return mEndian; } - - /** Pack a 4-character code into a 32-bit identifier. - @remarks - You can use this to generate id's for your chunks based on friendlier - 4-character codes rather than assigning numerical IDs, if you like. - @param code String to pack - must be 4 characters. - */ - static uint32 makeIdentifier(const String& code); - - /** Report the current depth of the chunk nesting, whether reading or writing. - @remarks - Returns how many levels of nested chunks are currently being processed, - either writing or reading. In order to tidily finish, you must call - read/writeChunkEnd this many times. - */ - size_t getCurrentChunkDepth() const { return mChunkStack.size(); } - - /** Get the ID of the chunk that's currently being read/written, if any. - @return The id of the current chunk being read / written (at the tightest - level of nesting), or zero if no chunk is being processed. - */ - uint32 getCurrentChunkID() const; - - /** Get the current byte position relative to the start of the data section - of the last chunk that was read or written. - @return the offset. Note that a return value of 0 means that either the - position is at the start of the chunk data section (ie right after the - header), or that no chunk is currently active. Use getCurrentChunkID - or getCurrentChunkDepth to determine if a chunk is active. - */ - size_t getOffsetFromChunkStart() const; - - /** Reads the start of the next chunk in the file. - @remarks - Files are serialised in a chunk-based manner, meaning that each section - of data is prepended by a chunk header. After reading this chunk header, - the next set of data is available directly afterwards. - @note - When you have finished with this chunk, you should call readChunkEnd. - This will perform a bit of validation and clear the chunk from - the stack. - @return The Chunk that comes next - */ - virtual const Chunk* readChunkBegin(); - - /** Reads the start of the next chunk so long as it's of a given ID and version. - @remarks - This method operates like readChunkBegin, except it checks the ID and - version. - @param id The ID you're expecting. If the next chunk isn't of this ID, then - the chunk read is undone and the method returns null. - @param maxVersion The maximum version you're able to process. If the ID is correct - but the version exceeds what is passed in here, the chunk is skipped over, - the problem logged and null is returned. - @param msg Descriptive text added to the log if versions are not compatible - @return The chunk if it passes the validation. - */ - virtual const Chunk* readChunkBegin(uint32 id, uint16 maxVersion, const String& msg = BLANKSTRING); - - /** Call this to 'rewind' the stream to just before the start of the current - chunk. - @remarks - The most common case of wanting to use this is if you'd calledReadChunkBegin(), - but the chunk you read wasn't one you wanted to process, and rather than - skipping over it (which readChunkEnd() would do), you want to backtrack - and give something else an opportunity to read it. - @param id The id of the chunk that you were reading (for validation purposes) - */ - virtual void undoReadChunk(uint32 id); - - /** Call this to 'peek' at the next chunk ID without permanently moving the stream pointer. */ - virtual uint32 peekNextChunkID(); - - /** Finish the reading of a chunk. - @remarks - You can call this method at any point after calling readChunkBegin, even - if you didn't read all the rest of the data in the chunk. If you did - not read to the end of a chunk, this method will automatically skip - over the remainder of the chunk and position the stream just after it. - @param id The id of the chunk that you were reading (for validation purposes) - */ - virtual void readChunkEnd(uint32 id); - - /** Return whether the current data pointer is at the end of the current chunk. - @param id The id of the chunk that you were reading (for validation purposes) - */ - virtual bool isEndOfChunk(uint32 id); - - /// Reports whether the stream is at the end of file - virtual bool eof() const; - - /** Get the definition of the current chunk being read (if any). */ - virtual const Chunk* getCurrentChunk() const; - - /** Begin writing a new chunk. - @remarks - This starts the process of writing a new chunk to the stream. This will - write the chunk header for you, and store a pointer so that the - class can automatically go back and fill in the size for you later - should you need it to. If you have already begun a chunk without ending - it, then this method will start a nested chunk within it. Once written, - you can then start writing chunk-specific data into your stream. - @note If this is the first chunk in the file - @param id The identifier of the new chunk. Any value that's unique in the - file context is valid, except for the numbers 0x0001 and 0x1000 which are reserved - for internal header identification use. - @param version The version of the chunk you're writing - */ - virtual void writeChunkBegin(uint32 id, uint16 version = 1); - /** End writing a chunk. - @param id The identifier of the chunk - this is really just a safety check, - since you can only end the chunk you most recently started. - */ - virtual void writeChunkEnd(uint32 id); - - /** Write arbitrary data to a stream. - @param buf Pointer to bytes - @param size The size of each element to write; each will be endian-flipped if - necessary - @param count The number of elements to write - */ - virtual void writeData(const void* buf, size_t size, size_t count); - - /** Catch-all method to write primitive types. */ - template - void write(const T* pT, size_t count = 1) - { - writeData(pT, sizeof(T), count); - } - - // Special-case Real since we need to deal with single/double precision - virtual void write(const Real* val, size_t count = 1); - - virtual void write(const Vector2* vec, size_t count = 1); - virtual void write(const Vector3* vec, size_t count = 1); - virtual void write(const Vector4* vec, size_t count = 1); - virtual void write(const Quaternion* q, size_t count = 1); - virtual void write(const Matrix3* m, size_t count = 1); - virtual void write(const Matrix4* m, size_t count = 1); - virtual void write(const String* string); - virtual void write(const AxisAlignedBox* aabb, size_t count = 1); - virtual void write(const Sphere* sphere, size_t count = 1); - virtual void write(const Plane* plane, size_t count = 1); - virtual void write(const Ray* ray, size_t count = 1); - virtual void write(const Radian* angle, size_t count = 1); - virtual void write(const Node* node, size_t count = 1); - virtual void write(const bool* boolean, size_t count = 1); - - - /** Read arbitrary data from a stream. - @param buf Pointer to bytes - @param size The size of each element to read; each will be endian-flipped if - necessary - @param count The number of elements to read - */ - virtual void readData(void* buf, size_t size, size_t count); - - /** Catch-all method to read primitive types. */ - template - void read(T* pT, size_t count = 1) - { - readData(pT, sizeof(T), count); - } - - // Special case Real, single/double-precision issues - virtual void read(Real* val, size_t count = 1); - - /// read a Vector3 - virtual void read(Vector2* vec, size_t count = 1); - virtual void read(Vector3* vec, size_t count = 1); - virtual void read(Vector4* vec, size_t count = 1); - virtual void read(Quaternion* q, size_t count = 1); - virtual void read(Matrix3* m, size_t count = 1); - virtual void read(Matrix4* m, size_t count = 1); - virtual void read(String* string); - virtual void read(AxisAlignedBox* aabb, size_t count = 1); - virtual void read(Sphere* sphere, size_t count = 1); - virtual void read(Plane* plane, size_t count = 1); - virtual void read(Ray* ray, size_t count = 1); - virtual void read(Radian* angle, size_t count = 1); - virtual void read(Node* node, size_t count = 1); - virtual void read(bool* val, size_t count = 1); - - /** Start (un)compressing data - @param avail_in Available bytes for uncompressing - */ - virtual void startDeflate(size_t avail_in = 0); - /** Stop (un)compressing data - */ - virtual void stopDeflate(); - protected: - DataStreamPtr mStream; - DataStreamPtr mOriginalStream; - Endian mEndian; - bool mFlipEndian; - bool mReadWriteHeader; - RealStorageFormat mRealFormat; - typedef deque::type ChunkStack; - /// Current list of open chunks - ChunkStack mChunkStack; - - static uint32 HEADER_ID; - static uint32 REVERSE_HEADER_ID; - static uint32 CHUNK_HEADER_SIZE; - - virtual Chunk* readChunkImpl(); - virtual void writeChunkImpl(uint32 id, uint16 version); - virtual void readHeader(); - virtual void writeHeader(); - virtual uint32 calculateChecksum(Chunk* c); - virtual void checkStream(bool failOnEof = false, - bool validateReadable = false, bool validateWriteable = false) const; - - virtual void flipEndian(void * pData, size_t size, size_t count); - virtual void flipEndian(void * pData, size_t size); - virtual void determineEndianness(); - virtual Chunk* popChunk(uint id); - - virtual void writeFloatsAsDoubles(const float* val, size_t count); - virtual void writeDoublesAsFloats(const double* val, size_t count); - virtual void readFloatsAsDoubles(double* val, size_t count); - virtual void readDoublesAsFloats(float* val, size_t count); - template - void writeConverted(const T* src, U typeToWrite, size_t count) - { - U* tmp = OGRE_ALLOC_T(U, count, MEMCATEGORY_GENERAL); - U* pDst = tmp; - const T* pSrc = src; - for (size_t i = 0; i < count; ++i) - *pDst++ = static_cast(*pSrc++); - - writeData(tmp, sizeof(U), count); - - OGRE_FREE(tmp, MEMCATEGORY_GENERAL); - } - template - void readConverted(T* dst, U typeToRead, size_t count) - { - U* tmp = OGRE_ALLOC_T(U, count, MEMCATEGORY_GENERAL); - readData(tmp, sizeof(U), count); - - T* pDst = dst; - const U* pSrc = tmp; - for (size_t i = 0; i < count; ++i) - *pDst++ = static_cast(*pSrc++); - - - OGRE_FREE(tmp, MEMCATEGORY_GENERAL); - } - - }; - /** @} */ - /** @} */ + ); + virtual ~StreamSerialiser(); + + /** Get the endian mode. + @remarks + If the result is ENDIAN_AUTO, this mode will change when the first piece of + data is read / written. + */ + virtual Endian getEndian() const { return mEndian; } + + /** Pack a 4-character code into a 32-bit identifier. + @remarks + You can use this to generate id's for your chunks based on friendlier + 4-character codes rather than assigning numerical IDs, if you like. + @param code String to pack - must be 4 characters. + */ + static uint32 makeIdentifier(const String& code); + + /** Report the current depth of the chunk nesting, whether reading or writing. + @remarks + Returns how many levels of nested chunks are currently being processed, + either writing or reading. In order to tidily finish, you must call + read/writeChunkEnd this many times. + */ + size_t getCurrentChunkDepth() const { return mChunkStack.size(); } + + /** Get the ID of the chunk that's currently being read/written, if any. + @return The id of the current chunk being read / written (at the tightest + level of nesting), or zero if no chunk is being processed. + */ + uint32 getCurrentChunkID() const; + + /** Get the current byte position relative to the start of the data section + of the last chunk that was read or written. + @return the offset. Note that a return value of 0 means that either the + position is at the start of the chunk data section (ie right after the + header), or that no chunk is currently active. Use getCurrentChunkID + or getCurrentChunkDepth to determine if a chunk is active. + */ + size_t getOffsetFromChunkStart() const; + + /** Reads the start of the next chunk in the file. + @remarks + Files are serialised in a chunk-based manner, meaning that each section + of data is prepended by a chunk header. After reading this chunk header, + the next set of data is available directly afterwards. + @note + When you have finished with this chunk, you should call readChunkEnd. + This will perform a bit of validation and clear the chunk from + the stack. + @return The Chunk that comes next + */ + virtual const Chunk* readChunkBegin(); + + /** Reads the start of the next chunk so long as it's of a given ID and version. + @remarks + This method operates like readChunkBegin, except it checks the ID and + version. + @param id The ID you're expecting. If the next chunk isn't of this ID, then + the chunk read is undone and the method returns null. + @param maxVersion The maximum version you're able to process. If the ID is correct + but the version exceeds what is passed in here, the chunk is skipped over, + the problem logged and null is returned. + @param msg Descriptive text added to the log if versions are not compatible + @return The chunk if it passes the validation. + */ + virtual const Chunk* readChunkBegin(uint32 id, uint16 maxVersion, const String& msg = BLANKSTRING); + + /** Call this to 'rewind' the stream to just before the start of the current + chunk. + @remarks + The most common case of wanting to use this is if you'd calledReadChunkBegin(), + but the chunk you read wasn't one you wanted to process, and rather than + skipping over it (which readChunkEnd() would do), you want to backtrack + and give something else an opportunity to read it. + @param id The id of the chunk that you were reading (for validation purposes) + */ + virtual void undoReadChunk(uint32 id); + + /** Call this to 'peek' at the next chunk ID without permanently moving the stream pointer. */ + virtual uint32 peekNextChunkID(); + + /** Finish the reading of a chunk. + @remarks + You can call this method at any point after calling readChunkBegin, even + if you didn't read all the rest of the data in the chunk. If you did + not read to the end of a chunk, this method will automatically skip + over the remainder of the chunk and position the stream just after it. + @param id The id of the chunk that you were reading (for validation purposes) + */ + virtual void readChunkEnd(uint32 id); + + /** Return whether the current data pointer is at the end of the current chunk. + @param id The id of the chunk that you were reading (for validation purposes) + */ + virtual bool isEndOfChunk(uint32 id); + + /// Reports whether the stream is at the end of file + virtual bool eof() const; + + /** Get the definition of the current chunk being read (if any). */ + virtual const Chunk* getCurrentChunk() const; + + /** Begin writing a new chunk. + @remarks + This starts the process of writing a new chunk to the stream. This will + write the chunk header for you, and store a pointer so that the + class can automatically go back and fill in the size for you later + should you need it to. If you have already begun a chunk without ending + it, then this method will start a nested chunk within it. Once written, + you can then start writing chunk-specific data into your stream. + @note If this is the first chunk in the file + @param id The identifier of the new chunk. Any value that's unique in the + file context is valid, except for the numbers 0x0001 and 0x1000 which are reserved + for internal header identification use. + @param version The version of the chunk you're writing + */ + virtual void writeChunkBegin(uint32 id, uint16 version = 1); + /** End writing a chunk. + @param id The identifier of the chunk - this is really just a safety check, + since you can only end the chunk you most recently started. + */ + virtual void writeChunkEnd(uint32 id); + + /** Write arbitrary data to a stream. + @param buf Pointer to bytes + @param size The size of each element to write; each will be endian-flipped if + necessary + @param count The number of elements to write + */ + virtual void writeData(const void* buf, size_t size, size_t count); + + /** Catch-all method to write primitive types. */ + template + void write(const T* pT, size_t count = 1) + { + writeData(pT, sizeof(T), count); + } + + // Special-case Real since we need to deal with single/double precision + virtual void write(const Real* val, size_t count = 1); + + virtual void write(const Vector2* vec, size_t count = 1); + virtual void write(const Vector3* vec, size_t count = 1); + virtual void write(const Vector4* vec, size_t count = 1); + virtual void write(const Quaternion* q, size_t count = 1); + virtual void write(const Matrix3* m, size_t count = 1); + virtual void write(const Matrix4* m, size_t count = 1); + virtual void write(const String* string); + virtual void write(const AxisAlignedBox* aabb, size_t count = 1); + virtual void write(const Sphere* sphere, size_t count = 1); + virtual void write(const Plane* plane, size_t count = 1); + virtual void write(const Ray* ray, size_t count = 1); + virtual void write(const Radian* angle, size_t count = 1); + virtual void write(const Node* node, size_t count = 1); + virtual void write(const bool* boolean, size_t count = 1); + + + /** Read arbitrary data from a stream. + @param buf Pointer to bytes + @param size The size of each element to read; each will be endian-flipped if + necessary + @param count The number of elements to read + */ + virtual void readData(void* buf, size_t size, size_t count); + + /** Catch-all method to read primitive types. */ + template + void read(T* pT, size_t count = 1) + { + readData(pT, sizeof(T), count); + } + + // Special case Real, single/double-precision issues + virtual void read(Real* val, size_t count = 1); + + /// read a Vector3 + virtual void read(Vector2* vec, size_t count = 1); + virtual void read(Vector3* vec, size_t count = 1); + virtual void read(Vector4* vec, size_t count = 1); + virtual void read(Quaternion* q, size_t count = 1); + virtual void read(Matrix3* m, size_t count = 1); + virtual void read(Matrix4* m, size_t count = 1); + virtual void read(String* string); + virtual void read(AxisAlignedBox* aabb, size_t count = 1); + virtual void read(Sphere* sphere, size_t count = 1); + virtual void read(Plane* plane, size_t count = 1); + virtual void read(Ray* ray, size_t count = 1); + virtual void read(Radian* angle, size_t count = 1); + virtual void read(Node* node, size_t count = 1); + virtual void read(bool* val, size_t count = 1); + + /** Start (un)compressing data + @param avail_in Available bytes for uncompressing + */ + virtual void startDeflate(size_t avail_in = 0); + /** Stop (un)compressing data + */ + virtual void stopDeflate(); + protected: + DataStreamPtr mStream; + DataStreamPtr mOriginalStream; + Endian mEndian; + bool mFlipEndian; + bool mReadWriteHeader; + RealStorageFormat mRealFormat; + typedef deque::type ChunkStack; + /// Current list of open chunks + ChunkStack mChunkStack; + + static uint32 HEADER_ID; + static uint32 REVERSE_HEADER_ID; + static uint32 CHUNK_HEADER_SIZE; + + virtual Chunk* readChunkImpl(); + virtual void writeChunkImpl(uint32 id, uint16 version); + virtual void readHeader(); + virtual void writeHeader(); + virtual uint32 calculateChecksum(Chunk* c); + virtual void checkStream(bool failOnEof = false, + bool validateReadable = false, bool validateWriteable = false) const; + + virtual void flipEndian(void * pData, size_t size, size_t count); + virtual void flipEndian(void * pData, size_t size); + virtual void determineEndianness(); + virtual Chunk* popChunk(uint id); + + virtual void writeFloatsAsDoubles(const float* val, size_t count); + virtual void writeDoublesAsFloats(const double* val, size_t count); + virtual void readFloatsAsDoubles(double* val, size_t count); + virtual void readDoublesAsFloats(float* val, size_t count); + template + void writeConverted(const T* src, U typeToWrite, size_t count) + { + U* tmp = OGRE_ALLOC_T(U, count, MEMCATEGORY_GENERAL); + U* pDst = tmp; + const T* pSrc = src; + for (size_t i = 0; i < count; ++i) + *pDst++ = static_cast(*pSrc++); + + writeData(tmp, sizeof(U), count); + + OGRE_FREE(tmp, MEMCATEGORY_GENERAL); + } + template + void readConverted(T* dst, U typeToRead, size_t count) + { + U* tmp = OGRE_ALLOC_T(U, count, MEMCATEGORY_GENERAL); + readData(tmp, sizeof(U), count); + + T* pDst = dst; + const U* pSrc = tmp; + for (size_t i = 0; i < count; ++i) + *pDst++ = static_cast(*pSrc++); + + + OGRE_FREE(tmp, MEMCATEGORY_GENERAL); + } + + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreStringInterface.h b/OgreMain/include/OgreStringInterface.h index a7cc180d8b6..5454bfc4607 100644 --- a/OgreMain/include/OgreStringInterface.h +++ b/OgreMain/include/OgreStringInterface.h @@ -36,12 +36,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ /// List of parameter types available enum ParameterType @@ -110,7 +110,7 @@ namespace Ogre { } } - const ParamCommand* getParamCommand(const String& name) const + const ParamCommand* getParamCommand(const String& name) const { ParamCommandMap::const_iterator i = mParamCommands.find(name); if (i != mParamCommands.end()) @@ -169,9 +169,9 @@ namespace Ogre { /// Class name for this instance to be used as a lookup (must be initialised by subclasses) String mParamDictName; - ParamDictionary* mParamDict; + ParamDictionary* mParamDict; - protected: + protected: /** Internal method for creating a parameter dictionary for the class, if it does not already exist. @remarks This method will check to see if a parameter dictionary exist for this class yet, @@ -186,24 +186,24 @@ namespace Ogre { { OGRE_LOCK_MUTEX( msDictionaryMutex ); - ParamDictionaryMap::iterator it = msDictionary.find(className); - - if ( it == msDictionary.end() ) - { - mParamDict = &msDictionary.insert( std::make_pair( className, ParamDictionary() ) ).first->second; - mParamDictName = className; - return true; - } - else - { - mParamDict = &it->second; - mParamDictName = className; - return false; - } + ParamDictionaryMap::iterator it = msDictionary.find(className); + + if ( it == msDictionary.end() ) + { + mParamDict = &msDictionary.insert( std::make_pair( className, ParamDictionary() ) ).first->second; + mParamDictName = className; + return true; + } + else + { + mParamDict = &it->second; + mParamDictName = className; + return false; + } } public: - StringInterface() : mParamDict(NULL) { } + StringInterface() : mParamDict(NULL) { } /** Virtual destructor, see Effective C++ */ virtual ~StringInterface() {} @@ -217,12 +217,12 @@ namespace Ogre { */ ParamDictionary* getParamDictionary(void) { - return mParamDict; + return mParamDict; } - const ParamDictionary* getParamDictionary(void) const + const ParamDictionary* getParamDictionary(void) const { - return mParamDict; + return mParamDict; } /** Retrieves a list of parameters valid for this object. @@ -326,8 +326,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreStringVector.h b/OgreMain/include/OgreStringVector.h index 6a60e31e1c5..0d5dc64f6a1 100644 --- a/OgreMain/include/OgreStringVector.h +++ b/OgreMain/include/OgreStringVector.h @@ -35,18 +35,18 @@ THE SOFTWARE. namespace Ogre { typedef _StringBase String; - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ typedef vector::type StringVector; typedef SharedPtr StringVectorPtr; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreSubEntity.h b/OgreMain/include/OgreSubEntity.h index ff4f07e63fb..6d98fb51740 100644 --- a/OgreMain/include/OgreSubEntity.h +++ b/OgreMain/include/OgreSubEntity.h @@ -37,13 +37,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Utility class which defines the sub-parts of an Entity. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Utility class which defines the sub-parts of an Entity. @remarks Just as meshes are split into submeshes, an Entity is made up of potentially multiple SubMeshes. These are mainly here to provide the @@ -82,7 +82,7 @@ namespace Ogre { /// Pointer to the SubMesh defining geometry. SubMesh* mSubMesh; - /// override the start index for the RenderOperation + /// override the start index for the RenderOperation size_t mIndexStart; /// override the end index for the RenderOperation @@ -100,31 +100,31 @@ namespace Ogre { /// Flags whether the RenderQueue's default should be used. bool mRenderQueuePrioritySet; #if !OGRE_NO_MESHLOD - /// The LOD number of the material to use, calculated by Entity::_notifyCurrentCamera - unsigned short mMaterialLodIndex; + /// The LOD number of the material to use, calculated by Entity::_notifyCurrentCamera + unsigned short mMaterialLodIndex; #else - const unsigned short mMaterialLodIndex; // = 0 + const unsigned short mMaterialLodIndex; // = 0 #endif /// Blend buffer details for dedicated geometry VertexData* mSkelAnimVertexData; /// Quick lookup of buffers TempBlendedBufferInfo mTempSkelAnimInfo; - /// Temp buffer details for software Vertex anim geometry - TempBlendedBufferInfo mTempVertexAnimInfo; - /// Vertex data details for software Vertex anim of shared geometry - VertexData* mSoftwareVertexAnimVertexData; - /// Vertex data details for hardware Vertex anim of shared geometry - /// - separate since we need to s/w anim for shadows whilst still altering - /// the vertex data for hardware morphing (pos2 binding) - VertexData* mHardwareVertexAnimVertexData; - /// Have we applied any vertex animation to geometry? - bool mVertexAnimationAppliedThisFrame; - /// Number of hardware blended poses supported by material - ushort mHardwarePoseCount; - /// Cached distance to last camera for getSquaredViewDepth - mutable Real mCachedCameraDist; - /// The camera for which the cached distance is valid - mutable const Camera *mCachedCamera; + /// Temp buffer details for software Vertex anim geometry + TempBlendedBufferInfo mTempVertexAnimInfo; + /// Vertex data details for software Vertex anim of shared geometry + VertexData* mSoftwareVertexAnimVertexData; + /// Vertex data details for hardware Vertex anim of shared geometry + /// - separate since we need to s/w anim for shadows whilst still altering + /// the vertex data for hardware morphing (pos2 binding) + VertexData* mHardwareVertexAnimVertexData; + /// Have we applied any vertex animation to geometry? + bool mVertexAnimationAppliedThisFrame; + /// Number of hardware blended poses supported by material + ushort mHardwarePoseCount; + /// Cached distance to last camera for getSquaredViewDepth + mutable Real mCachedCameraDist; + /// The camera for which the cached distance is valid + mutable const Camera *mCachedCamera; /** Internal method for preparing this Entity for use in animation. */ void prepareTempBlendBuffers(void); @@ -142,13 +142,13 @@ namespace Ogre { */ void setMaterialName( const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME ); - /** Sets a Material to be used. - @remarks - By default a SubEntity uses the default Material that the SubMesh - uses. This call can alter that so that the Material is different - for this instance. - */ - void setMaterial( const MaterialPtr& material ); + /** Sets a Material to be used. + @remarks + By default a SubEntity uses the default Material that the SubMesh + uses. This call can alter that so that the Material is different + for this instance. + */ + void setMaterial( const MaterialPtr& material ); /** Tells this SubEntity whether to be visible or not. */ virtual void setVisible(bool visible); @@ -200,8 +200,8 @@ namespace Ogre { */ SubMesh* getSubMesh(void); - /** Accessor to get parent Entity */ - Entity* getParent(void) const { return mParentEntity; } + /** Accessor to get parent Entity */ + Entity* getParent(void) const { return mParentEntity; } /** Overridden - see Renderable. */ @@ -215,7 +215,7 @@ namespace Ogre { */ void getRenderOperation(RenderOperation& op); - /** Tells this SubEntity to draw a subset of the SubMesh by adjusting the index buffer extents. + /** Tells this SubEntity to draw a subset of the SubMesh by adjusting the index buffer extents. * Default value is zero so that the entire index buffer is used when drawing. * Valid values are zero to getIndexDataEndIndex() */ @@ -233,11 +233,11 @@ namespace Ogre { void setIndexDataEndIndex(size_t end_index); /** Returns the current value of the start index used for drawing. - */ + */ size_t getIndexDataEndIndex() const; - /** Reset the custom start/end index to the default values. - */ + /** Reset the custom start/end index to the default values. + */ void resetIndexDataStartEndIndex(); /** Overridden - see Renderable. @@ -252,65 +252,65 @@ namespace Ogre { const LightList& getLights(void) const; /** @copydoc Renderable::getCastsShadows */ bool getCastsShadows(void) const; - /** Advanced method to get the temporarily blended vertex information - for entities which are software skinned. + /** Advanced method to get the temporarily blended vertex information + for entities which are software skinned. @remarks Internal engine will eliminate software animation if possible, this information is unreliable unless added request for software animation via Entity::addSoftwareAnimationRequest. @note The positions/normals of the returned vertex data is in object space. - */ - VertexData* _getSkelAnimVertexData(void); - /** Advanced method to get the temporarily blended software morph vertex information + */ + VertexData* _getSkelAnimVertexData(void); + /** Advanced method to get the temporarily blended software morph vertex information @remarks Internal engine will eliminate software animation if possible, this information is unreliable unless added request for software animation via Entity::addSoftwareAnimationRequest. @note The positions/normals of the returned vertex data is in object space. - */ - VertexData* _getSoftwareVertexAnimVertexData(void); - /** Advanced method to get the hardware morph vertex information + */ + VertexData* _getSoftwareVertexAnimVertexData(void); + /** Advanced method to get the hardware morph vertex information @note The positions/normals of the returned vertex data is in object space. - */ - VertexData* _getHardwareVertexAnimVertexData(void); - /** Advanced method to get the temp buffer information for software - skeletal animation. - */ - TempBlendedBufferInfo* _getSkelAnimTempBufferInfo(void); - /** Advanced method to get the temp buffer information for software - morph animation. - */ - TempBlendedBufferInfo* _getVertexAnimTempBufferInfo(void); - /// Retrieve the VertexData which should be used for GPU binding - VertexData* getVertexDataForBinding(void); - - /** Mark all vertex data as so far unanimated. - */ - void _markBuffersUnusedForAnimation(void); - /** Mark all vertex data as animated. - */ - void _markBuffersUsedForAnimation(void); - /** Are buffers already marked as vertex animated? */ - bool _getBuffersMarkedForAnimation(void) const { return mVertexAnimationAppliedThisFrame; } - /** Internal method to copy original vertex data to the morph structures - should there be no active animation in use. - */ - void _restoreBuffersForUnusedAnimation(bool hardwareAnimation); - - /** Overridden from Renderable to provide some custom behaviour. */ - void _updateCustomGpuParameter( - const GpuProgramParameters::AutoConstantEntry& constantEntry, - GpuProgramParameters* params) const; - - /** Invalidate the camera distance cache */ - void _invalidateCameraCache () - { mCachedCamera = 0; } + */ + VertexData* _getHardwareVertexAnimVertexData(void); + /** Advanced method to get the temp buffer information for software + skeletal animation. + */ + TempBlendedBufferInfo* _getSkelAnimTempBufferInfo(void); + /** Advanced method to get the temp buffer information for software + morph animation. + */ + TempBlendedBufferInfo* _getVertexAnimTempBufferInfo(void); + /// Retrieve the VertexData which should be used for GPU binding + VertexData* getVertexDataForBinding(void); + + /** Mark all vertex data as so far unanimated. + */ + void _markBuffersUnusedForAnimation(void); + /** Mark all vertex data as animated. + */ + void _markBuffersUsedForAnimation(void); + /** Are buffers already marked as vertex animated? */ + bool _getBuffersMarkedForAnimation(void) const { return mVertexAnimationAppliedThisFrame; } + /** Internal method to copy original vertex data to the morph structures + should there be no active animation in use. + */ + void _restoreBuffersForUnusedAnimation(bool hardwareAnimation); + + /** Overridden from Renderable to provide some custom behaviour. */ + void _updateCustomGpuParameter( + const GpuProgramParameters::AutoConstantEntry& constantEntry, + GpuProgramParameters* params) const; + + /** Invalidate the camera distance cache */ + void _invalidateCameraCache () + { mCachedCamera = 0; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreSubMesh.h b/OgreMain/include/OgreSubMesh.h index d94a771b59f..a993d52116d 100644 --- a/OgreMain/include/OgreSubMesh.h +++ b/OgreMain/include/OgreSubMesh.h @@ -38,13 +38,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Defines a part of a complete mesh. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Defines a part of a complete mesh. @remarks Meshes which make up the definition of a discrete 3D object are made up of potentially multiple parts. This is because @@ -57,7 +57,7 @@ namespace Ogre { their material differences on a per-object basis if required. See the SubEntity class for more information. */ - class _OgreExport SubMesh : public SubMeshAlloc + class _OgreExport SubMesh : public SubMeshAlloc { friend class Mesh; friend class MeshSerializerImpl; @@ -108,8 +108,8 @@ namespace Ogre { typedef vector::type IndexMap; IndexMap blendIndexToBoneIndexMap; - typedef vector::type LODFaceList; - LODFaceList mLodFaceList; + typedef vector::type LODFaceList; + LODFaceList mLodFaceList; /** A list of extreme points on the submesh (optional). @remarks @@ -182,9 +182,9 @@ namespace Ogre { */ BoneAssignmentIterator getBoneAssignmentIterator(void); - /** Gets a const reference to the list of bone assignments - */ - const VertexBoneAssignmentList& getBoneAssignments() { return mBoneAssignments; } + /** Gets a const reference to the list of bone assignments + */ + const VertexBoneAssignmentList& getBoneAssignments() { return mBoneAssignments; } /** Must be called once to compile bone assignments into geometry buffer. */ @@ -234,12 +234,12 @@ namespace Ogre { */ bool updateMaterialUsingTextureAliases(void); - /** Get the type of any vertex animation used by dedicated geometry. - */ - VertexAnimationType getVertexAnimationType(void) const; - - /// Returns whether animation on dedicated vertex data includes normals - bool getVertexAnimationIncludesNormals() const { return mVertexAnimationIncludesNormals; } + /** Get the type of any vertex animation used by dedicated geometry. + */ + VertexAnimationType getVertexAnimationType(void) const; + + /// Returns whether animation on dedicated vertex data includes normals + bool getVertexAnimationIncludesNormals() const { return mVertexAnimationIncludesNormals; } /** Generate the submesh extremes (@see extremityPoints). @@ -248,10 +248,10 @@ namespace Ogre { */ void generateExtremes(size_t count); - /** Returns true(by default) if the submesh should be included in the mesh EdgeList, otherwise returns false. - */ - bool isBuildEdgesEnabled(void) const { return mBuildEdgesEnabled; } - void setBuildEdgesEnabled(bool b); + /** Returns true(by default) if the submesh should be included in the mesh EdgeList, otherwise returns false. + */ + bool isBuildEdgesEnabled(void) const { return mBuildEdgesEnabled; } + void setBuildEdgesEnabled(bool b); /** Makes a copy of this submesh object and gives it a new name. @param newName The name to give the clone. @@ -277,22 +277,22 @@ namespace Ogre { /// Flag indicating that bone assignments need to be recompiled bool mBoneAssignmentsOutOfDate; - /// Type of vertex animation for dedicated vertex data (populated by Mesh) - mutable VertexAnimationType mVertexAnimationType; + /// Type of vertex animation for dedicated vertex data (populated by Mesh) + mutable VertexAnimationType mVertexAnimationType; - /// Whether normals are included in vertex animation keyframes - mutable bool mVertexAnimationIncludesNormals; + /// Whether normals are included in vertex animation keyframes + mutable bool mVertexAnimationIncludesNormals; - /// Is Build Edges Enabled - bool mBuildEdgesEnabled; + /// Is Build Edges Enabled + bool mBuildEdgesEnabled; /// Internal method for removing LOD data void removeLodLevels(void); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } // namespace diff --git a/OgreMain/include/OgreTagPoint.h b/OgreMain/include/OgreTagPoint.h index 8c18eeada5e..75e41d97a98 100644 --- a/OgreMain/include/OgreTagPoint.h +++ b/OgreMain/include/OgreTagPoint.h @@ -33,17 +33,17 @@ THE SOFTWARE. #include "OgreBone.h" #include "OgreMatrix4.h" -namespace Ogre { +namespace Ogre { - - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ - /** A tagged point on a skeleton, which can be used to attach entities to on specific + + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ + /** A tagged point on a skeleton, which can be used to attach entities to on specific other entities. @remarks A Skeleton, like a Mesh, is shared between Entity objects and simply updated as required @@ -58,17 +58,17 @@ namespace Ogre { the objects, which creates a new TagPoint on demand. */ class _OgreExport TagPoint : public Bone - { + { - public: - TagPoint(unsigned short handle, Skeleton* creator); - virtual ~TagPoint(); + public: + TagPoint(unsigned short handle, Skeleton* creator); + virtual ~TagPoint(); - Entity *getParentEntity(void) const; + Entity *getParentEntity(void) const; MovableObject* getChildObject(void) const; - - void setParentEntity(Entity *pEntity); - void setChildObject(MovableObject *pObject); + + void setParentEntity(Entity *pEntity); + void setChildObject(MovableObject *pObject); /** Tells the TagPoint whether it should inherit orientation from it's parent entity. @param inherit If true, this TagPoint's orientation will be affected by @@ -90,11 +90,11 @@ namespace Ogre { */ bool getInheritParentEntityScale(void) const; - /** Gets the transform of parent entity. */ - const Matrix4& getParentEntityTransform(void) const; + /** Gets the transform of parent entity. */ + const Matrix4& getParentEntityTransform(void) const; /** Gets the transform of this node just for the skeleton (not entity) */ - const Matrix4& _getFullLocalTransform(void) const; + const Matrix4& _getFullLocalTransform(void) const; /** @copydoc Node::needUpdate */ void needUpdate(bool forceParentUpdate = false); @@ -106,16 +106,16 @@ namespace Ogre { - private: - Entity *mParentEntity; - MovableObject *mChildObject; + private: + Entity *mParentEntity; + MovableObject *mChildObject; mutable Matrix4 mFullLocalTransform; bool mInheritParentEntityOrientation; bool mInheritParentEntityScale; - }; + }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } //namespace diff --git a/OgreMain/include/OgreTangentSpaceCalc.h b/OgreMain/include/OgreTangentSpaceCalc.h index aabd471962f..2b133126e69 100644 --- a/OgreMain/include/OgreTangentSpaceCalc.h +++ b/OgreMain/include/OgreTangentSpaceCalc.h @@ -37,230 +37,230 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Class for calculating a tangent space basis. - */ - class _OgreExport TangentSpaceCalc - { - public: - TangentSpaceCalc(); - virtual ~TangentSpaceCalc(); - - typedef std::pair VertexSplit; - - /// Information about a remapped index - struct IndexRemap - { - /// Index data set (can be >0 if more than one index data was added) - size_t indexSet; - /// The position in the index buffer that's affected - size_t faceIndex; - /// The old and new vertex index - VertexSplit splitVertex; - - IndexRemap() {} // to keep container happy - IndexRemap(size_t i, size_t f, const VertexSplit& s) : indexSet(i), faceIndex(f), splitVertex(s) {} - }; - /** List of indexes that were remapped (split vertices). - */ - typedef list::type IndexRemapList; - - typedef list::type VertexSplits; - - /// The result of having built a tangent space basis - struct Result - { - /** A list of vertex indices which were split off into new vertices - because of mirroring. First item in each pair is the source vertex - index, the second value is the split vertex index. - */ - VertexSplits vertexSplits; - /** A list of indexes which were affected by splits. You can use this if you have other - triangle-based data which you will need to alter to match. */ - IndexRemapList indexesRemapped; - }; - - /// Reset the calculation object - void clear(); - - /** Set the incoming vertex data (which will be modified) */ - void setVertexData(VertexData* v_in); - - /** Add a set of index data that references the vertex data. - This might be modified if there are vertex splits. - */ - void addIndexData(IndexData* i_in, RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST); - - /** Sets whether to store tangent space parity in the W of a 4-component tangent or not. - @remarks - The default element format to use is VET_FLOAT3 which is enough to accurately - deal with tangents that do not involve any texture coordinate mirroring. - If you wish to allow UV mirroring in your model, you must enable 4-component - tangents using this method, and the 'w' co-ordinate will be populated - with the parity of the triangle (+1 or -1), which will allow you to generate - the bitangent properly. - @param enabled true to enable 4-component tangents (default false). If you enable - this, you will probably also want to enable mirror splitting (see setSplitMirrored), - and your shader must understand how to deal with the parity. - */ - void setStoreParityInW(bool enabled) { mStoreParityInW = enabled; } - - /** Gets whether to store tangent space parity in the W of a 4-component tangent or not. */ - bool getStoreParityInW() const { return mStoreParityInW; } - - /** Sets whether or not to split vertices when a mirrored tangent space - transition is detected (matrix parity differs). - @remarks - This defaults to 'off' because it's the safest option; tangents will be - interpolated in all cases even if they don't agree around a vertex, so - artefacts will be smoothed out. When you're using art assets of - unknown quality this can avoid extra seams on the visible surface. - However, if your artists are good, they will be hiding texture seams - in folds of the model and thus you can turn this option on, which will - prevent the results of those seams from getting smoothed into other - areas, which is exactly what you want. - @note This option is automatically disabled if you provide any strip or - fan based geometry. - */ - void setSplitMirrored(bool split) { mSplitMirrored = split; } - - /** Gets whether or not to split vertices when a mirrored tangent space - transition is detected. - */ - bool getSplitMirrored() const { return mSplitMirrored; } - - /** Sets whether or not to split vertices when tangent space rotates - more than 90 degrees around a vertex. - @remarks - This defaults to 'off' because it's the safest option; tangents will be - interpolated in all cases even if they don't agree around a vertex, so - artefacts will be smoothed out. When you're using art assets of - unknown quality this can avoid extra seams on the visible surface. - However, if your artists are good, they will be hiding texture inconsistencies - in folds of the model and thus you can turn this option on, which will - prevent the results of those seams from getting smoothed into other - areas, which is exactly what you want. - @note This option is automatically disabled if you provide any strip or - fan based geometry. - */ - void setSplitRotated(bool split) { mSplitRotated = split; } - /** Sets whether or not to split vertices when tangent space rotates - more than 90 degrees around a vertex. - */ - bool getSplitRotated() const { return mSplitRotated; } - - /** Build a tangent space basis from the provided data. - @remarks - Only indexed triangle lists are allowed. Strips and fans cannot be - supported because it may be necessary to split the geometry up to - respect deviances in the tangent space basis better. - @param targetSemantic The semantic to store the tangents in. Defaults to - the explicit tangent binding, but note that this is only usable on more - modern hardware (Shader Model 2), so if you need portability with older - cards you should change this to a texture coordinate binding instead. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Class for calculating a tangent space basis. + */ + class _OgreExport TangentSpaceCalc + { + public: + TangentSpaceCalc(); + virtual ~TangentSpaceCalc(); + + typedef std::pair VertexSplit; + + /// Information about a remapped index + struct IndexRemap + { + /// Index data set (can be >0 if more than one index data was added) + size_t indexSet; + /// The position in the index buffer that's affected + size_t faceIndex; + /// The old and new vertex index + VertexSplit splitVertex; + + IndexRemap() {} // to keep container happy + IndexRemap(size_t i, size_t f, const VertexSplit& s) : indexSet(i), faceIndex(f), splitVertex(s) {} + }; + /** List of indexes that were remapped (split vertices). + */ + typedef list::type IndexRemapList; + + typedef list::type VertexSplits; + + /// The result of having built a tangent space basis + struct Result + { + /** A list of vertex indices which were split off into new vertices + because of mirroring. First item in each pair is the source vertex + index, the second value is the split vertex index. + */ + VertexSplits vertexSplits; + /** A list of indexes which were affected by splits. You can use this if you have other + triangle-based data which you will need to alter to match. */ + IndexRemapList indexesRemapped; + }; + + /// Reset the calculation object + void clear(); + + /** Set the incoming vertex data (which will be modified) */ + void setVertexData(VertexData* v_in); + + /** Add a set of index data that references the vertex data. + This might be modified if there are vertex splits. + */ + void addIndexData(IndexData* i_in, RenderOperation::OperationType opType = RenderOperation::OT_TRIANGLE_LIST); + + /** Sets whether to store tangent space parity in the W of a 4-component tangent or not. + @remarks + The default element format to use is VET_FLOAT3 which is enough to accurately + deal with tangents that do not involve any texture coordinate mirroring. + If you wish to allow UV mirroring in your model, you must enable 4-component + tangents using this method, and the 'w' co-ordinate will be populated + with the parity of the triangle (+1 or -1), which will allow you to generate + the bitangent properly. + @param enabled true to enable 4-component tangents (default false). If you enable + this, you will probably also want to enable mirror splitting (see setSplitMirrored), + and your shader must understand how to deal with the parity. + */ + void setStoreParityInW(bool enabled) { mStoreParityInW = enabled; } + + /** Gets whether to store tangent space parity in the W of a 4-component tangent or not. */ + bool getStoreParityInW() const { return mStoreParityInW; } + + /** Sets whether or not to split vertices when a mirrored tangent space + transition is detected (matrix parity differs). + @remarks + This defaults to 'off' because it's the safest option; tangents will be + interpolated in all cases even if they don't agree around a vertex, so + artefacts will be smoothed out. When you're using art assets of + unknown quality this can avoid extra seams on the visible surface. + However, if your artists are good, they will be hiding texture seams + in folds of the model and thus you can turn this option on, which will + prevent the results of those seams from getting smoothed into other + areas, which is exactly what you want. + @note This option is automatically disabled if you provide any strip or + fan based geometry. + */ + void setSplitMirrored(bool split) { mSplitMirrored = split; } + + /** Gets whether or not to split vertices when a mirrored tangent space + transition is detected. + */ + bool getSplitMirrored() const { return mSplitMirrored; } + + /** Sets whether or not to split vertices when tangent space rotates + more than 90 degrees around a vertex. + @remarks + This defaults to 'off' because it's the safest option; tangents will be + interpolated in all cases even if they don't agree around a vertex, so + artefacts will be smoothed out. When you're using art assets of + unknown quality this can avoid extra seams on the visible surface. + However, if your artists are good, they will be hiding texture inconsistencies + in folds of the model and thus you can turn this option on, which will + prevent the results of those seams from getting smoothed into other + areas, which is exactly what you want. + @note This option is automatically disabled if you provide any strip or + fan based geometry. + */ + void setSplitRotated(bool split) { mSplitRotated = split; } + /** Sets whether or not to split vertices when tangent space rotates + more than 90 degrees around a vertex. + */ + bool getSplitRotated() const { return mSplitRotated; } + + /** Build a tangent space basis from the provided data. + @remarks + Only indexed triangle lists are allowed. Strips and fans cannot be + supported because it may be necessary to split the geometry up to + respect deviances in the tangent space basis better. + @param targetSemantic The semantic to store the tangents in. Defaults to + the explicit tangent binding, but note that this is only usable on more + modern hardware (Shader Model 2), so if you need portability with older + cards you should change this to a texture coordinate binding instead. @param sourceTexCoordSet The texture coordinate index which should be used as the source of 2D texture coordinates, with which to calculate the tangents. @param index The element index, ie the texture coordinate set which should be used to store the 3D coordinates representing a tangent vector per vertex, if targetSemantic is - VES_TEXTURE_COORDINATES. If this already exists, it will be overwritten. - @return - A structure containing the results of the tangent space build. Vertex data - will always be modified but it's also possible that the index data - could be adjusted. This happens when mirroring is used on a mesh, which - causes the tangent space to be inverted on opposite sides of an edge. - This is discontinuous, therefore the vertices have to be split along - this edge, resulting in new vertices. - */ - Result build(VertexElementSemantic targetSemantic = VES_TANGENT, - unsigned short sourceTexCoordSet = 0, unsigned short index = 1); - - - protected: - - VertexData* mVData; - typedef vector::type IndexDataList; - typedef vector::type OpTypeList; - IndexDataList mIDataList; - OpTypeList mOpTypes; - bool mSplitMirrored; - bool mSplitRotated; - bool mStoreParityInW; - - - struct VertexInfo - { - Vector3 pos; - Vector3 norm; - Vector2 uv; - Vector3 tangent; - Vector3 binormal; - // Which way the tangent space is oriented (+1 / -1) (set on first time found) - int parity; - // What index the opposite parity vertex copy is at (0 if not created yet) - size_t oppositeParityIndex; - - VertexInfo() : tangent(Vector3::ZERO), binormal(Vector3::ZERO), - parity(0), oppositeParityIndex(0) {} - }; - typedef vector::type VertexInfoArray; - VertexInfoArray mVertexArray; - - void extendBuffers(VertexSplits& splits); - void insertTangents(Result& res, - VertexElementSemantic targetSemantic, - unsigned short sourceTexCoordSet, unsigned short index); - - void populateVertexArray(unsigned short sourceTexCoordSet); - void processFaces(Result& result); - /// Calculate face tangent space, U and V are weighted by UV area, N is normalised - void calculateFaceTangentSpace(const size_t* vertInd, Vector3& tsU, Vector3& tsV, Vector3& tsN); - Real calculateAngleWeight(size_t v0, size_t v1, size_t v2); - int calculateParity(const Vector3& u, const Vector3& v, const Vector3& n); - void addFaceTangentSpaceToVertices(size_t indexSet, size_t faceIndex, size_t *localVertInd, - const Vector3& faceTsU, const Vector3& faceTsV, const Vector3& faceNorm, Result& result); - void normaliseVertices(); - void remapIndexes(Result& res); - template - void remapIndexes(T* ibuf, size_t indexSet, Result& res) - { - for (IndexRemapList::iterator i = res.indexesRemapped.begin(); - i != res.indexesRemapped.end(); ++i) - { - IndexRemap& remap = *i; - - // Note that because this is a vertex split situation, and vertex - // split is only for some faces, it's not a case of replacing all - // instances of vertex index A with vertex index B - // It actually matters which triangle we're talking about, so drive - // the update from the face index - - if (remap.indexSet == indexSet) - { - T* pBuf; - pBuf = ibuf + remap.faceIndex * 3; - - for (int v = 0; v < 3; ++v, ++pBuf) - { - if (*pBuf == remap.splitVertex.first) - { - *pBuf = (T)remap.splitVertex.second; - } - } - } - - - } - } - - - }; - /** @} */ - /** @} */ + VES_TEXTURE_COORDINATES. If this already exists, it will be overwritten. + @return + A structure containing the results of the tangent space build. Vertex data + will always be modified but it's also possible that the index data + could be adjusted. This happens when mirroring is used on a mesh, which + causes the tangent space to be inverted on opposite sides of an edge. + This is discontinuous, therefore the vertices have to be split along + this edge, resulting in new vertices. + */ + Result build(VertexElementSemantic targetSemantic = VES_TANGENT, + unsigned short sourceTexCoordSet = 0, unsigned short index = 1); + + + protected: + + VertexData* mVData; + typedef vector::type IndexDataList; + typedef vector::type OpTypeList; + IndexDataList mIDataList; + OpTypeList mOpTypes; + bool mSplitMirrored; + bool mSplitRotated; + bool mStoreParityInW; + + + struct VertexInfo + { + Vector3 pos; + Vector3 norm; + Vector2 uv; + Vector3 tangent; + Vector3 binormal; + // Which way the tangent space is oriented (+1 / -1) (set on first time found) + int parity; + // What index the opposite parity vertex copy is at (0 if not created yet) + size_t oppositeParityIndex; + + VertexInfo() : tangent(Vector3::ZERO), binormal(Vector3::ZERO), + parity(0), oppositeParityIndex(0) {} + }; + typedef vector::type VertexInfoArray; + VertexInfoArray mVertexArray; + + void extendBuffers(VertexSplits& splits); + void insertTangents(Result& res, + VertexElementSemantic targetSemantic, + unsigned short sourceTexCoordSet, unsigned short index); + + void populateVertexArray(unsigned short sourceTexCoordSet); + void processFaces(Result& result); + /// Calculate face tangent space, U and V are weighted by UV area, N is normalised + void calculateFaceTangentSpace(const size_t* vertInd, Vector3& tsU, Vector3& tsV, Vector3& tsN); + Real calculateAngleWeight(size_t v0, size_t v1, size_t v2); + int calculateParity(const Vector3& u, const Vector3& v, const Vector3& n); + void addFaceTangentSpaceToVertices(size_t indexSet, size_t faceIndex, size_t *localVertInd, + const Vector3& faceTsU, const Vector3& faceTsV, const Vector3& faceNorm, Result& result); + void normaliseVertices(); + void remapIndexes(Result& res); + template + void remapIndexes(T* ibuf, size_t indexSet, Result& res) + { + for (IndexRemapList::iterator i = res.indexesRemapped.begin(); + i != res.indexesRemapped.end(); ++i) + { + IndexRemap& remap = *i; + + // Note that because this is a vertex split situation, and vertex + // split is only for some faces, it's not a case of replacing all + // instances of vertex index A with vertex index B + // It actually matters which triangle we're talking about, so drive + // the update from the face index + + if (remap.indexSet == indexSet) + { + T* pBuf; + pBuf = ibuf + remap.faceIndex * 3; + + for (int v = 0; v < 3; ++v, ++pBuf) + { + if (*pBuf == remap.splitVertex.first) + { + *pBuf = (T)remap.splitVertex.second; + } + } + } + + + } + } + + + }; + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreTechnique.h b/OgreMain/include/OgreTechnique.h index 08b92e0768d..00ed29186fc 100644 --- a/OgreMain/include/OgreTechnique.h +++ b/OgreMain/include/OgreTechnique.h @@ -35,19 +35,19 @@ THE SOFTWARE. #include "OgreUserObjectBindings.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Materials - * @{ - */ - /** Class representing an approach to rendering this particular Material. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Materials + * @{ + */ + /** Class representing an approach to rendering this particular Material. @remarks Ogre will attempt to use the best technique supported by the active hardware, unless you specifically request a lower detail technique (say for distant rendering). */ - class _OgreExport Technique : public TechniqueAlloc + class _OgreExport Technique : public TechniqueAlloc { protected: /// Illumination pass state type @@ -67,83 +67,83 @@ namespace Ogre { Material* mParent; bool mIsSupported; IlluminationPassesState mIlluminationPassesCompilationPhase; - /// LOD level + /// LOD level unsigned short mLodIndex; - /** Scheme index, derived from scheme name but the names are held on - MaterialManager, for speed an index is used here. - */ - unsigned short mSchemeIndex; + /** Scheme index, derived from scheme name but the names are held on + MaterialManager, for speed an index is used here. + */ + unsigned short mSchemeIndex; /// Optional name for the technique String mName; /// Internal method for clearing illumination pass list void clearIlluminationPasses(void); - /// Internal method - check for manually assigned illumination passes - bool checkManuallyOrganisedIlluminationPasses(); - - - /** When casting shadow, if not using default Ogre shadow casting material, or - * nor using fixed function casting, mShadowCasterMaterial let you customize per material - * shadow caster behavior - */ - MaterialPtr mShadowCasterMaterial; - /** When casting shadow, if not using default Ogre shadow casting material, or - * nor using fixed function casting, mShadowCasterMaterial let you customize per material - * shadow caster behavior.There only material name is stored so that it can be loaded once all file parsed in a resource group. - */ - String mShadowCasterMaterialName; - /** When receiving shadow, if not using default Ogre shadow receiving material, or - * nor using fixed function texture projection receiving, mShadowReceiverMaterial let you customize per material - * shadow caster behavior - */ - MaterialPtr mShadowReceiverMaterial; - /** When receiving shadow, if not using default Ogre shadow receiving material, or - * nor using fixed function texture projection receiving, mShadowReceiverMaterial let you customize per material - * shadow caster behavior. There only material name is stored so that it can be loaded once all file parsed in a resource group. - */ - String mShadowReceiverMaterialName; - - // User objects binding. - UserObjectBindings mUserObjectBindings; - - public: - /** Directive used to manually control technique support based on the - inclusion or exclusion of some factor. - */ - enum IncludeOrExclude - { - /// Inclusive - only support if present - INCLUDE = 0, - /// Exclusive - do not support if present - EXCLUDE = 1 - }; - /// Rule controlling whether technique is deemed supported based on GPU vendor - struct GPUVendorRule - { - GPUVendor vendor; - IncludeOrExclude includeOrExclude; - GPUVendorRule() - : vendor(GPU_UNKNOWN), includeOrExclude(EXCLUDE) {} - GPUVendorRule(GPUVendor v, IncludeOrExclude ie) - : vendor(v), includeOrExclude(ie) {} - }; - /// Rule controlling whether technique is deemed supported based on GPU device name - struct GPUDeviceNameRule - { - String devicePattern; - IncludeOrExclude includeOrExclude; - bool caseSensitive; - GPUDeviceNameRule() - : includeOrExclude(EXCLUDE), caseSensitive(false) {} - GPUDeviceNameRule(const String& pattern, IncludeOrExclude ie, bool caseSen) - : devicePattern(pattern), includeOrExclude(ie), caseSensitive(caseSen) {} - }; - typedef vector::type GPUVendorRuleList; - typedef vector::type GPUDeviceNameRuleList; - protected: - GPUVendorRuleList mGPUVendorRules; - GPUDeviceNameRuleList mGPUDeviceNameRules; - public: + /// Internal method - check for manually assigned illumination passes + bool checkManuallyOrganisedIlluminationPasses(); + + + /** When casting shadow, if not using default Ogre shadow casting material, or + * nor using fixed function casting, mShadowCasterMaterial let you customize per material + * shadow caster behavior + */ + MaterialPtr mShadowCasterMaterial; + /** When casting shadow, if not using default Ogre shadow casting material, or + * nor using fixed function casting, mShadowCasterMaterial let you customize per material + * shadow caster behavior.There only material name is stored so that it can be loaded once all file parsed in a resource group. + */ + String mShadowCasterMaterialName; + /** When receiving shadow, if not using default Ogre shadow receiving material, or + * nor using fixed function texture projection receiving, mShadowReceiverMaterial let you customize per material + * shadow caster behavior + */ + MaterialPtr mShadowReceiverMaterial; + /** When receiving shadow, if not using default Ogre shadow receiving material, or + * nor using fixed function texture projection receiving, mShadowReceiverMaterial let you customize per material + * shadow caster behavior. There only material name is stored so that it can be loaded once all file parsed in a resource group. + */ + String mShadowReceiverMaterialName; + + // User objects binding. + UserObjectBindings mUserObjectBindings; + + public: + /** Directive used to manually control technique support based on the + inclusion or exclusion of some factor. + */ + enum IncludeOrExclude + { + /// Inclusive - only support if present + INCLUDE = 0, + /// Exclusive - do not support if present + EXCLUDE = 1 + }; + /// Rule controlling whether technique is deemed supported based on GPU vendor + struct GPUVendorRule + { + GPUVendor vendor; + IncludeOrExclude includeOrExclude; + GPUVendorRule() + : vendor(GPU_UNKNOWN), includeOrExclude(EXCLUDE) {} + GPUVendorRule(GPUVendor v, IncludeOrExclude ie) + : vendor(v), includeOrExclude(ie) {} + }; + /// Rule controlling whether technique is deemed supported based on GPU device name + struct GPUDeviceNameRule + { + String devicePattern; + IncludeOrExclude includeOrExclude; + bool caseSensitive; + GPUDeviceNameRule() + : includeOrExclude(EXCLUDE), caseSensitive(false) {} + GPUDeviceNameRule(const String& pattern, IncludeOrExclude ie, bool caseSen) + : devicePattern(pattern), includeOrExclude(ie), caseSensitive(caseSen) {} + }; + typedef vector::type GPUVendorRuleList; + typedef vector::type GPUDeviceNameRuleList; + protected: + GPUVendorRuleList mGPUVendorRules; + GPUDeviceNameRuleList mGPUDeviceNameRules; + public: /// Constructor Technique(Material* parent); /// Copy constructor @@ -156,16 +156,16 @@ namespace Ogre { */ bool isSupported(void) const; /** Internal compilation method; see Material::compile. - @return Any information explaining problems with the compile. - */ + @return Any information explaining problems with the compile. + */ String _compile(bool autoManageTextureUnits); - /// Internal method for checking GPU vendor / device rules - bool checkGPURules(StringStream& errors); - /// Internal method for checking hardware support - bool checkHardwareSupport(bool autoManageTextureUnits, StringStream& compileErrors); + /// Internal method for checking GPU vendor / device rules + bool checkGPURules(StringStream& errors); + /// Internal method for checking hardware support + bool checkHardwareSupport(bool autoManageTextureUnits, StringStream& compileErrors); /** Internal method for splitting the passes into illumination passes. */ void _compileIlluminationPasses(void); - size_t calculateSize(void) const; + size_t calculateSize(void) const; /** Creates a new Pass for this Technique. @remarks @@ -206,32 +206,32 @@ namespace Ogre { /** Overloaded operator to copy on Technique to another. */ Technique& operator=(const Technique& rhs); - /// Gets the resource group of the ultimate parent Material - const String& getResourceGroup(void) const; - - /** Returns true if this Technique involves transparency. - @remarks - This basically boils down to whether the first pass - has a scene blending factor. Even if the other passes - do not, the base colour, including parts of the original - scene, may be used for blending, therefore we have to treat - the whole Technique as transparent. - */ - bool isTransparent(void) const; - - /** Returns true if this Technique has transparent sorting enabled. - @remarks - This basically boils down to whether the first pass - has transparent sorting enabled or not - */ - bool isTransparentSortingEnabled(void) const; - - /** Returns true if this Technique has transparent sorting forced. - @remarks - This basically boils down to whether the first pass - has transparent sorting forced or not - */ - bool isTransparentSortingForced(void) const; + /// Gets the resource group of the ultimate parent Material + const String& getResourceGroup(void) const; + + /** Returns true if this Technique involves transparency. + @remarks + This basically boils down to whether the first pass + has a scene blending factor. Even if the other passes + do not, the base colour, including parts of the original + scene, may be used for blending, therefore we have to treat + the whole Technique as transparent. + */ + bool isTransparent(void) const; + + /** Returns true if this Technique has transparent sorting enabled. + @remarks + This basically boils down to whether the first pass + has transparent sorting enabled or not + */ + bool isTransparentSortingEnabled(void) const; + + /** Returns true if this Technique has transparent sorting forced. + @remarks + This basically boils down to whether the first pass + has transparent sorting forced or not + */ + bool isTransparentSortingForced(void) const; /** Internal prepare method, derived from call to Material::prepare. */ void _prepare(void); @@ -248,24 +248,24 @@ namespace Ogre { /** Tells the technique that it needs recompilation. */ void _notifyNeedsRecompile(void); - /** return this material specific shadow casting specific material - */ - Ogre::MaterialPtr getShadowCasterMaterial() const; - /** set this material specific shadow casting specific material - */ - void setShadowCasterMaterial(Ogre::MaterialPtr val); - /** set this material specific shadow casting specific material - */ - void setShadowCasterMaterial(const Ogre::String &name); - /** return this material specific shadow receiving specific material - */ - Ogre::MaterialPtr getShadowReceiverMaterial() const; - /** set this material specific shadow receiving specific material - */ - void setShadowReceiverMaterial(Ogre::MaterialPtr val); - /** set this material specific shadow receiving specific material - */ - void setShadowReceiverMaterial(const Ogre::String &name); + /** return this material specific shadow casting specific material + */ + Ogre::MaterialPtr getShadowCasterMaterial() const; + /** set this material specific shadow casting specific material + */ + void setShadowCasterMaterial(Ogre::MaterialPtr val); + /** set this material specific shadow casting specific material + */ + void setShadowCasterMaterial(const Ogre::String &name); + /** return this material specific shadow receiving specific material + */ + Ogre::MaterialPtr getShadowReceiverMaterial() const; + /** set this material specific shadow receiving specific material + */ + void setShadowReceiverMaterial(Ogre::MaterialPtr val); + /** set this material specific shadow receiving specific material + */ + void setShadowReceiverMaterial(const Ogre::String &name); // ------------------------------------------------------------------------------- // The following methods are to make migration from previous versions simpler @@ -372,7 +372,7 @@ namespace Ogre { */ void setSelfIllumination(const ColourValue& selfIllum); - /** Sets whether or not each Pass renders with depth-buffer checking on or not. + /** Sets whether or not each Pass renders with depth-buffer checking on or not. @note This property actually exists on the Pass class. For simplicity, this method allows you to set these properties for every current Pass within this Technique. If @@ -402,15 +402,15 @@ namespace Ogre { */ void setDepthFunction( CompareFunction func ); - /** Sets whether or not colour buffer writing is enabled for each Pass. + /** Sets whether or not colour buffer writing is enabled for each Pass. @note This property actually exists on the Pass class. For simplicity, this method allows you to set these properties for every current Pass within this Technique. If you need more precision, retrieve the Pass instance and set the property there. @see Pass::setColourWriteEnabled - */ - void setColourWriteEnabled(bool enabled); + */ + void setColourWriteEnabled(bool enabled); /** Sets the culling mode for each pass based on the 'vertex winding'. @note @@ -555,32 +555,32 @@ namespace Ogre { /** Gets the level-of-detail index assigned to this Technique. */ unsigned short getLodIndex(void) const { return mLodIndex; } - /** Set the 'scheme name' for this technique. - @remarks - Material schemes are used to control top-level switching from one - set of techniques to another. For example, you might use this to - define 'high', 'medium' and 'low' complexity levels on materials - to allow a user to pick a performance / quality ratio. Another - possibility is that you have a fully HDR-enabled pipeline for top - machines, rendering all objects using unclamped shaders, and a - simpler pipeline for others; this can be implemented using - schemes. - @par - Every technique belongs to a scheme - if you don't specify one, the - Technique belongs to the scheme called 'Default', which is also the - scheme used to render by default. The active scheme is set one of - two ways - either by calling Viewport::setMaterialScheme, or - by manually calling MaterialManager::setActiveScheme. - */ - void setSchemeName(const String& schemeName); - /** Returns the scheme to which this technique is assigned. - @see Technique::setSchemeName - */ - const String& getSchemeName(void) const; - - /// Internal method for getting the scheme index - unsigned short _getSchemeIndex(void) const; - + /** Set the 'scheme name' for this technique. + @remarks + Material schemes are used to control top-level switching from one + set of techniques to another. For example, you might use this to + define 'high', 'medium' and 'low' complexity levels on materials + to allow a user to pick a performance / quality ratio. Another + possibility is that you have a fully HDR-enabled pipeline for top + machines, rendering all objects using unclamped shaders, and a + simpler pipeline for others; this can be implemented using + schemes. + @par + Every technique belongs to a scheme - if you don't specify one, the + Technique belongs to the scheme called 'Default', which is also the + scheme used to render by default. The active scheme is set one of + two ways - either by calling Viewport::setMaterialScheme, or + by manually calling MaterialManager::setActiveScheme. + */ + void setSchemeName(const String& schemeName); + /** Returns the scheme to which this technique is assigned. + @see Technique::setSchemeName + */ + const String& getSchemeName(void) const; + + /// Internal method for getting the scheme index + unsigned short _getSchemeIndex(void) const; + /** Is depth writing going to occur on this technique? */ bool isDepthWriteEnabled(void) const; @@ -592,8 +592,8 @@ namespace Ogre { /** Set the name of the technique. @remarks - The use of technique name is optional. Its useful in material scripts where a material could inherit - from another material and only want to modify a particular technique. + The use of technique name is optional. Its useful in material scripts where a material could inherit + from another material and only want to modify a particular technique. */ void setName(const String& name); /// Gets the name of the technique @@ -613,101 +613,101 @@ namespace Ogre { bool applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply = true) const; - /** Add a rule which manually influences the support for this technique based - on a GPU vendor. - @remarks - You can use this facility to manually control whether a technique is - considered supported, based on a GPU vendor. You can add inclusive - or exclusive rules, and you can add as many of each as you like. If - at least one inclusive rule is added, a technique is considered - unsupported if it does not match any of those inclusive rules. If exclusive rules are - added, the technique is considered unsupported if it matches any of - those inclusive rules. - @note - Any rule for the same vendor will be removed before adding this one. - @param vendor The GPU vendor - @param includeOrExclude Whether this is an inclusive or exclusive rule - */ - void addGPUVendorRule(GPUVendor vendor, IncludeOrExclude includeOrExclude); - /** Add a rule which manually influences the support for this technique based - on a GPU vendor. - @remarks - You can use this facility to manually control whether a technique is - considered supported, based on a GPU vendor. You can add inclusive - or exclusive rules, and you can add as many of each as you like. If - at least one inclusive rule is added, a technique is considered - unsupported if it does not match any of those inclusive rules. If exclusive rules are - added, the technique is considered unsupported if it matches any of - those inclusive rules. - @note - Any rule for the same vendor will be removed before adding this one. - */ - void addGPUVendorRule(const GPUVendorRule& rule); - /** Removes a matching vendor rule. - @see addGPUVendorRule - */ - void removeGPUVendorRule(GPUVendor vendor); - typedef ConstVectorIterator GPUVendorRuleIterator; - /// Get an iterator over the currently registered vendor rules. - GPUVendorRuleIterator getGPUVendorRuleIterator() const; - - /** Add a rule which manually influences the support for this technique based - on a pattern that matches a GPU device name (e.g. '*8800*'). - @remarks - You can use this facility to manually control whether a technique is - considered supported, based on a GPU device name pattern. You can add inclusive - or exclusive rules, and you can add as many of each as you like. If - at least one inclusive rule is added, a technique is considered - unsupported if it does not match any of those inclusive rules. If exclusive rules are - added, the technique is considered unsupported if it matches any of - those inclusive rules. The pattern you supply can include wildcard - characters ('*') if you only want to match part of the device name. - @note - Any rule for the same device pattern will be removed before adding this one. - @param devicePattern The GPU vendor - @param includeOrExclude Whether this is an inclusive or exclusive rule - @param caseSensitive Whether the match is case sensitive or not - */ - void addGPUDeviceNameRule(const String& devicePattern, IncludeOrExclude includeOrExclude, bool caseSensitive = false); - /** Add a rule which manually influences the support for this technique based - on a pattern that matches a GPU device name (e.g. '*8800*'). - @remarks - You can use this facility to manually control whether a technique is - considered supported, based on a GPU device name pattern. You can add inclusive - or exclusive rules, and you can add as many of each as you like. If - at least one inclusive rule is added, a technique is considered - unsupported if it does not match any of those inclusive rules. If exclusive rules are - added, the technique is considered unsupported if it matches any of - those inclusive rules. The pattern you supply can include wildcard - characters ('*') if you only want to match part of the device name. - @note - Any rule for the same device pattern will be removed before adding this one. - */ - void addGPUDeviceNameRule(const GPUDeviceNameRule& rule); - /** Removes a matching device name rule. - @see addGPUDeviceNameRule - */ - void removeGPUDeviceNameRule(const String& devicePattern); - typedef ConstVectorIterator GPUDeviceNameRuleIterator; - /// Get an iterator over the currently registered device name rules. - GPUDeviceNameRuleIterator getGPUDeviceNameRuleIterator() const; - - /** Return an instance of user objects binding associated with this class. - You can use it to associate one or more custom objects with this class instance. - @see UserObjectBindings::setUserAny. - */ - UserObjectBindings& getUserObjectBindings() { return mUserObjectBindings; } - - /** Return an instance of user objects binding associated with this class. - You can use it to associate one or more custom objects with this class instance. - @see UserObjectBindings::setUserAny. - */ - const UserObjectBindings& getUserObjectBindings() const { return mUserObjectBindings; } + /** Add a rule which manually influences the support for this technique based + on a GPU vendor. + @remarks + You can use this facility to manually control whether a technique is + considered supported, based on a GPU vendor. You can add inclusive + or exclusive rules, and you can add as many of each as you like. If + at least one inclusive rule is added, a technique is considered + unsupported if it does not match any of those inclusive rules. If exclusive rules are + added, the technique is considered unsupported if it matches any of + those inclusive rules. + @note + Any rule for the same vendor will be removed before adding this one. + @param vendor The GPU vendor + @param includeOrExclude Whether this is an inclusive or exclusive rule + */ + void addGPUVendorRule(GPUVendor vendor, IncludeOrExclude includeOrExclude); + /** Add a rule which manually influences the support for this technique based + on a GPU vendor. + @remarks + You can use this facility to manually control whether a technique is + considered supported, based on a GPU vendor. You can add inclusive + or exclusive rules, and you can add as many of each as you like. If + at least one inclusive rule is added, a technique is considered + unsupported if it does not match any of those inclusive rules. If exclusive rules are + added, the technique is considered unsupported if it matches any of + those inclusive rules. + @note + Any rule for the same vendor will be removed before adding this one. + */ + void addGPUVendorRule(const GPUVendorRule& rule); + /** Removes a matching vendor rule. + @see addGPUVendorRule + */ + void removeGPUVendorRule(GPUVendor vendor); + typedef ConstVectorIterator GPUVendorRuleIterator; + /// Get an iterator over the currently registered vendor rules. + GPUVendorRuleIterator getGPUVendorRuleIterator() const; + + /** Add a rule which manually influences the support for this technique based + on a pattern that matches a GPU device name (e.g. '*8800*'). + @remarks + You can use this facility to manually control whether a technique is + considered supported, based on a GPU device name pattern. You can add inclusive + or exclusive rules, and you can add as many of each as you like. If + at least one inclusive rule is added, a technique is considered + unsupported if it does not match any of those inclusive rules. If exclusive rules are + added, the technique is considered unsupported if it matches any of + those inclusive rules. The pattern you supply can include wildcard + characters ('*') if you only want to match part of the device name. + @note + Any rule for the same device pattern will be removed before adding this one. + @param devicePattern The GPU vendor + @param includeOrExclude Whether this is an inclusive or exclusive rule + @param caseSensitive Whether the match is case sensitive or not + */ + void addGPUDeviceNameRule(const String& devicePattern, IncludeOrExclude includeOrExclude, bool caseSensitive = false); + /** Add a rule which manually influences the support for this technique based + on a pattern that matches a GPU device name (e.g. '*8800*'). + @remarks + You can use this facility to manually control whether a technique is + considered supported, based on a GPU device name pattern. You can add inclusive + or exclusive rules, and you can add as many of each as you like. If + at least one inclusive rule is added, a technique is considered + unsupported if it does not match any of those inclusive rules. If exclusive rules are + added, the technique is considered unsupported if it matches any of + those inclusive rules. The pattern you supply can include wildcard + characters ('*') if you only want to match part of the device name. + @note + Any rule for the same device pattern will be removed before adding this one. + */ + void addGPUDeviceNameRule(const GPUDeviceNameRule& rule); + /** Removes a matching device name rule. + @see addGPUDeviceNameRule + */ + void removeGPUDeviceNameRule(const String& devicePattern); + typedef ConstVectorIterator GPUDeviceNameRuleIterator; + /// Get an iterator over the currently registered device name rules. + GPUDeviceNameRuleIterator getGPUDeviceNameRuleIterator() const; + + /** Return an instance of user objects binding associated with this class. + You can use it to associate one or more custom objects with this class instance. + @see UserObjectBindings::setUserAny. + */ + UserObjectBindings& getUserObjectBindings() { return mUserObjectBindings; } + + /** Return an instance of user objects binding associated with this class. + You can use it to associate one or more custom objects with this class instance. + @see UserObjectBindings::setUserAny. + */ + const UserObjectBindings& getUserObjectBindings() const { return mUserObjectBindings; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreTexture.h b/OgreMain/include/OgreTexture.h index 0d929def54a..7b80285a1e2 100644 --- a/OgreMain/include/OgreTexture.h +++ b/OgreMain/include/OgreTexture.h @@ -53,12 +53,12 @@ namespace Ogre { TU_STATIC_WRITE_ONLY = HardwareBuffer::HBU_STATIC_WRITE_ONLY, TU_DYNAMIC_WRITE_ONLY = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, TU_DYNAMIC_WRITE_ONLY_DISCARDABLE = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, - /// Mipmaps will be automatically generated for this texture - TU_AUTOMIPMAP = 16, - /** This texture will be a render target, i.e. used as a target for render to texture - setting this flag will ignore all other texture usages except TU_AUTOMIPMAP */ - TU_RENDERTARGET = 32, - /// Default to automatic mipmap generation static textures + /// Mipmaps will be automatically generated for this texture + TU_AUTOMIPMAP = 16, + /** This texture will be a render target, i.e. used as a target for render to texture + setting this flag will ignore all other texture usages except TU_AUTOMIPMAP */ + TU_RENDERTARGET = 32, + /// Default to automatic mipmap generation static textures TU_DEFAULT = TU_AUTOMIPMAP | TU_STATIC_WRITE_ONLY }; @@ -89,15 +89,15 @@ namespace Ogre { TEX_TYPE_2D_RECT = 6 }; - /** Enum identifying special mipmap numbers + /** Enum identifying special mipmap numbers */ - enum TextureMipmap - { - /// Generate mipmaps up to 1x1 - MIP_UNLIMITED = 0x7FFFFFFF, - /// Use TextureManager default - MIP_DEFAULT = -1 - }; + enum TextureMipmap + { + /// Generate mipmaps up to 1x1 + MIP_UNLIMITED = 0x7FFFFFFF, + /// Use TextureManager default + MIP_DEFAULT = -1 + }; /** Abstract class representing a Texture resource. @remarks @@ -128,76 +128,76 @@ namespace Ogre { */ virtual uint8 getNumMipmaps(void) const {return mNumMipmaps;} - /** Sets the number of mipmaps to be used for this texture. + /** Sets the number of mipmaps to be used for this texture. @note Must be set before calling any 'load' method. */ virtual void setNumMipmaps(uint8 num) {mNumRequestedMipmaps = mNumMipmaps = num;} - /** Are mipmaps hardware generated? - @remarks - Will only be accurate after texture load, or createInternalResources - */ - virtual bool getMipmapsHardwareGenerated(void) const { return mMipmapsHardwareGenerated; } + /** Are mipmaps hardware generated? + @remarks + Will only be accurate after texture load, or createInternalResources + */ + virtual bool getMipmapsHardwareGenerated(void) const { return mMipmapsHardwareGenerated; } /** Returns the gamma adjustment factor applied to this texture on loading. */ virtual float getGamma(void) const { return mGamma; } /** Sets the gamma adjustment factor applied to this texture on loading the - data. + data. @note Must be called before any 'load' method. This gamma factor will - be premultiplied in and may reduce the precision of your textures. - You can use setHardwareGamma if supported to apply gamma on - sampling the texture instead. + be premultiplied in and may reduce the precision of your textures. + You can use setHardwareGamma if supported to apply gamma on + sampling the texture instead. */ virtual void setGamma(float g) { mGamma = g; } - /** Sets whether this texture will be set up so that on sampling it, - hardware gamma correction is applied. - @remarks - 24-bit textures are often saved in gamma colour space; this preserves - precision in the 'darks'. However, if you're performing blending on - the sampled colours, you really want to be doing it in linear space. - One way is to apply a gamma correction value on loading (see setGamma), - but this means you lose precision in those dark colours. An alternative - is to get the hardware to do the gamma correction when reading the - texture and converting it to a floating point value for the rest of - the pipeline. This option allows you to do that; it's only supported - in relatively recent hardware (others will ignore it) but can improve - the quality of colour reproduction. - @note - Must be called before any 'load' method since it may affect the - construction of the underlying hardware resources. - Also note this only useful on textures using 8-bit colour channels. - */ - virtual void setHardwareGammaEnabled(bool enabled) { mHwGamma = enabled; } - - /** Gets whether this texture will be set up so that on sampling it, - hardware gamma correction is applied. - */ - virtual bool isHardwareGammaEnabled() const { return mHwGamma; } - - /** Set the level of multisample AA to be used if this texture is a - rendertarget. - @note This option will be ignored if TU_RENDERTARGET is not part of the - usage options on this texture, or if the hardware does not support it. - @param fsaa The number of samples - @param fsaaHint Any hinting text (@see Root::createRenderWindow) - */ - virtual void setFSAA(uint fsaa, const String& fsaaHint) { mFSAA = fsaa; mFSAAHint = fsaaHint; } - - /** Get the level of multisample AA to be used if this texture is a - rendertarget. - */ - virtual uint getFSAA() const { return mFSAA; } - - /** Get the multisample AA hint if this texture is a rendertarget. - */ - virtual const String& getFSAAHint() const { return mFSAAHint; } - - /** Returns the height of the texture. + /** Sets whether this texture will be set up so that on sampling it, + hardware gamma correction is applied. + @remarks + 24-bit textures are often saved in gamma colour space; this preserves + precision in the 'darks'. However, if you're performing blending on + the sampled colours, you really want to be doing it in linear space. + One way is to apply a gamma correction value on loading (see setGamma), + but this means you lose precision in those dark colours. An alternative + is to get the hardware to do the gamma correction when reading the + texture and converting it to a floating point value for the rest of + the pipeline. This option allows you to do that; it's only supported + in relatively recent hardware (others will ignore it) but can improve + the quality of colour reproduction. + @note + Must be called before any 'load' method since it may affect the + construction of the underlying hardware resources. + Also note this only useful on textures using 8-bit colour channels. + */ + virtual void setHardwareGammaEnabled(bool enabled) { mHwGamma = enabled; } + + /** Gets whether this texture will be set up so that on sampling it, + hardware gamma correction is applied. + */ + virtual bool isHardwareGammaEnabled() const { return mHwGamma; } + + /** Set the level of multisample AA to be used if this texture is a + rendertarget. + @note This option will be ignored if TU_RENDERTARGET is not part of the + usage options on this texture, or if the hardware does not support it. + @param fsaa The number of samples + @param fsaaHint Any hinting text (@see Root::createRenderWindow) + */ + virtual void setFSAA(uint fsaa, const String& fsaaHint) { mFSAA = fsaa; mFSAAHint = fsaaHint; } + + /** Get the level of multisample AA to be used if this texture is a + rendertarget. + */ + virtual uint getFSAA() const { return mFSAA; } + + /** Get the multisample AA hint if this texture is a rendertarget. + */ + virtual const String& getFSAAHint() const { return mFSAAHint; } + + /** Returns the height of the texture. */ virtual uint32 getHeight(void) const { return mHeight; } @@ -242,11 +242,11 @@ namespace Ogre { } /** Sets the TextureUsage identifier for this Texture; only useful before load() - - @param u is a combination of TU_STATIC, TU_DYNAMIC, TU_WRITE_ONLY - TU_AUTOMIPMAP and TU_RENDERTARGET (see TextureUsage enum). You are - strongly advised to use HBU_STATIC_WRITE_ONLY wherever possible, if you need to - update regularly, consider HBU_DYNAMIC_WRITE_ONLY. + + @param u is a combination of TU_STATIC, TU_DYNAMIC, TU_WRITE_ONLY + TU_AUTOMIPMAP and TU_RENDERTARGET (see TextureUsage enum). You are + strongly advised to use HBU_STATIC_WRITE_ONLY wherever possible, if you need to + update regularly, consider HBU_DYNAMIC_WRITE_ONLY. */ virtual void setUsage(int u) { mUsage = u; } @@ -267,43 +267,43 @@ namespace Ogre { */ virtual void freeInternalResources(void); - /** Copies (and maybe scales to fit) the contents of this texture to - another texture. */ - virtual void copyToTexture( TexturePtr& target ); + /** Copies (and maybe scales to fit) the contents of this texture to + another texture. */ + virtual void copyToTexture( TexturePtr& target ); /** Loads the data from an image. - @note Important: only call this from outside the load() routine of a - Resource. Don't call it within (including ManualResourceLoader) - use - _loadImages() instead. This method is designed to be external, - performs locking and checks the load status before loading. + @note Important: only call this from outside the load() routine of a + Resource. Don't call it within (including ManualResourceLoader) - use + _loadImages() instead. This method is designed to be external, + performs locking and checks the load status before loading. */ virtual void loadImage( const Image &img ); - - /** Loads the data from a raw stream. - @note Important: only call this from outside the load() routine of a - Resource. Don't call it within (including ManualResourceLoader) - use - _loadImages() instead. This method is designed to be external, - performs locking and checks the load status before loading. - @param stream Data stream containing the raw pixel data - @param uWidth Width of the image - @param uHeight Height of the image - @param eFormat The format of the pixel data - */ - virtual void loadRawData( DataStreamPtr& stream, - ushort uWidth, ushort uHeight, PixelFormat eFormat); - - /** Internal method to load the texture from a set of images. - @note Do NOT call this method unless you are inside the load() routine - already, e.g. a ManualResourceLoader. It is not threadsafe and does - not check or update resource loading status. - */ + + /** Loads the data from a raw stream. + @note Important: only call this from outside the load() routine of a + Resource. Don't call it within (including ManualResourceLoader) - use + _loadImages() instead. This method is designed to be external, + performs locking and checks the load status before loading. + @param stream Data stream containing the raw pixel data + @param uWidth Width of the image + @param uHeight Height of the image + @param eFormat The format of the pixel data + */ + virtual void loadRawData( DataStreamPtr& stream, + ushort uWidth, ushort uHeight, PixelFormat eFormat); + + /** Internal method to load the texture from a set of images. + @note Do NOT call this method unless you are inside the load() routine + already, e.g. a ManualResourceLoader. It is not threadsafe and does + not check or update resource loading status. + */ virtual void _loadImages( const ConstImagePtrList& images ); - /** Returns the pixel format for the texture surface. */ - virtual PixelFormat getFormat() const - { - return mFormat; - } + /** Returns the pixel format for the texture surface. */ + virtual PixelFormat getFormat() const + { + return mFormat; + } /** Returns the desired pixel format for the texture surface. */ virtual PixelFormat getDesiredFormat(void) const @@ -360,13 +360,13 @@ namespace Ogre { virtual bool getTreatLuminanceAsAlpha(void) const; /** Return the number of faces this texture has. This will be 6 for a cubemap - texture and 1 for a 1D, 2D or 3D one. + texture and 1 for a 1D, 2D or 3D one. */ virtual size_t getNumFaces() const; /** Return hardware pixel buffer for a surface. This buffer can then be used to copy data from and to a particular level of the texture. - @param face Face number, in case of a cubemap texture. Must be 0 + @param face Face number, in case of a cubemap texture. Must be 0 for other types of textures. For cubemaps, this is one of +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5) @@ -384,14 +384,14 @@ namespace Ogre { @param includeMipMaps Whether to embed mipmaps in the image */ virtual void convertToImage(Image& destImage, bool includeMipMaps = false); - + /** Retrieve a platform or API-specific piece of information from this texture. This method of retrieving information should only be used if you know what you're doing. @param name The name of the attribute to retrieve. @param pData Pointer to memory matching the type of data you want to retrieve. */ virtual void getCustomAttribute(const String& name, void* pData) {} - + /** Enable read and/or write privileges to the texture from shaders. @param bindPoint The buffer binding location for shader access. For OpenGL this must be unique and is not related to the texture binding point. @@ -411,15 +411,15 @@ namespace Ogre { uint32 mDepth; uint8 mNumRequestedMipmaps; - uint8 mNumMipmaps; - bool mMipmapsHardwareGenerated; + uint8 mNumMipmaps; + bool mMipmapsHardwareGenerated; float mGamma; - bool mHwGamma; - uint mFSAA; - String mFSAAHint; + bool mHwGamma; + uint mFSAA; + String mFSAAHint; TextureType mTextureType; - PixelFormat mFormat; + PixelFormat mFormat; int mUsage; /// Bit field, so this can't be TextureUsage PixelFormat mSrcFormat; @@ -430,31 +430,31 @@ namespace Ogre { unsigned short mDesiredFloatBitDepth; bool mTreatLuminanceAsAlpha; - bool mInternalResourcesCreated; + bool mInternalResourcesCreated; - /// @copydoc Resource::calculateSize - size_t calculateSize(void) const; - + /// @copydoc Resource::calculateSize + size_t calculateSize(void) const; + - /** Implementation of creating internal texture resources - */ - virtual void createInternalResourcesImpl(void) = 0; + /** Implementation of creating internal texture resources + */ + virtual void createInternalResourcesImpl(void) = 0; - /** Implementation of freeing internal texture resources - */ - virtual void freeInternalResourcesImpl(void) = 0; + /** Implementation of freeing internal texture resources + */ + virtual void freeInternalResourcesImpl(void) = 0; - /** Default implementation of unload which calls freeInternalResources */ - void unloadImpl(void); + /** Default implementation of unload which calls freeInternalResources */ + void unloadImpl(void); - /** Identify the source file type as a string, either from the extension - or from a magic number. - */ - String getSourceFileType() const; + /** Identify the source file type as a string, either from the extension + or from a magic number. + */ + String getSourceFileType() const; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreTextureManager.h b/OgreMain/include/OgreTextureManager.h index db2d87fd53d..c86a93db1bb 100644 --- a/OgreMain/include/OgreTextureManager.h +++ b/OgreMain/include/OgreTextureManager.h @@ -38,13 +38,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Class for loading & managing textures. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Class for loading & managing textures. @remarks Note that this class is abstract - the particular RenderSystem that is in use at the time will create @@ -65,14 +65,14 @@ namespace Ogre { virtual ~TextureManager(); - /// Create a new texture - /// @see ResourceManager::createResource - TexturePtr create (const String& name, const String& group, - bool isManual = false, ManualResourceLoader* loader = 0, - const NameValuePairList* createParams = 0); - /// Get a resource by name - /// @see ResourceManager::getResourceByName - TexturePtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + /// Create a new texture + /// @see ResourceManager::createResource + TexturePtr create (const String& name, const String& group, + bool isManual = false, ManualResourceLoader* loader = 0, + const NameValuePairList* createParams = 0); + /// Get a resource by name + /// @see ResourceManager::getResourceByName + TexturePtr getByName(const String& name, const String& groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); /** Create a new texture, or retrieve an existing one with the same name if it already exists. @@ -92,11 +92,11 @@ namespace Ogre { @param desiredFormat The format you would like to have used instead of the format being based on the contents of the texture - @param hwGammaCorrection Pass 'true' to enable hardware gamma correction - (sRGB) on this texture. The hardware will convert from gamma space - to linear space when reading from this texture. Only applicable for - 8-bits per channel textures, will be ignored for other types. Has the advantage - over pre-applied gamma that the texture precision is maintained. + @param hwGammaCorrection Pass 'true' to enable hardware gamma correction + (sRGB) on this texture. The hardware will convert from gamma space + to linear space when reading from this texture. Only applicable for + 8-bits per channel textures, will be ignored for other types. Has the advantage + over pre-applied gamma that the texture precision is maintained. @see ResourceManager::createOrRetrieve */ virtual ResourceCreateOrRetrieveResult createOrRetrieve( @@ -127,11 +127,11 @@ namespace Ogre { @param desiredFormat The format you would like to have used instead of the format being based on the contents of the texture - @param hwGammaCorrection Pass 'true' to enable hardware gamma correction - (sRGB) on this texture. The hardware will convert from gamma space - to linear space when reading from this texture. Only applicable for - 8-bits per channel textures, will be ignored for other types. Has the advantage - over pre-applied gamma that the texture precision is maintained. + @param hwGammaCorrection Pass 'true' to enable hardware gamma correction + (sRGB) on this texture. The hardware will convert from gamma space + to linear space when reading from this texture. Only applicable for + 8-bits per channel textures, will be ignored for other types. Has the advantage + over pre-applied gamma that the texture precision is maintained. */ virtual TexturePtr prepare( const String& name, const String& group, @@ -149,31 +149,31 @@ namespace Ogre { @param numMipmaps The number of pre-filtered mipmaps to generate. If left to MIP_DEFAULT then the TextureManager's default number of mipmaps will be used (see setDefaultNumMipmaps()) - If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible - level, 1x1x1. + If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible + level, 1x1x1. @param gamma The gamma adjustment factor to apply to this texture (brightening/darkening) - during loading - @param - isAlpha Only applicable to greyscale images. If true, specifies that - the image should be loaded into an alpha texture rather than a - single channel colour texture - useful for fixed-function systems. - @param - desiredFormat The format you would like to have used instead of - the format being based on the contents of the texture. Pass PF_UNKNOWN - to default. - @param hwGammaCorrection Pass 'true' to enable hardware gamma correction - (sRGB) on this texture. The hardware will convert from gamma space - to linear space when reading from this texture. Only applicable for - 8-bits per channel textures, will be ignored for other types. Has the advantage - over pre-applied gamma that the texture precision is maintained. + during loading + @param + isAlpha Only applicable to greyscale images. If true, specifies that + the image should be loaded into an alpha texture rather than a + single channel colour texture - useful for fixed-function systems. + @param + desiredFormat The format you would like to have used instead of + the format being based on the contents of the texture. Pass PF_UNKNOWN + to default. + @param hwGammaCorrection Pass 'true' to enable hardware gamma correction + (sRGB) on this texture. The hardware will convert from gamma space + to linear space when reading from this texture. Only applicable for + 8-bits per channel textures, will be ignored for other types. Has the advantage + over pre-applied gamma that the texture precision is maintained. */ virtual TexturePtr load( const String& name, const String& group, TextureType texType = TEX_TYPE_2D, int numMipmaps = MIP_DEFAULT, Real gamma = 1.0f, bool isAlpha = false, PixelFormat desiredFormat = PF_UNKNOWN, - bool hwGammaCorrection = false); + bool hwGammaCorrection = false); /** Loads a texture from an Image object. @note @@ -189,29 +189,29 @@ namespace Ogre { @param numMipmaps The number of pre-filtered mipmaps to generate. If left to MIP_DEFAULT then the TextureManager's default number of mipmaps will be used (see setDefaultNumMipmaps()) - If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible - level, 1x1x1. + If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible + level, 1x1x1. @param gamma The gamma adjustment factor to apply to this texture (brightening/darkening) - @param - isAlpha Only applicable to greyscale images. If true, specifies that - the image should be loaded into an alpha texture rather than a - single channel colour texture - useful for fixed-function systems. - @param - desiredFormat The format you would like to have used instead of - the format being based on the contents of the texture - @param hwGammaCorrection Pass 'true' to enable hardware gamma correction - (sRGB) on this texture. The hardware will convert from gamma space - to linear space when reading from this texture. Only applicable for - 8-bits per channel textures, will be ignored for other types. Has the advantage - over pre-applied gamma that the texture precision is maintained. + @param + isAlpha Only applicable to greyscale images. If true, specifies that + the image should be loaded into an alpha texture rather than a + single channel colour texture - useful for fixed-function systems. + @param + desiredFormat The format you would like to have used instead of + the format being based on the contents of the texture + @param hwGammaCorrection Pass 'true' to enable hardware gamma correction + (sRGB) on this texture. The hardware will convert from gamma space + to linear space when reading from this texture. Only applicable for + 8-bits per channel textures, will be ignored for other types. Has the advantage + over pre-applied gamma that the texture precision is maintained. */ virtual TexturePtr loadImage( const String &name, const String& group, const Image &img, TextureType texType = TEX_TYPE_2D, int numMipmaps = MIP_DEFAULT, Real gamma = 1.0f, bool isAlpha = false, PixelFormat desiredFormat = PF_UNKNOWN, bool hwGammaCorrection = false); - + /** Loads a texture from a raw data stream. @note The texture will create as manual texture without loader. @@ -234,23 +234,23 @@ namespace Ogre { @param numMipmaps The number of pre-filtered mipmaps to generate. If left to MIP_DEFAULT then the TextureManager's default number of mipmaps will be used (see setDefaultNumMipmaps()) - If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible - level, 1x1x1. + If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible + level, 1x1x1. @param gamma The gamma adjustment factor to apply to this texture (brightening/darkening) - while loading - @param hwGammaCorrection Pass 'true' to enable hardware gamma correction - (sRGB) on this texture. The hardware will convert from gamma space - to linear space when reading from this texture. Only applicable for - 8-bits per channel textures, will be ignored for other types. Has the advantage - over pre-applied gamma that the texture precision is maintained. + while loading + @param hwGammaCorrection Pass 'true' to enable hardware gamma correction + (sRGB) on this texture. The hardware will convert from gamma space + to linear space when reading from this texture. Only applicable for + 8-bits per channel textures, will be ignored for other types. Has the advantage + over pre-applied gamma that the texture precision is maintained. */ virtual TexturePtr loadRawData(const String &name, const String& group, DataStreamPtr& stream, ushort width, ushort height, PixelFormat format, TextureType texType = TEX_TYPE_2D, int numMipmaps = MIP_DEFAULT, Real gamma = 1.0f, bool hwGammaCorrection = false); - /** Create a manual texture with specified width, height and depth (not loaded from a file). + /** Create a manual texture with specified width, height and depth (not loaded from a file). @param name The name to give the resulting texture @param @@ -266,18 +266,18 @@ namespace Ogre { @param numMipmaps The number of pre-filtered mipmaps to generate. If left to MIP_DEFAULT then the TextureManager's default number of mipmaps will be used (see setDefaultNumMipmaps()) - If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible - level, 1x1x1. + If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible + level, 1x1x1. @param format The internal format you wish to request; the manager reserves the right to create a different format if the one you select is not available in this context. - @param - usage The kind of usage this texture is intended for. It - is a combination of TU_STATIC, TU_DYNAMIC, TU_WRITE_ONLY, - TU_AUTOMIPMAP and TU_RENDERTARGET (see TextureUsage enum). You are - strongly advised to use HBU_STATIC_WRITE_ONLY wherever possible, if you need to - update regularly, consider HBU_DYNAMIC_WRITE_ONLY. + @param + usage The kind of usage this texture is intended for. It + is a combination of TU_STATIC, TU_DYNAMIC, TU_WRITE_ONLY, + TU_AUTOMIPMAP and TU_RENDERTARGET (see TextureUsage enum). You are + strongly advised to use HBU_STATIC_WRITE_ONLY wherever possible, if you need to + update regularly, consider HBU_DYNAMIC_WRITE_ONLY. @param loader If you intend the contents of the manual texture to be regularly updated, to the extent that you don't need to recover @@ -287,20 +287,20 @@ namespace Ogre { and pass a pointer to it in this parameter; this means that if the manual texture ever needs to be reloaded, the ManualResourceLoader will be called to do it. - @param hwGammaCorrection Pass 'true' to enable hardware gamma correction - (sRGB) on this texture. The hardware will convert from gamma space - to linear space when reading from this texture. Only applicable for - 8-bits per channel textures, will be ignored for other types. Has the advantage - over pre-applied gamma that the texture precision is maintained. - @param fsaa The level of multisampling to use if this is a render target. Ignored - if usage does not include TU_RENDERTARGET or if the device does - not support it. + @param hwGammaCorrection Pass 'true' to enable hardware gamma correction + (sRGB) on this texture. The hardware will convert from gamma space + to linear space when reading from this texture. Only applicable for + 8-bits per channel textures, will be ignored for other types. Has the advantage + over pre-applied gamma that the texture precision is maintained. + @param fsaa The level of multisampling to use if this is a render target. Ignored + if usage does not include TU_RENDERTARGET or if the device does + not support it. */ virtual TexturePtr createManual(const String & name, const String& group, TextureType texType, uint width, uint height, uint depth, - int numMipmaps, PixelFormat format, int usage = TU_DEFAULT, ManualResourceLoader* loader = 0, - bool hwGammaCorrection = false, uint fsaa = 0, const String& fsaaHint = BLANKSTRING); - + int numMipmaps, PixelFormat format, int usage = TU_DEFAULT, ManualResourceLoader* loader = 0, + bool hwGammaCorrection = false, uint fsaa = 0, const String& fsaaHint = BLANKSTRING); + /** Create a manual texture with a depth of 1 (not loaded from a file). @param name The name to give the resulting texture @@ -315,18 +315,18 @@ namespace Ogre { @param numMipmaps The number of pre-filtered mipmaps to generate. If left to MIP_DEFAULT then the TextureManager's default number of mipmaps will be used (see setDefaultNumMipmaps()). - If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible - level, 1x1x1. + If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible + level, 1x1x1. @param format The internal format you wish to request; the manager reserves the right to create a different format if the one you select is not available in this context. - @param - usage The kind of usage this texture is intended for. It - is a combination of TU_STATIC, TU_DYNAMIC, TU_WRITE_ONLY, - TU_AUTOMIPMAP and TU_RENDERTARGET (see TextureUsage enum). You are - strongly advised to use HBU_STATIC_WRITE_ONLY wherever possible, if you need to - update regularly, consider HBU_DYNAMIC_WRITE_ONLY. + @param + usage The kind of usage this texture is intended for. It + is a combination of TU_STATIC, TU_DYNAMIC, TU_WRITE_ONLY, + TU_AUTOMIPMAP and TU_RENDERTARGET (see TextureUsage enum). You are + strongly advised to use HBU_STATIC_WRITE_ONLY wherever possible, if you need to + update regularly, consider HBU_DYNAMIC_WRITE_ONLY. @param loader If you intend the contents of the manual texture to be regularly updated, to the extent that you don't need to recover @@ -336,23 +336,23 @@ namespace Ogre { and pass a pointer to it in this parameter; this means that if the manual texture ever needs to be reloaded, the ManualResourceLoader will be called to do it. - @param hwGammaCorrection Pass 'true' to enable hardware gamma correction - (sRGB) on this texture. The hardware will convert from gamma space - to linear space when reading from this texture. Only applicable for - 8-bits per channel textures, will be ignored for other types. Has the advantage - over pre-applied gamma that the texture precision is maintained. - @param fsaa The level of multisampling to use if this is a render target. Ignored - if usage does not include TU_RENDERTARGET or if the device does - not support it. + @param hwGammaCorrection Pass 'true' to enable hardware gamma correction + (sRGB) on this texture. The hardware will convert from gamma space + to linear space when reading from this texture. Only applicable for + 8-bits per channel textures, will be ignored for other types. Has the advantage + over pre-applied gamma that the texture precision is maintained. + @param fsaa The level of multisampling to use if this is a render target. Ignored + if usage does not include TU_RENDERTARGET or if the device does + not support it. */ TexturePtr createManual(const String & name, const String& group, TextureType texType, uint width, uint height, int numMipmaps, PixelFormat format, int usage = TU_DEFAULT, ManualResourceLoader* loader = 0, - bool hwGammaCorrection = false, uint fsaa = 0, const String& fsaaHint = BLANKSTRING) - { - return createManual(name, group, texType, width, height, 1, - numMipmaps, format, usage, loader, hwGammaCorrection, fsaa, fsaaHint); - } + bool hwGammaCorrection = false, uint fsaa = 0, const String& fsaaHint = BLANKSTRING) + { + return createManual(name, group, texType, width, height, 1, + numMipmaps, format, usage, loader, hwGammaCorrection, fsaa, fsaaHint); + } /** Sets preferred bit depth for integer pixel format textures. @param @@ -392,33 +392,33 @@ namespace Ogre { */ virtual void setPreferredBitDepths(ushort integerBits, ushort floatBits, bool reloadTextures = true); - /** Returns whether this render system can natively support the precise texture - format requested with the given usage options. - @remarks - You can still create textures with this format even if this method returns - false; the texture format will just be altered to one which the device does - support. - @note - Sometimes the device may just slightly change the format, such as reordering the - channels or packing the channels differently, without it making and qualitative - differences to the texture. If you want to just detect whether the quality of a - given texture will be reduced, use isEquivalentFormatSupport instead. - @param format The pixel format requested - @param usage The kind of usage this texture is intended for, a combination of - the TextureUsage flags. - @return true if the format is natively supported, false if a fallback would be used. - */ - virtual bool isFormatSupported(TextureType ttype, PixelFormat format, int usage); - - /** Returns whether this render system can support the texture format requested - with the given usage options, or another format with no quality reduction. - */ - virtual bool isEquivalentFormatSupported(TextureType ttype, PixelFormat format, int usage); - - /** Gets the format which will be natively used for a requested format given the - constraints of the current device. - */ - virtual PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage) = 0; + /** Returns whether this render system can natively support the precise texture + format requested with the given usage options. + @remarks + You can still create textures with this format even if this method returns + false; the texture format will just be altered to one which the device does + support. + @note + Sometimes the device may just slightly change the format, such as reordering the + channels or packing the channels differently, without it making and qualitative + differences to the texture. If you want to just detect whether the quality of a + given texture will be reduced, use isEquivalentFormatSupport instead. + @param format The pixel format requested + @param usage The kind of usage this texture is intended for, a combination of + the TextureUsage flags. + @return true if the format is natively supported, false if a fallback would be used. + */ + virtual bool isFormatSupported(TextureType ttype, PixelFormat format, int usage); + + /** Returns whether this render system can support the texture format requested + with the given usage options, or another format with no quality reduction. + */ + virtual bool isEquivalentFormatSupported(TextureType ttype, PixelFormat format, int usage); + + /** Gets the format which will be natively used for a requested format given the + constraints of the current device. + */ + virtual PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage) = 0; /** Returns whether this render system has hardware filtering supported for the texture format requested with the given usage options. @@ -449,15 +449,15 @@ namespace Ogre { filtering none in the material script's texture_unit section, or call TextureUnitState::setTextureFiltering with TFO_NONE if populate material in code). - @param ttype The texture type requested - @param format The pixel format requested - @param usage The kind of usage this texture is intended for, a combination of - the TextureUsage flags. + @param ttype The texture type requested + @param format The pixel format requested + @param usage The kind of usage this texture is intended for, a combination of + the TextureUsage flags. @param preciseFormatOnly Whether precise or fallback format mode is used to detecting. In case the pixel format doesn't supported by device, false will be returned if in precise mode, and natively used pixel format will be actually use to check if in fallback mode. - @return true if the texture filtering is supported. + @return true if the texture filtering is supported. */ virtual bool isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage, bool preciseFormatOnly = false) = 0; @@ -465,8 +465,8 @@ namespace Ogre { /** Sets the default number of mipmaps to be used for loaded textures, for when textures are loaded automatically (e.g. by Material class) or when 'load' is called with the default parameters by the application. - If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible - level, 1x1x1. + If set to MIP_UNLIMITED mipmaps will be generated until the lowest possible + level, 1x1x1. @note The default value is 0. */ @@ -518,8 +518,8 @@ namespace Ogre { ushort mPreferredFloatBitDepth; size_t mDefaultNumMipmaps; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ }// Namespace #endif diff --git a/OgreMain/include/OgreTextureUnitState.h b/OgreMain/include/OgreTextureUnitState.h index b24dbdfe0ef..bd84ae385de 100644 --- a/OgreMain/include/OgreTextureUnitState.h +++ b/OgreMain/include/OgreTextureUnitState.h @@ -470,15 +470,15 @@ namespace Ogre { /** Vertex processing unit - indicates this unit will be used for a vertex texture fetch. */ - BT_VERTEX = 1, - /// Geometry processing unit - BT_GEOMETRY = 2, - /// Tessellation control processing unit - BT_TESSELLATION_HULL = 3, - /// Tessellation evaluation processing unit - BT_TESSELLATION_DOMAIN = 4, - /// Compute processing unit - BT_COMPUTE = 5 + BT_VERTEX = 1, + /// Geometry processing unit + BT_GEOMETRY = 2, + /// Tessellation control processing unit + BT_TESSELLATION_HULL = 3, + /// Tessellation evaluation processing unit + BT_TESSELLATION_DOMAIN = 4, + /// Compute processing unit + BT_COMPUTE = 5 }; /** Enum identifying the type of content this texture unit contains. */ @@ -697,9 +697,9 @@ namespace Ogre { /** Sets the texture addressing mode, i.e. what happens at uv values above 1.0. @note The default is TAM_WRAP i.e. the texture repeats over values of 1.0. - @note This is a shortcut method which sets the addressing mode for all - coordinates at once; you can also call the more specific method - to set the addressing mode per coordinate. + @note This is a shortcut method which sets the addressing mode for all + coordinates at once; you can also call the more specific method + to set the addressing mode per coordinate. @note This is a shortcut method which sets the addressing mode for all coordinates at once; you can also call the more specific method @@ -1081,11 +1081,11 @@ namespace Ogre { /// Get the texture filtering for the given type. FilterOptions getTextureFiltering(FilterType ftpye) const; - void setTextureCompareEnabled(bool enabled); - bool getTextureCompareEnabled() const; - - void setTextureCompareFunction(CompareFunction function); - CompareFunction getTextureCompareFunction() const; + void setTextureCompareEnabled(bool enabled); + bool getTextureCompareEnabled() const; + + void setTextureCompareFunction(CompareFunction function); + CompareFunction getTextureCompareFunction() const; /** Sets the anisotropy level to be used for this texture level. @param maxAniso @@ -1202,7 +1202,7 @@ namespace Ogre { /** Set the texture pointer for a given frame (internal use only!). */ void _setTexturePtr(const TexturePtr& texptr, size_t frame); - size_t calculateSize(void) const; + size_t calculateSize(void) const; /** Gets the animation controller (as created because of setAnimatedTexture) if it exists. @@ -1248,8 +1248,8 @@ namespace Ogre { /// Texture filtering - mipmapping. FilterOptions mMipFilter; - bool mCompareEnabled; - CompareFunction mCompareFunc; + bool mCompareEnabled; + CompareFunction mCompareFunc; /// Texture anisotropy. unsigned int mMaxAniso; diff --git a/OgreMain/include/OgreUTFString.h b/OgreMain/include/OgreUTFString.h index 089568c1182..0d41885e0d0 100644 --- a/OgreMain/include/OgreUTFString.h +++ b/OgreMain/include/OgreUTFString.h @@ -52,10 +52,10 @@ namespace std { template class _CRTIMP2 basic_string, - allocator >; + allocator >; template class _CRTIMP2 basic_string<__wchar_t, char_traits<__wchar_t>, - allocator<__wchar_t> >; + allocator<__wchar_t> >; } # endif // defined(_DLL_CPPLIB) @@ -64,46 +64,46 @@ namespace std namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Overlays - * @{ - */ - - /* READ THIS NOTICE BEFORE USING IN YOUR OWN APPLICATIONS - =NOTICE= - This class is not a complete Unicode solution. It purposefully does not - provide certain functionality, such as proper lexical sorting for - Unicode values. It does provide comparison operators for the sole purpose - of using UTFString as an index with std::map and other operator< sorted - containers, but it should NOT be relied upon for meaningful lexical - operations, such as alphabetical sorts. If you need this type of - functionality, look into using ICU instead (http://icu.sourceforge.net/). - - =REQUIREMENTS= - There are a few requirements for proper operation. They are fairly small, - and shouldn't restrict usage on any reasonable target. - * Compiler must support unsigned 16-bit integer types - * Compiler must support signed 32-bit integer types - * wchar_t must be either UTF-16 or UTF-32 encoding, and specified as such - using the WCHAR_UTF16 macro as outlined below. - * You must include , , and . Probably more, but - these are the most obvious. - - =REQUIRED PREPROCESSOR MACROS= - This class requires two preprocessor macros to be defined in order to - work as advertised. - INT32 - must be mapped to a signed 32 bit integer (ex. #define INT32 int) - UINT16 - must be mapped to an unsigned 16 bit integer (ex. #define UINT32 unsigned short) - - Additionally, a third macro should be defined to control the evaluation of wchar_t: - WCHAR_UTF16 - should be defined when wchar_t represents UTF-16 code points, - such as in Windows. Otherwise it is assumed that wchar_t is a 32-bit - integer representing UTF-32 code points. - */ - - // THIS IS A VERY BRIEF AUTO DETECTION. YOU MAY NEED TO TWEAK THIS + /** \addtogroup Core + * @{ + */ + /** \addtogroup Overlays + * @{ + */ + + /* READ THIS NOTICE BEFORE USING IN YOUR OWN APPLICATIONS + =NOTICE= + This class is not a complete Unicode solution. It purposefully does not + provide certain functionality, such as proper lexical sorting for + Unicode values. It does provide comparison operators for the sole purpose + of using UTFString as an index with std::map and other operator< sorted + containers, but it should NOT be relied upon for meaningful lexical + operations, such as alphabetical sorts. If you need this type of + functionality, look into using ICU instead (http://icu.sourceforge.net/). + + =REQUIREMENTS= + There are a few requirements for proper operation. They are fairly small, + and shouldn't restrict usage on any reasonable target. + * Compiler must support unsigned 16-bit integer types + * Compiler must support signed 32-bit integer types + * wchar_t must be either UTF-16 or UTF-32 encoding, and specified as such + using the WCHAR_UTF16 macro as outlined below. + * You must include , , and . Probably more, but + these are the most obvious. + + =REQUIRED PREPROCESSOR MACROS= + This class requires two preprocessor macros to be defined in order to + work as advertised. + INT32 - must be mapped to a signed 32 bit integer (ex. #define INT32 int) + UINT16 - must be mapped to an unsigned 16 bit integer (ex. #define UINT32 unsigned short) + + Additionally, a third macro should be defined to control the evaluation of wchar_t: + WCHAR_UTF16 - should be defined when wchar_t represents UTF-16 code points, + such as in Windows. Otherwise it is assumed that wchar_t is a 32-bit + integer representing UTF-32 code points. + */ + + // THIS IS A VERY BRIEF AUTO DETECTION. YOU MAY NEED TO TWEAK THIS #ifdef __STDC_ISO_10646__ // for any compiler that provides this, wchar_t is guaranteed to hold any Unicode value with a single code point (32-bit or larger) // so we can safely skip the rest of the testing @@ -140,971 +140,971 @@ namespace Ogre { #endif // OGRE_COMPILER == OGRE_COMPILER_MSVC - //! A UTF-16 string with implicit conversion to/from std::string and std::wstring - /*! This class provides a complete 1 to 1 map of most std::string functions (at least to my - knowledge). Implicit conversions allow this string class to work with all common C++ string - formats, with specialty functions defined where implicit conversion would cause potential - problems or is otherwise unavailable. - - Some additional functionality is present to assist in working with characters using the - 32-bit UTF-32 encoding. (Which is guaranteed to fit any Unicode character into a single - code point.) \b Note: Reverse iterators do not have this functionality due to the - ambiguity that surrounds working with UTF-16 in reverse. (Such as, where should an - iterator point to represent the beginning of a surrogate pair?) - - - \par Supported Input Types - The supported string types for input, and their assumed encoding schemes, are: - - std::string (UTF-8) - - char* (UTF-8) - - std::wstring (autodetected UTF-16 / UTF-32 based on compiler) - - wchar_t* (autodetected UTF-16 / UTF-32 based on compiler) - - - \see - - For additional information on UTF-16 encoding: http://en.wikipedia.org/wiki/UTF-16 - - For additional information on UTF-8 encoding: http://en.wikipedia.org/wiki/UTF-8 - - For additional information on UTF-32 encoding: http://en.wikipedia.org/wiki/UTF-32 - */ - class _OgreExport UTFString { - // constants used in UTF-8 conversions - static const unsigned char _lead1 = 0xC0; //110xxxxx - static const unsigned char _lead1_mask = 0x1F; //00011111 - static const unsigned char _lead2 = 0xE0; //1110xxxx - static const unsigned char _lead2_mask = 0x0F; //00001111 - static const unsigned char _lead3 = 0xF0; //11110xxx - static const unsigned char _lead3_mask = 0x07; //00000111 - static const unsigned char _lead4 = 0xF8; //111110xx - static const unsigned char _lead4_mask = 0x03; //00000011 - static const unsigned char _lead5 = 0xFC; //1111110x - static const unsigned char _lead5_mask = 0x01; //00000001 - static const unsigned char _cont = 0x80; //10xxxxxx - static const unsigned char _cont_mask = 0x3F; //00111111 - - public: - //! size type used to indicate string size and character positions within the string - typedef size_t size_type; - //! the usual constant representing: not found, no limit, etc - static const size_type npos = static_cast(~0); - - //! a single 32-bit Unicode character - typedef uint32 unicode_char; - - //! a single UTF-16 code point - typedef uint16 code_point; - - //! value type typedef for use in iterators - typedef code_point value_type; - - typedef std::basic_string dstring; // data string - - //! string type used for returning UTF-32 formatted data - typedef std::basic_string utf32string; - - //! This exception is used when invalid data streams are encountered - class _OgreExport invalid_data: public std::runtime_error { /* i don't know why the beautifier is freaking out on this line */ - public: - //! constructor takes a string message that can be later retrieved by the what() function - explicit invalid_data( const std::string& _Message ): std::runtime_error( _Message ) { - /* The thing is, Bob, it's not that I'm lazy, it's that I just don't care. */ - } - }; - - //######################################################################### - //! base iterator class for UTFString - class _OgreExport _base_iterator: public std::iterator { /* i don't know why the beautifier is freaking out on this line */ - friend class UTFString; - protected: - _base_iterator(); - - void _seekFwd( size_type c ); - void _seekRev( size_type c ); - void _become( const _base_iterator& i ); - bool _test_begin() const; - bool _test_end() const; - size_type _get_index() const; - void _jump_to( size_type index ); - - unicode_char _getCharacter() const; - int _setCharacter( unicode_char uc ); - - void _moveNext(); - void _movePrev(); - - dstring::iterator mIter; - UTFString* mString; - }; - - //######################################################################### - // FORWARD ITERATORS - //######################################################################### - class _const_fwd_iterator; // forward declaration - - //! forward iterator for UTFString - class _OgreExport _fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */ - friend class _const_fwd_iterator; - public: - _fwd_iterator(); - _fwd_iterator( const _fwd_iterator& i ); - - //! pre-increment - _fwd_iterator& operator++(); - //! post-increment - _fwd_iterator operator++( int ); - - //! pre-decrement - _fwd_iterator& operator--(); - //! post-decrement - _fwd_iterator operator--( int ); - - //! addition operator - _fwd_iterator operator+( difference_type n ); - //! subtraction operator - _fwd_iterator operator-( difference_type n ); - - //! addition assignment operator - _fwd_iterator& operator+=( difference_type n ); - //! subtraction assignment operator - _fwd_iterator& operator-=( difference_type n ); - - //! dereference operator - value_type& operator*() const; - - //! dereference at offset operator - value_type& operator[]( difference_type n ) const; - - //! advances to the next Unicode character, honoring surrogate pairs in the UTF-16 stream - _fwd_iterator& moveNext(); - //! rewinds to the previous Unicode character, honoring surrogate pairs in the UTF-16 stream - _fwd_iterator& movePrev(); - //! Returns the Unicode value of the character at the current position (decodes surrogate pairs if needed) - unicode_char getCharacter() const; - //! Sets the Unicode value of the character at the current position (adding a surrogate pair if needed); returns the amount of string length change caused by the operation - int setCharacter( unicode_char uc ); - }; - - - - //######################################################################### - //! const forward iterator for UTFString - class _OgreExport _const_fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */ - public: - _const_fwd_iterator(); - _const_fwd_iterator( const _const_fwd_iterator& i ); - _const_fwd_iterator( const _fwd_iterator& i ); - - //! pre-increment - _const_fwd_iterator& operator++(); - //! post-increment - _const_fwd_iterator operator++( int ); - - //! pre-decrement - _const_fwd_iterator& operator--(); - //! post-decrement - _const_fwd_iterator operator--( int ); - - //! addition operator - _const_fwd_iterator operator+( difference_type n ); - //! subtraction operator - _const_fwd_iterator operator-( difference_type n ); - - //! addition assignment operator - _const_fwd_iterator& operator+=( difference_type n ); - //! subtraction assignment operator - _const_fwd_iterator& operator-=( difference_type n ); - - //! dereference operator - const value_type& operator*() const; - - //! dereference at offset operator - const value_type& operator[]( difference_type n ) const; - - //! advances to the next Unicode character, honoring surrogate pairs in the UTF-16 stream - _const_fwd_iterator& moveNext(); - //! rewinds to the previous Unicode character, honoring surrogate pairs in the UTF-16 stream - _const_fwd_iterator& movePrev(); - //! Returns the Unicode value of the character at the current position (decodes surrogate pairs if needed) - unicode_char getCharacter() const; - - //! difference operator - friend size_type operator-( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); - //! equality operator - friend bool operator==( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); - //! inequality operator - friend bool operator!=( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); - //! less than - friend bool operator<( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); - //! less than or equal - friend bool operator<=( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); - //! greater than - friend bool operator>( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); - //! greater than or equal - friend bool operator>=( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); - - }; - - //######################################################################### - // REVERSE ITERATORS - //######################################################################### - class _const_rev_iterator; // forward declaration - //! forward iterator for UTFString - class _OgreExport _rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */ - friend class _const_rev_iterator; - public: - _rev_iterator(); - _rev_iterator( const _rev_iterator& i ); - - //! pre-increment - _rev_iterator& operator++(); - //! post-increment - _rev_iterator operator++( int ); - - //! pre-decrement - _rev_iterator& operator--(); - //! post-decrement - _rev_iterator operator--( int ); - - //! addition operator - _rev_iterator operator+( difference_type n ); - //! subtraction operator - _rev_iterator operator-( difference_type n ); - - //! addition assignment operator - _rev_iterator& operator+=( difference_type n ); - //! subtraction assignment operator - _rev_iterator& operator-=( difference_type n ); - - //! dereference operator - value_type& operator*() const; - - //! dereference at offset operator - value_type& operator[]( difference_type n ) const; - }; - //######################################################################### - //! const reverse iterator for UTFString - class _OgreExport _const_rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */ - public: - _const_rev_iterator(); - _const_rev_iterator( const _const_rev_iterator& i ); - _const_rev_iterator( const _rev_iterator& i ); - //! pre-increment - _const_rev_iterator& operator++(); - //! post-increment - _const_rev_iterator operator++( int ); - - //! pre-decrement - _const_rev_iterator& operator--(); - //! post-decrement - _const_rev_iterator operator--( int ); - - //! addition operator - _const_rev_iterator operator+( difference_type n ); - //! subtraction operator - _const_rev_iterator operator-( difference_type n ); - - //! addition assignment operator - _const_rev_iterator& operator+=( difference_type n ); - //! subtraction assignment operator - _const_rev_iterator& operator-=( difference_type n ); - - //! dereference operator - const value_type& operator*() const; - - //! dereference at offset operator - const value_type& operator[]( difference_type n ) const; - - //! difference operator - friend size_type operator-( const _const_rev_iterator& left, const _const_rev_iterator& right ); - //! equality operator - friend bool operator==( const _const_rev_iterator& left, const _const_rev_iterator& right ); - //! inequality operator - friend bool operator!=( const _const_rev_iterator& left, const _const_rev_iterator& right ); - //! less than - friend bool operator<( const _const_rev_iterator& left, const _const_rev_iterator& right ); - //! less than or equal - friend bool operator<=( const _const_rev_iterator& left, const _const_rev_iterator& right ); - //! greater than - friend bool operator>( const _const_rev_iterator& left, const _const_rev_iterator& right ); - //! greater than or equal - friend bool operator>=( const _const_rev_iterator& left, const _const_rev_iterator& right ); - }; - //######################################################################### - - typedef _fwd_iterator iterator; //!< iterator - typedef _rev_iterator reverse_iterator; //!< reverse iterator - typedef _const_fwd_iterator const_iterator; //!< const iterator - typedef _const_rev_iterator const_reverse_iterator; //!< const reverse iterator - - - //!\name Constructors/Destructor - //@{ - //! default constructor, creates an empty string - UTFString(); - //! copy constructor - UTFString( const UTFString& copy ); - //! \a length copies of \a ch - UTFString( size_type length, const code_point& ch ); - //! duplicate of nul-terminated sequence \a str - UTFString( const code_point* str ); - //! duplicate of \a str, \a length code points long - UTFString( const code_point* str, size_type length ); - //! substring of \a str starting at \a index and \a length code points long - UTFString( const UTFString& str, size_type index, size_type length ); + //! A UTF-16 string with implicit conversion to/from std::string and std::wstring + /*! This class provides a complete 1 to 1 map of most std::string functions (at least to my + knowledge). Implicit conversions allow this string class to work with all common C++ string + formats, with specialty functions defined where implicit conversion would cause potential + problems or is otherwise unavailable. + + Some additional functionality is present to assist in working with characters using the + 32-bit UTF-32 encoding. (Which is guaranteed to fit any Unicode character into a single + code point.) \b Note: Reverse iterators do not have this functionality due to the + ambiguity that surrounds working with UTF-16 in reverse. (Such as, where should an + iterator point to represent the beginning of a surrogate pair?) + + + \par Supported Input Types + The supported string types for input, and their assumed encoding schemes, are: + - std::string (UTF-8) + - char* (UTF-8) + - std::wstring (autodetected UTF-16 / UTF-32 based on compiler) + - wchar_t* (autodetected UTF-16 / UTF-32 based on compiler) + + + \see + - For additional information on UTF-16 encoding: http://en.wikipedia.org/wiki/UTF-16 + - For additional information on UTF-8 encoding: http://en.wikipedia.org/wiki/UTF-8 + - For additional information on UTF-32 encoding: http://en.wikipedia.org/wiki/UTF-32 + */ + class _OgreExport UTFString { + // constants used in UTF-8 conversions + static const unsigned char _lead1 = 0xC0; //110xxxxx + static const unsigned char _lead1_mask = 0x1F; //00011111 + static const unsigned char _lead2 = 0xE0; //1110xxxx + static const unsigned char _lead2_mask = 0x0F; //00001111 + static const unsigned char _lead3 = 0xF0; //11110xxx + static const unsigned char _lead3_mask = 0x07; //00000111 + static const unsigned char _lead4 = 0xF8; //111110xx + static const unsigned char _lead4_mask = 0x03; //00000011 + static const unsigned char _lead5 = 0xFC; //1111110x + static const unsigned char _lead5_mask = 0x01; //00000001 + static const unsigned char _cont = 0x80; //10xxxxxx + static const unsigned char _cont_mask = 0x3F; //00111111 + + public: + //! size type used to indicate string size and character positions within the string + typedef size_t size_type; + //! the usual constant representing: not found, no limit, etc + static const size_type npos = static_cast(~0); + + //! a single 32-bit Unicode character + typedef uint32 unicode_char; + + //! a single UTF-16 code point + typedef uint16 code_point; + + //! value type typedef for use in iterators + typedef code_point value_type; + + typedef std::basic_string dstring; // data string + + //! string type used for returning UTF-32 formatted data + typedef std::basic_string utf32string; + + //! This exception is used when invalid data streams are encountered + class _OgreExport invalid_data: public std::runtime_error { /* i don't know why the beautifier is freaking out on this line */ + public: + //! constructor takes a string message that can be later retrieved by the what() function + explicit invalid_data( const std::string& _Message ): std::runtime_error( _Message ) { + /* The thing is, Bob, it's not that I'm lazy, it's that I just don't care. */ + } + }; + + //######################################################################### + //! base iterator class for UTFString + class _OgreExport _base_iterator: public std::iterator { /* i don't know why the beautifier is freaking out on this line */ + friend class UTFString; + protected: + _base_iterator(); + + void _seekFwd( size_type c ); + void _seekRev( size_type c ); + void _become( const _base_iterator& i ); + bool _test_begin() const; + bool _test_end() const; + size_type _get_index() const; + void _jump_to( size_type index ); + + unicode_char _getCharacter() const; + int _setCharacter( unicode_char uc ); + + void _moveNext(); + void _movePrev(); + + dstring::iterator mIter; + UTFString* mString; + }; + + //######################################################################### + // FORWARD ITERATORS + //######################################################################### + class _const_fwd_iterator; // forward declaration + + //! forward iterator for UTFString + class _OgreExport _fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */ + friend class _const_fwd_iterator; + public: + _fwd_iterator(); + _fwd_iterator( const _fwd_iterator& i ); + + //! pre-increment + _fwd_iterator& operator++(); + //! post-increment + _fwd_iterator operator++( int ); + + //! pre-decrement + _fwd_iterator& operator--(); + //! post-decrement + _fwd_iterator operator--( int ); + + //! addition operator + _fwd_iterator operator+( difference_type n ); + //! subtraction operator + _fwd_iterator operator-( difference_type n ); + + //! addition assignment operator + _fwd_iterator& operator+=( difference_type n ); + //! subtraction assignment operator + _fwd_iterator& operator-=( difference_type n ); + + //! dereference operator + value_type& operator*() const; + + //! dereference at offset operator + value_type& operator[]( difference_type n ) const; + + //! advances to the next Unicode character, honoring surrogate pairs in the UTF-16 stream + _fwd_iterator& moveNext(); + //! rewinds to the previous Unicode character, honoring surrogate pairs in the UTF-16 stream + _fwd_iterator& movePrev(); + //! Returns the Unicode value of the character at the current position (decodes surrogate pairs if needed) + unicode_char getCharacter() const; + //! Sets the Unicode value of the character at the current position (adding a surrogate pair if needed); returns the amount of string length change caused by the operation + int setCharacter( unicode_char uc ); + }; + + + + //######################################################################### + //! const forward iterator for UTFString + class _OgreExport _const_fwd_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */ + public: + _const_fwd_iterator(); + _const_fwd_iterator( const _const_fwd_iterator& i ); + _const_fwd_iterator( const _fwd_iterator& i ); + + //! pre-increment + _const_fwd_iterator& operator++(); + //! post-increment + _const_fwd_iterator operator++( int ); + + //! pre-decrement + _const_fwd_iterator& operator--(); + //! post-decrement + _const_fwd_iterator operator--( int ); + + //! addition operator + _const_fwd_iterator operator+( difference_type n ); + //! subtraction operator + _const_fwd_iterator operator-( difference_type n ); + + //! addition assignment operator + _const_fwd_iterator& operator+=( difference_type n ); + //! subtraction assignment operator + _const_fwd_iterator& operator-=( difference_type n ); + + //! dereference operator + const value_type& operator*() const; + + //! dereference at offset operator + const value_type& operator[]( difference_type n ) const; + + //! advances to the next Unicode character, honoring surrogate pairs in the UTF-16 stream + _const_fwd_iterator& moveNext(); + //! rewinds to the previous Unicode character, honoring surrogate pairs in the UTF-16 stream + _const_fwd_iterator& movePrev(); + //! Returns the Unicode value of the character at the current position (decodes surrogate pairs if needed) + unicode_char getCharacter() const; + + //! difference operator + friend size_type operator-( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); + //! equality operator + friend bool operator==( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); + //! inequality operator + friend bool operator!=( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); + //! less than + friend bool operator<( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); + //! less than or equal + friend bool operator<=( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); + //! greater than + friend bool operator>( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); + //! greater than or equal + friend bool operator>=( const _const_fwd_iterator& left, const _const_fwd_iterator& right ); + + }; + + //######################################################################### + // REVERSE ITERATORS + //######################################################################### + class _const_rev_iterator; // forward declaration + //! forward iterator for UTFString + class _OgreExport _rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */ + friend class _const_rev_iterator; + public: + _rev_iterator(); + _rev_iterator( const _rev_iterator& i ); + + //! pre-increment + _rev_iterator& operator++(); + //! post-increment + _rev_iterator operator++( int ); + + //! pre-decrement + _rev_iterator& operator--(); + //! post-decrement + _rev_iterator operator--( int ); + + //! addition operator + _rev_iterator operator+( difference_type n ); + //! subtraction operator + _rev_iterator operator-( difference_type n ); + + //! addition assignment operator + _rev_iterator& operator+=( difference_type n ); + //! subtraction assignment operator + _rev_iterator& operator-=( difference_type n ); + + //! dereference operator + value_type& operator*() const; + + //! dereference at offset operator + value_type& operator[]( difference_type n ) const; + }; + //######################################################################### + //! const reverse iterator for UTFString + class _OgreExport _const_rev_iterator: public _base_iterator { /* i don't know why the beautifier is freaking out on this line */ + public: + _const_rev_iterator(); + _const_rev_iterator( const _const_rev_iterator& i ); + _const_rev_iterator( const _rev_iterator& i ); + //! pre-increment + _const_rev_iterator& operator++(); + //! post-increment + _const_rev_iterator operator++( int ); + + //! pre-decrement + _const_rev_iterator& operator--(); + //! post-decrement + _const_rev_iterator operator--( int ); + + //! addition operator + _const_rev_iterator operator+( difference_type n ); + //! subtraction operator + _const_rev_iterator operator-( difference_type n ); + + //! addition assignment operator + _const_rev_iterator& operator+=( difference_type n ); + //! subtraction assignment operator + _const_rev_iterator& operator-=( difference_type n ); + + //! dereference operator + const value_type& operator*() const; + + //! dereference at offset operator + const value_type& operator[]( difference_type n ) const; + + //! difference operator + friend size_type operator-( const _const_rev_iterator& left, const _const_rev_iterator& right ); + //! equality operator + friend bool operator==( const _const_rev_iterator& left, const _const_rev_iterator& right ); + //! inequality operator + friend bool operator!=( const _const_rev_iterator& left, const _const_rev_iterator& right ); + //! less than + friend bool operator<( const _const_rev_iterator& left, const _const_rev_iterator& right ); + //! less than or equal + friend bool operator<=( const _const_rev_iterator& left, const _const_rev_iterator& right ); + //! greater than + friend bool operator>( const _const_rev_iterator& left, const _const_rev_iterator& right ); + //! greater than or equal + friend bool operator>=( const _const_rev_iterator& left, const _const_rev_iterator& right ); + }; + //######################################################################### + + typedef _fwd_iterator iterator; //!< iterator + typedef _rev_iterator reverse_iterator; //!< reverse iterator + typedef _const_fwd_iterator const_iterator; //!< const iterator + typedef _const_rev_iterator const_reverse_iterator; //!< const reverse iterator + + + //!\name Constructors/Destructor + //@{ + //! default constructor, creates an empty string + UTFString(); + //! copy constructor + UTFString( const UTFString& copy ); + //! \a length copies of \a ch + UTFString( size_type length, const code_point& ch ); + //! duplicate of nul-terminated sequence \a str + UTFString( const code_point* str ); + //! duplicate of \a str, \a length code points long + UTFString( const code_point* str, size_type length ); + //! substring of \a str starting at \a index and \a length code points long + UTFString( const UTFString& str, size_type index, size_type length ); #if OGRE_IS_NATIVE_WCHAR_T - //! duplicate of nul-terminated \c wchar_t array - UTFString( const wchar_t* w_str ); - //! duplicate of \a w_str, \a length characters long - UTFString( const wchar_t* w_str, size_type length ); + //! duplicate of nul-terminated \c wchar_t array + UTFString( const wchar_t* w_str ); + //! duplicate of \a w_str, \a length characters long + UTFString( const wchar_t* w_str, size_type length ); #endif - //! duplicate of \a wstr - UTFString( const std::wstring& wstr ); - //! duplicate of nul-terminated C-string \a c_str (UTF-8 encoding) - UTFString( const char* c_str ); - //! duplicate of \a c_str, \a length characters long (UTF-8 encoding) - UTFString( const char* c_str, size_type length ); - //! duplicate of \a str (UTF-8 encoding) - UTFString( const std::string& str ); + //! duplicate of \a wstr + UTFString( const std::wstring& wstr ); + //! duplicate of nul-terminated C-string \a c_str (UTF-8 encoding) + UTFString( const char* c_str ); + //! duplicate of \a c_str, \a length characters long (UTF-8 encoding) + UTFString( const char* c_str, size_type length ); + //! duplicate of \a str (UTF-8 encoding) + UTFString( const std::string& str ); #if OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR - UTFString( const Ogre::String& str ); + UTFString( const Ogre::String& str ); #endif - //! destructor - ~UTFString(); - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name Utility functions - //@{ - //! Returns the number of code points in the current string - size_type size() const; - //! Returns the number of code points in the current string - size_type length() const; - //! Returns the number of Unicode characters in the string - /*! Executes in linear time. */ - size_type length_Characters() const; - //! returns the maximum number of UTF-16 code points that the string can hold - size_type max_size() const; - //! sets the capacity of the string to at least \a size code points - void reserve( size_type size ); - //! changes the size of the string to \a size, filling in any new area with \a val - void resize( size_type num, const code_point& val = 0 ); - //! exchanges the elements of the current string with those of \a from - void swap( UTFString& from ); - //! returns \c true if the string has no elements, \c false otherwise - bool empty() const; - //! returns a pointer to the first character in the current string - const code_point* c_str() const; - //! returns a pointer to the first character in the current string - const code_point* data() const; - //! returns the number of elements that the string can hold before it will need to allocate more space - size_type capacity() const; - //! deletes all of the elements in the string - void clear(); - //! returns a substring of the current string, starting at \a index, and \a num characters long. - /*! If \a num is omitted, it will default to \c UTFString::npos, and the substr() function will simply return the remainder of the string starting at \a index. */ - UTFString substr( size_type index, size_type num = npos ) const; - //! appends \a val to the end of the string - void push_back( unicode_char val ); + //! destructor + ~UTFString(); + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name Utility functions + //@{ + //! Returns the number of code points in the current string + size_type size() const; + //! Returns the number of code points in the current string + size_type length() const; + //! Returns the number of Unicode characters in the string + /*! Executes in linear time. */ + size_type length_Characters() const; + //! returns the maximum number of UTF-16 code points that the string can hold + size_type max_size() const; + //! sets the capacity of the string to at least \a size code points + void reserve( size_type size ); + //! changes the size of the string to \a size, filling in any new area with \a val + void resize( size_type num, const code_point& val = 0 ); + //! exchanges the elements of the current string with those of \a from + void swap( UTFString& from ); + //! returns \c true if the string has no elements, \c false otherwise + bool empty() const; + //! returns a pointer to the first character in the current string + const code_point* c_str() const; + //! returns a pointer to the first character in the current string + const code_point* data() const; + //! returns the number of elements that the string can hold before it will need to allocate more space + size_type capacity() const; + //! deletes all of the elements in the string + void clear(); + //! returns a substring of the current string, starting at \a index, and \a num characters long. + /*! If \a num is omitted, it will default to \c UTFString::npos, and the substr() function will simply return the remainder of the string starting at \a index. */ + UTFString substr( size_type index, size_type num = npos ) const; + //! appends \a val to the end of the string + void push_back( unicode_char val ); #if OGRE_IS_NATIVE_WCHAR_T - //! appends \a val to the end of the string - void push_back( wchar_t val ); + //! appends \a val to the end of the string + void push_back( wchar_t val ); #endif - //! appends \a val to the end of the string - /*! This can be used to push surrogate pair code points, you'll just need to push them - one after the other. */ - void push_back( code_point val ); - //! appends \a val to the end of the string - /*! Limited to characters under the 127 value barrier. */ - void push_back( char val ); - //! returns \c true if the given Unicode character \a ch is in this string - bool inString( unicode_char ch ) const; - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name Stream variations - //@{ - //! returns the current string in UTF-8 form within a std::string - const std::string& asUTF8() const; - //! returns the current string in UTF-8 form as a nul-terminated char array - const char* asUTF8_c_str() const; - //! returns the current string in UTF-32 form within a utf32string - const utf32string& asUTF32() const; - //! returns the current string in UTF-32 form as a nul-terminated unicode_char array - const unicode_char* asUTF32_c_str() const; - //! returns the current string in the native form of std::wstring - const std::wstring& asWStr() const; - //! returns the current string in the native form of a nul-terminated wchar_t array - const wchar_t* asWStr_c_str() const; - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name Single Character Access - //@{ - //! returns a reference to the element in the string at index \c loc - code_point& at( size_type loc ); - //! returns a reference to the element in the string at index \c loc - const code_point& at( size_type loc ) const; - //! returns the data point \a loc evaluated as a UTF-32 value - /*! This function will will only properly decode surrogate pairs when \a loc points to the index - of a lead code point that is followed by a trailing code point. Evaluating the trailing code point - itself, or pointing to a code point that is a sentinel value (part of a broken pair) will return - the value of just that code point (not a valid Unicode value, but useful as a sentinel value). */ - unicode_char getChar( size_type loc ) const; - //! sets the value of the character at \a loc to the Unicode value \a ch (UTF-32) - /*! Providing sentinel values (values between U+D800-U+DFFF) are accepted, but you should be aware - that you can also unwittingly create a valid surrogate pair if you don't pay attention to what you - are doing. @note This operation may also lengthen the string if a surrogate pair is needed to - represent the value given, but one is not available to replace; or alternatively shorten the string - if an existing surrogate pair is replaced with a character that is representable without a surrogate - pair. The return value will signify any lengthening or shortening performed, returning 0 if no change - was made, -1 if the string was shortened, or 1 if the string was lengthened. Any single call can - only change the string length by + or - 1. */ - int setChar( size_type loc, unicode_char ch ); - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name iterator acquisition - //@{ - //! returns an iterator to the first element of the string - iterator begin(); - //! returns an iterator to the first element of the string - const_iterator begin() const; - //! returns an iterator just past the end of the string - iterator end(); - //! returns an iterator just past the end of the string - const_iterator end() const; - //! returns a reverse iterator to the last element of the string - reverse_iterator rbegin(); - //! returns a reverse iterator to the last element of the string - const_reverse_iterator rbegin() const; - //! returns a reverse iterator just past the beginning of the string - reverse_iterator rend(); - //! returns a reverse iterator just past the beginning of the string - const_reverse_iterator rend() const; - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name assign - //@{ - //! gives the current string the values from \a start to \a end - UTFString& assign( iterator start, iterator end ); - //! assign \a str to the current string - UTFString& assign( const UTFString& str ); - //! assign the nul-terminated \a str to the current string - UTFString& assign( const code_point* str ); - //! assign the first \a num characters of \a str to the current string - UTFString& assign( const code_point* str, size_type num ); - //! assign \a len entries from \a str to the current string, starting at \a index - UTFString& assign( const UTFString& str, size_type index, size_type len ); - //! assign \a num copies of \a ch to the current string - UTFString& assign( size_type num, const code_point& ch ); - //! assign \a wstr to the current string (\a wstr is treated as a UTF-16 stream) - UTFString& assign( const std::wstring& wstr ); + //! appends \a val to the end of the string + /*! This can be used to push surrogate pair code points, you'll just need to push them + one after the other. */ + void push_back( code_point val ); + //! appends \a val to the end of the string + /*! Limited to characters under the 127 value barrier. */ + void push_back( char val ); + //! returns \c true if the given Unicode character \a ch is in this string + bool inString( unicode_char ch ) const; + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name Stream variations + //@{ + //! returns the current string in UTF-8 form within a std::string + const std::string& asUTF8() const; + //! returns the current string in UTF-8 form as a nul-terminated char array + const char* asUTF8_c_str() const; + //! returns the current string in UTF-32 form within a utf32string + const utf32string& asUTF32() const; + //! returns the current string in UTF-32 form as a nul-terminated unicode_char array + const unicode_char* asUTF32_c_str() const; + //! returns the current string in the native form of std::wstring + const std::wstring& asWStr() const; + //! returns the current string in the native form of a nul-terminated wchar_t array + const wchar_t* asWStr_c_str() const; + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name Single Character Access + //@{ + //! returns a reference to the element in the string at index \c loc + code_point& at( size_type loc ); + //! returns a reference to the element in the string at index \c loc + const code_point& at( size_type loc ) const; + //! returns the data point \a loc evaluated as a UTF-32 value + /*! This function will will only properly decode surrogate pairs when \a loc points to the index + of a lead code point that is followed by a trailing code point. Evaluating the trailing code point + itself, or pointing to a code point that is a sentinel value (part of a broken pair) will return + the value of just that code point (not a valid Unicode value, but useful as a sentinel value). */ + unicode_char getChar( size_type loc ) const; + //! sets the value of the character at \a loc to the Unicode value \a ch (UTF-32) + /*! Providing sentinel values (values between U+D800-U+DFFF) are accepted, but you should be aware + that you can also unwittingly create a valid surrogate pair if you don't pay attention to what you + are doing. @note This operation may also lengthen the string if a surrogate pair is needed to + represent the value given, but one is not available to replace; or alternatively shorten the string + if an existing surrogate pair is replaced with a character that is representable without a surrogate + pair. The return value will signify any lengthening or shortening performed, returning 0 if no change + was made, -1 if the string was shortened, or 1 if the string was lengthened. Any single call can + only change the string length by + or - 1. */ + int setChar( size_type loc, unicode_char ch ); + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name iterator acquisition + //@{ + //! returns an iterator to the first element of the string + iterator begin(); + //! returns an iterator to the first element of the string + const_iterator begin() const; + //! returns an iterator just past the end of the string + iterator end(); + //! returns an iterator just past the end of the string + const_iterator end() const; + //! returns a reverse iterator to the last element of the string + reverse_iterator rbegin(); + //! returns a reverse iterator to the last element of the string + const_reverse_iterator rbegin() const; + //! returns a reverse iterator just past the beginning of the string + reverse_iterator rend(); + //! returns a reverse iterator just past the beginning of the string + const_reverse_iterator rend() const; + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name assign + //@{ + //! gives the current string the values from \a start to \a end + UTFString& assign( iterator start, iterator end ); + //! assign \a str to the current string + UTFString& assign( const UTFString& str ); + //! assign the nul-terminated \a str to the current string + UTFString& assign( const code_point* str ); + //! assign the first \a num characters of \a str to the current string + UTFString& assign( const code_point* str, size_type num ); + //! assign \a len entries from \a str to the current string, starting at \a index + UTFString& assign( const UTFString& str, size_type index, size_type len ); + //! assign \a num copies of \a ch to the current string + UTFString& assign( size_type num, const code_point& ch ); + //! assign \a wstr to the current string (\a wstr is treated as a UTF-16 stream) + UTFString& assign( const std::wstring& wstr ); #if OGRE_IS_NATIVE_WCHAR_T - //! assign \a w_str to the current string - UTFString& assign( const wchar_t* w_str ); - //! assign the first \a num characters of \a w_str to the current string - UTFString& assign( const wchar_t* w_str, size_type num ); + //! assign \a w_str to the current string + UTFString& assign( const wchar_t* w_str ); + //! assign the first \a num characters of \a w_str to the current string + UTFString& assign( const wchar_t* w_str, size_type num ); #endif - //! assign \a str to the current string (\a str is treated as a UTF-8 stream) - UTFString& assign( const std::string& str ); - //! assign \a c_str to the current string (\a c_str is treated as a UTF-8 stream) - UTFString& assign( const char* c_str ); - //! assign the first \a num characters of \a c_str to the current string (\a c_str is treated as a UTF-8 stream) - UTFString& assign( const char* c_str, size_type num ); - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name append - //@{ - //! appends \a str on to the end of the current string - UTFString& append( const UTFString& str ); - //! appends \a str on to the end of the current string - UTFString& append( const code_point* str ); - //! appends a substring of \a str starting at \a index that is \a len characters long on to the end of the current string - UTFString& append( const UTFString& str, size_type index, size_type len ); - //! appends \a num characters of \a str on to the end of the current string - UTFString& append( const code_point* str, size_type num ); - //! appends \a num repetitions of \a ch on to the end of the current string - UTFString& append( size_type num, code_point ch ); - //! appends the sequence denoted by \a start and \a end on to the end of the current string - UTFString& append( iterator start, iterator end ); + //! assign \a str to the current string (\a str is treated as a UTF-8 stream) + UTFString& assign( const std::string& str ); + //! assign \a c_str to the current string (\a c_str is treated as a UTF-8 stream) + UTFString& assign( const char* c_str ); + //! assign the first \a num characters of \a c_str to the current string (\a c_str is treated as a UTF-8 stream) + UTFString& assign( const char* c_str, size_type num ); + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name append + //@{ + //! appends \a str on to the end of the current string + UTFString& append( const UTFString& str ); + //! appends \a str on to the end of the current string + UTFString& append( const code_point* str ); + //! appends a substring of \a str starting at \a index that is \a len characters long on to the end of the current string + UTFString& append( const UTFString& str, size_type index, size_type len ); + //! appends \a num characters of \a str on to the end of the current string + UTFString& append( const code_point* str, size_type num ); + //! appends \a num repetitions of \a ch on to the end of the current string + UTFString& append( size_type num, code_point ch ); + //! appends the sequence denoted by \a start and \a end on to the end of the current string + UTFString& append( iterator start, iterator end ); #if OGRE_IS_NATIVE_WCHAR_T - //! appends \a num characters of \a str on to the end of the current string - UTFString& append( const wchar_t* w_str, size_type num ); - //! appends \a num repetitions of \a ch on to the end of the current string - UTFString& append( size_type num, wchar_t ch ); + //! appends \a num characters of \a str on to the end of the current string + UTFString& append( const wchar_t* w_str, size_type num ); + //! appends \a num repetitions of \a ch on to the end of the current string + UTFString& append( size_type num, wchar_t ch ); #endif - //! appends \a num characters of \a str on to the end of the current string (UTF-8 encoding) - UTFString& append( const char* c_str, size_type num ); - //! appends \a num repetitions of \a ch on to the end of the current string (Unicode values less than 128) - UTFString& append( size_type num, char ch ); - //! appends \a num repetitions of \a ch on to the end of the current string (Full Unicode spectrum) - UTFString& append( size_type num, unicode_char ch ); - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name insert - //@{ - //! inserts \a ch before the code point denoted by \a i - iterator insert( iterator i, const code_point& ch ); - //! inserts \a str into the current string, at location \a index - UTFString& insert( size_type index, const UTFString& str ); - //! inserts \a str into the current string, at location \a index - UTFString& insert( size_type index, const code_point* str ) { - mData.insert( index, str ); - return *this; - } - //! inserts a substring of \a str (starting at \a index2 and \a num code points long) into the current string, at location \a index1 - UTFString& insert( size_type index1, const UTFString& str, size_type index2, size_type num ); - //! inserts the code points denoted by \a start and \a end into the current string, before the code point specified by \a i - void insert( iterator i, iterator start, iterator end ); - //! inserts \a num code points of \a str into the current string, at location \a index - UTFString& insert( size_type index, const code_point* str, size_type num ); + //! appends \a num characters of \a str on to the end of the current string (UTF-8 encoding) + UTFString& append( const char* c_str, size_type num ); + //! appends \a num repetitions of \a ch on to the end of the current string (Unicode values less than 128) + UTFString& append( size_type num, char ch ); + //! appends \a num repetitions of \a ch on to the end of the current string (Full Unicode spectrum) + UTFString& append( size_type num, unicode_char ch ); + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name insert + //@{ + //! inserts \a ch before the code point denoted by \a i + iterator insert( iterator i, const code_point& ch ); + //! inserts \a str into the current string, at location \a index + UTFString& insert( size_type index, const UTFString& str ); + //! inserts \a str into the current string, at location \a index + UTFString& insert( size_type index, const code_point* str ) { + mData.insert( index, str ); + return *this; + } + //! inserts a substring of \a str (starting at \a index2 and \a num code points long) into the current string, at location \a index1 + UTFString& insert( size_type index1, const UTFString& str, size_type index2, size_type num ); + //! inserts the code points denoted by \a start and \a end into the current string, before the code point specified by \a i + void insert( iterator i, iterator start, iterator end ); + //! inserts \a num code points of \a str into the current string, at location \a index + UTFString& insert( size_type index, const code_point* str, size_type num ); #if OGRE_IS_NATIVE_WCHAR_T - //! inserts \a num code points of \a str into the current string, at location \a index - UTFString& insert( size_type index, const wchar_t* w_str, size_type num ); + //! inserts \a num code points of \a str into the current string, at location \a index + UTFString& insert( size_type index, const wchar_t* w_str, size_type num ); #endif - //! inserts \a num code points of \a str into the current string, at location \a index - UTFString& insert( size_type index, const char* c_str, size_type num ); - //! inserts \a num copies of \a ch into the current string, at location \a index - UTFString& insert( size_type index, size_type num, code_point ch ); + //! inserts \a num code points of \a str into the current string, at location \a index + UTFString& insert( size_type index, const char* c_str, size_type num ); + //! inserts \a num copies of \a ch into the current string, at location \a index + UTFString& insert( size_type index, size_type num, code_point ch ); #if OGRE_IS_NATIVE_WCHAR_T - //! inserts \a num copies of \a ch into the current string, at location \a index - UTFString& insert( size_type index, size_type num, wchar_t ch ); + //! inserts \a num copies of \a ch into the current string, at location \a index + UTFString& insert( size_type index, size_type num, wchar_t ch ); #endif - //! inserts \a num copies of \a ch into the current string, at location \a index - UTFString& insert( size_type index, size_type num, char ch ); - //! inserts \a num copies of \a ch into the current string, at location \a index - UTFString& insert( size_type index, size_type num, unicode_char ch ); - //! inserts \a num copies of \a ch into the current string, before the code point denoted by \a i - void insert( iterator i, size_type num, const code_point& ch ); + //! inserts \a num copies of \a ch into the current string, at location \a index + UTFString& insert( size_type index, size_type num, char ch ); + //! inserts \a num copies of \a ch into the current string, at location \a index + UTFString& insert( size_type index, size_type num, unicode_char ch ); + //! inserts \a num copies of \a ch into the current string, before the code point denoted by \a i + void insert( iterator i, size_type num, const code_point& ch ); #if OGRE_IS_NATIVE_WCHAR_T - //! inserts \a num copies of \a ch into the current string, before the code point denoted by \a i - void insert( iterator i, size_type num, const wchar_t& ch ); + //! inserts \a num copies of \a ch into the current string, before the code point denoted by \a i + void insert( iterator i, size_type num, const wchar_t& ch ); #endif - //! inserts \a num copies of \a ch into the current string, before the code point denoted by \a i - void insert( iterator i, size_type num, const char& ch ); - //! inserts \a num copies of \a ch into the current string, before the code point denoted by \a i - void insert( iterator i, size_type num, const unicode_char& ch ); - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name erase - //@{ - //! removes the code point pointed to by \a loc, returning an iterator to the next character - iterator erase( iterator loc ); - //! removes the code points between \a start and \a end (including the one at \a start but not the one at \a end), returning an iterator to the code point after the last code point removed - iterator erase( iterator start, iterator end ); - //! removes \a num code points from the current string, starting at \a index - UTFString& erase( size_type index = 0, size_type num = npos ); - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name replace - //@{ - //! replaces up to \a num1 code points of the current string (starting at \a index1) with \a str - UTFString& replace( size_type index1, size_type num1, const UTFString& str ); - //! replaces up to \a num1 code points of the current string (starting at \a index1) with up to \a num2 code points from \a str - UTFString& replace( size_type index1, size_type num1, const UTFString& str, size_type num2 ); - //! replaces up to \a num1 code points of the current string (starting at \a index1) with up to \a num2 code points from \a str beginning at \a index2 - UTFString& replace( size_type index1, size_type num1, const UTFString& str, size_type index2, size_type num2 ); - //! replaces code points in the current string from \a start to \a end with \a num code points from \a str - UTFString& replace( iterator start, iterator end, const UTFString& str, size_type num = npos ); - //! replaces up to \a num1 code points in the current string (beginning at \a index) with \c num2 copies of \c ch - UTFString& replace( size_type index, size_type num1, size_type num2, code_point ch ); - //! replaces the code points in the current string from \a start to \a end with \a num copies of \a ch - UTFString& replace( iterator start, iterator end, size_type num, code_point ch ); - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name compare - //@{ - //! compare \a str to the current string - int compare( const UTFString& str ) const; - //! compare \a str to the current string - int compare( const code_point* str ) const; - //! compare \a str to a substring of the current string, starting at \a index for \a length characters - int compare( size_type index, size_type length, const UTFString& str ) const; - //! compare a substring of \a str to a substring of the current string, where \a index2 and \a length2 refer to \a str and \a index and \a length refer to the current string - int compare( size_type index, size_type length, const UTFString& str, size_type index2, size_type length2 ) const; - //! compare a substring of \a str to a substring of the current string, where the substring of \a str begins at zero and is \a length2 characters long, and the substring of the current string begins at \a index and is \a length characters long - int compare( size_type index, size_type length, const code_point* str, size_type length2 ) const; + //! inserts \a num copies of \a ch into the current string, before the code point denoted by \a i + void insert( iterator i, size_type num, const char& ch ); + //! inserts \a num copies of \a ch into the current string, before the code point denoted by \a i + void insert( iterator i, size_type num, const unicode_char& ch ); + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name erase + //@{ + //! removes the code point pointed to by \a loc, returning an iterator to the next character + iterator erase( iterator loc ); + //! removes the code points between \a start and \a end (including the one at \a start but not the one at \a end), returning an iterator to the code point after the last code point removed + iterator erase( iterator start, iterator end ); + //! removes \a num code points from the current string, starting at \a index + UTFString& erase( size_type index = 0, size_type num = npos ); + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name replace + //@{ + //! replaces up to \a num1 code points of the current string (starting at \a index1) with \a str + UTFString& replace( size_type index1, size_type num1, const UTFString& str ); + //! replaces up to \a num1 code points of the current string (starting at \a index1) with up to \a num2 code points from \a str + UTFString& replace( size_type index1, size_type num1, const UTFString& str, size_type num2 ); + //! replaces up to \a num1 code points of the current string (starting at \a index1) with up to \a num2 code points from \a str beginning at \a index2 + UTFString& replace( size_type index1, size_type num1, const UTFString& str, size_type index2, size_type num2 ); + //! replaces code points in the current string from \a start to \a end with \a num code points from \a str + UTFString& replace( iterator start, iterator end, const UTFString& str, size_type num = npos ); + //! replaces up to \a num1 code points in the current string (beginning at \a index) with \c num2 copies of \c ch + UTFString& replace( size_type index, size_type num1, size_type num2, code_point ch ); + //! replaces the code points in the current string from \a start to \a end with \a num copies of \a ch + UTFString& replace( iterator start, iterator end, size_type num, code_point ch ); + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name compare + //@{ + //! compare \a str to the current string + int compare( const UTFString& str ) const; + //! compare \a str to the current string + int compare( const code_point* str ) const; + //! compare \a str to a substring of the current string, starting at \a index for \a length characters + int compare( size_type index, size_type length, const UTFString& str ) const; + //! compare a substring of \a str to a substring of the current string, where \a index2 and \a length2 refer to \a str and \a index and \a length refer to the current string + int compare( size_type index, size_type length, const UTFString& str, size_type index2, size_type length2 ) const; + //! compare a substring of \a str to a substring of the current string, where the substring of \a str begins at zero and is \a length2 characters long, and the substring of the current string begins at \a index and is \a length characters long + int compare( size_type index, size_type length, const code_point* str, size_type length2 ) const; #if OGRE_IS_NATIVE_WCHAR_T - //! compare a substring of \a str to a substring of the current string, where the substring of \a str begins at zero and is \a length2 elements long, and the substring of the current string begins at \a index and is \a length characters long - int compare( size_type index, size_type length, const wchar_t* w_str, size_type length2 ) const; + //! compare a substring of \a str to a substring of the current string, where the substring of \a str begins at zero and is \a length2 elements long, and the substring of the current string begins at \a index and is \a length characters long + int compare( size_type index, size_type length, const wchar_t* w_str, size_type length2 ) const; #endif - //! compare a substring of \a str to a substring of the current string, where the substring of \a str begins at zero and is \a length2 UTF-8 code points long, and the substring of the current string begins at \a index and is \a length characters long - int compare( size_type index, size_type length, const char* c_str, size_type length2 ) const; - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name find & rfind - //@{ - //! returns the index of the first occurrence of \a str within the current string, starting at \a index; returns \c UTFString::npos if nothing is found - /*! \a str is a UTF-16 encoded string, but through implicit casting can also be a UTF-8 encoded string (const char* or std::string) */ - size_type find( const UTFString& str, size_type index = 0 ) const; - //! returns the index of the first occurrence of \a str within the current string and within \a length code points, starting at \a index; returns \c UTFString::npos if nothing is found - /*! \a cp_str is a UTF-16 encoded string */ - size_type find( const code_point* cp_str, size_type index, size_type length ) const; - //! returns the index of the first occurrence of \a str within the current string and within \a length code points, starting at \a index; returns \c UTFString::npos if nothing is found - /*! \a cp_str is a UTF-8 encoded string */ - size_type find( const char* c_str, size_type index, size_type length ) const; + //! compare a substring of \a str to a substring of the current string, where the substring of \a str begins at zero and is \a length2 UTF-8 code points long, and the substring of the current string begins at \a index and is \a length characters long + int compare( size_type index, size_type length, const char* c_str, size_type length2 ) const; + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name find & rfind + //@{ + //! returns the index of the first occurrence of \a str within the current string, starting at \a index; returns \c UTFString::npos if nothing is found + /*! \a str is a UTF-16 encoded string, but through implicit casting can also be a UTF-8 encoded string (const char* or std::string) */ + size_type find( const UTFString& str, size_type index = 0 ) const; + //! returns the index of the first occurrence of \a str within the current string and within \a length code points, starting at \a index; returns \c UTFString::npos if nothing is found + /*! \a cp_str is a UTF-16 encoded string */ + size_type find( const code_point* cp_str, size_type index, size_type length ) const; + //! returns the index of the first occurrence of \a str within the current string and within \a length code points, starting at \a index; returns \c UTFString::npos if nothing is found + /*! \a cp_str is a UTF-8 encoded string */ + size_type find( const char* c_str, size_type index, size_type length ) const; #if OGRE_IS_NATIVE_WCHAR_T - //! returns the index of the first occurrence of \a str within the current string and within \a length code points, starting at \a index; returns \c UTFString::npos if nothing is found - /*! \a cp_str is a UTF-16 encoded string */ - size_type find( const wchar_t* w_str, size_type index, size_type length ) const; + //! returns the index of the first occurrence of \a str within the current string and within \a length code points, starting at \a index; returns \c UTFString::npos if nothing is found + /*! \a cp_str is a UTF-16 encoded string */ + size_type find( const wchar_t* w_str, size_type index, size_type length ) const; #endif - //! returns the index of the first occurrence \a ch within the current string, starting at \a index; returns \c UTFString::npos if nothing is found - /*! \a ch is only capable of representing Unicode values up to U+007F (127) */ - size_type find( char ch, size_type index = 0 ) const; - //! returns the index of the first occurrence \a ch within the current string, starting at \a index; returns \c UTFString::npos if nothing is found - /*! \a ch is only capable of representing Unicode values up to U+FFFF (65535) */ - size_type find( code_point ch, size_type index = 0 ) const; + //! returns the index of the first occurrence \a ch within the current string, starting at \a index; returns \c UTFString::npos if nothing is found + /*! \a ch is only capable of representing Unicode values up to U+007F (127) */ + size_type find( char ch, size_type index = 0 ) const; + //! returns the index of the first occurrence \a ch within the current string, starting at \a index; returns \c UTFString::npos if nothing is found + /*! \a ch is only capable of representing Unicode values up to U+FFFF (65535) */ + size_type find( code_point ch, size_type index = 0 ) const; #if OGRE_IS_NATIVE_WCHAR_T - //! returns the index of the first occurrence \a ch within the current string, starting at \a index; returns \c UTFString::npos if nothing is found - /*! \a ch is only capable of representing Unicode values up to U+FFFF (65535) */ - size_type find( wchar_t ch, size_type index = 0 ) const; + //! returns the index of the first occurrence \a ch within the current string, starting at \a index; returns \c UTFString::npos if nothing is found + /*! \a ch is only capable of representing Unicode values up to U+FFFF (65535) */ + size_type find( wchar_t ch, size_type index = 0 ) const; #endif - //! returns the index of the first occurrence \a ch within the current string, starting at \a index; returns \c UTFString::npos if nothing is found - /*! \a ch can fully represent any Unicode character */ - size_type find( unicode_char ch, size_type index = 0 ) const; - - //! returns the location of the first occurrence of \a str in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type rfind( const UTFString& str, size_type index = 0 ) const; - //! returns the location of the first occurrence of \a str in the current string, doing a reverse search from \a index, searching at most \a num characters; returns \c UTFString::npos if nothing is found - size_type rfind( const code_point* cp_str, size_type index, size_type num ) const; - //! returns the location of the first occurrence of \a str in the current string, doing a reverse search from \a index, searching at most \a num characters; returns \c UTFString::npos if nothing is found - size_type rfind( const char* c_str, size_type index, size_type num ) const; + //! returns the index of the first occurrence \a ch within the current string, starting at \a index; returns \c UTFString::npos if nothing is found + /*! \a ch can fully represent any Unicode character */ + size_type find( unicode_char ch, size_type index = 0 ) const; + + //! returns the location of the first occurrence of \a str in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type rfind( const UTFString& str, size_type index = 0 ) const; + //! returns the location of the first occurrence of \a str in the current string, doing a reverse search from \a index, searching at most \a num characters; returns \c UTFString::npos if nothing is found + size_type rfind( const code_point* cp_str, size_type index, size_type num ) const; + //! returns the location of the first occurrence of \a str in the current string, doing a reverse search from \a index, searching at most \a num characters; returns \c UTFString::npos if nothing is found + size_type rfind( const char* c_str, size_type index, size_type num ) const; #if OGRE_IS_NATIVE_WCHAR_T - //! returns the location of the first occurrence of \a str in the current string, doing a reverse search from \a index, searching at most \a num characters; returns \c UTFString::npos if nothing is found - size_type rfind( const wchar_t* w_str, size_type index, size_type num ) const; + //! returns the location of the first occurrence of \a str in the current string, doing a reverse search from \a index, searching at most \a num characters; returns \c UTFString::npos if nothing is found + size_type rfind( const wchar_t* w_str, size_type index, size_type num ) const; #endif - //! returns the location of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type rfind( char ch, size_type index = 0 ) const; - //! returns the location of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type rfind( code_point ch, size_type index ) const; + //! returns the location of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type rfind( char ch, size_type index = 0 ) const; + //! returns the location of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type rfind( code_point ch, size_type index ) const; #if OGRE_IS_NATIVE_WCHAR_T - //! returns the location of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type rfind( wchar_t ch, size_type index = 0 ) const; + //! returns the location of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type rfind( wchar_t ch, size_type index = 0 ) const; #endif - //! returns the location of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type rfind( unicode_char ch, size_type index = 0 ) const; - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name find_first/last_(not)_of - //@{ - //! Returns the index of the first character within the current string that matches \b any character in \a str, beginning the search at \a index and searching at most \a num characters; returns \c UTFString::npos if nothing is found - size_type find_first_of( const UTFString &str, size_type index = 0, size_type num = npos ) const; - //! returns the index of the first occurrence of \a ch in the current string, starting the search at \a index; returns \c UTFString::npos if nothing is found - size_type find_first_of( code_point ch, size_type index = 0 ) const; - //! returns the index of the first occurrence of \a ch in the current string, starting the search at \a index; returns \c UTFString::npos if nothing is found - size_type find_first_of( char ch, size_type index = 0 ) const; + //! returns the location of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type rfind( unicode_char ch, size_type index = 0 ) const; + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name find_first/last_(not)_of + //@{ + //! Returns the index of the first character within the current string that matches \b any character in \a str, beginning the search at \a index and searching at most \a num characters; returns \c UTFString::npos if nothing is found + size_type find_first_of( const UTFString &str, size_type index = 0, size_type num = npos ) const; + //! returns the index of the first occurrence of \a ch in the current string, starting the search at \a index; returns \c UTFString::npos if nothing is found + size_type find_first_of( code_point ch, size_type index = 0 ) const; + //! returns the index of the first occurrence of \a ch in the current string, starting the search at \a index; returns \c UTFString::npos if nothing is found + size_type find_first_of( char ch, size_type index = 0 ) const; #if OGRE_IS_NATIVE_WCHAR_T - //! returns the index of the first occurrence of \a ch in the current string, starting the search at \a index; returns \c UTFString::npos if nothing is found - size_type find_first_of( wchar_t ch, size_type index = 0 ) const; + //! returns the index of the first occurrence of \a ch in the current string, starting the search at \a index; returns \c UTFString::npos if nothing is found + size_type find_first_of( wchar_t ch, size_type index = 0 ) const; #endif - //! returns the index of the first occurrence of \a ch in the current string, starting the search at \a index; returns \c UTFString::npos if nothing is found - size_type find_first_of( unicode_char ch, size_type index = 0 ) const; - - //! returns the index of the first character within the current string that does not match any character in \a str, beginning the search at \a index and searching at most \a num characters; returns \c UTFString::npos if nothing is found - size_type find_first_not_of( const UTFString& str, size_type index = 0, size_type num = npos ) const; - //! returns the index of the first character within the current string that does not match \a ch, starting the search at \a index; returns \c UTFString::npos if nothing is found - size_type find_first_not_of( code_point ch, size_type index = 0 ) const; - //! returns the index of the first character within the current string that does not match \a ch, starting the search at \a index; returns \c UTFString::npos if nothing is found - size_type find_first_not_of( char ch, size_type index = 0 ) const; + //! returns the index of the first occurrence of \a ch in the current string, starting the search at \a index; returns \c UTFString::npos if nothing is found + size_type find_first_of( unicode_char ch, size_type index = 0 ) const; + + //! returns the index of the first character within the current string that does not match any character in \a str, beginning the search at \a index and searching at most \a num characters; returns \c UTFString::npos if nothing is found + size_type find_first_not_of( const UTFString& str, size_type index = 0, size_type num = npos ) const; + //! returns the index of the first character within the current string that does not match \a ch, starting the search at \a index; returns \c UTFString::npos if nothing is found + size_type find_first_not_of( code_point ch, size_type index = 0 ) const; + //! returns the index of the first character within the current string that does not match \a ch, starting the search at \a index; returns \c UTFString::npos if nothing is found + size_type find_first_not_of( char ch, size_type index = 0 ) const; #if OGRE_IS_NATIVE_WCHAR_T - //! returns the index of the first character within the current string that does not match \a ch, starting the search at \a index; returns \c UTFString::npos if nothing is found - size_type find_first_not_of( wchar_t ch, size_type index = 0 ) const; + //! returns the index of the first character within the current string that does not match \a ch, starting the search at \a index; returns \c UTFString::npos if nothing is found + size_type find_first_not_of( wchar_t ch, size_type index = 0 ) const; #endif - //! returns the index of the first character within the current string that does not match \a ch, starting the search at \a index; returns \c UTFString::npos if nothing is found - size_type find_first_not_of( unicode_char ch, size_type index = 0 ) const; - - //! returns the index of the first character within the current string that matches any character in \a str, doing a reverse search from \a index and searching at most \a num characters; returns \c UTFString::npos if nothing is found - size_type find_last_of( const UTFString& str, size_type index = npos, size_type num = npos ) const; - //! returns the index of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type find_last_of( code_point ch, size_type index = npos ) const; - //! returns the index of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type find_last_of( char ch, size_type index = npos ) const { - return find_last_of( static_cast( ch ), index ); - } + //! returns the index of the first character within the current string that does not match \a ch, starting the search at \a index; returns \c UTFString::npos if nothing is found + size_type find_first_not_of( unicode_char ch, size_type index = 0 ) const; + + //! returns the index of the first character within the current string that matches any character in \a str, doing a reverse search from \a index and searching at most \a num characters; returns \c UTFString::npos if nothing is found + size_type find_last_of( const UTFString& str, size_type index = npos, size_type num = npos ) const; + //! returns the index of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type find_last_of( code_point ch, size_type index = npos ) const; + //! returns the index of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type find_last_of( char ch, size_type index = npos ) const { + return find_last_of( static_cast( ch ), index ); + } #if OGRE_IS_NATIVE_WCHAR_T - //! returns the index of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type find_last_of( wchar_t ch, size_type index = npos ) const; + //! returns the index of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type find_last_of( wchar_t ch, size_type index = npos ) const; #endif - //! returns the index of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type find_last_of( unicode_char ch, size_type index = npos ) const; - - //! returns the index of the last character within the current string that does not match any character in \a str, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type find_last_not_of( const UTFString& str, size_type index = npos, size_type num = npos ) const; - //! returns the index of the last occurrence of a character that does not match \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type find_last_not_of( code_point ch, size_type index = npos ) const; - //! returns the index of the last occurrence of a character that does not match \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type find_last_not_of( char ch, size_type index = npos ) const; + //! returns the index of the first occurrence of \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type find_last_of( unicode_char ch, size_type index = npos ) const; + + //! returns the index of the last character within the current string that does not match any character in \a str, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type find_last_not_of( const UTFString& str, size_type index = npos, size_type num = npos ) const; + //! returns the index of the last occurrence of a character that does not match \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type find_last_not_of( code_point ch, size_type index = npos ) const; + //! returns the index of the last occurrence of a character that does not match \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type find_last_not_of( char ch, size_type index = npos ) const; #if OGRE_IS_NATIVE_WCHAR_T - //! returns the index of the last occurrence of a character that does not match \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type find_last_not_of( wchar_t ch, size_type index = npos ) const; + //! returns the index of the last occurrence of a character that does not match \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type find_last_not_of( wchar_t ch, size_type index = npos ) const; #endif - //! returns the index of the last occurrence of a character that does not match \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found - size_type find_last_not_of( unicode_char ch, size_type index = npos ) const; - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name Operators - //@{ - //! less than operator - bool operator<( const UTFString& right ) const; - //! less than or equal operator - bool operator<=( const UTFString& right ) const; - //! greater than operator - bool operator>( const UTFString& right ) const; - //! greater than or equal operator - bool operator>=( const UTFString& right ) const; - //! equality operator - bool operator==( const UTFString& right ) const; - //! inequality operator - bool operator!=( const UTFString& right ) const; - //! assignment operator, implicitly casts all compatible types - UTFString& operator=( const UTFString& s ); - //! assignment operator - UTFString& operator=( code_point ch ); - //! assignment operator - UTFString& operator=( char ch ); + //! returns the index of the last occurrence of a character that does not match \a ch in the current string, doing a reverse search from \a index; returns \c UTFString::npos if nothing is found + size_type find_last_not_of( unicode_char ch, size_type index = npos ) const; + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name Operators + //@{ + //! less than operator + bool operator<( const UTFString& right ) const; + //! less than or equal operator + bool operator<=( const UTFString& right ) const; + //! greater than operator + bool operator>( const UTFString& right ) const; + //! greater than or equal operator + bool operator>=( const UTFString& right ) const; + //! equality operator + bool operator==( const UTFString& right ) const; + //! inequality operator + bool operator!=( const UTFString& right ) const; + //! assignment operator, implicitly casts all compatible types + UTFString& operator=( const UTFString& s ); + //! assignment operator + UTFString& operator=( code_point ch ); + //! assignment operator + UTFString& operator=( char ch ); #if OGRE_IS_NATIVE_WCHAR_T - //! assignment operator - UTFString& operator=( wchar_t ch ); + //! assignment operator + UTFString& operator=( wchar_t ch ); #endif - //! assignment operator - UTFString& operator=( unicode_char ch ); - //! code point dereference operator - code_point& operator[]( size_type index ); - //! code point dereference operator - const code_point& operator[]( size_type index ) const; - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name Implicit Cast Operators - //@{ - //! implicit cast to std::string - operator std::string() const; - //! implicit cast to std::wstring - operator std::wstring() const; + //! assignment operator + UTFString& operator=( unicode_char ch ); + //! code point dereference operator + code_point& operator[]( size_type index ); + //! code point dereference operator + const code_point& operator[]( size_type index ) const; + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name Implicit Cast Operators + //@{ + //! implicit cast to std::string + operator std::string() const; + //! implicit cast to std::wstring + operator std::wstring() const; #if OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR - //! implicit cast to Ogre::String - operator Ogre::String() const; + //! implicit cast to Ogre::String + operator Ogre::String() const; #endif - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name UTF-16 character encoding/decoding - //@{ - //! returns \c true if \a cp does not match the signature for the lead of follow code point of a surrogate pair in a UTF-16 sequence - static bool _utf16_independent_char( code_point cp ); - //! returns \c true if \a cp matches the signature of a surrogate pair lead character - static bool _utf16_surrogate_lead( code_point cp ); - //! returns \c true if \a cp matches the signature of a surrogate pair following character - static bool _utf16_surrogate_follow( code_point cp ); - //! estimates the number of UTF-16 code points in the sequence starting with \a cp - static size_t _utf16_char_length( code_point cp ); - //! returns the number of UTF-16 code points needed to represent the given UTF-32 character \a cp - static size_t _utf16_char_length( unicode_char uc ); - //! converts the given UTF-16 character buffer \a in_cp to a single UTF-32 Unicode character \a out_uc, returns the number of code points used to create the output character (2 for surrogate pairs, otherwise 1) - /*! This function does it's best to prevent error conditions, verifying complete - surrogate pairs before applying the algorithm. In the event that half of a pair - is found it will happily generate a value in the 0xD800 - 0xDFFF range, which is - normally an invalid Unicode value but we preserve them for use as sentinel values. */ - static size_t _utf16_to_utf32( const code_point in_cp[2], unicode_char& out_uc ); - //! writes the given UTF-32 \a uc_in to the buffer location \a out_cp using UTF-16 encoding, returns the number of code points used to encode the input (always 1 or 2) - /*! This function, like its counterpart, will happily create invalid UTF-16 surrogate pairs. These - invalid entries will be created for any value of \c in_uc that falls in the range U+D800 - U+DFFF. - These are generally useful as sentinel values to represent various program specific conditions. - @note This function will also pass through any single UTF-16 code point without modification, - making it a safe method of ensuring a stream that is unknown UTF-32 or UTF-16 is truly UTF-16.*/ - static size_t _utf32_to_utf16( const unicode_char& in_uc, code_point out_cp[2] ); - //@} - - ////////////////////////////////////////////////////////////////////////// - - //!\name UTF-8 character encoding/decoding - //@{ - //! returns \c true if \a cp is the beginning of a UTF-8 sequence - static bool _utf8_start_char( unsigned char cp ); - //! estimates the number of UTF-8 code points in the sequence starting with \a cp - static size_t _utf8_char_length( unsigned char cp ); - //! returns the number of UTF-8 code points needed to represent the given UTF-32 character \a cp - static size_t _utf8_char_length( unicode_char uc ); - - //! converts the given UTF-8 character buffer to a single UTF-32 Unicode character, returns the number of bytes used to create the output character (maximum of 6) - static size_t _utf8_to_utf32( const unsigned char in_cp[6], unicode_char& out_uc ); - //! writes the given UTF-32 \a uc_in to the buffer location \a out_cp using UTF-8 encoding, returns the number of bytes used to encode the input - static size_t _utf32_to_utf8( const unicode_char& in_uc, unsigned char out_cp[6] ); - - //! verifies a UTF-8 stream, returning the total number of Unicode characters found - static size_type _verifyUTF8( const unsigned char* c_str ); - //! verifies a UTF-8 stream, returning the total number of Unicode characters found - static size_type _verifyUTF8( const std::string& str ); - //@} - - private: - //template friend class _iterator; - dstring mData; - - //! buffer data type identifier - enum BufferType { - bt_none, - bt_string, - bt_wstring, - bt_utf32string - }; - - //! common constructor operations - void _init(); - - /////////////////////////////////////////////////////////////////////// - // Scratch buffer - //! auto cleans the scratch buffer using the proper delete for the stored type - void _cleanBuffer() const; - - //! create a std::string in the scratch buffer area - void _getBufferStr() const; - //! create a std::wstring in the scratch buffer area - void _getBufferWStr() const; - //! create a utf32string in the scratch buffer area - void _getBufferUTF32Str() const; - - void _load_buffer_UTF8() const; - void _load_buffer_WStr() const; - void _load_buffer_UTF32() const; - - mutable BufferType mBufferType; // identifies the data type held in mBuffer - mutable size_t mBufferSize; // size of the CString buffer - - // multi-purpose buffer used everywhere we need a throw-away buffer - union { - mutable void* mVoidBuffer; - mutable std::string* mStrBuffer; - mutable std::wstring* mWStrBuffer; - mutable utf32string* mUTF32StrBuffer; - } - mBuffer; - }; - - //! string addition operator \relates UTFString - inline UTFString operator+( const UTFString& s1, const UTFString& s2 ) { - return UTFString( s1 ).append( s2 ); - } - //! string addition operator \relates UTFString - inline UTFString operator+( const UTFString& s1, UTFString::code_point c ) { - return UTFString( s1 ).append( 1, c ); - } - //! string addition operator \relates UTFString - inline UTFString operator+( const UTFString& s1, UTFString::unicode_char c ) { - return UTFString( s1 ).append( 1, c ); - } - //! string addition operator \relates UTFString - inline UTFString operator+( const UTFString& s1, char c ) { - return UTFString( s1 ).append( 1, c ); - } + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name UTF-16 character encoding/decoding + //@{ + //! returns \c true if \a cp does not match the signature for the lead of follow code point of a surrogate pair in a UTF-16 sequence + static bool _utf16_independent_char( code_point cp ); + //! returns \c true if \a cp matches the signature of a surrogate pair lead character + static bool _utf16_surrogate_lead( code_point cp ); + //! returns \c true if \a cp matches the signature of a surrogate pair following character + static bool _utf16_surrogate_follow( code_point cp ); + //! estimates the number of UTF-16 code points in the sequence starting with \a cp + static size_t _utf16_char_length( code_point cp ); + //! returns the number of UTF-16 code points needed to represent the given UTF-32 character \a cp + static size_t _utf16_char_length( unicode_char uc ); + //! converts the given UTF-16 character buffer \a in_cp to a single UTF-32 Unicode character \a out_uc, returns the number of code points used to create the output character (2 for surrogate pairs, otherwise 1) + /*! This function does it's best to prevent error conditions, verifying complete + surrogate pairs before applying the algorithm. In the event that half of a pair + is found it will happily generate a value in the 0xD800 - 0xDFFF range, which is + normally an invalid Unicode value but we preserve them for use as sentinel values. */ + static size_t _utf16_to_utf32( const code_point in_cp[2], unicode_char& out_uc ); + //! writes the given UTF-32 \a uc_in to the buffer location \a out_cp using UTF-16 encoding, returns the number of code points used to encode the input (always 1 or 2) + /*! This function, like its counterpart, will happily create invalid UTF-16 surrogate pairs. These + invalid entries will be created for any value of \c in_uc that falls in the range U+D800 - U+DFFF. + These are generally useful as sentinel values to represent various program specific conditions. + @note This function will also pass through any single UTF-16 code point without modification, + making it a safe method of ensuring a stream that is unknown UTF-32 or UTF-16 is truly UTF-16.*/ + static size_t _utf32_to_utf16( const unicode_char& in_uc, code_point out_cp[2] ); + //@} + + ////////////////////////////////////////////////////////////////////////// + + //!\name UTF-8 character encoding/decoding + //@{ + //! returns \c true if \a cp is the beginning of a UTF-8 sequence + static bool _utf8_start_char( unsigned char cp ); + //! estimates the number of UTF-8 code points in the sequence starting with \a cp + static size_t _utf8_char_length( unsigned char cp ); + //! returns the number of UTF-8 code points needed to represent the given UTF-32 character \a cp + static size_t _utf8_char_length( unicode_char uc ); + + //! converts the given UTF-8 character buffer to a single UTF-32 Unicode character, returns the number of bytes used to create the output character (maximum of 6) + static size_t _utf8_to_utf32( const unsigned char in_cp[6], unicode_char& out_uc ); + //! writes the given UTF-32 \a uc_in to the buffer location \a out_cp using UTF-8 encoding, returns the number of bytes used to encode the input + static size_t _utf32_to_utf8( const unicode_char& in_uc, unsigned char out_cp[6] ); + + //! verifies a UTF-8 stream, returning the total number of Unicode characters found + static size_type _verifyUTF8( const unsigned char* c_str ); + //! verifies a UTF-8 stream, returning the total number of Unicode characters found + static size_type _verifyUTF8( const std::string& str ); + //@} + + private: + //template friend class _iterator; + dstring mData; + + //! buffer data type identifier + enum BufferType { + bt_none, + bt_string, + bt_wstring, + bt_utf32string + }; + + //! common constructor operations + void _init(); + + /////////////////////////////////////////////////////////////////////// + // Scratch buffer + //! auto cleans the scratch buffer using the proper delete for the stored type + void _cleanBuffer() const; + + //! create a std::string in the scratch buffer area + void _getBufferStr() const; + //! create a std::wstring in the scratch buffer area + void _getBufferWStr() const; + //! create a utf32string in the scratch buffer area + void _getBufferUTF32Str() const; + + void _load_buffer_UTF8() const; + void _load_buffer_WStr() const; + void _load_buffer_UTF32() const; + + mutable BufferType mBufferType; // identifies the data type held in mBuffer + mutable size_t mBufferSize; // size of the CString buffer + + // multi-purpose buffer used everywhere we need a throw-away buffer + union { + mutable void* mVoidBuffer; + mutable std::string* mStrBuffer; + mutable std::wstring* mWStrBuffer; + mutable utf32string* mUTF32StrBuffer; + } + mBuffer; + }; + + //! string addition operator \relates UTFString + inline UTFString operator+( const UTFString& s1, const UTFString& s2 ) { + return UTFString( s1 ).append( s2 ); + } + //! string addition operator \relates UTFString + inline UTFString operator+( const UTFString& s1, UTFString::code_point c ) { + return UTFString( s1 ).append( 1, c ); + } + //! string addition operator \relates UTFString + inline UTFString operator+( const UTFString& s1, UTFString::unicode_char c ) { + return UTFString( s1 ).append( 1, c ); + } + //! string addition operator \relates UTFString + inline UTFString operator+( const UTFString& s1, char c ) { + return UTFString( s1 ).append( 1, c ); + } #if OGRE_IS_NATIVE_WCHAR_T - //! string addition operator \relates UTFString - inline UTFString operator+( const UTFString& s1, wchar_t c ) { - return UTFString( s1 ).append( 1, c ); - } + //! string addition operator \relates UTFString + inline UTFString operator+( const UTFString& s1, wchar_t c ) { + return UTFString( s1 ).append( 1, c ); + } #endif - //! string addition operator \relates UTFString - inline UTFString operator+( UTFString::code_point c, const UTFString& s2 ) { - return UTFString().append( 1, c ).append( s2 ); - } - //! string addition operator \relates UTFString - inline UTFString operator+( UTFString::unicode_char c, const UTFString& s2 ) { - return UTFString().append( 1, c ).append( s2 ); - } - //! string addition operator \relates UTFString - inline UTFString operator+( char c, const UTFString& s2 ) { - return UTFString().append( 1, c ).append( s2 ); - } + //! string addition operator \relates UTFString + inline UTFString operator+( UTFString::code_point c, const UTFString& s2 ) { + return UTFString().append( 1, c ).append( s2 ); + } + //! string addition operator \relates UTFString + inline UTFString operator+( UTFString::unicode_char c, const UTFString& s2 ) { + return UTFString().append( 1, c ).append( s2 ); + } + //! string addition operator \relates UTFString + inline UTFString operator+( char c, const UTFString& s2 ) { + return UTFString().append( 1, c ).append( s2 ); + } #if OGRE_IS_NATIVE_WCHAR_T - //! string addition operator \relates UTFString - inline UTFString operator+( wchar_t c, const UTFString& s2 ) { - return UTFString().append( 1, c ).append( s2 ); - } + //! string addition operator \relates UTFString + inline UTFString operator+( wchar_t c, const UTFString& s2 ) { + return UTFString().append( 1, c ).append( s2 ); + } #endif - // (const) forward iterator common operators - inline UTFString::size_type operator-( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { - return ( left.mIter - right.mIter ); - } - inline bool operator==( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { - return left.mIter == right.mIter; - } - inline bool operator!=( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { - return left.mIter != right.mIter; - } - inline bool operator<( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { - return left.mIter < right.mIter; - } - inline bool operator<=( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { - return left.mIter <= right.mIter; - } - inline bool operator>( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { - return left.mIter > right.mIter; - } - inline bool operator>=( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { - return left.mIter >= right.mIter; - } - - // (const) reverse iterator common operators - // NB: many of these operations are evaluated in reverse because this is a reverse iterator wrapping a forward iterator - inline UTFString::size_type operator-( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { - return ( right.mIter - left.mIter ); - } - inline bool operator==( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { - return left.mIter == right.mIter; - } - inline bool operator!=( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { - return left.mIter != right.mIter; - } - inline bool operator<( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { - return right.mIter < left.mIter; - } - inline bool operator<=( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { - return right.mIter <= left.mIter; - } - inline bool operator>( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { - return right.mIter > left.mIter; - } - inline bool operator>=( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { - return right.mIter >= left.mIter; - } - - //! std::ostream write operator \relates UTFString - inline std::ostream& operator << ( std::ostream& os, const UTFString& s ) { - return os << s.asUTF8(); - } - - //! std::wostream write operator \relates UTFString - inline std::wostream& operator << ( std::wostream& os, const UTFString& s ) { - return os << s.asWStr(); - } - - /** @} */ - /** @} */ + // (const) forward iterator common operators + inline UTFString::size_type operator-( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { + return ( left.mIter - right.mIter ); + } + inline bool operator==( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { + return left.mIter == right.mIter; + } + inline bool operator!=( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { + return left.mIter != right.mIter; + } + inline bool operator<( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { + return left.mIter < right.mIter; + } + inline bool operator<=( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { + return left.mIter <= right.mIter; + } + inline bool operator>( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { + return left.mIter > right.mIter; + } + inline bool operator>=( const UTFString::_const_fwd_iterator& left, const UTFString::_const_fwd_iterator& right ) { + return left.mIter >= right.mIter; + } + + // (const) reverse iterator common operators + // NB: many of these operations are evaluated in reverse because this is a reverse iterator wrapping a forward iterator + inline UTFString::size_type operator-( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { + return ( right.mIter - left.mIter ); + } + inline bool operator==( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { + return left.mIter == right.mIter; + } + inline bool operator!=( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { + return left.mIter != right.mIter; + } + inline bool operator<( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { + return right.mIter < left.mIter; + } + inline bool operator<=( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { + return right.mIter <= left.mIter; + } + inline bool operator>( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { + return right.mIter > left.mIter; + } + inline bool operator>=( const UTFString::_const_rev_iterator& left, const UTFString::_const_rev_iterator& right ) { + return right.mIter >= left.mIter; + } + + //! std::ostream write operator \relates UTFString + inline std::ostream& operator << ( std::ostream& os, const UTFString& s ) { + return os << s.asUTF8(); + } + + //! std::wostream write operator \relates UTFString + inline std::wostream& operator << ( std::wostream& os, const UTFString& s ) { + return os << s.asWStr(); + } + + /** @} */ + /** @} */ } // namespace Ogre{ diff --git a/OgreMain/include/OgreUnifiedHighLevelGpuProgram.h b/OgreMain/include/OgreUnifiedHighLevelGpuProgram.h index d714dae486a..7c720c8e6af 100644 --- a/OgreMain/include/OgreUnifiedHighLevelGpuProgram.h +++ b/OgreMain/include/OgreUnifiedHighLevelGpuProgram.h @@ -34,151 +34,151 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Specialisation of HighLevelGpuProgram which just delegates its implementation - to one other high level program, allowing a single program definition - to represent one supported program from a number of options - @remarks - Whilst you can use Technique to implement several ways to render an object - depending on hardware support, if the only reason to need multiple paths is - because of the high-level shader language supported, this can be - cumbersome. For example you might want to implement the same shader - in HLSL and GLSL for portability but apart from the implementation detail, - the shaders do the same thing and take the same parameters. If the materials - in question are complex, duplicating the techniques just to switch language - is not optimal, so instead you can define high-level programs with a - syntax of 'unified', and list the actual implementations in order of - preference via repeated use of the 'delegate' parameter, which just points - at another program name. The first one which has a supported syntax - will be used. - */ - class _OgreExport UnifiedHighLevelGpuProgram : public HighLevelGpuProgram - { - private: - static std::map mLanguagePriorities; - - public: - /// Command object for setting delegate (can set more than once) - class CmdDelegate : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - - static void setPrioriry(String shaderLanguage,int priority); - static int getPriority(String shaderLanguage); - - protected: - static CmdDelegate msCmdDelegate; - - /// Ordered list of potential delegates - StringVector mDelegateNames; - /// The chosen delegate - mutable HighLevelGpuProgramPtr mChosenDelegate; - - /// Choose the delegate to use - void chooseDelegate() const; - - void createLowLevelImpl(void); - void unloadHighLevelImpl(void); - void buildConstantDefinitions() const; - void loadFromSource(void); - - public: - /** Constructor, should be used only by factory classes. */ - UnifiedHighLevelGpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual = false, ManualResourceLoader* loader = 0); - ~UnifiedHighLevelGpuProgram(); - - virtual size_t calculateSize(void) const; - - /** Adds a new delegate program to the list. - @remarks - Delegates are tested in order so earlier ones are preferred. - */ - void addDelegateProgram(const String& name); - - /// Remove all delegate programs - void clearDelegatePrograms(); - - /// Get the chosen delegate - const HighLevelGpuProgramPtr& _getDelegate() const; - - /** @copydoc GpuProgram::getLanguage */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Specialisation of HighLevelGpuProgram which just delegates its implementation + to one other high level program, allowing a single program definition + to represent one supported program from a number of options + @remarks + Whilst you can use Technique to implement several ways to render an object + depending on hardware support, if the only reason to need multiple paths is + because of the high-level shader language supported, this can be + cumbersome. For example you might want to implement the same shader + in HLSL and GLSL for portability but apart from the implementation detail, + the shaders do the same thing and take the same parameters. If the materials + in question are complex, duplicating the techniques just to switch language + is not optimal, so instead you can define high-level programs with a + syntax of 'unified', and list the actual implementations in order of + preference via repeated use of the 'delegate' parameter, which just points + at another program name. The first one which has a supported syntax + will be used. + */ + class _OgreExport UnifiedHighLevelGpuProgram : public HighLevelGpuProgram + { + private: + static std::map mLanguagePriorities; + + public: + /// Command object for setting delegate (can set more than once) + class CmdDelegate : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + + static void setPrioriry(String shaderLanguage,int priority); + static int getPriority(String shaderLanguage); + + protected: + static CmdDelegate msCmdDelegate; + + /// Ordered list of potential delegates + StringVector mDelegateNames; + /// The chosen delegate + mutable HighLevelGpuProgramPtr mChosenDelegate; + + /// Choose the delegate to use + void chooseDelegate() const; + + void createLowLevelImpl(void); + void unloadHighLevelImpl(void); + void buildConstantDefinitions() const; + void loadFromSource(void); + + public: + /** Constructor, should be used only by factory classes. */ + UnifiedHighLevelGpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual = false, ManualResourceLoader* loader = 0); + ~UnifiedHighLevelGpuProgram(); + + virtual size_t calculateSize(void) const; + + /** Adds a new delegate program to the list. + @remarks + Delegates are tested in order so earlier ones are preferred. + */ + void addDelegateProgram(const String& name); + + /// Remove all delegate programs + void clearDelegatePrograms(); + + /// Get the chosen delegate + const HighLevelGpuProgramPtr& _getDelegate() const; + + /** @copydoc GpuProgram::getLanguage */ const String& getLanguage(void) const; - /** Creates a new parameters object compatible with this program definition. - @remarks - Unlike low-level assembly programs, parameters objects are specific to the - program and therefore must be created from it rather than by the - HighLevelGpuProgramManager. This method creates a new instance of a parameters - object containing the definition of the parameters this program understands. - */ - GpuProgramParametersSharedPtr createParameters(void); - /** @copydoc GpuProgram::_getBindingDelegate */ - GpuProgram* _getBindingDelegate(void); - - // All the following methods must delegate to the implementation - - /** @copydoc GpuProgram::isSupported */ - bool isSupported(void) const; - - /** @copydoc GpuProgram::isSkeletalAnimationIncluded */ - bool isSkeletalAnimationIncluded(void) const; - - bool isMorphAnimationIncluded(void) const; - - bool isPoseAnimationIncluded(void) const; - - bool isVertexTextureFetchRequired(void) const; - GpuProgramParametersSharedPtr getDefaultParameters(void); - bool hasDefaultParameters(void) const; - bool getPassSurfaceAndLightStates(void) const; - bool getPassFogStates(void) const; - bool getPassTransformStates(void) const; - bool hasCompileError(void) const; - void resetCompileError(void); - - void load(bool backgroundThread = false); - void reload(void); - bool isReloadable(void) const; - bool isLoaded(void) const; - bool isLoading() const; - LoadingState getLoadingState() const; - void unload(void); - size_t getSize(void) const; - void touch(void); - bool isBackgroundLoaded(void) const; - void setBackgroundLoaded(bool bl); - void escalateLoading(); - void addListener(Listener* lis); - void removeListener(Listener* lis); - - }; - - /** Factory class for Unified programs. */ - class UnifiedHighLevelGpuProgramFactory : public HighLevelGpuProgramFactory - { - public: - UnifiedHighLevelGpuProgramFactory(); - ~UnifiedHighLevelGpuProgramFactory(); - /// Get the name of the language this factory creates programs for - const String& getLanguage(void) const; - HighLevelGpuProgram* create(ResourceManager* creator, - const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader); - void destroy(HighLevelGpuProgram* prog); - - }; - - /** @} */ - /** @} */ + /** Creates a new parameters object compatible with this program definition. + @remarks + Unlike low-level assembly programs, parameters objects are specific to the + program and therefore must be created from it rather than by the + HighLevelGpuProgramManager. This method creates a new instance of a parameters + object containing the definition of the parameters this program understands. + */ + GpuProgramParametersSharedPtr createParameters(void); + /** @copydoc GpuProgram::_getBindingDelegate */ + GpuProgram* _getBindingDelegate(void); + + // All the following methods must delegate to the implementation + + /** @copydoc GpuProgram::isSupported */ + bool isSupported(void) const; + + /** @copydoc GpuProgram::isSkeletalAnimationIncluded */ + bool isSkeletalAnimationIncluded(void) const; + + bool isMorphAnimationIncluded(void) const; + + bool isPoseAnimationIncluded(void) const; + + bool isVertexTextureFetchRequired(void) const; + GpuProgramParametersSharedPtr getDefaultParameters(void); + bool hasDefaultParameters(void) const; + bool getPassSurfaceAndLightStates(void) const; + bool getPassFogStates(void) const; + bool getPassTransformStates(void) const; + bool hasCompileError(void) const; + void resetCompileError(void); + + void load(bool backgroundThread = false); + void reload(void); + bool isReloadable(void) const; + bool isLoaded(void) const; + bool isLoading() const; + LoadingState getLoadingState() const; + void unload(void); + size_t getSize(void) const; + void touch(void); + bool isBackgroundLoaded(void) const; + void setBackgroundLoaded(bool bl); + void escalateLoading(); + void addListener(Listener* lis); + void removeListener(Listener* lis); + + }; + + /** Factory class for Unified programs. */ + class UnifiedHighLevelGpuProgramFactory : public HighLevelGpuProgramFactory + { + public: + UnifiedHighLevelGpuProgramFactory(); + ~UnifiedHighLevelGpuProgramFactory(); + /// Get the name of the language this factory creates programs for + const String& getLanguage(void) const; + HighLevelGpuProgram* create(ResourceManager* creator, + const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader); + void destroy(HighLevelGpuProgram* prog); + + }; + + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreUserObjectBindings.h b/OgreMain/include/OgreUserObjectBindings.h index 828c11ae415..a3fa8953eb6 100644 --- a/OgreMain/include/OgreUserObjectBindings.h +++ b/OgreMain/include/OgreUserObjectBindings.h @@ -34,108 +34,108 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - - /** Class that provides convenient interface to establish a linkage between - custom user application objects and Ogre core classes. - Any instance of Ogre class that will derive from this class could be associated with custom - application object using this class interface. - */ - class _OgreExport UserObjectBindings : public GeneralAllocatedObject - { - public: - /** Class constructor. */ - UserObjectBindings(); - - /** Class destructor. */ - virtual ~UserObjectBindings(); - - /** Sets any kind of user object on this class instance. - @remarks - This method allows you to associate any user object you like with - this class. This can be a pointer back to one of your own - classes for instance. - @note This method is key less meaning that each call for it will override - previous object that were set. If you need to associate multiple objects - with this class use the extended version that takes key. - */ - void setUserAny(const Any& anything); - - /** Retrieves the custom key less user object associated with this class. - */ - const Any& getUserAny(void) const; - - /** Sets any kind of user object on this class instance. - @remarks - This method allows you to associate multiple object with this class. - This can be a pointer back to one of your own classes for instance. - Use a unique key to distinguish between each of these objects. - @param key The key that this data is associate with. - @param anything The data to associate with the given key. - */ - void setUserAny(const String& key, const Any& anything); - - /** Retrieves the custom user object associated with this class and key. - @param key The key that the requested user object is associated with. - @remarks - In case no object associated with this key the returned Any object will be empty. - */ - const Any& getUserAny(const String& key) const; - - /** Erase the custom user object associated with this class and key from this binding. - @param key The key that the requested user object is associated with. - */ - void eraseUserAny(const String& key); - - /** Clear all user objects from this binding. */ - void clear() const; - - /** Returns empty user any object. - */ - static const Any& getEmptyUserAny() { return msEmptyAny; } - - // Types. - protected: - typedef map::type UserObjectsMap; - typedef UserObjectsMap::iterator UserObjectsMapIterator; - typedef UserObjectsMap::const_iterator UserObjectsMapConstIterator; - - /** Internal class that uses as data storage container. - */ - class Attributes : public GeneralAllocatedObject - { - public: - /** Attribute storage ctor. */ - Attributes() : mUserObjectsMap(NULL) {} - - /** Attribute storage dtor. */ - ~Attributes() - { - if (mUserObjectsMap != NULL) - { - OGRE_DELETE mUserObjectsMap; - mUserObjectsMap = NULL; - } - } - - Any mKeylessAny; // Will hold key less associated user object for fast access. - UserObjectsMap* mUserObjectsMap; // Will hold a map between user keys to user objects. - }; - - // Attributes. - private: - static Any msEmptyAny; // Shared empty any object. - mutable Attributes* mAttributes; // Class attributes - will be allocated on demand. - - }; - - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + + /** Class that provides convenient interface to establish a linkage between + custom user application objects and Ogre core classes. + Any instance of Ogre class that will derive from this class could be associated with custom + application object using this class interface. + */ + class _OgreExport UserObjectBindings : public GeneralAllocatedObject + { + public: + /** Class constructor. */ + UserObjectBindings(); + + /** Class destructor. */ + virtual ~UserObjectBindings(); + + /** Sets any kind of user object on this class instance. + @remarks + This method allows you to associate any user object you like with + this class. This can be a pointer back to one of your own + classes for instance. + @note This method is key less meaning that each call for it will override + previous object that were set. If you need to associate multiple objects + with this class use the extended version that takes key. + */ + void setUserAny(const Any& anything); + + /** Retrieves the custom key less user object associated with this class. + */ + const Any& getUserAny(void) const; + + /** Sets any kind of user object on this class instance. + @remarks + This method allows you to associate multiple object with this class. + This can be a pointer back to one of your own classes for instance. + Use a unique key to distinguish between each of these objects. + @param key The key that this data is associate with. + @param anything The data to associate with the given key. + */ + void setUserAny(const String& key, const Any& anything); + + /** Retrieves the custom user object associated with this class and key. + @param key The key that the requested user object is associated with. + @remarks + In case no object associated with this key the returned Any object will be empty. + */ + const Any& getUserAny(const String& key) const; + + /** Erase the custom user object associated with this class and key from this binding. + @param key The key that the requested user object is associated with. + */ + void eraseUserAny(const String& key); + + /** Clear all user objects from this binding. */ + void clear() const; + + /** Returns empty user any object. + */ + static const Any& getEmptyUserAny() { return msEmptyAny; } + + // Types. + protected: + typedef map::type UserObjectsMap; + typedef UserObjectsMap::iterator UserObjectsMapIterator; + typedef UserObjectsMap::const_iterator UserObjectsMapConstIterator; + + /** Internal class that uses as data storage container. + */ + class Attributes : public GeneralAllocatedObject + { + public: + /** Attribute storage ctor. */ + Attributes() : mUserObjectsMap(NULL) {} + + /** Attribute storage dtor. */ + ~Attributes() + { + if (mUserObjectsMap != NULL) + { + OGRE_DELETE mUserObjectsMap; + mUserObjectsMap = NULL; + } + } + + Any mKeylessAny; // Will hold key less associated user object for fast access. + UserObjectsMap* mUserObjectsMap; // Will hold a map between user keys to user objects. + }; + + // Attributes. + private: + static Any msEmptyAny; // Shared empty any object. + mutable Attributes* mAttributes; // Class attributes - will be allocated on demand. + + }; + + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreVector2.h b/OgreMain/include/OgreVector2.h index cd41b2accbc..aeb14ca749a 100644 --- a/OgreMain/include/OgreVector2.h +++ b/OgreMain/include/OgreVector2.h @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Standard 2-dimensional vector. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Standard 2-dimensional vector. @remarks A direction in 2D space represented as distances along the 2 orthogonal axes (x, y). Note that positions, directions and @@ -89,38 +89,38 @@ namespace Ogre { } - /** Exchange the contents of this vector with another. - */ - inline void swap(Vector2& other) - { - std::swap(x, other.x); - std::swap(y, other.y); - } + /** Exchange the contents of this vector with another. + */ + inline void swap(Vector2& other) + { + std::swap(x, other.x); + std::swap(y, other.y); + } - inline Real operator [] ( const size_t i ) const + inline Real operator [] ( const size_t i ) const { assert( i < 2 ); return *(&x+i); } - inline Real& operator [] ( const size_t i ) + inline Real& operator [] ( const size_t i ) { assert( i < 2 ); return *(&x+i); } - /// Pointer accessor for direct copying - inline Real* ptr() - { - return &x; - } - /// Pointer accessor for direct copying - inline const Real* ptr() const - { - return &x; - } + /// Pointer accessor for direct copying + inline Real* ptr() + { + return &x; + } + /// Pointer accessor for direct copying + inline const Real* ptr() const + { + return &x; + } /** Assigns the value of the other vector. @param @@ -134,13 +134,13 @@ namespace Ogre return *this; } - inline Vector2& operator = ( const Real fScalar) - { - x = fScalar; - y = fScalar; + inline Vector2& operator = ( const Real fScalar) + { + x = fScalar; + y = fScalar; - return *this; - } + return *this; + } inline bool operator == ( const Vector2& rkVector ) const { @@ -409,7 +409,7 @@ namespace Ogre Real fLength = Math::Sqrt( x * x + y * y); // Will also work for zero-sized vectors, but will change nothing - // We're not using epsilons because we don't need to. + // We're not using epsilons because we don't need to. // Read http://www.ogre3d.org/forums/viewtopic.php?f=4&t=61259 if ( fLength > Real(0.0f) ) { @@ -490,7 +490,7 @@ namespace Ogre } /** Calculates the 2 dimensional cross-product of 2 vectors, which results - in a single floating point value which is 2 times the area of the triangle. + in a single floating point value which is 2 times the area of the triangle. */ inline Real crossProduct( const Vector2& rkVector ) const { @@ -543,43 +543,43 @@ namespace Ogre return Vector2( *this - ( 2 * this->dotProduct(normal) * normal ) ); } - /// Check whether this vector contains valid values - inline bool isNaN() const - { - return Math::isNaN(x) || Math::isNaN(y); - } - - /** Gets the angle between 2 vectors. - @remarks - Vectors do not have to be unit-length but must represent directions. - */ - inline Ogre::Radian angleBetween(const Ogre::Vector2& other) const - { - Ogre::Real lenProduct = length() * other.length(); - // Divide by zero check - if(lenProduct < 1e-6f) - lenProduct = 1e-6f; - - Ogre::Real f = dotProduct(other) / lenProduct; - - f = Ogre::Math::Clamp(f, (Ogre::Real)-1.0, (Ogre::Real)1.0); - return Ogre::Math::ACos(f); - } - - /** Gets the oriented angle between 2 vectors. - @remarks - Vectors do not have to be unit-length but must represent directions. - The angle is comprised between 0 and 2 PI. - */ - inline Ogre::Radian angleTo(const Ogre::Vector2& other) const - { - Ogre::Radian angle = angleBetween(other); - - if (crossProduct(other)<0) - angle = (Ogre::Radian)Ogre::Math::TWO_PI - angle; - - return angle; - } + /// Check whether this vector contains valid values + inline bool isNaN() const + { + return Math::isNaN(x) || Math::isNaN(y); + } + + /** Gets the angle between 2 vectors. + @remarks + Vectors do not have to be unit-length but must represent directions. + */ + inline Ogre::Radian angleBetween(const Ogre::Vector2& other) const + { + Ogre::Real lenProduct = length() * other.length(); + // Divide by zero check + if(lenProduct < 1e-6f) + lenProduct = 1e-6f; + + Ogre::Real f = dotProduct(other) / lenProduct; + + f = Ogre::Math::Clamp(f, (Ogre::Real)-1.0, (Ogre::Real)1.0); + return Ogre::Math::ACos(f); + } + + /** Gets the oriented angle between 2 vectors. + @remarks + Vectors do not have to be unit-length but must represent directions. + The angle is comprised between 0 and 2 PI. + */ + inline Ogre::Radian angleTo(const Ogre::Vector2& other) const + { + Ogre::Radian angle = angleBetween(other); + + if (crossProduct(other)<0) + angle = (Ogre::Radian)Ogre::Math::TWO_PI - angle; + + return angle; + } // special points static const Vector2 ZERO; @@ -598,8 +598,8 @@ namespace Ogre return o; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreVector3.h b/OgreMain/include/OgreVector3.h index 0e22eb0a925..29d50e6cc14 100644 --- a/OgreMain/include/OgreVector3.h +++ b/OgreMain/include/OgreVector3.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** Standard 3-dimensional vector. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** Standard 3-dimensional vector. @remarks A direction in 3D space represented as distances along the 3 orthogonal axes (x, y, z). Note that positions, directions and @@ -50,7 +50,7 @@ namespace Ogre class _OgreExport Vector3 { public: - Real x, y, z; + Real x, y, z; public: /** Default constructor. @@ -93,38 +93,38 @@ namespace Ogre } - /** Exchange the contents of this vector with another. - */ - inline void swap(Vector3& other) - { - std::swap(x, other.x); - std::swap(y, other.y); - std::swap(z, other.z); - } + /** Exchange the contents of this vector with another. + */ + inline void swap(Vector3& other) + { + std::swap(x, other.x); + std::swap(y, other.y); + std::swap(z, other.z); + } - inline Real operator [] ( const size_t i ) const + inline Real operator [] ( const size_t i ) const { assert( i < 3 ); return *(&x+i); } - inline Real& operator [] ( const size_t i ) + inline Real& operator [] ( const size_t i ) { assert( i < 3 ); return *(&x+i); } - /// Pointer accessor for direct copying - inline Real* ptr() - { - return &x; - } - /// Pointer accessor for direct copying - inline const Real* ptr() const - { - return &x; - } + /// Pointer accessor for direct copying + inline Real* ptr() + { + return &x; + } + /// Pointer accessor for direct copying + inline const Real* ptr() const + { + return &x; + } /** Assigns the value of the other vector. @param @@ -447,7 +447,7 @@ namespace Ogre Real fLength = Math::Sqrt( x * x + y * y + z * z ); // Will also work for zero-sized vectors, but will change nothing - // We're not using epsilons because we don't need to. + // We're not using epsilons because we don't need to. // Read http://www.ogre3d.org/forums/viewtopic.php?f=4&t=61259 if ( fLength > Real(0.0f) ) { @@ -478,7 +478,7 @@ namespace Ogre returned vector will be on the side from which the arc from 'this' to rkVector is anticlockwise, e.g. UNIT_Y.crossProduct(UNIT_Z) = UNIT_X, whilst UNIT_Z.crossProduct(UNIT_Y) = -UNIT_X. - This is because OGRE uses a right-handed coordinate system. + This is because OGRE uses a right-handed coordinate system. @par For a clearer explanation, look a the left and the bottom edges of your monitor's screen. Assume that the first vector is the @@ -576,7 +576,7 @@ namespace Ogre */ perp = this->crossProduct( Vector3::UNIT_Y ); } - perp.normalise(); + perp.normalise(); return perp; } @@ -625,34 +625,34 @@ namespace Ogre return q * (*this); } - /** Gets the angle between 2 vectors. - @remarks - Vectors do not have to be unit-length but must represent directions. - */ - inline Radian angleBetween(const Vector3& dest) const - { - Real lenProduct = length() * dest.length(); + /** Gets the angle between 2 vectors. + @remarks + Vectors do not have to be unit-length but must represent directions. + */ + inline Radian angleBetween(const Vector3& dest) const + { + Real lenProduct = length() * dest.length(); - // Divide by zero check - if(lenProduct < 1e-6f) - lenProduct = 1e-6f; + // Divide by zero check + if(lenProduct < 1e-6f) + lenProduct = 1e-6f; - Real f = dotProduct(dest) / lenProduct; + Real f = dotProduct(dest) / lenProduct; - f = Math::Clamp(f, (Real)-1.0, (Real)1.0); - return Math::ACos(f); + f = Math::Clamp(f, (Real)-1.0, (Real)1.0); + return Math::ACos(f); - } + } /** Gets the shortest arc quaternion to rotate this vector to the destination vector. @remarks If you call this with a dest vector that is close to the inverse of this vector, we will rotate 180 degrees around the 'fallbackAxis' - (if specified, or a generated axis if not) since in this case - ANY axis of rotation is valid. + (if specified, or a generated axis if not) since in this case + ANY axis of rotation is valid. */ Quaternion getRotationTo(const Vector3& dest, - const Vector3& fallbackAxis = Vector3::ZERO) const + const Vector3& fallbackAxis = Vector3::ZERO) const { // Based on Stan Melax's article in Game Programming Gems Quaternion q; @@ -668,36 +668,36 @@ namespace Ogre { return Quaternion::IDENTITY; } - if (d < (1e-6f - 1.0f)) - { - if (fallbackAxis != Vector3::ZERO) - { - // rotate 180 degrees about the fallback axis - q.FromAngleAxis(Radian(Math::PI), fallbackAxis); - } - else - { - // Generate an axis - Vector3 axis = Vector3::UNIT_X.crossProduct(*this); - if (axis.isZeroLength()) // pick another if colinear - axis = Vector3::UNIT_Y.crossProduct(*this); - axis.normalise(); - q.FromAngleAxis(Radian(Math::PI), axis); - } - } - else - { + if (d < (1e-6f - 1.0f)) + { + if (fallbackAxis != Vector3::ZERO) + { + // rotate 180 degrees about the fallback axis + q.FromAngleAxis(Radian(Math::PI), fallbackAxis); + } + else + { + // Generate an axis + Vector3 axis = Vector3::UNIT_X.crossProduct(*this); + if (axis.isZeroLength()) // pick another if colinear + axis = Vector3::UNIT_Y.crossProduct(*this); + axis.normalise(); + q.FromAngleAxis(Radian(Math::PI), axis); + } + } + else + { Real s = Math::Sqrt( (1+d)*2 ); - Real invs = 1 / s; + Real invs = 1 / s; - Vector3 c = v0.crossProduct(v1); + Vector3 c = v0.crossProduct(v1); - q.x = c.x * invs; - q.y = c.y * invs; - q.z = c.z * invs; - q.w = s * 0.5f; - q.normalise(); - } + q.x = c.x * invs; + q.y = c.y * invs; + q.z = c.z * invs; + q.w = s * 0.5f; + q.normalise(); + } return q; } @@ -726,76 +726,76 @@ namespace Ogre return Vector3( *this - ( 2 * this->dotProduct(normal) * normal ) ); } - /** Returns whether this vector is within a positional tolerance - of another vector. - @param rhs The vector to compare with - @param tolerance The amount that each element of the vector may vary by - and still be considered equal - */ - inline bool positionEquals(const Vector3& rhs, Real tolerance = 1e-03) const - { - return Math::RealEqual(x, rhs.x, tolerance) && - Math::RealEqual(y, rhs.y, tolerance) && - Math::RealEqual(z, rhs.z, tolerance); - - } - - /** Returns whether this vector is within a positional tolerance - of another vector, also take scale of the vectors into account. - @param rhs The vector to compare with - @param tolerance The amount (related to the scale of vectors) that distance + /** Returns whether this vector is within a positional tolerance + of another vector. + @param rhs The vector to compare with + @param tolerance The amount that each element of the vector may vary by + and still be considered equal + */ + inline bool positionEquals(const Vector3& rhs, Real tolerance = 1e-03) const + { + return Math::RealEqual(x, rhs.x, tolerance) && + Math::RealEqual(y, rhs.y, tolerance) && + Math::RealEqual(z, rhs.z, tolerance); + + } + + /** Returns whether this vector is within a positional tolerance + of another vector, also take scale of the vectors into account. + @param rhs The vector to compare with + @param tolerance The amount (related to the scale of vectors) that distance of the vector may vary by and still be considered close - */ - inline bool positionCloses(const Vector3& rhs, Real tolerance = 1e-03f) const - { - return squaredDistance(rhs) <= + */ + inline bool positionCloses(const Vector3& rhs, Real tolerance = 1e-03f) const + { + return squaredDistance(rhs) <= (squaredLength() + rhs.squaredLength()) * tolerance; - } - - /** Returns whether this vector is within a directional tolerance - of another vector. - @param rhs The vector to compare with - @param tolerance The maximum angle by which the vectors may vary and - still be considered equal - @note Both vectors should be normalised. - */ - inline bool directionEquals(const Vector3& rhs, - const Radian& tolerance) const - { - Real dot = dotProduct(rhs); - Radian angle = Math::ACos(dot); - - return Math::Abs(angle.valueRadians()) <= tolerance.valueRadians(); - - } - - /// Check whether this vector contains valid values - inline bool isNaN() const - { - return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z); - } - - /// Extract the primary (dominant) axis from this direction vector - inline Vector3 primaryAxis() const - { - Real absx = Math::Abs(x); - Real absy = Math::Abs(y); - Real absz = Math::Abs(z); - if (absx > absy) - if (absx > absz) - return x > 0 ? Vector3::UNIT_X : Vector3::NEGATIVE_UNIT_X; - else - return z > 0 ? Vector3::UNIT_Z : Vector3::NEGATIVE_UNIT_Z; - else // absx <= absy - if (absy > absz) - return y > 0 ? Vector3::UNIT_Y : Vector3::NEGATIVE_UNIT_Y; - else - return z > 0 ? Vector3::UNIT_Z : Vector3::NEGATIVE_UNIT_Z; - - - } - - // special points + } + + /** Returns whether this vector is within a directional tolerance + of another vector. + @param rhs The vector to compare with + @param tolerance The maximum angle by which the vectors may vary and + still be considered equal + @note Both vectors should be normalised. + */ + inline bool directionEquals(const Vector3& rhs, + const Radian& tolerance) const + { + Real dot = dotProduct(rhs); + Radian angle = Math::ACos(dot); + + return Math::Abs(angle.valueRadians()) <= tolerance.valueRadians(); + + } + + /// Check whether this vector contains valid values + inline bool isNaN() const + { + return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z); + } + + /// Extract the primary (dominant) axis from this direction vector + inline Vector3 primaryAxis() const + { + Real absx = Math::Abs(x); + Real absy = Math::Abs(y); + Real absz = Math::Abs(z); + if (absx > absy) + if (absx > absz) + return x > 0 ? Vector3::UNIT_X : Vector3::NEGATIVE_UNIT_X; + else + return z > 0 ? Vector3::UNIT_Z : Vector3::NEGATIVE_UNIT_Z; + else // absx <= absy + if (absy > absz) + return y > 0 ? Vector3::UNIT_Y : Vector3::NEGATIVE_UNIT_Y; + else + return z > 0 ? Vector3::UNIT_Z : Vector3::NEGATIVE_UNIT_Z; + + + } + + // special points static const Vector3 ZERO; static const Vector3 UNIT_X; static const Vector3 UNIT_Y; @@ -814,8 +814,8 @@ namespace Ogre return o; } }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreVector4.h b/OgreMain/include/OgreVector4.h index 68668be7082..2bf872a5954 100644 --- a/OgreMain/include/OgreVector4.h +++ b/OgreMain/include/OgreVector4.h @@ -34,13 +34,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ - /** 4-dimensional homogeneous vector. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ + /** 4-dimensional homogeneous vector. */ class _OgreExport Vector4 { @@ -95,40 +95,40 @@ namespace Ogre { } - /** Exchange the contents of this vector with another. - */ - inline void swap(Vector4& other) - { - std::swap(x, other.x); - std::swap(y, other.y); - std::swap(z, other.z); - std::swap(w, other.w); - } - - inline Real operator [] ( const size_t i ) const + /** Exchange the contents of this vector with another. + */ + inline void swap(Vector4& other) + { + std::swap(x, other.x); + std::swap(y, other.y); + std::swap(z, other.z); + std::swap(w, other.w); + } + + inline Real operator [] ( const size_t i ) const { assert( i < 4 ); return *(&x+i); } - inline Real& operator [] ( const size_t i ) + inline Real& operator [] ( const size_t i ) { assert( i < 4 ); return *(&x+i); } - /// Pointer accessor for direct copying - inline Real* ptr() - { - return &x; - } - /// Pointer accessor for direct copying - inline const Real* ptr() const - { - return &x; - } + /// Pointer accessor for direct copying + inline Real* ptr() + { + return &x; + } + /// Pointer accessor for direct copying + inline const Real* ptr() const + { + return &x; + } /** Assigns the value of the other vector. @param @@ -144,14 +144,14 @@ namespace Ogre return *this; } - inline Vector4& operator = ( const Real fScalar) - { - x = fScalar; - y = fScalar; - z = fScalar; - w = fScalar; - return *this; - } + inline Vector4& operator = ( const Real fScalar) + { + x = fScalar; + y = fScalar; + z = fScalar; + w = fScalar; + return *this; + } inline bool operator == ( const Vector4& rkVector ) const { @@ -394,11 +394,11 @@ namespace Ogre { return x * vec.x + y * vec.y + z * vec.z + w * vec.w; } - /// Check whether this vector contains valid values - inline bool isNaN() const - { - return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z) || Math::isNaN(w); - } + /// Check whether this vector contains valid values + inline bool isNaN() const + { + return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z) || Math::isNaN(w); + } /** Function for writing to a stream. */ inline _OgreExport friend std::ostream& operator << @@ -410,8 +410,8 @@ namespace Ogre // special static const Vector4 ZERO; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/OgreVertexBoneAssignment.h b/OgreMain/include/OgreVertexBoneAssignment.h index c479d4109da..f809ea3b13a 100644 --- a/OgreMain/include/OgreVertexBoneAssignment.h +++ b/OgreMain/include/OgreVertexBoneAssignment.h @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Animation - * @{ - */ - /** Records the assignment of a single vertex to a single bone with the corresponding weight. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Animation + * @{ + */ + /** Records the assignment of a single vertex to a single bone with the corresponding weight. @remarks This simple struct simply holds a vertex index, bone index and weight representing the assignment of a vertex to a bone for skeletal animation. There may be many of these @@ -55,8 +55,8 @@ namespace Ogre } VertexBoneAssignment; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreVertexIndexData.h b/OgreMain/include/OgreVertexIndexData.h index 6e0bfbdeef8..f71b3d2885d 100644 --- a/OgreMain/include/OgreVertexIndexData.h +++ b/OgreMain/include/OgreVertexIndexData.h @@ -34,80 +34,80 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ - /// Define a list of usage flags - typedef vector::type BufferUsageList; + /// Define a list of usage flags + typedef vector::type BufferUsageList; - /** Summary class collecting together vertex source information. */ - class _OgreExport VertexData : public VertexDataAlloc - { + /** Summary class collecting together vertex source information. */ + class _OgreExport VertexData : public VertexDataAlloc + { private: /// Protected copy constructor, to prevent misuse VertexData(const VertexData& rhs); /* do nothing, should not use */ /// Protected operator=, to prevent misuse VertexData& operator=(const VertexData& rhs); /* do not use */ - HardwareBufferManagerBase* mMgr; + HardwareBufferManagerBase* mMgr; public: - /** Constructor. - @note - This constructor creates the VertexDeclaration and VertexBufferBinding - automatically, and arranges for their deletion afterwards. - @param mgr Optional HardwareBufferManager from which to create resources - */ + /** Constructor. + @note + This constructor creates the VertexDeclaration and VertexBufferBinding + automatically, and arranges for their deletion afterwards. + @param mgr Optional HardwareBufferManager from which to create resources + */ VertexData(HardwareBufferManagerBase* mgr = 0); - /** Constructor. - @note - This constructor receives the VertexDeclaration and VertexBufferBinding - from the caller, and as such does not arrange for their deletion afterwards, - the caller remains responsible for that. - @param dcl The VertexDeclaration to use - @param bind The VertexBufferBinding to use - */ - VertexData(VertexDeclaration* dcl, VertexBufferBinding* bind); + /** Constructor. + @note + This constructor receives the VertexDeclaration and VertexBufferBinding + from the caller, and as such does not arrange for their deletion afterwards, + the caller remains responsible for that. + @param dcl The VertexDeclaration to use + @param bind The VertexBufferBinding to use + */ + VertexData(VertexDeclaration* dcl, VertexBufferBinding* bind); ~VertexData(); - /** Declaration of the vertex to be used in this operation. - @remarks Note that this is created for you on construction. - */ - VertexDeclaration* vertexDeclaration; - /** The vertex buffer bindings to be used. - @remarks Note that this is created for you on construction. - */ - VertexBufferBinding* vertexBufferBinding; - /// Whether this class should delete the declaration and binding - bool mDeleteDclBinding; - /// The base vertex index to start from - size_t vertexStart; - /// The number of vertices used in this operation - size_t vertexCount; - - - /// Struct used to hold hardware morph / pose vertex data information - struct HardwareAnimationData - { - unsigned short targetBufferIndex; - Real parametric; - }; - typedef vector::type HardwareAnimationDataList; - /// VertexElements used for hardware morph / pose animation - HardwareAnimationDataList hwAnimationDataList; - /// Number of hardware animation data items used - size_t hwAnimDataItemsUsed; - - /** Clones this vertex data, potentially including replicating any vertex buffers. - @param copyData Whether to create new vertex buffers too or just reference the existing ones - @param mgr If supplied, the buffer manager through which copies should be made - @remarks The caller is expected to delete the returned pointer when ready - */ - VertexData* clone(bool copyData = true, HardwareBufferManagerBase* mgr = 0) const; + /** Declaration of the vertex to be used in this operation. + @remarks Note that this is created for you on construction. + */ + VertexDeclaration* vertexDeclaration; + /** The vertex buffer bindings to be used. + @remarks Note that this is created for you on construction. + */ + VertexBufferBinding* vertexBufferBinding; + /// Whether this class should delete the declaration and binding + bool mDeleteDclBinding; + /// The base vertex index to start from + size_t vertexStart; + /// The number of vertices used in this operation + size_t vertexCount; + + + /// Struct used to hold hardware morph / pose vertex data information + struct HardwareAnimationData + { + unsigned short targetBufferIndex; + Real parametric; + }; + typedef vector::type HardwareAnimationDataList; + /// VertexElements used for hardware morph / pose animation + HardwareAnimationDataList hwAnimationDataList; + /// Number of hardware animation data items used + size_t hwAnimDataItemsUsed; + + /** Clones this vertex data, potentially including replicating any vertex buffers. + @param copyData Whether to create new vertex buffers too or just reference the existing ones + @param mgr If supplied, the buffer manager through which copies should be made + @remarks The caller is expected to delete the returned pointer when ready + */ + VertexData* clone(bool copyData = true, HardwareBufferManagerBase* mgr = 0) const; /** Modifies the vertex data to be suitable for use for rendering shadow geometry. @remarks @@ -146,45 +146,45 @@ namespace Ogre { HardwareVertexBufferSharedPtr hardwareShadowVolWBuffer; - /** Reorganises the data in the vertex buffers according to the - new vertex declaration passed in. Note that new vertex buffers - are created and written to, so if the buffers being referenced - by this vertex data object are also used by others, then the - original buffers will not be damaged by this operation. - Once this operation has completed, the new declaration - passed in will overwrite the current one. - @param newDeclaration The vertex declaration which will be used - for the reorganised buffer state. Note that the new declaration - must not include any elements which do not already exist in the - current declaration; you can drop elements by - excluding them from the declaration if you wish, however. - @param bufferUsage Vector of usage flags which indicate the usage options - for each new vertex buffer created. The indexes of the entries must correspond - to the buffer binding values referenced in the declaration. - @param mgr Optional pointer to the manager to use to create new declarations - and buffers etc. If not supplied, the HardwareBufferManager singleton will be used - */ - void reorganiseBuffers(VertexDeclaration* newDeclaration, const BufferUsageList& bufferUsage, - HardwareBufferManagerBase* mgr = 0); - - /** Reorganises the data in the vertex buffers according to the - new vertex declaration passed in. Note that new vertex buffers - are created and written to, so if the buffers being referenced - by this vertex data object are also used by others, then the - original buffers will not be damaged by this operation. - Once this operation has completed, the new declaration - passed in will overwrite the current one. + /** Reorganises the data in the vertex buffers according to the + new vertex declaration passed in. Note that new vertex buffers + are created and written to, so if the buffers being referenced + by this vertex data object are also used by others, then the + original buffers will not be damaged by this operation. + Once this operation has completed, the new declaration + passed in will overwrite the current one. + @param newDeclaration The vertex declaration which will be used + for the reorganised buffer state. Note that the new declaration + must not include any elements which do not already exist in the + current declaration; you can drop elements by + excluding them from the declaration if you wish, however. + @param bufferUsage Vector of usage flags which indicate the usage options + for each new vertex buffer created. The indexes of the entries must correspond + to the buffer binding values referenced in the declaration. + @param mgr Optional pointer to the manager to use to create new declarations + and buffers etc. If not supplied, the HardwareBufferManager singleton will be used + */ + void reorganiseBuffers(VertexDeclaration* newDeclaration, const BufferUsageList& bufferUsage, + HardwareBufferManagerBase* mgr = 0); + + /** Reorganises the data in the vertex buffers according to the + new vertex declaration passed in. Note that new vertex buffers + are created and written to, so if the buffers being referenced + by this vertex data object are also used by others, then the + original buffers will not be damaged by this operation. + Once this operation has completed, the new declaration + passed in will overwrite the current one. This version of the method derives the buffer usages from the existing buffers, by using the 'most flexible' usage from the equivalent sources. - @param newDeclaration The vertex declaration which will be used - for the reorganised buffer state. Note that the new delcaration - must not include any elements which do not already exist in the - current declaration; you can drop elements by - excluding them from the declaration if you wish, however. - @param mgr Optional pointer to the manager to use to create new declarations - and buffers etc. If not supplied, the HardwareBufferManager singleton will be used - */ - void reorganiseBuffers(VertexDeclaration* newDeclaration, HardwareBufferManagerBase* mgr = 0); + @param newDeclaration The vertex declaration which will be used + for the reorganised buffer state. Note that the new delcaration + must not include any elements which do not already exist in the + current declaration; you can drop elements by + excluding them from the declaration if you wish, however. + @param mgr Optional pointer to the manager to use to create new declarations + and buffers etc. If not supplied, the HardwareBufferManager singleton will be used + */ + void reorganiseBuffers(VertexDeclaration* newDeclaration, HardwareBufferManagerBase* mgr = 0); /** Remove any gaps in the vertex buffer bindings. @remarks @@ -207,40 +207,40 @@ namespace Ogre { */ void removeUnusedBuffers(void); - /** Convert all packed colour values (VET_COLOUR_*) in buffers used to - another type. - @param srcType The source colour type to assume if the ambiguous VET_COLOUR - is encountered. - @param destType The destination colour type, must be VET_COLOUR_ABGR or - VET_COLOUR_ARGB. - */ - void convertPackedColour(VertexElementType srcType, VertexElementType destType); - - - /** Allocate elements to serve a holder of morph / pose target data - for hardware morphing / pose blending. - @remarks - This method will allocate the given number of 3D texture coordinate - sets for use as a morph target or target pose offset (3D position). - These elements will be saved in hwAnimationDataList. - It will also assume that the source of these new elements will be new - buffers which are not bound at this time, so will start the sources to - 1 higher than the current highest binding source. The caller is - expected to bind these new buffers when appropriate. For morph animation - the original position buffer will be the 'from' keyframe data, whilst - for pose animation it will be the original vertex data. - If normals are animated, then twice the number of 3D texture coordinates are required - @return The number of sets that were supported - */ - ushort allocateHardwareAnimationElements(ushort count, bool animateNormals); - - - - }; - - /** Summary class collecting together index data source information. */ - class _OgreExport IndexData : public IndexDataAlloc - { + /** Convert all packed colour values (VET_COLOUR_*) in buffers used to + another type. + @param srcType The source colour type to assume if the ambiguous VET_COLOUR + is encountered. + @param destType The destination colour type, must be VET_COLOUR_ABGR or + VET_COLOUR_ARGB. + */ + void convertPackedColour(VertexElementType srcType, VertexElementType destType); + + + /** Allocate elements to serve a holder of morph / pose target data + for hardware morphing / pose blending. + @remarks + This method will allocate the given number of 3D texture coordinate + sets for use as a morph target or target pose offset (3D position). + These elements will be saved in hwAnimationDataList. + It will also assume that the source of these new elements will be new + buffers which are not bound at this time, so will start the sources to + 1 higher than the current highest binding source. The caller is + expected to bind these new buffers when appropriate. For morph animation + the original position buffer will be the 'from' keyframe data, whilst + for pose animation it will be the original vertex data. + If normals are animated, then twice the number of 3D texture coordinates are required + @return The number of sets that were supported + */ + ushort allocateHardwareAnimationElements(ushort count, bool animateNormals); + + + + }; + + /** Summary class collecting together index data source information. */ + class _OgreExport IndexData : public IndexDataAlloc + { protected: /// Protected copy constructor, to prevent misuse IndexData(const IndexData& rhs); /* do nothing, should not use */ @@ -249,75 +249,75 @@ namespace Ogre { public: IndexData(); ~IndexData(); - /// Pointer to the HardwareIndexBuffer to use, must be specified if useIndexes = true - HardwareIndexBufferSharedPtr indexBuffer; - - /// Index in the buffer to start from for this operation - size_t indexStart; - - /// The number of indexes to use from the buffer - size_t indexCount; - - /** Clones this index data, potentially including replicating the index buffer. - @param copyData Whether to create new buffers too or just reference the existing ones - @param mgr If supplied, the buffer manager through which copies should be made - @remarks The caller is expected to delete the returned pointer when finished - */ - IndexData* clone(bool copyData = true, HardwareBufferManagerBase* mgr = 0) const; - - /** Re-order the indexes in this index data structure to be more - vertex cache friendly; that is to re-use the same vertices as close - together as possible. - @remarks - Can only be used for index data which consists of triangle lists. - It would in fact be pointless to use it on triangle strips or fans - in any case. - */ - void optimiseVertexCacheTriList(void); - - }; - - /** Vertex cache profiler. - @remarks - Utility class for evaluating the effectiveness of the use of the vertex - cache by a given index buffer. - */ - class _OgreExport VertexCacheProfiler : public BufferAlloc + /// Pointer to the HardwareIndexBuffer to use, must be specified if useIndexes = true + HardwareIndexBufferSharedPtr indexBuffer; + + /// Index in the buffer to start from for this operation + size_t indexStart; + + /// The number of indexes to use from the buffer + size_t indexCount; + + /** Clones this index data, potentially including replicating the index buffer. + @param copyData Whether to create new buffers too or just reference the existing ones + @param mgr If supplied, the buffer manager through which copies should be made + @remarks The caller is expected to delete the returned pointer when finished + */ + IndexData* clone(bool copyData = true, HardwareBufferManagerBase* mgr = 0) const; + + /** Re-order the indexes in this index data structure to be more + vertex cache friendly; that is to re-use the same vertices as close + together as possible. + @remarks + Can only be used for index data which consists of triangle lists. + It would in fact be pointless to use it on triangle strips or fans + in any case. + */ + void optimiseVertexCacheTriList(void); + + }; + + /** Vertex cache profiler. + @remarks + Utility class for evaluating the effectiveness of the use of the vertex + cache by a given index buffer. + */ + class _OgreExport VertexCacheProfiler : public BufferAlloc { - public: - enum CacheType { - FIFO, LRU - }; - - VertexCacheProfiler(unsigned int cachesize = 16, CacheType cachetype = FIFO ) - : size ( cachesize ), tail (0), buffersize (0), hit (0), miss (0) - { - cache = OGRE_ALLOC_T(uint32, size, MEMCATEGORY_GEOMETRY); - } - - ~VertexCacheProfiler() - { - OGRE_FREE(cache, MEMCATEGORY_GEOMETRY); - } - - void profile(const HardwareIndexBufferSharedPtr& indexBuffer); - void reset() { hit = 0; miss = 0; tail = 0; buffersize = 0; } - void flush() { tail = 0; buffersize = 0; } - - unsigned int getHits() { return hit; } - unsigned int getMisses() { return miss; } - unsigned int getSize() { return size; } - private: - unsigned int size; - uint32 *cache; - - unsigned int tail, buffersize; - unsigned int hit, miss; - - bool inCache(unsigned int index); - }; - /** @} */ - /** @} */ + public: + enum CacheType { + FIFO, LRU + }; + + VertexCacheProfiler(unsigned int cachesize = 16, CacheType cachetype = FIFO ) + : size ( cachesize ), tail (0), buffersize (0), hit (0), miss (0) + { + cache = OGRE_ALLOC_T(uint32, size, MEMCATEGORY_GEOMETRY); + } + + ~VertexCacheProfiler() + { + OGRE_FREE(cache, MEMCATEGORY_GEOMETRY); + } + + void profile(const HardwareIndexBufferSharedPtr& indexBuffer); + void reset() { hit = 0; miss = 0; tail = 0; buffersize = 0; } + void flush() { tail = 0; buffersize = 0; } + + unsigned int getHits() { return hit; } + unsigned int getMisses() { return miss; } + unsigned int getSize() { return size; } + private: + unsigned int size; + uint32 *cache; + + unsigned int tail, buffersize; + unsigned int hit, miss; + + bool inCache(unsigned int index); + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreViewport.h b/OgreMain/include/OgreViewport.h index fda0ed840f6..bf15f4aadfc 100644 --- a/OgreMain/include/OgreViewport.h +++ b/OgreMain/include/OgreViewport.h @@ -34,13 +34,13 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** An abstraction of a viewport, i.e. a rendering region on a render + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** An abstraction of a viewport, i.e. a rendering region on a render target. @remarks A viewport is the meeting of a camera and a rendering surface - @@ -53,24 +53,24 @@ namespace Ogre { viewport on a single render target and they overlap, one must obscure the other in some predetermined way. */ - class _OgreExport Viewport : public ViewportAlloc + class _OgreExport Viewport : public ViewportAlloc { public: - /** Listener interface so you can be notified of Viewport changes. */ - class _OgreExport Listener - { - public: - virtual ~Listener() {} + /** Listener interface so you can be notified of Viewport changes. */ + class _OgreExport Listener + { + public: + virtual ~Listener() {} - /** Notification of when a new camera is set to target listening Viewport. */ - virtual void viewportCameraChanged(Viewport* viewport) {} + /** Notification of when a new camera is set to target listening Viewport. */ + virtual void viewportCameraChanged(Viewport* viewport) {} - /** Notification of when target listening Viewport's dimensions changed. */ - virtual void viewportDimensionsChanged(Viewport* viewport) {} + /** Notification of when target listening Viewport's dimensions changed. */ + virtual void viewportDimensionsChanged(Viewport* viewport) {} - /** Notification of when target listening Viewport's is destroyed. */ - virtual void viewportDestroyed(Viewport* viewport) {} - }; + /** Notification of when target listening Viewport's is destroyed. */ + virtual void viewportDestroyed(Viewport* viewport) {} + }; /** The usual constructor. @param camera @@ -110,22 +110,22 @@ namespace Ogre { /** Instructs the viewport to updates its contents. */ void update(void); - - /** Instructs the viewport to clear itself, without performing an update. - @remarks - You would not normally call this method when updating the viewport, - since the viewport usually clears itself when updating anyway (@see - Viewport::setClearEveryFrame). However, if you wish you have the - option of manually clearing the frame buffer (or elements of it) - using this method. - @param buffers Bitmask identifying which buffer elements to clear - @param colour The colour value to clear to, if FBT_COLOUR is included - @param depth The depth value to clear to, if FBT_DEPTH is included - @param stencil The stencil value to clear to, if FBT_STENCIL is included - */ - void clear(unsigned int buffers = FBT_COLOUR | FBT_DEPTH, - const ColourValue& colour = ColourValue::Black, - Real depth = 1.0f, unsigned short stencil = 0); + + /** Instructs the viewport to clear itself, without performing an update. + @remarks + You would not normally call this method when updating the viewport, + since the viewport usually clears itself when updating anyway (@see + Viewport::setClearEveryFrame). However, if you wish you have the + option of manually clearing the frame buffer (or elements of it) + using this method. + @param buffers Bitmask identifying which buffer elements to clear + @param colour The colour value to clear to, if FBT_COLOUR is included + @param depth The depth value to clear to, if FBT_DEPTH is included + @param stencil The stencil value to clear to, if FBT_STENCIL is included + */ + void clear(unsigned int buffers = FBT_COLOUR | FBT_DEPTH, + const ColourValue& colour = ColourValue::Black, + Real depth = 1.0f, unsigned short stencil = 0); /** Retrieves a pointer to the render target for this viewport. */ @@ -139,8 +139,8 @@ namespace Ogre { void setCamera(Camera* cam); /** Gets the Z-Order of this viewport. */ - int getZOrder(void) const; - /** Gets one of the relative dimensions of the viewport, + int getZOrder(void) const; + /** Gets one of the relative dimensions of the viewport, a value between 0.0 and 1.0. */ Real getLeft(void) const; @@ -220,7 +220,7 @@ namespace Ogre { */ const ColourValue& getBackgroundColour(void) const; - /** Sets the initial depth buffer value of the viewport (before + /** Sets the initial depth buffer value of the viewport (before rendering). Default is 1 */ void setDepthClear( Real depth ); @@ -230,13 +230,13 @@ namespace Ogre { Real getDepthClear(void) const; /** Determines whether to clear the viewport before rendering. - @remarks - You can use this method to set which buffers are cleared - (if any) before rendering every frame. + @remarks + You can use this method to set which buffers are cleared + (if any) before rendering every frame. @param clear Whether or not to clear any buffers - @param buffers One or more values from FrameBufferType denoting - which buffers to clear, if clear is set to true. Note you should - not clear the stencil buffer here unless you know what you're doing. + @param buffers One or more values from FrameBufferType denoting + which buffers to clear, if clear is set to true. Note you should + not clear the stencil buffer here unless you know what you're doing. */ void setClearEveryFrame(bool clear, unsigned int buffers = FBT_COLOUR | FBT_DEPTH); @@ -244,42 +244,42 @@ namespace Ogre { */ bool getClearEveryFrame(void) const; - /** Gets which buffers are to be cleared each frame. */ + /** Gets which buffers are to be cleared each frame. */ unsigned int getClearBuffers(void) const; - /** Sets whether this viewport should be automatically updated - if Ogre's rendering loop or RenderTarget::update is being used. + /** Sets whether this viewport should be automatically updated + if Ogre's rendering loop or RenderTarget::update is being used. @remarks By default, if you use Ogre's own rendering loop (Root::startRendering) or call RenderTarget::update, all viewports are updated automatically. This method allows you to control that behaviour, if for example you - have a viewport which you only want to update periodically. + have a viewport which you only want to update periodically. @param autoupdate If true, the viewport is updated during the automatic render loop or when RenderTarget::update() is called. If false, the viewport is only updated when its update() method is called explicitly. */ - void setAutoUpdated(bool autoupdate); - /** Gets whether this viewport is automatically updated if - Ogre's rendering loop or RenderTarget::update is being used. - */ - bool isAutoUpdated() const; - - /** Set the material scheme which the viewport should use. - @remarks - This allows you to tell the system to use a particular - material scheme when rendering this viewport, which can - involve using different techniques to render your materials. - @see Technique::setSchemeName - */ - void setMaterialScheme(const String& schemeName) - { mMaterialSchemeName = schemeName; } - - /** Get the material scheme which the viewport should use. - */ - const String& getMaterialScheme(void) const - { return mMaterialSchemeName; } - - /** Access to actual dimensions (based on target size). + void setAutoUpdated(bool autoupdate); + /** Gets whether this viewport is automatically updated if + Ogre's rendering loop or RenderTarget::update is being used. + */ + bool isAutoUpdated() const; + + /** Set the material scheme which the viewport should use. + @remarks + This allows you to tell the system to use a particular + material scheme when rendering this viewport, which can + involve using different techniques to render your materials. + @see Technique::setSchemeName + */ + void setMaterialScheme(const String& schemeName) + { mMaterialSchemeName = schemeName; } + + /** Get the material scheme which the viewport should use. + */ + const String& getMaterialScheme(void) const + { return mMaterialSchemeName; } + + /** Access to actual dimensions (based on target size). */ void getActualDimensions( int &left, int &top, int &width, int &height ) const; @@ -330,9 +330,9 @@ namespace Ogre { /** Tells this viewport whether it should display shadows. @remarks This setting enables you to disable shadow rendering for a given viewport. The global - shadow technique set on SceneManager still controls the type and nature of shadows, - but this flag can override the setting so that no shadows are rendered for a given - viewport to save processing time where they are not required. + shadow technique set on SceneManager still controls the type and nature of shadows, + but this flag can override the setting so that no shadows are rendered for a given + viewport to save processing time where they are not required. @param enabled If true, any shadows are displayed, if false they are not. */ void setShadowsEnabled(bool enabled); @@ -342,48 +342,48 @@ namespace Ogre { bool getShadowsEnabled(void) const; - /** Sets a per-viewport visibility mask. - @remarks - The visibility mask is a way to exclude objects from rendering for - a given viewport. For each object in the frustum, a check is made - between this mask and the objects visibility flags - (@see MovableObject::setVisibilityFlags), and if a binary 'and' - returns zero, the object will not be rendered. - */ - void setVisibilityMask(uint32 mask) { mVisibilityMask = mask; } - - /** Gets a per-viewport visibility mask. - @see Viewport::setVisibilityMask - */ - uint getVisibilityMask(void) const { return mVisibilityMask; } - - /** Sets the use of a custom RenderQueueInvocationSequence for - rendering this target. - @remarks - RenderQueueInvocationSequence instances are managed through Root. By - setting this, you are indicating that you wish this RenderTarget to - be updated using a custom sequence of render queue invocations, with - potentially customised ordering and render state options. You should - create the named sequence through Root first, then set the name here. - @param sequenceName The name of the RenderQueueInvocationSequence to use. If you - specify a blank string, behaviour will return to the default render - queue management. - */ - virtual void setRenderQueueInvocationSequenceName(const String& sequenceName); - /** Gets the name of the render queue invocation sequence for this target. */ - virtual const String& getRenderQueueInvocationSequenceName(void) const; - /// Get the invocation sequence - will return null if using standard - RenderQueueInvocationSequence* _getRenderQueueInvocationSequence(void); + /** Sets a per-viewport visibility mask. + @remarks + The visibility mask is a way to exclude objects from rendering for + a given viewport. For each object in the frustum, a check is made + between this mask and the objects visibility flags + (@see MovableObject::setVisibilityFlags), and if a binary 'and' + returns zero, the object will not be rendered. + */ + void setVisibilityMask(uint32 mask) { mVisibilityMask = mask; } + + /** Gets a per-viewport visibility mask. + @see Viewport::setVisibilityMask + */ + uint getVisibilityMask(void) const { return mVisibilityMask; } + + /** Sets the use of a custom RenderQueueInvocationSequence for + rendering this target. + @remarks + RenderQueueInvocationSequence instances are managed through Root. By + setting this, you are indicating that you wish this RenderTarget to + be updated using a custom sequence of render queue invocations, with + potentially customised ordering and render state options. You should + create the named sequence through Root first, then set the name here. + @param sequenceName The name of the RenderQueueInvocationSequence to use. If you + specify a blank string, behaviour will return to the default render + queue management. + */ + virtual void setRenderQueueInvocationSequenceName(const String& sequenceName); + /** Gets the name of the render queue invocation sequence for this target. */ + virtual const String& getRenderQueueInvocationSequenceName(void) const; + /// Get the invocation sequence - will return null if using standard + RenderQueueInvocationSequence* _getRenderQueueInvocationSequence(void); /** Convert oriented input point coordinates to screen coordinates. */ void pointOrientedToScreen(const Vector2 &v, int orientationMode, Vector2 &outv); void pointOrientedToScreen(Real orientedX, Real orientedY, int orientationMode, Real &screenX, Real &screenY); - /// Add a listener to this viewport - void addListener(Listener* l); - /// Remove a listener to this viewport - void removeListener(Listener* l); + /// Add a listener to this viewport + void addListener(Listener* l); + /// Remove a listener to this viewport + void removeListener(Listener* l); protected: Camera* mCamera; @@ -396,31 +396,31 @@ namespace Ogre { int mZOrder; /// Background options ColourValue mBackColour; - Real mDepthClearValue; + Real mDepthClearValue; bool mClearEveryFrame; - unsigned int mClearBuffers; + unsigned int mClearBuffers; bool mUpdated; bool mShowOverlays; bool mShowSkies; - bool mShowShadows; - uint32 mVisibilityMask; - // Render queue invocation sequence name - String mRQSequenceName; - RenderQueueInvocationSequence* mRQSequence; - /// Material scheme - String mMaterialSchemeName; + bool mShowShadows; + uint32 mVisibilityMask; + // Render queue invocation sequence name + String mRQSequenceName; + RenderQueueInvocationSequence* mRQSequence; + /// Material scheme + String mMaterialSchemeName; /// Viewport orientation mode OrientationMode mOrientationMode; static OrientationMode mDefaultOrientationMode; - /// Automatic rendering on/off - bool mIsAutoUpdated; + /// Automatic rendering on/off + bool mIsAutoUpdated; - typedef vector::type ListenerList; - ListenerList mListeners; + typedef vector::type ListenerList; + ListenerList mListeners; }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreWindowEventUtilities.h b/OgreMain/include/OgreWindowEventUtilities.h index 4af76c0a14f..bd2a74a3b3f 100644 --- a/OgreMain/include/OgreWindowEventUtilities.h +++ b/OgreMain/include/OgreWindowEventUtilities.h @@ -38,7 +38,7 @@ THE SOFTWARE. # define WIN32_LEAN_AND_MEAN # endif # if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif # include #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined(__LP64__) @@ -49,141 +49,141 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup RenderSystem - * @{ - */ - /** - @remarks - Callback class used to send out window events to client app - */ - class _OgreExport WindowEventListener - { - public: - virtual ~WindowEventListener() {} - - /** - @remarks - Window has moved position - @param rw - The RenderWindow which created this events - */ - virtual void windowMoved(RenderWindow* rw) + /** \addtogroup Core + * @{ + */ + /** \addtogroup RenderSystem + * @{ + */ + /** + @remarks + Callback class used to send out window events to client app + */ + class _OgreExport WindowEventListener + { + public: + virtual ~WindowEventListener() {} + + /** + @remarks + Window has moved position + @param rw + The RenderWindow which created this events + */ + virtual void windowMoved(RenderWindow* rw) { (void)rw; } - /** - @remarks - Window has resized - @param rw - The RenderWindow which created this events - */ - virtual void windowResized(RenderWindow* rw) + /** + @remarks + Window has resized + @param rw + The RenderWindow which created this events + */ + virtual void windowResized(RenderWindow* rw) { (void)rw; } - /** - @remarks - Window is closing (Only triggered if user pressed the [X] button) - @param rw - The RenderWindow which created this events - @return True will close the window(default). - */ - virtual bool windowClosing(RenderWindow* rw) - { (void)rw; return true; } - - /** - @remarks - Window has been closed (Only triggered if user pressed the [X] button) - @param rw - The RenderWindow which created this events - @note - The window has not actually close yet when this event triggers. It's only closed after - all windowClosed events are triggered. This allows apps to deinitialise properly if they - have services that needs the window to exist when deinitialising. - */ - virtual void windowClosed(RenderWindow* rw) + /** + @remarks + Window is closing (Only triggered if user pressed the [X] button) + @param rw + The RenderWindow which created this events + @return True will close the window(default). + */ + virtual bool windowClosing(RenderWindow* rw) + { (void)rw; return true; } + + /** + @remarks + Window has been closed (Only triggered if user pressed the [X] button) + @param rw + The RenderWindow which created this events + @note + The window has not actually close yet when this event triggers. It's only closed after + all windowClosed events are triggered. This allows apps to deinitialise properly if they + have services that needs the window to exist when deinitialising. + */ + virtual void windowClosed(RenderWindow* rw) { (void)rw; } - /** - @remarks - Window has lost/gained focus - @param rw - The RenderWindow which created this events - */ - virtual void windowFocusChange(RenderWindow* rw) + /** + @remarks + Window has lost/gained focus + @param rw + The RenderWindow which created this events + */ + virtual void windowFocusChange(RenderWindow* rw) { (void)rw; } - }; - - /** - @remarks - Utility class to handle Window Events/Pumping/Messages - */ - class _OgreExport WindowEventUtilities - { - public: - /** - @remarks - Call this once per frame if not using Root:startRendering(). This will update all registered - RenderWindows (If using external Windows, you can optionally register those yourself) - */ - static void messagePump(); - - /** - @remarks - Add a listener to listen to renderwindow events (multiple listener's per renderwindow is fine) - The same listener can listen to multiple windows, as the Window Pointer is sent along with - any messages. - @param window - The RenderWindow you are interested in monitoring - @param listener - Your callback listener - */ - static void addWindowEventListener( RenderWindow* window, WindowEventListener* listener ); - - /** - @remarks - Remove previously added listener - @param window - The RenderWindow you registered with - @param listener - The listener registered - */ - static void removeWindowEventListener( RenderWindow* window, WindowEventListener* listener ); - - /** - @remarks - Called by RenderWindows upon creation for Ogre generated windows. You are free to add your - external windows here too if needed. - @param window - The RenderWindow to monitor - */ - static void _addRenderWindow(RenderWindow* window); - - /** - @remarks - Called by RenderWindows upon creation for Ogre generated windows. You are free to add your - external windows here too if needed. - @param window - The RenderWindow to remove from list - */ - static void _removeRenderWindow(RenderWindow* window); + }; + + /** + @remarks + Utility class to handle Window Events/Pumping/Messages + */ + class _OgreExport WindowEventUtilities + { + public: + /** + @remarks + Call this once per frame if not using Root:startRendering(). This will update all registered + RenderWindows (If using external Windows, you can optionally register those yourself) + */ + static void messagePump(); + + /** + @remarks + Add a listener to listen to renderwindow events (multiple listener's per renderwindow is fine) + The same listener can listen to multiple windows, as the Window Pointer is sent along with + any messages. + @param window + The RenderWindow you are interested in monitoring + @param listener + Your callback listener + */ + static void addWindowEventListener( RenderWindow* window, WindowEventListener* listener ); + + /** + @remarks + Remove previously added listener + @param window + The RenderWindow you registered with + @param listener + The listener registered + */ + static void removeWindowEventListener( RenderWindow* window, WindowEventListener* listener ); + + /** + @remarks + Called by RenderWindows upon creation for Ogre generated windows. You are free to add your + external windows here too if needed. + @param window + The RenderWindow to monitor + */ + static void _addRenderWindow(RenderWindow* window); + + /** + @remarks + Called by RenderWindows upon creation for Ogre generated windows. You are free to add your + external windows here too if needed. + @param window + The RenderWindow to remove from list + */ + static void _removeRenderWindow(RenderWindow* window); #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - //! Internal winProc (RenderWindow's use this when creating the Win32 Window) - static LRESULT CALLBACK _WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + //! Internal winProc (RenderWindow's use this when creating the Win32 Window) + static LRESULT CALLBACK _WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined(__LP64__) //! Internal UPP Window Handler (RenderWindow's use this when creating the OS X Carbon Window static OSStatus _CarbonWindowHandler(EventHandlerCallRef nextHandler, EventRef event, void* wnd); #endif - //These are public only so GLXProc can access them without adding Xlib headers header - typedef multimap::type WindowEventListeners; - static WindowEventListeners _msListeners; - static RenderWindowList _msWindows; - }; - /** @} */ - /** @} */ + //These are public only so GLXProc can access them without adding Xlib headers header + typedef multimap::type WindowEventListeners; + static WindowEventListeners _msListeners; + static RenderWindowList _msWindows; + }; + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/OgreWireBoundingBox.h b/OgreMain/include/OgreWireBoundingBox.h index 70296892511..34f3aefc726 100644 --- a/OgreMain/include/OgreWireBoundingBox.h +++ b/OgreMain/include/OgreWireBoundingBox.h @@ -34,51 +34,51 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Scene - * @{ - */ - /** Allows the rendering of a wireframe bounding box. + /** \addtogroup Core + * @{ + */ + /** \addtogroup Scene + * @{ + */ + /** Allows the rendering of a wireframe bounding box. @remarks This class builds a wireframe renderable from a given aabb. A pointer to this class can be - added to a render queue to display the bounding box of an object. + added to a render queue to display the bounding box of an object. */ - class _OgreExport WireBoundingBox : public SimpleRenderable - { + class _OgreExport WireBoundingBox : public SimpleRenderable + { protected: /** Override this method to prevent parent transforms (rotation,translation,scale) */ - void getWorldTransforms( Matrix4* xform ) const; - + void getWorldTransforms( Matrix4* xform ) const; + /** Builds the wireframe line list. */ - void setupBoundingBoxVertices(const AxisAlignedBox& aab); + void setupBoundingBoxVertices(const AxisAlignedBox& aab); Real mRadius; - void _initWireBoundingBox(); + void _initWireBoundingBox(); - public: - - WireBoundingBox(); - WireBoundingBox(const String& name); - ~WireBoundingBox(); + public: + + WireBoundingBox(); + WireBoundingBox(const String& name); + ~WireBoundingBox(); /** Builds the wireframe line list. @param aabb bounding box to build a wireframe from. */ - void setupBoundingBox(const AxisAlignedBox& aabb); + void setupBoundingBox(const AxisAlignedBox& aabb); - Real getSquaredViewDepth(const Camera* cam) const; + Real getSquaredViewDepth(const Camera* cam) const; Real getBoundingRadius(void) const { return mRadius; } - }; - /** @} */ - /** @} */ + }; + /** @} */ + /** @} */ }// namespace diff --git a/OgreMain/include/OgreWorkQueue.h b/OgreMain/include/OgreWorkQueue.h index 3e7e33ac313..25410e6b148 100644 --- a/OgreMain/include/OgreWorkQueue.h +++ b/OgreMain/include/OgreWorkQueue.h @@ -37,548 +37,548 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - - /** Interface to a general purpose request / response style background work queue. - @remarks - A work queue is a simple structure, where requests for work are placed - onto the queue, then removed by a worker for processing, then finally - a response is placed on the result queue for the originator to pick up - at their leisure. The typical use for this is in a threaded environment, - although any kind of deferred processing could use this approach to - decouple and distribute work over a period of time even - if it was single threaded. - @par - WorkQueues also incorporate thread pools. One or more background worker threads - can wait on the queue and be notified when a request is waiting to be - processed. For maximal thread usage, a WorkQueue instance should be shared - among many sources of work, rather than many work queues being created. - This way, you can share a small number of hardware threads among a large - number of background tasks. This doesn't mean you have to implement all the - request processing in one class, you can plug in many handlers in order to - process the requests. - @par - This is an abstract interface definition; users can subclass this and - provide their own implementation if required to centralise task management - in their own subsystems. We also provide a default implementation in the - form of DefaultWorkQueue. - */ - class _OgreExport WorkQueue : public UtilityAlloc - { - protected: - typedef map::type ChannelMap; - ChannelMap mChannelMap; - uint16 mNextChannel; - OGRE_MUTEX(mChannelMapMutex); - public: - /// Numeric identifier for a request - typedef unsigned long long int RequestID; - - /** General purpose request structure. - */ - class _OgreExport Request : public UtilityAlloc - { - friend class WorkQueue; - protected: - /// The request channel, as an integer - uint16 mChannel; - /// The request type, as an integer within the channel (user can define enumerations on this) - uint16 mType; - /// The details of the request (user defined) - Any mData; - /// Retry count - set this to non-zero to have the request try again on failure - uint8 mRetryCount; - /// Identifier (assigned by the system) - RequestID mID; - /// Abort Flag - mutable bool mAborted; - - public: - /// Constructor - Request(uint16 channel, uint16 rtype, const Any& rData, uint8 retry, RequestID rid); - ~Request(); - /// Set the abort flag - void abortRequest() const { mAborted = true; } - /// Get the request channel (top level categorisation) - uint16 getChannel() const { return mChannel; } - /// Get the type of this request within the given channel - uint16 getType() const { return mType; } - /// Get the user details of this request - const Any& getData() const { return mData; } - /// Get the remaining retry count - uint8 getRetryCount() const { return mRetryCount; } - /// Get the identifier of this request - RequestID getID() const { return mID; } - /// Get the abort flag - bool getAborted() const { return mAborted; } - }; - - /** General purpose response structure. - */ - struct _OgreExport Response : public UtilityAlloc - { - /// Pointer to the request that this response is in relation to - const Request* mRequest; - /// Whether the work item succeeded or not - bool mSuccess; - /// Any diagnostic messages - String mMessages; - /// Data associated with the result of the process - Any mData; - - public: - Response(const Request* rq, bool success, const Any& data, const String& msg = BLANKSTRING); - ~Response(); - /// Get the request that this is a response to (NB destruction destroys this) - const Request* getRequest() const { return mRequest; } - /// Return whether this is a successful response - bool succeeded() const { return mSuccess; } - /// Get any diagnostic messages about the process - const String& getMessages() const { return mMessages; } - /// Return the response data (user defined, only valid on success) - const Any& getData() const { return mData; } - /// Abort the request - void abortRequest() { mRequest->abortRequest(); mData.destroy(); } - }; - - /** Interface definition for a handler of requests. - @remarks - User classes are expected to implement this interface in order to - process requests on the queue. It's important to realise that - the calls to this class may be in a separate thread to the main - render context, and as such it may not be possible to make - rendersystem or other GPU-dependent calls in this handler. You can only - do so if the queue was created with 'workersCanAccessRenderSystem' - set to true, and OGRE_THREAD_SUPPORT=1, but this puts extra strain - on the thread safety of the render system and is not recommended. - It is best to perform CPU-side work in these handlers and let the - response handler transfer results to the GPU in the main render thread. - */ - class _OgreExport RequestHandler - { - public: - RequestHandler() {} - virtual ~RequestHandler() {} - - /** Return whether this handler can process a given request. - @remarks - Defaults to true, but if you wish to add several handlers each of - which deal with different types of request, you can override - this method. - */ - virtual bool canHandleRequest(const Request* req, const WorkQueue* srcQ) - { (void)srcQ; return !req->getAborted(); } - - /** The handler method every subclass must implement. - If a failure is encountered, return a Response with a failure - result rather than raise an exception. - @param req The Request structure, which is effectively owned by the - handler during this call. It must be attached to the returned - Response regardless of success or failure. - @param srcQ The work queue that this request originated from - @return Pointer to a Response object - the caller is responsible - for deleting the object. - */ - virtual Response* handleRequest(const Request* req, const WorkQueue* srcQ) = 0; - }; - - /** Interface definition for a handler of responses. - @remarks - User classes are expected to implement this interface in order to - process responses from the queue. All calls to this class will be - in the main render thread and thus all GPU resources will be - available. - */ - class _OgreExport ResponseHandler - { - public: - ResponseHandler() {} - virtual ~ResponseHandler() {} - - /** Return whether this handler can process a given response. - @remarks - Defaults to true, but if you wish to add several handlers each of - which deal with different types of response, you can override - this method. - */ - virtual bool canHandleResponse(const Response* res, const WorkQueue* srcQ) - { (void)srcQ; return !res->getRequest()->getAborted(); } - - /** The handler method every subclass must implement. - @param res The Response structure. The caller is responsible for - deleting this after the call is made, none of the data contained - (except pointers to structures in user Any data) will persist - after this call is returned. - @param srcQ The work queue that this request originated from - */ - virtual void handleResponse(const Response* res, const WorkQueue* srcQ) = 0; - }; - - WorkQueue() : mNextChannel(0) {} - virtual ~WorkQueue() {} - - /** Start up the queue with the options that have been set. - @param forceRestart If the queue is already running, whether to shut it - down and restart. - */ - virtual void startup(bool forceRestart = true) = 0; - /** Add a request handler instance to the queue. - @remarks - Every queue must have at least one request handler instance for each - channel in which requests are raised. If you - add more than one handler per channel, then you must implement canHandleRequest - differently in each if you wish them to respond to different requests. - @param channel The channel for requests you want to handle - @param rh Your handler - */ - virtual void addRequestHandler(uint16 channel, RequestHandler* rh) = 0; - /** Remove a request handler. */ - virtual void removeRequestHandler(uint16 channel, RequestHandler* rh) = 0; - - /** Add a response handler instance to the queue. - @remarks - Every queue must have at least one response handler instance for each - channel in which requests are raised. If you add more than one, then you - must implement canHandleResponse differently in each if you wish them - to respond to different responses. - @param channel The channel for responses you want to handle - @param rh Your handler - */ - virtual void addResponseHandler(uint16 channel, ResponseHandler* rh) = 0; - /** Remove a Response handler. */ - virtual void removeResponseHandler(uint16 channel, ResponseHandler* rh) = 0; - - /** Add a new request to the queue. - @param channel The channel this request will go into = 0; the channel is the top-level - categorisation of the request - @param requestType An identifier that's unique within this queue which - identifies the type of the request (user decides the actual value) - @param rData The data required by the request process. - @param retryCount The number of times the request should be retried - if it fails. - @param forceSynchronous Forces the request to be processed immediately - even if threading is enabled. - @param idleThread Request should be processed on the idle thread. - Idle requests will be processed on a single worker thread. You should use this in the following situations: - 1. If a request handler can't process multiple requests in parallel. - 2. If you add lot of requests, but you want to keep the game fast. - 3. If you have lot of more important threads. (example: physics). - @return The ID of the request that has been added - */ - virtual RequestID addRequest(uint16 channel, uint16 requestType, const Any& rData, uint8 retryCount = 0, - bool forceSynchronous = false, bool idleThread = false) = 0; - - /** Abort a previously issued request. - If the request is still waiting to be processed, it will be - removed from the queue. - @param id The ID of the previously issued request. - */ - virtual void abortRequest(RequestID id) = 0; - - /** Abort all previously issued requests in a given channel. - Any requests still waiting to be processed of the given channel, will be - removed from the queue. - Requests which are processed, but response handler is not called will also be removed. - @param channel The type of request to be aborted - */ - virtual void abortRequestsByChannel(uint16 channel) = 0; - - /** Abort all previously issued requests in a given channel. - Any requests still waiting to be processed of the given channel, will be - removed from the queue. - It will not remove requests, where the request handler is already called. - @param channel The type of request to be aborted - */ - virtual void abortPendingRequestsByChannel(uint16 channel) = 0; - - /** Abort all previously issued requests. - Any requests still waiting to be processed will be removed from the queue. - Any requests that are being processed will still complete. - */ - virtual void abortAllRequests() = 0; - - /** Set whether to pause further processing of any requests. - If true, any further requests will simply be queued and not processed until - setPaused(false) is called. Any requests which are in the process of being - worked on already will still continue. - */ - virtual void setPaused(bool pause) = 0; - /// Return whether the queue is paused ie not sending more work to workers - virtual bool isPaused() const = 0; - - /** Set whether to accept new requests or not. - If true, requests are added to the queue as usual. If false, requests - are silently ignored until setRequestsAccepted(true) is called. - */ - virtual void setRequestsAccepted(bool accept) = 0; - /// Returns whether requests are being accepted right now - virtual bool getRequestsAccepted() const = 0; - - /** Process the responses in the queue. - @remarks - This method is public, and must be called from the main render - thread to 'pump' responses through the system. The method will usually - try to clear all responses before returning = 0; however, you can specify - a time limit on the response processing to limit the impact of - spikes in demand by calling setResponseProcessingTimeLimit. - */ - virtual void processResponses() = 0; - - /** Get the time limit imposed on the processing of responses in a - single frame, in milliseconds (0 indicates no limit). - */ - virtual unsigned long getResponseProcessingTimeLimit() const = 0; - - /** Set the time limit imposed on the processing of responses in a - single frame, in milliseconds (0 indicates no limit). - This sets the maximum time that will be spent in processResponses() in - a single frame. The default is 8ms. - */ - virtual void setResponseProcessingTimeLimit(unsigned long ms) = 0; - - /** Shut down the queue. - */ - virtual void shutdown() = 0; - - /** Get a channel ID for a given channel name. - @remarks - Channels are assigned on a first-come, first-served basis and are - not persistent across application instances. This method allows - applications to not worry about channel clashes through manually - assigned channel numbers. - */ - virtual uint16 getChannel(const String& channelName); - - }; - - /** Base for a general purpose request / response style background work queue. - */ - class _OgreExport DefaultWorkQueueBase : public WorkQueue - { - public: - - /** Constructor. - Call startup() to initialise. - @param name Optional name, just helps to identify logging output - */ - DefaultWorkQueueBase(const String& name = BLANKSTRING); - virtual ~DefaultWorkQueueBase(); - /// Get the name of the work queue - const String& getName() const; - /** Get the number of worker threads that this queue will start when - startup() is called. - */ - virtual size_t getWorkerThreadCount() const; - - /** Set the number of worker threads that this queue will start - when startup() is called (default 1). - Calling this will have no effect unless the queue is shut down and - restarted. - */ - virtual void setWorkerThreadCount(size_t c); - - /** Get whether worker threads will be allowed to access render system - resources. - Accessing render system resources from a separate thread can require that - a context is maintained for that thread. Also, it requires that the - render system is running in threadsafe mode, which only happens - when OGRE_THREAD_SUPPORT=1. This option defaults to false, which means - that threads can not use GPU resources, and the render system can - work in non-threadsafe mode, which is more efficient. - */ - virtual bool getWorkersCanAccessRenderSystem() const; - - - /** Set whether worker threads will be allowed to access render system - resources. - Accessing render system resources from a separate thread can require that - a context is maintained for that thread. Also, it requires that the - render system is running in threadsafe mode, which only happens - when OGRE_THREAD_SUPPORT=1. This option defaults to false, which means - that threads can not use GPU resources, and the render system can - work in non-threadsafe mode, which is more efficient. - Calling this will have no effect unless the queue is shut down and - restarted. - */ - virtual void setWorkersCanAccessRenderSystem(bool access); - - /** Process the next request on the queue. - @remarks - This method is public, but only intended for advanced users to call. - The only reason you would call this, is if you were using your - own thread to drive the worker processing. The thread calling this - method will be the thread used to call the RequestHandler. - */ - virtual void _processNextRequest(); - - /// Main function for each thread spawned. - virtual void _threadMain() = 0; - - /** Returns whether the queue is trying to shut down. */ - virtual bool isShuttingDown() const { return mShuttingDown; } - - /// @copydoc WorkQueue::addRequestHandler - virtual void addRequestHandler(uint16 channel, RequestHandler* rh); - /// @copydoc WorkQueue::removeRequestHandler - virtual void removeRequestHandler(uint16 channel, RequestHandler* rh); - /// @copydoc WorkQueue::addResponseHandler - virtual void addResponseHandler(uint16 channel, ResponseHandler* rh); - /// @copydoc WorkQueue::removeResponseHandler - virtual void removeResponseHandler(uint16 channel, ResponseHandler* rh); - - /// @copydoc WorkQueue::addRequest - virtual RequestID addRequest(uint16 channel, uint16 requestType, const Any& rData, uint8 retryCount = 0, - bool forceSynchronous = false, bool idleThread = false); - /// @copydoc WorkQueue::abortRequest - virtual void abortRequest(RequestID id); - /// @copydoc WorkQueue::abortRequestsByChannel - virtual void abortRequestsByChannel(uint16 channel); - /// @copydoc WorkQueue::abortPendingRequestsByChannel - virtual void abortPendingRequestsByChannel(uint16 channel); - /// @copydoc WorkQueue::abortAllRequests - virtual void abortAllRequests(); - /// @copydoc WorkQueue::setPaused - virtual void setPaused(bool pause); - /// @copydoc WorkQueue::isPaused - virtual bool isPaused() const; - /// @copydoc WorkQueue::setRequestsAccepted - virtual void setRequestsAccepted(bool accept); - /// @copydoc WorkQueue::getRequestsAccepted - virtual bool getRequestsAccepted() const; - /// @copydoc WorkQueue::processResponses - virtual void processResponses(); - /// @copydoc WorkQueue::getResponseProcessingTimeLimit - virtual unsigned long getResponseProcessingTimeLimit() const { return mResposeTimeLimitMS; } - /// @copydoc WorkQueue::setResponseProcessingTimeLimit - virtual void setResponseProcessingTimeLimit(unsigned long ms) { mResposeTimeLimitMS = ms; } - protected: - String mName; - size_t mWorkerThreadCount; - bool mWorkerRenderSystemAccess; - bool mIsRunning; - unsigned long mResposeTimeLimitMS; - - typedef deque::type RequestQueue; - typedef deque::type ResponseQueue; - RequestQueue mRequestQueue; // Guarded by mRequestMutex - RequestQueue mProcessQueue; // Guarded by mProcessMutex - ResponseQueue mResponseQueue; // Guarded by mResponseMutex - - /// Thread function - struct _OgreExport WorkerFunc OGRE_THREAD_WORKER_INHERIT - { - DefaultWorkQueueBase* mQueue; - - WorkerFunc(DefaultWorkQueueBase* q) - : mQueue(q) {} - - void operator()(); - - void operator()() const; - - void run(); - }; - WorkerFunc* mWorkerFunc; - - /** Intermediate structure to hold a pointer to a request handler which - provides insurance against the handler itself being disconnected - while the list remains unchanged. - */ - class _OgreExport RequestHandlerHolder : public UtilityAlloc - { - protected: - OGRE_RW_MUTEX(mRWMutex); - RequestHandler* mHandler; - public: - RequestHandlerHolder(RequestHandler* handler) - : mHandler(handler) {} - - // Disconnect the handler to allow it to be destroyed - void disconnectHandler() - { - // write lock - must wait for all requests to finish - OGRE_LOCK_RW_MUTEX_WRITE(mRWMutex); - mHandler = 0; - } - - /** Get handler pointer - note, only use this for == comparison or similar, - do not attempt to call it as it is not thread safe. - */ - RequestHandler* getHandler() { return mHandler; } - - /** Process a request if possible. - @return Valid response if processed, null otherwise - */ - Response* handleRequest(const Request* req, const WorkQueue* srcQ) - { - // Read mutex so that multiple requests can be processed by the - // same handler in parallel if required - OGRE_LOCK_RW_MUTEX_READ(mRWMutex); - Response* response = 0; - if (mHandler) - { - if (mHandler->canHandleRequest(req, srcQ)) - { - response = mHandler->handleRequest(req, srcQ); - } - } - return response; - } - - }; - // Hold these by shared pointer so they can be copied keeping same instance - typedef SharedPtr RequestHandlerHolderPtr; - - typedef list::type RequestHandlerList; - typedef list::type ResponseHandlerList; - typedef map::type RequestHandlerListByChannel; - typedef map::type ResponseHandlerListByChannel; - - RequestHandlerListByChannel mRequestHandlers; - ResponseHandlerListByChannel mResponseHandlers; - RequestID mRequestCount; // Guarded by mRequestMutex - bool mPaused; - bool mAcceptRequests; - bool mShuttingDown; - - //NOTE: If you lock multiple mutexes at the same time, the order is important! - // For example if threadA locks mIdleMutex first then tries to lock mProcessMutex, - // and threadB locks mProcessMutex first, then mIdleMutex. In this case you can get livelock and the system is dead! - //RULE: Lock mProcessMutex before other mutex, to prevent livelocks - OGRE_MUTEX(mIdleMutex); - OGRE_MUTEX(mRequestMutex); - OGRE_MUTEX(mProcessMutex); - OGRE_MUTEX(mResponseMutex); - OGRE_RW_MUTEX(mRequestHandlerMutex); - - - void processRequestResponse(Request* r, bool synchronous); - Response* processRequest(Request* r); - void processResponse(Response* r); - /// Notify workers about a new request. - virtual void notifyWorkers() = 0; - /// Put a Request on the queue with a specific RequestID. - void addRequestWithRID(RequestID rid, uint16 channel, uint16 requestType, const Any& rData, uint8 retryCount); - - RequestQueue mIdleRequestQueue; // Guarded by mIdleMutex - bool mIdleThreadRunning; // Guarded by mIdleMutex - Request* mIdleProcessed; // Guarded by mProcessMutex - - - bool processIdleRequests(); - }; - - - - - - /** @} */ - /** @} */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + + /** Interface to a general purpose request / response style background work queue. + @remarks + A work queue is a simple structure, where requests for work are placed + onto the queue, then removed by a worker for processing, then finally + a response is placed on the result queue for the originator to pick up + at their leisure. The typical use for this is in a threaded environment, + although any kind of deferred processing could use this approach to + decouple and distribute work over a period of time even + if it was single threaded. + @par + WorkQueues also incorporate thread pools. One or more background worker threads + can wait on the queue and be notified when a request is waiting to be + processed. For maximal thread usage, a WorkQueue instance should be shared + among many sources of work, rather than many work queues being created. + This way, you can share a small number of hardware threads among a large + number of background tasks. This doesn't mean you have to implement all the + request processing in one class, you can plug in many handlers in order to + process the requests. + @par + This is an abstract interface definition; users can subclass this and + provide their own implementation if required to centralise task management + in their own subsystems. We also provide a default implementation in the + form of DefaultWorkQueue. + */ + class _OgreExport WorkQueue : public UtilityAlloc + { + protected: + typedef map::type ChannelMap; + ChannelMap mChannelMap; + uint16 mNextChannel; + OGRE_MUTEX(mChannelMapMutex); + public: + /// Numeric identifier for a request + typedef unsigned long long int RequestID; + + /** General purpose request structure. + */ + class _OgreExport Request : public UtilityAlloc + { + friend class WorkQueue; + protected: + /// The request channel, as an integer + uint16 mChannel; + /// The request type, as an integer within the channel (user can define enumerations on this) + uint16 mType; + /// The details of the request (user defined) + Any mData; + /// Retry count - set this to non-zero to have the request try again on failure + uint8 mRetryCount; + /// Identifier (assigned by the system) + RequestID mID; + /// Abort Flag + mutable bool mAborted; + + public: + /// Constructor + Request(uint16 channel, uint16 rtype, const Any& rData, uint8 retry, RequestID rid); + ~Request(); + /// Set the abort flag + void abortRequest() const { mAborted = true; } + /// Get the request channel (top level categorisation) + uint16 getChannel() const { return mChannel; } + /// Get the type of this request within the given channel + uint16 getType() const { return mType; } + /// Get the user details of this request + const Any& getData() const { return mData; } + /// Get the remaining retry count + uint8 getRetryCount() const { return mRetryCount; } + /// Get the identifier of this request + RequestID getID() const { return mID; } + /// Get the abort flag + bool getAborted() const { return mAborted; } + }; + + /** General purpose response structure. + */ + struct _OgreExport Response : public UtilityAlloc + { + /// Pointer to the request that this response is in relation to + const Request* mRequest; + /// Whether the work item succeeded or not + bool mSuccess; + /// Any diagnostic messages + String mMessages; + /// Data associated with the result of the process + Any mData; + + public: + Response(const Request* rq, bool success, const Any& data, const String& msg = BLANKSTRING); + ~Response(); + /// Get the request that this is a response to (NB destruction destroys this) + const Request* getRequest() const { return mRequest; } + /// Return whether this is a successful response + bool succeeded() const { return mSuccess; } + /// Get any diagnostic messages about the process + const String& getMessages() const { return mMessages; } + /// Return the response data (user defined, only valid on success) + const Any& getData() const { return mData; } + /// Abort the request + void abortRequest() { mRequest->abortRequest(); mData.destroy(); } + }; + + /** Interface definition for a handler of requests. + @remarks + User classes are expected to implement this interface in order to + process requests on the queue. It's important to realise that + the calls to this class may be in a separate thread to the main + render context, and as such it may not be possible to make + rendersystem or other GPU-dependent calls in this handler. You can only + do so if the queue was created with 'workersCanAccessRenderSystem' + set to true, and OGRE_THREAD_SUPPORT=1, but this puts extra strain + on the thread safety of the render system and is not recommended. + It is best to perform CPU-side work in these handlers and let the + response handler transfer results to the GPU in the main render thread. + */ + class _OgreExport RequestHandler + { + public: + RequestHandler() {} + virtual ~RequestHandler() {} + + /** Return whether this handler can process a given request. + @remarks + Defaults to true, but if you wish to add several handlers each of + which deal with different types of request, you can override + this method. + */ + virtual bool canHandleRequest(const Request* req, const WorkQueue* srcQ) + { (void)srcQ; return !req->getAborted(); } + + /** The handler method every subclass must implement. + If a failure is encountered, return a Response with a failure + result rather than raise an exception. + @param req The Request structure, which is effectively owned by the + handler during this call. It must be attached to the returned + Response regardless of success or failure. + @param srcQ The work queue that this request originated from + @return Pointer to a Response object - the caller is responsible + for deleting the object. + */ + virtual Response* handleRequest(const Request* req, const WorkQueue* srcQ) = 0; + }; + + /** Interface definition for a handler of responses. + @remarks + User classes are expected to implement this interface in order to + process responses from the queue. All calls to this class will be + in the main render thread and thus all GPU resources will be + available. + */ + class _OgreExport ResponseHandler + { + public: + ResponseHandler() {} + virtual ~ResponseHandler() {} + + /** Return whether this handler can process a given response. + @remarks + Defaults to true, but if you wish to add several handlers each of + which deal with different types of response, you can override + this method. + */ + virtual bool canHandleResponse(const Response* res, const WorkQueue* srcQ) + { (void)srcQ; return !res->getRequest()->getAborted(); } + + /** The handler method every subclass must implement. + @param res The Response structure. The caller is responsible for + deleting this after the call is made, none of the data contained + (except pointers to structures in user Any data) will persist + after this call is returned. + @param srcQ The work queue that this request originated from + */ + virtual void handleResponse(const Response* res, const WorkQueue* srcQ) = 0; + }; + + WorkQueue() : mNextChannel(0) {} + virtual ~WorkQueue() {} + + /** Start up the queue with the options that have been set. + @param forceRestart If the queue is already running, whether to shut it + down and restart. + */ + virtual void startup(bool forceRestart = true) = 0; + /** Add a request handler instance to the queue. + @remarks + Every queue must have at least one request handler instance for each + channel in which requests are raised. If you + add more than one handler per channel, then you must implement canHandleRequest + differently in each if you wish them to respond to different requests. + @param channel The channel for requests you want to handle + @param rh Your handler + */ + virtual void addRequestHandler(uint16 channel, RequestHandler* rh) = 0; + /** Remove a request handler. */ + virtual void removeRequestHandler(uint16 channel, RequestHandler* rh) = 0; + + /** Add a response handler instance to the queue. + @remarks + Every queue must have at least one response handler instance for each + channel in which requests are raised. If you add more than one, then you + must implement canHandleResponse differently in each if you wish them + to respond to different responses. + @param channel The channel for responses you want to handle + @param rh Your handler + */ + virtual void addResponseHandler(uint16 channel, ResponseHandler* rh) = 0; + /** Remove a Response handler. */ + virtual void removeResponseHandler(uint16 channel, ResponseHandler* rh) = 0; + + /** Add a new request to the queue. + @param channel The channel this request will go into = 0; the channel is the top-level + categorisation of the request + @param requestType An identifier that's unique within this queue which + identifies the type of the request (user decides the actual value) + @param rData The data required by the request process. + @param retryCount The number of times the request should be retried + if it fails. + @param forceSynchronous Forces the request to be processed immediately + even if threading is enabled. + @param idleThread Request should be processed on the idle thread. + Idle requests will be processed on a single worker thread. You should use this in the following situations: + 1. If a request handler can't process multiple requests in parallel. + 2. If you add lot of requests, but you want to keep the game fast. + 3. If you have lot of more important threads. (example: physics). + @return The ID of the request that has been added + */ + virtual RequestID addRequest(uint16 channel, uint16 requestType, const Any& rData, uint8 retryCount = 0, + bool forceSynchronous = false, bool idleThread = false) = 0; + + /** Abort a previously issued request. + If the request is still waiting to be processed, it will be + removed from the queue. + @param id The ID of the previously issued request. + */ + virtual void abortRequest(RequestID id) = 0; + + /** Abort all previously issued requests in a given channel. + Any requests still waiting to be processed of the given channel, will be + removed from the queue. + Requests which are processed, but response handler is not called will also be removed. + @param channel The type of request to be aborted + */ + virtual void abortRequestsByChannel(uint16 channel) = 0; + + /** Abort all previously issued requests in a given channel. + Any requests still waiting to be processed of the given channel, will be + removed from the queue. + It will not remove requests, where the request handler is already called. + @param channel The type of request to be aborted + */ + virtual void abortPendingRequestsByChannel(uint16 channel) = 0; + + /** Abort all previously issued requests. + Any requests still waiting to be processed will be removed from the queue. + Any requests that are being processed will still complete. + */ + virtual void abortAllRequests() = 0; + + /** Set whether to pause further processing of any requests. + If true, any further requests will simply be queued and not processed until + setPaused(false) is called. Any requests which are in the process of being + worked on already will still continue. + */ + virtual void setPaused(bool pause) = 0; + /// Return whether the queue is paused ie not sending more work to workers + virtual bool isPaused() const = 0; + + /** Set whether to accept new requests or not. + If true, requests are added to the queue as usual. If false, requests + are silently ignored until setRequestsAccepted(true) is called. + */ + virtual void setRequestsAccepted(bool accept) = 0; + /// Returns whether requests are being accepted right now + virtual bool getRequestsAccepted() const = 0; + + /** Process the responses in the queue. + @remarks + This method is public, and must be called from the main render + thread to 'pump' responses through the system. The method will usually + try to clear all responses before returning = 0; however, you can specify + a time limit on the response processing to limit the impact of + spikes in demand by calling setResponseProcessingTimeLimit. + */ + virtual void processResponses() = 0; + + /** Get the time limit imposed on the processing of responses in a + single frame, in milliseconds (0 indicates no limit). + */ + virtual unsigned long getResponseProcessingTimeLimit() const = 0; + + /** Set the time limit imposed on the processing of responses in a + single frame, in milliseconds (0 indicates no limit). + This sets the maximum time that will be spent in processResponses() in + a single frame. The default is 8ms. + */ + virtual void setResponseProcessingTimeLimit(unsigned long ms) = 0; + + /** Shut down the queue. + */ + virtual void shutdown() = 0; + + /** Get a channel ID for a given channel name. + @remarks + Channels are assigned on a first-come, first-served basis and are + not persistent across application instances. This method allows + applications to not worry about channel clashes through manually + assigned channel numbers. + */ + virtual uint16 getChannel(const String& channelName); + + }; + + /** Base for a general purpose request / response style background work queue. + */ + class _OgreExport DefaultWorkQueueBase : public WorkQueue + { + public: + + /** Constructor. + Call startup() to initialise. + @param name Optional name, just helps to identify logging output + */ + DefaultWorkQueueBase(const String& name = BLANKSTRING); + virtual ~DefaultWorkQueueBase(); + /// Get the name of the work queue + const String& getName() const; + /** Get the number of worker threads that this queue will start when + startup() is called. + */ + virtual size_t getWorkerThreadCount() const; + + /** Set the number of worker threads that this queue will start + when startup() is called (default 1). + Calling this will have no effect unless the queue is shut down and + restarted. + */ + virtual void setWorkerThreadCount(size_t c); + + /** Get whether worker threads will be allowed to access render system + resources. + Accessing render system resources from a separate thread can require that + a context is maintained for that thread. Also, it requires that the + render system is running in threadsafe mode, which only happens + when OGRE_THREAD_SUPPORT=1. This option defaults to false, which means + that threads can not use GPU resources, and the render system can + work in non-threadsafe mode, which is more efficient. + */ + virtual bool getWorkersCanAccessRenderSystem() const; + + + /** Set whether worker threads will be allowed to access render system + resources. + Accessing render system resources from a separate thread can require that + a context is maintained for that thread. Also, it requires that the + render system is running in threadsafe mode, which only happens + when OGRE_THREAD_SUPPORT=1. This option defaults to false, which means + that threads can not use GPU resources, and the render system can + work in non-threadsafe mode, which is more efficient. + Calling this will have no effect unless the queue is shut down and + restarted. + */ + virtual void setWorkersCanAccessRenderSystem(bool access); + + /** Process the next request on the queue. + @remarks + This method is public, but only intended for advanced users to call. + The only reason you would call this, is if you were using your + own thread to drive the worker processing. The thread calling this + method will be the thread used to call the RequestHandler. + */ + virtual void _processNextRequest(); + + /// Main function for each thread spawned. + virtual void _threadMain() = 0; + + /** Returns whether the queue is trying to shut down. */ + virtual bool isShuttingDown() const { return mShuttingDown; } + + /// @copydoc WorkQueue::addRequestHandler + virtual void addRequestHandler(uint16 channel, RequestHandler* rh); + /// @copydoc WorkQueue::removeRequestHandler + virtual void removeRequestHandler(uint16 channel, RequestHandler* rh); + /// @copydoc WorkQueue::addResponseHandler + virtual void addResponseHandler(uint16 channel, ResponseHandler* rh); + /// @copydoc WorkQueue::removeResponseHandler + virtual void removeResponseHandler(uint16 channel, ResponseHandler* rh); + + /// @copydoc WorkQueue::addRequest + virtual RequestID addRequest(uint16 channel, uint16 requestType, const Any& rData, uint8 retryCount = 0, + bool forceSynchronous = false, bool idleThread = false); + /// @copydoc WorkQueue::abortRequest + virtual void abortRequest(RequestID id); + /// @copydoc WorkQueue::abortRequestsByChannel + virtual void abortRequestsByChannel(uint16 channel); + /// @copydoc WorkQueue::abortPendingRequestsByChannel + virtual void abortPendingRequestsByChannel(uint16 channel); + /// @copydoc WorkQueue::abortAllRequests + virtual void abortAllRequests(); + /// @copydoc WorkQueue::setPaused + virtual void setPaused(bool pause); + /// @copydoc WorkQueue::isPaused + virtual bool isPaused() const; + /// @copydoc WorkQueue::setRequestsAccepted + virtual void setRequestsAccepted(bool accept); + /// @copydoc WorkQueue::getRequestsAccepted + virtual bool getRequestsAccepted() const; + /// @copydoc WorkQueue::processResponses + virtual void processResponses(); + /// @copydoc WorkQueue::getResponseProcessingTimeLimit + virtual unsigned long getResponseProcessingTimeLimit() const { return mResposeTimeLimitMS; } + /// @copydoc WorkQueue::setResponseProcessingTimeLimit + virtual void setResponseProcessingTimeLimit(unsigned long ms) { mResposeTimeLimitMS = ms; } + protected: + String mName; + size_t mWorkerThreadCount; + bool mWorkerRenderSystemAccess; + bool mIsRunning; + unsigned long mResposeTimeLimitMS; + + typedef deque::type RequestQueue; + typedef deque::type ResponseQueue; + RequestQueue mRequestQueue; // Guarded by mRequestMutex + RequestQueue mProcessQueue; // Guarded by mProcessMutex + ResponseQueue mResponseQueue; // Guarded by mResponseMutex + + /// Thread function + struct _OgreExport WorkerFunc OGRE_THREAD_WORKER_INHERIT + { + DefaultWorkQueueBase* mQueue; + + WorkerFunc(DefaultWorkQueueBase* q) + : mQueue(q) {} + + void operator()(); + + void operator()() const; + + void run(); + }; + WorkerFunc* mWorkerFunc; + + /** Intermediate structure to hold a pointer to a request handler which + provides insurance against the handler itself being disconnected + while the list remains unchanged. + */ + class _OgreExport RequestHandlerHolder : public UtilityAlloc + { + protected: + OGRE_RW_MUTEX(mRWMutex); + RequestHandler* mHandler; + public: + RequestHandlerHolder(RequestHandler* handler) + : mHandler(handler) {} + + // Disconnect the handler to allow it to be destroyed + void disconnectHandler() + { + // write lock - must wait for all requests to finish + OGRE_LOCK_RW_MUTEX_WRITE(mRWMutex); + mHandler = 0; + } + + /** Get handler pointer - note, only use this for == comparison or similar, + do not attempt to call it as it is not thread safe. + */ + RequestHandler* getHandler() { return mHandler; } + + /** Process a request if possible. + @return Valid response if processed, null otherwise + */ + Response* handleRequest(const Request* req, const WorkQueue* srcQ) + { + // Read mutex so that multiple requests can be processed by the + // same handler in parallel if required + OGRE_LOCK_RW_MUTEX_READ(mRWMutex); + Response* response = 0; + if (mHandler) + { + if (mHandler->canHandleRequest(req, srcQ)) + { + response = mHandler->handleRequest(req, srcQ); + } + } + return response; + } + + }; + // Hold these by shared pointer so they can be copied keeping same instance + typedef SharedPtr RequestHandlerHolderPtr; + + typedef list::type RequestHandlerList; + typedef list::type ResponseHandlerList; + typedef map::type RequestHandlerListByChannel; + typedef map::type ResponseHandlerListByChannel; + + RequestHandlerListByChannel mRequestHandlers; + ResponseHandlerListByChannel mResponseHandlers; + RequestID mRequestCount; // Guarded by mRequestMutex + bool mPaused; + bool mAcceptRequests; + bool mShuttingDown; + + //NOTE: If you lock multiple mutexes at the same time, the order is important! + // For example if threadA locks mIdleMutex first then tries to lock mProcessMutex, + // and threadB locks mProcessMutex first, then mIdleMutex. In this case you can get livelock and the system is dead! + //RULE: Lock mProcessMutex before other mutex, to prevent livelocks + OGRE_MUTEX(mIdleMutex); + OGRE_MUTEX(mRequestMutex); + OGRE_MUTEX(mProcessMutex); + OGRE_MUTEX(mResponseMutex); + OGRE_RW_MUTEX(mRequestHandlerMutex); + + + void processRequestResponse(Request* r, bool synchronous); + Response* processRequest(Request* r); + void processResponse(Response* r); + /// Notify workers about a new request. + virtual void notifyWorkers() = 0; + /// Put a Request on the queue with a specific RequestID. + void addRequestWithRID(RequestID rid, uint16 channel, uint16 requestType, const Any& rData, uint8 retryCount); + + RequestQueue mIdleRequestQueue; // Guarded by mIdleMutex + bool mIdleThreadRunning; // Guarded by mIdleMutex + Request* mIdleProcessed; // Guarded by mProcessMutex + + + bool processIdleRequests(); + }; + + + + + + /** @} */ + /** @} */ } diff --git a/OgreMain/include/OgreZip.h b/OgreMain/include/OgreZip.h index 5753d757a28..824779e0202 100644 --- a/OgreMain/include/OgreZip.h +++ b/OgreMain/include/OgreZip.h @@ -35,19 +35,19 @@ THE SOFTWARE. #include "OgreHeaderPrefix.h" // Forward declaration for zziplib to avoid header file dependency. -typedef struct zzip_dir ZZIP_DIR; -typedef struct zzip_file ZZIP_FILE; +typedef struct zzip_dir ZZIP_DIR; +typedef struct zzip_file ZZIP_FILE; typedef union _zzip_plugin_io zzip_plugin_io_handlers; namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Resources - * @{ - */ - /** Specialisation of the Archive class to allow reading of files from a zip + /** \addtogroup Core + * @{ + */ + /** \addtogroup Resources + * @{ + */ + /** Specialisation of the Archive class to allow reading of files from a zip format source archive. @remarks This archive format supports all archives compressed in the standard @@ -80,11 +80,11 @@ namespace Ogre { /// @copydoc Archive::open DataStreamPtr open(const String& filename, bool readOnly = true) const; - /// @copydoc Archive::create - DataStreamPtr create(const String& filename) const; + /// @copydoc Archive::create + DataStreamPtr create(const String& filename) const; - /// @copydoc Archive::remove - void remove(const String& filename) const; + /// @copydoc Archive::remove + void remove(const String& filename) const; /// @copydoc Archive::list StringVectorPtr list(bool recursive = true, bool dirs = false); @@ -103,8 +103,8 @@ namespace Ogre { /// @copydoc Archive::exists bool exists(const String& filename); - /// @copydoc Archive::getModifiedTime - time_t getModifiedTime(const String& filename); + /// @copydoc Archive::getModifiedTime + time_t getModifiedTime(const String& filename); }; /** Specialisation of ArchiveFactory for Zip files. */ @@ -117,8 +117,8 @@ namespace Ogre { /// @copydoc FactoryObj::createInstance Archive *createInstance( const String& name, bool readOnly ) { - if(!readOnly) - return NULL; + if(!readOnly) + return NULL; return OGRE_NEW ZipArchive(name, "Zip"); } @@ -166,18 +166,18 @@ namespace Ogre { { protected: ZZIP_FILE* mZzipFile; - /// We need caching because sometimes serializers step back in data stream and zziplib behaves slow - StaticCache<2 * OGRE_STREAM_TEMP_SIZE> mCache; + /// We need caching because sometimes serializers step back in data stream and zziplib behaves slow + StaticCache<2 * OGRE_STREAM_TEMP_SIZE> mCache; public: /// Unnamed constructor ZipDataStream(ZZIP_FILE* zzipFile, size_t uncompressedSize); /// Constructor for creating named streams ZipDataStream(const String& name, ZZIP_FILE* zzipFile, size_t uncompressedSize); - ~ZipDataStream(); + ~ZipDataStream(); /// @copydoc DataStream::read size_t read(void* buf, size_t count); - /// @copydoc DataStream::write - size_t write(void* buf, size_t count); + /// @copydoc DataStream::write + size_t write(void* buf, size_t count); /// @copydoc DataStream::skip void skip(long count); /// @copydoc DataStream::seek @@ -192,8 +192,8 @@ namespace Ogre { }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/include/Threading/OgreDefaultWorkQueue.h b/OgreMain/include/Threading/OgreDefaultWorkQueue.h index 8c390c10034..4e00d281cd0 100644 --- a/OgreMain/include/Threading/OgreDefaultWorkQueue.h +++ b/OgreMain/include/Threading/OgreDefaultWorkQueue.h @@ -27,13 +27,13 @@ THE SOFTWARE #define __OgreDefaultWorkQueue_H__ #if OGRE_THREAD_PROVIDER == 0 - #include "OgreDefaultWorkQueueStandard.h" + #include "OgreDefaultWorkQueueStandard.h" #elif OGRE_THREAD_PROVIDER == 1 - #include "OgreDefaultWorkQueueStandard.h" + #include "OgreDefaultWorkQueueStandard.h" #elif OGRE_THREAD_PROVIDER == 2 - #include "OgreDefaultWorkQueueStandard.h" + #include "OgreDefaultWorkQueueStandard.h" #elif OGRE_THREAD_PROVIDER == 3 - #include "OgreDefaultWorkQueueTBB.h" + #include "OgreDefaultWorkQueueTBB.h" #endif #endif diff --git a/OgreMain/include/Threading/OgreDefaultWorkQueueStandard.h b/OgreMain/include/Threading/OgreDefaultWorkQueueStandard.h index f3c0fb02c69..89184c4505f 100644 --- a/OgreMain/include/Threading/OgreDefaultWorkQueueStandard.h +++ b/OgreMain/include/Threading/OgreDefaultWorkQueueStandard.h @@ -30,52 +30,52 @@ THE SOFTWARE namespace Ogre { - /** Implementation of a general purpose request / response style background work queue. - @remarks - This default implementation of a work queue starts a thread pool and - provides queues to process requests. - */ - class _OgreExport DefaultWorkQueue : public DefaultWorkQueueBase - { - public: - - DefaultWorkQueue(const String& name = BLANKSTRING); - virtual ~DefaultWorkQueue(); - - /// Main function for each thread spawned. - virtual void _threadMain(); - - /// @copydoc WorkQueue::shutdown - virtual void shutdown(); - - /// @copydoc WorkQueue::startup - virtual void startup(bool forceRestart = true); - - protected: - /** To be called by a separate thread; will return immediately if there - are items in the queue, or suspend the thread until new items are added - otherwise. - */ - virtual void waitForNextRequest(); - - /// Notify that a thread has registered itself with the render system - virtual void notifyThreadRegistered(); - - virtual void notifyWorkers(); - - size_t mNumThreadsRegisteredWithRS; - /// Init notification mutex (must lock before waiting on initCondition) - OGRE_MUTEX(mInitMutex); - /// Synchroniser token to wait / notify on thread init - OGRE_THREAD_SYNCHRONISER(mInitSync); - - OGRE_THREAD_SYNCHRONISER(mRequestCondition); + /** Implementation of a general purpose request / response style background work queue. + @remarks + This default implementation of a work queue starts a thread pool and + provides queues to process requests. + */ + class _OgreExport DefaultWorkQueue : public DefaultWorkQueueBase + { + public: + + DefaultWorkQueue(const String& name = BLANKSTRING); + virtual ~DefaultWorkQueue(); + + /// Main function for each thread spawned. + virtual void _threadMain(); + + /// @copydoc WorkQueue::shutdown + virtual void shutdown(); + + /// @copydoc WorkQueue::startup + virtual void startup(bool forceRestart = true); + + protected: + /** To be called by a separate thread; will return immediately if there + are items in the queue, or suspend the thread until new items are added + otherwise. + */ + virtual void waitForNextRequest(); + + /// Notify that a thread has registered itself with the render system + virtual void notifyThreadRegistered(); + + virtual void notifyWorkers(); + + size_t mNumThreadsRegisteredWithRS; + /// Init notification mutex (must lock before waiting on initCondition) + OGRE_MUTEX(mInitMutex); + /// Synchroniser token to wait / notify on thread init + OGRE_THREAD_SYNCHRONISER(mInitSync); + + OGRE_THREAD_SYNCHRONISER(mRequestCondition); #if OGRE_THREAD_SUPPORT - typedef vector::type WorkerThreadList; - WorkerThreadList mWorkers; + typedef vector::type WorkerThreadList; + WorkerThreadList mWorkers; #endif - }; + }; } diff --git a/OgreMain/include/Threading/OgreDefaultWorkQueueTBB.h b/OgreMain/include/Threading/OgreDefaultWorkQueueTBB.h index 31229ed1cb1..b39a3a70d09 100644 --- a/OgreMain/include/Threading/OgreDefaultWorkQueueTBB.h +++ b/OgreMain/include/Threading/OgreDefaultWorkQueueTBB.h @@ -31,45 +31,45 @@ THE SOFTWARE namespace Ogre { - /** Implementation of a general purpose request / response style background work queue. - @remarks - This implementation utilises tbb's task system for the WorkQueue implementation. - */ - class _OgreExport DefaultWorkQueue : public DefaultWorkQueueBase - { - public: - DefaultWorkQueue(const String& name = BLANKSTRING); - virtual ~DefaultWorkQueue(); - /** Process the next request on the queue. - @remarks - This method is public, but only intended for advanced users to call. - The only reason you would call this, is if you were using your - own thread to drive the worker processing. The thread calling this - method will be the thread used to call the RequestHandler. - */ - - /// Main function for each thread spawned. - virtual void _threadMain(); - - /// @copydoc WorkQueue::shutdown - virtual void shutdown(); - - /// @copydoc WorkQueue::startup - virtual void startup(bool forceRestart = true); - - /// Register the current thread with the rendersystem - void _registerThreadWithRenderSystem(); - - protected: - virtual void notifyWorkers(); - - private: - tbb::task_scheduler_init mTaskScheduler; - tbb::task_group mTaskGroup; - /// Synchronise registering threads with the RenderSystem - OGRE_MUTEX(mRegisterRSMutex); - std::set mRegisteredThreads; - }; + /** Implementation of a general purpose request / response style background work queue. + @remarks + This implementation utilises tbb's task system for the WorkQueue implementation. + */ + class _OgreExport DefaultWorkQueue : public DefaultWorkQueueBase + { + public: + DefaultWorkQueue(const String& name = BLANKSTRING); + virtual ~DefaultWorkQueue(); + /** Process the next request on the queue. + @remarks + This method is public, but only intended for advanced users to call. + The only reason you would call this, is if you were using your + own thread to drive the worker processing. The thread calling this + method will be the thread used to call the RequestHandler. + */ + + /// Main function for each thread spawned. + virtual void _threadMain(); + + /// @copydoc WorkQueue::shutdown + virtual void shutdown(); + + /// @copydoc WorkQueue::startup + virtual void startup(bool forceRestart = true); + + /// Register the current thread with the rendersystem + void _registerThreadWithRenderSystem(); + + protected: + virtual void notifyWorkers(); + + private: + tbb::task_scheduler_init mTaskScheduler; + tbb::task_group mTaskGroup; + /// Synchronise registering threads with the RenderSystem + OGRE_MUTEX(mRegisterRSMutex); + std::set mRegisteredThreads; + }; } diff --git a/OgreMain/include/Threading/OgreThreadDefines.h b/OgreMain/include/Threading/OgreThreadDefines.h index 0e5fe2101d5..412b6f434bf 100644 --- a/OgreMain/include/Threading/OgreThreadDefines.h +++ b/OgreMain/include/Threading/OgreThreadDefines.h @@ -28,13 +28,13 @@ THE SOFTWARE #define OGRE_AUTO_MUTEX_NAME mutex #if OGRE_THREAD_PROVIDER == 0 - #include "OgreThreadDefinesNone.h" + #include "OgreThreadDefinesNone.h" #elif OGRE_THREAD_PROVIDER == 1 - #include "OgreThreadDefinesBoost.h" + #include "OgreThreadDefinesBoost.h" #elif OGRE_THREAD_PROVIDER == 2 - #include "OgreThreadDefinesPoco.h" + #include "OgreThreadDefinesPoco.h" #elif OGRE_THREAD_PROVIDER == 3 - #include "OgreThreadDefinesTBB.h" + #include "OgreThreadDefinesTBB.h" #endif #endif diff --git a/OgreMain/include/Threading/OgreThreadHeaders.h b/OgreMain/include/Threading/OgreThreadHeaders.h index 8ed8662691a..1410d285a97 100644 --- a/OgreMain/include/Threading/OgreThreadHeaders.h +++ b/OgreMain/include/Threading/OgreThreadHeaders.h @@ -27,15 +27,15 @@ THE SOFTWARE #define __OgreThreadHeaders_H__ #if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min #endif #if OGRE_THREAD_PROVIDER == 1 - #include "OgreThreadHeadersBoost.h" + #include "OgreThreadHeadersBoost.h" #elif OGRE_THREAD_PROVIDER == 2 - #include "OgreThreadHeadersPoco.h" + #include "OgreThreadHeadersPoco.h" #elif OGRE_THREAD_PROVIDER == 3 - #include "OgreThreadHeadersTBB.h" + #include "OgreThreadHeadersTBB.h" #endif #include "OgreThreadDefines.h" diff --git a/OgreMain/include/WIN32/OgreConfigDialogImp.h b/OgreMain/include/WIN32/OgreConfigDialogImp.h index c76bb2f3221..26cd23cc85f 100644 --- a/OgreMain/include/WIN32/OgreConfigDialogImp.h +++ b/OgreMain/include/WIN32/OgreConfigDialogImp.h @@ -32,51 +32,51 @@ THE SOFTWARE. #define WIN32_LEAN_AND_MEAN #if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min #endif #include namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ - /** Defines the behaviour of an automatic renderer configuration dialog. - @remarks - OGRE comes with it's own renderer configuration dialog, which - applications can use to easily allow the user to configure the - settings appropriate to their machine. This class defines the - interface to this standard dialog. Because dialogs are inherently - tied to a particular platform's windowing system, there will be a - different subclass for each platform. - @author - Steven J. Streeting - */ - class _OgreExport ConfigDialog : public UtilityAlloc + /** Defines the behaviour of an automatic renderer configuration dialog. + @remarks + OGRE comes with it's own renderer configuration dialog, which + applications can use to easily allow the user to configure the + settings appropriate to their machine. This class defines the + interface to this standard dialog. Because dialogs are inherently + tied to a particular platform's windowing system, there will be a + different subclass for each platform. + @author + Steven J. Streeting + */ + class _OgreExport ConfigDialog : public UtilityAlloc { public: ConfigDialog(); - ~ConfigDialog(); + ~ConfigDialog(); - /** Displays the dialog. - @remarks - This method displays the dialog and from then on the dialog - interacts with the user independently. The dialog will be - calling the relevant OGRE rendering systems to query them for - options and to set the options the user selects. The method - returns when the user closes the dialog. - @returns - If the user accepted the dialog, true is returned. - @par - If the user cancelled the dialog (indicating the application - should probably terminate), false is returned. - @see - RenderSystem - */ + /** Displays the dialog. + @remarks + This method displays the dialog and from then on the dialog + interacts with the user independently. The dialog will be + calling the relevant OGRE rendering systems to query them for + options and to set the options the user selects. The method + returns when the user closes the dialog. + @returns + If the user accepted the dialog, true is returned. + @par + If the user cancelled the dialog (indicating the application + should probably terminate), false is returned. + @see + RenderSystem + */ bool display(); protected: @@ -86,10 +86,10 @@ namespace Ogre #else static BOOL CALLBACK DlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam); #endif - RenderSystem* mSelectedRenderSystem; + RenderSystem* mSelectedRenderSystem; HINSTANCE mHInstance; // HInstance of application, for dialog }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/WIN32/OgreConfigDialogImpWinRT.h b/OgreMain/include/WIN32/OgreConfigDialogImpWinRT.h index 6785df14f8d..c3ae8ca985d 100644 --- a/OgreMain/include/WIN32/OgreConfigDialogImpWinRT.h +++ b/OgreMain/include/WIN32/OgreConfigDialogImpWinRT.h @@ -32,57 +32,57 @@ THE SOFTWARE. #define WIN32_LEAN_AND_MEAN #if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min #endif #include "windows.h" namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ - /** Defines the behaviour of an automatic renderer configuration dialog. - @remarks - OGRE comes with it's own renderer configuration dialog, which - applications can use to easily allow the user to configure the - settings appropriate to their machine. This class defines the - interface to this standard dialog. Because dialogs are inherently - tied to a particular platform's windowing system, there will be a - different subclass for each platform. - @author - Steven J. Streeting - */ - class _OgreExport ConfigDialog : public UtilityAlloc + /** Defines the behaviour of an automatic renderer configuration dialog. + @remarks + OGRE comes with it's own renderer configuration dialog, which + applications can use to easily allow the user to configure the + settings appropriate to their machine. This class defines the + interface to this standard dialog. Because dialogs are inherently + tied to a particular platform's windowing system, there will be a + different subclass for each platform. + @author + Steven J. Streeting + */ + class _OgreExport ConfigDialog : public UtilityAlloc { public: ConfigDialog(); - ~ConfigDialog(); + ~ConfigDialog(); - /** Displays the dialog. - @remarks - This method displays the dialog and from then on the dialog - interacts with the user independently. The dialog will be - calling the relevant OGRE rendering systems to query them for - options and to set the options the user selects. The method - returns when the user closes the dialog. - @returns - If the user accepted the dialog, true is returned. - @par - If the user cancelled the dialog (indicating the application - should probably terminate), false is returned. - @see - RenderSystem - */ + /** Displays the dialog. + @remarks + This method displays the dialog and from then on the dialog + interacts with the user independently. The dialog will be + calling the relevant OGRE rendering systems to query them for + options and to set the options the user selects. The method + returns when the user closes the dialog. + @returns + If the user accepted the dialog, true is returned. + @par + If the user cancelled the dialog (indicating the application + should probably terminate), false is returned. + @see + RenderSystem + */ bool display(); protected: - RenderSystem* mSelectedRenderSystem; - }; - /** @} */ - /** @} */ + RenderSystem* mSelectedRenderSystem; + }; + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/WIN32/OgreErrorDialogImp.h b/OgreMain/include/WIN32/OgreErrorDialogImp.h index ece2ff41b5f..b9f6cc365ed 100644 --- a/OgreMain/include/WIN32/OgreErrorDialogImp.h +++ b/OgreMain/include/WIN32/OgreErrorDialogImp.h @@ -32,33 +32,33 @@ THE SOFTWARE. #define WIN32_LEAN_AND_MEAN #if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min #endif #include namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** Class for displaying the error dialog if Ogre fails badly. */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** Class for displaying the error dialog if Ogre fails badly. */ class _OgreExport ErrorDialog { public: ErrorDialog(); - ~ErrorDialog() {} + ~ErrorDialog() {} - /** - @remarks - Displays the error dialog. - @param - errorMessage The error message which has caused the failure. - @param - logName Optional name of the log to display in the detail pane. - */ + /** + @remarks + Displays the error dialog. + @param + errorMessage The error message which has caused the failure. + @param + logName Optional name of the log to display in the detail pane. + */ void display(const String& errorMessage, String logName = ""); protected: @@ -73,8 +73,8 @@ namespace Ogre HINSTANCE mHInstance; // HInstance of application, for dialog }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #include "OgreHeaderSuffix.h" diff --git a/OgreMain/include/WIN32/OgreErrorDialogImpWinRT.h b/OgreMain/include/WIN32/OgreErrorDialogImpWinRT.h index b8778048046..3a295a38a7b 100644 --- a/OgreMain/include/WIN32/OgreErrorDialogImpWinRT.h +++ b/OgreMain/include/WIN32/OgreErrorDialogImpWinRT.h @@ -30,31 +30,31 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - /** Class for displaying the error dialog if Ogre fails badly. */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + /** Class for displaying the error dialog if Ogre fails badly. */ class _OgreExport ErrorDialog { public: ErrorDialog(); - ~ErrorDialog() {} + ~ErrorDialog() {} - /** - @remarks - Displays the error dialog. - @param - errorMessage The error message which has caused the failure. - @param - logName Optional name of the log to display in the detail pane. - */ + /** + @remarks + Displays the error dialog. + @param + errorMessage The error message which has caused the failure. + @param + logName Optional name of the log to display in the detail pane. + */ void display(const String& errorMessage, String logName = ""); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/WIN32/OgreTimerImp.h b/OgreMain/include/WIN32/OgreTimerImp.h index 86df62443ca..fb541c581a3 100644 --- a/OgreMain/include/WIN32/OgreTimerImp.h +++ b/OgreMain/include/WIN32/OgreTimerImp.h @@ -29,54 +29,54 @@ THE SOFTWARE. #define __Win32Timer_H__ #ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN #endif #if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min #endif #include namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup General - * @{ - */ - - class _OgreExport Timer : public TimerAlloc + /** \addtogroup Core + * @{ + */ + /** \addtogroup General + * @{ + */ + + class _OgreExport Timer : public TimerAlloc { private: - clock_t mZeroClock; + clock_t mZeroClock; DWORD mStartTick; - LONGLONG mLastTime; + LONGLONG mLastTime; LARGE_INTEGER mStartTime; LARGE_INTEGER mFrequency; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - DWORD_PTR mTimerMask; + DWORD_PTR mTimerMask; #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WINRT - DWORD GetTickCount() { return (DWORD)GetTickCount64(); } + DWORD GetTickCount() { return (DWORD)GetTickCount64(); } #endif public: - /** Timer constructor. MUST be called on same thread that calls getMilliseconds() */ - Timer(); - ~Timer(); + /** Timer constructor. MUST be called on same thread that calls getMilliseconds() */ + Timer(); + ~Timer(); - /** Method for setting a specific option of the Timer. These options are usually + /** Method for setting a specific option of the Timer. These options are usually specific for a certain implementation of the Timer class, and may (and probably will) not exist across different implementations. reset() must be called after - all setOption() calls. - @par - Current options supported are: -
      • "QueryAffinityMask" (DWORD): Set the thread affinity mask to be used - to check the timer. If 'reset' has been called already this mask should - overlap with the process mask that was in force at that point, and should - be a power of two (a single core).
      + all setOption() calls. + @par + Current options supported are: +
      • "QueryAffinityMask" (DWORD): Set the thread affinity mask to be used + to check the timer. If 'reset' has been called already this mask should + overlap with the process mask that was in force at that point, and should + be a power of two (a single core).
      @param strKey The name of the option to set @param @@ -89,22 +89,22 @@ namespace Ogre */ bool setOption( const String& strKey, const void* pValue ); - /** Resets timer */ - void reset(); + /** Resets timer */ + void reset(); - /** Returns milliseconds since initialisation or last reset */ - unsigned long getMilliseconds(); + /** Returns milliseconds since initialisation or last reset */ + unsigned long getMilliseconds(); - /** Returns microseconds since initialisation or last reset */ - unsigned long getMicroseconds(); + /** Returns microseconds since initialisation or last reset */ + unsigned long getMicroseconds(); - /** Returns milliseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMillisecondsCPU(); + /** Returns milliseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMillisecondsCPU(); - /** Returns microseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMicrosecondsCPU(); + /** Returns microseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMicrosecondsCPU(); }; - /** @} */ - /** @} */ + /** @} */ + /** @} */ } #endif diff --git a/OgreMain/include/asm_math.h b/OgreMain/include/asm_math.h index d3456497b82..37106cabe61 100644 --- a/OgreMain/include/asm_math.h +++ b/OgreMain/include/asm_math.h @@ -19,16 +19,16 @@ const float pi = 4.0f * atan( 1.0f ); const float half_pi = 0.5f * pi; /*============================================================================= - NO EXPLICIT RETURN REQUIRED FROM THESE METHODS!! + NO EXPLICIT RETURN REQUIRED FROM THESE METHODS!! =============================================================================*/ #if OGRE_COMPILER == OGRE_COMPILER_MSVC && OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86 -# pragma warning( push ) -# pragma warning( disable: 4035 ) +# pragma warning( push ) +# pragma warning( disable: 4035 ) #endif float asm_arccos( float r ) { // return half_pi + arctan( r / -sqr( 1.f - r * r ) ); - + #if OGRE_COMPILER == OGRE_COMPILER_MSVC && OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86 float asm_one = 1.f; @@ -48,7 +48,7 @@ float asm_arccos( float r ) { #else - return float( acos( r ) ); + return float( acos( r ) ); #endif } @@ -72,7 +72,7 @@ float asm_arcsin( float r ) { #else - return float( asin( r ) ); + return float( asin( r ) ); #endif @@ -90,7 +90,7 @@ float asm_arctan( float r ) { #else - return float( atan( r ) ); + return float( atan( r ) ); #endif @@ -107,7 +107,7 @@ float asm_sin( float r ) { #else - return sin( r ); + return sin( r ); #endif @@ -123,8 +123,8 @@ float asm_cos( float r ) { } // returns r0 #else - - return cos( r ); + + return cos( r ); #endif } @@ -143,8 +143,8 @@ float asm_tan( float r ) { } // returns r0 #else - - return tan( r ); + + return tan( r ); #endif } @@ -161,7 +161,7 @@ float asm_sqrt( float r ) #else - return sqrt( r ); + return sqrt( r ); #endif } @@ -181,7 +181,7 @@ float asm_rsq( float r ) #else - return 1. / sqrt( r ); + return 1. / sqrt( r ); #endif } @@ -211,7 +211,7 @@ float apx_rsq( float r ) { #else - return 1. / sqrt( r ); + return 1. / sqrt( r ); #endif } @@ -270,21 +270,21 @@ FORCEINLINE float asm_rand() #if 0 #if OGRE_COMP_VER >= 1300 - static unsigned __int64 q = time( NULL ); + static unsigned __int64 q = time( NULL ); - _asm { - movq mm0, q + _asm { + movq mm0, q - // do the magic MMX thing - pshufw mm1, mm0, 0x1E - paddd mm0, mm1 + // do the magic MMX thing + pshufw mm1, mm0, 0x1E + paddd mm0, mm1 - // move to integer memory location and free MMX - movq q, mm0 - emms - } + // move to integer memory location and free MMX + movq q, mm0 + emms + } - return float( q ); + return float( q ); #endif #else // VC6 does not support pshufw @@ -293,7 +293,7 @@ FORCEINLINE float asm_rand() #else // GCC etc - return float( rand() ); + return float( rand() ); #endif } @@ -306,8 +306,8 @@ FORCEINLINE float asm_rand_max() #if 0 #if OGRE_COMP_VER >= 1300 - return (std::numeric_limits< unsigned __int64 >::max)(); - return 9223372036854775807.0f; + return (std::numeric_limits< unsigned __int64 >::max)(); + return 9223372036854775807.0f; #endif #else // VC6 does not support unsigned __int64 @@ -316,7 +316,7 @@ FORCEINLINE float asm_rand_max() #else // GCC etc - return float( RAND_MAX ); + return float( RAND_MAX ); #endif } @@ -360,13 +360,13 @@ float asm_ln( float r ) { #else - return log( r ); + return log( r ); #endif } #if OGRE_COMPILER == OGRE_COMPILER_MSVC && OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32 && OGRE_CPU == OGRE_CPU_X86 -# pragma warning( pop ) +# pragma warning( pop ) #endif } // namespace diff --git a/OgreMain/include/gtk/OgreConfigDialogImp.h b/OgreMain/include/gtk/OgreConfigDialogImp.h index 158379cbaaf..e95f9341e85 100644 --- a/OgreMain/include/gtk/OgreConfigDialogImp.h +++ b/OgreMain/include/gtk/OgreConfigDialogImp.h @@ -90,8 +90,8 @@ namespace Ogre static void rendererChanged (GtkComboBox *widget, gpointer data); /// Callback function to change a renderer option static void optionChanged (GtkComboBox *widget, gpointer data); - /// Idle function to refresh renderer parameters - static gboolean refreshParams (gpointer data); + /// Idle function to refresh renderer parameters + static gboolean refreshParams (gpointer data); }; } #endif diff --git a/OgreMain/include/gtk/OgreErrorDialogImp.h b/OgreMain/include/gtk/OgreErrorDialogImp.h index 9d9f59bdf00..bc6eb3fc871 100644 --- a/OgreMain/include/gtk/OgreErrorDialogImp.h +++ b/OgreMain/include/gtk/OgreErrorDialogImp.h @@ -32,21 +32,21 @@ THE SOFTWARE. namespace Ogre { - /** Class for displaying the error dialog if Ogre fails badly. */ - class _OgreExport ErrorDialog - { - public: - ErrorDialog(); + /** Class for displaying the error dialog if Ogre fails badly. */ + class _OgreExport ErrorDialog + { + public: + ErrorDialog(); - /** - @remarks - Displays the error dialog. - @param - errorMessage The error message which has caused the failure. - @param - logName Optional name of the log to display in the detail pane. - */ + /** + @remarks + Displays the error dialog. + @param + errorMessage The error message which has caused the failure. + @param + logName Optional name of the log to display in the detail pane. + */ void display(const String& errorMessage, String logName = ""); - }; + }; } #endif diff --git a/OgreMain/include/iOS/OgreConfigDialogImp.h b/OgreMain/include/iOS/OgreConfigDialogImp.h index 450ca30e27f..39d6fe03de9 100644 --- a/OgreMain/include/iOS/OgreConfigDialogImp.h +++ b/OgreMain/include/iOS/OgreConfigDialogImp.h @@ -34,23 +34,23 @@ namespace Ogre { - class _OgreExport ConfigDialog : public UtilityAlloc - { - public: - ConfigDialog(); - ~ConfigDialog(); - - public: - void initialise(); - void run(); - void cancel(); + class _OgreExport ConfigDialog : public UtilityAlloc + { + public: + ConfigDialog(); + ~ConfigDialog(); + + public: + void initialise(); + void run(); + void cancel(); - bool display(); + bool display(); - protected: - RenderSystem* iSelectedRenderSystem; - bool iDisplayStatus; - }; + protected: + RenderSystem* iSelectedRenderSystem; + bool iDisplayStatus; + }; } #endif // __iOS_CONFIG_DIALOG_H__ diff --git a/OgreMain/include/iOS/OgreErrorDialogImp.h b/OgreMain/include/iOS/OgreErrorDialogImp.h index 86412158d47..bf69af8729b 100644 --- a/OgreMain/include/iOS/OgreErrorDialogImp.h +++ b/OgreMain/include/iOS/OgreErrorDialogImp.h @@ -32,21 +32,21 @@ THE SOFTWARE. namespace Ogre { - /** Class for displaying the error dialog if Ogre fails badly. */ - class _OgreExport ErrorDialog - { - public: - ErrorDialog(); + /** Class for displaying the error dialog if Ogre fails badly. */ + class _OgreExport ErrorDialog + { + public: + ErrorDialog(); - /** - @remarks - Displays the error dialog. - @param - errorMessage The error message which has caused the failure. - @param - logName Optional name of the log to display in the detail pane. - */ - void display(const String& errorMessage, String logName = ""); - }; + /** + @remarks + Displays the error dialog. + @param + errorMessage The error message which has caused the failure. + @param + logName Optional name of the log to display in the detail pane. + */ + void display(const String& errorMessage, String logName = ""); + }; } #endif diff --git a/OgreMain/include/iOS/OgreOSXCocoaTouchView.h b/OgreMain/include/iOS/OgreOSXCocoaTouchView.h index a23f2d6f8d7..d24dbe4204d 100644 --- a/OgreMain/include/iOS/OgreOSXCocoaTouchView.h +++ b/OgreMain/include/iOS/OgreOSXCocoaTouchView.h @@ -34,7 +34,7 @@ THE SOFTWARE. @interface OgreView : UIView { - Ogre::RenderWindow *window; + Ogre::RenderWindow *window; } - (id)initWithFrame:(CGRect)f; diff --git a/OgreMain/include/iOS/OgreTimerImp.h b/OgreMain/include/iOS/OgreTimerImp.h index f38cb9b6c43..4ef85d7cfe3 100644 --- a/OgreMain/include/iOS/OgreTimerImp.h +++ b/OgreMain/include/iOS/OgreTimerImp.h @@ -33,20 +33,20 @@ THE SOFTWARE. namespace Ogre { - /** Timer class */ - class _OgreExport Timer : public TimerAlloc - { - private: - struct timeval start; - clock_t zeroClock; - public: - Timer(); - ~Timer(); + /** Timer class */ + class _OgreExport Timer : public TimerAlloc + { + private: + struct timeval start; + clock_t zeroClock; + public: + Timer(); + ~Timer(); - /** Method for setting a specific option of the Timer. These options are usually + /** Method for setting a specific option of the Timer. These options are usually specific for a certain implementation of the Timer class, and may (and probably will) not exist across different implementations. reset() must be called after - all setOption() calls. + all setOption() calls. @param strKey The name of the option to set @param @@ -59,20 +59,20 @@ namespace Ogre */ bool setOption( const String& strKey, const void* pValue ) { return false; } - /** Resets timer */ - void reset(); + /** Resets timer */ + void reset(); - /** Returns milliseconds since initialisation or last reset */ - unsigned long getMilliseconds(); + /** Returns milliseconds since initialisation or last reset */ + unsigned long getMilliseconds(); - /** Returns microseconds since initialisation or last reset */ - unsigned long getMicroseconds(); + /** Returns microseconds since initialisation or last reset */ + unsigned long getMicroseconds(); - /** Returns milliseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMillisecondsCPU(); + /** Returns milliseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMillisecondsCPU(); - /** Returns microseconds since initialisation or last reset, only CPU time measured */ - unsigned long getMicrosecondsCPU(); - }; + /** Returns microseconds since initialisation or last reset, only CPU time measured */ + unsigned long getMicrosecondsCPU(); + }; } #endif diff --git a/OgreMain/src/Android/JNI/OgreActivityJNI.cpp b/OgreMain/src/Android/JNI/OgreActivityJNI.cpp index b3c0d832ce8..f88af83d0ef 100644 --- a/OgreMain/src/Android/JNI/OgreActivityJNI.cpp +++ b/OgreMain/src/Android/JNI/OgreActivityJNI.cpp @@ -1,220 +1,220 @@ -/* ------------------------------------------------------------------------------ -This source file is part of OGRE -(Object-oriented Graphics Rendering Engine) -For the latest info, see http://www.ogre3d.org/ - -Copyright (c) 2000-2012 Torus Knot Software Ltd - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. ------------------------------------------------------------------------------ -*/ - -#include -#include -#include -#include -#include -#include -#include "OgrePlatform.h" -#include "OgreRoot.h" -#include "OgreRenderWindow.h" -#include "OgreArchiveManager.h" -#include "OgreViewport.h" - -#include "Android/OgreAndroidEGLWindow.h" -#include "Android/OgreAPKFileSystemArchive.h" -#include "Android/OgreAPKZipArchive.h" - -#ifdef OGRE_BUILD_PLUGIN_OCTREE -# include "OgreOctreePlugin.h" -#endif - -#ifdef OGRE_BUILD_PLUGIN_PFX -# include "OgreParticleFXPlugin.h" -#endif - -#ifdef OGRE_BUILD_COMPONENT_OVERLAY -# include "OgreOverlaySystem.h" -#endif - -#include "OgreConfigFile.h" - -#ifdef OGRE_BUILD_RENDERSYSTEM_GLES2 -# include "OgreGLES2Plugin.h" -# define GLESRS GLES2Plugin -#else -# include "OgreGLESPlugin.h" -# define GLESRS GLESPlugin -#endif - -using namespace Ogre; - -static bool gInit = false; -static Ogre::Root* gRoot = NULL; -static Ogre::RenderWindow* gRenderWnd = NULL; - -#ifdef OGRE_BUILD_PLUGIN_OCTREE -static Ogre::OctreePlugin* gOctreePlugin = NULL; -#endif - -#ifdef OGRE_BUILD_PLUGIN_PFX -static Ogre::ParticleFXPlugin* gParticleFXPlugin = NULL; -#endif - -#ifdef OGRE_BUILD_COMPONENT_OVERLAY -static Ogre::OverlaySystem* gOverlaySystem = NULL; -#endif - -static Ogre::GLESRS* gGLESPlugin = NULL; - -static Ogre::SceneManager* pSceneMgr = NULL; -static Ogre::Camera* pCamera = NULL; -static JavaVM* gVM = NULL; -extern "C" -{ - JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) - { - gVM = vm; - return JNI_VERSION_1_4; - } - - JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_create(JNIEnv * env, jobject obj, jobject assetManager) - { - if(gInit) - return; - - gRoot = new Ogre::Root(); - - gGLESPlugin = OGRE_NEW GLESRS(); - gRoot->installPlugin(gGLESPlugin); - -#ifdef OGRE_BUILD_PLUGIN_OCTREE - gOctreePlugin = OGRE_NEW OctreePlugin(); - gRoot->installPlugin(gOctreePlugin); -#endif - -#ifdef OGRE_BUILD_PLUGIN_PFX - gParticleFXPlugin = OGRE_NEW ParticleFXPlugin(); - gRoot->installPlugin(gParticleFXPlugin); -#endif - -#ifdef OGRE_BUILD_COMPONENT_OVERLAY - gOverlaySystem = OGRE_NEW OverlaySystem(); -#endif - - gRoot->setRenderSystem(gRoot->getAvailableRenderers().at(0)); - gRoot->initialise(false); - gInit = true; - - AAssetManager* assetMgr = AAssetManager_fromJava(env, assetManager); - if (assetMgr) - { - ArchiveManager::getSingleton().addArchiveFactory( new APKFileSystemArchiveFactory(assetMgr) ); - ArchiveManager::getSingleton().addArchiveFactory( new APKZipArchiveFactory(assetMgr) ); - } - } - - JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_destroy(JNIEnv * env, jobject obj) - { - if(!gInit) - return; - - gInit = false; - -#ifdef OGRE_BUILD_COMPONENT_OVERLAY - OGRE_DELETE gOverlaySystem; - gOverlaySystem = NULL; -#endif - - OGRE_DELETE gRoot; - gRoot = NULL; - gRenderWnd = NULL; - -#ifdef OGRE_BUILD_PLUGIN_PFX - OGRE_DELETE gParticleFXPlugin; - gParticleFXPlugin = NULL; -#endif - -#ifdef OGRE_BUILD_PLUGIN_OCTREE - OGRE_DELETE gOctreePlugin; - gOctreePlugin = NULL; -#endif - - OGRE_DELETE gGLESPlugin; - gGLESPlugin = NULL; - } - - - JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_initWindow(JNIEnv * env, jobject obj, jobject surface) - { - if(surface) - { - ANativeWindow* nativeWnd = ANativeWindow_fromSurface(env, surface); - if (nativeWnd && gRoot) - { - if (!gRenderWnd) - { - Ogre::NameValuePairList opt; - opt["externalWindowHandle"] = Ogre::StringConverter::toString((int)nativeWnd); - gRenderWnd = Ogre::Root::getSingleton().createRenderWindow("OgreWindow", 0, 0, false, &opt); - - - if(pSceneMgr == NULL) - { - pSceneMgr = gRoot->createSceneManager(Ogre::ST_GENERIC); - pCamera = pSceneMgr->createCamera("MyCam"); - - Ogre::Viewport* vp = gRenderWnd->addViewport(pCamera); - vp->setBackgroundColour(Ogre::ColourValue(1,0,0)); - } - } - else - { - static_cast(gRenderWnd)->_createInternalResources(nativeWnd, NULL); - } - } - } - } - - JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_termWindow(JNIEnv * env, jobject obj) - { - if(gRoot && gRenderWnd) - { - static_cast(gRenderWnd)->_destroyInternalResources(); - } - } - - JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_renderOneFrame(JNIEnv * env, jobject obj) - { - if(gRenderWnd != NULL && gRenderWnd->isActive()) - { - try - { - if(gVM->AttachCurrentThread(&env, NULL) < 0) - return; - - gRenderWnd->windowMovedOrResized(); - gRoot->renderOneFrame(); - - //gVM->DetachCurrentThread(); - }catch(Ogre::RenderingAPIException ex) {} - } - } -}; +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org/ + +Copyright (c) 2000-2012 Torus Knot Software Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include +#include "OgrePlatform.h" +#include "OgreRoot.h" +#include "OgreRenderWindow.h" +#include "OgreArchiveManager.h" +#include "OgreViewport.h" + +#include "Android/OgreAndroidEGLWindow.h" +#include "Android/OgreAPKFileSystemArchive.h" +#include "Android/OgreAPKZipArchive.h" + +#ifdef OGRE_BUILD_PLUGIN_OCTREE +# include "OgreOctreePlugin.h" +#endif + +#ifdef OGRE_BUILD_PLUGIN_PFX +# include "OgreParticleFXPlugin.h" +#endif + +#ifdef OGRE_BUILD_COMPONENT_OVERLAY +# include "OgreOverlaySystem.h" +#endif + +#include "OgreConfigFile.h" + +#ifdef OGRE_BUILD_RENDERSYSTEM_GLES2 +# include "OgreGLES2Plugin.h" +# define GLESRS GLES2Plugin +#else +# include "OgreGLESPlugin.h" +# define GLESRS GLESPlugin +#endif + +using namespace Ogre; + +static bool gInit = false; +static Ogre::Root* gRoot = NULL; +static Ogre::RenderWindow* gRenderWnd = NULL; + +#ifdef OGRE_BUILD_PLUGIN_OCTREE +static Ogre::OctreePlugin* gOctreePlugin = NULL; +#endif + +#ifdef OGRE_BUILD_PLUGIN_PFX +static Ogre::ParticleFXPlugin* gParticleFXPlugin = NULL; +#endif + +#ifdef OGRE_BUILD_COMPONENT_OVERLAY +static Ogre::OverlaySystem* gOverlaySystem = NULL; +#endif + +static Ogre::GLESRS* gGLESPlugin = NULL; + +static Ogre::SceneManager* pSceneMgr = NULL; +static Ogre::Camera* pCamera = NULL; +static JavaVM* gVM = NULL; +extern "C" +{ + JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) + { + gVM = vm; + return JNI_VERSION_1_4; + } + + JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_create(JNIEnv * env, jobject obj, jobject assetManager) + { + if(gInit) + return; + + gRoot = new Ogre::Root(); + + gGLESPlugin = OGRE_NEW GLESRS(); + gRoot->installPlugin(gGLESPlugin); + +#ifdef OGRE_BUILD_PLUGIN_OCTREE + gOctreePlugin = OGRE_NEW OctreePlugin(); + gRoot->installPlugin(gOctreePlugin); +#endif + +#ifdef OGRE_BUILD_PLUGIN_PFX + gParticleFXPlugin = OGRE_NEW ParticleFXPlugin(); + gRoot->installPlugin(gParticleFXPlugin); +#endif + +#ifdef OGRE_BUILD_COMPONENT_OVERLAY + gOverlaySystem = OGRE_NEW OverlaySystem(); +#endif + + gRoot->setRenderSystem(gRoot->getAvailableRenderers().at(0)); + gRoot->initialise(false); + gInit = true; + + AAssetManager* assetMgr = AAssetManager_fromJava(env, assetManager); + if (assetMgr) + { + ArchiveManager::getSingleton().addArchiveFactory( new APKFileSystemArchiveFactory(assetMgr) ); + ArchiveManager::getSingleton().addArchiveFactory( new APKZipArchiveFactory(assetMgr) ); + } + } + + JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_destroy(JNIEnv * env, jobject obj) + { + if(!gInit) + return; + + gInit = false; + +#ifdef OGRE_BUILD_COMPONENT_OVERLAY + OGRE_DELETE gOverlaySystem; + gOverlaySystem = NULL; +#endif + + OGRE_DELETE gRoot; + gRoot = NULL; + gRenderWnd = NULL; + +#ifdef OGRE_BUILD_PLUGIN_PFX + OGRE_DELETE gParticleFXPlugin; + gParticleFXPlugin = NULL; +#endif + +#ifdef OGRE_BUILD_PLUGIN_OCTREE + OGRE_DELETE gOctreePlugin; + gOctreePlugin = NULL; +#endif + + OGRE_DELETE gGLESPlugin; + gGLESPlugin = NULL; + } + + + JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_initWindow(JNIEnv * env, jobject obj, jobject surface) + { + if(surface) + { + ANativeWindow* nativeWnd = ANativeWindow_fromSurface(env, surface); + if (nativeWnd && gRoot) + { + if (!gRenderWnd) + { + Ogre::NameValuePairList opt; + opt["externalWindowHandle"] = Ogre::StringConverter::toString((int)nativeWnd); + gRenderWnd = Ogre::Root::getSingleton().createRenderWindow("OgreWindow", 0, 0, false, &opt); + + + if(pSceneMgr == NULL) + { + pSceneMgr = gRoot->createSceneManager(Ogre::ST_GENERIC); + pCamera = pSceneMgr->createCamera("MyCam"); + + Ogre::Viewport* vp = gRenderWnd->addViewport(pCamera); + vp->setBackgroundColour(Ogre::ColourValue(1,0,0)); + } + } + else + { + static_cast(gRenderWnd)->_createInternalResources(nativeWnd, NULL); + } + } + } + } + + JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_termWindow(JNIEnv * env, jobject obj) + { + if(gRoot && gRenderWnd) + { + static_cast(gRenderWnd)->_destroyInternalResources(); + } + } + + JNIEXPORT void JNICALL Java_org_ogre3d_android_OgreActivityJNI_renderOneFrame(JNIEnv * env, jobject obj) + { + if(gRenderWnd != NULL && gRenderWnd->isActive()) + { + try + { + if(gVM->AttachCurrentThread(&env, NULL) < 0) + return; + + gRenderWnd->windowMovedOrResized(); + gRoot->renderOneFrame(); + + //gVM->DetachCurrentThread(); + }catch(Ogre::RenderingAPIException ex) {} + } + } +}; diff --git a/OgreMain/src/Android/OgreAPKFileSystemArchive.cpp b/OgreMain/src/Android/OgreAPKFileSystemArchive.cpp index a4ce88c7589..5d81e62a1df 100644 --- a/OgreMain/src/Android/OgreAPKFileSystemArchive.cpp +++ b/OgreMain/src/Android/OgreAPKFileSystemArchive.cpp @@ -5,176 +5,176 @@ namespace Ogre{ - APKFileSystemArchive::APKFileSystemArchive(const String& name, const String& archType, AAssetManager* assetMgr) - :Archive(name, archType), mAssetMgr(assetMgr) - { + APKFileSystemArchive::APKFileSystemArchive(const String& name, const String& archType, AAssetManager* assetMgr) + :Archive(name, archType), mAssetMgr(assetMgr) + { if (mName.size() > 0 && mName[0] == '/') - mName.erase(mName.begin()); + mName.erase(mName.begin()); mPathPreFix = mName; if (mPathPreFix.size() > 0) - mPathPreFix += "/"; - } - - APKFileSystemArchive::~APKFileSystemArchive() - { - unload(); - } - - bool APKFileSystemArchive::isCaseSensitive() const - { - return true; - } - - void APKFileSystemArchive::load() - { - - } - - void APKFileSystemArchive::unload() - { - - } - - DataStreamPtr APKFileSystemArchive::open(const Ogre::String &filename, bool readOnly) const - { - DataStreamPtr stream; - AAsset* asset = AAssetManager_open(mAssetMgr, (mPathPreFix + filename).c_str(), AASSET_MODE_BUFFER); - if(asset) - { - off_t length = AAsset_getLength(asset); - void* membuf = OGRE_MALLOC(length, Ogre::MEMCATEGORY_GENERAL); - memcpy(membuf, AAsset_getBuffer(asset), length); - AAsset_close(asset); - - stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream(membuf, length, true, true)); - } - return stream; - } - - DataStreamPtr APKFileSystemArchive::create(const Ogre::String &filename) const - { - return DataStreamPtr(); - } - - void APKFileSystemArchive::remove(const String &filename) const - { - - } - - StringVectorPtr APKFileSystemArchive::list(bool recursive, bool dirs) - { - StringVectorPtr files(new StringVector); - - AAssetDir* dir = AAssetManager_openDir(mAssetMgr, mName.c_str()); - const char* fileName = NULL; - while((fileName = AAssetDir_getNextFileName(dir)) != NULL) - { - files->push_back(fileName); - } - AAssetDir_close(dir); - - return files; - } - - FileInfoListPtr APKFileSystemArchive::listFileInfo(bool recursive, bool dirs) - { - FileInfoListPtr files(new FileInfoList); - - AAssetDir* dir = AAssetManager_openDir(mAssetMgr, mName.c_str()); - const char* fileName = NULL; - while((fileName = AAssetDir_getNextFileName(dir)) != NULL) - { - AAsset* asset = AAssetManager_open(mAssetMgr, (mPathPreFix + String(fileName)).c_str(), AASSET_MODE_UNKNOWN); - if(asset) - { - FileInfo info; - info.archive = this; - info.filename = fileName; - info.path = mName; - info.basename = fileName; - info.compressedSize = AAsset_getLength(asset); - info.uncompressedSize = info.compressedSize; - files->push_back(info); - - AAsset_close(asset); - } - - } - AAssetDir_close(dir); - - return files; - } - - StringVectorPtr APKFileSystemArchive::find(const String& pattern, bool recursive, bool dirs) - { - StringVectorPtr files(new StringVector); - - AAssetDir* dir = AAssetManager_openDir(mAssetMgr, mName.c_str()); - const char* fileName = NULL; - while((fileName = AAssetDir_getNextFileName(dir)) != NULL) - { - if(StringUtil::match(fileName, pattern)) - files->push_back(fileName); - } - AAssetDir_close(dir); - - return files; - } - - FileInfoListPtr APKFileSystemArchive::findFileInfo(const String& pattern, bool recursive, bool dirs) const - { - FileInfoListPtr files(new FileInfoList); - - AAssetDir* dir = AAssetManager_openDir(mAssetMgr, mName.c_str()); - const char* fileName = NULL; - while((fileName = AAssetDir_getNextFileName(dir)) != NULL) - { - if(StringUtil::match(fileName, pattern)) - { - AAsset* asset = AAssetManager_open(mAssetMgr, (mPathPreFix + String(fileName)).c_str(), AASSET_MODE_UNKNOWN); - if(asset) - { - FileInfo info; - info.archive = this; - info.filename = fileName; - info.path = mName; - info.basename = fileName; - info.compressedSize = AAsset_getLength(asset); - info.uncompressedSize = info.compressedSize; - files->push_back(info); - - AAsset_close(asset); - } - } - } - AAssetDir_close(dir); - - return files; - } - - bool APKFileSystemArchive::exists(const String& filename) - { - AAsset* asset = AAssetManager_open(mAssetMgr, (mPathPreFix + filename).c_str(), AASSET_MODE_UNKNOWN); - if(asset) - { - AAsset_close(asset); - return true; - } - return false; - } - - time_t APKFileSystemArchive::getModifiedTime(const Ogre::String &filename) - { - return 0; - } - - ////////////////////////////////////////////////////////////////////////////// - - const String &APKFileSystemArchiveFactory::getType() const - { - static String type = "APKFileSystem"; - return type; - } + mPathPreFix += "/"; + } + + APKFileSystemArchive::~APKFileSystemArchive() + { + unload(); + } + + bool APKFileSystemArchive::isCaseSensitive() const + { + return true; + } + + void APKFileSystemArchive::load() + { + + } + + void APKFileSystemArchive::unload() + { + + } + + DataStreamPtr APKFileSystemArchive::open(const Ogre::String &filename, bool readOnly) const + { + DataStreamPtr stream; + AAsset* asset = AAssetManager_open(mAssetMgr, (mPathPreFix + filename).c_str(), AASSET_MODE_BUFFER); + if(asset) + { + off_t length = AAsset_getLength(asset); + void* membuf = OGRE_MALLOC(length, Ogre::MEMCATEGORY_GENERAL); + memcpy(membuf, AAsset_getBuffer(asset), length); + AAsset_close(asset); + + stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream(membuf, length, true, true)); + } + return stream; + } + + DataStreamPtr APKFileSystemArchive::create(const Ogre::String &filename) const + { + return DataStreamPtr(); + } + + void APKFileSystemArchive::remove(const String &filename) const + { + + } + + StringVectorPtr APKFileSystemArchive::list(bool recursive, bool dirs) + { + StringVectorPtr files(new StringVector); + + AAssetDir* dir = AAssetManager_openDir(mAssetMgr, mName.c_str()); + const char* fileName = NULL; + while((fileName = AAssetDir_getNextFileName(dir)) != NULL) + { + files->push_back(fileName); + } + AAssetDir_close(dir); + + return files; + } + + FileInfoListPtr APKFileSystemArchive::listFileInfo(bool recursive, bool dirs) + { + FileInfoListPtr files(new FileInfoList); + + AAssetDir* dir = AAssetManager_openDir(mAssetMgr, mName.c_str()); + const char* fileName = NULL; + while((fileName = AAssetDir_getNextFileName(dir)) != NULL) + { + AAsset* asset = AAssetManager_open(mAssetMgr, (mPathPreFix + String(fileName)).c_str(), AASSET_MODE_UNKNOWN); + if(asset) + { + FileInfo info; + info.archive = this; + info.filename = fileName; + info.path = mName; + info.basename = fileName; + info.compressedSize = AAsset_getLength(asset); + info.uncompressedSize = info.compressedSize; + files->push_back(info); + + AAsset_close(asset); + } + + } + AAssetDir_close(dir); + + return files; + } + + StringVectorPtr APKFileSystemArchive::find(const String& pattern, bool recursive, bool dirs) + { + StringVectorPtr files(new StringVector); + + AAssetDir* dir = AAssetManager_openDir(mAssetMgr, mName.c_str()); + const char* fileName = NULL; + while((fileName = AAssetDir_getNextFileName(dir)) != NULL) + { + if(StringUtil::match(fileName, pattern)) + files->push_back(fileName); + } + AAssetDir_close(dir); + + return files; + } + + FileInfoListPtr APKFileSystemArchive::findFileInfo(const String& pattern, bool recursive, bool dirs) const + { + FileInfoListPtr files(new FileInfoList); + + AAssetDir* dir = AAssetManager_openDir(mAssetMgr, mName.c_str()); + const char* fileName = NULL; + while((fileName = AAssetDir_getNextFileName(dir)) != NULL) + { + if(StringUtil::match(fileName, pattern)) + { + AAsset* asset = AAssetManager_open(mAssetMgr, (mPathPreFix + String(fileName)).c_str(), AASSET_MODE_UNKNOWN); + if(asset) + { + FileInfo info; + info.archive = this; + info.filename = fileName; + info.path = mName; + info.basename = fileName; + info.compressedSize = AAsset_getLength(asset); + info.uncompressedSize = info.compressedSize; + files->push_back(info); + + AAsset_close(asset); + } + } + } + AAssetDir_close(dir); + + return files; + } + + bool APKFileSystemArchive::exists(const String& filename) + { + AAsset* asset = AAssetManager_open(mAssetMgr, (mPathPreFix + filename).c_str(), AASSET_MODE_UNKNOWN); + if(asset) + { + AAsset_close(asset); + return true; + } + return false; + } + + time_t APKFileSystemArchive::getModifiedTime(const Ogre::String &filename) + { + return 0; + } + + ////////////////////////////////////////////////////////////////////////////// + + const String &APKFileSystemArchiveFactory::getType() const + { + static String type = "APKFileSystem"; + return type; + } } diff --git a/OgreMain/src/Android/OgreAPKZipArchive.cpp b/OgreMain/src/Android/OgreAPKZipArchive.cpp index c35023f8520..65648f2fcc7 100644 --- a/OgreMain/src/Android/OgreAPKZipArchive.cpp +++ b/OgreMain/src/Android/OgreAPKZipArchive.cpp @@ -4,11 +4,11 @@ #include namespace Ogre{ - //----------------------------------------------------------------------- - const String &APKZipArchiveFactory::getType() const - { - static String type = "APKZip"; - return type; - } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + const String &APKZipArchiveFactory::getType() const + { + static String type = "APKZip"; + return type; + } + //----------------------------------------------------------------------- } diff --git a/OgreMain/src/Android/OgreConfigDialog.cpp b/OgreMain/src/Android/OgreConfigDialog.cpp index c995e7c7530..e1a3ede12f5 100644 --- a/OgreMain/src/Android/OgreConfigDialog.cpp +++ b/OgreMain/src/Android/OgreConfigDialog.cpp @@ -30,33 +30,33 @@ THE SOFTWARE. namespace Ogre { - ConfigDialog* dlg = NULL; - - ConfigDialog::ConfigDialog() - { - dlg = this; - } - - ConfigDialog::~ConfigDialog() - { - } - - void ConfigDialog::initialise() + ConfigDialog* dlg = NULL; + + ConfigDialog::ConfigDialog() + { + dlg = this; + } + + ConfigDialog::~ConfigDialog() + { + } + + void ConfigDialog::initialise() + { + } + + void ConfigDialog::run() + { + + } + + void ConfigDialog::cancel() + { + } + + bool ConfigDialog::display() { - } - - void ConfigDialog::run() - { - - } - - void ConfigDialog::cancel() - { - } - - bool ConfigDialog::display() - { - return true; - } + return true; + } }; diff --git a/OgreMain/src/Android/OgreFileSystemLayer.cpp b/OgreMain/src/Android/OgreFileSystemLayer.cpp index f8fc80145b1..b6867bf4010 100644 --- a/OgreMain/src/Android/OgreFileSystemLayer.cpp +++ b/OgreMain/src/Android/OgreFileSystemLayer.cpp @@ -29,21 +29,21 @@ namespace Ogre { - void FileSystemLayer::getConfigPaths() - { - } + void FileSystemLayer::getConfigPaths() + { + } //--------------------------------------------------------------------- - void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) - { - } + void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) + { + } //--------------------------------------------------------------------- - bool FileSystemLayer::fileExists(const Ogre::String& path) const - { - return access(path.c_str(), 00) == 0; - } + bool FileSystemLayer::fileExists(const Ogre::String& path) const + { + return access(path.c_str(), 00) == 0; + } //--------------------------------------------------------------------- - bool FileSystemLayer::createDirectory(const Ogre::String& path) - { - return false; - } + bool FileSystemLayer::createDirectory(const Ogre::String& path) + { + return false; + } } diff --git a/OgreMain/src/Android/OgreTimer.cpp b/OgreMain/src/Android/OgreTimer.cpp index 369bd29e465..9427a907838 100644 --- a/OgreMain/src/Android/OgreTimer.cpp +++ b/OgreMain/src/Android/OgreTimer.cpp @@ -33,7 +33,7 @@ using namespace Ogre; //--------------------------------------------------------------------------------// Timer::Timer() { - reset(); + reset(); } //--------------------------------------------------------------------------------// @@ -44,36 +44,36 @@ Timer::~Timer() //--------------------------------------------------------------------------------// void Timer::reset() { - zeroClock = clock(); - gettimeofday(&start, NULL); + zeroClock = clock(); + gettimeofday(&start, NULL); } //--------------------------------------------------------------------------------// unsigned long Timer::getMilliseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; } //--------------------------------------------------------------------------------// unsigned long Timer::getMicroseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMillisecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMicrosecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; } diff --git a/OgreMain/src/FlashCC/OgreConfigDialog.cpp b/OgreMain/src/FlashCC/OgreConfigDialog.cpp index c995e7c7530..e1a3ede12f5 100644 --- a/OgreMain/src/FlashCC/OgreConfigDialog.cpp +++ b/OgreMain/src/FlashCC/OgreConfigDialog.cpp @@ -30,33 +30,33 @@ THE SOFTWARE. namespace Ogre { - ConfigDialog* dlg = NULL; - - ConfigDialog::ConfigDialog() - { - dlg = this; - } - - ConfigDialog::~ConfigDialog() - { - } - - void ConfigDialog::initialise() + ConfigDialog* dlg = NULL; + + ConfigDialog::ConfigDialog() + { + dlg = this; + } + + ConfigDialog::~ConfigDialog() + { + } + + void ConfigDialog::initialise() + { + } + + void ConfigDialog::run() + { + + } + + void ConfigDialog::cancel() + { + } + + bool ConfigDialog::display() { - } - - void ConfigDialog::run() - { - - } - - void ConfigDialog::cancel() - { - } - - bool ConfigDialog::display() - { - return true; - } + return true; + } }; diff --git a/OgreMain/src/FlashCC/OgreTimer.cpp b/OgreMain/src/FlashCC/OgreTimer.cpp index 369bd29e465..9427a907838 100644 --- a/OgreMain/src/FlashCC/OgreTimer.cpp +++ b/OgreMain/src/FlashCC/OgreTimer.cpp @@ -33,7 +33,7 @@ using namespace Ogre; //--------------------------------------------------------------------------------// Timer::Timer() { - reset(); + reset(); } //--------------------------------------------------------------------------------// @@ -44,36 +44,36 @@ Timer::~Timer() //--------------------------------------------------------------------------------// void Timer::reset() { - zeroClock = clock(); - gettimeofday(&start, NULL); + zeroClock = clock(); + gettimeofday(&start, NULL); } //--------------------------------------------------------------------------------// unsigned long Timer::getMilliseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; } //--------------------------------------------------------------------------------// unsigned long Timer::getMicroseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMillisecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMicrosecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; } diff --git a/OgreMain/src/GLX/OgreConfigDialog.cpp b/OgreMain/src/GLX/OgreConfigDialog.cpp index cad3d2cfed9..6581f15560d 100644 --- a/OgreMain/src/GLX/OgreConfigDialog.cpp +++ b/OgreMain/src/GLX/OgreConfigDialog.cpp @@ -86,268 +86,268 @@ namespace Ogre { * buttons. */ class GLXConfigurator { - /* GUI constants */ - static const int wWidth = 400; // Width of window - static const int wHeight = 340; // Height of window - static const int col1x = 20; // Starting x of column 1 (labels) - static const int col2x = 180; // Starting x of column 2 (options) - static const int col1w = 150; // Width of column 1 (labels) - static const int col2w = 200; // Width of column 2 (options) - static const int ystart = 105; // Starting y of option table rows - static const int rowh = 20; // Height of one row in the option table + /* GUI constants */ + static const int wWidth = 400; // Width of window + static const int wHeight = 340; // Height of window + static const int col1x = 20; // Starting x of column 1 (labels) + static const int col2x = 180; // Starting x of column 2 (options) + static const int col1w = 150; // Width of column 1 (labels) + static const int col2w = 200; // Width of column 2 (options) + static const int ystart = 105; // Starting y of option table rows + static const int rowh = 20; // Height of one row in the option table public: - GLXConfigurator(); - virtual ~GLXConfigurator(); - - bool CreateWindow(); - void Main(); - /** - * Exit from main loop. - */ - void Exit(); + GLXConfigurator(); + virtual ~GLXConfigurator(); + + bool CreateWindow(); + void Main(); + /** + * Exit from main loop. + */ + void Exit(); protected: - Display *mDisplay; - Window mWindow; - Pixmap mBackDrop; - - int mWidth, mHeight; - // Xt - XtAppContext appContext; - Widget toplevel; - - /** - * Create backdrop image, and return it as a Pixmap. - */ - virtual Pixmap CreateBackdrop(Window rootWindow, int depth); - /** - * Called after window initialisation. - */ - virtual bool Init(); - /** - * Called initially, and on expose. - */ - virtual void Draw(); + Display *mDisplay; + Window mWindow; + Pixmap mBackDrop; + + int mWidth, mHeight; + // Xt + XtAppContext appContext; + Widget toplevel; + + /** + * Create backdrop image, and return it as a Pixmap. + */ + virtual Pixmap CreateBackdrop(Window rootWindow, int depth); + /** + * Called after window initialisation. + */ + virtual bool Init(); + /** + * Called initially, and on expose. + */ + virtual void Draw(); public: - /* Local */ - bool accept; - /* Class that binds a callback to a RenderSystem */ - class RendererCallbackData { - public: - RendererCallbackData(GLXConfigurator *parent_, RenderSystem *renderer_, Widget optionmenu_): - parent(parent_), - renderer(renderer_), - optionmenu(optionmenu_) { - } - GLXConfigurator *parent; - RenderSystem *renderer; - Widget optionmenu; - }; - std::list mRendererCallbackData; - - RenderSystem *mRenderer; - Widget box; // Box'o control widgets - std::list mRenderOptionWidgets; // List of RenderSystem specific - // widgets for visibility management (cleared when another rendersystem is selected) - /* Class that binds a callback to a certain configuration option/value */ - class ConfigCallbackData { - public: - ConfigCallbackData(GLXConfigurator *parent_, const String &optionName_, const String &valueName_, Widget optionmenu_): - parent(parent_), - optionName(optionName_), - valueName(valueName_), - optionmenu(optionmenu_) { - } - GLXConfigurator *parent; - String optionName, valueName; - Widget optionmenu; - }; - std::list mConfigCallbackData; - - void SetRenderSystem(RenderSystem *sys) { - mRenderer = sys; - } + /* Local */ + bool accept; + /* Class that binds a callback to a RenderSystem */ + class RendererCallbackData { + public: + RendererCallbackData(GLXConfigurator *parent_, RenderSystem *renderer_, Widget optionmenu_): + parent(parent_), + renderer(renderer_), + optionmenu(optionmenu_) { + } + GLXConfigurator *parent; + RenderSystem *renderer; + Widget optionmenu; + }; + std::list mRendererCallbackData; + + RenderSystem *mRenderer; + Widget box; // Box'o control widgets + std::list mRenderOptionWidgets; // List of RenderSystem specific + // widgets for visibility management (cleared when another rendersystem is selected) + /* Class that binds a callback to a certain configuration option/value */ + class ConfigCallbackData { + public: + ConfigCallbackData(GLXConfigurator *parent_, const String &optionName_, const String &valueName_, Widget optionmenu_): + parent(parent_), + optionName(optionName_), + valueName(valueName_), + optionmenu(optionmenu_) { + } + GLXConfigurator *parent; + String optionName, valueName; + Widget optionmenu; + }; + std::list mConfigCallbackData; + + void SetRenderSystem(RenderSystem *sys) { + mRenderer = sys; + } private: - /* Callbacks that terminate modal dialog loop */ - static void acceptHandler(Widget w, GLXConfigurator *obj, XtPointer callData) { - // Check if a renderer was selected, if not, don't accept - if(!obj->mRenderer) - return; - obj->accept = true; - obj->Exit(); - } - static void cancelHandler(Widget w, GLXConfigurator *obj, XtPointer callData) { - obj->Exit(); - } - /* Callbacks that set a setting */ - static void renderSystemHandler(Widget w, RendererCallbackData *cdata, XtPointer callData) { - // Set selected renderer its name + /* Callbacks that terminate modal dialog loop */ + static void acceptHandler(Widget w, GLXConfigurator *obj, XtPointer callData) { + // Check if a renderer was selected, if not, don't accept + if(!obj->mRenderer) + return; + obj->accept = true; + obj->Exit(); + } + static void cancelHandler(Widget w, GLXConfigurator *obj, XtPointer callData) { + obj->Exit(); + } + /* Callbacks that set a setting */ + static void renderSystemHandler(Widget w, RendererCallbackData *cdata, XtPointer callData) { + // Set selected renderer its name XtVaSetValues(cdata->optionmenu, XtNlabel, cdata->renderer->getName().c_str(), 0, NULL); - // Notify Configurator (and Ogre) - cdata->parent->SetRenderer(cdata->renderer); - } - static void configOptionHandler(Widget w, ConfigCallbackData *cdata, XtPointer callData) { - // Set selected renderer its name + // Notify Configurator (and Ogre) + cdata->parent->SetRenderer(cdata->renderer); + } + static void configOptionHandler(Widget w, ConfigCallbackData *cdata, XtPointer callData) { + // Set selected renderer its name XtVaSetValues(cdata->optionmenu, XtNlabel, cdata->valueName.c_str(), 0, NULL); - // Notify Configurator (and Ogre) - cdata->parent->SetConfigOption(cdata->optionName, cdata->valueName); - } + // Notify Configurator (and Ogre) + cdata->parent->SetConfigOption(cdata->optionName, cdata->valueName); + } - /* Functions reacting to GUI */ - void SetRenderer(RenderSystem *); - void SetConfigOption(const String &optionName, const String &valueName); + /* Functions reacting to GUI */ + void SetRenderer(RenderSystem *); + void SetConfigOption(const String &optionName, const String &valueName); }; GLXConfigurator::GLXConfigurator(): - mDisplay(0), mWindow(0), mBackDrop(0), - mWidth(wWidth), mHeight(wHeight), - appContext(0), toplevel(0), + mDisplay(0), mWindow(0), mBackDrop(0), + mWidth(wWidth), mHeight(wHeight), + appContext(0), toplevel(0), - accept(false), - mRenderer(0) { + accept(false), + mRenderer(0) { } GLXConfigurator::~GLXConfigurator() { - if(mBackDrop) - XFreePixmap(mDisplay, mBackDrop); - if(toplevel) { - XtUnrealizeWidget(toplevel); - XtDestroyWidget(toplevel); - } - if(mDisplay) { - XCloseDisplay(mDisplay); - } + if(mBackDrop) + XFreePixmap(mDisplay, mBackDrop); + if(toplevel) { + XtUnrealizeWidget(toplevel); + XtDestroyWidget(toplevel); + } + if(mDisplay) { + XCloseDisplay(mDisplay); + } } bool GLXConfigurator::CreateWindow() { - const char *bla[] = {"Rendering Settings", "-bg", "honeydew3", "-fg", "black","-bd","darkseagreen4"}; - int argc = sizeof(bla)/sizeof(*bla); - - toplevel = XtVaOpenApplication(&appContext, "OGRE", NULL, 0, &argc, const_cast(bla), NULL,sessionShellWidgetClass, - XtNwidth, mWidth, - XtNheight, mHeight, - XtNminWidth, mWidth, - XtNmaxWidth, mWidth, - XtNminHeight, mHeight, - XtNmaxHeight, mHeight, - XtNallowShellResize, False, - XtNborderWidth, 0, - XtNoverrideRedirect, False, - NULL, NULL); - - /* Find out display and screen used */ - mDisplay = XtDisplay(toplevel); - int screen = DefaultScreen(mDisplay); - Window rootWindow = RootWindow(mDisplay,screen); - - /* Move to center of display */ - int w = DisplayWidth(mDisplay, screen); - int h = DisplayHeight(mDisplay, screen); - XtVaSetValues(toplevel, - XtNx, w/2-mWidth/2, - XtNy, h/2-mHeight/2, 0, NULL); - - /* Backdrop stuff */ - mBackDrop = CreateBackdrop(rootWindow, DefaultDepth(mDisplay,screen)); - - /* Create toplevel */ - box = XtVaCreateManagedWidget("box",formWidgetClass,toplevel, - XtNbackgroundPixmap, mBackDrop, - 0,NULL); - - /* Create renderer selection */ - int cury = ystart + 0*rowh; + const char *bla[] = {"Rendering Settings", "-bg", "honeydew3", "-fg", "black","-bd","darkseagreen4"}; + int argc = sizeof(bla)/sizeof(*bla); + + toplevel = XtVaOpenApplication(&appContext, "OGRE", NULL, 0, &argc, const_cast(bla), NULL,sessionShellWidgetClass, + XtNwidth, mWidth, + XtNheight, mHeight, + XtNminWidth, mWidth, + XtNmaxWidth, mWidth, + XtNminHeight, mHeight, + XtNmaxHeight, mHeight, + XtNallowShellResize, False, + XtNborderWidth, 0, + XtNoverrideRedirect, False, + NULL, NULL); + + /* Find out display and screen used */ + mDisplay = XtDisplay(toplevel); + int screen = DefaultScreen(mDisplay); + Window rootWindow = RootWindow(mDisplay,screen); + + /* Move to center of display */ + int w = DisplayWidth(mDisplay, screen); + int h = DisplayHeight(mDisplay, screen); + XtVaSetValues(toplevel, + XtNx, w/2-mWidth/2, + XtNy, h/2-mHeight/2, 0, NULL); + + /* Backdrop stuff */ + mBackDrop = CreateBackdrop(rootWindow, DefaultDepth(mDisplay,screen)); + + /* Create toplevel */ + box = XtVaCreateManagedWidget("box",formWidgetClass,toplevel, + XtNbackgroundPixmap, mBackDrop, + 0,NULL); + + /* Create renderer selection */ + int cury = ystart + 0*rowh; XtVaCreateManagedWidget("topLabel", labelWidgetClass, box, XtNlabel, "Select Renderer", XtNborderWidth, 0, - XtNwidth, col1w, // Fixed width - XtNheight, 18, - XtNleft, XawChainLeft, - XtNtop, XawChainTop, - XtNright, XawChainLeft, - XtNbottom, XawChainTop, - XtNhorizDistance, col1x, - XtNvertDistance, cury, - XtNjustify, XtJustifyLeft, - NULL); - - const char *curRenderName = " Select One "; // Name of current renderer, or hint to select one - if(mRenderer) - curRenderName = mRenderer->getName().c_str(); - Widget mb1 = XtVaCreateManagedWidget("Menu", menuButtonWidgetClass, box, XtNlabel,curRenderName, - XtNresize, false, - XtNresizable, false, - XtNwidth, col2w, // Fixed width - XtNheight, 18, - XtNleft, XawChainLeft, - XtNtop, XawChainTop, - XtNright, XawChainLeft, - XtNbottom, XawChainTop, - XtNhorizDistance, col2x, - XtNvertDistance, cury, - NULL); - - Widget menu = XtVaCreatePopupShell("menu", simpleMenuWidgetClass, mb1, - 0, NULL); - - const RenderSystemList& renderers = Root::getSingleton().getAvailableRenderers(); - for (RenderSystemList::const_iterator pRend = renderers.begin(); - pRend != renderers.end(); pRend++) { - // Create callback data - mRendererCallbackData.push_back(RendererCallbackData(this, *pRend, mb1)); - - Widget entry = XtVaCreateManagedWidget("menuentry", smeBSBObjectClass, menu, - XtNlabel, (*pRend)->getName().c_str(), - 0, NULL); - XtAddCallback(entry, XtNcallback, (XtCallbackProc)&GLXConfigurator::renderSystemHandler, &mRendererCallbackData.back()); - } - - Widget bottomPanel = XtVaCreateManagedWidget("bottomPanel", formWidgetClass, box, - XtNsensitive, True, - XtNborderWidth, 0, - XtNwidth, 150, // Fixed width - XtNleft, XawChainLeft, - XtNtop, XawChainTop, - XtNright, XawChainLeft, - XtNbottom, XawChainTop, - XtNhorizDistance, mWidth - 160, - XtNvertDistance, mHeight - 40, - NULL); - - Widget helloButton = XtVaCreateManagedWidget("cancelButton", commandWidgetClass, bottomPanel, XtNlabel," Cancel ", NULL); - XtAddCallback(helloButton, XtNcallback, (XtCallbackProc)&GLXConfigurator::cancelHandler, this); - - Widget exitButton = XtVaCreateManagedWidget("acceptButton", commandWidgetClass, bottomPanel, XtNlabel," Accept ", XtNfromHoriz,helloButton, NULL); - XtAddCallback(exitButton, XtNcallback, (XtCallbackProc)&GLXConfigurator::acceptHandler, this); - - XtRealizeWidget(toplevel); - - if(mRenderer) - /* There was already a renderer selected; display its options */ - SetRenderer(mRenderer); - - return true; + XtNwidth, col1w, // Fixed width + XtNheight, 18, + XtNleft, XawChainLeft, + XtNtop, XawChainTop, + XtNright, XawChainLeft, + XtNbottom, XawChainTop, + XtNhorizDistance, col1x, + XtNvertDistance, cury, + XtNjustify, XtJustifyLeft, + NULL); + + const char *curRenderName = " Select One "; // Name of current renderer, or hint to select one + if(mRenderer) + curRenderName = mRenderer->getName().c_str(); + Widget mb1 = XtVaCreateManagedWidget("Menu", menuButtonWidgetClass, box, XtNlabel,curRenderName, + XtNresize, false, + XtNresizable, false, + XtNwidth, col2w, // Fixed width + XtNheight, 18, + XtNleft, XawChainLeft, + XtNtop, XawChainTop, + XtNright, XawChainLeft, + XtNbottom, XawChainTop, + XtNhorizDistance, col2x, + XtNvertDistance, cury, + NULL); + + Widget menu = XtVaCreatePopupShell("menu", simpleMenuWidgetClass, mb1, + 0, NULL); + + const RenderSystemList& renderers = Root::getSingleton().getAvailableRenderers(); + for (RenderSystemList::const_iterator pRend = renderers.begin(); + pRend != renderers.end(); pRend++) { + // Create callback data + mRendererCallbackData.push_back(RendererCallbackData(this, *pRend, mb1)); + + Widget entry = XtVaCreateManagedWidget("menuentry", smeBSBObjectClass, menu, + XtNlabel, (*pRend)->getName().c_str(), + 0, NULL); + XtAddCallback(entry, XtNcallback, (XtCallbackProc)&GLXConfigurator::renderSystemHandler, &mRendererCallbackData.back()); + } + + Widget bottomPanel = XtVaCreateManagedWidget("bottomPanel", formWidgetClass, box, + XtNsensitive, True, + XtNborderWidth, 0, + XtNwidth, 150, // Fixed width + XtNleft, XawChainLeft, + XtNtop, XawChainTop, + XtNright, XawChainLeft, + XtNbottom, XawChainTop, + XtNhorizDistance, mWidth - 160, + XtNvertDistance, mHeight - 40, + NULL); + + Widget helloButton = XtVaCreateManagedWidget("cancelButton", commandWidgetClass, bottomPanel, XtNlabel," Cancel ", NULL); + XtAddCallback(helloButton, XtNcallback, (XtCallbackProc)&GLXConfigurator::cancelHandler, this); + + Widget exitButton = XtVaCreateManagedWidget("acceptButton", commandWidgetClass, bottomPanel, XtNlabel," Accept ", XtNfromHoriz,helloButton, NULL); + XtAddCallback(exitButton, XtNcallback, (XtCallbackProc)&GLXConfigurator::acceptHandler, this); + + XtRealizeWidget(toplevel); + + if(mRenderer) + /* There was already a renderer selected; display its options */ + SetRenderer(mRenderer); + + return true; } Pixmap GLXConfigurator::CreateBackdrop(Window rootWindow, int depth) { - int bpl; - /* Find out number of bytes per pixel */ - switch(depth) { - default: - LogManager::getSingleton().logMessage("GLX backdrop: Unsupported bit depth"); - /* Unsupported bit depth */ - return 0; - case 15: - case 16: - bpl = 2; break; - case 24: - case 32: - bpl = 4; break; - } - /* Create background pixmap */ - unsigned char *data = 0; // Must be allocated with malloc - - try { + int bpl; + /* Find out number of bytes per pixel */ + switch(depth) { + default: + LogManager::getSingleton().logMessage("GLX backdrop: Unsupported bit depth"); + /* Unsupported bit depth */ + return 0; + case 15: + case 16: + bpl = 2; break; + case 24: + case 32: + bpl = 4; break; + } + /* Create background pixmap */ + unsigned char *data = 0; // Must be allocated with malloc + + try { String imgType = "png"; Image img; MemoryDataStream *imgStream; @@ -356,135 +356,135 @@ Pixmap GLXConfigurator::CreateBackdrop(Window rootWindow, int depth) { // Load backdrop image using OGRE imgStream = new MemoryDataStream(const_cast(GLX_backdrop_data), sizeof(GLX_backdrop_data), false); imgStreamPtr = DataStreamPtr(imgStream); - img.load(imgStreamPtr, imgType); + img.load(imgStreamPtr, imgType); PixelBox src = img.getPixelBox(0, 0); - // Convert and copy image - data = (unsigned char*)malloc(mWidth * mHeight * bpl); // Must be allocated with malloc + // Convert and copy image + data = (unsigned char*)malloc(mWidth * mHeight * bpl); // Must be allocated with malloc PixelBox dst(src, bpl == 2 ? PF_B5G6R5 : PF_A8R8G8B8, data ); PixelUtil::bulkPixelConversion(src, dst); - } catch(Exception &e) { - // Could not find image; never mind - LogManager::getSingleton().logMessage("WARNING: Can not load backdrop for config dialog. " + e.getDescription(), LML_TRIVIAL); - return 0; - } - - GC context = XCreateGC (mDisplay, rootWindow, 0, NULL); - - /* put my pixmap data into the client side X image data structure */ - XImage *image = XCreateImage (mDisplay, NULL, depth, ZPixmap, 0, - (char*)data, - mWidth, mHeight, 8, - mWidth*bpl); + } catch(Exception &e) { + // Could not find image; never mind + LogManager::getSingleton().logMessage("WARNING: Can not load backdrop for config dialog. " + e.getDescription(), LML_TRIVIAL); + return 0; + } + + GC context = XCreateGC (mDisplay, rootWindow, 0, NULL); + + /* put my pixmap data into the client side X image data structure */ + XImage *image = XCreateImage (mDisplay, NULL, depth, ZPixmap, 0, + (char*)data, + mWidth, mHeight, 8, + mWidth*bpl); #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - image->byte_order = MSBFirst; + image->byte_order = MSBFirst; #else image->byte_order = LSBFirst; #endif - /* tell server to start managing my pixmap */ - Pixmap rv = XCreatePixmap(mDisplay, rootWindow, mWidth, - mHeight, depth); + /* tell server to start managing my pixmap */ + Pixmap rv = XCreatePixmap(mDisplay, rootWindow, mWidth, + mHeight, depth); - /* copy from client to server */ - XPutImage(mDisplay, rv, context, image, 0, 0, 0, 0, - mWidth, mHeight); + /* copy from client to server */ + XPutImage(mDisplay, rv, context, image, 0, 0, 0, 0, + mWidth, mHeight); - /* free up the client side pixmap data area */ - XDestroyImage(image); // also cleans data - XFreeGC(mDisplay, context); + /* free up the client side pixmap data area */ + XDestroyImage(image); // also cleans data + XFreeGC(mDisplay, context); - return rv; + return rv; } bool GLXConfigurator::Init() { - // Init misc resources - return true; + // Init misc resources + return true; } void GLXConfigurator::Draw() { } void GLXConfigurator::Main() { - XtAppMainLoop(appContext); + XtAppMainLoop(appContext); } void GLXConfigurator::Exit() { - XtAppSetExitFlag(appContext); + XtAppSetExitFlag(appContext); } void GLXConfigurator::SetRenderer(RenderSystem *r) { - mRenderer = r; - - // Destroy each widget of GUI of previously selected renderer - for(std::list::iterator i=mRenderOptionWidgets.begin(); i!=mRenderOptionWidgets.end(); i++) - XtDestroyWidget(*i); - mRenderOptionWidgets.clear(); - mConfigCallbackData.back(); - - // Create option GUI - int cury = ystart + 1*rowh + 10; - - ConfigOptionMap options = mRenderer->getConfigOptions(); - // Process each option and create an optionmenu widget for it - for (ConfigOptionMap::iterator it = options.begin(); - it != options.end(); it++) { - // if the config option does not have any possible value, then skip it. - // if we create a popup with zero entries, it will crash when you click - // on it. - if (it->second.possibleValues.empty()) - continue; - - Widget lb1 = XtVaCreateManagedWidget("topLabel", labelWidgetClass, box, XtNlabel, it->second.name.c_str(), XtNborderWidth, 0, - XtNwidth, col1w, // Fixed width - XtNheight, 18, - XtNleft, XawChainLeft, - XtNtop, XawChainTop, - XtNright, XawChainLeft, - XtNbottom, XawChainTop, - XtNhorizDistance, col1x, - XtNvertDistance, cury, - XtNjustify, XtJustifyLeft, - NULL); - mRenderOptionWidgets.push_back(lb1); - Widget mb1 = XtVaCreateManagedWidget("Menu", menuButtonWidgetClass, box, XtNlabel, it->second.currentValue.c_str(), - XtNresize, false, - XtNresizable, false, - XtNwidth, col2w, // Fixed width - XtNheight, 18, - XtNleft, XawChainLeft, - XtNtop, XawChainTop, - XtNright, XawChainLeft, - XtNbottom, XawChainTop, - XtNhorizDistance, col2x, - XtNvertDistance, cury, - NULL); - mRenderOptionWidgets.push_back(mb1); - - Widget menu = XtVaCreatePopupShell("menu", simpleMenuWidgetClass, mb1, - 0, NULL); - - // Process each choice - StringVector::iterator opt_it; - for (opt_it = it->second.possibleValues.begin(); - opt_it != it->second.possibleValues.end(); opt_it++) { - // Create callback data - mConfigCallbackData.push_back(ConfigCallbackData(this, it->second.name, *opt_it, mb1)); - - Widget entry = XtVaCreateManagedWidget("menuentry", smeBSBObjectClass, menu, - XtNlabel, (*opt_it).c_str(), - 0, NULL); - XtAddCallback(entry, XtNcallback, (XtCallbackProc)&GLXConfigurator::configOptionHandler, &mConfigCallbackData.back()); - } - cury += rowh; - } + mRenderer = r; + + // Destroy each widget of GUI of previously selected renderer + for(std::list::iterator i=mRenderOptionWidgets.begin(); i!=mRenderOptionWidgets.end(); i++) + XtDestroyWidget(*i); + mRenderOptionWidgets.clear(); + mConfigCallbackData.back(); + + // Create option GUI + int cury = ystart + 1*rowh + 10; + + ConfigOptionMap options = mRenderer->getConfigOptions(); + // Process each option and create an optionmenu widget for it + for (ConfigOptionMap::iterator it = options.begin(); + it != options.end(); it++) { + // if the config option does not have any possible value, then skip it. + // if we create a popup with zero entries, it will crash when you click + // on it. + if (it->second.possibleValues.empty()) + continue; + + Widget lb1 = XtVaCreateManagedWidget("topLabel", labelWidgetClass, box, XtNlabel, it->second.name.c_str(), XtNborderWidth, 0, + XtNwidth, col1w, // Fixed width + XtNheight, 18, + XtNleft, XawChainLeft, + XtNtop, XawChainTop, + XtNright, XawChainLeft, + XtNbottom, XawChainTop, + XtNhorizDistance, col1x, + XtNvertDistance, cury, + XtNjustify, XtJustifyLeft, + NULL); + mRenderOptionWidgets.push_back(lb1); + Widget mb1 = XtVaCreateManagedWidget("Menu", menuButtonWidgetClass, box, XtNlabel, it->second.currentValue.c_str(), + XtNresize, false, + XtNresizable, false, + XtNwidth, col2w, // Fixed width + XtNheight, 18, + XtNleft, XawChainLeft, + XtNtop, XawChainTop, + XtNright, XawChainLeft, + XtNbottom, XawChainTop, + XtNhorizDistance, col2x, + XtNvertDistance, cury, + NULL); + mRenderOptionWidgets.push_back(mb1); + + Widget menu = XtVaCreatePopupShell("menu", simpleMenuWidgetClass, mb1, + 0, NULL); + + // Process each choice + StringVector::iterator opt_it; + for (opt_it = it->second.possibleValues.begin(); + opt_it != it->second.possibleValues.end(); opt_it++) { + // Create callback data + mConfigCallbackData.push_back(ConfigCallbackData(this, it->second.name, *opt_it, mb1)); + + Widget entry = XtVaCreateManagedWidget("menuentry", smeBSBObjectClass, menu, + XtNlabel, (*opt_it).c_str(), + 0, NULL); + XtAddCallback(entry, XtNcallback, (XtCallbackProc)&GLXConfigurator::configOptionHandler, &mConfigCallbackData.back()); + } + cury += rowh; + } } void GLXConfigurator::SetConfigOption(const String &optionName, const String &valueName) { - if(!mRenderer) - // No renderer set -- how can this be called? - return; - mRenderer->setConfigOption(optionName, valueName); - SetRenderer(mRenderer); + if(!mRenderer) + // No renderer set -- how can this be called? + return; + mRenderer->setConfigOption(optionName, valueName); + SetRenderer(mRenderer); } //------------------------------------------------------------------------------------// @@ -495,24 +495,24 @@ ConfigDialog::ConfigDialog() : mSelectedRenderSystem(0) //------------------------------------------------------------------------------------// bool ConfigDialog::display() { - GLXConfigurator test; - /* Select previously selected rendersystem */ - if(Root::getSingleton().getRenderSystem()) - test.SetRenderSystem(Root::getSingleton().getRenderSystem()); - /* Attempt to create the window */ - if(!test.CreateWindow()) - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Could not create configuration dialog", - "GLXConfig::display"); - - // Modal loop - test.Main(); - if(!test.accept) // User did not accept - return false; - - /* All done */ - Root::getSingleton().setRenderSystem(test.mRenderer); - - return true; + GLXConfigurator test; + /* Select previously selected rendersystem */ + if(Root::getSingleton().getRenderSystem()) + test.SetRenderSystem(Root::getSingleton().getRenderSystem()); + /* Attempt to create the window */ + if(!test.CreateWindow()) + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Could not create configuration dialog", + "GLXConfig::display"); + + // Modal loop + test.Main(); + if(!test.accept) // User did not accept + return false; + + /* All done */ + Root::getSingleton().setRenderSystem(test.mRenderer); + + return true; } } diff --git a/OgreMain/src/GLX/OgreErrorDialog.cpp b/OgreMain/src/GLX/OgreErrorDialog.cpp index 0cf4d51a7aa..98c0596c500 100644 --- a/OgreMain/src/GLX/OgreErrorDialog.cpp +++ b/OgreMain/src/GLX/OgreErrorDialog.cpp @@ -38,7 +38,7 @@ ErrorDialog::ErrorDialog() //---------------------------------------------------------------------------// void ErrorDialog::display(const String& errorMessage, String logName) { - std::cout << "*** ERROR: " << errorMessage << std::endl; + std::cout << "*** ERROR: " << errorMessage << std::endl; } } diff --git a/OgreMain/src/GLX/OgreFileSystemLayer.cpp b/OgreMain/src/GLX/OgreFileSystemLayer.cpp index 68a1320de27..7aab4d0f5c2 100644 --- a/OgreMain/src/GLX/OgreFileSystemLayer.cpp +++ b/OgreMain/src/GLX/OgreFileSystemLayer.cpp @@ -34,132 +34,132 @@ namespace Ogre { - namespace { - /** Get actual file pointed to by symlink */ - const Ogre::String resolveSymlink(const Ogre::String& symlink) - { - ssize_t bufsize = 256; - char* resolved = 0; - do - { - char* buf = OGRE_ALLOC_T(char, bufsize, Ogre::MEMCATEGORY_GENERAL); - ssize_t retval = readlink(symlink.c_str(), buf, bufsize); - if (retval == -1) - { - OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); - break; - } + namespace { + /** Get actual file pointed to by symlink */ + const Ogre::String resolveSymlink(const Ogre::String& symlink) + { + ssize_t bufsize = 256; + char* resolved = 0; + do + { + char* buf = OGRE_ALLOC_T(char, bufsize, Ogre::MEMCATEGORY_GENERAL); + ssize_t retval = readlink(symlink.c_str(), buf, bufsize); + if (retval == -1) + { + OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); + break; + } - if (retval < bufsize) - { - // operation was successful. - // readlink does not guarantee to 0-terminate, so do this manually - buf[retval] = '\0'; - resolved = buf; - } - else - { - // buffer was too small, grow buffer and try again - OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); - bufsize <<= 1; - } - } while (!resolved); + if (retval < bufsize) + { + // operation was successful. + // readlink does not guarantee to 0-terminate, so do this manually + buf[retval] = '\0'; + resolved = buf; + } + else + { + // buffer was too small, grow buffer and try again + OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); + bufsize <<= 1; + } + } while (!resolved); - if (resolved) - { - Ogre::String result (resolved); - OGRE_FREE(resolved, Ogre::MEMCATEGORY_GENERAL); - return result; - } - else - return ""; - } - } + if (resolved) + { + Ogre::String result (resolved); + OGRE_FREE(resolved, Ogre::MEMCATEGORY_GENERAL); + return result; + } + else + return ""; + } + } //--------------------------------------------------------------------- - void FileSystemLayer::getConfigPaths() - { - // try to determine the application's path: - // recent systems should provide the executable path via the /proc system - Ogre::String appPath = resolveSymlink("/proc/self/exe"); - if (appPath.empty()) - { - // if /proc/self/exe isn't available, try it via the program's pid - pid_t pid = getpid(); - char proc[64]; - int retval = snprintf(proc, sizeof(proc), "/proc/%llu/exe", (unsigned long long) pid); - if (retval > 0 && retval < (long)sizeof(proc)) - appPath = resolveSymlink(proc); - } + void FileSystemLayer::getConfigPaths() + { + // try to determine the application's path: + // recent systems should provide the executable path via the /proc system + Ogre::String appPath = resolveSymlink("/proc/self/exe"); + if (appPath.empty()) + { + // if /proc/self/exe isn't available, try it via the program's pid + pid_t pid = getpid(); + char proc[64]; + int retval = snprintf(proc, sizeof(proc), "/proc/%llu/exe", (unsigned long long) pid); + if (retval > 0 && retval < (long)sizeof(proc)) + appPath = resolveSymlink(proc); + } - if (!appPath.empty()) - { - // we need to strip the executable name from the path - Ogre::String::size_type pos = appPath.rfind('/'); - if (pos != Ogre::String::npos) - appPath.erase(pos); - } - else - { - // couldn't find actual executable path, assume current working dir - appPath = "."; - } + if (!appPath.empty()) + { + // we need to strip the executable name from the path + Ogre::String::size_type pos = appPath.rfind('/'); + if (pos != Ogre::String::npos) + appPath.erase(pos); + } + else + { + // couldn't find actual executable path, assume current working dir + appPath = "."; + } - // use application path as first config search path - mConfigPaths.push_back(appPath + '/'); - // then search inside ../share/OGRE - mConfigPaths.push_back(appPath + "/../share/OGRE/"); - // then try system wide /etc - mConfigPaths.push_back("/etc/OGRE/"); - } + // use application path as first config search path + mConfigPaths.push_back(appPath + '/'); + // then search inside ../share/OGRE + mConfigPaths.push_back(appPath + "/../share/OGRE/"); + // then try system wide /etc + mConfigPaths.push_back("/etc/OGRE/"); + } //--------------------------------------------------------------------- - void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) - { - struct passwd* pwd = getpwuid(getuid()); - if (pwd) - { - mHomePath = pwd->pw_dir; - } - else - { - // try the $HOME environment variable - mHomePath = getenv("HOME"); - } + void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd) + { + mHomePath = pwd->pw_dir; + } + else + { + // try the $HOME environment variable + mHomePath = getenv("HOME"); + } - if (!mHomePath.empty()) - { - // create an .ogre subdir - mHomePath.append("/.ogre/"); - if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) - { - // can't create dir - mHomePath.clear(); - } - else - { - // now create the given subdir - mHomePath.append(subdir + '/'); - if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) - { - // can't create dir - mHomePath.clear(); - } - } - } + if (!mHomePath.empty()) + { + // create an .ogre subdir + mHomePath.append("/.ogre/"); + if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) + { + // can't create dir + mHomePath.clear(); + } + else + { + // now create the given subdir + mHomePath.append(subdir + '/'); + if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) + { + // can't create dir + mHomePath.clear(); + } + } + } - if (mHomePath.empty()) - { - // couldn't create dir in home directory, fall back to cwd - mHomePath = "./"; - } - } + if (mHomePath.empty()) + { + // couldn't create dir in home directory, fall back to cwd + mHomePath = "./"; + } + } //--------------------------------------------------------------------- - bool FileSystemLayer::fileExists(const Ogre::String& path) const - { - return access(path.c_str(), R_OK) == 0; - } + bool FileSystemLayer::fileExists(const Ogre::String& path) const + { + return access(path.c_str(), R_OK) == 0; + } //--------------------------------------------------------------------- - bool FileSystemLayer::createDirectory(const Ogre::String& path) - { - return !mkdir(path.c_str(), 0755) || errno == EEXIST; - } + bool FileSystemLayer::createDirectory(const Ogre::String& path) + { + return !mkdir(path.c_str(), 0755) || errno == EEXIST; + } } diff --git a/OgreMain/src/GLX/OgreTimer.cpp b/OgreMain/src/GLX/OgreTimer.cpp index 2cba87799c1..c6a38190875 100644 --- a/OgreMain/src/GLX/OgreTimer.cpp +++ b/OgreMain/src/GLX/OgreTimer.cpp @@ -33,7 +33,7 @@ namespace Ogre { //--------------------------------------------------------------------------------// Timer::Timer() { - reset(); + reset(); } //--------------------------------------------------------------------------------// @@ -44,38 +44,38 @@ Timer::~Timer() //--------------------------------------------------------------------------------// void Timer::reset() { - zeroClock = clock(); - gettimeofday(&start, NULL); + zeroClock = clock(); + gettimeofday(&start, NULL); } //--------------------------------------------------------------------------------// unsigned long Timer::getMilliseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; } //--------------------------------------------------------------------------------// unsigned long Timer::getMicroseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMillisecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMicrosecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; } } diff --git a/OgreMain/src/NaCl/OgreConfigDialog.cpp b/OgreMain/src/NaCl/OgreConfigDialog.cpp index a0d3bcf2c8e..1e48a803bd4 100644 --- a/OgreMain/src/NaCl/OgreConfigDialog.cpp +++ b/OgreMain/src/NaCl/OgreConfigDialog.cpp @@ -37,7 +37,7 @@ ConfigDialog::ConfigDialog() : mSelectedRenderSystem(0) //------------------------------------------------------------------------------------// bool ConfigDialog::display() { - return true; + return true; } }; diff --git a/OgreMain/src/NaCl/OgreErrorDialog.cpp b/OgreMain/src/NaCl/OgreErrorDialog.cpp index 90a63fda6e0..4bc6a473174 100644 --- a/OgreMain/src/NaCl/OgreErrorDialog.cpp +++ b/OgreMain/src/NaCl/OgreErrorDialog.cpp @@ -38,5 +38,5 @@ ErrorDialog::ErrorDialog() //---------------------------------------------------------------------------// void ErrorDialog::display(const String& errorMessage, String logName) { - std::cout << "*** ERROR: " << errorMessage << std::endl; + std::cout << "*** ERROR: " << errorMessage << std::endl; } diff --git a/OgreMain/src/NaCl/OgreFileSystemLayer.cpp b/OgreMain/src/NaCl/OgreFileSystemLayer.cpp index ae8a7ea1b66..9ef40f6ab96 100644 --- a/OgreMain/src/NaCl/OgreFileSystemLayer.cpp +++ b/OgreMain/src/NaCl/OgreFileSystemLayer.cpp @@ -34,18 +34,18 @@ namespace Ogre { //--------------------------------------------------------------------- - void FileSystemLayer::getConfigPaths() - { - // use application path as first config search path - mConfigPaths.push_back(""); - } + void FileSystemLayer::getConfigPaths() + { + // use application path as first config search path + mConfigPaths.push_back(""); + } //--------------------------------------------------------------------- - void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) - { - } + void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) + { + } //--------------------------------------------------------------------- - bool FileSystemLayer::fileExists(const Ogre::String& path) const - { + bool FileSystemLayer::fileExists(const Ogre::String& path) const + { return false; } } diff --git a/OgreMain/src/NaCl/OgreTimer.cpp b/OgreMain/src/NaCl/OgreTimer.cpp index 369bd29e465..9427a907838 100644 --- a/OgreMain/src/NaCl/OgreTimer.cpp +++ b/OgreMain/src/NaCl/OgreTimer.cpp @@ -33,7 +33,7 @@ using namespace Ogre; //--------------------------------------------------------------------------------// Timer::Timer() { - reset(); + reset(); } //--------------------------------------------------------------------------------// @@ -44,36 +44,36 @@ Timer::~Timer() //--------------------------------------------------------------------------------// void Timer::reset() { - zeroClock = clock(); - gettimeofday(&start, NULL); + zeroClock = clock(); + gettimeofday(&start, NULL); } //--------------------------------------------------------------------------------// unsigned long Timer::getMilliseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; } //--------------------------------------------------------------------------------// unsigned long Timer::getMicroseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMillisecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMicrosecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; } diff --git a/OgreMain/src/OSX/OgreFileSystemLayer.cpp b/OgreMain/src/OSX/OgreFileSystemLayer.cpp index 6962fa45d28..1aacee28616 100644 --- a/OgreMain/src/OSX/OgreFileSystemLayer.cpp +++ b/OgreMain/src/OSX/OgreFileSystemLayer.cpp @@ -31,60 +31,60 @@ namespace Ogre { - void FileSystemLayer::getConfigPaths() - { - mConfigPaths.push_back(Ogre::macBundlePath() + "/Contents/Resources/"); - mConfigPaths.push_back(Ogre::macBundlePath() + "/"); - } + void FileSystemLayer::getConfigPaths() + { + mConfigPaths.push_back(Ogre::macBundlePath() + "/Contents/Resources/"); + mConfigPaths.push_back(Ogre::macBundlePath() + "/"); + } //--------------------------------------------------------------------- - void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) - { - struct passwd* pwd = getpwuid(getuid()); - if (pwd) - { - mHomePath = pwd->pw_dir; - } - else - { - // try the $HOME environment variable - mHomePath = getenv("HOME"); - } + void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd) + { + mHomePath = pwd->pw_dir; + } + else + { + // try the $HOME environment variable + mHomePath = getenv("HOME"); + } - if (!mHomePath.empty()) - { - // create an Ogre subdir in application support - mHomePath.append("/Library/Application Support/Ogre/"); - if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) - { - // can't create dir - mHomePath.clear(); - } - else - { - // now create the given subdir - mHomePath.append(subdir + '/'); - if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) - { - // can't create dir - mHomePath.clear(); - } - } - } + if (!mHomePath.empty()) + { + // create an Ogre subdir in application support + mHomePath.append("/Library/Application Support/Ogre/"); + if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) + { + // can't create dir + mHomePath.clear(); + } + else + { + // now create the given subdir + mHomePath.append(subdir + '/'); + if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) + { + // can't create dir + mHomePath.clear(); + } + } + } - if (mHomePath.empty()) - { - // couldn't create dir in home directory, fall back to cwd - mHomePath = "./"; - } - } + if (mHomePath.empty()) + { + // couldn't create dir in home directory, fall back to cwd + mHomePath = "./"; + } + } //--------------------------------------------------------------------- - bool FileSystemLayer::fileExists(const Ogre::String& path) const - { - return access(path.c_str(), R_OK) == 0; - } + bool FileSystemLayer::fileExists(const Ogre::String& path) const + { + return access(path.c_str(), R_OK) == 0; + } //--------------------------------------------------------------------- - bool FileSystemLayer::createDirectory(const Ogre::String& path) - { - return !mkdir(path.c_str(), 0755) || errno == EEXIST; - } + bool FileSystemLayer::createDirectory(const Ogre::String& path) + { + return !mkdir(path.c_str(), 0755) || errno == EEXIST; + } } diff --git a/OgreMain/src/OSX/OgreTimer.cpp b/OgreMain/src/OSX/OgreTimer.cpp index 369bd29e465..9427a907838 100644 --- a/OgreMain/src/OSX/OgreTimer.cpp +++ b/OgreMain/src/OSX/OgreTimer.cpp @@ -33,7 +33,7 @@ using namespace Ogre; //--------------------------------------------------------------------------------// Timer::Timer() { - reset(); + reset(); } //--------------------------------------------------------------------------------// @@ -44,36 +44,36 @@ Timer::~Timer() //--------------------------------------------------------------------------------// void Timer::reset() { - zeroClock = clock(); - gettimeofday(&start, NULL); + zeroClock = clock(); + gettimeofday(&start, NULL); } //--------------------------------------------------------------------------------// unsigned long Timer::getMilliseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; } //--------------------------------------------------------------------------------// unsigned long Timer::getMicroseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMillisecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMicrosecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; } diff --git a/OgreMain/src/OgreAnimable.cpp b/OgreMain/src/OgreAnimable.cpp index 4bc5d70259d..bb8b01ce094 100644 --- a/OgreMain/src/OgreAnimable.cpp +++ b/OgreMain/src/OgreAnimable.cpp @@ -30,145 +30,145 @@ THE SOFTWARE. #include "OgreAny.h" namespace Ogre { - //-------------------------------------------------------------------------- - AnimableObject::AnimableDictionaryMap AnimableObject::msAnimableDictionary; - //-------------------------------------------------------------------------- - void AnimableValue::resetToBaseValue(void) - { - switch(mType) - { - case INT: - setValue(mBaseValueInt); - break; - case REAL: - setValue(mBaseValueReal[0]); - break; - case VECTOR2: - setValue(Vector2(mBaseValueReal)); - break; - case VECTOR3: - setValue(Vector3(mBaseValueReal)); - break; - case VECTOR4: - setValue(Vector4(mBaseValueReal)); - break; - case QUATERNION: - setValue(Quaternion(mBaseValueReal)); - break; - case COLOUR: - setValue(ColourValue(mBaseValueReal[0], mBaseValueReal[1], - mBaseValueReal[2], mBaseValueReal[3])); - break; - case DEGREE: - setValue(Degree(mBaseValueReal[0])); - break; - case RADIAN: - setValue(Radian(mBaseValueReal[0])); - break; - } - } - //-------------------------------------------------------------------------- - void AnimableValue::setAsBaseValue(const Any& val) - { - switch(mType) - { - case INT: - setAsBaseValue(any_cast(val)); - break; - case REAL: - setAsBaseValue(any_cast(val)); - break; - case VECTOR2: - setAsBaseValue(any_cast(val)); - break; - case VECTOR3: - setAsBaseValue(any_cast(val)); - break; - case VECTOR4: - setAsBaseValue(any_cast(val)); - break; - case QUATERNION: - setAsBaseValue(any_cast(val)); - break; - case COLOUR: - setAsBaseValue(any_cast(val)); - break; - case DEGREE: - setAsBaseValue(any_cast(val)); - break; - case RADIAN: - setAsBaseValue(any_cast(val)); - break; - } - } - //-------------------------------------------------------------------------- - void AnimableValue::setValue(const Any& val) - { - switch(mType) - { - case INT: - setValue(any_cast(val)); - break; - case REAL: - setValue(any_cast(val)); - break; - case VECTOR2: - setValue(any_cast(val)); - break; - case VECTOR3: - setValue(any_cast(val)); - break; - case VECTOR4: - setValue(any_cast(val)); - break; - case QUATERNION: - setValue(any_cast(val)); - break; - case COLOUR: - setValue(any_cast(val)); - break; - case RADIAN: - setValue(any_cast(val)); - break; - case DEGREE: - setValue(any_cast(val)); - break; - } - } - //-------------------------------------------------------------------------- - void AnimableValue::applyDeltaValue(const Any& val) - { - switch(mType) - { - case INT: - applyDeltaValue(any_cast(val)); - break; - case REAL: - applyDeltaValue(any_cast(val)); - break; - case VECTOR2: - applyDeltaValue(any_cast(val)); - break; - case VECTOR3: - applyDeltaValue(any_cast(val)); - break; - case VECTOR4: - applyDeltaValue(any_cast(val)); - break; - case QUATERNION: - applyDeltaValue(any_cast(val)); - break; - case COLOUR: - applyDeltaValue(any_cast(val)); - break; - case DEGREE: - applyDeltaValue(any_cast(val)); - break; - case RADIAN: - applyDeltaValue(any_cast(val)); - break; - } - } + //-------------------------------------------------------------------------- + AnimableObject::AnimableDictionaryMap AnimableObject::msAnimableDictionary; + //-------------------------------------------------------------------------- + void AnimableValue::resetToBaseValue(void) + { + switch(mType) + { + case INT: + setValue(mBaseValueInt); + break; + case REAL: + setValue(mBaseValueReal[0]); + break; + case VECTOR2: + setValue(Vector2(mBaseValueReal)); + break; + case VECTOR3: + setValue(Vector3(mBaseValueReal)); + break; + case VECTOR4: + setValue(Vector4(mBaseValueReal)); + break; + case QUATERNION: + setValue(Quaternion(mBaseValueReal)); + break; + case COLOUR: + setValue(ColourValue(mBaseValueReal[0], mBaseValueReal[1], + mBaseValueReal[2], mBaseValueReal[3])); + break; + case DEGREE: + setValue(Degree(mBaseValueReal[0])); + break; + case RADIAN: + setValue(Radian(mBaseValueReal[0])); + break; + } + } + //-------------------------------------------------------------------------- + void AnimableValue::setAsBaseValue(const Any& val) + { + switch(mType) + { + case INT: + setAsBaseValue(any_cast(val)); + break; + case REAL: + setAsBaseValue(any_cast(val)); + break; + case VECTOR2: + setAsBaseValue(any_cast(val)); + break; + case VECTOR3: + setAsBaseValue(any_cast(val)); + break; + case VECTOR4: + setAsBaseValue(any_cast(val)); + break; + case QUATERNION: + setAsBaseValue(any_cast(val)); + break; + case COLOUR: + setAsBaseValue(any_cast(val)); + break; + case DEGREE: + setAsBaseValue(any_cast(val)); + break; + case RADIAN: + setAsBaseValue(any_cast(val)); + break; + } + } + //-------------------------------------------------------------------------- + void AnimableValue::setValue(const Any& val) + { + switch(mType) + { + case INT: + setValue(any_cast(val)); + break; + case REAL: + setValue(any_cast(val)); + break; + case VECTOR2: + setValue(any_cast(val)); + break; + case VECTOR3: + setValue(any_cast(val)); + break; + case VECTOR4: + setValue(any_cast(val)); + break; + case QUATERNION: + setValue(any_cast(val)); + break; + case COLOUR: + setValue(any_cast(val)); + break; + case RADIAN: + setValue(any_cast(val)); + break; + case DEGREE: + setValue(any_cast(val)); + break; + } + } + //-------------------------------------------------------------------------- + void AnimableValue::applyDeltaValue(const Any& val) + { + switch(mType) + { + case INT: + applyDeltaValue(any_cast(val)); + break; + case REAL: + applyDeltaValue(any_cast(val)); + break; + case VECTOR2: + applyDeltaValue(any_cast(val)); + break; + case VECTOR3: + applyDeltaValue(any_cast(val)); + break; + case VECTOR4: + applyDeltaValue(any_cast(val)); + break; + case QUATERNION: + applyDeltaValue(any_cast(val)); + break; + case COLOUR: + applyDeltaValue(any_cast(val)); + break; + case DEGREE: + applyDeltaValue(any_cast(val)); + break; + case RADIAN: + applyDeltaValue(any_cast(val)); + break; + } + } diff --git a/OgreMain/src/OgreAnimation.cpp b/OgreMain/src/OgreAnimation.cpp index bc23909a3cb..6a063bb49dc 100644 --- a/OgreMain/src/OgreAnimation.cpp +++ b/OgreMain/src/OgreAnimation.cpp @@ -48,10 +48,10 @@ namespace Ogre { , mInterpolationMode(msDefaultInterpolationMode) , mRotationInterpolationMode(msDefaultRotationInterpolationMode) , mKeyFrameTimesDirty(false) - , mUseBaseKeyFrame(false) - , mBaseKeyFrameTime(0.0f) - , mBaseKeyFrameAnimationName(BLANKSTRING) - , mContainer(0) + , mUseBaseKeyFrame(false) + , mBaseKeyFrameTime(0.0f) + , mBaseKeyFrameAnimationName(BLANKSTRING) + , mContainer(0) { } //--------------------------------------------------------------------- @@ -64,11 +64,11 @@ namespace Ogre { { return mLength; } - //--------------------------------------------------------------------- - void Animation::setLength(Real len) - { - mLength = len; - } + //--------------------------------------------------------------------- + void Animation::setLength(Real len) + { + mLength = len; + } //--------------------------------------------------------------------- NodeAnimationTrack* Animation::createNodeTrack(unsigned short handle) { @@ -99,11 +99,11 @@ namespace Ogre { { return (unsigned short)mNodeTrackList.size(); } - //--------------------------------------------------------------------- - bool Animation::hasNodeTrack(unsigned short handle) const - { - return (mNodeTrackList.find(handle) != mNodeTrackList.end()); - } + //--------------------------------------------------------------------- + bool Animation::hasNodeTrack(unsigned short handle) const + { + return (mNodeTrackList.find(handle) != mNodeTrackList.end()); + } //--------------------------------------------------------------------- NodeAnimationTrack* Animation::getNodeTrack(unsigned short handle) const { @@ -125,12 +125,12 @@ namespace Ogre { { NodeTrackList::iterator i = mNodeTrackList.find(handle); - if (i != mNodeTrackList.end()) - { - OGRE_DELETE i->second; - mNodeTrackList.erase(i); + if (i != mNodeTrackList.end()) + { + OGRE_DELETE i->second; + mNodeTrackList.erase(i); _keyFrameListChanged(); - } + } } //--------------------------------------------------------------------- void Animation::destroyAllNodeTracks(void) @@ -143,9 +143,9 @@ namespace Ogre { mNodeTrackList.clear(); _keyFrameListChanged(); } - //--------------------------------------------------------------------- - NumericAnimationTrack* Animation::createNumericTrack(unsigned short handle) - { + //--------------------------------------------------------------------- + NumericAnimationTrack* Animation::createNumericTrack(unsigned short handle) + { if (hasNumericTrack(handle)) { OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, @@ -154,74 +154,74 @@ namespace Ogre { "Animation::createNumericTrack"); } - NumericAnimationTrack* ret = OGRE_NEW NumericAnimationTrack(this, handle); - - mNumericTrackList[handle] = ret; - return ret; - } - //--------------------------------------------------------------------- - NumericAnimationTrack* Animation::createNumericTrack(unsigned short handle, - const AnimableValuePtr& anim) - { - NumericAnimationTrack* ret = createNumericTrack(handle); - - ret->setAssociatedAnimable(anim); - - return ret; - } - //--------------------------------------------------------------------- - unsigned short Animation::getNumNumericTracks(void) const - { - return (unsigned short)mNumericTrackList.size(); - } - //--------------------------------------------------------------------- - bool Animation::hasNumericTrack(unsigned short handle) const - { - return (mNumericTrackList.find(handle) != mNumericTrackList.end()); - } - //--------------------------------------------------------------------- - NumericAnimationTrack* Animation::getNumericTrack(unsigned short handle) const - { - NumericTrackList::const_iterator i = mNumericTrackList.find(handle); - - if (i == mNumericTrackList.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find numeric track with the specified handle " + + NumericAnimationTrack* ret = OGRE_NEW NumericAnimationTrack(this, handle); + + mNumericTrackList[handle] = ret; + return ret; + } + //--------------------------------------------------------------------- + NumericAnimationTrack* Animation::createNumericTrack(unsigned short handle, + const AnimableValuePtr& anim) + { + NumericAnimationTrack* ret = createNumericTrack(handle); + + ret->setAssociatedAnimable(anim); + + return ret; + } + //--------------------------------------------------------------------- + unsigned short Animation::getNumNumericTracks(void) const + { + return (unsigned short)mNumericTrackList.size(); + } + //--------------------------------------------------------------------- + bool Animation::hasNumericTrack(unsigned short handle) const + { + return (mNumericTrackList.find(handle) != mNumericTrackList.end()); + } + //--------------------------------------------------------------------- + NumericAnimationTrack* Animation::getNumericTrack(unsigned short handle) const + { + NumericTrackList::const_iterator i = mNumericTrackList.find(handle); + + if (i == mNumericTrackList.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find numeric track with the specified handle " + StringConverter::toString(handle), - "Animation::getNumericTrack"); - } + "Animation::getNumericTrack"); + } - return i->second; + return i->second; - } - //--------------------------------------------------------------------- - void Animation::destroyNumericTrack(unsigned short handle) - { - NumericTrackList::iterator i = mNumericTrackList.find(handle); + } + //--------------------------------------------------------------------- + void Animation::destroyNumericTrack(unsigned short handle) + { + NumericTrackList::iterator i = mNumericTrackList.find(handle); - if (i != mNumericTrackList.end()) - { - OGRE_DELETE i->second; - mNumericTrackList.erase(i); + if (i != mNumericTrackList.end()) + { + OGRE_DELETE i->second; + mNumericTrackList.erase(i); _keyFrameListChanged(); - } - } - //--------------------------------------------------------------------- - void Animation::destroyAllNumericTracks(void) - { - NumericTrackList::iterator i; - for (i = mNumericTrackList.begin(); i != mNumericTrackList.end(); ++i) - { - OGRE_DELETE i->second; - } - mNumericTrackList.clear(); + } + } + //--------------------------------------------------------------------- + void Animation::destroyAllNumericTracks(void) + { + NumericTrackList::iterator i; + for (i = mNumericTrackList.begin(); i != mNumericTrackList.end(); ++i) + { + OGRE_DELETE i->second; + } + mNumericTrackList.clear(); _keyFrameListChanged(); - } - //--------------------------------------------------------------------- - VertexAnimationTrack* Animation::createVertexTrack(unsigned short handle, - VertexAnimationType animType) - { + } + //--------------------------------------------------------------------- + VertexAnimationTrack* Animation::createVertexTrack(unsigned short handle, + VertexAnimationType animType) + { if (hasVertexTrack(handle)) { OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, @@ -230,87 +230,87 @@ namespace Ogre { "Animation::createVertexTrack"); } - VertexAnimationTrack* ret = OGRE_NEW VertexAnimationTrack(this, handle, animType); - - mVertexTrackList[handle] = ret; - return ret; - - } - //--------------------------------------------------------------------- - VertexAnimationTrack* Animation::createVertexTrack(unsigned short handle, - VertexData* data, VertexAnimationType animType) - { - VertexAnimationTrack* ret = createVertexTrack(handle, animType); - - ret->setAssociatedVertexData(data); - - return ret; - } - //--------------------------------------------------------------------- - unsigned short Animation::getNumVertexTracks(void) const - { - return (unsigned short)mVertexTrackList.size(); - } - //--------------------------------------------------------------------- - bool Animation::hasVertexTrack(unsigned short handle) const - { - return (mVertexTrackList.find(handle) != mVertexTrackList.end()); - } - //--------------------------------------------------------------------- - VertexAnimationTrack* Animation::getVertexTrack(unsigned short handle) const - { - VertexTrackList::const_iterator i = mVertexTrackList.find(handle); - - if (i == mVertexTrackList.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find vertex track with the specified handle " + + VertexAnimationTrack* ret = OGRE_NEW VertexAnimationTrack(this, handle, animType); + + mVertexTrackList[handle] = ret; + return ret; + + } + //--------------------------------------------------------------------- + VertexAnimationTrack* Animation::createVertexTrack(unsigned short handle, + VertexData* data, VertexAnimationType animType) + { + VertexAnimationTrack* ret = createVertexTrack(handle, animType); + + ret->setAssociatedVertexData(data); + + return ret; + } + //--------------------------------------------------------------------- + unsigned short Animation::getNumVertexTracks(void) const + { + return (unsigned short)mVertexTrackList.size(); + } + //--------------------------------------------------------------------- + bool Animation::hasVertexTrack(unsigned short handle) const + { + return (mVertexTrackList.find(handle) != mVertexTrackList.end()); + } + //--------------------------------------------------------------------- + VertexAnimationTrack* Animation::getVertexTrack(unsigned short handle) const + { + VertexTrackList::const_iterator i = mVertexTrackList.find(handle); + + if (i == mVertexTrackList.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find vertex track with the specified handle " + StringConverter::toString(handle), - "Animation::getVertexTrack"); - } + "Animation::getVertexTrack"); + } - return i->second; + return i->second; - } - //--------------------------------------------------------------------- - void Animation::destroyVertexTrack(unsigned short handle) - { - VertexTrackList::iterator i = mVertexTrackList.find(handle); + } + //--------------------------------------------------------------------- + void Animation::destroyVertexTrack(unsigned short handle) + { + VertexTrackList::iterator i = mVertexTrackList.find(handle); - if (i != mVertexTrackList.end()) - { - OGRE_DELETE i->second; - mVertexTrackList.erase(i); + if (i != mVertexTrackList.end()) + { + OGRE_DELETE i->second; + mVertexTrackList.erase(i); _keyFrameListChanged(); - } - } - //--------------------------------------------------------------------- - void Animation::destroyAllVertexTracks(void) - { - VertexTrackList::iterator i; - for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i) - { - OGRE_DELETE i->second; - } - mVertexTrackList.clear(); + } + } + //--------------------------------------------------------------------- + void Animation::destroyAllVertexTracks(void) + { + VertexTrackList::iterator i; + for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i) + { + OGRE_DELETE i->second; + } + mVertexTrackList.clear(); _keyFrameListChanged(); - } - //--------------------------------------------------------------------- - void Animation::destroyAllTracks(void) - { - destroyAllNodeTracks(); - destroyAllNumericTracks(); - destroyAllVertexTracks(); - } + } + //--------------------------------------------------------------------- + void Animation::destroyAllTracks(void) + { + destroyAllNodeTracks(); + destroyAllNumericTracks(); + destroyAllVertexTracks(); + } //--------------------------------------------------------------------- const String& Animation::getName(void) const { return mName; } //--------------------------------------------------------------------- - void Animation::apply(Real timePos, Real weight, Real scale) + void Animation::apply(Real timePos, Real weight, Real scale) { - _applyBaseKeyFrame(); + _applyBaseKeyFrame(); // Calculate time index for fast keyframe search TimeIndex timeIndex = _getTimeIndex(timePos); @@ -320,22 +320,22 @@ namespace Ogre { { i->second->apply(timeIndex, weight, scale); } - NumericTrackList::iterator j; - for (j = mNumericTrackList.begin(); j != mNumericTrackList.end(); ++j) - { - j->second->apply(timeIndex, weight, scale); - } - VertexTrackList::iterator k; - for (k = mVertexTrackList.begin(); k != mVertexTrackList.end(); ++k) - { - k->second->apply(timeIndex, weight, scale); - } + NumericTrackList::iterator j; + for (j = mNumericTrackList.begin(); j != mNumericTrackList.end(); ++j) + { + j->second->apply(timeIndex, weight, scale); + } + VertexTrackList::iterator k; + for (k = mVertexTrackList.begin(); k != mVertexTrackList.end(); ++k) + { + k->second->apply(timeIndex, weight, scale); + } } //--------------------------------------------------------------------- - void Animation::applyToNode(Node* node, Real timePos, Real weight, Real scale) + void Animation::applyToNode(Node* node, Real timePos, Real weight, Real scale) { - _applyBaseKeyFrame(); + _applyBaseKeyFrame(); // Calculate time index for fast keyframe search TimeIndex timeIndex = _getTimeIndex(timePos); @@ -348,9 +348,9 @@ namespace Ogre { } //--------------------------------------------------------------------- void Animation::apply(Skeleton* skel, Real timePos, Real weight, - Real scale) + Real scale) { - _applyBaseKeyFrame(); + _applyBaseKeyFrame(); // Calculate time index for fast keyframe search TimeIndex timeIndex = _getTimeIndex(timePos); @@ -369,9 +369,9 @@ namespace Ogre { void Animation::apply(Skeleton* skel, Real timePos, float weight, const AnimationState::BoneBlendMask* blendMask, Real scale) { - _applyBaseKeyFrame(); + _applyBaseKeyFrame(); - // Calculate time index for fast keyframe search + // Calculate time index for fast keyframe search TimeIndex timeIndex = _getTimeIndex(timePos); NodeTrackList::iterator i; @@ -379,87 +379,87 @@ namespace Ogre { { // get bone to apply to Bone* b = skel->getBone(i->first); - i->second->applyToNode(b, timeIndex, (*blendMask)[b->getHandle()] * weight, scale); + i->second->applyToNode(b, timeIndex, (*blendMask)[b->getHandle()] * weight, scale); } } - //--------------------------------------------------------------------- - void Animation::apply(Entity* entity, Real timePos, Real weight, - bool software, bool hardware) - { - _applyBaseKeyFrame(); + //--------------------------------------------------------------------- + void Animation::apply(Entity* entity, Real timePos, Real weight, + bool software, bool hardware) + { + _applyBaseKeyFrame(); // Calculate time index for fast keyframe search TimeIndex timeIndex = _getTimeIndex(timePos); - VertexTrackList::iterator i; - for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i) - { - unsigned short handle = i->first; - VertexAnimationTrack* track = i->second; - - VertexData* swVertexData; - VertexData* hwVertexData; - if (handle == 0) - { - // shared vertex data - swVertexData = entity->_getSoftwareVertexAnimVertexData(); - hwVertexData = entity->_getHardwareVertexAnimVertexData(); - entity->_markBuffersUsedForAnimation(); - } - else - { - // sub entity vertex data (-1) - SubEntity* s = entity->getSubEntity(handle - 1); - // Skip this track if subentity is not visible - if (!s->isVisible()) - continue; - swVertexData = s->_getSoftwareVertexAnimVertexData(); - hwVertexData = s->_getHardwareVertexAnimVertexData(); - s->_markBuffersUsedForAnimation(); - } - // Apply to both hardware and software, if requested - if (software) - { - track->setTargetMode(VertexAnimationTrack::TM_SOFTWARE); - track->applyToVertexData(swVertexData, timeIndex, weight, - &(entity->getMesh()->getPoseList())); - } - if (hardware) - { - track->setTargetMode(VertexAnimationTrack::TM_HARDWARE); - track->applyToVertexData(hwVertexData, timeIndex, weight, - &(entity->getMesh()->getPoseList())); - } - } - - } - //--------------------------------------------------------------------- - void Animation::applyToAnimable(const AnimableValuePtr& anim, Real timePos, Real weight, Real scale) - { - _applyBaseKeyFrame(); + VertexTrackList::iterator i; + for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i) + { + unsigned short handle = i->first; + VertexAnimationTrack* track = i->second; + + VertexData* swVertexData; + VertexData* hwVertexData; + if (handle == 0) + { + // shared vertex data + swVertexData = entity->_getSoftwareVertexAnimVertexData(); + hwVertexData = entity->_getHardwareVertexAnimVertexData(); + entity->_markBuffersUsedForAnimation(); + } + else + { + // sub entity vertex data (-1) + SubEntity* s = entity->getSubEntity(handle - 1); + // Skip this track if subentity is not visible + if (!s->isVisible()) + continue; + swVertexData = s->_getSoftwareVertexAnimVertexData(); + hwVertexData = s->_getHardwareVertexAnimVertexData(); + s->_markBuffersUsedForAnimation(); + } + // Apply to both hardware and software, if requested + if (software) + { + track->setTargetMode(VertexAnimationTrack::TM_SOFTWARE); + track->applyToVertexData(swVertexData, timeIndex, weight, + &(entity->getMesh()->getPoseList())); + } + if (hardware) + { + track->setTargetMode(VertexAnimationTrack::TM_HARDWARE); + track->applyToVertexData(hwVertexData, timeIndex, weight, + &(entity->getMesh()->getPoseList())); + } + } + + } + //--------------------------------------------------------------------- + void Animation::applyToAnimable(const AnimableValuePtr& anim, Real timePos, Real weight, Real scale) + { + _applyBaseKeyFrame(); // Calculate time index for fast keyframe search _getTimeIndex(timePos); - NumericTrackList::iterator j; - for (j = mNumericTrackList.begin(); j != mNumericTrackList.end(); ++j) - { - j->second->applyToAnimable(anim, weight, scale); - } + NumericTrackList::iterator j; + for (j = mNumericTrackList.begin(); j != mNumericTrackList.end(); ++j) + { + j->second->applyToAnimable(anim, weight, scale); + } } //--------------------------------------------------------------------- - void Animation::applyToVertexData(VertexData* data, Real timePos, Real weight) + void Animation::applyToVertexData(VertexData* data, Real timePos, Real weight) { - _applyBaseKeyFrame(); - + _applyBaseKeyFrame(); + // Calculate time index for fast keyframe search TimeIndex timeIndex = _getTimeIndex(timePos); - VertexTrackList::iterator k; - for (k = mVertexTrackList.begin(); k != mVertexTrackList.end(); ++k) - { - k->second->applyToVertexData(data, timeIndex, weight); - } + VertexTrackList::iterator k; + for (k = mVertexTrackList.begin(); k != mVertexTrackList.end(); ++k) + { + k->second->applyToVertexData(data, timeIndex, weight); + } } //--------------------------------------------------------------------- void Animation::setInterpolationMode(InterpolationMode im) @@ -487,11 +487,11 @@ namespace Ogre { return mNodeTrackList; } - //--------------------------------------------------------------------- - const Animation::NumericTrackList& Animation::_getNumericTrackList(void) const - { - return mNumericTrackList; - } + //--------------------------------------------------------------------- + const Animation::NumericTrackList& Animation::_getNumericTrackList(void) const + { + return mNumericTrackList; + } //--------------------------------------------------------------------- const Animation::VertexTrackList& Animation::_getVertexTrackList(void) const { @@ -518,121 +518,121 @@ namespace Ogre { return msDefaultRotationInterpolationMode; } //--------------------------------------------------------------------- - void Animation::optimise(bool discardIdentityNodeTracks) - { - optimiseNodeTracks(discardIdentityNodeTracks); - optimiseVertexTracks(); - - } - //----------------------------------------------------------------------- + void Animation::optimise(bool discardIdentityNodeTracks) + { + optimiseNodeTracks(discardIdentityNodeTracks); + optimiseVertexTracks(); + + } + //----------------------------------------------------------------------- void Animation::_collectIdentityNodeTracks(TrackHandleList& tracks) const { - NodeTrackList::const_iterator i, iend; + NodeTrackList::const_iterator i, iend; iend = mNodeTrackList.end(); - for (i = mNodeTrackList.begin(); i != iend; ++i) - { - const NodeAnimationTrack* track = i->second; - if (track->hasNonZeroKeyFrames()) - { + for (i = mNodeTrackList.begin(); i != iend; ++i) + { + const NodeAnimationTrack* track = i->second; + if (track->hasNonZeroKeyFrames()) + { tracks.erase(i->first); } - } + } } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void Animation::_destroyNodeTracks(const TrackHandleList& tracks) { TrackHandleList::const_iterator t, tend; tend = tracks.end(); - for (t = tracks.begin(); t != tend; ++t) - { - destroyNodeTrack(*t); - } - } - //----------------------------------------------------------------------- - void Animation::optimiseNodeTracks(bool discardIdentityTracks) - { - // Iterate over the node tracks and identify those with no useful keyframes - list::type tracksToDestroy; - NodeTrackList::iterator i; - for (i = mNodeTrackList.begin(); i != mNodeTrackList.end(); ++i) - { - NodeAnimationTrack* track = i->second; - if (discardIdentityTracks && !track->hasNonZeroKeyFrames()) - { - // mark the entire track for destruction - tracksToDestroy.push_back(i->first); - } - else - { - track->optimise(); - } - - } - - // Now destroy the tracks we marked for death - for(list::type::iterator h = tracksToDestroy.begin(); - h != tracksToDestroy.end(); ++h) - { - destroyNodeTrack(*h); - } - } - //----------------------------------------------------------------------- - void Animation::optimiseVertexTracks(void) - { - // Iterate over the node tracks and identify those with no useful keyframes - list::type tracksToDestroy; - VertexTrackList::iterator i; - for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i) - { - VertexAnimationTrack* track = i->second; - if (!track->hasNonZeroKeyFrames()) - { - // mark the entire track for destruction - tracksToDestroy.push_back(i->first); - } - else - { - track->optimise(); - } - - } - - // Now destroy the tracks we marked for death - for(list::type::iterator h = tracksToDestroy.begin(); - h != tracksToDestroy.end(); ++h) - { - destroyVertexTrack(*h); - } - - } - //----------------------------------------------------------------------- - Animation* Animation::clone(const String& newName) const - { - Animation* newAnim = OGRE_NEW Animation(newName, mLength); + for (t = tracks.begin(); t != tend; ++t) + { + destroyNodeTrack(*t); + } + } + //----------------------------------------------------------------------- + void Animation::optimiseNodeTracks(bool discardIdentityTracks) + { + // Iterate over the node tracks and identify those with no useful keyframes + list::type tracksToDestroy; + NodeTrackList::iterator i; + for (i = mNodeTrackList.begin(); i != mNodeTrackList.end(); ++i) + { + NodeAnimationTrack* track = i->second; + if (discardIdentityTracks && !track->hasNonZeroKeyFrames()) + { + // mark the entire track for destruction + tracksToDestroy.push_back(i->first); + } + else + { + track->optimise(); + } + + } + + // Now destroy the tracks we marked for death + for(list::type::iterator h = tracksToDestroy.begin(); + h != tracksToDestroy.end(); ++h) + { + destroyNodeTrack(*h); + } + } + //----------------------------------------------------------------------- + void Animation::optimiseVertexTracks(void) + { + // Iterate over the node tracks and identify those with no useful keyframes + list::type tracksToDestroy; + VertexTrackList::iterator i; + for (i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i) + { + VertexAnimationTrack* track = i->second; + if (!track->hasNonZeroKeyFrames()) + { + // mark the entire track for destruction + tracksToDestroy.push_back(i->first); + } + else + { + track->optimise(); + } + + } + + // Now destroy the tracks we marked for death + for(list::type::iterator h = tracksToDestroy.begin(); + h != tracksToDestroy.end(); ++h) + { + destroyVertexTrack(*h); + } + + } + //----------------------------------------------------------------------- + Animation* Animation::clone(const String& newName) const + { + Animation* newAnim = OGRE_NEW Animation(newName, mLength); newAnim->mInterpolationMode = mInterpolationMode; newAnim->mRotationInterpolationMode = mRotationInterpolationMode; - - // Clone all tracks - for (NodeTrackList::const_iterator i = mNodeTrackList.begin(); - i != mNodeTrackList.end(); ++i) - { - i->second->_clone(newAnim); - } - for (NumericTrackList::const_iterator i = mNumericTrackList.begin(); - i != mNumericTrackList.end(); ++i) - { - i->second->_clone(newAnim); - } - for (VertexTrackList::const_iterator i = mVertexTrackList.begin(); - i != mVertexTrackList.end(); ++i) - { - i->second->_clone(newAnim); - } + + // Clone all tracks + for (NodeTrackList::const_iterator i = mNodeTrackList.begin(); + i != mNodeTrackList.end(); ++i) + { + i->second->_clone(newAnim); + } + for (NumericTrackList::const_iterator i = mNumericTrackList.begin(); + i != mNumericTrackList.end(); ++i) + { + i->second->_clone(newAnim); + } + for (VertexTrackList::const_iterator i = mVertexTrackList.begin(); + i != mVertexTrackList.end(); ++i) + { + i->second->_clone(newAnim); + } newAnim->_keyFrameListChanged(); - return newAnim; + return newAnim; - } + } //----------------------------------------------------------------------- TimeIndex Animation::_getTimeIndex(Real timePos) const { @@ -649,7 +649,7 @@ namespace Ogre { Real totalAnimationLength = mLength; if( timePos > totalAnimationLength && totalAnimationLength > 0.0f ) - timePos = fmod( timePos, totalAnimationLength ); + timePos = fmod( timePos, totalAnimationLength ); // Search for global index KeyFrameTimeList::iterator it = @@ -661,8 +661,8 @@ namespace Ogre { void Animation::buildKeyFrameTimeList(void) const { NodeTrackList::const_iterator i; - NumericTrackList::const_iterator j; - VertexTrackList::const_iterator k; + NumericTrackList::const_iterator j; + VertexTrackList::const_iterator k; // Clear old keyframe times mKeyFrameTimes.clear(); @@ -672,122 +672,122 @@ namespace Ogre { { i->second->_collectKeyFrameTimes(mKeyFrameTimes); } - for (j = mNumericTrackList.begin(); j != mNumericTrackList.end(); ++j) - { + for (j = mNumericTrackList.begin(); j != mNumericTrackList.end(); ++j) + { j->second->_collectKeyFrameTimes(mKeyFrameTimes); - } - for (k = mVertexTrackList.begin(); k != mVertexTrackList.end(); ++k) - { + } + for (k = mVertexTrackList.begin(); k != mVertexTrackList.end(); ++k) + { k->second->_collectKeyFrameTimes(mKeyFrameTimes); - } + } // Build global index to local index map for each track for (i = mNodeTrackList.begin(); i != mNodeTrackList.end(); ++i) { i->second->_buildKeyFrameIndexMap(mKeyFrameTimes); } - for (j = mNumericTrackList.begin(); j != mNumericTrackList.end(); ++j) - { + for (j = mNumericTrackList.begin(); j != mNumericTrackList.end(); ++j) + { j->second->_buildKeyFrameIndexMap(mKeyFrameTimes); - } - for (k = mVertexTrackList.begin(); k != mVertexTrackList.end(); ++k) - { + } + for (k = mVertexTrackList.begin(); k != mVertexTrackList.end(); ++k) + { k->second->_buildKeyFrameIndexMap(mKeyFrameTimes); - } + } // Reset dirty flag mKeyFrameTimesDirty = false; } //----------------------------------------------------------------------- - void Animation::setUseBaseKeyFrame(bool useBaseKeyFrame, Real keyframeTime, const String& baseAnimName) - { - if (useBaseKeyFrame != mUseBaseKeyFrame || - keyframeTime != mBaseKeyFrameTime || - baseAnimName != mBaseKeyFrameAnimationName) - { - mUseBaseKeyFrame = useBaseKeyFrame; - mBaseKeyFrameTime = keyframeTime; - mBaseKeyFrameAnimationName = baseAnimName; - } - } + void Animation::setUseBaseKeyFrame(bool useBaseKeyFrame, Real keyframeTime, const String& baseAnimName) + { + if (useBaseKeyFrame != mUseBaseKeyFrame || + keyframeTime != mBaseKeyFrameTime || + baseAnimName != mBaseKeyFrameAnimationName) + { + mUseBaseKeyFrame = useBaseKeyFrame; + mBaseKeyFrameTime = keyframeTime; + mBaseKeyFrameAnimationName = baseAnimName; + } + } //----------------------------------------------------------------------- - bool Animation::getUseBaseKeyFrame() const - { - return mUseBaseKeyFrame; - } + bool Animation::getUseBaseKeyFrame() const + { + return mUseBaseKeyFrame; + } + //----------------------------------------------------------------------- + Real Animation::getBaseKeyFrameTime() const + { + return mBaseKeyFrameTime; + } //----------------------------------------------------------------------- - Real Animation::getBaseKeyFrameTime() const - { - return mBaseKeyFrameTime; - } + const String& Animation::getBaseKeyFrameAnimationName() const + { + return mBaseKeyFrameAnimationName; + } //----------------------------------------------------------------------- - const String& Animation::getBaseKeyFrameAnimationName() const - { - return mBaseKeyFrameAnimationName; - } + void Animation::_applyBaseKeyFrame() + { + if (mUseBaseKeyFrame) + { + Animation* baseAnim = this; + if (mBaseKeyFrameAnimationName != BLANKSTRING && mContainer) + baseAnim = mContainer->getAnimation(mBaseKeyFrameAnimationName); + + if (baseAnim) + { + for (NodeTrackList::iterator i = mNodeTrackList.begin(); i != mNodeTrackList.end(); ++i) + { + NodeAnimationTrack* track = i->second; + + NodeAnimationTrack* baseTrack; + if (baseAnim == this) + baseTrack = track; + else + baseTrack = baseAnim->getNodeTrack(track->getHandle()); + + TransformKeyFrame kf(baseTrack, mBaseKeyFrameTime); + baseTrack->getInterpolatedKeyFrame(baseAnim->_getTimeIndex(mBaseKeyFrameTime), &kf); + track->_applyBaseKeyFrame(&kf); + } + + for (VertexTrackList::iterator i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i) + { + VertexAnimationTrack* track = i->second; + + if (track->getAnimationType() == VAT_POSE) + { + VertexAnimationTrack* baseTrack; + if (baseAnim == this) + baseTrack = track; + else + baseTrack = baseAnim->getVertexTrack(track->getHandle()); + + VertexPoseKeyFrame kf(baseTrack, mBaseKeyFrameTime); + baseTrack->getInterpolatedKeyFrame(baseAnim->_getTimeIndex(mBaseKeyFrameTime), &kf); + track->_applyBaseKeyFrame(&kf); + + } + } + + } + + // Re-base has been done, this is a one-way translation + mUseBaseKeyFrame = false; + } + + } //----------------------------------------------------------------------- - void Animation::_applyBaseKeyFrame() - { - if (mUseBaseKeyFrame) - { - Animation* baseAnim = this; - if (mBaseKeyFrameAnimationName != BLANKSTRING && mContainer) - baseAnim = mContainer->getAnimation(mBaseKeyFrameAnimationName); - - if (baseAnim) - { - for (NodeTrackList::iterator i = mNodeTrackList.begin(); i != mNodeTrackList.end(); ++i) - { - NodeAnimationTrack* track = i->second; - - NodeAnimationTrack* baseTrack; - if (baseAnim == this) - baseTrack = track; - else - baseTrack = baseAnim->getNodeTrack(track->getHandle()); - - TransformKeyFrame kf(baseTrack, mBaseKeyFrameTime); - baseTrack->getInterpolatedKeyFrame(baseAnim->_getTimeIndex(mBaseKeyFrameTime), &kf); - track->_applyBaseKeyFrame(&kf); - } - - for (VertexTrackList::iterator i = mVertexTrackList.begin(); i != mVertexTrackList.end(); ++i) - { - VertexAnimationTrack* track = i->second; - - if (track->getAnimationType() == VAT_POSE) - { - VertexAnimationTrack* baseTrack; - if (baseAnim == this) - baseTrack = track; - else - baseTrack = baseAnim->getVertexTrack(track->getHandle()); - - VertexPoseKeyFrame kf(baseTrack, mBaseKeyFrameTime); - baseTrack->getInterpolatedKeyFrame(baseAnim->_getTimeIndex(mBaseKeyFrameTime), &kf); - track->_applyBaseKeyFrame(&kf); - - } - } - - } - - // Re-base has been done, this is a one-way translation - mUseBaseKeyFrame = false; - } - - } + void Animation::_notifyContainer(AnimationContainer* c) + { + mContainer = c; + } //----------------------------------------------------------------------- - void Animation::_notifyContainer(AnimationContainer* c) - { - mContainer = c; - } - //----------------------------------------------------------------------- - AnimationContainer* Animation::getContainer() - { - return mContainer; - } - + AnimationContainer* Animation::getContainer() + { + return mContainer; + } + } diff --git a/OgreMain/src/OgreAnimationState.cpp b/OgreMain/src/OgreAnimationState.cpp index c64bfb35d7e..c90b1de1f46 100644 --- a/OgreMain/src/OgreAnimationState.cpp +++ b/OgreMain/src/OgreAnimationState.cpp @@ -33,8 +33,8 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - AnimationState::AnimationState(AnimationStateSet* parent, const AnimationState &rhs) + //--------------------------------------------------------------------- + AnimationState::AnimationState(AnimationStateSet* parent, const AnimationState &rhs) : mBlendMask(0) , mAnimationName(rhs.mAnimationName) , mParent(parent) @@ -44,16 +44,16 @@ namespace Ogre , mEnabled(rhs.mEnabled) , mLoop(rhs.mLoop) { - mParent->_notifyDirty(); - } - //--------------------------------------------------------------------- - AnimationState::~AnimationState() - { - } + mParent->_notifyDirty(); + } + //--------------------------------------------------------------------- + AnimationState::~AnimationState() + { + } //--------------------------------------------------------------------- AnimationState::AnimationState(const String& animName, - AnimationStateSet *parent, Real timePos, Real length, Real weight, - bool enabled) + AnimationStateSet *parent, Real timePos, Real length, Real weight, + bool enabled) : mBlendMask(0) , mAnimationName(animName) , mParent(parent) @@ -63,7 +63,7 @@ namespace Ogre , mEnabled(enabled) , mLoop(true) { - mParent->_notifyDirty(); + mParent->_notifyDirty(); } //--------------------------------------------------------------------- const String& AnimationState::getAnimationName() const @@ -78,24 +78,24 @@ namespace Ogre //--------------------------------------------------------------------- void AnimationState::setTimePosition(Real timePos) { - if (timePos != mTimePos) - { - mTimePos = timePos; - if (mLoop) - { - // Wrap - mTimePos = fmod(mTimePos, mLength); - if(mTimePos < 0) - mTimePos += mLength; - } - else - { - // Clamp - if(mTimePos < 0) - mTimePos = 0; - else if (mTimePos > mLength) - mTimePos = mLength; - } + if (timePos != mTimePos) + { + mTimePos = timePos; + if (mLoop) + { + // Wrap + mTimePos = fmod(mTimePos, mLength); + if(mTimePos < 0) + mTimePos += mLength; + } + else + { + // Clamp + if(mTimePos < 0) + mTimePos = 0; + else if (mTimePos > mLength) + mTimePos = mLength; + } if (mEnabled) mParent->_notifyDirty(); @@ -131,10 +131,10 @@ namespace Ogre setTimePosition(mTimePos + offset); } //--------------------------------------------------------------------- - bool AnimationState::hasEnded(void) const - { - return (mTimePos >= mLength && !mLoop); - } + bool AnimationState::hasEnded(void) const + { + return (mTimePos >= mLength && !mLoop); + } //--------------------------------------------------------------------- bool AnimationState::getEnabled(void) const { @@ -176,10 +176,10 @@ namespace Ogre mWeight = animState.mWeight; mEnabled = animState.mEnabled; mLoop = animState.mLoop; - mParent->_notifyDirty(); + mParent->_notifyDirty(); } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void AnimationState::setBlendMaskEntry(size_t boneHandle, float weight) { assert(mBlendMask && mBlendMask->size() > boneHandle); @@ -187,7 +187,7 @@ namespace Ogre if (mEnabled) mParent->_notifyDirty(); } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void AnimationState::_setBlendMaskData(const float* blendMaskData) { assert(mBlendMask && "No BlendMask set!"); @@ -202,7 +202,7 @@ namespace Ogre if (mEnabled) mParent->_notifyDirty(); } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void AnimationState::_setBlendMask(const BoneBlendMask* blendMask) { if(!mBlendMask) @@ -211,48 +211,48 @@ namespace Ogre } _setBlendMaskData(&(*blendMask)[0]); } - //--------------------------------------------------------------------- - void AnimationState::createBlendMask(size_t blendMaskSizeHint, float initialWeight) - { - if(!mBlendMask) - { - if(initialWeight >= 0) - { - mBlendMask = OGRE_NEW_T(BoneBlendMask, MEMCATEGORY_ANIMATION)(blendMaskSizeHint, initialWeight); - } - else - { - mBlendMask = OGRE_NEW_T(BoneBlendMask, MEMCATEGORY_ANIMATION)(blendMaskSizeHint); - } - } - } - //--------------------------------------------------------------------- - void AnimationState::destroyBlendMask() - { - OGRE_DELETE_T(mBlendMask, BoneBlendMask, MEMCATEGORY_ANIMATION); - mBlendMask = 0; - } - //--------------------------------------------------------------------- - - //--------------------------------------------------------------------- - AnimationStateSet::AnimationStateSet() - : mDirtyFrameNumber(std::numeric_limits::max()) - { - } - //--------------------------------------------------------------------- - AnimationStateSet::AnimationStateSet(const AnimationStateSet& rhs) - : mDirtyFrameNumber(std::numeric_limits::max()) - { - // lock rhs + //--------------------------------------------------------------------- + void AnimationState::createBlendMask(size_t blendMaskSizeHint, float initialWeight) + { + if(!mBlendMask) + { + if(initialWeight >= 0) + { + mBlendMask = OGRE_NEW_T(BoneBlendMask, MEMCATEGORY_ANIMATION)(blendMaskSizeHint, initialWeight); + } + else + { + mBlendMask = OGRE_NEW_T(BoneBlendMask, MEMCATEGORY_ANIMATION)(blendMaskSizeHint); + } + } + } + //--------------------------------------------------------------------- + void AnimationState::destroyBlendMask() + { + OGRE_DELETE_T(mBlendMask, BoneBlendMask, MEMCATEGORY_ANIMATION); + mBlendMask = 0; + } + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + AnimationStateSet::AnimationStateSet() + : mDirtyFrameNumber(std::numeric_limits::max()) + { + } + //--------------------------------------------------------------------- + AnimationStateSet::AnimationStateSet(const AnimationStateSet& rhs) + : mDirtyFrameNumber(std::numeric_limits::max()) + { + // lock rhs OGRE_LOCK_MUTEX(rhs.OGRE_AUTO_MUTEX_NAME); - for (AnimationStateMap::const_iterator i = rhs.mAnimationStates.begin(); - i != rhs.mAnimationStates.end(); ++i) - { - AnimationState* src = i->second; - mAnimationStates[src->getAnimationName()] = - OGRE_NEW AnimationState(this, *src); - } + for (AnimationStateMap::const_iterator i = rhs.mAnimationStates.begin(); + i != rhs.mAnimationStates.end(); ++i) + { + AnimationState* src = i->second; + mAnimationStates[src->getAnimationName()] = + OGRE_NEW AnimationState(this, *src); + } // Clone enabled animation state list for (EnabledAnimationStateList::const_iterator it = rhs.mEnabledAnimationStates.begin(); @@ -261,108 +261,108 @@ namespace Ogre const AnimationState* src = *it; mEnabledAnimationStates.push_back(getAnimationState(src->getAnimationName())); } - } - //--------------------------------------------------------------------- - AnimationStateSet::~AnimationStateSet() - { - // Destroy - removeAllAnimationStates(); - } - //--------------------------------------------------------------------- - void AnimationStateSet::removeAnimationState(const String& name) - { + } + //--------------------------------------------------------------------- + AnimationStateSet::~AnimationStateSet() + { + // Destroy + removeAllAnimationStates(); + } + //--------------------------------------------------------------------- + void AnimationStateSet::removeAnimationState(const String& name) + { OGRE_LOCK_AUTO_MUTEX; - AnimationStateMap::iterator i = mAnimationStates.find(name); - if (i != mAnimationStates.end()) - { + AnimationStateMap::iterator i = mAnimationStates.find(name); + if (i != mAnimationStates.end()) + { mEnabledAnimationStates.remove(i->second); - OGRE_DELETE i->second; - mAnimationStates.erase(i); - } - } - //--------------------------------------------------------------------- - void AnimationStateSet::removeAllAnimationStates(void) - { + OGRE_DELETE i->second; + mAnimationStates.erase(i); + } + } + //--------------------------------------------------------------------- + void AnimationStateSet::removeAllAnimationStates(void) + { OGRE_LOCK_AUTO_MUTEX; - for (AnimationStateMap::iterator i = mAnimationStates.begin(); - i != mAnimationStates.end(); ++i) - { - OGRE_DELETE i->second; - } - mAnimationStates.clear(); + for (AnimationStateMap::iterator i = mAnimationStates.begin(); + i != mAnimationStates.end(); ++i) + { + OGRE_DELETE i->second; + } + mAnimationStates.clear(); mEnabledAnimationStates.clear(); - } - //--------------------------------------------------------------------- - AnimationState* AnimationStateSet::createAnimationState(const String& name, - Real timePos, Real length, Real weight, bool enabled) - { + } + //--------------------------------------------------------------------- + AnimationState* AnimationStateSet::createAnimationState(const String& name, + Real timePos, Real length, Real weight, bool enabled) + { OGRE_LOCK_AUTO_MUTEX; - AnimationStateMap::iterator i = mAnimationStates.find(name); - if (i != mAnimationStates.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "State for animation named '" + name + "' already exists.", - "AnimationStateSet::createAnimationState"); - } + AnimationStateMap::iterator i = mAnimationStates.find(name); + if (i != mAnimationStates.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "State for animation named '" + name + "' already exists.", + "AnimationStateSet::createAnimationState"); + } - AnimationState* newState = OGRE_NEW AnimationState(name, this, timePos, - length, weight, enabled); - mAnimationStates[name] = newState; + AnimationState* newState = OGRE_NEW AnimationState(name, this, timePos, + length, weight, enabled); + mAnimationStates[name] = newState; - return newState; + return newState; - } - //--------------------------------------------------------------------- - AnimationState* AnimationStateSet::getAnimationState(const String& name) const - { + } + //--------------------------------------------------------------------- + AnimationState* AnimationStateSet::getAnimationState(const String& name) const + { OGRE_LOCK_AUTO_MUTEX; - AnimationStateMap::const_iterator i = mAnimationStates.find(name); - if (i == mAnimationStates.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "No state found for animation named '" + name + "'", - "AnimationStateSet::getAnimationState"); - } - return i->second; - } - //--------------------------------------------------------------------- - bool AnimationStateSet::hasAnimationState(const String& name) const - { + AnimationStateMap::const_iterator i = mAnimationStates.find(name); + if (i == mAnimationStates.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "No state found for animation named '" + name + "'", + "AnimationStateSet::getAnimationState"); + } + return i->second; + } + //--------------------------------------------------------------------- + bool AnimationStateSet::hasAnimationState(const String& name) const + { OGRE_LOCK_AUTO_MUTEX; - return mAnimationStates.find(name) != mAnimationStates.end(); - } - //--------------------------------------------------------------------- - AnimationStateIterator AnimationStateSet::getAnimationStateIterator(void) - { + return mAnimationStates.find(name) != mAnimationStates.end(); + } + //--------------------------------------------------------------------- + AnimationStateIterator AnimationStateSet::getAnimationStateIterator(void) + { OGRE_LOCK_AUTO_MUTEX; - // returned iterator not threadsafe, noted in header - return AnimationStateIterator( - mAnimationStates.begin(), mAnimationStates.end()); - } - //--------------------------------------------------------------------- - ConstAnimationStateIterator AnimationStateSet::getAnimationStateIterator(void) const - { + // returned iterator not threadsafe, noted in header + return AnimationStateIterator( + mAnimationStates.begin(), mAnimationStates.end()); + } + //--------------------------------------------------------------------- + ConstAnimationStateIterator AnimationStateSet::getAnimationStateIterator(void) const + { OGRE_LOCK_AUTO_MUTEX; - // returned iterator not threadsafe, noted in header - return ConstAnimationStateIterator( - mAnimationStates.begin(), mAnimationStates.end()); - } - //--------------------------------------------------------------------- - void AnimationStateSet::copyMatchingState(AnimationStateSet* target) const - { - // lock target + // returned iterator not threadsafe, noted in header + return ConstAnimationStateIterator( + mAnimationStates.begin(), mAnimationStates.end()); + } + //--------------------------------------------------------------------- + void AnimationStateSet::copyMatchingState(AnimationStateSet* target) const + { + // lock target OGRE_LOCK_MUTEX(target->OGRE_AUTO_MUTEX_NAME); - // lock source + // lock source OGRE_LOCK_AUTO_MUTEX; - AnimationStateMap::iterator i, iend; + AnimationStateMap::iterator i, iend; iend = target->mAnimationStates.end(); for (i = target->mAnimationStates.begin(); i != iend; ++i) { AnimationStateMap::const_iterator iother = mAnimationStates.find(i->first); @@ -401,7 +401,7 @@ namespace Ogre void AnimationStateSet::_notifyAnimationStateEnabled(AnimationState* target, bool enabled) { OGRE_LOCK_AUTO_MUTEX; - // Remove from enabled animation state list first + // Remove from enabled animation state list first mEnabledAnimationStates.remove(target); // Add to enabled animation state list if need @@ -417,21 +417,21 @@ namespace Ogre ConstEnabledAnimationStateIterator AnimationStateSet::getEnabledAnimationStateIterator(void) const { OGRE_LOCK_AUTO_MUTEX; - // returned iterator not threadsafe, noted in header + // returned iterator not threadsafe, noted in header return ConstEnabledAnimationStateIterator( mEnabledAnimationStates.begin(), mEnabledAnimationStates.end()); } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - Real AnimationStateControllerValue::getValue(void) const - { - return mTargetAnimationState->getTimePosition() / mTargetAnimationState->getLength(); - } - //--------------------------------------------------------------------- - void AnimationStateControllerValue::setValue(Real value) - { - mTargetAnimationState->setTimePosition(value * mTargetAnimationState->getLength()); - } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + Real AnimationStateControllerValue::getValue(void) const + { + return mTargetAnimationState->getTimePosition() / mTargetAnimationState->getLength(); + } + //--------------------------------------------------------------------- + void AnimationStateControllerValue::setValue(Real value) + { + mTargetAnimationState->setTimePosition(value * mTargetAnimationState->getLength()); + } } diff --git a/OgreMain/src/OgreAnimationTrack.cpp b/OgreMain/src/OgreAnimationTrack.cpp index bce0b4b5e5b..7cbb89eacd9 100644 --- a/OgreMain/src/OgreAnimationTrack.cpp +++ b/OgreMain/src/OgreAnimationTrack.cpp @@ -48,7 +48,7 @@ namespace Ogre { //--------------------------------------------------------------------- //--------------------------------------------------------------------- AnimationTrack::AnimationTrack(Animation* parent, unsigned short handle) : - mParent(parent), mHandle(handle), mListener(0) + mParent(parent), mHandle(handle), mListener(0) { } //--------------------------------------------------------------------- @@ -64,7 +64,7 @@ namespace Ogre { //--------------------------------------------------------------------- KeyFrame* AnimationTrack::getKeyFrame(unsigned short index) const { - // If you hit this assert, then the keyframe index is out of bounds + // If you hit this assert, then the keyframe index is out of bounds assert( index < (ushort)mKeyFrames.size() ); return mKeyFrames[index]; @@ -104,7 +104,7 @@ namespace Ogre { assert(totalAnimationLength > 0.0f && "Invalid animation length!"); if( timePos > totalAnimationLength && totalAnimationLength > 0.0f ) - timePos = fmod( timePos, totalAnimationLength ); + timePos = fmod( timePos, totalAnimationLength ); // No global keyframe index, need to search with local keyframes. KeyFrame timeKey(0, timePos); @@ -171,7 +171,7 @@ namespace Ogre { //--------------------------------------------------------------------- void AnimationTrack::removeKeyFrame(unsigned short index) { - // If you hit this assert, then the keyframe index is out of bounds + // If you hit this assert, then the keyframe index is out of bounds assert( index < (ushort)mKeyFrames.size() ); KeyFrameList::iterator i = mKeyFrames.begin(); @@ -233,66 +233,66 @@ namespace Ogre { ++j; } } - //--------------------------------------------------------------------- - void AnimationTrack::populateClone(AnimationTrack* clone) const - { - for (KeyFrameList::const_iterator i = mKeyFrames.begin(); - i != mKeyFrames.end(); ++i) - { - KeyFrame* clonekf = (*i)->_clone(clone); - clone->mKeyFrames.push_back(clonekf); - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - // Numeric specialisations - //--------------------------------------------------------------------- - NumericAnimationTrack::NumericAnimationTrack(Animation* parent, - unsigned short handle) - : AnimationTrack(parent, handle) - { - } - //--------------------------------------------------------------------- - NumericAnimationTrack::NumericAnimationTrack(Animation* parent, - unsigned short handle, AnimableValuePtr& target) - :AnimationTrack(parent, handle), mTargetAnim(target) - { - } - //--------------------------------------------------------------------- - const AnimableValuePtr& NumericAnimationTrack::getAssociatedAnimable(void) const - { - return mTargetAnim; - } - //--------------------------------------------------------------------- - void NumericAnimationTrack::setAssociatedAnimable(const AnimableValuePtr& val) - { - mTargetAnim = val; - } - //--------------------------------------------------------------------- - KeyFrame* NumericAnimationTrack::createKeyFrameImpl(Real time) - { - return OGRE_NEW NumericKeyFrame(this, time); - } - //--------------------------------------------------------------------- - void NumericAnimationTrack::getInterpolatedKeyFrame(const TimeIndex& timeIndex, - KeyFrame* kf) const - { - if (mListener) - { - if (mListener->getInterpolatedKeyFrame(this, timeIndex, kf)) - return; - } - - NumericKeyFrame* kret = static_cast(kf); + //--------------------------------------------------------------------- + void AnimationTrack::populateClone(AnimationTrack* clone) const + { + for (KeyFrameList::const_iterator i = mKeyFrames.begin(); + i != mKeyFrames.end(); ++i) + { + KeyFrame* clonekf = (*i)->_clone(clone); + clone->mKeyFrames.push_back(clonekf); + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + // Numeric specialisations + //--------------------------------------------------------------------- + NumericAnimationTrack::NumericAnimationTrack(Animation* parent, + unsigned short handle) + : AnimationTrack(parent, handle) + { + } + //--------------------------------------------------------------------- + NumericAnimationTrack::NumericAnimationTrack(Animation* parent, + unsigned short handle, AnimableValuePtr& target) + :AnimationTrack(parent, handle), mTargetAnim(target) + { + } + //--------------------------------------------------------------------- + const AnimableValuePtr& NumericAnimationTrack::getAssociatedAnimable(void) const + { + return mTargetAnim; + } + //--------------------------------------------------------------------- + void NumericAnimationTrack::setAssociatedAnimable(const AnimableValuePtr& val) + { + mTargetAnim = val; + } + //--------------------------------------------------------------------- + KeyFrame* NumericAnimationTrack::createKeyFrameImpl(Real time) + { + return OGRE_NEW NumericKeyFrame(this, time); + } + //--------------------------------------------------------------------- + void NumericAnimationTrack::getInterpolatedKeyFrame(const TimeIndex& timeIndex, + KeyFrame* kf) const + { + if (mListener) + { + if (mListener->getInterpolatedKeyFrame(this, timeIndex, kf)) + return; + } + + NumericKeyFrame* kret = static_cast(kf); // Keyframe pointers - KeyFrame *kBase1, *kBase2; + KeyFrame *kBase1, *kBase2; NumericKeyFrame *k1, *k2; unsigned short firstKeyIndex; Real t = this->getKeyFramesAtTime(timeIndex, &kBase1, &kBase2, &firstKeyIndex); - k1 = static_cast(kBase1); - k2 = static_cast(kBase2); + k1 = static_cast(kBase1); + k2 = static_cast(kBase2); if (t == 0.0) { @@ -302,93 +302,93 @@ namespace Ogre { else { // Interpolate by t - AnyNumeric diff = k2->getValue() - k1->getValue(); - kret->setValue(k1->getValue() + diff * t); + AnyNumeric diff = k2->getValue() - k1->getValue(); + kret->setValue(k1->getValue() + diff * t); } - } - //--------------------------------------------------------------------- - void NumericAnimationTrack::apply(const TimeIndex& timeIndex, Real weight, Real scale) - { - applyToAnimable(mTargetAnim, timeIndex, weight, scale); - } - //--------------------------------------------------------------------- - void NumericAnimationTrack::applyToAnimable(const AnimableValuePtr& anim, const TimeIndex& timeIndex, - Real weight, Real scale) - { - // Nothing to do if no keyframes or zero weight, scale - if (mKeyFrames.empty() || !weight || !scale) - return; - - NumericKeyFrame kf(0, timeIndex.getTimePos()); - getInterpolatedKeyFrame(timeIndex, &kf); - // add to existing. Weights are not relative, but treated as - // absolute multipliers for the animation - AnyNumeric val = kf.getValue() * (weight * scale); - - anim->applyDeltaValue(val); - - } - //-------------------------------------------------------------------------- - NumericKeyFrame* NumericAnimationTrack::createNumericKeyFrame(Real timePos) - { - return static_cast(createKeyFrame(timePos)); - } - //-------------------------------------------------------------------------- - NumericKeyFrame* NumericAnimationTrack::getNumericKeyFrame(unsigned short index) const - { - return static_cast(getKeyFrame(index)); - } + } + //--------------------------------------------------------------------- + void NumericAnimationTrack::apply(const TimeIndex& timeIndex, Real weight, Real scale) + { + applyToAnimable(mTargetAnim, timeIndex, weight, scale); + } + //--------------------------------------------------------------------- + void NumericAnimationTrack::applyToAnimable(const AnimableValuePtr& anim, const TimeIndex& timeIndex, + Real weight, Real scale) + { + // Nothing to do if no keyframes or zero weight, scale + if (mKeyFrames.empty() || !weight || !scale) + return; + + NumericKeyFrame kf(0, timeIndex.getTimePos()); + getInterpolatedKeyFrame(timeIndex, &kf); + // add to existing. Weights are not relative, but treated as + // absolute multipliers for the animation + AnyNumeric val = kf.getValue() * (weight * scale); + + anim->applyDeltaValue(val); + + } + //-------------------------------------------------------------------------- + NumericKeyFrame* NumericAnimationTrack::createNumericKeyFrame(Real timePos) + { + return static_cast(createKeyFrame(timePos)); + } + //-------------------------------------------------------------------------- + NumericKeyFrame* NumericAnimationTrack::getNumericKeyFrame(unsigned short index) const + { + return static_cast(getKeyFrame(index)); + } //--------------------------------------------------------------------- - NumericAnimationTrack* NumericAnimationTrack::_clone(Animation* newParent) const - { - NumericAnimationTrack* newTrack = - newParent->createNumericTrack(mHandle); - newTrack->mTargetAnim = mTargetAnim; - populateClone(newTrack); - return newTrack; - } + NumericAnimationTrack* NumericAnimationTrack::_clone(Animation* newParent) const + { + NumericAnimationTrack* newTrack = + newParent->createNumericTrack(mHandle); + newTrack->mTargetAnim = mTargetAnim; + populateClone(newTrack); + return newTrack; + } //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - // Node specialisations - //--------------------------------------------------------------------- - NodeAnimationTrack::NodeAnimationTrack(Animation* parent, unsigned short handle) - : AnimationTrack(parent, handle), mTargetNode(0) + //--------------------------------------------------------------------- + // Node specialisations + //--------------------------------------------------------------------- + NodeAnimationTrack::NodeAnimationTrack(Animation* parent, unsigned short handle) + : AnimationTrack(parent, handle), mTargetNode(0) , mSplines(0), mSplineBuildNeeded(false) , mUseShortestRotationPath(true) - { - } - //--------------------------------------------------------------------- - NodeAnimationTrack::NodeAnimationTrack(Animation* parent, unsigned short handle, - Node* targetNode) - : AnimationTrack(parent, handle), mTargetNode(targetNode) + { + } + //--------------------------------------------------------------------- + NodeAnimationTrack::NodeAnimationTrack(Animation* parent, unsigned short handle, + Node* targetNode) + : AnimationTrack(parent, handle), mTargetNode(targetNode) , mSplines(0), mSplineBuildNeeded(false) , mUseShortestRotationPath(true) - { - } + { + } //--------------------------------------------------------------------- NodeAnimationTrack::~NodeAnimationTrack() { OGRE_DELETE_T(mSplines, Splines, MEMCATEGORY_ANIMATION); } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void NodeAnimationTrack::getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf) const { - if (mListener) - { - if (mListener->getInterpolatedKeyFrame(this, timeIndex, kf)) - return; - } + if (mListener) + { + if (mListener->getInterpolatedKeyFrame(this, timeIndex, kf)) + return; + } - TransformKeyFrame* kret = static_cast(kf); + TransformKeyFrame* kret = static_cast(kf); // Keyframe pointers - KeyFrame *kBase1, *kBase2; + KeyFrame *kBase1, *kBase2; TransformKeyFrame *k1, *k2; unsigned short firstKeyIndex; Real t = this->getKeyFramesAtTime(timeIndex, &kBase1, &kBase2, &firstKeyIndex); - k1 = static_cast(kBase1); - k2 = static_cast(kBase2); + k1 = static_cast(kBase1); + k2 = static_cast(kBase2); if (t == 0.0) { @@ -418,7 +418,7 @@ namespace Ogre { else //if (rim == Animation::RIM_SPHERICAL) { kret->setRotation( Quaternion::Slerp(t, k1->getRotation(), - k2->getRotation(), mUseShortestRotationPath) ); + k2->getRotation(), mUseShortestRotationPath) ); } // Translation @@ -441,7 +441,7 @@ namespace Ogre { // Rotation, take mUseShortestRotationPath into account kret->setRotation( mSplines->rotationSpline.interpolate(firstKeyIndex, t, - mUseShortestRotationPath) ); + mUseShortestRotationPath) ); // Translation kret->setTranslate( mSplines->positionSpline.interpolate(firstKeyIndex, t) ); @@ -472,20 +472,20 @@ namespace Ogre { } //--------------------------------------------------------------------- void NodeAnimationTrack::applyToNode(Node* node, const TimeIndex& timeIndex, Real weight, - Real scl) + Real scl) { - // Nothing to do if no keyframes or zero weight or no node - if (mKeyFrames.empty() || !weight || !node) - return; + // Nothing to do if no keyframes or zero weight or no node + if (mKeyFrames.empty() || !weight || !node) + return; TransformKeyFrame kf(0, timeIndex.getTimePos()); - getInterpolatedKeyFrame(timeIndex, &kf); + getInterpolatedKeyFrame(timeIndex, &kf); - // add to existing. Weights are not relative, but treated as absolute multipliers for the animation + // add to existing. Weights are not relative, but treated as absolute multipliers for the animation Vector3 translate = kf.getTranslate() * weight * scl; - node->translate(translate); + node->translate(translate); - // interpolate between no-rotation and full rotation, to point 'weight', so 0 = no rotate, 1 = full + // interpolate between no-rotation and full rotation, to point 'weight', so 0 = no rotate, 1 = full Quaternion rotate; Animation::RotationInterpolationMode rim = mParent->getRotationInterpolationMode(); @@ -497,19 +497,19 @@ namespace Ogre { { rotate = Quaternion::Slerp(weight, Quaternion::IDENTITY, kf.getRotation(), mUseShortestRotationPath); } - node->rotate(rotate); + node->rotate(rotate); - Vector3 scale = kf.getScale(); - // Not sure how to modify scale for cumulative anims... leave it alone - //scale = ((Vector3::UNIT_SCALE - kf.getScale()) * weight) + Vector3::UNIT_SCALE; - if (scale != Vector3::UNIT_SCALE) - { + Vector3 scale = kf.getScale(); + // Not sure how to modify scale for cumulative anims... leave it alone + //scale = ((Vector3::UNIT_SCALE - kf.getScale()) * weight) + Vector3::UNIT_SCALE; + if (scale != Vector3::UNIT_SCALE) + { if (scl != 1.0f) scale = Vector3::UNIT_SCALE + (scale - Vector3::UNIT_SCALE) * scl; else if (weight != 1.0f) scale = Vector3::UNIT_SCALE + (scale - Vector3::UNIT_SCALE) * weight; - } - node->scale(scale); + } + node->scale(scale); } //--------------------------------------------------------------------- @@ -537,7 +537,7 @@ namespace Ogre { iend = mKeyFrames.end(); // precall to avoid overhead for (i = mKeyFrames.begin(); i != iend; ++i) { - TransformKeyFrame* kf = static_cast(*i); + TransformKeyFrame* kf = static_cast(*i); splines->positionSpline.addPoint(kf->getTranslate()); splines->rotationSpline.addPoint(kf->getRotation()); splines->scaleSpline.addPoint(kf->getScale()); @@ -552,527 +552,527 @@ namespace Ogre { } //--------------------------------------------------------------------- - void NodeAnimationTrack::setUseShortestRotationPath(bool useShortestPath) - { - mUseShortestRotationPath = useShortestPath ; - } + void NodeAnimationTrack::setUseShortestRotationPath(bool useShortestPath) + { + mUseShortestRotationPath = useShortestPath ; + } //--------------------------------------------------------------------- - bool NodeAnimationTrack::getUseShortestRotationPath() const - { - return mUseShortestRotationPath ; - } + bool NodeAnimationTrack::getUseShortestRotationPath() const + { + return mUseShortestRotationPath ; + } //--------------------------------------------------------------------- void NodeAnimationTrack::_keyFrameDataChanged(void) const { mSplineBuildNeeded = true; } //--------------------------------------------------------------------- - bool NodeAnimationTrack::hasNonZeroKeyFrames(void) const - { + bool NodeAnimationTrack::hasNonZeroKeyFrames(void) const + { KeyFrameList::const_iterator i = mKeyFrames.begin(); for (; i != mKeyFrames.end(); ++i) { - // look for keyframes which have any component which is non-zero - // Since exporters can be a little inaccurate sometimes we use a - // tolerance value rather than looking for nothing - TransformKeyFrame* kf = static_cast(*i); - Vector3 trans = kf->getTranslate(); - Vector3 scale = kf->getScale(); - Vector3 axis; - Radian angle; - kf->getRotation().ToAngleAxis(angle, axis); - Real tolerance = 1e-3f; - if (!trans.positionEquals(Vector3::ZERO, tolerance) || - !scale.positionEquals(Vector3::UNIT_SCALE, tolerance) || - !Math::RealEqual(angle.valueRadians(), 0.0f, tolerance)) - { - return true; - } - - } - - return false; - } + // look for keyframes which have any component which is non-zero + // Since exporters can be a little inaccurate sometimes we use a + // tolerance value rather than looking for nothing + TransformKeyFrame* kf = static_cast(*i); + Vector3 trans = kf->getTranslate(); + Vector3 scale = kf->getScale(); + Vector3 axis; + Radian angle; + kf->getRotation().ToAngleAxis(angle, axis); + Real tolerance = 1e-3f; + if (!trans.positionEquals(Vector3::ZERO, tolerance) || + !scale.positionEquals(Vector3::UNIT_SCALE, tolerance) || + !Math::RealEqual(angle.valueRadians(), 0.0f, tolerance)) + { + return true; + } + + } + + return false; + } //--------------------------------------------------------------------- - void NodeAnimationTrack::optimise(void) - { - // Eliminate duplicate keyframes from 2nd to penultimate keyframe - // NB only eliminate middle keys from sequences of 5+ identical keyframes - // since we need to preserve the boundary keys in place, and we need - // 2 at each end to preserve tangents for spline interpolation - Vector3 lasttrans = Vector3::ZERO; - Vector3 lastscale = Vector3::ZERO; - Quaternion lastorientation; + void NodeAnimationTrack::optimise(void) + { + // Eliminate duplicate keyframes from 2nd to penultimate keyframe + // NB only eliminate middle keys from sequences of 5+ identical keyframes + // since we need to preserve the boundary keys in place, and we need + // 2 at each end to preserve tangents for spline interpolation + Vector3 lasttrans = Vector3::ZERO; + Vector3 lastscale = Vector3::ZERO; + Quaternion lastorientation; KeyFrameList::iterator i = mKeyFrames.begin(); - Radian quatTolerance(1e-3f); - list::type removeList; - unsigned short k = 0; - ushort dupKfCount = 0; + Radian quatTolerance(1e-3f); + list::type removeList; + unsigned short k = 0; + ushort dupKfCount = 0; for (; i != mKeyFrames.end(); ++i, ++k) { - TransformKeyFrame* kf = static_cast(*i); - Vector3 newtrans = kf->getTranslate(); - Vector3 newscale = kf->getScale(); - Quaternion neworientation = kf->getRotation(); - // Ignore first keyframe; now include the last keyframe as we eliminate - // only k-2 in a group of 5 to ensure we only eliminate middle keys - if (i != mKeyFrames.begin() && - newtrans.positionEquals(lasttrans) && - newscale.positionEquals(lastscale) && - neworientation.equals(lastorientation, quatTolerance)) - { - ++dupKfCount; - - // 4 indicates this is the 5th duplicate keyframe - if (dupKfCount == 4) - { - // remove the 'middle' keyframe - removeList.push_back(k-2); - --dupKfCount; - } - } - else - { - // reset - dupKfCount = 0; - lasttrans = newtrans; - lastscale = newscale; - lastorientation = neworientation; - } - } - - // Now remove keyframes, in reverse order to avoid index revocation - list::type::reverse_iterator r = removeList.rbegin(); - for (; r!= removeList.rend(); ++r) - { - removeKeyFrame(*r); - } - - - } - //-------------------------------------------------------------------------- - KeyFrame* NodeAnimationTrack::createKeyFrameImpl(Real time) - { - return OGRE_NEW TransformKeyFrame(this, time); - } - //-------------------------------------------------------------------------- - TransformKeyFrame* NodeAnimationTrack::createNodeKeyFrame(Real timePos) - { - return static_cast(createKeyFrame(timePos)); - } - //-------------------------------------------------------------------------- - TransformKeyFrame* NodeAnimationTrack::getNodeKeyFrame(unsigned short index) const - { - return static_cast(getKeyFrame(index)); - } + TransformKeyFrame* kf = static_cast(*i); + Vector3 newtrans = kf->getTranslate(); + Vector3 newscale = kf->getScale(); + Quaternion neworientation = kf->getRotation(); + // Ignore first keyframe; now include the last keyframe as we eliminate + // only k-2 in a group of 5 to ensure we only eliminate middle keys + if (i != mKeyFrames.begin() && + newtrans.positionEquals(lasttrans) && + newscale.positionEquals(lastscale) && + neworientation.equals(lastorientation, quatTolerance)) + { + ++dupKfCount; + + // 4 indicates this is the 5th duplicate keyframe + if (dupKfCount == 4) + { + // remove the 'middle' keyframe + removeList.push_back(k-2); + --dupKfCount; + } + } + else + { + // reset + dupKfCount = 0; + lasttrans = newtrans; + lastscale = newscale; + lastorientation = neworientation; + } + } + + // Now remove keyframes, in reverse order to avoid index revocation + list::type::reverse_iterator r = removeList.rbegin(); + for (; r!= removeList.rend(); ++r) + { + removeKeyFrame(*r); + } + + + } + //-------------------------------------------------------------------------- + KeyFrame* NodeAnimationTrack::createKeyFrameImpl(Real time) + { + return OGRE_NEW TransformKeyFrame(this, time); + } + //-------------------------------------------------------------------------- + TransformKeyFrame* NodeAnimationTrack::createNodeKeyFrame(Real timePos) + { + return static_cast(createKeyFrame(timePos)); + } + //-------------------------------------------------------------------------- + TransformKeyFrame* NodeAnimationTrack::getNodeKeyFrame(unsigned short index) const + { + return static_cast(getKeyFrame(index)); + } //--------------------------------------------------------------------- - NodeAnimationTrack* NodeAnimationTrack::_clone(Animation* newParent) const - { - NodeAnimationTrack* newTrack = - newParent->createNodeTrack(mHandle, mTargetNode); - newTrack->mUseShortestRotationPath = mUseShortestRotationPath; - populateClone(newTrack); - return newTrack; - } - //-------------------------------------------------------------------------- - void NodeAnimationTrack::_applyBaseKeyFrame(const KeyFrame* b) - { - const TransformKeyFrame* base = static_cast(b); - + NodeAnimationTrack* NodeAnimationTrack::_clone(Animation* newParent) const + { + NodeAnimationTrack* newTrack = + newParent->createNodeTrack(mHandle, mTargetNode); + newTrack->mUseShortestRotationPath = mUseShortestRotationPath; + populateClone(newTrack); + return newTrack; + } + //-------------------------------------------------------------------------- + void NodeAnimationTrack::_applyBaseKeyFrame(const KeyFrame* b) + { + const TransformKeyFrame* base = static_cast(b); + for (KeyFrameList::iterator i = mKeyFrames.begin(); i != mKeyFrames.end(); ++i) { - TransformKeyFrame* kf = static_cast(*i); - kf->setTranslate(kf->getTranslate() - base->getTranslate()); - kf->setRotation(base->getRotation().Inverse() * kf->getRotation()); - kf->setScale(kf->getScale() * (Vector3::UNIT_SCALE / base->getScale())); - } - - } - //-------------------------------------------------------------------------- - VertexAnimationTrack::VertexAnimationTrack(Animation* parent, - unsigned short handle, VertexAnimationType animType) - : AnimationTrack(parent, handle) - , mAnimationType(animType) - { - } - //-------------------------------------------------------------------------- - VertexAnimationTrack::VertexAnimationTrack(Animation* parent, unsigned short handle, - VertexAnimationType animType, VertexData* targetData, TargetMode target) - : AnimationTrack(parent, handle) - , mAnimationType(animType) - , mTargetVertexData(targetData) - , mTargetMode(target) - { - } - //-------------------------------------------------------------------------- - VertexMorphKeyFrame* VertexAnimationTrack::createVertexMorphKeyFrame(Real timePos) - { - if (mAnimationType != VAT_MORPH) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Morph keyframes can only be created on vertex tracks of type morph.", - "VertexAnimationTrack::createVertexMorphKeyFrame"); - } - return static_cast(createKeyFrame(timePos)); - } - //-------------------------------------------------------------------------- - VertexPoseKeyFrame* VertexAnimationTrack::createVertexPoseKeyFrame(Real timePos) - { - if (mAnimationType != VAT_POSE) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Pose keyframes can only be created on vertex tracks of type pose.", - "VertexAnimationTrack::createVertexPoseKeyFrame"); - } - return static_cast(createKeyFrame(timePos)); - } - //-------------------------------------------------------------------------- - void VertexAnimationTrack::getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf) const - { - // Only relevant for pose animation - if (mAnimationType == VAT_POSE) - { - // Get keyframes - KeyFrame *kf1, *kf2; - Real t = getKeyFramesAtTime(timeIndex, &kf1, &kf2); - - VertexPoseKeyFrame* vkfOut = static_cast(kf); - VertexPoseKeyFrame* vkf1 = static_cast(kf1); - VertexPoseKeyFrame* vkf2 = static_cast(kf2); - - // For each pose reference in key 1, we need to locate the entry in - // key 2 and interpolate the influence - const VertexPoseKeyFrame::PoseRefList& poseList1 = vkf1->getPoseReferences(); - const VertexPoseKeyFrame::PoseRefList& poseList2 = vkf2->getPoseReferences(); - for (VertexPoseKeyFrame::PoseRefList::const_iterator p1 = poseList1.begin(); - p1 != poseList1.end(); ++p1) - { - Real startInfluence = p1->influence; - Real endInfluence = 0; - // Search for entry in keyframe 2 list (if not there, will be 0) - for (VertexPoseKeyFrame::PoseRefList::const_iterator p2 = poseList2.begin(); - p2 != poseList2.end(); ++p2) - { - if (p1->poseIndex == p2->poseIndex) - { - endInfluence = p2->influence; - break; - } - } - // Interpolate influence - Real influence = startInfluence + t*(endInfluence - startInfluence); - - vkfOut->addPoseReference(p1->poseIndex, influence); - - - } - // Now deal with any poses in key 2 which are not in key 1 - for (VertexPoseKeyFrame::PoseRefList::const_iterator p2 = poseList2.begin(); - p2 != poseList2.end(); ++p2) - { - bool found = false; - for (VertexPoseKeyFrame::PoseRefList::const_iterator p1 = poseList1.begin(); - p1 != poseList1.end(); ++p1) - { - if (p1->poseIndex == p2->poseIndex) - { - found = true; - break; - } - } - if (!found) - { - // Need to apply this pose too, scaled from 0 start - Real influence = t * p2->influence; - - vkfOut->addPoseReference(p2->poseIndex, influence); - - } - } // key 2 iteration - - } - - - } - //-------------------------------------------------------------------------- - bool VertexAnimationTrack::getVertexAnimationIncludesNormals() const - { - if (mAnimationType == VAT_NONE) - return false; - - if (mAnimationType == VAT_MORPH) - { - bool normals = false; - for (KeyFrameList::const_iterator i = mKeyFrames.begin(); i != mKeyFrames.end(); ++i) - { - VertexMorphKeyFrame* kf = static_cast(*i); - bool thisnorm = kf->getVertexBuffer()->getVertexSize() > 12; - if (i == mKeyFrames.begin()) - normals = thisnorm; - else - // Only support normals if ALL keyframes include them - normals = normals && thisnorm; - - } - return normals; - } - else - { - // needs to derive from Mesh::PoseList, can't tell here - return false; - } - - - } - //-------------------------------------------------------------------------- - void VertexAnimationTrack::apply(const TimeIndex& timeIndex, Real weight, Real scale) - { - applyToVertexData(mTargetVertexData, timeIndex, weight); - } - //-------------------------------------------------------------------------- - void VertexAnimationTrack::applyToVertexData(VertexData* data, - const TimeIndex& timeIndex, Real weight, const PoseList* poseList) - { - // Nothing to do if no keyframes or no vertex data - if (mKeyFrames.empty() || !data) - return; - - // Get keyframes - KeyFrame *kf1, *kf2; - Real t = getKeyFramesAtTime(timeIndex, &kf1, &kf2); - - if (mAnimationType == VAT_MORPH) - { - VertexMorphKeyFrame* vkf1 = static_cast(kf1); - VertexMorphKeyFrame* vkf2 = static_cast(kf2); - - if (mTargetMode == TM_HARDWARE) - { - // If target mode is hardware, need to bind our 2 keyframe buffers, - // one to main pos, one to morph target texcoord - assert(!data->hwAnimationDataList.empty() && - "Haven't set up hardware vertex animation elements!"); - - // no use for TempBlendedBufferInfo here btw - // NB we assume that position buffer is unshared, except for normals - // VertexDeclaration::getAutoOrganisedDeclaration should see to that - const VertexElement* posElem = - data->vertexDeclaration->findElementBySemantic(VES_POSITION); - // Set keyframe1 data as original position - data->vertexBufferBinding->setBinding( - posElem->getSource(), vkf1->getVertexBuffer()); - // Set keyframe2 data as derived - data->vertexBufferBinding->setBinding( - data->hwAnimationDataList[0].targetBufferIndex, - vkf2->getVertexBuffer()); - // save T for use later - data->hwAnimationDataList[0].parametric = t; - - } - else - { - // If target mode is software, need to software interpolate each vertex - - Mesh::softwareVertexMorph( - t, vkf1->getVertexBuffer(), vkf2->getVertexBuffer(), data); - } - } - else - { - // Pose - - VertexPoseKeyFrame* vkf1 = static_cast(kf1); - VertexPoseKeyFrame* vkf2 = static_cast(kf2); - - // For each pose reference in key 1, we need to locate the entry in - // key 2 and interpolate the influence - const VertexPoseKeyFrame::PoseRefList& poseList1 = vkf1->getPoseReferences(); - const VertexPoseKeyFrame::PoseRefList& poseList2 = vkf2->getPoseReferences(); - for (VertexPoseKeyFrame::PoseRefList::const_iterator p1 = poseList1.begin(); - p1 != poseList1.end(); ++p1) - { - Real startInfluence = p1->influence; - Real endInfluence = 0; - // Search for entry in keyframe 2 list (if not there, will be 0) - for (VertexPoseKeyFrame::PoseRefList::const_iterator p2 = poseList2.begin(); - p2 != poseList2.end(); ++p2) - { - if (p1->poseIndex == p2->poseIndex) - { - endInfluence = p2->influence; - break; - } - } - // Interpolate influence - Real influence = startInfluence + t*(endInfluence - startInfluence); - // Scale by animation weight - influence = weight * influence; - // Get pose - assert (poseList && p1->poseIndex < poseList->size()); - Pose* pose = (*poseList)[p1->poseIndex]; - // apply - applyPoseToVertexData(pose, data, influence); - } - // Now deal with any poses in key 2 which are not in key 1 - for (VertexPoseKeyFrame::PoseRefList::const_iterator p2 = poseList2.begin(); - p2 != poseList2.end(); ++p2) - { - bool found = false; - for (VertexPoseKeyFrame::PoseRefList::const_iterator p1 = poseList1.begin(); - p1 != poseList1.end(); ++p1) - { - if (p1->poseIndex == p2->poseIndex) - { - found = true; - break; - } - } - if (!found) - { - // Need to apply this pose too, scaled from 0 start - Real influence = t * p2->influence; - // Scale by animation weight - influence = weight * influence; - // Get pose - assert (poseList && p2->poseIndex <= poseList->size()); - const Pose* pose = (*poseList)[p2->poseIndex]; - // apply - applyPoseToVertexData(pose, data, influence); - } - } // key 2 iteration - } // morph or pose animation - } - //----------------------------------------------------------------------------- - void VertexAnimationTrack::applyPoseToVertexData(const Pose* pose, - VertexData* data, Real influence) - { - if (mTargetMode == TM_HARDWARE) - { - // Hardware - // If target mode is hardware, need to bind our pose buffer - // to a target texcoord - assert(!data->hwAnimationDataList.empty() && - "Haven't set up hardware vertex animation elements!"); - // no use for TempBlendedBufferInfo here btw - // Set pose target as required - size_t hwIndex = data->hwAnimDataItemsUsed++; - // If we try to use too many poses, ignore extras - if (hwIndex < data->hwAnimationDataList.size()) - { - VertexData::HardwareAnimationData& animData = data->hwAnimationDataList[hwIndex]; - data->vertexBufferBinding->setBinding( - animData.targetBufferIndex, - pose->_getHardwareVertexBuffer(data)); - // save final influence in parametric - animData.parametric = influence; - - } - - } - else - { - // Software - Mesh::softwareVertexPoseBlend(influence, pose->getVertexOffsets(), pose->getNormals(), data); - } - - } - //-------------------------------------------------------------------------- - VertexMorphKeyFrame* VertexAnimationTrack::getVertexMorphKeyFrame(unsigned short index) const - { - if (mAnimationType != VAT_MORPH) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Morph keyframes can only be created on vertex tracks of type morph.", - "VertexAnimationTrack::getVertexMorphKeyFrame"); - } - - return static_cast(getKeyFrame(index)); - } - //-------------------------------------------------------------------------- - VertexPoseKeyFrame* VertexAnimationTrack::getVertexPoseKeyFrame(unsigned short index) const - { - if (mAnimationType != VAT_POSE) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Pose keyframes can only be created on vertex tracks of type pose.", - "VertexAnimationTrack::getVertexPoseKeyFrame"); - } - - return static_cast(getKeyFrame(index)); - } - //-------------------------------------------------------------------------- - KeyFrame* VertexAnimationTrack::createKeyFrameImpl(Real time) - { - switch(mAnimationType) - { - default: - case VAT_MORPH: + TransformKeyFrame* kf = static_cast(*i); + kf->setTranslate(kf->getTranslate() - base->getTranslate()); + kf->setRotation(base->getRotation().Inverse() * kf->getRotation()); + kf->setScale(kf->getScale() * (Vector3::UNIT_SCALE / base->getScale())); + } + + } + //-------------------------------------------------------------------------- + VertexAnimationTrack::VertexAnimationTrack(Animation* parent, + unsigned short handle, VertexAnimationType animType) + : AnimationTrack(parent, handle) + , mAnimationType(animType) + { + } + //-------------------------------------------------------------------------- + VertexAnimationTrack::VertexAnimationTrack(Animation* parent, unsigned short handle, + VertexAnimationType animType, VertexData* targetData, TargetMode target) + : AnimationTrack(parent, handle) + , mAnimationType(animType) + , mTargetVertexData(targetData) + , mTargetMode(target) + { + } + //-------------------------------------------------------------------------- + VertexMorphKeyFrame* VertexAnimationTrack::createVertexMorphKeyFrame(Real timePos) + { + if (mAnimationType != VAT_MORPH) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Morph keyframes can only be created on vertex tracks of type morph.", + "VertexAnimationTrack::createVertexMorphKeyFrame"); + } + return static_cast(createKeyFrame(timePos)); + } + //-------------------------------------------------------------------------- + VertexPoseKeyFrame* VertexAnimationTrack::createVertexPoseKeyFrame(Real timePos) + { + if (mAnimationType != VAT_POSE) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Pose keyframes can only be created on vertex tracks of type pose.", + "VertexAnimationTrack::createVertexPoseKeyFrame"); + } + return static_cast(createKeyFrame(timePos)); + } + //-------------------------------------------------------------------------- + void VertexAnimationTrack::getInterpolatedKeyFrame(const TimeIndex& timeIndex, KeyFrame* kf) const + { + // Only relevant for pose animation + if (mAnimationType == VAT_POSE) + { + // Get keyframes + KeyFrame *kf1, *kf2; + Real t = getKeyFramesAtTime(timeIndex, &kf1, &kf2); + + VertexPoseKeyFrame* vkfOut = static_cast(kf); + VertexPoseKeyFrame* vkf1 = static_cast(kf1); + VertexPoseKeyFrame* vkf2 = static_cast(kf2); + + // For each pose reference in key 1, we need to locate the entry in + // key 2 and interpolate the influence + const VertexPoseKeyFrame::PoseRefList& poseList1 = vkf1->getPoseReferences(); + const VertexPoseKeyFrame::PoseRefList& poseList2 = vkf2->getPoseReferences(); + for (VertexPoseKeyFrame::PoseRefList::const_iterator p1 = poseList1.begin(); + p1 != poseList1.end(); ++p1) + { + Real startInfluence = p1->influence; + Real endInfluence = 0; + // Search for entry in keyframe 2 list (if not there, will be 0) + for (VertexPoseKeyFrame::PoseRefList::const_iterator p2 = poseList2.begin(); + p2 != poseList2.end(); ++p2) + { + if (p1->poseIndex == p2->poseIndex) + { + endInfluence = p2->influence; + break; + } + } + // Interpolate influence + Real influence = startInfluence + t*(endInfluence - startInfluence); + + vkfOut->addPoseReference(p1->poseIndex, influence); + + + } + // Now deal with any poses in key 2 which are not in key 1 + for (VertexPoseKeyFrame::PoseRefList::const_iterator p2 = poseList2.begin(); + p2 != poseList2.end(); ++p2) + { + bool found = false; + for (VertexPoseKeyFrame::PoseRefList::const_iterator p1 = poseList1.begin(); + p1 != poseList1.end(); ++p1) + { + if (p1->poseIndex == p2->poseIndex) + { + found = true; + break; + } + } + if (!found) + { + // Need to apply this pose too, scaled from 0 start + Real influence = t * p2->influence; + + vkfOut->addPoseReference(p2->poseIndex, influence); + + } + } // key 2 iteration + + } + + + } + //-------------------------------------------------------------------------- + bool VertexAnimationTrack::getVertexAnimationIncludesNormals() const + { + if (mAnimationType == VAT_NONE) + return false; + + if (mAnimationType == VAT_MORPH) + { + bool normals = false; + for (KeyFrameList::const_iterator i = mKeyFrames.begin(); i != mKeyFrames.end(); ++i) + { + VertexMorphKeyFrame* kf = static_cast(*i); + bool thisnorm = kf->getVertexBuffer()->getVertexSize() > 12; + if (i == mKeyFrames.begin()) + normals = thisnorm; + else + // Only support normals if ALL keyframes include them + normals = normals && thisnorm; + + } + return normals; + } + else + { + // needs to derive from Mesh::PoseList, can't tell here + return false; + } + + + } + //-------------------------------------------------------------------------- + void VertexAnimationTrack::apply(const TimeIndex& timeIndex, Real weight, Real scale) + { + applyToVertexData(mTargetVertexData, timeIndex, weight); + } + //-------------------------------------------------------------------------- + void VertexAnimationTrack::applyToVertexData(VertexData* data, + const TimeIndex& timeIndex, Real weight, const PoseList* poseList) + { + // Nothing to do if no keyframes or no vertex data + if (mKeyFrames.empty() || !data) + return; + + // Get keyframes + KeyFrame *kf1, *kf2; + Real t = getKeyFramesAtTime(timeIndex, &kf1, &kf2); + + if (mAnimationType == VAT_MORPH) + { + VertexMorphKeyFrame* vkf1 = static_cast(kf1); + VertexMorphKeyFrame* vkf2 = static_cast(kf2); + + if (mTargetMode == TM_HARDWARE) + { + // If target mode is hardware, need to bind our 2 keyframe buffers, + // one to main pos, one to morph target texcoord + assert(!data->hwAnimationDataList.empty() && + "Haven't set up hardware vertex animation elements!"); + + // no use for TempBlendedBufferInfo here btw + // NB we assume that position buffer is unshared, except for normals + // VertexDeclaration::getAutoOrganisedDeclaration should see to that + const VertexElement* posElem = + data->vertexDeclaration->findElementBySemantic(VES_POSITION); + // Set keyframe1 data as original position + data->vertexBufferBinding->setBinding( + posElem->getSource(), vkf1->getVertexBuffer()); + // Set keyframe2 data as derived + data->vertexBufferBinding->setBinding( + data->hwAnimationDataList[0].targetBufferIndex, + vkf2->getVertexBuffer()); + // save T for use later + data->hwAnimationDataList[0].parametric = t; + + } + else + { + // If target mode is software, need to software interpolate each vertex + + Mesh::softwareVertexMorph( + t, vkf1->getVertexBuffer(), vkf2->getVertexBuffer(), data); + } + } + else + { + // Pose + + VertexPoseKeyFrame* vkf1 = static_cast(kf1); + VertexPoseKeyFrame* vkf2 = static_cast(kf2); + + // For each pose reference in key 1, we need to locate the entry in + // key 2 and interpolate the influence + const VertexPoseKeyFrame::PoseRefList& poseList1 = vkf1->getPoseReferences(); + const VertexPoseKeyFrame::PoseRefList& poseList2 = vkf2->getPoseReferences(); + for (VertexPoseKeyFrame::PoseRefList::const_iterator p1 = poseList1.begin(); + p1 != poseList1.end(); ++p1) + { + Real startInfluence = p1->influence; + Real endInfluence = 0; + // Search for entry in keyframe 2 list (if not there, will be 0) + for (VertexPoseKeyFrame::PoseRefList::const_iterator p2 = poseList2.begin(); + p2 != poseList2.end(); ++p2) + { + if (p1->poseIndex == p2->poseIndex) + { + endInfluence = p2->influence; + break; + } + } + // Interpolate influence + Real influence = startInfluence + t*(endInfluence - startInfluence); + // Scale by animation weight + influence = weight * influence; + // Get pose + assert (poseList && p1->poseIndex < poseList->size()); + Pose* pose = (*poseList)[p1->poseIndex]; + // apply + applyPoseToVertexData(pose, data, influence); + } + // Now deal with any poses in key 2 which are not in key 1 + for (VertexPoseKeyFrame::PoseRefList::const_iterator p2 = poseList2.begin(); + p2 != poseList2.end(); ++p2) + { + bool found = false; + for (VertexPoseKeyFrame::PoseRefList::const_iterator p1 = poseList1.begin(); + p1 != poseList1.end(); ++p1) + { + if (p1->poseIndex == p2->poseIndex) + { + found = true; + break; + } + } + if (!found) + { + // Need to apply this pose too, scaled from 0 start + Real influence = t * p2->influence; + // Scale by animation weight + influence = weight * influence; + // Get pose + assert (poseList && p2->poseIndex <= poseList->size()); + const Pose* pose = (*poseList)[p2->poseIndex]; + // apply + applyPoseToVertexData(pose, data, influence); + } + } // key 2 iteration + } // morph or pose animation + } + //----------------------------------------------------------------------------- + void VertexAnimationTrack::applyPoseToVertexData(const Pose* pose, + VertexData* data, Real influence) + { + if (mTargetMode == TM_HARDWARE) + { + // Hardware + // If target mode is hardware, need to bind our pose buffer + // to a target texcoord + assert(!data->hwAnimationDataList.empty() && + "Haven't set up hardware vertex animation elements!"); + // no use for TempBlendedBufferInfo here btw + // Set pose target as required + size_t hwIndex = data->hwAnimDataItemsUsed++; + // If we try to use too many poses, ignore extras + if (hwIndex < data->hwAnimationDataList.size()) + { + VertexData::HardwareAnimationData& animData = data->hwAnimationDataList[hwIndex]; + data->vertexBufferBinding->setBinding( + animData.targetBufferIndex, + pose->_getHardwareVertexBuffer(data)); + // save final influence in parametric + animData.parametric = influence; + + } + + } + else + { + // Software + Mesh::softwareVertexPoseBlend(influence, pose->getVertexOffsets(), pose->getNormals(), data); + } + + } + //-------------------------------------------------------------------------- + VertexMorphKeyFrame* VertexAnimationTrack::getVertexMorphKeyFrame(unsigned short index) const + { + if (mAnimationType != VAT_MORPH) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Morph keyframes can only be created on vertex tracks of type morph.", + "VertexAnimationTrack::getVertexMorphKeyFrame"); + } + + return static_cast(getKeyFrame(index)); + } + //-------------------------------------------------------------------------- + VertexPoseKeyFrame* VertexAnimationTrack::getVertexPoseKeyFrame(unsigned short index) const + { + if (mAnimationType != VAT_POSE) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Pose keyframes can only be created on vertex tracks of type pose.", + "VertexAnimationTrack::getVertexPoseKeyFrame"); + } + + return static_cast(getKeyFrame(index)); + } + //-------------------------------------------------------------------------- + KeyFrame* VertexAnimationTrack::createKeyFrameImpl(Real time) + { + switch(mAnimationType) + { + default: + case VAT_MORPH: return OGRE_NEW VertexMorphKeyFrame(this, time); - case VAT_POSE: - return OGRE_NEW VertexPoseKeyFrame(this, time); - }; - - } - //--------------------------------------------------------------------- - bool VertexAnimationTrack::hasNonZeroKeyFrames(void) const - { - if (mAnimationType == VAT_MORPH) - { - return !mKeyFrames.empty(); - } - else - { - - KeyFrameList::const_iterator i = mKeyFrames.begin(); - for (; i != mKeyFrames.end(); ++i) - { - // look for keyframes which have a pose influence which is non-zero - const VertexPoseKeyFrame* kf = static_cast(*i); - VertexPoseKeyFrame::ConstPoseRefIterator poseIt - = kf->getPoseReferenceIterator(); - while (poseIt.hasMoreElements()) - { - const VertexPoseKeyFrame::PoseRef& poseRef = poseIt.getNext(); - if (poseRef.influence > 0.0f) - return true; - } - - } - - return false; - } - } - //--------------------------------------------------------------------- - void VertexAnimationTrack::optimise(void) - { - // TODO - remove sequences of duplicate pose references? - - - } + case VAT_POSE: + return OGRE_NEW VertexPoseKeyFrame(this, time); + }; + + } //--------------------------------------------------------------------- - VertexAnimationTrack* VertexAnimationTrack::_clone(Animation* newParent) const - { - VertexAnimationTrack* newTrack = - newParent->createVertexTrack(mHandle, mAnimationType); - newTrack->mTargetMode = mTargetMode; - populateClone(newTrack); - return newTrack; - } - //-------------------------------------------------------------------------- - void VertexAnimationTrack::_applyBaseKeyFrame(const KeyFrame* b) - { - const VertexPoseKeyFrame* base = static_cast(b); - + bool VertexAnimationTrack::hasNonZeroKeyFrames(void) const + { + if (mAnimationType == VAT_MORPH) + { + return !mKeyFrames.empty(); + } + else + { + + KeyFrameList::const_iterator i = mKeyFrames.begin(); + for (; i != mKeyFrames.end(); ++i) + { + // look for keyframes which have a pose influence which is non-zero + const VertexPoseKeyFrame* kf = static_cast(*i); + VertexPoseKeyFrame::ConstPoseRefIterator poseIt + = kf->getPoseReferenceIterator(); + while (poseIt.hasMoreElements()) + { + const VertexPoseKeyFrame::PoseRef& poseRef = poseIt.getNext(); + if (poseRef.influence > 0.0f) + return true; + } + + } + + return false; + } + } + //--------------------------------------------------------------------- + void VertexAnimationTrack::optimise(void) + { + // TODO - remove sequences of duplicate pose references? + + + } + //--------------------------------------------------------------------- + VertexAnimationTrack* VertexAnimationTrack::_clone(Animation* newParent) const + { + VertexAnimationTrack* newTrack = + newParent->createVertexTrack(mHandle, mAnimationType); + newTrack->mTargetMode = mTargetMode; + populateClone(newTrack); + return newTrack; + } + //-------------------------------------------------------------------------- + void VertexAnimationTrack::_applyBaseKeyFrame(const KeyFrame* b) + { + const VertexPoseKeyFrame* base = static_cast(b); + for (KeyFrameList::iterator i = mKeyFrames.begin(); i != mKeyFrames.end(); ++i) { - VertexPoseKeyFrame* kf = static_cast(*i); - - kf->_applyBaseKeyFrame(base); - } - - } - + VertexPoseKeyFrame* kf = static_cast(*i); + + kf->_applyBaseKeyFrame(base); + } + + } + } diff --git a/OgreMain/src/OgreArchiveManager.cpp b/OgreMain/src/OgreArchiveManager.cpp index 84e2fc30afc..915702b5f42 100644 --- a/OgreMain/src/OgreArchiveManager.cpp +++ b/OgreMain/src/OgreArchiveManager.cpp @@ -45,9 +45,9 @@ namespace Ogre { assert( msSingleton ); return ( *msSingleton ); } //----------------------------------------------------------------------- - ArchiveManager::ArchiveManager() - { - } + ArchiveManager::ArchiveManager() + { + } //----------------------------------------------------------------------- Archive* ArchiveManager::load( const String& filename, const String& archiveType, bool readOnly) { @@ -74,36 +74,36 @@ namespace Ogre { } return pArch; } - //----------------------------------------------------------------------- - void ArchiveManager::unload(Archive* arch) - { - unload(arch->getName()); - } - //----------------------------------------------------------------------- - void ArchiveManager::unload(const String& filename) - { - ArchiveMap::iterator i = mArchives.find(filename); + //----------------------------------------------------------------------- + void ArchiveManager::unload(Archive* arch) + { + unload(arch->getName()); + } + //----------------------------------------------------------------------- + void ArchiveManager::unload(const String& filename) + { + ArchiveMap::iterator i = mArchives.find(filename); - if (i != mArchives.end()) - { - i->second->unload(); - // Find factory to destroy - ArchiveFactoryMap::iterator fit = mArchFactories.find(i->second->getType()); - if (fit == mArchFactories.end()) - { - // Factory not found - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot find an archive factory " - "to deal with archive of type " + i->second->getType(), "ArchiveManager::~ArchiveManager"); - } - fit->second->destroyInstance(i->second); - mArchives.erase(i); - } - } - //----------------------------------------------------------------------- - ArchiveManager::ArchiveMapIterator ArchiveManager::getArchiveIterator(void) - { - return ArchiveMapIterator(mArchives.begin(), mArchives.end()); - } + if (i != mArchives.end()) + { + i->second->unload(); + // Find factory to destroy + ArchiveFactoryMap::iterator fit = mArchFactories.find(i->second->getType()); + if (fit == mArchFactories.end()) + { + // Factory not found + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot find an archive factory " + "to deal with archive of type " + i->second->getType(), "ArchiveManager::~ArchiveManager"); + } + fit->second->destroyInstance(i->second); + mArchives.erase(i); + } + } + //----------------------------------------------------------------------- + ArchiveManager::ArchiveMapIterator ArchiveManager::getArchiveIterator(void) + { + return ArchiveMapIterator(mArchives.begin(), mArchives.end()); + } //----------------------------------------------------------------------- ArchiveManager::~ArchiveManager() { diff --git a/OgreMain/src/OgreAutoParamDataSource.cpp b/OgreMain/src/OgreAutoParamDataSource.cpp index c6a7e8fa9fa..d38a007aff8 100644 --- a/OgreMain/src/OgreAutoParamDataSource.cpp +++ b/OgreMain/src/OgreAutoParamDataSource.cpp @@ -63,49 +63,49 @@ namespace Ogre { mInverseViewMatrixDirty(true), mInverseTransposeWorldMatrixDirty(true), mInverseTransposeWorldViewMatrixDirty(true), - mCameraPositionDirty(true), + mCameraPositionDirty(true), mCameraPositionObjectSpaceDirty(true), mPassNumber(0), - mSceneDepthRangeDirty(true), - mLodCameraPositionDirty(true), - mLodCameraPositionObjectSpaceDirty(true), + mSceneDepthRangeDirty(true), + mLodCameraPositionDirty(true), + mLodCameraPositionObjectSpaceDirty(true), mCurrentRenderable(0), mCurrentCamera(0), - mCameraRelativeRendering(false), - mCurrentLightList(0), + mCameraRelativeRendering(false), + mCurrentLightList(0), mCurrentRenderTarget(0), mCurrentViewport(0), - mCurrentSceneManager(0), - mMainCamBoundsInfo(0), + mCurrentSceneManager(0), + mMainCamBoundsInfo(0), mCurrentPass(0) { mBlankLight.setDiffuseColour(ColourValue::Black); mBlankLight.setSpecularColour(ColourValue::Black); mBlankLight.setAttenuation(0,1,0,0); - for(size_t i = 0; i < OGRE_MAX_SIMULTANEOUS_LIGHTS; ++i) - { - mTextureViewProjMatrixDirty[i] = true; - mTextureWorldViewProjMatrixDirty[i] = true; - mSpotlightViewProjMatrixDirty[i] = true; - mSpotlightWorldViewProjMatrixDirty[i] = true; - mCurrentTextureProjector[i] = 0; - mShadowCamDepthRangesDirty[i] = false; - } + for(size_t i = 0; i < OGRE_MAX_SIMULTANEOUS_LIGHTS; ++i) + { + mTextureViewProjMatrixDirty[i] = true; + mTextureWorldViewProjMatrixDirty[i] = true; + mSpotlightViewProjMatrixDirty[i] = true; + mSpotlightWorldViewProjMatrixDirty[i] = true; + mCurrentTextureProjector[i] = 0; + mShadowCamDepthRangesDirty[i] = false; + } } //----------------------------------------------------------------------------- AutoParamDataSource::~AutoParamDataSource() { } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- const Light& AutoParamDataSource::getLight(size_t index) const { // If outside light range, return a blank light to ensure zeroised for program - if (mCurrentLightList && index < mCurrentLightList->size()) - { - return *((*mCurrentLightList)[index]); - } - else + if (mCurrentLightList && index < mCurrentLightList->size()) + { + return *((*mCurrentLightList)[index]); + } + else { return mBlankLight; } @@ -113,33 +113,33 @@ namespace Ogre { //----------------------------------------------------------------------------- void AutoParamDataSource::setCurrentRenderable(const Renderable* rend) { - mCurrentRenderable = rend; - mWorldMatrixDirty = true; + mCurrentRenderable = rend; + mWorldMatrixDirty = true; mViewMatrixDirty = true; mProjMatrixDirty = true; - mWorldViewMatrixDirty = true; + mWorldViewMatrixDirty = true; mViewProjMatrixDirty = true; - mWorldViewProjMatrixDirty = true; - mInverseWorldMatrixDirty = true; + mWorldViewProjMatrixDirty = true; + mInverseWorldMatrixDirty = true; mInverseViewMatrixDirty = true; - mInverseWorldViewMatrixDirty = true; - mInverseTransposeWorldMatrixDirty = true; - mInverseTransposeWorldViewMatrixDirty = true; - mCameraPositionObjectSpaceDirty = true; - mLodCameraPositionObjectSpaceDirty = true; - for(size_t i = 0; i < OGRE_MAX_SIMULTANEOUS_LIGHTS; ++i) - { - mTextureWorldViewProjMatrixDirty[i] = true; - mSpotlightWorldViewProjMatrixDirty[i] = true; - } + mInverseWorldViewMatrixDirty = true; + mInverseTransposeWorldMatrixDirty = true; + mInverseTransposeWorldViewMatrixDirty = true; + mCameraPositionObjectSpaceDirty = true; + mLodCameraPositionObjectSpaceDirty = true; + for(size_t i = 0; i < OGRE_MAX_SIMULTANEOUS_LIGHTS; ++i) + { + mTextureWorldViewProjMatrixDirty[i] = true; + mSpotlightWorldViewProjMatrixDirty[i] = true; + } } //----------------------------------------------------------------------------- void AutoParamDataSource::setCurrentCamera(const Camera* cam, bool useCameraRelative) { mCurrentCamera = cam; - mCameraRelativeRendering = useCameraRelative; - mCameraRelativePosition = cam->getDerivedPosition(); + mCameraRelativeRendering = useCameraRelative; + mCameraRelativePosition = cam->getDerivedPosition(); mViewMatrixDirty = true; mProjMatrixDirty = true; mWorldViewMatrixDirty = true; @@ -150,124 +150,124 @@ namespace Ogre { mInverseTransposeWorldViewMatrixDirty = true; mCameraPositionObjectSpaceDirty = true; mCameraPositionDirty = true; - mLodCameraPositionObjectSpaceDirty = true; - mLodCameraPositionDirty = true; + mLodCameraPositionObjectSpaceDirty = true; + mLodCameraPositionDirty = true; } //----------------------------------------------------------------------------- void AutoParamDataSource::setCurrentLightList(const LightList* ll) { mCurrentLightList = ll; - for(size_t i = 0; i < ll->size() && i < OGRE_MAX_SIMULTANEOUS_LIGHTS; ++i) - { - mSpotlightViewProjMatrixDirty[i] = true; - mSpotlightWorldViewProjMatrixDirty[i] = true; - } + for(size_t i = 0; i < ll->size() && i < OGRE_MAX_SIMULTANEOUS_LIGHTS; ++i) + { + mSpotlightViewProjMatrixDirty[i] = true; + mSpotlightWorldViewProjMatrixDirty[i] = true; + } } - //--------------------------------------------------------------------- - float AutoParamDataSource::getLightNumber(size_t index) const - { - return static_cast(getLight(index)._getIndexInFrame()); - } - //----------------------------------------------------------------------------- - const ColourValue& AutoParamDataSource::getLightDiffuseColour(size_t index) const - { - return getLight(index).getDiffuseColour(); - } - //----------------------------------------------------------------------------- - const ColourValue& AutoParamDataSource::getLightSpecularColour(size_t index) const - { - return getLight(index).getSpecularColour(); - } - //----------------------------------------------------------------------------- - const ColourValue AutoParamDataSource::getLightDiffuseColourWithPower(size_t index) const - { - const Light& l = getLight(index); - ColourValue scaled(l.getDiffuseColour()); - Real power = l.getPowerScale(); - // scale, but not alpha - scaled.r *= power; - scaled.g *= power; - scaled.b *= power; - return scaled; - } - //----------------------------------------------------------------------------- - const ColourValue AutoParamDataSource::getLightSpecularColourWithPower(size_t index) const - { - const Light& l = getLight(index); - ColourValue scaled(l.getSpecularColour()); - Real power = l.getPowerScale(); - // scale, but not alpha - scaled.r *= power; - scaled.g *= power; - scaled.b *= power; - return scaled; - } - //----------------------------------------------------------------------------- - const Vector3& AutoParamDataSource::getLightPosition(size_t index) const - { - return getLight(index).getDerivedPosition(true); - } - //----------------------------------------------------------------------------- - Vector4 AutoParamDataSource::getLightAs4DVector(size_t index) const - { - return getLight(index).getAs4DVector(true); - } - //----------------------------------------------------------------------------- - const Vector3& AutoParamDataSource::getLightDirection(size_t index) const - { - return getLight(index).getDerivedDirection(); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getLightPowerScale(size_t index) const - { - return getLight(index).getPowerScale(); - } - //----------------------------------------------------------------------------- - Vector4 AutoParamDataSource::getLightAttenuation(size_t index) const - { - // range, const, linear, quad + //--------------------------------------------------------------------- + float AutoParamDataSource::getLightNumber(size_t index) const + { + return static_cast(getLight(index)._getIndexInFrame()); + } + //----------------------------------------------------------------------------- + const ColourValue& AutoParamDataSource::getLightDiffuseColour(size_t index) const + { + return getLight(index).getDiffuseColour(); + } + //----------------------------------------------------------------------------- + const ColourValue& AutoParamDataSource::getLightSpecularColour(size_t index) const + { + return getLight(index).getSpecularColour(); + } + //----------------------------------------------------------------------------- + const ColourValue AutoParamDataSource::getLightDiffuseColourWithPower(size_t index) const + { + const Light& l = getLight(index); + ColourValue scaled(l.getDiffuseColour()); + Real power = l.getPowerScale(); + // scale, but not alpha + scaled.r *= power; + scaled.g *= power; + scaled.b *= power; + return scaled; + } + //----------------------------------------------------------------------------- + const ColourValue AutoParamDataSource::getLightSpecularColourWithPower(size_t index) const + { + const Light& l = getLight(index); + ColourValue scaled(l.getSpecularColour()); + Real power = l.getPowerScale(); + // scale, but not alpha + scaled.r *= power; + scaled.g *= power; + scaled.b *= power; + return scaled; + } + //----------------------------------------------------------------------------- + const Vector3& AutoParamDataSource::getLightPosition(size_t index) const + { + return getLight(index).getDerivedPosition(true); + } + //----------------------------------------------------------------------------- + Vector4 AutoParamDataSource::getLightAs4DVector(size_t index) const + { + return getLight(index).getAs4DVector(true); + } + //----------------------------------------------------------------------------- + const Vector3& AutoParamDataSource::getLightDirection(size_t index) const + { + return getLight(index).getDerivedDirection(); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getLightPowerScale(size_t index) const + { + return getLight(index).getPowerScale(); + } + //----------------------------------------------------------------------------- + Vector4 AutoParamDataSource::getLightAttenuation(size_t index) const + { + // range, const, linear, quad const Light& l = getLight(index); - return Vector4(l.getAttenuationRange(), - l.getAttenuationConstant(), - l.getAttenuationLinear(), - l.getAttenuationQuadric()); - } - //----------------------------------------------------------------------------- - Vector4 AutoParamDataSource::getSpotlightParams(size_t index) const - { - // inner, outer, fallof, isSpot - const Light& l = getLight(index); - if (l.getType() == Light::LT_SPOTLIGHT) - { - return Vector4(Math::Cos(l.getSpotlightInnerAngle().valueRadians() * 0.5f), - Math::Cos(l.getSpotlightOuterAngle().valueRadians() * 0.5f), - l.getSpotlightFalloff(), - 1.0); - } - else - { - // Use safe values which result in no change to point & dir light calcs - // The spot factor applied to the usual lighting calc is - // pow((dot(spotDir, lightDir) - y) / (x - y), z) - // Therefore if we set z to 0.0f then the factor will always be 1 - // since pow(anything, 0) == 1 - // However we also need to ensure we don't overflow because of the division - // therefore set x = 1 and y = 0 so divisor doesn't change scale - return Vector4(1.0, 0.0, 0.0, 1.0); // since the main op is pow(.., vec4.z), this will result in 1.0 - } - } - //----------------------------------------------------------------------------- - void AutoParamDataSource::setMainCamBoundsInfo(VisibleObjectsBoundsInfo* info) - { - mMainCamBoundsInfo = info; - mSceneDepthRangeDirty = true; - } - //----------------------------------------------------------------------------- - void AutoParamDataSource::setCurrentSceneManager(const SceneManager* sm) - { - mCurrentSceneManager = sm; - } + return Vector4(l.getAttenuationRange(), + l.getAttenuationConstant(), + l.getAttenuationLinear(), + l.getAttenuationQuadric()); + } + //----------------------------------------------------------------------------- + Vector4 AutoParamDataSource::getSpotlightParams(size_t index) const + { + // inner, outer, fallof, isSpot + const Light& l = getLight(index); + if (l.getType() == Light::LT_SPOTLIGHT) + { + return Vector4(Math::Cos(l.getSpotlightInnerAngle().valueRadians() * 0.5f), + Math::Cos(l.getSpotlightOuterAngle().valueRadians() * 0.5f), + l.getSpotlightFalloff(), + 1.0); + } + else + { + // Use safe values which result in no change to point & dir light calcs + // The spot factor applied to the usual lighting calc is + // pow((dot(spotDir, lightDir) - y) / (x - y), z) + // Therefore if we set z to 0.0f then the factor will always be 1 + // since pow(anything, 0) == 1 + // However we also need to ensure we don't overflow because of the division + // therefore set x = 1 and y = 0 so divisor doesn't change scale + return Vector4(1.0, 0.0, 0.0, 1.0); // since the main op is pow(.., vec4.z), this will result in 1.0 + } + } + //----------------------------------------------------------------------------- + void AutoParamDataSource::setMainCamBoundsInfo(VisibleObjectsBoundsInfo* info) + { + mMainCamBoundsInfo = info; + mSceneDepthRangeDirty = true; + } + //----------------------------------------------------------------------------- + void AutoParamDataSource::setCurrentSceneManager(const SceneManager* sm) + { + mCurrentSceneManager = sm; + } //----------------------------------------------------------------------------- void AutoParamDataSource::setWorldMatrices(const Matrix4* m, size_t count) { @@ -283,13 +283,13 @@ namespace Ogre { mWorldMatrixArray = mWorldMatrix; mCurrentRenderable->getWorldTransforms(mWorldMatrix); mWorldMatrixCount = mCurrentRenderable->getNumWorldTransforms(); - if (mCameraRelativeRendering) - { - for (size_t i = 0; i < mWorldMatrixCount; ++i) - { - mWorldMatrix[i].setTrans(mWorldMatrix[i].getTrans() - mCameraRelativePosition); - } - } + if (mCameraRelativeRendering) + { + for (size_t i = 0; i < mWorldMatrixCount; ++i) + { + mWorldMatrix[i].setTrans(mWorldMatrix[i].getTrans() - mCameraRelativePosition); + } + } mWorldMatrixDirty = false; } return mWorldMatrixArray[0]; @@ -297,15 +297,15 @@ namespace Ogre { //----------------------------------------------------------------------------- size_t AutoParamDataSource::getWorldMatrixCount(void) const { - // trigger derivation - getWorldMatrix(); + // trigger derivation + getWorldMatrix(); return mWorldMatrixCount; } //----------------------------------------------------------------------------- const Matrix4* AutoParamDataSource::getWorldMatrixArray(void) const { - // trigger derivation - getWorldMatrix(); + // trigger derivation + getWorldMatrix(); return mWorldMatrixArray; } //----------------------------------------------------------------------------- @@ -316,14 +316,14 @@ namespace Ogre { if (mCurrentRenderable && mCurrentRenderable->getUseIdentityView()) mViewMatrix = Matrix4::IDENTITY; else - { + { mViewMatrix = mCurrentCamera->getViewMatrix(true); - if (mCameraRelativeRendering) - { - mViewMatrix.setTrans(Vector3::ZERO); - } + if (mCameraRelativeRendering) + { + mViewMatrix.setTrans(Vector3::ZERO); + } - } + } mViewMatrixDirty = false; } return mViewMatrix; @@ -441,99 +441,99 @@ namespace Ogre { //----------------------------------------------------------------------------- const Vector4& AutoParamDataSource::getCameraPosition(void) const { - if(mCameraPositionDirty) - { - Vector3 vec3 = mCurrentCamera->getDerivedPosition(); - if (mCameraRelativeRendering) - { - vec3 -= mCameraRelativePosition; - } - mCameraPosition[0] = vec3[0]; - mCameraPosition[1] = vec3[1]; - mCameraPosition[2] = vec3[2]; - mCameraPosition[3] = 1.0; - mCameraPositionDirty = false; - } - return mCameraPosition; + if(mCameraPositionDirty) + { + Vector3 vec3 = mCurrentCamera->getDerivedPosition(); + if (mCameraRelativeRendering) + { + vec3 -= mCameraRelativePosition; + } + mCameraPosition[0] = vec3[0]; + mCameraPosition[1] = vec3[1]; + mCameraPosition[2] = vec3[2]; + mCameraPosition[3] = 1.0; + mCameraPositionDirty = false; + } + return mCameraPosition; } //----------------------------------------------------------------------------- const Vector4& AutoParamDataSource::getCameraPositionObjectSpace(void) const { if (mCameraPositionObjectSpaceDirty) { - if (mCameraRelativeRendering) - { - mCameraPositionObjectSpace = - getInverseWorldMatrix().transformAffine(Vector3::ZERO); - } - else - { - mCameraPositionObjectSpace = - getInverseWorldMatrix().transformAffine(mCurrentCamera->getDerivedPosition()); - } + if (mCameraRelativeRendering) + { + mCameraPositionObjectSpace = + getInverseWorldMatrix().transformAffine(Vector3::ZERO); + } + else + { + mCameraPositionObjectSpace = + getInverseWorldMatrix().transformAffine(mCurrentCamera->getDerivedPosition()); + } mCameraPositionObjectSpaceDirty = false; } return mCameraPositionObjectSpace; } - //----------------------------------------------------------------------------- - const Vector4& AutoParamDataSource::getLodCameraPosition(void) const - { - if(mLodCameraPositionDirty) - { - Vector3 vec3 = mCurrentCamera->getLodCamera()->getDerivedPosition(); + //----------------------------------------------------------------------------- + const Vector4& AutoParamDataSource::getLodCameraPosition(void) const + { + if(mLodCameraPositionDirty) + { + Vector3 vec3 = mCurrentCamera->getLodCamera()->getDerivedPosition(); if (mCameraRelativeRendering) { vec3 -= mCameraRelativePosition; } - mLodCameraPosition[0] = vec3[0]; - mLodCameraPosition[1] = vec3[1]; - mLodCameraPosition[2] = vec3[2]; - mLodCameraPosition[3] = 1.0; - mLodCameraPositionDirty = false; - } - return mLodCameraPosition; - } - //----------------------------------------------------------------------------- - const Vector4& AutoParamDataSource::getLodCameraPositionObjectSpace(void) const - { - if (mLodCameraPositionObjectSpaceDirty) - { + mLodCameraPosition[0] = vec3[0]; + mLodCameraPosition[1] = vec3[1]; + mLodCameraPosition[2] = vec3[2]; + mLodCameraPosition[3] = 1.0; + mLodCameraPositionDirty = false; + } + return mLodCameraPosition; + } + //----------------------------------------------------------------------------- + const Vector4& AutoParamDataSource::getLodCameraPositionObjectSpace(void) const + { + if (mLodCameraPositionObjectSpaceDirty) + { if (mCameraRelativeRendering) - { - mLodCameraPositionObjectSpace = - getInverseWorldMatrix().transformAffine(mCurrentCamera->getLodCamera()->getDerivedPosition() - - mCameraRelativePosition); - } - else - { - mLodCameraPositionObjectSpace = - getInverseWorldMatrix().transformAffine(mCurrentCamera->getLodCamera()->getDerivedPosition()); + { + mLodCameraPositionObjectSpace = + getInverseWorldMatrix().transformAffine(mCurrentCamera->getLodCamera()->getDerivedPosition() + - mCameraRelativePosition); + } + else + { + mLodCameraPositionObjectSpace = + getInverseWorldMatrix().transformAffine(mCurrentCamera->getLodCamera()->getDerivedPosition()); } mLodCameraPositionObjectSpaceDirty = false; - } - return mLodCameraPositionObjectSpace; - } - //----------------------------------------------------------------------------- - void AutoParamDataSource::setAmbientLightColour(const ColourValue& ambient) - { - mAmbientLight = ambient; - } - //--------------------------------------------------------------------- - float AutoParamDataSource::getLightCount() const - { - return static_cast(mCurrentLightList->size()); - } - //--------------------------------------------------------------------- - float AutoParamDataSource::getLightCastsShadows(size_t index) const - { - return getLight(index).getCastShadows() ? 1.0f : 0.0f; - } - //----------------------------------------------------------------------------- - const ColourValue& AutoParamDataSource::getAmbientLightColour(void) const - { - return mAmbientLight; - - } + } + return mLodCameraPositionObjectSpace; + } + //----------------------------------------------------------------------------- + void AutoParamDataSource::setAmbientLightColour(const ColourValue& ambient) + { + mAmbientLight = ambient; + } + //--------------------------------------------------------------------- + float AutoParamDataSource::getLightCount() const + { + return static_cast(mCurrentLightList->size()); + } + //--------------------------------------------------------------------- + float AutoParamDataSource::getLightCastsShadows(size_t index) const + { + return getLight(index).getCastShadows() ? 1.0f : 0.0f; + } + //----------------------------------------------------------------------------- + const ColourValue& AutoParamDataSource::getAmbientLightColour(void) const + { + return mAmbientLight; + + } //----------------------------------------------------------------------------- void AutoParamDataSource::setCurrentPass(const Pass* pass) { @@ -552,7 +552,7 @@ namespace Ogre { if (index < mCurrentPass->getNumTextureUnitStates()) { const TexturePtr& tex = mCurrentPass->getTextureUnitState( - static_cast(index))->_getTexturePtr(); + static_cast(index))->_getTexturePtr(); if (!tex.isNull()) { size.x = static_cast(tex->getWidth()); @@ -641,141 +641,141 @@ namespace Ogre { //----------------------------------------------------------------------------- void AutoParamDataSource::setTextureProjector(const Frustum* frust, size_t index = 0) { - if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) - { - mCurrentTextureProjector[index] = frust; - mTextureViewProjMatrixDirty[index] = true; - mTextureWorldViewProjMatrixDirty[index] = true; - mShadowCamDepthRangesDirty[index] = true; - } + if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) + { + mCurrentTextureProjector[index] = frust; + mTextureViewProjMatrixDirty[index] = true; + mTextureWorldViewProjMatrixDirty[index] = true; + mShadowCamDepthRangesDirty[index] = true; + } } //----------------------------------------------------------------------------- const Matrix4& AutoParamDataSource::getTextureViewProjMatrix(size_t index) const { - if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) - { - if (mTextureViewProjMatrixDirty[index] && mCurrentTextureProjector[index]) - { - if (mCameraRelativeRendering) - { - // World positions are now going to be relative to the camera position - // so we need to alter the projector view matrix to compensate - Matrix4 viewMatrix; - mCurrentTextureProjector[index]->calcViewMatrixRelative( - mCurrentCamera->getDerivedPosition(), viewMatrix); - mTextureViewProjMatrix[index] = - PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE * - mCurrentTextureProjector[index]->getProjectionMatrixWithRSDepth() * - viewMatrix; - } - else - { - mTextureViewProjMatrix[index] = - PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE * - mCurrentTextureProjector[index]->getProjectionMatrixWithRSDepth() * - mCurrentTextureProjector[index]->getViewMatrix(); - } - mTextureViewProjMatrixDirty[index] = false; - } - return mTextureViewProjMatrix[index]; - } - else - return Matrix4::IDENTITY; - } - //----------------------------------------------------------------------------- - const Matrix4& AutoParamDataSource::getTextureWorldViewProjMatrix(size_t index) const - { - if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) - { - if (mTextureWorldViewProjMatrixDirty[index] && mCurrentTextureProjector[index]) - { - mTextureWorldViewProjMatrix[index] = - getTextureViewProjMatrix(index) * getWorldMatrix(); - mTextureWorldViewProjMatrixDirty[index] = false; - } - return mTextureWorldViewProjMatrix[index]; - } - else - return Matrix4::IDENTITY; - } - //----------------------------------------------------------------------------- - const Matrix4& AutoParamDataSource::getSpotlightViewProjMatrix(size_t index) const - { - if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) - { - const Light& l = getLight(index); + if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) + { + if (mTextureViewProjMatrixDirty[index] && mCurrentTextureProjector[index]) + { + if (mCameraRelativeRendering) + { + // World positions are now going to be relative to the camera position + // so we need to alter the projector view matrix to compensate + Matrix4 viewMatrix; + mCurrentTextureProjector[index]->calcViewMatrixRelative( + mCurrentCamera->getDerivedPosition(), viewMatrix); + mTextureViewProjMatrix[index] = + PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE * + mCurrentTextureProjector[index]->getProjectionMatrixWithRSDepth() * + viewMatrix; + } + else + { + mTextureViewProjMatrix[index] = + PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE * + mCurrentTextureProjector[index]->getProjectionMatrixWithRSDepth() * + mCurrentTextureProjector[index]->getViewMatrix(); + } + mTextureViewProjMatrixDirty[index] = false; + } + return mTextureViewProjMatrix[index]; + } + else + return Matrix4::IDENTITY; + } + //----------------------------------------------------------------------------- + const Matrix4& AutoParamDataSource::getTextureWorldViewProjMatrix(size_t index) const + { + if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) + { + if (mTextureWorldViewProjMatrixDirty[index] && mCurrentTextureProjector[index]) + { + mTextureWorldViewProjMatrix[index] = + getTextureViewProjMatrix(index) * getWorldMatrix(); + mTextureWorldViewProjMatrixDirty[index] = false; + } + return mTextureWorldViewProjMatrix[index]; + } + else + return Matrix4::IDENTITY; + } + //----------------------------------------------------------------------------- + const Matrix4& AutoParamDataSource::getSpotlightViewProjMatrix(size_t index) const + { + if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) + { + const Light& l = getLight(index); - if (&l != &mBlankLight && - l.getType() == Light::LT_SPOTLIGHT && - mSpotlightViewProjMatrixDirty[index]) - { - Frustum frust; - SceneNode dummyNode(0); - dummyNode.attachObject(&frust); + if (&l != &mBlankLight && + l.getType() == Light::LT_SPOTLIGHT && + mSpotlightViewProjMatrixDirty[index]) + { + Frustum frust; + SceneNode dummyNode(0); + dummyNode.attachObject(&frust); - frust.setProjectionType(PT_PERSPECTIVE); - frust.setFOVy(l.getSpotlightOuterAngle()); - frust.setAspectRatio(1.0f); - // set near clip the same as main camera, since they are likely - // to both reflect the nature of the scene - frust.setNearClipDistance(mCurrentCamera->getNearClipDistance()); - // Calculate position, which same as spotlight position, in camera-relative coords if required - dummyNode.setPosition(l.getDerivedPosition(true)); - // Calculate direction, which same as spotlight direction - Vector3 dir = - l.getDerivedDirection(); // backwards since point down -z - dir.normalise(); - Vector3 up = Vector3::UNIT_Y; - // Check it's not coincident with dir - if (Math::Abs(up.dotProduct(dir)) >= 1.0f) - { - // Use camera up - up = Vector3::UNIT_Z; - } - // cross twice to rederive, only direction is unaltered - Vector3 left = dir.crossProduct(up); - left.normalise(); - up = dir.crossProduct(left); - up.normalise(); - // Derive quaternion from axes - Quaternion q; - q.FromAxes(left, up, dir); - dummyNode.setOrientation(q); + frust.setProjectionType(PT_PERSPECTIVE); + frust.setFOVy(l.getSpotlightOuterAngle()); + frust.setAspectRatio(1.0f); + // set near clip the same as main camera, since they are likely + // to both reflect the nature of the scene + frust.setNearClipDistance(mCurrentCamera->getNearClipDistance()); + // Calculate position, which same as spotlight position, in camera-relative coords if required + dummyNode.setPosition(l.getDerivedPosition(true)); + // Calculate direction, which same as spotlight direction + Vector3 dir = - l.getDerivedDirection(); // backwards since point down -z + dir.normalise(); + Vector3 up = Vector3::UNIT_Y; + // Check it's not coincident with dir + if (Math::Abs(up.dotProduct(dir)) >= 1.0f) + { + // Use camera up + up = Vector3::UNIT_Z; + } + // cross twice to rederive, only direction is unaltered + Vector3 left = dir.crossProduct(up); + left.normalise(); + up = dir.crossProduct(left); + up.normalise(); + // Derive quaternion from axes + Quaternion q; + q.FromAxes(left, up, dir); + dummyNode.setOrientation(q); - // The view matrix here already includes camera-relative changes if necessary - // since they are built into the frustum position - mSpotlightViewProjMatrix[index] = - PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE * - frust.getProjectionMatrixWithRSDepth() * - frust.getViewMatrix(); + // The view matrix here already includes camera-relative changes if necessary + // since they are built into the frustum position + mSpotlightViewProjMatrix[index] = + PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE * + frust.getProjectionMatrixWithRSDepth() * + frust.getViewMatrix(); - mSpotlightViewProjMatrixDirty[index] = false; - } - return mSpotlightViewProjMatrix[index]; - } - else - return Matrix4::IDENTITY; - } - //----------------------------------------------------------------------------- - const Matrix4& AutoParamDataSource::getSpotlightWorldViewProjMatrix(size_t index) const - { - if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) - { - const Light& l = getLight(index); + mSpotlightViewProjMatrixDirty[index] = false; + } + return mSpotlightViewProjMatrix[index]; + } + else + return Matrix4::IDENTITY; + } + //----------------------------------------------------------------------------- + const Matrix4& AutoParamDataSource::getSpotlightWorldViewProjMatrix(size_t index) const + { + if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) + { + const Light& l = getLight(index); - if (&l != &mBlankLight && - l.getType() == Light::LT_SPOTLIGHT && - mSpotlightWorldViewProjMatrixDirty[index]) - { - mSpotlightWorldViewProjMatrix[index] = - getSpotlightViewProjMatrix(index) * getWorldMatrix(); - mSpotlightWorldViewProjMatrixDirty[index] = false; - } - return mSpotlightWorldViewProjMatrix[index]; - } - else - return Matrix4::IDENTITY; - } + if (&l != &mBlankLight && + l.getType() == Light::LT_SPOTLIGHT && + mSpotlightWorldViewProjMatrixDirty[index]) + { + mSpotlightWorldViewProjMatrix[index] = + getSpotlightViewProjMatrix(index) * getWorldMatrix(); + mSpotlightWorldViewProjMatrixDirty[index] = false; + } + return mSpotlightWorldViewProjMatrix[index]; + } + else + return Matrix4::IDENTITY; + } //----------------------------------------------------------------------------- const Matrix4& AutoParamDataSource::getTextureTransformMatrix(size_t index) const { @@ -809,335 +809,335 @@ namespace Ogre { mCurrentViewport = viewport; } //----------------------------------------------------------------------------- - void AutoParamDataSource::setShadowDirLightExtrusionDistance(Real dist) - { - mDirLightExtrusionDistance = dist; - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getShadowExtrusionDistance(void) const - { - const Light& l = getLight(0); // only ever applies to one light at once - if (l.getType() == Light::LT_DIRECTIONAL) - { - // use constant - return mDirLightExtrusionDistance; - } - else - { - // Calculate based on object space light distance - // compared to light attenuation range - Vector3 objPos = getInverseWorldMatrix().transformAffine(l.getDerivedPosition(true)); - return l.getAttenuationRange() - objPos.length(); - } - } + void AutoParamDataSource::setShadowDirLightExtrusionDistance(Real dist) + { + mDirLightExtrusionDistance = dist; + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getShadowExtrusionDistance(void) const + { + const Light& l = getLight(0); // only ever applies to one light at once + if (l.getType() == Light::LT_DIRECTIONAL) + { + // use constant + return mDirLightExtrusionDistance; + } + else + { + // Calculate based on object space light distance + // compared to light attenuation range + Vector3 objPos = getInverseWorldMatrix().transformAffine(l.getDerivedPosition(true)); + return l.getAttenuationRange() - objPos.length(); + } + } //----------------------------------------------------------------------------- const Renderable* AutoParamDataSource::getCurrentRenderable(void) const { return mCurrentRenderable; } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getInverseViewProjMatrix(void) const - { - return this->getViewProjectionMatrix().inverse(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getInverseTransposeViewProjMatrix(void) const - { - return this->getInverseViewProjMatrix().transpose(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getTransposeViewProjMatrix(void) const - { - return this->getViewProjectionMatrix().transpose(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getTransposeViewMatrix(void) const - { - return this->getViewMatrix().transpose(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getInverseTransposeViewMatrix(void) const - { - return this->getInverseViewMatrix().transpose(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getTransposeProjectionMatrix(void) const - { - return this->getProjectionMatrix().transpose(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getInverseProjectionMatrix(void) const - { - return this->getProjectionMatrix().inverse(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getInverseTransposeProjectionMatrix(void) const - { - return this->getInverseProjectionMatrix().transpose(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getTransposeWorldViewProjMatrix(void) const - { - return this->getWorldViewProjMatrix().transpose(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getInverseWorldViewProjMatrix(void) const - { - return this->getWorldViewProjMatrix().inverse(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getInverseTransposeWorldViewProjMatrix(void) const - { - return this->getInverseWorldViewProjMatrix().transpose(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getTransposeWorldViewMatrix(void) const - { - return this->getWorldViewMatrix().transpose(); - } - //----------------------------------------------------------------------------- - Matrix4 AutoParamDataSource::getTransposeWorldMatrix(void) const - { - return this->getWorldMatrix().transpose(); - } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getInverseViewProjMatrix(void) const + { + return this->getViewProjectionMatrix().inverse(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getInverseTransposeViewProjMatrix(void) const + { + return this->getInverseViewProjMatrix().transpose(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getTransposeViewProjMatrix(void) const + { + return this->getViewProjectionMatrix().transpose(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getTransposeViewMatrix(void) const + { + return this->getViewMatrix().transpose(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getInverseTransposeViewMatrix(void) const + { + return this->getInverseViewMatrix().transpose(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getTransposeProjectionMatrix(void) const + { + return this->getProjectionMatrix().transpose(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getInverseProjectionMatrix(void) const + { + return this->getProjectionMatrix().inverse(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getInverseTransposeProjectionMatrix(void) const + { + return this->getInverseProjectionMatrix().transpose(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getTransposeWorldViewProjMatrix(void) const + { + return this->getWorldViewProjMatrix().transpose(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getInverseWorldViewProjMatrix(void) const + { + return this->getWorldViewProjMatrix().inverse(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getInverseTransposeWorldViewProjMatrix(void) const + { + return this->getInverseWorldViewProjMatrix().transpose(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getTransposeWorldViewMatrix(void) const + { + return this->getWorldViewMatrix().transpose(); + } + //----------------------------------------------------------------------------- + Matrix4 AutoParamDataSource::getTransposeWorldMatrix(void) const + { + return this->getWorldMatrix().transpose(); + } //----------------------------------------------------------------------------- Real AutoParamDataSource::getTime(void) const { return ControllerManager::getSingleton().getElapsedTime(); } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getTime_0_X(Real x) const - { - return fmod(this->getTime(), x); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getCosTime_0_X(Real x) const - { - return cos(this->getTime_0_X(x)); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getSinTime_0_X(Real x) const - { - return sin(this->getTime_0_X(x)); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getTanTime_0_X(Real x) const - { - return tan(this->getTime_0_X(x)); - } - //----------------------------------------------------------------------------- - Vector4 AutoParamDataSource::getTime_0_X_packed(Real x) const - { - Real t = this->getTime_0_X(x); - return Vector4(t, sin(t), cos(t), tan(t)); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getTime_0_1(Real x) const - { - return this->getTime_0_X(x)/x; - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getCosTime_0_1(Real x) const - { - return cos(this->getTime_0_1(x)); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getSinTime_0_1(Real x) const - { - return sin(this->getTime_0_1(x)); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getTanTime_0_1(Real x) const - { - return tan(this->getTime_0_1(x)); - } - //----------------------------------------------------------------------------- - Vector4 AutoParamDataSource::getTime_0_1_packed(Real x) const - { - Real t = this->getTime_0_1(x); - return Vector4(t, sin(t), cos(t), tan(t)); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getTime_0_2Pi(Real x) const - { - return this->getTime_0_X(x)/x*2*Math::PI; - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getCosTime_0_2Pi(Real x) const - { - return cos(this->getTime_0_2Pi(x)); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getSinTime_0_2Pi(Real x) const - { - return sin(this->getTime_0_2Pi(x)); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getTanTime_0_2Pi(Real x) const - { - return tan(this->getTime_0_2Pi(x)); - } - //----------------------------------------------------------------------------- - Vector4 AutoParamDataSource::getTime_0_2Pi_packed(Real x) const - { - Real t = this->getTime_0_2Pi(x); - return Vector4(t, sin(t), cos(t), tan(t)); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getFrameTime(void) const - { - return ControllerManager::getSingleton().getFrameTimeSource()->getValue(); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getFPS() const - { - return mCurrentRenderTarget->getLastFPS(); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getViewportWidth() const - { - return static_cast(mCurrentViewport->getActualWidth()); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getViewportHeight() const - { - return static_cast(mCurrentViewport->getActualHeight()); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getInverseViewportWidth() const - { - return 1.0f/mCurrentViewport->getActualWidth(); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getInverseViewportHeight() const - { - return 1.0f/mCurrentViewport->getActualHeight(); - } - //----------------------------------------------------------------------------- - Vector3 AutoParamDataSource::getViewDirection() const - { - return mCurrentCamera->getDerivedDirection(); - } - //----------------------------------------------------------------------------- - Vector3 AutoParamDataSource::getViewSideVector() const - { - return mCurrentCamera->getDerivedRight(); - } - //----------------------------------------------------------------------------- - Vector3 AutoParamDataSource::getViewUpVector() const - { - return mCurrentCamera->getDerivedUp(); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getFOV() const - { - return mCurrentCamera->getFOVy().valueRadians(); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getNearClipDistance() const - { - return mCurrentCamera->getNearClipDistance(); - } - //----------------------------------------------------------------------------- - Real AutoParamDataSource::getFarClipDistance() const - { - return mCurrentCamera->getFarClipDistance(); - } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getTime_0_X(Real x) const + { + return fmod(this->getTime(), x); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getCosTime_0_X(Real x) const + { + return cos(this->getTime_0_X(x)); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getSinTime_0_X(Real x) const + { + return sin(this->getTime_0_X(x)); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getTanTime_0_X(Real x) const + { + return tan(this->getTime_0_X(x)); + } + //----------------------------------------------------------------------------- + Vector4 AutoParamDataSource::getTime_0_X_packed(Real x) const + { + Real t = this->getTime_0_X(x); + return Vector4(t, sin(t), cos(t), tan(t)); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getTime_0_1(Real x) const + { + return this->getTime_0_X(x)/x; + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getCosTime_0_1(Real x) const + { + return cos(this->getTime_0_1(x)); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getSinTime_0_1(Real x) const + { + return sin(this->getTime_0_1(x)); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getTanTime_0_1(Real x) const + { + return tan(this->getTime_0_1(x)); + } + //----------------------------------------------------------------------------- + Vector4 AutoParamDataSource::getTime_0_1_packed(Real x) const + { + Real t = this->getTime_0_1(x); + return Vector4(t, sin(t), cos(t), tan(t)); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getTime_0_2Pi(Real x) const + { + return this->getTime_0_X(x)/x*2*Math::PI; + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getCosTime_0_2Pi(Real x) const + { + return cos(this->getTime_0_2Pi(x)); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getSinTime_0_2Pi(Real x) const + { + return sin(this->getTime_0_2Pi(x)); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getTanTime_0_2Pi(Real x) const + { + return tan(this->getTime_0_2Pi(x)); + } + //----------------------------------------------------------------------------- + Vector4 AutoParamDataSource::getTime_0_2Pi_packed(Real x) const + { + Real t = this->getTime_0_2Pi(x); + return Vector4(t, sin(t), cos(t), tan(t)); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getFrameTime(void) const + { + return ControllerManager::getSingleton().getFrameTimeSource()->getValue(); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getFPS() const + { + return mCurrentRenderTarget->getLastFPS(); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getViewportWidth() const + { + return static_cast(mCurrentViewport->getActualWidth()); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getViewportHeight() const + { + return static_cast(mCurrentViewport->getActualHeight()); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getInverseViewportWidth() const + { + return 1.0f/mCurrentViewport->getActualWidth(); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getInverseViewportHeight() const + { + return 1.0f/mCurrentViewport->getActualHeight(); + } + //----------------------------------------------------------------------------- + Vector3 AutoParamDataSource::getViewDirection() const + { + return mCurrentCamera->getDerivedDirection(); + } + //----------------------------------------------------------------------------- + Vector3 AutoParamDataSource::getViewSideVector() const + { + return mCurrentCamera->getDerivedRight(); + } + //----------------------------------------------------------------------------- + Vector3 AutoParamDataSource::getViewUpVector() const + { + return mCurrentCamera->getDerivedUp(); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getFOV() const + { + return mCurrentCamera->getFOVy().valueRadians(); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getNearClipDistance() const + { + return mCurrentCamera->getNearClipDistance(); + } + //----------------------------------------------------------------------------- + Real AutoParamDataSource::getFarClipDistance() const + { + return mCurrentCamera->getFarClipDistance(); + } + //----------------------------------------------------------------------------- int AutoParamDataSource::getPassNumber(void) const { return mPassNumber; } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void AutoParamDataSource::setPassNumber(const int passNumber) { mPassNumber = passNumber; } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void AutoParamDataSource::incPassNumber(void) { ++mPassNumber; } - //----------------------------------------------------------------------------- - const Vector4& AutoParamDataSource::getSceneDepthRange() const - { - static Vector4 dummy(0, 100000, 100000, 1/100000); + //----------------------------------------------------------------------------- + const Vector4& AutoParamDataSource::getSceneDepthRange() const + { + static Vector4 dummy(0, 100000, 100000, 1/100000); - if (mSceneDepthRangeDirty) - { - // calculate depth information - Real depthRange = mMainCamBoundsInfo->maxDistanceInFrustum - mMainCamBoundsInfo->minDistanceInFrustum; - if (depthRange > std::numeric_limits::epsilon()) - { - mSceneDepthRange = Vector4( - mMainCamBoundsInfo->minDistanceInFrustum, - mMainCamBoundsInfo->maxDistanceInFrustum, - depthRange, - 1.0f / depthRange); - } - else - { - mSceneDepthRange = dummy; - } - mSceneDepthRangeDirty = false; - } + if (mSceneDepthRangeDirty) + { + // calculate depth information + Real depthRange = mMainCamBoundsInfo->maxDistanceInFrustum - mMainCamBoundsInfo->minDistanceInFrustum; + if (depthRange > std::numeric_limits::epsilon()) + { + mSceneDepthRange = Vector4( + mMainCamBoundsInfo->minDistanceInFrustum, + mMainCamBoundsInfo->maxDistanceInFrustum, + depthRange, + 1.0f / depthRange); + } + else + { + mSceneDepthRange = dummy; + } + mSceneDepthRangeDirty = false; + } - return mSceneDepthRange; + return mSceneDepthRange; - } - //----------------------------------------------------------------------------- - const Vector4& AutoParamDataSource::getShadowSceneDepthRange(size_t index) const - { - static Vector4 dummy(0, 100000, 100000, 1/100000); + } + //----------------------------------------------------------------------------- + const Vector4& AutoParamDataSource::getShadowSceneDepthRange(size_t index) const + { + static Vector4 dummy(0, 100000, 100000, 1/100000); - if (!mCurrentSceneManager->isShadowTechniqueTextureBased()) - return dummy; + if (!mCurrentSceneManager->isShadowTechniqueTextureBased()) + return dummy; - if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) - { - if (mShadowCamDepthRangesDirty[index] && mCurrentTextureProjector[index]) - { - const VisibleObjectsBoundsInfo& info = - mCurrentSceneManager->getVisibleObjectsBoundsInfo( - (const Camera*)mCurrentTextureProjector[index]); + if (index < OGRE_MAX_SIMULTANEOUS_LIGHTS) + { + if (mShadowCamDepthRangesDirty[index] && mCurrentTextureProjector[index]) + { + const VisibleObjectsBoundsInfo& info = + mCurrentSceneManager->getVisibleObjectsBoundsInfo( + (const Camera*)mCurrentTextureProjector[index]); - Real depthRange = info.maxDistanceInFrustum - info.minDistanceInFrustum; - if (depthRange > std::numeric_limits::epsilon()) - { - mShadowCamDepthRanges[index] = Vector4( - info.minDistanceInFrustum, - info.maxDistanceInFrustum, - depthRange, - 1.0f / depthRange); - } - else - { - mShadowCamDepthRanges[index] = dummy; - } + Real depthRange = info.maxDistanceInFrustum - info.minDistanceInFrustum; + if (depthRange > std::numeric_limits::epsilon()) + { + mShadowCamDepthRanges[index] = Vector4( + info.minDistanceInFrustum, + info.maxDistanceInFrustum, + depthRange, + 1.0f / depthRange); + } + else + { + mShadowCamDepthRanges[index] = dummy; + } - mShadowCamDepthRangesDirty[index] = false; - } - return mShadowCamDepthRanges[index]; - } - else - return dummy; - } - //--------------------------------------------------------------------- - const ColourValue& AutoParamDataSource::getShadowColour() const - { - return mCurrentSceneManager->getShadowColour(); - } - //------------------------------------------------------------------------- - void AutoParamDataSource::updateLightCustomGpuParameter(const GpuProgramParameters::AutoConstantEntry& constantEntry, GpuProgramParameters *params) const - { - uint16 lightIndex = static_cast(constantEntry.data & 0xFFFF), - paramIndex = static_cast((constantEntry.data >> 16) & 0xFFFF); - if(mCurrentLightList && lightIndex < mCurrentLightList->size()) - { - const Light &light = getLight(lightIndex); - light._updateCustomGpuParameter(paramIndex, constantEntry, params); - } - } + mShadowCamDepthRangesDirty[index] = false; + } + return mShadowCamDepthRanges[index]; + } + else + return dummy; + } + //--------------------------------------------------------------------- + const ColourValue& AutoParamDataSource::getShadowColour() const + { + return mCurrentSceneManager->getShadowColour(); + } + //------------------------------------------------------------------------- + void AutoParamDataSource::updateLightCustomGpuParameter(const GpuProgramParameters::AutoConstantEntry& constantEntry, GpuProgramParameters *params) const + { + uint16 lightIndex = static_cast(constantEntry.data & 0xFFFF), + paramIndex = static_cast((constantEntry.data >> 16) & 0xFFFF); + if(mCurrentLightList && lightIndex < mCurrentLightList->size()) + { + const Light &light = getLight(lightIndex); + light._updateCustomGpuParameter(paramIndex, constantEntry, params); + } + } } diff --git a/OgreMain/src/OgreAxisAlignedBox.cpp b/OgreMain/src/OgreAxisAlignedBox.cpp index 72c7a606abf..edf6c42f3eb 100644 --- a/OgreMain/src/OgreAxisAlignedBox.cpp +++ b/OgreMain/src/OgreAxisAlignedBox.cpp @@ -30,7 +30,7 @@ THE SOFTWARE. namespace Ogre { - const AxisAlignedBox AxisAlignedBox::BOX_NULL; - const AxisAlignedBox AxisAlignedBox::BOX_INFINITE(AxisAlignedBox::EXTENT_INFINITE); + const AxisAlignedBox AxisAlignedBox::BOX_NULL; + const AxisAlignedBox AxisAlignedBox::BOX_INFINITE(AxisAlignedBox::EXTENT_INFINITE); } diff --git a/OgreMain/src/OgreBillboard.cpp b/OgreMain/src/OgreBillboard.cpp index b4f40137eb0..da7ca531b1e 100644 --- a/OgreMain/src/OgreBillboard.cpp +++ b/OgreMain/src/OgreBillboard.cpp @@ -38,11 +38,11 @@ namespace Ogre { mOwnDimensions(false), mUseTexcoordRect(false), mTexcoordIndex(0), - mPosition(Vector3::ZERO), + mPosition(Vector3::ZERO), mDirection(Vector3::ZERO), mParentSet(0), mColour(ColourValue::White), - mRotation(0) + mRotation(0) { } //----------------------------------------------------------------------- diff --git a/OgreMain/src/OgreBillboardChain.cpp b/OgreMain/src/OgreBillboardChain.cpp index 807019c5d23..22d76eb7f5f 100644 --- a/OgreMain/src/OgreBillboardChain.cpp +++ b/OgreMain/src/OgreBillboardChain.cpp @@ -43,447 +43,447 @@ THE SOFTWARE. #include namespace Ogre { - const size_t BillboardChain::SEGMENT_EMPTY = std::numeric_limits::max(); - //----------------------------------------------------------------------- - BillboardChain::Element::Element() - { - } - //----------------------------------------------------------------------- - BillboardChain::Element::Element(const Vector3 &_position, - Real _width, - Real _texCoord, - const ColourValue &_colour, - const Quaternion &_orientation) : - position(_position), - width(_width), - texCoord(_texCoord), - colour(_colour), - orientation(_orientation) - { - } - //----------------------------------------------------------------------- - BillboardChain::BillboardChain(const String& name, size_t maxElements, - size_t numberOfChains, bool useTextureCoords, bool useColours, bool dynamic) - :MovableObject(name), - mMaxElementsPerChain(maxElements), - mChainCount(numberOfChains), - mUseTexCoords(useTextureCoords), - mUseVertexColour(useColours), - mDynamic(dynamic), - mVertexDeclDirty(true), - mBuffersNeedRecreating(true), - mBoundsDirty(true), - mIndexContentDirty(true), + const size_t BillboardChain::SEGMENT_EMPTY = std::numeric_limits::max(); + //----------------------------------------------------------------------- + BillboardChain::Element::Element() + { + } + //----------------------------------------------------------------------- + BillboardChain::Element::Element(const Vector3 &_position, + Real _width, + Real _texCoord, + const ColourValue &_colour, + const Quaternion &_orientation) : + position(_position), + width(_width), + texCoord(_texCoord), + colour(_colour), + orientation(_orientation) + { + } + //----------------------------------------------------------------------- + BillboardChain::BillboardChain(const String& name, size_t maxElements, + size_t numberOfChains, bool useTextureCoords, bool useColours, bool dynamic) + :MovableObject(name), + mMaxElementsPerChain(maxElements), + mChainCount(numberOfChains), + mUseTexCoords(useTextureCoords), + mUseVertexColour(useColours), + mDynamic(dynamic), + mVertexDeclDirty(true), + mBuffersNeedRecreating(true), + mBoundsDirty(true), + mIndexContentDirty(true), mVertexContentDirty(true), - mRadius(0.0f), - mTexCoordDir(TCD_U), + mRadius(0.0f), + mTexCoordDir(TCD_U), mVertexCameraUsed(0), - mFaceCamera(true), - mNormalBase(Vector3::UNIT_X) - { - mVertexData = OGRE_NEW VertexData(); - mIndexData = OGRE_NEW IndexData(); - - mOtherTexCoordRange[0] = 0.0f; - mOtherTexCoordRange[1] = 1.0f; - - setupChainContainers(); - - mVertexData->vertexStart = 0; - // index data set up later - // set basic white material - this->setMaterialName("BaseWhiteNoLighting"); - - } - //----------------------------------------------------------------------- - BillboardChain::~BillboardChain() - { - OGRE_DELETE mVertexData; - OGRE_DELETE mIndexData; - } - //----------------------------------------------------------------------- - void BillboardChain::setupChainContainers(void) - { - // Allocate enough space for everything - mChainElementList.resize(mChainCount * mMaxElementsPerChain); - mVertexData->vertexCount = mChainElementList.size() * 2; - - // Configure chains - mChainSegmentList.resize(mChainCount); - for (size_t i = 0; i < mChainCount; ++i) - { - ChainSegment& seg = mChainSegmentList[i]; - seg.start = i * mMaxElementsPerChain; - seg.tail = seg.head = SEGMENT_EMPTY; - - } - - - } - //----------------------------------------------------------------------- - void BillboardChain::setupVertexDeclaration(void) - { - if (mVertexDeclDirty) - { - VertexDeclaration* decl = mVertexData->vertexDeclaration; - decl->removeAllElements(); - - size_t offset = 0; - // Add a description for the buffer of the positions of the vertices - decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); - offset += VertexElement::getTypeSize(VET_FLOAT3); - - if (mUseVertexColour) - { - decl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE); - offset += VertexElement::getTypeSize(VET_COLOUR); - } - - if (mUseTexCoords) - { - decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES); - } - - if (!mUseTexCoords && !mUseVertexColour) - { - LogManager::getSingleton().logMessage( - "Error - BillboardChain '" + mName + "' is using neither " - "texture coordinates or vertex colours; it will not be " - "visible on some rendering APIs so you should change this " - "so you use one or the other."); - } - mVertexDeclDirty = false; - } - } - //----------------------------------------------------------------------- - void BillboardChain::setupBuffers(void) - { - setupVertexDeclaration(); - if (mBuffersNeedRecreating) - { - // Create the vertex buffer (always dynamic due to the camera adjust) - HardwareVertexBufferSharedPtr pBuffer = - HardwareBufferManager::getSingleton().createVertexBuffer( - mVertexData->vertexDeclaration->getVertexSize(0), - mVertexData->vertexCount, - HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); - - // (re)Bind the buffer - // Any existing buffer will lose its reference count and be destroyed - mVertexData->vertexBufferBinding->setBinding(0, pBuffer); - - mIndexData->indexBuffer = - HardwareBufferManager::getSingleton().createIndexBuffer( - HardwareIndexBuffer::IT_16BIT, - mChainCount * mMaxElementsPerChain * 6, // max we can use - mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : HardwareBuffer::HBU_STATIC_WRITE_ONLY); - // NB we don't set the indexCount on IndexData here since we will - // probably use less than the maximum number of indices - - mBuffersNeedRecreating = false; - } - } - //----------------------------------------------------------------------- - void BillboardChain::setMaxChainElements(size_t maxElements) - { - mMaxElementsPerChain = maxElements; - setupChainContainers(); + mFaceCamera(true), + mNormalBase(Vector3::UNIT_X) + { + mVertexData = OGRE_NEW VertexData(); + mIndexData = OGRE_NEW IndexData(); + + mOtherTexCoordRange[0] = 0.0f; + mOtherTexCoordRange[1] = 1.0f; + + setupChainContainers(); + + mVertexData->vertexStart = 0; + // index data set up later + // set basic white material + this->setMaterialName("BaseWhiteNoLighting"); + + } + //----------------------------------------------------------------------- + BillboardChain::~BillboardChain() + { + OGRE_DELETE mVertexData; + OGRE_DELETE mIndexData; + } + //----------------------------------------------------------------------- + void BillboardChain::setupChainContainers(void) + { + // Allocate enough space for everything + mChainElementList.resize(mChainCount * mMaxElementsPerChain); + mVertexData->vertexCount = mChainElementList.size() * 2; + + // Configure chains + mChainSegmentList.resize(mChainCount); + for (size_t i = 0; i < mChainCount; ++i) + { + ChainSegment& seg = mChainSegmentList[i]; + seg.start = i * mMaxElementsPerChain; + seg.tail = seg.head = SEGMENT_EMPTY; + + } + + + } + //----------------------------------------------------------------------- + void BillboardChain::setupVertexDeclaration(void) + { + if (mVertexDeclDirty) + { + VertexDeclaration* decl = mVertexData->vertexDeclaration; + decl->removeAllElements(); + + size_t offset = 0; + // Add a description for the buffer of the positions of the vertices + decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); + offset += VertexElement::getTypeSize(VET_FLOAT3); + + if (mUseVertexColour) + { + decl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE); + offset += VertexElement::getTypeSize(VET_COLOUR); + } + + if (mUseTexCoords) + { + decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES); + } + + if (!mUseTexCoords && !mUseVertexColour) + { + LogManager::getSingleton().logMessage( + "Error - BillboardChain '" + mName + "' is using neither " + "texture coordinates or vertex colours; it will not be " + "visible on some rendering APIs so you should change this " + "so you use one or the other."); + } + mVertexDeclDirty = false; + } + } + //----------------------------------------------------------------------- + void BillboardChain::setupBuffers(void) + { + setupVertexDeclaration(); + if (mBuffersNeedRecreating) + { + // Create the vertex buffer (always dynamic due to the camera adjust) + HardwareVertexBufferSharedPtr pBuffer = + HardwareBufferManager::getSingleton().createVertexBuffer( + mVertexData->vertexDeclaration->getVertexSize(0), + mVertexData->vertexCount, + HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); + + // (re)Bind the buffer + // Any existing buffer will lose its reference count and be destroyed + mVertexData->vertexBufferBinding->setBinding(0, pBuffer); + + mIndexData->indexBuffer = + HardwareBufferManager::getSingleton().createIndexBuffer( + HardwareIndexBuffer::IT_16BIT, + mChainCount * mMaxElementsPerChain * 6, // max we can use + mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : HardwareBuffer::HBU_STATIC_WRITE_ONLY); + // NB we don't set the indexCount on IndexData here since we will + // probably use less than the maximum number of indices + + mBuffersNeedRecreating = false; + } + } + //----------------------------------------------------------------------- + void BillboardChain::setMaxChainElements(size_t maxElements) + { + mMaxElementsPerChain = maxElements; + setupChainContainers(); mBuffersNeedRecreating = mIndexContentDirty = mVertexContentDirty = true; - } - //----------------------------------------------------------------------- - void BillboardChain::setNumberOfChains(size_t numChains) - { - mChainCount = numChains; - setupChainContainers(); + } + //----------------------------------------------------------------------- + void BillboardChain::setNumberOfChains(size_t numChains) + { + mChainCount = numChains; + setupChainContainers(); mBuffersNeedRecreating = mIndexContentDirty = mVertexContentDirty = true; - } - //----------------------------------------------------------------------- - void BillboardChain::setUseTextureCoords(bool use) - { - mUseTexCoords = use; - mVertexDeclDirty = mBuffersNeedRecreating = true; + } + //----------------------------------------------------------------------- + void BillboardChain::setUseTextureCoords(bool use) + { + mUseTexCoords = use; + mVertexDeclDirty = mBuffersNeedRecreating = true; mIndexContentDirty = mVertexContentDirty = true; - } - //----------------------------------------------------------------------- - void BillboardChain::setTextureCoordDirection(BillboardChain::TexCoordDirection dir) - { - mTexCoordDir = dir; + } + //----------------------------------------------------------------------- + void BillboardChain::setTextureCoordDirection(BillboardChain::TexCoordDirection dir) + { + mTexCoordDir = dir; mVertexContentDirty = true; - } - //----------------------------------------------------------------------- - void BillboardChain::setOtherTextureCoordRange(Real start, Real end) - { - mOtherTexCoordRange[0] = start; - mOtherTexCoordRange[1] = end; + } + //----------------------------------------------------------------------- + void BillboardChain::setOtherTextureCoordRange(Real start, Real end) + { + mOtherTexCoordRange[0] = start; + mOtherTexCoordRange[1] = end; mVertexContentDirty = true; - } - //----------------------------------------------------------------------- - void BillboardChain::setUseVertexColours(bool use) - { - mUseVertexColour = use; - mVertexDeclDirty = mBuffersNeedRecreating = true; + } + //----------------------------------------------------------------------- + void BillboardChain::setUseVertexColours(bool use) + { + mUseVertexColour = use; + mVertexDeclDirty = mBuffersNeedRecreating = true; mIndexContentDirty = mVertexContentDirty = true; - } - //----------------------------------------------------------------------- - void BillboardChain::setDynamic(bool dyn) - { - mDynamic = dyn; - mBuffersNeedRecreating = mIndexContentDirty = mVertexContentDirty = true; - } - //----------------------------------------------------------------------- - void BillboardChain::addChainElement(size_t chainIndex, - const BillboardChain::Element& dtls) - { - - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "chainIndex out of bounds", - "BillboardChain::addChainElement"); - } - ChainSegment& seg = mChainSegmentList[chainIndex]; - if (seg.head == SEGMENT_EMPTY) - { - // Tail starts at end, head grows backwards - seg.tail = mMaxElementsPerChain - 1; - seg.head = seg.tail; - } - else - { - if (seg.head == 0) - { - // Wrap backwards - seg.head = mMaxElementsPerChain - 1; - } - else - { - // Just step backward - --seg.head; - } - // Run out of elements? - if (seg.head == seg.tail) - { - // Move tail backwards too, losing the end of the segment and re-using - // it in the head - if (seg.tail == 0) - seg.tail = mMaxElementsPerChain - 1; - else - --seg.tail; - } - } - - // Set the details - mChainElementList[seg.start + seg.head] = dtls; + } + //----------------------------------------------------------------------- + void BillboardChain::setDynamic(bool dyn) + { + mDynamic = dyn; + mBuffersNeedRecreating = mIndexContentDirty = mVertexContentDirty = true; + } + //----------------------------------------------------------------------- + void BillboardChain::addChainElement(size_t chainIndex, + const BillboardChain::Element& dtls) + { + + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "chainIndex out of bounds", + "BillboardChain::addChainElement"); + } + ChainSegment& seg = mChainSegmentList[chainIndex]; + if (seg.head == SEGMENT_EMPTY) + { + // Tail starts at end, head grows backwards + seg.tail = mMaxElementsPerChain - 1; + seg.head = seg.tail; + } + else + { + if (seg.head == 0) + { + // Wrap backwards + seg.head = mMaxElementsPerChain - 1; + } + else + { + // Just step backward + --seg.head; + } + // Run out of elements? + if (seg.head == seg.tail) + { + // Move tail backwards too, losing the end of the segment and re-using + // it in the head + if (seg.tail == 0) + seg.tail = mMaxElementsPerChain - 1; + else + --seg.tail; + } + } + + // Set the details + mChainElementList[seg.start + seg.head] = dtls; mVertexContentDirty = true; - mIndexContentDirty = true; - mBoundsDirty = true; - // tell parent node to update bounds - if (mParentNode) - mParentNode->needUpdate(); - - } - //----------------------------------------------------------------------- - void BillboardChain::removeChainElement(size_t chainIndex) - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "chainIndex out of bounds", - "BillboardChain::removeChainElement"); - } - ChainSegment& seg = mChainSegmentList[chainIndex]; - if (seg.head == SEGMENT_EMPTY) - return; // do nothing, nothing to remove - - - if (seg.tail == seg.head) - { - // last item - seg.head = seg.tail = SEGMENT_EMPTY; - } - else if (seg.tail == 0) - { - seg.tail = mMaxElementsPerChain - 1; - } - else - { - --seg.tail; - } - - // we removed an entry so indexes need updating + mIndexContentDirty = true; + mBoundsDirty = true; + // tell parent node to update bounds + if (mParentNode) + mParentNode->needUpdate(); + + } + //----------------------------------------------------------------------- + void BillboardChain::removeChainElement(size_t chainIndex) + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "chainIndex out of bounds", + "BillboardChain::removeChainElement"); + } + ChainSegment& seg = mChainSegmentList[chainIndex]; + if (seg.head == SEGMENT_EMPTY) + return; // do nothing, nothing to remove + + + if (seg.tail == seg.head) + { + // last item + seg.head = seg.tail = SEGMENT_EMPTY; + } + else if (seg.tail == 0) + { + seg.tail = mMaxElementsPerChain - 1; + } + else + { + --seg.tail; + } + + // we removed an entry so indexes need updating mVertexContentDirty = true; - mIndexContentDirty = true; - mBoundsDirty = true; - // tell parent node to update bounds - if (mParentNode) - mParentNode->needUpdate(); - - } - //----------------------------------------------------------------------- - void BillboardChain::clearChain(size_t chainIndex) - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "chainIndex out of bounds", - "BillboardChain::clearChain"); - } - ChainSegment& seg = mChainSegmentList[chainIndex]; - - // Just reset head & tail - seg.tail = seg.head = SEGMENT_EMPTY; - - // we removed an entry so indexes need updating + mIndexContentDirty = true; + mBoundsDirty = true; + // tell parent node to update bounds + if (mParentNode) + mParentNode->needUpdate(); + + } + //----------------------------------------------------------------------- + void BillboardChain::clearChain(size_t chainIndex) + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "chainIndex out of bounds", + "BillboardChain::clearChain"); + } + ChainSegment& seg = mChainSegmentList[chainIndex]; + + // Just reset head & tail + seg.tail = seg.head = SEGMENT_EMPTY; + + // we removed an entry so indexes need updating mVertexContentDirty = true; - mIndexContentDirty = true; - mBoundsDirty = true; - // tell parent node to update bounds - if (mParentNode) - mParentNode->needUpdate(); - - } - //----------------------------------------------------------------------- - void BillboardChain::clearAllChains(void) - { - for (size_t i = 0; i < mChainCount; ++i) - { - clearChain(i); - } - - } - //----------------------------------------------------------------------- - void BillboardChain::setFaceCamera( bool faceCamera, const Vector3 &normalVector ) - { - mFaceCamera = faceCamera; - mNormalBase = normalVector.normalisedCopy(); + mIndexContentDirty = true; + mBoundsDirty = true; + // tell parent node to update bounds + if (mParentNode) + mParentNode->needUpdate(); + + } + //----------------------------------------------------------------------- + void BillboardChain::clearAllChains(void) + { + for (size_t i = 0; i < mChainCount; ++i) + { + clearChain(i); + } + + } + //----------------------------------------------------------------------- + void BillboardChain::setFaceCamera( bool faceCamera, const Vector3 &normalVector ) + { + mFaceCamera = faceCamera; + mNormalBase = normalVector.normalisedCopy(); mVertexContentDirty = true; - } - //----------------------------------------------------------------------- - void BillboardChain::updateChainElement(size_t chainIndex, size_t elementIndex, - const BillboardChain::Element& dtls) - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "chainIndex out of bounds", - "BillboardChain::updateChainElement"); - } - ChainSegment& seg = mChainSegmentList[chainIndex]; - if (seg.head == SEGMENT_EMPTY) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Chain segment is empty", - "BillboardChain::updateChainElement"); - } - - size_t idx = seg.head + elementIndex; - // adjust for the edge and start - idx = (idx % mMaxElementsPerChain) + seg.start; - - mChainElementList[idx] = dtls; + } + //----------------------------------------------------------------------- + void BillboardChain::updateChainElement(size_t chainIndex, size_t elementIndex, + const BillboardChain::Element& dtls) + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "chainIndex out of bounds", + "BillboardChain::updateChainElement"); + } + ChainSegment& seg = mChainSegmentList[chainIndex]; + if (seg.head == SEGMENT_EMPTY) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Chain segment is empty", + "BillboardChain::updateChainElement"); + } + + size_t idx = seg.head + elementIndex; + // adjust for the edge and start + idx = (idx % mMaxElementsPerChain) + seg.start; + + mChainElementList[idx] = dtls; mVertexContentDirty = true; - mBoundsDirty = true; - // tell parent node to update bounds - if (mParentNode) - mParentNode->needUpdate(); - - - } - //----------------------------------------------------------------------- - const BillboardChain::Element& - BillboardChain::getChainElement(size_t chainIndex, size_t elementIndex) const - { - - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "chainIndex out of bounds", - "BillboardChain::getChainElement"); - } - const ChainSegment& seg = mChainSegmentList[chainIndex]; - - size_t idx = seg.head + elementIndex; - // adjust for the edge and start - idx = (idx % mMaxElementsPerChain) + seg.start; - - return mChainElementList[idx]; - } - //----------------------------------------------------------------------- - size_t BillboardChain::getNumChainElements(size_t chainIndex) const - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "chainIndex out of bounds", - "BillboardChain::getNumChainElements"); - } - const ChainSegment& seg = mChainSegmentList[chainIndex]; - - if( seg.tail < seg.head ) - { - return seg.tail - seg.head + mMaxElementsPerChain + 1; - } - else - { - return seg.tail - seg.head + 1; - } - } - //----------------------------------------------------------------------- - void BillboardChain::updateBoundingBox(void) const - { - if (mBoundsDirty) - { - mAABB.setNull(); - Vector3 widthVector; - for (ChainSegmentList::const_iterator segi = mChainSegmentList.begin(); - segi != mChainSegmentList.end(); ++segi) - { - const ChainSegment& seg = *segi; - - if (seg.head != SEGMENT_EMPTY) - { - - for(size_t e = seg.head; ; ++e) // until break - { - // Wrap forwards - if (e == mMaxElementsPerChain) - e = 0; - - const Element& elem = mChainElementList[seg.start + e]; - - widthVector.x = widthVector.y = widthVector.z = elem.width; - mAABB.merge(elem.position - widthVector); - mAABB.merge(elem.position + widthVector); - - if (e == seg.tail) - break; - - } - } - - } - - // Set the current radius - if (mAABB.isNull()) - { - mRadius = 0.0f; - } - else - { - mRadius = Math::Sqrt( - std::max(mAABB.getMinimum().squaredLength(), - mAABB.getMaximum().squaredLength())); - } - - mBoundsDirty = false; - } - } - //----------------------------------------------------------------------- - void BillboardChain::updateVertexBuffer(Camera* cam) - { - setupBuffers(); + mBoundsDirty = true; + // tell parent node to update bounds + if (mParentNode) + mParentNode->needUpdate(); + + + } + //----------------------------------------------------------------------- + const BillboardChain::Element& + BillboardChain::getChainElement(size_t chainIndex, size_t elementIndex) const + { + + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "chainIndex out of bounds", + "BillboardChain::getChainElement"); + } + const ChainSegment& seg = mChainSegmentList[chainIndex]; + + size_t idx = seg.head + elementIndex; + // adjust for the edge and start + idx = (idx % mMaxElementsPerChain) + seg.start; + + return mChainElementList[idx]; + } + //----------------------------------------------------------------------- + size_t BillboardChain::getNumChainElements(size_t chainIndex) const + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "chainIndex out of bounds", + "BillboardChain::getNumChainElements"); + } + const ChainSegment& seg = mChainSegmentList[chainIndex]; + + if( seg.tail < seg.head ) + { + return seg.tail - seg.head + mMaxElementsPerChain + 1; + } + else + { + return seg.tail - seg.head + 1; + } + } + //----------------------------------------------------------------------- + void BillboardChain::updateBoundingBox(void) const + { + if (mBoundsDirty) + { + mAABB.setNull(); + Vector3 widthVector; + for (ChainSegmentList::const_iterator segi = mChainSegmentList.begin(); + segi != mChainSegmentList.end(); ++segi) + { + const ChainSegment& seg = *segi; + + if (seg.head != SEGMENT_EMPTY) + { + + for(size_t e = seg.head; ; ++e) // until break + { + // Wrap forwards + if (e == mMaxElementsPerChain) + e = 0; + + const Element& elem = mChainElementList[seg.start + e]; + + widthVector.x = widthVector.y = widthVector.z = elem.width; + mAABB.merge(elem.position - widthVector); + mAABB.merge(elem.position + widthVector); + + if (e == seg.tail) + break; + + } + } + + } + + // Set the current radius + if (mAABB.isNull()) + { + mRadius = 0.0f; + } + else + { + mRadius = Math::Sqrt( + std::max(mAABB.getMinimum().squaredLength(), + mAABB.getMaximum().squaredLength())); + } + + mBoundsDirty = false; + } + } + //----------------------------------------------------------------------- + void BillboardChain::updateVertexBuffer(Camera* cam) + { + setupBuffers(); // The contents of the vertex buffer are correct if they are not dirty // and the camera used to build the vertex buffer is still the current @@ -491,294 +491,294 @@ namespace Ogre { if (!mVertexContentDirty && mVertexCameraUsed == cam) return; - HardwareVertexBufferSharedPtr pBuffer = - mVertexData->vertexBufferBinding->getBuffer(0); - void* pBufferStart = pBuffer->lock(HardwareBuffer::HBL_DISCARD); - - const Vector3& camPos = cam->getDerivedPosition(); - Vector3 eyePos = mParentNode->_getDerivedOrientation().Inverse() * - (camPos - mParentNode->_getDerivedPosition()) / mParentNode->_getDerivedScale(); - - Vector3 chainTangent; - for (ChainSegmentList::iterator segi = mChainSegmentList.begin(); - segi != mChainSegmentList.end(); ++segi) - { - ChainSegment& seg = *segi; - - // Skip 0 or 1 element segment counts - if (seg.head != SEGMENT_EMPTY && seg.head != seg.tail) - { - size_t laste = seg.head; - for (size_t e = seg.head; ; ++e) // until break - { - // Wrap forwards - if (e == mMaxElementsPerChain) - e = 0; - - Element& elem = mChainElementList[e + seg.start]; - assert (((e + seg.start) * 2) < 65536 && "Too many elements!"); - uint16 baseIdx = static_cast((e + seg.start) * 2); - - // Determine base pointer to vertex #1 - void* pBase = static_cast( - static_cast(pBufferStart) + - pBuffer->getVertexSize() * baseIdx); - - // Get index of next item - size_t nexte = e + 1; - if (nexte == mMaxElementsPerChain) - nexte = 0; - - if (e == seg.head) - { - // No laste, use next item - chainTangent = mChainElementList[nexte + seg.start].position - elem.position; - } - else if (e == seg.tail) - { - // No nexte, use only last item - chainTangent = elem.position - mChainElementList[laste + seg.start].position; - } - else - { - // A mid position, use tangent across both prev and next - chainTangent = mChainElementList[nexte + seg.start].position - mChainElementList[laste + seg.start].position; - - } - - Vector3 vP1ToEye; - - if( mFaceCamera ) - vP1ToEye = eyePos - elem.position; - else - vP1ToEye = elem.orientation * mNormalBase; - - Vector3 vPerpendicular = chainTangent.crossProduct(vP1ToEye); - vPerpendicular.normalise(); - vPerpendicular *= (elem.width * 0.5f); - - Vector3 pos0 = elem.position - vPerpendicular; - Vector3 pos1 = elem.position + vPerpendicular; - - float* pFloat = static_cast(pBase); - // pos1 - *pFloat++ = pos0.x; - *pFloat++ = pos0.y; - *pFloat++ = pos0.z; - - pBase = static_cast(pFloat); - - if (mUseVertexColour) - { - RGBA* pCol = static_cast(pBase); - Root::getSingleton().convertColourValue(elem.colour, pCol); - pCol++; - pBase = static_cast(pCol); - } - - if (mUseTexCoords) - { - pFloat = static_cast(pBase); - if (mTexCoordDir == TCD_U) - { - *pFloat++ = elem.texCoord; - *pFloat++ = mOtherTexCoordRange[0]; - } - else - { - *pFloat++ = mOtherTexCoordRange[0]; - *pFloat++ = elem.texCoord; - } - pBase = static_cast(pFloat); - } - - // pos2 - pFloat = static_cast(pBase); - *pFloat++ = pos1.x; - *pFloat++ = pos1.y; - *pFloat++ = pos1.z; - pBase = static_cast(pFloat); - - if (mUseVertexColour) - { - RGBA* pCol = static_cast(pBase); - Root::getSingleton().convertColourValue(elem.colour, pCol); - pCol++; - pBase = static_cast(pCol); - } - - if (mUseTexCoords) - { - pFloat = static_cast(pBase); - if (mTexCoordDir == TCD_U) - { - *pFloat++ = elem.texCoord; - *pFloat++ = mOtherTexCoordRange[1]; - } - else - { - *pFloat++ = mOtherTexCoordRange[1]; - *pFloat++ = elem.texCoord; - } - } - - if (e == seg.tail) - break; // last one - - laste = e; - - } // element - } // segment valid? - - } // each segment - - - - pBuffer->unlock(); + HardwareVertexBufferSharedPtr pBuffer = + mVertexData->vertexBufferBinding->getBuffer(0); + void* pBufferStart = pBuffer->lock(HardwareBuffer::HBL_DISCARD); + + const Vector3& camPos = cam->getDerivedPosition(); + Vector3 eyePos = mParentNode->_getDerivedOrientation().Inverse() * + (camPos - mParentNode->_getDerivedPosition()) / mParentNode->_getDerivedScale(); + + Vector3 chainTangent; + for (ChainSegmentList::iterator segi = mChainSegmentList.begin(); + segi != mChainSegmentList.end(); ++segi) + { + ChainSegment& seg = *segi; + + // Skip 0 or 1 element segment counts + if (seg.head != SEGMENT_EMPTY && seg.head != seg.tail) + { + size_t laste = seg.head; + for (size_t e = seg.head; ; ++e) // until break + { + // Wrap forwards + if (e == mMaxElementsPerChain) + e = 0; + + Element& elem = mChainElementList[e + seg.start]; + assert (((e + seg.start) * 2) < 65536 && "Too many elements!"); + uint16 baseIdx = static_cast((e + seg.start) * 2); + + // Determine base pointer to vertex #1 + void* pBase = static_cast( + static_cast(pBufferStart) + + pBuffer->getVertexSize() * baseIdx); + + // Get index of next item + size_t nexte = e + 1; + if (nexte == mMaxElementsPerChain) + nexte = 0; + + if (e == seg.head) + { + // No laste, use next item + chainTangent = mChainElementList[nexte + seg.start].position - elem.position; + } + else if (e == seg.tail) + { + // No nexte, use only last item + chainTangent = elem.position - mChainElementList[laste + seg.start].position; + } + else + { + // A mid position, use tangent across both prev and next + chainTangent = mChainElementList[nexte + seg.start].position - mChainElementList[laste + seg.start].position; + + } + + Vector3 vP1ToEye; + + if( mFaceCamera ) + vP1ToEye = eyePos - elem.position; + else + vP1ToEye = elem.orientation * mNormalBase; + + Vector3 vPerpendicular = chainTangent.crossProduct(vP1ToEye); + vPerpendicular.normalise(); + vPerpendicular *= (elem.width * 0.5f); + + Vector3 pos0 = elem.position - vPerpendicular; + Vector3 pos1 = elem.position + vPerpendicular; + + float* pFloat = static_cast(pBase); + // pos1 + *pFloat++ = pos0.x; + *pFloat++ = pos0.y; + *pFloat++ = pos0.z; + + pBase = static_cast(pFloat); + + if (mUseVertexColour) + { + RGBA* pCol = static_cast(pBase); + Root::getSingleton().convertColourValue(elem.colour, pCol); + pCol++; + pBase = static_cast(pCol); + } + + if (mUseTexCoords) + { + pFloat = static_cast(pBase); + if (mTexCoordDir == TCD_U) + { + *pFloat++ = elem.texCoord; + *pFloat++ = mOtherTexCoordRange[0]; + } + else + { + *pFloat++ = mOtherTexCoordRange[0]; + *pFloat++ = elem.texCoord; + } + pBase = static_cast(pFloat); + } + + // pos2 + pFloat = static_cast(pBase); + *pFloat++ = pos1.x; + *pFloat++ = pos1.y; + *pFloat++ = pos1.z; + pBase = static_cast(pFloat); + + if (mUseVertexColour) + { + RGBA* pCol = static_cast(pBase); + Root::getSingleton().convertColourValue(elem.colour, pCol); + pCol++; + pBase = static_cast(pCol); + } + + if (mUseTexCoords) + { + pFloat = static_cast(pBase); + if (mTexCoordDir == TCD_U) + { + *pFloat++ = elem.texCoord; + *pFloat++ = mOtherTexCoordRange[1]; + } + else + { + *pFloat++ = mOtherTexCoordRange[1]; + *pFloat++ = elem.texCoord; + } + } + + if (e == seg.tail) + break; // last one + + laste = e; + + } // element + } // segment valid? + + } // each segment + + + + pBuffer->unlock(); mVertexCameraUsed = cam; mVertexContentDirty = false; - } - //----------------------------------------------------------------------- - void BillboardChain::updateIndexBuffer(void) - { - - setupBuffers(); - if (mIndexContentDirty) - { - - uint16* pShort = static_cast( - mIndexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - mIndexData->indexCount = 0; - // indexes - for (ChainSegmentList::iterator segi = mChainSegmentList.begin(); - segi != mChainSegmentList.end(); ++segi) - { - ChainSegment& seg = *segi; - - // Skip 0 or 1 element segment counts - if (seg.head != SEGMENT_EMPTY && seg.head != seg.tail) - { - // Start from head + 1 since it's only useful in pairs - size_t laste = seg.head; - while(1) // until break - { - size_t e = laste + 1; - // Wrap forwards - if (e == mMaxElementsPerChain) - e = 0; - // indexes of this element are (e * 2) and (e * 2) + 1 - // indexes of the last element are the same, -2 - assert (((e + seg.start) * 2) < 65536 && "Too many elements!"); - uint16 baseIdx = static_cast((e + seg.start) * 2); - uint16 lastBaseIdx = static_cast((laste + seg.start) * 2); - *pShort++ = lastBaseIdx; - *pShort++ = lastBaseIdx + 1; - *pShort++ = baseIdx; - *pShort++ = lastBaseIdx + 1; - *pShort++ = baseIdx + 1; - *pShort++ = baseIdx; - - mIndexData->indexCount += 6; - - - if (e == seg.tail) - break; // last one - - laste = e; - - } - } - - } - mIndexData->indexBuffer->unlock(); - - mIndexContentDirty = false; - } - - } - //----------------------------------------------------------------------- - Real BillboardChain::getSquaredViewDepth(const Camera* cam) const - { - Vector3 min, max, mid, dist; - min = mAABB.getMinimum(); - max = mAABB.getMaximum(); - mid = ((max - min) * 0.5) + min; - dist = cam->getDerivedPosition() - mid; - - return dist.squaredLength(); - } - //----------------------------------------------------------------------- - Real BillboardChain::getBoundingRadius(void) const - { - return mRadius; - } - //----------------------------------------------------------------------- - const AxisAlignedBox& BillboardChain::getBoundingBox(void) const - { - updateBoundingBox(); - return mAABB; - } - //----------------------------------------------------------------------- - const MaterialPtr& BillboardChain::getMaterial(void) const - { - return mMaterial; - } - //----------------------------------------------------------------------- - void BillboardChain::setMaterialName( const String& name, const String& groupName /* = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME */) - { - mMaterialName = name; - mMaterial = MaterialManager::getSingleton().getByName(mMaterialName, groupName); - - if (mMaterial.isNull()) - { - LogManager::getSingleton().logMessage("Can't assign material " + name + - " to BillboardChain " + mName + " because this " - "Material does not exist. Have you forgotten to define it in a " - ".material script?", LML_CRITICAL); - mMaterial = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting"); - if (mMaterial.isNull()) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Can't assign default material " - "to BillboardChain of " + mName + ". Did " - "you forget to call MaterialManager::initialise()?", - "BillboardChain.setMaterialName"); - } - } - // Ensure new material loaded (will not load again if already loaded) - mMaterial->load(); - } - //----------------------------------------------------------------------- - const String& BillboardChain::getMovableType(void) const - { - return BillboardChainFactory::FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------- - void BillboardChain::_updateRenderQueue(RenderQueue* queue) - { - updateIndexBuffer(); - - if (mIndexData->indexCount > 0) - { - if (mRenderQueuePrioritySet) - queue->addRenderable(this, mRenderQueueID, mRenderQueuePriority); - else if (mRenderQueueIDSet) + } + //----------------------------------------------------------------------- + void BillboardChain::updateIndexBuffer(void) + { + + setupBuffers(); + if (mIndexContentDirty) + { + + uint16* pShort = static_cast( + mIndexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + mIndexData->indexCount = 0; + // indexes + for (ChainSegmentList::iterator segi = mChainSegmentList.begin(); + segi != mChainSegmentList.end(); ++segi) + { + ChainSegment& seg = *segi; + + // Skip 0 or 1 element segment counts + if (seg.head != SEGMENT_EMPTY && seg.head != seg.tail) + { + // Start from head + 1 since it's only useful in pairs + size_t laste = seg.head; + while(1) // until break + { + size_t e = laste + 1; + // Wrap forwards + if (e == mMaxElementsPerChain) + e = 0; + // indexes of this element are (e * 2) and (e * 2) + 1 + // indexes of the last element are the same, -2 + assert (((e + seg.start) * 2) < 65536 && "Too many elements!"); + uint16 baseIdx = static_cast((e + seg.start) * 2); + uint16 lastBaseIdx = static_cast((laste + seg.start) * 2); + *pShort++ = lastBaseIdx; + *pShort++ = lastBaseIdx + 1; + *pShort++ = baseIdx; + *pShort++ = lastBaseIdx + 1; + *pShort++ = baseIdx + 1; + *pShort++ = baseIdx; + + mIndexData->indexCount += 6; + + + if (e == seg.tail) + break; // last one + + laste = e; + + } + } + + } + mIndexData->indexBuffer->unlock(); + + mIndexContentDirty = false; + } + + } + //----------------------------------------------------------------------- + Real BillboardChain::getSquaredViewDepth(const Camera* cam) const + { + Vector3 min, max, mid, dist; + min = mAABB.getMinimum(); + max = mAABB.getMaximum(); + mid = ((max - min) * 0.5) + min; + dist = cam->getDerivedPosition() - mid; + + return dist.squaredLength(); + } + //----------------------------------------------------------------------- + Real BillboardChain::getBoundingRadius(void) const + { + return mRadius; + } + //----------------------------------------------------------------------- + const AxisAlignedBox& BillboardChain::getBoundingBox(void) const + { + updateBoundingBox(); + return mAABB; + } + //----------------------------------------------------------------------- + const MaterialPtr& BillboardChain::getMaterial(void) const + { + return mMaterial; + } + //----------------------------------------------------------------------- + void BillboardChain::setMaterialName( const String& name, const String& groupName /* = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME */) + { + mMaterialName = name; + mMaterial = MaterialManager::getSingleton().getByName(mMaterialName, groupName); + + if (mMaterial.isNull()) + { + LogManager::getSingleton().logMessage("Can't assign material " + name + + " to BillboardChain " + mName + " because this " + "Material does not exist. Have you forgotten to define it in a " + ".material script?", LML_CRITICAL); + mMaterial = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting"); + if (mMaterial.isNull()) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Can't assign default material " + "to BillboardChain of " + mName + ". Did " + "you forget to call MaterialManager::initialise()?", + "BillboardChain.setMaterialName"); + } + } + // Ensure new material loaded (will not load again if already loaded) + mMaterial->load(); + } + //----------------------------------------------------------------------- + const String& BillboardChain::getMovableType(void) const + { + return BillboardChainFactory::FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------- + void BillboardChain::_updateRenderQueue(RenderQueue* queue) + { + updateIndexBuffer(); + + if (mIndexData->indexCount > 0) + { + if (mRenderQueuePrioritySet) + queue->addRenderable(this, mRenderQueueID, mRenderQueuePriority); + else if (mRenderQueueIDSet) queue->addRenderable(this, mRenderQueueID); else queue->addRenderable(this); - } - - } - //----------------------------------------------------------------------- - void BillboardChain::getRenderOperation(RenderOperation& op) - { - op.indexData = mIndexData; - op.operationType = RenderOperation::OT_TRIANGLE_LIST; - op.srcRenderable = this; - op.useIndexes = true; - op.vertexData = mVertexData; - } - //----------------------------------------------------------------------- + } + + } + //----------------------------------------------------------------------- + void BillboardChain::getRenderOperation(RenderOperation& op) + { + op.indexData = mIndexData; + op.operationType = RenderOperation::OT_TRIANGLE_LIST; + op.srcRenderable = this; + op.useIndexes = true; + op.vertexData = mVertexData; + } + //----------------------------------------------------------------------- bool BillboardChain::preRender(SceneManager* sm, RenderSystem* rsys) { // Retrieve the current viewport from the scene manager. @@ -790,79 +790,79 @@ namespace Ogre { updateVertexBuffer(currentViewport->getCamera()); return true; } - //----------------------------------------------------------------------- - void BillboardChain::getWorldTransforms(Matrix4* xform) const - { - *xform = _getParentNodeFullTransform(); - } - //----------------------------------------------------------------------- - const LightList& BillboardChain::getLights(void) const - { - return queryLights(); - } - //--------------------------------------------------------------------- - void BillboardChain::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - // only one renderable - visitor->visit(this, 0, false); - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - String BillboardChainFactory::FACTORY_TYPE_NAME = "BillboardChain"; - //----------------------------------------------------------------------- - const String& BillboardChainFactory::getType(void) const - { - return FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------- - MovableObject* BillboardChainFactory::createInstanceImpl( const String& name, - const NameValuePairList* params) - { - size_t maxElements = 20; - size_t numberOfChains = 1; - bool useTex = true; - bool useCol = true; - bool dynamic = true; - // optional params - if (params != 0) - { - NameValuePairList::const_iterator ni = params->find("maxElements"); - if (ni != params->end()) - { - maxElements = StringConverter::parseUnsignedLong(ni->second); - } - ni = params->find("numberOfChains"); - if (ni != params->end()) - { - numberOfChains = StringConverter::parseUnsignedLong(ni->second); - } - ni = params->find("useTextureCoords"); - if (ni != params->end()) - { - useTex = StringConverter::parseBool(ni->second); - } - ni = params->find("useVertexColours"); - if (ni != params->end()) - { - useCol = StringConverter::parseBool(ni->second); - } - ni = params->find("dynamic"); - if (ni != params->end()) - { - dynamic = StringConverter::parseBool(ni->second); - } - - } - - return OGRE_NEW BillboardChain(name, maxElements, numberOfChains, useTex, useCol, dynamic); - - } - //----------------------------------------------------------------------- - void BillboardChainFactory::destroyInstance( MovableObject* obj) - { - OGRE_DELETE obj; - } + //----------------------------------------------------------------------- + void BillboardChain::getWorldTransforms(Matrix4* xform) const + { + *xform = _getParentNodeFullTransform(); + } + //----------------------------------------------------------------------- + const LightList& BillboardChain::getLights(void) const + { + return queryLights(); + } + //--------------------------------------------------------------------- + void BillboardChain::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + // only one renderable + visitor->visit(this, 0, false); + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + String BillboardChainFactory::FACTORY_TYPE_NAME = "BillboardChain"; + //----------------------------------------------------------------------- + const String& BillboardChainFactory::getType(void) const + { + return FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------- + MovableObject* BillboardChainFactory::createInstanceImpl( const String& name, + const NameValuePairList* params) + { + size_t maxElements = 20; + size_t numberOfChains = 1; + bool useTex = true; + bool useCol = true; + bool dynamic = true; + // optional params + if (params != 0) + { + NameValuePairList::const_iterator ni = params->find("maxElements"); + if (ni != params->end()) + { + maxElements = StringConverter::parseUnsignedLong(ni->second); + } + ni = params->find("numberOfChains"); + if (ni != params->end()) + { + numberOfChains = StringConverter::parseUnsignedLong(ni->second); + } + ni = params->find("useTextureCoords"); + if (ni != params->end()) + { + useTex = StringConverter::parseBool(ni->second); + } + ni = params->find("useVertexColours"); + if (ni != params->end()) + { + useCol = StringConverter::parseBool(ni->second); + } + ni = params->find("dynamic"); + if (ni != params->end()) + { + dynamic = StringConverter::parseBool(ni->second); + } + + } + + return OGRE_NEW BillboardChain(name, maxElements, numberOfChains, useTex, useCol, dynamic); + + } + //----------------------------------------------------------------------- + void BillboardChainFactory::destroyInstance( MovableObject* obj) + { + OGRE_DELETE obj; + } } diff --git a/OgreMain/src/OgreBillboardParticleRenderer.cpp b/OgreMain/src/OgreBillboardParticleRenderer.cpp index eae5084a693..2ffbbddaa6f 100644 --- a/OgreMain/src/OgreBillboardParticleRenderer.cpp +++ b/OgreMain/src/OgreBillboardParticleRenderer.cpp @@ -43,7 +43,7 @@ namespace Ogre { BillboardParticleRenderer::CmdCommonDirection BillboardParticleRenderer::msCommonDirectionCmd; BillboardParticleRenderer::CmdCommonUpVector BillboardParticleRenderer::msCommonUpVectorCmd; BillboardParticleRenderer::CmdPointRendering BillboardParticleRenderer::msPointRenderingCmd; - BillboardParticleRenderer::CmdAccurateFacing BillboardParticleRenderer::msAccurateFacingCmd; + BillboardParticleRenderer::CmdAccurateFacing BillboardParticleRenderer::msAccurateFacingCmd; //----------------------------------------------------------------------- BillboardParticleRenderer::BillboardParticleRenderer() { @@ -68,41 +68,41 @@ namespace Ogre { dict->addParameter(ParameterDef("billboard_rotation_type", "This setting controls the billboard rotation type. " - "'vertex' means rotate the billboard's vertices around their facing direction." + "'vertex' means rotate the billboard's vertices around their facing direction." "'texcoord' means rotate the billboard's texture coordinates. Default value is 'texcoord'.", PT_STRING), &msBillboardRotationTypeCmd); dict->addParameter(ParameterDef("common_direction", "Only useful when billboard_type is oriented_common or perpendicular_common. " - "When billboard_type is oriented_common, this parameter sets the common orientation for " - "all particles in the set (e.g. raindrops may all be oriented downwards). " - "When billboard_type is perpendicular_common, this parameter sets the perpendicular vector for " - "all particles in the set (e.g. an aureola around the player and parallel to the ground).", + "When billboard_type is oriented_common, this parameter sets the common orientation for " + "all particles in the set (e.g. raindrops may all be oriented downwards). " + "When billboard_type is perpendicular_common, this parameter sets the perpendicular vector for " + "all particles in the set (e.g. an aureola around the player and parallel to the ground).", PT_VECTOR3), &msCommonDirectionCmd); dict->addParameter(ParameterDef("common_up_vector", "Only useful when billboard_type is perpendicular_self or perpendicular_common. This " - "parameter sets the common up-vector for all particles in the set (e.g. an aureola around " - "the player and parallel to the ground).", + "parameter sets the common up-vector for all particles in the set (e.g. an aureola around " + "the player and parallel to the ground).", PT_VECTOR3), &msCommonUpVectorCmd); dict->addParameter(ParameterDef("point_rendering", "Set whether or not particles will use point rendering " - "rather than manually generated quads. This allows for faster " - "rendering of point-oriented particles although introduces some " - "limitations too such as requiring a common particle size." - "Possible values are 'true' or 'false'.", + "rather than manually generated quads. This allows for faster " + "rendering of point-oriented particles although introduces some " + "limitations too such as requiring a common particle size." + "Possible values are 'true' or 'false'.", PT_BOOL), &msPointRenderingCmd); - dict->addParameter(ParameterDef("accurate_facing", - "Set whether or not particles will be oriented to the camera " - "based on the relative position to the camera rather than just " - "the camera direction. This is more accurate but less optimal. " - "Cannot be combined with point rendering.", - PT_BOOL), - &msAccurateFacingCmd); + dict->addParameter(ParameterDef("accurate_facing", + "Set whether or not particles will be oriented to the camera " + "based on the relative position to the camera rather than just " + "the camera direction. This is more accurate but less optimal. " + "Cannot be combined with point rendering.", + PT_BOOL), + &msAccurateFacingCmd); } // Create billboard set @@ -113,10 +113,10 @@ namespace Ogre { //----------------------------------------------------------------------- BillboardParticleRenderer::~BillboardParticleRenderer() { - // mBillboardSet is never actually attached to a node, we just passthrough - // based on the particle system's attachment. So manually notify that it's - // no longer attached. - mBillboardSet->_notifyAttached(0); + // mBillboardSet is never actually attached to a node, we just passthrough + // based on the particle system's attachment. So manually notify that it's + // no longer attached. + mBillboardSet->_notifyAttached(0); OGRE_DELETE mBillboardSet; } //----------------------------------------------------------------------- @@ -156,12 +156,12 @@ namespace Ogre { radius = std::max( radius, p->mPosition.length() ); if (mBillboardSet->getBillboardType() == BBT_ORIENTED_SELF || - mBillboardSet->getBillboardType() == BBT_PERPENDICULAR_SELF) - { - // Normalise direction vector - bb.mDirection = p->mDirection; - bb.mDirection.normalise(); - } + mBillboardSet->getBillboardType() == BBT_PERPENDICULAR_SELF) + { + // Normalise direction vector + bb.mDirection = p->mDirection; + bb.mDirection.normalise(); + } bb.mColour = p->mColour; bb.mRotation = p->mRotation; // Assign and compare at the same time @@ -183,12 +183,12 @@ namespace Ogre { // Update the queue mBillboardSet->_updateRenderQueue(queue); } - //--------------------------------------------------------------------- - void BillboardParticleRenderer::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - mBillboardSet->visitRenderables(visitor, debugRenderables); - } + //--------------------------------------------------------------------- + void BillboardParticleRenderer::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + mBillboardSet->visitRenderables(visitor, debugRenderables); + } //----------------------------------------------------------------------- void BillboardParticleRenderer::_setMaterial(MaterialPtr& mat) { @@ -199,16 +199,16 @@ namespace Ogre { { mBillboardSet->setBillboardType(bbt); } - //----------------------------------------------------------------------- - void BillboardParticleRenderer::setUseAccurateFacing(bool acc) - { - mBillboardSet->setUseAccurateFacing(acc); - } - //----------------------------------------------------------------------- - bool BillboardParticleRenderer::getUseAccurateFacing(void) const - { - return mBillboardSet->getUseAccurateFacing(); - } + //----------------------------------------------------------------------- + void BillboardParticleRenderer::setUseAccurateFacing(bool acc) + { + mBillboardSet->setUseAccurateFacing(acc); + } + //----------------------------------------------------------------------- + bool BillboardParticleRenderer::getUseAccurateFacing(void) const + { + return mBillboardSet->getUseAccurateFacing(); + } //----------------------------------------------------------------------- BillboardType BillboardParticleRenderer::getBillboardType(void) const { @@ -274,38 +274,38 @@ namespace Ogre { { mBillboardSet->_notifyAttached(parent, isTagPoint); } - //----------------------------------------------------------------------- - void BillboardParticleRenderer::setRenderQueueGroup(uint8 queueID) - { - assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!"); - mBillboardSet->setRenderQueueGroup(queueID); - } - //----------------------------------------------------------------------- - void BillboardParticleRenderer::setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) - { - assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!"); - mBillboardSet->setRenderQueueGroupAndPriority(queueID, priority); - } - //----------------------------------------------------------------------- - void BillboardParticleRenderer::setKeepParticlesInLocalSpace(bool keepLocal) - { - mBillboardSet->setBillboardsInWorldSpace(!keepLocal); - } + //----------------------------------------------------------------------- + void BillboardParticleRenderer::setRenderQueueGroup(uint8 queueID) + { + assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!"); + mBillboardSet->setRenderQueueGroup(queueID); + } + //----------------------------------------------------------------------- + void BillboardParticleRenderer::setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) + { + assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!"); + mBillboardSet->setRenderQueueGroupAndPriority(queueID, priority); + } + //----------------------------------------------------------------------- + void BillboardParticleRenderer::setKeepParticlesInLocalSpace(bool keepLocal) + { + mBillboardSet->setBillboardsInWorldSpace(!keepLocal); + } //----------------------------------------------------------------------- SortMode BillboardParticleRenderer::_getSortMode(void) const { return mBillboardSet->_getSortMode(); } - //----------------------------------------------------------------------- - void BillboardParticleRenderer::setPointRenderingEnabled(bool enabled) - { - mBillboardSet->setPointRenderingEnabled(enabled); - } - //----------------------------------------------------------------------- - bool BillboardParticleRenderer::isPointRenderingEnabled(void) const - { - return mBillboardSet->isPointRenderingEnabled(); - } + //----------------------------------------------------------------------- + void BillboardParticleRenderer::setPointRenderingEnabled(bool enabled) + { + mBillboardSet->setPointRenderingEnabled(enabled); + } + //----------------------------------------------------------------------- + bool BillboardParticleRenderer::isPointRenderingEnabled(void) const + { + return mBillboardSet->isPointRenderingEnabled(); + } //----------------------------------------------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- @@ -502,17 +502,17 @@ namespace Ogre { static_cast(target)->setPointRenderingEnabled( StringConverter::parseBool(val)); } - //----------------------------------------------------------------------- - String BillboardParticleRenderer::CmdAccurateFacing::doGet(const void* target) const - { - return StringConverter::toString( - static_cast(target)->getUseAccurateFacing() ); - } - void BillboardParticleRenderer::CmdAccurateFacing::doSet(void* target, const String& val) - { - static_cast(target)->setUseAccurateFacing( - StringConverter::parseBool(val)); - } + //----------------------------------------------------------------------- + String BillboardParticleRenderer::CmdAccurateFacing::doGet(const void* target) const + { + return StringConverter::toString( + static_cast(target)->getUseAccurateFacing() ); + } + void BillboardParticleRenderer::CmdAccurateFacing::doSet(void* target, const String& val) + { + static_cast(target)->setUseAccurateFacing( + StringConverter::parseBool(val)); + } } diff --git a/OgreMain/src/OgreBillboardSet.cpp b/OgreMain/src/OgreBillboardSet.cpp index bdf5f952141..a0e8ecd386f 100644 --- a/OgreMain/src/OgreBillboardSet.cpp +++ b/OgreMain/src/OgreBillboardSet.cpp @@ -48,7 +48,7 @@ namespace Ogre { //----------------------------------------------------------------------- BillboardSet::BillboardSet() : - mBoundingRadius(0.0f), + mBoundingRadius(0.0f), mOriginType( BBO_CENTER ), mRotationType( BBR_TEXCOORD ), mAllDefaultSize( true ), @@ -66,9 +66,9 @@ namespace Ogre { mPointRendering(false), mBuffersCreated(false), mPoolSize(0), - mExternalData(false), - mAutoUpdate(true), - mBillboardDataChanged(true) + mExternalData(false), + mAutoUpdate(true), + mBillboardDataChanged(true) { setDefaultDimensions( 100, 100 ); setMaterialName( "BaseWhite" ); @@ -82,7 +82,7 @@ namespace Ogre { unsigned int poolSize, bool externalData) : MovableObject(name), - mBoundingRadius(0.0f), + mBoundingRadius(0.0f), mOriginType( BBO_CENTER ), mRotationType( BBR_TEXCOORD ), mAllDefaultSize( true ), @@ -97,12 +97,12 @@ namespace Ogre { mBillboardType(BBT_POINT), mCommonDirection(Ogre::Vector3::UNIT_Z), mCommonUpVector(Vector3::UNIT_Y), - mPointRendering(false), + mPointRendering(false), mBuffersCreated(false), mPoolSize(poolSize), mExternalData(externalData), - mAutoUpdate(true), - mBillboardDataChanged(true) + mAutoUpdate(true), + mBillboardDataChanged(true) { setDefaultDimensions( 100, 100 ); setMaterialName( "BaseWhite" ); @@ -121,7 +121,7 @@ namespace Ogre { } // Delete shared buffers - _destroyBuffers(); + _destroyBuffers(); } //----------------------------------------------------------------------- Billboard* BillboardSet::createBillboard( @@ -142,8 +142,8 @@ namespace Ogre { // Get a new billboard Billboard* newBill = mFreeBillboards.front(); - mActiveBillboards.splice( - mActiveBillboards.end(), mFreeBillboards, mFreeBillboards.begin()); + mActiveBillboards.splice( + mActiveBillboards.end(), mFreeBillboards, mFreeBillboards.begin()); newBill->setPosition(position); newBill->setColour(colour); newBill->mDirection = Vector3::ZERO; @@ -152,16 +152,16 @@ namespace Ogre { newBill->resetDimensions(); newBill->_notifyOwner(this); - // Merge into bounds - Real adjust = std::max(mDefaultWidth, mDefaultHeight); + // Merge into bounds + Real adjust = std::max(mDefaultWidth, mDefaultHeight); Vector3 vecAdjust(adjust, adjust, adjust); - Vector3 newMin = position - vecAdjust; - Vector3 newMax = position + vecAdjust; + Vector3 newMin = position - vecAdjust; + Vector3 newMax = position + vecAdjust; mAABB.merge(newMin); mAABB.merge(newMax); - mBoundingRadius = Math::boundingRadiusFromAABB(mAABB); + mBoundingRadius = Math::boundingRadiusFromAABB(mAABB); return newBill; } @@ -183,8 +183,8 @@ namespace Ogre { //----------------------------------------------------------------------- void BillboardSet::clear() { - // Move actives to free list - mFreeBillboards.splice(mFreeBillboards.end(), mActiveBillboards); + // Move actives to free list + mFreeBillboards.splice(mFreeBillboards.end(), mActiveBillboards); } //----------------------------------------------------------------------- @@ -201,7 +201,7 @@ namespace Ogre { ActiveBillboardList::const_iterator it; if( index >= ( mActiveBillboards.size() >> 1 ) ) { - index = static_cast(mActiveBillboards.size()) - index; + index = static_cast(mActiveBillboards.size()) - index; for( it = mActiveBillboards.end(); index; --index, --it ); } else @@ -228,7 +228,7 @@ namespace Ogre { ActiveBillboardList::iterator it; if( index >= ( mActiveBillboards.size() >> 1 ) ) { - index = static_cast(mActiveBillboards.size()) - index; + index = static_cast(mActiveBillboards.size()) - index; for( it = mActiveBillboards.end(); index; --index, --it ); } else @@ -306,9 +306,9 @@ namespace Ogre { mMaterial = MaterialManager::getSingleton().getByName(name, groupName); - if (mMaterial.isNull()) - OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + name, - "BillboardSet::setMaterialName" ); + if (mMaterial.isNull()) + OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + name, + "BillboardSet::setMaterialName" ); /* Ensure that the new material was loaded (will not load again if already loaded anyway) @@ -370,7 +370,7 @@ namespace Ogre { //----------------------------------------------------------------------- void BillboardSet::_notifyCurrentCamera( Camera* cam ) { - MovableObject::_notifyCurrentCamera(cam); + MovableObject::_notifyCurrentCamera(cam); mCurrentCamera = cam; @@ -417,76 +417,76 @@ namespace Ogre { if(!mBuffersCreated) _createBuffers(); - // Only calculate vertex offets et al if we're not point rendering - if (!mPointRendering) - { + // Only calculate vertex offets et al if we're not point rendering + if (!mPointRendering) + { - // Get offsets for origin type - getParametricOffsets(mLeftOff, mRightOff, mTopOff, mBottomOff); + // Get offsets for origin type + getParametricOffsets(mLeftOff, mRightOff, mTopOff, mBottomOff); - // Generate axes etc up-front if not oriented per-billboard - if (mBillboardType != BBT_ORIENTED_SELF && - mBillboardType != BBT_PERPENDICULAR_SELF && - !(mAccurateFacing && mBillboardType != BBT_PERPENDICULAR_COMMON)) - { - genBillboardAxes(&mCamX, &mCamY); + // Generate axes etc up-front if not oriented per-billboard + if (mBillboardType != BBT_ORIENTED_SELF && + mBillboardType != BBT_PERPENDICULAR_SELF && + !(mAccurateFacing && mBillboardType != BBT_PERPENDICULAR_COMMON)) + { + genBillboardAxes(&mCamX, &mCamY); - /* If all billboards are the same size we can precalculate the - offsets and just use '+' instead of '*' for each billboard, - and it should be faster. - */ - genVertOffsets(mLeftOff, mRightOff, mTopOff, mBottomOff, - mDefaultWidth, mDefaultHeight, mCamX, mCamY, mVOffset); + /* If all billboards are the same size we can precalculate the + offsets and just use '+' instead of '*' for each billboard, + and it should be faster. + */ + genVertOffsets(mLeftOff, mRightOff, mTopOff, mBottomOff, + mDefaultWidth, mDefaultHeight, mCamX, mCamY, mVOffset); - } - } + } + } // Init num visible mNumVisibleBillboards = 0; // Lock the buffer - if (numBillboards) // optimal lock - { - // clamp to max - numBillboards = std::min(mPoolSize, numBillboards); - - size_t billboardSize; - if (mPointRendering) - { - // just one vertex per billboard (this also excludes texcoords) - billboardSize = mMainBuf->getVertexSize(); - } - else - { - // 4 corners - billboardSize = mMainBuf->getVertexSize() * 4; - } - assert (numBillboards * billboardSize <= mMainBuf->getSizeInBytes()); - - mLockPtr = static_cast( - mMainBuf->lock(0, numBillboards * billboardSize, - mMainBuf->getUsage() & HardwareBuffer::HBU_DYNAMIC ? - HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL, - mAutoUpdate ? Root::getSingleton().getFreqUpdatedBuffersUploadOption() : HardwareBuffer::HBU_DEFAULT) ); - } - else // lock the entire thing - mLockPtr = static_cast( - mMainBuf->lock(mMainBuf->getUsage() & HardwareBuffer::HBU_DYNAMIC ? - HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL, - mAutoUpdate ? Root::getSingleton().getFreqUpdatedBuffersUploadOption() : HardwareBuffer::HBU_DEFAULT) ); + if (numBillboards) // optimal lock + { + // clamp to max + numBillboards = std::min(mPoolSize, numBillboards); + + size_t billboardSize; + if (mPointRendering) + { + // just one vertex per billboard (this also excludes texcoords) + billboardSize = mMainBuf->getVertexSize(); + } + else + { + // 4 corners + billboardSize = mMainBuf->getVertexSize() * 4; + } + assert (numBillboards * billboardSize <= mMainBuf->getSizeInBytes()); + + mLockPtr = static_cast( + mMainBuf->lock(0, numBillboards * billboardSize, + mMainBuf->getUsage() & HardwareBuffer::HBU_DYNAMIC ? + HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL, + mAutoUpdate ? Root::getSingleton().getFreqUpdatedBuffersUploadOption() : HardwareBuffer::HBU_DEFAULT) ); + } + else // lock the entire thing + mLockPtr = static_cast( + mMainBuf->lock(mMainBuf->getUsage() & HardwareBuffer::HBU_DYNAMIC ? + HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL, + mAutoUpdate ? Root::getSingleton().getFreqUpdatedBuffersUploadOption() : HardwareBuffer::HBU_DEFAULT) ); } //----------------------------------------------------------------------- void BillboardSet::injectBillboard(const Billboard& bb) { - // Don't accept injections beyond pool size - if (mNumVisibleBillboards == mPoolSize) return; + // Don't accept injections beyond pool size + if (mNumVisibleBillboards == mPoolSize) return; - // Skip if not visible (NB always true if not bounds checking individual billboards) + // Skip if not visible (NB always true if not bounds checking individual billboards) if (!billboardVisible(mCurrentCamera, bb)) return; if (!mPointRendering && - (mBillboardType == BBT_ORIENTED_SELF || + (mBillboardType == BBT_ORIENTED_SELF || mBillboardType == BBT_PERPENDICULAR_SELF || (mAccurateFacing && mBillboardType != BBT_PERPENDICULAR_COMMON))) { @@ -494,7 +494,7 @@ namespace Ogre { genBillboardAxes(&mCamX, &mCamY, &bb); } - // If they're all the same size or we're point rendering + // If they're all the same size or we're point rendering if( mAllDefaultSize || mPointRendering) { /* No per-billboard checking, just blast through. @@ -503,9 +503,9 @@ namespace Ogre { */ if (!mPointRendering && - (mBillboardType == BBT_ORIENTED_SELF || - mBillboardType == BBT_PERPENDICULAR_SELF || - (mAccurateFacing && mBillboardType != BBT_PERPENDICULAR_COMMON))) + (mBillboardType == BBT_ORIENTED_SELF || + mBillboardType == BBT_PERPENDICULAR_SELF || + (mAccurateFacing && mBillboardType != BBT_PERPENDICULAR_COMMON))) { genVertOffsets(mLeftOff, mRightOff, mTopOff, mBottomOff, mDefaultWidth, mDefaultHeight, mCamX, mCamY, mVOffset); @@ -540,12 +540,12 @@ namespace Ogre { { mMainBuf->unlock(); } - //----------------------------------------------------------------------- - void BillboardSet::setBounds(const AxisAlignedBox& box, Real radius) - { - mAABB = box; - mBoundingRadius = radius; - } + //----------------------------------------------------------------------- + void BillboardSet::setBounds(const AxisAlignedBox& box, Real radius) + { + mAABB = box; + mBoundingRadius = radius; + } //----------------------------------------------------------------------- void BillboardSet::_updateBounds(void) { @@ -553,31 +553,31 @@ namespace Ogre { { // No billboards, null bbox mAABB.setNull(); - mBoundingRadius = 0.0f; + mBoundingRadius = 0.0f; } else { - Real maxSqLen = -1.0f; + Real maxSqLen = -1.0f; Vector3 min(Math::POS_INFINITY, Math::POS_INFINITY, Math::POS_INFINITY); Vector3 max(Math::NEG_INFINITY, Math::NEG_INFINITY, Math::NEG_INFINITY); ActiveBillboardList::iterator i, iend; iend = mActiveBillboards.end(); - Matrix4 invWorld; - if (mWorldSpace && getParentSceneNode()) - invWorld = getParentSceneNode()->_getFullTransform().inverse(); + Matrix4 invWorld; + if (mWorldSpace && getParentSceneNode()) + invWorld = getParentSceneNode()->_getFullTransform().inverse(); for (i = mActiveBillboards.begin(); i != iend; ++i) { Vector3 pos = (*i)->getPosition(); - // transform from world space to local space - if (mWorldSpace && getParentSceneNode()) - pos = invWorld * pos; + // transform from world space to local space + if (mWorldSpace && getParentSceneNode()) + pos = invWorld * pos; min.makeFloor(pos); max.makeCeil(pos); - maxSqLen = std::max(maxSqLen, pos.squaredLength()); + maxSqLen = std::max(maxSqLen, pos.squaredLength()); } // Adjust for billboard size Real adjust = std::max(mDefaultWidth, mDefaultHeight); @@ -586,7 +586,7 @@ namespace Ogre { max += vecAdjust; mAABB.setExtents(min, max); - mBoundingRadius = Math::Sqrt(maxSqLen); + mBoundingRadius = Math::Sqrt(maxSqLen); } @@ -620,15 +620,15 @@ namespace Ogre { injectBillboard(*(*it)); } endBillboards(); - mBillboardDataChanged = false; + mBillboardDataChanged = false; } //only set the render queue group if it has been explicitly set. - if (mRenderQueuePrioritySet) - { - assert(mRenderQueueIDSet == true); - queue->addRenderable(this, mRenderQueueID, mRenderQueuePriority); - } + if (mRenderQueuePrioritySet) + { + assert(mRenderQueueIDSet == true); + queue->addRenderable(this, mRenderQueueID, mRenderQueuePriority); + } else if( mRenderQueueIDSet ) { queue->addRenderable(this, mRenderQueueID); @@ -645,18 +645,18 @@ namespace Ogre { } void BillboardSet::setMaterial( const MaterialPtr& material ) - { - mMaterial = material; - + { + mMaterial = material; + if (mMaterial.isNull()) { - LogManager::getSingleton().logMessage("Can't assign material " + LogManager::getSingleton().logMessage("Can't assign material " " to BillboardSet of " + getName() + " because this " "Material does not exist. Have you forgotten to define it in a " ".material script?", LML_CRITICAL); - - mMaterial = MaterialManager::getSingleton().getByName("BaseWhite"); - + + mMaterial = MaterialManager::getSingleton().getByName("BaseWhite"); + if (mMaterial.isNull()) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Can't assign default material " @@ -665,38 +665,38 @@ namespace Ogre { "BillboardSet::setMaterial"); } } - - mMaterialName = mMaterial->getName(); + + mMaterialName = mMaterial->getName(); // Ensure new material loaded (will not load again if already loaded) mMaterial->load(); - } + } //----------------------------------------------------------------------- void BillboardSet::getRenderOperation(RenderOperation& op) { op.vertexData = mVertexData; - op.vertexData->vertexStart = 0; + op.vertexData->vertexStart = 0; - if (mPointRendering) - { - op.operationType = RenderOperation::OT_POINT_LIST; - op.useIndexes = false; + if (mPointRendering) + { + op.operationType = RenderOperation::OT_POINT_LIST; + op.useIndexes = false; op.useGlobalInstancingVertexBufferIsAvailable = false; - op.indexData = 0; - op.vertexData->vertexCount = mNumVisibleBillboards; - } - else - { - op.operationType = RenderOperation::OT_TRIANGLE_LIST; - op.useIndexes = true; + op.indexData = 0; + op.vertexData->vertexCount = mNumVisibleBillboards; + } + else + { + op.operationType = RenderOperation::OT_TRIANGLE_LIST; + op.useIndexes = true; - op.vertexData->vertexCount = mNumVisibleBillboards * 4; + op.vertexData->vertexCount = mNumVisibleBillboards * 4; - op.indexData = mIndexData; - op.indexData->indexCount = mNumVisibleBillboards * 6; - op.indexData->indexStart = 0; - } + op.indexData = mIndexData; + op.indexData->indexCount = mNumVisibleBillboards * 6; + op.indexData->indexStart = 0; + } } //----------------------------------------------------------------------- @@ -758,7 +758,7 @@ namespace Ogre { mPoolSize = size; - _destroyBuffers(); + _destroyBuffers(); } //----------------------------------------------------------------------- @@ -775,22 +775,22 @@ namespace Ogre { tex. coords ( 2D coords, 1 or 4 per billboard ) */ - // Warn if user requested an invalid setup - // Do it here so it only appears once - if (mPointRendering && mBillboardType != BBT_POINT) - { + // Warn if user requested an invalid setup + // Do it here so it only appears once + if (mPointRendering && mBillboardType != BBT_POINT) + { - LogManager::getSingleton().logMessage("Warning: BillboardSet " + - mName + " has point rendering enabled but is using a type " - "other than BBT_POINT, this may not give you the results you " - "expect.", LML_CRITICAL); - } + LogManager::getSingleton().logMessage("Warning: BillboardSet " + + mName + " has point rendering enabled but is using a type " + "other than BBT_POINT, this may not give you the results you " + "expect.", LML_CRITICAL); + } mVertexData = OGRE_NEW VertexData(); - if (mPointRendering) - mVertexData->vertexCount = mPoolSize; - else - mVertexData->vertexCount = mPoolSize * 4; + if (mPointRendering) + mVertexData->vertexCount = mPoolSize; + else + mVertexData->vertexCount = mPoolSize * 4; mVertexData->vertexStart = 0; @@ -814,64 +814,64 @@ namespace Ogre { HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(0), mVertexData->vertexCount, - mAutoUpdate ? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE : - HardwareBuffer::HBU_STATIC_WRITE_ONLY); + mAutoUpdate ? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE : + HardwareBuffer::HBU_STATIC_WRITE_ONLY); // bind position and diffuses binding->setBinding(0, mMainBuf); - if (!mPointRendering) - { - mIndexData = OGRE_NEW IndexData(); - mIndexData->indexStart = 0; - mIndexData->indexCount = mPoolSize * 6; - - mIndexData->indexBuffer = HardwareBufferManager::getSingleton(). - createIndexBuffer(HardwareIndexBuffer::IT_16BIT, - mIndexData->indexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - /* Create indexes (will be the same every frame) - Using indexes because it means 1/3 less vertex transforms (4 instead of 6) - - Billboard layout relative to camera: - - 0-----1 - | /| - | / | - |/ | - 2-----3 - */ - - ushort* pIdx = static_cast( - mIndexData->indexBuffer->lock(0, - mIndexData->indexBuffer->getSizeInBytes(), - HardwareBuffer::HBL_DISCARD) ); - - for( - size_t idx, idxOff, bboard = 0; - bboard < mPoolSize; - ++bboard ) - { - // Do indexes - idx = bboard * 6; - idxOff = bboard * 4; - - pIdx[idx] = static_cast(idxOff); // + 0;, for clarity - pIdx[idx+1] = static_cast(idxOff + 2); - pIdx[idx+2] = static_cast(idxOff + 1); - pIdx[idx+3] = static_cast(idxOff + 1); - pIdx[idx+4] = static_cast(idxOff + 2); - pIdx[idx+5] = static_cast(idxOff + 3); - - } - - mIndexData->indexBuffer->unlock(); - } + if (!mPointRendering) + { + mIndexData = OGRE_NEW IndexData(); + mIndexData->indexStart = 0; + mIndexData->indexCount = mPoolSize * 6; + + mIndexData->indexBuffer = HardwareBufferManager::getSingleton(). + createIndexBuffer(HardwareIndexBuffer::IT_16BIT, + mIndexData->indexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + + /* Create indexes (will be the same every frame) + Using indexes because it means 1/3 less vertex transforms (4 instead of 6) + + Billboard layout relative to camera: + + 0-----1 + | /| + | / | + |/ | + 2-----3 + */ + + ushort* pIdx = static_cast( + mIndexData->indexBuffer->lock(0, + mIndexData->indexBuffer->getSizeInBytes(), + HardwareBuffer::HBL_DISCARD) ); + + for( + size_t idx, idxOff, bboard = 0; + bboard < mPoolSize; + ++bboard ) + { + // Do indexes + idx = bboard * 6; + idxOff = bboard * 4; + + pIdx[idx] = static_cast(idxOff); // + 0;, for clarity + pIdx[idx+1] = static_cast(idxOff + 2); + pIdx[idx+2] = static_cast(idxOff + 1); + pIdx[idx+3] = static_cast(idxOff + 1); + pIdx[idx+4] = static_cast(idxOff + 2); + pIdx[idx+5] = static_cast(idxOff + 3); + + } + + mIndexData->indexBuffer->unlock(); + } mBuffersCreated = true; } //----------------------------------------------------------------------- - void BillboardSet::_destroyBuffers(void) - { + void BillboardSet::_destroyBuffers(void) + { if (mVertexData) { OGRE_DELETE mVertexData; @@ -885,9 +885,9 @@ namespace Ogre { mMainBuf.setNull(); - mBuffersCreated = false; + mBuffersCreated = false; - } + } //----------------------------------------------------------------------- unsigned int BillboardSet::getPoolSize(void) const { @@ -1125,28 +1125,28 @@ namespace Ogre { { return mCommonUpVector; } - //----------------------------------------------------------------------- - uint32 BillboardSet::getTypeFlags(void) const - { - return SceneManager::FX_TYPE_MASK; - } + //----------------------------------------------------------------------- + uint32 BillboardSet::getTypeFlags(void) const + { + return SceneManager::FX_TYPE_MASK; + } //----------------------------------------------------------------------- void BillboardSet::genVertices( const Vector3* const offsets, const Billboard& bb) { RGBA colour; Root::getSingleton().convertColourValue(bb.mColour, &colour); - RGBA* pCol; + RGBA* pCol; // Texcoords assert( bb.mUseTexcoordRect || bb.mTexcoordIndex < mTextureCoords.size() ); const Ogre::FloatRect & r = bb.mUseTexcoordRect ? bb.mTexcoordRect : mTextureCoords[bb.mTexcoordIndex]; - if (mPointRendering) - { - // Single vertex per billboard, ignore offsets - // position + if (mPointRendering) + { + // Single vertex per billboard, ignore offsets + // position *mLockPtr++ = bb.mPosition.x; *mLockPtr++ = bb.mPosition.y; *mLockPtr++ = bb.mPosition.z; @@ -1154,11 +1154,11 @@ namespace Ogre { // Convert float* to RGBA* pCol = static_cast(static_cast(mLockPtr)); *pCol++ = colour; - // Update lock pointer - mLockPtr = static_cast(static_cast(pCol)); + // Update lock pointer + mLockPtr = static_cast(static_cast(pCol)); // No texture coords in point rendering - } - else if (mAllDefaultRotation || bb.mRotation == Radian(0)) + } + else if (mAllDefaultRotation || bb.mRotation == Radian(0)) { // Left-top // Positions @@ -1226,7 +1226,7 @@ namespace Ogre { Vector3 axis = (offsets[3] - offsets[0]).crossProduct(offsets[2] - offsets[1]).normalisedCopy(); Matrix3 rotation; - rotation.FromAngleAxis(axis, bb.mRotation); + rotation.FromAngleAxis(axis, bb.mRotation); Vector3 pt; @@ -1396,7 +1396,7 @@ namespace Ogre { //----------------------------------------------------------------------- const String& BillboardSet::getMovableType(void) const { - return BillboardSetFactory::FACTORY_TYPE_NAME; + return BillboardSetFactory::FACTORY_TYPE_NAME; } //----------------------------------------------------------------------- Real BillboardSet::getSquaredViewDepth(const Camera* const cam) const @@ -1405,10 +1405,10 @@ namespace Ogre { return mParentNode->getSquaredViewDepth(cam); } //----------------------------------------------------------------------- - Real BillboardSet::getBoundingRadius(void) const - { - return mBoundingRadius; - } + Real BillboardSet::getBoundingRadius(void) const + { + return mBoundingRadius; + } //----------------------------------------------------------------------- const LightList& BillboardSet::getLights(void) const { @@ -1416,20 +1416,20 @@ namespace Ogre { // because most billboards are unlit, but here we go anyway return queryLights(); } - //--------------------------------------------------------------------- - void BillboardSet::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - // only one renderable - visitor->visit(this, 0, false); - } + //--------------------------------------------------------------------- + void BillboardSet::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + // only one renderable + visitor->visit(this, 0, false); + } void BillboardSet::setTextureCoords( Ogre::FloatRect const * coords, uint16 numCoords ) { if( !numCoords || !coords ) { setTextureStacksAndSlices( 1, 1 ); - return; + return; } // clear out any previous allocation (as vectors may not shrink) TextureCoordSets().swap( mTextureCoords ); @@ -1465,88 +1465,88 @@ namespace Ogre { } assert( coordIndex == (size_t)stacks * slices ); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- Ogre::FloatRect const * BillboardSet::getTextureCoords( uint16 * oNumCoords ) { *oNumCoords = (uint16)mTextureCoords.size(); // std::vector<> is guaranteed to be contiguous return &mTextureCoords.front(); } - //----------------------------------------------------------------------- - void BillboardSet::setPointRenderingEnabled(bool enabled) - { - // Override point rendering if not supported - if (enabled && !Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_POINT_SPRITES)) - { - enabled = false; - } - - if (enabled != mPointRendering) - { - mPointRendering = enabled; - // Different buffer structure (1 or 4 verts per billboard) - _destroyBuffers(); - } - } - - //----------------------------------------------------------------------- - void BillboardSet::setAutoUpdate(bool autoUpdate) - { - // Case auto update buffers changed we have to destroy the current buffers - // since their usage will be different. - if (autoUpdate != mAutoUpdate) - { - mAutoUpdate = autoUpdate; - _destroyBuffers(); - } - } - - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - String BillboardSetFactory::FACTORY_TYPE_NAME = "BillboardSet"; - //----------------------------------------------------------------------- - const String& BillboardSetFactory::getType(void) const - { - return FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------- - MovableObject* BillboardSetFactory::createInstanceImpl( const String& name, - const NameValuePairList* params) - { - // may have parameters - bool externalData = false; - unsigned int poolSize = 0; - - if (params != 0) - { - NameValuePairList::const_iterator ni = params->find("poolSize"); - if (ni != params->end()) - { - poolSize = StringConverter::parseUnsignedInt(ni->second); - } - ni = params->find("externalData"); - if (ni != params->end()) - { - externalData = StringConverter::parseBool(ni->second); - } - - } - - if (poolSize > 0) - { - return OGRE_NEW BillboardSet(name, poolSize, externalData); - } - else - { - return OGRE_NEW BillboardSet(name); - } - - } - //----------------------------------------------------------------------- - void BillboardSetFactory::destroyInstance( MovableObject* obj) - { - OGRE_DELETE obj; - } + //----------------------------------------------------------------------- + void BillboardSet::setPointRenderingEnabled(bool enabled) + { + // Override point rendering if not supported + if (enabled && !Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_POINT_SPRITES)) + { + enabled = false; + } + + if (enabled != mPointRendering) + { + mPointRendering = enabled; + // Different buffer structure (1 or 4 verts per billboard) + _destroyBuffers(); + } + } + + //----------------------------------------------------------------------- + void BillboardSet::setAutoUpdate(bool autoUpdate) + { + // Case auto update buffers changed we have to destroy the current buffers + // since their usage will be different. + if (autoUpdate != mAutoUpdate) + { + mAutoUpdate = autoUpdate; + _destroyBuffers(); + } + } + + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + String BillboardSetFactory::FACTORY_TYPE_NAME = "BillboardSet"; + //----------------------------------------------------------------------- + const String& BillboardSetFactory::getType(void) const + { + return FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------- + MovableObject* BillboardSetFactory::createInstanceImpl( const String& name, + const NameValuePairList* params) + { + // may have parameters + bool externalData = false; + unsigned int poolSize = 0; + + if (params != 0) + { + NameValuePairList::const_iterator ni = params->find("poolSize"); + if (ni != params->end()) + { + poolSize = StringConverter::parseUnsignedInt(ni->second); + } + ni = params->find("externalData"); + if (ni != params->end()) + { + externalData = StringConverter::parseBool(ni->second); + } + + } + + if (poolSize > 0) + { + return OGRE_NEW BillboardSet(name, poolSize, externalData); + } + else + { + return OGRE_NEW BillboardSet(name); + } + + } + //----------------------------------------------------------------------- + void BillboardSetFactory::destroyInstance( MovableObject* obj) + { + OGRE_DELETE obj; + } } diff --git a/OgreMain/src/OgreBone.cpp b/OgreMain/src/OgreBone.cpp index 9867a2745e8..3a11c1ee762 100644 --- a/OgreMain/src/OgreBone.cpp +++ b/OgreMain/src/OgreBone.cpp @@ -83,9 +83,9 @@ namespace Ogre { } //--------------------------------------------------------------------- void Bone::setManuallyControlled(bool manuallyControlled) - { + { mManuallyControlled = manuallyControlled; - mCreator->_notifyManualBoneStateChange(this); + mCreator->_notifyManualBoneStateChange(this); } //--------------------------------------------------------------------- bool Bone::isManuallyControlled() const { @@ -115,18 +115,18 @@ namespace Ogre { { return mHandle; } - //--------------------------------------------------------------------- - void Bone::needUpdate(bool forceParentUpdate) - { - Node::needUpdate(forceParentUpdate); - - if (isManuallyControlled()) - { - // Dirty the skeleton if manually controlled so animation can be updated - mCreator->_notifyManualBonesDirty(); - } - - } + //--------------------------------------------------------------------- + void Bone::needUpdate(bool forceParentUpdate) + { + Node::needUpdate(forceParentUpdate); + + if (isManuallyControlled()) + { + // Dirty the skeleton if manually controlled so animation can be updated + mCreator->_notifyManualBonesDirty(); + } + + } diff --git a/OgreMain/src/OgreCamera.cpp b/OgreMain/src/OgreCamera.cpp index dfb084f2fb2..11f2ca6614c 100644 --- a/OgreMain/src/OgreCamera.cpp +++ b/OgreMain/src/OgreCamera.cpp @@ -42,22 +42,22 @@ namespace Ogre { //----------------------------------------------------------------------- Camera::Camera( const String& name, SceneManager* sm) : Frustum(name), - mSceneMgr(sm), - mOrientation(Quaternion::IDENTITY), - mPosition(Vector3::ZERO), - mSceneDetail(PM_SOLID), - mAutoTrackTarget(0), - mAutoTrackOffset(Vector3::ZERO), - mSceneLodFactor(1.0f), - mSceneLodFactorInv(1.0f), - mWindowSet(false), - mLastViewport(0), - mAutoAspectRatio(false), - mCullFrustum(0), - mUseRenderingDistance(true), - mLodCamera(0), - mUseMinPixelSize(false), - mPixelDisplayRatio(0) + mSceneMgr(sm), + mOrientation(Quaternion::IDENTITY), + mPosition(Vector3::ZERO), + mSceneDetail(PM_SOLID), + mAutoTrackTarget(0), + mAutoTrackOffset(Vector3::ZERO), + mSceneLodFactor(1.0f), + mSceneLodFactorInv(1.0f), + mWindowSet(false), + mLastViewport(0), + mAutoAspectRatio(false), + mCullFrustum(0), + mUseRenderingDistance(true), + mLodCamera(0), + mUseMinPixelSize(false), + mPixelDisplayRatio(0) { // Reasonable defaults to camera params @@ -87,11 +87,11 @@ namespace Ogre { //----------------------------------------------------------------------- Camera::~Camera() { - ListenerList listenersCopy = mListeners; - for (ListenerList::iterator i = listenersCopy.begin(); i != listenersCopy.end(); ++i) - { - (*i)->cameraDestroyed(this); - } + ListenerList listenersCopy = mListeners; + for (ListenerList::iterator i = listenersCopy.begin(); i != listenersCopy.end(); ++i) + { + (*i)->cameraDestroyed(this); + } } //----------------------------------------------------------------------- SceneManager* Camera::getSceneManager(void) const @@ -170,7 +170,7 @@ namespace Ogre { Vector3 zAdjustVec = -vec; zAdjustVec.normalise(); - Quaternion targetWorldOrientation; + Quaternion targetWorldOrientation; if( mYawFixed ) @@ -212,10 +212,10 @@ namespace Ogre { mOrientation = mParentNode->_getDerivedOrientation().Inverse() * targetWorldOrientation; } - else - { - mOrientation = targetWorldOrientation; - } + else + { + mOrientation = targetWorldOrientation; + } // TODO If we have a fixed yaw axis, we mustn't break it by using the // shortest arc because this will sometimes cause a relative yaw @@ -313,9 +313,9 @@ namespace Ogre { { // Note the order of the mult, i.e. q comes after - // Normalise the quat to avoid cumulative problems with precision - Quaternion qnorm = q; - qnorm.normalise(); + // Normalise the quat to avoid cumulative problems with precision + Quaternion qnorm = q; + qnorm.normalise(); mOrientation = qnorm * mOrientation; invalidateView(); @@ -366,10 +366,10 @@ namespace Ogre { if (mReflect) { // Calculate reflected orientation, use up-vector as fallback axis. - Vector3 dir = mRealOrientation * Vector3::NEGATIVE_UNIT_Z; - Vector3 rdir = dir.reflect(mReflectPlane.normal); + Vector3 dir = mRealOrientation * Vector3::NEGATIVE_UNIT_Z; + Vector3 rdir = dir.reflect(mReflectPlane.normal); Vector3 up = mRealOrientation * Vector3::UNIT_Y; - mDerivedOrientation = dir.getRotationTo(rdir, up) * mRealOrientation; + mDerivedOrientation = dir.getRotationTo(rdir, up) * mRealOrientation; // Calculate reflected position. mDerivedPosition = mReflectMatrix.transformAffine(mRealPosition); @@ -402,49 +402,49 @@ namespace Ogre { { OgreProfileBeginGPUEvent("Camera: " + getName()); - //update the pixel display ratio - if (mProjType == Ogre::PT_PERSPECTIVE) - { - mPixelDisplayRatio = (2 * Ogre::Math::Tan(mFOVy * 0.5f)) / vp->getActualHeight(); - } - else - { - mPixelDisplayRatio = (mTop - mBottom) / vp->getActualHeight(); - } - - //notify prerender scene - ListenerList listenersCopy = mListeners; - for (ListenerList::iterator i = listenersCopy.begin(); i != listenersCopy.end(); ++i) - { - (*i)->cameraPreRenderScene(this); - } - - //render scene - mSceneMgr->_renderScene(this, vp, includeOverlays); - - // Listener list may have change - listenersCopy = mListeners; - - //notify postrender scene - for (ListenerList::iterator i = listenersCopy.begin(); i != listenersCopy.end(); ++i) - { - (*i)->cameraPostRenderScene(this); - } + //update the pixel display ratio + if (mProjType == Ogre::PT_PERSPECTIVE) + { + mPixelDisplayRatio = (2 * Ogre::Math::Tan(mFOVy * 0.5f)) / vp->getActualHeight(); + } + else + { + mPixelDisplayRatio = (mTop - mBottom) / vp->getActualHeight(); + } + + //notify prerender scene + ListenerList listenersCopy = mListeners; + for (ListenerList::iterator i = listenersCopy.begin(); i != listenersCopy.end(); ++i) + { + (*i)->cameraPreRenderScene(this); + } + + //render scene + mSceneMgr->_renderScene(this, vp, includeOverlays); + + // Listener list may have change + listenersCopy = mListeners; + + //notify postrender scene + for (ListenerList::iterator i = listenersCopy.begin(); i != listenersCopy.end(); ++i) + { + (*i)->cameraPostRenderScene(this); + } OgreProfileEndGPUEvent("Camera: " + getName()); - } - //--------------------------------------------------------------------- - void Camera::addListener(Listener* l) - { - if (std::find(mListeners.begin(), mListeners.end(), l) == mListeners.end()) - mListeners.push_back(l); - } - //--------------------------------------------------------------------- - void Camera::removeListener(Listener* l) - { - ListenerList::iterator i = std::find(mListeners.begin(), mListeners.end(), l); - if (i != mListeners.end()) - mListeners.erase(i); - } + } + //--------------------------------------------------------------------- + void Camera::addListener(Listener* l) + { + if (std::find(mListeners.begin(), mListeners.end(), l) == mListeners.end()) + mListeners.push_back(l); + } + //--------------------------------------------------------------------- + void Camera::removeListener(Listener* l) + { + ListenerList::iterator i = std::find(mListeners.begin(), mListeners.end(), l); + if (i != mListeners.end()) + mListeners.erase(i); + } //----------------------------------------------------------------------- std::ostream& operator<<( std::ostream& o, const Camera& c ) { @@ -505,7 +505,7 @@ namespace Ogre { void Camera::setOrientation(const Quaternion& q) { mOrientation = q; - mOrientation.normalise(); + mOrientation.normalise(); invalidateView(); } //----------------------------------------------------------------------- @@ -614,46 +614,46 @@ namespace Ogre { } } //----------------------------------------------------------------------- - void Camera::setLodBias(Real factor) - { - assert(factor > 0.0f && "Bias factor must be > 0!"); - mSceneLodFactor = factor; - mSceneLodFactorInv = 1.0f / factor; - } - //----------------------------------------------------------------------- - Real Camera::getLodBias(void) const - { - return mSceneLodFactor; - } - //----------------------------------------------------------------------- - Real Camera::_getLodBiasInverse(void) const - { - return mSceneLodFactorInv; - } - //----------------------------------------------------------------------- - void Camera::setLodCamera(const Camera* lodCam) - { - if (lodCam == this) - mLodCamera = 0; - else - mLodCamera = lodCam; - } - //--------------------------------------------------------------------- - const Camera* Camera::getLodCamera() const - { - return mLodCamera? mLodCamera : this; - } - //----------------------------------------------------------------------- - Ray Camera::getCameraToViewportRay(Real screenX, Real screenY) const - { - Ray ret; - getCameraToViewportRay(screenX, screenY, &ret); - return ret; - } - //--------------------------------------------------------------------- + void Camera::setLodBias(Real factor) + { + assert(factor > 0.0f && "Bias factor must be > 0!"); + mSceneLodFactor = factor; + mSceneLodFactorInv = 1.0f / factor; + } + //----------------------------------------------------------------------- + Real Camera::getLodBias(void) const + { + return mSceneLodFactor; + } + //----------------------------------------------------------------------- + Real Camera::_getLodBiasInverse(void) const + { + return mSceneLodFactorInv; + } + //----------------------------------------------------------------------- + void Camera::setLodCamera(const Camera* lodCam) + { + if (lodCam == this) + mLodCamera = 0; + else + mLodCamera = lodCam; + } + //--------------------------------------------------------------------- + const Camera* Camera::getLodCamera() const + { + return mLodCamera? mLodCamera : this; + } + //----------------------------------------------------------------------- + Ray Camera::getCameraToViewportRay(Real screenX, Real screenY) const + { + Ray ret; + getCameraToViewportRay(screenX, screenY, &ret); + return ret; + } + //--------------------------------------------------------------------- void Camera::getCameraToViewportRay(Real screenX, Real screenY, Ray* outRay) const { - Matrix4 inverseVP = (getProjectionMatrix() * getViewMatrix(true)).inverse(); + Matrix4 inverseVP = (getProjectionMatrix() * getViewMatrix(true)).inverse(); #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 // We need to convert screen point to our oriented viewport (temp solution) @@ -663,102 +663,102 @@ namespace Ogre { if ((int)getOrientationMode()&1) screenY = 1.f - screenY; #endif - Real nx = (2.0f * screenX) - 1.0f; - Real ny = 1.0f - (2.0f * screenY); - Vector3 nearPoint(nx, ny, -1.f); - // Use midPoint rather than far point to avoid issues with infinite projection - Vector3 midPoint (nx, ny, 0.0f); + Real nx = (2.0f * screenX) - 1.0f; + Real ny = 1.0f - (2.0f * screenY); + Vector3 nearPoint(nx, ny, -1.f); + // Use midPoint rather than far point to avoid issues with infinite projection + Vector3 midPoint (nx, ny, 0.0f); - // Get ray origin and ray target on near plane in world space - Vector3 rayOrigin, rayTarget; - - rayOrigin = inverseVP * nearPoint; - rayTarget = inverseVP * midPoint; + // Get ray origin and ray target on near plane in world space + Vector3 rayOrigin, rayTarget; + + rayOrigin = inverseVP * nearPoint; + rayTarget = inverseVP * midPoint; - Vector3 rayDirection = rayTarget - rayOrigin; - rayDirection.normalise(); + Vector3 rayDirection = rayTarget - rayOrigin; + rayDirection.normalise(); - outRay->setOrigin(rayOrigin); - outRay->setDirection(rayDirection); + outRay->setOrigin(rayOrigin); + outRay->setDirection(rayDirection); } - //--------------------------------------------------------------------- - PlaneBoundedVolume Camera::getCameraToViewportBoxVolume(Real screenLeft, - Real screenTop, Real screenRight, Real screenBottom, bool includeFarPlane) - { - PlaneBoundedVolume vol; - getCameraToViewportBoxVolume(screenLeft, screenTop, screenRight, screenBottom, - &vol, includeFarPlane); - return vol; - - } - //---------------------------------------------------------------------() - void Camera::getCameraToViewportBoxVolume(Real screenLeft, - Real screenTop, Real screenRight, Real screenBottom, - PlaneBoundedVolume* outVolume, bool includeFarPlane) - { - outVolume->planes.clear(); - - if (mProjType == PT_PERSPECTIVE) - { - - // Use the corner rays to generate planes - Ray ul = getCameraToViewportRay(screenLeft, screenTop); - Ray ur = getCameraToViewportRay(screenRight, screenTop); - Ray bl = getCameraToViewportRay(screenLeft, screenBottom); - Ray br = getCameraToViewportRay(screenRight, screenBottom); - - - Vector3 normal; - // top plane - normal = ul.getDirection().crossProduct(ur.getDirection()); - normal.normalise(); - outVolume->planes.push_back( - Plane(normal, getDerivedPosition())); - - // right plane - normal = ur.getDirection().crossProduct(br.getDirection()); - normal.normalise(); - outVolume->planes.push_back( - Plane(normal, getDerivedPosition())); - - // bottom plane - normal = br.getDirection().crossProduct(bl.getDirection()); - normal.normalise(); - outVolume->planes.push_back( - Plane(normal, getDerivedPosition())); - - // left plane - normal = bl.getDirection().crossProduct(ul.getDirection()); - normal.normalise(); - outVolume->planes.push_back( - Plane(normal, getDerivedPosition())); - - } - else - { - // ortho planes are parallel to frustum planes - - Ray ul = getCameraToViewportRay(screenLeft, screenTop); - Ray br = getCameraToViewportRay(screenRight, screenBottom); - - updateFrustumPlanes(); - outVolume->planes.push_back( - Plane(mFrustumPlanes[FRUSTUM_PLANE_TOP].normal, ul.getOrigin())); - outVolume->planes.push_back( - Plane(mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal, br.getOrigin())); - outVolume->planes.push_back( - Plane(mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal, br.getOrigin())); - outVolume->planes.push_back( - Plane(mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal, ul.getOrigin())); - - - } - - // near & far plane applicable to both projection types - outVolume->planes.push_back(getFrustumPlane(FRUSTUM_PLANE_NEAR)); - if (includeFarPlane) - outVolume->planes.push_back(getFrustumPlane(FRUSTUM_PLANE_FAR)); - } + //--------------------------------------------------------------------- + PlaneBoundedVolume Camera::getCameraToViewportBoxVolume(Real screenLeft, + Real screenTop, Real screenRight, Real screenBottom, bool includeFarPlane) + { + PlaneBoundedVolume vol; + getCameraToViewportBoxVolume(screenLeft, screenTop, screenRight, screenBottom, + &vol, includeFarPlane); + return vol; + + } + //---------------------------------------------------------------------() + void Camera::getCameraToViewportBoxVolume(Real screenLeft, + Real screenTop, Real screenRight, Real screenBottom, + PlaneBoundedVolume* outVolume, bool includeFarPlane) + { + outVolume->planes.clear(); + + if (mProjType == PT_PERSPECTIVE) + { + + // Use the corner rays to generate planes + Ray ul = getCameraToViewportRay(screenLeft, screenTop); + Ray ur = getCameraToViewportRay(screenRight, screenTop); + Ray bl = getCameraToViewportRay(screenLeft, screenBottom); + Ray br = getCameraToViewportRay(screenRight, screenBottom); + + + Vector3 normal; + // top plane + normal = ul.getDirection().crossProduct(ur.getDirection()); + normal.normalise(); + outVolume->planes.push_back( + Plane(normal, getDerivedPosition())); + + // right plane + normal = ur.getDirection().crossProduct(br.getDirection()); + normal.normalise(); + outVolume->planes.push_back( + Plane(normal, getDerivedPosition())); + + // bottom plane + normal = br.getDirection().crossProduct(bl.getDirection()); + normal.normalise(); + outVolume->planes.push_back( + Plane(normal, getDerivedPosition())); + + // left plane + normal = bl.getDirection().crossProduct(ul.getDirection()); + normal.normalise(); + outVolume->planes.push_back( + Plane(normal, getDerivedPosition())); + + } + else + { + // ortho planes are parallel to frustum planes + + Ray ul = getCameraToViewportRay(screenLeft, screenTop); + Ray br = getCameraToViewportRay(screenRight, screenBottom); + + updateFrustumPlanes(); + outVolume->planes.push_back( + Plane(mFrustumPlanes[FRUSTUM_PLANE_TOP].normal, ul.getOrigin())); + outVolume->planes.push_back( + Plane(mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal, br.getOrigin())); + outVolume->planes.push_back( + Plane(mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal, br.getOrigin())); + outVolume->planes.push_back( + Plane(mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal, ul.getOrigin())); + + + } + + // near & far plane applicable to both projection types + outVolume->planes.push_back(getFrustumPlane(FRUSTUM_PLANE_NEAR)); + if (includeFarPlane) + outVolume->planes.push_back(getFrustumPlane(FRUSTUM_PLANE_FAR)); + } // ------------------------------------------------------------------- void Camera::setWindow (Real Left, Real Top, Real Right, Real Bottom) { @@ -805,7 +805,7 @@ namespace Ogre { Vector3 vw_bl = inv.transformAffine(vp_bl); Vector3 vw_br = inv.transformAffine(vp_br); - mWindowClipPlanes.clear(); + mWindowClipPlanes.clear(); if (mProjType == PT_PERSPECTIVE) { Vector3 position = getPositionForViewUpdate(); @@ -865,283 +865,283 @@ namespace Ogre { { mAutoAspectRatio = autoratio; } - //----------------------------------------------------------------------- - bool Camera::isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy) const - { - if (mCullFrustum) - { - return mCullFrustum->isVisible(bound, culledBy); - } - else - { - return Frustum::isVisible(bound, culledBy); - } - } - //----------------------------------------------------------------------- - bool Camera::isVisible(const Sphere& bound, FrustumPlane* culledBy) const - { - if (mCullFrustum) - { - return mCullFrustum->isVisible(bound, culledBy); - } - else - { - return Frustum::isVisible(bound, culledBy); - } - } - //----------------------------------------------------------------------- - bool Camera::isVisible(const Vector3& vert, FrustumPlane* culledBy) const - { - if (mCullFrustum) - { - return mCullFrustum->isVisible(vert, culledBy); - } - else - { - return Frustum::isVisible(vert, culledBy); - } - } - //----------------------------------------------------------------------- - const Vector3* Camera::getWorldSpaceCorners(void) const - { - if (mCullFrustum) - { - return mCullFrustum->getWorldSpaceCorners(); - } - else - { - return Frustum::getWorldSpaceCorners(); - } - } - //----------------------------------------------------------------------- - const Plane& Camera::getFrustumPlane( unsigned short plane ) const - { - if (mCullFrustum) - { - return mCullFrustum->getFrustumPlane(plane); - } - else - { - return Frustum::getFrustumPlane(plane); - } - } - //----------------------------------------------------------------------- - bool Camera::projectSphere(const Sphere& sphere, - Real* left, Real* top, Real* right, Real* bottom) const - { - if (mCullFrustum) - { - return mCullFrustum->projectSphere(sphere, left, top, right, bottom); - } - else - { - return Frustum::projectSphere(sphere, left, top, right, bottom); - } - } - //----------------------------------------------------------------------- - Real Camera::getNearClipDistance(void) const - { - if (mCullFrustum) - { - return mCullFrustum->getNearClipDistance(); - } - else - { - return Frustum::getNearClipDistance(); - } - } - //----------------------------------------------------------------------- - Real Camera::getFarClipDistance(void) const - { - if (mCullFrustum) - { - return mCullFrustum->getFarClipDistance(); - } - else - { - return Frustum::getFarClipDistance(); - } - } - //----------------------------------------------------------------------- - const Matrix4& Camera::getViewMatrix(void) const - { - if (mCullFrustum) - { - return mCullFrustum->getViewMatrix(); - } - else - { - return Frustum::getViewMatrix(); - } - } - //----------------------------------------------------------------------- - const Matrix4& Camera::getViewMatrix(bool ownFrustumOnly) const - { - if (ownFrustumOnly) - { - return Frustum::getViewMatrix(); - } - else - { - return getViewMatrix(); - } - } - //----------------------------------------------------------------------- - //_______________________________________________________ - //| | - //| getRayForwardIntersect | - //| ----------------------------- | - //| get the intersections of frustum rays with a plane | - //| of interest. The plane is assumed to have constant | - //| z. If this is not the case, rays | - //| should be rotated beforehand to work in a | - //| coordinate system in which this is true. | - //|_____________________________________________________| - // - vector::type Camera::getRayForwardIntersect(const Vector3& anchor, const Vector3 *dir, Real planeOffset) const - { - vector::type res; - - if(!dir) - return res; - - int infpt[4] = {0, 0, 0, 0}; // 0=finite, 1=infinite, 2=straddles infinity - Vector3 vec[4]; - - // find how much the anchor point must be displaced in the plane's - // constant variable - Real delta = planeOffset - anchor.z; - - // now set the intersection point and note whether it is a - // point at infinity or straddles infinity - unsigned int i; - for (i=0; i<4; i++) - { - Real test = dir[i].z * delta; - if (test == 0.0) { - vec[i] = dir[i]; - infpt[i] = 1; - } - else { - Real lambda = delta / dir[i].z; - vec[i] = anchor + (lambda * dir[i]); - if(test < 0.0) - infpt[i] = 2; - } - } - - for (i=0; i<4; i++) - { - // store the finite intersection points - if (infpt[i] == 0) - res.push_back(Vector4(vec[i].x, vec[i].y, vec[i].z, 1.0)); - else - { - // handle the infinite points of intersection; - // cases split up into the possible frustum planes - // pieces which may contain a finite intersection point - int nextind = (i+1) % 4; - int prevind = (i+3) % 4; - if ((infpt[prevind] == 0) || (infpt[nextind] == 0)) - { - if (infpt[i] == 1) - res.push_back(Vector4(vec[i].x, vec[i].y, vec[i].z, 0.0)); - else - { - // handle the intersection points that straddle infinity (back-project) - if(infpt[prevind] == 0) - { - Vector3 temp = vec[prevind] - vec[i]; - res.push_back(Vector4(temp.x, temp.y, temp.z, 0.0)); - } - if(infpt[nextind] == 0) - { - Vector3 temp = vec[nextind] - vec[i]; - res.push_back(Vector4(temp.x, temp.y, temp.z, 0.0)); - } - } - } // end if we need to add an intersection point to the list - } // end if infinite point needs to be considered - } // end loop over frustun corners - - // we end up with either 0, 3, 4, or 5 intersection points - - return res; - } - - //_______________________________________________________ - //| | - //| forwardIntersect | - //| ----------------------------- | - //| Forward intersect the camera's frustum rays with | - //| a specified plane of interest. | - //| Note that if the frustum rays shoot out and would | - //| back project onto the plane, this means the forward | - //| intersection of the frustum would occur at the | - //| line at infinity. | - //|_____________________________________________________| - // - void Camera::forwardIntersect(const Plane& worldPlane, vector::type* intersect3d) const - { - if(!intersect3d) - return; - - Vector3 trCorner = getWorldSpaceCorners()[0]; - Vector3 tlCorner = getWorldSpaceCorners()[1]; - Vector3 blCorner = getWorldSpaceCorners()[2]; - Vector3 brCorner = getWorldSpaceCorners()[3]; - - // need some sort of rotation that will bring the plane normal to the z axis - Plane pval = worldPlane; - if(pval.normal.z < 0.0) - { - pval.normal *= -1.0; - pval.d *= -1.0; - } - Quaternion invPlaneRot = pval.normal.getRotationTo(Vector3::UNIT_Z); - - // get rotated light - Vector3 lPos = invPlaneRot * getDerivedPosition(); - Vector3 vec[4]; - vec[0] = invPlaneRot * trCorner - lPos; - vec[1] = invPlaneRot * tlCorner - lPos; - vec[2] = invPlaneRot * blCorner - lPos; - vec[3] = invPlaneRot * brCorner - lPos; - - // compute intersection points on plane - vector::type iPnt = getRayForwardIntersect(lPos, vec, -pval.d); - - - // return wanted data - if(intersect3d) - { - Quaternion planeRot = invPlaneRot.Inverse(); - (*intersect3d).clear(); - for(unsigned int i=0; isetPosition(cam->getPosition()); - this->setProjectionType(cam->getProjectionType()); - this->setOrientation(cam->getOrientation()); - this->setAspectRatio(cam->getAspectRatio()); - this->setNearClipDistance(cam->getNearClipDistance()); - this->setFarClipDistance(cam->getFarClipDistance()); - this->setUseRenderingDistance(cam->getUseRenderingDistance()); - this->setFOVy(cam->getFOVy()); - this->setFocalLength(cam->getFocalLength()); - - // Don't do these, they're not base settings and can cause referencing issues - //this->setLodCamera(cam->getLodCamera()); - //this->setCullingFrustum(cam->getCullingFrustum()); - - } + //----------------------------------------------------------------------- + bool Camera::isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy) const + { + if (mCullFrustum) + { + return mCullFrustum->isVisible(bound, culledBy); + } + else + { + return Frustum::isVisible(bound, culledBy); + } + } + //----------------------------------------------------------------------- + bool Camera::isVisible(const Sphere& bound, FrustumPlane* culledBy) const + { + if (mCullFrustum) + { + return mCullFrustum->isVisible(bound, culledBy); + } + else + { + return Frustum::isVisible(bound, culledBy); + } + } + //----------------------------------------------------------------------- + bool Camera::isVisible(const Vector3& vert, FrustumPlane* culledBy) const + { + if (mCullFrustum) + { + return mCullFrustum->isVisible(vert, culledBy); + } + else + { + return Frustum::isVisible(vert, culledBy); + } + } + //----------------------------------------------------------------------- + const Vector3* Camera::getWorldSpaceCorners(void) const + { + if (mCullFrustum) + { + return mCullFrustum->getWorldSpaceCorners(); + } + else + { + return Frustum::getWorldSpaceCorners(); + } + } + //----------------------------------------------------------------------- + const Plane& Camera::getFrustumPlane( unsigned short plane ) const + { + if (mCullFrustum) + { + return mCullFrustum->getFrustumPlane(plane); + } + else + { + return Frustum::getFrustumPlane(plane); + } + } + //----------------------------------------------------------------------- + bool Camera::projectSphere(const Sphere& sphere, + Real* left, Real* top, Real* right, Real* bottom) const + { + if (mCullFrustum) + { + return mCullFrustum->projectSphere(sphere, left, top, right, bottom); + } + else + { + return Frustum::projectSphere(sphere, left, top, right, bottom); + } + } + //----------------------------------------------------------------------- + Real Camera::getNearClipDistance(void) const + { + if (mCullFrustum) + { + return mCullFrustum->getNearClipDistance(); + } + else + { + return Frustum::getNearClipDistance(); + } + } + //----------------------------------------------------------------------- + Real Camera::getFarClipDistance(void) const + { + if (mCullFrustum) + { + return mCullFrustum->getFarClipDistance(); + } + else + { + return Frustum::getFarClipDistance(); + } + } + //----------------------------------------------------------------------- + const Matrix4& Camera::getViewMatrix(void) const + { + if (mCullFrustum) + { + return mCullFrustum->getViewMatrix(); + } + else + { + return Frustum::getViewMatrix(); + } + } + //----------------------------------------------------------------------- + const Matrix4& Camera::getViewMatrix(bool ownFrustumOnly) const + { + if (ownFrustumOnly) + { + return Frustum::getViewMatrix(); + } + else + { + return getViewMatrix(); + } + } + //----------------------------------------------------------------------- + //_______________________________________________________ + //| | + //| getRayForwardIntersect | + //| ----------------------------- | + //| get the intersections of frustum rays with a plane | + //| of interest. The plane is assumed to have constant | + //| z. If this is not the case, rays | + //| should be rotated beforehand to work in a | + //| coordinate system in which this is true. | + //|_____________________________________________________| + // + vector::type Camera::getRayForwardIntersect(const Vector3& anchor, const Vector3 *dir, Real planeOffset) const + { + vector::type res; + + if(!dir) + return res; + + int infpt[4] = {0, 0, 0, 0}; // 0=finite, 1=infinite, 2=straddles infinity + Vector3 vec[4]; + + // find how much the anchor point must be displaced in the plane's + // constant variable + Real delta = planeOffset - anchor.z; + + // now set the intersection point and note whether it is a + // point at infinity or straddles infinity + unsigned int i; + for (i=0; i<4; i++) + { + Real test = dir[i].z * delta; + if (test == 0.0) { + vec[i] = dir[i]; + infpt[i] = 1; + } + else { + Real lambda = delta / dir[i].z; + vec[i] = anchor + (lambda * dir[i]); + if(test < 0.0) + infpt[i] = 2; + } + } + + for (i=0; i<4; i++) + { + // store the finite intersection points + if (infpt[i] == 0) + res.push_back(Vector4(vec[i].x, vec[i].y, vec[i].z, 1.0)); + else + { + // handle the infinite points of intersection; + // cases split up into the possible frustum planes + // pieces which may contain a finite intersection point + int nextind = (i+1) % 4; + int prevind = (i+3) % 4; + if ((infpt[prevind] == 0) || (infpt[nextind] == 0)) + { + if (infpt[i] == 1) + res.push_back(Vector4(vec[i].x, vec[i].y, vec[i].z, 0.0)); + else + { + // handle the intersection points that straddle infinity (back-project) + if(infpt[prevind] == 0) + { + Vector3 temp = vec[prevind] - vec[i]; + res.push_back(Vector4(temp.x, temp.y, temp.z, 0.0)); + } + if(infpt[nextind] == 0) + { + Vector3 temp = vec[nextind] - vec[i]; + res.push_back(Vector4(temp.x, temp.y, temp.z, 0.0)); + } + } + } // end if we need to add an intersection point to the list + } // end if infinite point needs to be considered + } // end loop over frustun corners + + // we end up with either 0, 3, 4, or 5 intersection points + + return res; + } + + //_______________________________________________________ + //| | + //| forwardIntersect | + //| ----------------------------- | + //| Forward intersect the camera's frustum rays with | + //| a specified plane of interest. | + //| Note that if the frustum rays shoot out and would | + //| back project onto the plane, this means the forward | + //| intersection of the frustum would occur at the | + //| line at infinity. | + //|_____________________________________________________| + // + void Camera::forwardIntersect(const Plane& worldPlane, vector::type* intersect3d) const + { + if(!intersect3d) + return; + + Vector3 trCorner = getWorldSpaceCorners()[0]; + Vector3 tlCorner = getWorldSpaceCorners()[1]; + Vector3 blCorner = getWorldSpaceCorners()[2]; + Vector3 brCorner = getWorldSpaceCorners()[3]; + + // need some sort of rotation that will bring the plane normal to the z axis + Plane pval = worldPlane; + if(pval.normal.z < 0.0) + { + pval.normal *= -1.0; + pval.d *= -1.0; + } + Quaternion invPlaneRot = pval.normal.getRotationTo(Vector3::UNIT_Z); + + // get rotated light + Vector3 lPos = invPlaneRot * getDerivedPosition(); + Vector3 vec[4]; + vec[0] = invPlaneRot * trCorner - lPos; + vec[1] = invPlaneRot * tlCorner - lPos; + vec[2] = invPlaneRot * blCorner - lPos; + vec[3] = invPlaneRot * brCorner - lPos; + + // compute intersection points on plane + vector::type iPnt = getRayForwardIntersect(lPos, vec, -pval.d); + + + // return wanted data + if(intersect3d) + { + Quaternion planeRot = invPlaneRot.Inverse(); + (*intersect3d).clear(); + for(unsigned int i=0; isetPosition(cam->getPosition()); + this->setProjectionType(cam->getProjectionType()); + this->setOrientation(cam->getOrientation()); + this->setAspectRatio(cam->getAspectRatio()); + this->setNearClipDistance(cam->getNearClipDistance()); + this->setFarClipDistance(cam->getFarClipDistance()); + this->setUseRenderingDistance(cam->getUseRenderingDistance()); + this->setFOVy(cam->getFOVy()); + this->setFocalLength(cam->getFocalLength()); + + // Don't do these, they're not base settings and can cause referencing issues + //this->setLodCamera(cam->getLodCamera()); + //this->setCullingFrustum(cam->getCullingFrustum()); + + } } // namespace Ogre diff --git a/OgreMain/src/OgreCodec.cpp b/OgreMain/src/OgreCodec.cpp index b126aa06f0c..e5c1584b55f 100644 --- a/OgreMain/src/OgreCodec.cpp +++ b/OgreMain/src/OgreCodec.cpp @@ -50,7 +50,7 @@ namespace Ogre { Codec* Codec::getCodec(const String& extension) { String lwrcase = extension; - StringUtil::toLowerCase(lwrcase); + StringUtil::toLowerCase(lwrcase); CodecList::const_iterator i = msMapCodecs.find(lwrcase); if (i == msMapCodecs.end()) { @@ -70,27 +70,27 @@ namespace Ogre { } - Codec* Codec::getCodec(char *magicNumberPtr, size_t maxbytes) - { - for (CodecList::const_iterator i = msMapCodecs. begin(); - i != msMapCodecs.end(); ++i) - { - String ext = i->second->magicNumberToFileExt(magicNumberPtr, maxbytes); - if (!ext.empty()) - { - // check codec type matches - // if we have a single codec class that can handle many types, - // and register many instances of it against different types, we - // can end up matching the wrong one here, so grab the right one - if (ext == i->second->getType()) - return i->second; - else - return getCodec(ext); - } - } - - return 0; - - } + Codec* Codec::getCodec(char *magicNumberPtr, size_t maxbytes) + { + for (CodecList::const_iterator i = msMapCodecs. begin(); + i != msMapCodecs.end(); ++i) + { + String ext = i->second->magicNumberToFileExt(magicNumberPtr, maxbytes); + if (!ext.empty()) + { + // check codec type matches + // if we have a single codec class that can handle many types, + // and register many instances of it against different types, we + // can end up matching the wrong one here, so grab the right one + if (ext == i->second->getType()) + return i->second; + else + return getCodec(ext); + } + } + + return 0; + + } } diff --git a/OgreMain/src/OgreColourValue.cpp b/OgreMain/src/OgreColourValue.cpp index 6f7e97e0763..3df526fa752 100644 --- a/OgreMain/src/OgreColourValue.cpp +++ b/OgreMain/src/OgreColourValue.cpp @@ -101,38 +101,38 @@ namespace Ogre { return val32; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - ARGB ColourValue::getAsARGB(void) const + ARGB ColourValue::getAsARGB(void) const #else - BGRA ColourValue::getAsBGRA(void) const + BGRA ColourValue::getAsBGRA(void) const #endif - { - uint8 val8; - uint32 val32 = 0; + { + uint8 val8; + uint32 val32 = 0; - // Convert to 32bit pattern - // (ARGB = 8888) + // Convert to 32bit pattern + // (ARGB = 8888) - // Blue - val8 = static_cast(b * 255); - val32 = val8 << 24; + // Blue + val8 = static_cast(b * 255); + val32 = val8 << 24; - // Green - val8 = static_cast(g * 255); - val32 += val8 << 16; + // Green + val8 = static_cast(g * 255); + val32 += val8 << 16; - // Red - val8 = static_cast(r * 255); - val32 += val8 << 8; + // Red + val8 = static_cast(r * 255); + val32 += val8 << 8; - // Alpha - val8 = static_cast(a * 255); - val32 += val8; + // Alpha + val8 = static_cast(a * 255); + val32 += val8; - return val32; - } + return val32; + } //--------------------------------------------------------------------- #if OGRE_ENDIAN == OGRE_ENDIAN_BIG RGBA ColourValue::getAsRGBA(void) const @@ -213,30 +213,30 @@ namespace Ogre { // Blue b = (val32 & 0xFF) / 255.0f; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - void ColourValue::setAsARGB(const ARGB val) + void ColourValue::setAsARGB(const ARGB val) #else - void ColourValue::setAsBGRA(const BGRA val) + void ColourValue::setAsBGRA(const BGRA val) #endif - { - uint32 val32 = val; + { + uint32 val32 = val; - // Convert from 32bit pattern - // (ARGB = 8888) + // Convert from 32bit pattern + // (ARGB = 8888) - // Blue - b = ((val32 >> 24) & 0xFF) / 255.0f; + // Blue + b = ((val32 >> 24) & 0xFF) / 255.0f; - // Green - g = ((val32 >> 16) & 0xFF) / 255.0f; + // Green + g = ((val32 >> 16) & 0xFF) / 255.0f; - // Red - r = ((val32 >> 8) & 0xFF) / 255.0f; + // Red + r = ((val32 >> 8) & 0xFF) / 255.0f; - // Alpha - a = (val32 & 0xFF) / 255.0f; - } + // Alpha + a = (val32 & 0xFF) / 255.0f; + } //--------------------------------------------------------------------- #if OGRE_ENDIAN == OGRE_ENDIAN_BIG void ColourValue::setAsRGBA(const RGBA val) @@ -274,133 +274,133 @@ namespace Ogre { { return !(*this == rhs); } - //--------------------------------------------------------------------- - void ColourValue::setHSB(Real hue, Real saturation, Real brightness) - { - // wrap hue - if (hue > 1.0f) - { - hue -= (int)hue; - } - else if (hue < 0.0f) - { - hue += (int)hue + 1; - } - // clamp saturation / brightness - saturation = std::min(saturation, (Real)1.0); - saturation = std::max(saturation, (Real)0.0); - brightness = std::min(brightness, (Real)1.0); - brightness = std::max(brightness, (Real)0.0); - - if (brightness == 0.0f) - { - // early exit, this has to be black - r = g = b = 0.0f; - return; - } - - if (saturation == 0.0f) - { - // early exit, this has to be grey - - r = g = b = brightness; - return; - } - - - Real hueDomain = hue * 6.0f; - if (hueDomain >= 6.0f) - { - // wrap around, and allow mathematical errors - hueDomain = 0.0f; - } - unsigned short domain = (unsigned short)hueDomain; - Real f1 = brightness * (1 - saturation); - Real f2 = brightness * (1 - saturation * (hueDomain - domain)); - Real f3 = brightness * (1 - saturation * (1 - (hueDomain - domain))); - - switch (domain) - { - case 0: - // red domain; green ascends - r = brightness; - g = f3; - b = f1; - break; - case 1: - // yellow domain; red descends - r = f2; - g = brightness; - b = f1; - break; - case 2: - // green domain; blue ascends - r = f1; - g = brightness; - b = f3; - break; - case 3: - // cyan domain; green descends - r = f1; - g = f2; - b = brightness; - break; - case 4: - // blue domain; red ascends - r = f3; - g = f1; - b = brightness; - break; - case 5: - // magenta domain; blue descends - r = brightness; - g = f1; - b = f2; - break; - } - - - } - //--------------------------------------------------------------------- - void ColourValue::getHSB(Real* hue, Real* saturation, Real* brightness) const - { - - Real vMin = std::min(r, std::min(g, b)); - Real vMax = std::max(r, std::max(g, b)); - Real delta = vMax - vMin; - - *brightness = vMax; - - if (Math::RealEqual(delta, 0.0f, 1e-6)) - { - // grey - *hue = 0; - *saturation = 0; - } - else - { - // a colour - *saturation = delta / vMax; - - Real deltaR = (((vMax - r) / 6.0f) + (delta / 2.0f)) / delta; - Real deltaG = (((vMax - g) / 6.0f) + (delta / 2.0f)) / delta; - Real deltaB = (((vMax - b) / 6.0f) + (delta / 2.0f)) / delta; - - if (Math::RealEqual(r, vMax)) - *hue = deltaB - deltaG; - else if (Math::RealEqual(g, vMax)) - *hue = 0.3333333f + deltaR - deltaB; - else if (Math::RealEqual(b, vMax)) - *hue = 0.6666667f + deltaG - deltaR; - - if (*hue < 0.0f) - *hue += 1.0f; - if (*hue > 1.0f) - *hue -= 1.0f; - } - - - } + //--------------------------------------------------------------------- + void ColourValue::setHSB(Real hue, Real saturation, Real brightness) + { + // wrap hue + if (hue > 1.0f) + { + hue -= (int)hue; + } + else if (hue < 0.0f) + { + hue += (int)hue + 1; + } + // clamp saturation / brightness + saturation = std::min(saturation, (Real)1.0); + saturation = std::max(saturation, (Real)0.0); + brightness = std::min(brightness, (Real)1.0); + brightness = std::max(brightness, (Real)0.0); + + if (brightness == 0.0f) + { + // early exit, this has to be black + r = g = b = 0.0f; + return; + } + + if (saturation == 0.0f) + { + // early exit, this has to be grey + + r = g = b = brightness; + return; + } + + + Real hueDomain = hue * 6.0f; + if (hueDomain >= 6.0f) + { + // wrap around, and allow mathematical errors + hueDomain = 0.0f; + } + unsigned short domain = (unsigned short)hueDomain; + Real f1 = brightness * (1 - saturation); + Real f2 = brightness * (1 - saturation * (hueDomain - domain)); + Real f3 = brightness * (1 - saturation * (1 - (hueDomain - domain))); + + switch (domain) + { + case 0: + // red domain; green ascends + r = brightness; + g = f3; + b = f1; + break; + case 1: + // yellow domain; red descends + r = f2; + g = brightness; + b = f1; + break; + case 2: + // green domain; blue ascends + r = f1; + g = brightness; + b = f3; + break; + case 3: + // cyan domain; green descends + r = f1; + g = f2; + b = brightness; + break; + case 4: + // blue domain; red ascends + r = f3; + g = f1; + b = brightness; + break; + case 5: + // magenta domain; blue descends + r = brightness; + g = f1; + b = f2; + break; + } + + + } + //--------------------------------------------------------------------- + void ColourValue::getHSB(Real* hue, Real* saturation, Real* brightness) const + { + + Real vMin = std::min(r, std::min(g, b)); + Real vMax = std::max(r, std::max(g, b)); + Real delta = vMax - vMin; + + *brightness = vMax; + + if (Math::RealEqual(delta, 0.0f, 1e-6)) + { + // grey + *hue = 0; + *saturation = 0; + } + else + { + // a colour + *saturation = delta / vMax; + + Real deltaR = (((vMax - r) / 6.0f) + (delta / 2.0f)) / delta; + Real deltaG = (((vMax - g) / 6.0f) + (delta / 2.0f)) / delta; + Real deltaB = (((vMax - b) / 6.0f) + (delta / 2.0f)) / delta; + + if (Math::RealEqual(r, vMax)) + *hue = deltaB - deltaG; + else if (Math::RealEqual(g, vMax)) + *hue = 0.3333333f + deltaR - deltaB; + else if (Math::RealEqual(b, vMax)) + *hue = 0.6666667f + deltaG - deltaR; + + if (*hue < 0.0f) + *hue += 1.0f; + if (*hue > 1.0f) + *hue -= 1.0f; + } + + + } } diff --git a/OgreMain/src/OgreCommon.cpp b/OgreMain/src/OgreCommon.cpp index b93540393c0..fde374c7b84 100644 --- a/OgreMain/src/OgreCommon.cpp +++ b/OgreMain/src/OgreCommon.cpp @@ -65,67 +65,67 @@ namespace Ogre return startIndex; } - /** General hash function, derived from here - http://www.azillionmonkeys.com/qed/hash.html - Original by Paul Hsieh - */ + /** General hash function, derived from here + http://www.azillionmonkeys.com/qed/hash.html + Original by Paul Hsieh + */ #if OGRE_ENDIAN == OGRE_ENDIAN_LITTLE # define OGRE_GET16BITS(d) (*((const uint16 *) (d))) #else - // Cast to uint16 in little endian means first byte is least significant - // replicate that here + // Cast to uint16 in little endian means first byte is least significant + // replicate that here # define OGRE_GET16BITS(d) (*((const uint8 *) (d)) + (*((const uint8 *) (d+1))<<8)) #endif - uint32 _OgreExport FastHash (const char * data, int len, uint32 hashSoFar) - { - uint32 hash; - int rem; - - if (hashSoFar) - hash = hashSoFar; - else - hash = len; - - if (len <= 0 || data == NULL) return 0; - - rem = len & 3; - len >>= 2; - - /* Main loop */ - for (;len > 0; len--) { - hash += OGRE_GET16BITS (data); - uint32 tmp = (OGRE_GET16BITS (data+2) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - data += 2*sizeof (uint16); - hash += hash >> 11; - } - - /* Handle end cases */ - switch (rem) { - case 3: hash += OGRE_GET16BITS (data); - hash ^= hash << 16; - hash ^= data[sizeof (uint16)] << 18; - hash += hash >> 11; - break; - case 2: hash += OGRE_GET16BITS (data); - hash ^= hash << 11; - hash += hash >> 17; - break; - case 1: hash += *data; - hash ^= hash << 10; - hash += hash >> 1; - } - - /* Force "avalanching" of final 127 bits */ - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - - return hash; - } + uint32 _OgreExport FastHash (const char * data, int len, uint32 hashSoFar) + { + uint32 hash; + int rem; + + if (hashSoFar) + hash = hashSoFar; + else + hash = len; + + if (len <= 0 || data == NULL) return 0; + + rem = len & 3; + len >>= 2; + + /* Main loop */ + for (;len > 0; len--) { + hash += OGRE_GET16BITS (data); + uint32 tmp = (OGRE_GET16BITS (data+2) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2*sizeof (uint16); + hash += hash >> 11; + } + + /* Handle end cases */ + switch (rem) { + case 3: hash += OGRE_GET16BITS (data); + hash ^= hash << 16; + hash ^= data[sizeof (uint16)] << 18; + hash += hash >> 11; + break; + case 2: hash += OGRE_GET16BITS (data); + hash ^= hash << 11; + hash += hash >> 17; + break; + case 1: hash += *data; + hash ^= hash << 10; + hash += hash >> 1; + } + + /* Force "avalanching" of final 127 bits */ + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + + return hash; + } } diff --git a/OgreMain/src/OgreCompositionPass.cpp b/OgreMain/src/OgreCompositionPass.cpp index a2ba3e98be6..764390c4efd 100644 --- a/OgreMain/src/OgreCompositionPass.cpp +++ b/OgreMain/src/OgreCompositionPass.cpp @@ -35,14 +35,14 @@ namespace Ogre { CompositionPass::CompositionPass(CompositionTargetPass *parent): mParent(parent), mType(PT_RENDERQUAD), - mIdentifier(0), - mFirstRenderQueue(RENDER_QUEUE_BACKGROUND), - mLastRenderQueue(RENDER_QUEUE_SKIES_LATE), - mMaterialScheme(BLANKSTRING), + mIdentifier(0), + mFirstRenderQueue(RENDER_QUEUE_BACKGROUND), + mLastRenderQueue(RENDER_QUEUE_SKIES_LATE), + mMaterialScheme(BLANKSTRING), mClearBuffers(FBT_COLOUR|FBT_DEPTH), mClearColour(0.0,0.0,0.0,0.0), - mClearDepth(1.0f), - mClearStencil(0), + mClearDepth(1.0f), + mClearStencil(0), mStencilCheck(false), mStencilFunc(CMPF_ALWAYS_PASS), mStencilRefValue(0), @@ -51,14 +51,14 @@ CompositionPass::CompositionPass(CompositionTargetPass *parent): mStencilDepthFailOp(SOP_KEEP), mStencilPassOp(SOP_KEEP), mStencilTwoSidedOperation(false), - mStencilReadBackAsTexture(false), + mStencilReadBackAsTexture(false), mQuadCornerModified(false), mQuadLeft(-1), mQuadTop(1), mQuadRight(1), mQuadBottom(-1), - mQuadFarCorners(false), - mQuadFarCornersViewSpace(false) + mQuadFarCorners(false), + mQuadFarCornersViewSpace(false) { } //----------------------------------------------------------------------- @@ -159,122 +159,122 @@ CompositionTargetPass *CompositionPass::getParent() //----------------------------------------------------------------------- void CompositionPass::setFirstRenderQueue(uint8 id) { - mFirstRenderQueue = id; + mFirstRenderQueue = id; } //----------------------------------------------------------------------- uint8 CompositionPass::getFirstRenderQueue() const { - return mFirstRenderQueue; + return mFirstRenderQueue; } //----------------------------------------------------------------------- void CompositionPass::setLastRenderQueue(uint8 id) { - mLastRenderQueue = id; + mLastRenderQueue = id; } //----------------------------------------------------------------------- void CompositionPass::setMaterialScheme(const String& schemeName) { - mMaterialScheme = schemeName; + mMaterialScheme = schemeName; } //----------------------------------------------------------------------- const String& CompositionPass::getMaterialScheme(void) const { - return mMaterialScheme; + return mMaterialScheme; } //----------------------------------------------------------------------- uint8 CompositionPass::getLastRenderQueue() const { - return mLastRenderQueue; + return mLastRenderQueue; } //----------------------------------------------------------------------- void CompositionPass::setClearDepth(Real depth) { - mClearDepth = depth; + mClearDepth = depth; } Real CompositionPass::getClearDepth() const { - return mClearDepth; + return mClearDepth; } void CompositionPass::setClearStencil(uint32 value) { - mClearStencil = value; + mClearStencil = value; } uint32 CompositionPass::getClearStencil() const { - return mClearStencil; + return mClearStencil; } void CompositionPass::setStencilCheck(bool value) { - mStencilCheck = value; + mStencilCheck = value; } bool CompositionPass::getStencilCheck() const { - return mStencilCheck; + return mStencilCheck; } void CompositionPass::setStencilFunc(CompareFunction value) { - mStencilFunc = value; + mStencilFunc = value; } CompareFunction CompositionPass::getStencilFunc() const { - return mStencilFunc; + return mStencilFunc; } void CompositionPass::setStencilRefValue(uint32 value) { - mStencilRefValue = value; + mStencilRefValue = value; } uint32 CompositionPass::getStencilRefValue() const { - return mStencilRefValue; + return mStencilRefValue; } void CompositionPass::setStencilMask(uint32 value) { - mStencilMask = value; + mStencilMask = value; } uint32 CompositionPass::getStencilMask() const { - return mStencilMask; + return mStencilMask; } void CompositionPass::setStencilFailOp(StencilOperation value) { - mStencilFailOp = value; + mStencilFailOp = value; } StencilOperation CompositionPass::getStencilFailOp() const { - return mStencilFailOp; + return mStencilFailOp; } void CompositionPass::setStencilDepthFailOp(StencilOperation value) { - mStencilDepthFailOp = value; + mStencilDepthFailOp = value; } StencilOperation CompositionPass::getStencilDepthFailOp() const { - return mStencilDepthFailOp; + return mStencilDepthFailOp; } void CompositionPass::setStencilPassOp(StencilOperation value) { - mStencilPassOp = value; + mStencilPassOp = value; } StencilOperation CompositionPass::getStencilPassOp() const { - return mStencilPassOp; + return mStencilPassOp; } void CompositionPass::setStencilTwoSidedOperation(bool value) { - mStencilTwoSidedOperation = value; + mStencilTwoSidedOperation = value; } bool CompositionPass::getStencilTwoSidedOperation() const { - return mStencilTwoSidedOperation; + return mStencilTwoSidedOperation; } void CompositionPass::setStencilReadBackAsTextureOperation(bool value) { - mStencilReadBackAsTexture = value; + mStencilReadBackAsTexture = value; } bool CompositionPass::getStencilReadBackAsTextureOperation() const { - return mStencilReadBackAsTexture; + return mStencilReadBackAsTexture; } void CompositionPass::setQuadCorners(Real left,Real top,Real right,Real bottom) @@ -295,26 +295,26 @@ bool CompositionPass::getQuadCorners(Real & left,Real & top,Real & right,Real & } void CompositionPass::setQuadFarCorners(bool farCorners, bool farCornersViewSpace) { - mQuadFarCorners = farCorners; - mQuadFarCornersViewSpace = farCornersViewSpace; + mQuadFarCorners = farCorners; + mQuadFarCornersViewSpace = farCornersViewSpace; } bool CompositionPass::getQuadFarCorners() const { - return mQuadFarCorners; + return mQuadFarCorners; } bool CompositionPass::getQuadFarCornersViewSpace() const { - return mQuadFarCornersViewSpace; + return mQuadFarCornersViewSpace; } - + void CompositionPass::setCustomType(const String& customType) { - mCustomType = customType; + mCustomType = customType; } const String& CompositionPass::getCustomType() const { - return mCustomType; + return mCustomType; } //----------------------------------------------------------------------- bool CompositionPass::_isSupported(void) diff --git a/OgreMain/src/OgreCompositionTargetPass.cpp b/OgreMain/src/OgreCompositionTargetPass.cpp index b60b8992bfb..48a746632ea 100644 --- a/OgreMain/src/OgreCompositionTargetPass.cpp +++ b/OgreMain/src/OgreCompositionTargetPass.cpp @@ -39,13 +39,13 @@ CompositionTargetPass::CompositionTargetPass(CompositionTechnique *parent): mOnlyInitial(false), mVisibilityMask(0xFFFFFFFF), mLodBias(1.0f), - mMaterialScheme(MaterialManager::DEFAULT_SCHEME_NAME), - mShadowsEnabled(true) + mMaterialScheme(MaterialManager::DEFAULT_SCHEME_NAME), + mShadowsEnabled(true) { - if (Root::getSingleton().getRenderSystem()) - { - mMaterialScheme = Root::getSingleton().getRenderSystem()->_getDefaultViewportMaterialScheme(); - } + if (Root::getSingleton().getRenderSystem()) + { + mMaterialScheme = Root::getSingleton().getRenderSystem()->_getDefaultViewportMaterialScheme(); + } } //----------------------------------------------------------------------- CompositionTargetPass::~CompositionTargetPass() @@ -105,22 +105,22 @@ float CompositionTargetPass::getLodBias() //----------------------------------------------------------------------- void CompositionTargetPass::setMaterialScheme(const String& schemeName) { - mMaterialScheme = schemeName; + mMaterialScheme = schemeName; } //----------------------------------------------------------------------- const String& CompositionTargetPass::getMaterialScheme(void) const { - return mMaterialScheme; + return mMaterialScheme; } //----------------------------------------------------------------------- void CompositionTargetPass::setShadowsEnabled(bool enabled) { - mShadowsEnabled = enabled; + mShadowsEnabled = enabled; } //----------------------------------------------------------------------- bool CompositionTargetPass::getShadowsEnabled(void) const { - return mShadowsEnabled; + return mShadowsEnabled; } //----------------------------------------------------------------------- CompositionPass *CompositionTargetPass::createPass() diff --git a/OgreMain/src/OgreCompositionTechnique.cpp b/OgreMain/src/OgreCompositionTechnique.cpp index cd527d90c41..f33a3012250 100644 --- a/OgreMain/src/OgreCompositionTechnique.cpp +++ b/OgreMain/src/OgreCompositionTechnique.cpp @@ -72,15 +72,15 @@ CompositionTechnique::TextureDefinition *CompositionTechnique::getTextureDefinit //--------------------------------------------------------------------- CompositionTechnique::TextureDefinition *CompositionTechnique::getTextureDefinition(const String& name) { - TextureDefinitions::iterator i, iend; - iend = mTextureDefinitions.end(); - for (i = mTextureDefinitions.begin(); i != iend; ++i) - { - if ((*i)->name == name) - return *i; - } + TextureDefinitions::iterator i, iend; + iend = mTextureDefinitions.end(); + for (i = mTextureDefinitions.begin(); i != iend; ++i) + { + if ((*i)->name == name) + return *i; + } - return 0; + return 0; } //----------------------------------------------------------------------- @@ -159,12 +159,12 @@ CompositionTargetPass *CompositionTechnique::getOutputTargetPass() //----------------------------------------------------------------------- bool CompositionTechnique::isSupported(bool acceptTextureDegradation) { - // A technique is supported if all materials referenced have a supported - // technique, and the intermediate texture formats requested are supported - // Material support is a cast-iron requirement, but if no texture formats - // are directly supported we can let the rendersystem create the closest - // match for the least demanding technique - + // A technique is supported if all materials referenced have a supported + // technique, and the intermediate texture formats requested are supported + // Material support is a cast-iron requirement, but if no texture formats + // are directly supported we can let the rendersystem create the closest + // match for the least demanding technique + // Check output target pass is supported if (!mOutputTarget->_isSupported()) @@ -186,62 +186,62 @@ bool CompositionTechnique::isSupported(bool acceptTextureDegradation) TextureDefinitions::iterator i, iend; iend = mTextureDefinitions.end(); - TextureManager& texMgr = TextureManager::getSingleton(); + TextureManager& texMgr = TextureManager::getSingleton(); for (i = mTextureDefinitions.begin(); i != iend; ++i) { - TextureDefinition* td = *i; + TextureDefinition* td = *i; - // Firstly check MRTs - if (td->formatList.size() > - Root::getSingleton().getRenderSystem()->getCapabilities()->getNumMultiRenderTargets()) - { - return false; - } + // Firstly check MRTs + if (td->formatList.size() > + Root::getSingleton().getRenderSystem()->getCapabilities()->getNumMultiRenderTargets()) + { + return false; + } - for (PixelFormatList::iterator pfi = td->formatList.begin(); pfi != td->formatList.end(); ++pfi) - { + for (PixelFormatList::iterator pfi = td->formatList.begin(); pfi != td->formatList.end(); ++pfi) + { - // Check whether equivalent supported - if(acceptTextureDegradation) - { - // Don't care about exact format so long as something is supported - if(texMgr.getNativeFormat(TEX_TYPE_2D, *pfi, TU_RENDERTARGET) == PF_UNKNOWN) - { - return false; - } - } - else - { - // Need a format which is the same number of bits to pass - if (!texMgr.isEquivalentFormatSupported(TEX_TYPE_2D, *pfi, TU_RENDERTARGET)) - { - return false; - } - } - } + // Check whether equivalent supported + if(acceptTextureDegradation) + { + // Don't care about exact format so long as something is supported + if(texMgr.getNativeFormat(TEX_TYPE_2D, *pfi, TU_RENDERTARGET) == PF_UNKNOWN) + { + return false; + } + } + else + { + // Need a format which is the same number of bits to pass + if (!texMgr.isEquivalentFormatSupported(TEX_TYPE_2D, *pfi, TU_RENDERTARGET)) + { + return false; + } + } + } - //Check all render targets have same number of bits - if( !Root::getSingleton().getRenderSystem()->getCapabilities()-> - hasCapability( RSC_MRT_DIFFERENT_BIT_DEPTHS ) && !td->formatList.empty() ) - { - PixelFormat nativeFormat = texMgr.getNativeFormat( TEX_TYPE_2D, td->formatList.front(), - TU_RENDERTARGET ); - size_t nativeBits = PixelUtil::getNumElemBits( nativeFormat ); - for( PixelFormatList::iterator pfi = td->formatList.begin()+1; - pfi != td->formatList.end(); ++pfi ) - { - PixelFormat nativeTmp = texMgr.getNativeFormat( TEX_TYPE_2D, *pfi, TU_RENDERTARGET ); - if( PixelUtil::getNumElemBits( nativeTmp ) != nativeBits ) - { - return false; - } - } - } - } - - // Must be ok - return true; + //Check all render targets have same number of bits + if( !Root::getSingleton().getRenderSystem()->getCapabilities()-> + hasCapability( RSC_MRT_DIFFERENT_BIT_DEPTHS ) && !td->formatList.empty() ) + { + PixelFormat nativeFormat = texMgr.getNativeFormat( TEX_TYPE_2D, td->formatList.front(), + TU_RENDERTARGET ); + size_t nativeBits = PixelUtil::getNumElemBits( nativeFormat ); + for( PixelFormatList::iterator pfi = td->formatList.begin()+1; + pfi != td->formatList.end(); ++pfi ) + { + PixelFormat nativeTmp = texMgr.getNativeFormat( TEX_TYPE_2D, *pfi, TU_RENDERTARGET ); + if( PixelUtil::getNumElemBits( nativeTmp ) != nativeBits ) + { + return false; + } + } + } + } + + // Must be ok + return true; } //----------------------------------------------------------------------- Compositor *CompositionTechnique::getParent() @@ -251,7 +251,7 @@ Compositor *CompositionTechnique::getParent() //--------------------------------------------------------------------- void CompositionTechnique::setSchemeName(const String& schemeName) { - mSchemeName = schemeName; + mSchemeName = schemeName; } } diff --git a/OgreMain/src/OgreCompositor.cpp b/OgreMain/src/OgreCompositor.cpp index 6b98bef0b92..4360a37dd6d 100644 --- a/OgreMain/src/OgreCompositor.cpp +++ b/OgreMain/src/OgreCompositor.cpp @@ -129,12 +129,12 @@ void Compositor::loadImpl(void) if (mCompilationRequired) compile(); - createGlobalTextures(); + createGlobalTextures(); } //----------------------------------------------------------------------- void Compositor::unloadImpl(void) { - freeGlobalTextures(); + freeGlobalTextures(); } //----------------------------------------------------------------------- size_t Compositor::calculateSize(void) const @@ -150,7 +150,7 @@ void Compositor::compile() Techniques::iterator i, iend; iend = mTechniques.end(); - // Try looking for exact technique support with no texture fallback + // Try looking for exact technique support with no texture fallback for (i = mTechniques.begin(); i != iend; ++i) { // Look for exact texture support first @@ -160,251 +160,251 @@ void Compositor::compile() } } - if (mSupportedTechniques.empty()) - { - // Check again, being more lenient with textures - for (i = mTechniques.begin(); i != iend; ++i) - { - // Allow texture support with degraded pixel format - if((*i)->isSupported(true)) - { - mSupportedTechniques.push_back(*i); - } - } - } - - mCompilationRequired = false; + if (mSupportedTechniques.empty()) + { + // Check again, being more lenient with textures + for (i = mTechniques.begin(); i != iend; ++i) + { + // Allow texture support with degraded pixel format + if((*i)->isSupported(true)) + { + mSupportedTechniques.push_back(*i); + } + } + } + + mCompilationRequired = false; } //--------------------------------------------------------------------- CompositionTechnique* Compositor::getSupportedTechnique(const String& schemeName) { - for(Techniques::iterator i = mSupportedTechniques.begin(); i != mSupportedTechniques.end(); ++i) - { - if ((*i)->getSchemeName() == schemeName) - { - return *i; - } - } - - // didn't find a matching one - for(Techniques::iterator i = mSupportedTechniques.begin(); i != mSupportedTechniques.end(); ++i) - { - if ((*i)->getSchemeName() == BLANKSTRING) - { - return *i; - } - } - - return 0; + for(Techniques::iterator i = mSupportedTechniques.begin(); i != mSupportedTechniques.end(); ++i) + { + if ((*i)->getSchemeName() == schemeName) + { + return *i; + } + } + + // didn't find a matching one + for(Techniques::iterator i = mSupportedTechniques.begin(); i != mSupportedTechniques.end(); ++i) + { + if ((*i)->getSchemeName() == BLANKSTRING) + { + return *i; + } + } + + return 0; } //----------------------------------------------------------------------- String getMRTTexLocalName(const String& baseName, size_t attachment) { - return baseName + "/" + StringConverter::toString(attachment); + return baseName + "/" + StringConverter::toString(attachment); } //----------------------------------------------------------------------- void Compositor::createGlobalTextures() { - static size_t dummyCounter = 0; - if (mSupportedTechniques.empty()) - return; - - //To make sure that we are consistent, it is demanded that all composition - //techniques define the same set of global textures. - - typedef set::type StringSet; - StringSet globalTextureNames; - - //Initialize global textures from first supported technique - CompositionTechnique* firstTechnique = mSupportedTechniques[0]; - - CompositionTechnique::TextureDefinitionIterator texDefIt = - firstTechnique->getTextureDefinitionIterator(); - while (texDefIt.hasMoreElements()) - { - CompositionTechnique::TextureDefinition* def = texDefIt.getNext(); - if (def->scope == CompositionTechnique::TS_GLOBAL) - { - //Check that this is a legit global texture - if (!def->refCompName.empty()) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Global compositor texture definition can not be a reference", - "Compositor::createGlobalTextures"); - } - if (def->width == 0 || def->height == 0) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Global compositor texture definition must have absolute size", - "Compositor::createGlobalTextures"); - } - if (def->pooled) - { - LogManager::getSingleton().logMessage( - "Pooling global compositor textures has no effect", LML_CRITICAL); - } - globalTextureNames.insert(def->name); - - //TODO GSOC : Heavy copy-pasting from CompositorInstance. How to we solve it? - - /// Make the tetxure - RenderTarget* rendTarget; - if (def->formatList.size() > 1) - { - String MRTbaseName = "c" + StringConverter::toString(dummyCounter++) + - "/" + mName + "/" + def->name; - MultiRenderTarget* mrt = - Root::getSingleton().getRenderSystem()->createMultiRenderTarget(MRTbaseName); - mGlobalMRTs[def->name] = mrt; - - // create and bind individual surfaces - size_t atch = 0; - for (PixelFormatList::iterator p = def->formatList.begin(); - p != def->formatList.end(); ++p, ++atch) - { - - String texname = MRTbaseName + "/" + StringConverter::toString(atch); - TexturePtr tex; - - tex = TextureManager::getSingleton().createManual( - texname, - ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - (uint)def->width, (uint)def->height, 0, *p, TU_RENDERTARGET, 0, - def->hwGammaWrite && !PixelUtil::isFloatingPoint(*p), def->fsaa); - - RenderTexture* rt = tex->getBuffer()->getRenderTarget(); - rt->setAutoUpdated(false); - mrt->bindSurface(atch, rt); - - // Also add to local textures so we can look up - String mrtLocalName = getMRTTexLocalName(def->name, atch); - mGlobalTextures[mrtLocalName] = tex; - - } - - rendTarget = mrt; - } - else - { - String texName = "c" + StringConverter::toString(dummyCounter++) + - "/" + mName + "/" + def->name; - - // space in the name mixup the cegui in the compositor demo - // this is an auto generated name - so no spaces can't hart us. - std::replace( texName.begin(), texName.end(), ' ', '_' ); - - TexturePtr tex; - tex = TextureManager::getSingleton().createManual( - texName, - ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - (uint)def->width, (uint)def->height, 0, def->formatList[0], TU_RENDERTARGET, 0, - def->hwGammaWrite && !PixelUtil::isFloatingPoint(def->formatList[0]), def->fsaa); - - - rendTarget = tex->getBuffer()->getRenderTarget(); - mGlobalTextures[def->name] = tex; - } - - //Set DepthBuffer pool for sharing - rendTarget->setDepthBufferPool( def->depthBufferId ); - } - } - - //Validate that all other supported techniques expose the same set of global textures. - for (size_t i=1; igetTextureDefinitionIterator(); - while (texDefIt.hasMoreElements()) - { - CompositionTechnique::TextureDefinition* texDef = texDefIt.getNext(); - if (texDef->scope == CompositionTechnique::TS_GLOBAL) - { - if (globalTextureNames.find(texDef->name) == globalTextureNames.end()) - { - isConsistent = false; - break; - } - numGlobals++; - } - } - if (numGlobals != globalTextureNames.size()) - isConsistent = false; - - if (!isConsistent) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Different composition techniques define different global textures", - "Compositor::createGlobalTextures"); - } - - } - + static size_t dummyCounter = 0; + if (mSupportedTechniques.empty()) + return; + + //To make sure that we are consistent, it is demanded that all composition + //techniques define the same set of global textures. + + typedef set::type StringSet; + StringSet globalTextureNames; + + //Initialize global textures from first supported technique + CompositionTechnique* firstTechnique = mSupportedTechniques[0]; + + CompositionTechnique::TextureDefinitionIterator texDefIt = + firstTechnique->getTextureDefinitionIterator(); + while (texDefIt.hasMoreElements()) + { + CompositionTechnique::TextureDefinition* def = texDefIt.getNext(); + if (def->scope == CompositionTechnique::TS_GLOBAL) + { + //Check that this is a legit global texture + if (!def->refCompName.empty()) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Global compositor texture definition can not be a reference", + "Compositor::createGlobalTextures"); + } + if (def->width == 0 || def->height == 0) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Global compositor texture definition must have absolute size", + "Compositor::createGlobalTextures"); + } + if (def->pooled) + { + LogManager::getSingleton().logMessage( + "Pooling global compositor textures has no effect", LML_CRITICAL); + } + globalTextureNames.insert(def->name); + + //TODO GSOC : Heavy copy-pasting from CompositorInstance. How to we solve it? + + /// Make the tetxure + RenderTarget* rendTarget; + if (def->formatList.size() > 1) + { + String MRTbaseName = "c" + StringConverter::toString(dummyCounter++) + + "/" + mName + "/" + def->name; + MultiRenderTarget* mrt = + Root::getSingleton().getRenderSystem()->createMultiRenderTarget(MRTbaseName); + mGlobalMRTs[def->name] = mrt; + + // create and bind individual surfaces + size_t atch = 0; + for (PixelFormatList::iterator p = def->formatList.begin(); + p != def->formatList.end(); ++p, ++atch) + { + + String texname = MRTbaseName + "/" + StringConverter::toString(atch); + TexturePtr tex; + + tex = TextureManager::getSingleton().createManual( + texname, + ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, + (uint)def->width, (uint)def->height, 0, *p, TU_RENDERTARGET, 0, + def->hwGammaWrite && !PixelUtil::isFloatingPoint(*p), def->fsaa); + + RenderTexture* rt = tex->getBuffer()->getRenderTarget(); + rt->setAutoUpdated(false); + mrt->bindSurface(atch, rt); + + // Also add to local textures so we can look up + String mrtLocalName = getMRTTexLocalName(def->name, atch); + mGlobalTextures[mrtLocalName] = tex; + + } + + rendTarget = mrt; + } + else + { + String texName = "c" + StringConverter::toString(dummyCounter++) + + "/" + mName + "/" + def->name; + + // space in the name mixup the cegui in the compositor demo + // this is an auto generated name - so no spaces can't hart us. + std::replace( texName.begin(), texName.end(), ' ', '_' ); + + TexturePtr tex; + tex = TextureManager::getSingleton().createManual( + texName, + ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, + (uint)def->width, (uint)def->height, 0, def->formatList[0], TU_RENDERTARGET, 0, + def->hwGammaWrite && !PixelUtil::isFloatingPoint(def->formatList[0]), def->fsaa); + + + rendTarget = tex->getBuffer()->getRenderTarget(); + mGlobalTextures[def->name] = tex; + } + + //Set DepthBuffer pool for sharing + rendTarget->setDepthBufferPool( def->depthBufferId ); + } + } + + //Validate that all other supported techniques expose the same set of global textures. + for (size_t i=1; igetTextureDefinitionIterator(); + while (texDefIt.hasMoreElements()) + { + CompositionTechnique::TextureDefinition* texDef = texDefIt.getNext(); + if (texDef->scope == CompositionTechnique::TS_GLOBAL) + { + if (globalTextureNames.find(texDef->name) == globalTextureNames.end()) + { + isConsistent = false; + break; + } + numGlobals++; + } + } + if (numGlobals != globalTextureNames.size()) + isConsistent = false; + + if (!isConsistent) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Different composition techniques define different global textures", + "Compositor::createGlobalTextures"); + } + + } + } //----------------------------------------------------------------------- void Compositor::freeGlobalTextures() { - GlobalTextureMap::iterator i = mGlobalTextures.begin(); - while (i != mGlobalTextures.end()) - { - TextureManager::getSingleton().remove(i->second->getName()); - ++i; - } - mGlobalTextures.clear(); - - GlobalMRTMap::iterator mrti = mGlobalMRTs.begin(); - while (mrti != mGlobalMRTs.end()) - { - // remove MRT - Root::getSingleton().getRenderSystem()->destroyRenderTarget(mrti->second->getName()); - ++mrti; - } - mGlobalMRTs.clear(); + GlobalTextureMap::iterator i = mGlobalTextures.begin(); + while (i != mGlobalTextures.end()) + { + TextureManager::getSingleton().remove(i->second->getName()); + ++i; + } + mGlobalTextures.clear(); + + GlobalMRTMap::iterator mrti = mGlobalMRTs.begin(); + while (mrti != mGlobalMRTs.end()) + { + // remove MRT + Root::getSingleton().getRenderSystem()->destroyRenderTarget(mrti->second->getName()); + ++mrti; + } + mGlobalMRTs.clear(); } //----------------------------------------------------------------------- const String& Compositor::getTextureInstanceName(const String& name, size_t mrtIndex) { - return getTextureInstance(name, mrtIndex)->getName(); + return getTextureInstance(name, mrtIndex)->getName(); } -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- TexturePtr Compositor::getTextureInstance(const String& name, size_t mrtIndex) { - //Try simple texture - GlobalTextureMap::iterator i = mGlobalTextures.find(name); - if(i != mGlobalTextures.end()) - { - return i->second; - } - //Try MRT - String mrtName = getMRTTexLocalName(name, mrtIndex); - i = mGlobalTextures.find(mrtName); - if(i != mGlobalTextures.end()) - { - return i->second; - } - - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Non-existent global texture name", - "Compositor::getTextureInstance") + //Try simple texture + GlobalTextureMap::iterator i = mGlobalTextures.find(name); + if(i != mGlobalTextures.end()) + { + return i->second; + } + //Try MRT + String mrtName = getMRTTexLocalName(name, mrtIndex); + i = mGlobalTextures.find(mrtName); + if(i != mGlobalTextures.end()) + { + return i->second; + } + + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Non-existent global texture name", + "Compositor::getTextureInstance") } //--------------------------------------------------------------------- RenderTarget* Compositor::getRenderTarget(const String& name) { - // try simple texture - GlobalTextureMap::iterator i = mGlobalTextures.find(name); + // try simple texture + GlobalTextureMap::iterator i = mGlobalTextures.find(name); if(i != mGlobalTextures.end()) - return i->second->getBuffer()->getRenderTarget(); - - // try MRTs - GlobalMRTMap::iterator mi = mGlobalMRTs.find(name); - if (mi != mGlobalMRTs.end()) - return mi->second; - else - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Non-existent global texture name", - "Compositor::getRenderTarget"); + return i->second->getBuffer()->getRenderTarget(); + + // try MRTs + GlobalMRTMap::iterator mi = mGlobalMRTs.find(name); + if (mi != mGlobalMRTs.end()) + return mi->second; + else + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Non-existent global texture name", + "Compositor::getRenderTarget"); } //--------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreCompositorChain.cpp b/OgreMain/src/OgreCompositorChain.cpp index 9640e25a32f..0fdf47ab797 100644 --- a/OgreMain/src/OgreCompositorChain.cpp +++ b/OgreMain/src/OgreCompositorChain.cpp @@ -42,36 +42,36 @@ THE SOFTWARE. namespace Ogre { CompositorChain::CompositorChain(Viewport *vp): mViewport(vp), - mOriginalScene(0), + mOriginalScene(0), mDirty(true), - mAnyCompositorsEnabled(false) + mAnyCompositorsEnabled(false) { - assert(vp); - mOldClearEveryFrameBuffers = vp->getClearBuffers(); - vp->addListener(this); + assert(vp); + mOldClearEveryFrameBuffers = vp->getClearBuffers(); + vp->addListener(this); - createOriginalScene(); - vp->getTarget()->addListener(this); + createOriginalScene(); + vp->getTarget()->addListener(this); } //----------------------------------------------------------------------- CompositorChain::~CompositorChain() { - destroyResources(); + destroyResources(); } //----------------------------------------------------------------------- void CompositorChain::destroyResources(void) { - clearCompiledState(); + clearCompiledState(); - if (mViewport) - { - mViewport->getTarget()->removeListener(this); - mViewport->removeListener(this); - removeAllCompositors(); - destroyOriginalScene(); + if (mViewport) + { + mViewport->getTarget()->removeListener(this); + mViewport->removeListener(this); + removeAllCompositors(); + destroyOriginalScene(); - mViewport = 0; - } + mViewport = 0; + } } //----------------------------------------------------------------------- void CompositorChain::createOriginalScene() @@ -85,14 +85,14 @@ void CompositorChain::createOriginalScene() { target_output { - pass clear - { - /// Clear frame - } + pass clear + { + /// Clear frame + } pass render_scene { - visibility_mask FFFFFFFF - render_queues SKIES_EARLY SKIES_LATE + visibility_mask FFFFFFFF + render_queues SKIES_EARLY SKIES_LATE } } } @@ -102,49 +102,49 @@ void CompositorChain::createOriginalScene() // If two viewports use the same scheme but differ in settings like visibility masks, shadows, etc we don't // want compositors to share their technique. Otherwise both compositors will have to recompile every time they // render. Thus we generate a unique compositor per viewport. - String compName("Ogre/Scene/"); + String compName("Ogre/Scene/"); compName += StringConverter::toString((size_t)mViewport); - mOriginalSceneScheme = mViewport->getMaterialScheme(); - CompositorPtr scene = CompositorManager::getSingleton().getByName(compName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); - if (scene.isNull()) - { - scene = CompositorManager::getSingleton().create(compName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); - CompositionTechnique *t = scene->createTechnique(); - t->setSchemeName(BLANKSTRING); - CompositionTargetPass *tp = t->getOutputTargetPass(); - tp->setVisibilityMask(0xFFFFFFFF); - { - CompositionPass *pass = tp->createPass(); - pass->setType(CompositionPass::PT_CLEAR); - } - { - CompositionPass *pass = tp->createPass(); - pass->setType(CompositionPass::PT_RENDERSCENE); - /// Render everything, including skies - pass->setFirstRenderQueue(RENDER_QUEUE_BACKGROUND); - pass->setLastRenderQueue(RENDER_QUEUE_SKIES_LATE); - } + mOriginalSceneScheme = mViewport->getMaterialScheme(); + CompositorPtr scene = CompositorManager::getSingleton().getByName(compName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + if (scene.isNull()) + { + scene = CompositorManager::getSingleton().create(compName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + CompositionTechnique *t = scene->createTechnique(); + t->setSchemeName(BLANKSTRING); + CompositionTargetPass *tp = t->getOutputTargetPass(); + tp->setVisibilityMask(0xFFFFFFFF); + { + CompositionPass *pass = tp->createPass(); + pass->setType(CompositionPass::PT_CLEAR); + } + { + CompositionPass *pass = tp->createPass(); + pass->setType(CompositionPass::PT_RENDERSCENE); + /// Render everything, including skies + pass->setFirstRenderQueue(RENDER_QUEUE_BACKGROUND); + pass->setLastRenderQueue(RENDER_QUEUE_SKIES_LATE); + } - /// Create base "original scene" compositor - scene = CompositorManager::getSingleton().load(compName, - ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME).staticCast(); + /// Create base "original scene" compositor + scene = CompositorManager::getSingleton().load(compName, + ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME).staticCast(); - } - mOriginalScene = OGRE_NEW CompositorInstance(scene->getSupportedTechnique(), this); + } + mOriginalScene = OGRE_NEW CompositorInstance(scene->getSupportedTechnique(), this); } //----------------------------------------------------------------------- void CompositorChain::destroyOriginalScene() { - /// Destroy "original scene" compositor instance - if (mOriginalScene) - { - OGRE_DELETE mOriginalScene; - mOriginalScene = 0; - } + /// Destroy "original scene" compositor instance + if (mOriginalScene) + { + OGRE_DELETE mOriginalScene; + mOriginalScene = 0; + } } //----------------------------------------------------------------------- @@ -152,16 +152,16 @@ CompositorInstance* CompositorChain::addCompositor(CompositorPtr filter, size_t { - filter->touch(); + filter->touch(); CompositionTechnique *tech = filter->getSupportedTechnique(scheme); - if(!tech) - { - /// Warn user - LogManager::getSingleton().logMessage( - "CompositorChain: Compositor " + filter->getName() + " has no supported techniques.", LML_CRITICAL - ); - return 0; - } + if(!tech) + { + /// Warn user + LogManager::getSingleton().logMessage( + "CompositorChain: Compositor " + filter->getName() + " has no supported techniques.", LML_CRITICAL + ); + return 0; + } CompositorInstance *t = OGRE_NEW CompositorInstance(tech, this); if(addPosition == LAST) @@ -171,7 +171,7 @@ CompositorInstance* CompositorChain::addCompositor(CompositorPtr filter, size_t mInstances.insert(mInstances.begin()+addPosition, t); mDirty = true; - mAnyCompositorsEnabled = true; + mAnyCompositorsEnabled = true; return t; } //----------------------------------------------------------------------- @@ -196,7 +196,7 @@ void CompositorChain::removeAllCompositors() iend = mInstances.end(); for (i = mInstances.begin(); i != iend; ++i) { - OGRE_DELETE *i; + OGRE_DELETE *i; } mInstances.clear(); @@ -205,13 +205,13 @@ void CompositorChain::removeAllCompositors() //----------------------------------------------------------------------- void CompositorChain::_removeInstance(CompositorInstance *i) { - mInstances.erase(std::find(mInstances.begin(), mInstances.end(), i)); - OGRE_DELETE i; + mInstances.erase(std::find(mInstances.begin(), mInstances.end(), i)); + OGRE_DELETE i; } //----------------------------------------------------------------------- void CompositorChain::_queuedOperation(CompositorInstance::RenderSystemOperation* op) { - mRenderSystemOperations.push_back(op); + mRenderSystemOperations.push_back(op); } //----------------------------------------------------------------------- @@ -223,14 +223,14 @@ CompositorInstance *CompositorChain::getCompositor(size_t index) //----------------------------------------------------------------------- CompositorInstance *CompositorChain::getCompositor(const String& name) { - for (Instances::iterator it = mInstances.begin(); it != mInstances.end(); ++it) - { - if ((*it)->getCompositor()->getName() == name) - { - return *it; - } - } - return 0; + for (Instances::iterator it = mInstances.begin(); it != mInstances.end(); ++it) + { + if ((*it)->getCompositor()->getName() == name) + { + return *it; + } + } + return 0; } //----------------------------------------------------------------------- CompositorChain::InstanceIterator CompositorChain::getCompositors() @@ -240,69 +240,69 @@ CompositorChain::InstanceIterator CompositorChain::getCompositors() //----------------------------------------------------------------------- void CompositorChain::setCompositorEnabled(size_t position, bool state) { - CompositorInstance* inst = getCompositor(position); - if (!state && inst->getEnabled()) - { - // If we're disabling a 'middle' compositor in a chain, we have to be - // careful about textures which might have been shared by non-adjacent - // instances which have now become adjacent. - CompositorInstance* nextInstance = getNextInstance(inst, true); - if (nextInstance) - { - CompositionTechnique::TargetPassIterator tpit = nextInstance->getTechnique()->getTargetPassIterator(); - while(tpit.hasMoreElements()) - { - CompositionTargetPass* tp = tpit.getNext(); - if (tp->getInputMode() == CompositionTargetPass::IM_PREVIOUS) - { - if (nextInstance->getTechnique()->getTextureDefinition(tp->getOutputName())->pooled) - { - // recreate - nextInstance->freeResources(false, true); - nextInstance->createResources(false); - } - } - - } - } - - } + CompositorInstance* inst = getCompositor(position); + if (!state && inst->getEnabled()) + { + // If we're disabling a 'middle' compositor in a chain, we have to be + // careful about textures which might have been shared by non-adjacent + // instances which have now become adjacent. + CompositorInstance* nextInstance = getNextInstance(inst, true); + if (nextInstance) + { + CompositionTechnique::TargetPassIterator tpit = nextInstance->getTechnique()->getTargetPassIterator(); + while(tpit.hasMoreElements()) + { + CompositionTargetPass* tp = tpit.getNext(); + if (tp->getInputMode() == CompositionTargetPass::IM_PREVIOUS) + { + if (nextInstance->getTechnique()->getTextureDefinition(tp->getOutputName())->pooled) + { + // recreate + nextInstance->freeResources(false, true); + nextInstance->createResources(false); + } + } + + } + } + + } inst->setEnabled(state); } //----------------------------------------------------------------------- void CompositorChain::preRenderTargetUpdate(const RenderTargetEvent& evt) { - /// Compile if state is dirty - if(mDirty) - _compile(); + /// Compile if state is dirty + if(mDirty) + _compile(); - // Do nothing if no compositors enabled - if (!mAnyCompositorsEnabled) - { - return; - } + // Do nothing if no compositors enabled + if (!mAnyCompositorsEnabled) + { + return; + } - /// Update dependent render targets; this is done in the preRenderTarget - /// and not the preViewportUpdate for a reason: at this time, the - /// target Rendertarget will not yet have been set as current. - /// ( RenderSystem::setViewport(...) ) if it would have been, the rendering - /// order would be screwed up and problems would arise with copying rendertextures. - Camera *cam = mViewport->getCamera(); - if (cam) - { - cam->getSceneManager()->_setActiveCompositorChain(this); - } + /// Update dependent render targets; this is done in the preRenderTarget + /// and not the preViewportUpdate for a reason: at this time, the + /// target Rendertarget will not yet have been set as current. + /// ( RenderSystem::setViewport(...) ) if it would have been, the rendering + /// order would be screwed up and problems would arise with copying rendertextures. + Camera *cam = mViewport->getCamera(); + if (cam) + { + cam->getSceneManager()->_setActiveCompositorChain(this); + } /// Iterate over compiled state CompositorInstance::CompiledState::iterator i; for(i=mCompiledState.begin(); i!=mCompiledState.end(); ++i) { - /// Skip if this is a target that should only be initialised initially - if(i->onlyInitial && i->hasBeenRendered) - continue; - i->hasBeenRendered = true; - /// Setup and render + /// Skip if this is a target that should only be initialised initially + if(i->onlyInitial && i->hasBeenRendered) + continue; + i->hasBeenRendered = true; + /// Setup and render preTargetOperation(*i, i->target->getViewport(0), cam); i->target->update(); postTargetOperation(*i, i->target->getViewport(0), cam); @@ -311,74 +311,74 @@ void CompositorChain::preRenderTargetUpdate(const RenderTargetEvent& evt) //----------------------------------------------------------------------- void CompositorChain::postRenderTargetUpdate(const RenderTargetEvent& evt) { - Camera *cam = mViewport->getCamera(); - if (cam) - { - cam->getSceneManager()->_setActiveCompositorChain(0); - } + Camera *cam = mViewport->getCamera(); + if (cam) + { + cam->getSceneManager()->_setActiveCompositorChain(0); + } } //----------------------------------------------------------------------- void CompositorChain::preViewportUpdate(const RenderTargetViewportEvent& evt) { - // Only set up if there is at least one compositor enabled, and it's this viewport + // Only set up if there is at least one compositor enabled, and it's this viewport if(evt.source != mViewport || !mAnyCompositorsEnabled) return; - // set original scene details from viewport - CompositionPass* pass = mOriginalScene->getTechnique()->getOutputTargetPass()->getPass(0); - CompositionTargetPass* passParent = pass->getParent(); - if (pass->getClearBuffers() != mViewport->getClearBuffers() || - pass->getClearColour() != mViewport->getBackgroundColour() || - pass->getClearDepth() != mViewport->getDepthClear() || - passParent->getVisibilityMask() != mViewport->getVisibilityMask() || - passParent->getMaterialScheme() != mViewport->getMaterialScheme() || - passParent->getShadowsEnabled() != mViewport->getShadowsEnabled()) - { - // recompile if viewport settings are different - pass->setClearBuffers(mViewport->getClearBuffers()); - pass->setClearColour(mViewport->getBackgroundColour()); - pass->setClearDepth(mViewport->getDepthClear()); - passParent->setVisibilityMask(mViewport->getVisibilityMask()); - passParent->setMaterialScheme(mViewport->getMaterialScheme()); - passParent->setShadowsEnabled(mViewport->getShadowsEnabled()); - _compile(); - } - - Camera *cam = mViewport->getCamera(); - if (cam) - { - /// Prepare for output operation - preTargetOperation(mOutputOperation, mViewport, cam); - } + // set original scene details from viewport + CompositionPass* pass = mOriginalScene->getTechnique()->getOutputTargetPass()->getPass(0); + CompositionTargetPass* passParent = pass->getParent(); + if (pass->getClearBuffers() != mViewport->getClearBuffers() || + pass->getClearColour() != mViewport->getBackgroundColour() || + pass->getClearDepth() != mViewport->getDepthClear() || + passParent->getVisibilityMask() != mViewport->getVisibilityMask() || + passParent->getMaterialScheme() != mViewport->getMaterialScheme() || + passParent->getShadowsEnabled() != mViewport->getShadowsEnabled()) + { + // recompile if viewport settings are different + pass->setClearBuffers(mViewport->getClearBuffers()); + pass->setClearColour(mViewport->getBackgroundColour()); + pass->setClearDepth(mViewport->getDepthClear()); + passParent->setVisibilityMask(mViewport->getVisibilityMask()); + passParent->setMaterialScheme(mViewport->getMaterialScheme()); + passParent->setShadowsEnabled(mViewport->getShadowsEnabled()); + _compile(); + } + + Camera *cam = mViewport->getCamera(); + if (cam) + { + /// Prepare for output operation + preTargetOperation(mOutputOperation, mViewport, cam); + } } //----------------------------------------------------------------------- void CompositorChain::preTargetOperation(CompositorInstance::TargetOperation &op, Viewport *vp, Camera *cam) { - if (cam) - { - SceneManager *sm = cam->getSceneManager(); - /// Set up render target listener - mOurListener.setOperation(&op, sm, sm->getDestinationRenderSystem()); - mOurListener.notifyViewport(vp); - /// Register it - sm->addRenderQueueListener(&mOurListener); - /// Set whether we find visibles - mOldFindVisibleObjects = sm->getFindVisibleObjects(); - sm->setFindVisibleObjects(op.findVisibleObjects); - /// Set LOD bias level - mOldLodBias = cam->getLodBias(); - cam->setLodBias(cam->getLodBias() * op.lodBias); - } + if (cam) + { + SceneManager *sm = cam->getSceneManager(); + /// Set up render target listener + mOurListener.setOperation(&op, sm, sm->getDestinationRenderSystem()); + mOurListener.notifyViewport(vp); + /// Register it + sm->addRenderQueueListener(&mOurListener); + /// Set whether we find visibles + mOldFindVisibleObjects = sm->getFindVisibleObjects(); + sm->setFindVisibleObjects(op.findVisibleObjects); + /// Set LOD bias level + mOldLodBias = cam->getLodBias(); + cam->setLodBias(cam->getLodBias() * op.lodBias); + } // Set the visibility mask mOldVisibilityMask = vp->getVisibilityMask(); vp->setVisibilityMask(op.visibilityMask); - /// Set material scheme - mOldMaterialScheme = vp->getMaterialScheme(); - vp->setMaterialScheme(op.materialScheme); - /// Set shadows enabled - mOldShadowsEnabled = vp->getShadowsEnabled(); - vp->setShadowsEnabled(op.shadowsEnabled); + /// Set material scheme + mOldMaterialScheme = vp->getMaterialScheme(); + vp->setMaterialScheme(op.materialScheme); + /// Set shadows enabled + mOldShadowsEnabled = vp->getShadowsEnabled(); + vp->setShadowsEnabled(op.shadowsEnabled); /// XXX TODO //vp->setClearEveryFrame( true ); //vp->setOverlaysEnabled( false ); @@ -387,101 +387,101 @@ void CompositorChain::preTargetOperation(CompositorInstance::TargetOperation &op //----------------------------------------------------------------------- void CompositorChain::postTargetOperation(CompositorInstance::TargetOperation &op, Viewport *vp, Camera *cam) { - if (cam) - { - SceneManager *sm = cam->getSceneManager(); - /// Unregister our listener - sm->removeRenderQueueListener(&mOurListener); - /// Restore default scene and camera settings - sm->setFindVisibleObjects(mOldFindVisibleObjects); - cam->setLodBias(mOldLodBias); - } + if (cam) + { + SceneManager *sm = cam->getSceneManager(); + /// Unregister our listener + sm->removeRenderQueueListener(&mOurListener); + /// Restore default scene and camera settings + sm->setFindVisibleObjects(mOldFindVisibleObjects); + cam->setLodBias(mOldLodBias); + } vp->setVisibilityMask(mOldVisibilityMask); - vp->setMaterialScheme(mOldMaterialScheme); - vp->setShadowsEnabled(mOldShadowsEnabled); + vp->setMaterialScheme(mOldMaterialScheme); + vp->setShadowsEnabled(mOldShadowsEnabled); } //----------------------------------------------------------------------- void CompositorChain::postViewportUpdate(const RenderTargetViewportEvent& evt) { - // Only tidy up if there is at least one compositor enabled, and it's this viewport + // Only tidy up if there is at least one compositor enabled, and it's this viewport if(evt.source != mViewport || !mAnyCompositorsEnabled) return; - Camera *cam = mViewport->getCamera(); - postTargetOperation(mOutputOperation, mViewport, cam); + Camera *cam = mViewport->getCamera(); + postTargetOperation(mOutputOperation, mViewport, cam); } //----------------------------------------------------------------------- void CompositorChain::viewportCameraChanged(Viewport* viewport) { - Camera* camera = viewport->getCamera(); - size_t count = mInstances.size(); - for (size_t i = 0; i < count; ++i) - { - mInstances[i]->notifyCameraChanged(camera); - } + Camera* camera = viewport->getCamera(); + size_t count = mInstances.size(); + for (size_t i = 0; i < count; ++i) + { + mInstances[i]->notifyCameraChanged(camera); + } } //----------------------------------------------------------------------- void CompositorChain::viewportDimensionsChanged(Viewport* viewport) { - size_t count = mInstances.size(); - for (size_t i = 0; i < count; ++i) - { - mInstances[i]->notifyResized(); - } + size_t count = mInstances.size(); + for (size_t i = 0; i < count; ++i) + { + mInstances[i]->notifyResized(); + } } //----------------------------------------------------------------------- void CompositorChain::viewportDestroyed(Viewport* viewport) { - // this chain is now orphaned. tell compositor manager to delete it. - CompositorManager::getSingleton().removeCompositorChain(viewport); + // this chain is now orphaned. tell compositor manager to delete it. + CompositorManager::getSingleton().removeCompositorChain(viewport); } //----------------------------------------------------------------------- void CompositorChain::clearCompiledState() { - for (RenderSystemOperations::iterator i = mRenderSystemOperations.begin(); - i != mRenderSystemOperations.end(); ++i) - { - OGRE_DELETE *i; - } - mRenderSystemOperations.clear(); + for (RenderSystemOperations::iterator i = mRenderSystemOperations.begin(); + i != mRenderSystemOperations.end(); ++i) + { + OGRE_DELETE *i; + } + mRenderSystemOperations.clear(); - /// Clear compiled state - mCompiledState.clear(); - mOutputOperation = CompositorInstance::TargetOperation(0); + /// Clear compiled state + mCompiledState.clear(); + mOutputOperation = CompositorInstance::TargetOperation(0); } //----------------------------------------------------------------------- void CompositorChain::_compile() { - // remove original scene if it has the wrong material scheme - if( mOriginalSceneScheme != mViewport->getMaterialScheme() ) - { - destroyOriginalScene(); - createOriginalScene(); - } + // remove original scene if it has the wrong material scheme + if( mOriginalSceneScheme != mViewport->getMaterialScheme() ) + { + destroyOriginalScene(); + createOriginalScene(); + } - clearCompiledState(); + clearCompiledState(); - bool compositorsEnabled = false; + bool compositorsEnabled = false; - // force default scheme so materials for compositor quads will determined correctly - MaterialManager& matMgr = MaterialManager::getSingleton(); - String prevMaterialScheme = matMgr.getActiveScheme(); - matMgr.setActiveScheme(MaterialManager::DEFAULT_SCHEME_NAME); - + // force default scheme so materials for compositor quads will determined correctly + MaterialManager& matMgr = MaterialManager::getSingleton(); + String prevMaterialScheme = matMgr.getActiveScheme(); + matMgr.setActiveScheme(MaterialManager::DEFAULT_SCHEME_NAME); + /// Set previous CompositorInstance for each compositor in the list CompositorInstance *lastComposition = mOriginalScene; - mOriginalScene->mPreviousInstance = 0; - CompositionPass* pass = mOriginalScene->getTechnique()->getOutputTargetPass()->getPass(0); - pass->setClearBuffers(mViewport->getClearBuffers()); - pass->setClearColour(mViewport->getBackgroundColour()); - pass->setClearDepth(mViewport->getDepthClear()); + mOriginalScene->mPreviousInstance = 0; + CompositionPass* pass = mOriginalScene->getTechnique()->getOutputTargetPass()->getPass(0); + pass->setClearBuffers(mViewport->getClearBuffers()); + pass->setClearColour(mViewport->getBackgroundColour()); + pass->setClearDepth(mViewport->getDepthClear()); for(Instances::iterator i=mInstances.begin(); i!=mInstances.end(); ++i) { if((*i)->getEnabled()) { - compositorsEnabled = true; + compositorsEnabled = true; (*i)->mPreviousInstance = lastComposition; lastComposition = (*i); } @@ -492,30 +492,30 @@ void CompositorChain::_compile() lastComposition->_compileTargetOperations(mCompiledState); /// Final target viewport (0) - mOutputOperation.renderSystemOperations.clear(); + mOutputOperation.renderSystemOperations.clear(); lastComposition->_compileOutputOperation(mOutputOperation); - // Deal with viewport settings - if (compositorsEnabled != mAnyCompositorsEnabled) - { - mAnyCompositorsEnabled = compositorsEnabled; - if (mAnyCompositorsEnabled) - { - // Save old viewport clearing options - mOldClearEveryFrameBuffers = mViewport->getClearBuffers(); - // Don't clear anything every frame since we have our own clear ops - mViewport->setClearEveryFrame(false); - } - else - { - // Reset clearing options - mViewport->setClearEveryFrame(mOldClearEveryFrameBuffers > 0, - mOldClearEveryFrameBuffers); - } - } - - // restore material scheme - matMgr.setActiveScheme(prevMaterialScheme); + // Deal with viewport settings + if (compositorsEnabled != mAnyCompositorsEnabled) + { + mAnyCompositorsEnabled = compositorsEnabled; + if (mAnyCompositorsEnabled) + { + // Save old viewport clearing options + mOldClearEveryFrameBuffers = mViewport->getClearBuffers(); + // Don't clear anything every frame since we have our own clear ops + mViewport->setClearEveryFrame(false); + } + else + { + // Reset clearing options + mViewport->setClearEveryFrame(mOldClearEveryFrameBuffers > 0, + mOldClearEveryFrameBuffers); + } + } + + // restore material scheme + matMgr.setActiveScheme(prevMaterialScheme); mDirty = false; @@ -533,103 +533,103 @@ Viewport *CompositorChain::getViewport() //--------------------------------------------------------------------- void CompositorChain::_notifyViewport(Viewport* vp) { - if (vp != mViewport) - { - if (mViewport != NULL) - mViewport->removeListener(this); + if (vp != mViewport) + { + if (mViewport != NULL) + mViewport->removeListener(this); - if (vp != NULL) - vp->addListener(this); - - if (vp->getTarget() != mViewport->getTarget()) - { - mViewport->getTarget()->removeListener(this); - vp->getTarget()->addListener(this); - } - mOurListener.notifyViewport(vp); - mViewport = vp; - } + if (vp != NULL) + vp->addListener(this); + + if (vp->getTarget() != mViewport->getTarget()) + { + mViewport->getTarget()->removeListener(this); + vp->getTarget()->addListener(this); + } + mOurListener.notifyViewport(vp); + mViewport = vp; + } } //----------------------------------------------------------------------- void CompositorChain::RQListener::renderQueueStarted(uint8 id, - const String& invocation, bool& skipThisQueue) + const String& invocation, bool& skipThisQueue) { - // Skip when not matching viewport - // shadows update is nested within main viewport update - if (mSceneManager->getCurrentViewport() != mViewport) - return; + // Skip when not matching viewport + // shadows update is nested within main viewport update + if (mSceneManager->getCurrentViewport() != mViewport) + return; - flushUpTo(id); - /// If no one wants to render this queue, skip it - /// Don't skip the OVERLAY queue because that's handled separately - if(!mOperation->renderQueues.test(id) && id!=RENDER_QUEUE_OVERLAY) - { - skipThisQueue = true; - } + flushUpTo(id); + /// If no one wants to render this queue, skip it + /// Don't skip the OVERLAY queue because that's handled separately + if(!mOperation->renderQueues.test(id) && id!=RENDER_QUEUE_OVERLAY) + { + skipThisQueue = true; + } } //----------------------------------------------------------------------- void CompositorChain::RQListener::renderQueueEnded(uint8 id, - const String& invocation, bool& repeatThisQueue) + const String& invocation, bool& repeatThisQueue) { } //----------------------------------------------------------------------- void CompositorChain::RQListener::setOperation(CompositorInstance::TargetOperation *op,SceneManager *sm,RenderSystem *rs) { - mOperation = op; - mSceneManager = sm; - mRenderSystem = rs; - currentOp = op->renderSystemOperations.begin(); - lastOp = op->renderSystemOperations.end(); + mOperation = op; + mSceneManager = sm; + mRenderSystem = rs; + currentOp = op->renderSystemOperations.begin(); + lastOp = op->renderSystemOperations.end(); } //----------------------------------------------------------------------- void CompositorChain::RQListener::flushUpTo(uint8 id) { - /// Process all RenderSystemOperations up to and including render queue id. + /// Process all RenderSystemOperations up to and including render queue id. /// Including, because the operations for RenderQueueGroup x should be executed - /// at the beginning of the RenderQueueGroup render for x. - while(currentOp != lastOp && currentOp->first <= id) - { - currentOp->second->execute(mSceneManager, mRenderSystem); - ++currentOp; - } + /// at the beginning of the RenderQueueGroup render for x. + while(currentOp != lastOp && currentOp->first <= id) + { + currentOp->second->execute(mSceneManager, mRenderSystem); + ++currentOp; + } } //----------------------------------------------------------------------- CompositorInstance* CompositorChain::getPreviousInstance(CompositorInstance* curr, bool activeOnly) { - bool found = false; - for(Instances::reverse_iterator i=mInstances.rbegin(); i!=mInstances.rend(); ++i) - { - if (found) - { - if ((*i)->getEnabled() || !activeOnly) - return *i; - } - else if(*i == curr) - { - found = true; - } - } - - return 0; + bool found = false; + for(Instances::reverse_iterator i=mInstances.rbegin(); i!=mInstances.rend(); ++i) + { + if (found) + { + if ((*i)->getEnabled() || !activeOnly) + return *i; + } + else if(*i == curr) + { + found = true; + } + } + + return 0; } //--------------------------------------------------------------------- CompositorInstance* CompositorChain::getNextInstance(CompositorInstance* curr, bool activeOnly) { - bool found = false; - for(Instances::iterator i=mInstances.begin(); i!=mInstances.end(); ++i) - { - if (found) - { - if ((*i)->getEnabled() || !activeOnly) - return *i; - } - else if(*i == curr) - { - found = true; - } - } - - return 0; + bool found = false; + for(Instances::iterator i=mInstances.begin(); i!=mInstances.end(); ++i) + { + if (found) + { + if ((*i)->getEnabled() || !activeOnly) + return *i; + } + else if(*i == curr) + { + found = true; + } + } + + return 0; } //--------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreCompositorInstance.cpp b/OgreMain/src/OgreCompositorInstance.cpp index 8ee08f98a2c..af3171fc893 100644 --- a/OgreMain/src/OgreCompositorInstance.cpp +++ b/OgreMain/src/OgreCompositorInstance.cpp @@ -49,43 +49,43 @@ namespace Ogre { CompositorInstance::CompositorInstance(CompositionTechnique *technique, CompositorChain *chain): mCompositor(technique->getParent()), mTechnique(technique), mChain(chain), - mEnabled(false), - mAlive(false) + mEnabled(false), + mAlive(false) { - mEnabled = false; - const String& logicName = mTechnique->getCompositorLogicName(); - if (!logicName.empty()) - { - CompositorManager::getSingleton(). - getCompositorLogic(logicName)->compositorInstanceCreated(this); - } + mEnabled = false; + const String& logicName = mTechnique->getCompositorLogicName(); + if (!logicName.empty()) + { + CompositorManager::getSingleton(). + getCompositorLogic(logicName)->compositorInstanceCreated(this); + } } //----------------------------------------------------------------------- CompositorInstance::~CompositorInstance() { - const String& logicName = mTechnique->getCompositorLogicName(); - if (!logicName.empty()) - { - CompositorManager::getSingleton(). - getCompositorLogic(logicName)->compositorInstanceDestroyed(this); - } + const String& logicName = mTechnique->getCompositorLogicName(); + if (!logicName.empty()) + { + CompositorManager::getSingleton(). + getCompositorLogic(logicName)->compositorInstanceDestroyed(this); + } freeResources(false, true); } //----------------------------------------------------------------------- void CompositorInstance::setEnabled(bool value) { - if (mEnabled != value) + if (mEnabled != value) { mEnabled = value; - //Probably first time enabling, create resources. - if( mEnabled && !mAlive ) - setAlive( true ); + //Probably first time enabling, create resources. + if( mEnabled && !mAlive ) + setAlive( true ); - /// Notify chain state needs recompile. + /// Notify chain state needs recompile. mChain->_markDirty(); - } + } } //----------------------------------------------------------------------- void CompositorInstance::setAlive(bool value) @@ -102,10 +102,10 @@ void CompositorInstance::setAlive(bool value) else { freeResources(false, true); - setEnabled(false); + setEnabled(false); } - /// Notify chain state needs recompile. + /// Notify chain state needs recompile. mChain->_markDirty(); } } @@ -116,22 +116,22 @@ void CompositorInstance::setAlive(bool value) class RSClearOperation: public CompositorInstance::RenderSystemOperation { public: - RSClearOperation(uint32 inBuffers, ColourValue inColour, Real inDepth, unsigned short inStencil): - buffers(inBuffers), colour(inColour), depth(inDepth), stencil(inStencil) - {} - /// Which buffers to clear (FrameBufferType) - uint32 buffers; - /// Colour to clear in case FBT_COLOUR is set - ColourValue colour; - /// Depth to set in case FBT_DEPTH is set - Real depth; - /// Stencil value to set in case FBT_STENCIL is set - unsigned short stencil; - - virtual void execute(SceneManager *sm, RenderSystem *rs) - { - rs->clearFrameBuffer(buffers, colour, depth, stencil); - } + RSClearOperation(uint32 inBuffers, ColourValue inColour, Real inDepth, unsigned short inStencil): + buffers(inBuffers), colour(inColour), depth(inDepth), stencil(inStencil) + {} + /// Which buffers to clear (FrameBufferType) + uint32 buffers; + /// Colour to clear in case FBT_COLOUR is set + ColourValue colour; + /// Depth to set in case FBT_DEPTH is set + Real depth; + /// Stencil value to set in case FBT_STENCIL is set + unsigned short stencil; + + virtual void execute(SceneManager *sm, RenderSystem *rs) + { + rs->clearFrameBuffer(buffers, colour, depth, stencil); + } }; /** "Set stencil state" RenderSystem operation @@ -139,28 +139,28 @@ class RSClearOperation: public CompositorInstance::RenderSystemOperation class RSStencilOperation: public CompositorInstance::RenderSystemOperation { public: - RSStencilOperation(bool inStencilCheck, CompareFunction inFunc, uint32 inRefValue, uint32 inMask, - StencilOperation inStencilFailOp, StencilOperation inDepthFailOp, StencilOperation inPassOp, - bool inTwoSidedOperation, bool inReadBackAsTexture): - stencilCheck(inStencilCheck), func(inFunc), refValue(inRefValue), mask(inMask), - stencilFailOp(inStencilFailOp), depthFailOp(inDepthFailOp), passOp(inPassOp), - twoSidedOperation(inTwoSidedOperation), readBackAsTexture(inReadBackAsTexture) - {} - bool stencilCheck; - CompareFunction func; + RSStencilOperation(bool inStencilCheck, CompareFunction inFunc, uint32 inRefValue, uint32 inMask, + StencilOperation inStencilFailOp, StencilOperation inDepthFailOp, StencilOperation inPassOp, + bool inTwoSidedOperation, bool inReadBackAsTexture): + stencilCheck(inStencilCheck), func(inFunc), refValue(inRefValue), mask(inMask), + stencilFailOp(inStencilFailOp), depthFailOp(inDepthFailOp), passOp(inPassOp), + twoSidedOperation(inTwoSidedOperation), readBackAsTexture(inReadBackAsTexture) + {} + bool stencilCheck; + CompareFunction func; uint32 refValue; - uint32 mask; + uint32 mask; StencilOperation stencilFailOp; StencilOperation depthFailOp; StencilOperation passOp; bool twoSidedOperation; - bool readBackAsTexture; + bool readBackAsTexture; - virtual void execute(SceneManager *sm, RenderSystem *rs) - { - rs->setStencilCheckEnabled(stencilCheck); - rs->setStencilBufferParams(func, refValue, mask, 0xFFFFFFFF, stencilFailOp, depthFailOp, passOp, twoSidedOperation, readBackAsTexture); - } + virtual void execute(SceneManager *sm, RenderSystem *rs) + { + rs->setStencilCheckEnabled(stencilCheck); + rs->setStencilBufferParams(func, refValue, mask, 0xFFFFFFFF, stencilFailOp, depthFailOp, passOp, twoSidedOperation, readBackAsTexture); + } }; /** "Render quad" RenderSystem operation @@ -168,8 +168,8 @@ class RSStencilOperation: public CompositorInstance::RenderSystemOperation class RSQuadOperation: public CompositorInstance::RenderSystemOperation { public: - RSQuadOperation(CompositorInstance *inInstance, uint32 inPass_id, MaterialPtr inMat): - mat(inMat), instance(inInstance), pass_id(inPass_id), + RSQuadOperation(CompositorInstance *inInstance, uint32 inPass_id, MaterialPtr inMat): + mat(inMat), instance(inInstance), pass_id(inPass_id), mQuadCornerModified(false), mQuadFarCorners(false), mQuadFarCornersViewSpace(false), @@ -177,16 +177,16 @@ class RSQuadOperation: public CompositorInstance::RenderSystemOperation mQuadTop(1), mQuadRight(1), mQuadBottom(-1) - { - mat->load(); - instance->_fireNotifyMaterialSetup(pass_id, mat); - technique = mat->getTechnique(0); - assert(technique); - } - MaterialPtr mat; - Technique *technique; - CompositorInstance *instance; - uint32 pass_id; + { + mat->load(); + instance->_fireNotifyMaterialSetup(pass_id, mat); + technique = mat->getTechnique(0); + assert(technique); + } + MaterialPtr mat; + Technique *technique; + CompositorInstance *instance; + uint32 pass_id; bool mQuadCornerModified, mQuadFarCorners, mQuadFarCornersViewSpace; Real mQuadLeft; @@ -203,53 +203,53 @@ class RSQuadOperation: public CompositorInstance::RenderSystemOperation mQuadCornerModified=true; } - void setQuadFarCorners(bool farCorners, bool farCornersViewSpace) - { - mQuadFarCorners = farCorners; - mQuadFarCornersViewSpace = farCornersViewSpace; - } + void setQuadFarCorners(bool farCorners, bool farCornersViewSpace) + { + mQuadFarCorners = farCorners; + mQuadFarCornersViewSpace = farCornersViewSpace; + } - virtual void execute(SceneManager *sm, RenderSystem *rs) - { - // Fire listener - instance->_fireNotifyMaterialRender(pass_id, mat); + virtual void execute(SceneManager *sm, RenderSystem *rs) + { + // Fire listener + instance->_fireNotifyMaterialRender(pass_id, mat); Viewport* vp = rs->_getViewport(); - Rectangle2D *rect = static_cast(CompositorManager::getSingleton()._getTexturedRectangle2D()); - - if (mQuadCornerModified) - { - // insure positions are using peculiar render system offsets - Real hOffset = rs->getHorizontalTexelOffset() / (0.5f * vp->getActualWidth()); - Real vOffset = rs->getVerticalTexelOffset() / (0.5f * vp->getActualHeight()); - rect->setCorners(mQuadLeft + hOffset, mQuadTop - vOffset, mQuadRight + hOffset, mQuadBottom - vOffset); - } - - if(mQuadFarCorners) - { - const Ogre::Vector3 *corners = vp->getCamera()->getWorldSpaceCorners(); - if(mQuadFarCornersViewSpace) - { - const Ogre::Matrix4 &viewMat = vp->getCamera()->getViewMatrix(true); - rect->setNormals(viewMat*corners[5], viewMat*corners[6], viewMat*corners[4], viewMat*corners[7]); - } - else - { - rect->setNormals(corners[5], corners[6], corners[4], corners[7]); - } - } - - // Queue passes from mat - Technique::PassIterator i = technique->getPassIterator(); - while(i.hasMoreElements()) - { - sm->_injectRenderWithPass( - i.getNext(), - rect, - false // don't allow replacement of shadow passes - ); - } - } + Rectangle2D *rect = static_cast(CompositorManager::getSingleton()._getTexturedRectangle2D()); + + if (mQuadCornerModified) + { + // insure positions are using peculiar render system offsets + Real hOffset = rs->getHorizontalTexelOffset() / (0.5f * vp->getActualWidth()); + Real vOffset = rs->getVerticalTexelOffset() / (0.5f * vp->getActualHeight()); + rect->setCorners(mQuadLeft + hOffset, mQuadTop - vOffset, mQuadRight + hOffset, mQuadBottom - vOffset); + } + + if(mQuadFarCorners) + { + const Ogre::Vector3 *corners = vp->getCamera()->getWorldSpaceCorners(); + if(mQuadFarCornersViewSpace) + { + const Ogre::Matrix4 &viewMat = vp->getCamera()->getViewMatrix(true); + rect->setNormals(viewMat*corners[5], viewMat*corners[6], viewMat*corners[4], viewMat*corners[7]); + } + else + { + rect->setNormals(corners[5], corners[6], corners[4], corners[7]); + } + } + + // Queue passes from mat + Technique::PassIterator i = technique->getPassIterator(); + while(i.hasMoreElements()) + { + sm->_injectRenderWithPass( + i.getNext(), + rect, + false // don't allow replacement of shadow passes + ); + } + } }; /** "Set material scheme" RenderSystem operation @@ -257,50 +257,50 @@ class RSQuadOperation: public CompositorInstance::RenderSystemOperation class RSSetSchemeOperation: public CompositorInstance::RenderSystemOperation { public: - RSSetSchemeOperation(const String& schemeName) : mPreviousLateResolving(false), mSchemeName(schemeName) {} - - String mPreviousScheme; - bool mPreviousLateResolving; + RSSetSchemeOperation(const String& schemeName) : mPreviousLateResolving(false), mSchemeName(schemeName) {} + + String mPreviousScheme; + bool mPreviousLateResolving; - String mSchemeName; + String mSchemeName; - virtual void execute(SceneManager *sm, RenderSystem *rs) - { - MaterialManager& matMgr = MaterialManager::getSingleton(); - mPreviousScheme = matMgr.getActiveScheme(); - matMgr.setActiveScheme(mSchemeName); + virtual void execute(SceneManager *sm, RenderSystem *rs) + { + MaterialManager& matMgr = MaterialManager::getSingleton(); + mPreviousScheme = matMgr.getActiveScheme(); + matMgr.setActiveScheme(mSchemeName); - mPreviousLateResolving = sm->isLateMaterialResolving(); - sm->setLateMaterialResolving(true); - } + mPreviousLateResolving = sm->isLateMaterialResolving(); + sm->setLateMaterialResolving(true); + } - const String& getPreviousScheme() const { return mPreviousScheme; } - bool getPreviousLateResolving() const { return mPreviousLateResolving; } + const String& getPreviousScheme() const { return mPreviousScheme; } + bool getPreviousLateResolving() const { return mPreviousLateResolving; } }; /** Restore the settings changed by the set scheme operation */ class RSRestoreSchemeOperation: public CompositorInstance::RenderSystemOperation { public: - RSRestoreSchemeOperation(const RSSetSchemeOperation* setOperation) : - mSetOperation(setOperation) {} - - const RSSetSchemeOperation* mSetOperation; - - virtual void execute(SceneManager *sm, RenderSystem *rs) - { - MaterialManager::getSingleton().setActiveScheme(mSetOperation->getPreviousScheme()); - sm->setLateMaterialResolving(mSetOperation->getPreviousLateResolving()); - } + RSRestoreSchemeOperation(const RSSetSchemeOperation* setOperation) : + mSetOperation(setOperation) {} + + const RSSetSchemeOperation* mSetOperation; + + virtual void execute(SceneManager *sm, RenderSystem *rs) + { + MaterialManager::getSingleton().setActiveScheme(mSetOperation->getPreviousScheme()); + sm->setLateMaterialResolving(mSetOperation->getPreviousLateResolving()); + } }; void CompositorInstance::collectPasses(TargetOperation &finalState, CompositionTargetPass *target) { - /// Here, passes are converted into render target operations + /// Here, passes are converted into render target operations Pass *targetpass; Technique *srctech; - MaterialPtr mat, srcmat; - + MaterialPtr mat, srcmat; + CompositionTargetPass::PassIterator it = target->getPassIterator(); while(it.hasMoreElements()) { @@ -308,123 +308,123 @@ void CompositorInstance::collectPasses(TargetOperation &finalState, CompositionT switch(pass->getType()) { case CompositionPass::PT_CLEAR: - queueRenderSystemOp(finalState, OGRE_NEW RSClearOperation( - pass->getClearBuffers(), - pass->getClearColour(), - pass->getClearDepth(), - (ushort)pass->getClearStencil() - )); + queueRenderSystemOp(finalState, OGRE_NEW RSClearOperation( + pass->getClearBuffers(), + pass->getClearColour(), + pass->getClearDepth(), + (ushort)pass->getClearStencil() + )); break; - case CompositionPass::PT_STENCIL: - queueRenderSystemOp(finalState, OGRE_NEW RSStencilOperation( - pass->getStencilCheck(),pass->getStencilFunc(), pass->getStencilRefValue(), - pass->getStencilMask(), pass->getStencilFailOp(), pass->getStencilDepthFailOp(), - pass->getStencilPassOp(), pass->getStencilTwoSidedOperation(), pass->getStencilReadBackAsTextureOperation() - )); + case CompositionPass::PT_STENCIL: + queueRenderSystemOp(finalState, OGRE_NEW RSStencilOperation( + pass->getStencilCheck(),pass->getStencilFunc(), pass->getStencilRefValue(), + pass->getStencilMask(), pass->getStencilFailOp(), pass->getStencilDepthFailOp(), + pass->getStencilPassOp(), pass->getStencilTwoSidedOperation(), pass->getStencilReadBackAsTextureOperation() + )); break; - case CompositionPass::PT_RENDERSCENE: - { - if(pass->getFirstRenderQueue() < finalState.currentQueueGroupID) - { - /// Mismatch -- warn user - /// XXX We could support repeating the last queue, with some effort - LogManager::getSingleton().logMessage("Warning in compilation of Compositor " - +mCompositor->getName()+": Attempt to render queue "+ - StringConverter::toString(pass->getFirstRenderQueue())+" before "+ - StringConverter::toString(finalState.currentQueueGroupID), LML_CRITICAL); - } - - RSSetSchemeOperation* setSchemeOperation = 0; - if (pass->getMaterialScheme() != BLANKSTRING) - { - //Add the triggers that will set the scheme and restore it each frame - finalState.currentQueueGroupID = pass->getFirstRenderQueue(); - setSchemeOperation = OGRE_NEW RSSetSchemeOperation(pass->getMaterialScheme()); - queueRenderSystemOp(finalState, setSchemeOperation); - } - - /// Add render queues - for(int x=pass->getFirstRenderQueue(); x<=pass->getLastRenderQueue(); ++x) - { - assert(x>=0); - finalState.renderQueues.set(x); - } - finalState.currentQueueGroupID = pass->getLastRenderQueue()+1; - - if (setSchemeOperation != 0) - { - //Restoring the scheme after the queues have been rendered - queueRenderSystemOp(finalState, - OGRE_NEW RSRestoreSchemeOperation(setSchemeOperation)); - } - - finalState.findVisibleObjects = true; + case CompositionPass::PT_RENDERSCENE: + { + if(pass->getFirstRenderQueue() < finalState.currentQueueGroupID) + { + /// Mismatch -- warn user + /// XXX We could support repeating the last queue, with some effort + LogManager::getSingleton().logMessage("Warning in compilation of Compositor " + +mCompositor->getName()+": Attempt to render queue "+ + StringConverter::toString(pass->getFirstRenderQueue())+" before "+ + StringConverter::toString(finalState.currentQueueGroupID), LML_CRITICAL); + } + + RSSetSchemeOperation* setSchemeOperation = 0; + if (pass->getMaterialScheme() != BLANKSTRING) + { + //Add the triggers that will set the scheme and restore it each frame + finalState.currentQueueGroupID = pass->getFirstRenderQueue(); + setSchemeOperation = OGRE_NEW RSSetSchemeOperation(pass->getMaterialScheme()); + queueRenderSystemOp(finalState, setSchemeOperation); + } + + /// Add render queues + for(int x=pass->getFirstRenderQueue(); x<=pass->getLastRenderQueue(); ++x) + { + assert(x>=0); + finalState.renderQueues.set(x); + } + finalState.currentQueueGroupID = pass->getLastRenderQueue()+1; + + if (setSchemeOperation != 0) + { + //Restoring the scheme after the queues have been rendered + queueRenderSystemOp(finalState, + OGRE_NEW RSRestoreSchemeOperation(setSchemeOperation)); + } + + finalState.findVisibleObjects = true; break; - } - case CompositionPass::PT_RENDERQUAD: { + } + case CompositionPass::PT_RENDERQUAD: { srcmat = pass->getMaterial(); - if(srcmat.isNull()) + if(srcmat.isNull()) { /// No material -- warn user - LogManager::getSingleton().logMessage("Warning in compilation of Compositor " - +mCompositor->getName()+": No material defined for composition pass", LML_CRITICAL); + LogManager::getSingleton().logMessage("Warning in compilation of Compositor " + +mCompositor->getName()+": No material defined for composition pass", LML_CRITICAL); break; } - srcmat->load(); - if(srcmat->getNumSupportedTechniques()==0) - { - /// No supported techniques -- warn user - LogManager::getSingleton().logMessage("Warning in compilation of Compositor " - +mCompositor->getName()+": material "+srcmat->getName()+" has no supported techniques", LML_CRITICAL); + srcmat->load(); + if(srcmat->getNumSupportedTechniques()==0) + { + /// No supported techniques -- warn user + LogManager::getSingleton().logMessage("Warning in compilation of Compositor " + +mCompositor->getName()+": material "+srcmat->getName()+" has no supported techniques", LML_CRITICAL); break; - } - srctech = srcmat->getBestTechnique(0); - /// Create local material - MaterialPtr localMat = createLocalMaterial(srcmat->getName()); - /// Copy and adapt passes from source material - Technique::PassIterator i = srctech->getPassIterator(); - while(i.hasMoreElements()) - { - Pass *srcpass = i.getNext(); - /// Create new target pass - targetpass = localMat->getTechnique(0)->createPass(); - (*targetpass) = (*srcpass); - /// Set up inputs - for(size_t x=0; xgetNumInputs(); ++x) - { - const CompositionPass::InputTex& inp = pass->getInput(x); - if(!inp.name.empty()) - { - if(x < targetpass->getNumTextureUnitStates()) - { - targetpass->getTextureUnitState((ushort)x)->setTextureName(getSourceForTex(inp.name, inp.mrtIndex)); - } - else - { - /// Texture unit not there - LogManager::getSingleton().logMessage("Warning in compilation of Compositor " - +mCompositor->getName()+": material "+srcmat->getName()+" texture unit " - +StringConverter::toString(x)+" out of bounds", LML_CRITICAL); - } - } - } - } + } + srctech = srcmat->getBestTechnique(0); + /// Create local material + MaterialPtr localMat = createLocalMaterial(srcmat->getName()); + /// Copy and adapt passes from source material + Technique::PassIterator i = srctech->getPassIterator(); + while(i.hasMoreElements()) + { + Pass *srcpass = i.getNext(); + /// Create new target pass + targetpass = localMat->getTechnique(0)->createPass(); + (*targetpass) = (*srcpass); + /// Set up inputs + for(size_t x=0; xgetNumInputs(); ++x) + { + const CompositionPass::InputTex& inp = pass->getInput(x); + if(!inp.name.empty()) + { + if(x < targetpass->getNumTextureUnitStates()) + { + targetpass->getTextureUnitState((ushort)x)->setTextureName(getSourceForTex(inp.name, inp.mrtIndex)); + } + else + { + /// Texture unit not there + LogManager::getSingleton().logMessage("Warning in compilation of Compositor " + +mCompositor->getName()+": material "+srcmat->getName()+" texture unit " + +StringConverter::toString(x)+" out of bounds", LML_CRITICAL); + } + } + } + } RSQuadOperation * rsQuadOperation = OGRE_NEW RSQuadOperation(this,pass->getIdentifier(),localMat); Real left,top,right,bottom; if (pass->getQuadCorners(left,top,right,bottom)) rsQuadOperation->setQuadCorners(left,top,right,bottom); - rsQuadOperation->setQuadFarCorners(pass->getQuadFarCorners(), pass->getQuadFarCornersViewSpace()); - - queueRenderSystemOp(finalState,rsQuadOperation); - } + rsQuadOperation->setQuadFarCorners(pass->getQuadFarCorners(), pass->getQuadFarCornersViewSpace()); + + queueRenderSystemOp(finalState,rsQuadOperation); + } + break; + case CompositionPass::PT_RENDERCUSTOM: + RenderSystemOperation* customOperation = CompositorManager::getSingleton(). + getCustomCompositionPass(pass->getCustomType())->createOperation(this, pass); + queueRenderSystemOp(finalState, customOperation); break; - case CompositionPass::PT_RENDERCUSTOM: - RenderSystemOperation* customOperation = CompositorManager::getSingleton(). - getCustomCompositionPass(pass->getCustomType())->createOperation(this, pass); - queueRenderSystemOp(finalState, customOperation); - break; } } } @@ -432,8 +432,8 @@ void CompositorInstance::collectPasses(TargetOperation &finalState, CompositionT void CompositorInstance::_compileTargetOperations(CompiledState &compiledState) { /// Collect targets of previous state - if(mPreviousInstance) - mPreviousInstance->_compileTargetOperations(compiledState); + if(mPreviousInstance) + mPreviousInstance->_compileTargetOperations(compiledState); /// Texture targets CompositionTechnique::TargetPassIterator it = mTechnique->getTargetPassIterator(); while(it.hasMoreElements()) @@ -495,82 +495,82 @@ CompositionTechnique *CompositorInstance::getTechnique() //----------------------------------------------------------------------- void CompositorInstance::setTechnique(CompositionTechnique* tech, bool reuseTextures) { - if (mTechnique != tech) - { - if (reuseTextures) - { - // make sure we store all (shared) textures in use in our reserve pool - // this will ensure they don't get destroyed as unreferenced - // so they're ready to use again later - CompositionTechnique::TextureDefinitionIterator it = mTechnique->getTextureDefinitionIterator(); - while(it.hasMoreElements()) - { - CompositionTechnique::TextureDefinition *def = it.getNext(); - if (def->pooled) - { - LocalTextureMap::iterator i = mLocalTextures.find(def->name); - if (i != mLocalTextures.end()) - { - // overwriting duplicates is fine, we only want one entry per def - mReserveTextures[def] = i->second; - } - - } - } - } - // replace technique - mTechnique = tech; - - if (mAlive) - { - // free up resources, but keep reserves if reusing - freeResources(false, !reuseTextures); - createResources(false); - /// Notify chain state needs recompile. - mChain->_markDirty(); - } - - } + if (mTechnique != tech) + { + if (reuseTextures) + { + // make sure we store all (shared) textures in use in our reserve pool + // this will ensure they don't get destroyed as unreferenced + // so they're ready to use again later + CompositionTechnique::TextureDefinitionIterator it = mTechnique->getTextureDefinitionIterator(); + while(it.hasMoreElements()) + { + CompositionTechnique::TextureDefinition *def = it.getNext(); + if (def->pooled) + { + LocalTextureMap::iterator i = mLocalTextures.find(def->name); + if (i != mLocalTextures.end()) + { + // overwriting duplicates is fine, we only want one entry per def + mReserveTextures[def] = i->second; + } + + } + } + } + // replace technique + mTechnique = tech; + + if (mAlive) + { + // free up resources, but keep reserves if reusing + freeResources(false, !reuseTextures); + createResources(false); + /// Notify chain state needs recompile. + mChain->_markDirty(); + } + + } } //--------------------------------------------------------------------- void CompositorInstance::setScheme(const String& schemeName, bool reuseTextures) { - CompositionTechnique* tech = mCompositor->getSupportedTechnique(schemeName); - if (tech) - { - setTechnique(tech, reuseTextures); - } + CompositionTechnique* tech = mCompositor->getSupportedTechnique(schemeName); + if (tech) + { + setTechnique(tech, reuseTextures); + } } //----------------------------------------------------------------------- CompositorChain *CompositorInstance::getChain() { - return mChain; + return mChain; } //----------------------------------------------------------------------- const String& CompositorInstance::getTextureInstanceName(const String& name, - size_t mrtIndex) + size_t mrtIndex) { - return getSourceForTex(name, mrtIndex); + return getSourceForTex(name, mrtIndex); } //--------------------------------------------------------------------- TexturePtr CompositorInstance::getTextureInstance(const String& name, size_t mrtIndex) { - // try simple textures first - LocalTextureMap::iterator i = mLocalTextures.find(name); - if(i != mLocalTextures.end()) - { - return i->second; - } - - // try MRTs - texture (rather than target) - i = mLocalTextures.find(getMRTTexLocalName(name, mrtIndex)); - if (i != mLocalTextures.end()) - { - return i->second; - } - - // not present - return TexturePtr(); + // try simple textures first + LocalTextureMap::iterator i = mLocalTextures.find(name); + if(i != mLocalTextures.end()) + { + return i->second; + } + + // try MRTs - texture (rather than target) + i = mLocalTextures.find(getMRTTexLocalName(name, mrtIndex)); + if (i != mLocalTextures.end()) + { + return i->second; + } + + // not present + return TexturePtr(); } //----------------------------------------------------------------------- @@ -594,49 +594,49 @@ static size_t dummyCounter = 0; //--------------------------------------------------------------------- void CompositorInstance::notifyResized() { - freeResources(true, true); - createResources(true); + freeResources(true, true); + createResources(true); } //----------------------------------------------------------------------- void CompositorInstance::createResources(bool forResizeOnly) { - static size_t dummyCounter = 0; + static size_t dummyCounter = 0; /// Create temporary textures /// In principle, temporary textures could be shared between multiple viewports /// (CompositorChains). This will save a lot of memory in case more viewports /// are composited. CompositionTechnique::TextureDefinitionIterator it = mTechnique->getTextureDefinitionIterator(); - CompositorManager::UniqueTextureSet assignedTextures; + CompositorManager::UniqueTextureSet assignedTextures; while(it.hasMoreElements()) { CompositionTechnique::TextureDefinition *def = it.getNext(); - if (!def->refCompName.empty()) { - //This is a reference, isn't created in this compositor - continue; - } + if (!def->refCompName.empty()) { + //This is a reference, isn't created in this compositor + continue; + } RenderTarget* rendTarget; - if (def->scope == CompositionTechnique::TS_GLOBAL) { - //This is a global texture, just link the created resources from the parent - Compositor* parentComp = mTechnique->getParent(); - if (def->formatList.size() > 1) - { - size_t atch = 0; - for (PixelFormatList::iterator p = def->formatList.begin(); + if (def->scope == CompositionTechnique::TS_GLOBAL) { + //This is a global texture, just link the created resources from the parent + Compositor* parentComp = mTechnique->getParent(); + if (def->formatList.size() > 1) + { + size_t atch = 0; + for (PixelFormatList::iterator p = def->formatList.begin(); p != def->formatList.end(); ++p, ++atch) - { - Ogre::TexturePtr tex = parentComp->getTextureInstance(def->name, atch); - mLocalTextures[getMRTTexLocalName(def->name, atch)] = tex; - } - MultiRenderTarget* mrt = static_cast + { + Ogre::TexturePtr tex = parentComp->getTextureInstance(def->name, atch); + mLocalTextures[getMRTTexLocalName(def->name, atch)] = tex; + } + MultiRenderTarget* mrt = static_cast (parentComp->getRenderTarget(def->name)); - mLocalMRTs[def->name] = mrt; + mLocalMRTs[def->name] = mrt; rendTarget = mrt; } else { - Ogre::TexturePtr tex = parentComp->getTextureInstance(def->name, 0); - mLocalTextures[def->name] = tex; + Ogre::TexturePtr tex = parentComp->getTextureInstance(def->name, 0); + mLocalTextures[def->name] = tex; rendTarget = tex->getBuffer()->getRenderTarget(); } @@ -675,9 +675,9 @@ void CompositorInstance::createResources(bool forResizeOnly) if (def->formatList.size() > 1) { String MRTbaseName = "c" + StringConverter::toString(dummyCounter++) + - "/" + def->name + "/" + mChain->getViewport()->getTarget()->getName(); + "/" + def->name + "/" + mChain->getViewport()->getTarget()->getName(); MultiRenderTarget* mrt = - Root::getSingleton().getRenderSystem()->createMultiRenderTarget(MRTbaseName); + Root::getSingleton().getRenderSystem()->createMultiRenderTarget(MRTbaseName); mLocalMRTs[def->name] = mrt; // create and bind individual surfaces @@ -721,7 +721,7 @@ void CompositorInstance::createResources(bool forResizeOnly) else { String texName = "c" + StringConverter::toString(dummyCounter++) + - "/" + def->name + "/" + mChain->getViewport()->getTarget()->getName(); + "/" + def->name + "/" + mChain->getViewport()->getTarget()->getName(); // space in the name mixup the cegui in the compositor demo // this is an auto generated name - so no spaces can't hart us. @@ -750,534 +750,534 @@ void CompositorInstance::createResources(bool forResizeOnly) } } - //Set DepthBuffer pool for sharing - rendTarget->setDepthBufferPool( def->depthBufferId ); + //Set DepthBuffer pool for sharing + rendTarget->setDepthBufferPool( def->depthBufferId ); /// Set up viewport over entire texture rendTarget->setAutoUpdated( false ); - // We may be sharing / reusing this texture, so test before adding viewport - if (rendTarget->getNumViewports() == 0) - { - Viewport* v; - Camera* camera = mChain->getViewport()->getCamera(); - if (!camera) - { - v = rendTarget->addViewport( camera ); - } - else - { - // Save last viewport and current aspect ratio - Viewport* oldViewport = camera->getViewport(); - Real aspectRatio = camera->getAspectRatio(); + // We may be sharing / reusing this texture, so test before adding viewport + if (rendTarget->getNumViewports() == 0) + { + Viewport* v; + Camera* camera = mChain->getViewport()->getCamera(); + if (!camera) + { + v = rendTarget->addViewport( camera ); + } + else + { + // Save last viewport and current aspect ratio + Viewport* oldViewport = camera->getViewport(); + Real aspectRatio = camera->getAspectRatio(); - v = rendTarget->addViewport( camera ); + v = rendTarget->addViewport( camera ); - // Should restore aspect ratio, in case of auto aspect ratio - // enabled, it'll changed when add new viewport. - camera->setAspectRatio(aspectRatio); - // Should restore last viewport, i.e. never disturb user code - // which might based on that. - camera->_notifyViewport(oldViewport); - } + // Should restore aspect ratio, in case of auto aspect ratio + // enabled, it'll changed when add new viewport. + camera->setAspectRatio(aspectRatio); + // Should restore last viewport, i.e. never disturb user code + // which might based on that. + camera->_notifyViewport(oldViewport); + } - v->setClearEveryFrame( false ); - v->setOverlaysEnabled( false ); - v->setBackgroundColour( ColourValue( 0, 0, 0, 0 ) ); - } + v->setClearEveryFrame( false ); + v->setOverlaysEnabled( false ); + v->setBackgroundColour( ColourValue( 0, 0, 0, 0 ) ); + } } - _fireNotifyResourcesCreated(forResizeOnly); + _fireNotifyResourcesCreated(forResizeOnly); } //--------------------------------------------------------------------- void CompositorInstance::deriveTextureRenderTargetOptions( - const String& texname, bool *hwGammaWrite, uint *fsaa, String* fsaaHint) + const String& texname, bool *hwGammaWrite, uint *fsaa, String* fsaaHint) { - // search for passes on this texture def that either include a render_scene - // or use input previous - bool renderingScene = false; - - CompositionTechnique::TargetPassIterator it = mTechnique->getTargetPassIterator(); - while (it.hasMoreElements()) - { - CompositionTargetPass* tp = it.getNext(); - if (tp->getOutputName() == texname) - { - if (tp->getInputMode() == CompositionTargetPass::IM_PREVIOUS) - { - // this may be rendering the scene implicitly - // Can't check mPreviousInstance against mChain->_getOriginalSceneCompositor() - // at this time, so check the position - CompositorChain::InstanceIterator instit = mChain->getCompositors(); - renderingScene = true; - while(instit.hasMoreElements()) - { - CompositorInstance* inst = instit.getNext(); - if (inst == this) - break; - else if (inst->getEnabled()) - { - // nope, we have another compositor before us, this will - // be doing the AA - renderingScene = false; - } - } - if (renderingScene) - break; - } - else - { - // look for a render_scene pass - CompositionTargetPass::PassIterator pit = tp->getPassIterator(); - while(pit.hasMoreElements()) - { - CompositionPass* pass = pit.getNext(); - if (pass->getType() == CompositionPass::PT_RENDERSCENE) - { - renderingScene = true; - break; - } - } - } - - } - } - - if (renderingScene) - { - // Ok, inherit settings from target - RenderTarget* target = mChain->getViewport()->getTarget(); - *hwGammaWrite = target->isHardwareGammaEnabled(); - *fsaa = target->getFSAA(); - *fsaaHint = target->getFSAAHint(); - } - else - { - *hwGammaWrite = false; - *fsaa = 0; - *fsaaHint = BLANKSTRING; - } + // search for passes on this texture def that either include a render_scene + // or use input previous + bool renderingScene = false; + + CompositionTechnique::TargetPassIterator it = mTechnique->getTargetPassIterator(); + while (it.hasMoreElements()) + { + CompositionTargetPass* tp = it.getNext(); + if (tp->getOutputName() == texname) + { + if (tp->getInputMode() == CompositionTargetPass::IM_PREVIOUS) + { + // this may be rendering the scene implicitly + // Can't check mPreviousInstance against mChain->_getOriginalSceneCompositor() + // at this time, so check the position + CompositorChain::InstanceIterator instit = mChain->getCompositors(); + renderingScene = true; + while(instit.hasMoreElements()) + { + CompositorInstance* inst = instit.getNext(); + if (inst == this) + break; + else if (inst->getEnabled()) + { + // nope, we have another compositor before us, this will + // be doing the AA + renderingScene = false; + } + } + if (renderingScene) + break; + } + else + { + // look for a render_scene pass + CompositionTargetPass::PassIterator pit = tp->getPassIterator(); + while(pit.hasMoreElements()) + { + CompositionPass* pass = pit.getNext(); + if (pass->getType() == CompositionPass::PT_RENDERSCENE) + { + renderingScene = true; + break; + } + } + } + + } + } + + if (renderingScene) + { + // Ok, inherit settings from target + RenderTarget* target = mChain->getViewport()->getTarget(); + *hwGammaWrite = target->isHardwareGammaEnabled(); + *fsaa = target->getFSAA(); + *fsaaHint = target->getFSAAHint(); + } + else + { + *hwGammaWrite = false; + *fsaa = 0; + *fsaaHint = BLANKSTRING; + } } //--------------------------------------------------------------------- String CompositorInstance::getMRTTexLocalName(const String& baseName, size_t attachment) { - return baseName + "/" + StringConverter::toString(attachment); + return baseName + "/" + StringConverter::toString(attachment); } //----------------------------------------------------------------------- void CompositorInstance::freeResources(bool forResizeOnly, bool clearReserveTextures) { // Remove temporary textures - // We only remove those that are not shared, shared textures are dealt with - // based on their reference count. - // We can also only free textures which are derived from the target size, if - // required (saves some time & memory thrashing / fragmentation on resize) - - CompositionTechnique::TextureDefinitionIterator it = mTechnique->getTextureDefinitionIterator(); - while(it.hasMoreElements()) - { - CompositionTechnique::TextureDefinition *def = it.getNext(); - - if (!def->refCompName.empty()) - { - //This is a reference, isn't created here - continue; - } - - // potentially only remove this one if based on size - if (!forResizeOnly || def->width == 0 || def->height == 0) - { - size_t subSurf = def->formatList.size(); - - // Potentially many surfaces - for (size_t s = 0; s < subSurf; ++s) - { - String texName = subSurf > 1 ? getMRTTexLocalName(def->name, s) - : def->name; - - LocalTextureMap::iterator i = mLocalTextures.find(texName); - if (i != mLocalTextures.end()) - { - if (!def->pooled && def->scope != CompositionTechnique::TS_GLOBAL) - { - // remove myself from central only if not pooled and not global - TextureManager::getSingleton().remove(i->second->getName()); - } - - // remove from local - // reserves are potentially cleared later - mLocalTextures.erase(i); - - } - - } // subSurf - - if (subSurf > 1) - { - LocalMRTMap::iterator mrti = mLocalMRTs.find(def->name); - if (mrti != mLocalMRTs.end()) - { - if (def->scope != CompositionTechnique::TS_GLOBAL) - { - // remove MRT if not global - Root::getSingleton().getRenderSystem()->destroyRenderTarget(mrti->second->getName()); - } - - mLocalMRTs.erase(mrti); - } - - } - - } // not for resize or width/height 0 - } - - if (clearReserveTextures) - { - if (forResizeOnly) - { - // just remove the ones which would be affected by a resize - for (ReserveTextureMap::iterator i = mReserveTextures.begin(); - i != mReserveTextures.end(); ) - { - if (i->first->width == 0 || i->first->height == 0) - { - mReserveTextures.erase(i++); - } - else - ++i; - } - } - else - { - // clear all - mReserveTextures.clear(); - } - } - - // Now we tell the central list of textures to check if its unreferenced, - // and to remove if necessary. Anything shared that was left in the reserve textures - // will not be released here - CompositorManager::getSingleton().freePooledTextures(true); + // We only remove those that are not shared, shared textures are dealt with + // based on their reference count. + // We can also only free textures which are derived from the target size, if + // required (saves some time & memory thrashing / fragmentation on resize) + + CompositionTechnique::TextureDefinitionIterator it = mTechnique->getTextureDefinitionIterator(); + while(it.hasMoreElements()) + { + CompositionTechnique::TextureDefinition *def = it.getNext(); + + if (!def->refCompName.empty()) + { + //This is a reference, isn't created here + continue; + } + + // potentially only remove this one if based on size + if (!forResizeOnly || def->width == 0 || def->height == 0) + { + size_t subSurf = def->formatList.size(); + + // Potentially many surfaces + for (size_t s = 0; s < subSurf; ++s) + { + String texName = subSurf > 1 ? getMRTTexLocalName(def->name, s) + : def->name; + + LocalTextureMap::iterator i = mLocalTextures.find(texName); + if (i != mLocalTextures.end()) + { + if (!def->pooled && def->scope != CompositionTechnique::TS_GLOBAL) + { + // remove myself from central only if not pooled and not global + TextureManager::getSingleton().remove(i->second->getName()); + } + + // remove from local + // reserves are potentially cleared later + mLocalTextures.erase(i); + + } + + } // subSurf + + if (subSurf > 1) + { + LocalMRTMap::iterator mrti = mLocalMRTs.find(def->name); + if (mrti != mLocalMRTs.end()) + { + if (def->scope != CompositionTechnique::TS_GLOBAL) + { + // remove MRT if not global + Root::getSingleton().getRenderSystem()->destroyRenderTarget(mrti->second->getName()); + } + + mLocalMRTs.erase(mrti); + } + + } + + } // not for resize or width/height 0 + } + + if (clearReserveTextures) + { + if (forResizeOnly) + { + // just remove the ones which would be affected by a resize + for (ReserveTextureMap::iterator i = mReserveTextures.begin(); + i != mReserveTextures.end(); ) + { + if (i->first->width == 0 || i->first->height == 0) + { + mReserveTextures.erase(i++); + } + else + ++i; + } + } + else + { + // clear all + mReserveTextures.clear(); + } + } + + // Now we tell the central list of textures to check if its unreferenced, + // and to remove if necessary. Anything shared that was left in the reserve textures + // will not be released here + CompositorManager::getSingleton().freePooledTextures(true); } //--------------------------------------------------------------------- RenderTarget* CompositorInstance::getRenderTarget(const String& name) { - return getTargetForTex(name); + return getTargetForTex(name); } //----------------------------------------------------------------------- RenderTarget *CompositorInstance::getTargetForTex(const String &name) { - // try simple texture - LocalTextureMap::iterator i = mLocalTextures.find(name); + // try simple texture + LocalTextureMap::iterator i = mLocalTextures.find(name); if(i != mLocalTextures.end()) - return i->second->getBuffer()->getRenderTarget(); - - // try MRTs - LocalMRTMap::iterator mi = mLocalMRTs.find(name); - if (mi != mLocalMRTs.end()) - return mi->second; - - //Try reference : Find the instance and check if it is before us - CompositionTechnique::TextureDefinition* texDef = mTechnique->getTextureDefinition(name); - if (texDef != 0 && !texDef->refCompName.empty()) - { - //This TextureDefinition is reference. - //Since referenced TD's have no info except name we have to find original TD + return i->second->getBuffer()->getRenderTarget(); + + // try MRTs + LocalMRTMap::iterator mi = mLocalMRTs.find(name); + if (mi != mLocalMRTs.end()) + return mi->second; + + //Try reference : Find the instance and check if it is before us + CompositionTechnique::TextureDefinition* texDef = mTechnique->getTextureDefinition(name); + if (texDef != 0 && !texDef->refCompName.empty()) + { + //This TextureDefinition is reference. + //Since referenced TD's have no info except name we have to find original TD - CompositionTechnique::TextureDefinition* refTexDef = 0; + CompositionTechnique::TextureDefinition* refTexDef = 0; - //Try chain first - if(mChain) - { - CompositorInstance* refCompInst = mChain->getCompositor(texDef->refCompName); - if(refCompInst) - { + //Try chain first + if(mChain) + { + CompositorInstance* refCompInst = mChain->getCompositor(texDef->refCompName); + if(refCompInst) + { refTexDef = refCompInst->getCompositor()->getSupportedTechnique( refCompInst->getScheme())->getTextureDefinition(texDef->refTexName); // if the texture with the reference name can not be found, try the name if (refTexDef == 0) { - refTexDef = refCompInst->getCompositor()->getSupportedTechnique( + refTexDef = refCompInst->getCompositor()->getSupportedTechnique( refCompInst->getScheme())->getTextureDefinition(name); } - } - else - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor", + } + else + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor", "CompositorInstance::getTargetForTex"); - } - } + } + } - if(refTexDef == 0) - { - //Still NULL. Try global search. + if(refTexDef == 0) + { + //Still NULL. Try global search. const CompositorPtr &refComp = CompositorManager::getSingleton().getByName(texDef->refCompName); - if(!refComp.isNull()) - { - refTexDef = refComp->getSupportedTechnique()->getTextureDefinition(name); - } - } + if(!refComp.isNull()) + { + refTexDef = refComp->getSupportedTechnique()->getTextureDefinition(name); + } + } - if(refTexDef == 0) - { - //Still NULL - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor texture", + if(refTexDef == 0) + { + //Still NULL + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor texture", "CompositorInstance::getTargetForTex"); - } + } - switch(refTexDef->scope) - { - case CompositionTechnique::TS_CHAIN: - { - //Find the instance and check if it is before us - CompositorInstance* refCompInst = 0; + switch(refTexDef->scope) + { + case CompositionTechnique::TS_CHAIN: + { + //Find the instance and check if it is before us + CompositorInstance* refCompInst = 0; OgreAssert(mChain, "Undefined compositor chain"); - CompositorChain::InstanceIterator it = mChain->getCompositors(); - bool beforeMe = true; - while (it.hasMoreElements()) - { - CompositorInstance* nextCompInst = it.getNext(); - if (nextCompInst->getCompositor()->getName() == texDef->refCompName) - { - refCompInst = nextCompInst; - break; - } - if (nextCompInst == this) - { - //We encountered ourselves while searching for the compositor - - //we are earlier in the chain. - beforeMe = false; - } - } - - if (refCompInst == 0 || !refCompInst->getEnabled()) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Referencing inactive compositor texture", - "CompositorInstance::getTargetForTex"); - } - if (!beforeMe) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Referencing compositor that is later in the chain", - "CompositorInstance::getTargetForTex"); - } - return refCompInst->getRenderTarget(texDef->refTexName); - } - case CompositionTechnique::TS_GLOBAL: - { - //Chain and global case - the referenced compositor will know how to handle - const CompositorPtr& refComp = CompositorManager::getSingleton().getByName(texDef->refCompName); - if(refComp.isNull()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor", - "CompositorInstance::getTargetForTex"); - } - return refComp->getRenderTarget(texDef->refTexName); - } - case CompositionTechnique::TS_LOCAL: - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Referencing local compositor texture", - "CompositorInstance::getTargetForTex"); - } - } - - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Non-existent local texture name", - "CompositorInstance::getTargetForTex"); + CompositorChain::InstanceIterator it = mChain->getCompositors(); + bool beforeMe = true; + while (it.hasMoreElements()) + { + CompositorInstance* nextCompInst = it.getNext(); + if (nextCompInst->getCompositor()->getName() == texDef->refCompName) + { + refCompInst = nextCompInst; + break; + } + if (nextCompInst == this) + { + //We encountered ourselves while searching for the compositor - + //we are earlier in the chain. + beforeMe = false; + } + } + + if (refCompInst == 0 || !refCompInst->getEnabled()) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Referencing inactive compositor texture", + "CompositorInstance::getTargetForTex"); + } + if (!beforeMe) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Referencing compositor that is later in the chain", + "CompositorInstance::getTargetForTex"); + } + return refCompInst->getRenderTarget(texDef->refTexName); + } + case CompositionTechnique::TS_GLOBAL: + { + //Chain and global case - the referenced compositor will know how to handle + const CompositorPtr& refComp = CompositorManager::getSingleton().getByName(texDef->refCompName); + if(refComp.isNull()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor", + "CompositorInstance::getTargetForTex"); + } + return refComp->getRenderTarget(texDef->refTexName); + } + case CompositionTechnique::TS_LOCAL: + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Referencing local compositor texture", + "CompositorInstance::getTargetForTex"); + } + } + + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Non-existent local texture name", + "CompositorInstance::getTargetForTex"); } //----------------------------------------------------------------------- const String &CompositorInstance::getSourceForTex(const String &name, size_t mrtIndex) { - CompositionTechnique::TextureDefinition* texDef = mTechnique->getTextureDefinition(name); - if(texDef == 0) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent TextureDefinition", + CompositionTechnique::TextureDefinition* texDef = mTechnique->getTextureDefinition(name); + if(texDef == 0) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent TextureDefinition", "CompositorInstance::getSourceForTex"); - } + } - //Check if texture definition is reference - if(!texDef->refCompName.empty()) - { - //This TextureDefinition is reference. - //Since referenced TD's have no info except name we have to find original TD - - CompositionTechnique::TextureDefinition* refTexDef = 0; + //Check if texture definition is reference + if(!texDef->refCompName.empty()) + { + //This TextureDefinition is reference. + //Since referenced TD's have no info except name we have to find original TD + + CompositionTechnique::TextureDefinition* refTexDef = 0; - //Try chain first - if(mChain) - { - CompositorInstance* refCompInst = mChain->getCompositor(texDef->refCompName); - if(refCompInst) - { - refTexDef = refCompInst->getCompositor()-> + //Try chain first + if(mChain) + { + CompositorInstance* refCompInst = mChain->getCompositor(texDef->refCompName); + if(refCompInst) + { + refTexDef = refCompInst->getCompositor()-> getSupportedTechnique(refCompInst->getScheme())->getTextureDefinition(texDef->refTexName); - } - else - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor", + } + else + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor", "CompositorInstance::getSourceForTex"); - } - } + } + } - if(refTexDef == 0) - { - //Still NULL. Try global search. + if(refTexDef == 0) + { + //Still NULL. Try global search. const CompositorPtr &refComp = CompositorManager::getSingleton().getByName(texDef->refCompName); - if(!refComp.isNull()) - { - refTexDef = refComp->getSupportedTechnique()->getTextureDefinition(texDef->refTexName); - } - } + if(!refComp.isNull()) + { + refTexDef = refComp->getSupportedTechnique()->getTextureDefinition(texDef->refTexName); + } + } - if(refTexDef == 0) - { - //Still NULL - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor texture", + if(refTexDef == 0) + { + //Still NULL + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor texture", "CompositorInstance::getSourceForTex"); - } + } - switch(refTexDef->scope) - { - case CompositionTechnique::TS_CHAIN: - { - //Find the instance and check if it is before us - CompositorInstance* refCompInst = 0; + switch(refTexDef->scope) + { + case CompositionTechnique::TS_CHAIN: + { + //Find the instance and check if it is before us + CompositorInstance* refCompInst = 0; OgreAssert(mChain, "Undefined compositor chain"); - CompositorChain::InstanceIterator it = mChain->getCompositors(); - bool beforeMe = true; - while (it.hasMoreElements()) - { - CompositorInstance* nextCompInst = it.getNext(); - if (nextCompInst->getCompositor()->getName() == texDef->refCompName) - { - refCompInst = nextCompInst; - break; - } - if (nextCompInst == this) - { - //We encountered ourselves while searching for the compositor - - //we are earlier in the chain. - beforeMe = false; - } - } - - if (refCompInst == 0 || !refCompInst->getEnabled()) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Referencing inactive compositor texture", - "CompositorInstance::getSourceForTex"); - } - if (!beforeMe) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Referencing compositor that is later in the chain", - "CompositorInstance::getSourceForTex"); - } - return refCompInst->getTextureInstanceName(texDef->refTexName, mrtIndex); - } - case CompositionTechnique::TS_GLOBAL: - { - //Chain and global case - the referenced compositor will know how to handle - const CompositorPtr& refComp = CompositorManager::getSingleton().getByName(texDef->refCompName); - if(refComp.isNull()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor", - "CompositorInstance::getSourceForTex"); - } - return refComp->getTextureInstanceName(texDef->refTexName, mrtIndex); - } - case CompositionTechnique::TS_LOCAL: - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Referencing local compositor texture", - "CompositorInstance::getSourceForTex"); - } - - } // End of handling texture references - - if (texDef->formatList.size() == 1) - { - //This is a simple texture - LocalTextureMap::iterator i = mLocalTextures.find(name); - if(i != mLocalTextures.end()) - { - return i->second->getName(); - } - } - else - { - // try MRTs - texture (rather than target) - LocalTextureMap::iterator i = mLocalTextures.find(getMRTTexLocalName(name, mrtIndex)); - if (i != mLocalTextures.end()) - { - return i->second->getName(); - } - } - - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Non-existent local texture name", - "CompositorInstance::getSourceForTex"); + CompositorChain::InstanceIterator it = mChain->getCompositors(); + bool beforeMe = true; + while (it.hasMoreElements()) + { + CompositorInstance* nextCompInst = it.getNext(); + if (nextCompInst->getCompositor()->getName() == texDef->refCompName) + { + refCompInst = nextCompInst; + break; + } + if (nextCompInst == this) + { + //We encountered ourselves while searching for the compositor - + //we are earlier in the chain. + beforeMe = false; + } + } + + if (refCompInst == 0 || !refCompInst->getEnabled()) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Referencing inactive compositor texture", + "CompositorInstance::getSourceForTex"); + } + if (!beforeMe) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Referencing compositor that is later in the chain", + "CompositorInstance::getSourceForTex"); + } + return refCompInst->getTextureInstanceName(texDef->refTexName, mrtIndex); + } + case CompositionTechnique::TS_GLOBAL: + { + //Chain and global case - the referenced compositor will know how to handle + const CompositorPtr& refComp = CompositorManager::getSingleton().getByName(texDef->refCompName); + if(refComp.isNull()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Referencing non-existent compositor", + "CompositorInstance::getSourceForTex"); + } + return refComp->getTextureInstanceName(texDef->refTexName, mrtIndex); + } + case CompositionTechnique::TS_LOCAL: + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Referencing local compositor texture", + "CompositorInstance::getSourceForTex"); + } + + } // End of handling texture references + + if (texDef->formatList.size() == 1) + { + //This is a simple texture + LocalTextureMap::iterator i = mLocalTextures.find(name); + if(i != mLocalTextures.end()) + { + return i->second->getName(); + } + } + else + { + // try MRTs - texture (rather than target) + LocalTextureMap::iterator i = mLocalTextures.find(getMRTTexLocalName(name, mrtIndex)); + if (i != mLocalTextures.end()) + { + return i->second->getName(); + } + } + + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Non-existent local texture name", + "CompositorInstance::getSourceForTex"); } //----------------------------------------------------------------------- void CompositorInstance::queueRenderSystemOp(TargetOperation &finalState, RenderSystemOperation *op) { - /// Store operation for current QueueGroup ID - finalState.renderSystemOperations.push_back(RenderSystemOpPair(finalState.currentQueueGroupID, op)); - /// Tell parent for deletion - mChain->_queuedOperation(op); + /// Store operation for current QueueGroup ID + finalState.renderSystemOperations.push_back(RenderSystemOpPair(finalState.currentQueueGroupID, op)); + /// Tell parent for deletion + mChain->_queuedOperation(op); } //----------------------------------------------------------------------- void CompositorInstance::addListener(Listener *l) { - mListeners.push_back(l); + mListeners.push_back(l); } //----------------------------------------------------------------------- void CompositorInstance::removeListener(Listener *l) { - mListeners.erase(std::find(mListeners.begin(), mListeners.end(), l)); + mListeners.erase(std::find(mListeners.begin(), mListeners.end(), l)); } //----------------------------------------------------------------------- void CompositorInstance::_fireNotifyMaterialSetup(uint32 pass_id, MaterialPtr &mat) { - Listeners::iterator i, iend=mListeners.end(); - for(i=mListeners.begin(); i!=iend; ++i) - (*i)->notifyMaterialSetup(pass_id, mat); + Listeners::iterator i, iend=mListeners.end(); + for(i=mListeners.begin(); i!=iend; ++i) + (*i)->notifyMaterialSetup(pass_id, mat); } //----------------------------------------------------------------------- void CompositorInstance::_fireNotifyMaterialRender(uint32 pass_id, MaterialPtr &mat) { - Listeners::iterator i, iend=mListeners.end(); - for(i=mListeners.begin(); i!=iend; ++i) - (*i)->notifyMaterialRender(pass_id, mat); + Listeners::iterator i, iend=mListeners.end(); + for(i=mListeners.begin(); i!=iend; ++i) + (*i)->notifyMaterialRender(pass_id, mat); } //----------------------------------------------------------------------- void CompositorInstance::_fireNotifyResourcesCreated(bool forResizeOnly) { - Listeners::iterator i, iend=mListeners.end(); - for(i=mListeners.begin(); i!=iend; ++i) - (*i)->notifyResourcesCreated(forResizeOnly); + Listeners::iterator i, iend=mListeners.end(); + for(i=mListeners.begin(); i!=iend; ++i) + (*i)->notifyResourcesCreated(forResizeOnly); } //----------------------------------------------------------------------- void CompositorInstance::notifyCameraChanged(Camera* camera) { - // update local texture's viewports. - LocalTextureMap::iterator localTexIter = mLocalTextures.begin(); - LocalTextureMap::iterator localTexIterEnd = mLocalTextures.end(); - while (localTexIter != localTexIterEnd) - { - RenderTexture* target = localTexIter->second->getBuffer()->getRenderTarget(); - // skip target that has no viewport (this means texture is under MRT) - if (target->getNumViewports() == 1) - { - target->getViewport(0)->setCamera(camera); - } - ++localTexIter; - } - - // update MRT's viewports. - LocalMRTMap::iterator localMRTIter = mLocalMRTs.begin(); - LocalMRTMap::iterator localMRTIterEnd = mLocalMRTs.end(); - while (localMRTIter != localMRTIterEnd) - { - MultiRenderTarget* target = localMRTIter->second; - target->getViewport(0)->setCamera(camera); - ++localMRTIter; - } + // update local texture's viewports. + LocalTextureMap::iterator localTexIter = mLocalTextures.begin(); + LocalTextureMap::iterator localTexIterEnd = mLocalTextures.end(); + while (localTexIter != localTexIterEnd) + { + RenderTexture* target = localTexIter->second->getBuffer()->getRenderTarget(); + // skip target that has no viewport (this means texture is under MRT) + if (target->getNumViewports() == 1) + { + target->getViewport(0)->setCamera(camera); + } + ++localTexIter; + } + + // update MRT's viewports. + LocalMRTMap::iterator localMRTIter = mLocalMRTs.begin(); + LocalMRTMap::iterator localMRTIterEnd = mLocalMRTs.end(); + while (localMRTIter != localMRTIterEnd) + { + MultiRenderTarget* target = localMRTIter->second; + target->getViewport(0)->setCamera(camera); + ++localMRTIter; + } } //----------------------------------------------------------------------- CompositorInstance::RenderSystemOperation::~RenderSystemOperation() diff --git a/OgreMain/src/OgreCompositorManager.cpp b/OgreMain/src/OgreCompositorManager.cpp index e055b24d010..f6ed6da5402 100644 --- a/OgreMain/src/OgreCompositorManager.cpp +++ b/OgreMain/src/OgreCompositorManager.cpp @@ -43,38 +43,38 @@ namespace Ogre { template<> CompositorManager* Singleton::msSingleton = 0; CompositorManager* CompositorManager::getSingletonPtr(void) { - return msSingleton; + return msSingleton; } CompositorManager& CompositorManager::getSingleton(void) { - assert( msSingleton ); return ( *msSingleton ); + assert( msSingleton ); return ( *msSingleton ); }//----------------------------------------------------------------------- CompositorManager::CompositorManager(): - mRectangle(0) + mRectangle(0) { - initialise(); + initialise(); - // Loading order (just after materials) - mLoadOrder = 110.0f; + // Loading order (just after materials) + mLoadOrder = 110.0f; - // Resource type - mResourceType = "Compositor"; + // Resource type + mResourceType = "Compositor"; - // Register with resource group manager - ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); + // Register with resource group manager + ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); } //----------------------------------------------------------------------- CompositorManager::~CompositorManager() { freeChains(); - freePooledTextures(false); - OGRE_DELETE mRectangle; + freePooledTextures(false); + OGRE_DELETE mRectangle; - // Resources cleared by superclass - // Unregister with resource group manager - ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); - ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); + // Resources cleared by superclass + // Unregister with resource group manager + ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); + ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); } //----------------------------------------------------------------------- Resource* CompositorManager::createImpl(const String& name, ResourceHandle handle, @@ -85,15 +85,15 @@ Resource* CompositorManager::createImpl(const String& name, ResourceHandle handl } //----------------------------------------------------------------------- CompositorPtr CompositorManager::create (const String& name, const String& group, - bool isManual, ManualResourceLoader* loader, - const NameValuePairList* createParams) + bool isManual, ManualResourceLoader* loader, + const NameValuePairList* createParams) { - return createResource(name,group,isManual,loader,createParams).staticCast(); + return createResource(name,group,isManual,loader,createParams).staticCast(); } //----------------------------------------------------------------------- CompositorPtr CompositorManager::getByName(const String& name, const String& groupName) { - return getResourceByName(name, groupName).staticCast(); + return getResourceByName(name, groupName).staticCast(); } //----------------------------------------------------------------------- void CompositorManager::initialise(void) @@ -102,7 +102,7 @@ void CompositorManager::initialise(void) //----------------------------------------------------------------------- void CompositorManager::parseScript(DataStreamPtr& stream, const String& groupName) { - ScriptCompilerManager::getSingleton().parseScript(stream, groupName); + ScriptCompilerManager::getSingleton().parseScript(stream, groupName); } //----------------------------------------------------------------------- CompositorChain *CompositorManager::getCompositorChain(Viewport *vp) @@ -137,8 +137,8 @@ void CompositorManager::removeCompositorChain(Viewport *vp) //----------------------------------------------------------------------- void CompositorManager::removeAll(void) { - freeChains(); - ResourceManager::removeAll(); + freeChains(); + ResourceManager::removeAll(); } //----------------------------------------------------------------------- void CompositorManager::freeChains() @@ -153,406 +153,406 @@ void CompositorManager::freeChains() //----------------------------------------------------------------------- Renderable *CompositorManager::_getTexturedRectangle2D() { - if(!mRectangle) - { - /// 2D rectangle, to use for render_quad passes - mRectangle = OGRE_NEW Rectangle2D(true, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); - } - RenderSystem* rs = Root::getSingleton().getRenderSystem(); - Viewport* vp = rs->_getViewport(); - Real hOffset = rs->getHorizontalTexelOffset() / (0.5f * vp->getActualWidth()); - Real vOffset = rs->getVerticalTexelOffset() / (0.5f * vp->getActualHeight()); - mRectangle->setCorners(-1 + hOffset, 1 - vOffset, 1 + hOffset, -1 - vOffset); - return mRectangle; + if(!mRectangle) + { + /// 2D rectangle, to use for render_quad passes + mRectangle = OGRE_NEW Rectangle2D(true, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); + } + RenderSystem* rs = Root::getSingleton().getRenderSystem(); + Viewport* vp = rs->_getViewport(); + Real hOffset = rs->getHorizontalTexelOffset() / (0.5f * vp->getActualWidth()); + Real vOffset = rs->getVerticalTexelOffset() / (0.5f * vp->getActualHeight()); + mRectangle->setCorners(-1 + hOffset, 1 - vOffset, 1 + hOffset, -1 - vOffset); + return mRectangle; } //----------------------------------------------------------------------- CompositorInstance *CompositorManager::addCompositor(Viewport *vp, const String &compositor, int addPosition) { - CompositorPtr comp = getByName(compositor); - if(comp.isNull()) - return 0; - CompositorChain *chain = getCompositorChain(vp); - return chain->addCompositor(comp, addPosition==-1 ? CompositorChain::LAST : (size_t)addPosition); + CompositorPtr comp = getByName(compositor); + if(comp.isNull()) + return 0; + CompositorChain *chain = getCompositorChain(vp); + return chain->addCompositor(comp, addPosition==-1 ? CompositorChain::LAST : (size_t)addPosition); } //----------------------------------------------------------------------- void CompositorManager::removeCompositor(Viewport *vp, const String &compositor) { - CompositorChain *chain = getCompositorChain(vp); - for(size_t pos=0; pos < chain->getNumCompositors(); ++pos) - { - CompositorInstance *instance = chain->getCompositor(pos); - if(instance->getCompositor()->getName() == compositor) - { - chain->removeCompositor(pos); - break; - } - } + CompositorChain *chain = getCompositorChain(vp); + for(size_t pos=0; pos < chain->getNumCompositors(); ++pos) + { + CompositorInstance *instance = chain->getCompositor(pos); + if(instance->getCompositor()->getName() == compositor) + { + chain->removeCompositor(pos); + break; + } + } } //----------------------------------------------------------------------- void CompositorManager::setCompositorEnabled(Viewport *vp, const String &compositor, bool value) { - CompositorChain *chain = getCompositorChain(vp); - for(size_t pos=0; pos < chain->getNumCompositors(); ++pos) - { - CompositorInstance *instance = chain->getCompositor(pos); - if(instance->getCompositor()->getName() == compositor) - { - chain->setCompositorEnabled(pos, value); - break; - } - } + CompositorChain *chain = getCompositorChain(vp); + for(size_t pos=0; pos < chain->getNumCompositors(); ++pos) + { + CompositorInstance *instance = chain->getCompositor(pos); + if(instance->getCompositor()->getName() == compositor) + { + chain->setCompositorEnabled(pos, value); + break; + } + } } //--------------------------------------------------------------------- void CompositorManager::_reconstructAllCompositorResources() { - // In order to deal with shared resources, we have to disable *all* compositors - // first, that way shared resources will get freed - typedef vector::type InstVec; - InstVec instancesToReenable; - for (Chains::iterator i = mChains.begin(); i != mChains.end(); ++i) - { - CompositorChain* chain = i->second; - CompositorChain::InstanceIterator instIt = chain->getCompositors(); - while (instIt.hasMoreElements()) - { - CompositorInstance* inst = instIt.getNext(); - if (inst->getEnabled()) - { - inst->setEnabled(false); - instancesToReenable.push_back(inst); - } - } - } - - //UVs are lost, and will never be reconstructed unless we do them again, now - if( mRectangle ) - mRectangle->setDefaultUVs(); - - for (InstVec::iterator i = instancesToReenable.begin(); i != instancesToReenable.end(); ++i) - { - CompositorInstance* inst = *i; - inst->setEnabled(true); - } + // In order to deal with shared resources, we have to disable *all* compositors + // first, that way shared resources will get freed + typedef vector::type InstVec; + InstVec instancesToReenable; + for (Chains::iterator i = mChains.begin(); i != mChains.end(); ++i) + { + CompositorChain* chain = i->second; + CompositorChain::InstanceIterator instIt = chain->getCompositors(); + while (instIt.hasMoreElements()) + { + CompositorInstance* inst = instIt.getNext(); + if (inst->getEnabled()) + { + inst->setEnabled(false); + instancesToReenable.push_back(inst); + } + } + } + + //UVs are lost, and will never be reconstructed unless we do them again, now + if( mRectangle ) + mRectangle->setDefaultUVs(); + + for (InstVec::iterator i = instancesToReenable.begin(); i != instancesToReenable.end(); ++i) + { + CompositorInstance* inst = *i; + inst->setEnabled(true); + } } //--------------------------------------------------------------------- TexturePtr CompositorManager::getPooledTexture(const String& name, - const String& localName, - size_t w, size_t h, PixelFormat f, uint aa, const String& aaHint, bool srgb, - CompositorManager::UniqueTextureSet& texturesAssigned, - CompositorInstance* inst, CompositionTechnique::TextureScope scope) + const String& localName, + size_t w, size_t h, PixelFormat f, uint aa, const String& aaHint, bool srgb, + CompositorManager::UniqueTextureSet& texturesAssigned, + CompositorInstance* inst, CompositionTechnique::TextureScope scope) { - if (scope == CompositionTechnique::TS_GLOBAL) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Global scope texture can not be pooled.", - "CompositorManager::getPooledTexture"); - } - - TextureDef def(w, h, f, aa, aaHint, srgb); - - if (scope == CompositionTechnique::TS_CHAIN) - { - StringPair pair = std::make_pair(inst->getCompositor()->getName(), localName); - TextureDefMap& defMap = mChainTexturesByDef[pair]; - TextureDefMap::iterator it = defMap.find(def); - if (it != defMap.end()) - { - return it->second; - } - // ok, we need to create a new one - TexturePtr newTex = TextureManager::getSingleton().createManual( - name, - ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - (uint)w, (uint)h, 0, f, TU_RENDERTARGET, 0, - srgb, aa, aaHint); - defMap.insert(TextureDefMap::value_type(def, newTex)); - return newTex; - } - - TexturesByDef::iterator i = mTexturesByDef.find(def); - if (i == mTexturesByDef.end()) - { - TextureList* texList = OGRE_NEW_T(TextureList, MEMCATEGORY_GENERAL); - i = mTexturesByDef.insert(TexturesByDef::value_type(def, texList)).first; - } - CompositorInstance* previous = inst->getChain()->getPreviousInstance(inst); - CompositorInstance* next = inst->getChain()->getNextInstance(inst); - - TexturePtr ret; - TextureList* texList = i->second; - // iterate over the existing textures and check if we can re-use - for (TextureList::iterator t = texList->begin(); t != texList->end(); ++t) - { - TexturePtr& tex = *t; - // check not already used - if (texturesAssigned.find(tex.get()) == texturesAssigned.end()) - { - bool allowReuse = true; - // ok, we didn't use this one already - // however, there is an edge case where if we re-use a texture - // which has an 'input previous' pass, and it is chained from another - // compositor, we can end up trying to use the same texture for both - // so, never allow a texture with an input previous pass to be - // shared with its immediate predecessor in the chain - if (isInputPreviousTarget(inst, localName)) - { - // Check whether this is also an input to the output target of previous - // can't use CompositorInstance::mPreviousInstance, only set up - // during compile - if (previous && isInputToOutputTarget(previous, tex)) - allowReuse = false; - } - // now check the other way around since we don't know what order they're bound in - if (isInputToOutputTarget(inst, localName)) - { - - if (next && isInputPreviousTarget(next, tex)) - allowReuse = false; - } - - if (allowReuse) - { - ret = tex; - break; - } - - } - } - - if (ret.isNull()) - { - // ok, we need to create a new one - ret = TextureManager::getSingleton().createManual( - name, - ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, - (uint)w, (uint)h, 0, f, TU_RENDERTARGET, 0, - srgb, aa, aaHint); - - texList->push_back(ret); - - } - - // record that we used this one in the requester's list - texturesAssigned.insert(ret.get()); - - - return ret; + if (scope == CompositionTechnique::TS_GLOBAL) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Global scope texture can not be pooled.", + "CompositorManager::getPooledTexture"); + } + + TextureDef def(w, h, f, aa, aaHint, srgb); + + if (scope == CompositionTechnique::TS_CHAIN) + { + StringPair pair = std::make_pair(inst->getCompositor()->getName(), localName); + TextureDefMap& defMap = mChainTexturesByDef[pair]; + TextureDefMap::iterator it = defMap.find(def); + if (it != defMap.end()) + { + return it->second; + } + // ok, we need to create a new one + TexturePtr newTex = TextureManager::getSingleton().createManual( + name, + ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, + (uint)w, (uint)h, 0, f, TU_RENDERTARGET, 0, + srgb, aa, aaHint); + defMap.insert(TextureDefMap::value_type(def, newTex)); + return newTex; + } + + TexturesByDef::iterator i = mTexturesByDef.find(def); + if (i == mTexturesByDef.end()) + { + TextureList* texList = OGRE_NEW_T(TextureList, MEMCATEGORY_GENERAL); + i = mTexturesByDef.insert(TexturesByDef::value_type(def, texList)).first; + } + CompositorInstance* previous = inst->getChain()->getPreviousInstance(inst); + CompositorInstance* next = inst->getChain()->getNextInstance(inst); + + TexturePtr ret; + TextureList* texList = i->second; + // iterate over the existing textures and check if we can re-use + for (TextureList::iterator t = texList->begin(); t != texList->end(); ++t) + { + TexturePtr& tex = *t; + // check not already used + if (texturesAssigned.find(tex.get()) == texturesAssigned.end()) + { + bool allowReuse = true; + // ok, we didn't use this one already + // however, there is an edge case where if we re-use a texture + // which has an 'input previous' pass, and it is chained from another + // compositor, we can end up trying to use the same texture for both + // so, never allow a texture with an input previous pass to be + // shared with its immediate predecessor in the chain + if (isInputPreviousTarget(inst, localName)) + { + // Check whether this is also an input to the output target of previous + // can't use CompositorInstance::mPreviousInstance, only set up + // during compile + if (previous && isInputToOutputTarget(previous, tex)) + allowReuse = false; + } + // now check the other way around since we don't know what order they're bound in + if (isInputToOutputTarget(inst, localName)) + { + + if (next && isInputPreviousTarget(next, tex)) + allowReuse = false; + } + + if (allowReuse) + { + ret = tex; + break; + } + + } + } + + if (ret.isNull()) + { + // ok, we need to create a new one + ret = TextureManager::getSingleton().createManual( + name, + ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, + (uint)w, (uint)h, 0, f, TU_RENDERTARGET, 0, + srgb, aa, aaHint); + + texList->push_back(ret); + + } + + // record that we used this one in the requester's list + texturesAssigned.insert(ret.get()); + + + return ret; } //--------------------------------------------------------------------- bool CompositorManager::isInputPreviousTarget(CompositorInstance* inst, const Ogre::String& localName) { - CompositionTechnique::TargetPassIterator tpit = inst->getTechnique()->getTargetPassIterator(); - while(tpit.hasMoreElements()) - { - CompositionTargetPass* tp = tpit.getNext(); - if (tp->getInputMode() == CompositionTargetPass::IM_PREVIOUS && - tp->getOutputName() == localName) - { - return true; - } + CompositionTechnique::TargetPassIterator tpit = inst->getTechnique()->getTargetPassIterator(); + while(tpit.hasMoreElements()) + { + CompositionTargetPass* tp = tpit.getNext(); + if (tp->getInputMode() == CompositionTargetPass::IM_PREVIOUS && + tp->getOutputName() == localName) + { + return true; + } - } + } - return false; + return false; } //--------------------------------------------------------------------- bool CompositorManager::isInputPreviousTarget(CompositorInstance* inst, TexturePtr tex) { - CompositionTechnique::TargetPassIterator tpit = inst->getTechnique()->getTargetPassIterator(); - while(tpit.hasMoreElements()) - { - CompositionTargetPass* tp = tpit.getNext(); - if (tp->getInputMode() == CompositionTargetPass::IM_PREVIOUS) - { - // Don't have to worry about an MRT, because no MRT can be input previous - TexturePtr t = inst->getTextureInstance(tp->getOutputName(), 0); - if (!t.isNull() && t.get() == tex.get()) - return true; - } - - } - - return false; + CompositionTechnique::TargetPassIterator tpit = inst->getTechnique()->getTargetPassIterator(); + while(tpit.hasMoreElements()) + { + CompositionTargetPass* tp = tpit.getNext(); + if (tp->getInputMode() == CompositionTargetPass::IM_PREVIOUS) + { + // Don't have to worry about an MRT, because no MRT can be input previous + TexturePtr t = inst->getTextureInstance(tp->getOutputName(), 0); + if (!t.isNull() && t.get() == tex.get()) + return true; + } + + } + + return false; } //--------------------------------------------------------------------- bool CompositorManager::isInputToOutputTarget(CompositorInstance* inst, const Ogre::String& localName) { - CompositionTargetPass* tp = inst->getTechnique()->getOutputTargetPass(); - CompositionTargetPass::PassIterator pit = tp->getPassIterator(); + CompositionTargetPass* tp = inst->getTechnique()->getOutputTargetPass(); + CompositionTargetPass::PassIterator pit = tp->getPassIterator(); - while(pit.hasMoreElements()) - { - CompositionPass* p = pit.getNext(); - for (size_t i = 0; i < p->getNumInputs(); ++i) - { - if (p->getInput(i).name == localName) - return true; - } - } + while(pit.hasMoreElements()) + { + CompositionPass* p = pit.getNext(); + for (size_t i = 0; i < p->getNumInputs(); ++i) + { + if (p->getInput(i).name == localName) + return true; + } + } - return false; + return false; } //---------------------------------------------------------------------() bool CompositorManager::isInputToOutputTarget(CompositorInstance* inst, TexturePtr tex) { - CompositionTargetPass* tp = inst->getTechnique()->getOutputTargetPass(); - CompositionTargetPass::PassIterator pit = tp->getPassIterator(); - - while(pit.hasMoreElements()) - { - CompositionPass* p = pit.getNext(); - for (size_t i = 0; i < p->getNumInputs(); ++i) - { - TexturePtr t = inst->getTextureInstance(p->getInput(i).name, 0); - if (!t.isNull() && t.get() == tex.get()) - return true; - } - } - - return false; + CompositionTargetPass* tp = inst->getTechnique()->getOutputTargetPass(); + CompositionTargetPass::PassIterator pit = tp->getPassIterator(); + + while(pit.hasMoreElements()) + { + CompositionPass* p = pit.getNext(); + for (size_t i = 0; i < p->getNumInputs(); ++i) + { + TexturePtr t = inst->getTextureInstance(p->getInput(i).name, 0); + if (!t.isNull() && t.get() == tex.get()) + return true; + } + } + + return false; } //--------------------------------------------------------------------- void CompositorManager::freePooledTextures(bool onlyIfUnreferenced) { - if (onlyIfUnreferenced) - { - for (TexturesByDef::iterator i = mTexturesByDef.begin(); i != mTexturesByDef.end(); ++i) - { - TextureList* texList = i->second; - for (TextureList::iterator j = texList->begin(); j != texList->end();) - { - // if the resource system, plus this class, are the only ones to have a reference.. - // NOTE: any material references will stop this texture getting freed (e.g. compositor demo) - // until this routine is called again after the material no longer references the texture - if (j->useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) - { - TextureManager::getSingleton().remove((*j)->getHandle()); - j = texList->erase(j); - } - else - ++j; - } - } - for (ChainTexturesByDef::iterator i = mChainTexturesByDef.begin(); i != mChainTexturesByDef.end(); ++i) - { - TextureDefMap& texMap = i->second; - for (TextureDefMap::iterator j = texMap.begin(); j != texMap.end();) - { - const TexturePtr& tex = j->second; - if (tex.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) - { - TextureManager::getSingleton().remove(tex->getHandle()); - texMap.erase(j++); - } - else - ++j; - } - } - } - else - { - // destroy all - for (TexturesByDef::iterator i = mTexturesByDef.begin(); i != mTexturesByDef.end(); ++i) - { - OGRE_DELETE_T(i->second, TextureList, MEMCATEGORY_GENERAL); - } - mTexturesByDef.clear(); - mChainTexturesByDef.clear(); - } + if (onlyIfUnreferenced) + { + for (TexturesByDef::iterator i = mTexturesByDef.begin(); i != mTexturesByDef.end(); ++i) + { + TextureList* texList = i->second; + for (TextureList::iterator j = texList->begin(); j != texList->end();) + { + // if the resource system, plus this class, are the only ones to have a reference.. + // NOTE: any material references will stop this texture getting freed (e.g. compositor demo) + // until this routine is called again after the material no longer references the texture + if (j->useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) + { + TextureManager::getSingleton().remove((*j)->getHandle()); + j = texList->erase(j); + } + else + ++j; + } + } + for (ChainTexturesByDef::iterator i = mChainTexturesByDef.begin(); i != mChainTexturesByDef.end(); ++i) + { + TextureDefMap& texMap = i->second; + for (TextureDefMap::iterator j = texMap.begin(); j != texMap.end();) + { + const TexturePtr& tex = j->second; + if (tex.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) + { + TextureManager::getSingleton().remove(tex->getHandle()); + texMap.erase(j++); + } + else + ++j; + } + } + } + else + { + // destroy all + for (TexturesByDef::iterator i = mTexturesByDef.begin(); i != mTexturesByDef.end(); ++i) + { + OGRE_DELETE_T(i->second, TextureList, MEMCATEGORY_GENERAL); + } + mTexturesByDef.clear(); + mChainTexturesByDef.clear(); + } } //--------------------------------------------------------------------- void CompositorManager::registerCompositorLogic(const String& name, CompositorLogic* logic) -{ - if (name.empty()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Compositor logic name must not be empty.", - "CompositorManager::registerCompositorLogic"); - } - if (mCompositorLogics.find(name) != mCompositorLogics.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "Compositor logic '" + name + "' already exists.", - "CompositorManager::registerCompositorLogic"); - } - mCompositorLogics[name] = logic; +{ + if (name.empty()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Compositor logic name must not be empty.", + "CompositorManager::registerCompositorLogic"); + } + if (mCompositorLogics.find(name) != mCompositorLogics.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "Compositor logic '" + name + "' already exists.", + "CompositorManager::registerCompositorLogic"); + } + mCompositorLogics[name] = logic; } //--------------------------------------------------------------------- void CompositorManager::unregisterCompositorLogic(const String& name) { - CompositorLogicMap::iterator itor = mCompositorLogics.find(name); - if( itor == mCompositorLogics.end() ) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Compositor logic '" + name + "' not registered.", - "CompositorManager::unregisterCompositorLogic"); - } - - mCompositorLogics.erase( itor ); + CompositorLogicMap::iterator itor = mCompositorLogics.find(name); + if( itor == mCompositorLogics.end() ) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Compositor logic '" + name + "' not registered.", + "CompositorManager::unregisterCompositorLogic"); + } + + mCompositorLogics.erase( itor ); } //--------------------------------------------------------------------- CompositorLogic* CompositorManager::getCompositorLogic(const String& name) { - CompositorLogicMap::iterator it = mCompositorLogics.find(name); - if (it == mCompositorLogics.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Compositor logic '" + name + "' not registered.", - "CompositorManager::getCompositorLogic"); - } - return it->second; + CompositorLogicMap::iterator it = mCompositorLogics.find(name); + if (it == mCompositorLogics.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Compositor logic '" + name + "' not registered.", + "CompositorManager::getCompositorLogic"); + } + return it->second; } //--------------------------------------------------------------------- void CompositorManager::registerCustomCompositionPass(const String& name, CustomCompositionPass* logic) -{ - if (name.empty()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Custom composition pass name must not be empty.", - "CompositorManager::registerCustomCompositionPass"); - } - if (mCustomCompositionPasses.find(name) != mCustomCompositionPasses.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "Custom composition pass '" + name + "' already exists.", - "CompositorManager::registerCustomCompositionPass"); - } - mCustomCompositionPasses[name] = logic; +{ + if (name.empty()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Custom composition pass name must not be empty.", + "CompositorManager::registerCustomCompositionPass"); + } + if (mCustomCompositionPasses.find(name) != mCustomCompositionPasses.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "Custom composition pass '" + name + "' already exists.", + "CompositorManager::registerCustomCompositionPass"); + } + mCustomCompositionPasses[name] = logic; } //--------------------------------------------------------------------- CustomCompositionPass* CompositorManager::getCustomCompositionPass(const String& name) { - CustomCompositionPassMap::iterator it = mCustomCompositionPasses.find(name); - if (it == mCustomCompositionPasses.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Custom composition pass '" + name + "' not registered.", - "CompositorManager::getCustomCompositionPass"); - } - return it->second; + CustomCompositionPassMap::iterator it = mCustomCompositionPasses.find(name); + if (it == mCustomCompositionPasses.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Custom composition pass '" + name + "' not registered.", + "CompositorManager::getCustomCompositionPass"); + } + return it->second; } //----------------------------------------------------------------------- void CompositorManager::_relocateChain( Viewport* sourceVP, Viewport* destVP ) { - if (sourceVP != destVP) - { - CompositorChain *chain = getCompositorChain(sourceVP); - Ogre::RenderTarget *srcTarget = sourceVP->getTarget(); - Ogre::RenderTarget *dstTarget = destVP->getTarget(); - if (srcTarget != dstTarget) - { - srcTarget->removeListener(chain); - dstTarget->addListener(chain); - } - chain->_notifyViewport(destVP); - mChains.erase(sourceVP); - mChains[destVP] = chain; - } + if (sourceVP != destVP) + { + CompositorChain *chain = getCompositorChain(sourceVP); + Ogre::RenderTarget *srcTarget = sourceVP->getTarget(); + Ogre::RenderTarget *dstTarget = destVP->getTarget(); + if (srcTarget != dstTarget) + { + srcTarget->removeListener(chain); + dstTarget->addListener(chain); + } + chain->_notifyViewport(destVP); + mChains.erase(sourceVP); + mChains[destVP] = chain; + } } //----------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreConfigFile.cpp b/OgreMain/src/OgreConfigFile.cpp index 6b885e89b18..9e01a587eef 100644 --- a/OgreMain/src/OgreConfigFile.cpp +++ b/OgreMain/src/OgreConfigFile.cpp @@ -68,39 +68,39 @@ namespace Ogre { void ConfigFile::load(const String& filename, const String& resourceGroup, const String& separators, bool trimWhitespace) { - loadFromResourceSystem(filename, resourceGroup, separators, trimWhitespace); + loadFromResourceSystem(filename, resourceGroup, separators, trimWhitespace); } - //----------------------------------------------------------------------- - void ConfigFile::loadDirect(const String& filename, const String& separators, - bool trimWhitespace) - { + //----------------------------------------------------------------------- + void ConfigFile::loadDirect(const String& filename, const String& separators, + bool trimWhitespace) + { #if OGRE_PLATFORM == OGRE_PLATFORM_NACL OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, "loadDirect is not supported on NaCl - tried to open: " + filename, "ConfigFile::loadDirect"); #endif /* Open the configuration file */ - std::ifstream fp; + std::ifstream fp; // Always open in binary mode - fp.open(filename.c_str(), std::ios::in | std::ios::binary); - if(!fp) - OGRE_EXCEPT( - Exception::ERR_FILE_NOT_FOUND, "'" + filename + "' file not found!", "ConfigFile::load" ); - - // Wrap as a stream - DataStreamPtr stream(OGRE_NEW FileStreamDataStream(filename, &fp, false)); - - load(stream, separators, trimWhitespace); - - } - //----------------------------------------------------------------------- - void ConfigFile::loadFromResourceSystem(const String& filename, - const String& resourceGroup, const String& separators, bool trimWhitespace) - { - DataStreamPtr stream = - ResourceGroupManager::getSingleton().openResource(filename, resourceGroup); - load(stream, separators, trimWhitespace); - } + fp.open(filename.c_str(), std::ios::in | std::ios::binary); + if(!fp) + OGRE_EXCEPT( + Exception::ERR_FILE_NOT_FOUND, "'" + filename + "' file not found!", "ConfigFile::load" ); + + // Wrap as a stream + DataStreamPtr stream(OGRE_NEW FileStreamDataStream(filename, &fp, false)); + + load(stream, separators, trimWhitespace); + + } + //----------------------------------------------------------------------- + void ConfigFile::loadFromResourceSystem(const String& filename, + const String& resourceGroup, const String& separators, bool trimWhitespace) + { + DataStreamPtr stream = + ResourceGroupManager::getSingleton().openResource(filename, resourceGroup); + load(stream, separators, trimWhitespace); + } //----------------------------------------------------------------------- void ConfigFile::load(const DataStreamPtr& stream, const String& separators, bool trimWhitespace) @@ -125,21 +125,21 @@ namespace Ogre { { // Section currentSection = line.substr(1, line.length() - 2); - SettingsBySection::const_iterator seci = mSettings.find(currentSection); - if (seci == mSettings.end()) - { - currentSettings = OGRE_NEW_T(SettingsMultiMap, MEMCATEGORY_GENERAL)(); - mSettings[currentSection] = currentSettings; - } - else - { - currentSettings = seci->second; - } + SettingsBySection::const_iterator seci = mSettings.find(currentSection); + if (seci == mSettings.end()) + { + currentSettings = OGRE_NEW_T(SettingsMultiMap, MEMCATEGORY_GENERAL)(); + mSettings[currentSection] = currentSettings; + } + else + { + currentSettings = seci->second; + } } else { /* Find the first separator character and split the string there */ - Ogre::String::size_type separator_pos = line.find_first_of(separators, 0); + Ogre::String::size_type separator_pos = line.find_first_of(separators, 0); if (separator_pos != Ogre::String::npos) { optName = line.substr(0, separator_pos); diff --git a/OgreMain/src/OgreControllerManager.cpp b/OgreMain/src/OgreControllerManager.cpp index 67b64662ac3..ab6a2a862af 100644 --- a/OgreMain/src/OgreControllerManager.cpp +++ b/OgreMain/src/OgreControllerManager.cpp @@ -44,9 +44,9 @@ namespace Ogre { } //----------------------------------------------------------------------- ControllerManager::ControllerManager() - : mFrameTimeController(OGRE_NEW FrameTimeControllerValue()) - , mPassthroughFunction(OGRE_NEW PassthroughControllerFunction()) - , mLastFrameNumber(0) + : mFrameTimeController(OGRE_NEW FrameTimeControllerValue()) + , mPassthroughFunction(OGRE_NEW PassthroughControllerFunction()) + , mLastFrameNumber(0) { } @@ -101,11 +101,11 @@ namespace Ogre { { return mFrameTimeController; } - //----------------------------------------------------------------------- - const ControllerFunctionRealPtr& ControllerManager::getPassthroughControllerFunction(void) const - { - return mPassthroughFunction; - } + //----------------------------------------------------------------------- + const ControllerFunctionRealPtr& ControllerManager::getPassthroughControllerFunction(void) const + { + return mPassthroughFunction; + } //----------------------------------------------------------------------- Controller* ControllerManager::createTextureAnimator(TextureUnitState* layer, Real sequenceTime) { @@ -117,22 +117,22 @@ namespace Ogre { //----------------------------------------------------------------------- Controller* ControllerManager::createTextureUVScroller(TextureUnitState* layer, Real speed) { - Controller* ret = 0; + Controller* ret = 0; - if (speed != 0) + if (speed != 0) { - SharedPtr< ControllerValue > val; - SharedPtr< ControllerFunction > func; + SharedPtr< ControllerValue > val; + SharedPtr< ControllerFunction > func; - // We do both scrolls with a single controller - val.bind(OGRE_NEW TexCoordModifierControllerValue(layer, true, true)); - // Create function: use -speed since we're altering texture coords so they have reverse effect + // We do both scrolls with a single controller + val.bind(OGRE_NEW TexCoordModifierControllerValue(layer, true, true)); + // Create function: use -speed since we're altering texture coords so they have reverse effect func.bind(OGRE_NEW ScaleControllerFunction(-speed, true)); ret = createController(mFrameTimeController, val, func); - } + } - return ret; - } + return ret; + } //----------------------------------------------------------------------- Controller* ControllerManager::createTextureUScroller(TextureUnitState* layer, Real uSpeed) { @@ -140,8 +140,8 @@ namespace Ogre { if (uSpeed != 0) { - SharedPtr< ControllerValue > uVal; - SharedPtr< ControllerFunction > uFunc; + SharedPtr< ControllerValue > uVal; + SharedPtr< ControllerFunction > uFunc; uVal.bind(OGRE_NEW TexCoordModifierControllerValue(layer, true)); // Create function: use -speed since we're altering texture coords so they have reverse effect @@ -151,15 +151,15 @@ namespace Ogre { return ret; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- Controller* ControllerManager::createTextureVScroller(TextureUnitState* layer, Real vSpeed) { - Controller* ret = 0; + Controller* ret = 0; - if (vSpeed != 0) + if (vSpeed != 0) { - SharedPtr< ControllerValue > vVal; - SharedPtr< ControllerFunction > vFunc; + SharedPtr< ControllerValue > vVal; + SharedPtr< ControllerFunction > vFunc; // Set up a second controller for v scroll vVal.bind(OGRE_NEW TexCoordModifierControllerValue(layer, false, true)); @@ -243,30 +243,30 @@ namespace Ogre { OGRE_DELETE controller; } } - //----------------------------------------------------------------------- - Real ControllerManager::getTimeFactor(void) const { - return static_cast(mFrameTimeController.get())->getTimeFactor(); - } - //----------------------------------------------------------------------- - void ControllerManager::setTimeFactor(Real tf) { - static_cast(mFrameTimeController.getPointer())->setTimeFactor(tf); - } - //----------------------------------------------------------------------- - Real ControllerManager::getFrameDelay(void) const { - return static_cast(mFrameTimeController.get())->getFrameDelay(); - } - //----------------------------------------------------------------------- - void ControllerManager::setFrameDelay(Real fd) { - static_cast(mFrameTimeController.getPointer())->setFrameDelay(fd); - } - //----------------------------------------------------------------------- - Real ControllerManager::getElapsedTime(void) const - { - return static_cast(mFrameTimeController.get())->getElapsedTime(); - } - //----------------------------------------------------------------------- - void ControllerManager::setElapsedTime(Real elapsedTime) - { - static_cast(mFrameTimeController.get())->setElapsedTime(elapsedTime); - } + //----------------------------------------------------------------------- + Real ControllerManager::getTimeFactor(void) const { + return static_cast(mFrameTimeController.get())->getTimeFactor(); + } + //----------------------------------------------------------------------- + void ControllerManager::setTimeFactor(Real tf) { + static_cast(mFrameTimeController.getPointer())->setTimeFactor(tf); + } + //----------------------------------------------------------------------- + Real ControllerManager::getFrameDelay(void) const { + return static_cast(mFrameTimeController.get())->getFrameDelay(); + } + //----------------------------------------------------------------------- + void ControllerManager::setFrameDelay(Real fd) { + static_cast(mFrameTimeController.getPointer())->setFrameDelay(fd); + } + //----------------------------------------------------------------------- + Real ControllerManager::getElapsedTime(void) const + { + return static_cast(mFrameTimeController.get())->getElapsedTime(); + } + //----------------------------------------------------------------------- + void ControllerManager::setElapsedTime(Real elapsedTime) + { + static_cast(mFrameTimeController.get())->setElapsedTime(elapsedTime); + } } diff --git a/OgreMain/src/OgreConvexBody.cpp b/OgreMain/src/OgreConvexBody.cpp index e74573036ee..1278e4e861e 100644 --- a/OgreMain/src/OgreConvexBody.cpp +++ b/OgreMain/src/OgreConvexBody.cpp @@ -5,7 +5,7 @@ This source file is part of OGRE For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd -Copyright (c) 2006 Matthias Fink, netAllied GmbH +Copyright (c) 2006 Matthias Fink, netAllied GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -40,1183 +40,1183 @@ namespace Ogre { - //----------------------------------------------------------------------- - // Statics - //----------------------------------------------------------------------- - ConvexBody::PolygonList ConvexBody::msFreePolygons; + //----------------------------------------------------------------------- + // Statics + //----------------------------------------------------------------------- + ConvexBody::PolygonList ConvexBody::msFreePolygons; #if OGRE_THREAD_SUPPORT OGRE_STATIC_MUTEX_INSTANCE(ConvexBody::msFreePolygonsMutex); #endif - //----------------------------------------------------------------------- - void ConvexBody::_initialisePool() - { + //----------------------------------------------------------------------- + void ConvexBody::_initialisePool() + { OGRE_LOCK_MUTEX(msFreePolygonsMutex); - if (msFreePolygons.empty()) - { - const size_t initialSize = 30; - - // Initialise polygon pool with 30 polys - msFreePolygons.resize(initialSize); - for (size_t i = 0; i < initialSize; ++i) - { - msFreePolygons[i] = OGRE_NEW_T(Polygon, MEMCATEGORY_SCENE_CONTROL)(); - } - } - } - //----------------------------------------------------------------------- - void ConvexBody::_destroyPool() - { + if (msFreePolygons.empty()) + { + const size_t initialSize = 30; + + // Initialise polygon pool with 30 polys + msFreePolygons.resize(initialSize); + for (size_t i = 0; i < initialSize; ++i) + { + msFreePolygons[i] = OGRE_NEW_T(Polygon, MEMCATEGORY_SCENE_CONTROL)(); + } + } + } + //----------------------------------------------------------------------- + void ConvexBody::_destroyPool() + { OGRE_LOCK_MUTEX(msFreePolygonsMutex); - - for (PolygonList::iterator i = msFreePolygons.begin(); - i != msFreePolygons.end(); ++i) - { - OGRE_DELETE_T(*i, Polygon, MEMCATEGORY_SCENE_CONTROL); - } - msFreePolygons.clear(); - } - //----------------------------------------------------------------------- - Polygon* ConvexBody::allocatePolygon() - { + + for (PolygonList::iterator i = msFreePolygons.begin(); + i != msFreePolygons.end(); ++i) + { + OGRE_DELETE_T(*i, Polygon, MEMCATEGORY_SCENE_CONTROL); + } + msFreePolygons.clear(); + } + //----------------------------------------------------------------------- + Polygon* ConvexBody::allocatePolygon() + { OGRE_LOCK_MUTEX(msFreePolygonsMutex); - if (msFreePolygons.empty()) - { - // if we ran out of polys to use, create a new one - // hopefully this one will return to the pool in due course - return OGRE_NEW_T(Polygon, MEMCATEGORY_SCENE_CONTROL)(); - } - else - { - Polygon* ret = msFreePolygons.back(); - ret->reset(); - - msFreePolygons.pop_back(); - - return ret; - - } - } - //----------------------------------------------------------------------- - void ConvexBody::freePolygon(Polygon* poly) - { + if (msFreePolygons.empty()) + { + // if we ran out of polys to use, create a new one + // hopefully this one will return to the pool in due course + return OGRE_NEW_T(Polygon, MEMCATEGORY_SCENE_CONTROL)(); + } + else + { + Polygon* ret = msFreePolygons.back(); + ret->reset(); + + msFreePolygons.pop_back(); + + return ret; + + } + } + //----------------------------------------------------------------------- + void ConvexBody::freePolygon(Polygon* poly) + { OGRE_LOCK_MUTEX(msFreePolygonsMutex); - msFreePolygons.push_back(poly); - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - ConvexBody::ConvexBody() - { - // Reserve space for 8 polys, normally 6 faces plus a couple of clips - mPolygons.reserve(8); - - } - //----------------------------------------------------------------------- - ConvexBody::~ConvexBody() - { - reset(); - } - //----------------------------------------------------------------------- - ConvexBody::ConvexBody( const ConvexBody& cpy ) - { - for ( size_t i = 0; i < cpy.getPolygonCount(); ++i ) - { - Polygon *p = allocatePolygon(); - *p = cpy.getPolygon( i ); - mPolygons.push_back( p ); - } - } - //----------------------------------------------------------------------- - void ConvexBody::define(const Frustum& frustum) - { - // ordering of the points: - // near (0-3), far (4-7); each (top-right, top-left, bottom-left, bottom-right) - // 5-----4 - // /| /| - // / | / | - // 1-----0 | - // | 6--|--7 - // | / | / - // |/ |/ - // 2-----3 - - const Vector3 *pts = frustum.getWorldSpaceCorners(); - - /// reset ConvexBody - reset(); - - /// update vertices: near, far, left, right, bottom, top; fill in ccw - Polygon *poly; - - // near - poly = allocatePolygon(); - poly->insertVertex( pts[0] ); - poly->insertVertex( pts[1] ); - poly->insertVertex( pts[2] ); - poly->insertVertex( pts[3] ); - mPolygons.push_back( poly ); - - // far - poly = allocatePolygon(); - poly->insertVertex( pts[5] ); - poly->insertVertex( pts[4] ); - poly->insertVertex( pts[7] ); - poly->insertVertex( pts[6] ); - mPolygons.push_back( poly ); - - // left - poly = allocatePolygon(); - poly->insertVertex( pts[5] ); - poly->insertVertex( pts[6] ); - poly->insertVertex( pts[2] ); - poly->insertVertex( pts[1] ); - mPolygons.push_back( poly ); - - // right - poly = allocatePolygon(); - poly->insertVertex( pts[4] ); - poly->insertVertex( pts[0] ); - poly->insertVertex( pts[3] ); - poly->insertVertex( pts[7] ); - mPolygons.push_back( poly ); - - // bottom - poly = allocatePolygon(); - poly->insertVertex( pts[6] ); - poly->insertVertex( pts[7] ); - poly->insertVertex( pts[3] ); - poly->insertVertex( pts[2] ); - mPolygons.push_back( poly ); - - // top - poly = allocatePolygon(); - poly->insertVertex( pts[4] ); - poly->insertVertex( pts[5] ); - poly->insertVertex( pts[1] ); - poly->insertVertex( pts[0] ); - mPolygons.push_back( poly ); - } - //----------------------------------------------------------------------- - void ConvexBody::define(const AxisAlignedBox& aab) - { - // ordering of the AAB points: - // 1-----2 - // /| /| - // / | / | - // 5-----4 | - // | 0--|--3 - // | / | / - // |/ |/ - // 6-----7 - - const Vector3& min = aab.getMinimum(); - const Vector3& max = aab.getMaximum(); - - Vector3 currentVertex = min; - - Polygon *poly; - - // reset body - reset(); - - // far - poly = allocatePolygon(); - poly->insertVertex( currentVertex ); // 0 - currentVertex.y = max.y; - poly->insertVertex( currentVertex ); // 1 - currentVertex.x = max.x; - poly->insertVertex( currentVertex ); // 2 - currentVertex.y = min.y; - poly->insertVertex( currentVertex ); // 3 - insertPolygon( poly ); - - // right - poly = allocatePolygon(); - poly->insertVertex( currentVertex ); // 3 - currentVertex.y = max.y; - poly->insertVertex( currentVertex ); // 2 - currentVertex.z = max.z; - poly->insertVertex( currentVertex ); // 4 - currentVertex.y = min.y; - poly->insertVertex( currentVertex ); // 7 - insertPolygon( poly ); - - // near - poly = allocatePolygon(); - poly->insertVertex( currentVertex ); // 7 - currentVertex.y = max.y; - poly->insertVertex( currentVertex ); // 4 - currentVertex.x = min.x; - poly->insertVertex( currentVertex ); // 5 - currentVertex.y = min.y; - poly->insertVertex( currentVertex ); // 6 - insertPolygon( poly ); - - // left - poly = allocatePolygon(); - poly->insertVertex( currentVertex ); // 6 - currentVertex.y = max.y; - poly->insertVertex( currentVertex ); // 5 - currentVertex.z = min.z; - poly->insertVertex( currentVertex ); // 1 - currentVertex.y = min.y; - poly->insertVertex( currentVertex ); // 0 - insertPolygon( poly ); - - // bottom - poly = allocatePolygon(); - poly->insertVertex( currentVertex ); // 0 - currentVertex.x = max.x; - poly->insertVertex( currentVertex ); // 3 - currentVertex.z = max.z; - poly->insertVertex( currentVertex ); // 7 - currentVertex.x = min.x; - poly->insertVertex( currentVertex ); // 6 - insertPolygon( poly ); - - // top - poly = allocatePolygon(); - currentVertex = max; - poly->insertVertex( currentVertex ); // 4 - currentVertex.z = min.z; - poly->insertVertex( currentVertex ); // 2 - currentVertex.x = min.x; - poly->insertVertex( currentVertex ); // 1 - currentVertex.z = max.z; - poly->insertVertex( currentVertex ); // 5 - insertPolygon( poly ); - - } - //----------------------------------------------------------------------- - void ConvexBody::clip(const AxisAlignedBox& aab) - { - // only process finite boxes - if (!aab.isFinite()) - return; - // ordering of the AAB points: - // 1-----2 - // /| /| - // / | / | - // 5-----4 | - // | 0--|--3 - // | / | / - // |/ |/ - // 6-----7 - - const Vector3& min = aab.getMinimum(); - const Vector3& max = aab.getMaximum(); - - // clip object for each plane of the AAB - Plane p; - - - // front - p.redefine(Vector3::UNIT_Z, max); - clip(p); - - // back - p.redefine(Vector3::NEGATIVE_UNIT_Z, min); - clip(p); - - // left - p.redefine(Vector3::NEGATIVE_UNIT_X, min); - clip(p); - - // right - p.redefine(Vector3::UNIT_X, max); - clip(p); - - // bottom - p.redefine(Vector3::NEGATIVE_UNIT_Y, min); - clip(p); - - // top - p.redefine(Vector3::UNIT_Y, max); - clip(p); - - } - //----------------------------------------------------------------------- - void ConvexBody::clip(const Frustum& fr) - { - // clip the body with each plane - for ( unsigned short i = 0; i < 6; ++i ) - { - // clip, but keep positive space this time since frustum planes are - // the opposite to other cases (facing inwards rather than outwards) - clip(fr.getFrustumPlane(i), false); - } - } - //----------------------------------------------------------------------- - void ConvexBody::clip(const ConvexBody& body) - { - if ( this == &body ) - return; - - // for each polygon; clip 'this' with each plane of 'body' - // front vertex representation is ccw - - Plane pl; - - for ( size_t iPoly = 0; iPoly < body.getPolygonCount(); ++iPoly ) - { - const Polygon& p = body.getPolygon( iPoly ); - - OgreAssert( p.getVertexCount() >= 3, "A valid polygon must contain at least three vertices." ); - - // set up plane with first three vertices of the polygon (a polygon is always planar) - pl.redefine( p.getVertex( 0 ), p.getVertex( 1 ), p.getVertex( 2 ) ); - - clip(pl); - } - } - //----------------------------------------------------------------------- - void ConvexBody::extend(const Vector3& pt) - { - // Erase all polygons facing towards the point. For all edges that - // are not removed twice (once in AB and once BA direction) build a - // convex polygon (triangle) with the point. - Polygon::EdgeMap edgeMap; - - for ( size_t i = 0; i < getPolygonCount(); ++i ) - { - const Vector3& normal = getNormal( i ); - // direction of the point in regard to the polygon - // the polygon is planar so we can take an arbitrary vertex - Vector3 ptDir = pt - getVertex( i, 0 ); - ptDir.normalise(); - - // remove polygon if dot product is greater or equals null. - if ( normal.dotProduct( ptDir ) >= 0 ) - { - // store edges (copy them because if the polygon is deleted - // its vertices are also deleted) - storeEdgesOfPolygon( i, &edgeMap ); - - // remove polygon - deletePolygon( i ); - - // decrement iterator because of deleted polygon - --i; - } - } - - // point is already a part of the hull (point lies inside) - if ( edgeMap.empty() ) - return; - - // remove the edges that are twice in the list (once from each side: AB,BA) - - Polygon::EdgeMap::iterator it; - // iterate from first to the element before the last one - for (Polygon::EdgeMap::iterator itStart = edgeMap.begin(); - itStart != edgeMap.end(); ) - { - // compare with iterator + 1 to end - // don't need to skip last entry in itStart since omitted in inner loop - it = itStart; - ++it; - - bool erased = false; - // iterate from itStart+1 to the element before the last one - for ( ; it != edgeMap.end(); ++it ) - { - if (itStart->first.positionEquals(it->second) && - itStart->second.positionEquals(it->first)) - { - edgeMap.erase(it); - // increment itStart before deletion (iterator invalidation) - Polygon::EdgeMap::iterator delistart = itStart++; - edgeMap.erase(delistart); - erased = true; - - break; // found and erased - } - } - // increment itStart if we didn't do it when erasing - if (!erased) - ++itStart; - - } - - // use the remaining edges to build triangles with the point - // the vertices of the edges are in ccw order (edgePtA-edgePtB-point - // to form a ccw polygon) - while ( !edgeMap.empty() ) - { - Polygon::EdgeMap::iterator mapIt = edgeMap.begin(); - - // build polygon it.first, it.second, point - Polygon *p = allocatePolygon(); - - p->insertVertex(mapIt->first); - p->insertVertex(mapIt->second); - - p->insertVertex( pt ); - // attach polygon to body - insertPolygon( p ); - - // erase the vertices from the list - // pointers are now held by the polygon - edgeMap.erase( mapIt ); - } - } - //----------------------------------------------------------------------- - void ConvexBody::reset( void ) - { - for (PolygonList::iterator it = mPolygons.begin(); - it != mPolygons.end(); ++it) - { - freePolygon(*it); - } - mPolygons.clear(); - } - //----------------------------------------------------------------------- - size_t ConvexBody::getPolygonCount( void ) const - { - return mPolygons.size(); - } - //----------------------------------------------------------------------- - size_t ConvexBody::getVertexCount( size_t poly ) const - { - OgreAssert(poly < getPolygonCount(), "Search position out of range" ); - - return mPolygons[ poly ]->getVertexCount(); - } - //----------------------------------------------------------------------- - bool ConvexBody::hasClosedHull( void ) const - { - // if this map is returned empty, the body is closed - Polygon::EdgeMap edgeMap = getSingleEdges(); - - return edgeMap.empty(); - } - //----------------------------------------------------------------------- - void ConvexBody::mergePolygons( void ) - { - // Merge all polygons that lay in the same plane as one big polygon. - // A convex body does not have two separate regions (separated by polygons - // with different normals) where the same normal occurs, so we can simply - // search all similar normals of a polygon. Two different options are - // possible when the normals fit: - // - the two polygons are neighbors - // - the two polygons aren't neighbors (but a third, fourth,.. polygon lays - // in between) - - // Signals if the body holds polygons which aren't neighbors but have the same - // normal. That means another step has to be processed. - bool bDirty = false; - - for ( size_t iPolyA = 0; iPolyA < getPolygonCount(); ++iPolyA ) - { - - for ( size_t iPolyB = iPolyA+1; iPolyB < getPolygonCount(); ++iPolyB ) - { - const Vector3& n1 = getNormal( iPolyA ); - const Vector3& n2 = getNormal( iPolyB ); - - // if the normals point into the same direction - if ( n1.directionEquals( n2, Radian( Degree( 0.00001 ) ) ) ) - { - // indicates if a neighbor has been found and joined - bool bFound = false; - - // search the two fitting vertices (if there are any) for the common edge - const size_t numVerticesA = getVertexCount( iPolyA ); - for ( size_t iVertexA = 0; iVertexA < numVerticesA; ++iVertexA ) - { - const size_t numVerticesB = getVertexCount( iPolyB ); - for ( size_t iVertexB = 0; iVertexB < numVerticesB; ++iVertexB ) - { - const Vector3& aCurrent = getVertex( iPolyA, iVertexA ); - const Vector3& aNext = getVertex( iPolyA, (iVertexA + 1) % getVertexCount( iPolyA ) ); - const Vector3& bCurrent = getVertex( iPolyB, iVertexB ); - const Vector3& bNext = getVertex( iPolyB, (iVertexB + 1) % getVertexCount( iPolyB ) ); - - // if the edge is the same the current vertex of A has to be equal to the next of B and the other - // way round - if ( aCurrent.positionEquals(bNext) && - bCurrent.positionEquals(aNext)) - { - // polygons are neighbors, assemble new one - Polygon *pNew = allocatePolygon(); - - // insert all vertices of A up to the join (including the common vertex, ignoring - // whether the first vertex of A may be a shared vertex) - for ( size_t i = 0; i <= iVertexA; ++i ) - { - pNew->insertVertex( getVertex( iPolyA, i%numVerticesA ) ); - } - - // insert all vertices of B _after_ the join to the end - for ( size_t i = iVertexB + 2; i < numVerticesB; ++i ) - { - pNew->insertVertex( getVertex( iPolyB, i ) ); - } - - // insert all vertices of B from the beginning up to the join (including the common vertex - // and excluding the first vertex if the first is part of the shared edge) - for ( size_t i = 0; i <= iVertexB; ++i ) - { - pNew->insertVertex( getVertex( iPolyB, i%numVerticesB ) ); - } - - // insert all vertices of A _after_ the join to the end - for ( size_t i = iVertexA + 2; i < numVerticesA; ++i ) - { - pNew->insertVertex( getVertex( iPolyA, i ) ); - } - - // in case there are double vertices (in special cases), remove them - for ( size_t i = 0; i < pNew->getVertexCount(); ++i ) - { - const Vector3& a = pNew->getVertex( i ); - const Vector3& b = pNew->getVertex( (i + 1) % pNew->getVertexCount() ); - - // if the two vertices are the same... - if (a.positionEquals(b)) - { - // remove a - pNew->deleteVertex( i ); - - // decrement counter - --i; - } - } - - // delete the two old ones - OgreAssert( iPolyA != iPolyB, "PolyA and polyB are the same!" ); - - // polyB is always higher than polyA, so delete polyB first - deletePolygon( iPolyB ); - deletePolygon( iPolyA ); - - // continue with next (current is deleted, so don't jump to the next after the next) - --iPolyA; - --iPolyB; - - // insert new polygon - insertPolygon( pNew ); - - bFound = true; - break; - } - } - - if ( bFound ) - { - break; - } - } - - if ( bFound == false ) - { - // there are two polygons available with the same normal direction, but they - // could not be merged into one single because of no shared edge - bDirty = true; - break; - } - } - } - } - - // recursion to merge the previous non-neighbors - if ( bDirty ) - { - mergePolygons(); - } - } - //----------------------------------------------------------------------- - const Vector3& ConvexBody::getNormal( size_t poly ) - { - OgreAssert( poly < getPolygonCount(), "Search position out of range" ); - - return mPolygons[ poly ]->getNormal(); - } - //----------------------------------------------------------------------- - AxisAlignedBox ConvexBody::getAABB( void ) const - { - AxisAlignedBox aab; - - for ( size_t i = 0; i < getPolygonCount(); ++i ) - { - for ( size_t j = 0; j < getVertexCount( i ); ++j ) - { - aab.merge( getVertex( i, j ) ); - } - } - - return aab; - } - //----------------------------------------------------------------------- - bool ConvexBody::operator == ( const ConvexBody& rhs ) const - { - if ( getPolygonCount() != rhs.getPolygonCount() ) - return false; - - // Compare the polygons. They may not be in correct order. - // A correct convex body does not have identical polygons in its body. - bool *bChecked = OGRE_ALLOC_T(bool, getPolygonCount(), MEMCATEGORY_SCENE_CONTROL); - for ( size_t i=0; iinsertVertex(vdata, vertex); - } - //----------------------------------------------------------------------- - void ConvexBody::insertVertex(size_t poly, const Vector3& vdata) - { - OgreAssert(poly < getPolygonCount(), "Search position (polygon) out of range" ); - - mPolygons[poly]->insertVertex(vdata); - } - //----------------------------------------------------------------------- - void ConvexBody::deletePolygon(size_t poly) - { - OgreAssert(poly < getPolygonCount(), "Search position out of range" ); - - PolygonList::iterator it = mPolygons.begin(); - std::advance(it, poly); - - freePolygon(*it); - mPolygons.erase(it); - } - //----------------------------------------------------------------------- - Polygon* ConvexBody::unlinkPolygon(size_t poly) - { - OgreAssert( poly < getPolygonCount(), "Search position out of range" ); - - PolygonList::iterator it = mPolygons.begin(); - std::advance(it, poly); - - // safe address - Polygon *pRet = *it; - - // delete entry - mPolygons.erase(it); - - // return polygon pointer - - return pRet; - } - //----------------------------------------------------------------------- - void ConvexBody::moveDataFromBody(ConvexBody& body) - { - body.mPolygons.swap(this->mPolygons); - } - //----------------------------------------------------------------------- - void ConvexBody::deleteVertex(size_t poly, size_t vertex) - { - OgreAssert(poly < getPolygonCount(), "Search position out of range" ); - - mPolygons[poly]->deleteVertex(vertex); - } - //----------------------------------------------------------------------- - const Polygon& ConvexBody::getPolygon(size_t poly) const - { - OgreAssert(poly < getPolygonCount(), "Search position out of range"); - - return *mPolygons[poly]; - } - //----------------------------------------------------------------------- - void ConvexBody::setPolygon(Polygon* pdata, size_t poly) - { - OgreAssert(poly < getPolygonCount(), "Search position out of range" ); - OgreAssert(pdata != NULL, "Polygon is NULL" ); - - if (pdata != mPolygons[poly]) - { - // delete old polygon - freePolygon(mPolygons[ poly ]); - - // set new polygon - mPolygons[poly] = pdata; - } - } - //----------------------------------------------------------------------- - const Vector3& ConvexBody::getVertex(size_t poly, size_t vertex) const - { - OgreAssert( poly < getPolygonCount(), "Search position out of range" ); - - return mPolygons[poly]->getVertex(vertex); - } - //----------------------------------------------------------------------- - void ConvexBody::setVertex(size_t poly, const Vector3& vdata, size_t vertex) - { - OgreAssert(poly < getPolygonCount(), "Search position out of range"); - - mPolygons[poly]->setVertex(vdata, vertex); - } - //----------------------------------------------------------------------- - void ConvexBody::storeEdgesOfPolygon(size_t poly, Polygon::EdgeMap *edgeMap ) const - { - OgreAssert(poly <= getPolygonCount(), "Search position out of range" ); - OgreAssert( edgeMap != NULL, "TEdgeMap ptr is NULL" ); - - mPolygons[poly]->storeEdges(edgeMap); - } - //----------------------------------------------------------------------- - Polygon::EdgeMap ConvexBody::getSingleEdges() const - { - Polygon::EdgeMap edgeMap; - - // put all edges of all polygons into a list every edge has to be - // walked in each direction once - for ( size_t i = 0; i < getPolygonCount(); ++i ) - { - const Polygon& p = getPolygon( i ); - - for ( size_t j = 0; j < p.getVertexCount(); ++j ) - { - const Vector3& a = p.getVertex( j ); - const Vector3& b = p.getVertex( ( j + 1 ) % p.getVertexCount() ); - - edgeMap.insert( Polygon::Edge( a, b ) ); - } - } - - // search corresponding parts - Polygon::EdgeMap::iterator it; - Polygon::EdgeMap::iterator itStart; - Polygon::EdgeMap::const_iterator itEnd; - while( !edgeMap.empty() ) - { - it = edgeMap.begin(); ++it; // start one element after itStart - itStart = edgeMap.begin(); // the element to be compared with the others - itEnd = edgeMap.end(); // beyond the last element - - bool bFound = false; - - for ( ; it != itEnd; ++it ) - { - if (itStart->first.positionEquals(it->second) && - itStart->second.positionEquals(it->first)) - { - // erase itStart and it - edgeMap.erase( it ); - edgeMap.erase( itStart ); - - bFound = true; - - break; // found - } - } - - if ( bFound == false ) - { - break; // not all edges could be matched - // body is not closed - } - } - - return edgeMap; - } - //----------------------------------------------------------------------- - void ConvexBody::allocateSpace( size_t numPolygons, size_t numVertices ) - { - reset(); - - // allocate numPolygons polygons with each numVertices vertices - for ( size_t iPoly = 0; iPoly < numPolygons; ++iPoly ) - { - Polygon *poly = allocatePolygon(); - - for ( size_t iVertex = 0; iVertex < numVertices; ++iVertex ) - { - poly->insertVertex( Vector3::ZERO ); - } - - mPolygons.push_back( poly ); - } - } - //----------------------------------------------------------------------- - void ConvexBody::clip( const Plane& pl, bool keepNegative ) - { - if ( getPolygonCount() == 0 ) - return; - - // current will be used as the reference body - ConvexBody current; - current.moveDataFromBody(*this); - - OgreAssert( this->getPolygonCount() == 0, "Body not empty!" ); - OgreAssert( current.getPolygonCount() != 0, "Body empty!" ); - - // holds all intersection edges for the different polygons - Polygon::EdgeMap intersectionEdges; - - // clip all polygons by the intersection plane - // add only valid or intersected polygons to *this - for ( size_t iPoly = 0; iPoly < current.getPolygonCount(); ++iPoly ) - { - - // fetch vertex count and ignore polygons with less than three vertices - // the polygon is not valid and won't be added - const size_t vertexCount = current.getVertexCount( iPoly ); - if ( vertexCount < 3 ) - continue; - - // current polygon - const Polygon& p = current.getPolygon( iPoly ); - - // the polygon to assemble - Polygon *pNew = allocatePolygon(); - - // the intersection polygon (indeed it's an edge or it's empty) - Polygon *pIntersect = allocatePolygon(); - - // check if polygons lie inside or outside (or on the plane) - // for each vertex check where it is situated in regard to the plane - // three possibilities appear: - Plane::Side clipSide = keepNegative ? Plane::POSITIVE_SIDE : Plane::NEGATIVE_SIDE; - // - side is clipSide: vertex will be clipped - // - side is !clipSide: vertex will be untouched - // - side is NOSIDE: vertex will be untouched - Plane::Side *side = OGRE_ALLOC_T(Plane::Side, vertexCount, MEMCATEGORY_SCENE_CONTROL); - for ( size_t iVertex = 0; iVertex < vertexCount; ++iVertex ) - { - side[ iVertex ] = pl.getSide( p.getVertex( iVertex ) ); - } - - // now we check the side combinations for the current and the next vertex - // four different combinations exist: - // - both points inside (or on the plane): keep the second (add it to the body) - // - both points outside: discard both (don't add them to the body) - // - first vertex is inside, second is outside: add the intersection point - // - first vertex is outside, second is inside: add the intersection point, then the second - for ( size_t iVertex = 0; iVertex < vertexCount; ++iVertex ) - { - // determine the next vertex - size_t iNextVertex = ( iVertex + 1 ) % vertexCount; - - const Vector3& vCurrent = p.getVertex( iVertex ); - const Vector3& vNext = p.getVertex( iNextVertex ); - - // case 1: both points inside (store next) - if ( side[ iVertex ] != clipSide && // NEGATIVE or NONE - side[ iNextVertex ] != clipSide ) // NEGATIVE or NONE - { - // keep the second - pNew->insertVertex( vNext ); - } - - // case 3: inside -> outside (store intersection) - else if ( side[ iVertex ] != clipSide && - side[ iNextVertex ] == clipSide ) - { - // Do an intersection with the plane. We use a ray with a start point and a direction. - // The ray is forced to hit the plane with any option available (eigher current or next - // is the starting point) - - // intersect from the outside vertex towards the inside one - Vector3 vDirection = vCurrent - vNext; - vDirection.normalise(); - Ray ray( vNext, vDirection ); - std::pair< bool, Real > intersect = ray.intersects( pl ); - - // store intersection - if ( intersect.first ) - { - // convert distance to vector - Vector3 vIntersect = ray.getPoint( intersect.second ); - - // store intersection - pNew->insertVertex( vIntersect ); - pIntersect->insertVertex( vIntersect ); - } - } - - // case 4: outside -> inside (store intersection, store next) - else if ( side[ iVertex ] == clipSide && - side[ iNextVertex ] != clipSide ) - { - // Do an intersection with the plane. We use a ray with a start point and a direction. - // The ray is forced to hit the plane with any option available (eigher current or next - // is the starting point) - - // intersect from the outside vertex towards the inside one - Vector3 vDirection = vNext - vCurrent; - vDirection.normalise(); - Ray ray( vCurrent, vDirection ); - std::pair< bool, Real > intersect = ray.intersects( pl ); - - // store intersection - if ( intersect.first ) - { - // convert distance to vector - Vector3 vIntersect = ray.getPoint( intersect.second ); - - // store intersection - pNew->insertVertex( vIntersect ); - pIntersect->insertVertex( vIntersect ); - } - - pNew->insertVertex( vNext ); - - } - // else: - // case 2: both outside (do nothing) - - } - - // insert the polygon only, if at least three vertices are present - if ( pNew->getVertexCount() >= 3 ) - { - // in case there are double vertices, remove them - pNew->removeDuplicates(); - - // in case there are still at least three vertices, insert the polygon - if ( pNew->getVertexCount() >= 3 ) - { - this->insertPolygon( pNew ); - } - else - { - // delete pNew because it's empty or invalid - freePolygon(pNew); - pNew = 0; - } - } - else - { - // delete pNew because it's empty or invalid - freePolygon(pNew); - pNew = 0; - } - - // insert intersection polygon only, if there are two vertices present - if ( pIntersect->getVertexCount() == 2 ) - { - intersectionEdges.insert( Polygon::Edge( pIntersect->getVertex( 0 ), - pIntersect->getVertex( 1 ) ) ); - } - - // delete intersection polygon - // vertices were copied (if there were any) - freePolygon(pIntersect); - pIntersect = 0; - - // delete side info - OGRE_FREE(side, MEMCATEGORY_SCENE_CONTROL); - side = 0; - } - - // if the polygon was partially clipped, close it - // at least three edges are needed for a polygon - if ( intersectionEdges.size() >= 3 ) - { - Polygon *pClosing = allocatePolygon(); - - // Analyze the intersection list and insert the intersection points in ccw order - // Each point is twice in the list because of the fact that we have a convex body - // with convex polygons. All we have to do is order the edges (an even-odd pair) - // in a ccw order. The plane normal shows us the direction. - Polygon::EdgeMap::iterator it = intersectionEdges.begin(); - - // check the cross product of the first two edges - Vector3 vFirst = it->first; - Vector3 vSecond = it->second; - - // remove inserted edge - intersectionEdges.erase( it ); - - Vector3 vNext; - - // find mating edge - if (findAndEraseEdgePair(vSecond, intersectionEdges, vNext)) - { - // detect the orientation - // the polygon must have the same normal direction as the plane and then n - Vector3 vCross = ( vFirst - vSecond ).crossProduct( vNext - vSecond ); - bool frontside = ( pl.normal ).directionEquals( vCross, Degree( 1 ) ); - - // first inserted vertex - Vector3 firstVertex; - // currently inserted vertex - Vector3 currentVertex; - // direction equals -> front side (walk ccw) - if ( frontside ) - { - // start with next as first vertex, then second, then first and continue with first to walk ccw - pClosing->insertVertex( vNext ); - pClosing->insertVertex( vSecond ); - pClosing->insertVertex( vFirst ); - firstVertex = vNext; - currentVertex = vFirst; - - #ifdef _DEBUG_INTERSECTION_LIST - std::cout << "Plane: n=" << pl.normal << ", d=" << pl.d << std::endl; - std::cout << "First inserted vertex: " << *next << std::endl; - std::cout << "Second inserted vertex: " << *vSecond << std::endl; - std::cout << "Third inserted vertex: " << *vFirst << std::endl; - #endif - } - // direction does not equal -> back side (walk cw) - else - { - // start with first as first vertex, then second, then next and continue with next to walk ccw - pClosing->insertVertex( vFirst ); - pClosing->insertVertex( vSecond ); - pClosing->insertVertex( vNext ); - firstVertex = vFirst; - currentVertex = vNext; - - #ifdef _DEBUG_INTERSECTION_LIST - std::cout << "Plane: n=" << pl.normal << ", d=" << pl.d << std::endl; - std::cout << "First inserted vertex: " << *vFirst << std::endl; - std::cout << "Second inserted vertex: " << *vSecond << std::endl; - std::cout << "Third inserted vertex: " << *next << std::endl; - #endif - } - - // search mating edges that have a point in common - // continue this operation as long as edges are present - while ( !intersectionEdges.empty() ) - { - - if (findAndEraseEdgePair(currentVertex, intersectionEdges, vNext)) - { - // insert only if it's not the last (which equals the first) vertex - if ( !intersectionEdges.empty() ) - { - currentVertex = vNext; - pClosing->insertVertex( vNext ); - } - } - else - { - // degenerated... - break; - } - - } // while intersectionEdges not empty - - // insert polygon (may be degenerated!) - this->insertPolygon( pClosing ); - - } - // mating intersection edge NOT found! - else - { - freePolygon(pClosing); - } - - } // if intersectionEdges contains more than three elements - } - //----------------------------------------------------------------------- - bool ConvexBody::findAndEraseEdgePair(const Vector3& vec, - Polygon::EdgeMap& intersectionEdges, Vector3& vNext ) const - { - for (Polygon::EdgeMap::iterator it = intersectionEdges.begin(); - it != intersectionEdges.end(); ++it) - { - if (it->first.positionEquals(vec)) - { - vNext = it->second; - - // erase found edge - intersectionEdges.erase( it ); - - return true; // found! - } - else if (it->second.positionEquals(vec)) - { - vNext = it->first; - - // erase found edge - intersectionEdges.erase( it ); - - return true; // found! - } - } - - return false; // not found! - } - //----------------------------------------------------------------------- - void ConvexBody::logInfo( void ) const - { - StringStream ssOut( std::stringstream::out ); - ssOut << *this; - - Ogre::LogManager::getSingleton().logMessage( Ogre::LML_NORMAL, ssOut.str() ); - } + msFreePolygons.push_back(poly); + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + ConvexBody::ConvexBody() + { + // Reserve space for 8 polys, normally 6 faces plus a couple of clips + mPolygons.reserve(8); + + } + //----------------------------------------------------------------------- + ConvexBody::~ConvexBody() + { + reset(); + } + //----------------------------------------------------------------------- + ConvexBody::ConvexBody( const ConvexBody& cpy ) + { + for ( size_t i = 0; i < cpy.getPolygonCount(); ++i ) + { + Polygon *p = allocatePolygon(); + *p = cpy.getPolygon( i ); + mPolygons.push_back( p ); + } + } + //----------------------------------------------------------------------- + void ConvexBody::define(const Frustum& frustum) + { + // ordering of the points: + // near (0-3), far (4-7); each (top-right, top-left, bottom-left, bottom-right) + // 5-----4 + // /| /| + // / | / | + // 1-----0 | + // | 6--|--7 + // | / | / + // |/ |/ + // 2-----3 + + const Vector3 *pts = frustum.getWorldSpaceCorners(); + + /// reset ConvexBody + reset(); + + /// update vertices: near, far, left, right, bottom, top; fill in ccw + Polygon *poly; + + // near + poly = allocatePolygon(); + poly->insertVertex( pts[0] ); + poly->insertVertex( pts[1] ); + poly->insertVertex( pts[2] ); + poly->insertVertex( pts[3] ); + mPolygons.push_back( poly ); + + // far + poly = allocatePolygon(); + poly->insertVertex( pts[5] ); + poly->insertVertex( pts[4] ); + poly->insertVertex( pts[7] ); + poly->insertVertex( pts[6] ); + mPolygons.push_back( poly ); + + // left + poly = allocatePolygon(); + poly->insertVertex( pts[5] ); + poly->insertVertex( pts[6] ); + poly->insertVertex( pts[2] ); + poly->insertVertex( pts[1] ); + mPolygons.push_back( poly ); + + // right + poly = allocatePolygon(); + poly->insertVertex( pts[4] ); + poly->insertVertex( pts[0] ); + poly->insertVertex( pts[3] ); + poly->insertVertex( pts[7] ); + mPolygons.push_back( poly ); + + // bottom + poly = allocatePolygon(); + poly->insertVertex( pts[6] ); + poly->insertVertex( pts[7] ); + poly->insertVertex( pts[3] ); + poly->insertVertex( pts[2] ); + mPolygons.push_back( poly ); + + // top + poly = allocatePolygon(); + poly->insertVertex( pts[4] ); + poly->insertVertex( pts[5] ); + poly->insertVertex( pts[1] ); + poly->insertVertex( pts[0] ); + mPolygons.push_back( poly ); + } + //----------------------------------------------------------------------- + void ConvexBody::define(const AxisAlignedBox& aab) + { + // ordering of the AAB points: + // 1-----2 + // /| /| + // / | / | + // 5-----4 | + // | 0--|--3 + // | / | / + // |/ |/ + // 6-----7 + + const Vector3& min = aab.getMinimum(); + const Vector3& max = aab.getMaximum(); + + Vector3 currentVertex = min; + + Polygon *poly; + + // reset body + reset(); + + // far + poly = allocatePolygon(); + poly->insertVertex( currentVertex ); // 0 + currentVertex.y = max.y; + poly->insertVertex( currentVertex ); // 1 + currentVertex.x = max.x; + poly->insertVertex( currentVertex ); // 2 + currentVertex.y = min.y; + poly->insertVertex( currentVertex ); // 3 + insertPolygon( poly ); + + // right + poly = allocatePolygon(); + poly->insertVertex( currentVertex ); // 3 + currentVertex.y = max.y; + poly->insertVertex( currentVertex ); // 2 + currentVertex.z = max.z; + poly->insertVertex( currentVertex ); // 4 + currentVertex.y = min.y; + poly->insertVertex( currentVertex ); // 7 + insertPolygon( poly ); + + // near + poly = allocatePolygon(); + poly->insertVertex( currentVertex ); // 7 + currentVertex.y = max.y; + poly->insertVertex( currentVertex ); // 4 + currentVertex.x = min.x; + poly->insertVertex( currentVertex ); // 5 + currentVertex.y = min.y; + poly->insertVertex( currentVertex ); // 6 + insertPolygon( poly ); + + // left + poly = allocatePolygon(); + poly->insertVertex( currentVertex ); // 6 + currentVertex.y = max.y; + poly->insertVertex( currentVertex ); // 5 + currentVertex.z = min.z; + poly->insertVertex( currentVertex ); // 1 + currentVertex.y = min.y; + poly->insertVertex( currentVertex ); // 0 + insertPolygon( poly ); + + // bottom + poly = allocatePolygon(); + poly->insertVertex( currentVertex ); // 0 + currentVertex.x = max.x; + poly->insertVertex( currentVertex ); // 3 + currentVertex.z = max.z; + poly->insertVertex( currentVertex ); // 7 + currentVertex.x = min.x; + poly->insertVertex( currentVertex ); // 6 + insertPolygon( poly ); + + // top + poly = allocatePolygon(); + currentVertex = max; + poly->insertVertex( currentVertex ); // 4 + currentVertex.z = min.z; + poly->insertVertex( currentVertex ); // 2 + currentVertex.x = min.x; + poly->insertVertex( currentVertex ); // 1 + currentVertex.z = max.z; + poly->insertVertex( currentVertex ); // 5 + insertPolygon( poly ); + + } + //----------------------------------------------------------------------- + void ConvexBody::clip(const AxisAlignedBox& aab) + { + // only process finite boxes + if (!aab.isFinite()) + return; + // ordering of the AAB points: + // 1-----2 + // /| /| + // / | / | + // 5-----4 | + // | 0--|--3 + // | / | / + // |/ |/ + // 6-----7 + + const Vector3& min = aab.getMinimum(); + const Vector3& max = aab.getMaximum(); + + // clip object for each plane of the AAB + Plane p; + + + // front + p.redefine(Vector3::UNIT_Z, max); + clip(p); + + // back + p.redefine(Vector3::NEGATIVE_UNIT_Z, min); + clip(p); + + // left + p.redefine(Vector3::NEGATIVE_UNIT_X, min); + clip(p); + + // right + p.redefine(Vector3::UNIT_X, max); + clip(p); + + // bottom + p.redefine(Vector3::NEGATIVE_UNIT_Y, min); + clip(p); + + // top + p.redefine(Vector3::UNIT_Y, max); + clip(p); + + } + //----------------------------------------------------------------------- + void ConvexBody::clip(const Frustum& fr) + { + // clip the body with each plane + for ( unsigned short i = 0; i < 6; ++i ) + { + // clip, but keep positive space this time since frustum planes are + // the opposite to other cases (facing inwards rather than outwards) + clip(fr.getFrustumPlane(i), false); + } + } + //----------------------------------------------------------------------- + void ConvexBody::clip(const ConvexBody& body) + { + if ( this == &body ) + return; + + // for each polygon; clip 'this' with each plane of 'body' + // front vertex representation is ccw + + Plane pl; + + for ( size_t iPoly = 0; iPoly < body.getPolygonCount(); ++iPoly ) + { + const Polygon& p = body.getPolygon( iPoly ); + + OgreAssert( p.getVertexCount() >= 3, "A valid polygon must contain at least three vertices." ); + + // set up plane with first three vertices of the polygon (a polygon is always planar) + pl.redefine( p.getVertex( 0 ), p.getVertex( 1 ), p.getVertex( 2 ) ); + + clip(pl); + } + } + //----------------------------------------------------------------------- + void ConvexBody::extend(const Vector3& pt) + { + // Erase all polygons facing towards the point. For all edges that + // are not removed twice (once in AB and once BA direction) build a + // convex polygon (triangle) with the point. + Polygon::EdgeMap edgeMap; + + for ( size_t i = 0; i < getPolygonCount(); ++i ) + { + const Vector3& normal = getNormal( i ); + // direction of the point in regard to the polygon + // the polygon is planar so we can take an arbitrary vertex + Vector3 ptDir = pt - getVertex( i, 0 ); + ptDir.normalise(); + + // remove polygon if dot product is greater or equals null. + if ( normal.dotProduct( ptDir ) >= 0 ) + { + // store edges (copy them because if the polygon is deleted + // its vertices are also deleted) + storeEdgesOfPolygon( i, &edgeMap ); + + // remove polygon + deletePolygon( i ); + + // decrement iterator because of deleted polygon + --i; + } + } + + // point is already a part of the hull (point lies inside) + if ( edgeMap.empty() ) + return; + + // remove the edges that are twice in the list (once from each side: AB,BA) + + Polygon::EdgeMap::iterator it; + // iterate from first to the element before the last one + for (Polygon::EdgeMap::iterator itStart = edgeMap.begin(); + itStart != edgeMap.end(); ) + { + // compare with iterator + 1 to end + // don't need to skip last entry in itStart since omitted in inner loop + it = itStart; + ++it; + + bool erased = false; + // iterate from itStart+1 to the element before the last one + for ( ; it != edgeMap.end(); ++it ) + { + if (itStart->first.positionEquals(it->second) && + itStart->second.positionEquals(it->first)) + { + edgeMap.erase(it); + // increment itStart before deletion (iterator invalidation) + Polygon::EdgeMap::iterator delistart = itStart++; + edgeMap.erase(delistart); + erased = true; + + break; // found and erased + } + } + // increment itStart if we didn't do it when erasing + if (!erased) + ++itStart; + + } + + // use the remaining edges to build triangles with the point + // the vertices of the edges are in ccw order (edgePtA-edgePtB-point + // to form a ccw polygon) + while ( !edgeMap.empty() ) + { + Polygon::EdgeMap::iterator mapIt = edgeMap.begin(); + + // build polygon it.first, it.second, point + Polygon *p = allocatePolygon(); + + p->insertVertex(mapIt->first); + p->insertVertex(mapIt->second); + + p->insertVertex( pt ); + // attach polygon to body + insertPolygon( p ); + + // erase the vertices from the list + // pointers are now held by the polygon + edgeMap.erase( mapIt ); + } + } + //----------------------------------------------------------------------- + void ConvexBody::reset( void ) + { + for (PolygonList::iterator it = mPolygons.begin(); + it != mPolygons.end(); ++it) + { + freePolygon(*it); + } + mPolygons.clear(); + } + //----------------------------------------------------------------------- + size_t ConvexBody::getPolygonCount( void ) const + { + return mPolygons.size(); + } + //----------------------------------------------------------------------- + size_t ConvexBody::getVertexCount( size_t poly ) const + { + OgreAssert(poly < getPolygonCount(), "Search position out of range" ); + + return mPolygons[ poly ]->getVertexCount(); + } + //----------------------------------------------------------------------- + bool ConvexBody::hasClosedHull( void ) const + { + // if this map is returned empty, the body is closed + Polygon::EdgeMap edgeMap = getSingleEdges(); + + return edgeMap.empty(); + } + //----------------------------------------------------------------------- + void ConvexBody::mergePolygons( void ) + { + // Merge all polygons that lay in the same plane as one big polygon. + // A convex body does not have two separate regions (separated by polygons + // with different normals) where the same normal occurs, so we can simply + // search all similar normals of a polygon. Two different options are + // possible when the normals fit: + // - the two polygons are neighbors + // - the two polygons aren't neighbors (but a third, fourth,.. polygon lays + // in between) + + // Signals if the body holds polygons which aren't neighbors but have the same + // normal. That means another step has to be processed. + bool bDirty = false; + + for ( size_t iPolyA = 0; iPolyA < getPolygonCount(); ++iPolyA ) + { + + for ( size_t iPolyB = iPolyA+1; iPolyB < getPolygonCount(); ++iPolyB ) + { + const Vector3& n1 = getNormal( iPolyA ); + const Vector3& n2 = getNormal( iPolyB ); + + // if the normals point into the same direction + if ( n1.directionEquals( n2, Radian( Degree( 0.00001 ) ) ) ) + { + // indicates if a neighbor has been found and joined + bool bFound = false; + + // search the two fitting vertices (if there are any) for the common edge + const size_t numVerticesA = getVertexCount( iPolyA ); + for ( size_t iVertexA = 0; iVertexA < numVerticesA; ++iVertexA ) + { + const size_t numVerticesB = getVertexCount( iPolyB ); + for ( size_t iVertexB = 0; iVertexB < numVerticesB; ++iVertexB ) + { + const Vector3& aCurrent = getVertex( iPolyA, iVertexA ); + const Vector3& aNext = getVertex( iPolyA, (iVertexA + 1) % getVertexCount( iPolyA ) ); + const Vector3& bCurrent = getVertex( iPolyB, iVertexB ); + const Vector3& bNext = getVertex( iPolyB, (iVertexB + 1) % getVertexCount( iPolyB ) ); + + // if the edge is the same the current vertex of A has to be equal to the next of B and the other + // way round + if ( aCurrent.positionEquals(bNext) && + bCurrent.positionEquals(aNext)) + { + // polygons are neighbors, assemble new one + Polygon *pNew = allocatePolygon(); + + // insert all vertices of A up to the join (including the common vertex, ignoring + // whether the first vertex of A may be a shared vertex) + for ( size_t i = 0; i <= iVertexA; ++i ) + { + pNew->insertVertex( getVertex( iPolyA, i%numVerticesA ) ); + } + + // insert all vertices of B _after_ the join to the end + for ( size_t i = iVertexB + 2; i < numVerticesB; ++i ) + { + pNew->insertVertex( getVertex( iPolyB, i ) ); + } + + // insert all vertices of B from the beginning up to the join (including the common vertex + // and excluding the first vertex if the first is part of the shared edge) + for ( size_t i = 0; i <= iVertexB; ++i ) + { + pNew->insertVertex( getVertex( iPolyB, i%numVerticesB ) ); + } + + // insert all vertices of A _after_ the join to the end + for ( size_t i = iVertexA + 2; i < numVerticesA; ++i ) + { + pNew->insertVertex( getVertex( iPolyA, i ) ); + } + + // in case there are double vertices (in special cases), remove them + for ( size_t i = 0; i < pNew->getVertexCount(); ++i ) + { + const Vector3& a = pNew->getVertex( i ); + const Vector3& b = pNew->getVertex( (i + 1) % pNew->getVertexCount() ); + + // if the two vertices are the same... + if (a.positionEquals(b)) + { + // remove a + pNew->deleteVertex( i ); + + // decrement counter + --i; + } + } + + // delete the two old ones + OgreAssert( iPolyA != iPolyB, "PolyA and polyB are the same!" ); + + // polyB is always higher than polyA, so delete polyB first + deletePolygon( iPolyB ); + deletePolygon( iPolyA ); + + // continue with next (current is deleted, so don't jump to the next after the next) + --iPolyA; + --iPolyB; + + // insert new polygon + insertPolygon( pNew ); + + bFound = true; + break; + } + } + + if ( bFound ) + { + break; + } + } + + if ( bFound == false ) + { + // there are two polygons available with the same normal direction, but they + // could not be merged into one single because of no shared edge + bDirty = true; + break; + } + } + } + } + + // recursion to merge the previous non-neighbors + if ( bDirty ) + { + mergePolygons(); + } + } + //----------------------------------------------------------------------- + const Vector3& ConvexBody::getNormal( size_t poly ) + { + OgreAssert( poly < getPolygonCount(), "Search position out of range" ); + + return mPolygons[ poly ]->getNormal(); + } + //----------------------------------------------------------------------- + AxisAlignedBox ConvexBody::getAABB( void ) const + { + AxisAlignedBox aab; + + for ( size_t i = 0; i < getPolygonCount(); ++i ) + { + for ( size_t j = 0; j < getVertexCount( i ); ++j ) + { + aab.merge( getVertex( i, j ) ); + } + } + + return aab; + } + //----------------------------------------------------------------------- + bool ConvexBody::operator == ( const ConvexBody& rhs ) const + { + if ( getPolygonCount() != rhs.getPolygonCount() ) + return false; + + // Compare the polygons. They may not be in correct order. + // A correct convex body does not have identical polygons in its body. + bool *bChecked = OGRE_ALLOC_T(bool, getPolygonCount(), MEMCATEGORY_SCENE_CONTROL); + for ( size_t i=0; iinsertVertex(vdata, vertex); + } + //----------------------------------------------------------------------- + void ConvexBody::insertVertex(size_t poly, const Vector3& vdata) + { + OgreAssert(poly < getPolygonCount(), "Search position (polygon) out of range" ); + + mPolygons[poly]->insertVertex(vdata); + } + //----------------------------------------------------------------------- + void ConvexBody::deletePolygon(size_t poly) + { + OgreAssert(poly < getPolygonCount(), "Search position out of range" ); + + PolygonList::iterator it = mPolygons.begin(); + std::advance(it, poly); + + freePolygon(*it); + mPolygons.erase(it); + } + //----------------------------------------------------------------------- + Polygon* ConvexBody::unlinkPolygon(size_t poly) + { + OgreAssert( poly < getPolygonCount(), "Search position out of range" ); + + PolygonList::iterator it = mPolygons.begin(); + std::advance(it, poly); + + // safe address + Polygon *pRet = *it; + + // delete entry + mPolygons.erase(it); + + // return polygon pointer + + return pRet; + } + //----------------------------------------------------------------------- + void ConvexBody::moveDataFromBody(ConvexBody& body) + { + body.mPolygons.swap(this->mPolygons); + } + //----------------------------------------------------------------------- + void ConvexBody::deleteVertex(size_t poly, size_t vertex) + { + OgreAssert(poly < getPolygonCount(), "Search position out of range" ); + + mPolygons[poly]->deleteVertex(vertex); + } + //----------------------------------------------------------------------- + const Polygon& ConvexBody::getPolygon(size_t poly) const + { + OgreAssert(poly < getPolygonCount(), "Search position out of range"); + + return *mPolygons[poly]; + } + //----------------------------------------------------------------------- + void ConvexBody::setPolygon(Polygon* pdata, size_t poly) + { + OgreAssert(poly < getPolygonCount(), "Search position out of range" ); + OgreAssert(pdata != NULL, "Polygon is NULL" ); + + if (pdata != mPolygons[poly]) + { + // delete old polygon + freePolygon(mPolygons[ poly ]); + + // set new polygon + mPolygons[poly] = pdata; + } + } + //----------------------------------------------------------------------- + const Vector3& ConvexBody::getVertex(size_t poly, size_t vertex) const + { + OgreAssert( poly < getPolygonCount(), "Search position out of range" ); + + return mPolygons[poly]->getVertex(vertex); + } + //----------------------------------------------------------------------- + void ConvexBody::setVertex(size_t poly, const Vector3& vdata, size_t vertex) + { + OgreAssert(poly < getPolygonCount(), "Search position out of range"); + + mPolygons[poly]->setVertex(vdata, vertex); + } + //----------------------------------------------------------------------- + void ConvexBody::storeEdgesOfPolygon(size_t poly, Polygon::EdgeMap *edgeMap ) const + { + OgreAssert(poly <= getPolygonCount(), "Search position out of range" ); + OgreAssert( edgeMap != NULL, "TEdgeMap ptr is NULL" ); + + mPolygons[poly]->storeEdges(edgeMap); + } + //----------------------------------------------------------------------- + Polygon::EdgeMap ConvexBody::getSingleEdges() const + { + Polygon::EdgeMap edgeMap; + + // put all edges of all polygons into a list every edge has to be + // walked in each direction once + for ( size_t i = 0; i < getPolygonCount(); ++i ) + { + const Polygon& p = getPolygon( i ); + + for ( size_t j = 0; j < p.getVertexCount(); ++j ) + { + const Vector3& a = p.getVertex( j ); + const Vector3& b = p.getVertex( ( j + 1 ) % p.getVertexCount() ); + + edgeMap.insert( Polygon::Edge( a, b ) ); + } + } + + // search corresponding parts + Polygon::EdgeMap::iterator it; + Polygon::EdgeMap::iterator itStart; + Polygon::EdgeMap::const_iterator itEnd; + while( !edgeMap.empty() ) + { + it = edgeMap.begin(); ++it; // start one element after itStart + itStart = edgeMap.begin(); // the element to be compared with the others + itEnd = edgeMap.end(); // beyond the last element + + bool bFound = false; + + for ( ; it != itEnd; ++it ) + { + if (itStart->first.positionEquals(it->second) && + itStart->second.positionEquals(it->first)) + { + // erase itStart and it + edgeMap.erase( it ); + edgeMap.erase( itStart ); + + bFound = true; + + break; // found + } + } + + if ( bFound == false ) + { + break; // not all edges could be matched + // body is not closed + } + } + + return edgeMap; + } + //----------------------------------------------------------------------- + void ConvexBody::allocateSpace( size_t numPolygons, size_t numVertices ) + { + reset(); + + // allocate numPolygons polygons with each numVertices vertices + for ( size_t iPoly = 0; iPoly < numPolygons; ++iPoly ) + { + Polygon *poly = allocatePolygon(); + + for ( size_t iVertex = 0; iVertex < numVertices; ++iVertex ) + { + poly->insertVertex( Vector3::ZERO ); + } + + mPolygons.push_back( poly ); + } + } + //----------------------------------------------------------------------- + void ConvexBody::clip( const Plane& pl, bool keepNegative ) + { + if ( getPolygonCount() == 0 ) + return; + + // current will be used as the reference body + ConvexBody current; + current.moveDataFromBody(*this); + + OgreAssert( this->getPolygonCount() == 0, "Body not empty!" ); + OgreAssert( current.getPolygonCount() != 0, "Body empty!" ); + + // holds all intersection edges for the different polygons + Polygon::EdgeMap intersectionEdges; + + // clip all polygons by the intersection plane + // add only valid or intersected polygons to *this + for ( size_t iPoly = 0; iPoly < current.getPolygonCount(); ++iPoly ) + { + + // fetch vertex count and ignore polygons with less than three vertices + // the polygon is not valid and won't be added + const size_t vertexCount = current.getVertexCount( iPoly ); + if ( vertexCount < 3 ) + continue; + + // current polygon + const Polygon& p = current.getPolygon( iPoly ); + + // the polygon to assemble + Polygon *pNew = allocatePolygon(); + + // the intersection polygon (indeed it's an edge or it's empty) + Polygon *pIntersect = allocatePolygon(); + + // check if polygons lie inside or outside (or on the plane) + // for each vertex check where it is situated in regard to the plane + // three possibilities appear: + Plane::Side clipSide = keepNegative ? Plane::POSITIVE_SIDE : Plane::NEGATIVE_SIDE; + // - side is clipSide: vertex will be clipped + // - side is !clipSide: vertex will be untouched + // - side is NOSIDE: vertex will be untouched + Plane::Side *side = OGRE_ALLOC_T(Plane::Side, vertexCount, MEMCATEGORY_SCENE_CONTROL); + for ( size_t iVertex = 0; iVertex < vertexCount; ++iVertex ) + { + side[ iVertex ] = pl.getSide( p.getVertex( iVertex ) ); + } + + // now we check the side combinations for the current and the next vertex + // four different combinations exist: + // - both points inside (or on the plane): keep the second (add it to the body) + // - both points outside: discard both (don't add them to the body) + // - first vertex is inside, second is outside: add the intersection point + // - first vertex is outside, second is inside: add the intersection point, then the second + for ( size_t iVertex = 0; iVertex < vertexCount; ++iVertex ) + { + // determine the next vertex + size_t iNextVertex = ( iVertex + 1 ) % vertexCount; + + const Vector3& vCurrent = p.getVertex( iVertex ); + const Vector3& vNext = p.getVertex( iNextVertex ); + + // case 1: both points inside (store next) + if ( side[ iVertex ] != clipSide && // NEGATIVE or NONE + side[ iNextVertex ] != clipSide ) // NEGATIVE or NONE + { + // keep the second + pNew->insertVertex( vNext ); + } + + // case 3: inside -> outside (store intersection) + else if ( side[ iVertex ] != clipSide && + side[ iNextVertex ] == clipSide ) + { + // Do an intersection with the plane. We use a ray with a start point and a direction. + // The ray is forced to hit the plane with any option available (eigher current or next + // is the starting point) + + // intersect from the outside vertex towards the inside one + Vector3 vDirection = vCurrent - vNext; + vDirection.normalise(); + Ray ray( vNext, vDirection ); + std::pair< bool, Real > intersect = ray.intersects( pl ); + + // store intersection + if ( intersect.first ) + { + // convert distance to vector + Vector3 vIntersect = ray.getPoint( intersect.second ); + + // store intersection + pNew->insertVertex( vIntersect ); + pIntersect->insertVertex( vIntersect ); + } + } + + // case 4: outside -> inside (store intersection, store next) + else if ( side[ iVertex ] == clipSide && + side[ iNextVertex ] != clipSide ) + { + // Do an intersection with the plane. We use a ray with a start point and a direction. + // The ray is forced to hit the plane with any option available (eigher current or next + // is the starting point) + + // intersect from the outside vertex towards the inside one + Vector3 vDirection = vNext - vCurrent; + vDirection.normalise(); + Ray ray( vCurrent, vDirection ); + std::pair< bool, Real > intersect = ray.intersects( pl ); + + // store intersection + if ( intersect.first ) + { + // convert distance to vector + Vector3 vIntersect = ray.getPoint( intersect.second ); + + // store intersection + pNew->insertVertex( vIntersect ); + pIntersect->insertVertex( vIntersect ); + } + + pNew->insertVertex( vNext ); + + } + // else: + // case 2: both outside (do nothing) + + } + + // insert the polygon only, if at least three vertices are present + if ( pNew->getVertexCount() >= 3 ) + { + // in case there are double vertices, remove them + pNew->removeDuplicates(); + + // in case there are still at least three vertices, insert the polygon + if ( pNew->getVertexCount() >= 3 ) + { + this->insertPolygon( pNew ); + } + else + { + // delete pNew because it's empty or invalid + freePolygon(pNew); + pNew = 0; + } + } + else + { + // delete pNew because it's empty or invalid + freePolygon(pNew); + pNew = 0; + } + + // insert intersection polygon only, if there are two vertices present + if ( pIntersect->getVertexCount() == 2 ) + { + intersectionEdges.insert( Polygon::Edge( pIntersect->getVertex( 0 ), + pIntersect->getVertex( 1 ) ) ); + } + + // delete intersection polygon + // vertices were copied (if there were any) + freePolygon(pIntersect); + pIntersect = 0; + + // delete side info + OGRE_FREE(side, MEMCATEGORY_SCENE_CONTROL); + side = 0; + } + + // if the polygon was partially clipped, close it + // at least three edges are needed for a polygon + if ( intersectionEdges.size() >= 3 ) + { + Polygon *pClosing = allocatePolygon(); + + // Analyze the intersection list and insert the intersection points in ccw order + // Each point is twice in the list because of the fact that we have a convex body + // with convex polygons. All we have to do is order the edges (an even-odd pair) + // in a ccw order. The plane normal shows us the direction. + Polygon::EdgeMap::iterator it = intersectionEdges.begin(); + + // check the cross product of the first two edges + Vector3 vFirst = it->first; + Vector3 vSecond = it->second; + + // remove inserted edge + intersectionEdges.erase( it ); + + Vector3 vNext; + + // find mating edge + if (findAndEraseEdgePair(vSecond, intersectionEdges, vNext)) + { + // detect the orientation + // the polygon must have the same normal direction as the plane and then n + Vector3 vCross = ( vFirst - vSecond ).crossProduct( vNext - vSecond ); + bool frontside = ( pl.normal ).directionEquals( vCross, Degree( 1 ) ); + + // first inserted vertex + Vector3 firstVertex; + // currently inserted vertex + Vector3 currentVertex; + // direction equals -> front side (walk ccw) + if ( frontside ) + { + // start with next as first vertex, then second, then first and continue with first to walk ccw + pClosing->insertVertex( vNext ); + pClosing->insertVertex( vSecond ); + pClosing->insertVertex( vFirst ); + firstVertex = vNext; + currentVertex = vFirst; + + #ifdef _DEBUG_INTERSECTION_LIST + std::cout << "Plane: n=" << pl.normal << ", d=" << pl.d << std::endl; + std::cout << "First inserted vertex: " << *next << std::endl; + std::cout << "Second inserted vertex: " << *vSecond << std::endl; + std::cout << "Third inserted vertex: " << *vFirst << std::endl; + #endif + } + // direction does not equal -> back side (walk cw) + else + { + // start with first as first vertex, then second, then next and continue with next to walk ccw + pClosing->insertVertex( vFirst ); + pClosing->insertVertex( vSecond ); + pClosing->insertVertex( vNext ); + firstVertex = vFirst; + currentVertex = vNext; + + #ifdef _DEBUG_INTERSECTION_LIST + std::cout << "Plane: n=" << pl.normal << ", d=" << pl.d << std::endl; + std::cout << "First inserted vertex: " << *vFirst << std::endl; + std::cout << "Second inserted vertex: " << *vSecond << std::endl; + std::cout << "Third inserted vertex: " << *next << std::endl; + #endif + } + + // search mating edges that have a point in common + // continue this operation as long as edges are present + while ( !intersectionEdges.empty() ) + { + + if (findAndEraseEdgePair(currentVertex, intersectionEdges, vNext)) + { + // insert only if it's not the last (which equals the first) vertex + if ( !intersectionEdges.empty() ) + { + currentVertex = vNext; + pClosing->insertVertex( vNext ); + } + } + else + { + // degenerated... + break; + } + + } // while intersectionEdges not empty + + // insert polygon (may be degenerated!) + this->insertPolygon( pClosing ); + + } + // mating intersection edge NOT found! + else + { + freePolygon(pClosing); + } + + } // if intersectionEdges contains more than three elements + } + //----------------------------------------------------------------------- + bool ConvexBody::findAndEraseEdgePair(const Vector3& vec, + Polygon::EdgeMap& intersectionEdges, Vector3& vNext ) const + { + for (Polygon::EdgeMap::iterator it = intersectionEdges.begin(); + it != intersectionEdges.end(); ++it) + { + if (it->first.positionEquals(vec)) + { + vNext = it->second; + + // erase found edge + intersectionEdges.erase( it ); + + return true; // found! + } + else if (it->second.positionEquals(vec)) + { + vNext = it->first; + + // erase found edge + intersectionEdges.erase( it ); + + return true; // found! + } + } + + return false; // not found! + } + //----------------------------------------------------------------------- + void ConvexBody::logInfo( void ) const + { + StringStream ssOut( std::stringstream::out ); + ssOut << *this; + + Ogre::LogManager::getSingleton().logMessage( Ogre::LML_NORMAL, ssOut.str() ); + } } diff --git a/OgreMain/src/OgreDDSCodec.cpp b/OgreMain/src/OgreDDSCodec.cpp index 22ddd771f8b..4c06686149e 100644 --- a/OgreMain/src/OgreDDSCodec.cpp +++ b/OgreMain/src/OgreDDSCodec.cpp @@ -36,51 +36,51 @@ THE SOFTWARE. #include "OgreLogManager.h" namespace Ogre { - // Internal DDS structure definitions + // Internal DDS structure definitions #define FOURCC(c0, c1, c2, c3) (c0 | (c1 << 8) | (c2 << 16) | (c3 << 24)) - + #if OGRE_COMPILER == OGRE_COMPILER_MSVC #pragma pack (push, 1) #else #pragma pack (1) #endif - // Nested structure - struct DDSPixelFormat - { - uint32 size; - uint32 flags; - uint32 fourCC; - uint32 rgbBits; - uint32 redMask; - uint32 greenMask; - uint32 blueMask; - uint32 alphaMask; - }; - - // Nested structure - struct DDSCaps - { - uint32 caps1; - uint32 caps2; - uint32 caps3; - uint32 caps4; - }; - // Main header, note preceded by 'DDS ' - struct DDSHeader - { - uint32 size; - uint32 flags; - uint32 height; - uint32 width; - uint32 sizeOrPitch; - uint32 depth; - uint32 mipMapCount; - uint32 reserved1[11]; - DDSPixelFormat pixelFormat; - DDSCaps caps; - uint32 reserved2; - }; + // Nested structure + struct DDSPixelFormat + { + uint32 size; + uint32 flags; + uint32 fourCC; + uint32 rgbBits; + uint32 redMask; + uint32 greenMask; + uint32 blueMask; + uint32 alphaMask; + }; + + // Nested structure + struct DDSCaps + { + uint32 caps1; + uint32 caps2; + uint32 caps3; + uint32 caps4; + }; + // Main header, note preceded by 'DDS ' + struct DDSHeader + { + uint32 size; + uint32 flags; + uint32 height; + uint32 width; + uint32 sizeOrPitch; + uint32 depth; + uint32 mipMapCount; + uint32 reserved1[11]; + DDSPixelFormat pixelFormat; + DDSCaps caps; + uint32 reserved2; + }; // Extended header struct DDSExtendedHeader @@ -93,106 +93,106 @@ namespace Ogre { }; - // An 8-byte DXT colour block, represents a 4x4 texel area. Used by all DXT formats - struct DXTColourBlock - { - // 2 colour ranges - uint16 colour_0; - uint16 colour_1; - // 16 2-bit indexes, each byte here is one row - uint8 indexRow[4]; - }; - // An 8-byte DXT explicit alpha block, represents a 4x4 texel area. Used by DXT2/3 - struct DXTExplicitAlphaBlock - { - // 16 4-bit values, each 16-bit value is one row - uint16 alphaRow[4]; - }; - // An 8-byte DXT interpolated alpha block, represents a 4x4 texel area. Used by DXT4/5 - struct DXTInterpolatedAlphaBlock - { - // 2 alpha ranges - uint8 alpha_0; - uint8 alpha_1; - // 16 3-bit indexes. Unfortunately 3 bits doesn't map too well to row bytes - // so just stored raw - uint8 indexes[6]; - }; - + // An 8-byte DXT colour block, represents a 4x4 texel area. Used by all DXT formats + struct DXTColourBlock + { + // 2 colour ranges + uint16 colour_0; + uint16 colour_1; + // 16 2-bit indexes, each byte here is one row + uint8 indexRow[4]; + }; + // An 8-byte DXT explicit alpha block, represents a 4x4 texel area. Used by DXT2/3 + struct DXTExplicitAlphaBlock + { + // 16 4-bit values, each 16-bit value is one row + uint16 alphaRow[4]; + }; + // An 8-byte DXT interpolated alpha block, represents a 4x4 texel area. Used by DXT4/5 + struct DXTInterpolatedAlphaBlock + { + // 2 alpha ranges + uint8 alpha_0; + uint8 alpha_1; + // 16 3-bit indexes. Unfortunately 3 bits doesn't map too well to row bytes + // so just stored raw + uint8 indexes[6]; + }; + #if OGRE_COMPILER == OGRE_COMPILER_MSVC #pragma pack (pop) #else #pragma pack () #endif - const uint32 DDS_MAGIC = FOURCC('D', 'D', 'S', ' '); - const uint32 DDS_PIXELFORMAT_SIZE = 8 * sizeof(uint32); - const uint32 DDS_CAPS_SIZE = 4 * sizeof(uint32); - const uint32 DDS_HEADER_SIZE = 19 * sizeof(uint32) + DDS_PIXELFORMAT_SIZE + DDS_CAPS_SIZE; - - const uint32 DDSD_CAPS = 0x00000001; - const uint32 DDSD_HEIGHT = 0x00000002; - const uint32 DDSD_WIDTH = 0x00000004; - const uint32 DDSD_PIXELFORMAT = 0x00001000; - const uint32 DDSD_DEPTH = 0x00800000; - const uint32 DDPF_ALPHAPIXELS = 0x00000001; - const uint32 DDPF_FOURCC = 0x00000004; - const uint32 DDPF_RGB = 0x00000040; - const uint32 DDSCAPS_COMPLEX = 0x00000008; - const uint32 DDSCAPS_TEXTURE = 0x00001000; - const uint32 DDSCAPS_MIPMAP = 0x00400000; - const uint32 DDSCAPS2_CUBEMAP = 0x00000200; - const uint32 DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400; - const uint32 DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800; - const uint32 DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000; - const uint32 DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000; - const uint32 DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000; - const uint32 DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000; - const uint32 DDSCAPS2_VOLUME = 0x00200000; + const uint32 DDS_MAGIC = FOURCC('D', 'D', 'S', ' '); + const uint32 DDS_PIXELFORMAT_SIZE = 8 * sizeof(uint32); + const uint32 DDS_CAPS_SIZE = 4 * sizeof(uint32); + const uint32 DDS_HEADER_SIZE = 19 * sizeof(uint32) + DDS_PIXELFORMAT_SIZE + DDS_CAPS_SIZE; + + const uint32 DDSD_CAPS = 0x00000001; + const uint32 DDSD_HEIGHT = 0x00000002; + const uint32 DDSD_WIDTH = 0x00000004; + const uint32 DDSD_PIXELFORMAT = 0x00001000; + const uint32 DDSD_DEPTH = 0x00800000; + const uint32 DDPF_ALPHAPIXELS = 0x00000001; + const uint32 DDPF_FOURCC = 0x00000004; + const uint32 DDPF_RGB = 0x00000040; + const uint32 DDSCAPS_COMPLEX = 0x00000008; + const uint32 DDSCAPS_TEXTURE = 0x00001000; + const uint32 DDSCAPS_MIPMAP = 0x00400000; + const uint32 DDSCAPS2_CUBEMAP = 0x00000200; + const uint32 DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400; + const uint32 DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800; + const uint32 DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000; + const uint32 DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000; + const uint32 DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000; + const uint32 DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000; + const uint32 DDSCAPS2_VOLUME = 0x00200000; // Currently unused // const uint32 DDSD_PITCH = 0x00000008; // const uint32 DDSD_MIPMAPCOUNT = 0x00020000; // const uint32 DDSD_LINEARSIZE = 0x00080000; - // Special FourCC codes - const uint32 D3DFMT_R16F = 111; - const uint32 D3DFMT_G16R16F = 112; - const uint32 D3DFMT_A16B16G16R16F = 113; - const uint32 D3DFMT_R32F = 114; - const uint32 D3DFMT_G32R32F = 115; - const uint32 D3DFMT_A32B32G32R32F = 116; - - - //--------------------------------------------------------------------- - DDSCodec* DDSCodec::msInstance = 0; - //--------------------------------------------------------------------- - void DDSCodec::startup(void) - { - if (!msInstance) - { - - LogManager::getSingleton().logMessage( - LML_NORMAL, - "DDS codec registering"); - - msInstance = OGRE_NEW DDSCodec(); - Codec::registerCodec(msInstance); - } - - } - //--------------------------------------------------------------------- - void DDSCodec::shutdown(void) - { - if(msInstance) - { - Codec::unregisterCodec(msInstance); - OGRE_DELETE msInstance; - msInstance = 0; - } - - } - //--------------------------------------------------------------------- + // Special FourCC codes + const uint32 D3DFMT_R16F = 111; + const uint32 D3DFMT_G16R16F = 112; + const uint32 D3DFMT_A16B16G16R16F = 113; + const uint32 D3DFMT_R32F = 114; + const uint32 D3DFMT_G32R32F = 115; + const uint32 D3DFMT_A32B32G32R32F = 116; + + + //--------------------------------------------------------------------- + DDSCodec* DDSCodec::msInstance = 0; + //--------------------------------------------------------------------- + void DDSCodec::startup(void) + { + if (!msInstance) + { + + LogManager::getSingleton().logMessage( + LML_NORMAL, + "DDS codec registering"); + + msInstance = OGRE_NEW DDSCodec(); + Codec::registerCodec(msInstance); + } + + } + //--------------------------------------------------------------------- + void DDSCodec::shutdown(void) + { + if(msInstance) + { + Codec::unregisterCodec(msInstance); + OGRE_DELETE msInstance; + msInstance = 0; + } + + } + //--------------------------------------------------------------------- DDSCodec::DDSCodec(): mType("dds") { @@ -200,184 +200,184 @@ namespace Ogre { //--------------------------------------------------------------------- DataStreamPtr DDSCodec::encode(MemoryDataStreamPtr& input, Codec::CodecDataPtr& pData) const { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "DDS encoding not supported", - "DDSCodec::encode" ) ; + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "DDS encoding not supported", + "DDSCodec::encode" ) ; } //--------------------------------------------------------------------- void DDSCodec::encodeToFile(MemoryDataStreamPtr& input, const String& outFileName, Codec::CodecDataPtr& pData) const { - // Unwrap codecDataPtr - data is cleaned by calling function - ImageData* imgData = static_cast(pData.getPointer()); - - - // Check size for cube map faces - bool isCubeMap = (imgData->size == - Image::calculateSize(imgData->num_mipmaps, 6, imgData->width, - imgData->height, imgData->depth, imgData->format)); - - // Establish texture attributes - bool isVolume = (imgData->depth > 1); - bool isFloat32r = (imgData->format == PF_FLOAT32_R); - bool notImplemented = false; - String notImplementedString = ""; - - // Check for all the 'not implemented' conditions - if (imgData->num_mipmaps != 0) - { - // No mip map functionality yet - notImplemented = true; - notImplementedString += " mipmaps"; - } - - if ((isVolume == true)&&(imgData->width != imgData->height)) - { - // Square textures only - notImplemented = true; - notImplementedString += " non square textures"; - } - - uint32 size = 1; - while (size < imgData->width) - { - size <<= 1; - } - if (size != imgData->width) - { - // Power two textures only - notImplemented = true; - notImplementedString += " non power two textures"; - } - - switch(imgData->format) - { - case PF_A8R8G8B8: - case PF_X8R8G8B8: - case PF_R8G8B8: - case PF_FLOAT32_R: - break; - default: - // No crazy FOURCC or 565 et al. file formats at this stage - notImplemented = true; - notImplementedString = " unsupported pixel format"; - break; - } - - - - // Except if any 'not implemented' conditions were met - if (notImplemented) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "DDS encoding for" + notImplementedString + " not supported", - "DDSCodec::encodeToFile" ) ; - } - else - { - // Build header and write to disk - - // Variables for some DDS header flags + // Unwrap codecDataPtr - data is cleaned by calling function + ImageData* imgData = static_cast(pData.getPointer()); + + + // Check size for cube map faces + bool isCubeMap = (imgData->size == + Image::calculateSize(imgData->num_mipmaps, 6, imgData->width, + imgData->height, imgData->depth, imgData->format)); + + // Establish texture attributes + bool isVolume = (imgData->depth > 1); + bool isFloat32r = (imgData->format == PF_FLOAT32_R); + bool notImplemented = false; + String notImplementedString = ""; + + // Check for all the 'not implemented' conditions + if (imgData->num_mipmaps != 0) + { + // No mip map functionality yet + notImplemented = true; + notImplementedString += " mipmaps"; + } + + if ((isVolume == true)&&(imgData->width != imgData->height)) + { + // Square textures only + notImplemented = true; + notImplementedString += " non square textures"; + } + + uint32 size = 1; + while (size < imgData->width) + { + size <<= 1; + } + if (size != imgData->width) + { + // Power two textures only + notImplemented = true; + notImplementedString += " non power two textures"; + } + + switch(imgData->format) + { + case PF_A8R8G8B8: + case PF_X8R8G8B8: + case PF_R8G8B8: + case PF_FLOAT32_R: + break; + default: + // No crazy FOURCC or 565 et al. file formats at this stage + notImplemented = true; + notImplementedString = " unsupported pixel format"; + break; + } + + + + // Except if any 'not implemented' conditions were met + if (notImplemented) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "DDS encoding for" + notImplementedString + " not supported", + "DDSCodec::encodeToFile" ) ; + } + else + { + // Build header and write to disk + + // Variables for some DDS header flags bool hasAlpha = false; - uint32 ddsHeaderFlags = 0; - uint32 ddsHeaderRgbBits = 0; - uint32 ddsHeaderSizeOrPitch = 0; - uint32 ddsHeaderCaps1 = 0; - uint32 ddsHeaderCaps2 = 0; - uint32 ddsMagic = DDS_MAGIC; - - // Initalise the header flags - ddsHeaderFlags = (isVolume) ? DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_DEPTH|DDSD_PIXELFORMAT : - DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT; - - // Initalise the rgbBits flags - switch(imgData->format) - { - case PF_A8R8G8B8: - ddsHeaderRgbBits = 8 * 4; - hasAlpha = true; - break; - case PF_X8R8G8B8: - ddsHeaderRgbBits = 8 * 4; - break; - case PF_R8G8B8: - ddsHeaderRgbBits = 8 * 3; - break; - case PF_FLOAT32_R: - ddsHeaderRgbBits = 32; - break; - default: - ddsHeaderRgbBits = 0; - break; - } - - // Initalise the SizeOrPitch flags (power two textures for now) - ddsHeaderSizeOrPitch = static_cast(ddsHeaderRgbBits * imgData->width); - - // Initalise the caps flags - ddsHeaderCaps1 = (isVolume||isCubeMap) ? DDSCAPS_COMPLEX|DDSCAPS_TEXTURE : DDSCAPS_TEXTURE; - if (isVolume) - { - ddsHeaderCaps2 = DDSCAPS2_VOLUME; - } - else if (isCubeMap) - { - ddsHeaderCaps2 = DDSCAPS2_CUBEMAP| - DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX| - DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY| - DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ; - } - - // Populate the DDS header information - DDSHeader ddsHeader; - ddsHeader.size = DDS_HEADER_SIZE; - ddsHeader.flags = ddsHeaderFlags; - ddsHeader.width = (uint32)imgData->width; - ddsHeader.height = (uint32)imgData->height; - ddsHeader.depth = (uint32)(isVolume ? imgData->depth : 0); - ddsHeader.depth = (uint32)(isCubeMap ? 6 : ddsHeader.depth); - ddsHeader.mipMapCount = 0; - ddsHeader.sizeOrPitch = ddsHeaderSizeOrPitch; - for (uint32 reserved1=0; reserved1<11; reserved1++) // XXX nasty constant 11 - { - ddsHeader.reserved1[reserved1] = 0; - } - ddsHeader.reserved2 = 0; - - ddsHeader.pixelFormat.size = DDS_PIXELFORMAT_SIZE; - ddsHeader.pixelFormat.flags = (hasAlpha) ? DDPF_RGB|DDPF_ALPHAPIXELS : DDPF_RGB; - ddsHeader.pixelFormat.flags = (isFloat32r) ? DDPF_FOURCC : ddsHeader.pixelFormat.flags; - ddsHeader.pixelFormat.fourCC = (isFloat32r) ? D3DFMT_R32F : 0; - ddsHeader.pixelFormat.rgbBits = ddsHeaderRgbBits; - - ddsHeader.pixelFormat.alphaMask = (hasAlpha) ? 0xFF000000 : 0x00000000; - ddsHeader.pixelFormat.alphaMask = (isFloat32r) ? 0x00000000 : ddsHeader.pixelFormat.alphaMask; - ddsHeader.pixelFormat.redMask = (isFloat32r) ? 0xFFFFFFFF :0x00FF0000; - ddsHeader.pixelFormat.greenMask = (isFloat32r) ? 0x00000000 :0x0000FF00; - ddsHeader.pixelFormat.blueMask = (isFloat32r) ? 0x00000000 :0x000000FF; - - ddsHeader.caps.caps1 = ddsHeaderCaps1; - ddsHeader.caps.caps2 = ddsHeaderCaps2; -// ddsHeader.caps.reserved[0] = 0; -// ddsHeader.caps.reserved[1] = 0; - - // Swap endian - flipEndian(&ddsMagic, sizeof(uint32), 1); - flipEndian(&ddsHeader, 4, sizeof(DDSHeader) / 4); - - // Write the file - std::ofstream of; - of.open(outFileName.c_str(), std::ios_base::binary|std::ios_base::out); - of.write((const char *)&ddsMagic, sizeof(uint32)); - of.write((const char *)&ddsHeader, DDS_HEADER_SIZE); - // XXX flipEndian on each pixel chunk written unless isFloat32r ? - of.write((const char *)input->getPtr(), (uint32)imgData->size); - of.close(); - } - } - //--------------------------------------------------------------------- - PixelFormat DDSCodec::convertDXToOgreFormat(uint32 dxfmt) const - { + uint32 ddsHeaderFlags = 0; + uint32 ddsHeaderRgbBits = 0; + uint32 ddsHeaderSizeOrPitch = 0; + uint32 ddsHeaderCaps1 = 0; + uint32 ddsHeaderCaps2 = 0; + uint32 ddsMagic = DDS_MAGIC; + + // Initalise the header flags + ddsHeaderFlags = (isVolume) ? DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_DEPTH|DDSD_PIXELFORMAT : + DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT; + + // Initalise the rgbBits flags + switch(imgData->format) + { + case PF_A8R8G8B8: + ddsHeaderRgbBits = 8 * 4; + hasAlpha = true; + break; + case PF_X8R8G8B8: + ddsHeaderRgbBits = 8 * 4; + break; + case PF_R8G8B8: + ddsHeaderRgbBits = 8 * 3; + break; + case PF_FLOAT32_R: + ddsHeaderRgbBits = 32; + break; + default: + ddsHeaderRgbBits = 0; + break; + } + + // Initalise the SizeOrPitch flags (power two textures for now) + ddsHeaderSizeOrPitch = static_cast(ddsHeaderRgbBits * imgData->width); + + // Initalise the caps flags + ddsHeaderCaps1 = (isVolume||isCubeMap) ? DDSCAPS_COMPLEX|DDSCAPS_TEXTURE : DDSCAPS_TEXTURE; + if (isVolume) + { + ddsHeaderCaps2 = DDSCAPS2_VOLUME; + } + else if (isCubeMap) + { + ddsHeaderCaps2 = DDSCAPS2_CUBEMAP| + DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX| + DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY| + DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ; + } + + // Populate the DDS header information + DDSHeader ddsHeader; + ddsHeader.size = DDS_HEADER_SIZE; + ddsHeader.flags = ddsHeaderFlags; + ddsHeader.width = (uint32)imgData->width; + ddsHeader.height = (uint32)imgData->height; + ddsHeader.depth = (uint32)(isVolume ? imgData->depth : 0); + ddsHeader.depth = (uint32)(isCubeMap ? 6 : ddsHeader.depth); + ddsHeader.mipMapCount = 0; + ddsHeader.sizeOrPitch = ddsHeaderSizeOrPitch; + for (uint32 reserved1=0; reserved1<11; reserved1++) // XXX nasty constant 11 + { + ddsHeader.reserved1[reserved1] = 0; + } + ddsHeader.reserved2 = 0; + + ddsHeader.pixelFormat.size = DDS_PIXELFORMAT_SIZE; + ddsHeader.pixelFormat.flags = (hasAlpha) ? DDPF_RGB|DDPF_ALPHAPIXELS : DDPF_RGB; + ddsHeader.pixelFormat.flags = (isFloat32r) ? DDPF_FOURCC : ddsHeader.pixelFormat.flags; + ddsHeader.pixelFormat.fourCC = (isFloat32r) ? D3DFMT_R32F : 0; + ddsHeader.pixelFormat.rgbBits = ddsHeaderRgbBits; + + ddsHeader.pixelFormat.alphaMask = (hasAlpha) ? 0xFF000000 : 0x00000000; + ddsHeader.pixelFormat.alphaMask = (isFloat32r) ? 0x00000000 : ddsHeader.pixelFormat.alphaMask; + ddsHeader.pixelFormat.redMask = (isFloat32r) ? 0xFFFFFFFF :0x00FF0000; + ddsHeader.pixelFormat.greenMask = (isFloat32r) ? 0x00000000 :0x0000FF00; + ddsHeader.pixelFormat.blueMask = (isFloat32r) ? 0x00000000 :0x000000FF; + + ddsHeader.caps.caps1 = ddsHeaderCaps1; + ddsHeader.caps.caps2 = ddsHeaderCaps2; +// ddsHeader.caps.reserved[0] = 0; +// ddsHeader.caps.reserved[1] = 0; + + // Swap endian + flipEndian(&ddsMagic, sizeof(uint32), 1); + flipEndian(&ddsHeader, 4, sizeof(DDSHeader) / 4); + + // Write the file + std::ofstream of; + of.open(outFileName.c_str(), std::ios_base::binary|std::ios_base::out); + of.write((const char *)&ddsMagic, sizeof(uint32)); + of.write((const char *)&ddsHeader, DDS_HEADER_SIZE); + // XXX flipEndian on each pixel chunk written unless isFloat32r ? + of.write((const char *)input->getPtr(), (uint32)imgData->size); + of.close(); + } + } + //--------------------------------------------------------------------- + PixelFormat DDSCodec::convertDXToOgreFormat(uint32 dxfmt) const + { switch (dxfmt) { case 80: // DXGI_FORMAT_BC4_UNORM return PF_BC4_UNORM; @@ -401,22 +401,22 @@ namespace Ogre { "DDSCodec::convertDXToOgreFormat"); } } - //--------------------------------------------------------------------- - PixelFormat DDSCodec::convertFourCCFormat(uint32 fourcc) const - { - // convert dxt pixel format - switch(fourcc) - { - case FOURCC('D','X','T','1'): - return PF_DXT1; - case FOURCC('D','X','T','2'): - return PF_DXT2; - case FOURCC('D','X','T','3'): - return PF_DXT3; - case FOURCC('D','X','T','4'): - return PF_DXT4; - case FOURCC('D','X','T','5'): - return PF_DXT5; + //--------------------------------------------------------------------- + PixelFormat DDSCodec::convertFourCCFormat(uint32 fourcc) const + { + // convert dxt pixel format + switch(fourcc) + { + case FOURCC('D','X','T','1'): + return PF_DXT1; + case FOURCC('D','X','T','2'): + return PF_DXT2; + case FOURCC('D','X','T','3'): + return PF_DXT3; + case FOURCC('D','X','T','4'): + return PF_DXT4; + case FOURCC('D','X','T','5'): + return PF_DXT5; case FOURCC('A','T','I','1'): case FOURCC('B','C','4','U'): return PF_BC4_UNORM; @@ -427,157 +427,157 @@ namespace Ogre { return PF_BC5_UNORM; case FOURCC('B','C','5','S'): return PF_BC5_SNORM; - case D3DFMT_R16F: - return PF_FLOAT16_R; - case D3DFMT_G16R16F: - return PF_FLOAT16_GR; - case D3DFMT_A16B16G16R16F: - return PF_FLOAT16_RGBA; - case D3DFMT_R32F: - return PF_FLOAT32_R; - case D3DFMT_G32R32F: - return PF_FLOAT32_GR; - case D3DFMT_A32B32G32R32F: - return PF_FLOAT32_RGBA; - // We could support 3Dc here, but only ATI cards support it, not nVidia - default: - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Unsupported FourCC format found in DDS file", - "DDSCodec::convertFourCCFormat"); - }; - - } - //--------------------------------------------------------------------- - PixelFormat DDSCodec::convertPixelFormat(uint32 rgbBits, uint32 rMask, - uint32 gMask, uint32 bMask, uint32 aMask) const - { - // General search through pixel formats - for (int i = PF_UNKNOWN + 1; i < PF_COUNT; ++i) - { - PixelFormat pf = static_cast(i); - if (PixelUtil::getNumElemBits(pf) == rgbBits) - { - uint64 testMasks[4]; - PixelUtil::getBitMasks(pf, testMasks); - int testBits[4]; - PixelUtil::getBitDepths(pf, testBits); - if (testMasks[0] == rMask && testMasks[1] == gMask && - testMasks[2] == bMask && - // for alpha, deal with 'X8' formats by checking bit counts - (testMasks[3] == aMask || (aMask == 0 && testBits[3] == 0))) - { - return pf; - } - } - - } - - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot determine pixel format", - "DDSCodec::convertPixelFormat"); - } - //--------------------------------------------------------------------- - void DDSCodec::unpackDXTColour(PixelFormat pf, const DXTColourBlock& block, - ColourValue* pCol) const - { - // Note - we assume all values have already been endian swapped - - // Colour lookup table - ColourValue derivedColours[4]; - - if (pf == PF_DXT1 && block.colour_0 <= block.colour_1) - { - // 1-bit alpha - PixelUtil::unpackColour(&(derivedColours[0]), PF_R5G6B5, &(block.colour_0)); - PixelUtil::unpackColour(&(derivedColours[1]), PF_R5G6B5, &(block.colour_1)); - // one intermediate colour, half way between the other two - derivedColours[2] = (derivedColours[0] + derivedColours[1]) / 2; - // transparent colour - derivedColours[3] = ColourValue::ZERO; - } - else - { - PixelUtil::unpackColour(&(derivedColours[0]), PF_R5G6B5, &(block.colour_0)); - PixelUtil::unpackColour(&(derivedColours[1]), PF_R5G6B5, &(block.colour_1)); - // first interpolated colour, 1/3 of the way along - derivedColours[2] = (2 * derivedColours[0] + derivedColours[1]) / 3; - // second interpolated colour, 2/3 of the way along - derivedColours[3] = (derivedColours[0] + 2 * derivedColours[1]) / 3; - } - - // Process 4x4 block of texels - for (size_t row = 0; row < 4; ++row) - { - for (size_t x = 0; x < 4; ++x) - { - // LSB come first - uint8 colIdx = static_cast(block.indexRow[row] >> (x * 2) & 0x3); - if (pf == PF_DXT1) - { - // Overwrite entire colour - pCol[(row * 4) + x] = derivedColours[colIdx]; - } - else - { - // alpha has already been read (alpha precedes colour) - ColourValue& col = pCol[(row * 4) + x]; - col.r = derivedColours[colIdx].r; - col.g = derivedColours[colIdx].g; - col.b = derivedColours[colIdx].b; - } - } - - } - - - } - //--------------------------------------------------------------------- - void DDSCodec::unpackDXTAlpha( - const DXTExplicitAlphaBlock& block, ColourValue* pCol) const - { - // Note - we assume all values have already been endian swapped - - // This is an explicit alpha block, 4 bits per pixel, LSB first - for (size_t row = 0; row < 4; ++row) - { - for (size_t x = 0; x < 4; ++x) - { - // Shift and mask off to 4 bits - uint8 val = static_cast(block.alphaRow[row] >> (x * 4) & 0xF); - // Convert to [0,1] - pCol->a = (Real)val / (Real)0xF; - pCol++; - - } - - } - - } - //--------------------------------------------------------------------- - void DDSCodec::unpackDXTAlpha( - const DXTInterpolatedAlphaBlock& block, ColourValue* pCol) const - { + case D3DFMT_R16F: + return PF_FLOAT16_R; + case D3DFMT_G16R16F: + return PF_FLOAT16_GR; + case D3DFMT_A16B16G16R16F: + return PF_FLOAT16_RGBA; + case D3DFMT_R32F: + return PF_FLOAT32_R; + case D3DFMT_G32R32F: + return PF_FLOAT32_GR; + case D3DFMT_A32B32G32R32F: + return PF_FLOAT32_RGBA; + // We could support 3Dc here, but only ATI cards support it, not nVidia + default: + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Unsupported FourCC format found in DDS file", + "DDSCodec::convertFourCCFormat"); + }; + + } + //--------------------------------------------------------------------- + PixelFormat DDSCodec::convertPixelFormat(uint32 rgbBits, uint32 rMask, + uint32 gMask, uint32 bMask, uint32 aMask) const + { + // General search through pixel formats + for (int i = PF_UNKNOWN + 1; i < PF_COUNT; ++i) + { + PixelFormat pf = static_cast(i); + if (PixelUtil::getNumElemBits(pf) == rgbBits) + { + uint64 testMasks[4]; + PixelUtil::getBitMasks(pf, testMasks); + int testBits[4]; + PixelUtil::getBitDepths(pf, testBits); + if (testMasks[0] == rMask && testMasks[1] == gMask && + testMasks[2] == bMask && + // for alpha, deal with 'X8' formats by checking bit counts + (testMasks[3] == aMask || (aMask == 0 && testBits[3] == 0))) + { + return pf; + } + } + + } + + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot determine pixel format", + "DDSCodec::convertPixelFormat"); + } + //--------------------------------------------------------------------- + void DDSCodec::unpackDXTColour(PixelFormat pf, const DXTColourBlock& block, + ColourValue* pCol) const + { + // Note - we assume all values have already been endian swapped + + // Colour lookup table + ColourValue derivedColours[4]; + + if (pf == PF_DXT1 && block.colour_0 <= block.colour_1) + { + // 1-bit alpha + PixelUtil::unpackColour(&(derivedColours[0]), PF_R5G6B5, &(block.colour_0)); + PixelUtil::unpackColour(&(derivedColours[1]), PF_R5G6B5, &(block.colour_1)); + // one intermediate colour, half way between the other two + derivedColours[2] = (derivedColours[0] + derivedColours[1]) / 2; + // transparent colour + derivedColours[3] = ColourValue::ZERO; + } + else + { + PixelUtil::unpackColour(&(derivedColours[0]), PF_R5G6B5, &(block.colour_0)); + PixelUtil::unpackColour(&(derivedColours[1]), PF_R5G6B5, &(block.colour_1)); + // first interpolated colour, 1/3 of the way along + derivedColours[2] = (2 * derivedColours[0] + derivedColours[1]) / 3; + // second interpolated colour, 2/3 of the way along + derivedColours[3] = (derivedColours[0] + 2 * derivedColours[1]) / 3; + } + + // Process 4x4 block of texels + for (size_t row = 0; row < 4; ++row) + { + for (size_t x = 0; x < 4; ++x) + { + // LSB come first + uint8 colIdx = static_cast(block.indexRow[row] >> (x * 2) & 0x3); + if (pf == PF_DXT1) + { + // Overwrite entire colour + pCol[(row * 4) + x] = derivedColours[colIdx]; + } + else + { + // alpha has already been read (alpha precedes colour) + ColourValue& col = pCol[(row * 4) + x]; + col.r = derivedColours[colIdx].r; + col.g = derivedColours[colIdx].g; + col.b = derivedColours[colIdx].b; + } + } + + } + + + } + //--------------------------------------------------------------------- + void DDSCodec::unpackDXTAlpha( + const DXTExplicitAlphaBlock& block, ColourValue* pCol) const + { + // Note - we assume all values have already been endian swapped + + // This is an explicit alpha block, 4 bits per pixel, LSB first + for (size_t row = 0; row < 4; ++row) + { + for (size_t x = 0; x < 4; ++x) + { + // Shift and mask off to 4 bits + uint8 val = static_cast(block.alphaRow[row] >> (x * 4) & 0xF); + // Convert to [0,1] + pCol->a = (Real)val / (Real)0xF; + pCol++; + + } + + } + + } + //--------------------------------------------------------------------- + void DDSCodec::unpackDXTAlpha( + const DXTInterpolatedAlphaBlock& block, ColourValue* pCol) const + { // Adaptive 3-bit alpha part float derivedAlphas[8]; - // Explicit extremes + // Explicit extremes derivedAlphas[0] = ((float) block.alpha_0) * (1.0f / 255.0f); derivedAlphas[1] = ((float) block.alpha_1) * (1.0f / 255.0f); if(block.alpha_0 > block.alpha_1) { // 6 interpolated alpha values. - // full range including extremes at [0] and [7] - // we want to fill in [1] through [6] at weights ranging - // from 1/7 to 6/7 + // full range including extremes at [0] and [7] + // we want to fill in [1] through [6] at weights ranging + // from 1/7 to 6/7 for(size_t i = 1; i < 7; ++i) derivedAlphas[i + 1] = (derivedAlphas[0] * (7 - i) + derivedAlphas[1] * i) * (1.0f / 7.0f); } else { // 4 interpolated alpha values. - // full range including extremes at [0] and [5] - // we want to fill in [1] through [4] at weights ranging - // from 1/5 to 4/5 + // full range including extremes at [0] and [5] + // we want to fill in [1] through [4] at weights ranging + // from 1/5 to 4/5 for(size_t i = 1; i < 5; ++i) derivedAlphas[i + 1] = (derivedAlphas[0] * (5 - i) + derivedAlphas[1] * i) * (1.0f / 5.0f); @@ -585,7 +585,7 @@ namespace Ogre { derivedAlphas[7] = 1.0f; } - // Ok, now we've built the reference values, process the indexes + // Ok, now we've built the reference values, process the indexes uint32 dw = block.indexes[0] | (block.indexes[1] << 8) | (block.indexes[2] << 16); for(size_t i = 0; i < 8; ++i, dw >>= 3) @@ -595,75 +595,75 @@ namespace Ogre { for(size_t i = 8; i < 16; ++i, dw >>= 3) pCol[i].a = derivedAlphas[dw & 0x7]; - } + } //--------------------------------------------------------------------- Codec::DecodeResult DDSCodec::decode(DataStreamPtr& stream) const { - // Read 4 character code - uint32 fileType; - stream->read(&fileType, sizeof(uint32)); - flipEndian(&fileType, sizeof(uint32), 1); - - if (FOURCC('D', 'D', 'S', ' ') != fileType) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "This is not a DDS file!", "DDSCodec::decode"); - } - - // Read header in full - DDSHeader header; - stream->read(&header, sizeof(DDSHeader)); - - // Endian flip if required, all 32-bit values - flipEndian(&header, 4, sizeof(DDSHeader) / 4); - - // Check some sizes - if (header.size != DDS_HEADER_SIZE) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "DDS header size mismatch!", "DDSCodec::decode"); - } - if (header.pixelFormat.size != DDS_PIXELFORMAT_SIZE) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "DDS header size mismatch!", "DDSCodec::decode"); - } - - ImageData* imgData = OGRE_NEW ImageData(); - MemoryDataStreamPtr output; - - imgData->depth = 1; // (deal with volume later) - imgData->width = header.width; - imgData->height = header.height; - size_t numFaces = 1; // assume one face until we know otherwise - - if (header.caps.caps1 & DDSCAPS_MIPMAP) - { - imgData->num_mipmaps = static_cast(header.mipMapCount - 1); - } - else - { - imgData->num_mipmaps = 0; - } - imgData->flags = 0; - - bool decompressDXT = false; - // Figure out basic image type - if (header.caps.caps2 & DDSCAPS2_CUBEMAP) - { - imgData->flags |= IF_CUBEMAP; - numFaces = 6; - } - else if (header.caps.caps2 & DDSCAPS2_VOLUME) - { - imgData->flags |= IF_3D_TEXTURE; - imgData->depth = header.depth; - } - // Pixel format - PixelFormat sourceFormat = PF_UNKNOWN; - - if (header.pixelFormat.flags & DDPF_FOURCC) - { + // Read 4 character code + uint32 fileType; + stream->read(&fileType, sizeof(uint32)); + flipEndian(&fileType, sizeof(uint32), 1); + + if (FOURCC('D', 'D', 'S', ' ') != fileType) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "This is not a DDS file!", "DDSCodec::decode"); + } + + // Read header in full + DDSHeader header; + stream->read(&header, sizeof(DDSHeader)); + + // Endian flip if required, all 32-bit values + flipEndian(&header, 4, sizeof(DDSHeader) / 4); + + // Check some sizes + if (header.size != DDS_HEADER_SIZE) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "DDS header size mismatch!", "DDSCodec::decode"); + } + if (header.pixelFormat.size != DDS_PIXELFORMAT_SIZE) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "DDS header size mismatch!", "DDSCodec::decode"); + } + + ImageData* imgData = OGRE_NEW ImageData(); + MemoryDataStreamPtr output; + + imgData->depth = 1; // (deal with volume later) + imgData->width = header.width; + imgData->height = header.height; + size_t numFaces = 1; // assume one face until we know otherwise + + if (header.caps.caps1 & DDSCAPS_MIPMAP) + { + imgData->num_mipmaps = static_cast(header.mipMapCount - 1); + } + else + { + imgData->num_mipmaps = 0; + } + imgData->flags = 0; + + bool decompressDXT = false; + // Figure out basic image type + if (header.caps.caps2 & DDSCAPS2_CUBEMAP) + { + imgData->flags |= IF_CUBEMAP; + numFaces = 6; + } + else if (header.caps.caps2 & DDSCAPS2_VOLUME) + { + imgData->flags |= IF_3D_TEXTURE; + imgData->depth = header.depth; + } + // Pixel format + PixelFormat sourceFormat = PF_UNKNOWN; + + if (header.pixelFormat.flags & DDPF_FOURCC) + { // Check if we have an DX10 style extended header and read it. This is necessary for B6H and B7 formats if(header.pixelFormat.fourCC == FOURCC('D', 'X', '1', '0')) { @@ -678,219 +678,219 @@ namespace Ogre { { sourceFormat = convertFourCCFormat(header.pixelFormat.fourCC); } - } - else - { - sourceFormat = convertPixelFormat(header.pixelFormat.rgbBits, - header.pixelFormat.redMask, header.pixelFormat.greenMask, - header.pixelFormat.blueMask, - header.pixelFormat.flags & DDPF_ALPHAPIXELS ? - header.pixelFormat.alphaMask : 0); - } - - if (PixelUtil::isCompressed(sourceFormat)) - { - if (Root::getSingleton().getRenderSystem() == NULL || - !Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_TEXTURE_COMPRESSION_DXT) + } + else + { + sourceFormat = convertPixelFormat(header.pixelFormat.rgbBits, + header.pixelFormat.redMask, header.pixelFormat.greenMask, + header.pixelFormat.blueMask, + header.pixelFormat.flags & DDPF_ALPHAPIXELS ? + header.pixelFormat.alphaMask : 0); + } + + if (PixelUtil::isCompressed(sourceFormat)) + { + if (Root::getSingleton().getRenderSystem() == NULL || + !Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_TEXTURE_COMPRESSION_DXT) || (!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP) && !imgData->num_mipmaps)) - { - // We'll need to decompress - decompressDXT = true; - // Convert format - switch (sourceFormat) - { - case PF_DXT1: - // source can be either 565 or 5551 depending on whether alpha present - // unfortunately you have to read a block to figure out which - // Note that we upgrade to 32-bit pixel formats here, even - // though the source is 16-bit; this is because the interpolated - // values will benefit from the 32-bit results, and the source - // from which the 16-bit samples are calculated may have been - // 32-bit so can benefit from this. - DXTColourBlock block; - stream->read(&block, sizeof(DXTColourBlock)); - flipEndian(&(block.colour_0), sizeof(uint16), 1); - flipEndian(&(block.colour_1), sizeof(uint16), 1); - // skip back since we'll need to read this again - stream->skip(0 - (long)sizeof(DXTColourBlock)); - // colour_0 <= colour_1 means transparency in DXT1 - if (block.colour_0 <= block.colour_1) - { - imgData->format = PF_BYTE_RGBA; - } - else - { - imgData->format = PF_BYTE_RGB; - } - break; - case PF_DXT2: - case PF_DXT3: - case PF_DXT4: - case PF_DXT5: - // full alpha present, formats vary only in encoding - imgData->format = PF_BYTE_RGBA; - break; + { + // We'll need to decompress + decompressDXT = true; + // Convert format + switch (sourceFormat) + { + case PF_DXT1: + // source can be either 565 or 5551 depending on whether alpha present + // unfortunately you have to read a block to figure out which + // Note that we upgrade to 32-bit pixel formats here, even + // though the source is 16-bit; this is because the interpolated + // values will benefit from the 32-bit results, and the source + // from which the 16-bit samples are calculated may have been + // 32-bit so can benefit from this. + DXTColourBlock block; + stream->read(&block, sizeof(DXTColourBlock)); + flipEndian(&(block.colour_0), sizeof(uint16), 1); + flipEndian(&(block.colour_1), sizeof(uint16), 1); + // skip back since we'll need to read this again + stream->skip(0 - (long)sizeof(DXTColourBlock)); + // colour_0 <= colour_1 means transparency in DXT1 + if (block.colour_0 <= block.colour_1) + { + imgData->format = PF_BYTE_RGBA; + } + else + { + imgData->format = PF_BYTE_RGB; + } + break; + case PF_DXT2: + case PF_DXT3: + case PF_DXT4: + case PF_DXT5: + // full alpha present, formats vary only in encoding + imgData->format = PF_BYTE_RGBA; + break; default: // all other cases need no special format handling break; - } - } - else - { - // Use original format - imgData->format = sourceFormat; - // Keep DXT data compressed - imgData->flags |= IF_COMPRESSED; - } - } - else // not compressed - { - // Don't test against DDPF_RGB since greyscale DDS doesn't set this - // just derive any other kind of format - imgData->format = sourceFormat; - } - - // Calculate total size from number of mipmaps, faces and size - imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, - imgData->width, imgData->height, imgData->depth, imgData->format); - - // Bind output buffer - output.bind(OGRE_NEW MemoryDataStream(imgData->size)); - - - // Now deal with the data - void* destPtr = output->getPtr(); - - // all mips for a face, then each face - for(size_t i = 0; i < numFaces; ++i) - { - uint32 width = imgData->width; - uint32 height = imgData->height; - uint32 depth = imgData->depth; - - for(size_t mip = 0; mip <= imgData->num_mipmaps; ++mip) - { - size_t dstPitch = width * PixelUtil::getNumElemBytes(imgData->format); - - if (PixelUtil::isCompressed(sourceFormat)) - { - // Compressed data - if (decompressDXT) - { - DXTColourBlock col; - DXTInterpolatedAlphaBlock iAlpha; - DXTExplicitAlphaBlock eAlpha; - // 4x4 block of decompressed colour - ColourValue tempColours[16]; - size_t destBpp = PixelUtil::getNumElemBytes(imgData->format); - size_t sx = std::min((size_t)width, (size_t)4); - size_t sy = std::min((size_t)height, (size_t)4); - size_t destPitchMinus4 = dstPitch - destBpp * sx; - // slices are done individually - for(size_t z = 0; z < depth; ++z) - { - // 4x4 blocks in x/y - for (size_t y = 0; y < height; y += 4) - { - for (size_t x = 0; x < width; x += 4) - { - if (sourceFormat == PF_DXT2 || - sourceFormat == PF_DXT3) - { - // explicit alpha - stream->read(&eAlpha, sizeof(DXTExplicitAlphaBlock)); - flipEndian(eAlpha.alphaRow, sizeof(uint16), 4); - unpackDXTAlpha(eAlpha, tempColours) ; - } - else if (sourceFormat == PF_DXT4 || - sourceFormat == PF_DXT5) - { - // interpolated alpha - stream->read(&iAlpha, sizeof(DXTInterpolatedAlphaBlock)); - flipEndian(&(iAlpha.alpha_0), sizeof(uint16), 1); - flipEndian(&(iAlpha.alpha_1), sizeof(uint16), 1); - unpackDXTAlpha(iAlpha, tempColours) ; - } - // always read colour - stream->read(&col, sizeof(DXTColourBlock)); - flipEndian(&(col.colour_0), sizeof(uint16), 1); - flipEndian(&(col.colour_1), sizeof(uint16), 1); - unpackDXTColour(sourceFormat, col, tempColours); - - // write 4x4 block to uncompressed version - for (size_t by = 0; by < sy; ++by) - { - for (size_t bx = 0; bx < sx; ++bx) - { - PixelUtil::packColour(tempColours[by*4+bx], - imgData->format, destPtr); - destPtr = static_cast( - static_cast(destPtr) + destBpp); - } - // advance to next row - destPtr = static_cast( - static_cast(destPtr) + destPitchMinus4); - } - // next block. Our dest pointer is 4 lines down - // from where it started - if (x + 4 >= width) - { - // Jump back to the start of the line - destPtr = static_cast( - static_cast(destPtr) - destPitchMinus4); - } - else - { - // Jump back up 4 rows and 4 pixels to the - // right to be at the next block to the right - destPtr = static_cast( - static_cast(destPtr) - dstPitch * sy + destBpp * sx); - - } - - } - - } - } - - } - else - { - // load directly - // DDS format lies! sizeOrPitch is not always set for DXT!! - size_t dxtSize = PixelUtil::getMemorySize(width, height, depth, imgData->format); - stream->read(destPtr, dxtSize); - destPtr = static_cast(static_cast(destPtr) + dxtSize); - } - - } - else - { + } + } + else + { + // Use original format + imgData->format = sourceFormat; + // Keep DXT data compressed + imgData->flags |= IF_COMPRESSED; + } + } + else // not compressed + { + // Don't test against DDPF_RGB since greyscale DDS doesn't set this + // just derive any other kind of format + imgData->format = sourceFormat; + } + + // Calculate total size from number of mipmaps, faces and size + imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, + imgData->width, imgData->height, imgData->depth, imgData->format); + + // Bind output buffer + output.bind(OGRE_NEW MemoryDataStream(imgData->size)); + + + // Now deal with the data + void* destPtr = output->getPtr(); + + // all mips for a face, then each face + for(size_t i = 0; i < numFaces; ++i) + { + uint32 width = imgData->width; + uint32 height = imgData->height; + uint32 depth = imgData->depth; + + for(size_t mip = 0; mip <= imgData->num_mipmaps; ++mip) + { + size_t dstPitch = width * PixelUtil::getNumElemBytes(imgData->format); + + if (PixelUtil::isCompressed(sourceFormat)) + { + // Compressed data + if (decompressDXT) + { + DXTColourBlock col; + DXTInterpolatedAlphaBlock iAlpha; + DXTExplicitAlphaBlock eAlpha; + // 4x4 block of decompressed colour + ColourValue tempColours[16]; + size_t destBpp = PixelUtil::getNumElemBytes(imgData->format); + size_t sx = std::min((size_t)width, (size_t)4); + size_t sy = std::min((size_t)height, (size_t)4); + size_t destPitchMinus4 = dstPitch - destBpp * sx; + // slices are done individually + for(size_t z = 0; z < depth; ++z) + { + // 4x4 blocks in x/y + for (size_t y = 0; y < height; y += 4) + { + for (size_t x = 0; x < width; x += 4) + { + if (sourceFormat == PF_DXT2 || + sourceFormat == PF_DXT3) + { + // explicit alpha + stream->read(&eAlpha, sizeof(DXTExplicitAlphaBlock)); + flipEndian(eAlpha.alphaRow, sizeof(uint16), 4); + unpackDXTAlpha(eAlpha, tempColours) ; + } + else if (sourceFormat == PF_DXT4 || + sourceFormat == PF_DXT5) + { + // interpolated alpha + stream->read(&iAlpha, sizeof(DXTInterpolatedAlphaBlock)); + flipEndian(&(iAlpha.alpha_0), sizeof(uint16), 1); + flipEndian(&(iAlpha.alpha_1), sizeof(uint16), 1); + unpackDXTAlpha(iAlpha, tempColours) ; + } + // always read colour + stream->read(&col, sizeof(DXTColourBlock)); + flipEndian(&(col.colour_0), sizeof(uint16), 1); + flipEndian(&(col.colour_1), sizeof(uint16), 1); + unpackDXTColour(sourceFormat, col, tempColours); + + // write 4x4 block to uncompressed version + for (size_t by = 0; by < sy; ++by) + { + for (size_t bx = 0; bx < sx; ++bx) + { + PixelUtil::packColour(tempColours[by*4+bx], + imgData->format, destPtr); + destPtr = static_cast( + static_cast(destPtr) + destBpp); + } + // advance to next row + destPtr = static_cast( + static_cast(destPtr) + destPitchMinus4); + } + // next block. Our dest pointer is 4 lines down + // from where it started + if (x + 4 >= width) + { + // Jump back to the start of the line + destPtr = static_cast( + static_cast(destPtr) - destPitchMinus4); + } + else + { + // Jump back up 4 rows and 4 pixels to the + // right to be at the next block to the right + destPtr = static_cast( + static_cast(destPtr) - dstPitch * sy + destBpp * sx); + + } + + } + + } + } + + } + else + { + // load directly + // DDS format lies! sizeOrPitch is not always set for DXT!! + size_t dxtSize = PixelUtil::getMemorySize(width, height, depth, imgData->format); + stream->read(destPtr, dxtSize); + destPtr = static_cast(static_cast(destPtr) + dxtSize); + } + + } + else + { // Note: We assume the source and destination have the same pitch - for (size_t z = 0; z < imgData->depth; ++z) - { - for (size_t y = 0; y < imgData->height; ++y) - { - stream->read(destPtr, dstPitch); - destPtr = static_cast(static_cast(destPtr) + dstPitch); - } - } - } - - /// Next mip - if(width!=1) width /= 2; - if(height!=1) height /= 2; - if(depth!=1) depth /= 2; - } - - } - - DecodeResult ret; - ret.first = output; - ret.second = CodecDataPtr(imgData); - return ret; - + for (size_t z = 0; z < imgData->depth; ++z) + { + for (size_t y = 0; y < imgData->height; ++y) + { + stream->read(destPtr, dstPitch); + destPtr = static_cast(static_cast(destPtr) + dstPitch); + } + } + } + + /// Next mip + if(width!=1) width /= 2; + if(height!=1) height /= 2; + if(depth!=1) depth /= 2; + } + + } + + DecodeResult ret; + ret.first = output; + ret.second = CodecDataPtr(imgData); + return ret; + } @@ -903,7 +903,7 @@ namespace Ogre { void DDSCodec::flipEndian(void * pData, size_t size, size_t count) const { #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - for(unsigned int index = 0; index < count; index++) + for(unsigned int index = 0; index < count; index++) { flipEndian((void *)((long)pData + (index * size)), size); } @@ -921,24 +921,24 @@ namespace Ogre { } #endif } - //--------------------------------------------------------------------- - String DDSCodec::magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const - { - if (maxbytes >= sizeof(uint32)) - { - uint32 fileType; - memcpy(&fileType, magicNumberPtr, sizeof(uint32)); - flipEndian(&fileType, sizeof(uint32), 1); - - if (DDS_MAGIC == fileType) - { - return String("dds"); - } - } - - return BLANKSTRING; - - } - + //--------------------------------------------------------------------- + String DDSCodec::magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const + { + if (maxbytes >= sizeof(uint32)) + { + uint32 fileType; + memcpy(&fileType, magicNumberPtr, sizeof(uint32)); + flipEndian(&fileType, sizeof(uint32), 1); + + if (DDS_MAGIC == fileType) + { + return String("dds"); + } + } + + return BLANKSTRING; + + } + } diff --git a/OgreMain/src/OgreDataStream.cpp b/OgreMain/src/OgreDataStream.cpp index 8121c3e3d1b..abf92cd5065 100644 --- a/OgreMain/src/OgreDataStream.cpp +++ b/OgreMain/src/OgreDataStream.cpp @@ -84,12 +84,12 @@ namespace Ogre { //----------------------------------------------------------------------- size_t DataStream::readLine(char* buf, size_t maxCount, const String& delim) { - // Deal with both Unix & Windows LFs - bool trimCR = false; - if (delim.find_first_of('\n') != String::npos) - { - trimCR = true; - } + // Deal with both Unix & Windows LFs + bool trimCR = false; + if (delim.find_first_of('\n') != String::npos) + { + trimCR = true; + } char tmpBuf[OGRE_STREAM_TEMP_SIZE]; size_t chunkSize = std::min(maxCount, (size_t)OGRE_STREAM_TEMP_SIZE-1); @@ -190,7 +190,7 @@ namespace Ogre { //----------------------------------------------------------------------- //----------------------------------------------------------------------- MemoryDataStream::MemoryDataStream(void* pMem, size_t inSize, bool freeOnClose, bool readOnly) - : DataStream(static_cast(readOnly ? READ : (READ | WRITE))) + : DataStream(static_cast(readOnly ? READ : (READ | WRITE))) { mData = mPos = static_cast(pMem); mSize = inSize; @@ -357,35 +357,35 @@ namespace Ogre { mPos += cnt; return cnt; } - //--------------------------------------------------------------------- - size_t MemoryDataStream::write(const void* buf, size_t count) - { - size_t written = 0; - if (isWriteable()) - { - written = count; - // we only allow writing within the extents of allocated memory - // check for buffer overrun & disallow - if (mPos + written > mEnd) - written = mEnd - mPos; - if (written == 0) - return 0; - - memcpy(mPos, buf, written); - mPos += written; - } - return written; - } + //--------------------------------------------------------------------- + size_t MemoryDataStream::write(const void* buf, size_t count) + { + size_t written = 0; + if (isWriteable()) + { + written = count; + // we only allow writing within the extents of allocated memory + // check for buffer overrun & disallow + if (mPos + written > mEnd) + written = mEnd - mPos; + if (written == 0) + return 0; + + memcpy(mPos, buf, written); + mPos += written; + } + return written; + } //----------------------------------------------------------------------- size_t MemoryDataStream::readLine(char* buf, size_t maxCount, const String& delim) { // Deal with both Unix & Windows LFs - bool trimCR = false; - if (delim.find_first_of('\n') != String::npos) - { - trimCR = true; - } + bool trimCR = false; + if (delim.find_first_of('\n') != String::npos) + { + trimCR = true; + } size_t pos = 0; @@ -449,11 +449,11 @@ namespace Ogre { } //----------------------------------------------------------------------- size_t MemoryDataStream::tell(void) const - { - //mData is start, mPos is current location - return mPos - mData; - } - //----------------------------------------------------------------------- + { + //mData is start, mPos is current location + return mPos - mData; + } + //----------------------------------------------------------------------- bool MemoryDataStream::eof(void) const { return mPos >= mEnd; @@ -477,7 +477,7 @@ namespace Ogre { mInStream->seekg(0, std::ios_base::end); mSize = (size_t)mInStream->tellg(); mInStream->seekg(0, std::ios_base::beg); - determineAccess(); + determineAccess(); } //----------------------------------------------------------------------- FileStreamDataStream::FileStreamDataStream(const String& name, @@ -488,7 +488,7 @@ namespace Ogre { mInStream->seekg(0, std::ios_base::end); mSize = (size_t)mInStream->tellg(); mInStream->seekg(0, std::ios_base::beg); - determineAccess(); + determineAccess(); } //----------------------------------------------------------------------- FileStreamDataStream::FileStreamDataStream(const String& name, @@ -497,51 +497,51 @@ namespace Ogre { { // Size is passed in mSize = inSize; - determineAccess(); - } - //--------------------------------------------------------------------- - FileStreamDataStream::FileStreamDataStream(std::fstream* s, bool freeOnClose) - : DataStream(false), mInStream(s), mFStreamRO(0), mFStream(s), mFreeOnClose(freeOnClose) - { - // writeable! - // calculate the size - mInStream->seekg(0, std::ios_base::end); - mSize = (size_t)mInStream->tellg(); - mInStream->seekg(0, std::ios_base::beg); - determineAccess(); - - } - //----------------------------------------------------------------------- - FileStreamDataStream::FileStreamDataStream(const String& name, - std::fstream* s, bool freeOnClose) - : DataStream(name, false), mInStream(s), mFStreamRO(0), mFStream(s), mFreeOnClose(freeOnClose) - { - // writeable! - // calculate the size - mInStream->seekg(0, std::ios_base::end); - mSize = (size_t)mInStream->tellg(); - mInStream->seekg(0, std::ios_base::beg); - determineAccess(); - } - //----------------------------------------------------------------------- - FileStreamDataStream::FileStreamDataStream(const String& name, - std::fstream* s, size_t inSize, bool freeOnClose) - : DataStream(name, false), mInStream(s), mFStreamRO(0), mFStream(s), mFreeOnClose(freeOnClose) - { - // writeable! - // Size is passed in - mSize = inSize; - determineAccess(); - } - //--------------------------------------------------------------------- - void FileStreamDataStream::determineAccess() - { - mAccess = 0; - if (mInStream) - mAccess |= READ; - if (mFStream) - mAccess |= WRITE; - } + determineAccess(); + } + //--------------------------------------------------------------------- + FileStreamDataStream::FileStreamDataStream(std::fstream* s, bool freeOnClose) + : DataStream(false), mInStream(s), mFStreamRO(0), mFStream(s), mFreeOnClose(freeOnClose) + { + // writeable! + // calculate the size + mInStream->seekg(0, std::ios_base::end); + mSize = (size_t)mInStream->tellg(); + mInStream->seekg(0, std::ios_base::beg); + determineAccess(); + + } + //----------------------------------------------------------------------- + FileStreamDataStream::FileStreamDataStream(const String& name, + std::fstream* s, bool freeOnClose) + : DataStream(name, false), mInStream(s), mFStreamRO(0), mFStream(s), mFreeOnClose(freeOnClose) + { + // writeable! + // calculate the size + mInStream->seekg(0, std::ios_base::end); + mSize = (size_t)mInStream->tellg(); + mInStream->seekg(0, std::ios_base::beg); + determineAccess(); + } + //----------------------------------------------------------------------- + FileStreamDataStream::FileStreamDataStream(const String& name, + std::fstream* s, size_t inSize, bool freeOnClose) + : DataStream(name, false), mInStream(s), mFStreamRO(0), mFStream(s), mFreeOnClose(freeOnClose) + { + // writeable! + // Size is passed in + mSize = inSize; + determineAccess(); + } + //--------------------------------------------------------------------- + void FileStreamDataStream::determineAccess() + { + mAccess = 0; + if (mInStream) + mAccess |= READ; + if (mFStream) + mAccess |= WRITE; + } //----------------------------------------------------------------------- FileStreamDataStream::~FileStreamDataStream() { @@ -550,119 +550,119 @@ namespace Ogre { //----------------------------------------------------------------------- size_t FileStreamDataStream::read(void* buf, size_t count) { - mInStream->read(static_cast(buf), static_cast(count)); + mInStream->read(static_cast(buf), static_cast(count)); return (size_t)mInStream->gcount(); } - //----------------------------------------------------------------------- - size_t FileStreamDataStream::write(const void* buf, size_t count) - { - size_t written = 0; - if (isWriteable() && mFStream) - { - mFStream->write(static_cast(buf), static_cast(count)); - written = count; - } - return written; - } + //----------------------------------------------------------------------- + size_t FileStreamDataStream::write(const void* buf, size_t count) + { + size_t written = 0; + if (isWriteable() && mFStream) + { + mFStream->write(static_cast(buf), static_cast(count)); + written = count; + } + return written; + } //----------------------------------------------------------------------- size_t FileStreamDataStream::readLine(char* buf, size_t maxCount, const String& delim) { - if (delim.empty()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "No delimiter provided", - "FileStreamDataStream::readLine"); - } - if (delim.size() > 1) - { - LogManager::getSingleton().logMessage( - "WARNING: FileStreamDataStream::readLine - using only first delimeter"); - } - // Deal with both Unix & Windows LFs - bool trimCR = false; - if (delim.at(0) == '\n') - { - trimCR = true; - } - // maxCount + 1 since count excludes terminator in getline - mInStream->getline(buf, static_cast(maxCount+1), delim.at(0)); - size_t ret = (size_t)mInStream->gcount(); - // three options - // 1) we had an eof before we read a whole line - // 2) we ran out of buffer space - // 3) we read a whole line - in this case the delim character is taken from the stream but not written in the buffer so the read data is of length ret-1 and thus ends at index ret-2 - // in all cases the buffer will be null terminated for us - - if (mInStream->eof()) - { - // no problem - } - else if (mInStream->fail()) - { - // Did we fail because of maxCount hit? No - no terminating character - // in included in the count in this case - if (ret == maxCount) - { - // clear failbit for next time - mInStream->clear(); - } - else - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Streaming error occurred", - "FileStreamDataStream::readLine"); - } - } - else - { - // we need to adjust ret because we want to use it as a - // pointer to the terminating null character and it is - // currently the length of the data read from the stream - // i.e. 1 more than the length of the data in the buffer and - // hence 1 more than the _index_ of the NULL character - --ret; - } - - // trim off CR if we found CR/LF - if (trimCR && buf[ret-1] == '\r') - { - --ret; - buf[ret] = '\0'; - } - return ret; - } + if (delim.empty()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "No delimiter provided", + "FileStreamDataStream::readLine"); + } + if (delim.size() > 1) + { + LogManager::getSingleton().logMessage( + "WARNING: FileStreamDataStream::readLine - using only first delimeter"); + } + // Deal with both Unix & Windows LFs + bool trimCR = false; + if (delim.at(0) == '\n') + { + trimCR = true; + } + // maxCount + 1 since count excludes terminator in getline + mInStream->getline(buf, static_cast(maxCount+1), delim.at(0)); + size_t ret = (size_t)mInStream->gcount(); + // three options + // 1) we had an eof before we read a whole line + // 2) we ran out of buffer space + // 3) we read a whole line - in this case the delim character is taken from the stream but not written in the buffer so the read data is of length ret-1 and thus ends at index ret-2 + // in all cases the buffer will be null terminated for us + + if (mInStream->eof()) + { + // no problem + } + else if (mInStream->fail()) + { + // Did we fail because of maxCount hit? No - no terminating character + // in included in the count in this case + if (ret == maxCount) + { + // clear failbit for next time + mInStream->clear(); + } + else + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Streaming error occurred", + "FileStreamDataStream::readLine"); + } + } + else + { + // we need to adjust ret because we want to use it as a + // pointer to the terminating null character and it is + // currently the length of the data read from the stream + // i.e. 1 more than the length of the data in the buffer and + // hence 1 more than the _index_ of the NULL character + --ret; + } + + // trim off CR if we found CR/LF + if (trimCR && buf[ret-1] == '\r') + { + --ret; + buf[ret] = '\0'; + } + return ret; + } //----------------------------------------------------------------------- void FileStreamDataStream::skip(long count) { #if defined(STLPORT) - // Workaround for STLport issues: After reached eof of file stream, - // it's seems the stream was putted in intermediate state, and will be - // fail if try to repositioning relative to current position. - // Note: tellg() fail in this case too. - if (mInStream->eof()) - { - mInStream->clear(); - // Use seek relative to either begin or end to bring the stream - // back to normal state. - mInStream->seekg(0, std::ios::end); - } -#endif - mInStream->clear(); //Clear fail status in case eof was set - mInStream->seekg(static_cast(count), std::ios::cur); + // Workaround for STLport issues: After reached eof of file stream, + // it's seems the stream was putted in intermediate state, and will be + // fail if try to repositioning relative to current position. + // Note: tellg() fail in this case too. + if (mInStream->eof()) + { + mInStream->clear(); + // Use seek relative to either begin or end to bring the stream + // back to normal state. + mInStream->seekg(0, std::ios::end); + } +#endif + mInStream->clear(); //Clear fail status in case eof was set + mInStream->seekg(static_cast(count), std::ios::cur); } //----------------------------------------------------------------------- void FileStreamDataStream::seek( size_t pos ) { - mInStream->clear(); //Clear fail status in case eof was set - mInStream->seekg(static_cast(pos), std::ios::beg); - } - //----------------------------------------------------------------------- + mInStream->clear(); //Clear fail status in case eof was set + mInStream->seekg(static_cast(pos), std::ios::beg); + } + //----------------------------------------------------------------------- size_t FileStreamDataStream::tell(void) const - { - mInStream->clear(); //Clear fail status in case eof was set - return (size_t)mInStream->tellg(); - } - //----------------------------------------------------------------------- + { + mInStream->clear(); //Clear fail status in case eof was set + return (size_t)mInStream->tellg(); + } + //----------------------------------------------------------------------- bool FileStreamDataStream::eof(void) const { return mInStream->eof(); @@ -672,23 +672,23 @@ namespace Ogre { { if (mInStream) { - // Unfortunately, there is no file-specific shared class hierarchy between fstream and ifstream (!!) - if (mFStreamRO) - mFStreamRO->close(); - if (mFStream) - { - mFStream->flush(); - mFStream->close(); - } + // Unfortunately, there is no file-specific shared class hierarchy between fstream and ifstream (!!) + if (mFStreamRO) + mFStreamRO->close(); + if (mFStream) + { + mFStream->flush(); + mFStream->close(); + } if (mFreeOnClose) { // delete the stream too OGRE_DELETE_T(mFStreamRO, basic_ifstream, MEMCATEGORY_GENERAL); OGRE_DELETE_T(mFStream, basic_fstream, MEMCATEGORY_GENERAL); - mInStream = 0; - mFStreamRO = 0; - mFStream = 0; + mInStream = 0; + mFStreamRO = 0; + mFStream = 0; } } } @@ -697,19 +697,19 @@ namespace Ogre { FileHandleDataStream::FileHandleDataStream(FILE* handle, uint16 accessMode) : DataStream(accessMode), mFileHandle(handle) { - // Determine size - fseek(mFileHandle, 0, SEEK_END); - mSize = ftell(mFileHandle); - fseek(mFileHandle, 0, SEEK_SET); + // Determine size + fseek(mFileHandle, 0, SEEK_END); + mSize = ftell(mFileHandle); + fseek(mFileHandle, 0, SEEK_SET); } //----------------------------------------------------------------------- FileHandleDataStream::FileHandleDataStream(const String& name, FILE* handle, uint16 accessMode) : DataStream(name, accessMode), mFileHandle(handle) { - // Determine size - fseek(mFileHandle, 0, SEEK_END); - mSize = ftell(mFileHandle); - fseek(mFileHandle, 0, SEEK_SET); + // Determine size + fseek(mFileHandle, 0, SEEK_END); + mSize = ftell(mFileHandle); + fseek(mFileHandle, 0, SEEK_SET); } //----------------------------------------------------------------------- FileHandleDataStream::~FileHandleDataStream() @@ -721,15 +721,15 @@ namespace Ogre { { return fread(buf, 1, count, mFileHandle); } - //----------------------------------------------------------------------- - size_t FileHandleDataStream::write(const void* buf, size_t count) - { - if (!isWriteable()) - return 0; - else - return fwrite(buf, 1, count, mFileHandle); - } - //--------------------------------------------------------------------- + //----------------------------------------------------------------------- + size_t FileHandleDataStream::write(const void* buf, size_t count) + { + if (!isWriteable()) + return 0; + else + return fwrite(buf, 1, count, mFileHandle); + } + //--------------------------------------------------------------------- //----------------------------------------------------------------------- void FileHandleDataStream::skip(long count) { @@ -742,10 +742,10 @@ namespace Ogre { } //----------------------------------------------------------------------- size_t FileHandleDataStream::tell(void) const - { - return ftell( mFileHandle ); - } - //----------------------------------------------------------------------- + { + return ftell( mFileHandle ); + } + //----------------------------------------------------------------------- bool FileHandleDataStream::eof(void) const { return feof(mFileHandle) != 0; @@ -753,11 +753,11 @@ namespace Ogre { //----------------------------------------------------------------------- void FileHandleDataStream::close(void) { - if (mFileHandle != 0) - { - fclose(mFileHandle); - mFileHandle = 0; - } + if (mFileHandle != 0) + { + fclose(mFileHandle); + mFileHandle = 0; + } } //----------------------------------------------------------------------- diff --git a/OgreMain/src/OgreDefaultHardwareBufferManager.cpp b/OgreMain/src/OgreDefaultHardwareBufferManager.cpp index 42e1f04f168..88e0c3dbaa0 100644 --- a/OgreMain/src/OgreDefaultHardwareBufferManager.cpp +++ b/OgreMain/src/OgreDefaultHardwareBufferManager.cpp @@ -30,275 +30,275 @@ THE SOFTWARE. namespace Ogre { - DefaultHardwareVertexBuffer::DefaultHardwareVertexBuffer(size_t vertexSize, size_t numVertices, - HardwareBuffer::Usage usage) - : HardwareVertexBuffer(0, vertexSize, numVertices, usage, true, false) // always software, never shadowed - { + DefaultHardwareVertexBuffer::DefaultHardwareVertexBuffer(size_t vertexSize, size_t numVertices, + HardwareBuffer::Usage usage) + : HardwareVertexBuffer(0, vertexSize, numVertices, usage, true, false) // always software, never shadowed + { // Allocate aligned memory for better SIMD processing friendly. mData = static_cast(OGRE_MALLOC_SIMD(mSizeInBytes, MEMCATEGORY_GEOMETRY)); - } - //----------------------------------------------------------------------- - DefaultHardwareVertexBuffer::DefaultHardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, - HardwareBuffer::Usage usage) + } + //----------------------------------------------------------------------- + DefaultHardwareVertexBuffer::DefaultHardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, + HardwareBuffer::Usage usage) : HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, true, false) // always software, never shadowed - { + { // Allocate aligned memory for better SIMD processing friendly. mData = static_cast(OGRE_MALLOC_SIMD(mSizeInBytes, MEMCATEGORY_GEOMETRY)); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- DefaultHardwareVertexBuffer::~DefaultHardwareVertexBuffer() - { - OGRE_FREE_SIMD(mData, MEMCATEGORY_GEOMETRY); - } - //----------------------------------------------------------------------- + { + OGRE_FREE_SIMD(mData, MEMCATEGORY_GEOMETRY); + } + //----------------------------------------------------------------------- void* DefaultHardwareVertexBuffer::lockImpl(size_t offset, size_t length, LockOptions options) - { + { // Only for use internally, no 'locking' as such - return mData + offset; - } - //----------------------------------------------------------------------- - void DefaultHardwareVertexBuffer::unlockImpl(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void DefaultHardwareVertexBuffer::unlockImpl(void) + { // Nothing to do - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void* DefaultHardwareVertexBuffer::lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt) - { + { mIsLocked = true; - return mData + offset; - } - //----------------------------------------------------------------------- - void DefaultHardwareVertexBuffer::unlock(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void DefaultHardwareVertexBuffer::unlock(void) + { mIsLocked = false; // Nothing to do - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void DefaultHardwareVertexBuffer::readData(size_t offset, size_t length, void* pDest) - { - assert((offset + length) <= mSizeInBytes); - memcpy(pDest, mData + offset, length); - } - //----------------------------------------------------------------------- + { + assert((offset + length) <= mSizeInBytes); + memcpy(pDest, mData + offset, length); + } + //----------------------------------------------------------------------- void DefaultHardwareVertexBuffer::writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer) - { - assert((offset + length) <= mSizeInBytes); - // ignore discard, memory is not guaranteed to be zeroised - memcpy(mData + offset, pSource, length); + bool discardWholeBuffer) + { + assert((offset + length) <= mSizeInBytes); + // ignore discard, memory is not guaranteed to be zeroised + memcpy(mData + offset, pSource, length); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- - DefaultHardwareIndexBuffer::DefaultHardwareIndexBuffer(IndexType idxType, - size_t numIndexes, HardwareBuffer::Usage usage) - : HardwareIndexBuffer(0, idxType, numIndexes, usage, true, false) // always software, never shadowed - { - mData = OGRE_ALLOC_T(unsigned char, mSizeInBytes, MEMCATEGORY_GEOMETRY); - } - //----------------------------------------------------------------------- + DefaultHardwareIndexBuffer::DefaultHardwareIndexBuffer(IndexType idxType, + size_t numIndexes, HardwareBuffer::Usage usage) + : HardwareIndexBuffer(0, idxType, numIndexes, usage, true, false) // always software, never shadowed + { + mData = OGRE_ALLOC_T(unsigned char, mSizeInBytes, MEMCATEGORY_GEOMETRY); + } + //----------------------------------------------------------------------- DefaultHardwareIndexBuffer::~DefaultHardwareIndexBuffer() - { - OGRE_FREE(mData, MEMCATEGORY_GEOMETRY); - } - //----------------------------------------------------------------------- + { + OGRE_FREE(mData, MEMCATEGORY_GEOMETRY); + } + //----------------------------------------------------------------------- void* DefaultHardwareIndexBuffer::lockImpl(size_t offset, size_t length, LockOptions options) - { + { // Only for use internally, no 'locking' as such - return mData + offset; - } - //----------------------------------------------------------------------- - void DefaultHardwareIndexBuffer::unlockImpl(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void DefaultHardwareIndexBuffer::unlockImpl(void) + { // Nothing to do - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void* DefaultHardwareIndexBuffer::lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt) - { + { mIsLocked = true; - return mData + offset; - } - //----------------------------------------------------------------------- - void DefaultHardwareIndexBuffer::unlock(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void DefaultHardwareIndexBuffer::unlock(void) + { mIsLocked = false; // Nothing to do - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void DefaultHardwareIndexBuffer::readData(size_t offset, size_t length, void* pDest) - { - assert((offset + length) <= mSizeInBytes); - memcpy(pDest, mData + offset, length); - } - //----------------------------------------------------------------------- + { + assert((offset + length) <= mSizeInBytes); + memcpy(pDest, mData + offset, length); + } + //----------------------------------------------------------------------- void DefaultHardwareIndexBuffer::writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer) - { - assert((offset + length) <= mSizeInBytes); - // ignore discard, memory is not guaranteed to be zeroised - memcpy(mData + offset, pSource, length); + bool discardWholeBuffer) + { + assert((offset + length) <= mSizeInBytes); + // ignore discard, memory is not guaranteed to be zeroised + memcpy(mData + offset, pSource, length); - } - //----------------------------------------------------------------------- - DefaultHardwareUniformBuffer::DefaultHardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - : HardwareUniformBuffer(mgr, sizeBytes, usage, useShadowBuffer, name) - { - // Allocate aligned memory for better SIMD processing friendly. + } + //----------------------------------------------------------------------- + DefaultHardwareUniformBuffer::DefaultHardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) + : HardwareUniformBuffer(mgr, sizeBytes, usage, useShadowBuffer, name) + { + // Allocate aligned memory for better SIMD processing friendly. mData = static_cast(OGRE_MALLOC_SIMD(mSizeInBytes, MEMCATEGORY_GEOMETRY)); - } - //----------------------------------------------------------------------- - DefaultHardwareUniformBuffer::~DefaultHardwareUniformBuffer() - { - OGRE_FREE_SIMD(mData, MEMCATEGORY_GEOMETRY); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- + DefaultHardwareUniformBuffer::~DefaultHardwareUniformBuffer() + { + OGRE_FREE_SIMD(mData, MEMCATEGORY_GEOMETRY); + } + //----------------------------------------------------------------------- void* DefaultHardwareUniformBuffer::lockImpl(size_t offset, size_t length, LockOptions options) - { + { // Only for use internally, no 'locking' as such - return mData + offset; - } - //----------------------------------------------------------------------- - void DefaultHardwareUniformBuffer::unlockImpl(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void DefaultHardwareUniformBuffer::unlockImpl(void) + { + // Nothing to do + } + /* + bool DefaultHardwareUniformBuffer::updateStructure(const Any& renderSystemInfo) + { // Nothing to do - } - /* - bool DefaultHardwareUniformBuffer::updateStructure(const Any& renderSystemInfo) - { - // Nothing to do - return true; - } - */ - //----------------------------------------------------------------------- + return true; + } + */ + //----------------------------------------------------------------------- void* DefaultHardwareUniformBuffer::lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt) - { + { mIsLocked = true; - return mData + offset; - } - //----------------------------------------------------------------------- - void DefaultHardwareUniformBuffer::unlock(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void DefaultHardwareUniformBuffer::unlock(void) + { mIsLocked = false; // Nothing to do - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void DefaultHardwareUniformBuffer::readData(size_t offset, size_t length, void* pDest) - { - assert((offset + length) <= mSizeInBytes); - memcpy(pDest, mData + offset, length); - } - //----------------------------------------------------------------------- + { + assert((offset + length) <= mSizeInBytes); + memcpy(pDest, mData + offset, length); + } + //----------------------------------------------------------------------- void DefaultHardwareUniformBuffer::writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer) - { - assert((offset + length) <= mSizeInBytes); - // ignore discard, memory is not guaranteed to be zeroised - memcpy(mData + offset, pSource, length); - } - //----------------------------------------------------------------------- - DefaultHardwareCounterBuffer::DefaultHardwareCounterBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) + bool discardWholeBuffer) + { + assert((offset + length) <= mSizeInBytes); + // ignore discard, memory is not guaranteed to be zeroised + memcpy(mData + offset, pSource, length); + } + //----------------------------------------------------------------------- + DefaultHardwareCounterBuffer::DefaultHardwareCounterBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) : HardwareCounterBuffer(mgr, sizeBytes, usage, useShadowBuffer, name) - { - // Allocate aligned memory for better SIMD processing friendly. + { + // Allocate aligned memory for better SIMD processing friendly. mData = static_cast(OGRE_MALLOC_SIMD(mSizeInBytes, MEMCATEGORY_GEOMETRY)); - } - //----------------------------------------------------------------------- - DefaultHardwareCounterBuffer::~DefaultHardwareCounterBuffer() - { - OGRE_FREE_SIMD(mData, MEMCATEGORY_GEOMETRY); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- + DefaultHardwareCounterBuffer::~DefaultHardwareCounterBuffer() + { + OGRE_FREE_SIMD(mData, MEMCATEGORY_GEOMETRY); + } + //----------------------------------------------------------------------- void* DefaultHardwareCounterBuffer::lockImpl(size_t offset, size_t length, LockOptions options) - { + { // Only for use internally, no 'locking' as such - return mData + offset; - } - //----------------------------------------------------------------------- - void DefaultHardwareCounterBuffer::unlockImpl(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void DefaultHardwareCounterBuffer::unlockImpl(void) + { // Nothing to do - } - /* + } + /* bool DefaultHardwareCounterBuffer::updateStructure(const Any& renderSystemInfo) { // Nothing to do return true; } */ - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void* DefaultHardwareCounterBuffer::lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt) - { + { mIsLocked = true; - return mData + offset; - } - //----------------------------------------------------------------------- - void DefaultHardwareCounterBuffer::unlock(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void DefaultHardwareCounterBuffer::unlock(void) + { mIsLocked = false; // Nothing to do - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void DefaultHardwareCounterBuffer::readData(size_t offset, size_t length, void* pDest) - { - assert((offset + length) <= mSizeInBytes); - memcpy(pDest, mData + offset, length); - } - //----------------------------------------------------------------------- + { + assert((offset + length) <= mSizeInBytes); + memcpy(pDest, mData + offset, length); + } + //----------------------------------------------------------------------- void DefaultHardwareCounterBuffer::writeData(size_t offset, size_t length, const void* pSource, bool discardWholeBuffer) - { - assert((offset + length) <= mSizeInBytes); - // ignore discard, memory is not guaranteed to be zeroised - memcpy(mData + offset, pSource, length); - } - //----------------------------------------------------------------------- + { + assert((offset + length) <= mSizeInBytes); + // ignore discard, memory is not guaranteed to be zeroised + memcpy(mData + offset, pSource, length); + } + //----------------------------------------------------------------------- //----------------------------------------------------------------------- DefaultHardwareBufferManagerBase::DefaultHardwareBufferManagerBase() - { - } + { + } //----------------------------------------------------------------------- DefaultHardwareBufferManagerBase::~DefaultHardwareBufferManagerBase() - { + { destroyAllDeclarations(); destroyAllBindings(); - } + } //----------------------------------------------------------------------- - HardwareVertexBufferSharedPtr + HardwareVertexBufferSharedPtr DefaultHardwareBufferManagerBase::createVertexBuffer(size_t vertexSize, - size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer) - { + size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer) + { DefaultHardwareVertexBuffer* vb = OGRE_NEW DefaultHardwareVertexBuffer(this, vertexSize, numVerts, usage); return HardwareVertexBufferSharedPtr(vb); - } + } //----------------------------------------------------------------------- - HardwareIndexBufferSharedPtr + HardwareIndexBufferSharedPtr DefaultHardwareBufferManagerBase::createIndexBuffer(HardwareIndexBuffer::IndexType itype, - size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer) - { + size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer) + { DefaultHardwareIndexBuffer* ib = OGRE_NEW DefaultHardwareIndexBuffer(itype, numIndexes, usage); - return HardwareIndexBufferSharedPtr(ib); - } - //----------------------------------------------------------------------- - RenderToVertexBufferSharedPtr - DefaultHardwareBufferManagerBase::createRenderToVertexBuffer() - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create RenderToVertexBuffer in DefaultHardwareBufferManagerBase", - "DefaultHardwareBufferManagerBase::createRenderToVertexBuffer"); - } + return HardwareIndexBufferSharedPtr(ib); + } + //----------------------------------------------------------------------- + RenderToVertexBufferSharedPtr + DefaultHardwareBufferManagerBase::createRenderToVertexBuffer() + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create RenderToVertexBuffer in DefaultHardwareBufferManagerBase", + "DefaultHardwareBufferManagerBase::createRenderToVertexBuffer"); + } - HardwareUniformBufferSharedPtr - DefaultHardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, - HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - { - DefaultHardwareUniformBuffer* ub = OGRE_NEW DefaultHardwareUniformBuffer(this, sizeBytes, usage, useShadowBuffer); - return HardwareUniformBufferSharedPtr(ub); - } - HardwareCounterBufferSharedPtr + HardwareUniformBufferSharedPtr + DefaultHardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, + HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) + { + DefaultHardwareUniformBuffer* ub = OGRE_NEW DefaultHardwareUniformBuffer(this, sizeBytes, usage, useShadowBuffer); + return HardwareUniformBufferSharedPtr(ub); + } + HardwareCounterBufferSharedPtr DefaultHardwareBufferManagerBase::createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - { - DefaultHardwareCounterBuffer* ub = OGRE_NEW DefaultHardwareCounterBuffer(this, sizeBytes, usage, useShadowBuffer); - return HardwareCounterBufferSharedPtr(ub); - } + { + DefaultHardwareCounterBuffer* ub = OGRE_NEW DefaultHardwareCounterBuffer(this, sizeBytes, usage, useShadowBuffer); + return HardwareCounterBufferSharedPtr(ub); + } } diff --git a/OgreMain/src/OgreDefaultSceneQueries.cpp b/OgreMain/src/OgreDefaultSceneQueries.cpp index 871b4dc6b06..f4215b6cce1 100644 --- a/OgreMain/src/OgreDefaultSceneQueries.cpp +++ b/OgreMain/src/OgreDefaultSceneQueries.cpp @@ -30,275 +30,275 @@ THE SOFTWARE. #include "OgreRoot.h" namespace Ogre { - //--------------------------------------------------------------------- - DefaultIntersectionSceneQuery::DefaultIntersectionSceneQuery(SceneManager* creator) - : IntersectionSceneQuery(creator) - { - // No world geometry results supported - mSupportedWorldFragments.insert(SceneQuery::WFT_NONE); - } - //--------------------------------------------------------------------- - DefaultIntersectionSceneQuery::~DefaultIntersectionSceneQuery() - { - } - //--------------------------------------------------------------------- - void DefaultIntersectionSceneQuery::execute(IntersectionSceneQueryListener* listener) - { - // Iterate over all movable types - Root::MovableObjectFactoryIterator factIt = - Root::getSingleton().getMovableObjectFactoryIterator(); - while(factIt.hasMoreElements()) - { - SceneManager::MovableObjectIterator objItA = - mParentSceneMgr->getMovableObjectIterator( - factIt.getNext()->getType()); - while (objItA.hasMoreElements()) - { - MovableObject* a = objItA.getNext(); - // skip entire section if type doesn't match - if (!(a->getTypeFlags() & mQueryTypeMask)) - break; + //--------------------------------------------------------------------- + DefaultIntersectionSceneQuery::DefaultIntersectionSceneQuery(SceneManager* creator) + : IntersectionSceneQuery(creator) + { + // No world geometry results supported + mSupportedWorldFragments.insert(SceneQuery::WFT_NONE); + } + //--------------------------------------------------------------------- + DefaultIntersectionSceneQuery::~DefaultIntersectionSceneQuery() + { + } + //--------------------------------------------------------------------- + void DefaultIntersectionSceneQuery::execute(IntersectionSceneQueryListener* listener) + { + // Iterate over all movable types + Root::MovableObjectFactoryIterator factIt = + Root::getSingleton().getMovableObjectFactoryIterator(); + while(factIt.hasMoreElements()) + { + SceneManager::MovableObjectIterator objItA = + mParentSceneMgr->getMovableObjectIterator( + factIt.getNext()->getType()); + while (objItA.hasMoreElements()) + { + MovableObject* a = objItA.getNext(); + // skip entire section if type doesn't match + if (!(a->getTypeFlags() & mQueryTypeMask)) + break; - // Skip if a does not pass the mask - if (!(a->getQueryFlags() & mQueryMask) || - !a->isInScene()) - continue; + // Skip if a does not pass the mask + if (!(a->getQueryFlags() & mQueryMask) || + !a->isInScene()) + continue; - // Check against later objects in the same group - SceneManager::MovableObjectIterator objItB = objItA; - while (objItB.hasMoreElements()) - { - MovableObject* b = objItB.getNext(); + // Check against later objects in the same group + SceneManager::MovableObjectIterator objItB = objItA; + while (objItB.hasMoreElements()) + { + MovableObject* b = objItB.getNext(); - // Apply mask to b (both must pass) - if ((b->getQueryFlags() & mQueryMask) && - b->isInScene()) - { - const AxisAlignedBox& box1 = a->getWorldBoundingBox(); - const AxisAlignedBox& box2 = b->getWorldBoundingBox(); + // Apply mask to b (both must pass) + if ((b->getQueryFlags() & mQueryMask) && + b->isInScene()) + { + const AxisAlignedBox& box1 = a->getWorldBoundingBox(); + const AxisAlignedBox& box2 = b->getWorldBoundingBox(); - if (box1.intersects(box2)) - { - if (!listener->queryResult(a, b)) return; - } - } - } - // Check against later groups - Root::MovableObjectFactoryIterator factItLater = factIt; - while (factItLater.hasMoreElements()) - { - SceneManager::MovableObjectIterator objItC = - mParentSceneMgr->getMovableObjectIterator( - factItLater.getNext()->getType()); - while (objItC.hasMoreElements()) - { - MovableObject* c = objItC.getNext(); - // skip entire section if type doesn't match - if (!(c->getTypeFlags() & mQueryTypeMask)) - break; + if (box1.intersects(box2)) + { + if (!listener->queryResult(a, b)) return; + } + } + } + // Check against later groups + Root::MovableObjectFactoryIterator factItLater = factIt; + while (factItLater.hasMoreElements()) + { + SceneManager::MovableObjectIterator objItC = + mParentSceneMgr->getMovableObjectIterator( + factItLater.getNext()->getType()); + while (objItC.hasMoreElements()) + { + MovableObject* c = objItC.getNext(); + // skip entire section if type doesn't match + if (!(c->getTypeFlags() & mQueryTypeMask)) + break; - // Apply mask to c (both must pass) - if ((c->getQueryFlags() & mQueryMask) && - c->isInScene()) - { - const AxisAlignedBox& box1 = a->getWorldBoundingBox(); - const AxisAlignedBox& box2 = c->getWorldBoundingBox(); + // Apply mask to c (both must pass) + if ((c->getQueryFlags() & mQueryMask) && + c->isInScene()) + { + const AxisAlignedBox& box1 = a->getWorldBoundingBox(); + const AxisAlignedBox& box2 = c->getWorldBoundingBox(); - if (box1.intersects(box2)) - { - if (!listener->queryResult(a, c)) return; - } - } - } + if (box1.intersects(box2)) + { + if (!listener->queryResult(a, c)) return; + } + } + } - } + } - } + } - } + } - } - //--------------------------------------------------------------------- - DefaultAxisAlignedBoxSceneQuery:: - DefaultAxisAlignedBoxSceneQuery(SceneManager* creator) - : AxisAlignedBoxSceneQuery(creator) - { - // No world geometry results supported - mSupportedWorldFragments.insert(SceneQuery::WFT_NONE); - } - //--------------------------------------------------------------------- - DefaultAxisAlignedBoxSceneQuery::~DefaultAxisAlignedBoxSceneQuery() - { - } - //--------------------------------------------------------------------- - void DefaultAxisAlignedBoxSceneQuery::execute(SceneQueryListener* listener) - { - // Iterate over all movable types - Root::MovableObjectFactoryIterator factIt = - Root::getSingleton().getMovableObjectFactoryIterator(); - while(factIt.hasMoreElements()) - { - SceneManager::MovableObjectIterator objItA = - mParentSceneMgr->getMovableObjectIterator( - factIt.getNext()->getType()); - while (objItA.hasMoreElements()) - { - MovableObject* a = objItA.getNext(); - // skip whole group if type doesn't match - if (!(a->getTypeFlags() & mQueryTypeMask)) - break; + } + //--------------------------------------------------------------------- + DefaultAxisAlignedBoxSceneQuery:: + DefaultAxisAlignedBoxSceneQuery(SceneManager* creator) + : AxisAlignedBoxSceneQuery(creator) + { + // No world geometry results supported + mSupportedWorldFragments.insert(SceneQuery::WFT_NONE); + } + //--------------------------------------------------------------------- + DefaultAxisAlignedBoxSceneQuery::~DefaultAxisAlignedBoxSceneQuery() + { + } + //--------------------------------------------------------------------- + void DefaultAxisAlignedBoxSceneQuery::execute(SceneQueryListener* listener) + { + // Iterate over all movable types + Root::MovableObjectFactoryIterator factIt = + Root::getSingleton().getMovableObjectFactoryIterator(); + while(factIt.hasMoreElements()) + { + SceneManager::MovableObjectIterator objItA = + mParentSceneMgr->getMovableObjectIterator( + factIt.getNext()->getType()); + while (objItA.hasMoreElements()) + { + MovableObject* a = objItA.getNext(); + // skip whole group if type doesn't match + if (!(a->getTypeFlags() & mQueryTypeMask)) + break; - if ((a->getQueryFlags() & mQueryMask) && - a->isInScene() && - mAABB.intersects(a->getWorldBoundingBox())) - { - if (!listener->queryResult(a)) return; - } - } - } - } - //--------------------------------------------------------------------- - DefaultRaySceneQuery:: - DefaultRaySceneQuery(SceneManager* creator) : RaySceneQuery(creator) - { - // No world geometry results supported - mSupportedWorldFragments.insert(SceneQuery::WFT_NONE); - } - //--------------------------------------------------------------------- - DefaultRaySceneQuery::~DefaultRaySceneQuery() - { - } - //--------------------------------------------------------------------- - void DefaultRaySceneQuery::execute(RaySceneQueryListener* listener) - { - // Note that because we have no scene partitioning, we actually - // perform a complete scene search even if restricted results are - // requested; smarter scene manager queries can utilise the paritioning - // of the scene in order to reduce the number of intersection tests - // required to fulfil the query + if ((a->getQueryFlags() & mQueryMask) && + a->isInScene() && + mAABB.intersects(a->getWorldBoundingBox())) + { + if (!listener->queryResult(a)) return; + } + } + } + } + //--------------------------------------------------------------------- + DefaultRaySceneQuery:: + DefaultRaySceneQuery(SceneManager* creator) : RaySceneQuery(creator) + { + // No world geometry results supported + mSupportedWorldFragments.insert(SceneQuery::WFT_NONE); + } + //--------------------------------------------------------------------- + DefaultRaySceneQuery::~DefaultRaySceneQuery() + { + } + //--------------------------------------------------------------------- + void DefaultRaySceneQuery::execute(RaySceneQueryListener* listener) + { + // Note that because we have no scene partitioning, we actually + // perform a complete scene search even if restricted results are + // requested; smarter scene manager queries can utilise the paritioning + // of the scene in order to reduce the number of intersection tests + // required to fulfil the query - // Iterate over all movable types - Root::MovableObjectFactoryIterator factIt = - Root::getSingleton().getMovableObjectFactoryIterator(); - while(factIt.hasMoreElements()) - { - SceneManager::MovableObjectIterator objItA = - mParentSceneMgr->getMovableObjectIterator( - factIt.getNext()->getType()); - while (objItA.hasMoreElements()) - { - MovableObject* a = objItA.getNext(); - // skip whole group if type doesn't match - if (!(a->getTypeFlags() & mQueryTypeMask)) - break; + // Iterate over all movable types + Root::MovableObjectFactoryIterator factIt = + Root::getSingleton().getMovableObjectFactoryIterator(); + while(factIt.hasMoreElements()) + { + SceneManager::MovableObjectIterator objItA = + mParentSceneMgr->getMovableObjectIterator( + factIt.getNext()->getType()); + while (objItA.hasMoreElements()) + { + MovableObject* a = objItA.getNext(); + // skip whole group if type doesn't match + if (!(a->getTypeFlags() & mQueryTypeMask)) + break; - if( (a->getQueryFlags() & mQueryMask) && - a->isInScene()) - { - // Do ray / box test - std::pair result = - mRay.intersects(a->getWorldBoundingBox()); + if( (a->getQueryFlags() & mQueryMask) && + a->isInScene()) + { + // Do ray / box test + std::pair result = + mRay.intersects(a->getWorldBoundingBox()); - if (result.first) - { - if (!listener->queryResult(a, result.second)) return; - } - } - } - } + if (result.first) + { + if (!listener->queryResult(a, result.second)) return; + } + } + } + } - } - //--------------------------------------------------------------------- - DefaultSphereSceneQuery:: - DefaultSphereSceneQuery(SceneManager* creator) : SphereSceneQuery(creator) - { - // No world geometry results supported - mSupportedWorldFragments.insert(SceneQuery::WFT_NONE); - } - //--------------------------------------------------------------------- - DefaultSphereSceneQuery::~DefaultSphereSceneQuery() - { - } - //--------------------------------------------------------------------- - void DefaultSphereSceneQuery::execute(SceneQueryListener* listener) - { - Sphere testSphere; + } + //--------------------------------------------------------------------- + DefaultSphereSceneQuery:: + DefaultSphereSceneQuery(SceneManager* creator) : SphereSceneQuery(creator) + { + // No world geometry results supported + mSupportedWorldFragments.insert(SceneQuery::WFT_NONE); + } + //--------------------------------------------------------------------- + DefaultSphereSceneQuery::~DefaultSphereSceneQuery() + { + } + //--------------------------------------------------------------------- + void DefaultSphereSceneQuery::execute(SceneQueryListener* listener) + { + Sphere testSphere; - // Iterate over all movable types - Root::MovableObjectFactoryIterator factIt = - Root::getSingleton().getMovableObjectFactoryIterator(); - while(factIt.hasMoreElements()) - { - SceneManager::MovableObjectIterator objItA = - mParentSceneMgr->getMovableObjectIterator( - factIt.getNext()->getType()); - while (objItA.hasMoreElements()) - { - MovableObject* a = objItA.getNext(); - // skip whole group if type doesn't match - if (!(a->getTypeFlags() & mQueryTypeMask)) - break; - // Skip unattached - if (!a->isInScene() || - !(a->getQueryFlags() & mQueryMask)) - continue; + // Iterate over all movable types + Root::MovableObjectFactoryIterator factIt = + Root::getSingleton().getMovableObjectFactoryIterator(); + while(factIt.hasMoreElements()) + { + SceneManager::MovableObjectIterator objItA = + mParentSceneMgr->getMovableObjectIterator( + factIt.getNext()->getType()); + while (objItA.hasMoreElements()) + { + MovableObject* a = objItA.getNext(); + // skip whole group if type doesn't match + if (!(a->getTypeFlags() & mQueryTypeMask)) + break; + // Skip unattached + if (!a->isInScene() || + !(a->getQueryFlags() & mQueryMask)) + continue; - // Do sphere / sphere test - testSphere.setCenter(a->getParentNode()->_getDerivedPosition()); - testSphere.setRadius(a->getBoundingRadius()); - if (mSphere.intersects(testSphere)) - { - if (!listener->queryResult(a)) return; - } - } - } - } - //--------------------------------------------------------------------- - DefaultPlaneBoundedVolumeListSceneQuery:: - DefaultPlaneBoundedVolumeListSceneQuery(SceneManager* creator) - : PlaneBoundedVolumeListSceneQuery(creator) - { - // No world geometry results supported - mSupportedWorldFragments.insert(SceneQuery::WFT_NONE); - } - //--------------------------------------------------------------------- - DefaultPlaneBoundedVolumeListSceneQuery::~DefaultPlaneBoundedVolumeListSceneQuery() - { - } - //--------------------------------------------------------------------- - void DefaultPlaneBoundedVolumeListSceneQuery::execute(SceneQueryListener* listener) - { - // Iterate over all movable types - Root::MovableObjectFactoryIterator factIt = - Root::getSingleton().getMovableObjectFactoryIterator(); - while(factIt.hasMoreElements()) - { - SceneManager::MovableObjectIterator objItA = - mParentSceneMgr->getMovableObjectIterator( - factIt.getNext()->getType()); - while (objItA.hasMoreElements()) - { - MovableObject* a = objItA.getNext(); - // skip whole group if type doesn't match - if (!(a->getTypeFlags() & mQueryTypeMask)) - break; + // Do sphere / sphere test + testSphere.setCenter(a->getParentNode()->_getDerivedPosition()); + testSphere.setRadius(a->getBoundingRadius()); + if (mSphere.intersects(testSphere)) + { + if (!listener->queryResult(a)) return; + } + } + } + } + //--------------------------------------------------------------------- + DefaultPlaneBoundedVolumeListSceneQuery:: + DefaultPlaneBoundedVolumeListSceneQuery(SceneManager* creator) + : PlaneBoundedVolumeListSceneQuery(creator) + { + // No world geometry results supported + mSupportedWorldFragments.insert(SceneQuery::WFT_NONE); + } + //--------------------------------------------------------------------- + DefaultPlaneBoundedVolumeListSceneQuery::~DefaultPlaneBoundedVolumeListSceneQuery() + { + } + //--------------------------------------------------------------------- + void DefaultPlaneBoundedVolumeListSceneQuery::execute(SceneQueryListener* listener) + { + // Iterate over all movable types + Root::MovableObjectFactoryIterator factIt = + Root::getSingleton().getMovableObjectFactoryIterator(); + while(factIt.hasMoreElements()) + { + SceneManager::MovableObjectIterator objItA = + mParentSceneMgr->getMovableObjectIterator( + factIt.getNext()->getType()); + while (objItA.hasMoreElements()) + { + MovableObject* a = objItA.getNext(); + // skip whole group if type doesn't match + if (!(a->getTypeFlags() & mQueryTypeMask)) + break; - PlaneBoundedVolumeList::iterator pi, piend; - piend = mVolumes.end(); - for (pi = mVolumes.begin(); pi != piend; ++pi) - { - PlaneBoundedVolume& vol = *pi; - // Do AABB / plane volume test - if ((a->getQueryFlags() & mQueryMask) && - a->isInScene() && - vol.intersects(a->getWorldBoundingBox())) - { - if (!listener->queryResult(a)) return; - break; - } - } - } - } - } + PlaneBoundedVolumeList::iterator pi, piend; + piend = mVolumes.end(); + for (pi = mVolumes.begin(); pi != piend; ++pi) + { + PlaneBoundedVolume& vol = *pi; + // Do AABB / plane volume test + if ((a->getQueryFlags() & mQueryMask) && + a->isInScene() && + vol.intersects(a->getWorldBoundingBox())) + { + if (!listener->queryResult(a)) return; + break; + } + } + } + } + } } diff --git a/OgreMain/src/OgreDeflate.cpp b/OgreMain/src/OgreDeflate.cpp index ba5eeeab066..fd81c3df559 100644 --- a/OgreMain/src/OgreDeflate.cpp +++ b/OgreMain/src/OgreDeflate.cpp @@ -39,106 +39,106 @@ namespace Ogre { - // memory implementations - void* OgreZalloc(void* opaque, unsigned int items, unsigned int size) - { - return OGRE_MALLOC(items * size, MEMCATEGORY_GENERAL); - } - void OgreZfree(void* opaque, void* address) - { - OGRE_FREE(address, MEMCATEGORY_GENERAL); - } - #define OGRE_DEFLATE_TMP_SIZE 16384 + // memory implementations + void* OgreZalloc(void* opaque, unsigned int items, unsigned int size) + { + return OGRE_MALLOC(items * size, MEMCATEGORY_GENERAL); + } + void OgreZfree(void* opaque, void* address) + { + OGRE_FREE(address, MEMCATEGORY_GENERAL); + } + #define OGRE_DEFLATE_TMP_SIZE 16384 //--------------------------------------------------------------------- - DeflateStream::DeflateStream(const DataStreamPtr& compressedStream, const String& tmpFileName, size_t avail_in) - : DataStream(compressedStream->getAccessMode()) - , mCompressedStream(compressedStream) + DeflateStream::DeflateStream(const DataStreamPtr& compressedStream, const String& tmpFileName, size_t avail_in) + : DataStream(compressedStream->getAccessMode()) + , mCompressedStream(compressedStream) , mTempFileName(tmpFileName) - , mZStream(0) - , mCurrentPos(0) - , mAvailIn(avail_in) - , mTmp(0) - , mIsCompressedValid(true) - { - init(); - } + , mZStream(0) + , mCurrentPos(0) + , mAvailIn(avail_in) + , mTmp(0) + , mIsCompressedValid(true) + { + init(); + } //--------------------------------------------------------------------- - DeflateStream::DeflateStream(const String& name, const DataStreamPtr& compressedStream, const String& tmpFileName, size_t avail_in) - : DataStream(name, compressedStream->getAccessMode()) - , mCompressedStream(compressedStream) + DeflateStream::DeflateStream(const String& name, const DataStreamPtr& compressedStream, const String& tmpFileName, size_t avail_in) + : DataStream(name, compressedStream->getAccessMode()) + , mCompressedStream(compressedStream) , mTempFileName(tmpFileName) - , mZStream(0) - , mCurrentPos(0) - , mAvailIn(avail_in) - , mTmp(0) - , mIsCompressedValid(true) - { - init(); - } + , mZStream(0) + , mCurrentPos(0) + , mAvailIn(avail_in) + , mTmp(0) + , mIsCompressedValid(true) + { + init(); + } //--------------------------------------------------------------------- - size_t DeflateStream::getAvailInForSinglePass() - { - size_t ret = OGRE_DEFLATE_TMP_SIZE; + size_t DeflateStream::getAvailInForSinglePass() + { + size_t ret = OGRE_DEFLATE_TMP_SIZE; - // if we are doing particial-uncompressing - if(mAvailIn>0) - { - if(mAvailIn0) + { + if(mAvailInzalloc = OgreZalloc; - mZStream->zfree = OgreZfree; - - if (getAccessMode() == READ) - { - mTmp = (unsigned char*)OGRE_MALLOC(OGRE_DEFLATE_TMP_SIZE, MEMCATEGORY_GENERAL); - size_t restorePoint = mCompressedStream->tell(); - // read early chunk - mZStream->next_in = mTmp; - mZStream->avail_in = static_cast(mCompressedStream->read(mTmp, getAvailInForSinglePass())); - - if (inflateInit(mZStream) != Z_OK) - { - mIsCompressedValid = false; - } - else - mIsCompressedValid = true; - - if (mIsCompressedValid) - { - // in fact, inflateInit on some implementations doesn't try to read - // anything. We need to at least read something to test - Bytef testOut[4]; - size_t savedIn = mZStream->avail_in; - mZStream->avail_out = 4; - mZStream->next_out = testOut; - if (inflate(mZStream, Z_SYNC_FLUSH) != Z_OK) - mIsCompressedValid = false; - // restore for reading - mZStream->avail_in = static_cast(savedIn); - mZStream->next_in = mTmp; + void DeflateStream::init() + { + mZStream = OGRE_ALLOC_T(z_stream, 1, MEMCATEGORY_GENERAL); + mZStream->zalloc = OgreZalloc; + mZStream->zfree = OgreZfree; + + if (getAccessMode() == READ) + { + mTmp = (unsigned char*)OGRE_MALLOC(OGRE_DEFLATE_TMP_SIZE, MEMCATEGORY_GENERAL); + size_t restorePoint = mCompressedStream->tell(); + // read early chunk + mZStream->next_in = mTmp; + mZStream->avail_in = static_cast(mCompressedStream->read(mTmp, getAvailInForSinglePass())); + + if (inflateInit(mZStream) != Z_OK) + { + mIsCompressedValid = false; + } + else + mIsCompressedValid = true; + + if (mIsCompressedValid) + { + // in fact, inflateInit on some implementations doesn't try to read + // anything. We need to at least read something to test + Bytef testOut[4]; + size_t savedIn = mZStream->avail_in; + mZStream->avail_out = 4; + mZStream->next_out = testOut; + if (inflate(mZStream, Z_SYNC_FLUSH) != Z_OK) + mIsCompressedValid = false; + // restore for reading + mZStream->avail_in = static_cast(savedIn); + mZStream->next_in = mTmp; - inflateReset(mZStream); - } + inflateReset(mZStream); + } - if (!mIsCompressedValid) - { - // Not compressed data! - // Fail gracefully, fall back on reading the underlying stream direct - destroy(); - mCompressedStream->seek(restorePoint); - } - } - else - { + if (!mIsCompressedValid) + { + // Not compressed data! + // Fail gracefully, fall back on reading the underlying stream direct + destroy(); + mCompressedStream->seek(restorePoint); + } + } + else + { if(mTempFileName.empty()) { // Write to temp file @@ -165,283 +165,283 @@ namespace Ogre #endif } - std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); - f->open(mTempFileName.c_str(), std::ios::binary | std::ios::out); - mTmpWriteStream = DataStreamPtr(OGRE_NEW FileStreamDataStream(f)); - - } + std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); + f->open(mTempFileName.c_str(), std::ios::binary | std::ios::out); + mTmpWriteStream = DataStreamPtr(OGRE_NEW FileStreamDataStream(f)); + + } - } + } //--------------------------------------------------------------------- - void DeflateStream::destroy() - { - if (getAccessMode() == READ) - inflateEnd(mZStream); + void DeflateStream::destroy() + { + if (getAccessMode() == READ) + inflateEnd(mZStream); - OGRE_FREE(mZStream, MEMCATEGORY_GENERAL); - mZStream = 0; - OGRE_FREE(mTmp, MEMCATEGORY_GENERAL); - mTmp = 0; - } - //--------------------------------------------------------------------- - DeflateStream::~DeflateStream() - { - close(); - destroy(); - } + OGRE_FREE(mZStream, MEMCATEGORY_GENERAL); + mZStream = 0; + OGRE_FREE(mTmp, MEMCATEGORY_GENERAL); + mTmp = 0; + } + //--------------------------------------------------------------------- + DeflateStream::~DeflateStream() + { + close(); + destroy(); + } //--------------------------------------------------------------------- - size_t DeflateStream::read(void* buf, size_t count) - { - if (!mIsCompressedValid) - { - return mCompressedStream->read(buf, count); - } - - if (getAccessMode() & WRITE) - { - return mTmpWriteStream->read(buf, count); - } - else - { + size_t DeflateStream::read(void* buf, size_t count) + { + if (!mIsCompressedValid) + { + return mCompressedStream->read(buf, count); + } + + if (getAccessMode() & WRITE) + { + return mTmpWriteStream->read(buf, count); + } + else + { - size_t restorePoint = mCompressedStream->tell(); - // read from cache first - size_t cachereads = mReadCache.read(buf, count); - - size_t newReadUncompressed = 0; + size_t restorePoint = mCompressedStream->tell(); + // read from cache first + size_t cachereads = mReadCache.read(buf, count); + + size_t newReadUncompressed = 0; - if (cachereads < count) - { - mZStream->avail_out = static_cast(count - cachereads); - mZStream->next_out = (Bytef*)buf + cachereads; - - while (mZStream->avail_out) - { - // Pull next chunk of compressed data from the underlying stream - if (!mZStream->avail_in && !mCompressedStream->eof()) - { - mZStream->avail_in = static_cast(mCompressedStream->read(mTmp, getAvailInForSinglePass())); - mZStream->next_in = mTmp; - } - - if (mZStream->avail_in) - { - int availpre = mZStream->avail_out; - int status = inflate(mZStream, Z_SYNC_FLUSH); - size_t readUncompressed = availpre - mZStream->avail_out; - newReadUncompressed += readUncompressed; - if (status != Z_OK) - { - // End of data, or error - if (status != Z_STREAM_END) - { - mCompressedStream->seek(restorePoint); - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Error in compressed stream", - "DeflateStrea::read"); - } - else - { - // back up the stream so that it can be used from the end onwards - long unusedCompressed = mZStream->avail_in; - mCompressedStream->skip(-unusedCompressed); - } + if (cachereads < count) + { + mZStream->avail_out = static_cast(count - cachereads); + mZStream->next_out = (Bytef*)buf + cachereads; + + while (mZStream->avail_out) + { + // Pull next chunk of compressed data from the underlying stream + if (!mZStream->avail_in && !mCompressedStream->eof()) + { + mZStream->avail_in = static_cast(mCompressedStream->read(mTmp, getAvailInForSinglePass())); + mZStream->next_in = mTmp; + } + + if (mZStream->avail_in) + { + int availpre = mZStream->avail_out; + int status = inflate(mZStream, Z_SYNC_FLUSH); + size_t readUncompressed = availpre - mZStream->avail_out; + newReadUncompressed += readUncompressed; + if (status != Z_OK) + { + // End of data, or error + if (status != Z_STREAM_END) + { + mCompressedStream->seek(restorePoint); + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Error in compressed stream", + "DeflateStrea::read"); + } + else + { + // back up the stream so that it can be used from the end onwards + long unusedCompressed = mZStream->avail_in; + mCompressedStream->skip(-unusedCompressed); + } - break; - } - } - } - } - - // Cache the last bytes read - mReadCache.cacheData((char*)buf + cachereads, newReadUncompressed); - - mCurrentPos += newReadUncompressed + cachereads; - - return newReadUncompressed + cachereads; - } - } + break; + } + } + } + } + + // Cache the last bytes read + mReadCache.cacheData((char*)buf + cachereads, newReadUncompressed); + + mCurrentPos += newReadUncompressed + cachereads; + + return newReadUncompressed + cachereads; + } + } //--------------------------------------------------------------------- - size_t DeflateStream::write(const void* buf, size_t count) - { - if ((getAccessMode() & WRITE) == 0) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Not a writable stream", "DeflateStream::write"); - - return mTmpWriteStream->write(buf, count); - } + size_t DeflateStream::write(const void* buf, size_t count) + { + if ((getAccessMode() & WRITE) == 0) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Not a writable stream", "DeflateStream::write"); + + return mTmpWriteStream->write(buf, count); + } //--------------------------------------------------------------------- - void DeflateStream::compressFinal() - { - // Close temp stream - mTmpWriteStream->close(); - - // Copy & compress - // We do this rather than compress directly because some code seeks - // around while writing (e.g. to update size blocks) which is not - // possible when compressing on the fly - - int ret, flush; - char in[OGRE_DEFLATE_TMP_SIZE]; - char out[OGRE_DEFLATE_TMP_SIZE]; - - if (deflateInit(mZStream, Z_DEFAULT_COMPRESSION) != Z_OK) - { - destroy(); - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Error initialising deflate compressed stream!", - "DeflateStream::init"); - } - - std::ifstream inFile; - inFile.open(mTempFileName.c_str(), std::ios::in | std::ios::binary); - - do - { - inFile.read(in, OGRE_DEFLATE_TMP_SIZE); - mZStream->avail_in = (uInt)inFile.gcount(); - if (inFile.bad()) - { - deflateEnd(mZStream); - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Error reading temp uncompressed stream!", - "DeflateStream::init"); - } - flush = inFile.eof() ? Z_FINISH : Z_NO_FLUSH; - mZStream->next_in = (Bytef*)in; - - /* run deflate() on input until output buffer not full, finish - compression if all of source has been read in */ - do - { - mZStream->avail_out = OGRE_DEFLATE_TMP_SIZE; - mZStream->next_out = (Bytef*)out; - ret = deflate(mZStream, flush); /* no bad return value */ - assert(ret != Z_STREAM_ERROR); /* state not clobbered */ - size_t compressed = OGRE_DEFLATE_TMP_SIZE - mZStream->avail_out; - mCompressedStream->write(out, compressed); - } while (mZStream->avail_out == 0); - assert(mZStream->avail_in == 0); /* all input will be used */ - - /* done when last data in file processed */ - } while (flush != Z_FINISH); - assert(ret == Z_STREAM_END); /* stream will be complete */ + void DeflateStream::compressFinal() + { + // Close temp stream + mTmpWriteStream->close(); + + // Copy & compress + // We do this rather than compress directly because some code seeks + // around while writing (e.g. to update size blocks) which is not + // possible when compressing on the fly + + int ret, flush; + char in[OGRE_DEFLATE_TMP_SIZE]; + char out[OGRE_DEFLATE_TMP_SIZE]; + + if (deflateInit(mZStream, Z_DEFAULT_COMPRESSION) != Z_OK) + { + destroy(); + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Error initialising deflate compressed stream!", + "DeflateStream::init"); + } + + std::ifstream inFile; + inFile.open(mTempFileName.c_str(), std::ios::in | std::ios::binary); + + do + { + inFile.read(in, OGRE_DEFLATE_TMP_SIZE); + mZStream->avail_in = (uInt)inFile.gcount(); + if (inFile.bad()) + { + deflateEnd(mZStream); + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Error reading temp uncompressed stream!", + "DeflateStream::init"); + } + flush = inFile.eof() ? Z_FINISH : Z_NO_FLUSH; + mZStream->next_in = (Bytef*)in; + + /* run deflate() on input until output buffer not full, finish + compression if all of source has been read in */ + do + { + mZStream->avail_out = OGRE_DEFLATE_TMP_SIZE; + mZStream->next_out = (Bytef*)out; + ret = deflate(mZStream, flush); /* no bad return value */ + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + size_t compressed = OGRE_DEFLATE_TMP_SIZE - mZStream->avail_out; + mCompressedStream->write(out, compressed); + } while (mZStream->avail_out == 0); + assert(mZStream->avail_in == 0); /* all input will be used */ + + /* done when last data in file processed */ + } while (flush != Z_FINISH); + assert(ret == Z_STREAM_END); /* stream will be complete */ (void)ret; - deflateEnd(mZStream); + deflateEnd(mZStream); inFile.close(); - remove(mTempFileName.c_str()); - - } + remove(mTempFileName.c_str()); + + } //--------------------------------------------------------------------- - void DeflateStream::skip(long count) - { - if (!mIsCompressedValid) - { - mCompressedStream->skip(count); - return; - } - - if (getAccessMode() & WRITE) - { - mTmpWriteStream->skip(count); - } - else - { - if (count > 0) - { - if (!mReadCache.ff(count)) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "You can only skip within the cache range in a deflate stream.", - "DeflateStream::skip"); - } - } - else if (count < 0) - { - if (!mReadCache.rewind((size_t)(-count))) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "You can only skip within the cache range in a deflate stream.", - "DeflateStream::skip"); - } - } - } - mCurrentPos = static_cast(static_cast(mCurrentPos) + count); - - - } + void DeflateStream::skip(long count) + { + if (!mIsCompressedValid) + { + mCompressedStream->skip(count); + return; + } + + if (getAccessMode() & WRITE) + { + mTmpWriteStream->skip(count); + } + else + { + if (count > 0) + { + if (!mReadCache.ff(count)) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "You can only skip within the cache range in a deflate stream.", + "DeflateStream::skip"); + } + } + else if (count < 0) + { + if (!mReadCache.rewind((size_t)(-count))) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "You can only skip within the cache range in a deflate stream.", + "DeflateStream::skip"); + } + } + } + mCurrentPos = static_cast(static_cast(mCurrentPos) + count); + + + } //--------------------------------------------------------------------- - void DeflateStream::seek( size_t pos ) - { - if (!mIsCompressedValid) - { - mCompressedStream->seek(pos); - return; - } - if (getAccessMode() & WRITE) - { - mTmpWriteStream->seek(pos); - } - else - { - if (pos == 0) - { - mCurrentPos = 0; - mZStream->next_in = mTmp; - mCompressedStream->seek(0); - mZStream->avail_in = static_cast(mCompressedStream->read(mTmp, getAvailInForSinglePass())); - inflateReset(mZStream); - } - else - { - skip(pos - tell()); - } - } - } + void DeflateStream::seek( size_t pos ) + { + if (!mIsCompressedValid) + { + mCompressedStream->seek(pos); + return; + } + if (getAccessMode() & WRITE) + { + mTmpWriteStream->seek(pos); + } + else + { + if (pos == 0) + { + mCurrentPos = 0; + mZStream->next_in = mTmp; + mCompressedStream->seek(0); + mZStream->avail_in = static_cast(mCompressedStream->read(mTmp, getAvailInForSinglePass())); + inflateReset(mZStream); + } + else + { + skip(pos - tell()); + } + } + } //--------------------------------------------------------------------- - size_t DeflateStream::tell(void) const - { - if (!mIsCompressedValid) - { - return mCompressedStream->tell(); - } - else if(getAccessMode() & WRITE) - { - return mTmpWriteStream->tell(); - } - else - { - return mCurrentPos; - } + size_t DeflateStream::tell(void) const + { + if (!mIsCompressedValid) + { + return mCompressedStream->tell(); + } + else if(getAccessMode() & WRITE) + { + return mTmpWriteStream->tell(); + } + else + { + return mCurrentPos; + } - } + } //--------------------------------------------------------------------- - bool DeflateStream::eof(void) const - { - if (getAccessMode() & WRITE) - return mTmpWriteStream->eof(); - else - { - if (!mIsCompressedValid) - return mCompressedStream->eof(); - else - return mCompressedStream->eof() && mZStream->avail_in == 0; - } - } + bool DeflateStream::eof(void) const + { + if (getAccessMode() & WRITE) + return mTmpWriteStream->eof(); + else + { + if (!mIsCompressedValid) + return mCompressedStream->eof(); + else + return mCompressedStream->eof() && mZStream->avail_in == 0; + } + } //--------------------------------------------------------------------- - void DeflateStream::close(void) - { - if (getAccessMode() & WRITE) - { - compressFinal(); - } - - // don't close underlying compressed stream in case used for something else - } + void DeflateStream::close(void) + { + if (getAccessMode() & WRITE) + { + compressFinal(); + } + + // don't close underlying compressed stream in case used for something else + } //--------------------------------------------------------------------- - - + + } #endif diff --git a/OgreMain/src/OgreDepthBuffer.cpp b/OgreMain/src/OgreDepthBuffer.cpp index 2572d421a0a..ffca80798ae 100644 --- a/OgreMain/src/OgreDepthBuffer.cpp +++ b/OgreMain/src/OgreDepthBuffer.cpp @@ -31,106 +31,106 @@ THE SOFTWARE. namespace Ogre { - DepthBuffer::DepthBuffer( uint16 poolId, uint16 bitDepth, uint32 width, uint32 height, - uint32 fsaa, const String &fsaaHint, bool manual ) : - mPoolId(poolId), - mBitDepth(bitDepth), - mWidth(width), - mHeight(height), - mFsaa(fsaa), - mFsaaHint(fsaaHint), - mManual(manual) - { - } + DepthBuffer::DepthBuffer( uint16 poolId, uint16 bitDepth, uint32 width, uint32 height, + uint32 fsaa, const String &fsaaHint, bool manual ) : + mPoolId(poolId), + mBitDepth(bitDepth), + mWidth(width), + mHeight(height), + mFsaa(fsaa), + mFsaaHint(fsaaHint), + mManual(manual) + { + } - DepthBuffer::~DepthBuffer() - { - detachFromAllRenderTargets(); - } + DepthBuffer::~DepthBuffer() + { + detachFromAllRenderTargets(); + } - void DepthBuffer::_setPoolId( uint16 poolId ) - { - //Change the pool Id - mPoolId = poolId; + void DepthBuffer::_setPoolId( uint16 poolId ) + { + //Change the pool Id + mPoolId = poolId; - //Render Targets were attached to us, but they have a different pool Id, - //so detach ourselves from them - detachFromAllRenderTargets(); - } - //----------------------------------------------------------------------- - uint16 DepthBuffer::getPoolId() const - { - return mPoolId; - } - //----------------------------------------------------------------------- - uint16 DepthBuffer::getBitDepth() const - { - return mBitDepth; - } - //----------------------------------------------------------------------- - uint32 DepthBuffer::getWidth() const - { - return mWidth; - } - //---------------------------------------------------------------------- - uint32 DepthBuffer::getHeight() const - { - return mHeight; - } - //----------------------------------------------------------------------- - uint32 DepthBuffer::getFsaa() const - { - return mFsaa; - } - //----------------------------------------------------------------------- - const String& DepthBuffer::getFsaaHint() const - { - return mFsaaHint; - } - //----------------------------------------------------------------------- - bool DepthBuffer::isManual() const - { - return mManual; - } - //----------------------------------------------------------------------- - bool DepthBuffer::isCompatible( RenderTarget *renderTarget ) const - { - if( this->getWidth() >= renderTarget->getWidth() && - this->getHeight() >= renderTarget->getHeight() && - this->getFsaa() == renderTarget->getFSAA() ) - { - return true; - } + //Render Targets were attached to us, but they have a different pool Id, + //so detach ourselves from them + detachFromAllRenderTargets(); + } + //----------------------------------------------------------------------- + uint16 DepthBuffer::getPoolId() const + { + return mPoolId; + } + //----------------------------------------------------------------------- + uint16 DepthBuffer::getBitDepth() const + { + return mBitDepth; + } + //----------------------------------------------------------------------- + uint32 DepthBuffer::getWidth() const + { + return mWidth; + } + //---------------------------------------------------------------------- + uint32 DepthBuffer::getHeight() const + { + return mHeight; + } + //----------------------------------------------------------------------- + uint32 DepthBuffer::getFsaa() const + { + return mFsaa; + } + //----------------------------------------------------------------------- + const String& DepthBuffer::getFsaaHint() const + { + return mFsaaHint; + } + //----------------------------------------------------------------------- + bool DepthBuffer::isManual() const + { + return mManual; + } + //----------------------------------------------------------------------- + bool DepthBuffer::isCompatible( RenderTarget *renderTarget ) const + { + if( this->getWidth() >= renderTarget->getWidth() && + this->getHeight() >= renderTarget->getHeight() && + this->getFsaa() == renderTarget->getFSAA() ) + { + return true; + } - return false; - } - //----------------------------------------------------------------------- - void DepthBuffer::_notifyRenderTargetAttached( RenderTarget *renderTarget ) - { - assert( mAttachedRenderTargets.find( renderTarget ) == mAttachedRenderTargets.end() ); + return false; + } + //----------------------------------------------------------------------- + void DepthBuffer::_notifyRenderTargetAttached( RenderTarget *renderTarget ) + { + assert( mAttachedRenderTargets.find( renderTarget ) == mAttachedRenderTargets.end() ); - mAttachedRenderTargets.insert( renderTarget ); - } - //----------------------------------------------------------------------- - void DepthBuffer::_notifyRenderTargetDetached( RenderTarget *renderTarget ) - { - RenderTargetSet::iterator itor = mAttachedRenderTargets.find( renderTarget ); - assert( itor != mAttachedRenderTargets.end() ); + mAttachedRenderTargets.insert( renderTarget ); + } + //----------------------------------------------------------------------- + void DepthBuffer::_notifyRenderTargetDetached( RenderTarget *renderTarget ) + { + RenderTargetSet::iterator itor = mAttachedRenderTargets.find( renderTarget ); + assert( itor != mAttachedRenderTargets.end() ); - mAttachedRenderTargets.erase( itor ); - } - //----------------------------------------------------------------------- - void DepthBuffer::detachFromAllRenderTargets() - { - RenderTargetSet::const_iterator itor = mAttachedRenderTargets.begin(); - RenderTargetSet::const_iterator end = mAttachedRenderTargets.end(); - while( itor != end ) - { - //If we call, detachDepthBuffer, we'll invalidate the iterators - (*itor)->_detachDepthBuffer(); - ++itor; - } + mAttachedRenderTargets.erase( itor ); + } + //----------------------------------------------------------------------- + void DepthBuffer::detachFromAllRenderTargets() + { + RenderTargetSet::const_iterator itor = mAttachedRenderTargets.begin(); + RenderTargetSet::const_iterator end = mAttachedRenderTargets.end(); + while( itor != end ) + { + //If we call, detachDepthBuffer, we'll invalidate the iterators + (*itor)->_detachDepthBuffer(); + ++itor; + } - mAttachedRenderTargets.clear(); - } + mAttachedRenderTargets.clear(); + } } diff --git a/OgreMain/src/OgreDualQuaternion.cpp b/OgreMain/src/OgreDualQuaternion.cpp index 7ddb2f8169d..1c39dad2bec 100644 --- a/OgreMain/src/OgreDualQuaternion.cpp +++ b/OgreMain/src/OgreDualQuaternion.cpp @@ -63,60 +63,60 @@ THE SOFTWARE. namespace Ogre { - //Based on dqconv.c from http://isg.cs.tcd.ie/projects/DualQuaternions/ - //----------------------------------------------------------------------- - void DualQuaternion::fromRotationTranslation (const Quaternion& q, const Vector3& trans) - { - // non-dual part (just copy the quaternion): - w = q.w; - x = q.x; - y = q.y; - z = q.z; - - // dual part: - Real half = 0.5; - dw = -half * (trans.x * x + trans.y * y + trans.z * z ); - dx = half * (trans.x * w + trans.y * z - trans.z * y ); - dy = half * (-trans.x * z + trans.y * w + trans.z * x ); - dz = half * (trans.x * y - trans.y * x + trans.z * w ); - } - - //Based on dqconv.c from http://isg.cs.tcd.ie/projects/DualQuaternions/ - //----------------------------------------------------------------------- - void DualQuaternion::toRotationTranslation (Quaternion& q, Vector3& translation) const - { - // regular quaternion (just copy the non-dual part): - q.w = w; - q.x = x; - q.y = y; - q.z = z; - - // translation vector: - Real doub = 2.0; - translation.x = doub * (-dw*x + dx*w - dy*z + dz*y); - translation.y = doub * (-dw*y + dx*z + dy*w - dz*x); - translation.z = doub * (-dw*z - dx*y + dy*x + dz*w); - } - - //----------------------------------------------------------------------- - void DualQuaternion::fromTransformationMatrix (const Matrix4& kTrans) - { - Vector3 pos; - Vector3 scale; - Quaternion rot; - - kTrans.decomposition(pos, scale, rot); - fromRotationTranslation(rot, pos); - } - - //----------------------------------------------------------------------- - void DualQuaternion::toTransformationMatrix (Matrix4& kTrans) const - { - Vector3 pos; - Quaternion rot; - toRotationTranslation(rot, pos); - - Vector3 scale = Vector3::UNIT_SCALE; - kTrans.makeTransform(pos, scale, rot); - } + //Based on dqconv.c from http://isg.cs.tcd.ie/projects/DualQuaternions/ + //----------------------------------------------------------------------- + void DualQuaternion::fromRotationTranslation (const Quaternion& q, const Vector3& trans) + { + // non-dual part (just copy the quaternion): + w = q.w; + x = q.x; + y = q.y; + z = q.z; + + // dual part: + Real half = 0.5; + dw = -half * (trans.x * x + trans.y * y + trans.z * z ); + dx = half * (trans.x * w + trans.y * z - trans.z * y ); + dy = half * (-trans.x * z + trans.y * w + trans.z * x ); + dz = half * (trans.x * y - trans.y * x + trans.z * w ); + } + + //Based on dqconv.c from http://isg.cs.tcd.ie/projects/DualQuaternions/ + //----------------------------------------------------------------------- + void DualQuaternion::toRotationTranslation (Quaternion& q, Vector3& translation) const + { + // regular quaternion (just copy the non-dual part): + q.w = w; + q.x = x; + q.y = y; + q.z = z; + + // translation vector: + Real doub = 2.0; + translation.x = doub * (-dw*x + dx*w - dy*z + dz*y); + translation.y = doub * (-dw*y + dx*z + dy*w - dz*x); + translation.z = doub * (-dw*z - dx*y + dy*x + dz*w); + } + + //----------------------------------------------------------------------- + void DualQuaternion::fromTransformationMatrix (const Matrix4& kTrans) + { + Vector3 pos; + Vector3 scale; + Quaternion rot; + + kTrans.decomposition(pos, scale, rot); + fromRotationTranslation(rot, pos); + } + + //----------------------------------------------------------------------- + void DualQuaternion::toTransformationMatrix (Matrix4& kTrans) const + { + Vector3 pos; + Quaternion rot; + toRotationTranslation(rot, pos); + + Vector3 scale = Vector3::UNIT_SCALE; + kTrans.makeTransform(pos, scale, rot); + } } \ No newline at end of file diff --git a/OgreMain/src/OgreDynLib.cpp b/OgreMain/src/OgreDynLib.cpp index 4d161ac47c6..42f62c09f02 100644 --- a/OgreMain/src/OgreDynLib.cpp +++ b/OgreMain/src/OgreDynLib.cpp @@ -35,7 +35,7 @@ THE SOFTWARE. #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT # define WIN32_LEAN_AND_MEAN # if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif # include #endif @@ -72,7 +72,7 @@ namespace Ogre { // Log library load LogManager::getSingleton().logMessage("Loading library " + mName); - String name = mName; + String name = mName; #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_NACL // dlopen() does not add .so to the filename, like windows does for .dll if (name.find(".so") == String::npos) @@ -85,12 +85,12 @@ namespace Ogre { #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE // dlopen() does not add .dylib to the filename, like windows does for .dll if (name.substr(name.length() - 6, 6) != ".dylib") - name += ".dylib"; + name += ".dylib"; #elif OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT - // Although LoadLibraryEx will add .dll itself when you only specify the library name, - // if you include a relative path then it does not. So, add it to be sure. - if (name.substr(name.length() - 4, 4) != ".dll") - name += ".dll"; + // Although LoadLibraryEx will add .dll itself when you only specify the library name, + // if you include a relative path then it does not. So, add it to be sure. + if (name.substr(name.length() - 4, 4) != ".dll") + name += ".dll"; #endif mInst = (DYNLIB_HANDLE)DYNLIB_LOAD( name.c_str() ); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE @@ -115,13 +115,13 @@ namespace Ogre { LogManager::getSingleton().logMessage("Unloading library " + mName); if( DYNLIB_UNLOAD( mInst ) ) - { + { OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Could not unload dynamic library " + mName + ". System Error: " + dynlibError(), "DynLib::unload"); - } + } } @@ -162,21 +162,21 @@ namespace Ogre { sizeof(wideMsgBuf) / sizeof(wideMsgBuf[0]), NULL )) - { - wideMsgBuf[0] = 0; - } + { + wideMsgBuf[0] = 0; + } #if OGRE_WCHAR_T_STRINGS String ret = wideMsgBuf; #else - char narrowMsgBuf[2048] = ""; - if(0 == WideCharToMultiByte( - CP_ACP, 0, - wideMsgBuf, -1, - narrowMsgBuf, sizeof(narrowMsgBuf) / sizeof(narrowMsgBuf[0]), - NULL, NULL)) - { - narrowMsgBuf[0] = 0; - } + char narrowMsgBuf[2048] = ""; + if(0 == WideCharToMultiByte( + CP_ACP, 0, + wideMsgBuf, -1, + narrowMsgBuf, sizeof(narrowMsgBuf) / sizeof(narrowMsgBuf[0]), + NULL, NULL)) + { + narrowMsgBuf[0] = 0; + } String ret = narrowMsgBuf; #endif return ret; diff --git a/OgreMain/src/OgreDynLibManager.cpp b/OgreMain/src/OgreDynLibManager.cpp index b9799b8a652..0661ff3b64c 100644 --- a/OgreMain/src/OgreDynLibManager.cpp +++ b/OgreMain/src/OgreDynLibManager.cpp @@ -39,43 +39,43 @@ namespace Ogre { return msSingleton; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- DynLibManager& DynLibManager::getSingleton(void) { assert( msSingleton ); return ( *msSingleton ); } //----------------------------------------------------------------------- - DynLibManager::DynLibManager() - { - } - //----------------------------------------------------------------------- + DynLibManager::DynLibManager() + { + } + //----------------------------------------------------------------------- DynLib* DynLibManager::load( const String& filename) { - DynLibList::iterator i = mLibList.find(filename); - if (i != mLibList.end()) - { - return i->second; - } - else - { - DynLib* pLib = OGRE_NEW DynLib(filename); - pLib->load(); - mLibList[filename] = pLib; - return pLib; - } + DynLibList::iterator i = mLibList.find(filename); + if (i != mLibList.end()) + { + return i->second; + } + else + { + DynLib* pLib = OGRE_NEW DynLib(filename); + pLib->load(); + mLibList[filename] = pLib; + return pLib; + } + } + //----------------------------------------------------------------------- + void DynLibManager::unload(DynLib* lib) + { + DynLibList::iterator i = mLibList.find(lib->getName()); + if (i != mLibList.end()) + { + mLibList.erase(i); + } + lib->unload(); + OGRE_DELETE lib; } - //----------------------------------------------------------------------- - void DynLibManager::unload(DynLib* lib) - { - DynLibList::iterator i = mLibList.find(lib->getName()); - if (i != mLibList.end()) - { - mLibList.erase(i); - } - lib->unload(); - OGRE_DELETE lib; - } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- DynLibManager::~DynLibManager() { // Unload & delete resources in turn diff --git a/OgreMain/src/OgreETCCodec.cpp b/OgreMain/src/OgreETCCodec.cpp index 4057fba80a4..4d621e67b94 100644 --- a/OgreMain/src/OgreETCCodec.cpp +++ b/OgreMain/src/OgreETCCodec.cpp @@ -71,63 +71,63 @@ namespace Ogre { uint8 iHeightMSB; uint8 iHeightLSB; } PKMHeader; - + typedef struct { - uint8 identifier[12]; - uint32 endianness; - uint32 glType; - uint32 glTypeSize; - uint32 glFormat; - uint32 glInternalFormat; - uint32 glBaseInternalFormat; - uint32 pixelWidth; - uint32 pixelHeight; - uint32 pixelDepth; - uint32 numberOfArrayElements; - uint32 numberOfFaces; - uint32 numberOfMipmapLevels; - uint32 bytesOfKeyValueData; + uint8 identifier[12]; + uint32 endianness; + uint32 glType; + uint32 glTypeSize; + uint32 glFormat; + uint32 glInternalFormat; + uint32 glBaseInternalFormat; + uint32 pixelWidth; + uint32 pixelHeight; + uint32 pixelDepth; + uint32 numberOfArrayElements; + uint32 numberOfFaces; + uint32 numberOfMipmapLevels; + uint32 bytesOfKeyValueData; } KTXHeader; - //--------------------------------------------------------------------- - ETCCodec* ETCCodec::msPKMInstance = 0; - ETCCodec* ETCCodec::msKTXInstance = 0; - //--------------------------------------------------------------------- - void ETCCodec::startup(void) - { - if (!msPKMInstance) - { - msPKMInstance = OGRE_NEW ETCCodec("pkm"); - Codec::registerCodec(msPKMInstance); - } - - if (!msKTXInstance) - { - msKTXInstance = OGRE_NEW ETCCodec("ktx"); - Codec::registerCodec(msKTXInstance); - } + //--------------------------------------------------------------------- + ETCCodec* ETCCodec::msPKMInstance = 0; + ETCCodec* ETCCodec::msKTXInstance = 0; + //--------------------------------------------------------------------- + void ETCCodec::startup(void) + { + if (!msPKMInstance) + { + msPKMInstance = OGRE_NEW ETCCodec("pkm"); + Codec::registerCodec(msPKMInstance); + } + + if (!msKTXInstance) + { + msKTXInstance = OGRE_NEW ETCCodec("ktx"); + Codec::registerCodec(msKTXInstance); + } LogManager::getSingleton().logMessage(LML_NORMAL, "ETC codec registering"); - } - //--------------------------------------------------------------------- - void ETCCodec::shutdown(void) - { - if(msPKMInstance) - { - Codec::unregisterCodec(msPKMInstance); - OGRE_DELETE msPKMInstance; - msPKMInstance = 0; - } - - if(msKTXInstance) - { - Codec::unregisterCodec(msKTXInstance); - OGRE_DELETE msKTXInstance; - msKTXInstance = 0; - } - } - //--------------------------------------------------------------------- + } + //--------------------------------------------------------------------- + void ETCCodec::shutdown(void) + { + if(msPKMInstance) + { + Codec::unregisterCodec(msPKMInstance); + OGRE_DELETE msPKMInstance; + msPKMInstance = 0; + } + + if(msKTXInstance) + { + Codec::unregisterCodec(msKTXInstance); + OGRE_DELETE msKTXInstance; + msKTXInstance = 0; + } + } + //--------------------------------------------------------------------- ETCCodec::ETCCodec(const String &type): mType(type) { @@ -135,7 +135,7 @@ namespace Ogre { //--------------------------------------------------------------------- DataStreamPtr ETCCodec::encode(MemoryDataStreamPtr& input, Codec::CodecDataPtr& pData) const { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "ETC encoding not supported", "ETCCodec::encode" ) ; } @@ -143,22 +143,22 @@ namespace Ogre { void ETCCodec::encodeToFile(MemoryDataStreamPtr& input, const String& outFileName, Codec::CodecDataPtr& pData) const { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "ETC encoding not supported", "ETCCodec::encodeToFile" ) ; - } + } //--------------------------------------------------------------------- Codec::DecodeResult ETCCodec::decode(DataStreamPtr& stream) const { DecodeResult ret; - if (decodeKTX(stream, ret)) - return ret; + if (decodeKTX(stream, ret)) + return ret; - stream->seek(0); - if (decodePKM(stream, ret)) - return ret; + stream->seek(0); + if (decodePKM(stream, ret)) + return ret; - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "This is not a valid ETC file!", "ETCCodec::decode"); } //--------------------------------------------------------------------- @@ -170,7 +170,7 @@ namespace Ogre { void ETCCodec::flipEndian(void * pData, size_t size, size_t count) const { #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - for(unsigned int index = 0; index < count; index++) + for(unsigned int index = 0; index < count; index++) { flipEndian((void *)((long)pData + (index * size)), size); } @@ -189,26 +189,26 @@ namespace Ogre { #endif } //--------------------------------------------------------------------- - String ETCCodec::magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const - { - if (maxbytes >= sizeof(uint32)) - { - uint32 fileType; - memcpy(&fileType, magicNumberPtr, sizeof(uint32)); - flipEndian(&fileType, sizeof(uint32), 1); - - if (PKM_MAGIC == fileType) - return String("pkm"); - - if (KTX_MAGIC == fileType) + String ETCCodec::magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const + { + if (maxbytes >= sizeof(uint32)) + { + uint32 fileType; + memcpy(&fileType, magicNumberPtr, sizeof(uint32)); + flipEndian(&fileType, sizeof(uint32), 1); + + if (PKM_MAGIC == fileType) + return String("pkm"); + + if (KTX_MAGIC == fileType) return String("ktx"); - } + } - return BLANKSTRING; - } + return BLANKSTRING; + } //--------------------------------------------------------------------- - bool ETCCodec::decodePKM(DataStreamPtr& stream, DecodeResult& result) const - { + bool ETCCodec::decodePKM(DataStreamPtr& stream, DecodeResult& result) const + { PKMHeader header; // Read the ETC header @@ -268,105 +268,105 @@ namespace Ogre { imgData->flags |= IF_COMPRESSED; // Calculate total size from number of mipmaps, faces and size - imgData->size = (paddedWidth * paddedHeight) >> 1; + imgData->size = (paddedWidth * paddedHeight) >> 1; - // Bind output buffer - MemoryDataStreamPtr output; - output.bind(OGRE_NEW MemoryDataStream(imgData->size)); + // Bind output buffer + MemoryDataStreamPtr output; + output.bind(OGRE_NEW MemoryDataStream(imgData->size)); - // Now deal with the data - void *destPtr = output->getPtr(); + // Now deal with the data + void *destPtr = output->getPtr(); stream->read(destPtr, imgData->size); destPtr = static_cast(static_cast(destPtr)); - DecodeResult ret; - ret.first = output; - ret.second = CodecDataPtr(imgData); + DecodeResult ret; + ret.first = output; + ret.second = CodecDataPtr(imgData); return true; } //--------------------------------------------------------------------- - bool ETCCodec::decodeKTX(DataStreamPtr& stream, DecodeResult& result) const - { + bool ETCCodec::decodeKTX(DataStreamPtr& stream, DecodeResult& result) const + { KTXHeader header; // Read the ETC1 header stream->read(&header, sizeof(KTXHeader)); - const uint8 KTXFileIdentifier[12] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }; - if (memcmp(KTXFileIdentifier, &header.identifier, sizeof(KTXFileIdentifier)) != 0 ) - return false; + const uint8 KTXFileIdentifier[12] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }; + if (memcmp(KTXFileIdentifier, &header.identifier, sizeof(KTXFileIdentifier)) != 0 ) + return false; - if (header.endianness == KTX_ENDIAN_REF_REV) - flipEndian(&header.glType, sizeof(uint32), 1); + if (header.endianness == KTX_ENDIAN_REF_REV) + flipEndian(&header.glType, sizeof(uint32), 1); ImageData *imgData = OGRE_NEW ImageData(); imgData->depth = 1; imgData->width = header.pixelWidth; imgData->height = header.pixelHeight; - imgData->num_mipmaps = static_cast(header.numberOfMipmapLevels - 1); + imgData->num_mipmaps = static_cast(header.numberOfMipmapLevels - 1); - switch(header.glInternalFormat) - { - case 37492: // GL_COMPRESSED_RGB8_ETC2 + switch(header.glInternalFormat) + { + case 37492: // GL_COMPRESSED_RGB8_ETC2 imgData->format = PF_ETC2_RGB8; - break; + break; case 37496:// GL_COMPRESSED_RGBA8_ETC2_EAC - imgData->format = PF_ETC2_RGBA8; + imgData->format = PF_ETC2_RGBA8; break; - case 37494: // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 + case 37494: // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 imgData->format = PF_ETC2_RGB8A1; - break; - case 35986: // ATC_RGB - imgData->format = PF_ATC_RGB; - break; - case 35987: // ATC_RGB_Explicit - imgData->format = PF_ATC_RGBA_EXPLICIT_ALPHA; - break; - case 34798: // ATC_RGB_Interpolated - imgData->format = PF_ATC_RGBA_INTERPOLATED_ALPHA; - break; - case 33777: // DXT 1 - imgData->format = PF_DXT1; - break; - case 33778: // DXT 3 - imgData->format = PF_DXT3; - break; - case 33779: // DXT 5 - imgData->format = PF_DXT5; - break; - default: - imgData->format = PF_ETC1_RGB8; - break; - } - - imgData->flags = 0; - if (header.glType == 0 || header.glFormat == 0) - imgData->flags |= IF_COMPRESSED; - - size_t numFaces = 1; // Assume one face until we know otherwise + break; + case 35986: // ATC_RGB + imgData->format = PF_ATC_RGB; + break; + case 35987: // ATC_RGB_Explicit + imgData->format = PF_ATC_RGBA_EXPLICIT_ALPHA; + break; + case 34798: // ATC_RGB_Interpolated + imgData->format = PF_ATC_RGBA_INTERPOLATED_ALPHA; + break; + case 33777: // DXT 1 + imgData->format = PF_DXT1; + break; + case 33778: // DXT 3 + imgData->format = PF_DXT3; + break; + case 33779: // DXT 5 + imgData->format = PF_DXT5; + break; + default: + imgData->format = PF_ETC1_RGB8; + break; + } + + imgData->flags = 0; + if (header.glType == 0 || header.glFormat == 0) + imgData->flags |= IF_COMPRESSED; + + size_t numFaces = 1; // Assume one face until we know otherwise // Calculate total size from number of mipmaps, faces and size - imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, + imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, imgData->width, imgData->height, imgData->depth, imgData->format); - stream->skip(header.bytesOfKeyValueData); + stream->skip(header.bytesOfKeyValueData); - // Bind output buffer - MemoryDataStreamPtr output; - output.bind(OGRE_NEW MemoryDataStream(imgData->size)); + // Bind output buffer + MemoryDataStreamPtr output; + output.bind(OGRE_NEW MemoryDataStream(imgData->size)); - // Now deal with the data - uchar* destPtr = output->getPtr(); - for (uint32 level = 0; level < header.numberOfMipmapLevels; ++level) - { - uint32 imageSize = 0; - stream->read(&imageSize, sizeof(uint32)); - stream->read(destPtr, imageSize); - destPtr += imageSize; - } + // Now deal with the data + uchar* destPtr = output->getPtr(); + for (uint32 level = 0; level < header.numberOfMipmapLevels; ++level) + { + uint32 imageSize = 0; + stream->read(&imageSize, sizeof(uint32)); + stream->read(destPtr, imageSize); + destPtr += imageSize; + } - result.first = output; - result.second = CodecDataPtr(imgData); + result.first = output; + result.second = CodecDataPtr(imgData); - return true; - } + return true; + } } diff --git a/OgreMain/src/OgreEdgeListBuilder.cpp b/OgreMain/src/OgreEdgeListBuilder.cpp index c028c529692..b45f2845356 100644 --- a/OgreMain/src/OgreEdgeListBuilder.cpp +++ b/OgreMain/src/OgreEdgeListBuilder.cpp @@ -33,8 +33,8 @@ THE SOFTWARE. namespace Ogre { - EdgeData::EdgeData() : isClosed(false){} - + EdgeData::EdgeData() : isClosed(false){} + void EdgeData::log(Log* l) { EdgeGroupList::iterator i, iend; @@ -228,23 +228,23 @@ namespace Ogre { // The edge group now we are dealing with. EdgeData::EdgeGroup& eg = mEdgeData->edgeGroups[vertexSet]; - // locate position element & the buffer to go with it + // locate position element & the buffer to go with it const VertexData* vertexData = mVertexDataList[vertexSet]; - const VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr vbuf = - vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); - // lock the buffer for reading - unsigned char* pBaseVertex = static_cast( - vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + const VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr vbuf = + vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); + // lock the buffer for reading + unsigned char* pBaseVertex = static_cast( + vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); // Get the indexes ready for reading - bool idx32bit = (indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT); - size_t indexSize = idx32bit ? sizeof(uint32) : sizeof(uint16); + bool idx32bit = (indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT); + size_t indexSize = idx32bit ? sizeof(uint32) : sizeof(uint16); #if defined(_MSC_VER) && _MSC_VER <= 1300 // NB: Can't use un-named union with VS.NET 2002 when /RTC1 compile flag enabled. void* pIndex = indexData->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY); - pIndex = static_cast( - static_cast(pIndex) + indexData->indexStart * indexSize); + pIndex = static_cast( + static_cast(pIndex) + indexData->indexStart * indexSize); unsigned short* p16Idx = static_cast(pIndex); unsigned int* p32Idx = static_cast(pIndex); #else @@ -254,8 +254,8 @@ namespace Ogre { unsigned int* p32Idx; }; pIndex = indexData->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY); - pIndex = static_cast( - static_cast(pIndex) + indexData->indexStart * indexSize); + pIndex = static_cast( + static_cast(pIndex) + indexData->indexStart * indexSize); #endif // Iterate over all the groups of 3 indexes @@ -431,14 +431,14 @@ namespace Ogre { assert(triangleFaceNormals.size() == triangleLightFacings.size()); // Use optimised util to determine if triangle's face normal are light facing - if(!triangleFaceNormals.empty()) - { - OptimisedUtil::getImplementation()->calculateLightFacing( - lightPos, - &triangleFaceNormals.front(), - &triangleLightFacings.front(), - triangleLightFacings.size()); - } + if(!triangleFaceNormals.empty()) + { + OptimisedUtil::getImplementation()->calculateLightFacing( + lightPos, + &triangleFaceNormals.front(), + &triangleLightFacings.front(), + triangleLightFacings.size()); + } } //--------------------------------------------------------------------- void EdgeData::updateFaceNormals(size_t vertexSet, @@ -456,30 +456,30 @@ namespace Ogre { // Calculate triangles which are using this vertex set const EdgeData::EdgeGroup& eg = edgeGroups[vertexSet]; - if (eg.triCount != 0) - { - OptimisedUtil::getImplementation()->calculateFaceNormals( - pVert, - &triangles[eg.triStart], - &triangleFaceNormals[eg.triStart], - eg.triCount); - } + if (eg.triCount != 0) + { + OptimisedUtil::getImplementation()->calculateFaceNormals( + pVert, + &triangles[eg.triStart], + &triangleFaceNormals[eg.triStart], + eg.triCount); + } // unlock the buffer positionBuffer->unlock(); } - //--------------------------------------------------------------------- - EdgeData* EdgeData::clone() - { - EdgeData* newEdgeData = OGRE_NEW EdgeData(); - newEdgeData->triangles = triangles; - newEdgeData->triangleFaceNormals = triangleFaceNormals; - newEdgeData->triangleLightFacings = triangleLightFacings; - newEdgeData->edgeGroups = edgeGroups; - newEdgeData->isClosed = isClosed; - return newEdgeData; - } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + EdgeData* EdgeData::clone() + { + EdgeData* newEdgeData = OGRE_NEW EdgeData(); + newEdgeData->triangles = triangles; + newEdgeData->triangleFaceNormals = triangleFaceNormals; + newEdgeData->triangleLightFacings = triangleLightFacings; + newEdgeData->edgeGroups = edgeGroups; + newEdgeData->isClosed = isClosed; + return newEdgeData; + } + //--------------------------------------------------------------------- void EdgeListBuilder::log(Log* l) { l->logMessage("EdgeListBuilder Log"); diff --git a/OgreMain/src/OgreEntity.cpp b/OgreMain/src/OgreEntity.cpp index 98b9c1c921b..c62287e8f74 100644 --- a/OgreMain/src/OgreEntity.cpp +++ b/OgreMain/src/OgreEntity.cpp @@ -80,11 +80,11 @@ namespace Ogre { mMeshLodIndex(0), mMeshLodFactorTransformed(1.0f), mMinMeshLodIndex(99), - mMaxMeshLodIndex(0), // Backwards, remember low value = high detail + mMaxMeshLodIndex(0), // Backwards, remember low value = high detail mMaterialLodFactor(1.0f), mMaterialLodFactorTransformed(1.0f), mMinMaterialLodIndex(99), - mMaxMaterialLodIndex(0), // Backwards, remember low value = high detail + mMaxMaterialLodIndex(0), // Backwards, remember low value = high detail mSkeletonInstance(0), mInitialised(false), mLastParentXform(Matrix4::ZERO), @@ -119,11 +119,11 @@ namespace Ogre { mMeshLodIndex(0), mMeshLodFactorTransformed(1.0f), mMinMeshLodIndex(99), - mMaxMeshLodIndex(0), // Backwards, remember low value = high detail + mMaxMeshLodIndex(0), // Backwards, remember low value = high detail mMaterialLodFactor(1.0f), mMaterialLodFactorTransformed(1.0f), mMinMaterialLodIndex(99), - mMaxMaterialLodIndex(0), // Backwards, remember low value = high detail + mMaxMaterialLodIndex(0), // Backwards, remember low value = high detail mSkeletonInstance(0), mInitialised(false), mLastParentXform(Matrix4::ZERO), @@ -156,7 +156,7 @@ namespace Ogre { // do this before asking for load to happen to avoid race mMesh->addListener(this); } - + // On-demand load mMesh->load(); // If loading failed, or deferred loading isn't done yet, defer @@ -181,7 +181,7 @@ namespace Ogre { buildSubEntityList(mMesh, &mSubEntityList); #if !OGRE_NO_MESHLOD // Check if mesh is using manual LOD - if (mMesh->hasManualLodLevel()) + if (mMesh->hasManualLodLevel()) { ushort i, numLod; numLod = mMesh->getNumLodLevels(); @@ -189,23 +189,23 @@ namespace Ogre { for (i = 1; i < numLod; ++i) { const MeshLodUsage& usage = mMesh->getLodLevel(i); - Entity* lodEnt; - if(!usage.manualName.empty()){ - // Disabled to prevent recursion when a.mesh has manualLod to b.mesh and b.mesh has manualLod to a.mesh. - OgreAssert(usage.manualMesh->getNumLodLevels() == 1, "Manual Lod Mesh can't have Lod levels!"); - - if(usage.manualMesh->getNumLodLevels() != 1) { - // To prevent crash in release builds, we will remove Lod levels. - usage.manualMesh->removeLodLevels(); - } - - // Manually create entity - lodEnt = OGRE_NEW Entity(mName + "Lod" + StringConverter::toString(i), - usage.manualMesh); - } else { - // Autogenerated lod uses original entity - lodEnt = this; - } + Entity* lodEnt; + if(!usage.manualName.empty()){ + // Disabled to prevent recursion when a.mesh has manualLod to b.mesh and b.mesh has manualLod to a.mesh. + OgreAssert(usage.manualMesh->getNumLodLevels() == 1, "Manual Lod Mesh can't have Lod levels!"); + + if(usage.manualMesh->getNumLodLevels() != 1) { + // To prevent crash in release builds, we will remove Lod levels. + usage.manualMesh->removeLodLevels(); + } + + // Manually create entity + lodEnt = OGRE_NEW Entity(mName + "Lod" + StringConverter::toString(i), + usage.manualMesh); + } else { + // Autogenerated lod uses original entity + lodEnt = this; + } mLodEntityList.push_back(lodEnt); } } @@ -226,7 +226,7 @@ namespace Ogre { } reevaluateVertexProcessing(); - + // Update of bounds of the parent SceneNode, if Entity already attached // this can happen if Mesh is loaded in background or after reinitialisation if( mParentNode ) @@ -261,12 +261,12 @@ namespace Ogre { liend = mLodEntityList.end(); for (li = mLodEntityList.begin(); li != liend; ++li) { - if(*li != this) { - // Delete - OGRE_DELETE *li; - *li = 0; - } - } + if(*li != this) { + // Delete + OGRE_DELETE *li; + *li = 0; + } + } mLodEntityList.clear(); #endif // Delete shadow renderables @@ -634,7 +634,7 @@ namespace Ogre { // derive child bounding boxes ChildObjectList::const_iterator child_itr = mChildObjectList.begin(); ChildObjectList::const_iterator child_itr_end = mChildObjectList.end(); - for( ; child_itr != child_itr_end; ++child_itr) + for( ; child_itr != child_itr_end; ++child_itr) { child_itr->second->getWorldBoundingBox(true); } @@ -649,7 +649,7 @@ namespace Ogre { // derive child bounding boxes ChildObjectList::const_iterator child_itr = mChildObjectList.begin(); ChildObjectList::const_iterator child_itr_end = mChildObjectList.end(); - for( ; child_itr != child_itr_end; ++child_itr) + for( ; child_itr != child_itr_end; ++child_itr) { child_itr->second->getWorldBoundingSphere(true); } @@ -680,20 +680,20 @@ namespace Ogre { assert( static_cast< size_t >( mMeshLodIndex - 1 ) < mLodEntityList.size() && "No LOD EntityList - did you build the manual LODs after creating the entity?"); // index - 1 as we skip index 0 (original LOD) - displayEntity = mLodEntityList[mMeshLodIndex-1]; + displayEntity = mLodEntityList[mMeshLodIndex-1]; - if (displayEntity != this && hasSkeleton() && displayEntity->hasSkeleton()) - { - // Copy the animation state set to lod entity, we assume the lod - // entity only has a subset animation states - AnimationStateSet* targetState = displayEntity->mAnimationState; + if (displayEntity != this && hasSkeleton() && displayEntity->hasSkeleton()) + { + // Copy the animation state set to lod entity, we assume the lod + // entity only has a subset animation states + AnimationStateSet* targetState = displayEntity->mAnimationState; if (mAnimationState != targetState) // only copy if LODs use different skeleton instances { if (mAnimationState->getDirtyFrameNumber() != targetState->getDirtyFrameNumber()) // only copy if animation was updated mAnimationState->copyMatchingState(targetState); } - } - } + } + } #endif // Add each visible SubEntity to the queue @@ -894,7 +894,7 @@ namespace Ogre { bool animationDirty = (mFrameAnimationLastUpdated != mAnimationState->getDirtyFrameNumber()) || (hasSkeleton() && getSkeleton()->getManualBonesDirty()); - + //update the current hardware animation state mCurrentHWAnimationState = hwAnimation; @@ -967,7 +967,7 @@ namespace Ogre { // Blend, taking source from either mesh data or morph data Mesh::softwareVertexBlend( (mMesh->getSharedVertexDataAnimationType() != VAT_NONE) ? - mSoftwareVertexAnimVertexData : mMesh->sharedVertexData, + mSoftwareVertexAnimVertexData : mMesh->sharedVertexData, mSkelAnimVertexData, blendMatrices, mMesh->sharedBlendIndexToBoneIndexMap.size(), blendNormals); @@ -1061,7 +1061,7 @@ namespace Ogre { } // reset used count vdata->hwAnimDataItemsUsed = 0; - + return elemsSupported; } @@ -1082,7 +1082,7 @@ namespace Ogre { (msh->getSharedVertexDataAnimationType() == VAT_POSE) ? mHardwarePoseCount : 1, msh->getSharedVertexDataAnimationIncludesNormals()); - + if (msh->getSharedVertexDataAnimationType() == VAT_POSE && supportedCount < mHardwarePoseCount) { @@ -1093,81 +1093,81 @@ namespace Ogre { " were able to be supported in the shared mesh data."; mHardwarePoseCount = supportedCount; } - + } - for (SubEntityList::iterator si = mSubEntityList.begin(); - si != mSubEntityList.end(); ++si) - { - SubEntity* sub = *si; - if (sub->getSubMesh()->getVertexAnimationType() != VAT_NONE && - !sub->getSubMesh()->useSharedVertices) - { - ushort supportedCount = initHardwareAnimationElements( - sub->_getHardwareVertexAnimVertexData(), - (sub->getSubMesh()->getVertexAnimationType() == VAT_POSE) - ? sub->mHardwarePoseCount : 1, - sub->getSubMesh()->getVertexAnimationIncludesNormals()); - - if (sub->getSubMesh()->getVertexAnimationType() == VAT_POSE && - supportedCount < sub->mHardwarePoseCount) - { - LogManager::getSingleton().stream() << - "Vertex program assigned to SubEntity of '" << mName << - "' claimed to support " << sub->mHardwarePoseCount << - " morph/pose vertex sets, but in fact only " << supportedCount << - " were able to be supported in the mesh data."; - sub->mHardwarePoseCount = supportedCount; - } - - } - } - - } - else - { - // May be blending multiple poses in software - // Suppress hardware upload of buffers - // Note, we query position buffer here but it may also include normals - if (mSoftwareVertexAnimVertexData && - mMesh->getSharedVertexDataAnimationType() == VAT_POSE) - { - const VertexElement* elem = mSoftwareVertexAnimVertexData - ->vertexDeclaration->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr buf = mSoftwareVertexAnimVertexData - ->vertexBufferBinding->getBuffer(elem->getSource()); - buf->suppressHardwareUpdate(true); - - initialisePoseVertexData(mMesh->sharedVertexData, mSoftwareVertexAnimVertexData, - mMesh->getSharedVertexDataAnimationIncludesNormals()); - } - for (SubEntityList::iterator si = mSubEntityList.begin(); - si != mSubEntityList.end(); ++si) - { - SubEntity* sub = *si; - if (!sub->getSubMesh()->useSharedVertices && - sub->getSubMesh()->getVertexAnimationType() == VAT_POSE) - { - VertexData* data = sub->_getSoftwareVertexAnimVertexData(); - const VertexElement* elem = data->vertexDeclaration - ->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr buf = data - ->vertexBufferBinding->getBuffer(elem->getSource()); - buf->suppressHardwareUpdate(true); - // if we're animating normals, we need to start with zeros - initialisePoseVertexData(sub->getSubMesh()->vertexData, data, - sub->getSubMesh()->getVertexAnimationIncludesNormals()); - } - } - } - - - // Now apply the animation(s) - // Note - you should only apply one morph animation to each set of vertex data - // at once; if you do more, only the last one will actually apply - markBuffersUnusedForAnimation(); - ConstEnabledAnimationStateIterator animIt = mAnimationState->getEnabledAnimationStateIterator(); - while(animIt.hasMoreElements()) - { + for (SubEntityList::iterator si = mSubEntityList.begin(); + si != mSubEntityList.end(); ++si) + { + SubEntity* sub = *si; + if (sub->getSubMesh()->getVertexAnimationType() != VAT_NONE && + !sub->getSubMesh()->useSharedVertices) + { + ushort supportedCount = initHardwareAnimationElements( + sub->_getHardwareVertexAnimVertexData(), + (sub->getSubMesh()->getVertexAnimationType() == VAT_POSE) + ? sub->mHardwarePoseCount : 1, + sub->getSubMesh()->getVertexAnimationIncludesNormals()); + + if (sub->getSubMesh()->getVertexAnimationType() == VAT_POSE && + supportedCount < sub->mHardwarePoseCount) + { + LogManager::getSingleton().stream() << + "Vertex program assigned to SubEntity of '" << mName << + "' claimed to support " << sub->mHardwarePoseCount << + " morph/pose vertex sets, but in fact only " << supportedCount << + " were able to be supported in the mesh data."; + sub->mHardwarePoseCount = supportedCount; + } + + } + } + + } + else + { + // May be blending multiple poses in software + // Suppress hardware upload of buffers + // Note, we query position buffer here but it may also include normals + if (mSoftwareVertexAnimVertexData && + mMesh->getSharedVertexDataAnimationType() == VAT_POSE) + { + const VertexElement* elem = mSoftwareVertexAnimVertexData + ->vertexDeclaration->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr buf = mSoftwareVertexAnimVertexData + ->vertexBufferBinding->getBuffer(elem->getSource()); + buf->suppressHardwareUpdate(true); + + initialisePoseVertexData(mMesh->sharedVertexData, mSoftwareVertexAnimVertexData, + mMesh->getSharedVertexDataAnimationIncludesNormals()); + } + for (SubEntityList::iterator si = mSubEntityList.begin(); + si != mSubEntityList.end(); ++si) + { + SubEntity* sub = *si; + if (!sub->getSubMesh()->useSharedVertices && + sub->getSubMesh()->getVertexAnimationType() == VAT_POSE) + { + VertexData* data = sub->_getSoftwareVertexAnimVertexData(); + const VertexElement* elem = data->vertexDeclaration + ->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr buf = data + ->vertexBufferBinding->getBuffer(elem->getSource()); + buf->suppressHardwareUpdate(true); + // if we're animating normals, we need to start with zeros + initialisePoseVertexData(sub->getSubMesh()->vertexData, data, + sub->getSubMesh()->getVertexAnimationIncludesNormals()); + } + } + } + + + // Now apply the animation(s) + // Note - you should only apply one morph animation to each set of vertex data + // at once; if you do more, only the last one will actually apply + markBuffersUnusedForAnimation(); + ConstEnabledAnimationStateIterator animIt = mAnimationState->getEnabledAnimationStateIterator(); + while(animIt.hasMoreElements()) + { const AnimationState* state = animIt.getNext(); Animation* anim = msh->_getAnimationImpl(state->getAnimationName()); if (anim) @@ -1175,300 +1175,300 @@ namespace Ogre { anim->apply(this, state->getTimePosition(), state->getWeight(), swAnim, hardwareAnimation); } - } - // Deal with cases where no animation applied - restoreBuffersForUnusedAnimation(hardwareAnimation); - - // Unsuppress hardware upload if we suppressed it - if (!hardwareAnimation) - { - if (mSoftwareVertexAnimVertexData && - msh->getSharedVertexDataAnimationType() == VAT_POSE) - { - // if we're animating normals, if pose influence < 1 need to use the base mesh - if (mMesh->getSharedVertexDataAnimationIncludesNormals()) - finalisePoseNormals(mMesh->sharedVertexData, mSoftwareVertexAnimVertexData); - - const VertexElement* elem = mSoftwareVertexAnimVertexData - ->vertexDeclaration->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr buf = mSoftwareVertexAnimVertexData - ->vertexBufferBinding->getBuffer(elem->getSource()); - buf->suppressHardwareUpdate(false); - } - for (SubEntityList::iterator si = mSubEntityList.begin(); - si != mSubEntityList.end(); ++si) - { - SubEntity* sub = *si; - if (!sub->getSubMesh()->useSharedVertices && - sub->getSubMesh()->getVertexAnimationType() == VAT_POSE) - { - VertexData* data = sub->_getSoftwareVertexAnimVertexData(); - // if we're animating normals, if pose influence < 1 need to use the base mesh - if (sub->getSubMesh()->getVertexAnimationIncludesNormals()) - finalisePoseNormals(sub->getSubMesh()->vertexData, data); - - const VertexElement* elem = data->vertexDeclaration - ->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr buf = data - ->vertexBufferBinding->getBuffer(elem->getSource()); - buf->suppressHardwareUpdate(false); - } - } - } - - } - //----------------------------------------------------------------------------- - void Entity::markBuffersUnusedForAnimation(void) - { - mVertexAnimationAppliedThisFrame = false; - for (SubEntityList::iterator i = mSubEntityList.begin(); - i != mSubEntityList.end(); ++i) - { - (*i)->_markBuffersUnusedForAnimation(); - } - } - //----------------------------------------------------------------------------- - void Entity::_markBuffersUsedForAnimation(void) - { - mVertexAnimationAppliedThisFrame = true; - // no cascade - } - //----------------------------------------------------------------------------- - void Entity::restoreBuffersForUnusedAnimation(bool hardwareAnimation) - { - // Rebind original positions if: - // We didn't apply any animation and - // We're morph animated (hardware binds keyframe, software is missing) - // or we're pose animated and software (hardware is fine, still bound) - if (mMesh->sharedVertexData && - !mVertexAnimationAppliedThisFrame && - (!hardwareAnimation || mMesh->getSharedVertexDataAnimationType() == VAT_MORPH)) - { - // Note, VES_POSITION is specified here but if normals are included in animation - // then these will be re-bound too (buffers must be shared) - const VertexElement* srcPosElem = - mMesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr srcBuf = - mMesh->sharedVertexData->vertexBufferBinding->getBuffer( - srcPosElem->getSource()); - - // Bind to software - const VertexElement* destPosElem = - mSoftwareVertexAnimVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - mSoftwareVertexAnimVertexData->vertexBufferBinding->setBinding( - destPosElem->getSource(), srcBuf); - - } - - // rebind any missing hardware pose buffers - // Caused by not having any animations enabled, or keyframes which reference - // no poses - if (mMesh->sharedVertexData && hardwareAnimation - && mMesh->getSharedVertexDataAnimationType() == VAT_POSE) - { - bindMissingHardwarePoseBuffers(mMesh->sharedVertexData, mHardwareVertexAnimVertexData); - } - - - for (SubEntityList::iterator i = mSubEntityList.begin(); - i != mSubEntityList.end(); ++i) - { - (*i)->_restoreBuffersForUnusedAnimation(hardwareAnimation); - } - - } - //--------------------------------------------------------------------- - void Entity::bindMissingHardwarePoseBuffers(const VertexData* srcData, - VertexData* destData) - { - // For hardware pose animation, also make sure we've bound buffers to all the elements - // required - if there are missing bindings for elements in use, - // some rendersystems can complain because elements refer - // to an unbound source. - // Get the original position source, we'll use this to fill gaps - const VertexElement* srcPosElem = - srcData->vertexDeclaration->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr srcBuf = - srcData->vertexBufferBinding->getBuffer( - srcPosElem->getSource()); - - for (VertexData::HardwareAnimationDataList::const_iterator i = destData->hwAnimationDataList.begin(); - i != destData->hwAnimationDataList.end(); ++i) - { - const VertexData::HardwareAnimationData& animData = *i; - if (!destData->vertexBufferBinding->isBufferBound( - animData.targetBufferIndex)) - { - // Bind to a safe default - destData->vertexBufferBinding->setBinding( - animData.targetBufferIndex, srcBuf); - } - } - - } - //----------------------------------------------------------------------- - void Entity::initialisePoseVertexData(const VertexData* srcData, - VertexData* destData, bool animateNormals) - { - - // First time through for a piece of pose animated vertex data - // We need to copy the original position values to the temp accumulator - const VertexElement* origelem = - srcData->vertexDeclaration->findElementBySemantic(VES_POSITION); - const VertexElement* destelem = - destData->vertexDeclaration->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr origBuffer = - srcData->vertexBufferBinding->getBuffer(origelem->getSource()); - HardwareVertexBufferSharedPtr destBuffer = - destData->vertexBufferBinding->getBuffer(destelem->getSource()); - destBuffer->copyData(*origBuffer.get(), 0, 0, destBuffer->getSizeInBytes(), true); - - // If normals are included in animation, we want to reset the normals to zero - if (animateNormals) - { - const VertexElement* normElem = - destData->vertexDeclaration->findElementBySemantic(VES_NORMAL); - - if (normElem) - { - HardwareVertexBufferSharedPtr buf = - destData->vertexBufferBinding->getBuffer(normElem->getSource()); - char* pBase = static_cast(buf->lock(HardwareBuffer::HBL_NORMAL)); - pBase += destData->vertexStart * buf->getVertexSize(); - - for (size_t v = 0; v < destData->vertexCount; ++v) - { - float* pNorm; - normElem->baseVertexPointerToElement(pBase, &pNorm); - *pNorm++ = 0.0f; - *pNorm++ = 0.0f; - *pNorm++ = 0.0f; - - pBase += buf->getVertexSize(); - } - buf->unlock(); - } - } - } - //----------------------------------------------------------------------- - void Entity::finalisePoseNormals(const VertexData* srcData, VertexData* destData) - { - const VertexElement* destNormElem = - destData->vertexDeclaration->findElementBySemantic(VES_NORMAL); - const VertexElement* srcNormElem = - srcData->vertexDeclaration->findElementBySemantic(VES_NORMAL); - - if (destNormElem && srcNormElem) - { - HardwareVertexBufferSharedPtr srcbuf = - srcData->vertexBufferBinding->getBuffer(srcNormElem->getSource()); - HardwareVertexBufferSharedPtr dstbuf = - destData->vertexBufferBinding->getBuffer(destNormElem->getSource()); - char* pSrcBase = static_cast(srcbuf->lock(HardwareBuffer::HBL_READ_ONLY)); - char* pDstBase = static_cast(dstbuf->lock(HardwareBuffer::HBL_NORMAL)); - pSrcBase += srcData->vertexStart * srcbuf->getVertexSize(); - pDstBase += destData->vertexStart * dstbuf->getVertexSize(); - - // The goal here is to detect the length of the vertices, and to apply - // the base mesh vertex normal at one minus that length; this deals with - // any individual vertices which were either not affected by any pose, or - // were not affected to a complete extent - // We also normalise every normal to deal with over-weighting - for (size_t v = 0; v < destData->vertexCount; ++v) - { - float* pDstNorm; - destNormElem->baseVertexPointerToElement(pDstBase, &pDstNorm); - Vector3 norm(pDstNorm[0], pDstNorm[1], pDstNorm[2]); - Real len = norm.length(); - if (len + 1e-4f < 1.0f) - { - // Poses did not completely fill in this normal - // Apply base mesh - float baseWeight = 1.0f - (float)len; - float* pSrcNorm; - srcNormElem->baseVertexPointerToElement(pSrcBase, &pSrcNorm); - norm.x += *pSrcNorm++ * baseWeight; - norm.y += *pSrcNorm++ * baseWeight; - norm.z += *pSrcNorm++ * baseWeight; - } - norm.normalise(); - - *pDstNorm++ = (float)norm.x; - *pDstNorm++ = (float)norm.y; - *pDstNorm++ = (float)norm.z; - - pDstBase += dstbuf->getVertexSize(); - pSrcBase += dstbuf->getVertexSize(); - } - srcbuf->unlock(); - dstbuf->unlock(); - } - } - //----------------------------------------------------------------------- - void Entity::_updateAnimation(void) - { - // Externally visible method - if (hasSkeleton() || hasVertexAnimation()) - { - updateAnimation(); - } - } - //----------------------------------------------------------------------- + } + // Deal with cases where no animation applied + restoreBuffersForUnusedAnimation(hardwareAnimation); + + // Unsuppress hardware upload if we suppressed it + if (!hardwareAnimation) + { + if (mSoftwareVertexAnimVertexData && + msh->getSharedVertexDataAnimationType() == VAT_POSE) + { + // if we're animating normals, if pose influence < 1 need to use the base mesh + if (mMesh->getSharedVertexDataAnimationIncludesNormals()) + finalisePoseNormals(mMesh->sharedVertexData, mSoftwareVertexAnimVertexData); + + const VertexElement* elem = mSoftwareVertexAnimVertexData + ->vertexDeclaration->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr buf = mSoftwareVertexAnimVertexData + ->vertexBufferBinding->getBuffer(elem->getSource()); + buf->suppressHardwareUpdate(false); + } + for (SubEntityList::iterator si = mSubEntityList.begin(); + si != mSubEntityList.end(); ++si) + { + SubEntity* sub = *si; + if (!sub->getSubMesh()->useSharedVertices && + sub->getSubMesh()->getVertexAnimationType() == VAT_POSE) + { + VertexData* data = sub->_getSoftwareVertexAnimVertexData(); + // if we're animating normals, if pose influence < 1 need to use the base mesh + if (sub->getSubMesh()->getVertexAnimationIncludesNormals()) + finalisePoseNormals(sub->getSubMesh()->vertexData, data); + + const VertexElement* elem = data->vertexDeclaration + ->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr buf = data + ->vertexBufferBinding->getBuffer(elem->getSource()); + buf->suppressHardwareUpdate(false); + } + } + } + + } + //----------------------------------------------------------------------------- + void Entity::markBuffersUnusedForAnimation(void) + { + mVertexAnimationAppliedThisFrame = false; + for (SubEntityList::iterator i = mSubEntityList.begin(); + i != mSubEntityList.end(); ++i) + { + (*i)->_markBuffersUnusedForAnimation(); + } + } + //----------------------------------------------------------------------------- + void Entity::_markBuffersUsedForAnimation(void) + { + mVertexAnimationAppliedThisFrame = true; + // no cascade + } + //----------------------------------------------------------------------------- + void Entity::restoreBuffersForUnusedAnimation(bool hardwareAnimation) + { + // Rebind original positions if: + // We didn't apply any animation and + // We're morph animated (hardware binds keyframe, software is missing) + // or we're pose animated and software (hardware is fine, still bound) + if (mMesh->sharedVertexData && + !mVertexAnimationAppliedThisFrame && + (!hardwareAnimation || mMesh->getSharedVertexDataAnimationType() == VAT_MORPH)) + { + // Note, VES_POSITION is specified here but if normals are included in animation + // then these will be re-bound too (buffers must be shared) + const VertexElement* srcPosElem = + mMesh->sharedVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr srcBuf = + mMesh->sharedVertexData->vertexBufferBinding->getBuffer( + srcPosElem->getSource()); + + // Bind to software + const VertexElement* destPosElem = + mSoftwareVertexAnimVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + mSoftwareVertexAnimVertexData->vertexBufferBinding->setBinding( + destPosElem->getSource(), srcBuf); + + } + + // rebind any missing hardware pose buffers + // Caused by not having any animations enabled, or keyframes which reference + // no poses + if (mMesh->sharedVertexData && hardwareAnimation + && mMesh->getSharedVertexDataAnimationType() == VAT_POSE) + { + bindMissingHardwarePoseBuffers(mMesh->sharedVertexData, mHardwareVertexAnimVertexData); + } + + + for (SubEntityList::iterator i = mSubEntityList.begin(); + i != mSubEntityList.end(); ++i) + { + (*i)->_restoreBuffersForUnusedAnimation(hardwareAnimation); + } + + } + //--------------------------------------------------------------------- + void Entity::bindMissingHardwarePoseBuffers(const VertexData* srcData, + VertexData* destData) + { + // For hardware pose animation, also make sure we've bound buffers to all the elements + // required - if there are missing bindings for elements in use, + // some rendersystems can complain because elements refer + // to an unbound source. + // Get the original position source, we'll use this to fill gaps + const VertexElement* srcPosElem = + srcData->vertexDeclaration->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr srcBuf = + srcData->vertexBufferBinding->getBuffer( + srcPosElem->getSource()); + + for (VertexData::HardwareAnimationDataList::const_iterator i = destData->hwAnimationDataList.begin(); + i != destData->hwAnimationDataList.end(); ++i) + { + const VertexData::HardwareAnimationData& animData = *i; + if (!destData->vertexBufferBinding->isBufferBound( + animData.targetBufferIndex)) + { + // Bind to a safe default + destData->vertexBufferBinding->setBinding( + animData.targetBufferIndex, srcBuf); + } + } + + } + //----------------------------------------------------------------------- + void Entity::initialisePoseVertexData(const VertexData* srcData, + VertexData* destData, bool animateNormals) + { + + // First time through for a piece of pose animated vertex data + // We need to copy the original position values to the temp accumulator + const VertexElement* origelem = + srcData->vertexDeclaration->findElementBySemantic(VES_POSITION); + const VertexElement* destelem = + destData->vertexDeclaration->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr origBuffer = + srcData->vertexBufferBinding->getBuffer(origelem->getSource()); + HardwareVertexBufferSharedPtr destBuffer = + destData->vertexBufferBinding->getBuffer(destelem->getSource()); + destBuffer->copyData(*origBuffer.get(), 0, 0, destBuffer->getSizeInBytes(), true); + + // If normals are included in animation, we want to reset the normals to zero + if (animateNormals) + { + const VertexElement* normElem = + destData->vertexDeclaration->findElementBySemantic(VES_NORMAL); + + if (normElem) + { + HardwareVertexBufferSharedPtr buf = + destData->vertexBufferBinding->getBuffer(normElem->getSource()); + char* pBase = static_cast(buf->lock(HardwareBuffer::HBL_NORMAL)); + pBase += destData->vertexStart * buf->getVertexSize(); + + for (size_t v = 0; v < destData->vertexCount; ++v) + { + float* pNorm; + normElem->baseVertexPointerToElement(pBase, &pNorm); + *pNorm++ = 0.0f; + *pNorm++ = 0.0f; + *pNorm++ = 0.0f; + + pBase += buf->getVertexSize(); + } + buf->unlock(); + } + } + } + //----------------------------------------------------------------------- + void Entity::finalisePoseNormals(const VertexData* srcData, VertexData* destData) + { + const VertexElement* destNormElem = + destData->vertexDeclaration->findElementBySemantic(VES_NORMAL); + const VertexElement* srcNormElem = + srcData->vertexDeclaration->findElementBySemantic(VES_NORMAL); + + if (destNormElem && srcNormElem) + { + HardwareVertexBufferSharedPtr srcbuf = + srcData->vertexBufferBinding->getBuffer(srcNormElem->getSource()); + HardwareVertexBufferSharedPtr dstbuf = + destData->vertexBufferBinding->getBuffer(destNormElem->getSource()); + char* pSrcBase = static_cast(srcbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + char* pDstBase = static_cast(dstbuf->lock(HardwareBuffer::HBL_NORMAL)); + pSrcBase += srcData->vertexStart * srcbuf->getVertexSize(); + pDstBase += destData->vertexStart * dstbuf->getVertexSize(); + + // The goal here is to detect the length of the vertices, and to apply + // the base mesh vertex normal at one minus that length; this deals with + // any individual vertices which were either not affected by any pose, or + // were not affected to a complete extent + // We also normalise every normal to deal with over-weighting + for (size_t v = 0; v < destData->vertexCount; ++v) + { + float* pDstNorm; + destNormElem->baseVertexPointerToElement(pDstBase, &pDstNorm); + Vector3 norm(pDstNorm[0], pDstNorm[1], pDstNorm[2]); + Real len = norm.length(); + if (len + 1e-4f < 1.0f) + { + // Poses did not completely fill in this normal + // Apply base mesh + float baseWeight = 1.0f - (float)len; + float* pSrcNorm; + srcNormElem->baseVertexPointerToElement(pSrcBase, &pSrcNorm); + norm.x += *pSrcNorm++ * baseWeight; + norm.y += *pSrcNorm++ * baseWeight; + norm.z += *pSrcNorm++ * baseWeight; + } + norm.normalise(); + + *pDstNorm++ = (float)norm.x; + *pDstNorm++ = (float)norm.y; + *pDstNorm++ = (float)norm.z; + + pDstBase += dstbuf->getVertexSize(); + pSrcBase += dstbuf->getVertexSize(); + } + srcbuf->unlock(); + dstbuf->unlock(); + } + } + //----------------------------------------------------------------------- + void Entity::_updateAnimation(void) + { + // Externally visible method + if (hasSkeleton() || hasVertexAnimation()) + { + updateAnimation(); + } + } + //----------------------------------------------------------------------- bool Entity::_isAnimated(void) const { return (mAnimationState && mAnimationState->hasEnabledAnimationState()) || (getSkeleton() && getSkeleton()->hasManualBones()); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- bool Entity::_isSkeletonAnimated(void) const { return getSkeleton() && (mAnimationState->hasEnabledAnimationState() || getSkeleton()->hasManualBones()); } - //----------------------------------------------------------------------- - VertexData* Entity::_getSkelAnimVertexData(void) const - { - assert (mSkelAnimVertexData && "Not software skinned or has no shared vertex data!"); + //----------------------------------------------------------------------- + VertexData* Entity::_getSkelAnimVertexData(void) const + { + assert (mSkelAnimVertexData && "Not software skinned or has no shared vertex data!"); return mSkelAnimVertexData; - } - //----------------------------------------------------------------------- - VertexData* Entity::_getSoftwareVertexAnimVertexData(void) const - { - assert (mSoftwareVertexAnimVertexData && "Not vertex animated or has no shared vertex data!"); - return mSoftwareVertexAnimVertexData; - } - //----------------------------------------------------------------------- - VertexData* Entity::_getHardwareVertexAnimVertexData(void) const - { - assert (mHardwareVertexAnimVertexData && "Not vertex animated or has no shared vertex data!"); - return mHardwareVertexAnimVertexData; - } - //----------------------------------------------------------------------- - TempBlendedBufferInfo* Entity::_getSkelAnimTempBufferInfo(void) - { - return &mTempSkelAnimInfo; - } - //----------------------------------------------------------------------- - TempBlendedBufferInfo* Entity::_getVertexAnimTempBufferInfo(void) - { - return &mTempVertexAnimInfo; - } + } + //----------------------------------------------------------------------- + VertexData* Entity::_getSoftwareVertexAnimVertexData(void) const + { + assert (mSoftwareVertexAnimVertexData && "Not vertex animated or has no shared vertex data!"); + return mSoftwareVertexAnimVertexData; + } + //----------------------------------------------------------------------- + VertexData* Entity::_getHardwareVertexAnimVertexData(void) const + { + assert (mHardwareVertexAnimVertexData && "Not vertex animated or has no shared vertex data!"); + return mHardwareVertexAnimVertexData; + } + //----------------------------------------------------------------------- + TempBlendedBufferInfo* Entity::_getSkelAnimTempBufferInfo(void) + { + return &mTempSkelAnimInfo; + } + //----------------------------------------------------------------------- + TempBlendedBufferInfo* Entity::_getVertexAnimTempBufferInfo(void) + { + return &mTempVertexAnimInfo; + } //----------------------------------------------------------------------- bool Entity::cacheBoneMatrices(void) { Root& root = Root::getSingleton(); unsigned long currentFrameNumber = root.getNextFrameNumber(); if ((*mFrameBonesLastUpdated != currentFrameNumber) || - (hasSkeleton() && getSkeleton()->getManualBonesDirty())) - { - if ((!mSkipAnimStateUpdates) && (*mFrameBonesLastUpdated != currentFrameNumber)) - mSkeletonInstance->setAnimationState(*mAnimationState); + (hasSkeleton() && getSkeleton()->getManualBonesDirty())) + { + if ((!mSkipAnimStateUpdates) && (*mFrameBonesLastUpdated != currentFrameNumber)) + mSkeletonInstance->setAnimationState(*mAnimationState); mSkeletonInstance->_getBoneMatrices(mBoneMatrices); *mFrameBonesLastUpdated = currentFrameNumber; - return true; + return true; } - return false; + return false; } //----------------------------------------------------------------------- void Entity::setDisplaySkeleton(bool display) @@ -1484,39 +1484,39 @@ namespace Ogre { size_t Entity::getNumManualLodLevels(void) const { #if !OGRE_NO_MESHLOD - return mLodEntityList.size(); + return mLodEntityList.size(); #else - return 0; + return 0; #endif } - //----------------------------------------------------------------------- - Entity* Entity::getManualLodLevel(size_t index) const - { + //----------------------------------------------------------------------- + Entity* Entity::getManualLodLevel(size_t index) const + { #if !OGRE_NO_MESHLOD - assert(index < mLodEntityList.size()); + assert(index < mLodEntityList.size()); - return mLodEntityList[index]; + return mLodEntityList[index]; #else - OgreAssert(0, "This feature is disabled in ogre configuration!"); - return NULL; + OgreAssert(0, "This feature is disabled in ogre configuration!"); + return NULL; #endif - } + } #if !OGRE_NO_MESHLOD //----------------------------------------------------------------------- void Entity::setMeshLodBias(Real factor, ushort maxDetailIndex, ushort minDetailIndex) { - mMeshLodFactorTransformed = mMesh->getLodStrategy()->transformBias(factor); - mMaxMeshLodIndex = maxDetailIndex; - mMinMeshLodIndex = minDetailIndex; + mMeshLodFactorTransformed = mMesh->getLodStrategy()->transformBias(factor); + mMaxMeshLodIndex = maxDetailIndex; + mMinMeshLodIndex = minDetailIndex; } //----------------------------------------------------------------------- void Entity::setMaterialLodBias(Real factor, ushort maxDetailIndex, ushort minDetailIndex) { - mMaterialLodFactor = factor; - mMaterialLodFactorTransformed = mMesh->getLodStrategy()->transformBias(factor); - mMaxMaterialLodIndex = maxDetailIndex; - mMinMaterialLodIndex = minDetailIndex; + mMaterialLodFactor = factor; + mMaterialLodFactorTransformed = mMesh->getLodStrategy()->transformBias(factor); + mMaxMaterialLodIndex = maxDetailIndex; + mMinMaterialLodIndex = minDetailIndex; } #endif //----------------------------------------------------------------------- @@ -1584,7 +1584,7 @@ namespace Ogre { if (mParentNode) mParentNode->needUpdate(); - return tp; + return tp; } //----------------------------------------------------------------------- @@ -1683,35 +1683,35 @@ namespace Ogre { OGRE_DELETE mSkelAnimVertexData; mSkelAnimVertexData = 0; } - if (mSoftwareVertexAnimVertexData) - { - OGRE_DELETE mSoftwareVertexAnimVertexData; - mSoftwareVertexAnimVertexData = 0; - } - if (mHardwareVertexAnimVertexData) - { - OGRE_DELETE mHardwareVertexAnimVertexData; - mHardwareVertexAnimVertexData = 0; - } - - if (hasVertexAnimation()) - { - // Shared data - if (mMesh->sharedVertexData - && mMesh->getSharedVertexDataAnimationType() != VAT_NONE) - { - // Create temporary vertex blend info - // Prepare temp vertex data if needed - // Clone without copying data, don't remove any blending info - // (since if we skeletally animate too, we need it) - mSoftwareVertexAnimVertexData = mMesh->sharedVertexData->clone(false); - extractTempBufferInfo(mSoftwareVertexAnimVertexData, &mTempVertexAnimInfo); - - // Also clone for hardware usage, don't remove blend info since we'll - // need it if we also hardware skeletally animate - mHardwareVertexAnimVertexData = mMesh->sharedVertexData->clone(false); - } - } + if (mSoftwareVertexAnimVertexData) + { + OGRE_DELETE mSoftwareVertexAnimVertexData; + mSoftwareVertexAnimVertexData = 0; + } + if (mHardwareVertexAnimVertexData) + { + OGRE_DELETE mHardwareVertexAnimVertexData; + mHardwareVertexAnimVertexData = 0; + } + + if (hasVertexAnimation()) + { + // Shared data + if (mMesh->sharedVertexData + && mMesh->getSharedVertexDataAnimationType() != VAT_NONE) + { + // Create temporary vertex blend info + // Prepare temp vertex data if needed + // Clone without copying data, don't remove any blending info + // (since if we skeletally animate too, we need it) + mSoftwareVertexAnimVertexData = mMesh->sharedVertexData->clone(false); + extractTempBufferInfo(mSoftwareVertexAnimVertexData, &mTempVertexAnimInfo); + + // Also clone for hardware usage, don't remove blend info since we'll + // need it if we also hardware skeletally animate + mHardwareVertexAnimVertexData = mMesh->sharedVertexData->clone(false); + } + } if (hasSkeleton()) { @@ -1729,14 +1729,14 @@ namespace Ogre { } - // Do SubEntities - SubEntityList::iterator i, iend; - iend = mSubEntityList.end(); - for (i = mSubEntityList.begin(); i != iend; ++i) - { - SubEntity* s = *i; - s->prepareTempBlendBuffers(); - } + // Do SubEntities + SubEntityList::iterator i, iend; + iend = mSubEntityList.end(); + for (i = mSubEntityList.begin(); i != iend; ++i) + { + SubEntity* s = *i; + s->prepareTempBlendBuffers(); + } // It's prepared for shadow volumes only if mesh has been prepared for shadow volumes. mPreparedForShadowVolumes = mMesh->isPreparedForShadowVolumes(); @@ -1751,44 +1751,44 @@ namespace Ogre { { // Clone without copying data VertexData* ret = source->clone(false); - bool removeIndices = Ogre::Root::getSingleton().isBlendIndicesGpuRedundant(); - bool removeWeights = Ogre::Root::getSingleton().isBlendWeightsGpuRedundant(); - - unsigned short safeSource = 0xFFFF; - const VertexElement* blendIndexElem = - source->vertexDeclaration->findElementBySemantic(VES_BLEND_INDICES); - if (blendIndexElem) - { - //save the source in order to prevent the next stage from unbinding it. - safeSource = blendIndexElem->getSource(); - if (removeIndices) - { - // Remove buffer reference - ret->vertexBufferBinding->unsetBinding(blendIndexElem->getSource()); - } - } - if (removeWeights) - { - // Remove blend weights - const VertexElement* blendWeightElem = - source->vertexDeclaration->findElementBySemantic(VES_BLEND_WEIGHTS); - if (blendWeightElem && - blendWeightElem->getSource() != safeSource) - { - // Remove buffer reference - ret->vertexBufferBinding->unsetBinding(blendWeightElem->getSource()); - } - } + bool removeIndices = Ogre::Root::getSingleton().isBlendIndicesGpuRedundant(); + bool removeWeights = Ogre::Root::getSingleton().isBlendWeightsGpuRedundant(); + + unsigned short safeSource = 0xFFFF; + const VertexElement* blendIndexElem = + source->vertexDeclaration->findElementBySemantic(VES_BLEND_INDICES); + if (blendIndexElem) + { + //save the source in order to prevent the next stage from unbinding it. + safeSource = blendIndexElem->getSource(); + if (removeIndices) + { + // Remove buffer reference + ret->vertexBufferBinding->unsetBinding(blendIndexElem->getSource()); + } + } + if (removeWeights) + { + // Remove blend weights + const VertexElement* blendWeightElem = + source->vertexDeclaration->findElementBySemantic(VES_BLEND_WEIGHTS); + if (blendWeightElem && + blendWeightElem->getSource() != safeSource) + { + // Remove buffer reference + ret->vertexBufferBinding->unsetBinding(blendWeightElem->getSource()); + } + } // remove elements from declaration if (removeIndices) - ret->vertexDeclaration->removeElement(VES_BLEND_INDICES); - if (removeWeights) - ret->vertexDeclaration->removeElement(VES_BLEND_WEIGHTS); + ret->vertexDeclaration->removeElement(VES_BLEND_INDICES); + if (removeWeights) + ret->vertexDeclaration->removeElement(VES_BLEND_WEIGHTS); // Close gaps in bindings for effective and safely - if (removeWeights || removeIndices) - ret->closeGapsInBindings(); + if (removeWeights || removeIndices) + ret->closeGapsInBindings(); return ret; } @@ -1796,152 +1796,152 @@ namespace Ogre { EdgeData* Entity::getEdgeList(void) { #if OGRE_NO_MESHLOD - unsigned short mMeshLodIndex = 0; + unsigned short mMeshLodIndex = 0; #endif // Get from Mesh return mMesh->getEdgeList(mMeshLodIndex); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- bool Entity::hasEdgeList(void) { #if OGRE_NO_MESHLOD - unsigned short mMeshLodIndex = 0; + unsigned short mMeshLodIndex = 0; #endif // check if mesh has an edge list attached // give mesh a chance to built it if scheduled return (mMesh->getEdgeList(mMeshLodIndex) != NULL); } //----------------------------------------------------------------------- - bool Entity::isHardwareAnimationEnabled(void) - { - //find whether the entity has hardware animation for the current active sceme - unsigned short schemeIndex = MaterialManager::getSingleton()._getActiveSchemeIndex(); - SchemeHardwareAnimMap::iterator it = mSchemeHardwareAnim.find(schemeIndex); - if (it == mSchemeHardwareAnim.end()) - { - //evaluate the animation hardware value - it = mSchemeHardwareAnim.insert( - SchemeHardwareAnimMap::value_type(schemeIndex, - calcVertexProcessing())).first; - } - return it->second; - } - - //----------------------------------------------------------------------- + bool Entity::isHardwareAnimationEnabled(void) + { + //find whether the entity has hardware animation for the current active sceme + unsigned short schemeIndex = MaterialManager::getSingleton()._getActiveSchemeIndex(); + SchemeHardwareAnimMap::iterator it = mSchemeHardwareAnim.find(schemeIndex); + if (it == mSchemeHardwareAnim.end()) + { + //evaluate the animation hardware value + it = mSchemeHardwareAnim.insert( + SchemeHardwareAnimMap::value_type(schemeIndex, + calcVertexProcessing())).first; + } + return it->second; + } + + //----------------------------------------------------------------------- void Entity::reevaluateVertexProcessing(void) { - //clear the cache so that the values will be reevaluated - mSchemeHardwareAnim.clear(); - } - //----------------------------------------------------------------------- + //clear the cache so that the values will be reevaluated + mSchemeHardwareAnim.clear(); + } + //----------------------------------------------------------------------- bool Entity::calcVertexProcessing(void) - { + { // init - bool hasHardwareAnimation = false; + bool hasHardwareAnimation = false; bool firstPass = true; SubEntityList::iterator i, iend; iend = mSubEntityList.end(); for (i = mSubEntityList.begin(); i != iend; ++i) { - SubEntity* sub = *i; + SubEntity* sub = *i; const MaterialPtr& m = sub->getMaterial(); // Make sure it's loaded m->load(); Technique* t = m->getBestTechnique(0, sub); - if (!t) - { - // No supported techniques - continue; - } - if (t->getNumPasses() == 0) - { - // No passes, invalid - continue; - } + if (!t) + { + // No supported techniques + continue; + } + if (t->getNumPasses() == 0) + { + // No passes, invalid + continue; + } Pass* p = t->getPass(0); if (p->hasVertexProgram()) { if (mVertexProgramInUse == false) - { - // If one material uses a vertex program, set this flag - // Causes some special processing like forcing a separate light cap - mVertexProgramInUse = true; - - // If shadow renderables already created create their light caps - ShadowRenderableList::iterator si = mShadowRenderables.begin(); - ShadowRenderableList::iterator siend = mShadowRenderables.end(); - for (si = mShadowRenderables.begin(); si != siend; ++si) - { - static_cast(*si)->_createSeparateLightCap(); - } - } - - if (hasSkeleton()) - { - // All materials must support skinning for us to consider using - // hardware animation - if one fails we use software - if (firstPass) - { - hasHardwareAnimation = p->getVertexProgram()->isSkeletalAnimationIncluded(); - firstPass = false; - } - else - { - hasHardwareAnimation = hasHardwareAnimation && - p->getVertexProgram()->isSkeletalAnimationIncluded(); - } - } - - VertexAnimationType animType = VAT_NONE; - if (sub->getSubMesh()->useSharedVertices) - { - animType = mMesh->getSharedVertexDataAnimationType(); - } - else - { - animType = sub->getSubMesh()->getVertexAnimationType(); - } - if (animType == VAT_MORPH) - { - // All materials must support morph animation for us to consider using - // hardware animation - if one fails we use software - if (firstPass) - { - hasHardwareAnimation = p->getVertexProgram()->isMorphAnimationIncluded(); - firstPass = false; - } - else - { - hasHardwareAnimation = hasHardwareAnimation && - p->getVertexProgram()->isMorphAnimationIncluded(); - } - } - else if (animType == VAT_POSE) - { - // All materials must support pose animation for us to consider using - // hardware animation - if one fails we use software - if (firstPass) - { - hasHardwareAnimation = p->getVertexProgram()->isPoseAnimationIncluded(); - if (sub->getSubMesh()->useSharedVertices) - mHardwarePoseCount = p->getVertexProgram()->getNumberOfPosesIncluded(); - else - sub->mHardwarePoseCount = p->getVertexProgram()->getNumberOfPosesIncluded(); - firstPass = false; - } - else - { - hasHardwareAnimation = hasHardwareAnimation && - p->getVertexProgram()->isPoseAnimationIncluded(); - if (sub->getSubMesh()->useSharedVertices) - mHardwarePoseCount = std::max(mHardwarePoseCount, - p->getVertexProgram()->getNumberOfPosesIncluded()); - else - sub->mHardwarePoseCount = std::max(sub->mHardwarePoseCount, - p->getVertexProgram()->getNumberOfPosesIncluded()); - } - } + { + // If one material uses a vertex program, set this flag + // Causes some special processing like forcing a separate light cap + mVertexProgramInUse = true; + + // If shadow renderables already created create their light caps + ShadowRenderableList::iterator si = mShadowRenderables.begin(); + ShadowRenderableList::iterator siend = mShadowRenderables.end(); + for (si = mShadowRenderables.begin(); si != siend; ++si) + { + static_cast(*si)->_createSeparateLightCap(); + } + } + + if (hasSkeleton()) + { + // All materials must support skinning for us to consider using + // hardware animation - if one fails we use software + if (firstPass) + { + hasHardwareAnimation = p->getVertexProgram()->isSkeletalAnimationIncluded(); + firstPass = false; + } + else + { + hasHardwareAnimation = hasHardwareAnimation && + p->getVertexProgram()->isSkeletalAnimationIncluded(); + } + } + + VertexAnimationType animType = VAT_NONE; + if (sub->getSubMesh()->useSharedVertices) + { + animType = mMesh->getSharedVertexDataAnimationType(); + } + else + { + animType = sub->getSubMesh()->getVertexAnimationType(); + } + if (animType == VAT_MORPH) + { + // All materials must support morph animation for us to consider using + // hardware animation - if one fails we use software + if (firstPass) + { + hasHardwareAnimation = p->getVertexProgram()->isMorphAnimationIncluded(); + firstPass = false; + } + else + { + hasHardwareAnimation = hasHardwareAnimation && + p->getVertexProgram()->isMorphAnimationIncluded(); + } + } + else if (animType == VAT_POSE) + { + // All materials must support pose animation for us to consider using + // hardware animation - if one fails we use software + if (firstPass) + { + hasHardwareAnimation = p->getVertexProgram()->isPoseAnimationIncluded(); + if (sub->getSubMesh()->useSharedVertices) + mHardwarePoseCount = p->getVertexProgram()->getNumberOfPosesIncluded(); + else + sub->mHardwarePoseCount = p->getVertexProgram()->getNumberOfPosesIncluded(); + firstPass = false; + } + else + { + hasHardwareAnimation = hasHardwareAnimation && + p->getVertexProgram()->isPoseAnimationIncluded(); + if (sub->getSubMesh()->useSharedVertices) + mHardwarePoseCount = std::max(mHardwarePoseCount, + p->getVertexProgram()->getNumberOfPosesIncluded()); + else + sub->mHardwarePoseCount = std::max(sub->mHardwarePoseCount, + p->getVertexProgram()->getNumberOfPosesIncluded()); + } + } } } @@ -1955,7 +1955,7 @@ namespace Ogre { mFrameAnimationLastUpdated = mAnimationState->getDirtyFrameNumber() - 1; } - return hasHardwareAnimation; + return hasHardwareAnimation; } //----------------------------------------------------------------------- @@ -1981,24 +1981,24 @@ namespace Ogre { assert( static_cast< size_t >( mMeshLodIndex - 1 ) < mLodEntityList.size() && "No LOD EntityList - did you build the manual LODs after creating the entity?"); - Entity* requiredEntity = mLodEntityList[mMeshLodIndex-1]; - if (requiredEntity != this) { - // delegate, we're using manual LOD and not the top lod index - if (hasSkeleton() && mLodEntityList[mMeshLodIndex-1]->hasSkeleton()) - { - // Copy the animation state set to lod entity, we assume the lod - // entity only has a subset animation states - AnimationStateSet* targetState = mLodEntityList[mMeshLodIndex-1]->mAnimationState; - if (mAnimationState != targetState) // only copy if lods have different skeleton instances - { - if (mAnimationState->getDirtyFrameNumber() != targetState->getDirtyFrameNumber()) // only copy if animation was updated - mAnimationState->copyMatchingState(targetState); - } - } - return mLodEntityList[mMeshLodIndex-1]->getShadowVolumeRenderableIterator( - shadowTechnique, light, indexBuffer, indexBufferUsedSize, - extrusionDistance, flags); - } + Entity* requiredEntity = mLodEntityList[mMeshLodIndex-1]; + if (requiredEntity != this) { + // delegate, we're using manual LOD and not the top lod index + if (hasSkeleton() && mLodEntityList[mMeshLodIndex-1]->hasSkeleton()) + { + // Copy the animation state set to lod entity, we assume the lod + // entity only has a subset animation states + AnimationStateSet* targetState = mLodEntityList[mMeshLodIndex-1]->mAnimationState; + if (mAnimationState != targetState) // only copy if lods have different skeleton instances + { + if (mAnimationState->getDirtyFrameNumber() != targetState->getDirtyFrameNumber()) // only copy if animation was updated + mAnimationState->copyMatchingState(targetState); + } + } + return mLodEntityList[mMeshLodIndex-1]->getShadowVolumeRenderableIterator( + shadowTechnique, light, indexBuffer, indexBufferUsedSize, + extrusionDistance, flags); + } } #endif @@ -2033,12 +2033,12 @@ namespace Ogre { // We need to search the edge list for silhouette edges EdgeData* edgeList = getEdgeList(); - if (!edgeList) - { - // we can't get an edge list for some reason, return blank - // really we shouldn't be able to get here, but this is a safeguard - return ShadowRenderableListIterator(mShadowRenderables.begin(), mShadowRenderables.end()); - } + if (!edgeList) + { + // we can't get an edge list for some reason, return blank + // really we shouldn't be able to get here, but this is a safeguard + return ShadowRenderableListIterator(mShadowRenderables.begin(), mShadowRenderables.end()); + } // Init shadow renderable list if required bool init = mShadowRenderables.empty(); @@ -2141,11 +2141,11 @@ namespace Ogre { //----------------------------------------------------------------------- const VertexData* Entity::findBlendedVertexData(const VertexData* orig) { - bool skel = hasSkeleton(); + bool skel = hasSkeleton(); if (orig == mMesh->sharedVertexData) { - return skel? mSkelAnimVertexData : mSoftwareVertexAnimVertexData; + return skel? mSkelAnimVertexData : mSoftwareVertexAnimVertexData; } SubEntityList::iterator i, iend; iend = mSubEntityList.end(); @@ -2154,7 +2154,7 @@ namespace Ogre { SubEntity* se = *i; if (orig == se->getSubMesh()->vertexData) { - return skel? se->_getSkelAnimVertexData() : se->_getSoftwareVertexAnimVertexData(); + return skel? se->_getSkelAnimVertexData() : se->_getSoftwareVertexAnimVertexData(); } } // None found @@ -2217,8 +2217,8 @@ namespace Ogre { iend = mLodEntityList.end(); for (i = mLodEntityList.begin(); i != iend; ++i) { - if(*i != this) - (*i)->_notifyAttached(parent, isTagPoint); + if(*i != this) + (*i)->_notifyAttached(parent, isTagPoint); } #endif } @@ -2269,21 +2269,21 @@ namespace Ogre { vertexData->vertexCount * 2; if (createSeparateLightCap) { - _createSeparateLightCap(); + _createSeparateLightCap(); } } } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void Entity::EntityShadowRenderable::_createSeparateLightCap() - { - if (mLightCap == NULL) - { - // Create child light cap - mLightCap = OGRE_NEW EntityShadowRenderable(mParent, - &mRenderOp.indexData->indexBuffer, mCurrentVertexData, false, mSubEntity, true); - } - } + { + if (mLightCap == NULL) + { + // Create child light cap + mLightCap = OGRE_NEW EntityShadowRenderable(mParent, + &mRenderOp.indexData->indexBuffer, mCurrentVertexData, false, mSubEntity, true); + } + } //----------------------------------------------------------------------- Entity::EntityShadowRenderable::~EntityShadowRenderable() { @@ -2322,12 +2322,12 @@ namespace Ogre { return ShadowRenderable::isVisible(); } } - //----------------------------------------------------------------------- - void Entity::EntityShadowRenderable::rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer) - { - mRenderOp.indexData->indexBuffer = indexBuffer; - if (mLightCap) mLightCap->rebindIndexBuffer(indexBuffer); - } + //----------------------------------------------------------------------- + void Entity::EntityShadowRenderable::rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer) + { + mRenderOp.indexData->indexBuffer = indexBuffer; + if (mLightCap) mLightCap->rebindIndexBuffer(indexBuffer); + } //----------------------------------------------------------------------- void Entity::setRenderQueueGroup(uint8 queueID) @@ -2341,30 +2341,30 @@ namespace Ogre { liend = mLodEntityList.end(); for (li = mLodEntityList.begin(); li != liend; ++li) { - if(*li != this) - (*li)->setRenderQueueGroup(queueID); + if(*li != this) + (*li)->setRenderQueueGroup(queueID); } } #endif } - //----------------------------------------------------------------------- - void Entity::setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) - { - MovableObject::setRenderQueueGroupAndPriority(queueID, priority); + //----------------------------------------------------------------------- + void Entity::setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) + { + MovableObject::setRenderQueueGroupAndPriority(queueID, priority); #if !OGRE_NO_MESHLOD - // Set render queue for all manual LOD entities - if (mMesh->hasManualLodLevel()) - { - LODEntityList::iterator li, liend; - liend = mLodEntityList.end(); - for (li = mLodEntityList.begin(); li != liend; ++li) - { - if(*li != this) - (*li)->setRenderQueueGroupAndPriority(queueID, priority); - } - } + // Set render queue for all manual LOD entities + if (mMesh->hasManualLodLevel()) + { + LODEntityList::iterator li, liend; + liend = mLodEntityList.end(); + for (li = mLodEntityList.begin(); li != liend; ++li) + { + if(*li != this) + (*li)->setRenderQueueGroupAndPriority(queueID, priority); + } + } #endif - } + } //----------------------------------------------------------------------- void Entity::shareSkeletonInstanceWith(Entity* entity) { @@ -2398,8 +2398,8 @@ namespace Ogre { OGRE_DELETE mSkeletonInstance; OGRE_FREE_SIMD(mBoneMatrices, MEMCATEGORY_ANIMATION); OGRE_DELETE mAnimationState; - // using OGRE_FREE since unsigned long is not a destructor - OGRE_FREE(mFrameBonesLastUpdated, MEMCATEGORY_ANIMATION); + // using OGRE_FREE since unsigned long is not a destructor + OGRE_FREE(mFrameBonesLastUpdated, MEMCATEGORY_ANIMATION); mSkeletonInstance = entity->mSkeletonInstance; mNumBoneMatrices = entity->mNumBoneMatrices; mBoneMatrices = entity->mBoneMatrices; @@ -2449,152 +2449,152 @@ namespace Ogre { } } //----------------------------------------------------------------------- - void Entity::refreshAvailableAnimationState(void) - { - mMesh->_refreshAnimationState(mAnimationState); - } - //----------------------------------------------------------------------- - uint32 Entity::getTypeFlags(void) const - { - return SceneManager::ENTITY_TYPE_MASK; - } - //----------------------------------------------------------------------- - VertexData* Entity::getVertexDataForBinding(void) - { - Entity::VertexDataBindChoice c = - chooseVertexDataForBinding(mMesh->getSharedVertexDataAnimationType() != VAT_NONE); - switch(c) - { - case BIND_ORIGINAL: - return mMesh->sharedVertexData; - case BIND_HARDWARE_MORPH: - return mHardwareVertexAnimVertexData; - case BIND_SOFTWARE_MORPH: - return mSoftwareVertexAnimVertexData; - case BIND_SOFTWARE_SKELETAL: - return mSkelAnimVertexData; - }; - // keep compiler happy - return mMesh->sharedVertexData; - } - //----------------------------------------------------------------------- - Entity::VertexDataBindChoice Entity::chooseVertexDataForBinding(bool vertexAnim) - { - if (hasSkeleton()) - { - if (!isHardwareAnimationEnabled()) - { - // all software skeletal binds same vertex data - // may be a 2-stage s/w transform including morph earlier though - return BIND_SOFTWARE_SKELETAL; - } - else if (vertexAnim) - { - // hardware morph animation - return BIND_HARDWARE_MORPH; - } - else - { - // hardware skeletal, no morphing - return BIND_ORIGINAL; - } - } - else if (vertexAnim) - { - // morph only, no skeletal - if (isHardwareAnimationEnabled()) - { - return BIND_HARDWARE_MORPH; - } - else - { - return BIND_SOFTWARE_MORPH; - } - - } - else - { - return BIND_ORIGINAL; - } - - } - //--------------------------------------------------------------------- - void Entity::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - // Visit each SubEntity - for (SubEntityList::iterator i = mSubEntityList.begin(); i != mSubEntityList.end(); ++i) - { - visitor->visit(*i, 0, false); - } + void Entity::refreshAvailableAnimationState(void) + { + mMesh->_refreshAnimationState(mAnimationState); + } + //----------------------------------------------------------------------- + uint32 Entity::getTypeFlags(void) const + { + return SceneManager::ENTITY_TYPE_MASK; + } + //----------------------------------------------------------------------- + VertexData* Entity::getVertexDataForBinding(void) + { + Entity::VertexDataBindChoice c = + chooseVertexDataForBinding(mMesh->getSharedVertexDataAnimationType() != VAT_NONE); + switch(c) + { + case BIND_ORIGINAL: + return mMesh->sharedVertexData; + case BIND_HARDWARE_MORPH: + return mHardwareVertexAnimVertexData; + case BIND_SOFTWARE_MORPH: + return mSoftwareVertexAnimVertexData; + case BIND_SOFTWARE_SKELETAL: + return mSkelAnimVertexData; + }; + // keep compiler happy + return mMesh->sharedVertexData; + } + //----------------------------------------------------------------------- + Entity::VertexDataBindChoice Entity::chooseVertexDataForBinding(bool vertexAnim) + { + if (hasSkeleton()) + { + if (!isHardwareAnimationEnabled()) + { + // all software skeletal binds same vertex data + // may be a 2-stage s/w transform including morph earlier though + return BIND_SOFTWARE_SKELETAL; + } + else if (vertexAnim) + { + // hardware morph animation + return BIND_HARDWARE_MORPH; + } + else + { + // hardware skeletal, no morphing + return BIND_ORIGINAL; + } + } + else if (vertexAnim) + { + // morph only, no skeletal + if (isHardwareAnimationEnabled()) + { + return BIND_HARDWARE_MORPH; + } + else + { + return BIND_SOFTWARE_MORPH; + } + + } + else + { + return BIND_ORIGINAL; + } + + } + //--------------------------------------------------------------------- + void Entity::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + // Visit each SubEntity + for (SubEntityList::iterator i = mSubEntityList.begin(); i != mSubEntityList.end(); ++i) + { + visitor->visit(*i, 0, false); + } #if !OGRE_NO_MESHLOD - // if manual LOD is in use, visit those too - ushort lodi = 1; - for (LODEntityList::iterator e = mLodEntityList.begin(); - e != mLodEntityList.end(); ++e, ++lodi) - { - if(*e != this) { - uint nsub = (*e)->getNumSubEntities(); - for (uint s = 0; s < nsub; ++s) - { - visitor->visit((*e)->getSubEntity(s), lodi, false); - } - } - } + // if manual LOD is in use, visit those too + ushort lodi = 1; + for (LODEntityList::iterator e = mLodEntityList.begin(); + e != mLodEntityList.end(); ++e, ++lodi) + { + if(*e != this) { + uint nsub = (*e)->getNumSubEntities(); + for (uint s = 0; s < nsub; ++s) + { + visitor->visit((*e)->getSubEntity(s), lodi, false); + } + } + } #endif - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - String EntityFactory::FACTORY_TYPE_NAME = "Entity"; - //----------------------------------------------------------------------- - const String& EntityFactory::getType(void) const - { - return FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------- - MovableObject* EntityFactory::createInstanceImpl( const String& name, - const NameValuePairList* params) - { - // must have mesh parameter - MeshPtr pMesh; - if (params != 0) - { - String groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; - - NameValuePairList::const_iterator ni; - - ni = params->find("resourceGroup"); - if (ni != params->end()) - { - groupName = ni->second; - } - - ni = params->find("mesh"); - if (ni != params->end()) - { - // Get mesh (load if required) - pMesh = MeshManager::getSingleton().load( - ni->second, - // autodetect group location - groupName ); - } - - } - if (pMesh.isNull()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "'mesh' parameter required when constructing an Entity.", - "EntityFactory::createInstance"); - } - - return OGRE_NEW Entity(name, pMesh); - - } - //----------------------------------------------------------------------- - void EntityFactory::destroyInstance( MovableObject* obj) - { - OGRE_DELETE obj; - } + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + String EntityFactory::FACTORY_TYPE_NAME = "Entity"; + //----------------------------------------------------------------------- + const String& EntityFactory::getType(void) const + { + return FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------- + MovableObject* EntityFactory::createInstanceImpl( const String& name, + const NameValuePairList* params) + { + // must have mesh parameter + MeshPtr pMesh; + if (params != 0) + { + String groupName = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME; + + NameValuePairList::const_iterator ni; + + ni = params->find("resourceGroup"); + if (ni != params->end()) + { + groupName = ni->second; + } + + ni = params->find("mesh"); + if (ni != params->end()) + { + // Get mesh (load if required) + pMesh = MeshManager::getSingleton().load( + ni->second, + // autodetect group location + groupName ); + } + + } + if (pMesh.isNull()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "'mesh' parameter required when constructing an Entity.", + "EntityFactory::createInstance"); + } + + return OGRE_NEW Entity(name, pMesh); + + } + //----------------------------------------------------------------------- + void EntityFactory::destroyInstance( MovableObject* obj) + { + OGRE_DELETE obj; + } } diff --git a/OgreMain/src/OgreException.cpp b/OgreMain/src/OgreException.cpp index 77a8e127b67..e6b23926413 100644 --- a/OgreMain/src/OgreException.cpp +++ b/OgreMain/src/OgreException.cpp @@ -46,31 +46,31 @@ namespace Ogre { } Exception::Exception(int num, const String& desc, const String& src, - const char* typ, const char* fil, long lin) : + const char* typ, const char* fil, long lin) : line( lin ), number( num ), - typeName(typ), + typeName(typ), description( desc ), source( src ), file( fil ) { // Log this error, mask it from debug though since it may be caught and ignored if(LogManager::getSingletonPtr()) - { + { LogManager::getSingleton().logMessage( - this->getFullDescription(), + this->getFullDescription(), LML_CRITICAL, true); - } + } } Exception::Exception(const Exception& rhs) : line( rhs.line ), - number( rhs.number ), - typeName( rhs.typeName ), - description( rhs.description ), - source( rhs.source ), - file( rhs.file ) + number( rhs.number ), + typeName( rhs.typeName ), + description( rhs.description ), + source( rhs.source ), + file( rhs.file ) { } @@ -81,31 +81,31 @@ namespace Ogre { source = rhs.source; file = rhs.file; line = rhs.line; - typeName = rhs.typeName; + typeName = rhs.typeName; return *this; } const String& Exception::getFullDescription(void) const { - if (fullDesc.empty()) - { + if (fullDesc.empty()) + { - StringStream desc; + StringStream desc; - desc << "OGRE EXCEPTION(" << number << ":" << typeName << "): " - << description - << " in " << source; + desc << "OGRE EXCEPTION(" << number << ":" << typeName << "): " + << description + << " in " << source; - if( line > 0 ) - { - desc << " at " << file << " (line " << line << ")"; - } + if( line > 0 ) + { + desc << " at " << file << " (line " << line << ")"; + } - fullDesc = desc.str(); - } + fullDesc = desc.str(); + } - return fullDesc; + return fullDesc; } int Exception::getNumber(void) const throw() diff --git a/OgreMain/src/OgreExternalTextureSource.cpp b/OgreMain/src/OgreExternalTextureSource.cpp index ec2f3798b05..3b3bb5b9b85 100644 --- a/OgreMain/src/OgreExternalTextureSource.cpp +++ b/OgreMain/src/OgreExternalTextureSource.cpp @@ -28,7 +28,7 @@ THE SOFTWARE. /*************************************************************************** OgreExternalTextureSource.cpp - - Implementation of texture controller class + Implementation of texture controller class ------------------- date : Jan 1 2004 @@ -43,149 +43,149 @@ email : pjcast@yahoo.com namespace Ogre { - //String interface commands for setting some basic commands - ExternalTextureSource::CmdInputFileName ExternalTextureSource::msCmdInputFile; - ExternalTextureSource::CmdFPS ExternalTextureSource::msCmdFramesPerSecond; - ExternalTextureSource::CmdPlayMode ExternalTextureSource::msCmdPlayMode; - ExternalTextureSource::CmdTecPassState ExternalTextureSource::msCmdTecPassState; - - //---------------------------------------------------------------------------------------// - - ExternalTextureSource::ExternalTextureSource() : mTechniqueLevel(0), mPassLevel(0), mStateLevel(0) - { - mInputFileName = "None"; - mDictionaryName = "NotAssigned"; - mUpdateEveryFrame = false; - mFramesPerSecond = 24; - mMode = TextureEffectPause; - } - - //---------------------------------------------------------------------------------------// - - void ExternalTextureSource::addBaseParams() - { - if( mDictionaryName == "NotAssigned" ) + //String interface commands for setting some basic commands + ExternalTextureSource::CmdInputFileName ExternalTextureSource::msCmdInputFile; + ExternalTextureSource::CmdFPS ExternalTextureSource::msCmdFramesPerSecond; + ExternalTextureSource::CmdPlayMode ExternalTextureSource::msCmdPlayMode; + ExternalTextureSource::CmdTecPassState ExternalTextureSource::msCmdTecPassState; + + //---------------------------------------------------------------------------------------// + + ExternalTextureSource::ExternalTextureSource() : mTechniqueLevel(0), mPassLevel(0), mStateLevel(0) + { + mInputFileName = "None"; + mDictionaryName = "NotAssigned"; + mUpdateEveryFrame = false; + mFramesPerSecond = 24; + mMode = TextureEffectPause; + } + + //---------------------------------------------------------------------------------------// + + void ExternalTextureSource::addBaseParams() + { + if( mDictionaryName == "NotAssigned" ) OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, "Plugin " + mPluginName + - " needs to override default mDictionaryName", + " needs to override default mDictionaryName", "ExternalTextureSource::addBaseParams"); - //Create Dictionary Here + //Create Dictionary Here if (createParamDictionary( mDictionaryName )) - { - ParamDictionary* dict = getParamDictionary(); - - dict->addParameter(ParameterDef("filename", - "A source for the texture effect (only certain plugins require this)" - , PT_STRING), - &ExternalTextureSource::msCmdInputFile); - dict->addParameter(ParameterDef("frames_per_second", - "How fast should playback be (only certain plugins use this)" - , PT_INT), - &ExternalTextureSource::msCmdFramesPerSecond); - dict->addParameter(ParameterDef("play_mode", - "How the playback starts(only certain plugins use this)" - , PT_STRING), - &ExternalTextureSource::msCmdPlayMode); - dict->addParameter(ParameterDef("set_T_P_S", - "Set the technique, pass, and state level of this texture_unit (eg. 0 0 0 )" - , PT_STRING), - &ExternalTextureSource::msCmdTecPassState); - } - } - - //---------------------------------------------------------------------------------------// - //*** String Interface Command Class Definitions *****************************************/ - String ExternalTextureSource::CmdInputFileName::doGet(const void* target) const - { - return static_cast(target)->getInputName(); - } - void ExternalTextureSource::CmdInputFileName::doSet(void* target, const String& val) - { - static_cast(target)->setInputName( val ); - } - - //------------------------------------------------------------------------------// - String ExternalTextureSource::CmdFPS::doGet(const void* target) const - { - return StringConverter::toString( - static_cast(target)->getFPS() ); - } - void ExternalTextureSource::CmdFPS::doSet(void* target, const String& val) - { - static_cast(target)->setFPS(StringConverter::parseInt(val)); - } - //------------------------------------------------------------------------------// - String ExternalTextureSource::CmdPlayMode::doGet(const void* target) const - { - eTexturePlayMode eMode = static_cast(target)->getPlayMode(); - String val; - - switch(eMode) - { - case TextureEffectPlay_ASAP: - val = "play"; - break; - case TextureEffectPlay_Looping: - val = "loop"; - break; - case TextureEffectPause: - val = "pause"; - break; - default: - val = "error"; - break; - } - - return val; - } - void ExternalTextureSource::CmdPlayMode::doSet(void* target, const String& val) - { - eTexturePlayMode eMode = TextureEffectPause; - - if( val == "play" ) - eMode = TextureEffectPlay_ASAP; - if( val == "loop" ) - eMode = TextureEffectPlay_Looping; - if( val == "pause" ) - eMode = TextureEffectPause; - - static_cast(target)->setPlayMode( eMode ); - } - - //------------------------------------------------------------------------------// - String ExternalTextureSource::CmdTecPassState::doGet(const void* target) const - { - int t = 0, p = 0, s = 0; - - static_cast(target)->getTextureTecPassStateLevel(t, p, s); - - String ret = StringConverter::toString( t ) + " " - + StringConverter::toString( p ) + " " - + StringConverter::toString( s ); - - return ret; - } - - void ExternalTextureSource::CmdTecPassState::doSet(void* target, const String& val) - { - int t = 0, p = 0, s = 0; - - StringVector vecparams = StringUtil::split(val, " \t"); - - if( vecparams.size() == 3 ) - { - t = StringConverter::parseInt( vecparams[0] ); - p = StringConverter::parseInt( vecparams[1] ); - s = StringConverter::parseInt( vecparams[2] ); - } - else - { - LogManager::getSingleton().logMessage("Texture controller had problems extracting technique, pass, and state level... Default to 0, 0, 0", LML_CRITICAL); - t = p = s = 0; - } - - static_cast(target)->setTextureTecPassStateLevel(t,p,s); - } + { + ParamDictionary* dict = getParamDictionary(); + + dict->addParameter(ParameterDef("filename", + "A source for the texture effect (only certain plugins require this)" + , PT_STRING), + &ExternalTextureSource::msCmdInputFile); + dict->addParameter(ParameterDef("frames_per_second", + "How fast should playback be (only certain plugins use this)" + , PT_INT), + &ExternalTextureSource::msCmdFramesPerSecond); + dict->addParameter(ParameterDef("play_mode", + "How the playback starts(only certain plugins use this)" + , PT_STRING), + &ExternalTextureSource::msCmdPlayMode); + dict->addParameter(ParameterDef("set_T_P_S", + "Set the technique, pass, and state level of this texture_unit (eg. 0 0 0 )" + , PT_STRING), + &ExternalTextureSource::msCmdTecPassState); + } + } + + //---------------------------------------------------------------------------------------// + //*** String Interface Command Class Definitions *****************************************/ + String ExternalTextureSource::CmdInputFileName::doGet(const void* target) const + { + return static_cast(target)->getInputName(); + } + void ExternalTextureSource::CmdInputFileName::doSet(void* target, const String& val) + { + static_cast(target)->setInputName( val ); + } + + //------------------------------------------------------------------------------// + String ExternalTextureSource::CmdFPS::doGet(const void* target) const + { + return StringConverter::toString( + static_cast(target)->getFPS() ); + } + void ExternalTextureSource::CmdFPS::doSet(void* target, const String& val) + { + static_cast(target)->setFPS(StringConverter::parseInt(val)); + } + //------------------------------------------------------------------------------// + String ExternalTextureSource::CmdPlayMode::doGet(const void* target) const + { + eTexturePlayMode eMode = static_cast(target)->getPlayMode(); + String val; + + switch(eMode) + { + case TextureEffectPlay_ASAP: + val = "play"; + break; + case TextureEffectPlay_Looping: + val = "loop"; + break; + case TextureEffectPause: + val = "pause"; + break; + default: + val = "error"; + break; + } + + return val; + } + void ExternalTextureSource::CmdPlayMode::doSet(void* target, const String& val) + { + eTexturePlayMode eMode = TextureEffectPause; + + if( val == "play" ) + eMode = TextureEffectPlay_ASAP; + if( val == "loop" ) + eMode = TextureEffectPlay_Looping; + if( val == "pause" ) + eMode = TextureEffectPause; + + static_cast(target)->setPlayMode( eMode ); + } + + //------------------------------------------------------------------------------// + String ExternalTextureSource::CmdTecPassState::doGet(const void* target) const + { + int t = 0, p = 0, s = 0; + + static_cast(target)->getTextureTecPassStateLevel(t, p, s); + + String ret = StringConverter::toString( t ) + " " + + StringConverter::toString( p ) + " " + + StringConverter::toString( s ); + + return ret; + } + + void ExternalTextureSource::CmdTecPassState::doSet(void* target, const String& val) + { + int t = 0, p = 0, s = 0; + + StringVector vecparams = StringUtil::split(val, " \t"); + + if( vecparams.size() == 3 ) + { + t = StringConverter::parseInt( vecparams[0] ); + p = StringConverter::parseInt( vecparams[1] ); + s = StringConverter::parseInt( vecparams[2] ); + } + else + { + LogManager::getSingleton().logMessage("Texture controller had problems extracting technique, pass, and state level... Default to 0, 0, 0", LML_CRITICAL); + t = p = s = 0; + } + + static_cast(target)->setTextureTecPassStateLevel(t,p,s); + } } diff --git a/OgreMain/src/OgreExternalTextureSourceManager.cpp b/OgreMain/src/OgreExternalTextureSourceManager.cpp index 47ece6f1658..2fc8ddda014 100644 --- a/OgreMain/src/OgreExternalTextureSourceManager.cpp +++ b/OgreMain/src/OgreExternalTextureSourceManager.cpp @@ -28,7 +28,7 @@ THE SOFTWARE. /*************************************************************************** OgreExternalTextureSourceManager.cpp - - Implementation of the manager class + Implementation of the manager class ------------------- date : Jan 1 2004 @@ -42,7 +42,7 @@ email : pjcast@yahoo.com namespace Ogre { - //**************************************************************************************** + //**************************************************************************************** template<> ExternalTextureSourceManager* Singleton::msSingleton = 0; ExternalTextureSourceManager* ExternalTextureSourceManager::getSingletonPtr(void) { @@ -52,93 +52,93 @@ namespace Ogre { assert( msSingleton ); return ( *msSingleton ); } - //**************************************************************************************** - - //**************************************************************************************** - ExternalTextureSourceManager::ExternalTextureSourceManager() - { - mCurrExternalTextureSource = 0; - } - - //**************************************************************************************** - ExternalTextureSourceManager::~ExternalTextureSourceManager() - { - mTextureSystems.clear(); - } - - //**************************************************************************************** - - void ExternalTextureSourceManager::setCurrentPlugIn( const String& sTexturePlugInType ) - { - TextureSystemList::iterator i; - - for( i = mTextureSystems.begin(); i != mTextureSystems.end(); ++i ) - { - if( i->first == sTexturePlugInType ) - { - mCurrExternalTextureSource = i->second; - mCurrExternalTextureSource->initialise(); //Now call overridden Init function - return; - } - } - mCurrExternalTextureSource = 0; - LogManager::getSingleton().logMessage( "ExternalTextureSourceManager::SetCurrentPlugIn(ENUM) failed setting texture plugin ", LML_CRITICAL); - } - - //**************************************************************************************** - void ExternalTextureSourceManager::destroyAdvancedTexture( const String& sTextureName, - const String& groupName ) - { - TextureSystemList::iterator i; - for( i = mTextureSystems.begin(); i != mTextureSystems.end(); ++i ) - { - //Broadcast to every registered System... Only the true one will destroy texture - i->second->destroyAdvancedTexture( sTextureName, groupName ); - } - } - - //**************************************************************************************** - void ExternalTextureSourceManager::setExternalTextureSource( const String& sTexturePlugInType, ExternalTextureSource* pTextureSystem ) - { - LogManager::getSingleton().logMessage( "Registering Texture Controller: Type = " - + sTexturePlugInType + " Name = " + pTextureSystem->getPluginStringName()); - - TextureSystemList::iterator i; - - for( i = mTextureSystems.begin(); i != mTextureSystems.end(); ++i ) - { - if( i->first == sTexturePlugInType ) - { - LogManager::getSingleton().logMessage( "Shutting Down Texture Controller: " - + i->second->getPluginStringName() - + " To be replaced by: " - + pTextureSystem->getPluginStringName()); - - i->second->shutDown(); //Only one plugIn of Sent Type can be registered at a time - //so shut down old plugin before starting new plugin - i->second = pTextureSystem; - // **Moved this line b/c Rendersystem needs to be selected before things - // such as framelistners can be added - // pTextureSystem->Initialise(); - return; - } - } - mTextureSystems[sTexturePlugInType] = pTextureSystem; //If we got here then add it to map - } - - //**************************************************************************************** - ExternalTextureSource* ExternalTextureSourceManager::getExternalTextureSource( const String& sTexturePlugInType ) - { - TextureSystemList::iterator i; - for( i = mTextureSystems.begin(); i != mTextureSystems.end(); ++i ) - { - if( i->first == sTexturePlugInType ) - return i->second; - } - return 0; - } - - //**************************************************************************************** + //**************************************************************************************** + + //**************************************************************************************** + ExternalTextureSourceManager::ExternalTextureSourceManager() + { + mCurrExternalTextureSource = 0; + } + + //**************************************************************************************** + ExternalTextureSourceManager::~ExternalTextureSourceManager() + { + mTextureSystems.clear(); + } + + //**************************************************************************************** + + void ExternalTextureSourceManager::setCurrentPlugIn( const String& sTexturePlugInType ) + { + TextureSystemList::iterator i; + + for( i = mTextureSystems.begin(); i != mTextureSystems.end(); ++i ) + { + if( i->first == sTexturePlugInType ) + { + mCurrExternalTextureSource = i->second; + mCurrExternalTextureSource->initialise(); //Now call overridden Init function + return; + } + } + mCurrExternalTextureSource = 0; + LogManager::getSingleton().logMessage( "ExternalTextureSourceManager::SetCurrentPlugIn(ENUM) failed setting texture plugin ", LML_CRITICAL); + } + + //**************************************************************************************** + void ExternalTextureSourceManager::destroyAdvancedTexture( const String& sTextureName, + const String& groupName ) + { + TextureSystemList::iterator i; + for( i = mTextureSystems.begin(); i != mTextureSystems.end(); ++i ) + { + //Broadcast to every registered System... Only the true one will destroy texture + i->second->destroyAdvancedTexture( sTextureName, groupName ); + } + } + + //**************************************************************************************** + void ExternalTextureSourceManager::setExternalTextureSource( const String& sTexturePlugInType, ExternalTextureSource* pTextureSystem ) + { + LogManager::getSingleton().logMessage( "Registering Texture Controller: Type = " + + sTexturePlugInType + " Name = " + pTextureSystem->getPluginStringName()); + + TextureSystemList::iterator i; + + for( i = mTextureSystems.begin(); i != mTextureSystems.end(); ++i ) + { + if( i->first == sTexturePlugInType ) + { + LogManager::getSingleton().logMessage( "Shutting Down Texture Controller: " + + i->second->getPluginStringName() + + " To be replaced by: " + + pTextureSystem->getPluginStringName()); + + i->second->shutDown(); //Only one plugIn of Sent Type can be registered at a time + //so shut down old plugin before starting new plugin + i->second = pTextureSystem; + // **Moved this line b/c Rendersystem needs to be selected before things + // such as framelistners can be added + // pTextureSystem->Initialise(); + return; + } + } + mTextureSystems[sTexturePlugInType] = pTextureSystem; //If we got here then add it to map + } + + //**************************************************************************************** + ExternalTextureSource* ExternalTextureSourceManager::getExternalTextureSource( const String& sTexturePlugInType ) + { + TextureSystemList::iterator i; + for( i = mTextureSystems.begin(); i != mTextureSystems.end(); ++i ) + { + if( i->first == sTexturePlugInType ) + return i->second; + } + return 0; + } + + //**************************************************************************************** } //End Ogre Namespace diff --git a/OgreMain/src/OgreFileSystem.cpp b/OgreMain/src/OgreFileSystem.cpp index b05886cadf0..432f61ab432 100644 --- a/OgreMain/src/OgreFileSystem.cpp +++ b/OgreMain/src/OgreFileSystem.cpp @@ -45,7 +45,7 @@ THE SOFTWARE. #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT # define WIN32_LEAN_AND_MEAN # if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif # include # include @@ -54,16 +54,16 @@ THE SOFTWARE. namespace Ogre { - bool FileSystemArchive::msIgnoreHidden = true; + bool FileSystemArchive::msIgnoreHidden = true; //----------------------------------------------------------------------- FileSystemArchive::FileSystemArchive(const String& name, const String& archType, bool readOnly ) : Archive(name, archType) { - // Even failed attempt to write to read only location violates Apple AppStore validation process. - // And successful writing to some probe file does not prove that whole location with subfolders - // is writable. Therefore we accept read only flag from outside and do not try to be too smart. - mReadOnly = readOnly; + // Even failed attempt to write to read only location violates Apple AppStore validation process. + // And successful writing to some probe file does not prove that whole location with subfolders + // is writable. Therefore we accept read only flag from outside and do not try to be too smart. + mReadOnly = readOnly; } //----------------------------------------------------------------------- bool FileSystemArchive::isCaseSensitive(void) const @@ -120,7 +120,7 @@ namespace Ogre { while (lHandle != -1 && res != -1) { if ((dirs == ((tagData.attrib & _A_SUBDIR) != 0)) && - ( !msIgnoreHidden || (tagData.attrib & _A_HIDDEN) == 0 ) && + ( !msIgnoreHidden || (tagData.attrib & _A_HIDDEN) == 0 ) && (!dirs || !is_reserved_dir (tagData.name))) { if (simpleList) @@ -169,7 +169,7 @@ namespace Ogre { while (lHandle != -1 && res != -1) { if ((tagData.attrib & _A_SUBDIR) && - ( !msIgnoreHidden || (tagData.attrib & _A_HIDDEN) == 0 ) && + ( !msIgnoreHidden || (tagData.attrib & _A_HIDDEN) == 0 ) && !is_reserved_dir (tagData.name)) { // recurse @@ -192,7 +192,7 @@ namespace Ogre { //----------------------------------------------------------------------- void FileSystemArchive::load() { - // nothing to do here + // nothing to do here } //----------------------------------------------------------------------- void FileSystemArchive::unload() @@ -202,21 +202,21 @@ namespace Ogre { //----------------------------------------------------------------------- DataStreamPtr FileSystemArchive::open(const String& filename, bool readOnly) const { - String full_path = concatenate_path(mName, filename); + String full_path = concatenate_path(mName, filename); - // Use filesystem to determine size - // (quicker than streaming to the end and back) - struct stat tagStat; - int ret = stat(full_path.c_str(), &tagStat); - assert(ret == 0 && "Problem getting file size" ); + // Use filesystem to determine size + // (quicker than streaming to the end and back) + struct stat tagStat; + int ret = stat(full_path.c_str(), &tagStat); + assert(ret == 0 && "Problem getting file size" ); (void)ret; // Silence warning - // Always open in binary mode - // Also, always include reading - std::ios::openmode mode = std::ios::in | std::ios::binary; - std::istream* baseStream = 0; - std::ifstream* roStream = 0; - std::fstream* rwStream = 0; + // Always open in binary mode + // Also, always include reading + std::ios::openmode mode = std::ios::in | std::ios::binary; + std::istream* baseStream = 0; + std::ifstream* roStream = 0; + std::fstream* rwStream = 0; if (!readOnly && isReadOnly()) { @@ -225,99 +225,99 @@ namespace Ogre { "FileSystemArchive::open"); } - if (!readOnly) - { - mode |= std::ios::out; - rwStream = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); - rwStream->open(full_path.c_str(), mode); - baseStream = rwStream; - } - else - { - roStream = OGRE_NEW_T(std::ifstream, MEMCATEGORY_GENERAL)(); - roStream->open(full_path.c_str(), mode); - baseStream = roStream; - } - - - // Should check ensure open succeeded, in case fail for some reason. - if (baseStream->fail()) - { - OGRE_DELETE_T(roStream, basic_ifstream, MEMCATEGORY_GENERAL); - OGRE_DELETE_T(rwStream, basic_fstream, MEMCATEGORY_GENERAL); - OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, - "Cannot open file: " + filename, - "FileSystemArchive::open"); - } - - /// Construct return stream, tell it to delete on destroy - FileStreamDataStream* stream = 0; - if (rwStream) - { - // use the writeable stream - stream = OGRE_NEW FileStreamDataStream(filename, - rwStream, (size_t)tagStat.st_size, true); - } - else - { - // read-only stream - stream = OGRE_NEW FileStreamDataStream(filename, - roStream, (size_t)tagStat.st_size, true); - } - return DataStreamPtr(stream); + if (!readOnly) + { + mode |= std::ios::out; + rwStream = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); + rwStream->open(full_path.c_str(), mode); + baseStream = rwStream; + } + else + { + roStream = OGRE_NEW_T(std::ifstream, MEMCATEGORY_GENERAL)(); + roStream->open(full_path.c_str(), mode); + baseStream = roStream; + } + + + // Should check ensure open succeeded, in case fail for some reason. + if (baseStream->fail()) + { + OGRE_DELETE_T(roStream, basic_ifstream, MEMCATEGORY_GENERAL); + OGRE_DELETE_T(rwStream, basic_fstream, MEMCATEGORY_GENERAL); + OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, + "Cannot open file: " + filename, + "FileSystemArchive::open"); + } + + /// Construct return stream, tell it to delete on destroy + FileStreamDataStream* stream = 0; + if (rwStream) + { + // use the writeable stream + stream = OGRE_NEW FileStreamDataStream(filename, + rwStream, (size_t)tagStat.st_size, true); + } + else + { + // read-only stream + stream = OGRE_NEW FileStreamDataStream(filename, + roStream, (size_t)tagStat.st_size, true); + } + return DataStreamPtr(stream); + } + //--------------------------------------------------------------------- + DataStreamPtr FileSystemArchive::create(const String& filename) const + { + if (isReadOnly()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Cannot create a file in a read-only archive", + "FileSystemArchive::remove"); + } + + String full_path = concatenate_path(mName, filename); + + // Always open in binary mode + // Also, always include reading + std::ios::openmode mode = std::ios::out | std::ios::binary; + std::fstream* rwStream = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); + rwStream->open(full_path.c_str(), mode); + + // Should check ensure open succeeded, in case fail for some reason. + if (rwStream->fail()) + { + OGRE_DELETE_T(rwStream, basic_fstream, MEMCATEGORY_GENERAL); + OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, + "Cannot open file: " + filename, + "FileSystemArchive::create"); + } + + /// Construct return stream, tell it to delete on destroy + FileStreamDataStream* stream = OGRE_NEW FileStreamDataStream(filename, + rwStream, 0, true); + + return DataStreamPtr(stream); + } + //--------------------------------------------------------------------- + void FileSystemArchive::remove(const String& filename) const + { + if (isReadOnly()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Cannot remove a file from a read-only archive", + "FileSystemArchive::remove"); + } + String full_path = concatenate_path(mName, filename); + ::remove(full_path.c_str()); + } - //--------------------------------------------------------------------- - DataStreamPtr FileSystemArchive::create(const String& filename) const - { - if (isReadOnly()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Cannot create a file in a read-only archive", - "FileSystemArchive::remove"); - } - - String full_path = concatenate_path(mName, filename); - - // Always open in binary mode - // Also, always include reading - std::ios::openmode mode = std::ios::out | std::ios::binary; - std::fstream* rwStream = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); - rwStream->open(full_path.c_str(), mode); - - // Should check ensure open succeeded, in case fail for some reason. - if (rwStream->fail()) - { - OGRE_DELETE_T(rwStream, basic_fstream, MEMCATEGORY_GENERAL); - OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, - "Cannot open file: " + filename, - "FileSystemArchive::create"); - } - - /// Construct return stream, tell it to delete on destroy - FileStreamDataStream* stream = OGRE_NEW FileStreamDataStream(filename, - rwStream, 0, true); - - return DataStreamPtr(stream); - } - //--------------------------------------------------------------------- - void FileSystemArchive::remove(const String& filename) const - { - if (isReadOnly()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Cannot remove a file from a read-only archive", - "FileSystemArchive::remove"); - } - String full_path = concatenate_path(mName, filename); - ::remove(full_path.c_str()); - - } //----------------------------------------------------------------------- StringVectorPtr FileSystemArchive::list(bool recursive, bool dirs) { - // directory change requires locking due to saved returns - // Note that we have to tell the SharedPtr to use OGRE_DELETE_T not OGRE_DELETE by passing category - StringVectorPtr ret(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); + // directory change requires locking due to saved returns + // Note that we have to tell the SharedPtr to use OGRE_DELETE_T not OGRE_DELETE by passing category + StringVectorPtr ret(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); findFiles("*", recursive, dirs, ret.getPointer(), 0); @@ -326,7 +326,7 @@ namespace Ogre { //----------------------------------------------------------------------- FileInfoListPtr FileSystemArchive::listFileInfo(bool recursive, bool dirs) { - // Note that we have to tell the SharedPtr to use OGRE_DELETE_T not OGRE_DELETE by passing category + // Note that we have to tell the SharedPtr to use OGRE_DELETE_T not OGRE_DELETE by passing category FileInfoListPtr ret(OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); findFiles("*", recursive, dirs, 0, ret.getPointer()); @@ -337,8 +337,8 @@ namespace Ogre { StringVectorPtr FileSystemArchive::find(const String& pattern, bool recursive, bool dirs) { - // Note that we have to tell the SharedPtr to use OGRE_DELETE_T not OGRE_DELETE by passing category - StringVectorPtr ret(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); + // Note that we have to tell the SharedPtr to use OGRE_DELETE_T not OGRE_DELETE by passing category + StringVectorPtr ret(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); findFiles(pattern, recursive, dirs, ret.getPointer(), 0); @@ -349,57 +349,57 @@ namespace Ogre { FileInfoListPtr FileSystemArchive::findFileInfo(const String& pattern, bool recursive, bool dirs) const { - // Note that we have to tell the SharedPtr to use OGRE_DELETE_T not OGRE_DELETE by passing category - FileInfoListPtr ret(OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); + // Note that we have to tell the SharedPtr to use OGRE_DELETE_T not OGRE_DELETE by passing category + FileInfoListPtr ret(OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); findFiles(pattern, recursive, dirs, 0, ret.getPointer()); return ret; } //----------------------------------------------------------------------- - bool FileSystemArchive::exists(const String& filename) - { + bool FileSystemArchive::exists(const String& filename) + { String full_path = concatenate_path(mName, filename); struct stat tagStat; bool ret = (stat(full_path.c_str(), &tagStat) == 0); - // stat will return true if the filename is absolute, but we need to check - // the file is actually in this archive + // stat will return true if the filename is absolute, but we need to check + // the file is actually in this archive if (ret && is_absolute_path(filename.c_str())) - { - // only valid if full path starts with our base + { + // only valid if full path starts with our base #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT - // case insensitive on windows - String lowerCaseName = mName; - StringUtil::toLowerCase(lowerCaseName); - ret = Ogre::StringUtil::startsWith(full_path, lowerCaseName, true); + // case insensitive on windows + String lowerCaseName = mName; + StringUtil::toLowerCase(lowerCaseName); + ret = Ogre::StringUtil::startsWith(full_path, lowerCaseName, true); #else - // case sensitive - ret = Ogre::StringUtil::startsWith(full_path, mName, false); + // case sensitive + ret = Ogre::StringUtil::startsWith(full_path, mName, false); #endif - } - - return ret; - } - //--------------------------------------------------------------------- - time_t FileSystemArchive::getModifiedTime(const String& filename) - { - String full_path = concatenate_path(mName, filename); - - struct stat tagStat; - bool ret = (stat(full_path.c_str(), &tagStat) == 0); - - if (ret) - { - return tagStat.st_mtime; - } - else - { - return 0; - } - - } + } + + return ret; + } + //--------------------------------------------------------------------- + time_t FileSystemArchive::getModifiedTime(const String& filename) + { + String full_path = concatenate_path(mName, filename); + + struct stat tagStat; + bool ret = (stat(full_path.c_str(), &tagStat) == 0); + + if (ret) + { + return tagStat.st_mtime; + } + else + { + return 0; + } + + } //----------------------------------------------------------------------- const String& FileSystemArchiveFactory::getType(void) const { diff --git a/OgreMain/src/OgreFreeImageCodec.cpp b/OgreMain/src/OgreFreeImageCodec.cpp index 8c069bfde82..c5c25a398e4 100644 --- a/OgreMain/src/OgreFreeImageCodec.cpp +++ b/OgreMain/src/OgreFreeImageCodec.cpp @@ -36,8 +36,8 @@ THE SOFTWARE. // freeimage 3.9.1~3.11.0 interoperability fix #ifndef FREEIMAGE_COLORORDER // we have freeimage 3.9.1, define these symbols in such way as 3.9.1 really work (do not use 3.11.0 definition, as color order was changed between these two versions on Apple systems) -#define FREEIMAGE_COLORORDER_BGR 0 -#define FREEIMAGE_COLORORDER_RGB 1 +#define FREEIMAGE_COLORORDER_BGR 0 +#define FREEIMAGE_COLORORDER_RGB 1 #if defined(FREEIMAGE_BIGENDIAN) #define FREEIMAGE_COLORORDER FREEIMAGE_COLORORDER_RGB #else @@ -47,342 +47,342 @@ THE SOFTWARE. namespace Ogre { - FreeImageCodec::RegisteredCodecList FreeImageCodec::msCodecList; - //--------------------------------------------------------------------- - void FreeImageLoadErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) - { - // Callback method as required by FreeImage to report problems - const char* typeName = FreeImage_GetFormatFromFIF(fif); - if (typeName) - { - LogManager::getSingleton().stream() - << "FreeImage error: '" << message << "' when loading format " - << typeName; - } - else - { - LogManager::getSingleton().stream() - << "FreeImage error: '" << message << "'"; - } - - } - //--------------------------------------------------------------------- - void FreeImageSaveErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) - { - // Callback method as required by FreeImage to report problems - OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, - message, "FreeImageCodec::save") - } - //--------------------------------------------------------------------- - void FreeImageCodec::startup(void) - { - FreeImage_Initialise(false); - - LogManager::getSingleton().logMessage( - LML_NORMAL, - "FreeImage version: " + String(FreeImage_GetVersion())); - LogManager::getSingleton().logMessage( - LML_NORMAL, - FreeImage_GetCopyrightMessage()); - - // Register codecs - StringStream strExt; - strExt << "Supported formats: "; - bool first = true; - for (int i = 0; i < FreeImage_GetFIFCount(); ++i) - { - - // Skip DDS codec since FreeImage does not have the option - // to keep DXT data compressed, we'll use our own codec - if ((FREE_IMAGE_FORMAT)i == FIF_DDS) - continue; - - String exts(FreeImage_GetFIFExtensionList((FREE_IMAGE_FORMAT)i)); - if (!first) - { - strExt << ","; - } - first = false; - strExt << exts; - - // Pull off individual formats (separated by comma by FI) - StringVector extsVector = StringUtil::split(exts, ","); - for (StringVector::iterator v = extsVector.begin(); v != extsVector.end(); ++v) - { - // FreeImage 3.13 lists many formats twice: once under their own codec and - // once under the "RAW" codec, which is listed last. Avoid letting the RAW override - // the dedicated codec! - if (!Codec::isCodecRegistered(*v)) - { - ImageCodec* codec = OGRE_NEW FreeImageCodec(*v, i); - msCodecList.push_back(codec); - Codec::registerCodec(codec); - } - } - } - LogManager::getSingleton().logMessage( - LML_NORMAL, - strExt.str()); - - // Set error handler - FreeImage_SetOutputMessage(FreeImageLoadErrorHandler); - - - - - } - //--------------------------------------------------------------------- - void FreeImageCodec::shutdown(void) - { - FreeImage_DeInitialise(); - - for (RegisteredCodecList::iterator i = msCodecList.begin(); - i != msCodecList.end(); ++i) - { - Codec::unregisterCodec(*i); - OGRE_DELETE *i; - } - msCodecList.clear(); - - } - //--------------------------------------------------------------------- + FreeImageCodec::RegisteredCodecList FreeImageCodec::msCodecList; + //--------------------------------------------------------------------- + void FreeImageLoadErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) + { + // Callback method as required by FreeImage to report problems + const char* typeName = FreeImage_GetFormatFromFIF(fif); + if (typeName) + { + LogManager::getSingleton().stream() + << "FreeImage error: '" << message << "' when loading format " + << typeName; + } + else + { + LogManager::getSingleton().stream() + << "FreeImage error: '" << message << "'"; + } + + } + //--------------------------------------------------------------------- + void FreeImageSaveErrorHandler(FREE_IMAGE_FORMAT fif, const char *message) + { + // Callback method as required by FreeImage to report problems + OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, + message, "FreeImageCodec::save") + } + //--------------------------------------------------------------------- + void FreeImageCodec::startup(void) + { + FreeImage_Initialise(false); + + LogManager::getSingleton().logMessage( + LML_NORMAL, + "FreeImage version: " + String(FreeImage_GetVersion())); + LogManager::getSingleton().logMessage( + LML_NORMAL, + FreeImage_GetCopyrightMessage()); + + // Register codecs + StringStream strExt; + strExt << "Supported formats: "; + bool first = true; + for (int i = 0; i < FreeImage_GetFIFCount(); ++i) + { + + // Skip DDS codec since FreeImage does not have the option + // to keep DXT data compressed, we'll use our own codec + if ((FREE_IMAGE_FORMAT)i == FIF_DDS) + continue; + + String exts(FreeImage_GetFIFExtensionList((FREE_IMAGE_FORMAT)i)); + if (!first) + { + strExt << ","; + } + first = false; + strExt << exts; + + // Pull off individual formats (separated by comma by FI) + StringVector extsVector = StringUtil::split(exts, ","); + for (StringVector::iterator v = extsVector.begin(); v != extsVector.end(); ++v) + { + // FreeImage 3.13 lists many formats twice: once under their own codec and + // once under the "RAW" codec, which is listed last. Avoid letting the RAW override + // the dedicated codec! + if (!Codec::isCodecRegistered(*v)) + { + ImageCodec* codec = OGRE_NEW FreeImageCodec(*v, i); + msCodecList.push_back(codec); + Codec::registerCodec(codec); + } + } + } + LogManager::getSingleton().logMessage( + LML_NORMAL, + strExt.str()); + + // Set error handler + FreeImage_SetOutputMessage(FreeImageLoadErrorHandler); + + + + + } + //--------------------------------------------------------------------- + void FreeImageCodec::shutdown(void) + { + FreeImage_DeInitialise(); + + for (RegisteredCodecList::iterator i = msCodecList.begin(); + i != msCodecList.end(); ++i) + { + Codec::unregisterCodec(*i); + OGRE_DELETE *i; + } + msCodecList.clear(); + + } + //--------------------------------------------------------------------- FreeImageCodec::FreeImageCodec(const String &type, unsigned int fiType): mType(type), mFreeImageType(fiType) { } - //--------------------------------------------------------------------- - FIBITMAP* FreeImageCodec::encodeBitmap(MemoryDataStreamPtr& input, CodecDataPtr& pData) const - { - FIBITMAP* ret = 0; - - ImageData* pImgData = static_cast< ImageData * >( pData.getPointer() ); - PixelBox src(pImgData->width, pImgData->height, pImgData->depth, pImgData->format, input->getPtr()); - - // The required format, which will adjust to the format - // actually supported by FreeImage. - PixelFormat requiredFormat = pImgData->format; - - // determine the settings - FREE_IMAGE_TYPE imageType; - PixelFormat determiningFormat = pImgData->format; - - switch(determiningFormat) - { - case PF_R5G6B5: - case PF_B5G6R5: - case PF_R8G8B8: - case PF_B8G8R8: - case PF_A8R8G8B8: - case PF_X8R8G8B8: - case PF_A8B8G8R8: - case PF_X8B8G8R8: - case PF_B8G8R8A8: - case PF_R8G8B8A8: - case PF_A4L4: - case PF_BYTE_LA: - case PF_R3G3B2: - case PF_A4R4G4B4: - case PF_A1R5G5B5: - case PF_A2R10G10B10: - case PF_A2B10G10R10: - // I'd like to be able to use r/g/b masks to get FreeImage to load the data - // in it's existing format, but that doesn't work, FreeImage needs to have - // data in RGB[A] (big endian) and BGR[A] (little endian), always. - if (PixelUtil::hasAlpha(determiningFormat)) - { + //--------------------------------------------------------------------- + FIBITMAP* FreeImageCodec::encodeBitmap(MemoryDataStreamPtr& input, CodecDataPtr& pData) const + { + FIBITMAP* ret = 0; + + ImageData* pImgData = static_cast< ImageData * >( pData.getPointer() ); + PixelBox src(pImgData->width, pImgData->height, pImgData->depth, pImgData->format, input->getPtr()); + + // The required format, which will adjust to the format + // actually supported by FreeImage. + PixelFormat requiredFormat = pImgData->format; + + // determine the settings + FREE_IMAGE_TYPE imageType; + PixelFormat determiningFormat = pImgData->format; + + switch(determiningFormat) + { + case PF_R5G6B5: + case PF_B5G6R5: + case PF_R8G8B8: + case PF_B8G8R8: + case PF_A8R8G8B8: + case PF_X8R8G8B8: + case PF_A8B8G8R8: + case PF_X8B8G8R8: + case PF_B8G8R8A8: + case PF_R8G8B8A8: + case PF_A4L4: + case PF_BYTE_LA: + case PF_R3G3B2: + case PF_A4R4G4B4: + case PF_A1R5G5B5: + case PF_A2R10G10B10: + case PF_A2B10G10R10: + // I'd like to be able to use r/g/b masks to get FreeImage to load the data + // in it's existing format, but that doesn't work, FreeImage needs to have + // data in RGB[A] (big endian) and BGR[A] (little endian), always. + if (PixelUtil::hasAlpha(determiningFormat)) + { #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB - requiredFormat = PF_BYTE_RGBA; + requiredFormat = PF_BYTE_RGBA; #else - requiredFormat = PF_BYTE_BGRA; + requiredFormat = PF_BYTE_BGRA; #endif - } - else - { + } + else + { #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB - requiredFormat = PF_BYTE_RGB; + requiredFormat = PF_BYTE_RGB; #else - requiredFormat = PF_BYTE_BGR; + requiredFormat = PF_BYTE_BGR; #endif - } - // fall through - case PF_L8: - case PF_A8: - imageType = FIT_BITMAP; - break; - - case PF_L16: - imageType = FIT_UINT16; - break; - - case PF_SHORT_GR: - requiredFormat = PF_SHORT_RGB; - // fall through - case PF_SHORT_RGB: - imageType = FIT_RGB16; - break; - - case PF_SHORT_RGBA: - imageType = FIT_RGBA16; - break; - - case PF_FLOAT16_R: - requiredFormat = PF_FLOAT32_R; - // fall through - case PF_FLOAT32_R: - imageType = FIT_FLOAT; - break; - - case PF_FLOAT16_GR: - case PF_FLOAT16_RGB: - case PF_FLOAT32_GR: - requiredFormat = PF_FLOAT32_RGB; - // fall through - case PF_FLOAT32_RGB: - imageType = FIT_RGBF; - break; - - case PF_FLOAT16_RGBA: - requiredFormat = PF_FLOAT32_RGBA; - // fall through - case PF_FLOAT32_RGBA: - imageType = FIT_RGBAF; - break; - - default: - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Invalid image format", "FreeImageCodec::encode"); - }; - - // Check support for this image type & bit depth - if (!FreeImage_FIFSupportsExportType((FREE_IMAGE_FORMAT)mFreeImageType, imageType) || - !FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, (int)PixelUtil::getNumElemBits(requiredFormat))) - { - // Ok, need to allocate a fallback - // Only deal with RGBA -> RGB for now - switch (requiredFormat) - { - case PF_BYTE_RGBA: - requiredFormat = PF_BYTE_RGB; - break; - case PF_BYTE_BGRA: - requiredFormat = PF_BYTE_BGR; - break; - default: - break; - }; - - } - - bool conversionRequired = false; - - unsigned char* srcData = input->getPtr(); - - // Check BPP - unsigned bpp = static_cast(PixelUtil::getNumElemBits(requiredFormat)); - if (!FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, (int)bpp)) - { - if (bpp == 32 && PixelUtil::hasAlpha(pImgData->format) && FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, 24)) - { - // drop to 24 bit (lose alpha) + } + // fall through + case PF_L8: + case PF_A8: + imageType = FIT_BITMAP; + break; + + case PF_L16: + imageType = FIT_UINT16; + break; + + case PF_SHORT_GR: + requiredFormat = PF_SHORT_RGB; + // fall through + case PF_SHORT_RGB: + imageType = FIT_RGB16; + break; + + case PF_SHORT_RGBA: + imageType = FIT_RGBA16; + break; + + case PF_FLOAT16_R: + requiredFormat = PF_FLOAT32_R; + // fall through + case PF_FLOAT32_R: + imageType = FIT_FLOAT; + break; + + case PF_FLOAT16_GR: + case PF_FLOAT16_RGB: + case PF_FLOAT32_GR: + requiredFormat = PF_FLOAT32_RGB; + // fall through + case PF_FLOAT32_RGB: + imageType = FIT_RGBF; + break; + + case PF_FLOAT16_RGBA: + requiredFormat = PF_FLOAT32_RGBA; + // fall through + case PF_FLOAT32_RGBA: + imageType = FIT_RGBAF; + break; + + default: + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Invalid image format", "FreeImageCodec::encode"); + }; + + // Check support for this image type & bit depth + if (!FreeImage_FIFSupportsExportType((FREE_IMAGE_FORMAT)mFreeImageType, imageType) || + !FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, (int)PixelUtil::getNumElemBits(requiredFormat))) + { + // Ok, need to allocate a fallback + // Only deal with RGBA -> RGB for now + switch (requiredFormat) + { + case PF_BYTE_RGBA: + requiredFormat = PF_BYTE_RGB; + break; + case PF_BYTE_BGRA: + requiredFormat = PF_BYTE_BGR; + break; + default: + break; + }; + + } + + bool conversionRequired = false; + + unsigned char* srcData = input->getPtr(); + + // Check BPP + unsigned bpp = static_cast(PixelUtil::getNumElemBits(requiredFormat)); + if (!FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, (int)bpp)) + { + if (bpp == 32 && PixelUtil::hasAlpha(pImgData->format) && FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, 24)) + { + // drop to 24 bit (lose alpha) #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB - requiredFormat = PF_BYTE_RGB; + requiredFormat = PF_BYTE_RGB; #else - requiredFormat = PF_BYTE_BGR; + requiredFormat = PF_BYTE_BGR; #endif - bpp = 24; - } - else if (bpp == 128 && PixelUtil::hasAlpha(pImgData->format) && FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, 96)) - { - // drop to 96-bit floating point - requiredFormat = PF_FLOAT32_RGB; - } - } - - PixelBox convBox(pImgData->width, pImgData->height, 1, requiredFormat); - if (requiredFormat != pImgData->format) - { - conversionRequired = true; - // Allocate memory - convBox.data = OGRE_ALLOC_T(uchar, convBox.getConsecutiveSize(), MEMCATEGORY_GENERAL); - // perform conversion and reassign source - PixelBox newSrc(pImgData->width, pImgData->height, 1, pImgData->format, input->getPtr()); - PixelUtil::bulkPixelConversion(newSrc, convBox); - srcData = static_cast(convBox.data); - } - - - ret = FreeImage_AllocateT( - imageType, - static_cast(pImgData->width), - static_cast(pImgData->height), - bpp); - - if (!ret) - { - if (conversionRequired) - OGRE_FREE(convBox.data, MEMCATEGORY_GENERAL); - - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "FreeImage_AllocateT failed - possibly out of memory. ", - __FUNCTION__); - } - - if (requiredFormat == PF_L8 || requiredFormat == PF_A8) - { - // Must explicitly tell FreeImage that this is greyscale by setting - // a "grey" palette (otherwise it will save as a normal RGB - // palettized image). - FIBITMAP *tmp = FreeImage_ConvertToGreyscale(ret); - FreeImage_Unload(ret); - ret = tmp; - } - - size_t dstPitch = FreeImage_GetPitch(ret); - size_t srcPitch = pImgData->width * PixelUtil::getNumElemBytes(requiredFormat); - - - // Copy data, invert scanlines and respect FreeImage pitch - uchar* pDst = FreeImage_GetBits(ret); - for (size_t y = 0; y < pImgData->height; ++y) - { - uchar* pSrc = srcData + (pImgData->height - y - 1) * srcPitch; - memcpy(pDst, pSrc, srcPitch); - pDst += dstPitch; - } - - if (conversionRequired) - { - // delete temporary conversion area - OGRE_FREE(convBox.data, MEMCATEGORY_GENERAL); - } - - return ret; - } + bpp = 24; + } + else if (bpp == 128 && PixelUtil::hasAlpha(pImgData->format) && FreeImage_FIFSupportsExportBPP((FREE_IMAGE_FORMAT)mFreeImageType, 96)) + { + // drop to 96-bit floating point + requiredFormat = PF_FLOAT32_RGB; + } + } + + PixelBox convBox(pImgData->width, pImgData->height, 1, requiredFormat); + if (requiredFormat != pImgData->format) + { + conversionRequired = true; + // Allocate memory + convBox.data = OGRE_ALLOC_T(uchar, convBox.getConsecutiveSize(), MEMCATEGORY_GENERAL); + // perform conversion and reassign source + PixelBox newSrc(pImgData->width, pImgData->height, 1, pImgData->format, input->getPtr()); + PixelUtil::bulkPixelConversion(newSrc, convBox); + srcData = static_cast(convBox.data); + } + + + ret = FreeImage_AllocateT( + imageType, + static_cast(pImgData->width), + static_cast(pImgData->height), + bpp); + + if (!ret) + { + if (conversionRequired) + OGRE_FREE(convBox.data, MEMCATEGORY_GENERAL); + + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "FreeImage_AllocateT failed - possibly out of memory. ", + __FUNCTION__); + } + + if (requiredFormat == PF_L8 || requiredFormat == PF_A8) + { + // Must explicitly tell FreeImage that this is greyscale by setting + // a "grey" palette (otherwise it will save as a normal RGB + // palettized image). + FIBITMAP *tmp = FreeImage_ConvertToGreyscale(ret); + FreeImage_Unload(ret); + ret = tmp; + } + + size_t dstPitch = FreeImage_GetPitch(ret); + size_t srcPitch = pImgData->width * PixelUtil::getNumElemBytes(requiredFormat); + + + // Copy data, invert scanlines and respect FreeImage pitch + uchar* pDst = FreeImage_GetBits(ret); + for (size_t y = 0; y < pImgData->height; ++y) + { + uchar* pSrc = srcData + (pImgData->height - y - 1) * srcPitch; + memcpy(pDst, pSrc, srcPitch); + pDst += dstPitch; + } + + if (conversionRequired) + { + // delete temporary conversion area + OGRE_FREE(convBox.data, MEMCATEGORY_GENERAL); + } + + return ret; + } //--------------------------------------------------------------------- DataStreamPtr FreeImageCodec::encode(MemoryDataStreamPtr& input, Codec::CodecDataPtr& pData) const { - FIBITMAP* fiBitmap = encodeBitmap(input, pData); - - // open memory chunk allocated by FreeImage - FIMEMORY* mem = FreeImage_OpenMemory(); - // write data into memory - FreeImage_SaveToMemory((FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, mem); - // Grab data information - BYTE* data; - DWORD size; - FreeImage_AcquireMemory(mem, &data, &size); - // Copy data into our own buffer - // Because we're asking MemoryDataStream to free this, must create in a compatible way - BYTE* ourData = OGRE_ALLOC_T(BYTE, size, MEMCATEGORY_GENERAL); - memcpy(ourData, data, size); - // Wrap data in stream, tell it to free on close - DataStreamPtr outstream(OGRE_NEW MemoryDataStream(ourData, size, true)); - // Now free FreeImage memory buffers - FreeImage_CloseMemory(mem); - // Unload bitmap - FreeImage_Unload(fiBitmap); - - return outstream; + FIBITMAP* fiBitmap = encodeBitmap(input, pData); + + // open memory chunk allocated by FreeImage + FIMEMORY* mem = FreeImage_OpenMemory(); + // write data into memory + FreeImage_SaveToMemory((FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, mem); + // Grab data information + BYTE* data; + DWORD size; + FreeImage_AcquireMemory(mem, &data, &size); + // Copy data into our own buffer + // Because we're asking MemoryDataStream to free this, must create in a compatible way + BYTE* ourData = OGRE_ALLOC_T(BYTE, size, MEMCATEGORY_GENERAL); + memcpy(ourData, data, size); + // Wrap data in stream, tell it to free on close + DataStreamPtr outstream(OGRE_NEW MemoryDataStream(ourData, size, true)); + // Now free FreeImage memory buffers + FreeImage_CloseMemory(mem); + // Unload bitmap + FreeImage_Unload(fiBitmap); + + return outstream; } @@ -390,184 +390,184 @@ namespace Ogre { void FreeImageCodec::encodeToFile(MemoryDataStreamPtr& input, const String& outFileName, Codec::CodecDataPtr& pData) const { - FIBITMAP* fiBitmap = encodeBitmap(input, pData); + FIBITMAP* fiBitmap = encodeBitmap(input, pData); - FreeImage_Save((FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, outFileName.c_str()); - FreeImage_Unload(fiBitmap); + FreeImage_Save((FREE_IMAGE_FORMAT)mFreeImageType, fiBitmap, outFileName.c_str()); + FreeImage_Unload(fiBitmap); } //--------------------------------------------------------------------- Codec::DecodeResult FreeImageCodec::decode(DataStreamPtr& input) const { - // Buffer stream into memory (TODO: override IO functions instead?) - MemoryDataStream memStream(input, true); + // Buffer stream into memory (TODO: override IO functions instead?) + MemoryDataStream memStream(input, true); - FIMEMORY* fiMem = - FreeImage_OpenMemory(memStream.getPtr(), static_cast(memStream.size())); + FIMEMORY* fiMem = + FreeImage_OpenMemory(memStream.getPtr(), static_cast(memStream.size())); - FIBITMAP* fiBitmap = FreeImage_LoadFromMemory( - (FREE_IMAGE_FORMAT)mFreeImageType, fiMem); - if (!fiBitmap) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Error decoding image", - "FreeImageCodec::decode"); - } + FIBITMAP* fiBitmap = FreeImage_LoadFromMemory( + (FREE_IMAGE_FORMAT)mFreeImageType, fiMem); + if (!fiBitmap) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Error decoding image", + "FreeImageCodec::decode"); + } - ImageData* imgData = OGRE_NEW ImageData(); - MemoryDataStreamPtr output; + ImageData* imgData = OGRE_NEW ImageData(); + MemoryDataStreamPtr output; - imgData->depth = 1; // only 2D formats handled by this codec - imgData->width = FreeImage_GetWidth(fiBitmap); - imgData->height = FreeImage_GetHeight(fiBitmap); + imgData->depth = 1; // only 2D formats handled by this codec + imgData->width = FreeImage_GetWidth(fiBitmap); + imgData->height = FreeImage_GetHeight(fiBitmap); imgData->num_mipmaps = 0; // no mipmaps in non-DDS imgData->flags = 0; - // Must derive format first, this may perform conversions - - FREE_IMAGE_TYPE imageType = FreeImage_GetImageType(fiBitmap); - FREE_IMAGE_COLOR_TYPE colourType = FreeImage_GetColorType(fiBitmap); - unsigned bpp = FreeImage_GetBPP(fiBitmap); - - switch(imageType) - { - case FIT_UNKNOWN: - case FIT_COMPLEX: - case FIT_UINT32: - case FIT_INT32: - case FIT_DOUBLE: + // Must derive format first, this may perform conversions + + FREE_IMAGE_TYPE imageType = FreeImage_GetImageType(fiBitmap); + FREE_IMAGE_COLOR_TYPE colourType = FreeImage_GetColorType(fiBitmap); + unsigned bpp = FreeImage_GetBPP(fiBitmap); + + switch(imageType) + { + case FIT_UNKNOWN: + case FIT_COMPLEX: + case FIT_UINT32: + case FIT_INT32: + case FIT_DOUBLE: default: - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Unknown or unsupported image format", - "FreeImageCodec::decode"); - - break; - case FIT_BITMAP: - // Standard image type - // Perform any colour conversions for greyscale - if (colourType == FIC_MINISWHITE || colourType == FIC_MINISBLACK) - { - FIBITMAP* newBitmap = FreeImage_ConvertToGreyscale(fiBitmap); - // free old bitmap and replace - FreeImage_Unload(fiBitmap); - fiBitmap = newBitmap; - // get new formats - bpp = FreeImage_GetBPP(fiBitmap); - } - // Perform any colour conversions for RGB - else if (bpp < 8 || colourType == FIC_PALETTE || colourType == FIC_CMYK) - { - FIBITMAP* newBitmap = NULL; - if (FreeImage_IsTransparent(fiBitmap)) - { - // convert to 32 bit to preserve the transparency - // (the alpha byte will be 0 if pixel is transparent) - newBitmap = FreeImage_ConvertTo32Bits(fiBitmap); - } - else - { - // no transparency - only 3 bytes are needed - newBitmap = FreeImage_ConvertTo24Bits(fiBitmap); - } - - // free old bitmap and replace - FreeImage_Unload(fiBitmap); - fiBitmap = newBitmap; - // get new formats - bpp = FreeImage_GetBPP(fiBitmap); - } - - // by this stage, 8-bit is greyscale, 16/24/32 bit are RGB[A] - switch(bpp) - { - case 8: - imgData->format = PF_L8; - break; - case 16: - // Determine 555 or 565 from green mask - // cannot be 16-bit greyscale since that's FIT_UINT16 - if(FreeImage_GetGreenMask(fiBitmap) == FI16_565_GREEN_MASK) - { - imgData->format = PF_R5G6B5; - } - else - { - // FreeImage doesn't support 4444 format so must be 1555 - imgData->format = PF_A1R5G5B5; - } - break; - case 24: - // FreeImage differs per platform - // PF_BYTE_BGR[A] for little endian (== PF_ARGB native) - // PF_BYTE_RGB[A] for big endian (== PF_RGBA native) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Unknown or unsupported image format", + "FreeImageCodec::decode"); + + break; + case FIT_BITMAP: + // Standard image type + // Perform any colour conversions for greyscale + if (colourType == FIC_MINISWHITE || colourType == FIC_MINISBLACK) + { + FIBITMAP* newBitmap = FreeImage_ConvertToGreyscale(fiBitmap); + // free old bitmap and replace + FreeImage_Unload(fiBitmap); + fiBitmap = newBitmap; + // get new formats + bpp = FreeImage_GetBPP(fiBitmap); + } + // Perform any colour conversions for RGB + else if (bpp < 8 || colourType == FIC_PALETTE || colourType == FIC_CMYK) + { + FIBITMAP* newBitmap = NULL; + if (FreeImage_IsTransparent(fiBitmap)) + { + // convert to 32 bit to preserve the transparency + // (the alpha byte will be 0 if pixel is transparent) + newBitmap = FreeImage_ConvertTo32Bits(fiBitmap); + } + else + { + // no transparency - only 3 bytes are needed + newBitmap = FreeImage_ConvertTo24Bits(fiBitmap); + } + + // free old bitmap and replace + FreeImage_Unload(fiBitmap); + fiBitmap = newBitmap; + // get new formats + bpp = FreeImage_GetBPP(fiBitmap); + } + + // by this stage, 8-bit is greyscale, 16/24/32 bit are RGB[A] + switch(bpp) + { + case 8: + imgData->format = PF_L8; + break; + case 16: + // Determine 555 or 565 from green mask + // cannot be 16-bit greyscale since that's FIT_UINT16 + if(FreeImage_GetGreenMask(fiBitmap) == FI16_565_GREEN_MASK) + { + imgData->format = PF_R5G6B5; + } + else + { + // FreeImage doesn't support 4444 format so must be 1555 + imgData->format = PF_A1R5G5B5; + } + break; + case 24: + // FreeImage differs per platform + // PF_BYTE_BGR[A] for little endian (== PF_ARGB native) + // PF_BYTE_RGB[A] for big endian (== PF_RGBA native) #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB - imgData->format = PF_BYTE_RGB; + imgData->format = PF_BYTE_RGB; #else - imgData->format = PF_BYTE_BGR; + imgData->format = PF_BYTE_BGR; #endif - break; - case 32: + break; + case 32: #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB - imgData->format = PF_BYTE_RGBA; + imgData->format = PF_BYTE_RGBA; #else - imgData->format = PF_BYTE_BGRA; + imgData->format = PF_BYTE_BGRA; #endif - break; - - - }; - break; - case FIT_UINT16: - case FIT_INT16: - // 16-bit greyscale - imgData->format = PF_L16; - break; - case FIT_FLOAT: - // Single-component floating point data - imgData->format = PF_FLOAT32_R; - break; - case FIT_RGB16: - imgData->format = PF_SHORT_RGB; - break; - case FIT_RGBA16: - imgData->format = PF_SHORT_RGBA; - break; - case FIT_RGBF: - imgData->format = PF_FLOAT32_RGB; - break; - case FIT_RGBAF: - imgData->format = PF_FLOAT32_RGBA; - break; - - - }; - - unsigned char* srcData = FreeImage_GetBits(fiBitmap); - unsigned srcPitch = FreeImage_GetPitch(fiBitmap); - - // Final data - invert image and trim pitch at the same time - size_t dstPitch = imgData->width * PixelUtil::getNumElemBytes(imgData->format); - imgData->size = dstPitch * imgData->height; + break; + + + }; + break; + case FIT_UINT16: + case FIT_INT16: + // 16-bit greyscale + imgData->format = PF_L16; + break; + case FIT_FLOAT: + // Single-component floating point data + imgData->format = PF_FLOAT32_R; + break; + case FIT_RGB16: + imgData->format = PF_SHORT_RGB; + break; + case FIT_RGBA16: + imgData->format = PF_SHORT_RGBA; + break; + case FIT_RGBF: + imgData->format = PF_FLOAT32_RGB; + break; + case FIT_RGBAF: + imgData->format = PF_FLOAT32_RGBA; + break; + + + }; + + unsigned char* srcData = FreeImage_GetBits(fiBitmap); + unsigned srcPitch = FreeImage_GetPitch(fiBitmap); + + // Final data - invert image and trim pitch at the same time + size_t dstPitch = imgData->width * PixelUtil::getNumElemBytes(imgData->format); + imgData->size = dstPitch * imgData->height; // Bind output buffer output.bind(OGRE_NEW MemoryDataStream(imgData->size)); - uchar* pDst = output->getPtr(); - for (size_t y = 0; y < imgData->height; ++y) - { - uchar* pSrc = srcData + (imgData->height - y - 1) * srcPitch; - memcpy(pDst, pSrc, dstPitch); - pDst += dstPitch; - } + uchar* pDst = output->getPtr(); + for (size_t y = 0; y < imgData->height; ++y) + { + uchar* pSrc = srcData + (imgData->height - y - 1) * srcPitch; + memcpy(pDst, pSrc, dstPitch); + pDst += dstPitch; + } - - FreeImage_Unload(fiBitmap); - FreeImage_CloseMemory(fiMem); + + FreeImage_Unload(fiBitmap); + FreeImage_CloseMemory(fiMem); DecodeResult ret; ret.first = output; ret.second = CodecDataPtr(imgData); - return ret; + return ret; } //--------------------------------------------------------------------- @@ -575,24 +575,24 @@ namespace Ogre { { return mType; } - //--------------------------------------------------------------------- - String FreeImageCodec::magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const - { - FIMEMORY* fiMem = + //--------------------------------------------------------------------- + String FreeImageCodec::magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const + { + FIMEMORY* fiMem = FreeImage_OpenMemory((BYTE*)const_cast(magicNumberPtr), static_cast(maxbytes)); - FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(fiMem, (int)maxbytes); - FreeImage_CloseMemory(fiMem); - - if (fif != FIF_UNKNOWN) - { - String ext(FreeImage_GetFormatFromFIF(fif)); - StringUtil::toLowerCase(ext); - return ext; - } - else - { - return BLANKSTRING; - } - } + FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(fiMem, (int)maxbytes); + FreeImage_CloseMemory(fiMem); + + if (fif != FIF_UNKNOWN) + { + String ext(FreeImage_GetFormatFromFIF(fif)); + StringUtil::toLowerCase(ext); + return ext; + } + else + { + return BLANKSTRING; + } + } } diff --git a/OgreMain/src/OgreFrustum.cpp b/OgreMain/src/OgreFrustum.cpp index 04a3116969f..56d687962a9 100644 --- a/OgreMain/src/OgreFrustum.cpp +++ b/OgreMain/src/OgreFrustum.cpp @@ -51,7 +51,7 @@ namespace Ogre { mFarDist(100000.0f), mNearDist(100.0f), mAspect(1.33333333333333f), - mOrthoHeight(1000), + mOrthoHeight(1000), mFrustumOffset(Vector2::ZERO), mFocalLength(1.0f), mLastParentOrientation(Quaternion::IDENTITY), @@ -61,9 +61,9 @@ namespace Ogre { mRecalcFrustumPlanes(true), mRecalcWorldSpaceCorners(true), mRecalcVertexData(true), - mCustomViewMatrix(false), - mCustomProjMatrix(false), - mFrustumExtentsManuallySet(false), + mCustomViewMatrix(false), + mCustomProjMatrix(false), + mFrustumExtentsManuallySet(false), mOrientationMode(OR_DEGREE_0), mReflect(false), mLinkedReflectPlane(0), @@ -313,86 +313,86 @@ namespace Ogre { return true; } - //--------------------------------------------------------------------- - uint32 Frustum::getTypeFlags(void) const - { - return SceneManager::FRUSTUM_TYPE_MASK; - } + //--------------------------------------------------------------------- + uint32 Frustum::getTypeFlags(void) const + { + return SceneManager::FRUSTUM_TYPE_MASK; + } //----------------------------------------------------------------------- void Frustum::calcProjectionParameters(Real& left, Real& right, Real& bottom, Real& top) const { - if (mCustomProjMatrix) - { - // Convert clipspace corners to camera space - Matrix4 invProj = mProjMatrix.inverse(); - Vector3 topLeft(-0.5f, 0.5f, 0.0f); - Vector3 bottomRight(0.5f, -0.5f, 0.0f); - - topLeft = invProj * topLeft; - bottomRight = invProj * bottomRight; - - left = topLeft.x; - top = topLeft.y; - right = bottomRight.x; - bottom = bottomRight.y; - - } - else - { - if (mFrustumExtentsManuallySet) - { - left = mLeft; - right = mRight; - top = mTop; - bottom = mBottom; - } - // Calculate general projection parameters - else if (mProjType == PT_PERSPECTIVE) - { - Radian thetaY (mFOVy * 0.5f); - Real tanThetaY = Math::Tan(thetaY); - Real tanThetaX = tanThetaY * mAspect; - - Real nearFocal = mNearDist / mFocalLength; - Real nearOffsetX = mFrustumOffset.x * nearFocal; - Real nearOffsetY = mFrustumOffset.y * nearFocal; - Real half_w = tanThetaX * mNearDist; - Real half_h = tanThetaY * mNearDist; - - left = - half_w + nearOffsetX; - right = + half_w + nearOffsetX; - bottom = - half_h + nearOffsetY; - top = + half_h + nearOffsetY; - - mLeft = left; - mRight = right; - mTop = top; - mBottom = bottom; - } - else - { - // Unknown how to apply frustum offset to orthographic camera, just ignore here - Real half_w = getOrthoWindowWidth() * 0.5f; - Real half_h = getOrthoWindowHeight() * 0.5f; - - left = - half_w; - right = + half_w; - bottom = - half_h; - top = + half_h; - - mLeft = left; - mRight = right; - mTop = top; - mBottom = bottom; - } - - } - } - //----------------------------------------------------------------------- - void Frustum::updateFrustumImpl(void) const - { - // Common calcs - Real left, right, bottom, top; + if (mCustomProjMatrix) + { + // Convert clipspace corners to camera space + Matrix4 invProj = mProjMatrix.inverse(); + Vector3 topLeft(-0.5f, 0.5f, 0.0f); + Vector3 bottomRight(0.5f, -0.5f, 0.0f); + + topLeft = invProj * topLeft; + bottomRight = invProj * bottomRight; + + left = topLeft.x; + top = topLeft.y; + right = bottomRight.x; + bottom = bottomRight.y; + + } + else + { + if (mFrustumExtentsManuallySet) + { + left = mLeft; + right = mRight; + top = mTop; + bottom = mBottom; + } + // Calculate general projection parameters + else if (mProjType == PT_PERSPECTIVE) + { + Radian thetaY (mFOVy * 0.5f); + Real tanThetaY = Math::Tan(thetaY); + Real tanThetaX = tanThetaY * mAspect; + + Real nearFocal = mNearDist / mFocalLength; + Real nearOffsetX = mFrustumOffset.x * nearFocal; + Real nearOffsetY = mFrustumOffset.y * nearFocal; + Real half_w = tanThetaX * mNearDist; + Real half_h = tanThetaY * mNearDist; + + left = - half_w + nearOffsetX; + right = + half_w + nearOffsetX; + bottom = - half_h + nearOffsetY; + top = + half_h + nearOffsetY; + + mLeft = left; + mRight = right; + mTop = top; + mBottom = bottom; + } + else + { + // Unknown how to apply frustum offset to orthographic camera, just ignore here + Real half_w = getOrthoWindowWidth() * 0.5f; + Real half_h = getOrthoWindowHeight() * 0.5f; + + left = - half_w; + right = + half_w; + bottom = - half_h; + top = + half_h; + + mLeft = left; + mRight = right; + mTop = top; + mBottom = bottom; + } + + } + } + //----------------------------------------------------------------------- + void Frustum::updateFrustumImpl(void) const + { + // Common calcs + Real left, right, bottom, top; #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 if (mOrientationMode != OR_PORTRAIT) @@ -401,197 +401,197 @@ namespace Ogre { #endif calcProjectionParameters(left, right, bottom, top); - if (!mCustomProjMatrix) - { - - // The code below will dealing with general projection - // parameters, similar glFrustum and glOrtho. - // Doesn't optimise manually except division operator, so the - // code more self-explaining. - - Real inv_w = 1 / (right - left); - Real inv_h = 1 / (top - bottom); - Real inv_d = 1 / (mFarDist - mNearDist); - - // Recalc if frustum params changed - if (mProjType == PT_PERSPECTIVE) - { - // Calc matrix elements - Real A = 2 * mNearDist * inv_w; - Real B = 2 * mNearDist * inv_h; - Real C = (right + left) * inv_w; - Real D = (top + bottom) * inv_h; - Real q, qn; - if (mFarDist == 0) - { - // Infinite far plane - q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1; - qn = mNearDist * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2); - } - else - { - q = - (mFarDist + mNearDist) * inv_d; - qn = -2 * (mFarDist * mNearDist) * inv_d; - } - - // NB: This creates 'uniform' perspective projection matrix, - // which depth range [-1,1], right-handed rules - // - // [ A 0 C 0 ] - // [ 0 B D 0 ] - // [ 0 0 q qn ] - // [ 0 0 -1 0 ] - // - // A = 2 * near / (right - left) - // B = 2 * near / (top - bottom) - // C = (right + left) / (right - left) - // D = (top + bottom) / (top - bottom) - // q = - (far + near) / (far - near) - // qn = - 2 * (far * near) / (far - near) - - mProjMatrix = Matrix4::ZERO; - mProjMatrix[0][0] = A; - mProjMatrix[0][2] = C; - mProjMatrix[1][1] = B; - mProjMatrix[1][2] = D; - mProjMatrix[2][2] = q; - mProjMatrix[2][3] = qn; - mProjMatrix[3][2] = -1; - - if (mObliqueDepthProjection) - { - // Translate the plane into view space - - // Don't use getViewMatrix here, incase overrided by - // camera and return a cull frustum view matrix - updateView(); - Plane plane = mViewMatrix * mObliqueProjPlane; - - // Thanks to Eric Lenyel for posting this calculation - // at www.terathon.com - - // Calculate the clip-space corner point opposite the - // clipping plane - // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and - // transform it into camera space by multiplying it - // by the inverse of the projection matrix - - /* generalised version - Vector4 q = matrix.inverse() * - Vector4(Math::Sign(plane.normal.x), - Math::Sign(plane.normal.y), 1.0f, 1.0f); - */ - Vector4 qVec; - qVec.x = (Math::Sign(plane.normal.x) + mProjMatrix[0][2]) / mProjMatrix[0][0]; - qVec.y = (Math::Sign(plane.normal.y) + mProjMatrix[1][2]) / mProjMatrix[1][1]; - qVec.z = -1; - qVec.w = (1 + mProjMatrix[2][2]) / mProjMatrix[2][3]; - - // Calculate the scaled plane vector - Vector4 clipPlane4d(plane.normal.x, plane.normal.y, plane.normal.z, plane.d); - Vector4 c = clipPlane4d * (2 / (clipPlane4d.dotProduct(qVec))); - - // Replace the third row of the projection matrix - mProjMatrix[2][0] = c.x; - mProjMatrix[2][1] = c.y; - mProjMatrix[2][2] = c.z + 1; - mProjMatrix[2][3] = c.w; - } - } // perspective - else if (mProjType == PT_ORTHOGRAPHIC) - { - Real A = 2 * inv_w; - Real B = 2 * inv_h; - Real C = - (right + left) * inv_w; - Real D = - (top + bottom) * inv_h; - Real q, qn; - if (mFarDist == 0) - { - // Can not do infinite far plane here, avoid divided zero only - q = - Frustum::INFINITE_FAR_PLANE_ADJUST / mNearDist; - qn = - Frustum::INFINITE_FAR_PLANE_ADJUST - 1; - } - else - { - q = - 2 * inv_d; - qn = - (mFarDist + mNearDist) * inv_d; - } - - // NB: This creates 'uniform' orthographic projection matrix, - // which depth range [-1,1], right-handed rules - // - // [ A 0 0 C ] - // [ 0 B 0 D ] - // [ 0 0 q qn ] - // [ 0 0 0 1 ] - // - // A = 2 * / (right - left) - // B = 2 * / (top - bottom) - // C = - (right + left) / (right - left) - // D = - (top + bottom) / (top - bottom) - // q = - 2 / (far - near) - // qn = - (far + near) / (far - near) - - mProjMatrix = Matrix4::ZERO; - mProjMatrix[0][0] = A; - mProjMatrix[0][3] = C; - mProjMatrix[1][1] = B; - mProjMatrix[1][3] = D; - mProjMatrix[2][2] = q; - mProjMatrix[2][3] = qn; - mProjMatrix[3][3] = 1; - } // ortho - } // !mCustomProjMatrix + if (!mCustomProjMatrix) + { + + // The code below will dealing with general projection + // parameters, similar glFrustum and glOrtho. + // Doesn't optimise manually except division operator, so the + // code more self-explaining. + + Real inv_w = 1 / (right - left); + Real inv_h = 1 / (top - bottom); + Real inv_d = 1 / (mFarDist - mNearDist); + + // Recalc if frustum params changed + if (mProjType == PT_PERSPECTIVE) + { + // Calc matrix elements + Real A = 2 * mNearDist * inv_w; + Real B = 2 * mNearDist * inv_h; + Real C = (right + left) * inv_w; + Real D = (top + bottom) * inv_h; + Real q, qn; + if (mFarDist == 0) + { + // Infinite far plane + q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1; + qn = mNearDist * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2); + } + else + { + q = - (mFarDist + mNearDist) * inv_d; + qn = -2 * (mFarDist * mNearDist) * inv_d; + } + + // NB: This creates 'uniform' perspective projection matrix, + // which depth range [-1,1], right-handed rules + // + // [ A 0 C 0 ] + // [ 0 B D 0 ] + // [ 0 0 q qn ] + // [ 0 0 -1 0 ] + // + // A = 2 * near / (right - left) + // B = 2 * near / (top - bottom) + // C = (right + left) / (right - left) + // D = (top + bottom) / (top - bottom) + // q = - (far + near) / (far - near) + // qn = - 2 * (far * near) / (far - near) + + mProjMatrix = Matrix4::ZERO; + mProjMatrix[0][0] = A; + mProjMatrix[0][2] = C; + mProjMatrix[1][1] = B; + mProjMatrix[1][2] = D; + mProjMatrix[2][2] = q; + mProjMatrix[2][3] = qn; + mProjMatrix[3][2] = -1; + + if (mObliqueDepthProjection) + { + // Translate the plane into view space + + // Don't use getViewMatrix here, incase overrided by + // camera and return a cull frustum view matrix + updateView(); + Plane plane = mViewMatrix * mObliqueProjPlane; + + // Thanks to Eric Lenyel for posting this calculation + // at www.terathon.com + + // Calculate the clip-space corner point opposite the + // clipping plane + // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and + // transform it into camera space by multiplying it + // by the inverse of the projection matrix + + /* generalised version + Vector4 q = matrix.inverse() * + Vector4(Math::Sign(plane.normal.x), + Math::Sign(plane.normal.y), 1.0f, 1.0f); + */ + Vector4 qVec; + qVec.x = (Math::Sign(plane.normal.x) + mProjMatrix[0][2]) / mProjMatrix[0][0]; + qVec.y = (Math::Sign(plane.normal.y) + mProjMatrix[1][2]) / mProjMatrix[1][1]; + qVec.z = -1; + qVec.w = (1 + mProjMatrix[2][2]) / mProjMatrix[2][3]; + + // Calculate the scaled plane vector + Vector4 clipPlane4d(plane.normal.x, plane.normal.y, plane.normal.z, plane.d); + Vector4 c = clipPlane4d * (2 / (clipPlane4d.dotProduct(qVec))); + + // Replace the third row of the projection matrix + mProjMatrix[2][0] = c.x; + mProjMatrix[2][1] = c.y; + mProjMatrix[2][2] = c.z + 1; + mProjMatrix[2][3] = c.w; + } + } // perspective + else if (mProjType == PT_ORTHOGRAPHIC) + { + Real A = 2 * inv_w; + Real B = 2 * inv_h; + Real C = - (right + left) * inv_w; + Real D = - (top + bottom) * inv_h; + Real q, qn; + if (mFarDist == 0) + { + // Can not do infinite far plane here, avoid divided zero only + q = - Frustum::INFINITE_FAR_PLANE_ADJUST / mNearDist; + qn = - Frustum::INFINITE_FAR_PLANE_ADJUST - 1; + } + else + { + q = - 2 * inv_d; + qn = - (mFarDist + mNearDist) * inv_d; + } + + // NB: This creates 'uniform' orthographic projection matrix, + // which depth range [-1,1], right-handed rules + // + // [ A 0 0 C ] + // [ 0 B 0 D ] + // [ 0 0 q qn ] + // [ 0 0 0 1 ] + // + // A = 2 * / (right - left) + // B = 2 * / (top - bottom) + // C = - (right + left) / (right - left) + // D = - (top + bottom) / (top - bottom) + // q = - 2 / (far - near) + // qn = - (far + near) / (far - near) + + mProjMatrix = Matrix4::ZERO; + mProjMatrix[0][0] = A; + mProjMatrix[0][3] = C; + mProjMatrix[1][1] = B; + mProjMatrix[1][3] = D; + mProjMatrix[2][2] = q; + mProjMatrix[2][3] = qn; + mProjMatrix[3][3] = 1; + } // ortho + } // !mCustomProjMatrix #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 // Deal with orientation mode mProjMatrix = mProjMatrix * Quaternion(Degree(mOrientationMode * 90.f), Vector3::UNIT_Z); #endif - RenderSystem* renderSystem = Root::getSingleton().getRenderSystem(); - // API specific - renderSystem->_convertProjectionMatrix(mProjMatrix, mProjMatrixRS); - // API specific for Gpu Programs - renderSystem->_convertProjectionMatrix(mProjMatrix, mProjMatrixRSDepth, true); - - - // Calculate bounding box (local) - // Box is from 0, down -Z, max dimensions as determined from far plane - // If infinite view frustum just pick a far value - Real farDist = (mFarDist == 0) ? 100000 : mFarDist; - // Near plane bounds - Vector3 min(left, bottom, -farDist); - Vector3 max(right, top, 0); - - if (mCustomProjMatrix) - { - // Some custom projection matrices can have unusual inverted settings - // So make sure the AABB is the right way around to start with - Vector3 tmp = min; - min.makeFloor(max); - max.makeCeil(tmp); - } - - if (mProjType == PT_PERSPECTIVE) - { - // Merge with far plane bounds - Real radio = farDist / mNearDist; - min.makeFloor(Vector3(left * radio, bottom * radio, -farDist)); - max.makeCeil(Vector3(right * radio, top * radio, 0)); - } - mBoundingBox.setExtents(min, max); - - mRecalcFrustum = false; - - // Signal to update frustum clipping planes - mRecalcFrustumPlanes = true; - } + RenderSystem* renderSystem = Root::getSingleton().getRenderSystem(); + // API specific + renderSystem->_convertProjectionMatrix(mProjMatrix, mProjMatrixRS); + // API specific for Gpu Programs + renderSystem->_convertProjectionMatrix(mProjMatrix, mProjMatrixRSDepth, true); + + + // Calculate bounding box (local) + // Box is from 0, down -Z, max dimensions as determined from far plane + // If infinite view frustum just pick a far value + Real farDist = (mFarDist == 0) ? 100000 : mFarDist; + // Near plane bounds + Vector3 min(left, bottom, -farDist); + Vector3 max(right, top, 0); + + if (mCustomProjMatrix) + { + // Some custom projection matrices can have unusual inverted settings + // So make sure the AABB is the right way around to start with + Vector3 tmp = min; + min.makeFloor(max); + max.makeCeil(tmp); + } + + if (mProjType == PT_PERSPECTIVE) + { + // Merge with far plane bounds + Real radio = farDist / mNearDist; + min.makeFloor(Vector3(left * radio, bottom * radio, -farDist)); + max.makeCeil(Vector3(right * radio, top * radio, 0)); + } + mBoundingBox.setExtents(min, max); + + mRecalcFrustum = false; + + // Signal to update frustum clipping planes + mRecalcFrustumPlanes = true; + } //----------------------------------------------------------------------- void Frustum::updateFrustum(void) const { if (isFrustumOutOfDate()) { - updateFrustumImpl(); + updateFrustumImpl(); } } @@ -750,100 +750,100 @@ namespace Ogre { } //----------------------------------------------------------------------- - void Frustum::updateViewImpl(void) const - { - // ---------------------- - // Update the view matrix - // ---------------------- - - // Get orientation from quaternion - - if (!mCustomViewMatrix) - { - Matrix3 rot; - const Quaternion& orientation = getOrientationForViewUpdate(); - const Vector3& position = getPositionForViewUpdate(); - - mViewMatrix = Math::makeViewMatrix(position, orientation, mReflect? &mReflectMatrix : 0); - } - - mRecalcView = false; - - // Signal to update frustum clipping planes - mRecalcFrustumPlanes = true; - // Signal to update world space corners - mRecalcWorldSpaceCorners = true; - // Signal to update frustum if oblique plane enabled, - // since plane needs to be in view space - if (mObliqueDepthProjection) - { - mRecalcFrustum = true; - } - } - //--------------------------------------------------------------------- - void Frustum::calcViewMatrixRelative(const Vector3& relPos, Matrix4& matToUpdate) const - { - Matrix4 matTrans = Matrix4::IDENTITY; - matTrans.setTrans(relPos); - matToUpdate = getViewMatrix() * matTrans; - - } - //----------------------------------------------------------------------- + void Frustum::updateViewImpl(void) const + { + // ---------------------- + // Update the view matrix + // ---------------------- + + // Get orientation from quaternion + + if (!mCustomViewMatrix) + { + Matrix3 rot; + const Quaternion& orientation = getOrientationForViewUpdate(); + const Vector3& position = getPositionForViewUpdate(); + + mViewMatrix = Math::makeViewMatrix(position, orientation, mReflect? &mReflectMatrix : 0); + } + + mRecalcView = false; + + // Signal to update frustum clipping planes + mRecalcFrustumPlanes = true; + // Signal to update world space corners + mRecalcWorldSpaceCorners = true; + // Signal to update frustum if oblique plane enabled, + // since plane needs to be in view space + if (mObliqueDepthProjection) + { + mRecalcFrustum = true; + } + } + //--------------------------------------------------------------------- + void Frustum::calcViewMatrixRelative(const Vector3& relPos, Matrix4& matToUpdate) const + { + Matrix4 matTrans = Matrix4::IDENTITY; + matTrans.setTrans(relPos); + matToUpdate = getViewMatrix() * matTrans; + + } + //----------------------------------------------------------------------- void Frustum::updateView(void) const { if (isViewOutOfDate()) { - updateViewImpl(); + updateViewImpl(); } } - //----------------------------------------------------------------------- - void Frustum::updateFrustumPlanesImpl(void) const - { - // ------------------------- - // Update the frustum planes - // ------------------------- - Matrix4 combo = mProjMatrix * mViewMatrix; - - mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal.x = combo[3][0] + combo[0][0]; - mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal.y = combo[3][1] + combo[0][1]; - mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal.z = combo[3][2] + combo[0][2]; - mFrustumPlanes[FRUSTUM_PLANE_LEFT].d = combo[3][3] + combo[0][3]; - - mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal.x = combo[3][0] - combo[0][0]; - mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal.y = combo[3][1] - combo[0][1]; - mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal.z = combo[3][2] - combo[0][2]; - mFrustumPlanes[FRUSTUM_PLANE_RIGHT].d = combo[3][3] - combo[0][3]; - - mFrustumPlanes[FRUSTUM_PLANE_TOP].normal.x = combo[3][0] - combo[1][0]; - mFrustumPlanes[FRUSTUM_PLANE_TOP].normal.y = combo[3][1] - combo[1][1]; - mFrustumPlanes[FRUSTUM_PLANE_TOP].normal.z = combo[3][2] - combo[1][2]; - mFrustumPlanes[FRUSTUM_PLANE_TOP].d = combo[3][3] - combo[1][3]; - - mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal.x = combo[3][0] + combo[1][0]; - mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal.y = combo[3][1] + combo[1][1]; - mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal.z = combo[3][2] + combo[1][2]; - mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].d = combo[3][3] + combo[1][3]; - - mFrustumPlanes[FRUSTUM_PLANE_NEAR].normal.x = combo[3][0] + combo[2][0]; - mFrustumPlanes[FRUSTUM_PLANE_NEAR].normal.y = combo[3][1] + combo[2][1]; - mFrustumPlanes[FRUSTUM_PLANE_NEAR].normal.z = combo[3][2] + combo[2][2]; - mFrustumPlanes[FRUSTUM_PLANE_NEAR].d = combo[3][3] + combo[2][3]; - - mFrustumPlanes[FRUSTUM_PLANE_FAR].normal.x = combo[3][0] - combo[2][0]; - mFrustumPlanes[FRUSTUM_PLANE_FAR].normal.y = combo[3][1] - combo[2][1]; - mFrustumPlanes[FRUSTUM_PLANE_FAR].normal.z = combo[3][2] - combo[2][2]; - mFrustumPlanes[FRUSTUM_PLANE_FAR].d = combo[3][3] - combo[2][3]; - - // Renormalise any normals which were not unit length - for(int i=0; i<6; i++ ) - { - Real length = mFrustumPlanes[i].normal.normalise(); - mFrustumPlanes[i].d /= length; - } - - mRecalcFrustumPlanes = false; - } + //----------------------------------------------------------------------- + void Frustum::updateFrustumPlanesImpl(void) const + { + // ------------------------- + // Update the frustum planes + // ------------------------- + Matrix4 combo = mProjMatrix * mViewMatrix; + + mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal.x = combo[3][0] + combo[0][0]; + mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal.y = combo[3][1] + combo[0][1]; + mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal.z = combo[3][2] + combo[0][2]; + mFrustumPlanes[FRUSTUM_PLANE_LEFT].d = combo[3][3] + combo[0][3]; + + mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal.x = combo[3][0] - combo[0][0]; + mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal.y = combo[3][1] - combo[0][1]; + mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal.z = combo[3][2] - combo[0][2]; + mFrustumPlanes[FRUSTUM_PLANE_RIGHT].d = combo[3][3] - combo[0][3]; + + mFrustumPlanes[FRUSTUM_PLANE_TOP].normal.x = combo[3][0] - combo[1][0]; + mFrustumPlanes[FRUSTUM_PLANE_TOP].normal.y = combo[3][1] - combo[1][1]; + mFrustumPlanes[FRUSTUM_PLANE_TOP].normal.z = combo[3][2] - combo[1][2]; + mFrustumPlanes[FRUSTUM_PLANE_TOP].d = combo[3][3] - combo[1][3]; + + mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal.x = combo[3][0] + combo[1][0]; + mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal.y = combo[3][1] + combo[1][1]; + mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal.z = combo[3][2] + combo[1][2]; + mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].d = combo[3][3] + combo[1][3]; + + mFrustumPlanes[FRUSTUM_PLANE_NEAR].normal.x = combo[3][0] + combo[2][0]; + mFrustumPlanes[FRUSTUM_PLANE_NEAR].normal.y = combo[3][1] + combo[2][1]; + mFrustumPlanes[FRUSTUM_PLANE_NEAR].normal.z = combo[3][2] + combo[2][2]; + mFrustumPlanes[FRUSTUM_PLANE_NEAR].d = combo[3][3] + combo[2][3]; + + mFrustumPlanes[FRUSTUM_PLANE_FAR].normal.x = combo[3][0] - combo[2][0]; + mFrustumPlanes[FRUSTUM_PLANE_FAR].normal.y = combo[3][1] - combo[2][1]; + mFrustumPlanes[FRUSTUM_PLANE_FAR].normal.z = combo[3][2] - combo[2][2]; + mFrustumPlanes[FRUSTUM_PLANE_FAR].d = combo[3][3] - combo[2][3]; + + // Renormalise any normals which were not unit length + for(int i=0; i<6; i++ ) + { + Real length = mFrustumPlanes[i].normal.normalise(); + mFrustumPlanes[i].d /= length; + } + + mRecalcFrustumPlanes = false; + } //----------------------------------------------------------------------- void Frustum::updateFrustumPlanes(void) const { @@ -852,46 +852,46 @@ namespace Ogre { if (mRecalcFrustumPlanes) { - updateFrustumPlanesImpl(); + updateFrustumPlanesImpl(); } } - //----------------------------------------------------------------------- - void Frustum::updateWorldSpaceCornersImpl(void) const - { - Matrix4 eyeToWorld = mViewMatrix.inverseAffine(); - - // Note: Even though we can dealing with general projection matrix here, - // but because it's incompatibly with infinite far plane, thus, we - // still need to working with projection parameters. - - // Calc near plane corners - Real nearLeft, nearRight, nearBottom, nearTop; - calcProjectionParameters(nearLeft, nearRight, nearBottom, nearTop); - - // Treat infinite fardist as some arbitrary far value - Real farDist = (mFarDist == 0) ? 100000 : mFarDist; - - // Calc far palne corners - Real radio = mProjType == PT_PERSPECTIVE ? farDist / mNearDist : 1; - Real farLeft = nearLeft * radio; - Real farRight = nearRight * radio; - Real farBottom = nearBottom * radio; - Real farTop = nearTop * radio; - - // near - mWorldSpaceCorners[0] = eyeToWorld.transformAffine(Vector3(nearRight, nearTop, -mNearDist)); - mWorldSpaceCorners[1] = eyeToWorld.transformAffine(Vector3(nearLeft, nearTop, -mNearDist)); - mWorldSpaceCorners[2] = eyeToWorld.transformAffine(Vector3(nearLeft, nearBottom, -mNearDist)); - mWorldSpaceCorners[3] = eyeToWorld.transformAffine(Vector3(nearRight, nearBottom, -mNearDist)); - // far - mWorldSpaceCorners[4] = eyeToWorld.transformAffine(Vector3(farRight, farTop, -farDist)); - mWorldSpaceCorners[5] = eyeToWorld.transformAffine(Vector3(farLeft, farTop, -farDist)); - mWorldSpaceCorners[6] = eyeToWorld.transformAffine(Vector3(farLeft, farBottom, -farDist)); - mWorldSpaceCorners[7] = eyeToWorld.transformAffine(Vector3(farRight, farBottom, -farDist)); - - - mRecalcWorldSpaceCorners = false; - } + //----------------------------------------------------------------------- + void Frustum::updateWorldSpaceCornersImpl(void) const + { + Matrix4 eyeToWorld = mViewMatrix.inverseAffine(); + + // Note: Even though we can dealing with general projection matrix here, + // but because it's incompatibly with infinite far plane, thus, we + // still need to working with projection parameters. + + // Calc near plane corners + Real nearLeft, nearRight, nearBottom, nearTop; + calcProjectionParameters(nearLeft, nearRight, nearBottom, nearTop); + + // Treat infinite fardist as some arbitrary far value + Real farDist = (mFarDist == 0) ? 100000 : mFarDist; + + // Calc far palne corners + Real radio = mProjType == PT_PERSPECTIVE ? farDist / mNearDist : 1; + Real farLeft = nearLeft * radio; + Real farRight = nearRight * radio; + Real farBottom = nearBottom * radio; + Real farTop = nearTop * radio; + + // near + mWorldSpaceCorners[0] = eyeToWorld.transformAffine(Vector3(nearRight, nearTop, -mNearDist)); + mWorldSpaceCorners[1] = eyeToWorld.transformAffine(Vector3(nearLeft, nearTop, -mNearDist)); + mWorldSpaceCorners[2] = eyeToWorld.transformAffine(Vector3(nearLeft, nearBottom, -mNearDist)); + mWorldSpaceCorners[3] = eyeToWorld.transformAffine(Vector3(nearRight, nearBottom, -mNearDist)); + // far + mWorldSpaceCorners[4] = eyeToWorld.transformAffine(Vector3(farRight, farTop, -farDist)); + mWorldSpaceCorners[5] = eyeToWorld.transformAffine(Vector3(farLeft, farTop, -farDist)); + mWorldSpaceCorners[6] = eyeToWorld.transformAffine(Vector3(farLeft, farBottom, -farDist)); + mWorldSpaceCorners[7] = eyeToWorld.transformAffine(Vector3(farRight, farBottom, -farDist)); + + + mRecalcWorldSpaceCorners = false; + } //----------------------------------------------------------------------- void Frustum::updateWorldSpaceCorners(void) const { @@ -899,7 +899,7 @@ namespace Ogre { if (mRecalcWorldSpaceCorners) { - updateWorldSpaceCornersImpl(); + updateWorldSpaceCornersImpl(); } } @@ -925,11 +925,11 @@ namespace Ogre { //----------------------------------------------------------------------- void Frustum::_updateRenderQueue(RenderQueue* queue) { - if (mDebugDisplay) - { - // Add self - queue->addRenderable(this); - } + if (mDebugDisplay) + { + // Add self + queue->addRenderable(this); + } } //----------------------------------------------------------------------- const String& Frustum::getMovableType(void) const @@ -937,10 +937,10 @@ namespace Ogre { return msMovableType; } //----------------------------------------------------------------------- - Real Frustum::getBoundingRadius(void) const - { + Real Frustum::getBoundingRadius(void) const + { return (mFarDist == 0)? 100000 : mFarDist; - } + } //----------------------------------------------------------------------- const MaterialPtr& Frustum::getMaterial(void) const { @@ -1066,165 +1066,165 @@ namespace Ogre { bool Frustum::projectSphere(const Sphere& sphere, Real* left, Real* top, Real* right, Real* bottom) const { - // See http://www.gamasutra.com/features/20021011/lengyel_06.htm + // See http://www.gamasutra.com/features/20021011/lengyel_06.htm // Transform light position into camera space updateView(); Vector3 eyeSpacePos = mViewMatrix.transformAffine(sphere.getCenter()); - // initialise - *left = *bottom = -1.0f; - *right = *top = 1.0f; + // initialise + *left = *bottom = -1.0f; + *right = *top = 1.0f; if (eyeSpacePos.z < 0) { - updateFrustum(); - const Matrix4& projMatrix = getProjectionMatrix(); + updateFrustum(); + const Matrix4& projMatrix = getProjectionMatrix(); Real r = sphere.getRadius(); - Real rsq = r * r; + Real rsq = r * r; // early-exit if (eyeSpacePos.squaredLength() <= rsq) return false; - Real Lxz = Math::Sqr(eyeSpacePos.x) + Math::Sqr(eyeSpacePos.z); - Real Lyz = Math::Sqr(eyeSpacePos.y) + Math::Sqr(eyeSpacePos.z); - - // Find the tangent planes to the sphere - // XZ first - // calculate quadratic discriminant: b*b - 4ac - // x = Nx - // a = Lx^2 + Lz^2 - // b = -2rLx - // c = r^2 - Lz^2 - Real a = Lxz; - Real b = -2.0f * r * eyeSpacePos.x; - Real c = rsq - Math::Sqr(eyeSpacePos.z); - Real D = b*b - 4.0f*a*c; - - // two roots? - if (D > 0) - { - Real sqrootD = Math::Sqrt(D); - // solve the quadratic to get the components of the normal - Real Nx0 = (-b + sqrootD) / (2 * a); - Real Nx1 = (-b - sqrootD) / (2 * a); - - // Derive Z from this - Real Nz0 = (r - Nx0 * eyeSpacePos.x) / eyeSpacePos.z; - Real Nz1 = (r - Nx1 * eyeSpacePos.x) / eyeSpacePos.z; - - // Get the point of tangency - // Only consider points of tangency in front of the camera - Real Pz0 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz0 / Nx0) * eyeSpacePos.x)); - if (Pz0 < 0) - { - // Project point onto near plane in worldspace - Real nearx0 = (Nz0 * mNearDist) / Nx0; - // now we need to map this to viewport coords - // use projection matrix since that will take into account all factors - Vector3 relx0 = projMatrix * Vector3(nearx0, 0, -mNearDist); - - // find out whether this is a left side or right side - Real Px0 = -(Pz0 * Nz0) / Nx0; - if (Px0 > eyeSpacePos.x) - { - *right = std::min(*right, relx0.x); - } - else - { - *left = std::max(*left, relx0.x); - } - } - Real Pz1 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz1 / Nx1) * eyeSpacePos.x)); - if (Pz1 < 0) - { - // Project point onto near plane in worldspace - Real nearx1 = (Nz1 * mNearDist) / Nx1; - // now we need to map this to viewport coords - // use projection matrix since that will take into account all factors - Vector3 relx1 = projMatrix * Vector3(nearx1, 0, -mNearDist); - - // find out whether this is a left side or right side - Real Px1 = -(Pz1 * Nz1) / Nx1; - if (Px1 > eyeSpacePos.x) - { - *right = std::min(*right, relx1.x); - } - else - { - *left = std::max(*left, relx1.x); - } - } - } - - - // Now YZ - // calculate quadratic discriminant: b*b - 4ac - // x = Ny - // a = Ly^2 + Lz^2 - // b = -2rLy - // c = r^2 - Lz^2 - a = Lyz; - b = -2.0f * r * eyeSpacePos.y; - c = rsq - Math::Sqr(eyeSpacePos.z); - D = b*b - 4.0f*a*c; - - // two roots? - if (D > 0) - { - Real sqrootD = Math::Sqrt(D); - // solve the quadratic to get the components of the normal - Real Ny0 = (-b + sqrootD) / (2 * a); - Real Ny1 = (-b - sqrootD) / (2 * a); - - // Derive Z from this - Real Nz0 = (r - Ny0 * eyeSpacePos.y) / eyeSpacePos.z; - Real Nz1 = (r - Ny1 * eyeSpacePos.y) / eyeSpacePos.z; - - // Get the point of tangency - // Only consider points of tangency in front of the camera - Real Pz0 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz0 / Ny0) * eyeSpacePos.y)); - if (Pz0 < 0) - { - // Project point onto near plane in worldspace - Real neary0 = (Nz0 * mNearDist) / Ny0; - // now we need to map this to viewport coords - // use projection matriy since that will take into account all factors - Vector3 rely0 = projMatrix * Vector3(0, neary0, -mNearDist); - - // find out whether this is a top side or bottom side - Real Py0 = -(Pz0 * Nz0) / Ny0; - if (Py0 > eyeSpacePos.y) - { - *top = std::min(*top, rely0.y); - } - else - { - *bottom = std::max(*bottom, rely0.y); - } - } - Real Pz1 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz1 / Ny1) * eyeSpacePos.y)); - if (Pz1 < 0) - { - // Project point onto near plane in worldspace - Real neary1 = (Nz1 * mNearDist) / Ny1; - // now we need to map this to viewport coords - // use projection matriy since that will take into account all factors - Vector3 rely1 = projMatrix * Vector3(0, neary1, -mNearDist); - - // find out whether this is a top side or bottom side - Real Py1 = -(Pz1 * Nz1) / Ny1; - if (Py1 > eyeSpacePos.y) - { - *top = std::min(*top, rely1.y); - } - else - { - *bottom = std::max(*bottom, rely1.y); - } - } - } + Real Lxz = Math::Sqr(eyeSpacePos.x) + Math::Sqr(eyeSpacePos.z); + Real Lyz = Math::Sqr(eyeSpacePos.y) + Math::Sqr(eyeSpacePos.z); + + // Find the tangent planes to the sphere + // XZ first + // calculate quadratic discriminant: b*b - 4ac + // x = Nx + // a = Lx^2 + Lz^2 + // b = -2rLx + // c = r^2 - Lz^2 + Real a = Lxz; + Real b = -2.0f * r * eyeSpacePos.x; + Real c = rsq - Math::Sqr(eyeSpacePos.z); + Real D = b*b - 4.0f*a*c; + + // two roots? + if (D > 0) + { + Real sqrootD = Math::Sqrt(D); + // solve the quadratic to get the components of the normal + Real Nx0 = (-b + sqrootD) / (2 * a); + Real Nx1 = (-b - sqrootD) / (2 * a); + + // Derive Z from this + Real Nz0 = (r - Nx0 * eyeSpacePos.x) / eyeSpacePos.z; + Real Nz1 = (r - Nx1 * eyeSpacePos.x) / eyeSpacePos.z; + + // Get the point of tangency + // Only consider points of tangency in front of the camera + Real Pz0 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz0 / Nx0) * eyeSpacePos.x)); + if (Pz0 < 0) + { + // Project point onto near plane in worldspace + Real nearx0 = (Nz0 * mNearDist) / Nx0; + // now we need to map this to viewport coords + // use projection matrix since that will take into account all factors + Vector3 relx0 = projMatrix * Vector3(nearx0, 0, -mNearDist); + + // find out whether this is a left side or right side + Real Px0 = -(Pz0 * Nz0) / Nx0; + if (Px0 > eyeSpacePos.x) + { + *right = std::min(*right, relx0.x); + } + else + { + *left = std::max(*left, relx0.x); + } + } + Real Pz1 = (Lxz - rsq) / (eyeSpacePos.z - ((Nz1 / Nx1) * eyeSpacePos.x)); + if (Pz1 < 0) + { + // Project point onto near plane in worldspace + Real nearx1 = (Nz1 * mNearDist) / Nx1; + // now we need to map this to viewport coords + // use projection matrix since that will take into account all factors + Vector3 relx1 = projMatrix * Vector3(nearx1, 0, -mNearDist); + + // find out whether this is a left side or right side + Real Px1 = -(Pz1 * Nz1) / Nx1; + if (Px1 > eyeSpacePos.x) + { + *right = std::min(*right, relx1.x); + } + else + { + *left = std::max(*left, relx1.x); + } + } + } + + + // Now YZ + // calculate quadratic discriminant: b*b - 4ac + // x = Ny + // a = Ly^2 + Lz^2 + // b = -2rLy + // c = r^2 - Lz^2 + a = Lyz; + b = -2.0f * r * eyeSpacePos.y; + c = rsq - Math::Sqr(eyeSpacePos.z); + D = b*b - 4.0f*a*c; + + // two roots? + if (D > 0) + { + Real sqrootD = Math::Sqrt(D); + // solve the quadratic to get the components of the normal + Real Ny0 = (-b + sqrootD) / (2 * a); + Real Ny1 = (-b - sqrootD) / (2 * a); + + // Derive Z from this + Real Nz0 = (r - Ny0 * eyeSpacePos.y) / eyeSpacePos.z; + Real Nz1 = (r - Ny1 * eyeSpacePos.y) / eyeSpacePos.z; + + // Get the point of tangency + // Only consider points of tangency in front of the camera + Real Pz0 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz0 / Ny0) * eyeSpacePos.y)); + if (Pz0 < 0) + { + // Project point onto near plane in worldspace + Real neary0 = (Nz0 * mNearDist) / Ny0; + // now we need to map this to viewport coords + // use projection matriy since that will take into account all factors + Vector3 rely0 = projMatrix * Vector3(0, neary0, -mNearDist); + + // find out whether this is a top side or bottom side + Real Py0 = -(Pz0 * Nz0) / Ny0; + if (Py0 > eyeSpacePos.y) + { + *top = std::min(*top, rely0.y); + } + else + { + *bottom = std::max(*bottom, rely0.y); + } + } + Real Pz1 = (Lyz - rsq) / (eyeSpacePos.z - ((Nz1 / Ny1) * eyeSpacePos.y)); + if (Pz1 < 0) + { + // Project point onto near plane in worldspace + Real neary1 = (Nz1 * mNearDist) / Ny1; + // now we need to map this to viewport coords + // use projection matriy since that will take into account all factors + Vector3 rely1 = projMatrix * Vector3(0, neary1, -mNearDist); + + // find out whether this is a top side or bottom side + Real Py1 = -(Pz1 * Nz1) / Ny1; + if (Py1 > eyeSpacePos.y) + { + *top = std::min(*top, rely1.y); + } + else + { + *bottom = std::max(*bottom, rely1.y); + } + } + } } return (*left != -1.0f) || (*top != 1.0f) || (*right != 1.0f) || (*bottom != -1.0f); @@ -1254,106 +1254,106 @@ namespace Ogre { invalidateFrustum(); } //--------------------------------------------------------------------- - void Frustum::setCustomViewMatrix(bool enable, const Matrix4& viewMatrix) - { - mCustomViewMatrix = enable; - if (enable) - { + void Frustum::setCustomViewMatrix(bool enable, const Matrix4& viewMatrix) + { + mCustomViewMatrix = enable; + if (enable) + { assert(viewMatrix.isAffine()); - mViewMatrix = viewMatrix; - } - invalidateView(); - } + mViewMatrix = viewMatrix; + } + invalidateView(); + } + //--------------------------------------------------------------------- + void Frustum::setCustomProjectionMatrix(bool enable, const Matrix4& projMatrix) + { + mCustomProjMatrix = enable; + if (enable) + { + mProjMatrix = projMatrix; + } + invalidateFrustum(); + } + //--------------------------------------------------------------------- + void Frustum::setOrthoWindow(Real w, Real h) + { + mOrthoHeight = h; + mAspect = w / h; + invalidateFrustum(); + } + //--------------------------------------------------------------------- + void Frustum::setOrthoWindowHeight(Real h) + { + mOrthoHeight = h; + invalidateFrustum(); + } //--------------------------------------------------------------------- - void Frustum::setCustomProjectionMatrix(bool enable, const Matrix4& projMatrix) - { - mCustomProjMatrix = enable; - if (enable) - { - mProjMatrix = projMatrix; - } - invalidateFrustum(); - } - //--------------------------------------------------------------------- - void Frustum::setOrthoWindow(Real w, Real h) - { - mOrthoHeight = h; - mAspect = w / h; - invalidateFrustum(); - } - //--------------------------------------------------------------------- - void Frustum::setOrthoWindowHeight(Real h) - { - mOrthoHeight = h; - invalidateFrustum(); - } - //--------------------------------------------------------------------- - void Frustum::setOrthoWindowWidth(Real w) - { - mOrthoHeight = w / mAspect; - invalidateFrustum(); - } - //--------------------------------------------------------------------- - Real Frustum::getOrthoWindowHeight() const - { - return mOrthoHeight; - } - //--------------------------------------------------------------------- - Real Frustum::getOrthoWindowWidth() const - { - return mOrthoHeight * mAspect; - } - //--------------------------------------------------------------------- - void Frustum::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - // Only displayed in debug - if (debugRenderables) - { - visitor->visit(this, 0, true); - } - - } - //--------------------------------------------------------------------- - void Frustum::setFrustumExtents(Real left, Real right, Real top, Real bottom) - { - mFrustumExtentsManuallySet = true; - mLeft = left; - mRight = right; - mTop = top; - mBottom = bottom; - - invalidateFrustum(); - } - //--------------------------------------------------------------------- - void Frustum::resetFrustumExtents() - { - mFrustumExtentsManuallySet = false; - invalidateFrustum(); - } - //--------------------------------------------------------------------- - void Frustum::getFrustumExtents(Real& outleft, Real& outright, Real& outtop, Real& outbottom) const - { - updateFrustum(); - outleft = mLeft; - outright = mRight; - outtop = mTop; - outbottom = mBottom; - } - //--------------------------------------------------------------------- - PlaneBoundedVolume Frustum::getPlaneBoundedVolume() - { - updateFrustumPlanes(); - - PlaneBoundedVolume volume; - volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_NEAR]); - volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_FAR]); - volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_BOTTOM]); - volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_TOP]); - volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_LEFT]); - volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_RIGHT]); - return volume; - } + void Frustum::setOrthoWindowWidth(Real w) + { + mOrthoHeight = w / mAspect; + invalidateFrustum(); + } + //--------------------------------------------------------------------- + Real Frustum::getOrthoWindowHeight() const + { + return mOrthoHeight; + } + //--------------------------------------------------------------------- + Real Frustum::getOrthoWindowWidth() const + { + return mOrthoHeight * mAspect; + } + //--------------------------------------------------------------------- + void Frustum::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + // Only displayed in debug + if (debugRenderables) + { + visitor->visit(this, 0, true); + } + + } + //--------------------------------------------------------------------- + void Frustum::setFrustumExtents(Real left, Real right, Real top, Real bottom) + { + mFrustumExtentsManuallySet = true; + mLeft = left; + mRight = right; + mTop = top; + mBottom = bottom; + + invalidateFrustum(); + } + //--------------------------------------------------------------------- + void Frustum::resetFrustumExtents() + { + mFrustumExtentsManuallySet = false; + invalidateFrustum(); + } + //--------------------------------------------------------------------- + void Frustum::getFrustumExtents(Real& outleft, Real& outright, Real& outtop, Real& outbottom) const + { + updateFrustum(); + outleft = mLeft; + outright = mRight; + outtop = mTop; + outbottom = mBottom; + } + //--------------------------------------------------------------------- + PlaneBoundedVolume Frustum::getPlaneBoundedVolume() + { + updateFrustumPlanes(); + + PlaneBoundedVolume volume; + volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_NEAR]); + volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_FAR]); + volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_BOTTOM]); + volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_TOP]); + volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_LEFT]); + volume.planes.push_back(mFrustumPlanes[FRUSTUM_PLANE_RIGHT]); + return volume; + } //--------------------------------------------------------------------- void Frustum::setOrientationMode(OrientationMode orientationMode) { diff --git a/OgreMain/src/OgreGpuProgram.cpp b/OgreMain/src/OgreGpuProgram.cpp index d3bb174a428..52b53b0d5aa 100644 --- a/OgreMain/src/OgreGpuProgram.cpp +++ b/OgreMain/src/OgreGpuProgram.cpp @@ -46,18 +46,18 @@ namespace Ogre GpuProgram::CmdManualNamedConstsFile GpuProgram::msManNamedConstsFileCmd; GpuProgram::CmdAdjacency GpuProgram::msAdjacencyCmd; GpuProgram::CmdComputeGroupDims GpuProgram::msComputeGroupDimsCmd; - + //----------------------------------------------------------------------------- GpuProgram::GpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) :Resource(creator, name, handle, group, isManual, loader), mType(GPT_VERTEX_PROGRAM), mLoadFromFile(true), mSkeletalAnimation(false), - mMorphAnimation(false), mPoseAnimation(0), + mMorphAnimation(false), mPoseAnimation(0), mVertexTextureFetch(false), mNeedsAdjacencyInfo(false), - mCompileError(false), mLoadedManualNamedConstants(false) + mCompileError(false), mLoadedManualNamedConstants(false) { - createParameterMappingStructures(); + createParameterMappingStructures(); } //----------------------------------------------------------------------------- void GpuProgram::setType(GpuProgramType t) @@ -75,7 +75,7 @@ namespace Ogre mFilename = filename; mSource.clear(); mLoadFromFile = true; - mCompileError = false; + mCompileError = false; } //----------------------------------------------------------------------------- void GpuProgram::setSource(const String& source) @@ -83,7 +83,7 @@ namespace Ogre mSource = source; mFilename.clear(); mLoadFromFile = false; - mCompileError = false; + mCompileError = false; } size_t GpuProgram::calculateSize(void) const { @@ -118,47 +118,47 @@ namespace Ogre // find & load source code DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource( - mFilename, mGroup, true, this); + mFilename, mGroup, true, this); mSource = stream->getAsString(); } // Call polymorphic load - try - { - loadFromSource(); + try + { + loadFromSource(); - if (!mDefaultParams.isNull()) - { - // Keep a reference to old ones to copy - GpuProgramParametersSharedPtr savedParams = mDefaultParams; - // reset params to stop them being referenced in the next create - mDefaultParams.setNull(); + if (!mDefaultParams.isNull()) + { + // Keep a reference to old ones to copy + GpuProgramParametersSharedPtr savedParams = mDefaultParams; + // reset params to stop them being referenced in the next create + mDefaultParams.setNull(); - // Create new params - mDefaultParams = createParameters(); + // Create new params + mDefaultParams = createParameters(); - // Copy old (matching) values across - // Don't use copyConstantsFrom since program may be different - mDefaultParams->copyMatchingNamedConstantsFrom(*savedParams.get()); + // Copy old (matching) values across + // Don't use copyConstantsFrom since program may be different + mDefaultParams->copyMatchingNamedConstantsFrom(*savedParams.get()); - } - } - catch (const Exception&) - { - // will already have been logged - LogManager::getSingleton().stream() - << "Gpu program " << mName << " encountered an error " - << "during loading and is thus not supported."; + } + } + catch (const Exception&) + { + // will already have been logged + LogManager::getSingleton().stream() + << "Gpu program " << mName << " encountered an error " + << "during loading and is thus not supported."; - mCompileError = true; - } + mCompileError = true; + } } //----------------------------------------------------------------------------- bool GpuProgram::isRequiredCapabilitiesSupported(void) const { - const RenderSystemCapabilities* caps = - Root::getSingleton().getRenderSystem()->getCapabilities(); + const RenderSystemCapabilities* caps = + Root::getSingleton().getRenderSystem()->getCapabilities(); // If skeletal animation is being done, we need support for UBYTE4 if (isSkeletalAnimationIncluded() && @@ -167,12 +167,12 @@ namespace Ogre return false; } - // Vertex texture fetch required? - if (isVertexTextureFetchRequired() && - !caps->hasCapability(RSC_VERTEX_TEXTURE_FETCH)) - { - return false; - } + // Vertex texture fetch required? + if (isVertexTextureFetchRequired() && + !caps->hasCapability(RSC_VERTEX_TEXTURE_FETCH)) + { + return false; + } return true; } @@ -184,103 +184,103 @@ namespace Ogre return GpuProgramManager::getSingleton().isSyntaxSupported(mSyntaxCode); } - //--------------------------------------------------------------------- - void GpuProgram::createParameterMappingStructures(bool recreateIfExists) const - { - createLogicalParameterMappingStructures(recreateIfExists); - createNamedParameterMappingStructures(recreateIfExists); - } - //--------------------------------------------------------------------- - void GpuProgram::createLogicalParameterMappingStructures(bool recreateIfExists) const - { - if (recreateIfExists || mFloatLogicalToPhysical.isNull()) - mFloatLogicalToPhysical = GpuLogicalBufferStructPtr(OGRE_NEW GpuLogicalBufferStruct()); - if (recreateIfExists || mIntLogicalToPhysical.isNull()) - mIntLogicalToPhysical = GpuLogicalBufferStructPtr(OGRE_NEW GpuLogicalBufferStruct()); - } - //--------------------------------------------------------------------- - void GpuProgram::createNamedParameterMappingStructures(bool recreateIfExists) const - { - if (recreateIfExists || mConstantDefs.isNull()) - mConstantDefs = GpuNamedConstantsPtr(OGRE_NEW GpuNamedConstants()); - } - //--------------------------------------------------------------------- - void GpuProgram::setManualNamedConstantsFile(const String& paramDefFile) - { - mManualNamedConstantsFile = paramDefFile; - mLoadedManualNamedConstants = false; - } - //--------------------------------------------------------------------- - void GpuProgram::setManualNamedConstants(const GpuNamedConstants& namedConstants) - { - createParameterMappingStructures(); - *mConstantDefs.get() = namedConstants; + //--------------------------------------------------------------------- + void GpuProgram::createParameterMappingStructures(bool recreateIfExists) const + { + createLogicalParameterMappingStructures(recreateIfExists); + createNamedParameterMappingStructures(recreateIfExists); + } + //--------------------------------------------------------------------- + void GpuProgram::createLogicalParameterMappingStructures(bool recreateIfExists) const + { + if (recreateIfExists || mFloatLogicalToPhysical.isNull()) + mFloatLogicalToPhysical = GpuLogicalBufferStructPtr(OGRE_NEW GpuLogicalBufferStruct()); + if (recreateIfExists || mIntLogicalToPhysical.isNull()) + mIntLogicalToPhysical = GpuLogicalBufferStructPtr(OGRE_NEW GpuLogicalBufferStruct()); + } + //--------------------------------------------------------------------- + void GpuProgram::createNamedParameterMappingStructures(bool recreateIfExists) const + { + if (recreateIfExists || mConstantDefs.isNull()) + mConstantDefs = GpuNamedConstantsPtr(OGRE_NEW GpuNamedConstants()); + } + //--------------------------------------------------------------------- + void GpuProgram::setManualNamedConstantsFile(const String& paramDefFile) + { + mManualNamedConstantsFile = paramDefFile; + mLoadedManualNamedConstants = false; + } + //--------------------------------------------------------------------- + void GpuProgram::setManualNamedConstants(const GpuNamedConstants& namedConstants) + { + createParameterMappingStructures(); + *mConstantDefs.get() = namedConstants; - mFloatLogicalToPhysical->bufferSize = mConstantDefs->floatBufferSize; - mIntLogicalToPhysical->bufferSize = mConstantDefs->intBufferSize; - mFloatLogicalToPhysical->map.clear(); - mIntLogicalToPhysical->map.clear(); - // need to set up logical mappings too for some rendersystems - for (GpuConstantDefinitionMap::const_iterator i = mConstantDefs->map.begin(); - i != mConstantDefs->map.end(); ++i) - { - const String& name = i->first; - const GpuConstantDefinition& def = i->second; - // only consider non-array entries - if (name.find("[") == String::npos) - { - GpuLogicalIndexUseMap::value_type val(def.logicalIndex, - GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, def.variability)); - if (def.isFloat()) - { - mFloatLogicalToPhysical->map.insert(val); - } - else - { - mIntLogicalToPhysical->map.insert(val); - } - } - } + mFloatLogicalToPhysical->bufferSize = mConstantDefs->floatBufferSize; + mIntLogicalToPhysical->bufferSize = mConstantDefs->intBufferSize; + mFloatLogicalToPhysical->map.clear(); + mIntLogicalToPhysical->map.clear(); + // need to set up logical mappings too for some rendersystems + for (GpuConstantDefinitionMap::const_iterator i = mConstantDefs->map.begin(); + i != mConstantDefs->map.end(); ++i) + { + const String& name = i->first; + const GpuConstantDefinition& def = i->second; + // only consider non-array entries + if (name.find("[") == String::npos) + { + GpuLogicalIndexUseMap::value_type val(def.logicalIndex, + GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, def.variability)); + if (def.isFloat()) + { + mFloatLogicalToPhysical->map.insert(val); + } + else + { + mIntLogicalToPhysical->map.insert(val); + } + } + } - } + } //----------------------------------------------------------------------------- GpuProgramParametersSharedPtr GpuProgram::createParameters(void) { // Default implementation simply returns standard parameters. GpuProgramParametersSharedPtr ret = GpuProgramManager::getSingleton().createParameters(); - - - // optionally load manually supplied named constants - if (!mManualNamedConstantsFile.empty() && !mLoadedManualNamedConstants) - { - try - { - GpuNamedConstants namedConstants; - DataStreamPtr stream = - ResourceGroupManager::getSingleton().openResource( - mManualNamedConstantsFile, mGroup, true, this); - namedConstants.load(stream); - setManualNamedConstants(namedConstants); - } - catch(const Exception& e) - { - LogManager::getSingleton().stream() << - "Unable to load manual named constants for GpuProgram " << mName << - ": " << e.getDescription(); - } - mLoadedManualNamedConstants = true; - } - - - // set up named parameters, if any - if (!mConstantDefs.isNull() && !mConstantDefs->map.empty()) - { - ret->_setNamedConstants(mConstantDefs); - } - // link shared logical / physical map for low-level use - ret->_setLogicalIndexes(mFloatLogicalToPhysical, mDoubleLogicalToPhysical, + + + // optionally load manually supplied named constants + if (!mManualNamedConstantsFile.empty() && !mLoadedManualNamedConstants) + { + try + { + GpuNamedConstants namedConstants; + DataStreamPtr stream = + ResourceGroupManager::getSingleton().openResource( + mManualNamedConstantsFile, mGroup, true, this); + namedConstants.load(stream); + setManualNamedConstants(namedConstants); + } + catch(const Exception& e) + { + LogManager::getSingleton().stream() << + "Unable to load manual named constants for GpuProgram " << mName << + ": " << e.getDescription(); + } + mLoadedManualNamedConstants = true; + } + + + // set up named parameters, if any + if (!mConstantDefs.isNull() && !mConstantDefs->map.empty()) + { + ret->_setNamedConstants(mConstantDefs); + } + // link shared logical / physical map for low-level use + ret->_setLogicalIndexes(mFloatLogicalToPhysical, mDoubleLogicalToPhysical, mIntLogicalToPhysical, mUIntLogicalToPhysical, mBoolLogicalToPhysical); @@ -356,23 +356,23 @@ namespace Ogre { return "vertex_program"; } - else if (t->getType() == GPT_GEOMETRY_PROGRAM) - { - return "geometry_program"; - } - else if (t->getType() == GPT_DOMAIN_PROGRAM) - { - return "domain_program"; - } - else if (t->getType() == GPT_HULL_PROGRAM) - { - return "hull_program"; - } - else if (t->getType() == GPT_COMPUTE_PROGRAM) - { - return "compute_program"; - } - else + else if (t->getType() == GPT_GEOMETRY_PROGRAM) + { + return "geometry_program"; + } + else if (t->getType() == GPT_DOMAIN_PROGRAM) + { + return "domain_program"; + } + else if (t->getType() == GPT_HULL_PROGRAM) + { + return "hull_program"; + } + else if (t->getType() == GPT_COMPUTE_PROGRAM) + { + return "compute_program"; + } + else { return "fragment_program"; } @@ -385,22 +385,22 @@ namespace Ogre t->setType(GPT_VERTEX_PROGRAM); } else if (val == "geometry_program") - { - t->setType(GPT_GEOMETRY_PROGRAM); - } - else if (val == "domain_program") - { - t->setType(GPT_DOMAIN_PROGRAM); - } - else if (val == "hull_program") - { - t->setType(GPT_HULL_PROGRAM); - } - else if (val == "compute_program") - { - t->setType(GPT_COMPUTE_PROGRAM); - } - else + { + t->setType(GPT_GEOMETRY_PROGRAM); + } + else if (val == "domain_program") + { + t->setType(GPT_DOMAIN_PROGRAM); + } + else if (val == "hull_program") + { + t->setType(GPT_HULL_PROGRAM); + } + else if (val == "compute_program") + { + t->setType(GPT_COMPUTE_PROGRAM); + } + else { t->setType(GPT_FRAGMENT_PROGRAM); } @@ -427,50 +427,50 @@ namespace Ogre GpuProgram* t = static_cast(target); t->setSkeletalAnimationIncluded(StringConverter::parseBool(val)); } - //----------------------------------------------------------------------- - String GpuProgram::CmdMorph::doGet(const void* target) const - { - const GpuProgram* t = static_cast(target); - return StringConverter::toString(t->isMorphAnimationIncluded()); - } - void GpuProgram::CmdMorph::doSet(void* target, const String& val) - { - GpuProgram* t = static_cast(target); - t->setMorphAnimationIncluded(StringConverter::parseBool(val)); - } - //----------------------------------------------------------------------- - String GpuProgram::CmdPose::doGet(const void* target) const - { - const GpuProgram* t = static_cast(target); - return StringConverter::toString(t->getNumberOfPosesIncluded()); - } - void GpuProgram::CmdPose::doSet(void* target, const String& val) - { - GpuProgram* t = static_cast(target); - t->setPoseAnimationIncluded((ushort)StringConverter::parseUnsignedInt(val)); - } - //----------------------------------------------------------------------- - String GpuProgram::CmdVTF::doGet(const void* target) const - { - const GpuProgram* t = static_cast(target); - return StringConverter::toString(t->isVertexTextureFetchRequired()); - } - void GpuProgram::CmdVTF::doSet(void* target, const String& val) - { - GpuProgram* t = static_cast(target); - t->setVertexTextureFetchRequired(StringConverter::parseBool(val)); - } - //----------------------------------------------------------------------- - String GpuProgram::CmdManualNamedConstsFile::doGet(const void* target) const - { - const GpuProgram* t = static_cast(target); - return t->getManualNamedConstantsFile(); - } - void GpuProgram::CmdManualNamedConstsFile::doSet(void* target, const String& val) - { - GpuProgram* t = static_cast(target); - t->setManualNamedConstantsFile(val); - } + //----------------------------------------------------------------------- + String GpuProgram::CmdMorph::doGet(const void* target) const + { + const GpuProgram* t = static_cast(target); + return StringConverter::toString(t->isMorphAnimationIncluded()); + } + void GpuProgram::CmdMorph::doSet(void* target, const String& val) + { + GpuProgram* t = static_cast(target); + t->setMorphAnimationIncluded(StringConverter::parseBool(val)); + } + //----------------------------------------------------------------------- + String GpuProgram::CmdPose::doGet(const void* target) const + { + const GpuProgram* t = static_cast(target); + return StringConverter::toString(t->getNumberOfPosesIncluded()); + } + void GpuProgram::CmdPose::doSet(void* target, const String& val) + { + GpuProgram* t = static_cast(target); + t->setPoseAnimationIncluded((ushort)StringConverter::parseUnsignedInt(val)); + } + //----------------------------------------------------------------------- + String GpuProgram::CmdVTF::doGet(const void* target) const + { + const GpuProgram* t = static_cast(target); + return StringConverter::toString(t->isVertexTextureFetchRequired()); + } + void GpuProgram::CmdVTF::doSet(void* target, const String& val) + { + GpuProgram* t = static_cast(target); + t->setVertexTextureFetchRequired(StringConverter::parseBool(val)); + } + //----------------------------------------------------------------------- + String GpuProgram::CmdManualNamedConstsFile::doGet(const void* target) const + { + const GpuProgram* t = static_cast(target); + return t->getManualNamedConstantsFile(); + } + void GpuProgram::CmdManualNamedConstsFile::doSet(void* target, const String& val) + { + GpuProgram* t = static_cast(target); + t->setManualNamedConstantsFile(val); + } //----------------------------------------------------------------------- String GpuProgram::CmdAdjacency::doGet(const void* target) const { diff --git a/OgreMain/src/OgreGpuProgramManager.cpp b/OgreMain/src/OgreGpuProgramManager.cpp index fd1b09d70d5..b08d0bb1f53 100644 --- a/OgreMain/src/OgreGpuProgramManager.cpp +++ b/OgreMain/src/OgreGpuProgramManager.cpp @@ -48,56 +48,56 @@ namespace Ogre { { return getResourceByName(name, preferHighLevelPrograms).staticCast(); } - //--------------------------------------------------------------------------- - GpuProgramManager::GpuProgramManager() - { - // Loading order - mLoadOrder = 50.0f; - // Resource type - mResourceType = "GpuProgram"; - mSaveMicrocodesToCache = false; - mCacheDirty = false; + //--------------------------------------------------------------------------- + GpuProgramManager::GpuProgramManager() + { + // Loading order + mLoadOrder = 50.0f; + // Resource type + mResourceType = "GpuProgram"; + mSaveMicrocodesToCache = false; + mCacheDirty = false; - // subclasses should register with resource group manager - } - //--------------------------------------------------------------------------- - GpuProgramManager::~GpuProgramManager() - { - // subclasses should unregister with resource group manager - } - //--------------------------------------------------------------------------- + // subclasses should register with resource group manager + } + //--------------------------------------------------------------------------- + GpuProgramManager::~GpuProgramManager() + { + // subclasses should unregister with resource group manager + } + //--------------------------------------------------------------------------- GpuProgramPtr GpuProgramManager::load(const String& name, - const String& groupName, const String& filename, - GpuProgramType gptype, const String& syntaxCode) + const String& groupName, const String& filename, + GpuProgramType gptype, const String& syntaxCode) { - GpuProgramPtr prg; - { + GpuProgramPtr prg; + { OGRE_LOCK_AUTO_MUTEX; prg = getByName(name); - if (prg.isNull()) - { - prg = createProgram(name, groupName, filename, gptype, syntaxCode); - } + if (prg.isNull()) + { + prg = createProgram(name, groupName, filename, gptype, syntaxCode); + } - } + } prg->load(); return prg; } //--------------------------------------------------------------------------- - GpuProgramPtr GpuProgramManager::loadFromString(const String& name, - const String& groupName, const String& code, + GpuProgramPtr GpuProgramManager::loadFromString(const String& name, + const String& groupName, const String& code, GpuProgramType gptype, const String& syntaxCode) { - GpuProgramPtr prg; - { + GpuProgramPtr prg; + { OGRE_LOCK_AUTO_MUTEX; prg = getByName(name); - if (prg.isNull()) - { - prg = createProgramFromString(name, groupName, code, gptype, syntaxCode); - } + if (prg.isNull()) + { + prg = createProgramFromString(name, groupName, code, gptype, syntaxCode); + } - } + } prg->load(); return prg; } @@ -116,27 +116,27 @@ namespace Ogre { return ret; } //--------------------------------------------------------------------------- - GpuProgramPtr GpuProgramManager::createProgram(const String& name, - const String& groupName, const String& filename, - GpuProgramType gptype, const String& syntaxCode) + GpuProgramPtr GpuProgramManager::createProgram(const String& name, + const String& groupName, const String& filename, + GpuProgramType gptype, const String& syntaxCode) { - GpuProgramPtr prg = create(name, groupName, gptype, syntaxCode).staticCast(); + GpuProgramPtr prg = create(name, groupName, gptype, syntaxCode).staticCast(); // Set all prarmeters (create does not set, just determines factory) - prg->setType(gptype); - prg->setSyntaxCode(syntaxCode); - prg->setSourceFile(filename); + prg->setType(gptype); + prg->setSyntaxCode(syntaxCode); + prg->setSourceFile(filename); return prg; } //--------------------------------------------------------------------------- - GpuProgramPtr GpuProgramManager::createProgramFromString(const String& name, - const String& groupName, const String& code, GpuProgramType gptype, - const String& syntaxCode) + GpuProgramPtr GpuProgramManager::createProgramFromString(const String& name, + const String& groupName, const String& code, GpuProgramType gptype, + const String& syntaxCode) { - GpuProgramPtr prg = create(name, groupName, gptype, syntaxCode).staticCast(); + GpuProgramPtr prg = create(name, groupName, gptype, syntaxCode).staticCast(); // Set all prarmeters (create does not set, just determines factory) - prg->setType(gptype); - prg->setSyntaxCode(syntaxCode); - prg->setSource(code); + prg->setType(gptype); + prg->setSyntaxCode(syntaxCode); + prg->setSource(code); return prg; } //--------------------------------------------------------------------------- @@ -170,195 +170,195 @@ namespace Ogre { } return ResourceManager::getResourceByName(name); } - //----------------------------------------------------------------------------- - GpuProgramParametersSharedPtr GpuProgramManager::createParameters(void) - { - return GpuProgramParametersSharedPtr(OGRE_NEW GpuProgramParameters()); - } - //--------------------------------------------------------------------- - GpuSharedParametersPtr GpuProgramManager::createSharedParameters(const String& name) - { - if (mSharedParametersMap.find(name) != mSharedParametersMap.end()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "The shared parameter set '" + name + "' already exists!", - "GpuProgramManager::createSharedParameters"); - } - GpuSharedParametersPtr ret(OGRE_NEW GpuSharedParameters(name)); - mSharedParametersMap[name] = ret; - return ret; - } - //--------------------------------------------------------------------- - GpuSharedParametersPtr GpuProgramManager::getSharedParameters(const String& name) const - { - SharedParametersMap::const_iterator i = mSharedParametersMap.find(name); - if (i == mSharedParametersMap.end()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "No shared parameter set with name '" + name + "'!", - "GpuProgramManager::createSharedParameters"); - } - return i->second; - } - //--------------------------------------------------------------------- - const GpuProgramManager::SharedParametersMap& - GpuProgramManager::getAvailableSharedParameters() const - { - return mSharedParametersMap; - } - //--------------------------------------------------------------------- - bool GpuProgramManager::getSaveMicrocodesToCache() - { - return mSaveMicrocodesToCache; - } - //--------------------------------------------------------------------- - bool GpuProgramManager::canGetCompiledShaderBuffer() - { - // Use the current render system - RenderSystem* rs = Root::getSingleton().getRenderSystem(); + //----------------------------------------------------------------------------- + GpuProgramParametersSharedPtr GpuProgramManager::createParameters(void) + { + return GpuProgramParametersSharedPtr(OGRE_NEW GpuProgramParameters()); + } + //--------------------------------------------------------------------- + GpuSharedParametersPtr GpuProgramManager::createSharedParameters(const String& name) + { + if (mSharedParametersMap.find(name) != mSharedParametersMap.end()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "The shared parameter set '" + name + "' already exists!", + "GpuProgramManager::createSharedParameters"); + } + GpuSharedParametersPtr ret(OGRE_NEW GpuSharedParameters(name)); + mSharedParametersMap[name] = ret; + return ret; + } + //--------------------------------------------------------------------- + GpuSharedParametersPtr GpuProgramManager::getSharedParameters(const String& name) const + { + SharedParametersMap::const_iterator i = mSharedParametersMap.find(name); + if (i == mSharedParametersMap.end()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "No shared parameter set with name '" + name + "'!", + "GpuProgramManager::createSharedParameters"); + } + return i->second; + } + //--------------------------------------------------------------------- + const GpuProgramManager::SharedParametersMap& + GpuProgramManager::getAvailableSharedParameters() const + { + return mSharedParametersMap; + } + //--------------------------------------------------------------------- + bool GpuProgramManager::getSaveMicrocodesToCache() + { + return mSaveMicrocodesToCache; + } + //--------------------------------------------------------------------- + bool GpuProgramManager::canGetCompiledShaderBuffer() + { + // Use the current render system + RenderSystem* rs = Root::getSingleton().getRenderSystem(); - // Check if the supported - return rs->getCapabilities()->hasCapability(RSC_CAN_GET_COMPILED_SHADER_BUFFER); - } - //--------------------------------------------------------------------- - void GpuProgramManager::setSaveMicrocodesToCache( const bool val ) - { + // Check if the supported + return rs->getCapabilities()->hasCapability(RSC_CAN_GET_COMPILED_SHADER_BUFFER); + } + //--------------------------------------------------------------------- + void GpuProgramManager::setSaveMicrocodesToCache( const bool val ) + { // Check that saving shader microcode is supported if(!canGetCompiledShaderBuffer()) mSaveMicrocodesToCache = false; else mSaveMicrocodesToCache = val; - } - //--------------------------------------------------------------------- - bool GpuProgramManager::isCacheDirty( void ) const - { - return mCacheDirty; - } - //--------------------------------------------------------------------- - String GpuProgramManager::addRenderSystemToName( const String & name ) - { - // Use the current render system - RenderSystem* rs = Root::getSingleton().getRenderSystem(); + } + //--------------------------------------------------------------------- + bool GpuProgramManager::isCacheDirty( void ) const + { + return mCacheDirty; + } + //--------------------------------------------------------------------- + String GpuProgramManager::addRenderSystemToName( const String & name ) + { + // Use the current render system + RenderSystem* rs = Root::getSingleton().getRenderSystem(); - return rs->getName() + "_" + name; - } - //--------------------------------------------------------------------- - bool GpuProgramManager::isMicrocodeAvailableInCache( const String & name ) const - { - return mMicrocodeCache.find(addRenderSystemToName(name)) != mMicrocodeCache.end(); - } - //--------------------------------------------------------------------- - const GpuProgramManager::Microcode & GpuProgramManager::getMicrocodeFromCache( const String & name ) const - { - return mMicrocodeCache.find(addRenderSystemToName(name))->second; - } - //--------------------------------------------------------------------- + return rs->getName() + "_" + name; + } + //--------------------------------------------------------------------- + bool GpuProgramManager::isMicrocodeAvailableInCache( const String & name ) const + { + return mMicrocodeCache.find(addRenderSystemToName(name)) != mMicrocodeCache.end(); + } + //--------------------------------------------------------------------- + const GpuProgramManager::Microcode & GpuProgramManager::getMicrocodeFromCache( const String & name ) const + { + return mMicrocodeCache.find(addRenderSystemToName(name))->second; + } + //--------------------------------------------------------------------- GpuProgramManager::Microcode GpuProgramManager::createMicrocode( const uint32 size ) const - { - return Microcode(OGRE_NEW MemoryDataStream(size)); - } - //--------------------------------------------------------------------- - void GpuProgramManager::addMicrocodeToCache( const String & name, const GpuProgramManager::Microcode & microcode ) - { - String nameWithRenderSystem = addRenderSystemToName(name); - MicrocodeMap::iterator foundIter = mMicrocodeCache.find(nameWithRenderSystem); - if ( foundIter == mMicrocodeCache.end() ) - { - mMicrocodeCache.insert(make_pair(nameWithRenderSystem, microcode)); - // if cache is modified, mark it as dirty. - mCacheDirty = true; - } - else - { - foundIter->second = microcode; + { + return Microcode(OGRE_NEW MemoryDataStream(size)); + } + //--------------------------------------------------------------------- + void GpuProgramManager::addMicrocodeToCache( const String & name, const GpuProgramManager::Microcode & microcode ) + { + String nameWithRenderSystem = addRenderSystemToName(name); + MicrocodeMap::iterator foundIter = mMicrocodeCache.find(nameWithRenderSystem); + if ( foundIter == mMicrocodeCache.end() ) + { + mMicrocodeCache.insert(make_pair(nameWithRenderSystem, microcode)); + // if cache is modified, mark it as dirty. + mCacheDirty = true; + } + else + { + foundIter->second = microcode; - } - } - //--------------------------------------------------------------------- - void GpuProgramManager::removeMicrocodeFromCache( const String & name ) - { - String nameWithRenderSystem = addRenderSystemToName(name); - MicrocodeMap::iterator foundIter = mMicrocodeCache.find(nameWithRenderSystem); + } + } + //--------------------------------------------------------------------- + void GpuProgramManager::removeMicrocodeFromCache( const String & name ) + { + String nameWithRenderSystem = addRenderSystemToName(name); + MicrocodeMap::iterator foundIter = mMicrocodeCache.find(nameWithRenderSystem); - if (foundIter != mMicrocodeCache.end()) - { - mMicrocodeCache.erase( foundIter ); - mCacheDirty = true; - } - } - //--------------------------------------------------------------------- - void GpuProgramManager::saveMicrocodeCache( DataStreamPtr stream ) const - { - if (!mCacheDirty) - return; + if (foundIter != mMicrocodeCache.end()) + { + mMicrocodeCache.erase( foundIter ); + mCacheDirty = true; + } + } + //--------------------------------------------------------------------- + void GpuProgramManager::saveMicrocodeCache( DataStreamPtr stream ) const + { + if (!mCacheDirty) + return; - if (!stream->isWriteable()) - { - OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, - "Unable to write to stream " + stream->getName(), - "GpuProgramManager::saveMicrocodeCache"); - } - - // write the size of the array - uint32 sizeOfArray = static_cast(mMicrocodeCache.size()); - stream->write(&sizeOfArray, sizeof(uint32)); - - // loop the array and save it - MicrocodeMap::const_iterator iter = mMicrocodeCache.begin(); - MicrocodeMap::const_iterator iterE = mMicrocodeCache.end(); - for ( ; iter != iterE ; ++iter ) - { - // saves the name of the shader - { - const String & nameOfShader = iter->first; - uint32 stringLength = static_cast(nameOfShader.size()); - stream->write(&stringLength, sizeof(uint32)); - stream->write(&nameOfShader[0], stringLength); - } - // saves the microcode - { - const Microcode & microcodeOfShader = iter->second; - uint32 microcodeLength = static_cast(microcodeOfShader->size()); - stream->write(µcodeLength, sizeof(uint32)); - stream->write(microcodeOfShader->getPtr(), microcodeLength); - } - } - } - //--------------------------------------------------------------------- - void GpuProgramManager::loadMicrocodeCache( DataStreamPtr stream ) - { - mMicrocodeCache.clear(); + if (!stream->isWriteable()) + { + OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, + "Unable to write to stream " + stream->getName(), + "GpuProgramManager::saveMicrocodeCache"); + } + + // write the size of the array + uint32 sizeOfArray = static_cast(mMicrocodeCache.size()); + stream->write(&sizeOfArray, sizeof(uint32)); + + // loop the array and save it + MicrocodeMap::const_iterator iter = mMicrocodeCache.begin(); + MicrocodeMap::const_iterator iterE = mMicrocodeCache.end(); + for ( ; iter != iterE ; ++iter ) + { + // saves the name of the shader + { + const String & nameOfShader = iter->first; + uint32 stringLength = static_cast(nameOfShader.size()); + stream->write(&stringLength, sizeof(uint32)); + stream->write(&nameOfShader[0], stringLength); + } + // saves the microcode + { + const Microcode & microcodeOfShader = iter->second; + uint32 microcodeLength = static_cast(microcodeOfShader->size()); + stream->write(µcodeLength, sizeof(uint32)); + stream->write(microcodeOfShader->getPtr(), microcodeLength); + } + } + } + //--------------------------------------------------------------------- + void GpuProgramManager::loadMicrocodeCache( DataStreamPtr stream ) + { + mMicrocodeCache.clear(); - // write the size of the array - uint32 sizeOfArray = 0; - stream->read(&sizeOfArray, sizeof(uint32)); - - // loop the array and load it + // write the size of the array + uint32 sizeOfArray = 0; + stream->read(&sizeOfArray, sizeof(uint32)); + + // loop the array and load it - for ( uint32 i = 0 ; i < sizeOfArray ; i++ ) - { - String nameOfShader; - // loads the name of the shader - uint32 stringLength = 0; - stream->read(&stringLength, sizeof(uint32)); - nameOfShader.resize(stringLength); - stream->read(&nameOfShader[0], stringLength); + for ( uint32 i = 0 ; i < sizeOfArray ; i++ ) + { + String nameOfShader; + // loads the name of the shader + uint32 stringLength = 0; + stream->read(&stringLength, sizeof(uint32)); + nameOfShader.resize(stringLength); + stream->read(&nameOfShader[0], stringLength); - // loads the microcode - uint32 microcodeLength = 0; - stream->read(µcodeLength, sizeof(uint32)); + // loads the microcode + uint32 microcodeLength = 0; + stream->read(µcodeLength, sizeof(uint32)); - Microcode microcodeOfShader(OGRE_NEW MemoryDataStream(nameOfShader, microcodeLength)); - microcodeOfShader->seek(0); - stream->read(microcodeOfShader->getPtr(), microcodeLength); + Microcode microcodeOfShader(OGRE_NEW MemoryDataStream(nameOfShader, microcodeLength)); + microcodeOfShader->seek(0); + stream->read(microcodeOfShader->getPtr(), microcodeLength); - mMicrocodeCache.insert(make_pair(nameOfShader, microcodeOfShader)); - } + mMicrocodeCache.insert(make_pair(nameOfShader, microcodeOfShader)); + } - // if cache is not modified, mark it as clean. - mCacheDirty = false; - - } - //--------------------------------------------------------------------- + // if cache is not modified, mark it as clean. + mCacheDirty = false; + + } + //--------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreGpuProgramUsage.cpp b/OgreMain/src/OgreGpuProgramUsage.cpp index 2739141d257..d65e3d65a6d 100644 --- a/OgreMain/src/OgreGpuProgramUsage.cpp +++ b/OgreMain/src/OgreGpuProgramUsage.cpp @@ -37,56 +37,56 @@ namespace Ogre mType(gptype), mParent(parent), mProgram(), mRecreateParams(false) { } - //----------------------------------------------------------------------------- - GpuProgramUsage::GpuProgramUsage(const GpuProgramUsage& oth, Pass* parent) + //----------------------------------------------------------------------------- + GpuProgramUsage::GpuProgramUsage(const GpuProgramUsage& oth, Pass* parent) : mType(oth.mType) - , mParent(parent) + , mParent(parent) , mProgram(oth.mProgram) // nfz: parameters should be copied not just use a shared ptr to the original - , mParameters(OGRE_NEW GpuProgramParameters(*oth.mParameters)) - , mRecreateParams(false) - { - } - //--------------------------------------------------------------------- - GpuProgramUsage::~GpuProgramUsage() - { - if (!mProgram.isNull()) - mProgram->removeListener(this); - } - //----------------------------------------------------------------------------- - void GpuProgramUsage::setProgramName(const String& name, bool resetParams) - { - if (!mProgram.isNull()) - { - mProgram->removeListener(this); - mRecreateParams = true; - } - - mProgram = GpuProgramManager::getSingleton().getByName(name); + , mParameters(OGRE_NEW GpuProgramParameters(*oth.mParameters)) + , mRecreateParams(false) + { + } + //--------------------------------------------------------------------- + GpuProgramUsage::~GpuProgramUsage() + { + if (!mProgram.isNull()) + mProgram->removeListener(this); + } + //----------------------------------------------------------------------------- + void GpuProgramUsage::setProgramName(const String& name, bool resetParams) + { + if (!mProgram.isNull()) + { + mProgram->removeListener(this); + mRecreateParams = true; + } + + mProgram = GpuProgramManager::getSingleton().getByName(name); if (mProgram.isNull()) { - String progType = "fragment"; - if (mType == GPT_VERTEX_PROGRAM) - { - progType = "vertex"; - } - else if (mType == GPT_GEOMETRY_PROGRAM) - { - progType = "geometry"; - } - else if (mType == GPT_DOMAIN_PROGRAM) - { - progType = "domain"; - } - else if (mType == GPT_HULL_PROGRAM) - { - progType = "hull"; - } - else if (mType == GPT_COMPUTE_PROGRAM) - { - progType = "compute"; - } + String progType = "fragment"; + if (mType == GPT_VERTEX_PROGRAM) + { + progType = "vertex"; + } + else if (mType == GPT_GEOMETRY_PROGRAM) + { + progType = "geometry"; + } + else if (mType == GPT_DOMAIN_PROGRAM) + { + progType = "domain"; + } + else if (mType == GPT_HULL_PROGRAM) + { + progType = "hull"; + } + else if (mType == GPT_COMPUTE_PROGRAM) + { + progType = "compute"; + } OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Unable to locate " + progType + " program called " + name + ".", @@ -95,14 +95,14 @@ namespace Ogre // Reset parameters if (resetParams || mParameters.isNull() || mRecreateParams) - { - recreateParameters(); - } + { + recreateParameters(); + } - // Listen in on reload events so we can regenerate params - mProgram->addListener(this); + // Listen in on reload events so we can regenerate params + mProgram->addListener(this); - } + } //----------------------------------------------------------------------------- void GpuProgramUsage::setParameters(GpuProgramParametersSharedPtr params) { @@ -120,8 +120,8 @@ namespace Ogre return mParameters; } //----------------------------------------------------------------------------- - void GpuProgramUsage::setProgram(GpuProgramPtr& prog) - { + void GpuProgramUsage::setProgram(GpuProgramPtr& prog) + { mProgram = prog; // Reset parameters mParameters = mProgram->createParameters(); @@ -148,96 +148,96 @@ namespace Ogre if (!mProgram->isLoaded()) mProgram->load(); - // check type - if (mProgram->isLoaded() && mProgram->getType() != mType) - { - String myType = "fragment"; - if (mType == GPT_VERTEX_PROGRAM) - { - myType = "vertex"; - } - else if (mType == GPT_GEOMETRY_PROGRAM) - { - myType = "geometry"; - } - else if (mType == GPT_DOMAIN_PROGRAM) - { - myType = "domain"; - } - else if (mType == GPT_HULL_PROGRAM) - { - myType = "hull"; - } - else if (mType == GPT_COMPUTE_PROGRAM) - { - myType = "compute"; - } - - String yourType = "fragment"; - if (mProgram->getType() == GPT_VERTEX_PROGRAM) - { - yourType = "vertex"; - } - else if (mProgram->getType() == GPT_GEOMETRY_PROGRAM) - { - yourType = "geometry"; - } - else if (mProgram->getType() == GPT_DOMAIN_PROGRAM) - { - yourType = "domain"; - } - else if (mProgram->getType() == GPT_HULL_PROGRAM) - { - yourType = "hull"; - } - else if (mType == GPT_COMPUTE_PROGRAM) - { - yourType = "compute"; - } - - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - mProgram->getName() + " is a " + yourType + " program, but you are assigning it to a " - + myType + " program slot. This is invalid.", - "GpuProgramUsage::setProgramName"); - - } + // check type + if (mProgram->isLoaded() && mProgram->getType() != mType) + { + String myType = "fragment"; + if (mType == GPT_VERTEX_PROGRAM) + { + myType = "vertex"; + } + else if (mType == GPT_GEOMETRY_PROGRAM) + { + myType = "geometry"; + } + else if (mType == GPT_DOMAIN_PROGRAM) + { + myType = "domain"; + } + else if (mType == GPT_HULL_PROGRAM) + { + myType = "hull"; + } + else if (mType == GPT_COMPUTE_PROGRAM) + { + myType = "compute"; + } + + String yourType = "fragment"; + if (mProgram->getType() == GPT_VERTEX_PROGRAM) + { + yourType = "vertex"; + } + else if (mProgram->getType() == GPT_GEOMETRY_PROGRAM) + { + yourType = "geometry"; + } + else if (mProgram->getType() == GPT_DOMAIN_PROGRAM) + { + yourType = "domain"; + } + else if (mProgram->getType() == GPT_HULL_PROGRAM) + { + yourType = "hull"; + } + else if (mType == GPT_COMPUTE_PROGRAM) + { + yourType = "compute"; + } + + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + mProgram->getName() + " is a " + yourType + " program, but you are assigning it to a " + + myType + " program slot. This is invalid.", + "GpuProgramUsage::setProgramName"); + + } } //----------------------------------------------------------------------------- void GpuProgramUsage::_unload(void) { // TODO? } - //--------------------------------------------------------------------- - void GpuProgramUsage::unloadingComplete(Resource* prog) - { - mRecreateParams = true; - - } - //--------------------------------------------------------------------- - void GpuProgramUsage::loadingComplete(Resource* prog) - { - // Need to re-create parameters - if (mRecreateParams) - recreateParameters(); - - } - //--------------------------------------------------------------------- - void GpuProgramUsage::recreateParameters() - { - // Keep a reference to old ones to copy - GpuProgramParametersSharedPtr savedParams = mParameters; - - // Create new params - mParameters = mProgram->createParameters(); - - // Copy old (matching) values across - // Don't use copyConstantsFrom since program may be different - if (!savedParams.isNull()) - mParameters->copyMatchingNamedConstantsFrom(*savedParams.get()); - - mRecreateParams = false; - - } + //--------------------------------------------------------------------- + void GpuProgramUsage::unloadingComplete(Resource* prog) + { + mRecreateParams = true; + + } + //--------------------------------------------------------------------- + void GpuProgramUsage::loadingComplete(Resource* prog) + { + // Need to re-create parameters + if (mRecreateParams) + recreateParameters(); + + } + //--------------------------------------------------------------------- + void GpuProgramUsage::recreateParameters() + { + // Keep a reference to old ones to copy + GpuProgramParametersSharedPtr savedParams = mParameters; + + // Create new params + mParameters = mProgram->createParameters(); + + // Copy old (matching) values across + // Don't use copyConstantsFrom since program may be different + if (!savedParams.isNull()) + mParameters->copyMatchingNamedConstantsFrom(*savedParams.get()); + + mRecreateParams = false; + + } diff --git a/OgreMain/src/OgreHardwareBufferManager.cpp b/OgreMain/src/OgreHardwareBufferManager.cpp index cde300b5fb7..d09fd46b5a7 100644 --- a/OgreMain/src/OgreHardwareBufferManager.cpp +++ b/OgreMain/src/OgreHardwareBufferManager.cpp @@ -43,19 +43,19 @@ namespace Ogre { { assert( msSingleton ); return ( *msSingleton ); } - //--------------------------------------------------------------------- - HardwareBufferManager::HardwareBufferManager(HardwareBufferManagerBase* imp) - : HardwareBufferManagerBase(), mImpl(imp) - { - - } - //--------------------------------------------------------------------- - HardwareBufferManager::~HardwareBufferManager() - { - // mImpl must be deleted by the creator - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + HardwareBufferManager::HardwareBufferManager(HardwareBufferManagerBase* imp) + : HardwareBufferManagerBase(), mImpl(imp) + { + + } + //--------------------------------------------------------------------- + HardwareBufferManager::~HardwareBufferManager() + { + // mImpl must be deleted by the creator + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- // Free temporary vertex buffers every 5 minutes on 100fps const size_t HardwareBufferManagerBase::UNDER_USED_FRAME_THRESHOLD = 30000; const size_t HardwareBufferManagerBase::EXPIRED_DELAY_FRAME_THRESHOLD = 5; @@ -69,10 +69,10 @@ namespace Ogre { { // Clear vertex/index buffer list first, avoid destroyed notify do // unnecessary work, and we'll destroy everything here. - mVertexBuffers.clear(); - mIndexBuffers.clear(); - mUniformBuffers.clear(); - mCounterBuffers.clear(); + mVertexBuffers.clear(); + mIndexBuffers.clear(); + mUniformBuffers.clear(); + mCounterBuffers.clear(); // Destroy everything destroyAllDeclarations(); @@ -97,20 +97,20 @@ namespace Ogre { destroyVertexDeclarationImpl(decl); } //----------------------------------------------------------------------- - VertexBufferBinding* HardwareBufferManagerBase::createVertexBufferBinding(void) - { - VertexBufferBinding* ret = createVertexBufferBindingImpl(); - OGRE_LOCK_MUTEX(mVertexBufferBindingsMutex); - mVertexBufferBindings.insert(ret); - return ret; - } + VertexBufferBinding* HardwareBufferManagerBase::createVertexBufferBinding(void) + { + VertexBufferBinding* ret = createVertexBufferBindingImpl(); + OGRE_LOCK_MUTEX(mVertexBufferBindingsMutex); + mVertexBufferBindings.insert(ret); + return ret; + } //----------------------------------------------------------------------- - void HardwareBufferManagerBase::destroyVertexBufferBinding(VertexBufferBinding* binding) - { + void HardwareBufferManagerBase::destroyVertexBufferBinding(VertexBufferBinding* binding) + { OGRE_LOCK_MUTEX(mVertexBufferBindingsMutex); - mVertexBufferBindings.erase(binding); - destroyVertexBufferBindingImpl(binding); - } + mVertexBufferBindings.erase(binding); + destroyVertexBufferBindingImpl(binding); + } //----------------------------------------------------------------------- VertexDeclaration* HardwareBufferManagerBase::createVertexDeclarationImpl(void) { @@ -122,15 +122,15 @@ namespace Ogre { OGRE_DELETE decl; } //----------------------------------------------------------------------- - VertexBufferBinding* HardwareBufferManagerBase::createVertexBufferBindingImpl(void) - { - return OGRE_NEW VertexBufferBinding(); - } + VertexBufferBinding* HardwareBufferManagerBase::createVertexBufferBindingImpl(void) + { + return OGRE_NEW VertexBufferBinding(); + } //----------------------------------------------------------------------- - void HardwareBufferManagerBase::destroyVertexBufferBindingImpl(VertexBufferBinding* binding) - { - OGRE_DELETE binding; - } + void HardwareBufferManagerBase::destroyVertexBufferBindingImpl(VertexBufferBinding* binding) + { + OGRE_DELETE binding; + } //----------------------------------------------------------------------- void HardwareBufferManagerBase::destroyAllDeclarations(void) { @@ -153,63 +153,63 @@ namespace Ogre { } mVertexBufferBindings.clear(); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void HardwareBufferManagerBase::registerVertexBufferSourceAndCopy( - const HardwareVertexBufferSharedPtr& sourceBuffer, - const HardwareVertexBufferSharedPtr& copy) - { + const HardwareVertexBufferSharedPtr& sourceBuffer, + const HardwareVertexBufferSharedPtr& copy) + { OGRE_LOCK_MUTEX(mTempBuffersMutex); - // Add copy to free temporary vertex buffers + // Add copy to free temporary vertex buffers mFreeTempVertexBufferMap.insert( FreeTemporaryVertexBufferMap::value_type(sourceBuffer.get(), copy)); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- HardwareVertexBufferSharedPtr HardwareBufferManagerBase::allocateVertexBufferCopy( const HardwareVertexBufferSharedPtr& sourceBuffer, BufferLicenseType licenseType, HardwareBufferLicensee* licensee, bool copyData) { - // pre-lock the mVertexBuffers mutex, which would usually get locked in - // makeBufferCopy / createVertexBuffer - // this prevents a deadlock in _notifyVertexBufferDestroyed - // which locks the same mutexes (via other methods) but in reverse order + // pre-lock the mVertexBuffers mutex, which would usually get locked in + // makeBufferCopy / createVertexBuffer + // this prevents a deadlock in _notifyVertexBufferDestroyed + // which locks the same mutexes (via other methods) but in reverse order OGRE_LOCK_MUTEX(mVertexBuffersMutex); - { + { OGRE_LOCK_MUTEX(mTempBuffersMutex); - HardwareVertexBufferSharedPtr vbuf; - - // Locate existing buffer copy in temporary vertex buffers - FreeTemporaryVertexBufferMap::iterator i = - mFreeTempVertexBufferMap.find(sourceBuffer.get()); - if (i == mFreeTempVertexBufferMap.end()) - { - // copy buffer, use shadow buffer and make dynamic - vbuf = makeBufferCopy( - sourceBuffer, - HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, - true); - } - else - { - // Allocate existing copy - vbuf = i->second; - mFreeTempVertexBufferMap.erase(i); - } - - // Copy data? - if (copyData) - { - vbuf->copyData(*(sourceBuffer.get()), 0, 0, sourceBuffer->getSizeInBytes(), true); - } - - // Insert copy into licensee list - mTempVertexBufferLicenses.insert( - TemporaryVertexBufferLicenseMap::value_type( - vbuf.get(), - VertexBufferLicense(sourceBuffer.get(), licenseType, EXPIRED_DELAY_FRAME_THRESHOLD, vbuf, licensee))); - return vbuf; - } + HardwareVertexBufferSharedPtr vbuf; + + // Locate existing buffer copy in temporary vertex buffers + FreeTemporaryVertexBufferMap::iterator i = + mFreeTempVertexBufferMap.find(sourceBuffer.get()); + if (i == mFreeTempVertexBufferMap.end()) + { + // copy buffer, use shadow buffer and make dynamic + vbuf = makeBufferCopy( + sourceBuffer, + HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, + true); + } + else + { + // Allocate existing copy + vbuf = i->second; + mFreeTempVertexBufferMap.erase(i); + } + + // Copy data? + if (copyData) + { + vbuf->copyData(*(sourceBuffer.get()), 0, 0, sourceBuffer->getSizeInBytes(), true); + } + + // Insert copy into licensee list + mTempVertexBufferLicenses.insert( + TemporaryVertexBufferLicenseMap::value_type( + vbuf.get(), + VertexBufferLicense(sourceBuffer.get(), licenseType, EXPIRED_DELAY_FRAME_THRESHOLD, vbuf, licensee))); + return vbuf; + } } //----------------------------------------------------------------------- @@ -218,7 +218,7 @@ namespace Ogre { { OGRE_LOCK_MUTEX(mTempBuffersMutex); - TemporaryVertexBufferLicenseMap::iterator i = + TemporaryVertexBufferLicenseMap::iterator i = mTempVertexBufferLicenses.find(bufferCopy.get()); if (i != mTempVertexBufferLicenses.end()) { @@ -296,7 +296,7 @@ namespace Ogre { if (vbl.licenseType == BLT_AUTOMATIC_RELEASE && (forceFreeUnused || --vbl.expiredDelay <= 0)) { - vbl.licensee->licenseExpired(vbl.buffer.get()); + vbl.licensee->licenseExpired(vbl.buffer.get()); mFreeTempVertexBufferMap.insert( FreeTemporaryVertexBufferMap::value_type(vbl.originalBufferPtr, vbl.buffer)); @@ -390,38 +390,38 @@ namespace Ogre { // holdForDelayDestroy will destroy auto. } } - //----------------------------------------------------------------------- - void HardwareBufferManagerBase::_notifyVertexBufferDestroyed(HardwareVertexBuffer* buf) - { + //----------------------------------------------------------------------- + void HardwareBufferManagerBase::_notifyVertexBufferDestroyed(HardwareVertexBuffer* buf) + { OGRE_LOCK_MUTEX(mVertexBuffersMutex); - VertexBufferList::iterator i = mVertexBuffers.find(buf); - if (i != mVertexBuffers.end()) - { + VertexBufferList::iterator i = mVertexBuffers.find(buf); + if (i != mVertexBuffers.end()) + { // release vertex buffer copies - mVertexBuffers.erase(i); + mVertexBuffers.erase(i); _forceReleaseBufferCopies(buf); - } - } - //----------------------------------------------------------------------- - void HardwareBufferManagerBase::_notifyIndexBufferDestroyed(HardwareIndexBuffer* buf) - { + } + } + //----------------------------------------------------------------------- + void HardwareBufferManagerBase::_notifyIndexBufferDestroyed(HardwareIndexBuffer* buf) + { OGRE_LOCK_MUTEX(mIndexBuffersMutex); - IndexBufferList::iterator i = mIndexBuffers.find(buf); - if (i != mIndexBuffers.end()) - { - mIndexBuffers.erase(i); - } - } - //----------------------------------------------------------------------- - void HardwareBufferManagerBase::_notifyUniformBufferDestroyed(HardwareUniformBuffer* buf) - { - } - //----------------------------------------------------------------------- - void HardwareBufferManagerBase::_notifyCounterBufferDestroyed(HardwareCounterBuffer* buf) - { - } + IndexBufferList::iterator i = mIndexBuffers.find(buf); + if (i != mIndexBuffers.end()) + { + mIndexBuffers.erase(i); + } + } + //----------------------------------------------------------------------- + void HardwareBufferManagerBase::_notifyUniformBufferDestroyed(HardwareUniformBuffer* buf) + { + } + //----------------------------------------------------------------------- + void HardwareBufferManagerBase::_notifyCounterBufferDestroyed(HardwareCounterBuffer* buf) + { + } //----------------------------------------------------------------------- HardwareVertexBufferSharedPtr HardwareBufferManagerBase::makeBufferCopy( @@ -507,9 +507,9 @@ namespace Ogre { HardwareBufferManagerBase::BLT_AUTOMATIC_RELEASE, this); } } - //----------------------------------------------------------------------------- - bool TempBlendedBufferInfo::buffersCheckedOut(bool positions, bool normals) const - { + //----------------------------------------------------------------------------- + bool TempBlendedBufferInfo::buffersCheckedOut(bool positions, bool normals) const + { if (positions || (normals && posNormalShareBuffer)) { if (destPositionBuffer.isNull()) @@ -526,8 +526,8 @@ namespace Ogre { destNormalBuffer->getManager()->touchVertexBufferCopy(destNormalBuffer); } - return true; - } + return true; + } //----------------------------------------------------------------------------- void TempBlendedBufferInfo::bindTempCopies(VertexData* targetData, bool suppressHardwareUpload) { diff --git a/OgreMain/src/OgreHardwareCounterBuffer.cpp b/OgreMain/src/OgreHardwareCounterBuffer.cpp index 0c319291509..1b194b56156 100644 --- a/OgreMain/src/OgreHardwareCounterBuffer.cpp +++ b/OgreMain/src/OgreHardwareCounterBuffer.cpp @@ -33,12 +33,12 @@ THE SOFTWARE. namespace Ogre { - HardwareCounterBuffer::HardwareCounterBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, - HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - : HardwareBuffer(usage, false, useShadowBuffer) - , mMgr(mgr), mName(name) - { - // Calculate the size of the vertices + HardwareCounterBuffer::HardwareCounterBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, + HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) + : HardwareBuffer(usage, false, useShadowBuffer) + , mMgr(mgr), mName(name) + { + // Calculate the size of the vertices mSizeInBytes = sizeBytes; // Create a shadow buffer if required @@ -46,18 +46,18 @@ namespace Ogre { { mShadowBuffer = OGRE_NEW DefaultHardwareCounterBuffer(mMgr, sizeBytes, HardwareBuffer::HBU_DYNAMIC, false); } - } - - HardwareCounterBuffer::~HardwareCounterBuffer() - { - if (mMgr) - { - mMgr->_notifyCounterBufferDestroyed(this); - } + } + + HardwareCounterBuffer::~HardwareCounterBuffer() + { + if (mMgr) + { + mMgr->_notifyCounterBufferDestroyed(this); + } OGRE_DELETE mShadowBuffer; - } + } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- HardwareCounterBufferSharedPtr::HardwareCounterBufferSharedPtr(HardwareCounterBuffer* buf) : SharedPtr(buf) { diff --git a/OgreMain/src/OgreHardwareIndexBuffer.cpp b/OgreMain/src/OgreHardwareIndexBuffer.cpp index 420a25e0ea5..375b57e0606 100644 --- a/OgreMain/src/OgreHardwareIndexBuffer.cpp +++ b/OgreMain/src/OgreHardwareIndexBuffer.cpp @@ -38,9 +38,9 @@ namespace Ogre { size_t numIndexes, HardwareBuffer::Usage usage, bool useSystemMemory, bool useShadowBuffer) : HardwareBuffer(usage, useSystemMemory, useShadowBuffer) - , mMgr(mgr) - , mIndexType(idxType) - , mNumIndexes(numIndexes) + , mMgr(mgr) + , mIndexType(idxType) + , mNumIndexes(numIndexes) { // Calculate the size of the indexes switch (mIndexType) @@ -66,10 +66,10 @@ namespace Ogre { //----------------------------------------------------------------------------- HardwareIndexBuffer::~HardwareIndexBuffer() { - if (mMgr) - { - mMgr->_notifyIndexBufferDestroyed(this); - } + if (mMgr) + { + mMgr->_notifyIndexBufferDestroyed(this); + } OGRE_DELETE mShadowBuffer; } diff --git a/OgreMain/src/OgreHardwarePixelBuffer.cpp b/OgreMain/src/OgreHardwarePixelBuffer.cpp index af0830bc9d0..63253400dad 100644 --- a/OgreMain/src/OgreHardwarePixelBuffer.cpp +++ b/OgreMain/src/OgreHardwarePixelBuffer.cpp @@ -44,7 +44,7 @@ namespace Ogre // Default mRowPitch = mWidth; mSlicePitch = mHeight*mWidth; - mSizeInBytes = mHeight*mWidth*PixelUtil::getNumElemBytes(mFormat); + mSizeInBytes = mHeight*mWidth*PixelUtil::getNumElemBytes(mFormat); } //----------------------------------------------------------------------------- @@ -89,7 +89,7 @@ namespace Ogre //----------------------------------------------------------------------------- const PixelBox& HardwarePixelBuffer::getCurrentLock() - { + { assert(isLocked() && "Cannot get current lock: buffer not locked"); return mCurrentLock; @@ -106,45 +106,45 @@ namespace Ogre //----------------------------------------------------------------------------- void HardwarePixelBuffer::blit(const HardwarePixelBufferSharedPtr &src, const Image::Box &srcBox, const Image::Box &dstBox) - { - if(isLocked() || src->isLocked()) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Source and destination buffer may not be locked!", - "HardwarePixelBuffer::blit"); - } - if(src.getPointer() == this) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + { + if(isLocked() || src->isLocked()) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Source and destination buffer may not be locked!", + "HardwarePixelBuffer::blit"); + } + if(src.getPointer() == this) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Source must not be the same object", "HardwarePixelBuffer::blit" ) ; - } - const PixelBox &srclock = src->lock(srcBox, HBL_READ_ONLY); - - LockOptions method = HBL_NORMAL; - if(dstBox.left == 0 && dstBox.top == 0 && dstBox.front == 0 && - dstBox.right == mWidth && dstBox.bottom == mHeight && - dstBox.back == mDepth) - // Entire buffer -- we can discard the previous contents - method = HBL_DISCARD; - - const PixelBox &dstlock = lock(dstBox, method); - if(dstlock.getWidth() != srclock.getWidth() || - dstlock.getHeight() != srclock.getHeight() || - dstlock.getDepth() != srclock.getDepth()) - { - // Scaling desired - Image::scale(srclock, dstlock); - } - else - { - // No scaling needed - PixelUtil::bulkPixelConversion(srclock, dstlock); - } - - unlock(); - src->unlock(); - } + } + const PixelBox &srclock = src->lock(srcBox, HBL_READ_ONLY); + + LockOptions method = HBL_NORMAL; + if(dstBox.left == 0 && dstBox.top == 0 && dstBox.front == 0 && + dstBox.right == mWidth && dstBox.bottom == mHeight && + dstBox.back == mDepth) + // Entire buffer -- we can discard the previous contents + method = HBL_DISCARD; + + const PixelBox &dstlock = lock(dstBox, method); + if(dstlock.getWidth() != srclock.getWidth() || + dstlock.getHeight() != srclock.getHeight() || + dstlock.getDepth() != srclock.getDepth()) + { + // Scaling desired + Image::scale(srclock, dstlock); + } + else + { + // No scaling needed + PixelUtil::bulkPixelConversion(srclock, dstlock); + } + + unlock(); + src->unlock(); + } //----------------------------------------------------------------------------- void HardwarePixelBuffer::blit(const HardwarePixelBufferSharedPtr &src) { @@ -154,30 +154,30 @@ namespace Ogre ); } //----------------------------------------------------------------------------- - void HardwarePixelBuffer::readData(size_t offset, size_t length, void* pDest) - { - // TODO - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "Reading a byte range is not implemented. Use blitToMemory.", - "HardwarePixelBuffer::readData"); - } - //----------------------------------------------------------------------------- - - void HardwarePixelBuffer::writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer) - { - // TODO - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "Writing a byte range is not implemented. Use blitFromMemory.", - "HardwarePixelBuffer::writeData"); - } + void HardwarePixelBuffer::readData(size_t offset, size_t length, void* pDest) + { + // TODO + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "Reading a byte range is not implemented. Use blitToMemory.", + "HardwarePixelBuffer::readData"); + } + //----------------------------------------------------------------------------- + + void HardwarePixelBuffer::writeData(size_t offset, size_t length, const void* pSource, + bool discardWholeBuffer) + { + // TODO + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "Writing a byte range is not implemented. Use blitFromMemory.", + "HardwarePixelBuffer::writeData"); + } //----------------------------------------------------------------------------- RenderTexture *HardwarePixelBuffer::getRenderTarget(size_t) { OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "Not yet implemented for this rendersystem.", - "HardwarePixelBuffer::getRenderTarget"); + "Not yet implemented for this rendersystem.", + "HardwarePixelBuffer::getRenderTarget"); } //----------------------------------------------------------------------------- @@ -187,10 +187,10 @@ namespace Ogre { } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- - void HardwarePixelBuffer::_clearSliceRTT(size_t zoffset) - { - } + void HardwarePixelBuffer::_clearSliceRTT(size_t zoffset) + { + } } diff --git a/OgreMain/src/OgreHardwareUniformBuffer.cpp b/OgreMain/src/OgreHardwareUniformBuffer.cpp index e73a092df5f..5b8e71c7aad 100644 --- a/OgreMain/src/OgreHardwareUniformBuffer.cpp +++ b/OgreMain/src/OgreHardwareUniformBuffer.cpp @@ -33,13 +33,13 @@ THE SOFTWARE. namespace Ogre { - HardwareUniformBuffer::HardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, - HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - : HardwareBuffer(usage, false, useShadowBuffer) + HardwareUniformBuffer::HardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, + HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) + : HardwareBuffer(usage, false, useShadowBuffer) , mMgr(mgr) - , mName(name) - { - // Calculate the size of the vertices + , mName(name) + { + // Calculate the size of the vertices mSizeInBytes = sizeBytes; // Create a shadow buffer if required @@ -47,111 +47,111 @@ namespace Ogre { { mShadowBuffer = OGRE_NEW DefaultHardwareUniformBuffer(mMgr, sizeBytes, HardwareBuffer::HBU_DYNAMIC, false); } - } - - HardwareUniformBuffer::~HardwareUniformBuffer() - { - if (mMgr) - { - mMgr->_notifyUniformBufferDestroyed(this); - } + } + + HardwareUniformBuffer::~HardwareUniformBuffer() + { + if (mMgr) + { + mMgr->_notifyUniformBufferDestroyed(this); + } OGRE_DELETE mShadowBuffer; - } - - /* - bool HardwareUniformBuffer::writeParams(GpuProgramParametersSharedPtr params) - { - // Lock buffer - void* mappedData = this->lock(HardwareBuffer::HBL_DISCARD); - if (!mappedData) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot update uniform buffer\nError description: error locking uniform buffer", - "HardwareUniformBuffer::writeParams"); - } - - // Store temporary data address - void* srcData = 0; - - // Iterate through variables - ShaderVariableIterator it = mShaderVars.begin(); - ShaderVariableIterator end = mShaderVars.end(); - while(it != end) - { - String varName = it->name; - - // hack for cg parameter with strange prefix - if (varName.size() > 0 && varName[0] == '_') - { - varName.erase(0,1); - } - - const GpuConstantDefinition& def = params->getConstantDefinition(varName); - if (def.isFloat()) - { - srcData = (void *)&(*(params->getFloatConstantList().begin() + def.physicalIndex)); - } - else - { - srcData = (void *)&(*(params->getIntConstantList().begin() + def.physicalIndex)); - } - - memcpy( &(((char *)(mappedData))[it->startOffset]), srcData , it->size); - } - - // Unlock buffer - this->unlock(); - - return true; - } - - bool HardwareUniformBuffer::writeSharedParams(GpuSharedParametersPtr sharedParams) - { - // Lock buffer - void* mappedData = this->lock(HardwareBuffer::HBL_DISCARD); - if (!mappedData) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot update uniform buffer\nError description: error locking uniform buffer", - "HardwareUniformBuffer::writeParams"); - } - - // Store temporary data address - void* srcData = 0; - - // Iterate through variables - ShaderVariableIterator it = mShaderVars.begin(); - ShaderVariableIterator end = mShaderVars.end(); - while(it != end) - { - String varName = it->name; - - // hack for cg parameter with strange prefix - if (varName.size() > 0 && varName[0] == '_') - { - varName.erase(0,1); - } - - const GpuConstantDefinition& def = sharedParams->getConstantDefinition(varName); - if (def.isFloat()) - { - srcData = (void *)&(*(sharedParams->getFloatConstantList().begin() + def.physicalIndex)); - } - else - { - srcData = (void *)&(*(sharedParams->getIntConstantList().begin() + def.physicalIndex)); - } - - memcpy( &(((char *)(mappedData))[it->startOffset]), srcData , it->size); - } - - // Unlock buffer - this->unlock(); - - return true; - } - */ - //----------------------------------------------------------------------------- + } + + /* + bool HardwareUniformBuffer::writeParams(GpuProgramParametersSharedPtr params) + { + // Lock buffer + void* mappedData = this->lock(HardwareBuffer::HBL_DISCARD); + if (!mappedData) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot update uniform buffer\nError description: error locking uniform buffer", + "HardwareUniformBuffer::writeParams"); + } + + // Store temporary data address + void* srcData = 0; + + // Iterate through variables + ShaderVariableIterator it = mShaderVars.begin(); + ShaderVariableIterator end = mShaderVars.end(); + while(it != end) + { + String varName = it->name; + + // hack for cg parameter with strange prefix + if (varName.size() > 0 && varName[0] == '_') + { + varName.erase(0,1); + } + + const GpuConstantDefinition& def = params->getConstantDefinition(varName); + if (def.isFloat()) + { + srcData = (void *)&(*(params->getFloatConstantList().begin() + def.physicalIndex)); + } + else + { + srcData = (void *)&(*(params->getIntConstantList().begin() + def.physicalIndex)); + } + + memcpy( &(((char *)(mappedData))[it->startOffset]), srcData , it->size); + } + + // Unlock buffer + this->unlock(); + + return true; + } + + bool HardwareUniformBuffer::writeSharedParams(GpuSharedParametersPtr sharedParams) + { + // Lock buffer + void* mappedData = this->lock(HardwareBuffer::HBL_DISCARD); + if (!mappedData) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot update uniform buffer\nError description: error locking uniform buffer", + "HardwareUniformBuffer::writeParams"); + } + + // Store temporary data address + void* srcData = 0; + + // Iterate through variables + ShaderVariableIterator it = mShaderVars.begin(); + ShaderVariableIterator end = mShaderVars.end(); + while(it != end) + { + String varName = it->name; + + // hack for cg parameter with strange prefix + if (varName.size() > 0 && varName[0] == '_') + { + varName.erase(0,1); + } + + const GpuConstantDefinition& def = sharedParams->getConstantDefinition(varName); + if (def.isFloat()) + { + srcData = (void *)&(*(sharedParams->getFloatConstantList().begin() + def.physicalIndex)); + } + else + { + srcData = (void *)&(*(sharedParams->getIntConstantList().begin() + def.physicalIndex)); + } + + memcpy( &(((char *)(mappedData))[it->startOffset]), srcData , it->size); + } + + // Unlock buffer + this->unlock(); + + return true; + } + */ + //----------------------------------------------------------------------------- HardwareUniformBufferSharedPtr::HardwareUniformBufferSharedPtr(HardwareUniformBuffer* buf) : SharedPtr(buf) { diff --git a/OgreMain/src/OgreHardwareVertexBuffer.cpp b/OgreMain/src/OgreHardwareVertexBuffer.cpp index 4467eef3ef7..1d7d549b5ca 100644 --- a/OgreMain/src/OgreHardwareVertexBuffer.cpp +++ b/OgreMain/src/OgreHardwareVertexBuffer.cpp @@ -41,11 +41,11 @@ namespace Ogre { size_t numVertices, HardwareBuffer::Usage usage, bool useSystemMemory, bool useShadowBuffer) : HardwareBuffer(usage, useSystemMemory, useShadowBuffer), - mMgr(mgr), + mMgr(mgr), mNumVertices(numVertices), mVertexSize(vertexSize), mIsInstanceData(false), - mInstanceDataStepRate(1) + mInstanceDataStepRate(1) { // Calculate the size of the vertices mSizeInBytes = mVertexSize * numVertices; @@ -61,20 +61,20 @@ namespace Ogre { //----------------------------------------------------------------------------- HardwareVertexBuffer::~HardwareVertexBuffer() { - if (mMgr) - { - mMgr->_notifyVertexBufferDestroyed(this); - } + if (mMgr) + { + mMgr->_notifyVertexBufferDestroyed(this); + } OGRE_DELETE mShadowBuffer; } //----------------------------------------------------------------------------- bool HardwareVertexBuffer::checkIfVertexInstanceDataIsSupported() { - // Use the current render system - RenderSystem* rs = Root::getSingleton().getRenderSystem(); + // Use the current render system + RenderSystem* rs = Root::getSingleton().getRenderSystem(); - // Check if the supported - return rs->getCapabilities()->hasCapability(RSC_VERTEX_BUFFER_INSTANCE_DATA); + // Check if the supported + return rs->getCapabilities()->hasCapability(RSC_VERTEX_BUFFER_INSTANCE_DATA); } //----------------------------------------------------------------------------- void HardwareVertexBuffer::setIsInstanceData( const bool val ) @@ -87,31 +87,31 @@ namespace Ogre { } else { - mIsInstanceData = val; + mIsInstanceData = val; } } - //----------------------------------------------------------------------------- - size_t HardwareVertexBuffer::getInstanceDataStepRate() const - { - return mInstanceDataStepRate; - } - //----------------------------------------------------------------------------- - void HardwareVertexBuffer::setInstanceDataStepRate( const size_t val ) - { + //----------------------------------------------------------------------------- + size_t HardwareVertexBuffer::getInstanceDataStepRate() const + { + return mInstanceDataStepRate; + } + //----------------------------------------------------------------------------- + void HardwareVertexBuffer::setInstanceDataStepRate( const size_t val ) + { if (val > 0) { - mInstanceDataStepRate = val; + mInstanceDataStepRate = val; } - else - { + else + { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Instance data step rate must be bigger then 0.", "HardwareVertexBuffer::setInstanceDataStepRate"); - } - } - //----------------------------------------------------------------------------- - // VertexElement - //----------------------------------------------------------------------------- + } + } + //----------------------------------------------------------------------------- + // VertexElement + //----------------------------------------------------------------------------- VertexElement::VertexElement(unsigned short source, size_t offset, VertexElementType theType, VertexElementSemantic semantic, unsigned short index) : mSource(source), mOffset(offset), mType(theType), @@ -119,27 +119,27 @@ namespace Ogre { { } //----------------------------------------------------------------------------- - size_t VertexElement::getSize(void) const - { - return getTypeSize(mType); - } - //----------------------------------------------------------------------------- - size_t VertexElement::getTypeSize(VertexElementType etype) - { - switch(etype) - { - case VET_COLOUR: - case VET_COLOUR_ABGR: - case VET_COLOUR_ARGB: - return sizeof(RGBA); - case VET_FLOAT1: - return sizeof(float); - case VET_FLOAT2: - return sizeof(float)*2; - case VET_FLOAT3: - return sizeof(float)*3; - case VET_FLOAT4: - return sizeof(float)*4; + size_t VertexElement::getSize(void) const + { + return getTypeSize(mType); + } + //----------------------------------------------------------------------------- + size_t VertexElement::getTypeSize(VertexElementType etype) + { + switch(etype) + { + case VET_COLOUR: + case VET_COLOUR_ABGR: + case VET_COLOUR_ARGB: + return sizeof(RGBA); + case VET_FLOAT1: + return sizeof(float); + case VET_FLOAT2: + return sizeof(float)*2; + case VET_FLOAT3: + return sizeof(float)*3; + case VET_FLOAT4: + return sizeof(float)*4; case VET_DOUBLE1: return sizeof(double); case VET_DOUBLE2: @@ -148,14 +148,14 @@ namespace Ogre { return sizeof(double)*3; case VET_DOUBLE4: return sizeof(double)*4; - case VET_SHORT1: - return sizeof(short); - case VET_SHORT2: - return sizeof(short)*2; - case VET_SHORT3: - return sizeof(short)*3; - case VET_SHORT4: - return sizeof(short)*4; + case VET_SHORT1: + return sizeof(short); + case VET_SHORT2: + return sizeof(short)*2; + case VET_SHORT3: + return sizeof(short)*3; + case VET_SHORT4: + return sizeof(short)*4; case VET_USHORT1: return sizeof(unsigned short); case VET_USHORT2: @@ -182,38 +182,38 @@ namespace Ogre { return sizeof(unsigned int)*4; case VET_UBYTE4: return sizeof(unsigned char)*4; - } - return 0; - } - //----------------------------------------------------------------------------- - unsigned short VertexElement::getTypeCount(VertexElementType etype) - { - switch (etype) - { - case VET_COLOUR: - case VET_COLOUR_ABGR: - case VET_COLOUR_ARGB: + } + return 0; + } + //----------------------------------------------------------------------------- + unsigned short VertexElement::getTypeCount(VertexElementType etype) + { + switch (etype) + { + case VET_COLOUR: + case VET_COLOUR_ABGR: + case VET_COLOUR_ARGB: case VET_FLOAT1: case VET_SHORT1: case VET_USHORT1: case VET_UINT1: case VET_INT1: case VET_DOUBLE1: - return 1; + return 1; case VET_FLOAT2: case VET_SHORT2: case VET_USHORT2: case VET_UINT2: case VET_INT2: case VET_DOUBLE2: - return 2; + return 2; case VET_FLOAT3: case VET_SHORT3: case VET_USHORT3: case VET_UINT3: case VET_INT3: case VET_DOUBLE3: - return 3; + return 3; case VET_FLOAT4: case VET_SHORT4: case VET_USHORT4: @@ -222,150 +222,150 @@ namespace Ogre { case VET_DOUBLE4: case VET_UBYTE4: return 4; - } - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid type", - "VertexElement::getTypeCount"); - } - //----------------------------------------------------------------------------- - VertexElementType VertexElement::multiplyTypeCount(VertexElementType baseType, - unsigned short count) - { - switch (baseType) - { - case VET_FLOAT1: - switch(count) - { - case 1: - return VET_FLOAT1; - case 2: - return VET_FLOAT2; - case 3: - return VET_FLOAT3; - case 4: - return VET_FLOAT4; + } + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid type", + "VertexElement::getTypeCount"); + } + //----------------------------------------------------------------------------- + VertexElementType VertexElement::multiplyTypeCount(VertexElementType baseType, + unsigned short count) + { + switch (baseType) + { + case VET_FLOAT1: + switch(count) + { + case 1: + return VET_FLOAT1; + case 2: + return VET_FLOAT2; + case 3: + return VET_FLOAT3; + case 4: + return VET_FLOAT4; default: break; - } - break; - case VET_SHORT1: - switch(count) - { - case 1: - return VET_SHORT1; - case 2: - return VET_SHORT2; - case 3: - return VET_SHORT3; - case 4: - return VET_SHORT4; + } + break; + case VET_SHORT1: + switch(count) + { + case 1: + return VET_SHORT1; + case 2: + return VET_SHORT2; + case 3: + return VET_SHORT3; + case 4: + return VET_SHORT4; default: break; - } - break; + } + break; default: break; - } - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid base type", - "VertexElement::multiplyTypeCount"); - } - //-------------------------------------------------------------------------- - VertexElementType VertexElement::getBestColourVertexElementType(void) - { - // Use the current render system to determine if possible - if (Root::getSingletonPtr() && Root::getSingletonPtr()->getRenderSystem()) - { - return Root::getSingleton().getRenderSystem()->getColourVertexElementType(); - } - else - { - // We can't know the specific type right now, so pick a type - // based on platform + } + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid base type", + "VertexElement::multiplyTypeCount"); + } + //-------------------------------------------------------------------------- + VertexElementType VertexElement::getBestColourVertexElementType(void) + { + // Use the current render system to determine if possible + if (Root::getSingletonPtr() && Root::getSingletonPtr()->getRenderSystem()) + { + return Root::getSingleton().getRenderSystem()->getColourVertexElementType(); + } + else + { + // We can't know the specific type right now, so pick a type + // based on platform #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT - return VET_COLOUR_ARGB; // prefer D3D format on windows + return VET_COLOUR_ARGB; // prefer D3D format on windows #else - return VET_COLOUR_ABGR; // prefer GL format on everything else + return VET_COLOUR_ABGR; // prefer GL format on everything else #endif - } - } - //-------------------------------------------------------------------------- - void VertexElement::convertColourValue(VertexElementType srcType, - VertexElementType dstType, uint32* ptr) - { - if (srcType == dstType) - return; - - // Conversion between ARGB and ABGR is always a case of flipping R/B - *ptr = - ((*ptr&0x00FF0000)>>16)|((*ptr&0x000000FF)<<16)|(*ptr&0xFF00FF00); - } - //-------------------------------------------------------------------------- - uint32 VertexElement::convertColourValue(const ColourValue& src, - VertexElementType dst) - { - switch(dst) - { + } + } + //-------------------------------------------------------------------------- + void VertexElement::convertColourValue(VertexElementType srcType, + VertexElementType dstType, uint32* ptr) + { + if (srcType == dstType) + return; + + // Conversion between ARGB and ABGR is always a case of flipping R/B + *ptr = + ((*ptr&0x00FF0000)>>16)|((*ptr&0x000000FF)<<16)|(*ptr&0xFF00FF00); + } + //-------------------------------------------------------------------------- + uint32 VertexElement::convertColourValue(const ColourValue& src, + VertexElementType dst) + { + switch(dst) + { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT default: #endif - case VET_COLOUR_ARGB: - return src.getAsARGB(); + case VET_COLOUR_ARGB: + return src.getAsARGB(); #if OGRE_PLATFORM != OGRE_PLATFORM_WIN32 && OGRE_PLATFORM != OGRE_PLATFORM_WINRT default: #endif - case VET_COLOUR_ABGR: - return src.getAsABGR(); - }; - - } - //----------------------------------------------------------------------------- - VertexElementType VertexElement::getBaseType(VertexElementType multiType) - { - switch (multiType) - { - case VET_FLOAT1: - case VET_FLOAT2: - case VET_FLOAT3: - case VET_FLOAT4: - return VET_FLOAT1; - case VET_DOUBLE1: - case VET_DOUBLE2: - case VET_DOUBLE3: - case VET_DOUBLE4: - return VET_DOUBLE1; + case VET_COLOUR_ABGR: + return src.getAsABGR(); + }; + + } + //----------------------------------------------------------------------------- + VertexElementType VertexElement::getBaseType(VertexElementType multiType) + { + switch (multiType) + { + case VET_FLOAT1: + case VET_FLOAT2: + case VET_FLOAT3: + case VET_FLOAT4: + return VET_FLOAT1; + case VET_DOUBLE1: + case VET_DOUBLE2: + case VET_DOUBLE3: + case VET_DOUBLE4: + return VET_DOUBLE1; case VET_INT1: - case VET_INT2: - case VET_INT3: - case VET_INT4: - return VET_INT1; + case VET_INT2: + case VET_INT3: + case VET_INT4: + return VET_INT1; case VET_UINT1: - case VET_UINT2: - case VET_UINT3: - case VET_UINT4: - return VET_UINT1; - case VET_COLOUR: - return VET_COLOUR; - case VET_COLOUR_ABGR: - return VET_COLOUR_ABGR; - case VET_COLOUR_ARGB: - return VET_COLOUR_ARGB; - case VET_SHORT1: - case VET_SHORT2: - case VET_SHORT3: - case VET_SHORT4: - return VET_SHORT1; - case VET_USHORT1: - case VET_USHORT2: - case VET_USHORT3: - case VET_USHORT4: - return VET_USHORT1; - case VET_UBYTE4: - return VET_UBYTE4; - }; + case VET_UINT2: + case VET_UINT3: + case VET_UINT4: + return VET_UINT1; + case VET_COLOUR: + return VET_COLOUR; + case VET_COLOUR_ABGR: + return VET_COLOUR_ABGR; + case VET_COLOUR_ARGB: + return VET_COLOUR_ARGB; + case VET_SHORT1: + case VET_SHORT2: + case VET_SHORT3: + case VET_SHORT4: + return VET_SHORT1; + case VET_USHORT1: + case VET_USHORT2: + case VET_USHORT3: + case VET_USHORT4: + return VET_USHORT1; + case VET_UBYTE4: + return VET_UBYTE4; + }; // To keep compiler happy return VET_FLOAT1; - } - //----------------------------------------------------------------------------- + } + //----------------------------------------------------------------------------- VertexDeclaration::VertexDeclaration() { } @@ -383,15 +383,15 @@ namespace Ogre { size_t offset, VertexElementType theType, VertexElementSemantic semantic, unsigned short index) { - // Refine colour type to a specific type - if (theType == VET_COLOUR) - { - theType = VertexElement::getBestColourVertexElementType(); - } + // Refine colour type to a specific type + if (theType == VET_COLOUR) + { + theType = VertexElement::getBestColourVertexElementType(); + } mElementList.push_back( VertexElement(source, offset, theType, semantic, index) ); - return mElementList.back(); + return mElementList.back(); } //----------------------------------------------------------------------------- const VertexElement& VertexDeclaration::insertElement(unsigned short atPosition, @@ -436,22 +436,22 @@ namespace Ogre { //----------------------------------------------------------------------------- void VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index) { - VertexElementList::iterator ei, eiend; - eiend = mElementList.end(); - for (ei = mElementList.begin(); ei != eiend; ++ei) - { - if (ei->getSemantic() == semantic && ei->getIndex() == index) - { - mElementList.erase(ei); + VertexElementList::iterator ei, eiend; + eiend = mElementList.end(); + for (ei = mElementList.begin(); ei != eiend; ++ei) + { + if (ei->getSemantic() == semantic && ei->getIndex() == index) + { + mElementList.erase(ei); break; - } - } + } + } + } + //----------------------------------------------------------------------------- + void VertexDeclaration::removeAllElements(void) + { + mElementList.clear(); } - //----------------------------------------------------------------------------- - void VertexDeclaration::removeAllElements(void) - { - mElementList.clear(); - } //----------------------------------------------------------------------------- void VertexDeclaration::modifyElement(unsigned short elem_index, unsigned short source, size_t offset, VertexElementType theType, @@ -463,68 +463,68 @@ namespace Ogre { (*i) = VertexElement(source, offset, theType, semantic, index); } //----------------------------------------------------------------------------- - const VertexElement* VertexDeclaration::findElementBySemantic( - VertexElementSemantic sem, unsigned short index) const - { - VertexElementList::const_iterator ei, eiend; - eiend = mElementList.end(); - for (ei = mElementList.begin(); ei != eiend; ++ei) - { - if (ei->getSemantic() == sem && ei->getIndex() == index) - { - return &(*ei); - } - } - - return NULL; - - - } - //----------------------------------------------------------------------------- - VertexDeclaration::VertexElementList VertexDeclaration::findElementsBySource( - unsigned short source) const - { - VertexElementList retList; - VertexElementList::const_iterator ei, eiend; - eiend = mElementList.end(); - for (ei = mElementList.begin(); ei != eiend; ++ei) - { - if (ei->getSource() == source) - { - retList.push_back(*ei); - } - } - return retList; - - } - - //----------------------------------------------------------------------------- - size_t VertexDeclaration::getVertexSize(unsigned short source) const - { - VertexElementList::const_iterator i, iend; - iend = mElementList.end(); - size_t sz = 0; - - for (i = mElementList.begin(); i != iend; ++i) - { - if (i->getSource() == source) - { - sz += i->getSize(); - - } - } - return sz; - } + const VertexElement* VertexDeclaration::findElementBySemantic( + VertexElementSemantic sem, unsigned short index) const + { + VertexElementList::const_iterator ei, eiend; + eiend = mElementList.end(); + for (ei = mElementList.begin(); ei != eiend; ++ei) + { + if (ei->getSemantic() == sem && ei->getIndex() == index) + { + return &(*ei); + } + } + + return NULL; + + + } + //----------------------------------------------------------------------------- + VertexDeclaration::VertexElementList VertexDeclaration::findElementsBySource( + unsigned short source) const + { + VertexElementList retList; + VertexElementList::const_iterator ei, eiend; + eiend = mElementList.end(); + for (ei = mElementList.begin(); ei != eiend; ++ei) + { + if (ei->getSource() == source) + { + retList.push_back(*ei); + } + } + return retList; + + } + + //----------------------------------------------------------------------------- + size_t VertexDeclaration::getVertexSize(unsigned short source) const + { + VertexElementList::const_iterator i, iend; + iend = mElementList.end(); + size_t sz = 0; + + for (i = mElementList.begin(); i != iend; ++i) + { + if (i->getSource() == source) + { + sz += i->getSize(); + + } + } + return sz; + } //----------------------------------------------------------------------------- VertexDeclaration* VertexDeclaration::clone(HardwareBufferManagerBase* mgr) const { - HardwareBufferManagerBase* pManager = mgr ? mgr : HardwareBufferManager::getSingletonPtr(); + HardwareBufferManagerBase* pManager = mgr ? mgr : HardwareBufferManager::getSingletonPtr(); VertexDeclaration* ret = pManager->createVertexDeclaration(); - VertexElementList::const_iterator i, iend; - iend = mElementList.end(); - for (i = mElementList.begin(); i != iend; ++i) - { + VertexElementList::const_iterator i, iend; + iend = mElementList.end(); + for (i = mElementList.begin(); i != iend; ++i) + { ret->addElement(i->getSource(), i->getOffset(), i->getType(), i->getSemantic(), i->getIndex()); } return ret; @@ -593,7 +593,7 @@ namespace Ogre { } //----------------------------------------------------------------------- VertexDeclaration* VertexDeclaration::getAutoOrganisedDeclaration( - bool skeletalAnimation, bool vertexAnimation, bool vertexAnimationNormals) const + bool skeletalAnimation, bool vertexAnimation, bool vertexAnimationNormals) const { VertexDeclaration* newDecl = this->clone(); // Set all sources to the same buffer (for now) @@ -610,7 +610,7 @@ namespace Ogre { // Now sort out proper buffer assignments and offsets size_t offset = 0; c = 0; - unsigned short buffer = 0; + unsigned short buffer = 0; VertexElementSemantic prevSemantic = VES_POSITION; for (i = elems.begin(); i != elems.end(); ++i, ++c) { @@ -622,8 +622,8 @@ namespace Ogre { { case VES_POSITION: // Split positions if vertex animated with only positions - // group with normals otherwise - splitWithPrev = false; + // group with normals otherwise + splitWithPrev = false; splitWithNext = vertexAnimation && !vertexAnimationNormals; break; case VES_NORMAL: @@ -640,15 +640,15 @@ namespace Ogre { // Blend weights/indices can be sharing with their own buffer only splitWithNext = true; break; - default: + default: case VES_DIFFUSE: case VES_SPECULAR: case VES_TEXTURE_COORDINATES: case VES_BINORMAL: case VES_TANGENT: - // Make sure position is separate if animated & there were no normals - splitWithPrev = prevSemantic == VES_POSITION && - (skeletalAnimation || vertexAnimation); + // Make sure position is separate if animated & there were no normals + splitWithPrev = prevSemantic == VES_POSITION && + (skeletalAnimation || vertexAnimation); break; } @@ -694,49 +694,49 @@ namespace Ogre { return ret; } //----------------------------------------------------------------------------- - unsigned short VertexDeclaration::getNextFreeTextureCoordinate() const - { - unsigned short texCoord = 0; - for (VertexElementList::const_iterator i = mElementList.begin(); - i != mElementList.end(); ++i) - { - const VertexElement& el = *i; - if (el.getSemantic() == VES_TEXTURE_COORDINATES) - { - ++texCoord; - } - } - return texCoord; - } - //----------------------------------------------------------------------------- - VertexBufferBinding::VertexBufferBinding() : mHighIndex(0) - { - } - //----------------------------------------------------------------------------- - VertexBufferBinding::~VertexBufferBinding() - { + unsigned short VertexDeclaration::getNextFreeTextureCoordinate() const + { + unsigned short texCoord = 0; + for (VertexElementList::const_iterator i = mElementList.begin(); + i != mElementList.end(); ++i) + { + const VertexElement& el = *i; + if (el.getSemantic() == VES_TEXTURE_COORDINATES) + { + ++texCoord; + } + } + return texCoord; + } + //----------------------------------------------------------------------------- + VertexBufferBinding::VertexBufferBinding() : mHighIndex(0) + { + } + //----------------------------------------------------------------------------- + VertexBufferBinding::~VertexBufferBinding() + { unsetAllBindings(); - } + } //----------------------------------------------------------------------------- - void VertexBufferBinding::setBinding(unsigned short index, const HardwareVertexBufferSharedPtr& buffer) - { + void VertexBufferBinding::setBinding(unsigned short index, const HardwareVertexBufferSharedPtr& buffer) + { // NB will replace any existing buffer ptr at this index, and will thus cause // reference count to decrement on that buffer (possibly destroying it) - mBindingMap[index] = buffer; - mHighIndex = std::max(mHighIndex, (unsigned short)(index+1)); - } - //----------------------------------------------------------------------------- - void VertexBufferBinding::unsetBinding(unsigned short index) - { - VertexBufferBindingMap::iterator i = mBindingMap.find(index); - if (i == mBindingMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find buffer binding for index " + StringConverter::toString(index), - "VertexBufferBinding::unsetBinding"); - } - mBindingMap.erase(i); - } + mBindingMap[index] = buffer; + mHighIndex = std::max(mHighIndex, (unsigned short)(index+1)); + } + //----------------------------------------------------------------------------- + void VertexBufferBinding::unsetBinding(unsigned short index) + { + VertexBufferBindingMap::iterator i = mBindingMap.find(index); + if (i == mBindingMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find buffer binding for index " + StringConverter::toString(index), + "VertexBufferBinding::unsetBinding"); + } + mBindingMap.erase(i); + } //----------------------------------------------------------------------------- void VertexBufferBinding::unsetAllBindings(void) { @@ -744,27 +744,27 @@ namespace Ogre { mHighIndex = 0; } //----------------------------------------------------------------------------- - const VertexBufferBinding::VertexBufferBindingMap& - VertexBufferBinding::getBindings(void) const - { - return mBindingMap; - } - //----------------------------------------------------------------------------- - const HardwareVertexBufferSharedPtr& VertexBufferBinding::getBuffer(unsigned short index) const - { - VertexBufferBindingMap::const_iterator i = mBindingMap.find(index); - if (i == mBindingMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No buffer is bound to that index.", - "VertexBufferBinding::getBuffer"); - } - return i->second; - } - //----------------------------------------------------------------------------- - bool VertexBufferBinding::isBufferBound(unsigned short index) const - { - return mBindingMap.find(index) != mBindingMap.end(); - } + const VertexBufferBinding::VertexBufferBindingMap& + VertexBufferBinding::getBindings(void) const + { + return mBindingMap; + } + //----------------------------------------------------------------------------- + const HardwareVertexBufferSharedPtr& VertexBufferBinding::getBuffer(unsigned short index) const + { + VertexBufferBindingMap::const_iterator i = mBindingMap.find(index); + if (i == mBindingMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No buffer is bound to that index.", + "VertexBufferBinding::getBuffer"); + } + return i->second; + } + //----------------------------------------------------------------------------- + bool VertexBufferBinding::isBufferBound(unsigned short index) const + { + return mBindingMap.find(index) != mBindingMap.end(); + } //----------------------------------------------------------------------------- unsigned short VertexBufferBinding::getLastBoundIndex(void) const { @@ -800,11 +800,11 @@ namespace Ogre { //----------------------------------------------------------------------------- bool VertexBufferBinding::getHasInstanceData() const { - VertexBufferBinding::VertexBufferBindingMap::const_iterator i, iend; - iend = mBindingMap.end(); - for (i = mBindingMap.begin(); i != iend; ++i) - { - if ( i->second->getIsInstanceData() ) + VertexBufferBinding::VertexBufferBindingMap::const_iterator i, iend; + iend = mBindingMap.end(); + for (i = mBindingMap.begin(); i != iend; ++i) + { + if ( i->second->getIsInstanceData() ) { return true; } diff --git a/OgreMain/src/OgreHighLevelGpuProgram.cpp b/OgreMain/src/OgreHighLevelGpuProgram.cpp index d76651f46e3..95e88c4efd0 100644 --- a/OgreMain/src/OgreHighLevelGpuProgram.cpp +++ b/OgreMain/src/OgreHighLevelGpuProgram.cpp @@ -44,20 +44,20 @@ namespace Ogre //--------------------------------------------------------------------------- void HighLevelGpuProgram::loadImpl() { - if (isSupported()) - { - // load self - loadHighLevel(); - - // create low-level implementation - createLowLevelImpl(); - // load constructed assembler program (if it exists) - if (!mAssemblerProgram.isNull() && mAssemblerProgram.getPointer() != this) - { - mAssemblerProgram->load(); - } - - } + if (isSupported()) + { + // load self + loadHighLevel(); + + // create low-level implementation + createLowLevelImpl(); + // load constructed assembler program (if it exists) + if (!mAssemblerProgram.isNull() && mAssemblerProgram.getPointer() != this) + { + mAssemblerProgram->load(); + } + + } } //--------------------------------------------------------------------------- void HighLevelGpuProgram::unloadImpl() @@ -69,7 +69,7 @@ namespace Ogre } unloadHighLevel(); - resetCompileError(); + resetCompileError(); } //--------------------------------------------------------------------------- HighLevelGpuProgram::~HighLevelGpuProgram() @@ -79,25 +79,25 @@ namespace Ogre //--------------------------------------------------------------------------- GpuProgramParametersSharedPtr HighLevelGpuProgram::createParameters(void) { - // Lock mutex before allowing this since this is a top-level method - // called outside of the load() + // Lock mutex before allowing this since this is a top-level method + // called outside of the load() OGRE_LOCK_AUTO_MUTEX; // Make sure param defs are loaded GpuProgramParametersSharedPtr params = GpuProgramManager::getSingleton().createParameters(); - // Only populate named parameters if we can support this program - if (this->isSupported()) - { - loadHighLevel(); - // Errors during load may have prevented compile - if (this->isSupported()) - { - populateParameterNames(params); - } - } - // Copy in default parameters if present - if (!mDefaultParams.isNull()) - params->copyConstantsFrom(*(mDefaultParams.get())); + // Only populate named parameters if we can support this program + if (this->isSupported()) + { + loadHighLevel(); + // Errors during load may have prevented compile + if (this->isSupported()) + { + populateParameterNames(params); + } + } + // Copy in default parameters if present + if (!mDefaultParams.isNull()) + params->copyConstantsFrom(*(mDefaultParams.get())); return params; } size_t HighLevelGpuProgram::calculateSize(void) const @@ -117,37 +117,37 @@ namespace Ogre { if (!mHighLevelLoaded) { - try - { - loadHighLevelImpl(); - mHighLevelLoaded = true; - if (!mDefaultParams.isNull()) - { - // Keep a reference to old ones to copy - GpuProgramParametersSharedPtr savedParams = mDefaultParams; - // reset params to stop them being referenced in the next create - mDefaultParams.setNull(); - - // Create new params - mDefaultParams = createParameters(); - - // Copy old (matching) values across - // Don't use copyConstantsFrom since program may be different - mDefaultParams->copyMatchingNamedConstantsFrom(*savedParams.get()); - - } - - } - catch (const Exception& e) - { - // will already have been logged - LogManager::getSingleton().stream() - << "High-level program " << mName << " encountered an error " - << "during loading and is thus not supported.\n" - << e.getFullDescription(); - - mCompileError = true; - } + try + { + loadHighLevelImpl(); + mHighLevelLoaded = true; + if (!mDefaultParams.isNull()) + { + // Keep a reference to old ones to copy + GpuProgramParametersSharedPtr savedParams = mDefaultParams; + // reset params to stop them being referenced in the next create + mDefaultParams.setNull(); + + // Create new params + mDefaultParams = createParameters(); + + // Copy old (matching) values across + // Don't use copyConstantsFrom since program may be different + mDefaultParams->copyMatchingNamedConstantsFrom(*savedParams.get()); + + } + + } + catch (const Exception& e) + { + // will already have been logged + LogManager::getSingleton().stream() + << "High-level program " << mName << " encountered an error " + << "during loading and is thus not supported.\n" + << e.getFullDescription(); + + mCompileError = true; + } } } //--------------------------------------------------------------------------- @@ -156,9 +156,9 @@ namespace Ogre if (mHighLevelLoaded) { unloadHighLevelImpl(); - // Clear saved constant defs - mConstantDefsBuilt = false; - createParameterMappingStructures(true); + // Clear saved constant defs + mConstantDefsBuilt = false; + createParameterMappingStructures(true); mHighLevelLoaded = false; } @@ -180,25 +180,25 @@ namespace Ogre } - //--------------------------------------------------------------------- - const GpuNamedConstants& HighLevelGpuProgram::getConstantDefinitions() const - { - if (!mConstantDefsBuilt) - { - buildConstantDefinitions(); - mConstantDefsBuilt = true; - } - return *mConstantDefs.get(); - - } - //--------------------------------------------------------------------- - void HighLevelGpuProgram::populateParameterNames(GpuProgramParametersSharedPtr params) - { - getConstantDefinitions(); - params->_setNamedConstants(mConstantDefs); - // also set logical / physical maps for programs which use this - params->_setLogicalIndexes(mFloatLogicalToPhysical, mDoubleLogicalToPhysical, + //--------------------------------------------------------------------- + const GpuNamedConstants& HighLevelGpuProgram::getConstantDefinitions() const + { + if (!mConstantDefsBuilt) + { + buildConstantDefinitions(); + mConstantDefsBuilt = true; + } + return *mConstantDefs.get(); + + } + //--------------------------------------------------------------------- + void HighLevelGpuProgram::populateParameterNames(GpuProgramParametersSharedPtr params) + { + getConstantDefinitions(); + params->_setNamedConstants(mConstantDefs); + // also set logical / physical maps for programs which use this + params->_setLogicalIndexes(mFloatLogicalToPhysical, mDoubleLogicalToPhysical, mIntLogicalToPhysical, mUIntLogicalToPhysical, mBoolLogicalToPhysical); - } + } } diff --git a/OgreMain/src/OgreHighLevelGpuProgramManager.cpp b/OgreMain/src/OgreHighLevelGpuProgramManager.cpp index 28a6e79ae7d..ec2314bf711 100644 --- a/OgreMain/src/OgreHighLevelGpuProgramManager.cpp +++ b/OgreMain/src/OgreHighLevelGpuProgramManager.cpp @@ -31,76 +31,76 @@ THE SOFTWARE. namespace Ogre { - String sNullLang = "null"; - class NullProgram : public HighLevelGpuProgram - { - protected: - /** Internal load implementation, must be implemented by subclasses. - */ - void loadFromSource(void) {} - /** Internal method for creating an appropriate low-level program from this - high-level program, must be implemented by subclasses. */ - void createLowLevelImpl(void) {} - /// Internal unload implementation, must be implemented by subclasses - void unloadHighLevelImpl(void) {} - /// Populate the passed parameters with name->index map, must be overridden - void populateParameterNames(GpuProgramParametersSharedPtr params) - { - // Skip the normal implementation - // Ensure we don't complain about missing parameter names - params->setIgnoreMissingParams(true); - - } - void buildConstantDefinitions() const - { - // do nothing - } - public: - NullProgram(ResourceManager* creator, - const String& name, ResourceHandle handle, const String& group, - bool isManual, ManualResourceLoader* loader) - : HighLevelGpuProgram(creator, name, handle, group, isManual, loader){} - ~NullProgram() {} - /// Overridden from GpuProgram - never supported - bool isSupported(void) const { return false; } - /// Overridden from GpuProgram - const String& getLanguage(void) const { return sNullLang; } + String sNullLang = "null"; + class NullProgram : public HighLevelGpuProgram + { + protected: + /** Internal load implementation, must be implemented by subclasses. + */ + void loadFromSource(void) {} + /** Internal method for creating an appropriate low-level program from this + high-level program, must be implemented by subclasses. */ + void createLowLevelImpl(void) {} + /// Internal unload implementation, must be implemented by subclasses + void unloadHighLevelImpl(void) {} + /// Populate the passed parameters with name->index map, must be overridden + void populateParameterNames(GpuProgramParametersSharedPtr params) + { + // Skip the normal implementation + // Ensure we don't complain about missing parameter names + params->setIgnoreMissingParams(true); + + } + void buildConstantDefinitions() const + { + // do nothing + } + public: + NullProgram(ResourceManager* creator, + const String& name, ResourceHandle handle, const String& group, + bool isManual, ManualResourceLoader* loader) + : HighLevelGpuProgram(creator, name, handle, group, isManual, loader){} + ~NullProgram() {} + /// Overridden from GpuProgram - never supported + bool isSupported(void) const { return false; } + /// Overridden from GpuProgram + const String& getLanguage(void) const { return sNullLang; } size_t calculateSize(void) const { return 0; } - /// Overridden from StringInterface - bool setParameter(const String& name, const String& value) - { - // always silently ignore all parameters so as not to report errors on - // unsupported platforms - return true; - } - - }; - class NullProgramFactory : public HighLevelGpuProgramFactory - { - public: - NullProgramFactory() {} - ~NullProgramFactory() {} - /// Get the name of the language this factory creates programs for - const String& getLanguage(void) const - { - return sNullLang; - } - HighLevelGpuProgram* create(ResourceManager* creator, - const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader) - { - return OGRE_NEW NullProgram(creator, name, handle, group, isManual, loader); - } - void destroy(HighLevelGpuProgram* prog) - { - OGRE_DELETE prog; - } - - }; - //----------------------------------------------------------------------- - template<> HighLevelGpuProgramManager* - Singleton::msSingleton = 0; + /// Overridden from StringInterface + bool setParameter(const String& name, const String& value) + { + // always silently ignore all parameters so as not to report errors on + // unsupported platforms + return true; + } + + }; + class NullProgramFactory : public HighLevelGpuProgramFactory + { + public: + NullProgramFactory() {} + ~NullProgramFactory() {} + /// Get the name of the language this factory creates programs for + const String& getLanguage(void) const + { + return sNullLang; + } + HighLevelGpuProgram* create(ResourceManager* creator, + const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader) + { + return OGRE_NEW NullProgram(creator, name, handle, group, isManual, loader); + } + void destroy(HighLevelGpuProgram* prog) + { + OGRE_DELETE prog; + } + + }; + //----------------------------------------------------------------------- + template<> HighLevelGpuProgramManager* + Singleton::msSingleton = 0; HighLevelGpuProgramManager* HighLevelGpuProgramManager::getSingletonPtr(void) { return msSingleton; @@ -109,9 +109,9 @@ namespace Ogre { { assert( msSingleton ); return ( *msSingleton ); } - //----------------------------------------------------------------------- - HighLevelGpuProgramManager::HighLevelGpuProgramManager() - { + //----------------------------------------------------------------------- + HighLevelGpuProgramManager::HighLevelGpuProgramManager() + { // Loading order mLoadOrder = 50.0f; // Resource type @@ -119,24 +119,24 @@ namespace Ogre { ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); - mNullFactory = OGRE_NEW NullProgramFactory(); - addFactory(mNullFactory); - mUnifiedFactory = OGRE_NEW UnifiedHighLevelGpuProgramFactory(); - addFactory(mUnifiedFactory); - } - //----------------------------------------------------------------------- - HighLevelGpuProgramManager::~HighLevelGpuProgramManager() - { - OGRE_DELETE mUnifiedFactory; - OGRE_DELETE mNullFactory; + mNullFactory = OGRE_NEW NullProgramFactory(); + addFactory(mNullFactory); + mUnifiedFactory = OGRE_NEW UnifiedHighLevelGpuProgramFactory(); + addFactory(mUnifiedFactory); + } + //----------------------------------------------------------------------- + HighLevelGpuProgramManager::~HighLevelGpuProgramManager() + { + OGRE_DELETE mUnifiedFactory; + OGRE_DELETE mNullFactory; ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); - } + } //--------------------------------------------------------------------------- - void HighLevelGpuProgramManager::addFactory(HighLevelGpuProgramFactory* factory) - { - // deliberately allow later plugins to override earlier ones - mFactories[factory->getLanguage()] = factory; - } + void HighLevelGpuProgramManager::addFactory(HighLevelGpuProgramFactory* factory) + { + // deliberately allow later plugins to override earlier ones + mFactories[factory->getLanguage()] = factory; + } //--------------------------------------------------------------------------- void HighLevelGpuProgramManager::removeFactory(HighLevelGpuProgramFactory* factory) { @@ -149,25 +149,25 @@ namespace Ogre { } } //--------------------------------------------------------------------------- - HighLevelGpuProgramFactory* HighLevelGpuProgramManager::getFactory(const String& language) - { - FactoryMap::iterator i = mFactories.find(language); - - if (i == mFactories.end()) - { - // use the null factory to create programs that will never be supported - i = mFactories.find(sNullLang); - } - return i->second; - } - //--------------------------------------------------------------------- - bool HighLevelGpuProgramManager::isLanguageSupported(const String& lang) - { - FactoryMap::iterator i = mFactories.find(lang); - - return i != mFactories.end(); - - } + HighLevelGpuProgramFactory* HighLevelGpuProgramManager::getFactory(const String& language) + { + FactoryMap::iterator i = mFactories.find(language); + + if (i == mFactories.end()) + { + // use the null factory to create programs that will never be supported + i = mFactories.find(sNullLang); + } + return i->second; + } + //--------------------------------------------------------------------- + bool HighLevelGpuProgramManager::isLanguageSupported(const String& lang) + { + FactoryMap::iterator i = mFactories.find(lang); + + return i != mFactories.end(); + + } //--------------------------------------------------------------------------- Resource* HighLevelGpuProgramManager::createImpl(const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader, @@ -192,7 +192,7 @@ namespace Ogre { } //--------------------------------------------------------------------------- HighLevelGpuProgramPtr HighLevelGpuProgramManager::createProgram( - const String& name, const String& groupName, + const String& name, const String& groupName, const String& language, GpuProgramType gptype) { ResourcePtr ret = ResourcePtr( diff --git a/OgreMain/src/OgreImage.cpp b/OgreMain/src/OgreImage.cpp index a68405f3ec0..80c8a2e4a2f 100644 --- a/OgreMain/src/OgreImage.cpp +++ b/OgreMain/src/OgreImage.cpp @@ -35,367 +35,367 @@ THE SOFTWARE. #include "OgreResourceGroupManager.h" namespace Ogre { - ImageCodec::~ImageCodec() { - } - - //----------------------------------------------------------------------------- - Image::Image() - : mWidth(0), - mHeight(0), - mDepth(0), - mBufSize(0), - mNumMipmaps(0), - mFlags(0), - mFormat(PF_UNKNOWN), - mBuffer( NULL ), - mAutoDelete( true ) - { - } - - //----------------------------------------------------------------------------- - Image::Image( const Image &img ) - : mBuffer( NULL ), - mAutoDelete( true ) - { - // call assignment operator - *this = img; - } - - //----------------------------------------------------------------------------- - Image::~Image() - { - freeMemory(); - } - //--------------------------------------------------------------------- - void Image::freeMemory() - { - //Only delete if this was not a dynamic image (meaning app holds & destroys buffer) - if( mBuffer && mAutoDelete ) - { - OGRE_FREE(mBuffer, MEMCATEGORY_GENERAL); - mBuffer = NULL; - } - - } - - //----------------------------------------------------------------------------- - Image & Image::operator = ( const Image &img ) - { - freeMemory(); - mWidth = img.mWidth; - mHeight = img.mHeight; - mDepth = img.mDepth; - mFormat = img.mFormat; - mBufSize = img.mBufSize; - mFlags = img.mFlags; - mPixelSize = img.mPixelSize; - mNumMipmaps = img.mNumMipmaps; - mAutoDelete = img.mAutoDelete; - //Only create/copy when previous data was not dynamic data - if( mAutoDelete ) - { - mBuffer = OGRE_ALLOC_T(uchar, mBufSize, MEMCATEGORY_GENERAL); - memcpy( mBuffer, img.mBuffer, mBufSize ); - } - else - { - mBuffer = img.mBuffer; - } - - return *this; - } - - //----------------------------------------------------------------------------- - Image & Image::flipAroundY() - { - if( !mBuffer ) - { - OGRE_EXCEPT( - Exception::ERR_INTERNAL_ERROR, - "Can not flip an uninitialised texture", - "Image::flipAroundY" ); - } + ImageCodec::~ImageCodec() { + } + + //----------------------------------------------------------------------------- + Image::Image() + : mWidth(0), + mHeight(0), + mDepth(0), + mBufSize(0), + mNumMipmaps(0), + mFlags(0), + mFormat(PF_UNKNOWN), + mBuffer( NULL ), + mAutoDelete( true ) + { + } + + //----------------------------------------------------------------------------- + Image::Image( const Image &img ) + : mBuffer( NULL ), + mAutoDelete( true ) + { + // call assignment operator + *this = img; + } + + //----------------------------------------------------------------------------- + Image::~Image() + { + freeMemory(); + } + //--------------------------------------------------------------------- + void Image::freeMemory() + { + //Only delete if this was not a dynamic image (meaning app holds & destroys buffer) + if( mBuffer && mAutoDelete ) + { + OGRE_FREE(mBuffer, MEMCATEGORY_GENERAL); + mBuffer = NULL; + } + + } + + //----------------------------------------------------------------------------- + Image & Image::operator = ( const Image &img ) + { + freeMemory(); + mWidth = img.mWidth; + mHeight = img.mHeight; + mDepth = img.mDepth; + mFormat = img.mFormat; + mBufSize = img.mBufSize; + mFlags = img.mFlags; + mPixelSize = img.mPixelSize; + mNumMipmaps = img.mNumMipmaps; + mAutoDelete = img.mAutoDelete; + //Only create/copy when previous data was not dynamic data + if( mAutoDelete ) + { + mBuffer = OGRE_ALLOC_T(uchar, mBufSize, MEMCATEGORY_GENERAL); + memcpy( mBuffer, img.mBuffer, mBufSize ); + } + else + { + mBuffer = img.mBuffer; + } + + return *this; + } + + //----------------------------------------------------------------------------- + Image & Image::flipAroundY() + { + if( !mBuffer ) + { + OGRE_EXCEPT( + Exception::ERR_INTERNAL_ERROR, + "Can not flip an uninitialised texture", + "Image::flipAroundY" ); + } mNumMipmaps = 0; // Image operations lose precomputed mipmaps - uchar *pTempBuffer1 = NULL; - ushort *pTempBuffer2 = NULL; - uchar *pTempBuffer3 = NULL; - uint *pTempBuffer4 = NULL; - - uchar *src1 = mBuffer; - ushort *src2 = (ushort *)mBuffer; - uchar *src3 = mBuffer; - uint *src4 = (uint *)mBuffer; - - ushort y; - switch (mPixelSize) - { - case 1: - pTempBuffer1 = OGRE_ALLOC_T(uchar, mWidth * mHeight, MEMCATEGORY_GENERAL); - for (y = 0; y < mHeight; y++) - { - uchar *dst1 = (pTempBuffer1 + ((y * mWidth) + mWidth - 1)); - for (ushort x = 0; x < mWidth; x++) - memcpy(dst1--, src1++, sizeof(uchar)); - } - - memcpy(mBuffer, pTempBuffer1, mWidth * mHeight * sizeof(uchar)); - OGRE_FREE(pTempBuffer1, MEMCATEGORY_GENERAL); - break; - - case 2: - pTempBuffer2 = OGRE_ALLOC_T(ushort, mWidth * mHeight, MEMCATEGORY_GENERAL); - for (y = 0; y < mHeight; y++) - { - ushort *dst2 = (pTempBuffer2 + ((y * mWidth) + mWidth - 1)); - for (ushort x = 0; x < mWidth; x++) - memcpy(dst2--, src2++, sizeof(ushort)); - } - - memcpy(mBuffer, pTempBuffer2, mWidth * mHeight * sizeof(ushort)); - OGRE_FREE(pTempBuffer2, MEMCATEGORY_GENERAL); - break; - - case 3: - pTempBuffer3 = OGRE_ALLOC_T(uchar, mWidth * mHeight * 3, MEMCATEGORY_GENERAL); - for (y = 0; y < mHeight; y++) - { - size_t offset = ((y * mWidth) + (mWidth - 1)) * 3; - uchar *dst3 = pTempBuffer3; - dst3 += offset; - for (size_t x = 0; x < mWidth; x++) - { - memcpy(dst3, src3, sizeof(uchar) * 3); - dst3 -= 3; src3 += 3; - } - } - - memcpy(mBuffer, pTempBuffer3, mWidth * mHeight * sizeof(uchar) * 3); - OGRE_FREE(pTempBuffer3, MEMCATEGORY_GENERAL); - break; - - case 4: - pTempBuffer4 = OGRE_ALLOC_T(uint, mWidth * mHeight, MEMCATEGORY_GENERAL); - for (y = 0; y < mHeight; y++) - { - uint *dst4 = (pTempBuffer4 + ((y * mWidth) + mWidth - 1)); - for (ushort x = 0; x < mWidth; x++) - memcpy(dst4--, src4++, sizeof(uint)); - } - - memcpy(mBuffer, pTempBuffer4, mWidth * mHeight * sizeof(uint)); - OGRE_FREE(pTempBuffer4, MEMCATEGORY_GENERAL); - break; - - default: - OGRE_EXCEPT( - Exception::ERR_INTERNAL_ERROR, - "Unknown pixel depth", - "Image::flipAroundY" ); - break; - } - - return *this; - - } - - //----------------------------------------------------------------------------- - Image & Image::flipAroundX() - { - if( !mBuffer ) - { - OGRE_EXCEPT( - Exception::ERR_INTERNAL_ERROR, - "Can not flip an uninitialised texture", - "Image::flipAroundX" ); - } + uchar *pTempBuffer1 = NULL; + ushort *pTempBuffer2 = NULL; + uchar *pTempBuffer3 = NULL; + uint *pTempBuffer4 = NULL; + + uchar *src1 = mBuffer; + ushort *src2 = (ushort *)mBuffer; + uchar *src3 = mBuffer; + uint *src4 = (uint *)mBuffer; + + ushort y; + switch (mPixelSize) + { + case 1: + pTempBuffer1 = OGRE_ALLOC_T(uchar, mWidth * mHeight, MEMCATEGORY_GENERAL); + for (y = 0; y < mHeight; y++) + { + uchar *dst1 = (pTempBuffer1 + ((y * mWidth) + mWidth - 1)); + for (ushort x = 0; x < mWidth; x++) + memcpy(dst1--, src1++, sizeof(uchar)); + } + + memcpy(mBuffer, pTempBuffer1, mWidth * mHeight * sizeof(uchar)); + OGRE_FREE(pTempBuffer1, MEMCATEGORY_GENERAL); + break; + + case 2: + pTempBuffer2 = OGRE_ALLOC_T(ushort, mWidth * mHeight, MEMCATEGORY_GENERAL); + for (y = 0; y < mHeight; y++) + { + ushort *dst2 = (pTempBuffer2 + ((y * mWidth) + mWidth - 1)); + for (ushort x = 0; x < mWidth; x++) + memcpy(dst2--, src2++, sizeof(ushort)); + } + + memcpy(mBuffer, pTempBuffer2, mWidth * mHeight * sizeof(ushort)); + OGRE_FREE(pTempBuffer2, MEMCATEGORY_GENERAL); + break; + + case 3: + pTempBuffer3 = OGRE_ALLOC_T(uchar, mWidth * mHeight * 3, MEMCATEGORY_GENERAL); + for (y = 0; y < mHeight; y++) + { + size_t offset = ((y * mWidth) + (mWidth - 1)) * 3; + uchar *dst3 = pTempBuffer3; + dst3 += offset; + for (size_t x = 0; x < mWidth; x++) + { + memcpy(dst3, src3, sizeof(uchar) * 3); + dst3 -= 3; src3 += 3; + } + } + + memcpy(mBuffer, pTempBuffer3, mWidth * mHeight * sizeof(uchar) * 3); + OGRE_FREE(pTempBuffer3, MEMCATEGORY_GENERAL); + break; + + case 4: + pTempBuffer4 = OGRE_ALLOC_T(uint, mWidth * mHeight, MEMCATEGORY_GENERAL); + for (y = 0; y < mHeight; y++) + { + uint *dst4 = (pTempBuffer4 + ((y * mWidth) + mWidth - 1)); + for (ushort x = 0; x < mWidth; x++) + memcpy(dst4--, src4++, sizeof(uint)); + } + + memcpy(mBuffer, pTempBuffer4, mWidth * mHeight * sizeof(uint)); + OGRE_FREE(pTempBuffer4, MEMCATEGORY_GENERAL); + break; + + default: + OGRE_EXCEPT( + Exception::ERR_INTERNAL_ERROR, + "Unknown pixel depth", + "Image::flipAroundY" ); + break; + } + + return *this; + + } + + //----------------------------------------------------------------------------- + Image & Image::flipAroundX() + { + if( !mBuffer ) + { + OGRE_EXCEPT( + Exception::ERR_INTERNAL_ERROR, + "Can not flip an uninitialised texture", + "Image::flipAroundX" ); + } mNumMipmaps = 0; // Image operations lose precomputed mipmaps - size_t rowSpan = mWidth * mPixelSize; - - uchar *pTempBuffer = OGRE_ALLOC_T(uchar, rowSpan * mHeight, MEMCATEGORY_GENERAL); - uchar *ptr1 = mBuffer, *ptr2 = pTempBuffer + ( ( mHeight - 1 ) * rowSpan ); - - for( ushort i = 0; i < mHeight; i++ ) - { - memcpy( ptr2, ptr1, rowSpan ); - ptr1 += rowSpan; ptr2 -= rowSpan; - } - - memcpy( mBuffer, pTempBuffer, rowSpan * mHeight); - - OGRE_FREE(pTempBuffer, MEMCATEGORY_GENERAL); - - return *this; - } - - //----------------------------------------------------------------------------- - Image& Image::loadDynamicImage( uchar* pData, uint32 uWidth, uint32 uHeight, - uint32 depth, - PixelFormat eFormat, bool autoDelete, - size_t numFaces, uint8 numMipMaps) - { - - freeMemory(); - // Set image metadata - mWidth = uWidth; - mHeight = uHeight; - mDepth = depth; - mFormat = eFormat; - mPixelSize = static_cast(PixelUtil::getNumElemBytes( mFormat )); - mNumMipmaps = numMipMaps; - mFlags = 0; - // Set flags - if (PixelUtil::isCompressed(eFormat)) - mFlags |= IF_COMPRESSED; - if (mDepth != 1) - mFlags |= IF_3D_TEXTURE; - if(numFaces == 6) - mFlags |= IF_CUBEMAP; - if(numFaces != 6 && numFaces != 1) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Number of faces currently must be 6 or 1.", - "Image::loadDynamicImage"); - - mBufSize = calculateSize(numMipMaps, numFaces, uWidth, uHeight, depth, eFormat); - mBuffer = pData; - mAutoDelete = autoDelete; - - return *this; - - } - - //----------------------------------------------------------------------------- - Image & Image::loadRawData( - DataStreamPtr& stream, - uint32 uWidth, uint32 uHeight, uint32 uDepth, - PixelFormat eFormat, - size_t numFaces, size_t numMipMaps) - { - - size_t size = calculateSize(numMipMaps, numFaces, uWidth, uHeight, uDepth, eFormat); - if (size != stream->size()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Stream size does not match calculated image size", - "Image::loadRawData"); - } - - uchar *buffer = OGRE_ALLOC_T(uchar, size, MEMCATEGORY_GENERAL); - stream->read(buffer, size); - - return loadDynamicImage(buffer, - uWidth, uHeight, uDepth, - eFormat, true, numFaces, numMipMaps); - - } - //----------------------------------------------------------------------------- - Image & Image::load(const String& strFileName, const String& group) - { - - String strExt; - - size_t pos = strFileName.find_last_of("."); - if( pos != String::npos && pos < (strFileName.length() - 1)) - { - strExt = strFileName.substr(pos+1); - } - - DataStreamPtr encoded = ResourceGroupManager::getSingleton().openResource(strFileName, group); - return load(encoded, strExt); - - } - //----------------------------------------------------------------------------- - void Image::save(const String& filename) - { - if( !mBuffer ) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "No image data loaded", - "Image::save"); - } - - String strExt; - size_t pos = filename.find_last_of("."); - if( pos == String::npos ) - OGRE_EXCEPT( - Exception::ERR_INVALIDPARAMS, - "Unable to save image file '" + filename + "' - invalid extension.", - "Image::save" ); - - while( pos != filename.length() - 1 ) - strExt += filename[++pos]; - - Codec * pCodec = Codec::getCodec(strExt); - if( !pCodec ) - OGRE_EXCEPT( - Exception::ERR_INVALIDPARAMS, - "Unable to save image file '" + filename + "' - invalid extension.", - "Image::save" ); - - ImageCodec::ImageData* imgData = OGRE_NEW ImageCodec::ImageData(); - imgData->format = mFormat; - imgData->height = mHeight; - imgData->width = mWidth; - imgData->depth = mDepth; - imgData->size = mBufSize; - // Wrap in CodecDataPtr, this will delete - Codec::CodecDataPtr codeDataPtr(imgData); - // Wrap memory, be sure not to delete when stream destroyed - MemoryDataStreamPtr wrapper(OGRE_NEW MemoryDataStream(mBuffer, mBufSize, false)); - - pCodec->encodeToFile(wrapper, filename, codeDataPtr); - } - //--------------------------------------------------------------------- - DataStreamPtr Image::encode(const String& formatextension) - { - if( !mBuffer ) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "No image data loaded", - "Image::encode"); - } - - Codec * pCodec = Codec::getCodec(formatextension); - if( !pCodec ) - OGRE_EXCEPT( - Exception::ERR_INVALIDPARAMS, - "Unable to encode image data as '" + formatextension + "' - invalid extension.", - "Image::encode" ); - - ImageCodec::ImageData* imgData = OGRE_NEW ImageCodec::ImageData(); - imgData->format = mFormat; - imgData->height = mHeight; - imgData->width = mWidth; - imgData->depth = mDepth; - // Wrap in CodecDataPtr, this will delete - Codec::CodecDataPtr codeDataPtr(imgData); - // Wrap memory, be sure not to delete when stream destroyed - MemoryDataStreamPtr wrapper(OGRE_NEW MemoryDataStream(mBuffer, mBufSize, false)); - - return pCodec->encode(wrapper, codeDataPtr); - } - //----------------------------------------------------------------------------- - Image & Image::load(DataStreamPtr& stream, const String& type ) - { - freeMemory(); - - Codec * pCodec = 0; - if (!type.empty()) - { - // use named codec - pCodec = Codec::getCodec(type); - } - else - { - // derive from magic number - // read the first 32 bytes or file size, if less - size_t magicLen = std::min(stream->size(), (size_t)32); - char magicBuf[32]; - stream->read(magicBuf, magicLen); - // return to start - stream->seek(0); - pCodec = Codec::getCodec(magicBuf, magicLen); + size_t rowSpan = mWidth * mPixelSize; + + uchar *pTempBuffer = OGRE_ALLOC_T(uchar, rowSpan * mHeight, MEMCATEGORY_GENERAL); + uchar *ptr1 = mBuffer, *ptr2 = pTempBuffer + ( ( mHeight - 1 ) * rowSpan ); + + for( ushort i = 0; i < mHeight; i++ ) + { + memcpy( ptr2, ptr1, rowSpan ); + ptr1 += rowSpan; ptr2 -= rowSpan; + } + + memcpy( mBuffer, pTempBuffer, rowSpan * mHeight); + + OGRE_FREE(pTempBuffer, MEMCATEGORY_GENERAL); + + return *this; + } + + //----------------------------------------------------------------------------- + Image& Image::loadDynamicImage( uchar* pData, uint32 uWidth, uint32 uHeight, + uint32 depth, + PixelFormat eFormat, bool autoDelete, + size_t numFaces, uint8 numMipMaps) + { + + freeMemory(); + // Set image metadata + mWidth = uWidth; + mHeight = uHeight; + mDepth = depth; + mFormat = eFormat; + mPixelSize = static_cast(PixelUtil::getNumElemBytes( mFormat )); + mNumMipmaps = numMipMaps; + mFlags = 0; + // Set flags + if (PixelUtil::isCompressed(eFormat)) + mFlags |= IF_COMPRESSED; + if (mDepth != 1) + mFlags |= IF_3D_TEXTURE; + if(numFaces == 6) + mFlags |= IF_CUBEMAP; + if(numFaces != 6 && numFaces != 1) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Number of faces currently must be 6 or 1.", + "Image::loadDynamicImage"); + + mBufSize = calculateSize(numMipMaps, numFaces, uWidth, uHeight, depth, eFormat); + mBuffer = pData; + mAutoDelete = autoDelete; + + return *this; + + } + + //----------------------------------------------------------------------------- + Image & Image::loadRawData( + DataStreamPtr& stream, + uint32 uWidth, uint32 uHeight, uint32 uDepth, + PixelFormat eFormat, + size_t numFaces, size_t numMipMaps) + { + + size_t size = calculateSize(numMipMaps, numFaces, uWidth, uHeight, uDepth, eFormat); + if (size != stream->size()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Stream size does not match calculated image size", + "Image::loadRawData"); + } + + uchar *buffer = OGRE_ALLOC_T(uchar, size, MEMCATEGORY_GENERAL); + stream->read(buffer, size); + + return loadDynamicImage(buffer, + uWidth, uHeight, uDepth, + eFormat, true, numFaces, numMipMaps); + + } + //----------------------------------------------------------------------------- + Image & Image::load(const String& strFileName, const String& group) + { + + String strExt; + + size_t pos = strFileName.find_last_of("."); + if( pos != String::npos && pos < (strFileName.length() - 1)) + { + strExt = strFileName.substr(pos+1); + } + + DataStreamPtr encoded = ResourceGroupManager::getSingleton().openResource(strFileName, group); + return load(encoded, strExt); + + } + //----------------------------------------------------------------------------- + void Image::save(const String& filename) + { + if( !mBuffer ) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "No image data loaded", + "Image::save"); + } + + String strExt; + size_t pos = filename.find_last_of("."); + if( pos == String::npos ) + OGRE_EXCEPT( + Exception::ERR_INVALIDPARAMS, + "Unable to save image file '" + filename + "' - invalid extension.", + "Image::save" ); + + while( pos != filename.length() - 1 ) + strExt += filename[++pos]; + + Codec * pCodec = Codec::getCodec(strExt); + if( !pCodec ) + OGRE_EXCEPT( + Exception::ERR_INVALIDPARAMS, + "Unable to save image file '" + filename + "' - invalid extension.", + "Image::save" ); + + ImageCodec::ImageData* imgData = OGRE_NEW ImageCodec::ImageData(); + imgData->format = mFormat; + imgData->height = mHeight; + imgData->width = mWidth; + imgData->depth = mDepth; + imgData->size = mBufSize; + // Wrap in CodecDataPtr, this will delete + Codec::CodecDataPtr codeDataPtr(imgData); + // Wrap memory, be sure not to delete when stream destroyed + MemoryDataStreamPtr wrapper(OGRE_NEW MemoryDataStream(mBuffer, mBufSize, false)); + + pCodec->encodeToFile(wrapper, filename, codeDataPtr); + } + //--------------------------------------------------------------------- + DataStreamPtr Image::encode(const String& formatextension) + { + if( !mBuffer ) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "No image data loaded", + "Image::encode"); + } + + Codec * pCodec = Codec::getCodec(formatextension); + if( !pCodec ) + OGRE_EXCEPT( + Exception::ERR_INVALIDPARAMS, + "Unable to encode image data as '" + formatextension + "' - invalid extension.", + "Image::encode" ); + + ImageCodec::ImageData* imgData = OGRE_NEW ImageCodec::ImageData(); + imgData->format = mFormat; + imgData->height = mHeight; + imgData->width = mWidth; + imgData->depth = mDepth; + // Wrap in CodecDataPtr, this will delete + Codec::CodecDataPtr codeDataPtr(imgData); + // Wrap memory, be sure not to delete when stream destroyed + MemoryDataStreamPtr wrapper(OGRE_NEW MemoryDataStream(mBuffer, mBufSize, false)); + + return pCodec->encode(wrapper, codeDataPtr); + } + //----------------------------------------------------------------------------- + Image & Image::load(DataStreamPtr& stream, const String& type ) + { + freeMemory(); + + Codec * pCodec = 0; + if (!type.empty()) + { + // use named codec + pCodec = Codec::getCodec(type); + } + else + { + // derive from magic number + // read the first 32 bytes or file size, if less + size_t magicLen = std::min(stream->size(), (size_t)32); + char magicBuf[32]; + stream->read(magicBuf, magicLen); + // return to start + stream->seek(0); + pCodec = Codec::getCodec(magicBuf, magicLen); if( !pCodec ) OGRE_EXCEPT( @@ -403,289 +403,289 @@ namespace Ogre { "Unable to load image: Image format is unknown. Unable to identify codec. " "Check it or specify format explicitly.", "Image::load" ); - } - - Codec::DecodeResult res = pCodec->decode(stream); - - ImageCodec::ImageData* pData = - static_cast(res.second.getPointer()); - - mWidth = pData->width; - mHeight = pData->height; - mDepth = pData->depth; - mBufSize = pData->size; - mNumMipmaps = pData->num_mipmaps; - mFlags = pData->flags; - - // Get the format and compute the pixel size - mFormat = pData->format; - mPixelSize = static_cast(PixelUtil::getNumElemBytes( mFormat )); - // Just use internal buffer of returned memory stream - mBuffer = res.first->getPtr(); - // Make sure stream does not delete - res.first->setFreeOnClose(false); - // make sure we delete - mAutoDelete = true; - - return *this; - } - //--------------------------------------------------------------------- - String Image::getFileExtFromMagic(DataStreamPtr stream) - { - // read the first 32 bytes or file size, if less - size_t magicLen = std::min(stream->size(), (size_t)32); - char magicBuf[32]; - stream->read(magicBuf, magicLen); - // return to start - stream->seek(0); - Codec* pCodec = Codec::getCodec(magicBuf, magicLen); - - if(pCodec) - return pCodec->getType(); - else - return BLANKSTRING; - - } - //----------------------------------------------------------------------------- - uchar* Image::getData() - { - return mBuffer; - } - - //----------------------------------------------------------------------------- - const uchar* Image::getData() const - { - assert( mBuffer ); - return mBuffer; - } - - //----------------------------------------------------------------------------- - size_t Image::getSize() const - { - return mBufSize; - } - - //----------------------------------------------------------------------------- - uint8 Image::getNumMipmaps() const - { - return mNumMipmaps; - } - - //----------------------------------------------------------------------------- - bool Image::hasFlag(const ImageFlags imgFlag) const - { - if(mFlags & imgFlag) - { - return true; - } - else - { - return false; - } - } - - //----------------------------------------------------------------------------- - uint32 Image::getDepth() const - { - return mDepth; - } - //----------------------------------------------------------------------------- - uint32 Image::getWidth() const - { - return mWidth; - } - - //----------------------------------------------------------------------------- - uint32 Image::getHeight() const - { - return mHeight; - } - //----------------------------------------------------------------------------- - size_t Image::getNumFaces(void) const - { - if(hasFlag(IF_CUBEMAP)) - return 6; - return 1; - } - //----------------------------------------------------------------------------- - size_t Image::getRowSpan() const - { - return mWidth * mPixelSize; - } - - //----------------------------------------------------------------------------- - PixelFormat Image::getFormat() const - { - return mFormat; - } - - //----------------------------------------------------------------------------- - uchar Image::getBPP() const - { - return mPixelSize * 8; - } - - //----------------------------------------------------------------------------- - bool Image::getHasAlpha(void) const - { - return PixelUtil::getFlags(mFormat) & PFF_HASALPHA; - } - //----------------------------------------------------------------------------- - void Image::applyGamma( uchar *buffer, Real gamma, size_t size, uchar bpp ) - { - if( gamma == 1.0f ) - return; - - //NB only 24/32-bit supported - if( bpp != 24 && bpp != 32 ) return; - - uint stride = bpp >> 3; - - uchar gammaramp[256]; - const Real exponent = 1.0f / gamma; - for(int i = 0; i < 256; i++) { - gammaramp[i] = static_cast(Math::Pow(i/255.0f, exponent)*255+0.5f); - } - - for( size_t i = 0, j = size / stride; i < j; i++, buffer += stride ) - { - buffer[0] = gammaramp[buffer[0]]; - buffer[1] = gammaramp[buffer[1]]; - buffer[2] = gammaramp[buffer[2]]; - } - } - //----------------------------------------------------------------------------- - void Image::resize(ushort width, ushort height, Filter filter) - { - // resizing dynamic images is not supported - assert(mAutoDelete); - assert(mDepth == 1); - - // reassign buffer to temp image, make sure auto-delete is true - Image temp; - temp.loadDynamicImage(mBuffer, mWidth, mHeight, 1, mFormat, true); - // do not delete[] mBuffer! temp will destroy it - - // set new dimensions, allocate new buffer - mWidth = width; - mHeight = height; - mBufSize = PixelUtil::getMemorySize(mWidth, mHeight, 1, mFormat); - mBuffer = OGRE_ALLOC_T(uchar, mBufSize, MEMCATEGORY_GENERAL); + } + + Codec::DecodeResult res = pCodec->decode(stream); + + ImageCodec::ImageData* pData = + static_cast(res.second.getPointer()); + + mWidth = pData->width; + mHeight = pData->height; + mDepth = pData->depth; + mBufSize = pData->size; + mNumMipmaps = pData->num_mipmaps; + mFlags = pData->flags; + + // Get the format and compute the pixel size + mFormat = pData->format; + mPixelSize = static_cast(PixelUtil::getNumElemBytes( mFormat )); + // Just use internal buffer of returned memory stream + mBuffer = res.first->getPtr(); + // Make sure stream does not delete + res.first->setFreeOnClose(false); + // make sure we delete + mAutoDelete = true; + + return *this; + } + //--------------------------------------------------------------------- + String Image::getFileExtFromMagic(DataStreamPtr stream) + { + // read the first 32 bytes or file size, if less + size_t magicLen = std::min(stream->size(), (size_t)32); + char magicBuf[32]; + stream->read(magicBuf, magicLen); + // return to start + stream->seek(0); + Codec* pCodec = Codec::getCodec(magicBuf, magicLen); + + if(pCodec) + return pCodec->getType(); + else + return BLANKSTRING; + + } + //----------------------------------------------------------------------------- + uchar* Image::getData() + { + return mBuffer; + } + + //----------------------------------------------------------------------------- + const uchar* Image::getData() const + { + assert( mBuffer ); + return mBuffer; + } + + //----------------------------------------------------------------------------- + size_t Image::getSize() const + { + return mBufSize; + } + + //----------------------------------------------------------------------------- + uint8 Image::getNumMipmaps() const + { + return mNumMipmaps; + } + + //----------------------------------------------------------------------------- + bool Image::hasFlag(const ImageFlags imgFlag) const + { + if(mFlags & imgFlag) + { + return true; + } + else + { + return false; + } + } + + //----------------------------------------------------------------------------- + uint32 Image::getDepth() const + { + return mDepth; + } + //----------------------------------------------------------------------------- + uint32 Image::getWidth() const + { + return mWidth; + } + + //----------------------------------------------------------------------------- + uint32 Image::getHeight() const + { + return mHeight; + } + //----------------------------------------------------------------------------- + size_t Image::getNumFaces(void) const + { + if(hasFlag(IF_CUBEMAP)) + return 6; + return 1; + } + //----------------------------------------------------------------------------- + size_t Image::getRowSpan() const + { + return mWidth * mPixelSize; + } + + //----------------------------------------------------------------------------- + PixelFormat Image::getFormat() const + { + return mFormat; + } + + //----------------------------------------------------------------------------- + uchar Image::getBPP() const + { + return mPixelSize * 8; + } + + //----------------------------------------------------------------------------- + bool Image::getHasAlpha(void) const + { + return PixelUtil::getFlags(mFormat) & PFF_HASALPHA; + } + //----------------------------------------------------------------------------- + void Image::applyGamma( uchar *buffer, Real gamma, size_t size, uchar bpp ) + { + if( gamma == 1.0f ) + return; + + //NB only 24/32-bit supported + if( bpp != 24 && bpp != 32 ) return; + + uint stride = bpp >> 3; + + uchar gammaramp[256]; + const Real exponent = 1.0f / gamma; + for(int i = 0; i < 256; i++) { + gammaramp[i] = static_cast(Math::Pow(i/255.0f, exponent)*255+0.5f); + } + + for( size_t i = 0, j = size / stride; i < j; i++, buffer += stride ) + { + buffer[0] = gammaramp[buffer[0]]; + buffer[1] = gammaramp[buffer[1]]; + buffer[2] = gammaramp[buffer[2]]; + } + } + //----------------------------------------------------------------------------- + void Image::resize(ushort width, ushort height, Filter filter) + { + // resizing dynamic images is not supported + assert(mAutoDelete); + assert(mDepth == 1); + + // reassign buffer to temp image, make sure auto-delete is true + Image temp; + temp.loadDynamicImage(mBuffer, mWidth, mHeight, 1, mFormat, true); + // do not delete[] mBuffer! temp will destroy it + + // set new dimensions, allocate new buffer + mWidth = width; + mHeight = height; + mBufSize = PixelUtil::getMemorySize(mWidth, mHeight, 1, mFormat); + mBuffer = OGRE_ALLOC_T(uchar, mBufSize, MEMCATEGORY_GENERAL); mNumMipmaps = 0; // Loses precomputed mipmaps - // scale the image from temp into our resized buffer - Image::scale(temp.getPixelBox(), getPixelBox(), filter); - } - //----------------------------------------------------------------------- - void Image::scale(const PixelBox &src, const PixelBox &scaled, Filter filter) - { - assert(PixelUtil::isAccessible(src.format)); - assert(PixelUtil::isAccessible(scaled.format)); - MemoryDataStreamPtr buf; // For auto-delete - PixelBox temp; - switch (filter) - { - default: - case FILTER_NEAREST: - if(src.format == scaled.format) - { - // No intermediate buffer needed - temp = scaled; - } - else - { - // Allocate temporary buffer of destination size in source format - temp = PixelBox(scaled.getWidth(), scaled.getHeight(), scaled.getDepth(), src.format); - buf.bind(OGRE_NEW MemoryDataStream(temp.getConsecutiveSize())); - temp.data = buf->getPtr(); - } - // super-optimized: no conversion - switch (PixelUtil::getNumElemBytes(src.format)) - { - case 1: NearestResampler<1>::scale(src, temp); break; - case 2: NearestResampler<2>::scale(src, temp); break; - case 3: NearestResampler<3>::scale(src, temp); break; - case 4: NearestResampler<4>::scale(src, temp); break; - case 6: NearestResampler<6>::scale(src, temp); break; - case 8: NearestResampler<8>::scale(src, temp); break; - case 12: NearestResampler<12>::scale(src, temp); break; - case 16: NearestResampler<16>::scale(src, temp); break; - default: - // never reached - assert(false); - } - if(temp.data != scaled.data) - { - // Blit temp buffer - PixelUtil::bulkPixelConversion(temp, scaled); - } - break; - - case FILTER_LINEAR: - case FILTER_BILINEAR: - switch (src.format) - { - case PF_L8: case PF_A8: case PF_BYTE_LA: - case PF_R8G8B8: case PF_B8G8R8: - case PF_R8G8B8A8: case PF_B8G8R8A8: - case PF_A8B8G8R8: case PF_A8R8G8B8: - case PF_X8B8G8R8: case PF_X8R8G8B8: - if(src.format == scaled.format) - { - // No intermediate buffer needed - temp = scaled; - } - else - { - // Allocate temp buffer of destination size in source format - temp = PixelBox(scaled.getWidth(), scaled.getHeight(), scaled.getDepth(), src.format); - buf.bind(OGRE_NEW MemoryDataStream(temp.getConsecutiveSize())); - temp.data = buf->getPtr(); - } - // super-optimized: byte-oriented math, no conversion - switch (PixelUtil::getNumElemBytes(src.format)) - { - case 1: LinearResampler_Byte<1>::scale(src, temp); break; - case 2: LinearResampler_Byte<2>::scale(src, temp); break; - case 3: LinearResampler_Byte<3>::scale(src, temp); break; - case 4: LinearResampler_Byte<4>::scale(src, temp); break; - default: - // never reached - assert(false); - } - if(temp.data != scaled.data) - { - // Blit temp buffer - PixelUtil::bulkPixelConversion(temp, scaled); - } - break; - case PF_FLOAT32_RGB: - case PF_FLOAT32_RGBA: - if (scaled.format == PF_FLOAT32_RGB || scaled.format == PF_FLOAT32_RGBA) - { - // float32 to float32, avoid unpack/repack overhead - LinearResampler_Float32::scale(src, scaled); - break; - } - // else, fall through - default: - // non-optimized: floating-point math, performs conversion but always works - LinearResampler::scale(src, scaled); - } - break; - } - } - - //----------------------------------------------------------------------------- - - ColourValue Image::getColourAt(size_t x, size_t y, size_t z) const - { - ColourValue rval; - PixelUtil::unpackColour(&rval, mFormat, &mBuffer[mPixelSize * (z * mWidth * mHeight + mWidth * y + x)]); - return rval; - } - - //----------------------------------------------------------------------------- + // scale the image from temp into our resized buffer + Image::scale(temp.getPixelBox(), getPixelBox(), filter); + } + //----------------------------------------------------------------------- + void Image::scale(const PixelBox &src, const PixelBox &scaled, Filter filter) + { + assert(PixelUtil::isAccessible(src.format)); + assert(PixelUtil::isAccessible(scaled.format)); + MemoryDataStreamPtr buf; // For auto-delete + PixelBox temp; + switch (filter) + { + default: + case FILTER_NEAREST: + if(src.format == scaled.format) + { + // No intermediate buffer needed + temp = scaled; + } + else + { + // Allocate temporary buffer of destination size in source format + temp = PixelBox(scaled.getWidth(), scaled.getHeight(), scaled.getDepth(), src.format); + buf.bind(OGRE_NEW MemoryDataStream(temp.getConsecutiveSize())); + temp.data = buf->getPtr(); + } + // super-optimized: no conversion + switch (PixelUtil::getNumElemBytes(src.format)) + { + case 1: NearestResampler<1>::scale(src, temp); break; + case 2: NearestResampler<2>::scale(src, temp); break; + case 3: NearestResampler<3>::scale(src, temp); break; + case 4: NearestResampler<4>::scale(src, temp); break; + case 6: NearestResampler<6>::scale(src, temp); break; + case 8: NearestResampler<8>::scale(src, temp); break; + case 12: NearestResampler<12>::scale(src, temp); break; + case 16: NearestResampler<16>::scale(src, temp); break; + default: + // never reached + assert(false); + } + if(temp.data != scaled.data) + { + // Blit temp buffer + PixelUtil::bulkPixelConversion(temp, scaled); + } + break; + + case FILTER_LINEAR: + case FILTER_BILINEAR: + switch (src.format) + { + case PF_L8: case PF_A8: case PF_BYTE_LA: + case PF_R8G8B8: case PF_B8G8R8: + case PF_R8G8B8A8: case PF_B8G8R8A8: + case PF_A8B8G8R8: case PF_A8R8G8B8: + case PF_X8B8G8R8: case PF_X8R8G8B8: + if(src.format == scaled.format) + { + // No intermediate buffer needed + temp = scaled; + } + else + { + // Allocate temp buffer of destination size in source format + temp = PixelBox(scaled.getWidth(), scaled.getHeight(), scaled.getDepth(), src.format); + buf.bind(OGRE_NEW MemoryDataStream(temp.getConsecutiveSize())); + temp.data = buf->getPtr(); + } + // super-optimized: byte-oriented math, no conversion + switch (PixelUtil::getNumElemBytes(src.format)) + { + case 1: LinearResampler_Byte<1>::scale(src, temp); break; + case 2: LinearResampler_Byte<2>::scale(src, temp); break; + case 3: LinearResampler_Byte<3>::scale(src, temp); break; + case 4: LinearResampler_Byte<4>::scale(src, temp); break; + default: + // never reached + assert(false); + } + if(temp.data != scaled.data) + { + // Blit temp buffer + PixelUtil::bulkPixelConversion(temp, scaled); + } + break; + case PF_FLOAT32_RGB: + case PF_FLOAT32_RGBA: + if (scaled.format == PF_FLOAT32_RGB || scaled.format == PF_FLOAT32_RGBA) + { + // float32 to float32, avoid unpack/repack overhead + LinearResampler_Float32::scale(src, scaled); + break; + } + // else, fall through + default: + // non-optimized: floating-point math, performs conversion but always works + LinearResampler::scale(src, scaled); + } + break; + } + } + + //----------------------------------------------------------------------------- + + ColourValue Image::getColourAt(size_t x, size_t y, size_t z) const + { + ColourValue rval; + PixelUtil::unpackColour(&rval, mFormat, &mBuffer[mPixelSize * (z * mWidth * mHeight + mWidth * y + x)]); + return rval; + } + + //----------------------------------------------------------------------------- void Image::setColourAt(ColourValue const &cv, size_t x, size_t y, size_t z) { @@ -693,44 +693,44 @@ namespace Ogre { PixelUtil::packColour(cv, getFormat(), &((unsigned char *)getData())[pixelSize * (z * getWidth() * getHeight() + y * getWidth() + x)]); } - //----------------------------------------------------------------------------- - - PixelBox Image::getPixelBox(size_t face, size_t mipmap) const - { - // Image data is arranged as: - // face 0, top level (mip 0) - // face 0, mip 1 - // face 0, mip 2 - // face 1, top level (mip 0) - // face 1, mip 1 - // face 1, mip 2 - // etc - if(mipmap > getNumMipmaps()) - OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, - "Mipmap index out of range", - "Image::getPixelBox" ) ; - if(face >= getNumFaces()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Face index out of range", - "Image::getPixelBox"); + //----------------------------------------------------------------------------- + + PixelBox Image::getPixelBox(size_t face, size_t mipmap) const + { + // Image data is arranged as: + // face 0, top level (mip 0) + // face 0, mip 1 + // face 0, mip 2 + // face 1, top level (mip 0) + // face 1, mip 1 + // face 1, mip 2 + // etc + if(mipmap > getNumMipmaps()) + OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, + "Mipmap index out of range", + "Image::getPixelBox" ) ; + if(face >= getNumFaces()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Face index out of range", + "Image::getPixelBox"); // Calculate mipmap offset and size uint8 *offset = const_cast(getData()); - // Base offset is number of full faces + // Base offset is number of full faces uint32 width = getWidth(), height=getHeight(), depth=getDepth(); - size_t numMips = getNumMipmaps(); + size_t numMips = getNumMipmaps(); - // Figure out the offsets - size_t fullFaceSize = 0; - size_t finalFaceSize = 0; - uint32 finalWidth = 0, finalHeight = 0, finalDepth = 0; - for(size_t mip=0; mip <= numMips; ++mip) + // Figure out the offsets + size_t fullFaceSize = 0; + size_t finalFaceSize = 0; + uint32 finalWidth = 0, finalHeight = 0, finalDepth = 0; + for(size_t mip=0; mip <= numMips; ++mip) { - if (mip == mipmap) - { - finalFaceSize = fullFaceSize; - finalWidth = width; - finalHeight = height; - finalDepth = depth; - } + if (mip == mipmap) + { + finalFaceSize = fullFaceSize; + finalWidth = width; + finalHeight = height; + finalDepth = depth; + } fullFaceSize += PixelUtil::getMemorySize(width, height, depth, getFormat()); /// Half size in each dimension @@ -738,13 +738,13 @@ namespace Ogre { if(height!=1) height /= 2; if(depth!=1) depth /= 2; } - // Advance pointer by number of full faces, plus mip offset into - offset += face * fullFaceSize; - offset += finalFaceSize; - // Return subface as pixelbox - PixelBox src(finalWidth, finalHeight, finalDepth, getFormat(), offset); - return src; - } + // Advance pointer by number of full faces, plus mip offset into + offset += face * fullFaceSize; + offset += finalFaceSize; + // Return subface as pixelbox + PixelBox src(finalWidth, finalHeight, finalDepth, getFormat(), offset); + return src; + } //----------------------------------------------------------------------------- size_t Image::calculateSize(size_t mipmaps, size_t faces, uint32 width, uint32 height, uint32 depth, PixelFormat format) @@ -759,133 +759,133 @@ namespace Ogre { } return size; } - //--------------------------------------------------------------------- - Image & Image::loadTwoImagesAsRGBA(const String& rgbFilename, const String& alphaFilename, - const String& groupName, PixelFormat fmt) - { - Image rgb, alpha; - - rgb.load(rgbFilename, groupName); - alpha.load(alphaFilename, groupName); - - return combineTwoImagesAsRGBA(rgb, alpha, fmt); - - } - //--------------------------------------------------------------------- - Image & Image::loadTwoImagesAsRGBA(DataStreamPtr& rgbStream, DataStreamPtr& alphaStream, - PixelFormat fmt, const String& rgbType, const String& alphaType) - { - Image rgb, alpha; - - rgb.load(rgbStream, rgbType); - alpha.load(alphaStream, alphaType); - - return combineTwoImagesAsRGBA(rgb, alpha, fmt); - - } - //--------------------------------------------------------------------- - Image & Image::combineTwoImagesAsRGBA(const Image& rgb, const Image& alpha, PixelFormat fmt) - { - // the images should be the same size, have the same number of mipmaps - if (rgb.getWidth() != alpha.getWidth() || - rgb.getHeight() != alpha.getHeight() || - rgb.getDepth() != alpha.getDepth()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Images must be the same dimensions", "Image::combineTwoImagesAsRGBA"); - } - if (rgb.getNumMipmaps() != alpha.getNumMipmaps() || - rgb.getNumFaces() != alpha.getNumFaces()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Images must have the same number of surfaces (faces & mipmaps)", - "Image::combineTwoImagesAsRGBA"); - } - // Format check - if (PixelUtil::getComponentCount(fmt) != 4) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Target format must have 4 components", - "Image::combineTwoImagesAsRGBA"); - } - if (PixelUtil::isCompressed(fmt) || PixelUtil::isCompressed(rgb.getFormat()) - || PixelUtil::isCompressed(alpha.getFormat())) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Compressed formats are not supported in this method", - "Image::combineTwoImagesAsRGBA"); - } - - freeMemory(); - - mWidth = rgb.getWidth(); - mHeight = rgb.getHeight(); - mDepth = rgb.getDepth(); - mFormat = fmt; - mNumMipmaps = rgb.getNumMipmaps(); - size_t numFaces = rgb.getNumFaces(); - - // Set flags - mFlags = 0; - if (mDepth != 1) - mFlags |= IF_3D_TEXTURE; - if(numFaces == 6) - mFlags |= IF_CUBEMAP; - - mBufSize = calculateSize(mNumMipmaps, numFaces, mWidth, mHeight, mDepth, mFormat); - - mPixelSize = static_cast(PixelUtil::getNumElemBytes( mFormat )); - - mBuffer = static_cast(OGRE_MALLOC(mBufSize, MEMCATEGORY_GENERAL)); - - // make sure we delete - mAutoDelete = true; - - - for (size_t face = 0; face < numFaces; ++face) - { - for (uint8 mip = 0; mip <= mNumMipmaps; ++mip) - { - // convert the RGB first - PixelBox srcRGB = rgb.getPixelBox(face, mip); - PixelBox dst = getPixelBox(face, mip); - PixelUtil::bulkPixelConversion(srcRGB, dst); - - // now selectively add the alpha - PixelBox srcAlpha = alpha.getPixelBox(face, mip); - uchar* psrcAlpha = static_cast(srcAlpha.data); - uchar* pdst = static_cast(dst.data); - for (size_t d = 0; d < mDepth; ++d) - { - for (size_t y = 0; y < mHeight; ++y) - { - for (size_t x = 0; x < mWidth; ++x) - { - ColourValue colRGBA, colA; - // read RGB back from dest to save having another pointer - PixelUtil::unpackColour(&colRGBA, mFormat, pdst); - PixelUtil::unpackColour(&colA, alpha.getFormat(), psrcAlpha); - - // combine RGB from alpha source texture - colRGBA.a = (colA.r + colA.g + colA.b) / 3.0f; - - PixelUtil::packColour(colRGBA, mFormat, pdst); - - psrcAlpha += PixelUtil::getNumElemBytes(alpha.getFormat()); - pdst += PixelUtil::getNumElemBytes(mFormat); - - } - } - } - - - } - } - - return *this; - - } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + Image & Image::loadTwoImagesAsRGBA(const String& rgbFilename, const String& alphaFilename, + const String& groupName, PixelFormat fmt) + { + Image rgb, alpha; + + rgb.load(rgbFilename, groupName); + alpha.load(alphaFilename, groupName); + + return combineTwoImagesAsRGBA(rgb, alpha, fmt); + + } + //--------------------------------------------------------------------- + Image & Image::loadTwoImagesAsRGBA(DataStreamPtr& rgbStream, DataStreamPtr& alphaStream, + PixelFormat fmt, const String& rgbType, const String& alphaType) + { + Image rgb, alpha; + + rgb.load(rgbStream, rgbType); + alpha.load(alphaStream, alphaType); + + return combineTwoImagesAsRGBA(rgb, alpha, fmt); + + } + //--------------------------------------------------------------------- + Image & Image::combineTwoImagesAsRGBA(const Image& rgb, const Image& alpha, PixelFormat fmt) + { + // the images should be the same size, have the same number of mipmaps + if (rgb.getWidth() != alpha.getWidth() || + rgb.getHeight() != alpha.getHeight() || + rgb.getDepth() != alpha.getDepth()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Images must be the same dimensions", "Image::combineTwoImagesAsRGBA"); + } + if (rgb.getNumMipmaps() != alpha.getNumMipmaps() || + rgb.getNumFaces() != alpha.getNumFaces()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Images must have the same number of surfaces (faces & mipmaps)", + "Image::combineTwoImagesAsRGBA"); + } + // Format check + if (PixelUtil::getComponentCount(fmt) != 4) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Target format must have 4 components", + "Image::combineTwoImagesAsRGBA"); + } + if (PixelUtil::isCompressed(fmt) || PixelUtil::isCompressed(rgb.getFormat()) + || PixelUtil::isCompressed(alpha.getFormat())) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Compressed formats are not supported in this method", + "Image::combineTwoImagesAsRGBA"); + } + + freeMemory(); + + mWidth = rgb.getWidth(); + mHeight = rgb.getHeight(); + mDepth = rgb.getDepth(); + mFormat = fmt; + mNumMipmaps = rgb.getNumMipmaps(); + size_t numFaces = rgb.getNumFaces(); + + // Set flags + mFlags = 0; + if (mDepth != 1) + mFlags |= IF_3D_TEXTURE; + if(numFaces == 6) + mFlags |= IF_CUBEMAP; + + mBufSize = calculateSize(mNumMipmaps, numFaces, mWidth, mHeight, mDepth, mFormat); + + mPixelSize = static_cast(PixelUtil::getNumElemBytes( mFormat )); + + mBuffer = static_cast(OGRE_MALLOC(mBufSize, MEMCATEGORY_GENERAL)); + + // make sure we delete + mAutoDelete = true; + + + for (size_t face = 0; face < numFaces; ++face) + { + for (uint8 mip = 0; mip <= mNumMipmaps; ++mip) + { + // convert the RGB first + PixelBox srcRGB = rgb.getPixelBox(face, mip); + PixelBox dst = getPixelBox(face, mip); + PixelUtil::bulkPixelConversion(srcRGB, dst); + + // now selectively add the alpha + PixelBox srcAlpha = alpha.getPixelBox(face, mip); + uchar* psrcAlpha = static_cast(srcAlpha.data); + uchar* pdst = static_cast(dst.data); + for (size_t d = 0; d < mDepth; ++d) + { + for (size_t y = 0; y < mHeight; ++y) + { + for (size_t x = 0; x < mWidth; ++x) + { + ColourValue colRGBA, colA; + // read RGB back from dest to save having another pointer + PixelUtil::unpackColour(&colRGBA, mFormat, pdst); + PixelUtil::unpackColour(&colA, alpha.getFormat(), psrcAlpha); + + // combine RGB from alpha source texture + colRGBA.a = (colA.r + colA.g + colA.b) / 3.0f; + + PixelUtil::packColour(colRGBA, mFormat, pdst); + + psrcAlpha += PixelUtil::getNumElemBytes(alpha.getFormat()); + pdst += PixelUtil::getNumElemBytes(mFormat); + + } + } + } + + + } + } + + return *this; + + } + //--------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreImageResampler.h b/OgreMain/src/OgreImageResampler.h index e4f82dff919..086c9cd70a4 100644 --- a/OgreMain/src/OgreImageResampler.h +++ b/OgreMain/src/OgreImageResampler.h @@ -33,12 +33,12 @@ THE SOFTWARE. // this file is inlined into OgreImage.cpp! // do not include anywhere else. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Image - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Image + * @{ + */ // variable name hints: // sx_48 = 16/48-bit fixed-point x-position in source @@ -52,225 +52,225 @@ namespace Ogre { // templated on bytes-per-pixel to allow compiler optimizations, such // as simplifying memcpy() and replacing multiplies with bitshifts template struct NearestResampler { - static void scale(const PixelBox& src, const PixelBox& dst) { - // assert(src.format == dst.format); - - // srcdata stays at beginning, pdst is a moving pointer - uchar* srcdata = (uchar*)src.getTopLeftFrontPixelPtr(); - uchar* pdst = (uchar*)dst.getTopLeftFrontPixelPtr(); - - // sx_48,sy_48,sz_48 represent current position in source - // using 16/48-bit fixed precision, incremented by steps - uint64 stepx = ((uint64)src.getWidth() << 48) / dst.getWidth(); - uint64 stepy = ((uint64)src.getHeight() << 48) / dst.getHeight(); - uint64 stepz = ((uint64)src.getDepth() << 48) / dst.getDepth(); - - // note: ((stepz>>1) - 1) is an extra half-step increment to adjust - // for the center of the destination pixel, not the top-left corner - uint64 sz_48 = (stepz >> 1) - 1; - for (size_t z = dst.front; z < dst.back; z++, sz_48 += stepz) { - size_t srczoff = (size_t)(sz_48 >> 48) * src.slicePitch; - - uint64 sy_48 = (stepy >> 1) - 1; - for (size_t y = dst.top; y < dst.bottom; y++, sy_48 += stepy) { - size_t srcyoff = (size_t)(sy_48 >> 48) * src.rowPitch; - - uint64 sx_48 = (stepx >> 1) - 1; - for (size_t x = dst.left; x < dst.right; x++, sx_48 += stepx) { - uchar* psrc = srcdata + - elemsize*((size_t)(sx_48 >> 48) + srcyoff + srczoff); + static void scale(const PixelBox& src, const PixelBox& dst) { + // assert(src.format == dst.format); + + // srcdata stays at beginning, pdst is a moving pointer + uchar* srcdata = (uchar*)src.getTopLeftFrontPixelPtr(); + uchar* pdst = (uchar*)dst.getTopLeftFrontPixelPtr(); + + // sx_48,sy_48,sz_48 represent current position in source + // using 16/48-bit fixed precision, incremented by steps + uint64 stepx = ((uint64)src.getWidth() << 48) / dst.getWidth(); + uint64 stepy = ((uint64)src.getHeight() << 48) / dst.getHeight(); + uint64 stepz = ((uint64)src.getDepth() << 48) / dst.getDepth(); + + // note: ((stepz>>1) - 1) is an extra half-step increment to adjust + // for the center of the destination pixel, not the top-left corner + uint64 sz_48 = (stepz >> 1) - 1; + for (size_t z = dst.front; z < dst.back; z++, sz_48 += stepz) { + size_t srczoff = (size_t)(sz_48 >> 48) * src.slicePitch; + + uint64 sy_48 = (stepy >> 1) - 1; + for (size_t y = dst.top; y < dst.bottom; y++, sy_48 += stepy) { + size_t srcyoff = (size_t)(sy_48 >> 48) * src.rowPitch; + + uint64 sx_48 = (stepx >> 1) - 1; + for (size_t x = dst.left; x < dst.right; x++, sx_48 += stepx) { + uchar* psrc = srcdata + + elemsize*((size_t)(sx_48 >> 48) + srcyoff + srczoff); memcpy(pdst, psrc, elemsize); - pdst += elemsize; - } - pdst += elemsize*dst.getRowSkip(); - } - pdst += elemsize*dst.getSliceSkip(); - } - } + pdst += elemsize; + } + pdst += elemsize*dst.getRowSkip(); + } + pdst += elemsize*dst.getSliceSkip(); + } + } }; // default floating-point linear resampler, does format conversion struct LinearResampler { - static void scale(const PixelBox& src, const PixelBox& dst) { - size_t srcelemsize = PixelUtil::getNumElemBytes(src.format); - size_t dstelemsize = PixelUtil::getNumElemBytes(dst.format); - - // srcdata stays at beginning, pdst is a moving pointer - uchar* srcdata = (uchar*)src.getTopLeftFrontPixelPtr(); - uchar* pdst = (uchar*)dst.getTopLeftFrontPixelPtr(); - - // sx_48,sy_48,sz_48 represent current position in source - // using 16/48-bit fixed precision, incremented by steps - uint64 stepx = ((uint64)src.getWidth() << 48) / dst.getWidth(); - uint64 stepy = ((uint64)src.getHeight() << 48) / dst.getHeight(); - uint64 stepz = ((uint64)src.getDepth() << 48) / dst.getDepth(); - - // note: ((stepz>>1) - 1) is an extra half-step increment to adjust - // for the center of the destination pixel, not the top-left corner - uint64 sz_48 = (stepz >> 1) - 1; - for (size_t z = dst.front; z < dst.back; z++, sz_48+=stepz) { + static void scale(const PixelBox& src, const PixelBox& dst) { + size_t srcelemsize = PixelUtil::getNumElemBytes(src.format); + size_t dstelemsize = PixelUtil::getNumElemBytes(dst.format); + + // srcdata stays at beginning, pdst is a moving pointer + uchar* srcdata = (uchar*)src.getTopLeftFrontPixelPtr(); + uchar* pdst = (uchar*)dst.getTopLeftFrontPixelPtr(); + + // sx_48,sy_48,sz_48 represent current position in source + // using 16/48-bit fixed precision, incremented by steps + uint64 stepx = ((uint64)src.getWidth() << 48) / dst.getWidth(); + uint64 stepy = ((uint64)src.getHeight() << 48) / dst.getHeight(); + uint64 stepz = ((uint64)src.getDepth() << 48) / dst.getDepth(); + + // note: ((stepz>>1) - 1) is an extra half-step increment to adjust + // for the center of the destination pixel, not the top-left corner + uint64 sz_48 = (stepz >> 1) - 1; + for (size_t z = dst.front; z < dst.back; z++, sz_48+=stepz) { // temp is 16/16 bit fixed precision, used to adjust a source // coordinate (x, y, or z) backwards by half a pixel so that the // integer bits represent the first sample (eg, sx1) and the // fractional bits are the blend weight of the second sample unsigned int temp = static_cast(sz_48 >> 32); - temp = (temp > 0x8000)? temp - 0x8000 : 0; - uint32 sz1 = temp >> 16; // src z, sample #1 - uint32 sz2 = std::min(sz1+1,src.getDepth()-1);// src z, sample #2 - float szf = (temp & 0xFFFF) / 65536.f; // weight of sample #2 - - uint64 sy_48 = (stepy >> 1) - 1; - for (size_t y = dst.top; y < dst.bottom; y++, sy_48+=stepy) { - temp = static_cast(sy_48 >> 32); - temp = (temp > 0x8000)? temp - 0x8000 : 0; - uint32 sy1 = temp >> 16; // src y #1 - uint32 sy2 = std::min(sy1+1,src.getHeight()-1);// src y #2 - float syf = (temp & 0xFFFF) / 65536.f; // weight of #2 - - uint64 sx_48 = (stepx >> 1) - 1; - for (size_t x = dst.left; x < dst.right; x++, sx_48+=stepx) { - temp = static_cast(sx_48 >> 32); - temp = (temp > 0x8000)? temp - 0x8000 : 0; - uint32 sx1 = temp >> 16; // src x #1 - uint32 sx2 = std::min(sx1+1,src.getWidth()-1);// src x #2 - float sxf = (temp & 0xFFFF) / 65536.f; // weight of #2 - - ColourValue x1y1z1, x2y1z1, x1y2z1, x2y2z1; - ColourValue x1y1z2, x2y1z2, x1y2z2, x2y2z2; + temp = (temp > 0x8000)? temp - 0x8000 : 0; + uint32 sz1 = temp >> 16; // src z, sample #1 + uint32 sz2 = std::min(sz1+1,src.getDepth()-1);// src z, sample #2 + float szf = (temp & 0xFFFF) / 65536.f; // weight of sample #2 + + uint64 sy_48 = (stepy >> 1) - 1; + for (size_t y = dst.top; y < dst.bottom; y++, sy_48+=stepy) { + temp = static_cast(sy_48 >> 32); + temp = (temp > 0x8000)? temp - 0x8000 : 0; + uint32 sy1 = temp >> 16; // src y #1 + uint32 sy2 = std::min(sy1+1,src.getHeight()-1);// src y #2 + float syf = (temp & 0xFFFF) / 65536.f; // weight of #2 + + uint64 sx_48 = (stepx >> 1) - 1; + for (size_t x = dst.left; x < dst.right; x++, sx_48+=stepx) { + temp = static_cast(sx_48 >> 32); + temp = (temp > 0x8000)? temp - 0x8000 : 0; + uint32 sx1 = temp >> 16; // src x #1 + uint32 sx2 = std::min(sx1+1,src.getWidth()-1);// src x #2 + float sxf = (temp & 0xFFFF) / 65536.f; // weight of #2 + + ColourValue x1y1z1, x2y1z1, x1y2z1, x2y2z1; + ColourValue x1y1z2, x2y1z2, x1y2z2, x2y2z2; #define UNPACK(dst,x,y,z) PixelUtil::unpackColour(&dst, src.format, \ - srcdata + srcelemsize*((x)+(y)*src.rowPitch+(z)*src.slicePitch)) + srcdata + srcelemsize*((x)+(y)*src.rowPitch+(z)*src.slicePitch)) - UNPACK(x1y1z1,sx1,sy1,sz1); UNPACK(x2y1z1,sx2,sy1,sz1); - UNPACK(x1y2z1,sx1,sy2,sz1); UNPACK(x2y2z1,sx2,sy2,sz1); - UNPACK(x1y1z2,sx1,sy1,sz2); UNPACK(x2y1z2,sx2,sy1,sz2); - UNPACK(x1y2z2,sx1,sy2,sz2); UNPACK(x2y2z2,sx2,sy2,sz2); + UNPACK(x1y1z1,sx1,sy1,sz1); UNPACK(x2y1z1,sx2,sy1,sz1); + UNPACK(x1y2z1,sx1,sy2,sz1); UNPACK(x2y2z1,sx2,sy2,sz1); + UNPACK(x1y1z2,sx1,sy1,sz2); UNPACK(x2y1z2,sx2,sy1,sz2); + UNPACK(x1y2z2,sx1,sy2,sz2); UNPACK(x2y2z2,sx2,sy2,sz2); #undef UNPACK - ColourValue accum = - x1y1z1 * ((1.0f - sxf)*(1.0f - syf)*(1.0f - szf)) + - x2y1z1 * ( sxf *(1.0f - syf)*(1.0f - szf)) + - x1y2z1 * ((1.0f - sxf)* syf *(1.0f - szf)) + - x2y2z1 * ( sxf * syf *(1.0f - szf)) + - x1y1z2 * ((1.0f - sxf)*(1.0f - syf)* szf ) + - x2y1z2 * ( sxf *(1.0f - syf)* szf ) + - x1y2z2 * ((1.0f - sxf)* syf * szf ) + - x2y2z2 * ( sxf * syf * szf ); - - PixelUtil::packColour(accum, dst.format, pdst); - - pdst += dstelemsize; - } - pdst += dstelemsize*dst.getRowSkip(); - } - pdst += dstelemsize*dst.getSliceSkip(); - } - } + ColourValue accum = + x1y1z1 * ((1.0f - sxf)*(1.0f - syf)*(1.0f - szf)) + + x2y1z1 * ( sxf *(1.0f - syf)*(1.0f - szf)) + + x1y2z1 * ((1.0f - sxf)* syf *(1.0f - szf)) + + x2y2z1 * ( sxf * syf *(1.0f - szf)) + + x1y1z2 * ((1.0f - sxf)*(1.0f - syf)* szf ) + + x2y1z2 * ( sxf *(1.0f - syf)* szf ) + + x1y2z2 * ((1.0f - sxf)* syf * szf ) + + x2y2z2 * ( sxf * syf * szf ); + + PixelUtil::packColour(accum, dst.format, pdst); + + pdst += dstelemsize; + } + pdst += dstelemsize*dst.getRowSkip(); + } + pdst += dstelemsize*dst.getSliceSkip(); + } + } }; // float32 linear resampler, converts FLOAT32_RGB/FLOAT32_RGBA only. // avoids overhead of pixel unpack/repack function calls struct LinearResampler_Float32 { - static void scale(const PixelBox& src, const PixelBox& dst) { - size_t srcchannels = PixelUtil::getNumElemBytes(src.format) / sizeof(float); - size_t dstchannels = PixelUtil::getNumElemBytes(dst.format) / sizeof(float); - // assert(srcchannels == 3 || srcchannels == 4); - // assert(dstchannels == 3 || dstchannels == 4); - - // srcdata stays at beginning, pdst is a moving pointer - float* srcdata = (float*)src.getTopLeftFrontPixelPtr(); - float* pdst = (float*)dst.getTopLeftFrontPixelPtr(); - - // sx_48,sy_48,sz_48 represent current position in source - // using 16/48-bit fixed precision, incremented by steps - uint64 stepx = ((uint64)src.getWidth() << 48) / dst.getWidth(); - uint64 stepy = ((uint64)src.getHeight() << 48) / dst.getHeight(); - uint64 stepz = ((uint64)src.getDepth() << 48) / dst.getDepth(); - - // note: ((stepz>>1) - 1) is an extra half-step increment to adjust - // for the center of the destination pixel, not the top-left corner - uint64 sz_48 = (stepz >> 1) - 1; - for (size_t z = dst.front; z < dst.back; z++, sz_48+=stepz) { + static void scale(const PixelBox& src, const PixelBox& dst) { + size_t srcchannels = PixelUtil::getNumElemBytes(src.format) / sizeof(float); + size_t dstchannels = PixelUtil::getNumElemBytes(dst.format) / sizeof(float); + // assert(srcchannels == 3 || srcchannels == 4); + // assert(dstchannels == 3 || dstchannels == 4); + + // srcdata stays at beginning, pdst is a moving pointer + float* srcdata = (float*)src.getTopLeftFrontPixelPtr(); + float* pdst = (float*)dst.getTopLeftFrontPixelPtr(); + + // sx_48,sy_48,sz_48 represent current position in source + // using 16/48-bit fixed precision, incremented by steps + uint64 stepx = ((uint64)src.getWidth() << 48) / dst.getWidth(); + uint64 stepy = ((uint64)src.getHeight() << 48) / dst.getHeight(); + uint64 stepz = ((uint64)src.getDepth() << 48) / dst.getDepth(); + + // note: ((stepz>>1) - 1) is an extra half-step increment to adjust + // for the center of the destination pixel, not the top-left corner + uint64 sz_48 = (stepz >> 1) - 1; + for (size_t z = dst.front; z < dst.back; z++, sz_48+=stepz) { // temp is 16/16 bit fixed precision, used to adjust a source // coordinate (x, y, or z) backwards by half a pixel so that the // integer bits represent the first sample (eg, sx1) and the // fractional bits are the blend weight of the second sample unsigned int temp = static_cast(sz_48 >> 32); - temp = (temp > 0x8000)? temp - 0x8000 : 0; - uint32 sz1 = temp >> 16; // src z, sample #1 - uint32 sz2 = std::min(sz1+1,src.getDepth()-1);// src z, sample #2 - float szf = (temp & 0xFFFF) / 65536.f; // weight of sample #2 - - uint64 sy_48 = (stepy >> 1) - 1; - for (size_t y = dst.top; y < dst.bottom; y++, sy_48+=stepy) { - temp = static_cast(sy_48 >> 32); - temp = (temp > 0x8000)? temp - 0x8000 : 0; - uint32 sy1 = temp >> 16; // src y #1 - uint32 sy2 = std::min(sy1+1,src.getHeight()-1);// src y #2 - float syf = (temp & 0xFFFF) / 65536.f; // weight of #2 - - uint64 sx_48 = (stepx >> 1) - 1; - for (size_t x = dst.left; x < dst.right; x++, sx_48+=stepx) { - temp = static_cast(sx_48 >> 32); - temp = (temp > 0x8000)? temp - 0x8000 : 0; - uint32 sx1 = temp >> 16; // src x #1 - uint32 sx2 = std::min(sx1+1,src.getWidth()-1);// src x #2 - float sxf = (temp & 0xFFFF) / 65536.f; // weight of #2 - - // process R,G,B,A simultaneously for cache coherence? - float accum[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + temp = (temp > 0x8000)? temp - 0x8000 : 0; + uint32 sz1 = temp >> 16; // src z, sample #1 + uint32 sz2 = std::min(sz1+1,src.getDepth()-1);// src z, sample #2 + float szf = (temp & 0xFFFF) / 65536.f; // weight of sample #2 + + uint64 sy_48 = (stepy >> 1) - 1; + for (size_t y = dst.top; y < dst.bottom; y++, sy_48+=stepy) { + temp = static_cast(sy_48 >> 32); + temp = (temp > 0x8000)? temp - 0x8000 : 0; + uint32 sy1 = temp >> 16; // src y #1 + uint32 sy2 = std::min(sy1+1,src.getHeight()-1);// src y #2 + float syf = (temp & 0xFFFF) / 65536.f; // weight of #2 + + uint64 sx_48 = (stepx >> 1) - 1; + for (size_t x = dst.left; x < dst.right; x++, sx_48+=stepx) { + temp = static_cast(sx_48 >> 32); + temp = (temp > 0x8000)? temp - 0x8000 : 0; + uint32 sx1 = temp >> 16; // src x #1 + uint32 sx2 = std::min(sx1+1,src.getWidth()-1);// src x #2 + float sxf = (temp & 0xFFFF) / 65536.f; // weight of #2 + + // process R,G,B,A simultaneously for cache coherence? + float accum[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; #define ACCUM3(x,y,z,factor) \ - { float f = factor; \ - size_t off = (x+y*src.rowPitch+z*src.slicePitch)*srcchannels; \ + { float f = factor; \ + size_t off = (x+y*src.rowPitch+z*src.slicePitch)*srcchannels; \ accum[0]+=srcdata[off+0]*f; accum[1]+=srcdata[off+1]*f; \ - accum[2]+=srcdata[off+2]*f; } + accum[2]+=srcdata[off+2]*f; } #define ACCUM4(x,y,z,factor) \ - { float f = factor; \ - size_t off = (x+y*src.rowPitch+z*src.slicePitch)*srcchannels; \ + { float f = factor; \ + size_t off = (x+y*src.rowPitch+z*src.slicePitch)*srcchannels; \ accum[0]+=srcdata[off+0]*f; accum[1]+=srcdata[off+1]*f; \ - accum[2]+=srcdata[off+2]*f; accum[3]+=srcdata[off+3]*f; } - - if (srcchannels == 3 || dstchannels == 3) { - // RGB, no alpha - ACCUM3(sx1,sy1,sz1,(1.0f-sxf)*(1.0f-syf)*(1.0f-szf)); - ACCUM3(sx2,sy1,sz1, sxf *(1.0f-syf)*(1.0f-szf)); - ACCUM3(sx1,sy2,sz1,(1.0f-sxf)* syf *(1.0f-szf)); - ACCUM3(sx2,sy2,sz1, sxf * syf *(1.0f-szf)); - ACCUM3(sx1,sy1,sz2,(1.0f-sxf)*(1.0f-syf)* szf ); - ACCUM3(sx2,sy1,sz2, sxf *(1.0f-syf)* szf ); - ACCUM3(sx1,sy2,sz2,(1.0f-sxf)* syf * szf ); - ACCUM3(sx2,sy2,sz2, sxf * syf * szf ); - accum[3] = 1.0f; - } else { - // RGBA - ACCUM4(sx1,sy1,sz1,(1.0f-sxf)*(1.0f-syf)*(1.0f-szf)); - ACCUM4(sx2,sy1,sz1, sxf *(1.0f-syf)*(1.0f-szf)); - ACCUM4(sx1,sy2,sz1,(1.0f-sxf)* syf *(1.0f-szf)); - ACCUM4(sx2,sy2,sz1, sxf * syf *(1.0f-szf)); - ACCUM4(sx1,sy1,sz2,(1.0f-sxf)*(1.0f-syf)* szf ); - ACCUM4(sx2,sy1,sz2, sxf *(1.0f-syf)* szf ); - ACCUM4(sx1,sy2,sz2,(1.0f-sxf)* syf * szf ); - ACCUM4(sx2,sy2,sz2, sxf * syf * szf ); - } - - memcpy(pdst, accum, sizeof(float)*dstchannels); + accum[2]+=srcdata[off+2]*f; accum[3]+=srcdata[off+3]*f; } + + if (srcchannels == 3 || dstchannels == 3) { + // RGB, no alpha + ACCUM3(sx1,sy1,sz1,(1.0f-sxf)*(1.0f-syf)*(1.0f-szf)); + ACCUM3(sx2,sy1,sz1, sxf *(1.0f-syf)*(1.0f-szf)); + ACCUM3(sx1,sy2,sz1,(1.0f-sxf)* syf *(1.0f-szf)); + ACCUM3(sx2,sy2,sz1, sxf * syf *(1.0f-szf)); + ACCUM3(sx1,sy1,sz2,(1.0f-sxf)*(1.0f-syf)* szf ); + ACCUM3(sx2,sy1,sz2, sxf *(1.0f-syf)* szf ); + ACCUM3(sx1,sy2,sz2,(1.0f-sxf)* syf * szf ); + ACCUM3(sx2,sy2,sz2, sxf * syf * szf ); + accum[3] = 1.0f; + } else { + // RGBA + ACCUM4(sx1,sy1,sz1,(1.0f-sxf)*(1.0f-syf)*(1.0f-szf)); + ACCUM4(sx2,sy1,sz1, sxf *(1.0f-syf)*(1.0f-szf)); + ACCUM4(sx1,sy2,sz1,(1.0f-sxf)* syf *(1.0f-szf)); + ACCUM4(sx2,sy2,sz1, sxf * syf *(1.0f-szf)); + ACCUM4(sx1,sy1,sz2,(1.0f-sxf)*(1.0f-syf)* szf ); + ACCUM4(sx2,sy1,sz2, sxf *(1.0f-syf)* szf ); + ACCUM4(sx1,sy2,sz2,(1.0f-sxf)* syf * szf ); + ACCUM4(sx2,sy2,sz2, sxf * syf * szf ); + } + + memcpy(pdst, accum, sizeof(float)*dstchannels); #undef ACCUM3 #undef ACCUM4 - pdst += dstchannels; - } - pdst += dstchannels*dst.getRowSkip(); - } - pdst += dstchannels*dst.getSliceSkip(); - } - } + pdst += dstchannels; + } + pdst += dstchannels*dst.getRowSkip(); + } + pdst += dstchannels*dst.getSliceSkip(); + } + } }; @@ -281,61 +281,61 @@ struct LinearResampler_Float32 { // templated on bytes-per-pixel to allow compiler optimizations, such // as unrolling loops and replacing multiplies with bitshifts template struct LinearResampler_Byte { - static void scale(const PixelBox& src, const PixelBox& dst) { - // assert(src.format == dst.format); - - // only optimized for 2D - if (src.getDepth() > 1 || dst.getDepth() > 1) { - LinearResampler::scale(src, dst); - return; - } - - // srcdata stays at beginning of slice, pdst is a moving pointer - uchar* srcdata = (uchar*)src.getTopLeftFrontPixelPtr(); - uchar* pdst = (uchar*)dst.getTopLeftFrontPixelPtr(); - - // sx_48,sy_48 represent current position in source - // using 16/48-bit fixed precision, incremented by steps - uint64 stepx = ((uint64)src.getWidth() << 48) / dst.getWidth(); - uint64 stepy = ((uint64)src.getHeight() << 48) / dst.getHeight(); - - uint64 sy_48 = (stepy >> 1) - 1; - for (size_t y = dst.top; y < dst.bottom; y++, sy_48+=stepy) { + static void scale(const PixelBox& src, const PixelBox& dst) { + // assert(src.format == dst.format); + + // only optimized for 2D + if (src.getDepth() > 1 || dst.getDepth() > 1) { + LinearResampler::scale(src, dst); + return; + } + + // srcdata stays at beginning of slice, pdst is a moving pointer + uchar* srcdata = (uchar*)src.getTopLeftFrontPixelPtr(); + uchar* pdst = (uchar*)dst.getTopLeftFrontPixelPtr(); + + // sx_48,sy_48 represent current position in source + // using 16/48-bit fixed precision, incremented by steps + uint64 stepx = ((uint64)src.getWidth() << 48) / dst.getWidth(); + uint64 stepy = ((uint64)src.getHeight() << 48) / dst.getHeight(); + + uint64 sy_48 = (stepy >> 1) - 1; + for (size_t y = dst.top; y < dst.bottom; y++, sy_48+=stepy) { // bottom 28 bits of temp are 16/12 bit fixed precision, used to // adjust a source coordinate backwards by half a pixel so that the // integer bits represent the first sample (eg, sx1) and the // fractional bits are the blend weight of the second sample unsigned int temp = static_cast(sy_48 >> 36); - temp = (temp > 0x800)? temp - 0x800: 0; - unsigned int syf = temp & 0xFFF; - uint32 sy1 = temp >> 12; - uint32 sy2 = std::min(sy1+1, src.bottom-src.top-1); - size_t syoff1 = sy1 * src.rowPitch; - size_t syoff2 = sy2 * src.rowPitch; - - uint64 sx_48 = (stepx >> 1) - 1; - for (size_t x = dst.left; x < dst.right; x++, sx_48+=stepx) { - temp = static_cast(sx_48 >> 36); - temp = (temp > 0x800)? temp - 0x800 : 0; - unsigned int sxf = temp & 0xFFF; - uint32 sx1 = temp >> 12; - uint32 sx2 = std::min(sx1+1, src.right-src.left-1); - - unsigned int sxfsyf = sxf*syf; - for (unsigned int k = 0; k < channels; k++) { - unsigned int accum = - srcdata[(sx1 + syoff1)*channels+k]*(0x1000000-(sxf<<12)-(syf<<12)+sxfsyf) + - srcdata[(sx2 + syoff1)*channels+k]*((sxf<<12)-sxfsyf) + - srcdata[(sx1 + syoff2)*channels+k]*((syf<<12)-sxfsyf) + - srcdata[(sx2 + syoff2)*channels+k]*sxfsyf; - // accum is computed using 8/24-bit fixed-point math - // (maximum is 0xFF000000; rounding will not cause overflow) - *pdst++ = static_cast((accum + 0x800000) >> 24); - } - } - pdst += channels*dst.getRowSkip(); - } - } + temp = (temp > 0x800)? temp - 0x800: 0; + unsigned int syf = temp & 0xFFF; + uint32 sy1 = temp >> 12; + uint32 sy2 = std::min(sy1+1, src.bottom-src.top-1); + size_t syoff1 = sy1 * src.rowPitch; + size_t syoff2 = sy2 * src.rowPitch; + + uint64 sx_48 = (stepx >> 1) - 1; + for (size_t x = dst.left; x < dst.right; x++, sx_48+=stepx) { + temp = static_cast(sx_48 >> 36); + temp = (temp > 0x800)? temp - 0x800 : 0; + unsigned int sxf = temp & 0xFFF; + uint32 sx1 = temp >> 12; + uint32 sx2 = std::min(sx1+1, src.right-src.left-1); + + unsigned int sxfsyf = sxf*syf; + for (unsigned int k = 0; k < channels; k++) { + unsigned int accum = + srcdata[(sx1 + syoff1)*channels+k]*(0x1000000-(sxf<<12)-(syf<<12)+sxfsyf) + + srcdata[(sx2 + syoff1)*channels+k]*((sxf<<12)-sxfsyf) + + srcdata[(sx1 + syoff2)*channels+k]*((syf<<12)-sxfsyf) + + srcdata[(sx2 + syoff2)*channels+k]*sxfsyf; + // accum is computed using 8/24-bit fixed-point math + // (maximum is 0xFF000000; rounding will not cause overflow) + *pdst++ = static_cast((accum + 0x800000) >> 24); + } + } + pdst += channels*dst.getRowSkip(); + } + } }; /** @} */ /** @} */ diff --git a/OgreMain/src/OgreInstanceBatch.cpp b/OgreMain/src/OgreInstanceBatch.cpp index 290fa769783..0951dee3a4f 100644 --- a/OgreMain/src/OgreInstanceBatch.cpp +++ b/OgreMain/src/OgreInstanceBatch.cpp @@ -37,463 +37,463 @@ THE SOFTWARE. namespace Ogre { - InstanceBatch::InstanceBatch( InstanceManager *creator, MeshPtr &meshReference, - const MaterialPtr &material, size_t instancesPerBatch, - const Mesh::IndexMap *indexToBoneMap, const String &batchName ) : - Renderable(), + InstanceBatch::InstanceBatch( InstanceManager *creator, MeshPtr &meshReference, + const MaterialPtr &material, size_t instancesPerBatch, + const Mesh::IndexMap *indexToBoneMap, const String &batchName ) : + Renderable(), MovableObject(), - mInstancesPerBatch( instancesPerBatch ), - mCreator( creator ), - mMaterial( material ), - mMeshReference( meshReference ), - mIndexToBoneMap( indexToBoneMap ), - mBoundingRadius( 0 ), - mBoundsDirty( false ), - mBoundsUpdated( false ), - mCurrentCamera( 0 ), - mMaterialLodIndex( 0 ), + mInstancesPerBatch( instancesPerBatch ), + mCreator( creator ), + mMaterial( material ), + mMeshReference( meshReference ), + mIndexToBoneMap( indexToBoneMap ), + mBoundingRadius( 0 ), + mBoundsDirty( false ), + mBoundsUpdated( false ), + mCurrentCamera( 0 ), + mMaterialLodIndex( 0 ), mDirtyAnimation(true), - mTechnSupportsSkeletal( true ), - mCachedCamera( 0 ), - mTransformSharingDirty(true), - mRemoveOwnVertexData(false), - mRemoveOwnIndexData(false) - { - assert( mInstancesPerBatch ); - - //Force batch visibility to be always visible. The instanced entities - //have individual visibility flags. If none matches the scene's current, - //then this batch won't rendered. - mVisibilityFlags = std::numeric_limits::max(); - - if( indexToBoneMap ) - { - assert( !(meshReference->hasSkeleton() && indexToBoneMap->empty()) ); - } - - mFullBoundingBox.setExtents( -Vector3::ZERO, Vector3::ZERO ); - - mName = batchName; - - mCustomParams.resize( mCreator->getNumCustomParams() * mInstancesPerBatch, Ogre::Vector4::ZERO ); - } - - InstanceBatch::~InstanceBatch() - { - deleteAllInstancedEntities(); - - //Remove the parent scene node automatically - SceneNode *sceneNode = getParentSceneNode(); - if( sceneNode ) - { - sceneNode->detachAllObjects(); - sceneNode->getParentSceneNode()->removeAndDestroyChild( sceneNode->getName() ); - } - - if( mRemoveOwnVertexData ) - OGRE_DELETE mRenderOperation.vertexData; - if( mRemoveOwnIndexData ) - OGRE_DELETE mRenderOperation.indexData; - - } - - void InstanceBatch::_setInstancesPerBatch( size_t instancesPerBatch ) - { - if( !mInstancedEntities.empty() ) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Instances per batch can only be changed before" - " building the batch.", "InstanceBatch::_setInstancesPerBatch"); - } - - mInstancesPerBatch = instancesPerBatch; - } - //----------------------------------------------------------------------- - bool InstanceBatch::checkSubMeshCompatibility( const SubMesh* baseSubMesh ) - { - if( baseSubMesh->operationType != RenderOperation::OT_TRIANGLE_LIST ) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Only meshes with OT_TRIANGLE_LIST are supported", - "InstanceBatch::checkSubMeshCompatibility"); - } - - if( !mCustomParams.empty() && mCreator->getInstancingTechnique() != InstanceManager::HWInstancingBasic ) - { - //Implementing this for ShaderBased is impossible. All other variants can be. - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Custom parameters not supported for this " - "technique. Do you dare implementing it?" - "See InstanceManager::setNumCustomParams " - "documentation.", - "InstanceBatch::checkSubMeshCompatibility"); - } - - return true; - } - //----------------------------------------------------------------------- - void InstanceBatch::_updateBounds(void) - { - mFullBoundingBox.setNull(); - - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - InstancedEntityVec::const_iterator end = mInstancedEntities.end(); - - Real maxScale = 0; - while( itor != end ) - { - InstancedEntity* ent = (*itor); - //Only increase the bounding box for those objects we know are in the scene - if( ent->isInScene() ) - { - maxScale = std::max(maxScale, ent->getMaxScaleCoef()); - mFullBoundingBox.merge( ent->_getDerivedPosition() ); - } - - ++itor; - } - - Real addToBound = maxScale * _getMeshReference()->getBoundingSphereRadius(); - mFullBoundingBox.setMaximum(mFullBoundingBox.getMaximum() + addToBound); - mFullBoundingBox.setMinimum(mFullBoundingBox.getMinimum() - addToBound); - - - mBoundingRadius = Math::boundingRadiusFromAABB( mFullBoundingBox ); - - //Tell the SceneManager our bounds have changed - getParentSceneNode()->needUpdate(true); - - mBoundsDirty = false; - mBoundsUpdated = true; - } - //----------------------------------------------------------------------- - void InstanceBatch::updateVisibility(void) - { - mVisible = false; - - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - InstancedEntityVec::const_iterator end = mInstancedEntities.end(); - - while( itor != end && !mVisible ) - { - //Trick to force Ogre not to render us if none of our instances is visible - //Because we do Camera::isVisible(), it is better if the SceneNode from the - //InstancedEntity is not part of the scene graph (i.e. ultimate parent is root node) - //to avoid unnecessary wasteful calculations - mVisible |= (*itor)->findVisible( mCurrentCamera ); - ++itor; - } - } - //----------------------------------------------------------------------- - void InstanceBatch::createAllInstancedEntities() - { - mInstancedEntities.reserve( mInstancesPerBatch ); - mUnusedEntities.reserve( mInstancesPerBatch ); - - for( size_t i=0; i(num)); - } - //----------------------------------------------------------------------- - void InstanceBatch::deleteAllInstancedEntities() - { - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - InstancedEntityVec::const_iterator end = mInstancedEntities.end(); - - while( itor != end ) - { - if( (*itor)->getParentSceneNode() ) - (*itor)->getParentSceneNode()->detachObject( (*itor) ); - - OGRE_DELETE *itor++; - } - } - //----------------------------------------------------------------------- - void InstanceBatch::deleteUnusedInstancedEntities() - { - InstancedEntityVec::const_iterator itor = mUnusedEntities.begin(); - InstancedEntityVec::const_iterator end = mUnusedEntities.end(); - - while( itor != end ) - OGRE_DELETE *itor++; - - mUnusedEntities.clear(); - } - //----------------------------------------------------------------------- - void InstanceBatch::makeMatrixCameraRelative3x4( float *mat3x4, size_t numFloats ) - { - const Vector3 &cameraRelativePosition = mCurrentCamera->getDerivedPosition(); - - for( size_t i=0; i> 2; i += 3 ) - { - const Vector3 worldTrans( mat3x4[(i+0) * 4 + 3], mat3x4[(i+1) * 4 + 3], - mat3x4[(i+2) * 4 + 3] ); - const Vector3 newPos( worldTrans - cameraRelativePosition ); - - mat3x4[(i+0) * 4 + 3] = (float)newPos.x; - mat3x4[(i+1) * 4 + 3] = (float)newPos.y; - mat3x4[(i+2) * 4 + 3] = (float)newPos.z; - } - } - //----------------------------------------------------------------------- - RenderOperation InstanceBatch::build( const SubMesh* baseSubMesh ) - { - if( checkSubMeshCompatibility( baseSubMesh ) ) - { - //Only triangle list at the moment - mRenderOperation.operationType = RenderOperation::OT_TRIANGLE_LIST; - mRenderOperation.srcRenderable = this; - mRenderOperation.useIndexes = true; - setupVertices( baseSubMesh ); - setupIndices( baseSubMesh ); - - createAllInstancedEntities(); - } - - return mRenderOperation; - } - //----------------------------------------------------------------------- - void InstanceBatch::buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ) - { - mRenderOperation = renderOperation; - createAllInstancedEntities(); - } - //----------------------------------------------------------------------- - InstancedEntity* InstanceBatch::createInstancedEntity() - { - InstancedEntity *retVal = 0; - - if( !mUnusedEntities.empty() ) - { - retVal = mUnusedEntities.back(); - mUnusedEntities.pop_back(); - - retVal->setInUse(true); - } - - return retVal; - } - //----------------------------------------------------------------------- - void InstanceBatch::removeInstancedEntity( InstancedEntity *instancedEntity ) - { - if( instancedEntity->mBatchOwner != this ) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Trying to remove an InstancedEntity from scene created" - " with a different InstanceBatch", - "InstanceBatch::removeInstancedEntity()"); - } - if( !instancedEntity->isInUse() ) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Trying to remove an InstancedEntity that is already removed!", - "InstanceBatch::removeInstancedEntity()"); - } - - if( instancedEntity->getParentSceneNode() ) - instancedEntity->getParentSceneNode()->detachObject( instancedEntity ); - - instancedEntity->setInUse(false); - instancedEntity->stopSharingTransform(); - - //Put it back into the queue - mUnusedEntities.push_back( instancedEntity ); - } - //----------------------------------------------------------------------- - void InstanceBatch::getInstancedEntitiesInUse( InstancedEntityVec &outEntities, - CustomParamsVec &outParams ) - { - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - InstancedEntityVec::const_iterator end = mInstancedEntities.end(); - - while( itor != end ) - { - if( (*itor)->isInUse() ) - { - outEntities.push_back( *itor ); - - for( unsigned char i=0; igetNumCustomParams(); ++i ) - outParams.push_back( _getCustomParam( *itor, i ) ); - } - - ++itor; - } - } - //----------------------------------------------------------------------- - void InstanceBatch::defragmentBatchNoCull( InstancedEntityVec &usedEntities, - CustomParamsVec &usedParams ) - { - const size_t maxInstancesToCopy = std::min( mInstancesPerBatch, usedEntities.size() ); - InstancedEntityVec::iterator first = usedEntities.end() - maxInstancesToCopy; - CustomParamsVec::iterator firstParams = usedParams.end() - maxInstancesToCopy * - mCreator->getNumCustomParams(); - - //Copy from the back to front, into m_instancedEntities - mInstancedEntities.insert( mInstancedEntities.begin(), first, usedEntities.end() ); - //Remove them from the array - usedEntities.resize( usedEntities.size() - maxInstancesToCopy ); - - mCustomParams.insert( mCustomParams.begin(), firstParams, usedParams.end() ); - } - //----------------------------------------------------------------------- - void InstanceBatch::defragmentBatchDoCull( InstancedEntityVec &usedEntities, - CustomParamsVec &usedParams ) - { - //Get the the entity closest to the minimum bbox edge and put into "first" - InstancedEntityVec::const_iterator itor = usedEntities.begin(); - InstancedEntityVec::const_iterator end = usedEntities.end(); - - Vector3 vMinPos = Vector3::ZERO, firstPos = Vector3::ZERO; - InstancedEntity *first = 0; - - if( !usedEntities.empty() ) - { - first = *usedEntities.begin(); - firstPos = first->_getDerivedPosition(); - vMinPos = first->_getDerivedPosition(); - } - - while( itor != end ) - { - const Vector3 &vPos = (*itor)->_getDerivedPosition(); - - vMinPos.x = std::min( vMinPos.x, vPos.x ); - vMinPos.y = std::min( vMinPos.y, vPos.y ); - vMinPos.z = std::min( vMinPos.z, vPos.z ); - - if( vMinPos.squaredDistance( vPos ) < vMinPos.squaredDistance( firstPos ) ) - { - firstPos = vPos; - } - - ++itor; - } - - //Now collect entities closest to 'first' - while( !usedEntities.empty() && mInstancedEntities.size() < mInstancesPerBatch ) - { - InstancedEntityVec::iterator closest = usedEntities.begin(); - InstancedEntityVec::iterator it = usedEntities.begin(); - InstancedEntityVec::iterator e = usedEntities.end(); - - Vector3 closestPos; - closestPos = (*closest)->_getDerivedPosition(); - - while( it != e ) - { - const Vector3 &vPos = (*it)->_getDerivedPosition(); - - if( firstPos.squaredDistance( vPos ) < firstPos.squaredDistance( closestPos ) ) - { - closest = it; - closestPos = vPos; - } - - ++it; - } - - mInstancedEntities.push_back( *closest ); - //Now the custom params - const size_t idx = closest - usedEntities.begin(); - for( unsigned char i=0; igetNumCustomParams(); ++i ) - { - mCustomParams.push_back( usedParams[idx + i] ); - } - - //Remove 'closest' from usedEntities & usedParams using swap and pop_back trick - *closest = *(usedEntities.end() - 1); - usedEntities.pop_back(); - - for( unsigned char i=1; i<=mCreator->getNumCustomParams(); ++i ) - { - usedParams[idx + mCreator->getNumCustomParams() - i] = *(usedParams.end() - 1); - usedParams.pop_back(); - } - } - } - //----------------------------------------------------------------------- - void InstanceBatch::_defragmentBatch( bool optimizeCulling, InstancedEntityVec &usedEntities, - CustomParamsVec &usedParams ) - { - //Remove and clear what we don't need - mInstancedEntities.clear(); - mCustomParams.clear(); - deleteUnusedInstancedEntities(); - - if( !optimizeCulling ) - defragmentBatchNoCull( usedEntities, usedParams ); - else - defragmentBatchDoCull( usedEntities, usedParams ); - - //Reassign instance IDs and tell we're the new parent - uint32 instanceId = 0; - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - InstancedEntityVec::const_iterator end = mInstancedEntities.end(); - - while( itor != end ) - { - (*itor)->mInstanceId = instanceId++; - (*itor)->mBatchOwner = this; - ++itor; - } - - //Recreate unused entities, if there's left space in our container - assert( (signed)(mInstancesPerBatch) - (signed)(mInstancedEntities.size()) >= 0 ); - mInstancedEntities.reserve( mInstancesPerBatch ); - mUnusedEntities.reserve( mInstancesPerBatch ); - mCustomParams.reserve( mCreator->getNumCustomParams() * mInstancesPerBatch ); - for( size_t i=mInstancedEntities.size(); i_addDirtyBatch( this ); - mBoundsDirty = true; - } - //----------------------------------------------------------------------- - const String& InstanceBatch::getMovableType(void) const - { - static String sType = "InstanceBatch"; - return sType; - } - //----------------------------------------------------------------------- - void InstanceBatch::_notifyCurrentCamera( Camera* cam ) - { - mCurrentCamera = cam; - - //See DistanceLodStrategy::getValueImpl() - //We use our own because our SceneNode is just filled with zeroes, and updating it - //with real values is expensive, plus we would need to make sure it doesn't get to - //the shader - Real depth = Math::Sqrt( getSquaredViewDepth(cam) ) - - mMeshReference->getBoundingSphereRadius(); + mTechnSupportsSkeletal( true ), + mCachedCamera( 0 ), + mTransformSharingDirty(true), + mRemoveOwnVertexData(false), + mRemoveOwnIndexData(false) + { + assert( mInstancesPerBatch ); + + //Force batch visibility to be always visible. The instanced entities + //have individual visibility flags. If none matches the scene's current, + //then this batch won't rendered. + mVisibilityFlags = std::numeric_limits::max(); + + if( indexToBoneMap ) + { + assert( !(meshReference->hasSkeleton() && indexToBoneMap->empty()) ); + } + + mFullBoundingBox.setExtents( -Vector3::ZERO, Vector3::ZERO ); + + mName = batchName; + + mCustomParams.resize( mCreator->getNumCustomParams() * mInstancesPerBatch, Ogre::Vector4::ZERO ); + } + + InstanceBatch::~InstanceBatch() + { + deleteAllInstancedEntities(); + + //Remove the parent scene node automatically + SceneNode *sceneNode = getParentSceneNode(); + if( sceneNode ) + { + sceneNode->detachAllObjects(); + sceneNode->getParentSceneNode()->removeAndDestroyChild( sceneNode->getName() ); + } + + if( mRemoveOwnVertexData ) + OGRE_DELETE mRenderOperation.vertexData; + if( mRemoveOwnIndexData ) + OGRE_DELETE mRenderOperation.indexData; + + } + + void InstanceBatch::_setInstancesPerBatch( size_t instancesPerBatch ) + { + if( !mInstancedEntities.empty() ) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Instances per batch can only be changed before" + " building the batch.", "InstanceBatch::_setInstancesPerBatch"); + } + + mInstancesPerBatch = instancesPerBatch; + } + //----------------------------------------------------------------------- + bool InstanceBatch::checkSubMeshCompatibility( const SubMesh* baseSubMesh ) + { + if( baseSubMesh->operationType != RenderOperation::OT_TRIANGLE_LIST ) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Only meshes with OT_TRIANGLE_LIST are supported", + "InstanceBatch::checkSubMeshCompatibility"); + } + + if( !mCustomParams.empty() && mCreator->getInstancingTechnique() != InstanceManager::HWInstancingBasic ) + { + //Implementing this for ShaderBased is impossible. All other variants can be. + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Custom parameters not supported for this " + "technique. Do you dare implementing it?" + "See InstanceManager::setNumCustomParams " + "documentation.", + "InstanceBatch::checkSubMeshCompatibility"); + } + + return true; + } + //----------------------------------------------------------------------- + void InstanceBatch::_updateBounds(void) + { + mFullBoundingBox.setNull(); + + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + InstancedEntityVec::const_iterator end = mInstancedEntities.end(); + + Real maxScale = 0; + while( itor != end ) + { + InstancedEntity* ent = (*itor); + //Only increase the bounding box for those objects we know are in the scene + if( ent->isInScene() ) + { + maxScale = std::max(maxScale, ent->getMaxScaleCoef()); + mFullBoundingBox.merge( ent->_getDerivedPosition() ); + } + + ++itor; + } + + Real addToBound = maxScale * _getMeshReference()->getBoundingSphereRadius(); + mFullBoundingBox.setMaximum(mFullBoundingBox.getMaximum() + addToBound); + mFullBoundingBox.setMinimum(mFullBoundingBox.getMinimum() - addToBound); + + + mBoundingRadius = Math::boundingRadiusFromAABB( mFullBoundingBox ); + + //Tell the SceneManager our bounds have changed + getParentSceneNode()->needUpdate(true); + + mBoundsDirty = false; + mBoundsUpdated = true; + } + //----------------------------------------------------------------------- + void InstanceBatch::updateVisibility(void) + { + mVisible = false; + + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + InstancedEntityVec::const_iterator end = mInstancedEntities.end(); + + while( itor != end && !mVisible ) + { + //Trick to force Ogre not to render us if none of our instances is visible + //Because we do Camera::isVisible(), it is better if the SceneNode from the + //InstancedEntity is not part of the scene graph (i.e. ultimate parent is root node) + //to avoid unnecessary wasteful calculations + mVisible |= (*itor)->findVisible( mCurrentCamera ); + ++itor; + } + } + //----------------------------------------------------------------------- + void InstanceBatch::createAllInstancedEntities() + { + mInstancedEntities.reserve( mInstancesPerBatch ); + mUnusedEntities.reserve( mInstancesPerBatch ); + + for( size_t i=0; i(num)); + } + //----------------------------------------------------------------------- + void InstanceBatch::deleteAllInstancedEntities() + { + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + InstancedEntityVec::const_iterator end = mInstancedEntities.end(); + + while( itor != end ) + { + if( (*itor)->getParentSceneNode() ) + (*itor)->getParentSceneNode()->detachObject( (*itor) ); + + OGRE_DELETE *itor++; + } + } + //----------------------------------------------------------------------- + void InstanceBatch::deleteUnusedInstancedEntities() + { + InstancedEntityVec::const_iterator itor = mUnusedEntities.begin(); + InstancedEntityVec::const_iterator end = mUnusedEntities.end(); + + while( itor != end ) + OGRE_DELETE *itor++; + + mUnusedEntities.clear(); + } + //----------------------------------------------------------------------- + void InstanceBatch::makeMatrixCameraRelative3x4( float *mat3x4, size_t numFloats ) + { + const Vector3 &cameraRelativePosition = mCurrentCamera->getDerivedPosition(); + + for( size_t i=0; i> 2; i += 3 ) + { + const Vector3 worldTrans( mat3x4[(i+0) * 4 + 3], mat3x4[(i+1) * 4 + 3], + mat3x4[(i+2) * 4 + 3] ); + const Vector3 newPos( worldTrans - cameraRelativePosition ); + + mat3x4[(i+0) * 4 + 3] = (float)newPos.x; + mat3x4[(i+1) * 4 + 3] = (float)newPos.y; + mat3x4[(i+2) * 4 + 3] = (float)newPos.z; + } + } + //----------------------------------------------------------------------- + RenderOperation InstanceBatch::build( const SubMesh* baseSubMesh ) + { + if( checkSubMeshCompatibility( baseSubMesh ) ) + { + //Only triangle list at the moment + mRenderOperation.operationType = RenderOperation::OT_TRIANGLE_LIST; + mRenderOperation.srcRenderable = this; + mRenderOperation.useIndexes = true; + setupVertices( baseSubMesh ); + setupIndices( baseSubMesh ); + + createAllInstancedEntities(); + } + + return mRenderOperation; + } + //----------------------------------------------------------------------- + void InstanceBatch::buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ) + { + mRenderOperation = renderOperation; + createAllInstancedEntities(); + } + //----------------------------------------------------------------------- + InstancedEntity* InstanceBatch::createInstancedEntity() + { + InstancedEntity *retVal = 0; + + if( !mUnusedEntities.empty() ) + { + retVal = mUnusedEntities.back(); + mUnusedEntities.pop_back(); + + retVal->setInUse(true); + } + + return retVal; + } + //----------------------------------------------------------------------- + void InstanceBatch::removeInstancedEntity( InstancedEntity *instancedEntity ) + { + if( instancedEntity->mBatchOwner != this ) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Trying to remove an InstancedEntity from scene created" + " with a different InstanceBatch", + "InstanceBatch::removeInstancedEntity()"); + } + if( !instancedEntity->isInUse() ) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Trying to remove an InstancedEntity that is already removed!", + "InstanceBatch::removeInstancedEntity()"); + } + + if( instancedEntity->getParentSceneNode() ) + instancedEntity->getParentSceneNode()->detachObject( instancedEntity ); + + instancedEntity->setInUse(false); + instancedEntity->stopSharingTransform(); + + //Put it back into the queue + mUnusedEntities.push_back( instancedEntity ); + } + //----------------------------------------------------------------------- + void InstanceBatch::getInstancedEntitiesInUse( InstancedEntityVec &outEntities, + CustomParamsVec &outParams ) + { + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + InstancedEntityVec::const_iterator end = mInstancedEntities.end(); + + while( itor != end ) + { + if( (*itor)->isInUse() ) + { + outEntities.push_back( *itor ); + + for( unsigned char i=0; igetNumCustomParams(); ++i ) + outParams.push_back( _getCustomParam( *itor, i ) ); + } + + ++itor; + } + } + //----------------------------------------------------------------------- + void InstanceBatch::defragmentBatchNoCull( InstancedEntityVec &usedEntities, + CustomParamsVec &usedParams ) + { + const size_t maxInstancesToCopy = std::min( mInstancesPerBatch, usedEntities.size() ); + InstancedEntityVec::iterator first = usedEntities.end() - maxInstancesToCopy; + CustomParamsVec::iterator firstParams = usedParams.end() - maxInstancesToCopy * + mCreator->getNumCustomParams(); + + //Copy from the back to front, into m_instancedEntities + mInstancedEntities.insert( mInstancedEntities.begin(), first, usedEntities.end() ); + //Remove them from the array + usedEntities.resize( usedEntities.size() - maxInstancesToCopy ); + + mCustomParams.insert( mCustomParams.begin(), firstParams, usedParams.end() ); + } + //----------------------------------------------------------------------- + void InstanceBatch::defragmentBatchDoCull( InstancedEntityVec &usedEntities, + CustomParamsVec &usedParams ) + { + //Get the the entity closest to the minimum bbox edge and put into "first" + InstancedEntityVec::const_iterator itor = usedEntities.begin(); + InstancedEntityVec::const_iterator end = usedEntities.end(); + + Vector3 vMinPos = Vector3::ZERO, firstPos = Vector3::ZERO; + InstancedEntity *first = 0; + + if( !usedEntities.empty() ) + { + first = *usedEntities.begin(); + firstPos = first->_getDerivedPosition(); + vMinPos = first->_getDerivedPosition(); + } + + while( itor != end ) + { + const Vector3 &vPos = (*itor)->_getDerivedPosition(); + + vMinPos.x = std::min( vMinPos.x, vPos.x ); + vMinPos.y = std::min( vMinPos.y, vPos.y ); + vMinPos.z = std::min( vMinPos.z, vPos.z ); + + if( vMinPos.squaredDistance( vPos ) < vMinPos.squaredDistance( firstPos ) ) + { + firstPos = vPos; + } + + ++itor; + } + + //Now collect entities closest to 'first' + while( !usedEntities.empty() && mInstancedEntities.size() < mInstancesPerBatch ) + { + InstancedEntityVec::iterator closest = usedEntities.begin(); + InstancedEntityVec::iterator it = usedEntities.begin(); + InstancedEntityVec::iterator e = usedEntities.end(); + + Vector3 closestPos; + closestPos = (*closest)->_getDerivedPosition(); + + while( it != e ) + { + const Vector3 &vPos = (*it)->_getDerivedPosition(); + + if( firstPos.squaredDistance( vPos ) < firstPos.squaredDistance( closestPos ) ) + { + closest = it; + closestPos = vPos; + } + + ++it; + } + + mInstancedEntities.push_back( *closest ); + //Now the custom params + const size_t idx = closest - usedEntities.begin(); + for( unsigned char i=0; igetNumCustomParams(); ++i ) + { + mCustomParams.push_back( usedParams[idx + i] ); + } + + //Remove 'closest' from usedEntities & usedParams using swap and pop_back trick + *closest = *(usedEntities.end() - 1); + usedEntities.pop_back(); + + for( unsigned char i=1; i<=mCreator->getNumCustomParams(); ++i ) + { + usedParams[idx + mCreator->getNumCustomParams() - i] = *(usedParams.end() - 1); + usedParams.pop_back(); + } + } + } + //----------------------------------------------------------------------- + void InstanceBatch::_defragmentBatch( bool optimizeCulling, InstancedEntityVec &usedEntities, + CustomParamsVec &usedParams ) + { + //Remove and clear what we don't need + mInstancedEntities.clear(); + mCustomParams.clear(); + deleteUnusedInstancedEntities(); + + if( !optimizeCulling ) + defragmentBatchNoCull( usedEntities, usedParams ); + else + defragmentBatchDoCull( usedEntities, usedParams ); + + //Reassign instance IDs and tell we're the new parent + uint32 instanceId = 0; + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + InstancedEntityVec::const_iterator end = mInstancedEntities.end(); + + while( itor != end ) + { + (*itor)->mInstanceId = instanceId++; + (*itor)->mBatchOwner = this; + ++itor; + } + + //Recreate unused entities, if there's left space in our container + assert( (signed)(mInstancesPerBatch) - (signed)(mInstancedEntities.size()) >= 0 ); + mInstancedEntities.reserve( mInstancesPerBatch ); + mUnusedEntities.reserve( mInstancesPerBatch ); + mCustomParams.reserve( mCreator->getNumCustomParams() * mInstancesPerBatch ); + for( size_t i=mInstancedEntities.size(); i_addDirtyBatch( this ); + mBoundsDirty = true; + } + //----------------------------------------------------------------------- + const String& InstanceBatch::getMovableType(void) const + { + static String sType = "InstanceBatch"; + return sType; + } + //----------------------------------------------------------------------- + void InstanceBatch::_notifyCurrentCamera( Camera* cam ) + { + mCurrentCamera = cam; + + //See DistanceLodStrategy::getValueImpl() + //We use our own because our SceneNode is just filled with zeroes, and updating it + //with real values is expensive, plus we would need to make sure it doesn't get to + //the shader + Real depth = Math::Sqrt( getSquaredViewDepth(cam) ) - + mMeshReference->getBoundingSphereRadius(); depth = std::max( depth, Real(0) ); Real lodValue = depth * cam->_getLodBiasInverse(); - //Now calculate Material LOD + //Now calculate Material LOD /*const LodStrategy *materialStrategy = m_material->getLodStrategy(); //Calculate LOD value for given strategy @@ -502,7 +502,7 @@ namespace Ogre //Get the index at this depth unsigned short idx = mMaterial->getLodIndex( lodValue ); - //TODO: Replace subEntity for MovableObject + //TODO: Replace subEntity for MovableObject // Construct event object /*EntityMaterialLodChangedEvent subEntEvt; subEntEvt.subEntity = this; @@ -517,96 +517,96 @@ namespace Ogre //Change LOD index mMaterialLodIndex = idx; - MovableObject::_notifyCurrentCamera( cam ); - } - //----------------------------------------------------------------------- - const AxisAlignedBox& InstanceBatch::getBoundingBox(void) const - { - return mFullBoundingBox; - } - //----------------------------------------------------------------------- - Real InstanceBatch::getBoundingRadius(void) const - { - return mBoundingRadius; - } - //----------------------------------------------------------------------- - Real InstanceBatch::getSquaredViewDepth( const Camera* cam ) const - { - if( mCachedCamera != cam ) - { - mCachedCameraDist = std::numeric_limits::infinity(); - - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - InstancedEntityVec::const_iterator end = mInstancedEntities.end(); - - while( itor != end ) - { - if( (*itor)->isVisible() ) - mCachedCameraDist = std::min( mCachedCameraDist, (*itor)->getSquaredViewDepth( cam ) ); - ++itor; - } - - mCachedCamera = cam; - } + MovableObject::_notifyCurrentCamera( cam ); + } + //----------------------------------------------------------------------- + const AxisAlignedBox& InstanceBatch::getBoundingBox(void) const + { + return mFullBoundingBox; + } + //----------------------------------------------------------------------- + Real InstanceBatch::getBoundingRadius(void) const + { + return mBoundingRadius; + } + //----------------------------------------------------------------------- + Real InstanceBatch::getSquaredViewDepth( const Camera* cam ) const + { + if( mCachedCamera != cam ) + { + mCachedCameraDist = std::numeric_limits::infinity(); + + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + InstancedEntityVec::const_iterator end = mInstancedEntities.end(); + + while( itor != end ) + { + if( (*itor)->isVisible() ) + mCachedCameraDist = std::min( mCachedCameraDist, (*itor)->getSquaredViewDepth( cam ) ); + ++itor; + } + + mCachedCamera = cam; + } return mCachedCameraDist; - } - //----------------------------------------------------------------------- - const LightList& InstanceBatch::getLights( void ) const - { - return queryLights(); - } - //----------------------------------------------------------------------- - Technique* InstanceBatch::getTechnique( void ) const - { - return mMaterial->getBestTechnique( mMaterialLodIndex, this ); - } - //----------------------------------------------------------------------- - void InstanceBatch::_updateRenderQueue( RenderQueue* queue ) - { - /*if( m_boundsDirty ) - _updateBounds();*/ - - mDirtyAnimation = false; - - //Is at least one object in the scene? - updateVisibility(); - - if( mVisible ) - { - if( mMeshReference->hasSkeleton() ) - { - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - InstancedEntityVec::const_iterator end = mInstancedEntities.end(); - - while( itor != end ) - { - mDirtyAnimation |= (*itor)->_updateAnimation(); - ++itor; - } - } - - queue->addRenderable( this, mRenderQueueID, mRenderQueuePriority ); - } - - //Reset visibility once we skipped addRenderable (which saves GPU time), because OGRE for some - //reason stops updating our render queue afterwards, preventing us to recalculate visibility - mVisible = true; - } - //----------------------------------------------------------------------- - void InstanceBatch::visitRenderables( Renderable::Visitor* visitor, bool debugRenderables ) - { - visitor->visit( this, 0, false ); - } - //----------------------------------------------------------------------- - void InstanceBatch::_setCustomParam( InstancedEntity *instancedEntity, unsigned char idx, - const Vector4 &newParam ) - { - mCustomParams[instancedEntity->mInstanceId * mCreator->getNumCustomParams() + idx] = newParam; - } - //----------------------------------------------------------------------- - const Vector4& InstanceBatch::_getCustomParam( InstancedEntity *instancedEntity, unsigned char idx ) - { - return mCustomParams[instancedEntity->mInstanceId * mCreator->getNumCustomParams() + idx]; - } + } + //----------------------------------------------------------------------- + const LightList& InstanceBatch::getLights( void ) const + { + return queryLights(); + } + //----------------------------------------------------------------------- + Technique* InstanceBatch::getTechnique( void ) const + { + return mMaterial->getBestTechnique( mMaterialLodIndex, this ); + } + //----------------------------------------------------------------------- + void InstanceBatch::_updateRenderQueue( RenderQueue* queue ) + { + /*if( m_boundsDirty ) + _updateBounds();*/ + + mDirtyAnimation = false; + + //Is at least one object in the scene? + updateVisibility(); + + if( mVisible ) + { + if( mMeshReference->hasSkeleton() ) + { + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + InstancedEntityVec::const_iterator end = mInstancedEntities.end(); + + while( itor != end ) + { + mDirtyAnimation |= (*itor)->_updateAnimation(); + ++itor; + } + } + + queue->addRenderable( this, mRenderQueueID, mRenderQueuePriority ); + } + + //Reset visibility once we skipped addRenderable (which saves GPU time), because OGRE for some + //reason stops updating our render queue afterwards, preventing us to recalculate visibility + mVisible = true; + } + //----------------------------------------------------------------------- + void InstanceBatch::visitRenderables( Renderable::Visitor* visitor, bool debugRenderables ) + { + visitor->visit( this, 0, false ); + } + //----------------------------------------------------------------------- + void InstanceBatch::_setCustomParam( InstancedEntity *instancedEntity, unsigned char idx, + const Vector4 &newParam ) + { + mCustomParams[instancedEntity->mInstanceId * mCreator->getNumCustomParams() + idx] = newParam; + } + //----------------------------------------------------------------------- + const Vector4& InstanceBatch::_getCustomParam( InstancedEntity *instancedEntity, unsigned char idx ) + { + return mCustomParams[instancedEntity->mInstanceId * mCreator->getNumCustomParams() + idx]; + } } diff --git a/OgreMain/src/OgreInstanceBatchHW.cpp b/OgreMain/src/OgreInstanceBatchHW.cpp index 12607a6a2ff..52b5a630291 100644 --- a/OgreMain/src/OgreInstanceBatchHW.cpp +++ b/OgreMain/src/OgreInstanceBatchHW.cpp @@ -35,254 +35,254 @@ THE SOFTWARE. namespace Ogre { - InstanceBatchHW::InstanceBatchHW( InstanceManager *creator, MeshPtr &meshReference, - const MaterialPtr &material, size_t instancesPerBatch, - const Mesh::IndexMap *indexToBoneMap, const String &batchName ) : - InstanceBatch( creator, meshReference, material, instancesPerBatch, - indexToBoneMap, batchName ), - mKeepStatic( false ) - { - //Override defaults, so that InstancedEntities don't create a skeleton instance - mTechnSupportsSkeletal = false; - } + InstanceBatchHW::InstanceBatchHW( InstanceManager *creator, MeshPtr &meshReference, + const MaterialPtr &material, size_t instancesPerBatch, + const Mesh::IndexMap *indexToBoneMap, const String &batchName ) : + InstanceBatch( creator, meshReference, material, instancesPerBatch, + indexToBoneMap, batchName ), + mKeepStatic( false ) + { + //Override defaults, so that InstancedEntities don't create a skeleton instance + mTechnSupportsSkeletal = false; + } - InstanceBatchHW::~InstanceBatchHW() - { - } + InstanceBatchHW::~InstanceBatchHW() + { + } - //----------------------------------------------------------------------- - size_t InstanceBatchHW::calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const - { - size_t retVal = 0; + //----------------------------------------------------------------------- + size_t InstanceBatchHW::calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const + { + size_t retVal = 0; - RenderSystem *renderSystem = Root::getSingleton().getRenderSystem(); - const RenderSystemCapabilities *capabilities = renderSystem->getCapabilities(); + RenderSystem *renderSystem = Root::getSingleton().getRenderSystem(); + const RenderSystemCapabilities *capabilities = renderSystem->getCapabilities(); - if( capabilities->hasCapability( RSC_VERTEX_BUFFER_INSTANCE_DATA ) ) - { - //This value is arbitrary (theorical max is 2^30 for D3D9) but is big enough and safe - retVal = 65535; - } + if( capabilities->hasCapability( RSC_VERTEX_BUFFER_INSTANCE_DATA ) ) + { + //This value is arbitrary (theorical max is 2^30 for D3D9) but is big enough and safe + retVal = 65535; + } - return retVal; - } - //----------------------------------------------------------------------- - void InstanceBatchHW::buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ) - { - InstanceBatch::buildFrom( baseSubMesh, renderOperation ); + return retVal; + } + //----------------------------------------------------------------------- + void InstanceBatchHW::buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ) + { + InstanceBatch::buildFrom( baseSubMesh, renderOperation ); - //We need to clone the VertexData (but just reference all buffers, except the last one) - //because last buffer contains data specific to this batch, we need a different binding - mRenderOperation.vertexData = mRenderOperation.vertexData->clone( false ); - VertexData *thisVertexData = mRenderOperation.vertexData; - const unsigned short lastSource = thisVertexData->vertexDeclaration->getMaxSource(); - HardwareVertexBufferSharedPtr vertexBuffer = - HardwareBufferManager::getSingleton().createVertexBuffer( - thisVertexData->vertexDeclaration->getVertexSize(lastSource), - mInstancesPerBatch, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - thisVertexData->vertexBufferBinding->setBinding( lastSource, vertexBuffer ); - vertexBuffer->setIsInstanceData( true ); - vertexBuffer->setInstanceDataStepRate( 1 ); - } - //----------------------------------------------------------------------- - void InstanceBatchHW::setupVertices( const SubMesh* baseSubMesh ) - { - mRenderOperation.vertexData = baseSubMesh->vertexData->clone(); - mRemoveOwnVertexData = true; //Raise flag to remove our own vertex data in the end (not always needed) - - VertexData *thisVertexData = mRenderOperation.vertexData; + //We need to clone the VertexData (but just reference all buffers, except the last one) + //because last buffer contains data specific to this batch, we need a different binding + mRenderOperation.vertexData = mRenderOperation.vertexData->clone( false ); + VertexData *thisVertexData = mRenderOperation.vertexData; + const unsigned short lastSource = thisVertexData->vertexDeclaration->getMaxSource(); + HardwareVertexBufferSharedPtr vertexBuffer = + HardwareBufferManager::getSingleton().createVertexBuffer( + thisVertexData->vertexDeclaration->getVertexSize(lastSource), + mInstancesPerBatch, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + thisVertexData->vertexBufferBinding->setBinding( lastSource, vertexBuffer ); + vertexBuffer->setIsInstanceData( true ); + vertexBuffer->setInstanceDataStepRate( 1 ); + } + //----------------------------------------------------------------------- + void InstanceBatchHW::setupVertices( const SubMesh* baseSubMesh ) + { + mRenderOperation.vertexData = baseSubMesh->vertexData->clone(); + mRemoveOwnVertexData = true; //Raise flag to remove our own vertex data in the end (not always needed) + + VertexData *thisVertexData = mRenderOperation.vertexData; - //No skeletal animation support in this technique, sorry - removeBlendData(); + //No skeletal animation support in this technique, sorry + removeBlendData(); - //Modify the declaration so it contains an extra source, where we can put the per instance data - size_t offset = 0; - unsigned short nextTexCoord = thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate(); - const unsigned short newSource = thisVertexData->vertexDeclaration->getMaxSource() + 1; - for( unsigned char i=0; i<3 + mCreator->getNumCustomParams(); ++i ) - { - thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, - VES_TEXTURE_COORDINATES, nextTexCoord++ ); - offset = thisVertexData->vertexDeclaration->getVertexSize( newSource ); - } + //Modify the declaration so it contains an extra source, where we can put the per instance data + size_t offset = 0; + unsigned short nextTexCoord = thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate(); + const unsigned short newSource = thisVertexData->vertexDeclaration->getMaxSource() + 1; + for( unsigned char i=0; i<3 + mCreator->getNumCustomParams(); ++i ) + { + thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, + VES_TEXTURE_COORDINATES, nextTexCoord++ ); + offset = thisVertexData->vertexDeclaration->getVertexSize( newSource ); + } - //Create the vertex buffer containing per instance data - HardwareVertexBufferSharedPtr vertexBuffer = - HardwareBufferManager::getSingleton().createVertexBuffer( - thisVertexData->vertexDeclaration->getVertexSize(newSource), - mInstancesPerBatch, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - thisVertexData->vertexBufferBinding->setBinding( newSource, vertexBuffer ); - vertexBuffer->setIsInstanceData( true ); - vertexBuffer->setInstanceDataStepRate( 1 ); - } - //----------------------------------------------------------------------- - void InstanceBatchHW::setupIndices( const SubMesh* baseSubMesh ) - { - //We could use just a reference, but the InstanceManager will in the end attampt to delete - //the pointer, and we can't give it something that doesn't belong to us. - mRenderOperation.indexData = baseSubMesh->indexData->clone( true ); - mRemoveOwnIndexData = true; //Raise flag to remove our own index data in the end (not always needed) - } - //----------------------------------------------------------------------- - void InstanceBatchHW::removeBlendData() - { - VertexData *thisVertexData = mRenderOperation.vertexData; + //Create the vertex buffer containing per instance data + HardwareVertexBufferSharedPtr vertexBuffer = + HardwareBufferManager::getSingleton().createVertexBuffer( + thisVertexData->vertexDeclaration->getVertexSize(newSource), + mInstancesPerBatch, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + thisVertexData->vertexBufferBinding->setBinding( newSource, vertexBuffer ); + vertexBuffer->setIsInstanceData( true ); + vertexBuffer->setInstanceDataStepRate( 1 ); + } + //----------------------------------------------------------------------- + void InstanceBatchHW::setupIndices( const SubMesh* baseSubMesh ) + { + //We could use just a reference, but the InstanceManager will in the end attampt to delete + //the pointer, and we can't give it something that doesn't belong to us. + mRenderOperation.indexData = baseSubMesh->indexData->clone( true ); + mRemoveOwnIndexData = true; //Raise flag to remove our own index data in the end (not always needed) + } + //----------------------------------------------------------------------- + void InstanceBatchHW::removeBlendData() + { + VertexData *thisVertexData = mRenderOperation.vertexData; - unsigned short safeSource = 0xFFFF; - const VertexElement* blendIndexElem = thisVertexData->vertexDeclaration->findElementBySemantic( - VES_BLEND_INDICES ); - if( blendIndexElem ) - { - //save the source in order to prevent the next stage from unbinding it. - safeSource = blendIndexElem->getSource(); - // Remove buffer reference - thisVertexData->vertexBufferBinding->unsetBinding( blendIndexElem->getSource() ); - } - // Remove blend weights - const VertexElement* blendWeightElem = thisVertexData->vertexDeclaration->findElementBySemantic( - VES_BLEND_WEIGHTS ); - if( blendWeightElem && blendWeightElem->getSource() != safeSource ) - { - // Remove buffer reference - thisVertexData->vertexBufferBinding->unsetBinding( blendWeightElem->getSource() ); - } + unsigned short safeSource = 0xFFFF; + const VertexElement* blendIndexElem = thisVertexData->vertexDeclaration->findElementBySemantic( + VES_BLEND_INDICES ); + if( blendIndexElem ) + { + //save the source in order to prevent the next stage from unbinding it. + safeSource = blendIndexElem->getSource(); + // Remove buffer reference + thisVertexData->vertexBufferBinding->unsetBinding( blendIndexElem->getSource() ); + } + // Remove blend weights + const VertexElement* blendWeightElem = thisVertexData->vertexDeclaration->findElementBySemantic( + VES_BLEND_WEIGHTS ); + if( blendWeightElem && blendWeightElem->getSource() != safeSource ) + { + // Remove buffer reference + thisVertexData->vertexBufferBinding->unsetBinding( blendWeightElem->getSource() ); + } - thisVertexData->vertexDeclaration->removeElement(VES_BLEND_INDICES); - thisVertexData->vertexDeclaration->removeElement(VES_BLEND_WEIGHTS); - thisVertexData->closeGapsInBindings(); - } - //----------------------------------------------------------------------- - bool InstanceBatchHW::checkSubMeshCompatibility( const SubMesh* baseSubMesh ) - { - //Max number of texture coordinates is _usually_ 8, we need at least 3 available - if( baseSubMesh->vertexData->vertexDeclaration->getNextFreeTextureCoordinate() > 8-2 ) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Given mesh must have at " - "least 3 free TEXCOORDs", - "InstanceBatchHW::checkSubMeshCompatibility"); - } - if( baseSubMesh->vertexData->vertexDeclaration->getNextFreeTextureCoordinate() > - 8-2-mCreator->getNumCustomParams() || - 3 + mCreator->getNumCustomParams() >= 8 ) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "There are not enough free TEXCOORDs to hold the " - "custom parameters (required: " + - Ogre::StringConverter::toString( 3 + mCreator-> - getNumCustomParams() ) + "). See InstanceManager" - "::setNumCustomParams documentation", - "InstanceBatchHW::checkSubMeshCompatibility"); - } + thisVertexData->vertexDeclaration->removeElement(VES_BLEND_INDICES); + thisVertexData->vertexDeclaration->removeElement(VES_BLEND_WEIGHTS); + thisVertexData->closeGapsInBindings(); + } + //----------------------------------------------------------------------- + bool InstanceBatchHW::checkSubMeshCompatibility( const SubMesh* baseSubMesh ) + { + //Max number of texture coordinates is _usually_ 8, we need at least 3 available + if( baseSubMesh->vertexData->vertexDeclaration->getNextFreeTextureCoordinate() > 8-2 ) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Given mesh must have at " + "least 3 free TEXCOORDs", + "InstanceBatchHW::checkSubMeshCompatibility"); + } + if( baseSubMesh->vertexData->vertexDeclaration->getNextFreeTextureCoordinate() > + 8-2-mCreator->getNumCustomParams() || + 3 + mCreator->getNumCustomParams() >= 8 ) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "There are not enough free TEXCOORDs to hold the " + "custom parameters (required: " + + Ogre::StringConverter::toString( 3 + mCreator-> + getNumCustomParams() ) + "). See InstanceManager" + "::setNumCustomParams documentation", + "InstanceBatchHW::checkSubMeshCompatibility"); + } - return InstanceBatch::checkSubMeshCompatibility( baseSubMesh ); - } - //----------------------------------------------------------------------- - size_t InstanceBatchHW::updateVertexBuffer( Camera *currentCamera ) - { - size_t retVal = 0; + return InstanceBatch::checkSubMeshCompatibility( baseSubMesh ); + } + //----------------------------------------------------------------------- + size_t InstanceBatchHW::updateVertexBuffer( Camera *currentCamera ) + { + size_t retVal = 0; - //Now lock the vertex buffer and copy the 4x3 matrices, only those who need it! - const size_t bufferIdx = mRenderOperation.vertexData->vertexBufferBinding->getBufferCount()-1; - float *pDest = static_cast(mRenderOperation.vertexData->vertexBufferBinding-> - getBuffer(bufferIdx)->lock( HardwareBuffer::HBL_DISCARD )); + //Now lock the vertex buffer and copy the 4x3 matrices, only those who need it! + const size_t bufferIdx = mRenderOperation.vertexData->vertexBufferBinding->getBufferCount()-1; + float *pDest = static_cast(mRenderOperation.vertexData->vertexBufferBinding-> + getBuffer(bufferIdx)->lock( HardwareBuffer::HBL_DISCARD )); - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - InstancedEntityVec::const_iterator end = mInstancedEntities.end(); + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + InstancedEntityVec::const_iterator end = mInstancedEntities.end(); - unsigned char numCustomParams = mCreator->getNumCustomParams(); - size_t customParamIdx = 0; + unsigned char numCustomParams = mCreator->getNumCustomParams(); + size_t customParamIdx = 0; - while( itor != end ) - { - //Cull on an individual basis, the less entities are visible, the less instances we draw. - //No need to use null matrices at all! - if( (*itor)->findVisible( currentCamera ) ) - { - const size_t floatsWritten = (*itor)->getTransforms3x4( pDest ); + while( itor != end ) + { + //Cull on an individual basis, the less entities are visible, the less instances we draw. + //No need to use null matrices at all! + if( (*itor)->findVisible( currentCamera ) ) + { + const size_t floatsWritten = (*itor)->getTransforms3x4( pDest ); - if( mManager->getCameraRelativeRendering() ) - makeMatrixCameraRelative3x4( pDest, floatsWritten ); + if( mManager->getCameraRelativeRendering() ) + makeMatrixCameraRelative3x4( pDest, floatsWritten ); - pDest += floatsWritten; + pDest += floatsWritten; - //Write custom parameters, if any - for( unsigned char i=0; ivertexBufferBinding->getBuffer(bufferIdx)->unlock(); + mRenderOperation.vertexData->vertexBufferBinding->getBuffer(bufferIdx)->unlock(); - return retVal; - } - //----------------------------------------------------------------------- - void InstanceBatchHW::_boundsDirty(void) - { - //Don't update if we're static, but still mark we're dirty - if( !mBoundsDirty && !mKeepStatic ) - mCreator->_addDirtyBatch( this ); - mBoundsDirty = true; - } - //----------------------------------------------------------------------- - void InstanceBatchHW::setStaticAndUpdate( bool bStatic ) - { - //We were dirty but didn't update bounds. Do it now. - if( mKeepStatic && mBoundsDirty ) - mCreator->_addDirtyBatch( this ); + return retVal; + } + //----------------------------------------------------------------------- + void InstanceBatchHW::_boundsDirty(void) + { + //Don't update if we're static, but still mark we're dirty + if( !mBoundsDirty && !mKeepStatic ) + mCreator->_addDirtyBatch( this ); + mBoundsDirty = true; + } + //----------------------------------------------------------------------- + void InstanceBatchHW::setStaticAndUpdate( bool bStatic ) + { + //We were dirty but didn't update bounds. Do it now. + if( mKeepStatic && mBoundsDirty ) + mCreator->_addDirtyBatch( this ); - mKeepStatic = bStatic; - if( mKeepStatic ) - { - //One final update, since there will be none from now on - //(except further calls to this function). Pass NULL because - //we want to include only those who were added to the scene - //but we don't want to perform culling - mRenderOperation.numberOfInstances = updateVertexBuffer( 0 ); - } - } - //----------------------------------------------------------------------- - void InstanceBatchHW::getWorldTransforms( Matrix4* xform ) const - { - *xform = Matrix4::IDENTITY; - } - //----------------------------------------------------------------------- - unsigned short InstanceBatchHW::getNumWorldTransforms(void) const - { - return 1; - } - //----------------------------------------------------------------------- - void InstanceBatchHW::_updateRenderQueue( RenderQueue* queue ) - { - if( !mKeepStatic ) - { - //Completely override base functionality, since we don't cull on an "all-or-nothing" basis - //and we don't support skeletal animation - if( (mRenderOperation.numberOfInstances = updateVertexBuffer( mCurrentCamera )) ) - queue->addRenderable( this, mRenderQueueID, mRenderQueuePriority ); - } - else - { - if( mManager->getCameraRelativeRendering() ) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Camera-relative rendering is incompatible" - " with Instancing's static batches. Disable at least one of them", - "InstanceBatch::_updateRenderQueue"); - } + mKeepStatic = bStatic; + if( mKeepStatic ) + { + //One final update, since there will be none from now on + //(except further calls to this function). Pass NULL because + //we want to include only those who were added to the scene + //but we don't want to perform culling + mRenderOperation.numberOfInstances = updateVertexBuffer( 0 ); + } + } + //----------------------------------------------------------------------- + void InstanceBatchHW::getWorldTransforms( Matrix4* xform ) const + { + *xform = Matrix4::IDENTITY; + } + //----------------------------------------------------------------------- + unsigned short InstanceBatchHW::getNumWorldTransforms(void) const + { + return 1; + } + //----------------------------------------------------------------------- + void InstanceBatchHW::_updateRenderQueue( RenderQueue* queue ) + { + if( !mKeepStatic ) + { + //Completely override base functionality, since we don't cull on an "all-or-nothing" basis + //and we don't support skeletal animation + if( (mRenderOperation.numberOfInstances = updateVertexBuffer( mCurrentCamera )) ) + queue->addRenderable( this, mRenderQueueID, mRenderQueuePriority ); + } + else + { + if( mManager->getCameraRelativeRendering() ) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Camera-relative rendering is incompatible" + " with Instancing's static batches. Disable at least one of them", + "InstanceBatch::_updateRenderQueue"); + } - //Don't update when we're static - if( mRenderOperation.numberOfInstances ) - queue->addRenderable( this, mRenderQueueID, mRenderQueuePriority ); - } - } + //Don't update when we're static + if( mRenderOperation.numberOfInstances ) + queue->addRenderable( this, mRenderQueueID, mRenderQueuePriority ); + } + } } diff --git a/OgreMain/src/OgreInstanceBatchHW_VTF.cpp b/OgreMain/src/OgreInstanceBatchHW_VTF.cpp index 3e9088bd8a4..a35d9f45fc8 100644 --- a/OgreMain/src/OgreInstanceBatchHW_VTF.cpp +++ b/OgreMain/src/OgreInstanceBatchHW_VTF.cpp @@ -36,515 +36,515 @@ THE SOFTWARE. namespace Ogre { - static const uint16 c_maxTexWidthHW = 4096; - static const uint16 c_maxTexHeightHW = 4096; - - InstanceBatchHW_VTF::InstanceBatchHW_VTF( - InstanceManager *creator, MeshPtr &meshReference, - const MaterialPtr &material, size_t instancesPerBatch, - const Mesh::IndexMap *indexToBoneMap, const String &batchName ) - : BaseInstanceBatchVTF( creator, meshReference, material, - instancesPerBatch, indexToBoneMap, batchName), - mKeepStatic( false ) - { - } - //----------------------------------------------------------------------- - InstanceBatchHW_VTF::~InstanceBatchHW_VTF() - { - } - //----------------------------------------------------------------------- - void InstanceBatchHW_VTF::setupVertices( const SubMesh* baseSubMesh ) - { - mRenderOperation.vertexData = OGRE_NEW VertexData(); - mRemoveOwnVertexData = true; //Raise flag to remove our own vertex data in the end (not always needed) - - VertexData *thisVertexData = mRenderOperation.vertexData; - VertexData *baseVertexData = baseSubMesh->vertexData; - - thisVertexData->vertexStart = 0; - thisVertexData->vertexCount = baseVertexData->vertexCount; - mRenderOperation.numberOfInstances = mInstancesPerBatch; - - HardwareBufferManager::getSingleton().destroyVertexDeclaration( - thisVertexData->vertexDeclaration ); - thisVertexData->vertexDeclaration = baseVertexData->vertexDeclaration->clone(); - - //Reuse all vertex buffers - VertexBufferBinding::VertexBufferBindingMap::const_iterator itor = baseVertexData-> - vertexBufferBinding->getBindings().begin(); - VertexBufferBinding::VertexBufferBindingMap::const_iterator end = baseVertexData-> - vertexBufferBinding->getBindings().end(); - while( itor != end ) - { - const unsigned short bufferIdx = itor->first; - const HardwareVertexBufferSharedPtr vBuf = itor->second; - thisVertexData->vertexBufferBinding->setBinding( bufferIdx, vBuf ); - ++itor; - } - - //Remove the blend weights & indices - HWBoneIdxVec hwBoneIdx; - HWBoneWgtVec hwBoneWgt; - - //Blend weights may not be present because HW_VTF does not require to be skeletally animated - const VertexElement *veWeights = baseVertexData->vertexDeclaration-> - findElementBySemantic( VES_BLEND_WEIGHTS ); - if( veWeights ) - mWeightCount = forceOneWeight() ? 1 : veWeights->getSize() / sizeof(float); - else - mWeightCount = 1; - - hwBoneIdx.resize( baseVertexData->vertexCount * mWeightCount, 0 ); - - if( mMeshReference->hasSkeleton() && !mMeshReference->getSkeleton().isNull() ) - { - if(mWeightCount > 1) - { - hwBoneWgt.resize( baseVertexData->vertexCount * mWeightCount, 0 ); - retrieveBoneIdxWithWeights(baseVertexData, hwBoneIdx, hwBoneWgt); - } - else - { - retrieveBoneIdx( baseVertexData, hwBoneIdx ); - } - - const VertexElement* pElement = thisVertexData->vertexDeclaration->findElementBySemantic - (VES_BLEND_INDICES); - if (pElement) - { - unsigned short skelDataSource = pElement->getSource(); - thisVertexData->vertexDeclaration->removeElement( VES_BLEND_INDICES ); - thisVertexData->vertexDeclaration->removeElement( VES_BLEND_WEIGHTS ); - if (thisVertexData->vertexDeclaration->findElementsBySource(skelDataSource).empty()) - { - thisVertexData->vertexDeclaration->closeGapsInSource(); - thisVertexData->vertexBufferBinding->unsetBinding(skelDataSource); - VertexBufferBinding::BindingIndexMap tmpMap; - thisVertexData->vertexBufferBinding->closeGaps(tmpMap); - } - } - } - - createVertexTexture( baseSubMesh ); - createVertexSemantics( thisVertexData, baseVertexData, hwBoneIdx, hwBoneWgt); - } - //----------------------------------------------------------------------- - void InstanceBatchHW_VTF::setupIndices( const SubMesh* baseSubMesh ) - { - //We could use just a reference, but the InstanceManager will in the end attampt to delete - //the pointer, and we can't give it something that doesn't belong to us. - mRenderOperation.indexData = baseSubMesh->indexData->clone( true ); - mRemoveOwnIndexData = true; //Raise flag to remove our own index data in the end (not always needed) - } - //----------------------------------------------------------------------- - void InstanceBatchHW_VTF::createVertexSemantics( VertexData *thisVertexData, - VertexData *baseVertexData, - const HWBoneIdxVec &hwBoneIdx, - const HWBoneWgtVec& hwBoneWgt) - { - const float texWidth = static_cast(mMatrixTexture->getWidth()); - - //Only one weight per vertex is supported. It would not only be complex, but prohibitively slow. - //Put them in a new buffer, since it's 16 bytes aligned :-) - unsigned short newSource = thisVertexData->vertexDeclaration->getMaxSource() + 1; - - size_t offset = 0; - - size_t maxFloatsPerVector = 4; - - //Can fit two dual quaternions in every float4, but only one 3x4 matrix - for(size_t i = 0; i < mWeightCount; i += maxFloatsPerVector / mRowLength) - { - offset += thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, - thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); - } - - //Add the weights (supports up to four, which is Ogre's limit) - if(mWeightCount > 1) - { - thisVertexData->vertexDeclaration->addElement(newSource, offset, VET_FLOAT4, VES_BLEND_WEIGHTS, - 0 ).getSize(); - } - - //Create our own vertex buffer - HardwareVertexBufferSharedPtr vertexBuffer = - HardwareBufferManager::getSingleton().createVertexBuffer( - thisVertexData->vertexDeclaration->getVertexSize(newSource), - thisVertexData->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - thisVertexData->vertexBufferBinding->setBinding( newSource, vertexBuffer ); - - float *thisFloat = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - - //Create the UVs to sample from the right bone/matrix - for( size_t j=0; j < baseVertexData->vertexCount * mWeightCount; j += mWeightCount) - { - size_t numberOfMatricesInLine = 0; - - //Write the matrices, adding padding as needed - for(size_t i = 0; i < mWeightCount; ++i) - { - //Write the matrix - for( size_t k=0; k < mRowLength; ++k) - { - //Only calculate U (not V) since all matrices are in the same row. We use the instanced - //(repeated) buffer to tell how much U & V we need to offset - size_t instanceIdx = hwBoneIdx[j+i] * mRowLength + k; - *thisFloat++ = instanceIdx / texWidth; - } - - ++numberOfMatricesInLine; - - //If another matrix can't be fit, we're on another line, or if this is the last weight - if((numberOfMatricesInLine + 1) * mRowLength > maxFloatsPerVector || (i+1) == mWeightCount) - { - //Place zeroes in the remaining coordinates - for ( size_t k=mRowLength * numberOfMatricesInLine; k < maxFloatsPerVector; ++k) - { - *thisFloat++ = 0.0f; - } - - numberOfMatricesInLine = 0; - } - } - - //Don't need to write weights if there is only one - if(mWeightCount > 1) - { - //Write the weights - for(size_t i = 0; i < mWeightCount; ++i) - { - *thisFloat++ = hwBoneWgt[j+i]; - } - - //Write the empty space - for(size_t i = mWeightCount; i < maxFloatsPerVector; ++i) - { - *thisFloat++ = 0.0f; - } - } - } - - vertexBuffer->unlock(); - - //Now create the instance buffer that will be incremented per instance, contains UV offsets - newSource = thisVertexData->vertexDeclaration->getMaxSource() + 1; - offset = thisVertexData->vertexDeclaration->addElement( newSource, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, - thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); - if (useBoneMatrixLookup()) - { - //if using bone matrix lookup we will need to add 3 more float4 to contain the matrix. containing - //the personal world transform of each entity. - offset += thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, - thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); - offset += thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, - thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); - thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, - thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); - //Add two floats of padding here? or earlier? - //If not using bone matrix lookup, is it ok that it is 8 bytes since divides evenly into 16 - - } - - //Create our own vertex buffer - mInstanceVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( - thisVertexData->vertexDeclaration->getVertexSize(newSource), - mInstancesPerBatch, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - thisVertexData->vertexBufferBinding->setBinding( newSource, mInstanceVertexBuffer ); - - //Mark this buffer as instanced - mInstanceVertexBuffer->setIsInstanceData( true ); - mInstanceVertexBuffer->setInstanceDataStepRate( 1 ); - - updateInstanceDataBuffer(true, NULL); - } - - //updates the vertex buffer containing the per instance data - size_t InstanceBatchHW_VTF::updateInstanceDataBuffer(bool isFirstTime, Camera* currentCamera) - { - size_t visibleEntityCount = 0; - bool useMatrixLookup = useBoneMatrixLookup(); - if (isFirstTime ^ useMatrixLookup) - { - //update the mTransformLookupNumber value in the entities if needed - updateSharedLookupIndexes(); - - const float texWidth = static_cast(mMatrixTexture->getWidth()); - const float texHeight = static_cast(mMatrixTexture->getHeight()); - - //Calculate the texel offsets to correct them offline - //Awkwardly enough, the offset is needed in OpenGL too - Vector2 texelOffsets; - //RenderSystem *renderSystem = Root::getSingleton().getRenderSystem(); - texelOffsets.x = /*renderSystem->getHorizontalTexelOffset()*/ -0.5f / texWidth; - texelOffsets.y = /*renderSystem->getHorizontalTexelOffset()*/ -0.5f / texHeight; - - float *thisVec = static_cast(mInstanceVertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - - const size_t maxPixelsPerLine = std::min( static_cast(mMatrixTexture->getWidth()), mMaxFloatsPerLine >> 2 ); - - //Calculate UV offsets, which change per instance - for( size_t i=0; ifindVisible(currentCamera))) - { - size_t matrixIndex = useMatrixLookup ? entity->mTransformLookupNumber : i; - size_t instanceIdx = matrixIndex * mMatricesPerInstance * mRowLength; - *thisVec = ((instanceIdx % maxPixelsPerLine) / texWidth) - (float)(texelOffsets.x); - *(thisVec + 1) = ((instanceIdx / maxPixelsPerLine) / texHeight) - (float)(texelOffsets.y); - thisVec += 2; - - if (useMatrixLookup) - { - const Matrix4& mat = entity->_getParentNodeFullTransform(); - *(thisVec) = static_cast( mat[0][0] ); - *(thisVec + 1) = static_cast( mat[0][1] ); - *(thisVec + 2) = static_cast( mat[0][2] ); - *(thisVec + 3) = static_cast( mat[0][3] ); - *(thisVec + 4) = static_cast( mat[1][0] ); - *(thisVec + 5) = static_cast( mat[1][1] ); - *(thisVec + 6) = static_cast( mat[1][2] ); - *(thisVec + 7) = static_cast( mat[1][3] ); - *(thisVec + 8) = static_cast( mat[2][0] ); - *(thisVec + 9) = static_cast( mat[2][1] ); - *(thisVec + 10)= static_cast( mat[2][2] ); - *(thisVec + 11)= static_cast( mat[2][3] ); - if(currentCamera && mManager->getCameraRelativeRendering()) // && useMatrixLookup - { - const Vector3 &cameraRelativePosition = currentCamera->getDerivedPosition(); - *(thisVec + 3) -= static_cast( cameraRelativePosition.x ); - *(thisVec + 7) -= static_cast( cameraRelativePosition.y ); - *(thisVec + 11) -= static_cast( cameraRelativePosition.z ); - } - thisVec += 12; - } - ++visibleEntityCount; - } - } - - mInstanceVertexBuffer->unlock(); - } - else - { - visibleEntityCount = mInstancedEntities.size(); - } - return visibleEntityCount; - } - - //----------------------------------------------------------------------- - bool InstanceBatchHW_VTF::checkSubMeshCompatibility( const SubMesh* baseSubMesh ) - { - //Max number of texture coordinates is _usually_ 8, we need at least 2 available - unsigned short neededTextureCoord = 2; - if (useBoneMatrixLookup()) - { - //we need another 3 for the unique world transform of each instanced entity - neededTextureCoord += 3; - } - if( baseSubMesh->vertexData->vertexDeclaration->getNextFreeTextureCoordinate() > 8 - neededTextureCoord ) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - String("Given mesh must have at least ") + - StringConverter::toString(neededTextureCoord) + "free TEXCOORDs", - "InstanceBatchHW_VTF::checkSubMeshCompatibility"); - } - - return InstanceBatch::checkSubMeshCompatibility( baseSubMesh ); - } - //----------------------------------------------------------------------- - size_t InstanceBatchHW_VTF::calculateMaxNumInstances( - const SubMesh *baseSubMesh, uint16 flags ) const - { - size_t retVal = 0; - - RenderSystem *renderSystem = Root::getSingleton().getRenderSystem(); - const RenderSystemCapabilities *capabilities = renderSystem->getCapabilities(); - - //VTF & HW Instancing must be supported - if( capabilities->hasCapability( RSC_VERTEX_BUFFER_INSTANCE_DATA ) && - capabilities->hasCapability( RSC_VERTEX_TEXTURE_FETCH ) ) - { - //TODO: Check PF_FLOAT32_RGBA is supported (should be, since it was the 1st one) - const size_t numBones = std::max( 1, baseSubMesh->blendIndexToBoneIndexMap.size() ); - - const size_t maxUsableWidth = c_maxTexWidthHW - (c_maxTexWidthHW % (numBones * mRowLength)); - - //See InstanceBatchHW::calculateMaxNumInstances for the 65535 - retVal = std::min( 65535, maxUsableWidth * c_maxTexHeightHW / mRowLength / numBones ); - - if( flags & IM_VTFBESTFIT ) - { - size_t numUsedSkeletons = mInstancesPerBatch; - if (flags & IM_VTFBONEMATRIXLOOKUP) - numUsedSkeletons = std::min(getMaxLookupTableInstances(), numUsedSkeletons); - const size_t instancesPerBatch = std::min( retVal, numUsedSkeletons ); - //Do the same as in createVertexTexture(), but changing c_maxTexWidthHW for maxUsableWidth - const size_t numWorldMatrices = instancesPerBatch * numBones; - - size_t texWidth = std::min( numWorldMatrices * mRowLength, maxUsableWidth ); - size_t texHeight = numWorldMatrices * mRowLength / maxUsableWidth; - - const size_t remainder = (numWorldMatrices * mRowLength) % maxUsableWidth; - - if( remainder && texHeight > 0 ) - retVal = static_cast(texWidth * texHeight / (float)mRowLength / (float)(numBones)); - } - } - - return retVal; - } - //----------------------------------------------------------------------- - size_t InstanceBatchHW_VTF::updateVertexTexture( Camera *currentCamera ) - { - size_t renderedInstances = 0; - bool useMatrixLookup = useBoneMatrixLookup(); - if (useMatrixLookup) - { - //if we are using bone matrix look up we have to update the instance buffer for the - //vertex texture to be relevant - - //also note that in this case the number of instances to render comes directly from the - //updateInstanceDataBuffer() function, not from this function. - renderedInstances = updateInstanceDataBuffer(false, currentCamera); - } - - - mDirtyAnimation = false; - - //Now lock the texture and copy the 4x3 matrices! - mMatrixTexture->getBuffer()->lock( HardwareBuffer::HBL_DISCARD ); - const PixelBox &pixelBox = mMatrixTexture->getBuffer()->getCurrentLock(); - - float *pSource = static_cast(pixelBox.data); - - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - - vector::type writtenPositions(getMaxLookupTableInstances(), false); - - size_t floatPerEntity = mMatricesPerInstance * mRowLength * 4; - size_t entitiesPerPadding = (size_t)(mMaxFloatsPerLine / floatPerEntity); - - size_t instanceCount = mInstancedEntities.size(); - size_t updatedInstances = 0; - - float* transforms = NULL; - //If using dual quaternions, write 3x4 matrices to a temporary buffer, then convert to dual quaternions - if(mUseBoneDualQuaternions) - { - transforms = mTempTransformsArray3x4; - } - - for(size_t i = 0 ; i < instanceCount ; ++i) - { - InstancedEntity* entity = mInstancedEntities[i]; - size_t textureLookupPosition = updatedInstances; - if (useMatrixLookup) - { - textureLookupPosition = entity->mTransformLookupNumber; - } - //Check that we are not using a lookup matrix or that we have not already written - //The bone data - if (((!useMatrixLookup) || !writtenPositions[entity->mTransformLookupNumber]) && - //Cull on an individual basis, the less entities are visible, the less instances we draw. - //No need to use null matrices at all! - (entity->findVisible( currentCamera ))) - { - float* pDest = pSource + floatPerEntity * textureLookupPosition + - (size_t)(textureLookupPosition / entitiesPerPadding) * mWidthFloatsPadding; - - if(!mUseBoneDualQuaternions) - { - transforms = pDest; - } - - if( mMeshReference->hasSkeleton() ) - mDirtyAnimation |= entity->_updateAnimation(); - - size_t floatsWritten = entity->getTransforms3x4( transforms ); - - if( !useMatrixLookup && mManager->getCameraRelativeRendering() ) - makeMatrixCameraRelative3x4( transforms, floatsWritten ); - - if(mUseBoneDualQuaternions) - { - convert3x4MatricesToDualQuaternions(transforms, floatsWritten / 12, pDest); - } - - if (useMatrixLookup) - { - writtenPositions[entity->mTransformLookupNumber] = true; - } - else - { - ++updatedInstances; - } - } - - ++itor; - } - - if (!useMatrixLookup) - { - renderedInstances = updatedInstances; - } - - mMatrixTexture->getBuffer()->unlock(); - - return renderedInstances; - } - //----------------------------------------------------------------------- - void InstanceBatchHW_VTF::_boundsDirty(void) - { - //Don't update if we're static, but still mark we're dirty - if( !mBoundsDirty && !mKeepStatic && mCreator) - mCreator->_addDirtyBatch( this ); - mBoundsDirty = true; - } - //----------------------------------------------------------------------- - void InstanceBatchHW_VTF::setStaticAndUpdate( bool bStatic ) - { - //We were dirty but didn't update bounds. Do it now. - if( mKeepStatic && mBoundsDirty ) - mCreator->_addDirtyBatch( this ); - - mKeepStatic = bStatic; - if( mKeepStatic ) - { - //One final update, since there will be none from now on - //(except further calls to this function). Pass NULL because - //we want to include only those who were added to the scene - //but we don't want to perform culling - mRenderOperation.numberOfInstances = updateVertexTexture( 0 ); - } - } - //----------------------------------------------------------------------- - void InstanceBatchHW_VTF::_updateRenderQueue( RenderQueue* queue ) - { - if( !mKeepStatic ) - { - //Completely override base functionality, since we don't cull on an "all-or-nothing" basis - if( (mRenderOperation.numberOfInstances = updateVertexTexture( mCurrentCamera )) ) - queue->addRenderable( this, mRenderQueueID, mRenderQueuePriority ); - } - else - { - if( mManager->getCameraRelativeRendering() ) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Camera-relative rendering is incompatible" - " with Instancing's static batches. Disable at least one of them", - "InstanceBatch::_updateRenderQueue"); - } - - //Don't update when we're static - if( mRenderOperation.numberOfInstances ) - queue->addRenderable( this, mRenderQueueID, mRenderQueuePriority ); - } - } + static const uint16 c_maxTexWidthHW = 4096; + static const uint16 c_maxTexHeightHW = 4096; + + InstanceBatchHW_VTF::InstanceBatchHW_VTF( + InstanceManager *creator, MeshPtr &meshReference, + const MaterialPtr &material, size_t instancesPerBatch, + const Mesh::IndexMap *indexToBoneMap, const String &batchName ) + : BaseInstanceBatchVTF( creator, meshReference, material, + instancesPerBatch, indexToBoneMap, batchName), + mKeepStatic( false ) + { + } + //----------------------------------------------------------------------- + InstanceBatchHW_VTF::~InstanceBatchHW_VTF() + { + } + //----------------------------------------------------------------------- + void InstanceBatchHW_VTF::setupVertices( const SubMesh* baseSubMesh ) + { + mRenderOperation.vertexData = OGRE_NEW VertexData(); + mRemoveOwnVertexData = true; //Raise flag to remove our own vertex data in the end (not always needed) + + VertexData *thisVertexData = mRenderOperation.vertexData; + VertexData *baseVertexData = baseSubMesh->vertexData; + + thisVertexData->vertexStart = 0; + thisVertexData->vertexCount = baseVertexData->vertexCount; + mRenderOperation.numberOfInstances = mInstancesPerBatch; + + HardwareBufferManager::getSingleton().destroyVertexDeclaration( + thisVertexData->vertexDeclaration ); + thisVertexData->vertexDeclaration = baseVertexData->vertexDeclaration->clone(); + + //Reuse all vertex buffers + VertexBufferBinding::VertexBufferBindingMap::const_iterator itor = baseVertexData-> + vertexBufferBinding->getBindings().begin(); + VertexBufferBinding::VertexBufferBindingMap::const_iterator end = baseVertexData-> + vertexBufferBinding->getBindings().end(); + while( itor != end ) + { + const unsigned short bufferIdx = itor->first; + const HardwareVertexBufferSharedPtr vBuf = itor->second; + thisVertexData->vertexBufferBinding->setBinding( bufferIdx, vBuf ); + ++itor; + } + + //Remove the blend weights & indices + HWBoneIdxVec hwBoneIdx; + HWBoneWgtVec hwBoneWgt; + + //Blend weights may not be present because HW_VTF does not require to be skeletally animated + const VertexElement *veWeights = baseVertexData->vertexDeclaration-> + findElementBySemantic( VES_BLEND_WEIGHTS ); + if( veWeights ) + mWeightCount = forceOneWeight() ? 1 : veWeights->getSize() / sizeof(float); + else + mWeightCount = 1; + + hwBoneIdx.resize( baseVertexData->vertexCount * mWeightCount, 0 ); + + if( mMeshReference->hasSkeleton() && !mMeshReference->getSkeleton().isNull() ) + { + if(mWeightCount > 1) + { + hwBoneWgt.resize( baseVertexData->vertexCount * mWeightCount, 0 ); + retrieveBoneIdxWithWeights(baseVertexData, hwBoneIdx, hwBoneWgt); + } + else + { + retrieveBoneIdx( baseVertexData, hwBoneIdx ); + } + + const VertexElement* pElement = thisVertexData->vertexDeclaration->findElementBySemantic + (VES_BLEND_INDICES); + if (pElement) + { + unsigned short skelDataSource = pElement->getSource(); + thisVertexData->vertexDeclaration->removeElement( VES_BLEND_INDICES ); + thisVertexData->vertexDeclaration->removeElement( VES_BLEND_WEIGHTS ); + if (thisVertexData->vertexDeclaration->findElementsBySource(skelDataSource).empty()) + { + thisVertexData->vertexDeclaration->closeGapsInSource(); + thisVertexData->vertexBufferBinding->unsetBinding(skelDataSource); + VertexBufferBinding::BindingIndexMap tmpMap; + thisVertexData->vertexBufferBinding->closeGaps(tmpMap); + } + } + } + + createVertexTexture( baseSubMesh ); + createVertexSemantics( thisVertexData, baseVertexData, hwBoneIdx, hwBoneWgt); + } + //----------------------------------------------------------------------- + void InstanceBatchHW_VTF::setupIndices( const SubMesh* baseSubMesh ) + { + //We could use just a reference, but the InstanceManager will in the end attampt to delete + //the pointer, and we can't give it something that doesn't belong to us. + mRenderOperation.indexData = baseSubMesh->indexData->clone( true ); + mRemoveOwnIndexData = true; //Raise flag to remove our own index data in the end (not always needed) + } + //----------------------------------------------------------------------- + void InstanceBatchHW_VTF::createVertexSemantics( VertexData *thisVertexData, + VertexData *baseVertexData, + const HWBoneIdxVec &hwBoneIdx, + const HWBoneWgtVec& hwBoneWgt) + { + const float texWidth = static_cast(mMatrixTexture->getWidth()); + + //Only one weight per vertex is supported. It would not only be complex, but prohibitively slow. + //Put them in a new buffer, since it's 16 bytes aligned :-) + unsigned short newSource = thisVertexData->vertexDeclaration->getMaxSource() + 1; + + size_t offset = 0; + + size_t maxFloatsPerVector = 4; + + //Can fit two dual quaternions in every float4, but only one 3x4 matrix + for(size_t i = 0; i < mWeightCount; i += maxFloatsPerVector / mRowLength) + { + offset += thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, + thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); + } + + //Add the weights (supports up to four, which is Ogre's limit) + if(mWeightCount > 1) + { + thisVertexData->vertexDeclaration->addElement(newSource, offset, VET_FLOAT4, VES_BLEND_WEIGHTS, + 0 ).getSize(); + } + + //Create our own vertex buffer + HardwareVertexBufferSharedPtr vertexBuffer = + HardwareBufferManager::getSingleton().createVertexBuffer( + thisVertexData->vertexDeclaration->getVertexSize(newSource), + thisVertexData->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + thisVertexData->vertexBufferBinding->setBinding( newSource, vertexBuffer ); + + float *thisFloat = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + + //Create the UVs to sample from the right bone/matrix + for( size_t j=0; j < baseVertexData->vertexCount * mWeightCount; j += mWeightCount) + { + size_t numberOfMatricesInLine = 0; + + //Write the matrices, adding padding as needed + for(size_t i = 0; i < mWeightCount; ++i) + { + //Write the matrix + for( size_t k=0; k < mRowLength; ++k) + { + //Only calculate U (not V) since all matrices are in the same row. We use the instanced + //(repeated) buffer to tell how much U & V we need to offset + size_t instanceIdx = hwBoneIdx[j+i] * mRowLength + k; + *thisFloat++ = instanceIdx / texWidth; + } + + ++numberOfMatricesInLine; + + //If another matrix can't be fit, we're on another line, or if this is the last weight + if((numberOfMatricesInLine + 1) * mRowLength > maxFloatsPerVector || (i+1) == mWeightCount) + { + //Place zeroes in the remaining coordinates + for ( size_t k=mRowLength * numberOfMatricesInLine; k < maxFloatsPerVector; ++k) + { + *thisFloat++ = 0.0f; + } + + numberOfMatricesInLine = 0; + } + } + + //Don't need to write weights if there is only one + if(mWeightCount > 1) + { + //Write the weights + for(size_t i = 0; i < mWeightCount; ++i) + { + *thisFloat++ = hwBoneWgt[j+i]; + } + + //Write the empty space + for(size_t i = mWeightCount; i < maxFloatsPerVector; ++i) + { + *thisFloat++ = 0.0f; + } + } + } + + vertexBuffer->unlock(); + + //Now create the instance buffer that will be incremented per instance, contains UV offsets + newSource = thisVertexData->vertexDeclaration->getMaxSource() + 1; + offset = thisVertexData->vertexDeclaration->addElement( newSource, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES, + thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); + if (useBoneMatrixLookup()) + { + //if using bone matrix lookup we will need to add 3 more float4 to contain the matrix. containing + //the personal world transform of each entity. + offset += thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, + thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); + offset += thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, + thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); + thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, + thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); + //Add two floats of padding here? or earlier? + //If not using bone matrix lookup, is it ok that it is 8 bytes since divides evenly into 16 + + } + + //Create our own vertex buffer + mInstanceVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( + thisVertexData->vertexDeclaration->getVertexSize(newSource), + mInstancesPerBatch, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + thisVertexData->vertexBufferBinding->setBinding( newSource, mInstanceVertexBuffer ); + + //Mark this buffer as instanced + mInstanceVertexBuffer->setIsInstanceData( true ); + mInstanceVertexBuffer->setInstanceDataStepRate( 1 ); + + updateInstanceDataBuffer(true, NULL); + } + + //updates the vertex buffer containing the per instance data + size_t InstanceBatchHW_VTF::updateInstanceDataBuffer(bool isFirstTime, Camera* currentCamera) + { + size_t visibleEntityCount = 0; + bool useMatrixLookup = useBoneMatrixLookup(); + if (isFirstTime ^ useMatrixLookup) + { + //update the mTransformLookupNumber value in the entities if needed + updateSharedLookupIndexes(); + + const float texWidth = static_cast(mMatrixTexture->getWidth()); + const float texHeight = static_cast(mMatrixTexture->getHeight()); + + //Calculate the texel offsets to correct them offline + //Awkwardly enough, the offset is needed in OpenGL too + Vector2 texelOffsets; + //RenderSystem *renderSystem = Root::getSingleton().getRenderSystem(); + texelOffsets.x = /*renderSystem->getHorizontalTexelOffset()*/ -0.5f / texWidth; + texelOffsets.y = /*renderSystem->getHorizontalTexelOffset()*/ -0.5f / texHeight; + + float *thisVec = static_cast(mInstanceVertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + + const size_t maxPixelsPerLine = std::min( static_cast(mMatrixTexture->getWidth()), mMaxFloatsPerLine >> 2 ); + + //Calculate UV offsets, which change per instance + for( size_t i=0; ifindVisible(currentCamera))) + { + size_t matrixIndex = useMatrixLookup ? entity->mTransformLookupNumber : i; + size_t instanceIdx = matrixIndex * mMatricesPerInstance * mRowLength; + *thisVec = ((instanceIdx % maxPixelsPerLine) / texWidth) - (float)(texelOffsets.x); + *(thisVec + 1) = ((instanceIdx / maxPixelsPerLine) / texHeight) - (float)(texelOffsets.y); + thisVec += 2; + + if (useMatrixLookup) + { + const Matrix4& mat = entity->_getParentNodeFullTransform(); + *(thisVec) = static_cast( mat[0][0] ); + *(thisVec + 1) = static_cast( mat[0][1] ); + *(thisVec + 2) = static_cast( mat[0][2] ); + *(thisVec + 3) = static_cast( mat[0][3] ); + *(thisVec + 4) = static_cast( mat[1][0] ); + *(thisVec + 5) = static_cast( mat[1][1] ); + *(thisVec + 6) = static_cast( mat[1][2] ); + *(thisVec + 7) = static_cast( mat[1][3] ); + *(thisVec + 8) = static_cast( mat[2][0] ); + *(thisVec + 9) = static_cast( mat[2][1] ); + *(thisVec + 10)= static_cast( mat[2][2] ); + *(thisVec + 11)= static_cast( mat[2][3] ); + if(currentCamera && mManager->getCameraRelativeRendering()) // && useMatrixLookup + { + const Vector3 &cameraRelativePosition = currentCamera->getDerivedPosition(); + *(thisVec + 3) -= static_cast( cameraRelativePosition.x ); + *(thisVec + 7) -= static_cast( cameraRelativePosition.y ); + *(thisVec + 11) -= static_cast( cameraRelativePosition.z ); + } + thisVec += 12; + } + ++visibleEntityCount; + } + } + + mInstanceVertexBuffer->unlock(); + } + else + { + visibleEntityCount = mInstancedEntities.size(); + } + return visibleEntityCount; + } + + //----------------------------------------------------------------------- + bool InstanceBatchHW_VTF::checkSubMeshCompatibility( const SubMesh* baseSubMesh ) + { + //Max number of texture coordinates is _usually_ 8, we need at least 2 available + unsigned short neededTextureCoord = 2; + if (useBoneMatrixLookup()) + { + //we need another 3 for the unique world transform of each instanced entity + neededTextureCoord += 3; + } + if( baseSubMesh->vertexData->vertexDeclaration->getNextFreeTextureCoordinate() > 8 - neededTextureCoord ) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + String("Given mesh must have at least ") + + StringConverter::toString(neededTextureCoord) + "free TEXCOORDs", + "InstanceBatchHW_VTF::checkSubMeshCompatibility"); + } + + return InstanceBatch::checkSubMeshCompatibility( baseSubMesh ); + } + //----------------------------------------------------------------------- + size_t InstanceBatchHW_VTF::calculateMaxNumInstances( + const SubMesh *baseSubMesh, uint16 flags ) const + { + size_t retVal = 0; + + RenderSystem *renderSystem = Root::getSingleton().getRenderSystem(); + const RenderSystemCapabilities *capabilities = renderSystem->getCapabilities(); + + //VTF & HW Instancing must be supported + if( capabilities->hasCapability( RSC_VERTEX_BUFFER_INSTANCE_DATA ) && + capabilities->hasCapability( RSC_VERTEX_TEXTURE_FETCH ) ) + { + //TODO: Check PF_FLOAT32_RGBA is supported (should be, since it was the 1st one) + const size_t numBones = std::max( 1, baseSubMesh->blendIndexToBoneIndexMap.size() ); + + const size_t maxUsableWidth = c_maxTexWidthHW - (c_maxTexWidthHW % (numBones * mRowLength)); + + //See InstanceBatchHW::calculateMaxNumInstances for the 65535 + retVal = std::min( 65535, maxUsableWidth * c_maxTexHeightHW / mRowLength / numBones ); + + if( flags & IM_VTFBESTFIT ) + { + size_t numUsedSkeletons = mInstancesPerBatch; + if (flags & IM_VTFBONEMATRIXLOOKUP) + numUsedSkeletons = std::min(getMaxLookupTableInstances(), numUsedSkeletons); + const size_t instancesPerBatch = std::min( retVal, numUsedSkeletons ); + //Do the same as in createVertexTexture(), but changing c_maxTexWidthHW for maxUsableWidth + const size_t numWorldMatrices = instancesPerBatch * numBones; + + size_t texWidth = std::min( numWorldMatrices * mRowLength, maxUsableWidth ); + size_t texHeight = numWorldMatrices * mRowLength / maxUsableWidth; + + const size_t remainder = (numWorldMatrices * mRowLength) % maxUsableWidth; + + if( remainder && texHeight > 0 ) + retVal = static_cast(texWidth * texHeight / (float)mRowLength / (float)(numBones)); + } + } + + return retVal; + } + //----------------------------------------------------------------------- + size_t InstanceBatchHW_VTF::updateVertexTexture( Camera *currentCamera ) + { + size_t renderedInstances = 0; + bool useMatrixLookup = useBoneMatrixLookup(); + if (useMatrixLookup) + { + //if we are using bone matrix look up we have to update the instance buffer for the + //vertex texture to be relevant + + //also note that in this case the number of instances to render comes directly from the + //updateInstanceDataBuffer() function, not from this function. + renderedInstances = updateInstanceDataBuffer(false, currentCamera); + } + + + mDirtyAnimation = false; + + //Now lock the texture and copy the 4x3 matrices! + mMatrixTexture->getBuffer()->lock( HardwareBuffer::HBL_DISCARD ); + const PixelBox &pixelBox = mMatrixTexture->getBuffer()->getCurrentLock(); + + float *pSource = static_cast(pixelBox.data); + + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + + vector::type writtenPositions(getMaxLookupTableInstances(), false); + + size_t floatPerEntity = mMatricesPerInstance * mRowLength * 4; + size_t entitiesPerPadding = (size_t)(mMaxFloatsPerLine / floatPerEntity); + + size_t instanceCount = mInstancedEntities.size(); + size_t updatedInstances = 0; + + float* transforms = NULL; + //If using dual quaternions, write 3x4 matrices to a temporary buffer, then convert to dual quaternions + if(mUseBoneDualQuaternions) + { + transforms = mTempTransformsArray3x4; + } + + for(size_t i = 0 ; i < instanceCount ; ++i) + { + InstancedEntity* entity = mInstancedEntities[i]; + size_t textureLookupPosition = updatedInstances; + if (useMatrixLookup) + { + textureLookupPosition = entity->mTransformLookupNumber; + } + //Check that we are not using a lookup matrix or that we have not already written + //The bone data + if (((!useMatrixLookup) || !writtenPositions[entity->mTransformLookupNumber]) && + //Cull on an individual basis, the less entities are visible, the less instances we draw. + //No need to use null matrices at all! + (entity->findVisible( currentCamera ))) + { + float* pDest = pSource + floatPerEntity * textureLookupPosition + + (size_t)(textureLookupPosition / entitiesPerPadding) * mWidthFloatsPadding; + + if(!mUseBoneDualQuaternions) + { + transforms = pDest; + } + + if( mMeshReference->hasSkeleton() ) + mDirtyAnimation |= entity->_updateAnimation(); + + size_t floatsWritten = entity->getTransforms3x4( transforms ); + + if( !useMatrixLookup && mManager->getCameraRelativeRendering() ) + makeMatrixCameraRelative3x4( transforms, floatsWritten ); + + if(mUseBoneDualQuaternions) + { + convert3x4MatricesToDualQuaternions(transforms, floatsWritten / 12, pDest); + } + + if (useMatrixLookup) + { + writtenPositions[entity->mTransformLookupNumber] = true; + } + else + { + ++updatedInstances; + } + } + + ++itor; + } + + if (!useMatrixLookup) + { + renderedInstances = updatedInstances; + } + + mMatrixTexture->getBuffer()->unlock(); + + return renderedInstances; + } + //----------------------------------------------------------------------- + void InstanceBatchHW_VTF::_boundsDirty(void) + { + //Don't update if we're static, but still mark we're dirty + if( !mBoundsDirty && !mKeepStatic && mCreator) + mCreator->_addDirtyBatch( this ); + mBoundsDirty = true; + } + //----------------------------------------------------------------------- + void InstanceBatchHW_VTF::setStaticAndUpdate( bool bStatic ) + { + //We were dirty but didn't update bounds. Do it now. + if( mKeepStatic && mBoundsDirty ) + mCreator->_addDirtyBatch( this ); + + mKeepStatic = bStatic; + if( mKeepStatic ) + { + //One final update, since there will be none from now on + //(except further calls to this function). Pass NULL because + //we want to include only those who were added to the scene + //but we don't want to perform culling + mRenderOperation.numberOfInstances = updateVertexTexture( 0 ); + } + } + //----------------------------------------------------------------------- + void InstanceBatchHW_VTF::_updateRenderQueue( RenderQueue* queue ) + { + if( !mKeepStatic ) + { + //Completely override base functionality, since we don't cull on an "all-or-nothing" basis + if( (mRenderOperation.numberOfInstances = updateVertexTexture( mCurrentCamera )) ) + queue->addRenderable( this, mRenderQueueID, mRenderQueuePriority ); + } + else + { + if( mManager->getCameraRelativeRendering() ) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Camera-relative rendering is incompatible" + " with Instancing's static batches. Disable at least one of them", + "InstanceBatch::_updateRenderQueue"); + } + + //Don't update when we're static + if( mRenderOperation.numberOfInstances ) + queue->addRenderable( this, mRenderQueueID, mRenderQueuePriority ); + } + } } diff --git a/OgreMain/src/OgreInstanceBatchShader.cpp b/OgreMain/src/OgreInstanceBatchShader.cpp index 38250c0a1ed..5ab14327d01 100644 --- a/OgreMain/src/OgreInstanceBatchShader.cpp +++ b/OgreMain/src/OgreInstanceBatchShader.cpp @@ -36,312 +36,312 @@ THE SOFTWARE. namespace Ogre { - InstanceBatchShader::InstanceBatchShader( InstanceManager *creator, MeshPtr &meshReference, - const MaterialPtr &material, size_t instancesPerBatch, - const Mesh::IndexMap *indexToBoneMap, const String &batchName ) : - InstanceBatch( creator, meshReference, material, instancesPerBatch, - indexToBoneMap, batchName ), - mNumWorldMatrices( instancesPerBatch ) - { - } - - InstanceBatchShader::~InstanceBatchShader() - { - } - - //----------------------------------------------------------------------- - size_t InstanceBatchShader::calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const - { - const size_t numBones = std::max( 1, baseSubMesh->blendIndexToBoneIndexMap.size() ); - - mMaterial->load(); - Technique *technique = mMaterial->getBestTechnique(); - if( technique ) - { - GpuProgramParametersSharedPtr vertexParam = technique->getPass(0)->getVertexProgramParameters(); - GpuConstantDefinitionIterator itor = vertexParam->getConstantDefinitionIterator(); - while( itor.hasMoreElements() ) - { - const GpuConstantDefinition &constDef = itor.getNext(); - if(((constDef.constType == GCT_MATRIX_3X4 || - constDef.constType == GCT_MATRIX_4X3 || //OGL GLSL bitches without this - constDef.constType == GCT_MATRIX_2X4 || - constDef.constType == GCT_FLOAT4) //OGL GLSL bitches without this - && constDef.isFloat()) || + InstanceBatchShader::InstanceBatchShader( InstanceManager *creator, MeshPtr &meshReference, + const MaterialPtr &material, size_t instancesPerBatch, + const Mesh::IndexMap *indexToBoneMap, const String &batchName ) : + InstanceBatch( creator, meshReference, material, instancesPerBatch, + indexToBoneMap, batchName ), + mNumWorldMatrices( instancesPerBatch ) + { + } + + InstanceBatchShader::~InstanceBatchShader() + { + } + + //----------------------------------------------------------------------- + size_t InstanceBatchShader::calculateMaxNumInstances( const SubMesh *baseSubMesh, uint16 flags ) const + { + const size_t numBones = std::max( 1, baseSubMesh->blendIndexToBoneIndexMap.size() ); + + mMaterial->load(); + Technique *technique = mMaterial->getBestTechnique(); + if( technique ) + { + GpuProgramParametersSharedPtr vertexParam = technique->getPass(0)->getVertexProgramParameters(); + GpuConstantDefinitionIterator itor = vertexParam->getConstantDefinitionIterator(); + while( itor.hasMoreElements() ) + { + const GpuConstantDefinition &constDef = itor.getNext(); + if(((constDef.constType == GCT_MATRIX_3X4 || + constDef.constType == GCT_MATRIX_4X3 || //OGL GLSL bitches without this + constDef.constType == GCT_MATRIX_2X4 || + constDef.constType == GCT_FLOAT4) //OGL GLSL bitches without this + && constDef.isFloat()) || ((constDef.constType == GCT_MATRIX_DOUBLE_3X4 || - constDef.constType == GCT_MATRIX_DOUBLE_4X3 || //OGL GLSL bitches without this - constDef.constType == GCT_MATRIX_DOUBLE_2X4 || - constDef.constType == GCT_DOUBLE4) //OGL GLSL bitches without this + constDef.constType == GCT_MATRIX_DOUBLE_4X3 || //OGL GLSL bitches without this + constDef.constType == GCT_MATRIX_DOUBLE_2X4 || + constDef.constType == GCT_DOUBLE4) //OGL GLSL bitches without this && constDef.isDouble()) ) - { - const GpuProgramParameters::AutoConstantEntry *entry = - vertexParam->_findRawAutoConstantEntryFloat( constDef.physicalIndex ); - if( entry && (entry->paramType == GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4 || entry->paramType == GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4)) - { - //Material is correctly done! - size_t arraySize = constDef.arraySize; - - //Deal with GL "hacky" way of doing 4x3 matrices - if(entry->paramType == GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4 && constDef.constType == GCT_FLOAT4) - arraySize /= 3; - else if(entry->paramType == GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4 && constDef.constType == GCT_FLOAT4) - arraySize /= 2; - - //Check the num of arrays - size_t retVal = arraySize / numBones; - - if( flags & IM_USE16BIT ) - { - if( baseSubMesh->vertexData->vertexCount * retVal > 0xFFFF ) - retVal = 0xFFFF / baseSubMesh->vertexData->vertexCount; - } - - if((retVal < 3 && entry->paramType == GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4) || - (retVal < 2 && entry->paramType == GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4)) - { - LogManager::getSingleton().logMessage( "InstanceBatchShader: Mesh " + - mMeshReference->getName() + " using material " + - mMaterial->getName() + " contains many bones. The amount of " - "instances per batch is very low. Performance benefits will " - "be minimal, if any. It might be even slower!", - LML_NORMAL ); - } - - return retVal; - } - } - } - - //Reaching here means material is supported, but malformed - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Material '" + mMaterial->getName() + "' is malformed for this instancing technique", - "InstanceBatchShader::calculateMaxNumInstances"); - } - - //Reaching here the material is just unsupported. - - return 0; - } - //----------------------------------------------------------------------- - void InstanceBatchShader::buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ) - { - if( mMeshReference->hasSkeleton() && !mMeshReference->getSkeleton().isNull() ) - mNumWorldMatrices = mInstancesPerBatch * baseSubMesh->blendIndexToBoneIndexMap.size(); - InstanceBatch::buildFrom( baseSubMesh, renderOperation ); - } - //----------------------------------------------------------------------- - void InstanceBatchShader::setupVertices( const SubMesh* baseSubMesh ) - { - mRenderOperation.vertexData = OGRE_NEW VertexData(); - mRemoveOwnVertexData = true; //Raise flag to remove our own vertex data in the end (not always needed) - - VertexData *thisVertexData = mRenderOperation.vertexData; - VertexData *baseVertexData = baseSubMesh->vertexData; - - thisVertexData->vertexStart = 0; - thisVertexData->vertexCount = baseVertexData->vertexCount * mInstancesPerBatch; - - HardwareBufferManager::getSingleton().destroyVertexDeclaration( thisVertexData->vertexDeclaration ); - thisVertexData->vertexDeclaration = baseVertexData->vertexDeclaration->clone(); - - if( mMeshReference->hasSkeleton() && !mMeshReference->getSkeleton().isNull() ) - { - //Building hw skinned batches follow a different path - setupHardwareSkinned( baseSubMesh, thisVertexData, baseVertexData ); - return; - } - - //TODO: Can't we, instead of using another source, put the index ID in the same source? - thisVertexData->vertexDeclaration->addElement( - thisVertexData->vertexDeclaration->getMaxSource() + 1, 0, - VET_UBYTE4, VES_BLEND_INDICES ); - - - for( size_t i=0; ivertexDeclaration->getMaxSource(); ++i ) - { - //Create our own vertex buffer - HardwareVertexBufferSharedPtr vertexBuffer = - HardwareBufferManager::getSingleton().createVertexBuffer( - thisVertexData->vertexDeclaration->getVertexSize(i), - thisVertexData->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - thisVertexData->vertexBufferBinding->setBinding( i, vertexBuffer ); - - //Grab the base submesh data - HardwareVertexBufferSharedPtr baseVertexBuffer = - baseVertexData->vertexBufferBinding->getBuffer(i); - - char* thisBuf = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - char* baseBuf = static_cast(baseVertexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); - - //Copy and repeat - for( size_t j=0; jvertexCount * - baseVertexData->vertexDeclaration->getVertexSize(i); - memcpy( thisBuf + j * sizeOfBuffer, baseBuf, sizeOfBuffer ); - } - - baseVertexBuffer->unlock(); - vertexBuffer->unlock(); - } - - { - //Now create the vertices "index ID" to individualize each instance - const unsigned short lastSource = thisVertexData->vertexDeclaration->getMaxSource(); - HardwareVertexBufferSharedPtr vertexBuffer = - HardwareBufferManager::getSingleton().createVertexBuffer( - thisVertexData->vertexDeclaration->getVertexSize( lastSource ), - thisVertexData->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - thisVertexData->vertexBufferBinding->setBinding( lastSource, vertexBuffer ); - - char* thisBuf = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - for( size_t j=0; jvertexCount; ++k ) - { - *thisBuf++ = j; - *thisBuf++ = j; - *thisBuf++ = j; - *thisBuf++ = j; - } - } - - vertexBuffer->unlock(); - } - } - //----------------------------------------------------------------------- - void InstanceBatchShader::setupIndices( const SubMesh* baseSubMesh ) - { - mRenderOperation.indexData = OGRE_NEW IndexData(); - mRemoveOwnIndexData = true; //Raise flag to remove our own index data in the end (not always needed) - - IndexData *thisIndexData = mRenderOperation.indexData; - IndexData *baseIndexData = baseSubMesh->indexData; - - thisIndexData->indexStart = 0; - thisIndexData->indexCount = baseIndexData->indexCount * mInstancesPerBatch; - - //TODO: Check numVertices is below max supported by GPU - HardwareIndexBuffer::IndexType indexType = HardwareIndexBuffer::IT_16BIT; - if( mRenderOperation.vertexData->vertexCount > 65535 ) - indexType = HardwareIndexBuffer::IT_32BIT; - thisIndexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( - indexType, thisIndexData->indexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - - void *buf = thisIndexData->indexBuffer->lock( HardwareBuffer::HBL_DISCARD ); - void const *baseBuf = baseIndexData->indexBuffer->lock( HardwareBuffer::HBL_READ_ONLY ); - - uint16 *thisBuf16 = static_cast(buf); - uint32 *thisBuf32 = static_cast(buf); - - for( size_t i=0; ivertexCount / mInstancesPerBatch; - - uint16 const *initBuf16 = static_cast(baseBuf); - uint32 const *initBuf32 = static_cast(baseBuf); - - for( size_t j=0; jindexCount; ++j ) - { - uint32 originalVal; - if( baseSubMesh->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT ) - originalVal = *initBuf16++; - else - originalVal = *initBuf32++; - - if( indexType == HardwareIndexBuffer::IT_16BIT ) - *thisBuf16++ = static_cast(originalVal) + vertexOffset; - else - *thisBuf32++ = static_cast(originalVal + vertexOffset); - } - } - - baseIndexData->indexBuffer->unlock(); - thisIndexData->indexBuffer->unlock(); - } - //----------------------------------------------------------------------- - void InstanceBatchShader::setupHardwareSkinned( const SubMesh* baseSubMesh, VertexData *thisVertexData, - VertexData *baseVertexData ) - { - const size_t numBones = baseSubMesh->blendIndexToBoneIndexMap.size(); - mNumWorldMatrices = mInstancesPerBatch * numBones; - - for( size_t i=0; i<=thisVertexData->vertexDeclaration->getMaxSource(); ++i ) - { - //Create our own vertex buffer - HardwareVertexBufferSharedPtr vertexBuffer = - HardwareBufferManager::getSingleton().createVertexBuffer( - thisVertexData->vertexDeclaration->getVertexSize(i), - thisVertexData->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - thisVertexData->vertexBufferBinding->setBinding( i, vertexBuffer ); - - VertexDeclaration::VertexElementList veList = - thisVertexData->vertexDeclaration->findElementsBySource(i); - - //Grab the base submesh data - HardwareVertexBufferSharedPtr baseVertexBuffer = - baseVertexData->vertexBufferBinding->getBuffer(i); - - char* thisBuf = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - char* baseBuf = static_cast(baseVertexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); - char *startBuf = baseBuf; - - //Copy and repeat - for( size_t j=0; jvertexCount; ++k ) - { - VertexDeclaration::VertexElementList::const_iterator it = veList.begin(); - VertexDeclaration::VertexElementList::const_iterator en = veList.end(); - - while( it != en ) - { - switch( it->getSemantic() ) - { - case VES_BLEND_INDICES: - *(thisBuf + it->getOffset() + 0) = *(baseBuf + it->getOffset() + 0) + j * numBones; - *(thisBuf + it->getOffset() + 1) = *(baseBuf + it->getOffset() + 1) + j * numBones; - *(thisBuf + it->getOffset() + 2) = *(baseBuf + it->getOffset() + 2) + j * numBones; - *(thisBuf + it->getOffset() + 3) = *(baseBuf + it->getOffset() + 3) + j * numBones; - break; - default: - memcpy( thisBuf + it->getOffset(), baseBuf + it->getOffset(), it->getSize() ); - break; - } - ++it; - } - thisBuf += baseVertexData->vertexDeclaration->getVertexSize(i); - baseBuf += baseVertexData->vertexDeclaration->getVertexSize(i); - } - } - - baseVertexBuffer->unlock(); - vertexBuffer->unlock(); - } - } - //----------------------------------------------------------------------- - void InstanceBatchShader::getWorldTransforms( Matrix4* xform ) const - { - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - InstancedEntityVec::const_iterator end = mInstancedEntities.end(); - - while( itor != end ) - { - xform += (*itor)->getTransforms( xform ); - ++itor; - } - } - //----------------------------------------------------------------------- - unsigned short InstanceBatchShader::getNumWorldTransforms(void) const - { - return mNumWorldMatrices; - } + { + const GpuProgramParameters::AutoConstantEntry *entry = + vertexParam->_findRawAutoConstantEntryFloat( constDef.physicalIndex ); + if( entry && (entry->paramType == GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4 || entry->paramType == GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4)) + { + //Material is correctly done! + size_t arraySize = constDef.arraySize; + + //Deal with GL "hacky" way of doing 4x3 matrices + if(entry->paramType == GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4 && constDef.constType == GCT_FLOAT4) + arraySize /= 3; + else if(entry->paramType == GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4 && constDef.constType == GCT_FLOAT4) + arraySize /= 2; + + //Check the num of arrays + size_t retVal = arraySize / numBones; + + if( flags & IM_USE16BIT ) + { + if( baseSubMesh->vertexData->vertexCount * retVal > 0xFFFF ) + retVal = 0xFFFF / baseSubMesh->vertexData->vertexCount; + } + + if((retVal < 3 && entry->paramType == GpuProgramParameters::ACT_WORLD_MATRIX_ARRAY_3x4) || + (retVal < 2 && entry->paramType == GpuProgramParameters::ACT_WORLD_DUALQUATERNION_ARRAY_2x4)) + { + LogManager::getSingleton().logMessage( "InstanceBatchShader: Mesh " + + mMeshReference->getName() + " using material " + + mMaterial->getName() + " contains many bones. The amount of " + "instances per batch is very low. Performance benefits will " + "be minimal, if any. It might be even slower!", + LML_NORMAL ); + } + + return retVal; + } + } + } + + //Reaching here means material is supported, but malformed + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Material '" + mMaterial->getName() + "' is malformed for this instancing technique", + "InstanceBatchShader::calculateMaxNumInstances"); + } + + //Reaching here the material is just unsupported. + + return 0; + } + //----------------------------------------------------------------------- + void InstanceBatchShader::buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ) + { + if( mMeshReference->hasSkeleton() && !mMeshReference->getSkeleton().isNull() ) + mNumWorldMatrices = mInstancesPerBatch * baseSubMesh->blendIndexToBoneIndexMap.size(); + InstanceBatch::buildFrom( baseSubMesh, renderOperation ); + } + //----------------------------------------------------------------------- + void InstanceBatchShader::setupVertices( const SubMesh* baseSubMesh ) + { + mRenderOperation.vertexData = OGRE_NEW VertexData(); + mRemoveOwnVertexData = true; //Raise flag to remove our own vertex data in the end (not always needed) + + VertexData *thisVertexData = mRenderOperation.vertexData; + VertexData *baseVertexData = baseSubMesh->vertexData; + + thisVertexData->vertexStart = 0; + thisVertexData->vertexCount = baseVertexData->vertexCount * mInstancesPerBatch; + + HardwareBufferManager::getSingleton().destroyVertexDeclaration( thisVertexData->vertexDeclaration ); + thisVertexData->vertexDeclaration = baseVertexData->vertexDeclaration->clone(); + + if( mMeshReference->hasSkeleton() && !mMeshReference->getSkeleton().isNull() ) + { + //Building hw skinned batches follow a different path + setupHardwareSkinned( baseSubMesh, thisVertexData, baseVertexData ); + return; + } + + //TODO: Can't we, instead of using another source, put the index ID in the same source? + thisVertexData->vertexDeclaration->addElement( + thisVertexData->vertexDeclaration->getMaxSource() + 1, 0, + VET_UBYTE4, VES_BLEND_INDICES ); + + + for( size_t i=0; ivertexDeclaration->getMaxSource(); ++i ) + { + //Create our own vertex buffer + HardwareVertexBufferSharedPtr vertexBuffer = + HardwareBufferManager::getSingleton().createVertexBuffer( + thisVertexData->vertexDeclaration->getVertexSize(i), + thisVertexData->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + thisVertexData->vertexBufferBinding->setBinding( i, vertexBuffer ); + + //Grab the base submesh data + HardwareVertexBufferSharedPtr baseVertexBuffer = + baseVertexData->vertexBufferBinding->getBuffer(i); + + char* thisBuf = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + char* baseBuf = static_cast(baseVertexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); + + //Copy and repeat + for( size_t j=0; jvertexCount * + baseVertexData->vertexDeclaration->getVertexSize(i); + memcpy( thisBuf + j * sizeOfBuffer, baseBuf, sizeOfBuffer ); + } + + baseVertexBuffer->unlock(); + vertexBuffer->unlock(); + } + + { + //Now create the vertices "index ID" to individualize each instance + const unsigned short lastSource = thisVertexData->vertexDeclaration->getMaxSource(); + HardwareVertexBufferSharedPtr vertexBuffer = + HardwareBufferManager::getSingleton().createVertexBuffer( + thisVertexData->vertexDeclaration->getVertexSize( lastSource ), + thisVertexData->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + thisVertexData->vertexBufferBinding->setBinding( lastSource, vertexBuffer ); + + char* thisBuf = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + for( size_t j=0; jvertexCount; ++k ) + { + *thisBuf++ = j; + *thisBuf++ = j; + *thisBuf++ = j; + *thisBuf++ = j; + } + } + + vertexBuffer->unlock(); + } + } + //----------------------------------------------------------------------- + void InstanceBatchShader::setupIndices( const SubMesh* baseSubMesh ) + { + mRenderOperation.indexData = OGRE_NEW IndexData(); + mRemoveOwnIndexData = true; //Raise flag to remove our own index data in the end (not always needed) + + IndexData *thisIndexData = mRenderOperation.indexData; + IndexData *baseIndexData = baseSubMesh->indexData; + + thisIndexData->indexStart = 0; + thisIndexData->indexCount = baseIndexData->indexCount * mInstancesPerBatch; + + //TODO: Check numVertices is below max supported by GPU + HardwareIndexBuffer::IndexType indexType = HardwareIndexBuffer::IT_16BIT; + if( mRenderOperation.vertexData->vertexCount > 65535 ) + indexType = HardwareIndexBuffer::IT_32BIT; + thisIndexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( + indexType, thisIndexData->indexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + + void *buf = thisIndexData->indexBuffer->lock( HardwareBuffer::HBL_DISCARD ); + void const *baseBuf = baseIndexData->indexBuffer->lock( HardwareBuffer::HBL_READ_ONLY ); + + uint16 *thisBuf16 = static_cast(buf); + uint32 *thisBuf32 = static_cast(buf); + + for( size_t i=0; ivertexCount / mInstancesPerBatch; + + uint16 const *initBuf16 = static_cast(baseBuf); + uint32 const *initBuf32 = static_cast(baseBuf); + + for( size_t j=0; jindexCount; ++j ) + { + uint32 originalVal; + if( baseSubMesh->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT ) + originalVal = *initBuf16++; + else + originalVal = *initBuf32++; + + if( indexType == HardwareIndexBuffer::IT_16BIT ) + *thisBuf16++ = static_cast(originalVal) + vertexOffset; + else + *thisBuf32++ = static_cast(originalVal + vertexOffset); + } + } + + baseIndexData->indexBuffer->unlock(); + thisIndexData->indexBuffer->unlock(); + } + //----------------------------------------------------------------------- + void InstanceBatchShader::setupHardwareSkinned( const SubMesh* baseSubMesh, VertexData *thisVertexData, + VertexData *baseVertexData ) + { + const size_t numBones = baseSubMesh->blendIndexToBoneIndexMap.size(); + mNumWorldMatrices = mInstancesPerBatch * numBones; + + for( size_t i=0; i<=thisVertexData->vertexDeclaration->getMaxSource(); ++i ) + { + //Create our own vertex buffer + HardwareVertexBufferSharedPtr vertexBuffer = + HardwareBufferManager::getSingleton().createVertexBuffer( + thisVertexData->vertexDeclaration->getVertexSize(i), + thisVertexData->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + thisVertexData->vertexBufferBinding->setBinding( i, vertexBuffer ); + + VertexDeclaration::VertexElementList veList = + thisVertexData->vertexDeclaration->findElementsBySource(i); + + //Grab the base submesh data + HardwareVertexBufferSharedPtr baseVertexBuffer = + baseVertexData->vertexBufferBinding->getBuffer(i); + + char* thisBuf = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + char* baseBuf = static_cast(baseVertexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); + char *startBuf = baseBuf; + + //Copy and repeat + for( size_t j=0; jvertexCount; ++k ) + { + VertexDeclaration::VertexElementList::const_iterator it = veList.begin(); + VertexDeclaration::VertexElementList::const_iterator en = veList.end(); + + while( it != en ) + { + switch( it->getSemantic() ) + { + case VES_BLEND_INDICES: + *(thisBuf + it->getOffset() + 0) = *(baseBuf + it->getOffset() + 0) + j * numBones; + *(thisBuf + it->getOffset() + 1) = *(baseBuf + it->getOffset() + 1) + j * numBones; + *(thisBuf + it->getOffset() + 2) = *(baseBuf + it->getOffset() + 2) + j * numBones; + *(thisBuf + it->getOffset() + 3) = *(baseBuf + it->getOffset() + 3) + j * numBones; + break; + default: + memcpy( thisBuf + it->getOffset(), baseBuf + it->getOffset(), it->getSize() ); + break; + } + ++it; + } + thisBuf += baseVertexData->vertexDeclaration->getVertexSize(i); + baseBuf += baseVertexData->vertexDeclaration->getVertexSize(i); + } + } + + baseVertexBuffer->unlock(); + vertexBuffer->unlock(); + } + } + //----------------------------------------------------------------------- + void InstanceBatchShader::getWorldTransforms( Matrix4* xform ) const + { + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + InstancedEntityVec::const_iterator end = mInstancedEntities.end(); + + while( itor != end ) + { + xform += (*itor)->getTransforms( xform ); + ++itor; + } + } + //----------------------------------------------------------------------- + unsigned short InstanceBatchShader::getNumWorldTransforms(void) const + { + return mNumWorldMatrices; + } } diff --git a/OgreMain/src/OgreInstanceBatchVTF.cpp b/OgreMain/src/OgreInstanceBatchVTF.cpp index aa07a63e1c9..2c9632e1fc2 100644 --- a/OgreMain/src/OgreInstanceBatchVTF.cpp +++ b/OgreMain/src/OgreInstanceBatchVTF.cpp @@ -40,727 +40,727 @@ THE SOFTWARE. namespace Ogre { - static const uint16 c_maxTexWidth = 4096; - static const uint16 c_maxTexHeight = 4096; - - BaseInstanceBatchVTF::BaseInstanceBatchVTF( InstanceManager *creator, MeshPtr &meshReference, - const MaterialPtr &material, size_t instancesPerBatch, - const Mesh::IndexMap *indexToBoneMap, const String &batchName) : - InstanceBatch( creator, meshReference, material, instancesPerBatch, - indexToBoneMap, batchName ), + static const uint16 c_maxTexWidth = 4096; + static const uint16 c_maxTexHeight = 4096; + + BaseInstanceBatchVTF::BaseInstanceBatchVTF( InstanceManager *creator, MeshPtr &meshReference, + const MaterialPtr &material, size_t instancesPerBatch, + const Mesh::IndexMap *indexToBoneMap, const String &batchName) : + InstanceBatch( creator, meshReference, material, instancesPerBatch, + indexToBoneMap, batchName ), mMatricesPerInstance(0), - mNumWorldMatrices( instancesPerBatch ), - mWidthFloatsPadding( 0 ), - mMaxFloatsPerLine( std::numeric_limits::max() ), - mRowLength(3), - mWeightCount(1), - mTempTransformsArray3x4(0), - mUseBoneMatrixLookup(false), - mMaxLookupTableInstances(16), - mUseBoneDualQuaternions(false), - mForceOneWeight(false), - mUseOneWeight(false) - { - cloneMaterial( mMaterial ); - } - - BaseInstanceBatchVTF::~BaseInstanceBatchVTF() - { - //Remove cloned caster materials (if any) - Material::TechniqueIterator techItor = mMaterial->getTechniqueIterator(); - while( techItor.hasMoreElements() ) - { - Technique *technique = techItor.getNext(); - - if( !technique->getShadowCasterMaterial().isNull() ) - MaterialManager::getSingleton().remove( technique->getShadowCasterMaterial()->getName() ); - } - - //Remove cloned material - MaterialManager::getSingleton().remove( mMaterial->getName() ); - - //Remove the VTF texture - if( !mMatrixTexture.isNull() ) - TextureManager::getSingleton().remove( mMatrixTexture->getName() ); - - OGRE_FREE(mTempTransformsArray3x4, MEMCATEGORY_GENERAL); - } - - //----------------------------------------------------------------------- - void BaseInstanceBatchVTF::buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ) - { - if (useBoneMatrixLookup()) - { - //when using bone matrix lookup resource are not shared - // - //Future implementation: while the instance vertex buffer can't be shared - //The texture can be. - // - build(baseSubMesh); - } - else - { - createVertexTexture( baseSubMesh ); - InstanceBatch::buildFrom( baseSubMesh, renderOperation ); - } - } - //----------------------------------------------------------------------- - void BaseInstanceBatchVTF::cloneMaterial( const MaterialPtr &material ) - { - //Used to track down shadow casters, so the same material caster doesn't get cloned twice - typedef map::type MatMap; - MatMap clonedMaterials; - - //We need to clone the material so we can have different textures for each batch. - mMaterial = material->clone( mName + "/VTFMaterial" ); - - //Now do the same with the techniques which have a material shadow caster - Material::TechniqueIterator techItor = material->getTechniqueIterator(); - while( techItor.hasMoreElements() ) - { - Technique *technique = techItor.getNext(); - - if( !technique->getShadowCasterMaterial().isNull() ) - { - const MaterialPtr &casterMat = technique->getShadowCasterMaterial(); - const String &casterName = casterMat->getName(); - - //Was this material already cloned? - MatMap::const_iterator itor = clonedMaterials.find(casterName); - - if( itor == clonedMaterials.end() ) - { - //No? Clone it and track it - MaterialPtr cloned = casterMat->clone( mName + "/VTFMaterialCaster" + - StringConverter::toString(clonedMaterials.size()) ); - technique->setShadowCasterMaterial( cloned ); - clonedMaterials[casterName] = cloned; - } - else - technique->setShadowCasterMaterial( itor->second ); //Reuse the previously cloned mat - } - } - } - //----------------------------------------------------------------------- - void BaseInstanceBatchVTF::retrieveBoneIdx( VertexData *baseVertexData, HWBoneIdxVec &outBoneIdx ) - { - const VertexElement *ve = baseVertexData->vertexDeclaration-> - findElementBySemantic( VES_BLEND_INDICES ); - const VertexElement *veWeights = baseVertexData->vertexDeclaration->findElementBySemantic( VES_BLEND_WEIGHTS ); - - HardwareVertexBufferSharedPtr buff = baseVertexData->vertexBufferBinding->getBuffer(ve->getSource()); - char const *baseBuffer = static_cast(buff->lock( HardwareBuffer::HBL_READ_ONLY )); - - for( size_t i=0; ivertexCount; ++i ) - { - float const *pWeights = reinterpret_cast(baseBuffer + veWeights->getOffset()); - - uint8 biggestWeightIdx = 0; - for( size_t j=1; j< mWeightCount; ++j ) - { - biggestWeightIdx = pWeights[biggestWeightIdx] < pWeights[j] ? j : biggestWeightIdx; - } - - uint8 const *pIndex = reinterpret_cast(baseBuffer + ve->getOffset()); - outBoneIdx[i] = pIndex[biggestWeightIdx]; - - baseBuffer += baseVertexData->vertexDeclaration->getVertexSize(ve->getSource()); - } - - buff->unlock(); - } - - //----------------------------------------------------------------------- - void BaseInstanceBatchVTF::retrieveBoneIdxWithWeights(VertexData *baseVertexData, HWBoneIdxVec &outBoneIdx, HWBoneWgtVec &outBoneWgt) - { - const VertexElement *ve = baseVertexData->vertexDeclaration->findElementBySemantic( VES_BLEND_INDICES ); - const VertexElement *veWeights = baseVertexData->vertexDeclaration->findElementBySemantic( VES_BLEND_WEIGHTS ); - - HardwareVertexBufferSharedPtr buff = baseVertexData->vertexBufferBinding->getBuffer(ve->getSource()); - char const *baseBuffer = static_cast(buff->lock( HardwareBuffer::HBL_READ_ONLY )); - - for( size_t i=0; ivertexCount * mWeightCount; i += mWeightCount) - { - float const *pWeights = reinterpret_cast(baseBuffer + veWeights->getOffset()); - uint8 const *pIndex = reinterpret_cast(baseBuffer + ve->getOffset()); - - float weightMagnitude = 0.0f; - for( size_t j=0; j < mWeightCount; ++j ) - { - outBoneWgt[i+j] = pWeights[j]; - weightMagnitude += pWeights[j]; - outBoneIdx[i+j] = pIndex[j]; - } - - //Normalize the bone weights so they add to one - for(size_t j=0; j < mWeightCount; ++j) - { - outBoneWgt[i+j] /= weightMagnitude; - } - - baseBuffer += baseVertexData->vertexDeclaration->getVertexSize(ve->getSource()); - } - - buff->unlock(); - } - - //----------------------------------------------------------------------- - void BaseInstanceBatchVTF::setupMaterialToUseVTF( TextureType textureType, MaterialPtr &material ) - { - Material::TechniqueIterator techItor = material->getTechniqueIterator(); - while( techItor.hasMoreElements() ) - { - Technique *technique = techItor.getNext(); - Technique::PassIterator passItor = technique->getPassIterator(); - - while( passItor.hasMoreElements() ) - { - bool bTexUnitFound = false; - - Pass *pass = passItor.getNext(); - Pass::TextureUnitStateIterator texUnitItor = pass->getTextureUnitStateIterator(); - - while( texUnitItor.hasMoreElements() && !bTexUnitFound ) - { - TextureUnitState *texUnit = texUnitItor.getNext(); - - if( texUnit->getName() == "InstancingVTF" ) - { - texUnit->setTextureName( mMatrixTexture->getName(), textureType ); - texUnit->setTextureFiltering( TFO_NONE ); - texUnit->setBindingType( TextureUnitState::BT_VERTEX ); - } - } - } - - if( !technique->getShadowCasterMaterial().isNull() ) - { - MaterialPtr matCaster = technique->getShadowCasterMaterial(); - setupMaterialToUseVTF( textureType, matCaster ); - } - } - } - //----------------------------------------------------------------------- - void BaseInstanceBatchVTF::createVertexTexture( const SubMesh* baseSubMesh ) - { - /* - TODO: Find a way to retrieve max texture resolution, - http://www.ogre3d.org/forums/viewtopic.php?t=38305 - - Currently assuming it's 4096x4096, which is a safe bet for any hardware with decent VTF*/ - - size_t uniqueAnimations = mInstancesPerBatch; - if (useBoneMatrixLookup()) - { - uniqueAnimations = std::min(getMaxLookupTableInstances(), uniqueAnimations); - } - mMatricesPerInstance = std::max( 1, baseSubMesh->blendIndexToBoneIndexMap.size() ); - - if(mUseBoneDualQuaternions && !mTempTransformsArray3x4) - { - mTempTransformsArray3x4 = OGRE_ALLOC_T(float, mMatricesPerInstance * 3 * 4, MEMCATEGORY_GENERAL); - } - - mNumWorldMatrices = uniqueAnimations * mMatricesPerInstance; - - //Calculate the width & height required to hold all the matrices. Start by filling the width - //first (i.e. 4096x1 4096x2 4096x3, etc) - - size_t texWidth = std::min( mNumWorldMatrices * mRowLength, c_maxTexWidth ); - size_t maxUsableWidth = texWidth; - if( matricesTogetherPerRow() ) - { - //The technique requires all matrices from the same instance in the same row - //i.e. 4094 -> 4095 -> skip 4096 -> 0 (next row) contains data from a new instance - mWidthFloatsPadding = texWidth % (mMatricesPerInstance * mRowLength); - - if( mWidthFloatsPadding ) - { - mMaxFloatsPerLine = texWidth - mWidthFloatsPadding; - - maxUsableWidth = mMaxFloatsPerLine; - - //Values are in pixels, convert them to floats (1 pixel = 4 floats) - mWidthFloatsPadding *= 4; - mMaxFloatsPerLine *= 4; - } - } - - size_t texHeight = mNumWorldMatrices * mRowLength / maxUsableWidth; - - if( (mNumWorldMatrices * mRowLength) % maxUsableWidth ) - texHeight += 1; - - //Don't use 1D textures, as OGL goes crazy because the shader should be calling texture1D()... - //TextureType texType = texHeight == 1 ? TEX_TYPE_1D : TEX_TYPE_2D; - TextureType texType = TEX_TYPE_2D; - - mMatrixTexture = TextureManager::getSingleton().createManual( - mName + "/VTF", mMeshReference->getGroup(), texType, - (uint)texWidth, (uint)texHeight, - 0, PF_FLOAT32_RGBA, TU_DYNAMIC_WRITE_ONLY_DISCARDABLE ); - - //Set our cloned material to use this custom texture! - setupMaterialToUseVTF( texType, mMaterial ); - } - - //----------------------------------------------------------------------- - size_t BaseInstanceBatchVTF::convert3x4MatricesToDualQuaternions(float* matrices, size_t numOfMatrices, float* outDualQuaternions) - { - DualQuaternion dQuat; - Matrix4 matrix; - size_t floatsWritten = 0; - - for (size_t m = 0; m < numOfMatrices; ++m) - { - for(int i = 0; i < 3; ++i) - { - for(int b = 0; b < 4; ++b) - { - matrix[i][b] = *matrices++; - } - } - - matrix[3][0] = 0; - matrix[3][1] = 0; - matrix[3][2] = 0; - matrix[3][3] = 1; - - dQuat.fromTransformationMatrix(matrix); - - //Copy the 2x4 matrix - for(int i = 0; i < 8; ++i) - { - *outDualQuaternions++ = static_cast( dQuat[i] ); - ++floatsWritten; - } - } - - return floatsWritten; - } - - //----------------------------------------------------------------------- - void BaseInstanceBatchVTF::updateVertexTexture(void) - { - //Now lock the texture and copy the 4x3 matrices! - mMatrixTexture->getBuffer()->lock( HardwareBuffer::HBL_DISCARD ); - const PixelBox &pixelBox = mMatrixTexture->getBuffer()->getCurrentLock(); - - float *pDest = static_cast(pixelBox.data); - - InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); - InstancedEntityVec::const_iterator end = mInstancedEntities.end(); - - float* transforms; - - //If using dual quaternion skinning, write the transforms to a temporary buffer, - //then convert to dual quaternions, then later write to the pixel buffer - //Otherwise simply write the transforms to the pixel buffer directly - if(mUseBoneDualQuaternions) - { - transforms = mTempTransformsArray3x4; - } - else - { - transforms = pDest; - } - - - while( itor != end ) - { - size_t floatsWritten = (*itor)->getTransforms3x4( transforms ); - - if( mManager->getCameraRelativeRendering() ) - makeMatrixCameraRelative3x4( transforms, floatsWritten ); - - if(mUseBoneDualQuaternions) - { - floatsWritten = convert3x4MatricesToDualQuaternions(transforms, floatsWritten / 12, pDest); - pDest += floatsWritten; - } - else - { - transforms += floatsWritten; - } - - ++itor; - } - - mMatrixTexture->getBuffer()->unlock(); - } - /** update the lookup numbers for entities with shared transforms */ - void BaseInstanceBatchVTF::updateSharedLookupIndexes() - { - if (mTransformSharingDirty) - { - if (useBoneMatrixLookup()) - { - //In each entity update the "transform lookup number" so that: - // 1. All entities sharing the same transformation will share the same unique number - // 2. "transform lookup number" will be numbered from 0 up to getMaxLookupTableInstances - size_t lookupCounter = 0; - typedef map::type MapTransformId; - MapTransformId transformToId; - InstancedEntityVec::const_iterator itEnt = mInstancedEntities.begin(), - itEntEnd = mInstancedEntities.end(); - for(;itEnt != itEntEnd ; ++itEnt) - { - if ((*itEnt)->isInScene()) - { - Matrix4* transformUniqueId = (*itEnt)->mBoneMatrices; - MapTransformId::iterator itLu = transformToId.find(transformUniqueId); - if (itLu == transformToId.end()) - { - itLu = transformToId.insert(MapTransformId::value_type(transformUniqueId,lookupCounter)).first; - ++lookupCounter; - } - (*itEnt)->setTransformLookupNumber(itLu->second); - } - else - { - (*itEnt)->setTransformLookupNumber(0); - } - } - - if (lookupCounter > getMaxLookupTableInstances()) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE,"Number of unique bone matrix states exceeds current limitation.","BaseInstanceBatchVTF::updateSharedLookupIndexes()"); - } - } - - mTransformSharingDirty = false; - } - } - - //----------------------------------------------------------------------- - InstancedEntity* BaseInstanceBatchVTF::generateInstancedEntity(size_t num) - { - InstancedEntity* sharedTransformEntity = NULL; - if ((useBoneMatrixLookup()) && (num >= getMaxLookupTableInstances())) - { - sharedTransformEntity = mInstancedEntities[num % getMaxLookupTableInstances()]; - if (sharedTransformEntity->mSharedTransformEntity) - { - sharedTransformEntity = sharedTransformEntity->mSharedTransformEntity; - } - } - - return OGRE_NEW InstancedEntity(this, static_cast(num), sharedTransformEntity); - } - - - //----------------------------------------------------------------------- - void BaseInstanceBatchVTF::getWorldTransforms( Matrix4* xform ) const - { - *xform = Matrix4::IDENTITY; - } - //----------------------------------------------------------------------- - unsigned short BaseInstanceBatchVTF::getNumWorldTransforms(void) const - { - return 1; - } - //----------------------------------------------------------------------- - void BaseInstanceBatchVTF::_updateRenderQueue(RenderQueue* queue) - { - InstanceBatch::_updateRenderQueue( queue ); - - if( mBoundsUpdated || mDirtyAnimation || mManager->getCameraRelativeRendering() ) - updateVertexTexture(); - - mBoundsUpdated = false; - } - //----------------------------------------------------------------------- - // InstanceBatchVTF - //----------------------------------------------------------------------- - InstanceBatchVTF::InstanceBatchVTF( - InstanceManager *creator, MeshPtr &meshReference, - const MaterialPtr &material, size_t instancesPerBatch, - const Mesh::IndexMap *indexToBoneMap, const String &batchName ) - : BaseInstanceBatchVTF (creator, meshReference, material, - instancesPerBatch, indexToBoneMap, batchName) - { - - } - //----------------------------------------------------------------------- - InstanceBatchVTF::~InstanceBatchVTF() - { - } - //----------------------------------------------------------------------- - void InstanceBatchVTF::setupVertices( const SubMesh* baseSubMesh ) - { - mRenderOperation.vertexData = OGRE_NEW VertexData(); - mRemoveOwnVertexData = true; //Raise flag to remove our own vertex data in the end (not always needed) - - VertexData *thisVertexData = mRenderOperation.vertexData; - VertexData *baseVertexData = baseSubMesh->vertexData; - - thisVertexData->vertexStart = 0; - thisVertexData->vertexCount = baseVertexData->vertexCount * mInstancesPerBatch; - - HardwareBufferManager::getSingleton().destroyVertexDeclaration( thisVertexData->vertexDeclaration ); - thisVertexData->vertexDeclaration = baseVertexData->vertexDeclaration->clone(); - - HWBoneIdxVec hwBoneIdx; - HWBoneWgtVec hwBoneWgt; - - //Blend weights may not be present because HW_VTF does not require to be skeletally animated - const VertexElement *veWeights = baseVertexData->vertexDeclaration-> - findElementBySemantic( VES_BLEND_WEIGHTS ); - if( veWeights ) - { - //One weight is recommended for VTF - mWeightCount = (forceOneWeight() || useOneWeight()) ? - 1 : veWeights->getSize() / sizeof(float); - } - else - { - mWeightCount = 1; - } - - hwBoneIdx.resize( baseVertexData->vertexCount * mWeightCount, 0 ); - - if( mMeshReference->hasSkeleton() && !mMeshReference->getSkeleton().isNull() ) - { - if(mWeightCount > 1) - { - hwBoneWgt.resize( baseVertexData->vertexCount * mWeightCount, 0 ); - retrieveBoneIdxWithWeights(baseVertexData, hwBoneIdx, hwBoneWgt); - } - else - { - retrieveBoneIdx( baseVertexData, hwBoneIdx ); - thisVertexData->vertexDeclaration->removeElement( VES_BLEND_INDICES ); - thisVertexData->vertexDeclaration->removeElement( VES_BLEND_WEIGHTS ); - - thisVertexData->vertexDeclaration->closeGapsInSource(); - } - - } - - for( unsigned short i=0; ivertexDeclaration->getMaxSource()+1; ++i ) - { - //Create our own vertex buffer - HardwareVertexBufferSharedPtr vertexBuffer = - HardwareBufferManager::getSingleton().createVertexBuffer( - thisVertexData->vertexDeclaration->getVertexSize(i), - thisVertexData->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - thisVertexData->vertexBufferBinding->setBinding( i, vertexBuffer ); - - //Grab the base submesh data - HardwareVertexBufferSharedPtr baseVertexBuffer = - baseVertexData->vertexBufferBinding->getBuffer(i); - - char* thisBuf = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - char* baseBuf = static_cast(baseVertexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); - - //Copy and repeat - for( size_t j=0; jvertexCount * - baseVertexData->vertexDeclaration->getVertexSize(i); - memcpy( thisBuf + j * sizeOfBuffer, baseBuf, sizeOfBuffer ); - } - - baseVertexBuffer->unlock(); - vertexBuffer->unlock(); - } - - createVertexTexture( baseSubMesh ); - createVertexSemantics( thisVertexData, baseVertexData, hwBoneIdx, hwBoneWgt); - } - //----------------------------------------------------------------------- - void InstanceBatchVTF::setupIndices( const SubMesh* baseSubMesh ) - { - mRenderOperation.indexData = OGRE_NEW IndexData(); - mRemoveOwnIndexData = true; //Raise flag to remove our own index data in the end (not always needed) - - IndexData *thisIndexData = mRenderOperation.indexData; - IndexData *baseIndexData = baseSubMesh->indexData; - - thisIndexData->indexStart = 0; - thisIndexData->indexCount = baseIndexData->indexCount * mInstancesPerBatch; - - //TODO: Check numVertices is below max supported by GPU - HardwareIndexBuffer::IndexType indexType = HardwareIndexBuffer::IT_16BIT; - if( mRenderOperation.vertexData->vertexCount > 65535 ) - indexType = HardwareIndexBuffer::IT_32BIT; - thisIndexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( - indexType, thisIndexData->indexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - - void *buf = thisIndexData->indexBuffer->lock( HardwareBuffer::HBL_DISCARD ); - void const *baseBuf = baseIndexData->indexBuffer->lock( HardwareBuffer::HBL_READ_ONLY ); - - uint16 *thisBuf16 = static_cast(buf); - uint32 *thisBuf32 = static_cast(buf); - - for( size_t i=0; ivertexCount / mInstancesPerBatch; - - uint16 const *initBuf16 = static_cast(baseBuf); - uint32 const *initBuf32 = static_cast(baseBuf); - - for( size_t j=0; jindexCount; ++j ) - { - uint32 originalVal; - if( baseSubMesh->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT ) - originalVal = *initBuf16++; - else - originalVal = *initBuf32++; - - if( indexType == HardwareIndexBuffer::IT_16BIT ) - *thisBuf16++ = static_cast(originalVal) + vertexOffset; - else - *thisBuf32++ = static_cast(originalVal + vertexOffset); - } - } - - baseIndexData->indexBuffer->unlock(); - thisIndexData->indexBuffer->unlock(); - } - //----------------------------------------------------------------------- - void InstanceBatchVTF::createVertexSemantics( - VertexData *thisVertexData, VertexData *baseVertexData, const HWBoneIdxVec &hwBoneIdx, const HWBoneWgtVec &hwBoneWgt) - { - const size_t texWidth = mMatrixTexture->getWidth(); - const size_t texHeight = mMatrixTexture->getHeight(); - - //Calculate the texel offsets to correct them offline - //Akwardly enough, the offset is needed in OpenGL too - Vector2 texelOffsets; - //RenderSystem *renderSystem = Root::getSingleton().getRenderSystem(); - texelOffsets.x = /*renderSystem->getHorizontalTexelOffset()*/ -0.5f / (float)texWidth; - texelOffsets.y = /*renderSystem->getVerticalTexelOffset()*/ -0.5f / (float)texHeight; - - //Only one weight per vertex is supported. It would not only be complex, but prohibitively slow. - //Put them in a new buffer, since it's 32 bytes aligned :-) - const unsigned short newSource = thisVertexData->vertexDeclaration->getMaxSource() + 1; - size_t maxFloatsPerVector = 4; - size_t offset = 0; - - for(size_t i = 0; i < mWeightCount; i += maxFloatsPerVector / mRowLength) - { - offset += thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, - thisVertexData->vertexDeclaration-> - getNextFreeTextureCoordinate() ).getSize(); - offset += thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, - thisVertexData->vertexDeclaration-> - getNextFreeTextureCoordinate() ).getSize(); - } - - //Add the weights (supports up to four, which is Ogre's limit) - if(mWeightCount > 1) - { - thisVertexData->vertexDeclaration->addElement(newSource, offset, VET_FLOAT4, VES_BLEND_WEIGHTS, - thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); - } - - //Create our own vertex buffer - HardwareVertexBufferSharedPtr vertexBuffer = - HardwareBufferManager::getSingleton().createVertexBuffer( - thisVertexData->vertexDeclaration->getVertexSize(newSource), - thisVertexData->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY ); - thisVertexData->vertexBufferBinding->setBinding( newSource, vertexBuffer ); - - float *thisFloat = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - - //Copy and repeat - for( size_t i=0; ivertexCount * mWeightCount; j += mWeightCount ) - { - size_t numberOfMatricesInLine = 0; - - for(size_t wgtIdx = 0; wgtIdx < mWeightCount; ++wgtIdx) - { - for( size_t k=0; k < mRowLength; ++k) - { - size_t instanceIdx = (hwBoneIdx[j+wgtIdx] + i * mMatricesPerInstance) * mRowLength + k; - //x - *thisFloat++ = ((instanceIdx % texWidth) / (float)texWidth) - (float)texelOffsets.x; - //y - *thisFloat++ = ((instanceIdx / texWidth) / (float)texHeight) - (float)texelOffsets.y; - } - - ++numberOfMatricesInLine; - - //If another matrix can't be fit, we're on another line, or if this is the last weight - if((numberOfMatricesInLine + 1) * mRowLength > maxFloatsPerVector || (wgtIdx+1) == mWeightCount) - { - //Place zeroes in the remaining coordinates - for ( size_t k=mRowLength * numberOfMatricesInLine; k < maxFloatsPerVector; ++k) - { - *thisFloat++ = 0.0f; - *thisFloat++ = 0.0f; - } - - numberOfMatricesInLine = 0; - } - } - - //Don't need to write weights if there is only one - if(mWeightCount > 1) - { - //Write the weights - for(size_t wgtIdx = 0; wgtIdx < mWeightCount; ++wgtIdx) - { - *thisFloat++ = hwBoneWgt[j+wgtIdx]; - } - - //Fill the rest of the line with zeros - for(size_t wgtIdx = mWeightCount; wgtIdx < maxFloatsPerVector; ++wgtIdx) - { - *thisFloat++ = 0.0f; - } - } - } - } - - vertexBuffer->unlock(); - - } - //----------------------------------------------------------------------- - size_t InstanceBatchVTF::calculateMaxNumInstances( - const SubMesh *baseSubMesh, uint16 flags ) const - { - size_t retVal = 0; - - RenderSystem *renderSystem = Root::getSingleton().getRenderSystem(); - const RenderSystemCapabilities *capabilities = renderSystem->getCapabilities(); - - //VTF must be supported - if( capabilities->hasCapability( RSC_VERTEX_TEXTURE_FETCH ) ) - { - //TODO: Check PF_FLOAT32_RGBA is supported (should be, since it was the 1st one) - const size_t numBones = std::max( 1, baseSubMesh->blendIndexToBoneIndexMap.size() ); - retVal = c_maxTexWidth * c_maxTexHeight / mRowLength / numBones; - - if( flags & IM_USE16BIT ) - { - if( baseSubMesh->vertexData->vertexCount * retVal > 0xFFFF ) - retVal = 0xFFFF / baseSubMesh->vertexData->vertexCount; - } - - if( flags & IM_VTFBESTFIT ) - { - const size_t instancesPerBatch = std::min( retVal, mInstancesPerBatch ); - //Do the same as in createVertexTexture() - const size_t numWorldMatrices = instancesPerBatch * numBones; - - size_t texWidth = std::min( numWorldMatrices * mRowLength, c_maxTexWidth ); - size_t texHeight = numWorldMatrices * mRowLength / c_maxTexWidth; - - const size_t remainder = (numWorldMatrices * mRowLength) % c_maxTexWidth; - - if( remainder && texHeight > 0 ) - retVal = static_cast(texWidth * texHeight / (float)mRowLength / (float)(numBones)); - } - } - - return retVal; - - } + mNumWorldMatrices( instancesPerBatch ), + mWidthFloatsPadding( 0 ), + mMaxFloatsPerLine( std::numeric_limits::max() ), + mRowLength(3), + mWeightCount(1), + mTempTransformsArray3x4(0), + mUseBoneMatrixLookup(false), + mMaxLookupTableInstances(16), + mUseBoneDualQuaternions(false), + mForceOneWeight(false), + mUseOneWeight(false) + { + cloneMaterial( mMaterial ); + } + + BaseInstanceBatchVTF::~BaseInstanceBatchVTF() + { + //Remove cloned caster materials (if any) + Material::TechniqueIterator techItor = mMaterial->getTechniqueIterator(); + while( techItor.hasMoreElements() ) + { + Technique *technique = techItor.getNext(); + + if( !technique->getShadowCasterMaterial().isNull() ) + MaterialManager::getSingleton().remove( technique->getShadowCasterMaterial()->getName() ); + } + + //Remove cloned material + MaterialManager::getSingleton().remove( mMaterial->getName() ); + + //Remove the VTF texture + if( !mMatrixTexture.isNull() ) + TextureManager::getSingleton().remove( mMatrixTexture->getName() ); + + OGRE_FREE(mTempTransformsArray3x4, MEMCATEGORY_GENERAL); + } + + //----------------------------------------------------------------------- + void BaseInstanceBatchVTF::buildFrom( const SubMesh *baseSubMesh, const RenderOperation &renderOperation ) + { + if (useBoneMatrixLookup()) + { + //when using bone matrix lookup resource are not shared + // + //Future implementation: while the instance vertex buffer can't be shared + //The texture can be. + // + build(baseSubMesh); + } + else + { + createVertexTexture( baseSubMesh ); + InstanceBatch::buildFrom( baseSubMesh, renderOperation ); + } + } + //----------------------------------------------------------------------- + void BaseInstanceBatchVTF::cloneMaterial( const MaterialPtr &material ) + { + //Used to track down shadow casters, so the same material caster doesn't get cloned twice + typedef map::type MatMap; + MatMap clonedMaterials; + + //We need to clone the material so we can have different textures for each batch. + mMaterial = material->clone( mName + "/VTFMaterial" ); + + //Now do the same with the techniques which have a material shadow caster + Material::TechniqueIterator techItor = material->getTechniqueIterator(); + while( techItor.hasMoreElements() ) + { + Technique *technique = techItor.getNext(); + + if( !technique->getShadowCasterMaterial().isNull() ) + { + const MaterialPtr &casterMat = technique->getShadowCasterMaterial(); + const String &casterName = casterMat->getName(); + + //Was this material already cloned? + MatMap::const_iterator itor = clonedMaterials.find(casterName); + + if( itor == clonedMaterials.end() ) + { + //No? Clone it and track it + MaterialPtr cloned = casterMat->clone( mName + "/VTFMaterialCaster" + + StringConverter::toString(clonedMaterials.size()) ); + technique->setShadowCasterMaterial( cloned ); + clonedMaterials[casterName] = cloned; + } + else + technique->setShadowCasterMaterial( itor->second ); //Reuse the previously cloned mat + } + } + } + //----------------------------------------------------------------------- + void BaseInstanceBatchVTF::retrieveBoneIdx( VertexData *baseVertexData, HWBoneIdxVec &outBoneIdx ) + { + const VertexElement *ve = baseVertexData->vertexDeclaration-> + findElementBySemantic( VES_BLEND_INDICES ); + const VertexElement *veWeights = baseVertexData->vertexDeclaration->findElementBySemantic( VES_BLEND_WEIGHTS ); + + HardwareVertexBufferSharedPtr buff = baseVertexData->vertexBufferBinding->getBuffer(ve->getSource()); + char const *baseBuffer = static_cast(buff->lock( HardwareBuffer::HBL_READ_ONLY )); + + for( size_t i=0; ivertexCount; ++i ) + { + float const *pWeights = reinterpret_cast(baseBuffer + veWeights->getOffset()); + + uint8 biggestWeightIdx = 0; + for( size_t j=1; j< mWeightCount; ++j ) + { + biggestWeightIdx = pWeights[biggestWeightIdx] < pWeights[j] ? j : biggestWeightIdx; + } + + uint8 const *pIndex = reinterpret_cast(baseBuffer + ve->getOffset()); + outBoneIdx[i] = pIndex[biggestWeightIdx]; + + baseBuffer += baseVertexData->vertexDeclaration->getVertexSize(ve->getSource()); + } + + buff->unlock(); + } + + //----------------------------------------------------------------------- + void BaseInstanceBatchVTF::retrieveBoneIdxWithWeights(VertexData *baseVertexData, HWBoneIdxVec &outBoneIdx, HWBoneWgtVec &outBoneWgt) + { + const VertexElement *ve = baseVertexData->vertexDeclaration->findElementBySemantic( VES_BLEND_INDICES ); + const VertexElement *veWeights = baseVertexData->vertexDeclaration->findElementBySemantic( VES_BLEND_WEIGHTS ); + + HardwareVertexBufferSharedPtr buff = baseVertexData->vertexBufferBinding->getBuffer(ve->getSource()); + char const *baseBuffer = static_cast(buff->lock( HardwareBuffer::HBL_READ_ONLY )); + + for( size_t i=0; ivertexCount * mWeightCount; i += mWeightCount) + { + float const *pWeights = reinterpret_cast(baseBuffer + veWeights->getOffset()); + uint8 const *pIndex = reinterpret_cast(baseBuffer + ve->getOffset()); + + float weightMagnitude = 0.0f; + for( size_t j=0; j < mWeightCount; ++j ) + { + outBoneWgt[i+j] = pWeights[j]; + weightMagnitude += pWeights[j]; + outBoneIdx[i+j] = pIndex[j]; + } + + //Normalize the bone weights so they add to one + for(size_t j=0; j < mWeightCount; ++j) + { + outBoneWgt[i+j] /= weightMagnitude; + } + + baseBuffer += baseVertexData->vertexDeclaration->getVertexSize(ve->getSource()); + } + + buff->unlock(); + } + + //----------------------------------------------------------------------- + void BaseInstanceBatchVTF::setupMaterialToUseVTF( TextureType textureType, MaterialPtr &material ) + { + Material::TechniqueIterator techItor = material->getTechniqueIterator(); + while( techItor.hasMoreElements() ) + { + Technique *technique = techItor.getNext(); + Technique::PassIterator passItor = technique->getPassIterator(); + + while( passItor.hasMoreElements() ) + { + bool bTexUnitFound = false; + + Pass *pass = passItor.getNext(); + Pass::TextureUnitStateIterator texUnitItor = pass->getTextureUnitStateIterator(); + + while( texUnitItor.hasMoreElements() && !bTexUnitFound ) + { + TextureUnitState *texUnit = texUnitItor.getNext(); + + if( texUnit->getName() == "InstancingVTF" ) + { + texUnit->setTextureName( mMatrixTexture->getName(), textureType ); + texUnit->setTextureFiltering( TFO_NONE ); + texUnit->setBindingType( TextureUnitState::BT_VERTEX ); + } + } + } + + if( !technique->getShadowCasterMaterial().isNull() ) + { + MaterialPtr matCaster = technique->getShadowCasterMaterial(); + setupMaterialToUseVTF( textureType, matCaster ); + } + } + } + //----------------------------------------------------------------------- + void BaseInstanceBatchVTF::createVertexTexture( const SubMesh* baseSubMesh ) + { + /* + TODO: Find a way to retrieve max texture resolution, + http://www.ogre3d.org/forums/viewtopic.php?t=38305 + + Currently assuming it's 4096x4096, which is a safe bet for any hardware with decent VTF*/ + + size_t uniqueAnimations = mInstancesPerBatch; + if (useBoneMatrixLookup()) + { + uniqueAnimations = std::min(getMaxLookupTableInstances(), uniqueAnimations); + } + mMatricesPerInstance = std::max( 1, baseSubMesh->blendIndexToBoneIndexMap.size() ); + + if(mUseBoneDualQuaternions && !mTempTransformsArray3x4) + { + mTempTransformsArray3x4 = OGRE_ALLOC_T(float, mMatricesPerInstance * 3 * 4, MEMCATEGORY_GENERAL); + } + + mNumWorldMatrices = uniqueAnimations * mMatricesPerInstance; + + //Calculate the width & height required to hold all the matrices. Start by filling the width + //first (i.e. 4096x1 4096x2 4096x3, etc) + + size_t texWidth = std::min( mNumWorldMatrices * mRowLength, c_maxTexWidth ); + size_t maxUsableWidth = texWidth; + if( matricesTogetherPerRow() ) + { + //The technique requires all matrices from the same instance in the same row + //i.e. 4094 -> 4095 -> skip 4096 -> 0 (next row) contains data from a new instance + mWidthFloatsPadding = texWidth % (mMatricesPerInstance * mRowLength); + + if( mWidthFloatsPadding ) + { + mMaxFloatsPerLine = texWidth - mWidthFloatsPadding; + + maxUsableWidth = mMaxFloatsPerLine; + + //Values are in pixels, convert them to floats (1 pixel = 4 floats) + mWidthFloatsPadding *= 4; + mMaxFloatsPerLine *= 4; + } + } + + size_t texHeight = mNumWorldMatrices * mRowLength / maxUsableWidth; + + if( (mNumWorldMatrices * mRowLength) % maxUsableWidth ) + texHeight += 1; + + //Don't use 1D textures, as OGL goes crazy because the shader should be calling texture1D()... + //TextureType texType = texHeight == 1 ? TEX_TYPE_1D : TEX_TYPE_2D; + TextureType texType = TEX_TYPE_2D; + + mMatrixTexture = TextureManager::getSingleton().createManual( + mName + "/VTF", mMeshReference->getGroup(), texType, + (uint)texWidth, (uint)texHeight, + 0, PF_FLOAT32_RGBA, TU_DYNAMIC_WRITE_ONLY_DISCARDABLE ); + + //Set our cloned material to use this custom texture! + setupMaterialToUseVTF( texType, mMaterial ); + } + + //----------------------------------------------------------------------- + size_t BaseInstanceBatchVTF::convert3x4MatricesToDualQuaternions(float* matrices, size_t numOfMatrices, float* outDualQuaternions) + { + DualQuaternion dQuat; + Matrix4 matrix; + size_t floatsWritten = 0; + + for (size_t m = 0; m < numOfMatrices; ++m) + { + for(int i = 0; i < 3; ++i) + { + for(int b = 0; b < 4; ++b) + { + matrix[i][b] = *matrices++; + } + } + + matrix[3][0] = 0; + matrix[3][1] = 0; + matrix[3][2] = 0; + matrix[3][3] = 1; + + dQuat.fromTransformationMatrix(matrix); + + //Copy the 2x4 matrix + for(int i = 0; i < 8; ++i) + { + *outDualQuaternions++ = static_cast( dQuat[i] ); + ++floatsWritten; + } + } + + return floatsWritten; + } + + //----------------------------------------------------------------------- + void BaseInstanceBatchVTF::updateVertexTexture(void) + { + //Now lock the texture and copy the 4x3 matrices! + mMatrixTexture->getBuffer()->lock( HardwareBuffer::HBL_DISCARD ); + const PixelBox &pixelBox = mMatrixTexture->getBuffer()->getCurrentLock(); + + float *pDest = static_cast(pixelBox.data); + + InstancedEntityVec::const_iterator itor = mInstancedEntities.begin(); + InstancedEntityVec::const_iterator end = mInstancedEntities.end(); + + float* transforms; + + //If using dual quaternion skinning, write the transforms to a temporary buffer, + //then convert to dual quaternions, then later write to the pixel buffer + //Otherwise simply write the transforms to the pixel buffer directly + if(mUseBoneDualQuaternions) + { + transforms = mTempTransformsArray3x4; + } + else + { + transforms = pDest; + } + + + while( itor != end ) + { + size_t floatsWritten = (*itor)->getTransforms3x4( transforms ); + + if( mManager->getCameraRelativeRendering() ) + makeMatrixCameraRelative3x4( transforms, floatsWritten ); + + if(mUseBoneDualQuaternions) + { + floatsWritten = convert3x4MatricesToDualQuaternions(transforms, floatsWritten / 12, pDest); + pDest += floatsWritten; + } + else + { + transforms += floatsWritten; + } + + ++itor; + } + + mMatrixTexture->getBuffer()->unlock(); + } + /** update the lookup numbers for entities with shared transforms */ + void BaseInstanceBatchVTF::updateSharedLookupIndexes() + { + if (mTransformSharingDirty) + { + if (useBoneMatrixLookup()) + { + //In each entity update the "transform lookup number" so that: + // 1. All entities sharing the same transformation will share the same unique number + // 2. "transform lookup number" will be numbered from 0 up to getMaxLookupTableInstances + size_t lookupCounter = 0; + typedef map::type MapTransformId; + MapTransformId transformToId; + InstancedEntityVec::const_iterator itEnt = mInstancedEntities.begin(), + itEntEnd = mInstancedEntities.end(); + for(;itEnt != itEntEnd ; ++itEnt) + { + if ((*itEnt)->isInScene()) + { + Matrix4* transformUniqueId = (*itEnt)->mBoneMatrices; + MapTransformId::iterator itLu = transformToId.find(transformUniqueId); + if (itLu == transformToId.end()) + { + itLu = transformToId.insert(MapTransformId::value_type(transformUniqueId,lookupCounter)).first; + ++lookupCounter; + } + (*itEnt)->setTransformLookupNumber(itLu->second); + } + else + { + (*itEnt)->setTransformLookupNumber(0); + } + } + + if (lookupCounter > getMaxLookupTableInstances()) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE,"Number of unique bone matrix states exceeds current limitation.","BaseInstanceBatchVTF::updateSharedLookupIndexes()"); + } + } + + mTransformSharingDirty = false; + } + } + + //----------------------------------------------------------------------- + InstancedEntity* BaseInstanceBatchVTF::generateInstancedEntity(size_t num) + { + InstancedEntity* sharedTransformEntity = NULL; + if ((useBoneMatrixLookup()) && (num >= getMaxLookupTableInstances())) + { + sharedTransformEntity = mInstancedEntities[num % getMaxLookupTableInstances()]; + if (sharedTransformEntity->mSharedTransformEntity) + { + sharedTransformEntity = sharedTransformEntity->mSharedTransformEntity; + } + } + + return OGRE_NEW InstancedEntity(this, static_cast(num), sharedTransformEntity); + } + + + //----------------------------------------------------------------------- + void BaseInstanceBatchVTF::getWorldTransforms( Matrix4* xform ) const + { + *xform = Matrix4::IDENTITY; + } + //----------------------------------------------------------------------- + unsigned short BaseInstanceBatchVTF::getNumWorldTransforms(void) const + { + return 1; + } + //----------------------------------------------------------------------- + void BaseInstanceBatchVTF::_updateRenderQueue(RenderQueue* queue) + { + InstanceBatch::_updateRenderQueue( queue ); + + if( mBoundsUpdated || mDirtyAnimation || mManager->getCameraRelativeRendering() ) + updateVertexTexture(); + + mBoundsUpdated = false; + } + //----------------------------------------------------------------------- + // InstanceBatchVTF + //----------------------------------------------------------------------- + InstanceBatchVTF::InstanceBatchVTF( + InstanceManager *creator, MeshPtr &meshReference, + const MaterialPtr &material, size_t instancesPerBatch, + const Mesh::IndexMap *indexToBoneMap, const String &batchName ) + : BaseInstanceBatchVTF (creator, meshReference, material, + instancesPerBatch, indexToBoneMap, batchName) + { + + } + //----------------------------------------------------------------------- + InstanceBatchVTF::~InstanceBatchVTF() + { + } + //----------------------------------------------------------------------- + void InstanceBatchVTF::setupVertices( const SubMesh* baseSubMesh ) + { + mRenderOperation.vertexData = OGRE_NEW VertexData(); + mRemoveOwnVertexData = true; //Raise flag to remove our own vertex data in the end (not always needed) + + VertexData *thisVertexData = mRenderOperation.vertexData; + VertexData *baseVertexData = baseSubMesh->vertexData; + + thisVertexData->vertexStart = 0; + thisVertexData->vertexCount = baseVertexData->vertexCount * mInstancesPerBatch; + + HardwareBufferManager::getSingleton().destroyVertexDeclaration( thisVertexData->vertexDeclaration ); + thisVertexData->vertexDeclaration = baseVertexData->vertexDeclaration->clone(); + + HWBoneIdxVec hwBoneIdx; + HWBoneWgtVec hwBoneWgt; + + //Blend weights may not be present because HW_VTF does not require to be skeletally animated + const VertexElement *veWeights = baseVertexData->vertexDeclaration-> + findElementBySemantic( VES_BLEND_WEIGHTS ); + if( veWeights ) + { + //One weight is recommended for VTF + mWeightCount = (forceOneWeight() || useOneWeight()) ? + 1 : veWeights->getSize() / sizeof(float); + } + else + { + mWeightCount = 1; + } + + hwBoneIdx.resize( baseVertexData->vertexCount * mWeightCount, 0 ); + + if( mMeshReference->hasSkeleton() && !mMeshReference->getSkeleton().isNull() ) + { + if(mWeightCount > 1) + { + hwBoneWgt.resize( baseVertexData->vertexCount * mWeightCount, 0 ); + retrieveBoneIdxWithWeights(baseVertexData, hwBoneIdx, hwBoneWgt); + } + else + { + retrieveBoneIdx( baseVertexData, hwBoneIdx ); + thisVertexData->vertexDeclaration->removeElement( VES_BLEND_INDICES ); + thisVertexData->vertexDeclaration->removeElement( VES_BLEND_WEIGHTS ); + + thisVertexData->vertexDeclaration->closeGapsInSource(); + } + + } + + for( unsigned short i=0; ivertexDeclaration->getMaxSource()+1; ++i ) + { + //Create our own vertex buffer + HardwareVertexBufferSharedPtr vertexBuffer = + HardwareBufferManager::getSingleton().createVertexBuffer( + thisVertexData->vertexDeclaration->getVertexSize(i), + thisVertexData->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + thisVertexData->vertexBufferBinding->setBinding( i, vertexBuffer ); + + //Grab the base submesh data + HardwareVertexBufferSharedPtr baseVertexBuffer = + baseVertexData->vertexBufferBinding->getBuffer(i); + + char* thisBuf = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + char* baseBuf = static_cast(baseVertexBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); + + //Copy and repeat + for( size_t j=0; jvertexCount * + baseVertexData->vertexDeclaration->getVertexSize(i); + memcpy( thisBuf + j * sizeOfBuffer, baseBuf, sizeOfBuffer ); + } + + baseVertexBuffer->unlock(); + vertexBuffer->unlock(); + } + + createVertexTexture( baseSubMesh ); + createVertexSemantics( thisVertexData, baseVertexData, hwBoneIdx, hwBoneWgt); + } + //----------------------------------------------------------------------- + void InstanceBatchVTF::setupIndices( const SubMesh* baseSubMesh ) + { + mRenderOperation.indexData = OGRE_NEW IndexData(); + mRemoveOwnIndexData = true; //Raise flag to remove our own index data in the end (not always needed) + + IndexData *thisIndexData = mRenderOperation.indexData; + IndexData *baseIndexData = baseSubMesh->indexData; + + thisIndexData->indexStart = 0; + thisIndexData->indexCount = baseIndexData->indexCount * mInstancesPerBatch; + + //TODO: Check numVertices is below max supported by GPU + HardwareIndexBuffer::IndexType indexType = HardwareIndexBuffer::IT_16BIT; + if( mRenderOperation.vertexData->vertexCount > 65535 ) + indexType = HardwareIndexBuffer::IT_32BIT; + thisIndexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( + indexType, thisIndexData->indexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + + void *buf = thisIndexData->indexBuffer->lock( HardwareBuffer::HBL_DISCARD ); + void const *baseBuf = baseIndexData->indexBuffer->lock( HardwareBuffer::HBL_READ_ONLY ); + + uint16 *thisBuf16 = static_cast(buf); + uint32 *thisBuf32 = static_cast(buf); + + for( size_t i=0; ivertexCount / mInstancesPerBatch; + + uint16 const *initBuf16 = static_cast(baseBuf); + uint32 const *initBuf32 = static_cast(baseBuf); + + for( size_t j=0; jindexCount; ++j ) + { + uint32 originalVal; + if( baseSubMesh->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT ) + originalVal = *initBuf16++; + else + originalVal = *initBuf32++; + + if( indexType == HardwareIndexBuffer::IT_16BIT ) + *thisBuf16++ = static_cast(originalVal) + vertexOffset; + else + *thisBuf32++ = static_cast(originalVal + vertexOffset); + } + } + + baseIndexData->indexBuffer->unlock(); + thisIndexData->indexBuffer->unlock(); + } + //----------------------------------------------------------------------- + void InstanceBatchVTF::createVertexSemantics( + VertexData *thisVertexData, VertexData *baseVertexData, const HWBoneIdxVec &hwBoneIdx, const HWBoneWgtVec &hwBoneWgt) + { + const size_t texWidth = mMatrixTexture->getWidth(); + const size_t texHeight = mMatrixTexture->getHeight(); + + //Calculate the texel offsets to correct them offline + //Akwardly enough, the offset is needed in OpenGL too + Vector2 texelOffsets; + //RenderSystem *renderSystem = Root::getSingleton().getRenderSystem(); + texelOffsets.x = /*renderSystem->getHorizontalTexelOffset()*/ -0.5f / (float)texWidth; + texelOffsets.y = /*renderSystem->getVerticalTexelOffset()*/ -0.5f / (float)texHeight; + + //Only one weight per vertex is supported. It would not only be complex, but prohibitively slow. + //Put them in a new buffer, since it's 32 bytes aligned :-) + const unsigned short newSource = thisVertexData->vertexDeclaration->getMaxSource() + 1; + size_t maxFloatsPerVector = 4; + size_t offset = 0; + + for(size_t i = 0; i < mWeightCount; i += maxFloatsPerVector / mRowLength) + { + offset += thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, + thisVertexData->vertexDeclaration-> + getNextFreeTextureCoordinate() ).getSize(); + offset += thisVertexData->vertexDeclaration->addElement( newSource, offset, VET_FLOAT4, VES_TEXTURE_COORDINATES, + thisVertexData->vertexDeclaration-> + getNextFreeTextureCoordinate() ).getSize(); + } + + //Add the weights (supports up to four, which is Ogre's limit) + if(mWeightCount > 1) + { + thisVertexData->vertexDeclaration->addElement(newSource, offset, VET_FLOAT4, VES_BLEND_WEIGHTS, + thisVertexData->vertexDeclaration->getNextFreeTextureCoordinate() ).getSize(); + } + + //Create our own vertex buffer + HardwareVertexBufferSharedPtr vertexBuffer = + HardwareBufferManager::getSingleton().createVertexBuffer( + thisVertexData->vertexDeclaration->getVertexSize(newSource), + thisVertexData->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); + thisVertexData->vertexBufferBinding->setBinding( newSource, vertexBuffer ); + + float *thisFloat = static_cast(vertexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + + //Copy and repeat + for( size_t i=0; ivertexCount * mWeightCount; j += mWeightCount ) + { + size_t numberOfMatricesInLine = 0; + + for(size_t wgtIdx = 0; wgtIdx < mWeightCount; ++wgtIdx) + { + for( size_t k=0; k < mRowLength; ++k) + { + size_t instanceIdx = (hwBoneIdx[j+wgtIdx] + i * mMatricesPerInstance) * mRowLength + k; + //x + *thisFloat++ = ((instanceIdx % texWidth) / (float)texWidth) - (float)texelOffsets.x; + //y + *thisFloat++ = ((instanceIdx / texWidth) / (float)texHeight) - (float)texelOffsets.y; + } + + ++numberOfMatricesInLine; + + //If another matrix can't be fit, we're on another line, or if this is the last weight + if((numberOfMatricesInLine + 1) * mRowLength > maxFloatsPerVector || (wgtIdx+1) == mWeightCount) + { + //Place zeroes in the remaining coordinates + for ( size_t k=mRowLength * numberOfMatricesInLine; k < maxFloatsPerVector; ++k) + { + *thisFloat++ = 0.0f; + *thisFloat++ = 0.0f; + } + + numberOfMatricesInLine = 0; + } + } + + //Don't need to write weights if there is only one + if(mWeightCount > 1) + { + //Write the weights + for(size_t wgtIdx = 0; wgtIdx < mWeightCount; ++wgtIdx) + { + *thisFloat++ = hwBoneWgt[j+wgtIdx]; + } + + //Fill the rest of the line with zeros + for(size_t wgtIdx = mWeightCount; wgtIdx < maxFloatsPerVector; ++wgtIdx) + { + *thisFloat++ = 0.0f; + } + } + } + } + + vertexBuffer->unlock(); + + } + //----------------------------------------------------------------------- + size_t InstanceBatchVTF::calculateMaxNumInstances( + const SubMesh *baseSubMesh, uint16 flags ) const + { + size_t retVal = 0; + + RenderSystem *renderSystem = Root::getSingleton().getRenderSystem(); + const RenderSystemCapabilities *capabilities = renderSystem->getCapabilities(); + + //VTF must be supported + if( capabilities->hasCapability( RSC_VERTEX_TEXTURE_FETCH ) ) + { + //TODO: Check PF_FLOAT32_RGBA is supported (should be, since it was the 1st one) + const size_t numBones = std::max( 1, baseSubMesh->blendIndexToBoneIndexMap.size() ); + retVal = c_maxTexWidth * c_maxTexHeight / mRowLength / numBones; + + if( flags & IM_USE16BIT ) + { + if( baseSubMesh->vertexData->vertexCount * retVal > 0xFFFF ) + retVal = 0xFFFF / baseSubMesh->vertexData->vertexCount; + } + + if( flags & IM_VTFBESTFIT ) + { + const size_t instancesPerBatch = std::min( retVal, mInstancesPerBatch ); + //Do the same as in createVertexTexture() + const size_t numWorldMatrices = instancesPerBatch * numBones; + + size_t texWidth = std::min( numWorldMatrices * mRowLength, c_maxTexWidth ); + size_t texHeight = numWorldMatrices * mRowLength / c_maxTexWidth; + + const size_t remainder = (numWorldMatrices * mRowLength) % c_maxTexWidth; + + if( remainder && texHeight > 0 ) + retVal = static_cast(texWidth * texHeight / (float)mRowLength / (float)(numBones)); + } + } + + return retVal; + + } } diff --git a/OgreMain/src/OgreInstanceManager.cpp b/OgreMain/src/OgreInstanceManager.cpp index 902e06aeabf..651e75913f3 100644 --- a/OgreMain/src/OgreInstanceManager.cpp +++ b/OgreMain/src/OgreInstanceManager.cpp @@ -42,594 +42,594 @@ THE SOFTWARE. namespace Ogre { - InstanceManager::InstanceManager( const String &customName, SceneManager *sceneManager, - const String &meshName, const String &groupName, - InstancingTechnique instancingTechnique, uint16 instancingFlags, - size_t instancesPerBatch, unsigned short subMeshIdx, bool useBoneMatrixLookup ) : - mName( customName ), - mIdCount( 0 ), - mInstancesPerBatch( instancesPerBatch ), - mInstancingTechnique( instancingTechnique ), - mInstancingFlags( instancingFlags ), - mSubMeshIdx( subMeshIdx ), + InstanceManager::InstanceManager( const String &customName, SceneManager *sceneManager, + const String &meshName, const String &groupName, + InstancingTechnique instancingTechnique, uint16 instancingFlags, + size_t instancesPerBatch, unsigned short subMeshIdx, bool useBoneMatrixLookup ) : + mName( customName ), + mIdCount( 0 ), + mInstancesPerBatch( instancesPerBatch ), + mInstancingTechnique( instancingTechnique ), + mInstancingFlags( instancingFlags ), + mSubMeshIdx( subMeshIdx ), mSceneManager( sceneManager ), - mMaxLookupTableInstances(16), - mNumCustomParams( 0 ) - { - mMeshReference = MeshManager::getSingleton().load( meshName, groupName ); - - if(mMeshReference->sharedVertexData) - unshareVertices(mMeshReference); - - if( mMeshReference->hasSkeleton() && !mMeshReference->getSkeleton().isNull() ) - mMeshReference->getSubMesh(mSubMeshIdx)->_compileBoneAssignments(); - } - - InstanceManager::~InstanceManager() - { - //Remove all batches from all materials we created - InstanceBatchMap::const_iterator itor = mInstanceBatches.begin(); - InstanceBatchMap::const_iterator end = mInstanceBatches.end(); - - while( itor != end ) - { - InstanceBatchVec::const_iterator it = itor->second.begin(); - InstanceBatchVec::const_iterator en = itor->second.end(); - - while( it != en ) - OGRE_DELETE *it++; - - ++itor; - } - } - //---------------------------------------------------------------------- - void InstanceManager::setInstancesPerBatch( size_t instancesPerBatch ) - { - if( !mInstanceBatches.empty() ) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Instances per batch can only be changed before" - " building the batch.", "InstanceManager::setInstancesPerBatch"); - } - - mInstancesPerBatch = instancesPerBatch; - } - - //---------------------------------------------------------------------- - void InstanceManager::setMaxLookupTableInstances( size_t maxLookupTableInstances ) - { - if( !mInstanceBatches.empty() ) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Instances per batch can only be changed before" - " building the batch.", "InstanceManager::setMaxLookupTableInstances"); - } - - mMaxLookupTableInstances = maxLookupTableInstances; - } - - //---------------------------------------------------------------------- - void InstanceManager::setNumCustomParams( unsigned char numCustomParams ) - { - if( !mInstanceBatches.empty() ) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "setNumCustomParams can only be changed before" - " building the batch.", "InstanceManager::setNumCustomParams"); - } - - mNumCustomParams = numCustomParams; - } - //---------------------------------------------------------------------- - size_t InstanceManager::getMaxOrBestNumInstancesPerBatch( const String &materialName, size_t suggestedSize, - uint16 flags ) - { - //Get the material - MaterialPtr mat = MaterialManager::getSingleton().getByName( materialName, - mMeshReference->getGroup() ); - InstanceBatch *batch = 0; - - //Base material couldn't be found - if( mat.isNull() ) - return 0; - - switch( mInstancingTechnique ) - { - case ShaderBased: - batch = OGRE_NEW InstanceBatchShader( this, mMeshReference, mat, suggestedSize, - 0, mName + "/TempBatch" ); - break; - case TextureVTF: - batch = OGRE_NEW InstanceBatchVTF( this, mMeshReference, mat, suggestedSize, - 0, mName + "/TempBatch" ); - static_cast(batch)->setBoneDualQuaternions((mInstancingFlags & IM_USEBONEDUALQUATERNIONS) != 0); - static_cast(batch)->setUseOneWeight((mInstancingFlags & IM_USEONEWEIGHT) != 0); - static_cast(batch)->setForceOneWeight((mInstancingFlags & IM_FORCEONEWEIGHT) != 0); - break; - case HWInstancingBasic: - batch = OGRE_NEW InstanceBatchHW( this, mMeshReference, mat, suggestedSize, - 0, mName + "/TempBatch" ); - break; - case HWInstancingVTF: - batch = OGRE_NEW InstanceBatchHW_VTF( this, mMeshReference, mat, suggestedSize, - 0, mName + "/TempBatch" ); - static_cast(batch)->setBoneMatrixLookup((mInstancingFlags & IM_VTFBONEMATRIXLOOKUP) != 0, mMaxLookupTableInstances); - static_cast(batch)->setBoneDualQuaternions((mInstancingFlags & IM_USEBONEDUALQUATERNIONS) != 0); - static_cast(batch)->setUseOneWeight((mInstancingFlags & IM_USEONEWEIGHT) != 0); - static_cast(batch)->setForceOneWeight((mInstancingFlags & IM_FORCEONEWEIGHT) != 0); - break; - default: - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "Unimplemented instancing technique: " + - StringConverter::toString(mInstancingTechnique), - "InstanceBatch::getMaxOrBestNumInstancesPerBatches()"); - } - - const size_t retVal = batch->calculateMaxNumInstances( mMeshReference->getSubMesh(mSubMeshIdx), - flags ); - - OGRE_DELETE batch; - - return retVal; - } - //---------------------------------------------------------------------- - InstancedEntity* InstanceManager::createInstancedEntity( const String &materialName ) - { - InstanceBatch *instanceBatch; - - if( mInstanceBatches.empty() ) - instanceBatch = buildNewBatch( materialName, true ); - else - instanceBatch = getFreeBatch( materialName ); - - return instanceBatch->createInstancedEntity(); - } - //----------------------------------------------------------------------- - inline InstanceBatch* InstanceManager::getFreeBatch( const String &materialName ) - { - InstanceBatchVec &batchVec = mInstanceBatches[materialName]; - - InstanceBatchVec::const_reverse_iterator itor = batchVec.rbegin(); - InstanceBatchVec::const_reverse_iterator end = batchVec.rend(); - - while( itor != end ) - { - if( !(*itor)->isBatchFull() ) - return *itor; - ++itor; - } - - //None found, or they're all full - return buildNewBatch( materialName, false ); - } - //----------------------------------------------------------------------- - InstanceBatch* InstanceManager::buildNewBatch( const String &materialName, bool firstTime ) - { - //Get the bone to index map for the batches - Mesh::IndexMap &idxMap = mMeshReference->getSubMesh(mSubMeshIdx)->blendIndexToBoneIndexMap; - idxMap = idxMap.empty() ? mMeshReference->sharedBlendIndexToBoneIndexMap : idxMap; - - //Get the material - MaterialPtr mat = MaterialManager::getSingleton().getByName( materialName, - mMeshReference->getGroup() ); - - //Get the array of batches grouped by this material - InstanceBatchVec &materialInstanceBatch = mInstanceBatches[materialName]; - - InstanceBatch *batch = 0; - - switch( mInstancingTechnique ) - { - case ShaderBased: - batch = OGRE_NEW InstanceBatchShader( this, mMeshReference, mat, mInstancesPerBatch, - &idxMap, mName + "/InstanceBatch_" + - StringConverter::toString(mIdCount++) ); - break; - case TextureVTF: - batch = OGRE_NEW InstanceBatchVTF( this, mMeshReference, mat, mInstancesPerBatch, - &idxMap, mName + "/InstanceBatch_" + - StringConverter::toString(mIdCount++) ); - static_cast(batch)->setBoneDualQuaternions((mInstancingFlags & IM_USEBONEDUALQUATERNIONS) != 0); - static_cast(batch)->setUseOneWeight((mInstancingFlags & IM_USEONEWEIGHT) != 0); - static_cast(batch)->setForceOneWeight((mInstancingFlags & IM_FORCEONEWEIGHT) != 0); - break; - case HWInstancingBasic: - batch = OGRE_NEW InstanceBatchHW( this, mMeshReference, mat, mInstancesPerBatch, - &idxMap, mName + "/InstanceBatch_" + - StringConverter::toString(mIdCount++) ); - break; - case HWInstancingVTF: - batch = OGRE_NEW InstanceBatchHW_VTF( this, mMeshReference, mat, mInstancesPerBatch, - &idxMap, mName + "/InstanceBatch_" + - StringConverter::toString(mIdCount++) ); - static_cast(batch)->setBoneMatrixLookup((mInstancingFlags & IM_VTFBONEMATRIXLOOKUP) != 0, mMaxLookupTableInstances); - static_cast(batch)->setBoneDualQuaternions((mInstancingFlags & IM_USEBONEDUALQUATERNIONS) != 0); - static_cast(batch)->setUseOneWeight((mInstancingFlags & IM_USEONEWEIGHT) != 0); - static_cast(batch)->setForceOneWeight((mInstancingFlags & IM_FORCEONEWEIGHT) != 0); - break; - default: - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "Unimplemented instancing technique: " + - StringConverter::toString(mInstancingTechnique), - "InstanceBatch::buildNewBatch()"); - } - - batch->_notifyManager( mSceneManager ); - - - if( !firstTime ) - { - //TODO: Check different materials have the same mInstancesPerBatch upper limit - //otherwise we can't share - batch->buildFrom( mMeshReference->getSubMesh(mSubMeshIdx), mSharedRenderOperation ); - } - else - { - //Ensure we don't request more than we can - const size_t maxInstPerBatch = batch->calculateMaxNumInstances( mMeshReference-> - getSubMesh(mSubMeshIdx), mInstancingFlags ); - mInstancesPerBatch = std::min( maxInstPerBatch, mInstancesPerBatch ); - batch->_setInstancesPerBatch( mInstancesPerBatch ); - - //TODO: Create a "merge" function that merges all submeshes into one big submesh - //instead of just sending submesh #0 - - //Get the RenderOperation to be shared with further instances. - mSharedRenderOperation = batch->build( mMeshReference->getSubMesh(mSubMeshIdx) ); - } - - const BatchSettings &batchSettings = mBatchSettings[materialName]; - batch->setCastShadows( batchSettings.setting[CAST_SHADOWS] ); - - //Batches need to be part of a scene node so that their renderable can be rendered - SceneNode *sceneNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); - sceneNode->attachObject( batch ); - sceneNode->showBoundingBox( batchSettings.setting[SHOW_BOUNDINGBOX] ); - - materialInstanceBatch.push_back( batch ); - - return batch; - } - //----------------------------------------------------------------------- - void InstanceManager::cleanupEmptyBatches(void) - { - //Do this now to avoid any dangling pointer inside mDirtyBatches - _updateDirtyBatches(); - - InstanceBatchMap::iterator itor = mInstanceBatches.begin(); - InstanceBatchMap::iterator end = mInstanceBatches.end(); - - while( itor != end ) - { - InstanceBatchVec::iterator it = itor->second.begin(); - InstanceBatchVec::iterator en = itor->second.end(); - - while( it != en ) - { - if( (*it)->isBatchUnused() ) - { - OGRE_DELETE *it; - //Remove it from the list swapping with the last element and popping back - size_t idx = it - itor->second.begin(); - *it = itor->second.back(); - itor->second.pop_back(); - - //Restore invalidated iterators - it = itor->second.begin() + idx; - en = itor->second.end(); - } - else - ++it; - } - - ++itor; - } - - //By this point it may happen that all mInstanceBatches' objects are also empty - //however if we call mInstanceBatches.clear(), next time we'll create an InstancedObject - //we'll end up calling buildFirstTime() instead of buildNewBatch(), which is not the idea - //(takes more time and will leak the shared render operation) - } - //----------------------------------------------------------------------- - void InstanceManager::defragmentBatches( bool optimizeCull, - InstanceBatch::InstancedEntityVec &usedEntities, - InstanceBatch::CustomParamsVec &usedParams, - InstanceBatchVec &fragmentedBatches ) - { - InstanceBatchVec::iterator itor = fragmentedBatches.begin(); - InstanceBatchVec::iterator end = fragmentedBatches.end(); - - while( itor != end && !usedEntities.empty() ) - { - if( !(*itor)->isStatic() ) - (*itor)->_defragmentBatch( optimizeCull, usedEntities, usedParams ); - ++itor; - } - - InstanceBatchVec::iterator lastImportantBatch = itor; - - while( itor != end ) - { - if( !(*itor)->isStatic() ) - { - //If we get here, this means we hit remaining batches which will be unused. - //Destroy them - //Call this to avoid freeing InstancedEntities that were just reparented - (*itor)->_defragmentBatchDiscard(); - OGRE_DELETE *itor; - } - else - { - //This isn't a meaningless batch, move it forward so it doesn't get wipe - //when we resize the container (faster than removing element by element) - *lastImportantBatch++ = *itor; - } - - ++itor; - } - - //Remove remaining batches all at once from the vector - const size_t remainingBatches = end - lastImportantBatch; - fragmentedBatches.resize( fragmentedBatches.size() - remainingBatches ); - } - //----------------------------------------------------------------------- - void InstanceManager::defragmentBatches( bool optimizeCulling ) - { - //Do this now to avoid any dangling pointer inside mDirtyBatches - _updateDirtyBatches(); - - //Do this for every material - InstanceBatchMap::iterator itor = mInstanceBatches.begin(); - InstanceBatchMap::iterator end = mInstanceBatches.end(); - - while( itor != end ) - { - InstanceBatch::InstancedEntityVec usedEntities; - InstanceBatch::CustomParamsVec usedParams; - usedEntities.reserve( itor->second.size() * mInstancesPerBatch ); - - //Collect all Instanced Entities being used by _all_ batches from this material - InstanceBatchVec::iterator it = itor->second.begin(); - InstanceBatchVec::iterator en = itor->second.end(); - - while( it != en ) - { - //Don't collect instances from static batches, we assume they're correctly set - //Plus, we don't want to put InstancedEntities from non-static into static batches - if( !(*it)->isStatic() ) - (*it)->getInstancedEntitiesInUse( usedEntities, usedParams ); - ++it; - } - - defragmentBatches( optimizeCulling, usedEntities, usedParams, itor->second ); - - ++itor; - } - } - //----------------------------------------------------------------------- - void InstanceManager::setSetting( BatchSettingId id, bool value, const String &materialName ) - { - assert( id < NUM_SETTINGS ); - - if( materialName == BLANKSTRING ) - { - //Setup all existing materials - InstanceBatchMap::iterator itor = mInstanceBatches.begin(); - InstanceBatchMap::iterator end = mInstanceBatches.end(); - - while( itor != end ) - { - mBatchSettings[itor->first].setting[id] = value; - applySettingToBatches( id, value, itor->second ); - - ++itor; - } - } - else - { - //Setup a given material - mBatchSettings[materialName].setting[id] = value; - - InstanceBatchMap::const_iterator itor = mInstanceBatches.find( materialName ); - //Don't crash or throw if the batch with that material hasn't been created yet - if( itor != mInstanceBatches.end() ) - applySettingToBatches( id, value, itor->second ); - } - } - //----------------------------------------------------------------------- - bool InstanceManager::getSetting( BatchSettingId id, const String &materialName ) const - { - assert( id < NUM_SETTINGS ); - - BatchSettingsMap::const_iterator itor = mBatchSettings.find( materialName ); - if( itor != mBatchSettings.end() ) - return itor->second.setting[id]; //Return current setting - - //Return default - return BatchSettings().setting[id]; - } - //----------------------------------------------------------------------- - void InstanceManager::applySettingToBatches( BatchSettingId id, bool value, - const InstanceBatchVec &container ) - { - InstanceBatchVec::const_iterator itor = container.begin(); - InstanceBatchVec::const_iterator end = container.end(); - - while( itor != end ) - { - switch( id ) - { - case CAST_SHADOWS: - (*itor)->setCastShadows( value ); - break; - case SHOW_BOUNDINGBOX: - (*itor)->getParentSceneNode()->showBoundingBox( value ); - break; - default: - break; - } - ++itor; - } - } - //----------------------------------------------------------------------- - void InstanceManager::setBatchesAsStaticAndUpdate( bool bStatic ) - { - InstanceBatchMap::iterator itor = mInstanceBatches.begin(); - InstanceBatchMap::iterator end = mInstanceBatches.end(); - - while( itor != end ) - { - InstanceBatchVec::iterator it = itor->second.begin(); - InstanceBatchVec::iterator en = itor->second.end(); - - while( it != en ) - { - (*it)->setStaticAndUpdate( bStatic ); - ++it; - } - - ++itor; - } - } - //----------------------------------------------------------------------- - void InstanceManager::_addDirtyBatch( InstanceBatch *dirtyBatch ) - { - if( mDirtyBatches.empty() ) - mSceneManager->_addDirtyInstanceManager( this ); - - mDirtyBatches.push_back( dirtyBatch ); - } - //----------------------------------------------------------------------- - void InstanceManager::_updateDirtyBatches(void) - { - InstanceBatchVec::const_iterator itor = mDirtyBatches.begin(); - InstanceBatchVec::const_iterator end = mDirtyBatches.end(); - - while( itor != end ) - { - (*itor)->_updateBounds(); - ++itor; - } - - mDirtyBatches.clear(); - } - //----------------------------------------------------------------------- - // Helper functions to unshare the vertices - //----------------------------------------------------------------------- - typedef map::type IndicesMap; - - template< typename TIndexType > - IndicesMap getUsedIndices(IndexData* idxData) - { - TIndexType *data = (TIndexType*)idxData->indexBuffer->lock(idxData->indexStart * sizeof(TIndexType), - idxData->indexCount * sizeof(TIndexType), HardwareBuffer::HBL_READ_ONLY); - - IndicesMap indicesMap; - for (size_t i = 0; i < idxData->indexCount; i++) - { - TIndexType index = data[i]; - if (indicesMap.find(index) == indicesMap.end()) - { - indicesMap[index] = (uint32)(indicesMap.size()); - } - } - - idxData->indexBuffer->unlock(); - return indicesMap; - } - //----------------------------------------------------------------------- - template< typename TIndexType > - void copyIndexBuffer(IndexData* idxData, IndicesMap& indicesMap) - { - TIndexType *data = (TIndexType*)idxData->indexBuffer->lock(idxData->indexStart * sizeof(TIndexType), - idxData->indexCount * sizeof(TIndexType), HardwareBuffer::HBL_NORMAL); - - for (uint32 i = 0; i < idxData->indexCount; i++) - { - data[i] = (TIndexType)indicesMap[data[i]]; - } - - idxData->indexBuffer->unlock(); - } - //----------------------------------------------------------------------- - void InstanceManager::unshareVertices(const Ogre::MeshPtr &mesh) - { - // Retrieve data to copy bone assignments - const Mesh::VertexBoneAssignmentList& boneAssignments = mesh->getBoneAssignments(); - Mesh::VertexBoneAssignmentList::const_iterator it = boneAssignments.begin(); - Mesh::VertexBoneAssignmentList::const_iterator end = boneAssignments.end(); - size_t curVertexOffset = 0; - - // Access shared vertices - VertexData* sharedVertexData = mesh->sharedVertexData; - - for (size_t subMeshIdx = 0; subMeshIdx < mesh->getNumSubMeshes(); subMeshIdx++) - { - SubMesh *subMesh = mesh->getSubMesh(subMeshIdx); - - IndexData *indexData = subMesh->indexData; - HardwareIndexBuffer::IndexType idxType = indexData->indexBuffer->getType(); - IndicesMap indicesMap = (idxType == HardwareIndexBuffer::IT_16BIT) ? getUsedIndices(indexData) : - getUsedIndices(indexData); - - - VertexData *newVertexData = new VertexData(); - newVertexData->vertexCount = indicesMap.size(); - newVertexData->vertexDeclaration = sharedVertexData->vertexDeclaration->clone(); - - for (size_t bufIdx = 0; bufIdx < sharedVertexData->vertexBufferBinding->getBufferCount(); bufIdx++) - { - HardwareVertexBufferSharedPtr sharedVertexBuffer = sharedVertexData->vertexBufferBinding->getBuffer(bufIdx); - size_t vertexSize = sharedVertexBuffer->getVertexSize(); - - HardwareVertexBufferSharedPtr newVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer - (vertexSize, newVertexData->vertexCount, sharedVertexBuffer->getUsage(), sharedVertexBuffer->hasShadowBuffer()); - - uint8 *oldLock = (uint8*)sharedVertexBuffer->lock(0, sharedVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_READ_ONLY); - uint8 *newLock = (uint8*)newVertexBuffer->lock(0, newVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_NORMAL); - - IndicesMap::iterator indIt = indicesMap.begin(); - IndicesMap::iterator endIndIt = indicesMap.end(); - for (; indIt != endIndIt; ++indIt) - { - memcpy(newLock + vertexSize * indIt->second, oldLock + vertexSize * indIt->first, vertexSize); - } - - sharedVertexBuffer->unlock(); - newVertexBuffer->unlock(); - - newVertexData->vertexBufferBinding->setBinding(bufIdx, newVertexBuffer); - } - - if (idxType == HardwareIndexBuffer::IT_16BIT) - { - copyIndexBuffer(indexData, indicesMap); - } - else - { - copyIndexBuffer(indexData, indicesMap); - } - - // Store new attributes - subMesh->useSharedVertices = false; - subMesh->vertexData = newVertexData; - - // Transfer bone assignments to the submesh - size_t offset = curVertexOffset + newVertexData->vertexCount; - for (; it != end; ++it) - { - size_t vertexIdx = (*it).first; - if (vertexIdx > offset) - break; - - VertexBoneAssignment boneAssignment = (*it).second; - boneAssignment.vertexIndex = static_cast(boneAssignment.vertexIndex - curVertexOffset); - subMesh->addBoneAssignment(boneAssignment); - } - curVertexOffset = newVertexData->vertexCount + 1; - } - - // Release shared vertex data - delete mesh->sharedVertexData; - mesh->sharedVertexData = NULL; - mesh->clearBoneAssignments(); - } - //----------------------------------------------------------------------- + mMaxLookupTableInstances(16), + mNumCustomParams( 0 ) + { + mMeshReference = MeshManager::getSingleton().load( meshName, groupName ); + + if(mMeshReference->sharedVertexData) + unshareVertices(mMeshReference); + + if( mMeshReference->hasSkeleton() && !mMeshReference->getSkeleton().isNull() ) + mMeshReference->getSubMesh(mSubMeshIdx)->_compileBoneAssignments(); + } + + InstanceManager::~InstanceManager() + { + //Remove all batches from all materials we created + InstanceBatchMap::const_iterator itor = mInstanceBatches.begin(); + InstanceBatchMap::const_iterator end = mInstanceBatches.end(); + + while( itor != end ) + { + InstanceBatchVec::const_iterator it = itor->second.begin(); + InstanceBatchVec::const_iterator en = itor->second.end(); + + while( it != en ) + OGRE_DELETE *it++; + + ++itor; + } + } + //---------------------------------------------------------------------- + void InstanceManager::setInstancesPerBatch( size_t instancesPerBatch ) + { + if( !mInstanceBatches.empty() ) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Instances per batch can only be changed before" + " building the batch.", "InstanceManager::setInstancesPerBatch"); + } + + mInstancesPerBatch = instancesPerBatch; + } + + //---------------------------------------------------------------------- + void InstanceManager::setMaxLookupTableInstances( size_t maxLookupTableInstances ) + { + if( !mInstanceBatches.empty() ) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Instances per batch can only be changed before" + " building the batch.", "InstanceManager::setMaxLookupTableInstances"); + } + + mMaxLookupTableInstances = maxLookupTableInstances; + } + + //---------------------------------------------------------------------- + void InstanceManager::setNumCustomParams( unsigned char numCustomParams ) + { + if( !mInstanceBatches.empty() ) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "setNumCustomParams can only be changed before" + " building the batch.", "InstanceManager::setNumCustomParams"); + } + + mNumCustomParams = numCustomParams; + } + //---------------------------------------------------------------------- + size_t InstanceManager::getMaxOrBestNumInstancesPerBatch( const String &materialName, size_t suggestedSize, + uint16 flags ) + { + //Get the material + MaterialPtr mat = MaterialManager::getSingleton().getByName( materialName, + mMeshReference->getGroup() ); + InstanceBatch *batch = 0; + + //Base material couldn't be found + if( mat.isNull() ) + return 0; + + switch( mInstancingTechnique ) + { + case ShaderBased: + batch = OGRE_NEW InstanceBatchShader( this, mMeshReference, mat, suggestedSize, + 0, mName + "/TempBatch" ); + break; + case TextureVTF: + batch = OGRE_NEW InstanceBatchVTF( this, mMeshReference, mat, suggestedSize, + 0, mName + "/TempBatch" ); + static_cast(batch)->setBoneDualQuaternions((mInstancingFlags & IM_USEBONEDUALQUATERNIONS) != 0); + static_cast(batch)->setUseOneWeight((mInstancingFlags & IM_USEONEWEIGHT) != 0); + static_cast(batch)->setForceOneWeight((mInstancingFlags & IM_FORCEONEWEIGHT) != 0); + break; + case HWInstancingBasic: + batch = OGRE_NEW InstanceBatchHW( this, mMeshReference, mat, suggestedSize, + 0, mName + "/TempBatch" ); + break; + case HWInstancingVTF: + batch = OGRE_NEW InstanceBatchHW_VTF( this, mMeshReference, mat, suggestedSize, + 0, mName + "/TempBatch" ); + static_cast(batch)->setBoneMatrixLookup((mInstancingFlags & IM_VTFBONEMATRIXLOOKUP) != 0, mMaxLookupTableInstances); + static_cast(batch)->setBoneDualQuaternions((mInstancingFlags & IM_USEBONEDUALQUATERNIONS) != 0); + static_cast(batch)->setUseOneWeight((mInstancingFlags & IM_USEONEWEIGHT) != 0); + static_cast(batch)->setForceOneWeight((mInstancingFlags & IM_FORCEONEWEIGHT) != 0); + break; + default: + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "Unimplemented instancing technique: " + + StringConverter::toString(mInstancingTechnique), + "InstanceBatch::getMaxOrBestNumInstancesPerBatches()"); + } + + const size_t retVal = batch->calculateMaxNumInstances( mMeshReference->getSubMesh(mSubMeshIdx), + flags ); + + OGRE_DELETE batch; + + return retVal; + } + //---------------------------------------------------------------------- + InstancedEntity* InstanceManager::createInstancedEntity( const String &materialName ) + { + InstanceBatch *instanceBatch; + + if( mInstanceBatches.empty() ) + instanceBatch = buildNewBatch( materialName, true ); + else + instanceBatch = getFreeBatch( materialName ); + + return instanceBatch->createInstancedEntity(); + } + //----------------------------------------------------------------------- + inline InstanceBatch* InstanceManager::getFreeBatch( const String &materialName ) + { + InstanceBatchVec &batchVec = mInstanceBatches[materialName]; + + InstanceBatchVec::const_reverse_iterator itor = batchVec.rbegin(); + InstanceBatchVec::const_reverse_iterator end = batchVec.rend(); + + while( itor != end ) + { + if( !(*itor)->isBatchFull() ) + return *itor; + ++itor; + } + + //None found, or they're all full + return buildNewBatch( materialName, false ); + } + //----------------------------------------------------------------------- + InstanceBatch* InstanceManager::buildNewBatch( const String &materialName, bool firstTime ) + { + //Get the bone to index map for the batches + Mesh::IndexMap &idxMap = mMeshReference->getSubMesh(mSubMeshIdx)->blendIndexToBoneIndexMap; + idxMap = idxMap.empty() ? mMeshReference->sharedBlendIndexToBoneIndexMap : idxMap; + + //Get the material + MaterialPtr mat = MaterialManager::getSingleton().getByName( materialName, + mMeshReference->getGroup() ); + + //Get the array of batches grouped by this material + InstanceBatchVec &materialInstanceBatch = mInstanceBatches[materialName]; + + InstanceBatch *batch = 0; + + switch( mInstancingTechnique ) + { + case ShaderBased: + batch = OGRE_NEW InstanceBatchShader( this, mMeshReference, mat, mInstancesPerBatch, + &idxMap, mName + "/InstanceBatch_" + + StringConverter::toString(mIdCount++) ); + break; + case TextureVTF: + batch = OGRE_NEW InstanceBatchVTF( this, mMeshReference, mat, mInstancesPerBatch, + &idxMap, mName + "/InstanceBatch_" + + StringConverter::toString(mIdCount++) ); + static_cast(batch)->setBoneDualQuaternions((mInstancingFlags & IM_USEBONEDUALQUATERNIONS) != 0); + static_cast(batch)->setUseOneWeight((mInstancingFlags & IM_USEONEWEIGHT) != 0); + static_cast(batch)->setForceOneWeight((mInstancingFlags & IM_FORCEONEWEIGHT) != 0); + break; + case HWInstancingBasic: + batch = OGRE_NEW InstanceBatchHW( this, mMeshReference, mat, mInstancesPerBatch, + &idxMap, mName + "/InstanceBatch_" + + StringConverter::toString(mIdCount++) ); + break; + case HWInstancingVTF: + batch = OGRE_NEW InstanceBatchHW_VTF( this, mMeshReference, mat, mInstancesPerBatch, + &idxMap, mName + "/InstanceBatch_" + + StringConverter::toString(mIdCount++) ); + static_cast(batch)->setBoneMatrixLookup((mInstancingFlags & IM_VTFBONEMATRIXLOOKUP) != 0, mMaxLookupTableInstances); + static_cast(batch)->setBoneDualQuaternions((mInstancingFlags & IM_USEBONEDUALQUATERNIONS) != 0); + static_cast(batch)->setUseOneWeight((mInstancingFlags & IM_USEONEWEIGHT) != 0); + static_cast(batch)->setForceOneWeight((mInstancingFlags & IM_FORCEONEWEIGHT) != 0); + break; + default: + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "Unimplemented instancing technique: " + + StringConverter::toString(mInstancingTechnique), + "InstanceBatch::buildNewBatch()"); + } + + batch->_notifyManager( mSceneManager ); + + + if( !firstTime ) + { + //TODO: Check different materials have the same mInstancesPerBatch upper limit + //otherwise we can't share + batch->buildFrom( mMeshReference->getSubMesh(mSubMeshIdx), mSharedRenderOperation ); + } + else + { + //Ensure we don't request more than we can + const size_t maxInstPerBatch = batch->calculateMaxNumInstances( mMeshReference-> + getSubMesh(mSubMeshIdx), mInstancingFlags ); + mInstancesPerBatch = std::min( maxInstPerBatch, mInstancesPerBatch ); + batch->_setInstancesPerBatch( mInstancesPerBatch ); + + //TODO: Create a "merge" function that merges all submeshes into one big submesh + //instead of just sending submesh #0 + + //Get the RenderOperation to be shared with further instances. + mSharedRenderOperation = batch->build( mMeshReference->getSubMesh(mSubMeshIdx) ); + } + + const BatchSettings &batchSettings = mBatchSettings[materialName]; + batch->setCastShadows( batchSettings.setting[CAST_SHADOWS] ); + + //Batches need to be part of a scene node so that their renderable can be rendered + SceneNode *sceneNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); + sceneNode->attachObject( batch ); + sceneNode->showBoundingBox( batchSettings.setting[SHOW_BOUNDINGBOX] ); + + materialInstanceBatch.push_back( batch ); + + return batch; + } + //----------------------------------------------------------------------- + void InstanceManager::cleanupEmptyBatches(void) + { + //Do this now to avoid any dangling pointer inside mDirtyBatches + _updateDirtyBatches(); + + InstanceBatchMap::iterator itor = mInstanceBatches.begin(); + InstanceBatchMap::iterator end = mInstanceBatches.end(); + + while( itor != end ) + { + InstanceBatchVec::iterator it = itor->second.begin(); + InstanceBatchVec::iterator en = itor->second.end(); + + while( it != en ) + { + if( (*it)->isBatchUnused() ) + { + OGRE_DELETE *it; + //Remove it from the list swapping with the last element and popping back + size_t idx = it - itor->second.begin(); + *it = itor->second.back(); + itor->second.pop_back(); + + //Restore invalidated iterators + it = itor->second.begin() + idx; + en = itor->second.end(); + } + else + ++it; + } + + ++itor; + } + + //By this point it may happen that all mInstanceBatches' objects are also empty + //however if we call mInstanceBatches.clear(), next time we'll create an InstancedObject + //we'll end up calling buildFirstTime() instead of buildNewBatch(), which is not the idea + //(takes more time and will leak the shared render operation) + } + //----------------------------------------------------------------------- + void InstanceManager::defragmentBatches( bool optimizeCull, + InstanceBatch::InstancedEntityVec &usedEntities, + InstanceBatch::CustomParamsVec &usedParams, + InstanceBatchVec &fragmentedBatches ) + { + InstanceBatchVec::iterator itor = fragmentedBatches.begin(); + InstanceBatchVec::iterator end = fragmentedBatches.end(); + + while( itor != end && !usedEntities.empty() ) + { + if( !(*itor)->isStatic() ) + (*itor)->_defragmentBatch( optimizeCull, usedEntities, usedParams ); + ++itor; + } + + InstanceBatchVec::iterator lastImportantBatch = itor; + + while( itor != end ) + { + if( !(*itor)->isStatic() ) + { + //If we get here, this means we hit remaining batches which will be unused. + //Destroy them + //Call this to avoid freeing InstancedEntities that were just reparented + (*itor)->_defragmentBatchDiscard(); + OGRE_DELETE *itor; + } + else + { + //This isn't a meaningless batch, move it forward so it doesn't get wipe + //when we resize the container (faster than removing element by element) + *lastImportantBatch++ = *itor; + } + + ++itor; + } + + //Remove remaining batches all at once from the vector + const size_t remainingBatches = end - lastImportantBatch; + fragmentedBatches.resize( fragmentedBatches.size() - remainingBatches ); + } + //----------------------------------------------------------------------- + void InstanceManager::defragmentBatches( bool optimizeCulling ) + { + //Do this now to avoid any dangling pointer inside mDirtyBatches + _updateDirtyBatches(); + + //Do this for every material + InstanceBatchMap::iterator itor = mInstanceBatches.begin(); + InstanceBatchMap::iterator end = mInstanceBatches.end(); + + while( itor != end ) + { + InstanceBatch::InstancedEntityVec usedEntities; + InstanceBatch::CustomParamsVec usedParams; + usedEntities.reserve( itor->second.size() * mInstancesPerBatch ); + + //Collect all Instanced Entities being used by _all_ batches from this material + InstanceBatchVec::iterator it = itor->second.begin(); + InstanceBatchVec::iterator en = itor->second.end(); + + while( it != en ) + { + //Don't collect instances from static batches, we assume they're correctly set + //Plus, we don't want to put InstancedEntities from non-static into static batches + if( !(*it)->isStatic() ) + (*it)->getInstancedEntitiesInUse( usedEntities, usedParams ); + ++it; + } + + defragmentBatches( optimizeCulling, usedEntities, usedParams, itor->second ); + + ++itor; + } + } + //----------------------------------------------------------------------- + void InstanceManager::setSetting( BatchSettingId id, bool value, const String &materialName ) + { + assert( id < NUM_SETTINGS ); + + if( materialName == BLANKSTRING ) + { + //Setup all existing materials + InstanceBatchMap::iterator itor = mInstanceBatches.begin(); + InstanceBatchMap::iterator end = mInstanceBatches.end(); + + while( itor != end ) + { + mBatchSettings[itor->first].setting[id] = value; + applySettingToBatches( id, value, itor->second ); + + ++itor; + } + } + else + { + //Setup a given material + mBatchSettings[materialName].setting[id] = value; + + InstanceBatchMap::const_iterator itor = mInstanceBatches.find( materialName ); + //Don't crash or throw if the batch with that material hasn't been created yet + if( itor != mInstanceBatches.end() ) + applySettingToBatches( id, value, itor->second ); + } + } + //----------------------------------------------------------------------- + bool InstanceManager::getSetting( BatchSettingId id, const String &materialName ) const + { + assert( id < NUM_SETTINGS ); + + BatchSettingsMap::const_iterator itor = mBatchSettings.find( materialName ); + if( itor != mBatchSettings.end() ) + return itor->second.setting[id]; //Return current setting + + //Return default + return BatchSettings().setting[id]; + } + //----------------------------------------------------------------------- + void InstanceManager::applySettingToBatches( BatchSettingId id, bool value, + const InstanceBatchVec &container ) + { + InstanceBatchVec::const_iterator itor = container.begin(); + InstanceBatchVec::const_iterator end = container.end(); + + while( itor != end ) + { + switch( id ) + { + case CAST_SHADOWS: + (*itor)->setCastShadows( value ); + break; + case SHOW_BOUNDINGBOX: + (*itor)->getParentSceneNode()->showBoundingBox( value ); + break; + default: + break; + } + ++itor; + } + } + //----------------------------------------------------------------------- + void InstanceManager::setBatchesAsStaticAndUpdate( bool bStatic ) + { + InstanceBatchMap::iterator itor = mInstanceBatches.begin(); + InstanceBatchMap::iterator end = mInstanceBatches.end(); + + while( itor != end ) + { + InstanceBatchVec::iterator it = itor->second.begin(); + InstanceBatchVec::iterator en = itor->second.end(); + + while( it != en ) + { + (*it)->setStaticAndUpdate( bStatic ); + ++it; + } + + ++itor; + } + } + //----------------------------------------------------------------------- + void InstanceManager::_addDirtyBatch( InstanceBatch *dirtyBatch ) + { + if( mDirtyBatches.empty() ) + mSceneManager->_addDirtyInstanceManager( this ); + + mDirtyBatches.push_back( dirtyBatch ); + } + //----------------------------------------------------------------------- + void InstanceManager::_updateDirtyBatches(void) + { + InstanceBatchVec::const_iterator itor = mDirtyBatches.begin(); + InstanceBatchVec::const_iterator end = mDirtyBatches.end(); + + while( itor != end ) + { + (*itor)->_updateBounds(); + ++itor; + } + + mDirtyBatches.clear(); + } + //----------------------------------------------------------------------- + // Helper functions to unshare the vertices + //----------------------------------------------------------------------- + typedef map::type IndicesMap; + + template< typename TIndexType > + IndicesMap getUsedIndices(IndexData* idxData) + { + TIndexType *data = (TIndexType*)idxData->indexBuffer->lock(idxData->indexStart * sizeof(TIndexType), + idxData->indexCount * sizeof(TIndexType), HardwareBuffer::HBL_READ_ONLY); + + IndicesMap indicesMap; + for (size_t i = 0; i < idxData->indexCount; i++) + { + TIndexType index = data[i]; + if (indicesMap.find(index) == indicesMap.end()) + { + indicesMap[index] = (uint32)(indicesMap.size()); + } + } + + idxData->indexBuffer->unlock(); + return indicesMap; + } + //----------------------------------------------------------------------- + template< typename TIndexType > + void copyIndexBuffer(IndexData* idxData, IndicesMap& indicesMap) + { + TIndexType *data = (TIndexType*)idxData->indexBuffer->lock(idxData->indexStart * sizeof(TIndexType), + idxData->indexCount * sizeof(TIndexType), HardwareBuffer::HBL_NORMAL); + + for (uint32 i = 0; i < idxData->indexCount; i++) + { + data[i] = (TIndexType)indicesMap[data[i]]; + } + + idxData->indexBuffer->unlock(); + } + //----------------------------------------------------------------------- + void InstanceManager::unshareVertices(const Ogre::MeshPtr &mesh) + { + // Retrieve data to copy bone assignments + const Mesh::VertexBoneAssignmentList& boneAssignments = mesh->getBoneAssignments(); + Mesh::VertexBoneAssignmentList::const_iterator it = boneAssignments.begin(); + Mesh::VertexBoneAssignmentList::const_iterator end = boneAssignments.end(); + size_t curVertexOffset = 0; + + // Access shared vertices + VertexData* sharedVertexData = mesh->sharedVertexData; + + for (size_t subMeshIdx = 0; subMeshIdx < mesh->getNumSubMeshes(); subMeshIdx++) + { + SubMesh *subMesh = mesh->getSubMesh(subMeshIdx); + + IndexData *indexData = subMesh->indexData; + HardwareIndexBuffer::IndexType idxType = indexData->indexBuffer->getType(); + IndicesMap indicesMap = (idxType == HardwareIndexBuffer::IT_16BIT) ? getUsedIndices(indexData) : + getUsedIndices(indexData); + + + VertexData *newVertexData = new VertexData(); + newVertexData->vertexCount = indicesMap.size(); + newVertexData->vertexDeclaration = sharedVertexData->vertexDeclaration->clone(); + + for (size_t bufIdx = 0; bufIdx < sharedVertexData->vertexBufferBinding->getBufferCount(); bufIdx++) + { + HardwareVertexBufferSharedPtr sharedVertexBuffer = sharedVertexData->vertexBufferBinding->getBuffer(bufIdx); + size_t vertexSize = sharedVertexBuffer->getVertexSize(); + + HardwareVertexBufferSharedPtr newVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer + (vertexSize, newVertexData->vertexCount, sharedVertexBuffer->getUsage(), sharedVertexBuffer->hasShadowBuffer()); + + uint8 *oldLock = (uint8*)sharedVertexBuffer->lock(0, sharedVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_READ_ONLY); + uint8 *newLock = (uint8*)newVertexBuffer->lock(0, newVertexData->vertexCount * vertexSize, HardwareBuffer::HBL_NORMAL); + + IndicesMap::iterator indIt = indicesMap.begin(); + IndicesMap::iterator endIndIt = indicesMap.end(); + for (; indIt != endIndIt; ++indIt) + { + memcpy(newLock + vertexSize * indIt->second, oldLock + vertexSize * indIt->first, vertexSize); + } + + sharedVertexBuffer->unlock(); + newVertexBuffer->unlock(); + + newVertexData->vertexBufferBinding->setBinding(bufIdx, newVertexBuffer); + } + + if (idxType == HardwareIndexBuffer::IT_16BIT) + { + copyIndexBuffer(indexData, indicesMap); + } + else + { + copyIndexBuffer(indexData, indicesMap); + } + + // Store new attributes + subMesh->useSharedVertices = false; + subMesh->vertexData = newVertexData; + + // Transfer bone assignments to the submesh + size_t offset = curVertexOffset + newVertexData->vertexCount; + for (; it != end; ++it) + { + size_t vertexIdx = (*it).first; + if (vertexIdx > offset) + break; + + VertexBoneAssignment boneAssignment = (*it).second; + boneAssignment.vertexIndex = static_cast(boneAssignment.vertexIndex - curVertexOffset); + subMesh->addBoneAssignment(boneAssignment); + } + curVertexOffset = newVertexData->vertexCount + 1; + } + + // Release shared vertex data + delete mesh->sharedVertexData; + mesh->sharedVertexData = NULL; + mesh->clearBoneAssignments(); + } + //----------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreInstancedEntity.cpp b/OgreMain/src/OgreInstancedEntity.cpp index ca458b14283..b7a3e1764c7 100644 --- a/OgreMain/src/OgreInstancedEntity.cpp +++ b/OgreMain/src/OgreInstancedEntity.cpp @@ -37,355 +37,355 @@ THE SOFTWARE. namespace Ogre { - NameGenerator InstancedEntity::msNameGenerator(""); + NameGenerator InstancedEntity::msNameGenerator(""); - InstancedEntity::InstancedEntity( InstanceBatch *batchOwner, uint32 instanceID, InstancedEntity* sharedTransformEntity ) : - MovableObject(), - mInstanceId( instanceID ), + InstancedEntity::InstancedEntity( InstanceBatch *batchOwner, uint32 instanceID, InstancedEntity* sharedTransformEntity ) : + MovableObject(), + mInstanceId( instanceID ), mInUse( false ), - mBatchOwner( batchOwner ), - mAnimationState( 0 ), - mSkeletonInstance( 0 ), - mBoneMatrices(0), - mBoneWorldMatrices(0), - mFrameAnimationLastUpdated(std::numeric_limits::max() - 1), - mSharedTransformEntity( 0 ), - mTransformLookupNumber(instanceID), - mPosition(Vector3::ZERO), - mDerivedLocalPosition(Vector3::ZERO), - mOrientation(Quaternion::IDENTITY), - mScale(Vector3::UNIT_SCALE), - mMaxScaleLocal(1), - mNeedTransformUpdate(true), - mNeedAnimTransformUpdate(true), - mUseLocalTransform(false) - - - { - //Use a static name generator to ensure this name stays unique (which may not happen - //otherwise due to reparenting when defragmenting) - mName = batchOwner->getName() + "/InstancedEntity_" + StringConverter::toString(mInstanceId) + "/"+ - msNameGenerator.generate(); - - if (sharedTransformEntity) - { - sharedTransformEntity->shareTransformWith(this); - } - else - { - createSkeletonInstance(); - } - updateTransforms(); - } - - InstancedEntity::~InstancedEntity() - { - unlinkTransform(); - destroySkeletonInstance(); - } - - bool InstancedEntity::shareTransformWith( InstancedEntity *slave ) - { - if( !this->mBatchOwner->_getMeshRef()->hasSkeleton() || - this->mBatchOwner->_getMeshRef()->getSkeleton().isNull() || - !this->mBatchOwner->_supportsSkeletalAnimation() ) - { - return false; - } - - if( this->mSharedTransformEntity ) - { - OGRE_EXCEPT( Exception::ERR_INVALID_STATE, "Attempted to share '" + mName + "' transforms " - "with slave '" + slave->mName + "' but '" + mName +"' is " - "already sharing. Hierarchical sharing not allowed.", - "InstancedEntity::shareTransformWith" ); - return false; - } - - if( this->mBatchOwner->_getMeshRef()->getSkeleton() != - slave->mBatchOwner->_getMeshRef()->getSkeleton() ) - { - OGRE_EXCEPT( Exception::ERR_INVALID_STATE, "Sharing transforms requires both instanced" - " entities to have the same skeleton", - "InstancedEntity::shareTransformWith" ); - return false; - } - - slave->unlinkTransform(); - slave->destroySkeletonInstance(); - - slave->mSkeletonInstance = this->mSkeletonInstance; - slave->mAnimationState = this->mAnimationState; - slave->mBoneMatrices = this->mBoneMatrices; - if (mBatchOwner->useBoneWorldMatrices()) - { - slave->mBoneWorldMatrices = this->mBoneWorldMatrices; - } - slave->mSharedTransformEntity = this; - //The sharing partners are kept in the parent entity - this->mSharingPartners.push_back( slave ); - - slave->mBatchOwner->_markTransformSharingDirty(); - - return true; - } - //----------------------------------------------------------------------- - void InstancedEntity::stopSharingTransform() - { - if( mSharedTransformEntity ) - { - stopSharingTransformAsSlave( true ); - } - else - { - //Tell the ones sharing skeleton with us to use their own - InstancedEntityVec::const_iterator itor = mSharingPartners.begin(); - InstancedEntityVec::const_iterator end = mSharingPartners.end(); - while( itor != end ) - { - (*itor)->stopSharingTransformAsSlave( false ); - ++itor; - } - mSharingPartners.clear(); - } - } - //----------------------------------------------------------------------- - const String& InstancedEntity::getMovableType(void) const - { - static String sType = "InstancedEntity"; - return sType; - } - //----------------------------------------------------------------------- - size_t InstancedEntity::getTransforms( Matrix4 *xform ) const - { - size_t retVal = 1; - - //When not attached, returns zero matrix to avoid rendering this one, not identity - if( isVisible() && isInScene() ) - { - if( !mSkeletonInstance ) - { - *xform = mBatchOwner->useBoneWorldMatrices() ? - _getParentNodeFullTransform() : Matrix4::IDENTITY; - } - else - { - Matrix4* matrices = mBatchOwner->useBoneWorldMatrices() ? mBoneWorldMatrices : mBoneMatrices; - const Mesh::IndexMap *indexMap = mBatchOwner->_getIndexToBoneMap(); - Mesh::IndexMap::const_iterator itor = indexMap->begin(); - Mesh::IndexMap::const_iterator end = indexMap->end(); - - while( itor != end ) - *xform++ = matrices[*itor++]; - - retVal = indexMap->size(); - } - } - else - { - if( mSkeletonInstance ) - retVal = mBatchOwner->_getIndexToBoneMap()->size(); - - std::fill_n( xform, retVal, Matrix4::ZEROAFFINE ); - } - - return retVal; - } - //----------------------------------------------------------------------- - size_t InstancedEntity::getTransforms3x4( float *xform ) const - { - size_t retVal; - //When not attached, returns zero matrix to avoid rendering this one, not identity - if( isVisible() && isInScene() ) - { - if( !mSkeletonInstance ) - { - const Matrix4& mat = mBatchOwner->useBoneWorldMatrices() ? - _getParentNodeFullTransform() : Matrix4::IDENTITY; - for( int i=0; i<3; ++i ) - { - Real const *row = mat[i]; - for( int j=0; j<4; ++j ) - *xform++ = static_cast( *row++ ); - } - - retVal = 12; - } - else - { - Matrix4* matrices = mBatchOwner->useBoneWorldMatrices() ? mBoneWorldMatrices : mBoneMatrices; - - const Mesh::IndexMap *indexMap = mBatchOwner->_getIndexToBoneMap(); - Mesh::IndexMap::const_iterator itor = indexMap->begin(); - Mesh::IndexMap::const_iterator end = indexMap->end(); - - while( itor != end ) - { - const Matrix4 &mat = matrices[*itor++]; - for( int i=0; i<3; ++i ) - { - Real const *row = mat[i]; - for( int j=0; j<4; ++j ) - *xform++ = static_cast( *row++ ); - } - } - - retVal = indexMap->size() * 4 * 3; - } - } - else - { - if( mSkeletonInstance ) - retVal = mBatchOwner->_getIndexToBoneMap()->size() * 3 * 4; - else - retVal = 12; - - std::fill_n( xform, retVal, 0.0f ); - } - - return retVal; - } - //----------------------------------------------------------------------- - bool InstancedEntity::findVisible( Camera *camera ) const - { - //Object is active - bool retVal = isInScene(); - if (retVal) - { - //check object is explicitly visible - retVal = isVisible(); - - //Object's bounding box is viewed by the camera - if( retVal && camera ) - retVal = camera->isVisible(Sphere(_getDerivedPosition(),getBoundingRadius())); - } - - return retVal; - } - //----------------------------------------------------------------------- - void InstancedEntity::createSkeletonInstance() - { - //Is mesh skeletally animated? - if( mBatchOwner->_getMeshRef()->hasSkeleton() && - !mBatchOwner->_getMeshRef()->getSkeleton().isNull() && - mBatchOwner->_supportsSkeletalAnimation() ) - { - mSkeletonInstance = OGRE_NEW SkeletonInstance( mBatchOwner->_getMeshRef()->getSkeleton() ); - mSkeletonInstance->load(); - - mBoneMatrices = static_cast(OGRE_MALLOC_SIMD( sizeof(Matrix4) * - mSkeletonInstance->getNumBones(), - MEMCATEGORY_ANIMATION)); - if (mBatchOwner->useBoneWorldMatrices()) - { - mBoneWorldMatrices = static_cast(OGRE_MALLOC_SIMD( sizeof(Matrix4) * - mSkeletonInstance->getNumBones(), - MEMCATEGORY_ANIMATION)); - } - - mAnimationState = OGRE_NEW AnimationStateSet(); - mBatchOwner->_getMeshRef()->_initAnimationState( mAnimationState ); - } - } - //----------------------------------------------------------------------- - void InstancedEntity::destroySkeletonInstance() - { - if( mSkeletonInstance ) - { - //Tell the ones sharing skeleton with us to use their own - //sharing partners will remove themselves from notifyUnlink - while( mSharingPartners.empty() == false ) - { - mSharingPartners.front()->stopSharingTransform(); - } - mSharingPartners.clear(); - - OGRE_DELETE mSkeletonInstance; - OGRE_DELETE mAnimationState; - OGRE_FREE_SIMD( mBoneMatrices, MEMCATEGORY_ANIMATION ); - OGRE_FREE_SIMD( mBoneWorldMatrices, MEMCATEGORY_ANIMATION ); - - mSkeletonInstance = 0; - mAnimationState = 0; - mBoneMatrices = 0; - mBoneWorldMatrices = 0; - } - } - //----------------------------------------------------------------------- - void InstancedEntity::stopSharingTransformAsSlave( bool notifyMaster ) - { - unlinkTransform( notifyMaster ); - createSkeletonInstance(); - } - //----------------------------------------------------------------------- - void InstancedEntity::unlinkTransform( bool notifyMaster ) - { - if( mSharedTransformEntity ) - { - //Tell our master we're no longer his slave - if( notifyMaster ) - mSharedTransformEntity->notifyUnlink( this ); - mBatchOwner->_markTransformSharingDirty(); - - mSkeletonInstance = 0; - mAnimationState = 0; - mBoneMatrices = 0; - mBoneWorldMatrices = 0; - mSharedTransformEntity = 0; - } - } - //----------------------------------------------------------------------- - void InstancedEntity::notifyUnlink( const InstancedEntity *slave ) - { - //Find the slave and remove it - InstancedEntityVec::iterator itor = mSharingPartners.begin(); - InstancedEntityVec::iterator end = mSharingPartners.end(); - while( itor != end ) - { - if( *itor == slave ) - { - std::swap(*itor,mSharingPartners.back()); - mSharingPartners.pop_back(); - break; - } - - ++itor; - } - } - //----------------------------------------------------------------------- + mBatchOwner( batchOwner ), + mAnimationState( 0 ), + mSkeletonInstance( 0 ), + mBoneMatrices(0), + mBoneWorldMatrices(0), + mFrameAnimationLastUpdated(std::numeric_limits::max() - 1), + mSharedTransformEntity( 0 ), + mTransformLookupNumber(instanceID), + mPosition(Vector3::ZERO), + mDerivedLocalPosition(Vector3::ZERO), + mOrientation(Quaternion::IDENTITY), + mScale(Vector3::UNIT_SCALE), + mMaxScaleLocal(1), + mNeedTransformUpdate(true), + mNeedAnimTransformUpdate(true), + mUseLocalTransform(false) + + + { + //Use a static name generator to ensure this name stays unique (which may not happen + //otherwise due to reparenting when defragmenting) + mName = batchOwner->getName() + "/InstancedEntity_" + StringConverter::toString(mInstanceId) + "/"+ + msNameGenerator.generate(); + + if (sharedTransformEntity) + { + sharedTransformEntity->shareTransformWith(this); + } + else + { + createSkeletonInstance(); + } + updateTransforms(); + } + + InstancedEntity::~InstancedEntity() + { + unlinkTransform(); + destroySkeletonInstance(); + } + + bool InstancedEntity::shareTransformWith( InstancedEntity *slave ) + { + if( !this->mBatchOwner->_getMeshRef()->hasSkeleton() || + this->mBatchOwner->_getMeshRef()->getSkeleton().isNull() || + !this->mBatchOwner->_supportsSkeletalAnimation() ) + { + return false; + } + + if( this->mSharedTransformEntity ) + { + OGRE_EXCEPT( Exception::ERR_INVALID_STATE, "Attempted to share '" + mName + "' transforms " + "with slave '" + slave->mName + "' but '" + mName +"' is " + "already sharing. Hierarchical sharing not allowed.", + "InstancedEntity::shareTransformWith" ); + return false; + } + + if( this->mBatchOwner->_getMeshRef()->getSkeleton() != + slave->mBatchOwner->_getMeshRef()->getSkeleton() ) + { + OGRE_EXCEPT( Exception::ERR_INVALID_STATE, "Sharing transforms requires both instanced" + " entities to have the same skeleton", + "InstancedEntity::shareTransformWith" ); + return false; + } + + slave->unlinkTransform(); + slave->destroySkeletonInstance(); + + slave->mSkeletonInstance = this->mSkeletonInstance; + slave->mAnimationState = this->mAnimationState; + slave->mBoneMatrices = this->mBoneMatrices; + if (mBatchOwner->useBoneWorldMatrices()) + { + slave->mBoneWorldMatrices = this->mBoneWorldMatrices; + } + slave->mSharedTransformEntity = this; + //The sharing partners are kept in the parent entity + this->mSharingPartners.push_back( slave ); + + slave->mBatchOwner->_markTransformSharingDirty(); + + return true; + } + //----------------------------------------------------------------------- + void InstancedEntity::stopSharingTransform() + { + if( mSharedTransformEntity ) + { + stopSharingTransformAsSlave( true ); + } + else + { + //Tell the ones sharing skeleton with us to use their own + InstancedEntityVec::const_iterator itor = mSharingPartners.begin(); + InstancedEntityVec::const_iterator end = mSharingPartners.end(); + while( itor != end ) + { + (*itor)->stopSharingTransformAsSlave( false ); + ++itor; + } + mSharingPartners.clear(); + } + } + //----------------------------------------------------------------------- + const String& InstancedEntity::getMovableType(void) const + { + static String sType = "InstancedEntity"; + return sType; + } + //----------------------------------------------------------------------- + size_t InstancedEntity::getTransforms( Matrix4 *xform ) const + { + size_t retVal = 1; + + //When not attached, returns zero matrix to avoid rendering this one, not identity + if( isVisible() && isInScene() ) + { + if( !mSkeletonInstance ) + { + *xform = mBatchOwner->useBoneWorldMatrices() ? + _getParentNodeFullTransform() : Matrix4::IDENTITY; + } + else + { + Matrix4* matrices = mBatchOwner->useBoneWorldMatrices() ? mBoneWorldMatrices : mBoneMatrices; + const Mesh::IndexMap *indexMap = mBatchOwner->_getIndexToBoneMap(); + Mesh::IndexMap::const_iterator itor = indexMap->begin(); + Mesh::IndexMap::const_iterator end = indexMap->end(); + + while( itor != end ) + *xform++ = matrices[*itor++]; + + retVal = indexMap->size(); + } + } + else + { + if( mSkeletonInstance ) + retVal = mBatchOwner->_getIndexToBoneMap()->size(); + + std::fill_n( xform, retVal, Matrix4::ZEROAFFINE ); + } + + return retVal; + } + //----------------------------------------------------------------------- + size_t InstancedEntity::getTransforms3x4( float *xform ) const + { + size_t retVal; + //When not attached, returns zero matrix to avoid rendering this one, not identity + if( isVisible() && isInScene() ) + { + if( !mSkeletonInstance ) + { + const Matrix4& mat = mBatchOwner->useBoneWorldMatrices() ? + _getParentNodeFullTransform() : Matrix4::IDENTITY; + for( int i=0; i<3; ++i ) + { + Real const *row = mat[i]; + for( int j=0; j<4; ++j ) + *xform++ = static_cast( *row++ ); + } + + retVal = 12; + } + else + { + Matrix4* matrices = mBatchOwner->useBoneWorldMatrices() ? mBoneWorldMatrices : mBoneMatrices; + + const Mesh::IndexMap *indexMap = mBatchOwner->_getIndexToBoneMap(); + Mesh::IndexMap::const_iterator itor = indexMap->begin(); + Mesh::IndexMap::const_iterator end = indexMap->end(); + + while( itor != end ) + { + const Matrix4 &mat = matrices[*itor++]; + for( int i=0; i<3; ++i ) + { + Real const *row = mat[i]; + for( int j=0; j<4; ++j ) + *xform++ = static_cast( *row++ ); + } + } + + retVal = indexMap->size() * 4 * 3; + } + } + else + { + if( mSkeletonInstance ) + retVal = mBatchOwner->_getIndexToBoneMap()->size() * 3 * 4; + else + retVal = 12; + + std::fill_n( xform, retVal, 0.0f ); + } + + return retVal; + } + //----------------------------------------------------------------------- + bool InstancedEntity::findVisible( Camera *camera ) const + { + //Object is active + bool retVal = isInScene(); + if (retVal) + { + //check object is explicitly visible + retVal = isVisible(); + + //Object's bounding box is viewed by the camera + if( retVal && camera ) + retVal = camera->isVisible(Sphere(_getDerivedPosition(),getBoundingRadius())); + } + + return retVal; + } + //----------------------------------------------------------------------- + void InstancedEntity::createSkeletonInstance() + { + //Is mesh skeletally animated? + if( mBatchOwner->_getMeshRef()->hasSkeleton() && + !mBatchOwner->_getMeshRef()->getSkeleton().isNull() && + mBatchOwner->_supportsSkeletalAnimation() ) + { + mSkeletonInstance = OGRE_NEW SkeletonInstance( mBatchOwner->_getMeshRef()->getSkeleton() ); + mSkeletonInstance->load(); + + mBoneMatrices = static_cast(OGRE_MALLOC_SIMD( sizeof(Matrix4) * + mSkeletonInstance->getNumBones(), + MEMCATEGORY_ANIMATION)); + if (mBatchOwner->useBoneWorldMatrices()) + { + mBoneWorldMatrices = static_cast(OGRE_MALLOC_SIMD( sizeof(Matrix4) * + mSkeletonInstance->getNumBones(), + MEMCATEGORY_ANIMATION)); + } + + mAnimationState = OGRE_NEW AnimationStateSet(); + mBatchOwner->_getMeshRef()->_initAnimationState( mAnimationState ); + } + } + //----------------------------------------------------------------------- + void InstancedEntity::destroySkeletonInstance() + { + if( mSkeletonInstance ) + { + //Tell the ones sharing skeleton with us to use their own + //sharing partners will remove themselves from notifyUnlink + while( mSharingPartners.empty() == false ) + { + mSharingPartners.front()->stopSharingTransform(); + } + mSharingPartners.clear(); + + OGRE_DELETE mSkeletonInstance; + OGRE_DELETE mAnimationState; + OGRE_FREE_SIMD( mBoneMatrices, MEMCATEGORY_ANIMATION ); + OGRE_FREE_SIMD( mBoneWorldMatrices, MEMCATEGORY_ANIMATION ); + + mSkeletonInstance = 0; + mAnimationState = 0; + mBoneMatrices = 0; + mBoneWorldMatrices = 0; + } + } + //----------------------------------------------------------------------- + void InstancedEntity::stopSharingTransformAsSlave( bool notifyMaster ) + { + unlinkTransform( notifyMaster ); + createSkeletonInstance(); + } + //----------------------------------------------------------------------- + void InstancedEntity::unlinkTransform( bool notifyMaster ) + { + if( mSharedTransformEntity ) + { + //Tell our master we're no longer his slave + if( notifyMaster ) + mSharedTransformEntity->notifyUnlink( this ); + mBatchOwner->_markTransformSharingDirty(); + + mSkeletonInstance = 0; + mAnimationState = 0; + mBoneMatrices = 0; + mBoneWorldMatrices = 0; + mSharedTransformEntity = 0; + } + } + //----------------------------------------------------------------------- + void InstancedEntity::notifyUnlink( const InstancedEntity *slave ) + { + //Find the slave and remove it + InstancedEntityVec::iterator itor = mSharingPartners.begin(); + InstancedEntityVec::iterator end = mSharingPartners.end(); + while( itor != end ) + { + if( *itor == slave ) + { + std::swap(*itor,mSharingPartners.back()); + mSharingPartners.pop_back(); + break; + } + + ++itor; + } + } + //----------------------------------------------------------------------- const AxisAlignedBox& InstancedEntity::getBoundingBox(void) const { - //TODO: Add attached objects (TagPoints) to the bbox - return mBatchOwner->_getMeshReference()->getBounds(); + //TODO: Add attached objects (TagPoints) to the bbox + return mBatchOwner->_getMeshReference()->getBounds(); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- Real InstancedEntity::getBoundingRadius(void) const - { - return mBatchOwner->_getMeshReference()->getBoundingSphereRadius() * getMaxScaleCoef(); - } - //----------------------------------------------------------------------- - Real InstancedEntity::getSquaredViewDepth( const Camera* cam ) const - { - return _getDerivedPosition().squaredDistance(cam->getDerivedPosition()); - } - //----------------------------------------------------------------------- - void InstancedEntity::_notifyMoved(void) - { - markTransformDirty(); - MovableObject::_notifyMoved(); - updateTransforms(); - } - - //----------------------------------------------------------------------- - void InstancedEntity::_notifyAttached( Node* parent, bool isTagPoint ) - { - markTransformDirty(); - MovableObject::_notifyAttached( parent, isTagPoint ); - updateTransforms(); - } - //----------------------------------------------------------------------- - AnimationState* InstancedEntity::getAnimationState(const String& name) const + { + return mBatchOwner->_getMeshReference()->getBoundingSphereRadius() * getMaxScaleCoef(); + } + //----------------------------------------------------------------------- + Real InstancedEntity::getSquaredViewDepth( const Camera* cam ) const + { + return _getDerivedPosition().squaredDistance(cam->getDerivedPosition()); + } + //----------------------------------------------------------------------- + void InstancedEntity::_notifyMoved(void) + { + markTransformDirty(); + MovableObject::_notifyMoved(); + updateTransforms(); + } + + //----------------------------------------------------------------------- + void InstancedEntity::_notifyAttached( Node* parent, bool isTagPoint ) + { + markTransformDirty(); + MovableObject::_notifyAttached( parent, isTagPoint ); + updateTransforms(); + } + //----------------------------------------------------------------------- + AnimationState* InstancedEntity::getAnimationState(const String& name) const { if (!mAnimationState) { @@ -393,141 +393,141 @@ namespace Ogre "InstancedEntity::getAnimationState"); } - return mAnimationState->getAnimationState(name); + return mAnimationState->getAnimationState(name); } //----------------------------------------------------------------------- AnimationStateSet* InstancedEntity::getAllAnimationStates(void) const { return mAnimationState; } - //----------------------------------------------------------------------- - bool InstancedEntity::_updateAnimation(void) - { - if (mSharedTransformEntity) - { - return mSharedTransformEntity->_updateAnimation(); - } - else - { - const bool animationDirty = - (mFrameAnimationLastUpdated != mAnimationState->getDirtyFrameNumber()) || - (mSkeletonInstance->getManualBonesDirty()); - - if( animationDirty || (mNeedAnimTransformUpdate && mBatchOwner->useBoneWorldMatrices())) - { - mSkeletonInstance->setAnimationState( *mAnimationState ); - mSkeletonInstance->_getBoneMatrices( mBoneMatrices ); - - // Cache last parent transform for next frame use too. - if (mBatchOwner->useBoneWorldMatrices()) - { - OptimisedUtil::getImplementation()->concatenateAffineMatrices( - _getParentNodeFullTransform(), - mBoneMatrices, - mBoneWorldMatrices, - mSkeletonInstance->getNumBones() ); - mNeedAnimTransformUpdate = false; - } - - mFrameAnimationLastUpdated = mAnimationState->getDirtyFrameNumber(); - - return true; - } - } - - return false; - } - - //----------------------------------------------------------------------- - void InstancedEntity::markTransformDirty() - { - mNeedTransformUpdate = true; - mNeedAnimTransformUpdate = true; - mBatchOwner->_boundsDirty(); - } - - //--------------------------------------------------------------------------- - void InstancedEntity::setPosition(const Vector3& position, bool doUpdate) - { - mPosition = position; - mDerivedLocalPosition = position; - mUseLocalTransform = true; - markTransformDirty(); - if (doUpdate) updateTransforms(); - } - - //--------------------------------------------------------------------------- - void InstancedEntity::setOrientation(const Quaternion& orientation, bool doUpdate) - { - mOrientation = orientation; - mUseLocalTransform = true; - markTransformDirty(); - if (doUpdate) updateTransforms(); - } - - //--------------------------------------------------------------------------- - void InstancedEntity::setScale(const Vector3& scale, bool doUpdate) - { - mScale = scale; - mMaxScaleLocal = std::max(std::max( - Math::Abs(mScale.x), Math::Abs(mScale.y)), Math::Abs(mScale.z)); - mUseLocalTransform = true; - markTransformDirty(); - if (doUpdate) updateTransforms(); - } - - //--------------------------------------------------------------------------- - Real InstancedEntity::getMaxScaleCoef() const - { - if (mParentNode) - { - const Ogre::Vector3& parentScale = mParentNode->_getDerivedScale(); - return mMaxScaleLocal * std::max(std::max( - Math::Abs(parentScale.x), Math::Abs(parentScale.y)), Math::Abs(parentScale.z)); - } - return mMaxScaleLocal; - } - - //--------------------------------------------------------------------------- - void InstancedEntity::updateTransforms() - { - if (mUseLocalTransform && mNeedTransformUpdate) - { - if (mParentNode) - { - const Vector3& parentPosition = mParentNode->_getDerivedPosition(); - const Quaternion& parentOrientation = mParentNode->_getDerivedOrientation(); - const Vector3& parentScale = mParentNode->_getDerivedScale(); - - Quaternion derivedOrientation = parentOrientation * mOrientation; - Vector3 derivedScale = parentScale * mScale; - mDerivedLocalPosition = parentOrientation * (parentScale * mPosition) + parentPosition; - - mFullLocalTransform.makeTransform(mDerivedLocalPosition, derivedScale, derivedOrientation); - } - else - { - mFullLocalTransform.makeTransform(mPosition,mScale,mOrientation); - } - mNeedTransformUpdate = false; - } - } - - //--------------------------------------------------------------------------- - void InstancedEntity::setInUse( bool used ) - { - mInUse = used; - //Remove the use of local transform if the object is deleted - mUseLocalTransform &= used; - } - //--------------------------------------------------------------------------- - void InstancedEntity::setCustomParam( unsigned char idx, const Vector4 &newParam ) - { - mBatchOwner->_setCustomParam( this, idx, newParam ); - } - //--------------------------------------------------------------------------- - const Vector4& InstancedEntity::getCustomParam( unsigned char idx ) - { - return mBatchOwner->_getCustomParam( this, idx ); - } + //----------------------------------------------------------------------- + bool InstancedEntity::_updateAnimation(void) + { + if (mSharedTransformEntity) + { + return mSharedTransformEntity->_updateAnimation(); + } + else + { + const bool animationDirty = + (mFrameAnimationLastUpdated != mAnimationState->getDirtyFrameNumber()) || + (mSkeletonInstance->getManualBonesDirty()); + + if( animationDirty || (mNeedAnimTransformUpdate && mBatchOwner->useBoneWorldMatrices())) + { + mSkeletonInstance->setAnimationState( *mAnimationState ); + mSkeletonInstance->_getBoneMatrices( mBoneMatrices ); + + // Cache last parent transform for next frame use too. + if (mBatchOwner->useBoneWorldMatrices()) + { + OptimisedUtil::getImplementation()->concatenateAffineMatrices( + _getParentNodeFullTransform(), + mBoneMatrices, + mBoneWorldMatrices, + mSkeletonInstance->getNumBones() ); + mNeedAnimTransformUpdate = false; + } + + mFrameAnimationLastUpdated = mAnimationState->getDirtyFrameNumber(); + + return true; + } + } + + return false; + } + + //----------------------------------------------------------------------- + void InstancedEntity::markTransformDirty() + { + mNeedTransformUpdate = true; + mNeedAnimTransformUpdate = true; + mBatchOwner->_boundsDirty(); + } + + //--------------------------------------------------------------------------- + void InstancedEntity::setPosition(const Vector3& position, bool doUpdate) + { + mPosition = position; + mDerivedLocalPosition = position; + mUseLocalTransform = true; + markTransformDirty(); + if (doUpdate) updateTransforms(); + } + + //--------------------------------------------------------------------------- + void InstancedEntity::setOrientation(const Quaternion& orientation, bool doUpdate) + { + mOrientation = orientation; + mUseLocalTransform = true; + markTransformDirty(); + if (doUpdate) updateTransforms(); + } + + //--------------------------------------------------------------------------- + void InstancedEntity::setScale(const Vector3& scale, bool doUpdate) + { + mScale = scale; + mMaxScaleLocal = std::max(std::max( + Math::Abs(mScale.x), Math::Abs(mScale.y)), Math::Abs(mScale.z)); + mUseLocalTransform = true; + markTransformDirty(); + if (doUpdate) updateTransforms(); + } + + //--------------------------------------------------------------------------- + Real InstancedEntity::getMaxScaleCoef() const + { + if (mParentNode) + { + const Ogre::Vector3& parentScale = mParentNode->_getDerivedScale(); + return mMaxScaleLocal * std::max(std::max( + Math::Abs(parentScale.x), Math::Abs(parentScale.y)), Math::Abs(parentScale.z)); + } + return mMaxScaleLocal; + } + + //--------------------------------------------------------------------------- + void InstancedEntity::updateTransforms() + { + if (mUseLocalTransform && mNeedTransformUpdate) + { + if (mParentNode) + { + const Vector3& parentPosition = mParentNode->_getDerivedPosition(); + const Quaternion& parentOrientation = mParentNode->_getDerivedOrientation(); + const Vector3& parentScale = mParentNode->_getDerivedScale(); + + Quaternion derivedOrientation = parentOrientation * mOrientation; + Vector3 derivedScale = parentScale * mScale; + mDerivedLocalPosition = parentOrientation * (parentScale * mPosition) + parentPosition; + + mFullLocalTransform.makeTransform(mDerivedLocalPosition, derivedScale, derivedOrientation); + } + else + { + mFullLocalTransform.makeTransform(mPosition,mScale,mOrientation); + } + mNeedTransformUpdate = false; + } + } + + //--------------------------------------------------------------------------- + void InstancedEntity::setInUse( bool used ) + { + mInUse = used; + //Remove the use of local transform if the object is deleted + mUseLocalTransform &= used; + } + //--------------------------------------------------------------------------- + void InstancedEntity::setCustomParam( unsigned char idx, const Vector4 &newParam ) + { + mBatchOwner->_setCustomParam( this, idx, newParam ); + } + //--------------------------------------------------------------------------- + const Vector4& InstancedEntity::getCustomParam( unsigned char idx ) + { + return mBatchOwner->_getCustomParam( this, idx ); + } } diff --git a/OgreMain/src/OgreInstancedGeometry.cpp b/OgreMain/src/OgreInstancedGeometry.cpp index 5f684b26c26..b8cb98664b5 100644 --- a/OgreMain/src/OgreInstancedGeometry.cpp +++ b/OgreMain/src/OgreInstancedGeometry.cpp @@ -42,1825 +42,1825 @@ THE SOFTWARE. namespace Ogre { - #define BatchInstance_RANGE 1024 - #define BatchInstance_HALF_RANGE 512 - #define BatchInstance_MAX_INDEX 511 - #define BatchInstance_MIN_INDEX -512 - - //-------------------------------------------------------------------------- - InstancedGeometry::InstancedGeometry(SceneManager* owner, const String& name): - mOwner(owner), - mName(name), - mBuilt(false), - mUpperDistance(0.0f), - mSquaredUpperDistance(0.0f), - mCastShadows(false), - mBatchInstanceDimensions(Vector3(1000,1000,1000)), - mHalfBatchInstanceDimensions(Vector3(500,500,500)), - mOrigin(Vector3(0,0,0)), - mVisible(true), + #define BatchInstance_RANGE 1024 + #define BatchInstance_HALF_RANGE 512 + #define BatchInstance_MAX_INDEX 511 + #define BatchInstance_MIN_INDEX -512 + + //-------------------------------------------------------------------------- + InstancedGeometry::InstancedGeometry(SceneManager* owner, const String& name): + mOwner(owner), + mName(name), + mBuilt(false), + mUpperDistance(0.0f), + mSquaredUpperDistance(0.0f), + mCastShadows(false), + mBatchInstanceDimensions(Vector3(1000,1000,1000)), + mHalfBatchInstanceDimensions(Vector3(500,500,500)), + mOrigin(Vector3(0,0,0)), + mVisible(true), mProvideWorldInverses(false), mRenderQueueID(RENDER_QUEUE_MAIN), mRenderQueueIDSet(false), - mObjectCount(0), - mInstancedGeometryInstance(0), - mSkeletonInstance(0), + mObjectCount(0), + mInstancedGeometryInstance(0), + mSkeletonInstance(0), mAnimationState(0) - { - mBaseSkeleton.setNull(); - } - //-------------------------------------------------------------------------- - InstancedGeometry::~InstancedGeometry() - { - reset(); + { + mBaseSkeleton.setNull(); + } + //-------------------------------------------------------------------------- + InstancedGeometry::~InstancedGeometry() + { + reset(); OGRE_DELETE mSkeletonInstance; - } - //-------------------------------------------------------------------------- - InstancedGeometry::BatchInstance*InstancedGeometry::getInstancedGeometryInstance(void) - { - if (!mInstancedGeometryInstance) - { - uint32 index = 0; - // Make a name - StringStream str; - str << mName << ":" << index; - - mInstancedGeometryInstance = OGRE_NEW BatchInstance(this, str.str(), mOwner, index); - mOwner->injectMovableObject(mInstancedGeometryInstance); - mInstancedGeometryInstance->setVisible(mVisible); - mInstancedGeometryInstance->setCastShadows(mCastShadows); - if (mRenderQueueIDSet) - { - mInstancedGeometryInstance->setRenderQueueGroup(mRenderQueueID); - } - mBatchInstanceMap[index] = mInstancedGeometryInstance; - - - } - return mInstancedGeometryInstance; - } - //-------------------------------------------------------------------------- - InstancedGeometry::BatchInstance* InstancedGeometry::getBatchInstance(const AxisAlignedBox& bounds, - bool autoCreate) - { - if (bounds.isNull()) - return 0; - - // Get the BatchInstance which has the largest overlapping volume - const Vector3 min = bounds.getMinimum(); - const Vector3 max = bounds.getMaximum(); - - // Get the min and max BatchInstance indexes - ushort minx, miny, minz; - ushort maxx, maxy, maxz; - getBatchInstanceIndexes(min, minx, miny, minz); - getBatchInstanceIndexes(max, maxx, maxy, maxz); - Real maxVolume = 0.0f; - ushort finalx =0 , finaly = 0, finalz = 0; - for (ushort x = minx; x <= maxx; ++x) - { - for (ushort y = miny; y <= maxy; ++y) - { - for (ushort z = minz; z <= maxz; ++z) - { - Real vol = getVolumeIntersection(bounds, x, y, z); - if (vol > maxVolume) - { - maxVolume = vol; - finalx = x; - finaly = y; - finalz = z; - } - - } - } - } - - assert(maxVolume > 0.0f && - "Static geometry: Problem determining closest volume match!"); - - return getBatchInstance(finalx, finaly, finalz, autoCreate); - - } - //-------------------------------------------------------------------------- - Real InstancedGeometry::getVolumeIntersection(const AxisAlignedBox& box, - ushort x, ushort y, ushort z) - { - // Get bounds of indexed BatchInstance - AxisAlignedBox BatchInstanceBounds = getBatchInstanceBounds(x, y, z); - AxisAlignedBox intersectBox = BatchInstanceBounds.intersection(box); - // return a 'volume' which ignores zero dimensions - // since we only use this for relative comparisons of the same bounds - // this will still be internally consistent - Vector3 boxdiff = box.getMaximum() - box.getMinimum(); - Vector3 intersectDiff = intersectBox.getMaximum() - intersectBox.getMinimum(); - - return (boxdiff.x == 0 ? 1 : intersectDiff.x) * - (boxdiff.y == 0 ? 1 : intersectDiff.y) * - (boxdiff.z == 0 ? 1 : intersectDiff.z); - - } - //-------------------------------------------------------------------------- - AxisAlignedBox InstancedGeometry::getBatchInstanceBounds(ushort x, ushort y, ushort z) - { - Vector3 min( - ((Real)x - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.x + mOrigin.x, - ((Real)y - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.y + mOrigin.y, - ((Real)z - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.z + mOrigin.z - ); - Vector3 max = min + mBatchInstanceDimensions; - return AxisAlignedBox(min, max); - } - //-------------------------------------------------------------------------- - Vector3 InstancedGeometry::getBatchInstanceCentre(ushort x, ushort y, ushort z) - { - return Vector3( - ((Real)x - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.x + mOrigin.x - + mHalfBatchInstanceDimensions.x, - ((Real)y - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.y + mOrigin.y - + mHalfBatchInstanceDimensions.y, - ((Real)z - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.z + mOrigin.z - + mHalfBatchInstanceDimensions.z - ); - } - //-------------------------------------------------------------------------- - InstancedGeometry::BatchInstance* InstancedGeometry::getBatchInstance( - ushort x, ushort y, ushort z, bool autoCreate) - { - uint32 index = packIndex(x, y, z); - BatchInstance* ret = getBatchInstance(index); - if (!ret && autoCreate) - { - // Make a name - StringStream str; - str << mName << ":" << index; - // Calculate the BatchInstance centre - Vector3 centre(0,0,0);// = getBatchInstanceCentre(x, y, z); - ret = OGRE_NEW BatchInstance(this, str.str(), mOwner, index/*, centre*/); - mOwner->injectMovableObject(ret); - ret->setVisible(mVisible); - ret->setCastShadows(mCastShadows); - if (mRenderQueueIDSet) - { - ret->setRenderQueueGroup(mRenderQueueID); - } - mBatchInstanceMap[index] = ret; - } - return ret; - } - //-------------------------------------------------------------------------- - InstancedGeometry::BatchInstance* InstancedGeometry::getBatchInstance(uint32 index) - { - BatchInstanceMap::iterator i = mBatchInstanceMap.find(index); - if (i != mBatchInstanceMap.end()) - { - return i->second; - } - else - { - return 0; - } - - } - //-------------------------------------------------------------------------- - void InstancedGeometry::getBatchInstanceIndexes(const Vector3& point, - ushort& x, ushort& y, ushort& z) - { - // Scale the point into multiples of BatchInstance and adjust for origin - Vector3 scaledPoint = (point - mOrigin) / mBatchInstanceDimensions; - - // Round down to 'bottom left' point which represents the cell index - int ix = Math::IFloor(scaledPoint.x); - int iy = Math::IFloor(scaledPoint.y); - int iz = Math::IFloor(scaledPoint.z); - - // Check bounds - if (ix < BatchInstance_MIN_INDEX || ix > BatchInstance_MAX_INDEX - || iy < BatchInstance_MIN_INDEX || iy > BatchInstance_MAX_INDEX - || iz < BatchInstance_MIN_INDEX || iz > BatchInstance_MAX_INDEX) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Point out of bounds", - "InstancedGeometry::getBatchInstanceIndexes"); - } - // Adjust for the fact that we use unsigned values for simplicity - // (requires less faffing about for negatives give 10-bit packing - x = static_cast(ix + BatchInstance_HALF_RANGE); - y = static_cast(iy + BatchInstance_HALF_RANGE); - z = static_cast(iz + BatchInstance_HALF_RANGE); - - - } - //-------------------------------------------------------------------------- - uint32 InstancedGeometry::packIndex(ushort x, ushort y, ushort z) - { - return x + (y << 10) + (z << 20); - } - //-------------------------------------------------------------------------- - InstancedGeometry::BatchInstance* InstancedGeometry::getBatchInstance(const Vector3& point, - bool autoCreate) - { - ushort x, y, z; - getBatchInstanceIndexes(point, x, y, z); - return getBatchInstance(x, y, z, autoCreate); - } - //-------------------------------------------------------------------------- - AxisAlignedBox InstancedGeometry::calculateBounds(VertexData* vertexData, - const Vector3& position, const Quaternion& orientation, - const Vector3& scale) - { - const VertexElement* posElem = - vertexData->vertexDeclaration->findElementBySemantic( - VES_POSITION); - HardwareVertexBufferSharedPtr vbuf = - vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); - unsigned char* vertex = - static_cast( - vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); - float* pFloat; - - Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE; - bool first = true; - - for(size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) - { - posElem->baseVertexPointerToElement(vertex, &pFloat); - - Vector3 pt; - - pt.x = (*pFloat++); - pt.y = (*pFloat++); - pt.z = (*pFloat++); - // Transform to world (scale, rotate, translate) - pt = (orientation * (pt * scale)) + position; - if (first) - { - min = max = pt; - first = false; - } - else - { - min.makeFloor(pt); - max.makeCeil(pt); - } - - } - vbuf->unlock(); - return AxisAlignedBox(min, max); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::addEntity(Entity* ent, const Vector3& position, - const Quaternion& orientation, const Vector3& scale) - { - - const MeshPtr& msh = ent->getMesh(); - // Validate - if (msh->hasManualLodLevel()) - { - LogManager::getSingleton().logMessage( - "WARNING (InstancedGeometry): Manual LOD is not supported. " - "Using only highest LOD level for mesh " + msh->getName(), LML_CRITICAL); - } - - //get the skeleton of the entity, if that's not already done - if(!ent->getMesh()->getSkeleton().isNull()&&mBaseSkeleton.isNull()) - { - mBaseSkeleton=ent->getMesh()->getSkeleton(); - mSkeletonInstance= OGRE_NEW SkeletonInstance(mBaseSkeleton); - mSkeletonInstance->load(); - mAnimationState=ent->getAllAnimationStates(); - } - AxisAlignedBox sharedWorldBounds; - // queue this entities submeshes and choice of material - // also build the lists of geometry to be used for the source of lods - - - for (uint i = 0; i < ent->getNumSubEntities(); ++i) - { - SubEntity* se = ent->getSubEntity(i); - QueuedSubMesh* q = OGRE_NEW QueuedSubMesh(); - - // Get the geometry for this SubMesh - q->submesh = se->getSubMesh(); - q->geometryLodList = determineGeometry(q->submesh); - q->materialName = se->getMaterialName(); - q->orientation = orientation; - q->position = position; - q->scale = scale; - q->ID = mObjectCount; - // Determine the bounds based on the highest LOD - q->worldBounds = calculateBounds( - (*q->geometryLodList)[0].vertexData, - position, orientation, scale); - - mQueuedSubMeshes.push_back(q); - } - mObjectCount++; - - } - //-------------------------------------------------------------------------- - InstancedGeometry::SubMeshLodGeometryLinkList* - InstancedGeometry::determineGeometry(SubMesh* sm) - { - // First, determine if we've already seen this submesh before - SubMeshGeometryLookup::iterator i = - mSubMeshGeometryLookup.find(sm); - if (i != mSubMeshGeometryLookup.end()) - { - return i->second; - } - // Otherwise, we have to create a new one - SubMeshLodGeometryLinkList* lodList = OGRE_NEW_T(SubMeshLodGeometryLinkList, MEMCATEGORY_GEOMETRY)(); - mSubMeshGeometryLookup[sm] = lodList; - ushort numLods = sm->parent->hasManualLodLevel() ? 1 : - sm->parent->getNumLodLevels(); - lodList->resize(numLods); - for (ushort lod = 0; lod < numLods; ++lod) - { - SubMeshLodGeometryLink& geomLink = (*lodList)[lod]; - IndexData *lodIndexData; - if (lod == 0) - { - lodIndexData = sm->indexData; - } - else - { - lodIndexData = sm->mLodFaceList[lod - 1]; - } - // Can use the original mesh geometry? - if (sm->useSharedVertices) - { - if (sm->parent->getNumSubMeshes() == 1) - { - // Ok, this is actually our own anyway - geomLink.vertexData = sm->parent->sharedVertexData; - geomLink.indexData = lodIndexData; - } - else - { - // We have to split it - splitGeometry(sm->parent->sharedVertexData, - lodIndexData, &geomLink); - } - } - else - { - if (lod == 0) - { - // Ok, we can use the existing geometry; should be in full - // use by just this SubMesh - geomLink.vertexData = sm->vertexData; - geomLink.indexData = sm->indexData; - } - else - { - // We have to split it - splitGeometry(sm->vertexData, - lodIndexData, &geomLink); - } - } - assert (geomLink.vertexData->vertexStart == 0 && - "Cannot use vertexStart > 0 on indexed geometry due to " - "rendersystem incompatibilities - see the docs!"); - } - - - return lodList; - } - //-------------------------------------------------------------------------- - void InstancedGeometry::splitGeometry(VertexData* vd, IndexData* id, - InstancedGeometry::SubMeshLodGeometryLink* targetGeomLink) - { - // Firstly we need to scan to see how many vertices are being used - // and while we're at it, build the remap we can use later - bool use32bitIndexes = - id->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT; - IndexRemap indexRemap; - if (use32bitIndexes) - { - uint32 *p32 = static_cast(id->indexBuffer->lock( - id->indexStart, - id->indexCount * id->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - buildIndexRemap(p32, id->indexCount, indexRemap); - id->indexBuffer->unlock(); - } - else - { - uint16 *p16 = static_cast(id->indexBuffer->lock( - id->indexStart, - id->indexCount * id->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - buildIndexRemap(p16, id->indexCount, indexRemap); - id->indexBuffer->unlock(); - } - if (indexRemap.size() == vd->vertexCount) - { - // ha, complete usage after all - targetGeomLink->vertexData = vd; - targetGeomLink->indexData = id; - return; - } - - - // Create the new vertex data records - targetGeomLink->vertexData = vd->clone(false); - // Convenience - VertexData* newvd = targetGeomLink->vertexData; - //IndexData* newid = targetGeomLink->indexData; - // Update the vertex count - newvd->vertexCount = indexRemap.size(); - - size_t numvbufs = vd->vertexBufferBinding->getBufferCount(); - // Copy buffers from old to new - for (unsigned short b = 0; b < numvbufs; ++b) - { - // Lock old buffer - HardwareVertexBufferSharedPtr oldBuf = - vd->vertexBufferBinding->getBuffer(b); - // Create new buffer - HardwareVertexBufferSharedPtr newBuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - oldBuf->getVertexSize(), - indexRemap.size(), - HardwareBuffer::HBU_STATIC); - // rebind - newvd->vertexBufferBinding->setBinding(b, newBuf); - - // Copy all the elements of the buffer across, by iterating over - // the IndexRemap which describes how to move the old vertices - // to the new ones. By nature of the map the remap is in order of - // indexes in the old buffer, but note that we're not guaranteed to - // address every vertex (which is kinda why we're here) - uchar* pSrcBase = static_cast( - oldBuf->lock(HardwareBuffer::HBL_READ_ONLY)); - uchar* pDstBase = static_cast( - newBuf->lock(HardwareBuffer::HBL_DISCARD)); - size_t vertexSize = oldBuf->getVertexSize(); - // Buffers should be the same size - assert (vertexSize == newBuf->getVertexSize()); - - for (IndexRemap::iterator r = indexRemap.begin(); - r != indexRemap.end(); ++r) - { - assert (r->first < oldBuf->getNumVertices()); - assert (r->second < newBuf->getNumVertices()); - - uchar* pSrc = pSrcBase + r->first * vertexSize; - uchar* pDst = pDstBase + r->second * vertexSize; - memcpy(pDst, pSrc, vertexSize); - } - // unlock - oldBuf->unlock(); - newBuf->unlock(); - - } - - // Now create a new index buffer - HardwareIndexBufferSharedPtr ibuf = - HardwareBufferManager::getSingleton().createIndexBuffer( - id->indexBuffer->getType(), id->indexCount, - HardwareBuffer::HBU_STATIC); - - if (use32bitIndexes) - { - uint32 *pSrc32, *pDst32; - pSrc32 = static_cast(id->indexBuffer->lock( - id->indexStart, id->indexCount * id->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - pDst32 = static_cast(ibuf->lock( - HardwareBuffer::HBL_DISCARD)); - remapIndexes(pSrc32, pDst32, indexRemap, id->indexCount); - id->indexBuffer->unlock(); - ibuf->unlock(); - } - else - { - uint16 *pSrc16, *pDst16; - pSrc16 = static_cast(id->indexBuffer->lock( - id->indexStart, id->indexCount * id->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - pDst16 = static_cast(ibuf->lock( - HardwareBuffer::HBL_DISCARD)); - remapIndexes(pSrc16, pDst16, indexRemap, id->indexCount); - id->indexBuffer->unlock(); - ibuf->unlock(); - } - - targetGeomLink->indexData = OGRE_NEW IndexData(); - targetGeomLink->indexData->indexStart = 0; - targetGeomLink->indexData->indexCount = id->indexCount; - targetGeomLink->indexData->indexBuffer = ibuf; - - // Store optimised geometry for deallocation later - OptimisedSubMeshGeometry *optGeom = OGRE_NEW OptimisedSubMeshGeometry(); - optGeom->indexData = targetGeomLink->indexData; - optGeom->vertexData = targetGeomLink->vertexData; - mOptimisedSubMeshGeometryList.push_back(optGeom); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::addSceneNode(const SceneNode* node) - { - SceneNode::ConstObjectIterator obji = node->getAttachedObjectIterator(); - while (obji.hasMoreElements()) - { - MovableObject* mobj = obji.getNext(); - if (mobj->getMovableType() == "Entity") - { - addEntity(static_cast(mobj), - node->_getDerivedPosition(), - node->_getDerivedOrientation(), - node->_getDerivedScale()); - } - } - // Iterate through all the child-nodes - SceneNode::ConstChildNodeIterator nodei = node->getChildIterator(); - - while (nodei.hasMoreElements()) - { - const SceneNode* newNode = static_cast(nodei.getNext()); - // Add this subnode and its children... - addSceneNode( newNode ); - } - } - //-------------------------------------------------------------------------- - void InstancedGeometry::build(void) - { - // Make sure there's nothing from previous builds - destroy(); - - // Firstly allocate meshes to BatchInstances - for (QueuedSubMeshList::iterator qi = mQueuedSubMeshes.begin(); - qi != mQueuedSubMeshes.end(); ++qi) - { - QueuedSubMesh* qsm = *qi; - //BatchInstance* BatchInstance = getBatchInstance(qsm->worldBounds, true); - BatchInstance* batchInstance = getInstancedGeometryInstance(); - batchInstance->assign(qsm); - } - - // Now tell each BatchInstance to build itself - for (BatchInstanceMap::iterator ri = mBatchInstanceMap.begin(); - ri != mBatchInstanceMap.end(); ++ri) - { - ri->second->build(); - } - - - } - //-------------------------------------------------------------------------- - void InstancedGeometry::addBatchInstance(void) - { - - - BatchInstanceIterator regIt = getBatchInstanceIterator(); - BatchInstance* lastBatchInstance=0 ; - while(regIt.hasMoreElements()) - { - lastBatchInstance= regIt.getNext(); - } + } + //-------------------------------------------------------------------------- + InstancedGeometry::BatchInstance*InstancedGeometry::getInstancedGeometryInstance(void) + { + if (!mInstancedGeometryInstance) + { + uint32 index = 0; + // Make a name + StringStream str; + str << mName << ":" << index; + + mInstancedGeometryInstance = OGRE_NEW BatchInstance(this, str.str(), mOwner, index); + mOwner->injectMovableObject(mInstancedGeometryInstance); + mInstancedGeometryInstance->setVisible(mVisible); + mInstancedGeometryInstance->setCastShadows(mCastShadows); + if (mRenderQueueIDSet) + { + mInstancedGeometryInstance->setRenderQueueGroup(mRenderQueueID); + } + mBatchInstanceMap[index] = mInstancedGeometryInstance; + + + } + return mInstancedGeometryInstance; + } + //-------------------------------------------------------------------------- + InstancedGeometry::BatchInstance* InstancedGeometry::getBatchInstance(const AxisAlignedBox& bounds, + bool autoCreate) + { + if (bounds.isNull()) + return 0; + + // Get the BatchInstance which has the largest overlapping volume + const Vector3 min = bounds.getMinimum(); + const Vector3 max = bounds.getMaximum(); + + // Get the min and max BatchInstance indexes + ushort minx, miny, minz; + ushort maxx, maxy, maxz; + getBatchInstanceIndexes(min, minx, miny, minz); + getBatchInstanceIndexes(max, maxx, maxy, maxz); + Real maxVolume = 0.0f; + ushort finalx =0 , finaly = 0, finalz = 0; + for (ushort x = minx; x <= maxx; ++x) + { + for (ushort y = miny; y <= maxy; ++y) + { + for (ushort z = minz; z <= maxz; ++z) + { + Real vol = getVolumeIntersection(bounds, x, y, z); + if (vol > maxVolume) + { + maxVolume = vol; + finalx = x; + finaly = y; + finalz = z; + } + + } + } + } + + assert(maxVolume > 0.0f && + "Static geometry: Problem determining closest volume match!"); + + return getBatchInstance(finalx, finaly, finalz, autoCreate); + + } + //-------------------------------------------------------------------------- + Real InstancedGeometry::getVolumeIntersection(const AxisAlignedBox& box, + ushort x, ushort y, ushort z) + { + // Get bounds of indexed BatchInstance + AxisAlignedBox BatchInstanceBounds = getBatchInstanceBounds(x, y, z); + AxisAlignedBox intersectBox = BatchInstanceBounds.intersection(box); + // return a 'volume' which ignores zero dimensions + // since we only use this for relative comparisons of the same bounds + // this will still be internally consistent + Vector3 boxdiff = box.getMaximum() - box.getMinimum(); + Vector3 intersectDiff = intersectBox.getMaximum() - intersectBox.getMinimum(); + + return (boxdiff.x == 0 ? 1 : intersectDiff.x) * + (boxdiff.y == 0 ? 1 : intersectDiff.y) * + (boxdiff.z == 0 ? 1 : intersectDiff.z); + + } + //-------------------------------------------------------------------------- + AxisAlignedBox InstancedGeometry::getBatchInstanceBounds(ushort x, ushort y, ushort z) + { + Vector3 min( + ((Real)x - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.x + mOrigin.x, + ((Real)y - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.y + mOrigin.y, + ((Real)z - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.z + mOrigin.z + ); + Vector3 max = min + mBatchInstanceDimensions; + return AxisAlignedBox(min, max); + } + //-------------------------------------------------------------------------- + Vector3 InstancedGeometry::getBatchInstanceCentre(ushort x, ushort y, ushort z) + { + return Vector3( + ((Real)x - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.x + mOrigin.x + + mHalfBatchInstanceDimensions.x, + ((Real)y - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.y + mOrigin.y + + mHalfBatchInstanceDimensions.y, + ((Real)z - BatchInstance_HALF_RANGE) * mBatchInstanceDimensions.z + mOrigin.z + + mHalfBatchInstanceDimensions.z + ); + } + //-------------------------------------------------------------------------- + InstancedGeometry::BatchInstance* InstancedGeometry::getBatchInstance( + ushort x, ushort y, ushort z, bool autoCreate) + { + uint32 index = packIndex(x, y, z); + BatchInstance* ret = getBatchInstance(index); + if (!ret && autoCreate) + { + // Make a name + StringStream str; + str << mName << ":" << index; + // Calculate the BatchInstance centre + Vector3 centre(0,0,0);// = getBatchInstanceCentre(x, y, z); + ret = OGRE_NEW BatchInstance(this, str.str(), mOwner, index/*, centre*/); + mOwner->injectMovableObject(ret); + ret->setVisible(mVisible); + ret->setCastShadows(mCastShadows); + if (mRenderQueueIDSet) + { + ret->setRenderQueueGroup(mRenderQueueID); + } + mBatchInstanceMap[index] = ret; + } + return ret; + } + //-------------------------------------------------------------------------- + InstancedGeometry::BatchInstance* InstancedGeometry::getBatchInstance(uint32 index) + { + BatchInstanceMap::iterator i = mBatchInstanceMap.find(index); + if (i != mBatchInstanceMap.end()) + { + return i->second; + } + else + { + return 0; + } + + } + //-------------------------------------------------------------------------- + void InstancedGeometry::getBatchInstanceIndexes(const Vector3& point, + ushort& x, ushort& y, ushort& z) + { + // Scale the point into multiples of BatchInstance and adjust for origin + Vector3 scaledPoint = (point - mOrigin) / mBatchInstanceDimensions; + + // Round down to 'bottom left' point which represents the cell index + int ix = Math::IFloor(scaledPoint.x); + int iy = Math::IFloor(scaledPoint.y); + int iz = Math::IFloor(scaledPoint.z); + + // Check bounds + if (ix < BatchInstance_MIN_INDEX || ix > BatchInstance_MAX_INDEX + || iy < BatchInstance_MIN_INDEX || iy > BatchInstance_MAX_INDEX + || iz < BatchInstance_MIN_INDEX || iz > BatchInstance_MAX_INDEX) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Point out of bounds", + "InstancedGeometry::getBatchInstanceIndexes"); + } + // Adjust for the fact that we use unsigned values for simplicity + // (requires less faffing about for negatives give 10-bit packing + x = static_cast(ix + BatchInstance_HALF_RANGE); + y = static_cast(iy + BatchInstance_HALF_RANGE); + z = static_cast(iz + BatchInstance_HALF_RANGE); + + + } + //-------------------------------------------------------------------------- + uint32 InstancedGeometry::packIndex(ushort x, ushort y, ushort z) + { + return x + (y << 10) + (z << 20); + } + //-------------------------------------------------------------------------- + InstancedGeometry::BatchInstance* InstancedGeometry::getBatchInstance(const Vector3& point, + bool autoCreate) + { + ushort x, y, z; + getBatchInstanceIndexes(point, x, y, z); + return getBatchInstance(x, y, z, autoCreate); + } + //-------------------------------------------------------------------------- + AxisAlignedBox InstancedGeometry::calculateBounds(VertexData* vertexData, + const Vector3& position, const Quaternion& orientation, + const Vector3& scale) + { + const VertexElement* posElem = + vertexData->vertexDeclaration->findElementBySemantic( + VES_POSITION); + HardwareVertexBufferSharedPtr vbuf = + vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); + unsigned char* vertex = + static_cast( + vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + float* pFloat; + + Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE; + bool first = true; + + for(size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) + { + posElem->baseVertexPointerToElement(vertex, &pFloat); + + Vector3 pt; + + pt.x = (*pFloat++); + pt.y = (*pFloat++); + pt.z = (*pFloat++); + // Transform to world (scale, rotate, translate) + pt = (orientation * (pt * scale)) + position; + if (first) + { + min = max = pt; + first = false; + } + else + { + min.makeFloor(pt); + max.makeCeil(pt); + } + + } + vbuf->unlock(); + return AxisAlignedBox(min, max); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::addEntity(Entity* ent, const Vector3& position, + const Quaternion& orientation, const Vector3& scale) + { + + const MeshPtr& msh = ent->getMesh(); + // Validate + if (msh->hasManualLodLevel()) + { + LogManager::getSingleton().logMessage( + "WARNING (InstancedGeometry): Manual LOD is not supported. " + "Using only highest LOD level for mesh " + msh->getName(), LML_CRITICAL); + } + + //get the skeleton of the entity, if that's not already done + if(!ent->getMesh()->getSkeleton().isNull()&&mBaseSkeleton.isNull()) + { + mBaseSkeleton=ent->getMesh()->getSkeleton(); + mSkeletonInstance= OGRE_NEW SkeletonInstance(mBaseSkeleton); + mSkeletonInstance->load(); + mAnimationState=ent->getAllAnimationStates(); + } + AxisAlignedBox sharedWorldBounds; + // queue this entities submeshes and choice of material + // also build the lists of geometry to be used for the source of lods + + + for (uint i = 0; i < ent->getNumSubEntities(); ++i) + { + SubEntity* se = ent->getSubEntity(i); + QueuedSubMesh* q = OGRE_NEW QueuedSubMesh(); + + // Get the geometry for this SubMesh + q->submesh = se->getSubMesh(); + q->geometryLodList = determineGeometry(q->submesh); + q->materialName = se->getMaterialName(); + q->orientation = orientation; + q->position = position; + q->scale = scale; + q->ID = mObjectCount; + // Determine the bounds based on the highest LOD + q->worldBounds = calculateBounds( + (*q->geometryLodList)[0].vertexData, + position, orientation, scale); + + mQueuedSubMeshes.push_back(q); + } + mObjectCount++; + + } + //-------------------------------------------------------------------------- + InstancedGeometry::SubMeshLodGeometryLinkList* + InstancedGeometry::determineGeometry(SubMesh* sm) + { + // First, determine if we've already seen this submesh before + SubMeshGeometryLookup::iterator i = + mSubMeshGeometryLookup.find(sm); + if (i != mSubMeshGeometryLookup.end()) + { + return i->second; + } + // Otherwise, we have to create a new one + SubMeshLodGeometryLinkList* lodList = OGRE_NEW_T(SubMeshLodGeometryLinkList, MEMCATEGORY_GEOMETRY)(); + mSubMeshGeometryLookup[sm] = lodList; + ushort numLods = sm->parent->hasManualLodLevel() ? 1 : + sm->parent->getNumLodLevels(); + lodList->resize(numLods); + for (ushort lod = 0; lod < numLods; ++lod) + { + SubMeshLodGeometryLink& geomLink = (*lodList)[lod]; + IndexData *lodIndexData; + if (lod == 0) + { + lodIndexData = sm->indexData; + } + else + { + lodIndexData = sm->mLodFaceList[lod - 1]; + } + // Can use the original mesh geometry? + if (sm->useSharedVertices) + { + if (sm->parent->getNumSubMeshes() == 1) + { + // Ok, this is actually our own anyway + geomLink.vertexData = sm->parent->sharedVertexData; + geomLink.indexData = lodIndexData; + } + else + { + // We have to split it + splitGeometry(sm->parent->sharedVertexData, + lodIndexData, &geomLink); + } + } + else + { + if (lod == 0) + { + // Ok, we can use the existing geometry; should be in full + // use by just this SubMesh + geomLink.vertexData = sm->vertexData; + geomLink.indexData = sm->indexData; + } + else + { + // We have to split it + splitGeometry(sm->vertexData, + lodIndexData, &geomLink); + } + } + assert (geomLink.vertexData->vertexStart == 0 && + "Cannot use vertexStart > 0 on indexed geometry due to " + "rendersystem incompatibilities - see the docs!"); + } + + + return lodList; + } + //-------------------------------------------------------------------------- + void InstancedGeometry::splitGeometry(VertexData* vd, IndexData* id, + InstancedGeometry::SubMeshLodGeometryLink* targetGeomLink) + { + // Firstly we need to scan to see how many vertices are being used + // and while we're at it, build the remap we can use later + bool use32bitIndexes = + id->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT; + IndexRemap indexRemap; + if (use32bitIndexes) + { + uint32 *p32 = static_cast(id->indexBuffer->lock( + id->indexStart, + id->indexCount * id->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + buildIndexRemap(p32, id->indexCount, indexRemap); + id->indexBuffer->unlock(); + } + else + { + uint16 *p16 = static_cast(id->indexBuffer->lock( + id->indexStart, + id->indexCount * id->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + buildIndexRemap(p16, id->indexCount, indexRemap); + id->indexBuffer->unlock(); + } + if (indexRemap.size() == vd->vertexCount) + { + // ha, complete usage after all + targetGeomLink->vertexData = vd; + targetGeomLink->indexData = id; + return; + } + + + // Create the new vertex data records + targetGeomLink->vertexData = vd->clone(false); + // Convenience + VertexData* newvd = targetGeomLink->vertexData; + //IndexData* newid = targetGeomLink->indexData; + // Update the vertex count + newvd->vertexCount = indexRemap.size(); + + size_t numvbufs = vd->vertexBufferBinding->getBufferCount(); + // Copy buffers from old to new + for (unsigned short b = 0; b < numvbufs; ++b) + { + // Lock old buffer + HardwareVertexBufferSharedPtr oldBuf = + vd->vertexBufferBinding->getBuffer(b); + // Create new buffer + HardwareVertexBufferSharedPtr newBuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + oldBuf->getVertexSize(), + indexRemap.size(), + HardwareBuffer::HBU_STATIC); + // rebind + newvd->vertexBufferBinding->setBinding(b, newBuf); + + // Copy all the elements of the buffer across, by iterating over + // the IndexRemap which describes how to move the old vertices + // to the new ones. By nature of the map the remap is in order of + // indexes in the old buffer, but note that we're not guaranteed to + // address every vertex (which is kinda why we're here) + uchar* pSrcBase = static_cast( + oldBuf->lock(HardwareBuffer::HBL_READ_ONLY)); + uchar* pDstBase = static_cast( + newBuf->lock(HardwareBuffer::HBL_DISCARD)); + size_t vertexSize = oldBuf->getVertexSize(); + // Buffers should be the same size + assert (vertexSize == newBuf->getVertexSize()); + + for (IndexRemap::iterator r = indexRemap.begin(); + r != indexRemap.end(); ++r) + { + assert (r->first < oldBuf->getNumVertices()); + assert (r->second < newBuf->getNumVertices()); + + uchar* pSrc = pSrcBase + r->first * vertexSize; + uchar* pDst = pDstBase + r->second * vertexSize; + memcpy(pDst, pSrc, vertexSize); + } + // unlock + oldBuf->unlock(); + newBuf->unlock(); + + } + + // Now create a new index buffer + HardwareIndexBufferSharedPtr ibuf = + HardwareBufferManager::getSingleton().createIndexBuffer( + id->indexBuffer->getType(), id->indexCount, + HardwareBuffer::HBU_STATIC); + + if (use32bitIndexes) + { + uint32 *pSrc32, *pDst32; + pSrc32 = static_cast(id->indexBuffer->lock( + id->indexStart, id->indexCount * id->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + pDst32 = static_cast(ibuf->lock( + HardwareBuffer::HBL_DISCARD)); + remapIndexes(pSrc32, pDst32, indexRemap, id->indexCount); + id->indexBuffer->unlock(); + ibuf->unlock(); + } + else + { + uint16 *pSrc16, *pDst16; + pSrc16 = static_cast(id->indexBuffer->lock( + id->indexStart, id->indexCount * id->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + pDst16 = static_cast(ibuf->lock( + HardwareBuffer::HBL_DISCARD)); + remapIndexes(pSrc16, pDst16, indexRemap, id->indexCount); + id->indexBuffer->unlock(); + ibuf->unlock(); + } + + targetGeomLink->indexData = OGRE_NEW IndexData(); + targetGeomLink->indexData->indexStart = 0; + targetGeomLink->indexData->indexCount = id->indexCount; + targetGeomLink->indexData->indexBuffer = ibuf; + + // Store optimised geometry for deallocation later + OptimisedSubMeshGeometry *optGeom = OGRE_NEW OptimisedSubMeshGeometry(); + optGeom->indexData = targetGeomLink->indexData; + optGeom->vertexData = targetGeomLink->vertexData; + mOptimisedSubMeshGeometryList.push_back(optGeom); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::addSceneNode(const SceneNode* node) + { + SceneNode::ConstObjectIterator obji = node->getAttachedObjectIterator(); + while (obji.hasMoreElements()) + { + MovableObject* mobj = obji.getNext(); + if (mobj->getMovableType() == "Entity") + { + addEntity(static_cast(mobj), + node->_getDerivedPosition(), + node->_getDerivedOrientation(), + node->_getDerivedScale()); + } + } + // Iterate through all the child-nodes + SceneNode::ConstChildNodeIterator nodei = node->getChildIterator(); + + while (nodei.hasMoreElements()) + { + const SceneNode* newNode = static_cast(nodei.getNext()); + // Add this subnode and its children... + addSceneNode( newNode ); + } + } + //-------------------------------------------------------------------------- + void InstancedGeometry::build(void) + { + // Make sure there's nothing from previous builds + destroy(); + + // Firstly allocate meshes to BatchInstances + for (QueuedSubMeshList::iterator qi = mQueuedSubMeshes.begin(); + qi != mQueuedSubMeshes.end(); ++qi) + { + QueuedSubMesh* qsm = *qi; + //BatchInstance* BatchInstance = getBatchInstance(qsm->worldBounds, true); + BatchInstance* batchInstance = getInstancedGeometryInstance(); + batchInstance->assign(qsm); + } + + // Now tell each BatchInstance to build itself + for (BatchInstanceMap::iterator ri = mBatchInstanceMap.begin(); + ri != mBatchInstanceMap.end(); ++ri) + { + ri->second->build(); + } + + + } + //-------------------------------------------------------------------------- + void InstancedGeometry::addBatchInstance(void) + { + + + BatchInstanceIterator regIt = getBatchInstanceIterator(); + BatchInstance* lastBatchInstance=0 ; + while(regIt.hasMoreElements()) + { + lastBatchInstance= regIt.getNext(); + } if(!lastBatchInstance) OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No batch instance found", "InstancedGeometry::addBatchInstance"); - uint32 index=(lastBatchInstance)?lastBatchInstance->getID()+1:0; - //create a new BatchInstance - - BatchInstance*ret = OGRE_NEW BatchInstance(this, mName+":"+StringConverter::toString(index), - mOwner, index); - - ret->attachToScene(); - - mOwner->injectMovableObject(ret); - ret->setVisible(mVisible); - ret->setCastShadows(mCastShadows); - mBatchInstanceMap[index] = ret; - - if (mRenderQueueIDSet) - { - ret->setRenderQueueGroup(mRenderQueueID); - } - - const size_t numLod = lastBatchInstance->mLodValues.size(); - ret->mLodValues.resize(numLod); - for (ushort lod = 0; lod < numLod; lod++) - { - ret->mLodValues[lod] = - lastBatchInstance->mLodValues[lod]; - } - - - - // update bounds - AxisAlignedBox box(lastBatchInstance->mAABB.getMinimum(),lastBatchInstance->mAABB.getMaximum()); - ret->mAABB.merge(box); - - ret->mBoundingRadius = lastBatchInstance->mBoundingRadius ; - //now create news instanced objects - BatchInstance::ObjectsMap::iterator objIt; - for(objIt=lastBatchInstance->getInstancesMap().begin();objIt!=lastBatchInstance->getInstancesMap().end();++objIt) - { - InstancedObject* instancedObject = ret->isInstancedObjectPresent(objIt->first); - if(instancedObject == NULL) - { - if(mBaseSkeleton.isNull()) - { - instancedObject= OGRE_NEW InstancedObject(objIt->first); - } - else - { - instancedObject= OGRE_NEW InstancedObject(objIt->first,mSkeletonInstance,mAnimationState); - } - ret->addInstancedObject(objIt->first,instancedObject); - } - - } - - - - BatchInstance::LODIterator lodIterator = lastBatchInstance->getLODIterator(); - //parse all the LOD buckets of the BatchInstance - while (lodIterator.hasMoreElements()) - { - - LODBucket* lod = lodIterator.getNext(); - //create a new LOD bucket for the new BatchInstance - LODBucket* lodBucket= OGRE_NEW LODBucket(ret, lod->getLod(), lod->getLodValue()); - - //add the LODBucket to the BatchInstance list - ret->updateContainers(lodBucket); - - LODBucket::MaterialIterator matIt = lod->getMaterialIterator(); - //parse all the material buckets of the LOD bucket - while (matIt.hasMoreElements()) - { - - MaterialBucket*mat = matIt.getNext(); - //create a new material bucket - String materialName=mat->getMaterialName(); - MaterialBucket* matBucket = OGRE_NEW MaterialBucket(lodBucket,materialName); - - //add the material bucket to the LOD buckets list and map - lodBucket->updateContainers(matBucket, materialName); - - MaterialBucket::GeometryIterator geomIt = mat->getGeometryIterator(); - //parse all the geometry buckets of the material bucket - while(geomIt.hasMoreElements()) - { - //get the source geometry bucket - GeometryBucket *geom = geomIt.getNext(); - //create a new geometry bucket - GeometryBucket *geomBucket = OGRE_NEW GeometryBucket(matBucket,geom->getFormatString(),geom); - - //update the material bucket map of the material bucket - matBucket->updateContainers(geomBucket, geomBucket->getFormatString() ); - - //copy bounding information - geomBucket->getAABB()=geom->getAABB(); - geomBucket->setBoundingBox( geom->getBoundingBox()); - //now setups the news InstancedObjects. - for(objIt=ret->getInstancesMap().begin();objIt!=ret->getInstancesMap().end();++objIt) - { - //get the destination IntanciedObject - InstancedObject*obj=objIt->second; - InstancedObject::GeometryBucketList::iterator findIt; - //check if the bucket is not already in the list - findIt=std::find(obj->getGeometryBucketList().begin(),obj->getGeometryBucketList().end(),geomBucket); - if(findIt==obj->getGeometryBucketList().end()) - obj->addBucketToList(geomBucket); - } - - - } - } - } - } - //-------------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::updateContainers(LODBucket* bucket ) - { - mLodBucketList.push_back(bucket); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::LODBucket::updateContainers(MaterialBucket* bucket, String& name ) - { - mMaterialBucketMap[name] = bucket; - } - - //-------------------------------------------------------------------------- - String InstancedGeometry::GeometryBucket::getFormatString(void) const - { - return mFormatString; - } - //-------------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::attachToScene() - { - - mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(mName/*,mCentre*/); - mNode->attachObject(this); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::MaterialBucket::updateContainers(InstancedGeometry::GeometryBucket* bucket, const String & format) - { - mCurrentGeometryMap[format]=bucket; - mGeometryBucketList.push_back(bucket); - } - void InstancedGeometry::MaterialBucket:: setMaterial(const String & name) - { - mMaterial=MaterialManager::getSingleton().getByName(name); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::destroy(void) - { - RenderOperationVector::iterator it; - for(it=mRenderOps.begin();it!=mRenderOps.end();++it) - { - OGRE_DELETE (*it)->vertexData; - OGRE_DELETE (*it)->indexData; - - } - mRenderOps.clear(); - - // delete the BatchInstances - for (BatchInstanceMap::iterator i = mBatchInstanceMap.begin(); - i != mBatchInstanceMap.end(); ++i) - { - mOwner->extractMovableObject(i->second); - OGRE_DELETE i->second; - - } - mBatchInstanceMap.clear(); - mInstancedGeometryInstance = NULL; - } - //-------------------------------------------------------------------------- - void InstancedGeometry::reset(void) - { - destroy(); - - for (QueuedSubMeshList::iterator i = mQueuedSubMeshes.begin(); - i != mQueuedSubMeshes.end(); ++i) - { - OGRE_DELETE *i; - - } - mQueuedSubMeshes.clear(); - // Delete precached geoemtry lists - for (SubMeshGeometryLookup::iterator l = mSubMeshGeometryLookup.begin(); - l != mSubMeshGeometryLookup.end(); ++l) - { - OGRE_DELETE_T(l->second, SubMeshLodGeometryLinkList, MEMCATEGORY_GEOMETRY); - - } - mSubMeshGeometryLookup.clear(); - // Delete optimised geometry - for (OptimisedSubMeshGeometryList::iterator o = mOptimisedSubMeshGeometryList.begin(); - o != mOptimisedSubMeshGeometryList.end(); ++o) - { - OGRE_DELETE *o; - - } - mOptimisedSubMeshGeometryList.clear(); - - } - //-------------------------------------------------------------------------- - void InstancedGeometry::setVisible(bool visible) - { - - mVisible = visible; - // tell any existing BatchInstances - for (BatchInstanceMap::iterator ri = mBatchInstanceMap.begin(); - ri != mBatchInstanceMap.end(); ++ri) - { - - - ri->second->setVisible(visible); - } - } - //-------------------------------------------------------------------------- - void InstancedGeometry::setCastShadows(bool castShadows) - { - mCastShadows = castShadows; - // tell any existing BatchInstances - for (BatchInstanceMap::iterator ri = mBatchInstanceMap.begin(); - ri != mBatchInstanceMap.end(); ++ri) - { - ri->second->setCastShadows(castShadows); - } - - } - //-------------------------------------------------------------------------- - void InstancedGeometry::setRenderQueueGroup(uint8 queueID) - { - assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!"); - mRenderQueueIDSet = true; - mRenderQueueID = queueID; - // tell any existing BatchInstances - for (BatchInstanceMap::iterator ri = mBatchInstanceMap.begin(); - ri != mBatchInstanceMap.end(); ++ri) - { - ri->second->setRenderQueueGroup(queueID); - } - } - //-------------------------------------------------------------------------- - uint8 InstancedGeometry::getRenderQueueGroup(void) const - { - return mRenderQueueID; - } - //-------------------------------------------------------------------------- - void InstancedGeometry::dump(const String& filename) const - { - std::ofstream of(filename.c_str()); - of << "Static Geometry Report for " << mName << std::endl; - of << "-------------------------------------------------" << std::endl; - of << "Number of queued submeshes: " << mQueuedSubMeshes.size() << std::endl; - of << "Number of BatchInstances: " << mBatchInstanceMap.size() << std::endl; - of << "BatchInstance dimensions: " << mBatchInstanceDimensions << std::endl; - of << "Origin: " << mOrigin << std::endl; - of << "Max distance: " << mUpperDistance << std::endl; - of << "Casts shadows?: " << mCastShadows << std::endl; - of << std::endl; - for (BatchInstanceMap::const_iterator ri = mBatchInstanceMap.begin(); - ri != mBatchInstanceMap.end(); ++ri) - { - ri->second->dump(of); - } - of << "-------------------------------------------------" << std::endl; - } - //-------------------------------------------------------------------------- - void InstancedGeometry::setProvideWorldInverses(bool flag) + uint32 index=(lastBatchInstance)?lastBatchInstance->getID()+1:0; + //create a new BatchInstance + + BatchInstance*ret = OGRE_NEW BatchInstance(this, mName+":"+StringConverter::toString(index), + mOwner, index); + + ret->attachToScene(); + + mOwner->injectMovableObject(ret); + ret->setVisible(mVisible); + ret->setCastShadows(mCastShadows); + mBatchInstanceMap[index] = ret; + + if (mRenderQueueIDSet) + { + ret->setRenderQueueGroup(mRenderQueueID); + } + + const size_t numLod = lastBatchInstance->mLodValues.size(); + ret->mLodValues.resize(numLod); + for (ushort lod = 0; lod < numLod; lod++) + { + ret->mLodValues[lod] = + lastBatchInstance->mLodValues[lod]; + } + + + + // update bounds + AxisAlignedBox box(lastBatchInstance->mAABB.getMinimum(),lastBatchInstance->mAABB.getMaximum()); + ret->mAABB.merge(box); + + ret->mBoundingRadius = lastBatchInstance->mBoundingRadius ; + //now create news instanced objects + BatchInstance::ObjectsMap::iterator objIt; + for(objIt=lastBatchInstance->getInstancesMap().begin();objIt!=lastBatchInstance->getInstancesMap().end();++objIt) + { + InstancedObject* instancedObject = ret->isInstancedObjectPresent(objIt->first); + if(instancedObject == NULL) + { + if(mBaseSkeleton.isNull()) + { + instancedObject= OGRE_NEW InstancedObject(objIt->first); + } + else + { + instancedObject= OGRE_NEW InstancedObject(objIt->first,mSkeletonInstance,mAnimationState); + } + ret->addInstancedObject(objIt->first,instancedObject); + } + + } + + + + BatchInstance::LODIterator lodIterator = lastBatchInstance->getLODIterator(); + //parse all the LOD buckets of the BatchInstance + while (lodIterator.hasMoreElements()) + { + + LODBucket* lod = lodIterator.getNext(); + //create a new LOD bucket for the new BatchInstance + LODBucket* lodBucket= OGRE_NEW LODBucket(ret, lod->getLod(), lod->getLodValue()); + + //add the LODBucket to the BatchInstance list + ret->updateContainers(lodBucket); + + LODBucket::MaterialIterator matIt = lod->getMaterialIterator(); + //parse all the material buckets of the LOD bucket + while (matIt.hasMoreElements()) + { + + MaterialBucket*mat = matIt.getNext(); + //create a new material bucket + String materialName=mat->getMaterialName(); + MaterialBucket* matBucket = OGRE_NEW MaterialBucket(lodBucket,materialName); + + //add the material bucket to the LOD buckets list and map + lodBucket->updateContainers(matBucket, materialName); + + MaterialBucket::GeometryIterator geomIt = mat->getGeometryIterator(); + //parse all the geometry buckets of the material bucket + while(geomIt.hasMoreElements()) + { + //get the source geometry bucket + GeometryBucket *geom = geomIt.getNext(); + //create a new geometry bucket + GeometryBucket *geomBucket = OGRE_NEW GeometryBucket(matBucket,geom->getFormatString(),geom); + + //update the material bucket map of the material bucket + matBucket->updateContainers(geomBucket, geomBucket->getFormatString() ); + + //copy bounding information + geomBucket->getAABB()=geom->getAABB(); + geomBucket->setBoundingBox( geom->getBoundingBox()); + //now setups the news InstancedObjects. + for(objIt=ret->getInstancesMap().begin();objIt!=ret->getInstancesMap().end();++objIt) + { + //get the destination IntanciedObject + InstancedObject*obj=objIt->second; + InstancedObject::GeometryBucketList::iterator findIt; + //check if the bucket is not already in the list + findIt=std::find(obj->getGeometryBucketList().begin(),obj->getGeometryBucketList().end(),geomBucket); + if(findIt==obj->getGeometryBucketList().end()) + obj->addBucketToList(geomBucket); + } + + + } + } + } + } + //-------------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::updateContainers(LODBucket* bucket ) { - mProvideWorldInverses = flag; + mLodBucketList.push_back(bucket); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::LODBucket::updateContainers(MaterialBucket* bucket, String& name ) + { + mMaterialBucketMap[name] = bucket; } - //--------------------------------------------------------------------- - void InstancedGeometry::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - for (BatchInstanceMap::const_iterator ri = mBatchInstanceMap.begin(); - ri != mBatchInstanceMap.end(); ++ri) - { - ri->second->visitRenderables(visitor, debugRenderables); - } - - } - //-------------------------------------------------------------------------- - InstancedGeometry::InstancedObject::InstancedObject(unsigned short index,SkeletonInstance *skeleton, AnimationStateSet*animations) - : mIndex(index), - mTransformation(Matrix4::ZERO), - mOrientation(Quaternion::IDENTITY), - mScale(Vector3::UNIT_SCALE), - mPosition(Vector3::ZERO), - mSkeletonInstance(skeleton), - mBoneWorldMatrices(NULL), - mBoneMatrices(NULL), - mNumBoneMatrices(0), - mFrameAnimationLastUpdated(std::numeric_limits::max()) - - { - - mSkeletonInstance->load(); - - mAnimationState = OGRE_NEW AnimationStateSet(); - mNumBoneMatrices = mSkeletonInstance->getNumBones(); - mBoneMatrices = OGRE_ALLOC_T(Matrix4, mNumBoneMatrices, MEMCATEGORY_ANIMATION); - AnimationStateIterator it=animations->getAnimationStateIterator(); - while (it.hasMoreElements()) - { - AnimationState*anim= it.getNext(); - mAnimationState->createAnimationState(anim->getAnimationName(),anim->getTimePosition(),anim->getLength(), - anim->getWeight()); - - } - - } - //-------------------------------------------------------------------------- - InstancedGeometry::InstancedObject::InstancedObject(unsigned short index) - :mIndex(index), - mTransformation(Matrix4::ZERO), - mOrientation(Quaternion::IDENTITY), - mScale(Vector3::UNIT_SCALE), - mPosition(Vector3::ZERO), - mSkeletonInstance(0), - mBoneWorldMatrices(0), - mBoneMatrices(0), - mAnimationState(0), - mNumBoneMatrices(0), - mFrameAnimationLastUpdated(std::numeric_limits::max()) - { - } - //-------------------------------------------------------------------------- - InstancedGeometry::InstancedObject::~InstancedObject() - { - mGeometryBucketList.clear(); - OGRE_DELETE mAnimationState; - OGRE_FREE(mBoneMatrices, MEMCATEGORY_ANIMATION); - OGRE_FREE(mBoneWorldMatrices, MEMCATEGORY_ANIMATION); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::addBucketToList(GeometryBucket *bucket) - { - mGeometryBucketList.push_back(bucket); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::setPosition( const Vector3 &position) - { - - mPosition=position; - needUpdate(); - BatchInstance*parentBatchInstance=(*(mGeometryBucketList.begin()))->getParent()->getParent()->getParent(); - parentBatchInstance->updateBoundingBox(); - - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::translate(const Vector3 &d) - { - mPosition += d; - needUpdate(); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::translate(const Matrix3 &axes, const Vector3 &move) - { - Vector3 derived = axes * move; - translate(derived); - } - //-------------------------------------------------------------------------- - Matrix3 InstancedGeometry::InstancedObject::getLocalAxes() const - { - Vector3 axisX = Vector3::UNIT_X; - Vector3 axisY = Vector3::UNIT_Y; - Vector3 axisZ = Vector3::UNIT_Z; - axisX = mOrientation * axisX; - axisY = mOrientation * axisY; - axisZ = mOrientation * axisZ; + //-------------------------------------------------------------------------- + String InstancedGeometry::GeometryBucket::getFormatString(void) const + { + return mFormatString; + } + //-------------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::attachToScene() + { - return Matrix3(axisX.x, axisY.x, axisZ.x, - axisX.y, axisY.y, axisZ.y, - axisX.z, axisY.z, axisZ.z); - } - //-------------------------------------------------------------------------- - const Vector3 & InstancedGeometry::InstancedObject::getPosition(void) const - { - return mPosition; - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::yaw(const Radian &angle) - { - Quaternion q; - q.FromAngleAxis(angle,Vector3::UNIT_Y); - rotate(q); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::pitch(const Radian &angle) - { - Quaternion q; - q.FromAngleAxis(angle,Vector3::UNIT_X); - rotate(q); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::roll(const Radian &angle) - { - Quaternion q; - q.FromAngleAxis(angle,Vector3::UNIT_Z); - rotate(q); + mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(mName/*,mCentre*/); + mNode->attachObject(this); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::MaterialBucket::updateContainers(InstancedGeometry::GeometryBucket* bucket, const String & format) + { + mCurrentGeometryMap[format]=bucket; + mGeometryBucketList.push_back(bucket); + } + void InstancedGeometry::MaterialBucket:: setMaterial(const String & name) + { + mMaterial=MaterialManager::getSingleton().getByName(name); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::destroy(void) + { + RenderOperationVector::iterator it; + for(it=mRenderOps.begin();it!=mRenderOps.end();++it) + { + OGRE_DELETE (*it)->vertexData; + OGRE_DELETE (*it)->indexData; + + } + mRenderOps.clear(); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::setScale(const Vector3 &scale) - { - mScale=scale; - needUpdate(); - } - - const Vector3& InstancedGeometry::InstancedObject::getScale() const - { - return mScale; - } - - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::rotate(const Quaternion& q) - { - + // delete the BatchInstances + for (BatchInstanceMap::iterator i = mBatchInstanceMap.begin(); + i != mBatchInstanceMap.end(); ++i) + { + mOwner->extractMovableObject(i->second); + OGRE_DELETE i->second; + + } + mBatchInstanceMap.clear(); + mInstancedGeometryInstance = NULL; + } + //-------------------------------------------------------------------------- + void InstancedGeometry::reset(void) + { + destroy(); + + for (QueuedSubMeshList::iterator i = mQueuedSubMeshes.begin(); + i != mQueuedSubMeshes.end(); ++i) + { + OGRE_DELETE *i; + + } + mQueuedSubMeshes.clear(); + // Delete precached geoemtry lists + for (SubMeshGeometryLookup::iterator l = mSubMeshGeometryLookup.begin(); + l != mSubMeshGeometryLookup.end(); ++l) + { + OGRE_DELETE_T(l->second, SubMeshLodGeometryLinkList, MEMCATEGORY_GEOMETRY); + + } + mSubMeshGeometryLookup.clear(); + // Delete optimised geometry + for (OptimisedSubMeshGeometryList::iterator o = mOptimisedSubMeshGeometryList.begin(); + o != mOptimisedSubMeshGeometryList.end(); ++o) + { + OGRE_DELETE *o; + + } + mOptimisedSubMeshGeometryList.clear(); + + } + //-------------------------------------------------------------------------- + void InstancedGeometry::setVisible(bool visible) + { + + mVisible = visible; + // tell any existing BatchInstances + for (BatchInstanceMap::iterator ri = mBatchInstanceMap.begin(); + ri != mBatchInstanceMap.end(); ++ri) + { + + + ri->second->setVisible(visible); + } + } + //-------------------------------------------------------------------------- + void InstancedGeometry::setCastShadows(bool castShadows) + { + mCastShadows = castShadows; + // tell any existing BatchInstances + for (BatchInstanceMap::iterator ri = mBatchInstanceMap.begin(); + ri != mBatchInstanceMap.end(); ++ri) + { + ri->second->setCastShadows(castShadows); + } + + } + //-------------------------------------------------------------------------- + void InstancedGeometry::setRenderQueueGroup(uint8 queueID) + { + assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!"); + mRenderQueueIDSet = true; + mRenderQueueID = queueID; + // tell any existing BatchInstances + for (BatchInstanceMap::iterator ri = mBatchInstanceMap.begin(); + ri != mBatchInstanceMap.end(); ++ri) + { + ri->second->setRenderQueueGroup(queueID); + } + } + //-------------------------------------------------------------------------- + uint8 InstancedGeometry::getRenderQueueGroup(void) const + { + return mRenderQueueID; + } + //-------------------------------------------------------------------------- + void InstancedGeometry::dump(const String& filename) const + { + std::ofstream of(filename.c_str()); + of << "Static Geometry Report for " << mName << std::endl; + of << "-------------------------------------------------" << std::endl; + of << "Number of queued submeshes: " << mQueuedSubMeshes.size() << std::endl; + of << "Number of BatchInstances: " << mBatchInstanceMap.size() << std::endl; + of << "BatchInstance dimensions: " << mBatchInstanceDimensions << std::endl; + of << "Origin: " << mOrigin << std::endl; + of << "Max distance: " << mUpperDistance << std::endl; + of << "Casts shadows?: " << mCastShadows << std::endl; + of << std::endl; + for (BatchInstanceMap::const_iterator ri = mBatchInstanceMap.begin(); + ri != mBatchInstanceMap.end(); ++ri) + { + ri->second->dump(of); + } + of << "-------------------------------------------------" << std::endl; + } + //-------------------------------------------------------------------------- + void InstancedGeometry::setProvideWorldInverses(bool flag) + { + mProvideWorldInverses = flag; + } + //--------------------------------------------------------------------- + void InstancedGeometry::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + for (BatchInstanceMap::const_iterator ri = mBatchInstanceMap.begin(); + ri != mBatchInstanceMap.end(); ++ri) + { + ri->second->visitRenderables(visitor, debugRenderables); + } + + } + //-------------------------------------------------------------------------- + InstancedGeometry::InstancedObject::InstancedObject(unsigned short index,SkeletonInstance *skeleton, AnimationStateSet*animations) + : mIndex(index), + mTransformation(Matrix4::ZERO), + mOrientation(Quaternion::IDENTITY), + mScale(Vector3::UNIT_SCALE), + mPosition(Vector3::ZERO), + mSkeletonInstance(skeleton), + mBoneWorldMatrices(NULL), + mBoneMatrices(NULL), + mNumBoneMatrices(0), + mFrameAnimationLastUpdated(std::numeric_limits::max()) + + { + + mSkeletonInstance->load(); + + mAnimationState = OGRE_NEW AnimationStateSet(); + mNumBoneMatrices = mSkeletonInstance->getNumBones(); + mBoneMatrices = OGRE_ALLOC_T(Matrix4, mNumBoneMatrices, MEMCATEGORY_ANIMATION); + AnimationStateIterator it=animations->getAnimationStateIterator(); + while (it.hasMoreElements()) + { + AnimationState*anim= it.getNext(); + mAnimationState->createAnimationState(anim->getAnimationName(),anim->getTimePosition(),anim->getLength(), + anim->getWeight()); + + } + + } + //-------------------------------------------------------------------------- + InstancedGeometry::InstancedObject::InstancedObject(unsigned short index) + :mIndex(index), + mTransformation(Matrix4::ZERO), + mOrientation(Quaternion::IDENTITY), + mScale(Vector3::UNIT_SCALE), + mPosition(Vector3::ZERO), + mSkeletonInstance(0), + mBoneWorldMatrices(0), + mBoneMatrices(0), + mAnimationState(0), + mNumBoneMatrices(0), + mFrameAnimationLastUpdated(std::numeric_limits::max()) + { + } + //-------------------------------------------------------------------------- + InstancedGeometry::InstancedObject::~InstancedObject() + { + mGeometryBucketList.clear(); + OGRE_DELETE mAnimationState; + OGRE_FREE(mBoneMatrices, MEMCATEGORY_ANIMATION); + OGRE_FREE(mBoneWorldMatrices, MEMCATEGORY_ANIMATION); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::addBucketToList(GeometryBucket *bucket) + { + mGeometryBucketList.push_back(bucket); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::setPosition( const Vector3 &position) + { + + mPosition=position; + needUpdate(); + BatchInstance*parentBatchInstance=(*(mGeometryBucketList.begin()))->getParent()->getParent()->getParent(); + parentBatchInstance->updateBoundingBox(); + + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::translate(const Vector3 &d) + { + mPosition += d; + needUpdate(); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::translate(const Matrix3 &axes, const Vector3 &move) + { + Vector3 derived = axes * move; + translate(derived); + } + //-------------------------------------------------------------------------- + Matrix3 InstancedGeometry::InstancedObject::getLocalAxes() const + { + Vector3 axisX = Vector3::UNIT_X; + Vector3 axisY = Vector3::UNIT_Y; + Vector3 axisZ = Vector3::UNIT_Z; + + axisX = mOrientation * axisX; + axisY = mOrientation * axisY; + axisZ = mOrientation * axisZ; + + return Matrix3(axisX.x, axisY.x, axisZ.x, + axisX.y, axisY.y, axisZ.y, + axisX.z, axisY.z, axisZ.z); + } + //-------------------------------------------------------------------------- + const Vector3 & InstancedGeometry::InstancedObject::getPosition(void) const + { + return mPosition; + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::yaw(const Radian &angle) + { + Quaternion q; + q.FromAngleAxis(angle,Vector3::UNIT_Y); + rotate(q); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::pitch(const Radian &angle) + { + Quaternion q; + q.FromAngleAxis(angle,Vector3::UNIT_X); + rotate(q); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::roll(const Radian &angle) + { + Quaternion q; + q.FromAngleAxis(angle,Vector3::UNIT_Z); + rotate(q); + + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::setScale(const Vector3 &scale) + { + mScale=scale; + needUpdate(); + } + + const Vector3& InstancedGeometry::InstancedObject::getScale() const + { + return mScale; + } + + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::rotate(const Quaternion& q) + { + mOrientation = mOrientation * q; - needUpdate(); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::setOrientation(const Quaternion& q) - { + needUpdate(); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::setOrientation(const Quaternion& q) + { mOrientation = q; - needUpdate(); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::setPositionAndOrientation(const Vector3 &p, const Quaternion& q) - { - mPosition = p; + needUpdate(); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::setPositionAndOrientation(const Vector3 &p, const Quaternion& q) + { + mPosition = p; mOrientation = q; needUpdate(); - BatchInstance* parentBatchInstance=(*(mGeometryBucketList.begin()))->getParent()->getParent()->getParent(); - parentBatchInstance->updateBoundingBox(); - } + BatchInstance* parentBatchInstance=(*(mGeometryBucketList.begin()))->getParent()->getParent()->getParent(); + parentBatchInstance->updateBoundingBox(); + } + + //-------------------------------------------------------------------------- + Quaternion &InstancedGeometry::InstancedObject::getOrientation(void) + { + return mOrientation; + } + + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::needUpdate() + { + mTransformation.makeTransform( + mPosition, + mScale, + mOrientation); + + + } + //-------------------------------------------------------------------------- + void InstancedGeometry::InstancedObject::updateAnimation(void) + { + + if(mSkeletonInstance) + { + GeometryBucketList::iterator it; + mSkeletonInstance->setAnimationState(*mAnimationState); + mSkeletonInstance->_getBoneMatrices(mBoneMatrices); + + // Allocate bone world matrices on demand, for better memory footprint + // when using software animation. + if (!mBoneWorldMatrices) + { + mBoneWorldMatrices = OGRE_ALLOC_T(Matrix4, mNumBoneMatrices, MEMCATEGORY_ANIMATION); + } + + for (unsigned short i = 0; i < mNumBoneMatrices; ++i) + { + mBoneWorldMatrices[i] = mTransformation * mBoneMatrices[i]; + + } + + + + } + + } + //-------------------------------------------------------------------------- + AnimationState* InstancedGeometry::InstancedObject::getAnimationState(const String& name) const + { + if (!mAnimationState) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Object is not animated", + "InstancedGeometry::InstancedObject::getAnimationState"); + } +// AnimationStateIterator it=mAnimationState->getAnimationStateIterator(); +// while (it.hasMoreElements()) +// { +// AnimationState*anim= it.getNext(); +// +// +// } + return mAnimationState->getAnimationState(name); + } + //-------------------------------------------------------------------------- + InstancedGeometry::BatchInstanceIterator InstancedGeometry::getBatchInstanceIterator(void) + { + return BatchInstanceIterator(mBatchInstanceMap.begin(), mBatchInstanceMap.end()); + } + //-------------------------------------------------------------------------- + InstancedGeometry::BatchInstance::BatchInstance(InstancedGeometry* parent, const String& name, + SceneManager* mgr, uint32 BatchInstanceID) + : MovableObject(name), mParent(parent), mSceneMgr(mgr), mNode(0), + mBatchInstanceID(BatchInstanceID), mBoundingRadius(0.0f), + mCurrentLod(0), mCamera(0), mLodStrategy(0) + { + } + //-------------------------------------------------------------------------- + InstancedGeometry::BatchInstance::~BatchInstance() + { + if (mNode) + { + mNode->getParentSceneNode()->removeChild(mNode); + mSceneMgr->destroySceneNode(mNode->getName()); + mNode = 0; + } + // delete + for (LODBucketList::iterator i = mLodBucketList.begin(); + i != mLodBucketList.end(); ++i) + { + OGRE_DELETE *i; + } + mLodBucketList.clear(); + ObjectsMap::iterator o; + + for(o=mInstancesMap.begin();o!=mInstancesMap.end();++o) + { + OGRE_DELETE o->second; + } + mInstancesMap.clear(); + // no need to delete queued meshes, these are managed in InstancedGeometry + } + //-------------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::assign(QueuedSubMesh* qmesh) + { + mQueuedSubMeshes.push_back(qmesh); + + // Set/check LOD strategy + const LodStrategy *lodStrategy = qmesh->submesh->parent->getLodStrategy(); + if (mLodStrategy == 0) + { + mLodStrategy = lodStrategy; + + // First LOD mandatory, and always from base LOD value + mLodValues.push_back(mLodStrategy->getBaseValue()); + } + else + { + if (mLodStrategy != lodStrategy) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Lod strategies do not match", + "InstancedGeometry::InstancedObject::assign"); + } + + // update LOD values + ushort lodLevels = qmesh->submesh->parent->getNumLodLevels(); + assert(qmesh->geometryLodList->size() == lodLevels); + + while(mLodValues.size() < lodLevels) + { + mLodValues.push_back(0.0f); + } + // Make sure LOD levels are max of all at the requested level + for (ushort lod = 1; lod < lodLevels; ++lod) + { + const MeshLodUsage& meshLod = + qmesh->submesh->parent->getLodLevel(lod); + mLodValues[lod] = std::max(mLodValues[lod], + meshLod.value); + } + + // update bounds + // Transform world bounds relative to our centre + AxisAlignedBox localBounds( + qmesh->worldBounds.getMinimum() , + qmesh->worldBounds.getMaximum()); + mAABB.merge(localBounds); + mBoundingRadius = Math::boundingRadiusFromAABB(mAABB); + + } + //-------------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::build() + { + // Create a node + mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(mName); + mNode->attachObject(this); + // We need to create enough LOD buckets to deal with the highest LOD + // we encountered in all the meshes queued + for (ushort lod = 0; lod < mLodValues.size(); ++lod) + { + LODBucket* lodBucket = + OGRE_NEW LODBucket(this, lod, mLodValues[lod]); + mLodBucketList.push_back(lodBucket); + // Now iterate over the meshes and assign to LODs + // LOD bucket will pick the right LOD to use + QueuedSubMeshList::iterator qi, qiend; + qiend = mQueuedSubMeshes.end(); + for (qi = mQueuedSubMeshes.begin(); qi != qiend; ++qi) + { + lodBucket->assign(*qi, lod); + } + // now build + lodBucket->build(); + } + + + } + + //-------------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::updateBoundingBox() + { + AxisAlignedBox aabb; + + //Get the first GeometryBucket to get the aabb + LODIterator lodIterator = getLODIterator(); + if( lodIterator.hasMoreElements() ) + { + LODBucket* lod = lodIterator.getNext(); + LODBucket::MaterialIterator matIt = lod->getMaterialIterator(); + if( matIt.hasMoreElements() ) + { + MaterialBucket*mat = matIt.getNext(); + MaterialBucket::GeometryIterator geomIt = mat->getGeometryIterator(); + if( geomIt.hasMoreElements() ) + { + GeometryBucket *geom = geomIt.getNext(); + aabb = geom->getAABB(); + } + } + } + + ObjectsMap::iterator objIt; + Vector3 vMin( Vector3::ZERO ); + Vector3 vMax( Vector3::ZERO ); + if( !mInstancesMap.empty() ) + { + objIt = mInstancesMap.begin(); + vMin = objIt->second->getPosition() + aabb.getMinimum(); + vMax = objIt->second->getPosition() + aabb.getMaximum(); + } + + for( objIt=mInstancesMap.begin(); objIt!=mInstancesMap.end(); ++objIt ) + { + const Vector3 &position = objIt->second->getPosition(); + const Vector3 &scale = objIt->second->getScale(); + + vMin.x = std::min( vMin.x, position.x + aabb.getMinimum().x * scale.x ); + vMin.y = std::min( vMin.y, position.y + aabb.getMinimum().y * scale.y ); + vMin.z = std::min( vMin.z, position.z + aabb.getMinimum().z * scale.z ); + + vMax.x = std::max( vMax.x, position.x + aabb.getMaximum().x * scale.x ); + vMax.y = std::max( vMax.y, position.y + aabb.getMaximum().y * scale.y ); + vMax.z = std::max( vMax.z, position.z + aabb.getMaximum().z * scale.z ); + } + + aabb.setExtents( vMin, vMax ); + + //Now apply the bounding box + lodIterator = getLODIterator(); + while( lodIterator.hasMoreElements() ) + { + LODBucket* lod = lodIterator.getNext(); + LODBucket::MaterialIterator matIt = lod->getMaterialIterator(); + while (matIt.hasMoreElements()) + { + MaterialBucket*mat = matIt.getNext(); + MaterialBucket::GeometryIterator geomIt = mat->getGeometryIterator(); + while( geomIt.hasMoreElements() ) + { + GeometryBucket *geom = geomIt.getNext(); + geom->setBoundingBox( aabb ); + this->mNode->_updateBounds(); + mAABB = aabb; + } + } + } + } + + //-------------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::addInstancedObject(unsigned short index,InstancedObject* object) + { + mInstancesMap[index]=object; + } + //-------------------------------------------------------------------------- + InstancedGeometry::InstancedObject* InstancedGeometry::BatchInstance::isInstancedObjectPresent(unsigned short index) + { + if (mInstancesMap.find(index)!=mInstancesMap.end()) + return mInstancesMap[index]; + else return NULL; + } + //-------------------------------------------------------------------------- + InstancedGeometry::BatchInstance::InstancedObjectIterator + InstancedGeometry::BatchInstance::getObjectIterator() + { + return InstancedObjectIterator(mInstancesMap.begin(), mInstancesMap.end()); + } + //-------------------------------------------------------------------------- + const String& InstancedGeometry::BatchInstance::getMovableType(void) const + { + static String sType = "InstancedGeometry"; + return sType; + } + //-------------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::_notifyCurrentCamera(Camera* cam) + { + // Set camera + mCamera = cam; + + + // Cache squared view depth for use by GeometryBucket + mSquaredViewDepth = mParentNode->getSquaredViewDepth(cam->getLodCamera()); + + // No LOD strategy set yet, skip (this indicates that there are no submeshes) + if (mLodStrategy == 0) + return; + + // Sanity check + assert(!mLodValues.empty()); + + // Calculate LOD value + Real lodValue = mLodStrategy->getValue(this, cam); + + // Store LOD value for this strategy + mLodValue = lodValue; + + // Get LOD index + mCurrentLod = mLodStrategy->getIndex(lodValue, mLodValues); + } + //-------------------------------------------------------------------------- + const AxisAlignedBox& InstancedGeometry::BatchInstance::getBoundingBox(void) const + { + return mAABB; + } + //-------------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::setBoundingBox(AxisAlignedBox & box) + { + mAABB=box; + } + //-------------------------------------------------------------------------- + Real InstancedGeometry::BatchInstance::getBoundingRadius(void) const + { + return mBoundingRadius; + } + //-------------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::_updateRenderQueue(RenderQueue* queue) + { + ObjectsMap::iterator it; + //we parse the Instanced Object map to update the animations. + + for (it=mInstancesMap.begin();it!=mInstancesMap.end();++it) + { + it->second->updateAnimation(); + + } + + mLodBucketList[mCurrentLod]->addRenderables(queue, mRenderQueueID, + mLodValue); + } + //--------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::visitRenderables( + Renderable::Visitor* visitor, bool debugRenderables) + { + for (LODBucketList::iterator i = mLodBucketList.begin(); i != mLodBucketList.end(); ++i) + { + (*i)->visitRenderables(visitor, debugRenderables); + } + + } + //-------------------------------------------------------------------------- + bool InstancedGeometry::BatchInstance::isVisible(void) const + { + return mVisible && !mBeyondFarDistance; + } + //-------------------------------------------------------------------------- + InstancedGeometry::BatchInstance::LODIterator + InstancedGeometry::BatchInstance::getLODIterator(void) + { + return LODIterator(mLodBucketList.begin(), mLodBucketList.end()); + } + //-------------------------------------------------------------------------- + const LightList& InstancedGeometry::BatchInstance::getLights(void) const + { + return queryLights(); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::BatchInstance::dump(std::ofstream& of) const + { + of << "BatchInstance " << mBatchInstanceID << std::endl; + of << "--------------------------" << std::endl; + of << "Local AABB: " << mAABB << std::endl; + of << "Bounding radius: " << mBoundingRadius << std::endl; + of << "Number of LODs: " << mLodBucketList.size() << std::endl; + + for (LODBucketList::const_iterator i = mLodBucketList.begin(); + i != mLodBucketList.end(); ++i) + { + (*i)->dump(of); + } + of << "--------------------------" << std::endl; + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + InstancedGeometry::LODBucket::LODBucket(BatchInstance* parent, unsigned short lod, + Real lodValue) + : mParent(parent), mLod(lod), mLodValue(lodValue) + { + } + //-------------------------------------------------------------------------- + InstancedGeometry::LODBucket::~LODBucket() + { + // delete + for (MaterialBucketMap::iterator i = mMaterialBucketMap.begin(); + i != mMaterialBucketMap.end(); ++i) + { + OGRE_DELETE i->second; + } + mMaterialBucketMap.clear(); + for(QueuedGeometryList::iterator qi = mQueuedGeometryList.begin(); + qi != mQueuedGeometryList.end(); ++qi) + { + OGRE_DELETE *qi; + } + mQueuedGeometryList.clear(); + // no need to delete queued meshes, these are managed in InstancedGeometry + } + //-------------------------------------------------------------------------- + void InstancedGeometry::LODBucket::assign(QueuedSubMesh* qmesh, ushort atLod) + { + QueuedGeometry* q = OGRE_NEW QueuedGeometry(); + mQueuedGeometryList.push_back(q); + q->position = qmesh->position; + q->orientation = qmesh->orientation; + q->scale = qmesh->scale; + q->ID = qmesh->ID; + if (qmesh->geometryLodList->size() > atLod) + { + // This submesh has enough lods, use the right one + q->geometry = &(*qmesh->geometryLodList)[atLod]; + } + else + { + // Not enough lods, use the lowest one we have + q->geometry = + &(*qmesh->geometryLodList)[qmesh->geometryLodList->size() - 1]; + } + // Locate a material bucket + MaterialBucket* mbucket = 0; + MaterialBucketMap::iterator m = + mMaterialBucketMap.find(qmesh->materialName); + if (m != mMaterialBucketMap.end()) + { + mbucket = m->second; + } + else + { + mbucket = OGRE_NEW MaterialBucket(this, qmesh->materialName); + mMaterialBucketMap[qmesh->materialName] = mbucket; + } + mbucket->assign(q); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::LODBucket::build() + { + // Just pass this on to child buckets + + for (MaterialBucketMap::iterator i = mMaterialBucketMap.begin(); + i != mMaterialBucketMap.end(); ++i) + { + i->second->build(); + } + } + //-------------------------------------------------------------------------- + void InstancedGeometry::LODBucket::addRenderables(RenderQueue* queue, + uint8 group, Real lodValue) + { + // Just pass this on to child buckets + MaterialBucketMap::iterator i, iend; + iend = mMaterialBucketMap.end(); + for (i = mMaterialBucketMap.begin(); i != iend; ++i) + { + i->second->addRenderables(queue, group, lodValue); + } + } + //--------------------------------------------------------------------- + void InstancedGeometry::LODBucket::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + MaterialBucketMap::iterator i, iend; + iend = mMaterialBucketMap.end(); + for (i = mMaterialBucketMap.begin(); i != iend; ++i) + { + i->second->visitRenderables(visitor, debugRenderables); + } + + } + //-------------------------------------------------------------------------- + InstancedGeometry::LODBucket::MaterialIterator + InstancedGeometry::LODBucket::getMaterialIterator(void) + { + return MaterialIterator( + mMaterialBucketMap.begin(), mMaterialBucketMap.end()); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::LODBucket::dump(std::ofstream& of) const + { + of << "LOD Bucket " << mLod << std::endl; + of << "------------------" << std::endl; + of << "Lod Value: " << mLodValue << std::endl; + of << "Number of Materials: " << mMaterialBucketMap.size() << std::endl; + for (MaterialBucketMap::const_iterator i = mMaterialBucketMap.begin(); + i != mMaterialBucketMap.end(); ++i) + { + i->second->dump(of); + } + of << "------------------" << std::endl; + } //-------------------------------------------------------------------------- - Quaternion &InstancedGeometry::InstancedObject::getOrientation(void) + //-------------------------------------------------------------------------- + InstancedGeometry::MaterialBucket::MaterialBucket(LODBucket* parent, + const String& materialName) + : mParent(parent) + , mMaterialName(materialName) + , mTechnique(0) + , mLastIndex(0) { - return mOrientation; + mMaterial = MaterialManager::getSingleton().getByName(mMaterialName); } + //-------------------------------------------------------------------------- + InstancedGeometry::MaterialBucket::~MaterialBucket() + { + // delete + for (GeometryBucketList::iterator i = mGeometryBucketList.begin(); + i != mGeometryBucketList.end(); ++i) + { + OGRE_DELETE *i; + } + mGeometryBucketList.clear(); + // no need to delete queued meshes, these are managed in InstancedGeometry - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::needUpdate() - { - mTransformation.makeTransform( - mPosition, - mScale, - mOrientation); - - - } - //-------------------------------------------------------------------------- - void InstancedGeometry::InstancedObject::updateAnimation(void) - { - - if(mSkeletonInstance) - { - GeometryBucketList::iterator it; - mSkeletonInstance->setAnimationState(*mAnimationState); - mSkeletonInstance->_getBoneMatrices(mBoneMatrices); + } + //-------------------------------------------------------------------------- - // Allocate bone world matrices on demand, for better memory footprint - // when using software animation. - if (!mBoneWorldMatrices) + void InstancedGeometry::MaterialBucket::assign(QueuedGeometry* qgeom) + { + // Look up any current geometry + String formatString = getGeometryFormatString(qgeom->geometry); + CurrentGeometryMap::iterator gi = mCurrentGeometryMap.find(formatString); + bool newBucket = true; + if (gi != mCurrentGeometryMap.end()) + { + // Found existing geometry, try to assign + newBucket = !gi->second->assign(qgeom); + // Note that this bucket will be replaced as the 'current' + // for this format string below since it's out of space + } + // Do we need to create a new one? + if (newBucket) + { + GeometryBucket* gbucket = OGRE_NEW GeometryBucket(this, formatString, + qgeom->geometry->vertexData, qgeom->geometry->indexData); + // Add to main list + mGeometryBucketList.push_back(gbucket); + // Also index in 'current' list + mCurrentGeometryMap[formatString] = gbucket; + if (!gbucket->assign(qgeom)) { - mBoneWorldMatrices = OGRE_ALLOC_T(Matrix4, mNumBoneMatrices, MEMCATEGORY_ANIMATION); + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Somehow we couldn't fit the requested geometry even in a " + "brand new GeometryBucket!! Must be a bug, please report.", + "InstancedGeometry::MaterialBucket::assign"); } + } + } + //-------------------------------------------------------------------------- + void InstancedGeometry::MaterialBucket::build() + { + mTechnique = 0; + mMaterial = MaterialManager::getSingleton().getByName(mMaterialName); + if (mMaterial.isNull()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Material '" + mMaterialName + "' not found.", + "InstancedGeometry::MaterialBucket::build"); + } + mMaterial->load(); + // tell the geometry buckets to build + + for (GeometryBucketList::iterator i = mGeometryBucketList.begin(); + i != mGeometryBucketList.end(); ++i) + { + (*i)->build(); + } + } + //-------------------------------------------------------------------------- + void InstancedGeometry::MaterialBucket::addRenderables(RenderQueue* queue, + uint8 group, Real lodValue) + { + // Get batch instance + BatchInstance *batchInstance = mParent->getParent(); - for (unsigned short i = 0; i < mNumBoneMatrices; ++i) - { - mBoneWorldMatrices[i] = mTransformation * mBoneMatrices[i]; - - } - + // Get material LOD strategy + const LodStrategy *materialLodStrategy = mMaterial->getLodStrategy(); + // If material strategy doesn't match, recompute LOD value with correct strategy + if (materialLodStrategy != batchInstance->mLodStrategy) + lodValue = materialLodStrategy->getValue(batchInstance, batchInstance->mCamera); - } + // Determine the current material technique + mTechnique = mMaterial->getBestTechnique( + mMaterial->getLodIndex(lodValue)); + GeometryBucketList::iterator i, iend; + iend = mGeometryBucketList.end(); + + for (i = mGeometryBucketList.begin(); i != iend; ++i) + { + queue->addRenderable(*i, group); + } - } - //-------------------------------------------------------------------------- - AnimationState* InstancedGeometry::InstancedObject::getAnimationState(const String& name) const + } + //--------------------------------------------------------------------- + void InstancedGeometry::MaterialBucket::visitRenderables( + Renderable::Visitor* visitor, bool debugRenderables) { - if (!mAnimationState) + GeometryBucketList::iterator i, iend; + iend = mGeometryBucketList.end(); + for (i = mGeometryBucketList.begin(); i != iend; ++i) { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Object is not animated", - "InstancedGeometry::InstancedObject::getAnimationState"); + (*i)->visitRenderables(visitor, debugRenderables); } -// AnimationStateIterator it=mAnimationState->getAnimationStateIterator(); -// while (it.hasMoreElements()) -// { -// AnimationState*anim= it.getNext(); -// -// -// } - return mAnimationState->getAnimationState(name); - } - //-------------------------------------------------------------------------- - InstancedGeometry::BatchInstanceIterator InstancedGeometry::getBatchInstanceIterator(void) - { - return BatchInstanceIterator(mBatchInstanceMap.begin(), mBatchInstanceMap.end()); - } - //-------------------------------------------------------------------------- - InstancedGeometry::BatchInstance::BatchInstance(InstancedGeometry* parent, const String& name, - SceneManager* mgr, uint32 BatchInstanceID) - : MovableObject(name), mParent(parent), mSceneMgr(mgr), mNode(0), - mBatchInstanceID(BatchInstanceID), mBoundingRadius(0.0f), - mCurrentLod(0), mCamera(0), mLodStrategy(0) - { - } - //-------------------------------------------------------------------------- - InstancedGeometry::BatchInstance::~BatchInstance() - { - if (mNode) - { - mNode->getParentSceneNode()->removeChild(mNode); - mSceneMgr->destroySceneNode(mNode->getName()); - mNode = 0; - } - // delete - for (LODBucketList::iterator i = mLodBucketList.begin(); - i != mLodBucketList.end(); ++i) - { - OGRE_DELETE *i; - } - mLodBucketList.clear(); - ObjectsMap::iterator o; - - for(o=mInstancesMap.begin();o!=mInstancesMap.end();++o) - { - OGRE_DELETE o->second; - } - mInstancesMap.clear(); - // no need to delete queued meshes, these are managed in InstancedGeometry - } - //-------------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::assign(QueuedSubMesh* qmesh) - { - mQueuedSubMeshes.push_back(qmesh); - // Set/check LOD strategy - const LodStrategy *lodStrategy = qmesh->submesh->parent->getLodStrategy(); - if (mLodStrategy == 0) + } + //-------------------------------------------------------------------------- + String InstancedGeometry::MaterialBucket::getGeometryFormatString( + SubMeshLodGeometryLink* geom) + { + // Formulate an identifying string for the geometry format + // Must take into account the vertex declaration and the index type + // Format is (all lines separated by '|'): + // Index type + // Vertex element (repeating) + // source + // semantic + // type + StringStream str; + + str << geom->indexData->indexBuffer->getType() << "|"; + const VertexDeclaration::VertexElementList& elemList = + geom->vertexData->vertexDeclaration->getElements(); + VertexDeclaration::VertexElementList::const_iterator ei, eiend; + eiend = elemList.end(); + for (ei = elemList.begin(); ei != eiend; ++ei) { - mLodStrategy = lodStrategy; - - // First LOD mandatory, and always from base LOD value - mLodValues.push_back(mLodStrategy->getBaseValue()); + const VertexElement& elem = *ei; + str << elem.getSource() << "|"; + str << elem.getSource() << "|"; + str << elem.getSemantic() << "|"; + str << elem.getType() << "|"; } - else + + return str.str(); + + } + //-------------------------------------------------------------------------- + InstancedGeometry::MaterialBucket::GeometryIterator + InstancedGeometry::MaterialBucket::getGeometryIterator(void) + { + return GeometryIterator( + mGeometryBucketList.begin(), mGeometryBucketList.end()); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::MaterialBucket::dump(std::ofstream& of) const + { + of << "Material Bucket " << mMaterialName << std::endl; + of << "--------------------------------------------------" << std::endl; + of << "Geometry buckets: " << mGeometryBucketList.size() << std::endl; + for (GeometryBucketList::const_iterator i = mGeometryBucketList.begin(); + i != mGeometryBucketList.end(); ++i) { - if (mLodStrategy != lodStrategy) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Lod strategies do not match", - "InstancedGeometry::InstancedObject::assign"); + (*i)->dump(of); } + of << "--------------------------------------------------" << std::endl; - // update LOD values - ushort lodLevels = qmesh->submesh->parent->getNumLodLevels(); - assert(qmesh->geometryLodList->size() == lodLevels); - - while(mLodValues.size() < lodLevels) - { - mLodValues.push_back(0.0f); - } - // Make sure LOD levels are max of all at the requested level - for (ushort lod = 1; lod < lodLevels; ++lod) - { - const MeshLodUsage& meshLod = - qmesh->submesh->parent->getLodLevel(lod); - mLodValues[lod] = std::max(mLodValues[lod], - meshLod.value); - } - - // update bounds - // Transform world bounds relative to our centre - AxisAlignedBox localBounds( - qmesh->worldBounds.getMinimum() , - qmesh->worldBounds.getMaximum()); - mAABB.merge(localBounds); - mBoundingRadius = Math::boundingRadiusFromAABB(mAABB); - - } - //-------------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::build() - { - // Create a node - mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(mName); - mNode->attachObject(this); - // We need to create enough LOD buckets to deal with the highest LOD - // we encountered in all the meshes queued - for (ushort lod = 0; lod < mLodValues.size(); ++lod) - { - LODBucket* lodBucket = - OGRE_NEW LODBucket(this, lod, mLodValues[lod]); - mLodBucketList.push_back(lodBucket); - // Now iterate over the meshes and assign to LODs - // LOD bucket will pick the right LOD to use - QueuedSubMeshList::iterator qi, qiend; - qiend = mQueuedSubMeshes.end(); - for (qi = mQueuedSubMeshes.begin(); qi != qiend; ++qi) - { - lodBucket->assign(*qi, lod); - } - // now build - lodBucket->build(); - } - - - } - - //-------------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::updateBoundingBox() - { - AxisAlignedBox aabb; - - //Get the first GeometryBucket to get the aabb - LODIterator lodIterator = getLODIterator(); - if( lodIterator.hasMoreElements() ) - { - LODBucket* lod = lodIterator.getNext(); - LODBucket::MaterialIterator matIt = lod->getMaterialIterator(); - if( matIt.hasMoreElements() ) - { - MaterialBucket*mat = matIt.getNext(); - MaterialBucket::GeometryIterator geomIt = mat->getGeometryIterator(); - if( geomIt.hasMoreElements() ) - { - GeometryBucket *geom = geomIt.getNext(); - aabb = geom->getAABB(); - } - } - } - - ObjectsMap::iterator objIt; - Vector3 vMin( Vector3::ZERO ); - Vector3 vMax( Vector3::ZERO ); - if( !mInstancesMap.empty() ) - { - objIt = mInstancesMap.begin(); - vMin = objIt->second->getPosition() + aabb.getMinimum(); - vMax = objIt->second->getPosition() + aabb.getMaximum(); - } - - for( objIt=mInstancesMap.begin(); objIt!=mInstancesMap.end(); ++objIt ) - { - const Vector3 &position = objIt->second->getPosition(); - const Vector3 &scale = objIt->second->getScale(); - - vMin.x = std::min( vMin.x, position.x + aabb.getMinimum().x * scale.x ); - vMin.y = std::min( vMin.y, position.y + aabb.getMinimum().y * scale.y ); - vMin.z = std::min( vMin.z, position.z + aabb.getMinimum().z * scale.z ); - - vMax.x = std::max( vMax.x, position.x + aabb.getMaximum().x * scale.x ); - vMax.y = std::max( vMax.y, position.y + aabb.getMaximum().y * scale.y ); - vMax.z = std::max( vMax.z, position.z + aabb.getMaximum().z * scale.z ); - } - - aabb.setExtents( vMin, vMax ); - - //Now apply the bounding box - lodIterator = getLODIterator(); - while( lodIterator.hasMoreElements() ) - { - LODBucket* lod = lodIterator.getNext(); - LODBucket::MaterialIterator matIt = lod->getMaterialIterator(); - while (matIt.hasMoreElements()) - { - MaterialBucket*mat = matIt.getNext(); - MaterialBucket::GeometryIterator geomIt = mat->getGeometryIterator(); - while( geomIt.hasMoreElements() ) - { - GeometryBucket *geom = geomIt.getNext(); - geom->setBoundingBox( aabb ); - this->mNode->_updateBounds(); - mAABB = aabb; - } - } - } - } - - //-------------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::addInstancedObject(unsigned short index,InstancedObject* object) - { - mInstancesMap[index]=object; - } - //-------------------------------------------------------------------------- - InstancedGeometry::InstancedObject* InstancedGeometry::BatchInstance::isInstancedObjectPresent(unsigned short index) - { - if (mInstancesMap.find(index)!=mInstancesMap.end()) - return mInstancesMap[index]; - else return NULL; - } - //-------------------------------------------------------------------------- - InstancedGeometry::BatchInstance::InstancedObjectIterator - InstancedGeometry::BatchInstance::getObjectIterator() - { - return InstancedObjectIterator(mInstancesMap.begin(), mInstancesMap.end()); - } - //-------------------------------------------------------------------------- - const String& InstancedGeometry::BatchInstance::getMovableType(void) const - { - static String sType = "InstancedGeometry"; - return sType; - } - //-------------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::_notifyCurrentCamera(Camera* cam) - { - // Set camera - mCamera = cam; + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + InstancedGeometry::GeometryBucket::GeometryBucket(MaterialBucket* parent, + const String& formatString, const VertexData* vData, + const IndexData* iData) + : SimpleRenderable() + , mParent(parent) + , mFormatString(formatString) + , mVertexData(0) + , mIndexData(0) + { + _initGeometryBucket(vData, iData); + } + //-------------------------------------------------------------------------- + InstancedGeometry::GeometryBucket::GeometryBucket(const String& name, MaterialBucket* parent, + const String& formatString, const VertexData* vData, + const IndexData* iData) + : SimpleRenderable(name) + , mParent(parent) + , mFormatString(formatString) + , mVertexData(0) + , mIndexData(0) + { + _initGeometryBucket(vData, iData); + } + //-------------------------------------------------------------------------- + InstancedGeometry::GeometryBucket::GeometryBucket(MaterialBucket* parent, + const String& formatString,GeometryBucket* bucket) + : SimpleRenderable() + , mParent(parent) + , mFormatString(formatString) + , mVertexData(0) + , mIndexData(0) + { + _initGeometryBucket(bucket); + } + //-------------------------------------------------------------------------- + InstancedGeometry::GeometryBucket::GeometryBucket(const String& name, MaterialBucket* parent, + const String& formatString,GeometryBucket* bucket) + : SimpleRenderable(name) + , mParent(parent) + , mFormatString(formatString) + , mVertexData(0) + , mIndexData(0) + { + _initGeometryBucket(bucket); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::GeometryBucket::_initGeometryBucket(const VertexData* vData, const IndexData* iData) + { + mBatch=mParent->getParent()->getParent()->getParent(); + if(!mBatch->getBaseSkeleton().isNull()) + setCustomParameter(0,Vector4(mBatch->getBaseSkeleton()->getNumBones(),0,0,0)); + //mRenderOperation=OGRE_NEW RenderOperation(); + // Clone the structure from the example + mVertexData = vData->clone(false); + mRenderOp.useIndexes = true; + mRenderOp.indexData = OGRE_NEW IndexData(); - // Cache squared view depth for use by GeometryBucket - mSquaredViewDepth = mParentNode->getSquaredViewDepth(cam->getLodCamera()); + mRenderOp.indexData->indexCount = 0; + mRenderOp.indexData->indexStart = 0; + mRenderOp.vertexData = OGRE_NEW VertexData(); + mRenderOp.vertexData->vertexCount = 0; - // No LOD strategy set yet, skip (this indicates that there are no submeshes) - if (mLodStrategy == 0) - return; + // VertexData constructor creates vertexDeclaration; must release to avoid + // memory leak + HardwareBufferManager::getSingleton().destroyVertexDeclaration(mRenderOp.vertexData->vertexDeclaration); + mRenderOp.vertexData->vertexDeclaration = vData->vertexDeclaration->clone(); + mIndexType = iData->indexBuffer->getType(); + // Derive the max vertices + if (mIndexType == HardwareIndexBuffer::IT_32BIT) + { + mMaxVertexIndex = 0xFFFFFFFF; + } + else + { + mMaxVertexIndex = 0xFFFF; + } - // Sanity check - assert(!mLodValues.empty()); - // Calculate LOD value - Real lodValue = mLodStrategy->getValue(this, cam); + size_t offset=0; + unsigned short texCoordOffset=0; + unsigned short texCoordSource=0; - // Store LOD value for this strategy - mLodValue = lodValue; + const Ogre::VertexElement*elem=mRenderOp.vertexData->vertexDeclaration->findElementBySemantic(VES_TEXTURE_COORDINATES); + + if (elem != NULL) + { + texCoordSource=elem->getSource(); + } + for(ushort i=0;ivertexDeclaration->getElementCount();i++) + { + if(mRenderOp.vertexData->vertexDeclaration->getElement(i)->getSemantic() == VES_TEXTURE_COORDINATES) + { + texCoordOffset++; + } + if(texCoordSource==mRenderOp.vertexData->vertexDeclaration->getElement(i)->getSource()) + { + offset+= VertexElement::getTypeSize( + mRenderOp.vertexData->vertexDeclaration->getElement(i)->getType()); + } + } - // Get LOD index - mCurrentLod = mLodStrategy->getIndex(lodValue, mLodValues); - } - //-------------------------------------------------------------------------- - const AxisAlignedBox& InstancedGeometry::BatchInstance::getBoundingBox(void) const - { - return mAABB; - } - //-------------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::setBoundingBox(AxisAlignedBox & box) - { - mAABB=box; - } - //-------------------------------------------------------------------------- - Real InstancedGeometry::BatchInstance::getBoundingRadius(void) const - { - return mBoundingRadius; - } - //-------------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::_updateRenderQueue(RenderQueue* queue) - { - ObjectsMap::iterator it; - //we parse the Instanced Object map to update the animations. - - for (it=mInstancesMap.begin();it!=mInstancesMap.end();++it) - { - it->second->updateAnimation(); - - } - - mLodBucketList[mCurrentLod]->addRenderables(queue, mRenderQueueID, - mLodValue); - } - //--------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::visitRenderables( - Renderable::Visitor* visitor, bool debugRenderables) - { - for (LODBucketList::iterator i = mLodBucketList.begin(); i != mLodBucketList.end(); ++i) - { - (*i)->visitRenderables(visitor, debugRenderables); - } - - } - //-------------------------------------------------------------------------- - bool InstancedGeometry::BatchInstance::isVisible(void) const - { - return mVisible && !mBeyondFarDistance; - } - //-------------------------------------------------------------------------- - InstancedGeometry::BatchInstance::LODIterator - InstancedGeometry::BatchInstance::getLODIterator(void) - { - return LODIterator(mLodBucketList.begin(), mLodBucketList.end()); - } - //-------------------------------------------------------------------------- - const LightList& InstancedGeometry::BatchInstance::getLights(void) const - { - return queryLights(); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::BatchInstance::dump(std::ofstream& of) const - { - of << "BatchInstance " << mBatchInstanceID << std::endl; - of << "--------------------------" << std::endl; - of << "Local AABB: " << mAABB << std::endl; - of << "Bounding radius: " << mBoundingRadius << std::endl; - of << "Number of LODs: " << mLodBucketList.size() << std::endl; - - for (LODBucketList::const_iterator i = mLodBucketList.begin(); - i != mLodBucketList.end(); ++i) - { - (*i)->dump(of); - } - of << "--------------------------" << std::endl; - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - InstancedGeometry::LODBucket::LODBucket(BatchInstance* parent, unsigned short lod, - Real lodValue) - : mParent(parent), mLod(lod), mLodValue(lodValue) - { - } - //-------------------------------------------------------------------------- - InstancedGeometry::LODBucket::~LODBucket() - { - // delete - for (MaterialBucketMap::iterator i = mMaterialBucketMap.begin(); - i != mMaterialBucketMap.end(); ++i) - { - OGRE_DELETE i->second; - } - mMaterialBucketMap.clear(); - for(QueuedGeometryList::iterator qi = mQueuedGeometryList.begin(); - qi != mQueuedGeometryList.end(); ++qi) - { - OGRE_DELETE *qi; - } - mQueuedGeometryList.clear(); - // no need to delete queued meshes, these are managed in InstancedGeometry - } - //-------------------------------------------------------------------------- - void InstancedGeometry::LODBucket::assign(QueuedSubMesh* qmesh, ushort atLod) - { - QueuedGeometry* q = OGRE_NEW QueuedGeometry(); - mQueuedGeometryList.push_back(q); - q->position = qmesh->position; - q->orientation = qmesh->orientation; - q->scale = qmesh->scale; - q->ID = qmesh->ID; - if (qmesh->geometryLodList->size() > atLod) - { - // This submesh has enough lods, use the right one - q->geometry = &(*qmesh->geometryLodList)[atLod]; - } - else - { - // Not enough lods, use the lowest one we have - q->geometry = - &(*qmesh->geometryLodList)[qmesh->geometryLodList->size() - 1]; - } - // Locate a material bucket - MaterialBucket* mbucket = 0; - MaterialBucketMap::iterator m = - mMaterialBucketMap.find(qmesh->materialName); - if (m != mMaterialBucketMap.end()) - { - mbucket = m->second; - } - else - { - mbucket = OGRE_NEW MaterialBucket(this, qmesh->materialName); - mMaterialBucketMap[qmesh->materialName] = mbucket; - } - mbucket->assign(q); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::LODBucket::build() - { - // Just pass this on to child buckets - - for (MaterialBucketMap::iterator i = mMaterialBucketMap.begin(); - i != mMaterialBucketMap.end(); ++i) - { - i->second->build(); - } - } - //-------------------------------------------------------------------------- - void InstancedGeometry::LODBucket::addRenderables(RenderQueue* queue, - uint8 group, Real lodValue) - { - // Just pass this on to child buckets - MaterialBucketMap::iterator i, iend; - iend = mMaterialBucketMap.end(); - for (i = mMaterialBucketMap.begin(); i != iend; ++i) - { - i->second->addRenderables(queue, group, lodValue); - } - } - //--------------------------------------------------------------------- - void InstancedGeometry::LODBucket::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - MaterialBucketMap::iterator i, iend; - iend = mMaterialBucketMap.end(); - for (i = mMaterialBucketMap.begin(); i != iend; ++i) - { - i->second->visitRenderables(visitor, debugRenderables); - } - - } - //-------------------------------------------------------------------------- - InstancedGeometry::LODBucket::MaterialIterator - InstancedGeometry::LODBucket::getMaterialIterator(void) - { - return MaterialIterator( - mMaterialBucketMap.begin(), mMaterialBucketMap.end()); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::LODBucket::dump(std::ofstream& of) const - { - of << "LOD Bucket " << mLod << std::endl; - of << "------------------" << std::endl; - of << "Lod Value: " << mLodValue << std::endl; - of << "Number of Materials: " << mMaterialBucketMap.size() << std::endl; - for (MaterialBucketMap::const_iterator i = mMaterialBucketMap.begin(); - i != mMaterialBucketMap.end(); ++i) - { - i->second->dump(of); - } - of << "------------------" << std::endl; - - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - InstancedGeometry::MaterialBucket::MaterialBucket(LODBucket* parent, - const String& materialName) - : mParent(parent) - , mMaterialName(materialName) - , mTechnique(0) - , mLastIndex(0) - { - mMaterial = MaterialManager::getSingleton().getByName(mMaterialName); - } - //-------------------------------------------------------------------------- - InstancedGeometry::MaterialBucket::~MaterialBucket() - { - // delete - for (GeometryBucketList::iterator i = mGeometryBucketList.begin(); - i != mGeometryBucketList.end(); ++i) - { - OGRE_DELETE *i; - } - mGeometryBucketList.clear(); - // no need to delete queued meshes, these are managed in InstancedGeometry - - } - //-------------------------------------------------------------------------- - - void InstancedGeometry::MaterialBucket::assign(QueuedGeometry* qgeom) - { - // Look up any current geometry - String formatString = getGeometryFormatString(qgeom->geometry); - CurrentGeometryMap::iterator gi = mCurrentGeometryMap.find(formatString); - bool newBucket = true; - if (gi != mCurrentGeometryMap.end()) - { - // Found existing geometry, try to assign - newBucket = !gi->second->assign(qgeom); - // Note that this bucket will be replaced as the 'current' - // for this format string below since it's out of space - } - // Do we need to create a new one? - if (newBucket) - { - GeometryBucket* gbucket = OGRE_NEW GeometryBucket(this, formatString, - qgeom->geometry->vertexData, qgeom->geometry->indexData); - // Add to main list - mGeometryBucketList.push_back(gbucket); - // Also index in 'current' list - mCurrentGeometryMap[formatString] = gbucket; - if (!gbucket->assign(qgeom)) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Somehow we couldn't fit the requested geometry even in a " - "brand new GeometryBucket!! Must be a bug, please report.", - "InstancedGeometry::MaterialBucket::assign"); - } - } - } - //-------------------------------------------------------------------------- - void InstancedGeometry::MaterialBucket::build() - { - mTechnique = 0; - mMaterial = MaterialManager::getSingleton().getByName(mMaterialName); - if (mMaterial.isNull()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Material '" + mMaterialName + "' not found.", - "InstancedGeometry::MaterialBucket::build"); - } - mMaterial->load(); - // tell the geometry buckets to build - - for (GeometryBucketList::iterator i = mGeometryBucketList.begin(); - i != mGeometryBucketList.end(); ++i) - { - (*i)->build(); - } - } - //-------------------------------------------------------------------------- - void InstancedGeometry::MaterialBucket::addRenderables(RenderQueue* queue, - uint8 group, Real lodValue) - { - // Get batch instance - BatchInstance *batchInstance = mParent->getParent(); + mRenderOp.vertexData->vertexDeclaration->addElement(texCoordSource, offset, VET_FLOAT1, VES_TEXTURE_COORDINATES, texCoordOffset); + mTexCoordIndex = texCoordOffset; - // Get material LOD strategy - const LodStrategy *materialLodStrategy = mMaterial->getLodStrategy(); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::GeometryBucket::_initGeometryBucket(GeometryBucket* bucket) + { - // If material strategy doesn't match, recompute LOD value with correct strategy - if (materialLodStrategy != batchInstance->mLodStrategy) - lodValue = materialLodStrategy->getValue(batchInstance, batchInstance->mCamera); + mBatch=mParent->getParent()->getParent()->getParent(); + if(!mBatch->getBaseSkeleton().isNull()) + setCustomParameter(0,Vector4(mBatch->getBaseSkeleton()->getNumBones(),0,0,0)); + bucket->getRenderOperation(mRenderOp); + mVertexData=mRenderOp.vertexData; + mIndexData=mRenderOp.indexData; + setBoundingBox(AxisAlignedBox(-10000,-10000,-10000, + 10000,10000,10000)); - // Determine the current material technique - mTechnique = mMaterial->getBestTechnique( - mMaterial->getLodIndex(lodValue)); - GeometryBucketList::iterator i, iend; - iend = mGeometryBucketList.end(); - - for (i = mGeometryBucketList.begin(); i != iend; ++i) - { - queue->addRenderable(*i, group); - } - - } - //--------------------------------------------------------------------- - void InstancedGeometry::MaterialBucket::visitRenderables( - Renderable::Visitor* visitor, bool debugRenderables) - { - GeometryBucketList::iterator i, iend; - iend = mGeometryBucketList.end(); - for (i = mGeometryBucketList.begin(); i != iend; ++i) - { - (*i)->visitRenderables(visitor, debugRenderables); - } - - } - //-------------------------------------------------------------------------- - String InstancedGeometry::MaterialBucket::getGeometryFormatString( - SubMeshLodGeometryLink* geom) - { - // Formulate an identifying string for the geometry format - // Must take into account the vertex declaration and the index type - // Format is (all lines separated by '|'): - // Index type - // Vertex element (repeating) - // source - // semantic - // type - StringStream str; - - str << geom->indexData->indexBuffer->getType() << "|"; - const VertexDeclaration::VertexElementList& elemList = - geom->vertexData->vertexDeclaration->getElements(); - VertexDeclaration::VertexElementList::const_iterator ei, eiend; - eiend = elemList.end(); - for (ei = elemList.begin(); ei != eiend; ++ei) - { - const VertexElement& elem = *ei; - str << elem.getSource() << "|"; - str << elem.getSource() << "|"; - str << elem.getSemantic() << "|"; - str << elem.getType() << "|"; - } - - return str.str(); - - } - //-------------------------------------------------------------------------- - InstancedGeometry::MaterialBucket::GeometryIterator - InstancedGeometry::MaterialBucket::getGeometryIterator(void) - { - return GeometryIterator( - mGeometryBucketList.begin(), mGeometryBucketList.end()); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::MaterialBucket::dump(std::ofstream& of) const - { - of << "Material Bucket " << mMaterialName << std::endl; - of << "--------------------------------------------------" << std::endl; - of << "Geometry buckets: " << mGeometryBucketList.size() << std::endl; - for (GeometryBucketList::const_iterator i = mGeometryBucketList.begin(); - i != mGeometryBucketList.end(); ++i) - { - (*i)->dump(of); - } - of << "--------------------------------------------------" << std::endl; - - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - InstancedGeometry::GeometryBucket::GeometryBucket(MaterialBucket* parent, - const String& formatString, const VertexData* vData, - const IndexData* iData) - : SimpleRenderable() - , mParent(parent) - , mFormatString(formatString) - , mVertexData(0) - , mIndexData(0) - { - _initGeometryBucket(vData, iData); - } - //-------------------------------------------------------------------------- - InstancedGeometry::GeometryBucket::GeometryBucket(const String& name, MaterialBucket* parent, - const String& formatString, const VertexData* vData, - const IndexData* iData) - : SimpleRenderable(name) - , mParent(parent) - , mFormatString(formatString) - , mVertexData(0) - , mIndexData(0) - { - _initGeometryBucket(vData, iData); - } - //-------------------------------------------------------------------------- - InstancedGeometry::GeometryBucket::GeometryBucket(MaterialBucket* parent, - const String& formatString,GeometryBucket* bucket) - : SimpleRenderable() - , mParent(parent) - , mFormatString(formatString) - , mVertexData(0) - , mIndexData(0) - { - _initGeometryBucket(bucket); - } - //-------------------------------------------------------------------------- - InstancedGeometry::GeometryBucket::GeometryBucket(const String& name, MaterialBucket* parent, - const String& formatString,GeometryBucket* bucket) - : SimpleRenderable(name) - , mParent(parent) - , mFormatString(formatString) - , mVertexData(0) - , mIndexData(0) - { - _initGeometryBucket(bucket); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::GeometryBucket::_initGeometryBucket(const VertexData* vData, const IndexData* iData) - { - mBatch=mParent->getParent()->getParent()->getParent(); - if(!mBatch->getBaseSkeleton().isNull()) - setCustomParameter(0,Vector4(mBatch->getBaseSkeleton()->getNumBones(),0,0,0)); - //mRenderOperation=OGRE_NEW RenderOperation(); - // Clone the structure from the example - mVertexData = vData->clone(false); - - mRenderOp.useIndexes = true; - mRenderOp.indexData = OGRE_NEW IndexData(); - - mRenderOp.indexData->indexCount = 0; - mRenderOp.indexData->indexStart = 0; - mRenderOp.vertexData = OGRE_NEW VertexData(); - mRenderOp.vertexData->vertexCount = 0; + } + //-------------------------------------------------------------------------- + InstancedGeometry::GeometryBucket::~GeometryBucket() + { + } - // VertexData constructor creates vertexDeclaration; must release to avoid - // memory leak - HardwareBufferManager::getSingleton().destroyVertexDeclaration(mRenderOp.vertexData->vertexDeclaration); - mRenderOp.vertexData->vertexDeclaration = vData->vertexDeclaration->clone(); - mIndexType = iData->indexBuffer->getType(); - // Derive the max vertices - if (mIndexType == HardwareIndexBuffer::IT_32BIT) - { - mMaxVertexIndex = 0xFFFFFFFF; - } - else - { - mMaxVertexIndex = 0xFFFF; - } - - - size_t offset=0; - unsigned short texCoordOffset=0; - unsigned short texCoordSource=0; - - const Ogre::VertexElement*elem=mRenderOp.vertexData->vertexDeclaration->findElementBySemantic(VES_TEXTURE_COORDINATES); - - if (elem != NULL) - { - texCoordSource=elem->getSource(); - } - for(ushort i=0;ivertexDeclaration->getElementCount();i++) - { - if(mRenderOp.vertexData->vertexDeclaration->getElement(i)->getSemantic() == VES_TEXTURE_COORDINATES) - { - texCoordOffset++; - } - if(texCoordSource==mRenderOp.vertexData->vertexDeclaration->getElement(i)->getSource()) - { - offset+= VertexElement::getTypeSize( - mRenderOp.vertexData->vertexDeclaration->getElement(i)->getType()); - } - } - - mRenderOp.vertexData->vertexDeclaration->addElement(texCoordSource, offset, VET_FLOAT1, VES_TEXTURE_COORDINATES, texCoordOffset); - mTexCoordIndex = texCoordOffset; - - } - //-------------------------------------------------------------------------- - void InstancedGeometry::GeometryBucket::_initGeometryBucket(GeometryBucket* bucket) - { - - mBatch=mParent->getParent()->getParent()->getParent(); - if(!mBatch->getBaseSkeleton().isNull()) - setCustomParameter(0,Vector4(mBatch->getBaseSkeleton()->getNumBones(),0,0,0)); - bucket->getRenderOperation(mRenderOp); - mVertexData=mRenderOp.vertexData; - mIndexData=mRenderOp.indexData; - setBoundingBox(AxisAlignedBox(-10000,-10000,-10000, - 10000,10000,10000)); - - } - //-------------------------------------------------------------------------- - InstancedGeometry::GeometryBucket::~GeometryBucket() - { - } - - //-------------------------------------------------------------------------- - Real InstancedGeometry::GeometryBucket::getBoundingRadius(void) const - { - return 1; - } - //-------------------------------------------------------------------------- - const MaterialPtr& InstancedGeometry::GeometryBucket::getMaterial(void) const - { - return mParent->getMaterial(); - } - //-------------------------------------------------------------------------- - Technique* InstancedGeometry::GeometryBucket::getTechnique(void) const - { - return mParent->getCurrentTechnique(); - } - //-------------------------------------------------------------------------- - void InstancedGeometry::GeometryBucket::getWorldTransforms(Matrix4* xform) const - { - // Should be the identity transform, but lets allow transformation of the - // nodes the BatchInstances are attached to for kicks - if(mBatch->getBaseSkeleton().isNull()) - { - BatchInstance::ObjectsMap::iterator it,itbegin,itend,newit; - itbegin=mParent->getParent()->getParent()->getInstancesMap().begin(); - itend=mParent->getParent()->getParent()->getInstancesMap().end(); + //-------------------------------------------------------------------------- + Real InstancedGeometry::GeometryBucket::getBoundingRadius(void) const + { + return 1; + } + //-------------------------------------------------------------------------- + const MaterialPtr& InstancedGeometry::GeometryBucket::getMaterial(void) const + { + return mParent->getMaterial(); + } + //-------------------------------------------------------------------------- + Technique* InstancedGeometry::GeometryBucket::getTechnique(void) const + { + return mParent->getCurrentTechnique(); + } + //-------------------------------------------------------------------------- + void InstancedGeometry::GeometryBucket::getWorldTransforms(Matrix4* xform) const + { + // Should be the identity transform, but lets allow transformation of the + // nodes the BatchInstances are attached to for kicks + if(mBatch->getBaseSkeleton().isNull()) + { + BatchInstance::ObjectsMap::iterator it,itbegin,itend,newit; + itbegin=mParent->getParent()->getParent()->getInstancesMap().begin(); + itend=mParent->getParent()->getParent()->getInstancesMap().end(); if( mParent->getParent()->getParent()->getParent()->getProvideWorldInverses() ) { @@ -1868,14 +1868,14 @@ namespace Ogre { // we can pass the world transform inverse matrices alongwith with // the world matrices. This reduces our usable geometry limit by // half in each instance. - for (it=itbegin; - it!=itend; - ++it,xform+=2) - { - - *xform = it->second->mTransformation; + for (it=itbegin; + it!=itend; + ++it,xform+=2) + { + + *xform = it->second->mTransformation; *(xform+1) = xform->inverse(); - } + } } else { @@ -1887,25 +1887,25 @@ namespace Ogre { *xform = it->second->mTransformation; } } - } - else - { - BatchInstance::ObjectsMap::iterator it,itbegin,itend,newit; - itbegin=mParent->getParent()->getParent()->getInstancesMap().begin(); - itend=mParent->getParent()->getParent()->getInstancesMap().end(); - - for (it=itbegin; - it!=itend; - ++it) - { - + } + else + { + BatchInstance::ObjectsMap::iterator it,itbegin,itend,newit; + itbegin=mParent->getParent()->getParent()->getInstancesMap().begin(); + itend=mParent->getParent()->getParent()->getInstancesMap().end(); + + for (it=itbegin; + it!=itend; + ++it) + { + if( mParent->getParent()->getParent()->getParent()->getProvideWorldInverses() ) { - for(int i=0;isecond->mNumBoneMatrices;++i,xform+=2) - { - *xform = it->second->mBoneWorldMatrices[i]; + for(int i=0;isecond->mNumBoneMatrices;++i,xform+=2) + { + *xform = it->second->mBoneWorldMatrices[i]; *(xform+1) = xform->inverse(); - } + } } else { @@ -1914,325 +1914,325 @@ namespace Ogre { *xform = it->second->mBoneWorldMatrices[i]; } } - } - - } - - } - //-------------------------------------------------------------------------- - unsigned short InstancedGeometry::GeometryBucket::getNumWorldTransforms(void) const - { + } + + } + + } + //-------------------------------------------------------------------------- + unsigned short InstancedGeometry::GeometryBucket::getNumWorldTransforms(void) const + { bool bSendInverseXfrm = mParent->getParent()->getParent()->getParent()->getProvideWorldInverses(); - if(mBatch->getBaseSkeleton().isNull()) - { - BatchInstance* batch=mParent->getParent()->getParent(); + if(mBatch->getBaseSkeleton().isNull()) + { + BatchInstance* batch=mParent->getParent()->getParent(); return static_cast(batch->getInstancesMap().size() * (bSendInverseXfrm ? 2 : 1)); - } - else - { - BatchInstance* batch=mParent->getParent()->getParent(); - return static_cast( - mBatch->getBaseSkeleton()->getNumBones()*batch->getInstancesMap().size() * (bSendInverseXfrm ? 2 : 1)); - } - } - //-------------------------------------------------------------------------- - Real InstancedGeometry::GeometryBucket::getSquaredViewDepth(const Camera* cam) const - { + } + else + { + BatchInstance* batch=mParent->getParent()->getParent(); + return static_cast( + mBatch->getBaseSkeleton()->getNumBones()*batch->getInstancesMap().size() * (bSendInverseXfrm ? 2 : 1)); + } + } + //-------------------------------------------------------------------------- + Real InstancedGeometry::GeometryBucket::getSquaredViewDepth(const Camera* cam) const + { const BatchInstance *batchInstance = mParent->getParent()->getParent(); if (cam == batchInstance->mCamera) return batchInstance->mSquaredViewDepth; else return batchInstance->getParentNode()->getSquaredViewDepth(cam->getLodCamera()); - } - //-------------------------------------------------------------------------- - const LightList& InstancedGeometry::GeometryBucket::getLights(void) const - { - return mParent->getParent()->getParent()->getLights(); - } - //-------------------------------------------------------------------------- - bool InstancedGeometry::GeometryBucket::getCastsShadows(void) const - { - return mParent->getParent()->getParent()->getCastShadows(); - } - //-------------------------------------------------------------------------- - bool InstancedGeometry::GeometryBucket::assign(QueuedGeometry* qgeom) - { - // Do we have enough space? - if (mRenderOp.vertexData->vertexCount + qgeom->geometry->vertexData->vertexCount - > mMaxVertexIndex) - { - return false; - } - - mQueuedGeometry.push_back(qgeom); - mRenderOp.vertexData->vertexCount += qgeom->geometry->vertexData->vertexCount; - mRenderOp.indexData->indexCount += qgeom->geometry->indexData->indexCount; - - return true; - } - - //-------------------------------------------------------------------------- - void InstancedGeometry::GeometryBucket::build() - { - - - - // Ok, here's where we transfer the vertices and indexes to the shared - // buffers - // Shortcuts - VertexDeclaration* dcl = mRenderOp.vertexData->vertexDeclaration; - VertexBufferBinding* binds =mVertexData->vertexBufferBinding; - - // create index buffer, and lock - mRenderOp.indexData->indexBuffer = HardwareBufferManager::getSingleton() - .createIndexBuffer(mIndexType, mRenderOp.indexData->indexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - uint32* p32Dest = 0; - uint16* p16Dest = 0; - - if (mIndexType == HardwareIndexBuffer::IT_32BIT) - { - p32Dest = static_cast( - mRenderOp.indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - } - else - { - p16Dest = static_cast( - mRenderOp.indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - } - - // create all vertex buffers, and lock - ushort b; - //ushort posBufferIdx = dcl->findElementBySemantic(VES_POSITION)->getSource(); - - vector::type destBufferLocks; - vector::type bufferElements; - - for (b = 0; b < binds->getBufferCount(); ++b) - { - - size_t vertexCount = mRenderOp.vertexData->vertexCount; - - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - dcl->getVertexSize(b), - vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - binds->setBinding(b, vbuf); - uchar* pLock = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD)); - destBufferLocks.push_back(pLock); - // Pre-cache vertex elements per buffer - bufferElements.push_back(dcl->findElementsBySource(b)); - mRenderOp.vertexData->vertexBufferBinding->setBinding(b,vbuf); - } - - - // Iterate over the geometry items - size_t indexOffset = 0; - - QueuedGeometryList::iterator gi, giend; - giend = mQueuedGeometry.end(); - - // to generate the boundingBox - Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax; - Xmin=0; - Ymin=0; - Zmin=0; - Xmax=0; - Ymax=0; - Zmax=0; - QueuedGeometry* precGeom = *(mQueuedGeometry.begin()); - unsigned short index=0; - if( mParent->getLastIndex()!=0) - index=mParent->getLastIndex()+1; - - for (gi = mQueuedGeometry.begin(); gi != giend; ++gi) - { - - QueuedGeometry* geom = *gi; - if(precGeom->ID!=geom->ID) - index++; - - //create a new instanced object - InstancedObject* instancedObject = mParent->getParent()->getParent()->isInstancedObjectPresent(index); - if(instancedObject == NULL) - { - if(mBatch->getBaseSkeleton().isNull()) - { - instancedObject= OGRE_NEW InstancedObject(index); - } - else - { - instancedObject= OGRE_NEW InstancedObject(index,mBatch->getBaseSkeletonInstance(), - mBatch->getBaseAnimationState()); - } - mParent->getParent()->getParent()->addInstancedObject(index,instancedObject); - - } - instancedObject->addBucketToList(this); - - - - // Copy indexes across with offset - IndexData* srcIdxData = geom->geometry->indexData; - if (mIndexType == HardwareIndexBuffer::IT_32BIT) - { - // Lock source indexes - uint32* pSrc = static_cast( - srcIdxData->indexBuffer->lock( - srcIdxData->indexStart, - srcIdxData->indexCount * srcIdxData->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - - copyIndexes(pSrc, p32Dest, srcIdxData->indexCount, indexOffset); - p32Dest += srcIdxData->indexCount; - srcIdxData->indexBuffer->unlock(); - } - else - { - - // Lock source indexes - uint16* pSrc = static_cast( - srcIdxData->indexBuffer->lock( - srcIdxData->indexStart, - srcIdxData->indexCount * srcIdxData->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - - copyIndexes(pSrc, p16Dest, srcIdxData->indexCount, indexOffset); - p16Dest += srcIdxData->indexCount; - srcIdxData->indexBuffer->unlock(); - } - - // Now deal with vertex buffers - // we can rely on buffer counts / formats being the same - VertexData* srcVData = geom->geometry->vertexData; - VertexBufferBinding* srcBinds = srcVData->vertexBufferBinding; - - for (b = 0; b < binds->getBufferCount(); ++b) - { - - // lock source - HardwareVertexBufferSharedPtr srcBuf = - srcBinds->getBuffer(b); - uchar* pSrcBase = static_cast( - srcBuf->lock(HardwareBuffer::HBL_READ_ONLY)); - // Get buffer lock pointer, we'll update this later - uchar* pDstBase = destBufferLocks[b]; - size_t bufInc = srcBuf->getVertexSize(); - - // Iterate over vertices - float *pSrcReal, *pDstReal; - Vector3 tmp; - - - - for (size_t v = 0; v < srcVData->vertexCount; ++v) - { - //to know if the current buffer is the one with the buffer or not - bool isTheBufferWithIndex=false; - // Iterate over vertex elements - VertexDeclaration::VertexElementList& elems = - bufferElements[b]; - VertexDeclaration::VertexElementList::iterator ei; - - for (ei = elems.begin(); ei != elems.end(); ++ei) - { - VertexElement& elem = *ei; - elem.baseVertexPointerToElement(pSrcBase, &pSrcReal); - elem.baseVertexPointerToElement(pDstBase, &pDstReal); - if(elem.getSemantic()==VES_TEXTURE_COORDINATES && elem.getIndex()==mTexCoordIndex) - { - isTheBufferWithIndex=true; - *pDstReal++ = static_cast(index); - } - else - { - switch (elem.getSemantic()) - { - case VES_POSITION: - tmp.x = pSrcReal[0]; - tmp.y = pSrcReal[1]; - tmp.z = pSrcReal[2]; - if(tmp.xXmax) - Xmax = tmp.x; - if(tmp.y>Ymax) - Ymax = tmp.y; - if(tmp.z>Zmax) - Zmax = tmp.z; - default: - // just raw copy - memcpy(pDstReal, pSrcReal, - VertexElement::getTypeSize(elem.getType())); - break; - }; - - } - - - } - if (isTheBufferWithIndex) - pDstBase += bufInc+4; - else - pDstBase += bufInc; - pSrcBase += bufInc; - - } - - // Update pointer - destBufferLocks[b] = pDstBase; - srcBuf->unlock(); - - - } - indexOffset += geom->geometry->vertexData->vertexCount; - - - precGeom=geom; - - } - mParent->setLastIndex(index); - // Unlock everything - mRenderOp.indexData->indexBuffer->unlock(); - for (b = 0; b < binds->getBufferCount(); ++b) - { - binds->getBuffer(b)->unlock(); - } - - OGRE_DELETE mVertexData; - OGRE_DELETE mIndexData; - - mVertexData=mRenderOp.vertexData; - mIndexData=mRenderOp.indexData; - mBatch->getRenderOperationVector().push_back(&mRenderOp); - setBoundingBox(AxisAlignedBox(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax)); - mAABB=AxisAlignedBox(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax); - - } - //-------------------------------------------------------------------------- - void InstancedGeometry::GeometryBucket::dump(std::ofstream& of) const - { - of << "Geometry Bucket" << std::endl; - of << "---------------" << std::endl; - of << "Format string: " << mFormatString << std::endl; - of << "Geometry items: " << mQueuedGeometry.size() << std::endl; - of << "---------------" << std::endl; - - } - //-------------------------------------------------------------------------- - void InstancedGeometry::GeometryBucket::visitRenderables( - Renderable::Visitor* visitor, bool debugRenderables) - { - visitor->visit(this, mParent->getParent()->getLod(), false); - } - //--------------------------------------------------------------------- + } + //-------------------------------------------------------------------------- + const LightList& InstancedGeometry::GeometryBucket::getLights(void) const + { + return mParent->getParent()->getParent()->getLights(); + } + //-------------------------------------------------------------------------- + bool InstancedGeometry::GeometryBucket::getCastsShadows(void) const + { + return mParent->getParent()->getParent()->getCastShadows(); + } + //-------------------------------------------------------------------------- + bool InstancedGeometry::GeometryBucket::assign(QueuedGeometry* qgeom) + { + // Do we have enough space? + if (mRenderOp.vertexData->vertexCount + qgeom->geometry->vertexData->vertexCount + > mMaxVertexIndex) + { + return false; + } + + mQueuedGeometry.push_back(qgeom); + mRenderOp.vertexData->vertexCount += qgeom->geometry->vertexData->vertexCount; + mRenderOp.indexData->indexCount += qgeom->geometry->indexData->indexCount; + + return true; + } + + //-------------------------------------------------------------------------- + void InstancedGeometry::GeometryBucket::build() + { + + + + // Ok, here's where we transfer the vertices and indexes to the shared + // buffers + // Shortcuts + VertexDeclaration* dcl = mRenderOp.vertexData->vertexDeclaration; + VertexBufferBinding* binds =mVertexData->vertexBufferBinding; + + // create index buffer, and lock + mRenderOp.indexData->indexBuffer = HardwareBufferManager::getSingleton() + .createIndexBuffer(mIndexType, mRenderOp.indexData->indexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + uint32* p32Dest = 0; + uint16* p16Dest = 0; + + if (mIndexType == HardwareIndexBuffer::IT_32BIT) + { + p32Dest = static_cast( + mRenderOp.indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + } + else + { + p16Dest = static_cast( + mRenderOp.indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + } + + // create all vertex buffers, and lock + ushort b; + //ushort posBufferIdx = dcl->findElementBySemantic(VES_POSITION)->getSource(); + + vector::type destBufferLocks; + vector::type bufferElements; + + for (b = 0; b < binds->getBufferCount(); ++b) + { + + size_t vertexCount = mRenderOp.vertexData->vertexCount; + + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + dcl->getVertexSize(b), + vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + binds->setBinding(b, vbuf); + uchar* pLock = static_cast( + vbuf->lock(HardwareBuffer::HBL_DISCARD)); + destBufferLocks.push_back(pLock); + // Pre-cache vertex elements per buffer + bufferElements.push_back(dcl->findElementsBySource(b)); + mRenderOp.vertexData->vertexBufferBinding->setBinding(b,vbuf); + } + + + // Iterate over the geometry items + size_t indexOffset = 0; + + QueuedGeometryList::iterator gi, giend; + giend = mQueuedGeometry.end(); + + // to generate the boundingBox + Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax; + Xmin=0; + Ymin=0; + Zmin=0; + Xmax=0; + Ymax=0; + Zmax=0; + QueuedGeometry* precGeom = *(mQueuedGeometry.begin()); + unsigned short index=0; + if( mParent->getLastIndex()!=0) + index=mParent->getLastIndex()+1; + + for (gi = mQueuedGeometry.begin(); gi != giend; ++gi) + { + + QueuedGeometry* geom = *gi; + if(precGeom->ID!=geom->ID) + index++; + + //create a new instanced object + InstancedObject* instancedObject = mParent->getParent()->getParent()->isInstancedObjectPresent(index); + if(instancedObject == NULL) + { + if(mBatch->getBaseSkeleton().isNull()) + { + instancedObject= OGRE_NEW InstancedObject(index); + } + else + { + instancedObject= OGRE_NEW InstancedObject(index,mBatch->getBaseSkeletonInstance(), + mBatch->getBaseAnimationState()); + } + mParent->getParent()->getParent()->addInstancedObject(index,instancedObject); + + } + instancedObject->addBucketToList(this); + + + + // Copy indexes across with offset + IndexData* srcIdxData = geom->geometry->indexData; + if (mIndexType == HardwareIndexBuffer::IT_32BIT) + { + // Lock source indexes + uint32* pSrc = static_cast( + srcIdxData->indexBuffer->lock( + srcIdxData->indexStart, + srcIdxData->indexCount * srcIdxData->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + + copyIndexes(pSrc, p32Dest, srcIdxData->indexCount, indexOffset); + p32Dest += srcIdxData->indexCount; + srcIdxData->indexBuffer->unlock(); + } + else + { + + // Lock source indexes + uint16* pSrc = static_cast( + srcIdxData->indexBuffer->lock( + srcIdxData->indexStart, + srcIdxData->indexCount * srcIdxData->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + + copyIndexes(pSrc, p16Dest, srcIdxData->indexCount, indexOffset); + p16Dest += srcIdxData->indexCount; + srcIdxData->indexBuffer->unlock(); + } + + // Now deal with vertex buffers + // we can rely on buffer counts / formats being the same + VertexData* srcVData = geom->geometry->vertexData; + VertexBufferBinding* srcBinds = srcVData->vertexBufferBinding; + + for (b = 0; b < binds->getBufferCount(); ++b) + { + + // lock source + HardwareVertexBufferSharedPtr srcBuf = + srcBinds->getBuffer(b); + uchar* pSrcBase = static_cast( + srcBuf->lock(HardwareBuffer::HBL_READ_ONLY)); + // Get buffer lock pointer, we'll update this later + uchar* pDstBase = destBufferLocks[b]; + size_t bufInc = srcBuf->getVertexSize(); + + // Iterate over vertices + float *pSrcReal, *pDstReal; + Vector3 tmp; + + + + for (size_t v = 0; v < srcVData->vertexCount; ++v) + { + //to know if the current buffer is the one with the buffer or not + bool isTheBufferWithIndex=false; + // Iterate over vertex elements + VertexDeclaration::VertexElementList& elems = + bufferElements[b]; + VertexDeclaration::VertexElementList::iterator ei; + + for (ei = elems.begin(); ei != elems.end(); ++ei) + { + VertexElement& elem = *ei; + elem.baseVertexPointerToElement(pSrcBase, &pSrcReal); + elem.baseVertexPointerToElement(pDstBase, &pDstReal); + if(elem.getSemantic()==VES_TEXTURE_COORDINATES && elem.getIndex()==mTexCoordIndex) + { + isTheBufferWithIndex=true; + *pDstReal++ = static_cast(index); + } + else + { + switch (elem.getSemantic()) + { + case VES_POSITION: + tmp.x = pSrcReal[0]; + tmp.y = pSrcReal[1]; + tmp.z = pSrcReal[2]; + if(tmp.xXmax) + Xmax = tmp.x; + if(tmp.y>Ymax) + Ymax = tmp.y; + if(tmp.z>Zmax) + Zmax = tmp.z; + default: + // just raw copy + memcpy(pDstReal, pSrcReal, + VertexElement::getTypeSize(elem.getType())); + break; + }; + + } + + + } + if (isTheBufferWithIndex) + pDstBase += bufInc+4; + else + pDstBase += bufInc; + pSrcBase += bufInc; + + } + + // Update pointer + destBufferLocks[b] = pDstBase; + srcBuf->unlock(); + + + } + indexOffset += geom->geometry->vertexData->vertexCount; + + + precGeom=geom; + + } + mParent->setLastIndex(index); + // Unlock everything + mRenderOp.indexData->indexBuffer->unlock(); + for (b = 0; b < binds->getBufferCount(); ++b) + { + binds->getBuffer(b)->unlock(); + } + + OGRE_DELETE mVertexData; + OGRE_DELETE mIndexData; + + mVertexData=mRenderOp.vertexData; + mIndexData=mRenderOp.indexData; + mBatch->getRenderOperationVector().push_back(&mRenderOp); + setBoundingBox(AxisAlignedBox(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax)); + mAABB=AxisAlignedBox(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax); + + } + //-------------------------------------------------------------------------- + void InstancedGeometry::GeometryBucket::dump(std::ofstream& of) const + { + of << "Geometry Bucket" << std::endl; + of << "---------------" << std::endl; + of << "Format string: " << mFormatString << std::endl; + of << "Geometry items: " << mQueuedGeometry.size() << std::endl; + of << "---------------" << std::endl; + + } + //-------------------------------------------------------------------------- + void InstancedGeometry::GeometryBucket::visitRenderables( + Renderable::Visitor* visitor, bool debugRenderables) + { + visitor->visit(this, mParent->getParent()->getLod(), false); + } + //--------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreKeyFrame.cpp b/OgreMain/src/OgreKeyFrame.cpp index 9fc18d97f7c..33adfede574 100644 --- a/OgreMain/src/OgreKeyFrame.cpp +++ b/OgreMain/src/OgreKeyFrame.cpp @@ -37,40 +37,40 @@ namespace Ogre : mTime(time), mParentTrack(parent) { } - //--------------------------------------------------------------------- - KeyFrame* KeyFrame::_clone(AnimationTrack* newParent) const - { - return OGRE_NEW KeyFrame(newParent, mTime); - } - //--------------------------------------------------------------------- - NumericKeyFrame::NumericKeyFrame(const AnimationTrack* parent, Real time) - :KeyFrame(parent, time) - { - } - //--------------------------------------------------------------------- - const AnyNumeric& NumericKeyFrame::getValue(void) const - { - return mValue; - } - //--------------------------------------------------------------------- - void NumericKeyFrame::setValue(const AnyNumeric& val) - { - mValue = val; - } - //--------------------------------------------------------------------- - KeyFrame* NumericKeyFrame::_clone(AnimationTrack* newParent) const - { - NumericKeyFrame* newKf = OGRE_NEW NumericKeyFrame(newParent, mTime); - newKf->mValue = mValue; - return newKf; - } - //--------------------------------------------------------------------- - TransformKeyFrame::TransformKeyFrame(const AnimationTrack* parent, Real time) - :KeyFrame(parent, time), mTranslate(Vector3::ZERO), - mScale(Vector3::UNIT_SCALE), mRotate(Quaternion::IDENTITY) - { - } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + KeyFrame* KeyFrame::_clone(AnimationTrack* newParent) const + { + return OGRE_NEW KeyFrame(newParent, mTime); + } + //--------------------------------------------------------------------- + NumericKeyFrame::NumericKeyFrame(const AnimationTrack* parent, Real time) + :KeyFrame(parent, time) + { + } + //--------------------------------------------------------------------- + const AnyNumeric& NumericKeyFrame::getValue(void) const + { + return mValue; + } + //--------------------------------------------------------------------- + void NumericKeyFrame::setValue(const AnyNumeric& val) + { + mValue = val; + } + //--------------------------------------------------------------------- + KeyFrame* NumericKeyFrame::_clone(AnimationTrack* newParent) const + { + NumericKeyFrame* newKf = OGRE_NEW NumericKeyFrame(newParent, mTime); + newKf->mValue = mValue; + return newKf; + } + //--------------------------------------------------------------------- + TransformKeyFrame::TransformKeyFrame(const AnimationTrack* parent, Real time) + :KeyFrame(parent, time), mTranslate(Vector3::ZERO), + mScale(Vector3::UNIT_SCALE), mRotate(Quaternion::IDENTITY) + { + } + //--------------------------------------------------------------------- void TransformKeyFrame::setTranslate(const Vector3& trans) { mTranslate = trans; @@ -107,131 +107,131 @@ namespace Ogre return mRotate; } //--------------------------------------------------------------------- - KeyFrame* TransformKeyFrame::_clone(AnimationTrack* newParent) const - { - TransformKeyFrame* newKf = OGRE_NEW TransformKeyFrame(newParent, mTime); - newKf->mTranslate = mTranslate; - newKf->mScale = mScale; - newKf->mRotate = mRotate; - return newKf; - } - //--------------------------------------------------------------------- - VertexMorphKeyFrame::VertexMorphKeyFrame(const AnimationTrack* parent, Real time) - : KeyFrame(parent, time) - { - } - //--------------------------------------------------------------------- - void VertexMorphKeyFrame::setVertexBuffer(const HardwareVertexBufferSharedPtr& buf) - { - mBuffer = buf; - } - //--------------------------------------------------------------------- - const HardwareVertexBufferSharedPtr& - VertexMorphKeyFrame::getVertexBuffer(void) const - { - return mBuffer; - } - //--------------------------------------------------------------------- - KeyFrame* VertexMorphKeyFrame::_clone(AnimationTrack* newParent) const - { - VertexMorphKeyFrame* newKf = OGRE_NEW VertexMorphKeyFrame(newParent, mTime); - newKf->mBuffer = mBuffer; - return newKf; - } - //--------------------------------------------------------------------- - VertexPoseKeyFrame::VertexPoseKeyFrame(const AnimationTrack* parent, Real time) - :KeyFrame(parent, time) - { - } - //--------------------------------------------------------------------- - void VertexPoseKeyFrame::addPoseReference(ushort poseIndex, Real influence) - { - mPoseRefs.push_back(PoseRef(poseIndex, influence)); - } - //--------------------------------------------------------------------- - void VertexPoseKeyFrame::updatePoseReference(ushort poseIndex, Real influence) - { - for (PoseRefList::iterator i = mPoseRefs.begin(); i != mPoseRefs.end(); ++i) - { - if (i->poseIndex == poseIndex) - { - i->influence = influence; - return; - } - } - // if we got here, we didn't find it - addPoseReference(poseIndex, influence); + KeyFrame* TransformKeyFrame::_clone(AnimationTrack* newParent) const + { + TransformKeyFrame* newKf = OGRE_NEW TransformKeyFrame(newParent, mTime); + newKf->mTranslate = mTranslate; + newKf->mScale = mScale; + newKf->mRotate = mRotate; + return newKf; + } + //--------------------------------------------------------------------- + VertexMorphKeyFrame::VertexMorphKeyFrame(const AnimationTrack* parent, Real time) + : KeyFrame(parent, time) + { + } + //--------------------------------------------------------------------- + void VertexMorphKeyFrame::setVertexBuffer(const HardwareVertexBufferSharedPtr& buf) + { + mBuffer = buf; + } + //--------------------------------------------------------------------- + const HardwareVertexBufferSharedPtr& + VertexMorphKeyFrame::getVertexBuffer(void) const + { + return mBuffer; + } + //--------------------------------------------------------------------- + KeyFrame* VertexMorphKeyFrame::_clone(AnimationTrack* newParent) const + { + VertexMorphKeyFrame* newKf = OGRE_NEW VertexMorphKeyFrame(newParent, mTime); + newKf->mBuffer = mBuffer; + return newKf; + } + //--------------------------------------------------------------------- + VertexPoseKeyFrame::VertexPoseKeyFrame(const AnimationTrack* parent, Real time) + :KeyFrame(parent, time) + { + } + //--------------------------------------------------------------------- + void VertexPoseKeyFrame::addPoseReference(ushort poseIndex, Real influence) + { + mPoseRefs.push_back(PoseRef(poseIndex, influence)); + } + //--------------------------------------------------------------------- + void VertexPoseKeyFrame::updatePoseReference(ushort poseIndex, Real influence) + { + for (PoseRefList::iterator i = mPoseRefs.begin(); i != mPoseRefs.end(); ++i) + { + if (i->poseIndex == poseIndex) + { + i->influence = influence; + return; + } + } + // if we got here, we didn't find it + addPoseReference(poseIndex, influence); - } - //--------------------------------------------------------------------- - void VertexPoseKeyFrame::removePoseReference(ushort poseIndex) - { - for (PoseRefList::iterator i = mPoseRefs.begin(); i != mPoseRefs.end(); ++i) - { - if (i->poseIndex == poseIndex) - { - mPoseRefs.erase(i); - return; - } - } - } - //--------------------------------------------------------------------- - void VertexPoseKeyFrame::removeAllPoseReferences(void) - { - mPoseRefs.clear(); - } - //--------------------------------------------------------------------- - const VertexPoseKeyFrame::PoseRefList& - VertexPoseKeyFrame::getPoseReferences(void) const - { - return mPoseRefs; - } - //--------------------------------------------------------------------- - VertexPoseKeyFrame::PoseRefIterator - VertexPoseKeyFrame::getPoseReferenceIterator(void) - { - return PoseRefIterator(mPoseRefs.begin(), mPoseRefs.end()); - } - //--------------------------------------------------------------------- - VertexPoseKeyFrame::ConstPoseRefIterator - VertexPoseKeyFrame::getPoseReferenceIterator(void) const - { - return ConstPoseRefIterator(mPoseRefs.begin(), mPoseRefs.end()); - } - //--------------------------------------------------------------------- - KeyFrame* VertexPoseKeyFrame::_clone(AnimationTrack* newParent) const - { - VertexPoseKeyFrame* newKf = OGRE_NEW VertexPoseKeyFrame(newParent, mTime); - // By-value copy ok - newKf->mPoseRefs = mPoseRefs; - return newKf; - } - //--------------------------------------------------------------------- - void VertexPoseKeyFrame::_applyBaseKeyFrame(const VertexPoseKeyFrame* base) - { - // We subtract the matching pose influences in the base keyframe from the - // influences in this keyframe - for (PoseRefList::iterator i = mPoseRefs.begin(); i != mPoseRefs.end(); ++i) - { - PoseRef& myPoseRef = *i; - - VertexPoseKeyFrame::ConstPoseRefIterator basePoseIt = base->getPoseReferenceIterator(); - Real baseInfluence = 0.0f; - while (basePoseIt.hasMoreElements()) - { - const VertexPoseKeyFrame::PoseRef& basePoseRef = basePoseIt.getNext(); - if (basePoseRef.poseIndex == myPoseRef.poseIndex) - { - baseInfluence = basePoseRef.influence; - break; - } - } - - myPoseRef.influence -= baseInfluence; - - } - - } + } + //--------------------------------------------------------------------- + void VertexPoseKeyFrame::removePoseReference(ushort poseIndex) + { + for (PoseRefList::iterator i = mPoseRefs.begin(); i != mPoseRefs.end(); ++i) + { + if (i->poseIndex == poseIndex) + { + mPoseRefs.erase(i); + return; + } + } + } + //--------------------------------------------------------------------- + void VertexPoseKeyFrame::removeAllPoseReferences(void) + { + mPoseRefs.clear(); + } + //--------------------------------------------------------------------- + const VertexPoseKeyFrame::PoseRefList& + VertexPoseKeyFrame::getPoseReferences(void) const + { + return mPoseRefs; + } + //--------------------------------------------------------------------- + VertexPoseKeyFrame::PoseRefIterator + VertexPoseKeyFrame::getPoseReferenceIterator(void) + { + return PoseRefIterator(mPoseRefs.begin(), mPoseRefs.end()); + } + //--------------------------------------------------------------------- + VertexPoseKeyFrame::ConstPoseRefIterator + VertexPoseKeyFrame::getPoseReferenceIterator(void) const + { + return ConstPoseRefIterator(mPoseRefs.begin(), mPoseRefs.end()); + } + //--------------------------------------------------------------------- + KeyFrame* VertexPoseKeyFrame::_clone(AnimationTrack* newParent) const + { + VertexPoseKeyFrame* newKf = OGRE_NEW VertexPoseKeyFrame(newParent, mTime); + // By-value copy ok + newKf->mPoseRefs = mPoseRefs; + return newKf; + } + //--------------------------------------------------------------------- + void VertexPoseKeyFrame::_applyBaseKeyFrame(const VertexPoseKeyFrame* base) + { + // We subtract the matching pose influences in the base keyframe from the + // influences in this keyframe + for (PoseRefList::iterator i = mPoseRefs.begin(); i != mPoseRefs.end(); ++i) + { + PoseRef& myPoseRef = *i; + + VertexPoseKeyFrame::ConstPoseRefIterator basePoseIt = base->getPoseReferenceIterator(); + Real baseInfluence = 0.0f; + while (basePoseIt.hasMoreElements()) + { + const VertexPoseKeyFrame::PoseRef& basePoseRef = basePoseIt.getNext(); + if (basePoseRef.poseIndex == myPoseRef.poseIndex) + { + baseInfluence = basePoseRef.influence; + break; + } + } + + myPoseRef.influence -= baseInfluence; + + } + + } } diff --git a/OgreMain/src/OgreLight.cpp b/OgreMain/src/OgreLight.cpp index fc87eb59d3c..1836129cfe4 100644 --- a/OgreMain/src/OgreLight.cpp +++ b/OgreMain/src/OgreLight.cpp @@ -35,68 +35,68 @@ THE SOFTWARE. namespace Ogre { //----------------------------------------------------------------------- Light::Light() - : mLightType(LT_POINT), + : mLightType(LT_POINT), mPosition(Vector3::ZERO), mDiffuse(ColourValue::White), mSpecular(ColourValue::Black), mDirection(Vector3::UNIT_Z), - mSpotOuter(Degree(40.0f)), + mSpotOuter(Degree(40.0f)), mSpotInner(Degree(30.0f)), mSpotFalloff(1.0f), mSpotNearClip(0.0f), - mRange(100000), - mAttenuationConst(1.0f), - mAttenuationLinear(0.0f), + mRange(100000), + mAttenuationConst(1.0f), + mAttenuationLinear(0.0f), mAttenuationQuad(0.0f), - mPowerScale(1.0f), - mIndexInFrame(0), - mOwnShadowFarDist(false), - mShadowFarDist(0), - mShadowFarDistSquared(0), - mShadowNearClipDist(-1), - mShadowFarClipDist(-1), + mPowerScale(1.0f), + mIndexInFrame(0), + mOwnShadowFarDist(false), + mShadowFarDist(0), + mShadowFarDistSquared(0), + mShadowNearClipDist(-1), + mShadowFarClipDist(-1), mDerivedPosition(Vector3::ZERO), mDerivedDirection(Vector3::UNIT_Z), - mDerivedCamRelativePosition(Vector3::ZERO), - mDerivedCamRelativeDirty(false), - mCameraToBeRelativeTo(0), + mDerivedCamRelativePosition(Vector3::ZERO), + mDerivedCamRelativeDirty(false), + mCameraToBeRelativeTo(0), mDerivedTransformDirty(false), - mCustomShadowCameraSetup() + mCustomShadowCameraSetup() { - //mMinPixelSize should always be zero for lights otherwise lights will disapear - mMinPixelSize = 0; + //mMinPixelSize should always be zero for lights otherwise lights will disapear + mMinPixelSize = 0; } //----------------------------------------------------------------------- - Light::Light(const String& name) : MovableObject(name), + Light::Light(const String& name) : MovableObject(name), mLightType(LT_POINT), mPosition(Vector3::ZERO), mDiffuse(ColourValue::White), mSpecular(ColourValue::Black), mDirection(Vector3::UNIT_Z), - mSpotOuter(Degree(40.0f)), + mSpotOuter(Degree(40.0f)), mSpotInner(Degree(30.0f)), mSpotFalloff(1.0f), mSpotNearClip(0.0f), - mRange(100000), - mAttenuationConst(1.0f), - mAttenuationLinear(0.0f), + mRange(100000), + mAttenuationConst(1.0f), + mAttenuationLinear(0.0f), mAttenuationQuad(0.0f), - mPowerScale(1.0f), - mIndexInFrame(0), - mOwnShadowFarDist(false), - mShadowFarDist(0), - mShadowFarDistSquared(0), - mShadowNearClipDist(-1), - mShadowFarClipDist(-1), + mPowerScale(1.0f), + mIndexInFrame(0), + mOwnShadowFarDist(false), + mShadowFarDist(0), + mShadowFarDistSquared(0), + mShadowNearClipDist(-1), + mShadowFarClipDist(-1), mDerivedPosition(Vector3::ZERO), mDerivedDirection(Vector3::UNIT_Z), - mDerivedCamRelativeDirty(false), - mCameraToBeRelativeTo(0), + mDerivedCamRelativeDirty(false), + mCameraToBeRelativeTo(0), mDerivedTransformDirty(false), - mCustomShadowCameraSetup() + mCustomShadowCameraSetup() { - //mMinPixelSize should always be zero for lights otherwise lights will disapear - mMinPixelSize = 0; + //mMinPixelSize should always be zero for lights otherwise lights will disapear + mMinPixelSize = 0; } //----------------------------------------------------------------------- Light::~Light() @@ -157,21 +157,21 @@ namespace Ogre { mSpotOuter = outerAngle; mSpotFalloff = falloff; } - //----------------------------------------------------------------------- - void Light::setSpotlightInnerAngle(const Radian& val) - { - mSpotInner = val; - } - //----------------------------------------------------------------------- - void Light::setSpotlightOuterAngle(const Radian& val) - { - mSpotOuter = val; - } - //----------------------------------------------------------------------- - void Light::setSpotlightFalloff(Real val) - { - mSpotFalloff = val; - } + //----------------------------------------------------------------------- + void Light::setSpotlightInnerAngle(const Radian& val) + { + mSpotInner = val; + } + //----------------------------------------------------------------------- + void Light::setSpotlightOuterAngle(const Radian& val) + { + mSpotOuter = val; + } + //----------------------------------------------------------------------- + void Light::setSpotlightFalloff(Real val) + { + mSpotFalloff = val; + } //----------------------------------------------------------------------- const Radian& Light::getSpotlightInnerAngle(void) const { @@ -251,15 +251,15 @@ namespace Ogre { return mAttenuationQuad; } //----------------------------------------------------------------------- - void Light::setPowerScale(Real power) - { - mPowerScale = power; - } + void Light::setPowerScale(Real power) + { + mPowerScale = power; + } //----------------------------------------------------------------------- - Real Light::getPowerScale(void) const - { - return mPowerScale; - } + Real Light::getPowerScale(void) const + { + return mPowerScale; + } //----------------------------------------------------------------------- void Light::update(void) const { @@ -283,11 +283,11 @@ namespace Ogre { //if the position has been updated we must update also the relative position mDerivedCamRelativeDirty = true; } - if (mCameraToBeRelativeTo && mDerivedCamRelativeDirty) - { - mDerivedCamRelativePosition = mDerivedPosition - mCameraToBeRelativeTo->getDerivedPosition(); - mDerivedCamRelativeDirty = false; - } + if (mCameraToBeRelativeTo && mDerivedCamRelativeDirty) + { + mDerivedCamRelativePosition = mDerivedPosition - mCameraToBeRelativeTo->getDerivedPosition(); + mDerivedCamRelativeDirty = false; + } } //----------------------------------------------------------------------- void Light::_notifyAttached(Node* parent, bool isTagPoint) @@ -315,29 +315,29 @@ namespace Ogre { { // Do nothing } - //----------------------------------------------------------------------- - void Light::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - // nothing to render - } + //----------------------------------------------------------------------- + void Light::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + // nothing to render + } //----------------------------------------------------------------------- const String& Light::getMovableType(void) const { - return LightFactory::FACTORY_TYPE_NAME; + return LightFactory::FACTORY_TYPE_NAME; } //----------------------------------------------------------------------- const Vector3& Light::getDerivedPosition(bool cameraRelative) const { update(); - if (cameraRelative && mCameraToBeRelativeTo) - { - return mDerivedCamRelativePosition; - } - else - { - return mDerivedPosition; - } + if (cameraRelative && mCameraToBeRelativeTo) + { + return mDerivedCamRelativePosition; + } + else + { + return mDerivedPosition; + } } //----------------------------------------------------------------------- const Vector3& Light::getDerivedDirection(void) const @@ -351,21 +351,21 @@ namespace Ogre { MovableObject::setVisible(visible); } //----------------------------------------------------------------------- - Vector4 Light::getAs4DVector(bool cameraRelativeIfSet) const - { - Vector4 ret; + Vector4 Light::getAs4DVector(bool cameraRelativeIfSet) const + { + Vector4 ret; if (mLightType == Light::LT_DIRECTIONAL) { ret = -(getDerivedDirection()); // negate direction as 'position' ret.w = 0.0; // infinite distance - } - else + } + else { ret = getDerivedPosition(cameraRelativeIfSet); ret.w = 1.0; } - return ret; - } + return ret; + } //----------------------------------------------------------------------- const PlaneBoundedVolume& Light::_getNearClipVolume(const Camera* const cam) const { @@ -456,15 +456,15 @@ namespace Ogre { bool infiniteViewDistance = (cam->getFarClipDistance() == 0); - Vector3 notSoFarCorners[4]; - if(infiniteViewDistance) - { - Vector3 camPosition = cam->getRealPosition(); - notSoFarCorners[0] = corners[0] + corners[0] - camPosition; - notSoFarCorners[1] = corners[1] + corners[1] - camPosition; - notSoFarCorners[2] = corners[2] + corners[2] - camPosition; - notSoFarCorners[3] = corners[3] + corners[3] - camPosition; - } + Vector3 notSoFarCorners[4]; + if(infiniteViewDistance) + { + Vector3 camPosition = cam->getRealPosition(); + notSoFarCorners[0] = corners[0] + corners[0] - camPosition; + notSoFarCorners[1] = corners[1] + corners[1] - camPosition; + notSoFarCorners[2] = corners[2] + corners[2] - camPosition; + notSoFarCorners[3] = corners[3] + corners[3] - camPosition; + } mFrustumClipVolumes.clear(); for (unsigned short n = 0; n < 6; ++n) @@ -529,7 +529,7 @@ namespace Ogre { // Iterate over world points and form side planes Vector3 normal; Vector3 lightDir; - unsigned int infiniteViewDistanceInt = infiniteViewDistance ? 1 : 0; + unsigned int infiniteViewDistanceInt = infiniteViewDistance ? 1 : 0; for (unsigned int i = 0; i < 4 - infiniteViewDistanceInt; ++i) { // Figure out light dir @@ -557,274 +557,274 @@ namespace Ogre { return mFrustumClipVolumes; } - //----------------------------------------------------------------------- - uint32 Light::getTypeFlags(void) const - { - return SceneManager::LIGHT_TYPE_MASK; - } - //--------------------------------------------------------------------- - void Light::_calcTempSquareDist(const Vector3& worldPos) - { - if (mLightType == LT_DIRECTIONAL) - { - tempSquareDist = 0; - } - else - { - tempSquareDist = - (worldPos - getDerivedPosition()).squaredLength(); - } - - } - //----------------------------------------------------------------------- - class LightDiffuseColourValue : public AnimableValue - { - protected: - Light* mLight; - public: - LightDiffuseColourValue(Light* l) :AnimableValue(COLOUR) - { mLight = l; } - void setValue(const ColourValue& val) - { - mLight->setDiffuseColour(val); - } - void applyDeltaValue(const ColourValue& val) - { - setValue(mLight->getDiffuseColour() + val); - } - void setCurrentStateAsBaseValue(void) - { - setAsBaseValue(mLight->getDiffuseColour()); - } - - }; - //----------------------------------------------------------------------- - class LightSpecularColourValue : public AnimableValue - { - protected: - Light* mLight; - public: - LightSpecularColourValue(Light* l) :AnimableValue(COLOUR) - { mLight = l; } - void setValue(const ColourValue& val) - { - mLight->setSpecularColour(val); - } - void applyDeltaValue(const ColourValue& val) - { - setValue(mLight->getSpecularColour() + val); - } - void setCurrentStateAsBaseValue(void) - { - setAsBaseValue(mLight->getSpecularColour()); - } - - }; - //----------------------------------------------------------------------- - class LightAttenuationValue : public AnimableValue - { - protected: - Light* mLight; - public: - LightAttenuationValue(Light* l) :AnimableValue(VECTOR4) - { mLight = l; } - void setValue(const Vector4& val) - { - mLight->setAttenuation(val.x, val.y, val.z, val.w); - } - void applyDeltaValue(const Vector4& val) - { - setValue(mLight->getAs4DVector() + val); - } - void setCurrentStateAsBaseValue(void) - { - setAsBaseValue(mLight->getAs4DVector()); - } - - }; - //----------------------------------------------------------------------- - class LightSpotlightInnerValue : public AnimableValue - { - protected: - Light* mLight; - public: - LightSpotlightInnerValue(Light* l) :AnimableValue(REAL) - { mLight = l; } - void setValue(Real val) - { - mLight->setSpotlightInnerAngle(Radian(val)); - } - void applyDeltaValue(Real val) - { - setValue(mLight->getSpotlightInnerAngle().valueRadians() + val); - } - void setCurrentStateAsBaseValue(void) - { - setAsBaseValue(mLight->getSpotlightInnerAngle().valueRadians()); - } - - }; - //----------------------------------------------------------------------- - class LightSpotlightOuterValue : public AnimableValue - { - protected: - Light* mLight; - public: - LightSpotlightOuterValue(Light* l) :AnimableValue(REAL) - { mLight = l; } - void setValue(Real val) - { - mLight->setSpotlightOuterAngle(Radian(val)); - } - void applyDeltaValue(Real val) - { - setValue(mLight->getSpotlightOuterAngle().valueRadians() + val); - } - void setCurrentStateAsBaseValue(void) - { - setAsBaseValue(mLight->getSpotlightOuterAngle().valueRadians()); - } - - }; - //----------------------------------------------------------------------- - class LightSpotlightFalloffValue : public AnimableValue - { - protected: - Light* mLight; - public: - LightSpotlightFalloffValue(Light* l) :AnimableValue(REAL) - { mLight = l; } - void setValue(Real val) - { - mLight->setSpotlightFalloff(val); - } - void applyDeltaValue(Real val) - { - setValue(mLight->getSpotlightFalloff() + val); - } - void setCurrentStateAsBaseValue(void) - { - setAsBaseValue(mLight->getSpotlightFalloff()); - } - - }; - //----------------------------------------------------------------------- - AnimableValuePtr Light::createAnimableValue(const String& valueName) - { - if (valueName == "diffuseColour") - { - return AnimableValuePtr( - OGRE_NEW LightDiffuseColourValue(this)); - } - else if(valueName == "specularColour") - { - return AnimableValuePtr( - OGRE_NEW LightSpecularColourValue(this)); - } - else if (valueName == "attenuation") - { - return AnimableValuePtr( - OGRE_NEW LightAttenuationValue(this)); - } - else if (valueName == "spotlightInner") - { - return AnimableValuePtr( - OGRE_NEW LightSpotlightInnerValue(this)); - } - else if (valueName == "spotlightOuter") - { - return AnimableValuePtr( - OGRE_NEW LightSpotlightOuterValue(this)); - } - else if (valueName == "spotlightFalloff") - { - return AnimableValuePtr( - OGRE_NEW LightSpotlightFalloffValue(this)); - } - else - { - return MovableObject::createAnimableValue(valueName); - } - } - //----------------------------------------------------------------------- - void Light::setCustomShadowCameraSetup(const ShadowCameraSetupPtr& customShadowSetup) - { - mCustomShadowCameraSetup = customShadowSetup; - } - //----------------------------------------------------------------------- - void Light::resetCustomShadowCameraSetup() - { - mCustomShadowCameraSetup.setNull(); - } - //----------------------------------------------------------------------- - const ShadowCameraSetupPtr& Light::getCustomShadowCameraSetup() const - { - return mCustomShadowCameraSetup; - } - //----------------------------------------------------------------------- - void Light::setShadowFarDistance(Real distance) - { - mOwnShadowFarDist = true; - mShadowFarDist = distance; - mShadowFarDistSquared = distance * distance; - } - //----------------------------------------------------------------------- - void Light::resetShadowFarDistance(void) - { - mOwnShadowFarDist = false; - } - //----------------------------------------------------------------------- - Real Light::getShadowFarDistance(void) const - { - if (mOwnShadowFarDist) - return mShadowFarDist; - else - return mManager->getShadowFarDistance (); - } - //----------------------------------------------------------------------- - Real Light::getShadowFarDistanceSquared(void) const - { - if (mOwnShadowFarDist) - return mShadowFarDistSquared; - else - return mManager->getShadowFarDistanceSquared (); - } - //--------------------------------------------------------------------- - void Light::_setCameraRelative(Camera* cam) - { - mCameraToBeRelativeTo = cam; - mDerivedCamRelativeDirty = true; - } - //--------------------------------------------------------------------- - Real Light::_deriveShadowNearClipDistance(const Camera* maincam) const - { - if (mShadowNearClipDist > 0) - return mShadowNearClipDist; - else - return maincam->getNearClipDistance(); - } - //--------------------------------------------------------------------- - Real Light::_deriveShadowFarClipDistance(const Camera* maincam) const - { - if (mShadowFarClipDist >= 0) - return mShadowFarClipDist; - else - { - if (mLightType == LT_DIRECTIONAL) - return 0; - else - return mRange; - } - } - //----------------------------------------------------------------------- - void Light::setCustomParameter(uint16 index, const Ogre::Vector4 &value) - { - mCustomParameters[index] = value; - } - //----------------------------------------------------------------------- - const Vector4 &Light::getCustomParameter(uint16 index) const - { - CustomParameterMap::const_iterator i = mCustomParameters.find(index); + //----------------------------------------------------------------------- + uint32 Light::getTypeFlags(void) const + { + return SceneManager::LIGHT_TYPE_MASK; + } + //--------------------------------------------------------------------- + void Light::_calcTempSquareDist(const Vector3& worldPos) + { + if (mLightType == LT_DIRECTIONAL) + { + tempSquareDist = 0; + } + else + { + tempSquareDist = + (worldPos - getDerivedPosition()).squaredLength(); + } + + } + //----------------------------------------------------------------------- + class LightDiffuseColourValue : public AnimableValue + { + protected: + Light* mLight; + public: + LightDiffuseColourValue(Light* l) :AnimableValue(COLOUR) + { mLight = l; } + void setValue(const ColourValue& val) + { + mLight->setDiffuseColour(val); + } + void applyDeltaValue(const ColourValue& val) + { + setValue(mLight->getDiffuseColour() + val); + } + void setCurrentStateAsBaseValue(void) + { + setAsBaseValue(mLight->getDiffuseColour()); + } + + }; + //----------------------------------------------------------------------- + class LightSpecularColourValue : public AnimableValue + { + protected: + Light* mLight; + public: + LightSpecularColourValue(Light* l) :AnimableValue(COLOUR) + { mLight = l; } + void setValue(const ColourValue& val) + { + mLight->setSpecularColour(val); + } + void applyDeltaValue(const ColourValue& val) + { + setValue(mLight->getSpecularColour() + val); + } + void setCurrentStateAsBaseValue(void) + { + setAsBaseValue(mLight->getSpecularColour()); + } + + }; + //----------------------------------------------------------------------- + class LightAttenuationValue : public AnimableValue + { + protected: + Light* mLight; + public: + LightAttenuationValue(Light* l) :AnimableValue(VECTOR4) + { mLight = l; } + void setValue(const Vector4& val) + { + mLight->setAttenuation(val.x, val.y, val.z, val.w); + } + void applyDeltaValue(const Vector4& val) + { + setValue(mLight->getAs4DVector() + val); + } + void setCurrentStateAsBaseValue(void) + { + setAsBaseValue(mLight->getAs4DVector()); + } + + }; + //----------------------------------------------------------------------- + class LightSpotlightInnerValue : public AnimableValue + { + protected: + Light* mLight; + public: + LightSpotlightInnerValue(Light* l) :AnimableValue(REAL) + { mLight = l; } + void setValue(Real val) + { + mLight->setSpotlightInnerAngle(Radian(val)); + } + void applyDeltaValue(Real val) + { + setValue(mLight->getSpotlightInnerAngle().valueRadians() + val); + } + void setCurrentStateAsBaseValue(void) + { + setAsBaseValue(mLight->getSpotlightInnerAngle().valueRadians()); + } + + }; + //----------------------------------------------------------------------- + class LightSpotlightOuterValue : public AnimableValue + { + protected: + Light* mLight; + public: + LightSpotlightOuterValue(Light* l) :AnimableValue(REAL) + { mLight = l; } + void setValue(Real val) + { + mLight->setSpotlightOuterAngle(Radian(val)); + } + void applyDeltaValue(Real val) + { + setValue(mLight->getSpotlightOuterAngle().valueRadians() + val); + } + void setCurrentStateAsBaseValue(void) + { + setAsBaseValue(mLight->getSpotlightOuterAngle().valueRadians()); + } + + }; + //----------------------------------------------------------------------- + class LightSpotlightFalloffValue : public AnimableValue + { + protected: + Light* mLight; + public: + LightSpotlightFalloffValue(Light* l) :AnimableValue(REAL) + { mLight = l; } + void setValue(Real val) + { + mLight->setSpotlightFalloff(val); + } + void applyDeltaValue(Real val) + { + setValue(mLight->getSpotlightFalloff() + val); + } + void setCurrentStateAsBaseValue(void) + { + setAsBaseValue(mLight->getSpotlightFalloff()); + } + + }; + //----------------------------------------------------------------------- + AnimableValuePtr Light::createAnimableValue(const String& valueName) + { + if (valueName == "diffuseColour") + { + return AnimableValuePtr( + OGRE_NEW LightDiffuseColourValue(this)); + } + else if(valueName == "specularColour") + { + return AnimableValuePtr( + OGRE_NEW LightSpecularColourValue(this)); + } + else if (valueName == "attenuation") + { + return AnimableValuePtr( + OGRE_NEW LightAttenuationValue(this)); + } + else if (valueName == "spotlightInner") + { + return AnimableValuePtr( + OGRE_NEW LightSpotlightInnerValue(this)); + } + else if (valueName == "spotlightOuter") + { + return AnimableValuePtr( + OGRE_NEW LightSpotlightOuterValue(this)); + } + else if (valueName == "spotlightFalloff") + { + return AnimableValuePtr( + OGRE_NEW LightSpotlightFalloffValue(this)); + } + else + { + return MovableObject::createAnimableValue(valueName); + } + } + //----------------------------------------------------------------------- + void Light::setCustomShadowCameraSetup(const ShadowCameraSetupPtr& customShadowSetup) + { + mCustomShadowCameraSetup = customShadowSetup; + } + //----------------------------------------------------------------------- + void Light::resetCustomShadowCameraSetup() + { + mCustomShadowCameraSetup.setNull(); + } + //----------------------------------------------------------------------- + const ShadowCameraSetupPtr& Light::getCustomShadowCameraSetup() const + { + return mCustomShadowCameraSetup; + } + //----------------------------------------------------------------------- + void Light::setShadowFarDistance(Real distance) + { + mOwnShadowFarDist = true; + mShadowFarDist = distance; + mShadowFarDistSquared = distance * distance; + } + //----------------------------------------------------------------------- + void Light::resetShadowFarDistance(void) + { + mOwnShadowFarDist = false; + } + //----------------------------------------------------------------------- + Real Light::getShadowFarDistance(void) const + { + if (mOwnShadowFarDist) + return mShadowFarDist; + else + return mManager->getShadowFarDistance (); + } + //----------------------------------------------------------------------- + Real Light::getShadowFarDistanceSquared(void) const + { + if (mOwnShadowFarDist) + return mShadowFarDistSquared; + else + return mManager->getShadowFarDistanceSquared (); + } + //--------------------------------------------------------------------- + void Light::_setCameraRelative(Camera* cam) + { + mCameraToBeRelativeTo = cam; + mDerivedCamRelativeDirty = true; + } + //--------------------------------------------------------------------- + Real Light::_deriveShadowNearClipDistance(const Camera* maincam) const + { + if (mShadowNearClipDist > 0) + return mShadowNearClipDist; + else + return maincam->getNearClipDistance(); + } + //--------------------------------------------------------------------- + Real Light::_deriveShadowFarClipDistance(const Camera* maincam) const + { + if (mShadowFarClipDist >= 0) + return mShadowFarClipDist; + else + { + if (mLightType == LT_DIRECTIONAL) + return 0; + else + return mRange; + } + } + //----------------------------------------------------------------------- + void Light::setCustomParameter(uint16 index, const Ogre::Vector4 &value) + { + mCustomParameters[index] = value; + } + //----------------------------------------------------------------------- + const Vector4 &Light::getCustomParameter(uint16 index) const + { + CustomParameterMap::const_iterator i = mCustomParameters.find(index); if (i != mCustomParameters.end()) { return i->second; @@ -835,171 +835,171 @@ namespace Ogre { "Parameter at the given index was not found.", "Light::getCustomParameter"); } - } - //----------------------------------------------------------------------- - void Light::_updateCustomGpuParameter(uint16 paramIndex, const GpuProgramParameters::AutoConstantEntry& constantEntry, GpuProgramParameters *params) const - { - CustomParameterMap::const_iterator i = mCustomParameters.find(paramIndex); + } + //----------------------------------------------------------------------- + void Light::_updateCustomGpuParameter(uint16 paramIndex, const GpuProgramParameters::AutoConstantEntry& constantEntry, GpuProgramParameters *params) const + { + CustomParameterMap::const_iterator i = mCustomParameters.find(paramIndex); if (i != mCustomParameters.end()) { params->_writeRawConstant(constantEntry.physicalIndex, i->second, - constantEntry.elementCount); - } - } - //----------------------------------------------------------------------- - bool Light::isInLightRange(const Ogre::Sphere& container) const - { - bool isIntersect = true; - //directional light always intersects (check only spotlight and point) - if (mLightType != LT_DIRECTIONAL) - { - //Check that the sphere is within the sphere of the light - isIntersect = container.intersects(Sphere(mDerivedPosition, mRange)); - //If this is a spotlight, check that the sphere is within the cone of the spot light - if ((isIntersect) && (mLightType == LT_SPOTLIGHT)) - { - //check first check of the sphere surrounds the position of the light - //(this covers the case where the center of the sphere is behind the position of the light - // something which is not covered in the next test). - isIntersect = container.intersects(mDerivedPosition); - //if not test cones - if (!isIntersect) - { - //Calculate the cone that exists between the sphere and the center position of the light - Ogre::Vector3 lightSphereConeDirection = container.getCenter() - mDerivedPosition; - Ogre::Radian halfLightSphereConeAngle = Math::ASin(container.getRadius() / lightSphereConeDirection.length()); - - //Check that the light cone and the light-position-to-sphere cone intersect) - Radian angleBetweenConeDirections = lightSphereConeDirection.angleBetween(mDerivedDirection); - isIntersect = angleBetweenConeDirections <= halfLightSphereConeAngle + mSpotOuter * 0.5; - } - } - } - return isIntersect; - } - - //----------------------------------------------------------------------- - bool Light::isInLightRange(const Ogre::AxisAlignedBox& container) const - { - bool isIntersect = true; - //Check the 2 simple / obvious situations. Light is directional or light source is inside the container - if ((mLightType != LT_DIRECTIONAL) && (container.intersects(mDerivedPosition) == false)) - { - //Check that the container is within the sphere of the light - isIntersect = Math::intersects(Sphere(mDerivedPosition, mRange),container); - //If this is a spotlight, do a more specific check - if ((isIntersect) && (mLightType == LT_SPOTLIGHT) && (mSpotOuter.valueRadians() <= Math::PI)) - { - //Create a rough bounding box around the light and check if - Quaternion localToWorld = Vector3::NEGATIVE_UNIT_Z.getRotationTo(mDerivedDirection); - - Real boxOffset = Math::Sin(mSpotOuter * 0.5) * mRange; - AxisAlignedBox lightBoxBound; - lightBoxBound.merge(Vector3::ZERO); - lightBoxBound.merge(localToWorld * Vector3(boxOffset, boxOffset, -mRange)); - lightBoxBound.merge(localToWorld * Vector3(-boxOffset, boxOffset, -mRange)); - lightBoxBound.merge(localToWorld * Vector3(-boxOffset, -boxOffset, -mRange)); - lightBoxBound.merge(localToWorld * Vector3(boxOffset, -boxOffset, -mRange)); - lightBoxBound.setMaximum(lightBoxBound.getMaximum() + mDerivedPosition); - lightBoxBound.setMinimum(lightBoxBound.getMinimum() + mDerivedPosition); - isIntersect = lightBoxBound.intersects(container); - - //If the bounding box check succeeded do one more test - if (isIntersect) - { - //Check intersection again with the bounding sphere of the container - //Helpful for when the light is at an angle near one of the vertexes of the bounding box - isIntersect = isInLightRange(Sphere(container.getCenter(), - container.getHalfSize().length())); - } - } - } - return isIntersect; - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - String LightFactory::FACTORY_TYPE_NAME = "Light"; - //----------------------------------------------------------------------- - const String& LightFactory::getType(void) const - { - return FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------- - MovableObject* LightFactory::createInstanceImpl( const String& name, - const NameValuePairList* params) - { - - Light* light = OGRE_NEW Light(name); + constantEntry.elementCount); + } + } + //----------------------------------------------------------------------- + bool Light::isInLightRange(const Ogre::Sphere& container) const + { + bool isIntersect = true; + //directional light always intersects (check only spotlight and point) + if (mLightType != LT_DIRECTIONAL) + { + //Check that the sphere is within the sphere of the light + isIntersect = container.intersects(Sphere(mDerivedPosition, mRange)); + //If this is a spotlight, check that the sphere is within the cone of the spot light + if ((isIntersect) && (mLightType == LT_SPOTLIGHT)) + { + //check first check of the sphere surrounds the position of the light + //(this covers the case where the center of the sphere is behind the position of the light + // something which is not covered in the next test). + isIntersect = container.intersects(mDerivedPosition); + //if not test cones + if (!isIntersect) + { + //Calculate the cone that exists between the sphere and the center position of the light + Ogre::Vector3 lightSphereConeDirection = container.getCenter() - mDerivedPosition; + Ogre::Radian halfLightSphereConeAngle = Math::ASin(container.getRadius() / lightSphereConeDirection.length()); + + //Check that the light cone and the light-position-to-sphere cone intersect) + Radian angleBetweenConeDirections = lightSphereConeDirection.angleBetween(mDerivedDirection); + isIntersect = angleBetweenConeDirections <= halfLightSphereConeAngle + mSpotOuter * 0.5; + } + } + } + return isIntersect; + } + + //----------------------------------------------------------------------- + bool Light::isInLightRange(const Ogre::AxisAlignedBox& container) const + { + bool isIntersect = true; + //Check the 2 simple / obvious situations. Light is directional or light source is inside the container + if ((mLightType != LT_DIRECTIONAL) && (container.intersects(mDerivedPosition) == false)) + { + //Check that the container is within the sphere of the light + isIntersect = Math::intersects(Sphere(mDerivedPosition, mRange),container); + //If this is a spotlight, do a more specific check + if ((isIntersect) && (mLightType == LT_SPOTLIGHT) && (mSpotOuter.valueRadians() <= Math::PI)) + { + //Create a rough bounding box around the light and check if + Quaternion localToWorld = Vector3::NEGATIVE_UNIT_Z.getRotationTo(mDerivedDirection); + + Real boxOffset = Math::Sin(mSpotOuter * 0.5) * mRange; + AxisAlignedBox lightBoxBound; + lightBoxBound.merge(Vector3::ZERO); + lightBoxBound.merge(localToWorld * Vector3(boxOffset, boxOffset, -mRange)); + lightBoxBound.merge(localToWorld * Vector3(-boxOffset, boxOffset, -mRange)); + lightBoxBound.merge(localToWorld * Vector3(-boxOffset, -boxOffset, -mRange)); + lightBoxBound.merge(localToWorld * Vector3(boxOffset, -boxOffset, -mRange)); + lightBoxBound.setMaximum(lightBoxBound.getMaximum() + mDerivedPosition); + lightBoxBound.setMinimum(lightBoxBound.getMinimum() + mDerivedPosition); + isIntersect = lightBoxBound.intersects(container); + + //If the bounding box check succeeded do one more test + if (isIntersect) + { + //Check intersection again with the bounding sphere of the container + //Helpful for when the light is at an angle near one of the vertexes of the bounding box + isIntersect = isInLightRange(Sphere(container.getCenter(), + container.getHalfSize().length())); + } + } + } + return isIntersect; + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + String LightFactory::FACTORY_TYPE_NAME = "Light"; + //----------------------------------------------------------------------- + const String& LightFactory::getType(void) const + { + return FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------- + MovableObject* LightFactory::createInstanceImpl( const String& name, + const NameValuePairList* params) + { + + Light* light = OGRE_NEW Light(name); - if(params) - { - NameValuePairList::const_iterator ni; - - // Setting the light type first before any property specific to a certain light type - if ((ni = params->find("type")) != params->end()) - { - if (ni->second == "point") - light->setType(Light::LT_POINT); - else if (ni->second == "directional") - light->setType(Light::LT_DIRECTIONAL); - else if (ni->second == "spotlight") - light->setType(Light::LT_SPOTLIGHT); - else - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid light type '" + ni->second + "'.", - "LightFactory::createInstance"); - } - - // Common properties - if ((ni = params->find("position")) != params->end()) - light->setPosition(StringConverter::parseVector3(ni->second)); - - if ((ni = params->find("direction")) != params->end()) - light->setDirection(StringConverter::parseVector3(ni->second)); - - if ((ni = params->find("diffuseColour")) != params->end()) - light->setDiffuseColour(StringConverter::parseColourValue(ni->second)); - - if ((ni = params->find("specularColour")) != params->end()) - light->setSpecularColour(StringConverter::parseColourValue(ni->second)); - - if ((ni = params->find("attenuation")) != params->end()) - { - Vector4 attenuation = StringConverter::parseVector4(ni->second); - light->setAttenuation(attenuation.x, attenuation.y, attenuation.z, attenuation.w); - } - - if ((ni = params->find("castShadows")) != params->end()) - light->setCastShadows(StringConverter::parseBool(ni->second)); - - if ((ni = params->find("visible")) != params->end()) - light->setVisible(StringConverter::parseBool(ni->second)); - - if ((ni = params->find("powerScale")) != params->end()) - light->setPowerScale(StringConverter::parseReal(ni->second)); - - if ((ni = params->find("shadowFarDistance")) != params->end()) - light->setShadowFarDistance(StringConverter::parseReal(ni->second)); - - - // Spotlight properties - if ((ni = params->find("spotlightInner")) != params->end()) - light->setSpotlightInnerAngle(StringConverter::parseAngle(ni->second)); - - if ((ni = params->find("spotlightOuter")) != params->end()) - light->setSpotlightOuterAngle(StringConverter::parseAngle(ni->second)); - - if ((ni = params->find("spotlightFalloff")) != params->end()) - light->setSpotlightFalloff(StringConverter::parseReal(ni->second)); - } - - return light; - } - //----------------------------------------------------------------------- - void LightFactory::destroyInstance( MovableObject* obj) - { - OGRE_DELETE obj; - } + if(params) + { + NameValuePairList::const_iterator ni; + + // Setting the light type first before any property specific to a certain light type + if ((ni = params->find("type")) != params->end()) + { + if (ni->second == "point") + light->setType(Light::LT_POINT); + else if (ni->second == "directional") + light->setType(Light::LT_DIRECTIONAL); + else if (ni->second == "spotlight") + light->setType(Light::LT_SPOTLIGHT); + else + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid light type '" + ni->second + "'.", + "LightFactory::createInstance"); + } + + // Common properties + if ((ni = params->find("position")) != params->end()) + light->setPosition(StringConverter::parseVector3(ni->second)); + + if ((ni = params->find("direction")) != params->end()) + light->setDirection(StringConverter::parseVector3(ni->second)); + + if ((ni = params->find("diffuseColour")) != params->end()) + light->setDiffuseColour(StringConverter::parseColourValue(ni->second)); + + if ((ni = params->find("specularColour")) != params->end()) + light->setSpecularColour(StringConverter::parseColourValue(ni->second)); + + if ((ni = params->find("attenuation")) != params->end()) + { + Vector4 attenuation = StringConverter::parseVector4(ni->second); + light->setAttenuation(attenuation.x, attenuation.y, attenuation.z, attenuation.w); + } + + if ((ni = params->find("castShadows")) != params->end()) + light->setCastShadows(StringConverter::parseBool(ni->second)); + + if ((ni = params->find("visible")) != params->end()) + light->setVisible(StringConverter::parseBool(ni->second)); + + if ((ni = params->find("powerScale")) != params->end()) + light->setPowerScale(StringConverter::parseReal(ni->second)); + + if ((ni = params->find("shadowFarDistance")) != params->end()) + light->setShadowFarDistance(StringConverter::parseReal(ni->second)); + + + // Spotlight properties + if ((ni = params->find("spotlightInner")) != params->end()) + light->setSpotlightInnerAngle(StringConverter::parseAngle(ni->second)); + + if ((ni = params->find("spotlightOuter")) != params->end()) + light->setSpotlightOuterAngle(StringConverter::parseAngle(ni->second)); + + if ((ni = params->find("spotlightFalloff")) != params->end()) + light->setSpotlightFalloff(StringConverter::parseReal(ni->second)); + } + + return light; + } + //----------------------------------------------------------------------- + void LightFactory::destroyInstance( MovableObject* obj) + { + OGRE_DELETE obj; + } diff --git a/OgreMain/src/OgreLodStrategy.cpp b/OgreMain/src/OgreLodStrategy.cpp index f8dea8f762e..af37d8f634b 100644 --- a/OgreMain/src/OgreLodStrategy.cpp +++ b/OgreMain/src/OgreLodStrategy.cpp @@ -126,7 +126,7 @@ namespace Ogre { { if (i->value > value) { - return index ? index - 1 : 0; + return index ? index - 1 : 0; } } @@ -143,7 +143,7 @@ namespace Ogre { { if (i->value < value) { - return index ? index - 1 : 0; + return index ? index - 1 : 0; } } @@ -160,7 +160,7 @@ namespace Ogre { { if (*i > value) { - return index ? index - 1 : 0; + return index ? index - 1 : 0; } } @@ -177,7 +177,7 @@ namespace Ogre { { if (*i < value) { - return index ? index - 1 : 0; + return index ? index - 1 : 0; } } diff --git a/OgreMain/src/OgreLodStrategyManager.cpp b/OgreMain/src/OgreLodStrategyManager.cpp index 8ad2775ff36..8b9d8a424f7 100644 --- a/OgreMain/src/OgreLodStrategyManager.cpp +++ b/OgreMain/src/OgreLodStrategyManager.cpp @@ -101,22 +101,22 @@ namespace Ogre { { // Get beginning iterator for (StrategyMap::iterator it = mStrategies.begin(); it != mStrategies.end(); ++it) - { - OGRE_DELETE it->second; - } - mStrategies.clear(); + { + OGRE_DELETE it->second; + } + mStrategies.clear(); } //----------------------------------------------------------------------- LodStrategy *LodStrategyManager::getStrategy(const String& name) { // If name is "default", return the default strategy instead of performing a lookup if (name == "default") { - return getDefaultStrategy(); - } else if (name == "Distance") { - return getStrategy("distance_box"); // Backward compatibility for loading old meshes. - } else if (name == "PixelCount") { - return getStrategy("pixel_count"); // Backward compatibility for loading old meshes. - } + return getDefaultStrategy(); + } else if (name == "Distance") { + return getStrategy("distance_box"); // Backward compatibility for loading old meshes. + } else if (name == "PixelCount") { + return getStrategy("pixel_count"); // Backward compatibility for loading old meshes. + } // Find strategy with specified name StrategyMap::iterator it = mStrategies.find(name); diff --git a/OgreMain/src/OgreLog.cpp b/OgreMain/src/OgreLog.cpp index 96e6d4d7c96..3c86ae7afc2 100644 --- a/OgreMain/src/OgreLog.cpp +++ b/OgreMain/src/OgreLog.cpp @@ -47,19 +47,19 @@ namespace Ogre mLogLevel(LL_NORMAL), mDebugOut(debuggerOuput), mSuppressFile(suppressFile), mTimeStamp(true), mLogName(name) { - if (!mSuppressFile) - { - mLog.open(name.c_str()); - } + if (!mSuppressFile) + { + mLog.open(name.c_str()); + } } //----------------------------------------------------------------------- Log::~Log() { OGRE_LOCK_AUTO_MUTEX; - if (!mSuppressFile) - { - mLog.close(); - } + if (!mSuppressFile) + { + mLog.close(); + } } //----------------------------------------------------------------------- void Log::logMessage( const String& message, LogMessageLevel lml, bool maskDebug ) @@ -67,12 +67,12 @@ namespace Ogre OGRE_LOCK_AUTO_MUTEX; if ((mLogLevel + lml) >= OGRE_LOG_THRESHOLD) { - bool skipThisMessage = false; + bool skipThisMessage = false; for( mtLogListener::iterator i = mListeners.begin(); i != mListeners.end(); ++i ) (*i)->messageLogged( message, lml, maskDebug, mLogName, skipThisMessage); - - if (!skipThisMessage) - { + + if (!skipThisMessage) + { #if OGRE_PLATFORM == OGRE_PLATFORM_NACL if(mInstance != NULL) { @@ -81,32 +81,32 @@ namespace Ogre #else if (mDebugOut && !maskDebug) { - if (lml == LML_CRITICAL) - std::cerr << message << std::endl; - else - std::cout << message << std::endl; - } + if (lml == LML_CRITICAL) + std::cerr << message << std::endl; + else + std::cout << message << std::endl; + } #endif - // Write time into log - if (!mSuppressFile) - { - if (mTimeStamp) - { - struct tm *pTime; - time_t ctTime; time(&ctTime); - pTime = localtime( &ctTime ); - mLog << std::setw(2) << std::setfill('0') << pTime->tm_hour - << ":" << std::setw(2) << std::setfill('0') << pTime->tm_min - << ":" << std::setw(2) << std::setfill('0') << pTime->tm_sec - << ": "; - } - mLog << message << std::endl; + // Write time into log + if (!mSuppressFile) + { + if (mTimeStamp) + { + struct tm *pTime; + time_t ctTime; time(&ctTime); + pTime = localtime( &ctTime ); + mLog << std::setw(2) << std::setfill('0') << pTime->tm_hour + << ":" << std::setw(2) << std::setfill('0') << pTime->tm_min + << ":" << std::setw(2) << std::setfill('0') << pTime->tm_sec + << ": "; + } + mLog << message << std::endl; - // Flush stcmdream to ensure it is written (incase of a crash, we need log to be up to date) - mLog.flush(); - } - } + // Flush stcmdream to ensure it is written (incase of a crash, we need log to be up to date) + mLog.flush(); + } + } } } @@ -124,7 +124,7 @@ namespace Ogre mDebugOut = debugOutput; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void Log::setLogDetail(LoggingLevel ll) { OGRE_LOCK_AUTO_MUTEX; @@ -144,10 +144,10 @@ namespace Ogre OGRE_LOCK_AUTO_MUTEX; mListeners.erase(std::find(mListeners.begin(), mListeners.end(), listener)); } - //--------------------------------------------------------------------- - Log::Stream Log::stream(LogMessageLevel lml, bool maskDebug) - { - return Stream(this, lml, maskDebug); + //--------------------------------------------------------------------- + Log::Stream Log::stream(LogMessageLevel lml, bool maskDebug) + { + return Stream(this, lml, maskDebug); - } + } } diff --git a/OgreMain/src/OgreLogManager.cpp b/OgreMain/src/OgreLogManager.cpp index ff5e072611f..39f5a3ab5e2 100644 --- a/OgreMain/src/OgreLogManager.cpp +++ b/OgreMain/src/OgreLogManager.cpp @@ -60,7 +60,7 @@ namespace Ogre { } //----------------------------------------------------------------------- Log* LogManager::createLog( const String& name, bool defaultLog, bool debuggerOutput, - bool suppressFileOutput) + bool suppressFileOutput) { OGRE_LOCK_AUTO_MUTEX; @@ -101,60 +101,60 @@ namespace Ogre { } - //----------------------------------------------------------------------- - void LogManager::destroyLog(const String& name) - { - LogList::iterator i = mLogs.find(name); - if (i != mLogs.end()) - { - if (mDefaultLog == i->second) - { - mDefaultLog = 0; - } - OGRE_DELETE i->second; - mLogs.erase(i); - } + //----------------------------------------------------------------------- + void LogManager::destroyLog(const String& name) + { + LogList::iterator i = mLogs.find(name); + if (i != mLogs.end()) + { + if (mDefaultLog == i->second) + { + mDefaultLog = 0; + } + OGRE_DELETE i->second; + mLogs.erase(i); + } - // Set another default log if this one removed - if (!mDefaultLog && !mLogs.empty()) - { - mDefaultLog = mLogs.begin()->second; - } - } - //----------------------------------------------------------------------- - void LogManager::destroyLog(Log* log) - { + // Set another default log if this one removed + if (!mDefaultLog && !mLogs.empty()) + { + mDefaultLog = mLogs.begin()->second; + } + } + //----------------------------------------------------------------------- + void LogManager::destroyLog(Log* log) + { if(!log) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot destroy a null log.", "LogManager::destroyLog"); destroyLog(log->getName()); - } + } //----------------------------------------------------------------------- void LogManager::logMessage( const String& message, LogMessageLevel lml, bool maskDebug) { OGRE_LOCK_AUTO_MUTEX; - if (mDefaultLog) - { - mDefaultLog->logMessage(message, lml, maskDebug); - } + if (mDefaultLog) + { + mDefaultLog->logMessage(message, lml, maskDebug); + } } //----------------------------------------------------------------------- void LogManager::setLogDetail(LoggingLevel ll) { OGRE_LOCK_AUTO_MUTEX; - if (mDefaultLog) - { - mDefaultLog->setLogDetail(ll); - } + if (mDefaultLog) + { + mDefaultLog->setLogDetail(ll); + } } - //--------------------------------------------------------------------- - Log::Stream LogManager::stream(LogMessageLevel lml, bool maskDebug) - { + //--------------------------------------------------------------------- + Log::Stream LogManager::stream(LogMessageLevel lml, bool maskDebug) + { OGRE_LOCK_AUTO_MUTEX; - if (mDefaultLog) - return mDefaultLog->stream(lml, maskDebug); - else - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Default log not found. ", "LogManager::stream"); + if (mDefaultLog) + return mDefaultLog->stream(lml, maskDebug); + else + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Default log not found. ", "LogManager::stream"); - } + } } diff --git a/OgreMain/src/OgreManualObject.cpp b/OgreMain/src/OgreManualObject.cpp index 384c4617457..f0699efbc84 100644 --- a/OgreMain/src/OgreManualObject.cpp +++ b/OgreMain/src/OgreManualObject.cpp @@ -45,580 +45,580 @@ namespace Ogre { #define TEMP_VERTEXSIZE_GUESS sizeof(float) * 12 #define TEMP_INITIAL_VERTEX_SIZE TEMP_VERTEXSIZE_GUESS * TEMP_INITIAL_SIZE #define TEMP_INITIAL_INDEX_SIZE sizeof(uint32) * TEMP_INITIAL_SIZE - //----------------------------------------------------------------------------- - ManualObject::ManualObject(const String& name) - : MovableObject(name), - mDynamic(false), mCurrentSection(0), mCurrentUpdating(false), mFirstVertex(true), - mTempVertexPending(false), - mTempVertexBuffer(0), mTempVertexSize(TEMP_INITIAL_VERTEX_SIZE), - mTempIndexBuffer(0), mTempIndexSize(TEMP_INITIAL_INDEX_SIZE), - mDeclSize(0), mEstVertexCount(0), mEstIndexCount(0), mTexCoordIndex(0), - mRadius(0), mAnyIndexed(false), mEdgeList(0), - mUseIdentityProjection(false), mUseIdentityView(false), mKeepDeclarationOrder(false) - { - } - //----------------------------------------------------------------------------- - ManualObject::~ManualObject() - { - clear(); - } - //----------------------------------------------------------------------------- - void ManualObject::clear(void) - { - resetTempAreas(); - for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) - { - OGRE_DELETE *i; - } - mSectionList.clear(); - mRadius = 0; - mAABB.setNull(); - OGRE_DELETE mEdgeList; - mEdgeList = 0; - mAnyIndexed = false; - for (ShadowRenderableList::iterator s = mShadowRenderables.begin(); - s != mShadowRenderables.end(); ++s) - { - OGRE_DELETE *s; - } - mShadowRenderables.clear(); - - - } - //----------------------------------------------------------------------------- - void ManualObject::resetTempAreas(void) - { - OGRE_FREE(mTempVertexBuffer, MEMCATEGORY_GEOMETRY); - OGRE_FREE(mTempIndexBuffer, MEMCATEGORY_GEOMETRY); - mTempVertexBuffer = 0; - mTempIndexBuffer = 0; - mTempVertexSize = TEMP_INITIAL_VERTEX_SIZE; - mTempIndexSize = TEMP_INITIAL_INDEX_SIZE; - } - //----------------------------------------------------------------------------- - void ManualObject::resizeTempVertexBufferIfNeeded(size_t numVerts) - { - // Calculate byte size - // Use decl if we know it by now, otherwise default size to pos/norm/texcoord*2 - size_t newSize; - if (!mFirstVertex) - { - newSize = mDeclSize * numVerts; - } - else - { - // estimate - size checks will deal for subsequent verts - newSize = TEMP_VERTEXSIZE_GUESS * numVerts; - } - if (newSize > mTempVertexSize || !mTempVertexBuffer) - { - if (!mTempVertexBuffer) - { - // init - newSize = mTempVertexSize; - } - else - { - // increase to at least double current - newSize = std::max(newSize, mTempVertexSize*2); - } - // copy old data - char* tmp = mTempVertexBuffer; - mTempVertexBuffer = OGRE_ALLOC_T(char, newSize, MEMCATEGORY_GEOMETRY); - if (tmp) - { - memcpy(mTempVertexBuffer, tmp, mTempVertexSize); - // delete old buffer - OGRE_FREE(tmp, MEMCATEGORY_GEOMETRY); - } - mTempVertexSize = newSize; - } - } - //----------------------------------------------------------------------------- - void ManualObject::resizeTempIndexBufferIfNeeded(size_t numInds) - { - size_t newSize = numInds * sizeof(uint32); - if (newSize > mTempIndexSize || !mTempIndexBuffer) - { - if (!mTempIndexBuffer) - { - // init - newSize = mTempIndexSize; - } - else - { - // increase to at least double current - newSize = std::max(newSize, mTempIndexSize*2); - } - numInds = newSize / sizeof(uint32); - uint32* tmp = mTempIndexBuffer; - mTempIndexBuffer = OGRE_ALLOC_T(uint32, numInds, MEMCATEGORY_GEOMETRY); - if (tmp) - { - memcpy(mTempIndexBuffer, tmp, mTempIndexSize); - OGRE_FREE(tmp, MEMCATEGORY_GEOMETRY); - } - mTempIndexSize = newSize; - } - - } - //----------------------------------------------------------------------------- - void ManualObject::estimateVertexCount(size_t vcount) - { - resizeTempVertexBufferIfNeeded(vcount); - mEstVertexCount = vcount; - } - //----------------------------------------------------------------------------- - void ManualObject::estimateIndexCount(size_t icount) - { - resizeTempIndexBufferIfNeeded(icount); - mEstIndexCount = icount; - } - //----------------------------------------------------------------------------- - void ManualObject::begin(const String& materialName, - RenderOperation::OperationType opType, const String & groupName) - { - if (mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You cannot call begin() again until after you call end()", - "ManualObject::begin"); - } + //----------------------------------------------------------------------------- + ManualObject::ManualObject(const String& name) + : MovableObject(name), + mDynamic(false), mCurrentSection(0), mCurrentUpdating(false), mFirstVertex(true), + mTempVertexPending(false), + mTempVertexBuffer(0), mTempVertexSize(TEMP_INITIAL_VERTEX_SIZE), + mTempIndexBuffer(0), mTempIndexSize(TEMP_INITIAL_INDEX_SIZE), + mDeclSize(0), mEstVertexCount(0), mEstIndexCount(0), mTexCoordIndex(0), + mRadius(0), mAnyIndexed(false), mEdgeList(0), + mUseIdentityProjection(false), mUseIdentityView(false), mKeepDeclarationOrder(false) + { + } + //----------------------------------------------------------------------------- + ManualObject::~ManualObject() + { + clear(); + } + //----------------------------------------------------------------------------- + void ManualObject::clear(void) + { + resetTempAreas(); + for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) + { + OGRE_DELETE *i; + } + mSectionList.clear(); + mRadius = 0; + mAABB.setNull(); + OGRE_DELETE mEdgeList; + mEdgeList = 0; + mAnyIndexed = false; + for (ShadowRenderableList::iterator s = mShadowRenderables.begin(); + s != mShadowRenderables.end(); ++s) + { + OGRE_DELETE *s; + } + mShadowRenderables.clear(); + + + } + //----------------------------------------------------------------------------- + void ManualObject::resetTempAreas(void) + { + OGRE_FREE(mTempVertexBuffer, MEMCATEGORY_GEOMETRY); + OGRE_FREE(mTempIndexBuffer, MEMCATEGORY_GEOMETRY); + mTempVertexBuffer = 0; + mTempIndexBuffer = 0; + mTempVertexSize = TEMP_INITIAL_VERTEX_SIZE; + mTempIndexSize = TEMP_INITIAL_INDEX_SIZE; + } + //----------------------------------------------------------------------------- + void ManualObject::resizeTempVertexBufferIfNeeded(size_t numVerts) + { + // Calculate byte size + // Use decl if we know it by now, otherwise default size to pos/norm/texcoord*2 + size_t newSize; + if (!mFirstVertex) + { + newSize = mDeclSize * numVerts; + } + else + { + // estimate - size checks will deal for subsequent verts + newSize = TEMP_VERTEXSIZE_GUESS * numVerts; + } + if (newSize > mTempVertexSize || !mTempVertexBuffer) + { + if (!mTempVertexBuffer) + { + // init + newSize = mTempVertexSize; + } + else + { + // increase to at least double current + newSize = std::max(newSize, mTempVertexSize*2); + } + // copy old data + char* tmp = mTempVertexBuffer; + mTempVertexBuffer = OGRE_ALLOC_T(char, newSize, MEMCATEGORY_GEOMETRY); + if (tmp) + { + memcpy(mTempVertexBuffer, tmp, mTempVertexSize); + // delete old buffer + OGRE_FREE(tmp, MEMCATEGORY_GEOMETRY); + } + mTempVertexSize = newSize; + } + } + //----------------------------------------------------------------------------- + void ManualObject::resizeTempIndexBufferIfNeeded(size_t numInds) + { + size_t newSize = numInds * sizeof(uint32); + if (newSize > mTempIndexSize || !mTempIndexBuffer) + { + if (!mTempIndexBuffer) + { + // init + newSize = mTempIndexSize; + } + else + { + // increase to at least double current + newSize = std::max(newSize, mTempIndexSize*2); + } + numInds = newSize / sizeof(uint32); + uint32* tmp = mTempIndexBuffer; + mTempIndexBuffer = OGRE_ALLOC_T(uint32, numInds, MEMCATEGORY_GEOMETRY); + if (tmp) + { + memcpy(mTempIndexBuffer, tmp, mTempIndexSize); + OGRE_FREE(tmp, MEMCATEGORY_GEOMETRY); + } + mTempIndexSize = newSize; + } + + } + //----------------------------------------------------------------------------- + void ManualObject::estimateVertexCount(size_t vcount) + { + resizeTempVertexBufferIfNeeded(vcount); + mEstVertexCount = vcount; + } + //----------------------------------------------------------------------------- + void ManualObject::estimateIndexCount(size_t icount) + { + resizeTempIndexBufferIfNeeded(icount); + mEstIndexCount = icount; + } + //----------------------------------------------------------------------------- + void ManualObject::begin(const String& materialName, + RenderOperation::OperationType opType, const String & groupName) + { + if (mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You cannot call begin() again until after you call end()", + "ManualObject::begin"); + } // Check that a valid material was provided MaterialPtr material = MaterialManager::getSingleton().getByName(materialName, groupName); - if( material.isNull() ) - { - LogManager::getSingleton().logMessage("Can't assign material " + materialName + + if( material.isNull() ) + { + LogManager::getSingleton().logMessage("Can't assign material " + materialName + " to the ManualObject " + mName + " because this " "Material does not exist. Have you forgotten to define it in a " ".material script?", LML_CRITICAL); material = MaterialManager::getSingleton().getByName("BaseWhite"); - if (material.isNull()) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Can't assign default material " + if (material.isNull()) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Can't assign default material " "to the ManualObject " + mName + ". Did " "you forget to call MaterialManager::initialise()?", "ManualObject::begin"); - } - } - - mCurrentSection = OGRE_NEW ManualObjectSection(this, materialName, opType, groupName); - mCurrentUpdating = false; - mCurrentSection->setUseIdentityProjection(mUseIdentityProjection); - mCurrentSection->setUseIdentityView(mUseIdentityView); - mSectionList.push_back(mCurrentSection); - mFirstVertex = true; - mDeclSize = 0; - mTexCoordIndex = 0; - } - //----------------------------------------------------------------------------- - void ManualObject::beginUpdate(size_t sectionIndex) - { - if (mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You cannot call begin() again until after you call end()", - "ManualObject::beginUpdate"); - } - if (sectionIndex >= mSectionList.size()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid section index - out of range.", - "ManualObject::beginUpdate"); - } - mCurrentSection = mSectionList[sectionIndex]; - mCurrentUpdating = true; - mFirstVertex = true; - mTexCoordIndex = 0; - // reset vertex & index count - RenderOperation* rop = mCurrentSection->getRenderOperation(); - rop->vertexData->vertexCount = 0; - if (rop->indexData) - rop->indexData->indexCount = 0; - rop->useIndexes = false; - mDeclSize = rop->vertexData->vertexDeclaration->getVertexSize(0); - } - //----------------------------------------------------------------------------- - void ManualObject::position(const Vector3& pos) - { - position(pos.x, pos.y, pos.z); - } - //----------------------------------------------------------------------------- - void ManualObject::position(Real x, Real y, Real z) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must call begin() before this method", - "ManualObject::position"); - } - if (mTempVertexPending) - { - // bake current vertex - copyTempVertexToBuffer(); - mFirstVertex = false; - } - - if (mFirstVertex && !mCurrentUpdating) - { - // defining declaration - mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration - ->addElement(0, mDeclSize, VET_FLOAT3, VES_POSITION); - mDeclSize += VertexElement::getTypeSize(VET_FLOAT3); - } - - mTempVertex.position.x = x; - mTempVertex.position.y = y; - mTempVertex.position.z = z; - - // update bounds - mAABB.merge(mTempVertex.position); - mRadius = std::max(mRadius, mTempVertex.position.length()); - - // reset current texture coord - mTexCoordIndex = 0; - - mTempVertexPending = true; - } - //----------------------------------------------------------------------------- - void ManualObject::normal(const Vector3& norm) - { - normal(norm.x, norm.y, norm.z); - } - //----------------------------------------------------------------------------- - void ManualObject::normal(Real x, Real y, Real z) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must call begin() before this method", - "ManualObject::normal"); - } - if (mFirstVertex && !mCurrentUpdating) - { - // defining declaration - mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration - ->addElement(0, mDeclSize, VET_FLOAT3, VES_NORMAL); - mDeclSize += VertexElement::getTypeSize(VET_FLOAT3); - } - mTempVertex.normal.x = x; - mTempVertex.normal.y = y; - mTempVertex.normal.z = z; - } - - //----------------------------------------------------------------------------- - void ManualObject::tangent(const Vector3& tan) - { - tangent(tan.x, tan.y, tan.z); - } - //----------------------------------------------------------------------------- - void ManualObject::tangent(Real x, Real y, Real z) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must call begin() before this method", - "ManualObject::tangent"); - } - if (mFirstVertex && !mCurrentUpdating) - { - // defining declaration - mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration - ->addElement(0, mDeclSize, VET_FLOAT3, VES_TANGENT); - mDeclSize += VertexElement::getTypeSize(VET_FLOAT3); - } - mTempVertex.tangent.x = x; - mTempVertex.tangent.y = y; - mTempVertex.tangent.z = z; - } - - //----------------------------------------------------------------------------- - void ManualObject::textureCoord(Real u) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must call begin() before this method", - "ManualObject::textureCoord"); - } - if (mFirstVertex && !mCurrentUpdating) - { - // defining declaration - mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration - ->addElement(0, mDeclSize, VET_FLOAT1, VES_TEXTURE_COORDINATES, mTexCoordIndex); - mDeclSize += VertexElement::getTypeSize(VET_FLOAT1); - } - mTempVertex.texCoordDims[mTexCoordIndex] = 1; - mTempVertex.texCoord[mTexCoordIndex].x = u; - - ++mTexCoordIndex; - - } - //----------------------------------------------------------------------------- - void ManualObject::textureCoord(Real u, Real v) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must call begin() before this method", - "ManualObject::textureCoord"); - } - if (mFirstVertex && !mCurrentUpdating) - { - // defining declaration - mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration - ->addElement(0, mDeclSize, VET_FLOAT2, VES_TEXTURE_COORDINATES, mTexCoordIndex); - mDeclSize += VertexElement::getTypeSize(VET_FLOAT2); - } - mTempVertex.texCoordDims[mTexCoordIndex] = 2; - mTempVertex.texCoord[mTexCoordIndex].x = u; - mTempVertex.texCoord[mTexCoordIndex].y = v; - - ++mTexCoordIndex; - } - //----------------------------------------------------------------------------- - void ManualObject::textureCoord(Real u, Real v, Real w) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must call begin() before this method", - "ManualObject::textureCoord"); - } - if (mFirstVertex && !mCurrentUpdating) - { - // defining declaration - mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration - ->addElement(0, mDeclSize, VET_FLOAT3, VES_TEXTURE_COORDINATES, mTexCoordIndex); - mDeclSize += VertexElement::getTypeSize(VET_FLOAT3); - } - mTempVertex.texCoordDims[mTexCoordIndex] = 3; - mTempVertex.texCoord[mTexCoordIndex].x = u; - mTempVertex.texCoord[mTexCoordIndex].y = v; - mTempVertex.texCoord[mTexCoordIndex].z = w; - - ++mTexCoordIndex; - } - //----------------------------------------------------------------------------- - void ManualObject::textureCoord(Real x, Real y, Real z, Real w) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must call begin() before this method", - "ManualObject::textureCoord"); - } - if (mFirstVertex && !mCurrentUpdating) - { - // defining declaration - mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration - ->addElement(0, mDeclSize, VET_FLOAT4, VES_TEXTURE_COORDINATES, mTexCoordIndex); - mDeclSize += VertexElement::getTypeSize(VET_FLOAT4); - } - mTempVertex.texCoordDims[mTexCoordIndex] = 4; - mTempVertex.texCoord[mTexCoordIndex].x = x; - mTempVertex.texCoord[mTexCoordIndex].y = y; - mTempVertex.texCoord[mTexCoordIndex].z = z; - mTempVertex.texCoord[mTexCoordIndex].w = w; - - ++mTexCoordIndex; - } - //----------------------------------------------------------------------------- - void ManualObject::textureCoord(const Vector2& uv) - { - textureCoord(uv.x, uv.y); - } - //----------------------------------------------------------------------------- - void ManualObject::textureCoord(const Vector3& uvw) - { - textureCoord(uvw.x, uvw.y, uvw.z); - } - //--------------------------------------------------------------------- - void ManualObject::textureCoord(const Vector4& xyzw) - { - textureCoord(xyzw.x, xyzw.y, xyzw.z, xyzw.w); - } - //----------------------------------------------------------------------------- - void ManualObject::colour(const ColourValue& col) - { - colour(col.r, col.g, col.b, col.a); - } - //----------------------------------------------------------------------------- - void ManualObject::colour(Real r, Real g, Real b, Real a) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must call begin() before this method", - "ManualObject::colour"); - } - if (mFirstVertex && !mCurrentUpdating) - { - // defining declaration - mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration - ->addElement(0, mDeclSize, VET_COLOUR, VES_DIFFUSE); - mDeclSize += VertexElement::getTypeSize(VET_COLOUR); - } - mTempVertex.colour.r = r; - mTempVertex.colour.g = g; - mTempVertex.colour.b = b; - mTempVertex.colour.a = a; - - } - //----------------------------------------------------------------------------- - void ManualObject::index(uint32 idx) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must call begin() before this method", - "ManualObject::index"); - } - mAnyIndexed = true; - if (idx >= 65536) - mCurrentSection->set32BitIndices(true); - - // make sure we have index data - RenderOperation* rop = mCurrentSection->getRenderOperation(); - if (!rop->indexData) - { - rop->indexData = OGRE_NEW IndexData(); - rop->indexData->indexCount = 0; - } - rop->useIndexes = true; - resizeTempIndexBufferIfNeeded(++rop->indexData->indexCount); - - mTempIndexBuffer[rop->indexData->indexCount - 1] = idx; - } - //----------------------------------------------------------------------------- - void ManualObject::triangle(uint32 i1, uint32 i2, uint32 i3) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must call begin() before this method", - "ManualObject::index"); - } - if (mCurrentSection->getRenderOperation()->operationType != - RenderOperation::OT_TRIANGLE_LIST) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "This method is only valid on triangle lists", - "ManualObject::index"); - } - - index(i1); - index(i2); - index(i3); - } - //----------------------------------------------------------------------------- - void ManualObject::quad(uint32 i1, uint32 i2, uint32 i3, uint32 i4) - { - // first tri - triangle(i1, i2, i3); - // second tri - triangle(i3, i4, i1); - } - //----------------------------------------------------------------------------- - size_t ManualObject::getCurrentVertexCount() const - { - if (!mCurrentSection) - return 0; - - RenderOperation* rop = mCurrentSection->getRenderOperation(); - - // There's an unfinished vertex being defined, so include it in count - if (mTempVertexPending) - return rop->vertexData->vertexCount + 1; - else - return rop->vertexData->vertexCount; - - } - //----------------------------------------------------------------------------- - size_t ManualObject::getCurrentIndexCount() const - { - if (!mCurrentSection) - return 0; - - RenderOperation* rop = mCurrentSection->getRenderOperation(); - if (rop->indexData) - return rop->indexData->indexCount; - else - return 0; - - } - //----------------------------------------------------------------------------- - void ManualObject::copyTempVertexToBuffer(void) - { - mTempVertexPending = false; - RenderOperation* rop = mCurrentSection->getRenderOperation(); - if (rop->vertexData->vertexCount == 0 && !mCurrentUpdating) - { - // first vertex, autoorganise decl - VertexDeclaration* oldDcl = rop->vertexData->vertexDeclaration; - rop->vertexData->vertexDeclaration = - oldDcl->getAutoOrganisedDeclaration(false, false, false); - HardwareBufferManager::getSingleton().destroyVertexDeclaration(oldDcl); - } - resizeTempVertexBufferIfNeeded(++rop->vertexData->vertexCount); - - // get base pointer - char* pBase = mTempVertexBuffer + (mDeclSize * (rop->vertexData->vertexCount-1)); - const VertexDeclaration::VertexElementList& elemList = - rop->vertexData->vertexDeclaration->getElements(); - for (VertexDeclaration::VertexElementList::const_iterator i = elemList.begin(); - i != elemList.end(); ++i) - { - float* pFloat = 0; - RGBA* pRGBA = 0; - const VertexElement& elem = *i; - switch(elem.getType()) - { - case VET_FLOAT1: - case VET_FLOAT2: - case VET_FLOAT3: - case VET_FLOAT4: - elem.baseVertexPointerToElement(pBase, &pFloat); - break; - case VET_COLOUR: - case VET_COLOUR_ABGR: - case VET_COLOUR_ARGB: - elem.baseVertexPointerToElement(pBase, &pRGBA); - break; - default: - // nop ? - break; - }; - - - RenderSystem* rs; - unsigned short dims; - switch(elem.getSemantic()) - { - case VES_POSITION: - *pFloat++ = mTempVertex.position.x; - *pFloat++ = mTempVertex.position.y; - *pFloat++ = mTempVertex.position.z; - break; - case VES_NORMAL: - *pFloat++ = mTempVertex.normal.x; - *pFloat++ = mTempVertex.normal.y; - *pFloat++ = mTempVertex.normal.z; - break; - case VES_TANGENT: - *pFloat++ = mTempVertex.tangent.x; - *pFloat++ = mTempVertex.tangent.y; - *pFloat++ = mTempVertex.tangent.z; - break; - case VES_TEXTURE_COORDINATES: - dims = VertexElement::getTypeCount(elem.getType()); - for (ushort t = 0; t < dims; ++t) - *pFloat++ = mTempVertex.texCoord[elem.getIndex()][t]; - break; + } + } + + mCurrentSection = OGRE_NEW ManualObjectSection(this, materialName, opType, groupName); + mCurrentUpdating = false; + mCurrentSection->setUseIdentityProjection(mUseIdentityProjection); + mCurrentSection->setUseIdentityView(mUseIdentityView); + mSectionList.push_back(mCurrentSection); + mFirstVertex = true; + mDeclSize = 0; + mTexCoordIndex = 0; + } + //----------------------------------------------------------------------------- + void ManualObject::beginUpdate(size_t sectionIndex) + { + if (mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You cannot call begin() again until after you call end()", + "ManualObject::beginUpdate"); + } + if (sectionIndex >= mSectionList.size()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid section index - out of range.", + "ManualObject::beginUpdate"); + } + mCurrentSection = mSectionList[sectionIndex]; + mCurrentUpdating = true; + mFirstVertex = true; + mTexCoordIndex = 0; + // reset vertex & index count + RenderOperation* rop = mCurrentSection->getRenderOperation(); + rop->vertexData->vertexCount = 0; + if (rop->indexData) + rop->indexData->indexCount = 0; + rop->useIndexes = false; + mDeclSize = rop->vertexData->vertexDeclaration->getVertexSize(0); + } + //----------------------------------------------------------------------------- + void ManualObject::position(const Vector3& pos) + { + position(pos.x, pos.y, pos.z); + } + //----------------------------------------------------------------------------- + void ManualObject::position(Real x, Real y, Real z) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must call begin() before this method", + "ManualObject::position"); + } + if (mTempVertexPending) + { + // bake current vertex + copyTempVertexToBuffer(); + mFirstVertex = false; + } + + if (mFirstVertex && !mCurrentUpdating) + { + // defining declaration + mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration + ->addElement(0, mDeclSize, VET_FLOAT3, VES_POSITION); + mDeclSize += VertexElement::getTypeSize(VET_FLOAT3); + } + + mTempVertex.position.x = x; + mTempVertex.position.y = y; + mTempVertex.position.z = z; + + // update bounds + mAABB.merge(mTempVertex.position); + mRadius = std::max(mRadius, mTempVertex.position.length()); + + // reset current texture coord + mTexCoordIndex = 0; + + mTempVertexPending = true; + } + //----------------------------------------------------------------------------- + void ManualObject::normal(const Vector3& norm) + { + normal(norm.x, norm.y, norm.z); + } + //----------------------------------------------------------------------------- + void ManualObject::normal(Real x, Real y, Real z) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must call begin() before this method", + "ManualObject::normal"); + } + if (mFirstVertex && !mCurrentUpdating) + { + // defining declaration + mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration + ->addElement(0, mDeclSize, VET_FLOAT3, VES_NORMAL); + mDeclSize += VertexElement::getTypeSize(VET_FLOAT3); + } + mTempVertex.normal.x = x; + mTempVertex.normal.y = y; + mTempVertex.normal.z = z; + } + + //----------------------------------------------------------------------------- + void ManualObject::tangent(const Vector3& tan) + { + tangent(tan.x, tan.y, tan.z); + } + //----------------------------------------------------------------------------- + void ManualObject::tangent(Real x, Real y, Real z) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must call begin() before this method", + "ManualObject::tangent"); + } + if (mFirstVertex && !mCurrentUpdating) + { + // defining declaration + mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration + ->addElement(0, mDeclSize, VET_FLOAT3, VES_TANGENT); + mDeclSize += VertexElement::getTypeSize(VET_FLOAT3); + } + mTempVertex.tangent.x = x; + mTempVertex.tangent.y = y; + mTempVertex.tangent.z = z; + } + + //----------------------------------------------------------------------------- + void ManualObject::textureCoord(Real u) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must call begin() before this method", + "ManualObject::textureCoord"); + } + if (mFirstVertex && !mCurrentUpdating) + { + // defining declaration + mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration + ->addElement(0, mDeclSize, VET_FLOAT1, VES_TEXTURE_COORDINATES, mTexCoordIndex); + mDeclSize += VertexElement::getTypeSize(VET_FLOAT1); + } + mTempVertex.texCoordDims[mTexCoordIndex] = 1; + mTempVertex.texCoord[mTexCoordIndex].x = u; + + ++mTexCoordIndex; + + } + //----------------------------------------------------------------------------- + void ManualObject::textureCoord(Real u, Real v) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must call begin() before this method", + "ManualObject::textureCoord"); + } + if (mFirstVertex && !mCurrentUpdating) + { + // defining declaration + mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration + ->addElement(0, mDeclSize, VET_FLOAT2, VES_TEXTURE_COORDINATES, mTexCoordIndex); + mDeclSize += VertexElement::getTypeSize(VET_FLOAT2); + } + mTempVertex.texCoordDims[mTexCoordIndex] = 2; + mTempVertex.texCoord[mTexCoordIndex].x = u; + mTempVertex.texCoord[mTexCoordIndex].y = v; + + ++mTexCoordIndex; + } + //----------------------------------------------------------------------------- + void ManualObject::textureCoord(Real u, Real v, Real w) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must call begin() before this method", + "ManualObject::textureCoord"); + } + if (mFirstVertex && !mCurrentUpdating) + { + // defining declaration + mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration + ->addElement(0, mDeclSize, VET_FLOAT3, VES_TEXTURE_COORDINATES, mTexCoordIndex); + mDeclSize += VertexElement::getTypeSize(VET_FLOAT3); + } + mTempVertex.texCoordDims[mTexCoordIndex] = 3; + mTempVertex.texCoord[mTexCoordIndex].x = u; + mTempVertex.texCoord[mTexCoordIndex].y = v; + mTempVertex.texCoord[mTexCoordIndex].z = w; + + ++mTexCoordIndex; + } + //----------------------------------------------------------------------------- + void ManualObject::textureCoord(Real x, Real y, Real z, Real w) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must call begin() before this method", + "ManualObject::textureCoord"); + } + if (mFirstVertex && !mCurrentUpdating) + { + // defining declaration + mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration + ->addElement(0, mDeclSize, VET_FLOAT4, VES_TEXTURE_COORDINATES, mTexCoordIndex); + mDeclSize += VertexElement::getTypeSize(VET_FLOAT4); + } + mTempVertex.texCoordDims[mTexCoordIndex] = 4; + mTempVertex.texCoord[mTexCoordIndex].x = x; + mTempVertex.texCoord[mTexCoordIndex].y = y; + mTempVertex.texCoord[mTexCoordIndex].z = z; + mTempVertex.texCoord[mTexCoordIndex].w = w; + + ++mTexCoordIndex; + } + //----------------------------------------------------------------------------- + void ManualObject::textureCoord(const Vector2& uv) + { + textureCoord(uv.x, uv.y); + } + //----------------------------------------------------------------------------- + void ManualObject::textureCoord(const Vector3& uvw) + { + textureCoord(uvw.x, uvw.y, uvw.z); + } + //--------------------------------------------------------------------- + void ManualObject::textureCoord(const Vector4& xyzw) + { + textureCoord(xyzw.x, xyzw.y, xyzw.z, xyzw.w); + } + //----------------------------------------------------------------------------- + void ManualObject::colour(const ColourValue& col) + { + colour(col.r, col.g, col.b, col.a); + } + //----------------------------------------------------------------------------- + void ManualObject::colour(Real r, Real g, Real b, Real a) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must call begin() before this method", + "ManualObject::colour"); + } + if (mFirstVertex && !mCurrentUpdating) + { + // defining declaration + mCurrentSection->getRenderOperation()->vertexData->vertexDeclaration + ->addElement(0, mDeclSize, VET_COLOUR, VES_DIFFUSE); + mDeclSize += VertexElement::getTypeSize(VET_COLOUR); + } + mTempVertex.colour.r = r; + mTempVertex.colour.g = g; + mTempVertex.colour.b = b; + mTempVertex.colour.a = a; + + } + //----------------------------------------------------------------------------- + void ManualObject::index(uint32 idx) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must call begin() before this method", + "ManualObject::index"); + } + mAnyIndexed = true; + if (idx >= 65536) + mCurrentSection->set32BitIndices(true); + + // make sure we have index data + RenderOperation* rop = mCurrentSection->getRenderOperation(); + if (!rop->indexData) + { + rop->indexData = OGRE_NEW IndexData(); + rop->indexData->indexCount = 0; + } + rop->useIndexes = true; + resizeTempIndexBufferIfNeeded(++rop->indexData->indexCount); + + mTempIndexBuffer[rop->indexData->indexCount - 1] = idx; + } + //----------------------------------------------------------------------------- + void ManualObject::triangle(uint32 i1, uint32 i2, uint32 i3) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must call begin() before this method", + "ManualObject::index"); + } + if (mCurrentSection->getRenderOperation()->operationType != + RenderOperation::OT_TRIANGLE_LIST) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "This method is only valid on triangle lists", + "ManualObject::index"); + } + + index(i1); + index(i2); + index(i3); + } + //----------------------------------------------------------------------------- + void ManualObject::quad(uint32 i1, uint32 i2, uint32 i3, uint32 i4) + { + // first tri + triangle(i1, i2, i3); + // second tri + triangle(i3, i4, i1); + } + //----------------------------------------------------------------------------- + size_t ManualObject::getCurrentVertexCount() const + { + if (!mCurrentSection) + return 0; + + RenderOperation* rop = mCurrentSection->getRenderOperation(); + + // There's an unfinished vertex being defined, so include it in count + if (mTempVertexPending) + return rop->vertexData->vertexCount + 1; + else + return rop->vertexData->vertexCount; + + } + //----------------------------------------------------------------------------- + size_t ManualObject::getCurrentIndexCount() const + { + if (!mCurrentSection) + return 0; + + RenderOperation* rop = mCurrentSection->getRenderOperation(); + if (rop->indexData) + return rop->indexData->indexCount; + else + return 0; + + } + //----------------------------------------------------------------------------- + void ManualObject::copyTempVertexToBuffer(void) + { + mTempVertexPending = false; + RenderOperation* rop = mCurrentSection->getRenderOperation(); + if (rop->vertexData->vertexCount == 0 && !mCurrentUpdating) + { + // first vertex, autoorganise decl + VertexDeclaration* oldDcl = rop->vertexData->vertexDeclaration; + rop->vertexData->vertexDeclaration = + oldDcl->getAutoOrganisedDeclaration(false, false, false); + HardwareBufferManager::getSingleton().destroyVertexDeclaration(oldDcl); + } + resizeTempVertexBufferIfNeeded(++rop->vertexData->vertexCount); + + // get base pointer + char* pBase = mTempVertexBuffer + (mDeclSize * (rop->vertexData->vertexCount-1)); + const VertexDeclaration::VertexElementList& elemList = + rop->vertexData->vertexDeclaration->getElements(); + for (VertexDeclaration::VertexElementList::const_iterator i = elemList.begin(); + i != elemList.end(); ++i) + { + float* pFloat = 0; + RGBA* pRGBA = 0; + const VertexElement& elem = *i; + switch(elem.getType()) + { + case VET_FLOAT1: + case VET_FLOAT2: + case VET_FLOAT3: + case VET_FLOAT4: + elem.baseVertexPointerToElement(pBase, &pFloat); + break; + case VET_COLOUR: + case VET_COLOUR_ABGR: + case VET_COLOUR_ARGB: + elem.baseVertexPointerToElement(pBase, &pRGBA); + break; + default: + // nop ? + break; + }; + + + RenderSystem* rs; + unsigned short dims; + switch(elem.getSemantic()) + { + case VES_POSITION: + *pFloat++ = mTempVertex.position.x; + *pFloat++ = mTempVertex.position.y; + *pFloat++ = mTempVertex.position.z; + break; + case VES_NORMAL: + *pFloat++ = mTempVertex.normal.x; + *pFloat++ = mTempVertex.normal.y; + *pFloat++ = mTempVertex.normal.z; + break; + case VES_TANGENT: + *pFloat++ = mTempVertex.tangent.x; + *pFloat++ = mTempVertex.tangent.y; + *pFloat++ = mTempVertex.tangent.z; + break; + case VES_TEXTURE_COORDINATES: + dims = VertexElement::getTypeCount(elem.getType()); + for (ushort t = 0; t < dims; ++t) + *pFloat++ = mTempVertex.texCoord[elem.getIndex()][t]; + break; case VES_DIFFUSE: rs = Root::getSingleton().getRenderSystem(); if (rs) @@ -640,242 +640,242 @@ namespace Ogre { } } break; - default: - // nop ? - break; - }; - - } - - } - //----------------------------------------------------------------------------- - ManualObject::ManualObjectSection* ManualObject::end(void) - { - if (!mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You cannot call end() until after you call begin()", - "ManualObject::end"); - } - if (mTempVertexPending) - { - // bake current vertex - copyTempVertexToBuffer(); - } - - // pointer that will be returned - ManualObjectSection* result = NULL; - - RenderOperation* rop = mCurrentSection->getRenderOperation(); - // Check for empty content - if (rop->vertexData->vertexCount == 0 || - (rop->useIndexes && rop->indexData->indexCount == 0)) - { - // You're wasting my time sonny - if (mCurrentUpdating) - { - // Can't just undo / remove since may be in the middle - // Just allow counts to be 0, will not be issued to renderer - - // return the finished section (though it has zero vertices) - result = mCurrentSection; - } - else - { - // First creation, can really undo - // Has already been added to section list end, so remove - mSectionList.pop_back(); - OGRE_DELETE mCurrentSection; - - } - } - else // not an empty section - { - - // Bake the real buffers - HardwareVertexBufferSharedPtr vbuf; - // Check buffer sizes - bool vbufNeedsCreating = true; - bool ibufNeedsCreating = rop->useIndexes; + default: + // nop ? + break; + }; + + } + + } + //----------------------------------------------------------------------------- + ManualObject::ManualObjectSection* ManualObject::end(void) + { + if (!mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You cannot call end() until after you call begin()", + "ManualObject::end"); + } + if (mTempVertexPending) + { + // bake current vertex + copyTempVertexToBuffer(); + } + + // pointer that will be returned + ManualObjectSection* result = NULL; + + RenderOperation* rop = mCurrentSection->getRenderOperation(); + // Check for empty content + if (rop->vertexData->vertexCount == 0 || + (rop->useIndexes && rop->indexData->indexCount == 0)) + { + // You're wasting my time sonny + if (mCurrentUpdating) + { + // Can't just undo / remove since may be in the middle + // Just allow counts to be 0, will not be issued to renderer + + // return the finished section (though it has zero vertices) + result = mCurrentSection; + } + else + { + // First creation, can really undo + // Has already been added to section list end, so remove + mSectionList.pop_back(); + OGRE_DELETE mCurrentSection; + + } + } + else // not an empty section + { + + // Bake the real buffers + HardwareVertexBufferSharedPtr vbuf; + // Check buffer sizes + bool vbufNeedsCreating = true; + bool ibufNeedsCreating = rop->useIndexes; // Work out if we require 16 or 32-bit index buffers HardwareIndexBuffer::IndexType indexType = mCurrentSection->get32BitIndices()? - HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT; - if (mCurrentUpdating) - { - // May be able to reuse buffers, check sizes - vbuf = rop->vertexData->vertexBufferBinding->getBuffer(0); - if (vbuf->getNumVertices() >= rop->vertexData->vertexCount) - vbufNeedsCreating = false; - - if (rop->useIndexes) - { - if ((rop->indexData->indexBuffer->getNumIndexes() >= rop->indexData->indexCount) && + HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT; + if (mCurrentUpdating) + { + // May be able to reuse buffers, check sizes + vbuf = rop->vertexData->vertexBufferBinding->getBuffer(0); + if (vbuf->getNumVertices() >= rop->vertexData->vertexCount) + vbufNeedsCreating = false; + + if (rop->useIndexes) + { + if ((rop->indexData->indexBuffer->getNumIndexes() >= rop->indexData->indexCount) && (indexType == rop->indexData->indexBuffer->getType())) - ibufNeedsCreating = false; - } - - } - if (vbufNeedsCreating) - { - // Make the vertex buffer larger if estimated vertex count higher - // to allow for user-configured growth area - size_t vertexCount = std::max(rop->vertexData->vertexCount, - mEstVertexCount); - vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - mDeclSize, - vertexCount, - mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - rop->vertexData->vertexBufferBinding->setBinding(0, vbuf); - } - if (ibufNeedsCreating) - { - // Make the index buffer larger if estimated index count higher - // to allow for user-configured growth area - size_t indexCount = std::max(rop->indexData->indexCount, - mEstIndexCount); - rop->indexData->indexBuffer = - HardwareBufferManager::getSingleton().createIndexBuffer( - indexType, - indexCount, - mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - } - // Write vertex data - vbuf->writeData( - 0, rop->vertexData->vertexCount * vbuf->getVertexSize(), - mTempVertexBuffer, true); - // Write index data - if(rop->useIndexes) - { + ibufNeedsCreating = false; + } + + } + if (vbufNeedsCreating) + { + // Make the vertex buffer larger if estimated vertex count higher + // to allow for user-configured growth area + size_t vertexCount = std::max(rop->vertexData->vertexCount, + mEstVertexCount); + vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + mDeclSize, + vertexCount, + mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + rop->vertexData->vertexBufferBinding->setBinding(0, vbuf); + } + if (ibufNeedsCreating) + { + // Make the index buffer larger if estimated index count higher + // to allow for user-configured growth area + size_t indexCount = std::max(rop->indexData->indexCount, + mEstIndexCount); + rop->indexData->indexBuffer = + HardwareBufferManager::getSingleton().createIndexBuffer( + indexType, + indexCount, + mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + } + // Write vertex data + vbuf->writeData( + 0, rop->vertexData->vertexCount * vbuf->getVertexSize(), + mTempVertexBuffer, true); + // Write index data + if(rop->useIndexes) + { if (HardwareIndexBuffer::IT_32BIT == indexType) { // direct copy from the mTempIndexBuffer - rop->indexData->indexBuffer->writeData( - 0, - rop->indexData->indexCount - * rop->indexData->indexBuffer->getIndexSize(), - mTempIndexBuffer, true); + rop->indexData->indexBuffer->writeData( + 0, + rop->indexData->indexCount + * rop->indexData->indexBuffer->getIndexSize(), + mTempIndexBuffer, true); } else //(HardwareIndexBuffer::IT_16BIT == indexType) { - uint16* pIdx = static_cast(rop->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - uint32* pSrc = mTempIndexBuffer; + uint16* pIdx = static_cast(rop->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + uint32* pSrc = mTempIndexBuffer; for (size_t i = 0; i < rop->indexData->indexCount; i++) { *pIdx++ = static_cast(*pSrc++); } - rop->indexData->indexBuffer->unlock(); + rop->indexData->indexBuffer->unlock(); } - } - - // return the finished section - result = mCurrentSection; - - } // empty section check - - mCurrentSection = 0; - resetTempAreas(); - - // Tell parent if present - if (mParentNode) - { - mParentNode->needUpdate(); - } - - // will return the finished section or NULL if - // the section was empty (i.e. zero vertices/indices) - return result; - } - //----------------------------------------------------------------------------- - void ManualObject::setMaterialName(size_t idx, const String& name, const String& group) - { - if (idx >= mSectionList.size()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Index out of bounds!", - "ManualObject::setMaterialName"); - } - - mSectionList[idx]->setMaterialName(name, group); - - } - //----------------------------------------------------------------------------- - MeshPtr ManualObject::convertToMesh(const String& meshName, const String& groupName) - { - if (mCurrentSection) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You cannot call convertToMesh() whilst you are in the middle of " - "defining the object; call end() first.", - "ManualObject::convertToMesh"); - } - if (mSectionList.empty()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "No data defined to convert to a mesh.", - "ManualObject::convertToMesh"); - } - MeshPtr m = MeshManager::getSingleton().createManual(meshName, groupName); - - for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) - { - ManualObjectSection* sec = *i; - RenderOperation* rop = sec->getRenderOperation(); - SubMesh* sm = m->createSubMesh(); - sm->useSharedVertices = false; - sm->operationType = rop->operationType; - sm->setMaterialName(sec->getMaterialName(), groupName); - // Copy vertex data; replicate buffers too - sm->vertexData = rop->vertexData->clone(true); - // Copy index data; replicate buffers too; delete the default, old one to avoid memory leaks - - // check if index data is present - if (rop->indexData) - { - // Copy index data; replicate buffers too; delete the default, old one to avoid memory leaks - OGRE_DELETE sm->indexData; - sm->indexData = rop->indexData->clone(true); - } - } + } + + // return the finished section + result = mCurrentSection; + + } // empty section check + + mCurrentSection = 0; + resetTempAreas(); + + // Tell parent if present + if (mParentNode) + { + mParentNode->needUpdate(); + } + + // will return the finished section or NULL if + // the section was empty (i.e. zero vertices/indices) + return result; + } + //----------------------------------------------------------------------------- + void ManualObject::setMaterialName(size_t idx, const String& name, const String& group) + { + if (idx >= mSectionList.size()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Index out of bounds!", + "ManualObject::setMaterialName"); + } + + mSectionList[idx]->setMaterialName(name, group); + + } + //----------------------------------------------------------------------------- + MeshPtr ManualObject::convertToMesh(const String& meshName, const String& groupName) + { + if (mCurrentSection) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You cannot call convertToMesh() whilst you are in the middle of " + "defining the object; call end() first.", + "ManualObject::convertToMesh"); + } + if (mSectionList.empty()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "No data defined to convert to a mesh.", + "ManualObject::convertToMesh"); + } + MeshPtr m = MeshManager::getSingleton().createManual(meshName, groupName); + + for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) + { + ManualObjectSection* sec = *i; + RenderOperation* rop = sec->getRenderOperation(); + SubMesh* sm = m->createSubMesh(); + sm->useSharedVertices = false; + sm->operationType = rop->operationType; + sm->setMaterialName(sec->getMaterialName(), groupName); + // Copy vertex data; replicate buffers too + sm->vertexData = rop->vertexData->clone(true); + // Copy index data; replicate buffers too; delete the default, old one to avoid memory leaks + + // check if index data is present + if (rop->indexData) + { + // Copy index data; replicate buffers too; delete the default, old one to avoid memory leaks + OGRE_DELETE sm->indexData; + sm->indexData = rop->indexData->clone(true); + } + } // update bounds - m->_setBounds(mAABB); - m->_setBoundingSphereRadius(mRadius); - - m->load(); - - return m; - - - } - //----------------------------------------------------------------------------- - void ManualObject::setUseIdentityProjection(bool useIdentityProjection) - { - // Set existing - for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) - { - (*i)->setUseIdentityProjection(useIdentityProjection); - } - - // Save setting for future sections - mUseIdentityProjection = useIdentityProjection; - } - //----------------------------------------------------------------------------- - void ManualObject::setUseIdentityView(bool useIdentityView) - { - // Set existing - for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) - { - (*i)->setUseIdentityView(useIdentityView); - } - - // Save setting for future sections - mUseIdentityView = useIdentityView; - } + m->_setBounds(mAABB); + m->_setBoundingSphereRadius(mRadius); + + m->load(); + + return m; + + + } + //----------------------------------------------------------------------------- + void ManualObject::setUseIdentityProjection(bool useIdentityProjection) + { + // Set existing + for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) + { + (*i)->setUseIdentityProjection(useIdentityProjection); + } + + // Save setting for future sections + mUseIdentityProjection = useIdentityProjection; + } + //----------------------------------------------------------------------------- + void ManualObject::setUseIdentityView(bool useIdentityView) + { + // Set existing + for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) + { + (*i)->setUseIdentityView(useIdentityView); + } + + // Save setting for future sections + mUseIdentityView = useIdentityView; + } //----------------------------------------------------------------------- - ManualObject::ManualObjectSection* ManualObject::getSection(unsigned int inIndex) const + ManualObject::ManualObjectSection* ManualObject::getSection(unsigned int inIndex) const { if (inIndex >= mSectionList.size()) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, @@ -884,103 +884,103 @@ namespace Ogre { return mSectionList[inIndex]; } //----------------------------------------------------------------------- - unsigned int ManualObject::getNumSections(void) const + unsigned int ManualObject::getNumSections(void) const { return static_cast< unsigned int >( mSectionList.size() ); } - //----------------------------------------------------------------------------- - const String& ManualObject::getMovableType(void) const - { - return ManualObjectFactory::FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------------- - const AxisAlignedBox& ManualObject::getBoundingBox(void) const - { - return mAABB; - } - //----------------------------------------------------------------------------- - Real ManualObject::getBoundingRadius(void) const - { - return mRadius; - } - //----------------------------------------------------------------------------- - void ManualObject::_updateRenderQueue(RenderQueue* queue) - { - // To be used when order of creation must be kept while rendering - unsigned short priority = queue->getDefaultRenderablePriority(); - - for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) - { - // Skip empty sections (only happens if non-empty first, then updated) - RenderOperation* rop = (*i)->getRenderOperation(); - if (rop->vertexData->vertexCount == 0 || - (rop->useIndexes && rop->indexData->indexCount == 0)) - continue; - - if (mRenderQueuePrioritySet) - { - assert(mRenderQueueIDSet == true); - queue->addRenderable(*i, mRenderQueueID, mRenderQueuePriority); - } - else if (mRenderQueueIDSet) - queue->addRenderable(*i, mRenderQueueID, mKeepDeclarationOrder ? priority++ : queue->getDefaultRenderablePriority()); - else - queue->addRenderable(*i, queue->getDefaultQueueGroup(), mKeepDeclarationOrder ? priority++ : queue->getDefaultRenderablePriority()); - } - } - //----------------------------------------------------------------------------- - void ManualObject::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) - { - visitor->visit(*i, 0, false); - } - - } - //----------------------------------------------------------------------------- - EdgeData* ManualObject::getEdgeList(void) - { - // Build on demand - if (!mEdgeList && mAnyIndexed) - { - EdgeListBuilder eb; - size_t vertexSet = 0; - bool anyBuilt = false; - for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) - { - RenderOperation* rop = (*i)->getRenderOperation(); - // Only indexed triangle geometry supported for stencil shadows - if (rop->useIndexes && rop->indexData->indexCount != 0 && - (rop->operationType == RenderOperation::OT_TRIANGLE_FAN || - rop->operationType == RenderOperation::OT_TRIANGLE_LIST || - rop->operationType == RenderOperation::OT_TRIANGLE_STRIP)) - { - eb.addVertexData(rop->vertexData); - eb.addIndexData(rop->indexData, vertexSet++); - anyBuilt = true; - } - } - - if (anyBuilt) - mEdgeList = eb.build(); - - } - return mEdgeList; - } - //--------------------------------------------------------------------- - bool ManualObject::hasEdgeList() - { - return getEdgeList() != 0; - } - //----------------------------------------------------------------------------- - ShadowCaster::ShadowRenderableListIterator - ManualObject::getShadowVolumeRenderableIterator( - ShadowTechnique shadowTechnique, const Light* light, - HardwareIndexBufferSharedPtr* indexBuffer, size_t* indexBufferUsedSize, - bool extrude, Real extrusionDistance, unsigned long flags) - { - assert(indexBuffer && "Only external index buffers are supported right now"); + //----------------------------------------------------------------------------- + const String& ManualObject::getMovableType(void) const + { + return ManualObjectFactory::FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------------- + const AxisAlignedBox& ManualObject::getBoundingBox(void) const + { + return mAABB; + } + //----------------------------------------------------------------------------- + Real ManualObject::getBoundingRadius(void) const + { + return mRadius; + } + //----------------------------------------------------------------------------- + void ManualObject::_updateRenderQueue(RenderQueue* queue) + { + // To be used when order of creation must be kept while rendering + unsigned short priority = queue->getDefaultRenderablePriority(); + + for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) + { + // Skip empty sections (only happens if non-empty first, then updated) + RenderOperation* rop = (*i)->getRenderOperation(); + if (rop->vertexData->vertexCount == 0 || + (rop->useIndexes && rop->indexData->indexCount == 0)) + continue; + + if (mRenderQueuePrioritySet) + { + assert(mRenderQueueIDSet == true); + queue->addRenderable(*i, mRenderQueueID, mRenderQueuePriority); + } + else if (mRenderQueueIDSet) + queue->addRenderable(*i, mRenderQueueID, mKeepDeclarationOrder ? priority++ : queue->getDefaultRenderablePriority()); + else + queue->addRenderable(*i, queue->getDefaultQueueGroup(), mKeepDeclarationOrder ? priority++ : queue->getDefaultRenderablePriority()); + } + } + //----------------------------------------------------------------------------- + void ManualObject::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) + { + visitor->visit(*i, 0, false); + } + + } + //----------------------------------------------------------------------------- + EdgeData* ManualObject::getEdgeList(void) + { + // Build on demand + if (!mEdgeList && mAnyIndexed) + { + EdgeListBuilder eb; + size_t vertexSet = 0; + bool anyBuilt = false; + for (SectionList::iterator i = mSectionList.begin(); i != mSectionList.end(); ++i) + { + RenderOperation* rop = (*i)->getRenderOperation(); + // Only indexed triangle geometry supported for stencil shadows + if (rop->useIndexes && rop->indexData->indexCount != 0 && + (rop->operationType == RenderOperation::OT_TRIANGLE_FAN || + rop->operationType == RenderOperation::OT_TRIANGLE_LIST || + rop->operationType == RenderOperation::OT_TRIANGLE_STRIP)) + { + eb.addVertexData(rop->vertexData); + eb.addIndexData(rop->indexData, vertexSet++); + anyBuilt = true; + } + } + + if (anyBuilt) + mEdgeList = eb.build(); + + } + return mEdgeList; + } + //--------------------------------------------------------------------- + bool ManualObject::hasEdgeList() + { + return getEdgeList() != 0; + } + //----------------------------------------------------------------------------- + ShadowCaster::ShadowRenderableListIterator + ManualObject::getShadowVolumeRenderableIterator( + ShadowTechnique shadowTechnique, const Light* light, + HardwareIndexBufferSharedPtr* indexBuffer, size_t* indexBufferUsedSize, + bool extrude, Real extrusionDistance, unsigned long flags) + { + assert(indexBuffer && "Only external index buffers are supported right now"); EdgeData* edgeList = getEdgeList(); if (!edgeList) @@ -989,244 +989,244 @@ namespace Ogre { mShadowRenderables.begin(), mShadowRenderables.end()); } - // Calculate the object space light details - Vector4 lightPos = light->getAs4DVector(); - Matrix4 world2Obj = mParentNode->_getFullTransform().inverseAffine(); - lightPos = world2Obj.transformAffine(lightPos); - Matrix3 world2Obj3x3; - world2Obj.extract3x3Matrix(world2Obj3x3); - extrusionDistance *= Math::Sqrt(std::min(std::min(world2Obj3x3.GetColumn(0).squaredLength(), world2Obj3x3.GetColumn(1).squaredLength()), world2Obj3x3.GetColumn(2).squaredLength())); - - // Init shadow renderable list if required (only allow indexed) - bool init = mShadowRenderables.empty() && mAnyIndexed; - - EdgeData::EdgeGroupList::iterator egi; - ShadowRenderableList::iterator si, siend; - ManualObjectSectionShadowRenderable* esr = 0; - SectionList::iterator seci; - if (init) - mShadowRenderables.resize(edgeList->edgeGroups.size()); - - siend = mShadowRenderables.end(); - egi = edgeList->edgeGroups.begin(); - seci = mSectionList.begin(); - for (si = mShadowRenderables.begin(); si != siend; ++seci) - { + // Calculate the object space light details + Vector4 lightPos = light->getAs4DVector(); + Matrix4 world2Obj = mParentNode->_getFullTransform().inverseAffine(); + lightPos = world2Obj.transformAffine(lightPos); + Matrix3 world2Obj3x3; + world2Obj.extract3x3Matrix(world2Obj3x3); + extrusionDistance *= Math::Sqrt(std::min(std::min(world2Obj3x3.GetColumn(0).squaredLength(), world2Obj3x3.GetColumn(1).squaredLength()), world2Obj3x3.GetColumn(2).squaredLength())); + + // Init shadow renderable list if required (only allow indexed) + bool init = mShadowRenderables.empty() && mAnyIndexed; + + EdgeData::EdgeGroupList::iterator egi; + ShadowRenderableList::iterator si, siend; + ManualObjectSectionShadowRenderable* esr = 0; + SectionList::iterator seci; + if (init) + mShadowRenderables.resize(edgeList->edgeGroups.size()); + + siend = mShadowRenderables.end(); + egi = edgeList->edgeGroups.begin(); + seci = mSectionList.begin(); + for (si = mShadowRenderables.begin(); si != siend; ++seci) + { // Skip non-indexed geometry if (!(*seci)->getRenderOperation()->useIndexes) { continue; } - if (init) - { - // Create a new renderable, create a separate light cap if - // we're using a vertex program (either for this model, or - // for extruding the shadow volume) since otherwise we can - // get depth-fighting on the light cap - MaterialPtr mat = (*seci)->getMaterial(); - mat->load(); - bool vertexProgram = false; - Technique* t = mat->getBestTechnique(0, *seci); - for (unsigned short p = 0; p < t->getNumPasses(); ++p) - { - Pass* pass = t->getPass(p); - if (pass->hasVertexProgram()) - { - vertexProgram = true; - break; - } - } - *si = OGRE_NEW ManualObjectSectionShadowRenderable(this, indexBuffer, - egi->vertexData, vertexProgram || !extrude); - } - // Get shadow renderable - esr = static_cast(*si); - HardwareVertexBufferSharedPtr esrPositionBuffer = esr->getPositionBuffer(); - // Extrude vertices in software if required - if (extrude) - { - extrudeVertices(esrPositionBuffer, - egi->vertexData->vertexCount, - lightPos, extrusionDistance); - - } + if (init) + { + // Create a new renderable, create a separate light cap if + // we're using a vertex program (either for this model, or + // for extruding the shadow volume) since otherwise we can + // get depth-fighting on the light cap + MaterialPtr mat = (*seci)->getMaterial(); + mat->load(); + bool vertexProgram = false; + Technique* t = mat->getBestTechnique(0, *seci); + for (unsigned short p = 0; p < t->getNumPasses(); ++p) + { + Pass* pass = t->getPass(p); + if (pass->hasVertexProgram()) + { + vertexProgram = true; + break; + } + } + *si = OGRE_NEW ManualObjectSectionShadowRenderable(this, indexBuffer, + egi->vertexData, vertexProgram || !extrude); + } + // Get shadow renderable + esr = static_cast(*si); + HardwareVertexBufferSharedPtr esrPositionBuffer = esr->getPositionBuffer(); + // Extrude vertices in software if required + if (extrude) + { + extrudeVertices(esrPositionBuffer, + egi->vertexData->vertexCount, + lightPos, extrusionDistance); + + } ++si; ++egi; - } - // Calc triangle light facing - updateEdgeListLightFacing(edgeList, lightPos); - - // Generate indexes and update renderables - generateShadowVolume(edgeList, *indexBuffer, *indexBufferUsedSize, - light, mShadowRenderables, flags); - - - return ShadowRenderableListIterator( - mShadowRenderables.begin(), mShadowRenderables.end()); - - - } - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- - ManualObject::ManualObjectSection::ManualObjectSection(ManualObject* parent, - const String& materialName, RenderOperation::OperationType opType, const String & groupName) - : mParent(parent), mMaterialName(materialName), mGroupName(groupName), m32BitIndices(false) - { - mRenderOperation.operationType = opType; - // default to no indexes unless we're told - mRenderOperation.useIndexes = false; + } + // Calc triangle light facing + updateEdgeListLightFacing(edgeList, lightPos); + + // Generate indexes and update renderables + generateShadowVolume(edgeList, *indexBuffer, *indexBufferUsedSize, + light, mShadowRenderables, flags); + + + return ShadowRenderableListIterator( + mShadowRenderables.begin(), mShadowRenderables.end()); + + + } + //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + ManualObject::ManualObjectSection::ManualObjectSection(ManualObject* parent, + const String& materialName, RenderOperation::OperationType opType, const String & groupName) + : mParent(parent), mMaterialName(materialName), mGroupName(groupName), m32BitIndices(false) + { + mRenderOperation.operationType = opType; + // default to no indexes unless we're told + mRenderOperation.useIndexes = false; mRenderOperation.useGlobalInstancingVertexBufferIsAvailable = false; - mRenderOperation.vertexData = OGRE_NEW VertexData(); - mRenderOperation.vertexData->vertexCount = 0; - - } - //----------------------------------------------------------------------------- - ManualObject::ManualObjectSection::~ManualObjectSection() - { - OGRE_DELETE mRenderOperation.vertexData; - OGRE_DELETE mRenderOperation.indexData; // ok to delete 0 - } - //----------------------------------------------------------------------------- - RenderOperation* ManualObject::ManualObjectSection::getRenderOperation(void) - { - return &mRenderOperation; - } - //----------------------------------------------------------------------------- - const MaterialPtr& ManualObject::ManualObjectSection::getMaterial(void) const - { - if (mMaterial.isNull()) - { - // Load from default group. If user wants to use alternate groups, - // they can define it and preload - mMaterial = MaterialManager::getSingleton().load(mMaterialName, mGroupName).staticCast(); - } - return mMaterial; - } - //----------------------------------------------------------------------------- - void ManualObject::ManualObjectSection::setMaterialName( const String& name, const String& groupName /* = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME */) - { - if (mMaterialName != name || mGroupName != groupName) - { - mMaterialName = name; - mGroupName = groupName; - mMaterial.setNull(); - } - } - //----------------------------------------------------------------------------- - void ManualObject::ManualObjectSection::getRenderOperation(RenderOperation& op) - { - // direct copy - op = mRenderOperation; - } - //----------------------------------------------------------------------------- - void ManualObject::ManualObjectSection::getWorldTransforms(Matrix4* xform) const - { - xform[0] = mParent->_getParentNodeFullTransform(); - } - //----------------------------------------------------------------------------- - Real ManualObject::ManualObjectSection::getSquaredViewDepth(const Ogre::Camera *cam) const - { - Node* n = mParent->getParentNode(); - assert(n); - return n->getSquaredViewDepth(cam); - } - //----------------------------------------------------------------------------- - const LightList& ManualObject::ManualObjectSection::getLights(void) const - { - return mParent->queryLights(); - } - //----------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - ManualObject::ManualObjectSectionShadowRenderable::ManualObjectSectionShadowRenderable( - ManualObject* parent, HardwareIndexBufferSharedPtr* indexBuffer, - const VertexData* vertexData, bool createSeparateLightCap, - bool isLightCap) - : mParent(parent) - { - // Initialise render op - mRenderOp.indexData = OGRE_NEW IndexData(); - mRenderOp.indexData->indexBuffer = *indexBuffer; - mRenderOp.indexData->indexStart = 0; - // index start and count are sorted out later - - // Create vertex data which just references position component (and 2 component) - mRenderOp.vertexData = OGRE_NEW VertexData(); - // Map in position data - mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT3, VES_POSITION); - ushort origPosBind = - vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource(); - mPositionBuffer = vertexData->vertexBufferBinding->getBuffer(origPosBind); - mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mPositionBuffer); - // Map in w-coord buffer (if present) - if(!vertexData->hardwareShadowVolWBuffer.isNull()) - { - mRenderOp.vertexData->vertexDeclaration->addElement(1,0,VET_FLOAT1, VES_TEXTURE_COORDINATES, 0); - mWBuffer = vertexData->hardwareShadowVolWBuffer; - mRenderOp.vertexData->vertexBufferBinding->setBinding(1, mWBuffer); - } - // Use same vertex start as input - mRenderOp.vertexData->vertexStart = vertexData->vertexStart; - - if (isLightCap) - { - // Use original vertex count, no extrusion - mRenderOp.vertexData->vertexCount = vertexData->vertexCount; - } - else - { - // Vertex count must take into account the doubling of the buffer, - // because second half of the buffer is the extruded copy - mRenderOp.vertexData->vertexCount = - vertexData->vertexCount * 2; - if (createSeparateLightCap) - { - // Create child light cap - mLightCap = OGRE_NEW ManualObjectSectionShadowRenderable(parent, - indexBuffer, vertexData, false, true); - } - } - } - //-------------------------------------------------------------------------- - ManualObject::ManualObjectSectionShadowRenderable::~ManualObjectSectionShadowRenderable() - { - OGRE_DELETE mRenderOp.indexData; - OGRE_DELETE mRenderOp.vertexData; - } - //-------------------------------------------------------------------------- - void ManualObject::ManualObjectSectionShadowRenderable::getWorldTransforms( - Matrix4* xform) const - { - // pretransformed - *xform = mParent->_getParentNodeFullTransform(); - } - //----------------------------------------------------------------------- - void ManualObject::ManualObjectSectionShadowRenderable::rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer) - { - mRenderOp.indexData->indexBuffer = indexBuffer; - if (mLightCap) mLightCap->rebindIndexBuffer(indexBuffer); - } - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- - String ManualObjectFactory::FACTORY_TYPE_NAME = "ManualObject"; - //----------------------------------------------------------------------------- - const String& ManualObjectFactory::getType(void) const - { - return FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------------- - MovableObject* ManualObjectFactory::createInstanceImpl( - const String& name, const NameValuePairList* params) - { - return OGRE_NEW ManualObject(name); - } - //----------------------------------------------------------------------------- - void ManualObjectFactory::destroyInstance( MovableObject* obj) - { - OGRE_DELETE obj; - } + mRenderOperation.vertexData = OGRE_NEW VertexData(); + mRenderOperation.vertexData->vertexCount = 0; + + } + //----------------------------------------------------------------------------- + ManualObject::ManualObjectSection::~ManualObjectSection() + { + OGRE_DELETE mRenderOperation.vertexData; + OGRE_DELETE mRenderOperation.indexData; // ok to delete 0 + } + //----------------------------------------------------------------------------- + RenderOperation* ManualObject::ManualObjectSection::getRenderOperation(void) + { + return &mRenderOperation; + } + //----------------------------------------------------------------------------- + const MaterialPtr& ManualObject::ManualObjectSection::getMaterial(void) const + { + if (mMaterial.isNull()) + { + // Load from default group. If user wants to use alternate groups, + // they can define it and preload + mMaterial = MaterialManager::getSingleton().load(mMaterialName, mGroupName).staticCast(); + } + return mMaterial; + } + //----------------------------------------------------------------------------- + void ManualObject::ManualObjectSection::setMaterialName( const String& name, const String& groupName /* = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME */) + { + if (mMaterialName != name || mGroupName != groupName) + { + mMaterialName = name; + mGroupName = groupName; + mMaterial.setNull(); + } + } + //----------------------------------------------------------------------------- + void ManualObject::ManualObjectSection::getRenderOperation(RenderOperation& op) + { + // direct copy + op = mRenderOperation; + } + //----------------------------------------------------------------------------- + void ManualObject::ManualObjectSection::getWorldTransforms(Matrix4* xform) const + { + xform[0] = mParent->_getParentNodeFullTransform(); + } + //----------------------------------------------------------------------------- + Real ManualObject::ManualObjectSection::getSquaredViewDepth(const Ogre::Camera *cam) const + { + Node* n = mParent->getParentNode(); + assert(n); + return n->getSquaredViewDepth(cam); + } + //----------------------------------------------------------------------------- + const LightList& ManualObject::ManualObjectSection::getLights(void) const + { + return mParent->queryLights(); + } + //----------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + ManualObject::ManualObjectSectionShadowRenderable::ManualObjectSectionShadowRenderable( + ManualObject* parent, HardwareIndexBufferSharedPtr* indexBuffer, + const VertexData* vertexData, bool createSeparateLightCap, + bool isLightCap) + : mParent(parent) + { + // Initialise render op + mRenderOp.indexData = OGRE_NEW IndexData(); + mRenderOp.indexData->indexBuffer = *indexBuffer; + mRenderOp.indexData->indexStart = 0; + // index start and count are sorted out later + + // Create vertex data which just references position component (and 2 component) + mRenderOp.vertexData = OGRE_NEW VertexData(); + // Map in position data + mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT3, VES_POSITION); + ushort origPosBind = + vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource(); + mPositionBuffer = vertexData->vertexBufferBinding->getBuffer(origPosBind); + mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mPositionBuffer); + // Map in w-coord buffer (if present) + if(!vertexData->hardwareShadowVolWBuffer.isNull()) + { + mRenderOp.vertexData->vertexDeclaration->addElement(1,0,VET_FLOAT1, VES_TEXTURE_COORDINATES, 0); + mWBuffer = vertexData->hardwareShadowVolWBuffer; + mRenderOp.vertexData->vertexBufferBinding->setBinding(1, mWBuffer); + } + // Use same vertex start as input + mRenderOp.vertexData->vertexStart = vertexData->vertexStart; + + if (isLightCap) + { + // Use original vertex count, no extrusion + mRenderOp.vertexData->vertexCount = vertexData->vertexCount; + } + else + { + // Vertex count must take into account the doubling of the buffer, + // because second half of the buffer is the extruded copy + mRenderOp.vertexData->vertexCount = + vertexData->vertexCount * 2; + if (createSeparateLightCap) + { + // Create child light cap + mLightCap = OGRE_NEW ManualObjectSectionShadowRenderable(parent, + indexBuffer, vertexData, false, true); + } + } + } + //-------------------------------------------------------------------------- + ManualObject::ManualObjectSectionShadowRenderable::~ManualObjectSectionShadowRenderable() + { + OGRE_DELETE mRenderOp.indexData; + OGRE_DELETE mRenderOp.vertexData; + } + //-------------------------------------------------------------------------- + void ManualObject::ManualObjectSectionShadowRenderable::getWorldTransforms( + Matrix4* xform) const + { + // pretransformed + *xform = mParent->_getParentNodeFullTransform(); + } + //----------------------------------------------------------------------- + void ManualObject::ManualObjectSectionShadowRenderable::rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer) + { + mRenderOp.indexData->indexBuffer = indexBuffer; + if (mLightCap) mLightCap->rebindIndexBuffer(indexBuffer); + } + //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + String ManualObjectFactory::FACTORY_TYPE_NAME = "ManualObject"; + //----------------------------------------------------------------------------- + const String& ManualObjectFactory::getType(void) const + { + return FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------------- + MovableObject* ManualObjectFactory::createInstanceImpl( + const String& name, const NameValuePairList* params) + { + return OGRE_NEW ManualObject(name); + } + //----------------------------------------------------------------------------- + void ManualObjectFactory::destroyInstance( MovableObject* obj) + { + OGRE_DELETE obj; + } diff --git a/OgreMain/src/OgreMaterial.cpp b/OgreMain/src/OgreMaterial.cpp index 59ae4ace308..a4412fc8fe4 100644 --- a/OgreMain/src/OgreMaterial.cpp +++ b/OgreMain/src/OgreMaterial.cpp @@ -38,35 +38,35 @@ THE SOFTWARE. namespace Ogre { //----------------------------------------------------------------------- - Material::Material(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader) - :Resource(creator, name, handle, group, isManual, loader), + Material::Material(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader) + :Resource(creator, name, handle, group, isManual, loader), mReceiveShadows(true), mTransparencyCastsShadows(false), mCompilationRequired(true) { - // Override isManual, not applicable for Material (we always want to call loadImpl) - if(isManual) - { - mIsManual = false; - LogManager::getSingleton().logMessage("Material " + name + - " was requested with isManual=true, but this is not applicable " - "for materials; the flag has been reset to false"); - } + // Override isManual, not applicable for Material (we always want to call loadImpl) + if(isManual) + { + mIsManual = false; + LogManager::getSingleton().logMessage("Material " + name + + " was requested with isManual=true, but this is not applicable " + "for materials; the flag has been reset to false"); + } - // Initialise to default strategy - mLodStrategy = LodStrategyManager::getSingleton().getDefaultStrategy(); + // Initialise to default strategy + mLodStrategy = LodStrategyManager::getSingleton().getDefaultStrategy(); - mLodValues.push_back(0.0f); + mLodValues.push_back(0.0f); - applyDefaults(); + applyDefaults(); - /* For consistency with StringInterface, but we don't add any parameters here - That's because the Resource implementation of StringInterface is to - list all the options that need to be set before loading, of which - we have none as such. Full details can be set through scripts. - */ - createParamDictionary("Material"); + /* For consistency with StringInterface, but we don't add any parameters here + That's because the Resource implementation of StringInterface is to + list all the options that need to be set before loading, of which + we have none as such. Full details can be set through scripts. + */ + createParamDictionary("Material"); } //----------------------------------------------------------------------- Material::~Material() @@ -79,18 +79,18 @@ namespace Ogre { //----------------------------------------------------------------------- Material& Material::operator=(const Material& rhs) { - mName = rhs.mName; - mGroup = rhs.mGroup; - mCreator = rhs.mCreator; - mIsManual = rhs.mIsManual; - mLoader = rhs.mLoader; - mHandle = rhs.mHandle; + mName = rhs.mName; + mGroup = rhs.mGroup; + mCreator = rhs.mCreator; + mIsManual = rhs.mIsManual; + mLoader = rhs.mLoader; + mHandle = rhs.mHandle; mSize = rhs.mSize; mReceiveShadows = rhs.mReceiveShadows; mTransparencyCastsShadows = rhs.mTransparencyCastsShadows; mLoadingState = rhs.mLoadingState; - mIsBackgroundLoaded = rhs.mIsBackgroundLoaded; + mIsBackgroundLoaded = rhs.mIsBackgroundLoaded; // Copy Techniques this->removeAllTechniques(); @@ -102,27 +102,27 @@ namespace Ogre { *t = *(*i); if ((*i)->isSupported()) { - insertSupportedTechnique(t); + insertSupportedTechnique(t); } } - // Also copy LOD information + // Also copy LOD information mUserLodValues = rhs.mUserLodValues; - mLodValues = rhs.mLodValues; + mLodValues = rhs.mLodValues; mLodStrategy = rhs.mLodStrategy; mCompilationRequired = rhs.mCompilationRequired; // illumination passes are not compiled right away so // mIsLoaded state should still be the same as the original material assert(isLoaded() == rhs.isLoaded()); - return *this; + return *this; } //----------------------------------------------------------------------- void Material::prepareImpl(void) { - // compile if required + // compile if required if (mCompilationRequired) compile(); @@ -192,29 +192,29 @@ namespace Ogre { } //----------------------------------------------------------------------- MaterialPtr Material::clone(const String& newName, bool changeGroup, - const String& newGroup) const - { - MaterialPtr newMat; - if (changeGroup) - { - newMat = MaterialManager::getSingleton().create(newName, newGroup); - } - else - { - newMat = MaterialManager::getSingleton().create(newName, mGroup); - } + const String& newGroup) const + { + MaterialPtr newMat; + if (changeGroup) + { + newMat = MaterialManager::getSingleton().create(newName, newGroup); + } + else + { + newMat = MaterialManager::getSingleton().create(newName, mGroup); + } // Keep handle (see below, copy overrides everything) ResourceHandle newHandle = newMat->getHandle(); // Assign values from this *newMat = *this; - // Restore new group if required, will have been overridden by operator - if (changeGroup) - { - newMat->mGroup = newGroup; - } - + // Restore new group if required, will have been overridden by operator + if (changeGroup) + { + newMat->mGroup = newGroup; + } + // Correct the name & handle, they get copied too newMat->mName = newName; newMat->mHandle = newHandle; @@ -231,39 +231,39 @@ namespace Ogre { ResourceHandle savedHandle = mat->mHandle; String savedName = mat->mName; String savedGroup = mat->mGroup; - ManualResourceLoader* savedLoader = mat->mLoader; - bool savedManual = mat->mIsManual; + ManualResourceLoader* savedLoader = mat->mLoader; + bool savedManual = mat->mIsManual; // Assign values from this *mat = *this; // Correct the name & handle, they get copied too mat->mName = savedName; mat->mHandle = savedHandle; mat->mGroup = savedGroup; - mat->mIsManual = savedManual; - mat->mLoader = savedLoader; + mat->mIsManual = savedManual; + mat->mLoader = savedLoader; } //----------------------------------------------------------------------- void Material::applyDefaults(void) { - MaterialPtr defaults = MaterialManager::getSingleton().getDefaultSettings(); + MaterialPtr defaults = MaterialManager::getSingleton().getDefaultSettings(); - if (!defaults.isNull()) - { + if (!defaults.isNull()) + { // save name & handle String savedName = mName; String savedGroup = mGroup; ResourceHandle savedHandle = mHandle; - ManualResourceLoader *savedLoader = mLoader; - bool savedManual = mIsManual; - *this = *defaults; + ManualResourceLoader *savedLoader = mLoader; + bool savedManual = mIsManual; + *this = *defaults; // restore name & handle mName = savedName; mHandle = savedHandle; mGroup = savedGroup; - mLoader = savedLoader; - mIsManual = savedManual; - } + mLoader = savedLoader; + mIsManual = savedManual; + } mCompilationRequired = true; } @@ -301,71 +301,71 @@ namespace Ogre { return foundTechnique; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- unsigned short Material::getNumTechniques(void) const { - return static_cast(mTechniques.size()); + return static_cast(mTechniques.size()); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- Technique* Material::getSupportedTechnique(unsigned short index) { assert (index < mSupportedTechniques.size() && "Index out of bounds."); return mSupportedTechniques[index]; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- unsigned short Material::getNumSupportedTechniques(void) const { - return static_cast(mSupportedTechniques.size()); - } - //----------------------------------------------------------------------- - unsigned short Material::getNumLodLevels(unsigned short schemeIndex) const - { - // Safety check - empty list? - if (mBestTechniquesBySchemeList.empty()) - return 0; - - BestTechniquesBySchemeList::const_iterator i = - mBestTechniquesBySchemeList.find(schemeIndex); - if (i == mBestTechniquesBySchemeList.end()) - { - // get the first item, will be 0 (the default) if default - // scheme techniques exist, otherwise the earliest defined - i = mBestTechniquesBySchemeList.begin(); - } - - return static_cast(i->second->size()); - } - //----------------------------------------------------------------------- - unsigned short Material::getNumLodLevels(const String& schemeName) const - { - return getNumLodLevels( - MaterialManager::getSingleton()._getSchemeIndex(schemeName)); - } - //----------------------------------------------------------------------- - void Material::insertSupportedTechnique(Technique* t) - { - mSupportedTechniques.push_back(t); - // get scheme - unsigned short schemeIndex = t->_getSchemeIndex(); - BestTechniquesBySchemeList::iterator i = - mBestTechniquesBySchemeList.find(schemeIndex); - LodTechniques* lodtechs = 0; - if (i == mBestTechniquesBySchemeList.end()) - { - lodtechs = OGRE_NEW_T(LodTechniques, MEMCATEGORY_RESOURCE); - mBestTechniquesBySchemeList[schemeIndex] = lodtechs; - } - else - { - lodtechs = i->second; - } - - // Insert won't replace if supported technique for this scheme/lod is - // already there, which is what we want - lodtechs->insert(LodTechniques::value_type(t->getLodIndex(), t)); - - } - //----------------------------------------------------------------------------- + return static_cast(mSupportedTechniques.size()); + } + //----------------------------------------------------------------------- + unsigned short Material::getNumLodLevels(unsigned short schemeIndex) const + { + // Safety check - empty list? + if (mBestTechniquesBySchemeList.empty()) + return 0; + + BestTechniquesBySchemeList::const_iterator i = + mBestTechniquesBySchemeList.find(schemeIndex); + if (i == mBestTechniquesBySchemeList.end()) + { + // get the first item, will be 0 (the default) if default + // scheme techniques exist, otherwise the earliest defined + i = mBestTechniquesBySchemeList.begin(); + } + + return static_cast(i->second->size()); + } + //----------------------------------------------------------------------- + unsigned short Material::getNumLodLevels(const String& schemeName) const + { + return getNumLodLevels( + MaterialManager::getSingleton()._getSchemeIndex(schemeName)); + } + //----------------------------------------------------------------------- + void Material::insertSupportedTechnique(Technique* t) + { + mSupportedTechniques.push_back(t); + // get scheme + unsigned short schemeIndex = t->_getSchemeIndex(); + BestTechniquesBySchemeList::iterator i = + mBestTechniquesBySchemeList.find(schemeIndex); + LodTechniques* lodtechs = 0; + if (i == mBestTechniquesBySchemeList.end()) + { + lodtechs = OGRE_NEW_T(LodTechniques, MEMCATEGORY_RESOURCE); + mBestTechniquesBySchemeList[schemeIndex] = lodtechs; + } + else + { + lodtechs = i->second; + } + + // Insert won't replace if supported technique for this scheme/lod is + // already there, which is what we want + lodtechs->insert(LodTechniques::value_type(t->getLodIndex(), t)); + + } + //----------------------------------------------------------------------------- Technique* Material::getBestTechnique(unsigned short lodIndex, const Renderable* rend) { if (mSupportedTechniques.empty()) @@ -374,56 +374,56 @@ namespace Ogre { } else { - Technique* ret = 0; - MaterialManager& matMgr = MaterialManager::getSingleton(); - // get scheme - BestTechniquesBySchemeList::iterator si = - mBestTechniquesBySchemeList.find(matMgr._getActiveSchemeIndex()); - // scheme not found? - if (si == mBestTechniquesBySchemeList.end()) - { - // listener specified alternative technique available? - ret = matMgr._arbitrateMissingTechniqueForActiveScheme(this, lodIndex, rend); - if (ret) - return ret; - - // Nope, use default - // get the first item, will be 0 (the default) if default - // scheme techniques exist, otherwise the earliest defined - si = mBestTechniquesBySchemeList.begin(); - } - - // get LOD - LodTechniques::iterator li = si->second->find(lodIndex); - // LOD not found? - if (li == si->second->end()) - { - // Use the next LOD level up - for (LodTechniques::reverse_iterator rli = si->second->rbegin(); - rli != si->second->rend(); ++rli) - { - if (rli->second->getLodIndex() < lodIndex) - { - ret = rli->second; - break; - } - - } - if (!ret) - { - // shouldn't ever hit this really, unless user defines no LOD 0 - // pick the first LOD we have (must be at least one to have a scheme entry) - ret = si->second->begin()->second; - } - - } - else - { - // LOD found - ret = li->second; - } - - return ret; + Technique* ret = 0; + MaterialManager& matMgr = MaterialManager::getSingleton(); + // get scheme + BestTechniquesBySchemeList::iterator si = + mBestTechniquesBySchemeList.find(matMgr._getActiveSchemeIndex()); + // scheme not found? + if (si == mBestTechniquesBySchemeList.end()) + { + // listener specified alternative technique available? + ret = matMgr._arbitrateMissingTechniqueForActiveScheme(this, lodIndex, rend); + if (ret) + return ret; + + // Nope, use default + // get the first item, will be 0 (the default) if default + // scheme techniques exist, otherwise the earliest defined + si = mBestTechniquesBySchemeList.begin(); + } + + // get LOD + LodTechniques::iterator li = si->second->find(lodIndex); + // LOD not found? + if (li == si->second->end()) + { + // Use the next LOD level up + for (LodTechniques::reverse_iterator rli = si->second->rbegin(); + rli != si->second->rend(); ++rli) + { + if (rli->second->getLodIndex() < lodIndex) + { + ret = rli->second; + break; + } + + } + if (!ret) + { + // shouldn't ever hit this really, unless user defines no LOD 0 + // pick the first LOD we have (must be at least one to have a scheme entry) + ret = si->second->begin()->second; + } + + } + else + { + // LOD found + ret = li->second; + } + + return ret; } } @@ -435,7 +435,7 @@ namespace Ogre { OGRE_DELETE(*i); mTechniques.erase(i); mSupportedTechniques.clear(); - clearBestTechniqueList(); + clearBestTechniqueList(); mCompilationRequired = true; } //----------------------------------------------------------------------- @@ -464,47 +464,47 @@ namespace Ogre { } //----------------------------------------------------------------------- bool Material::isTransparent(void) const - { - // Check each technique - Techniques::const_iterator i, iend; - iend = mTechniques.end(); - for (i = mTechniques.begin(); i != iend; ++i) - { - if ( (*i)->isTransparent() ) - return true; - } - return false; - } + { + // Check each technique + Techniques::const_iterator i, iend; + iend = mTechniques.end(); + for (i = mTechniques.begin(); i != iend; ++i) + { + if ( (*i)->isTransparent() ) + return true; + } + return false; + } //----------------------------------------------------------------------- void Material::compile(bool autoManageTextureUnits) { // Compile each technique, then add it to the list of supported techniques mSupportedTechniques.clear(); - clearBestTechniqueList(); - mUnsupportedReasons.clear(); + clearBestTechniqueList(); + mUnsupportedReasons.clear(); Techniques::iterator i, iend; iend = mTechniques.end(); - size_t techNo = 0; + size_t techNo = 0; for (i = mTechniques.begin(); i != iend; ++i, ++techNo) { String compileMessages = (*i)->_compile(autoManageTextureUnits); if ( (*i)->isSupported() ) { - insertSupportedTechnique(*i); + insertSupportedTechnique(*i); + } + else + { + // Log informational + StringStream str; + str << "Material " << mName << " Technique " << techNo; + if (!(*i)->getName().empty()) + str << "(" << (*i)->getName() << ")"; + str << " is not supported. " << compileMessages; + LogManager::getSingleton().logMessage(str.str(), LML_TRIVIAL); + mUnsupportedReasons += compileMessages; } - else - { - // Log informational - StringStream str; - str << "Material " << mName << " Technique " << techNo; - if (!(*i)->getName().empty()) - str << "(" << (*i)->getName() << ")"; - str << " is not supported. " << compileMessages; - LogManager::getSingleton().logMessage(str.str(), LML_TRIVIAL); - mUnsupportedReasons += compileMessages; - } } mCompilationRequired = false; @@ -513,20 +513,20 @@ namespace Ogre { if (mSupportedTechniques.empty()) { LogManager::getSingleton().stream(LML_CRITICAL) - << "WARNING: material " << mName << " has no supportable " - << "Techniques and will be blank. Explanation: \n" << mUnsupportedReasons; + << "WARNING: material " << mName << " has no supportable " + << "Techniques and will be blank. Explanation: \n" << mUnsupportedReasons; + } + } + //----------------------------------------------------------------------- + void Material::clearBestTechniqueList(void) + { + for (BestTechniquesBySchemeList::iterator i = mBestTechniquesBySchemeList.begin(); + i != mBestTechniquesBySchemeList.end(); ++i) + { + OGRE_DELETE_T(i->second, LodTechniques, MEMCATEGORY_RESOURCE); } + mBestTechniquesBySchemeList.clear(); } - //----------------------------------------------------------------------- - void Material::clearBestTechniqueList(void) - { - for (BestTechniquesBySchemeList::iterator i = mBestTechniquesBySchemeList.begin(); - i != mBestTechniquesBySchemeList.end(); ++i) - { - OGRE_DELETE_T(i->second, LodTechniques, MEMCATEGORY_RESOURCE); - } - mBestTechniquesBySchemeList.clear(); - } //----------------------------------------------------------------------- void Material::setPointSize(Real ps) { @@ -541,17 +541,17 @@ namespace Ogre { //----------------------------------------------------------------------- void Material::setAmbient(Real red, Real green, Real blue) { - setAmbient(ColourValue(red, green, blue)); + setAmbient(ColourValue(red, green, blue)); } //----------------------------------------------------------------------- void Material::setAmbient(const ColourValue& ambient) { - Techniques::iterator i, iend; - iend = mTechniques.end(); - for (i = mTechniques.begin(); i != iend; ++i) - { - (*i)->setAmbient(ambient); - } + Techniques::iterator i, iend; + iend = mTechniques.end(); + for (i = mTechniques.begin(); i != iend; ++i) + { + (*i)->setAmbient(ambient); + } } //----------------------------------------------------------------------- void Material::setDiffuse(Real red, Real green, Real blue, Real alpha) @@ -596,17 +596,17 @@ namespace Ogre { //----------------------------------------------------------------------- void Material::setSelfIllumination(Real red, Real green, Real blue) { - setSelfIllumination(ColourValue(red, green, blue)); + setSelfIllumination(ColourValue(red, green, blue)); } //----------------------------------------------------------------------- void Material::setSelfIllumination(const ColourValue& selfIllum) { - Techniques::iterator i, iend; - iend = mTechniques.end(); - for (i = mTechniques.begin(); i != iend; ++i) - { - (*i)->setSelfIllumination(selfIllum); - } + Techniques::iterator i, iend; + iend = mTechniques.end(); + for (i = mTechniques.begin(); i != iend; ++i) + { + (*i)->setSelfIllumination(selfIllum); + } } //----------------------------------------------------------------------- void Material::setDepthCheckEnabled(bool enabled) @@ -639,7 +639,7 @@ namespace Ogre { } } //----------------------------------------------------------------------- - void Material::setColourWriteEnabled(bool enabled) + void Material::setColourWriteEnabled(bool enabled) { Techniques::iterator i, iend; iend = mTechniques.end(); @@ -762,40 +762,40 @@ namespace Ogre { } // -------------------------------------------------------------------- void Material::setSeparateSceneBlending( const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor, const SceneBlendFactor sourceFactorAlpha, const SceneBlendFactor destFactorAlpha) - { + { Techniques::iterator i, iend; iend = mTechniques.end(); for (i = mTechniques.begin(); i != iend; ++i) { (*i)->setSeparateSceneBlending(sourceFactor, destFactor, sourceFactorAlpha, destFactorAlpha); } - } + } // -------------------------------------------------------------------- void Material::_notifyNeedsRecompile(void) { mCompilationRequired = true; // Also need to unload to ensure we loaded any new items - if (isLoaded()) // needed to stop this being called in 'loading' state - unload(); + if (isLoaded()) // needed to stop this being called in 'loading' state + unload(); } // -------------------------------------------------------------------- void Material::setLodLevels(const LodValueList& lodValues) { // Square the distances for the internal list - LodValueList::const_iterator i, iend; - iend = lodValues.end(); - // First, clear and add single zero entry - mLodValues.clear(); + LodValueList::const_iterator i, iend; + iend = lodValues.end(); + // First, clear and add single zero entry + mLodValues.clear(); mUserLodValues.clear(); mUserLodValues.push_back(0); - mLodValues.push_back(mLodStrategy->getBaseValue()); - for (i = lodValues.begin(); i != iend; ++i) - { - mUserLodValues.push_back(*i); + mLodValues.push_back(mLodStrategy->getBaseValue()); + for (i = lodValues.begin(); i != iend; ++i) + { + mUserLodValues.push_back(*i); if (mLodStrategy) mLodValues.push_back(mLodStrategy->transformUserValue(*i)); - } - + } + } // -------------------------------------------------------------------- ushort Material::getLodIndex(Real value) const @@ -817,15 +817,15 @@ namespace Ogre { bool Material::applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply) const { // iterate through all techniques and apply texture aliases - Techniques::const_iterator i, iend; - iend = mTechniques.end(); + Techniques::const_iterator i, iend; + iend = mTechniques.end(); bool testResult = false; - for (i = mTechniques.begin(); i != iend; ++i) - { + for (i = mTechniques.begin(); i != iend; ++i) + { if ((*i)->applyTextureAliases(aliasList, apply)) testResult = true; - } + } return testResult; } diff --git a/OgreMain/src/OgreMaterialManager.cpp b/OgreMain/src/OgreMaterialManager.cpp index 9214f89ee74..54f8fb3c0b2 100644 --- a/OgreMain/src/OgreMaterialManager.cpp +++ b/OgreMain/src/OgreMaterialManager.cpp @@ -46,97 +46,97 @@ namespace Ogre { { assert( msSingleton ); return ( *msSingleton ); } - String MaterialManager::DEFAULT_SCHEME_NAME = "Default"; + String MaterialManager::DEFAULT_SCHEME_NAME = "Default"; //----------------------------------------------------------------------- MaterialManager::MaterialManager() : OGRE_THREAD_POINTER_INIT(mSerializer) { - mDefaultMinFilter = FO_LINEAR; - mDefaultMagFilter = FO_LINEAR; - mDefaultMipFilter = FO_POINT; - mDefaultCompareEnabled = false; - mDefaultCompareFunction = CMPF_GREATER_EQUAL; + mDefaultMinFilter = FO_LINEAR; + mDefaultMagFilter = FO_LINEAR; + mDefaultMipFilter = FO_POINT; + mDefaultCompareEnabled = false; + mDefaultCompareFunction = CMPF_GREATER_EQUAL; - mDefaultMaxAniso = 1; + mDefaultMaxAniso = 1; - // Create primary thread copies of script compiler / serializer - // other copies for other threads may also be instantiated - OGRE_THREAD_POINTER_SET(mSerializer, OGRE_NEW MaterialSerializer()); + // Create primary thread copies of script compiler / serializer + // other copies for other threads may also be instantiated + OGRE_THREAD_POINTER_SET(mSerializer, OGRE_NEW MaterialSerializer()); // Loading order mLoadOrder = 100.0f; - // Scripting is supported by this manager + // Scripting is supported by this manager - // Resource type - mResourceType = "Material"; + // Resource type + mResourceType = "Material"; - // Register with resource group manager - ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); + // Register with resource group manager + ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); - // Default scheme - mActiveSchemeIndex = 0; - mActiveSchemeName = DEFAULT_SCHEME_NAME; - mSchemes[mActiveSchemeName] = 0; + // Default scheme + mActiveSchemeIndex = 0; + mActiveSchemeName = DEFAULT_SCHEME_NAME; + mSchemes[mActiveSchemeName] = 0; } //----------------------------------------------------------------------- MaterialManager::~MaterialManager() { mDefaultSettings.setNull(); - // Resources cleared by superclass - // Unregister with resource group manager - ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); - ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); + // Resources cleared by superclass + // Unregister with resource group manager + ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); + ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); - // delete primary thread instances directly, other threads will delete - // theirs automatically when the threads end. - OGRE_THREAD_POINTER_DELETE(mSerializer); + // delete primary thread instances directly, other threads will delete + // theirs automatically when the threads end. + OGRE_THREAD_POINTER_DELETE(mSerializer); } - //----------------------------------------------------------------------- - Resource* MaterialManager::createImpl(const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, + //----------------------------------------------------------------------- + Resource* MaterialManager::createImpl(const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* params) - { - return OGRE_NEW Material(this, name, handle, group, isManual, loader); - } - //----------------------------------------------------------------------- - MaterialPtr MaterialManager::create (const String& name, const String& group, - bool isManual, ManualResourceLoader* loader, - const NameValuePairList* createParams) - { - return createResource(name,group,isManual,loader,createParams).staticCast(); - } - //----------------------------------------------------------------------- - MaterialPtr MaterialManager::getByName(const String& name, const String& groupName) - { - return getResourceByName(name, groupName).staticCast(); - } + { + return OGRE_NEW Material(this, name, handle, group, isManual, loader); + } + //----------------------------------------------------------------------- + MaterialPtr MaterialManager::create (const String& name, const String& group, + bool isManual, ManualResourceLoader* loader, + const NameValuePairList* createParams) + { + return createResource(name,group,isManual,loader,createParams).staticCast(); + } //----------------------------------------------------------------------- - void MaterialManager::initialise(void) - { - // Set up default material - don't use name contructor as we want to avoid applying defaults - mDefaultSettings = create("DefaultSettings", ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + MaterialPtr MaterialManager::getByName(const String& name, const String& groupName) + { + return getResourceByName(name, groupName).staticCast(); + } + //----------------------------------------------------------------------- + void MaterialManager::initialise(void) + { + // Set up default material - don't use name contructor as we want to avoid applying defaults + mDefaultSettings = create("DefaultSettings", ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); // Add a single technique and pass, non-programmable mDefaultSettings->createTechnique()->createPass(); // Set the default LOD strategy mDefaultSettings->setLodStrategy(LodStrategyManager::getSingleton().getDefaultStrategy()); - // Set up a lit base white material - create("BaseWhite", ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); - // Set up an unlit base white material + // Set up a lit base white material + create("BaseWhite", ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + // Set up an unlit base white material MaterialPtr baseWhiteNoLighting = create("BaseWhiteNoLighting", ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); baseWhiteNoLighting->setLightingEnabled(false); - } + } //----------------------------------------------------------------------- void MaterialManager::parseScript(DataStreamPtr& stream, const String& groupName) { - ScriptCompilerManager::getSingleton().parseScript(stream, groupName); + ScriptCompilerManager::getSingleton().parseScript(stream, groupName); } //----------------------------------------------------------------------- - void MaterialManager::setDefaultTextureFiltering(TextureFilterOptions fo) - { + void MaterialManager::setDefaultTextureFiltering(TextureFilterOptions fo) + { switch (fo) { case TFO_NONE: @@ -152,17 +152,17 @@ namespace Ogre { setDefaultTextureFiltering(FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR); break; } - } + } //----------------------------------------------------------------------- - void MaterialManager::setDefaultAnisotropy(unsigned int maxAniso) - { - mDefaultMaxAniso = maxAniso; - } + void MaterialManager::setDefaultAnisotropy(unsigned int maxAniso) + { + mDefaultMaxAniso = maxAniso; + } //----------------------------------------------------------------------- - unsigned int MaterialManager::getDefaultAnisotropy() const - { - return mDefaultMaxAniso; - } + unsigned int MaterialManager::getDefaultAnisotropy() const + { + return mDefaultMaxAniso; + } //----------------------------------------------------------------------- void MaterialManager::setDefaultTextureFiltering(FilterType ftype, FilterOptions opts) { @@ -203,99 +203,99 @@ namespace Ogre { return mDefaultMinFilter; } //----------------------------------------------------------------------- - unsigned short MaterialManager::_getSchemeIndex(const String& schemeName) - { - unsigned short ret = 0; - SchemeMap::iterator i = mSchemes.find(schemeName); - if (i != mSchemes.end()) - { - ret = i->second; - } - else - { - // Create new - ret = static_cast(mSchemes.size()); - mSchemes[schemeName] = ret; - } - return ret; + unsigned short MaterialManager::_getSchemeIndex(const String& schemeName) + { + unsigned short ret = 0; + SchemeMap::iterator i = mSchemes.find(schemeName); + if (i != mSchemes.end()) + { + ret = i->second; + } + else + { + // Create new + ret = static_cast(mSchemes.size()); + mSchemes[schemeName] = ret; + } + return ret; - } - //----------------------------------------------------------------------- - const String& MaterialManager::_getSchemeName(unsigned short index) - { - for (SchemeMap::iterator i = mSchemes.begin(); i != mSchemes.end(); ++i) - { - if (i->second == index) - return i->first; - } - return DEFAULT_SCHEME_NAME; - } + } //----------------------------------------------------------------------- - unsigned short MaterialManager::_getActiveSchemeIndex(void) const - { - return mActiveSchemeIndex; - } + const String& MaterialManager::_getSchemeName(unsigned short index) + { + for (SchemeMap::iterator i = mSchemes.begin(); i != mSchemes.end(); ++i) + { + if (i->second == index) + return i->first; + } + return DEFAULT_SCHEME_NAME; + } //----------------------------------------------------------------------- - const String& MaterialManager::getActiveScheme(void) const - { - return mActiveSchemeName; - } + unsigned short MaterialManager::_getActiveSchemeIndex(void) const + { + return mActiveSchemeIndex; + } //----------------------------------------------------------------------- - void MaterialManager::setActiveScheme(const String& schemeName) - { - if (mActiveSchemeName != schemeName) - { - // Allow the creation of new scheme indexes on demand - // even if they're not specified in any Technique - mActiveSchemeIndex = _getSchemeIndex(schemeName); - mActiveSchemeName = schemeName; - } - } + const String& MaterialManager::getActiveScheme(void) const + { + return mActiveSchemeName; + } + //----------------------------------------------------------------------- + void MaterialManager::setActiveScheme(const String& schemeName) + { + if (mActiveSchemeName != schemeName) + { + // Allow the creation of new scheme indexes on demand + // even if they're not specified in any Technique + mActiveSchemeIndex = _getSchemeIndex(schemeName); + mActiveSchemeName = schemeName; + } + } //----------------------------------------------------------------------- - void MaterialManager::addListener(Listener* l, const Ogre::String& schemeName) - { - mListenerMap[schemeName].push_back(l); - } - //--------------------------------------------------------------------- - void MaterialManager::removeListener(Listener* l, const Ogre::String& schemeName) - { - mListenerMap[schemeName].remove(l); - } - //--------------------------------------------------------------------- - Technique* MaterialManager::_arbitrateMissingTechniqueForActiveScheme( - Material* mat, unsigned short lodIndex, const Renderable* rend) - { - //First, check the scheme specific listeners - ListenerMap::iterator it = mListenerMap.find(mActiveSchemeName); - if (it != mListenerMap.end()) - { - ListenerList& listenerList = it->second; - for (ListenerList::iterator i = listenerList.begin(); i != listenerList.end(); ++i) - { - Technique* t = (*i)->handleSchemeNotFound(mActiveSchemeIndex, - mActiveSchemeName, mat, lodIndex, rend); - if (t) - return t; - } - } + void MaterialManager::addListener(Listener* l, const Ogre::String& schemeName) + { + mListenerMap[schemeName].push_back(l); + } + //--------------------------------------------------------------------- + void MaterialManager::removeListener(Listener* l, const Ogre::String& schemeName) + { + mListenerMap[schemeName].remove(l); + } + //--------------------------------------------------------------------- + Technique* MaterialManager::_arbitrateMissingTechniqueForActiveScheme( + Material* mat, unsigned short lodIndex, const Renderable* rend) + { + //First, check the scheme specific listeners + ListenerMap::iterator it = mListenerMap.find(mActiveSchemeName); + if (it != mListenerMap.end()) + { + ListenerList& listenerList = it->second; + for (ListenerList::iterator i = listenerList.begin(); i != listenerList.end(); ++i) + { + Technique* t = (*i)->handleSchemeNotFound(mActiveSchemeIndex, + mActiveSchemeName, mat, lodIndex, rend); + if (t) + return t; + } + } - //If no success, check generic listeners - it = mListenerMap.find(BLANKSTRING); - if (it != mListenerMap.end()) - { - ListenerList& listenerList = it->second; - for (ListenerList::iterator i = listenerList.begin(); i != listenerList.end(); ++i) - { - Technique* t = (*i)->handleSchemeNotFound(mActiveSchemeIndex, - mActiveSchemeName, mat, lodIndex, rend); - if (t) - return t; - } - } - + //If no success, check generic listeners + it = mListenerMap.find(BLANKSTRING); + if (it != mListenerMap.end()) + { + ListenerList& listenerList = it->second; + for (ListenerList::iterator i = listenerList.begin(); i != listenerList.end(); ++i) + { + Technique* t = (*i)->handleSchemeNotFound(mActiveSchemeIndex, + mActiveSchemeName, mat, lodIndex, rend); + if (t) + return t; + } + } + - return 0; + return 0; - } + } } diff --git a/OgreMain/src/OgreMaterialSerializer.cpp b/OgreMain/src/OgreMaterialSerializer.cpp index 91d685c513f..7998abc953d 100644 --- a/OgreMain/src/OgreMaterialSerializer.cpp +++ b/OgreMain/src/OgreMaterialSerializer.cpp @@ -267,8 +267,8 @@ namespace Ogre stype = SBT_ADD; else if (vecparams[0] == "modulate") stype = SBT_MODULATE; - else if (vecparams[0] == "colour_blend") - stype = SBT_TRANSPARENT_COLOUR; + else if (vecparams[0] == "colour_blend") + stype = SBT_TRANSPARENT_COLOUR; else if (vecparams[0] == "alpha_blend") stype = SBT_TRANSPARENT_ALPHA; else @@ -321,8 +321,8 @@ namespace Ogre stype = SBT_ADD; else if (vecparams[0] == "modulate") stype = SBT_MODULATE; - else if (vecparams[0] == "colour_blend") - stype = SBT_TRANSPARENT_COLOUR; + else if (vecparams[0] == "colour_blend") + stype = SBT_TRANSPARENT_COLOUR; else if (vecparams[0] == "alpha_blend") stype = SBT_TRANSPARENT_ALPHA; else @@ -338,8 +338,8 @@ namespace Ogre stypea = SBT_ADD; else if (vecparams[0] == "modulate") stypea = SBT_MODULATE; - else if (vecparams[0] == "colour_blend") - stypea = SBT_TRANSPARENT_COLOUR; + else if (vecparams[0] == "colour_blend") + stypea = SBT_TRANSPARENT_COLOUR; else if (vecparams[0] == "alpha_blend") stypea = SBT_TRANSPARENT_ALPHA; else @@ -349,21 +349,21 @@ namespace Ogre context); return false; } - - context.pass->setSeparateSceneBlending(stype, stypea); + + context.pass->setSeparateSceneBlending(stype, stypea); } else if (vecparams.size() == 4) { //src/dest SceneBlendFactor src, dest; - SceneBlendFactor srca, desta; + SceneBlendFactor srca, desta; try { src = convertBlendFactor(vecparams[0]); dest = convertBlendFactor(vecparams[1]); srca = convertBlendFactor(vecparams[2]); desta = convertBlendFactor(vecparams[3]); - context.pass->setSeparateSceneBlending(src,dest,srca,desta); + context.pass->setSeparateSceneBlending(src,dest,srca,desta); } catch (Exception& e) { @@ -432,34 +432,34 @@ namespace Ogre context); return false; } - //----------------------------------------------------------------------- - bool parseLightScissor(String& params, MaterialScriptContext& context) - { - StringUtil::toLowerCase(params); - if (params == "on") - context.pass->setLightScissoringEnabled(true); - else if (params == "off") - context.pass->setLightScissoringEnabled(false); - else - logParseError( - "Bad light_scissor attribute, valid parameters are 'on' or 'off'.", - context); - return false; - } - //----------------------------------------------------------------------- - bool parseLightClip(String& params, MaterialScriptContext& context) - { - StringUtil::toLowerCase(params); - if (params == "on") - context.pass->setLightClipPlanesEnabled(true); - else if (params == "off") - context.pass->setLightClipPlanesEnabled(false); - else - logParseError( - "Bad light_clip_planes attribute, valid parameters are 'on' or 'off'.", - context); - return false; - } + //----------------------------------------------------------------------- + bool parseLightScissor(String& params, MaterialScriptContext& context) + { + StringUtil::toLowerCase(params); + if (params == "on") + context.pass->setLightScissoringEnabled(true); + else if (params == "off") + context.pass->setLightScissoringEnabled(false); + else + logParseError( + "Bad light_scissor attribute, valid parameters are 'on' or 'off'.", + context); + return false; + } + //----------------------------------------------------------------------- + bool parseLightClip(String& params, MaterialScriptContext& context) + { + StringUtil::toLowerCase(params); + if (params == "on") + context.pass->setLightClipPlanesEnabled(true); + else if (params == "off") + context.pass->setLightClipPlanesEnabled(false); + else + logParseError( + "Bad light_clip_planes attribute, valid parameters are 'on' or 'off'.", + context); + return false; + } //----------------------------------------------------------------------- bool parseDepthFunc(String& params, MaterialScriptContext& context) { @@ -475,20 +475,20 @@ namespace Ogre return false; } - //----------------------------------------------------------------------- - bool parseNormaliseNormals(String& params, MaterialScriptContext& context) - { - StringUtil::toLowerCase(params); - if (params == "on") - context.pass->setNormaliseNormals(true); - else if (params == "off") - context.pass->setNormaliseNormals(false); - else - logParseError( - "Bad normalise_normals attribute, valid parameters are 'on' or 'off'.", - context); - return false; - } + //----------------------------------------------------------------------- + bool parseNormaliseNormals(String& params, MaterialScriptContext& context) + { + StringUtil::toLowerCase(params); + if (params == "on") + context.pass->setNormaliseNormals(true); + else if (params == "off") + context.pass->setNormaliseNormals(false); + else + logParseError( + "Bad normalise_normals attribute, valid parameters are 'on' or 'off'.", + context); + return false; + } //----------------------------------------------------------------------- bool parseColourWrite(String& params, MaterialScriptContext& context) { @@ -552,15 +552,15 @@ namespace Ogre //----------------------------------------------------------------------- bool parseMaxLights(String& params, MaterialScriptContext& context) { - context.pass->setMaxSimultaneousLights((ushort)StringConverter::parseInt(params)); + context.pass->setMaxSimultaneousLights((ushort)StringConverter::parseInt(params)); + return false; + } + //----------------------------------------------------------------------- + bool parseStartLight(String& params, MaterialScriptContext& context) + { + context.pass->setStartLight((ushort)StringConverter::parseInt(params)); return false; } - //----------------------------------------------------------------------- - bool parseStartLight(String& params, MaterialScriptContext& context) - { - context.pass->setStartLight((ushort)StringConverter::parseInt(params)); - return false; - } //----------------------------------------------------------------------- void parseIterationLightTypes(String& params, MaterialScriptContext& context) { @@ -593,7 +593,7 @@ namespace Ogre iteration once_per_light [light type] iteration iteration [per_light] [light type] - iteration [per_n_lights] [light type] + iteration [per_n_lights] [light type] */ StringUtil::toLowerCase(params); StringVector vecparams = StringUtil::split(params, " \t"); @@ -636,30 +636,30 @@ namespace Ogre context.pass->setIteratePerLight(true, false); } } - else if (vecparams[1] == "per_n_lights") - { - if (vecparams.size() < 3) - { - logParseError( - "Bad iteration attribute, expected number of lights.", - context); - } - else - { - // Parse num lights - context.pass->setLightCountPerIteration( - (ushort)StringConverter::parseInt(vecparams[2])); - // Light type - if (vecparams.size() == 4) - { - parseIterationLightTypes(vecparams[3], context); - } - else - { - context.pass->setIteratePerLight(true, false); - } - } - } + else if (vecparams[1] == "per_n_lights") + { + if (vecparams.size() < 3) + { + logParseError( + "Bad iteration attribute, expected number of lights.", + context); + } + else + { + // Parse num lights + context.pass->setLightCountPerIteration( + (ushort)StringConverter::parseInt(vecparams[2])); + // Light type + if (vecparams.size() == 4) + { + parseIterationLightTypes(vecparams[3], context); + } + else + { + context.pass->setIteratePerLight(true, false); + } + } + } else logParseError( "Bad iteration attribute, valid parameters are [per_light|per_n_lights ] [light type].", context); @@ -681,59 +681,59 @@ namespace Ogre bool parsePointSprites(String& params, MaterialScriptContext& context) { if (params=="on") - context.pass->setPointSpritesEnabled(true); - else if (params=="off") - context.pass->setPointSpritesEnabled(false); - else + context.pass->setPointSpritesEnabled(true); + else if (params=="off") + context.pass->setPointSpritesEnabled(false); + else logParseError( "Bad point_sprites attribute, valid parameters are 'on' or 'off'.", context); return false; } //----------------------------------------------------------------------- - bool parsePointAttenuation(String& params, MaterialScriptContext& context) - { + bool parsePointAttenuation(String& params, MaterialScriptContext& context) + { StringVector vecparams = StringUtil::split(params, " \t"); if (vecparams.size() != 1 && vecparams.size() != 4) - { - logParseError("Bad point_size_attenuation attribute, 1 or 4 parameters expected", context); - return false; - } - if (vecparams[0] == "off") - { - context.pass->setPointAttenuation(false); - } - else if (vecparams[0] == "on") - { - if (vecparams.size() == 4) - { - context.pass->setPointAttenuation(true, - StringConverter::parseReal(vecparams[1]), - StringConverter::parseReal(vecparams[2]), - StringConverter::parseReal(vecparams[3])); - } - else - { - context.pass->setPointAttenuation(true); - } - } - - return false; - } - //----------------------------------------------------------------------- - bool parsePointSizeMin(String& params, MaterialScriptContext& context) - { - context.pass->setPointMinSize( - StringConverter::parseReal(params)); - return false; - } - //----------------------------------------------------------------------- - bool parsePointSizeMax(String& params, MaterialScriptContext& context) - { - context.pass->setPointMaxSize( - StringConverter::parseReal(params)); - return false; - } + { + logParseError("Bad point_size_attenuation attribute, 1 or 4 parameters expected", context); + return false; + } + if (vecparams[0] == "off") + { + context.pass->setPointAttenuation(false); + } + else if (vecparams[0] == "on") + { + if (vecparams.size() == 4) + { + context.pass->setPointAttenuation(true, + StringConverter::parseReal(vecparams[1]), + StringConverter::parseReal(vecparams[2]), + StringConverter::parseReal(vecparams[3])); + } + else + { + context.pass->setPointAttenuation(true); + } + } + + return false; + } + //----------------------------------------------------------------------- + bool parsePointSizeMin(String& params, MaterialScriptContext& context) + { + context.pass->setPointMinSize( + StringConverter::parseReal(params)); + return false; + } + //----------------------------------------------------------------------- + bool parsePointSizeMax(String& params, MaterialScriptContext& context) + { + context.pass->setPointMaxSize( + StringConverter::parseReal(params)); + return false; + } //----------------------------------------------------------------------- bool parseFogging(String& params, MaterialScriptContext& context) { @@ -804,31 +804,31 @@ namespace Ogre return false; } - //----------------------------------------------------------------------- - bool parsePolygonMode(String& params, MaterialScriptContext& context) - { - StringUtil::toLowerCase(params); - if (params=="solid") - context.pass->setPolygonMode(PM_SOLID); - else if (params=="wireframe") - context.pass->setPolygonMode(PM_WIREFRAME); - else if (params=="points") - context.pass->setPolygonMode(PM_POINTS); - else - logParseError("Bad polygon_mode attribute, valid parameters are 'solid', " - "'wireframe' or 'points'.", context); - - return false; - } - //----------------------------------------------------------------------- - bool parsePolygonModeOverrideable(String& params, MaterialScriptContext& context) - { - StringUtil::toLowerCase(params); - - context.pass->setPolygonModeOverrideable( - StringConverter::parseBool(params)); - return false; - } + //----------------------------------------------------------------------- + bool parsePolygonMode(String& params, MaterialScriptContext& context) + { + StringUtil::toLowerCase(params); + if (params=="solid") + context.pass->setPolygonMode(PM_SOLID); + else if (params=="wireframe") + context.pass->setPolygonMode(PM_WIREFRAME); + else if (params=="points") + context.pass->setPolygonMode(PM_POINTS); + else + logParseError("Bad polygon_mode attribute, valid parameters are 'solid', " + "'wireframe' or 'points'.", context); + + return false; + } + //----------------------------------------------------------------------- + bool parsePolygonModeOverrideable(String& params, MaterialScriptContext& context) + { + StringUtil::toLowerCase(params); + + context.pass->setPolygonModeOverrideable( + StringConverter::parseBool(params)); + return false; + } //----------------------------------------------------------------------- bool parseFiltering(String& params, MaterialScriptContext& context) { @@ -873,23 +873,23 @@ namespace Ogre return false; } //----------------------------------------------------------------------- - bool parseCompareTest(String& params, MaterialScriptContext& context) + bool parseCompareTest(String& params, MaterialScriptContext& context) { StringUtil::toLowerCase(params); try - { - if(params == "on") - { - context.textureUnit->setTextureCompareEnabled(true); - } - else if(params == "off") - { - context.textureUnit->setTextureCompareEnabled(false); - } - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid compare setting", "parseCompareEnabled"); - } + { + if(params == "on") + { + context.textureUnit->setTextureCompareEnabled(true); + } + else if(params == "off") + { + context.textureUnit->setTextureCompareEnabled(false); + } + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid compare setting", "parseCompareEnabled"); + } } catch (...) { @@ -898,22 +898,22 @@ namespace Ogre return false; } - //----------------------------------------------------------------------- - bool parseCompareFunction(String& params, MaterialScriptContext& context) - { - StringUtil::toLowerCase(params); - try { - CompareFunction func = convertCompareFunction(params); - context.textureUnit->setTextureCompareFunction(func); - } - catch (...) - { - logParseError("Bad compare_func attribute, invalid function parameter.", context); - } - - return false; - } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + bool parseCompareFunction(String& params, MaterialScriptContext& context) + { + StringUtil::toLowerCase(params); + try { + CompareFunction func = convertCompareFunction(params); + context.textureUnit->setTextureCompareFunction(func); + } + catch (...) + { + logParseError("Bad compare_func attribute, invalid function parameter.", context); + } + + return false; + } + //----------------------------------------------------------------------- // Texture layer attributes bool parseTexture(String& params, MaterialScriptContext& context) { @@ -925,12 +925,12 @@ namespace Ogre context); } TextureType tt = TEX_TYPE_2D; - int mipmaps = MIP_DEFAULT; // When passed to TextureManager::load, this means default to default number of mipmaps + int mipmaps = MIP_DEFAULT; // When passed to TextureManager::load, this means default to default number of mipmaps bool isAlpha = false; - bool hwGamma = false; + bool hwGamma = false; PixelFormat desiredFormat = PF_UNKNOWN; - for (size_t p = 1; p < numParams; ++p) - { + for (size_t p = 1; p < numParams; ++p) + { StringUtil::toLowerCase(vecparams[p]); if (vecparams[p] == "1d") { @@ -948,74 +948,74 @@ namespace Ogre { tt = TEX_TYPE_CUBE_MAP; } - else if (vecparams[p] == "unlimited") - { - mipmaps = MIP_UNLIMITED; - } - else if (StringConverter::isNumber(vecparams[p])) - { - mipmaps = StringConverter::parseInt(vecparams[p]); - } - else if (vecparams[p] == "alpha") - { - isAlpha = true; - } - else if (vecparams[p] == "gamma") - { - hwGamma = true; - } + else if (vecparams[p] == "unlimited") + { + mipmaps = MIP_UNLIMITED; + } + else if (StringConverter::isNumber(vecparams[p])) + { + mipmaps = StringConverter::parseInt(vecparams[p]); + } + else if (vecparams[p] == "alpha") + { + isAlpha = true; + } + else if (vecparams[p] == "gamma") + { + hwGamma = true; + } else if ((desiredFormat = PixelUtil::getFormatFromName(vecparams[p], true)) != PF_UNKNOWN) { // nothing to do here } - else - { - logParseError("Invalid texture option - "+vecparams[p]+".", + else + { + logParseError("Invalid texture option - "+vecparams[p]+".", context); - } + } } - context.textureUnit->setTextureName(vecparams[0], tt); + context.textureUnit->setTextureName(vecparams[0], tt); context.textureUnit->setNumMipmaps(mipmaps); context.textureUnit->setIsAlpha(isAlpha); context.textureUnit->setDesiredFormat(desiredFormat); - context.textureUnit->setHardwareGammaEnabled(hwGamma); + context.textureUnit->setHardwareGammaEnabled(hwGamma); + return false; + } + //--------------------------------------------------------------------- + bool parseBindingType(String& params, MaterialScriptContext& context) + { + if (params == "fragment") + { + context.textureUnit->setBindingType(TextureUnitState::BT_FRAGMENT); + } + else if (params == "vertex") + { + context.textureUnit->setBindingType(TextureUnitState::BT_VERTEX); + } + else if (params == "geometry") + { + context.textureUnit->setBindingType(TextureUnitState::BT_GEOMETRY); + } + else if (params == "tessellation_hull") + { + context.textureUnit->setBindingType(TextureUnitState::BT_TESSELLATION_HULL); + } + else if (params == "tessellation_domain") + { + context.textureUnit->setBindingType(TextureUnitState::BT_TESSELLATION_DOMAIN); + } + else if (params == "compute") + { + context.textureUnit->setBindingType(TextureUnitState::BT_COMPUTE); + } + else + { + logParseError("Invalid binding_type option - "+params+".", + context); + } return false; } - //--------------------------------------------------------------------- - bool parseBindingType(String& params, MaterialScriptContext& context) - { - if (params == "fragment") - { - context.textureUnit->setBindingType(TextureUnitState::BT_FRAGMENT); - } - else if (params == "vertex") - { - context.textureUnit->setBindingType(TextureUnitState::BT_VERTEX); - } - else if (params == "geometry") - { - context.textureUnit->setBindingType(TextureUnitState::BT_GEOMETRY); - } - else if (params == "tessellation_hull") - { - context.textureUnit->setBindingType(TextureUnitState::BT_TESSELLATION_HULL); - } - else if (params == "tessellation_domain") - { - context.textureUnit->setBindingType(TextureUnitState::BT_TESSELLATION_DOMAIN); - } - else if (params == "compute") - { - context.textureUnit->setBindingType(TextureUnitState::BT_COMPUTE); - } - else - { - logParseError("Invalid binding_type option - "+params+".", - context); - } - return false; - } //----------------------------------------------------------------------- bool parseAnimTexture(String& params, MaterialScriptContext& context) { @@ -1058,7 +1058,7 @@ namespace Ogre // Get final param bool useUVW; String& uvOpt = vecparams[numParams-1]; - StringUtil::toLowerCase(uvOpt); + StringUtil::toLowerCase(uvOpt); if (uvOpt == "combineduvw") useUVW = true; else if (uvOpt == "separateuv") @@ -1100,22 +1100,22 @@ namespace Ogre return false; } //----------------------------------------------------------------------- - TextureUnitState::TextureAddressingMode convTexAddressMode(const String& params, MaterialScriptContext& context) - { - if (params=="wrap") - return TextureUnitState::TAM_WRAP; - else if (params=="mirror") - return TextureUnitState::TAM_MIRROR; - else if (params=="clamp") - return TextureUnitState::TAM_CLAMP; - else if (params=="border") - return TextureUnitState::TAM_BORDER; - else - logParseError("Bad tex_address_mode attribute, valid parameters are " - "'wrap', 'mirror', 'clamp' or 'border'.", context); - // default - return TextureUnitState::TAM_WRAP; - } + TextureUnitState::TextureAddressingMode convTexAddressMode(const String& params, MaterialScriptContext& context) + { + if (params=="wrap") + return TextureUnitState::TAM_WRAP; + else if (params=="mirror") + return TextureUnitState::TAM_MIRROR; + else if (params=="clamp") + return TextureUnitState::TAM_CLAMP; + else if (params=="border") + return TextureUnitState::TAM_BORDER; + else + logParseError("Bad tex_address_mode attribute, valid parameters are " + "'wrap', 'mirror', 'clamp' or 'border'.", context); + // default + return TextureUnitState::TAM_WRAP; + } //----------------------------------------------------------------------- bool parseTexAddressMode(String& params, MaterialScriptContext& context) { @@ -1124,34 +1124,34 @@ namespace Ogre StringVector vecparams = StringUtil::split(params, " \t"); size_t numParams = vecparams.size(); - if (numParams > 3 || numParams < 1) - { - logParseError("Invalid number of parameters to tex_address_mode" - " - must be between 1 and 3", context); - } - if (numParams == 1) - { - // Single-parameter option - context.textureUnit->setTextureAddressingMode( - convTexAddressMode(vecparams[0], context)); - } - else - { - // 2-3 parameter option - TextureUnitState::UVWAddressingMode uvw; - uvw.u = convTexAddressMode(vecparams[0], context); - uvw.v = convTexAddressMode(vecparams[1], context); - if (numParams == 3) - { - // w - uvw.w = convTexAddressMode(vecparams[2], context); - } - else - { - uvw.w = TextureUnitState::TAM_WRAP; - } - context.textureUnit->setTextureAddressingMode(uvw); - } + if (numParams > 3 || numParams < 1) + { + logParseError("Invalid number of parameters to tex_address_mode" + " - must be between 1 and 3", context); + } + if (numParams == 1) + { + // Single-parameter option + context.textureUnit->setTextureAddressingMode( + convTexAddressMode(vecparams[0], context)); + } + else + { + // 2-3 parameter option + TextureUnitState::UVWAddressingMode uvw; + uvw.u = convTexAddressMode(vecparams[0], context); + uvw.v = convTexAddressMode(vecparams[1], context); + if (numParams == 3) + { + // w + uvw.w = convTexAddressMode(vecparams[2], context); + } + else + { + uvw.w = TextureUnitState::TAM_WRAP; + } + context.textureUnit->setTextureAddressingMode(uvw); + } return false; } //----------------------------------------------------------------------- @@ -1216,21 +1216,21 @@ namespace Ogre return false; } - //--------------------------------------------------------------------- - bool parseAlphaToCoverage(String& params, MaterialScriptContext& context) - { - StringUtil::toLowerCase(params); - if (params == "on") - context.pass->setAlphaToCoverageEnabled(true); - else if (params == "off") - context.pass->setAlphaToCoverageEnabled(false); - else - logParseError( - "Bad alpha_to_coverage attribute, valid parameters are 'on' or 'off'.", - context); - - return false; - } + //--------------------------------------------------------------------- + bool parseAlphaToCoverage(String& params, MaterialScriptContext& context) + { + StringUtil::toLowerCase(params); + if (params == "on") + context.pass->setAlphaToCoverageEnabled(true); + else if (params == "off") + context.pass->setAlphaToCoverageEnabled(false); + else + logParseError( + "Bad alpha_to_coverage attribute, valid parameters are 'on' or 'off'.", + context); + + return false; + } //----------------------------------------------------------------------- bool parseTransparentSorting(String& params, MaterialScriptContext& context) { @@ -1644,62 +1644,62 @@ namespace Ogre return false; } - //----------------------------------------------------------------------- - bool parseTransform(String& params, MaterialScriptContext& context) - { - StringVector vecparams = StringUtil::split(params, " \t"); - if (vecparams.size() != 16) - { - logParseError("Bad transform attribute, wrong number of parameters (expected 16)", context); - return false; - } - Matrix4 xform( - StringConverter::parseReal(vecparams[0]), - StringConverter::parseReal(vecparams[1]), - StringConverter::parseReal(vecparams[2]), - StringConverter::parseReal(vecparams[3]), - StringConverter::parseReal(vecparams[4]), - StringConverter::parseReal(vecparams[5]), - StringConverter::parseReal(vecparams[6]), - StringConverter::parseReal(vecparams[7]), - StringConverter::parseReal(vecparams[8]), - StringConverter::parseReal(vecparams[9]), - StringConverter::parseReal(vecparams[10]), - StringConverter::parseReal(vecparams[11]), - StringConverter::parseReal(vecparams[12]), - StringConverter::parseReal(vecparams[13]), - StringConverter::parseReal(vecparams[14]), - StringConverter::parseReal(vecparams[15]) ); - context.textureUnit->setTextureTransform(xform); - - - return false; - } + //----------------------------------------------------------------------- + bool parseTransform(String& params, MaterialScriptContext& context) + { + StringVector vecparams = StringUtil::split(params, " \t"); + if (vecparams.size() != 16) + { + logParseError("Bad transform attribute, wrong number of parameters (expected 16)", context); + return false; + } + Matrix4 xform( + StringConverter::parseReal(vecparams[0]), + StringConverter::parseReal(vecparams[1]), + StringConverter::parseReal(vecparams[2]), + StringConverter::parseReal(vecparams[3]), + StringConverter::parseReal(vecparams[4]), + StringConverter::parseReal(vecparams[5]), + StringConverter::parseReal(vecparams[6]), + StringConverter::parseReal(vecparams[7]), + StringConverter::parseReal(vecparams[8]), + StringConverter::parseReal(vecparams[9]), + StringConverter::parseReal(vecparams[10]), + StringConverter::parseReal(vecparams[11]), + StringConverter::parseReal(vecparams[12]), + StringConverter::parseReal(vecparams[13]), + StringConverter::parseReal(vecparams[14]), + StringConverter::parseReal(vecparams[15]) ); + context.textureUnit->setTextureTransform(xform); + + + return false; + } //----------------------------------------------------------------------- bool parseDepthBias(String& params, MaterialScriptContext& context) { - StringVector vecparams = StringUtil::split(params, " \t"); + StringVector vecparams = StringUtil::split(params, " \t"); - float constantBias = static_cast(StringConverter::parseReal(vecparams[0])); - float slopeScaleBias = 0.0f; - if (vecparams.size() > 1) - { - slopeScaleBias = static_cast(StringConverter::parseReal(vecparams[1])); - } + float constantBias = static_cast(StringConverter::parseReal(vecparams[0])); + float slopeScaleBias = 0.0f; + if (vecparams.size() > 1) + { + slopeScaleBias = static_cast(StringConverter::parseReal(vecparams[1])); + } context.pass->setDepthBias(constantBias, slopeScaleBias); return false; } - //----------------------------------------------------------------------- - bool parseIterationDepthBias(String& params, MaterialScriptContext& context) - { - StringVector vecparams = StringUtil::split(params, " \t"); + //----------------------------------------------------------------------- + bool parseIterationDepthBias(String& params, MaterialScriptContext& context) + { + StringVector vecparams = StringUtil::split(params, " \t"); - float bias = static_cast(StringConverter::parseReal(vecparams[0])); - context.pass->setIterationDepthBias(bias); + float bias = static_cast(StringConverter::parseReal(vecparams[0])); + context.pass->setIterationDepthBias(bias); - return false; - } + return false; + } //----------------------------------------------------------------------- bool parseAnisotropy(String& params, MaterialScriptContext& context) { @@ -1715,76 +1715,76 @@ namespace Ogre return false; } - //----------------------------------------------------------------------- - bool parseMipmapBias(String& params, MaterialScriptContext& context) - { - context.textureUnit->setTextureMipmapBias( - (float)StringConverter::parseReal(params)); - - return false; - } - //----------------------------------------------------------------------- - bool parseContentType(String& params, MaterialScriptContext& context) - { - StringVector vecparams = StringUtil::tokenise(params, " \t"); - if (vecparams.empty()) - { - logParseError("No content_type specified", context); - return false; - } - String& paramType = vecparams[0]; - if (paramType == "named") - { - context.textureUnit->setContentType(TextureUnitState::CONTENT_NAMED); - } - else if (paramType == "shadow") - { - context.textureUnit->setContentType(TextureUnitState::CONTENT_SHADOW); - } - else if (paramType == "compositor") - { - context.textureUnit->setContentType(TextureUnitState::CONTENT_COMPOSITOR); - if (vecparams.size() == 3) - { - context.textureUnit->setCompositorReference(vecparams[1], vecparams[2]); - } - else if (vecparams.size() == 4) - { - context.textureUnit->setCompositorReference(vecparams[1], vecparams[2], - StringConverter::parseUnsignedInt(vecparams[3])); - } - else - { - logParseError("compositor content_type requires 2 or 3 extra params", context); - } - } - else - { - logParseError("Invalid content_type specified : " + paramType, context); - } - return false; - } - //----------------------------------------------------------------------- - bool parseIlluminationStage(String& params, MaterialScriptContext& context) - { - if (params == "ambient") - { - context.pass->setIlluminationStage(IS_AMBIENT); - } - else if (params == "per_light") - { - context.pass->setIlluminationStage(IS_PER_LIGHT); - } - else if (params == "decal") - { - context.pass->setIlluminationStage(IS_DECAL); - } - else - { - logParseError("Invalid illumination_stage specified.", context); - } - return false; - } + //----------------------------------------------------------------------- + bool parseMipmapBias(String& params, MaterialScriptContext& context) + { + context.textureUnit->setTextureMipmapBias( + (float)StringConverter::parseReal(params)); + + return false; + } + //----------------------------------------------------------------------- + bool parseContentType(String& params, MaterialScriptContext& context) + { + StringVector vecparams = StringUtil::tokenise(params, " \t"); + if (vecparams.empty()) + { + logParseError("No content_type specified", context); + return false; + } + String& paramType = vecparams[0]; + if (paramType == "named") + { + context.textureUnit->setContentType(TextureUnitState::CONTENT_NAMED); + } + else if (paramType == "shadow") + { + context.textureUnit->setContentType(TextureUnitState::CONTENT_SHADOW); + } + else if (paramType == "compositor") + { + context.textureUnit->setContentType(TextureUnitState::CONTENT_COMPOSITOR); + if (vecparams.size() == 3) + { + context.textureUnit->setCompositorReference(vecparams[1], vecparams[2]); + } + else if (vecparams.size() == 4) + { + context.textureUnit->setCompositorReference(vecparams[1], vecparams[2], + StringConverter::parseUnsignedInt(vecparams[3])); + } + else + { + logParseError("compositor content_type requires 2 or 3 extra params", context); + } + } + else + { + logParseError("Invalid content_type specified : " + paramType, context); + } + return false; + } + //----------------------------------------------------------------------- + bool parseIlluminationStage(String& params, MaterialScriptContext& context) + { + if (params == "ambient") + { + context.pass->setIlluminationStage(IS_AMBIENT); + } + else if (params == "per_light") + { + context.pass->setIlluminationStage(IS_PER_LIGHT); + } + else if (params == "decal") + { + context.pass->setIlluminationStage(IS_DECAL); + } + else + { + logParseError("Invalid illumination_stage specified.", context); + } + return false; + } //----------------------------------------------------------------------- bool parseLodValues(String& params, MaterialScriptContext& context) { @@ -1809,88 +1809,88 @@ namespace Ogre context.technique->setLodIndex((ushort)StringConverter::parseInt(params)); return false; } - //----------------------------------------------------------------------- - bool parseScheme(String& params, MaterialScriptContext& context) - { - context.technique->setSchemeName(params); - return false; - } - //----------------------------------------------------------------------- - bool parseGPUVendorRule(String& params, MaterialScriptContext& context) - { - Technique::GPUVendorRule rule; - StringVector vecparams = StringUtil::split(params, " \t"); - if (vecparams.size() != 2) - { - logParseError("Wrong number of parameters for gpu_vendor_rule, expected 2", context); - return false; - } - if (vecparams[0] == "include") - { - rule.includeOrExclude = Technique::INCLUDE; - } - else if (vecparams[0] == "exclude") - { - rule.includeOrExclude = Technique::EXCLUDE; - } - else - { - logParseError("Wrong parameter to gpu_vendor_rule, expected 'include' or 'exclude'", context); - return false; - } - - rule.vendor = RenderSystemCapabilities::vendorFromString(vecparams[1]); - if (rule.vendor == GPU_UNKNOWN) - { - logParseError("Unknown vendor '" + vecparams[1] + "' ignored in gpu_vendor_rule", context); - return false; - } - context.technique->addGPUVendorRule(rule); - return false; - } - //----------------------------------------------------------------------- - bool parseGPUDeviceRule(String& params, MaterialScriptContext& context) - { - Technique::GPUDeviceNameRule rule; - StringVector vecparams = StringUtil::split(params, " \t"); - if (vecparams.size() != 2 && vecparams.size() != 3) - { - logParseError("Wrong number of parameters for gpu_vendor_rule, expected 2 or 3", context); - return false; - } - if (vecparams[0] == "include") - { - rule.includeOrExclude = Technique::INCLUDE; - } - else if (vecparams[0] == "exclude") - { - rule.includeOrExclude = Technique::EXCLUDE; - } - else - { - logParseError("Wrong parameter to gpu_device_rule, expected 'include' or 'exclude'", context); - return false; - } - - rule.devicePattern = vecparams[1]; - if (vecparams.size() == 3) - rule.caseSensitive = StringConverter::parseBool(vecparams[2]); - - context.technique->addGPUDeviceNameRule(rule); - return false; - } - //----------------------------------------------------------------------- - bool parseShadowCasterMaterial(String& params, MaterialScriptContext& context) - { - context.technique->setShadowCasterMaterial(params); - return false; - } - //----------------------------------------------------------------------- - bool parseShadowReceiverMaterial(String& params, MaterialScriptContext& context) - { - context.technique->setShadowReceiverMaterial(params); - return false; - } + //----------------------------------------------------------------------- + bool parseScheme(String& params, MaterialScriptContext& context) + { + context.technique->setSchemeName(params); + return false; + } + //----------------------------------------------------------------------- + bool parseGPUVendorRule(String& params, MaterialScriptContext& context) + { + Technique::GPUVendorRule rule; + StringVector vecparams = StringUtil::split(params, " \t"); + if (vecparams.size() != 2) + { + logParseError("Wrong number of parameters for gpu_vendor_rule, expected 2", context); + return false; + } + if (vecparams[0] == "include") + { + rule.includeOrExclude = Technique::INCLUDE; + } + else if (vecparams[0] == "exclude") + { + rule.includeOrExclude = Technique::EXCLUDE; + } + else + { + logParseError("Wrong parameter to gpu_vendor_rule, expected 'include' or 'exclude'", context); + return false; + } + + rule.vendor = RenderSystemCapabilities::vendorFromString(vecparams[1]); + if (rule.vendor == GPU_UNKNOWN) + { + logParseError("Unknown vendor '" + vecparams[1] + "' ignored in gpu_vendor_rule", context); + return false; + } + context.technique->addGPUVendorRule(rule); + return false; + } + //----------------------------------------------------------------------- + bool parseGPUDeviceRule(String& params, MaterialScriptContext& context) + { + Technique::GPUDeviceNameRule rule; + StringVector vecparams = StringUtil::split(params, " \t"); + if (vecparams.size() != 2 && vecparams.size() != 3) + { + logParseError("Wrong number of parameters for gpu_vendor_rule, expected 2 or 3", context); + return false; + } + if (vecparams[0] == "include") + { + rule.includeOrExclude = Technique::INCLUDE; + } + else if (vecparams[0] == "exclude") + { + rule.includeOrExclude = Technique::EXCLUDE; + } + else + { + logParseError("Wrong parameter to gpu_device_rule, expected 'include' or 'exclude'", context); + return false; + } + + rule.devicePattern = vecparams[1]; + if (vecparams.size() == 3) + rule.caseSensitive = StringConverter::parseBool(vecparams[2]); + + context.technique->addGPUDeviceNameRule(rule); + return false; + } + //----------------------------------------------------------------------- + bool parseShadowCasterMaterial(String& params, MaterialScriptContext& context) + { + context.technique->setShadowCasterMaterial(params); + return false; + } + //----------------------------------------------------------------------- + bool parseShadowReceiverMaterial(String& params, MaterialScriptContext& context) + { + context.technique->setShadowReceiverMaterial(params); + return false; + } //----------------------------------------------------------------------- bool parseSetTextureAlias(String& params, MaterialScriptContext& context) { @@ -1936,7 +1936,7 @@ namespace Ogre return dims; } //----------------------------------------------------------------------- - void processManualProgramParam(bool isNamed, const String &commandname, + void processManualProgramParam(bool isNamed, const String &commandname, StringVector& vecparams, MaterialScriptContext& context, size_t index = 0, const String& paramName = BLANKSTRING) { @@ -2170,7 +2170,7 @@ namespace Ogre //----------------------------------------------------------------------- void processAutoProgramParam(bool isNamed, const String& commandname, StringVector& vecparams, MaterialScriptContext& context, - size_t index = 0, const String& paramName = BLANKSTRING) + size_t index = 0, const String& paramName = BLANKSTRING) { // NB we assume that the first element of vecparams is taken up with either // the index or the parameter name, which we ignore @@ -2184,67 +2184,67 @@ namespace Ogre // exit with error msg if the auto constant definition wasn't found if (!autoConstantDef) - { - logParseError("Invalid " + commandname + " attribute - " - + vecparams[1], context); - return; - } + { + logParseError("Invalid " + commandname + " attribute - " + + vecparams[1], context); + return; + } // add AutoConstant based on the type of data it uses switch (autoConstantDef->dataType) { case GpuProgramParameters::ACDT_NONE: - if (isNamed) - context.programParams->setNamedAutoConstant(paramName, autoConstantDef->acType, 0); - else - context.programParams->setAutoConstant(index, autoConstantDef->acType, 0); + if (isNamed) + context.programParams->setNamedAutoConstant(paramName, autoConstantDef->acType, 0); + else + context.programParams->setAutoConstant(index, autoConstantDef->acType, 0); break; case GpuProgramParameters::ACDT_INT: { - // Special case animation_parametric, we need to keep track of number of times used - if (autoConstantDef->acType == GpuProgramParameters::ACT_ANIMATION_PARAMETRIC) - { - if (isNamed) - context.programParams->setNamedAutoConstant( - paramName, autoConstantDef->acType, context.numAnimationParametrics++); - else - context.programParams->setAutoConstant( - index, autoConstantDef->acType, context.numAnimationParametrics++); - } - // Special case texture projector - assume 0 if data not specified - else if ((autoConstantDef->acType == GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX || - autoConstantDef->acType == GpuProgramParameters::ACT_TEXTURE_WORLDVIEWPROJ_MATRIX || - autoConstantDef->acType == GpuProgramParameters::ACT_SPOTLIGHT_VIEWPROJ_MATRIX || - autoConstantDef->acType == GpuProgramParameters::ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX) - && vecparams.size() == 2) - { - if (isNamed) - context.programParams->setNamedAutoConstant( - paramName, autoConstantDef->acType, 0); - else - context.programParams->setAutoConstant( - index, autoConstantDef->acType, 0); - - } - else - { - - if (vecparams.size() != 3) - { - logParseError("Invalid " + commandname + " attribute - " - "expected 3 parameters.", context); - return; - } - - size_t extraParam = StringConverter::parseInt(vecparams[2]); - if (isNamed) - context.programParams->setNamedAutoConstant( - paramName, autoConstantDef->acType, extraParam); - else - context.programParams->setAutoConstant( - index, autoConstantDef->acType, extraParam); - } + // Special case animation_parametric, we need to keep track of number of times used + if (autoConstantDef->acType == GpuProgramParameters::ACT_ANIMATION_PARAMETRIC) + { + if (isNamed) + context.programParams->setNamedAutoConstant( + paramName, autoConstantDef->acType, context.numAnimationParametrics++); + else + context.programParams->setAutoConstant( + index, autoConstantDef->acType, context.numAnimationParametrics++); + } + // Special case texture projector - assume 0 if data not specified + else if ((autoConstantDef->acType == GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX || + autoConstantDef->acType == GpuProgramParameters::ACT_TEXTURE_WORLDVIEWPROJ_MATRIX || + autoConstantDef->acType == GpuProgramParameters::ACT_SPOTLIGHT_VIEWPROJ_MATRIX || + autoConstantDef->acType == GpuProgramParameters::ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX) + && vecparams.size() == 2) + { + if (isNamed) + context.programParams->setNamedAutoConstant( + paramName, autoConstantDef->acType, 0); + else + context.programParams->setAutoConstant( + index, autoConstantDef->acType, 0); + + } + else + { + + if (vecparams.size() != 3) + { + logParseError("Invalid " + commandname + " attribute - " + "expected 3 parameters.", context); + return; + } + + size_t extraParam = StringConverter::parseInt(vecparams[2]); + if (isNamed) + context.programParams->setNamedAutoConstant( + paramName, autoConstantDef->acType, extraParam); + else + context.programParams->setAutoConstant( + index, autoConstantDef->acType, extraParam); + } } break; @@ -2260,12 +2260,12 @@ namespace Ogre factor = StringConverter::parseReal(vecparams[2]); } - if (isNamed) - context.programParams->setNamedAutoConstantReal(paramName, - autoConstantDef->acType, factor); - else - context.programParams->setAutoConstantReal(index, - autoConstantDef->acType, factor); + if (isNamed) + context.programParams->setNamedAutoConstantReal(paramName, + autoConstantDef->acType, factor); + else + context.programParams->setAutoConstantReal(index, + autoConstantDef->acType, factor); } else // normal processing for auto constants that take an extra real value { @@ -2276,13 +2276,13 @@ namespace Ogre return; } - Real rData = StringConverter::parseReal(vecparams[2]); - if (isNamed) - context.programParams->setNamedAutoConstantReal(paramName, - autoConstantDef->acType, rData); - else - context.programParams->setAutoConstantReal(index, - autoConstantDef->acType, rData); + Real rData = StringConverter::parseReal(vecparams[2]); + if (isNamed) + context.programParams->setNamedAutoConstantReal(paramName, + autoConstantDef->acType, rData); + else + context.programParams->setAutoConstantReal(index, + autoConstantDef->acType, rData); } } break; @@ -2393,8 +2393,8 @@ namespace Ogre // Get start index from name try { - const GpuConstantDefinition& def = - context.programParams->getConstantDefinition(vecparams[0]); + const GpuConstantDefinition& def = + context.programParams->getConstantDefinition(vecparams[0]); (void)def; // Silence warning } catch (Exception& e) @@ -2450,7 +2450,7 @@ namespace Ogre context.material->removeAllTechniques(); } - context.material->_notifyOrigin(context.filename); + context.material->_notifyOrigin(context.filename); // update section context.section = MSS_MATERIAL; @@ -2495,8 +2495,8 @@ namespace Ogre else { // no name was given in the script so a new technique will be created - // Increase technique level depth - ++context.techLev; + // Increase technique level depth + ++context.techLev; } // Create a new technique if it doesn't already exist @@ -2540,8 +2540,8 @@ namespace Ogre } else { - //Increase pass level depth - ++context.passLev; + //Increase pass level depth + ++context.passLev; } if (context.technique->getNumPasses() > context.passLev) @@ -2588,8 +2588,8 @@ namespace Ogre } else { - //Increase Texture Unit State level depth - ++context.stateLev; + //Increase Texture Unit State level depth + ++context.stateLev; } if (context.pass->getNumTextureUnitStates() > static_cast(context.stateLev)) @@ -2653,13 +2653,13 @@ namespace Ogre if (context.program->isSupported()) { context.programParams = context.pass->getVertexProgramParameters(); - context.numAnimationParametrics = 0; + context.numAnimationParametrics = 0; } // Return TRUE because this must be followed by a { return true; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- bool parseGeometryProgramRef(String& params, MaterialScriptContext& context) { // update section @@ -2702,7 +2702,7 @@ namespace Ogre if (context.program->isSupported()) { context.programParams = context.pass->getGeometryProgramParameters(); - context.numAnimationParametrics = 0; + context.numAnimationParametrics = 0; } // Return TRUE because this must be followed by a { @@ -2726,7 +2726,7 @@ namespace Ogre context.isVertexProgramShadowCaster = true; context.isFragmentProgramShadowCaster = false; context.isVertexProgramShadowReceiver = false; - context.isFragmentProgramShadowReceiver = false; + context.isFragmentProgramShadowReceiver = false; // Set the vertex program for this pass context.pass->setShadowCasterVertexProgram(params); @@ -2735,7 +2735,7 @@ namespace Ogre if (context.program->isSupported()) { context.programParams = context.pass->getShadowCasterVertexProgramParameters(); - context.numAnimationParametrics = 0; + context.numAnimationParametrics = 0; } // Return TRUE because this must be followed by a { @@ -2759,7 +2759,7 @@ namespace Ogre context.isVertexProgramShadowCaster = false; context.isFragmentProgramShadowCaster = true; context.isVertexProgramShadowReceiver = false; - context.isFragmentProgramShadowReceiver = false; + context.isFragmentProgramShadowReceiver = false; // Set the vertex program for this pass context.pass->setShadowCasterFragmentProgram(params); @@ -2768,7 +2768,7 @@ namespace Ogre if (context.program->isSupported()) { context.programParams = context.pass->getShadowCasterFragmentProgramParameters(); - context.numAnimationParametrics = 0; + context.numAnimationParametrics = 0; } // Return TRUE because this must be followed by a { @@ -2793,7 +2793,7 @@ namespace Ogre context.isVertexProgramShadowCaster = false; context.isFragmentProgramShadowCaster = false; context.isVertexProgramShadowReceiver = true; - context.isFragmentProgramShadowReceiver = false; + context.isFragmentProgramShadowReceiver = false; // Set the vertex program for this pass context.pass->setShadowReceiverVertexProgram(params); @@ -2802,46 +2802,46 @@ namespace Ogre if (context.program->isSupported()) { context.programParams = context.pass->getShadowReceiverVertexProgramParameters(); - context.numAnimationParametrics = 0; + context.numAnimationParametrics = 0; } // Return TRUE because this must be followed by a { return true; } - //----------------------------------------------------------------------- - bool parseShadowReceiverFragmentProgramRef(String& params, MaterialScriptContext& context) - { - // update section - context.section = MSS_PROGRAM_REF; + //----------------------------------------------------------------------- + bool parseShadowReceiverFragmentProgramRef(String& params, MaterialScriptContext& context) + { + // update section + context.section = MSS_PROGRAM_REF; - context.program = GpuProgramManager::getSingleton().getByName(params); - if (context.program.isNull()) - { - // Unknown program - logParseError("Invalid shadow_receiver_fragment_program_ref entry - fragment program " - + params + " has not been defined.", context); - return true; - } + context.program = GpuProgramManager::getSingleton().getByName(params); + if (context.program.isNull()) + { + // Unknown program + logParseError("Invalid shadow_receiver_fragment_program_ref entry - fragment program " + + params + " has not been defined.", context); + return true; + } context.isVertexProgramShadowCaster = false; context.isFragmentProgramShadowCaster = false; - context.isVertexProgramShadowReceiver = false; - context.isFragmentProgramShadowReceiver = true; + context.isVertexProgramShadowReceiver = false; + context.isFragmentProgramShadowReceiver = true; - // Set the vertex program for this pass - context.pass->setShadowReceiverFragmentProgram(params); + // Set the vertex program for this pass + context.pass->setShadowReceiverFragmentProgram(params); - // Create params? Skip this if program is not supported - if (context.program->isSupported()) - { - context.programParams = context.pass->getShadowReceiverFragmentProgramParameters(); - context.numAnimationParametrics = 0; - } + // Create params? Skip this if program is not supported + if (context.program->isSupported()) + { + context.programParams = context.pass->getShadowReceiverFragmentProgramParameters(); + context.numAnimationParametrics = 0; + } - // Return TRUE because this must be followed by a { - return true; - } + // Return TRUE because this must be followed by a { + return true; + } //----------------------------------------------------------------------- bool parseFragmentProgramRef(String& params, MaterialScriptContext& context) { @@ -2880,7 +2880,7 @@ namespace Ogre if (context.program->isSupported()) { context.programParams = context.pass->getFragmentProgramParameters(); - context.numAnimationParametrics = 0; + context.numAnimationParametrics = 0; } // Return TRUE because this must be followed by a { @@ -2892,102 +2892,102 @@ namespace Ogre // update section context.section = MSS_PROGRAM; - // Create new program definition-in-progress - context.programDef = OGRE_NEW_T(MaterialScriptProgramDefinition, MEMCATEGORY_SCRIPTING)(); - context.programDef->progType = GPT_VERTEX_PROGRAM; + // Create new program definition-in-progress + context.programDef = OGRE_NEW_T(MaterialScriptProgramDefinition, MEMCATEGORY_SCRIPTING)(); + context.programDef->progType = GPT_VERTEX_PROGRAM; context.programDef->supportsSkeletalAnimation = false; - context.programDef->supportsMorphAnimation = false; - context.programDef->supportsPoseAnimation = 0; - context.programDef->usesVertexTextureFetch = false; - - // Get name and language code - StringVector vecparams = StringUtil::split(params, " \t"); - if (vecparams.size() != 2) - { + context.programDef->supportsMorphAnimation = false; + context.programDef->supportsPoseAnimation = 0; + context.programDef->usesVertexTextureFetch = false; + + // Get name and language code + StringVector vecparams = StringUtil::split(params, " \t"); + if (vecparams.size() != 2) + { logParseError("Invalid vertex_program entry - expected " - "2 parameters.", context); + "2 parameters.", context); return true; - } - // Name, preserve case - context.programDef->name = vecparams[0]; - // language code, make lower case - context.programDef->language = vecparams[1]; - StringUtil::toLowerCase(context.programDef->language); + } + // Name, preserve case + context.programDef->name = vecparams[0]; + // language code, make lower case + context.programDef->language = vecparams[1]; + StringUtil::toLowerCase(context.programDef->language); // Return TRUE because this must be followed by a { return true; - } + } //----------------------------------------------------------------------- bool parseGeometryProgram(String& params, MaterialScriptContext& context) { // update section context.section = MSS_PROGRAM; - // Create new program definition-in-progress - context.programDef = OGRE_NEW_T(MaterialScriptProgramDefinition, MEMCATEGORY_SCRIPTING)(); - context.programDef->progType = GPT_GEOMETRY_PROGRAM; + // Create new program definition-in-progress + context.programDef = OGRE_NEW_T(MaterialScriptProgramDefinition, MEMCATEGORY_SCRIPTING)(); + context.programDef->progType = GPT_GEOMETRY_PROGRAM; context.programDef->supportsSkeletalAnimation = false; - context.programDef->supportsMorphAnimation = false; - context.programDef->supportsPoseAnimation = 0; - context.programDef->usesVertexTextureFetch = false; - - // Get name and language code - StringVector vecparams = StringUtil::split(params, " \t"); - if (vecparams.size() != 2) - { + context.programDef->supportsMorphAnimation = false; + context.programDef->supportsPoseAnimation = 0; + context.programDef->usesVertexTextureFetch = false; + + // Get name and language code + StringVector vecparams = StringUtil::split(params, " \t"); + if (vecparams.size() != 2) + { logParseError("Invalid geometry_program entry - expected " - "2 parameters.", context); + "2 parameters.", context); return true; - } - // Name, preserve case - context.programDef->name = vecparams[0]; - // language code, make lower case - context.programDef->language = vecparams[1]; - StringUtil::toLowerCase(context.programDef->language); + } + // Name, preserve case + context.programDef->name = vecparams[0]; + // language code, make lower case + context.programDef->language = vecparams[1]; + StringUtil::toLowerCase(context.programDef->language); // Return TRUE because this must be followed by a { return true; - } + } //----------------------------------------------------------------------- bool parseFragmentProgram(String& params, MaterialScriptContext& context) { // update section context.section = MSS_PROGRAM; - // Create new program definition-in-progress - context.programDef = OGRE_NEW_T(MaterialScriptProgramDefinition, MEMCATEGORY_SCRIPTING)(); - context.programDef->progType = GPT_FRAGMENT_PROGRAM; - context.programDef->supportsSkeletalAnimation = false; - context.programDef->supportsMorphAnimation = false; - context.programDef->supportsPoseAnimation = 0; - context.programDef->usesVertexTextureFetch = false; - - // Get name and language code - StringVector vecparams = StringUtil::split(params, " \t"); - if (vecparams.size() != 2) - { + // Create new program definition-in-progress + context.programDef = OGRE_NEW_T(MaterialScriptProgramDefinition, MEMCATEGORY_SCRIPTING)(); + context.programDef->progType = GPT_FRAGMENT_PROGRAM; + context.programDef->supportsSkeletalAnimation = false; + context.programDef->supportsMorphAnimation = false; + context.programDef->supportsPoseAnimation = 0; + context.programDef->usesVertexTextureFetch = false; + + // Get name and language code + StringVector vecparams = StringUtil::split(params, " \t"); + if (vecparams.size() != 2) + { logParseError("Invalid fragment_program entry - expected " - "2 parameters.", context); + "2 parameters.", context); return true; - } - // Name, preserve case - context.programDef->name = vecparams[0]; - // language code, make lower case - context.programDef->language = vecparams[1]; - StringUtil::toLowerCase(context.programDef->language); - - // Return TRUE because this must be followed by a { + } + // Name, preserve case + context.programDef->name = vecparams[0]; + // language code, make lower case + context.programDef->language = vecparams[1]; + StringUtil::toLowerCase(context.programDef->language); + + // Return TRUE because this must be followed by a { return true; - } + } //----------------------------------------------------------------------- bool parseProgramSource(String& params, MaterialScriptContext& context) { - // Source filename, preserve case - context.programDef->source = params; + // Source filename, preserve case + context.programDef->source = params; - return false; - } + return false; + } //----------------------------------------------------------------------- bool parseProgramSkeletalAnimation(String& params, MaterialScriptContext& context) { @@ -2997,82 +2997,82 @@ namespace Ogre return false; } - //----------------------------------------------------------------------- - bool parseProgramMorphAnimation(String& params, MaterialScriptContext& context) - { - // Source filename, preserve case - context.programDef->supportsMorphAnimation - = StringConverter::parseBool(params); - - return false; - } - //----------------------------------------------------------------------- - bool parseProgramPoseAnimation(String& params, MaterialScriptContext& context) - { - // Source filename, preserve case - context.programDef->supportsPoseAnimation - = (ushort)StringConverter::parseInt(params); - - return false; - } - //----------------------------------------------------------------------- - bool parseProgramVertexTextureFetch(String& params, MaterialScriptContext& context) - { - // Source filename, preserve case - context.programDef->usesVertexTextureFetch - = StringConverter::parseBool(params); - - return false; - } + //----------------------------------------------------------------------- + bool parseProgramMorphAnimation(String& params, MaterialScriptContext& context) + { + // Source filename, preserve case + context.programDef->supportsMorphAnimation + = StringConverter::parseBool(params); + + return false; + } + //----------------------------------------------------------------------- + bool parseProgramPoseAnimation(String& params, MaterialScriptContext& context) + { + // Source filename, preserve case + context.programDef->supportsPoseAnimation + = (ushort)StringConverter::parseInt(params); + + return false; + } + //----------------------------------------------------------------------- + bool parseProgramVertexTextureFetch(String& params, MaterialScriptContext& context) + { + // Source filename, preserve case + context.programDef->usesVertexTextureFetch + = StringConverter::parseBool(params); + + return false; + } //----------------------------------------------------------------------- bool parseProgramSyntax(String& params, MaterialScriptContext& context) { - // Syntax code, make lower case + // Syntax code, make lower case StringUtil::toLowerCase(params); - context.programDef->syntax = params; + context.programDef->syntax = params; - return false; - } + return false; + } //----------------------------------------------------------------------- bool parseProgramCustomParameter(String& params, MaterialScriptContext& context) { - // This params object does not have the command stripped - // Lower case the command, but not the value incase it's relevant - // Split only up to first delimiter, program deals with the rest - StringVector vecparams = StringUtil::split(params, " \t", 1); - if (vecparams.size() != 2) - { + // This params object does not have the command stripped + // Lower case the command, but not the value incase it's relevant + // Split only up to first delimiter, program deals with the rest + StringVector vecparams = StringUtil::split(params, " \t", 1); + if (vecparams.size() != 2) + { logParseError("Invalid custom program parameter entry; " - "there must be a parameter name and at least one value.", - context); + "there must be a parameter name and at least one value.", + context); return false; - } + } - context.programDef->customParameters.push_back( - std::pair(vecparams[0], vecparams[1])); + context.programDef->customParameters.push_back( + std::pair(vecparams[0], vecparams[1])); - return false; - } + return false; + } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- bool parseTextureSource(String& params, MaterialScriptContext& context) { - StringUtil::toLowerCase(params); + StringUtil::toLowerCase(params); StringVector vecparams = StringUtil::split(params, " \t"); if (vecparams.size() != 1) - logParseError("Invalid texture source attribute - expected 1 parameter.", context); + logParseError("Invalid texture source attribute - expected 1 parameter.", context); //The only param should identify which ExternalTextureSource is needed - ExternalTextureSourceManager::getSingleton().setCurrentPlugIn( vecparams[0] ); + ExternalTextureSourceManager::getSingleton().setCurrentPlugIn( vecparams[0] ); - if( ExternalTextureSourceManager::getSingleton().getCurrentPlugIn() != 0 ) - { - String tps; - tps = StringConverter::toString( context.techLev ) + " " - + StringConverter::toString( context.passLev ) + " " - + StringConverter::toString( context.stateLev); + if( ExternalTextureSourceManager::getSingleton().getCurrentPlugIn() != 0 ) + { + String tps; + tps = StringConverter::toString( context.techLev ) + " " + + StringConverter::toString( context.passLev ) + " " + + StringConverter::toString( context.stateLev); - ExternalTextureSourceManager::getSingleton().getCurrentPlugIn()->setParameter( "set_T_P_S", tps ); - } + ExternalTextureSourceManager::getSingleton().getCurrentPlugIn()->setParameter( "set_T_P_S", tps ); + } // update section context.section = MSS_TEXTURESOURCE; @@ -3083,23 +3083,23 @@ namespace Ogre //----------------------------------------------------------------------- bool parseTextureCustomParameter(String& params, MaterialScriptContext& context) { - // This params object does not have the command stripped - // Split only up to first delimiter, program deals with the rest - StringVector vecparams = StringUtil::split(params, " \t", 1); - if (vecparams.size() != 2) - { + // This params object does not have the command stripped + // Split only up to first delimiter, program deals with the rest + StringVector vecparams = StringUtil::split(params, " \t", 1); + if (vecparams.size() != 2) + { logParseError("Invalid texture parameter entry; " - "there must be a parameter name and at least one value.", - context); + "there must be a parameter name and at least one value.", + context); return false; - } + } - if( ExternalTextureSourceManager::getSingleton().getCurrentPlugIn() != 0 ) - ////First is command, next could be a string with one or more values - ExternalTextureSourceManager::getSingleton().getCurrentPlugIn()->setParameter( vecparams[0], vecparams[1] ); + if( ExternalTextureSourceManager::getSingleton().getCurrentPlugIn() != 0 ) + ////First is command, next could be a string with one or more values + ExternalTextureSourceManager::getSingleton().getCurrentPlugIn()->setParameter( vecparams[0], vecparams[1] ); - return false; - } + return false; + } //----------------------------------------------------------------------- bool parseReceiveShadows(String& params, MaterialScriptContext& context) { @@ -3124,22 +3124,22 @@ namespace Ogre return true; } - //----------------------------------------------------------------------- - bool parseTransparencyCastsShadows(String& params, MaterialScriptContext& context) - { + //----------------------------------------------------------------------- + bool parseTransparencyCastsShadows(String& params, MaterialScriptContext& context) + { StringUtil::toLowerCase(params); - if (params == "on") - context.material->setTransparencyCastsShadows(true); - else if (params == "off") - context.material->setTransparencyCastsShadows(false); - else - logParseError( - "Bad transparency_casts_shadows attribute, valid parameters are 'on' or 'off'.", - context); + if (params == "on") + context.material->setTransparencyCastsShadows(true); + else if (params == "off") + context.material->setTransparencyCastsShadows(false); + else + logParseError( + "Bad transparency_casts_shadows attribute, valid parameters are 'on' or 'off'.", + context); - return false; + return false; - } + } //----------------------------------------------------------------------- bool parseLodStrategy(String& params, MaterialScriptContext& context) { @@ -3175,14 +3175,14 @@ namespace Ogre return false; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- //----------------------------------------------------------------------- MaterialSerializer::MaterialSerializer() { // Set up root attribute parsers mRootAttribParsers.insert(AttribParserList::value_type("material", (ATTRIBUTE_PARSER)parseMaterial)); mRootAttribParsers.insert(AttribParserList::value_type("vertex_program", (ATTRIBUTE_PARSER)parseVertexProgram)); - mRootAttribParsers.insert(AttribParserList::value_type("geometry_program", (ATTRIBUTE_PARSER)parseGeometryProgram)); + mRootAttribParsers.insert(AttribParserList::value_type("geometry_program", (ATTRIBUTE_PARSER)parseGeometryProgram)); mRootAttribParsers.insert(AttribParserList::value_type("fragment_program", (ATTRIBUTE_PARSER)parseFragmentProgram)); // Set up material attribute parsers @@ -3190,17 +3190,17 @@ namespace Ogre mMaterialAttribParsers.insert(AttribParserList::value_type("lod_strategy", (ATTRIBUTE_PARSER)parseLodStrategy)); mMaterialAttribParsers.insert(AttribParserList::value_type("lod_distances", (ATTRIBUTE_PARSER)parseLodDistances)); mMaterialAttribParsers.insert(AttribParserList::value_type("receive_shadows", (ATTRIBUTE_PARSER)parseReceiveShadows)); - mMaterialAttribParsers.insert(AttribParserList::value_type("transparency_casts_shadows", (ATTRIBUTE_PARSER)parseTransparencyCastsShadows)); + mMaterialAttribParsers.insert(AttribParserList::value_type("transparency_casts_shadows", (ATTRIBUTE_PARSER)parseTransparencyCastsShadows)); mMaterialAttribParsers.insert(AttribParserList::value_type("technique", (ATTRIBUTE_PARSER)parseTechnique)); mMaterialAttribParsers.insert(AttribParserList::value_type("set_texture_alias", (ATTRIBUTE_PARSER)parseSetTextureAlias)); // Set up technique attribute parsers mTechniqueAttribParsers.insert(AttribParserList::value_type("lod_index", (ATTRIBUTE_PARSER)parseLodIndex)); - mTechniqueAttribParsers.insert(AttribParserList::value_type("shadow_caster_material", (ATTRIBUTE_PARSER)parseShadowCasterMaterial)); - mTechniqueAttribParsers.insert(AttribParserList::value_type("shadow_receiver_material", (ATTRIBUTE_PARSER)parseShadowReceiverMaterial)); - mTechniqueAttribParsers.insert(AttribParserList::value_type("scheme", (ATTRIBUTE_PARSER)parseScheme)); - mTechniqueAttribParsers.insert(AttribParserList::value_type("gpu_vendor_rule", (ATTRIBUTE_PARSER)parseGPUVendorRule)); - mTechniqueAttribParsers.insert(AttribParserList::value_type("gpu_device_rule", (ATTRIBUTE_PARSER)parseGPUDeviceRule)); + mTechniqueAttribParsers.insert(AttribParserList::value_type("shadow_caster_material", (ATTRIBUTE_PARSER)parseShadowCasterMaterial)); + mTechniqueAttribParsers.insert(AttribParserList::value_type("shadow_receiver_material", (ATTRIBUTE_PARSER)parseShadowReceiverMaterial)); + mTechniqueAttribParsers.insert(AttribParserList::value_type("scheme", (ATTRIBUTE_PARSER)parseScheme)); + mTechniqueAttribParsers.insert(AttribParserList::value_type("gpu_vendor_rule", (ATTRIBUTE_PARSER)parseGPUVendorRule)); + mTechniqueAttribParsers.insert(AttribParserList::value_type("gpu_device_rule", (ATTRIBUTE_PARSER)parseGPUDeviceRule)); mTechniqueAttribParsers.insert(AttribParserList::value_type("pass", (ATTRIBUTE_PARSER)parsePass)); // Set up pass attribute parsers @@ -3210,49 +3210,49 @@ namespace Ogre mPassAttribParsers.insert(AttribParserList::value_type("emissive", (ATTRIBUTE_PARSER)parseEmissive)); mPassAttribParsers.insert(AttribParserList::value_type("scene_blend", (ATTRIBUTE_PARSER)parseSceneBlend)); mPassAttribParsers.insert(AttribParserList::value_type("separate_scene_blend", (ATTRIBUTE_PARSER)parseSeparateSceneBlend)); - mPassAttribParsers.insert(AttribParserList::value_type("depth_check", (ATTRIBUTE_PARSER)parseDepthCheck)); + mPassAttribParsers.insert(AttribParserList::value_type("depth_check", (ATTRIBUTE_PARSER)parseDepthCheck)); mPassAttribParsers.insert(AttribParserList::value_type("depth_write", (ATTRIBUTE_PARSER)parseDepthWrite)); mPassAttribParsers.insert(AttribParserList::value_type("depth_func", (ATTRIBUTE_PARSER)parseDepthFunc)); - mPassAttribParsers.insert(AttribParserList::value_type("normalise_normals", (ATTRIBUTE_PARSER)parseNormaliseNormals)); - mPassAttribParsers.insert(AttribParserList::value_type("alpha_rejection", (ATTRIBUTE_PARSER)parseAlphaRejection)); - mPassAttribParsers.insert(AttribParserList::value_type("alpha_to_coverage", (ATTRIBUTE_PARSER)parseAlphaToCoverage)); - mPassAttribParsers.insert(AttribParserList::value_type("transparent_sorting", (ATTRIBUTE_PARSER)parseTransparentSorting)); + mPassAttribParsers.insert(AttribParserList::value_type("normalise_normals", (ATTRIBUTE_PARSER)parseNormaliseNormals)); + mPassAttribParsers.insert(AttribParserList::value_type("alpha_rejection", (ATTRIBUTE_PARSER)parseAlphaRejection)); + mPassAttribParsers.insert(AttribParserList::value_type("alpha_to_coverage", (ATTRIBUTE_PARSER)parseAlphaToCoverage)); + mPassAttribParsers.insert(AttribParserList::value_type("transparent_sorting", (ATTRIBUTE_PARSER)parseTransparentSorting)); mPassAttribParsers.insert(AttribParserList::value_type("colour_write", (ATTRIBUTE_PARSER)parseColourWrite)); - mPassAttribParsers.insert(AttribParserList::value_type("light_scissor", (ATTRIBUTE_PARSER)parseLightScissor)); - mPassAttribParsers.insert(AttribParserList::value_type("light_clip_planes", (ATTRIBUTE_PARSER)parseLightClip)); + mPassAttribParsers.insert(AttribParserList::value_type("light_scissor", (ATTRIBUTE_PARSER)parseLightScissor)); + mPassAttribParsers.insert(AttribParserList::value_type("light_clip_planes", (ATTRIBUTE_PARSER)parseLightClip)); mPassAttribParsers.insert(AttribParserList::value_type("cull_hardware", (ATTRIBUTE_PARSER)parseCullHardware)); mPassAttribParsers.insert(AttribParserList::value_type("cull_software", (ATTRIBUTE_PARSER)parseCullSoftware)); mPassAttribParsers.insert(AttribParserList::value_type("lighting", (ATTRIBUTE_PARSER)parseLighting)); mPassAttribParsers.insert(AttribParserList::value_type("fog_override", (ATTRIBUTE_PARSER)parseFogging)); mPassAttribParsers.insert(AttribParserList::value_type("shading", (ATTRIBUTE_PARSER)parseShading)); - mPassAttribParsers.insert(AttribParserList::value_type("polygon_mode", (ATTRIBUTE_PARSER)parsePolygonMode)); - mPassAttribParsers.insert(AttribParserList::value_type("polygon_mode_overrideable", (ATTRIBUTE_PARSER)parsePolygonModeOverrideable)); + mPassAttribParsers.insert(AttribParserList::value_type("polygon_mode", (ATTRIBUTE_PARSER)parsePolygonMode)); + mPassAttribParsers.insert(AttribParserList::value_type("polygon_mode_overrideable", (ATTRIBUTE_PARSER)parsePolygonModeOverrideable)); mPassAttribParsers.insert(AttribParserList::value_type("depth_bias", (ATTRIBUTE_PARSER)parseDepthBias)); - mPassAttribParsers.insert(AttribParserList::value_type("iteration_depth_bias", (ATTRIBUTE_PARSER)parseIterationDepthBias)); + mPassAttribParsers.insert(AttribParserList::value_type("iteration_depth_bias", (ATTRIBUTE_PARSER)parseIterationDepthBias)); mPassAttribParsers.insert(AttribParserList::value_type("texture_unit", (ATTRIBUTE_PARSER)parseTextureUnit)); mPassAttribParsers.insert(AttribParserList::value_type("vertex_program_ref", (ATTRIBUTE_PARSER)parseVertexProgramRef)); - mPassAttribParsers.insert(AttribParserList::value_type("geometry_program_ref", (ATTRIBUTE_PARSER)parseGeometryProgramRef)); + mPassAttribParsers.insert(AttribParserList::value_type("geometry_program_ref", (ATTRIBUTE_PARSER)parseGeometryProgramRef)); mPassAttribParsers.insert(AttribParserList::value_type("shadow_caster_vertex_program_ref", (ATTRIBUTE_PARSER)parseShadowCasterVertexProgramRef)); mPassAttribParsers.insert(AttribParserList::value_type("shadow_caster_fragment_program_ref", (ATTRIBUTE_PARSER)parseShadowCasterFragmentProgramRef)); mPassAttribParsers.insert(AttribParserList::value_type("shadow_receiver_vertex_program_ref", (ATTRIBUTE_PARSER)parseShadowReceiverVertexProgramRef)); - mPassAttribParsers.insert(AttribParserList::value_type("shadow_receiver_fragment_program_ref", (ATTRIBUTE_PARSER)parseShadowReceiverFragmentProgramRef)); + mPassAttribParsers.insert(AttribParserList::value_type("shadow_receiver_fragment_program_ref", (ATTRIBUTE_PARSER)parseShadowReceiverFragmentProgramRef)); mPassAttribParsers.insert(AttribParserList::value_type("fragment_program_ref", (ATTRIBUTE_PARSER)parseFragmentProgramRef)); mPassAttribParsers.insert(AttribParserList::value_type("max_lights", (ATTRIBUTE_PARSER)parseMaxLights)); - mPassAttribParsers.insert(AttribParserList::value_type("start_light", (ATTRIBUTE_PARSER)parseStartLight)); + mPassAttribParsers.insert(AttribParserList::value_type("start_light", (ATTRIBUTE_PARSER)parseStartLight)); mPassAttribParsers.insert(AttribParserList::value_type("iteration", (ATTRIBUTE_PARSER)parseIteration)); - mPassAttribParsers.insert(AttribParserList::value_type("point_size", (ATTRIBUTE_PARSER)parsePointSize)); - mPassAttribParsers.insert(AttribParserList::value_type("point_sprites", (ATTRIBUTE_PARSER)parsePointSprites)); - mPassAttribParsers.insert(AttribParserList::value_type("point_size_attenuation", (ATTRIBUTE_PARSER)parsePointAttenuation)); - mPassAttribParsers.insert(AttribParserList::value_type("point_size_min", (ATTRIBUTE_PARSER)parsePointSizeMin)); - mPassAttribParsers.insert(AttribParserList::value_type("point_size_max", (ATTRIBUTE_PARSER)parsePointSizeMax)); - mPassAttribParsers.insert(AttribParserList::value_type("illumination_stage", (ATTRIBUTE_PARSER)parseIlluminationStage)); + mPassAttribParsers.insert(AttribParserList::value_type("point_size", (ATTRIBUTE_PARSER)parsePointSize)); + mPassAttribParsers.insert(AttribParserList::value_type("point_sprites", (ATTRIBUTE_PARSER)parsePointSprites)); + mPassAttribParsers.insert(AttribParserList::value_type("point_size_attenuation", (ATTRIBUTE_PARSER)parsePointAttenuation)); + mPassAttribParsers.insert(AttribParserList::value_type("point_size_min", (ATTRIBUTE_PARSER)parsePointSizeMin)); + mPassAttribParsers.insert(AttribParserList::value_type("point_size_max", (ATTRIBUTE_PARSER)parsePointSizeMax)); + mPassAttribParsers.insert(AttribParserList::value_type("illumination_stage", (ATTRIBUTE_PARSER)parseIlluminationStage)); // Set up texture unit attribute parsers - mTextureUnitAttribParsers.insert(AttribParserList::value_type("texture_source", (ATTRIBUTE_PARSER)parseTextureSource)); + mTextureUnitAttribParsers.insert(AttribParserList::value_type("texture_source", (ATTRIBUTE_PARSER)parseTextureSource)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("texture", (ATTRIBUTE_PARSER)parseTexture)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("anim_texture", (ATTRIBUTE_PARSER)parseAnimTexture)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("cubic_texture", (ATTRIBUTE_PARSER)parseCubicTexture)); - mTextureUnitAttribParsers.insert(AttribParserList::value_type("binding_type", (ATTRIBUTE_PARSER)parseBindingType)); + mTextureUnitAttribParsers.insert(AttribParserList::value_type("binding_type", (ATTRIBUTE_PARSER)parseBindingType)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("tex_coord_set", (ATTRIBUTE_PARSER)parseTexCoord)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("tex_address_mode", (ATTRIBUTE_PARSER)parseTexAddressMode)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("tex_border_colour", (ATTRIBUTE_PARSER)parseTexBorderColour)); @@ -3267,14 +3267,14 @@ namespace Ogre mTextureUnitAttribParsers.insert(AttribParserList::value_type("rotate_anim", (ATTRIBUTE_PARSER)parseRotateAnim)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("scale", (ATTRIBUTE_PARSER)parseScale)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("wave_xform", (ATTRIBUTE_PARSER)parseWaveXform)); - mTextureUnitAttribParsers.insert(AttribParserList::value_type("transform", (ATTRIBUTE_PARSER)parseTransform)); + mTextureUnitAttribParsers.insert(AttribParserList::value_type("transform", (ATTRIBUTE_PARSER)parseTransform)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("filtering", (ATTRIBUTE_PARSER)parseFiltering)); - mTextureUnitAttribParsers.insert(AttribParserList::value_type("compare_test", (ATTRIBUTE_PARSER)parseCompareTest)); - mTextureUnitAttribParsers.insert(AttribParserList::value_type("compare_func", (ATTRIBUTE_PARSER)parseCompareFunction)); + mTextureUnitAttribParsers.insert(AttribParserList::value_type("compare_test", (ATTRIBUTE_PARSER)parseCompareTest)); + mTextureUnitAttribParsers.insert(AttribParserList::value_type("compare_func", (ATTRIBUTE_PARSER)parseCompareFunction)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("max_anisotropy", (ATTRIBUTE_PARSER)parseAnisotropy)); mTextureUnitAttribParsers.insert(AttribParserList::value_type("texture_alias", (ATTRIBUTE_PARSER)parseTextureAlias)); - mTextureUnitAttribParsers.insert(AttribParserList::value_type("mipmap_bias", (ATTRIBUTE_PARSER)parseMipmapBias)); - mTextureUnitAttribParsers.insert(AttribParserList::value_type("content_type", (ATTRIBUTE_PARSER)parseContentType)); + mTextureUnitAttribParsers.insert(AttribParserList::value_type("mipmap_bias", (ATTRIBUTE_PARSER)parseMipmapBias)); + mTextureUnitAttribParsers.insert(AttribParserList::value_type("content_type", (ATTRIBUTE_PARSER)parseContentType)); // Set up program reference attribute parsers mProgramRefAttribParsers.insert(AttribParserList::value_type("param_indexed", (ATTRIBUTE_PARSER)parseParamIndexed)); @@ -3305,9 +3305,9 @@ namespace Ogre mScriptContext.program.setNull(); mScriptContext.lineNo = 0; mScriptContext.filename.clear(); - mScriptContext.techLev = -1; - mScriptContext.passLev = -1; - mScriptContext.stateLev = -1; + mScriptContext.techLev = -1; + mScriptContext.passLev = -1; + mScriptContext.stateLev = -1; mDefaults = false; mBuffer.clear(); @@ -3326,11 +3326,11 @@ namespace Ogre mScriptContext.textureUnit = 0; mScriptContext.program.setNull(); mScriptContext.lineNo = 0; - mScriptContext.techLev = -1; - mScriptContext.passLev = -1; - mScriptContext.stateLev = -1; + mScriptContext.techLev = -1; + mScriptContext.passLev = -1; + mScriptContext.stateLev = -1; mScriptContext.filename = stream->getName(); - mScriptContext.groupName = groupName; + mScriptContext.groupName = groupName; while(!stream->eof()) { line = stream->getLine(); @@ -3367,8 +3367,8 @@ namespace Ogre logParseError("Unexpected end of file.", mScriptContext); } - // Make sure we invalidate our context shared pointer (don't want to hold on) - mScriptContext.material.setNull(); + // Make sure we invalidate our context shared pointer (don't want to hold on) + mScriptContext.material.setNull(); } //----------------------------------------------------------------------- @@ -3403,10 +3403,10 @@ namespace Ogre mScriptContext.section = MSS_NONE; mScriptContext.material.setNull(); - //Reset all levels for next material - mScriptContext.passLev = -1; - mScriptContext.stateLev= -1; - mScriptContext.techLev = -1; + //Reset all levels for next material + mScriptContext.passLev = -1; + mScriptContext.stateLev= -1; + mScriptContext.techLev = -1; mScriptContext.textureAliases.clear(); } else @@ -3421,7 +3421,7 @@ namespace Ogre // End of technique mScriptContext.section = MSS_MATERIAL; mScriptContext.technique = NULL; - mScriptContext.passLev = -1; //Reset pass level (yes, the pass level) + mScriptContext.passLev = -1; //Reset pass level (yes, the pass level) } else { @@ -3435,7 +3435,7 @@ namespace Ogre // End of pass mScriptContext.section = MSS_TECHNIQUE; mScriptContext.pass = NULL; - mScriptContext.stateLev = -1; //Reset state level (yes, the state level) + mScriptContext.stateLev = -1; //Reset state level (yes, the state level) } else { @@ -3456,24 +3456,24 @@ namespace Ogre return invokeParser(line, mTextureUnitAttribParsers); } break; - case MSS_TEXTURESOURCE: - if( line == "}" ) - { - //End texture source section - //Finish creating texture here - String sMaterialName = mScriptContext.material->getName(); - if( ExternalTextureSourceManager::getSingleton().getCurrentPlugIn() != 0) - ExternalTextureSourceManager::getSingleton().getCurrentPlugIn()-> - createDefinedTexture( sMaterialName, mScriptContext.groupName ); - //Revert back to texture unit - mScriptContext.section = MSS_TEXTUREUNIT; - } - else - { - // custom texture parameter, use original line - parseTextureCustomParameter(line, mScriptContext); - } - break; + case MSS_TEXTURESOURCE: + if( line == "}" ) + { + //End texture source section + //Finish creating texture here + String sMaterialName = mScriptContext.material->getName(); + if( ExternalTextureSourceManager::getSingleton().getCurrentPlugIn() != 0) + ExternalTextureSourceManager::getSingleton().getCurrentPlugIn()-> + createDefinedTexture( sMaterialName, mScriptContext.groupName ); + //Revert back to texture unit + mScriptContext.section = MSS_TEXTUREUNIT; + } + else + { + // custom texture parameter, use original line + parseTextureCustomParameter(line, mScriptContext); + } + break; case MSS_PROGRAM_REF: if (line == "}") { @@ -3488,12 +3488,12 @@ namespace Ogre } break; case MSS_PROGRAM: - // Program definitions are slightly different, they are deferred - // until all the information required is known + // Program definitions are slightly different, they are deferred + // until all the information required is known if (line == "}") { // End of program - finishProgramDefinition(); + finishProgramDefinition(); mScriptContext.section = MSS_NONE; OGRE_DELETE_T(mScriptContext.programDef, MaterialScriptProgramDefinition, MEMCATEGORY_SCRIPTING); mScriptContext.defaultParamLines.clear(); @@ -3502,23 +3502,23 @@ namespace Ogre else { // find & invoke a parser - // do this manually because we want to call a custom - // routine when the parser is not found - // First, split line on first divisor only - StringVector splitCmd = StringUtil::split(line, " \t", 1); - // Find attribute parser - AttribParserList::iterator iparser = mProgramAttribParsers.find(splitCmd[0]); - if (iparser == mProgramAttribParsers.end()) - { - // custom parameter, use original line - parseProgramCustomParameter(line, mScriptContext); - } - else - { + // do this manually because we want to call a custom + // routine when the parser is not found + // First, split line on first divisor only + StringVector splitCmd = StringUtil::split(line, " \t", 1); + // Find attribute parser + AttribParserList::iterator iparser = mProgramAttribParsers.find(splitCmd[0]); + if (iparser == mProgramAttribParsers.end()) + { + // custom parameter, use original line + parseProgramCustomParameter(line, mScriptContext); + } + else + { String cmd = splitCmd.size() >= 2? splitCmd[1]:BLANKSTRING; - // Use parser with remainder + // Use parser with remainder return iparser->second(cmd, mScriptContext ); - } + } } break; @@ -3541,89 +3541,89 @@ namespace Ogre return false; } //----------------------------------------------------------------------- - void MaterialSerializer::finishProgramDefinition(void) - { - // Now it is time to create the program and propagate the parameters - MaterialScriptProgramDefinition* def = mScriptContext.programDef; + void MaterialSerializer::finishProgramDefinition(void) + { + // Now it is time to create the program and propagate the parameters + MaterialScriptProgramDefinition* def = mScriptContext.programDef; GpuProgramPtr gp; - if (def->language == "asm") - { - // Native assembler - // Validate - if (def->source.empty()) - { - logParseError("Invalid program definition for " + def->name + - ", you must specify a source file.", mScriptContext); - } - if (def->syntax.empty()) - { - logParseError("Invalid program definition for " + def->name + - ", you must specify a syntax code.", mScriptContext); - } - // Create - gp = GpuProgramManager::getSingleton(). - createProgram(def->name, mScriptContext.groupName, def->source, + if (def->language == "asm") + { + // Native assembler + // Validate + if (def->source.empty()) + { + logParseError("Invalid program definition for " + def->name + + ", you must specify a source file.", mScriptContext); + } + if (def->syntax.empty()) + { + logParseError("Invalid program definition for " + def->name + + ", you must specify a syntax code.", mScriptContext); + } + // Create + gp = GpuProgramManager::getSingleton(). + createProgram(def->name, mScriptContext.groupName, def->source, def->progType, def->syntax); - } - else - { - // High-level program - // Validate - if (def->source.empty() && def->language != "unified") - { - logParseError("Invalid program definition for " + def->name + - ", you must specify a source file.", mScriptContext); - } - // Create + } + else + { + // High-level program + // Validate + if (def->source.empty() && def->language != "unified") + { + logParseError("Invalid program definition for " + def->name + + ", you must specify a source file.", mScriptContext); + } + // Create try { - HighLevelGpuProgramPtr hgp = HighLevelGpuProgramManager::getSingleton(). - createProgram(def->name, mScriptContext.groupName, + HighLevelGpuProgramPtr hgp = HighLevelGpuProgramManager::getSingleton(). + createProgram(def->name, mScriptContext.groupName, def->language, def->progType); // Assign to generalised version gp = hgp; // Set source file hgp->setSourceFile(def->source); - // Set custom parameters - vector >::type::const_iterator i, iend; - iend = def->customParameters.end(); - for (i = def->customParameters.begin(); i != iend; ++i) - { - if (!hgp->setParameter(i->first, i->second)) - { - logParseError("Error in program " + def->name + - " parameter " + i->first + " is not valid.", mScriptContext); - } - } + // Set custom parameters + vector >::type::const_iterator i, iend; + iend = def->customParameters.end(); + for (i = def->customParameters.begin(); i != iend; ++i) + { + if (!hgp->setParameter(i->first, i->second)) + { + logParseError("Error in program " + def->name + + " parameter " + i->first + " is not valid.", mScriptContext); + } + } } catch (Exception& e) { logParseError("Could not create GPU program '" + def->name + "', error reported was: " + e.getDescription(), mScriptContext); - mScriptContext.program.setNull(); - mScriptContext.programParams.setNull(); - return; + mScriptContext.program.setNull(); + mScriptContext.programParams.setNull(); + return; } } // Set skeletal animation option gp->setSkeletalAnimationIncluded(def->supportsSkeletalAnimation); - // Set morph animation option - gp->setMorphAnimationIncluded(def->supportsMorphAnimation); - // Set pose animation option - gp->setPoseAnimationIncluded(def->supportsPoseAnimation); - // Set vertex texture usage - gp->setVertexTextureFetchRequired(def->usesVertexTextureFetch); - // set origin - gp->_notifyOrigin(mScriptContext.filename); + // Set morph animation option + gp->setMorphAnimationIncluded(def->supportsMorphAnimation); + // Set pose animation option + gp->setPoseAnimationIncluded(def->supportsPoseAnimation); + // Set vertex texture usage + gp->setVertexTextureFetchRequired(def->usesVertexTextureFetch); + // set origin + gp->_notifyOrigin(mScriptContext.filename); // Set up to receive default parameters if (gp->isSupported() && !mScriptContext.defaultParamLines.empty()) { mScriptContext.programParams = gp->getDefaultParameters(); - mScriptContext.numAnimationParametrics = 0; + mScriptContext.numAnimationParametrics = 0; mScriptContext.program = gp; StringVector::iterator i, iend; iend = mScriptContext.defaultParamLines.end(); @@ -3651,9 +3651,9 @@ namespace Ogre mScriptContext.programParams.setNull(); } - } + } //----------------------------------------------------------------------- - bool MaterialSerializer::invokeParser(String& line, AttribParserList& parsers) + bool MaterialSerializer::invokeParser(String& line, AttribParserList& parsers) { // First, split line on first divisor only StringVector splitCmd(StringUtil::split(line, " \t", 1)); @@ -3728,7 +3728,7 @@ namespace Ogre } //----------------------------------------------------------------------- void MaterialSerializer::queueForExport(const MaterialPtr& pMat, - bool clearQueued, bool exportDefaults, const String& materialName) + bool clearQueued, bool exportDefaults, const String& materialName) { if (clearQueued) clearQueue(); @@ -3751,34 +3751,34 @@ namespace Ogre //----------------------------------------------------------------------- void MaterialSerializer::writeMaterial(const MaterialPtr& pMat, const String& materialName) { - String outMaterialName; + String outMaterialName; - if (materialName.length() > 0) - { - outMaterialName = materialName; - } - else - { - outMaterialName = pMat->getName(); - } + if (materialName.length() > 0) + { + outMaterialName = materialName; + } + else + { + outMaterialName = pMat->getName(); + } LogManager::getSingleton().logMessage("MaterialSerializer : writing material " + outMaterialName + " to queue.", LML_NORMAL); - bool skipWriting = false; + bool skipWriting = false; - // Fire pre-write event. - fireMaterialEvent(MSE_PRE_WRITE, skipWriting, pMat.get()); - if (skipWriting) - return; + // Fire pre-write event. + fireMaterialEvent(MSE_PRE_WRITE, skipWriting, pMat.get()); + if (skipWriting) + return; // Material name - writeAttribute(0, "material"); - writeValue(quoteWord(outMaterialName)); - + writeAttribute(0, "material"); + writeValue(quoteWord(outMaterialName)); + beginSection(0); { - // Fire write begin event. - fireMaterialEvent(MSE_WRITE_BEGIN, skipWriting, pMat.get()); + // Fire write begin event. + fireMaterialEvent(MSE_WRITE_BEGIN, skipWriting, pMat.get()); // Write LOD information Material::LodValueIterator valueIt = pMat->getUserLodValueIterator(); @@ -3807,13 +3807,13 @@ namespace Ogre writeValue(pMat->getReceiveShadows() ? "on" : "off"); } - // When rendering shadows, treat transparent things as opaque? - if (mDefaults || - pMat->getTransparencyCastsShadows() == true) - { - writeAttribute(1, "transparency_casts_shadows"); - writeValue(pMat->getTransparencyCastsShadows() ? "on" : "off"); - } + // When rendering shadows, treat transparent things as opaque? + if (mDefaults || + pMat->getTransparencyCastsShadows() == true) + { + writeAttribute(1, "transparency_casts_shadows"); + writeValue(pMat->getTransparencyCastsShadows() ? "on" : "off"); + } // Iterate over techniques Material::TechniqueIterator it = pMat->getTechniqueIterator(); @@ -3823,25 +3823,25 @@ namespace Ogre mBuffer += "\n"; } - // Fire write end event. - fireMaterialEvent(MSE_WRITE_END, skipWriting, pMat.get()); + // Fire write end event. + fireMaterialEvent(MSE_WRITE_END, skipWriting, pMat.get()); } endSection(0); mBuffer += "\n"; - // Fire post section write event. - fireMaterialEvent(MSE_POST_WRITE, skipWriting, pMat.get()); + // Fire post section write event. + fireMaterialEvent(MSE_POST_WRITE, skipWriting, pMat.get()); } //----------------------------------------------------------------------- void MaterialSerializer::writeTechnique(const Technique* pTech) { - bool skipWriting = false; + bool skipWriting = false; - // Fire pre-write event. - fireTechniqueEvent(MSE_PRE_WRITE, skipWriting, pTech); - if (skipWriting) - return; - + // Fire pre-write event. + fireTechniqueEvent(MSE_PRE_WRITE, skipWriting, pTech); + if (skipWriting) + return; + // Technique header writeAttribute(1, "technique"); // only output technique name if it exists. @@ -3850,62 +3850,62 @@ namespace Ogre beginSection(1); { - // Fire write begin event. - fireTechniqueEvent(MSE_WRITE_BEGIN, skipWriting, pTech); - - // LOD index - if (mDefaults || - pTech->getLodIndex() != 0) - { - writeAttribute(2, "lod_index"); - writeValue(StringConverter::toString(pTech->getLodIndex())); - } - - // Scheme name - if (mDefaults || - pTech->getSchemeName() != MaterialManager::DEFAULT_SCHEME_NAME) - { - writeAttribute(2, "scheme"); - writeValue(quoteWord(pTech->getSchemeName())); - } - - // ShadowCasterMaterial name - if (!pTech->getShadowCasterMaterial().isNull()) - { - writeAttribute(2, "shadow_caster_material"); - writeValue(quoteWord(pTech->getShadowCasterMaterial()->getName())); - } - // ShadowReceiverMaterial name - if (!pTech->getShadowReceiverMaterial().isNull()) - { - writeAttribute(2, "shadow_receiver_material"); - writeValue(quoteWord(pTech->getShadowReceiverMaterial()->getName())); - } - // GPU vendor rules - Technique::GPUVendorRuleIterator vrit = pTech->getGPUVendorRuleIterator(); - while (vrit.hasMoreElements()) - { - const Technique::GPUVendorRule& rule = vrit.getNext(); - writeAttribute(2, "gpu_vendor_rule"); - if (rule.includeOrExclude == Technique::INCLUDE) - writeValue("include"); - else - writeValue("exclude"); - writeValue(quoteWord(RenderSystemCapabilities::vendorToString(rule.vendor))); - } - // GPU device rules - Technique::GPUDeviceNameRuleIterator dnit = pTech->getGPUDeviceNameRuleIterator(); - while (dnit.hasMoreElements()) - { - const Technique::GPUDeviceNameRule& rule = dnit.getNext(); - writeAttribute(2, "gpu_device_rule"); - if (rule.includeOrExclude == Technique::INCLUDE) - writeValue("include"); - else - writeValue("exclude"); - writeValue(quoteWord(rule.devicePattern)); - writeValue(StringConverter::toString(rule.caseSensitive)); - } + // Fire write begin event. + fireTechniqueEvent(MSE_WRITE_BEGIN, skipWriting, pTech); + + // LOD index + if (mDefaults || + pTech->getLodIndex() != 0) + { + writeAttribute(2, "lod_index"); + writeValue(StringConverter::toString(pTech->getLodIndex())); + } + + // Scheme name + if (mDefaults || + pTech->getSchemeName() != MaterialManager::DEFAULT_SCHEME_NAME) + { + writeAttribute(2, "scheme"); + writeValue(quoteWord(pTech->getSchemeName())); + } + + // ShadowCasterMaterial name + if (!pTech->getShadowCasterMaterial().isNull()) + { + writeAttribute(2, "shadow_caster_material"); + writeValue(quoteWord(pTech->getShadowCasterMaterial()->getName())); + } + // ShadowReceiverMaterial name + if (!pTech->getShadowReceiverMaterial().isNull()) + { + writeAttribute(2, "shadow_receiver_material"); + writeValue(quoteWord(pTech->getShadowReceiverMaterial()->getName())); + } + // GPU vendor rules + Technique::GPUVendorRuleIterator vrit = pTech->getGPUVendorRuleIterator(); + while (vrit.hasMoreElements()) + { + const Technique::GPUVendorRule& rule = vrit.getNext(); + writeAttribute(2, "gpu_vendor_rule"); + if (rule.includeOrExclude == Technique::INCLUDE) + writeValue("include"); + else + writeValue("exclude"); + writeValue(quoteWord(RenderSystemCapabilities::vendorToString(rule.vendor))); + } + // GPU device rules + Technique::GPUDeviceNameRuleIterator dnit = pTech->getGPUDeviceNameRuleIterator(); + while (dnit.hasMoreElements()) + { + const Technique::GPUDeviceNameRule& rule = dnit.getNext(); + writeAttribute(2, "gpu_device_rule"); + if (rule.includeOrExclude == Technique::INCLUDE) + writeValue("include"); + else + writeValue("exclude"); + writeValue(quoteWord(rule.devicePattern)); + writeValue(StringConverter::toString(rule.caseSensitive)); + } // Iterate over passes Technique::PassIterator it = const_cast(pTech)->getPassIterator(); while (it.hasMoreElements()) @@ -3914,25 +3914,25 @@ namespace Ogre mBuffer += "\n"; } - // Fire write end event. - fireTechniqueEvent(MSE_WRITE_END, skipWriting, pTech); + // Fire write end event. + fireTechniqueEvent(MSE_WRITE_END, skipWriting, pTech); } endSection(1); - // Fire post section write event. - fireTechniqueEvent(MSE_POST_WRITE, skipWriting, pTech); + // Fire post section write event. + fireTechniqueEvent(MSE_POST_WRITE, skipWriting, pTech); } //----------------------------------------------------------------------- void MaterialSerializer::writePass(const Pass* pPass) { - bool skipWriting = false; + bool skipWriting = false; - // Fire pre-write event. - firePassEvent(MSE_PRE_WRITE, skipWriting, pPass); - if (skipWriting) - return; - + // Fire pre-write event. + firePassEvent(MSE_PRE_WRITE, skipWriting, pPass); + if (skipWriting) + return; + writeAttribute(2, "pass"); // only output pass name if its not the default name if (pPass->getName() != StringConverter::toString(pPass->getIndex())) @@ -3940,8 +3940,8 @@ namespace Ogre beginSection(2); { - // Fire write begin event. - firePassEvent(MSE_WRITE_BEGIN, skipWriting, pPass); + // Fire write begin event. + firePassEvent(MSE_WRITE_BEGIN, skipWriting, pPass); //lighting if (mDefaults || @@ -3950,21 +3950,21 @@ namespace Ogre writeAttribute(3, "lighting"); writeValue(pPass->getLightingEnabled() ? "on" : "off"); } - // max_lights + // max_lights if (mDefaults || pPass->getMaxSimultaneousLights() != OGRE_MAX_SIMULTANEOUS_LIGHTS) { writeAttribute(3, "max_lights"); writeValue(StringConverter::toString(pPass->getMaxSimultaneousLights())); } - // start_light - if (mDefaults || - pPass->getStartLight() != 0) - { - writeAttribute(3, "start_light"); - writeValue(StringConverter::toString(pPass->getStartLight())); - } - // iteration + // start_light + if (mDefaults || + pPass->getStartLight() != 0) + { + writeAttribute(3, "start_light"); + writeValue(StringConverter::toString(pPass->getStartLight())); + } + // iteration if (mDefaults || pPass->getIteratePerLight() || (pPass->getPassIterationCount() > 1)) { @@ -3974,18 +3974,18 @@ namespace Ogre { writeValue(StringConverter::toString(pPass->getPassIterationCount())); if (pPass->getIteratePerLight()) - { - if (pPass->getLightCountPerIteration() > 1) - { - writeValue("per_n_lights"); - writeValue(StringConverter::toString( - pPass->getLightCountPerIteration())); - } - else - { - writeValue("per_light"); - } - } + { + if (pPass->getLightCountPerIteration() > 1) + { + writeValue("per_n_lights"); + writeValue(StringConverter::toString( + pPass->getLightCountPerIteration())); + } + else + { + writeValue("per_light"); + } + } } else { @@ -4009,11 +4009,11 @@ namespace Ogre } } - if(mDefaults || pPass->getLightMask() != 0xFFFFFFFF) - { - writeAttribute(3, "light_mask"); - writeValue(StringConverter::toString(pPass->getLightMask())); - } + if(mDefaults || pPass->getLightMask() != 0xFFFFFFFF) + { + writeAttribute(3, "light_mask"); + writeValue(StringConverter::toString(pPass->getLightMask())); + } if (pPass->getLightingEnabled()) { @@ -4135,29 +4135,29 @@ namespace Ogre } // scene blend factor - if (pPass->hasSeparateSceneBlending()) - { - if (mDefaults || - pPass->getSourceBlendFactor() != SBF_ONE || - pPass->getDestBlendFactor() != SBF_ZERO || - pPass->getSourceBlendFactorAlpha() != SBF_ONE || - pPass->getDestBlendFactorAlpha() != SBF_ZERO) - { - writeAttribute(3, "separate_scene_blend"); - writeSceneBlendFactor(pPass->getSourceBlendFactor(), pPass->getDestBlendFactor(), - pPass->getSourceBlendFactorAlpha(), pPass->getDestBlendFactorAlpha()); - } - } - else - { - if (mDefaults || - pPass->getSourceBlendFactor() != SBF_ONE || - pPass->getDestBlendFactor() != SBF_ZERO) - { - writeAttribute(3, "scene_blend"); - writeSceneBlendFactor(pPass->getSourceBlendFactor(), pPass->getDestBlendFactor()); - } - } + if (pPass->hasSeparateSceneBlending()) + { + if (mDefaults || + pPass->getSourceBlendFactor() != SBF_ONE || + pPass->getDestBlendFactor() != SBF_ZERO || + pPass->getSourceBlendFactorAlpha() != SBF_ONE || + pPass->getDestBlendFactorAlpha() != SBF_ZERO) + { + writeAttribute(3, "separate_scene_blend"); + writeSceneBlendFactor(pPass->getSourceBlendFactor(), pPass->getDestBlendFactor(), + pPass->getSourceBlendFactorAlpha(), pPass->getDestBlendFactorAlpha()); + } + } + else + { + if (mDefaults || + pPass->getSourceBlendFactor() != SBF_ONE || + pPass->getDestBlendFactor() != SBF_ZERO) + { + writeAttribute(3, "scene_blend"); + writeSceneBlendFactor(pPass->getSourceBlendFactor(), pPass->getDestBlendFactor()); + } + } //depth check @@ -4167,31 +4167,31 @@ namespace Ogre writeAttribute(3, "depth_check"); writeValue(pPass->getDepthCheckEnabled() ? "on" : "off"); } - // alpha_rejection - if (mDefaults || - pPass->getAlphaRejectFunction() != CMPF_ALWAYS_PASS || - pPass->getAlphaRejectValue() != 0) - { - writeAttribute(3, "alpha_rejection"); - writeCompareFunction(pPass->getAlphaRejectFunction()); - writeValue(StringConverter::toString(pPass->getAlphaRejectValue())); - } - // alpha_to_coverage - if (mDefaults || - pPass->isAlphaToCoverageEnabled()) - { - writeAttribute(3, "alpha_to_coverage"); - writeValue(pPass->isAlphaToCoverageEnabled() ? "on" : "off"); - } - // transparent_sorting - if (mDefaults || - pPass->getTransparentSortingForced() == true || - pPass->getTransparentSortingEnabled() != true) - { - writeAttribute(3, "transparent_sorting"); - writeValue(pPass->getTransparentSortingForced() ? "force" : - (pPass->getTransparentSortingEnabled() ? "on" : "off")); - } + // alpha_rejection + if (mDefaults || + pPass->getAlphaRejectFunction() != CMPF_ALWAYS_PASS || + pPass->getAlphaRejectValue() != 0) + { + writeAttribute(3, "alpha_rejection"); + writeCompareFunction(pPass->getAlphaRejectFunction()); + writeValue(StringConverter::toString(pPass->getAlphaRejectValue())); + } + // alpha_to_coverage + if (mDefaults || + pPass->isAlphaToCoverageEnabled()) + { + writeAttribute(3, "alpha_to_coverage"); + writeValue(pPass->isAlphaToCoverageEnabled() ? "on" : "off"); + } + // transparent_sorting + if (mDefaults || + pPass->getTransparentSortingForced() == true || + pPass->getTransparentSortingEnabled() != true) + { + writeAttribute(3, "transparent_sorting"); + writeValue(pPass->getTransparentSortingForced() ? "force" : + (pPass->getTransparentSortingEnabled() ? "on" : "off")); + } //depth write @@ -4213,57 +4213,57 @@ namespace Ogre //depth bias if (mDefaults || pPass->getDepthBiasConstant() != 0 || - pPass->getDepthBiasSlopeScale() != 0) + pPass->getDepthBiasSlopeScale() != 0) { writeAttribute(3, "depth_bias"); writeValue(StringConverter::toString(pPass->getDepthBiasConstant())); - writeValue(StringConverter::toString(pPass->getDepthBiasSlopeScale())); - } - //iteration depth bias - if (mDefaults || - pPass->getIterationDepthBias() != 0) - { - writeAttribute(3, "iteration_depth_bias"); - writeValue(StringConverter::toString(pPass->getIterationDepthBias())); - } - - //light scissor - if (mDefaults || - pPass->getLightScissoringEnabled() != false) - { - writeAttribute(3, "light_scissor"); - writeValue(pPass->getLightScissoringEnabled() ? "on" : "off"); - } - - //light clip planes - if (mDefaults || - pPass->getLightClipPlanesEnabled() != false) - { - writeAttribute(3, "light_clip_planes"); - writeValue(pPass->getLightClipPlanesEnabled() ? "on" : "off"); - } - - // illumination stage - if (pPass->getIlluminationStage() != IS_UNKNOWN) - { - writeAttribute(3, "illumination_stage"); - switch(pPass->getIlluminationStage()) - { - case IS_AMBIENT: - writeValue("ambient"); - break; - case IS_PER_LIGHT: - writeValue("per_light"); - break; - case IS_DECAL: - writeValue("decal"); - break; + writeValue(StringConverter::toString(pPass->getDepthBiasSlopeScale())); + } + //iteration depth bias + if (mDefaults || + pPass->getIterationDepthBias() != 0) + { + writeAttribute(3, "iteration_depth_bias"); + writeValue(StringConverter::toString(pPass->getIterationDepthBias())); + } + + //light scissor + if (mDefaults || + pPass->getLightScissoringEnabled() != false) + { + writeAttribute(3, "light_scissor"); + writeValue(pPass->getLightScissoringEnabled() ? "on" : "off"); + } + + //light clip planes + if (mDefaults || + pPass->getLightClipPlanesEnabled() != false) + { + writeAttribute(3, "light_clip_planes"); + writeValue(pPass->getLightClipPlanesEnabled() ? "on" : "off"); + } + + // illumination stage + if (pPass->getIlluminationStage() != IS_UNKNOWN) + { + writeAttribute(3, "illumination_stage"); + switch(pPass->getIlluminationStage()) + { + case IS_AMBIENT: + writeValue("ambient"); + break; + case IS_PER_LIGHT: + writeValue("per_light"); + break; + case IS_DECAL: + writeValue("decal"); + break; case IS_UNKNOWN: break; - }; - } + }; + } - // hardware culling mode + // hardware culling mode if (mDefaults || pPass->getCullingMode() != CULL_CLOCKWISE) { @@ -4323,39 +4323,39 @@ namespace Ogre } - if (mDefaults || - pPass->getPolygonMode() != PM_SOLID) - { - writeAttribute(3, "polygon_mode"); - switch (pPass->getPolygonMode()) - { - case PM_POINTS: - writeValue("points"); - break; - case PM_WIREFRAME: - writeValue("wireframe"); - break; - case PM_SOLID: - writeValue("solid"); - break; - } - } - - // polygon mode overrideable - if (mDefaults || - !pPass->getPolygonModeOverrideable()) - { - writeAttribute(3, "polygon_mode_overrideable"); - writeValue(pPass->getPolygonModeOverrideable() ? "on" : "off"); - } - - // normalise normals - if (mDefaults || - pPass->getNormaliseNormals() != false) - { - writeAttribute(3, "normalise_normals"); - writeValue(pPass->getNormaliseNormals() ? "on" : "off"); - } + if (mDefaults || + pPass->getPolygonMode() != PM_SOLID) + { + writeAttribute(3, "polygon_mode"); + switch (pPass->getPolygonMode()) + { + case PM_POINTS: + writeValue("points"); + break; + case PM_WIREFRAME: + writeValue("wireframe"); + break; + case PM_SOLID: + writeValue("solid"); + break; + } + } + + // polygon mode overrideable + if (mDefaults || + !pPass->getPolygonModeOverrideable()) + { + writeAttribute(3, "polygon_mode_overrideable"); + writeValue(pPass->getPolygonModeOverrideable() ? "on" : "off"); + } + + // normalise normals + if (mDefaults || + pPass->getNormaliseNormals() != false) + { + writeAttribute(3, "normalise_normals"); + writeValue(pPass->getNormaliseNormals() ? "on" : "off"); + } //fog override if (mDefaults || @@ -4404,16 +4404,16 @@ namespace Ogre writeFragmentProgramRef(pPass); } - if(pPass->hasTessellationHullProgram()) - { - writeTesselationHullProgramRef(pPass); - } + if(pPass->hasTessellationHullProgram()) + { + writeTesselationHullProgramRef(pPass); + } - if(pPass->hasTessellationHullProgram()) - { - writeTesselationDomainProgramRef(pPass); - } - + if(pPass->hasTessellationHullProgram()) + { + writeTesselationDomainProgramRef(pPass); + } + if (pPass->hasGeometryProgram()) { writeGeometryProgramRef(pPass); @@ -4441,15 +4441,15 @@ namespace Ogre writeTextureUnit(it.getNext()); } - // Fire write end event. - firePassEvent(MSE_WRITE_END, skipWriting, pPass); + // Fire write end event. + firePassEvent(MSE_WRITE_END, skipWriting, pPass); } endSection(2); - - // Fire post section write event. - firePassEvent(MSE_POST_WRITE, skipWriting, pPass); - LogManager::getSingleton().logMessage("MaterialSerializer : done.", LML_NORMAL); + // Fire post section write event. + firePassEvent(MSE_POST_WRITE, skipWriting, pPass); + + LogManager::getSingleton().logMessage("MaterialSerializer : done.", LML_NORMAL); } //----------------------------------------------------------------------- String MaterialSerializer::convertFiltering(FilterOptions fo) @@ -4470,7 +4470,7 @@ namespace Ogre } //----------------------------------------------------------------------- String convertTexAddressMode(TextureUnitState::TextureAddressingMode tam) - { + { switch (tam) { case TextureUnitState::TAM_BORDER: @@ -4485,17 +4485,17 @@ namespace Ogre } return "wrap"; - } + } //----------------------------------------------------------------------- void MaterialSerializer::writeTextureUnit(const TextureUnitState *pTex) { - bool skipWriting = false; + bool skipWriting = false; - // Fire pre-write event. - fireTextureUnitStateEvent(MSE_PRE_WRITE, skipWriting, pTex); - if (skipWriting) - return; - + // Fire pre-write event. + fireTextureUnitStateEvent(MSE_PRE_WRITE, skipWriting, pTex); + if (skipWriting) + return; + LogManager::getSingleton().logMessage("MaterialSerializer : parsing texture layer.", LML_NORMAL); mBuffer += "\n"; writeAttribute(3, "texture_unit"); @@ -4505,8 +4505,8 @@ namespace Ogre beginSection(3); { - // Fire write begin event. - fireTextureUnitStateEvent(MSE_WRITE_BEGIN, skipWriting, pTex); + // Fire write begin event. + fireTextureUnitStateEvent(MSE_WRITE_BEGIN, skipWriting, pTex); // texture_alias if (!pTex->getTextureNameAlias().empty()) @@ -4595,12 +4595,12 @@ namespace Ogre } //addressing mode - const TextureUnitState::UVWAddressingMode& uvw = - pTex->getTextureAddressingMode(); + const TextureUnitState::UVWAddressingMode& uvw = + pTex->getTextureAddressingMode(); if (mDefaults || uvw.u != Ogre::TextureUnitState::TAM_WRAP || - uvw.v != Ogre::TextureUnitState::TAM_WRAP || - uvw.w != Ogre::TextureUnitState::TAM_WRAP ) + uvw.v != Ogre::TextureUnitState::TAM_WRAP || + uvw.w != Ogre::TextureUnitState::TAM_WRAP ) { writeAttribute(4, "tex_address_mode"); if (uvw.u == uvw.v && uvw.u == uvw.w) @@ -4643,14 +4643,14 @@ namespace Ogre + convertFiltering(pTex->getTextureFiltering(FT_MIP))); } - // Mip biasing - if (mDefaults || - pTex->getTextureMipmapBias() != 0.0f) - { - writeAttribute(4, "mipmap_bias"); - writeValue( - StringConverter::toString(pTex->getTextureMipmapBias())); - } + // Mip biasing + if (mDefaults || + pTex->getTextureMipmapBias() != 0.0f) + { + writeAttribute(4, "mipmap_bias"); + writeValue( + StringConverter::toString(pTex->getTextureMipmapBias())); + } // colour_op_ex if (mDefaults || @@ -4693,14 +4693,14 @@ namespace Ogre writeValue(StringConverter::toString(pTex->getAlphaBlendMode().alphaArg2)); } - bool individualTransformElems = false; + bool individualTransformElems = false; // rotate if (mDefaults || pTex->getTextureRotate() != Radian(0)) { writeAttribute(4, "rotate"); writeValue(StringConverter::toString(pTex->getTextureRotate().valueDegrees())); - individualTransformElems = true; + individualTransformElems = true; } // scroll @@ -4711,7 +4711,7 @@ namespace Ogre writeAttribute(4, "scroll"); writeValue(StringConverter::toString(pTex->getTextureUScroll())); writeValue(StringConverter::toString(pTex->getTextureVScroll())); - individualTransformElems = true; + individualTransformElems = true; } // scale if (mDefaults || @@ -4721,28 +4721,28 @@ namespace Ogre writeAttribute(4, "scale"); writeValue(StringConverter::toString(pTex->getTextureUScale())); writeValue(StringConverter::toString(pTex->getTextureVScale())); - individualTransformElems = true; - } - - // free transform - if (!individualTransformElems && - (mDefaults || - pTex->getTextureTransform() != Matrix4::IDENTITY)) - { - writeAttribute(4, "transform"); - const Matrix4& xform = pTex->getTextureTransform(); - for (int row = 0; row < 4; ++row) - { - for (int col = 0; col < 4; ++col) - { - writeValue(StringConverter::toString(xform[row][col])); - } - } - } - - // Used to store the u and v speeds of scroll animation effects - float scrollAnimU = 0; - float scrollAnimV = 0; + individualTransformElems = true; + } + + // free transform + if (!individualTransformElems && + (mDefaults || + pTex->getTextureTransform() != Matrix4::IDENTITY)) + { + writeAttribute(4, "transform"); + const Matrix4& xform = pTex->getTextureTransform(); + for (int row = 0; row < 4; ++row) + { + for (int col = 0; col < 4; ++col) + { + writeValue(StringConverter::toString(xform[row][col])); + } + } + } + + // Used to store the u and v speeds of scroll animation effects + float scrollAnimU = 0; + float scrollAnimV = 0; EffectMap effMap = pTex->getEffects(); if (!effMap.empty()) @@ -4759,14 +4759,14 @@ namespace Ogre case TextureUnitState::ET_ROTATE : writeRotationEffect(ef, pTex); break; - case TextureUnitState::ET_UVSCROLL : - scrollAnimU = scrollAnimV = ef.arg1; - break; + case TextureUnitState::ET_UVSCROLL : + scrollAnimU = scrollAnimV = ef.arg1; + break; case TextureUnitState::ET_USCROLL : - scrollAnimU = ef.arg1; - break; - case TextureUnitState::ET_VSCROLL : - scrollAnimV = ef.arg1; + scrollAnimU = ef.arg1; + break; + case TextureUnitState::ET_VSCROLL : + scrollAnimV = ef.arg1; break; case TextureUnitState::ET_TRANSFORM : writeTransformEffect(ef, pTex); @@ -4777,72 +4777,72 @@ namespace Ogre } } - // u and v scroll animation speeds merged, if present serialize scroll_anim - if(scrollAnimU || scrollAnimV) { - TextureUnitState::TextureEffect texEffect; - texEffect.arg1 = scrollAnimU; - texEffect.arg2 = scrollAnimV; - writeScrollEffect(texEffect, pTex); - } - - // Binding type - TextureUnitState::BindingType bt = pTex->getBindingType(); - if (mDefaults || - bt != TextureUnitState::BT_FRAGMENT) - { - writeAttribute(4, "binding_type"); - switch(bt) - { - case TextureUnitState::BT_FRAGMENT: - writeValue("fragment"); - break; - case TextureUnitState::BT_VERTEX: - writeValue("vertex"); - break; + // u and v scroll animation speeds merged, if present serialize scroll_anim + if(scrollAnimU || scrollAnimV) { + TextureUnitState::TextureEffect texEffect; + texEffect.arg1 = scrollAnimU; + texEffect.arg2 = scrollAnimV; + writeScrollEffect(texEffect, pTex); + } + + // Binding type + TextureUnitState::BindingType bt = pTex->getBindingType(); + if (mDefaults || + bt != TextureUnitState::BT_FRAGMENT) + { + writeAttribute(4, "binding_type"); + switch(bt) + { + case TextureUnitState::BT_FRAGMENT: + writeValue("fragment"); + break; + case TextureUnitState::BT_VERTEX: + writeValue("vertex"); + break; case TextureUnitState::BT_GEOMETRY: - writeValue("geometry"); - break; + writeValue("geometry"); + break; case TextureUnitState::BT_TESSELLATION_DOMAIN: - writeValue("tessellation_domain"); - break; + writeValue("tessellation_domain"); + break; case TextureUnitState::BT_TESSELLATION_HULL: - writeValue("tessellation_hull"); - break; + writeValue("tessellation_hull"); + break; case TextureUnitState::BT_COMPUTE: - writeValue("compute"); + writeValue("compute"); + break; + }; + + } + // Content type + if (mDefaults || + pTex->getContentType() != TextureUnitState::CONTENT_NAMED) + { + writeAttribute(4, "content_type"); + switch(pTex->getContentType()) + { + case TextureUnitState::CONTENT_NAMED: + writeValue("named"); + break; + case TextureUnitState::CONTENT_SHADOW: + writeValue("shadow"); break; - }; - - } - // Content type - if (mDefaults || - pTex->getContentType() != TextureUnitState::CONTENT_NAMED) - { - writeAttribute(4, "content_type"); - switch(pTex->getContentType()) - { - case TextureUnitState::CONTENT_NAMED: - writeValue("named"); - break; - case TextureUnitState::CONTENT_SHADOW: - writeValue("shadow"); - break; - case TextureUnitState::CONTENT_COMPOSITOR: - writeValue("compositor"); - writeValue(quoteWord(pTex->getReferencedCompositorName())); - writeValue(quoteWord(pTex->getReferencedTextureName())); - writeValue(StringConverter::toString(pTex->getReferencedMRTIndex())); - break; - }; - } - - // Fire write end event. - fireTextureUnitStateEvent(MSE_WRITE_END, skipWriting, pTex); + case TextureUnitState::CONTENT_COMPOSITOR: + writeValue("compositor"); + writeValue(quoteWord(pTex->getReferencedCompositorName())); + writeValue(quoteWord(pTex->getReferencedTextureName())); + writeValue(StringConverter::toString(pTex->getReferencedMRTIndex())); + break; + }; + } + + // Fire write end event. + fireTextureUnitStateEvent(MSE_WRITE_END, skipWriting, pTex); } endSection(3); - // Fire post section write event. - fireTextureUnitStateEvent(MSE_POST_WRITE, skipWriting, pTex); + // Fire post section write event. + fireTextureUnitStateEvent(MSE_POST_WRITE, skipWriting, pTex); } //----------------------------------------------------------------------- @@ -4927,7 +4927,7 @@ namespace Ogre } //----------------------------------------------------------------------- void MaterialSerializer::writeScrollEffect( - const TextureUnitState::TextureEffect& effect, const TextureUnitState *pTex) + const TextureUnitState::TextureEffect& effect, const TextureUnitState *pTex) { if (effect.arg1 || effect.arg2) { @@ -4990,14 +4990,14 @@ namespace Ogre writeSceneBlendFactor(sbf_dst); } } - //----------------------------------------------------------------------- - void MaterialSerializer::writeSceneBlendFactor( - const SceneBlendFactor c_src, const SceneBlendFactor c_dest, - const SceneBlendFactor a_src, const SceneBlendFactor a_dest) - { - writeSceneBlendFactor(c_src, c_dest); - writeSceneBlendFactor(a_src, a_dest); - } + //----------------------------------------------------------------------- + void MaterialSerializer::writeSceneBlendFactor( + const SceneBlendFactor c_src, const SceneBlendFactor c_dest, + const SceneBlendFactor a_src, const SceneBlendFactor a_dest) + { + writeSceneBlendFactor(c_src, c_dest); + writeSceneBlendFactor(a_src, a_dest); + } //----------------------------------------------------------------------- void MaterialSerializer::writeCompareFunction(const CompareFunction cf) { @@ -5124,13 +5124,13 @@ namespace Ogre void MaterialSerializer::writeTesselationHullProgramRef(const Pass* pPass) { writeGpuProgramRef("tesselation_hull_program_ref", - pPass->getTessellationHullProgram(), pPass->getTessellationHullProgramParameters()); + pPass->getTessellationHullProgram(), pPass->getTessellationHullProgramParameters()); } //----------------------------------------------------------------------- void MaterialSerializer::writeTesselationDomainProgramRef(const Pass* pPass) { writeGpuProgramRef("tesselation_domain_program_ref", - pPass->getTessellationDomainProgram(), pPass->getTessellationDomainProgramParameters()); + pPass->getTessellationDomainProgram(), pPass->getTessellationDomainProgramParameters()); } //----------------------------------------------------------------------- void MaterialSerializer::writeShadowCasterVertexProgramRef(const Pass* pPass) @@ -5160,7 +5160,7 @@ namespace Ogre void MaterialSerializer::writeGeometryProgramRef(const Pass* pPass) { writeGpuProgramRef("geometry_program_ref", - pPass->getGeometryProgram(), pPass->getGeometryProgramParameters()); + pPass->getGeometryProgram(), pPass->getGeometryProgramParameters()); } //-- //----------------------------------------------------------------------- @@ -5172,12 +5172,12 @@ namespace Ogre //----------------------------------------------------------------------- void MaterialSerializer::writeGpuProgramRef(const String& attrib, const GpuProgramPtr& program, const GpuProgramParametersSharedPtr& params) - { + { bool skipWriting = false; // Fire pre-write event. fireGpuProgramRefEvent(MSE_PRE_WRITE, skipWriting, attrib, program, params, NULL); - if (skipWriting) + if (skipWriting) return; mBuffer += "\n"; @@ -5205,7 +5205,7 @@ namespace Ogre mGpuProgramDefinitionContainer.insert(program->getName()); // Fire post section write event. - fireGpuProgramRefEvent(MSE_POST_WRITE, skipWriting, attrib, program, params, NULL); + fireGpuProgramRefEvent(MSE_POST_WRITE, skipWriting, attrib, program, params, NULL); } //----------------------------------------------------------------------- void MaterialSerializer::writeGPUProgramParameters( @@ -5688,104 +5688,104 @@ namespace Ogre mGpuProgramBuffer += "\n"; } - //--------------------------------------------------------------------- - void MaterialSerializer::addListener(Listener* listener) - { - mListeners.push_back(listener); - } - - //--------------------------------------------------------------------- - void MaterialSerializer::removeListener(Listener* listener) - { - ListenerListIterator i, iend; - iend = mListeners.end(); - for (i = mListeners.begin(); i != iend; ++i) - { - if (*i == listener) - { - mListeners.erase(i); - break; - } - } - } - - //--------------------------------------------------------------------- - void MaterialSerializer::fireMaterialEvent(SerializeEvent event, bool& skip, const Material* mat) - { - ListenerListIterator it = mListeners.begin(); - ListenerListIterator itEnd = mListeners.end(); - - while (it != itEnd) - { - (*it)->materialEventRaised(this, event, skip, mat); - if (skip) - break; - ++it; - } - } - - //--------------------------------------------------------------------- - void MaterialSerializer::fireTechniqueEvent(SerializeEvent event, bool& skip, const Technique* tech) - { - ListenerListIterator it = mListeners.begin(); - ListenerListIterator itEnd = mListeners.end(); - - while (it != itEnd) - { - (*it)->techniqueEventRaised(this, event, skip, tech); - if (skip) - break; - ++it; - } - } - - //--------------------------------------------------------------------- - void MaterialSerializer::firePassEvent(SerializeEvent event, bool& skip, const Pass* pass) - { - ListenerListIterator it = mListeners.begin(); - ListenerListIterator itEnd = mListeners.end(); - - while (it != itEnd) - { - (*it)->passEventRaised(this, event, skip, pass); - if (skip) - break; - ++it; - } - } - - //--------------------------------------------------------------------- - void MaterialSerializer::fireGpuProgramRefEvent(SerializeEvent event, bool& skip, - const String& attrib, - const GpuProgramPtr& program, - const GpuProgramParametersSharedPtr& params, - GpuProgramParameters* defaultParams) - { - ListenerListIterator it = mListeners.begin(); - ListenerListIterator itEnd = mListeners.end(); - - while (it != itEnd) - { - (*it)->gpuProgramRefEventRaised(this, event, skip, attrib, program, params, defaultParams); - if (skip) - break; - ++it; - } - } - - //--------------------------------------------------------------------- - void MaterialSerializer::fireTextureUnitStateEvent(SerializeEvent event, bool& skip, - const TextureUnitState* textureUnit) - { - ListenerListIterator it = mListeners.begin(); - ListenerListIterator itEnd = mListeners.end(); - - while (it != itEnd) - { - (*it)->textureUnitStateEventRaised(this, event, skip, textureUnit); - if (skip) - break; - ++it; - } - } + //--------------------------------------------------------------------- + void MaterialSerializer::addListener(Listener* listener) + { + mListeners.push_back(listener); + } + + //--------------------------------------------------------------------- + void MaterialSerializer::removeListener(Listener* listener) + { + ListenerListIterator i, iend; + iend = mListeners.end(); + for (i = mListeners.begin(); i != iend; ++i) + { + if (*i == listener) + { + mListeners.erase(i); + break; + } + } + } + + //--------------------------------------------------------------------- + void MaterialSerializer::fireMaterialEvent(SerializeEvent event, bool& skip, const Material* mat) + { + ListenerListIterator it = mListeners.begin(); + ListenerListIterator itEnd = mListeners.end(); + + while (it != itEnd) + { + (*it)->materialEventRaised(this, event, skip, mat); + if (skip) + break; + ++it; + } + } + + //--------------------------------------------------------------------- + void MaterialSerializer::fireTechniqueEvent(SerializeEvent event, bool& skip, const Technique* tech) + { + ListenerListIterator it = mListeners.begin(); + ListenerListIterator itEnd = mListeners.end(); + + while (it != itEnd) + { + (*it)->techniqueEventRaised(this, event, skip, tech); + if (skip) + break; + ++it; + } + } + + //--------------------------------------------------------------------- + void MaterialSerializer::firePassEvent(SerializeEvent event, bool& skip, const Pass* pass) + { + ListenerListIterator it = mListeners.begin(); + ListenerListIterator itEnd = mListeners.end(); + + while (it != itEnd) + { + (*it)->passEventRaised(this, event, skip, pass); + if (skip) + break; + ++it; + } + } + + //--------------------------------------------------------------------- + void MaterialSerializer::fireGpuProgramRefEvent(SerializeEvent event, bool& skip, + const String& attrib, + const GpuProgramPtr& program, + const GpuProgramParametersSharedPtr& params, + GpuProgramParameters* defaultParams) + { + ListenerListIterator it = mListeners.begin(); + ListenerListIterator itEnd = mListeners.end(); + + while (it != itEnd) + { + (*it)->gpuProgramRefEventRaised(this, event, skip, attrib, program, params, defaultParams); + if (skip) + break; + ++it; + } + } + + //--------------------------------------------------------------------- + void MaterialSerializer::fireTextureUnitStateEvent(SerializeEvent event, bool& skip, + const TextureUnitState* textureUnit) + { + ListenerListIterator it = mListeners.begin(); + ListenerListIterator itEnd = mListeners.end(); + + while (it != itEnd) + { + (*it)->textureUnitStateEventRaised(this, event, skip, textureUnit); + if (skip) + break; + ++it; + } + } } diff --git a/OgreMain/src/OgreMath.cpp b/OgreMain/src/OgreMath.cpp index 64f0abd5bd0..382dc5ba1a9 100644 --- a/OgreMain/src/OgreMath.cpp +++ b/OgreMain/src/OgreMath.cpp @@ -46,9 +46,9 @@ namespace Ogre const Real Math::PI = Real( 4.0 * atan( 1.0 ) ); const Real Math::TWO_PI = Real( 2.0 * PI ); const Real Math::HALF_PI = Real( 0.5 * PI ); - const Real Math::fDeg2Rad = PI / Real(180.0); - const Real Math::fRad2Deg = Real(180.0) / PI; - const Real Math::LOG2 = log(Real(2.0)); + const Real Math::fDeg2Rad = PI / Real(180.0); + const Real Math::fRad2Deg = Real(180.0) / PI; + const Real Math::LOG2 = log(Real(2.0)); int Math::mTrigTableSize; Math::AngleUnit Math::msAngleUnit; @@ -94,8 +94,8 @@ namespace Ogre mTanTable[i] = tan(angle); } } - //----------------------------------------------------------------------- - Real Math::SinTable (Real fValue) + //----------------------------------------------------------------------- + Real Math::SinTable (Real fValue) { // Convert range to index values, wrap if required int idx; @@ -110,12 +110,12 @@ namespace Ogre return mSinTable[idx]; } - //----------------------------------------------------------------------- - Real Math::TanTable (Real fValue) + //----------------------------------------------------------------------- + Real Math::TanTable (Real fValue) { // Convert range to index values, wrap if required - int idx = int(fValue *= mTrigTableFactor) % mTrigTableSize; - return mTanTable[idx]; + int idx = int(fValue *= mTrigTableFactor) % mTrigTableSize; + return mTanTable[idx]; } //----------------------------------------------------------------------- int Math::ISign (int iValue) @@ -242,101 +242,101 @@ namespace Ogre } //----------------------------------------------------------------------- - bool Math::pointInTri2D(const Vector2& p, const Vector2& a, - const Vector2& b, const Vector2& c) + bool Math::pointInTri2D(const Vector2& p, const Vector2& a, + const Vector2& b, const Vector2& c) { - // Winding must be consistent from all edges for point to be inside - Vector2 v1, v2; - Real dot[3]; - bool zeroDot[3]; + // Winding must be consistent from all edges for point to be inside + Vector2 v1, v2; + Real dot[3]; + bool zeroDot[3]; - v1 = b - a; - v2 = p - a; + v1 = b - a; + v2 = p - a; - // Note we don't care about normalisation here since sign is all we need - // It means we don't have to worry about magnitude of cross products either - dot[0] = v1.crossProduct(v2); - zeroDot[0] = Math::RealEqual(dot[0], 0.0f, 1e-3); + // Note we don't care about normalisation here since sign is all we need + // It means we don't have to worry about magnitude of cross products either + dot[0] = v1.crossProduct(v2); + zeroDot[0] = Math::RealEqual(dot[0], 0.0f, 1e-3); - v1 = c - b; - v2 = p - b; + v1 = c - b; + v2 = p - b; - dot[1] = v1.crossProduct(v2); - zeroDot[1] = Math::RealEqual(dot[1], 0.0f, 1e-3); + dot[1] = v1.crossProduct(v2); + zeroDot[1] = Math::RealEqual(dot[1], 0.0f, 1e-3); - // Compare signs (ignore colinear / coincident points) - if(!zeroDot[0] && !zeroDot[1] - && Math::Sign(dot[0]) != Math::Sign(dot[1])) - { - return false; - } + // Compare signs (ignore colinear / coincident points) + if(!zeroDot[0] && !zeroDot[1] + && Math::Sign(dot[0]) != Math::Sign(dot[1])) + { + return false; + } - v1 = a - c; - v2 = p - c; + v1 = a - c; + v2 = p - c; - dot[2] = v1.crossProduct(v2); - zeroDot[2] = Math::RealEqual(dot[2], 0.0f, 1e-3); - // Compare signs (ignore colinear / coincident points) - if((!zeroDot[0] && !zeroDot[2] - && Math::Sign(dot[0]) != Math::Sign(dot[2])) || - (!zeroDot[1] && !zeroDot[2] - && Math::Sign(dot[1]) != Math::Sign(dot[2]))) - { - return false; - } + dot[2] = v1.crossProduct(v2); + zeroDot[2] = Math::RealEqual(dot[2], 0.0f, 1e-3); + // Compare signs (ignore colinear / coincident points) + if((!zeroDot[0] && !zeroDot[2] + && Math::Sign(dot[0]) != Math::Sign(dot[2])) || + (!zeroDot[1] && !zeroDot[2] + && Math::Sign(dot[1]) != Math::Sign(dot[2]))) + { + return false; + } - return true; + return true; } - //----------------------------------------------------------------------- - bool Math::pointInTri3D(const Vector3& p, const Vector3& a, - const Vector3& b, const Vector3& c, const Vector3& normal) - { + //----------------------------------------------------------------------- + bool Math::pointInTri3D(const Vector3& p, const Vector3& a, + const Vector3& b, const Vector3& c, const Vector3& normal) + { // Winding must be consistent from all edges for point to be inside - Vector3 v1, v2; - Real dot[3]; - bool zeroDot[3]; + Vector3 v1, v2; + Real dot[3]; + bool zeroDot[3]; v1 = b - a; v2 = p - a; - // Note we don't care about normalisation here since sign is all we need - // It means we don't have to worry about magnitude of cross products either + // Note we don't care about normalisation here since sign is all we need + // It means we don't have to worry about magnitude of cross products either dot[0] = v1.crossProduct(v2).dotProduct(normal); - zeroDot[0] = Math::RealEqual(dot[0], 0.0f, 1e-3); + zeroDot[0] = Math::RealEqual(dot[0], 0.0f, 1e-3); v1 = c - b; v2 = p - b; - dot[1] = v1.crossProduct(v2).dotProduct(normal); - zeroDot[1] = Math::RealEqual(dot[1], 0.0f, 1e-3); + dot[1] = v1.crossProduct(v2).dotProduct(normal); + zeroDot[1] = Math::RealEqual(dot[1], 0.0f, 1e-3); - // Compare signs (ignore colinear / coincident points) - if(!zeroDot[0] && !zeroDot[1] - && Math::Sign(dot[0]) != Math::Sign(dot[1])) - { + // Compare signs (ignore colinear / coincident points) + if(!zeroDot[0] && !zeroDot[1] + && Math::Sign(dot[0]) != Math::Sign(dot[1])) + { return false; - } + } v1 = a - c; v2 = p - c; - dot[2] = v1.crossProduct(v2).dotProduct(normal); - zeroDot[2] = Math::RealEqual(dot[2], 0.0f, 1e-3); - // Compare signs (ignore colinear / coincident points) - if((!zeroDot[0] && !zeroDot[2] - && Math::Sign(dot[0]) != Math::Sign(dot[2])) || - (!zeroDot[1] && !zeroDot[2] - && Math::Sign(dot[1]) != Math::Sign(dot[2]))) - { - return false; - } + dot[2] = v1.crossProduct(v2).dotProduct(normal); + zeroDot[2] = Math::RealEqual(dot[2], 0.0f, 1e-3); + // Compare signs (ignore colinear / coincident points) + if((!zeroDot[0] && !zeroDot[2] + && Math::Sign(dot[0]) != Math::Sign(dot[2])) || + (!zeroDot[1] && !zeroDot[2] + && Math::Sign(dot[1]) != Math::Sign(dot[2]))) + { + return false; + } return true; - } + } //----------------------------------------------------------------------- bool Math::RealEqual( Real a, Real b, Real tolerance ) { @@ -368,95 +368,95 @@ namespace Ogre std::pair Math::intersects(const Ray& ray, const vector::type& planes, bool normalIsOutside) { - list::type planesList; - for (vector::type::const_iterator i = planes.begin(); i != planes.end(); ++i) - { - planesList.push_back(*i); - } - return intersects(ray, planesList, normalIsOutside); + list::type planesList; + for (vector::type::const_iterator i = planes.begin(); i != planes.end(); ++i) + { + planesList.push_back(*i); + } + return intersects(ray, planesList, normalIsOutside); } //----------------------------------------------------------------------- std::pair Math::intersects(const Ray& ray, const list::type& planes, bool normalIsOutside) { - list::type::const_iterator planeit, planeitend; - planeitend = planes.end(); - bool allInside = true; - std::pair ret; - std::pair end; - ret.first = false; - ret.second = 0.0f; - end.first = false; - end.second = 0; - - - // derive side - // NB we don't pass directly since that would require Plane::Side in - // interface, which results in recursive includes since Math is so fundamental - Plane::Side outside = normalIsOutside ? Plane::POSITIVE_SIDE : Plane::NEGATIVE_SIDE; - - for (planeit = planes.begin(); planeit != planeitend; ++planeit) - { - const Plane& plane = *planeit; - // is origin outside? - if (plane.getSide(ray.getOrigin()) == outside) - { - allInside = false; - // Test single plane - std::pair planeRes = - ray.intersects(plane); - if (planeRes.first) - { - // Ok, we intersected - ret.first = true; - // Use the most distant result since convex volume - ret.second = std::max(ret.second, planeRes.second); - } - else - { - ret.first =false; - ret.second=0.0f; - return ret; - } - } - else - { - std::pair planeRes = - ray.intersects(plane); - if (planeRes.first) - { - if( !end.first ) - { - end.first = true; - end.second = planeRes.second; - } - else - { - end.second = std::min( planeRes.second, end.second ); - } - - } - - } - } - - if (allInside) - { - // Intersecting at 0 distance since inside the volume! - ret.first = true; - ret.second = 0.0f; - return ret; - } - - if( end.first ) - { - if( end.second < ret.second ) - { - ret.first = false; - return ret; - } - } - return ret; + list::type::const_iterator planeit, planeitend; + planeitend = planes.end(); + bool allInside = true; + std::pair ret; + std::pair end; + ret.first = false; + ret.second = 0.0f; + end.first = false; + end.second = 0; + + + // derive side + // NB we don't pass directly since that would require Plane::Side in + // interface, which results in recursive includes since Math is so fundamental + Plane::Side outside = normalIsOutside ? Plane::POSITIVE_SIDE : Plane::NEGATIVE_SIDE; + + for (planeit = planes.begin(); planeit != planeitend; ++planeit) + { + const Plane& plane = *planeit; + // is origin outside? + if (plane.getSide(ray.getOrigin()) == outside) + { + allInside = false; + // Test single plane + std::pair planeRes = + ray.intersects(plane); + if (planeRes.first) + { + // Ok, we intersected + ret.first = true; + // Use the most distant result since convex volume + ret.second = std::max(ret.second, planeRes.second); + } + else + { + ret.first =false; + ret.second=0.0f; + return ret; + } + } + else + { + std::pair planeRes = + ray.intersects(plane); + if (planeRes.first) + { + if( !end.first ) + { + end.first = true; + end.second = planeRes.second; + } + else + { + end.second = std::min( planeRes.second, end.second ); + } + + } + + } + } + + if (allInside) + { + // Intersecting at 0 distance since inside the volume! + ret.first = true; + ret.second = 0.0f; + return ret; + } + + if( end.first ) + { + if( end.second < ret.second ) + { + ret.first = false; + return ret; + } + } + return ret; } //----------------------------------------------------------------------- std::pair Math::intersects(const Ray& ray, const Sphere& sphere, @@ -501,133 +501,133 @@ namespace Ogre } //----------------------------------------------------------------------- - std::pair Math::intersects(const Ray& ray, const AxisAlignedBox& box) - { - if (box.isNull()) return std::pair(false, (Real)0); - if (box.isInfinite()) return std::pair(true, (Real)0); - - Real lowt = 0.0f; - Real t; - bool hit = false; - Vector3 hitpoint; - const Vector3& min = box.getMinimum(); - const Vector3& max = box.getMaximum(); - const Vector3& rayorig = ray.getOrigin(); - const Vector3& raydir = ray.getDirection(); - - // Check origin inside first - if ( rayorig > min && rayorig < max ) - { - return std::pair(true, (Real)0); - } - - // Check each face in turn, only check closest 3 - // Min x - if (rayorig.x <= min.x && raydir.x > 0) - { - t = (min.x - rayorig.x) / raydir.x; - if (t >= 0) - { - // Substitute t back into ray and check bounds and dist - hitpoint = rayorig + raydir * t; - if (hitpoint.y >= min.y && hitpoint.y <= max.y && - hitpoint.z >= min.z && hitpoint.z <= max.z && - t < lowt) - { - hit = true; - lowt = t; - } - } - } - // Max x - if (rayorig.x >= max.x && raydir.x < 0) - { - t = (max.x - rayorig.x) / raydir.x; - if (t >= 0) - { - // Substitute t back into ray and check bounds and dist - hitpoint = rayorig + raydir * t; - if (hitpoint.y >= min.y && hitpoint.y <= max.y && - hitpoint.z >= min.z && hitpoint.z <= max.z && - (!hit || t < lowt)) - { - hit = true; - lowt = t; - } - } - } - // Min y - if (rayorig.y <= min.y && raydir.y > 0) - { - t = (min.y - rayorig.y) / raydir.y; - if (t >= 0) - { - // Substitute t back into ray and check bounds and dist - hitpoint = rayorig + raydir * t; - if (hitpoint.x >= min.x && hitpoint.x <= max.x && - hitpoint.z >= min.z && hitpoint.z <= max.z && - (!hit || t < lowt)) - { - hit = true; - lowt = t; - } - } - } - // Max y - if (rayorig.y >= max.y && raydir.y < 0) - { - t = (max.y - rayorig.y) / raydir.y; - if (t >= 0) - { - // Substitute t back into ray and check bounds and dist - hitpoint = rayorig + raydir * t; - if (hitpoint.x >= min.x && hitpoint.x <= max.x && - hitpoint.z >= min.z && hitpoint.z <= max.z && - (!hit || t < lowt)) - { - hit = true; - lowt = t; - } - } - } - // Min z - if (rayorig.z <= min.z && raydir.z > 0) - { - t = (min.z - rayorig.z) / raydir.z; - if (t >= 0) - { - // Substitute t back into ray and check bounds and dist - hitpoint = rayorig + raydir * t; - if (hitpoint.x >= min.x && hitpoint.x <= max.x && - hitpoint.y >= min.y && hitpoint.y <= max.y && - (!hit || t < lowt)) - { - hit = true; - lowt = t; - } - } - } - // Max z - if (rayorig.z >= max.z && raydir.z < 0) - { - t = (max.z - rayorig.z) / raydir.z; - if (t >= 0) - { - // Substitute t back into ray and check bounds and dist - hitpoint = rayorig + raydir * t; - if (hitpoint.x >= min.x && hitpoint.x <= max.x && - hitpoint.y >= min.y && hitpoint.y <= max.y && - (!hit || t < lowt)) - { - hit = true; - lowt = t; - } - } - } - - return std::pair(hit, (Real)lowt); - - } + std::pair Math::intersects(const Ray& ray, const AxisAlignedBox& box) + { + if (box.isNull()) return std::pair(false, (Real)0); + if (box.isInfinite()) return std::pair(true, (Real)0); + + Real lowt = 0.0f; + Real t; + bool hit = false; + Vector3 hitpoint; + const Vector3& min = box.getMinimum(); + const Vector3& max = box.getMaximum(); + const Vector3& rayorig = ray.getOrigin(); + const Vector3& raydir = ray.getDirection(); + + // Check origin inside first + if ( rayorig > min && rayorig < max ) + { + return std::pair(true, (Real)0); + } + + // Check each face in turn, only check closest 3 + // Min x + if (rayorig.x <= min.x && raydir.x > 0) + { + t = (min.x - rayorig.x) / raydir.x; + if (t >= 0) + { + // Substitute t back into ray and check bounds and dist + hitpoint = rayorig + raydir * t; + if (hitpoint.y >= min.y && hitpoint.y <= max.y && + hitpoint.z >= min.z && hitpoint.z <= max.z && + t < lowt) + { + hit = true; + lowt = t; + } + } + } + // Max x + if (rayorig.x >= max.x && raydir.x < 0) + { + t = (max.x - rayorig.x) / raydir.x; + if (t >= 0) + { + // Substitute t back into ray and check bounds and dist + hitpoint = rayorig + raydir * t; + if (hitpoint.y >= min.y && hitpoint.y <= max.y && + hitpoint.z >= min.z && hitpoint.z <= max.z && + (!hit || t < lowt)) + { + hit = true; + lowt = t; + } + } + } + // Min y + if (rayorig.y <= min.y && raydir.y > 0) + { + t = (min.y - rayorig.y) / raydir.y; + if (t >= 0) + { + // Substitute t back into ray and check bounds and dist + hitpoint = rayorig + raydir * t; + if (hitpoint.x >= min.x && hitpoint.x <= max.x && + hitpoint.z >= min.z && hitpoint.z <= max.z && + (!hit || t < lowt)) + { + hit = true; + lowt = t; + } + } + } + // Max y + if (rayorig.y >= max.y && raydir.y < 0) + { + t = (max.y - rayorig.y) / raydir.y; + if (t >= 0) + { + // Substitute t back into ray and check bounds and dist + hitpoint = rayorig + raydir * t; + if (hitpoint.x >= min.x && hitpoint.x <= max.x && + hitpoint.z >= min.z && hitpoint.z <= max.z && + (!hit || t < lowt)) + { + hit = true; + lowt = t; + } + } + } + // Min z + if (rayorig.z <= min.z && raydir.z > 0) + { + t = (min.z - rayorig.z) / raydir.z; + if (t >= 0) + { + // Substitute t back into ray and check bounds and dist + hitpoint = rayorig + raydir * t; + if (hitpoint.x >= min.x && hitpoint.x <= max.x && + hitpoint.y >= min.y && hitpoint.y <= max.y && + (!hit || t < lowt)) + { + hit = true; + lowt = t; + } + } + } + // Max z + if (rayorig.z >= max.z && raydir.z < 0) + { + t = (max.z - rayorig.z) / raydir.z; + if (t >= 0) + { + // Substitute t back into ray and check bounds and dist + hitpoint = rayorig + raydir * t; + if (hitpoint.x >= min.x && hitpoint.x <= max.x && + hitpoint.y >= min.y && hitpoint.y <= max.y && + (!hit || t < lowt)) + { + hit = true; + lowt = t; + } + } + } + + return std::pair(hit, (Real)lowt); + + } //----------------------------------------------------------------------- bool Math::intersects(const Ray& ray, const AxisAlignedBox& box, Real* d1, Real* d2) @@ -829,22 +829,22 @@ namespace Ogre const Vector3& min = box.getMinimum(); const Vector3& max = box.getMaximum(); - // Arvo's algorithm - Real s, d = 0; - for (int i = 0; i < 3; ++i) - { - if (center.ptr()[i] < min.ptr()[i]) - { - s = center.ptr()[i] - min.ptr()[i]; - d += s * s; - } - else if(center.ptr()[i] > max.ptr()[i]) - { - s = center.ptr()[i] - max.ptr()[i]; - d += s * s; - } - } - return d <= radius * radius; + // Arvo's algorithm + Real s, d = 0; + for (int i = 0; i < 3; ++i) + { + if (center.ptr()[i] < min.ptr()[i]) + { + s = center.ptr()[i] - min.ptr()[i]; + d += s * s; + } + else if(center.ptr()[i] > max.ptr()[i]) + { + s = center.ptr()[i] - max.ptr()[i]; + d += s * s; + } + } + return d <= radius * radius; } //----------------------------------------------------------------------- @@ -864,35 +864,35 @@ namespace Ogre const Vector3& position1, const Vector3& position2, const Vector3& position3, Real u1, Real v1, Real u2, Real v2, Real u3, Real v3) { - //side0 is the vector along one side of the triangle of vertices passed in, - //and side1 is the vector along another side. Taking the cross product of these returns the normal. - Vector3 side0 = position1 - position2; - Vector3 side1 = position3 - position1; - //Calculate face normal - Vector3 normal = side1.crossProduct(side0); - normal.normalise(); - //Now we use a formula to calculate the tangent. - Real deltaV0 = v1 - v2; - Real deltaV1 = v3 - v1; - Vector3 tangent = deltaV1 * side0 - deltaV0 * side1; - tangent.normalise(); - //Calculate binormal - Real deltaU0 = u1 - u2; - Real deltaU1 = u3 - u1; - Vector3 binormal = deltaU1 * side0 - deltaU0 * side1; - binormal.normalise(); - //Now, we take the cross product of the tangents to get a vector which - //should point in the same direction as our normal calculated above. - //If it points in the opposite direction (the dot product between the normals is less than zero), - //then we need to reverse the s and t tangents. - //This is because the triangle has been mirrored when going from tangent space to object space. - //reverse tangents if necessary - Vector3 tangentCross = tangent.crossProduct(binormal); - if (tangentCross.dotProduct(normal) < 0.0f) - { - tangent = -tangent; - binormal = -binormal; - } + //side0 is the vector along one side of the triangle of vertices passed in, + //and side1 is the vector along another side. Taking the cross product of these returns the normal. + Vector3 side0 = position1 - position2; + Vector3 side1 = position3 - position1; + //Calculate face normal + Vector3 normal = side1.crossProduct(side0); + normal.normalise(); + //Now we use a formula to calculate the tangent. + Real deltaV0 = v1 - v2; + Real deltaV1 = v3 - v1; + Vector3 tangent = deltaV1 * side0 - deltaV0 * side1; + tangent.normalise(); + //Calculate binormal + Real deltaU0 = u1 - u2; + Real deltaU1 = u3 - u1; + Vector3 binormal = deltaU1 * side0 - deltaU0 * side1; + binormal.normalise(); + //Now, we take the cross product of the tangents to get a vector which + //should point in the same direction as our normal calculated above. + //If it points in the opposite direction (the dot product between the normals is less than zero), + //then we need to reverse the s and t tangents. + //This is because the triangle has been mirrored when going from tangent space to object space. + //reverse tangents if necessary + Vector3 tangentCross = tangent.crossProduct(binormal); + if (tangentCross.dotProduct(normal) < 0.0f) + { + tangent = -tangent; + binormal = -binormal; + } return tangent; @@ -933,67 +933,67 @@ namespace Ogre Vector3 normal = (v2 - v1).crossProduct(v3 - v1); return normal; } - //----------------------------------------------------------------------- - Real Math::gaussianDistribution(Real x, Real offset, Real scale) - { - Real nom = Math::Exp( - -Math::Sqr(x - offset) / (2 * Math::Sqr(scale))); - Real denom = scale * Math::Sqrt(2 * Math::PI); - - return nom / denom; - - } - //--------------------------------------------------------------------- - Matrix4 Math::makeViewMatrix(const Vector3& position, const Quaternion& orientation, - const Matrix4* reflectMatrix) - { - Matrix4 viewMatrix; - - // View matrix is: - // - // [ Lx Uy Dz Tx ] - // [ Lx Uy Dz Ty ] - // [ Lx Uy Dz Tz ] - // [ 0 0 0 1 ] - // - // Where T = -(Transposed(Rot) * Pos) - - // This is most efficiently done using 3x3 Matrices - Matrix3 rot; - orientation.ToRotationMatrix(rot); - - // Make the translation relative to new axes - Matrix3 rotT = rot.Transpose(); - Vector3 trans = -rotT * position; - - // Make final matrix - viewMatrix = Matrix4::IDENTITY; - viewMatrix = rotT; // fills upper 3x3 - viewMatrix[0][3] = trans.x; - viewMatrix[1][3] = trans.y; - viewMatrix[2][3] = trans.z; - - // Deal with reflections - if (reflectMatrix) - { - viewMatrix = viewMatrix * (*reflectMatrix); - } - - return viewMatrix; - - } - //--------------------------------------------------------------------- - Real Math::boundingRadiusFromAABB(const AxisAlignedBox& aabb) - { - Vector3 max = aabb.getMaximum(); - Vector3 min = aabb.getMinimum(); - - Vector3 magnitude = max; - magnitude.makeCeil(-max); - magnitude.makeCeil(min); - magnitude.makeCeil(-min); - - return magnitude.length(); - } + //----------------------------------------------------------------------- + Real Math::gaussianDistribution(Real x, Real offset, Real scale) + { + Real nom = Math::Exp( + -Math::Sqr(x - offset) / (2 * Math::Sqr(scale))); + Real denom = scale * Math::Sqrt(2 * Math::PI); + + return nom / denom; + + } + //--------------------------------------------------------------------- + Matrix4 Math::makeViewMatrix(const Vector3& position, const Quaternion& orientation, + const Matrix4* reflectMatrix) + { + Matrix4 viewMatrix; + + // View matrix is: + // + // [ Lx Uy Dz Tx ] + // [ Lx Uy Dz Ty ] + // [ Lx Uy Dz Tz ] + // [ 0 0 0 1 ] + // + // Where T = -(Transposed(Rot) * Pos) + + // This is most efficiently done using 3x3 Matrices + Matrix3 rot; + orientation.ToRotationMatrix(rot); + + // Make the translation relative to new axes + Matrix3 rotT = rot.Transpose(); + Vector3 trans = -rotT * position; + + // Make final matrix + viewMatrix = Matrix4::IDENTITY; + viewMatrix = rotT; // fills upper 3x3 + viewMatrix[0][3] = trans.x; + viewMatrix[1][3] = trans.y; + viewMatrix[2][3] = trans.z; + + // Deal with reflections + if (reflectMatrix) + { + viewMatrix = viewMatrix * (*reflectMatrix); + } + + return viewMatrix; + + } + //--------------------------------------------------------------------- + Real Math::boundingRadiusFromAABB(const AxisAlignedBox& aabb) + { + Vector3 max = aabb.getMaximum(); + Vector3 min = aabb.getMinimum(); + + Vector3 magnitude = max; + magnitude.makeCeil(-max); + magnitude.makeCeil(min); + magnitude.makeCeil(-min); + + return magnitude.length(); + } } diff --git a/OgreMain/src/OgreMatrix3.cpp b/OgreMain/src/OgreMatrix3.cpp index 32c82ad7544..54b2464c1fd 100644 --- a/OgreMain/src/OgreMatrix3.cpp +++ b/OgreMain/src/OgreMatrix3.cpp @@ -389,7 +389,7 @@ namespace Ogre Real fY = kA[0][0] - (Math::Abs(fRoot1-fT22) <= Math::Abs(fRoot2-fT22) ? fRoot1 : fRoot2); Real fZ = kA[0][1]; - Real fInvLength = Math::InvSqrt(fY*fY+fZ*fZ); + Real fInvLength = Math::InvSqrt(fY*fY+fZ*fZ); Real fSin = fZ*fInvLength; Real fCos = -fY*fInvLength; @@ -483,7 +483,7 @@ namespace Ogre { // temas: currently unused //const int iMax = 16; - size_t iRow, iCol; + size_t iRow, iCol; Matrix3 kA = *this; Bidiagonalize(kA,kL,kR); @@ -731,7 +731,7 @@ namespace Ogre kQ[0][1] = m[0][1]-fDot*kQ[0][0]; kQ[1][1] = m[1][1]-fDot*kQ[1][0]; kQ[2][1] = m[2][1]-fDot*kQ[2][0]; - fInvLength = Math::InvSqrt(kQ[0][1]*kQ[0][1] + kQ[1][1]*kQ[1][1] + kQ[2][1]*kQ[2][1]); + fInvLength = Math::InvSqrt(kQ[0][1]*kQ[0][1] + kQ[1][1]*kQ[1][1] + kQ[2][1]*kQ[2][1]); kQ[0][1] *= fInvLength; kQ[1][1] *= fInvLength; @@ -749,7 +749,7 @@ namespace Ogre kQ[2][2] -= fDot*kQ[2][1]; fInvLength = Math::InvSqrt(kQ[0][2]*kQ[0][2] + kQ[1][2]*kQ[1][2] + kQ[2][2]*kQ[2][2]); - kQ[0][2] *= fInvLength; + kQ[0][2] *= fInvLength; kQ[1][2] *= fInvLength; kQ[2][2] *= fInvLength; diff --git a/OgreMain/src/OgreMatrix4.cpp b/OgreMain/src/OgreMatrix4.cpp index 62a0546ba2d..3b6fc57eca1 100644 --- a/OgreMain/src/OgreMatrix4.cpp +++ b/OgreMain/src/OgreMatrix4.cpp @@ -41,10 +41,10 @@ namespace Ogre 0, 0, 0, 0 ); const Matrix4 Matrix4::ZEROAFFINE( - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 1 ); + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1 ); const Matrix4 Matrix4::IDENTITY( 1, 0, 0, 0, @@ -61,7 +61,7 @@ namespace Ogre //----------------------------------------------------------------------- inline static Real MINOR(const Matrix4& m, const size_t r0, const size_t r1, const size_t r2, - const size_t c0, const size_t c1, const size_t c2) + const size_t c0, const size_t c1, const size_t c2) { return m[r0][c0] * (m[r1][c1] * m[r2][c2] - m[r2][c1] * m[r1][c2]) - m[r0][c1] * (m[r1][c0] * m[r2][c2] - m[r2][c0] * m[r1][c2]) + @@ -243,25 +243,25 @@ namespace Ogre // Set up final matrix with scale, rotation and translation m[0][0] = invScale.x * rot3x3[0][0]; m[0][1] = invScale.x * rot3x3[0][1]; m[0][2] = invScale.x * rot3x3[0][2]; m[0][3] = invTranslate.x; m[1][0] = invScale.y * rot3x3[1][0]; m[1][1] = invScale.y * rot3x3[1][1]; m[1][2] = invScale.y * rot3x3[1][2]; m[1][3] = invTranslate.y; - m[2][0] = invScale.z * rot3x3[2][0]; m[2][1] = invScale.z * rot3x3[2][1]; m[2][2] = invScale.z * rot3x3[2][2]; m[2][3] = invTranslate.z; + m[2][0] = invScale.z * rot3x3[2][0]; m[2][1] = invScale.z * rot3x3[2][1]; m[2][2] = invScale.z * rot3x3[2][2]; m[2][3] = invTranslate.z; // No projection term m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1; } //----------------------------------------------------------------------- - void Matrix4::decomposition(Vector3& position, Vector3& scale, Quaternion& orientation) const - { - assert(isAffine()); + void Matrix4::decomposition(Vector3& position, Vector3& scale, Quaternion& orientation) const + { + assert(isAffine()); - Matrix3 m3x3; - extract3x3Matrix(m3x3); + Matrix3 m3x3; + extract3x3Matrix(m3x3); - Matrix3 matQ; - Vector3 vecU; - m3x3.QDUDecomposition( matQ, scale, vecU ); + Matrix3 matQ; + Vector3 vecU; + m3x3.QDUDecomposition( matQ, scale, vecU ); - orientation = Quaternion( matQ ); - position = Vector3( m[0][3], m[1][3], m[2][3] ); - } + orientation = Quaternion( matQ ); + position = Vector3( m[0][3], m[1][3], m[2][3] ); + } } diff --git a/OgreMain/src/OgreMemoryAllocatedObject.cpp b/OgreMain/src/OgreMemoryAllocatedObject.cpp index 708f6b394ae..f49bfde92a2 100644 --- a/OgreMain/src/OgreMemoryAllocatedObject.cpp +++ b/OgreMain/src/OgreMemoryAllocatedObject.cpp @@ -30,26 +30,26 @@ THE SOFTWARE. namespace Ogre { - /* + /* - Ugh, I wish I didn't have to do this. + Ugh, I wish I didn't have to do this. - The problem is that operator new/delete are *implicitly* static. We have to - instantiate them for each combination exactly once throughout all the compilation - units that are linked together, and this appears to be the only way to do it. + The problem is that operator new/delete are *implicitly* static. We have to + instantiate them for each combination exactly once throughout all the compilation + units that are linked together, and this appears to be the only way to do it. - At least I can do it via templates. + At least I can do it via templates. - */ + */ - template class AllocatedObject; - template class AllocatedObject; - template class AllocatedObject; - template class AllocatedObject; - template class AllocatedObject; - template class AllocatedObject; - template class AllocatedObject; - template class AllocatedObject; + template class AllocatedObject; + template class AllocatedObject; + template class AllocatedObject; + template class AllocatedObject; + template class AllocatedObject; + template class AllocatedObject; + template class AllocatedObject; + template class AllocatedObject; diff --git a/OgreMain/src/OgreMemoryNedAlloc.cpp b/OgreMain/src/OgreMemoryNedAlloc.cpp index 49b0c5ab75e..744c67cc28b 100644 --- a/OgreMain/src/OgreMemoryNedAlloc.cpp +++ b/OgreMain/src/OgreMemoryNedAlloc.cpp @@ -41,53 +41,53 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - void* NedAllocImpl::allocBytes(size_t count, - const char* file, int line, const char* func) - { - void* ptr = nedalloc::nedmalloc(count); - #if OGRE_MEMORY_TRACKER - // this alloc policy doesn't do pools (yet, ned can do it) - MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); - #endif - return ptr; - } - //--------------------------------------------------------------------- - void NedAllocImpl::deallocBytes(void* ptr) - { - // deal with null - if (!ptr) - return; + //--------------------------------------------------------------------- + void* NedAllocImpl::allocBytes(size_t count, + const char* file, int line, const char* func) + { + void* ptr = nedalloc::nedmalloc(count); + #if OGRE_MEMORY_TRACKER + // this alloc policy doesn't do pools (yet, ned can do it) + MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); + #endif + return ptr; + } + //--------------------------------------------------------------------- + void NedAllocImpl::deallocBytes(void* ptr) + { + // deal with null + if (!ptr) + return; #if OGRE_MEMORY_TRACKER - MemoryTracker::get()._recordDealloc(ptr); + MemoryTracker::get()._recordDealloc(ptr); #endif - nedalloc::nedfree(ptr); - } - //--------------------------------------------------------------------- - void* NedAllocImpl::allocBytesAligned(size_t align, size_t count, - const char* file, int line, const char* func) - { - // default to platform SIMD alignment if none specified - void* ptr = align ? nedalloc::nedmemalign(align, count) - : nedalloc::nedmemalign(OGRE_SIMD_ALIGNMENT, count); + nedalloc::nedfree(ptr); + } + //--------------------------------------------------------------------- + void* NedAllocImpl::allocBytesAligned(size_t align, size_t count, + const char* file, int line, const char* func) + { + // default to platform SIMD alignment if none specified + void* ptr = align ? nedalloc::nedmemalign(align, count) + : nedalloc::nedmemalign(OGRE_SIMD_ALIGNMENT, count); #if OGRE_MEMORY_TRACKER - // this alloc policy doesn't do pools (yet, ned can do it) - MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); + // this alloc policy doesn't do pools (yet, ned can do it) + MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); #endif - return ptr; - } - //--------------------------------------------------------------------- - void NedAllocImpl::deallocBytesAligned(size_t align, void* ptr) - { - // deal with null - if (!ptr) - return; + return ptr; + } + //--------------------------------------------------------------------- + void NedAllocImpl::deallocBytesAligned(size_t align, void* ptr) + { + // deal with null + if (!ptr) + return; #if OGRE_MEMORY_TRACKER - // this alloc policy doesn't do pools (yet, ned can do it) - MemoryTracker::get()._recordDealloc(ptr); + // this alloc policy doesn't do pools (yet, ned can do it) + MemoryTracker::get()._recordDealloc(ptr); #endif - nedalloc::nedfree(ptr); - } + nedalloc::nedfree(ptr); + } } diff --git a/OgreMain/src/OgreMemoryNedPooling.cpp b/OgreMain/src/OgreMemoryNedPooling.cpp index 0e574a89b01..9e953ae0c97 100644 --- a/OgreMain/src/OgreMemoryNedPooling.cpp +++ b/OgreMain/src/OgreMemoryNedPooling.cpp @@ -39,156 +39,156 @@ THE SOFTWARE. namespace Ogre { - namespace _NedPoolingIntern - { - const size_t s_poolCount = 14; // Needs to be greater than 4 - void* s_poolFootprint = reinterpret_cast(0xBB1AA45A); - nedalloc::nedpool* s_pools[s_poolCount + 1] = { 0 }; - nedalloc::nedpool* s_poolsAligned[s_poolCount + 1] = { 0 }; - - size_t poolIDFromSize(size_t a_reqSize) - { - // Requests size 16 or smaller are allocated at a 4 byte granularity. - // Requests size 17 or larger are allocated at a 16 byte granularity. - // With a s_poolCount of 14, requests size 177 or larger go in the default pool. - - // spreadsheet style =IF(B35<=16; FLOOR((B35-1)/4;1); MIN(FLOOR((B35-1)/16; 1) + 3; 14)) - - size_t poolID = 0; - - if (a_reqSize > 0) - { - if (a_reqSize <= 16) - { - poolID = (a_reqSize - 1) >> 2; - } - else - { - poolID = std::min(((a_reqSize - 1) >> 4) + 3, s_poolCount); - } - } - - return poolID; - } - - void* internalAlloc(size_t a_reqSize) - { - size_t poolID = poolIDFromSize(a_reqSize); - nedalloc::nedpool* pool(0); // A pool pointer of 0 means the default pool. - - if (poolID < s_poolCount) - { - if (s_pools[poolID] == 0) - { - // Init pool if first use - - s_pools[poolID] = nedalloc::nedcreatepool(0, 8); - nedalloc::nedpsetvalue(s_pools[poolID], s_poolFootprint); // All pools are stamped with a footprint - } - - pool = s_pools[poolID]; - } - - return nedalloc::nedpmalloc(pool, a_reqSize); - } - - void* internalAllocAligned(size_t a_align, size_t a_reqSize) - { - size_t poolID = poolIDFromSize(a_reqSize); - nedalloc::nedpool* pool(0); // A pool pointer of 0 means the default pool. - - if (poolID < s_poolCount) - { - if (s_poolsAligned[poolID] == 0) - { - // Init pool if first use - - s_poolsAligned[poolID] = nedalloc::nedcreatepool(0, 8); - nedalloc::nedpsetvalue(s_poolsAligned[poolID], s_poolFootprint); // All pools are stamped with a footprint - } - - pool = s_poolsAligned[poolID]; - } - - return nedalloc::nedpmemalign(pool, a_align, a_reqSize); - } - - void internalFree(void* a_mem) - { - if (a_mem) - { - nedalloc::nedpool* pool(0); - - // nedalloc lets us get the pool pointer from the memory pointer - void* footprint = nedalloc::nedgetvalue(&pool, a_mem); - - // Check footprint - if (footprint == s_poolFootprint) - { - // If we allocated the pool, deallocate from this pool... - nedalloc::nedpfree(pool, a_mem); - } - else - { - // ...otherwise let nedalloc handle it. - nedalloc::nedfree(a_mem); - } - } - } - } - - //--------------------------------------------------------------------- - void* NedPoolingImpl::allocBytes(size_t count, - const char* file, int line, const char* func) - { - void* ptr = _NedPoolingIntern::internalAlloc(count); + namespace _NedPoolingIntern + { + const size_t s_poolCount = 14; // Needs to be greater than 4 + void* s_poolFootprint = reinterpret_cast(0xBB1AA45A); + nedalloc::nedpool* s_pools[s_poolCount + 1] = { 0 }; + nedalloc::nedpool* s_poolsAligned[s_poolCount + 1] = { 0 }; + + size_t poolIDFromSize(size_t a_reqSize) + { + // Requests size 16 or smaller are allocated at a 4 byte granularity. + // Requests size 17 or larger are allocated at a 16 byte granularity. + // With a s_poolCount of 14, requests size 177 or larger go in the default pool. + + // spreadsheet style =IF(B35<=16; FLOOR((B35-1)/4;1); MIN(FLOOR((B35-1)/16; 1) + 3; 14)) + + size_t poolID = 0; + + if (a_reqSize > 0) + { + if (a_reqSize <= 16) + { + poolID = (a_reqSize - 1) >> 2; + } + else + { + poolID = std::min(((a_reqSize - 1) >> 4) + 3, s_poolCount); + } + } + + return poolID; + } + + void* internalAlloc(size_t a_reqSize) + { + size_t poolID = poolIDFromSize(a_reqSize); + nedalloc::nedpool* pool(0); // A pool pointer of 0 means the default pool. + + if (poolID < s_poolCount) + { + if (s_pools[poolID] == 0) + { + // Init pool if first use + + s_pools[poolID] = nedalloc::nedcreatepool(0, 8); + nedalloc::nedpsetvalue(s_pools[poolID], s_poolFootprint); // All pools are stamped with a footprint + } + + pool = s_pools[poolID]; + } + + return nedalloc::nedpmalloc(pool, a_reqSize); + } + + void* internalAllocAligned(size_t a_align, size_t a_reqSize) + { + size_t poolID = poolIDFromSize(a_reqSize); + nedalloc::nedpool* pool(0); // A pool pointer of 0 means the default pool. + + if (poolID < s_poolCount) + { + if (s_poolsAligned[poolID] == 0) + { + // Init pool if first use + + s_poolsAligned[poolID] = nedalloc::nedcreatepool(0, 8); + nedalloc::nedpsetvalue(s_poolsAligned[poolID], s_poolFootprint); // All pools are stamped with a footprint + } + + pool = s_poolsAligned[poolID]; + } + + return nedalloc::nedpmemalign(pool, a_align, a_reqSize); + } + + void internalFree(void* a_mem) + { + if (a_mem) + { + nedalloc::nedpool* pool(0); + + // nedalloc lets us get the pool pointer from the memory pointer + void* footprint = nedalloc::nedgetvalue(&pool, a_mem); + + // Check footprint + if (footprint == s_poolFootprint) + { + // If we allocated the pool, deallocate from this pool... + nedalloc::nedpfree(pool, a_mem); + } + else + { + // ...otherwise let nedalloc handle it. + nedalloc::nedfree(a_mem); + } + } + } + } + + //--------------------------------------------------------------------- + void* NedPoolingImpl::allocBytes(size_t count, + const char* file, int line, const char* func) + { + void* ptr = _NedPoolingIntern::internalAlloc(count); #if OGRE_MEMORY_TRACKER - MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); + MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); #else - // avoid unused params warning - file = func = ""; + // avoid unused params warning + file = func = ""; line = 0; #endif - return ptr; - } - //--------------------------------------------------------------------- - void NedPoolingImpl::deallocBytes(void* ptr) - { - // deal with null - if (!ptr) - return; + return ptr; + } + //--------------------------------------------------------------------- + void NedPoolingImpl::deallocBytes(void* ptr) + { + // deal with null + if (!ptr) + return; #if OGRE_MEMORY_TRACKER - MemoryTracker::get()._recordDealloc(ptr); + MemoryTracker::get()._recordDealloc(ptr); #endif - _NedPoolingIntern::internalFree(ptr); - } - //--------------------------------------------------------------------- - void* NedPoolingImpl::allocBytesAligned(size_t align, size_t count, - const char* file, int line, const char* func) - { - // default to platform SIMD alignment if none specified - void* ptr = align ? _NedPoolingIntern::internalAllocAligned(align, count) - : _NedPoolingIntern::internalAllocAligned(OGRE_SIMD_ALIGNMENT, count); + _NedPoolingIntern::internalFree(ptr); + } + //--------------------------------------------------------------------- + void* NedPoolingImpl::allocBytesAligned(size_t align, size_t count, + const char* file, int line, const char* func) + { + // default to platform SIMD alignment if none specified + void* ptr = align ? _NedPoolingIntern::internalAllocAligned(align, count) + : _NedPoolingIntern::internalAllocAligned(OGRE_SIMD_ALIGNMENT, count); #if OGRE_MEMORY_TRACKER - MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); + MemoryTracker::get()._recordAlloc(ptr, count, 0, file, line, func); #else - // avoid unused params warning - file = func = ""; + // avoid unused params warning + file = func = ""; line = 0; #endif - return ptr; - } - //--------------------------------------------------------------------- - void NedPoolingImpl::deallocBytesAligned(size_t align, void* ptr) - { - // deal with null - if (!ptr) - return; + return ptr; + } + //--------------------------------------------------------------------- + void NedPoolingImpl::deallocBytesAligned(size_t align, void* ptr) + { + // deal with null + if (!ptr) + return; #if OGRE_MEMORY_TRACKER - MemoryTracker::get()._recordDealloc(ptr); + MemoryTracker::get()._recordDealloc(ptr); #endif - _NedPoolingIntern::internalFree(ptr); - } + _NedPoolingIntern::internalFree(ptr); + } } diff --git a/OgreMain/src/OgreMemoryTracker.cpp b/OgreMain/src/OgreMemoryTracker.cpp index f42ede533eb..e1907b72389 100644 --- a/OgreMain/src/OgreMemoryTracker.cpp +++ b/OgreMain/src/OgreMemoryTracker.cpp @@ -34,120 +34,120 @@ THE SOFTWARE. #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT # include -# define Ogre_OutputCString(str) ::OutputDebugStringA(str) -# define Ogre_OutputWString(str) ::OutputDebugStringW(str) +# define Ogre_OutputCString(str) ::OutputDebugStringA(str) +# define Ogre_OutputWString(str) ::OutputDebugStringW(str) #else -# define Ogre_OutputCString(str) std::cerr << str -# define Ogre_OutputWString(str) std::cerr << str +# define Ogre_OutputCString(str) std::cerr << str +# define Ogre_OutputWString(str) std::cerr << str #endif namespace Ogre { - + #if OGRE_MEMORY_TRACKER - //-------------------------------------------------------------------------- - MemoryTracker& MemoryTracker::get() - { - static MemoryTracker tracker; - return tracker; - } - //-------------------------------------------------------------------------- - void MemoryTracker::_recordAlloc(void* ptr, size_t sz, unsigned int pool, - const char* file, size_t ln, const char* func) - { - if (mRecordEnable) - { + //-------------------------------------------------------------------------- + MemoryTracker& MemoryTracker::get() + { + static MemoryTracker tracker; + return tracker; + } + //-------------------------------------------------------------------------- + void MemoryTracker::_recordAlloc(void* ptr, size_t sz, unsigned int pool, + const char* file, size_t ln, const char* func) + { + if (mRecordEnable) + { OGRE_LOCK_AUTO_MUTEX; - assert(mAllocations.find(ptr) == mAllocations.end() && "Double allocation with same address - " - "this probably means you have a mismatched allocation / deallocation style, " - "check if you're are using OGRE_ALLOC_T / OGRE_FREE and OGRE_NEW_T / OGRE_DELETE_T consistently"); - - mAllocations[ptr] = Alloc(sz, pool, file, ln, func); - if(pool >= mAllocationsByPool.size()) - mAllocationsByPool.resize(pool+1, 0); - mAllocationsByPool[pool] += sz; - mTotalAllocations += sz; - } - - } - //-------------------------------------------------------------------------- - void MemoryTracker::_recordDealloc(void* ptr) - { - if (mRecordEnable) - { - // deal cleanly with null pointers - if (!ptr) - return; - - OGRE_LOCK_AUTO_MUTEX; - - AllocationMap::iterator i = mAllocations.find(ptr); - assert(i != mAllocations.end() && "Unable to locate allocation unit - " - "this probably means you have a mismatched allocation / deallocation style, " - "check if you're are using OGRE_ALLOC_T / OGRE_FREE and OGRE_NEW_T / OGRE_DELETE_T consistently"); - // update category stats - mAllocationsByPool[i->second.pool] -= i->second.bytes; - // global stats - mTotalAllocations -= i->second.bytes; - mAllocations.erase(i); - } - } - //-------------------------------------------------------------------------- - size_t MemoryTracker::getTotalMemoryAllocated() const - { - return mTotalAllocations; - } - //-------------------------------------------------------------------------- - size_t MemoryTracker::getMemoryAllocatedForPool(unsigned int pool) const - { - return mAllocationsByPool[pool]; - } - //-------------------------------------------------------------------------- - void MemoryTracker::reportLeaks() - { - if (mRecordEnable) - { - StringStream os; - - if (mAllocations.empty()) - { - os << "Ogre Memory: No memory leaks" << std::endl; - } - else - { - os << "Ogre Memory: Detected memory leaks !!! " << std::endl; - os << "Ogre Memory: (" << mAllocations.size() << ") Allocation(s) with total " << mTotalAllocations << " bytes." << std::endl; - os << "Ogre Memory: Dumping allocations -> " << std::endl; - - - for (AllocationMap::const_iterator i = mAllocations.begin(); i != mAllocations.end(); ++i) - { - const Alloc& alloc = i->second; - if (!alloc.filename.empty()) - os << alloc.filename; - else - os << "(unknown source):"; - - os << "(" << alloc.line << ") : {" << alloc.bytes << " bytes}" << " function: " << alloc.function << std::endl; - - } - os << std::endl; - } - - if (mDumpToStdOut) - std::cout << os.str(); - - std::ofstream of; - of.open(mLeakFileName.c_str()); - of << os.str(); - of.close(); - - Ogre_OutputCString(os.str().c_str()); - } - } -#endif // OGRE_DEBUG_MODE - + assert(mAllocations.find(ptr) == mAllocations.end() && "Double allocation with same address - " + "this probably means you have a mismatched allocation / deallocation style, " + "check if you're are using OGRE_ALLOC_T / OGRE_FREE and OGRE_NEW_T / OGRE_DELETE_T consistently"); + + mAllocations[ptr] = Alloc(sz, pool, file, ln, func); + if(pool >= mAllocationsByPool.size()) + mAllocationsByPool.resize(pool+1, 0); + mAllocationsByPool[pool] += sz; + mTotalAllocations += sz; + } + + } + //-------------------------------------------------------------------------- + void MemoryTracker::_recordDealloc(void* ptr) + { + if (mRecordEnable) + { + // deal cleanly with null pointers + if (!ptr) + return; + + OGRE_LOCK_AUTO_MUTEX; + + AllocationMap::iterator i = mAllocations.find(ptr); + assert(i != mAllocations.end() && "Unable to locate allocation unit - " + "this probably means you have a mismatched allocation / deallocation style, " + "check if you're are using OGRE_ALLOC_T / OGRE_FREE and OGRE_NEW_T / OGRE_DELETE_T consistently"); + // update category stats + mAllocationsByPool[i->second.pool] -= i->second.bytes; + // global stats + mTotalAllocations -= i->second.bytes; + mAllocations.erase(i); + } + } + //-------------------------------------------------------------------------- + size_t MemoryTracker::getTotalMemoryAllocated() const + { + return mTotalAllocations; + } + //-------------------------------------------------------------------------- + size_t MemoryTracker::getMemoryAllocatedForPool(unsigned int pool) const + { + return mAllocationsByPool[pool]; + } + //-------------------------------------------------------------------------- + void MemoryTracker::reportLeaks() + { + if (mRecordEnable) + { + StringStream os; + + if (mAllocations.empty()) + { + os << "Ogre Memory: No memory leaks" << std::endl; + } + else + { + os << "Ogre Memory: Detected memory leaks !!! " << std::endl; + os << "Ogre Memory: (" << mAllocations.size() << ") Allocation(s) with total " << mTotalAllocations << " bytes." << std::endl; + os << "Ogre Memory: Dumping allocations -> " << std::endl; + + + for (AllocationMap::const_iterator i = mAllocations.begin(); i != mAllocations.end(); ++i) + { + const Alloc& alloc = i->second; + if (!alloc.filename.empty()) + os << alloc.filename; + else + os << "(unknown source):"; + + os << "(" << alloc.line << ") : {" << alloc.bytes << " bytes}" << " function: " << alloc.function << std::endl; + + } + os << std::endl; + } + + if (mDumpToStdOut) + std::cout << os.str(); + + std::ofstream of; + of.open(mLeakFileName.c_str()); + of << os.str(); + of.close(); + + Ogre_OutputCString(os.str().c_str()); + } + } +#endif // OGRE_DEBUG_MODE + } diff --git a/OgreMain/src/OgreMesh.cpp b/OgreMain/src/OgreMesh.cpp index 005862238cc..54a91af2ec4 100644 --- a/OgreMain/src/OgreMesh.cpp +++ b/OgreMain/src/OgreMesh.cpp @@ -65,19 +65,19 @@ namespace Ogre { mPreparedForShadowVolumes(false), mEdgeListsBuilt(false), mAutoBuildEdgeLists(true), // will be set to false by serializers of 1.30 and above - mSharedVertexDataAnimationType(VAT_NONE), - mSharedVertexDataAnimationIncludesNormals(false), - mAnimationTypesDirty(true), - mPosesIncludeNormals(false), - sharedVertexData(0) - { - // Init first (manual) lod - MeshLodUsage lod; + mSharedVertexDataAnimationType(VAT_NONE), + mSharedVertexDataAnimationIncludesNormals(false), + mAnimationTypesDirty(true), + mPosesIncludeNormals(false), + sharedVertexData(0) + { + // Init first (manual) lod + MeshLodUsage lod; lod.userValue = 0; // User value not used for base LOD level - lod.value = getLodStrategy()->getBaseValue(); + lod.value = getLodStrategy()->getBaseValue(); lod.edgeData = NULL; lod.manualMesh.setNull(); - mMeshLodUsageList.push_back(lod); + mMeshLodUsageList.push_back(lod); } //----------------------------------------------------------------------- Mesh::~Mesh() @@ -94,91 +94,91 @@ namespace Ogre { mSubMeshList.push_back(sub); - if (isLoaded()) - _dirtyState(); + if (isLoaded()) + _dirtyState(); return sub; } //----------------------------------------------------------------------- SubMesh* Mesh::createSubMesh(const String& name) - { - SubMesh *sub = createSubMesh(); - nameSubMesh(name, (ushort)mSubMeshList.size()-1); - return sub ; - } + { + SubMesh *sub = createSubMesh(); + nameSubMesh(name, (ushort)mSubMeshList.size()-1); + return sub ; + } //----------------------------------------------------------------------- - void Mesh::destroySubMesh(unsigned short index) - { + void Mesh::destroySubMesh(unsigned short index) + { if (index >= mSubMeshList.size()) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Index out of bounds.", - "Mesh::removeSubMesh"); - } - SubMeshList::iterator i = mSubMeshList.begin(); - std::advance(i, index); - mSubMeshList.erase(i); - - // Fix up any name/index entries - for(SubMeshNameMap::iterator ni = mSubMeshNameMap.begin(); ni != mSubMeshNameMap.end();) - { - if (ni->second == index) - { - SubMeshNameMap::iterator eraseIt = ni++; - mSubMeshNameMap.erase(eraseIt); - } - else - { - // reduce indexes following - if (ni->second > index) - ni->second = ni->second - 1; - - ++ni; - } - } - - // fix edge list data by simply recreating all edge lists - if( mEdgeListsBuilt) - { - this->freeEdgeList(); - this->buildEdgeList(); - } - - if (isLoaded()) - _dirtyState(); - - } + "Index out of bounds.", + "Mesh::removeSubMesh"); + } + SubMeshList::iterator i = mSubMeshList.begin(); + std::advance(i, index); + mSubMeshList.erase(i); + + // Fix up any name/index entries + for(SubMeshNameMap::iterator ni = mSubMeshNameMap.begin(); ni != mSubMeshNameMap.end();) + { + if (ni->second == index) + { + SubMeshNameMap::iterator eraseIt = ni++; + mSubMeshNameMap.erase(eraseIt); + } + else + { + // reduce indexes following + if (ni->second > index) + ni->second = ni->second - 1; + + ++ni; + } + } + + // fix edge list data by simply recreating all edge lists + if( mEdgeListsBuilt) + { + this->freeEdgeList(); + this->buildEdgeList(); + } + + if (isLoaded()) + _dirtyState(); + + } //----------------------------------------------------------------------- void Mesh::destroySubMesh(const String& name) - { - unsigned short index = _getSubMeshIndex(name); - destroySubMesh(index); - } - //----------------------------------------------------------------------- + { + unsigned short index = _getSubMeshIndex(name); + destroySubMesh(index); + } + //----------------------------------------------------------------------- unsigned short Mesh::getNumSubMeshes() const { return static_cast< unsigned short >( mSubMeshList.size() ); } //--------------------------------------------------------------------- - void Mesh::nameSubMesh(const String& name, ushort index) - { - mSubMeshNameMap[name] = index ; - } - - //--------------------------------------------------------------------- - void Mesh::unnameSubMesh(const String& name) - { - SubMeshNameMap::iterator i = mSubMeshNameMap.find(name); - if (i != mSubMeshNameMap.end()) - mSubMeshNameMap.erase(i); - } + void Mesh::nameSubMesh(const String& name, ushort index) + { + mSubMeshNameMap[name] = index ; + } + + //--------------------------------------------------------------------- + void Mesh::unnameSubMesh(const String& name) + { + SubMeshNameMap::iterator i = mSubMeshNameMap.find(name); + if (i != mSubMeshNameMap.end()) + mSubMeshNameMap.erase(i); + } //----------------------------------------------------------------------- SubMesh* Mesh::getSubMesh(const String& name) const - { - ushort index = _getSubMeshIndex(name); - return getSubMesh(index); - } + { + ushort index = _getSubMeshIndex(name); + return getSubMesh(index); + } //----------------------------------------------------------------------- SubMesh* Mesh::getSubMesh(unsigned short index) const { @@ -191,32 +191,32 @@ namespace Ogre { return mSubMeshList[index]; } - //----------------------------------------------------------------------- - void Mesh::postLoadImpl(void) - { - // Prepare for shadow volumes? - if (MeshManager::getSingleton().getPrepareAllMeshesForShadowVolumes()) - { - if (mEdgeListsBuilt || mAutoBuildEdgeLists) - { - prepareForShadowVolume(); - } - - if (!mEdgeListsBuilt && mAutoBuildEdgeLists) - { - buildEdgeList(); - } - } + //----------------------------------------------------------------------- + void Mesh::postLoadImpl(void) + { + // Prepare for shadow volumes? + if (MeshManager::getSingleton().getPrepareAllMeshesForShadowVolumes()) + { + if (mEdgeListsBuilt || mAutoBuildEdgeLists) + { + prepareForShadowVolume(); + } + + if (!mEdgeListsBuilt && mAutoBuildEdgeLists) + { + buildEdgeList(); + } + } #if !OGRE_NO_MESHLOD // The loading process accesses LOD usages directly, so // transformation of user values must occur after loading is complete. // Transform user LOD values (starting at index 1, no need to transform base value) - for (MeshLodUsageList::iterator i = mMeshLodUsageList.begin() + 1; i != mMeshLodUsageList.end(); ++i) + for (MeshLodUsageList::iterator i = mMeshLodUsageList.begin() + 1; i != mMeshLodUsageList.end(); ++i) i->value = mLodStrategy->transformUserValue(i->userValue); #endif - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void Mesh::prepareImpl() { // Load from specified 'name' @@ -225,7 +225,7 @@ namespace Ogre { mFreshFromDisk = ResourceGroupManager::getSingleton().openResource( - mName, mGroup, true, this); + mName, mGroup, true, this); // fully prebuffer into host RAM mFreshFromDisk = DataStreamPtr(OGRE_NEW MemoryDataStream(mName,mFreshFromDisk)); @@ -251,7 +251,7 @@ namespace Ogre { "Mesh::loadImpl()"); } - serializer.importMesh(data, this); + serializer.importMesh(data, this); /* check all submeshes to see if their materials should be updated. If the submesh has texture aliases that match those @@ -275,18 +275,18 @@ namespace Ogre { OGRE_DELETE sharedVertexData; sharedVertexData = NULL; } - // Clear SubMesh lists - mSubMeshList.clear(); - mSubMeshNameMap.clear(); + // Clear SubMesh lists + mSubMeshList.clear(); + mSubMeshNameMap.clear(); #if !OGRE_NO_MESHLOD // Removes all LOD data removeLodLevels(); #endif mPreparedForShadowVolumes = false; - // remove all poses & animations - removeAllAnimations(); - removeAllPoses(); + // remove all poses & animations + removeAllAnimations(); + removeAllPoses(); // Clear bone assignments mBoneAssignments.clear(); @@ -329,8 +329,8 @@ namespace Ogre { newMesh->sharedBlendIndexToBoneIndexMap = sharedBlendIndexToBoneIndexMap; } - // Copy submesh names - newMesh->mSubMeshNameMap = mSubMeshNameMap ; + // Copy submesh names + newMesh->mSubMeshNameMap = mSubMeshNameMap ; // Copy any bone assignments newMesh->mBoneAssignments = mBoneAssignments; newMesh->mBoneAssignmentsOutOfDate = mBoneAssignmentsOutOfDate; @@ -339,55 +339,55 @@ namespace Ogre { newMesh->mBoundRadius = mBoundRadius; newMesh->mBoneBoundingRadius = mBoneBoundingRadius; newMesh->mAutoBuildEdgeLists = mAutoBuildEdgeLists; - newMesh->mEdgeListsBuilt = mEdgeListsBuilt; + newMesh->mEdgeListsBuilt = mEdgeListsBuilt; #if !OGRE_NO_MESHLOD - newMesh->mHasManualLodLevel = mHasManualLodLevel; + newMesh->mHasManualLodLevel = mHasManualLodLevel; newMesh->mLodStrategy = mLodStrategy; newMesh->mNumLods = mNumLods; newMesh->mMeshLodUsageList = mMeshLodUsageList; #endif // Unreference edge lists, otherwise we'll delete the same lot twice, build on demand MeshLodUsageList::iterator lodi, lodOldi; - lodOldi = mMeshLodUsageList.begin(); - for (lodi = newMesh->mMeshLodUsageList.begin(); lodi != newMesh->mMeshLodUsageList.end(); ++lodi, ++lodOldi) { + lodOldi = mMeshLodUsageList.begin(); + for (lodi = newMesh->mMeshLodUsageList.begin(); lodi != newMesh->mMeshLodUsageList.end(); ++lodi, ++lodOldi) { MeshLodUsage& newLod = *lodi; - MeshLodUsage& lod = *lodOldi; - newLod.manualName = lod.manualName; - newLod.userValue = lod.userValue; - newLod.value = lod.value; - if (lod.edgeData) { - newLod.edgeData = lod.edgeData->clone(); + MeshLodUsage& lod = *lodOldi; + newLod.manualName = lod.manualName; + newLod.userValue = lod.userValue; + newLod.value = lod.value; + if (lod.edgeData) { + newLod.edgeData = lod.edgeData->clone(); } } - newMesh->mVertexBufferUsage = mVertexBufferUsage; - newMesh->mIndexBufferUsage = mIndexBufferUsage; - newMesh->mVertexBufferShadowBuffer = mVertexBufferShadowBuffer; - newMesh->mIndexBufferShadowBuffer = mIndexBufferShadowBuffer; + newMesh->mVertexBufferUsage = mVertexBufferUsage; + newMesh->mIndexBufferUsage = mIndexBufferUsage; + newMesh->mVertexBufferShadowBuffer = mVertexBufferShadowBuffer; + newMesh->mIndexBufferShadowBuffer = mIndexBufferShadowBuffer; newMesh->mSkeletonName = mSkeletonName; newMesh->mSkeleton = mSkeleton; - // Keep prepared shadow volume info (buffers may already be prepared) - newMesh->mPreparedForShadowVolumes = mPreparedForShadowVolumes; - - newMesh->mEdgeListsBuilt = mEdgeListsBuilt; - - // Clone vertex animation - for (AnimationList::iterator i = mAnimationsList.begin(); - i != mAnimationsList.end(); ++i) - { - Animation *newAnim = i->second->clone(i->second->getName()); - newMesh->mAnimationsList[i->second->getName()] = newAnim; - } - // Clone pose list - for (PoseList::iterator i = mPoseList.begin(); i != mPoseList.end(); ++i) - { - Pose* newPose = (*i)->clone(); - newMesh->mPoseList.push_back(newPose); - } - newMesh->mSharedVertexDataAnimationType = mSharedVertexDataAnimationType; - newMesh->mAnimationTypesDirty = true; + // Keep prepared shadow volume info (buffers may already be prepared) + newMesh->mPreparedForShadowVolumes = mPreparedForShadowVolumes; + + newMesh->mEdgeListsBuilt = mEdgeListsBuilt; + + // Clone vertex animation + for (AnimationList::iterator i = mAnimationsList.begin(); + i != mAnimationsList.end(); ++i) + { + Animation *newAnim = i->second->clone(i->second->getName()); + newMesh->mAnimationsList[i->second->getName()] = newAnim; + } + // Clone pose list + for (PoseList::iterator i = mPoseList.begin(); i != mPoseList.end(); ++i) + { + Pose* newPose = (*i)->clone(); + newMesh->mPoseList.push_back(newPose); + } + newMesh->mSharedVertexDataAnimationType = mSharedVertexDataAnimationType; + newMesh->mAnimationTypesDirty = true; newMesh->load(); newMesh->touch(); @@ -403,22 +403,22 @@ namespace Ogre { void Mesh::_setBounds(const AxisAlignedBox& bounds, bool pad) { mAABB = bounds; - mBoundRadius = Math::boundingRadiusFromAABB(mAABB); - - if( mAABB.isFinite() ) - { - Vector3 max = mAABB.getMaximum(); - Vector3 min = mAABB.getMinimum(); - - if (pad) - { - // Pad out the AABB a little, helps with most bounds tests - Vector3 scaler = (max - min) * MeshManager::getSingleton().getBoundsPaddingFactor(); - mAABB.setExtents(min - scaler, max + scaler); - // Pad out the sphere a little too - mBoundRadius = mBoundRadius + (mBoundRadius * MeshManager::getSingleton().getBoundsPaddingFactor()); - } - } + mBoundRadius = Math::boundingRadiusFromAABB(mAABB); + + if( mAABB.isFinite() ) + { + Vector3 max = mAABB.getMaximum(); + Vector3 min = mAABB.getMinimum(); + + if (pad) + { + // Pad out the AABB a little, helps with most bounds tests + Vector3 scaler = (max - min) * MeshManager::getSingleton().getBoundsPaddingFactor(); + mAABB.setExtents(min - scaler, max + scaler); + // Pad out the sphere a little too + mBoundRadius = mBoundRadius + (mBoundRadius * MeshManager::getSingleton().getBoundsPaddingFactor()); + } + } } //----------------------------------------------------------------------- void Mesh::_setBoundingSphereRadius(Real radius) @@ -431,101 +431,101 @@ namespace Ogre { mBoneBoundingRadius = radius; } //----------------------------------------------------------------------- - void Mesh::_updateBoundsFromVertexBuffers(bool pad) - { - bool extendOnly = false; // First time we need full AABB of the given submesh, but on the second call just extend that one. - if (sharedVertexData){ - _calcBoundsFromVertexBuffer(sharedVertexData, mAABB, mBoundRadius, extendOnly); - extendOnly = true; - } - for (size_t i = 0; i < mSubMeshList.size(); i++){ - if (mSubMeshList[i]->vertexData){ - _calcBoundsFromVertexBuffer(mSubMeshList[i]->vertexData, mAABB, mBoundRadius, extendOnly); - extendOnly = true; - } - } - if (pad) - { - Vector3 max = mAABB.getMaximum(); - Vector3 min = mAABB.getMinimum(); - // Pad out the AABB a little, helps with most bounds tests - Vector3 scaler = (max - min) * MeshManager::getSingleton().getBoundsPaddingFactor(); - mAABB.setExtents(min - scaler, max + scaler); - // Pad out the sphere a little too - mBoundRadius = mBoundRadius + (mBoundRadius * MeshManager::getSingleton().getBoundsPaddingFactor()); - } - } - void Mesh::_calcBoundsFromVertexBuffer(VertexData* vertexData, AxisAlignedBox& outAABB, Real& outRadius, bool extendOnly /*= false*/) - { - if (vertexData->vertexCount == 0) { - if (!extendOnly) { - outAABB = AxisAlignedBox(Vector3::ZERO, Vector3::ZERO); - outRadius = 0; - } - return; - } - const VertexElement* elemPos = vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(elemPos->getSource()); - - unsigned char* vertex = static_cast(vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); - - if (!extendOnly){ - // init values - outRadius = 0; - float* pFloat; - elemPos->baseVertexPointerToElement(vertex, &pFloat); - Vector3 basePos(pFloat[0], pFloat[1], pFloat[2]); - outAABB.setExtents(basePos, basePos); - } - size_t vSize = vbuf->getVertexSize(); - unsigned char* vEnd = vertex + vertexData->vertexCount * vSize; - Real radiusSqr = outRadius * outRadius; - // Loop through all vertices. - for (; vertex < vEnd; vertex += vSize) { - float* pFloat; - elemPos->baseVertexPointerToElement(vertex, &pFloat); - Vector3 pos(pFloat[0], pFloat[1], pFloat[2]); - outAABB.getMinimum().makeFloor(pos); - outAABB.getMaximum().makeCeil(pos); - radiusSqr = std::max(radiusSqr, pos.squaredLength()); - } - outRadius = std::sqrt(radiusSqr); - } + void Mesh::_updateBoundsFromVertexBuffers(bool pad) + { + bool extendOnly = false; // First time we need full AABB of the given submesh, but on the second call just extend that one. + if (sharedVertexData){ + _calcBoundsFromVertexBuffer(sharedVertexData, mAABB, mBoundRadius, extendOnly); + extendOnly = true; + } + for (size_t i = 0; i < mSubMeshList.size(); i++){ + if (mSubMeshList[i]->vertexData){ + _calcBoundsFromVertexBuffer(mSubMeshList[i]->vertexData, mAABB, mBoundRadius, extendOnly); + extendOnly = true; + } + } + if (pad) + { + Vector3 max = mAABB.getMaximum(); + Vector3 min = mAABB.getMinimum(); + // Pad out the AABB a little, helps with most bounds tests + Vector3 scaler = (max - min) * MeshManager::getSingleton().getBoundsPaddingFactor(); + mAABB.setExtents(min - scaler, max + scaler); + // Pad out the sphere a little too + mBoundRadius = mBoundRadius + (mBoundRadius * MeshManager::getSingleton().getBoundsPaddingFactor()); + } + } + void Mesh::_calcBoundsFromVertexBuffer(VertexData* vertexData, AxisAlignedBox& outAABB, Real& outRadius, bool extendOnly /*= false*/) + { + if (vertexData->vertexCount == 0) { + if (!extendOnly) { + outAABB = AxisAlignedBox(Vector3::ZERO, Vector3::ZERO); + outRadius = 0; + } + return; + } + const VertexElement* elemPos = vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(elemPos->getSource()); + + unsigned char* vertex = static_cast(vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + + if (!extendOnly){ + // init values + outRadius = 0; + float* pFloat; + elemPos->baseVertexPointerToElement(vertex, &pFloat); + Vector3 basePos(pFloat[0], pFloat[1], pFloat[2]); + outAABB.setExtents(basePos, basePos); + } + size_t vSize = vbuf->getVertexSize(); + unsigned char* vEnd = vertex + vertexData->vertexCount * vSize; + Real radiusSqr = outRadius * outRadius; + // Loop through all vertices. + for (; vertex < vEnd; vertex += vSize) { + float* pFloat; + elemPos->baseVertexPointerToElement(vertex, &pFloat); + Vector3 pos(pFloat[0], pFloat[1], pFloat[2]); + outAABB.getMinimum().makeFloor(pos); + outAABB.getMaximum().makeCeil(pos); + radiusSqr = std::max(radiusSqr, pos.squaredLength()); + } + outRadius = std::sqrt(radiusSqr); + } //----------------------------------------------------------------------- void Mesh::setSkeletonName(const String& skelName) { - if (skelName != mSkeletonName) - { - mSkeletonName = skelName; - - if (skelName.empty()) - { - // No skeleton - mSkeleton.setNull(); - } - else - { - // Load skeleton - try { - mSkeleton = SkeletonManager::getSingleton().load(skelName, mGroup).staticCast(); - } - catch (...) - { - mSkeleton.setNull(); - // Log this error - String msg = "Unable to load skeleton "; - msg += skelName + " for Mesh " + mName - + ". This Mesh will not be animated. " - + "You can ignore this message if you are using an offline tool."; - LogManager::getSingleton().logMessage(msg); - - } - - - } - if (isLoaded()) - _dirtyState(); - } + if (skelName != mSkeletonName) + { + mSkeletonName = skelName; + + if (skelName.empty()) + { + // No skeleton + mSkeleton.setNull(); + } + else + { + // Load skeleton + try { + mSkeleton = SkeletonManager::getSingleton().load(skelName, mGroup).staticCast(); + } + catch (...) + { + mSkeleton.setNull(); + // Log this error + String msg = "Unable to load skeleton "; + msg += skelName + " for Mesh " + mName + + ". This Mesh will not be animated. " + + "You can ignore this message if you are using an offline tool."; + LogManager::getSingleton().logMessage(msg); + + } + + + } + if (isLoaded()) + _dirtyState(); + } } //----------------------------------------------------------------------- bool Mesh::hasSkeleton(void) const @@ -553,63 +553,63 @@ namespace Ogre { //----------------------------------------------------------------------- void Mesh::_initAnimationState(AnimationStateSet* animSet) { - // Animation states for skeletal animation - if (!mSkeleton.isNull()) - { - // Delegate to Skeleton - mSkeleton->_initAnimationState(animSet); + // Animation states for skeletal animation + if (!mSkeleton.isNull()) + { + // Delegate to Skeleton + mSkeleton->_initAnimationState(animSet); - // Take the opportunity to update the compiled bone assignments + // Take the opportunity to update the compiled bone assignments _updateCompiledBoneAssignments(); } - // Animation states for vertex animation - for (AnimationList::iterator i = mAnimationsList.begin(); - i != mAnimationsList.end(); ++i) - { - // Only create a new animation state if it doesn't exist - // We can have the same named animation in both skeletal and vertex - // with a shared animation state affecting both, for combined effects - // The animations should be the same length if this feature is used! - if (!animSet->hasAnimationState(i->second->getName())) - { - animSet->createAnimationState(i->second->getName(), 0.0, - i->second->getLength()); - } - - } - - } - //--------------------------------------------------------------------- - void Mesh::_refreshAnimationState(AnimationStateSet* animSet) - { - if (!mSkeleton.isNull()) - { - mSkeleton->_refreshAnimationState(animSet); - } - - // Merge in any new vertex animations - AnimationList::iterator i; - for (i = mAnimationsList.begin(); i != mAnimationsList.end(); ++i) - { - Animation* anim = i->second; - // Create animation at time index 0, default params mean this has weight 1 and is disabled - const String& animName = anim->getName(); - if (!animSet->hasAnimationState(animName)) - { - animSet->createAnimationState(animName, 0.0, anim->getLength()); - } - else - { - // Update length incase changed - AnimationState* animState = animSet->getAnimationState(animName); - animState->setLength(anim->getLength()); - animState->setTimePosition(std::min(anim->getLength(), animState->getTimePosition())); - } - } - - } + // Animation states for vertex animation + for (AnimationList::iterator i = mAnimationsList.begin(); + i != mAnimationsList.end(); ++i) + { + // Only create a new animation state if it doesn't exist + // We can have the same named animation in both skeletal and vertex + // with a shared animation state affecting both, for combined effects + // The animations should be the same length if this feature is used! + if (!animSet->hasAnimationState(i->second->getName())) + { + animSet->createAnimationState(i->second->getName(), 0.0, + i->second->getLength()); + } + + } + + } + //--------------------------------------------------------------------- + void Mesh::_refreshAnimationState(AnimationStateSet* animSet) + { + if (!mSkeleton.isNull()) + { + mSkeleton->_refreshAnimationState(animSet); + } + + // Merge in any new vertex animations + AnimationList::iterator i; + for (i = mAnimationsList.begin(); i != mAnimationsList.end(); ++i) + { + Animation* anim = i->second; + // Create animation at time index 0, default params mean this has weight 1 and is disabled + const String& animName = anim->getName(); + if (!animSet->hasAnimationState(animName)) + { + animSet->createAnimationState(animName, 0.0, anim->getLength()); + } + else + { + // Update length incase changed + AnimationState* animState = animSet->getAnimationState(animName); + animState->setLength(anim->getLength()); + animState->setTimePosition(std::min(anim->getLength(), animState->getTimePosition())); + } + } + + } //----------------------------------------------------------------------- void Mesh::_updateCompiledBoneAssignments(void) { @@ -631,15 +631,15 @@ namespace Ogre { { // Iterate through, finding the largest # bones per vertex unsigned short maxBones = 0; - bool existsNonSkinnedVertices = false; + bool existsNonSkinnedVertices = false; VertexBoneAssignmentList::iterator i; for (size_t v = 0; v < vertexCount; ++v) { // Get number of entries for this vertex short currBones = static_cast(assignments.count(v)); - if (currBones <= 0) - existsNonSkinnedVertices = true; + if (currBones <= 0) + existsNonSkinnedVertices = true; // Deal with max bones update // (note this will record maxBones even if they exceed limit) @@ -695,8 +695,8 @@ namespace Ogre { } - if (maxBones > OGRE_MAX_BLEND_WEIGHTS) - { + if (maxBones > OGRE_MAX_BLEND_WEIGHTS) + { // Warn that we've reduced bone assignments LogManager::getSingleton().logMessage("WARNING: the mesh '" + mName + "' " "includes vertices with more than " + @@ -710,31 +710,31 @@ namespace Ogre { } - if (existsNonSkinnedVertices) - { + if (existsNonSkinnedVertices) + { // Warn that we've non-skinned vertices LogManager::getSingleton().logMessage("WARNING: the mesh '" + mName + "' " "includes vertices without bone assignments. Those vertices will " - "transform to wrong position when skeletal animation enabled. " - "To eliminate this, assign at least one bone assignment per vertex " - "on your mesh.", LML_CRITICAL); - } + "transform to wrong position when skeletal animation enabled. " + "To eliminate this, assign at least one bone assignment per vertex " + "on your mesh.", LML_CRITICAL); + } return maxBones; } //----------------------------------------------------------------------- void Mesh::_compileBoneAssignments(void) { - if (sharedVertexData) - { - unsigned short maxBones = _rationaliseBoneAssignments(sharedVertexData->vertexCount, mBoneAssignments); + if (sharedVertexData) + { + unsigned short maxBones = _rationaliseBoneAssignments(sharedVertexData->vertexCount, mBoneAssignments); - if (maxBones != 0) - { - compileBoneAssignments(mBoneAssignments, maxBones, - sharedBlendIndexToBoneIndexMap, sharedVertexData); - } - } + if (maxBones != 0) + { + compileBoneAssignments(mBoneAssignments, maxBones, + sharedBlendIndexToBoneIndexMap, sharedVertexData); + } + } mBoneAssignmentsOutOfDate = false; } //--------------------------------------------------------------------- @@ -860,7 +860,7 @@ namespace Ogre { size_t v; VertexBoneAssignmentList::const_iterator i, iend; i = boneAssignments.begin(); - iend = boneAssignments.end(); + iend = boneAssignments.end(); unsigned char *pBase = static_cast( vbuf->lock(HardwareBuffer::HBL_DISCARD)); // Iterate by vertex @@ -884,7 +884,7 @@ namespace Ogre { else { // Ran out of assignments for this vertex, use weight 0 to indicate empty. - // If no bones are defined (an error in itself) set bone 0 as the assigned bone. + // If no bones are defined (an error in itself) set bone 0 as the assigned bone. *pWeight++ = (bone == 0) ? 1.0f : 0.0f; *pIndex++ = 0; } @@ -1054,125 +1054,125 @@ namespace Ogre { if (this->_isManualLodLevel(index) && index > 0 && mMeshLodUsageList[index].manualMesh.isNull()) { // Load the mesh now - try { - mMeshLodUsageList[index].manualMesh = - MeshManager::getSingleton().load( - mMeshLodUsageList[index].manualName, - getGroup()); - // get the edge data, if required - if (!mMeshLodUsageList[index].edgeData) - { - mMeshLodUsageList[index].edgeData = - mMeshLodUsageList[index].manualMesh->getEdgeList(0); - } - } - catch (Exception& ) - { - LogManager::getSingleton().stream() - << "Error while loading manual LOD level " - << mMeshLodUsageList[index].manualName - << " - this LOD level will not be rendered. You can " - << "ignore this error in offline mesh tools."; - } + try { + mMeshLodUsageList[index].manualMesh = + MeshManager::getSingleton().load( + mMeshLodUsageList[index].manualName, + getGroup()); + // get the edge data, if required + if (!mMeshLodUsageList[index].edgeData) + { + mMeshLodUsageList[index].edgeData = + mMeshLodUsageList[index].manualMesh->getEdgeList(0); + } + } + catch (Exception& ) + { + LogManager::getSingleton().stream() + << "Error while loading manual LOD level " + << mMeshLodUsageList[index].manualName + << " - this LOD level will not be rendered. You can " + << "ignore this error in offline mesh tools."; + } } return mMeshLodUsageList[index]; #else - return mMeshLodUsageList[0]; + return mMeshLodUsageList[0]; #endif } - //--------------------------------------------------------------------- - ushort Mesh::getLodIndex(Real value) const - { + //--------------------------------------------------------------------- + ushort Mesh::getLodIndex(Real value) const + { #if !OGRE_NO_MESHLOD - // Get index from strategy - return mLodStrategy->getIndex(value, mMeshLodUsageList); + // Get index from strategy + return mLodStrategy->getIndex(value, mMeshLodUsageList); #else - return 0; + return 0; #endif - } + } //--------------------------------------------------------------------- #if !OGRE_NO_MESHLOD - void Mesh::updateManualLodLevel(ushort index, const String& meshName) - { + void Mesh::updateManualLodLevel(ushort index, const String& meshName) + { - // Basic prerequisites - assert(index != 0 && "Can't modify first LOD level (full detail)"); - assert(index < mMeshLodUsageList.size() && "Idndex out of bounds"); - // get lod - MeshLodUsage* lod = &(mMeshLodUsageList[index]); + // Basic prerequisites + assert(index != 0 && "Can't modify first LOD level (full detail)"); + assert(index < mMeshLodUsageList.size() && "Idndex out of bounds"); + // get lod + MeshLodUsage* lod = &(mMeshLodUsageList[index]); - lod->manualName = meshName; - lod->manualMesh.setNull(); + lod->manualName = meshName; + lod->manualMesh.setNull(); OGRE_DELETE lod->edgeData; lod->edgeData = 0; - } + } //--------------------------------------------------------------------- - void Mesh::_setLodInfo(unsigned short numLevels) - { + void Mesh::_setLodInfo(unsigned short numLevels) + { assert(!mEdgeListsBuilt && "Can't modify LOD after edge lists built"); - // Basic prerequisites + // Basic prerequisites assert(numLevels > 0 && "Must be at least one level (full detail level must exist)"); - mNumLods = numLevels; - mMeshLodUsageList.resize(numLevels); - // Resize submesh face data lists too - for (SubMeshList::iterator i = mSubMeshList.begin(); i != mSubMeshList.end(); ++i) - { - (*i)->mLodFaceList.resize(numLevels - 1); - } - } + mNumLods = numLevels; + mMeshLodUsageList.resize(numLevels); + // Resize submesh face data lists too + for (SubMeshList::iterator i = mSubMeshList.begin(); i != mSubMeshList.end(); ++i) + { + (*i)->mLodFaceList.resize(numLevels - 1); + } + } + //--------------------------------------------------------------------- + void Mesh::_setLodUsage(unsigned short level, MeshLodUsage& usage) + { + assert(!mEdgeListsBuilt && "Can't modify LOD after edge lists built"); + + // Basic prerequisites + assert(level != 0 && "Can't modify first LOD level (full detail)"); + assert(level < mMeshLodUsageList.size() && "Index out of bounds"); + + mMeshLodUsageList[level] = usage; + + if(!mMeshLodUsageList[level].manualName.empty()){ + mHasManualLodLevel = true; + } + } //--------------------------------------------------------------------- - void Mesh::_setLodUsage(unsigned short level, MeshLodUsage& usage) - { + void Mesh::_setSubMeshLodFaceList(unsigned short subIdx, unsigned short level, + IndexData* facedata) + { assert(!mEdgeListsBuilt && "Can't modify LOD after edge lists built"); - // Basic prerequisites - assert(level != 0 && "Can't modify first LOD level (full detail)"); - assert(level < mMeshLodUsageList.size() && "Index out of bounds"); - - mMeshLodUsageList[level] = usage; - - if(!mMeshLodUsageList[level].manualName.empty()){ - mHasManualLodLevel = true; - } - } - //--------------------------------------------------------------------- - void Mesh::_setSubMeshLodFaceList(unsigned short subIdx, unsigned short level, - IndexData* facedata) - { - assert(!mEdgeListsBuilt && "Can't modify LOD after edge lists built"); - - // Basic prerequisites - assert(mMeshLodUsageList[level].manualName.empty() && "Not using generated LODs!"); - assert(subIdx < mSubMeshList.size() && "Index out of bounds"); - assert(level != 0 && "Can't modify first LOD level (full detail)"); - assert(level-1 < (unsigned short)mSubMeshList[subIdx]->mLodFaceList.size() && "Index out of bounds"); - - SubMesh* sm = mSubMeshList[subIdx]; - sm->mLodFaceList[level - 1] = facedata; - } + // Basic prerequisites + assert(mMeshLodUsageList[level].manualName.empty() && "Not using generated LODs!"); + assert(subIdx < mSubMeshList.size() && "Index out of bounds"); + assert(level != 0 && "Can't modify first LOD level (full detail)"); + assert(level-1 < (unsigned short)mSubMeshList[subIdx]->mLodFaceList.size() && "Index out of bounds"); + + SubMesh* sm = mSubMeshList[subIdx]; + sm->mLodFaceList[level - 1] = facedata; + } #endif - //--------------------------------------------------------------------- - bool Mesh::_isManualLodLevel( unsigned short level ) const - { + //--------------------------------------------------------------------- + bool Mesh::_isManualLodLevel( unsigned short level ) const + { #if !OGRE_NO_MESHLOD - return !mMeshLodUsageList[level].manualName.empty(); + return !mMeshLodUsageList[level].manualName.empty(); #else - return false; + return false; #endif - } + } //--------------------------------------------------------------------- - ushort Mesh::_getSubMeshIndex(const String& name) const - { - SubMeshNameMap::const_iterator i = mSubMeshNameMap.find(name) ; - if (i == mSubMeshNameMap.end()) + ushort Mesh::_getSubMeshIndex(const String& name) const + { + SubMeshNameMap::const_iterator i = mSubMeshNameMap.find(name) ; + if (i == mSubMeshNameMap.end()) OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No SubMesh named " + name + " found.", "Mesh::_getSubMeshIndex"); - return i->second; - } + return i->second; + } //-------------------------------------------------------------------- void Mesh::removeLodLevels(void) { @@ -1189,9 +1189,9 @@ namespace Ogre { // Reinitialise mNumLods = 1; - mMeshLodUsageList.resize(1); - mMeshLodUsageList[0].edgeData = NULL; - // TODO: Shouldn't we rebuild edge lists after freeing them? + mMeshLodUsageList.resize(1); + mMeshLodUsageList[0].edgeData = NULL; + // TODO: Shouldn't we rebuild edge lists after freeing them? #endif } @@ -1206,107 +1206,107 @@ namespace Ogre { return mBoneBoundingRadius; } //--------------------------------------------------------------------- - void Mesh::setVertexBufferPolicy(HardwareBuffer::Usage vbUsage, bool shadowBuffer) - { - mVertexBufferUsage = vbUsage; - mVertexBufferShadowBuffer = shadowBuffer; - } + void Mesh::setVertexBufferPolicy(HardwareBuffer::Usage vbUsage, bool shadowBuffer) + { + mVertexBufferUsage = vbUsage; + mVertexBufferShadowBuffer = shadowBuffer; + } //--------------------------------------------------------------------- - void Mesh::setIndexBufferPolicy(HardwareBuffer::Usage vbUsage, bool shadowBuffer) - { - mIndexBufferUsage = vbUsage; - mIndexBufferShadowBuffer = shadowBuffer; - } - //--------------------------------------------------------------------- - void Mesh::mergeAdjacentTexcoords( unsigned short finalTexCoordSet, - unsigned short texCoordSetToDestroy ) - { - if( sharedVertexData ) - mergeAdjacentTexcoords( finalTexCoordSet, texCoordSetToDestroy, sharedVertexData ); - - SubMeshList::const_iterator itor = mSubMeshList.begin(); - SubMeshList::const_iterator end = mSubMeshList.end(); - - while( itor != end ) - { - if( !(*itor)->useSharedVertices ) - mergeAdjacentTexcoords( finalTexCoordSet, texCoordSetToDestroy, (*itor)->vertexData ); - ++itor; - } - } - //--------------------------------------------------------------------- - void Mesh::mergeAdjacentTexcoords( unsigned short finalTexCoordSet, - unsigned short texCoordSetToDestroy, - VertexData *vertexData ) - { - VertexDeclaration *vDecl = vertexData->vertexDeclaration; - - const VertexElement *uv0 = vDecl->findElementBySemantic( VES_TEXTURE_COORDINATES, - finalTexCoordSet ); - const VertexElement *uv1 = vDecl->findElementBySemantic( VES_TEXTURE_COORDINATES, - texCoordSetToDestroy ); - - if( uv0 && uv1 ) - { - //Check that both base types are compatible (mix floats w/ shorts) and there's enough space - VertexElementType baseType0 = VertexElement::getBaseType( uv0->getType() ); - VertexElementType baseType1 = VertexElement::getBaseType( uv1->getType() ); - - unsigned short totalTypeCount = VertexElement::getTypeCount( uv0->getType() ) + - VertexElement::getTypeCount( uv1->getType() ); - if( baseType0 == baseType1 && totalTypeCount <= 4 ) - { - const VertexDeclaration::VertexElementList &veList = vDecl->getElements(); - VertexDeclaration::VertexElementList::const_iterator uv0Itor = std::find( veList.begin(), - veList.end(), *uv0 ); - unsigned short elem_idx = std::distance( veList.begin(), uv0Itor ); - VertexElementType newType = VertexElement::multiplyTypeCount( baseType0, - totalTypeCount ); - - if( ( uv0->getOffset() + uv0->getSize() == uv1->getOffset() || - uv1->getOffset() + uv1->getSize() == uv0->getOffset() ) && - uv0->getSource() == uv1->getSource() ) - { - //Special case where they adjacent, just change the declaration & we're done. - size_t newOffset = std::min( uv0->getOffset(), uv1->getOffset() ); - unsigned short newIdx = std::min( uv0->getIndex(), uv1->getIndex() ); - - vDecl->modifyElement( elem_idx, uv0->getSource(), newOffset, newType, - VES_TEXTURE_COORDINATES, newIdx ); - vDecl->removeElement( VES_TEXTURE_COORDINATES, texCoordSetToDestroy ); - uv1 = 0; - } - - vDecl->closeGapsInSource(); - } - } - } + void Mesh::setIndexBufferPolicy(HardwareBuffer::Usage vbUsage, bool shadowBuffer) + { + mIndexBufferUsage = vbUsage; + mIndexBufferShadowBuffer = shadowBuffer; + } + //--------------------------------------------------------------------- + void Mesh::mergeAdjacentTexcoords( unsigned short finalTexCoordSet, + unsigned short texCoordSetToDestroy ) + { + if( sharedVertexData ) + mergeAdjacentTexcoords( finalTexCoordSet, texCoordSetToDestroy, sharedVertexData ); + + SubMeshList::const_iterator itor = mSubMeshList.begin(); + SubMeshList::const_iterator end = mSubMeshList.end(); + + while( itor != end ) + { + if( !(*itor)->useSharedVertices ) + mergeAdjacentTexcoords( finalTexCoordSet, texCoordSetToDestroy, (*itor)->vertexData ); + ++itor; + } + } + //--------------------------------------------------------------------- + void Mesh::mergeAdjacentTexcoords( unsigned short finalTexCoordSet, + unsigned short texCoordSetToDestroy, + VertexData *vertexData ) + { + VertexDeclaration *vDecl = vertexData->vertexDeclaration; + + const VertexElement *uv0 = vDecl->findElementBySemantic( VES_TEXTURE_COORDINATES, + finalTexCoordSet ); + const VertexElement *uv1 = vDecl->findElementBySemantic( VES_TEXTURE_COORDINATES, + texCoordSetToDestroy ); + + if( uv0 && uv1 ) + { + //Check that both base types are compatible (mix floats w/ shorts) and there's enough space + VertexElementType baseType0 = VertexElement::getBaseType( uv0->getType() ); + VertexElementType baseType1 = VertexElement::getBaseType( uv1->getType() ); + + unsigned short totalTypeCount = VertexElement::getTypeCount( uv0->getType() ) + + VertexElement::getTypeCount( uv1->getType() ); + if( baseType0 == baseType1 && totalTypeCount <= 4 ) + { + const VertexDeclaration::VertexElementList &veList = vDecl->getElements(); + VertexDeclaration::VertexElementList::const_iterator uv0Itor = std::find( veList.begin(), + veList.end(), *uv0 ); + unsigned short elem_idx = std::distance( veList.begin(), uv0Itor ); + VertexElementType newType = VertexElement::multiplyTypeCount( baseType0, + totalTypeCount ); + + if( ( uv0->getOffset() + uv0->getSize() == uv1->getOffset() || + uv1->getOffset() + uv1->getSize() == uv0->getOffset() ) && + uv0->getSource() == uv1->getSource() ) + { + //Special case where they adjacent, just change the declaration & we're done. + size_t newOffset = std::min( uv0->getOffset(), uv1->getOffset() ); + unsigned short newIdx = std::min( uv0->getIndex(), uv1->getIndex() ); + + vDecl->modifyElement( elem_idx, uv0->getSource(), newOffset, newType, + VES_TEXTURE_COORDINATES, newIdx ); + vDecl->removeElement( VES_TEXTURE_COORDINATES, texCoordSetToDestroy ); + uv1 = 0; + } + + vDecl->closeGapsInSource(); + } + } + } //--------------------------------------------------------------------- void Mesh::organiseTangentsBuffer(VertexData *vertexData, VertexElementSemantic targetSemantic, unsigned short index, - unsigned short sourceTexCoordSet) + unsigned short sourceTexCoordSet) { - VertexDeclaration *vDecl = vertexData->vertexDeclaration ; - VertexBufferBinding *vBind = vertexData->vertexBufferBinding ; + VertexDeclaration *vDecl = vertexData->vertexDeclaration ; + VertexBufferBinding *vBind = vertexData->vertexBufferBinding ; - const VertexElement *tangentsElem = vDecl->findElementBySemantic(targetSemantic, index); - bool needsToBeCreated = false; + const VertexElement *tangentsElem = vDecl->findElementBySemantic(targetSemantic, index); + bool needsToBeCreated = false; - if (!tangentsElem) + if (!tangentsElem) { // no tex coords with index 1 - needsToBeCreated = true ; - } + needsToBeCreated = true ; + } else if (tangentsElem->getType() != VET_FLOAT3) { // buffer exists, but not 3D OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Target semantic set already exists but is not 3D, therefore " - "cannot contain tangents. Pick an alternative destination semantic. ", + "cannot contain tangents. Pick an alternative destination semantic. ", "Mesh::organiseTangentsBuffer"); - } + } - HardwareVertexBufferSharedPtr newBuffer; - if (needsToBeCreated) + HardwareVertexBufferSharedPtr newBuffer; + if (needsToBeCreated) { // To be most efficient with our vertex streams, // tack the new tangents onto the same buffer as the @@ -1318,8 +1318,8 @@ namespace Ogre { { OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate the first texture coordinate element to " - "which to append the new tangents.", - "Mesh::orgagniseTangentsBuffer"); + "which to append the new tangents.", + "Mesh::orgagniseTangentsBuffer"); } // Find the buffer associated with this element HardwareVertexBufferSharedPtr origBuffer = @@ -1327,13 +1327,13 @@ namespace Ogre { prevTexCoordElem->getSource()); // Now create a new buffer, which includes the previous contents // plus extra space for the 3D coords - newBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( + newBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( origBuffer->getVertexSize() + 3*sizeof(float), vertexData->vertexCount, - origBuffer->getUsage(), - origBuffer->hasShadowBuffer() ); + origBuffer->getUsage(), + origBuffer->hasShadowBuffer() ); // Add the new element - vDecl->addElement( + vDecl->addElement( prevTexCoordElem->getSource(), origBuffer->getVertexSize(), VET_FLOAT3, @@ -1360,128 +1360,128 @@ namespace Ogre { // Rebind the new buffer vBind->setBinding(prevTexCoordElem->getSource(), newBuffer); - } + } } //--------------------------------------------------------------------- void Mesh::buildTangentVectors(VertexElementSemantic targetSemantic, - unsigned short sourceTexCoordSet, unsigned short index, - bool splitMirrored, bool splitRotated, bool storeParityInW) - { - - TangentSpaceCalc tangentsCalc; - tangentsCalc.setSplitMirrored(splitMirrored); - tangentsCalc.setSplitRotated(splitRotated); - tangentsCalc.setStoreParityInW(storeParityInW); - - // shared geometry first - if (sharedVertexData) - { - tangentsCalc.setVertexData(sharedVertexData); - bool found = false; - for (SubMeshList::iterator i = mSubMeshList.begin(); i != mSubMeshList.end(); ++i) - { - SubMesh* sm = *i; - if (sm->useSharedVertices) - { - tangentsCalc.addIndexData(sm->indexData); - found = true; - } - } - if (found) - { - TangentSpaceCalc::Result res = - tangentsCalc.build(targetSemantic, sourceTexCoordSet, index); - - // If any vertex splitting happened, we have to give them bone assignments - if (getSkeletonName() != BLANKSTRING) - { - for (TangentSpaceCalc::IndexRemapList::iterator r = res.indexesRemapped.begin(); - r != res.indexesRemapped.end(); ++r) - { - TangentSpaceCalc::IndexRemap& remap = *r; - // Copy all bone assignments from the split vertex - VertexBoneAssignmentList::iterator vbstart = mBoneAssignments.lower_bound(remap.splitVertex.first); - VertexBoneAssignmentList::iterator vbend = mBoneAssignments.upper_bound(remap.splitVertex.first); - for (VertexBoneAssignmentList::iterator vba = vbstart; vba != vbend; ++vba) - { - VertexBoneAssignment newAsgn = vba->second; - newAsgn.vertexIndex = static_cast(remap.splitVertex.second); - // multimap insert doesn't invalidate iterators - addBoneAssignment(newAsgn); - } - - } - } - - // Update poses (some vertices might have been duplicated) - // we will just check which vertices have been split and copy - // the offset for the original vertex to the corresponding new vertex - PoseIterator pose_it = getPoseIterator(); - - while( pose_it.hasMoreElements() ) - { - Pose* current_pose = pose_it.getNext(); - const Pose::VertexOffsetMap& offset_map = current_pose->getVertexOffsets(); - - for( TangentSpaceCalc::VertexSplits::iterator it = res.vertexSplits.begin(); - it != res.vertexSplits.end(); ++it ) - { - TangentSpaceCalc::VertexSplit& split = *it; - - Pose::VertexOffsetMap::const_iterator found_offset = offset_map.find( split.first ); - - // copy the offset - if( found_offset != offset_map.end() ) - { - current_pose->addVertex( split.second, found_offset->second ); - } - } - } - } - } - - // Dedicated geometry - for (SubMeshList::iterator i = mSubMeshList.begin(); i != mSubMeshList.end(); ++i) - { - SubMesh* sm = *i; - if (!sm->useSharedVertices) - { - tangentsCalc.clear(); - tangentsCalc.setVertexData(sm->vertexData); + unsigned short sourceTexCoordSet, unsigned short index, + bool splitMirrored, bool splitRotated, bool storeParityInW) + { + + TangentSpaceCalc tangentsCalc; + tangentsCalc.setSplitMirrored(splitMirrored); + tangentsCalc.setSplitRotated(splitRotated); + tangentsCalc.setStoreParityInW(storeParityInW); + + // shared geometry first + if (sharedVertexData) + { + tangentsCalc.setVertexData(sharedVertexData); + bool found = false; + for (SubMeshList::iterator i = mSubMeshList.begin(); i != mSubMeshList.end(); ++i) + { + SubMesh* sm = *i; + if (sm->useSharedVertices) + { + tangentsCalc.addIndexData(sm->indexData); + found = true; + } + } + if (found) + { + TangentSpaceCalc::Result res = + tangentsCalc.build(targetSemantic, sourceTexCoordSet, index); + + // If any vertex splitting happened, we have to give them bone assignments + if (getSkeletonName() != BLANKSTRING) + { + for (TangentSpaceCalc::IndexRemapList::iterator r = res.indexesRemapped.begin(); + r != res.indexesRemapped.end(); ++r) + { + TangentSpaceCalc::IndexRemap& remap = *r; + // Copy all bone assignments from the split vertex + VertexBoneAssignmentList::iterator vbstart = mBoneAssignments.lower_bound(remap.splitVertex.first); + VertexBoneAssignmentList::iterator vbend = mBoneAssignments.upper_bound(remap.splitVertex.first); + for (VertexBoneAssignmentList::iterator vba = vbstart; vba != vbend; ++vba) + { + VertexBoneAssignment newAsgn = vba->second; + newAsgn.vertexIndex = static_cast(remap.splitVertex.second); + // multimap insert doesn't invalidate iterators + addBoneAssignment(newAsgn); + } + + } + } + + // Update poses (some vertices might have been duplicated) + // we will just check which vertices have been split and copy + // the offset for the original vertex to the corresponding new vertex + PoseIterator pose_it = getPoseIterator(); + + while( pose_it.hasMoreElements() ) + { + Pose* current_pose = pose_it.getNext(); + const Pose::VertexOffsetMap& offset_map = current_pose->getVertexOffsets(); + + for( TangentSpaceCalc::VertexSplits::iterator it = res.vertexSplits.begin(); + it != res.vertexSplits.end(); ++it ) + { + TangentSpaceCalc::VertexSplit& split = *it; + + Pose::VertexOffsetMap::const_iterator found_offset = offset_map.find( split.first ); + + // copy the offset + if( found_offset != offset_map.end() ) + { + current_pose->addVertex( split.second, found_offset->second ); + } + } + } + } + } + + // Dedicated geometry + for (SubMeshList::iterator i = mSubMeshList.begin(); i != mSubMeshList.end(); ++i) + { + SubMesh* sm = *i; + if (!sm->useSharedVertices) + { + tangentsCalc.clear(); + tangentsCalc.setVertexData(sm->vertexData); tangentsCalc.addIndexData(sm->indexData, sm->operationType); - TangentSpaceCalc::Result res = - tangentsCalc.build(targetSemantic, sourceTexCoordSet, index); - - // If any vertex splitting happened, we have to give them bone assignments - if (getSkeletonName() != BLANKSTRING) - { - for (TangentSpaceCalc::IndexRemapList::iterator r = res.indexesRemapped.begin(); - r != res.indexesRemapped.end(); ++r) - { - TangentSpaceCalc::IndexRemap& remap = *r; - // Copy all bone assignments from the split vertex - VertexBoneAssignmentList::const_iterator vbstart = - sm->getBoneAssignments().lower_bound(remap.splitVertex.first); - VertexBoneAssignmentList::const_iterator vbend = - sm->getBoneAssignments().upper_bound(remap.splitVertex.first); - for (VertexBoneAssignmentList::const_iterator vba = vbstart; vba != vbend; ++vba) - { - VertexBoneAssignment newAsgn = vba->second; - newAsgn.vertexIndex = static_cast(remap.splitVertex.second); - // multimap insert doesn't invalidate iterators - sm->addBoneAssignment(newAsgn); - } - - } - - } - } - } + TangentSpaceCalc::Result res = + tangentsCalc.build(targetSemantic, sourceTexCoordSet, index); + + // If any vertex splitting happened, we have to give them bone assignments + if (getSkeletonName() != BLANKSTRING) + { + for (TangentSpaceCalc::IndexRemapList::iterator r = res.indexesRemapped.begin(); + r != res.indexesRemapped.end(); ++r) + { + TangentSpaceCalc::IndexRemap& remap = *r; + // Copy all bone assignments from the split vertex + VertexBoneAssignmentList::const_iterator vbstart = + sm->getBoneAssignments().lower_bound(remap.splitVertex.first); + VertexBoneAssignmentList::const_iterator vbend = + sm->getBoneAssignments().upper_bound(remap.splitVertex.first); + for (VertexBoneAssignmentList::const_iterator vba = vbstart; vba != vbend; ++vba) + { + VertexBoneAssignment newAsgn = vba->second; + newAsgn.vertexIndex = static_cast(remap.splitVertex.second); + // multimap insert doesn't invalidate iterators + sm->addBoneAssignment(newAsgn); + } + + } + + } + } + } } //--------------------------------------------------------------------- bool Mesh::suggestTangentVectorBuildParams(VertexElementSemantic targetSemantic, - unsigned short& outSourceCoordSet, unsigned short& outIndex) + unsigned short& outSourceCoordSet, unsigned short& outIndex) { // Go through all the vertex data and locate source and dest (must agree) bool sharedGeometryDone = false; @@ -1526,7 +1526,7 @@ namespace Ogre { } } - if(!foundExisting && targetSemantic == VES_TEXTURE_COORDINATES) + if(!foundExisting && targetSemantic == VES_TEXTURE_COORDINATES) { // We're looking for the destination // Check to see if we've found a possible @@ -1540,19 +1540,19 @@ namespace Ogre { } - if (!foundExisting && targetSemantic != VES_TEXTURE_COORDINATES) - { - targetIndex = 0; - // Look for existing semantic - const VertexElement* testElem = - vertexData->vertexDeclaration->findElementBySemantic( - targetSemantic, targetIndex); - if (testElem) - { - foundExisting = true; - } + if (!foundExisting && targetSemantic != VES_TEXTURE_COORDINATES) + { + targetIndex = 0; + // Look for existing semantic + const VertexElement* testElem = + vertexData->vertexDeclaration->findElementBySemantic( + targetSemantic, targetIndex); + if (testElem) + { + foundExisting = true; + } - } + } // After iterating, we should have a source and a possible destination (t) if (!sourceElem) @@ -1611,10 +1611,10 @@ namespace Ogre { { // Delegate edge building to manual mesh // It should have already built it's own edge list while loading - if (!usage.manualMesh.isNull()) - { - usage.edgeData = usage.manualMesh->getEdgeList(0); - } + if (!usage.manualMesh.isNull()) + { + usage.edgeData = usage.manualMesh->getEdgeList(0); + } } else { @@ -1635,12 +1635,12 @@ namespace Ogre { for (i = mSubMeshList.begin(); i != iend; ++i) { SubMesh* s = *i; - if (s->operationType != RenderOperation::OT_TRIANGLE_FAN && - s->operationType != RenderOperation::OT_TRIANGLE_LIST && - s->operationType != RenderOperation::OT_TRIANGLE_STRIP) - { + if (s->operationType != RenderOperation::OT_TRIANGLE_FAN && + s->operationType != RenderOperation::OT_TRIANGLE_LIST && + s->operationType != RenderOperation::OT_TRIANGLE_STRIP) + { continue; - } + } if (s->useSharedVertices) { // Use shared vertex data, index as set 0 @@ -1672,12 +1672,12 @@ namespace Ogre { } } - atLeastOneIndexSet = true; + atLeastOneIndexSet = true; } if (atLeastOneIndexSet) - { - usage.edgeData = eb.build(); + { + usage.edgeData = eb.build(); #if OGRE_DEBUG_MODE // Override default log @@ -1685,63 +1685,63 @@ namespace Ogre { mName + "_lod" + StringConverter::toString(lodIndex) + "_prepshadow.log", false, false); usage.edgeData->log(log); - // clean up log & close file handle - LogManager::getSingleton().destroyLog(log); + // clean up log & close file handle + LogManager::getSingleton().destroyLog(log); #endif - } - else - { - // create empty edge data - usage.edgeData = OGRE_NEW EdgeData(); - } + } + else + { + // create empty edge data + usage.edgeData = OGRE_NEW EdgeData(); + } } } #else - // Build - EdgeListBuilder eb; - size_t vertexSetCount = 0; - if (sharedVertexData) - { - eb.addVertexData(sharedVertexData); - vertexSetCount++; - } - - // Prepare the builder using the submesh information - SubMeshList::iterator i, iend; - iend = mSubMeshList.end(); - for (i = mSubMeshList.begin(); i != iend; ++i) - { - SubMesh* s = *i; - if (s->operationType != RenderOperation::OT_TRIANGLE_FAN && - s->operationType != RenderOperation::OT_TRIANGLE_LIST && - s->operationType != RenderOperation::OT_TRIANGLE_STRIP) - { - continue; - } - if (s->useSharedVertices) - { - eb.addIndexData(s->indexData, 0, s->operationType); - } - else if(s->isBuildEdgesEnabled()) - { - // own vertex data, add it and reference it directly - eb.addVertexData(s->vertexData); - // Base index data - eb.addIndexData(s->indexData, vertexSetCount++, - s->operationType); - } - } - - mMeshLodUsageList[0].edgeData = eb.build(); + // Build + EdgeListBuilder eb; + size_t vertexSetCount = 0; + if (sharedVertexData) + { + eb.addVertexData(sharedVertexData); + vertexSetCount++; + } + + // Prepare the builder using the submesh information + SubMeshList::iterator i, iend; + iend = mSubMeshList.end(); + for (i = mSubMeshList.begin(); i != iend; ++i) + { + SubMesh* s = *i; + if (s->operationType != RenderOperation::OT_TRIANGLE_FAN && + s->operationType != RenderOperation::OT_TRIANGLE_LIST && + s->operationType != RenderOperation::OT_TRIANGLE_STRIP) + { + continue; + } + if (s->useSharedVertices) + { + eb.addIndexData(s->indexData, 0, s->operationType); + } + else if(s->isBuildEdgesEnabled()) + { + // own vertex data, add it and reference it directly + eb.addVertexData(s->vertexData); + // Base index data + eb.addIndexData(s->indexData, vertexSetCount++, + s->operationType); + } + } + + mMeshLodUsageList[0].edgeData = eb.build(); #if OGRE_DEBUG_MODE - // Override default log - Log* log = LogManager::getSingleton().createLog( - mName + "_lod0"+ - "_prepshadow.log", false, false); - mMeshLodUsageList[0].edgeData->log(log); - // clean up log & close file handle - LogManager::getSingleton().destroyLog(log); + // Override default log + Log* log = LogManager::getSingleton().createLog( + mName + "_lod0"+ + "_prepshadow.log", false, false); + mMeshLodUsageList[0].edgeData->log(log); + // clean up log & close file handle + LogManager::getSingleton().destroyLog(log); #endif #endif mEdgeListsBuilt = true; @@ -1769,8 +1769,8 @@ namespace Ogre { usage.edgeData = NULL; } #else - OGRE_DELETE mMeshLodUsageList[0].edgeData; - mMeshLodUsageList[0].edgeData = NULL; + OGRE_DELETE mMeshLodUsageList[0].edgeData; + mMeshLodUsageList[0].edgeData = NULL; #endif mEdgeListsBuilt = false; } @@ -1790,9 +1790,9 @@ namespace Ogre { { SubMesh* s = *i; if (!s->useSharedVertices && - (s->operationType == RenderOperation::OT_TRIANGLE_FAN || - s->operationType == RenderOperation::OT_TRIANGLE_LIST || - s->operationType == RenderOperation::OT_TRIANGLE_STRIP)) + (s->operationType == RenderOperation::OT_TRIANGLE_FAN || + s->operationType == RenderOperation::OT_TRIANGLE_LIST || + s->operationType == RenderOperation::OT_TRIANGLE_STRIP)) { s->vertexData->prepareForShadowVolume(); } @@ -1808,20 +1808,20 @@ namespace Ogre { buildEdgeList(); } #if !OGRE_NO_MESHLOD - return getLodLevel(lodIndex).edgeData; + return getLodLevel(lodIndex).edgeData; #else - assert(lodIndex == 0); - return mMeshLodUsageList[0].edgeData; + assert(lodIndex == 0); + return mMeshLodUsageList[0].edgeData; #endif } //--------------------------------------------------------------------- const EdgeData* Mesh::getEdgeList(unsigned short lodIndex) const { #if !OGRE_NO_MESHLOD - return getLodLevel(lodIndex).edgeData; + return getLodLevel(lodIndex).edgeData; #else - assert(lodIndex == 0); - return mMeshLodUsageList[0].edgeData; + assert(lodIndex == 0); + return mMeshLodUsageList[0].edgeData; #endif } //--------------------------------------------------------------------- @@ -1879,9 +1879,9 @@ namespace Ogre { // Get buffers for source HardwareVertexBufferSharedPtr srcPosBuf = sourceVertexData->vertexBufferBinding->getBuffer(srcElemPos->getSource()); - HardwareVertexBufferSharedPtr srcIdxBuf = sourceVertexData->vertexBufferBinding->getBuffer(srcElemBlendIndices->getSource()); - HardwareVertexBufferSharedPtr srcWeightBuf = sourceVertexData->vertexBufferBinding->getBuffer(srcElemBlendWeights->getSource()); - HardwareVertexBufferSharedPtr srcNormBuf; + HardwareVertexBufferSharedPtr srcIdxBuf = sourceVertexData->vertexBufferBinding->getBuffer(srcElemBlendIndices->getSource()); + HardwareVertexBufferSharedPtr srcWeightBuf = sourceVertexData->vertexBufferBinding->getBuffer(srcElemBlendWeights->getSource()); + HardwareVertexBufferSharedPtr srcNormBuf; srcPosStride = srcPosBuf->getVertexSize(); @@ -1895,7 +1895,7 @@ namespace Ogre { } // Get buffers for target HardwareVertexBufferSharedPtr destPosBuf = targetVertexData->vertexBufferBinding->getBuffer(destElemPos->getSource()); - HardwareVertexBufferSharedPtr destNormBuf; + HardwareVertexBufferSharedPtr destNormBuf; destPosStride = destPosBuf->getVertexSize(); if (includeNormals) { @@ -1980,470 +1980,470 @@ namespace Ogre { } } - //--------------------------------------------------------------------- - void Mesh::softwareVertexMorph(Real t, - const HardwareVertexBufferSharedPtr& b1, - const HardwareVertexBufferSharedPtr& b2, - VertexData* targetVertexData) - { - float* pb1 = static_cast(b1->lock(HardwareBuffer::HBL_READ_ONLY)); - float* pb2; - if (b1.get() != b2.get()) - { - pb2 = static_cast(b2->lock(HardwareBuffer::HBL_READ_ONLY)); - } - else - { - // Same buffer - track with only one entry or time index exactly matching - // one keyframe - // For simplicity of main code, interpolate still but with same val - pb2 = pb1; - } - - const VertexElement* posElem = - targetVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - assert(posElem); - const VertexElement* normElem = - targetVertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL); - - bool morphNormals = false; - if (normElem && normElem->getSource() == posElem->getSource() && - b1->getVertexSize() == 24 && b2->getVertexSize() == 24) - morphNormals = true; - - HardwareVertexBufferSharedPtr destBuf = - targetVertexData->vertexBufferBinding->getBuffer( - posElem->getSource()); - assert((posElem->getSize() == destBuf->getVertexSize() - || (morphNormals && posElem->getSize() + normElem->getSize() == destBuf->getVertexSize())) && - "Positions (or positions & normals) must be in a buffer on their own for morphing"); - float* pdst = static_cast( - destBuf->lock(HardwareBuffer::HBL_DISCARD)); + //--------------------------------------------------------------------- + void Mesh::softwareVertexMorph(Real t, + const HardwareVertexBufferSharedPtr& b1, + const HardwareVertexBufferSharedPtr& b2, + VertexData* targetVertexData) + { + float* pb1 = static_cast(b1->lock(HardwareBuffer::HBL_READ_ONLY)); + float* pb2; + if (b1.get() != b2.get()) + { + pb2 = static_cast(b2->lock(HardwareBuffer::HBL_READ_ONLY)); + } + else + { + // Same buffer - track with only one entry or time index exactly matching + // one keyframe + // For simplicity of main code, interpolate still but with same val + pb2 = pb1; + } + + const VertexElement* posElem = + targetVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + assert(posElem); + const VertexElement* normElem = + targetVertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL); + + bool morphNormals = false; + if (normElem && normElem->getSource() == posElem->getSource() && + b1->getVertexSize() == 24 && b2->getVertexSize() == 24) + morphNormals = true; + + HardwareVertexBufferSharedPtr destBuf = + targetVertexData->vertexBufferBinding->getBuffer( + posElem->getSource()); + assert((posElem->getSize() == destBuf->getVertexSize() + || (morphNormals && posElem->getSize() + normElem->getSize() == destBuf->getVertexSize())) && + "Positions (or positions & normals) must be in a buffer on their own for morphing"); + float* pdst = static_cast( + destBuf->lock(HardwareBuffer::HBL_DISCARD)); OptimisedUtil::getImplementation()->softwareVertexMorph( t, pb1, pb2, pdst, - b1->getVertexSize(), b2->getVertexSize(), destBuf->getVertexSize(), + b1->getVertexSize(), b2->getVertexSize(), destBuf->getVertexSize(), targetVertexData->vertexCount, - morphNormals); - - destBuf->unlock(); - b1->unlock(); - if (b1.get() != b2.get()) - b2->unlock(); - } - //--------------------------------------------------------------------- - void Mesh::softwareVertexPoseBlend(Real weight, - const map::type& vertexOffsetMap, - const map::type& normalsMap, - VertexData* targetVertexData) - { - // Do nothing if no weight - if (weight == 0.0f) - return; - - const VertexElement* posElem = - targetVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - const VertexElement* normElem = - targetVertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL); - assert(posElem); - // Support normals if they're in the same buffer as positions and pose includes them - bool normals = normElem && !normalsMap.empty() && posElem->getSource() == normElem->getSource(); - HardwareVertexBufferSharedPtr destBuf = - targetVertexData->vertexBufferBinding->getBuffer( - posElem->getSource()); - - size_t elemsPerVertex = destBuf->getVertexSize()/sizeof(float); - - // Have to lock in normal mode since this is incremental - float* pBase = static_cast( - destBuf->lock(HardwareBuffer::HBL_NORMAL)); - - // Iterate over affected vertices - for (map::type::const_iterator i = vertexOffsetMap.begin(); - i != vertexOffsetMap.end(); ++i) - { - // Adjust pointer - float *pdst = pBase + i->first*elemsPerVertex; - - *pdst = *pdst + (i->second.x * weight); - ++pdst; - *pdst = *pdst + (i->second.y * weight); - ++pdst; - *pdst = *pdst + (i->second.z * weight); - ++pdst; - - } - - if (normals) - { - float* pNormBase; - normElem->baseVertexPointerToElement((void*)pBase, &pNormBase); - for (map::type::const_iterator i = normalsMap.begin(); - i != normalsMap.end(); ++i) - { - // Adjust pointer - float *pdst = pNormBase + i->first*elemsPerVertex; - - *pdst = *pdst + (i->second.x * weight); - ++pdst; - *pdst = *pdst + (i->second.y * weight); - ++pdst; - *pdst = *pdst + (i->second.z * weight); - ++pdst; - - } - } - destBuf->unlock(); - } + morphNormals); + + destBuf->unlock(); + b1->unlock(); + if (b1.get() != b2.get()) + b2->unlock(); + } + //--------------------------------------------------------------------- + void Mesh::softwareVertexPoseBlend(Real weight, + const map::type& vertexOffsetMap, + const map::type& normalsMap, + VertexData* targetVertexData) + { + // Do nothing if no weight + if (weight == 0.0f) + return; + + const VertexElement* posElem = + targetVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + const VertexElement* normElem = + targetVertexData->vertexDeclaration->findElementBySemantic(VES_NORMAL); + assert(posElem); + // Support normals if they're in the same buffer as positions and pose includes them + bool normals = normElem && !normalsMap.empty() && posElem->getSource() == normElem->getSource(); + HardwareVertexBufferSharedPtr destBuf = + targetVertexData->vertexBufferBinding->getBuffer( + posElem->getSource()); + + size_t elemsPerVertex = destBuf->getVertexSize()/sizeof(float); + + // Have to lock in normal mode since this is incremental + float* pBase = static_cast( + destBuf->lock(HardwareBuffer::HBL_NORMAL)); + + // Iterate over affected vertices + for (map::type::const_iterator i = vertexOffsetMap.begin(); + i != vertexOffsetMap.end(); ++i) + { + // Adjust pointer + float *pdst = pBase + i->first*elemsPerVertex; + + *pdst = *pdst + (i->second.x * weight); + ++pdst; + *pdst = *pdst + (i->second.y * weight); + ++pdst; + *pdst = *pdst + (i->second.z * weight); + ++pdst; + + } + + if (normals) + { + float* pNormBase; + normElem->baseVertexPointerToElement((void*)pBase, &pNormBase); + for (map::type::const_iterator i = normalsMap.begin(); + i != normalsMap.end(); ++i) + { + // Adjust pointer + float *pdst = pNormBase + i->first*elemsPerVertex; + + *pdst = *pdst + (i->second.x * weight); + ++pdst; + *pdst = *pdst + (i->second.y * weight); + ++pdst; + *pdst = *pdst + (i->second.z * weight); + ++pdst; + + } + } + destBuf->unlock(); + } + //--------------------------------------------------------------------- + size_t Mesh::calculateSize(void) const + { + // calculate GPU size + size_t ret = 0; + unsigned short i; + // Shared vertices + if (sharedVertexData) + { + for (i = 0; + i < sharedVertexData->vertexBufferBinding->getBufferCount(); + ++i) + { + ret += sharedVertexData->vertexBufferBinding + ->getBuffer(i)->getSizeInBytes(); + } + } + + SubMeshList::const_iterator si; + for (si = mSubMeshList.begin(); si != mSubMeshList.end(); ++si) + { + // Dedicated vertices + if (!(*si)->useSharedVertices) + { + for (i = 0; + i < (*si)->vertexData->vertexBufferBinding->getBufferCount(); + ++i) + { + ret += (*si)->vertexData->vertexBufferBinding + ->getBuffer(i)->getSizeInBytes(); + } + } + if (!(*si)->indexData->indexBuffer.isNull()) + { + // Index data + ret += (*si)->indexData->indexBuffer->getSizeInBytes(); + } + + } + return ret; + } + //----------------------------------------------------------------------------- + bool Mesh::hasVertexAnimation(void) const + { + return !mAnimationsList.empty(); + } + //--------------------------------------------------------------------- + VertexAnimationType Mesh::getSharedVertexDataAnimationType(void) const + { + if (mAnimationTypesDirty) + { + _determineAnimationTypes(); + } + + return mSharedVertexDataAnimationType; + } + //--------------------------------------------------------------------- + void Mesh::_determineAnimationTypes(void) const + { + // Don't check flag here; since detail checks on track changes are not + // done, allow caller to force if they need to + + // Initialise all types to nothing + mSharedVertexDataAnimationType = VAT_NONE; + mSharedVertexDataAnimationIncludesNormals = false; + for (SubMeshList::const_iterator i = mSubMeshList.begin(); + i != mSubMeshList.end(); ++i) + { + (*i)->mVertexAnimationType = VAT_NONE; + (*i)->mVertexAnimationIncludesNormals = false; + } + + mPosesIncludeNormals = false; + for (PoseList::const_iterator i = mPoseList.begin(); i != mPoseList.end(); ++i) + { + if (i == mPoseList.begin()) + mPosesIncludeNormals = (*i)->getIncludesNormals(); + else if (mPosesIncludeNormals != (*i)->getIncludesNormals()) + // only support normals if consistently included + mPosesIncludeNormals = mPosesIncludeNormals && (*i)->getIncludesNormals(); + } + + // Scan all animations and determine the type of animation tracks + // relating to each vertex data + for(AnimationList::const_iterator ai = mAnimationsList.begin(); + ai != mAnimationsList.end(); ++ai) + { + Animation* anim = ai->second; + Animation::VertexTrackIterator vit = anim->getVertexTrackIterator(); + while (vit.hasMoreElements()) + { + VertexAnimationTrack* track = vit.getNext(); + ushort handle = track->getHandle(); + if (handle == 0) + { + // shared data + if (mSharedVertexDataAnimationType != VAT_NONE && + mSharedVertexDataAnimationType != track->getAnimationType()) + { + // Mixing of morph and pose animation on same data is not allowed + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Animation tracks for shared vertex data on mesh " + + mName + " try to mix vertex animation types, which is " + "not allowed.", + "Mesh::_determineAnimationTypes"); + } + mSharedVertexDataAnimationType = track->getAnimationType(); + if (track->getAnimationType() == VAT_MORPH) + mSharedVertexDataAnimationIncludesNormals = track->getVertexAnimationIncludesNormals(); + else + mSharedVertexDataAnimationIncludesNormals = mPosesIncludeNormals; + + } + else + { + // submesh index (-1) + SubMesh* sm = getSubMesh(handle-1); + if (sm->mVertexAnimationType != VAT_NONE && + sm->mVertexAnimationType != track->getAnimationType()) + { + // Mixing of morph and pose animation on same data is not allowed + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Animation tracks for dedicated vertex data " + + StringConverter::toString(handle-1) + " on mesh " + + mName + " try to mix vertex animation types, which is " + "not allowed.", + "Mesh::_determineAnimationTypes"); + } + sm->mVertexAnimationType = track->getAnimationType(); + if (track->getAnimationType() == VAT_MORPH) + sm->mVertexAnimationIncludesNormals = track->getVertexAnimationIncludesNormals(); + else + sm->mVertexAnimationIncludesNormals = mPosesIncludeNormals; + + } + } + } + + mAnimationTypesDirty = false; + } + //--------------------------------------------------------------------- + Animation* Mesh::createAnimation(const String& name, Real length) + { + // Check name not used + if (mAnimationsList.find(name) != mAnimationsList.end()) + { + OGRE_EXCEPT( + Exception::ERR_DUPLICATE_ITEM, + "An animation with the name " + name + " already exists", + "Mesh::createAnimation"); + } + + Animation* ret = OGRE_NEW Animation(name, length); + ret->_notifyContainer(this); + + // Add to list + mAnimationsList[name] = ret; + + // Mark animation types dirty + mAnimationTypesDirty = true; + + return ret; + + } + //--------------------------------------------------------------------- + Animation* Mesh::getAnimation(const String& name) const + { + Animation* ret = _getAnimationImpl(name); + if (!ret) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "No animation entry found named " + name, + "Mesh::getAnimation"); + } + + return ret; + } + //--------------------------------------------------------------------- + Animation* Mesh::getAnimation(unsigned short index) const + { + // If you hit this assert, then the index is out of bounds. + assert( index < mAnimationsList.size() ); + + AnimationList::const_iterator i = mAnimationsList.begin(); + + std::advance(i, index); + + return i->second; + + } + //--------------------------------------------------------------------- + unsigned short Mesh::getNumAnimations(void) const + { + return static_cast(mAnimationsList.size()); + } + //--------------------------------------------------------------------- + bool Mesh::hasAnimation(const String& name) const + { + return _getAnimationImpl(name) != 0; + } + //--------------------------------------------------------------------- + Animation* Mesh::_getAnimationImpl(const String& name) const + { + Animation* ret = 0; + AnimationList::const_iterator i = mAnimationsList.find(name); + + if (i != mAnimationsList.end()) + { + ret = i->second; + } + + return ret; + + } + //--------------------------------------------------------------------- + void Mesh::removeAnimation(const String& name) + { + AnimationList::iterator i = mAnimationsList.find(name); + + if (i == mAnimationsList.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No animation entry found named " + name, + "Mesh::getAnimation"); + } + + OGRE_DELETE i->second; + + mAnimationsList.erase(i); + + mAnimationTypesDirty = true; + } + //--------------------------------------------------------------------- + void Mesh::removeAllAnimations(void) + { + AnimationList::iterator i = mAnimationsList.begin(); + for (; i != mAnimationsList.end(); ++i) + { + OGRE_DELETE i->second; + } + mAnimationsList.clear(); + mAnimationTypesDirty = true; + } //--------------------------------------------------------------------- - size_t Mesh::calculateSize(void) const - { - // calculate GPU size - size_t ret = 0; - unsigned short i; - // Shared vertices - if (sharedVertexData) - { - for (i = 0; - i < sharedVertexData->vertexBufferBinding->getBufferCount(); - ++i) - { - ret += sharedVertexData->vertexBufferBinding - ->getBuffer(i)->getSizeInBytes(); - } - } - - SubMeshList::const_iterator si; - for (si = mSubMeshList.begin(); si != mSubMeshList.end(); ++si) - { - // Dedicated vertices - if (!(*si)->useSharedVertices) - { - for (i = 0; - i < (*si)->vertexData->vertexBufferBinding->getBufferCount(); - ++i) - { - ret += (*si)->vertexData->vertexBufferBinding - ->getBuffer(i)->getSizeInBytes(); - } - } - if (!(*si)->indexData->indexBuffer.isNull()) - { - // Index data - ret += (*si)->indexData->indexBuffer->getSizeInBytes(); - } - - } - return ret; - } - //----------------------------------------------------------------------------- - bool Mesh::hasVertexAnimation(void) const - { - return !mAnimationsList.empty(); - } - //--------------------------------------------------------------------- - VertexAnimationType Mesh::getSharedVertexDataAnimationType(void) const - { - if (mAnimationTypesDirty) - { - _determineAnimationTypes(); - } - - return mSharedVertexDataAnimationType; - } - //--------------------------------------------------------------------- - void Mesh::_determineAnimationTypes(void) const - { - // Don't check flag here; since detail checks on track changes are not - // done, allow caller to force if they need to - - // Initialise all types to nothing - mSharedVertexDataAnimationType = VAT_NONE; - mSharedVertexDataAnimationIncludesNormals = false; - for (SubMeshList::const_iterator i = mSubMeshList.begin(); - i != mSubMeshList.end(); ++i) - { - (*i)->mVertexAnimationType = VAT_NONE; - (*i)->mVertexAnimationIncludesNormals = false; - } - - mPosesIncludeNormals = false; - for (PoseList::const_iterator i = mPoseList.begin(); i != mPoseList.end(); ++i) - { - if (i == mPoseList.begin()) - mPosesIncludeNormals = (*i)->getIncludesNormals(); - else if (mPosesIncludeNormals != (*i)->getIncludesNormals()) - // only support normals if consistently included - mPosesIncludeNormals = mPosesIncludeNormals && (*i)->getIncludesNormals(); - } - - // Scan all animations and determine the type of animation tracks - // relating to each vertex data - for(AnimationList::const_iterator ai = mAnimationsList.begin(); - ai != mAnimationsList.end(); ++ai) - { - Animation* anim = ai->second; - Animation::VertexTrackIterator vit = anim->getVertexTrackIterator(); - while (vit.hasMoreElements()) - { - VertexAnimationTrack* track = vit.getNext(); - ushort handle = track->getHandle(); - if (handle == 0) - { - // shared data - if (mSharedVertexDataAnimationType != VAT_NONE && - mSharedVertexDataAnimationType != track->getAnimationType()) - { - // Mixing of morph and pose animation on same data is not allowed - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Animation tracks for shared vertex data on mesh " - + mName + " try to mix vertex animation types, which is " - "not allowed.", - "Mesh::_determineAnimationTypes"); - } - mSharedVertexDataAnimationType = track->getAnimationType(); - if (track->getAnimationType() == VAT_MORPH) - mSharedVertexDataAnimationIncludesNormals = track->getVertexAnimationIncludesNormals(); - else - mSharedVertexDataAnimationIncludesNormals = mPosesIncludeNormals; - - } - else - { - // submesh index (-1) - SubMesh* sm = getSubMesh(handle-1); - if (sm->mVertexAnimationType != VAT_NONE && - sm->mVertexAnimationType != track->getAnimationType()) - { - // Mixing of morph and pose animation on same data is not allowed - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Animation tracks for dedicated vertex data " - + StringConverter::toString(handle-1) + " on mesh " - + mName + " try to mix vertex animation types, which is " - "not allowed.", - "Mesh::_determineAnimationTypes"); - } - sm->mVertexAnimationType = track->getAnimationType(); - if (track->getAnimationType() == VAT_MORPH) - sm->mVertexAnimationIncludesNormals = track->getVertexAnimationIncludesNormals(); - else - sm->mVertexAnimationIncludesNormals = mPosesIncludeNormals; - - } - } - } - - mAnimationTypesDirty = false; - } - //--------------------------------------------------------------------- - Animation* Mesh::createAnimation(const String& name, Real length) - { - // Check name not used - if (mAnimationsList.find(name) != mAnimationsList.end()) - { - OGRE_EXCEPT( - Exception::ERR_DUPLICATE_ITEM, - "An animation with the name " + name + " already exists", - "Mesh::createAnimation"); - } - - Animation* ret = OGRE_NEW Animation(name, length); - ret->_notifyContainer(this); - - // Add to list - mAnimationsList[name] = ret; - - // Mark animation types dirty - mAnimationTypesDirty = true; - - return ret; - - } - //--------------------------------------------------------------------- - Animation* Mesh::getAnimation(const String& name) const - { - Animation* ret = _getAnimationImpl(name); - if (!ret) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "No animation entry found named " + name, - "Mesh::getAnimation"); - } - - return ret; - } - //--------------------------------------------------------------------- - Animation* Mesh::getAnimation(unsigned short index) const - { - // If you hit this assert, then the index is out of bounds. - assert( index < mAnimationsList.size() ); - - AnimationList::const_iterator i = mAnimationsList.begin(); - - std::advance(i, index); - - return i->second; - - } - //--------------------------------------------------------------------- - unsigned short Mesh::getNumAnimations(void) const - { - return static_cast(mAnimationsList.size()); - } - //--------------------------------------------------------------------- - bool Mesh::hasAnimation(const String& name) const - { - return _getAnimationImpl(name) != 0; - } - //--------------------------------------------------------------------- - Animation* Mesh::_getAnimationImpl(const String& name) const - { - Animation* ret = 0; - AnimationList::const_iterator i = mAnimationsList.find(name); - - if (i != mAnimationsList.end()) - { - ret = i->second; - } - - return ret; - - } - //--------------------------------------------------------------------- - void Mesh::removeAnimation(const String& name) - { - AnimationList::iterator i = mAnimationsList.find(name); - - if (i == mAnimationsList.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No animation entry found named " + name, - "Mesh::getAnimation"); - } - - OGRE_DELETE i->second; - - mAnimationsList.erase(i); - - mAnimationTypesDirty = true; - } - //--------------------------------------------------------------------- - void Mesh::removeAllAnimations(void) - { - AnimationList::iterator i = mAnimationsList.begin(); - for (; i != mAnimationsList.end(); ++i) - { - OGRE_DELETE i->second; - } - mAnimationsList.clear(); - mAnimationTypesDirty = true; - } - //--------------------------------------------------------------------- - VertexData* Mesh::getVertexDataByTrackHandle(unsigned short handle) - { - if (handle == 0) - { - return sharedVertexData; - } - else - { - return getSubMesh(handle-1)->vertexData; - } - } - //--------------------------------------------------------------------- - Pose* Mesh::createPose(ushort target, const String& name) - { - Pose* retPose = OGRE_NEW Pose(target, name); - mPoseList.push_back(retPose); - return retPose; - } - //--------------------------------------------------------------------- - Pose* Mesh::getPose(ushort index) - { - if (index >= getPoseCount()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Index out of bounds", - "Mesh::getPose"); - } - - return mPoseList[index]; - - } - //--------------------------------------------------------------------- - Pose* Mesh::getPose(const String& name) - { - for (PoseList::iterator i = mPoseList.begin(); i != mPoseList.end(); ++i) - { - if ((*i)->getName() == name) - return *i; - } - StringStream str; - str << "No pose called " << name << " found in Mesh " << mName; - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - str.str(), - "Mesh::getPose"); - - } - //--------------------------------------------------------------------- - void Mesh::removePose(ushort index) - { - if (index >= getPoseCount()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Index out of bounds", - "Mesh::removePose"); - } - PoseList::iterator i = mPoseList.begin(); - std::advance(i, index); - OGRE_DELETE *i; - mPoseList.erase(i); - - } - //--------------------------------------------------------------------- - void Mesh::removePose(const String& name) - { - for (PoseList::iterator i = mPoseList.begin(); i != mPoseList.end(); ++i) - { - if ((*i)->getName() == name) - { - OGRE_DELETE *i; - mPoseList.erase(i); - return; - } - } - StringStream str; - str << "No pose called " << name << " found in Mesh " << mName; - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - str.str(), - "Mesh::removePose"); - } - //--------------------------------------------------------------------- - void Mesh::removeAllPoses(void) - { - for (PoseList::iterator i = mPoseList.begin(); i != mPoseList.end(); ++i) - { - OGRE_DELETE *i; - } - mPoseList.clear(); - } - //--------------------------------------------------------------------- - Mesh::PoseIterator Mesh::getPoseIterator(void) - { - return PoseIterator(mPoseList.begin(), mPoseList.end()); - } - //--------------------------------------------------------------------- - Mesh::ConstPoseIterator Mesh::getPoseIterator(void) const - { - return ConstPoseIterator(mPoseList.begin(), mPoseList.end()); - } - //----------------------------------------------------------------------------- - const PoseList& Mesh::getPoseList(void) const - { - return mPoseList; - } - //--------------------------------------------------------------------- - void Mesh::updateMaterialForAllSubMeshes(void) - { + VertexData* Mesh::getVertexDataByTrackHandle(unsigned short handle) + { + if (handle == 0) + { + return sharedVertexData; + } + else + { + return getSubMesh(handle-1)->vertexData; + } + } + //--------------------------------------------------------------------- + Pose* Mesh::createPose(ushort target, const String& name) + { + Pose* retPose = OGRE_NEW Pose(target, name); + mPoseList.push_back(retPose); + return retPose; + } + //--------------------------------------------------------------------- + Pose* Mesh::getPose(ushort index) + { + if (index >= getPoseCount()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Index out of bounds", + "Mesh::getPose"); + } + + return mPoseList[index]; + + } + //--------------------------------------------------------------------- + Pose* Mesh::getPose(const String& name) + { + for (PoseList::iterator i = mPoseList.begin(); i != mPoseList.end(); ++i) + { + if ((*i)->getName() == name) + return *i; + } + StringStream str; + str << "No pose called " << name << " found in Mesh " << mName; + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + str.str(), + "Mesh::getPose"); + + } + //--------------------------------------------------------------------- + void Mesh::removePose(ushort index) + { + if (index >= getPoseCount()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Index out of bounds", + "Mesh::removePose"); + } + PoseList::iterator i = mPoseList.begin(); + std::advance(i, index); + OGRE_DELETE *i; + mPoseList.erase(i); + + } + //--------------------------------------------------------------------- + void Mesh::removePose(const String& name) + { + for (PoseList::iterator i = mPoseList.begin(); i != mPoseList.end(); ++i) + { + if ((*i)->getName() == name) + { + OGRE_DELETE *i; + mPoseList.erase(i); + return; + } + } + StringStream str; + str << "No pose called " << name << " found in Mesh " << mName; + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + str.str(), + "Mesh::removePose"); + } + //--------------------------------------------------------------------- + void Mesh::removeAllPoses(void) + { + for (PoseList::iterator i = mPoseList.begin(); i != mPoseList.end(); ++i) + { + OGRE_DELETE *i; + } + mPoseList.clear(); + } + //--------------------------------------------------------------------- + Mesh::PoseIterator Mesh::getPoseIterator(void) + { + return PoseIterator(mPoseList.begin(), mPoseList.end()); + } + //--------------------------------------------------------------------- + Mesh::ConstPoseIterator Mesh::getPoseIterator(void) const + { + return ConstPoseIterator(mPoseList.begin(), mPoseList.end()); + } + //----------------------------------------------------------------------------- + const PoseList& Mesh::getPoseList(void) const + { + return mPoseList; + } + //--------------------------------------------------------------------- + void Mesh::updateMaterialForAllSubMeshes(void) + { // iterate through each sub mesh and request the submesh to update its material vector::type::iterator subi; for (subi = mSubMeshList.begin(); subi != mSubMeshList.end(); ++subi) @@ -2452,10 +2452,10 @@ namespace Ogre { } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- const LodStrategy *Mesh::getLodStrategy() const { - return mLodStrategy; + return mLodStrategy; } #if !OGRE_NO_MESHLOD //--------------------------------------------------------------------- @@ -2467,7 +2467,7 @@ namespace Ogre { mMeshLodUsageList[0].value = mLodStrategy->getBaseValue(); // Re-transform user LOD values (starting at index 1, no need to transform base value) - for (MeshLodUsageList::iterator i = mMeshLodUsageList.begin()+1; i != mMeshLodUsageList.end(); ++i) + for (MeshLodUsageList::iterator i = mMeshLodUsageList.begin()+1; i != mMeshLodUsageList.end(); ++i) i->value = mLodStrategy->transformUserValue(i->userValue); } diff --git a/OgreMain/src/OgreMeshManager.cpp b/OgreMain/src/OgreMeshManager.cpp index c9a48486d16..2a450a7b8f1 100644 --- a/OgreMain/src/OgreMeshManager.cpp +++ b/OgreMain/src/OgreMeshManager.cpp @@ -77,52 +77,52 @@ namespace Ogre { // Create prefab objects createPrefabPlane(); - createPrefabCube(); - createPrefabSphere(); + createPrefabCube(); + createPrefabSphere(); } //----------------------------------------------------------------------- MeshManager::ResourceCreateOrRetrieveResult MeshManager::createOrRetrieve( const String& name, const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* params, - HardwareBuffer::Usage vertexBufferUsage, - HardwareBuffer::Usage indexBufferUsage, - bool vertexBufferShadowed, bool indexBufferShadowed) + HardwareBuffer::Usage vertexBufferUsage, + HardwareBuffer::Usage indexBufferUsage, + bool vertexBufferShadowed, bool indexBufferShadowed) { ResourceCreateOrRetrieveResult res = ResourceManager::createOrRetrieve(name,group,isManual,loader,params); - MeshPtr pMesh = res.first.staticCast(); - // Was it created? + MeshPtr pMesh = res.first.staticCast(); + // Was it created? if (res.second) { - pMesh->setVertexBufferPolicy(vertexBufferUsage, vertexBufferShadowed); - pMesh->setIndexBufferPolicy(indexBufferUsage, indexBufferShadowed); + pMesh->setVertexBufferPolicy(vertexBufferUsage, vertexBufferShadowed); + pMesh->setIndexBufferPolicy(indexBufferUsage, indexBufferShadowed); } return res; } //----------------------------------------------------------------------- MeshPtr MeshManager::prepare( const String& filename, const String& groupName, - HardwareBuffer::Usage vertexBufferUsage, - HardwareBuffer::Usage indexBufferUsage, - bool vertexBufferShadowed, bool indexBufferShadowed) + HardwareBuffer::Usage vertexBufferUsage, + HardwareBuffer::Usage indexBufferUsage, + bool vertexBufferShadowed, bool indexBufferShadowed) { - MeshPtr pMesh = createOrRetrieve(filename,groupName,false,0,0, + MeshPtr pMesh = createOrRetrieve(filename,groupName,false,0,0, vertexBufferUsage,indexBufferUsage, vertexBufferShadowed,indexBufferShadowed).first.staticCast(); - pMesh->prepare(); + pMesh->prepare(); return pMesh; } //----------------------------------------------------------------------- MeshPtr MeshManager::load( const String& filename, const String& groupName, - HardwareBuffer::Usage vertexBufferUsage, - HardwareBuffer::Usage indexBufferUsage, - bool vertexBufferShadowed, bool indexBufferShadowed) + HardwareBuffer::Usage vertexBufferUsage, + HardwareBuffer::Usage indexBufferUsage, + bool vertexBufferShadowed, bool indexBufferShadowed) { - MeshPtr pMesh = createOrRetrieve(filename,groupName,false,0,0, + MeshPtr pMesh = createOrRetrieve(filename,groupName,false,0,0, vertexBufferUsage,indexBufferUsage, vertexBufferShadowed,indexBufferShadowed).first.staticCast(); - pMesh->load(); + pMesh->load(); return pMesh; } //----------------------------------------------------------------------- @@ -136,20 +136,20 @@ namespace Ogre MeshPtr MeshManager::createManual( const String& name, const String& groupName, ManualResourceLoader* loader) { - // Don't try to get existing, create should fail if already exists - return create(name, groupName, true, loader); + // Don't try to get existing, create should fail if already exists + return create(name, groupName, true, loader); } //----------------------------------------------------------------------- MeshPtr MeshManager::createPlane( const String& name, const String& groupName, const Plane& plane, Real width, Real height, int xsegments, int ysegments, bool normals, unsigned short numTexCoordSets, Real xTile, Real yTile, const Vector3& upVector, - HardwareBuffer::Usage vertexBufferUsage, HardwareBuffer::Usage indexBufferUsage, - bool vertexShadowBuffer, bool indexShadowBuffer) + HardwareBuffer::Usage vertexBufferUsage, HardwareBuffer::Usage indexBufferUsage, + bool vertexShadowBuffer, bool indexShadowBuffer) { // Create manual mesh which calls back self to load MeshPtr pMesh = createManual(name, groupName, this); - // Planes can never be manifold - pMesh->setAutoBuildEdgeLists(false); + // Planes can never be manifold + pMesh->setAutoBuildEdgeLists(false); // store parameters MeshBuildParams params; params.type = MBT_PLANE; @@ -174,18 +174,18 @@ namespace Ogre return pMesh; } - - //----------------------------------------------------------------------- - MeshPtr MeshManager::createCurvedPlane( const String& name, const String& groupName, + + //----------------------------------------------------------------------- + MeshPtr MeshManager::createCurvedPlane( const String& name, const String& groupName, const Plane& plane, Real width, Real height, Real bow, int xsegments, int ysegments, bool normals, unsigned short numTexCoordSets, Real xTile, Real yTile, const Vector3& upVector, - HardwareBuffer::Usage vertexBufferUsage, HardwareBuffer::Usage indexBufferUsage, - bool vertexShadowBuffer, bool indexShadowBuffer) + HardwareBuffer::Usage vertexBufferUsage, HardwareBuffer::Usage indexBufferUsage, + bool vertexShadowBuffer, bool indexShadowBuffer) { // Create manual mesh which calls back self to load MeshPtr pMesh = createManual(name, groupName, this); - // Planes can never be manifold - pMesh->setAutoBuildEdgeLists(false); + // Planes can never be manifold + pMesh->setAutoBuildEdgeLists(false); // store parameters MeshBuildParams params; params.type = MBT_CURVED_PLANE; @@ -213,22 +213,22 @@ namespace Ogre } //----------------------------------------------------------------------- - MeshPtr MeshManager::createCurvedIllusionPlane( + MeshPtr MeshManager::createCurvedIllusionPlane( const String& name, const String& groupName, const Plane& plane, Real width, Real height, Real curvature, int xsegments, int ysegments, bool normals, unsigned short numTexCoordSets, Real uTile, Real vTile, const Vector3& upVector, - const Quaternion& orientation, + const Quaternion& orientation, HardwareBuffer::Usage vertexBufferUsage, - HardwareBuffer::Usage indexBufferUsage, - bool vertexShadowBuffer, bool indexShadowBuffer, + HardwareBuffer::Usage indexBufferUsage, + bool vertexShadowBuffer, bool indexShadowBuffer, int ySegmentsToKeep) - { + { // Create manual mesh which calls back self to load MeshPtr pMesh = createManual(name, groupName, this); - // Planes can never be manifold - pMesh->setAutoBuildEdgeLists(false); + // Planes can never be manifold + pMesh->setAutoBuildEdgeLists(false); // store parameters MeshBuildParams params; params.type = MBT_CURVED_ILLUSION_PLANE; @@ -255,11 +255,11 @@ namespace Ogre pMesh->load(); return pMesh; - } + } //----------------------------------------------------------------------- void MeshManager::tesselate2DMesh(SubMesh* sm, unsigned short meshWidth, unsigned short meshHeight, - bool doubleSided, HardwareBuffer::Usage indexBufferUsage, bool indexShadowBuffer) + bool doubleSided, HardwareBuffer::Usage indexBufferUsage, bool indexShadowBuffer) { // The mesh is built, just make a list of indexes to spit out the triangles unsigned short vInc, v, iterations; @@ -280,16 +280,16 @@ namespace Ogre // Allocate memory for faces // Num faces, width*height*2 (2 tris per square), index count is * 3 on top sm->indexData->indexCount = (meshWidth-1) * (meshHeight-1) * 2 * iterations * 3; - sm->indexData->indexBuffer = HardwareBufferManager::getSingleton(). - createIndexBuffer(HardwareIndexBuffer::IT_16BIT, - sm->indexData->indexCount, indexBufferUsage, indexShadowBuffer); + sm->indexData->indexBuffer = HardwareBufferManager::getSingleton(). + createIndexBuffer(HardwareIndexBuffer::IT_16BIT, + sm->indexData->indexCount, indexBufferUsage, indexShadowBuffer); unsigned short v1, v2, v3; //bool firstTri = true; - HardwareIndexBufferSharedPtr ibuf = sm->indexData->indexBuffer; - // Lock the whole buffer - unsigned short* pIndexes = static_cast( - ibuf->lock(HardwareBuffer::HBL_DISCARD) ); + HardwareIndexBufferSharedPtr ibuf = sm->indexData->indexBuffer; + // Lock the whole buffer + unsigned short* pIndexes = static_cast( + ibuf->lock(HardwareBuffer::HBL_DISCARD) ); while (iterations--) { @@ -337,8 +337,8 @@ namespace Ogre vInc = -vInc; } - // Unlock - ibuf->unlock(); + // Unlock + ibuf->unlock(); } @@ -350,92 +350,92 @@ namespace Ogre ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, true, // manually loaded this); - // Planes can never be manifold - msh->setAutoBuildEdgeLists(false); + // Planes can never be manifold + msh->setAutoBuildEdgeLists(false); // to preserve previous behaviour, load immediately msh->load(); } - //----------------------------------------------------------------------- - void MeshManager::createPrefabCube(void) - { - MeshPtr msh = create( - "Prefab_Cube", - ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - true, // manually loaded - this); - - // to preserve previous behaviour, load immediately - msh->load(); - } - //------------------------------------------------------------------------- - void MeshManager::createPrefabSphere(void) - { - MeshPtr msh = create( - "Prefab_Sphere", - ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - true, // manually loaded - this); - - // to preserve previous behaviour, load immediately - msh->load(); - } - //------------------------------------------------------------------------- - void MeshManager::setListener(Ogre::MeshSerializerListener *listener) - { - mListener = listener; - } - //------------------------------------------------------------------------- - MeshSerializerListener *MeshManager::getListener() - { - return mListener; - } //----------------------------------------------------------------------- - void MeshManager::loadResource(Resource* res) - { - Mesh* msh = static_cast(res); - - // attempt to create a prefab mesh - bool createdPrefab = PrefabFactory::createPrefab(msh); - - // the mesh was not a prefab.. - if(!createdPrefab) - { - // Find build parameters - MeshBuildParamsMap::iterator ibld = mMeshBuildParams.find(res); - if (ibld == mMeshBuildParams.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find build parameters for " + res->getName(), - "MeshManager::loadResource"); - } - MeshBuildParams& params = ibld->second; - - switch(params.type) - { - case MBT_PLANE: - loadManualPlane(msh, params); - break; - case MBT_CURVED_ILLUSION_PLANE: - loadManualCurvedIllusionPlane(msh, params); - break; - case MBT_CURVED_PLANE: - loadManualCurvedPlane(msh, params); - break; - default: - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Unknown build parameters for " + res->getName(), - "MeshManager::loadResource"); - } - } - } + void MeshManager::createPrefabCube(void) + { + MeshPtr msh = create( + "Prefab_Cube", + ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, + true, // manually loaded + this); + + // to preserve previous behaviour, load immediately + msh->load(); + } + //------------------------------------------------------------------------- + void MeshManager::createPrefabSphere(void) + { + MeshPtr msh = create( + "Prefab_Sphere", + ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, + true, // manually loaded + this); + + // to preserve previous behaviour, load immediately + msh->load(); + } + //------------------------------------------------------------------------- + void MeshManager::setListener(Ogre::MeshSerializerListener *listener) + { + mListener = listener; + } + //------------------------------------------------------------------------- + MeshSerializerListener *MeshManager::getListener() + { + return mListener; + } + //----------------------------------------------------------------------- + void MeshManager::loadResource(Resource* res) + { + Mesh* msh = static_cast(res); + + // attempt to create a prefab mesh + bool createdPrefab = PrefabFactory::createPrefab(msh); + + // the mesh was not a prefab.. + if(!createdPrefab) + { + // Find build parameters + MeshBuildParamsMap::iterator ibld = mMeshBuildParams.find(res); + if (ibld == mMeshBuildParams.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find build parameters for " + res->getName(), + "MeshManager::loadResource"); + } + MeshBuildParams& params = ibld->second; + + switch(params.type) + { + case MBT_PLANE: + loadManualPlane(msh, params); + break; + case MBT_CURVED_ILLUSION_PLANE: + loadManualCurvedIllusionPlane(msh, params); + break; + case MBT_CURVED_PLANE: + loadManualCurvedPlane(msh, params); + break; + default: + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Unknown build parameters for " + res->getName(), + "MeshManager::loadResource"); + } + } + } //----------------------------------------------------------------------- void MeshManager::loadManualPlane(Mesh* pMesh, MeshBuildParams& params) { - if ((params.xsegments + 1) * (params.ysegments + 1) > 65536) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Plane tessellation is too high, must generate max 65536 vertices", - __FUNCTION__); + if ((params.xsegments + 1) * (params.ysegments + 1) > 65536) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Plane tessellation is too high, must generate max 65536 vertices", + __FUNCTION__); SubMesh *pSub = pMesh->createSubMesh(); // Set up vertex data @@ -582,10 +582,10 @@ namespace Ogre //----------------------------------------------------------------------- void MeshManager::loadManualCurvedPlane(Mesh* pMesh, MeshBuildParams& params) { - if ((params.xsegments + 1) * (params.ysegments + 1) > 65536) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Plane tessellation is too high, must generate max 65536 vertices", - __FUNCTION__); + if ((params.xsegments + 1) * (params.ysegments + 1) > 65536) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Plane tessellation is too high, must generate max 65536 vertices", + __FUNCTION__); SubMesh *pSub = pMesh->createSubMesh(); // Set options @@ -678,7 +678,7 @@ namespace Ogre diff_x = (x - ((params.xsegments) / 2)) / static_cast((params.xsegments)); diff_y = (y - ((params.ysegments) / 2)) / static_cast((params.ysegments)); dist = sqrt(diff_x*diff_x + diff_y * diff_y ); - vec.z = (-sin((1-dist) * (Math::PI/2)) * params.curvature) + params.curvature; + vec.z = (-sin((1-dist) * (Math::PI/2)) * params.curvature) + params.curvature; // Transform by orientation and distance Vector3 pos = xform.transformAffine(vec); @@ -711,7 +711,7 @@ namespace Ogre //vec = Vector3::UNIT_Z; // Rotate vec = rot.transformAffine(vec); - vec.normalise(); + vec.normalise(); *pFloat++ = vec.x; *pFloat++ = vec.y; @@ -739,12 +739,12 @@ namespace Ogre //----------------------------------------------------------------------- void MeshManager::loadManualCurvedIllusionPlane(Mesh* pMesh, MeshBuildParams& params) { - if (params.ySegmentsToKeep == -1) params.ySegmentsToKeep = params.ysegments; + if (params.ySegmentsToKeep == -1) params.ySegmentsToKeep = params.ysegments; - if ((params.xsegments + 1) * (params.ySegmentsToKeep + 1) > 65536) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Plane tessellation is too high, must generate max 65536 vertices", - __FUNCTION__); + if ((params.xsegments + 1) * (params.ySegmentsToKeep + 1) > 65536) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Plane tessellation is too high, must generate max 65536 vertices", + __FUNCTION__); SubMesh *pSub = pMesh->createSubMesh(); diff --git a/OgreMain/src/OgreMeshSerializer.cpp b/OgreMain/src/OgreMeshSerializer.cpp index f572ee41eb4..5502ec46f40 100644 --- a/OgreMain/src/OgreMeshSerializer.cpp +++ b/OgreMain/src/OgreMeshSerializer.cpp @@ -38,42 +38,42 @@ namespace Ogre { const unsigned short HEADER_CHUNK_ID = 0x1000; //--------------------------------------------------------------------- MeshSerializer::MeshSerializer() - :mListener(0) + :mListener(0) { - // Init implementations - // String identifiers have not always been 100% unified with OGRE version - - // Note MUST be added in reverse order so latest is first in the list + // Init implementations + // String identifiers have not always been 100% unified with OGRE version + + // Note MUST be added in reverse order so latest is first in the list // This one is a little ugly, 1.10 is used for version 1.1 legacy meshes. // So bump up to 1.100 - mVersionData.push_back(OGRE_NEW MeshVersionData( - MESH_VERSION_1_10, "[MeshSerializer_v1.100]", - OGRE_NEW MeshSerializerImpl())); - - mVersionData.push_back(OGRE_NEW MeshVersionData( - MESH_VERSION_1_8, "[MeshSerializer_v1.8]", - OGRE_NEW MeshSerializerImpl_v1_8())); - - mVersionData.push_back(OGRE_NEW MeshVersionData( - MESH_VERSION_1_7, "[MeshSerializer_v1.41]", - OGRE_NEW MeshSerializerImpl_v1_41())); - - mVersionData.push_back(OGRE_NEW MeshVersionData( - MESH_VERSION_1_4, "[MeshSerializer_v1.40]", - OGRE_NEW MeshSerializerImpl_v1_4())); - - mVersionData.push_back(OGRE_NEW MeshVersionData( - MESH_VERSION_1_0, "[MeshSerializer_v1.30]", - OGRE_NEW MeshSerializerImpl_v1_3())); - mVersionData.push_back(OGRE_NEW MeshVersionData( - MESH_VERSION_LEGACY, "[MeshSerializer_v1.20]", - OGRE_NEW MeshSerializerImpl_v1_2())); - - mVersionData.push_back(OGRE_NEW MeshVersionData( - MESH_VERSION_LEGACY, "[MeshSerializer_v1.10]", - OGRE_NEW MeshSerializerImpl_v1_1())); - + mVersionData.push_back(OGRE_NEW MeshVersionData( + MESH_VERSION_1_10, "[MeshSerializer_v1.100]", + OGRE_NEW MeshSerializerImpl())); + + mVersionData.push_back(OGRE_NEW MeshVersionData( + MESH_VERSION_1_8, "[MeshSerializer_v1.8]", + OGRE_NEW MeshSerializerImpl_v1_8())); + + mVersionData.push_back(OGRE_NEW MeshVersionData( + MESH_VERSION_1_7, "[MeshSerializer_v1.41]", + OGRE_NEW MeshSerializerImpl_v1_41())); + + mVersionData.push_back(OGRE_NEW MeshVersionData( + MESH_VERSION_1_4, "[MeshSerializer_v1.40]", + OGRE_NEW MeshSerializerImpl_v1_4())); + + mVersionData.push_back(OGRE_NEW MeshVersionData( + MESH_VERSION_1_0, "[MeshSerializer_v1.30]", + OGRE_NEW MeshSerializerImpl_v1_3())); + mVersionData.push_back(OGRE_NEW MeshVersionData( + MESH_VERSION_LEGACY, "[MeshSerializer_v1.20]", + OGRE_NEW MeshSerializerImpl_v1_2())); + + mVersionData.push_back(OGRE_NEW MeshVersionData( + MESH_VERSION_LEGACY, "[MeshSerializer_v1.10]", + OGRE_NEW MeshSerializerImpl_v1_1())); + } //--------------------------------------------------------------------- MeshSerializer::~MeshSerializer() @@ -89,66 +89,66 @@ namespace Ogre { } //--------------------------------------------------------------------- void MeshSerializer::exportMesh(const Mesh* pMesh, const String& filename, - Endian endianMode) + Endian endianMode) { - std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); - f->open(filename.c_str(), std::ios::binary | std::ios::out); - DataStreamPtr stream(OGRE_NEW FileStreamDataStream(f)); + std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); + f->open(filename.c_str(), std::ios::binary | std::ios::out); + DataStreamPtr stream(OGRE_NEW FileStreamDataStream(f)); exportMesh(pMesh, stream, endianMode); - stream->close(); + stream->close(); } //--------------------------------------------------------------------- void MeshSerializer::exportMesh(const Mesh* pMesh, const String& filename, - MeshVersion version, Endian endianMode) + MeshVersion version, Endian endianMode) { - std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); - f->open(filename.c_str(), std::ios::binary | std::ios::out); - DataStreamPtr stream(OGRE_NEW FileStreamDataStream(f)); - + std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); + f->open(filename.c_str(), std::ios::binary | std::ios::out); + DataStreamPtr stream(OGRE_NEW FileStreamDataStream(f)); + exportMesh(pMesh, stream, version, endianMode); - - stream->close(); + + stream->close(); + } + //--------------------------------------------------------------------- + void MeshSerializer::exportMesh(const Mesh* pMesh, DataStreamPtr stream, + Endian endianMode) + { + exportMesh(pMesh, stream, MESH_VERSION_LATEST, endianMode); + } + //--------------------------------------------------------------------- + void MeshSerializer::exportMesh(const Mesh* pMesh, DataStreamPtr stream, + MeshVersion version, Endian endianMode) + { + if (version == MESH_VERSION_LEGACY) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You may not supply a legacy version number (pre v1.0) for writing meshes.", + "MeshSerializer::exportMesh"); + + MeshSerializerImpl* impl = 0; + if (version == MESH_VERSION_LATEST) + impl = mVersionData[0]->impl; + else + { + for (MeshVersionDataList::iterator i = mVersionData.begin(); + i != mVersionData.end(); ++i) + { + if (version == (*i)->version) + { + impl = (*i)->impl; + break; + } + } + } + + if (!impl) + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Cannot find serializer implementation for " + "specified version", "MeshSerializer::exportMesh"); + + + impl->exportMesh(pMesh, stream, endianMode); } - //--------------------------------------------------------------------- - void MeshSerializer::exportMesh(const Mesh* pMesh, DataStreamPtr stream, - Endian endianMode) - { - exportMesh(pMesh, stream, MESH_VERSION_LATEST, endianMode); - } - //--------------------------------------------------------------------- - void MeshSerializer::exportMesh(const Mesh* pMesh, DataStreamPtr stream, - MeshVersion version, Endian endianMode) - { - if (version == MESH_VERSION_LEGACY) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You may not supply a legacy version number (pre v1.0) for writing meshes.", - "MeshSerializer::exportMesh"); - - MeshSerializerImpl* impl = 0; - if (version == MESH_VERSION_LATEST) - impl = mVersionData[0]->impl; - else - { - for (MeshVersionDataList::iterator i = mVersionData.begin(); - i != mVersionData.end(); ++i) - { - if (version == (*i)->version) - { - impl = (*i)->impl; - break; - } - } - } - - if (!impl) - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Cannot find serializer implementation for " - "specified version", "MeshSerializer::exportMesh"); - - - impl->exportMesh(pMesh, stream, endianMode); - } //--------------------------------------------------------------------- void MeshSerializer::importMesh(DataStreamPtr& stream, Mesh* pDest) { @@ -171,20 +171,20 @@ namespace Ogre { stream->seek(0); // Find the implementation to use - MeshSerializerImpl* impl = 0; - for (MeshVersionDataList::iterator i = mVersionData.begin(); - i != mVersionData.end(); ++i) - { - if ((*i)->versionString == ver) - { - impl = (*i)->impl; - break; - } - } - if (!impl) + MeshSerializerImpl* impl = 0; + for (MeshVersionDataList::iterator i = mVersionData.begin(); + i != mVersionData.end(); ++i) + { + if ((*i)->versionString == ver) + { + impl = (*i)->impl; + break; + } + } + if (!impl) OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Cannot find serializer implementation for " - "mesh version " + ver, "MeshSerializer::importMesh"); - + "mesh version " + ver, "MeshSerializer::importMesh"); + // Call implementation impl->importMesh(stream, pDest, mListener); // Warn on old version of mesh @@ -195,18 +195,18 @@ namespace Ogre { " using the OgreMeshUpgrade tool.", LML_CRITICAL); } - if(mListener) - mListener->processMeshCompleted(pDest); + if(mListener) + mListener->processMeshCompleted(pDest); } //--------------------------------------------------------------------- - void MeshSerializer::setListener(Ogre::MeshSerializerListener *listener) - { - mListener = listener; - } - //------------------------------------------------------------------------- - MeshSerializerListener *MeshSerializer::getListener() - { - return mListener; - } + void MeshSerializer::setListener(Ogre::MeshSerializerListener *listener) + { + mListener = listener; + } + //------------------------------------------------------------------------- + MeshSerializerListener *MeshSerializer::getListener() + { + return mListener; + } } diff --git a/OgreMain/src/OgreMeshSerializerImpl.cpp b/OgreMain/src/OgreMeshSerializerImpl.cpp index 72a1ccc985b..cee9b4aaeba 100644 --- a/OgreMain/src/OgreMeshSerializerImpl.cpp +++ b/OgreMain/src/OgreMeshSerializerImpl.cpp @@ -63,12 +63,12 @@ namespace Ogre { } //--------------------------------------------------------------------- void MeshSerializerImpl::exportMesh(const Mesh* pMesh, - DataStreamPtr stream, Endian endianMode) + DataStreamPtr stream, Endian endianMode) { LogManager::getSingleton().logMessage("MeshSerializer writing mesh data to stream " + stream->getName() + "..."); - // Decide on endian mode - determineEndianness(endianMode); + // Decide on endian mode + determineEndianness(endianMode); // Check that the mesh has it's bounds set if (pMesh->getBounds().isNull() || pMesh->getBoundingSphereRadius() == 0.0f) @@ -78,21 +78,21 @@ namespace Ogre { "MeshSerializerImpl::exportMesh"); } mStream = stream; - if (!mStream->isWriteable()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unable to use stream " + mStream->getName() + " for writing", - "MeshSerializerImpl::exportMesh"); - } + if (!mStream->isWriteable()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Unable to use stream " + mStream->getName() + " for writing", + "MeshSerializerImpl::exportMesh"); + } writeFileHeader(); LogManager::getSingleton().logMessage("File header written."); LogManager::getSingleton().logMessage("Writing mesh data..."); - pushInnerChunk(mStream); + pushInnerChunk(mStream); writeMesh(pMesh); - popInnerChunk(mStream); + popInnerChunk(mStream); LogManager::getSingleton().logMessage("Mesh data exported."); LogManager::getSingleton().logMessage("MeshSerializer export successful."); @@ -100,15 +100,15 @@ namespace Ogre { //--------------------------------------------------------------------- void MeshSerializerImpl::importMesh(DataStreamPtr& stream, Mesh* pMesh, MeshSerializerListener *listener) { - // Determine endianness (must be the first thing we do!) - determineEndianness(stream); + // Determine endianness (must be the first thing we do!) + determineEndianness(stream); #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - enableValidation(); + enableValidation(); #endif // Check header readFileHeader(stream); - pushInnerChunk(stream); + pushInnerChunk(stream); unsigned short streamID; while(!stream->eof()) { @@ -118,24 +118,24 @@ namespace Ogre { case M_MESH: readMesh(stream, pMesh, listener); break; - } + } } - popInnerChunk(stream); + popInnerChunk(stream); } //--------------------------------------------------------------------- void MeshSerializerImpl::writeMesh(const Mesh* pMesh) { - exportedLodCount = 1; // generate edge data for original mesh + exportedLodCount = 1; // generate edge data for original mesh // Header writeChunkHeader(M_MESH, calcMeshSize(pMesh)); - { - // bool skeletallyAnimated - bool skelAnim = pMesh->hasSkeleton(); - writeBools(&skelAnim, 1); + { + // bool skeletallyAnimated + bool skelAnim = pMesh->hasSkeleton(); + writeBools(&skelAnim, 1); - pushInnerChunk(mStream); - + pushInnerChunk(mStream); + // Write shared geometry if (pMesh->sharedVertexData) writeGeometry(pMesh->sharedVertexData); @@ -171,16 +171,16 @@ namespace Ogre { LogManager::getSingleton().logMessage("Shared geometry bone assignments exported."); } } - + #if !OGRE_NO_MESHLOD - // Write LOD data if any - if (pMesh->getNumLodLevels() > 1) - { - LogManager::getSingleton().logMessage("Exporting LOD information...."); - writeLodLevel(pMesh); - LogManager::getSingleton().logMessage("LOD information exported."); - - } + // Write LOD data if any + if (pMesh->getNumLodLevels() > 1) + { + LogManager::getSingleton().logMessage("Exporting LOD information...."); + writeLodLevel(pMesh); + LogManager::getSingleton().logMessage("LOD information exported."); + + } #endif // Write bounds information @@ -188,56 +188,56 @@ namespace Ogre { writeBoundsInfo(pMesh); LogManager::getSingleton().logMessage("Bounds information exported."); - // Write submesh name table - LogManager::getSingleton().logMessage("Exporting submesh name table..."); - writeSubMeshNameTable(pMesh); - LogManager::getSingleton().logMessage("Submesh name table exported."); - - // Write edge lists - if (pMesh->isEdgeListBuilt()) - { - LogManager::getSingleton().logMessage("Exporting edge lists..."); - writeEdgeList(pMesh); - LogManager::getSingleton().logMessage("Edge lists exported"); - } - - // Write morph animation - writePoses(pMesh); - if (pMesh->hasVertexAnimation()) - { - writeAnimations(pMesh); + // Write submesh name table + LogManager::getSingleton().logMessage("Exporting submesh name table..."); + writeSubMeshNameTable(pMesh); + LogManager::getSingleton().logMessage("Submesh name table exported."); + + // Write edge lists + if (pMesh->isEdgeListBuilt()) + { + LogManager::getSingleton().logMessage("Exporting edge lists..."); + writeEdgeList(pMesh); + LogManager::getSingleton().logMessage("Edge lists exported"); + } + + // Write morph animation + writePoses(pMesh); + if (pMesh->hasVertexAnimation()) + { + writeAnimations(pMesh); } // Write submesh extremes writeExtremes(pMesh); - popInnerChunk(mStream); - } - } - //--------------------------------------------------------------------- - // Added by DrEvil - void MeshSerializerImpl::writeSubMeshNameTable(const Mesh* pMesh) - { - // Header - writeChunkHeader(M_SUBMESH_NAME_TABLE, calcSubMeshNameTableSize(pMesh)); - - // Loop through and save out the index and names. - Mesh::SubMeshNameMap::const_iterator it = pMesh->mSubMeshNameMap.begin(); - pushInnerChunk(mStream); - while(it != pMesh->mSubMeshNameMap.end()) - { - // Header - writeChunkHeader(M_SUBMESH_NAME_TABLE_ELEMENT, MSTREAM_OVERHEAD_SIZE + - sizeof(unsigned short) + calcStringSize(it->first)); - - // write the index - writeShorts(&it->second, 1); - // name - writeString(it->first); - - ++it; - } - popInnerChunk(mStream); - } + popInnerChunk(mStream); + } + } + //--------------------------------------------------------------------- + // Added by DrEvil + void MeshSerializerImpl::writeSubMeshNameTable(const Mesh* pMesh) + { + // Header + writeChunkHeader(M_SUBMESH_NAME_TABLE, calcSubMeshNameTableSize(pMesh)); + + // Loop through and save out the index and names. + Mesh::SubMeshNameMap::const_iterator it = pMesh->mSubMeshNameMap.begin(); + pushInnerChunk(mStream); + while(it != pMesh->mSubMeshNameMap.end()) + { + // Header + writeChunkHeader(M_SUBMESH_NAME_TABLE_ELEMENT, MSTREAM_OVERHEAD_SIZE + + sizeof(unsigned short) + calcStringSize(it->first)); + + // write the index + writeShorts(&it->second, 1); + // name + writeString(it->first); + + ++it; + } + popInnerChunk(mStream); + } //--------------------------------------------------------------------- void MeshSerializerImpl::writeSubMesh(const SubMesh* s) { @@ -250,34 +250,34 @@ namespace Ogre { // bool useSharedVertices writeBools(&s->useSharedVertices, 1); - unsigned int indexCount = static_cast(s->indexData->indexCount); + unsigned int indexCount = static_cast(s->indexData->indexCount); writeInts(&indexCount, 1); // bool indexes32Bit bool idx32bit = (!s->indexData->indexBuffer.isNull() && - s->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT); + s->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT); writeBools(&idx32bit, 1); - if (indexCount > 0) - { - // unsigned short* faceVertexIndices ((indexCount) - HardwareIndexBufferSharedPtr ibuf = s->indexData->indexBuffer; - void* pIdx = ibuf->lock(HardwareBuffer::HBL_READ_ONLY); - if (idx32bit) - { - unsigned int* pIdx32 = static_cast(pIdx); - writeInts(pIdx32, s->indexData->indexCount); - } - else - { - unsigned short* pIdx16 = static_cast(pIdx); - writeShorts(pIdx16, s->indexData->indexCount); - } - ibuf->unlock(); - } - - pushInnerChunk(mStream); - + if (indexCount > 0) + { + // unsigned short* faceVertexIndices ((indexCount) + HardwareIndexBufferSharedPtr ibuf = s->indexData->indexBuffer; + void* pIdx = ibuf->lock(HardwareBuffer::HBL_READ_ONLY); + if (idx32bit) + { + unsigned int* pIdx32 = static_cast(pIdx); + writeInts(pIdx32, s->indexData->indexCount); + } + else + { + unsigned short* pIdx16 = static_cast(pIdx); + writeShorts(pIdx16, s->indexData->indexCount); + } + ibuf->unlock(); + } + + pushInnerChunk(mStream); + // M_GEOMETRY stream (Optional: present only if useSharedVertices = false) if (!s->useSharedVertices) { @@ -302,7 +302,7 @@ namespace Ogre { } LogManager::getSingleton().logMessage("Dedicated geometry bone assignments exported."); } - popInnerChunk(mStream); + popInnerChunk(mStream); } //--------------------------------------------------------------------- @@ -324,46 +324,46 @@ namespace Ogre { if (has_extremes) LogManager::getSingleton().logMessage("Extremes exported."); } - size_t MeshSerializerImpl::calcExtremesSize(const Mesh* pMesh) - { - size_t size = 0; - for (unsigned short i = 0; i < pMesh->getNumSubMeshes(); ++i) - { - SubMesh *sm = pMesh->getSubMesh(i); - if (!sm->extremityPoints.empty()){ - size += calcSubMeshExtremesSize(i, sm); - } - } - return size; - } + size_t MeshSerializerImpl::calcExtremesSize(const Mesh* pMesh) + { + size_t size = 0; + for (unsigned short i = 0; i < pMesh->getNumSubMeshes(); ++i) + { + SubMesh *sm = pMesh->getSubMesh(i); + if (!sm->extremityPoints.empty()){ + size += calcSubMeshExtremesSize(i, sm); + } + } + return size; + } //--------------------------------------------------------------------- void MeshSerializerImpl::writeSubMeshExtremes(unsigned short idx, const SubMesh* s) { - writeChunkHeader(M_TABLE_EXTREMES, calcSubMeshExtremesSize(idx, s)); + writeChunkHeader(M_TABLE_EXTREMES, calcSubMeshExtremesSize(idx, s)); writeShorts(&idx, 1); float *vertices = OGRE_ALLOC_T(float, s->extremityPoints.size() * 3, MEMCATEGORY_GEOMETRY); - float *pVert = vertices; + float *pVert = vertices; for (vector::type::const_iterator i = s->extremityPoints.begin(); i != s->extremityPoints.end(); ++i) { - *pVert++ = i->x; - *pVert++ = i->y; - *pVert++ = i->z; + *pVert++ = i->x; + *pVert++ = i->y; + *pVert++ = i->z; } writeFloats(vertices, s->extremityPoints.size () * 3); OGRE_FREE(vertices, MEMCATEGORY_GEOMETRY); } - size_t MeshSerializerImpl::calcSubMeshExtremesSize(unsigned short idx, const SubMesh* s) - { - return MSTREAM_OVERHEAD_SIZE + sizeof (unsigned short) + - s->extremityPoints.size() * sizeof (float)* 3; - } + size_t MeshSerializerImpl::calcSubMeshExtremesSize(unsigned short idx, const SubMesh* s) + { + return MSTREAM_OVERHEAD_SIZE + sizeof (unsigned short) + + s->extremityPoints.size() * sizeof (float)* 3; + } //--------------------------------------------------------------------- @@ -372,21 +372,21 @@ namespace Ogre { size_t chunkSize; AliasTextureNamePairList::const_iterator i; - LogManager::getSingleton().logMessage("Exporting submesh texture aliases..."); + LogManager::getSingleton().logMessage("Exporting submesh texture aliases..."); // iterate through texture aliases and write them out as a chunk for (i = s->mTextureAliases.begin(); i != s->mTextureAliases.end(); ++i) { // calculate chunk size based on string length + 1. Add 1 for the line feed. chunkSize = MSTREAM_OVERHEAD_SIZE + calcStringSize(i->first) + calcStringSize(i->second); - writeChunkHeader(M_SUBMESH_TEXTURE_ALIAS, chunkSize); + writeChunkHeader(M_SUBMESH_TEXTURE_ALIAS, chunkSize); // write out alias name writeString(i->first); // write out texture name writeString(i->second); } - LogManager::getSingleton().logMessage("Submesh texture aliases exported."); + LogManager::getSingleton().logMessage("Submesh texture aliases exported."); } //--------------------------------------------------------------------- @@ -408,114 +408,114 @@ namespace Ogre { vertexData->vertexBufferBinding->getBindings(); VertexBufferBinding::VertexBufferBindingMap::const_iterator vbi, vbiend; - // Header + // Header writeChunkHeader(M_GEOMETRY, calcGeometrySize(vertexData)); unsigned int vertexCount = static_cast(vertexData->vertexCount); writeInts(&vertexCount, 1); - pushInnerChunk(mStream); - { - // Vertex declaration - size_t size = MSTREAM_OVERHEAD_SIZE + elemList.size() * (MSTREAM_OVERHEAD_SIZE + sizeof(unsigned short)* 5); - writeChunkHeader(M_GEOMETRY_VERTEX_DECLARATION, size); + pushInnerChunk(mStream); + { + // Vertex declaration + size_t size = MSTREAM_OVERHEAD_SIZE + elemList.size() * (MSTREAM_OVERHEAD_SIZE + sizeof(unsigned short)* 5); + writeChunkHeader(M_GEOMETRY_VERTEX_DECLARATION, size); - pushInnerChunk(mStream); - { + pushInnerChunk(mStream); + { VertexDeclaration::VertexElementList::const_iterator vei, veiend; - veiend = elemList.end(); - unsigned short tmp; - size = MSTREAM_OVERHEAD_SIZE + sizeof(unsigned short) * 5; - for (vei = elemList.begin(); vei != veiend; ++vei) - { - const VertexElement& elem = *vei; - writeChunkHeader(M_GEOMETRY_VERTEX_ELEMENT, size); - // unsigned short source; // buffer bind source - tmp = elem.getSource(); - writeShorts(&tmp, 1); - // unsigned short type; // VertexElementType - tmp = static_cast(elem.getType()); - writeShorts(&tmp, 1); - // unsigned short semantic; // VertexElementSemantic - tmp = static_cast(elem.getSemantic()); - writeShorts(&tmp, 1); - // unsigned short offset; // start offset in buffer in bytes - tmp = static_cast(elem.getOffset()); - writeShorts(&tmp, 1); - // unsigned short index; // index of the semantic (for colours and texture coords) - tmp = elem.getIndex(); - writeShorts(&tmp, 1); - - } - } - popInnerChunk(mStream); - - - // Buffers and bindings - vbiend = bindings.end(); - for (vbi = bindings.begin(); vbi != vbiend; ++vbi) - { - const HardwareVertexBufferSharedPtr& vbuf = vbi->second; - size = (MSTREAM_OVERHEAD_SIZE * 2) + (sizeof(unsigned short) * 2) + vbuf->getSizeInBytes(); - writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER, size); - // unsigned short bindIndex; // Index to bind this buffer to - unsigned short tmp = vbi->first; - writeShorts(&tmp, 1); - // unsigned short vertexSize; // Per-vertex size, must agree with declaration at this index - tmp = (unsigned short)vbuf->getVertexSize(); - writeShorts(&tmp, 1); - pushInnerChunk(mStream); - { - // Data - size = MSTREAM_OVERHEAD_SIZE + vbuf->getSizeInBytes(); - writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA, size); - void* pBuf = vbuf->lock(HardwareBuffer::HBL_READ_ONLY); - - if (mFlipEndian) - { - // endian conversion - // Copy data - unsigned char* tempData = OGRE_ALLOC_T(unsigned char, vbuf->getSizeInBytes(), MEMCATEGORY_GEOMETRY); - memcpy(tempData, pBuf, vbuf->getSizeInBytes()); - flipToLittleEndian( - tempData, - vertexData->vertexCount, - vbuf->getVertexSize(), - vertexData->vertexDeclaration->findElementsBySource(vbi->first)); - writeData(tempData, vbuf->getVertexSize(), vertexData->vertexCount); - OGRE_FREE(tempData, MEMCATEGORY_GEOMETRY); - } - else - { - writeData(pBuf, vbuf->getVertexSize(), vertexData->vertexCount); - } + veiend = elemList.end(); + unsigned short tmp; + size = MSTREAM_OVERHEAD_SIZE + sizeof(unsigned short) * 5; + for (vei = elemList.begin(); vei != veiend; ++vei) + { + const VertexElement& elem = *vei; + writeChunkHeader(M_GEOMETRY_VERTEX_ELEMENT, size); + // unsigned short source; // buffer bind source + tmp = elem.getSource(); + writeShorts(&tmp, 1); + // unsigned short type; // VertexElementType + tmp = static_cast(elem.getType()); + writeShorts(&tmp, 1); + // unsigned short semantic; // VertexElementSemantic + tmp = static_cast(elem.getSemantic()); + writeShorts(&tmp, 1); + // unsigned short offset; // start offset in buffer in bytes + tmp = static_cast(elem.getOffset()); + writeShorts(&tmp, 1); + // unsigned short index; // index of the semantic (for colours and texture coords) + tmp = elem.getIndex(); + writeShorts(&tmp, 1); + + } + } + popInnerChunk(mStream); + + + // Buffers and bindings + vbiend = bindings.end(); + for (vbi = bindings.begin(); vbi != vbiend; ++vbi) + { + const HardwareVertexBufferSharedPtr& vbuf = vbi->second; + size = (MSTREAM_OVERHEAD_SIZE * 2) + (sizeof(unsigned short) * 2) + vbuf->getSizeInBytes(); + writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER, size); + // unsigned short bindIndex; // Index to bind this buffer to + unsigned short tmp = vbi->first; + writeShorts(&tmp, 1); + // unsigned short vertexSize; // Per-vertex size, must agree with declaration at this index + tmp = (unsigned short)vbuf->getVertexSize(); + writeShorts(&tmp, 1); + pushInnerChunk(mStream); + { + // Data + size = MSTREAM_OVERHEAD_SIZE + vbuf->getSizeInBytes(); + writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA, size); + void* pBuf = vbuf->lock(HardwareBuffer::HBL_READ_ONLY); + + if (mFlipEndian) + { + // endian conversion + // Copy data + unsigned char* tempData = OGRE_ALLOC_T(unsigned char, vbuf->getSizeInBytes(), MEMCATEGORY_GEOMETRY); + memcpy(tempData, pBuf, vbuf->getSizeInBytes()); + flipToLittleEndian( + tempData, + vertexData->vertexCount, + vbuf->getVertexSize(), + vertexData->vertexDeclaration->findElementsBySource(vbi->first)); + writeData(tempData, vbuf->getVertexSize(), vertexData->vertexCount); + OGRE_FREE(tempData, MEMCATEGORY_GEOMETRY); + } + else + { + writeData(pBuf, vbuf->getVertexSize(), vertexData->vertexCount); + } vbuf->unlock(); - } - popInnerChunk(mStream); - } - } - popInnerChunk(mStream); - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcSubMeshNameTableSize(const Mesh* pMesh) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - // Figure out the size of the Name table. - // Iterate through the subMeshList & add up the size of the indexes and names. - Mesh::SubMeshNameMap::const_iterator it = pMesh->mSubMeshNameMap.begin(); - while(it != pMesh->mSubMeshNameMap.end()) - { - // size of the index + header size for each element chunk - size += MSTREAM_OVERHEAD_SIZE + sizeof(uint16); - // name - size += calcStringSize(it->first); - - ++it; - } - - // size of the sub-mesh name table. - return size; - } + } + popInnerChunk(mStream); + } + } + popInnerChunk(mStream); + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl::calcSubMeshNameTableSize(const Mesh* pMesh) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + // Figure out the size of the Name table. + // Iterate through the subMeshList & add up the size of the indexes and names. + Mesh::SubMeshNameMap::const_iterator it = pMesh->mSubMeshNameMap.begin(); + while(it != pMesh->mSubMeshNameMap.end()) + { + // size of the index + header size for each element chunk + size += MSTREAM_OVERHEAD_SIZE + sizeof(uint16); + // name + size += calcStringSize(it->first); + + ++it; + } + + // size of the sub-mesh name table. + return size; + } //--------------------------------------------------------------------- size_t MeshSerializerImpl::calcMeshSize(const Mesh* pMesh) { @@ -540,47 +540,47 @@ namespace Ogre { if (pMesh->hasSkeleton()) { size += calcSkeletonLinkSize(pMesh->getSkeletonName()); - // Write bone assignments - size += pMesh->mBoneAssignments.size() * calcBoneAssignmentSize(); + // Write bone assignments + size += pMesh->mBoneAssignments.size() * calcBoneAssignmentSize(); } - + #if !OGRE_NO_MESHLOD - // Write LOD data if any - if (pMesh->getNumLodLevels() > 1) - { - size += calcLodLevelSize(pMesh); - } + // Write LOD data if any + if (pMesh->getNumLodLevels() > 1) + { + size += calcLodLevelSize(pMesh); + } #endif - - size += calcBoundsInfoSize(pMesh); + + size += calcBoundsInfoSize(pMesh); - // Submesh name table - size += calcSubMeshNameTableSize(pMesh); + // Submesh name table + size += calcSubMeshNameTableSize(pMesh); - // Edge list - if (pMesh->isEdgeListBuilt()) - { - size += calcEdgeListSize(pMesh); - } + // Edge list + if (pMesh->isEdgeListBuilt()) + { + size += calcEdgeListSize(pMesh); + } - // Morph animation - size += calcPosesSize(pMesh); + // Morph animation + size += calcPosesSize(pMesh); - // Vertex animation - if (pMesh->hasVertexAnimation()) - { - size += calcAnimationsSize(pMesh); - } + // Vertex animation + if (pMesh->hasVertexAnimation()) + { + size += calcAnimationsSize(pMesh); + } - size += calcExtremesSize(pMesh); + size += calcExtremesSize(pMesh); - return size; + return size; } //--------------------------------------------------------------------- size_t MeshSerializerImpl::calcSubMeshSize(const SubMesh* pSub) { size_t size = MSTREAM_OVERHEAD_SIZE; - + // Material name size += calcStringSize(pSub->getMaterialName()); @@ -591,13 +591,13 @@ namespace Ogre { // bool indexes32bit size += sizeof(bool); - bool idx32bit = (!pSub->indexData->indexBuffer.isNull() && - pSub->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT); + bool idx32bit = (!pSub->indexData->indexBuffer.isNull() && + pSub->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT); // unsigned int* / unsigned short* faceVertexIndices - if (idx32bit) - size += sizeof(unsigned int) * pSub->indexData->indexCount; - else - size += sizeof(unsigned short) * pSub->indexData->indexCount; + if (idx32bit) + size += sizeof(unsigned int) * pSub->indexData->indexCount; + else + size += sizeof(unsigned short) * pSub->indexData->indexCount; // Geometry if (!pSub->useSharedVertices) @@ -644,28 +644,28 @@ namespace Ogre { //--------------------------------------------------------------------- size_t MeshSerializerImpl::calcGeometrySize(const VertexData* vertexData) { - const VertexDeclaration::VertexElementList& elemList = - vertexData->vertexDeclaration->getElements(); - const VertexBufferBinding::VertexBufferBindingMap& bindings = - vertexData->vertexBufferBinding->getBindings(); + const VertexDeclaration::VertexElementList& elemList = + vertexData->vertexDeclaration->getElements(); + const VertexBufferBinding::VertexBufferBindingMap& bindings = + vertexData->vertexBufferBinding->getBindings(); size_t size = MSTREAM_OVERHEAD_SIZE; - // Vertex count + // Vertex count size += sizeof(unsigned int); // Vertex declaration - size += MSTREAM_OVERHEAD_SIZE + elemList.size() * (MSTREAM_OVERHEAD_SIZE + sizeof(unsigned short)* 5); - - // Buffers and bindings - size += bindings.size() * ((MSTREAM_OVERHEAD_SIZE * 2) + (sizeof(unsigned short)* 2)); - - // Buffer data - VertexBufferBinding::VertexBufferBindingMap::const_iterator vbi, vbiend; - vbiend = bindings.end(); - for (vbi = bindings.begin(); vbi != vbiend; ++vbi) - { - const HardwareVertexBufferSharedPtr& vbuf = vbi->second; - size += vbuf->getSizeInBytes(); + size += MSTREAM_OVERHEAD_SIZE + elemList.size() * (MSTREAM_OVERHEAD_SIZE + sizeof(unsigned short)* 5); + + // Buffers and bindings + size += bindings.size() * ((MSTREAM_OVERHEAD_SIZE * 2) + (sizeof(unsigned short)* 2)); + + // Buffer data + VertexBufferBinding::VertexBufferBindingMap::const_iterator vbi, vbiend; + vbiend = bindings.end(); + for (vbi = bindings.begin(); vbi != vbiend; ++vbi) + { + const HardwareVertexBufferSharedPtr& vbuf = vbi->second; + size += vbuf->getSizeInBytes(); } return size; } @@ -682,7 +682,7 @@ namespace Ogre { // Find optional geometry streams if (!stream->eof()) { - pushInnerChunk(stream); + pushInnerChunk(stream); unsigned short streamID = readChunk(stream); while(!stream->eof() && (streamID == M_GEOMETRY_VERTEX_DECLARATION || @@ -706,20 +706,20 @@ namespace Ogre { if (!stream->eof()) { // Backpedal back to start of non-submesh stream - backpedalChunkHeader(stream); + backpedalChunkHeader(stream); } - popInnerChunk(stream); + popInnerChunk(stream); } - // Perform any necessary colour conversion for an active rendersystem - if (Root::getSingletonPtr() && Root::getSingleton().getRenderSystem()) - { - // We don't know the source type if it's VET_COLOUR, but assume ARGB - // since that's the most common. Won't get used unless the mesh is - // ambiguous anyway, which will have been warned about in the log - dest->convertPackedColour(VET_COLOUR_ARGB, - VertexElement::getBestColourVertexElementType()); - } + // Perform any necessary colour conversion for an active rendersystem + if (Root::getSingletonPtr() && Root::getSingleton().getRenderSystem()) + { + // We don't know the source type if it's VET_COLOUR, but assume ARGB + // since that's the most common. Won't get used unless the mesh is + // ambiguous anyway, which will have been warned about in the log + dest->convertPackedColour(VET_COLOUR_ARGB, + VertexElement::getBestColourVertexElementType()); + } } //--------------------------------------------------------------------- void MeshSerializerImpl::readGeometryVertexDeclaration(DataStreamPtr& stream, @@ -728,7 +728,7 @@ namespace Ogre { // Find optional geometry streams if (!stream->eof()) { - pushInnerChunk(stream); + pushInnerChunk(stream); unsigned short streamID = readChunk(stream); while(!stream->eof() && (streamID == M_GEOMETRY_VERTEX_ELEMENT )) @@ -748,146 +748,146 @@ namespace Ogre { if (!stream->eof()) { // Backpedal back to start of non-submesh stream - backpedalChunkHeader(stream); + backpedalChunkHeader(stream); } - popInnerChunk(stream); + popInnerChunk(stream); } - } + } //--------------------------------------------------------------------- void MeshSerializerImpl::readGeometryVertexElement(DataStreamPtr& stream, Mesh* pMesh, VertexData* dest) { - unsigned short source, offset, index, tmp; - VertexElementType vType; - VertexElementSemantic vSemantic; - // unsigned short source; // buffer bind source - readShorts(stream, &source, 1); - // unsigned short type; // VertexElementType - readShorts(stream, &tmp, 1); - vType = static_cast(tmp); - // unsigned short semantic; // VertexElementSemantic - readShorts(stream, &tmp, 1); - vSemantic = static_cast(tmp); - // unsigned short offset; // start offset in buffer in bytes - readShorts(stream, &offset, 1); - // unsigned short index; // index of the semantic - readShorts(stream, &index, 1); - - dest->vertexDeclaration->addElement(source, offset, vType, vSemantic, index); - - if (vType == VET_COLOUR) - { - LogManager::getSingleton().stream() - << "Warning: VET_COLOUR element type is deprecated, you should use " - << "one of the more specific types to indicate the byte order. " - << "Use OgreMeshUpgrade on " << pMesh->getName() << " as soon as possible. "; - } - - } + unsigned short source, offset, index, tmp; + VertexElementType vType; + VertexElementSemantic vSemantic; + // unsigned short source; // buffer bind source + readShorts(stream, &source, 1); + // unsigned short type; // VertexElementType + readShorts(stream, &tmp, 1); + vType = static_cast(tmp); + // unsigned short semantic; // VertexElementSemantic + readShorts(stream, &tmp, 1); + vSemantic = static_cast(tmp); + // unsigned short offset; // start offset in buffer in bytes + readShorts(stream, &offset, 1); + // unsigned short index; // index of the semantic + readShorts(stream, &index, 1); + + dest->vertexDeclaration->addElement(source, offset, vType, vSemantic, index); + + if (vType == VET_COLOUR) + { + LogManager::getSingleton().stream() + << "Warning: VET_COLOUR element type is deprecated, you should use " + << "one of the more specific types to indicate the byte order. " + << "Use OgreMeshUpgrade on " << pMesh->getName() << " as soon as possible. "; + } + + } //--------------------------------------------------------------------- void MeshSerializerImpl::readGeometryVertexBuffer(DataStreamPtr& stream, Mesh* pMesh, VertexData* dest) { - unsigned short bindIndex, vertexSize; - // unsigned short bindIndex; // Index to bind this buffer to - readShorts(stream, &bindIndex, 1); - // unsigned short vertexSize; // Per-vertex size, must agree with declaration at this index - readShorts(stream, &vertexSize, 1); - pushInnerChunk(stream); - { - // Check for vertex data header - unsigned short headerID; - headerID = readChunk(stream); - if (headerID != M_GEOMETRY_VERTEX_BUFFER_DATA) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Can't find vertex buffer data area", - "MeshSerializerImpl::readGeometryVertexBuffer"); - } - // Check that vertex size agrees - if (dest->vertexDeclaration->getVertexSize(bindIndex) != vertexSize) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer vertex size does not agree with vertex declaration", - "MeshSerializerImpl::readGeometryVertexBuffer"); - } - - // Create / populate vertex buffer - HardwareVertexBufferSharedPtr vbuf; + unsigned short bindIndex, vertexSize; + // unsigned short bindIndex; // Index to bind this buffer to + readShorts(stream, &bindIndex, 1); + // unsigned short vertexSize; // Per-vertex size, must agree with declaration at this index + readShorts(stream, &vertexSize, 1); + pushInnerChunk(stream); + { + // Check for vertex data header + unsigned short headerID; + headerID = readChunk(stream); + if (headerID != M_GEOMETRY_VERTEX_BUFFER_DATA) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Can't find vertex buffer data area", + "MeshSerializerImpl::readGeometryVertexBuffer"); + } + // Check that vertex size agrees + if (dest->vertexDeclaration->getVertexSize(bindIndex) != vertexSize) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer vertex size does not agree with vertex declaration", + "MeshSerializerImpl::readGeometryVertexBuffer"); + } + + // Create / populate vertex buffer + HardwareVertexBufferSharedPtr vbuf; vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( vertexSize, dest->vertexCount, pMesh->mVertexBufferUsage, - pMesh->mVertexBufferShadowBuffer); + pMesh->mVertexBufferShadowBuffer); void* pBuf = vbuf->lock(HardwareBuffer::HBL_DISCARD); stream->read(pBuf, dest->vertexCount * vertexSize); - // endian conversion for OSX - flipFromLittleEndian( - pBuf, - dest->vertexCount, - vertexSize, - dest->vertexDeclaration->findElementsBySource(bindIndex)); + // endian conversion for OSX + flipFromLittleEndian( + pBuf, + dest->vertexCount, + vertexSize, + dest->vertexDeclaration->findElementsBySource(bindIndex)); vbuf->unlock(); - // Set binding + // Set binding dest->vertexBufferBinding->setBinding(bindIndex, vbuf); - } - popInnerChunk(stream); + } + popInnerChunk(stream); - } + } //--------------------------------------------------------------------- - void MeshSerializerImpl::readSubMeshNameTable(DataStreamPtr& stream, Mesh* pMesh) - { - // The map for - map::type subMeshNames; - unsigned short streamID, subMeshIndex; + void MeshSerializerImpl::readSubMeshNameTable(DataStreamPtr& stream, Mesh* pMesh) + { + // The map for + map::type subMeshNames; + unsigned short streamID, subMeshIndex; - // Need something to store the index, and the objects name - // This table is a method that imported meshes can retain their naming - // so that the names established in the modelling software can be used - // to get the sub-meshes by name. The exporter must support exporting - // the optional stream M_SUBMESH_NAME_TABLE. + // Need something to store the index, and the objects name + // This table is a method that imported meshes can retain their naming + // so that the names established in the modelling software can be used + // to get the sub-meshes by name. The exporter must support exporting + // the optional stream M_SUBMESH_NAME_TABLE. // Read in all the sub-streams. Each sub-stream should contain an index and Ogre::String for the name. - if (!stream->eof()) - { - pushInnerChunk(stream); - streamID = readChunk(stream); - while(!stream->eof() && (streamID == M_SUBMESH_NAME_TABLE_ELEMENT )) - { - // Read in the index of the submesh. - readShorts(stream, &subMeshIndex, 1); - // Read in the String and map it to its index. - subMeshNames[subMeshIndex] = readString(stream); - - // If we're not end of file get the next stream ID - if (!stream->eof()) - streamID = readChunk(stream); - } - if (!stream->eof()) - { - // Backpedal back to start of stream - backpedalChunkHeader(stream); - } - popInnerChunk(stream); - } - - // Set all the submeshes names - // ? - - // Loop through and save out the index and names. - map::type::const_iterator it = subMeshNames.begin(); - - while(it != subMeshNames.end()) - { - // Name this submesh to the stored name. - pMesh->nameSubMesh(it->second, it->first); - ++it; - } - - - - } + if (!stream->eof()) + { + pushInnerChunk(stream); + streamID = readChunk(stream); + while(!stream->eof() && (streamID == M_SUBMESH_NAME_TABLE_ELEMENT )) + { + // Read in the index of the submesh. + readShorts(stream, &subMeshIndex, 1); + // Read in the String and map it to its index. + subMeshNames[subMeshIndex] = readString(stream); + + // If we're not end of file get the next stream ID + if (!stream->eof()) + streamID = readChunk(stream); + } + if (!stream->eof()) + { + // Backpedal back to start of stream + backpedalChunkHeader(stream); + } + popInnerChunk(stream); + } + + // Set all the submeshes names + // ? + + // Loop through and save out the index and names. + map::type::const_iterator it = subMeshNames.begin(); + + while(it != subMeshNames.end()) + { + // Name this submesh to the stored name. + pMesh->nameSubMesh(it->second, it->first); + ++it; + } + + + + } //--------------------------------------------------------------------- void MeshSerializerImpl::readMesh(DataStreamPtr& stream, Mesh* pMesh, MeshSerializerListener *listener) { @@ -895,51 +895,51 @@ namespace Ogre { // expect them in the file or not at all pMesh->mAutoBuildEdgeLists = false; - // bool skeletallyAnimated - bool skeletallyAnimated; - readBools(stream, &skeletallyAnimated, 1); + // bool skeletallyAnimated + bool skeletallyAnimated; + readBools(stream, &skeletallyAnimated, 1); // Find all substreams if (!stream->eof()) { - pushInnerChunk(stream); + pushInnerChunk(stream); unsigned short streamID = readChunk(stream); while(!stream->eof() && (streamID == M_GEOMETRY || - streamID == M_SUBMESH || + streamID == M_SUBMESH || streamID == M_MESH_SKELETON_LINK || streamID == M_MESH_BONE_ASSIGNMENT || - streamID == M_MESH_LOD_LEVEL || + streamID == M_MESH_LOD_LEVEL || streamID == M_MESH_BOUNDS || - streamID == M_SUBMESH_NAME_TABLE || - streamID == M_EDGE_LISTS || - streamID == M_POSES || - streamID == M_ANIMATIONS || - streamID == M_TABLE_EXTREMES)) + streamID == M_SUBMESH_NAME_TABLE || + streamID == M_EDGE_LISTS || + streamID == M_POSES || + streamID == M_ANIMATIONS || + streamID == M_TABLE_EXTREMES)) { switch(streamID) { - case M_GEOMETRY: - pMesh->sharedVertexData = OGRE_NEW VertexData(); - try { - readGeometry(stream, pMesh, pMesh->sharedVertexData); - } - catch (Exception& e) - { - if (e.getNumber() == Exception::ERR_ITEM_NOT_FOUND) - { - // duff geometry data entry with 0 vertices - OGRE_DELETE pMesh->sharedVertexData; - pMesh->sharedVertexData = 0; - // Skip this stream (pointer will have been returned to just after header) - stream->skip(mCurrentstreamLen - MSTREAM_OVERHEAD_SIZE); - } - else - { - throw; - } - } - break; + case M_GEOMETRY: + pMesh->sharedVertexData = OGRE_NEW VertexData(); + try { + readGeometry(stream, pMesh, pMesh->sharedVertexData); + } + catch (Exception& e) + { + if (e.getNumber() == Exception::ERR_ITEM_NOT_FOUND) + { + // duff geometry data entry with 0 vertices + OGRE_DELETE pMesh->sharedVertexData; + pMesh->sharedVertexData = 0; + // Skip this stream (pointer will have been returned to just after header) + stream->skip(mCurrentstreamLen - MSTREAM_OVERHEAD_SIZE); + } + else + { + throw; + } + } + break; case M_SUBMESH: readSubMesh(stream, pMesh, listener); break; @@ -950,22 +950,22 @@ namespace Ogre { readMeshBoneAssignment(stream, pMesh); break; case M_MESH_LOD_LEVEL: - readMeshLodLevel(stream, pMesh); - break; + readMeshLodLevel(stream, pMesh); + break; case M_MESH_BOUNDS: readBoundsInfo(stream, pMesh); break; - case M_SUBMESH_NAME_TABLE: - readSubMeshNameTable(stream, pMesh); - break; + case M_SUBMESH_NAME_TABLE: + readSubMeshNameTable(stream, pMesh); + break; case M_EDGE_LISTS: readEdgeList(stream, pMesh); break; - case M_POSES: - readPoses(stream, pMesh); - break; - case M_ANIMATIONS: - readAnimations(stream, pMesh); + case M_POSES: + readPoses(stream, pMesh); + break; + case M_ANIMATIONS: + readAnimations(stream, pMesh); break; case M_TABLE_EXTREMES: readExtremes(stream, pMesh); @@ -981,9 +981,9 @@ namespace Ogre { if (!stream->eof()) { // Backpedal back to start of stream - backpedalChunkHeader(stream); - } - popInnerChunk(stream); + backpedalChunkHeader(stream); + } + popInnerChunk(stream); } } @@ -996,8 +996,8 @@ namespace Ogre { // char* materialName String materialName = readString(stream); - if(listener) - listener->processMaterialName(pMesh, &materialName); + if(listener) + listener->processMaterialName(pMesh, &materialName); sm->setMaterialName(materialName, pMesh->getGroup()); // bool useSharedVertices @@ -1021,7 +1021,7 @@ namespace Ogre { HardwareIndexBuffer::IT_32BIT, sm->indexData->indexCount, pMesh->mIndexBufferUsage, - pMesh->mIndexBufferShadowBuffer); + pMesh->mIndexBufferShadowBuffer); // unsigned int* faceVertexIndices unsigned int* pIdx = static_cast( ibuf->lock(HardwareBuffer::HBL_DISCARD) @@ -1037,7 +1037,7 @@ namespace Ogre { HardwareIndexBuffer::IT_16BIT, sm->indexData->indexCount, pMesh->mIndexBufferUsage, - pMesh->mIndexBufferShadowBuffer); + pMesh->mIndexBufferShadowBuffer); // unsigned short* faceVertexIndices unsigned short* pIdx = static_cast( ibuf->lock(HardwareBuffer::HBL_DISCARD) @@ -1048,8 +1048,8 @@ namespace Ogre { } sm->indexData->indexBuffer = ibuf; - pushInnerChunk(stream); - { + pushInnerChunk(stream); + { // M_GEOMETRY stream (Optional: present only if useSharedVertices = false) if (!sm->useSharedVertices) { @@ -1095,11 +1095,11 @@ namespace Ogre { if (!stream->eof()) { // Backpedal back to start of stream - backpedalChunkHeader(stream); - } - } - } - popInnerChunk(stream); + backpedalChunkHeader(stream); + } + } + } + popInnerChunk(stream); } //--------------------------------------------------------------------- @@ -1131,8 +1131,8 @@ namespace Ogre { { String skelName = readString(stream); - if(listener) - listener->processSkeletonName(pMesh, &skelName); + if(listener) + listener->processSkeletonName(pMesh, &skelName); pMesh->setSkeletonName(skelName); } @@ -1147,7 +1147,7 @@ namespace Ogre { { size_t size = MSTREAM_OVERHEAD_SIZE; - size += calcStringSize(skelName); + size += calcStringSize(skelName); return size; @@ -1223,169 +1223,169 @@ namespace Ogre { } //--------------------------------------------------------------------- #if !OGRE_NO_MESHLOD - void MeshSerializerImpl::writeLodLevel(const Mesh* pMesh) - { - const LodStrategy *strategy = pMesh->getLodStrategy(); - exportedLodCount = pMesh->getNumLodLevels(); - writeChunkHeader(M_MESH_LOD_LEVEL, calcLodLevelSize(pMesh)); - writeString(strategy->getName()); // string strategyName; - writeShorts(&exportedLodCount, 1); // unsigned short numLevels; - - pushInnerChunk(mStream); - // Loop from LOD 1 (not 0, this is full detail) - for (ushort i = 1; i < exportedLodCount; ++i) - { - const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; - if (pMesh->_isManualLodLevel(i)) - { - writeLodUsageManual(usage); - } - else - { - writeLodUsageGenerated(pMesh, usage, i); - } - } - popInnerChunk(mStream); - } - - //--------------------------------------------------------------------- - void MeshSerializerImpl::writeLodUsageManual(const MeshLodUsage& usage) - { - writeChunkHeader(M_MESH_LOD_MANUAL, calcLodUsageManualSize(usage)); - float userValue = static_cast(usage.userValue); - writeFloats(&userValue, 1); - writeString(usage.manualName); - } - - void MeshSerializerImpl::writeLodUsageGeneratedSubmesh( const SubMesh* submesh, unsigned short lodNum ) - { - const IndexData* indexData = submesh->mLodFaceList[lodNum-1]; - HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; - assert(!ibuf.isNull()); - unsigned int bufferIndex = -1; - for(ushort i = 1; i < lodNum; i++){ - // it will check any previous Lod levels for the same buffer. - // This will allow to use merged/shared/compressed buffers. - const IndexData* prevIndexData = submesh->mLodFaceList[i-1]; - if(prevIndexData->indexCount != 0 && prevIndexData->indexBuffer == indexData->indexBuffer){ - bufferIndex = i; - } - } - - unsigned int indexCount = static_cast(indexData->indexCount); - writeInts(&indexCount, 1); - unsigned int indexStart = static_cast(indexData->indexStart); - writeInts(&indexStart, 1); - writeInts(&bufferIndex, 1); - - if(bufferIndex == (unsigned int)-1) { // It has its own buffer (Not compressed). - bool is32BitIndices = (ibuf->getType() == HardwareIndexBuffer::IT_32BIT); - writeBools(&is32BitIndices, 1); - - unsigned int bufIndexCount = static_cast(ibuf->getNumIndexes()); - writeInts(&bufIndexCount, 1); - - if (bufIndexCount > 0) - { - if (is32BitIndices) - { - unsigned int* pIdx = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - writeInts(pIdx, bufIndexCount); - ibuf->unlock(); - } - else - { - unsigned short* pIdx = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - writeShorts(pIdx, bufIndexCount); - ibuf->unlock(); - } - } - } - } - void MeshSerializerImpl::writeLodUsageGenerated(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum) - { - writeChunkHeader(M_MESH_LOD_GENERATED, calcLodUsageGeneratedSize(pMesh, usage, lodNum)); - float userValue = static_cast(usage.userValue); - writeFloats(&userValue, 1); - for (ushort i = 0; i < pMesh->getNumSubMeshes(); i++) - { - SubMesh* submesh = pMesh->getSubMesh(i); - writeLodUsageGeneratedSubmesh(submesh, lodNum); - } - } + void MeshSerializerImpl::writeLodLevel(const Mesh* pMesh) + { + const LodStrategy *strategy = pMesh->getLodStrategy(); + exportedLodCount = pMesh->getNumLodLevels(); + writeChunkHeader(M_MESH_LOD_LEVEL, calcLodLevelSize(pMesh)); + writeString(strategy->getName()); // string strategyName; + writeShorts(&exportedLodCount, 1); // unsigned short numLevels; + + pushInnerChunk(mStream); + // Loop from LOD 1 (not 0, this is full detail) + for (ushort i = 1; i < exportedLodCount; ++i) + { + const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; + if (pMesh->_isManualLodLevel(i)) + { + writeLodUsageManual(usage); + } + else + { + writeLodUsageGenerated(pMesh, usage, i); + } + } + popInnerChunk(mStream); + } + + //--------------------------------------------------------------------- + void MeshSerializerImpl::writeLodUsageManual(const MeshLodUsage& usage) + { + writeChunkHeader(M_MESH_LOD_MANUAL, calcLodUsageManualSize(usage)); + float userValue = static_cast(usage.userValue); + writeFloats(&userValue, 1); + writeString(usage.manualName); + } + + void MeshSerializerImpl::writeLodUsageGeneratedSubmesh( const SubMesh* submesh, unsigned short lodNum ) + { + const IndexData* indexData = submesh->mLodFaceList[lodNum-1]; + HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; + assert(!ibuf.isNull()); + unsigned int bufferIndex = -1; + for(ushort i = 1; i < lodNum; i++){ + // it will check any previous Lod levels for the same buffer. + // This will allow to use merged/shared/compressed buffers. + const IndexData* prevIndexData = submesh->mLodFaceList[i-1]; + if(prevIndexData->indexCount != 0 && prevIndexData->indexBuffer == indexData->indexBuffer){ + bufferIndex = i; + } + } + + unsigned int indexCount = static_cast(indexData->indexCount); + writeInts(&indexCount, 1); + unsigned int indexStart = static_cast(indexData->indexStart); + writeInts(&indexStart, 1); + writeInts(&bufferIndex, 1); + + if(bufferIndex == (unsigned int)-1) { // It has its own buffer (Not compressed). + bool is32BitIndices = (ibuf->getType() == HardwareIndexBuffer::IT_32BIT); + writeBools(&is32BitIndices, 1); + + unsigned int bufIndexCount = static_cast(ibuf->getNumIndexes()); + writeInts(&bufIndexCount, 1); + + if (bufIndexCount > 0) + { + if (is32BitIndices) + { + unsigned int* pIdx = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + writeInts(pIdx, bufIndexCount); + ibuf->unlock(); + } + else + { + unsigned short* pIdx = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + writeShorts(pIdx, bufIndexCount); + ibuf->unlock(); + } + } + } + } + void MeshSerializerImpl::writeLodUsageGenerated(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum) + { + writeChunkHeader(M_MESH_LOD_GENERATED, calcLodUsageGeneratedSize(pMesh, usage, lodNum)); + float userValue = static_cast(usage.userValue); + writeFloats(&userValue, 1); + for (ushort i = 0; i < pMesh->getNumSubMeshes(); i++) + { + SubMesh* submesh = pMesh->getSubMesh(i); + writeLodUsageGeneratedSubmesh(submesh, lodNum); + } + } #endif - size_t MeshSerializerImpl::calcLodLevelSize(const Mesh* pMesh) - { - exportedLodCount = pMesh->getNumLodLevels(); - size_t size = MSTREAM_OVERHEAD_SIZE; // Header - size += calcStringSize(pMesh->getLodStrategy()->getName()); // string strategyName; - size += sizeof(unsigned short); // unsigned short numLevels; - //size += sizeof(bool); // bool manual; <== this is removed in v1_9 - - // Loop from LOD 1 (not 0, this is full detail) - for (ushort i = 1; i < exportedLodCount; ++i) - { - const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; - if (pMesh->_isManualLodLevel(i)) - { - size += calcLodUsageManualSize(usage); - } - else - { - size += calcLodUsageGeneratedSize(pMesh, usage, i); - } - } - return size; - } - - size_t MeshSerializerImpl::calcLodUsageManualSize(const MeshLodUsage& usage) - { - size_t size = MSTREAM_OVERHEAD_SIZE;// Header - size += sizeof(float);// float usage.userValue; - size += calcStringSize(usage.manualName); - return size; - } - - size_t MeshSerializerImpl::calcLodUsageGeneratedSize(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - size += sizeof(float); // float usage.userValue; - for (ushort i = 0; i < pMesh->getNumSubMeshes(); i++) - { - SubMesh* submesh = pMesh->getSubMesh(i); - size += calcLodUsageGeneratedSubmeshSize(submesh, lodNum); - } - return size; - } - size_t MeshSerializerImpl::calcLodUsageGeneratedSubmeshSize( const SubMesh* submesh, unsigned short lodNum ) - { - size_t size = 0; - - const IndexData* indexData = submesh->mLodFaceList[lodNum-1]; - HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; - assert(!ibuf.isNull()); - unsigned int bufferIndex = -1; - for(ushort i = 1; i < lodNum; i++){ - // it will check any previous Lod levels for the same buffer. - // This will allow to use merged/shared/compressed buffers. - const IndexData* prevIndexData = submesh->mLodFaceList[i-1]; - if(prevIndexData->indexCount != 0 && prevIndexData->indexBuffer == indexData->indexBuffer){ - bufferIndex = i; - } - } - - size += sizeof(unsigned int); // unsigned int indexData->indexCount; - size += sizeof(unsigned int); // unsigned int indexData->indexStart; - size += sizeof(unsigned int); // unsigned int bufferIndex; - if(bufferIndex == (unsigned int)-1) { - size += sizeof(bool); // bool indexes32Bit - size += sizeof(unsigned int); // unsigned int ibuf->getNumIndexes() - size += ibuf.isNull() ? 0 : static_cast(ibuf->getIndexSize() * ibuf->getNumIndexes()); // faces - } - return size; - } + size_t MeshSerializerImpl::calcLodLevelSize(const Mesh* pMesh) + { + exportedLodCount = pMesh->getNumLodLevels(); + size_t size = MSTREAM_OVERHEAD_SIZE; // Header + size += calcStringSize(pMesh->getLodStrategy()->getName()); // string strategyName; + size += sizeof(unsigned short); // unsigned short numLevels; + //size += sizeof(bool); // bool manual; <== this is removed in v1_9 + + // Loop from LOD 1 (not 0, this is full detail) + for (ushort i = 1; i < exportedLodCount; ++i) + { + const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; + if (pMesh->_isManualLodLevel(i)) + { + size += calcLodUsageManualSize(usage); + } + else + { + size += calcLodUsageGeneratedSize(pMesh, usage, i); + } + } + return size; + } + + size_t MeshSerializerImpl::calcLodUsageManualSize(const MeshLodUsage& usage) + { + size_t size = MSTREAM_OVERHEAD_SIZE;// Header + size += sizeof(float);// float usage.userValue; + size += calcStringSize(usage.manualName); + return size; + } + + size_t MeshSerializerImpl::calcLodUsageGeneratedSize(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + size += sizeof(float); // float usage.userValue; + for (ushort i = 0; i < pMesh->getNumSubMeshes(); i++) + { + SubMesh* submesh = pMesh->getSubMesh(i); + size += calcLodUsageGeneratedSubmeshSize(submesh, lodNum); + } + return size; + } + size_t MeshSerializerImpl::calcLodUsageGeneratedSubmeshSize( const SubMesh* submesh, unsigned short lodNum ) + { + size_t size = 0; + + const IndexData* indexData = submesh->mLodFaceList[lodNum-1]; + HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; + assert(!ibuf.isNull()); + unsigned int bufferIndex = -1; + for(ushort i = 1; i < lodNum; i++){ + // it will check any previous Lod levels for the same buffer. + // This will allow to use merged/shared/compressed buffers. + const IndexData* prevIndexData = submesh->mLodFaceList[i-1]; + if(prevIndexData->indexCount != 0 && prevIndexData->indexBuffer == indexData->indexBuffer){ + bufferIndex = i; + } + } + + size += sizeof(unsigned int); // unsigned int indexData->indexCount; + size += sizeof(unsigned int); // unsigned int indexData->indexStart; + size += sizeof(unsigned int); // unsigned int bufferIndex; + if(bufferIndex == (unsigned int)-1) { + size += sizeof(bool); // bool indexes32Bit + size += sizeof(unsigned int); // unsigned int ibuf->getNumIndexes() + size += ibuf.isNull() ? 0 : static_cast(ibuf->getIndexSize() * ibuf->getNumIndexes()); // faces + } + return size; + } //--------------------------------------------------------------------- void MeshSerializerImpl::writeBoundsInfo(const Mesh* pMesh) { @@ -1424,76 +1424,76 @@ namespace Ogre { readFloats(stream, &radius, 1); pMesh->_setBoundingSphereRadius(radius); } - size_t MeshSerializerImpl::calcBoundsInfoSize(const Mesh* pMesh) - { - unsigned long size = MSTREAM_OVERHEAD_SIZE; - size += sizeof(float) * 7; - return size; - } + size_t MeshSerializerImpl::calcBoundsInfoSize(const Mesh* pMesh) + { + unsigned long size = MSTREAM_OVERHEAD_SIZE; + size += sizeof(float) * 7; + return size; + } //--------------------------------------------------------------------- - void MeshSerializerImpl::readMeshLodLevel(DataStreamPtr& stream, Mesh* pMesh) - { + void MeshSerializerImpl::readMeshLodLevel(DataStreamPtr& stream, Mesh* pMesh) + { #if OGRE_NO_MESHLOD - /* - //Since the chunk sizes in old versions are messed up, we can't use this clean solution. - // We need to walk through the data to not rely on the chunk size! - stream->skip(mCurrentstreamLen); - - // Since we got here, we have already read the chunk header. - backpedalChunkHeader(stream); - */ - uint16 numSubs = pMesh->getNumSubMeshes(); - String strategyName = readString(stream); - uint16 numLods; - readShorts(stream, &numLods, 1); - pushInnerChunk(stream); - for (int lodID = 1; lodID < numLods; lodID++){ - unsigned short streamID = readChunk(stream); - Real usageValue; - readFloats(stream, &usageValue, 1); - switch (streamID){ - case M_MESH_LOD_MANUAL: - { - String manualName = readString(stream); - break; - } - case M_MESH_LOD_GENERATED: - for (int i = 0; i < numSubs; ++i) - { - unsigned int numIndexes; - readInts(stream, &numIndexes, 1); - - unsigned int offset; - readInts(stream, &offset, 1); - - // For merged buffers, you can pass the index of previous Lod. - // To create buffer it should be -1. - unsigned int bufferIndex; - readInts(stream, &bufferIndex, 1); - if (bufferIndex == (unsigned int)-1) { - // generate buffers - - // bool indexes32Bit - bool idx32Bit; - readBools(stream, &idx32Bit, 1); - - unsigned int buffIndexCount; - readInts(stream, &buffIndexCount, 1); - - size_t buffSize = buffIndexCount * (idx32Bit ? 4 : 2); - stream->skip(buffSize); - } - } - break; - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid Lod Usage type in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodInfo"); - } - } - popInnerChunk(stream); + /* + //Since the chunk sizes in old versions are messed up, we can't use this clean solution. + // We need to walk through the data to not rely on the chunk size! + stream->skip(mCurrentstreamLen); + + // Since we got here, we have already read the chunk header. + backpedalChunkHeader(stream); + */ + uint16 numSubs = pMesh->getNumSubMeshes(); + String strategyName = readString(stream); + uint16 numLods; + readShorts(stream, &numLods, 1); + pushInnerChunk(stream); + for (int lodID = 1; lodID < numLods; lodID++){ + unsigned short streamID = readChunk(stream); + Real usageValue; + readFloats(stream, &usageValue, 1); + switch (streamID){ + case M_MESH_LOD_MANUAL: + { + String manualName = readString(stream); + break; + } + case M_MESH_LOD_GENERATED: + for (int i = 0; i < numSubs; ++i) + { + unsigned int numIndexes; + readInts(stream, &numIndexes, 1); + + unsigned int offset; + readInts(stream, &offset, 1); + + // For merged buffers, you can pass the index of previous Lod. + // To create buffer it should be -1. + unsigned int bufferIndex; + readInts(stream, &bufferIndex, 1); + if (bufferIndex == (unsigned int)-1) { + // generate buffers + + // bool indexes32Bit + bool idx32Bit; + readBools(stream, &idx32Bit, 1); + + unsigned int buffIndexCount; + readInts(stream, &buffIndexCount, 1); + + size_t buffSize = buffIndexCount * (idx32Bit ? 4 : 2); + stream->skip(buffSize); + } + } + break; + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid Lod Usage type in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodInfo"); + } + } + popInnerChunk(stream); #else // Read the strategy to be used for this mesh String strategyName = readString(stream); @@ -1506,200 +1506,200 @@ namespace Ogre { pMesh->setLodStrategy(strategy); // unsigned short numLevels; - readShorts(stream, &(pMesh->mNumLods), 1); - - pMesh->mMeshLodUsageList.resize(pMesh->mNumLods); - ushort numSubs, i; - numSubs = pMesh->getNumSubMeshes(); - for (i = 0; i < numSubs; ++i) - { - SubMesh* sm = pMesh->getSubMesh(i); - assert(sm->mLodFaceList.empty()); - sm->mLodFaceList.resize(pMesh->mNumLods-1); - } - pushInnerChunk(stream); - // lodID=0 is the original mesh. We need to skip it. - for(int lodID = 1; lodID < pMesh->mNumLods; lodID++){ - // Read depth - MeshLodUsage& usage = pMesh->mMeshLodUsageList[lodID]; - unsigned short streamID = readChunk(stream); - readFloats(stream, &(usage.userValue), 1); - switch(streamID){ - case M_MESH_LOD_MANUAL: - readMeshLodUsageManual(stream, pMesh, lodID, usage); - break; - case M_MESH_LOD_GENERATED: - readMeshLodUsageGenerated(stream, pMesh, lodID, usage); - break; - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid Lod Usage type in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodInfo"); - } - usage.manualMesh.setNull(); // will trigger load later with manual Lod - usage.edgeData = NULL; - } - popInnerChunk(stream); + readShorts(stream, &(pMesh->mNumLods), 1); + + pMesh->mMeshLodUsageList.resize(pMesh->mNumLods); + ushort numSubs, i; + numSubs = pMesh->getNumSubMeshes(); + for (i = 0; i < numSubs; ++i) + { + SubMesh* sm = pMesh->getSubMesh(i); + assert(sm->mLodFaceList.empty()); + sm->mLodFaceList.resize(pMesh->mNumLods-1); + } + pushInnerChunk(stream); + // lodID=0 is the original mesh. We need to skip it. + for(int lodID = 1; lodID < pMesh->mNumLods; lodID++){ + // Read depth + MeshLodUsage& usage = pMesh->mMeshLodUsageList[lodID]; + unsigned short streamID = readChunk(stream); + readFloats(stream, &(usage.userValue), 1); + switch(streamID){ + case M_MESH_LOD_MANUAL: + readMeshLodUsageManual(stream, pMesh, lodID, usage); + break; + case M_MESH_LOD_GENERATED: + readMeshLodUsageGenerated(stream, pMesh, lodID, usage); + break; + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid Lod Usage type in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodInfo"); + } + usage.manualMesh.setNull(); // will trigger load later with manual Lod + usage.edgeData = NULL; + } + popInnerChunk(stream); #endif - } + } #if !OGRE_NO_MESHLOD - //--------------------------------------------------------------------- - void MeshSerializerImpl::readMeshLodUsageManual( DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage ) - { - pMesh->mHasManualLodLevel = true; - usage.manualName = readString(stream); - - // Generate for mixed - ushort numSubs, i; - numSubs = pMesh->getNumSubMeshes(); - for (i = 0; i < numSubs; ++i) - { - - SubMesh* sm = pMesh->getSubMesh(i); - sm->mLodFaceList[lodNum-1] = OGRE_NEW IndexData(); - } - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::readMeshLodUsageGenerated( DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage ) - { - usage.manualName = ""; - - // Get one set of detail per SubMesh - unsigned short numSubs, i; - numSubs = pMesh->getNumSubMeshes(); - for (i = 0; i < numSubs; ++i) - { - SubMesh* sm = pMesh->getSubMesh(i); - sm->mLodFaceList[lodNum-1] = OGRE_NEW IndexData(); - IndexData* indexData = sm->mLodFaceList[lodNum-1]; - - unsigned int numIndexes; - readInts(stream, &numIndexes, 1); - indexData->indexCount = static_cast(numIndexes); - - unsigned int offset; - readInts(stream, &offset, 1); - indexData->indexStart = static_cast(offset); - - // For merged buffers, you can pass the index of previous Lod. - // To create buffer it should be -1. - unsigned int bufferIndex; - readInts(stream, &bufferIndex, 1); - if(bufferIndex != (unsigned int)-1) { - // copy buffer pointer - indexData->indexBuffer = sm->mLodFaceList[bufferIndex]->indexBuffer; - } else { - // generate buffers - - // bool indexes32Bit - bool idx32Bit; - readBools(stream, &idx32Bit, 1); - - unsigned int buffIndexCount; - readInts(stream, &buffIndexCount, 1); - - indexData->indexBuffer = HardwareBufferManager::getSingleton(). - createIndexBuffer(idx32Bit ? HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT, - buffIndexCount, pMesh->mIndexBufferUsage, pMesh->mIndexBufferShadowBuffer); - void* pIdx = static_cast(indexData->indexBuffer->lock( - 0, indexData->indexBuffer->getSizeInBytes(), HardwareBuffer::HBL_DISCARD)); - - // unsigned short*/int* faceIndexes; ((v1, v2, v3) * numFaces) - if (idx32Bit) - { - readInts(stream, (uint32*)pIdx, buffIndexCount); - } - else - { - readShorts(stream, (uint16*)pIdx, buffIndexCount); - } - indexData->indexBuffer->unlock(); - } - } - } -#endif //--------------------------------------------------------------------- - void MeshSerializerImpl::flipFromLittleEndian(void* pData, size_t vertexCount, - size_t vertexSize, const VertexDeclaration::VertexElementList& elems) - { - if (mFlipEndian) - { - flipEndian(pData, vertexCount, vertexSize, elems); - } + void MeshSerializerImpl::readMeshLodUsageManual( DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage ) + { + pMesh->mHasManualLodLevel = true; + usage.manualName = readString(stream); + + // Generate for mixed + ushort numSubs, i; + numSubs = pMesh->getNumSubMeshes(); + for (i = 0; i < numSubs; ++i) + { + + SubMesh* sm = pMesh->getSubMesh(i); + sm->mLodFaceList[lodNum-1] = OGRE_NEW IndexData(); + } + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::readMeshLodUsageGenerated( DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage ) + { + usage.manualName = ""; + + // Get one set of detail per SubMesh + unsigned short numSubs, i; + numSubs = pMesh->getNumSubMeshes(); + for (i = 0; i < numSubs; ++i) + { + SubMesh* sm = pMesh->getSubMesh(i); + sm->mLodFaceList[lodNum-1] = OGRE_NEW IndexData(); + IndexData* indexData = sm->mLodFaceList[lodNum-1]; + + unsigned int numIndexes; + readInts(stream, &numIndexes, 1); + indexData->indexCount = static_cast(numIndexes); + + unsigned int offset; + readInts(stream, &offset, 1); + indexData->indexStart = static_cast(offset); + + // For merged buffers, you can pass the index of previous Lod. + // To create buffer it should be -1. + unsigned int bufferIndex; + readInts(stream, &bufferIndex, 1); + if(bufferIndex != (unsigned int)-1) { + // copy buffer pointer + indexData->indexBuffer = sm->mLodFaceList[bufferIndex]->indexBuffer; + } else { + // generate buffers + + // bool indexes32Bit + bool idx32Bit; + readBools(stream, &idx32Bit, 1); + + unsigned int buffIndexCount; + readInts(stream, &buffIndexCount, 1); + + indexData->indexBuffer = HardwareBufferManager::getSingleton(). + createIndexBuffer(idx32Bit ? HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT, + buffIndexCount, pMesh->mIndexBufferUsage, pMesh->mIndexBufferShadowBuffer); + void* pIdx = static_cast(indexData->indexBuffer->lock( + 0, indexData->indexBuffer->getSizeInBytes(), HardwareBuffer::HBL_DISCARD)); + + // unsigned short*/int* faceIndexes; ((v1, v2, v3) * numFaces) + if (idx32Bit) + { + readInts(stream, (uint32*)pIdx, buffIndexCount); + } + else + { + readShorts(stream, (uint16*)pIdx, buffIndexCount); + } + indexData->indexBuffer->unlock(); + } + } + } +#endif + //--------------------------------------------------------------------- + void MeshSerializerImpl::flipFromLittleEndian(void* pData, size_t vertexCount, + size_t vertexSize, const VertexDeclaration::VertexElementList& elems) + { + if (mFlipEndian) + { + flipEndian(pData, vertexCount, vertexSize, elems); + } } //--------------------------------------------------------------------- void MeshSerializerImpl::flipToLittleEndian(void* pData, size_t vertexCount, - size_t vertexSize, const VertexDeclaration::VertexElementList& elems) - { - if (mFlipEndian) - { - flipEndian(pData, vertexCount, vertexSize, elems); - } - } + size_t vertexSize, const VertexDeclaration::VertexElementList& elems) + { + if (mFlipEndian) + { + flipEndian(pData, vertexCount, vertexSize, elems); + } + } //--------------------------------------------------------------------- void MeshSerializerImpl::flipEndian(void* pData, size_t vertexCount, size_t vertexSize, const VertexDeclaration::VertexElementList& elems) - { - void *pBase = pData; - for (size_t v = 0; v < vertexCount; ++v) - { - VertexDeclaration::VertexElementList::const_iterator ei, eiend; - eiend = elems.end(); - for (ei = elems.begin(); ei != eiend; ++ei) - { - void *pElem; - // re-base pointer to the element - (*ei).baseVertexPointerToElement(pBase, &pElem); - // Flip the endian based on the type - size_t typeSize = 0; - switch (VertexElement::getBaseType((*ei).getType())) - { - case VET_FLOAT1: - typeSize = sizeof(float); - break; - case VET_DOUBLE1: - typeSize = sizeof(double); - break; - case VET_SHORT1: - typeSize = sizeof(short); - break; - case VET_USHORT1: - typeSize = sizeof(unsigned short); - break; - case VET_INT1: - typeSize = sizeof(int); - break; - case VET_UINT1: - typeSize = sizeof(unsigned int); - break; - case VET_COLOUR: - case VET_COLOUR_ABGR: - case VET_COLOUR_ARGB: - typeSize = sizeof(RGBA); - break; - case VET_UBYTE4: - typeSize = 0; // NO FLIPPING - break; - default: - assert(false); // Should never happen - }; + { + void *pBase = pData; + for (size_t v = 0; v < vertexCount; ++v) + { + VertexDeclaration::VertexElementList::const_iterator ei, eiend; + eiend = elems.end(); + for (ei = elems.begin(); ei != eiend; ++ei) + { + void *pElem; + // re-base pointer to the element + (*ei).baseVertexPointerToElement(pBase, &pElem); + // Flip the endian based on the type + size_t typeSize = 0; + switch (VertexElement::getBaseType((*ei).getType())) + { + case VET_FLOAT1: + typeSize = sizeof(float); + break; + case VET_DOUBLE1: + typeSize = sizeof(double); + break; + case VET_SHORT1: + typeSize = sizeof(short); + break; + case VET_USHORT1: + typeSize = sizeof(unsigned short); + break; + case VET_INT1: + typeSize = sizeof(int); + break; + case VET_UINT1: + typeSize = sizeof(unsigned int); + break; + case VET_COLOUR: + case VET_COLOUR_ABGR: + case VET_COLOUR_ARGB: + typeSize = sizeof(RGBA); + break; + case VET_UBYTE4: + typeSize = 0; // NO FLIPPING + break; + default: + assert(false); // Should never happen + }; Serializer::flipEndian(pElem, typeSize, - VertexElement::getTypeCount((*ei).getType())); + VertexElement::getTypeCount((*ei).getType())); - } + } - pBase = static_cast( - static_cast(pBase) + vertexSize); + pBase = static_cast( + static_cast(pBase) + vertexSize); - } - } + } + } //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcEdgeListSize(const Mesh* pMesh) - { + size_t MeshSerializerImpl::calcEdgeListSize(const Mesh* pMesh) + { size_t size = MSTREAM_OVERHEAD_SIZE; - for (ushort i = 0; i < exportedLodCount; ++i) + for (ushort i = 0; i < exportedLodCount; ++i) { const EdgeData* edgeData = pMesh->getEdgeList(i); @@ -1710,7 +1710,7 @@ namespace Ogre { } return size; - } + } //--------------------------------------------------------------------- size_t MeshSerializerImpl::calcEdgeListLodSize(const EdgeData* edgeData, bool isManual) { @@ -1719,7 +1719,7 @@ namespace Ogre { // unsigned short lodIndex size += sizeof(uint16); - // bool isManual // If manual, no edge data here, loaded from manual mesh + // bool isManual // If manual, no edge data here, loaded from manual mesh size += sizeof(bool); if (!isManual) { @@ -1777,21 +1777,21 @@ namespace Ogre { return size; } //--------------------------------------------------------------------- - void MeshSerializerImpl::writeEdgeList(const Mesh* pMesh) - { + void MeshSerializerImpl::writeEdgeList(const Mesh* pMesh) + { writeChunkHeader(M_EDGE_LISTS, calcEdgeListSize(pMesh)); - pushInnerChunk(mStream); - { - for (ushort i = 0; i < exportedLodCount; ++i) + pushInnerChunk(mStream); + { + for (ushort i = 0; i < exportedLodCount; ++i) { const EdgeData* edgeData = pMesh->getEdgeList(i); - bool isManual = !pMesh->mMeshLodUsageList[i].manualName.empty(); + bool isManual = !pMesh->mMeshLodUsageList[i].manualName.empty(); writeChunkHeader(M_EDGE_LIST_LOD, calcEdgeListLodSize(edgeData, isManual)); // unsigned short lodIndex writeShorts(&i, 1); - // bool isManual // If manual, no edge data here, loaded from manual mesh + // bool isManual // If manual, no edge data here, loaded from manual mesh writeBools(&isManual, 1); if (!isManual) { @@ -1831,8 +1831,8 @@ namespace Ogre { writeFloats(&(fni->x), 4); } - pushInnerChunk(mStream); - { + pushInnerChunk(mStream); + { // Write the groups for (EdgeData::EdgeGroupList::const_iterator gi = edgeData->edgeGroups.begin(); gi != edgeData->edgeGroups.end(); ++gi) @@ -1875,21 +1875,21 @@ namespace Ogre { } } - } - popInnerChunk(mStream); + } + popInnerChunk(mStream); - } + } - } - } - popInnerChunk(mStream); - } + } + } + popInnerChunk(mStream); + } //--------------------------------------------------------------------- - void MeshSerializerImpl::readEdgeList(DataStreamPtr& stream, Mesh* pMesh) - { + void MeshSerializerImpl::readEdgeList(DataStreamPtr& stream, Mesh* pMesh) + { if (!stream->eof()) { - pushInnerChunk(stream); + pushInnerChunk(stream); unsigned short streamID = readChunk(stream); while(!stream->eof() && streamID == M_EDGE_LIST_LOD) @@ -1900,20 +1900,20 @@ namespace Ogre { unsigned short lodIndex; readShorts(stream, &lodIndex, 1); - // bool isManual // If manual, no edge data here, loaded from manual mesh + // bool isManual // If manual, no edge data here, loaded from manual mesh bool isManual; readBools(stream, &isManual, 1); // Only load in non-manual levels; others will be connected up by Mesh on demand #if OGRE_NO_MESHLOD - // + // if (!isManual) - if (lodIndex != 0) { - readEdgeListLodInfo(stream, NULL); - } else { + if (lodIndex != 0) { + readEdgeListLodInfo(stream, NULL); + } else { #else - if (!isManual) { + if (!isManual) { #endif - MeshLodUsage& usage = pMesh->mMeshLodUsageList[lodIndex]; + MeshLodUsage& usage = pMesh->mMeshLodUsageList[lodIndex]; usage.edgeData = OGRE_NEW EdgeData(); @@ -1958,1429 +1958,1429 @@ namespace Ogre { if (!stream->eof()) { // Backpedal back to start of stream - backpedalChunkHeader(stream); + backpedalChunkHeader(stream); + } + popInnerChunk(stream); + } + + pMesh->mEdgeListsBuilt = true; + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::readEdgeListLodInfo(DataStreamPtr& stream, + EdgeData* edgeData) + { +#if OGRE_NO_MESHLOD + if (edgeData == NULL) { // skip it! + bool isClosed; + readBools(stream, &isClosed, 1); + // unsigned long numTriangles + uint32 numTriangles; + readInts(stream, &numTriangles, 1); + // unsigned long numEdgeGroups + uint32 numEdgeGroups; + readInts(stream, &numEdgeGroups, 1); + stream->skip(numTriangles * (8 * sizeof(uint32) + 4 * sizeof(float))); + pushInnerChunk(stream); + for (uint32 eg = 0; eg < numEdgeGroups; ++eg) + { + unsigned short streamID = readChunk(stream); + if (streamID != M_EDGE_GROUP) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Missing M_EDGE_GROUP stream", + "MeshSerializerImpl::readEdgeListLodInfo"); + } + uint32 tmp[3]; + // unsigned long vertexSet + readInts(stream, &tmp[0], 3); + uint32 numEdges; + readInts(stream, &numEdges, 1); + + stream->skip(numEdges * (6 * sizeof(uint32) + sizeof(bool))); + } + popInnerChunk(stream); + return; + } +#endif + // bool isClosed + readBools(stream, &edgeData->isClosed, 1); + // unsigned long numTriangles + uint32 numTriangles; + readInts(stream, &numTriangles, 1); + // Allocate correct amount of memory + edgeData->triangles.resize(numTriangles); + edgeData->triangleFaceNormals.resize(numTriangles); + edgeData->triangleLightFacings.resize(numTriangles); + // unsigned long numEdgeGroups + uint32 numEdgeGroups; + readInts(stream, &numEdgeGroups, 1); + // Allocate correct amount of memory + edgeData->edgeGroups.resize(numEdgeGroups); + // Triangle* triangleList + uint32 tmp[3]; + for (size_t t = 0; t < numTriangles; ++t) + { + EdgeData::Triangle& tri = edgeData->triangles[t]; + // unsigned long indexSet + readInts(stream, tmp, 1); + tri.indexSet = tmp[0]; + // unsigned long vertexSet + readInts(stream, tmp, 1); + tri.vertexSet = tmp[0]; + // unsigned long vertIndex[3] + readInts(stream, tmp, 3); + + tri.vertIndex[0] = tmp[0]; + tri.vertIndex[1] = tmp[1]; + tri.vertIndex[2] = tmp[2]; + // unsigned long sharedVertIndex[3] + readInts(stream, tmp, 3); + tri.sharedVertIndex[0] = tmp[0]; + tri.sharedVertIndex[1] = tmp[1]; + tri.sharedVertIndex[2] = tmp[2]; + // float normal[4] + readFloats(stream, &(edgeData->triangleFaceNormals[t].x), 4); + + } + pushInnerChunk(stream); + for (uint32 eg = 0; eg < numEdgeGroups; ++eg) + { + unsigned short streamID = readChunk(stream); + if (streamID != M_EDGE_GROUP) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Missing M_EDGE_GROUP stream", + "MeshSerializerImpl::readEdgeListLodInfo"); + } + EdgeData::EdgeGroup& edgeGroup = edgeData->edgeGroups[eg]; + + // unsigned long vertexSet + readInts(stream, tmp, 1); + edgeGroup.vertexSet = tmp[0]; + // unsigned long triStart + readInts(stream, tmp, 1); + edgeGroup.triStart = tmp[0]; + // unsigned long triCount + readInts(stream, tmp, 1); + edgeGroup.triCount = tmp[0]; + // unsigned long numEdges + uint32 numEdges; + readInts(stream, &numEdges, 1); + edgeGroup.edges.resize(numEdges); + // Edge* edgeList + for (uint32 e = 0; e < numEdges; ++e) + { + EdgeData::Edge& edge = edgeGroup.edges[e]; + // unsigned long triIndex[2] + readInts(stream, tmp, 2); + edge.triIndex[0] = tmp[0]; + edge.triIndex[1] = tmp[1]; + // unsigned long vertIndex[2] + readInts(stream, tmp, 2); + edge.vertIndex[0] = tmp[0]; + edge.vertIndex[1] = tmp[1]; + // unsigned long sharedVertIndex[2] + readInts(stream, tmp, 2); + edge.sharedVertIndex[0] = tmp[0]; + edge.sharedVertIndex[1] = tmp[1]; + // bool degenerate + readBools(stream, &(edge.degenerate), 1); + } + } + popInnerChunk(stream); + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl::calcAnimationsSize(const Mesh* pMesh) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + + for (unsigned short a = 0; a < pMesh->getNumAnimations(); ++a) + { + Animation* anim = pMesh->getAnimation(a); + size += calcAnimationSize(anim); + } + return size; + + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl::calcAnimationSize(const Animation* anim) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + // char* name + size += anim->getName().length() + 1; + + // float length + size += sizeof(float); + + Animation::VertexTrackIterator trackIt = anim->getVertexTrackIterator(); + while (trackIt.hasMoreElements()) + { + VertexAnimationTrack* vt = trackIt.getNext(); + size += calcAnimationTrackSize(vt); + } + + return size; + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl::calcAnimationTrackSize(const VertexAnimationTrack* track) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + // uint16 type + size += sizeof(uint16); + // unsigned short target // 0 for shared geometry, + size += sizeof(unsigned short); + + if (track->getAnimationType() == VAT_MORPH) + { + for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) + { + VertexMorphKeyFrame* kf = track->getVertexMorphKeyFrame(i); + size += calcMorphKeyframeSize(kf, track->getAssociatedVertexData()->vertexCount); + } + } + else + { + for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) + { + VertexPoseKeyFrame* kf = track->getVertexPoseKeyFrame(i); + size += calcPoseKeyframeSize(kf); + } + } + return size; + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl::calcMorphKeyframeSize(const VertexMorphKeyFrame* kf, + size_t vertexCount) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + // float time + size += sizeof(float); + // float x,y,z[,nx,ny,nz] + bool includesNormals = kf->getVertexBuffer()->getVertexSize() > (sizeof(float) * 3); + size += sizeof(float) * (includesNormals ? 6 : 3) * vertexCount; + + return size; + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl::calcPoseKeyframeSize(const VertexPoseKeyFrame* kf) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + + // float time + size += sizeof(float); + + size += calcPoseKeyframePoseRefSize() * kf->getPoseReferences().size(); + + return size; + + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl::calcPoseKeyframePoseRefSize(void) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + // unsigned short poseIndex + size += sizeof(uint16); + // float influence + size += sizeof(float); + + return size; + + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl::calcPosesSize(const Mesh* pMesh) + { + size_t size = 0; + Mesh::ConstPoseIterator poseIterator = pMesh->getPoseIterator(); + if (poseIterator.hasMoreElements()) + { + size += MSTREAM_OVERHEAD_SIZE; + while (poseIterator.hasMoreElements()) + { + size += calcPoseSize(poseIterator.getNext()); + } + } + return size; + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl::calcPoseSize(const Pose* pose) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + + // char* name (may be blank) + size += pose->getName().length() + 1; + // unsigned short target + size += sizeof(uint16); + // bool includesNormals + size += sizeof(bool); + + // vertex offsets + size += pose->getVertexOffsets().size() * calcPoseVertexSize(pose); + + return size; + + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl::calcPoseVertexSize(const Pose* pose) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + // unsigned long vertexIndex + size += sizeof(uint32); + // float xoffset, yoffset, zoffset + size += sizeof(float) * 3; + // optional normals + if (!pose->getNormals().empty()) + size += sizeof(float) * 3; + + return size; + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::writePoses(const Mesh* pMesh) + { + Mesh::ConstPoseIterator poseIterator = pMesh->getPoseIterator(); + if (poseIterator.hasMoreElements()) + { + writeChunkHeader(M_POSES, calcPosesSize(pMesh)); + pushInnerChunk(mStream); + while (poseIterator.hasMoreElements()) + { + writePose(poseIterator.getNext()); + } + popInnerChunk(mStream); + } + + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::writePose(const Pose* pose) + { + writeChunkHeader(M_POSE, calcPoseSize(pose)); + + // char* name (may be blank) + writeString(pose->getName()); + + // unsigned short target + ushort val = pose->getTarget(); + writeShorts(&val, 1); + + // bool includesNormals + bool includesNormals = !pose->getNormals().empty(); + writeBools(&includesNormals, 1); + pushInnerChunk(mStream); + { + size_t vertexSize = calcPoseVertexSize(pose); + Pose::ConstVertexOffsetIterator vit = pose->getVertexOffsetIterator(); + Pose::ConstNormalsIterator nit = pose->getNormalsIterator(); + while (vit.hasMoreElements()) + { + uint32 vertexIndex = (uint32)vit.peekNextKey(); + Vector3 offset = vit.getNext(); + writeChunkHeader(M_POSE_VERTEX, vertexSize); + // unsigned long vertexIndex + writeInts(&vertexIndex, 1); + // float xoffset, yoffset, zoffset + writeFloats(offset.ptr(), 3); + if (includesNormals) + { + Vector3 normal = nit.getNext(); + // float xnormal, ynormal, znormal + writeFloats(normal.ptr(), 3); + } + } + } + popInnerChunk(mStream); + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::writeAnimations(const Mesh* pMesh) + { + writeChunkHeader(M_ANIMATIONS, calcAnimationsSize(pMesh)); + pushInnerChunk(mStream); + for (unsigned short a = 0; a < pMesh->getNumAnimations(); ++a) + { + Animation* anim = pMesh->getAnimation(a); + LogManager::getSingleton().logMessage("Exporting animation " + anim->getName()); + writeAnimation(anim); + LogManager::getSingleton().logMessage("Animation exported."); + } + popInnerChunk(mStream); + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::writeAnimation(const Animation* anim) + { + writeChunkHeader(M_ANIMATION, calcAnimationSize(anim)); + // char* name + writeString(anim->getName()); + // float length + float len = anim->getLength(); + writeFloats(&len, 1); + pushInnerChunk(mStream); + if (anim->getUseBaseKeyFrame()) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + // char* baseAnimationName (including terminator) + size += anim->getBaseKeyFrameAnimationName().length() + 1; + // float baseKeyFrameTime + size += sizeof(float); + + writeChunkHeader(M_ANIMATION_BASEINFO, size); + + // char* baseAnimationName (blank for self) + writeString(anim->getBaseKeyFrameAnimationName()); + + // float baseKeyFrameTime + float t = (float)anim->getBaseKeyFrameTime(); + writeFloats(&t, 1); + } + + // tracks + Animation::VertexTrackIterator trackIt = anim->getVertexTrackIterator(); + while (trackIt.hasMoreElements()) + { + VertexAnimationTrack* vt = trackIt.getNext(); + writeAnimationTrack(vt); + } + popInnerChunk(mStream); + + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::writeAnimationTrack(const VertexAnimationTrack* track) + { + writeChunkHeader(M_ANIMATION_TRACK, calcAnimationTrackSize(track)); + // unsigned short type // 1 == morph, 2 == pose + uint16 animType = (uint16)track->getAnimationType(); + writeShorts(&animType, 1); + // unsigned short target + uint16 target = track->getHandle(); + writeShorts(&target, 1); + pushInnerChunk(mStream); + { + if (track->getAnimationType() == VAT_MORPH) + { + for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) + { + VertexMorphKeyFrame* kf = track->getVertexMorphKeyFrame(i); + writeMorphKeyframe(kf, track->getAssociatedVertexData()->vertexCount); + } + } + else // VAT_POSE + { + for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) + { + VertexPoseKeyFrame* kf = track->getVertexPoseKeyFrame(i); + writePoseKeyframe(kf); + } + } + } + popInnerChunk(mStream); + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::writeMorphKeyframe(const VertexMorphKeyFrame* kf, size_t vertexCount) + { + writeChunkHeader(M_ANIMATION_MORPH_KEYFRAME, calcMorphKeyframeSize(kf, vertexCount)); + // float time + float timePos = kf->getTime(); + writeFloats(&timePos, 1); + // bool includeNormals + bool includeNormals = kf->getVertexBuffer()->getVertexSize() > (sizeof(float) * 3); + writeBools(&includeNormals, 1); + // float x,y,z // repeat by number of vertices in original geometry + float* pSrc = static_cast( + kf->getVertexBuffer()->lock(HardwareBuffer::HBL_READ_ONLY)); + writeFloats(pSrc, vertexCount * (includeNormals ? 6 : 3)); + kf->getVertexBuffer()->unlock(); + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::writePoseKeyframe(const VertexPoseKeyFrame* kf) + { + writeChunkHeader(M_ANIMATION_POSE_KEYFRAME, calcPoseKeyframeSize(kf)); + // float time + float timePos = kf->getTime(); + writeFloats(&timePos, 1); + pushInnerChunk(mStream); + // pose references + VertexPoseKeyFrame::ConstPoseRefIterator poseRefIt = + kf->getPoseReferenceIterator(); + while (poseRefIt.hasMoreElements()) + { + writePoseKeyframePoseRef(poseRefIt.getNext()); + } + popInnerChunk(mStream); + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::writePoseKeyframePoseRef( + const VertexPoseKeyFrame::PoseRef& poseRef) + { + writeChunkHeader(M_ANIMATION_POSE_REF, calcPoseKeyframePoseRefSize()); + // unsigned short poseIndex + writeShorts(&(poseRef.poseIndex), 1); + // float influence + writeFloats(&(poseRef.influence), 1); + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::readPoses(DataStreamPtr& stream, Mesh* pMesh) + { + // Find all substreams + if (!stream->eof()) + { + pushInnerChunk(stream); + unsigned short streamID = readChunk(stream); + while(!stream->eof() && + (streamID == M_POSE)) + { + switch(streamID) + { + case M_POSE: + readPose(stream, pMesh); + break; + + } + + if (!stream->eof()) + { + streamID = readChunk(stream); + } + + } + if (!stream->eof()) + { + // Backpedal back to start of stream + backpedalChunkHeader(stream); + } + popInnerChunk(stream); + } + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::readPose(DataStreamPtr& stream, Mesh* pMesh) + { + // char* name (may be blank) + String name = readString(stream); + // unsigned short target + unsigned short target; + readShorts(stream, &target, 1); + + // bool includesNormals + bool includesNormals; + readBools(stream, &includesNormals, 1); + + Pose* pose = pMesh->createPose(target, name); + + // Find all substreams + if (!stream->eof()) + { + pushInnerChunk(stream); + unsigned short streamID = readChunk(stream); + while(!stream->eof() && + (streamID == M_POSE_VERTEX)) + { + switch(streamID) + { + case M_POSE_VERTEX: + // create vertex offset + uint32 vertIndex; + Vector3 offset, normal; + // unsigned long vertexIndex + readInts(stream, &vertIndex, 1); + // float xoffset, yoffset, zoffset + readFloats(stream, offset.ptr(), 3); + + if (includesNormals) + { + readFloats(stream, normal.ptr(), 3); + pose->addVertex(vertIndex, offset, normal); + } + else + { + pose->addVertex(vertIndex, offset); + } + + + break; + + } + + if (!stream->eof()) + { + streamID = readChunk(stream); + } + + } + if (!stream->eof()) + { + // Backpedal back to start of stream + backpedalChunkHeader(stream); + } + popInnerChunk(stream); + } + + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::readAnimations(DataStreamPtr& stream, Mesh* pMesh) + { + // Find all substreams + if (!stream->eof()) + { + pushInnerChunk(stream); + unsigned short streamID = readChunk(stream); + while(!stream->eof() && + (streamID == M_ANIMATION)) + { + switch(streamID) + { + case M_ANIMATION: + readAnimation(stream, pMesh); + break; + + } + + if (!stream->eof()) + { + streamID = readChunk(stream); + } + + } + if (!stream->eof()) + { + // Backpedal back to start of stream + backpedalChunkHeader(stream); + } + popInnerChunk(stream); + } + + + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::readAnimation(DataStreamPtr& stream, Mesh* pMesh) + { + + // char* name + String name = readString(stream); + // float length + float len; + readFloats(stream, &len, 1); + + Animation* anim = pMesh->createAnimation(name, len); + + // tracks + if (!stream->eof()) + { + pushInnerChunk(stream); + unsigned short streamID = readChunk(stream); + + // Optional base info is possible + if (streamID == M_ANIMATION_BASEINFO) + { + // char baseAnimationName + String baseAnimName = readString(stream); + // float baseKeyFrameTime + float baseKeyTime; + readFloats(stream, &baseKeyTime, 1); + + anim->setUseBaseKeyFrame(true, baseKeyTime, baseAnimName); + + if (!stream->eof()) + { + // Get next stream + streamID = readChunk(stream); + } + } + + while(!stream->eof() && + streamID == M_ANIMATION_TRACK) + { + switch(streamID) + { + case M_ANIMATION_TRACK: + readAnimationTrack(stream, anim, pMesh); + break; + }; + if (!stream->eof()) + { + streamID = readChunk(stream); + } + + } + if (!stream->eof()) + { + // Backpedal back to start of stream + backpedalChunkHeader(stream); + } + popInnerChunk(stream); + } + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::readAnimationTrack(DataStreamPtr& stream, + Animation* anim, Mesh* pMesh) + { + // ushort type + uint16 inAnimType; + readShorts(stream, &inAnimType, 1); + VertexAnimationType animType = (VertexAnimationType)inAnimType; + + // unsigned short target + uint16 target; + readShorts(stream, &target, 1); + + VertexAnimationTrack* track = anim->createVertexTrack(target, + pMesh->getVertexDataByTrackHandle(target), animType); + + // keyframes + if (!stream->eof()) + { + pushInnerChunk(stream); + unsigned short streamID = readChunk(stream); + while(!stream->eof() && + (streamID == M_ANIMATION_MORPH_KEYFRAME || + streamID == M_ANIMATION_POSE_KEYFRAME)) + { + switch(streamID) + { + case M_ANIMATION_MORPH_KEYFRAME: + readMorphKeyFrame(stream, track); + break; + case M_ANIMATION_POSE_KEYFRAME: + readPoseKeyFrame(stream, track); + break; + }; + if (!stream->eof()) + { + streamID = readChunk(stream); + } + + } + if (!stream->eof()) + { + // Backpedal back to start of stream + backpedalChunkHeader(stream); + } + popInnerChunk(stream); + } + + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::readMorphKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track) + { + // float time + float timePos; + readFloats(stream, &timePos, 1); + + // bool includesNormals + bool includesNormals; + readBools(stream, &includesNormals, 1); + + VertexMorphKeyFrame* kf = track->createVertexMorphKeyFrame(timePos); + + // Create buffer, allow read and use shadow buffer + size_t vertexCount = track->getAssociatedVertexData()->vertexCount; + size_t vertexSize = sizeof(float) * (includesNormals ? 6 : 3); + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + vertexSize, vertexCount, + HardwareBuffer::HBU_STATIC, true); + // float x,y,z // repeat by number of vertices in original geometry + float* pDst = static_cast( + vbuf->lock(HardwareBuffer::HBL_DISCARD)); + readFloats(stream, pDst, vertexCount * (includesNormals ? 6 : 3)); + vbuf->unlock(); + kf->setVertexBuffer(vbuf); + + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::readPoseKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track) + { + // float time + float timePos; + readFloats(stream, &timePos, 1); + + // Create keyframe + VertexPoseKeyFrame* kf = track->createVertexPoseKeyFrame(timePos); + + if (!stream->eof()) + { + pushInnerChunk(stream); + unsigned short streamID = readChunk(stream); + while(!stream->eof() && + streamID == M_ANIMATION_POSE_REF) + { + switch(streamID) + { + case M_ANIMATION_POSE_REF: + uint16 poseIndex; + float influence; + // unsigned short poseIndex + readShorts(stream, &poseIndex, 1); + // float influence + readFloats(stream, &influence, 1); + + kf->addPoseReference(poseIndex, influence); + + break; + }; + if (!stream->eof()) + { + streamID = readChunk(stream); + } + } + if (!stream->eof()) + { + // Backpedal back to start of stream + backpedalChunkHeader(stream); + } + popInnerChunk(stream); + } + + } + //--------------------------------------------------------------------- + void MeshSerializerImpl::readExtremes(DataStreamPtr& stream, Mesh *pMesh) + { + unsigned short idx; + readShorts(stream, &idx, 1); + + SubMesh *sm = pMesh->getSubMesh (idx); + + int n_floats = (mCurrentstreamLen - MSTREAM_OVERHEAD_SIZE - + sizeof (unsigned short)) / sizeof (float); + + assert ((n_floats % 3) == 0); + + float *vert = OGRE_ALLOC_T(float, n_floats, MEMCATEGORY_GEOMETRY); + readFloats(stream, vert, n_floats); + + for (int i = 0; i < n_floats; i += 3) + sm->extremityPoints.push_back(Vector3(vert [i], vert [i + 1], vert [i + 2])); + + OGRE_FREE(vert, MEMCATEGORY_GEOMETRY); + } + + void MeshSerializerImpl::enableValidation() + { +#if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE + mReportChunkErrors = true; +#endif + } + + + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + MeshSerializerImpl_v1_8::MeshSerializerImpl_v1_8() + { + // Version number + mVersion = "[MeshSerializer_v1.8]"; + } + //--------------------------------------------------------------------- + MeshSerializerImpl_v1_8::~MeshSerializerImpl_v1_8() + { + } + //-------------------------------------------------------------------- + bool MeshSerializerImpl_v1_8::isLodMixed(const Mesh* pMesh) + { + if(!pMesh->hasManualLodLevel()) { + return false; + } + + unsigned short numLods = pMesh->getNumLodLevels(); + for (unsigned short i = 1; i < numLods; ++i) + { + if(!pMesh->_isManualLodLevel(i)){ + return true; + } + } + + return false; + } + size_t MeshSerializerImpl_v1_8::calcLodLevelSize(const Mesh* pMesh) + { + if (isLodMixed(pMesh)) { + return 0; // Supported in v1_9+ + } + exportedLodCount = pMesh->getNumLodLevels(); + size_t size = MSTREAM_OVERHEAD_SIZE; // Header + size += calcStringSize(pMesh->getLodStrategy()->getName()); // string strategyName; + size += sizeof(unsigned short); // unsigned short numLevels; + size += sizeof(bool); // bool manual; <== this is removed in v1_9 + + // Loop from LOD 1 (not 0, this is full detail) + for (ushort i = 1; i < exportedLodCount; ++i) + { + const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; + if (pMesh->_isManualLodLevel(i)) + { + size += calcLodUsageManualSize(usage); + } + else + { + size += calcLodUsageGeneratedSize(pMesh, usage, i); + } + } + return size; + } + size_t MeshSerializerImpl_v1_8::calcLodUsageManualSize(const MeshLodUsage& usage) + { + // Header + size_t size = MSTREAM_OVERHEAD_SIZE; // M_MESH_LOD_USAGE <== this is removed in v1_9 + + // float fromDepthSquared; + size += sizeof(float); + + // Manual part size + size += MSTREAM_OVERHEAD_SIZE; // M_MESH_LOD_MANUAL + // String manualMeshName; + size += calcStringSize(usage.manualName); + return size; + } + + size_t MeshSerializerImpl_v1_8::calcLodUsageGeneratedSize(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum) + { + // Usage Header + size_t size = MSTREAM_OVERHEAD_SIZE; + unsigned short subidx; + + // float fromDepthSquared; + size += sizeof(float); + + // Calc generated SubMesh sections size + for (subidx = 0; subidx < pMesh->getNumSubMeshes(); ++subidx) + { + SubMesh* submesh = pMesh->getSubMesh(subidx); + size += calcLodUsageGeneratedSubmeshSize(submesh, lodNum); + } + return size; + } + size_t MeshSerializerImpl_v1_8::calcLodUsageGeneratedSubmeshSize(const SubMesh* submesh, unsigned short lodNum) + { + const IndexData* indexData = submesh->mLodFaceList[lodNum - 1]; + const HardwareIndexBufferSharedPtr& ibuf = indexData->indexBuffer; + + size_t size = MSTREAM_OVERHEAD_SIZE; // M_MESH_LOD_GENERATED + size += sizeof(unsigned int); // unsigned int indexData->indexCount; + size += sizeof(bool); // bool indexes32Bit + size += ibuf.isNull() ? 0 : ibuf->getIndexSize() * indexData->indexCount; // faces + return size; + } +#if !OGRE_NO_MESHLOD + //-------------------------------------------------------------------- + void MeshSerializerImpl_v1_8::writeLodLevel(const Mesh* pMesh) + { + if (isLodMixed(pMesh)) { + LogManager::getSingleton().logMessage("MeshSerializer_v1_8 older mesh format is incompatible with mixed manual/generated Lod levels. Lod levels will not be exported."); + } else { + + exportedLodCount = pMesh->getNumLodLevels(); + bool manual = pMesh->hasManualLodLevel(); + + writeChunkHeader(M_MESH_LOD_LEVEL, calcLodLevelSize(pMesh)); + + // Details + // Get backward compatible strategy name + String strategyName = pMesh->getLodStrategy()->getName(); + if (strategyName == "distance_box" || strategyName == "distance_sphere") { + strategyName = "Distance"; + } else if (strategyName == "pixel_count" || strategyName == "screen_ratio_pixel_count") { + strategyName = "PixelCount"; + } + // string strategyName; + writeString(strategyName); + // unsigned short numLevels; + writeShorts(&exportedLodCount, 1); + // bool manual; (true for manual alternate meshes, false for generated) + writeBools(&manual, 1); + + pushInnerChunk(mStream); + // Loop from LOD 1 (not 0, this is full detail) + for (ushort i = 1; i < exportedLodCount; ++i) + { + const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; + assert(pMesh->_isManualLodLevel(i) == manual); + if (manual) + { + writeLodUsageManual(usage); + } + else + { + writeLodUsageGenerated(pMesh, usage, i); + } + } + popInnerChunk(mStream); + } + } + //--------------------------------------------------------------------- + /*void MeshSerializerImpl_v1_8::writeLodUsageGenerated( const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum ) + { + writeChunkHeader(M_MESH_LOD_USAGE, calcLodUsageGeneratedSize(pMesh, usage, lodNum)); + writeFloats(&(usage.userValue), 1); + pushInnerChunk(mStream); + // Now write sections + for (unsigned short subidx = 0; subidx < pMesh->getNumSubMeshes(); ++subidx) + { + SubMesh* sm = pMesh->getSubMesh(subidx); + const IndexData* indexData = sm->mLodFaceList[lodNum-1]; + + // Lock index buffer to write + HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; + + bool idx32 = (!ibuf.isNull() && ibuf->getType() == HardwareIndexBuffer::IT_32BIT); + + writeChunkHeader(M_MESH_LOD_GENERATED, calcLodUsageGeneratedSubmeshSize(sm, lodNum)); + unsigned int idxCount = static_cast(indexData->indexCount); + writeInts(&idxCount, 1); + writeBools(&idx32, 1); + + if (idxCount > 0) + { + if (idx32) + { + unsigned int* pIdx = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + writeInts(pIdx + indexData->indexStart, indexData->indexCount); + ibuf->unlock(); + } + else + { + unsigned short* pIdx = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + writeShorts(pIdx + indexData->indexStart, indexData->indexCount); + ibuf->unlock(); + } + } + } + popInnerChunk(mStream); + }*/ + + void MeshSerializerImpl_v1_8::writeLodUsageGenerated(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum) + { + writeChunkHeader(M_MESH_LOD_USAGE, calcLodUsageGeneratedSize(pMesh, usage, lodNum)); + float userValue = static_cast(usage.userValue); + writeFloats(&userValue, 1); + pushInnerChunk(mStream); + for (ushort i = 0; i < pMesh->getNumSubMeshes(); i++) + { + SubMesh* submesh = pMesh->getSubMesh(i); + writeLodUsageGeneratedSubmesh(submesh, lodNum); + } + popInnerChunk(mStream); + } + void MeshSerializerImpl_v1_8::writeLodUsageGeneratedSubmesh(const SubMesh* submesh, unsigned short lodNum) + { + const IndexData* indexData = submesh->mLodFaceList[lodNum - 1]; + HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; + assert(!ibuf.isNull()); + + writeChunkHeader(M_MESH_LOD_GENERATED, calcLodUsageGeneratedSubmeshSize(submesh, lodNum)); + unsigned int indexCount = static_cast(indexData->indexCount); + writeInts(&indexCount, 1); + bool is32BitIndices = (ibuf->getType() == HardwareIndexBuffer::IT_32BIT); + writeBools(&is32BitIndices, 1); + + if (is32BitIndices) + { + unsigned int* pIdx = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + writeInts(pIdx + indexData->indexStart, indexCount); + ibuf->unlock(); + } + else + { + unsigned short* pIdx = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + writeShorts(pIdx + indexData->indexStart, indexCount); + ibuf->unlock(); + } + } + //--------------------------------------------------------------------- + void MeshSerializerImpl_v1_8::writeLodUsageManual(const MeshLodUsage& usage) + { + writeChunkHeader(M_MESH_LOD_USAGE, calcLodUsageManualSize(usage)); + writeFloats(&(usage.userValue), 1); + pushInnerChunk(mStream); + writeChunkHeader(M_MESH_LOD_MANUAL, MSTREAM_OVERHEAD_SIZE + calcStringSize(usage.manualName)); + writeString(usage.manualName); + popInnerChunk(mStream); + } + //--------------------------------------------------------------------- + + void MeshSerializerImpl_v1_8::readMeshLodUsageGenerated( DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage ) + { + usage.manualName = ""; + usage.manualMesh.setNull(); + pushInnerChunk(stream); + { + // Get one set of detail per SubMesh + unsigned short numSubs, i; + numSubs = pMesh->getNumSubMeshes(); + for (i = 0; i < numSubs; ++i) + { + unsigned long streamID = readChunk(stream); + if (streamID != M_MESH_LOD_GENERATED) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Missing M_MESH_LOD_GENERATED stream in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodUsageGenerated"); + } + + SubMesh* sm = pMesh->getSubMesh(i); + IndexData* indexData = OGRE_NEW IndexData(); + sm->mLodFaceList[lodNum - 1] = indexData; + // unsigned int numIndexes + unsigned int numIndexes; + readInts(stream, &numIndexes, 1); + indexData->indexCount = static_cast(numIndexes); + + // bool indexes32Bit + bool idx32Bit; + readBools(stream, &idx32Bit, 1); + // unsigned short*/int* faceIndexes; ((v1, v2, v3) * numFaces) + if (idx32Bit) + { + indexData->indexBuffer = HardwareBufferManager::getSingleton(). + createIndexBuffer(HardwareIndexBuffer::IT_32BIT, indexData->indexCount, + pMesh->mIndexBufferUsage, pMesh->mIndexBufferShadowBuffer); + unsigned int* pIdx = static_cast( + indexData->indexBuffer->lock( + 0, + indexData->indexBuffer->getSizeInBytes(), + HardwareBuffer::HBL_DISCARD)); + + readInts(stream, pIdx, indexData->indexCount); + indexData->indexBuffer->unlock(); + + } + else + { + indexData->indexBuffer = HardwareBufferManager::getSingleton(). + createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, + pMesh->mIndexBufferUsage, pMesh->mIndexBufferShadowBuffer); + unsigned short* pIdx = static_cast( + indexData->indexBuffer->lock( + 0, + indexData->indexBuffer->getSizeInBytes(), + HardwareBuffer::HBL_DISCARD)); + readShorts(stream, pIdx, indexData->indexCount); + indexData->indexBuffer->unlock(); + } + } + } + popInnerChunk(stream); + } + //--------------------------------------------------------------------- + void MeshSerializerImpl_v1_8::readMeshLodUsageManual(DataStreamPtr& stream, + Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage) + { + pushInnerChunk(stream); + unsigned long streamID; + // Read detail stream + streamID = readChunk(stream); + if (streamID != M_MESH_LOD_MANUAL) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Missing M_MESH_LOD_MANUAL stream in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodUsageManual"); + } + + usage.manualName = readString(stream); + usage.manualMesh.setNull(); // will trigger load later + popInnerChunk(stream); + } + +#endif + void MeshSerializerImpl_v1_8::readMeshLodLevel(DataStreamPtr& stream, Mesh* pMesh) + { +#if OGRE_NO_MESHLOD + + /* + //Since the chunk sizes in old versions are messed up, we can't use this clean solution. + // We need to walk through the data to not rely on the chunk size! + stream->skip(mCurrentstreamLen); + + // Since we got here, we have already read the chunk header. + backpedalChunkHeader(stream); + */ + uint16 numSubs = pMesh->getNumSubMeshes(); + String strategyName = readString(stream); + uint16 numLods; + readShorts(stream, &numLods, 1); + bool manual; + readBools(stream, &manual, 1); // missing in v1_9 + pushInnerChunk(stream); + for (uint16 i = 1; i < numLods; ++i) + { + uint16 streamID = readChunk(stream); + if (streamID != M_MESH_LOD_USAGE) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Missing M_MESH_LOD_USAGE stream in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodInfo"); + } + float usageValue; + readFloats(stream, &usageValue, 1); + + if (manual) + { + // Read detail stream + uint16 streamID = readChunk(stream); + if (streamID != M_MESH_LOD_MANUAL) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Missing M_MESH_LOD_MANUAL stream in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodUsageManual"); + } + + String manualName = readString(stream); + } + else + { + pushInnerChunk(stream); + for (uint16 n = 0; n < numSubs; ++n) + { + unsigned long streamID = readChunk(stream); + if (streamID != M_MESH_LOD_GENERATED) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Missing M_MESH_LOD_GENERATED stream in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodUsageGenerated"); + } + + unsigned int numIndexes; + readInts(stream, &numIndexes, 1); + + bool idx32Bit; + readBools(stream, &idx32Bit, 1); + + size_t buffSize = numIndexes * (idx32Bit ? 4 : 2); + stream->skip(buffSize); + } + popInnerChunk(stream); + } + } + popInnerChunk(stream); +#else + unsigned short streamID, i; + + // Read the strategy to be used for this mesh + String strategyName = readString(stream); + LodStrategy *strategy = LodStrategyManager::getSingleton().getStrategy(strategyName); + pMesh->setLodStrategy(strategy); + + // unsigned short numLevels; + readShorts(stream, &(pMesh->mNumLods), 1); + // bool manual; (true for manual alternate meshes, false for generated) + readBools(stream, &(pMesh->mHasManualLodLevel), 1); + + // Preallocate submesh lod face data if not manual + if (!pMesh->hasManualLodLevel()) + { + unsigned short numsubs = pMesh->getNumSubMeshes(); + for (i = 0; i < numsubs; ++i) + { + SubMesh* sm = pMesh->getSubMesh(i); + assert(sm->mLodFaceList.empty()); + sm->mLodFaceList.resize(pMesh->mNumLods - 1); + } + } + + pushInnerChunk(stream); + // Loop from 1 rather than 0 (full detail index is not in file) + for (i = 1; i < pMesh->mNumLods; ++i) + { + streamID = readChunk(stream); + if (streamID != M_MESH_LOD_USAGE) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Missing M_MESH_LOD_USAGE stream in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodInfo"); + } + // Read depth + MeshLodUsage usage; + readFloats(stream, &(usage.userValue), 1); + + // Set default values + usage.manualName = ""; + usage.manualMesh.setNull(); + usage.edgeData = NULL; + + if (pMesh->hasManualLodLevel()) + { + readMeshLodUsageManual(stream, pMesh, i, usage); + } + else //(!pMesh->hasManualLodLevel()) + { + readMeshLodUsageGenerated(stream, pMesh, i, usage); + } + usage.edgeData = NULL; + + // Save usage + pMesh->mMeshLodUsageList.push_back(usage); + } + popInnerChunk(stream); +#endif + } + + void MeshSerializerImpl_v1_8::enableValidation() + { +#if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE + mReportChunkErrors = false; +#endif + } + + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + MeshSerializerImpl_v1_41::MeshSerializerImpl_v1_41() + { + // Version number + mVersion = "[MeshSerializer_v1.41]"; + } + //--------------------------------------------------------------------- + MeshSerializerImpl_v1_41::~MeshSerializerImpl_v1_41() + { + } + //--------------------------------------------------------------------- + void MeshSerializerImpl_v1_41::writeMorphKeyframe(const VertexMorphKeyFrame* kf, size_t vertexCount) + { + writeChunkHeader(M_ANIMATION_MORPH_KEYFRAME, calcMorphKeyframeSize(kf, vertexCount)); + // float time + float timePos = kf->getTime(); + writeFloats(&timePos, 1); + // float x,y,z // repeat by number of vertices in original geometry + float* pSrc = static_cast( + kf->getVertexBuffer()->lock(HardwareBuffer::HBL_READ_ONLY)); + writeFloats(pSrc, vertexCount * 3); + kf->getVertexBuffer()->unlock(); + } + //--------------------------------------------------------------------- + void MeshSerializerImpl_v1_41::readMorphKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track) + { + // float time + float timePos; + readFloats(stream, &timePos, 1); + + VertexMorphKeyFrame* kf = track->createVertexMorphKeyFrame(timePos); + + // Create buffer, allow read and use shadow buffer + size_t vertexCount = track->getAssociatedVertexData()->vertexCount; + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + VertexElement::getTypeSize(VET_FLOAT3), vertexCount, + HardwareBuffer::HBU_STATIC, true); + // float x,y,z // repeat by number of vertices in original geometry + float* pDst = static_cast( + vbuf->lock(HardwareBuffer::HBL_DISCARD)); + readFloats(stream, pDst, vertexCount * 3); + vbuf->unlock(); + kf->setVertexBuffer(vbuf); + } + //--------------------------------------------------------------------- + void MeshSerializerImpl_v1_41::writePose(const Pose* pose) + { + writeChunkHeader(M_POSE, calcPoseSize(pose)); + + // char* name (may be blank) + writeString(pose->getName()); + + // unsigned short target + ushort val = pose->getTarget(); + writeShorts(&val, 1); + pushInnerChunk(mStream); + size_t vertexSize = calcPoseVertexSize(); + Pose::ConstVertexOffsetIterator vit = pose->getVertexOffsetIterator(); + while (vit.hasMoreElements()) + { + uint32 vertexIndex = (uint32)vit.peekNextKey(); + Vector3 offset = vit.getNext(); + writeChunkHeader(M_POSE_VERTEX, vertexSize); + // unsigned long vertexIndex + writeInts(&vertexIndex, 1); + // float xoffset, yoffset, zoffset + writeFloats(offset.ptr(), 3); + } + popInnerChunk(mStream); + } + //--------------------------------------------------------------------- + void MeshSerializerImpl_v1_41::readPose(DataStreamPtr& stream, Mesh* pMesh) + { + // char* name (may be blank) + String name = readString(stream); + // unsigned short target + unsigned short target; + readShorts(stream, &target, 1); + + Pose* pose = pMesh->createPose(target, name); + + // Find all substreams + if (!stream->eof()) + { + pushInnerChunk(stream); + unsigned short streamID = readChunk(stream); + while(!stream->eof() && + (streamID == M_POSE_VERTEX)) + { + switch(streamID) + { + case M_POSE_VERTEX: + // create vertex offset + uint32 vertIndex; + Vector3 offset; + // unsigned long vertexIndex + readInts(stream, &vertIndex, 1); + // float xoffset, yoffset, zoffset + readFloats(stream, offset.ptr(), 3); + + pose->addVertex(vertIndex, offset); + break; + + } + + if (!stream->eof()) + { + streamID = readChunk(stream); + } + + } + if (!stream->eof()) + { + // Backpedal back to start of stream + backpedalChunkHeader(stream); } - popInnerChunk(stream); + popInnerChunk(stream); } - - pMesh->mEdgeListsBuilt = true; - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::readEdgeListLodInfo(DataStreamPtr& stream, - EdgeData* edgeData) + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl_v1_41::calcPoseSize(const Pose* pose) { -#if OGRE_NO_MESHLOD - if (edgeData == NULL) { // skip it! - bool isClosed; - readBools(stream, &isClosed, 1); - // unsigned long numTriangles - uint32 numTriangles; - readInts(stream, &numTriangles, 1); - // unsigned long numEdgeGroups - uint32 numEdgeGroups; - readInts(stream, &numEdgeGroups, 1); - stream->skip(numTriangles * (8 * sizeof(uint32) + 4 * sizeof(float))); - pushInnerChunk(stream); - for (uint32 eg = 0; eg < numEdgeGroups; ++eg) - { - unsigned short streamID = readChunk(stream); - if (streamID != M_EDGE_GROUP) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Missing M_EDGE_GROUP stream", - "MeshSerializerImpl::readEdgeListLodInfo"); - } - uint32 tmp[3]; - // unsigned long vertexSet - readInts(stream, &tmp[0], 3); - uint32 numEdges; - readInts(stream, &numEdges, 1); - - stream->skip(numEdges * (6 * sizeof(uint32) + sizeof(bool))); - } - popInnerChunk(stream); - return; - } -#endif - // bool isClosed - readBools(stream, &edgeData->isClosed, 1); - // unsigned long numTriangles - uint32 numTriangles; - readInts(stream, &numTriangles, 1); - // Allocate correct amount of memory - edgeData->triangles.resize(numTriangles); - edgeData->triangleFaceNormals.resize(numTriangles); - edgeData->triangleLightFacings.resize(numTriangles); - // unsigned long numEdgeGroups - uint32 numEdgeGroups; - readInts(stream, &numEdgeGroups, 1); - // Allocate correct amount of memory - edgeData->edgeGroups.resize(numEdgeGroups); - // Triangle* triangleList - uint32 tmp[3]; - for (size_t t = 0; t < numTriangles; ++t) - { - EdgeData::Triangle& tri = edgeData->triangles[t]; - // unsigned long indexSet - readInts(stream, tmp, 1); - tri.indexSet = tmp[0]; - // unsigned long vertexSet - readInts(stream, tmp, 1); - tri.vertexSet = tmp[0]; - // unsigned long vertIndex[3] - readInts(stream, tmp, 3); - - tri.vertIndex[0] = tmp[0]; - tri.vertIndex[1] = tmp[1]; - tri.vertIndex[2] = tmp[2]; - // unsigned long sharedVertIndex[3] - readInts(stream, tmp, 3); - tri.sharedVertIndex[0] = tmp[0]; - tri.sharedVertIndex[1] = tmp[1]; - tri.sharedVertIndex[2] = tmp[2]; - // float normal[4] - readFloats(stream, &(edgeData->triangleFaceNormals[t].x), 4); - - } - pushInnerChunk(stream); - for (uint32 eg = 0; eg < numEdgeGroups; ++eg) - { - unsigned short streamID = readChunk(stream); - if (streamID != M_EDGE_GROUP) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Missing M_EDGE_GROUP stream", - "MeshSerializerImpl::readEdgeListLodInfo"); - } - EdgeData::EdgeGroup& edgeGroup = edgeData->edgeGroups[eg]; - - // unsigned long vertexSet - readInts(stream, tmp, 1); - edgeGroup.vertexSet = tmp[0]; - // unsigned long triStart - readInts(stream, tmp, 1); - edgeGroup.triStart = tmp[0]; - // unsigned long triCount - readInts(stream, tmp, 1); - edgeGroup.triCount = tmp[0]; - // unsigned long numEdges - uint32 numEdges; - readInts(stream, &numEdges, 1); - edgeGroup.edges.resize(numEdges); - // Edge* edgeList - for (uint32 e = 0; e < numEdges; ++e) - { - EdgeData::Edge& edge = edgeGroup.edges[e]; - // unsigned long triIndex[2] - readInts(stream, tmp, 2); - edge.triIndex[0] = tmp[0]; - edge.triIndex[1] = tmp[1]; - // unsigned long vertIndex[2] - readInts(stream, tmp, 2); - edge.vertIndex[0] = tmp[0]; - edge.vertIndex[1] = tmp[1]; - // unsigned long sharedVertIndex[2] - readInts(stream, tmp, 2); - edge.sharedVertIndex[0] = tmp[0]; - edge.sharedVertIndex[1] = tmp[1]; - // bool degenerate - readBools(stream, &(edge.degenerate), 1); - } - } - popInnerChunk(stream); - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcAnimationsSize(const Mesh* pMesh) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - - for (unsigned short a = 0; a < pMesh->getNumAnimations(); ++a) - { - Animation* anim = pMesh->getAnimation(a); - size += calcAnimationSize(anim); - } - return size; - - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcAnimationSize(const Animation* anim) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - // char* name - size += anim->getName().length() + 1; - - // float length - size += sizeof(float); - - Animation::VertexTrackIterator trackIt = anim->getVertexTrackIterator(); - while (trackIt.hasMoreElements()) - { - VertexAnimationTrack* vt = trackIt.getNext(); - size += calcAnimationTrackSize(vt); - } - - return size; - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcAnimationTrackSize(const VertexAnimationTrack* track) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - // uint16 type - size += sizeof(uint16); - // unsigned short target // 0 for shared geometry, - size += sizeof(unsigned short); - - if (track->getAnimationType() == VAT_MORPH) - { - for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) - { - VertexMorphKeyFrame* kf = track->getVertexMorphKeyFrame(i); - size += calcMorphKeyframeSize(kf, track->getAssociatedVertexData()->vertexCount); - } - } - else - { - for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) - { - VertexPoseKeyFrame* kf = track->getVertexPoseKeyFrame(i); - size += calcPoseKeyframeSize(kf); - } - } - return size; - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcMorphKeyframeSize(const VertexMorphKeyFrame* kf, - size_t vertexCount) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - // float time - size += sizeof(float); - // float x,y,z[,nx,ny,nz] - bool includesNormals = kf->getVertexBuffer()->getVertexSize() > (sizeof(float) * 3); - size += sizeof(float) * (includesNormals ? 6 : 3) * vertexCount; - - return size; - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcPoseKeyframeSize(const VertexPoseKeyFrame* kf) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - - // float time - size += sizeof(float); - - size += calcPoseKeyframePoseRefSize() * kf->getPoseReferences().size(); - - return size; - - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcPoseKeyframePoseRefSize(void) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - // unsigned short poseIndex - size += sizeof(uint16); - // float influence - size += sizeof(float); - - return size; - - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcPosesSize(const Mesh* pMesh) - { - size_t size = 0; - Mesh::ConstPoseIterator poseIterator = pMesh->getPoseIterator(); - if (poseIterator.hasMoreElements()) - { - size += MSTREAM_OVERHEAD_SIZE; - while (poseIterator.hasMoreElements()) - { - size += calcPoseSize(poseIterator.getNext()); - } - } - return size; - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcPoseSize(const Pose* pose) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - - // char* name (may be blank) - size += pose->getName().length() + 1; - // unsigned short target - size += sizeof(uint16); - // bool includesNormals - size += sizeof(bool); - - // vertex offsets - size += pose->getVertexOffsets().size() * calcPoseVertexSize(pose); - - return size; - - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl::calcPoseVertexSize(const Pose* pose) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - // unsigned long vertexIndex - size += sizeof(uint32); - // float xoffset, yoffset, zoffset - size += sizeof(float) * 3; - // optional normals - if (!pose->getNormals().empty()) - size += sizeof(float) * 3; - - return size; - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::writePoses(const Mesh* pMesh) - { - Mesh::ConstPoseIterator poseIterator = pMesh->getPoseIterator(); - if (poseIterator.hasMoreElements()) - { - writeChunkHeader(M_POSES, calcPosesSize(pMesh)); - pushInnerChunk(mStream); - while (poseIterator.hasMoreElements()) - { - writePose(poseIterator.getNext()); - } - popInnerChunk(mStream); - } - - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::writePose(const Pose* pose) - { - writeChunkHeader(M_POSE, calcPoseSize(pose)); - - // char* name (may be blank) - writeString(pose->getName()); - - // unsigned short target - ushort val = pose->getTarget(); - writeShorts(&val, 1); - - // bool includesNormals - bool includesNormals = !pose->getNormals().empty(); - writeBools(&includesNormals, 1); - pushInnerChunk(mStream); - { - size_t vertexSize = calcPoseVertexSize(pose); - Pose::ConstVertexOffsetIterator vit = pose->getVertexOffsetIterator(); - Pose::ConstNormalsIterator nit = pose->getNormalsIterator(); - while (vit.hasMoreElements()) - { - uint32 vertexIndex = (uint32)vit.peekNextKey(); - Vector3 offset = vit.getNext(); - writeChunkHeader(M_POSE_VERTEX, vertexSize); - // unsigned long vertexIndex - writeInts(&vertexIndex, 1); - // float xoffset, yoffset, zoffset - writeFloats(offset.ptr(), 3); - if (includesNormals) - { - Vector3 normal = nit.getNext(); - // float xnormal, ynormal, znormal - writeFloats(normal.ptr(), 3); - } - } - } - popInnerChunk(mStream); - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::writeAnimations(const Mesh* pMesh) - { - writeChunkHeader(M_ANIMATIONS, calcAnimationsSize(pMesh)); - pushInnerChunk(mStream); - for (unsigned short a = 0; a < pMesh->getNumAnimations(); ++a) - { - Animation* anim = pMesh->getAnimation(a); - LogManager::getSingleton().logMessage("Exporting animation " + anim->getName()); - writeAnimation(anim); - LogManager::getSingleton().logMessage("Animation exported."); - } - popInnerChunk(mStream); - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::writeAnimation(const Animation* anim) - { - writeChunkHeader(M_ANIMATION, calcAnimationSize(anim)); - // char* name - writeString(anim->getName()); - // float length - float len = anim->getLength(); - writeFloats(&len, 1); - pushInnerChunk(mStream); - if (anim->getUseBaseKeyFrame()) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - // char* baseAnimationName (including terminator) - size += anim->getBaseKeyFrameAnimationName().length() + 1; - // float baseKeyFrameTime - size += sizeof(float); - - writeChunkHeader(M_ANIMATION_BASEINFO, size); - - // char* baseAnimationName (blank for self) - writeString(anim->getBaseKeyFrameAnimationName()); - - // float baseKeyFrameTime - float t = (float)anim->getBaseKeyFrameTime(); - writeFloats(&t, 1); - } - - // tracks - Animation::VertexTrackIterator trackIt = anim->getVertexTrackIterator(); - while (trackIt.hasMoreElements()) - { - VertexAnimationTrack* vt = trackIt.getNext(); - writeAnimationTrack(vt); - } - popInnerChunk(mStream); - - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::writeAnimationTrack(const VertexAnimationTrack* track) - { - writeChunkHeader(M_ANIMATION_TRACK, calcAnimationTrackSize(track)); - // unsigned short type // 1 == morph, 2 == pose - uint16 animType = (uint16)track->getAnimationType(); - writeShorts(&animType, 1); - // unsigned short target - uint16 target = track->getHandle(); - writeShorts(&target, 1); - pushInnerChunk(mStream); - { - if (track->getAnimationType() == VAT_MORPH) - { - for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) - { - VertexMorphKeyFrame* kf = track->getVertexMorphKeyFrame(i); - writeMorphKeyframe(kf, track->getAssociatedVertexData()->vertexCount); - } - } - else // VAT_POSE - { - for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) - { - VertexPoseKeyFrame* kf = track->getVertexPoseKeyFrame(i); - writePoseKeyframe(kf); - } - } - } - popInnerChunk(mStream); - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::writeMorphKeyframe(const VertexMorphKeyFrame* kf, size_t vertexCount) - { - writeChunkHeader(M_ANIMATION_MORPH_KEYFRAME, calcMorphKeyframeSize(kf, vertexCount)); - // float time - float timePos = kf->getTime(); - writeFloats(&timePos, 1); - // bool includeNormals - bool includeNormals = kf->getVertexBuffer()->getVertexSize() > (sizeof(float) * 3); - writeBools(&includeNormals, 1); - // float x,y,z // repeat by number of vertices in original geometry - float* pSrc = static_cast( - kf->getVertexBuffer()->lock(HardwareBuffer::HBL_READ_ONLY)); - writeFloats(pSrc, vertexCount * (includeNormals ? 6 : 3)); - kf->getVertexBuffer()->unlock(); - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::writePoseKeyframe(const VertexPoseKeyFrame* kf) - { - writeChunkHeader(M_ANIMATION_POSE_KEYFRAME, calcPoseKeyframeSize(kf)); - // float time - float timePos = kf->getTime(); - writeFloats(&timePos, 1); - pushInnerChunk(mStream); - // pose references - VertexPoseKeyFrame::ConstPoseRefIterator poseRefIt = - kf->getPoseReferenceIterator(); - while (poseRefIt.hasMoreElements()) - { - writePoseKeyframePoseRef(poseRefIt.getNext()); - } - popInnerChunk(mStream); - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::writePoseKeyframePoseRef( - const VertexPoseKeyFrame::PoseRef& poseRef) - { - writeChunkHeader(M_ANIMATION_POSE_REF, calcPoseKeyframePoseRefSize()); - // unsigned short poseIndex - writeShorts(&(poseRef.poseIndex), 1); - // float influence - writeFloats(&(poseRef.influence), 1); - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::readPoses(DataStreamPtr& stream, Mesh* pMesh) - { - // Find all substreams - if (!stream->eof()) - { - pushInnerChunk(stream); - unsigned short streamID = readChunk(stream); - while(!stream->eof() && - (streamID == M_POSE)) - { - switch(streamID) - { - case M_POSE: - readPose(stream, pMesh); - break; - - } - - if (!stream->eof()) - { - streamID = readChunk(stream); - } - - } - if (!stream->eof()) - { - // Backpedal back to start of stream - backpedalChunkHeader(stream); - } - popInnerChunk(stream); - } - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::readPose(DataStreamPtr& stream, Mesh* pMesh) - { - // char* name (may be blank) - String name = readString(stream); - // unsigned short target - unsigned short target; - readShorts(stream, &target, 1); - - // bool includesNormals - bool includesNormals; - readBools(stream, &includesNormals, 1); - - Pose* pose = pMesh->createPose(target, name); - - // Find all substreams - if (!stream->eof()) - { - pushInnerChunk(stream); - unsigned short streamID = readChunk(stream); - while(!stream->eof() && - (streamID == M_POSE_VERTEX)) - { - switch(streamID) - { - case M_POSE_VERTEX: - // create vertex offset - uint32 vertIndex; - Vector3 offset, normal; - // unsigned long vertexIndex - readInts(stream, &vertIndex, 1); - // float xoffset, yoffset, zoffset - readFloats(stream, offset.ptr(), 3); - - if (includesNormals) - { - readFloats(stream, normal.ptr(), 3); - pose->addVertex(vertIndex, offset, normal); - } - else - { - pose->addVertex(vertIndex, offset); - } - - - break; - - } - - if (!stream->eof()) - { - streamID = readChunk(stream); - } - - } - if (!stream->eof()) - { - // Backpedal back to start of stream - backpedalChunkHeader(stream); - } - popInnerChunk(stream); - } - - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::readAnimations(DataStreamPtr& stream, Mesh* pMesh) - { - // Find all substreams - if (!stream->eof()) - { - pushInnerChunk(stream); - unsigned short streamID = readChunk(stream); - while(!stream->eof() && - (streamID == M_ANIMATION)) - { - switch(streamID) - { - case M_ANIMATION: - readAnimation(stream, pMesh); - break; - - } - - if (!stream->eof()) - { - streamID = readChunk(stream); - } - - } - if (!stream->eof()) - { - // Backpedal back to start of stream - backpedalChunkHeader(stream); - } - popInnerChunk(stream); - } - - - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::readAnimation(DataStreamPtr& stream, Mesh* pMesh) - { - - // char* name - String name = readString(stream); - // float length - float len; - readFloats(stream, &len, 1); - - Animation* anim = pMesh->createAnimation(name, len); - - // tracks - if (!stream->eof()) - { - pushInnerChunk(stream); - unsigned short streamID = readChunk(stream); - - // Optional base info is possible - if (streamID == M_ANIMATION_BASEINFO) - { - // char baseAnimationName - String baseAnimName = readString(stream); - // float baseKeyFrameTime - float baseKeyTime; - readFloats(stream, &baseKeyTime, 1); - - anim->setUseBaseKeyFrame(true, baseKeyTime, baseAnimName); - - if (!stream->eof()) - { - // Get next stream - streamID = readChunk(stream); - } - } - - while(!stream->eof() && - streamID == M_ANIMATION_TRACK) - { - switch(streamID) - { - case M_ANIMATION_TRACK: - readAnimationTrack(stream, anim, pMesh); - break; - }; - if (!stream->eof()) - { - streamID = readChunk(stream); - } - - } - if (!stream->eof()) - { - // Backpedal back to start of stream - backpedalChunkHeader(stream); - } - popInnerChunk(stream); - } - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::readAnimationTrack(DataStreamPtr& stream, - Animation* anim, Mesh* pMesh) - { - // ushort type - uint16 inAnimType; - readShorts(stream, &inAnimType, 1); - VertexAnimationType animType = (VertexAnimationType)inAnimType; - - // unsigned short target - uint16 target; - readShorts(stream, &target, 1); - - VertexAnimationTrack* track = anim->createVertexTrack(target, - pMesh->getVertexDataByTrackHandle(target), animType); - - // keyframes - if (!stream->eof()) - { - pushInnerChunk(stream); - unsigned short streamID = readChunk(stream); - while(!stream->eof() && - (streamID == M_ANIMATION_MORPH_KEYFRAME || - streamID == M_ANIMATION_POSE_KEYFRAME)) - { - switch(streamID) - { - case M_ANIMATION_MORPH_KEYFRAME: - readMorphKeyFrame(stream, track); - break; - case M_ANIMATION_POSE_KEYFRAME: - readPoseKeyFrame(stream, track); - break; - }; - if (!stream->eof()) - { - streamID = readChunk(stream); - } - - } - if (!stream->eof()) - { - // Backpedal back to start of stream - backpedalChunkHeader(stream); - } - popInnerChunk(stream); - } - - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::readMorphKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track) - { - // float time - float timePos; - readFloats(stream, &timePos, 1); - - // bool includesNormals - bool includesNormals; - readBools(stream, &includesNormals, 1); - - VertexMorphKeyFrame* kf = track->createVertexMorphKeyFrame(timePos); - - // Create buffer, allow read and use shadow buffer - size_t vertexCount = track->getAssociatedVertexData()->vertexCount; - size_t vertexSize = sizeof(float) * (includesNormals ? 6 : 3); - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - vertexSize, vertexCount, - HardwareBuffer::HBU_STATIC, true); - // float x,y,z // repeat by number of vertices in original geometry - float* pDst = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD)); - readFloats(stream, pDst, vertexCount * (includesNormals ? 6 : 3)); - vbuf->unlock(); - kf->setVertexBuffer(vbuf); - - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::readPoseKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track) - { - // float time - float timePos; - readFloats(stream, &timePos, 1); - - // Create keyframe - VertexPoseKeyFrame* kf = track->createVertexPoseKeyFrame(timePos); - - if (!stream->eof()) - { - pushInnerChunk(stream); - unsigned short streamID = readChunk(stream); - while(!stream->eof() && - streamID == M_ANIMATION_POSE_REF) - { - switch(streamID) - { - case M_ANIMATION_POSE_REF: - uint16 poseIndex; - float influence; - // unsigned short poseIndex - readShorts(stream, &poseIndex, 1); - // float influence - readFloats(stream, &influence, 1); - - kf->addPoseReference(poseIndex, influence); - - break; - }; - if (!stream->eof()) - { - streamID = readChunk(stream); - } - } - if (!stream->eof()) - { - // Backpedal back to start of stream - backpedalChunkHeader(stream); - } - popInnerChunk(stream); - } - - } - //--------------------------------------------------------------------- - void MeshSerializerImpl::readExtremes(DataStreamPtr& stream, Mesh *pMesh) - { - unsigned short idx; - readShorts(stream, &idx, 1); - - SubMesh *sm = pMesh->getSubMesh (idx); - - int n_floats = (mCurrentstreamLen - MSTREAM_OVERHEAD_SIZE - - sizeof (unsigned short)) / sizeof (float); - - assert ((n_floats % 3) == 0); - - float *vert = OGRE_ALLOC_T(float, n_floats, MEMCATEGORY_GEOMETRY); - readFloats(stream, vert, n_floats); - - for (int i = 0; i < n_floats; i += 3) - sm->extremityPoints.push_back(Vector3(vert [i], vert [i + 1], vert [i + 2])); - - OGRE_FREE(vert, MEMCATEGORY_GEOMETRY); - } - - void MeshSerializerImpl::enableValidation() - { -#if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - mReportChunkErrors = true; -#endif - } - - - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - MeshSerializerImpl_v1_8::MeshSerializerImpl_v1_8() - { - // Version number - mVersion = "[MeshSerializer_v1.8]"; - } - //--------------------------------------------------------------------- - MeshSerializerImpl_v1_8::~MeshSerializerImpl_v1_8() - { - } - //-------------------------------------------------------------------- - bool MeshSerializerImpl_v1_8::isLodMixed(const Mesh* pMesh) - { - if(!pMesh->hasManualLodLevel()) { - return false; - } - - unsigned short numLods = pMesh->getNumLodLevels(); - for (unsigned short i = 1; i < numLods; ++i) - { - if(!pMesh->_isManualLodLevel(i)){ - return true; - } - } - - return false; - } - size_t MeshSerializerImpl_v1_8::calcLodLevelSize(const Mesh* pMesh) - { - if (isLodMixed(pMesh)) { - return 0; // Supported in v1_9+ - } - exportedLodCount = pMesh->getNumLodLevels(); - size_t size = MSTREAM_OVERHEAD_SIZE; // Header - size += calcStringSize(pMesh->getLodStrategy()->getName()); // string strategyName; - size += sizeof(unsigned short); // unsigned short numLevels; - size += sizeof(bool); // bool manual; <== this is removed in v1_9 - - // Loop from LOD 1 (not 0, this is full detail) - for (ushort i = 1; i < exportedLodCount; ++i) - { - const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; - if (pMesh->_isManualLodLevel(i)) - { - size += calcLodUsageManualSize(usage); - } - else - { - size += calcLodUsageGeneratedSize(pMesh, usage, i); - } - } - return size; - } - size_t MeshSerializerImpl_v1_8::calcLodUsageManualSize(const MeshLodUsage& usage) - { - // Header - size_t size = MSTREAM_OVERHEAD_SIZE; // M_MESH_LOD_USAGE <== this is removed in v1_9 - - // float fromDepthSquared; - size += sizeof(float); - - // Manual part size - size += MSTREAM_OVERHEAD_SIZE; // M_MESH_LOD_MANUAL - // String manualMeshName; - size += calcStringSize(usage.manualName); - return size; - } - - size_t MeshSerializerImpl_v1_8::calcLodUsageGeneratedSize(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum) - { - // Usage Header - size_t size = MSTREAM_OVERHEAD_SIZE; - unsigned short subidx; - - // float fromDepthSquared; - size += sizeof(float); - - // Calc generated SubMesh sections size - for (subidx = 0; subidx < pMesh->getNumSubMeshes(); ++subidx) - { - SubMesh* submesh = pMesh->getSubMesh(subidx); - size += calcLodUsageGeneratedSubmeshSize(submesh, lodNum); - } - return size; - } - size_t MeshSerializerImpl_v1_8::calcLodUsageGeneratedSubmeshSize(const SubMesh* submesh, unsigned short lodNum) - { - const IndexData* indexData = submesh->mLodFaceList[lodNum - 1]; - const HardwareIndexBufferSharedPtr& ibuf = indexData->indexBuffer; - - size_t size = MSTREAM_OVERHEAD_SIZE; // M_MESH_LOD_GENERATED - size += sizeof(unsigned int); // unsigned int indexData->indexCount; - size += sizeof(bool); // bool indexes32Bit - size += ibuf.isNull() ? 0 : ibuf->getIndexSize() * indexData->indexCount; // faces - return size; - } -#if !OGRE_NO_MESHLOD - //-------------------------------------------------------------------- - void MeshSerializerImpl_v1_8::writeLodLevel(const Mesh* pMesh) - { - if (isLodMixed(pMesh)) { - LogManager::getSingleton().logMessage("MeshSerializer_v1_8 older mesh format is incompatible with mixed manual/generated Lod levels. Lod levels will not be exported."); - } else { - - exportedLodCount = pMesh->getNumLodLevels(); - bool manual = pMesh->hasManualLodLevel(); - - writeChunkHeader(M_MESH_LOD_LEVEL, calcLodLevelSize(pMesh)); - - // Details - // Get backward compatible strategy name - String strategyName = pMesh->getLodStrategy()->getName(); - if (strategyName == "distance_box" || strategyName == "distance_sphere") { - strategyName = "Distance"; - } else if (strategyName == "pixel_count" || strategyName == "screen_ratio_pixel_count") { - strategyName = "PixelCount"; - } - // string strategyName; - writeString(strategyName); - // unsigned short numLevels; - writeShorts(&exportedLodCount, 1); - // bool manual; (true for manual alternate meshes, false for generated) - writeBools(&manual, 1); - - pushInnerChunk(mStream); - // Loop from LOD 1 (not 0, this is full detail) - for (ushort i = 1; i < exportedLodCount; ++i) - { - const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; - assert(pMesh->_isManualLodLevel(i) == manual); - if (manual) - { - writeLodUsageManual(usage); - } - else - { - writeLodUsageGenerated(pMesh, usage, i); - } - } - popInnerChunk(mStream); - } - } - //--------------------------------------------------------------------- - /*void MeshSerializerImpl_v1_8::writeLodUsageGenerated( const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum ) - { - writeChunkHeader(M_MESH_LOD_USAGE, calcLodUsageGeneratedSize(pMesh, usage, lodNum)); - writeFloats(&(usage.userValue), 1); - pushInnerChunk(mStream); - // Now write sections - for (unsigned short subidx = 0; subidx < pMesh->getNumSubMeshes(); ++subidx) - { - SubMesh* sm = pMesh->getSubMesh(subidx); - const IndexData* indexData = sm->mLodFaceList[lodNum-1]; - - // Lock index buffer to write - HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; - - bool idx32 = (!ibuf.isNull() && ibuf->getType() == HardwareIndexBuffer::IT_32BIT); - - writeChunkHeader(M_MESH_LOD_GENERATED, calcLodUsageGeneratedSubmeshSize(sm, lodNum)); - unsigned int idxCount = static_cast(indexData->indexCount); - writeInts(&idxCount, 1); - writeBools(&idx32, 1); - - if (idxCount > 0) - { - if (idx32) - { - unsigned int* pIdx = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - writeInts(pIdx + indexData->indexStart, indexData->indexCount); - ibuf->unlock(); - } - else - { - unsigned short* pIdx = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - writeShorts(pIdx + indexData->indexStart, indexData->indexCount); - ibuf->unlock(); - } - } - } - popInnerChunk(mStream); - }*/ - - void MeshSerializerImpl_v1_8::writeLodUsageGenerated(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum) - { - writeChunkHeader(M_MESH_LOD_USAGE, calcLodUsageGeneratedSize(pMesh, usage, lodNum)); - float userValue = static_cast(usage.userValue); - writeFloats(&userValue, 1); - pushInnerChunk(mStream); - for (ushort i = 0; i < pMesh->getNumSubMeshes(); i++) - { - SubMesh* submesh = pMesh->getSubMesh(i); - writeLodUsageGeneratedSubmesh(submesh, lodNum); - } - popInnerChunk(mStream); - } - void MeshSerializerImpl_v1_8::writeLodUsageGeneratedSubmesh(const SubMesh* submesh, unsigned short lodNum) - { - const IndexData* indexData = submesh->mLodFaceList[lodNum - 1]; - HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; - assert(!ibuf.isNull()); - - writeChunkHeader(M_MESH_LOD_GENERATED, calcLodUsageGeneratedSubmeshSize(submesh, lodNum)); - unsigned int indexCount = static_cast(indexData->indexCount); - writeInts(&indexCount, 1); - bool is32BitIndices = (ibuf->getType() == HardwareIndexBuffer::IT_32BIT); - writeBools(&is32BitIndices, 1); - - if (is32BitIndices) - { - unsigned int* pIdx = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - writeInts(pIdx + indexData->indexStart, indexCount); - ibuf->unlock(); - } - else - { - unsigned short* pIdx = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - writeShorts(pIdx + indexData->indexStart, indexCount); - ibuf->unlock(); - } - } - //--------------------------------------------------------------------- - void MeshSerializerImpl_v1_8::writeLodUsageManual(const MeshLodUsage& usage) - { - writeChunkHeader(M_MESH_LOD_USAGE, calcLodUsageManualSize(usage)); - writeFloats(&(usage.userValue), 1); - pushInnerChunk(mStream); - writeChunkHeader(M_MESH_LOD_MANUAL, MSTREAM_OVERHEAD_SIZE + calcStringSize(usage.manualName)); - writeString(usage.manualName); - popInnerChunk(mStream); - } - //--------------------------------------------------------------------- - - void MeshSerializerImpl_v1_8::readMeshLodUsageGenerated( DataStreamPtr& stream, Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage ) - { - usage.manualName = ""; - usage.manualMesh.setNull(); - pushInnerChunk(stream); - { - // Get one set of detail per SubMesh - unsigned short numSubs, i; - numSubs = pMesh->getNumSubMeshes(); - for (i = 0; i < numSubs; ++i) - { - unsigned long streamID = readChunk(stream); - if (streamID != M_MESH_LOD_GENERATED) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Missing M_MESH_LOD_GENERATED stream in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodUsageGenerated"); - } - - SubMesh* sm = pMesh->getSubMesh(i); - IndexData* indexData = OGRE_NEW IndexData(); - sm->mLodFaceList[lodNum - 1] = indexData; - // unsigned int numIndexes - unsigned int numIndexes; - readInts(stream, &numIndexes, 1); - indexData->indexCount = static_cast(numIndexes); - - // bool indexes32Bit - bool idx32Bit; - readBools(stream, &idx32Bit, 1); - // unsigned short*/int* faceIndexes; ((v1, v2, v3) * numFaces) - if (idx32Bit) - { - indexData->indexBuffer = HardwareBufferManager::getSingleton(). - createIndexBuffer(HardwareIndexBuffer::IT_32BIT, indexData->indexCount, - pMesh->mIndexBufferUsage, pMesh->mIndexBufferShadowBuffer); - unsigned int* pIdx = static_cast( - indexData->indexBuffer->lock( - 0, - indexData->indexBuffer->getSizeInBytes(), - HardwareBuffer::HBL_DISCARD)); - - readInts(stream, pIdx, indexData->indexCount); - indexData->indexBuffer->unlock(); - - } - else - { - indexData->indexBuffer = HardwareBufferManager::getSingleton(). - createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, - pMesh->mIndexBufferUsage, pMesh->mIndexBufferShadowBuffer); - unsigned short* pIdx = static_cast( - indexData->indexBuffer->lock( - 0, - indexData->indexBuffer->getSizeInBytes(), - HardwareBuffer::HBL_DISCARD)); - readShorts(stream, pIdx, indexData->indexCount); - indexData->indexBuffer->unlock(); - } - } - } - popInnerChunk(stream); - } - //--------------------------------------------------------------------- - void MeshSerializerImpl_v1_8::readMeshLodUsageManual(DataStreamPtr& stream, - Mesh* pMesh, unsigned short lodNum, MeshLodUsage& usage) - { - pushInnerChunk(stream); - unsigned long streamID; - // Read detail stream - streamID = readChunk(stream); - if (streamID != M_MESH_LOD_MANUAL) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Missing M_MESH_LOD_MANUAL stream in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodUsageManual"); - } - - usage.manualName = readString(stream); - usage.manualMesh.setNull(); // will trigger load later - popInnerChunk(stream); - } + size_t size = MSTREAM_OVERHEAD_SIZE; -#endif - void MeshSerializerImpl_v1_8::readMeshLodLevel(DataStreamPtr& stream, Mesh* pMesh) - { -#if OGRE_NO_MESHLOD + // char* name (may be blank) + size += pose->getName().length() + 1; + // unsigned short target + size += sizeof(uint16); - /* - //Since the chunk sizes in old versions are messed up, we can't use this clean solution. - // We need to walk through the data to not rely on the chunk size! - stream->skip(mCurrentstreamLen); - - // Since we got here, we have already read the chunk header. - backpedalChunkHeader(stream); - */ - uint16 numSubs = pMesh->getNumSubMeshes(); - String strategyName = readString(stream); - uint16 numLods; - readShorts(stream, &numLods, 1); - bool manual; - readBools(stream, &manual, 1); // missing in v1_9 - pushInnerChunk(stream); - for (uint16 i = 1; i < numLods; ++i) - { - uint16 streamID = readChunk(stream); - if (streamID != M_MESH_LOD_USAGE) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Missing M_MESH_LOD_USAGE stream in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodInfo"); - } - float usageValue; - readFloats(stream, &usageValue, 1); - - if (manual) - { - // Read detail stream - uint16 streamID = readChunk(stream); - if (streamID != M_MESH_LOD_MANUAL) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Missing M_MESH_LOD_MANUAL stream in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodUsageManual"); - } - - String manualName = readString(stream); - } - else - { - pushInnerChunk(stream); - for (uint16 n = 0; n < numSubs; ++n) - { - unsigned long streamID = readChunk(stream); - if (streamID != M_MESH_LOD_GENERATED) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Missing M_MESH_LOD_GENERATED stream in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodUsageGenerated"); - } - - unsigned int numIndexes; - readInts(stream, &numIndexes, 1); - - bool idx32Bit; - readBools(stream, &idx32Bit, 1); - - size_t buffSize = numIndexes * (idx32Bit ? 4 : 2); - stream->skip(buffSize); - } - popInnerChunk(stream); - } - } - popInnerChunk(stream); -#else - unsigned short streamID, i; - - // Read the strategy to be used for this mesh - String strategyName = readString(stream); - LodStrategy *strategy = LodStrategyManager::getSingleton().getStrategy(strategyName); - pMesh->setLodStrategy(strategy); - - // unsigned short numLevels; - readShorts(stream, &(pMesh->mNumLods), 1); - // bool manual; (true for manual alternate meshes, false for generated) - readBools(stream, &(pMesh->mHasManualLodLevel), 1); - - // Preallocate submesh lod face data if not manual - if (!pMesh->hasManualLodLevel()) - { - unsigned short numsubs = pMesh->getNumSubMeshes(); - for (i = 0; i < numsubs; ++i) - { - SubMesh* sm = pMesh->getSubMesh(i); - assert(sm->mLodFaceList.empty()); - sm->mLodFaceList.resize(pMesh->mNumLods - 1); - } - } - - pushInnerChunk(stream); - // Loop from 1 rather than 0 (full detail index is not in file) - for (i = 1; i < pMesh->mNumLods; ++i) - { - streamID = readChunk(stream); - if (streamID != M_MESH_LOD_USAGE) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Missing M_MESH_LOD_USAGE stream in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodInfo"); - } - // Read depth - MeshLodUsage usage; - readFloats(stream, &(usage.userValue), 1); - - // Set default values - usage.manualName = ""; - usage.manualMesh.setNull(); - usage.edgeData = NULL; - - if (pMesh->hasManualLodLevel()) - { - readMeshLodUsageManual(stream, pMesh, i, usage); - } - else //(!pMesh->hasManualLodLevel()) - { - readMeshLodUsageGenerated(stream, pMesh, i, usage); - } - usage.edgeData = NULL; - - // Save usage - pMesh->mMeshLodUsageList.push_back(usage); - } - popInnerChunk(stream); -#endif - } + // vertex offsets + size += pose->getVertexOffsets().size() * calcPoseVertexSize(); - void MeshSerializerImpl_v1_8::enableValidation() - { -#if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - mReportChunkErrors = false; -#endif - } + return size; - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- + } //--------------------------------------------------------------------- + size_t MeshSerializerImpl_v1_41::calcPoseVertexSize(void) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + // unsigned long vertexIndex + size += sizeof(uint32); + // float xoffset, yoffset, zoffset + size += sizeof(float) * 3; + + return size; + } //--------------------------------------------------------------------- - MeshSerializerImpl_v1_41::MeshSerializerImpl_v1_41() - { - // Version number - mVersion = "[MeshSerializer_v1.41]"; - } - //--------------------------------------------------------------------- - MeshSerializerImpl_v1_41::~MeshSerializerImpl_v1_41() - { - } - //--------------------------------------------------------------------- - void MeshSerializerImpl_v1_41::writeMorphKeyframe(const VertexMorphKeyFrame* kf, size_t vertexCount) - { - writeChunkHeader(M_ANIMATION_MORPH_KEYFRAME, calcMorphKeyframeSize(kf, vertexCount)); - // float time - float timePos = kf->getTime(); - writeFloats(&timePos, 1); - // float x,y,z // repeat by number of vertices in original geometry - float* pSrc = static_cast( - kf->getVertexBuffer()->lock(HardwareBuffer::HBL_READ_ONLY)); - writeFloats(pSrc, vertexCount * 3); - kf->getVertexBuffer()->unlock(); - } - //--------------------------------------------------------------------- - void MeshSerializerImpl_v1_41::readMorphKeyFrame(DataStreamPtr& stream, VertexAnimationTrack* track) - { - // float time - float timePos; - readFloats(stream, &timePos, 1); - - VertexMorphKeyFrame* kf = track->createVertexMorphKeyFrame(timePos); - - // Create buffer, allow read and use shadow buffer - size_t vertexCount = track->getAssociatedVertexData()->vertexCount; - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - VertexElement::getTypeSize(VET_FLOAT3), vertexCount, - HardwareBuffer::HBU_STATIC, true); - // float x,y,z // repeat by number of vertices in original geometry - float* pDst = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD)); - readFloats(stream, pDst, vertexCount * 3); - vbuf->unlock(); - kf->setVertexBuffer(vbuf); - } - //--------------------------------------------------------------------- - void MeshSerializerImpl_v1_41::writePose(const Pose* pose) - { - writeChunkHeader(M_POSE, calcPoseSize(pose)); - - // char* name (may be blank) - writeString(pose->getName()); - - // unsigned short target - ushort val = pose->getTarget(); - writeShorts(&val, 1); - pushInnerChunk(mStream); - size_t vertexSize = calcPoseVertexSize(); - Pose::ConstVertexOffsetIterator vit = pose->getVertexOffsetIterator(); - while (vit.hasMoreElements()) - { - uint32 vertexIndex = (uint32)vit.peekNextKey(); - Vector3 offset = vit.getNext(); - writeChunkHeader(M_POSE_VERTEX, vertexSize); - // unsigned long vertexIndex - writeInts(&vertexIndex, 1); - // float xoffset, yoffset, zoffset - writeFloats(offset.ptr(), 3); - } - popInnerChunk(mStream); - } - //--------------------------------------------------------------------- - void MeshSerializerImpl_v1_41::readPose(DataStreamPtr& stream, Mesh* pMesh) - { - // char* name (may be blank) - String name = readString(stream); - // unsigned short target - unsigned short target; - readShorts(stream, &target, 1); - - Pose* pose = pMesh->createPose(target, name); - - // Find all substreams - if (!stream->eof()) - { - pushInnerChunk(stream); - unsigned short streamID = readChunk(stream); - while(!stream->eof() && - (streamID == M_POSE_VERTEX)) - { - switch(streamID) - { - case M_POSE_VERTEX: - // create vertex offset - uint32 vertIndex; - Vector3 offset; - // unsigned long vertexIndex - readInts(stream, &vertIndex, 1); - // float xoffset, yoffset, zoffset - readFloats(stream, offset.ptr(), 3); - - pose->addVertex(vertIndex, offset); - break; - - } - - if (!stream->eof()) - { - streamID = readChunk(stream); - } - - } - if (!stream->eof()) - { - // Backpedal back to start of stream - backpedalChunkHeader(stream); - } - popInnerChunk(stream); - } - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl_v1_41::calcPoseSize(const Pose* pose) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - - // char* name (may be blank) - size += pose->getName().length() + 1; - // unsigned short target - size += sizeof(uint16); - - // vertex offsets - size += pose->getVertexOffsets().size() * calcPoseVertexSize(); - - return size; - - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl_v1_41::calcPoseVertexSize(void) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - // unsigned long vertexIndex - size += sizeof(uint32); - // float xoffset, yoffset, zoffset - size += sizeof(float) * 3; - - return size; - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl_v1_41::calcMorphKeyframeSize(const VertexMorphKeyFrame* kf, - size_t vertexCount) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - // float time - size += sizeof(float); - // float x,y,z - size += sizeof(float) * 3 * vertexCount; - - return size; - } + size_t MeshSerializerImpl_v1_41::calcMorphKeyframeSize(const VertexMorphKeyFrame* kf, + size_t vertexCount) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + // float time + size += sizeof(float); + // float x,y,z + size += sizeof(float) * 3 * vertexCount; + + return size; + } //--------------------------------------------------------------------- //--------------------------------------------------------------------- @@ -3393,160 +3393,160 @@ namespace Ogre { MeshSerializerImpl_v1_4::~MeshSerializerImpl_v1_4() { } - size_t MeshSerializerImpl_v1_4::calcLodLevelSize(const Mesh* pMesh) - { - if (isLodMixed(pMesh) || pMesh->getLodStrategy() != DistanceLodStrategy::getSingletonPtr()) { - return 0; // Supported in v1_9+ - } - exportedLodCount = pMesh->getNumLodLevels(); - size_t size = MSTREAM_OVERHEAD_SIZE; // Header - //size += calcStringSize(pMesh->getLodStrategy()->getName()); // string strategyName; <== missing in v1_4 - size += sizeof(unsigned short); // unsigned short numLevels; - size += sizeof(bool); // bool manual; <== this is removed in v1_9 - - // Loop from LOD 1 (not 0, this is full detail) - for (ushort i = 1; i < exportedLodCount; ++i) - { - const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; - if (pMesh->_isManualLodLevel(i)) - { - size += calcLodUsageManualSize(usage); - } - else - { - size += calcLodUsageGeneratedSize(pMesh, usage, i); - } - } - return size; - } + size_t MeshSerializerImpl_v1_4::calcLodLevelSize(const Mesh* pMesh) + { + if (isLodMixed(pMesh) || pMesh->getLodStrategy() != DistanceLodStrategy::getSingletonPtr()) { + return 0; // Supported in v1_9+ + } + exportedLodCount = pMesh->getNumLodLevels(); + size_t size = MSTREAM_OVERHEAD_SIZE; // Header + //size += calcStringSize(pMesh->getLodStrategy()->getName()); // string strategyName; <== missing in v1_4 + size += sizeof(unsigned short); // unsigned short numLevels; + size += sizeof(bool); // bool manual; <== this is removed in v1_9 + + // Loop from LOD 1 (not 0, this is full detail) + for (ushort i = 1; i < exportedLodCount; ++i) + { + const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; + if (pMesh->_isManualLodLevel(i)) + { + size += calcLodUsageManualSize(usage); + } + else + { + size += calcLodUsageGeneratedSize(pMesh, usage, i); + } + } + return size; + } #if !OGRE_NO_MESHLOD //--------------------------------------------------------------------- - void MeshSerializerImpl_v1_4::writeLodLevel(const Mesh* pMesh) - { - if (isLodMixed(pMesh)) { - LogManager::getSingleton().logMessage("MeshSerializer_v1_4 or older mesh format is incompatible with mixed manual/generated Lod levels. Lod levels will not be exported."); - } else if (pMesh->getLodStrategy() != DistanceLodStrategy::getSingletonPtr()) { - LogManager::getSingleton().logMessage("MeshSerializer_v1_4 or older mesh format is only compatible with Distance Lod Strategy. Lod levels will not be exported."); - } else { - exportedLodCount = pMesh->getNumLodLevels(); - bool manual = pMesh->hasManualLodLevel(); - - writeChunkHeader(M_MESH_LOD_LEVEL, calcLodLevelSize(pMesh)); - - // Details - // string strategyName; - //writeString(pMesh->getLodStrategy()->getName()); <== missing in v1_4 - // unsigned short numLevels; - writeShorts(&exportedLodCount, 1); - // bool manual; (true for manual alternate meshes, false for generated) - writeBools(&manual, 1); - - pushInnerChunk(mStream); - // Loop from LOD 1 (not 0, this is full detail) - for (ushort i = 1; i < exportedLodCount; ++i) - { - const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; - assert(pMesh->_isManualLodLevel(i) == manual); - if (manual) - { - writeLodUsageManual(usage); - } - else - { - /*readFloats(stream, &(usage.value), 1); - usage.userValue = Math::Sqrt(usage.value);*/ - writeLodUsageGenerated(pMesh, usage, i); - } - } - popInnerChunk(mStream); - } - } - //--------------------------------------------------------------------- - void MeshSerializerImpl_v1_4::writeLodUsageGenerated(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum) - { - writeChunkHeader(M_MESH_LOD_USAGE, calcLodUsageGeneratedSize(pMesh, usage, lodNum)); - float value = static_cast(usage.value); - writeFloats(&value, 1); // <== In v1_4 this is value instead of userValue - pushInnerChunk(mStream); - for (ushort i = 0; i < pMesh->getNumSubMeshes(); i++) - { - SubMesh* submesh = pMesh->getSubMesh(i); - writeLodUsageGeneratedSubmesh(submesh, lodNum); - } - popInnerChunk(mStream); - } + void MeshSerializerImpl_v1_4::writeLodLevel(const Mesh* pMesh) + { + if (isLodMixed(pMesh)) { + LogManager::getSingleton().logMessage("MeshSerializer_v1_4 or older mesh format is incompatible with mixed manual/generated Lod levels. Lod levels will not be exported."); + } else if (pMesh->getLodStrategy() != DistanceLodStrategy::getSingletonPtr()) { + LogManager::getSingleton().logMessage("MeshSerializer_v1_4 or older mesh format is only compatible with Distance Lod Strategy. Lod levels will not be exported."); + } else { + exportedLodCount = pMesh->getNumLodLevels(); + bool manual = pMesh->hasManualLodLevel(); + + writeChunkHeader(M_MESH_LOD_LEVEL, calcLodLevelSize(pMesh)); + + // Details + // string strategyName; + //writeString(pMesh->getLodStrategy()->getName()); <== missing in v1_4 + // unsigned short numLevels; + writeShorts(&exportedLodCount, 1); + // bool manual; (true for manual alternate meshes, false for generated) + writeBools(&manual, 1); + + pushInnerChunk(mStream); + // Loop from LOD 1 (not 0, this is full detail) + for (ushort i = 1; i < exportedLodCount; ++i) + { + const MeshLodUsage& usage = pMesh->mMeshLodUsageList[i]; + assert(pMesh->_isManualLodLevel(i) == manual); + if (manual) + { + writeLodUsageManual(usage); + } + else + { + /*readFloats(stream, &(usage.value), 1); + usage.userValue = Math::Sqrt(usage.value);*/ + writeLodUsageGenerated(pMesh, usage, i); + } + } + popInnerChunk(mStream); + } + } + //--------------------------------------------------------------------- + void MeshSerializerImpl_v1_4::writeLodUsageGenerated(const Mesh* pMesh, const MeshLodUsage& usage, unsigned short lodNum) + { + writeChunkHeader(M_MESH_LOD_USAGE, calcLodUsageGeneratedSize(pMesh, usage, lodNum)); + float value = static_cast(usage.value); + writeFloats(&value, 1); // <== In v1_4 this is value instead of userValue + pushInnerChunk(mStream); + for (ushort i = 0; i < pMesh->getNumSubMeshes(); i++) + { + SubMesh* submesh = pMesh->getSubMesh(i); + writeLodUsageGeneratedSubmesh(submesh, lodNum); + } + popInnerChunk(mStream); + } #endif //--------------------------------------------------------------------- void MeshSerializerImpl_v1_4::readMeshLodLevel(DataStreamPtr& stream, Mesh* pMesh) { #if OGRE_NO_MESHLOD - /* - //Since the chunk sizes in old versions are messed up, we can't use this clean solution. - // We need to walk through the data to not rely on the chunk size! - stream->skip(mCurrentstreamLen); - - // Since we got here, we have already read the chunk header. - backpedalChunkHeader(stream); - */ - uint16 numSubs = pMesh->getNumSubMeshes(); - // String strategyName = readString(stream); // missing in v1_4 - uint16 numLods; - readShorts(stream, &numLods, 1); - bool manual; - readBools(stream, &manual, 1); // missing in v1_9 - pushInnerChunk(stream); - for (uint16 i = 1; i < numLods; ++i) - { - uint16 streamID = readChunk(stream); - if (streamID != M_MESH_LOD_USAGE) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Missing M_MESH_LOD_USAGE stream in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodInfo"); - } - float usageValue; - readFloats(stream, &usageValue, 1); - - if (manual) - { - // Read detail stream - uint16 streamID = readChunk(stream); - if (streamID != M_MESH_LOD_MANUAL) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Missing M_MESH_LOD_MANUAL stream in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodUsageManual"); - } - - String manualName = readString(stream); - } - else - { - pushInnerChunk(stream); - for (uint16 n = 0; n < numSubs; ++n) - { - unsigned long streamID = readChunk(stream); - if (streamID != M_MESH_LOD_GENERATED) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Missing M_MESH_LOD_GENERATED stream in " + pMesh->getName(), - "MeshSerializerImpl::readMeshLodUsageGenerated"); - } - - unsigned int numIndexes; - readInts(stream, &numIndexes, 1); - - bool idx32Bit; - readBools(stream, &idx32Bit, 1); - - size_t buffSize = numIndexes * (idx32Bit ? 4 : 2); - stream->skip(buffSize); - } - popInnerChunk(stream); - } - } - popInnerChunk(stream); + /* + //Since the chunk sizes in old versions are messed up, we can't use this clean solution. + // We need to walk through the data to not rely on the chunk size! + stream->skip(mCurrentstreamLen); + + // Since we got here, we have already read the chunk header. + backpedalChunkHeader(stream); + */ + uint16 numSubs = pMesh->getNumSubMeshes(); + // String strategyName = readString(stream); // missing in v1_4 + uint16 numLods; + readShorts(stream, &numLods, 1); + bool manual; + readBools(stream, &manual, 1); // missing in v1_9 + pushInnerChunk(stream); + for (uint16 i = 1; i < numLods; ++i) + { + uint16 streamID = readChunk(stream); + if (streamID != M_MESH_LOD_USAGE) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Missing M_MESH_LOD_USAGE stream in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodInfo"); + } + float usageValue; + readFloats(stream, &usageValue, 1); + + if (manual) + { + // Read detail stream + uint16 streamID = readChunk(stream); + if (streamID != M_MESH_LOD_MANUAL) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Missing M_MESH_LOD_MANUAL stream in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodUsageManual"); + } + + String manualName = readString(stream); + } + else + { + pushInnerChunk(stream); + for (uint16 n = 0; n < numSubs; ++n) + { + unsigned long streamID = readChunk(stream); + if (streamID != M_MESH_LOD_GENERATED) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Missing M_MESH_LOD_GENERATED stream in " + pMesh->getName(), + "MeshSerializerImpl::readMeshLodUsageGenerated"); + } + + unsigned int numIndexes; + readInts(stream, &numIndexes, 1); + + bool idx32Bit; + readBools(stream, &idx32Bit, 1); + + size_t buffSize = numIndexes * (idx32Bit ? 4 : 2); + stream->skip(buffSize); + } + popInnerChunk(stream); + } + } + popInnerChunk(stream); #else unsigned short streamID, i; @@ -3559,7 +3559,7 @@ namespace Ogre { bool manual; // true for manual alternate meshes, false for generated readBools(stream, &manual, 1); - pMesh->mHasManualLodLevel = manual; + pMesh->mHasManualLodLevel = manual; // Preallocate submesh LOD face data if not manual if (!manual) @@ -3569,11 +3569,11 @@ namespace Ogre { for (i = 0; i < numsubs; ++i) { SubMesh* sm = pMesh->getSubMesh(i); - assert(sm->mLodFaceList.empty()); - sm->mLodFaceList.resize(pMesh->mNumLods-1); + assert(sm->mLodFaceList.empty()); + sm->mLodFaceList.resize(pMesh->mNumLods-1); } } - pushInnerChunk(stream); + pushInnerChunk(stream); // Loop from 1 rather than 0 (full detail index is not in file) for (i = 1; i < pMesh->mNumLods; ++i) { @@ -3589,10 +3589,10 @@ namespace Ogre { readFloats(stream, &(usage.value), 1); usage.userValue = Math::Sqrt(usage.value); - // Set default values - usage.manualName = ""; - usage.manualMesh.setNull(); - usage.edgeData = NULL; + // Set default values + usage.manualName = ""; + usage.manualMesh.setNull(); + usage.edgeData = NULL; if (manual) { @@ -3607,9 +3607,9 @@ namespace Ogre { // Save usage pMesh->mMeshLodUsageList.push_back(usage); } - popInnerChunk(stream); + popInnerChunk(stream); #endif - } + } //--------------------------------------------------------------------- //--------------------------------------------------------------------- @@ -3628,38 +3628,38 @@ namespace Ogre { EdgeData* edgeData) { #if OGRE_NO_MESHLOD - if (edgeData == NULL) { // skip it! - // unsigned long numTriangles - uint32 numTriangles; - readInts(stream, &numTriangles, 1); - // unsigned long numEdgeGroups - uint32 numEdgeGroups; - readInts(stream, &numEdgeGroups, 1); - stream->skip(numTriangles * (8 * sizeof(uint32) + 4 * sizeof(float))); - - pushInnerChunk(stream); - uint32 tmp[6]; - for (uint32 eg = 0; eg < numEdgeGroups; ++eg) - { - unsigned short streamID = readChunk(stream); - if (streamID != M_EDGE_GROUP) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Missing M_EDGE_GROUP stream", - "MeshSerializerImpl_v1_3::readEdgeListLodInfo"); - } - - // unsigned long vertexSet - readInts(stream, tmp, 1); - // unsigned long numEdges - uint32 numEdges; - readInts(stream, &numEdges, 1); - // Edge* edgeList - stream->skip(numEdges * (6 * sizeof(uint32) + sizeof(bool))); - } - popInnerChunk(stream); - return; - } + if (edgeData == NULL) { // skip it! + // unsigned long numTriangles + uint32 numTriangles; + readInts(stream, &numTriangles, 1); + // unsigned long numEdgeGroups + uint32 numEdgeGroups; + readInts(stream, &numEdgeGroups, 1); + stream->skip(numTriangles * (8 * sizeof(uint32) + 4 * sizeof(float))); + + pushInnerChunk(stream); + uint32 tmp[6]; + for (uint32 eg = 0; eg < numEdgeGroups; ++eg) + { + unsigned short streamID = readChunk(stream); + if (streamID != M_EDGE_GROUP) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Missing M_EDGE_GROUP stream", + "MeshSerializerImpl_v1_3::readEdgeListLodInfo"); + } + + // unsigned long vertexSet + readInts(stream, tmp, 1); + // unsigned long numEdges + uint32 numEdges; + readInts(stream, &numEdges, 1); + // Edge* edgeList + stream->skip(numEdges * (6 * sizeof(uint32) + sizeof(bool))); + } + popInnerChunk(stream); + return; + } #endif // unsigned long numTriangles uint32 numTriangles; @@ -3702,7 +3702,7 @@ namespace Ogre { // Assume the mesh is closed, it will update later edgeData->isClosed = true; - pushInnerChunk(stream); + pushInnerChunk(stream); for (uint32 eg = 0; eg < numEdgeGroups; ++eg) { unsigned short streamID = readChunk(stream); @@ -3747,7 +3747,7 @@ namespace Ogre { } } } - popInnerChunk(stream); + popInnerChunk(stream); reorganiseTriangles(edgeData); } //--------------------------------------------------------------------- @@ -3880,86 +3880,86 @@ namespace Ogre { } } } - size_t MeshSerializerImpl_v1_3::calcEdgeListLodSize(const EdgeData* edgeData, bool isManual) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - - // unsigned short lodIndex - size += sizeof(uint16); - - // bool isManual // If manual, no edge data here, loaded from manual mesh - size += sizeof(bool); - if (!isManual) - { - // bool isClosed - //size += sizeof(bool); <== missing in v1_3 - // unsigned long numTriangles - size += sizeof(uint32); - // unsigned long numEdgeGroups - size += sizeof(uint32); - // Triangle* triangleList - size_t triSize = 0; - // unsigned long indexSet - // unsigned long vertexSet - // unsigned long vertIndex[3] - // unsigned long sharedVertIndex[3] - // float normal[4] - triSize += sizeof(uint32)* 8 - + sizeof(float)* 4; - - size += triSize * edgeData->triangles.size(); - // Write the groups - for (EdgeData::EdgeGroupList::const_iterator gi = edgeData->edgeGroups.begin(); - gi != edgeData->edgeGroups.end(); ++gi) - { - const EdgeData::EdgeGroup& edgeGroup = *gi; - size += calcEdgeGroupSize(edgeGroup); - } - - } - - return size; - } - //--------------------------------------------------------------------- - size_t MeshSerializerImpl_v1_3::calcEdgeGroupSize(const EdgeData::EdgeGroup& group) - { - size_t size = MSTREAM_OVERHEAD_SIZE; - - // unsigned long vertexSet - size += sizeof(uint32); - // unsigned long triStart - //size += sizeof(uint32); <== missing in v1_3 - // unsigned long triCount - //size += sizeof(uint32); <== missing in v1_3 - // unsigned long numEdges - size += sizeof(uint32); - // Edge* edgeList - size_t edgeSize = 0; - // unsigned long triIndex[2] - // unsigned long vertIndex[2] - // unsigned long sharedVertIndex[2] - // bool degenerate - edgeSize += sizeof(uint32)* 6 + sizeof(bool); - size += edgeSize * group.edges.size(); - - return size; - } - //--------------------------------------------------------------------- - void MeshSerializerImpl_v1_3::writeEdgeList(const Mesh* pMesh) - { - assert(exportedLodCount != 0); + size_t MeshSerializerImpl_v1_3::calcEdgeListLodSize(const EdgeData* edgeData, bool isManual) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + + // unsigned short lodIndex + size += sizeof(uint16); + + // bool isManual // If manual, no edge data here, loaded from manual mesh + size += sizeof(bool); + if (!isManual) + { + // bool isClosed + //size += sizeof(bool); <== missing in v1_3 + // unsigned long numTriangles + size += sizeof(uint32); + // unsigned long numEdgeGroups + size += sizeof(uint32); + // Triangle* triangleList + size_t triSize = 0; + // unsigned long indexSet + // unsigned long vertexSet + // unsigned long vertIndex[3] + // unsigned long sharedVertIndex[3] + // float normal[4] + triSize += sizeof(uint32)* 8 + + sizeof(float)* 4; + + size += triSize * edgeData->triangles.size(); + // Write the groups + for (EdgeData::EdgeGroupList::const_iterator gi = edgeData->edgeGroups.begin(); + gi != edgeData->edgeGroups.end(); ++gi) + { + const EdgeData::EdgeGroup& edgeGroup = *gi; + size += calcEdgeGroupSize(edgeGroup); + } + + } + + return size; + } + //--------------------------------------------------------------------- + size_t MeshSerializerImpl_v1_3::calcEdgeGroupSize(const EdgeData::EdgeGroup& group) + { + size_t size = MSTREAM_OVERHEAD_SIZE; + + // unsigned long vertexSet + size += sizeof(uint32); + // unsigned long triStart + //size += sizeof(uint32); <== missing in v1_3 + // unsigned long triCount + //size += sizeof(uint32); <== missing in v1_3 + // unsigned long numEdges + size += sizeof(uint32); + // Edge* edgeList + size_t edgeSize = 0; + // unsigned long triIndex[2] + // unsigned long vertIndex[2] + // unsigned long sharedVertIndex[2] + // bool degenerate + edgeSize += sizeof(uint32)* 6 + sizeof(bool); + size += edgeSize * group.edges.size(); + + return size; + } + //--------------------------------------------------------------------- + void MeshSerializerImpl_v1_3::writeEdgeList(const Mesh* pMesh) + { + assert(exportedLodCount != 0); writeChunkHeader(M_EDGE_LISTS, calcEdgeListSize(pMesh)); - pushInnerChunk(mStream); - for (ushort i = 0; i < exportedLodCount; ++i) + pushInnerChunk(mStream); + for (ushort i = 0; i < exportedLodCount; ++i) { const EdgeData* edgeData = pMesh->getEdgeList(i); bool isManual = !pMesh->mMeshLodUsageList[i].manualName.empty(); writeChunkHeader(M_EDGE_LIST_LOD, calcEdgeListLodSize(edgeData, isManual)); - + // unsigned short lodIndex writeShorts(&i, 1); - - // bool isManual // If manual, no edge data here, loaded from manual mesh + + // bool isManual // If manual, no edge data here, loaded from manual mesh writeBools(&isManual, 1); if (!isManual) { @@ -3995,12 +3995,12 @@ namespace Ogre { writeInts(tmp, 3); // float normal[4]; writeFloats(&(fni->x), 4); - + } - pushInnerChunk(mStream); + pushInnerChunk(mStream); // Write the groups for (EdgeData::EdgeGroupList::const_iterator gi = edgeData->edgeGroups.begin(); - gi != edgeData->edgeGroups.end(); ++gi) + gi != edgeData->edgeGroups.end(); ++gi) { const EdgeData::EdgeGroup& edgeGroup = *gi; writeChunkHeader(M_EDGE_GROUP, calcEdgeGroupSize(edgeGroup)); @@ -4013,7 +4013,7 @@ namespace Ogre { // Edge* edgeList // Iterate rather than writing en-masse to allow endian conversion for (EdgeData::EdgeList::const_iterator ei = edgeGroup.edges.begin(); - ei != edgeGroup.edges.end(); ++ei) + ei != edgeGroup.edges.end(); ++ei) { const EdgeData::Edge& edge = *ei; uint32 tmp[2]; @@ -4032,16 +4032,16 @@ namespace Ogre { // bool degenerate writeBools(&(edge.degenerate), 1); } - + } - popInnerChunk(mStream); - + popInnerChunk(mStream); + } - + } - popInnerChunk(mStream); - } - //--------------------------------------------------------------------- + popInnerChunk(mStream); + } + //--------------------------------------------------------------------- //--------------------------------------------------------------------- //--------------------------------------------------------------------- MeshSerializerImpl_v1_2::MeshSerializerImpl_v1_2() @@ -4080,7 +4080,7 @@ namespace Ogre { // Find optional geometry streams if (!stream->eof()) { - pushInnerChunk(stream); + pushInnerChunk(stream); unsigned short streamID = readChunk(stream); unsigned short texCoordSet = 0; @@ -4112,7 +4112,7 @@ namespace Ogre { // Backpedal back to start of non-submesh stream backpedalChunkHeader(stream); } - popInnerChunk(stream); + popInnerChunk(stream); } } //--------------------------------------------------------------------- @@ -4127,7 +4127,7 @@ namespace Ogre { dest->vertexDeclaration->getVertexSize(bindIdx), dest->vertexCount, pMesh->mVertexBufferUsage, - pMesh->mVertexBufferShadowBuffer); + pMesh->mVertexBufferShadowBuffer); pFloat = static_cast( vbuf->lock(HardwareBuffer::HBL_DISCARD)); readFloats(stream, pFloat, dest->vertexCount * 3); @@ -4146,7 +4146,7 @@ namespace Ogre { dest->vertexDeclaration->getVertexSize(bindIdx), dest->vertexCount, pMesh->mVertexBufferUsage, - pMesh->mVertexBufferShadowBuffer); + pMesh->mVertexBufferShadowBuffer); pFloat = static_cast( vbuf->lock(HardwareBuffer::HBL_DISCARD)); readFloats(stream, pFloat, dest->vertexCount * 3); @@ -4165,7 +4165,7 @@ namespace Ogre { dest->vertexDeclaration->getVertexSize(bindIdx), dest->vertexCount, pMesh->mVertexBufferUsage, - pMesh->mVertexBufferShadowBuffer); + pMesh->mVertexBufferShadowBuffer); pRGBA = static_cast( vbuf->lock(HardwareBuffer::HBL_DISCARD)); readInts(stream, pRGBA, dest->vertexCount); @@ -4192,7 +4192,7 @@ namespace Ogre { dest->vertexDeclaration->getVertexSize(bindIdx), dest->vertexCount, pMesh->mVertexBufferUsage, - pMesh->mVertexBufferShadowBuffer); + pMesh->mVertexBufferShadowBuffer); pFloat = static_cast( vbuf->lock(HardwareBuffer::HBL_DISCARD)); readFloats(stream, pFloat, dest->vertexCount * dim); @@ -4231,7 +4231,7 @@ namespace Ogre { dest->vertexDeclaration->getVertexSize(bindIdx), dest->vertexCount, pMesh->getVertexBufferUsage(), - pMesh->isVertexBufferShadowed()); + pMesh->isVertexBufferShadowed()); pFloat = static_cast( vbuf->lock(HardwareBuffer::HBL_DISCARD)); readFloats(stream, pFloat, dest->vertexCount * dim); diff --git a/OgreMain/src/OgreMovableObject.cpp b/OgreMain/src/OgreMovableObject.cpp index de8cf782691..294b5b0b983 100644 --- a/OgreMain/src/OgreMovableObject.cpp +++ b/OgreMain/src/OgreMovableObject.cpp @@ -39,10 +39,10 @@ THE SOFTWARE. #include "OgreTechnique.h" namespace Ogre { - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - uint32 MovableObject::msDefaultQueryFlags = 0xFFFFFFFF; - uint32 MovableObject::msDefaultVisibilityFlags = 0xFFFFFFFF; + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + uint32 MovableObject::msDefaultQueryFlags = 0xFFFFFFFF; + uint32 MovableObject::msDefaultVisibilityFlags = 0xFFFFFFFF; //----------------------------------------------------------------------- MovableObject::MovableObject() : mCreator(0) @@ -50,25 +50,25 @@ namespace Ogre { , mParentNode(0) , mParentIsTagPoint(false) , mVisible(true) - , mDebugDisplay(false) + , mDebugDisplay(false) , mUpperDistance(0) , mSquaredUpperDistance(0) - , mMinPixelSize(0) + , mMinPixelSize(0) , mBeyondFarDistance(false) , mRenderQueueID(RENDER_QUEUE_MAIN) , mRenderQueueIDSet(false) - , mRenderQueuePriority(100) - , mRenderQueuePrioritySet(false) - , mQueryFlags(msDefaultQueryFlags) + , mRenderQueuePriority(100) + , mRenderQueuePrioritySet(false) + , mQueryFlags(msDefaultQueryFlags) , mVisibilityFlags(msDefaultVisibilityFlags) , mCastShadows(true) , mRenderingDisabled(false) , mListener(0) , mLightListUpdated(0) - , mLightMask(0xFFFFFFFF) + , mLightMask(0xFFFFFFFF) { - if (Root::getSingletonPtr()) - mMinPixelSize = Root::getSingleton().getDefaultMinPixelSize(); + if (Root::getSingletonPtr()) + mMinPixelSize = Root::getSingleton().getDefaultMinPixelSize(); } //----------------------------------------------------------------------- MovableObject::MovableObject(const String& name) @@ -78,25 +78,25 @@ namespace Ogre { , mParentNode(0) , mParentIsTagPoint(false) , mVisible(true) - , mDebugDisplay(false) + , mDebugDisplay(false) , mUpperDistance(0) , mSquaredUpperDistance(0) - , mMinPixelSize(0) + , mMinPixelSize(0) , mBeyondFarDistance(false) , mRenderQueueID(RENDER_QUEUE_MAIN) , mRenderQueueIDSet(false) - , mRenderQueuePriority(100) - , mRenderQueuePrioritySet(false) - , mQueryFlags(msDefaultQueryFlags) + , mRenderQueuePriority(100) + , mRenderQueuePrioritySet(false) + , mQueryFlags(msDefaultQueryFlags) , mVisibilityFlags(msDefaultVisibilityFlags) , mCastShadows(true) , mRenderingDisabled(false) , mListener(0) , mLightListUpdated(0) - , mLightMask(0xFFFFFFFF) + , mLightMask(0xFFFFFFFF) { - if (Root::getSingletonPtr()) - mMinPixelSize = Root::getSingleton().getDefaultMinPixelSize(); + if (Root::getSingletonPtr()) + mMinPixelSize = Root::getSingleton().getDefaultMinPixelSize(); } //----------------------------------------------------------------------- MovableObject::~MovableObject() @@ -171,44 +171,44 @@ namespace Ogre { return (mParentNode != 0); } - //--------------------------------------------------------------------- - void MovableObject::detachFromParent(void) - { - if (isAttached()) - { - if (mParentIsTagPoint) - { - TagPoint* tp = static_cast(mParentNode); - tp->getParentEntity()->detachObjectFromBone(this); - } - else - { - SceneNode* sn = static_cast(mParentNode); - sn->detachObject(this); - } - } - } + //--------------------------------------------------------------------- + void MovableObject::detachFromParent(void) + { + if (isAttached()) + { + if (mParentIsTagPoint) + { + TagPoint* tp = static_cast(mParentNode); + tp->getParentEntity()->detachObjectFromBone(this); + } + else + { + SceneNode* sn = static_cast(mParentNode); + sn->detachObject(this); + } + } + } //----------------------------------------------------------------------- - bool MovableObject::isInScene(void) const - { - if (mParentNode != 0) - { - if (mParentIsTagPoint) - { - TagPoint* tp = static_cast(mParentNode); - return tp->getParentEntity()->isInScene(); - } - else - { - SceneNode* sn = static_cast(mParentNode); - return sn->isInSceneGraph(); - } - } - else - { - return false; - } - } + bool MovableObject::isInScene(void) const + { + if (mParentNode != 0) + { + if (mParentIsTagPoint) + { + TagPoint* tp = static_cast(mParentNode); + return tp->getParentEntity()->isInScene(); + } + else + { + SceneNode* sn = static_cast(mParentNode); + return sn->isInSceneGraph(); + } + } + else + { + return false; + } + } //----------------------------------------------------------------------- void MovableObject::_notifyMoved(void) { @@ -244,65 +244,65 @@ namespace Ogre { return true; } - //----------------------------------------------------------------------- - void MovableObject::_notifyCurrentCamera(Camera* cam) - { - if (mParentNode) - { - mBeyondFarDistance = false; - - if (cam->getUseRenderingDistance() && mUpperDistance > 0) - { - Real rad = getBoundingRadius(); - Real squaredDepth = mParentNode->getSquaredViewDepth(cam->getLodCamera()); - - const Vector3& scl = mParentNode->_getDerivedScale(); - Real factor = std::max(std::max(scl.x, scl.y), scl.z); - - // Max distance to still render - Real maxDist = mUpperDistance + rad * factor; - if (squaredDepth > Math::Sqr(maxDist)) - { - mBeyondFarDistance = true; - } - } - - if (!mBeyondFarDistance && cam->getUseMinPixelSize() && mMinPixelSize > 0) - { - - Real pixelRatio = cam->getPixelDisplayRatio(); - - //if ratio is relative to distance than the distance at which the object should be displayed - //is the size of the radius divided by the ratio - //get the size of the entity in the world - Ogre::Vector3 objBound = getBoundingBox().getSize() * - getParentNode()->_getDerivedScale(); - - //We object are projected from 3 dimensions to 2. The shortest displayed dimension of - //as object will always be at most the second largest dimension of the 3 dimensional - //bounding box. - //The square calculation come both to get rid of minus sign and for improve speed - //in the final calculation - objBound.x = Math::Sqr(objBound.x); - objBound.y = Math::Sqr(objBound.y); - objBound.z = Math::Sqr(objBound.z); - float sqrObjMedianSize = std::max(std::max( - std::min(objBound.x,objBound.y), - std::min(objBound.x,objBound.z)), - std::min(objBound.y,objBound.z)); - - //If we have a perspective camera calculations are done relative to distance - Real sqrDistance = 1; - if (cam->getProjectionType() == PT_PERSPECTIVE) - { - sqrDistance = mParentNode->getSquaredViewDepth(cam->getLodCamera()); - } - - //Final Calculation to tell whether the object is to small - mBeyondFarDistance = sqrObjMedianSize < - sqrDistance * Math::Sqr(pixelRatio * mMinPixelSize); - } - + //----------------------------------------------------------------------- + void MovableObject::_notifyCurrentCamera(Camera* cam) + { + if (mParentNode) + { + mBeyondFarDistance = false; + + if (cam->getUseRenderingDistance() && mUpperDistance > 0) + { + Real rad = getBoundingRadius(); + Real squaredDepth = mParentNode->getSquaredViewDepth(cam->getLodCamera()); + + const Vector3& scl = mParentNode->_getDerivedScale(); + Real factor = std::max(std::max(scl.x, scl.y), scl.z); + + // Max distance to still render + Real maxDist = mUpperDistance + rad * factor; + if (squaredDepth > Math::Sqr(maxDist)) + { + mBeyondFarDistance = true; + } + } + + if (!mBeyondFarDistance && cam->getUseMinPixelSize() && mMinPixelSize > 0) + { + + Real pixelRatio = cam->getPixelDisplayRatio(); + + //if ratio is relative to distance than the distance at which the object should be displayed + //is the size of the radius divided by the ratio + //get the size of the entity in the world + Ogre::Vector3 objBound = getBoundingBox().getSize() * + getParentNode()->_getDerivedScale(); + + //We object are projected from 3 dimensions to 2. The shortest displayed dimension of + //as object will always be at most the second largest dimension of the 3 dimensional + //bounding box. + //The square calculation come both to get rid of minus sign and for improve speed + //in the final calculation + objBound.x = Math::Sqr(objBound.x); + objBound.y = Math::Sqr(objBound.y); + objBound.z = Math::Sqr(objBound.z); + float sqrObjMedianSize = std::max(std::max( + std::min(objBound.x,objBound.y), + std::min(objBound.x,objBound.z)), + std::min(objBound.y,objBound.z)); + + //If we have a perspective camera calculations are done relative to distance + Real sqrDistance = 1; + if (cam->getProjectionType() == PT_PERSPECTIVE) + { + sqrDistance = mParentNode->getSquaredViewDepth(cam->getLodCamera()); + } + + //Final Calculation to tell whether the object is to small + mBeyondFarDistance = sqrObjMedianSize < + sqrDistance * Math::Sqr(pixelRatio * mMinPixelSize); + } + // Construct event object MovableObjectLodChangedEvent evt; evt.movableObject = this; @@ -311,26 +311,26 @@ namespace Ogre { // Notify LOD event listeners cam->getSceneManager()->_notifyMovableObjectLodChanged(evt); - } + } mRenderingDisabled = mListener && !mListener->objectRendering(this, cam); - } + } //----------------------------------------------------------------------- void MovableObject::setRenderQueueGroup(uint8 queueID) { - assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!"); + assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!"); mRenderQueueID = queueID; mRenderQueueIDSet = true; } - //----------------------------------------------------------------------- - void MovableObject::setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) - { - setRenderQueueGroup(queueID); - mRenderQueuePriority = priority; - mRenderQueuePrioritySet = true; + //----------------------------------------------------------------------- + void MovableObject::setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) + { + setRenderQueueGroup(queueID); + mRenderQueuePriority = priority; + mRenderQueuePrioritySet = true; - } + } //----------------------------------------------------------------------- uint8 MovableObject::getRenderQueueGroup(void) const @@ -338,17 +338,17 @@ namespace Ogre { return mRenderQueueID; } //----------------------------------------------------------------------- - const Matrix4& MovableObject::_getParentNodeFullTransform(void) const - { - - if(mParentNode) - { - // object attached to a sceneNode - return mParentNode->_getFullTransform(); - } + const Matrix4& MovableObject::_getParentNodeFullTransform(void) const + { + + if(mParentNode) + { + // object attached to a sceneNode + return mParentNode->_getFullTransform(); + } // fallback return Matrix4::IDENTITY; - } + } //----------------------------------------------------------------------- const AxisAlignedBox& MovableObject::getWorldBoundingBox(bool derive) const { @@ -362,17 +362,17 @@ namespace Ogre { } //----------------------------------------------------------------------- - const Sphere& MovableObject::getWorldBoundingSphere(bool derive) const - { - if (derive) - { - const Vector3& scl = mParentNode->_getDerivedScale(); - Real factor = std::max(std::max(scl.x, scl.y), scl.z); - mWorldBoundingSphere.setRadius(getBoundingRadius() * factor); - mWorldBoundingSphere.setCenter(mParentNode->_getDerivedPosition()); - } - return mWorldBoundingSphere; - } + const Sphere& MovableObject::getWorldBoundingSphere(bool derive) const + { + if (derive) + { + const Vector3& scl = mParentNode->_getDerivedScale(); + Real factor = std::max(std::max(scl.x, scl.y), scl.z); + mWorldBoundingSphere.setRadius(getBoundingRadius() * factor); + mWorldBoundingSphere.setCenter(mParentNode->_getDerivedPosition()); + } + return mWorldBoundingSphere; + } //----------------------------------------------------------------------- const LightList& MovableObject::queryLights(void) const { @@ -404,8 +404,8 @@ namespace Ogre { { mLightListUpdated = frame; - const Vector3& scl = mParentNode->_getDerivedScale(); - Real factor = std::max(std::max(scl.x, scl.y), scl.z); + const Vector3& scl = mParentNode->_getDerivedScale(); + Real factor = std::max(std::max(scl.x, scl.y), scl.z); sn->findLights(mLightList, this->getBoundingRadius() * factor, this->getLightMask()); } @@ -454,62 +454,62 @@ namespace Ogre { return 0; } } - //----------------------------------------------------------------------- - uint32 MovableObject::getTypeFlags(void) const - { - if (mCreator) - { - return mCreator->getTypeFlags(); - } - else - { - return 0xFFFFFFFF; - } - } - //--------------------------------------------------------------------- - void MovableObject::setLightMask(uint32 lightMask) - { - this->mLightMask = lightMask; - //make sure to request a new light list from the scene manager if mask changed - mLightListUpdated = 0; - } - //--------------------------------------------------------------------- - class MORecvShadVisitor : public Renderable::Visitor - { - public: - bool anyReceiveShadows; - MORecvShadVisitor() : anyReceiveShadows(false) - { - - } - void visit(Renderable* rend, ushort lodIndex, bool isDebug, - Any* pAny = 0) - { - Technique* tech = rend->getTechnique(); - bool techReceivesShadows = tech && tech->getParent()->getReceiveShadows(); - anyReceiveShadows = anyReceiveShadows || - techReceivesShadows || !tech; - } - }; - //--------------------------------------------------------------------- - bool MovableObject::getReceivesShadows() - { - MORecvShadVisitor visitor; - visitRenderables(&visitor); - return visitor.anyReceiveShadows; - - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - MovableObject* MovableObjectFactory::createInstance( - const String& name, SceneManager* manager, - const NameValuePairList* params) - { - MovableObject* m = createInstanceImpl(name, params); - m->_notifyCreator(this); - m->_notifyManager(manager); - return m; - } + //----------------------------------------------------------------------- + uint32 MovableObject::getTypeFlags(void) const + { + if (mCreator) + { + return mCreator->getTypeFlags(); + } + else + { + return 0xFFFFFFFF; + } + } + //--------------------------------------------------------------------- + void MovableObject::setLightMask(uint32 lightMask) + { + this->mLightMask = lightMask; + //make sure to request a new light list from the scene manager if mask changed + mLightListUpdated = 0; + } + //--------------------------------------------------------------------- + class MORecvShadVisitor : public Renderable::Visitor + { + public: + bool anyReceiveShadows; + MORecvShadVisitor() : anyReceiveShadows(false) + { + + } + void visit(Renderable* rend, ushort lodIndex, bool isDebug, + Any* pAny = 0) + { + Technique* tech = rend->getTechnique(); + bool techReceivesShadows = tech && tech->getParent()->getReceiveShadows(); + anyReceiveShadows = anyReceiveShadows || + techReceivesShadows || !tech; + } + }; + //--------------------------------------------------------------------- + bool MovableObject::getReceivesShadows() + { + MORecvShadVisitor visitor; + visitRenderables(&visitor); + return visitor.anyReceiveShadows; + + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + MovableObject* MovableObjectFactory::createInstance( + const String& name, SceneManager* manager, + const NameValuePairList* params) + { + MovableObject* m = createInstanceImpl(name, params); + m->_notifyCreator(this); + m->_notifyManager(manager); + return m; + } } diff --git a/OgreMain/src/OgreNode.cpp b/OgreMain/src/OgreNode.cpp index f96b02a416f..a9010a84737 100644 --- a/OgreMain/src/OgreNode.cpp +++ b/OgreMain/src/OgreNode.cpp @@ -44,28 +44,28 @@ THE SOFTWARE. namespace Ogre { NameGenerator Node::msNameGenerator("Unnamed_"); - Node::QueuedUpdates Node::msQueuedUpdates; + Node::QueuedUpdates Node::msQueuedUpdates; //----------------------------------------------------------------------- Node::Node() - :mParent(0), - mNeedParentUpdate(false), - mNeedChildUpdate(false), - mParentNotified(false), + :mParent(0), + mNeedParentUpdate(false), + mNeedChildUpdate(false), + mParentNotified(false), mQueuedForUpdate(false), - mOrientation(Quaternion::IDENTITY), - mPosition(Vector3::ZERO), - mScale(Vector3::UNIT_SCALE), + mOrientation(Quaternion::IDENTITY), + mPosition(Vector3::ZERO), + mScale(Vector3::UNIT_SCALE), mInheritOrientation(true), - mInheritScale(true), - mDerivedOrientation(Quaternion::IDENTITY), - mDerivedPosition(Vector3::ZERO), - mDerivedScale(Vector3::UNIT_SCALE), - mInitialPosition(Vector3::ZERO), - mInitialOrientation(Quaternion::IDENTITY), - mInitialScale(Vector3::UNIT_SCALE), - mCachedTransformOutOfDate(true), - mListener(0), - mDebug(0) + mInheritScale(true), + mDerivedOrientation(Quaternion::IDENTITY), + mDerivedPosition(Vector3::ZERO), + mDerivedScale(Vector3::UNIT_SCALE), + mInitialPosition(Vector3::ZERO), + mInitialOrientation(Quaternion::IDENTITY), + mInitialScale(Vector3::UNIT_SCALE), + mCachedTransformOutOfDate(true), + mListener(0), + mDebug(0) { // Generate a name mName = msNameGenerator.generate(); @@ -74,28 +74,28 @@ namespace Ogre { } //----------------------------------------------------------------------- - Node::Node(const String& name) - : - mParent(0), - mNeedParentUpdate(false), - mNeedChildUpdate(false), - mParentNotified(false), + Node::Node(const String& name) + : + mParent(0), + mNeedParentUpdate(false), + mNeedChildUpdate(false), + mParentNotified(false), mQueuedForUpdate(false), - mName(name), - mOrientation(Quaternion::IDENTITY), - mPosition(Vector3::ZERO), - mScale(Vector3::UNIT_SCALE), + mName(name), + mOrientation(Quaternion::IDENTITY), + mPosition(Vector3::ZERO), + mScale(Vector3::UNIT_SCALE), mInheritOrientation(true), - mInheritScale(true), - mDerivedOrientation(Quaternion::IDENTITY), - mDerivedPosition(Vector3::ZERO), - mDerivedScale(Vector3::UNIT_SCALE), - mInitialPosition(Vector3::ZERO), - mInitialOrientation(Quaternion::IDENTITY), - mInitialScale(Vector3::UNIT_SCALE), - mCachedTransformOutOfDate(true), - mListener(0), - mDebug(0) + mInheritScale(true), + mDerivedOrientation(Quaternion::IDENTITY), + mDerivedPosition(Vector3::ZERO), + mDerivedScale(Vector3::UNIT_SCALE), + mInitialPosition(Vector3::ZERO), + mInitialOrientation(Quaternion::IDENTITY), + mInitialScale(Vector3::UNIT_SCALE), + mCachedTransformOutOfDate(true), + mListener(0), + mDebug(0) { @@ -106,18 +106,18 @@ namespace Ogre { //----------------------------------------------------------------------- Node::~Node() { - OGRE_DELETE mDebug; - mDebug = 0; + OGRE_DELETE mDebug; + mDebug = 0; - // Call listener (note, only called if there's something to do) - if (mListener) - { - mListener->nodeDestroyed(this); - } + // Call listener (note, only called if there's something to do) + if (mListener) + { + mListener->nodeDestroyed(this); + } - removeAllChildren(); - if(mParent) - mParent->removeChild(this); + removeAllChildren(); + if(mParent) + mParent->removeChild(this); if (mQueuedForUpdate) { @@ -133,7 +133,7 @@ namespace Ogre { } } - } + } //----------------------------------------------------------------------- Node* Node::getParent(void) const { @@ -143,21 +143,21 @@ namespace Ogre { //----------------------------------------------------------------------- void Node::setParent(Node* parent) { - bool different = (parent != mParent); + bool different = (parent != mParent); mParent = parent; // Request update from parent - mParentNotified = false ; + mParentNotified = false ; needUpdate(); - // Call listener (note, only called if there's something to do) - if (mListener && different) - { - if (mParent) - mListener->nodeAttached(this); - else - mListener->nodeDetached(this); - } + // Call listener (note, only called if there's something to do) + if (mListener && different) + { + if (mParent) + mListener->nodeAttached(this); + else + mListener->nodeDetached(this); + } } @@ -178,15 +178,15 @@ namespace Ogre { //----------------------------------------------------------------------- void Node::_update(bool updateChildren, bool parentHasChanged) { - // always clear information about parent notification - mParentNotified = false; + // always clear information about parent notification + mParentNotified = false; // See if we should process everyone if (mNeedParentUpdate || parentHasChanged) { // Update transforms from parent _updateFromParent(); - } + } if(updateChildren) { @@ -217,17 +217,17 @@ namespace Ogre { mNeedChildUpdate = false; } } - //----------------------------------------------------------------------- - void Node::_updateFromParent(void) const - { - updateFromParentImpl(); + //----------------------------------------------------------------------- + void Node::_updateFromParent(void) const + { + updateFromParentImpl(); - // Call listener (note, this method only called if there's something to do) - if (mListener) - { - mListener->nodeUpdated(this); - } - } + // Call listener (note, this method only called if there's something to do) + if (mListener) + { + mListener->nodeUpdated(this); + } + } //----------------------------------------------------------------------- void Node::updateFromParentImpl(void) const { @@ -240,7 +240,7 @@ namespace Ogre { // Combine orientation with that of parent mDerivedOrientation = parentOrientation * mOrientation; } - else + else { // No inheritance mDerivedOrientation = mOrientation; @@ -274,8 +274,8 @@ namespace Ogre { mDerivedScale = mScale; } - mCachedTransformOutOfDate = true; - mNeedParentUpdate = false; + mCachedTransformOutOfDate = true; + mNeedParentUpdate = false; } //----------------------------------------------------------------------- @@ -381,15 +381,15 @@ namespace Ogre { //----------------------------------------------------------------------- void Node::setOrientation( const Quaternion & q ) { - assert(!q.isNaN() && "Invalid orientation supplied as parameter"); - mOrientation = q; - mOrientation.normalise(); + assert(!q.isNaN() && "Invalid orientation supplied as parameter"); + mOrientation = q; + mOrientation.normalise(); needUpdate(); } //----------------------------------------------------------------------- void Node::setOrientation( Real w, Real x, Real y, Real z) { - setOrientation(Quaternion(w, x, y, z)); + setOrientation(Quaternion(w, x, y, z)); } //----------------------------------------------------------------------- void Node::resetOrientation(void) @@ -401,7 +401,7 @@ namespace Ogre { //----------------------------------------------------------------------- void Node::setPosition(const Vector3& pos) { - assert(!pos.isNaN() && "Invalid vector supplied as parameter"); + assert(!pos.isNaN() && "Invalid vector supplied as parameter"); mPosition = pos; needUpdate(); } @@ -443,7 +443,7 @@ namespace Ogre { case TS_LOCAL: // position is relative to parent so transform downwards mPosition += mOrientation * d; - break; + break; case TS_WORLD: // position is relative to parent so transform upwards if (mParent) @@ -455,7 +455,7 @@ namespace Ogre { { mPosition += d; } - break; + break; case TS_PARENT: mPosition += d; break; @@ -508,9 +508,9 @@ namespace Ogre { //----------------------------------------------------------------------- void Node::rotate(const Quaternion& q, TransformSpace relativeTo) { - // Normalise quaternion to avoid drift - Quaternion qnorm = q; - qnorm.normalise(); + // Normalise quaternion to avoid drift + Quaternion qnorm = q; + qnorm.normalise(); switch(relativeTo) { @@ -531,38 +531,38 @@ namespace Ogre { needUpdate(); } - - //----------------------------------------------------------------------- - void Node::_setDerivedPosition( const Vector3& pos ) - { - //find where the node would end up in parent's local space + + //----------------------------------------------------------------------- + void Node::_setDerivedPosition( const Vector3& pos ) + { + //find where the node would end up in parent's local space if(mParent) setPosition( mParent->convertWorldToLocalPosition( pos ) ); - } - //----------------------------------------------------------------------- - void Node::_setDerivedOrientation( const Quaternion& q ) - { - //find where the node would end up in parent's local space + } + //----------------------------------------------------------------------- + void Node::_setDerivedOrientation( const Quaternion& q ) + { + //find where the node would end up in parent's local space if(mParent) setOrientation( mParent->convertWorldToLocalOrientation( q ) ); - } + } //----------------------------------------------------------------------- const Quaternion & Node::_getDerivedOrientation(void) const { - if (mNeedParentUpdate) - { - _updateFromParent(); - } + if (mNeedParentUpdate) + { + _updateFromParent(); + } return mDerivedOrientation; } //----------------------------------------------------------------------- const Vector3 & Node::_getDerivedPosition(void) const { - if (mNeedParentUpdate) - { - _updateFromParent(); - } + if (mNeedParentUpdate) + { + _updateFromParent(); + } return mDerivedPosition; } //----------------------------------------------------------------------- @@ -574,66 +574,66 @@ namespace Ogre { } return mDerivedScale; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- Vector3 Node::convertWorldToLocalPosition( const Vector3 &worldPos ) - { - if (mNeedParentUpdate) + { + if (mNeedParentUpdate) + { + _updateFromParent(); + } + return mDerivedOrientation.Inverse() * (worldPos - mDerivedPosition) / mDerivedScale; + } + //----------------------------------------------------------------------- + Vector3 Node::convertLocalToWorldPosition( const Vector3 &localPos ) + { + if (mNeedParentUpdate) + { + _updateFromParent(); + } + return (mDerivedOrientation * (localPos * mDerivedScale)) + mDerivedPosition; + } + //----------------------------------------------------------------------- + Quaternion Node::convertWorldToLocalOrientation( const Quaternion &worldOrientation ) + { + if (mNeedParentUpdate) { _updateFromParent(); } - return mDerivedOrientation.Inverse() * (worldPos - mDerivedPosition) / mDerivedScale; - } - //----------------------------------------------------------------------- - Vector3 Node::convertLocalToWorldPosition( const Vector3 &localPos ) - { - if (mNeedParentUpdate) + return mDerivedOrientation.Inverse() * worldOrientation; + } + //----------------------------------------------------------------------- + Quaternion Node::convertLocalToWorldOrientation( const Quaternion &localOrientation ) + { + if (mNeedParentUpdate) { _updateFromParent(); } - return (mDerivedOrientation * (localPos * mDerivedScale)) + mDerivedPosition; - } - //----------------------------------------------------------------------- - Quaternion Node::convertWorldToLocalOrientation( const Quaternion &worldOrientation ) - { - if (mNeedParentUpdate) - { - _updateFromParent(); - } - return mDerivedOrientation.Inverse() * worldOrientation; - } - //----------------------------------------------------------------------- - Quaternion Node::convertLocalToWorldOrientation( const Quaternion &localOrientation ) - { - if (mNeedParentUpdate) - { - _updateFromParent(); - } - return mDerivedOrientation * localOrientation; - - } + return mDerivedOrientation * localOrientation; + + } //----------------------------------------------------------------------- void Node::removeAllChildren(void) { - ChildNodeMap::iterator i, iend; - iend = mChildren.end(); - for (i = mChildren.begin(); i != iend; ++i) - { - i->second->setParent(0); - } + ChildNodeMap::iterator i, iend; + iend = mChildren.end(); + for (i = mChildren.begin(); i != iend; ++i) + { + i->second->setParent(0); + } mChildren.clear(); - mChildrenToUpdate.clear(); + mChildrenToUpdate.clear(); } //----------------------------------------------------------------------- void Node::setScale(const Vector3& inScale) { - assert(!inScale.isNaN() && "Invalid vector supplied as parameter"); + assert(!inScale.isNaN() && "Invalid vector supplied as parameter"); mScale = inScale; needUpdate(); } //----------------------------------------------------------------------- void Node::setScale(Real x, Real y, Real z) { - setScale(Vector3(x, y, z)); + setScale(Vector3(x, y, z)); } //----------------------------------------------------------------------- const Vector3 & Node::getScale(void) const @@ -755,11 +755,11 @@ namespace Ogre { { return ChildNodeIterator(mChildren.begin(), mChildren.end()); } - //----------------------------------------------------------------------- - Node::ConstChildNodeIterator Node::getChildIterator(void) const - { - return ConstChildNodeIterator(mChildren.begin(), mChildren.end()); - } + //----------------------------------------------------------------------- + Node::ConstChildNodeIterator Node::getChildIterator(void) const + { + return ConstChildNodeIterator(mChildren.begin(), mChildren.end()); + } //----------------------------------------------------------------------- Real Node::getSquaredViewDepth(const Camera* cam) const { @@ -773,14 +773,14 @@ namespace Ogre { { mNeedParentUpdate = true; - mNeedChildUpdate = true; + mNeedChildUpdate = true; mCachedTransformOutOfDate = true; // Make sure we're not root and parent hasn't been notified before if (mParent && (!mParentNotified || forceParentUpdate)) { mParent->requestUpdate(this, forceParentUpdate); - mParentNotified = true ; + mParentNotified = true ; } // all children will be updated @@ -798,10 +798,10 @@ namespace Ogre { mChildrenToUpdate.insert(child); // Request selective update of me, if we didn't do it before if (mParent && (!mParentNotified || forceParentUpdate)) - { + { mParent->requestUpdate(this, forceParentUpdate); - mParentNotified = true ; - } + mParentNotified = true ; + } } //----------------------------------------------------------------------- @@ -813,176 +813,176 @@ namespace Ogre { if (mChildrenToUpdate.empty() && mParent && !mNeedChildUpdate) { mParent->cancelUpdate(this); - mParentNotified = false ; + mParentNotified = false ; } } - //----------------------------------------------------------------------- - void Node::queueNeedUpdate(Node* n) - { + //----------------------------------------------------------------------- + void Node::queueNeedUpdate(Node* n) + { // Don't queue the node more than once if (!n->mQueuedForUpdate) { n->mQueuedForUpdate = true; - msQueuedUpdates.push_back(n); - } - } - //----------------------------------------------------------------------- - void Node::processQueuedUpdates(void) - { - for (QueuedUpdates::iterator i = msQueuedUpdates.begin(); - i != msQueuedUpdates.end(); ++i) - { - // Update, and force parent update since chances are we've ended - // up with some mixed state in there due to re-entrancy + msQueuedUpdates.push_back(n); + } + } + //----------------------------------------------------------------------- + void Node::processQueuedUpdates(void) + { + for (QueuedUpdates::iterator i = msQueuedUpdates.begin(); + i != msQueuedUpdates.end(); ++i) + { + // Update, and force parent update since chances are we've ended + // up with some mixed state in there due to re-entrancy Node* n = *i; n->mQueuedForUpdate = false; - n->needUpdate(true); - } - msQueuedUpdates.clear(); - } - //--------------------------------------------------------------------- - Node::DebugRenderable* Node::getDebugRenderable(Real scaling) - { - if (!mDebug) - { - mDebug = OGRE_NEW DebugRenderable(this); - } - mDebug->setScaling(scaling); - return mDebug; - } - //--------------------------------------------------------------------- - //----------------------------------------------------------------------- - Node::DebugRenderable::DebugRenderable(Node* parent) - : mParent(parent) - { - String matName = "Ogre/Debug/AxesMat"; - mMat = MaterialManager::getSingleton().getByName(matName); - if (mMat.isNull()) - { - mMat = MaterialManager::getSingleton().create(matName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); - Pass* p = mMat->getTechnique(0)->getPass(0); - p->setLightingEnabled(false); - p->setPolygonModeOverrideable(false); - p->setVertexColourTracking(TVC_AMBIENT); - p->setSceneBlending(SBT_TRANSPARENT_ALPHA); - p->setCullingMode(CULL_NONE); - p->setDepthWriteEnabled(false); - } - - String meshName = "Ogre/Debug/AxesMesh"; - mMeshPtr = MeshManager::getSingleton().getByName(meshName); - if (mMeshPtr.isNull()) - { - ManualObject mo("tmp"); - mo.begin(mMat->getName()); - /* 3 axes, each made up of 2 of these (base plane = XY) + n->needUpdate(true); + } + msQueuedUpdates.clear(); + } + //--------------------------------------------------------------------- + Node::DebugRenderable* Node::getDebugRenderable(Real scaling) + { + if (!mDebug) + { + mDebug = OGRE_NEW DebugRenderable(this); + } + mDebug->setScaling(scaling); + return mDebug; + } + //--------------------------------------------------------------------- + //----------------------------------------------------------------------- + Node::DebugRenderable::DebugRenderable(Node* parent) + : mParent(parent) + { + String matName = "Ogre/Debug/AxesMat"; + mMat = MaterialManager::getSingleton().getByName(matName); + if (mMat.isNull()) + { + mMat = MaterialManager::getSingleton().create(matName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + Pass* p = mMat->getTechnique(0)->getPass(0); + p->setLightingEnabled(false); + p->setPolygonModeOverrideable(false); + p->setVertexColourTracking(TVC_AMBIENT); + p->setSceneBlending(SBT_TRANSPARENT_ALPHA); + p->setCullingMode(CULL_NONE); + p->setDepthWriteEnabled(false); + } + + String meshName = "Ogre/Debug/AxesMesh"; + mMeshPtr = MeshManager::getSingleton().getByName(meshName); + if (mMeshPtr.isNull()) + { + ManualObject mo("tmp"); + mo.begin(mMat->getName()); + /* 3 axes, each made up of 2 of these (base plane = XY) * .------------|\ - * '------------|/ + * '------------|/ */ - mo.estimateVertexCount(7 * 2 * 3); - mo.estimateIndexCount(3 * 2 * 3); - Quaternion quat[6]; - ColourValue col[3]; - - // x-axis - quat[0] = Quaternion::IDENTITY; - quat[1].FromAxes(Vector3::UNIT_X, Vector3::NEGATIVE_UNIT_Z, Vector3::UNIT_Y); - col[0] = ColourValue::Red; - col[0].a = 0.8; - // y-axis - quat[2].FromAxes(Vector3::UNIT_Y, Vector3::NEGATIVE_UNIT_X, Vector3::UNIT_Z); - quat[3].FromAxes(Vector3::UNIT_Y, Vector3::UNIT_Z, Vector3::UNIT_X); - col[1] = ColourValue::Green; - col[1].a = 0.8; - // z-axis - quat[4].FromAxes(Vector3::UNIT_Z, Vector3::UNIT_Y, Vector3::NEGATIVE_UNIT_X); - quat[5].FromAxes(Vector3::UNIT_Z, Vector3::UNIT_X, Vector3::UNIT_Y); - col[2] = ColourValue::Blue; - col[2].a = 0.8; - - Vector3 basepos[7] = - { - // stalk - Vector3(0, 0.05, 0), - Vector3(0, -0.05, 0), - Vector3(0.7, -0.05, 0), - Vector3(0.7, 0.05, 0), - // head - Vector3(0.7, -0.15, 0), - Vector3(1, 0, 0), - Vector3(0.7, 0.15, 0) - }; - - - // vertices - // 6 arrows - for (size_t i = 0; i < 6; ++i) - { - // 7 points - for (size_t p = 0; p < 7; ++p) - { - Vector3 pos = quat[i] * basepos[p]; - mo.position(pos); - mo.colour(col[i / 2]); - } - } - - // indices - // 6 arrows - for (uint32 i = 0; i < 6; ++i) - { - uint32 base = i * 7; - mo.triangle(base + 0, base + 1, base + 2); - mo.triangle(base + 0, base + 2, base + 3); - mo.triangle(base + 4, base + 5, base + 6); - } - - mo.end(); - - mMeshPtr = mo.convertToMesh(meshName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); - - } - - } - //--------------------------------------------------------------------- - Node::DebugRenderable::~DebugRenderable() - { - } - //----------------------------------------------------------------------- - const MaterialPtr& Node::DebugRenderable::getMaterial(void) const - { - return mMat; - } - //--------------------------------------------------------------------- - void Node::DebugRenderable::getRenderOperation(RenderOperation& op) - { - return mMeshPtr->getSubMesh(0)->_getRenderOperation(op); - } - //----------------------------------------------------------------------- - void Node::DebugRenderable::getWorldTransforms(Matrix4* xform) const - { - // Assumes up to date - *xform = mParent->_getFullTransform(); - if (!Math::RealEqual(mScaling, 1.0)) - { - Matrix4 m = Matrix4::IDENTITY; - Vector3 s(mScaling, mScaling, mScaling); - m.setScale(s); - *xform = (*xform) * m; - } - } - //----------------------------------------------------------------------- - Real Node::DebugRenderable::getSquaredViewDepth(const Camera* cam) const - { - return mParent->getSquaredViewDepth(cam); - } - //----------------------------------------------------------------------- - const LightList& Node::DebugRenderable::getLights(void) const - { - // Nodes should not be lit by the scene, this will not get called - static LightList ll; - return ll; - } + mo.estimateVertexCount(7 * 2 * 3); + mo.estimateIndexCount(3 * 2 * 3); + Quaternion quat[6]; + ColourValue col[3]; + + // x-axis + quat[0] = Quaternion::IDENTITY; + quat[1].FromAxes(Vector3::UNIT_X, Vector3::NEGATIVE_UNIT_Z, Vector3::UNIT_Y); + col[0] = ColourValue::Red; + col[0].a = 0.8; + // y-axis + quat[2].FromAxes(Vector3::UNIT_Y, Vector3::NEGATIVE_UNIT_X, Vector3::UNIT_Z); + quat[3].FromAxes(Vector3::UNIT_Y, Vector3::UNIT_Z, Vector3::UNIT_X); + col[1] = ColourValue::Green; + col[1].a = 0.8; + // z-axis + quat[4].FromAxes(Vector3::UNIT_Z, Vector3::UNIT_Y, Vector3::NEGATIVE_UNIT_X); + quat[5].FromAxes(Vector3::UNIT_Z, Vector3::UNIT_X, Vector3::UNIT_Y); + col[2] = ColourValue::Blue; + col[2].a = 0.8; + + Vector3 basepos[7] = + { + // stalk + Vector3(0, 0.05, 0), + Vector3(0, -0.05, 0), + Vector3(0.7, -0.05, 0), + Vector3(0.7, 0.05, 0), + // head + Vector3(0.7, -0.15, 0), + Vector3(1, 0, 0), + Vector3(0.7, 0.15, 0) + }; + + + // vertices + // 6 arrows + for (size_t i = 0; i < 6; ++i) + { + // 7 points + for (size_t p = 0; p < 7; ++p) + { + Vector3 pos = quat[i] * basepos[p]; + mo.position(pos); + mo.colour(col[i / 2]); + } + } + + // indices + // 6 arrows + for (uint32 i = 0; i < 6; ++i) + { + uint32 base = i * 7; + mo.triangle(base + 0, base + 1, base + 2); + mo.triangle(base + 0, base + 2, base + 3); + mo.triangle(base + 4, base + 5, base + 6); + } + + mo.end(); + + mMeshPtr = mo.convertToMesh(meshName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + + } + + } + //--------------------------------------------------------------------- + Node::DebugRenderable::~DebugRenderable() + { + } + //----------------------------------------------------------------------- + const MaterialPtr& Node::DebugRenderable::getMaterial(void) const + { + return mMat; + } + //--------------------------------------------------------------------- + void Node::DebugRenderable::getRenderOperation(RenderOperation& op) + { + return mMeshPtr->getSubMesh(0)->_getRenderOperation(op); + } + //----------------------------------------------------------------------- + void Node::DebugRenderable::getWorldTransforms(Matrix4* xform) const + { + // Assumes up to date + *xform = mParent->_getFullTransform(); + if (!Math::RealEqual(mScaling, 1.0)) + { + Matrix4 m = Matrix4::IDENTITY; + Vector3 s(mScaling, mScaling, mScaling); + m.setScale(s); + *xform = (*xform) * m; + } + } + //----------------------------------------------------------------------- + Real Node::DebugRenderable::getSquaredViewDepth(const Camera* cam) const + { + return mParent->getSquaredViewDepth(cam); + } + //----------------------------------------------------------------------- + const LightList& Node::DebugRenderable::getLights(void) const + { + // Nodes should not be lit by the scene, this will not get called + static LightList ll; + return ll; + } } diff --git a/OgreMain/src/OgreNumerics.cpp b/OgreMain/src/OgreNumerics.cpp index 80a15aa2567..fabc1c1acf4 100644 --- a/OgreMain/src/OgreNumerics.cpp +++ b/OgreMain/src/OgreNumerics.cpp @@ -33,51 +33,51 @@ THE SOFTWARE. namespace Ogre { - bool NumericSolver::solveNxNLinearSysDestr(int n, PreciseReal **coeff, PreciseReal *col) - { - // we'll use standard row reduction; since we only care about systems with unique - // solutions, our job is slightly easier. more can probably be done later to improve - // precision versus this naive method + bool NumericSolver::solveNxNLinearSysDestr(int n, PreciseReal **coeff, PreciseReal *col) + { + // we'll use standard row reduction; since we only care about systems with unique + // solutions, our job is slightly easier. more can probably be done later to improve + // precision versus this naive method - int i, j; + int i, j; - for(j=0; jread(&headerV2, sizeof(PVRTCTexHeaderV2)); - stream->seek(0); - - if (PVR2_MAGIC == headerV2.pvrTag) - { - return decodeV2(stream); - } - - // Try it as pvr 3 header - PVRTCTexHeaderV3 headerV3; - stream->read(&headerV3, sizeof(PVRTCTexHeaderV3)); - stream->seek(0); - - if (PVR3_MAGIC == headerV3.version) - { - return decodeV3(stream); - } - - - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + // Assume its a pvr 2 header + PVRTCTexHeaderV2 headerV2; + stream->read(&headerV2, sizeof(PVRTCTexHeaderV2)); + stream->seek(0); + + if (PVR2_MAGIC == headerV2.pvrTag) + { + return decodeV2(stream); + } + + // Try it as pvr 3 header + PVRTCTexHeaderV3 headerV3; + stream->read(&headerV3, sizeof(PVRTCTexHeaderV3)); + stream->seek(0); + + if (PVR3_MAGIC == headerV3.version) + { + return decodeV3(stream); + } + + + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "This is not a PVR2 / PVR3 file!", "PVRTCCodec::decode"); } //--------------------------------------------------------------------- - Codec::DecodeResult PVRTCCodec::decodeV2(DataStreamPtr& stream) const - { - PVRTCTexHeaderV2 header; + Codec::DecodeResult PVRTCCodec::decodeV2(DataStreamPtr& stream) const + { + PVRTCTexHeaderV2 header; uint32 flags = 0, formatFlags = 0; size_t numFaces = 1; // Assume one face until we know otherwise ImageData *imgData = OGRE_NEW ImageData(); - MemoryDataStreamPtr output; + MemoryDataStreamPtr output; // Read the PVRTC header stream->read(&header, sizeof(PVRTCTexHeaderV2)); @@ -224,33 +224,33 @@ namespace Ogre { } // Calculate total size from number of mipmaps, faces and size - imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, + imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, imgData->width, imgData->height, imgData->depth, imgData->format); - // Bind output buffer - output.bind(OGRE_NEW MemoryDataStream(imgData->size)); + // Bind output buffer + output.bind(OGRE_NEW MemoryDataStream(imgData->size)); - // Now deal with the data - void *destPtr = output->getPtr(); + // Now deal with the data + void *destPtr = output->getPtr(); stream->read(destPtr, imgData->size); destPtr = static_cast(static_cast(destPtr)); - DecodeResult ret; - ret.first = output; - ret.second = CodecDataPtr(imgData); + DecodeResult ret; + ret.first = output; + ret.second = CodecDataPtr(imgData); - return ret; - } - //--------------------------------------------------------------------- - Codec::DecodeResult PVRTCCodec::decodeV3(DataStreamPtr& stream) const - { - PVRTCTexHeaderV3 header; + return ret; + } + //--------------------------------------------------------------------- + Codec::DecodeResult PVRTCCodec::decodeV3(DataStreamPtr& stream) const + { + PVRTCTexHeaderV3 header; PVRTCMetadata metadata; uint32 flags = 0; size_t numFaces = 1; // Assume one face until we know otherwise ImageData *imgData = OGRE_NEW ImageData(); - MemoryDataStreamPtr output; + MemoryDataStreamPtr output; // Read the PVRTC header stream->read(&header, sizeof(PVRTCTexHeaderV3)); @@ -303,14 +303,14 @@ namespace Ogre { imgData->flags |= IF_3D_TEXTURE; // Calculate total size from number of mipmaps, faces and size - imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, + imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, imgData->width, imgData->height, imgData->depth, imgData->format); - // Bind output buffer - output.bind(OGRE_NEW MemoryDataStream(imgData->size)); + // Bind output buffer + output.bind(OGRE_NEW MemoryDataStream(imgData->size)); - // Now deal with the data - void *destPtr = output->getPtr(); + // Now deal with the data + void *destPtr = output->getPtr(); uint width = imgData->width; uint height = imgData->height; @@ -318,7 +318,7 @@ namespace Ogre { // All mips for a surface, then each face for(size_t mip = 0; mip <= imgData->num_mipmaps; ++mip) - { + { for(size_t surface = 0; surface < header.numSurfaces; ++surface) { for(size_t i = 0; i < numFaces; ++i) @@ -334,14 +334,14 @@ namespace Ogre { if(width!=1) width /= 2; if(height!=1) height /= 2; if(depth!=1) depth /= 2; - } + } DecodeResult ret; - ret.first = output; - ret.second = CodecDataPtr(imgData); + ret.first = output; + ret.second = CodecDataPtr(imgData); - return ret; - } + return ret; + } //--------------------------------------------------------------------- String PVRTCCodec::getType() const { @@ -351,7 +351,7 @@ namespace Ogre { void PVRTCCodec::flipEndian(void * pData, size_t size, size_t count) const { #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - for(unsigned int index = 0; index < count; index++) + for(unsigned int index = 0; index < count; index++) { flipEndian((void *)((long)pData + (index * size)), size); } @@ -369,21 +369,21 @@ namespace Ogre { } #endif } - //--------------------------------------------------------------------- - String PVRTCCodec::magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const - { - if (maxbytes >= sizeof(uint32)) - { - uint32 fileType; - memcpy(&fileType, magicNumberPtr, sizeof(uint32)); - flipEndian(&fileType, sizeof(uint32), 1); - - if (PVR3_MAGIC == fileType || PVR2_MAGIC == fileType) - { - return String("pvr"); - } - } - - return BLANKSTRING; - } + //--------------------------------------------------------------------- + String PVRTCCodec::magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const + { + if (maxbytes >= sizeof(uint32)) + { + uint32 fileType; + memcpy(&fileType, magicNumberPtr, sizeof(uint32)); + flipEndian(&fileType, sizeof(uint32), 1); + + if (PVR3_MAGIC == fileType || PVR2_MAGIC == fileType) + { + return String("pvr"); + } + } + + return BLANKSTRING; + } } diff --git a/OgreMain/src/OgreParticle.cpp b/OgreMain/src/OgreParticle.cpp index 87f41ec2d89..d78595827ae 100644 --- a/OgreMain/src/OgreParticle.cpp +++ b/OgreMain/src/OgreParticle.cpp @@ -32,7 +32,7 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void Particle::setRotation(const Radian& rot) { mRotation = rot; diff --git a/OgreMain/src/OgreParticleEmitter.cpp b/OgreMain/src/OgreParticleEmitter.cpp index b807fa21b09..e8351a6e4a5 100644 --- a/OgreMain/src/OgreParticleEmitter.cpp +++ b/OgreMain/src/OgreParticleEmitter.cpp @@ -32,14 +32,14 @@ THE SOFTWARE. namespace Ogre { - // Define static members + // Define static members EmitterCommands::CmdAngle ParticleEmitter::msAngleCmd; EmitterCommands::CmdColour ParticleEmitter::msColourCmd; EmitterCommands::CmdColourRangeStart ParticleEmitter::msColourRangeStartCmd; EmitterCommands::CmdColourRangeEnd ParticleEmitter::msColourRangeEndCmd; EmitterCommands::CmdDirection ParticleEmitter::msDirectionCmd; EmitterCommands::CmdUp ParticleEmitter::msUpCmd; - EmitterCommands::CmdDirPositionRef ParticleEmitter::msDirPositionRefCmd; + EmitterCommands::CmdDirPositionRef ParticleEmitter::msDirPositionRefCmd; EmitterCommands::CmdEmissionRate ParticleEmitter::msEmissionRateCmd; EmitterCommands::CmdMaxTTL ParticleEmitter::msMaxTTLCmd; EmitterCommands::CmdMaxVelocity ParticleEmitter::msMaxVelocityCmd; @@ -62,7 +62,7 @@ namespace Ogre ParticleEmitter::ParticleEmitter(ParticleSystem* psys) : mParent(psys), mUseDirPositionRef(false), - mDirPositionRef(Vector3::ZERO), + mDirPositionRef(Vector3::ZERO), mStartTime(0), mDurationMin(0), mDurationMax(0), @@ -82,9 +82,9 @@ namespace Ogre mColourRangeStart = mColourRangeEnd = ColourValue::White; mEnabled = true; mRemainder = 0; - mName = BLANKSTRING; - mEmittedEmitter = BLANKSTRING; - mEmitted = false; + mName = BLANKSTRING; + mEmittedEmitter = BLANKSTRING; + mEmitted = false; } //----------------------------------------------------------------------- ParticleEmitter::~ParticleEmitter() @@ -109,7 +109,7 @@ namespace Ogre mUp = mDirection.perpendicular(); mUp.normalise(); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- const Vector3& ParticleEmitter::getDirection(void) const { return mDirection; @@ -125,23 +125,23 @@ namespace Ogre { return mUp; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void ParticleEmitter::setDirPositionReference( const Vector3& nposition, bool enable ) { - mUseDirPositionRef = enable; - mDirPositionRef = nposition; - } - //----------------------------------------------------------------------- - const Vector3& ParticleEmitter::getDirPositionReference() const - { - return mDirPositionRef; - } - //----------------------------------------------------------------------- - bool ParticleEmitter::getDirPositionReferenceEnabled() const - { - return mUseDirPositionRef; - } - //----------------------------------------------------------------------- + mUseDirPositionRef = enable; + mDirPositionRef = nposition; + } + //----------------------------------------------------------------------- + const Vector3& ParticleEmitter::getDirPositionReference() const + { + return mDirPositionRef; + } + //----------------------------------------------------------------------- + bool ParticleEmitter::getDirPositionReferenceEnabled() const + { + return mUseDirPositionRef; + } + //----------------------------------------------------------------------- void ParticleEmitter::setAngle(const Radian& angle) { // Store as radians for efficiency @@ -195,77 +195,77 @@ namespace Ogre mColourRangeStart = colourStart; mColourRangeEnd = colourEnd; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- const String& ParticleEmitter::getName(void) const { return mName; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void ParticleEmitter::setName(const String& newName) { - mName = newName; + mName = newName; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- const String& ParticleEmitter::getEmittedEmitter(void) const { return mEmittedEmitter; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void ParticleEmitter::setEmittedEmitter(const String& emittedEmitter) { mEmittedEmitter = emittedEmitter; } - //----------------------------------------------------------------------- - bool ParticleEmitter::isEmitted(void) const + //----------------------------------------------------------------------- + bool ParticleEmitter::isEmitted(void) const { - return mEmitted; + return mEmitted; } - //----------------------------------------------------------------------- - void ParticleEmitter::setEmitted(bool emitted) + //----------------------------------------------------------------------- + void ParticleEmitter::setEmitted(bool emitted) { mEmitted = emitted; } //----------------------------------------------------------------------- void ParticleEmitter::genEmissionDirection( const Vector3 &particlePos, Vector3& destVector ) { - if( mUseDirPositionRef ) - { - Vector3 particleDir = particlePos - mDirPositionRef; - particleDir.normalise(); - - if (mAngle != Radian(0)) - { - // Randomise angle - Radian angle = Math::UnitRandom() * mAngle; - - // Randomise direction - destVector = particleDir.randomDeviant( angle ); - } - else - { - // Constant angle - destVector = particleDir.normalisedCopy(); - } - } - else - { - if (mAngle != Radian(0)) - { - // Randomise angle - Radian angle = Math::UnitRandom() * mAngle; - - // Randomise direction - destVector = mDirection.randomDeviant(angle, mUp); - } - else - { - // Constant angle - destVector = mDirection; - } - } - - // Don't normalise, we can assume that it will still be a unit vector since - // both direction and 'up' are. + if( mUseDirPositionRef ) + { + Vector3 particleDir = particlePos - mDirPositionRef; + particleDir.normalise(); + + if (mAngle != Radian(0)) + { + // Randomise angle + Radian angle = Math::UnitRandom() * mAngle; + + // Randomise direction + destVector = particleDir.randomDeviant( angle ); + } + else + { + // Constant angle + destVector = particleDir.normalisedCopy(); + } + } + else + { + if (mAngle != Radian(0)) + { + // Randomise angle + Radian angle = Math::UnitRandom() * mAngle; + + // Randomise direction + destVector = mDirection.randomDeviant(angle, mUp); + } + else + { + // Constant angle + destVector = mDirection; + } + } + + // Don't normalise, we can assume that it will still be a unit vector since + // both direction and 'up' are. } //----------------------------------------------------------------------- void ParticleEmitter::genEmissionVelocity(Vector3& destVector) @@ -388,9 +388,9 @@ namespace Ogre "The up vector of the emitter." , PT_VECTOR3), &msUpCmd); - dict->addParameter(ParameterDef("direction_position_reference", + dict->addParameter(ParameterDef("direction_position_reference", "The reference position to calculate the direction of emitted particles " - "based on their position. Good for explosions and implosions (use negative velocity)" , PT_COLOURVALUE), + "based on their position. Good for explosions and implosions (use negative velocity)" , PT_COLOURVALUE), &msDirPositionRefCmd); dict->addParameter(ParameterDef("emission_rate", @@ -449,13 +449,13 @@ namespace Ogre "If set, after disabling an emitter will repeat (reenable) after this maximum number of seconds." , PT_REAL), &msMaxRepeatDelayCmd); - dict->addParameter(ParameterDef("name", - "This is the name of the emitter" , PT_STRING), - &msNameCmd); - - dict->addParameter(ParameterDef("emit_emitter", - "If set, this emitter will emit other emitters instead of visual particles" , PT_STRING), - &msEmittedEmitterCmd); + dict->addParameter(ParameterDef("name", + "This is the name of the emitter" , PT_STRING), + &msNameCmd); + + dict->addParameter(ParameterDef("emit_emitter", + "If set, this emitter will emit other emitters instead of visual particles" , PT_STRING), + &msEmittedEmitterCmd); } //----------------------------------------------------------------------- Real ParticleEmitter::getParticleVelocity(void) const diff --git a/OgreMain/src/OgreParticleEmitterCommands.cpp b/OgreMain/src/OgreParticleEmitterCommands.cpp index 29610cd78ed..1eb9c8360c7 100644 --- a/OgreMain/src/OgreParticleEmitterCommands.cpp +++ b/OgreMain/src/OgreParticleEmitterCommands.cpp @@ -95,18 +95,18 @@ namespace Ogre { { static_cast(target)->setUp(StringConverter::parseVector3(val)); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- String CmdDirPositionRef::doGet(const void* target) const { - Vector4 val( static_cast(target)->getDirPositionReference() ); - val.w = static_cast(target)->getDirPositionReferenceEnabled(); + Vector4 val( static_cast(target)->getDirPositionReference() ); + val.w = static_cast(target)->getDirPositionReferenceEnabled(); return StringConverter::toString( val ); } void CmdDirPositionRef::doSet(void* target, const String& val) { - const Vector4 parsed = StringConverter::parseVector4(val); - const Vector3 vPos( parsed.x, parsed.y, parsed.z ); - static_cast(target)->setDirPositionReference( vPos, parsed.w != 0 ); + const Vector4 parsed = StringConverter::parseVector4(val); + const Vector3 vPos( parsed.x, parsed.y, parsed.z ); + static_cast(target)->setDirPositionReference( vPos, parsed.w != 0 ); } //----------------------------------------------------------------------- String CmdEmissionRate::doGet(const void* target) const diff --git a/OgreMain/src/OgreParticleSystem.cpp b/OgreMain/src/OgreParticleSystem.cpp index 4fcb9ff996a..b1d903d7752 100644 --- a/OgreMain/src/OgreParticleSystem.cpp +++ b/OgreMain/src/OgreParticleSystem.cpp @@ -48,33 +48,33 @@ namespace Ogre { ParticleSystem::CmdHeight ParticleSystem::msHeightCmd; ParticleSystem::CmdMaterial ParticleSystem::msMaterialCmd; ParticleSystem::CmdQuota ParticleSystem::msQuotaCmd; - ParticleSystem::CmdEmittedEmitterQuota ParticleSystem::msEmittedEmitterQuotaCmd; + ParticleSystem::CmdEmittedEmitterQuota ParticleSystem::msEmittedEmitterQuotaCmd; ParticleSystem::CmdWidth ParticleSystem::msWidthCmd; ParticleSystem::CmdRenderer ParticleSystem::msRendererCmd; - ParticleSystem::CmdSorted ParticleSystem::msSortedCmd; - ParticleSystem::CmdLocalSpace ParticleSystem::msLocalSpaceCmd; - ParticleSystem::CmdIterationInterval ParticleSystem::msIterationIntervalCmd; - ParticleSystem::CmdNonvisibleTimeout ParticleSystem::msNonvisibleTimeoutCmd; + ParticleSystem::CmdSorted ParticleSystem::msSortedCmd; + ParticleSystem::CmdLocalSpace ParticleSystem::msLocalSpaceCmd; + ParticleSystem::CmdIterationInterval ParticleSystem::msIterationIntervalCmd; + ParticleSystem::CmdNonvisibleTimeout ParticleSystem::msNonvisibleTimeoutCmd; RadixSort ParticleSystem::mRadixSorter; Real ParticleSystem::msDefaultIterationInterval = 0; Real ParticleSystem::msDefaultNonvisibleTimeout = 0; - //----------------------------------------------------------------------- - // Local class for updating based on time - class ParticleSystemUpdateValue : public ControllerValue - { - protected: - ParticleSystem* mTarget; - public: - ParticleSystemUpdateValue(ParticleSystem* target) : mTarget(target) {} + //----------------------------------------------------------------------- + // Local class for updating based on time + class ParticleSystemUpdateValue : public ControllerValue + { + protected: + ParticleSystem* mTarget; + public: + ParticleSystemUpdateValue(ParticleSystem* target) : mTarget(target) {} - Real getValue(void) const { return 0; } // N/A + Real getValue(void) const { return 0; } // N/A - void setValue(Real value) { mTarget->_update(value); } + void setValue(Real value) { mTarget->_update(value); } - }; + }; //----------------------------------------------------------------------- ParticleSystem::ParticleSystem() : mAABB(), @@ -86,21 +86,21 @@ namespace Ogre { mIsRendererConfigured(false), mSpeedFactor(1.0f), mIterationInterval(0), - mIterationIntervalSet(false), + mIterationIntervalSet(false), mSorted(false), mLocalSpace(false), - mNonvisibleTimeout(0), - mNonvisibleTimeoutSet(false), - mTimeSinceLastVisible(0), - mLastVisibleFrame(0), + mNonvisibleTimeout(0), + mNonvisibleTimeoutSet(false), + mTimeSinceLastVisible(0), + mLastVisibleFrame(0), mTimeController(0), - mEmittedEmitterPoolInitialised(false), - mIsEmitting(true), + mEmittedEmitterPoolInitialised(false), + mIsEmitting(true), mRenderer(0), mCullIndividual(false), mPoolSize(0), mEmittedEmitterPoolSize(0) - { + { initParameters(); // Default to billboard renderer @@ -119,16 +119,16 @@ namespace Ogre { mIsRendererConfigured(false), mSpeedFactor(1.0f), mIterationInterval(0), - mIterationIntervalSet(false), + mIterationIntervalSet(false), mSorted(false), mLocalSpace(false), - mNonvisibleTimeout(0), - mNonvisibleTimeoutSet(false), - mTimeSinceLastVisible(0), - mLastVisibleFrame(Root::getSingleton().getNextFrameNumber()), + mNonvisibleTimeout(0), + mNonvisibleTimeoutSet(false), + mTimeSinceLastVisible(0), + mLastVisibleFrame(Root::getSingleton().getNextFrameNumber()), mTimeController(0), - mEmittedEmitterPoolInitialised(false), - mIsEmitting(true), + mEmittedEmitterPoolInitialised(false), + mIsEmitting(true), mRenderer(0), mCullIndividual(false), mPoolSize(0), @@ -138,7 +138,7 @@ namespace Ogre { setMaterialName( "BaseWhite" ); // Default to 10 particles, expect app to specify (will only be increased, not decreased) setParticleQuota( 10 ); - setEmittedEmitterQuota( 3 ); + setEmittedEmitterQuota( 3 ); initParameters(); // Default to billboard renderer @@ -154,13 +154,13 @@ namespace Ogre { mTimeController = 0; } - // Arrange for the deletion of emitters & affectors + // Arrange for the deletion of emitters & affectors removeAllEmitters(); - removeAllEmittedEmitters(); + removeAllEmittedEmitters(); removeAllAffectors(); - // Deallocate all particles - destroyVisualParticles(0, mParticlePool.size()); + // Deallocate all particles + destroyVisualParticles(0, mParticlePool.size()); // Free pool items ParticlePool::iterator i; for (i = mParticlePool.begin(); i != mParticlePool.end(); ++i) @@ -256,7 +256,7 @@ namespace Ogre { { // Blank this system's emitters & affectors removeAllEmitters(); - removeAllEmittedEmitters(); + removeAllEmittedEmitters(); removeAllAffectors(); // Copy emitters @@ -274,17 +274,17 @@ namespace Ogre { rhsAf->copyParametersTo(newAf); } setParticleQuota(rhs.getParticleQuota()); - setEmittedEmitterQuota(rhs.getEmittedEmitterQuota()); + setEmittedEmitterQuota(rhs.getEmittedEmitterQuota()); setMaterialName(rhs.mMaterialName); setDefaultDimensions(rhs.mDefaultWidth, rhs.mDefaultHeight); mCullIndividual = rhs.mCullIndividual; - mSorted = rhs.mSorted; - mLocalSpace = rhs.mLocalSpace; - mIterationInterval = rhs.mIterationInterval; - mIterationIntervalSet = rhs.mIterationIntervalSet; - mNonvisibleTimeout = rhs.mNonvisibleTimeout; - mNonvisibleTimeoutSet = rhs.mNonvisibleTimeoutSet; - // last frame visible and time since last visible should be left default + mSorted = rhs.mSorted; + mLocalSpace = rhs.mLocalSpace; + mIterationInterval = rhs.mIterationInterval; + mIterationIntervalSet = rhs.mIterationIntervalSet; + mNonvisibleTimeout = rhs.mNonvisibleTimeout; + mNonvisibleTimeoutSet = rhs.mNonvisibleTimeoutSet; + // last frame visible and time since last visible should be left default setRenderer(rhs.getRendererName()); // Copy settings @@ -319,40 +319,40 @@ namespace Ogre { } } - //----------------------------------------------------------------------- - size_t ParticleSystem::getEmittedEmitterQuota(void) const - { - return mEmittedEmitterPoolSize; - } - //----------------------------------------------------------------------- - void ParticleSystem::setEmittedEmitterQuota(size_t size) - { - // Never shrink below size() - EmittedEmitterPool::iterator i; - size_t currSize = 0; - for (i = mEmittedEmitterPool.begin(); i != mEmittedEmitterPool.end(); ++i) - { - currSize += i->second.size(); - } - - if( currSize < size ) - { - // Will allocate emitted emitters on demand - mEmittedEmitterPoolSize = size; - } - } - //----------------------------------------------------------------------- - void ParticleSystem::setNonVisibleUpdateTimeout(Real timeout) - { - mNonvisibleTimeout = timeout; - mNonvisibleTimeoutSet = true; - } - //----------------------------------------------------------------------- - void ParticleSystem::setIterationInterval(Real interval) - { - mIterationInterval = interval; - mIterationIntervalSet = true; - } + //----------------------------------------------------------------------- + size_t ParticleSystem::getEmittedEmitterQuota(void) const + { + return mEmittedEmitterPoolSize; + } + //----------------------------------------------------------------------- + void ParticleSystem::setEmittedEmitterQuota(size_t size) + { + // Never shrink below size() + EmittedEmitterPool::iterator i; + size_t currSize = 0; + for (i = mEmittedEmitterPool.begin(); i != mEmittedEmitterPool.end(); ++i) + { + currSize += i->second.size(); + } + + if( currSize < size ) + { + // Will allocate emitted emitters on demand + mEmittedEmitterPoolSize = size; + } + } + //----------------------------------------------------------------------- + void ParticleSystem::setNonVisibleUpdateTimeout(Real timeout) + { + mNonvisibleTimeout = timeout; + mNonvisibleTimeoutSet = true; + } + //----------------------------------------------------------------------- + void ParticleSystem::setIterationInterval(Real interval) + { + mIterationInterval = interval; + mIterationIntervalSet = true; + } //----------------------------------------------------------------------- void ParticleSystem::_update(Real timeElapsed) { @@ -360,35 +360,35 @@ namespace Ogre { if (!mParentNode) return; - Real nonvisibleTimeout = mNonvisibleTimeoutSet ? - mNonvisibleTimeout : msDefaultNonvisibleTimeout; - - if (nonvisibleTimeout > 0) - { - // Check whether it's been more than one frame (update is ahead of - // camera notification by one frame because of the ordering) - long frameDiff = Root::getSingleton().getNextFrameNumber() - mLastVisibleFrame; - if (frameDiff > 1 || frameDiff < 0) // < 0 if wrap only - { - mTimeSinceLastVisible += timeElapsed; - if (mTimeSinceLastVisible >= nonvisibleTimeout) - { - // No update - return; - } - } - } - - // Scale incoming speed for the rest of the calculation - timeElapsed *= mSpeedFactor; + Real nonvisibleTimeout = mNonvisibleTimeoutSet ? + mNonvisibleTimeout : msDefaultNonvisibleTimeout; + + if (nonvisibleTimeout > 0) + { + // Check whether it's been more than one frame (update is ahead of + // camera notification by one frame because of the ordering) + long frameDiff = Root::getSingleton().getNextFrameNumber() - mLastVisibleFrame; + if (frameDiff > 1 || frameDiff < 0) // < 0 if wrap only + { + mTimeSinceLastVisible += timeElapsed; + if (mTimeSinceLastVisible >= nonvisibleTimeout) + { + // No update + return; + } + } + } + + // Scale incoming speed for the rest of the calculation + timeElapsed *= mSpeedFactor; // Init renderer if not done already configureRenderer(); - // Initialise emitted emitters list if not done already - initialiseEmittedEmitters(); + // Initialise emitted emitters list if not done already + initialiseEmittedEmitters(); - Real iterationInterval = mIterationIntervalSet ? + Real iterationInterval = mIterationIntervalSet ? mIterationInterval : msDefaultIterationInterval; if (iterationInterval > 0) { @@ -401,11 +401,11 @@ namespace Ogre { _triggerAffectors(iterationInterval); _applyMotion(iterationInterval); - if(mIsEmitting) - { - // Emit new particles - _triggerEmitters(iterationInterval); - } + if(mIsEmitting) + { + // Emit new particles + _triggerEmitters(iterationInterval); + } mUpdateRemainTime -= iterationInterval; } @@ -417,11 +417,11 @@ namespace Ogre { _triggerAffectors(timeElapsed); _applyMotion(timeElapsed); - if(mIsEmitting) - { - // Emit new particles - _triggerEmitters(timeElapsed); - } + if(mIsEmitting) + { + // Emit new particles + _triggerEmitters(timeElapsed); + } } if (!mBoundsAutoUpdate && mBoundsUpdateTime > 0.0f) @@ -434,7 +434,7 @@ namespace Ogre { { ActiveParticleList::iterator i, itEnd; Particle* pParticle; - ParticleEmitter* pParticleEmitter; + ParticleEmitter* pParticleEmitter; itEnd = mActiveParticles.end(); @@ -446,31 +446,31 @@ namespace Ogre { // Notify renderer mRenderer->_notifyParticleExpired(pParticle); - // Identify the particle type - if (pParticle->mParticleType == Particle::Visual) - { - // Destroy this one - mFreeParticles.splice(mFreeParticles.end(), mActiveParticles, i++); - } - else - { - // For now, it can only be an emitted emitter - pParticleEmitter = static_cast(*i); - list::type* fee = findFreeEmittedEmitter(pParticleEmitter->getName()); - fee->push_back(pParticleEmitter); - - // Also erase from mActiveEmittedEmitters - removeFromActiveEmittedEmitters (pParticleEmitter); - - // And erase from mActiveParticles - i = mActiveParticles.erase( i ); - } + // Identify the particle type + if (pParticle->mParticleType == Particle::Visual) + { + // Destroy this one + mFreeParticles.splice(mFreeParticles.end(), mActiveParticles, i++); + } + else + { + // For now, it can only be an emitted emitter + pParticleEmitter = static_cast(*i); + list::type* fee = findFreeEmittedEmitter(pParticleEmitter->getName()); + fee->push_back(pParticleEmitter); + + // Also erase from mActiveEmittedEmitters + removeFromActiveEmittedEmitters (pParticleEmitter); + + // And erase from mActiveParticles + i = mActiveParticles.erase( i ); + } } else { // Decrement TTL pParticle->mTimeToLive -= timeElapsed; - ++i; + ++i; } } @@ -551,63 +551,63 @@ namespace Ogre { //----------------------------------------------------------------------- void ParticleSystem::_executeTriggerEmitters(ParticleEmitter* emitter, unsigned requested, Real timeElapsed) { - ParticleAffectorList::iterator itAff, itAffEnd; - Real timePoint = 0.0f; + ParticleAffectorList::iterator itAff, itAffEnd; + Real timePoint = 0.0f; // avoid any divide by zero conditions - if(!requested) - return; - - Real timeInc = timeElapsed / requested; - - for (unsigned int j = 0; j < requested; ++j) - { - // Create a new particle & init using emitter - // The particle is a visual particle if the emit_emitter property of the emitter isn't set - Particle* p = 0; - String emitterName = emitter->getEmittedEmitter(); - if (emitterName == BLANKSTRING) - p = createParticle(); - else - p = createEmitterParticle(emitterName); - - // Only continue if the particle was really created (not null) - if (!p) - return; - - emitter->_initParticle(p); - - // Translate position & direction into world space - if (!mLocalSpace) - { - p->mPosition = - (mParentNode->_getDerivedOrientation() * - (mParentNode->_getDerivedScale() * p->mPosition)) - + mParentNode->_getDerivedPosition(); - p->mDirection = - (mParentNode->_getDerivedOrientation() * p->mDirection); - } - - // apply partial frame motion to this particle + if(!requested) + return; + + Real timeInc = timeElapsed / requested; + + for (unsigned int j = 0; j < requested; ++j) + { + // Create a new particle & init using emitter + // The particle is a visual particle if the emit_emitter property of the emitter isn't set + Particle* p = 0; + String emitterName = emitter->getEmittedEmitter(); + if (emitterName == BLANKSTRING) + p = createParticle(); + else + p = createEmitterParticle(emitterName); + + // Only continue if the particle was really created (not null) + if (!p) + return; + + emitter->_initParticle(p); + + // Translate position & direction into world space + if (!mLocalSpace) + { + p->mPosition = + (mParentNode->_getDerivedOrientation() * + (mParentNode->_getDerivedScale() * p->mPosition)) + + mParentNode->_getDerivedPosition(); + p->mDirection = + (mParentNode->_getDerivedOrientation() * p->mDirection); + } + + // apply partial frame motion to this particle p->mPosition += (p->mDirection * timePoint); - // apply particle initialization by the affectors - itAffEnd = mAffectors.end(); - for (itAff = mAffectors.begin(); itAff != itAffEnd; ++itAff) - (*itAff)->_initParticle(p); + // apply particle initialization by the affectors + itAffEnd = mAffectors.end(); + for (itAff = mAffectors.begin(); itAff != itAffEnd; ++itAff) + (*itAff)->_initParticle(p); - // Increment time fragment - timePoint += timeInc; + // Increment time fragment + timePoint += timeInc; - if (p->mParticleType == Particle::Emitter) - { - // If the particle is an emitter, the position on the emitter side must also be initialised - // Note, that position of the emitter becomes a position in worldspace if mLocalSpace is set - // to false (will this become a problem?) - ParticleEmitter* pParticleEmitter = static_cast(p); - pParticleEmitter->setPosition(p->mPosition); - } + if (p->mParticleType == Particle::Emitter) + { + // If the particle is an emitter, the position on the emitter side must also be initialised + // Note, that position of the emitter becomes a position in worldspace if mLocalSpace is set + // to false (will this become a problem?) + ParticleEmitter* pParticleEmitter = static_cast(p); + pParticleEmitter->setPosition(p->mPosition); + } // Notify renderer mRenderer->_notifyParticleEmitted(p); @@ -618,7 +618,7 @@ namespace Ogre { { ActiveParticleList::iterator i, itEnd; Particle* pParticle; - ParticleEmitter* pParticleEmitter; + ParticleEmitter* pParticleEmitter; itEnd = mActiveParticles.end(); for (i = mActiveParticles.begin(); i != itEnd; ++i) @@ -626,14 +626,14 @@ namespace Ogre { pParticle = static_cast(*i); pParticle->mPosition += (pParticle->mDirection * timeElapsed); - if (pParticle->mParticleType == Particle::Emitter) - { - // If it is an emitter, the emitter position must also be updated - // Note, that position of the emitter becomes a position in worldspace if mLocalSpace is set - // to false (will this become a problem?) - pParticleEmitter = static_cast(*i); - pParticleEmitter->setPosition(pParticle->mPosition); - } + if (pParticle->mParticleType == Particle::Emitter) + { + // If it is an emitter, the emitter position must also be updated + // Note, that position of the emitter becomes a position in worldspace if mLocalSpace is set + // to false (will this become a problem?) + pParticleEmitter = static_cast(*i); + pParticleEmitter->setPosition(pParticle->mPosition); + } } // Notify renderer @@ -662,14 +662,14 @@ namespace Ogre { // Create new particles for( size_t i = oldSize; i < size; i++ ) - { + { mParticlePool[i] = OGRE_NEW Particle(); - } + } - if (mIsRendererConfigured) - { - createVisualParticles(oldSize, size); - } + if (mIsRendererConfigured) + { + createVisualParticles(oldSize, size); + } } @@ -679,25 +679,25 @@ namespace Ogre { return ParticleIterator(mActiveParticles.begin(), mActiveParticles.end()); } //----------------------------------------------------------------------- - Particle* ParticleSystem::getParticle(size_t index) - { - assert (index < mActiveParticles.size() && "Index out of bounds!"); - ActiveParticleList::iterator i = mActiveParticles.begin(); - std::advance(i, index); - return *i; - } + Particle* ParticleSystem::getParticle(size_t index) + { + assert (index < mActiveParticles.size() && "Index out of bounds!"); + ActiveParticleList::iterator i = mActiveParticles.begin(); + std::advance(i, index); + return *i; + } //----------------------------------------------------------------------- Particle* ParticleSystem::createParticle(void) { - Particle* p = 0; - if (!mFreeParticles.empty()) - { - // Fast creation (don't use superclass since emitter will init) - p = mFreeParticles.front(); - mActiveParticles.splice(mActiveParticles.end(), mFreeParticles, mFreeParticles.begin()); + Particle* p = 0; + if (!mFreeParticles.empty()) + { + // Fast creation (don't use superclass since emitter will init) + p = mFreeParticles.front(); + mActiveParticles.splice(mActiveParticles.end(), mFreeParticles, mFreeParticles.begin()); - p->_notifyOwner(this); - } + p->_notifyOwner(this); + } return p; @@ -705,23 +705,23 @@ namespace Ogre { //----------------------------------------------------------------------- Particle* ParticleSystem::createEmitterParticle(const String& emitterName) { - // Get the appropriate list and retrieve an emitter - Particle* p = 0; - list::type* fee = findFreeEmittedEmitter(emitterName); - if (fee && !fee->empty()) - { - p = fee->front(); - p->mParticleType = Particle::Emitter; - fee->pop_front(); - mActiveParticles.push_back(p); - - // Also add to mActiveEmittedEmitters. This is needed to traverse through all active emitters - // that are emitted. Don't use mActiveParticles for that (although they are added to - // mActiveParticles also), because it would take too long to traverse. - mActiveEmittedEmitters.push_back(static_cast(p)); - - p->_notifyOwner(this); - } + // Get the appropriate list and retrieve an emitter + Particle* p = 0; + list::type* fee = findFreeEmittedEmitter(emitterName); + if (fee && !fee->empty()) + { + p = fee->front(); + p->mParticleType = Particle::Emitter; + fee->pop_front(); + mActiveParticles.push_back(p); + + // Also add to mActiveEmittedEmitters. This is needed to traverse through all active emitters + // that are emitted. Don't use mActiveParticles for that (although they are added to + // mActiveParticles also), because it would take too long to traverse. + mActiveEmittedEmitters.push_back(static_cast(p)); + + p->_notifyOwner(this); + } return p; } @@ -733,16 +733,16 @@ namespace Ogre { mRenderer->_updateRenderQueue(queue, mActiveParticles, mCullIndividual); } } - //--------------------------------------------------------------------- - void ParticleSystem::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - if (mRenderer) - { - mRenderer->visitRenderables(visitor, debugRenderables); - } - } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void ParticleSystem::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + if (mRenderer) + { + mRenderer->visitRenderables(visitor, debugRenderables); + } + } + //--------------------------------------------------------------------- void ParticleSystem::initParameters(void) { if (createParamDictionary("ParticleSystem")) @@ -757,9 +757,9 @@ namespace Ogre { dict->addParameter(ParameterDef("emit_emitter_quota", "The maximum number of emitters to be emitted at once in this system.", PT_UNSIGNED_INT), - &msEmittedEmitterQuotaCmd); + &msEmittedEmitterQuotaCmd); - dict->addParameter(ParameterDef("material", + dict->addParameter(ParameterDef("material", "The name of the material to be used to render all particles in this system.", PT_STRING), &msMaterialCmd); @@ -779,32 +779,32 @@ namespace Ogre { PT_BOOL), &msCullCmd); - dict->addParameter(ParameterDef("renderer", - "Sets the particle system renderer to use (default 'billboard').", - PT_STRING), - &msRendererCmd); + dict->addParameter(ParameterDef("renderer", + "Sets the particle system renderer to use (default 'billboard').", + PT_STRING), + &msRendererCmd); - dict->addParameter(ParameterDef("sorted", - "Sets whether particles should be sorted relative to the camera. ", - PT_BOOL), - &msSortedCmd); + dict->addParameter(ParameterDef("sorted", + "Sets whether particles should be sorted relative to the camera. ", + PT_BOOL), + &msSortedCmd); - dict->addParameter(ParameterDef("local_space", - "Sets whether particles should be kept in local space rather than " - "emitted into world space. ", - PT_BOOL), - &msLocalSpaceCmd); + dict->addParameter(ParameterDef("local_space", + "Sets whether particles should be kept in local space rather than " + "emitted into world space. ", + PT_BOOL), + &msLocalSpaceCmd); - dict->addParameter(ParameterDef("iteration_interval", - "Sets a fixed update interval for the system, or 0 for the frame rate. ", - PT_REAL), - &msIterationIntervalCmd); + dict->addParameter(ParameterDef("iteration_interval", + "Sets a fixed update interval for the system, or 0 for the frame rate. ", + PT_REAL), + &msIterationIntervalCmd); - dict->addParameter(ParameterDef("nonvisible_update_timeout", - "Sets a timeout on updates to the system if the system is not visible " - "for the given number of seconds (0 to always update)", - PT_REAL), - &msNonvisibleTimeoutCmd); + dict->addParameter(ParameterDef("nonvisible_update_timeout", + "Sets a timeout on updates to the system if the system is not visible " + "for the given number of seconds (0 to always update)", + PT_REAL), + &msNonvisibleTimeoutCmd); } } @@ -891,16 +891,16 @@ namespace Ogre { _update(interval); } } - //----------------------------------------------------------------------- - void ParticleSystem::setEmitting(bool v) - { - mIsEmitting = v; - } - //----------------------------------------------------------------------- - bool ParticleSystem::getEmitting() const - { - return mIsEmitting; - } + //----------------------------------------------------------------------- + void ParticleSystem::setEmitting(bool v) + { + mIsEmitting = v; + } + //----------------------------------------------------------------------- + bool ParticleSystem::getEmitting() const + { + return mIsEmitting; + } //----------------------------------------------------------------------- const String& ParticleSystem::getMovableType(void) const { @@ -963,27 +963,27 @@ namespace Ogre { //----------------------------------------------------------------------- void ParticleSystem::_notifyCurrentCamera(Camera* cam) { - MovableObject::_notifyCurrentCamera(cam); + MovableObject::_notifyCurrentCamera(cam); - // Record visible - if (isVisible()) - { - mLastVisibleFrame = Root::getSingleton().getNextFrameNumber(); - mTimeSinceLastVisible = 0.0f; + // Record visible + if (isVisible()) + { + mLastVisibleFrame = Root::getSingleton().getNextFrameNumber(); + mTimeSinceLastVisible = 0.0f; - if (mSorted) - { - _sortParticles(cam); - } + if (mSorted) + { + _sortParticles(cam); + } - if (mRenderer) - { - if (!mIsRendererConfigured) - configureRenderer(); + if (mRenderer) + { + if (!mIsRendererConfigured) + configureRenderer(); - mRenderer->_notifyCurrentCamera(cam); - } - } + mRenderer->_notifyCurrentCamera(cam); + } + } } //----------------------------------------------------------------------- void ParticleSystem::_notifyAttached(Node* parent, bool isTagPoint) @@ -1041,28 +1041,28 @@ namespace Ogre { mFreeParticles.splice(mFreeParticles.end(), mActiveParticles); // Add active emitted emitters to free list - addActiveEmittedEmittersToFreeList(); + addActiveEmittedEmittersToFreeList(); - // Remove all active emitted emitter instances - mActiveEmittedEmitters.clear(); + // Remove all active emitted emitter instances + mActiveEmittedEmitters.clear(); - // Reset update remain time + // Reset update remain time mUpdateRemainTime = 0; } //----------------------------------------------------------------------- void ParticleSystem::setRenderer(const String& rendererName) { - if (mRenderer) - { - // Destroy existing - destroyVisualParticles(0, mParticlePool.size()); - ParticleSystemManager::getSingleton()._destroyRenderer(mRenderer); - mRenderer = 0; - } + if (mRenderer) + { + // Destroy existing + destroyVisualParticles(0, mParticlePool.size()); + ParticleSystemManager::getSingleton()._destroyRenderer(mRenderer); + mRenderer = 0; + } if (!rendererName.empty()) { - mRenderer = ParticleSystemManager::getSingleton()._createRenderer(rendererName); + mRenderer = ParticleSystemManager::getSingleton()._createRenderer(rendererName); mIsRendererConfigured = false; } } @@ -1098,9 +1098,9 @@ namespace Ogre { MaterialPtr mat = MaterialManager::getSingleton().load( mMaterialName, mResourceGroupName).staticCast(); mRenderer->_setMaterial(mat); - if (mRenderQueueIDSet) - mRenderer->setRenderQueueGroup(mRenderQueueID); - mRenderer->setKeepParticlesInLocalSpace(mLocalSpace); + if (mRenderQueueIDSet) + mRenderer->setRenderQueueGroup(mRenderQueueID); + mRenderer->setKeepParticlesInLocalSpace(mLocalSpace); mIsRendererConfigured = true; } } @@ -1132,31 +1132,31 @@ namespace Ogre { mCullIndividual = cullIndividual; } //----------------------------------------------------------------------- - void ParticleSystem::createVisualParticles(size_t poolstart, size_t poolend) - { - ParticlePool::iterator i = mParticlePool.begin(); - ParticlePool::iterator iend = mParticlePool.begin(); - std::advance(i, poolstart); - std::advance(iend, poolend); - for (; i != iend; ++i) - { - (*i)->_notifyVisualData( - mRenderer->_createVisualData()); - } - } - //----------------------------------------------------------------------- - void ParticleSystem::destroyVisualParticles(size_t poolstart, size_t poolend) - { - ParticlePool::iterator i = mParticlePool.begin(); - ParticlePool::iterator iend = mParticlePool.begin(); - std::advance(i, poolstart); - std::advance(iend, poolend); - for (; i != iend; ++i) - { - mRenderer->_destroyVisualData((*i)->getVisualData()); - (*i)->_notifyVisualData(0); - } - } + void ParticleSystem::createVisualParticles(size_t poolstart, size_t poolend) + { + ParticlePool::iterator i = mParticlePool.begin(); + ParticlePool::iterator iend = mParticlePool.begin(); + std::advance(i, poolstart); + std::advance(iend, poolend); + for (; i != iend; ++i) + { + (*i)->_notifyVisualData( + mRenderer->_createVisualData()); + } + } + //----------------------------------------------------------------------- + void ParticleSystem::destroyVisualParticles(size_t poolstart, size_t poolend) + { + ParticlePool::iterator i = mParticlePool.begin(); + ParticlePool::iterator iend = mParticlePool.begin(); + std::advance(i, poolstart); + std::advance(iend, poolend); + for (; i != iend; ++i) + { + mRenderer->_destroyVisualData((*i)->getVisualData()); + (*i)->_notifyVisualData(0); + } + } //----------------------------------------------------------------------- void ParticleSystem::setBounds(const AxisAlignedBox& aabb) { @@ -1170,33 +1170,33 @@ namespace Ogre { mBoundsAutoUpdate = autoUpdate; mBoundsUpdateTime = stopIn; } - //----------------------------------------------------------------------- - void ParticleSystem::setRenderQueueGroup(uint8 queueID) - { - MovableObject::setRenderQueueGroup(queueID); - if (mRenderer) - { - mRenderer->setRenderQueueGroup(queueID); - } - } - //----------------------------------------------------------------------- - void ParticleSystem::setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) - { - MovableObject::setRenderQueueGroupAndPriority(queueID, priority); - if (mRenderer) - { - mRenderer->setRenderQueueGroupAndPriority(queueID, priority); - } - } - //----------------------------------------------------------------------- - void ParticleSystem::setKeepParticlesInLocalSpace(bool keepLocal) - { - mLocalSpace = keepLocal; - if (mRenderer) - { - mRenderer->setKeepParticlesInLocalSpace(keepLocal); - } - } + //----------------------------------------------------------------------- + void ParticleSystem::setRenderQueueGroup(uint8 queueID) + { + MovableObject::setRenderQueueGroup(queueID); + if (mRenderer) + { + mRenderer->setRenderQueueGroup(queueID); + } + } + //----------------------------------------------------------------------- + void ParticleSystem::setRenderQueueGroupAndPriority(uint8 queueID, ushort priority) + { + MovableObject::setRenderQueueGroupAndPriority(queueID, priority); + if (mRenderer) + { + mRenderer->setRenderQueueGroupAndPriority(queueID, priority); + } + } + //----------------------------------------------------------------------- + void ParticleSystem::setKeepParticlesInLocalSpace(bool keepLocal) + { + mLocalSpace = keepLocal; + if (mRenderer) + { + mRenderer->setKeepParticlesInLocalSpace(keepLocal); + } + } //----------------------------------------------------------------------- void ParticleSystem::_sortParticles(Camera* cam) { @@ -1243,245 +1243,245 @@ namespace Ogre { // Sort descending by squared distance return - (sortPos - p->mPosition).squaredLength(); } - //----------------------------------------------------------------------- - uint32 ParticleSystem::getTypeFlags(void) const - { - return SceneManager::FX_TYPE_MASK; - } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + uint32 ParticleSystem::getTypeFlags(void) const + { + return SceneManager::FX_TYPE_MASK; + } + //----------------------------------------------------------------------- void ParticleSystem::initialiseEmittedEmitters(void) { - // Initialise the pool if needed - size_t currSize = 0; - if (mEmittedEmitterPool.empty()) - { - if (mEmittedEmitterPoolInitialised) - { - // It was already initialised, but apparently no emitted emitters were used - return; - } - else - { - initialiseEmittedEmitterPool(); - } - } - else - { - EmittedEmitterPool::iterator i; - for (i = mEmittedEmitterPool.begin(); i != mEmittedEmitterPool.end(); ++i) - { - currSize += i->second.size(); - } - } + // Initialise the pool if needed + size_t currSize = 0; + if (mEmittedEmitterPool.empty()) + { + if (mEmittedEmitterPoolInitialised) + { + // It was already initialised, but apparently no emitted emitters were used + return; + } + else + { + initialiseEmittedEmitterPool(); + } + } + else + { + EmittedEmitterPool::iterator i; + for (i = mEmittedEmitterPool.begin(); i != mEmittedEmitterPool.end(); ++i) + { + currSize += i->second.size(); + } + } size_t size = mEmittedEmitterPoolSize; if( currSize < size && !mEmittedEmitterPool.empty()) { - // Increase the pool. Equally distribute over all vectors in the map + // Increase the pool. Equally distribute over all vectors in the map increaseEmittedEmitterPool(size); - - // Add new items to the free list - addFreeEmittedEmitters(); - } - } - - //----------------------------------------------------------------------- - void ParticleSystem::initialiseEmittedEmitterPool(void) - { - if (mEmittedEmitterPoolInitialised) - return; - - // Run through mEmitters and add keys to the pool - ParticleEmitterList::iterator emitterIterator; - ParticleEmitterList::iterator emitterIteratorInner; - ParticleEmitter* emitterInner = 0; - for (emitterIterator = mEmitters.begin(); emitterIterator != mEmitters.end(); ++emitterIterator) - { - // Determine the names of all emitters that are emitted - ParticleEmitter* emitter = *emitterIterator ; - if (emitter && emitter->getEmittedEmitter() != BLANKSTRING) - { - // This one will be emitted, register its name and leave the vector empty! - EmittedEmitterList empty; - mEmittedEmitterPool.insert(make_pair(emitter->getEmittedEmitter(), empty)); - } - - // Determine whether the emitter itself will be emitted and set the 'mEmitted' attribute - for (emitterIteratorInner = mEmitters.begin(); emitterIteratorInner != mEmitters.end(); ++emitterIteratorInner) - { - emitterInner = *emitterIteratorInner; - if (emitter && - emitterInner && - emitter->getName() != BLANKSTRING && - emitter->getName() == emitterInner->getEmittedEmitter()) - { - emitter->setEmitted(true); - break; - } - else if(emitter) - { - // Set explicitly to 'false' although the default value is already 'false' - emitter->setEmitted(false); - } - } - } - - mEmittedEmitterPoolInitialised = true; - } + + // Add new items to the free list + addFreeEmittedEmitters(); + } + } + + //----------------------------------------------------------------------- + void ParticleSystem::initialiseEmittedEmitterPool(void) + { + if (mEmittedEmitterPoolInitialised) + return; + + // Run through mEmitters and add keys to the pool + ParticleEmitterList::iterator emitterIterator; + ParticleEmitterList::iterator emitterIteratorInner; + ParticleEmitter* emitterInner = 0; + for (emitterIterator = mEmitters.begin(); emitterIterator != mEmitters.end(); ++emitterIterator) + { + // Determine the names of all emitters that are emitted + ParticleEmitter* emitter = *emitterIterator ; + if (emitter && emitter->getEmittedEmitter() != BLANKSTRING) + { + // This one will be emitted, register its name and leave the vector empty! + EmittedEmitterList empty; + mEmittedEmitterPool.insert(make_pair(emitter->getEmittedEmitter(), empty)); + } + + // Determine whether the emitter itself will be emitted and set the 'mEmitted' attribute + for (emitterIteratorInner = mEmitters.begin(); emitterIteratorInner != mEmitters.end(); ++emitterIteratorInner) + { + emitterInner = *emitterIteratorInner; + if (emitter && + emitterInner && + emitter->getName() != BLANKSTRING && + emitter->getName() == emitterInner->getEmittedEmitter()) + { + emitter->setEmitted(true); + break; + } + else if(emitter) + { + // Set explicitly to 'false' although the default value is already 'false' + emitter->setEmitted(false); + } + } + } + + mEmittedEmitterPoolInitialised = true; + } //----------------------------------------------------------------------- void ParticleSystem::increaseEmittedEmitterPool(size_t size) { - // Don't proceed if the pool doesn't contain any keys of emitted emitters - if (mEmittedEmitterPool.empty()) - return; - - EmittedEmitterPool::iterator emittedEmitterPoolIterator; - ParticleEmitterList::iterator emitterIterator; - ParticleEmitter* clonedEmitter = 0; - String name = BLANKSTRING; - EmittedEmitterList* e = 0; - size_t maxNumberOfEmitters = size / mEmittedEmitterPool.size(); // equally distribute the number for each emitted emitter list - size_t oldSize = 0; - - // Run through mEmittedEmitterPool and search for every key (=name) its corresponding emitter in mEmitters - for (emittedEmitterPoolIterator = mEmittedEmitterPool.begin(); emittedEmitterPoolIterator != mEmittedEmitterPool.end(); ++emittedEmitterPoolIterator) - { - name = emittedEmitterPoolIterator->first; - e = &emittedEmitterPoolIterator->second; - - // Search the correct emitter in the mEmitters vector - for (emitterIterator = mEmitters.begin(); emitterIterator != mEmitters.end(); ++emitterIterator) - { - ParticleEmitter* emitter = *emitterIterator; - if (emitter && - name != BLANKSTRING && - name == emitter->getName()) - { - // Found the right emitter, clone each emitter a number of times - oldSize = e->size(); - for (size_t t = oldSize; t < maxNumberOfEmitters; ++t) - { - clonedEmitter = ParticleSystemManager::getSingleton()._createEmitter(emitter->getType(), this); - emitter->copyParametersTo(clonedEmitter); - clonedEmitter->setEmitted(emitter->isEmitted()); // is always 'true' by the way, but just in case - - // Initially deactivate the emitted emitter if duration/repeat_delay are set - if (clonedEmitter->getDuration() > 0.0f && - (clonedEmitter->getRepeatDelay() > 0.0f || clonedEmitter->getMinRepeatDelay() > 0.0f)) - clonedEmitter->setEnabled(false); - - // Add cloned emitters to the pool - e->push_back(clonedEmitter); - } - } - } - } - } + // Don't proceed if the pool doesn't contain any keys of emitted emitters + if (mEmittedEmitterPool.empty()) + return; + + EmittedEmitterPool::iterator emittedEmitterPoolIterator; + ParticleEmitterList::iterator emitterIterator; + ParticleEmitter* clonedEmitter = 0; + String name = BLANKSTRING; + EmittedEmitterList* e = 0; + size_t maxNumberOfEmitters = size / mEmittedEmitterPool.size(); // equally distribute the number for each emitted emitter list + size_t oldSize = 0; + + // Run through mEmittedEmitterPool and search for every key (=name) its corresponding emitter in mEmitters + for (emittedEmitterPoolIterator = mEmittedEmitterPool.begin(); emittedEmitterPoolIterator != mEmittedEmitterPool.end(); ++emittedEmitterPoolIterator) + { + name = emittedEmitterPoolIterator->first; + e = &emittedEmitterPoolIterator->second; + + // Search the correct emitter in the mEmitters vector + for (emitterIterator = mEmitters.begin(); emitterIterator != mEmitters.end(); ++emitterIterator) + { + ParticleEmitter* emitter = *emitterIterator; + if (emitter && + name != BLANKSTRING && + name == emitter->getName()) + { + // Found the right emitter, clone each emitter a number of times + oldSize = e->size(); + for (size_t t = oldSize; t < maxNumberOfEmitters; ++t) + { + clonedEmitter = ParticleSystemManager::getSingleton()._createEmitter(emitter->getType(), this); + emitter->copyParametersTo(clonedEmitter); + clonedEmitter->setEmitted(emitter->isEmitted()); // is always 'true' by the way, but just in case + + // Initially deactivate the emitted emitter if duration/repeat_delay are set + if (clonedEmitter->getDuration() > 0.0f && + (clonedEmitter->getRepeatDelay() > 0.0f || clonedEmitter->getMinRepeatDelay() > 0.0f)) + clonedEmitter->setEnabled(false); + + // Add cloned emitters to the pool + e->push_back(clonedEmitter); + } + } + } + } + } //----------------------------------------------------------------------- void ParticleSystem::addFreeEmittedEmitters(void) { - // Don't proceed if the EmittedEmitterPool is empty - if (mEmittedEmitterPool.empty()) - return; - - // Copy all pooled emitters to the free list - EmittedEmitterPool::iterator emittedEmitterPoolIterator; - EmittedEmitterList::iterator emittedEmitterIterator; - EmittedEmitterList* emittedEmitters = 0; - list::type* fee = 0; - String name = BLANKSTRING; - - // Run through the emittedEmitterPool map - for (emittedEmitterPoolIterator = mEmittedEmitterPool.begin(); emittedEmitterPoolIterator != mEmittedEmitterPool.end(); ++emittedEmitterPoolIterator) - { - name = emittedEmitterPoolIterator->first; - emittedEmitters = &emittedEmitterPoolIterator->second; - fee = findFreeEmittedEmitter(name); - - // If its not in the map, create an empty one - if (!fee) - { - FreeEmittedEmitterList empty; - mFreeEmittedEmitters.insert(make_pair(name, empty)); - fee = findFreeEmittedEmitter(name); - } - - // Check anyway if its ok now - if (!fee) - return; // forget it! - - // Add all emitted emitters from the pool to the free list - for(emittedEmitterIterator = emittedEmitters->begin(); emittedEmitterIterator != emittedEmitters->end(); ++emittedEmitterIterator) - { - fee->push_back(*emittedEmitterIterator); - } - } - } + // Don't proceed if the EmittedEmitterPool is empty + if (mEmittedEmitterPool.empty()) + return; + + // Copy all pooled emitters to the free list + EmittedEmitterPool::iterator emittedEmitterPoolIterator; + EmittedEmitterList::iterator emittedEmitterIterator; + EmittedEmitterList* emittedEmitters = 0; + list::type* fee = 0; + String name = BLANKSTRING; + + // Run through the emittedEmitterPool map + for (emittedEmitterPoolIterator = mEmittedEmitterPool.begin(); emittedEmitterPoolIterator != mEmittedEmitterPool.end(); ++emittedEmitterPoolIterator) + { + name = emittedEmitterPoolIterator->first; + emittedEmitters = &emittedEmitterPoolIterator->second; + fee = findFreeEmittedEmitter(name); + + // If its not in the map, create an empty one + if (!fee) + { + FreeEmittedEmitterList empty; + mFreeEmittedEmitters.insert(make_pair(name, empty)); + fee = findFreeEmittedEmitter(name); + } + + // Check anyway if its ok now + if (!fee) + return; // forget it! + + // Add all emitted emitters from the pool to the free list + for(emittedEmitterIterator = emittedEmitters->begin(); emittedEmitterIterator != emittedEmitters->end(); ++emittedEmitterIterator) + { + fee->push_back(*emittedEmitterIterator); + } + } + } //----------------------------------------------------------------------- void ParticleSystem::removeAllEmittedEmitters(void) { - EmittedEmitterPool::iterator emittedEmitterPoolIterator; - EmittedEmitterList::iterator emittedEmitterListIterator; - EmittedEmitterList* e = 0; + EmittedEmitterPool::iterator emittedEmitterPoolIterator; + EmittedEmitterList::iterator emittedEmitterListIterator; + EmittedEmitterList* e = 0; for (emittedEmitterPoolIterator = mEmittedEmitterPool.begin(); emittedEmitterPoolIterator != mEmittedEmitterPool.end(); ++emittedEmitterPoolIterator) { - e = &emittedEmitterPoolIterator->second; - for (emittedEmitterListIterator = e->begin(); emittedEmitterListIterator != e->end(); ++emittedEmitterListIterator) - { - ParticleSystemManager::getSingleton()._destroyEmitter(*emittedEmitterListIterator); - } - e->clear(); - } - - // Don't leave any references behind - mEmittedEmitterPool.clear(); - mFreeEmittedEmitters.clear(); - mActiveEmittedEmitters.clear(); - } - //----------------------------------------------------------------------- - list::type* ParticleSystem::findFreeEmittedEmitter (const String& name) - { - FreeEmittedEmitterMap::iterator it; - it = mFreeEmittedEmitters.find (name); - if (it != mFreeEmittedEmitters.end()) - { - // Found it - return &it->second; - } - - return 0; - } - //----------------------------------------------------------------------- - void ParticleSystem::removeFromActiveEmittedEmitters (ParticleEmitter* emitter) - { - assert(emitter && "Emitter to be removed is 0!"); - ActiveEmittedEmitterList::iterator itActiveEmit; - for (itActiveEmit = mActiveEmittedEmitters.begin(); itActiveEmit != mActiveEmittedEmitters.end(); ++itActiveEmit) - { - if (emitter == (*itActiveEmit)) - { - mActiveEmittedEmitters.erase(itActiveEmit); - break; - } - } - } - //----------------------------------------------------------------------- - void ParticleSystem::addActiveEmittedEmittersToFreeList (void) - { - ActiveEmittedEmitterList::iterator itActiveEmit; - for (itActiveEmit = mActiveEmittedEmitters.begin(); itActiveEmit != mActiveEmittedEmitters.end(); ++itActiveEmit) - { - list::type* fee = findFreeEmittedEmitter ((*itActiveEmit)->getName()); - if (fee) - fee->push_back(*itActiveEmit); - } - } - //----------------------------------------------------------------------- - void ParticleSystem::_notifyReorganiseEmittedEmitterData (void) - { - removeAllEmittedEmitters(); - mEmittedEmitterPoolInitialised = false; // Don't rearrange immediately; it will be performed in the regular flow - } + e = &emittedEmitterPoolIterator->second; + for (emittedEmitterListIterator = e->begin(); emittedEmitterListIterator != e->end(); ++emittedEmitterListIterator) + { + ParticleSystemManager::getSingleton()._destroyEmitter(*emittedEmitterListIterator); + } + e->clear(); + } + + // Don't leave any references behind + mEmittedEmitterPool.clear(); + mFreeEmittedEmitters.clear(); + mActiveEmittedEmitters.clear(); + } + //----------------------------------------------------------------------- + list::type* ParticleSystem::findFreeEmittedEmitter (const String& name) + { + FreeEmittedEmitterMap::iterator it; + it = mFreeEmittedEmitters.find (name); + if (it != mFreeEmittedEmitters.end()) + { + // Found it + return &it->second; + } + + return 0; + } + //----------------------------------------------------------------------- + void ParticleSystem::removeFromActiveEmittedEmitters (ParticleEmitter* emitter) + { + assert(emitter && "Emitter to be removed is 0!"); + ActiveEmittedEmitterList::iterator itActiveEmit; + for (itActiveEmit = mActiveEmittedEmitters.begin(); itActiveEmit != mActiveEmittedEmitters.end(); ++itActiveEmit) + { + if (emitter == (*itActiveEmit)) + { + mActiveEmittedEmitters.erase(itActiveEmit); + break; + } + } + } + //----------------------------------------------------------------------- + void ParticleSystem::addActiveEmittedEmittersToFreeList (void) + { + ActiveEmittedEmitterList::iterator itActiveEmit; + for (itActiveEmit = mActiveEmittedEmitters.begin(); itActiveEmit != mActiveEmittedEmitters.end(); ++itActiveEmit) + { + list::type* fee = findFreeEmittedEmitter ((*itActiveEmit)->getName()); + if (fee) + fee->push_back(*itActiveEmit); + } + } + //----------------------------------------------------------------------- + void ParticleSystem::_notifyReorganiseEmittedEmitterData (void) + { + removeAllEmittedEmitters(); + mEmittedEmitterPoolInitialised = false; // Don't rearrange immediately; it will be performed in the regular flow + } //----------------------------------------------------------------------- String ParticleSystem::CmdCull::doGet(const void* target) const { @@ -1555,50 +1555,50 @@ namespace Ogre { { static_cast(target)->setRenderer(val); } - //----------------------------------------------------------------------- - String ParticleSystem::CmdSorted::doGet(const void* target) const - { - return StringConverter::toString( - static_cast(target)->getSortingEnabled()); - } - void ParticleSystem::CmdSorted::doSet(void* target, const String& val) - { - static_cast(target)->setSortingEnabled( - StringConverter::parseBool(val)); - } - //----------------------------------------------------------------------- - String ParticleSystem::CmdLocalSpace::doGet(const void* target) const - { - return StringConverter::toString( - static_cast(target)->getKeepParticlesInLocalSpace()); - } - void ParticleSystem::CmdLocalSpace::doSet(void* target, const String& val) - { - static_cast(target)->setKeepParticlesInLocalSpace( - StringConverter::parseBool(val)); - } - //----------------------------------------------------------------------- - String ParticleSystem::CmdIterationInterval::doGet(const void* target) const - { - return StringConverter::toString( - static_cast(target)->getIterationInterval()); - } - void ParticleSystem::CmdIterationInterval::doSet(void* target, const String& val) - { - static_cast(target)->setIterationInterval( - StringConverter::parseReal(val)); - } - //----------------------------------------------------------------------- - String ParticleSystem::CmdNonvisibleTimeout::doGet(const void* target) const - { - return StringConverter::toString( - static_cast(target)->getNonVisibleUpdateTimeout()); - } - void ParticleSystem::CmdNonvisibleTimeout::doSet(void* target, const String& val) - { - static_cast(target)->setNonVisibleUpdateTimeout( - StringConverter::parseReal(val)); - } + //----------------------------------------------------------------------- + String ParticleSystem::CmdSorted::doGet(const void* target) const + { + return StringConverter::toString( + static_cast(target)->getSortingEnabled()); + } + void ParticleSystem::CmdSorted::doSet(void* target, const String& val) + { + static_cast(target)->setSortingEnabled( + StringConverter::parseBool(val)); + } + //----------------------------------------------------------------------- + String ParticleSystem::CmdLocalSpace::doGet(const void* target) const + { + return StringConverter::toString( + static_cast(target)->getKeepParticlesInLocalSpace()); + } + void ParticleSystem::CmdLocalSpace::doSet(void* target, const String& val) + { + static_cast(target)->setKeepParticlesInLocalSpace( + StringConverter::parseBool(val)); + } + //----------------------------------------------------------------------- + String ParticleSystem::CmdIterationInterval::doGet(const void* target) const + { + return StringConverter::toString( + static_cast(target)->getIterationInterval()); + } + void ParticleSystem::CmdIterationInterval::doSet(void* target, const String& val) + { + static_cast(target)->setIterationInterval( + StringConverter::parseReal(val)); + } + //----------------------------------------------------------------------- + String ParticleSystem::CmdNonvisibleTimeout::doGet(const void* target) const + { + return StringConverter::toString( + static_cast(target)->getNonVisibleUpdateTimeout()); + } + void ParticleSystem::CmdNonvisibleTimeout::doSet(void* target, const String& val) + { + static_cast(target)->setNonVisibleUpdateTimeout( + StringConverter::parseReal(val)); + } //----------------------------------------------------------------------- ParticleAffector::~ParticleAffector() { diff --git a/OgreMain/src/OgreParticleSystemManager.cpp b/OgreMain/src/OgreParticleSystemManager.cpp index 61a57658723..df668052a9d 100644 --- a/OgreMain/src/OgreParticleSystemManager.cpp +++ b/OgreMain/src/OgreParticleSystemManager.cpp @@ -56,8 +56,8 @@ namespace Ogre { ParticleSystemManager::ParticleSystemManager() { OGRE_LOCK_AUTO_MUTEX; - mFactory = OGRE_NEW ParticleSystemFactory(); - Root::getSingleton().addMovableObjectFactory(mFactory); + mFactory = OGRE_NEW ParticleSystemFactory(); + Root::getSingleton().addMovableObjectFactory(mFactory); } //----------------------------------------------------------------------- ParticleSystemManager::~ParticleSystemManager() @@ -74,18 +74,18 @@ namespace Ogre { ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); // delete billboard factory if (mBillboardRendererFactory) - { + { OGRE_DELETE mBillboardRendererFactory; - mBillboardRendererFactory = 0; - } + mBillboardRendererFactory = 0; + } - if (mFactory) - { - // delete particle system factory - Root::getSingleton().removeMovableObjectFactory(mFactory); - OGRE_DELETE mFactory; - mFactory = 0; - } + if (mFactory) + { + // delete particle system factory + Root::getSingleton().removeMovableObjectFactory(mFactory); + OGRE_DELETE mFactory; + mFactory = 0; + } } //----------------------------------------------------------------------- @@ -102,7 +102,7 @@ namespace Ogre { //----------------------------------------------------------------------- void ParticleSystemManager::parseScript(DataStreamPtr& stream, const String& groupName) { - ScriptCompilerManager::getSingleton().parseScript(stream, groupName); + ScriptCompilerManager::getSingleton().parseScript(stream, groupName); } //----------------------------------------------------------------------- void ParticleSystemManager::addEmitterFactory(ParticleEmitterFactory* factory) @@ -120,25 +120,25 @@ namespace Ogre { mAffectorFactories[name] = factory; LogManager::getSingleton().logMessage("Particle Affector Type '" + name + "' registered"); } - //----------------------------------------------------------------------- - void ParticleSystemManager::addRendererFactory(ParticleSystemRendererFactory* factory) - { + //----------------------------------------------------------------------- + void ParticleSystemManager::addRendererFactory(ParticleSystemRendererFactory* factory) + { OGRE_LOCK_AUTO_MUTEX ; - String name = factory->getType(); + String name = factory->getType(); mRendererFactories[name] = factory; LogManager::getSingleton().logMessage("Particle Renderer Type '" + name + "' registered"); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void ParticleSystemManager::addTemplate(const String& name, ParticleSystem* sysTemplate) { OGRE_LOCK_AUTO_MUTEX; - // check name - if (mSystemTemplates.find(name) != mSystemTemplates.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "ParticleSystem template with name '" + name + "' already exists.", - "ParticleSystemManager::addTemplate"); - } + // check name + if (mSystemTemplates.find(name) != mSystemTemplates.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "ParticleSystem template with name '" + name + "' already exists.", + "ParticleSystemManager::addTemplate"); + } mSystemTemplates[name] = sysTemplate; } @@ -174,36 +174,36 @@ namespace Ogre { void ParticleSystemManager::removeTemplatesByResourceGroup(const String& resourceGroup) { OGRE_LOCK_AUTO_MUTEX; - - ParticleTemplateMap::iterator i = mSystemTemplates.begin(); - while (i != mSystemTemplates.end()) - { - ParticleTemplateMap::iterator icur = i++; - - if(icur->second->getResourceGroupName() == resourceGroup) - { - delete icur->second; - mSystemTemplates.erase(icur); - } - } - } + + ParticleTemplateMap::iterator i = mSystemTemplates.begin(); + while (i != mSystemTemplates.end()) + { + ParticleTemplateMap::iterator icur = i++; + + if(icur->second->getResourceGroupName() == resourceGroup) + { + delete icur->second; + mSystemTemplates.erase(icur); + } + } + } //----------------------------------------------------------------------- ParticleSystem* ParticleSystemManager::createTemplate(const String& name, const String& resourceGroup) { OGRE_LOCK_AUTO_MUTEX; - // check name - if (mSystemTemplates.find(name) != mSystemTemplates.end()) - { + // check name + if (mSystemTemplates.find(name) != mSystemTemplates.end()) + { #if OGRE_PLATFORM == OGRE_PLATFORM_WINRT - LogManager::getSingleton().logMessage("ParticleSystem template with name '" + name + "' already exists."); - return NULL; + LogManager::getSingleton().logMessage("ParticleSystem template with name '" + name + "' already exists."); + return NULL; #else - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "ParticleSystem template with name '" + name + "' already exists.", - "ParticleSystemManager::createTemplate"); + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "ParticleSystem template with name '" + name + "' already exists.", + "ParticleSystemManager::createTemplate"); #endif - } + } ParticleSystem* tpl = OGRE_NEW ParticleSystem(name, resourceGroup); addTemplate(name, tpl); @@ -224,9 +224,9 @@ namespace Ogre { return 0; } } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- ParticleSystem* ParticleSystemManager::createSystemImpl(const String& name, - size_t quota, const String& resourceGroup) + size_t quota, const String& resourceGroup) { ParticleSystem* sys = OGRE_NEW ParticleSystem(name, resourceGroup); sys->setParticleQuota(quota); @@ -234,7 +234,7 @@ namespace Ogre { } //----------------------------------------------------------------------- ParticleSystem* ParticleSystemManager::createSystemImpl(const String& name, - const String& templateName) + const String& templateName) { // Look up template ParticleSystem* pTemplate = getTemplate(templateName); @@ -252,9 +252,9 @@ namespace Ogre { } //----------------------------------------------------------------------- void ParticleSystemManager::destroySystemImpl(ParticleSystem* sys) - { - OGRE_DELETE sys; - } + { + OGRE_DELETE sys; + } //----------------------------------------------------------------------- ParticleEmitter* ParticleSystemManager::_createEmitter( const String& emitterType, ParticleSystem* psys) @@ -326,7 +326,7 @@ namespace Ogre { } //----------------------------------------------------------------------- ParticleSystemRenderer* ParticleSystemManager::_createRenderer(const String& rendererType) - { + { OGRE_LOCK_AUTO_MUTEX; // Locate affector type ParticleSystemRendererFactoryMap::iterator pFact = mRendererFactories.find(rendererType); @@ -338,10 +338,10 @@ namespace Ogre { } return pFact->second->createInstance(rendererType); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void ParticleSystemManager::_destroyRenderer(ParticleSystemRenderer* renderer) - { + { if(!renderer) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot destroy a null ParticleSystemRenderer.", "ParticleSystemManager::_destroyRenderer"); @@ -356,7 +356,7 @@ namespace Ogre { } pFact->second->destroyInstance(renderer); - } + } //----------------------------------------------------------------------- void ParticleSystemManager::_initialise(void) { @@ -388,7 +388,7 @@ namespace Ogre { else { // Attribute - StringUtil::toLowerCase(line); + StringUtil::toLowerCase(line); parseEmitterAttrib(line, pEmit); } } @@ -419,7 +419,7 @@ namespace Ogre { else { // Attribute - StringUtil::toLowerCase(line); + StringUtil::toLowerCase(line); parseAffectorAttrib(line, pAff); } } @@ -500,80 +500,80 @@ namespace Ogre { } } - //----------------------------------------------------------------------- - ParticleSystemManager::ParticleAffectorFactoryIterator - ParticleSystemManager::getAffectorFactoryIterator(void) - { - return ParticleAffectorFactoryIterator( - mAffectorFactories.begin(), mAffectorFactories.end()); - } - //----------------------------------------------------------------------- - ParticleSystemManager::ParticleEmitterFactoryIterator - ParticleSystemManager::getEmitterFactoryIterator(void) - { - return ParticleEmitterFactoryIterator( - mEmitterFactories.begin(), mEmitterFactories.end()); - } - //----------------------------------------------------------------------- - ParticleSystemManager::ParticleRendererFactoryIterator - ParticleSystemManager::getRendererFactoryIterator(void) - { - return ParticleRendererFactoryIterator( - mRendererFactories.begin(), mRendererFactories.end()); - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - String ParticleSystemFactory::FACTORY_TYPE_NAME = "ParticleSystem"; - //----------------------------------------------------------------------- - MovableObject* ParticleSystemFactory::createInstanceImpl( const String& name, - const NameValuePairList* params) - { - if (params != 0) - { - NameValuePairList::const_iterator ni = params->find("templateName"); - if (ni != params->end()) - { - String templateName = ni->second; - // create using manager - return ParticleSystemManager::getSingleton().createSystemImpl( - name, templateName); - } - } - // Not template based, look for quota & resource name - size_t quota = 500; - String resourceGroup = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME; - if (params != 0) - { - NameValuePairList::const_iterator ni = params->find("quota"); - if (ni != params->end()) - { - quota = StringConverter::parseUnsignedInt(ni->second); - } - ni = params->find("resourceGroup"); - if (ni != params->end()) - { - resourceGroup = ni->second; - } - } - // create using manager - return ParticleSystemManager::getSingleton().createSystemImpl( - name, quota, resourceGroup); - - - } - //----------------------------------------------------------------------- - const String& ParticleSystemFactory::getType(void) const - { - return FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------- - void ParticleSystemFactory::destroyInstance( MovableObject* obj) - { - // use manager - ParticleSystemManager::getSingleton().destroySystemImpl( - static_cast(obj)); - - } + //----------------------------------------------------------------------- + ParticleSystemManager::ParticleAffectorFactoryIterator + ParticleSystemManager::getAffectorFactoryIterator(void) + { + return ParticleAffectorFactoryIterator( + mAffectorFactories.begin(), mAffectorFactories.end()); + } + //----------------------------------------------------------------------- + ParticleSystemManager::ParticleEmitterFactoryIterator + ParticleSystemManager::getEmitterFactoryIterator(void) + { + return ParticleEmitterFactoryIterator( + mEmitterFactories.begin(), mEmitterFactories.end()); + } + //----------------------------------------------------------------------- + ParticleSystemManager::ParticleRendererFactoryIterator + ParticleSystemManager::getRendererFactoryIterator(void) + { + return ParticleRendererFactoryIterator( + mRendererFactories.begin(), mRendererFactories.end()); + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + String ParticleSystemFactory::FACTORY_TYPE_NAME = "ParticleSystem"; + //----------------------------------------------------------------------- + MovableObject* ParticleSystemFactory::createInstanceImpl( const String& name, + const NameValuePairList* params) + { + if (params != 0) + { + NameValuePairList::const_iterator ni = params->find("templateName"); + if (ni != params->end()) + { + String templateName = ni->second; + // create using manager + return ParticleSystemManager::getSingleton().createSystemImpl( + name, templateName); + } + } + // Not template based, look for quota & resource name + size_t quota = 500; + String resourceGroup = ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME; + if (params != 0) + { + NameValuePairList::const_iterator ni = params->find("quota"); + if (ni != params->end()) + { + quota = StringConverter::parseUnsignedInt(ni->second); + } + ni = params->find("resourceGroup"); + if (ni != params->end()) + { + resourceGroup = ni->second; + } + } + // create using manager + return ParticleSystemManager::getSingleton().createSystemImpl( + name, quota, resourceGroup); + + + } + //----------------------------------------------------------------------- + const String& ParticleSystemFactory::getType(void) const + { + return FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------- + void ParticleSystemFactory::destroyInstance( MovableObject* obj) + { + // use manager + ParticleSystemManager::getSingleton().destroySystemImpl( + static_cast(obj)); + + } //----------------------------------------------------------------------- } diff --git a/OgreMain/src/OgrePass.cpp b/OgreMain/src/OgrePass.cpp index 2bcc5a8c75f..f6bf7bd06fe 100644 --- a/OgreMain/src/OgrePass.cpp +++ b/OgreMain/src/OgrePass.cpp @@ -37,233 +37,233 @@ THE SOFTWARE. namespace Ogre { - /** Default pass hash function. - @remarks - Tries to minimise the number of texture changes. - */ - struct MinTextureStateChangeHashFunc : public Pass::HashFunc - { - uint32 operator()(const Pass* p) const - { + /** Default pass hash function. + @remarks + Tries to minimise the number of texture changes. + */ + struct MinTextureStateChangeHashFunc : public Pass::HashFunc + { + uint32 operator()(const Pass* p) const + { OGRE_LOCK_MUTEX(p->mTexUnitChangeMutex); - _StringHash H; - uint32 hash = p->getIndex() << 28; - size_t c = p->getNumTextureUnitStates(); - - const TextureUnitState* t0 = 0; - const TextureUnitState* t1 = 0; - if (c) - t0 = p->getTextureUnitState(0); - if (c > 1) - t1 = p->getTextureUnitState(1); - - if (t0 && !t0->getTextureName().empty()) - hash += (static_cast(H(t0->getTextureName())) - % (1 << 14)) << 14; - if (t1 && !t1->getTextureName().empty()) - hash += (static_cast(H(t1->getTextureName())) - % (1 << 14)); - - return hash; - } - }; - MinTextureStateChangeHashFunc sMinTextureStateChangeHashFunc; - /** Alternate pass hash function. - @remarks - Tries to minimise the number of GPU program changes. - */ - struct MinGpuProgramChangeHashFunc : public Pass::HashFunc - { - uint32 operator()(const Pass* p) const - { - OGRE_LOCK_MUTEX(p->mGpuProgramChangeMutex); - - _StringHash H; - uint32 hash = p->getIndex() << 28; - if (p->hasVertexProgram()) - hash += (static_cast(H(p->getVertexProgramName())) - % (1 << 14)) << 14; - if (p->hasFragmentProgram()) - hash += (static_cast(H(p->getFragmentProgramName())) - % (1 << 14)); - if (p->hasGeometryProgram()) - hash += (static_cast(H(p->getGeometryProgramName())) - % (1 << 14)); - if (p->hasTessellationDomainProgram()) - hash += (static_cast(H(p->getTessellationDomainProgramName())) - % (1 << 14)); - if (p->hasTessellationHullProgram()) - hash += (static_cast(H(p->getTessellationHullProgramName())) - % (1 << 14)); - if (p->hasComputeProgram()) - hash += (static_cast(H(p->getComputeProgramName())) - % (1 << 14)); - - return hash; - } - }; - MinGpuProgramChangeHashFunc sMinGpuProgramChangeHashFunc; + _StringHash H; + uint32 hash = p->getIndex() << 28; + size_t c = p->getNumTextureUnitStates(); + + const TextureUnitState* t0 = 0; + const TextureUnitState* t1 = 0; + if (c) + t0 = p->getTextureUnitState(0); + if (c > 1) + t1 = p->getTextureUnitState(1); + + if (t0 && !t0->getTextureName().empty()) + hash += (static_cast(H(t0->getTextureName())) + % (1 << 14)) << 14; + if (t1 && !t1->getTextureName().empty()) + hash += (static_cast(H(t1->getTextureName())) + % (1 << 14)); + + return hash; + } + }; + MinTextureStateChangeHashFunc sMinTextureStateChangeHashFunc; + /** Alternate pass hash function. + @remarks + Tries to minimise the number of GPU program changes. + */ + struct MinGpuProgramChangeHashFunc : public Pass::HashFunc + { + uint32 operator()(const Pass* p) const + { + OGRE_LOCK_MUTEX(p->mGpuProgramChangeMutex); + + _StringHash H; + uint32 hash = p->getIndex() << 28; + if (p->hasVertexProgram()) + hash += (static_cast(H(p->getVertexProgramName())) + % (1 << 14)) << 14; + if (p->hasFragmentProgram()) + hash += (static_cast(H(p->getFragmentProgramName())) + % (1 << 14)); + if (p->hasGeometryProgram()) + hash += (static_cast(H(p->getGeometryProgramName())) + % (1 << 14)); + if (p->hasTessellationDomainProgram()) + hash += (static_cast(H(p->getTessellationDomainProgramName())) + % (1 << 14)); + if (p->hasTessellationHullProgram()) + hash += (static_cast(H(p->getTessellationHullProgramName())) + % (1 << 14)); + if (p->hasComputeProgram()) + hash += (static_cast(H(p->getComputeProgramName())) + % (1 << 14)); + + return hash; + } + }; + MinGpuProgramChangeHashFunc sMinGpuProgramChangeHashFunc; //----------------------------------------------------------------------------- - Pass::PassSet Pass::msDirtyHashList; + Pass::PassSet Pass::msDirtyHashList; Pass::PassSet Pass::msPassGraveyard; OGRE_STATIC_MUTEX_INSTANCE(Pass::msDirtyHashListMutex); OGRE_STATIC_MUTEX_INSTANCE(Pass::msPassGraveyardMutex); - Pass::HashFunc* Pass::msHashFunc = &sMinTextureStateChangeHashFunc; - //----------------------------------------------------------------------------- - Pass::HashFunc* Pass::getBuiltinHashFunction(BuiltinHashFunction builtin) - { - Pass::HashFunc* hashFunc = NULL; - - switch(builtin) - { - case MIN_TEXTURE_CHANGE: - hashFunc = &sMinTextureStateChangeHashFunc; - break; - case MIN_GPU_PROGRAM_CHANGE: - hashFunc = &sMinGpuProgramChangeHashFunc; - break; - } - - return hashFunc; - } - //----------------------------------------------------------------------------- - void Pass::setHashFunction(BuiltinHashFunction builtin) - { - switch(builtin) - { - case MIN_TEXTURE_CHANGE: - msHashFunc = &sMinTextureStateChangeHashFunc; - break; - case MIN_GPU_PROGRAM_CHANGE: - msHashFunc = &sMinGpuProgramChangeHashFunc; - break; - } - } + Pass::HashFunc* Pass::msHashFunc = &sMinTextureStateChangeHashFunc; + //----------------------------------------------------------------------------- + Pass::HashFunc* Pass::getBuiltinHashFunction(BuiltinHashFunction builtin) + { + Pass::HashFunc* hashFunc = NULL; + + switch(builtin) + { + case MIN_TEXTURE_CHANGE: + hashFunc = &sMinTextureStateChangeHashFunc; + break; + case MIN_GPU_PROGRAM_CHANGE: + hashFunc = &sMinGpuProgramChangeHashFunc; + break; + } + + return hashFunc; + } + //----------------------------------------------------------------------------- + void Pass::setHashFunction(BuiltinHashFunction builtin) + { + switch(builtin) + { + case MIN_TEXTURE_CHANGE: + msHashFunc = &sMinTextureStateChangeHashFunc; + break; + case MIN_GPU_PROGRAM_CHANGE: + msHashFunc = &sMinGpuProgramChangeHashFunc; + break; + } + } //----------------------------------------------------------------------------- - Pass::Pass(Technique* parent, unsigned short index) + Pass::Pass(Technique* parent, unsigned short index) : mParent(parent) - , mIndex(index) - , mHash(0) - , mHashDirtyQueued(false) - , mAmbient(ColourValue::White) - , mDiffuse(ColourValue::White) - , mSpecular(ColourValue::Black) - , mEmissive(ColourValue::Black) - , mShininess(0) - , mTracking(TVC_NONE) - , mSourceBlendFactor(SBF_ONE) - , mDestBlendFactor(SBF_ZERO) - , mSourceBlendFactorAlpha(SBF_ONE) - , mDestBlendFactorAlpha(SBF_ZERO) - , mSeparateBlend(false) - , mBlendOperation(SBO_ADD) - , mAlphaBlendOperation(SBO_ADD) - , mSeparateBlendOperation(false) - , mDepthCheck(true) - , mDepthWrite(true) - , mDepthFunc(CMPF_LESS_EQUAL) - , mDepthBiasConstant(0.0f) - , mDepthBiasSlopeScale(0.0f) - , mDepthBiasPerIteration(0.0f) - , mColourWrite(true) - , mAlphaRejectFunc(CMPF_ALWAYS_PASS) - , mAlphaRejectVal(0) - , mAlphaToCoverageEnabled(false) - , mTransparentSorting(true) - , mTransparentSortingForced(false) - , mCullMode(CULL_CLOCKWISE) - , mManualCullMode(MANUAL_CULL_BACK) - , mLightingEnabled(true) - , mMaxSimultaneousLights(OGRE_MAX_SIMULTANEOUS_LIGHTS) - , mStartLight(0) - , mIteratePerLight(false) - , mLightsPerIteration(1) - , mRunOnlyForOneLightType(false) - , mOnlyLightType(Light::LT_POINT) - , mLightMask(0xFFFFFFFF) - , mShadeOptions(SO_GOURAUD) - , mPolygonMode(PM_SOLID) - , mNormaliseNormals(false) - , mPolygonModeOverrideable(true) - , mFogOverride(false) - , mFogMode(FOG_NONE) - , mFogColour(ColourValue::White) - , mFogStart(0.0) - , mFogEnd(1.0) - , mFogDensity(0.001) - , mVertexProgramUsage(0) - , mShadowCasterVertexProgramUsage(0) + , mIndex(index) + , mHash(0) + , mHashDirtyQueued(false) + , mAmbient(ColourValue::White) + , mDiffuse(ColourValue::White) + , mSpecular(ColourValue::Black) + , mEmissive(ColourValue::Black) + , mShininess(0) + , mTracking(TVC_NONE) + , mSourceBlendFactor(SBF_ONE) + , mDestBlendFactor(SBF_ZERO) + , mSourceBlendFactorAlpha(SBF_ONE) + , mDestBlendFactorAlpha(SBF_ZERO) + , mSeparateBlend(false) + , mBlendOperation(SBO_ADD) + , mAlphaBlendOperation(SBO_ADD) + , mSeparateBlendOperation(false) + , mDepthCheck(true) + , mDepthWrite(true) + , mDepthFunc(CMPF_LESS_EQUAL) + , mDepthBiasConstant(0.0f) + , mDepthBiasSlopeScale(0.0f) + , mDepthBiasPerIteration(0.0f) + , mColourWrite(true) + , mAlphaRejectFunc(CMPF_ALWAYS_PASS) + , mAlphaRejectVal(0) + , mAlphaToCoverageEnabled(false) + , mTransparentSorting(true) + , mTransparentSortingForced(false) + , mCullMode(CULL_CLOCKWISE) + , mManualCullMode(MANUAL_CULL_BACK) + , mLightingEnabled(true) + , mMaxSimultaneousLights(OGRE_MAX_SIMULTANEOUS_LIGHTS) + , mStartLight(0) + , mIteratePerLight(false) + , mLightsPerIteration(1) + , mRunOnlyForOneLightType(false) + , mOnlyLightType(Light::LT_POINT) + , mLightMask(0xFFFFFFFF) + , mShadeOptions(SO_GOURAUD) + , mPolygonMode(PM_SOLID) + , mNormaliseNormals(false) + , mPolygonModeOverrideable(true) + , mFogOverride(false) + , mFogMode(FOG_NONE) + , mFogColour(ColourValue::White) + , mFogStart(0.0) + , mFogEnd(1.0) + , mFogDensity(0.001) + , mVertexProgramUsage(0) + , mShadowCasterVertexProgramUsage(0) , mShadowCasterFragmentProgramUsage(0) - , mShadowReceiverVertexProgramUsage(0) - , mFragmentProgramUsage(0) - , mShadowReceiverFragmentProgramUsage(0) + , mShadowReceiverVertexProgramUsage(0) + , mFragmentProgramUsage(0) + , mShadowReceiverFragmentProgramUsage(0) , mGeometryProgramUsage(0) - , mTessellationHullProgramUsage(0) - , mTessellationDomainProgramUsage(0) - , mComputeProgramUsage(0) - , mQueuedForDeletion(false) - , mPassIterationCount(1) - , mPointSize(1.0f) - , mPointMinSize(0.0f) - , mPointMaxSize(0.0f) - , mPointSpritesEnabled(false) - , mPointAttenuationEnabled(false) - , mContentTypeLookupBuilt(false) - , mLightScissoring(false) - , mLightClipPlanes(false) - , mIlluminationStage(IS_UNKNOWN) - { - mPointAttenuationCoeffs[0] = 1.0f; - mPointAttenuationCoeffs[1] = mPointAttenuationCoeffs[2] = 0.0f; + , mTessellationHullProgramUsage(0) + , mTessellationDomainProgramUsage(0) + , mComputeProgramUsage(0) + , mQueuedForDeletion(false) + , mPassIterationCount(1) + , mPointSize(1.0f) + , mPointMinSize(0.0f) + , mPointMaxSize(0.0f) + , mPointSpritesEnabled(false) + , mPointAttenuationEnabled(false) + , mContentTypeLookupBuilt(false) + , mLightScissoring(false) + , mLightClipPlanes(false) + , mIlluminationStage(IS_UNKNOWN) + { + mPointAttenuationCoeffs[0] = 1.0f; + mPointAttenuationCoeffs[1] = mPointAttenuationCoeffs[2] = 0.0f; // default name to index mName = StringConverter::toString(mIndex); - // init the hash inline - _recalculateHash(); + // init the hash inline + _recalculateHash(); } //----------------------------------------------------------------------------- - Pass::Pass(Technique *parent, unsigned short index, const Pass& oth) + Pass::Pass(Technique *parent, unsigned short index, const Pass& oth) :mParent(parent), mIndex(index), mVertexProgramUsage(0), mShadowCasterVertexProgramUsage(0), - mShadowCasterFragmentProgramUsage(0), mShadowReceiverVertexProgramUsage(0), mFragmentProgramUsage(0), - mShadowReceiverFragmentProgramUsage(0), mGeometryProgramUsage(0), mTessellationHullProgramUsage(0) - , mTessellationDomainProgramUsage(0), mComputeProgramUsage(0), mQueuedForDeletion(false), mPassIterationCount(1) + mShadowCasterFragmentProgramUsage(0), mShadowReceiverVertexProgramUsage(0), mFragmentProgramUsage(0), + mShadowReceiverFragmentProgramUsage(0), mGeometryProgramUsage(0), mTessellationHullProgramUsage(0) + , mTessellationDomainProgramUsage(0), mComputeProgramUsage(0), mQueuedForDeletion(false), mPassIterationCount(1) { *this = oth; mParent = parent; mIndex = index; mQueuedForDeletion = false; - // init the hash inline - _recalculateHash(); + // init the hash inline + _recalculateHash(); } //----------------------------------------------------------------------------- Pass::~Pass() { - OGRE_DELETE mVertexProgramUsage; - OGRE_DELETE mFragmentProgramUsage; - OGRE_DELETE mTessellationHullProgramUsage; - OGRE_DELETE mTessellationDomainProgramUsage; - OGRE_DELETE mGeometryProgramUsage; - OGRE_DELETE mComputeProgramUsage; - OGRE_DELETE mShadowCasterVertexProgramUsage; + OGRE_DELETE mVertexProgramUsage; + OGRE_DELETE mFragmentProgramUsage; + OGRE_DELETE mTessellationHullProgramUsage; + OGRE_DELETE mTessellationDomainProgramUsage; + OGRE_DELETE mGeometryProgramUsage; + OGRE_DELETE mComputeProgramUsage; + OGRE_DELETE mShadowCasterVertexProgramUsage; OGRE_DELETE mShadowCasterFragmentProgramUsage; - OGRE_DELETE mShadowReceiverVertexProgramUsage; - OGRE_DELETE mShadowReceiverFragmentProgramUsage; + OGRE_DELETE mShadowReceiverVertexProgramUsage; + OGRE_DELETE mShadowReceiverFragmentProgramUsage; } //----------------------------------------------------------------------------- Pass& Pass::operator=(const Pass& oth) { mName = oth.mName; mHash = oth.mHash; - mAmbient = oth.mAmbient; + mAmbient = oth.mAmbient; mDiffuse = oth.mDiffuse; - mSpecular = oth.mSpecular; + mSpecular = oth.mSpecular; mEmissive = oth.mEmissive; - mShininess = oth.mShininess; + mShininess = oth.mShininess; mTracking = oth.mTracking; // Copy fog parameters @@ -274,67 +274,67 @@ namespace Ogre { mFogEnd = oth.mFogEnd; mFogDensity = oth.mFogDensity; - // Default blending (overwrite) - mSourceBlendFactor = oth.mSourceBlendFactor; - mDestBlendFactor = oth.mDestBlendFactor; - mSourceBlendFactorAlpha = oth.mSourceBlendFactorAlpha; - mDestBlendFactorAlpha = oth.mDestBlendFactorAlpha; - mSeparateBlend = oth.mSeparateBlend; - - mBlendOperation = oth.mBlendOperation; - mAlphaBlendOperation = oth.mAlphaBlendOperation; - mSeparateBlendOperation = oth.mSeparateBlendOperation; - - mDepthCheck = oth.mDepthCheck; - mDepthWrite = oth.mDepthWrite; - mAlphaRejectFunc = oth.mAlphaRejectFunc; - mAlphaRejectVal = oth.mAlphaRejectVal; - mAlphaToCoverageEnabled = oth.mAlphaToCoverageEnabled; - mTransparentSorting = oth.mTransparentSorting; - mTransparentSortingForced = oth.mTransparentSortingForced; + // Default blending (overwrite) + mSourceBlendFactor = oth.mSourceBlendFactor; + mDestBlendFactor = oth.mDestBlendFactor; + mSourceBlendFactorAlpha = oth.mSourceBlendFactorAlpha; + mDestBlendFactorAlpha = oth.mDestBlendFactorAlpha; + mSeparateBlend = oth.mSeparateBlend; + + mBlendOperation = oth.mBlendOperation; + mAlphaBlendOperation = oth.mAlphaBlendOperation; + mSeparateBlendOperation = oth.mSeparateBlendOperation; + + mDepthCheck = oth.mDepthCheck; + mDepthWrite = oth.mDepthWrite; + mAlphaRejectFunc = oth.mAlphaRejectFunc; + mAlphaRejectVal = oth.mAlphaRejectVal; + mAlphaToCoverageEnabled = oth.mAlphaToCoverageEnabled; + mTransparentSorting = oth.mTransparentSorting; + mTransparentSortingForced = oth.mTransparentSortingForced; mColourWrite = oth.mColourWrite; - mDepthFunc = oth.mDepthFunc; + mDepthFunc = oth.mDepthFunc; mDepthBiasConstant = oth.mDepthBiasConstant; - mDepthBiasSlopeScale = oth.mDepthBiasSlopeScale; - mDepthBiasPerIteration = oth.mDepthBiasPerIteration; - mCullMode = oth.mCullMode; - mManualCullMode = oth.mManualCullMode; - mLightingEnabled = oth.mLightingEnabled; + mDepthBiasSlopeScale = oth.mDepthBiasSlopeScale; + mDepthBiasPerIteration = oth.mDepthBiasPerIteration; + mCullMode = oth.mCullMode; + mManualCullMode = oth.mManualCullMode; + mLightingEnabled = oth.mLightingEnabled; mMaxSimultaneousLights = oth.mMaxSimultaneousLights; - mStartLight = oth.mStartLight; - mIteratePerLight = oth.mIteratePerLight; - mLightsPerIteration = oth.mLightsPerIteration; + mStartLight = oth.mStartLight; + mIteratePerLight = oth.mIteratePerLight; + mLightsPerIteration = oth.mLightsPerIteration; mRunOnlyForOneLightType = oth.mRunOnlyForOneLightType; - mNormaliseNormals = oth.mNormaliseNormals; + mNormaliseNormals = oth.mNormaliseNormals; mOnlyLightType = oth.mOnlyLightType; - mShadeOptions = oth.mShadeOptions; - mPolygonMode = oth.mPolygonMode; - mPolygonModeOverrideable = oth.mPolygonModeOverrideable; + mShadeOptions = oth.mShadeOptions; + mPolygonMode = oth.mPolygonMode; + mPolygonModeOverrideable = oth.mPolygonModeOverrideable; mPassIterationCount = oth.mPassIterationCount; - mPointSize = oth.mPointSize; - mPointMinSize = oth.mPointMinSize; - mPointMaxSize = oth.mPointMaxSize; - mPointSpritesEnabled = oth.mPointSpritesEnabled; - mPointAttenuationEnabled = oth.mPointAttenuationEnabled; - memcpy(mPointAttenuationCoeffs, oth.mPointAttenuationCoeffs, sizeof(Real)*3); - mShadowContentTypeLookup = oth.mShadowContentTypeLookup; - mContentTypeLookupBuilt = oth.mContentTypeLookupBuilt; - mLightScissoring = oth.mLightScissoring; - mLightClipPlanes = oth.mLightClipPlanes; - mIlluminationStage = oth.mIlluminationStage; - mLightMask = oth.mLightMask; - - OGRE_DELETE mVertexProgramUsage; - if (oth.mVertexProgramUsage) - { - mVertexProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mVertexProgramUsage), this); - } - else - { - mVertexProgramUsage = NULL; - } - - OGRE_DELETE mShadowCasterVertexProgramUsage; + mPointSize = oth.mPointSize; + mPointMinSize = oth.mPointMinSize; + mPointMaxSize = oth.mPointMaxSize; + mPointSpritesEnabled = oth.mPointSpritesEnabled; + mPointAttenuationEnabled = oth.mPointAttenuationEnabled; + memcpy(mPointAttenuationCoeffs, oth.mPointAttenuationCoeffs, sizeof(Real)*3); + mShadowContentTypeLookup = oth.mShadowContentTypeLookup; + mContentTypeLookupBuilt = oth.mContentTypeLookupBuilt; + mLightScissoring = oth.mLightScissoring; + mLightClipPlanes = oth.mLightClipPlanes; + mIlluminationStage = oth.mIlluminationStage; + mLightMask = oth.mLightMask; + + OGRE_DELETE mVertexProgramUsage; + if (oth.mVertexProgramUsage) + { + mVertexProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mVertexProgramUsage), this); + } + else + { + mVertexProgramUsage = NULL; + } + + OGRE_DELETE mShadowCasterVertexProgramUsage; if (oth.mShadowCasterVertexProgramUsage) { mShadowCasterVertexProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mShadowCasterVertexProgramUsage), this); @@ -344,7 +344,7 @@ namespace Ogre { mShadowCasterVertexProgramUsage = NULL; } - OGRE_DELETE mShadowCasterFragmentProgramUsage; + OGRE_DELETE mShadowCasterFragmentProgramUsage; if (oth.mShadowCasterFragmentProgramUsage) { mShadowCasterFragmentProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mShadowCasterFragmentProgramUsage), this); @@ -354,7 +354,7 @@ namespace Ogre { mShadowCasterFragmentProgramUsage = NULL; } - OGRE_DELETE mShadowReceiverVertexProgramUsage; + OGRE_DELETE mShadowReceiverVertexProgramUsage; if (oth.mShadowReceiverVertexProgramUsage) { mShadowReceiverVertexProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mShadowReceiverVertexProgramUsage), this); @@ -364,67 +364,67 @@ namespace Ogre { mShadowReceiverVertexProgramUsage = NULL; } - OGRE_DELETE mFragmentProgramUsage; - if (oth.mFragmentProgramUsage) - { - mFragmentProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mFragmentProgramUsage), this); + OGRE_DELETE mFragmentProgramUsage; + if (oth.mFragmentProgramUsage) + { + mFragmentProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mFragmentProgramUsage), this); } else { - mFragmentProgramUsage = NULL; + mFragmentProgramUsage = NULL; } - OGRE_DELETE mGeometryProgramUsage; - if (oth.mGeometryProgramUsage) - { - mGeometryProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mGeometryProgramUsage), this); + OGRE_DELETE mGeometryProgramUsage; + if (oth.mGeometryProgramUsage) + { + mGeometryProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mGeometryProgramUsage), this); } else { - mGeometryProgramUsage = NULL; + mGeometryProgramUsage = NULL; } - OGRE_DELETE mTessellationHullProgramUsage; - if (oth.mTessellationHullProgramUsage) - { - mTessellationHullProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mTessellationHullProgramUsage), this); + OGRE_DELETE mTessellationHullProgramUsage; + if (oth.mTessellationHullProgramUsage) + { + mTessellationHullProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mTessellationHullProgramUsage), this); } else { - mTessellationHullProgramUsage = NULL; + mTessellationHullProgramUsage = NULL; } - OGRE_DELETE mTessellationDomainProgramUsage; - if (oth.mTessellationDomainProgramUsage) - { - mTessellationDomainProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mTessellationDomainProgramUsage), this); + OGRE_DELETE mTessellationDomainProgramUsage; + if (oth.mTessellationDomainProgramUsage) + { + mTessellationDomainProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mTessellationDomainProgramUsage), this); } else { - mTessellationDomainProgramUsage = NULL; + mTessellationDomainProgramUsage = NULL; } - OGRE_DELETE mComputeProgramUsage; - if (oth.mComputeProgramUsage) - { - mComputeProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mComputeProgramUsage), this); + OGRE_DELETE mComputeProgramUsage; + if (oth.mComputeProgramUsage) + { + mComputeProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mComputeProgramUsage), this); } else { - mComputeProgramUsage = NULL; + mComputeProgramUsage = NULL; } - OGRE_DELETE mShadowReceiverFragmentProgramUsage; - if (oth.mShadowReceiverFragmentProgramUsage) - { - mShadowReceiverFragmentProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mShadowReceiverFragmentProgramUsage), this); - } - else - { - mShadowReceiverFragmentProgramUsage = NULL; - } + OGRE_DELETE mShadowReceiverFragmentProgramUsage; + if (oth.mShadowReceiverFragmentProgramUsage) + { + mShadowReceiverFragmentProgramUsage = OGRE_NEW GpuProgramUsage(*(oth.mShadowReceiverFragmentProgramUsage), this); + } + else + { + mShadowReceiverFragmentProgramUsage = NULL; + } - TextureUnitStates::const_iterator i, iend; + TextureUnitStates::const_iterator i, iend; // Clear texture units but doesn't notify need recompilation in the case // we are cloning, The parent material will take care of this. @@ -436,17 +436,17 @@ namespace Ogre { mTextureUnitStates.clear(); - // Copy texture units - iend = oth.mTextureUnitStates.end(); - for (i = oth.mTextureUnitStates.begin(); i != iend; ++i) - { - TextureUnitState* t = OGRE_NEW TextureUnitState(this, *(*i)); - mTextureUnitStates.push_back(t); - } + // Copy texture units + iend = oth.mTextureUnitStates.end(); + for (i = oth.mTextureUnitStates.begin(); i != iend; ++i) + { + TextureUnitState* t = OGRE_NEW TextureUnitState(this, *(*i)); + mTextureUnitStates.push_back(t); + } _dirtyHash(); - return *this; + return *this; } //----------------------------------------------------------------------------- size_t Pass::calculateSize(void) const @@ -490,123 +490,123 @@ namespace Ogre { //----------------------------------------------------------------------- void Pass::setPointSize(Real ps) { - mPointSize = ps; - } - //----------------------------------------------------------------------- - void Pass::setPointSpritesEnabled(bool enabled) - { - mPointSpritesEnabled = enabled; - } - //----------------------------------------------------------------------- - bool Pass::getPointSpritesEnabled(void) const - { - return mPointSpritesEnabled; - } - //----------------------------------------------------------------------- - void Pass::setPointAttenuation(bool enabled, - Real constant, Real linear, Real quadratic) - { - mPointAttenuationEnabled = enabled; - mPointAttenuationCoeffs[0] = constant; - mPointAttenuationCoeffs[1] = linear; - mPointAttenuationCoeffs[2] = quadratic; - } - //----------------------------------------------------------------------- - bool Pass::isPointAttenuationEnabled(void) const - { - return mPointAttenuationEnabled; - } - //----------------------------------------------------------------------- - Real Pass::getPointAttenuationConstant(void) const - { - return mPointAttenuationCoeffs[0]; - } - //----------------------------------------------------------------------- - Real Pass::getPointAttenuationLinear(void) const - { - return mPointAttenuationCoeffs[1]; - } - //----------------------------------------------------------------------- - Real Pass::getPointAttenuationQuadratic(void) const - { - return mPointAttenuationCoeffs[2]; - } - //----------------------------------------------------------------------- - void Pass::setPointMinSize(Real min) - { - mPointMinSize = min; - } - //----------------------------------------------------------------------- - Real Pass::getPointMinSize(void) const - { - return mPointMinSize; - } - //----------------------------------------------------------------------- - void Pass::setPointMaxSize(Real max) - { - mPointMaxSize = max; - } - //----------------------------------------------------------------------- - Real Pass::getPointMaxSize(void) const - { - return mPointMaxSize; - } + mPointSize = ps; + } + //----------------------------------------------------------------------- + void Pass::setPointSpritesEnabled(bool enabled) + { + mPointSpritesEnabled = enabled; + } + //----------------------------------------------------------------------- + bool Pass::getPointSpritesEnabled(void) const + { + return mPointSpritesEnabled; + } + //----------------------------------------------------------------------- + void Pass::setPointAttenuation(bool enabled, + Real constant, Real linear, Real quadratic) + { + mPointAttenuationEnabled = enabled; + mPointAttenuationCoeffs[0] = constant; + mPointAttenuationCoeffs[1] = linear; + mPointAttenuationCoeffs[2] = quadratic; + } + //----------------------------------------------------------------------- + bool Pass::isPointAttenuationEnabled(void) const + { + return mPointAttenuationEnabled; + } + //----------------------------------------------------------------------- + Real Pass::getPointAttenuationConstant(void) const + { + return mPointAttenuationCoeffs[0]; + } + //----------------------------------------------------------------------- + Real Pass::getPointAttenuationLinear(void) const + { + return mPointAttenuationCoeffs[1]; + } + //----------------------------------------------------------------------- + Real Pass::getPointAttenuationQuadratic(void) const + { + return mPointAttenuationCoeffs[2]; + } + //----------------------------------------------------------------------- + void Pass::setPointMinSize(Real min) + { + mPointMinSize = min; + } + //----------------------------------------------------------------------- + Real Pass::getPointMinSize(void) const + { + return mPointMinSize; + } + //----------------------------------------------------------------------- + void Pass::setPointMaxSize(Real max) + { + mPointMaxSize = max; + } + //----------------------------------------------------------------------- + Real Pass::getPointMaxSize(void) const + { + return mPointMaxSize; + } //----------------------------------------------------------------------- void Pass::setAmbient(Real red, Real green, Real blue) { - mAmbient.r = red; - mAmbient.g = green; - mAmbient.b = blue; + mAmbient.r = red; + mAmbient.g = green; + mAmbient.b = blue; } //----------------------------------------------------------------------- void Pass::setAmbient(const ColourValue& ambient) { - mAmbient = ambient; + mAmbient = ambient; } //----------------------------------------------------------------------- void Pass::setDiffuse(Real red, Real green, Real blue, Real alpha) { - mDiffuse.r = red; - mDiffuse.g = green; - mDiffuse.b = blue; - mDiffuse.a = alpha; + mDiffuse.r = red; + mDiffuse.g = green; + mDiffuse.b = blue; + mDiffuse.a = alpha; } //----------------------------------------------------------------------- void Pass::setDiffuse(const ColourValue& diffuse) { - mDiffuse = diffuse; + mDiffuse = diffuse; } //----------------------------------------------------------------------- void Pass::setSpecular(Real red, Real green, Real blue, Real alpha) { - mSpecular.r = red; - mSpecular.g = green; - mSpecular.b = blue; - mSpecular.a = alpha; + mSpecular.r = red; + mSpecular.g = green; + mSpecular.b = blue; + mSpecular.a = alpha; } //----------------------------------------------------------------------- void Pass::setSpecular(const ColourValue& specular) { - mSpecular = specular; + mSpecular = specular; } //----------------------------------------------------------------------- void Pass::setShininess(Real val) { - mShininess = val; + mShininess = val; } //----------------------------------------------------------------------- void Pass::setSelfIllumination(Real red, Real green, Real blue) { - mEmissive.r = red; - mEmissive.g = green; - mEmissive.b = blue; + mEmissive.r = red; + mEmissive.g = green; + mEmissive.b = blue; } //----------------------------------------------------------------------- void Pass::setSelfIllumination(const ColourValue& selfIllum) { - mEmissive = selfIllum; + mEmissive = selfIllum; } //----------------------------------------------------------------------- void Pass::setVertexColourTracking(TrackVertexColourType tracking) @@ -616,32 +616,32 @@ namespace Ogre { //----------------------------------------------------------------------- Real Pass::getPointSize(void) const { - return mPointSize; + return mPointSize; } //----------------------------------------------------------------------- const ColourValue& Pass::getAmbient(void) const { - return mAmbient; + return mAmbient; } //----------------------------------------------------------------------- const ColourValue& Pass::getDiffuse(void) const { - return mDiffuse; + return mDiffuse; } //----------------------------------------------------------------------- const ColourValue& Pass::getSpecular(void) const { - return mSpecular; + return mSpecular; } //----------------------------------------------------------------------- const ColourValue& Pass::getSelfIllumination(void) const { - return mEmissive; + return mEmissive; } //----------------------------------------------------------------------- Real Pass::getShininess(void) const { - return mShininess; + return mShininess; } //----------------------------------------------------------------------- TrackVertexColourType Pass::getVertexColourTracking(void) const @@ -653,23 +653,23 @@ namespace Ogre { { TextureUnitState *t = OGRE_NEW TextureUnitState(this); addTextureUnitState(t); - mContentTypeLookupBuilt = false; - return t; + mContentTypeLookupBuilt = false; + return t; } //----------------------------------------------------------------------- TextureUnitState* Pass::createTextureUnitState( const String& textureName, unsigned short texCoordSet) { TextureUnitState *t = OGRE_NEW TextureUnitState(this); - t->setTextureName(textureName); - t->setTextureCoordSet(texCoordSet); + t->setTextureName(textureName); + t->setTextureCoordSet(texCoordSet); addTextureUnitState(t); - mContentTypeLookupBuilt = false; - return t; + mContentTypeLookupBuilt = false; + return t; } //----------------------------------------------------------------------- - void Pass::addTextureUnitState(TextureUnitState* state) - { + void Pass::addTextureUnitState(TextureUnitState* state) + { OGRE_LOCK_MUTEX(mTexUnitChangeMutex); assert(state && "state is 0 in Pass::addTextureUnitState()"); @@ -678,23 +678,23 @@ namespace Ogre { // only attach TUS to pass if TUS does not belong to another pass if ((state->getParent() == 0) || (state->getParent() == this)) { - mTextureUnitStates.push_back(state); - // Notify state - state->_notifyParent(this); + mTextureUnitStates.push_back(state); + // Notify state + state->_notifyParent(this); // if texture unit state name is empty then give it a default name based on its index if (state->getName().empty()) { // its the last entry in the container so its index is size - 1 size_t idx = mTextureUnitStates.size() - 1; - // allow 8 digit hex number. there should never be that many texture units. - // This sprintf replaced a call to StringConverter::toString for performance reasons - char buff[9]; - memset(buff, 0, 9); - sprintf(buff, "%lx", static_cast(idx)); + // allow 8 digit hex number. there should never be that many texture units. + // This sprintf replaced a call to StringConverter::toString for performance reasons + char buff[9]; + memset(buff, 0, 9); + sprintf(buff, "%lx", static_cast(idx)); state->setName( buff ); - /** since the name was never set and a default one has been made, clear the alias name + /** since the name was never set and a default one has been made, clear the alias name so that when the texture unit name is set by the user, the alias name will be set to that name */ @@ -706,19 +706,19 @@ namespace Ogre { } else { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "TextureUnitState already attached to another pass", - "Pass:addTextureUnitState"); + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "TextureUnitState already attached to another pass", + "Pass:addTextureUnitState"); } - mContentTypeLookupBuilt = false; + mContentTypeLookupBuilt = false; } - } + } //----------------------------------------------------------------------- TextureUnitState* Pass::getTextureUnitState(unsigned short index) { OGRE_LOCK_MUTEX(mTexUnitChangeMutex); assert (index < mTextureUnitStates.size() && "Index out of bounds"); - return mTextureUnitStates[index]; + return mTextureUnitStates[index]; } //----------------------------------------------------------------------------- TextureUnitState* Pass::getTextureUnitState(const String& name) @@ -742,35 +742,35 @@ namespace Ogre { return foundTUS; } - //----------------------------------------------------------------------- - const TextureUnitState* Pass::getTextureUnitState(unsigned short index) const - { + //----------------------------------------------------------------------- + const TextureUnitState* Pass::getTextureUnitState(unsigned short index) const + { OGRE_LOCK_MUTEX(mTexUnitChangeMutex); - assert (index < mTextureUnitStates.size() && "Index out of bounds"); - return mTextureUnitStates[index]; - } - //----------------------------------------------------------------------------- - const TextureUnitState* Pass::getTextureUnitState(const String& name) const - { + assert (index < mTextureUnitStates.size() && "Index out of bounds"); + return mTextureUnitStates[index]; + } + //----------------------------------------------------------------------------- + const TextureUnitState* Pass::getTextureUnitState(const String& name) const + { OGRE_LOCK_MUTEX(mTexUnitChangeMutex); - TextureUnitStates::const_iterator i = mTextureUnitStates.begin(); - TextureUnitStates::const_iterator iend = mTextureUnitStates.end(); - const TextureUnitState* foundTUS = 0; + TextureUnitStates::const_iterator i = mTextureUnitStates.begin(); + TextureUnitStates::const_iterator iend = mTextureUnitStates.end(); + const TextureUnitState* foundTUS = 0; - // iterate through TUS Container to find a match - while (i != iend) - { - if ( (*i)->getName() == name ) - { - foundTUS = (*i); - break; - } + // iterate through TUS Container to find a match + while (i != iend) + { + if ( (*i)->getName() == name ) + { + foundTUS = (*i); + break; + } - ++i; - } + ++i; + } - return foundTUS; - } + return foundTUS; + } //----------------------------------------------------------------------- unsigned short Pass::getTextureUnitStateIndex(const TextureUnitState* state) const @@ -788,8 +788,8 @@ namespace Ogre { } else { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "TextureUnitState is not attached to this pass", - "Pass:getTextureUnitStateIndex"); + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "TextureUnitState is not attached to this pass", + "Pass:getTextureUnitStateIndex"); } } @@ -799,12 +799,12 @@ namespace Ogre { { return TextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end()); } - //----------------------------------------------------------------------- - Pass::ConstTextureUnitStateIterator - Pass::getTextureUnitStateIterator(void) const - { - return ConstTextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end()); - } + //----------------------------------------------------------------------- + Pass::ConstTextureUnitStateIterator + Pass::getTextureUnitStateIterator(void) const + { + return ConstTextureUnitStateIterator(mTextureUnitStates.begin(), mTextureUnitStates.end()); + } //----------------------------------------------------------------------- void Pass::removeTextureUnitState(unsigned short index) { @@ -813,14 +813,14 @@ namespace Ogre { TextureUnitStates::iterator i = mTextureUnitStates.begin() + index; OGRE_DELETE *i; - mTextureUnitStates.erase(i); + mTextureUnitStates.erase(i); if (!mQueuedForDeletion) { // Needs recompilation mParent->_notifyNeedsRecompile(); } _dirtyHash(); - mContentTypeLookupBuilt = false; + mContentTypeLookupBuilt = false; } //----------------------------------------------------------------------- void Pass::removeAllTextureUnitStates(void) @@ -839,260 +839,260 @@ namespace Ogre { mParent->_notifyNeedsRecompile(); } _dirtyHash(); - mContentTypeLookupBuilt = false; - } - //----------------------------------------------------------------------- - void Pass::_getBlendFlags(SceneBlendType type, SceneBlendFactor& source, SceneBlendFactor& dest) - { - switch ( type ) - { - case SBT_TRANSPARENT_ALPHA: - source = SBF_SOURCE_ALPHA; - dest = SBF_ONE_MINUS_SOURCE_ALPHA; - return; - case SBT_TRANSPARENT_COLOUR: - source = SBF_SOURCE_COLOUR; - dest = SBF_ONE_MINUS_SOURCE_COLOUR; - return; - case SBT_MODULATE: - source = SBF_DEST_COLOUR; - dest = SBF_ZERO; - return; - case SBT_ADD: - source = SBF_ONE; - dest = SBF_ONE; - return; + mContentTypeLookupBuilt = false; + } + //----------------------------------------------------------------------- + void Pass::_getBlendFlags(SceneBlendType type, SceneBlendFactor& source, SceneBlendFactor& dest) + { + switch ( type ) + { + case SBT_TRANSPARENT_ALPHA: + source = SBF_SOURCE_ALPHA; + dest = SBF_ONE_MINUS_SOURCE_ALPHA; + return; + case SBT_TRANSPARENT_COLOUR: + source = SBF_SOURCE_COLOUR; + dest = SBF_ONE_MINUS_SOURCE_COLOUR; + return; + case SBT_MODULATE: + source = SBF_DEST_COLOUR; + dest = SBF_ZERO; + return; + case SBT_ADD: + source = SBF_ONE; + dest = SBF_ONE; + return; case SBT_REPLACE: source = SBF_ONE; - dest = SBF_ZERO; + dest = SBF_ZERO; return; - } + } - // Default to SBT_REPLACE + // Default to SBT_REPLACE - source = SBF_ONE; - dest = SBF_ZERO; - } + source = SBF_ONE; + dest = SBF_ZERO; + } //----------------------------------------------------------------------- void Pass::setSceneBlending(SceneBlendType sbt) { - // Convert type into blend factors + // Convert type into blend factors - SceneBlendFactor source; - SceneBlendFactor dest; - _getBlendFlags(sbt, source, dest); + SceneBlendFactor source; + SceneBlendFactor dest; + _getBlendFlags(sbt, source, dest); - // Set blend factors + // Set blend factors - setSceneBlending(source, dest); + setSceneBlending(source, dest); } - //----------------------------------------------------------------------- - void Pass::setSeparateSceneBlending( const SceneBlendType sbt, const SceneBlendType sbta ) - { - // Convert types into blend factors + //----------------------------------------------------------------------- + void Pass::setSeparateSceneBlending( const SceneBlendType sbt, const SceneBlendType sbta ) + { + // Convert types into blend factors - SceneBlendFactor source; - SceneBlendFactor dest; - _getBlendFlags(sbt, source, dest); + SceneBlendFactor source; + SceneBlendFactor dest; + _getBlendFlags(sbt, source, dest); - SceneBlendFactor sourceAlpha; - SceneBlendFactor destAlpha; - _getBlendFlags(sbta, sourceAlpha, destAlpha); + SceneBlendFactor sourceAlpha; + SceneBlendFactor destAlpha; + _getBlendFlags(sbta, sourceAlpha, destAlpha); - // Set blend factors + // Set blend factors - setSeparateSceneBlending(source, dest, sourceAlpha, destAlpha); - } + setSeparateSceneBlending(source, dest, sourceAlpha, destAlpha); + } //----------------------------------------------------------------------- void Pass::setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor) { - mSourceBlendFactor = sourceFactor; - mDestBlendFactor = destFactor; + mSourceBlendFactor = sourceFactor; + mDestBlendFactor = destFactor; - mSeparateBlend = false; + mSeparateBlend = false; } - //----------------------------------------------------------------------- - void Pass::setSeparateSceneBlending( const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor, const SceneBlendFactor sourceFactorAlpha, const SceneBlendFactor destFactorAlpha ) - { - mSourceBlendFactor = sourceFactor; - mDestBlendFactor = destFactor; - mSourceBlendFactorAlpha = sourceFactorAlpha; - mDestBlendFactorAlpha = destFactorAlpha; + //----------------------------------------------------------------------- + void Pass::setSeparateSceneBlending( const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor, const SceneBlendFactor sourceFactorAlpha, const SceneBlendFactor destFactorAlpha ) + { + mSourceBlendFactor = sourceFactor; + mDestBlendFactor = destFactor; + mSourceBlendFactorAlpha = sourceFactorAlpha; + mDestBlendFactorAlpha = destFactorAlpha; - mSeparateBlend = true; - } + mSeparateBlend = true; + } //----------------------------------------------------------------------- SceneBlendFactor Pass::getSourceBlendFactor(void) const { - return mSourceBlendFactor; + return mSourceBlendFactor; } //----------------------------------------------------------------------- SceneBlendFactor Pass::getDestBlendFactor(void) const { - return mDestBlendFactor; + return mDestBlendFactor; } //----------------------------------------------------------------------- SceneBlendFactor Pass::getSourceBlendFactorAlpha(void) const { - return mSourceBlendFactorAlpha; + return mSourceBlendFactorAlpha; } //----------------------------------------------------------------------- SceneBlendFactor Pass::getDestBlendFactorAlpha(void) const { - return mDestBlendFactorAlpha; - } - //----------------------------------------------------------------------- - bool Pass::hasSeparateSceneBlending() const - { - return mSeparateBlend; - } - //----------------------------------------------------------------------- - void Pass::setSceneBlendingOperation(SceneBlendOperation op) - { - mBlendOperation = op; - mSeparateBlendOperation = false; - } - //----------------------------------------------------------------------- - void Pass::setSeparateSceneBlendingOperation(SceneBlendOperation op, SceneBlendOperation alphaOp) - { - mBlendOperation = op; - mAlphaBlendOperation = alphaOp; - mSeparateBlendOperation = true; - } - //----------------------------------------------------------------------- - SceneBlendOperation Pass::getSceneBlendingOperation() const - { - return mBlendOperation; - } - //----------------------------------------------------------------------- - SceneBlendOperation Pass::getSceneBlendingOperationAlpha() const - { - return mAlphaBlendOperation; - } - //----------------------------------------------------------------------- - bool Pass::hasSeparateSceneBlendingOperations() const - { - return mSeparateBlendOperation; - } + return mDestBlendFactorAlpha; + } + //----------------------------------------------------------------------- + bool Pass::hasSeparateSceneBlending() const + { + return mSeparateBlend; + } + //----------------------------------------------------------------------- + void Pass::setSceneBlendingOperation(SceneBlendOperation op) + { + mBlendOperation = op; + mSeparateBlendOperation = false; + } + //----------------------------------------------------------------------- + void Pass::setSeparateSceneBlendingOperation(SceneBlendOperation op, SceneBlendOperation alphaOp) + { + mBlendOperation = op; + mAlphaBlendOperation = alphaOp; + mSeparateBlendOperation = true; + } + //----------------------------------------------------------------------- + SceneBlendOperation Pass::getSceneBlendingOperation() const + { + return mBlendOperation; + } + //----------------------------------------------------------------------- + SceneBlendOperation Pass::getSceneBlendingOperationAlpha() const + { + return mAlphaBlendOperation; + } + //----------------------------------------------------------------------- + bool Pass::hasSeparateSceneBlendingOperations() const + { + return mSeparateBlendOperation; + } //----------------------------------------------------------------------- bool Pass::isTransparent(void) const { - // Transparent if any of the destination colour is taken into account - if (mDestBlendFactor == SBF_ZERO && - mSourceBlendFactor != SBF_DEST_COLOUR && - mSourceBlendFactor != SBF_ONE_MINUS_DEST_COLOUR && - mSourceBlendFactor != SBF_DEST_ALPHA && - mSourceBlendFactor != SBF_ONE_MINUS_DEST_ALPHA) - { - return false; - } - else - { - return true; - } + // Transparent if any of the destination colour is taken into account + if (mDestBlendFactor == SBF_ZERO && + mSourceBlendFactor != SBF_DEST_COLOUR && + mSourceBlendFactor != SBF_ONE_MINUS_DEST_COLOUR && + mSourceBlendFactor != SBF_DEST_ALPHA && + mSourceBlendFactor != SBF_ONE_MINUS_DEST_ALPHA) + { + return false; + } + else + { + return true; + } } //----------------------------------------------------------------------- void Pass::setDepthCheckEnabled(bool enabled) { - mDepthCheck = enabled; + mDepthCheck = enabled; } //----------------------------------------------------------------------- bool Pass::getDepthCheckEnabled(void) const { - return mDepthCheck; + return mDepthCheck; } //----------------------------------------------------------------------- void Pass::setDepthWriteEnabled(bool enabled) { - mDepthWrite = enabled; + mDepthWrite = enabled; } //----------------------------------------------------------------------- bool Pass::getDepthWriteEnabled(void) const { - return mDepthWrite; + return mDepthWrite; } //----------------------------------------------------------------------- void Pass::setDepthFunction( CompareFunction func) { - mDepthFunc = func; + mDepthFunc = func; } //----------------------------------------------------------------------- CompareFunction Pass::getDepthFunction(void) const { - return mDepthFunc; - } - //----------------------------------------------------------------------- - void Pass::setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage) - { - mAlphaRejectFunc = func; - mAlphaRejectVal = value; - mAlphaToCoverageEnabled = alphaToCoverage; - } - //----------------------------------------------------------------------- - void Pass::setAlphaRejectFunction(CompareFunction func) - { - mAlphaRejectFunc = func; - } - //----------------------------------------------------------------------- - void Pass::setAlphaRejectValue(unsigned char val) - { - mAlphaRejectVal = val; - } - //--------------------------------------------------------------------- - void Pass::setAlphaToCoverageEnabled(bool enabled) - { - mAlphaToCoverageEnabled = enabled; - } - //----------------------------------------------------------------------- - void Pass::setTransparentSortingEnabled(bool enabled) - { - mTransparentSorting = enabled; - } - //----------------------------------------------------------------------- - bool Pass::getTransparentSortingEnabled(void) const - { - return mTransparentSorting; - } - //----------------------------------------------------------------------- - void Pass::setTransparentSortingForced(bool enabled) - { - mTransparentSortingForced = enabled; - } - //----------------------------------------------------------------------- - bool Pass::getTransparentSortingForced(void) const - { - return mTransparentSortingForced; - } - //----------------------------------------------------------------------- - void Pass::setColourWriteEnabled(bool enabled) - { - mColourWrite = enabled; - } - //----------------------------------------------------------------------- - bool Pass::getColourWriteEnabled(void) const - { - return mColourWrite; - } + return mDepthFunc; + } + //----------------------------------------------------------------------- + void Pass::setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage) + { + mAlphaRejectFunc = func; + mAlphaRejectVal = value; + mAlphaToCoverageEnabled = alphaToCoverage; + } + //----------------------------------------------------------------------- + void Pass::setAlphaRejectFunction(CompareFunction func) + { + mAlphaRejectFunc = func; + } + //----------------------------------------------------------------------- + void Pass::setAlphaRejectValue(unsigned char val) + { + mAlphaRejectVal = val; + } + //--------------------------------------------------------------------- + void Pass::setAlphaToCoverageEnabled(bool enabled) + { + mAlphaToCoverageEnabled = enabled; + } + //----------------------------------------------------------------------- + void Pass::setTransparentSortingEnabled(bool enabled) + { + mTransparentSorting = enabled; + } + //----------------------------------------------------------------------- + bool Pass::getTransparentSortingEnabled(void) const + { + return mTransparentSorting; + } + //----------------------------------------------------------------------- + void Pass::setTransparentSortingForced(bool enabled) + { + mTransparentSortingForced = enabled; + } + //----------------------------------------------------------------------- + bool Pass::getTransparentSortingForced(void) const + { + return mTransparentSortingForced; + } + //----------------------------------------------------------------------- + void Pass::setColourWriteEnabled(bool enabled) + { + mColourWrite = enabled; + } + //----------------------------------------------------------------------- + bool Pass::getColourWriteEnabled(void) const + { + return mColourWrite; + } //----------------------------------------------------------------------- void Pass::setCullingMode( CullingMode mode) { - mCullMode = mode; + mCullMode = mode; } //----------------------------------------------------------------------- CullingMode Pass::getCullingMode(void) const { - return mCullMode; + return mCullMode; } //----------------------------------------------------------------------- void Pass::setLightingEnabled(bool enabled) { - mLightingEnabled = enabled; + mLightingEnabled = enabled; } //----------------------------------------------------------------------- bool Pass::getLightingEnabled(void) const { - return mLightingEnabled; + return mLightingEnabled; } //----------------------------------------------------------------------- void Pass::setMaxSimultaneousLights(unsigned short maxLights) @@ -1104,36 +1104,36 @@ namespace Ogre { { return mMaxSimultaneousLights; } - //----------------------------------------------------------------------- - void Pass::setStartLight(unsigned short startLight) - { - mStartLight = startLight; - } - //----------------------------------------------------------------------- - unsigned short Pass::getStartLight(void) const - { - return mStartLight; - } - //----------------------------------------------------------------------- - void Pass::setLightMask(uint32 mask) - { - mLightMask = mask; - } - //----------------------------------------------------------------------- - uint32 Pass::getLightMask() const - { - return mLightMask; - } - //----------------------------------------------------------------------- - void Pass::setLightCountPerIteration(unsigned short c) - { - mLightsPerIteration = c; - } - //----------------------------------------------------------------------- - unsigned short Pass::getLightCountPerIteration(void) const - { - return mLightsPerIteration; - } + //----------------------------------------------------------------------- + void Pass::setStartLight(unsigned short startLight) + { + mStartLight = startLight; + } + //----------------------------------------------------------------------- + unsigned short Pass::getStartLight(void) const + { + return mStartLight; + } + //----------------------------------------------------------------------- + void Pass::setLightMask(uint32 mask) + { + mLightMask = mask; + } + //----------------------------------------------------------------------- + uint32 Pass::getLightMask() const + { + return mLightMask; + } + //----------------------------------------------------------------------- + void Pass::setLightCountPerIteration(unsigned short c) + { + mLightsPerIteration = c; + } + //----------------------------------------------------------------------- + unsigned short Pass::getLightCountPerIteration(void) const + { + return mLightsPerIteration; + } //----------------------------------------------------------------------- void Pass::setIteratePerLight(bool enabled, bool onlyForOneLightType, Light::LightTypes lightType) @@ -1145,200 +1145,200 @@ namespace Ogre { //----------------------------------------------------------------------- void Pass::setShadingMode(ShadeOptions mode) { - mShadeOptions = mode; + mShadeOptions = mode; } //----------------------------------------------------------------------- ShadeOptions Pass::getShadingMode(void) const { - return mShadeOptions; + return mShadeOptions; + } + //----------------------------------------------------------------------- + void Pass::setPolygonMode(PolygonMode mode) + { + mPolygonMode = mode; + } + //----------------------------------------------------------------------- + PolygonMode Pass::getPolygonMode(void) const + { + return mPolygonMode; } - //----------------------------------------------------------------------- - void Pass::setPolygonMode(PolygonMode mode) - { - mPolygonMode = mode; - } - //----------------------------------------------------------------------- - PolygonMode Pass::getPolygonMode(void) const - { - return mPolygonMode; - } //----------------------------------------------------------------------- void Pass::setManualCullingMode(ManualCullingMode mode) { - mManualCullMode = mode; + mManualCullMode = mode; } //----------------------------------------------------------------------- ManualCullingMode Pass::getManualCullingMode(void) const { - return mManualCullMode; + return mManualCullMode; } //----------------------------------------------------------------------- void Pass::setFog(bool overrideScene, FogMode mode, const ColourValue& colour, Real density, Real start, Real end) { - mFogOverride = overrideScene; - if (overrideScene) - { - mFogMode = mode; - mFogColour = colour; - mFogStart = start; - mFogEnd = end; - mFogDensity = density; - } + mFogOverride = overrideScene; + if (overrideScene) + { + mFogMode = mode; + mFogColour = colour; + mFogStart = start; + mFogEnd = end; + mFogDensity = density; + } } //----------------------------------------------------------------------- bool Pass::getFogOverride(void) const { - return mFogOverride; + return mFogOverride; } //----------------------------------------------------------------------- FogMode Pass::getFogMode(void) const { - return mFogMode; + return mFogMode; } //----------------------------------------------------------------------- const ColourValue& Pass::getFogColour(void) const { - return mFogColour; + return mFogColour; } //----------------------------------------------------------------------- Real Pass::getFogStart(void) const { - return mFogStart; + return mFogStart; } //----------------------------------------------------------------------- Real Pass::getFogEnd(void) const { - return mFogEnd; + return mFogEnd; } //----------------------------------------------------------------------- Real Pass::getFogDensity(void) const { - return mFogDensity; + return mFogDensity; } //----------------------------------------------------------------------- void Pass::setDepthBias(float constantBias, float slopeScaleBias) { mDepthBiasConstant = constantBias; - mDepthBiasSlopeScale = slopeScaleBias; + mDepthBiasSlopeScale = slopeScaleBias; } //----------------------------------------------------------------------- float Pass::getDepthBiasConstant(void) const { return mDepthBiasConstant; } - //----------------------------------------------------------------------- - float Pass::getDepthBiasSlopeScale(void) const - { - return mDepthBiasSlopeScale; - } - //--------------------------------------------------------------------- - void Pass::setIterationDepthBias(float biasPerIteration) - { - mDepthBiasPerIteration = biasPerIteration; - } - //--------------------------------------------------------------------- - float Pass::getIterationDepthBias() const - { - return mDepthBiasPerIteration; - } - //----------------------------------------------------------------------- - Pass* Pass::_split(unsigned short numUnits) - { - if (mVertexProgramUsage || mGeometryProgramUsage || mFragmentProgramUsage) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Programmable passes cannot be " - "automatically split, define a fallback technique instead.", - "Pass:_split"); - } - - if (mTextureUnitStates.size() > numUnits) - { - size_t start = mTextureUnitStates.size() - numUnits; - - Pass* newPass = mParent->createPass(); - - TextureUnitStates::iterator istart, i, iend; - iend = mTextureUnitStates.end(); - i = istart = mTextureUnitStates.begin() + start; - // Set the new pass to fallback using scene blend - newPass->setSceneBlending( - (*i)->getColourBlendFallbackSrc(), (*i)->getColourBlendFallbackDest()); - // Fixup the texture unit 0 of new pass blending method to replace - // all colour and alpha with texture without adjustment, because we - // assume it's detail texture. - (*i)->setColourOperationEx(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT); - (*i)->setAlphaOperation(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT); - - // Add all the other texture unit states - for (; i != iend; ++i) - { - // detach from parent first - (*i)->_notifyParent(0); - newPass->addTextureUnitState(*i); - } - // Now remove texture units from this Pass, we don't need to delete since they've - // been transferred - mTextureUnitStates.erase(istart, iend); - _dirtyHash(); - mContentTypeLookupBuilt = false; - return newPass; - } - return NULL; - } - //----------------------------------------------------------------------------- - void Pass::_notifyIndex(unsigned short index) - { - if (mIndex != index) - { - mIndex = index; - _dirtyHash(); - } - } - //----------------------------------------------------------------------- - void Pass::_prepare(void) - { - // We assume the Technique only calls this when the material is being - // prepared - - // prepare each TextureUnitState - TextureUnitStates::iterator i, iend; - iend = mTextureUnitStates.end(); - for (i = mTextureUnitStates.begin(); i != iend; ++i) - { - (*i)->_prepare(); - } - - } - //----------------------------------------------------------------------- - void Pass::_unprepare(void) - { - // unprepare each TextureUnitState - TextureUnitStates::iterator i, iend; - iend = mTextureUnitStates.end(); - for (i = mTextureUnitStates.begin(); i != iend; ++i) - { - (*i)->_unprepare(); - } - - } - //----------------------------------------------------------------------- - void Pass::_load(void) - { - // We assume the Technique only calls this when the material is being - // loaded - - // Load each TextureUnitState - TextureUnitStates::iterator i, iend; - iend = mTextureUnitStates.end(); - for (i = mTextureUnitStates.begin(); i != iend; ++i) - { - (*i)->_load(); - } - - // Load programs - if (mVertexProgramUsage) - { - // Load vertex program + //----------------------------------------------------------------------- + float Pass::getDepthBiasSlopeScale(void) const + { + return mDepthBiasSlopeScale; + } + //--------------------------------------------------------------------- + void Pass::setIterationDepthBias(float biasPerIteration) + { + mDepthBiasPerIteration = biasPerIteration; + } + //--------------------------------------------------------------------- + float Pass::getIterationDepthBias() const + { + return mDepthBiasPerIteration; + } + //----------------------------------------------------------------------- + Pass* Pass::_split(unsigned short numUnits) + { + if (mVertexProgramUsage || mGeometryProgramUsage || mFragmentProgramUsage) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Programmable passes cannot be " + "automatically split, define a fallback technique instead.", + "Pass:_split"); + } + + if (mTextureUnitStates.size() > numUnits) + { + size_t start = mTextureUnitStates.size() - numUnits; + + Pass* newPass = mParent->createPass(); + + TextureUnitStates::iterator istart, i, iend; + iend = mTextureUnitStates.end(); + i = istart = mTextureUnitStates.begin() + start; + // Set the new pass to fallback using scene blend + newPass->setSceneBlending( + (*i)->getColourBlendFallbackSrc(), (*i)->getColourBlendFallbackDest()); + // Fixup the texture unit 0 of new pass blending method to replace + // all colour and alpha with texture without adjustment, because we + // assume it's detail texture. + (*i)->setColourOperationEx(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT); + (*i)->setAlphaOperation(LBX_SOURCE1, LBS_TEXTURE, LBS_CURRENT); + + // Add all the other texture unit states + for (; i != iend; ++i) + { + // detach from parent first + (*i)->_notifyParent(0); + newPass->addTextureUnitState(*i); + } + // Now remove texture units from this Pass, we don't need to delete since they've + // been transferred + mTextureUnitStates.erase(istart, iend); + _dirtyHash(); + mContentTypeLookupBuilt = false; + return newPass; + } + return NULL; + } + //----------------------------------------------------------------------------- + void Pass::_notifyIndex(unsigned short index) + { + if (mIndex != index) + { + mIndex = index; + _dirtyHash(); + } + } + //----------------------------------------------------------------------- + void Pass::_prepare(void) + { + // We assume the Technique only calls this when the material is being + // prepared + + // prepare each TextureUnitState + TextureUnitStates::iterator i, iend; + iend = mTextureUnitStates.end(); + for (i = mTextureUnitStates.begin(); i != iend; ++i) + { + (*i)->_prepare(); + } + + } + //----------------------------------------------------------------------- + void Pass::_unprepare(void) + { + // unprepare each TextureUnitState + TextureUnitStates::iterator i, iend; + iend = mTextureUnitStates.end(); + for (i = mTextureUnitStates.begin(); i != iend; ++i) + { + (*i)->_unprepare(); + } + + } + //----------------------------------------------------------------------- + void Pass::_load(void) + { + // We assume the Technique only calls this when the material is being + // loaded + + // Load each TextureUnitState + TextureUnitStates::iterator i, iend; + iend = mTextureUnitStates.end(); + for (i = mTextureUnitStates.begin(); i != iend; ++i) + { + (*i)->_load(); + } + + // Load programs + if (mVertexProgramUsage) + { + // Load vertex program mVertexProgramUsage->_load(); } if (mShadowCasterVertexProgramUsage) @@ -1357,479 +1357,479 @@ namespace Ogre { mShadowReceiverVertexProgramUsage->_load(); } - if (mTessellationHullProgramUsage) - { - // Load tessellation control program + if (mTessellationHullProgramUsage) + { + // Load tessellation control program mTessellationHullProgramUsage->_load(); } - if (mTessellationDomainProgramUsage) - { - // Load tessellation evaluation program + if (mTessellationDomainProgramUsage) + { + // Load tessellation evaluation program mTessellationDomainProgramUsage->_load(); } - if (mGeometryProgramUsage) - { - // Load geometry program + if (mGeometryProgramUsage) + { + // Load geometry program mGeometryProgramUsage->_load(); } if (mFragmentProgramUsage) { - // Load fragment program + // Load fragment program mFragmentProgramUsage->_load(); - } - if (mShadowReceiverFragmentProgramUsage) - { - // Load Fragment program - mShadowReceiverFragmentProgramUsage->_load(); - } - - if (mComputeProgramUsage) - { - // Load compute program - mComputeProgramUsage->_load(); + } + if (mShadowReceiverFragmentProgramUsage) + { + // Load Fragment program + mShadowReceiverFragmentProgramUsage->_load(); } - if (mHashDirtyQueued) - { - _dirtyHash(); - } - - } - //----------------------------------------------------------------------- - void Pass::_unload(void) - { - // Unload each TextureUnitState - TextureUnitStates::iterator i, iend; - iend = mTextureUnitStates.end(); - for (i = mTextureUnitStates.begin(); i != iend; ++i) - { - (*i)->_unload(); - } - - // Unload programs - if (mVertexProgramUsage) - { - // TODO - } - if (mGeometryProgramUsage) - { - // TODO - } - if (mFragmentProgramUsage) + if (mComputeProgramUsage) { - // TODO + // Load compute program + mComputeProgramUsage->_load(); } - if (mTessellationHullProgramUsage) - { - // TODO - } - if (mTessellationDomainProgramUsage) - { - // TODO - } - if (mComputeProgramUsage) - { - // TODO - } - if (mGeometryProgramUsage) - { - // TODO - } - } - //----------------------------------------------------------------------- - void Pass::setVertexProgram(const String& name, bool resetParams) - { - OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (getVertexProgramName() != name) - { - // Turn off vertex program if name blank - if (name.empty()) - { - OGRE_DELETE mVertexProgramUsage; - mVertexProgramUsage = NULL; - } - else - { - if (!mVertexProgramUsage) - { - mVertexProgramUsage = OGRE_NEW GpuProgramUsage(GPT_VERTEX_PROGRAM, this); - } - mVertexProgramUsage->setProgramName(name, resetParams); - } - // Needs recompilation - mParent->_notifyNeedsRecompile(); - - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) - { - _dirtyHash(); - } - - } - } - //----------------------------------------------------------------------- - void Pass::setVertexProgramParameters(GpuProgramParametersSharedPtr params) - { - OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (!mVertexProgramUsage) + if (mHashDirtyQueued) { - OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, + _dirtyHash(); + } + + } + //----------------------------------------------------------------------- + void Pass::_unload(void) + { + // Unload each TextureUnitState + TextureUnitStates::iterator i, iend; + iend = mTextureUnitStates.end(); + for (i = mTextureUnitStates.begin(); i != iend; ++i) + { + (*i)->_unload(); + } + + // Unload programs + if (mVertexProgramUsage) + { + // TODO + } + if (mGeometryProgramUsage) + { + // TODO + } + if (mFragmentProgramUsage) + { + // TODO + } + if (mTessellationHullProgramUsage) + { + // TODO + } + if (mTessellationDomainProgramUsage) + { + // TODO + } + if (mComputeProgramUsage) + { + // TODO + } + if (mGeometryProgramUsage) + { + // TODO + } + } + //----------------------------------------------------------------------- + void Pass::setVertexProgram(const String& name, bool resetParams) + { + OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); + + if (getVertexProgramName() != name) + { + // Turn off vertex program if name blank + if (name.empty()) + { + OGRE_DELETE mVertexProgramUsage; + mVertexProgramUsage = NULL; + } + else + { + if (!mVertexProgramUsage) + { + mVertexProgramUsage = OGRE_NEW GpuProgramUsage(GPT_VERTEX_PROGRAM, this); + } + mVertexProgramUsage->setProgramName(name, resetParams); + } + // Needs recompilation + mParent->_notifyNeedsRecompile(); + + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) + { + _dirtyHash(); + } + + } + } + //----------------------------------------------------------------------- + void Pass::setVertexProgramParameters(GpuProgramParametersSharedPtr params) + { + OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); + if (!mVertexProgramUsage) + { + OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, "This pass does not have a vertex program assigned!", "Pass::setVertexProgramParameters"); } - mVertexProgramUsage->setParameters(params); - } + mVertexProgramUsage->setParameters(params); + } //----------------------------------------------------------------------- - void Pass::setFragmentProgram(const String& name, bool resetParams) - { + void Pass::setFragmentProgram(const String& name, bool resetParams) + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (getFragmentProgramName() != name) - { - // Turn off fragment program if name blank - if (name.empty()) - { - OGRE_DELETE mFragmentProgramUsage; - mFragmentProgramUsage = NULL; - } - else - { - if (!mFragmentProgramUsage) - { - mFragmentProgramUsage = OGRE_NEW GpuProgramUsage(GPT_FRAGMENT_PROGRAM, this); - } - mFragmentProgramUsage->setProgramName(name, resetParams); - } - // Needs recompilation - mParent->_notifyNeedsRecompile(); - - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) - { - _dirtyHash(); - } - } - } - //----------------------------------------------------------------------- - void Pass::setFragmentProgramParameters(GpuProgramParametersSharedPtr params) - { + if (getFragmentProgramName() != name) + { + // Turn off fragment program if name blank + if (name.empty()) + { + OGRE_DELETE mFragmentProgramUsage; + mFragmentProgramUsage = NULL; + } + else + { + if (!mFragmentProgramUsage) + { + mFragmentProgramUsage = OGRE_NEW GpuProgramUsage(GPT_FRAGMENT_PROGRAM, this); + } + mFragmentProgramUsage->setProgramName(name, resetParams); + } + // Needs recompilation + mParent->_notifyNeedsRecompile(); + + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) + { + _dirtyHash(); + } + } + } + //----------------------------------------------------------------------- + void Pass::setFragmentProgramParameters(GpuProgramParametersSharedPtr params) + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (!mFragmentProgramUsage) + if (!mFragmentProgramUsage) { OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, "This pass does not have a fragment program assigned!", "Pass::setFragmentProgramParameters"); } - mFragmentProgramUsage->setParameters(params); - } - //----------------------------------------------------------------------- - void Pass::setGeometryProgram(const String& name, bool resetParams) - { + mFragmentProgramUsage->setParameters(params); + } + //----------------------------------------------------------------------- + void Pass::setGeometryProgram(const String& name, bool resetParams) + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (getGeometryProgramName() != name) - { - // Turn off geometry program if name blank - if (name.empty()) - { - OGRE_DELETE mGeometryProgramUsage; - mGeometryProgramUsage = NULL; - } - else - { - if (!mGeometryProgramUsage) - { - mGeometryProgramUsage = OGRE_NEW GpuProgramUsage(GPT_GEOMETRY_PROGRAM, this); - } - mGeometryProgramUsage->setProgramName(name, resetParams); - } - // Needs recompilation - mParent->_notifyNeedsRecompile(); - - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) - { - _dirtyHash(); - } - } - } - //----------------------------------------------------------------------- - void Pass::setGeometryProgramParameters(GpuProgramParametersSharedPtr params) - { + if (getGeometryProgramName() != name) + { + // Turn off geometry program if name blank + if (name.empty()) + { + OGRE_DELETE mGeometryProgramUsage; + mGeometryProgramUsage = NULL; + } + else + { + if (!mGeometryProgramUsage) + { + mGeometryProgramUsage = OGRE_NEW GpuProgramUsage(GPT_GEOMETRY_PROGRAM, this); + } + mGeometryProgramUsage->setProgramName(name, resetParams); + } + // Needs recompilation + mParent->_notifyNeedsRecompile(); + + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) + { + _dirtyHash(); + } + } + } + //----------------------------------------------------------------------- + void Pass::setGeometryProgramParameters(GpuProgramParametersSharedPtr params) + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (!mGeometryProgramUsage) + if (!mGeometryProgramUsage) { OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, "This pass does not have a geometry program assigned!", "Pass::setGeometryProgramParameters"); } - mGeometryProgramUsage->setParameters(params); - } - //----------------------------------------------------------------------- - void Pass::setTessellationHullProgram(const String& name, bool resetParams) - { + mGeometryProgramUsage->setParameters(params); + } + //----------------------------------------------------------------------- + void Pass::setTessellationHullProgram(const String& name, bool resetParams) + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (getTessellationHullProgramName() != name) - { - // Turn off tessellation Hull program if name blank - if (name.empty()) - { - OGRE_DELETE mTessellationHullProgramUsage; - mTessellationHullProgramUsage = NULL; - } - else - { - if (!mTessellationHullProgramUsage) - { - mTessellationHullProgramUsage = OGRE_NEW GpuProgramUsage(GPT_HULL_PROGRAM, this); - } - mTessellationHullProgramUsage->setProgramName(name, resetParams); - } - // Needs recompilation - mParent->_notifyNeedsRecompile(); - - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) - { - _dirtyHash(); - } - } - } - //----------------------------------------------------------------------- - void Pass::setTessellationHullProgramParameters(GpuProgramParametersSharedPtr params) - { + if (getTessellationHullProgramName() != name) + { + // Turn off tessellation Hull program if name blank + if (name.empty()) + { + OGRE_DELETE mTessellationHullProgramUsage; + mTessellationHullProgramUsage = NULL; + } + else + { + if (!mTessellationHullProgramUsage) + { + mTessellationHullProgramUsage = OGRE_NEW GpuProgramUsage(GPT_HULL_PROGRAM, this); + } + mTessellationHullProgramUsage->setProgramName(name, resetParams); + } + // Needs recompilation + mParent->_notifyNeedsRecompile(); + + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) + { + _dirtyHash(); + } + } + } + //----------------------------------------------------------------------- + void Pass::setTessellationHullProgramParameters(GpuProgramParametersSharedPtr params) + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (!mTessellationHullProgramUsage) + if (!mTessellationHullProgramUsage) { OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, "This pass does not have a tessellation Hull program assigned!", "Pass::setTessellationHullProgramParameters"); } - mTessellationHullProgramUsage->setParameters(params); - } - //----------------------------------------------------------------------- - void Pass::setTessellationDomainProgram(const String& name, bool resetParams) - { + mTessellationHullProgramUsage->setParameters(params); + } + //----------------------------------------------------------------------- + void Pass::setTessellationDomainProgram(const String& name, bool resetParams) + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (getTessellationDomainProgramName() != name) - { - // Turn off tessellation Domain program if name blank - if (name.empty()) - { - OGRE_DELETE mTessellationDomainProgramUsage; - mTessellationDomainProgramUsage = NULL; - } - else - { - if (!mTessellationDomainProgramUsage) - { - mTessellationDomainProgramUsage = OGRE_NEW GpuProgramUsage(GPT_DOMAIN_PROGRAM, this); - } - mTessellationDomainProgramUsage->setProgramName(name, resetParams); - } - // Needs recompilation - mParent->_notifyNeedsRecompile(); - - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) - { - _dirtyHash(); - } - } - } - //----------------------------------------------------------------------- - void Pass::setTessellationDomainProgramParameters(GpuProgramParametersSharedPtr params) - { + if (getTessellationDomainProgramName() != name) + { + // Turn off tessellation Domain program if name blank + if (name.empty()) + { + OGRE_DELETE mTessellationDomainProgramUsage; + mTessellationDomainProgramUsage = NULL; + } + else + { + if (!mTessellationDomainProgramUsage) + { + mTessellationDomainProgramUsage = OGRE_NEW GpuProgramUsage(GPT_DOMAIN_PROGRAM, this); + } + mTessellationDomainProgramUsage->setProgramName(name, resetParams); + } + // Needs recompilation + mParent->_notifyNeedsRecompile(); + + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) + { + _dirtyHash(); + } + } + } + //----------------------------------------------------------------------- + void Pass::setTessellationDomainProgramParameters(GpuProgramParametersSharedPtr params) + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (!mTessellationDomainProgramUsage) + if (!mTessellationDomainProgramUsage) { OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, "This pass does not have a tessellation Domain program assigned!", "Pass::setTessellationDomainProgramParameters"); } - mTessellationDomainProgramUsage->setParameters(params); - } - //----------------------------------------------------------------------- - void Pass::setComputeProgram(const String& name, bool resetParams) - { + mTessellationDomainProgramUsage->setParameters(params); + } + //----------------------------------------------------------------------- + void Pass::setComputeProgram(const String& name, bool resetParams) + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (getComputeProgramName() != name) - { - // Turn off compute program if name blank - if (name.empty()) - { - OGRE_DELETE mComputeProgramUsage; - mComputeProgramUsage = NULL; - } - else - { - if (!mComputeProgramUsage) - { - mComputeProgramUsage = OGRE_NEW GpuProgramUsage(GPT_COMPUTE_PROGRAM, this); - } - mComputeProgramUsage->setProgramName(name, resetParams); - } - // Needs recompilation - mParent->_notifyNeedsRecompile(); - - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) - { - _dirtyHash(); - } - } - } - //----------------------------------------------------------------------- - void Pass::setComputeProgramParameters(GpuProgramParametersSharedPtr params) - { + if (getComputeProgramName() != name) + { + // Turn off compute program if name blank + if (name.empty()) + { + OGRE_DELETE mComputeProgramUsage; + mComputeProgramUsage = NULL; + } + else + { + if (!mComputeProgramUsage) + { + mComputeProgramUsage = OGRE_NEW GpuProgramUsage(GPT_COMPUTE_PROGRAM, this); + } + mComputeProgramUsage->setProgramName(name, resetParams); + } + // Needs recompilation + mParent->_notifyNeedsRecompile(); + + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_GPU_PROGRAM_CHANGE ) ) + { + _dirtyHash(); + } + } + } + //----------------------------------------------------------------------- + void Pass::setComputeProgramParameters(GpuProgramParametersSharedPtr params) + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (!mComputeProgramUsage) + if (!mComputeProgramUsage) { OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, "This pass does not have a compute program assigned!", "Pass::setComputeProgramParameters"); } - mComputeProgramUsage->setParameters(params); - } - //----------------------------------------------------------------------- - const String& Pass::getVertexProgramName(void) const - { + mComputeProgramUsage->setParameters(params); + } + //----------------------------------------------------------------------- + const String& Pass::getVertexProgramName(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); if (!mVertexProgramUsage) return BLANKSTRING; else - return mVertexProgramUsage->getProgramName(); - } - //----------------------------------------------------------------------- - GpuProgramParametersSharedPtr Pass::getVertexProgramParameters(void) const - { + return mVertexProgramUsage->getProgramName(); + } + //----------------------------------------------------------------------- + GpuProgramParametersSharedPtr Pass::getVertexProgramParameters(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - if (!mVertexProgramUsage) + if (!mVertexProgramUsage) { OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, "This pass does not have a vertex program assigned!", "Pass::getVertexProgramParameters"); } - return mVertexProgramUsage->getParameters(); - } - //----------------------------------------------------------------------- - const GpuProgramPtr& Pass::getVertexProgram(void) const - { + return mVertexProgramUsage->getParameters(); + } + //----------------------------------------------------------------------- + const GpuProgramPtr& Pass::getVertexProgram(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mVertexProgramUsage->getProgram(); - } - //----------------------------------------------------------------------- - const String& Pass::getFragmentProgramName(void) const - { + return mVertexProgramUsage->getProgram(); + } + //----------------------------------------------------------------------- + const String& Pass::getFragmentProgramName(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); if (!mFragmentProgramUsage) return BLANKSTRING; else - return mFragmentProgramUsage->getProgramName(); - } - //----------------------------------------------------------------------- - GpuProgramParametersSharedPtr Pass::getFragmentProgramParameters(void) const - { + return mFragmentProgramUsage->getProgramName(); + } + //----------------------------------------------------------------------- + GpuProgramParametersSharedPtr Pass::getFragmentProgramParameters(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mFragmentProgramUsage->getParameters(); - } - //----------------------------------------------------------------------- - const GpuProgramPtr& Pass::getFragmentProgram(void) const - { + return mFragmentProgramUsage->getParameters(); + } + //----------------------------------------------------------------------- + const GpuProgramPtr& Pass::getFragmentProgram(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mFragmentProgramUsage->getProgram(); - } - //----------------------------------------------------------------------- - const String& Pass::getGeometryProgramName(void) const - { + return mFragmentProgramUsage->getProgram(); + } + //----------------------------------------------------------------------- + const String& Pass::getGeometryProgramName(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); if (!mGeometryProgramUsage) return BLANKSTRING; else - return mGeometryProgramUsage->getProgramName(); - } - //----------------------------------------------------------------------- - GpuProgramParametersSharedPtr Pass::getGeometryProgramParameters(void) const - { + return mGeometryProgramUsage->getProgramName(); + } + //----------------------------------------------------------------------- + GpuProgramParametersSharedPtr Pass::getGeometryProgramParameters(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mGeometryProgramUsage->getParameters(); - } - //----------------------------------------------------------------------- - const GpuProgramPtr& Pass::getGeometryProgram(void) const - { + return mGeometryProgramUsage->getParameters(); + } + //----------------------------------------------------------------------- + const GpuProgramPtr& Pass::getGeometryProgram(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mGeometryProgramUsage->getProgram(); - } - //----------------------------------------------------------------------- - const String& Pass::getTessellationHullProgramName(void) const - { + return mGeometryProgramUsage->getProgram(); + } + //----------------------------------------------------------------------- + const String& Pass::getTessellationHullProgramName(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); if (!mTessellationHullProgramUsage) return BLANKSTRING; else - return mTessellationHullProgramUsage->getProgramName(); - } - //----------------------------------------------------------------------- - GpuProgramParametersSharedPtr Pass::getTessellationHullProgramParameters(void) const - { + return mTessellationHullProgramUsage->getProgramName(); + } + //----------------------------------------------------------------------- + GpuProgramParametersSharedPtr Pass::getTessellationHullProgramParameters(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mTessellationHullProgramUsage->getParameters(); - } - //----------------------------------------------------------------------- - const GpuProgramPtr& Pass::getTessellationHullProgram(void) const - { + return mTessellationHullProgramUsage->getParameters(); + } + //----------------------------------------------------------------------- + const GpuProgramPtr& Pass::getTessellationHullProgram(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mTessellationHullProgramUsage->getProgram(); - } - //----------------------------------------------------------------------- - const String& Pass::getTessellationDomainProgramName(void) const - { + return mTessellationHullProgramUsage->getProgram(); + } + //----------------------------------------------------------------------- + const String& Pass::getTessellationDomainProgramName(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); if (!mTessellationDomainProgramUsage) return BLANKSTRING; else - return mTessellationDomainProgramUsage->getProgramName(); - } - //----------------------------------------------------------------------- - GpuProgramParametersSharedPtr Pass::getTessellationDomainProgramParameters(void) const - { + return mTessellationDomainProgramUsage->getProgramName(); + } + //----------------------------------------------------------------------- + GpuProgramParametersSharedPtr Pass::getTessellationDomainProgramParameters(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mTessellationDomainProgramUsage->getParameters(); - } - //----------------------------------------------------------------------- - const GpuProgramPtr& Pass::getTessellationDomainProgram(void) const - { + return mTessellationDomainProgramUsage->getParameters(); + } + //----------------------------------------------------------------------- + const GpuProgramPtr& Pass::getTessellationDomainProgram(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mTessellationDomainProgramUsage->getProgram(); - } - //----------------------------------------------------------------------- - const String& Pass::getComputeProgramName(void) const - { + return mTessellationDomainProgramUsage->getProgram(); + } + //----------------------------------------------------------------------- + const String& Pass::getComputeProgramName(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); if (!mComputeProgramUsage) return BLANKSTRING; else - return mComputeProgramUsage->getProgramName(); - } - //----------------------------------------------------------------------- - GpuProgramParametersSharedPtr Pass::getComputeProgramParameters(void) const - { + return mComputeProgramUsage->getProgramName(); + } + //----------------------------------------------------------------------- + GpuProgramParametersSharedPtr Pass::getComputeProgramParameters(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mComputeProgramUsage->getParameters(); - } - //----------------------------------------------------------------------- - const GpuProgramPtr& Pass::getComputeProgram(void) const - { + return mComputeProgramUsage->getParameters(); + } + //----------------------------------------------------------------------- + const GpuProgramPtr& Pass::getComputeProgram(void) const + { OGRE_LOCK_MUTEX(mGpuProgramChangeMutex); - return mComputeProgramUsage->getProgram(); - } - //----------------------------------------------------------------------- + return mComputeProgramUsage->getProgram(); + } + //----------------------------------------------------------------------- bool Pass::isLoaded(void) const { return mParent->isLoaded(); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void Pass::_recalculateHash(void) { /* Hash format is 32-bit, divided as follows (high to low bits) @@ -1845,27 +1845,27 @@ namespace Ogre { mHash = (*msHashFunc)(this); } //----------------------------------------------------------------------- - void Pass::_dirtyHash(void) - { - Material* mat = mParent->getParent(); - if (mat->isLoading() || mat->isLoaded()) - { + void Pass::_dirtyHash(void) + { + Material* mat = mParent->getParent(); + if (mat->isLoading() || mat->isLoaded()) + { OGRE_LOCK_MUTEX(msDirtyHashListMutex); - // Mark this hash as for follow up - msDirtyHashList.insert(this); - mHashDirtyQueued = false; - } - else - { - mHashDirtyQueued = true; - } - } - //--------------------------------------------------------------------- - void Pass::clearDirtyHashList(void) - { + // Mark this hash as for follow up + msDirtyHashList.insert(this); + mHashDirtyQueued = false; + } + else + { + mHashDirtyQueued = true; + } + } + //--------------------------------------------------------------------- + void Pass::clearDirtyHashList(void) + { OGRE_LOCK_MUTEX(msDirtyHashListMutex); - msDirtyHashList.clear(); - } + msDirtyHashList.clear(); + } //----------------------------------------------------------------------- void Pass::_notifyNeedsRecompile(void) { @@ -1894,63 +1894,63 @@ namespace Ogre { (*i)->setTextureAnisotropy(maxAniso); } } - //----------------------------------------------------------------------- - void Pass::_updateAutoParams(const AutoParamDataSource* source, uint16 mask) const - { - if (hasVertexProgram()) - { - // Update vertex program auto params - mVertexProgramUsage->getParameters()->_updateAutoParams(source, mask); - } - - if (hasGeometryProgram()) - { - // Update geometry program auto params - mGeometryProgramUsage->getParameters()->_updateAutoParams(source, mask); - } - - if (hasFragmentProgram()) - { - // Update fragment program auto params - mFragmentProgramUsage->getParameters()->_updateAutoParams(source, mask); - } - - if (hasTessellationHullProgram()) - { - // Update fragment program auto params - mTessellationHullProgramUsage->getParameters()->_updateAutoParams(source, mask); - } - - if (hasTessellationDomainProgram()) - { - // Update fragment program auto params - mTessellationDomainProgramUsage->getParameters()->_updateAutoParams(source, mask); - } - - if (hasComputeProgram()) - { - // Update fragment program auto params - mComputeProgramUsage->getParameters()->_updateAutoParams(source, mask); - } - } + //----------------------------------------------------------------------- + void Pass::_updateAutoParams(const AutoParamDataSource* source, uint16 mask) const + { + if (hasVertexProgram()) + { + // Update vertex program auto params + mVertexProgramUsage->getParameters()->_updateAutoParams(source, mask); + } + + if (hasGeometryProgram()) + { + // Update geometry program auto params + mGeometryProgramUsage->getParameters()->_updateAutoParams(source, mask); + } + + if (hasFragmentProgram()) + { + // Update fragment program auto params + mFragmentProgramUsage->getParameters()->_updateAutoParams(source, mask); + } + + if (hasTessellationHullProgram()) + { + // Update fragment program auto params + mTessellationHullProgramUsage->getParameters()->_updateAutoParams(source, mask); + } + + if (hasTessellationDomainProgram()) + { + // Update fragment program auto params + mTessellationDomainProgramUsage->getParameters()->_updateAutoParams(source, mask); + } + + if (hasComputeProgram()) + { + // Update fragment program auto params + mComputeProgramUsage->getParameters()->_updateAutoParams(source, mask); + } + } //----------------------------------------------------------------------- void Pass::processPendingPassUpdates(void) { - { + { OGRE_LOCK_MUTEX(msPassGraveyardMutex); - // Delete items in the graveyard - PassSet::iterator i, iend; - iend = msPassGraveyard.end(); - for (i = msPassGraveyard.begin(); i != iend; ++i) - { - OGRE_DELETE *i; - } - msPassGraveyard.clear(); - } + // Delete items in the graveyard + PassSet::iterator i, iend; + iend = msPassGraveyard.end(); + for (i = msPassGraveyard.begin(); i != iend; ++i) + { + OGRE_DELETE *i; + } + msPassGraveyard.clear(); + } PassSet tempDirtyHashList; - { + { OGRE_LOCK_MUTEX(msDirtyHashListMutex); - // The dirty ones will have been removed from the groups above using the old hash now + // The dirty ones will have been removed from the groups above using the old hash now tempDirtyHashList.swap(msDirtyHashList); } PassSet::iterator i, iend; @@ -1997,35 +1997,35 @@ namespace Ogre { OGRE_DELETE mFragmentProgramUsage; mFragmentProgramUsage = 0; } - if (mTessellationHullProgramUsage) + if (mTessellationHullProgramUsage) { OGRE_DELETE mTessellationHullProgramUsage; mTessellationHullProgramUsage = 0; } - if (mTessellationDomainProgramUsage) + if (mTessellationDomainProgramUsage) { OGRE_DELETE mTessellationDomainProgramUsage; mTessellationDomainProgramUsage = 0; } - if (mComputeProgramUsage) + if (mComputeProgramUsage) { OGRE_DELETE mComputeProgramUsage; mComputeProgramUsage = 0; } - if (mShadowReceiverFragmentProgramUsage) - { - OGRE_DELETE mShadowReceiverFragmentProgramUsage; - mShadowReceiverFragmentProgramUsage = 0; - } + if (mShadowReceiverFragmentProgramUsage) + { + OGRE_DELETE mShadowReceiverFragmentProgramUsage; + mShadowReceiverFragmentProgramUsage = 0; + } // remove from dirty list, if there - { + { OGRE_LOCK_MUTEX(msDirtyHashListMutex); - msDirtyHashList.erase(this); - } - { + msDirtyHashList.erase(this); + } + { OGRE_LOCK_MUTEX(msPassGraveyardMutex); - msPassGraveyard.insert(this); - } + msPassGraveyard.insert(this); + } } //----------------------------------------------------------------------- bool Pass::isAmbientOnly(void) const @@ -2211,66 +2211,66 @@ namespace Ogre { { return mShadowReceiverVertexProgramUsage->getProgram(); } - //----------------------------------------------------------------------- - void Pass::setShadowReceiverFragmentProgram(const String& name) - { - // Turn off Fragment program if name blank - if (name.empty()) - { - OGRE_DELETE mShadowReceiverFragmentProgramUsage; - mShadowReceiverFragmentProgramUsage = NULL; - } - else - { - if (!mShadowReceiverFragmentProgramUsage) - { - mShadowReceiverFragmentProgramUsage = OGRE_NEW GpuProgramUsage(GPT_FRAGMENT_PROGRAM, this); - } - mShadowReceiverFragmentProgramUsage->setProgramName(name); - } - // Needs recompilation - mParent->_notifyNeedsRecompile(); - } - //----------------------------------------------------------------------- - void Pass::setShadowReceiverFragmentProgramParameters(GpuProgramParametersSharedPtr params) - { - if (!mShadowReceiverFragmentProgramUsage) - { - OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, - "This pass does not have a shadow receiver fragment program assigned!", - "Pass::setShadowReceiverFragmentProgramParameters"); - } - mShadowReceiverFragmentProgramUsage->setParameters(params); - } - //----------------------------------------------------------------------- - const String& Pass::getShadowReceiverFragmentProgramName(void) const - { - if (!mShadowReceiverFragmentProgramUsage) - return BLANKSTRING; - else - return mShadowReceiverFragmentProgramUsage->getProgramName(); - } - //----------------------------------------------------------------------- - GpuProgramParametersSharedPtr Pass::getShadowReceiverFragmentProgramParameters(void) const - { - if (!mShadowReceiverFragmentProgramUsage) - { - OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, - "This pass does not have a shadow receiver fragment program assigned!", - "Pass::getShadowReceiverFragmentProgramParameters"); - } - return mShadowReceiverFragmentProgramUsage->getParameters(); - } - //----------------------------------------------------------------------- - const GpuProgramPtr& Pass::getShadowReceiverFragmentProgram(void) const - { - return mShadowReceiverFragmentProgramUsage->getProgram(); - } - //----------------------------------------------------------------------- - const String& Pass::getResourceGroup(void) const - { - return mParent->getResourceGroup(); - } + //----------------------------------------------------------------------- + void Pass::setShadowReceiverFragmentProgram(const String& name) + { + // Turn off Fragment program if name blank + if (name.empty()) + { + OGRE_DELETE mShadowReceiverFragmentProgramUsage; + mShadowReceiverFragmentProgramUsage = NULL; + } + else + { + if (!mShadowReceiverFragmentProgramUsage) + { + mShadowReceiverFragmentProgramUsage = OGRE_NEW GpuProgramUsage(GPT_FRAGMENT_PROGRAM, this); + } + mShadowReceiverFragmentProgramUsage->setProgramName(name); + } + // Needs recompilation + mParent->_notifyNeedsRecompile(); + } + //----------------------------------------------------------------------- + void Pass::setShadowReceiverFragmentProgramParameters(GpuProgramParametersSharedPtr params) + { + if (!mShadowReceiverFragmentProgramUsage) + { + OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, + "This pass does not have a shadow receiver fragment program assigned!", + "Pass::setShadowReceiverFragmentProgramParameters"); + } + mShadowReceiverFragmentProgramUsage->setParameters(params); + } + //----------------------------------------------------------------------- + const String& Pass::getShadowReceiverFragmentProgramName(void) const + { + if (!mShadowReceiverFragmentProgramUsage) + return BLANKSTRING; + else + return mShadowReceiverFragmentProgramUsage->getProgramName(); + } + //----------------------------------------------------------------------- + GpuProgramParametersSharedPtr Pass::getShadowReceiverFragmentProgramParameters(void) const + { + if (!mShadowReceiverFragmentProgramUsage) + { + OGRE_EXCEPT (Exception::ERR_INVALIDPARAMS, + "This pass does not have a shadow receiver fragment program assigned!", + "Pass::getShadowReceiverFragmentProgramParameters"); + } + return mShadowReceiverFragmentProgramUsage->getParameters(); + } + //----------------------------------------------------------------------- + const GpuProgramPtr& Pass::getShadowReceiverFragmentProgram(void) const + { + return mShadowReceiverFragmentProgramUsage->getProgram(); + } + //----------------------------------------------------------------------- + const String& Pass::getResourceGroup(void) const + { + return mParent->getResourceGroup(); + } //----------------------------------------------------------------------- bool Pass::applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply) const @@ -2289,52 +2289,52 @@ namespace Ogre { return testResult; } - //----------------------------------------------------------------------- - unsigned short Pass::_getTextureUnitWithContentTypeIndex( - TextureUnitState::ContentType contentType, unsigned short index) const - { - if (!mContentTypeLookupBuilt) - { - mShadowContentTypeLookup.clear(); - for (unsigned short i = 0; i < mTextureUnitStates.size(); ++i) - { - if (mTextureUnitStates[i]->getContentType() == TextureUnitState::CONTENT_SHADOW) - { - mShadowContentTypeLookup.push_back(i); - } - } - mContentTypeLookupBuilt = true; - } - - switch(contentType) - { - case TextureUnitState::CONTENT_SHADOW: - if (index < mShadowContentTypeLookup.size()) - { - return mShadowContentTypeLookup[index]; - } - break; - default: - // Simple iteration - for (unsigned short i = 0; i < mTextureUnitStates.size(); ++i) - { - if (mTextureUnitStates[i]->getContentType() == TextureUnitState::CONTENT_SHADOW) - { - if (index == 0) - { - return i; - } - else - { - --index; - } - } - } - break; - } - - // not found - return out of range - return static_cast(mTextureUnitStates.size() + 1); - - } + //----------------------------------------------------------------------- + unsigned short Pass::_getTextureUnitWithContentTypeIndex( + TextureUnitState::ContentType contentType, unsigned short index) const + { + if (!mContentTypeLookupBuilt) + { + mShadowContentTypeLookup.clear(); + for (unsigned short i = 0; i < mTextureUnitStates.size(); ++i) + { + if (mTextureUnitStates[i]->getContentType() == TextureUnitState::CONTENT_SHADOW) + { + mShadowContentTypeLookup.push_back(i); + } + } + mContentTypeLookupBuilt = true; + } + + switch(contentType) + { + case TextureUnitState::CONTENT_SHADOW: + if (index < mShadowContentTypeLookup.size()) + { + return mShadowContentTypeLookup[index]; + } + break; + default: + // Simple iteration + for (unsigned short i = 0; i < mTextureUnitStates.size(); ++i) + { + if (mTextureUnitStates[i]->getContentType() == TextureUnitState::CONTENT_SHADOW) + { + if (index == 0) + { + return i; + } + else + { + --index; + } + } + } + break; + } + + // not found - return out of range + return static_cast(mTextureUnitStates.size() + 1); + + } } diff --git a/OgreMain/src/OgrePatchMesh.cpp b/OgreMain/src/OgrePatchMesh.cpp index 9927ed4e5d2..950e137d9b9 100644 --- a/OgreMain/src/OgrePatchMesh.cpp +++ b/OgreMain/src/OgrePatchMesh.cpp @@ -61,19 +61,19 @@ namespace Ogre { } //----------------------------------------------------------------------- - void PatchMesh::update(void* controlPointBuffer, size_t width, size_t height, + void PatchMesh::update(void* controlPointBuffer, size_t width, size_t height, size_t uMaxSubdivisionLevel, size_t vMaxSubdivisionLevel, PatchSurface::VisibleSide visibleSide) - { - mSurface.defineSurface(controlPointBuffer, mDeclaration, width, height, PatchSurface::PST_BEZIER, uMaxSubdivisionLevel, vMaxSubdivisionLevel, visibleSide); - Ogre::SubMesh* sm = this->getSubMesh(0); - Ogre::VertexData* vertex_data = sm->useSharedVertices ? this->sharedVertexData : sm->vertexData; - const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); - Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); + { + mSurface.defineSurface(controlPointBuffer, mDeclaration, width, height, PatchSurface::PST_BEZIER, uMaxSubdivisionLevel, vMaxSubdivisionLevel, visibleSide); + Ogre::SubMesh* sm = this->getSubMesh(0); + Ogre::VertexData* vertex_data = sm->useSharedVertices ? this->sharedVertexData : sm->vertexData; + const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); + Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); // Build patch with new control points - mSurface.build(vbuf, 0, sm->indexData->indexBuffer, 0); - } + mSurface.build(vbuf, 0, sm->indexData->indexBuffer, 0); + } //----------------------------------------------------------------------- void PatchMesh::setSubdivision(Real factor) { diff --git a/OgreMain/src/OgrePixelConversions.h b/OgreMain/src/OgrePixelConversions.h index b942113a7bd..a260ecf5d96 100644 --- a/OgreMain/src/OgrePixelConversions.h +++ b/OgreMain/src/OgrePixelConversions.h @@ -54,9 +54,9 @@ template struct PixelBoxConverter static void conversion(const Ogre::PixelBox &src, const Ogre::PixelBox &dst) { typename U::SrcType *srcptr = static_cast(src.data) - + (src.left + src.top * src.rowPitch + src.front * src.slicePitch); + + (src.left + src.top * src.rowPitch + src.front * src.slicePitch); typename U::DstType *dstptr = static_cast(dst.data) - + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch); + + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch); const size_t srcSliceSkip = src.getSliceSkip(); const size_t dstSliceSkip = dst.getSliceSkip(); const size_t k = src.right - src.left; @@ -94,15 +94,15 @@ struct Col3b { }; /** Type for PF_FLOAT32_RGB */ struct Col3f { - Col3f(float inR, float inG, float inB): - r(inR), g(inG), b(inB) { } - float r,g,b; + Col3f(float inR, float inG, float inB): + r(inR), g(inG), b(inB) { } + float r,g,b; }; /** Type for PF_FLOAT32_RGBA */ struct Col4f { - Col4f(float inR, float inG, float inB, float inA): - r(inR), g(inG), b(inB), a(inA) { } - float r,g,b,a; + Col4f(float inR, float inG, float inB, float inA): + r(inR), g(inG), b(inB), a(inA) { } + float r,g,b,a; }; struct A8R8G8B8toA8B8G8R8: public PixelConverter @@ -358,7 +358,7 @@ struct X8B8G8R8toA8R8G8B8: public PixelConverter { - inline static DstType pixelConvert(SrcType inp) + inline static DstType pixelConvert(SrcType inp) { return inp | 0xFF000000; } @@ -386,18 +386,18 @@ inline int doOptimizedConversion(const Ogre::PixelBox &src, const Ogre::PixelBox switch(FMTCONVERTERID(src.format, dst.format)) { // Register converters here - CASECONVERTER(A8R8G8B8toA8B8G8R8); - CASECONVERTER(A8R8G8B8toB8G8R8A8); - CASECONVERTER(A8R8G8B8toR8G8B8A8); - CASECONVERTER(A8B8G8R8toA8R8G8B8); - CASECONVERTER(A8B8G8R8toB8G8R8A8); - CASECONVERTER(A8B8G8R8toR8G8B8A8); - CASECONVERTER(B8G8R8A8toA8R8G8B8); - CASECONVERTER(B8G8R8A8toA8B8G8R8); - CASECONVERTER(B8G8R8A8toR8G8B8A8); - CASECONVERTER(R8G8B8A8toA8R8G8B8); - CASECONVERTER(R8G8B8A8toA8B8G8R8); - CASECONVERTER(R8G8B8A8toB8G8R8A8); + CASECONVERTER(A8R8G8B8toA8B8G8R8); + CASECONVERTER(A8R8G8B8toB8G8R8A8); + CASECONVERTER(A8R8G8B8toR8G8B8A8); + CASECONVERTER(A8B8G8R8toA8R8G8B8); + CASECONVERTER(A8B8G8R8toB8G8R8A8); + CASECONVERTER(A8B8G8R8toR8G8B8A8); + CASECONVERTER(B8G8R8A8toA8R8G8B8); + CASECONVERTER(B8G8R8A8toA8B8G8R8); + CASECONVERTER(B8G8R8A8toR8G8B8A8); + CASECONVERTER(R8G8B8A8toA8R8G8B8); + CASECONVERTER(R8G8B8A8toA8B8G8R8); + CASECONVERTER(R8G8B8A8toB8G8R8A8); CASECONVERTER(A8B8G8R8toL8); CASECONVERTER(L8toA8B8G8R8); CASECONVERTER(A8R8G8B8toL8); @@ -414,16 +414,16 @@ inline int doOptimizedConversion(const Ogre::PixelBox &src, const Ogre::PixelBox CASECONVERTER(B8G8R8toA8B8G8R8); CASECONVERTER(R8G8B8toB8G8R8A8); CASECONVERTER(B8G8R8toB8G8R8A8); - CASECONVERTER(A8R8G8B8toR8G8B8); - CASECONVERTER(A8R8G8B8toB8G8R8); - CASECONVERTER(X8R8G8B8toA8R8G8B8); - CASECONVERTER(X8R8G8B8toA8B8G8R8); - CASECONVERTER(X8R8G8B8toB8G8R8A8); - CASECONVERTER(X8R8G8B8toR8G8B8A8); - CASECONVERTER(X8B8G8R8toA8R8G8B8); - CASECONVERTER(X8B8G8R8toA8B8G8R8); - CASECONVERTER(X8B8G8R8toB8G8R8A8); - CASECONVERTER(X8B8G8R8toR8G8B8A8); + CASECONVERTER(A8R8G8B8toR8G8B8); + CASECONVERTER(A8R8G8B8toB8G8R8); + CASECONVERTER(X8R8G8B8toA8R8G8B8); + CASECONVERTER(X8R8G8B8toA8B8G8R8); + CASECONVERTER(X8R8G8B8toB8G8R8A8); + CASECONVERTER(X8R8G8B8toR8G8B8A8); + CASECONVERTER(X8B8G8R8toA8R8G8B8); + CASECONVERTER(X8B8G8R8toA8B8G8R8); + CASECONVERTER(X8B8G8R8toB8G8R8A8); + CASECONVERTER(X8B8G8R8toR8G8B8A8); default: return 0; diff --git a/OgreMain/src/OgrePixelFormat.cpp b/OgreMain/src/OgrePixelFormat.cpp index 6577e346539..336be76ccf7 100644 --- a/OgreMain/src/OgrePixelFormat.cpp +++ b/OgreMain/src/OgrePixelFormat.cpp @@ -39,41 +39,41 @@ namespace { namespace Ogre { //----------------------------------------------------------------------- - size_t PixelBox::getConsecutiveSize() const - { - return PixelUtil::getMemorySize(getWidth(), getHeight(), getDepth(), format); - } - PixelBox PixelBox::getSubVolume(const Box &def) const - { - if(PixelUtil::isCompressed(format)) - { - if(def.left == left && def.top == top && def.front == front && - def.right == right && def.bottom == bottom && def.back == back) - { - // Entire buffer is being queried - return *this; - } - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot return subvolume of compressed PixelBuffer", "PixelBox::getSubVolume"); - } - if(!contains(def)) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Bounds out of range", "PixelBox::getSubVolume"); - - const size_t elemSize = PixelUtil::getNumElemBytes(format); - // Calculate new data origin - // Notice how we do not propagate left/top/front from the incoming box, since - // the returned pointer is already offset - PixelBox rval(def.getWidth(), def.getHeight(), def.getDepth(), format, - ((uint8*)data) + ((def.left-left)*elemSize) - + ((def.top-top)*rowPitch*elemSize) - + ((def.front-front)*slicePitch*elemSize) - ); - - rval.rowPitch = rowPitch; - rval.slicePitch = slicePitch; - rval.format = format; - - return rval; - } + size_t PixelBox::getConsecutiveSize() const + { + return PixelUtil::getMemorySize(getWidth(), getHeight(), getDepth(), format); + } + PixelBox PixelBox::getSubVolume(const Box &def) const + { + if(PixelUtil::isCompressed(format)) + { + if(def.left == left && def.top == top && def.front == front && + def.right == right && def.bottom == bottom && def.back == back) + { + // Entire buffer is being queried + return *this; + } + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot return subvolume of compressed PixelBuffer", "PixelBox::getSubVolume"); + } + if(!contains(def)) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Bounds out of range", "PixelBox::getSubVolume"); + + const size_t elemSize = PixelUtil::getNumElemBytes(format); + // Calculate new data origin + // Notice how we do not propagate left/top/front from the incoming box, since + // the returned pointer is already offset + PixelBox rval(def.getWidth(), def.getHeight(), def.getDepth(), format, + ((uint8*)data) + ((def.left-left)*elemSize) + + ((def.top-top)*rowPitch*elemSize) + + ((def.front-front)*slicePitch*elemSize) + ); + + rval.rowPitch = rowPitch; + rval.slicePitch = slicePitch; + rval.format = format; + + return rval; + } void* PixelBox::getTopLeftFrontPixelPtr() const { return (uint8*)data + (left + top * rowPitch + front * slicePitch) * PixelUtil::getNumElemBytes(format); @@ -95,22 +95,22 @@ namespace Ogre { { return getDescriptionFor(format).elemBytes; } - //----------------------------------------------------------------------- - size_t PixelUtil::getMemorySize(uint32 width, uint32 height, uint32 depth, PixelFormat format) - { - if(isCompressed(format)) - { - switch(format) - { - // DXT formats work by dividing the image into 4x4 blocks, then encoding each - // 4x4 block with a certain number of bytes. - case PF_DXT1: - return ((width+3)/4)*((height+3)/4)*8 * depth; - case PF_DXT2: - case PF_DXT3: - case PF_DXT4: - case PF_DXT5: - return ((width+3)/4)*((height+3)/4)*16 * depth; + //----------------------------------------------------------------------- + size_t PixelUtil::getMemorySize(uint32 width, uint32 height, uint32 depth, PixelFormat format) + { + if(isCompressed(format)) + { + switch(format) + { + // DXT formats work by dividing the image into 4x4 blocks, then encoding each + // 4x4 block with a certain number of bytes. + case PF_DXT1: + return ((width+3)/4)*((height+3)/4)*8 * depth; + case PF_DXT2: + case PF_DXT3: + case PF_DXT4: + case PF_DXT5: + return ((width+3)/4)*((height+3)/4)*16 * depth; case PF_BC4_SNORM: case PF_BC4_UNORM: return ceilf(width/4.0f)*ceilf(height/4.0f)*8.0f; @@ -145,16 +145,16 @@ namespace Ogre { case PF_ATC_RGBA_INTERPOLATED_ALPHA: return ((width + 3) / 4) * ((height + 3) / 4) * 16; - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid compressed pixel format", - "PixelUtil::getMemorySize"); - } - } - else - { - return width*height*depth*getNumElemBytes(format); - } - } + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid compressed pixel format", + "PixelUtil::getMemorySize"); + } + } + else + { + return width*height*depth*getNumElemBytes(format); + } + } //----------------------------------------------------------------------- size_t PixelUtil::getNumElemBits( PixelFormat format ) { @@ -201,17 +201,17 @@ namespace Ogre { return (PixelUtil::getFlags(format) & PFF_LUMINANCE) > 0; } //----------------------------------------------------------------------- - bool PixelUtil::isValidExtent(size_t width, size_t height, size_t depth, PixelFormat format) - { - if(isCompressed(format)) - { - switch(format) - { - case PF_DXT1: - case PF_DXT2: - case PF_DXT3: - case PF_DXT4: - case PF_DXT5: + bool PixelUtil::isValidExtent(size_t width, size_t height, size_t depth, PixelFormat format) + { + if(isCompressed(format)) + { + switch(format) + { + case PF_DXT1: + case PF_DXT2: + case PF_DXT3: + case PF_DXT4: + case PF_DXT5: case PF_BC4_SNORM: case PF_BC4_UNORM: case PF_BC5_SNORM: @@ -220,17 +220,17 @@ namespace Ogre { case PF_BC6H_UF16: case PF_BC7_UNORM: case PF_BC7_UNORM_SRGB: - return ((width&3)==0 && (height&3)==0 && depth==1); - default: - return true; - } - } - else - { - return true; - } - } - //----------------------------------------------------------------------- + return ((width&3)==0 && (height&3)==0 && depth==1); + default: + return true; + } + } + else + { + return true; + } + } + //----------------------------------------------------------------------- void PixelUtil::getBitDepths(PixelFormat format, int rgba[4]) { const PixelFormatDescription &des = getDescriptionFor(format); @@ -239,8 +239,8 @@ namespace Ogre { rgba[2] = des.bbits; rgba[3] = des.abits; } - //----------------------------------------------------------------------- - void PixelUtil::getBitMasks(PixelFormat format, uint64 rgba[4]) + //----------------------------------------------------------------------- + void PixelUtil::getBitMasks(PixelFormat format, uint64 rgba[4]) { const PixelFormatDescription &des = getDescriptionFor(format); rgba[0] = des.rmask; @@ -248,15 +248,15 @@ namespace Ogre { rgba[2] = des.bmask; rgba[3] = des.amask; } - //--------------------------------------------------------------------- - void PixelUtil::getBitShifts(PixelFormat format, unsigned char rgba[4]) - { - const PixelFormatDescription &des = getDescriptionFor(format); - rgba[0] = des.rshift; - rgba[1] = des.gshift; - rgba[2] = des.bshift; - rgba[3] = des.ashift; - } + //--------------------------------------------------------------------- + void PixelUtil::getBitShifts(PixelFormat format, unsigned char rgba[4]) + { + const PixelFormatDescription &des = getDescriptionFor(format); + rgba[0] = des.rshift; + rgba[1] = des.gshift; + rgba[2] = des.bshift; + rgba[3] = des.ashift; + } //----------------------------------------------------------------------- String PixelUtil::getFormatName(PixelFormat srcformat) { @@ -480,10 +480,10 @@ namespace Ogre { case PF_FLOAT32_R: ((float*)dest)[0] = r; break; - case PF_FLOAT32_GR: - ((float*)dest)[0] = g; - ((float*)dest)[1] = r; - break; + case PF_FLOAT32_GR: + ((float*)dest)[0] = g; + ((float*)dest)[1] = r; + break; case PF_FLOAT32_RGB: ((float*)dest)[0] = r; ((float*)dest)[1] = g; @@ -499,10 +499,10 @@ namespace Ogre { case PF_FLOAT16_R: ((uint16*)dest)[0] = Bitwise::floatToHalf(r); break; - case PF_FLOAT16_GR: - ((uint16*)dest)[0] = Bitwise::floatToHalf(g); - ((uint16*)dest)[1] = Bitwise::floatToHalf(r); - break; + case PF_FLOAT16_GR: + ((uint16*)dest)[0] = Bitwise::floatToHalf(g); + ((uint16*)dest)[1] = Bitwise::floatToHalf(r); + break; case PF_FLOAT16_RGB: ((uint16*)dest)[0] = Bitwise::floatToHalf(r); ((uint16*)dest)[1] = Bitwise::floatToHalf(g); @@ -515,20 +515,20 @@ namespace Ogre { ((uint16*)dest)[3] = Bitwise::floatToHalf(a); break; case PF_SHORT_RGB: - ((uint16*)dest)[0] = (uint16)Bitwise::floatToFixed(r, 16); + ((uint16*)dest)[0] = (uint16)Bitwise::floatToFixed(r, 16); ((uint16*)dest)[1] = (uint16)Bitwise::floatToFixed(g, 16); ((uint16*)dest)[2] = (uint16)Bitwise::floatToFixed(b, 16); break; - case PF_SHORT_RGBA: - ((uint16*)dest)[0] = (uint16)Bitwise::floatToFixed(r, 16); + case PF_SHORT_RGBA: + ((uint16*)dest)[0] = (uint16)Bitwise::floatToFixed(r, 16); ((uint16*)dest)[1] = (uint16)Bitwise::floatToFixed(g, 16); ((uint16*)dest)[2] = (uint16)Bitwise::floatToFixed(b, 16); ((uint16*)dest)[3] = (uint16)Bitwise::floatToFixed(a, 16); - break; - case PF_BYTE_LA: - ((uint8*)dest)[0] = (uint8)Bitwise::floatToFixed(r, 8); + break; + case PF_BYTE_LA: + ((uint8*)dest)[0] = (uint8)Bitwise::floatToFixed(r, 8); ((uint8*)dest)[1] = (uint8)Bitwise::floatToFixed(a, 8); - break; + break; default: // Not yet supported OGRE_EXCEPT( @@ -616,11 +616,11 @@ namespace Ogre { *r = *g = *b = ((const float*)src)[0]; *a = 1.0f; break; - case PF_FLOAT32_GR: - *g = ((const float*)src)[0]; - *r = *b = ((const float*)src)[1]; - *a = 1.0f; - break; + case PF_FLOAT32_GR: + *g = ((const float*)src)[0]; + *r = *b = ((const float*)src)[1]; + *a = 1.0f; + break; case PF_FLOAT32_RGB: *r = ((const float*)src)[0]; *g = ((const float*)src)[1]; @@ -686,7 +686,7 @@ namespace Ogre { void *destp, PixelFormat dstFormat, unsigned int count) { PixelBox src(count, 1, 1, srcFormat, srcp), - dst(count, 1, 1, dstFormat, destp); + dst(count, 1, 1, dstFormat, destp); bulkPixelConversion(src, dst); } @@ -694,31 +694,31 @@ namespace Ogre { void PixelUtil::bulkPixelConversion(const PixelBox &src, const PixelBox &dst) { assert(src.getWidth() == dst.getWidth() && - src.getHeight() == dst.getHeight() && - src.getDepth() == dst.getDepth()); - - // Check for compressed formats, we don't support decompression, compression or recoding - if(PixelUtil::isCompressed(src.format) || PixelUtil::isCompressed(dst.format)) - { - if(src.format == dst.format) - { - memcpy(dst.data, src.data, src.getConsecutiveSize()); - return; - } - else - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This method can not be used to compress or decompress images", - "PixelUtil::bulkPixelConversion"); - } - } + src.getHeight() == dst.getHeight() && + src.getDepth() == dst.getDepth()); + + // Check for compressed formats, we don't support decompression, compression or recoding + if(PixelUtil::isCompressed(src.format) || PixelUtil::isCompressed(dst.format)) + { + if(src.format == dst.format) + { + memcpy(dst.data, src.data, src.getConsecutiveSize()); + return; + } + else + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This method can not be used to compress or decompress images", + "PixelUtil::bulkPixelConversion"); + } + } // The easy case if(src.format == dst.format) { // Everything consecutive? if(src.isConsecutive() && dst.isConsecutive()) { - memcpy(dst.data, src.data, src.getConsecutiveSize()); + memcpy(dst.data, src.data, src.getConsecutiveSize()); return; } @@ -727,7 +727,7 @@ namespace Ogre { uint8 *srcptr = static_cast(src.data) + (src.left + src.top * src.rowPitch + src.front * src.slicePitch) * srcPixelSize; uint8 *dstptr = static_cast(dst.data) - + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch) * dstPixelSize; + + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch) * dstPixelSize; // Calculate pitches+skips in bytes const size_t srcRowPitchBytes = src.rowPitch*srcPixelSize; @@ -744,7 +744,7 @@ namespace Ogre { { for(size_t y=src.top; y= 1300 @@ -792,9 +792,9 @@ namespace Ogre { + (src.left + src.top * src.rowPitch + src.front * src.slicePitch) * srcPixelSize; uint8 *dstptr = static_cast(dst.data) + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch) * dstPixelSize; - - // Old way, not taking into account box dimensions - //uint8 *srcptr = static_cast(src.data), *dstptr = static_cast(dst.data); + + // Old way, not taking into account box dimensions + //uint8 *srcptr = static_cast(src.data), *dstptr = static_cast(dst.data); // Calculate pitches+skips in bytes const size_t srcRowSkipBytes = src.getRowSkip()*srcPixelSize; @@ -825,13 +825,13 @@ namespace Ogre { //----------------------------------------------------------------------- void PixelUtil::bulkPixelVerticalFlip(const PixelBox &box) { - // Check for compressed formats, we don't support decompression, compression or recoding - if(PixelUtil::isCompressed(box.format)) - { + // Check for compressed formats, we don't support decompression, compression or recoding + if(PixelUtil::isCompressed(box.format)) + { OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "This method can not be used for compressed formats", "PixelUtil::bulkPixelVerticalFlip"); - } + } const size_t pixelSize = PixelUtil::getNumElemBytes(box.format); const size_t copySize = (box.right - box.left) * pixelSize; diff --git a/OgreMain/src/OgrePlane.cpp b/OgreMain/src/OgrePlane.cpp index 16764bff4a7..a4f4f886fab 100644 --- a/OgreMain/src/OgrePlane.cpp +++ b/OgreMain/src/OgrePlane.cpp @@ -31,70 +31,70 @@ THE SOFTWARE. #include "OgreAxisAlignedBox.h" namespace Ogre { - //----------------------------------------------------------------------- - Plane::Plane () - { - normal = Vector3::ZERO; - d = 0.0; - } - //----------------------------------------------------------------------- - Plane::Plane (const Plane& rhs) - { - normal = rhs.normal; - d = rhs.d; - } - //----------------------------------------------------------------------- - Plane::Plane (const Vector3& rkNormal, Real fConstant) - { - normal = rkNormal; - d = -fConstant; - } - //--------------------------------------------------------------------- - Plane::Plane (Real a, Real b, Real c, Real _d) - : normal(a, b, c), d(_d) - { - } - //----------------------------------------------------------------------- - Plane::Plane (const Vector3& rkNormal, const Vector3& rkPoint) - { - redefine(rkNormal, rkPoint); - } - //----------------------------------------------------------------------- - Plane::Plane (const Vector3& rkPoint0, const Vector3& rkPoint1, - const Vector3& rkPoint2) - { - redefine(rkPoint0, rkPoint1, rkPoint2); - } - //----------------------------------------------------------------------- - Real Plane::getDistance (const Vector3& rkPoint) const - { - return normal.dotProduct(rkPoint) + d; - } - //----------------------------------------------------------------------- - Plane::Side Plane::getSide (const Vector3& rkPoint) const - { - Real fDistance = getDistance(rkPoint); - - if ( fDistance < 0.0 ) - return Plane::NEGATIVE_SIDE; - - if ( fDistance > 0.0 ) - return Plane::POSITIVE_SIDE; - - return Plane::NO_SIDE; - } - - - //----------------------------------------------------------------------- - Plane::Side Plane::getSide (const AxisAlignedBox& box) const - { - if (box.isNull()) - return NO_SIDE; - if (box.isInfinite()) - return BOTH_SIDE; + //----------------------------------------------------------------------- + Plane::Plane () + { + normal = Vector3::ZERO; + d = 0.0; + } + //----------------------------------------------------------------------- + Plane::Plane (const Plane& rhs) + { + normal = rhs.normal; + d = rhs.d; + } + //----------------------------------------------------------------------- + Plane::Plane (const Vector3& rkNormal, Real fConstant) + { + normal = rkNormal; + d = -fConstant; + } + //--------------------------------------------------------------------- + Plane::Plane (Real a, Real b, Real c, Real _d) + : normal(a, b, c), d(_d) + { + } + //----------------------------------------------------------------------- + Plane::Plane (const Vector3& rkNormal, const Vector3& rkPoint) + { + redefine(rkNormal, rkPoint); + } + //----------------------------------------------------------------------- + Plane::Plane (const Vector3& rkPoint0, const Vector3& rkPoint1, + const Vector3& rkPoint2) + { + redefine(rkPoint0, rkPoint1, rkPoint2); + } + //----------------------------------------------------------------------- + Real Plane::getDistance (const Vector3& rkPoint) const + { + return normal.dotProduct(rkPoint) + d; + } + //----------------------------------------------------------------------- + Plane::Side Plane::getSide (const Vector3& rkPoint) const + { + Real fDistance = getDistance(rkPoint); + + if ( fDistance < 0.0 ) + return Plane::NEGATIVE_SIDE; + + if ( fDistance > 0.0 ) + return Plane::POSITIVE_SIDE; + + return Plane::NO_SIDE; + } + + + //----------------------------------------------------------------------- + Plane::Side Plane::getSide (const AxisAlignedBox& box) const + { + if (box.isNull()) + return NO_SIDE; + if (box.isInfinite()) + return BOTH_SIDE; return getSide(box.getCenter(), box.getHalfSize()); - } + } //----------------------------------------------------------------------- Plane::Side Plane::getSide (const Vector3& centre, const Vector3& halfSize) const { @@ -113,46 +113,46 @@ namespace Ogre { return Plane::BOTH_SIDE; } - //----------------------------------------------------------------------- - void Plane::redefine(const Vector3& rkPoint0, const Vector3& rkPoint1, - const Vector3& rkPoint2) - { - Vector3 kEdge1 = rkPoint1 - rkPoint0; - Vector3 kEdge2 = rkPoint2 - rkPoint0; - normal = kEdge1.crossProduct(kEdge2); - normal.normalise(); - d = -normal.dotProduct(rkPoint0); - } - //----------------------------------------------------------------------- - void Plane::redefine(const Vector3& rkNormal, const Vector3& rkPoint) - { - normal = rkNormal; - d = -rkNormal.dotProduct(rkPoint); - } - //----------------------------------------------------------------------- - Vector3 Plane::projectVector(const Vector3& p) const - { - // We know plane normal is unit length, so use simple method - Matrix3 xform; - xform[0][0] = 1.0f - normal.x * normal.x; - xform[0][1] = -normal.x * normal.y; - xform[0][2] = -normal.x * normal.z; - xform[1][0] = -normal.y * normal.x; - xform[1][1] = 1.0f - normal.y * normal.y; - xform[1][2] = -normal.y * normal.z; - xform[2][0] = -normal.z * normal.x; - xform[2][1] = -normal.z * normal.y; - xform[2][2] = 1.0f - normal.z * normal.z; - return xform * p; - - } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + void Plane::redefine(const Vector3& rkPoint0, const Vector3& rkPoint1, + const Vector3& rkPoint2) + { + Vector3 kEdge1 = rkPoint1 - rkPoint0; + Vector3 kEdge2 = rkPoint2 - rkPoint0; + normal = kEdge1.crossProduct(kEdge2); + normal.normalise(); + d = -normal.dotProduct(rkPoint0); + } + //----------------------------------------------------------------------- + void Plane::redefine(const Vector3& rkNormal, const Vector3& rkPoint) + { + normal = rkNormal; + d = -rkNormal.dotProduct(rkPoint); + } + //----------------------------------------------------------------------- + Vector3 Plane::projectVector(const Vector3& p) const + { + // We know plane normal is unit length, so use simple method + Matrix3 xform; + xform[0][0] = 1.0f - normal.x * normal.x; + xform[0][1] = -normal.x * normal.y; + xform[0][2] = -normal.x * normal.z; + xform[1][0] = -normal.y * normal.x; + xform[1][1] = 1.0f - normal.y * normal.y; + xform[1][2] = -normal.y * normal.z; + xform[2][0] = -normal.z * normal.x; + xform[2][1] = -normal.z * normal.y; + xform[2][2] = 1.0f - normal.z * normal.z; + return xform * p; + + } + //----------------------------------------------------------------------- Real Plane::normalise(void) { Real fLength = normal.length(); // Will also work for zero-sized vectors, but will change nothing - // We're not using epsilons because we don't need to. + // We're not using epsilons because we don't need to. // Read http://www.ogre3d.org/forums/viewtopic.php?f=4&t=61259 if ( fLength > Real(0.0f) ) { @@ -163,10 +163,10 @@ namespace Ogre { return fLength; } - //----------------------------------------------------------------------- - std::ostream& operator<< (std::ostream& o, const Plane& p) - { - o << "Plane(normal=" << p.normal << ", d=" << p.d << ")"; - return o; - } + //----------------------------------------------------------------------- + std::ostream& operator<< (std::ostream& o, const Plane& p) + { + o << "Plane(normal=" << p.normal << ", d=" << p.d << ")"; + return o; + } } // namespace Ogre diff --git a/OgreMain/src/OgrePlatformInformation.cpp b/OgreMain/src/OgrePlatformInformation.cpp index 3edacf19be4..1e371d4c94c 100644 --- a/OgreMain/src/OgrePlatformInformation.cpp +++ b/OgreMain/src/OgrePlatformInformation.cpp @@ -31,9 +31,9 @@ THE SOFTWARE. #if OGRE_COMPILER == OGRE_COMPILER_MSVC #include // For SEH values - #if _MSC_VER >= 1400 - #include - #endif + #if _MSC_VER >= 1400 + #include + #endif #elif (OGRE_COMPILER == OGRE_COMPILER_GNUC || OGRE_COMPILER == OGRE_COMPILER_CLANG) && OGRE_PLATFORM != OGRE_PLATFORM_NACL #include #include @@ -86,13 +86,13 @@ namespace Ogre { static int _isSupportCpuid(void) { #if OGRE_COMPILER == OGRE_COMPILER_MSVC - // Visual Studio 2005 & 64-bit compilers always supports __cpuid intrinsic - // note that even though this is a build rather than runtime setting, all - // 64-bit CPUs support this so since binary is 64-bit only we're ok - #if _MSC_VER >= 1400 && defined(_M_X64) - return true; - #else - // If we can modify flag register bit 21, the cpu is supports CPUID instruction + // Visual Studio 2005 & 64-bit compilers always supports __cpuid intrinsic + // note that even though this is a build rather than runtime setting, all + // 64-bit CPUs support this so since binary is 64-bit only we're ok + #if _MSC_VER >= 1400 && defined(_M_X64) + return true; + #else + // If we can modify flag register bit 21, the cpu is supports CPUID instruction __asm { // Read EFLAG @@ -120,7 +120,7 @@ namespace Ogre { // Return values in eax, no return statement requirement here for VC. } - #endif + #endif #elif (OGRE_COMPILER == OGRE_COMPILER_GNUC || OGRE_COMPILER == OGRE_COMPILER_CLANG) && OGRE_PLATFORM != OGRE_PLATFORM_NACL #if OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_64 return true; @@ -154,15 +154,15 @@ namespace Ogre { static uint _performCpuid(int query, CpuidResult& result) { #if OGRE_COMPILER == OGRE_COMPILER_MSVC - #if _MSC_VER >= 1400 - int CPUInfo[4]; - __cpuid(CPUInfo, query); - result._eax = CPUInfo[0]; - result._ebx = CPUInfo[1]; - result._ecx = CPUInfo[2]; - result._edx = CPUInfo[3]; - return result._eax; - #else + #if _MSC_VER >= 1400 + int CPUInfo[4]; + __cpuid(CPUInfo, query); + result._eax = CPUInfo[0]; + result._ebx = CPUInfo[1]; + result._ecx = CPUInfo[2]; + result._edx = CPUInfo[3]; + return result._eax; + #else __asm { mov edi, result @@ -174,7 +174,7 @@ namespace Ogre { mov [edi]._ecx, ecx // Return values in eax, no return statement requirement here for VC. } - #endif + #endif #elif (OGRE_COMPILER == OGRE_COMPILER_GNUC || OGRE_COMPILER == OGRE_COMPILER_CLANG) && OGRE_PLATFORM != OGRE_PLATFORM_NACL #if OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_64 __asm__ @@ -233,12 +233,12 @@ namespace Ogre { exception using the (non-standard) __try/__except mechanism of Microsoft Visual C/C++. */ - // Visual Studio 2005, Both AMD and Intel x64 support SSE - // note that even though this is a build rather than runtime setting, all - // 64-bit CPUs support this so since binary is 64-bit only we're ok - #if _MSC_VER >= 1400 && defined(_M_X64) - return true; - #else + // Visual Studio 2005, Both AMD and Intel x64 support SSE + // note that even though this is a build rather than runtime setting, all + // 64-bit CPUs support this so since binary is 64-bit only we're ok + #if _MSC_VER >= 1400 && defined(_M_X64) + return true; + #else __try { __asm orps xmm0, xmm0 @@ -248,7 +248,7 @@ namespace Ogre { { return false; } - #endif + #endif #elif (OGRE_COMPILER == OGRE_COMPILER_GNUC || OGRE_COMPILER == OGRE_COMPILER_CLANG) && OGRE_PLATFORM != OGRE_PLATFORM_NACL #if OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_64 return true; @@ -403,73 +403,73 @@ namespace Ogre { //--------------------------------------------------------------------- static String _detectCpuIdentifier(void) { - // Supports CPUID instruction ? - if (_isSupportCpuid()) - { - CpuidResult result; - uint nExIds; - char CPUString[0x20]; - char CPUBrandString[0x40]; + // Supports CPUID instruction ? + if (_isSupportCpuid()) + { + CpuidResult result; + uint nExIds; + char CPUString[0x20]; + char CPUBrandString[0x40]; - StringStream detailedIdentStr; + StringStream detailedIdentStr; - // Has standard feature ? - if (_performCpuid(0, result)) - { - memset(CPUString, 0, sizeof(CPUString)); - memset(CPUBrandString, 0, sizeof(CPUBrandString)); + // Has standard feature ? + if (_performCpuid(0, result)) + { + memset(CPUString, 0, sizeof(CPUString)); + memset(CPUBrandString, 0, sizeof(CPUBrandString)); - //*((int*)CPUString) = result._ebx; + //*((int*)CPUString) = result._ebx; memcpy(CPUString, &result._ebx, sizeof(int)); - //*((int*)(CPUString+4)) = result._edx; + //*((int*)(CPUString+4)) = result._edx; //*((int*)(CPUString+8)) = result._ecx; memcpy(CPUString+8, &result._ecx, sizeof(int)); - detailedIdentStr << CPUString; + detailedIdentStr << CPUString; - // Calling _performCpuid with 0x80000000 as the query argument - // gets the number of valid extended IDs. - nExIds = _performCpuid(0x80000000, result); + // Calling _performCpuid with 0x80000000 as the query argument + // gets the number of valid extended IDs. + nExIds = _performCpuid(0x80000000, result); - for (uint i=0x80000000; i<=nExIds; ++i) - { - _performCpuid(i, result); + for (uint i=0x80000000; i<=nExIds; ++i) + { + _performCpuid(i, result); - // Interpret CPU brand string and cache information. - if (i == 0x80000002) + // Interpret CPU brand string and cache information. + if (i == 0x80000002) { - memcpy(CPUBrandString + 0, &result._eax, sizeof(result._eax)); - memcpy(CPUBrandString + 4, &result._ebx, sizeof(result._ebx)); - memcpy(CPUBrandString + 8, &result._ecx, sizeof(result._ecx)); - memcpy(CPUBrandString + 12, &result._edx, sizeof(result._edx)); + memcpy(CPUBrandString + 0, &result._eax, sizeof(result._eax)); + memcpy(CPUBrandString + 4, &result._ebx, sizeof(result._ebx)); + memcpy(CPUBrandString + 8, &result._ecx, sizeof(result._ecx)); + memcpy(CPUBrandString + 12, &result._edx, sizeof(result._edx)); } - else if (i == 0x80000003) + else if (i == 0x80000003) { - memcpy(CPUBrandString + 16 + 0, &result._eax, sizeof(result._eax)); - memcpy(CPUBrandString + 16 + 4, &result._ebx, sizeof(result._ebx)); - memcpy(CPUBrandString + 16 + 8, &result._ecx, sizeof(result._ecx)); - memcpy(CPUBrandString + 16 + 12, &result._edx, sizeof(result._edx)); + memcpy(CPUBrandString + 16 + 0, &result._eax, sizeof(result._eax)); + memcpy(CPUBrandString + 16 + 4, &result._ebx, sizeof(result._ebx)); + memcpy(CPUBrandString + 16 + 8, &result._ecx, sizeof(result._ecx)); + memcpy(CPUBrandString + 16 + 12, &result._edx, sizeof(result._edx)); } - else if (i == 0x80000004) + else if (i == 0x80000004) { - memcpy(CPUBrandString + 32 + 0, &result._eax, sizeof(result._eax)); - memcpy(CPUBrandString + 32 + 4, &result._ebx, sizeof(result._ebx)); - memcpy(CPUBrandString + 32 + 8, &result._ecx, sizeof(result._ecx)); - memcpy(CPUBrandString + 32 + 12, &result._edx, sizeof(result._edx)); + memcpy(CPUBrandString + 32 + 0, &result._eax, sizeof(result._eax)); + memcpy(CPUBrandString + 32 + 4, &result._ebx, sizeof(result._ebx)); + memcpy(CPUBrandString + 32 + 8, &result._ecx, sizeof(result._ecx)); + memcpy(CPUBrandString + 32 + 12, &result._edx, sizeof(result._edx)); } - } + } - String brand(CPUBrandString); - StringUtil::trim(brand); - if (!brand.empty()) - detailedIdentStr << ": " << brand; + String brand(CPUBrandString); + StringUtil::trim(brand); + if (!brand.empty()) + detailedIdentStr << ": " << brand; - return detailedIdentStr.str(); - } - } + return detailedIdentStr.str(); + } + } - return "X86"; + return "X86"; } #elif OGRE_PLATFORM == OGRE_PLATFORM_ANDROID @@ -630,58 +630,58 @@ namespace Ogre { static const uint sFeatures = _detectCpuFeatures(); return sFeatures; } - //--------------------------------------------------------------------- - bool PlatformInformation::hasCpuFeature(CpuFeatures feature) - { - return (getCpuFeatures() & feature) != 0; - } - //--------------------------------------------------------------------- - void PlatformInformation::log(Log* pLog) - { - pLog->logMessage("CPU Identifier & Features"); - pLog->logMessage("-------------------------"); - pLog->logMessage( - " * CPU ID: " + getCpuIdentifier()); + //--------------------------------------------------------------------- + bool PlatformInformation::hasCpuFeature(CpuFeatures feature) + { + return (getCpuFeatures() & feature) != 0; + } + //--------------------------------------------------------------------- + void PlatformInformation::log(Log* pLog) + { + pLog->logMessage("CPU Identifier & Features"); + pLog->logMessage("-------------------------"); + pLog->logMessage( + " * CPU ID: " + getCpuIdentifier()); #if OGRE_CPU == OGRE_CPU_X86 - if(_isSupportCpuid()) - { - pLog->logMessage( - " * SSE: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_SSE), true)); - pLog->logMessage( - " * SSE2: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_SSE2), true)); - pLog->logMessage( - " * SSE3: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_SSE3), true)); - pLog->logMessage( - " * MMX: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_MMX), true)); - pLog->logMessage( - " * MMXEXT: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_MMXEXT), true)); - pLog->logMessage( - " * 3DNOW: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_3DNOW), true)); - pLog->logMessage( - " * 3DNOWEXT: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_3DNOWEXT), true)); - pLog->logMessage( - " * CMOV: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_CMOV), true)); - pLog->logMessage( - " * TSC: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_TSC), true)); - pLog->logMessage( - " * FPU: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_FPU), true)); - pLog->logMessage( - " * PRO: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_PRO), true)); - pLog->logMessage( - " * HT: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_HTT), true)); - } + if(_isSupportCpuid()) + { + pLog->logMessage( + " * SSE: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_SSE), true)); + pLog->logMessage( + " * SSE2: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_SSE2), true)); + pLog->logMessage( + " * SSE3: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_SSE3), true)); + pLog->logMessage( + " * MMX: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_MMX), true)); + pLog->logMessage( + " * MMXEXT: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_MMXEXT), true)); + pLog->logMessage( + " * 3DNOW: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_3DNOW), true)); + pLog->logMessage( + " * 3DNOWEXT: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_3DNOWEXT), true)); + pLog->logMessage( + " * CMOV: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_CMOV), true)); + pLog->logMessage( + " * TSC: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_TSC), true)); + pLog->logMessage( + " * FPU: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_FPU), true)); + pLog->logMessage( + " * PRO: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_PRO), true)); + pLog->logMessage( + " * HT: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_HTT), true)); + } #elif OGRE_CPU == OGRE_CPU_ARM || OGRE_PLATFORM == OGRE_PLATFORM_ANDROID pLog->logMessage( - " * VFP: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_VFP), true)); + " * VFP: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_VFP), true)); pLog->logMessage( - " * NEON: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_NEON), true)); + " * NEON: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_NEON), true)); #elif OGRE_CPU == OGRE_CPU_MIPS pLog->logMessage( " * MSA: " + StringConverter::toString(hasCpuFeature(CPU_FEATURE_MSA), true)); #endif - pLog->logMessage("-------------------------"); + pLog->logMessage("-------------------------"); - } + } } diff --git a/OgreMain/src/OgrePolygon.cpp b/OgreMain/src/OgrePolygon.cpp index 884768abb1c..8b6edcd4d76 100644 --- a/OgreMain/src/OgrePolygon.cpp +++ b/OgreMain/src/OgrePolygon.cpp @@ -5,7 +5,7 @@ This source file is part of OGRE For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd -Copyright (c) 2006 Matthias Fink, netAllied GmbH +Copyright (c) 2006 Matthias Fink, netAllied GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -34,225 +34,225 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - Polygon::Polygon() - : mNormal( Vector3::ZERO ) - , mIsNormalSet(false) - { - // reserve space for 6 vertices to reduce allocation cost - mVertexList.reserve(6); - } - //----------------------------------------------------------------------- - Polygon::~Polygon() - { - } - //----------------------------------------------------------------------- - Polygon::Polygon( const Polygon& cpy ) - { - mVertexList = cpy.mVertexList; - mNormal = cpy.mNormal; - mIsNormalSet = cpy.mIsNormalSet; - } - //----------------------------------------------------------------------- - void Polygon::insertVertex(const Vector3& vdata, size_t vertex ) - { - // TODO: optional: check planarity - OgreAssert(vertex <= getVertexCount(), "Insert position out of range" ); - - VertexList::iterator it = mVertexList.begin(); - - std::advance(it, vertex); - mVertexList.insert(it, vdata); - - } - //----------------------------------------------------------------------- - void Polygon::insertVertex(const Vector3& vdata) - { - mVertexList.push_back(vdata); - } - //----------------------------------------------------------------------- - const Vector3& Polygon::getVertex( size_t vertex ) const - { - OgreAssert(vertex < getVertexCount(), "Search position out of range"); - - return mVertexList[vertex]; - } - //----------------------------------------------------------------------- - void Polygon::setVertex(const Vector3& vdata, size_t vertex ) - { - // TODO: optional: check planarity - OgreAssert(vertex < getVertexCount(), "Search position out of range" ); - - // set new vertex - mVertexList[ vertex ] = vdata; - } - //----------------------------------------------------------------------- - void Polygon::removeDuplicates( void ) - { - for ( size_t i = 0; i < getVertexCount(); ++i ) - { - const Vector3& a = getVertex( i ); - const Vector3& b = getVertex( (i + 1)%getVertexCount() ); - - if (a.positionEquals(b)) - { - deleteVertex(i); - --i; - } - } - } - //----------------------------------------------------------------------- - size_t Polygon::getVertexCount( void ) const - { - return mVertexList.size(); - } - //----------------------------------------------------------------------- - const Vector3& Polygon::getNormal( void ) const - { - OgreAssert( getVertexCount() >= 3, "Insufficient vertex count!" ); - - updateNormal(); - - return mNormal; - } - //----------------------------------------------------------------------- - void Polygon::updateNormal( void ) const - { - OgreAssert( getVertexCount() >= 3, "Insufficient vertex count!" ); - - if (mIsNormalSet) - return; - - // vertex order is ccw - const Vector3& a = getVertex( 0 ); - const Vector3& b = getVertex( 1 ); - const Vector3& c = getVertex( 2 ); - - // used method: Newell - mNormal.x = 0.5f * ( (a.y - b.y) * (a.z + b.z) + - (b.y - c.y) * (b.z + c.z) + - (c.y - a.y) * (c.z + a.z)); - - mNormal.y = 0.5f * ( (a.z - b.z) * (a.x + b.x) + - (b.z - c.z) * (b.x + c.x) + - (c.z - a.z) * (c.x + a.x)); - - mNormal.z = 0.5f * ( (a.x - b.x) * (a.y + b.y) + - (b.x - c.x) * (b.y + c.y) + - (c.x - a.x) * (c.y + a.y)); - - mNormal.normalise(); - - mIsNormalSet = true; - - } - //----------------------------------------------------------------------- - void Polygon::deleteVertex( size_t vertex ) - { - OgreAssert( vertex < getVertexCount(), "Search position out of range" ); - - VertexList::iterator it = mVertexList.begin(); - std::advance(it, vertex); - - mVertexList.erase( it ); - } - //----------------------------------------------------------------------- - void Polygon::storeEdges( Polygon::EdgeMap *edgeMap ) const - { - OgreAssert( edgeMap != NULL, "EdgeMap ptr is NULL" ); - - size_t vertexCount = getVertexCount(); - - for ( size_t i = 0; i < vertexCount; ++i ) - { - edgeMap->insert( Edge( getVertex( i ), getVertex( ( i + 1 ) % vertexCount ) ) ); - } - } - //----------------------------------------------------------------------- - void Polygon::reset( void ) - { - // could use swap() to free memory here, but assume most may be reused so avoid realloc - mVertexList.clear(); - - mIsNormalSet = false; - } - //----------------------------------------------------------------------- - bool Polygon::operator == (const Polygon& rhs) const - { - if ( getVertexCount() != rhs.getVertexCount() ) - return false; - - // Compare vertices. They may differ in its starting position. - // find start - size_t start = 0; - bool foundStart = false; - for (size_t i = 0; i < getVertexCount(); ++i ) - { - if (getVertex(0).positionEquals(rhs.getVertex(i))) - { - start = i; - foundStart = true; - break; - } - } - - if (!foundStart) - return false; - - for (size_t i = 0; i < getVertexCount(); ++i ) - { - const Vector3& vA = getVertex( i ); - const Vector3& vB = rhs.getVertex( ( i + start) % getVertexCount() ); - - if (!vA.positionEquals(vB)) - return false; - } - - return true; - } - //----------------------------------------------------------------------- - std::ostream& operator<< ( std::ostream& strm, const Polygon& poly ) - { - strm << "NUM VERTICES: " << poly.getVertexCount() << std::endl; - - for (size_t j = 0; j < poly.getVertexCount(); ++j ) - { - strm << "VERTEX " << j << ": " << poly.getVertex( j ) << std::endl; - } - - return strm; - } - //----------------------------------------------------------------------- - bool Polygon::isPointInside(const Vector3& point) const - { - // sum the angles - Real anglesum = 0; - size_t n = getVertexCount(); - for (size_t i = 0; i < n; i++) - { - const Vector3& p1 = getVertex(i); - const Vector3& p2 = getVertex((i + 1) % n); - - Vector3 v1 = p1 - point; - Vector3 v2 = p2 - point; - - Real len1 = v1.length(); - Real len2 = v2.length(); - - if (Math::RealEqual(len1 * len2, 0.0f, 1e-4f)) - { - // We are on a vertex so consider this inside - return true; - } - else - { - Real costheta = v1.dotProduct(v2) / (len1 * len2); - anglesum += acos(costheta); - } - } - - // result should be 2*PI if point is inside poly - return Math::RealEqual(anglesum, Math::TWO_PI, 1e-4f); - - } + //----------------------------------------------------------------------- + Polygon::Polygon() + : mNormal( Vector3::ZERO ) + , mIsNormalSet(false) + { + // reserve space for 6 vertices to reduce allocation cost + mVertexList.reserve(6); + } + //----------------------------------------------------------------------- + Polygon::~Polygon() + { + } + //----------------------------------------------------------------------- + Polygon::Polygon( const Polygon& cpy ) + { + mVertexList = cpy.mVertexList; + mNormal = cpy.mNormal; + mIsNormalSet = cpy.mIsNormalSet; + } + //----------------------------------------------------------------------- + void Polygon::insertVertex(const Vector3& vdata, size_t vertex ) + { + // TODO: optional: check planarity + OgreAssert(vertex <= getVertexCount(), "Insert position out of range" ); + + VertexList::iterator it = mVertexList.begin(); + + std::advance(it, vertex); + mVertexList.insert(it, vdata); + + } + //----------------------------------------------------------------------- + void Polygon::insertVertex(const Vector3& vdata) + { + mVertexList.push_back(vdata); + } + //----------------------------------------------------------------------- + const Vector3& Polygon::getVertex( size_t vertex ) const + { + OgreAssert(vertex < getVertexCount(), "Search position out of range"); + + return mVertexList[vertex]; + } + //----------------------------------------------------------------------- + void Polygon::setVertex(const Vector3& vdata, size_t vertex ) + { + // TODO: optional: check planarity + OgreAssert(vertex < getVertexCount(), "Search position out of range" ); + + // set new vertex + mVertexList[ vertex ] = vdata; + } + //----------------------------------------------------------------------- + void Polygon::removeDuplicates( void ) + { + for ( size_t i = 0; i < getVertexCount(); ++i ) + { + const Vector3& a = getVertex( i ); + const Vector3& b = getVertex( (i + 1)%getVertexCount() ); + + if (a.positionEquals(b)) + { + deleteVertex(i); + --i; + } + } + } + //----------------------------------------------------------------------- + size_t Polygon::getVertexCount( void ) const + { + return mVertexList.size(); + } + //----------------------------------------------------------------------- + const Vector3& Polygon::getNormal( void ) const + { + OgreAssert( getVertexCount() >= 3, "Insufficient vertex count!" ); + + updateNormal(); + + return mNormal; + } + //----------------------------------------------------------------------- + void Polygon::updateNormal( void ) const + { + OgreAssert( getVertexCount() >= 3, "Insufficient vertex count!" ); + + if (mIsNormalSet) + return; + + // vertex order is ccw + const Vector3& a = getVertex( 0 ); + const Vector3& b = getVertex( 1 ); + const Vector3& c = getVertex( 2 ); + + // used method: Newell + mNormal.x = 0.5f * ( (a.y - b.y) * (a.z + b.z) + + (b.y - c.y) * (b.z + c.z) + + (c.y - a.y) * (c.z + a.z)); + + mNormal.y = 0.5f * ( (a.z - b.z) * (a.x + b.x) + + (b.z - c.z) * (b.x + c.x) + + (c.z - a.z) * (c.x + a.x)); + + mNormal.z = 0.5f * ( (a.x - b.x) * (a.y + b.y) + + (b.x - c.x) * (b.y + c.y) + + (c.x - a.x) * (c.y + a.y)); + + mNormal.normalise(); + + mIsNormalSet = true; + + } + //----------------------------------------------------------------------- + void Polygon::deleteVertex( size_t vertex ) + { + OgreAssert( vertex < getVertexCount(), "Search position out of range" ); + + VertexList::iterator it = mVertexList.begin(); + std::advance(it, vertex); + + mVertexList.erase( it ); + } + //----------------------------------------------------------------------- + void Polygon::storeEdges( Polygon::EdgeMap *edgeMap ) const + { + OgreAssert( edgeMap != NULL, "EdgeMap ptr is NULL" ); + + size_t vertexCount = getVertexCount(); + + for ( size_t i = 0; i < vertexCount; ++i ) + { + edgeMap->insert( Edge( getVertex( i ), getVertex( ( i + 1 ) % vertexCount ) ) ); + } + } + //----------------------------------------------------------------------- + void Polygon::reset( void ) + { + // could use swap() to free memory here, but assume most may be reused so avoid realloc + mVertexList.clear(); + + mIsNormalSet = false; + } + //----------------------------------------------------------------------- + bool Polygon::operator == (const Polygon& rhs) const + { + if ( getVertexCount() != rhs.getVertexCount() ) + return false; + + // Compare vertices. They may differ in its starting position. + // find start + size_t start = 0; + bool foundStart = false; + for (size_t i = 0; i < getVertexCount(); ++i ) + { + if (getVertex(0).positionEquals(rhs.getVertex(i))) + { + start = i; + foundStart = true; + break; + } + } + + if (!foundStart) + return false; + + for (size_t i = 0; i < getVertexCount(); ++i ) + { + const Vector3& vA = getVertex( i ); + const Vector3& vB = rhs.getVertex( ( i + start) % getVertexCount() ); + + if (!vA.positionEquals(vB)) + return false; + } + + return true; + } + //----------------------------------------------------------------------- + std::ostream& operator<< ( std::ostream& strm, const Polygon& poly ) + { + strm << "NUM VERTICES: " << poly.getVertexCount() << std::endl; + + for (size_t j = 0; j < poly.getVertexCount(); ++j ) + { + strm << "VERTEX " << j << ": " << poly.getVertex( j ) << std::endl; + } + + return strm; + } + //----------------------------------------------------------------------- + bool Polygon::isPointInside(const Vector3& point) const + { + // sum the angles + Real anglesum = 0; + size_t n = getVertexCount(); + for (size_t i = 0; i < n; i++) + { + const Vector3& p1 = getVertex(i); + const Vector3& p2 = getVertex((i + 1) % n); + + Vector3 v1 = p1 - point; + Vector3 v2 = p2 - point; + + Real len1 = v1.length(); + Real len2 = v2.length(); + + if (Math::RealEqual(len1 * len2, 0.0f, 1e-4f)) + { + // We are on a vertex so consider this inside + return true; + } + else + { + Real costheta = v1.dotProduct(v2) / (len1 * len2); + anglesum += acos(costheta); + } + } + + // result should be 2*PI if point is inside poly + return Math::RealEqual(anglesum, Math::TWO_PI, 1e-4f); + + } } diff --git a/OgreMain/src/OgrePose.cpp b/OgreMain/src/OgrePose.cpp index 592641670af..ddf481ce231 100644 --- a/OgreMain/src/OgrePose.cpp +++ b/OgreMain/src/OgrePose.cpp @@ -30,22 +30,22 @@ THE SOFTWARE. #include "OgreHardwareBufferManager.h" namespace Ogre { - //--------------------------------------------------------------------- - Pose::Pose(ushort target, const String& name) - : mTarget(target), mName(name) - { - } - //--------------------------------------------------------------------- - Pose::~Pose() - { - } - //--------------------------------------------------------------------- - void Pose::addVertex(size_t index, const Vector3& offset) - { - if (!mNormalsMap.empty()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Inconsistent calls to addVertex, must include normals always or never", - "Pose::addVertex"); + //--------------------------------------------------------------------- + Pose::Pose(ushort target, const String& name) + : mTarget(target), mName(name) + { + } + //--------------------------------------------------------------------- + Pose::~Pose() + { + } + //--------------------------------------------------------------------- + void Pose::addVertex(size_t index, const Vector3& offset) + { + if (!mNormalsMap.empty()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Inconsistent calls to addVertex, must include normals always or never", + "Pose::addVertex"); if(offset.squaredLength() < 1e-6f) { @@ -53,15 +53,15 @@ namespace Ogre { } mVertexOffsetMap[index] = offset; - mBuffer.setNull(); - } - //--------------------------------------------------------------------- - void Pose::addVertex(size_t index, const Vector3& offset, const Vector3& normal) - { - if (!mVertexOffsetMap.empty() && mNormalsMap.empty()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Inconsistent calls to addVertex, must include normals always or never", - "Pose::addVertex"); + mBuffer.setNull(); + } + //--------------------------------------------------------------------- + void Pose::addVertex(size_t index, const Vector3& offset, const Vector3& normal) + { + if (!mVertexOffsetMap.empty() && mNormalsMap.empty()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Inconsistent calls to addVertex, must include normals always or never", + "Pose::addVertex"); if(offset.squaredLength() < 1e-6f && normal.squaredLength() < 1e-6f) { @@ -69,136 +69,136 @@ namespace Ogre { } mVertexOffsetMap[index] = offset; - mNormalsMap[index] = normal; - mBuffer.setNull(); - } - //--------------------------------------------------------------------- - void Pose::removeVertex(size_t index) - { - VertexOffsetMap::iterator i = mVertexOffsetMap.find(index); - if (i != mVertexOffsetMap.end()) - { - mVertexOffsetMap.erase(i); - mBuffer.setNull(); - } - NormalsMap::iterator j = mNormalsMap.find(index); - if (j != mNormalsMap.end()) - { - mNormalsMap.erase(j); - } - } - //--------------------------------------------------------------------- - void Pose::clearVertices(void) - { - mVertexOffsetMap.clear(); - mNormalsMap.clear(); - mBuffer.setNull(); - } - //--------------------------------------------------------------------- - Pose::ConstVertexOffsetIterator - Pose::getVertexOffsetIterator(void) const - { - return ConstVertexOffsetIterator(mVertexOffsetMap.begin(), mVertexOffsetMap.end()); - } - //--------------------------------------------------------------------- - Pose::VertexOffsetIterator - Pose::getVertexOffsetIterator(void) - { - return VertexOffsetIterator(mVertexOffsetMap.begin(), mVertexOffsetMap.end()); - } - //--------------------------------------------------------------------- - Pose::ConstNormalsIterator Pose::getNormalsIterator(void) const - { - return ConstNormalsIterator(mNormalsMap.begin(), mNormalsMap.end()); - } - //--------------------------------------------------------------------- - Pose::NormalsIterator Pose::getNormalsIterator(void) - { - return NormalsIterator(mNormalsMap.begin(), mNormalsMap.end()); - } - //--------------------------------------------------------------------- - const HardwareVertexBufferSharedPtr& Pose::_getHardwareVertexBuffer(const VertexData* origData) const - { - size_t numVertices = origData->vertexCount; - - if (mBuffer.isNull()) - { - // Create buffer - size_t vertexSize = VertexElement::getTypeSize(VET_FLOAT3); - bool normals = getIncludesNormals(); - if (normals) - vertexSize += VertexElement::getTypeSize(VET_FLOAT3); - - mBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( - vertexSize, numVertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); + mNormalsMap[index] = normal; + mBuffer.setNull(); + } + //--------------------------------------------------------------------- + void Pose::removeVertex(size_t index) + { + VertexOffsetMap::iterator i = mVertexOffsetMap.find(index); + if (i != mVertexOffsetMap.end()) + { + mVertexOffsetMap.erase(i); + mBuffer.setNull(); + } + NormalsMap::iterator j = mNormalsMap.find(index); + if (j != mNormalsMap.end()) + { + mNormalsMap.erase(j); + } + } + //--------------------------------------------------------------------- + void Pose::clearVertices(void) + { + mVertexOffsetMap.clear(); + mNormalsMap.clear(); + mBuffer.setNull(); + } + //--------------------------------------------------------------------- + Pose::ConstVertexOffsetIterator + Pose::getVertexOffsetIterator(void) const + { + return ConstVertexOffsetIterator(mVertexOffsetMap.begin(), mVertexOffsetMap.end()); + } + //--------------------------------------------------------------------- + Pose::VertexOffsetIterator + Pose::getVertexOffsetIterator(void) + { + return VertexOffsetIterator(mVertexOffsetMap.begin(), mVertexOffsetMap.end()); + } + //--------------------------------------------------------------------- + Pose::ConstNormalsIterator Pose::getNormalsIterator(void) const + { + return ConstNormalsIterator(mNormalsMap.begin(), mNormalsMap.end()); + } + //--------------------------------------------------------------------- + Pose::NormalsIterator Pose::getNormalsIterator(void) + { + return NormalsIterator(mNormalsMap.begin(), mNormalsMap.end()); + } + //--------------------------------------------------------------------- + const HardwareVertexBufferSharedPtr& Pose::_getHardwareVertexBuffer(const VertexData* origData) const + { + size_t numVertices = origData->vertexCount; + + if (mBuffer.isNull()) + { + // Create buffer + size_t vertexSize = VertexElement::getTypeSize(VET_FLOAT3); + bool normals = getIncludesNormals(); + if (normals) + vertexSize += VertexElement::getTypeSize(VET_FLOAT3); + + mBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( + vertexSize, numVertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - float* pFloat = static_cast( - mBuffer->lock(HardwareBuffer::HBL_DISCARD)); - // initialise - these will be the values used where no pose vertex is included - memset(pFloat, 0, mBuffer->getSizeInBytes()); - if (normals) - { - // zeroes are fine for positions (deltas), but for normals we need the original - // mesh normals, since delta normals don't work (re-normalisation would - // always result in a blended normal even with full pose applied) - const VertexElement* origNormElem = - origData->vertexDeclaration->findElementBySemantic(VES_NORMAL, 0); - assert(origNormElem); - - const HardwareVertexBufferSharedPtr& origBuffer = - origData->vertexBufferBinding->getBuffer(origNormElem->getSource()); - float* pDst = pFloat + 3; - void* pSrcBase = origBuffer->lock(HardwareBuffer::HBL_READ_ONLY); - float* pSrc; - origNormElem->baseVertexPointerToElement(pSrcBase, &pSrc); - for (size_t v = 0; v < numVertices; ++v) - { - memcpy(pDst, pSrc, sizeof(float)*3); - - pDst += 6; - pSrc = (float*)(((char*)pSrc) + origBuffer->getVertexSize()); - } - origBuffer->unlock(); - - - } - // Set each vertex - VertexOffsetMap::const_iterator v = mVertexOffsetMap.begin(); - NormalsMap::const_iterator n = mNormalsMap.begin(); - - size_t numFloatsPerVertex = normals ? 6: 3; - - while(v != mVertexOffsetMap.end()) - { - // Remember, vertex maps are *sparse* so may have missing entries - // This is why we skip - float* pDst = pFloat + (numFloatsPerVertex * v->first); - *pDst++ = v->second.x; - *pDst++ = v->second.y; - *pDst++ = v->second.z; - ++v; - if (normals) - { - *pDst++ = n->second.x; - *pDst++ = n->second.y; - *pDst++ = n->second.z; - ++n; - } - - } - mBuffer->unlock(); - } - return mBuffer; - } - //--------------------------------------------------------------------- - Pose* Pose::clone(void) const - { - Pose* newPose = OGRE_NEW Pose(mTarget, mName); - newPose->mVertexOffsetMap = mVertexOffsetMap; + float* pFloat = static_cast( + mBuffer->lock(HardwareBuffer::HBL_DISCARD)); + // initialise - these will be the values used where no pose vertex is included + memset(pFloat, 0, mBuffer->getSizeInBytes()); + if (normals) + { + // zeroes are fine for positions (deltas), but for normals we need the original + // mesh normals, since delta normals don't work (re-normalisation would + // always result in a blended normal even with full pose applied) + const VertexElement* origNormElem = + origData->vertexDeclaration->findElementBySemantic(VES_NORMAL, 0); + assert(origNormElem); + + const HardwareVertexBufferSharedPtr& origBuffer = + origData->vertexBufferBinding->getBuffer(origNormElem->getSource()); + float* pDst = pFloat + 3; + void* pSrcBase = origBuffer->lock(HardwareBuffer::HBL_READ_ONLY); + float* pSrc; + origNormElem->baseVertexPointerToElement(pSrcBase, &pSrc); + for (size_t v = 0; v < numVertices; ++v) + { + memcpy(pDst, pSrc, sizeof(float)*3); + + pDst += 6; + pSrc = (float*)(((char*)pSrc) + origBuffer->getVertexSize()); + } + origBuffer->unlock(); + + + } + // Set each vertex + VertexOffsetMap::const_iterator v = mVertexOffsetMap.begin(); + NormalsMap::const_iterator n = mNormalsMap.begin(); + + size_t numFloatsPerVertex = normals ? 6: 3; + + while(v != mVertexOffsetMap.end()) + { + // Remember, vertex maps are *sparse* so may have missing entries + // This is why we skip + float* pDst = pFloat + (numFloatsPerVertex * v->first); + *pDst++ = v->second.x; + *pDst++ = v->second.y; + *pDst++ = v->second.z; + ++v; + if (normals) + { + *pDst++ = n->second.x; + *pDst++ = n->second.y; + *pDst++ = n->second.z; + ++n; + } + + } + mBuffer->unlock(); + } + return mBuffer; + } + //--------------------------------------------------------------------- + Pose* Pose::clone(void) const + { + Pose* newPose = OGRE_NEW Pose(mTarget, mName); + newPose->mVertexOffsetMap = mVertexOffsetMap; newPose->mNormalsMap = mNormalsMap; - // Allow buffer to recreate itself, contents may change anyway - return newPose; - } + // Allow buffer to recreate itself, contents may change anyway + return newPose; + } } diff --git a/OgreMain/src/OgrePredefinedControllers.cpp b/OgreMain/src/OgrePredefinedControllers.cpp index ca98bb86451..45d6fdd1b03 100644 --- a/OgreMain/src/OgrePredefinedControllers.cpp +++ b/OgreMain/src/OgrePredefinedControllers.cpp @@ -42,25 +42,25 @@ namespace Ogre // Register self Root::getSingleton().addFrameListener(this); mFrameTime = 0; - mTimeFactor = 1; - mFrameDelay = 0; + mTimeFactor = 1; + mFrameDelay = 0; mElapsedTime = 0; } //----------------------------------------------------------------------- bool FrameTimeControllerValue::frameStarted(const FrameEvent &evt) { - if(mFrameDelay) - { - // Fixed frame time - mFrameTime = mFrameDelay; - mTimeFactor = mFrameDelay / evt.timeSinceLastFrame; - } - else - { - // Save the time value after applying time factor - mFrameTime = mTimeFactor * evt.timeSinceLastFrame; - } + if(mFrameDelay) + { + // Fixed frame time + mFrameTime = mFrameDelay; + mTimeFactor = mFrameDelay / evt.timeSinceLastFrame; + } + else + { + // Save the time value after applying time factor + mFrameTime = mTimeFactor * evt.timeSinceLastFrame; + } // Accumulate the elapsed time mElapsedTime += mFrameTime; return true; @@ -80,27 +80,27 @@ namespace Ogre { // Do nothing - value is set from frame listener } - //----------------------------------------------------------------------- - Real FrameTimeControllerValue::getTimeFactor(void) const { - return mTimeFactor; - } - //----------------------------------------------------------------------- - void FrameTimeControllerValue::setTimeFactor(Real tf) { - if(tf >= 0) - { - mTimeFactor = tf; - mFrameDelay = 0; - } - } - //----------------------------------------------------------------------- - Real FrameTimeControllerValue::getFrameDelay(void) const { - return mFrameDelay; - } - //----------------------------------------------------------------------- - void FrameTimeControllerValue::setFrameDelay(Real fd) { - mTimeFactor = 0; - mFrameDelay = fd; - } + //----------------------------------------------------------------------- + Real FrameTimeControllerValue::getTimeFactor(void) const { + return mTimeFactor; + } + //----------------------------------------------------------------------- + void FrameTimeControllerValue::setTimeFactor(Real tf) { + if(tf >= 0) + { + mTimeFactor = tf; + mFrameDelay = 0; + } + } + //----------------------------------------------------------------------- + Real FrameTimeControllerValue::getFrameDelay(void) const { + return mFrameDelay; + } + //----------------------------------------------------------------------- + void FrameTimeControllerValue::setFrameDelay(Real fd) { + mTimeFactor = 0; + mFrameDelay = fd; + } //----------------------------------------------------------------------- Real FrameTimeControllerValue::getElapsedTime(void) const { @@ -192,42 +192,42 @@ namespace Ogre } //----------------------------------------------------------------------- //----------------------------------------------------------------------- - FloatGpuParameterControllerValue::FloatGpuParameterControllerValue( - GpuProgramParametersSharedPtr params, size_t index) : - mParams(params), mParamIndex(index) - { - } - //----------------------------------------------------------------------- - Real FloatGpuParameterControllerValue::getValue(void) const - { - // do nothing, reading from a set of params not supported - return 0.0f; - } - //----------------------------------------------------------------------- - void FloatGpuParameterControllerValue::setValue(Real val) - { - Vector4 v4 = Vector4(0,0,0,0); - v4.x = val; - mParams->setConstant(mParamIndex, v4); - } - //----------------------------------------------------------------------- - // PassthroughControllerFunction - //----------------------------------------------------------------------- - PassthroughControllerFunction::PassthroughControllerFunction(bool delta) - : ControllerFunction(delta) - { - } - //----------------------------------------------------------------------- - Real PassthroughControllerFunction::calculate(Real source) - { - return getAdjustedInput(source); + FloatGpuParameterControllerValue::FloatGpuParameterControllerValue( + GpuProgramParametersSharedPtr params, size_t index) : + mParams(params), mParamIndex(index) + { + } + //----------------------------------------------------------------------- + Real FloatGpuParameterControllerValue::getValue(void) const + { + // do nothing, reading from a set of params not supported + return 0.0f; + } + //----------------------------------------------------------------------- + void FloatGpuParameterControllerValue::setValue(Real val) + { + Vector4 v4 = Vector4(0,0,0,0); + v4.x = val; + mParams->setConstant(mParamIndex, v4); + } + //----------------------------------------------------------------------- + // PassthroughControllerFunction + //----------------------------------------------------------------------- + PassthroughControllerFunction::PassthroughControllerFunction(bool delta) + : ControllerFunction(delta) + { + } + //----------------------------------------------------------------------- + Real PassthroughControllerFunction::calculate(Real source) + { + return getAdjustedInput(source); - } + } //----------------------------------------------------------------------- // AnimationControllerFunction //----------------------------------------------------------------------- AnimationControllerFunction::AnimationControllerFunction(Real sequenceTime, Real timeOffset) - : ControllerFunction(false) + : ControllerFunction(false) { mSeqTime = sequenceTime; mTime = timeOffset; @@ -244,16 +244,16 @@ namespace Ogre // Return parametric return mTime / mSeqTime; } - //----------------------------------------------------------------------- - void AnimationControllerFunction::setTime(Real timeVal) - { - mTime = timeVal; - } - //----------------------------------------------------------------------- - void AnimationControllerFunction::setSequenceTime(Real seqVal) - { - mSeqTime = seqVal; - } + //----------------------------------------------------------------------- + void AnimationControllerFunction::setTime(Real timeVal) + { + mTime = timeVal; + } + //----------------------------------------------------------------------- + void AnimationControllerFunction::setSequenceTime(Real seqVal) + { + mSeqTime = seqVal; + } //----------------------------------------------------------------------- // ScaleControllerFunction //----------------------------------------------------------------------- @@ -279,7 +279,7 @@ namespace Ogre mPhase = phase; mAmplitude = amplitude; mDeltaCount = phase; - mDutyCycle = dutyCycle; + mDutyCycle = dutyCycle; } //----------------------------------------------------------------------- Real WaveformControllerFunction::getAdjustedInput(Real input) @@ -334,12 +334,12 @@ namespace Ogre case WFT_INVERSE_SAWTOOTH: output = -((input * 2.0f) - 1.0f); break; - case WFT_PWM: - if( input <= mDutyCycle ) - output = 1.0f; - else - output = -1.0f; - break; + case WFT_PWM: + if( input <= mDutyCycle ) + output = 1.0f; + else + output = -1.0f; + break; } // Scale output into 0..1 range and then by base + amplitude diff --git a/OgreMain/src/OgrePrefabFactory.cpp b/OgreMain/src/OgrePrefabFactory.cpp index 0f8154d6980..92c8e079398 100644 --- a/OgreMain/src/OgrePrefabFactory.cpp +++ b/OgreMain/src/OgrePrefabFactory.cpp @@ -33,338 +33,338 @@ THE SOFTWARE. #include "OgreSubMesh.h" namespace Ogre { - //--------------------------------------------------------------------- - bool PrefabFactory::createPrefab(Mesh* mesh) - { - const String& resourceName = mesh->getName(); - - if(resourceName == "Prefab_Plane") - { - createPlane(mesh); - return true; - } - else if(resourceName == "Prefab_Cube") - { - createCube(mesh); - return true; - } - else if(resourceName == "Prefab_Sphere") - { - createSphere(mesh); - return true; - } - - return false; - } - //--------------------------------------------------------------------- - void PrefabFactory::createPlane(Mesh* mesh) - { - SubMesh* sub = mesh->createSubMesh(); - float vertices[32] = { - -100, -100, 0, // pos - 0,0,1, // normal - 0,1, // texcoord - 100, -100, 0, - 0,0,1, - 1,1, - 100, 100, 0, - 0,0,1, - 1,0, - -100, 100, 0 , - 0,0,1, - 0,0 - }; - mesh->sharedVertexData = OGRE_NEW VertexData(); - mesh->sharedVertexData->vertexCount = 4; - VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; - VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; - - size_t offset = 0; - decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); - offset += VertexElement::getTypeSize(VET_FLOAT3); - decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); - offset += VertexElement::getTypeSize(VET_FLOAT3); - decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); - offset += VertexElement::getTypeSize(VET_FLOAT2); - - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - bind->setBinding(0, vbuf); - - vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); - - sub->useSharedVertices = true; - HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). - createIndexBuffer( - HardwareIndexBuffer::IT_16BIT, - 6, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - unsigned short faces[6] = {0,1,2, - 0,2,3 }; - sub->indexData->indexBuffer = ibuf; - sub->indexData->indexCount = 6; - sub->indexData->indexStart =0; - ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); - - mesh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true); - mesh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100)); - } - //--------------------------------------------------------------------- - void PrefabFactory::createCube(Mesh* mesh) - { - SubMesh* sub = mesh->createSubMesh(); - - const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides - const int NUM_ENTRIES_PER_VERTEX = 8; - const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX; - const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides - - const float CUBE_SIZE = 100.0f; - const float CUBE_HALF_SIZE = CUBE_SIZE / 2.0f; - - // Create 4 vertices per side instead of 6 that are shared for the whole cube. - // The reason for this is with only 6 vertices the normals will look bad - // since each vertex can "point" in a different direction depending on the face it is included in. - float vertices[NUM_VERTEX_ENTRIES] = { - // front side - -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, // pos - 0,0,1, // normal - 0,1, // texcoord - CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, - 0,0,1, - 1,1, - CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, - 0,0,1, - 1,0, - -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE , - 0,0,1, - 0,0, - - // back side - CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - 0,0,-1, - 0,1, - -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - 0,0,-1, - 1,1, - -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - 0,0,-1, - 1,0, - CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - 0,0,-1, - 0,0, - - // left side - -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - -1,0,0, - 0,1, - -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, - -1,0,0, - 1,1, - -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, - -1,0,0, - 1,0, - -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - -1,0,0, - 0,0, - - // right side - CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, - 1,0,0, - 0,1, - CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - 1,0,0, - 1,1, - CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - 1,0,0, - 1,0, - CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, - 1,0,0, - 0,0, - - // up side - -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, - 0,1,0, - 0,1, - CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, - 0,1,0, - 1,1, - CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - 0,1,0, - 1,0, - -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - 0,1,0, - 0,0, - - // down side - -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - 0,-1,0, - 0,1, - CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - 0,-1,0, - 1,1, - CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, - 0,-1,0, - 1,0, - -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, - 0,-1,0, - 0,0 - }; - - mesh->sharedVertexData = OGRE_NEW VertexData(); - mesh->sharedVertexData->vertexCount = NUM_VERTICES; - VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; - VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; - - size_t offset = 0; - decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); - offset += VertexElement::getTypeSize(VET_FLOAT3); - decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); - offset += VertexElement::getTypeSize(VET_FLOAT3); - decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); - offset += VertexElement::getTypeSize(VET_FLOAT2); - - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - bind->setBinding(0, vbuf); - - vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); - - sub->useSharedVertices = true; - HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). - createIndexBuffer( - HardwareIndexBuffer::IT_16BIT, - NUM_INDICES, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - unsigned short faces[NUM_INDICES] = { - // front - 0,1,2, - 0,2,3, - - // back - 4,5,6, - 4,6,7, - - // left - 8,9,10, - 8,10,11, - - // right - 12,13,14, - 12,14,15, - - // up - 16,17,18, - 16,18,19, - - // down - 20,21,22, - 20,22,23 - }; - - sub->indexData->indexBuffer = ibuf; - sub->indexData->indexCount = NUM_INDICES; - sub->indexData->indexStart = 0; - ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); - - mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, - CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true); - - mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE); - } - //--------------------------------------------------------------------- - void PrefabFactory::createSphere(Mesh* mesh) - { - // sphere creation code taken from the DeferredShading sample, originally from the wiki - SubMesh *pSphereVertex = mesh->createSubMesh(); - - const int NUM_SEGMENTS = 16; - const int NUM_RINGS = 16; - const Real SPHERE_RADIUS = 50.0; - - mesh->sharedVertexData = OGRE_NEW VertexData(); - VertexData* vertexData = mesh->sharedVertexData; - - // define the vertex format - VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; - size_t currOffset = 0; - // positions - vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); - currOffset += VertexElement::getTypeSize(VET_FLOAT3); - // normals - vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); - currOffset += VertexElement::getTypeSize(VET_FLOAT3); - // two dimensional texture coordinates - vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); - - // allocate the vertex buffer - vertexData->vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS+1); - HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - VertexBufferBinding* binding = vertexData->vertexBufferBinding; - binding->setBinding(0, vBuf); - float* pVertex = static_cast(vBuf->lock(HardwareBuffer::HBL_DISCARD)); - - // allocate index buffer - pSphereVertex->indexData->indexCount = 6 * NUM_RINGS * (NUM_SEGMENTS + 1); - pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer; - unsigned short* pIndices = static_cast(iBuf->lock(HardwareBuffer::HBL_DISCARD)); - - float fDeltaRingAngle = (Math::PI / NUM_RINGS); - float fDeltaSegAngle = (2 * Math::PI / NUM_SEGMENTS); - unsigned short wVerticeIndex = 0 ; - - // Generate the group of rings for the sphere - for( int ring = 0; ring <= NUM_RINGS; ring++ ) { - float r0 = SPHERE_RADIUS * sinf (ring * fDeltaRingAngle); - float y0 = SPHERE_RADIUS * cosf (ring * fDeltaRingAngle); - - // Generate the group of segments for the current ring - for(int seg = 0; seg <= NUM_SEGMENTS; seg++) { - float x0 = r0 * sinf(seg * fDeltaSegAngle); - float z0 = r0 * cosf(seg * fDeltaSegAngle); - - // Add one vertex to the strip which makes up the sphere - *pVertex++ = x0; - *pVertex++ = y0; - *pVertex++ = z0; - - Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy(); - *pVertex++ = vNormal.x; - *pVertex++ = vNormal.y; - *pVertex++ = vNormal.z; - - *pVertex++ = (float) seg / (float) NUM_SEGMENTS; - *pVertex++ = (float) ring / (float) NUM_RINGS; - - if (ring != NUM_RINGS) { - // each vertex (except the last) has six indicies pointing to it - *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1; - *pIndices++ = wVerticeIndex; - *pIndices++ = wVerticeIndex + NUM_SEGMENTS; - *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1; - *pIndices++ = wVerticeIndex + 1; - *pIndices++ = wVerticeIndex; - wVerticeIndex ++; - } - }; // end for seg - } // end for ring - - // Unlock - vBuf->unlock(); - iBuf->unlock(); - // Generate face list - pSphereVertex->useSharedVertices = true; - - // the original code was missing this line: - mesh->_setBounds( AxisAlignedBox( Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS), - Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS) ), false ); - - mesh->_setBoundingSphereRadius(SPHERE_RADIUS); - } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + bool PrefabFactory::createPrefab(Mesh* mesh) + { + const String& resourceName = mesh->getName(); + + if(resourceName == "Prefab_Plane") + { + createPlane(mesh); + return true; + } + else if(resourceName == "Prefab_Cube") + { + createCube(mesh); + return true; + } + else if(resourceName == "Prefab_Sphere") + { + createSphere(mesh); + return true; + } + + return false; + } + //--------------------------------------------------------------------- + void PrefabFactory::createPlane(Mesh* mesh) + { + SubMesh* sub = mesh->createSubMesh(); + float vertices[32] = { + -100, -100, 0, // pos + 0,0,1, // normal + 0,1, // texcoord + 100, -100, 0, + 0,0,1, + 1,1, + 100, 100, 0, + 0,0,1, + 1,0, + -100, 100, 0 , + 0,0,1, + 0,0 + }; + mesh->sharedVertexData = OGRE_NEW VertexData(); + mesh->sharedVertexData->vertexCount = 4; + VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; + VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; + + size_t offset = 0; + decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); + offset += VertexElement::getTypeSize(VET_FLOAT3); + decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); + offset += VertexElement::getTypeSize(VET_FLOAT3); + decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); + offset += VertexElement::getTypeSize(VET_FLOAT2); + + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + offset, 4, HardwareBuffer::HBU_STATIC_WRITE_ONLY); + bind->setBinding(0, vbuf); + + vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); + + sub->useSharedVertices = true; + HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). + createIndexBuffer( + HardwareIndexBuffer::IT_16BIT, + 6, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + + unsigned short faces[6] = {0,1,2, + 0,2,3 }; + sub->indexData->indexBuffer = ibuf; + sub->indexData->indexCount = 6; + sub->indexData->indexStart =0; + ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); + + mesh->_setBounds(AxisAlignedBox(-100,-100,0,100,100,0), true); + mesh->_setBoundingSphereRadius(Math::Sqrt(100*100+100*100)); + } + //--------------------------------------------------------------------- + void PrefabFactory::createCube(Mesh* mesh) + { + SubMesh* sub = mesh->createSubMesh(); + + const int NUM_VERTICES = 4 * 6; // 4 vertices per side * 6 sides + const int NUM_ENTRIES_PER_VERTEX = 8; + const int NUM_VERTEX_ENTRIES = NUM_VERTICES * NUM_ENTRIES_PER_VERTEX; + const int NUM_INDICES = 3 * 2 * 6; // 3 indices per face * 2 faces per side * 6 sides + + const float CUBE_SIZE = 100.0f; + const float CUBE_HALF_SIZE = CUBE_SIZE / 2.0f; + + // Create 4 vertices per side instead of 6 that are shared for the whole cube. + // The reason for this is with only 6 vertices the normals will look bad + // since each vertex can "point" in a different direction depending on the face it is included in. + float vertices[NUM_VERTEX_ENTRIES] = { + // front side + -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, // pos + 0,0,1, // normal + 0,1, // texcoord + CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, + 0,0,1, + 1,1, + CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, + 0,0,1, + 1,0, + -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE , + 0,0,1, + 0,0, + + // back side + CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + 0,0,-1, + 0,1, + -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + 0,0,-1, + 1,1, + -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + 0,0,-1, + 1,0, + CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + 0,0,-1, + 0,0, + + // left side + -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + -1,0,0, + 0,1, + -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, + -1,0,0, + 1,1, + -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, + -1,0,0, + 1,0, + -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + -1,0,0, + 0,0, + + // right side + CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, + 1,0,0, + 0,1, + CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + 1,0,0, + 1,1, + CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + 1,0,0, + 1,0, + CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, + 1,0,0, + 0,0, + + // up side + -CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, + 0,1,0, + 0,1, + CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE, + 0,1,0, + 1,1, + CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + 0,1,0, + 1,0, + -CUBE_HALF_SIZE, CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + 0,1,0, + 0,0, + + // down side + -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + 0,-1,0, + 0,1, + CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + 0,-1,0, + 1,1, + CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, + 0,-1,0, + 1,0, + -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, CUBE_HALF_SIZE, + 0,-1,0, + 0,0 + }; + + mesh->sharedVertexData = OGRE_NEW VertexData(); + mesh->sharedVertexData->vertexCount = NUM_VERTICES; + VertexDeclaration* decl = mesh->sharedVertexData->vertexDeclaration; + VertexBufferBinding* bind = mesh->sharedVertexData->vertexBufferBinding; + + size_t offset = 0; + decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); + offset += VertexElement::getTypeSize(VET_FLOAT3); + decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); + offset += VertexElement::getTypeSize(VET_FLOAT3); + decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); + offset += VertexElement::getTypeSize(VET_FLOAT2); + + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + offset, NUM_VERTICES, HardwareBuffer::HBU_STATIC_WRITE_ONLY); + bind->setBinding(0, vbuf); + + vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); + + sub->useSharedVertices = true; + HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). + createIndexBuffer( + HardwareIndexBuffer::IT_16BIT, + NUM_INDICES, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + + unsigned short faces[NUM_INDICES] = { + // front + 0,1,2, + 0,2,3, + + // back + 4,5,6, + 4,6,7, + + // left + 8,9,10, + 8,10,11, + + // right + 12,13,14, + 12,14,15, + + // up + 16,17,18, + 16,18,19, + + // down + 20,21,22, + 20,22,23 + }; + + sub->indexData->indexBuffer = ibuf; + sub->indexData->indexCount = NUM_INDICES; + sub->indexData->indexStart = 0; + ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); + + mesh->_setBounds(AxisAlignedBox(-CUBE_HALF_SIZE, -CUBE_HALF_SIZE, -CUBE_HALF_SIZE, + CUBE_HALF_SIZE, CUBE_HALF_SIZE, CUBE_HALF_SIZE), true); + + mesh->_setBoundingSphereRadius(CUBE_HALF_SIZE); + } + //--------------------------------------------------------------------- + void PrefabFactory::createSphere(Mesh* mesh) + { + // sphere creation code taken from the DeferredShading sample, originally from the wiki + SubMesh *pSphereVertex = mesh->createSubMesh(); + + const int NUM_SEGMENTS = 16; + const int NUM_RINGS = 16; + const Real SPHERE_RADIUS = 50.0; + + mesh->sharedVertexData = OGRE_NEW VertexData(); + VertexData* vertexData = mesh->sharedVertexData; + + // define the vertex format + VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; + size_t currOffset = 0; + // positions + vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); + currOffset += VertexElement::getTypeSize(VET_FLOAT3); + // normals + vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); + currOffset += VertexElement::getTypeSize(VET_FLOAT3); + // two dimensional texture coordinates + vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); + + // allocate the vertex buffer + vertexData->vertexCount = (NUM_RINGS + 1) * (NUM_SEGMENTS+1); + HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + VertexBufferBinding* binding = vertexData->vertexBufferBinding; + binding->setBinding(0, vBuf); + float* pVertex = static_cast(vBuf->lock(HardwareBuffer::HBL_DISCARD)); + + // allocate index buffer + pSphereVertex->indexData->indexCount = 6 * NUM_RINGS * (NUM_SEGMENTS + 1); + pSphereVertex->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, pSphereVertex->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + HardwareIndexBufferSharedPtr iBuf = pSphereVertex->indexData->indexBuffer; + unsigned short* pIndices = static_cast(iBuf->lock(HardwareBuffer::HBL_DISCARD)); + + float fDeltaRingAngle = (Math::PI / NUM_RINGS); + float fDeltaSegAngle = (2 * Math::PI / NUM_SEGMENTS); + unsigned short wVerticeIndex = 0 ; + + // Generate the group of rings for the sphere + for( int ring = 0; ring <= NUM_RINGS; ring++ ) { + float r0 = SPHERE_RADIUS * sinf (ring * fDeltaRingAngle); + float y0 = SPHERE_RADIUS * cosf (ring * fDeltaRingAngle); + + // Generate the group of segments for the current ring + for(int seg = 0; seg <= NUM_SEGMENTS; seg++) { + float x0 = r0 * sinf(seg * fDeltaSegAngle); + float z0 = r0 * cosf(seg * fDeltaSegAngle); + + // Add one vertex to the strip which makes up the sphere + *pVertex++ = x0; + *pVertex++ = y0; + *pVertex++ = z0; + + Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy(); + *pVertex++ = vNormal.x; + *pVertex++ = vNormal.y; + *pVertex++ = vNormal.z; + + *pVertex++ = (float) seg / (float) NUM_SEGMENTS; + *pVertex++ = (float) ring / (float) NUM_RINGS; + + if (ring != NUM_RINGS) { + // each vertex (except the last) has six indicies pointing to it + *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1; + *pIndices++ = wVerticeIndex; + *pIndices++ = wVerticeIndex + NUM_SEGMENTS; + *pIndices++ = wVerticeIndex + NUM_SEGMENTS + 1; + *pIndices++ = wVerticeIndex + 1; + *pIndices++ = wVerticeIndex; + wVerticeIndex ++; + } + }; // end for seg + } // end for ring + + // Unlock + vBuf->unlock(); + iBuf->unlock(); + // Generate face list + pSphereVertex->useSharedVertices = true; + + // the original code was missing this line: + mesh->_setBounds( AxisAlignedBox( Vector3(-SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS), + Vector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS) ), false ); + + mesh->_setBoundingSphereRadius(SPHERE_RADIUS); + } + //--------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreProfiler.cpp b/OgreMain/src/OgreProfiler.cpp index 46a1a49801b..ca36cfb2b4d 100644 --- a/OgreMain/src/OgreProfiler.cpp +++ b/OgreMain/src/OgreProfiler.cpp @@ -60,9 +60,9 @@ namespace Ogre { } //----------------------------------------------------------------------- Profile::Profile(const String& profileName, uint32 groupID) - : mName(profileName) - , mGroupID(groupID) - { + : mName(profileName) + , mGroupID(groupID) + { Ogre::Profiler::getSingleton().beginProfile(profileName, groupID); } //----------------------------------------------------------------------- @@ -81,54 +81,54 @@ namespace Ogre { , mLast(NULL) , mRoot() , mInitialized(false) - , mUpdateDisplayFrequency(10) - , mCurrentFrame(0) - , mTimer(0) - , mTotalFrameTime(0) - , mEnabled(false) - , mNewEnableState(false) - , mProfileMask(0xFFFFFFFF) - , mMaxTotalFrameTime(0) - , mAverageFrameTime(0) - , mResetExtents(false) - { - mRoot.hierarchicalLvl = 0 - 1; - } - //----------------------------------------------------------------------- - ProfileInstance::ProfileInstance(void) - : parent(NULL) + , mUpdateDisplayFrequency(10) + , mCurrentFrame(0) + , mTimer(0) + , mTotalFrameTime(0) + , mEnabled(false) + , mNewEnableState(false) + , mProfileMask(0xFFFFFFFF) + , mMaxTotalFrameTime(0) + , mAverageFrameTime(0) + , mResetExtents(false) + { + mRoot.hierarchicalLvl = 0 - 1; + } + //----------------------------------------------------------------------- + ProfileInstance::ProfileInstance(void) + : parent(NULL) , frameNumber(0) - , accum(0) - , hierarchicalLvl(0) - { - history.numCallsThisFrame = 0; - history.totalTimePercent = 0; - history.totalTimeMillisecs = 0; - history.totalCalls = 0; - history.maxTimePercent = 0; - history.maxTimeMillisecs = 0; - history.minTimePercent = 1; - history.minTimeMillisecs = 100000; - history.currentTimePercent = 0; - history.currentTimeMillisecs = 0; - - frame.frameTime = 0; - frame.calls = 0; - } - ProfileInstance::~ProfileInstance(void) - { - for(ProfileChildren::iterator it = children.begin(); it != children.end(); ++it) - { - ProfileInstance* instance = it->second; - OGRE_DELETE instance; - } - children.clear(); - } + , accum(0) + , hierarchicalLvl(0) + { + history.numCallsThisFrame = 0; + history.totalTimePercent = 0; + history.totalTimeMillisecs = 0; + history.totalCalls = 0; + history.maxTimePercent = 0; + history.maxTimeMillisecs = 0; + history.minTimePercent = 1; + history.minTimeMillisecs = 100000; + history.currentTimePercent = 0; + history.currentTimeMillisecs = 0; + + frame.frameTime = 0; + frame.calls = 0; + } + ProfileInstance::~ProfileInstance(void) + { + for(ProfileChildren::iterator it = children.begin(); it != children.end(); ++it) + { + ProfileInstance* instance = it->second; + OGRE_DELETE instance; + } + children.clear(); + } //----------------------------------------------------------------------- Profiler::~Profiler() { - if (!mRoot.children.empty()) - { + if (!mRoot.children.empty()) + { // log the results of our profiling before we quit logResults(); } @@ -149,9 +149,9 @@ namespace Ogre { } //----------------------------------------------------------------------- void Profiler::setEnabled(bool enabled) - { + { if (!mInitialized && enabled) - { + { for( TProfileSessionListener::iterator i = mListeners.begin(); i != mListeners.end(); ++i ) (*i)->initializeSession(); @@ -159,11 +159,11 @@ namespace Ogre { } else if (mInitialized) { - for( TProfileSessionListener::iterator i = mListeners.begin(); i != mListeners.end(); ++i ) + for( TProfileSessionListener::iterator i = mListeners.begin(); i != mListeners.end(); ++i ) (*i)->finializeSession(); mInitialized = false; - mEnabled = false; + mEnabled = false; } // We store this enable/disable request until the frame ends // (don't want to screw up any open profiles!) @@ -174,422 +174,422 @@ namespace Ogre { { return mEnabled; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void Profiler::changeEnableState() - { - for( TProfileSessionListener::iterator i = mListeners.begin(); i != mListeners.end(); ++i ) - (*i)->changeEnableState(mNewEnableState); + { + for( TProfileSessionListener::iterator i = mListeners.begin(); i != mListeners.end(); ++i ) + (*i)->changeEnableState(mNewEnableState); mEnabled = mNewEnableState; } //----------------------------------------------------------------------- void Profiler::disableProfile(const String& profileName) - { + { // even if we are in the middle of this profile, endProfile() will still end it. mDisabledProfiles.insert(profileName); } //----------------------------------------------------------------------- void Profiler::enableProfile(const String& profileName) - { - mDisabledProfiles.erase(profileName); + { + mDisabledProfiles.erase(profileName); } //----------------------------------------------------------------------- void Profiler::beginProfile(const String& profileName, uint32 groupID) - { - // regardless of whether or not we are enabled, we need the application's root profile (ie the first profile started each frame) - // we need this so bogus profiles don't show up when users enable profiling mid frame - // so we check + { + // regardless of whether or not we are enabled, we need the application's root profile (ie the first profile started each frame) + // we need this so bogus profiles don't show up when users enable profiling mid frame + // so we check - // if the profiler is enabled - if (!mEnabled) - return; + // if the profiler is enabled + if (!mEnabled) + return; - // mask groups - if ((groupID & mProfileMask) == 0) - return; + // mask groups + if ((groupID & mProfileMask) == 0) + return; - // we only process this profile if isn't disabled - if (mDisabledProfiles.find(profileName) != mDisabledProfiles.end()) - return; + // we only process this profile if isn't disabled + if (mDisabledProfiles.find(profileName) != mDisabledProfiles.end()) + return; - // empty string is reserved for the root - // not really fatal anymore, however one shouldn't name one's profile as an empty string anyway. - assert ((profileName != "") && ("Profile name can't be an empty string")); + // empty string is reserved for the root + // not really fatal anymore, however one shouldn't name one's profile as an empty string anyway. + assert ((profileName != "") && ("Profile name can't be an empty string")); - // this would be an internal error. - assert (mCurrent); + // this would be an internal error. + assert (mCurrent); - // need a timer to profile! - assert (mTimer && "Timer not set!"); + // need a timer to profile! + assert (mTimer && "Timer not set!"); - ProfileInstance*& instance = mCurrent->children[profileName]; - if(instance) - { // found existing child. + ProfileInstance*& instance = mCurrent->children[profileName]; + if(instance) + { // found existing child. - // Sanity check. - assert(instance->name == profileName); + // Sanity check. + assert(instance->name == profileName); - if(instance->frameNumber != mCurrentFrame) - { // new frame, reset stats - instance->frame.calls = 0; - instance->frame.frameTime = 0; - instance->frameNumber = mCurrentFrame; - } - } - else - { // new child! - instance = OGRE_NEW ProfileInstance(); - instance->name = profileName; - instance->parent = mCurrent; - instance->hierarchicalLvl = mCurrent->hierarchicalLvl + 1; - } + if(instance->frameNumber != mCurrentFrame) + { // new frame, reset stats + instance->frame.calls = 0; + instance->frame.frameTime = 0; + instance->frameNumber = mCurrentFrame; + } + } + else + { // new child! + instance = OGRE_NEW ProfileInstance(); + instance->name = profileName; + instance->parent = mCurrent; + instance->hierarchicalLvl = mCurrent->hierarchicalLvl + 1; + } - instance->frameNumber = mCurrentFrame; + instance->frameNumber = mCurrentFrame; - mCurrent = instance; + mCurrent = instance; - // we do this at the very end of the function to get the most - // accurate timing results - mCurrent->currTime = mTimer->getMicroseconds(); + // we do this at the very end of the function to get the most + // accurate timing results + mCurrent->currTime = mTimer->getMicroseconds(); } //----------------------------------------------------------------------- void Profiler::endProfile(const String& profileName, uint32 groupID) - { - if(!mEnabled) - { - // if the profiler received a request to be enabled or disabled - if(mNewEnableState != mEnabled) - { // note mNewEnableState == true to reach this. - changeEnableState(); - - // NOTE we will be in an 'error' state until the next begin. ie endProfile will likely get invoked using a profileName that was never started. - // even then, we can't be sure that the next beginProfile will be the true start of a new frame - } - - return; - } - else - { - if(mNewEnableState != mEnabled) - { // note mNewEnableState == false to reach this. - changeEnableState(); - - // unwind the hierarchy, should be easy enough - mCurrent = &mRoot; - mLast = NULL; - } - - if(&mRoot == mCurrent && mLast) - { // profiler was enabled this frame, but the first subsequent beginProfile was NOT the beinging of a new frame as we had hoped. - // we have a bogus ProfileInstance in our hierarchy, we will need to remove it, then update the overlays so as not to confuse ze user - - // we could use mRoot.children.find() instead of this, except we'd be compairing strings instead of a pointer. - // the string way could be faster, but i don't believe it would. - ProfileChildren::iterator it = mRoot.children.begin(), endit = mRoot.children.end(); - for(;it != endit; ++it) - { - if(mLast == it->second) - { - mRoot.children.erase(it); - break; - } - } - - // with mLast == NULL we won't reach this code, in case this isn't the end of the top level profile - ProfileInstance* last = mLast; - mLast = NULL; - OGRE_DELETE last; - - processFrameStats(); - displayResults(); - } - } - - if(&mRoot == mCurrent) - return; - - // mask groups - if ((groupID & mProfileMask) == 0) - return; - - // need a timer to profile! - assert (mTimer && "Timer not set!"); - - // get the end time of this profile - // we do this as close the beginning of this function as possible - // to get more accurate timing results - const ulong endTime = mTimer->getMicroseconds(); - - // empty string is reserved for designating an empty parent - assert ((profileName != "") && ("Profile name can't be an empty string")); - - // we only process this profile if isn't disabled - // we check the current instance name against the provided profileName as a guard against disabling a profile name /after/ said profile began - if(mCurrent->name != profileName && mDisabledProfiles.find(profileName) != mDisabledProfiles.end()) - return; - - // calculate the elapsed time of this profile - const ulong timeElapsed = endTime - mCurrent->currTime; - - // update parent's accumulator if it isn't the root - if (&mRoot != mCurrent->parent) - { - // add this profile's time to the parent's accumlator - mCurrent->parent->accum += timeElapsed; - } - - mCurrent->frame.frameTime += timeElapsed; - ++mCurrent->frame.calls; - - mLast = mCurrent; - mCurrent = mCurrent->parent; - - if (&mRoot == mCurrent) - { - // the stack is empty and all the profiles have been completed - // we have reached the end of the frame so process the frame statistics - - // we know that the time elapsed of the main loop is the total time the frame took - mTotalFrameTime = timeElapsed; - - if(timeElapsed > mMaxTotalFrameTime) - mMaxTotalFrameTime = timeElapsed; - - // we got all the information we need, so process the profiles - // for this frame - processFrameStats(); - - // we display everything to the screen - displayResults(); - } - } - //----------------------------------------------------------------------- - void Profiler::beginGPUEvent(const String& event) + { + if(!mEnabled) + { + // if the profiler received a request to be enabled or disabled + if(mNewEnableState != mEnabled) + { // note mNewEnableState == true to reach this. + changeEnableState(); + + // NOTE we will be in an 'error' state until the next begin. ie endProfile will likely get invoked using a profileName that was never started. + // even then, we can't be sure that the next beginProfile will be the true start of a new frame + } + + return; + } + else + { + if(mNewEnableState != mEnabled) + { // note mNewEnableState == false to reach this. + changeEnableState(); + + // unwind the hierarchy, should be easy enough + mCurrent = &mRoot; + mLast = NULL; + } + + if(&mRoot == mCurrent && mLast) + { // profiler was enabled this frame, but the first subsequent beginProfile was NOT the beinging of a new frame as we had hoped. + // we have a bogus ProfileInstance in our hierarchy, we will need to remove it, then update the overlays so as not to confuse ze user + + // we could use mRoot.children.find() instead of this, except we'd be compairing strings instead of a pointer. + // the string way could be faster, but i don't believe it would. + ProfileChildren::iterator it = mRoot.children.begin(), endit = mRoot.children.end(); + for(;it != endit; ++it) + { + if(mLast == it->second) + { + mRoot.children.erase(it); + break; + } + } + + // with mLast == NULL we won't reach this code, in case this isn't the end of the top level profile + ProfileInstance* last = mLast; + mLast = NULL; + OGRE_DELETE last; + + processFrameStats(); + displayResults(); + } + } + + if(&mRoot == mCurrent) + return; + + // mask groups + if ((groupID & mProfileMask) == 0) + return; + + // need a timer to profile! + assert (mTimer && "Timer not set!"); + + // get the end time of this profile + // we do this as close the beginning of this function as possible + // to get more accurate timing results + const ulong endTime = mTimer->getMicroseconds(); + + // empty string is reserved for designating an empty parent + assert ((profileName != "") && ("Profile name can't be an empty string")); + + // we only process this profile if isn't disabled + // we check the current instance name against the provided profileName as a guard against disabling a profile name /after/ said profile began + if(mCurrent->name != profileName && mDisabledProfiles.find(profileName) != mDisabledProfiles.end()) + return; + + // calculate the elapsed time of this profile + const ulong timeElapsed = endTime - mCurrent->currTime; + + // update parent's accumulator if it isn't the root + if (&mRoot != mCurrent->parent) + { + // add this profile's time to the parent's accumlator + mCurrent->parent->accum += timeElapsed; + } + + mCurrent->frame.frameTime += timeElapsed; + ++mCurrent->frame.calls; + + mLast = mCurrent; + mCurrent = mCurrent->parent; + + if (&mRoot == mCurrent) + { + // the stack is empty and all the profiles have been completed + // we have reached the end of the frame so process the frame statistics + + // we know that the time elapsed of the main loop is the total time the frame took + mTotalFrameTime = timeElapsed; + + if(timeElapsed > mMaxTotalFrameTime) + mMaxTotalFrameTime = timeElapsed; + + // we got all the information we need, so process the profiles + // for this frame + processFrameStats(); + + // we display everything to the screen + displayResults(); + } + } + //----------------------------------------------------------------------- + void Profiler::beginGPUEvent(const String& event) { Root::getSingleton().getRenderSystem()->beginProfileEvent(event); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void Profiler::endGPUEvent(const String& event) { Root::getSingleton().getRenderSystem()->endProfileEvent(); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void Profiler::markGPUEvent(const String& event) { Root::getSingleton().getRenderSystem()->markProfileEvent(event); } - //----------------------------------------------------------------------- - void Profiler::processFrameStats(ProfileInstance* instance, Real& maxFrameTime) - { - // calculate what percentage of frame time this profile took - const Real framePercentage = (Real) instance->frame.frameTime / (Real) mTotalFrameTime; - - const Real frameTimeMillisecs = (Real) instance->frame.frameTime / 1000.0f; - - // update the profile stats - instance->history.currentTimePercent = framePercentage; - instance->history.currentTimeMillisecs = frameTimeMillisecs; - if(mResetExtents) - { - instance->history.totalTimePercent = framePercentage; - instance->history.totalTimeMillisecs = frameTimeMillisecs; - instance->history.totalCalls = 1; - } - else - { - instance->history.totalTimePercent += framePercentage; - instance->history.totalTimeMillisecs += frameTimeMillisecs; - instance->history.totalCalls++; - } - instance->history.numCallsThisFrame = instance->frame.calls; - - // if we find a new minimum for this profile, update it - if (frameTimeMillisecs < instance->history.minTimeMillisecs || mResetExtents) - { - instance->history.minTimePercent = framePercentage; - instance->history.minTimeMillisecs = frameTimeMillisecs; - } - - // if we find a new maximum for this profile, update it - if (frameTimeMillisecs > instance->history.maxTimeMillisecs || mResetExtents) - { - instance->history.maxTimePercent = framePercentage; - instance->history.maxTimeMillisecs = frameTimeMillisecs; - } - - if(instance->frame.frameTime > maxFrameTime) - maxFrameTime = (Real)instance->frame.frameTime; - - ProfileChildren::iterator it = instance->children.begin(), endit = instance->children.end(); - for(;it != endit; ++it) - { - ProfileInstance* child = it->second; - - // we set the number of times each profile was called per frame to 0 - // because not all profiles are called every frame - child->history.numCallsThisFrame = 0; - - if(child->frame.calls > 0) - { - processFrameStats(child, maxFrameTime); - } - } - } - //----------------------------------------------------------------------- - void Profiler::processFrameStats(void) - { - Real maxFrameTime = 0; - - ProfileChildren::iterator it = mRoot.children.begin(), endit = mRoot.children.end(); - for(;it != endit; ++it) - { - ProfileInstance* child = it->second; - - // we set the number of times each profile was called per frame to 0 - // because not all profiles are called every frame - child->history.numCallsThisFrame = 0; - - if(child->frame.calls > 0) - { - processFrameStats(child, maxFrameTime); - } - } - - // Calculate whether the extents are now so out of date they need regenerating - if (mCurrentFrame == 0) - mAverageFrameTime = maxFrameTime; - else - mAverageFrameTime = (mAverageFrameTime + maxFrameTime) * 0.5f; - - if ((Real)mMaxTotalFrameTime > mAverageFrameTime * 4) - { - mResetExtents = true; - mMaxTotalFrameTime = (ulong)mAverageFrameTime; - } - else - mResetExtents = false; - } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + void Profiler::processFrameStats(ProfileInstance* instance, Real& maxFrameTime) + { + // calculate what percentage of frame time this profile took + const Real framePercentage = (Real) instance->frame.frameTime / (Real) mTotalFrameTime; + + const Real frameTimeMillisecs = (Real) instance->frame.frameTime / 1000.0f; + + // update the profile stats + instance->history.currentTimePercent = framePercentage; + instance->history.currentTimeMillisecs = frameTimeMillisecs; + if(mResetExtents) + { + instance->history.totalTimePercent = framePercentage; + instance->history.totalTimeMillisecs = frameTimeMillisecs; + instance->history.totalCalls = 1; + } + else + { + instance->history.totalTimePercent += framePercentage; + instance->history.totalTimeMillisecs += frameTimeMillisecs; + instance->history.totalCalls++; + } + instance->history.numCallsThisFrame = instance->frame.calls; + + // if we find a new minimum for this profile, update it + if (frameTimeMillisecs < instance->history.minTimeMillisecs || mResetExtents) + { + instance->history.minTimePercent = framePercentage; + instance->history.minTimeMillisecs = frameTimeMillisecs; + } + + // if we find a new maximum for this profile, update it + if (frameTimeMillisecs > instance->history.maxTimeMillisecs || mResetExtents) + { + instance->history.maxTimePercent = framePercentage; + instance->history.maxTimeMillisecs = frameTimeMillisecs; + } + + if(instance->frame.frameTime > maxFrameTime) + maxFrameTime = (Real)instance->frame.frameTime; + + ProfileChildren::iterator it = instance->children.begin(), endit = instance->children.end(); + for(;it != endit; ++it) + { + ProfileInstance* child = it->second; + + // we set the number of times each profile was called per frame to 0 + // because not all profiles are called every frame + child->history.numCallsThisFrame = 0; + + if(child->frame.calls > 0) + { + processFrameStats(child, maxFrameTime); + } + } + } + //----------------------------------------------------------------------- + void Profiler::processFrameStats(void) + { + Real maxFrameTime = 0; + + ProfileChildren::iterator it = mRoot.children.begin(), endit = mRoot.children.end(); + for(;it != endit; ++it) + { + ProfileInstance* child = it->second; + + // we set the number of times each profile was called per frame to 0 + // because not all profiles are called every frame + child->history.numCallsThisFrame = 0; + + if(child->frame.calls > 0) + { + processFrameStats(child, maxFrameTime); + } + } + + // Calculate whether the extents are now so out of date they need regenerating + if (mCurrentFrame == 0) + mAverageFrameTime = maxFrameTime; + else + mAverageFrameTime = (mAverageFrameTime + maxFrameTime) * 0.5f; + + if ((Real)mMaxTotalFrameTime > mAverageFrameTime * 4) + { + mResetExtents = true; + mMaxTotalFrameTime = (ulong)mAverageFrameTime; + } + else + mResetExtents = false; + } + //----------------------------------------------------------------------- void Profiler::displayResults() - { - // if its time to update the display - if (!(mCurrentFrame % mUpdateDisplayFrequency)) - { - // ensure the root won't be culled - mRoot.frame.calls = 1; + { + // if its time to update the display + if (!(mCurrentFrame % mUpdateDisplayFrequency)) + { + // ensure the root won't be culled + mRoot.frame.calls = 1; - for( TProfileSessionListener::iterator i = mListeners.begin(); i != mListeners.end(); ++i ) - (*i)->displayResults(mRoot, mMaxTotalFrameTime); - } - ++mCurrentFrame; + for( TProfileSessionListener::iterator i = mListeners.begin(); i != mListeners.end(); ++i ) + (*i)->displayResults(mRoot, mMaxTotalFrameTime); + } + ++mCurrentFrame; } //----------------------------------------------------------------------- bool Profiler::watchForMax(const String& profileName) - { - assert ((profileName != "") && ("Profile name can't be an empty string")); + { + assert ((profileName != "") && ("Profile name can't be an empty string")); - return mRoot.watchForMax(profileName); + return mRoot.watchForMax(profileName); } - //----------------------------------------------------------------------- - bool ProfileInstance::watchForMax(const String& profileName) - { + //----------------------------------------------------------------------- + bool ProfileInstance::watchForMax(const String& profileName) + { ProfileChildren::iterator it = children.begin(), endit = children.end(); - for(;it != endit; ++it) - { - ProfileInstance* child = it->second; - if( (child->name == profileName && child->watchForMax()) || child->watchForMax(profileName)) - return true; - } - return false; + for(;it != endit; ++it) + { + ProfileInstance* child = it->second; + if( (child->name == profileName && child->watchForMax()) || child->watchForMax(profileName)) + return true; + } + return false; } //----------------------------------------------------------------------- bool Profiler::watchForMin(const String& profileName) - { - assert ((profileName != "") && ("Profile name can't be an empty string")); - return mRoot.watchForMin(profileName); + { + assert ((profileName != "") && ("Profile name can't be an empty string")); + return mRoot.watchForMin(profileName); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- bool ProfileInstance::watchForMin(const String& profileName) - { - ProfileChildren::iterator it = children.begin(), endit = children.end(); - for(;it != endit; ++it) - { - ProfileInstance* child = it->second; - if( (child->name == profileName && child->watchForMin()) || child->watchForMin(profileName)) - return true; - } - return false; + { + ProfileChildren::iterator it = children.begin(), endit = children.end(); + for(;it != endit; ++it) + { + ProfileInstance* child = it->second; + if( (child->name == profileName && child->watchForMin()) || child->watchForMin(profileName)) + return true; + } + return false; } //----------------------------------------------------------------------- bool Profiler::watchForLimit(const String& profileName, Real limit, bool greaterThan) - { + { assert ((profileName != "") && ("Profile name can't be an empty string")); - return mRoot.watchForLimit(profileName, limit, greaterThan); + return mRoot.watchForLimit(profileName, limit, greaterThan); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- bool ProfileInstance::watchForLimit(const String& profileName, Real limit, bool greaterThan) - { + { ProfileChildren::iterator it = children.begin(), endit = children.end(); - for(;it != endit; ++it) - { - ProfileInstance* child = it->second; - if( (child->name == profileName && child->watchForLimit(limit, greaterThan)) || child->watchForLimit(profileName, limit, greaterThan)) - return true; - } - return false; + for(;it != endit; ++it) + { + ProfileInstance* child = it->second; + if( (child->name == profileName && child->watchForLimit(limit, greaterThan)) || child->watchForLimit(profileName, limit, greaterThan)) + return true; + } + return false; } //----------------------------------------------------------------------- void Profiler::logResults() - { + { LogManager::getSingleton().logMessage("----------------------Profiler Results----------------------"); - for(ProfileChildren::iterator it = mRoot.children.begin(); it != mRoot.children.end(); ++it) - { - it->second->logResults(); - } + for(ProfileChildren::iterator it = mRoot.children.begin(); it != mRoot.children.end(); ++it) + { + it->second->logResults(); + } LogManager::getSingleton().logMessage("------------------------------------------------------------"); } - //----------------------------------------------------------------------- - void ProfileInstance::logResults() - { - // create an indent that represents the hierarchical order of the profile - String indent = ""; - for (uint i = 0; i < hierarchicalLvl; ++i) - { - indent = indent + "\t"; - } - - LogManager::getSingleton().logMessage(indent + "Name " + name + - " | Min " + StringConverter::toString(history.minTimePercent) + - " | Max " + StringConverter::toString(history.maxTimePercent) + - " | Avg "+ StringConverter::toString(history.totalTimePercent / history.totalCalls)); - - for(ProfileChildren::iterator it = children.begin(); it != children.end(); ++it) - { - it->second->logResults(); - } - } + //----------------------------------------------------------------------- + void ProfileInstance::logResults() + { + // create an indent that represents the hierarchical order of the profile + String indent = ""; + for (uint i = 0; i < hierarchicalLvl; ++i) + { + indent = indent + "\t"; + } + + LogManager::getSingleton().logMessage(indent + "Name " + name + + " | Min " + StringConverter::toString(history.minTimePercent) + + " | Max " + StringConverter::toString(history.maxTimePercent) + + " | Avg "+ StringConverter::toString(history.totalTimePercent / history.totalCalls)); + + for(ProfileChildren::iterator it = children.begin(); it != children.end(); ++it) + { + it->second->logResults(); + } + } //----------------------------------------------------------------------- void Profiler::reset() - { + { mRoot.reset(); mMaxTotalFrameTime = 0; } - //----------------------------------------------------------------------- - void ProfileInstance::reset(void) - { - history.currentTimePercent = history.maxTimePercent = history.totalTimePercent = 0; - history.currentTimeMillisecs = history.maxTimeMillisecs = history.totalTimeMillisecs = 0; - history.numCallsThisFrame = history.totalCalls = 0; - - history.minTimePercent = 1; - history.minTimeMillisecs = 100000; - for(ProfileChildren::iterator it = children.begin(); it != children.end(); ++it) - { - it->second->reset(); - } - } + //----------------------------------------------------------------------- + void ProfileInstance::reset(void) + { + history.currentTimePercent = history.maxTimePercent = history.totalTimePercent = 0; + history.currentTimeMillisecs = history.maxTimeMillisecs = history.totalTimeMillisecs = 0; + history.numCallsThisFrame = history.totalCalls = 0; + + history.minTimePercent = 1; + history.minTimeMillisecs = 100000; + for(ProfileChildren::iterator it = children.begin(); it != children.end(); ++it) + { + it->second->reset(); + } + } //----------------------------------------------------------------------- void Profiler::setUpdateDisplayFrequency(uint freq) { @@ -601,14 +601,14 @@ namespace Ogre { return mUpdateDisplayFrequency; } //----------------------------------------------------------------------- - void Profiler::addListener(ProfileSessionListener* listener) - { - mListeners.push_back(listener); - } + void Profiler::addListener(ProfileSessionListener* listener) + { + mListeners.push_back(listener); + } //----------------------------------------------------------------------- - void Profiler::removeListener(ProfileSessionListener* listener) - { + void Profiler::removeListener(ProfileSessionListener* listener) + { mListeners.erase(std::find(mListeners.begin(), mListeners.end(), listener)); - } + } //----------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreQuaternion.cpp b/OgreMain/src/OgreQuaternion.cpp index ab506013a4c..6e0dd267e7f 100644 --- a/OgreMain/src/OgreQuaternion.cpp +++ b/OgreMain/src/OgreQuaternion.cpp @@ -396,28 +396,28 @@ namespace Ogre { //----------------------------------------------------------------------- Vector3 Quaternion::operator* (const Vector3& v) const { - // nVidia SDK implementation - Vector3 uv, uuv; - Vector3 qvec(x, y, z); - uv = qvec.crossProduct(v); - uuv = qvec.crossProduct(uv); - uv *= (2.0f * w); - uuv *= 2.0f; + // nVidia SDK implementation + Vector3 uv, uuv; + Vector3 qvec(x, y, z); + uv = qvec.crossProduct(v); + uuv = qvec.crossProduct(uv); + uv *= (2.0f * w); + uuv *= 2.0f; - return v + uv + uuv; + return v + uv + uuv; } //----------------------------------------------------------------------- - bool Quaternion::equals(const Quaternion& rhs, const Radian& tolerance) const - { + bool Quaternion::equals(const Quaternion& rhs, const Radian& tolerance) const + { Real fCos = Dot(rhs); Radian angle = Math::ACos(fCos); - return (Math::Abs(angle.valueRadians()) <= tolerance.valueRadians()) + return (Math::Abs(angle.valueRadians()) <= tolerance.valueRadians()) || Math::RealEqual(angle.valueRadians(), Math::PI, tolerance.valueRadians()); - } + } //----------------------------------------------------------------------- Quaternion Quaternion::Slerp (Real fT, const Quaternion& rkP, const Quaternion& rkQ, bool shortestPath) @@ -513,94 +513,94 @@ namespace Ogre { return len; } //----------------------------------------------------------------------- - Radian Quaternion::getRoll(bool reprojectAxis) const - { - if (reprojectAxis) - { - // roll = atan2(localx.y, localx.x) - // pick parts of xAxis() implementation that we need -// Real fTx = 2.0*x; - Real fTy = 2.0f*y; - Real fTz = 2.0f*z; - Real fTwz = fTz*w; - Real fTxy = fTy*x; - Real fTyy = fTy*y; - Real fTzz = fTz*z; - - // Vector3(1.0-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy); - - return Radian(Math::ATan2(fTxy+fTwz, 1.0f-(fTyy+fTzz))); - - } - else - { - return Radian(Math::ATan2(2*(x*y + w*z), w*w + x*x - y*y - z*z)); - } - } - //----------------------------------------------------------------------- - Radian Quaternion::getPitch(bool reprojectAxis) const - { - if (reprojectAxis) - { - // pitch = atan2(localy.z, localy.y) - // pick parts of yAxis() implementation that we need - Real fTx = 2.0f*x; -// Real fTy = 2.0f*y; - Real fTz = 2.0f*z; - Real fTwx = fTx*w; - Real fTxx = fTx*x; - Real fTyz = fTz*y; - Real fTzz = fTz*z; - - // Vector3(fTxy-fTwz, 1.0-(fTxx+fTzz), fTyz+fTwx); - return Radian(Math::ATan2(fTyz+fTwx, 1.0f-(fTxx+fTzz))); - } - else - { - // internal version - return Radian(Math::ATan2(2*(y*z + w*x), w*w - x*x - y*y + z*z)); - } - } - //----------------------------------------------------------------------- - Radian Quaternion::getYaw(bool reprojectAxis) const - { - if (reprojectAxis) - { - // yaw = atan2(localz.x, localz.z) - // pick parts of zAxis() implementation that we need - Real fTx = 2.0f*x; - Real fTy = 2.0f*y; - Real fTz = 2.0f*z; - Real fTwy = fTy*w; - Real fTxx = fTx*x; - Real fTxz = fTz*x; - Real fTyy = fTy*y; - - // Vector3(fTxz+fTwy, fTyz-fTwx, 1.0-(fTxx+fTyy)); - - return Radian(Math::ATan2(fTxz+fTwy, 1.0f-(fTxx+fTyy))); - - } - else - { - // internal version - return Radian(Math::ASin(-2*(x*z - w*y))); - } - } + Radian Quaternion::getRoll(bool reprojectAxis) const + { + if (reprojectAxis) + { + // roll = atan2(localx.y, localx.x) + // pick parts of xAxis() implementation that we need +// Real fTx = 2.0*x; + Real fTy = 2.0f*y; + Real fTz = 2.0f*z; + Real fTwz = fTz*w; + Real fTxy = fTy*x; + Real fTyy = fTy*y; + Real fTzz = fTz*z; + + // Vector3(1.0-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy); + + return Radian(Math::ATan2(fTxy+fTwz, 1.0f-(fTyy+fTzz))); + + } + else + { + return Radian(Math::ATan2(2*(x*y + w*z), w*w + x*x - y*y - z*z)); + } + } + //----------------------------------------------------------------------- + Radian Quaternion::getPitch(bool reprojectAxis) const + { + if (reprojectAxis) + { + // pitch = atan2(localy.z, localy.y) + // pick parts of yAxis() implementation that we need + Real fTx = 2.0f*x; +// Real fTy = 2.0f*y; + Real fTz = 2.0f*z; + Real fTwx = fTx*w; + Real fTxx = fTx*x; + Real fTyz = fTz*y; + Real fTzz = fTz*z; + + // Vector3(fTxy-fTwz, 1.0-(fTxx+fTzz), fTyz+fTwx); + return Radian(Math::ATan2(fTyz+fTwx, 1.0f-(fTxx+fTzz))); + } + else + { + // internal version + return Radian(Math::ATan2(2*(y*z + w*x), w*w - x*x - y*y + z*z)); + } + } + //----------------------------------------------------------------------- + Radian Quaternion::getYaw(bool reprojectAxis) const + { + if (reprojectAxis) + { + // yaw = atan2(localz.x, localz.z) + // pick parts of zAxis() implementation that we need + Real fTx = 2.0f*x; + Real fTy = 2.0f*y; + Real fTz = 2.0f*z; + Real fTwy = fTy*w; + Real fTxx = fTx*x; + Real fTxz = fTz*x; + Real fTyy = fTy*y; + + // Vector3(fTxz+fTwy, fTyz-fTwx, 1.0-(fTxx+fTyy)); + + return Radian(Math::ATan2(fTxz+fTwy, 1.0f-(fTxx+fTyy))); + + } + else + { + // internal version + return Radian(Math::ASin(-2*(x*z - w*y))); + } + } //----------------------------------------------------------------------- Quaternion Quaternion::nlerp(Real fT, const Quaternion& rkP, const Quaternion& rkQ, bool shortestPath) { - Quaternion result; + Quaternion result; Real fCos = rkP.Dot(rkQ); - if (fCos < 0.0f && shortestPath) - { - result = rkP + fT * ((-rkQ) - rkP); - } - else - { - result = rkP + fT * (rkQ - rkP); - } + if (fCos < 0.0f && shortestPath) + { + result = rkP + fT * ((-rkQ) - rkP); + } + else + { + result = rkP + fT * (rkQ - rkP); + } result.normalise(); return result; } diff --git a/OgreMain/src/OgreRectangle2D.cpp b/OgreMain/src/OgreRectangle2D.cpp index 3c287d2ef6b..701d1c7f3c4 100644 --- a/OgreMain/src/OgreRectangle2D.cpp +++ b/OgreMain/src/OgreRectangle2D.cpp @@ -35,19 +35,19 @@ namespace Ogre { #define NORMAL_BINDING 1 #define TEXCOORD_BINDING 2 - Rectangle2D::Rectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage) - : SimpleRenderable() - { - _initRectangle2D(includeTextureCoords, vBufUsage); - } - - Rectangle2D::Rectangle2D(const String& name, bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage) - : SimpleRenderable(name) - { - _initRectangle2D(includeTextureCoords, vBufUsage); - } - - void Rectangle2D::_initRectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage) + Rectangle2D::Rectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage) + : SimpleRenderable() + { + _initRectangle2D(includeTextureCoords, vBufUsage); + } + + Rectangle2D::Rectangle2D(const String& name, bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage) + : SimpleRenderable(name) + { + _initRectangle2D(includeTextureCoords, vBufUsage); + } + + void Rectangle2D::_initRectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage) { // use identity projection and view matrices mUseIdentityProjection = true; @@ -77,34 +77,34 @@ namespace Ogre { // Bind buffer bind->setBinding(POSITION_BINDING, vbuf); - decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL); + decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL); - vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( + vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( decl->getVertexSize(NORMAL_BINDING), mRenderOp.vertexData->vertexCount, vBufUsage); - bind->setBinding(NORMAL_BINDING, vbuf); + bind->setBinding(NORMAL_BINDING, vbuf); - float *pNorm = static_cast(vbuf->lock(HardwareBuffer::HBL_DISCARD)); - *pNorm++ = 0.0f; - *pNorm++ = 0.0f; - *pNorm++ = 1.0f; + float *pNorm = static_cast(vbuf->lock(HardwareBuffer::HBL_DISCARD)); + *pNorm++ = 0.0f; + *pNorm++ = 0.0f; + *pNorm++ = 1.0f; - *pNorm++ = 0.0f; - *pNorm++ = 0.0f; - *pNorm++ = 1.0f; + *pNorm++ = 0.0f; + *pNorm++ = 0.0f; + *pNorm++ = 1.0f; - *pNorm++ = 0.0f; - *pNorm++ = 0.0f; - *pNorm++ = 1.0f; + *pNorm++ = 0.0f; + *pNorm++ = 0.0f; + *pNorm++ = 1.0f; - *pNorm++ = 0.0f; - *pNorm++ = 0.0f; - *pNorm++ = 1.0f; + *pNorm++ = 0.0f; + *pNorm++ = 0.0f; + *pNorm++ = 1.0f; - vbuf->unlock(); + vbuf->unlock(); if (includeTextureCoords) { @@ -157,17 +157,17 @@ namespace Ogre { vbuf->unlock(); - if(updateAABB) - { - mBox.setExtents( - std::min(left, right), std::min(top, bottom), 0, - std::max(left, right), std::max(top, bottom), 0); - } + if(updateAABB) + { + mBox.setExtents( + std::min(left, right), std::min(top, bottom), 0, + std::max(left, right), std::max(top, bottom), 0); + } } - void Rectangle2D::setNormals(const Ogre::Vector3 &topLeft, const Ogre::Vector3 &bottomLeft, const Ogre::Vector3 &topRight, const Ogre::Vector3 &bottomRight) - { - HardwareVertexBufferSharedPtr vbuf = + void Rectangle2D::setNormals(const Ogre::Vector3 &topLeft, const Ogre::Vector3 &bottomLeft, const Ogre::Vector3 &topRight, const Ogre::Vector3 &bottomRight) + { + HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(NORMAL_BINDING); float* pFloat = static_cast(vbuf->lock(HardwareBuffer::HBL_DISCARD)); @@ -188,15 +188,15 @@ namespace Ogre { *pFloat++ = bottomRight.z; vbuf->unlock(); - } + } - void Rectangle2D::setUVs( const Ogre::Vector2 &topLeft, const Ogre::Vector2 &bottomLeft, - const Ogre::Vector2 &topRight, const Ogre::Vector2 &bottomRight) - { - if( mRenderOp.vertexData->vertexDeclaration->getElementCount() <= TEXCOORD_BINDING ) - return; //Vertex data wasn't built with UV buffer + void Rectangle2D::setUVs( const Ogre::Vector2 &topLeft, const Ogre::Vector2 &bottomLeft, + const Ogre::Vector2 &topRight, const Ogre::Vector2 &bottomRight) + { + if( mRenderOp.vertexData->vertexDeclaration->getElementCount() <= TEXCOORD_BINDING ) + return; //Vertex data wasn't built with UV buffer - HardwareVertexBufferSharedPtr vbuf = + HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING); float* pFloat = static_cast(vbuf->lock(HardwareBuffer::HBL_DISCARD)); @@ -213,12 +213,12 @@ namespace Ogre { *pFloat++ = bottomRight.y; vbuf->unlock(); - } + } - void Rectangle2D::setDefaultUVs() - { - setUVs( Vector2::ZERO, Vector2::UNIT_Y, Vector2::UNIT_X, Vector2::UNIT_SCALE ); - } + void Rectangle2D::setDefaultUVs() + { + setUVs( Vector2::ZERO, Vector2::UNIT_Y, Vector2::UNIT_X, Vector2::UNIT_SCALE ); + } // Override this method to prevent parent transforms (rotation,translation,scale) void Rectangle2D::getWorldTransforms( Matrix4* xform ) const diff --git a/OgreMain/src/OgreRenderQueue.cpp b/OgreMain/src/OgreRenderQueue.cpp index f3269fa463c..421581986a4 100644 --- a/OgreMain/src/OgreRenderQueue.cpp +++ b/OgreMain/src/OgreRenderQueue.cpp @@ -44,9 +44,9 @@ namespace Ogre { //--------------------------------------------------------------------- RenderQueue::RenderQueue() : mSplitPassesByLightingType(false) - , mSplitNoShadowPasses(false) + , mSplitNoShadowPasses(false) , mShadowCastersCannotBeReceivers(false) - , mRenderableListener(0) + , mRenderableListener(0) { // Create the 'main' queue up-front since we'll always need that mGroups.insert( @@ -61,7 +61,7 @@ namespace Ogre { // set default queue mDefaultQueueGroup = RENDER_QUEUE_MAIN; - mDefaultRenderablePriority = OGRE_RENDERABLE_DEFAULT_PRIORITY; + mDefaultRenderablePriority = OGRE_RENDERABLE_DEFAULT_PRIORITY; } //--------------------------------------------------------------------- @@ -87,13 +87,13 @@ namespace Ogre { // Find group RenderQueueGroup* pGroup = getQueueGroup(groupID); - Technique* pTech; + Technique* pTech; - // tell material it's been used - if (!pRend->getMaterial().isNull()) - pRend->getMaterial()->touch(); + // tell material it's been used + if (!pRend->getMaterial().isNull()) + pRend->getMaterial()->touch(); - // Check material & technique supplied (the former since the default implementation + // Check material & technique supplied (the former since the default implementation // of getTechnique is based on it for backwards compatibility if(pRend->getMaterial().isNull() || !pRend->getTechnique()) { @@ -101,20 +101,20 @@ namespace Ogre { MaterialPtr baseWhite = MaterialManager::getSingleton().getByName("BaseWhite"); pTech = baseWhite->getTechnique(0); } - else - pTech = pRend->getTechnique(); - - if (mRenderableListener) - { - // Allow listener to override technique and to abort - if (!mRenderableListener->renderableQueued(pRend, groupID, priority, - &pTech, this)) - return; // rejected - - // tell material it's been used (incase changed) - pTech->getParent()->touch(); - } - + else + pTech = pRend->getTechnique(); + + if (mRenderableListener) + { + // Allow listener to override technique and to abort + if (!mRenderableListener->renderableQueued(pRend, groupID, priority, + &pTech, this)) + return; // rejected + + // tell material it's been used (incase changed) + pTech->getParent()->touch(); + } + pGroup->addRenderable(pRend, pTech, priority); } @@ -165,7 +165,7 @@ namespace Ogre { { addRenderable(pRend, groupID, mDefaultRenderablePriority); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void RenderQueue::addRenderable(Renderable* pRend) { addRenderable(pRend, mDefaultQueueGroup, mDefaultRenderablePriority); @@ -190,33 +190,33 @@ namespace Ogre { { mDefaultRenderablePriority = priority; } - - - //----------------------------------------------------------------------- - RenderQueueGroup* RenderQueue::getQueueGroup(uint8 groupID) - { - // Find group - RenderQueueGroupMap::iterator groupIt; - RenderQueueGroup* pGroup; - - groupIt = mGroups.find(groupID); - if (groupIt == mGroups.end()) - { - // Insert new - pGroup = OGRE_NEW RenderQueueGroup(this, + + + //----------------------------------------------------------------------- + RenderQueueGroup* RenderQueue::getQueueGroup(uint8 groupID) + { + // Find group + RenderQueueGroupMap::iterator groupIt; + RenderQueueGroup* pGroup; + + groupIt = mGroups.find(groupID); + if (groupIt == mGroups.end()) + { + // Insert new + pGroup = OGRE_NEW RenderQueueGroup(this, mSplitPassesByLightingType, mSplitNoShadowPasses, mShadowCastersCannotBeReceivers); - mGroups.insert(RenderQueueGroupMap::value_type(groupID, pGroup)); - } - else - { - pGroup = groupIt->second; - } + mGroups.insert(RenderQueueGroupMap::value_type(groupID, pGroup)); + } + else + { + pGroup = groupIt->second; + } - return pGroup; + return pGroup; - } + } //----------------------------------------------------------------------- void RenderQueue::setSplitPassesByLightingType(bool split) { @@ -253,71 +253,71 @@ namespace Ogre { { return mSplitNoShadowPasses; } - //----------------------------------------------------------------------- - void RenderQueue::setShadowCastersCannotBeReceivers(bool ind) - { - mShadowCastersCannotBeReceivers = ind; - - RenderQueueGroupMap::iterator i, iend; - i = mGroups.begin(); - iend = mGroups.end(); - for (; i != iend; ++i) - { - i->second->setShadowCastersCannotBeReceivers(ind); - } - } - //----------------------------------------------------------------------- - bool RenderQueue::getShadowCastersCannotBeReceivers(void) const - { - return mShadowCastersCannotBeReceivers; - } - //----------------------------------------------------------------------- - void RenderQueue::merge( const RenderQueue* rhs ) - { - ConstQueueGroupIterator it = rhs->_getQueueGroupIterator( ); - - while( it.hasMoreElements() ) - { - uint8 groupID = it.peekNextKey(); - RenderQueueGroup* pSrcGroup = it.getNext(); - RenderQueueGroup* pDstGroup = getQueueGroup( groupID ); - - pDstGroup->merge( pSrcGroup ); - } - } - - //--------------------------------------------------------------------- - void RenderQueue::processVisibleObject(MovableObject* mo, - Camera* cam, - bool onlyShadowCasters, - VisibleObjectsBoundsInfo* visibleBounds) - { - mo->_notifyCurrentCamera(cam); - if (mo->isVisible()) - { - bool receiveShadows = getQueueGroup(mo->getRenderQueueGroup())->getShadowsEnabled() - && mo->getReceivesShadows(); - - if (!onlyShadowCasters || mo->getCastShadows()) - { - mo -> _updateRenderQueue( this ); - if (visibleBounds) - { - visibleBounds->merge(mo->getWorldBoundingBox(true), - mo->getWorldBoundingSphere(true), cam, - receiveShadows); - } - } - // not shadow caster, receiver only? - else if (onlyShadowCasters && !mo->getCastShadows() && - receiveShadows) - { - visibleBounds->mergeNonRenderedButInFrustum(mo->getWorldBoundingBox(true), - mo->getWorldBoundingSphere(true), cam); - } - } - - } + //----------------------------------------------------------------------- + void RenderQueue::setShadowCastersCannotBeReceivers(bool ind) + { + mShadowCastersCannotBeReceivers = ind; + + RenderQueueGroupMap::iterator i, iend; + i = mGroups.begin(); + iend = mGroups.end(); + for (; i != iend; ++i) + { + i->second->setShadowCastersCannotBeReceivers(ind); + } + } + //----------------------------------------------------------------------- + bool RenderQueue::getShadowCastersCannotBeReceivers(void) const + { + return mShadowCastersCannotBeReceivers; + } + //----------------------------------------------------------------------- + void RenderQueue::merge( const RenderQueue* rhs ) + { + ConstQueueGroupIterator it = rhs->_getQueueGroupIterator( ); + + while( it.hasMoreElements() ) + { + uint8 groupID = it.peekNextKey(); + RenderQueueGroup* pSrcGroup = it.getNext(); + RenderQueueGroup* pDstGroup = getQueueGroup( groupID ); + + pDstGroup->merge( pSrcGroup ); + } + } + + //--------------------------------------------------------------------- + void RenderQueue::processVisibleObject(MovableObject* mo, + Camera* cam, + bool onlyShadowCasters, + VisibleObjectsBoundsInfo* visibleBounds) + { + mo->_notifyCurrentCamera(cam); + if (mo->isVisible()) + { + bool receiveShadows = getQueueGroup(mo->getRenderQueueGroup())->getShadowsEnabled() + && mo->getReceivesShadows(); + + if (!onlyShadowCasters || mo->getCastShadows()) + { + mo -> _updateRenderQueue( this ); + if (visibleBounds) + { + visibleBounds->merge(mo->getWorldBoundingBox(true), + mo->getWorldBoundingSphere(true), cam, + receiveShadows); + } + } + // not shadow caster, receiver only? + else if (onlyShadowCasters && !mo->getCastShadows() && + receiveShadows) + { + visibleBounds->mergeNonRenderedButInFrustum(mo->getWorldBoundingBox(true), + mo->getWorldBoundingSphere(true), cam); + } + } + + } } diff --git a/OgreMain/src/OgreRenderQueueInvocation.cpp b/OgreMain/src/OgreRenderQueueInvocation.cpp index f05689b8011..183346e0139 100644 --- a/OgreMain/src/OgreRenderQueueInvocation.cpp +++ b/OgreMain/src/OgreRenderQueueInvocation.cpp @@ -33,104 +33,104 @@ THE SOFTWARE. namespace Ogre { - String RenderQueueInvocation::RENDER_QUEUE_INVOCATION_SHADOWS = "SHADOWS"; - //----------------------------------------------------------------------------- - RenderQueueInvocation::RenderQueueInvocation(uint8 renderQueueGroupID, - const String& invocationName) - : mRenderQueueGroupID(renderQueueGroupID), mInvocationName(invocationName), - mSolidsOrganisation(QueuedRenderableCollection::OM_PASS_GROUP), - mSuppressShadows(false), mSuppressRenderStateChanges(false) - { - - } - //----------------------------------------------------------------------------- - RenderQueueInvocation::~RenderQueueInvocation() - { - - } - //----------------------------------------------------------------------------- - void RenderQueueInvocation::invoke(RenderQueueGroup* group, SceneManager* targetSceneManager) - { - bool oldShadows = targetSceneManager->_areShadowsSuppressed(); - bool oldRSChanges = targetSceneManager->_areRenderStateChangesSuppressed(); - - targetSceneManager->_suppressShadows(mSuppressShadows); - targetSceneManager->_suppressRenderStateChanges(mSuppressRenderStateChanges); - - targetSceneManager->_renderQueueGroupObjects(group, mSolidsOrganisation); - - targetSceneManager->_suppressShadows(oldShadows); - targetSceneManager->_suppressRenderStateChanges(oldRSChanges); - - } - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- - RenderQueueInvocationSequence::RenderQueueInvocationSequence(const String& name) - :mName(name) - { - } - //----------------------------------------------------------------------------- - RenderQueueInvocationSequence::~RenderQueueInvocationSequence() - { - clear(); - } - //----------------------------------------------------------------------------- - RenderQueueInvocation* RenderQueueInvocationSequence::add(uint8 renderQueueGroupID, - const String& invocationName) - { - RenderQueueInvocation* ret = - OGRE_NEW RenderQueueInvocation(renderQueueGroupID, invocationName); - - mInvocations.push_back(ret); - - return ret; - - } - //----------------------------------------------------------------------------- - void RenderQueueInvocationSequence::add(RenderQueueInvocation* i) - { - mInvocations.push_back(i); - } - //----------------------------------------------------------------------------- - void RenderQueueInvocationSequence::clear(void) - { - for (RenderQueueInvocationList::iterator i = mInvocations.begin(); - i != mInvocations.end(); ++i) - { - OGRE_DELETE *i; - } - mInvocations.clear(); - } - //----------------------------------------------------------------------------- - RenderQueueInvocation* RenderQueueInvocationSequence::get(size_t index) - { - if (index >= size()) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Index out of bounds", - "RenderQueueInvocationSequence::get"); - - return mInvocations[index]; - } - //----------------------------------------------------------------------------- - void RenderQueueInvocationSequence::remove(size_t index) - { - if (index >= size()) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Index out of bounds", - "RenderQueueInvocationSequence::remove"); - - RenderQueueInvocationList::iterator i = mInvocations.begin(); - std::advance(i, index); - OGRE_DELETE *i; - mInvocations.erase(i); - - } - //----------------------------------------------------------------------------- - RenderQueueInvocationIterator RenderQueueInvocationSequence::iterator(void) - { - return RenderQueueInvocationIterator(mInvocations.begin(), mInvocations.end()); - } - //----------------------------------------------------------------------------- + String RenderQueueInvocation::RENDER_QUEUE_INVOCATION_SHADOWS = "SHADOWS"; + //----------------------------------------------------------------------------- + RenderQueueInvocation::RenderQueueInvocation(uint8 renderQueueGroupID, + const String& invocationName) + : mRenderQueueGroupID(renderQueueGroupID), mInvocationName(invocationName), + mSolidsOrganisation(QueuedRenderableCollection::OM_PASS_GROUP), + mSuppressShadows(false), mSuppressRenderStateChanges(false) + { + + } + //----------------------------------------------------------------------------- + RenderQueueInvocation::~RenderQueueInvocation() + { + + } + //----------------------------------------------------------------------------- + void RenderQueueInvocation::invoke(RenderQueueGroup* group, SceneManager* targetSceneManager) + { + bool oldShadows = targetSceneManager->_areShadowsSuppressed(); + bool oldRSChanges = targetSceneManager->_areRenderStateChangesSuppressed(); + + targetSceneManager->_suppressShadows(mSuppressShadows); + targetSceneManager->_suppressRenderStateChanges(mSuppressRenderStateChanges); + + targetSceneManager->_renderQueueGroupObjects(group, mSolidsOrganisation); + + targetSceneManager->_suppressShadows(oldShadows); + targetSceneManager->_suppressRenderStateChanges(oldRSChanges); + + } + //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + RenderQueueInvocationSequence::RenderQueueInvocationSequence(const String& name) + :mName(name) + { + } + //----------------------------------------------------------------------------- + RenderQueueInvocationSequence::~RenderQueueInvocationSequence() + { + clear(); + } + //----------------------------------------------------------------------------- + RenderQueueInvocation* RenderQueueInvocationSequence::add(uint8 renderQueueGroupID, + const String& invocationName) + { + RenderQueueInvocation* ret = + OGRE_NEW RenderQueueInvocation(renderQueueGroupID, invocationName); + + mInvocations.push_back(ret); + + return ret; + + } + //----------------------------------------------------------------------------- + void RenderQueueInvocationSequence::add(RenderQueueInvocation* i) + { + mInvocations.push_back(i); + } + //----------------------------------------------------------------------------- + void RenderQueueInvocationSequence::clear(void) + { + for (RenderQueueInvocationList::iterator i = mInvocations.begin(); + i != mInvocations.end(); ++i) + { + OGRE_DELETE *i; + } + mInvocations.clear(); + } + //----------------------------------------------------------------------------- + RenderQueueInvocation* RenderQueueInvocationSequence::get(size_t index) + { + if (index >= size()) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Index out of bounds", + "RenderQueueInvocationSequence::get"); + + return mInvocations[index]; + } + //----------------------------------------------------------------------------- + void RenderQueueInvocationSequence::remove(size_t index) + { + if (index >= size()) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Index out of bounds", + "RenderQueueInvocationSequence::remove"); + + RenderQueueInvocationList::iterator i = mInvocations.begin(); + std::advance(i, index); + OGRE_DELETE *i; + mInvocations.erase(i); + + } + //----------------------------------------------------------------------------- + RenderQueueInvocationIterator RenderQueueInvocationSequence::iterator(void) + { + return RenderQueueInvocationIterator(mInvocations.begin(), mInvocations.end()); + } + //----------------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreRenderQueueSortingGrouping.cpp b/OgreMain/src/OgreRenderQueueSortingGrouping.cpp index 4e3ad9d5f0f..0db8b1044bc 100644 --- a/OgreMain/src/OgreRenderQueueSortingGrouping.cpp +++ b/OgreMain/src/OgreRenderQueueSortingGrouping.cpp @@ -38,65 +38,65 @@ namespace Ogre { RenderablePass, float> QueuedRenderableCollection::msRadixSorter2; - //----------------------------------------------------------------------- - RenderPriorityGroup::RenderPriorityGroup(RenderQueueGroup* parent, + //----------------------------------------------------------------------- + RenderPriorityGroup::RenderPriorityGroup(RenderQueueGroup* parent, bool splitPassesByLightingType, bool splitNoShadowPasses, - bool shadowCastersNotReceivers) - : mParent(parent) + bool shadowCastersNotReceivers) + : mParent(parent) , mSplitPassesByLightingType(splitPassesByLightingType) , mSplitNoShadowPasses(splitNoShadowPasses) , mShadowCastersNotReceivers(shadowCastersNotReceivers) - { - // Initialise collection sorting options - // this can become dynamic according to invocation later - defaultOrganisationMode(); - - // Transparents will always be sorted this way - mTransparents.addOrganisationMode(QueuedRenderableCollection::OM_SORT_DESCENDING); - - - } - //----------------------------------------------------------------------- - void RenderPriorityGroup::resetOrganisationModes(void) - { - mSolidsBasic.resetOrganisationModes(); - mSolidsDiffuseSpecular.resetOrganisationModes(); - mSolidsDecal.resetOrganisationModes(); - mSolidsNoShadowReceive.resetOrganisationModes(); - mTransparentsUnsorted.resetOrganisationModes(); - } - //----------------------------------------------------------------------- - void RenderPriorityGroup::addOrganisationMode(QueuedRenderableCollection::OrganisationMode om) - { - mSolidsBasic.addOrganisationMode(om); - mSolidsDiffuseSpecular.addOrganisationMode(om); - mSolidsDecal.addOrganisationMode(om); - mSolidsNoShadowReceive.addOrganisationMode(om); - mTransparentsUnsorted.addOrganisationMode(om); - } - //----------------------------------------------------------------------- - void RenderPriorityGroup::defaultOrganisationMode(void) - { - resetOrganisationModes(); - addOrganisationMode(QueuedRenderableCollection::OM_PASS_GROUP); - } - //----------------------------------------------------------------------- + { + // Initialise collection sorting options + // this can become dynamic according to invocation later + defaultOrganisationMode(); + + // Transparents will always be sorted this way + mTransparents.addOrganisationMode(QueuedRenderableCollection::OM_SORT_DESCENDING); + + + } + //----------------------------------------------------------------------- + void RenderPriorityGroup::resetOrganisationModes(void) + { + mSolidsBasic.resetOrganisationModes(); + mSolidsDiffuseSpecular.resetOrganisationModes(); + mSolidsDecal.resetOrganisationModes(); + mSolidsNoShadowReceive.resetOrganisationModes(); + mTransparentsUnsorted.resetOrganisationModes(); + } + //----------------------------------------------------------------------- + void RenderPriorityGroup::addOrganisationMode(QueuedRenderableCollection::OrganisationMode om) + { + mSolidsBasic.addOrganisationMode(om); + mSolidsDiffuseSpecular.addOrganisationMode(om); + mSolidsDecal.addOrganisationMode(om); + mSolidsNoShadowReceive.addOrganisationMode(om); + mTransparentsUnsorted.addOrganisationMode(om); + } + //----------------------------------------------------------------------- + void RenderPriorityGroup::defaultOrganisationMode(void) + { + resetOrganisationModes(); + addOrganisationMode(QueuedRenderableCollection::OM_PASS_GROUP); + } + //----------------------------------------------------------------------- void RenderPriorityGroup::addRenderable(Renderable* rend, Technique* pTech) { // Transparent and depth/colour settings mean depth sorting is required? // Note: colour write disabled with depth check/write enabled means // setup depth buffer for other passes use. if (pTech->isTransparentSortingForced() || - (pTech->isTransparent() && + (pTech->isTransparent() && (!pTech->isDepthWriteEnabled() || !pTech->isDepthCheckEnabled() || pTech->hasColourWriteDisabled()))) { - if (pTech->isTransparentSortingEnabled()) - addTransparentRenderable(pTech, rend); - else - addUnsortedTransparentRenderable(pTech, rend); + if (pTech->isTransparentSortingEnabled()) + addTransparentRenderable(pTech, rend); + else + addUnsortedTransparentRenderable(pTech, rend); } else { @@ -128,7 +128,7 @@ namespace Ogre { { Technique::PassIterator pi = pTech->getPassIterator(); - QueuedRenderableCollection* collection; + QueuedRenderableCollection* collection; if (addToNoShadow) { collection = &mSolidsNoShadowReceive; @@ -143,7 +143,7 @@ namespace Ogre { { // Insert into solid list Pass* p = pi.getNext(); - collection->addRenderable(p, rend); + collection->addRenderable(p, rend); } } //----------------------------------------------------------------------- @@ -174,7 +174,7 @@ namespace Ogre { assert(false); // should never happen }; - collection->addRenderable(p->pass, rend); + collection->addRenderable(p->pass, rend); } } //----------------------------------------------------------------------- @@ -200,91 +200,91 @@ namespace Ogre { } } //----------------------------------------------------------------------- - void RenderPriorityGroup::removePassEntry(Pass* p) - { - mSolidsBasic.removePassGroup(p); - mSolidsDiffuseSpecular.removePassGroup(p); - mSolidsNoShadowReceive.removePassGroup(p); - mSolidsDecal.removePassGroup(p); - mTransparentsUnsorted.removePassGroup(p); - mTransparents.removePassGroup(p); // shouldn't be any, but for completeness - } + void RenderPriorityGroup::removePassEntry(Pass* p) + { + mSolidsBasic.removePassGroup(p); + mSolidsDiffuseSpecular.removePassGroup(p); + mSolidsNoShadowReceive.removePassGroup(p); + mSolidsDecal.removePassGroup(p); + mTransparentsUnsorted.removePassGroup(p); + mTransparents.removePassGroup(p); // shouldn't be any, but for completeness + } //----------------------------------------------------------------------- void RenderPriorityGroup::clear(void) { // Delete queue groups which are using passes which are to be // deleted, we won't need these any more and they clutter up // the list and can cause problems with future clones - { - // Hmm, a bit hacky but least obtrusive for now + { + // Hmm, a bit hacky but least obtrusive for now OGRE_LOCK_MUTEX(Pass::msPassGraveyardMutex); - const Pass::PassSet& graveyardList = Pass::getPassGraveyard(); - Pass::PassSet::const_iterator gi, giend; - giend = graveyardList.end(); - for (gi = graveyardList.begin(); gi != giend; ++gi) - { - removePassEntry(*gi); - } - } + const Pass::PassSet& graveyardList = Pass::getPassGraveyard(); + Pass::PassSet::const_iterator gi, giend; + giend = graveyardList.end(); + for (gi = graveyardList.begin(); gi != giend; ++gi) + { + removePassEntry(*gi); + } + } // Now remove any dirty passes, these will have their hashes recalculated // by the parent queue after all groups have been processed // If we don't do this, the std::map will become inconsistent for new insterts - { - // Hmm, a bit hacky but least obtrusive for now + { + // Hmm, a bit hacky but least obtrusive for now OGRE_LOCK_MUTEX(Pass::msDirtyHashListMutex); - const Pass::PassSet& dirtyList = Pass::getDirtyHashList(); - Pass::PassSet::const_iterator di, diend; - diend = dirtyList.end(); - for (di = dirtyList.begin(); di != diend; ++di) - { - removePassEntry(*di); - } - } + const Pass::PassSet& dirtyList = Pass::getDirtyHashList(); + Pass::PassSet::const_iterator di, diend; + diend = dirtyList.end(); + for (di = dirtyList.begin(); di != diend; ++di) + { + removePassEntry(*di); + } + } // NB we do NOT clear the graveyard or the dirty list here, because // it needs to be acted on for all groups, the parent queue takes // care of this afterwards - // Now empty the remaining collections - // Note that groups don't get deleted, just emptied hence the difference - // between the pass groups which are removed above, and clearing done - // here - mSolidsBasic.clear(); + // Now empty the remaining collections + // Note that groups don't get deleted, just emptied hence the difference + // between the pass groups which are removed above, and clearing done + // here + mSolidsBasic.clear(); mSolidsDecal.clear(); mSolidsDiffuseSpecular.clear(); mSolidsNoShadowReceive.clear(); - mTransparentsUnsorted.clear(); + mTransparentsUnsorted.clear(); mTransparents.clear(); } - //----------------------------------------------------------------------- - void RenderPriorityGroup::sort(const Camera* cam) - { - mSolidsBasic.sort(cam); - mSolidsDecal.sort(cam); - mSolidsDiffuseSpecular.sort(cam); - mSolidsNoShadowReceive.sort(cam); - mTransparentsUnsorted.sort(cam); - mTransparents.sort(cam); - } //----------------------------------------------------------------------- - void RenderPriorityGroup::merge( const RenderPriorityGroup* rhs ) - { - mSolidsBasic.merge( rhs->mSolidsBasic ); - mSolidsDecal.merge( rhs->mSolidsDecal ); - mSolidsDiffuseSpecular.merge( rhs->mSolidsDiffuseSpecular ); - mSolidsNoShadowReceive.merge( rhs->mSolidsNoShadowReceive ); - mTransparentsUnsorted.merge( rhs->mTransparentsUnsorted ); - mTransparents.merge( rhs->mTransparents ); - } - //----------------------------------------------------------------------- - QueuedRenderableCollection::QueuedRenderableCollection(void) - :mOrganisationMode(0) - { - } + void RenderPriorityGroup::sort(const Camera* cam) + { + mSolidsBasic.sort(cam); + mSolidsDecal.sort(cam); + mSolidsDiffuseSpecular.sort(cam); + mSolidsNoShadowReceive.sort(cam); + mTransparentsUnsorted.sort(cam); + mTransparents.sort(cam); + } + //----------------------------------------------------------------------- + void RenderPriorityGroup::merge( const RenderPriorityGroup* rhs ) + { + mSolidsBasic.merge( rhs->mSolidsBasic ); + mSolidsDecal.merge( rhs->mSolidsDecal ); + mSolidsDiffuseSpecular.merge( rhs->mSolidsDiffuseSpecular ); + mSolidsNoShadowReceive.merge( rhs->mSolidsNoShadowReceive ); + mTransparentsUnsorted.merge( rhs->mTransparentsUnsorted ); + mTransparents.merge( rhs->mTransparents ); + } + //----------------------------------------------------------------------- + QueuedRenderableCollection::QueuedRenderableCollection(void) + :mOrganisationMode(0) + { + } //----------------------------------------------------------------------- - QueuedRenderableCollection::~QueuedRenderableCollection(void) - { + QueuedRenderableCollection::~QueuedRenderableCollection(void) + { // destroy all the pass map entries (rather than clearing) PassGroupRenderableMap::iterator i, iend; iend = mGrouped.end(); @@ -293,11 +293,11 @@ namespace Ogre { // Free the list associated with this pass OGRE_DELETE_T(i->second, RenderableList, MEMCATEGORY_SCENE_CONTROL); } - - } + + } //----------------------------------------------------------------------- - void QueuedRenderableCollection::clear(void) - { + void QueuedRenderableCollection::clear(void) + { PassGroupRenderableMap::iterator i, iend; iend = mGrouped.end(); for (i = mGrouped.begin(); i != iend; ++i) @@ -306,12 +306,12 @@ namespace Ogre { i->second->clear(); } - // Clear sorted list - mSortedDescending.clear(); - } + // Clear sorted list + mSortedDescending.clear(); + } //----------------------------------------------------------------------- - void QueuedRenderableCollection::removePassGroup(Pass* p) - { + void QueuedRenderableCollection::removePassGroup(Pass* p) + { PassGroupRenderableMap::iterator i; i = mGrouped.find(p); @@ -322,192 +322,192 @@ namespace Ogre { // erase from map mGrouped.erase(i); } - } + } //----------------------------------------------------------------------- - void QueuedRenderableCollection::sort(const Camera* cam) + void QueuedRenderableCollection::sort(const Camera* cam) { - // ascending and descending sort both set bit 1 - // We always sort descending, because the only difference is in the - // acceptVisitor method, where we iterate in reverse in ascending mode - if (mOrganisationMode & OM_SORT_DESCENDING) - { - - // We can either use a stable_sort and the 'less' implementation, - // or a 2-pass radix sort (once by pass, then by distance, since - // radix sorting is inherently stable this will work) - // We use stable_sort if the number of items is 512 or less, since - // the complexity of the radix sort is approximately O(10N), since - // each sort is O(5N) (1 pass histograms, 4 passes sort) - // Since stable_sort has a worst-case performance of O(N(logN)^2) - // the performance tipping point is from about 1500 items, but in - // stable_sorts best-case scenario O(NlogN) it would be much higher. - // Take a stab at 2000 items. - - if (mSortedDescending.size() > 2000) - { - // sort by pass - msRadixSorter1.sort(mSortedDescending, RadixSortFunctorPass()); - // sort by depth - msRadixSorter2.sort(mSortedDescending, RadixSortFunctorDistance(cam)); - } - else - { - std::stable_sort( - mSortedDescending.begin(), mSortedDescending.end(), - DepthSortDescendingLess(cam)); - } - } - - // Nothing needs to be done for pass groups, they auto-organise + // ascending and descending sort both set bit 1 + // We always sort descending, because the only difference is in the + // acceptVisitor method, where we iterate in reverse in ascending mode + if (mOrganisationMode & OM_SORT_DESCENDING) + { + + // We can either use a stable_sort and the 'less' implementation, + // or a 2-pass radix sort (once by pass, then by distance, since + // radix sorting is inherently stable this will work) + // We use stable_sort if the number of items is 512 or less, since + // the complexity of the radix sort is approximately O(10N), since + // each sort is O(5N) (1 pass histograms, 4 passes sort) + // Since stable_sort has a worst-case performance of O(N(logN)^2) + // the performance tipping point is from about 1500 items, but in + // stable_sorts best-case scenario O(NlogN) it would be much higher. + // Take a stab at 2000 items. + + if (mSortedDescending.size() > 2000) + { + // sort by pass + msRadixSorter1.sort(mSortedDescending, RadixSortFunctorPass()); + // sort by depth + msRadixSorter2.sort(mSortedDescending, RadixSortFunctorDistance(cam)); + } + else + { + std::stable_sort( + mSortedDescending.begin(), mSortedDescending.end(), + DepthSortDescendingLess(cam)); + } + } + + // Nothing needs to be done for pass groups, they auto-organise } //----------------------------------------------------------------------- void QueuedRenderableCollection::addRenderable(Pass* pass, Renderable* rend) - { - // ascending and descending sort both set bit 1 - if (mOrganisationMode & OM_SORT_DESCENDING) - { - mSortedDescending.push_back(RenderablePass(rend, pass)); - } - - if (mOrganisationMode & OM_PASS_GROUP) - { + { + // ascending and descending sort both set bit 1 + if (mOrganisationMode & OM_SORT_DESCENDING) + { + mSortedDescending.push_back(RenderablePass(rend, pass)); + } + + if (mOrganisationMode & OM_PASS_GROUP) + { PassGroupRenderableMap::iterator i = mGrouped.find(pass); if (i == mGrouped.end()) { std::pair retPair; // Create new pass entry, build a new list // Note that this pass and list are never destroyed until the - // engine shuts down, or a pass is destroyed or has it's hash - // recalculated, although the lists will be cleared + // engine shuts down, or a pass is destroyed or has it's hash + // recalculated, although the lists will be cleared retPair = mGrouped.insert( PassGroupRenderableMap::value_type( - pass, OGRE_NEW_T(RenderableList, MEMCATEGORY_SCENE_CONTROL)() )); + pass, OGRE_NEW_T(RenderableList, MEMCATEGORY_SCENE_CONTROL)() )); assert(retPair.second && - "Error inserting new pass entry into PassGroupRenderableMap"); + "Error inserting new pass entry into PassGroupRenderableMap"); i = retPair.first; } // Insert renderable i->second->push_back(rend); - - } - - } + + } + + } //----------------------------------------------------------------------- - void QueuedRenderableCollection::acceptVisitor( - QueuedRenderableVisitor* visitor, OrganisationMode om) const - { - if ((om & mOrganisationMode) == 0) - { - // try to fall back - if (OM_PASS_GROUP & mOrganisationMode) - om = OM_PASS_GROUP; - else if (OM_SORT_ASCENDING & mOrganisationMode) - om = OM_SORT_ASCENDING; - else if (OM_SORT_DESCENDING & mOrganisationMode) - om = OM_SORT_DESCENDING; - else - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Organisation mode requested in acceptVistor was not notified " - "to this class ahead of time, therefore may not be supported.", - "QueuedRenderableCollection::acceptVisitor"); - } - - switch(om) - { - case OM_PASS_GROUP: - acceptVisitorGrouped(visitor); - break; - case OM_SORT_DESCENDING: - acceptVisitorDescending(visitor); - break; - case OM_SORT_ASCENDING: - acceptVisitorAscending(visitor); - break; - } - - } + void QueuedRenderableCollection::acceptVisitor( + QueuedRenderableVisitor* visitor, OrganisationMode om) const + { + if ((om & mOrganisationMode) == 0) + { + // try to fall back + if (OM_PASS_GROUP & mOrganisationMode) + om = OM_PASS_GROUP; + else if (OM_SORT_ASCENDING & mOrganisationMode) + om = OM_SORT_ASCENDING; + else if (OM_SORT_DESCENDING & mOrganisationMode) + om = OM_SORT_DESCENDING; + else + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Organisation mode requested in acceptVistor was not notified " + "to this class ahead of time, therefore may not be supported.", + "QueuedRenderableCollection::acceptVisitor"); + } + + switch(om) + { + case OM_PASS_GROUP: + acceptVisitorGrouped(visitor); + break; + case OM_SORT_DESCENDING: + acceptVisitorDescending(visitor); + break; + case OM_SORT_ASCENDING: + acceptVisitorAscending(visitor); + break; + } + + } //----------------------------------------------------------------------- - void QueuedRenderableCollection::acceptVisitorGrouped( - QueuedRenderableVisitor* visitor) const - { - PassGroupRenderableMap::const_iterator ipass, ipassend; - ipassend = mGrouped.end(); - for (ipass = mGrouped.begin(); ipass != ipassend; ++ipass) - { - // Fast bypass if this group is now empty - if (ipass->second->empty()) continue; - - // Visit Pass - allow skip - if (!visitor->visit(ipass->first)) - continue; - - RenderableList* rendList = ipass->second; - RenderableList::const_iterator irend, irendend; - irendend = rendList->end(); - for (irend = rendList->begin(); irend != irendend; ++irend) - { - // Visit Renderable - visitor->visit(const_cast(*irend)); - } - } - - } + void QueuedRenderableCollection::acceptVisitorGrouped( + QueuedRenderableVisitor* visitor) const + { + PassGroupRenderableMap::const_iterator ipass, ipassend; + ipassend = mGrouped.end(); + for (ipass = mGrouped.begin(); ipass != ipassend; ++ipass) + { + // Fast bypass if this group is now empty + if (ipass->second->empty()) continue; + + // Visit Pass - allow skip + if (!visitor->visit(ipass->first)) + continue; + + RenderableList* rendList = ipass->second; + RenderableList::const_iterator irend, irendend; + irendend = rendList->end(); + for (irend = rendList->begin(); irend != irendend; ++irend) + { + // Visit Renderable + visitor->visit(const_cast(*irend)); + } + } + + } //----------------------------------------------------------------------- - void QueuedRenderableCollection::acceptVisitorDescending( - QueuedRenderableVisitor* visitor) const - { - // List is already in descending order, so iterate forward - RenderablePassList::const_iterator i, iend; - - iend = mSortedDescending.end(); - for (i = mSortedDescending.begin(); i != iend; ++i) - { - visitor->visit(const_cast(&(*i))); - } - } + void QueuedRenderableCollection::acceptVisitorDescending( + QueuedRenderableVisitor* visitor) const + { + // List is already in descending order, so iterate forward + RenderablePassList::const_iterator i, iend; + + iend = mSortedDescending.end(); + for (i = mSortedDescending.begin(); i != iend; ++i) + { + visitor->visit(const_cast(&(*i))); + } + } //----------------------------------------------------------------------- - void QueuedRenderableCollection::acceptVisitorAscending( - QueuedRenderableVisitor* visitor) const - { - // List is in descending order, so iterate in reverse - RenderablePassList::const_reverse_iterator i, iend; - - iend = mSortedDescending.rend(); - for (i = mSortedDescending.rbegin(); i != iend; ++i) - { - visitor->visit(const_cast(&(*i))); - } - - } + void QueuedRenderableCollection::acceptVisitorAscending( + QueuedRenderableVisitor* visitor) const + { + // List is in descending order, so iterate in reverse + RenderablePassList::const_reverse_iterator i, iend; + + iend = mSortedDescending.rend(); + for (i = mSortedDescending.rbegin(); i != iend; ++i) + { + visitor->visit(const_cast(&(*i))); + } + + } //----------------------------------------------------------------------- - void QueuedRenderableCollection::merge( const QueuedRenderableCollection& rhs ) - { - mSortedDescending.insert( mSortedDescending.end(), rhs.mSortedDescending.begin(), rhs.mSortedDescending.end() ); + void QueuedRenderableCollection::merge( const QueuedRenderableCollection& rhs ) + { + mSortedDescending.insert( mSortedDescending.end(), rhs.mSortedDescending.begin(), rhs.mSortedDescending.end() ); - PassGroupRenderableMap::const_iterator srcGroup; - for( srcGroup = rhs.mGrouped.begin(); srcGroup != rhs.mGrouped.end(); ++srcGroup ) - { + PassGroupRenderableMap::const_iterator srcGroup; + for( srcGroup = rhs.mGrouped.begin(); srcGroup != rhs.mGrouped.end(); ++srcGroup ) + { PassGroupRenderableMap::iterator dstGroup = mGrouped.find( srcGroup->first ); if (dstGroup == mGrouped.end()) { std::pair retPair; // Create new pass entry, build a new list // Note that this pass and list are never destroyed until the - // engine shuts down, or a pass is destroyed or has it's hash - // recalculated, although the lists will be cleared + // engine shuts down, or a pass is destroyed or has it's hash + // recalculated, although the lists will be cleared retPair = mGrouped.insert( PassGroupRenderableMap::value_type( - srcGroup->first, OGRE_NEW_T(RenderableList, MEMCATEGORY_SCENE_CONTROL)() )); + srcGroup->first, OGRE_NEW_T(RenderableList, MEMCATEGORY_SCENE_CONTROL)() )); assert(retPair.second && - "Error inserting new pass entry into PassGroupRenderableMap"); + "Error inserting new pass entry into PassGroupRenderableMap"); dstGroup = retPair.first; } - // Insert renderable + // Insert renderable dstGroup->second->insert( dstGroup->second->end(), srcGroup->second->begin(), srcGroup->second->end() ); - } - } + } + } } diff --git a/OgreMain/src/OgreRenderSystem.cpp b/OgreMain/src/OgreRenderSystem.cpp index edee35d910d..f902bee8f81 100644 --- a/OgreMain/src/OgreRenderSystem.cpp +++ b/OgreMain/src/OgreRenderSystem.cpp @@ -55,34 +55,34 @@ namespace Ogre { // This means CULL clockwise vertices, i.e. front of poly is counter-clockwise // This makes it the same as OpenGL and other right-handed systems , mCullingMode(CULL_CLOCKWISE) - , mWBuffer(false) + , mWBuffer(false) , mBatchCount(0) , mFaceCount(0) , mVertexCount(0) , mInvertVertexWinding(false) , mDisabledTexUnitsFrom(0) , mCurrentPassIterationCount(0) - , mCurrentPassIterationNum(0) - , mDerivedDepthBias(false) - , mDerivedDepthBiasBase(0.0f) - , mDerivedDepthBiasMultiplier(0.0f) + , mCurrentPassIterationNum(0) + , mDerivedDepthBias(false) + , mDerivedDepthBiasBase(0.0f) + , mDerivedDepthBiasMultiplier(0.0f) , mDerivedDepthBiasSlopeScale(0.0f) , mGlobalInstanceVertexBufferVertexDeclaration(NULL) , mGlobalNumberOfInstances(1) - , mEnableFixedPipeline(true) + , mEnableFixedPipeline(true) , mVertexProgramBound(false) - , mGeometryProgramBound(false) + , mGeometryProgramBound(false) , mFragmentProgramBound(false) - , mTessellationHullProgramBound(false) - , mTessellationDomainProgramBound(false) - , mComputeProgramBound(false) - , mClipPlanesDirty(true) - , mRealCapabilities(0) - , mCurrentCapabilities(0) - , mUseCustomCapabilities(false) + , mTessellationHullProgramBound(false) + , mTessellationDomainProgramBound(false) + , mComputeProgramBound(false) + , mClipPlanesDirty(true) + , mRealCapabilities(0) + , mCurrentCapabilities(0) + , mUseCustomCapabilities(false) , mNativeShadingLanguageVersion(0) - , mTexProjRelative(false) - , mTexProjRelativeOrigin(Vector3::ZERO) + , mTexProjRelative(false) + , mTexProjRelativeOrigin(Vector3::ZERO) { mEventNames.push_back("RenderSystemCapabilitiesCreated"); } @@ -91,10 +91,10 @@ namespace Ogre { RenderSystem::~RenderSystem() { shutdown(); - OGRE_DELETE mRealCapabilities; - mRealCapabilities = 0; - // Current capabilities managed externally - mCurrentCapabilities = 0; + OGRE_DELETE mRealCapabilities; + mRealCapabilities = 0; + // Current capabilities managed externally + mCurrentCapabilities = 0; } //----------------------------------------------------------------------- void RenderSystem::_initRenderTargets(void) @@ -115,37 +115,37 @@ namespace Ogre { { // Update all in order of priority // This ensures render-to-texture targets get updated before render windows - RenderTargetPriorityMap::iterator itarg, itargend; - itargend = mPrioritisedRenderTargets.end(); - for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg ) - { - if( itarg->second->isActive() && itarg->second->isAutoUpdated()) - itarg->second->update(swapBuffers); - } + RenderTargetPriorityMap::iterator itarg, itargend; + itargend = mPrioritisedRenderTargets.end(); + for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg ) + { + if( itarg->second->isActive() && itarg->second->isAutoUpdated()) + itarg->second->update(swapBuffers); + } } //----------------------------------------------------------------------- void RenderSystem::_swapAllRenderTargetBuffers() { // Update all in order of priority // This ensures render-to-texture targets get updated before render windows - RenderTargetPriorityMap::iterator itarg, itargend; - itargend = mPrioritisedRenderTargets.end(); - for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg ) - { - if( itarg->second->isActive() && itarg->second->isAutoUpdated()) - itarg->second->swapBuffers(); - } + RenderTargetPriorityMap::iterator itarg, itargend; + itargend = mPrioritisedRenderTargets.end(); + for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg ) + { + if( itarg->second->isActive() && itarg->second->isAutoUpdated()) + itarg->second->swapBuffers(); + } } //----------------------------------------------------------------------- RenderWindow* RenderSystem::_initialise(bool autoCreateWindow, const String& windowTitle) { // Have I been registered by call to Root::setRenderSystem? - /** Don't do this anymore, just allow via Root + /** Don't do this anymore, just allow via Root RenderSystem* regPtr = Root::getSingleton().getRenderSystem(); if (!regPtr || regPtr != this) // Register self - library user has come to me direct Root::getSingleton().setRenderSystem(this); - */ + */ // Subclasses should take it from here @@ -153,18 +153,18 @@ namespace Ogre { // their own initialise() implementations. mVertexProgramBound = false; - mGeometryProgramBound = false; + mGeometryProgramBound = false; mFragmentProgramBound = false; - mTessellationHullProgramBound = false; - mTessellationDomainProgramBound = false; - mComputeProgramBound = false; + mTessellationHullProgramBound = false; + mTessellationDomainProgramBound = false; + mComputeProgramBound = false; return 0; } - //--------------------------------------------------------------------------------------------- - void RenderSystem::useCustomRenderSystemCapabilities(RenderSystemCapabilities* capabilities) - { + //--------------------------------------------------------------------------------------------- + void RenderSystem::useCustomRenderSystemCapabilities(RenderSystemCapabilities* capabilities) + { if (mRealCapabilities != 0) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, @@ -172,67 +172,67 @@ namespace Ogre { "RenderSystem::useCustomRenderSystemCapabilities"); } - mCurrentCapabilities = capabilities; - mUseCustomCapabilities = true; - } - - //--------------------------------------------------------------------------------------------- - bool RenderSystem::_createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, - RenderWindowList& createdWindows) - { - unsigned int fullscreenWindowsCount = 0; - - // Grab some information and avoid duplicate render windows. - for (unsigned int nWindow=0; nWindow < renderWindowDescriptions.size(); ++nWindow) - { - const RenderWindowDescription* curDesc = &renderWindowDescriptions[nWindow]; - - // Count full screen windows. - if (curDesc->useFullScreen) - fullscreenWindowsCount++; - - bool renderWindowFound = false; - - if (mRenderTargets.find(curDesc->name) != mRenderTargets.end()) - renderWindowFound = true; - else - { - for (unsigned int nSecWindow = nWindow + 1 ; nSecWindow < renderWindowDescriptions.size(); ++nSecWindow) - { - if (curDesc->name == renderWindowDescriptions[nSecWindow].name) - { - renderWindowFound = true; - break; - } - } - } - - // Make sure we don't already have a render target of the - // same name as the one supplied - if(renderWindowFound) - { - String msg; - - msg = "A render target of the same name '" + String(curDesc->name) + "' already " - "exists. You cannot create a new window with this name."; - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, msg, "RenderSystem::createRenderWindow" ); - } - } - - // Case we have to create some full screen rendering windows. - if (fullscreenWindowsCount > 0) - { - // Can not mix full screen and windowed rendering windows. - if (fullscreenWindowsCount != renderWindowDescriptions.size()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Can not create mix of full screen and windowed rendering windows", - "RenderSystem::createRenderWindows"); - } - } - - return true; - } + mCurrentCapabilities = capabilities; + mUseCustomCapabilities = true; + } + + //--------------------------------------------------------------------------------------------- + bool RenderSystem::_createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, + RenderWindowList& createdWindows) + { + unsigned int fullscreenWindowsCount = 0; + + // Grab some information and avoid duplicate render windows. + for (unsigned int nWindow=0; nWindow < renderWindowDescriptions.size(); ++nWindow) + { + const RenderWindowDescription* curDesc = &renderWindowDescriptions[nWindow]; + + // Count full screen windows. + if (curDesc->useFullScreen) + fullscreenWindowsCount++; + + bool renderWindowFound = false; + + if (mRenderTargets.find(curDesc->name) != mRenderTargets.end()) + renderWindowFound = true; + else + { + for (unsigned int nSecWindow = nWindow + 1 ; nSecWindow < renderWindowDescriptions.size(); ++nSecWindow) + { + if (curDesc->name == renderWindowDescriptions[nSecWindow].name) + { + renderWindowFound = true; + break; + } + } + } + + // Make sure we don't already have a render target of the + // same name as the one supplied + if(renderWindowFound) + { + String msg; + + msg = "A render target of the same name '" + String(curDesc->name) + "' already " + "exists. You cannot create a new window with this name."; + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, msg, "RenderSystem::createRenderWindow" ); + } + } + + // Case we have to create some full screen rendering windows. + if (fullscreenWindowsCount > 0) + { + // Can not mix full screen and windowed rendering windows. + if (fullscreenWindowsCount != renderWindowDescriptions.size()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Can not create mix of full screen and windowed rendering windows", + "RenderSystem::createRenderWindows"); + } + } + + return true; + } //--------------------------------------------------------------------------------------------- void RenderSystem::destroyRenderWindow(const String& name) @@ -253,7 +253,7 @@ namespace Ogre { //--------------------------------------------------------------------------------------------- void RenderSystem::attachRenderTarget( RenderTarget &target ) { - assert( target.getPriority() < OGRE_NUM_RENDERTARGET_GROUPS ); + assert( target.getPriority() < OGRE_NUM_RENDERTARGET_GROUPS ); mRenderTargets.insert( RenderTargetMap::value_type( target.getName(), &target ) ); mPrioritisedRenderTargets.insert( @@ -283,16 +283,16 @@ namespace Ogre { if( it != mRenderTargets.end() ) { ret = it->second; - - /* Remove the render target from the priority groups. */ + + /* Remove the render target from the priority groups. */ RenderTargetPriorityMap::iterator itarg, itargend; itargend = mPrioritisedRenderTargets.end(); - for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg ) + for( itarg = mPrioritisedRenderTargets.begin(); itarg != itargend; ++itarg ) { - if( itarg->second == ret ) { - mPrioritisedRenderTargets.erase( itarg ); - break; - } + if( itarg->second == ret ) { + mPrioritisedRenderTargets.erase( itarg ); + break; + } } mRenderTargets.erase( it ); @@ -315,121 +315,121 @@ namespace Ogre { // The method _disableTextureUnit is called to turn a unit off const TexturePtr& tex = tl._getTexturePtr(); - bool isValidBinding = false; - - if (mCurrentCapabilities->hasCapability(RSC_COMPLETE_TEXTURE_BINDING)) - _setBindingType(tl.getBindingType()); - - // Vertex texture binding? - if (mCurrentCapabilities->hasCapability(RSC_VERTEX_TEXTURE_FETCH) && - !mCurrentCapabilities->getVertexTextureUnitsShared()) - { - isValidBinding = true; - if (tl.getBindingType() == TextureUnitState::BT_VERTEX) - { - // Bind vertex texture - _setVertexTexture(texUnit, tex); - // bind nothing to fragment unit (hardware isn't shared but fragment - // unit can't be using the same index - _setTexture(texUnit, true, sNullTexPtr); - } - else - { - // vice versa - _setVertexTexture(texUnit, sNullTexPtr); - _setTexture(texUnit, true, tex); - } - } - - if (mCurrentCapabilities->hasCapability(RSC_GEOMETRY_PROGRAM)) - { - isValidBinding = true; - if (tl.getBindingType() == TextureUnitState::BT_GEOMETRY) - { - // Bind vertex texture - _setGeometryTexture(texUnit, tex); - // bind nothing to fragment unit (hardware isn't shared but fragment - // unit can't be using the same index - _setTexture(texUnit, true, sNullTexPtr); - } - else - { - // vice versa - _setGeometryTexture(texUnit, sNullTexPtr); - _setTexture(texUnit, true, tex); - } - } - - if (mCurrentCapabilities->hasCapability(RSC_COMPUTE_PROGRAM)) - { - isValidBinding = true; - if (tl.getBindingType() == TextureUnitState::BT_COMPUTE) - { - // Bind vertex texture - _setComputeTexture(texUnit, tex); - // bind nothing to fragment unit (hardware isn't shared but fragment - // unit can't be using the same index - _setTexture(texUnit, true, sNullTexPtr); - } - else - { - // vice versa - _setComputeTexture(texUnit, sNullTexPtr); - _setTexture(texUnit, true, tex); - } - } - - if (mCurrentCapabilities->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) - { - isValidBinding = true; - if (tl.getBindingType() == TextureUnitState::BT_TESSELLATION_DOMAIN) - { - // Bind vertex texture - _setTesselationDomainTexture(texUnit, tex); - // bind nothing to fragment unit (hardware isn't shared but fragment - // unit can't be using the same index - _setTexture(texUnit, true, sNullTexPtr); - } - else - { - // vice versa - _setTesselationDomainTexture(texUnit, sNullTexPtr); - _setTexture(texUnit, true, tex); - } - } - - if (mCurrentCapabilities->hasCapability(RSC_TESSELLATION_HULL_PROGRAM)) - { - isValidBinding = true; - if (tl.getBindingType() == TextureUnitState::BT_TESSELLATION_HULL) - { - // Bind vertex texture - _setTesselationHullTexture(texUnit, tex); - // bind nothing to fragment unit (hardware isn't shared but fragment - // unit can't be using the same index - _setTexture(texUnit, true, sNullTexPtr); - } - else - { - // vice versa - _setTesselationHullTexture(texUnit, sNullTexPtr); - _setTexture(texUnit, true, tex); - } - } - - if (!isValidBinding) - { - // Shared vertex / fragment textures or no vertex texture support - // Bind texture (may be blank) - _setTexture(texUnit, true, tex); - } + bool isValidBinding = false; + + if (mCurrentCapabilities->hasCapability(RSC_COMPLETE_TEXTURE_BINDING)) + _setBindingType(tl.getBindingType()); + + // Vertex texture binding? + if (mCurrentCapabilities->hasCapability(RSC_VERTEX_TEXTURE_FETCH) && + !mCurrentCapabilities->getVertexTextureUnitsShared()) + { + isValidBinding = true; + if (tl.getBindingType() == TextureUnitState::BT_VERTEX) + { + // Bind vertex texture + _setVertexTexture(texUnit, tex); + // bind nothing to fragment unit (hardware isn't shared but fragment + // unit can't be using the same index + _setTexture(texUnit, true, sNullTexPtr); + } + else + { + // vice versa + _setVertexTexture(texUnit, sNullTexPtr); + _setTexture(texUnit, true, tex); + } + } + + if (mCurrentCapabilities->hasCapability(RSC_GEOMETRY_PROGRAM)) + { + isValidBinding = true; + if (tl.getBindingType() == TextureUnitState::BT_GEOMETRY) + { + // Bind vertex texture + _setGeometryTexture(texUnit, tex); + // bind nothing to fragment unit (hardware isn't shared but fragment + // unit can't be using the same index + _setTexture(texUnit, true, sNullTexPtr); + } + else + { + // vice versa + _setGeometryTexture(texUnit, sNullTexPtr); + _setTexture(texUnit, true, tex); + } + } + + if (mCurrentCapabilities->hasCapability(RSC_COMPUTE_PROGRAM)) + { + isValidBinding = true; + if (tl.getBindingType() == TextureUnitState::BT_COMPUTE) + { + // Bind vertex texture + _setComputeTexture(texUnit, tex); + // bind nothing to fragment unit (hardware isn't shared but fragment + // unit can't be using the same index + _setTexture(texUnit, true, sNullTexPtr); + } + else + { + // vice versa + _setComputeTexture(texUnit, sNullTexPtr); + _setTexture(texUnit, true, tex); + } + } + + if (mCurrentCapabilities->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) + { + isValidBinding = true; + if (tl.getBindingType() == TextureUnitState::BT_TESSELLATION_DOMAIN) + { + // Bind vertex texture + _setTesselationDomainTexture(texUnit, tex); + // bind nothing to fragment unit (hardware isn't shared but fragment + // unit can't be using the same index + _setTexture(texUnit, true, sNullTexPtr); + } + else + { + // vice versa + _setTesselationDomainTexture(texUnit, sNullTexPtr); + _setTexture(texUnit, true, tex); + } + } + + if (mCurrentCapabilities->hasCapability(RSC_TESSELLATION_HULL_PROGRAM)) + { + isValidBinding = true; + if (tl.getBindingType() == TextureUnitState::BT_TESSELLATION_HULL) + { + // Bind vertex texture + _setTesselationHullTexture(texUnit, tex); + // bind nothing to fragment unit (hardware isn't shared but fragment + // unit can't be using the same index + _setTexture(texUnit, true, sNullTexPtr); + } + else + { + // vice versa + _setTesselationHullTexture(texUnit, sNullTexPtr); + _setTexture(texUnit, true, tex); + } + } + + if (!isValidBinding) + { + // Shared vertex / fragment textures or no vertex texture support + // Bind texture (may be blank) + _setTexture(texUnit, true, tex); + } // Set texture coordinate set _setTextureCoordSet(texUnit, tl.getTextureCoordSet()); - //Set texture layer compare state and function - _setTextureUnitCompareEnabled(texUnit,tl.getTextureCompareEnabled()); - _setTextureUnitCompareFunction(texUnit,tl.getTextureCompareFunction()); + //Set texture layer compare state and function + _setTextureUnitCompareEnabled(texUnit,tl.getTextureCompareEnabled()); + _setTextureUnitCompareFunction(texUnit,tl.getTextureCompareFunction()); // Set texture layer filtering @@ -441,11 +441,11 @@ namespace Ogre { // Set texture layer filtering _setTextureLayerAnisotropy(texUnit, tl.getTextureAnisotropy()); - // Set mipmap biasing - _setTextureMipmapBias(texUnit, tl.getTextureMipmapBias()); + // Set mipmap biasing + _setTextureMipmapBias(texUnit, tl.getTextureMipmapBias()); - // Set blend modes - // Note, colour before alpha is important + // Set blend modes + // Note, colour before alpha is important _setTextureBlendMode(texUnit, tl.getColourBlendMode()); _setTextureBlendMode(texUnit, tl.getAlphaBlendMode()); @@ -492,8 +492,8 @@ namespace Ogre { } break; case TextureUnitState::ET_UVSCROLL: - case TextureUnitState::ET_USCROLL: - case TextureUnitState::ET_VSCROLL: + case TextureUnitState::ET_USCROLL: + case TextureUnitState::ET_VSCROLL: case TextureUnitState::ET_ROTATE: case TextureUnitState::ET_TRANSFORM: break; @@ -516,65 +516,65 @@ namespace Ogre { } //----------------------------------------------------------------------- - void RenderSystem::_setTexture(size_t unit, bool enabled, - const String &texname) - { - TexturePtr t = TextureManager::getSingleton().getByName(texname); - _setTexture(unit, enabled, t); - } - //----------------------------------------------------------------------- - void RenderSystem::_setBindingType(TextureUnitState::BindingType bindingType) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This rendersystem does not support binding texture to other shaders then fragment", - "RenderSystem::_setBindingType"); - } - //----------------------------------------------------------------------- - void RenderSystem::_setVertexTexture(size_t unit, const TexturePtr& tex) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This rendersystem does not support separate vertex texture samplers, " - "you should use the regular texture samplers which are shared between " - "the vertex and fragment units.", - "RenderSystem::_setVertexTexture"); - } - //----------------------------------------------------------------------- - void RenderSystem::_setGeometryTexture(size_t unit, const TexturePtr& tex) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This rendersystem does not support separate geometry texture samplers, " - "you should use the regular texture samplers which are shared between " - "the vertex and fragment units.", - "RenderSystem::_setGeometryTexture"); - } - //----------------------------------------------------------------------- - void RenderSystem::_setComputeTexture(size_t unit, const TexturePtr& tex) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This rendersystem does not support separate compute texture samplers, " - "you should use the regular texture samplers which are shared between " - "the vertex and fragment units.", - "RenderSystem::_setComputeTexture"); - } - //----------------------------------------------------------------------- - void RenderSystem::_setTesselationHullTexture(size_t unit, const TexturePtr& tex) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This rendersystem does not support separate tesselation hull texture samplers, " - "you should use the regular texture samplers which are shared between " - "the vertex and fragment units.", - "RenderSystem::_setTesselationHullTexture"); - } - //----------------------------------------------------------------------- - void RenderSystem::_setTesselationDomainTexture(size_t unit, const TexturePtr& tex) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This rendersystem does not support separate tesselation domain texture samplers, " - "you should use the regular texture samplers which are shared between " - "the vertex and fragment units.", - "RenderSystem::_setTesselationDomainTexture"); - } - //----------------------------------------------------------------------- + void RenderSystem::_setTexture(size_t unit, bool enabled, + const String &texname) + { + TexturePtr t = TextureManager::getSingleton().getByName(texname); + _setTexture(unit, enabled, t); + } + //----------------------------------------------------------------------- + void RenderSystem::_setBindingType(TextureUnitState::BindingType bindingType) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This rendersystem does not support binding texture to other shaders then fragment", + "RenderSystem::_setBindingType"); + } + //----------------------------------------------------------------------- + void RenderSystem::_setVertexTexture(size_t unit, const TexturePtr& tex) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This rendersystem does not support separate vertex texture samplers, " + "you should use the regular texture samplers which are shared between " + "the vertex and fragment units.", + "RenderSystem::_setVertexTexture"); + } + //----------------------------------------------------------------------- + void RenderSystem::_setGeometryTexture(size_t unit, const TexturePtr& tex) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This rendersystem does not support separate geometry texture samplers, " + "you should use the regular texture samplers which are shared between " + "the vertex and fragment units.", + "RenderSystem::_setGeometryTexture"); + } + //----------------------------------------------------------------------- + void RenderSystem::_setComputeTexture(size_t unit, const TexturePtr& tex) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This rendersystem does not support separate compute texture samplers, " + "you should use the regular texture samplers which are shared between " + "the vertex and fragment units.", + "RenderSystem::_setComputeTexture"); + } + //----------------------------------------------------------------------- + void RenderSystem::_setTesselationHullTexture(size_t unit, const TexturePtr& tex) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This rendersystem does not support separate tesselation hull texture samplers, " + "you should use the regular texture samplers which are shared between " + "the vertex and fragment units.", + "RenderSystem::_setTesselationHullTexture"); + } + //----------------------------------------------------------------------- + void RenderSystem::_setTesselationDomainTexture(size_t unit, const TexturePtr& tex) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This rendersystem does not support separate tesselation domain texture samplers, " + "you should use the regular texture samplers which are shared between " + "the vertex and fragment units.", + "RenderSystem::_setTesselationDomainTexture"); + } + //----------------------------------------------------------------------- void RenderSystem::_disableTextureUnit(size_t texUnit) { _setTexture(texUnit, false, sNullTexPtr); @@ -599,31 +599,31 @@ namespace Ogre { _setTextureUnitFiltering(unit, FT_MAG, magFilter); _setTextureUnitFiltering(unit, FT_MIP, mipFilter); } - //--------------------------------------------------------------------- - void RenderSystem::_cleanupDepthBuffers( bool bCleanManualBuffers ) - { - DepthBufferMap::iterator itMap = mDepthBufferPool.begin(); - DepthBufferMap::iterator enMap = mDepthBufferPool.end(); + //--------------------------------------------------------------------- + void RenderSystem::_cleanupDepthBuffers( bool bCleanManualBuffers ) + { + DepthBufferMap::iterator itMap = mDepthBufferPool.begin(); + DepthBufferMap::iterator enMap = mDepthBufferPool.end(); - while( itMap != enMap ) - { - DepthBufferVec::const_iterator itor = itMap->second.begin(); - DepthBufferVec::const_iterator end = itMap->second.end(); + while( itMap != enMap ) + { + DepthBufferVec::const_iterator itor = itMap->second.begin(); + DepthBufferVec::const_iterator end = itMap->second.end(); - while( itor != end ) - { - if( bCleanManualBuffers || !(*itor)->isManual() ) - delete *itor; - ++itor; - } + while( itor != end ) + { + if( bCleanManualBuffers || !(*itor)->isManual() ) + delete *itor; + ++itor; + } - itMap->second.clear(); + itMap->second.clear(); - ++itMap; - } + ++itMap; + } - mDepthBufferPool.clear(); - } + mDepthBufferPool.clear(); + } //----------------------------------------------------------------------- CullingMode RenderSystem::_getCullingMode(void) const { @@ -640,40 +640,40 @@ namespace Ogre { mEnableFixedPipeline = enabled; } //----------------------------------------------------------------------- - void RenderSystem::setDepthBufferFor( RenderTarget *renderTarget ) - { - uint16 poolId = renderTarget->getDepthBufferPool(); - if( poolId == DepthBuffer::POOL_NO_DEPTH ) - return; //RenderTarget explicitly requested no depth buffer - - //Find a depth buffer in the pool - DepthBufferVec::const_iterator itor = mDepthBufferPool[poolId].begin(); - DepthBufferVec::const_iterator end = mDepthBufferPool[poolId].end(); - - bool bAttached = false; - while( itor != end && !bAttached ) - bAttached = renderTarget->attachDepthBuffer( *itor++ ); - - //Not found yet? Create a new one! - if( !bAttached ) - { - DepthBuffer *newDepthBuffer = _createDepthBufferFor( renderTarget ); - - if( newDepthBuffer ) - { - newDepthBuffer->_setPoolId( poolId ); - mDepthBufferPool[poolId].push_back( newDepthBuffer ); - - bAttached = renderTarget->attachDepthBuffer( newDepthBuffer ); - - assert( bAttached && "A new DepthBuffer for a RenderTarget was created, but after creation" - "it says it's incompatible with that RT" ); - } - else - LogManager::getSingleton().logMessage( "WARNING: Couldn't create a suited DepthBuffer" - "for RT: " + renderTarget->getName() , LML_CRITICAL); - } - } + void RenderSystem::setDepthBufferFor( RenderTarget *renderTarget ) + { + uint16 poolId = renderTarget->getDepthBufferPool(); + if( poolId == DepthBuffer::POOL_NO_DEPTH ) + return; //RenderTarget explicitly requested no depth buffer + + //Find a depth buffer in the pool + DepthBufferVec::const_iterator itor = mDepthBufferPool[poolId].begin(); + DepthBufferVec::const_iterator end = mDepthBufferPool[poolId].end(); + + bool bAttached = false; + while( itor != end && !bAttached ) + bAttached = renderTarget->attachDepthBuffer( *itor++ ); + + //Not found yet? Create a new one! + if( !bAttached ) + { + DepthBuffer *newDepthBuffer = _createDepthBufferFor( renderTarget ); + + if( newDepthBuffer ) + { + newDepthBuffer->_setPoolId( poolId ); + mDepthBufferPool[poolId].push_back( newDepthBuffer ); + + bAttached = renderTarget->attachDepthBuffer( newDepthBuffer ); + + assert( bAttached && "A new DepthBuffer for a RenderTarget was created, but after creation" + "it says it's incompatible with that RT" ); + } + else + LogManager::getSingleton().logMessage( "WARNING: Couldn't create a suited DepthBuffer" + "for RT: " + renderTarget->getName() , LML_CRITICAL); + } + } bool RenderSystem::getWBufferEnabled(void) const { return mWBuffer; @@ -686,30 +686,30 @@ namespace Ogre { //----------------------------------------------------------------------- void RenderSystem::shutdown(void) { - // Remove occlusion queries - for (HardwareOcclusionQueryList::iterator i = mHwOcclusionQueries.begin(); - i != mHwOcclusionQueries.end(); ++i) - { - OGRE_DELETE *i; - } - mHwOcclusionQueries.clear(); + // Remove occlusion queries + for (HardwareOcclusionQueryList::iterator i = mHwOcclusionQueries.begin(); + i != mHwOcclusionQueries.end(); ++i) + { + OGRE_DELETE *i; + } + mHwOcclusionQueries.clear(); - _cleanupDepthBuffers(); + _cleanupDepthBuffers(); // Remove all the render targets. - // (destroy primary target last since others may depend on it) - RenderTarget* primary = 0; - for (RenderTargetMap::iterator it = mRenderTargets.begin(); it != mRenderTargets.end(); ++it) - { - if (!primary && it->second->isPrimary()) - primary = it->second; - else - OGRE_DELETE it->second; - } - OGRE_DELETE primary; - mRenderTargets.clear(); - - mPrioritisedRenderTargets.clear(); + // (destroy primary target last since others may depend on it) + RenderTarget* primary = 0; + for (RenderTargetMap::iterator it = mRenderTargets.begin(); it != mRenderTargets.end(); ++it) + { + if (!primary && it->second->isPrimary()) + primary = it->second; + else + OGRE_DELETE it->second; + } + OGRE_DELETE primary; + mRenderTargets.clear(); + + mPrioritisedRenderTargets.clear(); } //----------------------------------------------------------------------- void RenderSystem::_beginGeometryCount(void) @@ -733,16 +733,16 @@ namespace Ogre { return static_cast< unsigned int >( mVertexCount ); } //----------------------------------------------------------------------- - void RenderSystem::convertColourValue(const ColourValue& colour, uint32* pDest) - { - *pDest = VertexElement::convertColourValue(colour, getColourVertexElementType()); + void RenderSystem::convertColourValue(const ColourValue& colour, uint32* pDest) + { + *pDest = VertexElement::convertColourValue(colour, getColourVertexElementType()); - } + } //----------------------------------------------------------------------- void RenderSystem::_setWorldMatrices(const Matrix4* m, unsigned short count) { // Do nothing with these matrices here, it never used for now, - // derived class should take care with them if required. + // derived class should take care with them if required. // Set hardware matrix to nothing _setWorldMatrix(Matrix4::IDENTITY); @@ -758,26 +758,26 @@ namespace Ogre { else val = op.vertexData->vertexCount; - size_t trueInstanceNum = std::max(op.numberOfInstances,1); - val *= trueInstanceNum; + size_t trueInstanceNum = std::max(op.numberOfInstances,1); + val *= trueInstanceNum; // account for a pass having multiple iterations if (mCurrentPassIterationCount > 1) val *= mCurrentPassIterationCount; - mCurrentPassIterationNum = 0; + mCurrentPassIterationNum = 0; switch(op.operationType) { - case RenderOperation::OT_TRIANGLE_LIST: + case RenderOperation::OT_TRIANGLE_LIST: mFaceCount += (val / 3); break; case RenderOperation::OT_TRIANGLE_STRIP: case RenderOperation::OT_TRIANGLE_FAN: mFaceCount += (val - 2); break; - case RenderOperation::OT_POINT_LIST: - case RenderOperation::OT_LINE_LIST: - case RenderOperation::OT_LINE_STRIP: + case RenderOperation::OT_POINT_LIST: + case RenderOperation::OT_LINE_LIST: + case RenderOperation::OT_LINE_STRIP: case RenderOperation::OT_PATCH_1_CONTROL_POINT: case RenderOperation::OT_PATCH_2_CONTROL_POINT: case RenderOperation::OT_PATCH_3_CONTROL_POINT: @@ -810,66 +810,66 @@ namespace Ogre { case RenderOperation::OT_PATCH_30_CONTROL_POINT: case RenderOperation::OT_PATCH_31_CONTROL_POINT: case RenderOperation::OT_PATCH_32_CONTROL_POINT: - break; - } + break; + } - mVertexCount += op.vertexData->vertexCount * trueInstanceNum; + mVertexCount += op.vertexData->vertexCount * trueInstanceNum; mBatchCount += mCurrentPassIterationCount; - // sort out clip planes - // have to do it here in case of matrix issues - if (mClipPlanesDirty) - { - setClipPlanesImpl(mClipPlanes); - mClipPlanesDirty = false; - } - } - void RenderSystem::_renderUsingReadBackAsTexture(unsigned int secondPass,Ogre::String variableName,unsigned int StartSlot) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This rendersystem does not support reading back the inactive depth/stencil \ + // sort out clip planes + // have to do it here in case of matrix issues + if (mClipPlanesDirty) + { + setClipPlanesImpl(mClipPlanes); + mClipPlanesDirty = false; + } + } + void RenderSystem::_renderUsingReadBackAsTexture(unsigned int secondPass,Ogre::String variableName,unsigned int StartSlot) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This rendersystem does not support reading back the inactive depth/stencil \ buffer as a texture. Only DirectX 11 Render System supports it.", - "RenderSystem::_renderUsingReadBackAsTexture"); - } + "RenderSystem::_renderUsingReadBackAsTexture"); + } //----------------------------------------------------------------------- void RenderSystem::setInvertVertexWinding(bool invert) { mInvertVertexWinding = invert; } - //----------------------------------------------------------------------- - bool RenderSystem::getInvertVertexWinding(void) const - { - return mInvertVertexWinding; - } - //--------------------------------------------------------------------- - void RenderSystem::addClipPlane (const Plane &p) - { - mClipPlanes.push_back(p); - mClipPlanesDirty = true; - } - //--------------------------------------------------------------------- - void RenderSystem::addClipPlane (Real A, Real B, Real C, Real D) - { - addClipPlane(Plane(A, B, C, D)); - } - //--------------------------------------------------------------------- - void RenderSystem::setClipPlanes(const PlaneList& clipPlanes) - { - if (clipPlanes != mClipPlanes) - { - mClipPlanes = clipPlanes; - mClipPlanesDirty = true; - } - } - //--------------------------------------------------------------------- - void RenderSystem::resetClipPlanes() - { - if (!mClipPlanes.empty()) - { - mClipPlanes.clear(); - mClipPlanesDirty = true; - } - } + //----------------------------------------------------------------------- + bool RenderSystem::getInvertVertexWinding(void) const + { + return mInvertVertexWinding; + } + //--------------------------------------------------------------------- + void RenderSystem::addClipPlane (const Plane &p) + { + mClipPlanes.push_back(p); + mClipPlanesDirty = true; + } + //--------------------------------------------------------------------- + void RenderSystem::addClipPlane (Real A, Real B, Real C, Real D) + { + addClipPlane(Plane(A, B, C, D)); + } + //--------------------------------------------------------------------- + void RenderSystem::setClipPlanes(const PlaneList& clipPlanes) + { + if (clipPlanes != mClipPlanes) + { + mClipPlanes = clipPlanes; + mClipPlanesDirty = true; + } + } + //--------------------------------------------------------------------- + void RenderSystem::resetClipPlanes() + { + if (!mClipPlanes.empty()) + { + mClipPlanes.clear(); + mClipPlanesDirty = true; + } + } //----------------------------------------------------------------------- void RenderSystem::_notifyCameraRemoved(const Camera* cam) { @@ -882,14 +882,14 @@ namespace Ogre { } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- bool RenderSystem::updatePassIterationRenderState(void) { if (mCurrentPassIterationCount <= 1) return false; --mCurrentPassIterationCount; - ++mCurrentPassIterationNum; + ++mCurrentPassIterationNum; if (!mActiveVertexGpuProgramParameters.isNull()) { mActiveVertexGpuProgramParameters->incPassIterationNumber(); @@ -905,17 +905,17 @@ namespace Ogre { mActiveFragmentGpuProgramParameters->incPassIterationNumber(); bindGpuProgramPassIterationParameters(GPT_FRAGMENT_PROGRAM); } - if (!mActiveTessellationHullGpuProgramParameters.isNull()) + if (!mActiveTessellationHullGpuProgramParameters.isNull()) { mActiveTessellationHullGpuProgramParameters->incPassIterationNumber(); - bindGpuProgramPassIterationParameters(GPT_HULL_PROGRAM); + bindGpuProgramPassIterationParameters(GPT_HULL_PROGRAM); } - if (!mActiveTessellationDomainGpuProgramParameters.isNull()) + if (!mActiveTessellationDomainGpuProgramParameters.isNull()) { mActiveTessellationDomainGpuProgramParameters->incPassIterationNumber(); - bindGpuProgramPassIterationParameters(GPT_DOMAIN_PROGRAM); + bindGpuProgramPassIterationParameters(GPT_DOMAIN_PROGRAM); } - if (!mActiveComputeGpuProgramParameters.isNull()) + if (!mActiveComputeGpuProgramParameters.isNull()) { mActiveComputeGpuProgramParameters->incPassIterationNumber(); bindGpuProgramPassIterationParameters(GPT_COMPUTE_PROGRAM); @@ -923,155 +923,155 @@ namespace Ogre { return true; } - //----------------------------------------------------------------------- - void RenderSystem::addListener(Listener* l) - { - mEventListeners.push_back(l); - } - //----------------------------------------------------------------------- - void RenderSystem::removeListener(Listener* l) - { - mEventListeners.remove(l); - } - //----------------------------------------------------------------------- - void RenderSystem::fireEvent(const String& name, const NameValuePairList* params) - { - for(ListenerList::iterator i = mEventListeners.begin(); - i != mEventListeners.end(); ++i) - { - (*i)->eventOccurred(name, params); - } - } - //----------------------------------------------------------------------- - void RenderSystem::destroyHardwareOcclusionQuery( HardwareOcclusionQuery *hq) - { - HardwareOcclusionQueryList::iterator i = - std::find(mHwOcclusionQueries.begin(), mHwOcclusionQueries.end(), hq); - if (i != mHwOcclusionQueries.end()) - { - mHwOcclusionQueries.erase(i); - OGRE_DELETE hq; - } - } - //----------------------------------------------------------------------- - void RenderSystem::bindGpuProgram(GpuProgram* prg) - { - switch(prg->getType()) - { + //----------------------------------------------------------------------- + void RenderSystem::addListener(Listener* l) + { + mEventListeners.push_back(l); + } + //----------------------------------------------------------------------- + void RenderSystem::removeListener(Listener* l) + { + mEventListeners.remove(l); + } + //----------------------------------------------------------------------- + void RenderSystem::fireEvent(const String& name, const NameValuePairList* params) + { + for(ListenerList::iterator i = mEventListeners.begin(); + i != mEventListeners.end(); ++i) + { + (*i)->eventOccurred(name, params); + } + } + //----------------------------------------------------------------------- + void RenderSystem::destroyHardwareOcclusionQuery( HardwareOcclusionQuery *hq) + { + HardwareOcclusionQueryList::iterator i = + std::find(mHwOcclusionQueries.begin(), mHwOcclusionQueries.end(), hq); + if (i != mHwOcclusionQueries.end()) + { + mHwOcclusionQueries.erase(i); + OGRE_DELETE hq; + } + } + //----------------------------------------------------------------------- + void RenderSystem::bindGpuProgram(GpuProgram* prg) + { + switch(prg->getType()) + { case GPT_VERTEX_PROGRAM: - // mark clip planes dirty if changed (programmable can change space) - if (!mVertexProgramBound && !mClipPlanes.empty()) - mClipPlanesDirty = true; + // mark clip planes dirty if changed (programmable can change space) + if (!mVertexProgramBound && !mClipPlanes.empty()) + mClipPlanesDirty = true; mVertexProgramBound = true; - break; + break; case GPT_GEOMETRY_PROGRAM: - mGeometryProgramBound = true; - break; + mGeometryProgramBound = true; + break; case GPT_FRAGMENT_PROGRAM: mFragmentProgramBound = true; - break; - case GPT_HULL_PROGRAM: - mTessellationHullProgramBound = true; - break; - case GPT_DOMAIN_PROGRAM: - mTessellationDomainProgramBound = true; - break; - case GPT_COMPUTE_PROGRAM: + break; + case GPT_HULL_PROGRAM: + mTessellationHullProgramBound = true; + break; + case GPT_DOMAIN_PROGRAM: + mTessellationDomainProgramBound = true; + break; + case GPT_COMPUTE_PROGRAM: mComputeProgramBound = true; - break; - } - } - //----------------------------------------------------------------------- - void RenderSystem::unbindGpuProgram(GpuProgramType gptype) - { - switch(gptype) - { + break; + } + } + //----------------------------------------------------------------------- + void RenderSystem::unbindGpuProgram(GpuProgramType gptype) + { + switch(gptype) + { case GPT_VERTEX_PROGRAM: - // mark clip planes dirty if changed (programmable can change space) - if (mVertexProgramBound && !mClipPlanes.empty()) - mClipPlanesDirty = true; + // mark clip planes dirty if changed (programmable can change space) + if (mVertexProgramBound && !mClipPlanes.empty()) + mClipPlanesDirty = true; mVertexProgramBound = false; - break; + break; case GPT_GEOMETRY_PROGRAM: - mGeometryProgramBound = false; - break; + mGeometryProgramBound = false; + break; case GPT_FRAGMENT_PROGRAM: mFragmentProgramBound = false; - break; - case GPT_HULL_PROGRAM: - mTessellationHullProgramBound = false; - break; - case GPT_DOMAIN_PROGRAM: - mTessellationDomainProgramBound = false; - break; - case GPT_COMPUTE_PROGRAM: + break; + case GPT_HULL_PROGRAM: + mTessellationHullProgramBound = false; + break; + case GPT_DOMAIN_PROGRAM: + mTessellationDomainProgramBound = false; + break; + case GPT_COMPUTE_PROGRAM: mComputeProgramBound = false; - break; - } - } - //----------------------------------------------------------------------- - bool RenderSystem::isGpuProgramBound(GpuProgramType gptype) - { - switch(gptype) - { + break; + } + } + //----------------------------------------------------------------------- + bool RenderSystem::isGpuProgramBound(GpuProgramType gptype) + { + switch(gptype) + { case GPT_VERTEX_PROGRAM: return mVertexProgramBound; case GPT_GEOMETRY_PROGRAM: return mGeometryProgramBound; case GPT_FRAGMENT_PROGRAM: return mFragmentProgramBound; - case GPT_HULL_PROGRAM: - return mTessellationHullProgramBound; - case GPT_DOMAIN_PROGRAM: - return mTessellationDomainProgramBound; - case GPT_COMPUTE_PROGRAM: + case GPT_HULL_PROGRAM: + return mTessellationHullProgramBound; + case GPT_DOMAIN_PROGRAM: + return mTessellationDomainProgramBound; + case GPT_COMPUTE_PROGRAM: return mComputeProgramBound; - } + } // Make compiler happy return false; - } - //--------------------------------------------------------------------- - void RenderSystem::_setTextureProjectionRelativeTo(bool enabled, const Vector3& pos) - { - mTexProjRelative = enabled; - mTexProjRelativeOrigin = pos; - - } - //--------------------------------------------------------------------- - RenderSystem::RenderSystemContext* RenderSystem::_pauseFrame(void) - { - _endFrame(); - return new RenderSystem::RenderSystemContext; - } - //--------------------------------------------------------------------- - void RenderSystem::_resumeFrame(RenderSystemContext* context) - { - _beginFrame(); - delete context; - } - //--------------------------------------------------------------------- - const String& RenderSystem::_getDefaultViewportMaterialScheme( void ) const - { -#ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS - if ( !(getCapabilities()->hasCapability(Ogre::RSC_FIXED_FUNCTION)) ) - { - // I am returning the exact value for now - I don't want to add dependency for the RTSS just for one string - static const String ShaderGeneratorDefaultScheme = "ShaderGeneratorDefaultScheme"; - return ShaderGeneratorDefaultScheme; - } - else + } + //--------------------------------------------------------------------- + void RenderSystem::_setTextureProjectionRelativeTo(bool enabled, const Vector3& pos) + { + mTexProjRelative = enabled; + mTexProjRelativeOrigin = pos; + + } + //--------------------------------------------------------------------- + RenderSystem::RenderSystemContext* RenderSystem::_pauseFrame(void) + { + _endFrame(); + return new RenderSystem::RenderSystemContext; + } + //--------------------------------------------------------------------- + void RenderSystem::_resumeFrame(RenderSystemContext* context) + { + _beginFrame(); + delete context; + } + //--------------------------------------------------------------------- + const String& RenderSystem::_getDefaultViewportMaterialScheme( void ) const + { +#ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS + if ( !(getCapabilities()->hasCapability(Ogre::RSC_FIXED_FUNCTION)) ) + { + // I am returning the exact value for now - I don't want to add dependency for the RTSS just for one string + static const String ShaderGeneratorDefaultScheme = "ShaderGeneratorDefaultScheme"; + return ShaderGeneratorDefaultScheme; + } + else #endif - { - return MaterialManager::DEFAULT_SCHEME_NAME; - } - } - //--------------------------------------------------------------------- + { + return MaterialManager::DEFAULT_SCHEME_NAME; + } + } + //--------------------------------------------------------------------- Ogre::HardwareVertexBufferSharedPtr RenderSystem::getGlobalInstanceVertexBuffer() const { return mGlobalInstanceVertexBuffer; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void RenderSystem::setGlobalInstanceVertexBuffer( const HardwareVertexBufferSharedPtr &val ) { if ( !val.isNull() && !val->getIsInstanceData() ) @@ -1082,12 +1082,12 @@ namespace Ogre { } mGlobalInstanceVertexBuffer = val; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- size_t RenderSystem::getGlobalNumberOfInstances() const { return mGlobalNumberOfInstances; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void RenderSystem::setGlobalNumberOfInstances( const size_t val ) { mGlobalNumberOfInstances = val; @@ -1103,7 +1103,7 @@ namespace Ogre { mGlobalInstanceVertexBufferVertexDeclaration = val; } //--------------------------------------------------------------------- - void RenderSystem::getCustomAttribute(const String& name, void* pData) + void RenderSystem::getCustomAttribute(const String& name, void* pData) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Attribute not found.", "RenderSystem::getCustomAttribute"); } diff --git a/OgreMain/src/OgreRenderSystemCapabilities.cpp b/OgreMain/src/OgreRenderSystemCapabilities.cpp index 77753db3539..370e5d167b6 100644 --- a/OgreMain/src/OgreRenderSystemCapabilities.cpp +++ b/OgreMain/src/OgreRenderSystemCapabilities.cpp @@ -1,393 +1,393 @@ -/* ------------------------------------------------------------------------------ -This source file is part of OGRE -(Object-oriented Graphics Rendering Engine) -For the latest info, see http://www.ogre3d.org/ - -Copyright (c) 2000-2014 Torus Knot Software Ltd - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. ------------------------------------------------------------------------------ -*/ -#include "OgreStableHeaders.h" - -#include "OgreRenderSystemCapabilities.h" - -namespace Ogre { - - //----------------------------------------------------------------------- - RenderSystemCapabilities::RenderSystemCapabilities() - : mVendor(GPU_UNKNOWN) - , mNumWorldMatrices(0) - , mNumTextureUnits(0) - , mStencilBufferBitDepth(0) - , mNumVertexBlendMatrices(0) - , mNumMultiRenderTargets(1) - , mNonPOW2TexturesLimited(false) - , mMaxSupportedAnisotropy(0) - , mVertexTextureUnitsShared(0) - , mGeometryProgramNumOutputVertices(0) - { - for(int i = 0; i < CAPS_CATEGORY_COUNT; i++) - { - mCapabilities[i] = 0; - } - mCategoryRelevant[CAPS_CATEGORY_COMMON] = true; - mCategoryRelevant[CAPS_CATEGORY_COMMON_2] = true; - // each rendersystem should enable these - mCategoryRelevant[CAPS_CATEGORY_D3D9] = false; - mCategoryRelevant[CAPS_CATEGORY_GL] = false; - } - //----------------------------------------------------------------------- - RenderSystemCapabilities::~RenderSystemCapabilities() - { - } - //----------------------------------------------------------------------- - void RenderSystemCapabilities::log(Log* pLog) - { -#if OGRE_PLATFORM != OGRE_PLATFORM_WINRT - pLog->logMessage("RenderSystem capabilities"); - pLog->logMessage("-------------------------"); - pLog->logMessage("RenderSystem Name: " + getRenderSystemName()); - pLog->logMessage("GPU Vendor: " + vendorToString(getVendor())); - pLog->logMessage("Device Name: " + getDeviceName()); - pLog->logMessage("Driver Version: " + getDriverVersion().toString()); - pLog->logMessage(" * Fixed function pipeline: " - + StringConverter::toString(hasCapability(RSC_FIXED_FUNCTION), true)); - pLog->logMessage( - " * Hardware generation of mipmaps: " - + StringConverter::toString(hasCapability(RSC_AUTOMIPMAP), true)); - pLog->logMessage( - " * Texture blending: " - + StringConverter::toString(hasCapability(RSC_BLENDING), true)); - pLog->logMessage( - " * Anisotropic texture filtering: " - + StringConverter::toString(hasCapability(RSC_ANISOTROPY), true)); - pLog->logMessage( - " * Dot product texture operation: " - + StringConverter::toString(hasCapability(RSC_DOT3), true)); - pLog->logMessage( - " * Cube mapping: " - + StringConverter::toString(hasCapability(RSC_CUBEMAPPING), true)); - pLog->logMessage( - " * Hardware stencil buffer: " - + StringConverter::toString(hasCapability(RSC_HWSTENCIL), true)); - if (hasCapability(RSC_HWSTENCIL)) - { - pLog->logMessage( - " - Stencil depth: " - + StringConverter::toString(getStencilBufferBitDepth())); - pLog->logMessage( - " - Two sided stencil support: " - + StringConverter::toString(hasCapability(RSC_TWO_SIDED_STENCIL), true)); - pLog->logMessage( - " - Wrap stencil values: " - + StringConverter::toString(hasCapability(RSC_STENCIL_WRAP), true)); - } - pLog->logMessage( - " * Hardware vertex / index buffers: " - + StringConverter::toString(hasCapability(RSC_VBO), true)); - if(hasCapability(RSC_VBO)) - { - pLog->logMessage( - " * 32-bit index buffers: " - + StringConverter::toString(hasCapability(RSC_32BIT_INDEX), true)); - } - pLog->logMessage( - " * Vertex programs: " - + StringConverter::toString(hasCapability(RSC_VERTEX_PROGRAM), true)); - pLog->logMessage( - " * Number of floating-point constants for vertex programs: " - + StringConverter::toString(mVertexProgramConstantFloatCount)); - pLog->logMessage( - " * Number of integer constants for vertex programs: " - + StringConverter::toString(mVertexProgramConstantIntCount)); - pLog->logMessage( - " * Number of boolean constants for vertex programs: " - + StringConverter::toString(mVertexProgramConstantBoolCount)); - pLog->logMessage( - " * Fragment programs: " - + StringConverter::toString(hasCapability(RSC_FRAGMENT_PROGRAM), true)); - pLog->logMessage( - " * Number of floating-point constants for fragment programs: " - + StringConverter::toString(mFragmentProgramConstantFloatCount)); - pLog->logMessage( - " * Number of integer constants for fragment programs: " - + StringConverter::toString(mFragmentProgramConstantIntCount)); - pLog->logMessage( - " * Number of boolean constants for fragment programs: " - + StringConverter::toString(mFragmentProgramConstantBoolCount)); - pLog->logMessage( - " * Geometry programs: " - + StringConverter::toString(hasCapability(RSC_GEOMETRY_PROGRAM), true)); - pLog->logMessage( - " * Number of floating-point constants for geometry programs: " - + StringConverter::toString(mGeometryProgramConstantFloatCount)); - pLog->logMessage( - " * Number of integer constants for geometry programs: " - + StringConverter::toString(mGeometryProgramConstantIntCount)); - pLog->logMessage( - " * Number of boolean constants for geometry programs: " - + StringConverter::toString(mGeometryProgramConstantBoolCount)); - pLog->logMessage( - " * Tessellation Hull programs: " - + StringConverter::toString(hasCapability(RSC_TESSELLATION_HULL_PROGRAM), true)); - pLog->logMessage( - " * Number of floating-point constants for tessellation hull programs: " - + StringConverter::toString(mTessellationHullProgramConstantFloatCount)); - pLog->logMessage( - " * Number of integer constants for tessellation hull programs: " - + StringConverter::toString(mTessellationHullProgramConstantIntCount)); - pLog->logMessage( - " * Number of boolean constants for tessellation hull programs: " - + StringConverter::toString(mTessellationHullProgramConstantBoolCount)); - pLog->logMessage( - " * Tessellation Domain programs: " - + StringConverter::toString(hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM), true)); - pLog->logMessage( - " * Number of floating-point constants for tessellation domain programs: " - + StringConverter::toString(mTessellationDomainProgramConstantFloatCount)); - pLog->logMessage( - " * Number of integer constants for tessellation domain programs: " - + StringConverter::toString(mTessellationDomainProgramConstantIntCount)); - pLog->logMessage( - " * Number of boolean constants for tessellation domain programs: " - + StringConverter::toString(mTessellationDomainProgramConstantBoolCount)); - pLog->logMessage( - " * Compute programs: " - + StringConverter::toString(hasCapability(RSC_COMPUTE_PROGRAM), true)); - pLog->logMessage( - " * Number of floating-point constants for compute programs: " - + StringConverter::toString(mComputeProgramConstantFloatCount)); - pLog->logMessage( - " * Number of integer constants for compute programs: " - + StringConverter::toString(mComputeProgramConstantIntCount)); - pLog->logMessage( - " * Number of boolean constants for compute programs: " - + StringConverter::toString(mComputeProgramConstantBoolCount)); - String profileList = ""; - for(ShaderProfiles::iterator iter = mSupportedShaderProfiles.begin(), end = mSupportedShaderProfiles.end(); - iter != end; ++iter) - { - profileList += " " + *iter; - } - pLog->logMessage(" * Supported Shader Profiles:" + profileList); - - pLog->logMessage( - " * Texture Compression: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION), true)); - if (hasCapability(RSC_TEXTURE_COMPRESSION)) - { - pLog->logMessage( - " - DXT: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_DXT), true)); - pLog->logMessage( - " - VTC: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_VTC), true)); - pLog->logMessage( - " - PVRTC: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_PVRTC), true)); - pLog->logMessage( - " - ATC: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_ATC), true)); - pLog->logMessage( - " - ETC1: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_ETC1), true)); - pLog->logMessage( - " - ETC2: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_ETC2), true)); - pLog->logMessage( - " - BC4/BC5: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_BC4_BC5), true)); - pLog->logMessage( - " - BC6H/BC7: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_BC6H_BC7), true)); - } - - pLog->logMessage( - " * Scissor Rectangle: " - + StringConverter::toString(hasCapability(RSC_SCISSOR_TEST), true)); - pLog->logMessage( - " * Hardware Occlusion Query: " - + StringConverter::toString(hasCapability(RSC_HWOCCLUSION), true)); - pLog->logMessage( - " * User clip planes: " - + StringConverter::toString(hasCapability(RSC_USER_CLIP_PLANES), true)); - pLog->logMessage( - " * VET_UBYTE4 vertex element type: " - + StringConverter::toString(hasCapability(RSC_VERTEX_FORMAT_UBYTE4), true)); - pLog->logMessage( - " * Infinite far plane projection: " - + StringConverter::toString(hasCapability(RSC_INFINITE_FAR_PLANE), true)); - pLog->logMessage( - " * Hardware render-to-texture: " - + StringConverter::toString(hasCapability(RSC_HWRENDER_TO_TEXTURE), true)); - pLog->logMessage( - " * Floating point textures: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_FLOAT), true)); - pLog->logMessage( - " * Non-power-of-two textures: " - + StringConverter::toString(hasCapability(RSC_NON_POWER_OF_2_TEXTURES), true) - + (mNonPOW2TexturesLimited ? " (limited)" : "")); - pLog->logMessage( - " * 1d textures: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_1D), true)); - pLog->logMessage( - " * Volume textures: " - + StringConverter::toString(hasCapability(RSC_TEXTURE_3D), true)); - pLog->logMessage( - " * Multiple Render Targets: " - + StringConverter::toString(mNumMultiRenderTargets)); - pLog->logMessage( - " - With different bit depths: " + StringConverter::toString(hasCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS), true)); - pLog->logMessage( - " * Point Sprites: " - + StringConverter::toString(hasCapability(RSC_POINT_SPRITES), true)); - pLog->logMessage( - " * Extended point parameters: " - + StringConverter::toString(hasCapability(RSC_POINT_EXTENDED_PARAMETERS), true)); - if(hasCapability(RSC_POINT_SPRITES)) - { - pLog->logMessage( - " * Max Point Size: " - + StringConverter::toString(mMaxPointSize)); - } - pLog->logMessage( - " * Vertex texture fetch: " - + StringConverter::toString(hasCapability(RSC_VERTEX_TEXTURE_FETCH), true)); - pLog->logMessage( - " * Number of world matrices: " - + StringConverter::toString(mNumWorldMatrices)); - pLog->logMessage( - " * Number of texture units: " - + StringConverter::toString(mNumTextureUnits)); - pLog->logMessage( - " * Stencil buffer depth: " - + StringConverter::toString(mStencilBufferBitDepth)); - pLog->logMessage( - " * Number of vertex blend matrices: " - + StringConverter::toString(mNumVertexBlendMatrices)); - if (hasCapability(RSC_VERTEX_TEXTURE_FETCH)) - { - pLog->logMessage( - " - Max vertex textures: " - + StringConverter::toString(mNumVertexTextureUnits)); - pLog->logMessage( - " - Vertex textures shared: " - + StringConverter::toString(mVertexTextureUnitsShared, true)); - - } - pLog->logMessage( - " * Render to Vertex Buffer : " - + StringConverter::toString(hasCapability(RSC_HWRENDER_TO_VERTEX_BUFFER), true)); - pLog->logMessage( - " * Hardware Atomic Counters: " - + StringConverter::toString(hasCapability(RSC_ATOMIC_COUNTERS), true)); - - if (mCategoryRelevant[CAPS_CATEGORY_GL]) - { - pLog->logMessage( - " * GL 1.5 without VBO workaround: " - + StringConverter::toString(hasCapability(RSC_GL1_5_NOVBO), true)); - - pLog->logMessage( - " * Frame Buffer objects: " - + StringConverter::toString(hasCapability(RSC_FBO), true)); - pLog->logMessage( - " * Frame Buffer objects (ARB extension): " - + StringConverter::toString(hasCapability(RSC_FBO_ARB), true)); - pLog->logMessage( - " * Frame Buffer objects (ATI extension): " - + StringConverter::toString(hasCapability(RSC_FBO_ATI), true)); - pLog->logMessage( - " * PBuffer support: " - + StringConverter::toString(hasCapability(RSC_PBUFFER), true)); - pLog->logMessage( - " * GL 1.5 without HW-occlusion workaround: " - + StringConverter::toString(hasCapability(RSC_GL1_5_NOHWOCCLUSION), true)); - pLog->logMessage( - " * Vertex Array Objects: " - + StringConverter::toString(hasCapability(RSC_VAO), true)); - pLog->logMessage( - " * Separate shader objects: " - + StringConverter::toString(hasCapability(RSC_SEPARATE_SHADER_OBJECTS), true)); - } - - if (mCategoryRelevant[CAPS_CATEGORY_D3D9]) - { - pLog->logMessage( - " * DirectX per stage constants: " - + StringConverter::toString(hasCapability(RSC_PERSTAGECONSTANT), true)); - } -#endif - } - //--------------------------------------------------------------------- - StringVector RenderSystemCapabilities::msGPUVendorStrings; - //--------------------------------------------------------------------- - GPUVendor RenderSystemCapabilities::vendorFromString(const String& vendorString) - { - initVendorStrings(); - GPUVendor ret = GPU_UNKNOWN; - String cmpString = vendorString; - StringUtil::toLowerCase(cmpString); - for (int i = 0; i < GPU_VENDOR_COUNT; ++i) - { - // case insensitive (lower case) - if (msGPUVendorStrings[i] == cmpString) - { - ret = static_cast(i); - break; - } - } - - return ret; - - } - //--------------------------------------------------------------------- - String RenderSystemCapabilities::vendorToString(GPUVendor v) - { - initVendorStrings(); - return msGPUVendorStrings[v]; - } - //--------------------------------------------------------------------- - void RenderSystemCapabilities::initVendorStrings() - { - if (msGPUVendorStrings.empty()) - { - // Always lower case! - msGPUVendorStrings.resize(GPU_VENDOR_COUNT); - msGPUVendorStrings[GPU_UNKNOWN] = "unknown"; - msGPUVendorStrings[GPU_NVIDIA] = "nvidia"; - msGPUVendorStrings[GPU_AMD] = "amd"; - msGPUVendorStrings[GPU_INTEL] = "intel"; - msGPUVendorStrings[GPU_3DLABS] = "3dlabs"; - msGPUVendorStrings[GPU_S3] = "s3"; - msGPUVendorStrings[GPU_MATROX] = "matrox"; - msGPUVendorStrings[GPU_SIS] = "sis"; - msGPUVendorStrings[GPU_IMAGINATION_TECHNOLOGIES] = "imagination technologies"; - msGPUVendorStrings[GPU_APPLE] = "apple"; // iOS Simulator - msGPUVendorStrings[GPU_NOKIA] = "nokia"; - msGPUVendorStrings[GPU_MS_SOFTWARE] = "microsoft"; // Microsoft software device - msGPUVendorStrings[GPU_MS_WARP] = "ms warp"; - msGPUVendorStrings[GPU_ARM] = "arm"; - msGPUVendorStrings[GPU_QUALCOMM] = "qualcomm"; - } - } - -} +/* +----------------------------------------------------------------------------- +This source file is part of OGRE +(Object-oriented Graphics Rendering Engine) +For the latest info, see http://www.ogre3d.org/ + +Copyright (c) 2000-2014 Torus Knot Software Ltd + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +----------------------------------------------------------------------------- +*/ +#include "OgreStableHeaders.h" + +#include "OgreRenderSystemCapabilities.h" + +namespace Ogre { + + //----------------------------------------------------------------------- + RenderSystemCapabilities::RenderSystemCapabilities() + : mVendor(GPU_UNKNOWN) + , mNumWorldMatrices(0) + , mNumTextureUnits(0) + , mStencilBufferBitDepth(0) + , mNumVertexBlendMatrices(0) + , mNumMultiRenderTargets(1) + , mNonPOW2TexturesLimited(false) + , mMaxSupportedAnisotropy(0) + , mVertexTextureUnitsShared(0) + , mGeometryProgramNumOutputVertices(0) + { + for(int i = 0; i < CAPS_CATEGORY_COUNT; i++) + { + mCapabilities[i] = 0; + } + mCategoryRelevant[CAPS_CATEGORY_COMMON] = true; + mCategoryRelevant[CAPS_CATEGORY_COMMON_2] = true; + // each rendersystem should enable these + mCategoryRelevant[CAPS_CATEGORY_D3D9] = false; + mCategoryRelevant[CAPS_CATEGORY_GL] = false; + } + //----------------------------------------------------------------------- + RenderSystemCapabilities::~RenderSystemCapabilities() + { + } + //----------------------------------------------------------------------- + void RenderSystemCapabilities::log(Log* pLog) + { +#if OGRE_PLATFORM != OGRE_PLATFORM_WINRT + pLog->logMessage("RenderSystem capabilities"); + pLog->logMessage("-------------------------"); + pLog->logMessage("RenderSystem Name: " + getRenderSystemName()); + pLog->logMessage("GPU Vendor: " + vendorToString(getVendor())); + pLog->logMessage("Device Name: " + getDeviceName()); + pLog->logMessage("Driver Version: " + getDriverVersion().toString()); + pLog->logMessage(" * Fixed function pipeline: " + + StringConverter::toString(hasCapability(RSC_FIXED_FUNCTION), true)); + pLog->logMessage( + " * Hardware generation of mipmaps: " + + StringConverter::toString(hasCapability(RSC_AUTOMIPMAP), true)); + pLog->logMessage( + " * Texture blending: " + + StringConverter::toString(hasCapability(RSC_BLENDING), true)); + pLog->logMessage( + " * Anisotropic texture filtering: " + + StringConverter::toString(hasCapability(RSC_ANISOTROPY), true)); + pLog->logMessage( + " * Dot product texture operation: " + + StringConverter::toString(hasCapability(RSC_DOT3), true)); + pLog->logMessage( + " * Cube mapping: " + + StringConverter::toString(hasCapability(RSC_CUBEMAPPING), true)); + pLog->logMessage( + " * Hardware stencil buffer: " + + StringConverter::toString(hasCapability(RSC_HWSTENCIL), true)); + if (hasCapability(RSC_HWSTENCIL)) + { + pLog->logMessage( + " - Stencil depth: " + + StringConverter::toString(getStencilBufferBitDepth())); + pLog->logMessage( + " - Two sided stencil support: " + + StringConverter::toString(hasCapability(RSC_TWO_SIDED_STENCIL), true)); + pLog->logMessage( + " - Wrap stencil values: " + + StringConverter::toString(hasCapability(RSC_STENCIL_WRAP), true)); + } + pLog->logMessage( + " * Hardware vertex / index buffers: " + + StringConverter::toString(hasCapability(RSC_VBO), true)); + if(hasCapability(RSC_VBO)) + { + pLog->logMessage( + " * 32-bit index buffers: " + + StringConverter::toString(hasCapability(RSC_32BIT_INDEX), true)); + } + pLog->logMessage( + " * Vertex programs: " + + StringConverter::toString(hasCapability(RSC_VERTEX_PROGRAM), true)); + pLog->logMessage( + " * Number of floating-point constants for vertex programs: " + + StringConverter::toString(mVertexProgramConstantFloatCount)); + pLog->logMessage( + " * Number of integer constants for vertex programs: " + + StringConverter::toString(mVertexProgramConstantIntCount)); + pLog->logMessage( + " * Number of boolean constants for vertex programs: " + + StringConverter::toString(mVertexProgramConstantBoolCount)); + pLog->logMessage( + " * Fragment programs: " + + StringConverter::toString(hasCapability(RSC_FRAGMENT_PROGRAM), true)); + pLog->logMessage( + " * Number of floating-point constants for fragment programs: " + + StringConverter::toString(mFragmentProgramConstantFloatCount)); + pLog->logMessage( + " * Number of integer constants for fragment programs: " + + StringConverter::toString(mFragmentProgramConstantIntCount)); + pLog->logMessage( + " * Number of boolean constants for fragment programs: " + + StringConverter::toString(mFragmentProgramConstantBoolCount)); + pLog->logMessage( + " * Geometry programs: " + + StringConverter::toString(hasCapability(RSC_GEOMETRY_PROGRAM), true)); + pLog->logMessage( + " * Number of floating-point constants for geometry programs: " + + StringConverter::toString(mGeometryProgramConstantFloatCount)); + pLog->logMessage( + " * Number of integer constants for geometry programs: " + + StringConverter::toString(mGeometryProgramConstantIntCount)); + pLog->logMessage( + " * Number of boolean constants for geometry programs: " + + StringConverter::toString(mGeometryProgramConstantBoolCount)); + pLog->logMessage( + " * Tessellation Hull programs: " + + StringConverter::toString(hasCapability(RSC_TESSELLATION_HULL_PROGRAM), true)); + pLog->logMessage( + " * Number of floating-point constants for tessellation hull programs: " + + StringConverter::toString(mTessellationHullProgramConstantFloatCount)); + pLog->logMessage( + " * Number of integer constants for tessellation hull programs: " + + StringConverter::toString(mTessellationHullProgramConstantIntCount)); + pLog->logMessage( + " * Number of boolean constants for tessellation hull programs: " + + StringConverter::toString(mTessellationHullProgramConstantBoolCount)); + pLog->logMessage( + " * Tessellation Domain programs: " + + StringConverter::toString(hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM), true)); + pLog->logMessage( + " * Number of floating-point constants for tessellation domain programs: " + + StringConverter::toString(mTessellationDomainProgramConstantFloatCount)); + pLog->logMessage( + " * Number of integer constants for tessellation domain programs: " + + StringConverter::toString(mTessellationDomainProgramConstantIntCount)); + pLog->logMessage( + " * Number of boolean constants for tessellation domain programs: " + + StringConverter::toString(mTessellationDomainProgramConstantBoolCount)); + pLog->logMessage( + " * Compute programs: " + + StringConverter::toString(hasCapability(RSC_COMPUTE_PROGRAM), true)); + pLog->logMessage( + " * Number of floating-point constants for compute programs: " + + StringConverter::toString(mComputeProgramConstantFloatCount)); + pLog->logMessage( + " * Number of integer constants for compute programs: " + + StringConverter::toString(mComputeProgramConstantIntCount)); + pLog->logMessage( + " * Number of boolean constants for compute programs: " + + StringConverter::toString(mComputeProgramConstantBoolCount)); + String profileList = ""; + for(ShaderProfiles::iterator iter = mSupportedShaderProfiles.begin(), end = mSupportedShaderProfiles.end(); + iter != end; ++iter) + { + profileList += " " + *iter; + } + pLog->logMessage(" * Supported Shader Profiles:" + profileList); + + pLog->logMessage( + " * Texture Compression: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION), true)); + if (hasCapability(RSC_TEXTURE_COMPRESSION)) + { + pLog->logMessage( + " - DXT: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_DXT), true)); + pLog->logMessage( + " - VTC: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_VTC), true)); + pLog->logMessage( + " - PVRTC: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_PVRTC), true)); + pLog->logMessage( + " - ATC: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_ATC), true)); + pLog->logMessage( + " - ETC1: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_ETC1), true)); + pLog->logMessage( + " - ETC2: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_ETC2), true)); + pLog->logMessage( + " - BC4/BC5: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_BC4_BC5), true)); + pLog->logMessage( + " - BC6H/BC7: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_BC6H_BC7), true)); + } + + pLog->logMessage( + " * Scissor Rectangle: " + + StringConverter::toString(hasCapability(RSC_SCISSOR_TEST), true)); + pLog->logMessage( + " * Hardware Occlusion Query: " + + StringConverter::toString(hasCapability(RSC_HWOCCLUSION), true)); + pLog->logMessage( + " * User clip planes: " + + StringConverter::toString(hasCapability(RSC_USER_CLIP_PLANES), true)); + pLog->logMessage( + " * VET_UBYTE4 vertex element type: " + + StringConverter::toString(hasCapability(RSC_VERTEX_FORMAT_UBYTE4), true)); + pLog->logMessage( + " * Infinite far plane projection: " + + StringConverter::toString(hasCapability(RSC_INFINITE_FAR_PLANE), true)); + pLog->logMessage( + " * Hardware render-to-texture: " + + StringConverter::toString(hasCapability(RSC_HWRENDER_TO_TEXTURE), true)); + pLog->logMessage( + " * Floating point textures: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_FLOAT), true)); + pLog->logMessage( + " * Non-power-of-two textures: " + + StringConverter::toString(hasCapability(RSC_NON_POWER_OF_2_TEXTURES), true) + + (mNonPOW2TexturesLimited ? " (limited)" : "")); + pLog->logMessage( + " * 1d textures: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_1D), true)); + pLog->logMessage( + " * Volume textures: " + + StringConverter::toString(hasCapability(RSC_TEXTURE_3D), true)); + pLog->logMessage( + " * Multiple Render Targets: " + + StringConverter::toString(mNumMultiRenderTargets)); + pLog->logMessage( + " - With different bit depths: " + StringConverter::toString(hasCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS), true)); + pLog->logMessage( + " * Point Sprites: " + + StringConverter::toString(hasCapability(RSC_POINT_SPRITES), true)); + pLog->logMessage( + " * Extended point parameters: " + + StringConverter::toString(hasCapability(RSC_POINT_EXTENDED_PARAMETERS), true)); + if(hasCapability(RSC_POINT_SPRITES)) + { + pLog->logMessage( + " * Max Point Size: " + + StringConverter::toString(mMaxPointSize)); + } + pLog->logMessage( + " * Vertex texture fetch: " + + StringConverter::toString(hasCapability(RSC_VERTEX_TEXTURE_FETCH), true)); + pLog->logMessage( + " * Number of world matrices: " + + StringConverter::toString(mNumWorldMatrices)); + pLog->logMessage( + " * Number of texture units: " + + StringConverter::toString(mNumTextureUnits)); + pLog->logMessage( + " * Stencil buffer depth: " + + StringConverter::toString(mStencilBufferBitDepth)); + pLog->logMessage( + " * Number of vertex blend matrices: " + + StringConverter::toString(mNumVertexBlendMatrices)); + if (hasCapability(RSC_VERTEX_TEXTURE_FETCH)) + { + pLog->logMessage( + " - Max vertex textures: " + + StringConverter::toString(mNumVertexTextureUnits)); + pLog->logMessage( + " - Vertex textures shared: " + + StringConverter::toString(mVertexTextureUnitsShared, true)); + + } + pLog->logMessage( + " * Render to Vertex Buffer : " + + StringConverter::toString(hasCapability(RSC_HWRENDER_TO_VERTEX_BUFFER), true)); + pLog->logMessage( + " * Hardware Atomic Counters: " + + StringConverter::toString(hasCapability(RSC_ATOMIC_COUNTERS), true)); + + if (mCategoryRelevant[CAPS_CATEGORY_GL]) + { + pLog->logMessage( + " * GL 1.5 without VBO workaround: " + + StringConverter::toString(hasCapability(RSC_GL1_5_NOVBO), true)); + + pLog->logMessage( + " * Frame Buffer objects: " + + StringConverter::toString(hasCapability(RSC_FBO), true)); + pLog->logMessage( + " * Frame Buffer objects (ARB extension): " + + StringConverter::toString(hasCapability(RSC_FBO_ARB), true)); + pLog->logMessage( + " * Frame Buffer objects (ATI extension): " + + StringConverter::toString(hasCapability(RSC_FBO_ATI), true)); + pLog->logMessage( + " * PBuffer support: " + + StringConverter::toString(hasCapability(RSC_PBUFFER), true)); + pLog->logMessage( + " * GL 1.5 without HW-occlusion workaround: " + + StringConverter::toString(hasCapability(RSC_GL1_5_NOHWOCCLUSION), true)); + pLog->logMessage( + " * Vertex Array Objects: " + + StringConverter::toString(hasCapability(RSC_VAO), true)); + pLog->logMessage( + " * Separate shader objects: " + + StringConverter::toString(hasCapability(RSC_SEPARATE_SHADER_OBJECTS), true)); + } + + if (mCategoryRelevant[CAPS_CATEGORY_D3D9]) + { + pLog->logMessage( + " * DirectX per stage constants: " + + StringConverter::toString(hasCapability(RSC_PERSTAGECONSTANT), true)); + } +#endif + } + //--------------------------------------------------------------------- + StringVector RenderSystemCapabilities::msGPUVendorStrings; + //--------------------------------------------------------------------- + GPUVendor RenderSystemCapabilities::vendorFromString(const String& vendorString) + { + initVendorStrings(); + GPUVendor ret = GPU_UNKNOWN; + String cmpString = vendorString; + StringUtil::toLowerCase(cmpString); + for (int i = 0; i < GPU_VENDOR_COUNT; ++i) + { + // case insensitive (lower case) + if (msGPUVendorStrings[i] == cmpString) + { + ret = static_cast(i); + break; + } + } + + return ret; + + } + //--------------------------------------------------------------------- + String RenderSystemCapabilities::vendorToString(GPUVendor v) + { + initVendorStrings(); + return msGPUVendorStrings[v]; + } + //--------------------------------------------------------------------- + void RenderSystemCapabilities::initVendorStrings() + { + if (msGPUVendorStrings.empty()) + { + // Always lower case! + msGPUVendorStrings.resize(GPU_VENDOR_COUNT); + msGPUVendorStrings[GPU_UNKNOWN] = "unknown"; + msGPUVendorStrings[GPU_NVIDIA] = "nvidia"; + msGPUVendorStrings[GPU_AMD] = "amd"; + msGPUVendorStrings[GPU_INTEL] = "intel"; + msGPUVendorStrings[GPU_3DLABS] = "3dlabs"; + msGPUVendorStrings[GPU_S3] = "s3"; + msGPUVendorStrings[GPU_MATROX] = "matrox"; + msGPUVendorStrings[GPU_SIS] = "sis"; + msGPUVendorStrings[GPU_IMAGINATION_TECHNOLOGIES] = "imagination technologies"; + msGPUVendorStrings[GPU_APPLE] = "apple"; // iOS Simulator + msGPUVendorStrings[GPU_NOKIA] = "nokia"; + msGPUVendorStrings[GPU_MS_SOFTWARE] = "microsoft"; // Microsoft software device + msGPUVendorStrings[GPU_MS_WARP] = "ms warp"; + msGPUVendorStrings[GPU_ARM] = "arm"; + msGPUVendorStrings[GPU_QUALCOMM] = "qualcomm"; + } + } + +} diff --git a/OgreMain/src/OgreRenderSystemCapabilitiesManager.cpp b/OgreMain/src/OgreRenderSystemCapabilitiesManager.cpp index ea077e7366e..11edf35af72 100644 --- a/OgreMain/src/OgreRenderSystemCapabilitiesManager.cpp +++ b/OgreMain/src/OgreRenderSystemCapabilitiesManager.cpp @@ -86,10 +86,10 @@ namespace Ogre { return mCapabilitiesMap[name]; } - const map::type &RenderSystemCapabilitiesManager::getCapabilities() const - { - return mCapabilitiesMap; - } + const map::type &RenderSystemCapabilitiesManager::getCapabilities() const + { + return mCapabilitiesMap; + } /** Method used by RenderSystemCapabilitiesSerializer::parseScript */ void RenderSystemCapabilitiesManager::_addRenderSystemCapabilities(const String& name, RenderSystemCapabilities* caps) diff --git a/OgreMain/src/OgreRenderSystemCapabilitiesSerializer.cpp b/OgreMain/src/OgreRenderSystemCapabilitiesSerializer.cpp index e36d504afb8..83a2d139f82 100644 --- a/OgreMain/src/OgreRenderSystemCapabilitiesSerializer.cpp +++ b/OgreMain/src/OgreRenderSystemCapabilitiesSerializer.cpp @@ -46,28 +46,28 @@ namespace Ogre initialiaseDispatchTables(); } - - //----------------------------------------------------------------------- - static void write(const RenderSystemCapabilities* caps, const String &name, std::ostream &file) - { - using namespace std; + + //----------------------------------------------------------------------- + static void write(const RenderSystemCapabilities* caps, const String &name, std::ostream &file) + { + using namespace std; - file << "render_system_capabilities \"" << name << "\"" << endl; + file << "render_system_capabilities \"" << name << "\"" << endl; file << "{" << endl; file << "\t" << "render_system_name " << caps->getRenderSystemName() << endl; file << endl; - file << "\t" << "device_name " << caps->getDeviceName() << endl; - const DriverVersion& driverVer = caps->getDriverVersion(); - file << "\t" << "driver_version " << driverVer.toString() << endl; - file << "\t" << "vendor " << caps->vendorToString(caps->getVendor()); + file << "\t" << "device_name " << caps->getDeviceName() << endl; + const DriverVersion& driverVer = caps->getDriverVersion(); + file << "\t" << "driver_version " << driverVer.toString() << endl; + file << "\t" << "vendor " << caps->vendorToString(caps->getVendor()); - file << endl; + file << endl; file << endl; - file << "\t" << "fixed_function " << StringConverter::toString(caps->hasCapability(RSC_FIXED_FUNCTION)) << endl; + file << "\t" << "fixed_function " << StringConverter::toString(caps->hasCapability(RSC_FIXED_FUNCTION)) << endl; file << "\t" << "automipmap " << StringConverter::toString(caps->hasCapability(RSC_AUTOMIPMAP)) << endl; file << "\t" << "blending " << StringConverter::toString(caps->hasCapability(RSC_BLENDING)) << endl; file << "\t" << "anisotropy " << StringConverter::toString(caps->hasCapability(RSC_ANISOTROPY)) << endl; @@ -106,7 +106,7 @@ namespace Ogre file << "\t" << "texture_compression_atc " << StringConverter::toString(caps->hasCapability(RSC_TEXTURE_COMPRESSION_ATC)) << endl; file << "\t" << "texture_compression_etc1 " << StringConverter::toString(caps->hasCapability(RSC_TEXTURE_COMPRESSION_ETC1)) << endl; file << "\t" << "texture_compression_etc2 " << StringConverter::toString(caps->hasCapability(RSC_TEXTURE_COMPRESSION_ETC2)) << endl; - file << "\t" << "texture_compression_bc4_bc5 " << StringConverter::toString(caps->hasCapability(RSC_TEXTURE_COMPRESSION_BC4_BC5)) << endl; + file << "\t" << "texture_compression_bc4_bc5 " << StringConverter::toString(caps->hasCapability(RSC_TEXTURE_COMPRESSION_BC4_BC5)) << endl; file << "\t" << "texture_compression_bc6h_bc7 " << StringConverter::toString(caps->hasCapability(RSC_TEXTURE_COMPRESSION_BC6H_BC7)) << endl; file << "\t" << "gl1_5_novbo " << StringConverter::toString(caps->hasCapability(RSC_GL1_5_NOVBO)) << endl; file << "\t" << "fbo " << StringConverter::toString(caps->hasCapability(RSC_FBO)) << endl; @@ -162,31 +162,31 @@ namespace Ogre file << endl; file << "}" << endl; - } + } //----------------------------------------------------------------------- void RenderSystemCapabilitiesSerializer::writeScript(const RenderSystemCapabilities* caps, const String &name, String filename) { using namespace std; - ofstream file(filename.c_str()); + ofstream file(filename.c_str()); write(caps, name, file); file.close(); } - - //----------------------------------------------------------------------- - String RenderSystemCapabilitiesSerializer::writeString(const RenderSystemCapabilities* caps, const String &name) - { - using namespace std; - - stringstream stream; - - write(caps, name, stream); - - return stream.str(); - } + + //----------------------------------------------------------------------- + String RenderSystemCapabilitiesSerializer::writeString(const RenderSystemCapabilities* caps, const String &name) + { + using namespace std; + + stringstream stream; + + write(caps, name, stream); + + return stream.str(); + } //----------------------------------------------------------------------- void RenderSystemCapabilitiesSerializer::parseScript(DataStreamPtr& stream) @@ -209,17 +209,17 @@ namespace Ogre // comment or empty line) for further processing CapabilitiesLinesList capabilitiesLines; - // for reading data - char tmpBuf[OGRE_STREAM_TEMP_SIZE]; + // for reading data + char tmpBuf[OGRE_STREAM_TEMP_SIZE]; // TODO: build a smarter tokenizer so that "{" and "}" // don't need separate lines while (!stream->eof()) { - stream->readLine(tmpBuf, OGRE_STREAM_TEMP_SIZE-1); + stream->readLine(tmpBuf, OGRE_STREAM_TEMP_SIZE-1); line = String(tmpBuf); - StringUtil::trim(line); + StringUtil::trim(line); // keep track of parse position mCurrentLine = &line; @@ -329,27 +329,27 @@ namespace Ogre void RenderSystemCapabilitiesSerializer::initialiaseDispatchTables() { - // set up driver version parsing - addKeywordType("driver_version", SET_STRING_METHOD); + // set up driver version parsing + addKeywordType("driver_version", SET_STRING_METHOD); // set up the setters for driver versions addSetStringMethod("driver_version", &RenderSystemCapabilities::parseDriverVersionFromString); // set up device name parsing - addKeywordType("device_name", SET_STRING_METHOD); + addKeywordType("device_name", SET_STRING_METHOD); // set up the setters for device names addSetStringMethod("device_name", &RenderSystemCapabilities::setDeviceName); - // set up render system name parsing - addKeywordType("render_system_name", SET_STRING_METHOD); - // set up the setters - addSetStringMethod("render_system_name", &RenderSystemCapabilities::setRenderSystemName); + // set up render system name parsing + addKeywordType("render_system_name", SET_STRING_METHOD); + // set up the setters + addSetStringMethod("render_system_name", &RenderSystemCapabilities::setRenderSystemName); - // set up vendor parsing - addKeywordType("vendor", SET_STRING_METHOD); - // set up the setters for driver versions - addSetStringMethod("vendor", &RenderSystemCapabilities::parseVendorFromString); + // set up vendor parsing + addKeywordType("vendor", SET_STRING_METHOD); + // set up the setters for driver versions + addSetStringMethod("vendor", &RenderSystemCapabilities::parseVendorFromString); - // initialize int types + // initialize int types addKeywordType("num_world_matrices", SET_INT_METHOD); addKeywordType("num_texture_units", SET_INT_METHOD); addKeywordType("stencil_buffer_bit_depth", SET_INT_METHOD); @@ -419,7 +419,7 @@ namespace Ogre addKeywordType("shader_profile", ADD_SHADER_PROFILE_STRING); // set up RSC_XXX style capabilities - addKeywordType("fixed_function", SET_CAPABILITY_ENUM_BOOL); + addKeywordType("fixed_function", SET_CAPABILITY_ENUM_BOOL); addKeywordType("automipmap", SET_CAPABILITY_ENUM_BOOL); addKeywordType("blending", SET_CAPABILITY_ENUM_BOOL); addKeywordType("anisotropy", SET_CAPABILITY_ENUM_BOOL); @@ -428,7 +428,7 @@ namespace Ogre addKeywordType("hwstencil", SET_CAPABILITY_ENUM_BOOL); addKeywordType("vbo", SET_CAPABILITY_ENUM_BOOL); addKeywordType("vertex_program", SET_CAPABILITY_ENUM_BOOL); - addKeywordType("geometry_program", SET_CAPABILITY_ENUM_BOOL); + addKeywordType("geometry_program", SET_CAPABILITY_ENUM_BOOL); addKeywordType("fragment_program", SET_CAPABILITY_ENUM_BOOL); addKeywordType("tessellation_hull_program", SET_CAPABILITY_ENUM_BOOL); addKeywordType("tessellation_domain_program", SET_CAPABILITY_ENUM_BOOL); @@ -469,7 +469,7 @@ namespace Ogre addKeywordType("vao", SET_CAPABILITY_ENUM_BOOL); addKeywordType("separate_shader_objects", SET_CAPABILITY_ENUM_BOOL); - addCapabilitiesMapping("fixed_function", RSC_FIXED_FUNCTION); + addCapabilitiesMapping("fixed_function", RSC_FIXED_FUNCTION); addCapabilitiesMapping("automipmap", RSC_AUTOMIPMAP); addCapabilitiesMapping("blending", RSC_BLENDING); addCapabilitiesMapping("anisotropy", RSC_ANISOTROPY); @@ -479,7 +479,7 @@ namespace Ogre addCapabilitiesMapping("vbo", RSC_VBO); addCapabilitiesMapping("32bit_index", RSC_32BIT_INDEX); addCapabilitiesMapping("vertex_program", RSC_VERTEX_PROGRAM); - addCapabilitiesMapping("geometry_program", RSC_GEOMETRY_PROGRAM); + addCapabilitiesMapping("geometry_program", RSC_GEOMETRY_PROGRAM); addCapabilitiesMapping("fragment_program", RSC_FRAGMENT_PROGRAM); addCapabilitiesMapping("tessellation_hull_program", RSC_TESSELLATION_HULL_PROGRAM); addCapabilitiesMapping("tessellation_domain_program", RSC_TESSELLATION_DOMAIN_PROGRAM); @@ -492,10 +492,10 @@ namespace Ogre addCapabilitiesMapping("vertex_format_ubyte4", RSC_VERTEX_FORMAT_UBYTE4); addCapabilitiesMapping("infinite_far_plane", RSC_INFINITE_FAR_PLANE); addCapabilitiesMapping("hwrender_to_texture", RSC_HWRENDER_TO_TEXTURE); - addCapabilitiesMapping("texture_float", RSC_TEXTURE_FLOAT); + addCapabilitiesMapping("texture_float", RSC_TEXTURE_FLOAT); addCapabilitiesMapping("non_power_of_2_textures", RSC_NON_POWER_OF_2_TEXTURES); addCapabilitiesMapping("texture_3d", RSC_TEXTURE_3D); - addCapabilitiesMapping("texture_1d", RSC_TEXTURE_1D); + addCapabilitiesMapping("texture_1d", RSC_TEXTURE_1D); addCapabilitiesMapping("point_sprites", RSC_POINT_SPRITES); addCapabilitiesMapping("point_extended_parameters", RSC_POINT_EXTENDED_PARAMETERS); addCapabilitiesMapping("vertex_texture_fetch", RSC_VERTEX_TEXTURE_FETCH); @@ -510,7 +510,7 @@ namespace Ogre addCapabilitiesMapping("texture_compression_etc2", RSC_TEXTURE_COMPRESSION_ETC2); addCapabilitiesMapping("texture_compression_bc4_bc5", RSC_TEXTURE_COMPRESSION_BC4_BC5); addCapabilitiesMapping("texture_compression_bc6h_bc7", RSC_TEXTURE_COMPRESSION_BC6H_BC7); - addCapabilitiesMapping("hwrender_to_vertex_buffer", RSC_HWRENDER_TO_VERTEX_BUFFER); + addCapabilitiesMapping("hwrender_to_vertex_buffer", RSC_HWRENDER_TO_VERTEX_BUFFER); addCapabilitiesMapping("gl1_5_novbo", RSC_GL1_5_NOVBO); addCapabilitiesMapping("fbo", RSC_FBO); addCapabilitiesMapping("fbo_arb", RSC_FBO_ARB); diff --git a/OgreMain/src/OgreRenderTarget.cpp b/OgreMain/src/OgreRenderTarget.cpp index 5c0f7fb0a2d..d02401e324e 100644 --- a/OgreMain/src/OgreRenderTarget.cpp +++ b/OgreMain/src/OgreRenderTarget.cpp @@ -41,13 +41,13 @@ THE SOFTWARE. namespace Ogre { RenderTarget::RenderTarget() - : mPriority(OGRE_DEFAULT_RT_GROUP) - , mDepthBufferPoolId(DepthBuffer::POOL_DEFAULT) - , mDepthBuffer(0) - , mActive(true) - , mAutoUpdate(true) - , mHwGamma(false) - , mFSAA(0) + : mPriority(OGRE_DEFAULT_RT_GROUP) + , mDepthBufferPoolId(DepthBuffer::POOL_DEFAULT) + , mDepthBuffer(0) + , mActive(true) + , mAutoUpdate(true) + , mHwGamma(false) + , mFSAA(0) { mTimer = Root::getSingleton().getTimer(); resetStatistics(); @@ -63,16 +63,16 @@ namespace Ogre { OGRE_DELETE (*i).second; } - //DepthBuffer keeps track of us, avoid a dangling pointer - detachDepthBuffer(); + //DepthBuffer keeps track of us, avoid a dangling pointer + detachDepthBuffer(); // Write closing message - LogManager::getSingleton().stream(LML_TRIVIAL) - << "Render Target '" << mName << "' " - << "Average FPS: " << mStats.avgFPS << " " - << "Best FPS: " << mStats.bestFPS << " " - << "Worst FPS: " << mStats.worstFPS; + LogManager::getSingleton().stream(LML_TRIVIAL) + << "Render Target '" << mName << "' " + << "Average FPS: " << mStats.avgFPS << " " + << "Best FPS: " << mStats.bestFPS << " " + << "Worst FPS: " << mStats.worstFPS; } @@ -101,138 +101,138 @@ namespace Ogre { { return mColourDepth; } - //----------------------------------------------------------------------- - void RenderTarget::setDepthBufferPool( uint16 poolId ) - { - if( mDepthBufferPoolId != poolId ) - { - mDepthBufferPoolId = poolId; - detachDepthBuffer(); - } - } - //----------------------------------------------------------------------- - uint16 RenderTarget::getDepthBufferPool() const - { - return mDepthBufferPoolId; - } - //----------------------------------------------------------------------- - DepthBuffer* RenderTarget::getDepthBuffer() const - { - return mDepthBuffer; - } - //----------------------------------------------------------------------- - bool RenderTarget::attachDepthBuffer( DepthBuffer *depthBuffer ) - { - bool retVal = false; - - if( (retVal = depthBuffer->isCompatible( this )) ) - { - detachDepthBuffer(); - mDepthBuffer = depthBuffer; - mDepthBuffer->_notifyRenderTargetAttached( this ); - } - - return retVal; - } - //----------------------------------------------------------------------- - void RenderTarget::detachDepthBuffer() - { - if( mDepthBuffer ) - { - mDepthBuffer->_notifyRenderTargetDetached( this ); - mDepthBuffer = 0; - } - } - //----------------------------------------------------------------------- - void RenderTarget::_detachDepthBuffer() - { - mDepthBuffer = 0; - } + //----------------------------------------------------------------------- + void RenderTarget::setDepthBufferPool( uint16 poolId ) + { + if( mDepthBufferPoolId != poolId ) + { + mDepthBufferPoolId = poolId; + detachDepthBuffer(); + } + } + //----------------------------------------------------------------------- + uint16 RenderTarget::getDepthBufferPool() const + { + return mDepthBufferPoolId; + } + //----------------------------------------------------------------------- + DepthBuffer* RenderTarget::getDepthBuffer() const + { + return mDepthBuffer; + } + //----------------------------------------------------------------------- + bool RenderTarget::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + bool retVal = false; + + if( (retVal = depthBuffer->isCompatible( this )) ) + { + detachDepthBuffer(); + mDepthBuffer = depthBuffer; + mDepthBuffer->_notifyRenderTargetAttached( this ); + } + + return retVal; + } + //----------------------------------------------------------------------- + void RenderTarget::detachDepthBuffer() + { + if( mDepthBuffer ) + { + mDepthBuffer->_notifyRenderTargetDetached( this ); + mDepthBuffer = 0; + } + } + //----------------------------------------------------------------------- + void RenderTarget::_detachDepthBuffer() + { + mDepthBuffer = 0; + } void RenderTarget::updateImpl(void) { - _beginUpdate(); - _updateAutoUpdatedViewports(true); - _endUpdate(); + _beginUpdate(); + _updateAutoUpdatedViewports(true); + _endUpdate(); } - void RenderTarget::_beginUpdate() - { - // notify listeners (pre) + void RenderTarget::_beginUpdate() + { + // notify listeners (pre) firePreUpdate(); mStats.triangleCount = 0; mStats.batchCount = 0; - } + } - void RenderTarget::_updateAutoUpdatedViewports(bool updateStatistics) - { - // Go through viewports in Z-order + void RenderTarget::_updateAutoUpdatedViewports(bool updateStatistics) + { + // Go through viewports in Z-order // Tell each to refresh - ViewportList::iterator it = mViewportList.begin(); + ViewportList::iterator it = mViewportList.begin(); while (it != mViewportList.end()) { - Viewport* viewport = (*it).second; - if(viewport->isAutoUpdated()) - { - _updateViewport(viewport,updateStatistics); - } - ++it; - } - } - - void RenderTarget::_endUpdate() - { - // notify listeners (post) + Viewport* viewport = (*it).second; + if(viewport->isAutoUpdated()) + { + _updateViewport(viewport,updateStatistics); + } + ++it; + } + } + + void RenderTarget::_endUpdate() + { + // notify listeners (post) firePostUpdate(); // Update statistics (always on top) updateStats(); - } - - void RenderTarget::_updateViewport(Viewport* viewport, bool updateStatistics) - { - assert(viewport->getTarget() == this && - "RenderTarget::_updateViewport the requested viewport is " - "not bound to the rendertarget!"); - - fireViewportPreUpdate(viewport); - viewport->update(); - if(updateStatistics) - { - mStats.triangleCount += viewport->_getNumRenderedFaces(); - mStats.batchCount += viewport->_getNumRenderedBatches(); - } - fireViewportPostUpdate(viewport); - } - - void RenderTarget::_updateViewport(int zorder, bool updateStatistics) - { - ViewportList::iterator it = mViewportList.find(zorder); + } + + void RenderTarget::_updateViewport(Viewport* viewport, bool updateStatistics) + { + assert(viewport->getTarget() == this && + "RenderTarget::_updateViewport the requested viewport is " + "not bound to the rendertarget!"); + + fireViewportPreUpdate(viewport); + viewport->update(); + if(updateStatistics) + { + mStats.triangleCount += viewport->_getNumRenderedFaces(); + mStats.batchCount += viewport->_getNumRenderedBatches(); + } + fireViewportPostUpdate(viewport); + } + + void RenderTarget::_updateViewport(int zorder, bool updateStatistics) + { + ViewportList::iterator it = mViewportList.find(zorder); if (it != mViewportList.end()) { - _updateViewport((*it).second,updateStatistics); - } - else - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,"No viewport with given zorder : " - + StringConverter::toString(zorder), "RenderTarget::_updateViewport"); - } - } + _updateViewport((*it).second,updateStatistics); + } + else + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,"No viewport with given zorder : " + + StringConverter::toString(zorder), "RenderTarget::_updateViewport"); + } + } Viewport* RenderTarget::addViewport(Camera* cam, int ZOrder, float left, float top , float width , float height) - { + { // Check no existing viewport with this Z-order ViewportList::iterator it = mViewportList.find(ZOrder); if (it != mViewportList.end()) { - StringStream str; - str << "Can't create another viewport for " - << mName << " with Z-order " << ZOrder - << " because a viewport exists with this Z-order already."; - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, str.str(), "RenderTarget::addViewport"); + StringStream str; + str << "Can't create another viewport for " + << mName << " with Z-order " << ZOrder + << " because a viewport exists with this Z-order already."; + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, str.str(), "RenderTarget::addViewport"); } // Add viewport to list // Order based on Z-order @@ -240,18 +240,18 @@ namespace Ogre { mViewportList.insert(ViewportList::value_type(ZOrder, vp)); - fireViewportAdded(vp); + fireViewportAdded(vp); return vp; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void RenderTarget::removeViewport(int ZOrder) { ViewportList::iterator it = mViewportList.find(ZOrder); if (it != mViewportList.end()) { - fireViewportRemoved((*it).second); + fireViewportRemoved((*it).second); OGRE_DELETE (*it).second; mViewportList.erase(ZOrder); } @@ -336,7 +336,7 @@ namespace Ogre { mStats.batchCount = 0; mStats.bestFrameTime = 999999; mStats.worstFrameTime = 0; - mStats.vBlankMissCount = 0; + mStats.vBlankMissCount = 0; mLastTime = mTimer->getMilliseconds(); mLastSecond = mLastTime; @@ -450,22 +450,22 @@ namespace Ogre { ++i; return i->second; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- Viewport* RenderTarget::getViewportByZOrder(int ZOrder) { - ViewportList::iterator i = mViewportList.find(ZOrder); - if(i == mViewportList.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,"No viewport with given Z-order: " - + StringConverter::toString(ZOrder), "RenderTarget::getViewportByZOrder"); - } + ViewportList::iterator i = mViewportList.find(ZOrder); + if(i == mViewportList.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,"No viewport with given Z-order: " + + StringConverter::toString(ZOrder), "RenderTarget::getViewportByZOrder"); + } return i->second; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- bool RenderTarget::hasViewportWithZOrder(int ZOrder) { - ViewportList::iterator i = mViewportList.find(ZOrder); - return i != mViewportList.end(); + ViewportList::iterator i = mViewportList.find(ZOrder); + return i != mViewportList.end(); } //----------------------------------------------------------------------- bool RenderTarget::isActive() const @@ -505,38 +505,38 @@ namespace Ogre { (*i)->postViewportUpdate(evt); } } - //----------------------------------------------------------------------- - void RenderTarget::fireViewportAdded(Viewport* vp) - { - RenderTargetViewportEvent evt; - evt.source = vp; - - RenderTargetListenerList::iterator i, iend; - i = mListeners.begin(); - iend = mListeners.end(); - for(; i != iend; ++i) - { - (*i)->viewportAdded(evt); - } - } - //----------------------------------------------------------------------- - void RenderTarget::fireViewportRemoved(Viewport* vp) - { - RenderTargetViewportEvent evt; - evt.source = vp; - - // Make a temp copy of the listeners - // some will want to remove themselves as listeners when they get this - RenderTargetListenerList tempList = mListeners; - - RenderTargetListenerList::iterator i, iend; - i = tempList.begin(); - iend = tempList.end(); - for(; i != iend; ++i) - { - (*i)->viewportRemoved(evt); - } - } + //----------------------------------------------------------------------- + void RenderTarget::fireViewportAdded(Viewport* vp) + { + RenderTargetViewportEvent evt; + evt.source = vp; + + RenderTargetListenerList::iterator i, iend; + i = mListeners.begin(); + iend = mListeners.end(); + for(; i != iend; ++i) + { + (*i)->viewportAdded(evt); + } + } + //----------------------------------------------------------------------- + void RenderTarget::fireViewportRemoved(Viewport* vp) + { + RenderTargetViewportEvent evt; + evt.source = vp; + + // Make a temp copy of the listeners + // some will want to remove themselves as listeners when they get this + RenderTargetListenerList tempList = mListeners; + + RenderTargetListenerList::iterator i, iend; + i = tempList.begin(); + iend = tempList.end(); + for(; i != iend; ++i) + { + (*i)->viewportRemoved(evt); + } + } //----------------------------------------------------------------------- String RenderTarget::writeContentsToTimestampedFile(const String& filenamePrefix, const String& filenameSuffix) { @@ -544,7 +544,7 @@ namespace Ogre { time_t ctTime; time(&ctTime); pTime = localtime( &ctTime ); Ogre::StringStream oss; - oss << std::setw(2) << std::setfill('0') << (pTime->tm_mon + 1) + oss << std::setw(2) << std::setfill('0') << (pTime->tm_mon + 1) << std::setw(2) << std::setfill('0') << pTime->tm_mday << std::setw(2) << std::setfill('0') << (pTime->tm_year + 1900) << "_" << std::setw(2) << std::setfill('0') << pTime->tm_hour @@ -556,20 +556,20 @@ namespace Ogre { return filename; } - //----------------------------------------------------------------------- - void RenderTarget::writeContentsToFile(const String& filename) - { - PixelFormat pf = suggestPixelFormat(); + //----------------------------------------------------------------------- + void RenderTarget::writeContentsToFile(const String& filename) + { + PixelFormat pf = suggestPixelFormat(); - uchar *data = OGRE_ALLOC_T(uchar, mWidth * mHeight * PixelUtil::getNumElemBytes(pf), MEMCATEGORY_RENDERSYS); - PixelBox pb(mWidth, mHeight, 1, pf, data); + uchar *data = OGRE_ALLOC_T(uchar, mWidth * mHeight * PixelUtil::getNumElemBytes(pf), MEMCATEGORY_RENDERSYS); + PixelBox pb(mWidth, mHeight, 1, pf, data); - copyContentsToMemory(pb); + copyContentsToMemory(pb); - Image().loadDynamicImage(data, mWidth, mHeight, 1, pf, false, 1, 0).save(filename); + Image().loadDynamicImage(data, mWidth, mHeight, 1, pf, false, 1, 0).save(filename); - OGRE_FREE(data, MEMCATEGORY_RENDERSYS); - } + OGRE_FREE(data, MEMCATEGORY_RENDERSYS); + } //----------------------------------------------------------------------- void RenderTarget::_notifyCameraRemoved(const Camera* cam) { @@ -614,13 +614,13 @@ namespace Ogre { updateImpl(); - if (swap) - { - // Swap buffers - swapBuffers(); - } + if (swap) + { + // Swap buffers + swapBuffers(); + } OgreProfileEndGPUEvent("RenderTarget: " + getName()); } - + } diff --git a/OgreMain/src/OgreRenderTexture.cpp b/OgreMain/src/OgreRenderTexture.cpp index 4bc96df4707..e92e01e275d 100644 --- a/OgreMain/src/OgreRenderTexture.cpp +++ b/OgreMain/src/OgreRenderTexture.cpp @@ -35,50 +35,50 @@ namespace Ogre { //----------------------------------------------------------------------------- - RenderTexture::RenderTexture(HardwarePixelBuffer *buffer, uint32 zoffset): - mBuffer(buffer), mZOffset(zoffset) + RenderTexture::RenderTexture(HardwarePixelBuffer *buffer, uint32 zoffset): + mBuffer(buffer), mZOffset(zoffset) { mPriority = OGRE_REND_TO_TEX_RT_GROUP; - mWidth = mBuffer->getWidth(); - mHeight = mBuffer->getHeight(); + mWidth = mBuffer->getWidth(); + mHeight = mBuffer->getHeight(); mColourDepth = static_cast( - Ogre::PixelUtil::getNumElemBits(mBuffer->getFormat())); + Ogre::PixelUtil::getNumElemBits(mBuffer->getFormat())); } RenderTexture::~RenderTexture() { - mBuffer->_clearSliceRTT(0); + mBuffer->_clearSliceRTT(0); } - void RenderTexture::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) + void RenderTexture::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) { - if (buffer == FB_AUTO) buffer = FB_FRONT; - if (buffer != FB_FRONT) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid buffer.", - "RenderTexture::copyContentsToMemory" ); - } + if (buffer == FB_AUTO) buffer = FB_FRONT; + if (buffer != FB_FRONT) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid buffer.", + "RenderTexture::copyContentsToMemory" ); + } - mBuffer->blitToMemory(dst); - } - //--------------------------------------------------------------------- - PixelFormat RenderTexture::suggestPixelFormat() const - { - return mBuffer->getFormat(); - } - //----------------------------------------------------------------------------- - MultiRenderTarget::MultiRenderTarget(const String &name) + mBuffer->blitToMemory(dst); + } + //--------------------------------------------------------------------- + PixelFormat RenderTexture::suggestPixelFormat() const + { + return mBuffer->getFormat(); + } + //----------------------------------------------------------------------------- + MultiRenderTarget::MultiRenderTarget(const String &name) { mPriority = OGRE_REND_TO_TEX_RT_GROUP; - mName = name; - /// Width and height is unknown with no targets attached - mWidth = mHeight = 0; + mName = name; + /// Width and height is unknown with no targets attached + mWidth = mHeight = 0; + } + //----------------------------------------------------------------------------- + void MultiRenderTarget::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Cannot get MultiRenderTargets pixels", + "MultiRenderTarget::copyContentsToMemory"); } - //----------------------------------------------------------------------------- - void MultiRenderTarget::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Cannot get MultiRenderTargets pixels", - "MultiRenderTarget::copyContentsToMemory"); - } } diff --git a/OgreMain/src/OgreRenderWindow.cpp b/OgreMain/src/OgreRenderWindow.cpp index cf6d0cb3d9f..bab648543bd 100644 --- a/OgreMain/src/OgreRenderWindow.cpp +++ b/OgreMain/src/OgreRenderWindow.cpp @@ -38,7 +38,7 @@ namespace Ogre { //----------------------------------------------------------------------- void RenderWindow::getMetrics(unsigned int& width, unsigned int& height, unsigned int& colourDepth, - int& left, int& top) const + int& left, int& top) const { width = mWidth; height = mHeight; @@ -51,7 +51,7 @@ namespace Ogre { { return mIsFullScreen; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- bool RenderWindow::isPrimary(void) const { return mIsPrimary; diff --git a/OgreMain/src/OgreResource.cpp b/OgreMain/src/OgreResource.cpp index 331eeb3d7ba..52da647260f 100644 --- a/OgreMain/src/OgreResource.cpp +++ b/OgreMain/src/OgreResource.cpp @@ -35,85 +35,85 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - Resource::Resource(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader) - : mCreator(creator), mName(name), mGroup(group), mHandle(handle), - mLoadingState(LOADSTATE_UNLOADED), mIsBackgroundLoaded(false), - mSize(0), mIsManual(isManual), mLoader(loader), mStateCount(0) - { - } - //----------------------------------------------------------------------- - Resource::~Resource() - { - } - //----------------------------------------------------------------------- - void Resource::escalateLoading() - { - // Just call load as if this is the background thread, locking on - // load status will prevent race conditions - load(true); - _fireLoadingComplete(true); - } - //----------------------------------------------------------------------- - void Resource::prepare(bool background) - { + //----------------------------------------------------------------------- + Resource::Resource(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader) + : mCreator(creator), mName(name), mGroup(group), mHandle(handle), + mLoadingState(LOADSTATE_UNLOADED), mIsBackgroundLoaded(false), + mSize(0), mIsManual(isManual), mLoader(loader), mStateCount(0) + { + } + //----------------------------------------------------------------------- + Resource::~Resource() + { + } + //----------------------------------------------------------------------- + void Resource::escalateLoading() + { + // Just call load as if this is the background thread, locking on + // load status will prevent race conditions + load(true); + _fireLoadingComplete(true); + } + //----------------------------------------------------------------------- + void Resource::prepare(bool background) + { // quick check that avoids any synchronisation LoadingState old = mLoadingState.get(); if (old != LOADSTATE_UNLOADED && old != LOADSTATE_PREPARING) return; // atomically do slower check to make absolutely sure, // and set the load state to PREPARING - if (!mLoadingState.cas(LOADSTATE_UNLOADED,LOADSTATE_PREPARING)) - { - while( mLoadingState.get() == LOADSTATE_PREPARING ) - { + if (!mLoadingState.cas(LOADSTATE_UNLOADED,LOADSTATE_PREPARING)) + { + while( mLoadingState.get() == LOADSTATE_PREPARING ) + { OGRE_LOCK_AUTO_MUTEX; - } - - LoadingState state = mLoadingState.get(); - if( state != LOADSTATE_PREPARED && state != LOADSTATE_LOADING && state != LOADSTATE_LOADED ) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Another thread failed in resource operation", - "Resource::prepare"); - } - return; - } - - // Scope lock for actual loading + } + + LoadingState state = mLoadingState.get(); + if( state != LOADSTATE_PREPARED && state != LOADSTATE_LOADING && state != LOADSTATE_LOADED ) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Another thread failed in resource operation", + "Resource::prepare"); + } + return; + } + + // Scope lock for actual loading try - { + { OGRE_LOCK_AUTO_MUTEX; - if (mIsManual) - { + if (mIsManual) + { if (mLoader) - { - mLoader->prepareResource(this); - } - else - { - // Warn that this resource is not reloadable - LogManager::getSingleton().stream(LML_TRIVIAL) - << "WARNING: " << mCreator->getResourceType() - << " instance '" << mName << "' was defined as manually " - << "loaded, but no manual loader was provided. This Resource " - << "will be lost if it has to be reloaded."; - } - } - else - { - if (mGroup == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) - { - // Derive resource group - changeGroupOwnership( - ResourceGroupManager::getSingleton() - .findGroupContainingResource(mName)); - } - prepareImpl(); - } - } + { + mLoader->prepareResource(this); + } + else + { + // Warn that this resource is not reloadable + LogManager::getSingleton().stream(LML_TRIVIAL) + << "WARNING: " << mCreator->getResourceType() + << " instance '" << mName << "' was defined as manually " + << "loaded, but no manual loader was provided. This Resource " + << "will be lost if it has to be reloaded."; + } + } + else + { + if (mGroup == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) + { + // Derive resource group + changeGroupOwnership( + ResourceGroupManager::getSingleton() + .findGroupContainingResource(mName)); + } + prepareImpl(); + } + } catch (...) { mLoadingState.set(LOADSTATE_UNLOADED); @@ -122,126 +122,126 @@ namespace Ogre mLoadingState.set(LOADSTATE_PREPARED); - // Since we don't distinguish between GPU and CPU RAM, this - // seems pointless - //if(mCreator) - // mCreator->_notifyResourcePrepared(this); + // Since we don't distinguish between GPU and CPU RAM, this + // seems pointless + //if(mCreator) + // mCreator->_notifyResourcePrepared(this); - // Fire events (if not background) - if (!background) - _firePreparingComplete(false); + // Fire events (if not background) + if (!background) + _firePreparingComplete(false); - } - //--------------------------------------------------------------------- + } + //--------------------------------------------------------------------- void Resource::load(bool background) - { - // Early-out without lock (mitigate perf cost of ensuring loaded) - // Don't load if: - // 1. We're already loaded - // 2. Another thread is loading right now - // 3. We're marked for background loading and this is not the background - // loading thread we're being called by + { + // Early-out without lock (mitigate perf cost of ensuring loaded) + // Don't load if: + // 1. We're already loaded + // 2. Another thread is loading right now + // 3. We're marked for background loading and this is not the background + // loading thread we're being called by if (mIsBackgroundLoaded && !background) return; - // This next section is to deal with cases where 2 threads are fighting over - // who gets to prepare / load - this will only usually happen if loading is escalated - bool keepChecking = true; - LoadingState old = LOADSTATE_UNLOADED; - while (keepChecking) - { - // quick check that avoids any synchronisation - old = mLoadingState.get(); - - if ( old == LOADSTATE_PREPARING ) - { - while( mLoadingState.get() == LOADSTATE_PREPARING ) - { + // This next section is to deal with cases where 2 threads are fighting over + // who gets to prepare / load - this will only usually happen if loading is escalated + bool keepChecking = true; + LoadingState old = LOADSTATE_UNLOADED; + while (keepChecking) + { + // quick check that avoids any synchronisation + old = mLoadingState.get(); + + if ( old == LOADSTATE_PREPARING ) + { + while( mLoadingState.get() == LOADSTATE_PREPARING ) + { OGRE_LOCK_AUTO_MUTEX; - } - old = mLoadingState.get(); - } - - if (old!=LOADSTATE_UNLOADED && old!=LOADSTATE_PREPARED && old!=LOADSTATE_LOADING) return; - - // atomically do slower check to make absolutely sure, - // and set the load state to LOADING - if (old==LOADSTATE_LOADING || !mLoadingState.cas(old,LOADSTATE_LOADING)) - { - while( mLoadingState.get() == LOADSTATE_LOADING ) - { + } + old = mLoadingState.get(); + } + + if (old!=LOADSTATE_UNLOADED && old!=LOADSTATE_PREPARED && old!=LOADSTATE_LOADING) return; + + // atomically do slower check to make absolutely sure, + // and set the load state to LOADING + if (old==LOADSTATE_LOADING || !mLoadingState.cas(old,LOADSTATE_LOADING)) + { + while( mLoadingState.get() == LOADSTATE_LOADING ) + { OGRE_LOCK_AUTO_MUTEX; - } - - LoadingState state = mLoadingState.get(); - if( state == LOADSTATE_PREPARED || state == LOADSTATE_PREPARING ) - { - // another thread is preparing, loop around - continue; - } - else if( state != LOADSTATE_LOADED ) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Another thread failed in resource operation", - "Resource::load"); - } - return; - } - keepChecking = false; - } - - // Scope lock for actual loading + } + + LoadingState state = mLoadingState.get(); + if( state == LOADSTATE_PREPARED || state == LOADSTATE_PREPARING ) + { + // another thread is preparing, loop around + continue; + } + else if( state != LOADSTATE_LOADED ) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Another thread failed in resource operation", + "Resource::load"); + } + return; + } + keepChecking = false; + } + + // Scope lock for actual loading try - { + { OGRE_LOCK_AUTO_MUTEX; - if (mIsManual) - { + if (mIsManual) + { preLoadImpl(); - // Load from manual loader - if (mLoader) - { - mLoader->loadResource(this); - } - else - { - // Warn that this resource is not reloadable - LogManager::getSingleton().stream(LML_TRIVIAL) - << "WARNING: " << mCreator->getResourceType() - << " instance '" << mName << "' was defined as manually " - << "loaded, but no manual loader was provided. This Resource " - << "will be lost if it has to be reloaded."; - } + // Load from manual loader + if (mLoader) + { + mLoader->loadResource(this); + } + else + { + // Warn that this resource is not reloadable + LogManager::getSingleton().stream(LML_TRIVIAL) + << "WARNING: " << mCreator->getResourceType() + << " instance '" << mName << "' was defined as manually " + << "loaded, but no manual loader was provided. This Resource " + << "will be lost if it has to be reloaded."; + } postLoadImpl(); - } - else - { + } + else + { if (old==LOADSTATE_UNLOADED) prepareImpl(); preLoadImpl(); - if (mGroup == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) - { - // Derive resource group - changeGroupOwnership( - ResourceGroupManager::getSingleton() - .findGroupContainingResource(mName)); - } + if (mGroup == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) + { + // Derive resource group + changeGroupOwnership( + ResourceGroupManager::getSingleton() + .findGroupContainingResource(mName)); + } - loadImpl(); + loadImpl(); postLoadImpl(); - } + } - // Calculate resource size - mSize = calculateSize(); + // Calculate resource size + mSize = calculateSize(); - } + } catch (...) { // Reset loading in-progress flag, in case failed for some reason. @@ -256,16 +256,16 @@ namespace Ogre mLoadingState.set(LOADSTATE_LOADED); _dirtyState(); - // Notify manager - if(mCreator) - mCreator->_notifyResourceLoaded(this); + // Notify manager + if(mCreator) + mCreator->_notifyResourceLoaded(this); - // Fire events, if not background - if (!background) - _fireLoadingComplete(false); + // Fire events, if not background + if (!background) + _fireLoadingComplete(false); - } + } //--------------------------------------------------------------------- size_t Resource::calculateSize(void) const { @@ -283,36 +283,36 @@ namespace Ogre return memSize; } - //--------------------------------------------------------------------- - void Resource::_dirtyState() - { - // don't worry about threading here, count only ever increases so - // doesn't matter if we get a lost increment (one is enough) - ++mStateCount; - } - //----------------------------------------------------------------------- - void Resource::changeGroupOwnership(const String& newGroup) - { - if (mGroup != newGroup) - { - String oldGroup = mGroup; - mGroup = newGroup; - ResourceGroupManager::getSingleton() - ._notifyResourceGroupChanged(oldGroup, this); - } - } - //----------------------------------------------------------------------- - void Resource::unload(void) - { - // Early-out without lock (mitigate perf cost of ensuring unloaded) + //--------------------------------------------------------------------- + void Resource::_dirtyState() + { + // don't worry about threading here, count only ever increases so + // doesn't matter if we get a lost increment (one is enough) + ++mStateCount; + } + //----------------------------------------------------------------------- + void Resource::changeGroupOwnership(const String& newGroup) + { + if (mGroup != newGroup) + { + String oldGroup = mGroup; + mGroup = newGroup; + ResourceGroupManager::getSingleton() + ._notifyResourceGroupChanged(oldGroup, this); + } + } + //----------------------------------------------------------------------- + void Resource::unload(void) + { + // Early-out without lock (mitigate perf cost of ensuring unloaded) LoadingState old = mLoadingState.get(); if (old!=LOADSTATE_LOADED && old!=LOADSTATE_PREPARED) return; if (!mLoadingState.cas(old,LOADSTATE_UNLOADING)) return; - // Scope lock for actual unload - { + // Scope lock for actual unload + { OGRE_LOCK_AUTO_MUTEX; if (old==LOADSTATE_PREPARED) { unprepareImpl(); @@ -321,95 +321,95 @@ namespace Ogre unloadImpl(); postUnloadImpl(); } - } + } mLoadingState.set(LOADSTATE_UNLOADED); - // Notify manager - // Note if we have gone from PREPARED to UNLOADED, then we haven't actually - // unloaded, i.e. there is no memory freed on the GPU. - if(old==LOADSTATE_LOADED && mCreator) - mCreator->_notifyResourceUnloaded(this); + // Notify manager + // Note if we have gone from PREPARED to UNLOADED, then we haven't actually + // unloaded, i.e. there is no memory freed on the GPU. + if(old==LOADSTATE_LOADED && mCreator) + mCreator->_notifyResourceUnloaded(this); - _fireUnloadingComplete(); + _fireUnloadingComplete(); - } - //----------------------------------------------------------------------- - void Resource::reload(void) - { + } + //----------------------------------------------------------------------- + void Resource::reload(void) + { OGRE_LOCK_AUTO_MUTEX; - if (mLoadingState.get() == LOADSTATE_LOADED) - { - unload(); - load(); - } - } - //----------------------------------------------------------------------- - void Resource::touch(void) - { + if (mLoadingState.get() == LOADSTATE_LOADED) + { + unload(); + load(); + } + } + //----------------------------------------------------------------------- + void Resource::touch(void) + { // make sure loaded load(); - if(mCreator) - mCreator->_notifyResourceTouched(this); - } - //----------------------------------------------------------------------- - void Resource::addListener(Resource::Listener* lis) - { + if(mCreator) + mCreator->_notifyResourceTouched(this); + } + //----------------------------------------------------------------------- + void Resource::addListener(Resource::Listener* lis) + { OGRE_LOCK_MUTEX(mListenerListMutex); - mListenerList.insert(lis); - } - //----------------------------------------------------------------------- - void Resource::removeListener(Resource::Listener* lis) - { - // O(n) but not called very often + mListenerList.insert(lis); + } + //----------------------------------------------------------------------- + void Resource::removeListener(Resource::Listener* lis) + { + // O(n) but not called very often OGRE_LOCK_MUTEX(mListenerListMutex); - mListenerList.erase(lis); - } - //----------------------------------------------------------------------- - void Resource::_fireLoadingComplete(bool wasBackgroundLoaded) - { - // Lock the listener list + mListenerList.erase(lis); + } + //----------------------------------------------------------------------- + void Resource::_fireLoadingComplete(bool wasBackgroundLoaded) + { + // Lock the listener list OGRE_LOCK_MUTEX(mListenerListMutex); - for (ListenerList::iterator i = mListenerList.begin(); - i != mListenerList.end(); ++i) - { - // deprecated call - if (wasBackgroundLoaded) - (*i)->backgroundLoadingComplete(this); - - (*i)->loadingComplete(this); - } - } - //----------------------------------------------------------------------- - void Resource::_firePreparingComplete(bool wasBackgroundLoaded) - { - // Lock the listener list + for (ListenerList::iterator i = mListenerList.begin(); + i != mListenerList.end(); ++i) + { + // deprecated call + if (wasBackgroundLoaded) + (*i)->backgroundLoadingComplete(this); + + (*i)->loadingComplete(this); + } + } + //----------------------------------------------------------------------- + void Resource::_firePreparingComplete(bool wasBackgroundLoaded) + { + // Lock the listener list OGRE_LOCK_MUTEX(mListenerListMutex); - for (ListenerList::iterator i = mListenerList.begin(); - i != mListenerList.end(); ++i) - { - // deprecated call - if (wasBackgroundLoaded) - (*i)->backgroundPreparingComplete(this); - - (*i)->preparingComplete(this); - - } - } - //----------------------------------------------------------------------- - void Resource::_fireUnloadingComplete(void) - { - // Lock the listener list + for (ListenerList::iterator i = mListenerList.begin(); + i != mListenerList.end(); ++i) + { + // deprecated call + if (wasBackgroundLoaded) + (*i)->backgroundPreparingComplete(this); + + (*i)->preparingComplete(this); + + } + } + //----------------------------------------------------------------------- + void Resource::_fireUnloadingComplete(void) + { + // Lock the listener list OGRE_LOCK_MUTEX(mListenerListMutex); - for (ListenerList::iterator i = mListenerList.begin(); - i != mListenerList.end(); ++i) - { + for (ListenerList::iterator i = mListenerList.begin(); + i != mListenerList.end(); ++i) + { - (*i)->unloadingComplete(this); + (*i)->unloadingComplete(this); - } - } + } + } } diff --git a/OgreMain/src/OgreResourceBackgroundQueue.cpp b/OgreMain/src/OgreResourceBackgroundQueue.cpp index 1cb8af3c19f..4fce50ff845 100644 --- a/OgreMain/src/OgreResourceBackgroundQueue.cpp +++ b/OgreMain/src/OgreResourceBackgroundQueue.cpp @@ -33,9 +33,9 @@ THE SOFTWARE. namespace Ogre { - // Note, no locks are required here anymore because all of the parallelisation - // is now contained in WorkQueue - this class is entirely single-threaded - //------------------------------------------------------------------------ + // Note, no locks are required here anymore because all of the parallelisation + // is now contained in WorkQueue - this class is entirely single-threaded + //------------------------------------------------------------------------ //----------------------------------------------------------------------- template<> ResourceBackgroundQueue* Singleton::msSingleton = 0; ResourceBackgroundQueue* ResourceBackgroundQueue::getSingletonPtr(void) @@ -46,409 +46,409 @@ namespace Ogre { { assert( msSingleton ); return ( *msSingleton ); } - //----------------------------------------------------------------------- - //------------------------------------------------------------------------ - ResourceBackgroundQueue::ResourceBackgroundQueue() : mWorkQueueChannel(0) - { - } - //------------------------------------------------------------------------ - ResourceBackgroundQueue::~ResourceBackgroundQueue() - { - shutdown(); - } - //--------------------------------------------------------------------- - void ResourceBackgroundQueue::initialise() - { - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - mWorkQueueChannel = wq->getChannel("Ogre/ResourceBGQ"); - wq->addResponseHandler(mWorkQueueChannel, this); - wq->addRequestHandler(mWorkQueueChannel, this); - } - //--------------------------------------------------------------------- - void ResourceBackgroundQueue::shutdown() - { - WorkQueue* wq = Root::getSingleton().getWorkQueue(); - wq->abortRequestsByChannel(mWorkQueueChannel); - wq->removeRequestHandler(mWorkQueueChannel, this); - wq->removeResponseHandler(mWorkQueueChannel, this); - } - //------------------------------------------------------------------------ - BackgroundProcessTicket ResourceBackgroundQueue::initialiseResourceGroup( - const String& name, ResourceBackgroundQueue::Listener* listener) - { + //----------------------------------------------------------------------- + //------------------------------------------------------------------------ + ResourceBackgroundQueue::ResourceBackgroundQueue() : mWorkQueueChannel(0) + { + } + //------------------------------------------------------------------------ + ResourceBackgroundQueue::~ResourceBackgroundQueue() + { + shutdown(); + } + //--------------------------------------------------------------------- + void ResourceBackgroundQueue::initialise() + { + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + mWorkQueueChannel = wq->getChannel("Ogre/ResourceBGQ"); + wq->addResponseHandler(mWorkQueueChannel, this); + wq->addRequestHandler(mWorkQueueChannel, this); + } + //--------------------------------------------------------------------- + void ResourceBackgroundQueue::shutdown() + { + WorkQueue* wq = Root::getSingleton().getWorkQueue(); + wq->abortRequestsByChannel(mWorkQueueChannel); + wq->removeRequestHandler(mWorkQueueChannel, this); + wq->removeResponseHandler(mWorkQueueChannel, this); + } + //------------------------------------------------------------------------ + BackgroundProcessTicket ResourceBackgroundQueue::initialiseResourceGroup( + const String& name, ResourceBackgroundQueue::Listener* listener) + { #if OGRE_THREAD_SUPPORT - // queue a request - ResourceRequest req; - req.type = RT_INITIALISE_GROUP; - req.groupName = name; - req.listener = listener; - return addRequest(req); + // queue a request + ResourceRequest req; + req.type = RT_INITIALISE_GROUP; + req.groupName = name; + req.listener = listener; + return addRequest(req); #else - // synchronous - ResourceGroupManager::getSingleton().initialiseResourceGroup(name); - return 0; + // synchronous + ResourceGroupManager::getSingleton().initialiseResourceGroup(name); + return 0; #endif - } - //------------------------------------------------------------------------ - BackgroundProcessTicket - ResourceBackgroundQueue::initialiseAllResourceGroups( - ResourceBackgroundQueue::Listener* listener) - { + } + //------------------------------------------------------------------------ + BackgroundProcessTicket + ResourceBackgroundQueue::initialiseAllResourceGroups( + ResourceBackgroundQueue::Listener* listener) + { #if OGRE_THREAD_SUPPORT - // queue a request - ResourceRequest req; - req.type = RT_INITIALISE_ALL_GROUPS; - req.listener = listener; - return addRequest(req); + // queue a request + ResourceRequest req; + req.type = RT_INITIALISE_ALL_GROUPS; + req.listener = listener; + return addRequest(req); #else - // synchronous - ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - return 0; + // synchronous + ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + return 0; #endif - } - //------------------------------------------------------------------------ - BackgroundProcessTicket ResourceBackgroundQueue::prepareResourceGroup( - const String& name, ResourceBackgroundQueue::Listener* listener) - { + } + //------------------------------------------------------------------------ + BackgroundProcessTicket ResourceBackgroundQueue::prepareResourceGroup( + const String& name, ResourceBackgroundQueue::Listener* listener) + { #if OGRE_THREAD_SUPPORT - // queue a request - ResourceRequest req; - req.type = RT_PREPARE_GROUP; - req.groupName = name; - req.listener = listener; - return addRequest(req); + // queue a request + ResourceRequest req; + req.type = RT_PREPARE_GROUP; + req.groupName = name; + req.listener = listener; + return addRequest(req); #else - // synchronous - ResourceGroupManager::getSingleton().prepareResourceGroup(name); - return 0; + // synchronous + ResourceGroupManager::getSingleton().prepareResourceGroup(name); + return 0; #endif - } - //------------------------------------------------------------------------ - BackgroundProcessTicket ResourceBackgroundQueue::loadResourceGroup( - const String& name, ResourceBackgroundQueue::Listener* listener) - { + } + //------------------------------------------------------------------------ + BackgroundProcessTicket ResourceBackgroundQueue::loadResourceGroup( + const String& name, ResourceBackgroundQueue::Listener* listener) + { #if OGRE_THREAD_SUPPORT - // queue a request - ResourceRequest req; - req.type = RT_LOAD_GROUP; - req.groupName = name; - req.listener = listener; - return addRequest(req); + // queue a request + ResourceRequest req; + req.type = RT_LOAD_GROUP; + req.groupName = name; + req.listener = listener; + return addRequest(req); #else - // synchronous - ResourceGroupManager::getSingleton().loadResourceGroup(name); - return 0; + // synchronous + ResourceGroupManager::getSingleton().loadResourceGroup(name); + return 0; #endif - } - //------------------------------------------------------------------------ - BackgroundProcessTicket ResourceBackgroundQueue::prepare( - const String& resType, const String& name, - const String& group, bool isManual, - ManualResourceLoader* loader, - const NameValuePairList* loadParams, - ResourceBackgroundQueue::Listener* listener) - { + } + //------------------------------------------------------------------------ + BackgroundProcessTicket ResourceBackgroundQueue::prepare( + const String& resType, const String& name, + const String& group, bool isManual, + ManualResourceLoader* loader, + const NameValuePairList* loadParams, + ResourceBackgroundQueue::Listener* listener) + { #if OGRE_THREAD_SUPPORT - // queue a request - ResourceRequest req; - req.type = RT_PREPARE_RESOURCE; - req.resourceType = resType; - req.resourceName = name; - req.groupName = group; - req.isManual = isManual; - req.loader = loader; - // Make instance copy of loadParams for thread independence - req.loadParams = ( loadParams ? OGRE_NEW_T(NameValuePairList, MEMCATEGORY_GENERAL)( *loadParams ) : 0 ); - req.listener = listener; - return addRequest(req); + // queue a request + ResourceRequest req; + req.type = RT_PREPARE_RESOURCE; + req.resourceType = resType; + req.resourceName = name; + req.groupName = group; + req.isManual = isManual; + req.loader = loader; + // Make instance copy of loadParams for thread independence + req.loadParams = ( loadParams ? OGRE_NEW_T(NameValuePairList, MEMCATEGORY_GENERAL)( *loadParams ) : 0 ); + req.listener = listener; + return addRequest(req); #else - // synchronous - ResourceManager* rm = - ResourceGroupManager::getSingleton()._getResourceManager(resType); - rm->prepare(name, group, isManual, loader, loadParams); - return 0; + // synchronous + ResourceManager* rm = + ResourceGroupManager::getSingleton()._getResourceManager(resType); + rm->prepare(name, group, isManual, loader, loadParams); + return 0; #endif - } - //------------------------------------------------------------------------ - BackgroundProcessTicket ResourceBackgroundQueue::load( - const String& resType, const String& name, - const String& group, bool isManual, - ManualResourceLoader* loader, - const NameValuePairList* loadParams, - ResourceBackgroundQueue::Listener* listener) - { + } + //------------------------------------------------------------------------ + BackgroundProcessTicket ResourceBackgroundQueue::load( + const String& resType, const String& name, + const String& group, bool isManual, + ManualResourceLoader* loader, + const NameValuePairList* loadParams, + ResourceBackgroundQueue::Listener* listener) + { #if OGRE_THREAD_SUPPORT - // queue a request - ResourceRequest req; - req.type = RT_LOAD_RESOURCE; - req.resourceType = resType; - req.resourceName = name; - req.groupName = group; - req.isManual = isManual; - req.loader = loader; - // Make instance copy of loadParams for thread independence - req.loadParams = ( loadParams ? OGRE_NEW_T(NameValuePairList, MEMCATEGORY_GENERAL)( *loadParams ) : 0 ); - req.listener = listener; - return addRequest(req); + // queue a request + ResourceRequest req; + req.type = RT_LOAD_RESOURCE; + req.resourceType = resType; + req.resourceName = name; + req.groupName = group; + req.isManual = isManual; + req.loader = loader; + // Make instance copy of loadParams for thread independence + req.loadParams = ( loadParams ? OGRE_NEW_T(NameValuePairList, MEMCATEGORY_GENERAL)( *loadParams ) : 0 ); + req.listener = listener; + return addRequest(req); #else - // synchronous - ResourceManager* rm = - ResourceGroupManager::getSingleton()._getResourceManager(resType); - rm->load(name, group, isManual, loader, loadParams); - return 0; + // synchronous + ResourceManager* rm = + ResourceGroupManager::getSingleton()._getResourceManager(resType); + rm->load(name, group, isManual, loader, loadParams); + return 0; #endif - } - //--------------------------------------------------------------------- - BackgroundProcessTicket ResourceBackgroundQueue::unload( - const String& resType, const String& name, Listener* listener) - { + } + //--------------------------------------------------------------------- + BackgroundProcessTicket ResourceBackgroundQueue::unload( + const String& resType, const String& name, Listener* listener) + { #if OGRE_THREAD_SUPPORT - // queue a request - ResourceRequest req; - req.type = RT_UNLOAD_RESOURCE; - req.resourceType = resType; - req.resourceName = name; - req.listener = listener; - return addRequest(req); + // queue a request + ResourceRequest req; + req.type = RT_UNLOAD_RESOURCE; + req.resourceType = resType; + req.resourceName = name; + req.listener = listener; + return addRequest(req); #else - // synchronous - ResourceManager* rm = - ResourceGroupManager::getSingleton()._getResourceManager(resType); - rm->unload(name); - return 0; + // synchronous + ResourceManager* rm = + ResourceGroupManager::getSingleton()._getResourceManager(resType); + rm->unload(name); + return 0; #endif - } - //--------------------------------------------------------------------- - BackgroundProcessTicket ResourceBackgroundQueue::unload( - const String& resType, ResourceHandle handle, Listener* listener) - { + } + //--------------------------------------------------------------------- + BackgroundProcessTicket ResourceBackgroundQueue::unload( + const String& resType, ResourceHandle handle, Listener* listener) + { #if OGRE_THREAD_SUPPORT - // queue a request - ResourceRequest req; - req.type = RT_UNLOAD_RESOURCE; - req.resourceType = resType; - req.resourceHandle = handle; - req.listener = listener; - return addRequest(req); + // queue a request + ResourceRequest req; + req.type = RT_UNLOAD_RESOURCE; + req.resourceType = resType; + req.resourceHandle = handle; + req.listener = listener; + return addRequest(req); #else - // synchronous - ResourceManager* rm = - ResourceGroupManager::getSingleton()._getResourceManager(resType); - rm->unload(handle); - return 0; + // synchronous + ResourceManager* rm = + ResourceGroupManager::getSingleton()._getResourceManager(resType); + rm->unload(handle); + return 0; #endif - } - //--------------------------------------------------------------------- - BackgroundProcessTicket ResourceBackgroundQueue::unloadResourceGroup( - const String& name, Listener* listener) - { + } + //--------------------------------------------------------------------- + BackgroundProcessTicket ResourceBackgroundQueue::unloadResourceGroup( + const String& name, Listener* listener) + { #if OGRE_THREAD_SUPPORT - // queue a request - ResourceRequest req; - req.type = RT_UNLOAD_GROUP; - req.groupName = name; - req.listener = listener; - return addRequest(req); + // queue a request + ResourceRequest req; + req.type = RT_UNLOAD_GROUP; + req.groupName = name; + req.listener = listener; + return addRequest(req); #else - // synchronous - ResourceGroupManager::getSingleton().unloadResourceGroup(name); - return 0; + // synchronous + ResourceGroupManager::getSingleton().unloadResourceGroup(name); + return 0; #endif - } - //------------------------------------------------------------------------ - bool ResourceBackgroundQueue::isProcessComplete( - BackgroundProcessTicket ticket) - { - return mOutstandingRequestSet.find(ticket) == mOutstandingRequestSet.end(); - } - //------------------------------------------------------------------------ + } + //------------------------------------------------------------------------ + bool ResourceBackgroundQueue::isProcessComplete( + BackgroundProcessTicket ticket) + { + return mOutstandingRequestSet.find(ticket) == mOutstandingRequestSet.end(); + } + //------------------------------------------------------------------------ void ResourceBackgroundQueue::abortRequest( BackgroundProcessTicket ticket ) { - WorkQueue* queue = Root::getSingleton().getWorkQueue(); - - queue->abortRequest( ticket ); - } - //------------------------------------------------------------------------ - BackgroundProcessTicket ResourceBackgroundQueue::addRequest(ResourceRequest& req) - { - WorkQueue* queue = Root::getSingleton().getWorkQueue(); - - Any data(req); - - WorkQueue::RequestID requestID = - queue->addRequest(mWorkQueueChannel, (uint16)req.type, data); - - - mOutstandingRequestSet.insert(requestID); - - return requestID; - } - //----------------------------------------------------------------------- - bool ResourceBackgroundQueue::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - return true; - } - //----------------------------------------------------------------------- - WorkQueue::Response* ResourceBackgroundQueue::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) - { - - ResourceRequest resreq = any_cast(req->getData()); - - if( req->getAborted() ) - { - if( resreq.type == RT_PREPARE_RESOURCE || resreq.type == RT_LOAD_RESOURCE ) - { - OGRE_DELETE_T(resreq.loadParams, NameValuePairList, MEMCATEGORY_GENERAL); - resreq.loadParams = 0; - } - resreq.result.error = false; - ResourceResponse resresp(ResourcePtr(), resreq); - return OGRE_NEW WorkQueue::Response(req, true, Any(resresp)); - } - - ResourceManager* rm = 0; - ResourcePtr resource; - try - { - - switch (resreq.type) - { - case RT_INITIALISE_GROUP: - ResourceGroupManager::getSingleton().initialiseResourceGroup( - resreq.groupName); - break; - case RT_INITIALISE_ALL_GROUPS: - ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - break; - case RT_PREPARE_GROUP: - ResourceGroupManager::getSingleton().prepareResourceGroup( - resreq.groupName); - break; - case RT_LOAD_GROUP: - #if OGRE_THREAD_SUPPORT == 2 - ResourceGroupManager::getSingleton().prepareResourceGroup( - resreq.groupName); - #else - ResourceGroupManager::getSingleton().loadResourceGroup( - resreq.groupName); - #endif - break; - case RT_UNLOAD_GROUP: - ResourceGroupManager::getSingleton().unloadResourceGroup( - resreq.groupName); - break; - case RT_PREPARE_RESOURCE: - rm = ResourceGroupManager::getSingleton()._getResourceManager( - resreq.resourceType); - resource = rm->prepare(resreq.resourceName, resreq.groupName, resreq.isManual, - resreq.loader, resreq.loadParams, true); - break; - case RT_LOAD_RESOURCE: - rm = ResourceGroupManager::getSingleton()._getResourceManager( - resreq.resourceType); - #if OGRE_THREAD_SUPPORT == 2 - resource = rm->prepare(resreq.resourceName, resreq.groupName, resreq.isManual, - resreq.loader, resreq.loadParams, true); - #else - resource = rm->load(resreq.resourceName, resreq.groupName, resreq.isManual, - resreq.loader, resreq.loadParams, true); - #endif - break; - case RT_UNLOAD_RESOURCE: - rm = ResourceGroupManager::getSingleton()._getResourceManager( - resreq.resourceType); - if (resreq.resourceName.empty()) - rm->unload(resreq.resourceHandle); - else - rm->unload(resreq.resourceName); - break; - }; - } - catch (Exception& e) - { - if( resreq.type == RT_PREPARE_RESOURCE || resreq.type == RT_LOAD_RESOURCE ) - { - OGRE_DELETE_T(resreq.loadParams, NameValuePairList, MEMCATEGORY_GENERAL); - resreq.loadParams = 0; - } - resreq.result.error = true; - resreq.result.message = e.getFullDescription(); - - // return error response - ResourceResponse resresp(resource, resreq); - return OGRE_NEW WorkQueue::Response(req, false, Any(resresp), e.getFullDescription()); - } - - - // success - if( resreq.type == RT_PREPARE_RESOURCE || resreq.type == RT_LOAD_RESOURCE ) - { - OGRE_DELETE_T(resreq.loadParams, NameValuePairList, MEMCATEGORY_GENERAL); - resreq.loadParams = 0; - } - resreq.result.error = false; - ResourceResponse resresp(resource, resreq); - return OGRE_NEW WorkQueue::Response(req, true, Any(resresp)); - - } - //------------------------------------------------------------------------ - bool ResourceBackgroundQueue::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - return true; - } - //------------------------------------------------------------------------ - void ResourceBackgroundQueue::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) - { - if( res->getRequest()->getAborted() ) - { - mOutstandingRequestSet.erase(res->getRequest()->getID()); - return ; - } - - ResourceResponse resresp = any_cast(res->getData()); - - // Complete full loading in main thread if semithreading - const ResourceRequest& req = resresp.request; - - if (res->succeeded()) - { + WorkQueue* queue = Root::getSingleton().getWorkQueue(); + + queue->abortRequest( ticket ); + } + //------------------------------------------------------------------------ + BackgroundProcessTicket ResourceBackgroundQueue::addRequest(ResourceRequest& req) + { + WorkQueue* queue = Root::getSingleton().getWorkQueue(); + + Any data(req); + + WorkQueue::RequestID requestID = + queue->addRequest(mWorkQueueChannel, (uint16)req.type, data); + + + mOutstandingRequestSet.insert(requestID); + + return requestID; + } + //----------------------------------------------------------------------- + bool ResourceBackgroundQueue::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + return true; + } + //----------------------------------------------------------------------- + WorkQueue::Response* ResourceBackgroundQueue::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ) + { + + ResourceRequest resreq = any_cast(req->getData()); + + if( req->getAborted() ) + { + if( resreq.type == RT_PREPARE_RESOURCE || resreq.type == RT_LOAD_RESOURCE ) + { + OGRE_DELETE_T(resreq.loadParams, NameValuePairList, MEMCATEGORY_GENERAL); + resreq.loadParams = 0; + } + resreq.result.error = false; + ResourceResponse resresp(ResourcePtr(), resreq); + return OGRE_NEW WorkQueue::Response(req, true, Any(resresp)); + } + + ResourceManager* rm = 0; + ResourcePtr resource; + try + { + + switch (resreq.type) + { + case RT_INITIALISE_GROUP: + ResourceGroupManager::getSingleton().initialiseResourceGroup( + resreq.groupName); + break; + case RT_INITIALISE_ALL_GROUPS: + ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + break; + case RT_PREPARE_GROUP: + ResourceGroupManager::getSingleton().prepareResourceGroup( + resreq.groupName); + break; + case RT_LOAD_GROUP: + #if OGRE_THREAD_SUPPORT == 2 + ResourceGroupManager::getSingleton().prepareResourceGroup( + resreq.groupName); + #else + ResourceGroupManager::getSingleton().loadResourceGroup( + resreq.groupName); + #endif + break; + case RT_UNLOAD_GROUP: + ResourceGroupManager::getSingleton().unloadResourceGroup( + resreq.groupName); + break; + case RT_PREPARE_RESOURCE: + rm = ResourceGroupManager::getSingleton()._getResourceManager( + resreq.resourceType); + resource = rm->prepare(resreq.resourceName, resreq.groupName, resreq.isManual, + resreq.loader, resreq.loadParams, true); + break; + case RT_LOAD_RESOURCE: + rm = ResourceGroupManager::getSingleton()._getResourceManager( + resreq.resourceType); + #if OGRE_THREAD_SUPPORT == 2 + resource = rm->prepare(resreq.resourceName, resreq.groupName, resreq.isManual, + resreq.loader, resreq.loadParams, true); + #else + resource = rm->load(resreq.resourceName, resreq.groupName, resreq.isManual, + resreq.loader, resreq.loadParams, true); + #endif + break; + case RT_UNLOAD_RESOURCE: + rm = ResourceGroupManager::getSingleton()._getResourceManager( + resreq.resourceType); + if (resreq.resourceName.empty()) + rm->unload(resreq.resourceHandle); + else + rm->unload(resreq.resourceName); + break; + }; + } + catch (Exception& e) + { + if( resreq.type == RT_PREPARE_RESOURCE || resreq.type == RT_LOAD_RESOURCE ) + { + OGRE_DELETE_T(resreq.loadParams, NameValuePairList, MEMCATEGORY_GENERAL); + resreq.loadParams = 0; + } + resreq.result.error = true; + resreq.result.message = e.getFullDescription(); + + // return error response + ResourceResponse resresp(resource, resreq); + return OGRE_NEW WorkQueue::Response(req, false, Any(resresp), e.getFullDescription()); + } + + + // success + if( resreq.type == RT_PREPARE_RESOURCE || resreq.type == RT_LOAD_RESOURCE ) + { + OGRE_DELETE_T(resreq.loadParams, NameValuePairList, MEMCATEGORY_GENERAL); + resreq.loadParams = 0; + } + resreq.result.error = false; + ResourceResponse resresp(resource, resreq); + return OGRE_NEW WorkQueue::Response(req, true, Any(resresp)); + + } + //------------------------------------------------------------------------ + bool ResourceBackgroundQueue::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + return true; + } + //------------------------------------------------------------------------ + void ResourceBackgroundQueue::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) + { + if( res->getRequest()->getAborted() ) + { + mOutstandingRequestSet.erase(res->getRequest()->getID()); + return ; + } + + ResourceResponse resresp = any_cast(res->getData()); + + // Complete full loading in main thread if semithreading + const ResourceRequest& req = resresp.request; + + if (res->succeeded()) + { #if OGRE_THREAD_SUPPORT == 2 - // These load commands would have been downgraded to prepare() for the background - if (req.type == RT_LOAD_RESOURCE) - { - ResourceManager *rm = ResourceGroupManager::getSingleton() - ._getResourceManager(req.resourceType); - rm->load(req.resourceName, req.groupName, req.isManual, req.loader, req.loadParams, true); - } - else if (req.type == RT_LOAD_GROUP) - { - ResourceGroupManager::getSingleton().loadResourceGroup(req.groupName); - } + // These load commands would have been downgraded to prepare() for the background + if (req.type == RT_LOAD_RESOURCE) + { + ResourceManager *rm = ResourceGroupManager::getSingleton() + ._getResourceManager(req.resourceType); + rm->load(req.resourceName, req.groupName, req.isManual, req.loader, req.loadParams, true); + } + else if (req.type == RT_LOAD_GROUP) + { + ResourceGroupManager::getSingleton().loadResourceGroup(req.groupName); + } #endif - mOutstandingRequestSet.erase(res->getRequest()->getID()); - - // Call resource listener - if (!resresp.resource.isNull()) - { - - if (req.type == RT_LOAD_RESOURCE) - { - resresp.resource->_fireLoadingComplete( true ); - } - else - { - resresp.resource->_firePreparingComplete( true ); - } - } - } + mOutstandingRequestSet.erase(res->getRequest()->getID()); + + // Call resource listener + if (!resresp.resource.isNull()) + { + + if (req.type == RT_LOAD_RESOURCE) + { + resresp.resource->_fireLoadingComplete( true ); + } + else + { + resresp.resource->_firePreparingComplete( true ); + } + } + } // Call queue listener if (req.listener) req.listener->operationCompleted(res->getRequest()->getID(), req.result); - } - //------------------------------------------------------------------------ + } + //------------------------------------------------------------------------ } diff --git a/OgreMain/src/OgreResourceGroupManager.cpp b/OgreMain/src/OgreResourceGroupManager.cpp index 351661cef68..29c6fdaff89 100644 --- a/OgreMain/src/OgreResourceGroupManager.cpp +++ b/OgreMain/src/OgreResourceGroupManager.cpp @@ -47,12 +47,12 @@ namespace Ogre { { assert( msSingleton ); return ( *msSingleton ); } - String ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME = "General"; - String ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME = "Internal"; - String ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME = "Autodetect"; - // A reference count of 3 means that only RGM and RM have references - // RGM has one (this one) and RM has 2 (by name and by handle) - size_t ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS = 3; + String ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME = "General"; + String ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME = "Internal"; + String ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME = "Autodetect"; + // A reference count of 3 means that only RGM and RM have references + // RGM has one (this one) and RM has 2 (by name and by handle) + size_t ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS = 3; //----------------------------------------------------------------------- //----------------------------------------------------------------------- ResourceGroupManager::ResourceGroupManager() @@ -62,8 +62,8 @@ namespace Ogre { createResourceGroup(DEFAULT_RESOURCE_GROUP_NAME); // Create the 'Internal' group createResourceGroup(INTERNAL_RESOURCE_GROUP_NAME); - // Create the 'Autodetect' group (only used for temp storage) - createResourceGroup(AUTODETECT_RESOURCE_GROUP_NAME); + // Create the 'Autodetect' group (only used for temp storage) + createResourceGroup(AUTODETECT_RESOURCE_GROUP_NAME); // default world group to the default group mWorldGroupName = DEFAULT_RESOURCE_GROUP_NAME; } @@ -75,7 +75,7 @@ namespace Ogre { iend = mResourceGroupMap.end(); for (i = mResourceGroupMap.begin(); i != iend; ++i) { - deleteGroup(i->second); + deleteGroup(i->second); } mResourceGroupMap.clear(); } @@ -84,7 +84,7 @@ namespace Ogre { { OGRE_LOCK_AUTO_MUTEX; - LogManager::getSingleton().logMessage("Creating resource group " + name); + LogManager::getSingleton().logMessage("Creating resource group " + name); if (getResourceGroup(name)) { OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, @@ -92,456 +92,456 @@ namespace Ogre { "ResourceGroupManager::createResourceGroup"); } ResourceGroup* grp = OGRE_NEW_T(ResourceGroup, MEMCATEGORY_RESOURCE)(); - grp->groupStatus = ResourceGroup::UNINITIALSED; + grp->groupStatus = ResourceGroup::UNINITIALSED; grp->name = name; - grp->inGlobalPool = inGlobalPool; + grp->inGlobalPool = inGlobalPool; grp->worldGeometrySceneManager = 0; mResourceGroupMap.insert( ResourceGroupMap::value_type(name, grp)); } - //----------------------------------------------------------------------- - void ResourceGroupManager::initialiseResourceGroup(const String& name) - { + //----------------------------------------------------------------------- + void ResourceGroupManager::initialiseResourceGroup(const String& name) + { OGRE_LOCK_AUTO_MUTEX; - LogManager::getSingleton().logMessage("Initialising resource group " + name); - ResourceGroup* grp = getResourceGroup(name); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + name, - "ResourceGroupManager::initialiseResourceGroup"); - } - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex; - - if (grp->groupStatus == ResourceGroup::UNINITIALSED) - { - // in the process of initialising - grp->groupStatus = ResourceGroup::INITIALISING; - // Set current group - parseResourceGroupScripts(grp); - mCurrentGroup = grp; - LogManager::getSingleton().logMessage("Creating resources for group " + name); - createDeclaredResources(grp); - grp->groupStatus = ResourceGroup::INITIALISED; - LogManager::getSingleton().logMessage("All done"); - // Reset current group - mCurrentGroup = 0; - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::initialiseAllResourceGroups(void) - { + LogManager::getSingleton().logMessage("Initialising resource group " + name); + ResourceGroup* grp = getResourceGroup(name); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + name, + "ResourceGroupManager::initialiseResourceGroup"); + } + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex; + + if (grp->groupStatus == ResourceGroup::UNINITIALSED) + { + // in the process of initialising + grp->groupStatus = ResourceGroup::INITIALISING; + // Set current group + parseResourceGroupScripts(grp); + mCurrentGroup = grp; + LogManager::getSingleton().logMessage("Creating resources for group " + name); + createDeclaredResources(grp); + grp->groupStatus = ResourceGroup::INITIALISED; + LogManager::getSingleton().logMessage("All done"); + // Reset current group + mCurrentGroup = 0; + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::initialiseAllResourceGroups(void) + { OGRE_LOCK_AUTO_MUTEX; - // Intialise all declared resource groups - ResourceGroupMap::iterator i, iend; - iend = mResourceGroupMap.end(); - for (i = mResourceGroupMap.begin(); i != iend; ++i) - { - ResourceGroup* grp = i->second; - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - if (grp->groupStatus == ResourceGroup::UNINITIALSED) - { - // in the process of initialising - grp->groupStatus = ResourceGroup::INITIALISING; - // Set current group - mCurrentGroup = grp; - parseResourceGroupScripts(grp); - LogManager::getSingleton().logMessage("Creating resources for group " + i->first); - createDeclaredResources(grp); - grp->groupStatus = ResourceGroup::INITIALISED; - LogManager::getSingleton().logMessage("All done"); - // Reset current group - mCurrentGroup = 0; - } - } - } + // Intialise all declared resource groups + ResourceGroupMap::iterator i, iend; + iend = mResourceGroupMap.end(); + for (i = mResourceGroupMap.begin(); i != iend; ++i) + { + ResourceGroup* grp = i->second; + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + if (grp->groupStatus == ResourceGroup::UNINITIALSED) + { + // in the process of initialising + grp->groupStatus = ResourceGroup::INITIALISING; + // Set current group + mCurrentGroup = grp; + parseResourceGroupScripts(grp); + LogManager::getSingleton().logMessage("Creating resources for group " + i->first); + createDeclaredResources(grp); + grp->groupStatus = ResourceGroup::INITIALISED; + LogManager::getSingleton().logMessage("All done"); + // Reset current group + mCurrentGroup = 0; + } + } + } //----------------------------------------------------------------------- void ResourceGroupManager::prepareResourceGroup(const String& name, - bool prepareMainResources, bool prepareWorldGeom) + bool prepareMainResources, bool prepareWorldGeom) { - // Can only bulk-load one group at a time (reasonable limitation I think) + // Can only bulk-load one group at a time (reasonable limitation I think) OGRE_LOCK_AUTO_MUTEX; - LogManager::getSingleton().stream() - << "Preparing resource group '" << name << "' - Resources: " - << prepareMainResources << " World Geometry: " << prepareWorldGeom; - // load all created resources - ResourceGroup* grp = getResourceGroup(name); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + name, - "ResourceGroupManager::prepareResourceGroup"); - } - - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - // Set current group - mCurrentGroup = grp; - - // Count up resources for starting event - ResourceGroup::LoadResourceOrderMap::iterator oi; - size_t resourceCount = 0; - if (prepareMainResources) - { - for (oi = grp->loadResourceOrderMap.begin(); oi != grp->loadResourceOrderMap.end(); ++oi) - { - resourceCount += oi->second->size(); - } - } + LogManager::getSingleton().stream() + << "Preparing resource group '" << name << "' - Resources: " + << prepareMainResources << " World Geometry: " << prepareWorldGeom; + // load all created resources + ResourceGroup* grp = getResourceGroup(name); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + name, + "ResourceGroupManager::prepareResourceGroup"); + } + + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + // Set current group + mCurrentGroup = grp; + + // Count up resources for starting event + ResourceGroup::LoadResourceOrderMap::iterator oi; + size_t resourceCount = 0; + if (prepareMainResources) + { + for (oi = grp->loadResourceOrderMap.begin(); oi != grp->loadResourceOrderMap.end(); ++oi) + { + resourceCount += oi->second->size(); + } + } // Estimate world geometry size if (grp->worldGeometrySceneManager && prepareWorldGeom) { resourceCount += - grp->worldGeometrySceneManager->estimateWorldGeometry( - grp->worldGeometry); + grp->worldGeometrySceneManager->estimateWorldGeometry( + grp->worldGeometry); } - fireResourceGroupPrepareStarted(name, resourceCount); + fireResourceGroupPrepareStarted(name, resourceCount); - // Now load for real - if (prepareMainResources) - { - for (oi = grp->loadResourceOrderMap.begin(); - oi != grp->loadResourceOrderMap.end(); ++oi) - { - size_t n = 0; - LoadUnloadResourceList::iterator l = oi->second->begin(); - while (l != oi->second->end()) - { - ResourcePtr res = *l; + // Now load for real + if (prepareMainResources) + { + for (oi = grp->loadResourceOrderMap.begin(); + oi != grp->loadResourceOrderMap.end(); ++oi) + { + size_t n = 0; + LoadUnloadResourceList::iterator l = oi->second->begin(); + while (l != oi->second->end()) + { + ResourcePtr res = *l; - // Fire resource events no matter whether resource needs preparing + // Fire resource events no matter whether resource needs preparing // or not. This ensures that the number of callbacks - // matches the number originally estimated, which is important - // for progress bars. - fireResourcePrepareStarted(res); - - // If preparing one of these resources cascade-prepares another resource, - // the list will get longer! But these should be prepared immediately - // Call prepare regardless, already prepared or loaded resources will be skipped - res->prepare(); - - fireResourcePrepareEnded(); - - ++n; - - // Did the resource change group? if so, our iterator will have - // been invalidated - if (res->getGroup() != name) - { - l = oi->second->begin(); - std::advance(l, n); - } - else - { - ++l; - } - } - } - } + // matches the number originally estimated, which is important + // for progress bars. + fireResourcePrepareStarted(res); + + // If preparing one of these resources cascade-prepares another resource, + // the list will get longer! But these should be prepared immediately + // Call prepare regardless, already prepared or loaded resources will be skipped + res->prepare(); + + fireResourcePrepareEnded(); + + ++n; + + // Did the resource change group? if so, our iterator will have + // been invalidated + if (res->getGroup() != name) + { + l = oi->second->begin(); + std::advance(l, n); + } + else + { + ++l; + } + } + } + } // Load World Geometry if (grp->worldGeometrySceneManager && prepareWorldGeom) { grp->worldGeometrySceneManager->prepareWorldGeometry( grp->worldGeometry); } - fireResourceGroupPrepareEnded(name); + fireResourceGroupPrepareEnded(name); - // reset current group - mCurrentGroup = 0; - - LogManager::getSingleton().logMessage("Finished preparing resource group " + name); + // reset current group + mCurrentGroup = 0; + + LogManager::getSingleton().logMessage("Finished preparing resource group " + name); } //----------------------------------------------------------------------- void ResourceGroupManager::loadResourceGroup(const String& name, - bool loadMainResources, bool loadWorldGeom) + bool loadMainResources, bool loadWorldGeom) { - // Can only bulk-load one group at a time (reasonable limitation I think) + // Can only bulk-load one group at a time (reasonable limitation I think) OGRE_LOCK_AUTO_MUTEX; - LogManager::getSingleton().stream() - << "Loading resource group '" << name << "' - Resources: " - << loadMainResources << " World Geometry: " << loadWorldGeom; - // load all created resources - ResourceGroup* grp = getResourceGroup(name); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + name, - "ResourceGroupManager::loadResourceGroup"); - } - - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - // Set current group - mCurrentGroup = grp; - - // Count up resources for starting event - ResourceGroup::LoadResourceOrderMap::iterator oi; - size_t resourceCount = 0; - if (loadMainResources) - { - for (oi = grp->loadResourceOrderMap.begin(); oi != grp->loadResourceOrderMap.end(); ++oi) - { - resourceCount += oi->second->size(); - } - } + LogManager::getSingleton().stream() + << "Loading resource group '" << name << "' - Resources: " + << loadMainResources << " World Geometry: " << loadWorldGeom; + // load all created resources + ResourceGroup* grp = getResourceGroup(name); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + name, + "ResourceGroupManager::loadResourceGroup"); + } + + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + // Set current group + mCurrentGroup = grp; + + // Count up resources for starting event + ResourceGroup::LoadResourceOrderMap::iterator oi; + size_t resourceCount = 0; + if (loadMainResources) + { + for (oi = grp->loadResourceOrderMap.begin(); oi != grp->loadResourceOrderMap.end(); ++oi) + { + resourceCount += oi->second->size(); + } + } // Estimate world geometry size if (grp->worldGeometrySceneManager && loadWorldGeom) { resourceCount += - grp->worldGeometrySceneManager->estimateWorldGeometry( - grp->worldGeometry); - } - - fireResourceGroupLoadStarted(name, resourceCount); - - // Now load for real - if (loadMainResources) - { - for (oi = grp->loadResourceOrderMap.begin(); - oi != grp->loadResourceOrderMap.end(); ++oi) - { - size_t n = 0; - LoadUnloadResourceList::iterator l = oi->second->begin(); - while (l != oi->second->end()) - { - ResourcePtr res = *l; - - // Fire resource events no matter whether resource is already - // loaded or not. This ensures that the number of callbacks - // matches the number originally estimated, which is important - // for progress bars. - fireResourceLoadStarted(res); - - // If loading one of these resources cascade-loads another resource, - // the list will get longer! But these should be loaded immediately - // Call load regardless, already loaded resources will be skipped - res->load(); - - fireResourceLoadEnded(); - - ++n; - - // Did the resource change group? if so, our iterator will have - // been invalidated - if (res->getGroup() != name) - { - l = oi->second->begin(); - std::advance(l, n); - } - else - { - ++l; - } - } - } - } + grp->worldGeometrySceneManager->estimateWorldGeometry( + grp->worldGeometry); + } + + fireResourceGroupLoadStarted(name, resourceCount); + + // Now load for real + if (loadMainResources) + { + for (oi = grp->loadResourceOrderMap.begin(); + oi != grp->loadResourceOrderMap.end(); ++oi) + { + size_t n = 0; + LoadUnloadResourceList::iterator l = oi->second->begin(); + while (l != oi->second->end()) + { + ResourcePtr res = *l; + + // Fire resource events no matter whether resource is already + // loaded or not. This ensures that the number of callbacks + // matches the number originally estimated, which is important + // for progress bars. + fireResourceLoadStarted(res); + + // If loading one of these resources cascade-loads another resource, + // the list will get longer! But these should be loaded immediately + // Call load regardless, already loaded resources will be skipped + res->load(); + + fireResourceLoadEnded(); + + ++n; + + // Did the resource change group? if so, our iterator will have + // been invalidated + if (res->getGroup() != name) + { + l = oi->second->begin(); + std::advance(l, n); + } + else + { + ++l; + } + } + } + } // Load World Geometry if (grp->worldGeometrySceneManager && loadWorldGeom) { grp->worldGeometrySceneManager->setWorldGeometry( grp->worldGeometry); } - fireResourceGroupLoadEnded(name); + fireResourceGroupLoadEnded(name); - // group is loaded - grp->groupStatus = ResourceGroup::LOADED; + // group is loaded + grp->groupStatus = ResourceGroup::LOADED; - // reset current group - mCurrentGroup = 0; - - LogManager::getSingleton().logMessage("Finished loading resource group " + name); + // reset current group + mCurrentGroup = 0; + + LogManager::getSingleton().logMessage("Finished loading resource group " + name); } //----------------------------------------------------------------------- void ResourceGroupManager::unloadResourceGroup(const String& name, bool reloadableOnly) { - // Can only bulk-unload one group at a time (reasonable limitation I think) + // Can only bulk-unload one group at a time (reasonable limitation I think) OGRE_LOCK_AUTO_MUTEX; - LogManager::getSingleton().logMessage("Unloading resource group " + name); - ResourceGroup* grp = getResourceGroup(name); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + name, - "ResourceGroupManager::unloadResourceGroup"); - } - // Set current group - mCurrentGroup = grp; - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - - // Count up resources for starting event - ResourceGroup::LoadResourceOrderMap::reverse_iterator oi; - // unload in reverse order - for (oi = grp->loadResourceOrderMap.rbegin(); oi != grp->loadResourceOrderMap.rend(); ++oi) - { - for (LoadUnloadResourceList::iterator l = oi->second->begin(); - l != oi->second->end(); ++l) - { - Resource* resource = l->get(); - if (!reloadableOnly || resource->isReloadable()) - { - resource->unload(); - } - } - } - - grp->groupStatus = ResourceGroup::INITIALISED; - - // reset current group - mCurrentGroup = 0; - LogManager::getSingleton().logMessage("Finished unloading resource group " + name); - } - //----------------------------------------------------------------------- - void ResourceGroupManager::unloadUnreferencedResourcesInGroup( - const String& name, bool reloadableOnly ) - { - // Can only bulk-unload one group at a time (reasonable limitation I think) + LogManager::getSingleton().logMessage("Unloading resource group " + name); + ResourceGroup* grp = getResourceGroup(name); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + name, + "ResourceGroupManager::unloadResourceGroup"); + } + // Set current group + mCurrentGroup = grp; + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + + // Count up resources for starting event + ResourceGroup::LoadResourceOrderMap::reverse_iterator oi; + // unload in reverse order + for (oi = grp->loadResourceOrderMap.rbegin(); oi != grp->loadResourceOrderMap.rend(); ++oi) + { + for (LoadUnloadResourceList::iterator l = oi->second->begin(); + l != oi->second->end(); ++l) + { + Resource* resource = l->get(); + if (!reloadableOnly || resource->isReloadable()) + { + resource->unload(); + } + } + } + + grp->groupStatus = ResourceGroup::INITIALISED; + + // reset current group + mCurrentGroup = 0; + LogManager::getSingleton().logMessage("Finished unloading resource group " + name); + } + //----------------------------------------------------------------------- + void ResourceGroupManager::unloadUnreferencedResourcesInGroup( + const String& name, bool reloadableOnly ) + { + // Can only bulk-unload one group at a time (reasonable limitation I think) OGRE_LOCK_AUTO_MUTEX; - LogManager::getSingleton().logMessage( - "Unloading unused resources in resource group " + name); - ResourceGroup* grp = getResourceGroup(name); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + name, - "ResourceGroupManager::unloadUnreferencedResourcesInGroup"); - } - // Set current group - mCurrentGroup = grp; - - ResourceGroup::LoadResourceOrderMap::reverse_iterator oi; - // unload in reverse order - for (oi = grp->loadResourceOrderMap.rbegin(); oi != grp->loadResourceOrderMap.rend(); ++oi) - { - for (LoadUnloadResourceList::iterator l = oi->second->begin(); - l != oi->second->end(); ++l) - { - // A use count of 3 means that only RGM and RM have references - // RGM has one (this one) and RM has 2 (by name and by handle) - if (l->useCount() == RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS) - { - Resource* resource = l->get(); - if (!reloadableOnly || resource->isReloadable()) - { - resource->unload(); - } - } - } - } - - grp->groupStatus = ResourceGroup::INITIALISED; - - // reset current group - mCurrentGroup = 0; - LogManager::getSingleton().logMessage( - "Finished unloading unused resources in resource group " + name); - } - //----------------------------------------------------------------------- - void ResourceGroupManager::clearResourceGroup(const String& name) - { - // Can only bulk-clear one group at a time (reasonable limitation I think) + LogManager::getSingleton().logMessage( + "Unloading unused resources in resource group " + name); + ResourceGroup* grp = getResourceGroup(name); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + name, + "ResourceGroupManager::unloadUnreferencedResourcesInGroup"); + } + // Set current group + mCurrentGroup = grp; + + ResourceGroup::LoadResourceOrderMap::reverse_iterator oi; + // unload in reverse order + for (oi = grp->loadResourceOrderMap.rbegin(); oi != grp->loadResourceOrderMap.rend(); ++oi) + { + for (LoadUnloadResourceList::iterator l = oi->second->begin(); + l != oi->second->end(); ++l) + { + // A use count of 3 means that only RGM and RM have references + // RGM has one (this one) and RM has 2 (by name and by handle) + if (l->useCount() == RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS) + { + Resource* resource = l->get(); + if (!reloadableOnly || resource->isReloadable()) + { + resource->unload(); + } + } + } + } + + grp->groupStatus = ResourceGroup::INITIALISED; + + // reset current group + mCurrentGroup = 0; + LogManager::getSingleton().logMessage( + "Finished unloading unused resources in resource group " + name); + } + //----------------------------------------------------------------------- + void ResourceGroupManager::clearResourceGroup(const String& name) + { + // Can only bulk-clear one group at a time (reasonable limitation I think) OGRE_LOCK_AUTO_MUTEX; - LogManager::getSingleton().logMessage("Clearing resource group " + name); - ResourceGroup* grp = getResourceGroup(name); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + name, - "ResourceGroupManager::clearResourceGroup"); - } - // set current group - mCurrentGroup = grp; - dropGroupContents(grp); - // clear initialised flag - grp->groupStatus = ResourceGroup::UNINITIALSED; - // reset current group - mCurrentGroup = 0; - LogManager::getSingleton().logMessage("Finished clearing resource group " + name); - } + LogManager::getSingleton().logMessage("Clearing resource group " + name); + ResourceGroup* grp = getResourceGroup(name); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + name, + "ResourceGroupManager::clearResourceGroup"); + } + // set current group + mCurrentGroup = grp; + dropGroupContents(grp); + // clear initialised flag + grp->groupStatus = ResourceGroup::UNINITIALSED; + // reset current group + mCurrentGroup = 0; + LogManager::getSingleton().logMessage("Finished clearing resource group " + name); + } //----------------------------------------------------------------------- void ResourceGroupManager::destroyResourceGroup(const String& name) { - // Can only bulk-destroy one group at a time (reasonable limitation I think) + // Can only bulk-destroy one group at a time (reasonable limitation I think) OGRE_LOCK_AUTO_MUTEX; - LogManager::getSingleton().logMessage("Destroying resource group " + name); - ResourceGroup* grp = getResourceGroup(name); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + name, - "ResourceGroupManager::destroyResourceGroup"); - } - // set current group - mCurrentGroup = grp; + LogManager::getSingleton().logMessage("Destroying resource group " + name); + ResourceGroup* grp = getResourceGroup(name); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + name, + "ResourceGroupManager::destroyResourceGroup"); + } + // set current group + mCurrentGroup = grp; unloadResourceGroup(name, false); // will throw an exception if name not valid - dropGroupContents(grp); - deleteGroup(grp); + dropGroupContents(grp); + deleteGroup(grp); mResourceGroupMap.erase(mResourceGroupMap.find(name)); - // reset current group - mCurrentGroup = 0; + // reset current group + mCurrentGroup = 0; } - //----------------------------------------------------------------------- - bool ResourceGroupManager::isResourceGroupInitialised(const String& name) + //----------------------------------------------------------------------- + bool ResourceGroupManager::isResourceGroupInitialised(const String& name) { - // Can only bulk-destroy one group at a time (reasonable limitation I think) + // Can only bulk-destroy one group at a time (reasonable limitation I think) OGRE_LOCK_AUTO_MUTEX; - ResourceGroup* grp = getResourceGroup(name); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + name, - "ResourceGroupManager::isResourceGroupInitialised"); - } - return (grp->groupStatus != ResourceGroup::UNINITIALSED && - grp->groupStatus != ResourceGroup::INITIALISING); + ResourceGroup* grp = getResourceGroup(name); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + name, + "ResourceGroupManager::isResourceGroupInitialised"); + } + return (grp->groupStatus != ResourceGroup::UNINITIALSED && + grp->groupStatus != ResourceGroup::INITIALISING); } - //----------------------------------------------------------------------- - bool ResourceGroupManager::isResourceGroupLoaded(const String& name) + //----------------------------------------------------------------------- + bool ResourceGroupManager::isResourceGroupLoaded(const String& name) { - // Can only bulk-destroy one group at a time (reasonable limitation I think) + // Can only bulk-destroy one group at a time (reasonable limitation I think) OGRE_LOCK_AUTO_MUTEX; - ResourceGroup* grp = getResourceGroup(name); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + name, - "ResourceGroupManager::isResourceGroupInitialised"); - } - return (grp->groupStatus == ResourceGroup::LOADED); - } - //----------------------------------------------------------------------- - bool ResourceGroupManager::resourceGroupExists(const String& name) - { - return getResourceGroup(name) ? true : false; - } + ResourceGroup* grp = getResourceGroup(name); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + name, + "ResourceGroupManager::isResourceGroupInitialised"); + } + return (grp->groupStatus == ResourceGroup::LOADED); + } + //----------------------------------------------------------------------- + bool ResourceGroupManager::resourceGroupExists(const String& name) + { + return getResourceGroup(name) ? true : false; + } //----------------------------------------------------------------------- bool ResourceGroupManager::resourceLocationExists(const String& name, const String& resGroup) { - ResourceGroup* grp = getResourceGroup(resGroup); - if (!grp) - return false; + ResourceGroup* grp = getResourceGroup(resGroup); + if (!grp) + return false; - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - LocationList::iterator li, liend; - liend = grp->locationList.end(); - for (li = grp->locationList.begin(); li != liend; ++li) - { - Archive* pArch = (*li)->archive; - if (pArch->getName() == name) - // Delete indexes - return true; - } - return false; - } + LocationList::iterator li, liend; + liend = grp->locationList.end(); + for (li = grp->locationList.begin(); li != liend; ++li) + { + Archive* pArch = (*li)->archive; + if (pArch->getName() == name) + // Delete indexes + return true; + } + return false; + } //----------------------------------------------------------------------- void ResourceGroupManager::addResourceLocation(const String& name, const String& locType, const String& resGroup, bool recursive, bool readOnly) @@ -558,63 +558,63 @@ namespace Ogre { // Get archive Archive* pArch = ArchiveManager::getSingleton().load( name, locType, readOnly ); // Add to location list - ResourceLocation* loc = OGRE_NEW_T(ResourceLocation, MEMCATEGORY_RESOURCE); - loc->archive = pArch; - loc->recursive = recursive; + ResourceLocation* loc = OGRE_NEW_T(ResourceLocation, MEMCATEGORY_RESOURCE); + loc->archive = pArch; + loc->recursive = recursive; grp->locationList.push_back(loc); // Index resources StringVectorPtr vec = pArch->find("*", recursive); for( StringVector::iterator it = vec->begin(); it != vec->end(); ++it ) - grp->addToIndex(*it, pArch); - - StringStream msg; - msg << "Added resource location '" << name << "' of type '" << locType - << "' to resource group '" << resGroup << "'"; - if (recursive) - msg << " with recursive option"; - LogManager::getSingleton().logMessage(msg.str()); + grp->addToIndex(*it, pArch); + + StringStream msg; + msg << "Added resource location '" << name << "' of type '" << locType + << "' to resource group '" << resGroup << "'"; + if (recursive) + msg << " with recursive option"; + LogManager::getSingleton().logMessage(msg.str()); } //----------------------------------------------------------------------- void ResourceGroupManager::removeResourceLocation(const String& name, const String& resGroup) { - ResourceGroup* grp = getResourceGroup(resGroup); - if (!grp) + ResourceGroup* grp = getResourceGroup(resGroup); + if (!grp) { OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate a resource group called '" + resGroup + "'", "ResourceGroupManager::removeResourceLocation"); } - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex // Remove from location list - LocationList::iterator li, liend; - liend = grp->locationList.end(); - for (li = grp->locationList.begin(); li != liend; ++li) - { - Archive* pArch = (*li)->archive; - if (pArch->getName() == name) - { - grp->removeFromIndex(pArch); - // Erase list entry - OGRE_DELETE_T(*li, ResourceLocation, MEMCATEGORY_RESOURCE); - grp->locationList.erase(li); + LocationList::iterator li, liend; + liend = grp->locationList.end(); + for (li = grp->locationList.begin(); li != liend; ++li) + { + Archive* pArch = (*li)->archive; + if (pArch->getName() == name) + { + grp->removeFromIndex(pArch); + // Erase list entry + OGRE_DELETE_T(*li, ResourceLocation, MEMCATEGORY_RESOURCE); + grp->locationList.erase(li); - break; - } + break; + } - } + } - LogManager::getSingleton().logMessage("Removed resource location " + name); + LogManager::getSingleton().logMessage("Removed resource location " + name); } //----------------------------------------------------------------------- void ResourceGroupManager::declareResource(const String& name, const String& resourceType, const String& groupName, - const NameValuePairList& loadParameters) + const NameValuePairList& loadParameters) { declareResource(name, resourceType, groupName, 0, loadParameters); } @@ -624,84 +624,84 @@ namespace Ogre { ManualResourceLoader* loader, const NameValuePairList& loadParameters) { - ResourceGroup* grp = getResourceGroup(groupName); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + groupName, - "ResourceGroupManager::declareResource"); - } - - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + ResourceGroup* grp = getResourceGroup(groupName); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + groupName, + "ResourceGroupManager::declareResource"); + } + + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - ResourceDeclaration dcl; - dcl.loader = loader; - dcl.parameters = loadParameters; - dcl.resourceName = name; - dcl.resourceType = resourceType; - grp->resourceDeclarations.push_back(dcl); + ResourceDeclaration dcl; + dcl.loader = loader; + dcl.parameters = loadParameters; + dcl.resourceName = name; + dcl.resourceType = resourceType; + grp->resourceDeclarations.push_back(dcl); } //----------------------------------------------------------------------- void ResourceGroupManager::undeclareResource(const String& name, - const String& groupName) + const String& groupName) { - ResourceGroup* grp = getResourceGroup(groupName); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + groupName, - "ResourceGroupManager::undeclareResource"); - } + ResourceGroup* grp = getResourceGroup(groupName); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + groupName, + "ResourceGroupManager::undeclareResource"); + } - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - for (ResourceDeclarationList::iterator i = grp->resourceDeclarations.begin(); - i != grp->resourceDeclarations.end(); ++i) - { - if (i->resourceName == name) - { - grp->resourceDeclarations.erase(i); - break; - } - } + for (ResourceDeclarationList::iterator i = grp->resourceDeclarations.begin(); + i != grp->resourceDeclarations.end(); ++i) + { + if (i->resourceName == name) + { + grp->resourceDeclarations.erase(i); + break; + } + } } //----------------------------------------------------------------------- DataStreamPtr ResourceGroupManager::openResource( const String& resourceName, const String& groupName, - bool searchGroupsIfNotFound, Resource* resourceBeingLoaded) + bool searchGroupsIfNotFound, Resource* resourceBeingLoaded) { OGRE_LOCK_AUTO_MUTEX; - if(mLoadingListener) - { - DataStreamPtr stream = mLoadingListener->resourceLoading(resourceName, groupName, resourceBeingLoaded); - if(!stream.isNull()) - return stream; - } - - // Try to find in resource index first - ResourceGroup* grp = getResourceGroup(groupName); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot locate a resource group called '" + groupName + - "' for resource '" + resourceName + "'" , - "ResourceGroupManager::openResource"); - } - - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - - Archive* pArch = 0; - ResourceLocationIndex::iterator rit = grp->resourceIndexCaseSensitive.find(resourceName); - if (rit != grp->resourceIndexCaseSensitive.end()) - { - // Found in the index - pArch = rit->second; - DataStreamPtr stream = pArch->open(resourceName); - if (mLoadingListener) - mLoadingListener->resourceStreamOpened(resourceName, groupName, resourceBeingLoaded, stream); - return stream; - } + if(mLoadingListener) + { + DataStreamPtr stream = mLoadingListener->resourceLoading(resourceName, groupName, resourceBeingLoaded); + if(!stream.isNull()) + return stream; + } + + // Try to find in resource index first + ResourceGroup* grp = getResourceGroup(groupName); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot locate a resource group called '" + groupName + + "' for resource '" + resourceName + "'" , + "ResourceGroupManager::openResource"); + } + + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + + Archive* pArch = 0; + ResourceLocationIndex::iterator rit = grp->resourceIndexCaseSensitive.find(resourceName); + if (rit != grp->resourceIndexCaseSensitive.end()) + { + // Found in the index + pArch = rit->second; + DataStreamPtr stream = pArch->open(resourceName); + if (mLoadingListener) + mLoadingListener->resourceStreamOpened(resourceName, groupName, resourceBeingLoaded, stream); + return stream; + } else { // try case insensitive @@ -712,54 +712,54 @@ namespace Ogre { { // Found in the index pArch = rit->second; - DataStreamPtr stream = pArch->open(resourceName); - if (mLoadingListener) - mLoadingListener->resourceStreamOpened(resourceName, groupName, resourceBeingLoaded, stream); - return stream; + DataStreamPtr stream = pArch->open(resourceName); + if (mLoadingListener) + mLoadingListener->resourceStreamOpened(resourceName, groupName, resourceBeingLoaded, stream); + return stream; } - else - { - // Search the hard way - LocationList::iterator li, liend; - liend = grp->locationList.end(); - for (li = grp->locationList.begin(); li != liend; ++li) - { - Archive* arch = (*li)->archive; + else + { + // Search the hard way + LocationList::iterator li, liend; + liend = grp->locationList.end(); + for (li = grp->locationList.begin(); li != liend; ++li) + { + Archive* arch = (*li)->archive; if (arch->exists(resourceName)) - { + { DataStreamPtr ptr = arch->open(resourceName); - if (mLoadingListener) - mLoadingListener->resourceStreamOpened(resourceName, groupName, resourceBeingLoaded, ptr); - return ptr; - } - } - } - } - - - // Not found - if (searchGroupsIfNotFound) - { - ResourceGroup* foundGrp = findGroupContainingResourceImpl(resourceName); - if (foundGrp) - { - if (resourceBeingLoaded) - { - resourceBeingLoaded->changeGroupOwnership(foundGrp->name); - } - return openResource(resourceName, foundGrp->name, false); - } - else - { - OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, - "Cannot locate resource " + resourceName + - " in resource group " + groupName + " or any other group.", - "ResourceGroupManager::openResource"); - } - } - OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, "Cannot locate resource " + - resourceName + " in resource group " + groupName + ".", - "ResourceGroupManager::openResource"); + if (mLoadingListener) + mLoadingListener->resourceStreamOpened(resourceName, groupName, resourceBeingLoaded, ptr); + return ptr; + } + } + } + } + + + // Not found + if (searchGroupsIfNotFound) + { + ResourceGroup* foundGrp = findGroupContainingResourceImpl(resourceName); + if (foundGrp) + { + if (resourceBeingLoaded) + { + resourceBeingLoaded->changeGroupOwnership(foundGrp->name); + } + return openResource(resourceName, foundGrp->name, false); + } + else + { + OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, + "Cannot locate resource " + resourceName + + " in resource group " + groupName + " or any other group.", + "ResourceGroupManager::openResource"); + } + } + OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, "Cannot locate resource " + + resourceName + " in resource group " + groupName + ".", + "ResourceGroupManager::openResource"); } //----------------------------------------------------------------------- @@ -767,178 +767,178 @@ namespace Ogre { const String& pattern, const String& groupName) { OGRE_LOCK_AUTO_MUTEX; - ResourceGroup* grp = getResourceGroup(groupName); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot locate a resource group called '" + groupName + "'", - "ResourceGroupManager::openResources"); - } - - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - - // Iterate through all the archives and build up a combined list of - // streams - // MEMCATEGORY_GENERAL is the only category supported for SharedPtr - DataStreamListPtr ret = DataStreamListPtr(OGRE_NEW_T(DataStreamList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); - - LocationList::iterator li, liend; - liend = grp->locationList.end(); - for (li = grp->locationList.begin(); li != liend; ++li) - { - Archive* arch = (*li)->archive; - // Find all the names based on whether this archive is recursive - StringVectorPtr names = arch->find(pattern, (*li)->recursive); - - // Iterate over the names and load a stream for each - for (StringVector::iterator ni = names->begin(); ni != names->end(); ++ni) - { - DataStreamPtr ptr = arch->open(*ni); - if (!ptr.isNull()) - { - ret->push_back(ptr); - } - } - } - return ret; - - } - //--------------------------------------------------------------------- - DataStreamPtr ResourceGroupManager::createResource(const String& filename, - const String& groupName, bool overwrite, const String& locationPattern) - { + ResourceGroup* grp = getResourceGroup(groupName); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot locate a resource group called '" + groupName + "'", + "ResourceGroupManager::openResources"); + } + + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + + // Iterate through all the archives and build up a combined list of + // streams + // MEMCATEGORY_GENERAL is the only category supported for SharedPtr + DataStreamListPtr ret = DataStreamListPtr(OGRE_NEW_T(DataStreamList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); + + LocationList::iterator li, liend; + liend = grp->locationList.end(); + for (li = grp->locationList.begin(); li != liend; ++li) + { + Archive* arch = (*li)->archive; + // Find all the names based on whether this archive is recursive + StringVectorPtr names = arch->find(pattern, (*li)->recursive); + + // Iterate over the names and load a stream for each + for (StringVector::iterator ni = names->begin(); ni != names->end(); ++ni) + { + DataStreamPtr ptr = arch->open(*ni); + if (!ptr.isNull()) + { + ret->push_back(ptr); + } + } + } + return ret; + + } + //--------------------------------------------------------------------- + DataStreamPtr ResourceGroupManager::createResource(const String& filename, + const String& groupName, bool overwrite, const String& locationPattern) + { OGRE_LOCK_AUTO_MUTEX; - ResourceGroup* grp = getResourceGroup(groupName); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot locate a resource group called '" + groupName + "'", - "ResourceGroupManager::createResource"); - } - - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - - - for (LocationList::iterator li = grp->locationList.begin(); - li != grp->locationList.end(); ++li) - { - Archive* arch = (*li)->archive; - - if (!arch->isReadOnly() && - (locationPattern.empty() || StringUtil::match(arch->getName(), locationPattern, false))) - { - if (!overwrite && arch->exists(filename)) - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "Cannot overwrite existing file " + filename, - "ResourceGroupManager::createResource"); - - // create it - DataStreamPtr ret = arch->create(filename); - grp->addToIndex(filename, arch); - - - return ret; - } - } - - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a writable location in group " + groupName, - "ResourceGroupManager::createResource"); - - } - //--------------------------------------------------------------------- - void ResourceGroupManager::deleteResource(const String& filename, const String& groupName, - const String& locationPattern) - { + ResourceGroup* grp = getResourceGroup(groupName); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot locate a resource group called '" + groupName + "'", + "ResourceGroupManager::createResource"); + } + + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + + + for (LocationList::iterator li = grp->locationList.begin(); + li != grp->locationList.end(); ++li) + { + Archive* arch = (*li)->archive; + + if (!arch->isReadOnly() && + (locationPattern.empty() || StringUtil::match(arch->getName(), locationPattern, false))) + { + if (!overwrite && arch->exists(filename)) + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "Cannot overwrite existing file " + filename, + "ResourceGroupManager::createResource"); + + // create it + DataStreamPtr ret = arch->create(filename); + grp->addToIndex(filename, arch); + + + return ret; + } + } + + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a writable location in group " + groupName, + "ResourceGroupManager::createResource"); + + } + //--------------------------------------------------------------------- + void ResourceGroupManager::deleteResource(const String& filename, const String& groupName, + const String& locationPattern) + { OGRE_LOCK_AUTO_MUTEX; - ResourceGroup* grp = getResourceGroup(groupName); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot locate a resource group called '" + groupName + "'", - "ResourceGroupManager::createResource"); - } - - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - - - for (LocationList::iterator li = grp->locationList.begin(); - li != grp->locationList.end(); ++li) - { - Archive* arch = (*li)->archive; - - if (!arch->isReadOnly() && - (locationPattern.empty() || StringUtil::match(arch->getName(), locationPattern, false))) - { - if (arch->exists(filename)) - { - arch->remove(filename); - grp->removeFromIndex(filename, arch); - - // only remove one file - break; - } - } - } - - } - //--------------------------------------------------------------------- - void ResourceGroupManager::deleteMatchingResources(const String& filePattern, - const String& groupName, const String& locationPattern) - { + ResourceGroup* grp = getResourceGroup(groupName); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot locate a resource group called '" + groupName + "'", + "ResourceGroupManager::createResource"); + } + + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + + + for (LocationList::iterator li = grp->locationList.begin(); + li != grp->locationList.end(); ++li) + { + Archive* arch = (*li)->archive; + + if (!arch->isReadOnly() && + (locationPattern.empty() || StringUtil::match(arch->getName(), locationPattern, false))) + { + if (arch->exists(filename)) + { + arch->remove(filename); + grp->removeFromIndex(filename, arch); + + // only remove one file + break; + } + } + } + + } + //--------------------------------------------------------------------- + void ResourceGroupManager::deleteMatchingResources(const String& filePattern, + const String& groupName, const String& locationPattern) + { OGRE_LOCK_AUTO_MUTEX; - ResourceGroup* grp = getResourceGroup(groupName); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot locate a resource group called '" + groupName + "'", - "ResourceGroupManager::createResource"); - } - - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - - - for (LocationList::iterator li = grp->locationList.begin(); - li != grp->locationList.end(); ++li) - { - Archive* arch = (*li)->archive; - - if (!arch->isReadOnly() && - (locationPattern.empty() || StringUtil::match(arch->getName(), locationPattern, false))) - { - StringVectorPtr matchingFiles = arch->find(filePattern); - for (StringVector::iterator f = matchingFiles->begin(); f != matchingFiles->end(); ++f) - { - arch->remove(*f); - grp->removeFromIndex(*f, arch); - - } - } - } - - - } + ResourceGroup* grp = getResourceGroup(groupName); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot locate a resource group called '" + groupName + "'", + "ResourceGroupManager::createResource"); + } + + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + + + for (LocationList::iterator li = grp->locationList.begin(); + li != grp->locationList.end(); ++li) + { + Archive* arch = (*li)->archive; + + if (!arch->isReadOnly() && + (locationPattern.empty() || StringUtil::match(arch->getName(), locationPattern, false))) + { + StringVectorPtr matchingFiles = arch->find(filePattern); + for (StringVector::iterator f = matchingFiles->begin(); f != matchingFiles->end(); ++f) + { + arch->remove(*f); + grp->removeFromIndex(*f, arch); + + } + } + } + + + } //----------------------------------------------------------------------- void ResourceGroupManager::addResourceGroupListener(ResourceGroupListener* l) { OGRE_LOCK_AUTO_MUTEX; - mResourceGroupListenerList.push_back(l); + mResourceGroupListenerList.push_back(l); } //----------------------------------------------------------------------- void ResourceGroupManager::removeResourceGroupListener(ResourceGroupListener* l) { OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator i = mResourceGroupListenerList.begin(); - i != mResourceGroupListenerList.end(); ++i) - { - if (*i == l) - { - mResourceGroupListenerList.erase(i); - break; - } - } + for (ResourceGroupListenerList::iterator i = mResourceGroupListenerList.begin(); + i != mResourceGroupListenerList.end(); ++i) + { + if (*i == l) + { + mResourceGroupListenerList.erase(i); + break; + } + } } //----------------------------------------------------------------------- void ResourceGroupManager::_registerResourceManager( @@ -946,9 +946,9 @@ namespace Ogre { { OGRE_LOCK_AUTO_MUTEX; - LogManager::getSingleton().logMessage( - "Registering ResourceManager for type " + resourceType); - mResourceManagerMap[resourceType] = rm; + LogManager::getSingleton().logMessage( + "Registering ResourceManager for type " + resourceType); + mResourceManagerMap[resourceType] = rm; } //----------------------------------------------------------------------- void ResourceGroupManager::_unregisterResourceManager( @@ -956,336 +956,336 @@ namespace Ogre { { OGRE_LOCK_AUTO_MUTEX; - LogManager::getSingleton().logMessage( - "Unregistering ResourceManager for type " + resourceType); - - ResourceManagerMap::iterator i = mResourceManagerMap.find(resourceType); - if (i != mResourceManagerMap.end()) - { - mResourceManagerMap.erase(i); - } + LogManager::getSingleton().logMessage( + "Unregistering ResourceManager for type " + resourceType); + + ResourceManagerMap::iterator i = mResourceManagerMap.find(resourceType); + if (i != mResourceManagerMap.end()) + { + mResourceManagerMap.erase(i); + } } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void ResourceGroupManager::_registerScriptLoader(ScriptLoader* su) - { + { OGRE_LOCK_AUTO_MUTEX; - mScriptLoaderOrderMap.insert( - ScriptLoaderOrderMap::value_type(su->getLoadingOrder(), su)); - } - //----------------------------------------------------------------------- + mScriptLoaderOrderMap.insert( + ScriptLoaderOrderMap::value_type(su->getLoadingOrder(), su)); + } + //----------------------------------------------------------------------- void ResourceGroupManager::_unregisterScriptLoader(ScriptLoader* su) - { + { OGRE_LOCK_AUTO_MUTEX; - Real order = su->getLoadingOrder(); - ScriptLoaderOrderMap::iterator oi = mScriptLoaderOrderMap.find(order); - while (oi != mScriptLoaderOrderMap.end() && oi->first == order) - { - if (oi->second == su) - { - // erase does not invalidate on multimap, except current - ScriptLoaderOrderMap::iterator del = oi++; - mScriptLoaderOrderMap.erase(del); - } - else - { - ++oi; - } - } - } - //----------------------------------------------------------------------- - ScriptLoader *ResourceGroupManager::_findScriptLoader(const String &pattern) - { - OGRE_LOCK_AUTO_MUTEX; - - ScriptLoaderOrderMap::iterator oi; - for (oi = mScriptLoaderOrderMap.begin(); - oi != mScriptLoaderOrderMap.end(); ++oi) - { - ScriptLoader* su = oi->second; - const StringVector& patterns = su->getScriptPatterns(); - - // Search for matches in the patterns - for (StringVector::const_iterator p = patterns.begin(); p != patterns.end(); ++p) - { - if(*p == pattern) - return su; - } - } - - return 0; // No loader was found - } - //----------------------------------------------------------------------- - void ResourceGroupManager::parseResourceGroupScripts(ResourceGroup* grp) - { - - LogManager::getSingleton().logMessage( - "Parsing scripts for resource group " + grp->name); - - // Count up the number of scripts we have to parse + Real order = su->getLoadingOrder(); + ScriptLoaderOrderMap::iterator oi = mScriptLoaderOrderMap.find(order); + while (oi != mScriptLoaderOrderMap.end() && oi->first == order) + { + if (oi->second == su) + { + // erase does not invalidate on multimap, except current + ScriptLoaderOrderMap::iterator del = oi++; + mScriptLoaderOrderMap.erase(del); + } + else + { + ++oi; + } + } + } + //----------------------------------------------------------------------- + ScriptLoader *ResourceGroupManager::_findScriptLoader(const String &pattern) + { + OGRE_LOCK_AUTO_MUTEX; + + ScriptLoaderOrderMap::iterator oi; + for (oi = mScriptLoaderOrderMap.begin(); + oi != mScriptLoaderOrderMap.end(); ++oi) + { + ScriptLoader* su = oi->second; + const StringVector& patterns = su->getScriptPatterns(); + + // Search for matches in the patterns + for (StringVector::const_iterator p = patterns.begin(); p != patterns.end(); ++p) + { + if(*p == pattern) + return su; + } + } + + return 0; // No loader was found + } + //----------------------------------------------------------------------- + void ResourceGroupManager::parseResourceGroupScripts(ResourceGroup* grp) + { + + LogManager::getSingleton().logMessage( + "Parsing scripts for resource group " + grp->name); + + // Count up the number of scripts we have to parse typedef list::type FileListList; typedef SharedPtr FileListListPtr; typedef std::pair LoaderFileListPair; typedef list::type ScriptLoaderFileList; ScriptLoaderFileList scriptLoaderFileList; - size_t scriptCount = 0; - // Iterate over script users in loading order and get streams - ScriptLoaderOrderMap::iterator oi; - for (oi = mScriptLoaderOrderMap.begin(); - oi != mScriptLoaderOrderMap.end(); ++oi) - { - ScriptLoader* su = oi->second; - // MEMCATEGORY_GENERAL is the only category supported for SharedPtr + size_t scriptCount = 0; + // Iterate over script users in loading order and get streams + ScriptLoaderOrderMap::iterator oi; + for (oi = mScriptLoaderOrderMap.begin(); + oi != mScriptLoaderOrderMap.end(); ++oi) + { + ScriptLoader* su = oi->second; + // MEMCATEGORY_GENERAL is the only category supported for SharedPtr FileListListPtr fileListList(OGRE_NEW_T(FileListList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); - // Get all the patterns and search them - const StringVector& patterns = su->getScriptPatterns(); - for (StringVector::const_iterator p = patterns.begin(); p != patterns.end(); ++p) - { - FileInfoListPtr fileList = findResourceFileInfo(grp->name, *p); - scriptCount += fileList->size(); - fileListList->push_back(fileList); - } - scriptLoaderFileList.push_back( - LoaderFileListPair(su, fileListList)); - } - // Fire scripting event - fireResourceGroupScriptingStarted(grp->name, scriptCount); + // Get all the patterns and search them + const StringVector& patterns = su->getScriptPatterns(); + for (StringVector::const_iterator p = patterns.begin(); p != patterns.end(); ++p) + { + FileInfoListPtr fileList = findResourceFileInfo(grp->name, *p); + scriptCount += fileList->size(); + fileListList->push_back(fileList); + } + scriptLoaderFileList.push_back( + LoaderFileListPair(su, fileListList)); + } + // Fire scripting event + fireResourceGroupScriptingStarted(grp->name, scriptCount); + + // Iterate over scripts and parse + // Note we respect original ordering + for (ScriptLoaderFileList::iterator slfli = scriptLoaderFileList.begin(); + slfli != scriptLoaderFileList.end(); ++slfli) + { + ScriptLoader* su = slfli->first; + // Iterate over each list + for (FileListList::iterator flli = slfli->second->begin(); flli != slfli->second->end(); ++flli) + { + // Iterate over each item in the list + for (FileInfoList::iterator fii = (*flli)->begin(); fii != (*flli)->end(); ++fii) + { + bool skipScript = false; + fireScriptStarted(fii->filename, skipScript); + if(skipScript) + { + LogManager::getSingleton().logMessage( + "Skipping script " + fii->filename); + } + else + { + LogManager::getSingleton().logMessage( + "Parsing script " + fii->filename); + DataStreamPtr stream = fii->archive->open(fii->filename); + if (!stream.isNull()) + { + if (mLoadingListener) + mLoadingListener->resourceStreamOpened(fii->filename, grp->name, 0, stream); + + if(fii->archive->getType() == "FileSystem" && stream->size() <= 1024 * 1024) + { + DataStreamPtr cachedCopy; + cachedCopy.bind(OGRE_NEW MemoryDataStream(stream->getName(), stream)); + su->parseScript(cachedCopy, grp->name); + } + else + su->parseScript(stream, grp->name); + } + } + fireScriptEnded(fii->filename, skipScript); + } + } + } + + fireResourceGroupScriptingEnded(grp->name); + LogManager::getSingleton().logMessage( + "Finished parsing scripts for resource group " + grp->name); + } + //----------------------------------------------------------------------- + void ResourceGroupManager::createDeclaredResources(ResourceGroup* grp) + { + + for (ResourceDeclarationList::iterator i = grp->resourceDeclarations.begin(); + i != grp->resourceDeclarations.end(); ++i) + { + ResourceDeclaration& dcl = *i; + // Retrieve the appropriate manager + ResourceManager* mgr = _getResourceManager(dcl.resourceType); + // Create the resource + ResourcePtr res = mgr->createResource(dcl.resourceName, grp->name, + dcl.loader != 0, dcl.loader, &dcl.parameters); + // Add resource to load list + ResourceGroup::LoadResourceOrderMap::iterator li = + grp->loadResourceOrderMap.find(mgr->getLoadingOrder()); + LoadUnloadResourceList* loadList; + if (li == grp->loadResourceOrderMap.end()) + { + loadList = OGRE_NEW_T(LoadUnloadResourceList, MEMCATEGORY_RESOURCE)(); + grp->loadResourceOrderMap[mgr->getLoadingOrder()] = loadList; + } + } + + } + //----------------------------------------------------------------------- + void ResourceGroupManager::_notifyResourceCreated(ResourcePtr& res) + { + if (mCurrentGroup && res->getGroup() == mCurrentGroup->name) + { + // Use current group (batch loading) + addCreatedResource(res, *mCurrentGroup); + } + else + { + // Find group + ResourceGroup* grp = getResourceGroup(res->getGroup()); + if (grp) + { + addCreatedResource(res, *grp); + } + } + + fireResourceCreated(res); + } + //----------------------------------------------------------------------- + void ResourceGroupManager::_notifyResourceRemoved(ResourcePtr& res) + { + fireResourceRemove(res); - // Iterate over scripts and parse - // Note we respect original ordering - for (ScriptLoaderFileList::iterator slfli = scriptLoaderFileList.begin(); - slfli != scriptLoaderFileList.end(); ++slfli) + if (mCurrentGroup) { - ScriptLoader* su = slfli->first; - // Iterate over each list - for (FileListList::iterator flli = slfli->second->begin(); flli != slfli->second->end(); ++flli) + // Do nothing - we're batch unloading so list will be cleared + } + else + { + // Find group + ResourceGroup* grp = getResourceGroup(res->getGroup()); + if (grp) { - // Iterate over each item in the list - for (FileInfoList::iterator fii = (*flli)->begin(); fii != (*flli)->end(); ++fii) - { - bool skipScript = false; - fireScriptStarted(fii->filename, skipScript); - if(skipScript) - { - LogManager::getSingleton().logMessage( - "Skipping script " + fii->filename); - } - else - { - LogManager::getSingleton().logMessage( - "Parsing script " + fii->filename); - DataStreamPtr stream = fii->archive->open(fii->filename); - if (!stream.isNull()) + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + ResourceGroup::LoadResourceOrderMap::iterator i = + grp->loadResourceOrderMap.find( + res->getCreator()->getLoadingOrder()); + if (i != grp->loadResourceOrderMap.end()) + { + // Iterate over the resource list and remove + LoadUnloadResourceList* resList = i->second; + for (LoadUnloadResourceList::iterator l = resList->begin(); + l != resList->end(); ++ l) + { + if ((*l).getPointer() == res.getPointer()) { - if (mLoadingListener) - mLoadingListener->resourceStreamOpened(fii->filename, grp->name, 0, stream); - - if(fii->archive->getType() == "FileSystem" && stream->size() <= 1024 * 1024) - { - DataStreamPtr cachedCopy; - cachedCopy.bind(OGRE_NEW MemoryDataStream(stream->getName(), stream)); - su->parseScript(cachedCopy, grp->name); - } - else - su->parseScript(stream, grp->name); + // this is the one + resList->erase(l); + break; } } - fireScriptEnded(fii->filename, skipScript); - } + } } - } - - fireResourceGroupScriptingEnded(grp->name); - LogManager::getSingleton().logMessage( - "Finished parsing scripts for resource group " + grp->name); - } - //----------------------------------------------------------------------- - void ResourceGroupManager::createDeclaredResources(ResourceGroup* grp) - { - - for (ResourceDeclarationList::iterator i = grp->resourceDeclarations.begin(); - i != grp->resourceDeclarations.end(); ++i) - { - ResourceDeclaration& dcl = *i; - // Retrieve the appropriate manager - ResourceManager* mgr = _getResourceManager(dcl.resourceType); - // Create the resource - ResourcePtr res = mgr->createResource(dcl.resourceName, grp->name, - dcl.loader != 0, dcl.loader, &dcl.parameters); - // Add resource to load list - ResourceGroup::LoadResourceOrderMap::iterator li = - grp->loadResourceOrderMap.find(mgr->getLoadingOrder()); - LoadUnloadResourceList* loadList; - if (li == grp->loadResourceOrderMap.end()) - { - loadList = OGRE_NEW_T(LoadUnloadResourceList, MEMCATEGORY_RESOURCE)(); - grp->loadResourceOrderMap[mgr->getLoadingOrder()] = loadList; - } - } - - } - //----------------------------------------------------------------------- - void ResourceGroupManager::_notifyResourceCreated(ResourcePtr& res) - { - if (mCurrentGroup && res->getGroup() == mCurrentGroup->name) - { - // Use current group (batch loading) - addCreatedResource(res, *mCurrentGroup); - } - else - { - // Find group - ResourceGroup* grp = getResourceGroup(res->getGroup()); - if (grp) - { - addCreatedResource(res, *grp); - } - } - - fireResourceCreated(res); - } - //----------------------------------------------------------------------- - void ResourceGroupManager::_notifyResourceRemoved(ResourcePtr& res) - { - fireResourceRemove(res); - - if (mCurrentGroup) - { - // Do nothing - we're batch unloading so list will be cleared - } - else - { - // Find group - ResourceGroup* grp = getResourceGroup(res->getGroup()); - if (grp) - { - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - ResourceGroup::LoadResourceOrderMap::iterator i = - grp->loadResourceOrderMap.find( - res->getCreator()->getLoadingOrder()); - if (i != grp->loadResourceOrderMap.end()) - { - // Iterate over the resource list and remove - LoadUnloadResourceList* resList = i->second; - for (LoadUnloadResourceList::iterator l = resList->begin(); - l != resList->end(); ++ l) - { - if ((*l).getPointer() == res.getPointer()) - { - // this is the one - resList->erase(l); - break; - } - } - } - } - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::_notifyResourceGroupChanged(const String& oldGroup, - Resource* res) - { - ResourcePtr resPtr; - - // find old entry - ResourceGroup* grp = getResourceGroup(oldGroup); - - if (grp) - { + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::_notifyResourceGroupChanged(const String& oldGroup, + Resource* res) + { + ResourcePtr resPtr; + + // find old entry + ResourceGroup* grp = getResourceGroup(oldGroup); + + if (grp) + { OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - Real order = res->getCreator()->getLoadingOrder(); - ResourceGroup::LoadResourceOrderMap::iterator i = - grp->loadResourceOrderMap.find(order); - assert(i != grp->loadResourceOrderMap.end()); - LoadUnloadResourceList* loadList = i->second; - for (LoadUnloadResourceList::iterator l = loadList->begin(); - l != loadList->end(); ++l) - { - if ((*l).getPointer() == res) - { - resPtr = *l; - loadList->erase(l); - break; - } - } - } - - if (!resPtr.isNull()) - { - // New group - ResourceGroup* newGrp = getResourceGroup(res->getGroup()); - - addCreatedResource(resPtr, *newGrp); - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::_notifyAllResourcesRemoved(ResourceManager* manager) - { + Real order = res->getCreator()->getLoadingOrder(); + ResourceGroup::LoadResourceOrderMap::iterator i = + grp->loadResourceOrderMap.find(order); + assert(i != grp->loadResourceOrderMap.end()); + LoadUnloadResourceList* loadList = i->second; + for (LoadUnloadResourceList::iterator l = loadList->begin(); + l != loadList->end(); ++l) + { + if ((*l).getPointer() == res) + { + resPtr = *l; + loadList->erase(l); + break; + } + } + } + + if (!resPtr.isNull()) + { + // New group + ResourceGroup* newGrp = getResourceGroup(res->getGroup()); + + addCreatedResource(resPtr, *newGrp); + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::_notifyAllResourcesRemoved(ResourceManager* manager) + { OGRE_LOCK_AUTO_MUTEX; - // Iterate over all groups - for (ResourceGroupMap::iterator grpi = mResourceGroupMap.begin(); - grpi != mResourceGroupMap.end(); ++grpi) - { + // Iterate over all groups + for (ResourceGroupMap::iterator grpi = mResourceGroupMap.begin(); + grpi != mResourceGroupMap.end(); ++grpi) + { OGRE_LOCK_MUTEX(grpi->second->OGRE_AUTO_MUTEX_NAME); - // Iterate over all priorities - for (ResourceGroup::LoadResourceOrderMap::iterator oi = grpi->second->loadResourceOrderMap.begin(); - oi != grpi->second->loadResourceOrderMap.end(); ++oi) - { - // Iterate over all resources - for (LoadUnloadResourceList::iterator l = oi->second->begin(); - l != oi->second->end(); ) - { - if ((*l)->getCreator() == manager) - { - // Increment first since iterator will be invalidated - LoadUnloadResourceList::iterator del = l++; - oi->second->erase(del); - } - else - { - ++l; - } - } - } - - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::addCreatedResource(ResourcePtr& res, ResourceGroup& grp) - { + // Iterate over all priorities + for (ResourceGroup::LoadResourceOrderMap::iterator oi = grpi->second->loadResourceOrderMap.begin(); + oi != grpi->second->loadResourceOrderMap.end(); ++oi) + { + // Iterate over all resources + for (LoadUnloadResourceList::iterator l = oi->second->begin(); + l != oi->second->end(); ) + { + if ((*l)->getCreator() == manager) + { + // Increment first since iterator will be invalidated + LoadUnloadResourceList::iterator del = l++; + oi->second->erase(del); + } + else + { + ++l; + } + } + } + + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::addCreatedResource(ResourcePtr& res, ResourceGroup& grp) + { OGRE_LOCK_MUTEX(grp.OGRE_AUTO_MUTEX_NAME); - Real order = res->getCreator()->getLoadingOrder(); - - ResourceGroup::LoadResourceOrderMap::iterator i = grp.loadResourceOrderMap.find(order); - LoadUnloadResourceList* loadList; - if (i == grp.loadResourceOrderMap.end()) - { - loadList = OGRE_NEW_T(LoadUnloadResourceList, MEMCATEGORY_RESOURCE)(); - grp.loadResourceOrderMap[order] = loadList; - } - else - { - loadList = i->second; - } - loadList->push_back(res); - } - //----------------------------------------------------------------------- - ResourceGroupManager::ResourceGroup* ResourceGroupManager::getResourceGroup(const String& name) - { + Real order = res->getCreator()->getLoadingOrder(); + + ResourceGroup::LoadResourceOrderMap::iterator i = grp.loadResourceOrderMap.find(order); + LoadUnloadResourceList* loadList; + if (i == grp.loadResourceOrderMap.end()) + { + loadList = OGRE_NEW_T(LoadUnloadResourceList, MEMCATEGORY_RESOURCE)(); + grp.loadResourceOrderMap[order] = loadList; + } + else + { + loadList = i->second; + } + loadList->push_back(res); + } + //----------------------------------------------------------------------- + ResourceGroupManager::ResourceGroup* ResourceGroupManager::getResourceGroup(const String& name) + { OGRE_LOCK_AUTO_MUTEX; - ResourceGroupMap::iterator i = mResourceGroupMap.find(name); - if (i != mResourceGroupMap.end()) - { - return i->second; - } - return 0; + ResourceGroupMap::iterator i = mResourceGroupMap.find(name); + if (i != mResourceGroupMap.end()) + { + return i->second; + } + return 0; - } + } //----------------------------------------------------------------------- ResourceManager* ResourceGroupManager::_getResourceManager(const String& resourceType) { @@ -1301,86 +1301,86 @@ namespace Ogre { return i->second; } - //----------------------------------------------------------------------- - void ResourceGroupManager::dropGroupContents(ResourceGroup* grp) - { + //----------------------------------------------------------------------- + void ResourceGroupManager::dropGroupContents(ResourceGroup* grp) + { OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); - bool groupSet = false; - if (!mCurrentGroup) - { - // Set current group to indicate ignoring of notifications - mCurrentGroup = grp; - groupSet = true; - } - // delete all the load list entries - ResourceGroup::LoadResourceOrderMap::iterator j, jend; - jend = grp->loadResourceOrderMap.end(); - for (j = grp->loadResourceOrderMap.begin(); j != jend; ++j) - { - // Iterate over resources - for (LoadUnloadResourceList::iterator k = j->second->begin(); - k != j->second->end(); ++k) - { - (*k)->getCreator()->remove((*k)->getHandle()); - } - OGRE_DELETE_T(j->second, LoadUnloadResourceList, MEMCATEGORY_RESOURCE); - } + bool groupSet = false; + if (!mCurrentGroup) + { + // Set current group to indicate ignoring of notifications + mCurrentGroup = grp; + groupSet = true; + } + // delete all the load list entries + ResourceGroup::LoadResourceOrderMap::iterator j, jend; + jend = grp->loadResourceOrderMap.end(); + for (j = grp->loadResourceOrderMap.begin(); j != jend; ++j) + { + // Iterate over resources + for (LoadUnloadResourceList::iterator k = j->second->begin(); + k != j->second->end(); ++k) + { + (*k)->getCreator()->remove((*k)->getHandle()); + } + OGRE_DELETE_T(j->second, LoadUnloadResourceList, MEMCATEGORY_RESOURCE); + } grp->loadResourceOrderMap.clear(); - if (groupSet) - { - mCurrentGroup = 0; - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::deleteGroup(ResourceGroup* grp) - { + if (groupSet) + { + mCurrentGroup = 0; + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::deleteGroup(ResourceGroup* grp) + { { OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); - // delete all the load list entries - ResourceGroup::LoadResourceOrderMap::iterator j, jend; - jend = grp->loadResourceOrderMap.end(); - for (j = grp->loadResourceOrderMap.begin(); j != jend; ++j) - { - // Don't iterate over resources to drop with ResourceManager - // Assume this is being done anyway since this is a shutdown method - OGRE_DELETE_T(j->second, LoadUnloadResourceList, MEMCATEGORY_RESOURCE); - } - // Drop location list - for (LocationList::iterator ll = grp->locationList.begin(); - ll != grp->locationList.end(); ++ll) - { - OGRE_DELETE_T(*ll, ResourceLocation, MEMCATEGORY_RESOURCE); - } - } - - // delete ResourceGroup - OGRE_DELETE_T(grp, ResourceGroup, MEMCATEGORY_RESOURCE); - } - //----------------------------------------------------------------------- - void ResourceGroupManager::fireResourceGroupScriptingStarted(const String& groupName, size_t scriptCount) - { + // delete all the load list entries + ResourceGroup::LoadResourceOrderMap::iterator j, jend; + jend = grp->loadResourceOrderMap.end(); + for (j = grp->loadResourceOrderMap.begin(); j != jend; ++j) + { + // Don't iterate over resources to drop with ResourceManager + // Assume this is being done anyway since this is a shutdown method + OGRE_DELETE_T(j->second, LoadUnloadResourceList, MEMCATEGORY_RESOURCE); + } + // Drop location list + for (LocationList::iterator ll = grp->locationList.begin(); + ll != grp->locationList.end(); ++ll) + { + OGRE_DELETE_T(*ll, ResourceLocation, MEMCATEGORY_RESOURCE); + } + } + + // delete ResourceGroup + OGRE_DELETE_T(grp, ResourceGroup, MEMCATEGORY_RESOURCE); + } + //----------------------------------------------------------------------- + void ResourceGroupManager::fireResourceGroupScriptingStarted(const String& groupName, size_t scriptCount) + { OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - (*l)->resourceGroupScriptingStarted(groupName, scriptCount); - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::fireScriptStarted(const String& scriptName, bool &skipScript) - { + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + (*l)->resourceGroupScriptingStarted(groupName, scriptCount); + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::fireScriptStarted(const String& scriptName, bool &skipScript) + { OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - bool temp = false; - (*l)->scriptParseStarted(scriptName, temp); - if(temp) - skipScript = true; - } - } + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + bool temp = false; + (*l)->scriptParseStarted(scriptName, temp); + if(temp) + skipScript = true; + } + } //----------------------------------------------------------------------- void ResourceGroupManager::fireScriptEnded(const String& scriptName, bool skipped) { @@ -1391,36 +1391,36 @@ namespace Ogre { (*l)->scriptParseEnded(scriptName, skipped); } } - //----------------------------------------------------------------------- - void ResourceGroupManager::fireResourceGroupScriptingEnded(const String& groupName) - { + //----------------------------------------------------------------------- + void ResourceGroupManager::fireResourceGroupScriptingEnded(const String& groupName) + { OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - (*l)->resourceGroupScriptingEnded(groupName); - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::fireResourceGroupLoadStarted(const String& groupName, size_t resourceCount) - { + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + (*l)->resourceGroupScriptingEnded(groupName); + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::fireResourceGroupLoadStarted(const String& groupName, size_t resourceCount) + { OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - (*l)->resourceGroupLoadStarted(groupName, resourceCount); - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::fireResourceLoadStarted(const ResourcePtr& resource) - { + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + (*l)->resourceGroupLoadStarted(groupName, resourceCount); + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::fireResourceLoadStarted(const ResourcePtr& resource) + { OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - (*l)->resourceLoadStarted(resource); - } - } + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + (*l)->resourceLoadStarted(resource); + } + } //----------------------------------------------------------------------- void ResourceGroupManager::fireResourceLoadEnded(void) { @@ -1435,11 +1435,11 @@ namespace Ogre { void ResourceGroupManager::_notifyWorldGeometryStageStarted(const String& desc) { OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - (*l)->worldGeometryStageStarted(desc); - } + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + (*l)->worldGeometryStageStarted(desc); + } } //----------------------------------------------------------------------- void ResourceGroupManager::_notifyWorldGeometryStageEnded(void) @@ -1451,26 +1451,26 @@ namespace Ogre { (*l)->worldGeometryStageEnded(); } } - //----------------------------------------------------------------------- - void ResourceGroupManager::fireResourceGroupLoadEnded(const String& groupName) - { + //----------------------------------------------------------------------- + void ResourceGroupManager::fireResourceGroupLoadEnded(const String& groupName) + { OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - (*l)->resourceGroupLoadEnded(groupName); - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::fireResourceGroupPrepareStarted(const String& groupName, size_t resourceCount) - { + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + (*l)->resourceGroupLoadEnded(groupName); + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::fireResourceGroupPrepareStarted(const String& groupName, size_t resourceCount) + { OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - (*l)->resourceGroupPrepareStarted(groupName, resourceCount); - } - } + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + (*l)->resourceGroupPrepareStarted(groupName, resourceCount); + } + } //----------------------------------------------------------------------- void ResourceGroupManager::fireResourcePrepareStarted(const ResourcePtr& resource) { @@ -1491,37 +1491,37 @@ namespace Ogre { (*l)->resourcePrepareEnded(); } } - //----------------------------------------------------------------------- - void ResourceGroupManager::fireResourceGroupPrepareEnded(const String& groupName) - { + //----------------------------------------------------------------------- + void ResourceGroupManager::fireResourceGroupPrepareEnded(const String& groupName) + { OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - (*l)->resourceGroupPrepareEnded(groupName); - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::fireResourceCreated(const ResourcePtr& resource) - { - OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - (*l)->resourceCreated(resource); - } - } - //----------------------------------------------------------------------- - void ResourceGroupManager::fireResourceRemove(const ResourcePtr& resource) - { - OGRE_LOCK_AUTO_MUTEX; - for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); - l != mResourceGroupListenerList.end(); ++l) - { - (*l)->resourceRemove(resource); - } - } - //----------------------------------------------------------------------- + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + (*l)->resourceGroupPrepareEnded(groupName); + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::fireResourceCreated(const ResourcePtr& resource) + { + OGRE_LOCK_AUTO_MUTEX; + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + (*l)->resourceCreated(resource); + } + } + //----------------------------------------------------------------------- + void ResourceGroupManager::fireResourceRemove(const ResourcePtr& resource) + { + OGRE_LOCK_AUTO_MUTEX; + for (ResourceGroupListenerList::iterator l = mResourceGroupListenerList.begin(); + l != mResourceGroupListenerList.end(); ++l) + { + (*l)->resourceRemove(resource); + } + } + //----------------------------------------------------------------------- void ResourceGroupManager::shutdownAll(void) { OGRE_LOCK_AUTO_MUTEX; @@ -1537,7 +1537,7 @@ namespace Ogre { StringVectorPtr ResourceGroupManager::listResourceNames(const String& groupName, bool dirs) { OGRE_LOCK_AUTO_MUTEX; - // MEMCATEGORY_GENERAL is the only category supported for SharedPtr + // MEMCATEGORY_GENERAL is the only category supported for SharedPtr StringVectorPtr vec(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); // Try to find in resource index first @@ -1568,7 +1568,7 @@ namespace Ogre { FileInfoListPtr ResourceGroupManager::listResourceFileInfo(const String& groupName, bool dirs) { OGRE_LOCK_AUTO_MUTEX; - // MEMCATEGORY_GENERAL is the only category supported for SharedPtr + // MEMCATEGORY_GENERAL is the only category supported for SharedPtr FileInfoListPtr vec(OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); // Try to find in resource index first @@ -1599,8 +1599,8 @@ namespace Ogre { const String& pattern, bool dirs) { OGRE_LOCK_AUTO_MUTEX; - // MEMCATEGORY_GENERAL is the only category supported for SharedPtr - StringVectorPtr vec(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); + // MEMCATEGORY_GENERAL is the only category supported for SharedPtr + StringVectorPtr vec(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); // Try to find in resource index first ResourceGroup* grp = getResourceGroup(groupName); @@ -1629,7 +1629,7 @@ namespace Ogre { const String& pattern, bool dirs) { OGRE_LOCK_AUTO_MUTEX; - // MEMCATEGORY_GENERAL is the only category supported for SharedPtr + // MEMCATEGORY_GENERAL is the only category supported for SharedPtr FileInfoListPtr vec(OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); // Try to find in resource index first @@ -1655,11 +1655,11 @@ namespace Ogre { return vec; } //----------------------------------------------------------------------- - bool ResourceGroupManager::resourceExists(const String& groupName, const String& resourceName) - { + bool ResourceGroupManager::resourceExists(const String& groupName, const String& resourceName) + { OGRE_LOCK_AUTO_MUTEX; - // Try to find in resource index first + // Try to find in resource index first ResourceGroup* grp = getResourceGroup(groupName); if (!grp) { @@ -1668,21 +1668,21 @@ namespace Ogre { "ResourceGroupManager::resourceExists"); } - return resourceExists(grp, resourceName); - } + return resourceExists(grp, resourceName); + } //----------------------------------------------------------------------- - bool ResourceGroupManager::resourceExists(ResourceGroup* grp, const String& resourceName) - { + bool ResourceGroupManager::resourceExists(ResourceGroup* grp, const String& resourceName) + { OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - // Try indexes first - ResourceLocationIndex::iterator rit = grp->resourceIndexCaseSensitive.find(resourceName); - if (rit != grp->resourceIndexCaseSensitive.end()) - { - // Found in the index - return true; - } + // Try indexes first + ResourceLocationIndex::iterator rit = grp->resourceIndexCaseSensitive.find(resourceName); + if (rit != grp->resourceIndexCaseSensitive.end()) + { + // Found in the index + return true; + } else { // try case insensitive @@ -1694,53 +1694,53 @@ namespace Ogre { // Found in the index return true; } - else - { - // Search the hard way - LocationList::iterator li, liend; - liend = grp->locationList.end(); - for (li = grp->locationList.begin(); li != liend; ++li) - { - Archive* arch = (*li)->archive; + else + { + // Search the hard way + LocationList::iterator li, liend; + liend = grp->locationList.end(); + for (li = grp->locationList.begin(); li != liend; ++li) + { + Archive* arch = (*li)->archive; if (arch->exists(resourceName)) - { - return true; - } - } - } + { + return true; + } + } + } } - return false; + return false; - } - //----------------------------------------------------------------------- - time_t ResourceGroupManager::resourceModifiedTime(const String& groupName, const String& resourceName) - { + } + //----------------------------------------------------------------------- + time_t ResourceGroupManager::resourceModifiedTime(const String& groupName, const String& resourceName) + { OGRE_LOCK_AUTO_MUTEX; - // Try to find in resource index first - ResourceGroup* grp = getResourceGroup(groupName); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot locate a resource group called '" + groupName + "'", - "ResourceGroupManager::resourceModifiedTime"); - } - - return resourceModifiedTime(grp, resourceName); - - } - //----------------------------------------------------------------------- - time_t ResourceGroupManager::resourceModifiedTime(ResourceGroup* grp, const String& resourceName) - { + // Try to find in resource index first + ResourceGroup* grp = getResourceGroup(groupName); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot locate a resource group called '" + groupName + "'", + "ResourceGroupManager::resourceModifiedTime"); + } + + return resourceModifiedTime(grp, resourceName); + + } + //----------------------------------------------------------------------- + time_t ResourceGroupManager::resourceModifiedTime(ResourceGroup* grp, const String& resourceName) + { OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - // Try indexes first - ResourceLocationIndex::iterator rit = grp->resourceIndexCaseSensitive.find(resourceName); - if (rit != grp->resourceIndexCaseSensitive.end()) - { - return rit->second->getModifiedTime(resourceName); - } + // Try indexes first + ResourceLocationIndex::iterator rit = grp->resourceIndexCaseSensitive.find(resourceName); + if (rit != grp->resourceIndexCaseSensitive.end()) + { + return rit->second->getModifiedTime(resourceName); + } else { // try case insensitive @@ -1749,70 +1749,70 @@ namespace Ogre { rit = grp->resourceIndexCaseInsensitive.find(lcResourceName); if (rit != grp->resourceIndexCaseInsensitive.end()) { - return rit->second->getModifiedTime(resourceName); + return rit->second->getModifiedTime(resourceName); } - else - { - // Search the hard way - LocationList::iterator li, liend; - liend = grp->locationList.end(); - for (li = grp->locationList.begin(); li != liend; ++li) - { - Archive* arch = (*li)->archive; - time_t testTime = arch->getModifiedTime(resourceName); + else + { + // Search the hard way + LocationList::iterator li, liend; + liend = grp->locationList.end(); + for (li = grp->locationList.begin(); li != liend; ++li) + { + Archive* arch = (*li)->archive; + time_t testTime = arch->getModifiedTime(resourceName); if (testTime > 0) - { - return testTime; - } - } - } - } - - return 0; - } - //----------------------------------------------------------------------- - ResourceGroupManager::ResourceGroup* - ResourceGroupManager::findGroupContainingResourceImpl(const String& filename) - { + { + return testTime; + } + } + } + } + + return 0; + } + //----------------------------------------------------------------------- + ResourceGroupManager::ResourceGroup* + ResourceGroupManager::findGroupContainingResourceImpl(const String& filename) + { OGRE_LOCK_AUTO_MUTEX; - // Iterate over resource groups and find - for (ResourceGroupMap::iterator i = mResourceGroupMap.begin(); - i != mResourceGroupMap.end(); ++i) - { - ResourceGroup* grp = i->second; + // Iterate over resource groups and find + for (ResourceGroupMap::iterator i = mResourceGroupMap.begin(); + i != mResourceGroupMap.end(); ++i) + { + ResourceGroup* grp = i->second; OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - - if (resourceExists(grp, filename)) - return grp; - } - // Not found - return 0; - } - //----------------------------------------------------------------------- - bool ResourceGroupManager::resourceExistsInAnyGroup(const String& filename) - { - ResourceGroup* grp = findGroupContainingResourceImpl(filename); - if (!grp) - return false; - return true; - } - //----------------------------------------------------------------------- - const String& ResourceGroupManager::findGroupContainingResource(const String& filename) - { - ResourceGroup* grp = findGroupContainingResourceImpl(filename); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Unable to derive resource group for " + - filename + " automatically since the resource was not " - "found.", - "ResourceGroupManager::findGroupContainingResource"); - } - return grp->name; - } + + if (resourceExists(grp, filename)) + return grp; + } + // Not found + return 0; + } + //----------------------------------------------------------------------- + bool ResourceGroupManager::resourceExistsInAnyGroup(const String& filename) + { + ResourceGroup* grp = findGroupContainingResourceImpl(filename); + if (!grp) + return false; + return true; + } + //----------------------------------------------------------------------- + const String& ResourceGroupManager::findGroupContainingResource(const String& filename) + { + ResourceGroup* grp = findGroupContainingResourceImpl(filename); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Unable to derive resource group for " + + filename + " automatically since the resource was not " + "found.", + "ResourceGroupManager::findGroupContainingResource"); + } + return grp->name; + } //----------------------------------------------------------------------- StringVectorPtr ResourceGroupManager::listResourceLocations(const String& groupName) { @@ -1906,36 +1906,36 @@ namespace Ogre { grp->worldGeometry = BLANKSTRING; grp->worldGeometrySceneManager = 0; } - //----------------------------------------------------------------------- - bool ResourceGroupManager::isResourceGroupInGlobalPool(const String& name) + //----------------------------------------------------------------------- + bool ResourceGroupManager::isResourceGroupInGlobalPool(const String& name) { OGRE_LOCK_AUTO_MUTEX; - ResourceGroup* grp = getResourceGroup(name); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find a group named " + name, - "ResourceGroupManager::isResourceGroupInitialised"); - } - return grp->inGlobalPool; + ResourceGroup* grp = getResourceGroup(name); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find a group named " + name, + "ResourceGroupManager::isResourceGroupInitialised"); + } + return grp->inGlobalPool; } //----------------------------------------------------------------------- - StringVector ResourceGroupManager::getResourceGroups(void) - { + StringVector ResourceGroupManager::getResourceGroups(void) + { OGRE_LOCK_AUTO_MUTEX; - StringVector vec; - for (ResourceGroupMap::iterator i = mResourceGroupMap.begin(); - i != mResourceGroupMap.end(); ++i) - { - vec.push_back(i->second->name); - } - return vec; - } - //----------------------------------------------------------------------- - ResourceGroupManager::ResourceDeclarationList - ResourceGroupManager::getResourceDeclarationList(const String& group) - { + StringVector vec; + for (ResourceGroupMap::iterator i = mResourceGroupMap.begin(); + i != mResourceGroupMap.end(); ++i) + { + vec.push_back(i->second->name); + } + return vec; + } + //----------------------------------------------------------------------- + ResourceGroupManager::ResourceDeclarationList + ResourceGroupManager::getResourceDeclarationList(const String& group) + { OGRE_LOCK_AUTO_MUTEX; ResourceGroup* grp = getResourceGroup(group); if (!grp) @@ -1946,104 +1946,104 @@ namespace Ogre { } OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - return grp->resourceDeclarations; - } - //--------------------------------------------------------------------- - const ResourceGroupManager::LocationList& - ResourceGroupManager::getResourceLocationList(const String& group) - { + return grp->resourceDeclarations; + } + //--------------------------------------------------------------------- + const ResourceGroupManager::LocationList& + ResourceGroupManager::getResourceLocationList(const String& group) + { OGRE_LOCK_AUTO_MUTEX; - ResourceGroup* grp = getResourceGroup(group); - if (!grp) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot locate a resource group called '" + group + "'", - "ResourceGroupManager::getResourceLocationList"); - } - - OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex - return grp->locationList; - - } - //------------------------------------------------------------------------- - void ResourceGroupManager::setLoadingListener(ResourceLoadingListener *listener) - { - mLoadingListener = listener; - } - //------------------------------------------------------------------------- - ResourceLoadingListener *ResourceGroupManager::getLoadingListener() - { - return mLoadingListener; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - void ResourceGroupManager::ResourceGroup::addToIndex(const String& filename, Archive* arch) - { - // internal, assumes mutex lock has already been obtained - this->resourceIndexCaseSensitive[filename] = arch; - - if (!arch->isCaseSensitive()) - { - String lcase = filename; - StringUtil::toLowerCase(lcase); - this->resourceIndexCaseInsensitive[lcase] = arch; - } - } - //--------------------------------------------------------------------- - void ResourceGroupManager::ResourceGroup::removeFromIndex(const String& filename, Archive* arch) - { - // internal, assumes mutex lock has already been obtained - ResourceLocationIndex::iterator i = this->resourceIndexCaseSensitive.find(filename); - if (i != this->resourceIndexCaseSensitive.end() && i->second == arch) - this->resourceIndexCaseSensitive.erase(i); - - if (!arch->isCaseSensitive()) - { - String lcase = filename; - StringUtil::toLowerCase(lcase); - i = this->resourceIndexCaseInsensitive.find(lcase); - if (i != this->resourceIndexCaseInsensitive.end() && i->second == arch) - this->resourceIndexCaseInsensitive.erase(i); - } - } - //--------------------------------------------------------------------- - void ResourceGroupManager::ResourceGroup::removeFromIndex(Archive* arch) - { - // Delete indexes - ResourceLocationIndex::iterator rit, ritend; - ritend = this->resourceIndexCaseInsensitive.end(); - for (rit = this->resourceIndexCaseInsensitive.begin(); rit != ritend;) - { - if (rit->second == arch) - { - ResourceLocationIndex::iterator del = rit++; - this->resourceIndexCaseInsensitive.erase(del); - } - else - { - ++rit; - } - } - ritend = this->resourceIndexCaseSensitive.end(); - for (rit = this->resourceIndexCaseSensitive.begin(); rit != ritend;) - { - if (rit->second == arch) - { - ResourceLocationIndex::iterator del = rit++; - this->resourceIndexCaseSensitive.erase(del); - } - else - { - ++rit; - } - } - - } - //--------------------------------------------------------------------- - //----------------------------------------------------------------------- - ScriptLoader::~ScriptLoader() - { - } + ResourceGroup* grp = getResourceGroup(group); + if (!grp) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot locate a resource group called '" + group + "'", + "ResourceGroupManager::getResourceLocationList"); + } + + OGRE_LOCK_MUTEX(grp->OGRE_AUTO_MUTEX_NAME); // lock group mutex + return grp->locationList; + + } + //------------------------------------------------------------------------- + void ResourceGroupManager::setLoadingListener(ResourceLoadingListener *listener) + { + mLoadingListener = listener; + } + //------------------------------------------------------------------------- + ResourceLoadingListener *ResourceGroupManager::getLoadingListener() + { + return mLoadingListener; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void ResourceGroupManager::ResourceGroup::addToIndex(const String& filename, Archive* arch) + { + // internal, assumes mutex lock has already been obtained + this->resourceIndexCaseSensitive[filename] = arch; + + if (!arch->isCaseSensitive()) + { + String lcase = filename; + StringUtil::toLowerCase(lcase); + this->resourceIndexCaseInsensitive[lcase] = arch; + } + } + //--------------------------------------------------------------------- + void ResourceGroupManager::ResourceGroup::removeFromIndex(const String& filename, Archive* arch) + { + // internal, assumes mutex lock has already been obtained + ResourceLocationIndex::iterator i = this->resourceIndexCaseSensitive.find(filename); + if (i != this->resourceIndexCaseSensitive.end() && i->second == arch) + this->resourceIndexCaseSensitive.erase(i); + + if (!arch->isCaseSensitive()) + { + String lcase = filename; + StringUtil::toLowerCase(lcase); + i = this->resourceIndexCaseInsensitive.find(lcase); + if (i != this->resourceIndexCaseInsensitive.end() && i->second == arch) + this->resourceIndexCaseInsensitive.erase(i); + } + } + //--------------------------------------------------------------------- + void ResourceGroupManager::ResourceGroup::removeFromIndex(Archive* arch) + { + // Delete indexes + ResourceLocationIndex::iterator rit, ritend; + ritend = this->resourceIndexCaseInsensitive.end(); + for (rit = this->resourceIndexCaseInsensitive.begin(); rit != ritend;) + { + if (rit->second == arch) + { + ResourceLocationIndex::iterator del = rit++; + this->resourceIndexCaseInsensitive.erase(del); + } + else + { + ++rit; + } + } + ritend = this->resourceIndexCaseSensitive.end(); + for (rit = this->resourceIndexCaseSensitive.begin(); rit != ritend;) + { + if (rit->second == arch) + { + ResourceLocationIndex::iterator del = rit++; + this->resourceIndexCaseSensitive.erase(del); + } + else + { + ++rit; + } + } + + } + //--------------------------------------------------------------------- + //----------------------------------------------------------------------- + ScriptLoader::~ScriptLoader() + { + } } diff --git a/OgreMain/src/OgreResourceManager.cpp b/OgreMain/src/OgreResourceManager.cpp index 3bf66b9bfdc..dbab19b4a1a 100644 --- a/OgreMain/src/OgreResourceManager.cpp +++ b/OgreMain/src/OgreResourceManager.cpp @@ -35,7 +35,7 @@ namespace Ogre { //----------------------------------------------------------------------- ResourceManager::ResourceManager() - : mNextHandle(1), mMemoryUsage(0), mVerbose(true), mLoadOrder(0) + : mNextHandle(1), mMemoryUsage(0), mVerbose(true), mLoadOrder(0) { // Init memory limit & usage mMemoryBudget = std::numeric_limits::max(); @@ -43,52 +43,52 @@ namespace Ogre { //----------------------------------------------------------------------- ResourceManager::~ResourceManager() { - destroyAllResourcePools(); + destroyAllResourcePools(); removeAll(); } - //----------------------------------------------------------------------- - ResourcePtr ResourceManager::createResource(const String& name, const String& group, - bool isManual, ManualResourceLoader* loader, const NameValuePairList* params) - { - // Call creation implementation - ResourcePtr ret = ResourcePtr( + //----------------------------------------------------------------------- + ResourcePtr ResourceManager::createResource(const String& name, const String& group, + bool isManual, ManualResourceLoader* loader, const NameValuePairList* params) + { + // Call creation implementation + ResourcePtr ret = ResourcePtr( createImpl(name, getNextHandle(), group, isManual, loader, params)); if (params) ret->setParameterList(*params); - addImpl(ret); - // Tell resource group manager - ResourceGroupManager::getSingleton()._notifyResourceCreated(ret); - return ret; + addImpl(ret); + // Tell resource group manager + ResourceGroupManager::getSingleton()._notifyResourceCreated(ret); + return ret; - } + } //----------------------------------------------------------------------- ResourceManager::ResourceCreateOrRetrieveResult - ResourceManager::createOrRetrieve( - const String& name, const String& group, - bool isManual, ManualResourceLoader* loader, - const NameValuePairList* params) - { - // Lock for the whole get / insert + ResourceManager::createOrRetrieve( + const String& name, const String& group, + bool isManual, ManualResourceLoader* loader, + const NameValuePairList* params) + { + // Lock for the whole get / insert OGRE_LOCK_AUTO_MUTEX; - ResourcePtr res = getResourceByName(name, group); - bool created = false; - if (res.isNull()) - { - created = true; - res = createResource(name, group, isManual, loader, params); - } + ResourcePtr res = getResourceByName(name, group); + bool created = false; + if (res.isNull()) + { + created = true; + res = createResource(name, group, isManual, loader, params); + } - return ResourceCreateOrRetrieveResult(res, created); - } + return ResourceCreateOrRetrieveResult(res, created); + } //----------------------------------------------------------------------- ResourcePtr ResourceManager::prepare(const String& name, const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* loadParams, bool backgroundThread) { ResourcePtr r = createOrRetrieve(name,group,isManual,loader,loadParams).first; - // ensure prepared + // ensure prepared r->prepare(backgroundThread); return r; } @@ -98,123 +98,123 @@ namespace Ogre { const NameValuePairList* loadParams, bool backgroundThread) { ResourcePtr r = createOrRetrieve(name,group,isManual,loader,loadParams).first; - // ensure loaded + // ensure loaded r->load(backgroundThread); return r; } //----------------------------------------------------------------------- - void ResourceManager::addImpl( ResourcePtr& res ) - { + void ResourceManager::addImpl( ResourcePtr& res ) + { OGRE_LOCK_AUTO_MUTEX; - std::pair result; - if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup())) - { - result = mResources.insert( ResourceMap::value_type( res->getName(), res ) ); - } - else - { - ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(res->getGroup()); - - // we will create the group if it doesn't exists in our list - if( itGroup == mResourcesWithGroup.end()) - { - ResourceMap dummy; - mResourcesWithGroup.insert( ResourceWithGroupMap::value_type( res->getGroup(), dummy ) ); - itGroup = mResourcesWithGroup.find(res->getGroup()); - } - result = itGroup->second.insert( ResourceMap::value_type( res->getName(), res ) ); - - } - - if (!result.second) - { - // Attempt to resolve the collision - if(ResourceGroupManager::getSingleton().getLoadingListener()) - { - if(ResourceGroupManager::getSingleton().getLoadingListener()->resourceCollision(res.get(), this)) - { - // Try to do the addition again, no seconds attempts to resolve collisions are allowed - std::pair insertResult; - if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup())) - { - insertResult = mResources.insert( ResourceMap::value_type( res->getName(), res ) ); - } - else - { - ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(res->getGroup()); - insertResult = itGroup->second.insert( ResourceMap::value_type( res->getName(), res ) ); - } - if (!insertResult.second) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the name " + res->getName() + - " already exists.", "ResourceManager::add"); - } - - std::pair resultHandle = - mResourcesByHandle.insert( ResourceHandleMap::value_type( res->getHandle(), res ) ); - if (!resultHandle.second) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the handle " + - StringConverter::toString((long) (res->getHandle())) + - " already exists.", "ResourceManager::add"); - } - } - } - } - else - { - // Insert the handle - std::pair resultHandle = - mResourcesByHandle.insert( ResourceHandleMap::value_type( res->getHandle(), res ) ); - if (!resultHandle.second) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the handle " + - StringConverter::toString((long) (res->getHandle())) + - " already exists.", "ResourceManager::add"); - } - } - } - //----------------------------------------------------------------------- - void ResourceManager::removeImpl( ResourcePtr& res ) - { + std::pair result; + if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup())) + { + result = mResources.insert( ResourceMap::value_type( res->getName(), res ) ); + } + else + { + ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(res->getGroup()); + + // we will create the group if it doesn't exists in our list + if( itGroup == mResourcesWithGroup.end()) + { + ResourceMap dummy; + mResourcesWithGroup.insert( ResourceWithGroupMap::value_type( res->getGroup(), dummy ) ); + itGroup = mResourcesWithGroup.find(res->getGroup()); + } + result = itGroup->second.insert( ResourceMap::value_type( res->getName(), res ) ); + + } + + if (!result.second) + { + // Attempt to resolve the collision + if(ResourceGroupManager::getSingleton().getLoadingListener()) + { + if(ResourceGroupManager::getSingleton().getLoadingListener()->resourceCollision(res.get(), this)) + { + // Try to do the addition again, no seconds attempts to resolve collisions are allowed + std::pair insertResult; + if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup())) + { + insertResult = mResources.insert( ResourceMap::value_type( res->getName(), res ) ); + } + else + { + ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(res->getGroup()); + insertResult = itGroup->second.insert( ResourceMap::value_type( res->getName(), res ) ); + } + if (!insertResult.second) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the name " + res->getName() + + " already exists.", "ResourceManager::add"); + } + + std::pair resultHandle = + mResourcesByHandle.insert( ResourceHandleMap::value_type( res->getHandle(), res ) ); + if (!resultHandle.second) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the handle " + + StringConverter::toString((long) (res->getHandle())) + + " already exists.", "ResourceManager::add"); + } + } + } + } + else + { + // Insert the handle + std::pair resultHandle = + mResourcesByHandle.insert( ResourceHandleMap::value_type( res->getHandle(), res ) ); + if (!resultHandle.second) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the handle " + + StringConverter::toString((long) (res->getHandle())) + + " already exists.", "ResourceManager::add"); + } + } + } + //----------------------------------------------------------------------- + void ResourceManager::removeImpl( ResourcePtr& res ) + { OGRE_LOCK_AUTO_MUTEX; - if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup())) - { - ResourceMap::iterator nameIt = mResources.find(res->getName()); - if (nameIt != mResources.end()) - { - mResources.erase(nameIt); - } - } - else - { - ResourceWithGroupMap::iterator groupIt = mResourcesWithGroup.find(res->getGroup()); - if (groupIt != mResourcesWithGroup.end()) - { - ResourceMap::iterator nameIt = groupIt->second.find(res->getName()); - if (nameIt != groupIt->second.end()) - { - groupIt->second.erase(nameIt); - } - - if (groupIt->second.empty()) - { - mResourcesWithGroup.erase(groupIt); - } - } - } - - ResourceHandleMap::iterator handleIt = mResourcesByHandle.find(res->getHandle()); - if (handleIt != mResourcesByHandle.end()) - { - mResourcesByHandle.erase(handleIt); - } - // Tell resource group manager - ResourceGroupManager::getSingleton()._notifyResourceRemoved(res); - } + if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup())) + { + ResourceMap::iterator nameIt = mResources.find(res->getName()); + if (nameIt != mResources.end()) + { + mResources.erase(nameIt); + } + } + else + { + ResourceWithGroupMap::iterator groupIt = mResourcesWithGroup.find(res->getGroup()); + if (groupIt != mResourcesWithGroup.end()) + { + ResourceMap::iterator nameIt = groupIt->second.find(res->getName()); + if (nameIt != groupIt->second.end()) + { + groupIt->second.erase(nameIt); + } + + if (groupIt->second.empty()) + { + mResourcesWithGroup.erase(groupIt); + } + } + } + + ResourceHandleMap::iterator handleIt = mResourcesByHandle.find(res->getHandle()); + if (handleIt != mResourcesByHandle.end()) + { + mResourcesByHandle.erase(handleIt); + } + // Tell resource group manager + ResourceGroupManager::getSingleton()._notifyResourceRemoved(res); + } //----------------------------------------------------------------------- void ResourceManager::setMemoryBudget( size_t bytes) { @@ -227,62 +227,62 @@ namespace Ogre { { return mMemoryBudget; } - //----------------------------------------------------------------------- - void ResourceManager::unload(const String& name) - { - ResourcePtr res = getResourceByName(name); - - if (!res.isNull()) - { - // Unload resource - res->unload(); - - } - } - //----------------------------------------------------------------------- - void ResourceManager::unload(ResourceHandle handle) - { - ResourcePtr res = getByHandle(handle); - - if (!res.isNull()) - { - // Unload resource - res->unload(); - - } - } - //----------------------------------------------------------------------- - void ResourceManager::unloadAll(bool reloadableOnly) - { + //----------------------------------------------------------------------- + void ResourceManager::unload(const String& name) + { + ResourcePtr res = getResourceByName(name); + + if (!res.isNull()) + { + // Unload resource + res->unload(); + + } + } + //----------------------------------------------------------------------- + void ResourceManager::unload(ResourceHandle handle) + { + ResourcePtr res = getByHandle(handle); + + if (!res.isNull()) + { + // Unload resource + res->unload(); + + } + } + //----------------------------------------------------------------------- + void ResourceManager::unloadAll(bool reloadableOnly) + { OGRE_LOCK_AUTO_MUTEX; - ResourceMap::iterator i, iend; - iend = mResources.end(); - for (i = mResources.begin(); i != iend; ++i) - { - if (!reloadableOnly || i->second->isReloadable()) - { - i->second->unload(); - } - } - - } - //----------------------------------------------------------------------- - void ResourceManager::reloadAll(bool reloadableOnly) - { + ResourceMap::iterator i, iend; + iend = mResources.end(); + for (i = mResources.begin(); i != iend; ++i) + { + if (!reloadableOnly || i->second->isReloadable()) + { + i->second->unload(); + } + } + + } + //----------------------------------------------------------------------- + void ResourceManager::reloadAll(bool reloadableOnly) + { OGRE_LOCK_AUTO_MUTEX; - ResourceMap::iterator i, iend; - iend = mResources.end(); - for (i = mResources.begin(); i != iend; ++i) - { - if (!reloadableOnly || i->second->isReloadable()) - { - i->second->reload(); - } - } - - } + ResourceMap::iterator i, iend; + iend = mResources.end(); + for (i = mResources.begin(); i != iend; ++i) + { + if (!reloadableOnly || i->second->isReloadable()) + { + i->second->reload(); + } + } + + } //----------------------------------------------------------------------- void ResourceManager::unloadUnreferencedResources(bool reloadableOnly) { @@ -330,37 +330,37 @@ namespace Ogre { { removeImpl(res); } - //----------------------------------------------------------------------- - void ResourceManager::remove(const String& name) - { - ResourcePtr res = getResourceByName(name); - - if (!res.isNull()) - { - removeImpl(res); - } - } - //----------------------------------------------------------------------- - void ResourceManager::remove(ResourceHandle handle) - { - ResourcePtr res = getByHandle(handle); - - if (!res.isNull()) - { - removeImpl(res); - } - } - //----------------------------------------------------------------------- - void ResourceManager::removeAll(void) - { + //----------------------------------------------------------------------- + void ResourceManager::remove(const String& name) + { + ResourcePtr res = getResourceByName(name); + + if (!res.isNull()) + { + removeImpl(res); + } + } + //----------------------------------------------------------------------- + void ResourceManager::remove(ResourceHandle handle) + { + ResourcePtr res = getByHandle(handle); + + if (!res.isNull()) + { + removeImpl(res); + } + } + //----------------------------------------------------------------------- + void ResourceManager::removeAll(void) + { OGRE_LOCK_AUTO_MUTEX; - mResources.clear(); - mResourcesWithGroup.clear(); - mResourcesByHandle.clear(); - // Notify resource group manager - ResourceGroupManager::getSingleton()._notifyAllResourcesRemoved(this); - } + mResources.clear(); + mResourcesWithGroup.clear(); + mResourcesByHandle.clear(); + // Notify resource group manager + ResourceGroupManager::getSingleton()._notifyAllResourcesRemoved(this); + } //----------------------------------------------------------------------- void ResourceManager::removeUnreferencedResources(bool reloadableOnly) { @@ -388,59 +388,59 @@ namespace Ogre { } //----------------------------------------------------------------------- ResourcePtr ResourceManager::getResourceByName(const String& name, const String& groupName /* = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME */) - { - ResourcePtr res; + { + ResourcePtr res; - // if not in the global pool - get it from the grouped pool - if(!ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(groupName)) - { + // if not in the global pool - get it from the grouped pool + if(!ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(groupName)) + { OGRE_LOCK_AUTO_MUTEX; - ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(groupName); - - if( itGroup != mResourcesWithGroup.end()) - { - ResourceMap::iterator it = itGroup->second.find(name); - - if( it != itGroup->second.end()) - { - res = it->second; - } - } - } - - // if didn't find it the grouped pool - get it from the global pool - if (res.isNull()) - { + ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(groupName); + + if( itGroup != mResourcesWithGroup.end()) + { + ResourceMap::iterator it = itGroup->second.find(name); + + if( it != itGroup->second.end()) + { + res = it->second; + } + } + } + + // if didn't find it the grouped pool - get it from the global pool + if (res.isNull()) + { OGRE_LOCK_AUTO_MUTEX; - ResourceMap::iterator it = mResources.find(name); - - if( it != mResources.end()) - { - res = it->second; - } - else - { - // this is the case when we need to search also in the grouped hash - if (groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) - { - ResourceWithGroupMap::iterator iter = mResourcesWithGroup.begin(); - ResourceWithGroupMap::iterator iterE = mResourcesWithGroup.end(); - for ( ; iter != iterE ; ++iter ) - { - ResourceMap::iterator resMapIt = iter->second.find(name); - - if( resMapIt != iter->second.end()) - { - res = resMapIt->second; - break; - } - } - } - } - } - - return res; + ResourceMap::iterator it = mResources.find(name); + + if( it != mResources.end()) + { + res = it->second; + } + else + { + // this is the case when we need to search also in the grouped hash + if (groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) + { + ResourceWithGroupMap::iterator iter = mResourcesWithGroup.begin(); + ResourceWithGroupMap::iterator iterE = mResourcesWithGroup.end(); + for ( ; iter != iterE ; ++iter ) + { + ResourceMap::iterator resMapIt = iter->second.find(name); + + if( resMapIt != iter->second.end()) + { + res = resMapIt->second; + break; + } + } + } + } + } + + return res; } //----------------------------------------------------------------------- ResourcePtr ResourceManager::getByHandle(ResourceHandle handle) @@ -466,123 +466,123 @@ namespace Ogre { //----------------------------------------------------------------------- void ResourceManager::checkUsage(void) { - if (getMemoryUsage() > mMemoryBudget) - { + if (getMemoryUsage() > mMemoryBudget) + { OGRE_LOCK_AUTO_MUTEX; - // unload unreferenced resources until we are within our budget again - ResourceMap::iterator i, iend; - iend = mResources.end(); - for (i = mResources.begin(); i != iend && getMemoryUsage() > mMemoryBudget; ++i) - { - // A use count of 3 means that only RGM and RM have references - // RGM has one (this one) and RM has 2 (by name and by handle) - if (i->second.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS) - { - Resource* res = i->second.get(); - if (res->isReloadable()) - { - res->unload(); - } - } - } - } - } - //----------------------------------------------------------------------- - void ResourceManager::_notifyResourceTouched(Resource* res) - { - // TODO - } - //----------------------------------------------------------------------- - void ResourceManager::_notifyResourceLoaded(Resource* res) - { - mMemoryUsage += res->getSize(); - checkUsage(); - } - //----------------------------------------------------------------------- - void ResourceManager::_notifyResourceUnloaded(Resource* res) - { - mMemoryUsage -= res->getSize(); - } - //--------------------------------------------------------------------- - ResourceManager::ResourcePool* ResourceManager::getResourcePool(const String& name) - { + // unload unreferenced resources until we are within our budget again + ResourceMap::iterator i, iend; + iend = mResources.end(); + for (i = mResources.begin(); i != iend && getMemoryUsage() > mMemoryBudget; ++i) + { + // A use count of 3 means that only RGM and RM have references + // RGM has one (this one) and RM has 2 (by name and by handle) + if (i->second.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS) + { + Resource* res = i->second.get(); + if (res->isReloadable()) + { + res->unload(); + } + } + } + } + } + //----------------------------------------------------------------------- + void ResourceManager::_notifyResourceTouched(Resource* res) + { + // TODO + } + //----------------------------------------------------------------------- + void ResourceManager::_notifyResourceLoaded(Resource* res) + { + mMemoryUsage += res->getSize(); + checkUsage(); + } + //----------------------------------------------------------------------- + void ResourceManager::_notifyResourceUnloaded(Resource* res) + { + mMemoryUsage -= res->getSize(); + } + //--------------------------------------------------------------------- + ResourceManager::ResourcePool* ResourceManager::getResourcePool(const String& name) + { OGRE_LOCK_AUTO_MUTEX; - ResourcePoolMap::iterator i = mResourcePoolMap.find(name); - if (i == mResourcePoolMap.end()) - { - i = mResourcePoolMap.insert(ResourcePoolMap::value_type(name, - OGRE_NEW ResourcePool(name))).first; - } - return i->second; - - } - //--------------------------------------------------------------------- - void ResourceManager::destroyResourcePool(ResourcePool* pool) - { + ResourcePoolMap::iterator i = mResourcePoolMap.find(name); + if (i == mResourcePoolMap.end()) + { + i = mResourcePoolMap.insert(ResourcePoolMap::value_type(name, + OGRE_NEW ResourcePool(name))).first; + } + return i->second; + + } + //--------------------------------------------------------------------- + void ResourceManager::destroyResourcePool(ResourcePool* pool) + { if(!pool) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot destroy a null ResourcePool.", "ResourceManager::destroyResourcePool"); OGRE_LOCK_AUTO_MUTEX; - ResourcePoolMap::iterator i = mResourcePoolMap.find(pool->getName()); - if (i != mResourcePoolMap.end()) - mResourcePoolMap.erase(i); + ResourcePoolMap::iterator i = mResourcePoolMap.find(pool->getName()); + if (i != mResourcePoolMap.end()) + mResourcePoolMap.erase(i); - OGRE_DELETE pool; - - } - //--------------------------------------------------------------------- - void ResourceManager::destroyResourcePool(const String& name) - { + OGRE_DELETE pool; + + } + //--------------------------------------------------------------------- + void ResourceManager::destroyResourcePool(const String& name) + { OGRE_LOCK_AUTO_MUTEX; - ResourcePoolMap::iterator i = mResourcePoolMap.find(name); - if (i != mResourcePoolMap.end()) - { - OGRE_DELETE i->second; - mResourcePoolMap.erase(i); - } - - } - //--------------------------------------------------------------------- - void ResourceManager::destroyAllResourcePools() - { + ResourcePoolMap::iterator i = mResourcePoolMap.find(name); + if (i != mResourcePoolMap.end()) + { + OGRE_DELETE i->second; + mResourcePoolMap.erase(i); + } + + } + //--------------------------------------------------------------------- + void ResourceManager::destroyAllResourcePools() + { OGRE_LOCK_AUTO_MUTEX; - for (ResourcePoolMap::iterator i = mResourcePoolMap.begin(); - i != mResourcePoolMap.end(); ++i) - OGRE_DELETE i->second; - - mResourcePoolMap.clear(); - } - //----------------------------------------------------------------------- - //--------------------------------------------------------------------- - ResourceManager::ResourcePool::ResourcePool(const String& name) - : mName(name) - { - - } - //--------------------------------------------------------------------- - ResourceManager::ResourcePool::~ResourcePool() - { - clear(); - } - //--------------------------------------------------------------------- - const String& ResourceManager::ResourcePool::getName() const - { - return mName; - } - //--------------------------------------------------------------------- - void ResourceManager::ResourcePool::clear() - { + for (ResourcePoolMap::iterator i = mResourcePoolMap.begin(); + i != mResourcePoolMap.end(); ++i) + OGRE_DELETE i->second; + + mResourcePoolMap.clear(); + } + //----------------------------------------------------------------------- + //--------------------------------------------------------------------- + ResourceManager::ResourcePool::ResourcePool(const String& name) + : mName(name) + { + + } + //--------------------------------------------------------------------- + ResourceManager::ResourcePool::~ResourcePool() + { + clear(); + } + //--------------------------------------------------------------------- + const String& ResourceManager::ResourcePool::getName() const + { + return mName; + } + //--------------------------------------------------------------------- + void ResourceManager::ResourcePool::clear() + { OGRE_LOCK_AUTO_MUTEX; - for (ItemList::iterator i = mItems.begin(); i != mItems.end(); ++i) - { - (*i)->getCreator()->remove((*i)->getHandle()); - } - mItems.clear(); - } + for (ItemList::iterator i = mItems.begin(); i != mItems.end(); ++i) + { + (*i)->getCreator()->remove((*i)->getHandle()); + } + mItems.clear(); + } } diff --git a/OgreMain/src/OgreRibbonTrail.cpp b/OgreMain/src/OgreRibbonTrail.cpp index 9b2595d14f7..1410ac3d692 100644 --- a/OgreMain/src/OgreRibbonTrail.cpp +++ b/OgreMain/src/OgreRibbonTrail.cpp @@ -49,424 +49,424 @@ namespace Ogre void setValue(Real value) { mTrail->_timeUpdate(value); } }; } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - RibbonTrail::RibbonTrail(const String& name, size_t maxElements, - size_t numberOfChains, bool useTextureCoords, bool useColours) - :BillboardChain(name, maxElements, 0, useTextureCoords, useColours, true), - mFadeController(0) - { - setTrailLength(100); - setNumberOfChains(numberOfChains); - mTimeControllerValue = ControllerValueRealPtr(OGRE_NEW TimeControllerValue(this)); - - // use V as varying texture coord, so we can use 1D textures to 'smear' - setTextureCoordDirection(TCD_V); - - - } - //----------------------------------------------------------------------- - RibbonTrail::~RibbonTrail() - { - // Detach listeners - for (NodeList::iterator i = mNodeList.begin(); i != mNodeList.end(); ++i) - { - (*i)->setListener(0); - } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + RibbonTrail::RibbonTrail(const String& name, size_t maxElements, + size_t numberOfChains, bool useTextureCoords, bool useColours) + :BillboardChain(name, maxElements, 0, useTextureCoords, useColours, true), + mFadeController(0) + { + setTrailLength(100); + setNumberOfChains(numberOfChains); + mTimeControllerValue = ControllerValueRealPtr(OGRE_NEW TimeControllerValue(this)); + + // use V as varying texture coord, so we can use 1D textures to 'smear' + setTextureCoordDirection(TCD_V); + + + } + //----------------------------------------------------------------------- + RibbonTrail::~RibbonTrail() + { + // Detach listeners + for (NodeList::iterator i = mNodeList.begin(); i != mNodeList.end(); ++i) + { + (*i)->setListener(0); + } if (mFadeController) { - // destroy controller - ControllerManager::getSingleton().destroyController(mFadeController); + // destroy controller + ControllerManager::getSingleton().destroyController(mFadeController); + } + + } + //----------------------------------------------------------------------- + void RibbonTrail::addNode(Node* n) + { + if (mNodeList.size() == mChainCount) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + mName + " cannot monitor any more nodes, chain count exceeded", + "RibbonTrail::addNode"); + } + if (n->getListener()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + mName + " cannot monitor node " + n->getName() + " since it already has a listener.", + "RibbonTrail::addNode"); } - } - //----------------------------------------------------------------------- - void RibbonTrail::addNode(Node* n) - { - if (mNodeList.size() == mChainCount) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - mName + " cannot monitor any more nodes, chain count exceeded", - "RibbonTrail::addNode"); - } - if (n->getListener()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - mName + " cannot monitor node " + n->getName() + " since it already has a listener.", - "RibbonTrail::addNode"); - } - - // get chain index - size_t chainIndex = mFreeChains.back(); - mFreeChains.pop_back(); - mNodeToChainSegment.push_back(chainIndex); - mNodeToSegMap[n] = chainIndex; + // get chain index + size_t chainIndex = mFreeChains.back(); + mFreeChains.pop_back(); + mNodeToChainSegment.push_back(chainIndex); + mNodeToSegMap[n] = chainIndex; // initialise the chain resetTrail(chainIndex, n); - mNodeList.push_back(n); - n->setListener(this); - - } - //----------------------------------------------------------------------- - size_t RibbonTrail::getChainIndexForNode(const Node* n) - { - NodeToChainSegmentMap::const_iterator i = mNodeToSegMap.find(n); - if (i == mNodeToSegMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "This node is not being tracked", "RibbonTrail::getChainIndexForNode"); - } - return i->second; - } - //----------------------------------------------------------------------- - void RibbonTrail::removeNode(Node* n) - { - NodeList::iterator i = std::find(mNodeList.begin(), mNodeList.end(), n); - if (i != mNodeList.end()) - { - // also get matching chain segment - size_t index = std::distance(mNodeList.begin(), i); - IndexVector::iterator mi = mNodeToChainSegment.begin(); - std::advance(mi, index); - size_t chainIndex = *mi; - BillboardChain::clearChain(chainIndex); - // mark as free now - mFreeChains.push_back(chainIndex); - n->setListener(0); - mNodeList.erase(i); - mNodeToChainSegment.erase(mi); - mNodeToSegMap.erase(mNodeToSegMap.find(n)); - - } - } - //----------------------------------------------------------------------- - RibbonTrail::NodeIterator - RibbonTrail::getNodeIterator(void) const - { - return NodeIterator(mNodeList.begin(), mNodeList.end()); - } - //----------------------------------------------------------------------- - void RibbonTrail::setTrailLength(Real len) - { - mTrailLength = len; - mElemLength = mTrailLength / mMaxElementsPerChain; - mSquaredElemLength = mElemLength * mElemLength; - } - //----------------------------------------------------------------------- - void RibbonTrail::setMaxChainElements(size_t maxElements) - { - BillboardChain::setMaxChainElements(maxElements); - mElemLength = mTrailLength / mMaxElementsPerChain; - mSquaredElemLength = mElemLength * mElemLength; + mNodeList.push_back(n); + n->setListener(this); + + } + //----------------------------------------------------------------------- + size_t RibbonTrail::getChainIndexForNode(const Node* n) + { + NodeToChainSegmentMap::const_iterator i = mNodeToSegMap.find(n); + if (i == mNodeToSegMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "This node is not being tracked", "RibbonTrail::getChainIndexForNode"); + } + return i->second; + } + //----------------------------------------------------------------------- + void RibbonTrail::removeNode(Node* n) + { + NodeList::iterator i = std::find(mNodeList.begin(), mNodeList.end(), n); + if (i != mNodeList.end()) + { + // also get matching chain segment + size_t index = std::distance(mNodeList.begin(), i); + IndexVector::iterator mi = mNodeToChainSegment.begin(); + std::advance(mi, index); + size_t chainIndex = *mi; + BillboardChain::clearChain(chainIndex); + // mark as free now + mFreeChains.push_back(chainIndex); + n->setListener(0); + mNodeList.erase(i); + mNodeToChainSegment.erase(mi); + mNodeToSegMap.erase(mNodeToSegMap.find(n)); + + } + } + //----------------------------------------------------------------------- + RibbonTrail::NodeIterator + RibbonTrail::getNodeIterator(void) const + { + return NodeIterator(mNodeList.begin(), mNodeList.end()); + } + //----------------------------------------------------------------------- + void RibbonTrail::setTrailLength(Real len) + { + mTrailLength = len; + mElemLength = mTrailLength / mMaxElementsPerChain; + mSquaredElemLength = mElemLength * mElemLength; + } + //----------------------------------------------------------------------- + void RibbonTrail::setMaxChainElements(size_t maxElements) + { + BillboardChain::setMaxChainElements(maxElements); + mElemLength = mTrailLength / mMaxElementsPerChain; + mSquaredElemLength = mElemLength * mElemLength; resetAllTrails(); - } - //----------------------------------------------------------------------- - void RibbonTrail::setNumberOfChains(size_t numChains) - { + } + //----------------------------------------------------------------------- + void RibbonTrail::setNumberOfChains(size_t numChains) + { if (numChains < mNodeList.size()) { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Can't shrink the number of chains less than number of tracking nodes", + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Can't shrink the number of chains less than number of tracking nodes", "RibbonTrail::setNumberOfChains"); } - size_t oldChains = getNumberOfChains(); + size_t oldChains = getNumberOfChains(); - BillboardChain::setNumberOfChains(numChains); + BillboardChain::setNumberOfChains(numChains); - mInitialColour.resize(numChains, ColourValue::White); + mInitialColour.resize(numChains, ColourValue::White); mDeltaColour.resize(numChains, ColourValue::ZERO); - mInitialWidth.resize(numChains, 10); - mDeltaWidth.resize(numChains, 0); - - if (oldChains > numChains) - { - // remove free chains - for (IndexVector::iterator i = mFreeChains.begin(); i != mFreeChains.end();) - { - if (*i >= numChains) - i = mFreeChains.erase(i); - else - ++i; - } - } - else if (oldChains < numChains) - { - // add new chains, at front to preserve previous ordering (pop_back) - for (size_t i = oldChains; i < numChains; ++i) - mFreeChains.insert(mFreeChains.begin(), i); - } + mInitialWidth.resize(numChains, 10); + mDeltaWidth.resize(numChains, 0); + + if (oldChains > numChains) + { + // remove free chains + for (IndexVector::iterator i = mFreeChains.begin(); i != mFreeChains.end();) + { + if (*i >= numChains) + i = mFreeChains.erase(i); + else + ++i; + } + } + else if (oldChains < numChains) + { + // add new chains, at front to preserve previous ordering (pop_back) + for (size_t i = oldChains; i < numChains; ++i) + mFreeChains.insert(mFreeChains.begin(), i); + } resetAllTrails(); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void RibbonTrail::clearChain(size_t chainIndex) { BillboardChain::clearChain(chainIndex); // Reset if we are tracking for this chain - IndexVector::iterator i = std::find(mNodeToChainSegment.begin(), mNodeToChainSegment.end(), chainIndex); - if (i != mNodeToChainSegment.end()) - { - size_t nodeIndex = std::distance(mNodeToChainSegment.begin(), i); + IndexVector::iterator i = std::find(mNodeToChainSegment.begin(), mNodeToChainSegment.end(), chainIndex); + if (i != mNodeToChainSegment.end()) + { + size_t nodeIndex = std::distance(mNodeToChainSegment.begin(), i); resetTrail(*i, mNodeList[nodeIndex]); } } - //----------------------------------------------------------------------- - void RibbonTrail::setInitialColour(size_t chainIndex, const ColourValue& col) - { - setInitialColour(chainIndex, col.r, col.g, col.b, col.a); - } - //----------------------------------------------------------------------- - void RibbonTrail::setInitialColour(size_t chainIndex, Real r, Real g, Real b, Real a) - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "chainIndex out of bounds", "RibbonTrail::setInitialColour"); - } - mInitialColour[chainIndex].r = r; - mInitialColour[chainIndex].g = g; - mInitialColour[chainIndex].b = b; - mInitialColour[chainIndex].a = a; - } - //----------------------------------------------------------------------- - const ColourValue& RibbonTrail::getInitialColour(size_t chainIndex) const - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "chainIndex out of bounds", "RibbonTrail::getInitialColour"); - } - return mInitialColour[chainIndex]; - } - //----------------------------------------------------------------------- - void RibbonTrail::setInitialWidth(size_t chainIndex, Real width) - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "chainIndex out of bounds", "RibbonTrail::setInitialWidth"); - } - mInitialWidth[chainIndex] = width; - } - //----------------------------------------------------------------------- - Real RibbonTrail::getInitialWidth(size_t chainIndex) const - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "chainIndex out of bounds", "RibbonTrail::getInitialWidth"); - } - return mInitialWidth[chainIndex]; - } - //----------------------------------------------------------------------- - void RibbonTrail::setColourChange(size_t chainIndex, const ColourValue& valuePerSecond) - { - setColourChange(chainIndex, - valuePerSecond.r, valuePerSecond.g, valuePerSecond.b, valuePerSecond.a); - } - //----------------------------------------------------------------------- - void RibbonTrail::setColourChange(size_t chainIndex, Real r, Real g, Real b, Real a) - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "chainIndex out of bounds", "RibbonTrail::setColourChange"); - } - mDeltaColour[chainIndex].r = r; - mDeltaColour[chainIndex].g = g; - mDeltaColour[chainIndex].b = b; - mDeltaColour[chainIndex].a = a; - - manageController(); - - } - //----------------------------------------------------------------------- - const ColourValue& RibbonTrail::getColourChange(size_t chainIndex) const - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "chainIndex out of bounds", "RibbonTrail::getColourChange"); - } - return mDeltaColour[chainIndex]; - } - //----------------------------------------------------------------------- - void RibbonTrail::setWidthChange(size_t chainIndex, Real widthDeltaPerSecond) - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "chainIndex out of bounds", "RibbonTrail::setWidthChange"); - } - mDeltaWidth[chainIndex] = widthDeltaPerSecond; - manageController(); - } - //----------------------------------------------------------------------- - Real RibbonTrail::getWidthChange(size_t chainIndex) const - { - if (chainIndex >= mChainCount) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "chainIndex out of bounds", "RibbonTrail::getWidthChange"); - } - return mDeltaWidth[chainIndex]; - - } - //----------------------------------------------------------------------- - void RibbonTrail::manageController(void) - { - bool needController = false; - for (size_t i = 0; i < mChainCount; ++i) - { - if (mDeltaWidth[i] != 0 || mDeltaColour[i] != ColourValue::ZERO) - { - needController = true; - break; - } - } - if (!mFadeController && needController) - { - // Set up fading via frame time controller - ControllerManager& mgr = ControllerManager::getSingleton(); - mFadeController = mgr.createFrameTimePassthroughController(mTimeControllerValue); - } - else if (mFadeController && !needController) - { - // destroy controller - ControllerManager::getSingleton().destroyController(mFadeController); - mFadeController = 0; - } - - } - //----------------------------------------------------------------------- - void RibbonTrail::nodeUpdated(const Node* node) - { - size_t chainIndex = getChainIndexForNode(node); - updateTrail(chainIndex, node); - } - //----------------------------------------------------------------------- - void RibbonTrail::nodeDestroyed(const Node* node) - { - removeNode(const_cast(node)); - - } - //----------------------------------------------------------------------- - void RibbonTrail::updateTrail(size_t index, const Node* node) - { - // Repeat this entire process if chain is stretched beyond its natural length - bool done = false; - while (!done) - { - // Node has changed somehow, we're only interested in the derived position - ChainSegment& seg = mChainSegmentList[index]; - Element& headElem = mChainElementList[seg.start + seg.head]; - size_t nextElemIdx = seg.head + 1; - // wrap - if (nextElemIdx == mMaxElementsPerChain) - nextElemIdx = 0; - Element& nextElem = mChainElementList[seg.start + nextElemIdx]; - - // Vary the head elem, but bake new version if that exceeds element len - Vector3 newPos = node->_getDerivedPosition(); - if (mParentNode) - { - // Transform position to ourself space - newPos = mParentNode->_getDerivedOrientation().UnitInverse() * - (newPos - mParentNode->_getDerivedPosition()) / mParentNode->_getDerivedScale(); - } - Vector3 diff = newPos - nextElem.position; - Real sqlen = diff.squaredLength(); - if (sqlen >= mSquaredElemLength) - { - // Move existing head to mElemLength - Vector3 scaledDiff = diff * (mElemLength / Math::Sqrt(sqlen)); - headElem.position = nextElem.position + scaledDiff; - // Add a new element to be the new head - Element newElem( newPos, mInitialWidth[index], 0.0f, - mInitialColour[index], node->_getDerivedOrientation() ); - addChainElement(index, newElem); - // alter diff to represent new head size - diff = newPos - headElem.position; - // check whether another step is needed or not - if (diff.squaredLength() <= mSquaredElemLength) - done = true; - - } - else - { - // Extend existing head - headElem.position = newPos; - done = true; - } - - // Is this segment full? - if ((seg.tail + 1) % mMaxElementsPerChain == seg.head) - { - // If so, shrink tail gradually to match head extension - Element& tailElem = mChainElementList[seg.start + seg.tail]; - size_t preTailIdx; - if (seg.tail == 0) - preTailIdx = mMaxElementsPerChain - 1; - else - preTailIdx = seg.tail - 1; - Element& preTailElem = mChainElementList[seg.start + preTailIdx]; - - // Measure tail diff from pretail to tail - Vector3 taildiff = tailElem.position - preTailElem.position; - Real taillen = taildiff.length(); - if (taillen > 1e-06) - { - Real tailsize = mElemLength - diff.length(); - taildiff *= tailsize / taillen; - tailElem.position = preTailElem.position + taildiff; - } - - } - } // end while - - - mBoundsDirty = true; - // Need to dirty the parent node, but can't do it using needUpdate() here - // since we're in the middle of the scene graph update (node listener), - // so re-entrant calls don't work. Queue. - if (mParentNode) - { - Node::queueNeedUpdate(getParentSceneNode()); - } - - } - //----------------------------------------------------------------------- - void RibbonTrail::_timeUpdate(Real time) - { - // Apply all segment effects - for (size_t s = 0; s < mChainSegmentList.size(); ++s) - { - ChainSegment& seg = mChainSegmentList[s]; - if (seg.head != SEGMENT_EMPTY && seg.head != seg.tail) - { - - for(size_t e = seg.head + 1;; ++e) // until break - { - e = e % mMaxElementsPerChain; - - Element& elem = mChainElementList[seg.start + e]; - elem.width = elem.width - (time * mDeltaWidth[s]); - elem.width = std::max(Real(0.0f), elem.width); - elem.colour = elem.colour - (mDeltaColour[s] * time); - elem.colour.saturate(); - - if (e == seg.tail) - break; - } - } - } - mVertexContentDirty = true; - } + //----------------------------------------------------------------------- + void RibbonTrail::setInitialColour(size_t chainIndex, const ColourValue& col) + { + setInitialColour(chainIndex, col.r, col.g, col.b, col.a); + } + //----------------------------------------------------------------------- + void RibbonTrail::setInitialColour(size_t chainIndex, Real r, Real g, Real b, Real a) + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "chainIndex out of bounds", "RibbonTrail::setInitialColour"); + } + mInitialColour[chainIndex].r = r; + mInitialColour[chainIndex].g = g; + mInitialColour[chainIndex].b = b; + mInitialColour[chainIndex].a = a; + } + //----------------------------------------------------------------------- + const ColourValue& RibbonTrail::getInitialColour(size_t chainIndex) const + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "chainIndex out of bounds", "RibbonTrail::getInitialColour"); + } + return mInitialColour[chainIndex]; + } + //----------------------------------------------------------------------- + void RibbonTrail::setInitialWidth(size_t chainIndex, Real width) + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "chainIndex out of bounds", "RibbonTrail::setInitialWidth"); + } + mInitialWidth[chainIndex] = width; + } + //----------------------------------------------------------------------- + Real RibbonTrail::getInitialWidth(size_t chainIndex) const + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "chainIndex out of bounds", "RibbonTrail::getInitialWidth"); + } + return mInitialWidth[chainIndex]; + } + //----------------------------------------------------------------------- + void RibbonTrail::setColourChange(size_t chainIndex, const ColourValue& valuePerSecond) + { + setColourChange(chainIndex, + valuePerSecond.r, valuePerSecond.g, valuePerSecond.b, valuePerSecond.a); + } + //----------------------------------------------------------------------- + void RibbonTrail::setColourChange(size_t chainIndex, Real r, Real g, Real b, Real a) + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "chainIndex out of bounds", "RibbonTrail::setColourChange"); + } + mDeltaColour[chainIndex].r = r; + mDeltaColour[chainIndex].g = g; + mDeltaColour[chainIndex].b = b; + mDeltaColour[chainIndex].a = a; + + manageController(); + + } + //----------------------------------------------------------------------- + const ColourValue& RibbonTrail::getColourChange(size_t chainIndex) const + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "chainIndex out of bounds", "RibbonTrail::getColourChange"); + } + return mDeltaColour[chainIndex]; + } + //----------------------------------------------------------------------- + void RibbonTrail::setWidthChange(size_t chainIndex, Real widthDeltaPerSecond) + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "chainIndex out of bounds", "RibbonTrail::setWidthChange"); + } + mDeltaWidth[chainIndex] = widthDeltaPerSecond; + manageController(); + } + //----------------------------------------------------------------------- + Real RibbonTrail::getWidthChange(size_t chainIndex) const + { + if (chainIndex >= mChainCount) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "chainIndex out of bounds", "RibbonTrail::getWidthChange"); + } + return mDeltaWidth[chainIndex]; + + } + //----------------------------------------------------------------------- + void RibbonTrail::manageController(void) + { + bool needController = false; + for (size_t i = 0; i < mChainCount; ++i) + { + if (mDeltaWidth[i] != 0 || mDeltaColour[i] != ColourValue::ZERO) + { + needController = true; + break; + } + } + if (!mFadeController && needController) + { + // Set up fading via frame time controller + ControllerManager& mgr = ControllerManager::getSingleton(); + mFadeController = mgr.createFrameTimePassthroughController(mTimeControllerValue); + } + else if (mFadeController && !needController) + { + // destroy controller + ControllerManager::getSingleton().destroyController(mFadeController); + mFadeController = 0; + } + + } + //----------------------------------------------------------------------- + void RibbonTrail::nodeUpdated(const Node* node) + { + size_t chainIndex = getChainIndexForNode(node); + updateTrail(chainIndex, node); + } + //----------------------------------------------------------------------- + void RibbonTrail::nodeDestroyed(const Node* node) + { + removeNode(const_cast(node)); + + } + //----------------------------------------------------------------------- + void RibbonTrail::updateTrail(size_t index, const Node* node) + { + // Repeat this entire process if chain is stretched beyond its natural length + bool done = false; + while (!done) + { + // Node has changed somehow, we're only interested in the derived position + ChainSegment& seg = mChainSegmentList[index]; + Element& headElem = mChainElementList[seg.start + seg.head]; + size_t nextElemIdx = seg.head + 1; + // wrap + if (nextElemIdx == mMaxElementsPerChain) + nextElemIdx = 0; + Element& nextElem = mChainElementList[seg.start + nextElemIdx]; + + // Vary the head elem, but bake new version if that exceeds element len + Vector3 newPos = node->_getDerivedPosition(); + if (mParentNode) + { + // Transform position to ourself space + newPos = mParentNode->_getDerivedOrientation().UnitInverse() * + (newPos - mParentNode->_getDerivedPosition()) / mParentNode->_getDerivedScale(); + } + Vector3 diff = newPos - nextElem.position; + Real sqlen = diff.squaredLength(); + if (sqlen >= mSquaredElemLength) + { + // Move existing head to mElemLength + Vector3 scaledDiff = diff * (mElemLength / Math::Sqrt(sqlen)); + headElem.position = nextElem.position + scaledDiff; + // Add a new element to be the new head + Element newElem( newPos, mInitialWidth[index], 0.0f, + mInitialColour[index], node->_getDerivedOrientation() ); + addChainElement(index, newElem); + // alter diff to represent new head size + diff = newPos - headElem.position; + // check whether another step is needed or not + if (diff.squaredLength() <= mSquaredElemLength) + done = true; + + } + else + { + // Extend existing head + headElem.position = newPos; + done = true; + } + + // Is this segment full? + if ((seg.tail + 1) % mMaxElementsPerChain == seg.head) + { + // If so, shrink tail gradually to match head extension + Element& tailElem = mChainElementList[seg.start + seg.tail]; + size_t preTailIdx; + if (seg.tail == 0) + preTailIdx = mMaxElementsPerChain - 1; + else + preTailIdx = seg.tail - 1; + Element& preTailElem = mChainElementList[seg.start + preTailIdx]; + + // Measure tail diff from pretail to tail + Vector3 taildiff = tailElem.position - preTailElem.position; + Real taillen = taildiff.length(); + if (taillen > 1e-06) + { + Real tailsize = mElemLength - diff.length(); + taildiff *= tailsize / taillen; + tailElem.position = preTailElem.position + taildiff; + } + + } + } // end while + + + mBoundsDirty = true; + // Need to dirty the parent node, but can't do it using needUpdate() here + // since we're in the middle of the scene graph update (node listener), + // so re-entrant calls don't work. Queue. + if (mParentNode) + { + Node::queueNeedUpdate(getParentSceneNode()); + } + + } + //----------------------------------------------------------------------- + void RibbonTrail::_timeUpdate(Real time) + { + // Apply all segment effects + for (size_t s = 0; s < mChainSegmentList.size(); ++s) + { + ChainSegment& seg = mChainSegmentList[s]; + if (seg.head != SEGMENT_EMPTY && seg.head != seg.tail) + { + + for(size_t e = seg.head + 1;; ++e) // until break + { + e = e % mMaxElementsPerChain; + + Element& elem = mChainElementList[seg.start + e]; + elem.width = elem.width - (time * mDeltaWidth[s]); + elem.width = std::max(Real(0.0f), elem.width); + elem.colour = elem.colour - (mDeltaColour[s] * time); + elem.colour.saturate(); + + if (e == seg.tail) + break; + } + } + } + mVertexContentDirty = true; + } //----------------------------------------------------------------------- void RibbonTrail::resetTrail(size_t index, const Node* node) { @@ -476,22 +476,22 @@ namespace Ogre // set up this segment seg.head = seg.tail = SEGMENT_EMPTY; // Create new element, v coord is always 0.0f - // need to convert to take parent node's position into account - Vector3 position = node->_getDerivedPosition(); - if (mParentNode) - { - position = mParentNode->_getDerivedOrientation().Inverse() - * (position - mParentNode->_getDerivedPosition()) - / mParentNode->_getDerivedScale(); - } + // need to convert to take parent node's position into account + Vector3 position = node->_getDerivedPosition(); + if (mParentNode) + { + position = mParentNode->_getDerivedOrientation().Inverse() + * (position - mParentNode->_getDerivedPosition()) + / mParentNode->_getDerivedScale(); + } Element e(position, - mInitialWidth[index], 0.0f, mInitialColour[index], node->_getDerivedOrientation()); + mInitialWidth[index], 0.0f, mInitialColour[index], node->_getDerivedOrientation()); // Add the start position addChainElement(index, e); // Add another on the same spot, this will extend addChainElement(index, e); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void RibbonTrail::resetAllTrails(void) { for (size_t i = 0; i < mNodeList.size(); ++i) @@ -499,61 +499,61 @@ namespace Ogre resetTrail(i, mNodeList[i]); } } - //----------------------------------------------------------------------- - const String& RibbonTrail::getMovableType(void) const - { - return RibbonTrailFactory::FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - String RibbonTrailFactory::FACTORY_TYPE_NAME = "RibbonTrail"; - //----------------------------------------------------------------------- - const String& RibbonTrailFactory::getType(void) const - { - return FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------- - MovableObject* RibbonTrailFactory::createInstanceImpl( const String& name, - const NameValuePairList* params) - { - size_t maxElements = 20; - size_t numberOfChains = 1; - bool useTex = true; - bool useCol = true; - // optional params - if (params != 0) - { - NameValuePairList::const_iterator ni = params->find("maxElements"); - if (ni != params->end()) - { - maxElements = StringConverter::parseUnsignedLong(ni->second); - } - ni = params->find("numberOfChains"); - if (ni != params->end()) - { - numberOfChains = StringConverter::parseUnsignedLong(ni->second); - } - ni = params->find("useTextureCoords"); - if (ni != params->end()) - { - useTex = StringConverter::parseBool(ni->second); - } - ni = params->find("useVertexColours"); - if (ni != params->end()) - { - useCol = StringConverter::parseBool(ni->second); - } - - } - - return OGRE_NEW RibbonTrail(name, maxElements, numberOfChains, useTex, useCol); - - } - //----------------------------------------------------------------------- - void RibbonTrailFactory::destroyInstance( MovableObject* obj) - { - OGRE_DELETE obj; - } + //----------------------------------------------------------------------- + const String& RibbonTrail::getMovableType(void) const + { + return RibbonTrailFactory::FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + String RibbonTrailFactory::FACTORY_TYPE_NAME = "RibbonTrail"; + //----------------------------------------------------------------------- + const String& RibbonTrailFactory::getType(void) const + { + return FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------- + MovableObject* RibbonTrailFactory::createInstanceImpl( const String& name, + const NameValuePairList* params) + { + size_t maxElements = 20; + size_t numberOfChains = 1; + bool useTex = true; + bool useCol = true; + // optional params + if (params != 0) + { + NameValuePairList::const_iterator ni = params->find("maxElements"); + if (ni != params->end()) + { + maxElements = StringConverter::parseUnsignedLong(ni->second); + } + ni = params->find("numberOfChains"); + if (ni != params->end()) + { + numberOfChains = StringConverter::parseUnsignedLong(ni->second); + } + ni = params->find("useTextureCoords"); + if (ni != params->end()) + { + useTex = StringConverter::parseBool(ni->second); + } + ni = params->find("useVertexColours"); + if (ni != params->end()) + { + useCol = StringConverter::parseBool(ni->second); + } + + } + + return OGRE_NEW RibbonTrail(name, maxElements, numberOfChains, useTex, useCol); + + } + //----------------------------------------------------------------------- + void RibbonTrailFactory::destroyInstance( MovableObject* obj) + { + OGRE_DELETE obj; + } diff --git a/OgreMain/src/OgreRoot.cpp b/OgreMain/src/OgreRoot.cpp index 270324afd64..d26d909c149 100644 --- a/OgreMain/src/OgreRoot.cpp +++ b/OgreMain/src/OgreRoot.cpp @@ -111,18 +111,18 @@ namespace Ogre { //----------------------------------------------------------------------- Root::Root(const String& pluginFileName, const String& configFileName, - const String& logFileName) + const String& logFileName) : mQueuedEnd(false) , mLogManager(0) - , mRenderSystemCapabilitiesManager(0) - , mNextFrame(0) - , mFrameSmoothingTime(0.0f) - , mRemoveQueueStructuresOnClear(false) - , mDefaultMinPixelSize(0) + , mRenderSystemCapabilitiesManager(0) + , mNextFrame(0) + , mFrameSmoothingTime(0.0f) + , mRemoveQueueStructuresOnClear(false) + , mDefaultMinPixelSize(0) , mFreqUpdatedBuffersUploadOption(HardwareBuffer::HBU_DEFAULT) - , mNextMovableObjectTypeFlag(1) - , mIsInitialised(false) - , mIsBlendIndicesGpuRedundant(true) + , mNextMovableObjectTypeFlag(1) + , mIsInitialised(false) + , mIsBlendIndicesGpuRedundant(true) , mIsBlendWeightsGpuRedundant(true) { // superclass will do singleton checking @@ -133,16 +133,16 @@ namespace Ogre { mVersion = StringConverter::toString(OGRE_VERSION_MAJOR) + "." + StringConverter::toString(OGRE_VERSION_MINOR) + "." + StringConverter::toString(OGRE_VERSION_PATCH) + - OGRE_VERSION_SUFFIX + " " + + OGRE_VERSION_SUFFIX + " " + "(" + OGRE_VERSION_NAME + ")"; - mConfigFileName = configFileName; + mConfigFileName = configFileName; - // Create log manager and default log file if there is no log manager yet - if(LogManager::getSingletonPtr() == 0) - { - mLogManager = OGRE_NEW LogManager(); - mLogManager->createLog(logFileName, true, true); - } + // Create log manager and default log file if there is no log manager yet + if(LogManager::getSingletonPtr() == 0) + { + mLogManager = OGRE_NEW LogManager(); + mLogManager->createLog(logFileName, true, true); + } #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID mAndroidLogger = OGRE_NEW AndroidLogListener(); @@ -154,37 +154,37 @@ namespace Ogre { mArchiveManager = OGRE_NEW ArchiveManager(); - // ResourceGroupManager - mResourceGroupManager = OGRE_NEW ResourceGroupManager(); + // ResourceGroupManager + mResourceGroupManager = OGRE_NEW ResourceGroupManager(); - // WorkQueue (note: users can replace this if they want) - DefaultWorkQueue* defaultQ = OGRE_NEW DefaultWorkQueue("Root"); - // never process responses in main thread for longer than 10ms by default - defaultQ->setResponseProcessingTimeLimit(10); - // match threads to hardware + // WorkQueue (note: users can replace this if they want) + DefaultWorkQueue* defaultQ = OGRE_NEW DefaultWorkQueue("Root"); + // never process responses in main thread for longer than 10ms by default + defaultQ->setResponseProcessingTimeLimit(10); + // match threads to hardware #if OGRE_THREAD_SUPPORT - unsigned threadCount = OGRE_THREAD_HARDWARE_CONCURRENCY; - if (!threadCount) - threadCount = 1; - defaultQ->setWorkerThreadCount(threadCount); + unsigned threadCount = OGRE_THREAD_HARDWARE_CONCURRENCY; + if (!threadCount) + threadCount = 1; + defaultQ->setWorkerThreadCount(threadCount); #endif - // only allow workers to access rendersystem if threadsupport is 1 + // only allow workers to access rendersystem if threadsupport is 1 #if OGRE_THREAD_SUPPORT == 1 - defaultQ->setWorkersCanAccessRenderSystem(true); + defaultQ->setWorkersCanAccessRenderSystem(true); #else - defaultQ->setWorkersCanAccessRenderSystem(false); + defaultQ->setWorkersCanAccessRenderSystem(false); #endif - mWorkQueue = defaultQ; + mWorkQueue = defaultQ; - // ResourceBackgroundQueue - mResourceBackgroundQueue = OGRE_NEW ResourceBackgroundQueue(); + // ResourceBackgroundQueue + mResourceBackgroundQueue = OGRE_NEW ResourceBackgroundQueue(); - // Create SceneManager enumerator (note - will be managed by singleton) + // Create SceneManager enumerator (note - will be managed by singleton) mSceneManagerEnum = OGRE_NEW SceneManagerEnumerator(); - mShadowTextureManager = OGRE_NEW ShadowTextureManager(); + mShadowTextureManager = OGRE_NEW ShadowTextureManager(); - mRenderSystemCapabilitiesManager = OGRE_NEW RenderSystemCapabilitiesManager(); + mRenderSystemCapabilitiesManager = OGRE_NEW RenderSystemCapabilitiesManager(); // ..material manager mMaterialManager = OGRE_NEW MaterialManager(); @@ -198,8 +198,8 @@ namespace Ogre { // ..particle system manager mParticleManager = OGRE_NEW ParticleSystemManager(); - // Compiler manager - //mCompilerManager = OGRE_NEW ScriptCompilerManager(); + // Compiler manager + //mCompilerManager = OGRE_NEW ScriptCompilerManager(); mTimer = OGRE_NEW Timer(); @@ -209,7 +209,7 @@ namespace Ogre { #if OGRE_PROFILING // Profiler mProfiler = OGRE_NEW Profiler(); - Profiler::getSingleton().setTimer(mTimer); + Profiler::getSingleton().setTimer(mTimer); #endif @@ -223,12 +223,12 @@ namespace Ogre { # endif #if OGRE_NO_DDS_CODEC == 0 - // Register image codecs - DDSCodec::startup(); + // Register image codecs + DDSCodec::startup(); #endif #if OGRE_NO_FREEIMAGE == 0 - // Register image codecs - FreeImageCodec::startup(); + // Register image codecs + FreeImageCodec::startup(); #endif #if OGRE_NO_PVRTC_CODEC == 0 PVRTCCodec::startup(); @@ -241,33 +241,33 @@ namespace Ogre { mHighLevelGpuProgramManager = OGRE_NEW HighLevelGpuProgramManager(); - mExternalTextureSourceManager = OGRE_NEW ExternalTextureSourceManager(); + mExternalTextureSourceManager = OGRE_NEW ExternalTextureSourceManager(); mCompositorManager = OGRE_NEW CompositorManager(); - mCompilerManager = OGRE_NEW ScriptCompilerManager(); + mCompilerManager = OGRE_NEW ScriptCompilerManager(); // Auto window mAutoWindow = 0; - // instantiate and register base movable factories - mEntityFactory = OGRE_NEW EntityFactory(); - addMovableObjectFactory(mEntityFactory); - mLightFactory = OGRE_NEW LightFactory(); - addMovableObjectFactory(mLightFactory); - mBillboardSetFactory = OGRE_NEW BillboardSetFactory(); - addMovableObjectFactory(mBillboardSetFactory); - mManualObjectFactory = OGRE_NEW ManualObjectFactory(); - addMovableObjectFactory(mManualObjectFactory); - mBillboardChainFactory = OGRE_NEW BillboardChainFactory(); - addMovableObjectFactory(mBillboardChainFactory); - mRibbonTrailFactory = OGRE_NEW RibbonTrailFactory(); - addMovableObjectFactory(mRibbonTrailFactory); - - // Load plugins + // instantiate and register base movable factories + mEntityFactory = OGRE_NEW EntityFactory(); + addMovableObjectFactory(mEntityFactory); + mLightFactory = OGRE_NEW LightFactory(); + addMovableObjectFactory(mLightFactory); + mBillboardSetFactory = OGRE_NEW BillboardSetFactory(); + addMovableObjectFactory(mBillboardSetFactory); + mManualObjectFactory = OGRE_NEW ManualObjectFactory(); + addMovableObjectFactory(mManualObjectFactory); + mBillboardChainFactory = OGRE_NEW BillboardChainFactory(); + addMovableObjectFactory(mBillboardChainFactory); + mRibbonTrailFactory = OGRE_NEW RibbonTrailFactory(); + addMovableObjectFactory(mRibbonTrailFactory); + + // Load plugins if (!pluginFileName.empty()) loadPlugins(pluginFileName); - LogManager::getSingleton().logMessage("*-*-* OGRE Initialising"); + LogManager::getSingleton().logMessage("*-*-* OGRE Initialising"); msg = "*-*-* Version " + mVersion; LogManager::getSingleton().logMessage(msg); @@ -283,20 +283,20 @@ namespace Ogre { { shutdown(); OGRE_DELETE mSceneManagerEnum; - OGRE_DELETE mShadowTextureManager; - OGRE_DELETE mRenderSystemCapabilitiesManager; + OGRE_DELETE mShadowTextureManager; + OGRE_DELETE mRenderSystemCapabilitiesManager; - destroyAllRenderQueueInvocationSequences(); + destroyAllRenderQueueInvocationSequences(); OGRE_DELETE mCompositorManager; - OGRE_DELETE mExternalTextureSourceManager; + OGRE_DELETE mExternalTextureSourceManager; #if OGRE_NO_FREEIMAGE == 0 - FreeImageCodec::shutdown(); + FreeImageCodec::shutdown(); #endif #if OGRE_NO_DDS_CODEC == 0 - DDSCodec::shutdown(); + DDSCodec::shutdown(); #endif #if OGRE_NO_PVRTC_CODEC == 0 - PVRTCCodec::shutdown(); + PVRTCCodec::shutdown(); #endif #if OGRE_NO_ETC_CODEC == 0 ETCCodec::shutdown(); @@ -305,7 +305,7 @@ namespace Ogre { OGRE_DELETE mProfiler; #endif - OGRE_DELETE mLodStrategyManager; + OGRE_DELETE mLodStrategyManager; OGRE_DELETE mArchiveManager; @@ -325,19 +325,19 @@ namespace Ogre { unloadPlugins(); OGRE_DELETE mMaterialManager; Pass::processPendingPassUpdates(); // make sure passes are cleaned - OGRE_DELETE mResourceBackgroundQueue; + OGRE_DELETE mResourceBackgroundQueue; OGRE_DELETE mResourceGroupManager; - OGRE_DELETE mEntityFactory; - OGRE_DELETE mLightFactory; - OGRE_DELETE mBillboardSetFactory; - OGRE_DELETE mManualObjectFactory; - OGRE_DELETE mBillboardChainFactory; - OGRE_DELETE mRibbonTrailFactory; + OGRE_DELETE mEntityFactory; + OGRE_DELETE mLightFactory; + OGRE_DELETE mBillboardSetFactory; + OGRE_DELETE mManualObjectFactory; + OGRE_DELETE mBillboardChainFactory; + OGRE_DELETE mRibbonTrailFactory; - OGRE_DELETE mWorkQueue; + OGRE_DELETE mWorkQueue; - OGRE_DELETE mTimer; + OGRE_DELETE mTimer; OGRE_DELETE mDynLibManager; @@ -348,10 +348,10 @@ namespace Ogre { OGRE_DELETE mLogManager; - OGRE_DELETE mCompilerManager; + OGRE_DELETE mCompilerManager; - mAutoWindow = 0; - mFirstTimePostWindowInit = false; + mAutoWindow = 0; + mFirstTimePostWindowInit = false; StringInterface::cleanupDictionary (); @@ -369,7 +369,7 @@ namespace Ogre { Ogre::String outBaseName, extension, configFileName; Ogre::StringUtil::splitFilename(mConfigFileName, outBaseName, extension); configFileName = macBundlePath() + "/../Documents/" + outBaseName; - std::ofstream of(configFileName.c_str()); + std::ofstream of(configFileName.c_str()); if (of.is_open()) mConfigFileName = configFileName; else @@ -378,7 +378,7 @@ namespace Ogre { if (mConfigFileName.empty()) return; - std::ofstream of(mConfigFileName.c_str()); + std::ofstream of(mConfigFileName.c_str()); #endif if (!of) OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, "Cannot create settings file.", @@ -401,7 +401,7 @@ namespace Ogre { const ConfigOptionMap& opts = rs->getConfigOptions(); for (ConfigOptionMap::const_iterator pOpt = opts.begin(); pOpt != opts.end(); ++pOpt) { - of << pOpt->first << "=" << pOpt->second.currentValue << std::endl; + of << pOpt->first << "=" << pOpt->second.currentValue << std::endl; } } @@ -424,7 +424,7 @@ namespace Ogre { Ogre::StringUtil::splitFilename(mConfigFileName, outBaseName, extension); configFileName = macBundlePath() + "/../Documents/" + outBaseName; - std::ifstream fp; + std::ifstream fp; fp.open(configFileName.c_str(), std::ios::in); if(fp.is_open()) { @@ -514,9 +514,9 @@ namespace Ogre { return false; } - String err = rs->validateConfigOptions(); - if (err.length() > 0) - return false; + String err = rs->validateConfigOptions(); + if (err.length() > 0) + return false; setRenderSystem(rs); @@ -541,7 +541,7 @@ namespace Ogre { restoreConfig(); dlg = OGRE_NEW ConfigDialog(); - isOk = dlg->display(); + isOk = dlg->display(); if (isOk) saveConfig(); @@ -603,26 +603,26 @@ namespace Ogre { { mRenderers.push_back(newRend); } - //----------------------------------------------------------------------- - SceneManager* Root::_getCurrentSceneManager(void) const - { - if (mSceneManagerStack.empty()) - return 0; - else - return mSceneManagerStack.back(); - } - //----------------------------------------------------------------------- - void Root::_pushCurrentSceneManager(SceneManager* sm) - { - mSceneManagerStack.push_back(sm); - } - //----------------------------------------------------------------------- - void Root::_popCurrentSceneManager(SceneManager* sm) - { - assert (_getCurrentSceneManager() == sm && "Mismatched push/pop of SceneManager"); - - mSceneManagerStack.pop_back(); - } + //----------------------------------------------------------------------- + SceneManager* Root::_getCurrentSceneManager(void) const + { + if (mSceneManagerStack.empty()) + return 0; + else + return mSceneManagerStack.back(); + } + //----------------------------------------------------------------------- + void Root::_pushCurrentSceneManager(SceneManager* sm) + { + mSceneManagerStack.push_back(sm); + } + //----------------------------------------------------------------------- + void Root::_popCurrentSceneManager(SceneManager* sm) + { + assert (_getCurrentSceneManager() == sm && "Mismatched push/pop of SceneManager"); + + mSceneManagerStack.pop_back(); + } //----------------------------------------------------------------------- RenderSystem* Root::getRenderSystem(void) { @@ -640,7 +640,7 @@ namespace Ogre { "system has been selected.", "Root::initialise"); if (!mControllerManager) - mControllerManager = OGRE_NEW ControllerManager(); + mControllerManager = OGRE_NEW ControllerManager(); // .rendercaps manager RenderSystemCapabilitiesManager& rscManager = RenderSystemCapabilitiesManager::getSingleton(); @@ -675,20 +675,20 @@ namespace Ogre { String capsName = cfg.getSetting("Custom Capabilities"); // The custom capabilities have been parsed, let's retrieve them RenderSystemCapabilities* rsc = rscManager.loadParsedCapabilities(capsName); - if(rsc == 0) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - String("Cannot load a RenderSystemCapability named ") + capsName, - "Root::initialise"); - } + if(rsc == 0) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + String("Cannot load a RenderSystemCapability named ") + capsName, + "Root::initialise"); + } // Tell RenderSystem to use the comon rsc useCustomRenderSystemCapabilities(rsc); } - PlatformInformation::log(LogManager::getSingleton().getDefaultLog()); - mAutoWindow = mActiveRenderer->_initialise(autoCreateWindow, windowTitle); + PlatformInformation::log(LogManager::getSingleton().getDefaultLog()); + mAutoWindow = mActiveRenderer->_initialise(autoCreateWindow, windowTitle); if (autoCreateWindow && !mFirstTimePostWindowInit) @@ -700,10 +700,10 @@ namespace Ogre { // Initialise timer mTimer->reset(); - // Init pools - ConvexBody::_initialisePool(); + // Init pools + ConvexBody::_initialisePool(); - mIsInitialised = true; + mIsInitialised = true; return mAutoWindow; @@ -724,60 +724,60 @@ namespace Ogre { return ""; } - //----------------------------------------------------------------------- - void Root::addSceneManagerFactory(SceneManagerFactory* fact) - { - mSceneManagerEnum->addFactory(fact); - } - //----------------------------------------------------------------------- - void Root::removeSceneManagerFactory(SceneManagerFactory* fact) - { - mSceneManagerEnum->removeFactory(fact); - } - //----------------------------------------------------------------------- - const SceneManagerMetaData* Root::getSceneManagerMetaData(const String& typeName) const - { - return mSceneManagerEnum->getMetaData(typeName); - } - //----------------------------------------------------------------------- - SceneManagerEnumerator::MetaDataIterator - Root::getSceneManagerMetaDataIterator(void) const - { - return mSceneManagerEnum->getMetaDataIterator(); - - } - //----------------------------------------------------------------------- - SceneManager* Root::createSceneManager(const String& typeName, - const String& instanceName) - { - return mSceneManagerEnum->createSceneManager(typeName, instanceName); - } - //----------------------------------------------------------------------- - SceneManager* Root::createSceneManager(SceneTypeMask typeMask, - const String& instanceName) - { - return mSceneManagerEnum->createSceneManager(typeMask, instanceName); - } - //----------------------------------------------------------------------- - void Root::destroySceneManager(SceneManager* sm) - { - mSceneManagerEnum->destroySceneManager(sm); - } - //----------------------------------------------------------------------- - SceneManager* Root::getSceneManager(const String& instanceName) const - { - return mSceneManagerEnum->getSceneManager(instanceName); - } - //--------------------------------------------------------------------- - bool Root::hasSceneManager(const String& instanceName) const - { - return mSceneManagerEnum->hasSceneManager(instanceName); - } - //----------------------------------------------------------------------- - SceneManagerEnumerator::SceneManagerIterator Root::getSceneManagerIterator(void) - { - return mSceneManagerEnum->getSceneManagerIterator(); - } + //----------------------------------------------------------------------- + void Root::addSceneManagerFactory(SceneManagerFactory* fact) + { + mSceneManagerEnum->addFactory(fact); + } + //----------------------------------------------------------------------- + void Root::removeSceneManagerFactory(SceneManagerFactory* fact) + { + mSceneManagerEnum->removeFactory(fact); + } + //----------------------------------------------------------------------- + const SceneManagerMetaData* Root::getSceneManagerMetaData(const String& typeName) const + { + return mSceneManagerEnum->getMetaData(typeName); + } + //----------------------------------------------------------------------- + SceneManagerEnumerator::MetaDataIterator + Root::getSceneManagerMetaDataIterator(void) const + { + return mSceneManagerEnum->getMetaDataIterator(); + + } + //----------------------------------------------------------------------- + SceneManager* Root::createSceneManager(const String& typeName, + const String& instanceName) + { + return mSceneManagerEnum->createSceneManager(typeName, instanceName); + } + //----------------------------------------------------------------------- + SceneManager* Root::createSceneManager(SceneTypeMask typeMask, + const String& instanceName) + { + return mSceneManagerEnum->createSceneManager(typeMask, instanceName); + } + //----------------------------------------------------------------------- + void Root::destroySceneManager(SceneManager* sm) + { + mSceneManagerEnum->destroySceneManager(sm); + } + //----------------------------------------------------------------------- + SceneManager* Root::getSceneManager(const String& instanceName) const + { + return mSceneManagerEnum->getSceneManager(instanceName); + } + //--------------------------------------------------------------------- + bool Root::hasSceneManager(const String& instanceName) const + { + return mSceneManagerEnum->hasSceneManager(instanceName); + } + //----------------------------------------------------------------------- + SceneManagerEnumerator::SceneManagerIterator Root::getSceneManagerIterator(void) + { + return mSceneManagerEnum->getSceneManagerIterator(); + } //----------------------------------------------------------------------- TextureManager* Root::getTextureManager(void) { @@ -814,7 +814,7 @@ namespace Ogre { //----------------------------------------------------------------------- bool Root::_fireFrameStarted(FrameEvent& evt) { - OgreProfileBeginGroup("Frame", OGREPROF_GENERAL); + OgreProfileBeginGroup("Frame", OGREPROF_GENERAL); _syncAddedRemovedFrameListeners(); // Tell all listeners @@ -826,11 +826,11 @@ namespace Ogre { return true; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- bool Root::_fireFrameRenderingQueued(FrameEvent& evt) { - // Increment next frame number - ++mNextFrame; + // Increment next frame number + ++mNextFrame; _syncAddedRemovedFrameListeners(); // Tell all listeners @@ -848,24 +848,24 @@ namespace Ogre { _syncAddedRemovedFrameListeners(); // Tell all listeners - bool ret = true; + bool ret = true; for (set::type::iterator i = mFrameListeners.begin(); i != mFrameListeners.end(); ++i) { if (!(*i)->frameEnded(evt)) - { + { ret = false; - break; - } + break; + } } // Tell buffer manager to free temp buffers used this frame if (HardwareBufferManager::getSingletonPtr()) HardwareBufferManager::getSingleton()._releaseBufferCopies(); - // Tell the queue to process responses - mWorkQueue->processResponses(); + // Tell the queue to process responses + mWorkQueue->processResponses(); - OgreProfileEndGroup("Frame", OGREPROF_GENERAL); + OgreProfileEndGroup("Frame", OGREPROF_GENERAL); return ret; } @@ -873,15 +873,15 @@ namespace Ogre { bool Root::_fireFrameStarted() { FrameEvent evt; - populateFrameEvent(FETT_STARTED, evt); + populateFrameEvent(FETT_STARTED, evt); return _fireFrameStarted(evt); } //----------------------------------------------------------------------- bool Root::_fireFrameRenderingQueued() { - FrameEvent evt; - populateFrameEvent(FETT_QUEUED, evt); + FrameEvent evt; + populateFrameEvent(FETT_QUEUED, evt); return _fireFrameRenderingQueued(evt); } @@ -889,16 +889,16 @@ namespace Ogre { bool Root::_fireFrameEnded() { FrameEvent evt; - populateFrameEvent(FETT_ENDED, evt); + populateFrameEvent(FETT_ENDED, evt); return _fireFrameEnded(evt); } - //--------------------------------------------------------------------- - void Root::populateFrameEvent(FrameEventTimeType type, FrameEvent& evtToUpdate) - { - unsigned long now = mTimer->getMilliseconds(); - evtToUpdate.timeSinceLastEvent = calculateEventTime(now, FETT_ANY); - evtToUpdate.timeSinceLastFrame = calculateEventTime(now, type); - } + //--------------------------------------------------------------------- + void Root::populateFrameEvent(FrameEventTimeType type, FrameEvent& evtToUpdate) + { + unsigned long now = mTimer->getMilliseconds(); + evtToUpdate.timeSinceLastEvent = calculateEventTime(now, FETT_ANY); + evtToUpdate.timeSinceLastFrame = calculateEventTime(now, type); + } //----------------------------------------------------------------------- Real Root::calculateEventTime(unsigned long now, FrameEventTimeType type) { @@ -913,7 +913,7 @@ namespace Ogre { // Times up to mFrameSmoothingTime seconds old should be kept unsigned long discardThreshold = - static_cast(mFrameSmoothingTime * 1000.0f); + static_cast(mFrameSmoothingTime * 1000.0f); // Find the oldest time to keep EventTimesQueue::iterator it = times.begin(), @@ -934,12 +934,12 @@ namespace Ogre { //----------------------------------------------------------------------- void Root::queueEndRendering(bool state /* = true */) { - mQueuedEnd = state; + mQueuedEnd = state; } //----------------------------------------------------------------------- bool Root::endRenderingQueued(void) { - return mQueuedEnd; + return mQueuedEnd; } //----------------------------------------------------------------------- void Root::startRendering(void) @@ -949,7 +949,7 @@ namespace Ogre { mActiveRenderer->_initRenderTargets(); // Clear event times - clearEventTimes(); + clearEventTimes(); // Infinite loop, until broken out of by frame listeners // or break out by calling queueEndRendering() @@ -957,10 +957,10 @@ namespace Ogre { while( !mQueuedEnd ) { - //Pump messages in all registered RenderWindow windows - WindowEventUtilities::messagePump(); + //Pump messages in all registered RenderWindow windows + WindowEventUtilities::messagePump(); - if (!renderOneFrame()) + if (!renderOneFrame()) break; } } @@ -970,55 +970,55 @@ namespace Ogre { if(!_fireFrameStarted()) return false; - if (!_updateAllRenderTargets()) - return false; + if (!_updateAllRenderTargets()) + return false; return _fireFrameEnded(); } - //--------------------------------------------------------------------- - bool Root::renderOneFrame(Real timeSinceLastFrame) - { - FrameEvent evt; - evt.timeSinceLastFrame = timeSinceLastFrame; + //--------------------------------------------------------------------- + bool Root::renderOneFrame(Real timeSinceLastFrame) + { + FrameEvent evt; + evt.timeSinceLastFrame = timeSinceLastFrame; - unsigned long now = mTimer->getMilliseconds(); - evt.timeSinceLastEvent = calculateEventTime(now, FETT_ANY); + unsigned long now = mTimer->getMilliseconds(); + evt.timeSinceLastEvent = calculateEventTime(now, FETT_ANY); - if(!_fireFrameStarted(evt)) - return false; + if(!_fireFrameStarted(evt)) + return false; - if (!_updateAllRenderTargets(evt)) - return false; + if (!_updateAllRenderTargets(evt)) + return false; - now = mTimer->getMilliseconds(); - evt.timeSinceLastEvent = calculateEventTime(now, FETT_ANY); + now = mTimer->getMilliseconds(); + evt.timeSinceLastEvent = calculateEventTime(now, FETT_ANY); - return _fireFrameEnded(evt); - } + return _fireFrameEnded(evt); + } //----------------------------------------------------------------------- void Root::shutdown(void) { - if(mActiveRenderer) - mActiveRenderer->_setViewport(NULL); + if(mActiveRenderer) + mActiveRenderer->_setViewport(NULL); - // Since background thread might be access resources, - // ensure shutdown before destroying resource manager. - mResourceBackgroundQueue->shutdown(); - mWorkQueue->shutdown(); + // Since background thread might be access resources, + // ensure shutdown before destroying resource manager. + mResourceBackgroundQueue->shutdown(); + mWorkQueue->shutdown(); - SceneManagerEnumerator::getSingleton().shutdownAll(); - shutdownPlugins(); + SceneManagerEnumerator::getSingleton().shutdownAll(); + shutdownPlugins(); ShadowVolumeExtrudeProgram::shutdown(); ResourceGroupManager::getSingleton().shutdownAll(); - // Destroy pools - ConvexBody::_destroyPool(); + // Destroy pools + ConvexBody::_destroyPool(); - mIsInitialised = false; + mIsInitialised = false; - LogManager::getSingleton().logMessage("*-*-* OGRE Shutdown"); + LogManager::getSingleton().logMessage("*-*-* OGRE Shutdown"); } //----------------------------------------------------------------------- void Root::loadPlugins( const String& pluginsfile ) @@ -1027,14 +1027,14 @@ namespace Ogre { String pluginDir; ConfigFile cfg; - try { - cfg.load( pluginsfile ); - } - catch (Exception) - { - LogManager::getSingleton().logMessage(pluginsfile + " not found, automatic plugin loading disabled."); - return; - } + try { + cfg.load( pluginsfile ); + } + catch (Exception) + { + LogManager::getSingleton().logMessage(pluginsfile + " not found, automatic plugin loading disabled."); + return; + } pluginDir = cfg.getSetting("PluginFolder"); // Ignored on Mac OS X, uses Resources/ directory pluginList = cfg.getMultiSetting("Plugin"); @@ -1050,32 +1050,32 @@ namespace Ogre { for( StringVector::iterator it = pluginList.begin(); it != pluginList.end(); ++it ) { - loadPlugin(pluginDir + (*it)); + loadPlugin(pluginDir + (*it)); } } //----------------------------------------------------------------------- - void Root::shutdownPlugins(void) - { - // NB Shutdown plugins in reverse order to enforce dependencies - for (PluginInstanceList::reverse_iterator i = mPlugins.rbegin(); i != mPlugins.rend(); ++i) - { - (*i)->shutdown(); - } - } - //----------------------------------------------------------------------- - void Root::initialisePlugins(void) - { - for (PluginInstanceList::iterator i = mPlugins.begin(); i != mPlugins.end(); ++i) - { - (*i)->initialise(); - } - } - //----------------------------------------------------------------------- - void Root::unloadPlugins(void) + void Root::shutdownPlugins(void) + { + // NB Shutdown plugins in reverse order to enforce dependencies + for (PluginInstanceList::reverse_iterator i = mPlugins.rbegin(); i != mPlugins.rend(); ++i) + { + (*i)->shutdown(); + } + } + //----------------------------------------------------------------------- + void Root::initialisePlugins(void) + { + for (PluginInstanceList::iterator i = mPlugins.begin(); i != mPlugins.end(); ++i) + { + (*i)->initialise(); + } + } + //----------------------------------------------------------------------- + void Root::unloadPlugins(void) { #if OGRE_PLATFORM != OGRE_PLATFORM_NACL - // unload dynamic libs first + // unload dynamic libs first for (PluginLibList::reverse_iterator i = mPluginLibs.rbegin(); i != mPluginLibs.rend(); ++i) { // Call plugin shutdown @@ -1083,102 +1083,102 @@ namespace Ogre { __extension__ #endif DLL_STOP_PLUGIN pFunc = reinterpret_cast((*i)->getSymbol("dllStopPlugin")); - // this will call uninstallPlugin + // this will call uninstallPlugin pFunc(); // Unload library & destroy DynLibManager::getSingleton().unload(*i); } - mPluginLibs.clear(); - - // now deal with any remaining plugins that were registered through other means - for (PluginInstanceList::reverse_iterator i = mPlugins.rbegin(); i != mPlugins.rend(); ++i) - { - // Note this does NOT call uninstallPlugin - this shutdown is for the - // detail objects - (*i)->uninstall(); - } - mPlugins.clear(); + mPluginLibs.clear(); + + // now deal with any remaining plugins that were registered through other means + for (PluginInstanceList::reverse_iterator i = mPlugins.rbegin(); i != mPlugins.rend(); ++i) + { + // Note this does NOT call uninstallPlugin - this shutdown is for the + // detail objects + (*i)->uninstall(); + } + mPlugins.clear(); #endif } //----------------------------------------------------------------------- void Root::addResourceLocation(const String& name, const String& locType, - const String& groupName, bool recursive) - { - ResourceGroupManager::getSingleton().addResourceLocation( - name, locType, groupName, recursive); - } - //----------------------------------------------------------------------- - void Root::removeResourceLocation(const String& name, const String& groupName) - { - ResourceGroupManager::getSingleton().removeResourceLocation( - name, groupName); - } - //--------------------------------------------------------------------- - DataStreamPtr Root::createFileStream(const String& filename, const String& groupName, - bool overwrite, const String& locationPattern) - { - // Does this file include path specifiers? - String path, basename; - StringUtil::splitFilename(filename, basename, path); - - // no path elements, try the resource system first - DataStreamPtr stream; - if (path.empty()) - { - try - { - stream = ResourceGroupManager::getSingleton().createResource( - filename, groupName, overwrite, locationPattern); - } - catch (...) {} - - } - - if (stream.isNull()) - { - // save direct in filesystem - std::fstream* fs = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL); - fs->open(filename.c_str(), std::ios::out | std::ios::binary); - if (!*fs) - { - OGRE_DELETE_T(fs, basic_fstream, MEMCATEGORY_GENERAL); - OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, - "Can't open " + filename + " for writing", __FUNCTION__); - } - - stream = DataStreamPtr(OGRE_NEW FileStreamDataStream(filename, fs)); - } - - return stream; - - } - //--------------------------------------------------------------------- - DataStreamPtr Root::openFileStream(const String& filename, const String& groupName, - const String& locationPattern) - { - DataStreamPtr stream; - if (ResourceGroupManager::getSingleton().resourceExists( - groupName, filename)) - { - stream = ResourceGroupManager::getSingleton().openResource( - filename, groupName); - } - else - { - // try direct - std::ifstream *ifs = OGRE_NEW_T(std::ifstream, MEMCATEGORY_GENERAL); - ifs->open(filename.c_str(), std::ios::in | std::ios::binary); - if(!*ifs) - { - OGRE_DELETE_T(ifs, basic_ifstream, MEMCATEGORY_GENERAL); - OGRE_EXCEPT( - Exception::ERR_FILE_NOT_FOUND, "'" + filename + "' file not found!", __FUNCTION__); - } - stream.bind(OGRE_NEW FileStreamDataStream(filename, ifs)); - } - return stream; - } + const String& groupName, bool recursive) + { + ResourceGroupManager::getSingleton().addResourceLocation( + name, locType, groupName, recursive); + } + //----------------------------------------------------------------------- + void Root::removeResourceLocation(const String& name, const String& groupName) + { + ResourceGroupManager::getSingleton().removeResourceLocation( + name, groupName); + } + //--------------------------------------------------------------------- + DataStreamPtr Root::createFileStream(const String& filename, const String& groupName, + bool overwrite, const String& locationPattern) + { + // Does this file include path specifiers? + String path, basename; + StringUtil::splitFilename(filename, basename, path); + + // no path elements, try the resource system first + DataStreamPtr stream; + if (path.empty()) + { + try + { + stream = ResourceGroupManager::getSingleton().createResource( + filename, groupName, overwrite, locationPattern); + } + catch (...) {} + + } + + if (stream.isNull()) + { + // save direct in filesystem + std::fstream* fs = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL); + fs->open(filename.c_str(), std::ios::out | std::ios::binary); + if (!*fs) + { + OGRE_DELETE_T(fs, basic_fstream, MEMCATEGORY_GENERAL); + OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, + "Can't open " + filename + " for writing", __FUNCTION__); + } + + stream = DataStreamPtr(OGRE_NEW FileStreamDataStream(filename, fs)); + } + + return stream; + + } + //--------------------------------------------------------------------- + DataStreamPtr Root::openFileStream(const String& filename, const String& groupName, + const String& locationPattern) + { + DataStreamPtr stream; + if (ResourceGroupManager::getSingleton().resourceExists( + groupName, filename)) + { + stream = ResourceGroupManager::getSingleton().openResource( + filename, groupName); + } + else + { + // try direct + std::ifstream *ifs = OGRE_NEW_T(std::ifstream, MEMCATEGORY_GENERAL); + ifs->open(filename.c_str(), std::ios::in | std::ios::binary); + if(!*ifs) + { + OGRE_DELETE_T(ifs, basic_ifstream, MEMCATEGORY_GENERAL); + OGRE_EXCEPT( + Exception::ERR_FILE_NOT_FOUND, "'" + filename + "' file not found!", __FUNCTION__); + } + stream.bind(OGRE_NEW FileStreamDataStream(filename, ifs)); + } + return stream; + } //----------------------------------------------------------------------- void Root::convertColourValue(const ColourValue& colour, uint32* pDest) { @@ -1191,15 +1191,15 @@ namespace Ogre { return mAutoWindow; } //----------------------------------------------------------------------- - RenderWindow* Root::createRenderWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) - { - if (!mIsInitialised) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Cannot create window - Root has not been initialised! " - "Make sure to call Root::initialise before creating a window.", "Root::createRenderWindow"); - } + RenderWindow* Root::createRenderWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams) + { + if (!mIsInitialised) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Cannot create window - Root has not been initialised! " + "Make sure to call Root::initialise before creating a window.", "Root::createRenderWindow"); + } if (!mActiveRenderer) { OGRE_EXCEPT(Exception::ERR_INVALID_STATE, @@ -1219,34 +1219,34 @@ namespace Ogre { return ret; } - //----------------------------------------------------------------------- - bool Root::createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, - RenderWindowList& createdWindows) - { - if (!mIsInitialised) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Cannot create window - Root has not been initialised! " - "Make sure to call Root::initialise before creating a window.", "Root::createRenderWindows"); - } - if (!mActiveRenderer) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Cannot create render windows - no render " - "system has been selected.", "Root::createRenderWindows"); - } - - bool success; - - success = mActiveRenderer->_createRenderWindows(renderWindowDescriptions, createdWindows); - if(success && !mFirstTimePostWindowInit) - { - oneTimePostWindowInit(); - createdWindows[0]->_setPrimary(); - } - - return success; - } + //----------------------------------------------------------------------- + bool Root::createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, + RenderWindowList& createdWindows) + { + if (!mIsInitialised) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Cannot create window - Root has not been initialised! " + "Make sure to call Root::initialise before creating a window.", "Root::createRenderWindows"); + } + if (!mActiveRenderer) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Cannot create render windows - no render " + "system has been selected.", "Root::createRenderWindows"); + } + + bool success; + + success = mActiveRenderer->_createRenderWindows(renderWindowDescriptions, createdWindows); + if(success && !mFirstTimePostWindowInit) + { + oneTimePostWindowInit(); + createdWindows[0]->_setPrimary(); + } + + return success; + } //----------------------------------------------------------------------- RenderTarget* Root::detachRenderTarget(RenderTarget* target) { @@ -1295,87 +1295,87 @@ namespace Ogre { return mActiveRenderer->getRenderTarget(name); } - //--------------------------------------------------------------------- - void Root::installPlugin(Plugin* plugin) - { - LogManager::getSingleton().logMessage("Installing plugin: " + plugin->getName()); - - mPlugins.push_back(plugin); - plugin->install(); - - // if rendersystem is already initialised, call rendersystem init too - if (mIsInitialised) - { - plugin->initialise(); - } - - LogManager::getSingleton().logMessage("Plugin successfully installed"); - } - //--------------------------------------------------------------------- - void Root::uninstallPlugin(Plugin* plugin) - { - LogManager::getSingleton().logMessage("Uninstalling plugin: " + plugin->getName()); - PluginInstanceList::iterator i = - std::find(mPlugins.begin(), mPlugins.end(), plugin); - if (i != mPlugins.end()) - { - if (mIsInitialised) - plugin->shutdown(); - plugin->uninstall(); - mPlugins.erase(i); - } - LogManager::getSingleton().logMessage("Plugin successfully uninstalled"); - - } - //----------------------------------------------------------------------- - void Root::loadPlugin(const String& pluginName) - { + //--------------------------------------------------------------------- + void Root::installPlugin(Plugin* plugin) + { + LogManager::getSingleton().logMessage("Installing plugin: " + plugin->getName()); + + mPlugins.push_back(plugin); + plugin->install(); + + // if rendersystem is already initialised, call rendersystem init too + if (mIsInitialised) + { + plugin->initialise(); + } + + LogManager::getSingleton().logMessage("Plugin successfully installed"); + } + //--------------------------------------------------------------------- + void Root::uninstallPlugin(Plugin* plugin) + { + LogManager::getSingleton().logMessage("Uninstalling plugin: " + plugin->getName()); + PluginInstanceList::iterator i = + std::find(mPlugins.begin(), mPlugins.end(), plugin); + if (i != mPlugins.end()) + { + if (mIsInitialised) + plugin->shutdown(); + plugin->uninstall(); + mPlugins.erase(i); + } + LogManager::getSingleton().logMessage("Plugin successfully uninstalled"); + + } + //----------------------------------------------------------------------- + void Root::loadPlugin(const String& pluginName) + { #if OGRE_PLATFORM != OGRE_PLATFORM_NACL - // Load plugin library + // Load plugin library DynLib* lib = DynLibManager::getSingleton().load( pluginName ); - // Store for later unload - // Check for existence, because if called 2+ times DynLibManager returns existing entry - if (std::find(mPluginLibs.begin(), mPluginLibs.end(), lib) == mPluginLibs.end()) - { - mPluginLibs.push_back(lib); + // Store for later unload + // Check for existence, because if called 2+ times DynLibManager returns existing entry + if (std::find(mPluginLibs.begin(), mPluginLibs.end(), lib) == mPluginLibs.end()) + { + mPluginLibs.push_back(lib); - // Call startup function + // Call startup function #ifdef __GNUC__ __extension__ #endif - DLL_START_PLUGIN pFunc = (DLL_START_PLUGIN)lib->getSymbol("dllStartPlugin"); + DLL_START_PLUGIN pFunc = (DLL_START_PLUGIN)lib->getSymbol("dllStartPlugin"); - if (!pFunc) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot find symbol dllStartPlugin in library " + pluginName, - "Root::loadPlugin"); + if (!pFunc) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot find symbol dllStartPlugin in library " + pluginName, + "Root::loadPlugin"); - // This must call installPlugin - pFunc(); - } + // This must call installPlugin + pFunc(); + } #endif - } + } //----------------------------------------------------------------------- - void Root::unloadPlugin(const String& pluginName) - { + void Root::unloadPlugin(const String& pluginName) + { #if OGRE_PLATFORM != OGRE_PLATFORM_NACL PluginLibList::iterator i; for (i = mPluginLibs.begin(); i != mPluginLibs.end(); ++i) { - if ((*i)->getName() == pluginName) - { - // Call plugin shutdown + if ((*i)->getName() == pluginName) + { + // Call plugin shutdown #ifdef __GNUC__ __extension__ #endif - DLL_STOP_PLUGIN pFunc = (DLL_STOP_PLUGIN)(*i)->getSymbol("dllStopPlugin"); - // this must call uninstallPlugin - pFunc(); - // Unload library (destroyed by DynLibManager) - DynLibManager::getSingleton().unload(*i); - mPluginLibs.erase(i); - return; - } + DLL_STOP_PLUGIN pFunc = (DLL_STOP_PLUGIN)(*i)->getSymbol("dllStopPlugin"); + // this must call uninstallPlugin + pFunc(); + // Unload library (destroyed by DynLibManager) + DynLibManager::getSingleton().unload(*i); + mPluginLibs.erase(i); + return; + } } #endif @@ -1390,17 +1390,17 @@ namespace Ogre { { if (!mFirstTimePostWindowInit) { - // Background loader - mResourceBackgroundQueue->initialise(); - mWorkQueue->startup(); - // Initialise material manager - mMaterialManager->initialise(); + // Background loader + mResourceBackgroundQueue->initialise(); + mWorkQueue->startup(); + // Initialise material manager + mMaterialManager->initialise(); // Init particle systems manager mParticleManager->_initialise(); - // Init mesh manager - MeshManager::getSingleton()._initialise(); - // Init plugins - after window creation so rsys resources available - initialisePlugins(); + // Init mesh manager + MeshManager::getSingleton()._initialise(); + // Init plugins - after window creation so rsys resources available + initialisePlugins(); mFirstTimePostWindowInit = true; } @@ -1410,10 +1410,28 @@ namespace Ogre { { // update all targets but don't swap buffers mActiveRenderer->_updateAllRenderTargets(false); - // give client app opportunity to use queued GPU time - bool ret = _fireFrameRenderingQueued(); - // block for final swap - mActiveRenderer->_swapAllRenderTargetBuffers(); + // give client app opportunity to use queued GPU time + bool ret = _fireFrameRenderingQueued(); + // block for final swap + mActiveRenderer->_swapAllRenderTargetBuffers(); + + // This belongs here, as all render targets must be updated before events are + // triggered, otherwise targets could be mismatched. This could produce artifacts, + // for instance, with shadows. + for (SceneManagerEnumerator::SceneManagerIterator it = getSceneManagerIterator(); it.hasMoreElements(); it.moveNext()) + it.peekNextValue()->_handleLodEvents(); + + return ret; + } + //--------------------------------------------------------------------- + bool Root::_updateAllRenderTargets(FrameEvent& evt) + { + // update all targets but don't swap buffers + mActiveRenderer->_updateAllRenderTargets(false); + // give client app opportunity to use queued GPU time + bool ret = _fireFrameRenderingQueued(evt); + // block for final swap + mActiveRenderer->_swapAllRenderTargetBuffers(); // This belongs here, as all render targets must be updated before events are // triggered, otherwise targets could be mismatched. This could produce artifacts, @@ -1421,202 +1439,184 @@ namespace Ogre { for (SceneManagerEnumerator::SceneManagerIterator it = getSceneManagerIterator(); it.hasMoreElements(); it.moveNext()) it.peekNextValue()->_handleLodEvents(); - return ret; - } - //--------------------------------------------------------------------- - bool Root::_updateAllRenderTargets(FrameEvent& evt) - { - // update all targets but don't swap buffers - mActiveRenderer->_updateAllRenderTargets(false); - // give client app opportunity to use queued GPU time - bool ret = _fireFrameRenderingQueued(evt); - // block for final swap - mActiveRenderer->_swapAllRenderTargetBuffers(); - - // This belongs here, as all render targets must be updated before events are - // triggered, otherwise targets could be mismatched. This could produce artifacts, - // for instance, with shadows. - for (SceneManagerEnumerator::SceneManagerIterator it = getSceneManagerIterator(); it.hasMoreElements(); it.moveNext()) - it.peekNextValue()->_handleLodEvents(); - - return ret; - } - //----------------------------------------------------------------------- - void Root::clearEventTimes(void) - { - // Clear event times - for(int i=0; igetType()); - if (!overrideExisting && facti != mMovableObjectFactoryMap.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "A factory of type '" + fact->getType() + "' already exists.", - "Root::addMovableObjectFactory"); - } - - if (fact->requestTypeFlags()) - { - if (facti != mMovableObjectFactoryMap.end() && facti->second->requestTypeFlags()) - { - // Copy type flags from the factory we're replacing - fact->_notifyTypeFlags(facti->second->getTypeFlags()); - } - else - { - // Allocate new - fact->_notifyTypeFlags(_allocateNextMovableObjectTypeFlag()); - } - } - - // Save - mMovableObjectFactoryMap[fact->getType()] = fact; - - LogManager::getSingleton().logMessage("MovableObjectFactory for type '" + - fact->getType() + "' registered."); - - } - //--------------------------------------------------------------------- - bool Root::hasMovableObjectFactory(const String& typeName) const - { - return !(mMovableObjectFactoryMap.find(typeName) == mMovableObjectFactoryMap.end()); - } - //--------------------------------------------------------------------- - MovableObjectFactory* Root::getMovableObjectFactory(const String& typeName) - { - MovableObjectFactoryMap::iterator i = - mMovableObjectFactoryMap.find(typeName); - if (i == mMovableObjectFactoryMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "MovableObjectFactory of type " + typeName + " does not exist", - "Root::getMovableObjectFactory"); - } - return i->second; - } - //--------------------------------------------------------------------- - uint32 Root::_allocateNextMovableObjectTypeFlag(void) - { - if (mNextMovableObjectTypeFlag == SceneManager::USER_TYPE_MASK_LIMIT) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "Cannot allocate a type flag since " - "all the available flags have been used.", - "Root::_allocateNextMovableObjectTypeFlag"); - - } - uint32 ret = mNextMovableObjectTypeFlag; - mNextMovableObjectTypeFlag <<= 1; - return ret; - - } - //--------------------------------------------------------------------- - void Root::removeMovableObjectFactory(MovableObjectFactory* fact) - { - MovableObjectFactoryMap::iterator i = mMovableObjectFactoryMap.find( - fact->getType()); - if (i != mMovableObjectFactoryMap.end()) - { - mMovableObjectFactoryMap.erase(i); - } - - } - //--------------------------------------------------------------------- - Root::MovableObjectFactoryIterator - Root::getMovableObjectFactoryIterator(void) const - { - return MovableObjectFactoryIterator(mMovableObjectFactoryMap.begin(), - mMovableObjectFactoryMap.end()); - - } - //--------------------------------------------------------------------- - RenderQueueInvocationSequence* Root::createRenderQueueInvocationSequence( - const String& name) - { - RenderQueueInvocationSequenceMap::iterator i = - mRQSequenceMap.find(name); - if (i != mRQSequenceMap.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "RenderQueueInvocationSequence with the name " + name + - " already exists.", - "Root::createRenderQueueInvocationSequence"); - } - RenderQueueInvocationSequence* ret = OGRE_NEW RenderQueueInvocationSequence(name); - mRQSequenceMap[name] = ret; - return ret; - } - //--------------------------------------------------------------------- - RenderQueueInvocationSequence* Root::getRenderQueueInvocationSequence( - const String& name) - { - RenderQueueInvocationSequenceMap::iterator i = - mRQSequenceMap.find(name); - if (i == mRQSequenceMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "RenderQueueInvocationSequence with the name " + name + - " not found.", - "Root::getRenderQueueInvocationSequence"); - } - return i->second; - } - //--------------------------------------------------------------------- - void Root::destroyRenderQueueInvocationSequence( - const String& name) - { - RenderQueueInvocationSequenceMap::iterator i = - mRQSequenceMap.find(name); - if (i != mRQSequenceMap.end()) - { - OGRE_DELETE i->second; - mRQSequenceMap.erase(i); - } - } - //--------------------------------------------------------------------- - void Root::destroyAllRenderQueueInvocationSequences(void) - { - for (RenderQueueInvocationSequenceMap::iterator i = mRQSequenceMap.begin(); - i != mRQSequenceMap.end(); ++i) - { - OGRE_DELETE i->second; - } - mRQSequenceMap.clear(); - } - - //--------------------------------------------------------------------- - unsigned int Root::getDisplayMonitorCount() const - { - if (!mActiveRenderer) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Cannot get display monitor count " - "No render system has been selected.", "Root::getDisplayMonitorCount"); - } - - return mActiveRenderer->getDisplayMonitorCount(); - - } - //--------------------------------------------------------------------- - void Root::setWorkQueue(WorkQueue* queue) - { - if (mWorkQueue != queue) - { - // delete old one (will shut down) - OGRE_DELETE mWorkQueue; - - mWorkQueue = queue; - if (mIsInitialised) - mWorkQueue->startup(); - - } - } + return ret; + } + //----------------------------------------------------------------------- + void Root::clearEventTimes(void) + { + // Clear event times + for(int i=0; igetType()); + if (!overrideExisting && facti != mMovableObjectFactoryMap.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "A factory of type '" + fact->getType() + "' already exists.", + "Root::addMovableObjectFactory"); + } + + if (fact->requestTypeFlags()) + { + if (facti != mMovableObjectFactoryMap.end() && facti->second->requestTypeFlags()) + { + // Copy type flags from the factory we're replacing + fact->_notifyTypeFlags(facti->second->getTypeFlags()); + } + else + { + // Allocate new + fact->_notifyTypeFlags(_allocateNextMovableObjectTypeFlag()); + } + } + + // Save + mMovableObjectFactoryMap[fact->getType()] = fact; + + LogManager::getSingleton().logMessage("MovableObjectFactory for type '" + + fact->getType() + "' registered."); + + } + //--------------------------------------------------------------------- + bool Root::hasMovableObjectFactory(const String& typeName) const + { + return !(mMovableObjectFactoryMap.find(typeName) == mMovableObjectFactoryMap.end()); + } + //--------------------------------------------------------------------- + MovableObjectFactory* Root::getMovableObjectFactory(const String& typeName) + { + MovableObjectFactoryMap::iterator i = + mMovableObjectFactoryMap.find(typeName); + if (i == mMovableObjectFactoryMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "MovableObjectFactory of type " + typeName + " does not exist", + "Root::getMovableObjectFactory"); + } + return i->second; + } + //--------------------------------------------------------------------- + uint32 Root::_allocateNextMovableObjectTypeFlag(void) + { + if (mNextMovableObjectTypeFlag == SceneManager::USER_TYPE_MASK_LIMIT) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "Cannot allocate a type flag since " + "all the available flags have been used.", + "Root::_allocateNextMovableObjectTypeFlag"); + + } + uint32 ret = mNextMovableObjectTypeFlag; + mNextMovableObjectTypeFlag <<= 1; + return ret; + + } + //--------------------------------------------------------------------- + void Root::removeMovableObjectFactory(MovableObjectFactory* fact) + { + MovableObjectFactoryMap::iterator i = mMovableObjectFactoryMap.find( + fact->getType()); + if (i != mMovableObjectFactoryMap.end()) + { + mMovableObjectFactoryMap.erase(i); + } + + } + //--------------------------------------------------------------------- + Root::MovableObjectFactoryIterator + Root::getMovableObjectFactoryIterator(void) const + { + return MovableObjectFactoryIterator(mMovableObjectFactoryMap.begin(), + mMovableObjectFactoryMap.end()); + + } + //--------------------------------------------------------------------- + RenderQueueInvocationSequence* Root::createRenderQueueInvocationSequence( + const String& name) + { + RenderQueueInvocationSequenceMap::iterator i = + mRQSequenceMap.find(name); + if (i != mRQSequenceMap.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "RenderQueueInvocationSequence with the name " + name + + " already exists.", + "Root::createRenderQueueInvocationSequence"); + } + RenderQueueInvocationSequence* ret = OGRE_NEW RenderQueueInvocationSequence(name); + mRQSequenceMap[name] = ret; + return ret; + } + //--------------------------------------------------------------------- + RenderQueueInvocationSequence* Root::getRenderQueueInvocationSequence( + const String& name) + { + RenderQueueInvocationSequenceMap::iterator i = + mRQSequenceMap.find(name); + if (i == mRQSequenceMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "RenderQueueInvocationSequence with the name " + name + + " not found.", + "Root::getRenderQueueInvocationSequence"); + } + return i->second; + } + //--------------------------------------------------------------------- + void Root::destroyRenderQueueInvocationSequence( + const String& name) + { + RenderQueueInvocationSequenceMap::iterator i = + mRQSequenceMap.find(name); + if (i != mRQSequenceMap.end()) + { + OGRE_DELETE i->second; + mRQSequenceMap.erase(i); + } + } + //--------------------------------------------------------------------- + void Root::destroyAllRenderQueueInvocationSequences(void) + { + for (RenderQueueInvocationSequenceMap::iterator i = mRQSequenceMap.begin(); + i != mRQSequenceMap.end(); ++i) + { + OGRE_DELETE i->second; + } + mRQSequenceMap.clear(); + } + + //--------------------------------------------------------------------- + unsigned int Root::getDisplayMonitorCount() const + { + if (!mActiveRenderer) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Cannot get display monitor count " + "No render system has been selected.", "Root::getDisplayMonitorCount"); + } + + return mActiveRenderer->getDisplayMonitorCount(); + + } + //--------------------------------------------------------------------- + void Root::setWorkQueue(WorkQueue* queue) + { + if (mWorkQueue != queue) + { + // delete old one (will shut down) + OGRE_DELETE mWorkQueue; + + mWorkQueue = queue; + if (mIsInitialised) + mWorkQueue->startup(); + + } + } diff --git a/OgreMain/src/OgreRotationSpline.cpp b/OgreMain/src/OgreRotationSpline.cpp index 54fdab32cba..b0cdd691611 100644 --- a/OgreMain/src/OgreRotationSpline.cpp +++ b/OgreMain/src/OgreRotationSpline.cpp @@ -64,7 +64,7 @@ namespace Ogre { } //--------------------------------------------------------------------- Quaternion RotationalSpline::interpolate(unsigned int fromIndex, Real t, - bool useShortestPath) + bool useShortestPath) { // Bounds check assert (fromIndex < mPoints.size() && diff --git a/OgreMain/src/OgreSIMDHelper.h b/OgreMain/src/OgreSIMDHelper.h index 8a302940e2c..2305b50e744 100644 --- a/OgreMain/src/OgreSIMDHelper.h +++ b/OgreMain/src/OgreSIMDHelper.h @@ -86,12 +86,12 @@ THE SOFTWARE. namespace Ogre { - /** \addtogroup Core - * @{ - */ - /** \addtogroup Math - * @{ - */ + /** \addtogroup Core + * @{ + */ + /** \addtogroup Math + * @{ + */ #if __OGRE_HAVE_SSE @@ -307,8 +307,8 @@ namespace Ogre { #endif // __OGRE_HAVE_SSE - /** @} */ - /** @} */ + /** @} */ + /** @} */ } diff --git a/OgreMain/src/OgreSceneManager.cpp b/OgreMain/src/OgreSceneManager.cpp index 7f9c7ad9f26..20667d605e1 100644 --- a/OgreMain/src/OgreSceneManager.cpp +++ b/OgreMain/src/OgreSceneManager.cpp @@ -71,12 +71,12 @@ THE SOFTWARE. namespace Ogre { //----------------------------------------------------------------------- -uint32 SceneManager::WORLD_GEOMETRY_TYPE_MASK = 0x80000000; -uint32 SceneManager::ENTITY_TYPE_MASK = 0x40000000; -uint32 SceneManager::FX_TYPE_MASK = 0x20000000; +uint32 SceneManager::WORLD_GEOMETRY_TYPE_MASK = 0x80000000; +uint32 SceneManager::ENTITY_TYPE_MASK = 0x40000000; +uint32 SceneManager::FX_TYPE_MASK = 0x20000000; uint32 SceneManager::STATICGEOMETRY_TYPE_MASK = 0x10000000; -uint32 SceneManager::LIGHT_TYPE_MASK = 0x08000000; -uint32 SceneManager::FRUSTUM_TYPE_MASK = 0x04000000; +uint32 SceneManager::LIGHT_TYPE_MASK = 0x08000000; +uint32 SceneManager::FRUSTUM_TYPE_MASK = 0x04000000; uint32 SceneManager::USER_TYPE_MASK_LIMIT = SceneManager::FRUSTUM_TYPE_MASK; //----------------------------------------------------------------------- SceneManager::SceneManager(const String& name) : @@ -159,58 +159,58 @@ mGpuParamsDirty((uint16)GPV_ALL) mSkyDomeEntity[i] = 0; } - mShadowCasterQueryListener = OGRE_NEW ShadowCasterSceneQueryListener(this); + mShadowCasterQueryListener = OGRE_NEW ShadowCasterSceneQueryListener(this); Root *root = Root::getSingletonPtr(); if (root) _setDestinationRenderSystem(root->getRenderSystem()); - // Setup default queued renderable visitor - mActiveQueuedRenderableVisitor = &mDefaultQueuedRenderableVisitor; + // Setup default queued renderable visitor + mActiveQueuedRenderableVisitor = &mDefaultQueuedRenderableVisitor; - // set up default shadow camera setup - mDefaultShadowCameraSetup.bind(OGRE_NEW DefaultShadowCameraSetup()); + // set up default shadow camera setup + mDefaultShadowCameraSetup.bind(OGRE_NEW DefaultShadowCameraSetup()); - // init shadow texture config - setShadowTextureCount(1); + // init shadow texture config + setShadowTextureCount(1); - // init shadow texture count per type. - mShadowTextureCountPerType[Light::LT_POINT] = 1; - mShadowTextureCountPerType[Light::LT_DIRECTIONAL] = 1; - mShadowTextureCountPerType[Light::LT_SPOTLIGHT] = 1; + // init shadow texture count per type. + mShadowTextureCountPerType[Light::LT_POINT] = 1; + mShadowTextureCountPerType[Light::LT_DIRECTIONAL] = 1; + mShadowTextureCountPerType[Light::LT_SPOTLIGHT] = 1; - // create the auto param data source instance - mAutoParamDataSource = createAutoParamDataSource(); + // create the auto param data source instance + mAutoParamDataSource = createAutoParamDataSource(); } //----------------------------------------------------------------------- SceneManager::~SceneManager() { - fireSceneManagerDestroyed(); - destroyShadowTextures(); + fireSceneManagerDestroyed(); + destroyShadowTextures(); clearScene(); destroyAllCameras(); - // clear down movable object collection map - { + // clear down movable object collection map + { OGRE_LOCK_MUTEX(mMovableObjectCollectionMapMutex); - for (MovableObjectCollectionMap::iterator i = mMovableObjectCollectionMap.begin(); - i != mMovableObjectCollectionMap.end(); ++i) - { - OGRE_DELETE_T(i->second, MovableObjectCollection, MEMCATEGORY_SCENE_CONTROL); - } - mMovableObjectCollectionMap.clear(); - } + for (MovableObjectCollectionMap::iterator i = mMovableObjectCollectionMap.begin(); + i != mMovableObjectCollectionMap.end(); ++i) + { + OGRE_DELETE_T(i->second, MovableObjectCollection, MEMCATEGORY_SCENE_CONTROL); + } + mMovableObjectCollectionMap.clear(); + } - OGRE_DELETE mSkyBoxObj; + OGRE_DELETE mSkyBoxObj; - OGRE_DELETE mShadowCasterQueryListener; + OGRE_DELETE mShadowCasterQueryListener; OGRE_DELETE mSceneRoot; OGRE_DELETE mFullScreenQuad; OGRE_DELETE mShadowCasterSphereQuery; OGRE_DELETE mShadowCasterAABBQuery; OGRE_DELETE mRenderQueue; - OGRE_DELETE mAutoParamDataSource; + OGRE_DELETE mAutoParamDataSource; } //----------------------------------------------------------------------- RenderQueue* SceneManager::getRenderQueue(void) @@ -234,44 +234,44 @@ void SceneManager::initRenderQueue(void) //----------------------------------------------------------------------- void SceneManager::addSpecialCaseRenderQueue(uint8 qid) { - mSpecialCaseQueueList.insert(qid); + mSpecialCaseQueueList.insert(qid); } //----------------------------------------------------------------------- void SceneManager::removeSpecialCaseRenderQueue(uint8 qid) { - mSpecialCaseQueueList.erase(qid); + mSpecialCaseQueueList.erase(qid); } //----------------------------------------------------------------------- void SceneManager::clearSpecialCaseRenderQueues(void) { - mSpecialCaseQueueList.clear(); + mSpecialCaseQueueList.clear(); } //----------------------------------------------------------------------- void SceneManager::setSpecialCaseRenderQueueMode(SceneManager::SpecialCaseRenderQueueMode mode) { - mSpecialCaseQueueMode = mode; + mSpecialCaseQueueMode = mode; } //----------------------------------------------------------------------- SceneManager::SpecialCaseRenderQueueMode SceneManager::getSpecialCaseRenderQueueMode(void) { - return mSpecialCaseQueueMode; + return mSpecialCaseQueueMode; } //----------------------------------------------------------------------- bool SceneManager::isRenderQueueToBeProcessed(uint8 qid) { - bool inList = mSpecialCaseQueueList.find(qid) != mSpecialCaseQueueList.end(); - return (inList && mSpecialCaseQueueMode == SCRQM_INCLUDE) - || (!inList && mSpecialCaseQueueMode == SCRQM_EXCLUDE); + bool inList = mSpecialCaseQueueList.find(qid) != mSpecialCaseQueueList.end(); + return (inList && mSpecialCaseQueueMode == SCRQM_INCLUDE) + || (!inList && mSpecialCaseQueueMode == SCRQM_EXCLUDE); } //----------------------------------------------------------------------- void SceneManager::setWorldGeometryRenderQueue(uint8 qid) { - mWorldGeometryRenderQueue = qid; + mWorldGeometryRenderQueue = qid; } //----------------------------------------------------------------------- uint8 SceneManager::getWorldGeometryRenderQueue(void) { - return mWorldGeometryRenderQueue; + return mWorldGeometryRenderQueue; } //----------------------------------------------------------------------- Camera* SceneManager::createCamera(const String& name) @@ -288,8 +288,8 @@ Camera* SceneManager::createCamera(const String& name) Camera *c = OGRE_NEW Camera(name, this); mCameras.insert(CameraList::value_type(name, c)); - // create visible bounds aab map entry - mCamVisibleObjectsMap[c] = VisibleObjectsBoundsInfo(); + // create visible bounds aab map entry + mCamVisibleObjectsMap[c] = VisibleObjectsBoundsInfo(); return c; } @@ -312,7 +312,7 @@ Camera* SceneManager::getCamera(const String& name) const //----------------------------------------------------------------------- bool SceneManager::hasCamera(const String& name) const { - return (mCameras.find(name) != mCameras.end()); + return (mCameras.find(name) != mCameras.end()); } //----------------------------------------------------------------------- @@ -321,7 +321,7 @@ void SceneManager::destroyCamera(Camera *cam) if(!cam) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot destroy a null Camera.", "SceneManager::destroyCamera"); - destroyCamera(cam->getName()); + destroyCamera(cam->getName()); } //----------------------------------------------------------------------- @@ -331,17 +331,17 @@ void SceneManager::destroyCamera(const String& name) CameraList::iterator i = mCameras.find(name); if (i != mCameras.end()) { - // Remove visible boundary AAB entry - CamVisibleObjectsMap::iterator camVisObjIt = mCamVisibleObjectsMap.find( i->second ); - if ( camVisObjIt != mCamVisibleObjectsMap.end() ) - mCamVisibleObjectsMap.erase( camVisObjIt ); + // Remove visible boundary AAB entry + CamVisibleObjectsMap::iterator camVisObjIt = mCamVisibleObjectsMap.find( i->second ); + if ( camVisObjIt != mCamVisibleObjectsMap.end() ) + mCamVisibleObjectsMap.erase( camVisObjIt ); - // Remove light-shadow cam mapping entry - ShadowCamLightMapping::iterator camLightIt = mShadowCamLightMapping.find( i->second ); - if ( camLightIt != mShadowCamLightMapping.end() ) - mShadowCamLightMapping.erase( camLightIt ); + // Remove light-shadow cam mapping entry + ShadowCamLightMapping::iterator camLightIt = mShadowCamLightMapping.find( i->second ); + if ( camLightIt != mShadowCamLightMapping.end() ) + mShadowCamLightMapping.erase( camLightIt ); - // Notify render system + // Notify render system mDestRenderSystem->_notifyCameraRemoved(i->second); OGRE_DELETE i->second; mCameras.erase(i); @@ -352,68 +352,68 @@ void SceneManager::destroyCamera(const String& name) //----------------------------------------------------------------------- void SceneManager::destroyAllCameras(void) { - CameraList::iterator camIt = mCameras.begin(); - while( camIt != mCameras.end() ) - { - bool dontDelete = false; - // dont destroy shadow texture cameras here. destroyAllCameras is public - ShadowTextureCameraList::iterator camShadowTexIt = mShadowTextureCameras.begin( ); - for( ; camShadowTexIt != mShadowTextureCameras.end(); ++camShadowTexIt ) - { - if( (*camShadowTexIt) == camIt->second ) - { - dontDelete = true; - break; - } - } - - if( dontDelete ) // skip this camera - ++camIt; - else - { - destroyCamera(camIt->second); - camIt = mCameras.begin(); // recreate iterator - } - } + CameraList::iterator camIt = mCameras.begin(); + while( camIt != mCameras.end() ) + { + bool dontDelete = false; + // dont destroy shadow texture cameras here. destroyAllCameras is public + ShadowTextureCameraList::iterator camShadowTexIt = mShadowTextureCameras.begin( ); + for( ; camShadowTexIt != mShadowTextureCameras.end(); ++camShadowTexIt ) + { + if( (*camShadowTexIt) == camIt->second ) + { + dontDelete = true; + break; + } + } + + if( dontDelete ) // skip this camera + ++camIt; + else + { + destroyCamera(camIt->second); + camIt = mCameras.begin(); // recreate iterator + } + } } //----------------------------------------------------------------------- Light* SceneManager::createLight(const String& name) { - return static_cast( - createMovableObject(name, LightFactory::FACTORY_TYPE_NAME)); + return static_cast( + createMovableObject(name, LightFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- Light* SceneManager::createLight() { - String name = mMovableNameGenerator.generate(); - return createLight(name); + String name = mMovableNameGenerator.generate(); + return createLight(name); } //----------------------------------------------------------------------- Light* SceneManager::getLight(const String& name) const { - return static_cast( - getMovableObject(name, LightFactory::FACTORY_TYPE_NAME)); + return static_cast( + getMovableObject(name, LightFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- bool SceneManager::hasLight(const String& name) const { - return hasMovableObject(name, LightFactory::FACTORY_TYPE_NAME); + return hasMovableObject(name, LightFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyLight(Light *l) { - destroyMovableObject(l); + destroyMovableObject(l); } //----------------------------------------------------------------------- void SceneManager::destroyLight(const String& name) { - destroyMovableObject(name, LightFactory::FACTORY_TYPE_NAME); + destroyMovableObject(name, LightFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyAllLights(void) { - destroyAllMovableObjectsByType(LightFactory::FACTORY_TYPE_NAME); + destroyAllMovableObjectsByType(LightFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- const LightList& SceneManager::_getLightsAffectingFrustum(void) const @@ -427,7 +427,7 @@ bool SceneManager::lightLess::operator()(const Light* a, const Light* b) const } //----------------------------------------------------------------------- void SceneManager::_populateLightList(const Vector3& position, Real radius, - LightList& destList, uint32 lightMask) + LightList& destList, uint32 lightMask) { // Really basic trawl of the lights, then sort // Subclasses could do something smarter @@ -444,12 +444,12 @@ void SceneManager::_populateLightList(const Vector3& position, Real radius, for (it = candidateLights.begin(); it != candidateLights.end(); ++it) { Light* lt = *it; - // check whether or not this light is suppose to be taken into consideration for the current light mask set for this operation - if(!(lt->getLightMask() & lightMask)) - continue; //skip this light + // check whether or not this light is suppose to be taken into consideration for the current light mask set for this operation + if(!(lt->getLightMask() & lightMask)) + continue; //skip this light - // Calc squared distance - lt->_calcTempSquareDist(position); + // Calc squared distance + lt->_calcTempSquareDist(position); if (lt->getType() == Light::LT_DIRECTIONAL) { @@ -459,7 +459,7 @@ void SceneManager::_populateLightList(const Vector3& position, Real radius, else { // only add in-range lights - if (lt->isInLightRange(Sphere(position,radius))) + if (lt->isInLightRange(Sphere(position,radius))) { destList.push_back(lt); } @@ -467,30 +467,30 @@ void SceneManager::_populateLightList(const Vector3& position, Real radius, } // Sort (stable to guarantee ordering on directional lights) - if (isShadowTechniqueTextureBased()) - { - // Note that if we're using texture shadows, we actually want to use - // the first few lights unchanged from the frustum list, matching the - // texture shadows that were generated - // Thus we only allow object-relative sorting on the remainder of the list - if (destList.size() > getShadowTextureCount()) - { - LightList::iterator start = destList.begin(); - std::advance(start, getShadowTextureCount()); - std::stable_sort(start, destList.end(), lightLess()); - } - } - else - { - std::stable_sort(destList.begin(), destList.end(), lightLess()); - } - - // Now assign indexes in the list so they can be examined if needed - size_t lightIndex = 0; - for (LightList::iterator li = destList.begin(); li != destList.end(); ++li, ++lightIndex) - { - (*li)->_notifyIndexInFrame(lightIndex); - } + if (isShadowTechniqueTextureBased()) + { + // Note that if we're using texture shadows, we actually want to use + // the first few lights unchanged from the frustum list, matching the + // texture shadows that were generated + // Thus we only allow object-relative sorting on the remainder of the list + if (destList.size() > getShadowTextureCount()) + { + LightList::iterator start = destList.begin(); + std::advance(start, getShadowTextureCount()); + std::stable_sort(start, destList.end(), lightLess()); + } + } + else + { + std::stable_sort(destList.begin(), destList.end(), lightLess()); + } + + // Now assign indexes in the list so they can be examined if needed + size_t lightIndex = 0; + for (LightList::iterator li = destList.begin(); li != destList.end(); ++li, ++lightIndex) + { + (*li)->_notifyIndexInFrame(lightIndex); + } } @@ -506,10 +506,10 @@ Entity* SceneManager::createEntity(const String& entityName, PrefabType ptype) { case PT_PLANE: return createEntity(entityName, "Prefab_Plane"); - case PT_CUBE: - return createEntity(entityName, "Prefab_Cube"); - case PT_SPHERE: - return createEntity(entityName, "Prefab_Sphere"); + case PT_CUBE: + return createEntity(entityName, "Prefab_Cube"); + case PT_SPHERE: + return createEntity(entityName, "Prefab_Sphere"); break; } @@ -521,23 +521,23 @@ Entity* SceneManager::createEntity(const String& entityName, PrefabType ptype) //--------------------------------------------------------------------- Entity* SceneManager::createEntity(PrefabType ptype) { - String name = mMovableNameGenerator.generate(); - return createEntity(name, ptype); + String name = mMovableNameGenerator.generate(); + return createEntity(name, ptype); } //----------------------------------------------------------------------- Entity* SceneManager::createEntity( const String& entityName, const String& meshName, - const String& groupName /* = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME */) + const String& groupName /* = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME */) { - // delegate to factory implementation - NameValuePairList params; - params["mesh"] = meshName; - params["resourceGroup"] = groupName; - return static_cast( - createMovableObject(entityName, EntityFactory::FACTORY_TYPE_NAME, - ¶ms)); + // delegate to factory implementation + NameValuePairList params; + params["mesh"] = meshName; + params["resourceGroup"] = groupName; + return static_cast( + createMovableObject(entityName, EntityFactory::FACTORY_TYPE_NAME, + ¶ms)); } //--------------------------------------------------------------------- @@ -548,9 +548,9 @@ Entity* SceneManager::createEntity(const String& entityName, const MeshPtr& pMes //--------------------------------------------------------------------- Entity* SceneManager::createEntity(const String& meshName) { - String name = mMovableNameGenerator.generate(); - // note, we can't allow groupName to be passes, it would be ambiguous (2 string params) - return createEntity(name, meshName, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + String name = mMovableNameGenerator.generate(); + // note, we can't allow groupName to be passes, it would be ambiguous (2 string params) + return createEntity(name, meshName, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); } //--------------------------------------------------------------------- Entity* SceneManager::createEntity(const MeshPtr& pMesh) @@ -561,25 +561,25 @@ Entity* SceneManager::createEntity(const MeshPtr& pMesh) //----------------------------------------------------------------------- Entity* SceneManager::getEntity(const String& name) const { - return static_cast( - getMovableObject(name, EntityFactory::FACTORY_TYPE_NAME)); + return static_cast( + getMovableObject(name, EntityFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- bool SceneManager::hasEntity(const String& name) const { - return hasMovableObject(name, EntityFactory::FACTORY_TYPE_NAME); + return hasMovableObject(name, EntityFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyEntity(Entity *e) { - destroyMovableObject(e); + destroyMovableObject(e); } //----------------------------------------------------------------------- void SceneManager::destroyEntity(const String& name) { - destroyMovableObject(name, EntityFactory::FACTORY_TYPE_NAME); + destroyMovableObject(name, EntityFactory::FACTORY_TYPE_NAME); } @@ -587,224 +587,224 @@ void SceneManager::destroyEntity(const String& name) void SceneManager::destroyAllEntities(void) { - destroyAllMovableObjectsByType(EntityFactory::FACTORY_TYPE_NAME); + destroyAllMovableObjectsByType(EntityFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyAllBillboardSets(void) { - destroyAllMovableObjectsByType(BillboardSetFactory::FACTORY_TYPE_NAME); + destroyAllMovableObjectsByType(BillboardSetFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- ManualObject* SceneManager::createManualObject(const String& name) { - return static_cast( - createMovableObject(name, ManualObjectFactory::FACTORY_TYPE_NAME)); + return static_cast( + createMovableObject(name, ManualObjectFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- ManualObject* SceneManager::createManualObject() { - String name = mMovableNameGenerator.generate(); - return createManualObject(name); + String name = mMovableNameGenerator.generate(); + return createManualObject(name); } //----------------------------------------------------------------------- ManualObject* SceneManager::getManualObject(const String& name) const { - return static_cast( - getMovableObject(name, ManualObjectFactory::FACTORY_TYPE_NAME)); + return static_cast( + getMovableObject(name, ManualObjectFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- bool SceneManager::hasManualObject(const String& name) const { - return hasMovableObject(name, ManualObjectFactory::FACTORY_TYPE_NAME); + return hasMovableObject(name, ManualObjectFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyManualObject(ManualObject* obj) { - destroyMovableObject(obj); + destroyMovableObject(obj); } //----------------------------------------------------------------------- void SceneManager::destroyManualObject(const String& name) { - destroyMovableObject(name, ManualObjectFactory::FACTORY_TYPE_NAME); + destroyMovableObject(name, ManualObjectFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyAllManualObjects(void) { - destroyAllMovableObjectsByType(ManualObjectFactory::FACTORY_TYPE_NAME); + destroyAllMovableObjectsByType(ManualObjectFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- BillboardChain* SceneManager::createBillboardChain(const String& name) { - return static_cast( - createMovableObject(name, BillboardChainFactory::FACTORY_TYPE_NAME)); + return static_cast( + createMovableObject(name, BillboardChainFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- BillboardChain* SceneManager::createBillboardChain() { - String name = mMovableNameGenerator.generate(); - return createBillboardChain(name); + String name = mMovableNameGenerator.generate(); + return createBillboardChain(name); } //----------------------------------------------------------------------- BillboardChain* SceneManager::getBillboardChain(const String& name) const { - return static_cast( - getMovableObject(name, BillboardChainFactory::FACTORY_TYPE_NAME)); + return static_cast( + getMovableObject(name, BillboardChainFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- bool SceneManager::hasBillboardChain(const String& name) const { - return hasMovableObject(name, BillboardChainFactory::FACTORY_TYPE_NAME); + return hasMovableObject(name, BillboardChainFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyBillboardChain(BillboardChain* obj) { - destroyMovableObject(obj); + destroyMovableObject(obj); } //----------------------------------------------------------------------- void SceneManager::destroyBillboardChain(const String& name) { - destroyMovableObject(name, BillboardChainFactory::FACTORY_TYPE_NAME); + destroyMovableObject(name, BillboardChainFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyAllBillboardChains(void) { - destroyAllMovableObjectsByType(BillboardChainFactory::FACTORY_TYPE_NAME); + destroyAllMovableObjectsByType(BillboardChainFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- RibbonTrail* SceneManager::createRibbonTrail(const String& name) { - return static_cast( - createMovableObject(name, RibbonTrailFactory::FACTORY_TYPE_NAME)); + return static_cast( + createMovableObject(name, RibbonTrailFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- RibbonTrail* SceneManager::createRibbonTrail() { - String name = mMovableNameGenerator.generate(); - return createRibbonTrail(name); + String name = mMovableNameGenerator.generate(); + return createRibbonTrail(name); } //----------------------------------------------------------------------- RibbonTrail* SceneManager::getRibbonTrail(const String& name) const { - return static_cast( - getMovableObject(name, RibbonTrailFactory::FACTORY_TYPE_NAME)); + return static_cast( + getMovableObject(name, RibbonTrailFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- bool SceneManager::hasRibbonTrail(const String& name) const { - return hasMovableObject(name, RibbonTrailFactory::FACTORY_TYPE_NAME); + return hasMovableObject(name, RibbonTrailFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyRibbonTrail(RibbonTrail* obj) { - destroyMovableObject(obj); + destroyMovableObject(obj); } //----------------------------------------------------------------------- void SceneManager::destroyRibbonTrail(const String& name) { - destroyMovableObject(name, RibbonTrailFactory::FACTORY_TYPE_NAME); + destroyMovableObject(name, RibbonTrailFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyAllRibbonTrails(void) { - destroyAllMovableObjectsByType(RibbonTrailFactory::FACTORY_TYPE_NAME); + destroyAllMovableObjectsByType(RibbonTrailFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- ParticleSystem* SceneManager::createParticleSystem(const String& name, - const String& templateName) + const String& templateName) { - NameValuePairList params; - params["templateName"] = templateName; - - return static_cast( - createMovableObject(name, ParticleSystemFactory::FACTORY_TYPE_NAME, - ¶ms)); + NameValuePairList params; + params["templateName"] = templateName; + + return static_cast( + createMovableObject(name, ParticleSystemFactory::FACTORY_TYPE_NAME, + ¶ms)); } //----------------------------------------------------------------------- ParticleSystem* SceneManager::createParticleSystem(const String& name, - size_t quota, const String& group) + size_t quota, const String& group) { - NameValuePairList params; - params["quota"] = StringConverter::toString(quota); - params["resourceGroup"] = group; - - return static_cast( - createMovableObject(name, ParticleSystemFactory::FACTORY_TYPE_NAME, - ¶ms)); + NameValuePairList params; + params["quota"] = StringConverter::toString(quota); + params["resourceGroup"] = group; + + return static_cast( + createMovableObject(name, ParticleSystemFactory::FACTORY_TYPE_NAME, + ¶ms)); } //----------------------------------------------------------------------- ParticleSystem* SceneManager::createParticleSystem(size_t quota, const String& group) { - String name = mMovableNameGenerator.generate(); - return createParticleSystem(name, quota, group); + String name = mMovableNameGenerator.generate(); + return createParticleSystem(name, quota, group); } //----------------------------------------------------------------------- ParticleSystem* SceneManager::getParticleSystem(const String& name) const { - return static_cast( - getMovableObject(name, ParticleSystemFactory::FACTORY_TYPE_NAME)); + return static_cast( + getMovableObject(name, ParticleSystemFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- bool SceneManager::hasParticleSystem(const String& name) const { - return hasMovableObject(name, ParticleSystemFactory::FACTORY_TYPE_NAME); + return hasMovableObject(name, ParticleSystemFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyParticleSystem(ParticleSystem* obj) { - destroyMovableObject(obj); + destroyMovableObject(obj); } //----------------------------------------------------------------------- void SceneManager::destroyParticleSystem(const String& name) { - destroyMovableObject(name, ParticleSystemFactory::FACTORY_TYPE_NAME); + destroyMovableObject(name, ParticleSystemFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyAllParticleSystems(void) { - destroyAllMovableObjectsByType(ParticleSystemFactory::FACTORY_TYPE_NAME); + destroyAllMovableObjectsByType(ParticleSystemFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::clearScene(void) { - destroyAllStaticGeometry(); - destroyAllInstanceManagers(); - destroyAllMovableObjects(); + destroyAllStaticGeometry(); + destroyAllInstanceManagers(); + destroyAllMovableObjects(); - // Clear root node of all children - getRootSceneNode()->removeAllChildren(); - getRootSceneNode()->detachAllObjects(); + // Clear root node of all children + getRootSceneNode()->removeAllChildren(); + getRootSceneNode()->detachAllObjects(); - // Delete all SceneNodes, except root that is - for (SceneNodeList::iterator i = mSceneNodes.begin(); - i != mSceneNodes.end(); ++i) - { - OGRE_DELETE i->second; - } - mSceneNodes.clear(); - mAutoTrackingSceneNodes.clear(); + // Delete all SceneNodes, except root that is + for (SceneNodeList::iterator i = mSceneNodes.begin(); + i != mSceneNodes.end(); ++i) + { + OGRE_DELETE i->second; + } + mSceneNodes.clear(); + mAutoTrackingSceneNodes.clear(); - - // Clear animations + + // Clear animations destroyAllAnimations(); // Remove sky nodes since they've been deleted mSkyBoxNode = mSkyPlaneNode = mSkyDomeNode = 0; mSkyBoxEnabled = mSkyPlaneEnabled = mSkyDomeEnabled = false; - // Clear render queue, empty completely - if (mRenderQueue) - mRenderQueue->clear(true); + // Clear render queue, empty completely + if (mRenderQueue) + mRenderQueue->clear(true); } //----------------------------------------------------------------------- @@ -856,8 +856,8 @@ void SceneManager::destroySceneNode(const String& name) aiend = mAutoTrackingSceneNodes.end(); for (ai = mAutoTrackingSceneNodes.begin(); ai != aiend; ) { - // Pre-increment incase we delete - AutoTrackingSceneNodes::iterator curri = ai++; + // Pre-increment incase we delete + AutoTrackingSceneNodes::iterator curri = ai++; SceneNode* n = *curri; // Tracking this node if (n->getAutoTrackTarget() == i->second) @@ -872,13 +872,13 @@ void SceneManager::destroySceneNode(const String& name) } } - // detach from parent (don't do this in destructor since bulk destruction - // behaves differently) - Node* parentNode = i->second->getParent(); - if (parentNode) - { - parentNode->removeChild(i->second); - } + // detach from parent (don't do this in destructor since bulk destruction + // behaves differently) + Node* parentNode = i->second->getParent(); + if (parentNode) + { + parentNode->removeChild(i->second); + } OGRE_DELETE i->second; mSceneNodes.erase(i); } @@ -888,17 +888,17 @@ void SceneManager::destroySceneNode(SceneNode* sn) if(!sn) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot destroy a null SceneNode.", "SceneManager::destroySceneNode"); - destroySceneNode(sn->getName()); + destroySceneNode(sn->getName()); } //----------------------------------------------------------------------- SceneNode* SceneManager::getRootSceneNode(void) { - if (!mSceneRoot) - { - // Create root scene node - mSceneRoot = createSceneNodeImpl("Ogre/SceneRoot"); - mSceneRoot->_notifyRootNode(); - } + if (!mSceneRoot) + { + // Create root scene node + mSceneRoot = createSceneNodeImpl("Ogre/SceneRoot"); + mSceneRoot->_notifyRootNode(); + } return mSceneRoot; } @@ -919,458 +919,458 @@ SceneNode* SceneManager::getSceneNode(const String& name) const //----------------------------------------------------------------------- bool SceneManager::hasSceneNode(const String& name) const { - return (mSceneNodes.find(name) != mSceneNodes.end()); + return (mSceneNodes.find(name) != mSceneNodes.end()); } //----------------------------------------------------------------------- const Pass* SceneManager::_setPass(const Pass* pass, bool evenIfSuppressed, - bool shadowDerivation) -{ - //If using late material resolving, swap now. - if (isLateMaterialResolving()) - { - Technique* lateTech = pass->getParent()->getParent()->getBestTechnique(); - if (lateTech->getNumPasses() > pass->getIndex()) - { - pass = lateTech->getPass(pass->getIndex()); - } - else + bool shadowDerivation) +{ + //If using late material resolving, swap now. + if (isLateMaterialResolving()) + { + Technique* lateTech = pass->getParent()->getParent()->getBestTechnique(); + if (lateTech->getNumPasses() > pass->getIndex()) + { + pass = lateTech->getPass(pass->getIndex()); + } + else { pass = lateTech->getPass(0); } - //Should we warn or throw an exception if an illegal state was achieved? - } - - if (!mSuppressRenderStateChanges || evenIfSuppressed) - { - if (mIlluminationStage == IRS_RENDER_TO_TEXTURE && shadowDerivation) - { - // Derive a special shadow caster pass from this one - pass = deriveShadowCasterPass(pass); - } - else if (mIlluminationStage == IRS_RENDER_RECEIVER_PASS && shadowDerivation) - { - pass = deriveShadowReceiverPass(pass); - } + //Should we warn or throw an exception if an illegal state was achieved? + } + + if (!mSuppressRenderStateChanges || evenIfSuppressed) + { + if (mIlluminationStage == IRS_RENDER_TO_TEXTURE && shadowDerivation) + { + // Derive a special shadow caster pass from this one + pass = deriveShadowCasterPass(pass); + } + else if (mIlluminationStage == IRS_RENDER_RECEIVER_PASS && shadowDerivation) + { + pass = deriveShadowReceiverPass(pass); + } // Tell params about current pass mAutoParamDataSource->setCurrentPass(pass); - bool passSurfaceAndLightParams = true; - bool passFogParams = true; - - if (pass->hasVertexProgram()) - { - bindGpuProgram(pass->getVertexProgram()->_getBindingDelegate()); - // bind parameters later - // does the vertex program want surface and light params passed to rendersystem? - passSurfaceAndLightParams = pass->getVertexProgram()->getPassSurfaceAndLightStates(); - } - else - { - // Unbind program? - if (mDestRenderSystem->isGpuProgramBound(GPT_VERTEX_PROGRAM)) - { - mDestRenderSystem->unbindGpuProgram(GPT_VERTEX_PROGRAM); - } - // Set fixed-function vertex parameters - } - - if (pass->hasGeometryProgram()) - { - bindGpuProgram(pass->getGeometryProgram()->_getBindingDelegate()); - // bind parameters later - } - else - { - // Unbind program? - if (mDestRenderSystem->isGpuProgramBound(GPT_GEOMETRY_PROGRAM)) - { - mDestRenderSystem->unbindGpuProgram(GPT_GEOMETRY_PROGRAM); - } - // Set fixed-function vertex parameters - } - if (pass->hasTessellationHullProgram()) - { - bindGpuProgram(pass->getTessellationHullProgram()->_getBindingDelegate()); - // bind parameters later - } - else - { - // Unbind program? - if (mDestRenderSystem->isGpuProgramBound(GPT_HULL_PROGRAM)) - { - mDestRenderSystem->unbindGpuProgram(GPT_HULL_PROGRAM); - } - // Set fixed-function tessellation control parameters - } - - if (pass->hasTessellationDomainProgram()) - { - bindGpuProgram(pass->getTessellationDomainProgram()->_getBindingDelegate()); - // bind parameters later - } - else - { - // Unbind program? - if (mDestRenderSystem->isGpuProgramBound(GPT_DOMAIN_PROGRAM)) - { - mDestRenderSystem->unbindGpuProgram(GPT_DOMAIN_PROGRAM); - } - // Set fixed-function tessellation evaluation parameters - } + bool passSurfaceAndLightParams = true; + bool passFogParams = true; + + if (pass->hasVertexProgram()) + { + bindGpuProgram(pass->getVertexProgram()->_getBindingDelegate()); + // bind parameters later + // does the vertex program want surface and light params passed to rendersystem? + passSurfaceAndLightParams = pass->getVertexProgram()->getPassSurfaceAndLightStates(); + } + else + { + // Unbind program? + if (mDestRenderSystem->isGpuProgramBound(GPT_VERTEX_PROGRAM)) + { + mDestRenderSystem->unbindGpuProgram(GPT_VERTEX_PROGRAM); + } + // Set fixed-function vertex parameters + } + + if (pass->hasGeometryProgram()) + { + bindGpuProgram(pass->getGeometryProgram()->_getBindingDelegate()); + // bind parameters later + } + else + { + // Unbind program? + if (mDestRenderSystem->isGpuProgramBound(GPT_GEOMETRY_PROGRAM)) + { + mDestRenderSystem->unbindGpuProgram(GPT_GEOMETRY_PROGRAM); + } + // Set fixed-function vertex parameters + } + if (pass->hasTessellationHullProgram()) + { + bindGpuProgram(pass->getTessellationHullProgram()->_getBindingDelegate()); + // bind parameters later + } + else + { + // Unbind program? + if (mDestRenderSystem->isGpuProgramBound(GPT_HULL_PROGRAM)) + { + mDestRenderSystem->unbindGpuProgram(GPT_HULL_PROGRAM); + } + // Set fixed-function tessellation control parameters + } + + if (pass->hasTessellationDomainProgram()) + { + bindGpuProgram(pass->getTessellationDomainProgram()->_getBindingDelegate()); + // bind parameters later + } + else + { + // Unbind program? + if (mDestRenderSystem->isGpuProgramBound(GPT_DOMAIN_PROGRAM)) + { + mDestRenderSystem->unbindGpuProgram(GPT_DOMAIN_PROGRAM); + } + // Set fixed-function tessellation evaluation parameters + } if (pass->hasComputeProgram()) - { + { bindGpuProgram(pass->getComputeProgram()->_getBindingDelegate()); // bind parameters later - } - else - { + } + else + { // Unbind program? if (mDestRenderSystem->isGpuProgramBound(GPT_COMPUTE_PROGRAM)) { mDestRenderSystem->unbindGpuProgram(GPT_COMPUTE_PROGRAM); } // Set fixed-function compute parameters - } - - if (passSurfaceAndLightParams) - { - // Set surface reflectance properties, only valid if lighting is enabled - if (pass->getLightingEnabled()) - { - mDestRenderSystem->_setSurfaceParams( - pass->getAmbient(), - pass->getDiffuse(), - pass->getSpecular(), - pass->getSelfIllumination(), - pass->getShininess(), - pass->getVertexColourTracking() ); - } - - // Dynamic lighting enabled? - mDestRenderSystem->setLightingEnabled(pass->getLightingEnabled()); - } - - // Using a fragment program? - if (pass->hasFragmentProgram()) - { - bindGpuProgram(pass->getFragmentProgram()->_getBindingDelegate()); - // bind parameters later - passFogParams = pass->getFragmentProgram()->getPassFogStates(); - } - else - { - // Unbind program? - if (mDestRenderSystem->isGpuProgramBound(GPT_FRAGMENT_PROGRAM)) - { - mDestRenderSystem->unbindGpuProgram(GPT_FRAGMENT_PROGRAM); - } - - // Set fixed-function fragment settings - } - - if (passFogParams) - { - // New fog params can either be from scene or from material - FogMode newFogMode; - ColourValue newFogColour; - Real newFogStart, newFogEnd, newFogDensity; - if (pass->getFogOverride()) - { - // New fog params from material - newFogMode = pass->getFogMode(); - newFogColour = pass->getFogColour(); - newFogStart = pass->getFogStart(); - newFogEnd = pass->getFogEnd(); - newFogDensity = pass->getFogDensity(); - } - else - { - // New fog params from scene - newFogMode = mFogMode; - newFogColour = mFogColour; - newFogStart = mFogStart; - newFogEnd = mFogEnd; - newFogDensity = mFogDensity; - } - - /* In D3D, it applies to shaders prior - to version vs_3_0 and ps_3_0. And in OGL, it applies to "ARB_fog_XXX" in - fragment program, and in other ways, them maybe access by gpu program via - "state.fog.XXX". - */ - mDestRenderSystem->_setFog( - newFogMode, newFogColour, newFogDensity, newFogStart, newFogEnd); - } + } + + if (passSurfaceAndLightParams) + { + // Set surface reflectance properties, only valid if lighting is enabled + if (pass->getLightingEnabled()) + { + mDestRenderSystem->_setSurfaceParams( + pass->getAmbient(), + pass->getDiffuse(), + pass->getSpecular(), + pass->getSelfIllumination(), + pass->getShininess(), + pass->getVertexColourTracking() ); + } + + // Dynamic lighting enabled? + mDestRenderSystem->setLightingEnabled(pass->getLightingEnabled()); + } + + // Using a fragment program? + if (pass->hasFragmentProgram()) + { + bindGpuProgram(pass->getFragmentProgram()->_getBindingDelegate()); + // bind parameters later + passFogParams = pass->getFragmentProgram()->getPassFogStates(); + } + else + { + // Unbind program? + if (mDestRenderSystem->isGpuProgramBound(GPT_FRAGMENT_PROGRAM)) + { + mDestRenderSystem->unbindGpuProgram(GPT_FRAGMENT_PROGRAM); + } + + // Set fixed-function fragment settings + } + + if (passFogParams) + { + // New fog params can either be from scene or from material + FogMode newFogMode; + ColourValue newFogColour; + Real newFogStart, newFogEnd, newFogDensity; + if (pass->getFogOverride()) + { + // New fog params from material + newFogMode = pass->getFogMode(); + newFogColour = pass->getFogColour(); + newFogStart = pass->getFogStart(); + newFogEnd = pass->getFogEnd(); + newFogDensity = pass->getFogDensity(); + } + else + { + // New fog params from scene + newFogMode = mFogMode; + newFogColour = mFogColour; + newFogStart = mFogStart; + newFogEnd = mFogEnd; + newFogDensity = mFogDensity; + } + + /* In D3D, it applies to shaders prior + to version vs_3_0 and ps_3_0. And in OGL, it applies to "ARB_fog_XXX" in + fragment program, and in other ways, them maybe access by gpu program via + "state.fog.XXX". + */ + mDestRenderSystem->_setFog( + newFogMode, newFogColour, newFogDensity, newFogStart, newFogEnd); + } // Tell params about ORIGINAL fog - // Need to be able to override fixed function fog, but still have - // original fog parameters available to a shader than chooses to use + // Need to be able to override fixed function fog, but still have + // original fog parameters available to a shader than chooses to use mAutoParamDataSource->setFog( mFogMode, mFogColour, mFogDensity, mFogStart, mFogEnd); - // The rest of the settings are the same no matter whether we use programs or not - - // Set scene blending - if ( pass->hasSeparateSceneBlending( ) ) - { - mDestRenderSystem->_setSeparateSceneBlending( - pass->getSourceBlendFactor(), pass->getDestBlendFactor(), - pass->getSourceBlendFactorAlpha(), pass->getDestBlendFactorAlpha(), - pass->getSceneBlendingOperation(), - pass->hasSeparateSceneBlendingOperations() ? pass->getSceneBlendingOperation() : pass->getSceneBlendingOperationAlpha() ); - } - else - { - if(pass->hasSeparateSceneBlendingOperations( ) ) - { - mDestRenderSystem->_setSeparateSceneBlending( - pass->getSourceBlendFactor(), pass->getDestBlendFactor(), - pass->getSourceBlendFactor(), pass->getDestBlendFactor(), - pass->getSceneBlendingOperation(), pass->getSceneBlendingOperationAlpha() ); - } - else - { - mDestRenderSystem->_setSceneBlending( - pass->getSourceBlendFactor(), pass->getDestBlendFactor(), pass->getSceneBlendingOperation() ); - } - } - - // Set point parameters - mDestRenderSystem->_setPointParameters( - pass->getPointSize(), - pass->isPointAttenuationEnabled(), - pass->getPointAttenuationConstant(), - pass->getPointAttenuationLinear(), - pass->getPointAttenuationQuadratic(), - pass->getPointMinSize(), - pass->getPointMaxSize()); - - if (mDestRenderSystem->getCapabilities()->hasCapability(RSC_POINT_SPRITES)) - mDestRenderSystem->_setPointSpritesEnabled(pass->getPointSpritesEnabled()); - - // Texture unit settings - - Pass::ConstTextureUnitStateIterator texIter = pass->getTextureUnitStateIterator(); - size_t unit = 0; - // Reset the shadow texture index for each pass - size_t startLightIndex = pass->getStartLight(); - size_t shadowTexUnitIndex = 0; - size_t shadowTexIndex = mShadowTextures.size(); - if (mShadowTextureIndexLightList.size() > startLightIndex) - shadowTexIndex = mShadowTextureIndexLightList[startLightIndex]; - while(texIter.hasMoreElements()) - { - TextureUnitState* pTex = texIter.getNext(); - if (!pass->getIteratePerLight() && - isShadowTechniqueTextureBased() && - pTex->getContentType() == TextureUnitState::CONTENT_SHADOW) - { - // Need to bind the correct shadow texture, based on the start light - // Even though the light list can change per object, our restrictions - // say that when texture shadows are enabled, the lights up to the - // number of texture shadows will be fixed for all objects - // to match the shadow textures that have been generated - // see Listener::sortLightsAffectingFrustum and - // MovableObject::Listener::objectQueryLights - // Note that light iteration throws the indexes out so we don't bind here - // if that's the case, we have to bind when lights are iterated - // in renderSingleObject - - TexturePtr shadowTex; - if (shadowTexIndex < mShadowTextures.size()) - { - shadowTex = getShadowTexture(shadowTexIndex); - // Hook up projection frustum - Camera *cam = shadowTex->getBuffer()->getRenderTarget()->getViewport(0)->getCamera(); - // Enable projective texturing if fixed-function, but also need to - // disable it explicitly for program pipeline. - pTex->setProjectiveTexturing(!pass->hasVertexProgram(), cam); - mAutoParamDataSource->setTextureProjector(cam, shadowTexUnitIndex); - } - else - { - // Use fallback 'null' shadow texture - // no projection since all uniform colour anyway - shadowTex = mNullShadowTexture; - pTex->setProjectiveTexturing(false); - mAutoParamDataSource->setTextureProjector(0, shadowTexUnitIndex); - - } - pTex->_setTexturePtr(shadowTex); - - ++shadowTexIndex; - ++shadowTexUnitIndex; - } - else if (mIlluminationStage == IRS_NONE && pass->hasVertexProgram()) - { - // Manually set texture projector for shaders if present - // This won't get set any other way if using manual projection - TextureUnitState::EffectMap::const_iterator effi = - pTex->getEffects().find(TextureUnitState::ET_PROJECTIVE_TEXTURE); - if (effi != pTex->getEffects().end()) - { - mAutoParamDataSource->setTextureProjector(effi->second.frustum, unit); - } - } - if (pTex->getContentType() == TextureUnitState::CONTENT_COMPOSITOR) - { - CompositorChain* currentChain = _getActiveCompositorChain(); - if (!currentChain) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "A pass that wishes to reference a compositor texture " - "attempted to render in a pipeline without a compositor", - "SceneManager::_setPass"); - } - CompositorInstance* refComp = currentChain->getCompositor(pTex->getReferencedCompositorName()); - if (refComp == 0) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Invalid compositor content_type compositor name", - "SceneManager::_setPass"); - } - Ogre::TexturePtr refTex = refComp->getTextureInstance( - pTex->getReferencedTextureName(), pTex->getReferencedMRTIndex()); - if (refTex.isNull()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Invalid compositor content_type texture name", - "SceneManager::_setPass"); - } - pTex->_setTexturePtr(refTex); - } - mDestRenderSystem->_setTextureUnitSettings(unit, *pTex); - ++unit; - } - // Disable remaining texture units - mDestRenderSystem->_disableTextureUnitsFrom(pass->getNumTextureUnitStates()); - - // Set up non-texture related material settings - // Depth buffer settings - mDestRenderSystem->_setDepthBufferFunction(pass->getDepthFunction()); - mDestRenderSystem->_setDepthBufferCheckEnabled(pass->getDepthCheckEnabled()); - mDestRenderSystem->_setDepthBufferWriteEnabled(pass->getDepthWriteEnabled()); - mDestRenderSystem->_setDepthBias(pass->getDepthBiasConstant(), - pass->getDepthBiasSlopeScale()); - // Alpha-reject settings - mDestRenderSystem->_setAlphaRejectSettings( - pass->getAlphaRejectFunction(), pass->getAlphaRejectValue(), pass->isAlphaToCoverageEnabled()); - // Set colour write mode - // Right now we only use on/off, not per-channel - bool colWrite = pass->getColourWriteEnabled(); - mDestRenderSystem->_setColourBufferWriteEnabled(colWrite, colWrite, colWrite, colWrite); - // Culling mode - if (isShadowTechniqueTextureBased() - && mIlluminationStage == IRS_RENDER_TO_TEXTURE - && mShadowCasterRenderBackFaces - && pass->getCullingMode() == CULL_CLOCKWISE) - { - // render back faces into shadow caster, can help with depth comparison - mPassCullingMode = CULL_ANTICLOCKWISE; - } - else - { - mPassCullingMode = pass->getCullingMode(); - } - mDestRenderSystem->_setCullingMode(mPassCullingMode); - - // Shading - mDestRenderSystem->setShadingType(pass->getShadingMode()); - // Polygon mode - mDestRenderSystem->_setPolygonMode(pass->getPolygonMode()); - - // set pass number - mAutoParamDataSource->setPassNumber( pass->getIndex() ); - - // mark global params as dirty - mGpuParamsDirty |= (uint16)GPV_GLOBAL; - - } + // The rest of the settings are the same no matter whether we use programs or not + + // Set scene blending + if ( pass->hasSeparateSceneBlending( ) ) + { + mDestRenderSystem->_setSeparateSceneBlending( + pass->getSourceBlendFactor(), pass->getDestBlendFactor(), + pass->getSourceBlendFactorAlpha(), pass->getDestBlendFactorAlpha(), + pass->getSceneBlendingOperation(), + pass->hasSeparateSceneBlendingOperations() ? pass->getSceneBlendingOperation() : pass->getSceneBlendingOperationAlpha() ); + } + else + { + if(pass->hasSeparateSceneBlendingOperations( ) ) + { + mDestRenderSystem->_setSeparateSceneBlending( + pass->getSourceBlendFactor(), pass->getDestBlendFactor(), + pass->getSourceBlendFactor(), pass->getDestBlendFactor(), + pass->getSceneBlendingOperation(), pass->getSceneBlendingOperationAlpha() ); + } + else + { + mDestRenderSystem->_setSceneBlending( + pass->getSourceBlendFactor(), pass->getDestBlendFactor(), pass->getSceneBlendingOperation() ); + } + } + + // Set point parameters + mDestRenderSystem->_setPointParameters( + pass->getPointSize(), + pass->isPointAttenuationEnabled(), + pass->getPointAttenuationConstant(), + pass->getPointAttenuationLinear(), + pass->getPointAttenuationQuadratic(), + pass->getPointMinSize(), + pass->getPointMaxSize()); + + if (mDestRenderSystem->getCapabilities()->hasCapability(RSC_POINT_SPRITES)) + mDestRenderSystem->_setPointSpritesEnabled(pass->getPointSpritesEnabled()); + + // Texture unit settings + + Pass::ConstTextureUnitStateIterator texIter = pass->getTextureUnitStateIterator(); + size_t unit = 0; + // Reset the shadow texture index for each pass + size_t startLightIndex = pass->getStartLight(); + size_t shadowTexUnitIndex = 0; + size_t shadowTexIndex = mShadowTextures.size(); + if (mShadowTextureIndexLightList.size() > startLightIndex) + shadowTexIndex = mShadowTextureIndexLightList[startLightIndex]; + while(texIter.hasMoreElements()) + { + TextureUnitState* pTex = texIter.getNext(); + if (!pass->getIteratePerLight() && + isShadowTechniqueTextureBased() && + pTex->getContentType() == TextureUnitState::CONTENT_SHADOW) + { + // Need to bind the correct shadow texture, based on the start light + // Even though the light list can change per object, our restrictions + // say that when texture shadows are enabled, the lights up to the + // number of texture shadows will be fixed for all objects + // to match the shadow textures that have been generated + // see Listener::sortLightsAffectingFrustum and + // MovableObject::Listener::objectQueryLights + // Note that light iteration throws the indexes out so we don't bind here + // if that's the case, we have to bind when lights are iterated + // in renderSingleObject + + TexturePtr shadowTex; + if (shadowTexIndex < mShadowTextures.size()) + { + shadowTex = getShadowTexture(shadowTexIndex); + // Hook up projection frustum + Camera *cam = shadowTex->getBuffer()->getRenderTarget()->getViewport(0)->getCamera(); + // Enable projective texturing if fixed-function, but also need to + // disable it explicitly for program pipeline. + pTex->setProjectiveTexturing(!pass->hasVertexProgram(), cam); + mAutoParamDataSource->setTextureProjector(cam, shadowTexUnitIndex); + } + else + { + // Use fallback 'null' shadow texture + // no projection since all uniform colour anyway + shadowTex = mNullShadowTexture; + pTex->setProjectiveTexturing(false); + mAutoParamDataSource->setTextureProjector(0, shadowTexUnitIndex); + + } + pTex->_setTexturePtr(shadowTex); + + ++shadowTexIndex; + ++shadowTexUnitIndex; + } + else if (mIlluminationStage == IRS_NONE && pass->hasVertexProgram()) + { + // Manually set texture projector for shaders if present + // This won't get set any other way if using manual projection + TextureUnitState::EffectMap::const_iterator effi = + pTex->getEffects().find(TextureUnitState::ET_PROJECTIVE_TEXTURE); + if (effi != pTex->getEffects().end()) + { + mAutoParamDataSource->setTextureProjector(effi->second.frustum, unit); + } + } + if (pTex->getContentType() == TextureUnitState::CONTENT_COMPOSITOR) + { + CompositorChain* currentChain = _getActiveCompositorChain(); + if (!currentChain) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "A pass that wishes to reference a compositor texture " + "attempted to render in a pipeline without a compositor", + "SceneManager::_setPass"); + } + CompositorInstance* refComp = currentChain->getCompositor(pTex->getReferencedCompositorName()); + if (refComp == 0) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Invalid compositor content_type compositor name", + "SceneManager::_setPass"); + } + Ogre::TexturePtr refTex = refComp->getTextureInstance( + pTex->getReferencedTextureName(), pTex->getReferencedMRTIndex()); + if (refTex.isNull()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Invalid compositor content_type texture name", + "SceneManager::_setPass"); + } + pTex->_setTexturePtr(refTex); + } + mDestRenderSystem->_setTextureUnitSettings(unit, *pTex); + ++unit; + } + // Disable remaining texture units + mDestRenderSystem->_disableTextureUnitsFrom(pass->getNumTextureUnitStates()); + + // Set up non-texture related material settings + // Depth buffer settings + mDestRenderSystem->_setDepthBufferFunction(pass->getDepthFunction()); + mDestRenderSystem->_setDepthBufferCheckEnabled(pass->getDepthCheckEnabled()); + mDestRenderSystem->_setDepthBufferWriteEnabled(pass->getDepthWriteEnabled()); + mDestRenderSystem->_setDepthBias(pass->getDepthBiasConstant(), + pass->getDepthBiasSlopeScale()); + // Alpha-reject settings + mDestRenderSystem->_setAlphaRejectSettings( + pass->getAlphaRejectFunction(), pass->getAlphaRejectValue(), pass->isAlphaToCoverageEnabled()); + // Set colour write mode + // Right now we only use on/off, not per-channel + bool colWrite = pass->getColourWriteEnabled(); + mDestRenderSystem->_setColourBufferWriteEnabled(colWrite, colWrite, colWrite, colWrite); + // Culling mode + if (isShadowTechniqueTextureBased() + && mIlluminationStage == IRS_RENDER_TO_TEXTURE + && mShadowCasterRenderBackFaces + && pass->getCullingMode() == CULL_CLOCKWISE) + { + // render back faces into shadow caster, can help with depth comparison + mPassCullingMode = CULL_ANTICLOCKWISE; + } + else + { + mPassCullingMode = pass->getCullingMode(); + } + mDestRenderSystem->_setCullingMode(mPassCullingMode); + + // Shading + mDestRenderSystem->setShadingType(pass->getShadingMode()); + // Polygon mode + mDestRenderSystem->_setPolygonMode(pass->getPolygonMode()); + + // set pass number + mAutoParamDataSource->setPassNumber( pass->getIndex() ); + + // mark global params as dirty + mGpuParamsDirty |= (uint16)GPV_GLOBAL; + + } return pass; } //----------------------------------------------------------------------- void SceneManager::prepareRenderQueue(void) { - RenderQueue* q = getRenderQueue(); - // Clear the render queue - q->clear(Root::getSingleton().getRemoveRenderQueueStructuresOnClear()); - - // Prep the ordering options - - // If we're using a custom render squence, define based on that - RenderQueueInvocationSequence* seq = - mCurrentViewport->_getRenderQueueInvocationSequence(); - if (seq) - { - // Iterate once to crate / reset all - RenderQueueInvocationIterator invokeIt = seq->iterator(); - while (invokeIt.hasMoreElements()) - { - RenderQueueInvocation* invocation = invokeIt.getNext(); - RenderQueueGroup* group = - q->getQueueGroup(invocation->getRenderQueueGroupID()); - group->resetOrganisationModes(); - } - // Iterate again to build up options (may be more than one) - invokeIt = seq->iterator(); - while (invokeIt.hasMoreElements()) - { - RenderQueueInvocation* invocation = invokeIt.getNext(); - RenderQueueGroup* group = - q->getQueueGroup(invocation->getRenderQueueGroupID()); - group->addOrganisationMode(invocation->getSolidsOrganisation()); - // also set splitting options - updateRenderQueueGroupSplitOptions(group, invocation->getSuppressShadows(), - invocation->getSuppressRenderStateChanges()); - } - - mLastRenderQueueInvocationCustom = true; - } - else - { - if (mLastRenderQueueInvocationCustom) - { - // We need this here to reset if coming out of a render queue sequence, - // but doing it resets any specialised settings set globally per render queue - // so only do it when necessary - it's nice to allow people to set the organisation - // mode manually for example - - // Default all the queue groups that are there, new ones will be created - // with defaults too - RenderQueue::QueueGroupIterator groupIter = q->_getQueueGroupIterator(); - while (groupIter.hasMoreElements()) - { - RenderQueueGroup* g = groupIter.getNext(); - g->defaultOrganisationMode(); - } - } - - // Global split options - updateRenderQueueSplitOptions(); - - mLastRenderQueueInvocationCustom = false; - } + RenderQueue* q = getRenderQueue(); + // Clear the render queue + q->clear(Root::getSingleton().getRemoveRenderQueueStructuresOnClear()); + + // Prep the ordering options + + // If we're using a custom render squence, define based on that + RenderQueueInvocationSequence* seq = + mCurrentViewport->_getRenderQueueInvocationSequence(); + if (seq) + { + // Iterate once to crate / reset all + RenderQueueInvocationIterator invokeIt = seq->iterator(); + while (invokeIt.hasMoreElements()) + { + RenderQueueInvocation* invocation = invokeIt.getNext(); + RenderQueueGroup* group = + q->getQueueGroup(invocation->getRenderQueueGroupID()); + group->resetOrganisationModes(); + } + // Iterate again to build up options (may be more than one) + invokeIt = seq->iterator(); + while (invokeIt.hasMoreElements()) + { + RenderQueueInvocation* invocation = invokeIt.getNext(); + RenderQueueGroup* group = + q->getQueueGroup(invocation->getRenderQueueGroupID()); + group->addOrganisationMode(invocation->getSolidsOrganisation()); + // also set splitting options + updateRenderQueueGroupSplitOptions(group, invocation->getSuppressShadows(), + invocation->getSuppressRenderStateChanges()); + } + + mLastRenderQueueInvocationCustom = true; + } + else + { + if (mLastRenderQueueInvocationCustom) + { + // We need this here to reset if coming out of a render queue sequence, + // but doing it resets any specialised settings set globally per render queue + // so only do it when necessary - it's nice to allow people to set the organisation + // mode manually for example + + // Default all the queue groups that are there, new ones will be created + // with defaults too + RenderQueue::QueueGroupIterator groupIter = q->_getQueueGroupIterator(); + while (groupIter.hasMoreElements()) + { + RenderQueueGroup* g = groupIter.getNext(); + g->defaultOrganisationMode(); + } + } + + // Global split options + updateRenderQueueSplitOptions(); + + mLastRenderQueueInvocationCustom = false; + } } //----------------------------------------------------------------------- void SceneManager::_renderScene(Camera* camera, Viewport* vp, bool includeOverlays) { - OgreProfileGroup("_renderScene", OGREPROF_GENERAL); + OgreProfileGroup("_renderScene", OGREPROF_GENERAL); Root::getSingleton()._pushCurrentSceneManager(this); - mActiveQueuedRenderableVisitor->targetSceneMgr = this; - mAutoParamDataSource->setCurrentSceneManager(this); + mActiveQueuedRenderableVisitor->targetSceneMgr = this; + mAutoParamDataSource->setCurrentSceneManager(this); - // Also set the internal viewport pointer at this point, for calls that need it - // However don't call setViewport just yet (see below) - mCurrentViewport = vp; + // Also set the internal viewport pointer at this point, for calls that need it + // However don't call setViewport just yet (see below) + mCurrentViewport = vp; - // reset light hash so even if light list is the same, we refresh the content every frame - LightList emptyLightList; - useLights(emptyLightList, 0); + // reset light hash so even if light list is the same, we refresh the content every frame + LightList emptyLightList; + useLights(emptyLightList, 0); if (isShadowTechniqueInUse()) { @@ -1403,170 +1403,170 @@ void SceneManager::_renderScene(Camera* camera, Viewport* vp, bool includeOverla { // Update animations _applySceneAnimations(); - updateDirtyInstanceManagers(); + updateDirtyInstanceManagers(); mLastFrameNumber = thisFrameNumber; } - { - // Lock scene graph mutex, no more changes until we're ready to render + { + // Lock scene graph mutex, no more changes until we're ready to render OGRE_LOCK_MUTEX(sceneGraphMutex); - // Update scene graph for this camera (can happen multiple times per frame) - { - OgreProfileGroup("_updateSceneGraph", OGREPROF_GENERAL); - _updateSceneGraph(camera); - - // Auto-track nodes - AutoTrackingSceneNodes::iterator atsni, atsniend; - atsniend = mAutoTrackingSceneNodes.end(); - for (atsni = mAutoTrackingSceneNodes.begin(); atsni != atsniend; ++atsni) - { - (*atsni)->_autoTrack(); - } - // Auto-track camera if required - camera->_autoTrack(); - } - - if (mIlluminationStage != IRS_RENDER_TO_TEXTURE && mFindVisibleObjects) - { - // Locate any lights which could be affecting the frustum - findLightsAffectingFrustum(camera); - - // Are we using any shadows at all? - if (isShadowTechniqueInUse() && vp->getShadowsEnabled()) - { - // Prepare shadow textures if texture shadow based shadowing - // technique in use - if (isShadowTechniqueTextureBased()) - { - OgreProfileGroup("prepareShadowTextures", OGREPROF_GENERAL); - - // ******* - // WARNING - // ******* - // This call will result in re-entrant calls to this method - // therefore anything which comes before this is NOT - // guaranteed persistent. Make sure that anything which - // MUST be specific to this camera / target is done - // AFTER THIS POINT - prepareShadowTextures(camera, vp); - // reset the cameras & viewport because of the re-entrant call - mCameraInProgress = camera; - mCurrentViewport = vp; - } - } - } - - // Invert vertex winding? - if (camera->isReflected()) - { - mDestRenderSystem->setInvertVertexWinding(true); - } - else - { - mDestRenderSystem->setInvertVertexWinding(false); - } - - // Tell params about viewport - mAutoParamDataSource->setCurrentViewport(vp); - // Set the viewport - this is deliberately after the shadow texture update - setViewport(vp); - - // Tell params about camera - mAutoParamDataSource->setCurrentCamera(camera, mCameraRelativeRendering); - // Set autoparams for finite dir light extrusion - mAutoParamDataSource->setShadowDirLightExtrusionDistance(mShadowDirLightExtrudeDist); - - // Tell params about current ambient light - mAutoParamDataSource->setAmbientLightColour(mAmbientLight); - // Tell rendersystem - mDestRenderSystem->setAmbientLight(mAmbientLight.r, mAmbientLight.g, mAmbientLight.b); - - // Tell params about render target - mAutoParamDataSource->setCurrentRenderTarget(vp->getTarget()); - - - // Set camera window clipping planes (if any) - if (mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) - { - mDestRenderSystem->resetClipPlanes(); - if (camera->isWindowSet()) - { - mDestRenderSystem->setClipPlanes(camera->getWindowPlanes()); - } - } - - // Prepare render queue for receiving new objects - { - OgreProfileGroup("prepareRenderQueue", OGREPROF_GENERAL); - prepareRenderQueue(); - } - - if (mFindVisibleObjects) - { - OgreProfileGroup("_findVisibleObjects", OGREPROF_CULLING); - - // Assemble an AAB on the fly which contains the scene elements visible - // by the camera. - CamVisibleObjectsMap::iterator camVisObjIt = mCamVisibleObjectsMap.find( camera ); - - assert (camVisObjIt != mCamVisibleObjectsMap.end() && - "Should never fail to find a visible object bound for a camera, " - "did you override SceneManager::createCamera or something?"); - - // reset the bounds - camVisObjIt->second.reset(); - - // Parse the scene and tag visibles - firePreFindVisibleObjects(vp); - _findVisibleObjects(camera, &(camVisObjIt->second), - mIlluminationStage == IRS_RENDER_TO_TEXTURE? true : false); - firePostFindVisibleObjects(vp); - - mAutoParamDataSource->setMainCamBoundsInfo(&(camVisObjIt->second)); - } - // Queue skies, if viewport seems it - if (vp->getSkiesEnabled() && mFindVisibleObjects && mIlluminationStage != IRS_RENDER_TO_TEXTURE) - { - _queueSkiesForRendering(camera); - } - } // end lock on scene graph mutex + // Update scene graph for this camera (can happen multiple times per frame) + { + OgreProfileGroup("_updateSceneGraph", OGREPROF_GENERAL); + _updateSceneGraph(camera); + + // Auto-track nodes + AutoTrackingSceneNodes::iterator atsni, atsniend; + atsniend = mAutoTrackingSceneNodes.end(); + for (atsni = mAutoTrackingSceneNodes.begin(); atsni != atsniend; ++atsni) + { + (*atsni)->_autoTrack(); + } + // Auto-track camera if required + camera->_autoTrack(); + } + + if (mIlluminationStage != IRS_RENDER_TO_TEXTURE && mFindVisibleObjects) + { + // Locate any lights which could be affecting the frustum + findLightsAffectingFrustum(camera); + + // Are we using any shadows at all? + if (isShadowTechniqueInUse() && vp->getShadowsEnabled()) + { + // Prepare shadow textures if texture shadow based shadowing + // technique in use + if (isShadowTechniqueTextureBased()) + { + OgreProfileGroup("prepareShadowTextures", OGREPROF_GENERAL); + + // ******* + // WARNING + // ******* + // This call will result in re-entrant calls to this method + // therefore anything which comes before this is NOT + // guaranteed persistent. Make sure that anything which + // MUST be specific to this camera / target is done + // AFTER THIS POINT + prepareShadowTextures(camera, vp); + // reset the cameras & viewport because of the re-entrant call + mCameraInProgress = camera; + mCurrentViewport = vp; + } + } + } + + // Invert vertex winding? + if (camera->isReflected()) + { + mDestRenderSystem->setInvertVertexWinding(true); + } + else + { + mDestRenderSystem->setInvertVertexWinding(false); + } + + // Tell params about viewport + mAutoParamDataSource->setCurrentViewport(vp); + // Set the viewport - this is deliberately after the shadow texture update + setViewport(vp); + + // Tell params about camera + mAutoParamDataSource->setCurrentCamera(camera, mCameraRelativeRendering); + // Set autoparams for finite dir light extrusion + mAutoParamDataSource->setShadowDirLightExtrusionDistance(mShadowDirLightExtrudeDist); + + // Tell params about current ambient light + mAutoParamDataSource->setAmbientLightColour(mAmbientLight); + // Tell rendersystem + mDestRenderSystem->setAmbientLight(mAmbientLight.r, mAmbientLight.g, mAmbientLight.b); + + // Tell params about render target + mAutoParamDataSource->setCurrentRenderTarget(vp->getTarget()); + + + // Set camera window clipping planes (if any) + if (mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) + { + mDestRenderSystem->resetClipPlanes(); + if (camera->isWindowSet()) + { + mDestRenderSystem->setClipPlanes(camera->getWindowPlanes()); + } + } + + // Prepare render queue for receiving new objects + { + OgreProfileGroup("prepareRenderQueue", OGREPROF_GENERAL); + prepareRenderQueue(); + } + + if (mFindVisibleObjects) + { + OgreProfileGroup("_findVisibleObjects", OGREPROF_CULLING); + + // Assemble an AAB on the fly which contains the scene elements visible + // by the camera. + CamVisibleObjectsMap::iterator camVisObjIt = mCamVisibleObjectsMap.find( camera ); + + assert (camVisObjIt != mCamVisibleObjectsMap.end() && + "Should never fail to find a visible object bound for a camera, " + "did you override SceneManager::createCamera or something?"); + + // reset the bounds + camVisObjIt->second.reset(); + + // Parse the scene and tag visibles + firePreFindVisibleObjects(vp); + _findVisibleObjects(camera, &(camVisObjIt->second), + mIlluminationStage == IRS_RENDER_TO_TEXTURE? true : false); + firePostFindVisibleObjects(vp); + + mAutoParamDataSource->setMainCamBoundsInfo(&(camVisObjIt->second)); + } + // Queue skies, if viewport seems it + if (vp->getSkiesEnabled() && mFindVisibleObjects && mIlluminationStage != IRS_RENDER_TO_TEXTURE) + { + _queueSkiesForRendering(camera); + } + } // end lock on scene graph mutex mDestRenderSystem->_beginGeometryCount(); - // Clear the viewport if required - if (mCurrentViewport->getClearEveryFrame()) - { - mDestRenderSystem->clearFrameBuffer( - mCurrentViewport->getClearBuffers(), - mCurrentViewport->getBackgroundColour(), - mCurrentViewport->getDepthClear() ); - } + // Clear the viewport if required + if (mCurrentViewport->getClearEveryFrame()) + { + mDestRenderSystem->clearFrameBuffer( + mCurrentViewport->getClearBuffers(), + mCurrentViewport->getBackgroundColour(), + mCurrentViewport->getDepthClear() ); + } // Begin the frame mDestRenderSystem->_beginFrame(); // Set rasterisation mode mDestRenderSystem->_setPolygonMode(camera->getPolygonMode()); - // Set initial camera state - mDestRenderSystem->_setProjectionMatrix(mCameraInProgress->getProjectionMatrixRS()); - - mCachedViewMatrix = mCameraInProgress->getViewMatrix(true); + // Set initial camera state + mDestRenderSystem->_setProjectionMatrix(mCameraInProgress->getProjectionMatrixRS()); + + mCachedViewMatrix = mCameraInProgress->getViewMatrix(true); - if (mCameraRelativeRendering) - { - mCachedViewMatrix.setTrans(Vector3::ZERO); - mCameraRelativePosition = mCameraInProgress->getDerivedPosition(); - } - mDestRenderSystem->_setTextureProjectionRelativeTo(mCameraRelativeRendering, camera->getDerivedPosition()); + if (mCameraRelativeRendering) + { + mCachedViewMatrix.setTrans(Vector3::ZERO); + mCameraRelativePosition = mCameraInProgress->getDerivedPosition(); + } + mDestRenderSystem->_setTextureProjectionRelativeTo(mCameraRelativeRendering, camera->getDerivedPosition()); - - setViewMatrix(mCachedViewMatrix); + + setViewMatrix(mCachedViewMatrix); // Render scene content - { - OgreProfileGroup("_renderVisibleObjects", OGREPROF_RENDERING); - _renderVisibleObjects(); - } + { + OgreProfileGroup("_renderVisibleObjects", OGREPROF_RENDERING); + _renderVisibleObjects(); + } // End frame mDestRenderSystem->_endFrame(); @@ -1577,7 +1577,7 @@ void SceneManager::_renderScene(Camera* camera, Viewport* vp, bool includeOverla // Notify camera of vis batches camera->_notifyRenderedBatches(mDestRenderSystem->_getBatchCount()); - Root::getSingleton()._popCurrentSceneManager(this); + Root::getSingleton()._popCurrentSceneManager(this); } @@ -1600,7 +1600,7 @@ void SceneManager::prepareWorldGeometry(const String& filename) } //----------------------------------------------------------------------- void SceneManager::prepareWorldGeometry(DataStreamPtr& stream, - const String& typeName) + const String& typeName) { // This default implementation cannot handle world geometry OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, @@ -1618,7 +1618,7 @@ void SceneManager::setWorldGeometry(const String& filename) } //----------------------------------------------------------------------- void SceneManager::setWorldGeometry(DataStreamPtr& stream, - const String& typeName) + const String& typeName) { // This default implementation cannot handle world geometry OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, @@ -1715,11 +1715,11 @@ void SceneManager::_setSkyPlane( mSkyPlaneEntity = 0; } // Create, use the same name for mesh and entity - // manually construct as we don't want this to be destroyed on destroyAllMovableObjects - MovableObjectFactory* factory = - Root::getSingleton().getMovableObjectFactory(EntityFactory::FACTORY_TYPE_NAME); - NameValuePairList params; - params["mesh"] = meshName; + // manually construct as we don't want this to be destroyed on destroyAllMovableObjects + MovableObjectFactory* factory = + Root::getSingleton().getMovableObjectFactory(EntityFactory::FACTORY_TYPE_NAME); + NameValuePairList params; + params["mesh"] = meshName; mSkyPlaneEntity = static_cast(factory->createInstance(meshName, this, ¶ms)); mSkyPlaneEntity->setMaterialName(materialName, groupName); mSkyPlaneEntity->setCastShadows(false); @@ -1739,12 +1739,12 @@ void SceneManager::_setSkyPlane( mSkyPlaneNode->attachObject(mSkyPlaneEntity); } - mSkyPlaneEnabled = enable; - mSkyPlaneGenParameters.skyPlaneBow = bow; - mSkyPlaneGenParameters.skyPlaneScale = gscale; - mSkyPlaneGenParameters.skyPlaneTiling = tiling; - mSkyPlaneGenParameters.skyPlaneXSegments = xsegments; - mSkyPlaneGenParameters.skyPlaneYSegments = ysegments; + mSkyPlaneEnabled = enable; + mSkyPlaneGenParameters.skyPlaneBow = bow; + mSkyPlaneGenParameters.skyPlaneScale = gscale; + mSkyPlaneGenParameters.skyPlaneTiling = tiling; + mSkyPlaneGenParameters.skyPlaneXSegments = xsegments; + mSkyPlaneGenParameters.skyPlaneYSegments = ysegments; } //----------------------------------------------------------------------- void SceneManager::setSkyPlane( @@ -1758,9 +1758,9 @@ void SceneManager::setSkyPlane( int xsegments, int ysegments, const String& groupName) { - _setSkyPlane(enable, plane, materialName, gscale, tiling, - static_cast(drawFirst?RENDER_QUEUE_SKIES_EARLY: RENDER_QUEUE_SKIES_LATE), - bow, xsegments, ysegments, groupName); + _setSkyPlane(enable, plane, materialName, gscale, tiling, + static_cast(drawFirst?RENDER_QUEUE_SKIES_EARLY: RENDER_QUEUE_SKIES_LATE), + bow, xsegments, ysegments, groupName); } //----------------------------------------------------------------------- void SceneManager::_setSkyBox( @@ -1782,18 +1782,18 @@ void SceneManager::_setSkyBox( } // Ensure loaded m->load(); - if (!m->getBestTechnique() || - !m->getBestTechnique()->getNumPasses()) - { - LogManager::getSingleton().logMessage( - "Warning, skybox material " + materialName + " is not supported, defaulting.", LML_CRITICAL); - m = MaterialManager::getSingleton().getDefaultSettings(); - } - - bool t3d = false; - Pass* pass = m->getBestTechnique()->getPass(0); - if (pass->getNumTextureUnitStates() > 0 && pass->getTextureUnitState(0)->is3D()) - t3d = true; + if (!m->getBestTechnique() || + !m->getBestTechnique()->getNumPasses()) + { + LogManager::getSingleton().logMessage( + "Warning, skybox material " + materialName + " is not supported, defaulting.", LML_CRITICAL); + m = MaterialManager::getSingleton().getDefaultSettings(); + } + + bool t3d = false; + Pass* pass = m->getBestTechnique()->getPass(0); + if (pass->getNumTextureUnitStates() > 0 && pass->getTextureUnitState(0)->is3D()) + t3d = true; mSkyBoxRenderQueue = renderQueue; @@ -1803,173 +1803,173 @@ void SceneManager::_setSkyBox( mSkyBoxNode = createSceneNode("SkyBoxNode"); } - // Create object - if (!mSkyBoxObj) - { - mSkyBoxObj = OGRE_NEW ManualObject("SkyBox"); - mSkyBoxObj->setCastShadows(false); - mSkyBoxNode->attachObject(mSkyBoxObj); - } - else - { - if (!mSkyBoxObj->isAttached()) - { - mSkyBoxNode->attachObject(mSkyBoxObj); - } - mSkyBoxObj->clear(); - } - - mSkyBoxObj->setRenderQueueGroup(mSkyBoxRenderQueue); - - if (t3d) - { - mSkyBoxObj->begin(materialName); - } + // Create object + if (!mSkyBoxObj) + { + mSkyBoxObj = OGRE_NEW ManualObject("SkyBox"); + mSkyBoxObj->setCastShadows(false); + mSkyBoxNode->attachObject(mSkyBoxObj); + } + else + { + if (!mSkyBoxObj->isAttached()) + { + mSkyBoxNode->attachObject(mSkyBoxObj); + } + mSkyBoxObj->clear(); + } + + mSkyBoxObj->setRenderQueueGroup(mSkyBoxRenderQueue); + + if (t3d) + { + mSkyBoxObj->begin(materialName); + } MaterialManager& matMgr = MaterialManager::getSingleton(); // Set up the box (6 planes) for (uint16 i = 0; i < 6; ++i) { - Plane plane; - Vector3 middle; - Vector3 up, right; - - switch(i) - { - case BP_FRONT: - middle = Vector3(0, 0, -distance); - up = Vector3::UNIT_Y * distance; - right = Vector3::UNIT_X * distance; - break; - case BP_BACK: - middle = Vector3(0, 0, distance); - up = Vector3::UNIT_Y * distance; - right = Vector3::NEGATIVE_UNIT_X * distance; - break; - case BP_LEFT: - middle = Vector3(-distance, 0, 0); - up = Vector3::UNIT_Y * distance; - right = Vector3::NEGATIVE_UNIT_Z * distance; - break; - case BP_RIGHT: - middle = Vector3(distance, 0, 0); - up = Vector3::UNIT_Y * distance; - right = Vector3::UNIT_Z * distance; - break; - case BP_UP: - middle = Vector3(0, distance, 0); - up = Vector3::UNIT_Z * distance; - right = Vector3::UNIT_X * distance; - break; - case BP_DOWN: - middle = Vector3(0, -distance, 0); - up = Vector3::NEGATIVE_UNIT_Z * distance; - right = Vector3::UNIT_X * distance; - break; - } - // Modify by orientation - middle = orientation * middle; - up = orientation * up; - right = orientation * right; - - - if (t3d) - { - // 3D cubic texture - // Note UVs mirrored front/back - // I could save a few vertices here by sharing the corners - // since 3D coords will function correctly but it's really not worth - // making the code more complicated for the sake of 16 verts - // top left - Vector3 pos; - pos = middle + up - right; - mSkyBoxObj->position(pos); - mSkyBoxObj->textureCoord(pos.normalisedCopy() * Vector3(1,1,-1)); - // bottom left - pos = middle - up - right; - mSkyBoxObj->position(pos); - mSkyBoxObj->textureCoord(pos.normalisedCopy() * Vector3(1,1,-1)); - // bottom right - pos = middle - up + right; - mSkyBoxObj->position(pos); - mSkyBoxObj->textureCoord(pos.normalisedCopy() * Vector3(1,1,-1)); - // top right - pos = middle + up + right; - mSkyBoxObj->position(pos); - mSkyBoxObj->textureCoord(pos.normalisedCopy() * Vector3(1,1,-1)); - - uint16 base = i * 4; - mSkyBoxObj->quad(base, base+1, base+2, base+3); - - } - else // !t3d - { - // If we're using 6 separate images, have to create 6 materials, one for each frame - // Used to use combined material but now we're using queue we can't split to change frame - // This doesn't use much memory because textures aren't duplicated - String matName = mName + "SkyBoxPlane" + StringConverter::toString(i); - MaterialPtr boxMat = matMgr.getByName(matName, groupName); - if (boxMat.isNull()) - { - // Create new by clone - boxMat = m->clone(matName); - boxMat->load(); - } - else - { - // Copy over existing - m->copyDetailsTo(boxMat); - boxMat->load(); - } - // Make sure the material doesn't update the depth buffer - boxMat->setDepthWriteEnabled(false); - // Set active frame - Material::TechniqueIterator ti = boxMat->getSupportedTechniqueIterator(); - while (ti.hasMoreElements()) - { - Technique* tech = ti.getNext(); - if (tech->getPass(0)->getNumTextureUnitStates() > 0) - { - TextureUnitState* t = tech->getPass(0)->getTextureUnitState(0); - // Also clamp texture, don't wrap (otherwise edges can get filtered) - t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); - t->setCurrentFrame(i); - - } - } - - // section per material - mSkyBoxObj->begin(matName, RenderOperation::OT_TRIANGLE_LIST, groupName); - // top left - mSkyBoxObj->position(middle + up - right); - mSkyBoxObj->textureCoord(0,0); - // bottom left - mSkyBoxObj->position(middle - up - right); - mSkyBoxObj->textureCoord(0,1); - // bottom right - mSkyBoxObj->position(middle - up + right); - mSkyBoxObj->textureCoord(1,1); - // top right - mSkyBoxObj->position(middle + up + right); - mSkyBoxObj->textureCoord(1,0); - - mSkyBoxObj->quad(0, 1, 2, 3); - - mSkyBoxObj->end(); - - } - - } // for each plane + Plane plane; + Vector3 middle; + Vector3 up, right; - if (t3d) - { - mSkyBoxObj->end(); - } + switch(i) + { + case BP_FRONT: + middle = Vector3(0, 0, -distance); + up = Vector3::UNIT_Y * distance; + right = Vector3::UNIT_X * distance; + break; + case BP_BACK: + middle = Vector3(0, 0, distance); + up = Vector3::UNIT_Y * distance; + right = Vector3::NEGATIVE_UNIT_X * distance; + break; + case BP_LEFT: + middle = Vector3(-distance, 0, 0); + up = Vector3::UNIT_Y * distance; + right = Vector3::NEGATIVE_UNIT_Z * distance; + break; + case BP_RIGHT: + middle = Vector3(distance, 0, 0); + up = Vector3::UNIT_Y * distance; + right = Vector3::UNIT_Z * distance; + break; + case BP_UP: + middle = Vector3(0, distance, 0); + up = Vector3::UNIT_Z * distance; + right = Vector3::UNIT_X * distance; + break; + case BP_DOWN: + middle = Vector3(0, -distance, 0); + up = Vector3::NEGATIVE_UNIT_Z * distance; + right = Vector3::UNIT_X * distance; + break; + } + // Modify by orientation + middle = orientation * middle; + up = orientation * up; + right = orientation * right; + + + if (t3d) + { + // 3D cubic texture + // Note UVs mirrored front/back + // I could save a few vertices here by sharing the corners + // since 3D coords will function correctly but it's really not worth + // making the code more complicated for the sake of 16 verts + // top left + Vector3 pos; + pos = middle + up - right; + mSkyBoxObj->position(pos); + mSkyBoxObj->textureCoord(pos.normalisedCopy() * Vector3(1,1,-1)); + // bottom left + pos = middle - up - right; + mSkyBoxObj->position(pos); + mSkyBoxObj->textureCoord(pos.normalisedCopy() * Vector3(1,1,-1)); + // bottom right + pos = middle - up + right; + mSkyBoxObj->position(pos); + mSkyBoxObj->textureCoord(pos.normalisedCopy() * Vector3(1,1,-1)); + // top right + pos = middle + up + right; + mSkyBoxObj->position(pos); + mSkyBoxObj->textureCoord(pos.normalisedCopy() * Vector3(1,1,-1)); + + uint16 base = i * 4; + mSkyBoxObj->quad(base, base+1, base+2, base+3); + + } + else // !t3d + { + // If we're using 6 separate images, have to create 6 materials, one for each frame + // Used to use combined material but now we're using queue we can't split to change frame + // This doesn't use much memory because textures aren't duplicated + String matName = mName + "SkyBoxPlane" + StringConverter::toString(i); + MaterialPtr boxMat = matMgr.getByName(matName, groupName); + if (boxMat.isNull()) + { + // Create new by clone + boxMat = m->clone(matName); + boxMat->load(); + } + else + { + // Copy over existing + m->copyDetailsTo(boxMat); + boxMat->load(); + } + // Make sure the material doesn't update the depth buffer + boxMat->setDepthWriteEnabled(false); + // Set active frame + Material::TechniqueIterator ti = boxMat->getSupportedTechniqueIterator(); + while (ti.hasMoreElements()) + { + Technique* tech = ti.getNext(); + if (tech->getPass(0)->getNumTextureUnitStates() > 0) + { + TextureUnitState* t = tech->getPass(0)->getTextureUnitState(0); + // Also clamp texture, don't wrap (otherwise edges can get filtered) + t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); + t->setCurrentFrame(i); + + } + } + + // section per material + mSkyBoxObj->begin(matName, RenderOperation::OT_TRIANGLE_LIST, groupName); + // top left + mSkyBoxObj->position(middle + up - right); + mSkyBoxObj->textureCoord(0,0); + // bottom left + mSkyBoxObj->position(middle - up - right); + mSkyBoxObj->textureCoord(0,1); + // bottom right + mSkyBoxObj->position(middle - up + right); + mSkyBoxObj->textureCoord(1,1); + // top right + mSkyBoxObj->position(middle + up + right); + mSkyBoxObj->textureCoord(1,0); + + mSkyBoxObj->quad(0, 1, 2, 3); + + mSkyBoxObj->end(); + + } + + } // for each plane + + if (t3d) + { + mSkyBoxObj->end(); + } } - mSkyBoxEnabled = enable; - mSkyBoxGenParameters.skyBoxDistance = distance; + mSkyBoxEnabled = enable; + mSkyBoxGenParameters.skyBoxDistance = distance; } //----------------------------------------------------------------------- void SceneManager::setSkyBox( @@ -1980,9 +1980,9 @@ void SceneManager::setSkyBox( const Quaternion& orientation, const String& groupName) { - _setSkyBox(enable, materialName, distance, - static_cast(drawFirst?RENDER_QUEUE_SKIES_EARLY: RENDER_QUEUE_SKIES_LATE), - orientation, groupName); + _setSkyBox(enable, materialName, distance, + static_cast(drawFirst?RENDER_QUEUE_SKIES_EARLY: RENDER_QUEUE_SKIES_LATE), + orientation, groupName); } //----------------------------------------------------------------------- void SceneManager::_setSkyDome( @@ -2039,13 +2039,13 @@ void SceneManager::_setSkyDome( destroyEntity(entName); mSkyDomeEntity[i] = 0; } - // construct manually so we don't have problems if destroyAllMovableObjects called - MovableObjectFactory* factory = - Root::getSingleton().getMovableObjectFactory(EntityFactory::FACTORY_TYPE_NAME); + // construct manually so we don't have problems if destroyAllMovableObjects called + MovableObjectFactory* factory = + Root::getSingleton().getMovableObjectFactory(EntityFactory::FACTORY_TYPE_NAME); - NameValuePairList params; - params["mesh"] = planeMesh->getName(); - mSkyDomeEntity[i] = static_cast(factory->createInstance(entName, this, ¶ms)); + NameValuePairList params; + params["mesh"] = planeMesh->getName(); + mSkyDomeEntity[i] = static_cast(factory->createInstance(entName, this, ¶ms)); mSkyDomeEntity[i]->setMaterialName(m->getName(), groupName); mSkyDomeEntity[i]->setCastShadows(false); @@ -2057,13 +2057,13 @@ void SceneManager::_setSkyDome( } // for each plane } - mSkyDomeEnabled = enable; - mSkyDomeGenParameters.skyDomeCurvature = curvature; - mSkyDomeGenParameters.skyDomeDistance = distance; - mSkyDomeGenParameters.skyDomeTiling = tiling; - mSkyDomeGenParameters.skyDomeXSegments = xsegments; - mSkyDomeGenParameters.skyDomeYSegments = ysegments; - mSkyDomeGenParameters.skyDomeYSegments_keep = ySegmentsToKeep; + mSkyDomeEnabled = enable; + mSkyDomeGenParameters.skyDomeCurvature = curvature; + mSkyDomeGenParameters.skyDomeDistance = distance; + mSkyDomeGenParameters.skyDomeTiling = tiling; + mSkyDomeGenParameters.skyDomeXSegments = xsegments; + mSkyDomeGenParameters.skyDomeYSegments = ysegments; + mSkyDomeGenParameters.skyDomeYSegments_keep = ySegmentsToKeep; } //----------------------------------------------------------------------- void SceneManager::setSkyDome( @@ -2077,9 +2077,9 @@ void SceneManager::setSkyDome( int xsegments, int ysegments, int ySegmentsToKeep, const String& groupName) { - _setSkyDome(enable, materialName, curvature, tiling, distance, - static_cast(drawFirst?RENDER_QUEUE_SKIES_EARLY: RENDER_QUEUE_SKIES_LATE), - orientation, xsegments, ysegments, ySegmentsToKeep, groupName); + _setSkyDome(enable, materialName, curvature, tiling, distance, + static_cast(drawFirst?RENDER_QUEUE_SKIES_EARLY: RENDER_QUEUE_SKIES_LATE), + orientation, xsegments, ysegments, ySegmentsToKeep, groupName); } //----------------------------------------------------------------------- MeshPtr SceneManager::createSkyboxPlane( @@ -2231,10 +2231,10 @@ MeshPtr SceneManager::createSkydomePlane( //----------------------------------------------------------------------- void SceneManager::_updateSceneGraph(Camera* cam) { - firePreUpdateSceneGraph(cam); + firePreUpdateSceneGraph(cam); - // Process queued needUpdate calls - Node::processQueuedUpdates(); + // Process queued needUpdate calls + Node::processQueuedUpdates(); // Cascade down the graph updating transforms & world bounds // In this implementation, just update from the root @@ -2242,11 +2242,11 @@ void SceneManager::_updateSceneGraph(Camera* cam) // certain scene graph branches getRootSceneNode()->_update(true, false); - firePostUpdateSceneGraph(cam); + firePostUpdateSceneGraph(cam); } //----------------------------------------------------------------------- void SceneManager::_findVisibleObjects( - Camera* cam, VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters) + Camera* cam, VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters) { // Tell nodes to find, cascade down all nodes getRootSceneNode()->_findVisibleObjects(cam, getRenderQueue(), visibleBounds, true, @@ -2256,71 +2256,71 @@ void SceneManager::_findVisibleObjects( //----------------------------------------------------------------------- void SceneManager::_renderVisibleObjects(void) { - RenderQueueInvocationSequence* invocationSequence = - mCurrentViewport->_getRenderQueueInvocationSequence(); - // Use custom sequence only if we're not doing the texture shadow render - // since texture shadow render should not be interfered with by suppressing - // render state changes for example - if (invocationSequence && mIlluminationStage != IRS_RENDER_TO_TEXTURE) - { - renderVisibleObjectsCustomSequence(invocationSequence); - } - else - { - renderVisibleObjectsDefaultSequence(); - } + RenderQueueInvocationSequence* invocationSequence = + mCurrentViewport->_getRenderQueueInvocationSequence(); + // Use custom sequence only if we're not doing the texture shadow render + // since texture shadow render should not be interfered with by suppressing + // render state changes for example + if (invocationSequence && mIlluminationStage != IRS_RENDER_TO_TEXTURE) + { + renderVisibleObjectsCustomSequence(invocationSequence); + } + else + { + renderVisibleObjectsDefaultSequence(); + } } //----------------------------------------------------------------------- void SceneManager::renderVisibleObjectsCustomSequence(RenderQueueInvocationSequence* seq) { - firePreRenderQueues(); + firePreRenderQueues(); - RenderQueueInvocationIterator invocationIt = seq->iterator(); - while (invocationIt.hasMoreElements()) - { - RenderQueueInvocation* invocation = invocationIt.getNext(); - uint8 qId = invocation->getRenderQueueGroupID(); - // Skip this one if not to be processed - if (!isRenderQueueToBeProcessed(qId)) - continue; + RenderQueueInvocationIterator invocationIt = seq->iterator(); + while (invocationIt.hasMoreElements()) + { + RenderQueueInvocation* invocation = invocationIt.getNext(); + uint8 qId = invocation->getRenderQueueGroupID(); + // Skip this one if not to be processed + if (!isRenderQueueToBeProcessed(qId)) + continue; - bool repeatQueue = false; - const String& invocationName = invocation->getInvocationName(); - RenderQueueGroup* queueGroup = getRenderQueue()->getQueueGroup(qId); - do // for repeating queues - { - // Fire queue started event - if (fireRenderQueueStarted(qId, invocationName)) - { - // Someone requested we skip this queue - break; - } + bool repeatQueue = false; + const String& invocationName = invocation->getInvocationName(); + RenderQueueGroup* queueGroup = getRenderQueue()->getQueueGroup(qId); + do // for repeating queues + { + // Fire queue started event + if (fireRenderQueueStarted(qId, invocationName)) + { + // Someone requested we skip this queue + break; + } - // Invoke it - invocation->invoke(queueGroup, this); + // Invoke it + invocation->invoke(queueGroup, this); - // Fire queue ended event - if (fireRenderQueueEnded(qId, invocationName)) - { - // Someone requested we repeat this queue - repeatQueue = true; - } - else - { - repeatQueue = false; - } - } while (repeatQueue); + // Fire queue ended event + if (fireRenderQueueEnded(qId, invocationName)) + { + // Someone requested we repeat this queue + repeatQueue = true; + } + else + { + repeatQueue = false; + } + } while (repeatQueue); - } + } - firePostRenderQueues(); + firePostRenderQueues(); } //----------------------------------------------------------------------- void SceneManager::renderVisibleObjectsDefaultSequence(void) { - firePreRenderQueues(); + firePreRenderQueues(); // Render each separate queue RenderQueue::QueueGroupIterator queueIt = getRenderQueue()->_getQueueGroupIterator(); @@ -2332,32 +2332,32 @@ void SceneManager::renderVisibleObjectsDefaultSequence(void) { // Get queue group id uint8 qId = queueIt.peekNextKey(); - RenderQueueGroup* pGroup = queueIt.getNext(); - // Skip this one if not to be processed - if (!isRenderQueueToBeProcessed(qId)) - continue; + RenderQueueGroup* pGroup = queueIt.getNext(); + // Skip this one if not to be processed + if (!isRenderQueueToBeProcessed(qId)) + continue; bool repeatQueue = false; do // for repeating queues { // Fire queue started event - if (fireRenderQueueStarted(qId, - mIlluminationStage == IRS_RENDER_TO_TEXTURE ? - RenderQueueInvocation::RENDER_QUEUE_INVOCATION_SHADOWS : - BLANKSTRING)) + if (fireRenderQueueStarted(qId, + mIlluminationStage == IRS_RENDER_TO_TEXTURE ? + RenderQueueInvocation::RENDER_QUEUE_INVOCATION_SHADOWS : + BLANKSTRING)) { // Someone requested we skip this queue break; } - _renderQueueGroupObjects(pGroup, QueuedRenderableCollection::OM_PASS_GROUP); + _renderQueueGroupObjects(pGroup, QueuedRenderableCollection::OM_PASS_GROUP); // Fire queue ended event - if (fireRenderQueueEnded(qId, - mIlluminationStage == IRS_RENDER_TO_TEXTURE ? - RenderQueueInvocation::RENDER_QUEUE_INVOCATION_SHADOWS : - BLANKSTRING)) + if (fireRenderQueueEnded(qId, + mIlluminationStage == IRS_RENDER_TO_TEXTURE ? + RenderQueueInvocation::RENDER_QUEUE_INVOCATION_SHADOWS : + BLANKSTRING)) { // Someone requested we repeat this queue repeatQueue = true; @@ -2370,13 +2370,13 @@ void SceneManager::renderVisibleObjectsDefaultSequence(void) } // for each queue group - firePostRenderQueues(); + firePostRenderQueues(); } //----------------------------------------------------------------------- void SceneManager::renderAdditiveStencilShadowedQueueGroupObjects( - RenderQueueGroup* pGroup, - QueuedRenderableCollection::OrganisationMode om) + RenderQueueGroup* pGroup, + QueuedRenderableCollection::OrganisationMode om) { RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); LightList lightList; @@ -2406,20 +2406,20 @@ void SceneManager::renderAdditiveStencilShadowedQueueGroupObjects( { Light* l = *li; // Set light state - if (lightList.empty()) - lightList.push_back(l); - else - lightList[0] = l; + if (lightList.empty()) + lightList.push_back(l); + else + lightList[0] = l; - // set up scissor, will cover shadow vol and regular light rendering - ClipResult scissored = buildAndSetScissor(lightList, mCameraInProgress); - ClipResult clipped = CLIPPED_NONE; - if (mShadowAdditiveLightClip) - clipped = buildAndSetLightClip(lightList); + // set up scissor, will cover shadow vol and regular light rendering + ClipResult scissored = buildAndSetScissor(lightList, mCameraInProgress); + ClipResult clipped = CLIPPED_NONE; + if (mShadowAdditiveLightClip) + clipped = buildAndSetLightClip(lightList); - // skip light if scissored / clipped entirely - if (scissored == CLIPPED_ALL || clipped == CLIPPED_ALL) - continue; + // skip light if scissored / clipped entirely + if (scissored == CLIPPED_ALL || clipped == CLIPPED_ALL) + continue; if (l->getCastShadows()) { @@ -2440,10 +2440,10 @@ void SceneManager::renderAdditiveStencilShadowedQueueGroupObjects( mDestRenderSystem->setStencilCheckEnabled(false); mDestRenderSystem->_setDepthBufferParams(); - if (scissored == CLIPPED_SOME) - resetScissor(); - if (clipped == CLIPPED_SOME) - resetLightClip(); + if (scissored == CLIPPED_SOME) + resetScissor(); + if (clipped == CLIPPED_SOME) + resetLightClip(); }// for each light @@ -2464,7 +2464,7 @@ void SceneManager::renderAdditiveStencilShadowedQueueGroupObjects( renderObjects(pPriorityGrp->getTransparentsUnsorted(), om, true, true); // Do transparents (always descending sort) renderObjects(pPriorityGrp->getTransparents(), - QueuedRenderableCollection::OM_SORT_DESCENDING, true, true); + QueuedRenderableCollection::OM_SORT_DESCENDING, true, true); }// for each priority @@ -2472,8 +2472,8 @@ void SceneManager::renderAdditiveStencilShadowedQueueGroupObjects( } //----------------------------------------------------------------------- void SceneManager::renderModulativeStencilShadowedQueueGroupObjects( - RenderQueueGroup* pGroup, - QueuedRenderableCollection::OrganisationMode om) + RenderQueueGroup* pGroup, + QueuedRenderableCollection::OrganisationMode om) { /* For each light, we need to render all the solids from each group, then do the modulative shadows, then render the transparents from @@ -2547,15 +2547,15 @@ void SceneManager::renderModulativeStencilShadowedQueueGroupObjects( renderObjects(pPriorityGrp->getTransparentsUnsorted(), om, true, true); // Do transparents (always descending sort) renderObjects(pPriorityGrp->getTransparents(), - QueuedRenderableCollection::OM_SORT_DESCENDING, true, true); + QueuedRenderableCollection::OM_SORT_DESCENDING, true, true); }// for each priority } //----------------------------------------------------------------------- void SceneManager::renderTextureShadowCasterQueueGroupObjects( - RenderQueueGroup* pGroup, - QueuedRenderableCollection::OrganisationMode om) + RenderQueueGroup* pGroup, + QueuedRenderableCollection::OrganisationMode om) { // This is like the basic group render, except we skip all transparents // and we also render any non-shadowed objects @@ -2566,18 +2566,18 @@ void SceneManager::renderTextureShadowCasterQueueGroupObjects( RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); // Override auto param ambient to force vertex programs and fixed function to - if (isShadowTechniqueAdditive()) - { - // Use simple black / white mask if additive - mAutoParamDataSource->setAmbientLightColour(ColourValue::Black); - mDestRenderSystem->setAmbientLight(0, 0, 0); - } - else - { - // Use shadow colour as caster colour if modulative - mAutoParamDataSource->setAmbientLightColour(mShadowColour); - mDestRenderSystem->setAmbientLight(mShadowColour.r, mShadowColour.g, mShadowColour.b); - } + if (isShadowTechniqueAdditive()) + { + // Use simple black / white mask if additive + mAutoParamDataSource->setAmbientLightColour(ColourValue::Black); + mDestRenderSystem->setAmbientLight(0, 0, 0); + } + else + { + // Use shadow colour as caster colour if modulative + mAutoParamDataSource->setAmbientLightColour(mShadowColour); + mDestRenderSystem->setAmbientLight(mShadowColour.r, mShadowColour.g, mShadowColour.b); + } while (groupIt.hasMoreElements()) { @@ -2589,13 +2589,13 @@ void SceneManager::renderTextureShadowCasterQueueGroupObjects( // Do solids, override light list incase any vertex programs use them renderObjects(pPriorityGrp->getSolidsBasic(), om, false, false, &mShadowTextureCurrentCasterLightList); renderObjects(pPriorityGrp->getSolidsNoShadowReceive(), om, false, false, &mShadowTextureCurrentCasterLightList); - // Do unsorted transparents that cast shadows - renderObjects(pPriorityGrp->getTransparentsUnsorted(), om, false, false, &mShadowTextureCurrentCasterLightList); - // Do transparents that cast shadows - renderTransparentShadowCasterObjects( - pPriorityGrp->getTransparents(), - QueuedRenderableCollection::OM_SORT_DESCENDING, - false, false, &mShadowTextureCurrentCasterLightList); + // Do unsorted transparents that cast shadows + renderObjects(pPriorityGrp->getTransparentsUnsorted(), om, false, false, &mShadowTextureCurrentCasterLightList); + // Do transparents that cast shadows + renderTransparentShadowCasterObjects( + pPriorityGrp->getTransparents(), + QueuedRenderableCollection::OM_SORT_DESCENDING, + false, false, &mShadowTextureCurrentCasterLightList); }// for each priority @@ -2606,8 +2606,8 @@ void SceneManager::renderTextureShadowCasterQueueGroupObjects( } //----------------------------------------------------------------------- void SceneManager::renderModulativeTextureShadowedQueueGroupObjects( - RenderQueueGroup* pGroup, - QueuedRenderableCollection::OrganisationMode om) + RenderQueueGroup* pGroup, + QueuedRenderableCollection::OrganisationMode om) { /* For each light, we need to render all the solids from each group, then do the modulative shadows, then render the transparents from @@ -2652,49 +2652,49 @@ void SceneManager::renderModulativeTextureShadowedQueueGroupObjects( if (!l->getCastShadows()) continue; - // Store current shadow texture + // Store current shadow texture mCurrentShadowTexture = si->getPointer(); - // Get camera for current shadow texture + // Get camera for current shadow texture Camera *cam = mCurrentShadowTexture->getBuffer()->getRenderTarget()->getViewport(0)->getCamera(); // Hook up receiver texture - Pass* targetPass = mShadowTextureCustomReceiverPass ? - mShadowTextureCustomReceiverPass : mShadowReceiverPass; - targetPass->getTextureUnitState(0)->setTextureName( - mCurrentShadowTexture->getName()); - // Hook up projection frustum if fixed-function, but also need to - // disable it explicitly for program pipeline. - TextureUnitState* texUnit = targetPass->getTextureUnitState(0); - texUnit->setProjectiveTexturing(!targetPass->hasVertexProgram(), cam); - // clamp to border colour in case this is a custom material - texUnit->setTextureAddressingMode(TextureUnitState::TAM_BORDER); - texUnit->setTextureBorderColour(ColourValue::White); + Pass* targetPass = mShadowTextureCustomReceiverPass ? + mShadowTextureCustomReceiverPass : mShadowReceiverPass; + targetPass->getTextureUnitState(0)->setTextureName( + mCurrentShadowTexture->getName()); + // Hook up projection frustum if fixed-function, but also need to + // disable it explicitly for program pipeline. + TextureUnitState* texUnit = targetPass->getTextureUnitState(0); + texUnit->setProjectiveTexturing(!targetPass->hasVertexProgram(), cam); + // clamp to border colour in case this is a custom material + texUnit->setTextureAddressingMode(TextureUnitState::TAM_BORDER); + texUnit->setTextureBorderColour(ColourValue::White); mAutoParamDataSource->setTextureProjector(cam, 0); // if this light is a spotlight, we need to add the spot fader layer - // BUT not if using a custom projection matrix, since then it will be - // inappropriately shaped most likely + // BUT not if using a custom projection matrix, since then it will be + // inappropriately shaped most likely if (l->getType() == Light::LT_SPOTLIGHT && !cam->isCustomProjectionMatrixEnabled()) { - // remove all TUs except 0 & 1 - // (only an issue if additive shadows have been used) - while(targetPass->getNumTextureUnitStates() > 2) - targetPass->removeTextureUnitState(2); + // remove all TUs except 0 & 1 + // (only an issue if additive shadows have been used) + while(targetPass->getNumTextureUnitStates() > 2) + targetPass->removeTextureUnitState(2); // Add spot fader if not present already if (targetPass->getNumTextureUnitStates() == 2 && - targetPass->getTextureUnitState(1)->getTextureName() == - "spot_shadow_fade.png") - { - // Just set - TextureUnitState* t = - targetPass->getTextureUnitState(1); - t->setProjectiveTexturing(!targetPass->hasVertexProgram(), cam); - } + targetPass->getTextureUnitState(1)->getTextureName() == + "spot_shadow_fade.png") + { + // Just set + TextureUnitState* t = + targetPass->getTextureUnitState(1); + t->setProjectiveTexturing(!targetPass->hasVertexProgram(), cam); + } else - { - // Remove any non-conforming spot layers - while(targetPass->getNumTextureUnitStates() > 1) - targetPass->removeTextureUnitState(1); + { + // Remove any non-conforming spot layers + while(targetPass->getNumTextureUnitStates() > 1) + targetPass->removeTextureUnitState(1); TextureUnitState* t = targetPass->createTextureUnitState("spot_shadow_fade.png"); @@ -2705,19 +2705,19 @@ void SceneManager::renderModulativeTextureShadowedQueueGroupObjects( } else { - // remove all TUs except 0 including spot - while(targetPass->getNumTextureUnitStates() > 1) - targetPass->removeTextureUnitState(1); + // remove all TUs except 0 including spot + while(targetPass->getNumTextureUnitStates() > 1) + targetPass->removeTextureUnitState(1); } - // Set lighting / blending modes - targetPass->setSceneBlending(SBF_DEST_COLOUR, SBF_ZERO); - targetPass->setLightingEnabled(false); + // Set lighting / blending modes + targetPass->setSceneBlending(SBF_DEST_COLOUR, SBF_ZERO); + targetPass->setLightingEnabled(false); targetPass->_load(); - // Fire pre-receiver event - fireShadowTexturesPreReceiver(l, cam); + // Fire pre-receiver event + fireShadowTexturesPreReceiver(l, cam); renderTextureShadowReceiverQueueGroupObjects(pGroup, om); @@ -2739,94 +2739,94 @@ void SceneManager::renderModulativeTextureShadowedQueueGroupObjects( renderObjects(pPriorityGrp->getTransparentsUnsorted(), om, true, true); // Do transparents (always descending) renderObjects(pPriorityGrp->getTransparents(), - QueuedRenderableCollection::OM_SORT_DESCENDING, true, true); + QueuedRenderableCollection::OM_SORT_DESCENDING, true, true); }// for each priority } //----------------------------------------------------------------------- void SceneManager::renderAdditiveTextureShadowedQueueGroupObjects( - RenderQueueGroup* pGroup, - QueuedRenderableCollection::OrganisationMode om) + RenderQueueGroup* pGroup, + QueuedRenderableCollection::OrganisationMode om) { - RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); - LightList lightList; + RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator(); + LightList lightList; - while (groupIt.hasMoreElements()) - { - RenderPriorityGroup* pPriorityGrp = groupIt.getNext(); + while (groupIt.hasMoreElements()) + { + RenderPriorityGroup* pPriorityGrp = groupIt.getNext(); - // Sort the queue first - pPriorityGrp->sort(mCameraInProgress); + // Sort the queue first + pPriorityGrp->sort(mCameraInProgress); - // Clear light list - lightList.clear(); + // Clear light list + lightList.clear(); - // Render all the ambient passes first, no light iteration, no lights - renderObjects(pPriorityGrp->getSolidsBasic(), om, false, false, &lightList); - // Also render any objects which have receive shadows disabled - renderObjects(pPriorityGrp->getSolidsNoShadowReceive(), om, true, true); + // Render all the ambient passes first, no light iteration, no lights + renderObjects(pPriorityGrp->getSolidsBasic(), om, false, false, &lightList); + // Also render any objects which have receive shadows disabled + renderObjects(pPriorityGrp->getSolidsNoShadowReceive(), om, true, true); - // only perform this next part if we're in the 'normal' render stage, to avoid - // doing it during the render to texture - if (mIlluminationStage == IRS_NONE) - { - // Iterate over lights, render masked - LightList::const_iterator li, liend; - ShadowTextureList::iterator si, siend; - liend = mLightsAffectingFrustum.end(); - siend = mShadowTextures.end(); + // only perform this next part if we're in the 'normal' render stage, to avoid + // doing it during the render to texture + if (mIlluminationStage == IRS_NONE) + { + // Iterate over lights, render masked + LightList::const_iterator li, liend; + ShadowTextureList::iterator si, siend; + liend = mLightsAffectingFrustum.end(); + siend = mShadowTextures.end(); si = mShadowTextures.begin(); - for (li = mLightsAffectingFrustum.begin(); li != liend; ++li) - { - Light* l = *li; - - if (l->getCastShadows() && si != siend) - { - // Store current shadow texture - mCurrentShadowTexture = si->getPointer(); - // Get camera for current shadow texture - Camera *cam = mCurrentShadowTexture->getBuffer()->getRenderTarget()->getViewport(0)->getCamera(); - // Hook up receiver texture - Pass* targetPass = mShadowTextureCustomReceiverPass ? - mShadowTextureCustomReceiverPass : mShadowReceiverPass; - targetPass->getTextureUnitState(0)->setTextureName( - mCurrentShadowTexture->getName()); - // Hook up projection frustum if fixed-function, but also need to - // disable it explicitly for program pipeline. - TextureUnitState* texUnit = targetPass->getTextureUnitState(0); - texUnit->setProjectiveTexturing(!targetPass->hasVertexProgram(), cam); - // clamp to border colour in case this is a custom material - texUnit->setTextureAddressingMode(TextureUnitState::TAM_BORDER); - texUnit->setTextureBorderColour(ColourValue::White); - mAutoParamDataSource->setTextureProjector(cam, 0); - // Remove any spot fader layer - if (targetPass->getNumTextureUnitStates() > 1 && - targetPass->getTextureUnitState(1)->getTextureName() - == "spot_shadow_fade.png") - { - // remove spot fader layer (should only be there if - // we previously used modulative shadows) - targetPass->removeTextureUnitState(1); - } - // Set lighting / blending modes - targetPass->setSceneBlending(SBF_ONE, SBF_ONE); - targetPass->setLightingEnabled(true); - targetPass->_load(); - - // increment shadow texture since used - ++si; - - mIlluminationStage = IRS_RENDER_RECEIVER_PASS; - - } - else - { - mIlluminationStage = IRS_NONE; - - } + for (li = mLightsAffectingFrustum.begin(); li != liend; ++li) + { + Light* l = *li; + + if (l->getCastShadows() && si != siend) + { + // Store current shadow texture + mCurrentShadowTexture = si->getPointer(); + // Get camera for current shadow texture + Camera *cam = mCurrentShadowTexture->getBuffer()->getRenderTarget()->getViewport(0)->getCamera(); + // Hook up receiver texture + Pass* targetPass = mShadowTextureCustomReceiverPass ? + mShadowTextureCustomReceiverPass : mShadowReceiverPass; + targetPass->getTextureUnitState(0)->setTextureName( + mCurrentShadowTexture->getName()); + // Hook up projection frustum if fixed-function, but also need to + // disable it explicitly for program pipeline. + TextureUnitState* texUnit = targetPass->getTextureUnitState(0); + texUnit->setProjectiveTexturing(!targetPass->hasVertexProgram(), cam); + // clamp to border colour in case this is a custom material + texUnit->setTextureAddressingMode(TextureUnitState::TAM_BORDER); + texUnit->setTextureBorderColour(ColourValue::White); + mAutoParamDataSource->setTextureProjector(cam, 0); + // Remove any spot fader layer + if (targetPass->getNumTextureUnitStates() > 1 && + targetPass->getTextureUnitState(1)->getTextureName() + == "spot_shadow_fade.png") + { + // remove spot fader layer (should only be there if + // we previously used modulative shadows) + targetPass->removeTextureUnitState(1); + } + // Set lighting / blending modes + targetPass->setSceneBlending(SBF_ONE, SBF_ONE); + targetPass->setLightingEnabled(true); + targetPass->_load(); + + // increment shadow texture since used + ++si; + + mIlluminationStage = IRS_RENDER_RECEIVER_PASS; + + } + else + { + mIlluminationStage = IRS_NONE; + + } // render lighting passes for this light if (lightList.empty()) @@ -2834,52 +2834,52 @@ void SceneManager::renderAdditiveTextureShadowedQueueGroupObjects( else lightList[0] = l; - // set up light scissoring, always useful in additive modes - ClipResult scissored = buildAndSetScissor(lightList, mCameraInProgress); - ClipResult clipped = CLIPPED_NONE; - if(mShadowAdditiveLightClip) - clipped = buildAndSetLightClip(lightList); - // skip if entirely clipped - if(scissored == CLIPPED_ALL || clipped == CLIPPED_ALL) - continue; + // set up light scissoring, always useful in additive modes + ClipResult scissored = buildAndSetScissor(lightList, mCameraInProgress); + ClipResult clipped = CLIPPED_NONE; + if(mShadowAdditiveLightClip) + clipped = buildAndSetLightClip(lightList); + // skip if entirely clipped + if(scissored == CLIPPED_ALL || clipped == CLIPPED_ALL) + continue; - renderObjects(pPriorityGrp->getSolidsDiffuseSpecular(), om, false, false, &lightList); - if (scissored == CLIPPED_SOME) - resetScissor(); - if (clipped == CLIPPED_SOME) - resetLightClip(); + renderObjects(pPriorityGrp->getSolidsDiffuseSpecular(), om, false, false, &lightList); + if (scissored == CLIPPED_SOME) + resetScissor(); + if (clipped == CLIPPED_SOME) + resetLightClip(); - }// for each light + }// for each light - mIlluminationStage = IRS_NONE; + mIlluminationStage = IRS_NONE; - // Now render decal passes, no need to set lights as lighting will be disabled - renderObjects(pPriorityGrp->getSolidsDecal(), om, false, false); + // Now render decal passes, no need to set lights as lighting will be disabled + renderObjects(pPriorityGrp->getSolidsDecal(), om, false, false); - } + } - }// for each priority + }// for each priority - // Iterate again - variable name changed to appease gcc. - RenderQueueGroup::PriorityMapIterator groupIt2 = pGroup->getIterator(); - while (groupIt2.hasMoreElements()) - { - RenderPriorityGroup* pPriorityGrp = groupIt2.getNext(); + // Iterate again - variable name changed to appease gcc. + RenderQueueGroup::PriorityMapIterator groupIt2 = pGroup->getIterator(); + while (groupIt2.hasMoreElements()) + { + RenderPriorityGroup* pPriorityGrp = groupIt2.getNext(); // Do unsorted transparents renderObjects(pPriorityGrp->getTransparentsUnsorted(), om, true, true); - // Do transparents (always descending sort) - renderObjects(pPriorityGrp->getTransparents(), - QueuedRenderableCollection::OM_SORT_DESCENDING, true, true); + // Do transparents (always descending sort) + renderObjects(pPriorityGrp->getTransparents(), + QueuedRenderableCollection::OM_SORT_DESCENDING, true, true); - }// for each priority + }// for each priority } //----------------------------------------------------------------------- void SceneManager::renderTextureShadowReceiverQueueGroupObjects( - RenderQueueGroup* pGroup, - QueuedRenderableCollection::OrganisationMode om) + RenderQueueGroup* pGroup, + QueuedRenderableCollection::OrganisationMode om) { static LightList nullLightList; @@ -2909,70 +2909,70 @@ void SceneManager::renderTextureShadowReceiverQueueGroupObjects( //----------------------------------------------------------------------- void SceneManager::SceneMgrQueuedRenderableVisitor::visit(Renderable* r) { - // Give SM a chance to eliminate - if (targetSceneMgr->validateRenderableForRendering(mUsedPass, r)) - { - // Render a single object, this will set up auto params if required - targetSceneMgr->renderSingleObject(r, mUsedPass, scissoring, autoLights, manualLightList); - } + // Give SM a chance to eliminate + if (targetSceneMgr->validateRenderableForRendering(mUsedPass, r)) + { + // Render a single object, this will set up auto params if required + targetSceneMgr->renderSingleObject(r, mUsedPass, scissoring, autoLights, manualLightList); + } } //----------------------------------------------------------------------- bool SceneManager::SceneMgrQueuedRenderableVisitor::visit(const Pass* p) { - // Give SM a chance to eliminate this pass - if (!targetSceneMgr->validatePassForRendering(p)) - return false; + // Give SM a chance to eliminate this pass + if (!targetSceneMgr->validatePassForRendering(p)) + return false; - // Set pass, store the actual one used - mUsedPass = targetSceneMgr->_setPass(p); + // Set pass, store the actual one used + mUsedPass = targetSceneMgr->_setPass(p); - return true; + return true; } //----------------------------------------------------------------------- void SceneManager::SceneMgrQueuedRenderableVisitor::visit(RenderablePass* rp) { - // Skip this one if we're in transparency cast shadows mode & it doesn't - // Don't need to implement this one in the other visit methods since - // transparents are never grouped, always sorted - if (transparentShadowCastersMode && - !rp->pass->getParent()->getParent()->getTransparencyCastsShadows()) - return; + // Skip this one if we're in transparency cast shadows mode & it doesn't + // Don't need to implement this one in the other visit methods since + // transparents are never grouped, always sorted + if (transparentShadowCastersMode && + !rp->pass->getParent()->getParent()->getTransparencyCastsShadows()) + return; - // Give SM a chance to eliminate - if (targetSceneMgr->validateRenderableForRendering(rp->pass, rp->renderable)) - { - mUsedPass = targetSceneMgr->_setPass(rp->pass); - targetSceneMgr->renderSingleObject(rp->renderable, mUsedPass, scissoring, - autoLights, manualLightList); - } + // Give SM a chance to eliminate + if (targetSceneMgr->validateRenderableForRendering(rp->pass, rp->renderable)) + { + mUsedPass = targetSceneMgr->_setPass(rp->pass); + targetSceneMgr->renderSingleObject(rp->renderable, mUsedPass, scissoring, + autoLights, manualLightList); + } } //----------------------------------------------------------------------- bool SceneManager::validatePassForRendering(const Pass* pass) { // Bypass if we're doing a texture shadow render and // this pass is after the first (only 1 pass needed for shadow texture render, and - // one pass for shadow texture receive for modulative technique) - // Also bypass if passes above the first if render state changes are - // suppressed since we're not actually using this pass data anyway + // one pass for shadow texture receive for modulative technique) + // Also bypass if passes above the first if render state changes are + // suppressed since we're not actually using this pass data anyway if (!mSuppressShadows && mCurrentViewport->getShadowsEnabled() && - ((isShadowTechniqueModulative() && mIlluminationStage == IRS_RENDER_RECEIVER_PASS) - || mIlluminationStage == IRS_RENDER_TO_TEXTURE || mSuppressRenderStateChanges) && + ((isShadowTechniqueModulative() && mIlluminationStage == IRS_RENDER_RECEIVER_PASS) + || mIlluminationStage == IRS_RENDER_TO_TEXTURE || mSuppressRenderStateChanges) && pass->getIndex() > 0) { return false; } - // If using late material resolving, check if there is a pass with the same index - // as this one in the 'late' material. If not, skip. - if (isLateMaterialResolving()) - { - Technique* lateTech = pass->getParent()->getParent()->getBestTechnique(); - if (lateTech->getNumPasses() <= pass->getIndex()) - { - return false; - } - } + // If using late material resolving, check if there is a pass with the same index + // as this one in the 'late' material. If not, skip. + if (isLateMaterialResolving()) + { + Technique* lateTech = pass->getParent()->getParent()->getBestTechnique(); + if (lateTech->getNumPasses() <= pass->getIndex()) + { + return false; + } + } return true; } @@ -2981,22 +2981,22 @@ bool SceneManager::validateRenderableForRendering(const Pass* pass, const Render { // Skip this renderable if we're doing modulative texture shadows, it casts shadows // and we're doing the render receivers pass and we're not self-shadowing - // also if pass number > 0 + // also if pass number > 0 if (!mSuppressShadows && mCurrentViewport->getShadowsEnabled() && - isShadowTechniqueTextureBased()) - { - if (mIlluminationStage == IRS_RENDER_RECEIVER_PASS && - rend->getCastsShadows() && !mShadowTextureSelfShadow) - { - return false; - } - // Some duplication here with validatePassForRendering, for transparents - if (((isShadowTechniqueModulative() && mIlluminationStage == IRS_RENDER_RECEIVER_PASS) - || mIlluminationStage == IRS_RENDER_TO_TEXTURE || mSuppressRenderStateChanges) && - pass->getIndex() > 0) - { - return false; - } + isShadowTechniqueTextureBased()) + { + if (mIlluminationStage == IRS_RENDER_RECEIVER_PASS && + rend->getCastsShadows() && !mShadowTextureSelfShadow) + { + return false; + } + // Some duplication here with validatePassForRendering, for transparents + if (((isShadowTechniqueModulative() && mIlluminationStage == IRS_RENDER_RECEIVER_PASS) + || mIlluminationStage == IRS_RENDER_TO_TEXTURE || mSuppressRenderStateChanges) && + pass->getIndex() > 0) + { + return false; + } } return true; @@ -3004,27 +3004,27 @@ bool SceneManager::validateRenderableForRendering(const Pass* pass, const Render } //----------------------------------------------------------------------- void SceneManager::renderObjects(const QueuedRenderableCollection& objs, - QueuedRenderableCollection::OrganisationMode om, - bool lightScissoringClipping, - bool doLightIteration, + QueuedRenderableCollection::OrganisationMode om, + bool lightScissoringClipping, + bool doLightIteration, const LightList* manualLightList) { - mActiveQueuedRenderableVisitor->autoLights = doLightIteration; - mActiveQueuedRenderableVisitor->manualLightList = manualLightList; - mActiveQueuedRenderableVisitor->transparentShadowCastersMode = false; - mActiveQueuedRenderableVisitor->scissoring = lightScissoringClipping; - // Use visitor - objs.acceptVisitor(mActiveQueuedRenderableVisitor, om); + mActiveQueuedRenderableVisitor->autoLights = doLightIteration; + mActiveQueuedRenderableVisitor->manualLightList = manualLightList; + mActiveQueuedRenderableVisitor->transparentShadowCastersMode = false; + mActiveQueuedRenderableVisitor->scissoring = lightScissoringClipping; + // Use visitor + objs.acceptVisitor(mActiveQueuedRenderableVisitor, om); } //----------------------------------------------------------------------- void SceneManager::_renderQueueGroupObjects(RenderQueueGroup* pGroup, - QueuedRenderableCollection::OrganisationMode om) + QueuedRenderableCollection::OrganisationMode om) { - bool doShadows = - pGroup->getShadowsEnabled() && - mCurrentViewport->getShadowsEnabled() && - !mSuppressShadows && !mSuppressRenderStateChanges; - + bool doShadows = + pGroup->getShadowsEnabled() && + mCurrentViewport->getShadowsEnabled() && + !mSuppressShadows && !mSuppressRenderStateChanges; + if (doShadows && mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE) { // Additive stencil shadows in use @@ -3051,21 +3051,21 @@ void SceneManager::_renderQueueGroupObjects(RenderQueueGroup* pGroup, { // Ordinary + receiver pass if (doShadows && !isShadowTechniqueIntegrated()) - { - // Receiver pass(es) - if (isShadowTechniqueAdditive()) - { - // Auto-additive - renderAdditiveTextureShadowedQueueGroupObjects(pGroup, om); - } - else - { - // Modulative - renderModulativeTextureShadowedQueueGroupObjects(pGroup, om); - } - } - else - renderBasicQueueGroupObjects(pGroup, om); + { + // Receiver pass(es) + if (isShadowTechniqueAdditive()) + { + // Auto-additive + renderAdditiveTextureShadowedQueueGroupObjects(pGroup, om); + } + else + { + // Modulative + renderModulativeTextureShadowedQueueGroupObjects(pGroup, om); + } + } + else + renderBasicQueueGroupObjects(pGroup, om); } } else @@ -3078,7 +3078,7 @@ void SceneManager::_renderQueueGroupObjects(RenderQueueGroup* pGroup, } //----------------------------------------------------------------------- void SceneManager::renderBasicQueueGroupObjects(RenderQueueGroup* pGroup, - QueuedRenderableCollection::OrganisationMode om) + QueuedRenderableCollection::OrganisationMode om) { // Basic render loop // Iterate through priorities @@ -3093,37 +3093,37 @@ void SceneManager::renderBasicQueueGroupObjects(RenderQueueGroup* pGroup, // Do solids renderObjects(pPriorityGrp->getSolidsBasic(), om, true, true); - // Do unsorted transparents - renderObjects(pPriorityGrp->getTransparentsUnsorted(), om, true, true); + // Do unsorted transparents + renderObjects(pPriorityGrp->getTransparentsUnsorted(), om, true, true); // Do transparents (always descending) renderObjects(pPriorityGrp->getTransparents(), - QueuedRenderableCollection::OM_SORT_DESCENDING, true, true); + QueuedRenderableCollection::OM_SORT_DESCENDING, true, true); }// for each priority } //----------------------------------------------------------------------- void SceneManager::renderTransparentShadowCasterObjects( - const QueuedRenderableCollection& objs, - QueuedRenderableCollection::OrganisationMode om, bool lightScissoringClipping, - bool doLightIteration, - const LightList* manualLightList) -{ - mActiveQueuedRenderableVisitor->transparentShadowCastersMode = true; - mActiveQueuedRenderableVisitor->autoLights = doLightIteration; - mActiveQueuedRenderableVisitor->manualLightList = manualLightList; - mActiveQueuedRenderableVisitor->scissoring = lightScissoringClipping; - - // Sort descending (transparency) - objs.acceptVisitor(mActiveQueuedRenderableVisitor, - QueuedRenderableCollection::OM_SORT_DESCENDING); + const QueuedRenderableCollection& objs, + QueuedRenderableCollection::OrganisationMode om, bool lightScissoringClipping, + bool doLightIteration, + const LightList* manualLightList) +{ + mActiveQueuedRenderableVisitor->transparentShadowCastersMode = true; + mActiveQueuedRenderableVisitor->autoLights = doLightIteration; + mActiveQueuedRenderableVisitor->manualLightList = manualLightList; + mActiveQueuedRenderableVisitor->scissoring = lightScissoringClipping; + + // Sort descending (transparency) + objs.acceptVisitor(mActiveQueuedRenderableVisitor, + QueuedRenderableCollection::OM_SORT_DESCENDING); - mActiveQueuedRenderableVisitor->transparentShadowCastersMode = false; + mActiveQueuedRenderableVisitor->transparentShadowCastersMode = false; } //----------------------------------------------------------------------- void SceneManager::renderSingleObject(Renderable* rend, const Pass* pass, bool lightScissoringClipping, bool doLightIteration, - const LightList* manualLightList) + const LightList* manualLightList) { unsigned short numMatrices; RenderOperation ro; @@ -3131,47 +3131,47 @@ void SceneManager::renderSingleObject(Renderable* rend, const Pass* pass, OgreProfileBeginGPUEvent("Material: " + pass->getParent()->getParent()->getName()); ro.srcRenderable = rend; - GpuProgram* vprog = pass->hasVertexProgram() ? pass->getVertexProgram().get() : 0; + GpuProgram* vprog = pass->hasVertexProgram() ? pass->getVertexProgram().get() : 0; - bool passTransformState = true; + bool passTransformState = true; - if (vprog) - { - passTransformState = vprog->getPassTransformStates(); - } + if (vprog) + { + passTransformState = vprog->getPassTransformStates(); + } // Set world transformation numMatrices = rend->getNumWorldTransforms(); - - if (numMatrices > 0) - { - rend->getWorldTransforms(mTempXform); - - if (mCameraRelativeRendering && !rend->getUseIdentityView()) - { - for (unsigned short i = 0; i < numMatrices; ++i) - { - mTempXform[i].setTrans(mTempXform[i].getTrans() - mCameraRelativePosition); - } - } - - if (passTransformState) - { - if (numMatrices > 1) - { - mDestRenderSystem->_setWorldMatrices(mTempXform, numMatrices); - } - else - { - mDestRenderSystem->_setWorldMatrix(*mTempXform); - } - } - } + + if (numMatrices > 0) + { + rend->getWorldTransforms(mTempXform); + + if (mCameraRelativeRendering && !rend->getUseIdentityView()) + { + for (unsigned short i = 0; i < numMatrices; ++i) + { + mTempXform[i].setTrans(mTempXform[i].getTrans() - mCameraRelativePosition); + } + } + + if (passTransformState) + { + if (numMatrices > 1) + { + mDestRenderSystem->_setWorldMatrices(mTempXform, numMatrices); + } + else + { + mDestRenderSystem->_setWorldMatrix(*mTempXform); + } + } + } // Issue view / projection changes if any - useRenderableViewProjMode(rend, passTransformState); + useRenderableViewProjMode(rend, passTransformState); - // mark per-object params as dirty - mGpuParamsDirty |= (uint16)GPV_PER_OBJECT; + // mark per-object params as dirty + mGpuParamsDirty |= (uint16)GPV_PER_OBJECT; if (!mSuppressRenderStateChanges) { @@ -3183,10 +3183,10 @@ void SceneManager::renderSingleObject(Renderable* rend, const Pass* pass, mAutoParamDataSource->setCurrentRenderable(rend); // Tell auto params object about the world matrices, eliminated query from renderable again mAutoParamDataSource->setWorldMatrices(mTempXform, numMatrices); - if (vprog) - { - passSurfaceAndLightParams = vprog->getPassSurfaceAndLightStates(); - } + if (vprog) + { + passSurfaceAndLightParams = vprog->getPassSurfaceAndLightStates(); + } } // Reissue any texture gen settings which are dependent on view matrix @@ -3203,396 +3203,396 @@ void SceneManager::renderSingleObject(Renderable* rend, const Pass* pass, } // Sort out normalisation - // Assume first world matrix representative - shaders that use multiple - // matrices should control renormalisation themselves - if ((pass->getNormaliseNormals() || mNormaliseNormalsOnScale) - && mTempXform[0].hasScale()) - mDestRenderSystem->setNormaliseNormals(true); - else - mDestRenderSystem->setNormaliseNormals(false); - - // Sort out negative scaling - // Assume first world matrix representative - if (mFlipCullingOnNegativeScale) - { - CullingMode cullMode = mPassCullingMode; - - if (mTempXform[0].hasNegativeScale()) - { - switch(mPassCullingMode) - { - case CULL_CLOCKWISE: - cullMode = CULL_ANTICLOCKWISE; - break; - case CULL_ANTICLOCKWISE: - cullMode = CULL_CLOCKWISE; - break; + // Assume first world matrix representative - shaders that use multiple + // matrices should control renormalisation themselves + if ((pass->getNormaliseNormals() || mNormaliseNormalsOnScale) + && mTempXform[0].hasScale()) + mDestRenderSystem->setNormaliseNormals(true); + else + mDestRenderSystem->setNormaliseNormals(false); + + // Sort out negative scaling + // Assume first world matrix representative + if (mFlipCullingOnNegativeScale) + { + CullingMode cullMode = mPassCullingMode; + + if (mTempXform[0].hasNegativeScale()) + { + switch(mPassCullingMode) + { + case CULL_CLOCKWISE: + cullMode = CULL_ANTICLOCKWISE; + break; + case CULL_ANTICLOCKWISE: + cullMode = CULL_CLOCKWISE; + break; case CULL_NONE: break; - }; - } - - // this also copes with returning from negative scale in previous render op - // for same pass - if (cullMode != mDestRenderSystem->_getCullingMode()) - mDestRenderSystem->_setCullingMode(cullMode); - } - - // Set up the solid / wireframe override - // Precedence is Camera, Object, Material - // Camera might not override object if not overrideable - PolygonMode reqMode = pass->getPolygonMode(); - if (pass->getPolygonModeOverrideable() && rend->getPolygonModeOverrideable()) - { + }; + } + + // this also copes with returning from negative scale in previous render op + // for same pass + if (cullMode != mDestRenderSystem->_getCullingMode()) + mDestRenderSystem->_setCullingMode(cullMode); + } + + // Set up the solid / wireframe override + // Precedence is Camera, Object, Material + // Camera might not override object if not overrideable + PolygonMode reqMode = pass->getPolygonMode(); + if (pass->getPolygonModeOverrideable() && rend->getPolygonModeOverrideable()) + { PolygonMode camPolyMode = mCameraInProgress->getPolygonMode(); - // check camera detial only when render detail is overridable - if (reqMode > camPolyMode) - { - // only downgrade detail; if cam says wireframe we don't go up to solid - reqMode = camPolyMode; - } - } - mDestRenderSystem->_setPolygonMode(reqMode); - - if (doLightIteration) - { + // check camera detial only when render detail is overridable + if (reqMode > camPolyMode) + { + // only downgrade detail; if cam says wireframe we don't go up to solid + reqMode = camPolyMode; + } + } + mDestRenderSystem->_setPolygonMode(reqMode); + + if (doLightIteration) + { // Create local light list for faster light iteration setup static LightList localLightList; - // Here's where we issue the rendering operation to the render system - // Note that we may do this once per light, therefore it's in a loop - // and the light parameters are updated once per traversal through the - // loop - const LightList& rendLightList = rend->getLights(); - - bool iteratePerLight = pass->getIteratePerLight(); - - // deliberately unsigned in case start light exceeds number of lights - // in which case this pass would be skipped - int lightsLeft = 1; - if (iteratePerLight) - { - lightsLeft = static_cast(rendLightList.size()) - pass->getStartLight(); - // Don't allow total light count for all iterations to exceed max per pass - if (lightsLeft > static_cast(pass->getMaxSimultaneousLights())) - { - lightsLeft = static_cast(pass->getMaxSimultaneousLights()); - } - } - - - const LightList* pLightListToUse; - // Start counting from the start light - size_t lightIndex = pass->getStartLight(); - size_t depthInc = 0; - - while (lightsLeft > 0) - { - // Determine light list to use - if (iteratePerLight) - { - // Starting shadow texture index. - size_t shadowTexIndex = mShadowTextures.size(); - if (mShadowTextureIndexLightList.size() > lightIndex) - shadowTexIndex = mShadowTextureIndexLightList[lightIndex]; - - localLightList.resize(pass->getLightCountPerIteration()); - - LightList::iterator destit = localLightList.begin(); - unsigned short numShadowTextureLights = 0; - for (; destit != localLightList.end() - && lightIndex < rendLightList.size(); - ++lightIndex, --lightsLeft) - { - Light* currLight = rendLightList[lightIndex]; - - // Check whether we need to filter this one out - if ((pass->getRunOnlyForOneLightType() && - pass->getOnlyLightType() != currLight->getType()) || - (pass->getLightMask() & currLight->getLightMask()) == 0) - { - // Skip - // Also skip shadow texture(s) - if (isShadowTechniqueTextureBased()) - { - shadowTexIndex += mShadowTextureCountPerType[currLight->getType()]; - } - continue; - } - - *destit++ = currLight; - - // potentially need to update content_type shadow texunit - // corresponding to this light - if (isShadowTechniqueTextureBased()) - { - size_t textureCountPerLight = mShadowTextureCountPerType[currLight->getType()]; - for (size_t j = 0; j < textureCountPerLight && shadowTexIndex < mShadowTextures.size(); ++j) - { - // link the numShadowTextureLights'th shadow texture unit - unsigned short tuindex = - pass->_getTextureUnitWithContentTypeIndex( - TextureUnitState::CONTENT_SHADOW, numShadowTextureLights); - if (tuindex > pass->getNumTextureUnitStates()) break; - - // I know, nasty const_cast - TextureUnitState* tu = - const_cast( - pass->getTextureUnitState(tuindex)); - const TexturePtr& shadowTex = mShadowTextures[shadowTexIndex]; - tu->_setTexturePtr(shadowTex); - Camera *cam = shadowTex->getBuffer()->getRenderTarget()->getViewport(0)->getCamera(); - tu->setProjectiveTexturing(!pass->hasVertexProgram(), cam); - mAutoParamDataSource->setTextureProjector(cam, numShadowTextureLights); - ++numShadowTextureLights; - ++shadowTexIndex; - // Have to set TU on rendersystem right now, although - // autoparams will be set later - mDestRenderSystem->_setTextureUnitSettings(tuindex, *tu); - } - } - - - - } - // Did we run out of lights before slots? e.g. 5 lights, 2 per iteration - if (destit != localLightList.end()) - { - localLightList.erase(destit, localLightList.end()); - lightsLeft = 0; - } - pLightListToUse = &localLightList; - - // deal with the case where we found no lights - // since this is light iteration, we shouldn't render at all - if (pLightListToUse->empty()) - return; - - } - else // !iterate per light - { - // Use complete light list potentially adjusted by start light - if (pass->getStartLight() || pass->getMaxSimultaneousLights() != OGRE_MAX_SIMULTANEOUS_LIGHTS || - pass->getLightMask() != 0xFFFFFFFF) - { - // out of lights? - // skip manual 2nd lighting passes onwards if we run out of lights, but never the first one - if (pass->getStartLight() > 0 && - pass->getStartLight() >= rendLightList.size()) - { - break; - } - else - { - localLightList.clear(); - LightList::const_iterator copyStart = rendLightList.begin(); - std::advance(copyStart, pass->getStartLight()); - // Clamp lights to copy to avoid overrunning the end of the list - size_t lightsCopied = 0, lightsToCopy = std::min( - static_cast(pass->getMaxSimultaneousLights()), - rendLightList.size() - pass->getStartLight()); - - //localLightList.insert(localLightList.begin(), - // copyStart, copyEnd); - - // Copy lights over - for(LightList::const_iterator iter = copyStart; iter != rendLightList.end() && lightsCopied < lightsToCopy; ++iter) - { - if((pass->getLightMask() & (*iter)->getLightMask()) != 0) - { - localLightList.push_back(*iter); - lightsCopied++; - } - } - - pLightListToUse = &localLightList; - } - } - else - { - pLightListToUse = &rendLightList; - } - lightsLeft = 0; - } - - fireRenderSingleObject(rend, pass, mAutoParamDataSource, pLightListToUse, mSuppressRenderStateChanges); - - // Do we need to update GPU program parameters? - if (pass->isProgrammable()) - { - useLightsGpuProgram(pass, pLightListToUse); - } - // Do we need to update light states? - // Only do this if fixed-function vertex lighting applies - if (pass->getLightingEnabled() && passSurfaceAndLightParams) - { - useLights(*pLightListToUse, pass->getMaxSimultaneousLights()); - } - // optional light scissoring & clipping - ClipResult scissored = CLIPPED_NONE; - ClipResult clipped = CLIPPED_NONE; - if (lightScissoringClipping && - (pass->getLightScissoringEnabled() || pass->getLightClipPlanesEnabled())) - { - // if there's no lights hitting the scene, then we might as - // well stop since clipping cannot include anything - if (pLightListToUse->empty()) - continue; - - if (pass->getLightScissoringEnabled()) - scissored = buildAndSetScissor(*pLightListToUse, mCameraInProgress); - - if (pass->getLightClipPlanesEnabled()) - clipped = buildAndSetLightClip(*pLightListToUse); - - if (scissored == CLIPPED_ALL || clipped == CLIPPED_ALL) - continue; - } - // issue the render op - // nfz: check for gpu_multipass - mDestRenderSystem->setCurrentPassIterationCount(pass->getPassIterationCount()); - // We might need to update the depth bias each iteration - if (pass->getIterationDepthBias() != 0.0f) - { - float depthBiasBase = pass->getDepthBiasConstant() + - pass->getIterationDepthBias() * depthInc; - // depthInc deals with light iteration - - // Note that we have to set the depth bias here even if the depthInc - // is zero (in which case you would think there is no change from - // what was set in _setPass(). The reason is that if there are - // multiple Renderables with this Pass, we won't go through _setPass - // again at the start of the iteration for the next Renderable - // because of Pass state grouping. So set it always - - // Set modified depth bias right away - mDestRenderSystem->_setDepthBias(depthBiasBase, pass->getDepthBiasSlopeScale()); - - // Set to increment internally too if rendersystem iterates - mDestRenderSystem->setDeriveDepthBias(true, - depthBiasBase, pass->getIterationDepthBias(), - pass->getDepthBiasSlopeScale()); - } - else - { - mDestRenderSystem->setDeriveDepthBias(false); - } - depthInc += pass->getPassIterationCount(); - - // Finalise GPU parameter bindings - updateGpuProgramParameters(pass); + // Here's where we issue the rendering operation to the render system + // Note that we may do this once per light, therefore it's in a loop + // and the light parameters are updated once per traversal through the + // loop + const LightList& rendLightList = rend->getLights(); + + bool iteratePerLight = pass->getIteratePerLight(); + + // deliberately unsigned in case start light exceeds number of lights + // in which case this pass would be skipped + int lightsLeft = 1; + if (iteratePerLight) + { + lightsLeft = static_cast(rendLightList.size()) - pass->getStartLight(); + // Don't allow total light count for all iterations to exceed max per pass + if (lightsLeft > static_cast(pass->getMaxSimultaneousLights())) + { + lightsLeft = static_cast(pass->getMaxSimultaneousLights()); + } + } + + + const LightList* pLightListToUse; + // Start counting from the start light + size_t lightIndex = pass->getStartLight(); + size_t depthInc = 0; + + while (lightsLeft > 0) + { + // Determine light list to use + if (iteratePerLight) + { + // Starting shadow texture index. + size_t shadowTexIndex = mShadowTextures.size(); + if (mShadowTextureIndexLightList.size() > lightIndex) + shadowTexIndex = mShadowTextureIndexLightList[lightIndex]; + + localLightList.resize(pass->getLightCountPerIteration()); + + LightList::iterator destit = localLightList.begin(); + unsigned short numShadowTextureLights = 0; + for (; destit != localLightList.end() + && lightIndex < rendLightList.size(); + ++lightIndex, --lightsLeft) + { + Light* currLight = rendLightList[lightIndex]; + + // Check whether we need to filter this one out + if ((pass->getRunOnlyForOneLightType() && + pass->getOnlyLightType() != currLight->getType()) || + (pass->getLightMask() & currLight->getLightMask()) == 0) + { + // Skip + // Also skip shadow texture(s) + if (isShadowTechniqueTextureBased()) + { + shadowTexIndex += mShadowTextureCountPerType[currLight->getType()]; + } + continue; + } + + *destit++ = currLight; + + // potentially need to update content_type shadow texunit + // corresponding to this light + if (isShadowTechniqueTextureBased()) + { + size_t textureCountPerLight = mShadowTextureCountPerType[currLight->getType()]; + for (size_t j = 0; j < textureCountPerLight && shadowTexIndex < mShadowTextures.size(); ++j) + { + // link the numShadowTextureLights'th shadow texture unit + unsigned short tuindex = + pass->_getTextureUnitWithContentTypeIndex( + TextureUnitState::CONTENT_SHADOW, numShadowTextureLights); + if (tuindex > pass->getNumTextureUnitStates()) break; + + // I know, nasty const_cast + TextureUnitState* tu = + const_cast( + pass->getTextureUnitState(tuindex)); + const TexturePtr& shadowTex = mShadowTextures[shadowTexIndex]; + tu->_setTexturePtr(shadowTex); + Camera *cam = shadowTex->getBuffer()->getRenderTarget()->getViewport(0)->getCamera(); + tu->setProjectiveTexturing(!pass->hasVertexProgram(), cam); + mAutoParamDataSource->setTextureProjector(cam, numShadowTextureLights); + ++numShadowTextureLights; + ++shadowTexIndex; + // Have to set TU on rendersystem right now, although + // autoparams will be set later + mDestRenderSystem->_setTextureUnitSettings(tuindex, *tu); + } + } + + + + } + // Did we run out of lights before slots? e.g. 5 lights, 2 per iteration + if (destit != localLightList.end()) + { + localLightList.erase(destit, localLightList.end()); + lightsLeft = 0; + } + pLightListToUse = &localLightList; + + // deal with the case where we found no lights + // since this is light iteration, we shouldn't render at all + if (pLightListToUse->empty()) + return; + + } + else // !iterate per light + { + // Use complete light list potentially adjusted by start light + if (pass->getStartLight() || pass->getMaxSimultaneousLights() != OGRE_MAX_SIMULTANEOUS_LIGHTS || + pass->getLightMask() != 0xFFFFFFFF) + { + // out of lights? + // skip manual 2nd lighting passes onwards if we run out of lights, but never the first one + if (pass->getStartLight() > 0 && + pass->getStartLight() >= rendLightList.size()) + { + break; + } + else + { + localLightList.clear(); + LightList::const_iterator copyStart = rendLightList.begin(); + std::advance(copyStart, pass->getStartLight()); + // Clamp lights to copy to avoid overrunning the end of the list + size_t lightsCopied = 0, lightsToCopy = std::min( + static_cast(pass->getMaxSimultaneousLights()), + rendLightList.size() - pass->getStartLight()); + + //localLightList.insert(localLightList.begin(), + // copyStart, copyEnd); + + // Copy lights over + for(LightList::const_iterator iter = copyStart; iter != rendLightList.end() && lightsCopied < lightsToCopy; ++iter) + { + if((pass->getLightMask() & (*iter)->getLightMask()) != 0) + { + localLightList.push_back(*iter); + lightsCopied++; + } + } + + pLightListToUse = &localLightList; + } + } + else + { + pLightListToUse = &rendLightList; + } + lightsLeft = 0; + } + + fireRenderSingleObject(rend, pass, mAutoParamDataSource, pLightListToUse, mSuppressRenderStateChanges); + + // Do we need to update GPU program parameters? + if (pass->isProgrammable()) + { + useLightsGpuProgram(pass, pLightListToUse); + } + // Do we need to update light states? + // Only do this if fixed-function vertex lighting applies + if (pass->getLightingEnabled() && passSurfaceAndLightParams) + { + useLights(*pLightListToUse, pass->getMaxSimultaneousLights()); + } + // optional light scissoring & clipping + ClipResult scissored = CLIPPED_NONE; + ClipResult clipped = CLIPPED_NONE; + if (lightScissoringClipping && + (pass->getLightScissoringEnabled() || pass->getLightClipPlanesEnabled())) + { + // if there's no lights hitting the scene, then we might as + // well stop since clipping cannot include anything + if (pLightListToUse->empty()) + continue; + + if (pass->getLightScissoringEnabled()) + scissored = buildAndSetScissor(*pLightListToUse, mCameraInProgress); + + if (pass->getLightClipPlanesEnabled()) + clipped = buildAndSetLightClip(*pLightListToUse); + + if (scissored == CLIPPED_ALL || clipped == CLIPPED_ALL) + continue; + } + // issue the render op + // nfz: check for gpu_multipass + mDestRenderSystem->setCurrentPassIterationCount(pass->getPassIterationCount()); + // We might need to update the depth bias each iteration + if (pass->getIterationDepthBias() != 0.0f) + { + float depthBiasBase = pass->getDepthBiasConstant() + + pass->getIterationDepthBias() * depthInc; + // depthInc deals with light iteration + + // Note that we have to set the depth bias here even if the depthInc + // is zero (in which case you would think there is no change from + // what was set in _setPass(). The reason is that if there are + // multiple Renderables with this Pass, we won't go through _setPass + // again at the start of the iteration for the next Renderable + // because of Pass state grouping. So set it always + + // Set modified depth bias right away + mDestRenderSystem->_setDepthBias(depthBiasBase, pass->getDepthBiasSlopeScale()); + + // Set to increment internally too if rendersystem iterates + mDestRenderSystem->setDeriveDepthBias(true, + depthBiasBase, pass->getIterationDepthBias(), + pass->getDepthBiasSlopeScale()); + } + else + { + mDestRenderSystem->setDeriveDepthBias(false); + } + depthInc += pass->getPassIterationCount(); + + // Finalise GPU parameter bindings + updateGpuProgramParameters(pass); rend->getRenderOperation(ro); - if (rend->preRender(this, mDestRenderSystem)) - mDestRenderSystem->_render(ro); - rend->postRender(this, mDestRenderSystem); - - if (scissored == CLIPPED_SOME) - resetScissor(); - if (clipped == CLIPPED_SOME) - resetLightClip(); - } // possibly iterate per light - } - else // no automatic light processing - { - // Even if manually driving lights, check light type passes - bool skipBecauseOfLightType = false; - if (pass->getRunOnlyForOneLightType()) - { - if (!manualLightList || - (manualLightList->size() == 1 && - manualLightList->at(0)->getType() != pass->getOnlyLightType())) - { - skipBecauseOfLightType = true; - } - } - - if (!skipBecauseOfLightType) - { - fireRenderSingleObject(rend, pass, mAutoParamDataSource, manualLightList, mSuppressRenderStateChanges); - // Do we need to update GPU program parameters? - if (pass->isProgrammable()) - { - // Do we have a manual light list? - if (manualLightList) - { - useLightsGpuProgram(pass, manualLightList); - } - - } - - // Use manual lights if present, and not using vertex programs that don't use fixed pipeline - if (manualLightList && - pass->getLightingEnabled() && passSurfaceAndLightParams) - { - useLights(*manualLightList, pass->getMaxSimultaneousLights()); - } - - // optional light scissoring - ClipResult scissored = CLIPPED_NONE; - ClipResult clipped = CLIPPED_NONE; - if (lightScissoringClipping && manualLightList && pass->getLightScissoringEnabled()) - { - scissored = buildAndSetScissor(*manualLightList, mCameraInProgress); - } - if (lightScissoringClipping && manualLightList && pass->getLightClipPlanesEnabled()) - { - clipped = buildAndSetLightClip(*manualLightList); - } - - // don't bother rendering if clipped / scissored entirely - if (scissored != CLIPPED_ALL && clipped != CLIPPED_ALL) - { - // issue the render op - // nfz: set up multipass rendering - mDestRenderSystem->setCurrentPassIterationCount(pass->getPassIterationCount()); - // Finalise GPU parameter bindings - updateGpuProgramParameters(pass); + if (rend->preRender(this, mDestRenderSystem)) + mDestRenderSystem->_render(ro); + rend->postRender(this, mDestRenderSystem); + + if (scissored == CLIPPED_SOME) + resetScissor(); + if (clipped == CLIPPED_SOME) + resetLightClip(); + } // possibly iterate per light + } + else // no automatic light processing + { + // Even if manually driving lights, check light type passes + bool skipBecauseOfLightType = false; + if (pass->getRunOnlyForOneLightType()) + { + if (!manualLightList || + (manualLightList->size() == 1 && + manualLightList->at(0)->getType() != pass->getOnlyLightType())) + { + skipBecauseOfLightType = true; + } + } + + if (!skipBecauseOfLightType) + { + fireRenderSingleObject(rend, pass, mAutoParamDataSource, manualLightList, mSuppressRenderStateChanges); + // Do we need to update GPU program parameters? + if (pass->isProgrammable()) + { + // Do we have a manual light list? + if (manualLightList) + { + useLightsGpuProgram(pass, manualLightList); + } + + } + + // Use manual lights if present, and not using vertex programs that don't use fixed pipeline + if (manualLightList && + pass->getLightingEnabled() && passSurfaceAndLightParams) + { + useLights(*manualLightList, pass->getMaxSimultaneousLights()); + } + + // optional light scissoring + ClipResult scissored = CLIPPED_NONE; + ClipResult clipped = CLIPPED_NONE; + if (lightScissoringClipping && manualLightList && pass->getLightScissoringEnabled()) + { + scissored = buildAndSetScissor(*manualLightList, mCameraInProgress); + } + if (lightScissoringClipping && manualLightList && pass->getLightClipPlanesEnabled()) + { + clipped = buildAndSetLightClip(*manualLightList); + } + + // don't bother rendering if clipped / scissored entirely + if (scissored != CLIPPED_ALL && clipped != CLIPPED_ALL) + { + // issue the render op + // nfz: set up multipass rendering + mDestRenderSystem->setCurrentPassIterationCount(pass->getPassIterationCount()); + // Finalise GPU parameter bindings + updateGpuProgramParameters(pass); rend->getRenderOperation(ro); - if (rend->preRender(this, mDestRenderSystem)) - mDestRenderSystem->_render(ro); - rend->postRender(this, mDestRenderSystem); - } - if (scissored == CLIPPED_SOME) - resetScissor(); - if (clipped == CLIPPED_SOME) - resetLightClip(); - - } // !skipBecauseOfLightType - } - - } - else // mSuppressRenderStateChanges - { - fireRenderSingleObject(rend, pass, mAutoParamDataSource, NULL, mSuppressRenderStateChanges); - // Just render - mDestRenderSystem->setCurrentPassIterationCount(1); - if (rend->preRender(this, mDestRenderSystem)) - { - rend->getRenderOperation(ro); - try - { - mDestRenderSystem->_render(ro); - } - catch (RenderingAPIException& e) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + if (rend->preRender(this, mDestRenderSystem)) + mDestRenderSystem->_render(ro); + rend->postRender(this, mDestRenderSystem); + } + if (scissored == CLIPPED_SOME) + resetScissor(); + if (clipped == CLIPPED_SOME) + resetLightClip(); + + } // !skipBecauseOfLightType + } + + } + else // mSuppressRenderStateChanges + { + fireRenderSingleObject(rend, pass, mAutoParamDataSource, NULL, mSuppressRenderStateChanges); + // Just render + mDestRenderSystem->setCurrentPassIterationCount(1); + if (rend->preRender(this, mDestRenderSystem)) + { + rend->getRenderOperation(ro); + try + { + mDestRenderSystem->_render(ro); + } + catch (RenderingAPIException& e) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Exception when rendering material: " + pass->getParent()->getParent()->getName() + "\nOriginal Exception description: " + e.getFullDescription() + "\n" , "SceneManager::renderSingleObject"); - } - } - rend->postRender(this, mDestRenderSystem); - } - - // Reset view / projection changes if any - resetViewProjMode(passTransformState); - OgreProfileEndGPUEvent("Material: " + pass->getParent()->getParent()->getName()); + } + } + rend->postRender(this, mDestRenderSystem); + } + + // Reset view / projection changes if any + resetViewProjMode(passTransformState); + OgreProfileEndGPUEvent("Material: " + pass->getParent()->getParent()->getName()); } //----------------------------------------------------------------------- void SceneManager::setAmbientLight(const ColourValue& colour) @@ -3650,38 +3650,38 @@ Real SceneManager::getFogDensity(void) const //----------------------------------------------------------------------- BillboardSet* SceneManager::createBillboardSet(const String& name, unsigned int poolSize) { - NameValuePairList params; - params["poolSize"] = StringConverter::toString(poolSize); - return static_cast( - createMovableObject(name, BillboardSetFactory::FACTORY_TYPE_NAME, ¶ms)); + NameValuePairList params; + params["poolSize"] = StringConverter::toString(poolSize); + return static_cast( + createMovableObject(name, BillboardSetFactory::FACTORY_TYPE_NAME, ¶ms)); } //----------------------------------------------------------------------- BillboardSet* SceneManager::createBillboardSet(unsigned int poolSize) { - String name = mMovableNameGenerator.generate(); - return createBillboardSet(name, poolSize); + String name = mMovableNameGenerator.generate(); + return createBillboardSet(name, poolSize); } //----------------------------------------------------------------------- BillboardSet* SceneManager::getBillboardSet(const String& name) const { - return static_cast( - getMovableObject(name, BillboardSetFactory::FACTORY_TYPE_NAME)); + return static_cast( + getMovableObject(name, BillboardSetFactory::FACTORY_TYPE_NAME)); } //----------------------------------------------------------------------- bool SceneManager::hasBillboardSet(const String& name) const { - return hasMovableObject(name, BillboardSetFactory::FACTORY_TYPE_NAME); + return hasMovableObject(name, BillboardSetFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::destroyBillboardSet(BillboardSet* set) { - destroyMovableObject(set); + destroyMovableObject(set); } //----------------------------------------------------------------------- void SceneManager::destroyBillboardSet(const String& name) { - destroyMovableObject(name, BillboardSetFactory::FACTORY_TYPE_NAME); + destroyMovableObject(name, BillboardSetFactory::FACTORY_TYPE_NAME); } //----------------------------------------------------------------------- void SceneManager::setDisplaySceneNodes(bool display) @@ -3711,7 +3711,7 @@ Animation* SceneManager::getAnimation(const String& name) const { OGRE_LOCK_MUTEX(mAnimationsListMutex); - AnimationList::const_iterator i = mAnimationsList.find(name); + AnimationList::const_iterator i = mAnimationsList.find(name); if (i == mAnimationsList.end()) { OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, @@ -3724,28 +3724,28 @@ Animation* SceneManager::getAnimation(const String& name) const bool SceneManager::hasAnimation(const String& name) const { OGRE_LOCK_MUTEX(mAnimationsListMutex); - return (mAnimationsList.find(name) != mAnimationsList.end()); + return (mAnimationsList.find(name) != mAnimationsList.end()); } //----------------------------------------------------------------------- void SceneManager::destroyAnimation(const String& name) { OGRE_LOCK_MUTEX(mAnimationsListMutex); - // Also destroy any animation states referencing this animation - mAnimationStates.removeAnimationState(name); + // Also destroy any animation states referencing this animation + mAnimationStates.removeAnimationState(name); - AnimationList::iterator i = mAnimationsList.find(name); - if (i == mAnimationsList.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find animation with name " + name, - "SceneManager::getAnimation"); - } + AnimationList::iterator i = mAnimationsList.find(name); + if (i == mAnimationsList.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find animation with name " + name, + "SceneManager::getAnimation"); + } - // Free memory - OGRE_DELETE i->second; + // Free memory + OGRE_DELETE i->second; - mAnimationsList.erase(i); + mAnimationsList.erase(i); } //----------------------------------------------------------------------- @@ -3755,13 +3755,13 @@ void SceneManager::destroyAllAnimations(void) // Destroy all states too, since they cannot reference destroyed animations destroyAllAnimationStates(); - AnimationList::iterator i; - for (i = mAnimationsList.begin(); i != mAnimationsList.end(); ++i) - { - // destroy - OGRE_DELETE i->second; - } - mAnimationsList.clear(); + AnimationList::iterator i; + for (i = mAnimationsList.begin(); i != mAnimationsList.end(); ++i) + { + // destroy + OGRE_DELETE i->second; + } + mAnimationsList.clear(); } //----------------------------------------------------------------------- AnimationState* SceneManager::createAnimationState(const String& animName) @@ -3770,24 +3770,24 @@ AnimationState* SceneManager::createAnimationState(const String& animName) Animation* anim = getAnimation(animName); // Create new state - return mAnimationStates.createAnimationState(animName, 0, anim->getLength()); + return mAnimationStates.createAnimationState(animName, 0, anim->getLength()); } //----------------------------------------------------------------------- AnimationState* SceneManager::getAnimationState(const String& animName) const { - return mAnimationStates.getAnimationState(animName); + return mAnimationStates.getAnimationState(animName); } //----------------------------------------------------------------------- bool SceneManager::hasAnimationState(const String& name) const { - return mAnimationStates.hasAnimationState(name); + return mAnimationStates.hasAnimationState(name); } //----------------------------------------------------------------------- void SceneManager::destroyAnimationState(const String& name) { - mAnimationStates.removeAnimationState(name); + mAnimationStates.removeAnimationState(name); } //----------------------------------------------------------------------- void SceneManager::destroyAllAnimationStates(void) @@ -3797,10 +3797,10 @@ void SceneManager::destroyAllAnimationStates(void) //----------------------------------------------------------------------- void SceneManager::_applySceneAnimations(void) { - // manual lock over states (extended duration required) + // manual lock over states (extended duration required) OGRE_LOCK_MUTEX(mAnimationStates.OGRE_AUTO_MUTEX_NAME); - // Iterate twice, once to reset, once to apply, to allow blending + // Iterate twice, once to reset, once to apply, to allow blending ConstEnabledAnimationStateIterator stateIt = mAnimationStates.getEnabledAnimationStateIterator(); while (stateIt.hasMoreElements()) @@ -3813,28 +3813,28 @@ void SceneManager::_applySceneAnimations(void) while(nodeTrackIt.hasMoreElements()) { Node* nd = nodeTrackIt.getNext()->getAssociatedNode(); - if (nd) - nd->resetToInitialState(); + if (nd) + nd->resetToInitialState(); } Animation::NumericTrackIterator numTrackIt = anim->getNumericTrackIterator(); while(numTrackIt.hasMoreElements()) { const AnimableValuePtr& animPtr = numTrackIt.getNext()->getAssociatedAnimable(); - if (!animPtr.isNull()) - animPtr->resetToBaseValue(); + if (!animPtr.isNull()) + animPtr->resetToBaseValue(); } } - // this should allow blended animations - stateIt = mAnimationStates.getEnabledAnimationStateIterator(); - while (stateIt.hasMoreElements()) - { - const AnimationState* state = stateIt.getNext(); - Animation* anim = getAnimation(state->getAnimationName()); - // Apply the animation - anim->apply(state->getTimePosition(), state->getWeight()); - } + // this should allow blended animations + stateIt = mAnimationStates.getEnabledAnimationStateIterator(); + while (stateIt.hasMoreElements()) + { + const AnimationState* state = stateIt.getNext(); + Animation* anim = getAnimation(state->getAnimationName()); + // Apply the animation + anim->apply(state->getTimePosition(), state->getWeight()); + } } //--------------------------------------------------------------------- void SceneManager::manualRender(RenderOperation* rend, @@ -3842,33 +3842,33 @@ void SceneManager::manualRender(RenderOperation* rend, const Matrix4& viewMatrix, const Matrix4& projMatrix, bool doBeginEndFrame) { - if (vp) - mDestRenderSystem->_setViewport(vp); + if (vp) + mDestRenderSystem->_setViewport(vp); if (doBeginEndFrame) mDestRenderSystem->_beginFrame(); - mDestRenderSystem->_setWorldMatrix(worldMatrix); - setViewMatrix(viewMatrix); - mDestRenderSystem->_setProjectionMatrix(projMatrix); - - _setPass(pass); - // Do we need to update GPU program parameters? - if (pass->isProgrammable()) - { - if (vp) - { - mAutoParamDataSource->setCurrentViewport(vp); - mAutoParamDataSource->setCurrentRenderTarget(vp->getTarget()); - } - mAutoParamDataSource->setCurrentSceneManager(this); - mAutoParamDataSource->setWorldMatrices(&worldMatrix, 1); - Camera dummyCam(BLANKSTRING, 0); - dummyCam.setCustomViewMatrix(true, viewMatrix); - dummyCam.setCustomProjectionMatrix(true, projMatrix); - mAutoParamDataSource->setCurrentCamera(&dummyCam, false); - updateGpuProgramParameters(pass); - } + mDestRenderSystem->_setWorldMatrix(worldMatrix); + setViewMatrix(viewMatrix); + mDestRenderSystem->_setProjectionMatrix(projMatrix); + + _setPass(pass); + // Do we need to update GPU program parameters? + if (pass->isProgrammable()) + { + if (vp) + { + mAutoParamDataSource->setCurrentViewport(vp); + mAutoParamDataSource->setCurrentRenderTarget(vp->getTarget()); + } + mAutoParamDataSource->setCurrentSceneManager(this); + mAutoParamDataSource->setWorldMatrices(&worldMatrix, 1); + Camera dummyCam(BLANKSTRING, 0); + dummyCam.setCustomViewMatrix(true, viewMatrix); + dummyCam.setCustomProjectionMatrix(true, projMatrix); + mAutoParamDataSource->setCurrentCamera(&dummyCam, false); + updateGpuProgramParameters(pass); + } mDestRenderSystem->_render(*rend); if (doBeginEndFrame) @@ -3877,42 +3877,42 @@ void SceneManager::manualRender(RenderOperation* rend, } //--------------------------------------------------------------------- void SceneManager::manualRender(Renderable* rend, const Pass* pass, Viewport* vp, - const Matrix4& viewMatrix, - const Matrix4& projMatrix,bool doBeginEndFrame, - bool lightScissoringClipping, bool doLightIteration, const LightList* manualLightList) + const Matrix4& viewMatrix, + const Matrix4& projMatrix,bool doBeginEndFrame, + bool lightScissoringClipping, bool doLightIteration, const LightList* manualLightList) { - if (vp) - mDestRenderSystem->_setViewport(vp); + if (vp) + mDestRenderSystem->_setViewport(vp); - if (doBeginEndFrame) - mDestRenderSystem->_beginFrame(); + if (doBeginEndFrame) + mDestRenderSystem->_beginFrame(); - setViewMatrix(viewMatrix); - mDestRenderSystem->_setProjectionMatrix(projMatrix); + setViewMatrix(viewMatrix); + mDestRenderSystem->_setProjectionMatrix(projMatrix); - _setPass(pass); - Camera dummyCam(BLANKSTRING, 0); - dummyCam.setCustomViewMatrix(true, viewMatrix); - dummyCam.setCustomProjectionMatrix(true, projMatrix); - // Do we need to update GPU program parameters? - if (pass->isProgrammable()) - { - if (vp) - { - mAutoParamDataSource->setCurrentViewport(vp); - mAutoParamDataSource->setCurrentRenderTarget(vp->getTarget()); - } - mAutoParamDataSource->setCurrentSceneManager(this); - mAutoParamDataSource->setCurrentCamera(&dummyCam, false); - updateGpuProgramParameters(pass); - } - if (vp) - mCurrentViewport = vp; - renderSingleObject(rend, pass, lightScissoringClipping, doLightIteration, manualLightList); + _setPass(pass); + Camera dummyCam(BLANKSTRING, 0); + dummyCam.setCustomViewMatrix(true, viewMatrix); + dummyCam.setCustomProjectionMatrix(true, projMatrix); + // Do we need to update GPU program parameters? + if (pass->isProgrammable()) + { + if (vp) + { + mAutoParamDataSource->setCurrentViewport(vp); + mAutoParamDataSource->setCurrentRenderTarget(vp->getTarget()); + } + mAutoParamDataSource->setCurrentSceneManager(this); + mAutoParamDataSource->setCurrentCamera(&dummyCam, false); + updateGpuProgramParameters(pass); + } + if (vp) + mCurrentViewport = vp; + renderSingleObject(rend, pass, lightScissoringClipping, doLightIteration, manualLightList); - if (doBeginEndFrame) - mDestRenderSystem->_endFrame(); + if (doBeginEndFrame) + mDestRenderSystem->_endFrame(); } //--------------------------------------------------------------------- @@ -3923,9 +3923,9 @@ void SceneManager::useRenderableViewProjMode(const Renderable* pRend, bool fixed if (useIdentityView) { // Using identity view now, change it - if (fixedFunction) - setViewMatrix(Matrix4::IDENTITY); - mGpuParamsDirty |= (uint16)GPV_GLOBAL; + if (fixedFunction) + setViewMatrix(Matrix4::IDENTITY); + mGpuParamsDirty |= (uint16)GPV_GLOBAL; mResetIdentityView = true; } @@ -3933,13 +3933,13 @@ void SceneManager::useRenderableViewProjMode(const Renderable* pRend, bool fixed if (useIdentityProj) { // Use identity projection matrix, still need to take RS depth into account. - if (fixedFunction) - { - Matrix4 mat; - mDestRenderSystem->_convertProjectionMatrix(Matrix4::IDENTITY, mat); - mDestRenderSystem->_setProjectionMatrix(mat); - } - mGpuParamsDirty |= (uint16)GPV_GLOBAL; + if (fixedFunction) + { + Matrix4 mat; + mDestRenderSystem->_convertProjectionMatrix(Matrix4::IDENTITY, mat); + mDestRenderSystem->_setProjectionMatrix(mat); + } + mGpuParamsDirty |= (uint16)GPV_GLOBAL; mResetIdentityProj = true; } @@ -3952,9 +3952,9 @@ void SceneManager::resetViewProjMode(bool fixedFunction) if (mResetIdentityView) { // Coming back to normal from identity view - if (fixedFunction) - setViewMatrix(mCachedViewMatrix); - mGpuParamsDirty |= (uint16)GPV_GLOBAL; + if (fixedFunction) + setViewMatrix(mCachedViewMatrix); + mGpuParamsDirty |= (uint16)GPV_GLOBAL; mResetIdentityView = false; } @@ -3963,10 +3963,10 @@ void SceneManager::resetViewProjMode(bool fixedFunction) { // Coming back from flat projection if (fixedFunction) - mDestRenderSystem->_setProjectionMatrix(mCameraInProgress->getProjectionMatrixRS()); - mGpuParamsDirty |= (uint16)GPV_GLOBAL; + mDestRenderSystem->_setProjectionMatrix(mCameraInProgress->getProjectionMatrixRS()); + mGpuParamsDirty |= (uint16)GPV_GLOBAL; - mResetIdentityProj = false; + mResetIdentityProj = false; } @@ -3974,49 +3974,49 @@ void SceneManager::resetViewProjMode(bool fixedFunction) //--------------------------------------------------------------------- void SceneManager::_queueSkiesForRendering(Camera* cam) { - // Update nodes - // Translate the box by the camera position (constant distance) - if (mSkyPlaneNode) - { - // The plane position relative to the camera has already been set up - mSkyPlaneNode->setPosition(cam->getDerivedPosition()); - } - - if (mSkyBoxNode) - { - mSkyBoxNode->setPosition(cam->getDerivedPosition()); - } - - if (mSkyDomeNode) - { - mSkyDomeNode->setPosition(cam->getDerivedPosition()); - } - - if (mSkyPlaneEnabled - && mSkyPlaneEntity && mSkyPlaneEntity->isVisible() - && mSkyPlaneEntity->getSubEntity(0) && mSkyPlaneEntity->getSubEntity(0)->isVisible()) - { - getRenderQueue()->addRenderable(mSkyPlaneEntity->getSubEntity(0), mSkyPlaneRenderQueue, OGRE_RENDERABLE_DEFAULT_PRIORITY); - } - - if (mSkyBoxEnabled - && mSkyBoxObj && mSkyBoxObj->isVisible()) - { - mSkyBoxObj->_updateRenderQueue(getRenderQueue()); - } - - if (mSkyDomeEnabled) - { - for (uint plane = 0; plane < 5; ++plane) - { - if (mSkyDomeEntity[plane] && mSkyDomeEntity[plane]->isVisible() - && mSkyDomeEntity[plane]->getSubEntity(0) && mSkyDomeEntity[plane]->getSubEntity(0)->isVisible()) - { - getRenderQueue()->addRenderable( - mSkyDomeEntity[plane]->getSubEntity(0), mSkyDomeRenderQueue, OGRE_RENDERABLE_DEFAULT_PRIORITY); - } - } - } + // Update nodes + // Translate the box by the camera position (constant distance) + if (mSkyPlaneNode) + { + // The plane position relative to the camera has already been set up + mSkyPlaneNode->setPosition(cam->getDerivedPosition()); + } + + if (mSkyBoxNode) + { + mSkyBoxNode->setPosition(cam->getDerivedPosition()); + } + + if (mSkyDomeNode) + { + mSkyDomeNode->setPosition(cam->getDerivedPosition()); + } + + if (mSkyPlaneEnabled + && mSkyPlaneEntity && mSkyPlaneEntity->isVisible() + && mSkyPlaneEntity->getSubEntity(0) && mSkyPlaneEntity->getSubEntity(0)->isVisible()) + { + getRenderQueue()->addRenderable(mSkyPlaneEntity->getSubEntity(0), mSkyPlaneRenderQueue, OGRE_RENDERABLE_DEFAULT_PRIORITY); + } + + if (mSkyBoxEnabled + && mSkyBoxObj && mSkyBoxObj->isVisible()) + { + mSkyBoxObj->_updateRenderQueue(getRenderQueue()); + } + + if (mSkyDomeEnabled) + { + for (uint plane = 0; plane < 5; ++plane) + { + if (mSkyDomeEntity[plane] && mSkyDomeEntity[plane]->isVisible() + && mSkyDomeEntity[plane]->getSubEntity(0) && mSkyDomeEntity[plane]->getSubEntity(0)->isVisible()) + { + getRenderQueue()->addRenderable( + mSkyDomeEntity[plane]->getSubEntity(0), mSkyDomeRenderQueue, OGRE_RENDERABLE_DEFAULT_PRIORITY); + } + } + } } //--------------------------------------------------------------------- void SceneManager::addRenderQueueListener(RenderQueueListener* newListener) @@ -4041,21 +4041,21 @@ void SceneManager::removeRenderQueueListener(RenderQueueListener* delListener) //--------------------------------------------------------------------- void SceneManager::addRenderObjectListener(RenderObjectListener* newListener) { - mRenderObjectListeners.push_back(newListener); + mRenderObjectListeners.push_back(newListener); } //--------------------------------------------------------------------- void SceneManager::removeRenderObjectListener(RenderObjectListener* delListener) { - RenderObjectListenerList::iterator i, iend; - iend = mRenderObjectListeners.end(); - for (i = mRenderObjectListeners.begin(); i != iend; ++i) - { - if (*i == delListener) - { - mRenderObjectListeners.erase(i); - break; - } - } + RenderObjectListenerList::iterator i, iend; + iend = mRenderObjectListeners.end(); + for (i = mRenderObjectListeners.begin(); i != iend; ++i) + { + if (*i == delListener) + { + mRenderObjectListeners.erase(i); + break; + } + } } void SceneManager::addListener(Listener* newListener) { @@ -4071,20 +4071,20 @@ void SceneManager::removeListener(Listener* delListener) //--------------------------------------------------------------------- void SceneManager::firePreRenderQueues() { - for (RenderQueueListenerList::iterator i = mRenderQueueListeners.begin(); - i != mRenderQueueListeners.end(); ++i) - { - (*i)->preRenderQueues(); - } + for (RenderQueueListenerList::iterator i = mRenderQueueListeners.begin(); + i != mRenderQueueListeners.end(); ++i) + { + (*i)->preRenderQueues(); + } } //--------------------------------------------------------------------- void SceneManager::firePostRenderQueues() { - for (RenderQueueListenerList::iterator i = mRenderQueueListeners.begin(); - i != mRenderQueueListeners.end(); ++i) - { - (*i)->postRenderQueues(); - } + for (RenderQueueListenerList::iterator i = mRenderQueueListeners.begin(); + i != mRenderQueueListeners.end(); ++i) + { + (*i)->postRenderQueues(); + } } //--------------------------------------------------------------------- bool SceneManager::fireRenderQueueStarted(uint8 id, const String& invocation) @@ -4114,16 +4114,16 @@ bool SceneManager::fireRenderQueueEnded(uint8 id, const String& invocation) } //--------------------------------------------------------------------- void SceneManager::fireRenderSingleObject(Renderable* rend, const Pass* pass, - const AutoParamDataSource* source, - const LightList* pLightList, bool suppressRenderStateChanges) + const AutoParamDataSource* source, + const LightList* pLightList, bool suppressRenderStateChanges) { - RenderObjectListenerList::iterator i, iend; + RenderObjectListenerList::iterator i, iend; - iend = mRenderObjectListeners.end(); - for (i = mRenderObjectListeners.begin(); i != iend; ++i) - { - (*i)->notifyRenderSingleObject(rend, pass, source, pLightList, suppressRenderStateChanges); - } + iend = mRenderObjectListeners.end(); + for (i = mRenderObjectListeners.begin(); i != iend; ++i) + { + (*i)->notifyRenderSingleObject(rend, pass, source, pLightList, suppressRenderStateChanges); + } } //--------------------------------------------------------------------- void SceneManager::fireShadowTexturesUpdated(size_t numberOfShadowTextures) @@ -4165,51 +4165,51 @@ void SceneManager::fireShadowTexturesPreReceiver(Light* light, Frustum* f) void SceneManager::firePreUpdateSceneGraph(Camera* camera) { ListenerList listenersCopy = mListeners; - ListenerList::iterator i, iend; + ListenerList::iterator i, iend; - iend = listenersCopy.end(); - for (i = listenersCopy.begin(); i != iend; ++i) - { - (*i)->preUpdateSceneGraph(this, camera); - } + iend = listenersCopy.end(); + for (i = listenersCopy.begin(); i != iend; ++i) + { + (*i)->preUpdateSceneGraph(this, camera); + } } //--------------------------------------------------------------------- void SceneManager::firePostUpdateSceneGraph(Camera* camera) { ListenerList listenersCopy = mListeners; - ListenerList::iterator i, iend; + ListenerList::iterator i, iend; - iend = listenersCopy.end(); - for (i = listenersCopy.begin(); i != iend; ++i) - { - (*i)->postUpdateSceneGraph(this, camera); - } + iend = listenersCopy.end(); + for (i = listenersCopy.begin(); i != iend; ++i) + { + (*i)->postUpdateSceneGraph(this, camera); + } } //--------------------------------------------------------------------- void SceneManager::firePreFindVisibleObjects(Viewport* v) { ListenerList listenersCopy = mListeners; - ListenerList::iterator i, iend; + ListenerList::iterator i, iend; - iend = listenersCopy.end(); - for (i = listenersCopy.begin(); i != iend; ++i) - { - (*i)->preFindVisibleObjects(this, mIlluminationStage, v); - } + iend = listenersCopy.end(); + for (i = listenersCopy.begin(); i != iend; ++i) + { + (*i)->preFindVisibleObjects(this, mIlluminationStage, v); + } } //--------------------------------------------------------------------- void SceneManager::firePostFindVisibleObjects(Viewport* v) { ListenerList listenersCopy = mListeners; - ListenerList::iterator i, iend; + ListenerList::iterator i, iend; - iend = listenersCopy.end(); - for (i = listenersCopy.begin(); i != iend; ++i) - { - (*i)->postFindVisibleObjects(this, mIlluminationStage, v); - } + iend = listenersCopy.end(); + for (i = listenersCopy.begin(); i != iend; ++i) + { + (*i)->postFindVisibleObjects(this, mIlluminationStage, v); + } } @@ -4217,13 +4217,13 @@ void SceneManager::firePostFindVisibleObjects(Viewport* v) void SceneManager::fireSceneManagerDestroyed() { ListenerList listenersCopy = mListeners; - ListenerList::iterator i, iend; + ListenerList::iterator i, iend; - iend = listenersCopy.end(); - for (i = listenersCopy.begin(); i != iend; ++i) - { - (*i)->sceneManagerDestroyed(this); - } + iend = listenersCopy.end(); + for (i = listenersCopy.begin(); i != iend; ++i) + { + (*i)->sceneManagerDestroyed(this); + } } //--------------------------------------------------------------------- void SceneManager::setViewport(Viewport* vp) @@ -4231,8 +4231,8 @@ void SceneManager::setViewport(Viewport* vp) mCurrentViewport = vp; // Set viewport in render system mDestRenderSystem->_setViewport(vp); - // Set the active material scheme for this viewport - MaterialManager::getSingleton().setActiveScheme(vp->getMaterialScheme()); + // Set the active material scheme for this viewport + MaterialManager::getSingleton().setActiveScheme(vp->getMaterialScheme()); } //--------------------------------------------------------------------- void SceneManager::showBoundingBoxes(bool bShow) @@ -4282,109 +4282,109 @@ void SceneManager::setShadowTechnique(ShadowTechnique technique) // tell all meshes to prepare shadow volumes MeshManager::getSingleton().setPrepareAllMeshesForShadowVolumes(true); } - } + } if (!isShadowTechniqueTextureBased()) { // Destroy shadow textures to optimise resource usage destroyShadowTextures(); } - else - { - // assure no custom shadow matrix is used accidentally in case we switch - // from a custom shadow mapping type to a non-custom (uniform shadow mapping) - for ( size_t i = 0; i < mShadowTextureCameras.size(); ++i ) - { - Camera* texCam = mShadowTextureCameras[i]; + else + { + // assure no custom shadow matrix is used accidentally in case we switch + // from a custom shadow mapping type to a non-custom (uniform shadow mapping) + for ( size_t i = 0; i < mShadowTextureCameras.size(); ++i ) + { + Camera* texCam = mShadowTextureCameras[i]; - texCam->setCustomViewMatrix(false); - texCam->setCustomProjectionMatrix(false); - } - } + texCam->setCustomViewMatrix(false); + texCam->setCustomProjectionMatrix(false); + } + } } //--------------------------------------------------------------------- void SceneManager::_suppressShadows(bool suppress) { - mSuppressShadows = suppress; + mSuppressShadows = suppress; } //--------------------------------------------------------------------- void SceneManager::_suppressRenderStateChanges(bool suppress) { - mSuppressRenderStateChanges = suppress; + mSuppressRenderStateChanges = suppress; } //--------------------------------------------------------------------- void SceneManager::updateRenderQueueSplitOptions(void) { - if (isShadowTechniqueStencilBased()) - { - // Casters can always be receivers - getRenderQueue()->setShadowCastersCannotBeReceivers(false); - } - else // texture based - { - getRenderQueue()->setShadowCastersCannotBeReceivers(!mShadowTextureSelfShadow); - } - - if (isShadowTechniqueAdditive() && !isShadowTechniqueIntegrated() - && mCurrentViewport->getShadowsEnabled()) - { - // Additive lighting, we need to split everything by illumination stage - getRenderQueue()->setSplitPassesByLightingType(true); - } - else - { - getRenderQueue()->setSplitPassesByLightingType(false); - } - - if (isShadowTechniqueInUse() && mCurrentViewport->getShadowsEnabled() - && !isShadowTechniqueIntegrated()) - { - // Tell render queue to split off non-shadowable materials - getRenderQueue()->setSplitNoShadowPasses(true); - } - else - { - getRenderQueue()->setSplitNoShadowPasses(false); - } + if (isShadowTechniqueStencilBased()) + { + // Casters can always be receivers + getRenderQueue()->setShadowCastersCannotBeReceivers(false); + } + else // texture based + { + getRenderQueue()->setShadowCastersCannotBeReceivers(!mShadowTextureSelfShadow); + } + + if (isShadowTechniqueAdditive() && !isShadowTechniqueIntegrated() + && mCurrentViewport->getShadowsEnabled()) + { + // Additive lighting, we need to split everything by illumination stage + getRenderQueue()->setSplitPassesByLightingType(true); + } + else + { + getRenderQueue()->setSplitPassesByLightingType(false); + } + + if (isShadowTechniqueInUse() && mCurrentViewport->getShadowsEnabled() + && !isShadowTechniqueIntegrated()) + { + // Tell render queue to split off non-shadowable materials + getRenderQueue()->setSplitNoShadowPasses(true); + } + else + { + getRenderQueue()->setSplitNoShadowPasses(false); + } } //--------------------------------------------------------------------- void SceneManager::updateRenderQueueGroupSplitOptions(RenderQueueGroup* group, - bool suppressShadows, bool suppressRenderState) -{ - if (isShadowTechniqueStencilBased()) - { - // Casters can always be receivers - group->setShadowCastersCannotBeReceivers(false); - } - else if (isShadowTechniqueTextureBased()) - { - group->setShadowCastersCannotBeReceivers(!mShadowTextureSelfShadow); - } - - if (!suppressShadows && mCurrentViewport->getShadowsEnabled() && - isShadowTechniqueAdditive() && !isShadowTechniqueIntegrated()) - { - // Additive lighting, we need to split everything by illumination stage - group->setSplitPassesByLightingType(true); - } - else - { - group->setSplitPassesByLightingType(false); - } - - if (!suppressShadows && mCurrentViewport->getShadowsEnabled() - && isShadowTechniqueInUse()) - { - // Tell render queue to split off non-shadowable materials - group->setSplitNoShadowPasses(true); - } - else - { - group->setSplitNoShadowPasses(false); - } + bool suppressShadows, bool suppressRenderState) +{ + if (isShadowTechniqueStencilBased()) + { + // Casters can always be receivers + group->setShadowCastersCannotBeReceivers(false); + } + else if (isShadowTechniqueTextureBased()) + { + group->setShadowCastersCannotBeReceivers(!mShadowTextureSelfShadow); + } + + if (!suppressShadows && mCurrentViewport->getShadowsEnabled() && + isShadowTechniqueAdditive() && !isShadowTechniqueIntegrated()) + { + // Additive lighting, we need to split everything by illumination stage + group->setSplitPassesByLightingType(true); + } + else + { + group->setSplitPassesByLightingType(false); + } + + if (!suppressShadows && mCurrentViewport->getShadowsEnabled() + && isShadowTechniqueInUse()) + { + // Tell render queue to split off non-shadowable materials + group->setSplitNoShadowPasses(true); + } + else + { + group->setSplitNoShadowPasses(false); + } } @@ -4395,19 +4395,19 @@ void SceneManager::_notifyLightsDirty(void) } //--------------------------------------------------------------------- bool SceneManager::lightsForShadowTextureLess::operator ()( - const Ogre::Light *l1, const Ogre::Light *l2) const + const Ogre::Light *l1, const Ogre::Light *l2) const { - if (l1 == l2) - return false; + if (l1 == l2) + return false; - // sort shadow casting lights ahead of non-shadow casting - if (l1->getCastShadows() != l2->getCastShadows()) - { - return l1->getCastShadows(); - } + // sort shadow casting lights ahead of non-shadow casting + if (l1->getCastShadows() != l2->getCastShadows()) + { + return l1->getCastShadows(); + } - // otherwise sort by distance (directional lights will have 0 here) - return l1->tempSquareDist < l2->tempSquareDist; + // otherwise sort by distance (directional lights will have 0 here) + return l1->tempSquareDist < l2->tempSquareDist; } //--------------------------------------------------------------------- @@ -4419,52 +4419,52 @@ void SceneManager::findLightsAffectingFrustum(const Camera* camera) getMovableObjectCollection(LightFactory::FACTORY_TYPE_NAME); - { + { OGRE_LOCK_MUTEX(lights->mutex); - // Pre-allocate memory - mTestLightInfos.clear(); - mTestLightInfos.reserve(lights->map.size()); - - MovableObjectIterator it(lights->map.begin(), lights->map.end()); - - while(it.hasMoreElements()) - { - Light* l = static_cast(it.getNext()); - - if (mCameraRelativeRendering) - l->_setCameraRelative(mCameraInProgress); - else - l->_setCameraRelative(0); - - if (l->isVisible()) - { - LightInfo lightInfo; - lightInfo.light = l; - lightInfo.type = l->getType(); - lightInfo.lightMask = l->getLightMask(); - if (lightInfo.type == Light::LT_DIRECTIONAL) - { - // Always visible - lightInfo.position = Vector3::ZERO; - lightInfo.range = 0; - mTestLightInfos.push_back(lightInfo); - } - else - { - // NB treating spotlight as point for simplicity - // Just see if the lights attenuation range is within the frustum - lightInfo.range = l->getAttenuationRange(); - lightInfo.position = l->getDerivedPosition(); - Sphere sphere(lightInfo.position, lightInfo.range); - if (camera->isVisible(sphere)) - { - mTestLightInfos.push_back(lightInfo); - } - } - } - } - } // release lock on lights collection + // Pre-allocate memory + mTestLightInfos.clear(); + mTestLightInfos.reserve(lights->map.size()); + + MovableObjectIterator it(lights->map.begin(), lights->map.end()); + + while(it.hasMoreElements()) + { + Light* l = static_cast(it.getNext()); + + if (mCameraRelativeRendering) + l->_setCameraRelative(mCameraInProgress); + else + l->_setCameraRelative(0); + + if (l->isVisible()) + { + LightInfo lightInfo; + lightInfo.light = l; + lightInfo.type = l->getType(); + lightInfo.lightMask = l->getLightMask(); + if (lightInfo.type == Light::LT_DIRECTIONAL) + { + // Always visible + lightInfo.position = Vector3::ZERO; + lightInfo.range = 0; + mTestLightInfos.push_back(lightInfo); + } + else + { + // NB treating spotlight as point for simplicity + // Just see if the lights attenuation range is within the frustum + lightInfo.range = l->getAttenuationRange(); + lightInfo.position = l->getDerivedPosition(); + Sphere sphere(lightInfo.position, lightInfo.range); + if (camera->isVisible(sphere)) + { + mTestLightInfos.push_back(lightInfo); + } + } + } + } + } // release lock on lights collection // Update lights affecting frustum if changed if (mCachedLightInfos != mTestLightInfos) @@ -4475,37 +4475,37 @@ void SceneManager::findLightsAffectingFrustum(const Camera* camera) for (i = mTestLightInfos.begin(); i != mTestLightInfos.end(); ++i, ++j) { *j = i->light; - // add cam distance for sorting if texture shadows - if (isShadowTechniqueTextureBased()) - { - (*j)->_calcTempSquareDist(camera->getDerivedPosition()); - } - } - - // Sort the lights if using texture shadows, since the first 'n' will be - // used to generate shadow textures and we should pick the most appropriate - if (isShadowTechniqueTextureBased()) - { - // Allow a Listener to override light sorting - // Reverse iterate so last takes precedence - bool overridden = false; - ListenerList listenersCopy = mListeners; - for (ListenerList::reverse_iterator ri = listenersCopy.rbegin(); - ri != listenersCopy.rend(); ++ri) - { - overridden = (*ri)->sortLightsAffectingFrustum(mLightsAffectingFrustum); - if (overridden) - break; - } - if (!overridden) - { - // default sort (stable to preserve directional light ordering - std::stable_sort( - mLightsAffectingFrustum.begin(), mLightsAffectingFrustum.end(), - lightsForShadowTextureLess()); - } - - } + // add cam distance for sorting if texture shadows + if (isShadowTechniqueTextureBased()) + { + (*j)->_calcTempSquareDist(camera->getDerivedPosition()); + } + } + + // Sort the lights if using texture shadows, since the first 'n' will be + // used to generate shadow textures and we should pick the most appropriate + if (isShadowTechniqueTextureBased()) + { + // Allow a Listener to override light sorting + // Reverse iterate so last takes precedence + bool overridden = false; + ListenerList listenersCopy = mListeners; + for (ListenerList::reverse_iterator ri = listenersCopy.rbegin(); + ri != listenersCopy.rend(); ++ri) + { + overridden = (*ri)->sortLightsAffectingFrustum(mLightsAffectingFrustum); + if (overridden) + break; + } + if (!overridden) + { + // default sort (stable to preserve directional light ordering + std::stable_sort( + mLightsAffectingFrustum.begin(), mLightsAffectingFrustum.end(), + lightsForShadowTextureLess()); + } + + } // Use swap instead of copy operator for efficiently mCachedLightInfos.swap(mTestLightInfos); @@ -4521,12 +4521,12 @@ bool SceneManager::ShadowCasterSceneQueryListener::queryResult( MovableObject* object) { if (object->getCastShadows() && object->isVisible() && - mSceneMgr->isRenderQueueToBeProcessed(object->getRenderQueueGroup()) && - // objects need an edge list to cast shadows (shadow volumes only) - ((mSceneMgr->getShadowTechnique() & SHADOWDETAILTYPE_TEXTURE) || + mSceneMgr->isRenderQueueToBeProcessed(object->getRenderQueueGroup()) && + // objects need an edge list to cast shadows (shadow volumes only) + ((mSceneMgr->getShadowTechnique() & SHADOWDETAILTYPE_TEXTURE) || ((mSceneMgr->getShadowTechnique() & SHADOWDETAILTYPE_STENCIL) && object->hasEdgeList()) - ) - ) + ) + ) { if (mFarDistSquared) { @@ -4690,7 +4690,7 @@ void SceneManager::initShadowVolumeMaterials(void) // Enable the (infinite) point light extruder for now, just to get some params mShadowDebugPass->setVertexProgram( ShadowVolumeExtrudeProgram::programNames[ShadowVolumeExtrudeProgram::POINT_LIGHT]); - mShadowDebugPass->setFragmentProgram(ShadowVolumeExtrudeProgram::frgProgramName); + mShadowDebugPass->setFragmentProgram(ShadowVolumeExtrudeProgram::frgProgramName); mInfiniteExtrusionParams = mShadowDebugPass->getVertexProgramParameters(); mInfiniteExtrusionParams->setAutoConstant(0, @@ -4699,8 +4699,8 @@ void SceneManager::initShadowVolumeMaterials(void) GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE); // Note ignored extra parameter - for compatibility with finite extrusion vertex program mInfiniteExtrusionParams->setAutoConstant(5, - GpuProgramParameters::ACT_SHADOW_EXTRUSION_DISTANCE); - } + GpuProgramParameters::ACT_SHADOW_EXTRUSION_DISTANCE); + } matDebug->compile(); } @@ -4735,7 +4735,7 @@ void SceneManager::initShadowVolumeMaterials(void) // Enable the finite point light extruder for now, just to get some params mShadowStencilPass->setVertexProgram( ShadowVolumeExtrudeProgram::programNames[ShadowVolumeExtrudeProgram::POINT_LIGHT_FINITE]); - mShadowStencilPass->setFragmentProgram(ShadowVolumeExtrudeProgram::frgProgramName); + mShadowStencilPass->setFragmentProgram(ShadowVolumeExtrudeProgram::frgProgramName); mFiniteExtrusionParams = mShadowStencilPass->getVertexProgramParameters(); mFiniteExtrusionParams->setAutoConstant(0, @@ -4817,8 +4817,8 @@ void SceneManager::initShadowVolumeMaterials(void) mShadowCasterPlainBlackPass->setDiffuse(ColourValue::Black); mShadowCasterPlainBlackPass->setSelfIllumination(ColourValue::Black); mShadowCasterPlainBlackPass->setSpecular(ColourValue::Black); - // Override fog - mShadowCasterPlainBlackPass->setFog(true, FOG_NONE); + // Override fog + mShadowCasterPlainBlackPass->setFog(true, FOG_NONE); // no textures or anything else, we will bind vertex programs // every so often though } @@ -4832,13 +4832,13 @@ void SceneManager::initShadowVolumeMaterials(void) { MaterialPtr matShadRec = MaterialManager::getSingleton().getByName( "Ogre/TextureShadowReceiver"); - if (matShadRec.isNull()) + if (matShadRec.isNull()) { matShadRec = MaterialManager::getSingleton().create( "Ogre/TextureShadowReceiver", ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); mShadowReceiverPass = matShadRec->getTechnique(0)->getPass(0); - // Don't set lighting and blending modes here, depends on additive / modulative + // Don't set lighting and blending modes here, depends on additive / modulative TextureUnitState* t = mShadowReceiverPass->createTextureUnitState(); t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); } @@ -4855,13 +4855,13 @@ void SceneManager::initShadowVolumeMaterials(void) { // Load the manual buffer into an image (don't destroy memory! DataStreamPtr stream( - OGRE_NEW MemoryDataStream(SPOT_SHADOW_FADE_PNG, SPOT_SHADOW_FADE_PNG_SIZE, false)); + OGRE_NEW MemoryDataStream(SPOT_SHADOW_FADE_PNG, SPOT_SHADOW_FADE_PNG_SIZE, false)); Image img; img.load(stream, "png"); spotShadowFadeTex = TextureManager::getSingleton().loadImage( - "spot_shadow_fade.png", ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - img, TEX_TYPE_2D); + "spot_shadow_fade.png", ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, + img, TEX_TYPE_2D); } mShadowMaterialInitDone = true; @@ -4869,608 +4869,608 @@ void SceneManager::initShadowVolumeMaterials(void) //--------------------------------------------------------------------- const Pass* SceneManager::deriveShadowCasterPass(const Pass* pass) { - if (isShadowTechniqueTextureBased()) - { - Pass* retPass; - if (!pass->getParent()->getShadowCasterMaterial().isNull()) - { - return pass->getParent()->getShadowCasterMaterial()->getBestTechnique()->getPass(0); - } - else - { - retPass = mShadowTextureCustomCasterPass ? - mShadowTextureCustomCasterPass : mShadowCasterPlainBlackPass; - } - - - // Special case alpha-blended passes - if ((pass->getSourceBlendFactor() == SBF_SOURCE_ALPHA && - pass->getDestBlendFactor() == SBF_ONE_MINUS_SOURCE_ALPHA) - || pass->getAlphaRejectFunction() != CMPF_ALWAYS_PASS) - { - // Alpha blended passes must retain their transparency - retPass->setAlphaRejectSettings(pass->getAlphaRejectFunction(), - pass->getAlphaRejectValue()); - retPass->setSceneBlending(pass->getSourceBlendFactor(), pass->getDestBlendFactor()); - retPass->getParent()->getParent()->setTransparencyCastsShadows(true); - - // So we allow the texture units, but override the colour functions - // Copy texture state, shift up one since 0 is shadow texture - unsigned short origPassTUCount = pass->getNumTextureUnitStates(); - for (unsigned short t = 0; t < origPassTUCount; ++t) - { - TextureUnitState* tex; - if (retPass->getNumTextureUnitStates() <= t) - { - tex = retPass->createTextureUnitState(); - } - else - { - tex = retPass->getTextureUnitState(t); - } - // copy base state - (*tex) = *(pass->getTextureUnitState(t)); - // override colour function - tex->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, - isShadowTechniqueAdditive()? ColourValue::Black : mShadowColour); - - } - // Remove any extras - while (retPass->getNumTextureUnitStates() > origPassTUCount) - { - retPass->removeTextureUnitState(origPassTUCount); - } - - } - else - { - // reset - retPass->setSceneBlending(SBT_REPLACE); - retPass->setAlphaRejectFunction(CMPF_ALWAYS_PASS); - while (retPass->getNumTextureUnitStates() > 0) - { - retPass->removeTextureUnitState(0); - } - } - - // Propagate culling modes - retPass->setCullingMode(pass->getCullingMode()); - retPass->setManualCullingMode(pass->getManualCullingMode()); - - - // Does incoming pass have a custom shadow caster program? - if (!pass->getShadowCasterVertexProgramName().empty()) - { - // Have to merge the shadow caster vertex program in - retPass->setVertexProgram( - pass->getShadowCasterVertexProgramName(), false); - const GpuProgramPtr& prg = retPass->getVertexProgram(); - // Load this program if not done already - if (!prg->isLoaded()) - prg->load(); - // Copy params - retPass->setVertexProgramParameters( - pass->getShadowCasterVertexProgramParameters()); - // Also have to hack the light autoparams, that is done later - } - else - { - if (retPass == mShadowTextureCustomCasterPass) - { - // reset vp? - if (mShadowTextureCustomCasterPass->getVertexProgramName() != - mShadowTextureCustomCasterVertexProgram) - { - mShadowTextureCustomCasterPass->setVertexProgram( - mShadowTextureCustomCasterVertexProgram, false); - if(mShadowTextureCustomCasterPass->hasVertexProgram()) - { - mShadowTextureCustomCasterPass->setVertexProgramParameters( - mShadowTextureCustomCasterVPParams); - - } - - } - - } - else - { - // Standard shadow caster pass, reset to no vp - retPass->setVertexProgram(BLANKSTRING); - } - } - - if (!pass->getShadowCasterFragmentProgramName().empty()) - { - // Have to merge the shadow caster fragment program in - retPass->setFragmentProgram( - pass->getShadowCasterFragmentProgramName(), false); - const GpuProgramPtr& prg = retPass->getFragmentProgram(); - // Load this program if not done already - if (!prg->isLoaded()) - prg->load(); - // Copy params - retPass->setFragmentProgramParameters( - pass->getShadowCasterFragmentProgramParameters()); - // Also have to hack the light autoparams, that is done later - } - else - { - if (retPass == mShadowTextureCustomCasterPass) - { - // reset fp? - if (mShadowTextureCustomCasterPass->getFragmentProgramName() != - mShadowTextureCustomCasterFragmentProgram) - { - mShadowTextureCustomCasterPass->setFragmentProgram( - mShadowTextureCustomCasterFragmentProgram, false); - if(mShadowTextureCustomCasterPass->hasFragmentProgram()) - { - mShadowTextureCustomCasterPass->setFragmentProgramParameters( - mShadowTextureCustomCasterFPParams); - } - } - } - else - { - // Standard shadow caster pass, reset to no fp - retPass->setFragmentProgram(BLANKSTRING); - } - } - - // handle the case where there is no fixed pipeline support - if( retPass->getParent()->getParent()->getCompilationRequired() ) - retPass->getParent()->getParent()->compile(); - - Technique* btech = retPass->getParent()->getParent()->getBestTechnique(); - if( btech ) - { - retPass = btech->getPass(0); - } - - return retPass; - } - else - { - return pass; - } - -} -//--------------------------------------------------------------------- -const Pass* SceneManager::deriveShadowReceiverPass(const Pass* pass) -{ - if (isShadowTechniqueTextureBased()) { - Pass* retPass = NULL; - if (!pass->getParent()->getShadowReceiverMaterial().isNull()) - { - return retPass = pass->getParent()->getShadowReceiverMaterial()->getBestTechnique()->getPass(0); - } - else - { - retPass = mShadowTextureCustomReceiverPass ? - mShadowTextureCustomReceiverPass : mShadowReceiverPass; - } - - // Does incoming pass have a custom shadow receiver program? - if (!pass->getShadowReceiverVertexProgramName().empty()) - { - // Have to merge the shadow receiver vertex program in - retPass->setVertexProgram( - pass->getShadowReceiverVertexProgramName(), false); - const GpuProgramPtr& prg = retPass->getVertexProgram(); - // Load this program if not done already - if (!prg->isLoaded()) - prg->load(); - // Copy params - retPass->setVertexProgramParameters( - pass->getShadowReceiverVertexProgramParameters()); - // Also have to hack the light autoparams, that is done later - } - else - { - if (retPass == mShadowTextureCustomReceiverPass) - { - // reset vp? - if (mShadowTextureCustomReceiverPass->getVertexProgramName() != - mShadowTextureCustomReceiverVertexProgram) - { - mShadowTextureCustomReceiverPass->setVertexProgram( - mShadowTextureCustomReceiverVertexProgram, false); - if(mShadowTextureCustomReceiverPass->hasVertexProgram()) - { - mShadowTextureCustomReceiverPass->setVertexProgramParameters( - mShadowTextureCustomReceiverVPParams); - - } - - } - - } - else - { - // Standard shadow receiver pass, reset to no vp - retPass->setVertexProgram(BLANKSTRING); - } - } - - unsigned short keepTUCount; - // If additive, need lighting parameters & standard programs - if (isShadowTechniqueAdditive()) - { - retPass->setLightingEnabled(true); - retPass->setAmbient(pass->getAmbient()); - retPass->setSelfIllumination(pass->getSelfIllumination()); - retPass->setDiffuse(pass->getDiffuse()); - retPass->setSpecular(pass->getSpecular()); - retPass->setShininess(pass->getShininess()); - retPass->setIteratePerLight(pass->getIteratePerLight(), - pass->getRunOnlyForOneLightType(), pass->getOnlyLightType()); - retPass->setLightMask(pass->getLightMask()); + Pass* retPass; + if (!pass->getParent()->getShadowCasterMaterial().isNull()) + { + return pass->getParent()->getShadowCasterMaterial()->getBestTechnique()->getPass(0); + } + else + { + retPass = mShadowTextureCustomCasterPass ? + mShadowTextureCustomCasterPass : mShadowCasterPlainBlackPass; + } - // We need to keep alpha rejection settings - retPass->setAlphaRejectSettings(pass->getAlphaRejectFunction(), + + // Special case alpha-blended passes + if ((pass->getSourceBlendFactor() == SBF_SOURCE_ALPHA && + pass->getDestBlendFactor() == SBF_ONE_MINUS_SOURCE_ALPHA) + || pass->getAlphaRejectFunction() != CMPF_ALWAYS_PASS) + { + // Alpha blended passes must retain their transparency + retPass->setAlphaRejectSettings(pass->getAlphaRejectFunction(), pass->getAlphaRejectValue()); + retPass->setSceneBlending(pass->getSourceBlendFactor(), pass->getDestBlendFactor()); + retPass->getParent()->getParent()->setTransparencyCastsShadows(true); + + // So we allow the texture units, but override the colour functions // Copy texture state, shift up one since 0 is shadow texture unsigned short origPassTUCount = pass->getNumTextureUnitStates(); for (unsigned short t = 0; t < origPassTUCount; ++t) { - unsigned short targetIndex = t+1; TextureUnitState* tex; - if (retPass->getNumTextureUnitStates() <= targetIndex) + if (retPass->getNumTextureUnitStates() <= t) { tex = retPass->createTextureUnitState(); } else { - tex = retPass->getTextureUnitState(targetIndex); + tex = retPass->getTextureUnitState(t); } + // copy base state (*tex) = *(pass->getTextureUnitState(t)); - // If programmable, have to adjust the texcoord sets too - // D3D insists that texcoordsets match tex unit in programmable mode - if (retPass->hasVertexProgram()) - tex->setTextureCoordSet(targetIndex); + // override colour function + tex->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, + isShadowTechniqueAdditive()? ColourValue::Black : mShadowColour); + + } + // Remove any extras + while (retPass->getNumTextureUnitStates() > origPassTUCount) + { + retPass->removeTextureUnitState(origPassTUCount); } - keepTUCount = origPassTUCount + 1; - }// additive lighting - else - { - // need to keep spotlight fade etc - keepTUCount = retPass->getNumTextureUnitStates(); - } - - - // Will also need fragment programs since this is a complex light setup - if (!pass->getShadowReceiverFragmentProgramName().empty()) - { - // Have to merge the shadow receiver vertex program in - retPass->setFragmentProgram( - pass->getShadowReceiverFragmentProgramName(), false); - const GpuProgramPtr& prg = retPass->getFragmentProgram(); - // Load this program if not done already - if (!prg->isLoaded()) - prg->load(); - // Copy params - retPass->setFragmentProgramParameters( - pass->getShadowReceiverFragmentProgramParameters()); - - // Did we bind a shadow vertex program? - if (pass->hasVertexProgram() && !retPass->hasVertexProgram()) - { - // We didn't bind a receiver-specific program, so bind the original - retPass->setVertexProgram(pass->getVertexProgramName(), false); - const GpuProgramPtr& prog = retPass->getVertexProgram(); - // Load this program if required - if (!prog->isLoaded()) - prog->load(); - // Copy params - retPass->setVertexProgramParameters( - pass->getVertexProgramParameters()); - - } - } - else - { - // Reset any merged fragment programs from last time - if (retPass == mShadowTextureCustomReceiverPass) - { - // reset fp? - if (mShadowTextureCustomReceiverPass->getFragmentProgramName() != - mShadowTextureCustomReceiverFragmentProgram) - { - mShadowTextureCustomReceiverPass->setFragmentProgram( - mShadowTextureCustomReceiverFragmentProgram, false); - if(mShadowTextureCustomReceiverPass->hasFragmentProgram()) - { - mShadowTextureCustomReceiverPass->setFragmentProgramParameters( - mShadowTextureCustomReceiverFPParams); - - } - - } - - } - else - { - // Standard shadow receiver pass, reset to no fp - retPass->setFragmentProgram(BLANKSTRING); - } - - } - // Remove any extra texture units - while (retPass->getNumTextureUnitStates() > keepTUCount) + } + else { - retPass->removeTextureUnitState(keepTUCount); + // reset + retPass->setSceneBlending(SBT_REPLACE); + retPass->setAlphaRejectFunction(CMPF_ALWAYS_PASS); + while (retPass->getNumTextureUnitStates() > 0) + { + retPass->removeTextureUnitState(0); + } } - retPass->_load(); - - // handle the case where there is no fixed pipeline support - if( retPass->getParent()->getParent()->getCompilationRequired() ) - retPass->getParent()->getParent()->compile(); + // Propagate culling modes + retPass->setCullingMode(pass->getCullingMode()); + retPass->setManualCullingMode(pass->getManualCullingMode()); + - Technique* btech = retPass->getParent()->getParent()->getBestTechnique(); - if( btech ) + // Does incoming pass have a custom shadow caster program? + if (!pass->getShadowCasterVertexProgramName().empty()) { - retPass = btech->getPass(0); + // Have to merge the shadow caster vertex program in + retPass->setVertexProgram( + pass->getShadowCasterVertexProgramName(), false); + const GpuProgramPtr& prg = retPass->getVertexProgram(); + // Load this program if not done already + if (!prg->isLoaded()) + prg->load(); + // Copy params + retPass->setVertexProgramParameters( + pass->getShadowCasterVertexProgramParameters()); + // Also have to hack the light autoparams, that is done later } + else + { + if (retPass == mShadowTextureCustomCasterPass) + { + // reset vp? + if (mShadowTextureCustomCasterPass->getVertexProgramName() != + mShadowTextureCustomCasterVertexProgram) + { + mShadowTextureCustomCasterPass->setVertexProgram( + mShadowTextureCustomCasterVertexProgram, false); + if(mShadowTextureCustomCasterPass->hasVertexProgram()) + { + mShadowTextureCustomCasterPass->setVertexProgramParameters( + mShadowTextureCustomCasterVPParams); - return retPass; - } - else - { - return pass; - } - -} -//--------------------------------------------------------------------- -const RealRect& SceneManager::getLightScissorRect(Light* l, const Camera* cam) -{ - checkCachedLightClippingInfo(); - - // Re-use calculations if possible - LightClippingInfoMap::iterator ci = mLightClippingInfoMap.find(l); - if (ci == mLightClippingInfoMap.end()) - { - // create new entry - ci = mLightClippingInfoMap.insert(LightClippingInfoMap::value_type(l, LightClippingInfo())).first; - } - if (!ci->second.scissorValid) - { - - buildScissor(l, cam, ci->second.scissorRect); - ci->second.scissorValid = true; - } - - return ci->second.scissorRect; - -} -//--------------------------------------------------------------------- -ClipResult SceneManager::buildAndSetScissor(const LightList& ll, const Camera* cam) -{ - if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_SCISSOR_TEST)) - return CLIPPED_NONE; - - RealRect finalRect; - // init (inverted since we want to grow from nothing) - finalRect.left = finalRect.bottom = 1.0f; - finalRect.right = finalRect.top = -1.0f; - - for (LightList::const_iterator i = ll.begin(); i != ll.end(); ++i) - { - Light* l = *i; - // a directional light is being used, no scissoring can be done, period. - if (l->getType() == Light::LT_DIRECTIONAL) - return CLIPPED_NONE; - - const RealRect& scissorRect = getLightScissorRect(l, cam); - - // merge with final - finalRect.left = std::min(finalRect.left, scissorRect.left); - finalRect.bottom = std::min(finalRect.bottom, scissorRect.bottom); - finalRect.right= std::max(finalRect.right, scissorRect.right); - finalRect.top = std::max(finalRect.top, scissorRect.top); - - - } - - if (finalRect.left >= 1.0f || finalRect.right <= -1.0f || - finalRect.top <= -1.0f || finalRect.bottom >= 1.0f) - { - // rect was offscreen - return CLIPPED_ALL; - } + } - // Some scissoring? - if (finalRect.left > -1.0f || finalRect.right < 1.0f || - finalRect.bottom > -1.0f || finalRect.top < 1.0f) - { - // Turn normalised device coordinates into pixels - int iLeft, iTop, iWidth, iHeight; - mCurrentViewport->getActualDimensions(iLeft, iTop, iWidth, iHeight); - size_t szLeft, szRight, szTop, szBottom; + } - szLeft = (size_t)(iLeft + ((finalRect.left + 1) * 0.5 * iWidth)); - szRight = (size_t)(iLeft + ((finalRect.right + 1) * 0.5 * iWidth)); - szTop = (size_t)(iTop + ((-finalRect.top + 1) * 0.5 * iHeight)); - szBottom = (size_t)(iTop + ((-finalRect.bottom + 1) * 0.5 * iHeight)); + } + else + { + // Standard shadow caster pass, reset to no vp + retPass->setVertexProgram(BLANKSTRING); + } + } - mDestRenderSystem->setScissorTest(true, szLeft, szTop, szRight, szBottom); + if (!pass->getShadowCasterFragmentProgramName().empty()) + { + // Have to merge the shadow caster fragment program in + retPass->setFragmentProgram( + pass->getShadowCasterFragmentProgramName(), false); + const GpuProgramPtr& prg = retPass->getFragmentProgram(); + // Load this program if not done already + if (!prg->isLoaded()) + prg->load(); + // Copy params + retPass->setFragmentProgramParameters( + pass->getShadowCasterFragmentProgramParameters()); + // Also have to hack the light autoparams, that is done later + } + else + { + if (retPass == mShadowTextureCustomCasterPass) + { + // reset fp? + if (mShadowTextureCustomCasterPass->getFragmentProgramName() != + mShadowTextureCustomCasterFragmentProgram) + { + mShadowTextureCustomCasterPass->setFragmentProgram( + mShadowTextureCustomCasterFragmentProgram, false); + if(mShadowTextureCustomCasterPass->hasFragmentProgram()) + { + mShadowTextureCustomCasterPass->setFragmentProgramParameters( + mShadowTextureCustomCasterFPParams); + } + } + } + else + { + // Standard shadow caster pass, reset to no fp + retPass->setFragmentProgram(BLANKSTRING); + } + } + + // handle the case where there is no fixed pipeline support + if( retPass->getParent()->getParent()->getCompilationRequired() ) + retPass->getParent()->getParent()->compile(); + + Technique* btech = retPass->getParent()->getParent()->getBestTechnique(); + if( btech ) + { + retPass = btech->getPass(0); + } + + return retPass; + } + else + { + return pass; + } + +} +//--------------------------------------------------------------------- +const Pass* SceneManager::deriveShadowReceiverPass(const Pass* pass) +{ + + if (isShadowTechniqueTextureBased()) + { + Pass* retPass = NULL; + if (!pass->getParent()->getShadowReceiverMaterial().isNull()) + { + return retPass = pass->getParent()->getShadowReceiverMaterial()->getBestTechnique()->getPass(0); + } + else + { + retPass = mShadowTextureCustomReceiverPass ? + mShadowTextureCustomReceiverPass : mShadowReceiverPass; + } + + // Does incoming pass have a custom shadow receiver program? + if (!pass->getShadowReceiverVertexProgramName().empty()) + { + // Have to merge the shadow receiver vertex program in + retPass->setVertexProgram( + pass->getShadowReceiverVertexProgramName(), false); + const GpuProgramPtr& prg = retPass->getVertexProgram(); + // Load this program if not done already + if (!prg->isLoaded()) + prg->load(); + // Copy params + retPass->setVertexProgramParameters( + pass->getShadowReceiverVertexProgramParameters()); + // Also have to hack the light autoparams, that is done later + } + else + { + if (retPass == mShadowTextureCustomReceiverPass) + { + // reset vp? + if (mShadowTextureCustomReceiverPass->getVertexProgramName() != + mShadowTextureCustomReceiverVertexProgram) + { + mShadowTextureCustomReceiverPass->setVertexProgram( + mShadowTextureCustomReceiverVertexProgram, false); + if(mShadowTextureCustomReceiverPass->hasVertexProgram()) + { + mShadowTextureCustomReceiverPass->setVertexProgramParameters( + mShadowTextureCustomReceiverVPParams); + + } + + } + + } + else + { + // Standard shadow receiver pass, reset to no vp + retPass->setVertexProgram(BLANKSTRING); + } + } + + unsigned short keepTUCount; + // If additive, need lighting parameters & standard programs + if (isShadowTechniqueAdditive()) + { + retPass->setLightingEnabled(true); + retPass->setAmbient(pass->getAmbient()); + retPass->setSelfIllumination(pass->getSelfIllumination()); + retPass->setDiffuse(pass->getDiffuse()); + retPass->setSpecular(pass->getSpecular()); + retPass->setShininess(pass->getShininess()); + retPass->setIteratePerLight(pass->getIteratePerLight(), + pass->getRunOnlyForOneLightType(), pass->getOnlyLightType()); + retPass->setLightMask(pass->getLightMask()); + + // We need to keep alpha rejection settings + retPass->setAlphaRejectSettings(pass->getAlphaRejectFunction(), + pass->getAlphaRejectValue()); + // Copy texture state, shift up one since 0 is shadow texture + unsigned short origPassTUCount = pass->getNumTextureUnitStates(); + for (unsigned short t = 0; t < origPassTUCount; ++t) + { + unsigned short targetIndex = t+1; + TextureUnitState* tex; + if (retPass->getNumTextureUnitStates() <= targetIndex) + { + tex = retPass->createTextureUnitState(); + } + else + { + tex = retPass->getTextureUnitState(targetIndex); + } + (*tex) = *(pass->getTextureUnitState(t)); + // If programmable, have to adjust the texcoord sets too + // D3D insists that texcoordsets match tex unit in programmable mode + if (retPass->hasVertexProgram()) + tex->setTextureCoordSet(targetIndex); + } + keepTUCount = origPassTUCount + 1; + }// additive lighting + else + { + // need to keep spotlight fade etc + keepTUCount = retPass->getNumTextureUnitStates(); + } + + + // Will also need fragment programs since this is a complex light setup + if (!pass->getShadowReceiverFragmentProgramName().empty()) + { + // Have to merge the shadow receiver vertex program in + retPass->setFragmentProgram( + pass->getShadowReceiverFragmentProgramName(), false); + const GpuProgramPtr& prg = retPass->getFragmentProgram(); + // Load this program if not done already + if (!prg->isLoaded()) + prg->load(); + // Copy params + retPass->setFragmentProgramParameters( + pass->getShadowReceiverFragmentProgramParameters()); + + // Did we bind a shadow vertex program? + if (pass->hasVertexProgram() && !retPass->hasVertexProgram()) + { + // We didn't bind a receiver-specific program, so bind the original + retPass->setVertexProgram(pass->getVertexProgramName(), false); + const GpuProgramPtr& prog = retPass->getVertexProgram(); + // Load this program if required + if (!prog->isLoaded()) + prog->load(); + // Copy params + retPass->setVertexProgramParameters( + pass->getVertexProgramParameters()); + + } + } + else + { + // Reset any merged fragment programs from last time + if (retPass == mShadowTextureCustomReceiverPass) + { + // reset fp? + if (mShadowTextureCustomReceiverPass->getFragmentProgramName() != + mShadowTextureCustomReceiverFragmentProgram) + { + mShadowTextureCustomReceiverPass->setFragmentProgram( + mShadowTextureCustomReceiverFragmentProgram, false); + if(mShadowTextureCustomReceiverPass->hasFragmentProgram()) + { + mShadowTextureCustomReceiverPass->setFragmentProgramParameters( + mShadowTextureCustomReceiverFPParams); + + } + + } + + } + else + { + // Standard shadow receiver pass, reset to no fp + retPass->setFragmentProgram(BLANKSTRING); + } + + } + + // Remove any extra texture units + while (retPass->getNumTextureUnitStates() > keepTUCount) + { + retPass->removeTextureUnitState(keepTUCount); + } + + retPass->_load(); + + // handle the case where there is no fixed pipeline support + if( retPass->getParent()->getParent()->getCompilationRequired() ) + retPass->getParent()->getParent()->compile(); + + Technique* btech = retPass->getParent()->getParent()->getBestTechnique(); + if( btech ) + { + retPass = btech->getPass(0); + } + + return retPass; + } + else + { + return pass; + } - return CLIPPED_SOME; - } - else - return CLIPPED_NONE; +} +//--------------------------------------------------------------------- +const RealRect& SceneManager::getLightScissorRect(Light* l, const Camera* cam) +{ + checkCachedLightClippingInfo(); + + // Re-use calculations if possible + LightClippingInfoMap::iterator ci = mLightClippingInfoMap.find(l); + if (ci == mLightClippingInfoMap.end()) + { + // create new entry + ci = mLightClippingInfoMap.insert(LightClippingInfoMap::value_type(l, LightClippingInfo())).first; + } + if (!ci->second.scissorValid) + { + + buildScissor(l, cam, ci->second.scissorRect); + ci->second.scissorValid = true; + } + + return ci->second.scissorRect; + +} +//--------------------------------------------------------------------- +ClipResult SceneManager::buildAndSetScissor(const LightList& ll, const Camera* cam) +{ + if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_SCISSOR_TEST)) + return CLIPPED_NONE; + + RealRect finalRect; + // init (inverted since we want to grow from nothing) + finalRect.left = finalRect.bottom = 1.0f; + finalRect.right = finalRect.top = -1.0f; + + for (LightList::const_iterator i = ll.begin(); i != ll.end(); ++i) + { + Light* l = *i; + // a directional light is being used, no scissoring can be done, period. + if (l->getType() == Light::LT_DIRECTIONAL) + return CLIPPED_NONE; + + const RealRect& scissorRect = getLightScissorRect(l, cam); + + // merge with final + finalRect.left = std::min(finalRect.left, scissorRect.left); + finalRect.bottom = std::min(finalRect.bottom, scissorRect.bottom); + finalRect.right= std::max(finalRect.right, scissorRect.right); + finalRect.top = std::max(finalRect.top, scissorRect.top); + + + } + + if (finalRect.left >= 1.0f || finalRect.right <= -1.0f || + finalRect.top <= -1.0f || finalRect.bottom >= 1.0f) + { + // rect was offscreen + return CLIPPED_ALL; + } + + // Some scissoring? + if (finalRect.left > -1.0f || finalRect.right < 1.0f || + finalRect.bottom > -1.0f || finalRect.top < 1.0f) + { + // Turn normalised device coordinates into pixels + int iLeft, iTop, iWidth, iHeight; + mCurrentViewport->getActualDimensions(iLeft, iTop, iWidth, iHeight); + size_t szLeft, szRight, szTop, szBottom; + + szLeft = (size_t)(iLeft + ((finalRect.left + 1) * 0.5 * iWidth)); + szRight = (size_t)(iLeft + ((finalRect.right + 1) * 0.5 * iWidth)); + szTop = (size_t)(iTop + ((-finalRect.top + 1) * 0.5 * iHeight)); + szBottom = (size_t)(iTop + ((-finalRect.bottom + 1) * 0.5 * iHeight)); + + mDestRenderSystem->setScissorTest(true, szLeft, szTop, szRight, szBottom); + + return CLIPPED_SOME; + } + else + return CLIPPED_NONE; } //--------------------------------------------------------------------- void SceneManager::buildScissor(const Light* light, const Camera* cam, RealRect& rect) { - // Project the sphere onto the camera - Sphere sphere(light->getDerivedPosition(), light->getAttenuationRange()); - cam->projectSphere(sphere, &(rect.left), &(rect.top), &(rect.right), &(rect.bottom)); + // Project the sphere onto the camera + Sphere sphere(light->getDerivedPosition(), light->getAttenuationRange()); + cam->projectSphere(sphere, &(rect.left), &(rect.top), &(rect.right), &(rect.bottom)); } //--------------------------------------------------------------------- void SceneManager::resetScissor() { - if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_SCISSOR_TEST)) - return; + if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_SCISSOR_TEST)) + return; - mDestRenderSystem->setScissorTest(false); + mDestRenderSystem->setScissorTest(false); } //--------------------------------------------------------------------- void SceneManager::checkCachedLightClippingInfo() { - unsigned long frame = Root::getSingleton().getNextFrameNumber(); - if (frame != mLightClippingInfoMapFrameNumber) - { - // reset cached clip information - mLightClippingInfoMap.clear(); - mLightClippingInfoMapFrameNumber = frame; - } + unsigned long frame = Root::getSingleton().getNextFrameNumber(); + if (frame != mLightClippingInfoMapFrameNumber) + { + // reset cached clip information + mLightClippingInfoMap.clear(); + mLightClippingInfoMapFrameNumber = frame; + } } //--------------------------------------------------------------------- const PlaneList& SceneManager::getLightClippingPlanes(Light* l) { - checkCachedLightClippingInfo(); + checkCachedLightClippingInfo(); - // Try to re-use clipping info if already calculated - LightClippingInfoMap::iterator ci = mLightClippingInfoMap.find(l); - if (ci == mLightClippingInfoMap.end()) - { - // create new entry - ci = mLightClippingInfoMap.insert(LightClippingInfoMap::value_type(l, LightClippingInfo())).first; - } - if (!ci->second.clipPlanesValid) - { - buildLightClip(l, ci->second.clipPlanes); - ci->second.clipPlanesValid = true; - } - return ci->second.clipPlanes; - + // Try to re-use clipping info if already calculated + LightClippingInfoMap::iterator ci = mLightClippingInfoMap.find(l); + if (ci == mLightClippingInfoMap.end()) + { + // create new entry + ci = mLightClippingInfoMap.insert(LightClippingInfoMap::value_type(l, LightClippingInfo())).first; + } + if (!ci->second.clipPlanesValid) + { + buildLightClip(l, ci->second.clipPlanes); + ci->second.clipPlanesValid = true; + } + return ci->second.clipPlanes; + } //--------------------------------------------------------------------- ClipResult SceneManager::buildAndSetLightClip(const LightList& ll) { - if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) - return CLIPPED_NONE; - - Light* clipBase = 0; - for (LightList::const_iterator i = ll.begin(); i != ll.end(); ++i) - { - // a directional light is being used, no clipping can be done, period. - if ((*i)->getType() == Light::LT_DIRECTIONAL) - return CLIPPED_NONE; - - if (clipBase) - { - // we already have a clip base, so we had more than one light - // in this list we could clip by, so clip none - return CLIPPED_NONE; - } - clipBase = *i; - } - - if (clipBase) - { - const PlaneList& clipPlanes = getLightClippingPlanes(clipBase); - - mDestRenderSystem->setClipPlanes(clipPlanes); - return CLIPPED_SOME; - } - else - { - // Can only get here if no non-directional lights from which to clip from - // ie list must be empty - return CLIPPED_ALL; - } + if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) + return CLIPPED_NONE; + + Light* clipBase = 0; + for (LightList::const_iterator i = ll.begin(); i != ll.end(); ++i) + { + // a directional light is being used, no clipping can be done, period. + if ((*i)->getType() == Light::LT_DIRECTIONAL) + return CLIPPED_NONE; + + if (clipBase) + { + // we already have a clip base, so we had more than one light + // in this list we could clip by, so clip none + return CLIPPED_NONE; + } + clipBase = *i; + } + + if (clipBase) + { + const PlaneList& clipPlanes = getLightClippingPlanes(clipBase); + + mDestRenderSystem->setClipPlanes(clipPlanes); + return CLIPPED_SOME; + } + else + { + // Can only get here if no non-directional lights from which to clip from + // ie list must be empty + return CLIPPED_ALL; + } } //--------------------------------------------------------------------- void SceneManager::buildLightClip(const Light* l, PlaneList& planes) { - if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) - return; - - planes.clear(); - - Vector3 pos = l->getDerivedPosition(); - Real r = l->getAttenuationRange(); - switch(l->getType()) - { - case Light::LT_POINT: - { - planes.push_back(Plane(Vector3::UNIT_X, pos + Vector3(-r, 0, 0))); - planes.push_back(Plane(Vector3::NEGATIVE_UNIT_X, pos + Vector3(r, 0, 0))); - planes.push_back(Plane(Vector3::UNIT_Y, pos + Vector3(0, -r, 0))); - planes.push_back(Plane(Vector3::NEGATIVE_UNIT_Y, pos + Vector3(0, r, 0))); - planes.push_back(Plane(Vector3::UNIT_Z, pos + Vector3(0, 0, -r))); - planes.push_back(Plane(Vector3::NEGATIVE_UNIT_Z, pos + Vector3(0, 0, r))); - } - break; - case Light::LT_SPOTLIGHT: - { - Vector3 dir = l->getDerivedDirection(); - // near & far planes - planes.push_back(Plane(dir, pos + dir * l->getSpotlightNearClipDistance())); - planes.push_back(Plane(-dir, pos + dir * r)); - // 4 sides of pyramids - // derive orientation - Vector3 up = Vector3::UNIT_Y; - // Check it's not coincident with dir - if (Math::Abs(up.dotProduct(dir)) >= 1.0f) - { - up = Vector3::UNIT_Z; - } - // cross twice to rederive, only direction is unaltered - Vector3 right = dir.crossProduct(up); - right.normalise(); - up = right.crossProduct(dir); - up.normalise(); - // Derive quaternion from axes (negate dir since -Z) - Quaternion q; - q.FromAxes(right, up, -dir); - - // derive pyramid corner vectors in world orientation - Vector3 tl, tr, bl, br; - Real d = Math::Tan(l->getSpotlightOuterAngle() * 0.5) * r; - tl = q * Vector3(-d, d, -r); - tr = q * Vector3(d, d, -r); - bl = q * Vector3(-d, -d, -r); - br = q * Vector3(d, -d, -r); - - // use cross product to derive normals, pass through light world pos - // top - planes.push_back(Plane(tl.crossProduct(tr).normalisedCopy(), pos)); - // right - planes.push_back(Plane(tr.crossProduct(br).normalisedCopy(), pos)); - // bottom - planes.push_back(Plane(br.crossProduct(bl).normalisedCopy(), pos)); - // left - planes.push_back(Plane(bl.crossProduct(tl).normalisedCopy(), pos)); - - } - break; - default: - // do nothing - break; - }; + if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) + return; + + planes.clear(); + + Vector3 pos = l->getDerivedPosition(); + Real r = l->getAttenuationRange(); + switch(l->getType()) + { + case Light::LT_POINT: + { + planes.push_back(Plane(Vector3::UNIT_X, pos + Vector3(-r, 0, 0))); + planes.push_back(Plane(Vector3::NEGATIVE_UNIT_X, pos + Vector3(r, 0, 0))); + planes.push_back(Plane(Vector3::UNIT_Y, pos + Vector3(0, -r, 0))); + planes.push_back(Plane(Vector3::NEGATIVE_UNIT_Y, pos + Vector3(0, r, 0))); + planes.push_back(Plane(Vector3::UNIT_Z, pos + Vector3(0, 0, -r))); + planes.push_back(Plane(Vector3::NEGATIVE_UNIT_Z, pos + Vector3(0, 0, r))); + } + break; + case Light::LT_SPOTLIGHT: + { + Vector3 dir = l->getDerivedDirection(); + // near & far planes + planes.push_back(Plane(dir, pos + dir * l->getSpotlightNearClipDistance())); + planes.push_back(Plane(-dir, pos + dir * r)); + // 4 sides of pyramids + // derive orientation + Vector3 up = Vector3::UNIT_Y; + // Check it's not coincident with dir + if (Math::Abs(up.dotProduct(dir)) >= 1.0f) + { + up = Vector3::UNIT_Z; + } + // cross twice to rederive, only direction is unaltered + Vector3 right = dir.crossProduct(up); + right.normalise(); + up = right.crossProduct(dir); + up.normalise(); + // Derive quaternion from axes (negate dir since -Z) + Quaternion q; + q.FromAxes(right, up, -dir); + + // derive pyramid corner vectors in world orientation + Vector3 tl, tr, bl, br; + Real d = Math::Tan(l->getSpotlightOuterAngle() * 0.5) * r; + tl = q * Vector3(-d, d, -r); + tr = q * Vector3(d, d, -r); + bl = q * Vector3(-d, -d, -r); + br = q * Vector3(d, -d, -r); + + // use cross product to derive normals, pass through light world pos + // top + planes.push_back(Plane(tl.crossProduct(tr).normalisedCopy(), pos)); + // right + planes.push_back(Plane(tr.crossProduct(br).normalisedCopy(), pos)); + // bottom + planes.push_back(Plane(br.crossProduct(bl).normalisedCopy(), pos)); + // left + planes.push_back(Plane(bl.crossProduct(tl).normalisedCopy(), pos)); + + } + break; + default: + // do nothing + break; + }; } //--------------------------------------------------------------------- void SceneManager::resetLightClip() { - if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) - return; + if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) + return; - mDestRenderSystem->resetClipPlanes(); + mDestRenderSystem->resetClipPlanes(); } //--------------------------------------------------------------------- void SceneManager::renderShadowVolumesToStencil(const Light* light, - const Camera* camera, bool calcScissor) + const Camera* camera, bool calcScissor) { // Get the shadow caster list const ShadowCasterList& casters = findShadowCastersForLight(light, camera); @@ -5481,19 +5481,19 @@ void SceneManager::renderShadowVolumesToStencil(const Light* light, return; } - // Add light to internal list for use in render call - LightList lightList; - // const_cast is forgiveable here since we pass this const - lightList.push_back(const_cast(light)); + // Add light to internal list for use in render call + LightList lightList; + // const_cast is forgiveable here since we pass this const + lightList.push_back(const_cast(light)); // Set up scissor test (point & spot lights only) ClipResult scissored = CLIPPED_NONE; - if (calcScissor) - { - scissored = buildAndSetScissor(lightList, camera); - if (scissored == CLIPPED_ALL) - return; // nothing to do - } + if (calcScissor) + { + scissored = buildAndSetScissor(lightList, camera); + if (scissored == CLIPPED_ALL) + return; // nothing to do + } mDestRenderSystem->unbindGpuProgram(GPT_FRAGMENT_PROGRAM); @@ -5518,7 +5518,7 @@ void SceneManager::renderShadowVolumesToStencil(const Light* light, mShadowStencilPass->setVertexProgram( ShadowVolumeExtrudeProgram::getProgramName(light->getType(), finiteExtrude, false) , false); - mShadowStencilPass->setFragmentProgram(ShadowVolumeExtrudeProgram::frgProgramName); + mShadowStencilPass->setFragmentProgram(ShadowVolumeExtrudeProgram::frgProgramName); // Set params if (finiteExtrude) { @@ -5532,8 +5532,8 @@ void SceneManager::renderShadowVolumesToStencil(const Light* light, { mShadowDebugPass->setVertexProgram( ShadowVolumeExtrudeProgram::getProgramName(light->getType(), finiteExtrude, true) - , false); - mShadowDebugPass->setFragmentProgram(ShadowVolumeExtrudeProgram::frgProgramName); + , false); + mShadowDebugPass->setFragmentProgram(ShadowVolumeExtrudeProgram::frgProgramName); // Set params @@ -5548,10 +5548,10 @@ void SceneManager::renderShadowVolumesToStencil(const Light* light, } bindGpuProgram(mShadowStencilPass->getVertexProgram()->_getBindingDelegate()); - if (!ShadowVolumeExtrudeProgram::frgProgramName.empty()) - { - bindGpuProgram(mShadowStencilPass->getFragmentProgram()->_getBindingDelegate()); - } + if (!ShadowVolumeExtrudeProgram::frgProgramName.empty()) + { + bindGpuProgram(mShadowStencilPass->getFragmentProgram()->_getBindingDelegate()); + } } else @@ -5561,7 +5561,7 @@ void SceneManager::renderShadowVolumesToStencil(const Light* light, // Turn off colour writing and depth writing mDestRenderSystem->_setColourBufferWriteEnabled(false, false, false, false); - mDestRenderSystem->_disableTextureUnitsFrom(0); + mDestRenderSystem->_disableTextureUnitsFrom(0); mDestRenderSystem->_setDepthBufferParams(true, false, CMPF_LESS); mDestRenderSystem->setStencilCheckEnabled(true); @@ -5579,12 +5579,12 @@ void SceneManager::renderShadowVolumesToStencil(const Light* light, siend = casters.end(); - // Now iterate over the casters and render - for (si = casters.begin(); si != siend; ++si) - { + // Now iterate over the casters and render + for (si = casters.begin(); si != siend; ++si) + { ShadowCaster* caster = *si; - bool zfailAlgo = camera->isCustomNearClipPlaneEnabled(); - unsigned long flags = 0; + bool zfailAlgo = camera->isCustomNearClipPlaneEnabled(); + unsigned long flags = 0; if (light->getType() != Light::LT_DIRECTIONAL) { @@ -5599,52 +5599,52 @@ void SceneManager::renderShadowVolumesToStencil(const Light* light, darkCapExtrudeDist = mShadowDirLightExtrudeDist; } - // Determine whether zfail is required + // Determine whether zfail is required if (zfailAlgo || nearClipVol.intersects(caster->getWorldBoundingBox())) { // We use zfail for this object only because zfail - // compatible with zpass algorithm - zfailAlgo = true; + // compatible with zpass algorithm + zfailAlgo = true; // We need to include the light and / or dark cap // But only if they will be visible if(camera->isVisible(caster->getLightCapBounds())) { flags |= SRF_INCLUDE_LIGHT_CAP; } - // zfail needs dark cap - // UNLESS directional lights using hardware extrusion to infinity - // since that extrudes to a single point - if(!((flags & SRF_EXTRUDE_TO_INFINITY) && - light->getType() == Light::LT_DIRECTIONAL) && - camera->isVisible(caster->getDarkCapBounds(*light, darkCapExtrudeDist))) - { - flags |= SRF_INCLUDE_DARK_CAP; - } - } - else - { - // In zpass we need a dark cap if - // 1: infinite extrusion on point/spotlight sources in modulative shadows - // mode, since otherwise in areas where there is no depth (skybox) - // the infinitely projected volume will leave a dark band - // 2: finite extrusion on any light source since glancing angles - // can peek through the end and shadow objects behind incorrectly - if ((flags & SRF_EXTRUDE_TO_INFINITY) && - light->getType() != Light::LT_DIRECTIONAL && - isShadowTechniqueModulative() && - camera->isVisible(caster->getDarkCapBounds(*light, darkCapExtrudeDist))) - { - flags |= SRF_INCLUDE_DARK_CAP; - } - else if (!(flags & SRF_EXTRUDE_TO_INFINITY) && - camera->isVisible(caster->getDarkCapBounds(*light, darkCapExtrudeDist))) - { - flags |= SRF_INCLUDE_DARK_CAP; - } - - } - - // Get shadow renderables + // zfail needs dark cap + // UNLESS directional lights using hardware extrusion to infinity + // since that extrudes to a single point + if(!((flags & SRF_EXTRUDE_TO_INFINITY) && + light->getType() == Light::LT_DIRECTIONAL) && + camera->isVisible(caster->getDarkCapBounds(*light, darkCapExtrudeDist))) + { + flags |= SRF_INCLUDE_DARK_CAP; + } + } + else + { + // In zpass we need a dark cap if + // 1: infinite extrusion on point/spotlight sources in modulative shadows + // mode, since otherwise in areas where there is no depth (skybox) + // the infinitely projected volume will leave a dark band + // 2: finite extrusion on any light source since glancing angles + // can peek through the end and shadow objects behind incorrectly + if ((flags & SRF_EXTRUDE_TO_INFINITY) && + light->getType() != Light::LT_DIRECTIONAL && + isShadowTechniqueModulative() && + camera->isVisible(caster->getDarkCapBounds(*light, darkCapExtrudeDist))) + { + flags |= SRF_INCLUDE_DARK_CAP; + } + else if (!(flags & SRF_EXTRUDE_TO_INFINITY) && + camera->isVisible(caster->getDarkCapBounds(*light, darkCapExtrudeDist))) + { + flags |= SRF_INCLUDE_DARK_CAP; + } + + } + + // Get shadow renderables ShadowCaster::ShadowRenderableListIterator iShadowRenderables = caster->getShadowVolumeRenderableIterator(mShadowTechnique, light, &mShadowIndexBuffer, &mShadowIndexBufferUsedSize, @@ -5744,13 +5744,13 @@ void SceneManager::renderShadowVolumeObjects(ShadowCaster::ShadowRenderableListI { // select back facing light caps to render mDestRenderSystem->_setCullingMode(CULL_ANTICLOCKWISE); - mPassCullingMode = CULL_ANTICLOCKWISE; + mPassCullingMode = CULL_ANTICLOCKWISE; // use normal depth function for back facing light caps renderSingleObject(lightCap, pass, false, false, manualLightList); // select front facing light caps to render mDestRenderSystem->_setCullingMode(CULL_CLOCKWISE); - mPassCullingMode = CULL_CLOCKWISE; + mPassCullingMode = CULL_CLOCKWISE; // must always fail depth check for front facing light caps mDestRenderSystem->_setDepthBufferFunction(CMPF_ALWAYS_FAIL); renderSingleObject(lightCap, pass, false, false, manualLightList); @@ -5759,7 +5759,7 @@ void SceneManager::renderShadowVolumeObjects(ShadowCaster::ShadowRenderableListI mDestRenderSystem->_setDepthBufferFunction(CMPF_LESS); // reset culling mode mDestRenderSystem->_setCullingMode(CULL_NONE); - mPassCullingMode = CULL_NONE; + mPassCullingMode = CULL_NONE; } else if ((secondpass || zfail) && !(secondpass && zfail)) { @@ -5804,7 +5804,7 @@ void SceneManager::setShadowVolumeStencilState(bool secondpass, bool zfail, bool // for back faces if ( !twosided && ((secondpass || zfail) && !(secondpass && zfail)) ) { - mPassCullingMode = twosided? CULL_NONE : CULL_ANTICLOCKWISE; + mPassCullingMode = twosided? CULL_NONE : CULL_ANTICLOCKWISE; mDestRenderSystem->setStencilBufferParams( CMPF_ALWAYS_PASS, // always pass stencil check 0, // no ref value (no compare) @@ -5814,33 +5814,33 @@ void SceneManager::setShadowVolumeStencilState(bool secondpass, bool zfail, bool zfail ? incrOp : SOP_KEEP, // back face depth fail zfail ? SOP_KEEP : decrOp, // back face pass twosided, - false + false ); } else { - mPassCullingMode = twosided? CULL_NONE : CULL_CLOCKWISE; + mPassCullingMode = twosided? CULL_NONE : CULL_CLOCKWISE; mDestRenderSystem->setStencilBufferParams( CMPF_ALWAYS_PASS, // always pass stencil check 0, // no ref value (no compare) - 0xFFFFFFFF, // no compare mask + 0xFFFFFFFF, // no compare mask 0xFFFFFFFF, // no write mask SOP_KEEP, // stencil test will never fail zfail ? decrOp : SOP_KEEP, // front face depth fail zfail ? SOP_KEEP : incrOp, // front face pass twosided, - false + false ); } - mDestRenderSystem->_setCullingMode(mPassCullingMode); + mDestRenderSystem->_setCullingMode(mPassCullingMode); } //--------------------------------------------------------------------- void SceneManager::renderUsingReadBackAsTexture(unsigned int secondPass, Ogre::String variableName, unsigned int StartSlot) { - if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_READ_BACK_AS_TEXTURE)) return; + if (!mDestRenderSystem->getCapabilities()->hasCapability(RSC_READ_BACK_AS_TEXTURE)) return; - mDestRenderSystem->_renderUsingReadBackAsTexture(secondPass,variableName,StartSlot); + mDestRenderSystem->_renderUsingReadBackAsTexture(secondPass,variableName,StartSlot); } //--------------------------------------------------------------------- void SceneManager::setShadowColour(const ColourValue& colour) @@ -5889,90 +5889,90 @@ void SceneManager::setShadowIndexBufferSize(size_t size) false); } mShadowIndexBufferSize = size; - mShadowIndexBufferUsedSize = 0; + mShadowIndexBufferUsedSize = 0; } //--------------------------------------------------------------------- void SceneManager::setShadowTextureConfig(size_t shadowIndex, unsigned short width, - unsigned short height, PixelFormat format, unsigned short fsaa, uint16 depthBufferPoolId ) + unsigned short height, PixelFormat format, unsigned short fsaa, uint16 depthBufferPoolId ) { - ShadowTextureConfig conf; - conf.width = width; - conf.height = height; - conf.format = format; + ShadowTextureConfig conf; + conf.width = width; + conf.height = height; + conf.format = format; conf.fsaa = fsaa; - conf.depthBufferPoolId = depthBufferPoolId; + conf.depthBufferPoolId = depthBufferPoolId; - setShadowTextureConfig(shadowIndex, conf); + setShadowTextureConfig(shadowIndex, conf); } //--------------------------------------------------------------------- void SceneManager::setShadowTextureConfig(size_t shadowIndex, - const ShadowTextureConfig& config) + const ShadowTextureConfig& config) { - if (shadowIndex >= mShadowTextureConfigList.size()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "shadowIndex out of bounds", - "SceneManager::setShadowTextureConfig"); - } - mShadowTextureConfigList[shadowIndex] = config; + if (shadowIndex >= mShadowTextureConfigList.size()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "shadowIndex out of bounds", + "SceneManager::setShadowTextureConfig"); + } + mShadowTextureConfigList[shadowIndex] = config; - mShadowTextureConfigDirty = true; + mShadowTextureConfigDirty = true; } //--------------------------------------------------------------------- ConstShadowTextureConfigIterator SceneManager::getShadowTextureConfigIterator() const { - return ConstShadowTextureConfigIterator( - mShadowTextureConfigList.begin(), mShadowTextureConfigList.end()); + return ConstShadowTextureConfigIterator( + mShadowTextureConfigList.begin(), mShadowTextureConfigList.end()); } //--------------------------------------------------------------------- void SceneManager::setShadowTextureSize(unsigned short size) { - // default all current - for (ShadowTextureConfigList::iterator i = mShadowTextureConfigList.begin(); - i != mShadowTextureConfigList.end(); ++i) - { - if (i->width != size || i->height != size) - { - i->width = i->height = size; - mShadowTextureConfigDirty = true; - } - } + // default all current + for (ShadowTextureConfigList::iterator i = mShadowTextureConfigList.begin(); + i != mShadowTextureConfigList.end(); ++i) + { + if (i->width != size || i->height != size) + { + i->width = i->height = size; + mShadowTextureConfigDirty = true; + } + } } //--------------------------------------------------------------------- void SceneManager::setShadowTextureCount(size_t count) { // Change size, any new items will need defaults - if (count != mShadowTextureConfigList.size()) - { - // if no entries yet, use the defaults - if (mShadowTextureConfigList.empty()) - { - mShadowTextureConfigList.resize(count); - } - else - { - // create new instances with the same settings as the last item in the list - mShadowTextureConfigList.resize(count, *mShadowTextureConfigList.rbegin()); - } - mShadowTextureConfigDirty = true; - } + if (count != mShadowTextureConfigList.size()) + { + // if no entries yet, use the defaults + if (mShadowTextureConfigList.empty()) + { + mShadowTextureConfigList.resize(count); + } + else + { + // create new instances with the same settings as the last item in the list + mShadowTextureConfigList.resize(count, *mShadowTextureConfigList.rbegin()); + } + mShadowTextureConfigDirty = true; + } } //--------------------------------------------------------------------- void SceneManager::setShadowTexturePixelFormat(PixelFormat fmt) { - for (ShadowTextureConfigList::iterator i = mShadowTextureConfigList.begin(); - i != mShadowTextureConfigList.end(); ++i) - { - if (i->format != fmt) - { - i->format = fmt; - mShadowTextureConfigDirty = true; - } - } + for (ShadowTextureConfigList::iterator i = mShadowTextureConfigList.begin(); + i != mShadowTextureConfigList.end(); ++i) + { + if (i->format != fmt) + { + i->format = fmt; + mShadowTextureConfigDirty = true; + } + } } void SceneManager::setShadowTextureFSAA(unsigned short fsaa) { @@ -5988,638 +5988,638 @@ void SceneManager::setShadowTextureFSAA(unsigned short fsaa) } //--------------------------------------------------------------------- void SceneManager::setShadowTextureSettings(unsigned short size, - unsigned short count, PixelFormat fmt, unsigned short fsaa, uint16 depthBufferPoolId) -{ - setShadowTextureCount(count); - for (ShadowTextureConfigList::iterator i = mShadowTextureConfigList.begin(); - i != mShadowTextureConfigList.end(); ++i) - { - if (i->width != size || i->height != size || i->format != fmt || i->fsaa != fsaa) - { - i->width = i->height = size; - i->format = fmt; + unsigned short count, PixelFormat fmt, unsigned short fsaa, uint16 depthBufferPoolId) +{ + setShadowTextureCount(count); + for (ShadowTextureConfigList::iterator i = mShadowTextureConfigList.begin(); + i != mShadowTextureConfigList.end(); ++i) + { + if (i->width != size || i->height != size || i->format != fmt || i->fsaa != fsaa) + { + i->width = i->height = size; + i->format = fmt; i->fsaa = fsaa; - i->depthBufferPoolId = depthBufferPoolId; - mShadowTextureConfigDirty = true; - } - } + i->depthBufferPoolId = depthBufferPoolId; + mShadowTextureConfigDirty = true; + } + } } //--------------------------------------------------------------------- const TexturePtr& SceneManager::getShadowTexture(size_t shadowIndex) { - if (shadowIndex >= mShadowTextureConfigList.size()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "shadowIndex out of bounds", - "SceneManager::getShadowTexture"); - } - ensureShadowTexturesCreated(); + if (shadowIndex >= mShadowTextureConfigList.size()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "shadowIndex out of bounds", + "SceneManager::getShadowTexture"); + } + ensureShadowTexturesCreated(); - return mShadowTextures[shadowIndex]; + return mShadowTextures[shadowIndex]; } //--------------------------------------------------------------------- void SceneManager::setShadowTextureSelfShadow(bool selfShadow) { - mShadowTextureSelfShadow = selfShadow; - if (isShadowTechniqueTextureBased()) - getRenderQueue()->setShadowCastersCannotBeReceivers(!selfShadow); + mShadowTextureSelfShadow = selfShadow; + if (isShadowTechniqueTextureBased()) + getRenderQueue()->setShadowCastersCannotBeReceivers(!selfShadow); } //--------------------------------------------------------------------- void SceneManager::setShadowTextureCasterMaterial(const String& name) { - if (name.empty()) - { - mShadowTextureCustomCasterPass = 0; - } - else - { - MaterialPtr mat = MaterialManager::getSingleton().getByName(name); - if (mat.isNull()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot locate material called '" + name + "'", - "SceneManager::setShadowTextureCasterMaterial"); - } - mat->load(); - if (!mat->getBestTechnique()) - { - // unsupported - mShadowTextureCustomCasterPass = 0; - } - else - { - - mShadowTextureCustomCasterPass = mat->getBestTechnique()->getPass(0); - if (mShadowTextureCustomCasterPass->hasVertexProgram()) - { - // Save vertex program and params in case we have to swap them out - mShadowTextureCustomCasterVertexProgram = - mShadowTextureCustomCasterPass->getVertexProgramName(); - mShadowTextureCustomCasterVPParams = - mShadowTextureCustomCasterPass->getVertexProgramParameters(); - } - if (mShadowTextureCustomCasterPass->hasFragmentProgram()) - { - // Save fragment program and params in case we have to swap them out - mShadowTextureCustomCasterFragmentProgram = - mShadowTextureCustomCasterPass->getFragmentProgramName(); - mShadowTextureCustomCasterFPParams = - mShadowTextureCustomCasterPass->getFragmentProgramParameters(); - } - } - } -} -//--------------------------------------------------------------------- -void SceneManager::setShadowTextureReceiverMaterial(const String& name) + if (name.empty()) + { + mShadowTextureCustomCasterPass = 0; + } + else + { + MaterialPtr mat = MaterialManager::getSingleton().getByName(name); + if (mat.isNull()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot locate material called '" + name + "'", + "SceneManager::setShadowTextureCasterMaterial"); + } + mat->load(); + if (!mat->getBestTechnique()) + { + // unsupported + mShadowTextureCustomCasterPass = 0; + } + else + { + + mShadowTextureCustomCasterPass = mat->getBestTechnique()->getPass(0); + if (mShadowTextureCustomCasterPass->hasVertexProgram()) + { + // Save vertex program and params in case we have to swap them out + mShadowTextureCustomCasterVertexProgram = + mShadowTextureCustomCasterPass->getVertexProgramName(); + mShadowTextureCustomCasterVPParams = + mShadowTextureCustomCasterPass->getVertexProgramParameters(); + } + if (mShadowTextureCustomCasterPass->hasFragmentProgram()) + { + // Save fragment program and params in case we have to swap them out + mShadowTextureCustomCasterFragmentProgram = + mShadowTextureCustomCasterPass->getFragmentProgramName(); + mShadowTextureCustomCasterFPParams = + mShadowTextureCustomCasterPass->getFragmentProgramParameters(); + } + } + } +} +//--------------------------------------------------------------------- +void SceneManager::setShadowTextureReceiverMaterial(const String& name) { - if (name.empty()) - { - mShadowTextureCustomReceiverPass = 0; - } - else - { - MaterialPtr mat = MaterialManager::getSingleton().getByName(name); - if (mat.isNull()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot locate material called '" + name + "'", - "SceneManager::setShadowTextureReceiverMaterial"); - } - mat->load(); - if (!mat->getBestTechnique()) - { - // unsupported - mShadowTextureCustomReceiverPass = 0; - } - else - { - - mShadowTextureCustomReceiverPass = mat->getBestTechnique()->getPass(0); - if (mShadowTextureCustomReceiverPass->hasVertexProgram()) - { - // Save vertex program and params in case we have to swap them out - mShadowTextureCustomReceiverVertexProgram = - mShadowTextureCustomReceiverPass->getVertexProgramName(); - mShadowTextureCustomReceiverVPParams = - mShadowTextureCustomReceiverPass->getVertexProgramParameters(); - } - else - { - mShadowTextureCustomReceiverVertexProgram = BLANKSTRING; - } - if (mShadowTextureCustomReceiverPass->hasFragmentProgram()) - { - // Save fragment program and params in case we have to swap them out - mShadowTextureCustomReceiverFragmentProgram = - mShadowTextureCustomReceiverPass->getFragmentProgramName(); - mShadowTextureCustomReceiverFPParams = - mShadowTextureCustomReceiverPass->getFragmentProgramParameters(); - } - else - { - mShadowTextureCustomReceiverFragmentProgram = BLANKSTRING; - } - } - } + if (name.empty()) + { + mShadowTextureCustomReceiverPass = 0; + } + else + { + MaterialPtr mat = MaterialManager::getSingleton().getByName(name); + if (mat.isNull()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot locate material called '" + name + "'", + "SceneManager::setShadowTextureReceiverMaterial"); + } + mat->load(); + if (!mat->getBestTechnique()) + { + // unsupported + mShadowTextureCustomReceiverPass = 0; + } + else + { + + mShadowTextureCustomReceiverPass = mat->getBestTechnique()->getPass(0); + if (mShadowTextureCustomReceiverPass->hasVertexProgram()) + { + // Save vertex program and params in case we have to swap them out + mShadowTextureCustomReceiverVertexProgram = + mShadowTextureCustomReceiverPass->getVertexProgramName(); + mShadowTextureCustomReceiverVPParams = + mShadowTextureCustomReceiverPass->getVertexProgramParameters(); + } + else + { + mShadowTextureCustomReceiverVertexProgram = BLANKSTRING; + } + if (mShadowTextureCustomReceiverPass->hasFragmentProgram()) + { + // Save fragment program and params in case we have to swap them out + mShadowTextureCustomReceiverFragmentProgram = + mShadowTextureCustomReceiverPass->getFragmentProgramName(); + mShadowTextureCustomReceiverFPParams = + mShadowTextureCustomReceiverPass->getFragmentProgramParameters(); + } + else + { + mShadowTextureCustomReceiverFragmentProgram = BLANKSTRING; + } + } + } } //--------------------------------------------------------------------- void SceneManager::setShadowCameraSetup(const ShadowCameraSetupPtr& shadowSetup) { - mDefaultShadowCameraSetup = shadowSetup; + mDefaultShadowCameraSetup = shadowSetup; } //--------------------------------------------------------------------- const ShadowCameraSetupPtr& SceneManager::getShadowCameraSetup() const { - return mDefaultShadowCameraSetup; + return mDefaultShadowCameraSetup; } //--------------------------------------------------------------------- void SceneManager::ensureShadowTexturesCreated() { - if (mShadowTextureConfigDirty) - { - destroyShadowTextures(); - ShadowTextureManager::getSingleton().getShadowTextures( - mShadowTextureConfigList, mShadowTextures); - - // clear shadow cam - light mapping - mShadowCamLightMapping.clear(); - - //Used to get the depth buffer ID setting for each RTT - size_t __i = 0; - - // Recreate shadow textures - for (ShadowTextureList::iterator i = mShadowTextures.begin(); - i != mShadowTextures.end(); ++i, ++__i) - { - const TexturePtr& shadowTex = *i; - - // Camera names are local to SM - String camName = shadowTex->getName() + "Cam"; - // Material names are global to SM, make specific - String matName = shadowTex->getName() + "Mat" + getName(); - - RenderTexture *shadowRTT = shadowTex->getBuffer()->getRenderTarget(); - - //Set appropriate depth buffer - shadowRTT->setDepthBufferPool( mShadowTextureConfigList[__i].depthBufferPoolId ); - - // Create camera for this texture, but note that we have to rebind - // in prepareShadowTextures to coexist with multiple SMs - Camera* cam = createCamera(camName); - cam->setAspectRatio((Real)shadowTex->getWidth() / (Real)shadowTex->getHeight()); - mShadowTextureCameras.push_back(cam); - - // Create a viewport, if not there already - if (shadowRTT->getNumViewports() == 0) - { - // Note camera assignment is transient when multiple SMs - Viewport *v = shadowRTT->addViewport(cam); - v->setClearEveryFrame(true); - // remove overlays - v->setOverlaysEnabled(false); - } - - // Don't update automatically - we'll do it when required - shadowRTT->setAutoUpdated(false); - - // Also create corresponding Material used for rendering this shadow - MaterialPtr mat = MaterialManager::getSingleton().getByName(matName); - if (mat.isNull()) - { - mat = MaterialManager::getSingleton().create( - matName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); - } - Pass* p = mat->getTechnique(0)->getPass(0); - if (p->getNumTextureUnitStates() != 1 || - p->getTextureUnitState(0)->_getTexturePtr(0) != shadowTex) - { - mat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); - // create texture unit referring to render target texture - TextureUnitState* texUnit = - p->createTextureUnitState(shadowTex->getName()); - // set projective based on camera - texUnit->setProjectiveTexturing(!p->hasVertexProgram(), cam); - // clamp to border colour - texUnit->setTextureAddressingMode(TextureUnitState::TAM_BORDER); - texUnit->setTextureBorderColour(ColourValue::White); - mat->touch(); - - } - - // insert dummy camera-light combination - mShadowCamLightMapping[cam] = 0; - - // Get null shadow texture - if (mShadowTextureConfigList.empty()) - { - mNullShadowTexture.setNull(); - } - else - { - mNullShadowTexture = - ShadowTextureManager::getSingleton().getNullShadowTexture( - mShadowTextureConfigList[0].format); - } - - - } - mShadowTextureConfigDirty = false; - } + if (mShadowTextureConfigDirty) + { + destroyShadowTextures(); + ShadowTextureManager::getSingleton().getShadowTextures( + mShadowTextureConfigList, mShadowTextures); + + // clear shadow cam - light mapping + mShadowCamLightMapping.clear(); + + //Used to get the depth buffer ID setting for each RTT + size_t __i = 0; + + // Recreate shadow textures + for (ShadowTextureList::iterator i = mShadowTextures.begin(); + i != mShadowTextures.end(); ++i, ++__i) + { + const TexturePtr& shadowTex = *i; + + // Camera names are local to SM + String camName = shadowTex->getName() + "Cam"; + // Material names are global to SM, make specific + String matName = shadowTex->getName() + "Mat" + getName(); + + RenderTexture *shadowRTT = shadowTex->getBuffer()->getRenderTarget(); + + //Set appropriate depth buffer + shadowRTT->setDepthBufferPool( mShadowTextureConfigList[__i].depthBufferPoolId ); + + // Create camera for this texture, but note that we have to rebind + // in prepareShadowTextures to coexist with multiple SMs + Camera* cam = createCamera(camName); + cam->setAspectRatio((Real)shadowTex->getWidth() / (Real)shadowTex->getHeight()); + mShadowTextureCameras.push_back(cam); + + // Create a viewport, if not there already + if (shadowRTT->getNumViewports() == 0) + { + // Note camera assignment is transient when multiple SMs + Viewport *v = shadowRTT->addViewport(cam); + v->setClearEveryFrame(true); + // remove overlays + v->setOverlaysEnabled(false); + } + + // Don't update automatically - we'll do it when required + shadowRTT->setAutoUpdated(false); + + // Also create corresponding Material used for rendering this shadow + MaterialPtr mat = MaterialManager::getSingleton().getByName(matName); + if (mat.isNull()) + { + mat = MaterialManager::getSingleton().create( + matName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + } + Pass* p = mat->getTechnique(0)->getPass(0); + if (p->getNumTextureUnitStates() != 1 || + p->getTextureUnitState(0)->_getTexturePtr(0) != shadowTex) + { + mat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); + // create texture unit referring to render target texture + TextureUnitState* texUnit = + p->createTextureUnitState(shadowTex->getName()); + // set projective based on camera + texUnit->setProjectiveTexturing(!p->hasVertexProgram(), cam); + // clamp to border colour + texUnit->setTextureAddressingMode(TextureUnitState::TAM_BORDER); + texUnit->setTextureBorderColour(ColourValue::White); + mat->touch(); + + } + + // insert dummy camera-light combination + mShadowCamLightMapping[cam] = 0; + + // Get null shadow texture + if (mShadowTextureConfigList.empty()) + { + mNullShadowTexture.setNull(); + } + else + { + mNullShadowTexture = + ShadowTextureManager::getSingleton().getNullShadowTexture( + mShadowTextureConfigList[0].format); + } + + + } + mShadowTextureConfigDirty = false; + } } //--------------------------------------------------------------------- void SceneManager::destroyShadowTextures(void) { - - ShadowTextureList::iterator i, iend; - iend = mShadowTextures.end(); - for (i = mShadowTextures.begin(); i != iend; ++i) - { - TexturePtr &shadowTex = *i; - - // Cleanup material that references this texture - String matName = shadowTex->getName() + "Mat" + getName(); - MaterialPtr mat = MaterialManager::getSingleton().getByName(matName); - if (!mat.isNull()) - { - // manually clear TUS to ensure texture ref released - mat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); - MaterialManager::getSingleton().remove(mat->getHandle()); - } - - } - - ShadowTextureCameraList::iterator ci, ciend; - ciend = mShadowTextureCameras.end(); - for (ci = mShadowTextureCameras.begin(); ci != ciend; ++ci) - { - // Always destroy camera since they are local to this SM - destroyCamera(*ci); + + ShadowTextureList::iterator i, iend; + iend = mShadowTextures.end(); + for (i = mShadowTextures.begin(); i != iend; ++i) + { + TexturePtr &shadowTex = *i; + + // Cleanup material that references this texture + String matName = shadowTex->getName() + "Mat" + getName(); + MaterialPtr mat = MaterialManager::getSingleton().getByName(matName); + if (!mat.isNull()) + { + // manually clear TUS to ensure texture ref released + mat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); + MaterialManager::getSingleton().remove(mat->getHandle()); + } + + } + + ShadowTextureCameraList::iterator ci, ciend; + ciend = mShadowTextureCameras.end(); + for (ci = mShadowTextureCameras.begin(); ci != ciend; ++ci) + { + // Always destroy camera since they are local to this SM + destroyCamera(*ci); } mShadowTextures.clear(); - mShadowTextureCameras.clear(); + mShadowTextureCameras.clear(); - // Will destroy if no other scene managers referencing - ShadowTextureManager::getSingleton().clearUnused(); + // Will destroy if no other scene managers referencing + ShadowTextureManager::getSingleton().clearUnused(); - mShadowTextureConfigDirty = true; + mShadowTextureConfigDirty = true; } //--------------------------------------------------------------------- void SceneManager::prepareShadowTextures(Camera* cam, Viewport* vp, const LightList* lightList) { - // create shadow textures if needed - ensureShadowTexturesCreated(); + // create shadow textures if needed + ensureShadowTexturesCreated(); // Set the illumination stage, prevents recursive calls IlluminationRenderStage savedStage = mIlluminationStage; mIlluminationStage = IRS_RENDER_TO_TEXTURE; - if (lightList == 0) - lightList = &mLightsAffectingFrustum; - - try - { - - // Determine far shadow distance - Real shadowDist = mDefaultShadowFarDist; - if (!shadowDist) - { - // need a shadow distance, make one up - shadowDist = cam->getNearClipDistance() * 300; - } - Real shadowOffset = shadowDist * mShadowTextureOffset; - // Precalculate fading info - Real shadowEnd = shadowDist + shadowOffset; - Real fadeStart = shadowEnd * mShadowTextureFadeStart; - Real fadeEnd = shadowEnd * mShadowTextureFadeEnd; - // Additive lighting should not use fogging, since it will overbrighten; use border clamp - if (!isShadowTechniqueAdditive()) - { - // set fogging to hide the shadow edge - mShadowReceiverPass->setFog(true, FOG_LINEAR, ColourValue::White, - 0, fadeStart, fadeEnd); - } - else - { - // disable fogging explicitly - mShadowReceiverPass->setFog(true, FOG_NONE); - } - - // Iterate over the lights we've found, max out at the limit of light textures - // Note that the light sorting must now place shadow casting lights at the - // start of the light list, therefore we do not need to deal with potential - // mismatches in the light<->shadow texture list any more - - LightList::const_iterator i, iend; - ShadowTextureList::iterator si, siend; - ShadowTextureCameraList::iterator ci; - iend = lightList->end(); - siend = mShadowTextures.end(); - ci = mShadowTextureCameras.begin(); - mShadowTextureIndexLightList.clear(); - size_t shadowTextureIndex = 0; - for (i = lightList->begin(), si = mShadowTextures.begin(); - i != iend && si != siend; ++i) - { - Light* light = *i; - - // skip light if shadows are disabled - if (!light->getCastShadows()) - continue; - - if (mShadowTextureCurrentCasterLightList.empty()) - mShadowTextureCurrentCasterLightList.push_back(light); - else - mShadowTextureCurrentCasterLightList[0] = light; - - - // texture iteration per light. - size_t textureCountPerLight = mShadowTextureCountPerType[light->getType()]; - for (size_t j = 0; j < textureCountPerLight && si != siend; ++j) - { - TexturePtr &shadowTex = *si; - RenderTarget *shadowRTT = shadowTex->getBuffer()->getRenderTarget(); - Viewport *shadowView = shadowRTT->getViewport(0); - Camera *texCam = *ci; - // rebind camera, incase another SM in use which has switched to its cam - shadowView->setCamera(texCam); - - // Associate main view camera as LOD camera - texCam->setLodCamera(cam); - // set base - if (light->getType() != Light::LT_POINT) - texCam->setDirection(light->getDerivedDirection()); - if (light->getType() != Light::LT_DIRECTIONAL) - texCam->setPosition(light->getDerivedPosition()); - - // Use the material scheme of the main viewport - // This is required to pick up the correct shadow_caster_material and similar properties. - shadowView->setMaterialScheme(vp->getMaterialScheme()); - - // update shadow cam - light mapping - ShadowCamLightMapping::iterator camLightIt = mShadowCamLightMapping.find( texCam ); - assert(camLightIt != mShadowCamLightMapping.end()); - camLightIt->second = light; - - if (light->getCustomShadowCameraSetup().isNull()) - mDefaultShadowCameraSetup->getShadowCamera(this, cam, vp, light, texCam, j); - else - light->getCustomShadowCameraSetup()->getShadowCamera(this, cam, vp, light, texCam, j); - - // Setup background colour - shadowView->setBackgroundColour(ColourValue::White); - - // Fire shadow caster update, callee can alter camera settings - fireShadowTexturesPreCaster(light, texCam, j); - - // Update target - shadowRTT->update(); - - ++si; // next shadow texture - ++ci; // next camera - } - - // set the first shadow texture index for this light. - mShadowTextureIndexLightList.push_back(shadowTextureIndex); - shadowTextureIndex += textureCountPerLight; - } - } - catch (Exception&) - { - // we must reset the illumination stage if an exception occurs - mIlluminationStage = savedStage; - throw; - } + if (lightList == 0) + lightList = &mLightsAffectingFrustum; + + try + { + + // Determine far shadow distance + Real shadowDist = mDefaultShadowFarDist; + if (!shadowDist) + { + // need a shadow distance, make one up + shadowDist = cam->getNearClipDistance() * 300; + } + Real shadowOffset = shadowDist * mShadowTextureOffset; + // Precalculate fading info + Real shadowEnd = shadowDist + shadowOffset; + Real fadeStart = shadowEnd * mShadowTextureFadeStart; + Real fadeEnd = shadowEnd * mShadowTextureFadeEnd; + // Additive lighting should not use fogging, since it will overbrighten; use border clamp + if (!isShadowTechniqueAdditive()) + { + // set fogging to hide the shadow edge + mShadowReceiverPass->setFog(true, FOG_LINEAR, ColourValue::White, + 0, fadeStart, fadeEnd); + } + else + { + // disable fogging explicitly + mShadowReceiverPass->setFog(true, FOG_NONE); + } + + // Iterate over the lights we've found, max out at the limit of light textures + // Note that the light sorting must now place shadow casting lights at the + // start of the light list, therefore we do not need to deal with potential + // mismatches in the light<->shadow texture list any more + + LightList::const_iterator i, iend; + ShadowTextureList::iterator si, siend; + ShadowTextureCameraList::iterator ci; + iend = lightList->end(); + siend = mShadowTextures.end(); + ci = mShadowTextureCameras.begin(); + mShadowTextureIndexLightList.clear(); + size_t shadowTextureIndex = 0; + for (i = lightList->begin(), si = mShadowTextures.begin(); + i != iend && si != siend; ++i) + { + Light* light = *i; + + // skip light if shadows are disabled + if (!light->getCastShadows()) + continue; + + if (mShadowTextureCurrentCasterLightList.empty()) + mShadowTextureCurrentCasterLightList.push_back(light); + else + mShadowTextureCurrentCasterLightList[0] = light; + + + // texture iteration per light. + size_t textureCountPerLight = mShadowTextureCountPerType[light->getType()]; + for (size_t j = 0; j < textureCountPerLight && si != siend; ++j) + { + TexturePtr &shadowTex = *si; + RenderTarget *shadowRTT = shadowTex->getBuffer()->getRenderTarget(); + Viewport *shadowView = shadowRTT->getViewport(0); + Camera *texCam = *ci; + // rebind camera, incase another SM in use which has switched to its cam + shadowView->setCamera(texCam); + + // Associate main view camera as LOD camera + texCam->setLodCamera(cam); + // set base + if (light->getType() != Light::LT_POINT) + texCam->setDirection(light->getDerivedDirection()); + if (light->getType() != Light::LT_DIRECTIONAL) + texCam->setPosition(light->getDerivedPosition()); + + // Use the material scheme of the main viewport + // This is required to pick up the correct shadow_caster_material and similar properties. + shadowView->setMaterialScheme(vp->getMaterialScheme()); + + // update shadow cam - light mapping + ShadowCamLightMapping::iterator camLightIt = mShadowCamLightMapping.find( texCam ); + assert(camLightIt != mShadowCamLightMapping.end()); + camLightIt->second = light; + + if (light->getCustomShadowCameraSetup().isNull()) + mDefaultShadowCameraSetup->getShadowCamera(this, cam, vp, light, texCam, j); + else + light->getCustomShadowCameraSetup()->getShadowCamera(this, cam, vp, light, texCam, j); + + // Setup background colour + shadowView->setBackgroundColour(ColourValue::White); + + // Fire shadow caster update, callee can alter camera settings + fireShadowTexturesPreCaster(light, texCam, j); + + // Update target + shadowRTT->update(); + + ++si; // next shadow texture + ++ci; // next camera + } + + // set the first shadow texture index for this light. + mShadowTextureIndexLightList.push_back(shadowTextureIndex); + shadowTextureIndex += textureCountPerLight; + } + } + catch (Exception&) + { + // we must reset the illumination stage if an exception occurs + mIlluminationStage = savedStage; + throw; + } // Set the illumination stage, prevents recursive calls mIlluminationStage = savedStage; - fireShadowTexturesUpdated( - std::min(lightList->size(), mShadowTextures.size())); + fireShadowTexturesUpdated( + std::min(lightList->size(), mShadowTextures.size())); - ShadowTextureManager::getSingleton().clearUnused(); + ShadowTextureManager::getSingleton().clearUnused(); } //--------------------------------------------------------------------- SceneManager::RenderContext* SceneManager::_pauseRendering() { - RenderContext* context = new RenderContext; - context->renderQueue = mRenderQueue; - context->viewport = mCurrentViewport; - context->camera = mCameraInProgress; - context->activeChain = _getActiveCompositorChain(); + RenderContext* context = new RenderContext; + context->renderQueue = mRenderQueue; + context->viewport = mCurrentViewport; + context->camera = mCameraInProgress; + context->activeChain = _getActiveCompositorChain(); - context->rsContext = mDestRenderSystem->_pauseFrame(); - mRenderQueue = 0; - return context; + context->rsContext = mDestRenderSystem->_pauseFrame(); + mRenderQueue = 0; + return context; } //--------------------------------------------------------------------- void SceneManager::_resumeRendering(SceneManager::RenderContext* context) { delete mRenderQueue; - mRenderQueue = context->renderQueue; - _setActiveCompositorChain(context->activeChain); - Ogre::Viewport* vp = context->viewport; - Ogre::Camera* camera = context->camera; - - // Tell params about viewport - mAutoParamDataSource->setCurrentViewport(vp); - // Set the viewport - this is deliberately after the shadow texture update - setViewport(vp); - - // Tell params about camera - mAutoParamDataSource->setCurrentCamera(camera, mCameraRelativeRendering); - // Set autoparams for finite dir light extrusion - mAutoParamDataSource->setShadowDirLightExtrusionDistance(mShadowDirLightExtrudeDist); - - // Tell params about current ambient light - mAutoParamDataSource->setAmbientLightColour(mAmbientLight); - // Tell rendersystem - mDestRenderSystem->setAmbientLight(mAmbientLight.r, mAmbientLight.g, mAmbientLight.b); - - // Tell params about render target - mAutoParamDataSource->setCurrentRenderTarget(vp->getTarget()); - - - // Set camera window clipping planes (if any) - if (mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) - { - mDestRenderSystem->resetClipPlanes(); - if (camera->isWindowSet()) - { - mDestRenderSystem->setClipPlanes(camera->getWindowPlanes()); - } - } - mCameraInProgress = context->camera; - mDestRenderSystem->_resumeFrame(context->rsContext); - - // Set rasterisation mode + mRenderQueue = context->renderQueue; + _setActiveCompositorChain(context->activeChain); + Ogre::Viewport* vp = context->viewport; + Ogre::Camera* camera = context->camera; + + // Tell params about viewport + mAutoParamDataSource->setCurrentViewport(vp); + // Set the viewport - this is deliberately after the shadow texture update + setViewport(vp); + + // Tell params about camera + mAutoParamDataSource->setCurrentCamera(camera, mCameraRelativeRendering); + // Set autoparams for finite dir light extrusion + mAutoParamDataSource->setShadowDirLightExtrusionDistance(mShadowDirLightExtrudeDist); + + // Tell params about current ambient light + mAutoParamDataSource->setAmbientLightColour(mAmbientLight); + // Tell rendersystem + mDestRenderSystem->setAmbientLight(mAmbientLight.r, mAmbientLight.g, mAmbientLight.b); + + // Tell params about render target + mAutoParamDataSource->setCurrentRenderTarget(vp->getTarget()); + + + // Set camera window clipping planes (if any) + if (mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES)) + { + mDestRenderSystem->resetClipPlanes(); + if (camera->isWindowSet()) + { + mDestRenderSystem->setClipPlanes(camera->getWindowPlanes()); + } + } + mCameraInProgress = context->camera; + mDestRenderSystem->_resumeFrame(context->rsContext); + + // Set rasterisation mode mDestRenderSystem->_setPolygonMode(mCameraInProgress->getPolygonMode()); - // Set initial camera state - mDestRenderSystem->_setProjectionMatrix(mCameraInProgress->getProjectionMatrixRS()); - - mCachedViewMatrix = mCameraInProgress->getViewMatrix(true); + // Set initial camera state + mDestRenderSystem->_setProjectionMatrix(mCameraInProgress->getProjectionMatrixRS()); + + mCachedViewMatrix = mCameraInProgress->getViewMatrix(true); - if (mCameraRelativeRendering) - { - mCachedViewMatrix.setTrans(Vector3::ZERO); - mCameraRelativePosition = mCameraInProgress->getDerivedPosition(); - } - mDestRenderSystem->_setTextureProjectionRelativeTo(mCameraRelativeRendering, mCameraInProgress->getDerivedPosition()); + if (mCameraRelativeRendering) + { + mCachedViewMatrix.setTrans(Vector3::ZERO); + mCameraRelativePosition = mCameraInProgress->getDerivedPosition(); + } + mDestRenderSystem->_setTextureProjectionRelativeTo(mCameraRelativeRendering, mCameraInProgress->getDerivedPosition()); - - setViewMatrix(mCachedViewMatrix); - delete context; + + setViewMatrix(mCachedViewMatrix); + delete context; } //--------------------------------------------------------------------- StaticGeometry* SceneManager::createStaticGeometry(const String& name) { - // Check not existing - if (mStaticGeometryList.find(name) != mStaticGeometryList.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "StaticGeometry with name '" + name + "' already exists!", - "SceneManager::createStaticGeometry"); - } - StaticGeometry* ret = OGRE_NEW StaticGeometry(this, name); - mStaticGeometryList[name] = ret; - return ret; + // Check not existing + if (mStaticGeometryList.find(name) != mStaticGeometryList.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "StaticGeometry with name '" + name + "' already exists!", + "SceneManager::createStaticGeometry"); + } + StaticGeometry* ret = OGRE_NEW StaticGeometry(this, name); + mStaticGeometryList[name] = ret; + return ret; } //--------------------------------------------------------------------- StaticGeometry* SceneManager::getStaticGeometry(const String& name) const { - StaticGeometryList::const_iterator i = mStaticGeometryList.find(name); - if (i == mStaticGeometryList.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "StaticGeometry with name '" + name + "' not found", - "SceneManager::createStaticGeometry"); - } - return i->second; + StaticGeometryList::const_iterator i = mStaticGeometryList.find(name); + if (i == mStaticGeometryList.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "StaticGeometry with name '" + name + "' not found", + "SceneManager::createStaticGeometry"); + } + return i->second; } //----------------------------------------------------------------------- bool SceneManager::hasStaticGeometry(const String& name) const { - return (mStaticGeometryList.find(name) != mStaticGeometryList.end()); + return (mStaticGeometryList.find(name) != mStaticGeometryList.end()); } //--------------------------------------------------------------------- void SceneManager::destroyStaticGeometry(StaticGeometry* geom) { - destroyStaticGeometry(geom->getName()); + destroyStaticGeometry(geom->getName()); } //--------------------------------------------------------------------- void SceneManager::destroyStaticGeometry(const String& name) { - StaticGeometryList::iterator i = mStaticGeometryList.find(name); - if (i != mStaticGeometryList.end()) - { - OGRE_DELETE i->second; - mStaticGeometryList.erase(i); - } + StaticGeometryList::iterator i = mStaticGeometryList.find(name); + if (i != mStaticGeometryList.end()) + { + OGRE_DELETE i->second; + mStaticGeometryList.erase(i); + } } //--------------------------------------------------------------------- void SceneManager::destroyAllStaticGeometry(void) { - StaticGeometryList::iterator i, iend; - iend = mStaticGeometryList.end(); - for (i = mStaticGeometryList.begin(); i != iend; ++i) - { - OGRE_DELETE i->second; - } - mStaticGeometryList.clear(); + StaticGeometryList::iterator i, iend; + iend = mStaticGeometryList.end(); + for (i = mStaticGeometryList.begin(); i != iend; ++i) + { + OGRE_DELETE i->second; + } + mStaticGeometryList.clear(); } //--------------------------------------------------------------------- InstancedGeometry* SceneManager::createInstancedGeometry(const String& name) { - // Check not existing - if (mInstancedGeometryList.find(name) != mInstancedGeometryList.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "InstancedGeometry with name '" + name + "' already exists!", - "SceneManager::createInstancedGeometry"); - } - InstancedGeometry* ret = OGRE_NEW InstancedGeometry(this, name); - mInstancedGeometryList[name] = ret; - return ret; + // Check not existing + if (mInstancedGeometryList.find(name) != mInstancedGeometryList.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "InstancedGeometry with name '" + name + "' already exists!", + "SceneManager::createInstancedGeometry"); + } + InstancedGeometry* ret = OGRE_NEW InstancedGeometry(this, name); + mInstancedGeometryList[name] = ret; + return ret; } //--------------------------------------------------------------------- InstancedGeometry* SceneManager::getInstancedGeometry(const String& name) const { - InstancedGeometryList::const_iterator i = mInstancedGeometryList.find(name); - if (i == mInstancedGeometryList.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "InstancedGeometry with name '" + name + "' not found", - "SceneManager::createInstancedGeometry"); - } - return i->second; + InstancedGeometryList::const_iterator i = mInstancedGeometryList.find(name); + if (i == mInstancedGeometryList.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "InstancedGeometry with name '" + name + "' not found", + "SceneManager::createInstancedGeometry"); + } + return i->second; } //--------------------------------------------------------------------- void SceneManager::destroyInstancedGeometry(InstancedGeometry* geom) { - destroyInstancedGeometry(geom->getName()); + destroyInstancedGeometry(geom->getName()); } //--------------------------------------------------------------------- void SceneManager::destroyInstancedGeometry(const String& name) { - InstancedGeometryList::iterator i = mInstancedGeometryList.find(name); - if (i != mInstancedGeometryList.end()) - { - OGRE_DELETE i->second; - mInstancedGeometryList.erase(i); - } + InstancedGeometryList::iterator i = mInstancedGeometryList.find(name); + if (i != mInstancedGeometryList.end()) + { + OGRE_DELETE i->second; + mInstancedGeometryList.erase(i); + } } //--------------------------------------------------------------------- void SceneManager::destroyAllInstancedGeometry(void) { - InstancedGeometryList::iterator i, iend; - iend = mInstancedGeometryList.end(); - for (i = mInstancedGeometryList.begin(); i != iend; ++i) - { - OGRE_DELETE i->second; - } - mInstancedGeometryList.clear(); + InstancedGeometryList::iterator i, iend; + iend = mInstancedGeometryList.end(); + for (i = mInstancedGeometryList.begin(); i != iend; ++i) + { + OGRE_DELETE i->second; + } + mInstancedGeometryList.clear(); } //--------------------------------------------------------------------- InstanceManager* SceneManager::createInstanceManager( const String &customName, const String &meshName, - const String &groupName, - InstanceManager::InstancingTechnique technique, - size_t numInstancesPerBatch, uint16 flags, - unsigned short subMeshIdx ) + const String &groupName, + InstanceManager::InstancingTechnique technique, + size_t numInstancesPerBatch, uint16 flags, + unsigned short subMeshIdx ) { - if (mInstanceManagerMap.find(customName) != mInstanceManagerMap.end()) - { - OGRE_EXCEPT( Exception::ERR_DUPLICATE_ITEM, - "InstancedManager with name '" + customName + "' already exists!", - "SceneManager::createInstanceManager"); - } + if (mInstanceManagerMap.find(customName) != mInstanceManagerMap.end()) + { + OGRE_EXCEPT( Exception::ERR_DUPLICATE_ITEM, + "InstancedManager with name '" + customName + "' already exists!", + "SceneManager::createInstanceManager"); + } - InstanceManager *retVal = new InstanceManager( customName, this, meshName, groupName, technique, - flags, numInstancesPerBatch, subMeshIdx ); + InstanceManager *retVal = new InstanceManager( customName, this, meshName, groupName, technique, + flags, numInstancesPerBatch, subMeshIdx ); - mInstanceManagerMap[customName] = retVal; - return retVal; + mInstanceManagerMap[customName] = retVal; + return retVal; } //--------------------------------------------------------------------- InstanceManager* SceneManager::getInstanceManager( const String &managerName ) const { - InstanceManagerMap::const_iterator itor = mInstanceManagerMap.find(managerName); + InstanceManagerMap::const_iterator itor = mInstanceManagerMap.find(managerName); - if (itor == mInstanceManagerMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "InstancedManager with name '" + managerName + "' not found", - "SceneManager::getInstanceManager"); - } + if (itor == mInstanceManagerMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "InstancedManager with name '" + managerName + "' not found", + "SceneManager::getInstanceManager"); + } - return itor->second; + return itor->second; } //--------------------------------------------------------------------- bool SceneManager::hasInstanceManager( const String &managerName ) const @@ -6630,105 +6630,105 @@ bool SceneManager::hasInstanceManager( const String &managerName ) const //--------------------------------------------------------------------- void SceneManager::destroyInstanceManager( const String &name ) { - //The manager we're trying to destroy might have been scheduled for updating - //while we haven't yet rendered a frame. Update now to avoid a dangling ptr - updateDirtyInstanceManagers(); + //The manager we're trying to destroy might have been scheduled for updating + //while we haven't yet rendered a frame. Update now to avoid a dangling ptr + updateDirtyInstanceManagers(); - InstanceManagerMap::iterator i = mInstanceManagerMap.find(name); - if (i != mInstanceManagerMap.end()) - { - OGRE_DELETE i->second; - mInstanceManagerMap.erase(i); - } + InstanceManagerMap::iterator i = mInstanceManagerMap.find(name); + if (i != mInstanceManagerMap.end()) + { + OGRE_DELETE i->second; + mInstanceManagerMap.erase(i); + } } //--------------------------------------------------------------------- void SceneManager::destroyInstanceManager( InstanceManager *instanceManager ) { - destroyInstanceManager( instanceManager->getName() ); + destroyInstanceManager( instanceManager->getName() ); } //--------------------------------------------------------------------- void SceneManager::destroyAllInstanceManagers(void) { - InstanceManagerMap::iterator itor = mInstanceManagerMap.begin(); - InstanceManagerMap::iterator end = mInstanceManagerMap.end(); + InstanceManagerMap::iterator itor = mInstanceManagerMap.begin(); + InstanceManagerMap::iterator end = mInstanceManagerMap.end(); - while( itor != end ) - { - OGRE_DELETE itor->second; - ++itor; - } + while( itor != end ) + { + OGRE_DELETE itor->second; + ++itor; + } - mInstanceManagerMap.clear(); - mDirtyInstanceManagers.clear(); + mInstanceManagerMap.clear(); + mDirtyInstanceManagers.clear(); } //--------------------------------------------------------------------- size_t SceneManager::getNumInstancesPerBatch( const String &meshName, const String &groupName, - const String &materialName, - InstanceManager::InstancingTechnique technique, - size_t numInstancesPerBatch, uint16 flags, - unsigned short subMeshIdx ) + const String &materialName, + InstanceManager::InstancingTechnique technique, + size_t numInstancesPerBatch, uint16 flags, + unsigned short subMeshIdx ) { - InstanceManager tmpMgr( "TmpInstanceManager", this, meshName, groupName, - technique, flags, numInstancesPerBatch, subMeshIdx ); - - return tmpMgr.getMaxOrBestNumInstancesPerBatch( materialName, numInstancesPerBatch, flags ); + InstanceManager tmpMgr( "TmpInstanceManager", this, meshName, groupName, + technique, flags, numInstancesPerBatch, subMeshIdx ); + + return tmpMgr.getMaxOrBestNumInstancesPerBatch( materialName, numInstancesPerBatch, flags ); } //--------------------------------------------------------------------- InstancedEntity* SceneManager::createInstancedEntity( const String &materialName, const String &managerName ) { - InstanceManagerMap::const_iterator itor = mInstanceManagerMap.find(managerName); + InstanceManagerMap::const_iterator itor = mInstanceManagerMap.find(managerName); - if (itor == mInstanceManagerMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "InstancedManager with name '" + managerName + "' not found", - "SceneManager::createInstanceEntity"); - } + if (itor == mInstanceManagerMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "InstancedManager with name '" + managerName + "' not found", + "SceneManager::createInstanceEntity"); + } - return itor->second->createInstancedEntity( materialName ); + return itor->second->createInstancedEntity( materialName ); } //--------------------------------------------------------------------- void SceneManager::destroyInstancedEntity( InstancedEntity *instancedEntity ) { - instancedEntity->_getOwner()->removeInstancedEntity( instancedEntity ); + instancedEntity->_getOwner()->removeInstancedEntity( instancedEntity ); } //--------------------------------------------------------------------- void SceneManager::_addDirtyInstanceManager( InstanceManager *dirtyManager ) { - mDirtyInstanceManagers.push_back( dirtyManager ); + mDirtyInstanceManagers.push_back( dirtyManager ); } //--------------------------------------------------------------------- void SceneManager::updateDirtyInstanceManagers(void) { - //Copy all dirty mgrs to a temporary buffer to iterate through them. We need this because - //if two InstancedEntities from different managers belong to the same SceneNode, one of the - //managers may have been tagged as dirty while the other wasn't, and _addDirtyInstanceManager - //will get called while iterating through them. The "while" loop will update all mgrs until - //no one is dirty anymore (i.e. A makes B aware it's dirty, B makes C aware it's dirty) - //mDirtyInstanceMgrsTmp isn't a local variable to prevent allocs & deallocs every frame. - mDirtyInstanceMgrsTmp.insert( mDirtyInstanceMgrsTmp.end(), mDirtyInstanceManagers.begin(), - mDirtyInstanceManagers.end() ); - mDirtyInstanceManagers.clear(); - - while( !mDirtyInstanceMgrsTmp.empty() ) - { - InstanceManagerVec::const_iterator itor = mDirtyInstanceMgrsTmp.begin(); - InstanceManagerVec::const_iterator end = mDirtyInstanceMgrsTmp.end(); - - while( itor != end ) - { - (*itor)->_updateDirtyBatches(); - ++itor; - } - - //Clear temp buffer - mDirtyInstanceMgrsTmp.clear(); - - //Do it again? - mDirtyInstanceMgrsTmp.insert( mDirtyInstanceMgrsTmp.end(), mDirtyInstanceManagers.begin(), - mDirtyInstanceManagers.end() ); - mDirtyInstanceManagers.clear(); - } + //Copy all dirty mgrs to a temporary buffer to iterate through them. We need this because + //if two InstancedEntities from different managers belong to the same SceneNode, one of the + //managers may have been tagged as dirty while the other wasn't, and _addDirtyInstanceManager + //will get called while iterating through them. The "while" loop will update all mgrs until + //no one is dirty anymore (i.e. A makes B aware it's dirty, B makes C aware it's dirty) + //mDirtyInstanceMgrsTmp isn't a local variable to prevent allocs & deallocs every frame. + mDirtyInstanceMgrsTmp.insert( mDirtyInstanceMgrsTmp.end(), mDirtyInstanceManagers.begin(), + mDirtyInstanceManagers.end() ); + mDirtyInstanceManagers.clear(); + + while( !mDirtyInstanceMgrsTmp.empty() ) + { + InstanceManagerVec::const_iterator itor = mDirtyInstanceMgrsTmp.begin(); + InstanceManagerVec::const_iterator end = mDirtyInstanceMgrsTmp.end(); + + while( itor != end ) + { + (*itor)->_updateDirtyBatches(); + ++itor; + } + + //Clear temp buffer + mDirtyInstanceMgrsTmp.clear(); + + //Do it again? + mDirtyInstanceMgrsTmp.insert( mDirtyInstanceMgrsTmp.end(), mDirtyInstanceManagers.begin(), + mDirtyInstanceManagers.end() ); + mDirtyInstanceManagers.clear(); + } } //--------------------------------------------------------------------- AxisAlignedBoxSceneQuery* @@ -6786,216 +6786,216 @@ void SceneManager::destroyQuery(SceneQuery* query) SceneManager::MovableObjectCollection* SceneManager::getMovableObjectCollection(const String& typeName) { - // lock collection mutex + // lock collection mutex OGRE_LOCK_MUTEX(mMovableObjectCollectionMapMutex); - MovableObjectCollectionMap::iterator i = - mMovableObjectCollectionMap.find(typeName); - if (i == mMovableObjectCollectionMap.end()) - { - // create - MovableObjectCollection* newCollection = OGRE_NEW_T(MovableObjectCollection, MEMCATEGORY_SCENE_CONTROL)(); - mMovableObjectCollectionMap[typeName] = newCollection; - return newCollection; - } - else - { - return i->second; - } + MovableObjectCollectionMap::iterator i = + mMovableObjectCollectionMap.find(typeName); + if (i == mMovableObjectCollectionMap.end()) + { + // create + MovableObjectCollection* newCollection = OGRE_NEW_T(MovableObjectCollection, MEMCATEGORY_SCENE_CONTROL)(); + mMovableObjectCollectionMap[typeName] = newCollection; + return newCollection; + } + else + { + return i->second; + } } //--------------------------------------------------------------------- const SceneManager::MovableObjectCollection* SceneManager::getMovableObjectCollection(const String& typeName) const { - // lock collection mutex + // lock collection mutex OGRE_LOCK_MUTEX(mMovableObjectCollectionMapMutex); - MovableObjectCollectionMap::const_iterator i = - mMovableObjectCollectionMap.find(typeName); - if (i == mMovableObjectCollectionMap.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Object collection named '" + typeName + "' does not exist.", - "SceneManager::getMovableObjectCollection"); - } - else - { - return i->second; - } + MovableObjectCollectionMap::const_iterator i = + mMovableObjectCollectionMap.find(typeName); + if (i == mMovableObjectCollectionMap.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Object collection named '" + typeName + "' does not exist.", + "SceneManager::getMovableObjectCollection"); + } + else + { + return i->second; + } } //--------------------------------------------------------------------- MovableObject* SceneManager::createMovableObject(const String& name, - const String& typeName, const NameValuePairList* params) -{ - // Nasty hack to make generalised Camera functions work without breaking add-on SMs - if (typeName == "Camera") - { - return createCamera(name); - } - MovableObjectFactory* factory = - Root::getSingleton().getMovableObjectFactory(typeName); - // Check for duplicate names - MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); - - { + const String& typeName, const NameValuePairList* params) +{ + // Nasty hack to make generalised Camera functions work without breaking add-on SMs + if (typeName == "Camera") + { + return createCamera(name); + } + MovableObjectFactory* factory = + Root::getSingleton().getMovableObjectFactory(typeName); + // Check for duplicate names + MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); + + { OGRE_LOCK_MUTEX(objectMap->mutex); - if (objectMap->map.find(name) != objectMap->map.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "An object of type '" + typeName + "' with name '" + name - + "' already exists.", - "SceneManager::createMovableObject"); - } + if (objectMap->map.find(name) != objectMap->map.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "An object of type '" + typeName + "' with name '" + name + + "' already exists.", + "SceneManager::createMovableObject"); + } - MovableObject* newObj = factory->createInstance(name, this, params); - objectMap->map[name] = newObj; - return newObj; - } + MovableObject* newObj = factory->createInstance(name, this, params); + objectMap->map[name] = newObj; + return newObj; + } } //--------------------------------------------------------------------- MovableObject* SceneManager::createMovableObject(const String& typeName, const NameValuePairList* params /* = 0 */) { - String name = mMovableNameGenerator.generate(); - return createMovableObject(name, typeName, params); + String name = mMovableNameGenerator.generate(); + return createMovableObject(name, typeName, params); } //--------------------------------------------------------------------- void SceneManager::destroyMovableObject(const String& name, const String& typeName) { - // Nasty hack to make generalised Camera functions work without breaking add-on SMs - if (typeName == "Camera") - { - destroyCamera(name); - return; - } - MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); - MovableObjectFactory* factory = - Root::getSingleton().getMovableObjectFactory(typeName); - - { + // Nasty hack to make generalised Camera functions work without breaking add-on SMs + if (typeName == "Camera") + { + destroyCamera(name); + return; + } + MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); + MovableObjectFactory* factory = + Root::getSingleton().getMovableObjectFactory(typeName); + + { OGRE_LOCK_MUTEX(objectMap->mutex); - MovableObjectMap::iterator mi = objectMap->map.find(name); - if (mi != objectMap->map.end()) - { - factory->destroyInstance(mi->second); - objectMap->map.erase(mi); - } - } + MovableObjectMap::iterator mi = objectMap->map.find(name); + if (mi != objectMap->map.end()) + { + factory->destroyInstance(mi->second); + objectMap->map.erase(mi); + } + } } //--------------------------------------------------------------------- void SceneManager::destroyAllMovableObjectsByType(const String& typeName) { - // Nasty hack to make generalised Camera functions work without breaking add-on SMs - if (typeName == "Camera") - { - destroyAllCameras(); - return; - } - MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); - MovableObjectFactory* factory = - Root::getSingleton().getMovableObjectFactory(typeName); - - { + // Nasty hack to make generalised Camera functions work without breaking add-on SMs + if (typeName == "Camera") + { + destroyAllCameras(); + return; + } + MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); + MovableObjectFactory* factory = + Root::getSingleton().getMovableObjectFactory(typeName); + + { OGRE_LOCK_MUTEX(objectMap->mutex); - MovableObjectMap::iterator i = objectMap->map.begin(); - for (; i != objectMap->map.end(); ++i) - { - // Only destroy our own - if (i->second->_getManager() == this) - { - factory->destroyInstance(i->second); - } - } - objectMap->map.clear(); - } + MovableObjectMap::iterator i = objectMap->map.begin(); + for (; i != objectMap->map.end(); ++i) + { + // Only destroy our own + if (i->second->_getManager() == this) + { + factory->destroyInstance(i->second); + } + } + objectMap->map.clear(); + } } //--------------------------------------------------------------------- void SceneManager::destroyAllMovableObjects(void) { - // Lock collection mutex + // Lock collection mutex OGRE_LOCK_MUTEX(mMovableObjectCollectionMapMutex); - MovableObjectCollectionMap::iterator ci = mMovableObjectCollectionMap.begin(); + MovableObjectCollectionMap::iterator ci = mMovableObjectCollectionMap.begin(); - for(;ci != mMovableObjectCollectionMap.end(); ++ci) - { - MovableObjectCollection* coll = ci->second; + for(;ci != mMovableObjectCollectionMap.end(); ++ci) + { + MovableObjectCollection* coll = ci->second; - // lock map mutex - OGRE_LOCK_MUTEX(coll->mutex); + // lock map mutex + OGRE_LOCK_MUTEX(coll->mutex); - if (Root::getSingleton().hasMovableObjectFactory(ci->first)) - { - // Only destroy if we have a factory instance; otherwise must be injected - MovableObjectFactory* factory = - Root::getSingleton().getMovableObjectFactory(ci->first); - MovableObjectMap::iterator i = coll->map.begin(); - for (; i != coll->map.end(); ++i) - { - if (i->second->_getManager() == this) - { - factory->destroyInstance(i->second); - } - } - } - coll->map.clear(); - } + if (Root::getSingleton().hasMovableObjectFactory(ci->first)) + { + // Only destroy if we have a factory instance; otherwise must be injected + MovableObjectFactory* factory = + Root::getSingleton().getMovableObjectFactory(ci->first); + MovableObjectMap::iterator i = coll->map.begin(); + for (; i != coll->map.end(); ++i) + { + if (i->second->_getManager() == this) + { + factory->destroyInstance(i->second); + } + } + } + coll->map.clear(); + } } //--------------------------------------------------------------------- MovableObject* SceneManager::getMovableObject(const String& name, const String& typeName) const { - // Nasty hack to make generalised Camera functions work without breaking add-on SMs - if (typeName == "Camera") - { - return getCamera(name); - } + // Nasty hack to make generalised Camera functions work without breaking add-on SMs + if (typeName == "Camera") + { + return getCamera(name); + } - const MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); - - { + const MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); + + { OGRE_LOCK_MUTEX(objectMap->mutex); - MovableObjectMap::const_iterator mi = objectMap->map.find(name); - if (mi == objectMap->map.end()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Object named '" + name + "' does not exist.", - "SceneManager::getMovableObject"); - } - return mi->second; - } - + MovableObjectMap::const_iterator mi = objectMap->map.find(name); + if (mi == objectMap->map.end()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Object named '" + name + "' does not exist.", + "SceneManager::getMovableObject"); + } + return mi->second; + } + } //----------------------------------------------------------------------- bool SceneManager::hasMovableObject(const String& name, const String& typeName) const { - // Nasty hack to make generalised Camera functions work without breaking add-on SMs - if (typeName == "Camera") - { - return hasCamera(name); - } - OGRE_LOCK_MUTEX(mMovableObjectCollectionMapMutex); - - MovableObjectCollectionMap::const_iterator i = - mMovableObjectCollectionMap.find(typeName); - if (i == mMovableObjectCollectionMap.end()) - return false; - - { + // Nasty hack to make generalised Camera functions work without breaking add-on SMs + if (typeName == "Camera") + { + return hasCamera(name); + } + OGRE_LOCK_MUTEX(mMovableObjectCollectionMapMutex); + + MovableObjectCollectionMap::const_iterator i = + mMovableObjectCollectionMap.find(typeName); + if (i == mMovableObjectCollectionMap.end()) + return false; + + { OGRE_LOCK_MUTEX(i->second->mutex); - return (i->second->map.find(name) != i->second->map.end()); - } + return (i->second->map.find(name) != i->second->map.end()); + } } //--------------------------------------------------------------------- SceneManager::MovableObjectIterator SceneManager::getMovableObjectIterator(const String& typeName) { - MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); - // Iterator not thread safe! Warned in header. - return MovableObjectIterator(objectMap->map.begin(), objectMap->map.end()); + MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); + // Iterator not thread safe! Warned in header. + return MovableObjectIterator(objectMap->map.begin(), objectMap->map.end()); } //--------------------------------------------------------------------- void SceneManager::destroyMovableObject(MovableObject* m) @@ -7003,131 +7003,131 @@ void SceneManager::destroyMovableObject(MovableObject* m) if(!m) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot destroy a null MovableObject.", "SceneManager::destroyMovableObject"); - destroyMovableObject(m->getName(), m->getMovableType()); + destroyMovableObject(m->getName(), m->getMovableType()); } //--------------------------------------------------------------------- void SceneManager::injectMovableObject(MovableObject* m) { - MovableObjectCollection* objectMap = getMovableObjectCollection(m->getMovableType()); - { + MovableObjectCollection* objectMap = getMovableObjectCollection(m->getMovableType()); + { OGRE_LOCK_MUTEX(objectMap->mutex); - objectMap->map[m->getName()] = m; - } + objectMap->map[m->getName()] = m; + } } //--------------------------------------------------------------------- void SceneManager::extractMovableObject(const String& name, const String& typeName) { - MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); - { + MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); + { OGRE_LOCK_MUTEX(objectMap->mutex); - MovableObjectMap::iterator mi = objectMap->map.find(name); - if (mi != objectMap->map.end()) - { - // no delete - objectMap->map.erase(mi); - } - } + MovableObjectMap::iterator mi = objectMap->map.find(name); + if (mi != objectMap->map.end()) + { + // no delete + objectMap->map.erase(mi); + } + } } //--------------------------------------------------------------------- void SceneManager::extractMovableObject(MovableObject* m) { - extractMovableObject(m->getName(), m->getMovableType()); + extractMovableObject(m->getName(), m->getMovableType()); } //--------------------------------------------------------------------- void SceneManager::extractAllMovableObjectsByType(const String& typeName) { - MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); - { + MovableObjectCollection* objectMap = getMovableObjectCollection(typeName); + { OGRE_LOCK_MUTEX(objectMap->mutex); - // no deletion - objectMap->map.clear(); - } + // no deletion + objectMap->map.clear(); + } } //--------------------------------------------------------------------- void SceneManager::_injectRenderWithPass(Pass *pass, Renderable *rend, bool shadowDerivation, - bool doLightIteration, const LightList* manualLightList) + bool doLightIteration, const LightList* manualLightList) { - // render something as if it came from the current queue + // render something as if it came from the current queue const Pass *usedPass = _setPass(pass, false, shadowDerivation); renderSingleObject(rend, usedPass, false, doLightIteration, manualLightList); } //--------------------------------------------------------------------- RenderSystem *SceneManager::getDestinationRenderSystem() { - return mDestRenderSystem; + return mDestRenderSystem; } //--------------------------------------------------------------------- uint32 SceneManager::_getCombinedVisibilityMask(void) const { - return mCurrentViewport ? - mCurrentViewport->getVisibilityMask() & mVisibilityMask : mVisibilityMask; + return mCurrentViewport ? + mCurrentViewport->getVisibilityMask() & mVisibilityMask : mVisibilityMask; } //--------------------------------------------------------------------- const VisibleObjectsBoundsInfo& SceneManager::getVisibleObjectsBoundsInfo(const Camera* cam) const { - static VisibleObjectsBoundsInfo nullBox; + static VisibleObjectsBoundsInfo nullBox; - CamVisibleObjectsMap::const_iterator camVisObjIt = mCamVisibleObjectsMap.find( cam ); + CamVisibleObjectsMap::const_iterator camVisObjIt = mCamVisibleObjectsMap.find( cam ); - if ( camVisObjIt == mCamVisibleObjectsMap.end() ) - return nullBox; - else - return camVisObjIt->second; + if ( camVisObjIt == mCamVisibleObjectsMap.end() ) + return nullBox; + else + return camVisObjIt->second; } //--------------------------------------------------------------------- const VisibleObjectsBoundsInfo& SceneManager::getShadowCasterBoundsInfo( const Light* light, size_t iteration ) const { - static VisibleObjectsBoundsInfo nullBox; - - // find light - unsigned int foundCount = 0; - ShadowCamLightMapping::const_iterator it; - for ( it = mShadowCamLightMapping.begin() ; it != mShadowCamLightMapping.end(); ++it ) - { - if ( it->second == light ) - { - if (foundCount == iteration) - { - // search the camera-aab list for the texture cam - CamVisibleObjectsMap::const_iterator camIt = mCamVisibleObjectsMap.find( it->first ); - - if ( camIt == mCamVisibleObjectsMap.end() ) - { - return nullBox; - } - else - { - return camIt->second; - } - } - else - { - // multiple shadow textures per light, keep searching - ++foundCount; - } - } - } - - // AAB not available - return nullBox; + static VisibleObjectsBoundsInfo nullBox; + + // find light + unsigned int foundCount = 0; + ShadowCamLightMapping::const_iterator it; + for ( it = mShadowCamLightMapping.begin() ; it != mShadowCamLightMapping.end(); ++it ) + { + if ( it->second == light ) + { + if (foundCount == iteration) + { + // search the camera-aab list for the texture cam + CamVisibleObjectsMap::const_iterator camIt = mCamVisibleObjectsMap.find( it->first ); + + if ( camIt == mCamVisibleObjectsMap.end() ) + { + return nullBox; + } + else + { + return camIt->second; + } + } + else + { + // multiple shadow textures per light, keep searching + ++foundCount; + } + } + } + + // AAB not available + return nullBox; } //--------------------------------------------------------------------- void SceneManager::setQueuedRenderableVisitor(SceneManager::SceneMgrQueuedRenderableVisitor* visitor) { - if (visitor) - mActiveQueuedRenderableVisitor = visitor; - else - mActiveQueuedRenderableVisitor = &mDefaultQueuedRenderableVisitor; + if (visitor) + mActiveQueuedRenderableVisitor = visitor; + else + mActiveQueuedRenderableVisitor = &mDefaultQueuedRenderableVisitor; } //--------------------------------------------------------------------- SceneManager::SceneMgrQueuedRenderableVisitor* SceneManager::getQueuedRenderableVisitor(void) const { - return mActiveQueuedRenderableVisitor; + return mActiveQueuedRenderableVisitor; } //--------------------------------------------------------------------- void SceneManager::addLodListener(LodListener *listener) @@ -7210,146 +7210,146 @@ void SceneManager::_handleLodEvents() //--------------------------------------------------------------------- void SceneManager::setViewMatrix(const Matrix4& m) { - mDestRenderSystem->_setViewMatrix(m); - if (mDestRenderSystem->areFixedFunctionLightsInViewSpace()) - { - // reset light hash if we've got lights already set + mDestRenderSystem->_setViewMatrix(m); + if (mDestRenderSystem->areFixedFunctionLightsInViewSpace()) + { + // reset light hash if we've got lights already set if(mLastLightHash) mLastLightHash = 0; - } + } } //--------------------------------------------------------------------- void SceneManager::useLights(const LightList& lights, unsigned short limit) { - // only call the rendersystem if light list has changed - if (lights.getHash() != mLastLightHash || limit != mLastLightLimit) - { - mDestRenderSystem->_useLights(lights, limit); - mLastLightHash = lights.getHash(); - mLastLightLimit = limit; - } + // only call the rendersystem if light list has changed + if (lights.getHash() != mLastLightHash || limit != mLastLightLimit) + { + mDestRenderSystem->_useLights(lights, limit); + mLastLightHash = lights.getHash(); + mLastLightLimit = limit; + } } //--------------------------------------------------------------------- void SceneManager::useLightsGpuProgram(const Pass* pass, const LightList* lights) { - // only call the rendersystem if light list has changed - if (lights->getHash() != mLastLightHashGpuProgram) - { - // Update any automatic gpu params for lights - // Other bits of information will have to be looked up - mAutoParamDataSource->setCurrentLightList(lights); - mGpuParamsDirty |= GPV_LIGHTS; + // only call the rendersystem if light list has changed + if (lights->getHash() != mLastLightHashGpuProgram) + { + // Update any automatic gpu params for lights + // Other bits of information will have to be looked up + mAutoParamDataSource->setCurrentLightList(lights); + mGpuParamsDirty |= GPV_LIGHTS; - mLastLightHashGpuProgram = lights->getHash(); + mLastLightHashGpuProgram = lights->getHash(); - } + } } //--------------------------------------------------------------------- void SceneManager::bindGpuProgram(GpuProgram* prog) { - // need to dirty the light hash, and paarams that need resetting, since program params will have been invalidated - // Use 1 to guarantee changing it (using 0 could result in no change if list is empty) - // Hash == 1 is almost impossible to achieve otherwise - mLastLightHashGpuProgram = 1; - mGpuParamsDirty = (uint16)GPV_ALL; - mDestRenderSystem->bindGpuProgram(prog); + // need to dirty the light hash, and paarams that need resetting, since program params will have been invalidated + // Use 1 to guarantee changing it (using 0 could result in no change if list is empty) + // Hash == 1 is almost impossible to achieve otherwise + mLastLightHashGpuProgram = 1; + mGpuParamsDirty = (uint16)GPV_ALL; + mDestRenderSystem->bindGpuProgram(prog); } //--------------------------------------------------------------------- void SceneManager::_markGpuParamsDirty(uint16 mask) { - mGpuParamsDirty |= mask; + mGpuParamsDirty |= mask; } //--------------------------------------------------------------------- void SceneManager::updateGpuProgramParameters(const Pass* pass) { - if (pass->isProgrammable()) - { - - if (!mGpuParamsDirty) - return; - - if (mGpuParamsDirty) - pass->_updateAutoParams(mAutoParamDataSource, mGpuParamsDirty); - - if (pass->hasVertexProgram()) - { - mDestRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, - pass->getVertexProgramParameters(), mGpuParamsDirty); - } - - if (pass->hasGeometryProgram()) - { - mDestRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, - pass->getGeometryProgramParameters(), mGpuParamsDirty); - } - - if (pass->hasFragmentProgram()) - { - mDestRenderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, - pass->getFragmentProgramParameters(), mGpuParamsDirty); - } - - if (pass->hasTessellationHullProgram()) - { - mDestRenderSystem->bindGpuProgramParameters(GPT_HULL_PROGRAM, - pass->getTessellationHullProgramParameters(), mGpuParamsDirty); - } - - if (pass->hasTessellationDomainProgram()) - { - mDestRenderSystem->bindGpuProgramParameters(GPT_DOMAIN_PROGRAM, - pass->getTessellationDomainProgramParameters(), mGpuParamsDirty); - } + if (pass->isProgrammable()) + { + + if (!mGpuParamsDirty) + return; + + if (mGpuParamsDirty) + pass->_updateAutoParams(mAutoParamDataSource, mGpuParamsDirty); + + if (pass->hasVertexProgram()) + { + mDestRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, + pass->getVertexProgramParameters(), mGpuParamsDirty); + } + + if (pass->hasGeometryProgram()) + { + mDestRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, + pass->getGeometryProgramParameters(), mGpuParamsDirty); + } + + if (pass->hasFragmentProgram()) + { + mDestRenderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, + pass->getFragmentProgramParameters(), mGpuParamsDirty); + } + + if (pass->hasTessellationHullProgram()) + { + mDestRenderSystem->bindGpuProgramParameters(GPT_HULL_PROGRAM, + pass->getTessellationHullProgramParameters(), mGpuParamsDirty); + } + + if (pass->hasTessellationDomainProgram()) + { + mDestRenderSystem->bindGpuProgramParameters(GPT_DOMAIN_PROGRAM, + pass->getTessellationDomainProgramParameters(), mGpuParamsDirty); + } // if (pass->hasComputeProgram()) - // { + // { // mDestRenderSystem->bindGpuProgramParameters(GPT_COMPUTE_PROGRAM, // pass->getComputeProgramParameters(), mGpuParamsDirty); - // } + // } - mGpuParamsDirty = 0; - } + mGpuParamsDirty = 0; + } } //--------------------------------------------------------------------- //--------------------------------------------------------------------- VisibleObjectsBoundsInfo::VisibleObjectsBoundsInfo() { - reset(); + reset(); } //--------------------------------------------------------------------- void VisibleObjectsBoundsInfo::reset() { - aabb.setNull(); - receiverAabb.setNull(); - minDistance = minDistanceInFrustum = std::numeric_limits::infinity(); - maxDistance = maxDistanceInFrustum = 0; + aabb.setNull(); + receiverAabb.setNull(); + minDistance = minDistanceInFrustum = std::numeric_limits::infinity(); + maxDistance = maxDistanceInFrustum = 0; } //--------------------------------------------------------------------- void VisibleObjectsBoundsInfo::merge(const AxisAlignedBox& boxBounds, const Sphere& sphereBounds, - const Camera* cam, bool receiver) + const Camera* cam, bool receiver) { - aabb.merge(boxBounds); - if (receiver) - receiverAabb.merge(boxBounds); - // use view matrix to determine distance, works with custom view matrices - Vector3 vsSpherePos = cam->getViewMatrix(true) * sphereBounds.getCenter(); - Real camDistToCenter = vsSpherePos.length(); - minDistance = std::min(minDistance, std::max((Real)0, camDistToCenter - sphereBounds.getRadius())); - maxDistance = std::max(maxDistance, camDistToCenter + sphereBounds.getRadius()); - minDistanceInFrustum = std::min(minDistanceInFrustum, std::max((Real)0, camDistToCenter - sphereBounds.getRadius())); - maxDistanceInFrustum = std::max(maxDistanceInFrustum, camDistToCenter + sphereBounds.getRadius()); + aabb.merge(boxBounds); + if (receiver) + receiverAabb.merge(boxBounds); + // use view matrix to determine distance, works with custom view matrices + Vector3 vsSpherePos = cam->getViewMatrix(true) * sphereBounds.getCenter(); + Real camDistToCenter = vsSpherePos.length(); + minDistance = std::min(minDistance, std::max((Real)0, camDistToCenter - sphereBounds.getRadius())); + maxDistance = std::max(maxDistance, camDistToCenter + sphereBounds.getRadius()); + minDistanceInFrustum = std::min(minDistanceInFrustum, std::max((Real)0, camDistToCenter - sphereBounds.getRadius())); + maxDistanceInFrustum = std::max(maxDistanceInFrustum, camDistToCenter + sphereBounds.getRadius()); } //--------------------------------------------------------------------- void VisibleObjectsBoundsInfo::mergeNonRenderedButInFrustum(const AxisAlignedBox& boxBounds, - const Sphere& sphereBounds, const Camera* cam) -{ - (void)boxBounds; - // use view matrix to determine distance, works with custom view matrices - Vector3 vsSpherePos = cam->getViewMatrix(true) * sphereBounds.getCenter(); - Real camDistToCenter = vsSpherePos.length(); - minDistanceInFrustum = std::min(minDistanceInFrustum, std::max((Real)0, camDistToCenter - sphereBounds.getRadius())); - maxDistanceInFrustum = std::max(maxDistanceInFrustum, camDistToCenter + sphereBounds.getRadius()); + const Sphere& sphereBounds, const Camera* cam) +{ + (void)boxBounds; + // use view matrix to determine distance, works with custom view matrices + Vector3 vsSpherePos = cam->getViewMatrix(true) * sphereBounds.getCenter(); + Real camDistToCenter = vsSpherePos.length(); + minDistanceInFrustum = std::min(minDistanceInFrustum, std::max((Real)0, camDistToCenter - sphereBounds.getRadius())); + maxDistanceInFrustum = std::max(maxDistanceInFrustum, camDistToCenter + sphereBounds.getRadius()); } diff --git a/OgreMain/src/OgreSceneManagerEnumerator.cpp b/OgreMain/src/OgreSceneManagerEnumerator.cpp index 365d6e19a8c..7e176bf07bd 100644 --- a/OgreMain/src/OgreSceneManagerEnumerator.cpp +++ b/OgreMain/src/OgreSceneManagerEnumerator.cpp @@ -47,7 +47,7 @@ namespace Ogre { //----------------------------------------------------------------------- SceneManagerEnumerator::SceneManagerEnumerator() - : mInstanceCreateCount(0), mCurrentRenderSystem(0) + : mInstanceCreateCount(0), mCurrentRenderSystem(0) { addFactory(&mDefaultFactory); @@ -55,240 +55,240 @@ namespace Ogre { //----------------------------------------------------------------------- SceneManagerEnumerator::~SceneManagerEnumerator() { - // Destroy all remaining instances - // Really should have shutdown and unregistered by now, but catch here in case - Instances instancesCopy = mInstances; - for (Instances::iterator i = instancesCopy.begin(); i != instancesCopy.end(); ++i) - { - // destroy instances - for(Factories::iterator f = mFactories.begin(); f != mFactories.end(); ++f) - { - if ((*f)->getMetaData().typeName == i->second->getTypeName()) - { - (*f)->destroyInstance(i->second); - mInstances.erase(i->first); - break; - } - } - - } - mInstances.clear(); + // Destroy all remaining instances + // Really should have shutdown and unregistered by now, but catch here in case + Instances instancesCopy = mInstances; + for (Instances::iterator i = instancesCopy.begin(); i != instancesCopy.end(); ++i) + { + // destroy instances + for(Factories::iterator f = mFactories.begin(); f != mFactories.end(); ++f) + { + if ((*f)->getMetaData().typeName == i->second->getTypeName()) + { + (*f)->destroyInstance(i->second); + mInstances.erase(i->first); + break; + } + } + } + mInstances.clear(); + + } + //----------------------------------------------------------------------- + void SceneManagerEnumerator::addFactory(SceneManagerFactory* fact) + { + mFactories.push_back(fact); + // add to metadata + mMetaDataList.push_back(&fact->getMetaData()); + // Log + LogManager::getSingleton().logMessage("SceneManagerFactory for type '" + + fact->getMetaData().typeName + "' registered."); } - //----------------------------------------------------------------------- - void SceneManagerEnumerator::addFactory(SceneManagerFactory* fact) - { - mFactories.push_back(fact); - // add to metadata - mMetaDataList.push_back(&fact->getMetaData()); - // Log - LogManager::getSingleton().logMessage("SceneManagerFactory for type '" + - fact->getMetaData().typeName + "' registered."); - } - //----------------------------------------------------------------------- - void SceneManagerEnumerator::removeFactory(SceneManagerFactory* fact) - { + //----------------------------------------------------------------------- + void SceneManagerEnumerator::removeFactory(SceneManagerFactory* fact) + { if(!fact) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot remove a null SceneManagerFactory.", "SceneManagerEnumerator::removeFactory"); - // destroy all instances for this factory - for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ) - { - SceneManager* instance = i->second; - if (instance->getTypeName() == fact->getMetaData().typeName) - { - fact->destroyInstance(instance); - Instances::iterator deli = i++; - mInstances.erase(deli); - } - else - { - ++i; - } - } - // remove from metadata - for (MetaDataList::iterator m = mMetaDataList.begin(); m != mMetaDataList.end(); ++m) - { - if(*m == &(fact->getMetaData())) - { - mMetaDataList.erase(m); - break; - } - } - mFactories.remove(fact); - } - //----------------------------------------------------------------------- - const SceneManagerMetaData* SceneManagerEnumerator::getMetaData(const String& typeName) const - { - for (MetaDataList::const_iterator i = mMetaDataList.begin(); - i != mMetaDataList.end(); ++i) - { - if (typeName == (*i)->typeName) - { - return *i; - } - } - - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "No metadata found for scene manager of type '" + typeName + "'", - "SceneManagerEnumerator::createSceneManager"); - - } - //----------------------------------------------------------------------- - SceneManagerEnumerator::MetaDataIterator - SceneManagerEnumerator::getMetaDataIterator(void) const - { - return MetaDataIterator(mMetaDataList.begin(), mMetaDataList.end()); - - } - //----------------------------------------------------------------------- - SceneManager* SceneManagerEnumerator::createSceneManager( - const String& typeName, const String& instanceName) - { - if (mInstances.find(instanceName) != mInstances.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "SceneManager instance called '" + instanceName + "' already exists", - "SceneManagerEnumerator::createSceneManager"); - } - - SceneManager* inst = 0; - for(Factories::iterator i = mFactories.begin(); i != mFactories.end(); ++i) - { - if ((*i)->getMetaData().typeName == typeName) - { - if (instanceName.empty()) - { - // generate a name - StringStream s; - s << "SceneManagerInstance" << ++mInstanceCreateCount; - inst = (*i)->createInstance(s.str()); - } - else - { - inst = (*i)->createInstance(instanceName); - } - break; - } - } - - if (!inst) - { - // Error! - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "No factory found for scene manager of type '" + typeName + "'", - "SceneManagerEnumerator::createSceneManager"); - } - - /// assign rs if already configured - if (mCurrentRenderSystem) - inst->_setDestinationRenderSystem(mCurrentRenderSystem); - - mInstances[inst->getName()] = inst; - - return inst; - - - } - //----------------------------------------------------------------------- - SceneManager* SceneManagerEnumerator::createSceneManager( - SceneTypeMask typeMask, const String& instanceName) - { - if (mInstances.find(instanceName) != mInstances.end()) - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "SceneManager instance called '" + instanceName + "' already exists", - "SceneManagerEnumerator::createSceneManager"); - } - - SceneManager* inst = 0; - String name = instanceName; - if (name.empty()) - { - // generate a name - StringStream s; - s << "SceneManagerInstance" << ++mInstanceCreateCount; - name = s.str(); - } - - // Iterate backwards to find the matching factory registered last - for(Factories::reverse_iterator i = mFactories.rbegin(); i != mFactories.rend(); ++i) - { - if ((*i)->getMetaData().sceneTypeMask & typeMask) - { - inst = (*i)->createInstance(name); - break; - } - } - - // use default factory if none - if (!inst) - inst = mDefaultFactory.createInstance(name); - - /// assign rs if already configured - if (mCurrentRenderSystem) - inst->_setDestinationRenderSystem(mCurrentRenderSystem); - - mInstances[inst->getName()] = inst; - - return inst; - - } - //----------------------------------------------------------------------- - void SceneManagerEnumerator::destroySceneManager(SceneManager* sm) - { + // destroy all instances for this factory + for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ) + { + SceneManager* instance = i->second; + if (instance->getTypeName() == fact->getMetaData().typeName) + { + fact->destroyInstance(instance); + Instances::iterator deli = i++; + mInstances.erase(deli); + } + else + { + ++i; + } + } + // remove from metadata + for (MetaDataList::iterator m = mMetaDataList.begin(); m != mMetaDataList.end(); ++m) + { + if(*m == &(fact->getMetaData())) + { + mMetaDataList.erase(m); + break; + } + } + mFactories.remove(fact); + } + //----------------------------------------------------------------------- + const SceneManagerMetaData* SceneManagerEnumerator::getMetaData(const String& typeName) const + { + for (MetaDataList::const_iterator i = mMetaDataList.begin(); + i != mMetaDataList.end(); ++i) + { + if (typeName == (*i)->typeName) + { + return *i; + } + } + + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "No metadata found for scene manager of type '" + typeName + "'", + "SceneManagerEnumerator::createSceneManager"); + + } + //----------------------------------------------------------------------- + SceneManagerEnumerator::MetaDataIterator + SceneManagerEnumerator::getMetaDataIterator(void) const + { + return MetaDataIterator(mMetaDataList.begin(), mMetaDataList.end()); + + } + //----------------------------------------------------------------------- + SceneManager* SceneManagerEnumerator::createSceneManager( + const String& typeName, const String& instanceName) + { + if (mInstances.find(instanceName) != mInstances.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "SceneManager instance called '" + instanceName + "' already exists", + "SceneManagerEnumerator::createSceneManager"); + } + + SceneManager* inst = 0; + for(Factories::iterator i = mFactories.begin(); i != mFactories.end(); ++i) + { + if ((*i)->getMetaData().typeName == typeName) + { + if (instanceName.empty()) + { + // generate a name + StringStream s; + s << "SceneManagerInstance" << ++mInstanceCreateCount; + inst = (*i)->createInstance(s.str()); + } + else + { + inst = (*i)->createInstance(instanceName); + } + break; + } + } + + if (!inst) + { + // Error! + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "No factory found for scene manager of type '" + typeName + "'", + "SceneManagerEnumerator::createSceneManager"); + } + + /// assign rs if already configured + if (mCurrentRenderSystem) + inst->_setDestinationRenderSystem(mCurrentRenderSystem); + + mInstances[inst->getName()] = inst; + + return inst; + + + } + //----------------------------------------------------------------------- + SceneManager* SceneManagerEnumerator::createSceneManager( + SceneTypeMask typeMask, const String& instanceName) + { + if (mInstances.find(instanceName) != mInstances.end()) + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "SceneManager instance called '" + instanceName + "' already exists", + "SceneManagerEnumerator::createSceneManager"); + } + + SceneManager* inst = 0; + String name = instanceName; + if (name.empty()) + { + // generate a name + StringStream s; + s << "SceneManagerInstance" << ++mInstanceCreateCount; + name = s.str(); + } + + // Iterate backwards to find the matching factory registered last + for(Factories::reverse_iterator i = mFactories.rbegin(); i != mFactories.rend(); ++i) + { + if ((*i)->getMetaData().sceneTypeMask & typeMask) + { + inst = (*i)->createInstance(name); + break; + } + } + + // use default factory if none + if (!inst) + inst = mDefaultFactory.createInstance(name); + + /// assign rs if already configured + if (mCurrentRenderSystem) + inst->_setDestinationRenderSystem(mCurrentRenderSystem); + + mInstances[inst->getName()] = inst; + + return inst; + + } + //----------------------------------------------------------------------- + void SceneManagerEnumerator::destroySceneManager(SceneManager* sm) + { if(!sm) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot destroy a null SceneManager.", "SceneManagerEnumerator::destroySceneManager"); - // Erase instance from map - mInstances.erase(sm->getName()); - - // Find factory to destroy - for(Factories::iterator i = mFactories.begin(); i != mFactories.end(); ++i) - { - if ((*i)->getMetaData().typeName == sm->getTypeName()) - { - (*i)->destroyInstance(sm); - break; - } - } - - } - //----------------------------------------------------------------------- - SceneManager* SceneManagerEnumerator::getSceneManager(const String& instanceName) const - { - Instances::const_iterator i = mInstances.find(instanceName); - if(i != mInstances.end()) - { - return i->second; - } - else - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "SceneManager instance with name '" + instanceName + "' not found.", - "SceneManagerEnumerator::getSceneManager"); - } - - } - //--------------------------------------------------------------------- - bool SceneManagerEnumerator::hasSceneManager(const String& instanceName) const - { - return mInstances.find(instanceName) != mInstances.end(); - } - //----------------------------------------------------------------------- - SceneManagerEnumerator::SceneManagerIterator - SceneManagerEnumerator::getSceneManagerIterator(void) - { - return SceneManagerIterator(mInstances.begin(), mInstances.end()); - - } - //----------------------------------------------------------------------- + // Erase instance from map + mInstances.erase(sm->getName()); + + // Find factory to destroy + for(Factories::iterator i = mFactories.begin(); i != mFactories.end(); ++i) + { + if ((*i)->getMetaData().typeName == sm->getTypeName()) + { + (*i)->destroyInstance(sm); + break; + } + } + + } + //----------------------------------------------------------------------- + SceneManager* SceneManagerEnumerator::getSceneManager(const String& instanceName) const + { + Instances::const_iterator i = mInstances.find(instanceName); + if(i != mInstances.end()) + { + return i->second; + } + else + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "SceneManager instance with name '" + instanceName + "' not found.", + "SceneManagerEnumerator::getSceneManager"); + } + + } + //--------------------------------------------------------------------- + bool SceneManagerEnumerator::hasSceneManager(const String& instanceName) const + { + return mInstances.find(instanceName) != mInstances.end(); + } + //----------------------------------------------------------------------- + SceneManagerEnumerator::SceneManagerIterator + SceneManagerEnumerator::getSceneManagerIterator(void) + { + return SceneManagerIterator(mInstances.begin(), mInstances.end()); + + } + //----------------------------------------------------------------------- void SceneManagerEnumerator::setRenderSystem(RenderSystem* rs) { - mCurrentRenderSystem = rs; + mCurrentRenderSystem = rs; - for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ++i) - { + for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ++i) + { i->second->_setDestinationRenderSystem(rs); } @@ -296,49 +296,49 @@ namespace Ogre { //----------------------------------------------------------------------- void SceneManagerEnumerator::shutdownAll(void) { - for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ++i) - { - // shutdown instances (clear scene) - i->second->clearScene(); + for (Instances::iterator i = mInstances.begin(); i != mInstances.end(); ++i) + { + // shutdown instances (clear scene) + i->second->clearScene(); } } //----------------------------------------------------------------------- - const String DefaultSceneManagerFactory::FACTORY_TYPE_NAME = "DefaultSceneManager"; + const String DefaultSceneManagerFactory::FACTORY_TYPE_NAME = "DefaultSceneManager"; //----------------------------------------------------------------------- - void DefaultSceneManagerFactory::initMetaData(void) const - { - mMetaData.typeName = FACTORY_TYPE_NAME; - mMetaData.description = "The default scene manager"; - mMetaData.sceneTypeMask = ST_GENERIC; - mMetaData.worldGeometrySupported = false; - } + void DefaultSceneManagerFactory::initMetaData(void) const + { + mMetaData.typeName = FACTORY_TYPE_NAME; + mMetaData.description = "The default scene manager"; + mMetaData.sceneTypeMask = ST_GENERIC; + mMetaData.worldGeometrySupported = false; + } //----------------------------------------------------------------------- - SceneManager* DefaultSceneManagerFactory::createInstance( - const String& instanceName) - { - return OGRE_NEW DefaultSceneManager(instanceName); - } + SceneManager* DefaultSceneManagerFactory::createInstance( + const String& instanceName) + { + return OGRE_NEW DefaultSceneManager(instanceName); + } //----------------------------------------------------------------------- - void DefaultSceneManagerFactory::destroyInstance(SceneManager* instance) - { - OGRE_DELETE instance; - } + void DefaultSceneManagerFactory::destroyInstance(SceneManager* instance) + { + OGRE_DELETE instance; + } //----------------------------------------------------------------------- //----------------------------------------------------------------------- - DefaultSceneManager::DefaultSceneManager(const String& name) - : SceneManager(name) - { - } + DefaultSceneManager::DefaultSceneManager(const String& name) + : SceneManager(name) + { + } //----------------------------------------------------------------------- - DefaultSceneManager::~DefaultSceneManager() - { - } + DefaultSceneManager::~DefaultSceneManager() + { + } //----------------------------------------------------------------------- - const String& DefaultSceneManager::getTypeName(void) const - { - return DefaultSceneManagerFactory::FACTORY_TYPE_NAME; - } + const String& DefaultSceneManager::getTypeName(void) const + { + return DefaultSceneManagerFactory::FACTORY_TYPE_NAME; + } //----------------------------------------------------------------------- diff --git a/OgreMain/src/OgreSceneNode.cpp b/OgreMain/src/OgreSceneNode.cpp index bd297e7f030..c4b63589b9f 100644 --- a/OgreMain/src/OgreSceneNode.cpp +++ b/OgreMain/src/OgreSceneNode.cpp @@ -67,12 +67,12 @@ namespace Ogre { { // Detach all objects, do this manually to avoid needUpdate() call // which can fail because of deleted items - ObjectMap::iterator itr; - for ( itr = mObjectsByName.begin(); itr != mObjectsByName.end(); ++itr ) - { + ObjectMap::iterator itr; + for ( itr = mObjectsByName.begin(); itr != mObjectsByName.end(); ++itr ) + { MovableObject* ret = itr->second; ret->_notifyAttached((SceneNode*)0); - } + } mObjectsByName.clear(); OGRE_DELETE mWireBoundingBox; @@ -84,35 +84,35 @@ namespace Ogre { _updateBounds(); } //----------------------------------------------------------------------- - void SceneNode::setParent(Node* parent) - { - Node::setParent(parent); - - if (parent) - { - SceneNode* sceneParent = static_cast(parent); - setInSceneGraph(sceneParent->isInSceneGraph()); - } - else - { - setInSceneGraph(false); - } - } - //----------------------------------------------------------------------- - void SceneNode::setInSceneGraph(bool inGraph) - { - if (inGraph != mIsInSceneGraph) - { - mIsInSceneGraph = inGraph; - // Tell children - ChildNodeMap::iterator child; - for (child = mChildren.begin(); child != mChildren.end(); ++child) - { - SceneNode* sceneChild = static_cast(child->second); - sceneChild->setInSceneGraph(inGraph); - } - } - } + void SceneNode::setParent(Node* parent) + { + Node::setParent(parent); + + if (parent) + { + SceneNode* sceneParent = static_cast(parent); + setInSceneGraph(sceneParent->isInSceneGraph()); + } + else + { + setInSceneGraph(false); + } + } + //----------------------------------------------------------------------- + void SceneNode::setInSceneGraph(bool inGraph) + { + if (inGraph != mIsInSceneGraph) + { + mIsInSceneGraph = inGraph; + // Tell children + ChildNodeMap::iterator child; + for (child = mChildren.begin(); child != mChildren.end(); ++child) + { + SceneNode* sceneChild = static_cast(child->second); + sceneChild->setInSceneGraph(inGraph); + } + } + } //----------------------------------------------------------------------- void SceneNode::attachObject(MovableObject* obj) { @@ -236,12 +236,12 @@ namespace Ogre { //----------------------------------------------------------------------- void SceneNode::detachAllObjects(void) { - ObjectMap::iterator itr; - for ( itr = mObjectsByName.begin(); itr != mObjectsByName.end(); ++itr ) - { + ObjectMap::iterator itr; + for ( itr = mObjectsByName.begin(); itr != mObjectsByName.end(); ++itr ) + { MovableObject* ret = itr->second; ret->_notifyAttached((SceneNode*)0); - } + } mObjectsByName.clear(); // Make sure bounds get updated (must go right to the top) needUpdate(); @@ -271,8 +271,8 @@ namespace Ogre { } //----------------------------------------------------------------------- void SceneNode::_findVisibleObjects(Camera* cam, RenderQueue* queue, - VisibleObjectsBoundsInfo* visibleBounds, bool includeChildren, - bool displayNodes, bool onlyShadowCasters) + VisibleObjectsBoundsInfo* visibleBounds, bool includeChildren, + bool displayNodes, bool onlyShadowCasters) { // Check self visible if (!cam->isVisible(mWorldAABB)) @@ -283,9 +283,9 @@ namespace Ogre { ObjectMap::iterator iobjend = mObjectsByName.end(); for (iobj = mObjectsByName.begin(); iobj != iobjend; ++iobj) { - MovableObject* mo = iobj->second; + MovableObject* mo = iobj->second; - queue->processVisibleObject(mo, cam, onlyShadowCasters, visibleBounds); + queue->processVisibleObject(mo, cam, onlyShadowCasters, visibleBounds); } if (includeChildren) @@ -296,7 +296,7 @@ namespace Ogre { { SceneNode* sceneChild = static_cast(child->second); sceneChild->_findVisibleObjects(cam, queue, visibleBounds, includeChildren, - displayNodes, onlyShadowCasters); + displayNodes, onlyShadowCasters); } } @@ -306,47 +306,47 @@ namespace Ogre { queue->addRenderable(getDebugRenderable()); } - // Check if the bounding box should be shown. - // See if our flag is set or if the scene manager flag is set. - if ( !mHideBoundingBox && + // Check if the bounding box should be shown. + // See if our flag is set or if the scene manager flag is set. + if ( !mHideBoundingBox && (mShowBoundingBox || (mCreator && mCreator->getShowBoundingBoxes())) ) - { - _addBoundingBoxToQueue(queue); - } + { + _addBoundingBoxToQueue(queue); + } } - Node::DebugRenderable* SceneNode::getDebugRenderable() - { - Vector3 hs = mWorldAABB.getHalfSize(); - Real sz = std::min(hs.x, hs.y); - sz = std::min(sz, hs.z); - sz = std::max(sz, (Real)1.0); - return Node::getDebugRenderable(sz); - } + Node::DebugRenderable* SceneNode::getDebugRenderable() + { + Vector3 hs = mWorldAABB.getHalfSize(); + Real sz = std::min(hs.x, hs.y); + sz = std::min(sz, hs.z); + sz = std::max(sz, (Real)1.0); + return Node::getDebugRenderable(sz); + } - void SceneNode::_addBoundingBoxToQueue(RenderQueue* queue) { - // Create a WireBoundingBox if needed. - if (mWireBoundingBox == NULL) { - mWireBoundingBox = OGRE_NEW WireBoundingBox(); - } - mWireBoundingBox->setupBoundingBox(mWorldAABB); - queue->addRenderable(mWireBoundingBox); - } + void SceneNode::_addBoundingBoxToQueue(RenderQueue* queue) { + // Create a WireBoundingBox if needed. + if (mWireBoundingBox == NULL) { + mWireBoundingBox = OGRE_NEW WireBoundingBox(); + } + mWireBoundingBox->setupBoundingBox(mWorldAABB); + queue->addRenderable(mWireBoundingBox); + } - void SceneNode::showBoundingBox(bool bShow) { - mShowBoundingBox = bShow; - } + void SceneNode::showBoundingBox(bool bShow) { + mShowBoundingBox = bShow; + } - bool SceneNode::getShowBoundingBox() const { - return mShowBoundingBox; - } + bool SceneNode::getShowBoundingBox() const { + return mShowBoundingBox; + } - void SceneNode::hideBoundingBox(bool bHide) { - mHideBoundingBox = bHide; - } + void SceneNode::hideBoundingBox(bool bHide) { + mHideBoundingBox = bHide; + } //----------------------------------------------------------------------- void SceneNode::updateFromParentImpl(void) const @@ -383,11 +383,11 @@ namespace Ogre { { return ObjectIterator(mObjectsByName.begin(), mObjectsByName.end()); } - //----------------------------------------------------------------------- - SceneNode::ConstObjectIterator SceneNode::getAttachedObjectIterator(void) const - { - return ConstObjectIterator(mObjectsByName.begin(), mObjectsByName.end()); - } + //----------------------------------------------------------------------- + SceneNode::ConstObjectIterator SceneNode::getAttachedObjectIterator(void) const + { + return ConstObjectIterator(mObjectsByName.begin(), mObjectsByName.end()); + } //----------------------------------------------------------------------- void SceneNode::removeAndDestroyChild(const String& name) { @@ -415,27 +415,27 @@ namespace Ogre { for (i = mChildren.begin(); i != iend;) { SceneNode* sn = static_cast(i->second); - // increment iterator before destroying (iterator invalidated by - // SceneManager::destroySceneNode because it causes removal from parent) - ++i; + // increment iterator before destroying (iterator invalidated by + // SceneManager::destroySceneNode because it causes removal from parent) + ++i; sn->removeAndDestroyAllChildren(); sn->getCreator()->destroySceneNode(sn->getName()); } - mChildren.clear(); + mChildren.clear(); needUpdate(); } //----------------------------------------------------------------------- - SceneNode* SceneNode::createChildSceneNode(const Vector3& inTranslate, + SceneNode* SceneNode::createChildSceneNode(const Vector3& inTranslate, const Quaternion& inRotate) - { - return static_cast(this->createChild(inTranslate, inRotate)); - } + { + return static_cast(this->createChild(inTranslate, inRotate)); + } //----------------------------------------------------------------------- SceneNode* SceneNode::createChildSceneNode(const String& name, const Vector3& inTranslate, - const Quaternion& inRotate) - { - return static_cast(this->createChild(name, inTranslate, inRotate)); - } + const Quaternion& inRotate) + { + return static_cast(this->createChild(name, inTranslate, inRotate)); + } //----------------------------------------------------------------------- void SceneNode::findLights(LightList& destList, Real radius, uint32 lightMask) const { @@ -481,19 +481,19 @@ namespace Ogre { mYawFixedAxis = fixedAxis; } - //----------------------------------------------------------------------- - void SceneNode::yaw(const Radian& angle, TransformSpace relativeTo) - { - if (mYawFixed) - { - rotate(mYawFixedAxis, angle, relativeTo); - } - else - { - rotate(Vector3::UNIT_Y, angle, relativeTo); - } + //----------------------------------------------------------------------- + void SceneNode::yaw(const Radian& angle, TransformSpace relativeTo) + { + if (mYawFixed) + { + rotate(mYawFixedAxis, angle, relativeTo); + } + else + { + rotate(Vector3::UNIT_Y, angle, relativeTo); + } - } + } //----------------------------------------------------------------------- void SceneNode::setDirection(Real x, Real y, Real z, TransformSpace relativeTo, const Vector3& localDirectionVector) @@ -642,26 +642,26 @@ namespace Ogre { } } } - //----------------------------------------------------------------------- - void SceneNode::setDebugDisplayEnabled(bool enabled, bool cascade) - { - ObjectMap::iterator oi, oiend; - oiend = mObjectsByName.end(); - for (oi = mObjectsByName.begin(); oi != oiend; ++oi) - { - oi->second->setDebugDisplayEnabled(enabled); - } - - if (cascade) - { - ChildNodeMap::iterator i, iend; - iend = mChildren.end(); - for (i = mChildren.begin(); i != iend; ++i) - { - static_cast(i->second)->setDebugDisplayEnabled(enabled, cascade); - } - } - } + //----------------------------------------------------------------------- + void SceneNode::setDebugDisplayEnabled(bool enabled, bool cascade) + { + ObjectMap::iterator oi, oiend; + oiend = mObjectsByName.end(); + for (oi = mObjectsByName.begin(); oi != oiend; ++oi) + { + oi->second->setDebugDisplayEnabled(enabled); + } + + if (cascade) + { + ChildNodeMap::iterator i, iend; + iend = mChildren.end(); + for (i = mChildren.begin(); i != iend; ++i) + { + static_cast(i->second)->setDebugDisplayEnabled(enabled, cascade); + } + } + } //----------------------------------------------------------------------- void SceneNode::flipVisibility(bool cascade) { diff --git a/OgreMain/src/OgreSceneQuery.cpp b/OgreMain/src/OgreSceneQuery.cpp index 5b7b7b40cdf..830112eedcc 100644 --- a/OgreMain/src/OgreSceneQuery.cpp +++ b/OgreMain/src/OgreSceneQuery.cpp @@ -35,11 +35,11 @@ namespace Ogre { //----------------------------------------------------------------------- SceneQuery::SceneQuery(SceneManager* mgr) : mParentSceneMgr(mgr), mQueryMask(0xFFFFFFFF), - mWorldFragmentType(SceneQuery::WFT_NONE) + mWorldFragmentType(SceneQuery::WFT_NONE) { - // default type mask to everything except lights & fx (previous behaviour) - mQueryTypeMask = (0xFFFFFFFF & ~SceneManager::FX_TYPE_MASK) - & ~SceneManager::LIGHT_TYPE_MASK; + // default type mask to everything except lights & fx (previous behaviour) + mQueryTypeMask = (0xFFFFFFFF & ~SceneManager::FX_TYPE_MASK) + & ~SceneManager::LIGHT_TYPE_MASK; } //----------------------------------------------------------------------- @@ -56,16 +56,16 @@ namespace Ogre { { return mQueryMask; } - //----------------------------------------------------------------------- - void SceneQuery::setQueryTypeMask(uint32 mask) - { - mQueryTypeMask = mask; - } - //----------------------------------------------------------------------- - uint32 SceneQuery::getQueryTypeMask(void) const - { - return mQueryTypeMask; - } + //----------------------------------------------------------------------- + void SceneQuery::setQueryTypeMask(uint32 mask) + { + mQueryTypeMask = mask; + } + //----------------------------------------------------------------------- + uint32 SceneQuery::getQueryTypeMask(void) const + { + return mQueryTypeMask; + } //----------------------------------------------------------------------- void SceneQuery::setWorldFragmentType(enum SceneQuery::WorldFragmentType wft) { @@ -105,7 +105,7 @@ namespace Ogre { OGRE_DELETE mLastResult; mLastResult = NULL; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- SceneQueryResult& RegionSceneQuery::execute(void) { @@ -115,7 +115,7 @@ namespace Ogre { execute(this); return *mLastResult; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- bool RegionSceneQuery:: queryResult(MovableObject* obj) { @@ -124,7 +124,7 @@ namespace Ogre { // Continue return true; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- bool RegionSceneQuery::queryResult(SceneQuery::WorldFragment* fragment) { // Add to internal list @@ -320,7 +320,7 @@ namespace Ogre { OGRE_DELETE mLastResult; mLastResult = NULL; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- IntersectionSceneQueryResult& IntersectionSceneQuery::execute(void) { @@ -330,7 +330,7 @@ namespace Ogre { execute(this); return *mLastResult; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- bool IntersectionSceneQuery:: queryResult(MovableObject* first, MovableObject* second) { @@ -341,7 +341,7 @@ namespace Ogre { // Continue return true; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- bool IntersectionSceneQuery:: queryResult(MovableObject* movable, SceneQuery::WorldFragment* fragment) { diff --git a/OgreMain/src/OgreScriptCompiler.cpp b/OgreMain/src/OgreScriptCompiler.cpp index f385b48560a..833bf542131 100644 --- a/OgreMain/src/OgreScriptCompiler.cpp +++ b/OgreMain/src/OgreScriptCompiler.cpp @@ -35,1013 +35,1013 @@ THE SOFTWARE. namespace Ogre { - // AbstractNode - AbstractNode::AbstractNode(AbstractNode *ptr) - :line(0), type(ANT_UNKNOWN), parent(ptr) - {} - - // AtomAbstractNode - AtomAbstractNode::AtomAbstractNode(AbstractNode *ptr) - :AbstractNode(ptr), id(0) - { - type = ANT_ATOM; - } - - AbstractNode *AtomAbstractNode::clone() const - { - AtomAbstractNode *node = OGRE_NEW AtomAbstractNode(parent); - node->file = file; - node->line = line; - node->id = id; - node->type = type; - node->value = value; - return node; - } - - String AtomAbstractNode::getValue() const - { - return value; - } - - // ObjectAbstractNode - ObjectAbstractNode::ObjectAbstractNode(AbstractNode *ptr) - :AbstractNode(ptr), id(0), abstract(false) - { - type = ANT_OBJECT; - } - - AbstractNode *ObjectAbstractNode::clone() const - { - ObjectAbstractNode *node = OGRE_NEW ObjectAbstractNode(parent); - node->file = file; - node->line = line; - node->type = type; - node->name = name; - node->cls = cls; - node->id = id; - node->abstract = abstract; - for(AbstractNodeList::const_iterator i = children.begin(); i != children.end(); ++i) - { - AbstractNodePtr newNode = AbstractNodePtr((*i)->clone()); - newNode->parent = node; - node->children.push_back(newNode); - } - for(AbstractNodeList::const_iterator i = values.begin(); i != values.end(); ++i) - { - AbstractNodePtr newNode = AbstractNodePtr((*i)->clone()); - newNode->parent = node; - node->values.push_back(newNode); - } - node->mEnv = mEnv; - return node; - } - - String ObjectAbstractNode::getValue() const - { - return cls; - } - - void ObjectAbstractNode::addVariable(const Ogre::String &inName) - { - mEnv.insert(std::make_pair(inName, "")); - } - - void ObjectAbstractNode::setVariable(const Ogre::String &inName, const Ogre::String &value) - { - mEnv[inName] = value; - } - - std::pair ObjectAbstractNode::getVariable(const String &inName) const - { - map::type::const_iterator i = mEnv.find(inName); - if(i != mEnv.end()) - return std::make_pair(true, i->second); - - ObjectAbstractNode *parentNode = (ObjectAbstractNode*)this->parent; - while(parentNode) - { - i = parentNode->mEnv.find(inName); - if(i != parentNode->mEnv.end()) - return std::make_pair(true, i->second); - parentNode = (ObjectAbstractNode*)parentNode->parent; - } - return std::make_pair(false, ""); - } - - const map::type &ObjectAbstractNode::getVariables() const - { - return mEnv; - } - - // PropertyAbstractNode - PropertyAbstractNode::PropertyAbstractNode(AbstractNode *ptr) - :AbstractNode(ptr), id(0) - { - type = ANT_PROPERTY; - } - - AbstractNode *PropertyAbstractNode::clone() const - { - PropertyAbstractNode *node = OGRE_NEW PropertyAbstractNode(parent); - node->file = file; - node->line = line; - node->type = type; - node->name = name; - node->id = id; - for(AbstractNodeList::const_iterator i = values.begin(); i != values.end(); ++i) - { - AbstractNodePtr newNode = AbstractNodePtr((*i)->clone()); - newNode->parent = node; - node->values.push_back(newNode); - } - return node; - } - - String PropertyAbstractNode::getValue() const - { - return name; - } - - // ImportAbstractNode - ImportAbstractNode::ImportAbstractNode() - :AbstractNode(0) - { - type = ANT_IMPORT; - } - - AbstractNode *ImportAbstractNode::clone() const - { - ImportAbstractNode *node = OGRE_NEW ImportAbstractNode(); - node->file = file; - node->line = line; - node->type = type; - node->target = target; - node->source = source; - return node; - } - - String ImportAbstractNode::getValue() const - { - return target; - } - - // VariableAccessAbstractNode - VariableAccessAbstractNode::VariableAccessAbstractNode(AbstractNode *ptr) - :AbstractNode(ptr) - { - type = ANT_VARIABLE_ACCESS; - } - - AbstractNode *VariableAccessAbstractNode::clone() const - { - VariableAccessAbstractNode *node = OGRE_NEW VariableAccessAbstractNode(parent); - node->file = file; - node->line = line; - node->type = type; - node->name = name; - return node; - } - - String VariableAccessAbstractNode::getValue() const - { - return name; - } - - // ScriptCompilerListener - ScriptCompilerListener::ScriptCompilerListener() - { - } - - ConcreteNodeListPtr ScriptCompilerListener::importFile(ScriptCompiler *compiler, const String &name) - { - return ConcreteNodeListPtr(); - } - - void ScriptCompilerListener::preConversion(ScriptCompiler *compiler, ConcreteNodeListPtr nodes) - { - - } - - bool ScriptCompilerListener::postConversion(ScriptCompiler *compiler, const AbstractNodeListPtr &nodes) - { - return true; - } - - void ScriptCompilerListener::handleError(ScriptCompiler *compiler, uint32 code, const String &file, int line, const String &msg) - { - Ogre::String str = "Compiler error: "; - str = str + ScriptCompiler::formatErrorCode(code) + " in " + file + "(" + - Ogre::StringConverter::toString(line) + ")"; - if(!msg.empty()) - str = str + ": " + msg; - Ogre::LogManager::getSingleton().logMessage(str, LML_CRITICAL); - } - - bool ScriptCompilerListener::handleEvent(ScriptCompiler *compiler, ScriptCompilerEvent *evt, void *retval) - { - return false; - } - - // ScriptCompiler - String ScriptCompiler::formatErrorCode(uint32 code) - { - switch(code) - { - case ScriptCompiler::CE_STRINGEXPECTED: - return "string expected"; - case ScriptCompiler::CE_NUMBEREXPECTED: - return "number expected"; - case ScriptCompiler::CE_FEWERPARAMETERSEXPECTED: - return "fewer parameters expected"; - case ScriptCompiler::CE_VARIABLEEXPECTED: - return "variable expected"; - case ScriptCompiler::CE_UNDEFINEDVARIABLE: - return "undefined variable"; - case ScriptCompiler::CE_OBJECTNAMEEXPECTED: - return "object name expected"; - case ScriptCompiler::CE_OBJECTALLOCATIONERROR: - return "object allocation error"; - case ScriptCompiler::CE_INVALIDPARAMETERS: - return "invalid parameters"; - case ScriptCompiler::CE_DUPLICATEOVERRIDE: - return "duplicate object override"; - case ScriptCompiler::CE_UNSUPPORTEDBYRENDERSYSTEM: - return "object unsupported by render system"; - case ScriptCompiler::CE_REFERENCETOANONEXISTINGOBJECT: - return "reference to a non existing object"; - default: - return "unknown error"; - } - } - - ScriptCompiler::ScriptCompiler() - :mListener(0) - { - initWordMap(); - } - - bool ScriptCompiler::compile(const String &str, const String &source, const String &group) - { - ScriptLexer lexer; - ScriptParser parser; - ConcreteNodeListPtr nodes = parser.parse(lexer.tokenize(str, source)); - return compile(nodes, group); - } - -// static void logAST(int tabs, const AbstractNodePtr &node) -// { -// String msg = ""; -// for(int i = 0; i < tabs; ++i) -// msg += "\t"; + // AbstractNode + AbstractNode::AbstractNode(AbstractNode *ptr) + :line(0), type(ANT_UNKNOWN), parent(ptr) + {} + + // AtomAbstractNode + AtomAbstractNode::AtomAbstractNode(AbstractNode *ptr) + :AbstractNode(ptr), id(0) + { + type = ANT_ATOM; + } + + AbstractNode *AtomAbstractNode::clone() const + { + AtomAbstractNode *node = OGRE_NEW AtomAbstractNode(parent); + node->file = file; + node->line = line; + node->id = id; + node->type = type; + node->value = value; + return node; + } + + String AtomAbstractNode::getValue() const + { + return value; + } + + // ObjectAbstractNode + ObjectAbstractNode::ObjectAbstractNode(AbstractNode *ptr) + :AbstractNode(ptr), id(0), abstract(false) + { + type = ANT_OBJECT; + } + + AbstractNode *ObjectAbstractNode::clone() const + { + ObjectAbstractNode *node = OGRE_NEW ObjectAbstractNode(parent); + node->file = file; + node->line = line; + node->type = type; + node->name = name; + node->cls = cls; + node->id = id; + node->abstract = abstract; + for(AbstractNodeList::const_iterator i = children.begin(); i != children.end(); ++i) + { + AbstractNodePtr newNode = AbstractNodePtr((*i)->clone()); + newNode->parent = node; + node->children.push_back(newNode); + } + for(AbstractNodeList::const_iterator i = values.begin(); i != values.end(); ++i) + { + AbstractNodePtr newNode = AbstractNodePtr((*i)->clone()); + newNode->parent = node; + node->values.push_back(newNode); + } + node->mEnv = mEnv; + return node; + } + + String ObjectAbstractNode::getValue() const + { + return cls; + } + + void ObjectAbstractNode::addVariable(const Ogre::String &inName) + { + mEnv.insert(std::make_pair(inName, "")); + } + + void ObjectAbstractNode::setVariable(const Ogre::String &inName, const Ogre::String &value) + { + mEnv[inName] = value; + } + + std::pair ObjectAbstractNode::getVariable(const String &inName) const + { + map::type::const_iterator i = mEnv.find(inName); + if(i != mEnv.end()) + return std::make_pair(true, i->second); + + ObjectAbstractNode *parentNode = (ObjectAbstractNode*)this->parent; + while(parentNode) + { + i = parentNode->mEnv.find(inName); + if(i != parentNode->mEnv.end()) + return std::make_pair(true, i->second); + parentNode = (ObjectAbstractNode*)parentNode->parent; + } + return std::make_pair(false, ""); + } + + const map::type &ObjectAbstractNode::getVariables() const + { + return mEnv; + } + + // PropertyAbstractNode + PropertyAbstractNode::PropertyAbstractNode(AbstractNode *ptr) + :AbstractNode(ptr), id(0) + { + type = ANT_PROPERTY; + } + + AbstractNode *PropertyAbstractNode::clone() const + { + PropertyAbstractNode *node = OGRE_NEW PropertyAbstractNode(parent); + node->file = file; + node->line = line; + node->type = type; + node->name = name; + node->id = id; + for(AbstractNodeList::const_iterator i = values.begin(); i != values.end(); ++i) + { + AbstractNodePtr newNode = AbstractNodePtr((*i)->clone()); + newNode->parent = node; + node->values.push_back(newNode); + } + return node; + } + + String PropertyAbstractNode::getValue() const + { + return name; + } + + // ImportAbstractNode + ImportAbstractNode::ImportAbstractNode() + :AbstractNode(0) + { + type = ANT_IMPORT; + } + + AbstractNode *ImportAbstractNode::clone() const + { + ImportAbstractNode *node = OGRE_NEW ImportAbstractNode(); + node->file = file; + node->line = line; + node->type = type; + node->target = target; + node->source = source; + return node; + } + + String ImportAbstractNode::getValue() const + { + return target; + } + + // VariableAccessAbstractNode + VariableAccessAbstractNode::VariableAccessAbstractNode(AbstractNode *ptr) + :AbstractNode(ptr) + { + type = ANT_VARIABLE_ACCESS; + } + + AbstractNode *VariableAccessAbstractNode::clone() const + { + VariableAccessAbstractNode *node = OGRE_NEW VariableAccessAbstractNode(parent); + node->file = file; + node->line = line; + node->type = type; + node->name = name; + return node; + } + + String VariableAccessAbstractNode::getValue() const + { + return name; + } + + // ScriptCompilerListener + ScriptCompilerListener::ScriptCompilerListener() + { + } + + ConcreteNodeListPtr ScriptCompilerListener::importFile(ScriptCompiler *compiler, const String &name) + { + return ConcreteNodeListPtr(); + } + + void ScriptCompilerListener::preConversion(ScriptCompiler *compiler, ConcreteNodeListPtr nodes) + { + + } + + bool ScriptCompilerListener::postConversion(ScriptCompiler *compiler, const AbstractNodeListPtr &nodes) + { + return true; + } + + void ScriptCompilerListener::handleError(ScriptCompiler *compiler, uint32 code, const String &file, int line, const String &msg) + { + Ogre::String str = "Compiler error: "; + str = str + ScriptCompiler::formatErrorCode(code) + " in " + file + "(" + + Ogre::StringConverter::toString(line) + ")"; + if(!msg.empty()) + str = str + ": " + msg; + Ogre::LogManager::getSingleton().logMessage(str, LML_CRITICAL); + } + + bool ScriptCompilerListener::handleEvent(ScriptCompiler *compiler, ScriptCompilerEvent *evt, void *retval) + { + return false; + } + + // ScriptCompiler + String ScriptCompiler::formatErrorCode(uint32 code) + { + switch(code) + { + case ScriptCompiler::CE_STRINGEXPECTED: + return "string expected"; + case ScriptCompiler::CE_NUMBEREXPECTED: + return "number expected"; + case ScriptCompiler::CE_FEWERPARAMETERSEXPECTED: + return "fewer parameters expected"; + case ScriptCompiler::CE_VARIABLEEXPECTED: + return "variable expected"; + case ScriptCompiler::CE_UNDEFINEDVARIABLE: + return "undefined variable"; + case ScriptCompiler::CE_OBJECTNAMEEXPECTED: + return "object name expected"; + case ScriptCompiler::CE_OBJECTALLOCATIONERROR: + return "object allocation error"; + case ScriptCompiler::CE_INVALIDPARAMETERS: + return "invalid parameters"; + case ScriptCompiler::CE_DUPLICATEOVERRIDE: + return "duplicate object override"; + case ScriptCompiler::CE_UNSUPPORTEDBYRENDERSYSTEM: + return "object unsupported by render system"; + case ScriptCompiler::CE_REFERENCETOANONEXISTINGOBJECT: + return "reference to a non existing object"; + default: + return "unknown error"; + } + } + + ScriptCompiler::ScriptCompiler() + :mListener(0) + { + initWordMap(); + } + + bool ScriptCompiler::compile(const String &str, const String &source, const String &group) + { + ScriptLexer lexer; + ScriptParser parser; + ConcreteNodeListPtr nodes = parser.parse(lexer.tokenize(str, source)); + return compile(nodes, group); + } + +// static void logAST(int tabs, const AbstractNodePtr &node) +// { +// String msg = ""; +// for(int i = 0; i < tabs; ++i) +// msg += "\t"; // -// switch(node->type) -// { -// case ANT_ATOM: -// { -// AtomAbstractNode *atom = reinterpret_cast(node.get()); -// msg = msg + atom->value; -// } -// break; -// case ANT_PROPERTY: -// { -// PropertyAbstractNode *prop = reinterpret_cast(node.get()); -// msg = msg + prop->name + " ="; -// for(AbstractNodeList::iterator i = prop->values.begin(); i != prop->values.end(); ++i) -// { -// if((*i)->type == ANT_ATOM) -// msg = msg + " " + reinterpret_cast((*i).get())->value; -// } -// } -// break; -// case ANT_OBJECT: -// { -// ObjectAbstractNode *obj = reinterpret_cast(node.get()); -// msg = msg + node->file + " - " + StringConverter::toString(node->line) + " - " + obj->cls + " \"" + obj->name + "\" ="; -// for(AbstractNodeList::iterator i = obj->values.begin(); i != obj->values.end(); ++i) -// { -// if((*i)->type == ANT_ATOM) -// msg = msg + " " + reinterpret_cast((*i).get())->value; -// } -// } -// break; -// default: -// msg = msg + "Unacceptable node type: " + StringConverter::toString(node->type); -// } +// switch(node->type) +// { +// case ANT_ATOM: +// { +// AtomAbstractNode *atom = reinterpret_cast(node.get()); +// msg = msg + atom->value; +// } +// break; +// case ANT_PROPERTY: +// { +// PropertyAbstractNode *prop = reinterpret_cast(node.get()); +// msg = msg + prop->name + " ="; +// for(AbstractNodeList::iterator i = prop->values.begin(); i != prop->values.end(); ++i) +// { +// if((*i)->type == ANT_ATOM) +// msg = msg + " " + reinterpret_cast((*i).get())->value; +// } +// } +// break; +// case ANT_OBJECT: +// { +// ObjectAbstractNode *obj = reinterpret_cast(node.get()); +// msg = msg + node->file + " - " + StringConverter::toString(node->line) + " - " + obj->cls + " \"" + obj->name + "\" ="; +// for(AbstractNodeList::iterator i = obj->values.begin(); i != obj->values.end(); ++i) +// { +// if((*i)->type == ANT_ATOM) +// msg = msg + " " + reinterpret_cast((*i).get())->value; +// } +// } +// break; +// default: +// msg = msg + "Unacceptable node type: " + StringConverter::toString(node->type); +// } // -// LogManager::getSingleton().logMessage(msg); +// LogManager::getSingleton().logMessage(msg); // -// if(node->type == ANT_OBJECT) -// { -// ObjectAbstractNode *obj = reinterpret_cast(node.get()); -// for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) -// { -// logAST(tabs + 1, *i); -// } -// } -// } - - bool ScriptCompiler::compile(const ConcreteNodeListPtr &nodes, const String &group) - { - // Set up the compilation context - mGroup = group; - - // Clear the past errors - mErrors.clear(); - - // Clear the environment - mEnv.clear(); - - if(mListener) - mListener->preConversion(this, nodes); - - // Convert our nodes to an AST - AbstractNodeListPtr ast = convertToAST(nodes); - // Processes the imports for this script - processImports(ast); - // Process object inheritance - processObjects(ast.get(), ast); - // Process variable expansion - processVariables(ast.get()); - - // Allows early bail-out through the listener - if(mListener && !mListener->postConversion(this, ast)) - return mErrors.empty(); - - // Translate the nodes - for(AbstractNodeList::iterator i = ast->begin(); i != ast->end(); ++i) - { - //logAST(0, *i); - if((*i)->type == ANT_OBJECT && reinterpret_cast((*i).get())->abstract) - continue; - //LogManager::getSingleton().logMessage(reinterpret_cast((*i).get())->name); - ScriptTranslator *translator = ScriptCompilerManager::getSingleton().getTranslator(*i); - if(translator) - translator->translate(this, *i); - } - - mImports.clear(); - mImportRequests.clear(); - mImportTable.clear(); - - return mErrors.empty(); - } - - AbstractNodeListPtr ScriptCompiler::_generateAST(const String &str, const String &source, bool doImports, bool doObjects, bool doVariables) - { - // Clear the past errors - mErrors.clear(); - - ScriptLexer lexer; - ScriptParser parser; - ConcreteNodeListPtr cst = parser.parse(lexer.tokenize(str, source)); - - // Call the listener to intercept CST - if(mListener) - mListener->preConversion(this, cst); - - // Convert our nodes to an AST - AbstractNodeListPtr ast = convertToAST(cst); - - if(!ast.isNull() && doImports) - processImports(ast); - if(!ast.isNull() && doObjects) - processObjects(ast.get(), ast); - if(!ast.isNull() && doVariables) - processVariables(ast.get()); - - return ast; - } - - bool ScriptCompiler::_compile(AbstractNodeListPtr nodes, const String &group, bool doImports, bool doObjects, bool doVariables) - { - // Set up the compilation context - mGroup = group; - - // Clear the past errors - mErrors.clear(); - - // Clear the environment - mEnv.clear(); - - // Processes the imports for this script - if(doImports) - processImports(nodes); - // Process object inheritance - if(doObjects) - processObjects(nodes.get(), nodes); - // Process variable expansion - if(doVariables) - processVariables(nodes.get()); - - // Translate the nodes - for(AbstractNodeList::iterator i = nodes->begin(); i != nodes->end(); ++i) - { - //logAST(0, *i); - if((*i)->type == ANT_OBJECT && reinterpret_cast((*i).get())->abstract) - continue; - ScriptTranslator *translator = ScriptCompilerManager::getSingleton().getTranslator(*i); - if(translator) - translator->translate(this, *i); - } - - return mErrors.empty(); - } - - void ScriptCompiler::addError(uint32 code, const Ogre::String &file, int line, const String &msg) - { - ErrorPtr err(OGRE_NEW Error()); - err->code = code; - err->file = file; - err->line = line; - err->message = msg; - - if(mListener) - { - mListener->handleError(this, code, file, line, msg); - } - else - { - Ogre::String str = "Compiler error: "; - str = str + formatErrorCode(code) + " in " + file + "(" + - Ogre::StringConverter::toString(line) + ")"; - if(!msg.empty()) - str = str + ": " + msg; - Ogre::LogManager::getSingleton().logMessage(str, LML_CRITICAL); - } - - mErrors.push_back(err); - } - - void ScriptCompiler::setListener(ScriptCompilerListener *listener) - { - mListener = listener; - } - - ScriptCompilerListener *ScriptCompiler::getListener() - { - return mListener; - } - - const String &ScriptCompiler::getResourceGroup() const - { - return mGroup; - } - - bool ScriptCompiler::_fireEvent(ScriptCompilerEvent *evt, void *retval) - { - if(mListener) - return mListener->handleEvent(this, evt, retval); - return false; - } - - AbstractNodeListPtr ScriptCompiler::convertToAST(const Ogre::ConcreteNodeListPtr &nodes) - { - AbstractTreeBuilder builder(this); - AbstractTreeBuilder::visit(&builder, *nodes.get()); - return builder.getResult(); - } - - void ScriptCompiler::processImports(Ogre::AbstractNodeListPtr &nodes) - { - // We only need to iterate over the top-level of nodes - AbstractNodeList::iterator i = nodes->begin(); - while(i != nodes->end()) - { - // We move to the next node here and save the current one. - // If any replacement happens, then we are still assured that - // i points to the node *after* the replaced nodes, no matter - // how many insertions and deletions may happen - AbstractNodeList::iterator cur = i++; - if((*cur)->type == ANT_IMPORT) - { - ImportAbstractNode *import = (ImportAbstractNode*)(*cur).get(); - // Only process if the file's contents haven't been loaded - if(mImports.find(import->source) == mImports.end()) - { - // Load the script - AbstractNodeListPtr importedNodes = loadImportPath(import->source); - if(!importedNodes.isNull() && !importedNodes->empty()) - { - processImports(importedNodes); - processObjects(importedNodes.get(), importedNodes); - } - if(!importedNodes.isNull() && !importedNodes->empty()) - mImports.insert(std::make_pair(import->source, importedNodes)); - } - - // Handle the target request now - // If it is a '*' import we remove all previous requests and just use the '*' - // Otherwise, ensure '*' isn't already registered and register our request - if(import->target == "*") - { - mImportRequests.erase(mImportRequests.lower_bound(import->source), - mImportRequests.upper_bound(import->source)); - mImportRequests.insert(std::make_pair(import->source, "*")); - } - else - { - ImportRequestMap::iterator iter = mImportRequests.lower_bound(import->source), - end = mImportRequests.upper_bound(import->source); - if(iter == end || iter->second != "*") - { - mImportRequests.insert(std::make_pair(import->source, import->target)); - } - } - - nodes->erase(cur); - } - } - - // All import nodes are removed - // We have cached the code blocks from all the imported scripts - // We can process all import requests now - for(ImportCacheMap::iterator it = mImports.begin(); it != mImports.end(); ++it) - { - ImportRequestMap::iterator j = mImportRequests.lower_bound(it->first), - end = mImportRequests.upper_bound(it->first); - if(j != end) - { - if(j->second == "*") - { - // Insert the entire AST into the import table - mImportTable.insert(mImportTable.begin(), it->second->begin(), it->second->end()); - continue; // Skip ahead to the next file - } - else - { - for(; j != end; ++j) - { - // Locate this target and insert it into the import table - AbstractNodeListPtr newNodes = locateTarget(it->second.get(), j->second); - if(!newNodes.isNull() && !newNodes->empty()) - mImportTable.insert(mImportTable.begin(), newNodes->begin(), newNodes->end()); - } - } - } - } - } - - AbstractNodeListPtr ScriptCompiler::loadImportPath(const Ogre::String &name) - { - AbstractNodeListPtr retval; - ConcreteNodeListPtr nodes; - - if(mListener) - nodes = mListener->importFile(this, name); - - if(nodes.isNull() && ResourceGroupManager::getSingletonPtr()) - { - DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(name, mGroup); - if(!stream.isNull()) - { - ScriptLexer lexer; - ScriptTokenListPtr tokens = lexer.tokenize(stream->getAsString(), name); - ScriptParser parser; - nodes = parser.parse(tokens); - } - } - - if(!nodes.isNull()) - retval = convertToAST(nodes); - - return retval; - } - - AbstractNodeListPtr ScriptCompiler::locateTarget(AbstractNodeList *nodes, const Ogre::String &target) - { - AbstractNodeList::iterator iter = nodes->end(); - - // Search for a top-level object node - for(AbstractNodeList::iterator i = nodes->begin(); i != nodes->end(); ++i) - { - if((*i)->type == ANT_OBJECT) - { - ObjectAbstractNode *impl = (ObjectAbstractNode*)(*i).get(); - if(impl->name == target) - iter = i; - } - } - - // MEMCATEGORY_GENERAL is the only category supported for SharedPtr - AbstractNodeListPtr newNodes(OGRE_NEW_T(AbstractNodeList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); - if(iter != nodes->end()) - { - newNodes->push_back(*iter); - } - return newNodes; - } - - void ScriptCompiler::processObjects(Ogre::AbstractNodeList *nodes, const Ogre::AbstractNodeListPtr &top) - { - for(AbstractNodeList::iterator i = nodes->begin(); i != nodes->end(); ++i) - { - if((*i)->type == ANT_OBJECT) - { - ObjectAbstractNode *obj = (ObjectAbstractNode*)(*i).get(); - - // Overlay base classes in order. +// if(node->type == ANT_OBJECT) +// { +// ObjectAbstractNode *obj = reinterpret_cast(node.get()); +// for(AbstractNodeList::iterator i = obj->children.begin(); i != obj->children.end(); ++i) +// { +// logAST(tabs + 1, *i); +// } +// } +// } + + bool ScriptCompiler::compile(const ConcreteNodeListPtr &nodes, const String &group) + { + // Set up the compilation context + mGroup = group; + + // Clear the past errors + mErrors.clear(); + + // Clear the environment + mEnv.clear(); + + if(mListener) + mListener->preConversion(this, nodes); + + // Convert our nodes to an AST + AbstractNodeListPtr ast = convertToAST(nodes); + // Processes the imports for this script + processImports(ast); + // Process object inheritance + processObjects(ast.get(), ast); + // Process variable expansion + processVariables(ast.get()); + + // Allows early bail-out through the listener + if(mListener && !mListener->postConversion(this, ast)) + return mErrors.empty(); + + // Translate the nodes + for(AbstractNodeList::iterator i = ast->begin(); i != ast->end(); ++i) + { + //logAST(0, *i); + if((*i)->type == ANT_OBJECT && reinterpret_cast((*i).get())->abstract) + continue; + //LogManager::getSingleton().logMessage(reinterpret_cast((*i).get())->name); + ScriptTranslator *translator = ScriptCompilerManager::getSingleton().getTranslator(*i); + if(translator) + translator->translate(this, *i); + } + + mImports.clear(); + mImportRequests.clear(); + mImportTable.clear(); + + return mErrors.empty(); + } + + AbstractNodeListPtr ScriptCompiler::_generateAST(const String &str, const String &source, bool doImports, bool doObjects, bool doVariables) + { + // Clear the past errors + mErrors.clear(); + + ScriptLexer lexer; + ScriptParser parser; + ConcreteNodeListPtr cst = parser.parse(lexer.tokenize(str, source)); + + // Call the listener to intercept CST + if(mListener) + mListener->preConversion(this, cst); + + // Convert our nodes to an AST + AbstractNodeListPtr ast = convertToAST(cst); + + if(!ast.isNull() && doImports) + processImports(ast); + if(!ast.isNull() && doObjects) + processObjects(ast.get(), ast); + if(!ast.isNull() && doVariables) + processVariables(ast.get()); + + return ast; + } + + bool ScriptCompiler::_compile(AbstractNodeListPtr nodes, const String &group, bool doImports, bool doObjects, bool doVariables) + { + // Set up the compilation context + mGroup = group; + + // Clear the past errors + mErrors.clear(); + + // Clear the environment + mEnv.clear(); + + // Processes the imports for this script + if(doImports) + processImports(nodes); + // Process object inheritance + if(doObjects) + processObjects(nodes.get(), nodes); + // Process variable expansion + if(doVariables) + processVariables(nodes.get()); + + // Translate the nodes + for(AbstractNodeList::iterator i = nodes->begin(); i != nodes->end(); ++i) + { + //logAST(0, *i); + if((*i)->type == ANT_OBJECT && reinterpret_cast((*i).get())->abstract) + continue; + ScriptTranslator *translator = ScriptCompilerManager::getSingleton().getTranslator(*i); + if(translator) + translator->translate(this, *i); + } + + return mErrors.empty(); + } + + void ScriptCompiler::addError(uint32 code, const Ogre::String &file, int line, const String &msg) + { + ErrorPtr err(OGRE_NEW Error()); + err->code = code; + err->file = file; + err->line = line; + err->message = msg; + + if(mListener) + { + mListener->handleError(this, code, file, line, msg); + } + else + { + Ogre::String str = "Compiler error: "; + str = str + formatErrorCode(code) + " in " + file + "(" + + Ogre::StringConverter::toString(line) + ")"; + if(!msg.empty()) + str = str + ": " + msg; + Ogre::LogManager::getSingleton().logMessage(str, LML_CRITICAL); + } + + mErrors.push_back(err); + } + + void ScriptCompiler::setListener(ScriptCompilerListener *listener) + { + mListener = listener; + } + + ScriptCompilerListener *ScriptCompiler::getListener() + { + return mListener; + } + + const String &ScriptCompiler::getResourceGroup() const + { + return mGroup; + } + + bool ScriptCompiler::_fireEvent(ScriptCompilerEvent *evt, void *retval) + { + if(mListener) + return mListener->handleEvent(this, evt, retval); + return false; + } + + AbstractNodeListPtr ScriptCompiler::convertToAST(const Ogre::ConcreteNodeListPtr &nodes) + { + AbstractTreeBuilder builder(this); + AbstractTreeBuilder::visit(&builder, *nodes.get()); + return builder.getResult(); + } + + void ScriptCompiler::processImports(Ogre::AbstractNodeListPtr &nodes) + { + // We only need to iterate over the top-level of nodes + AbstractNodeList::iterator i = nodes->begin(); + while(i != nodes->end()) + { + // We move to the next node here and save the current one. + // If any replacement happens, then we are still assured that + // i points to the node *after* the replaced nodes, no matter + // how many insertions and deletions may happen + AbstractNodeList::iterator cur = i++; + if((*cur)->type == ANT_IMPORT) + { + ImportAbstractNode *import = (ImportAbstractNode*)(*cur).get(); + // Only process if the file's contents haven't been loaded + if(mImports.find(import->source) == mImports.end()) + { + // Load the script + AbstractNodeListPtr importedNodes = loadImportPath(import->source); + if(!importedNodes.isNull() && !importedNodes->empty()) + { + processImports(importedNodes); + processObjects(importedNodes.get(), importedNodes); + } + if(!importedNodes.isNull() && !importedNodes->empty()) + mImports.insert(std::make_pair(import->source, importedNodes)); + } + + // Handle the target request now + // If it is a '*' import we remove all previous requests and just use the '*' + // Otherwise, ensure '*' isn't already registered and register our request + if(import->target == "*") + { + mImportRequests.erase(mImportRequests.lower_bound(import->source), + mImportRequests.upper_bound(import->source)); + mImportRequests.insert(std::make_pair(import->source, "*")); + } + else + { + ImportRequestMap::iterator iter = mImportRequests.lower_bound(import->source), + end = mImportRequests.upper_bound(import->source); + if(iter == end || iter->second != "*") + { + mImportRequests.insert(std::make_pair(import->source, import->target)); + } + } + + nodes->erase(cur); + } + } + + // All import nodes are removed + // We have cached the code blocks from all the imported scripts + // We can process all import requests now + for(ImportCacheMap::iterator it = mImports.begin(); it != mImports.end(); ++it) + { + ImportRequestMap::iterator j = mImportRequests.lower_bound(it->first), + end = mImportRequests.upper_bound(it->first); + if(j != end) + { + if(j->second == "*") + { + // Insert the entire AST into the import table + mImportTable.insert(mImportTable.begin(), it->second->begin(), it->second->end()); + continue; // Skip ahead to the next file + } + else + { + for(; j != end; ++j) + { + // Locate this target and insert it into the import table + AbstractNodeListPtr newNodes = locateTarget(it->second.get(), j->second); + if(!newNodes.isNull() && !newNodes->empty()) + mImportTable.insert(mImportTable.begin(), newNodes->begin(), newNodes->end()); + } + } + } + } + } + + AbstractNodeListPtr ScriptCompiler::loadImportPath(const Ogre::String &name) + { + AbstractNodeListPtr retval; + ConcreteNodeListPtr nodes; + + if(mListener) + nodes = mListener->importFile(this, name); + + if(nodes.isNull() && ResourceGroupManager::getSingletonPtr()) + { + DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(name, mGroup); + if(!stream.isNull()) + { + ScriptLexer lexer; + ScriptTokenListPtr tokens = lexer.tokenize(stream->getAsString(), name); + ScriptParser parser; + nodes = parser.parse(tokens); + } + } + + if(!nodes.isNull()) + retval = convertToAST(nodes); + + return retval; + } + + AbstractNodeListPtr ScriptCompiler::locateTarget(AbstractNodeList *nodes, const Ogre::String &target) + { + AbstractNodeList::iterator iter = nodes->end(); + + // Search for a top-level object node + for(AbstractNodeList::iterator i = nodes->begin(); i != nodes->end(); ++i) + { + if((*i)->type == ANT_OBJECT) + { + ObjectAbstractNode *impl = (ObjectAbstractNode*)(*i).get(); + if(impl->name == target) + iter = i; + } + } + + // MEMCATEGORY_GENERAL is the only category supported for SharedPtr + AbstractNodeListPtr newNodes(OGRE_NEW_T(AbstractNodeList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); + if(iter != nodes->end()) + { + newNodes->push_back(*iter); + } + return newNodes; + } + + void ScriptCompiler::processObjects(Ogre::AbstractNodeList *nodes, const Ogre::AbstractNodeListPtr &top) + { + for(AbstractNodeList::iterator i = nodes->begin(); i != nodes->end(); ++i) + { + if((*i)->type == ANT_OBJECT) + { + ObjectAbstractNode *obj = (ObjectAbstractNode*)(*i).get(); + + // Overlay base classes in order. for (vector::const_iterator baseIt = obj->bases.begin(), end_it = obj->bases.end(); baseIt != end_it; ++baseIt) - { + { const String& base = *baseIt; - // Check the top level first, then check the import table - AbstractNodeListPtr newNodes = locateTarget(top.get(), base); - if(newNodes->empty()) - newNodes = locateTarget(&mImportTable, base); - - if (!newNodes->empty()) { - for(AbstractNodeList::iterator j = newNodes->begin(); j != newNodes->end(); ++j) { - overlayObject(*j, obj); + // Check the top level first, then check the import table + AbstractNodeListPtr newNodes = locateTarget(top.get(), base); + if(newNodes->empty()) + newNodes = locateTarget(&mImportTable, base); + + if (!newNodes->empty()) { + for(AbstractNodeList::iterator j = newNodes->begin(); j != newNodes->end(); ++j) { + overlayObject(*j, obj); + } + } else { + addError(CE_OBJECTBASENOTFOUND, obj->file, obj->line, + "base object named \"" + base + "\" not found in script definition"); + } + } + + // Recurse into children + processObjects(&obj->children, top); + + // Overrides now exist in obj's overrides list. These are non-object nodes which must now + // Be placed in the children section of the object node such that overriding from parents + // into children works properly. + obj->children.insert(obj->children.begin(), obj->overrides.begin(), obj->overrides.end()); + } + } + } + + void ScriptCompiler::overlayObject(const AbstractNodePtr &source, ObjectAbstractNode *dest) + { + if(source->type == ANT_OBJECT) + { + ObjectAbstractNode *src = reinterpret_cast(source.get()); + + // Overlay the environment of one on top the other first + for(map::type::const_iterator i = src->getVariables().begin(); i != src->getVariables().end(); ++i) + { + std::pair var = dest->getVariable(i->first); + if(!var.first) + dest->setVariable(i->first, i->second); + } + + // Create a vector storing each pairing of override between source and destination + vector >::type overrides; + // A list of indices for each destination node tracks the minimum + // source node they can index-match against + map::type indices; + // A map storing which nodes have overridden from the destination node + map::type overridden; + + // Fill the vector with objects from the source node (base) + // And insert non-objects into the overrides list of the destination + AbstractNodeList::iterator insertPos = dest->children.begin(); + for(AbstractNodeList::const_iterator i = src->children.begin(); i != src->children.end(); ++i) + { + if((*i)->type == ANT_OBJECT) + { + overrides.push_back(std::make_pair(*i, dest->children.end())); + } + else + { + AbstractNodePtr newNode((*i)->clone()); + newNode->parent = dest; + dest->overrides.push_back(newNode); + } + } + + // Track the running maximum override index in the name-matching phase + size_t maxOverrideIndex = 0; + + // Loop through destination children searching for name-matching overrides + for(AbstractNodeList::iterator i = dest->children.begin(); i != dest->children.end(); ) + { + if((*i)->type == ANT_OBJECT) + { + // Start tracking the override index position for this object + size_t overrideIndex = 0; + + ObjectAbstractNode *node = reinterpret_cast((*i).get()); + indices[node] = maxOverrideIndex; + overridden[node] = false; + + // special treatment for materials with * in their name + bool nodeHasWildcard=node->name.find('*') != String::npos; + + // Find the matching name node + for(size_t j = 0; j < overrides.size(); ++j) + { + ObjectAbstractNode *temp = reinterpret_cast(overrides[j].first.get()); + // Consider a match a node that has a wildcard and matches an input name + bool wildcardMatch = nodeHasWildcard && + (StringUtil::match(temp->name,node->name,true) || + (node->name.size() == 1 && temp->name.empty())); + if(temp->cls == node->cls && !node->name.empty() && (temp->name == node->name || wildcardMatch)) + { + // Pair these two together unless it's already paired + if(overrides[j].second == dest->children.end()) + { + AbstractNodeList::iterator currentIterator = i; + ObjectAbstractNode *currentNode = node; + if (wildcardMatch) + { + //If wildcard is matched, make a copy of current material and put it before the iterator, matching its name to the parent. Use same reinterpret cast as above when node is set + AbstractNodePtr newNode((*i)->clone()); + currentIterator = dest->children.insert(currentIterator, newNode); + currentNode = reinterpret_cast((*currentIterator).get()); + currentNode->name = temp->name;//make the regex match its matcher + } + overrides[j] = std::make_pair(overrides[j].first, currentIterator); + // Store the max override index for this matched pair + overrideIndex = j; + overrideIndex = maxOverrideIndex = std::max(overrideIndex, maxOverrideIndex); + indices[currentNode] = overrideIndex; + overridden[currentNode] = true; + } + else + { + addError(CE_DUPLICATEOVERRIDE, node->file, node->line); + } + + if(!wildcardMatch) + break; } - } else { - addError(CE_OBJECTBASENOTFOUND, obj->file, obj->line, - "base object named \"" + base + "\" not found in script definition"); - } - } - - // Recurse into children - processObjects(&obj->children, top); - - // Overrides now exist in obj's overrides list. These are non-object nodes which must now - // Be placed in the children section of the object node such that overriding from parents - // into children works properly. - obj->children.insert(obj->children.begin(), obj->overrides.begin(), obj->overrides.end()); - } - } - } - - void ScriptCompiler::overlayObject(const AbstractNodePtr &source, ObjectAbstractNode *dest) - { - if(source->type == ANT_OBJECT) - { - ObjectAbstractNode *src = reinterpret_cast(source.get()); - - // Overlay the environment of one on top the other first - for(map::type::const_iterator i = src->getVariables().begin(); i != src->getVariables().end(); ++i) - { - std::pair var = dest->getVariable(i->first); - if(!var.first) - dest->setVariable(i->first, i->second); - } - - // Create a vector storing each pairing of override between source and destination - vector >::type overrides; - // A list of indices for each destination node tracks the minimum - // source node they can index-match against - map::type indices; - // A map storing which nodes have overridden from the destination node - map::type overridden; - - // Fill the vector with objects from the source node (base) - // And insert non-objects into the overrides list of the destination - AbstractNodeList::iterator insertPos = dest->children.begin(); - for(AbstractNodeList::const_iterator i = src->children.begin(); i != src->children.end(); ++i) - { - if((*i)->type == ANT_OBJECT) - { - overrides.push_back(std::make_pair(*i, dest->children.end())); - } - else - { - AbstractNodePtr newNode((*i)->clone()); - newNode->parent = dest; - dest->overrides.push_back(newNode); - } - } - - // Track the running maximum override index in the name-matching phase - size_t maxOverrideIndex = 0; - - // Loop through destination children searching for name-matching overrides - for(AbstractNodeList::iterator i = dest->children.begin(); i != dest->children.end(); ) - { - if((*i)->type == ANT_OBJECT) - { - // Start tracking the override index position for this object - size_t overrideIndex = 0; - - ObjectAbstractNode *node = reinterpret_cast((*i).get()); - indices[node] = maxOverrideIndex; - overridden[node] = false; - - // special treatment for materials with * in their name - bool nodeHasWildcard=node->name.find('*') != String::npos; - - // Find the matching name node - for(size_t j = 0; j < overrides.size(); ++j) - { - ObjectAbstractNode *temp = reinterpret_cast(overrides[j].first.get()); - // Consider a match a node that has a wildcard and matches an input name - bool wildcardMatch = nodeHasWildcard && - (StringUtil::match(temp->name,node->name,true) || - (node->name.size() == 1 && temp->name.empty())); - if(temp->cls == node->cls && !node->name.empty() && (temp->name == node->name || wildcardMatch)) - { - // Pair these two together unless it's already paired - if(overrides[j].second == dest->children.end()) - { - AbstractNodeList::iterator currentIterator = i; - ObjectAbstractNode *currentNode = node; - if (wildcardMatch) - { - //If wildcard is matched, make a copy of current material and put it before the iterator, matching its name to the parent. Use same reinterpret cast as above when node is set - AbstractNodePtr newNode((*i)->clone()); - currentIterator = dest->children.insert(currentIterator, newNode); - currentNode = reinterpret_cast((*currentIterator).get()); - currentNode->name = temp->name;//make the regex match its matcher - } - overrides[j] = std::make_pair(overrides[j].first, currentIterator); - // Store the max override index for this matched pair - overrideIndex = j; - overrideIndex = maxOverrideIndex = std::max(overrideIndex, maxOverrideIndex); - indices[currentNode] = overrideIndex; - overridden[currentNode] = true; - } - else - { - addError(CE_DUPLICATEOVERRIDE, node->file, node->line); - } - - if(!wildcardMatch) - break; - } - } - - if (nodeHasWildcard) - { - //if the node has a wildcard it will be deleted since it was duplicated for every match - AbstractNodeList::iterator deletable=i++; - dest->children.erase(deletable); - } - else - { - ++i; //Behavior in absence of regex, just increment iterator - } - } - else - { - ++i; //Behavior in absence of replaceable object, just increment iterator to find another - } - } - - // Now make matches based on index - // Loop through destination children searching for name-matching overrides - for(AbstractNodeList::iterator i = dest->children.begin(); i != dest->children.end(); ++i) - { - if((*i)->type == ANT_OBJECT) - { - ObjectAbstractNode *node = reinterpret_cast((*i).get()); - if(!overridden[node]) - { - // Retrieve the minimum override index from the map - size_t overrideIndex = indices[node]; - - if(overrideIndex < overrides.size()) - { - // Search for minimum matching override - for(size_t j = overrideIndex; j < overrides.size(); ++j) - { - ObjectAbstractNode *temp = reinterpret_cast(overrides[j].first.get()); - if(temp->name.empty() && temp->cls == node->cls && overrides[j].second == dest->children.end()) - { - overrides[j] = std::make_pair(overrides[j].first, i); - break; - } - } - } - } - } - } - - // Loop through overrides, either inserting source nodes or overriding - insertPos = dest->children.begin(); - for(size_t i = 0; i < overrides.size(); ++i) - { - if(overrides[i].second != dest->children.end()) - { - // Override the destination with the source (base) object - overlayObject(overrides[i].first, - reinterpret_cast((*overrides[i].second).get())); - insertPos = overrides[i].second; - insertPos++; - } - else - { - // No override was possible, so insert this node at the insert position - // into the destination (child) object - AbstractNodePtr newNode(overrides[i].first->clone()); - newNode->parent = dest; - if(insertPos != dest->children.end()) - { - dest->children.insert(insertPos, newNode); - } - else - { - dest->children.push_back(newNode); - } - } - } - } - } - - bool ScriptCompiler::isNameExcluded(const String &cls, AbstractNode *parent) - { - // Run past the listener - bool excludeName = false; - ProcessNameExclusionScriptCompilerEvent evt(cls, parent); - bool processed = _fireEvent(&evt, (void*)&excludeName); - - if(!processed) - { - // Process the built-in name exclusions - if(cls == "emitter" || cls == "affector") - { - // emitters or affectors inside a particle_system are excluded - while(parent && parent->type == ANT_OBJECT) - { - ObjectAbstractNode *obj = reinterpret_cast(parent); - if(obj->cls == "particle_system") - return true; - parent = obj->parent; - } - return false; - } - else if(cls == "pass") - { - // passes inside compositors are excluded - while(parent && parent->type == ANT_OBJECT) - { - ObjectAbstractNode *obj = reinterpret_cast(parent); - if(obj->cls == "compositor") - return true; - parent = obj->parent; - } - return false; - } - else if(cls == "texture_source") - { - // Parent must be texture_unit - while(parent && parent->type == ANT_OBJECT) - { - ObjectAbstractNode *obj = reinterpret_cast(parent); - if(obj->cls == "texture_unit") - return true; - parent = obj->parent; - } - return false; - } - } - else - { - return excludeName; - } - return false; - } - - void ScriptCompiler::processVariables(Ogre::AbstractNodeList *nodes) - { - AbstractNodeList::iterator i = nodes->begin(); - while(i != nodes->end()) - { - AbstractNodeList::iterator cur = i; - ++i; - - if((*cur)->type == ANT_OBJECT) - { - // Only process if this object is not abstract - ObjectAbstractNode *obj = (ObjectAbstractNode*)(*cur).get(); - if(!obj->abstract) - { - processVariables(&obj->children); - processVariables(&obj->values); - } - } - else if((*cur)->type == ANT_PROPERTY) - { - PropertyAbstractNode *prop = (PropertyAbstractNode*)(*cur).get(); - processVariables(&prop->values); - } - else if((*cur)->type == ANT_VARIABLE_ACCESS) - { - VariableAccessAbstractNode *var = (VariableAccessAbstractNode*)(*cur).get(); - - // Look up the enclosing scope - ObjectAbstractNode *scope = 0; - AbstractNode *temp = var->parent; - while(temp) - { - if(temp->type == ANT_OBJECT) - { - scope = (ObjectAbstractNode*)temp; - break; - } - temp = temp->parent; - } - - // Look up the variable in the environment - std::pair varAccess; - if(scope) - varAccess = scope->getVariable(var->name); - if(!scope || !varAccess.first) - { - map::type::iterator k = mEnv.find(var->name); - varAccess.first = k != mEnv.end(); - if(varAccess.first) - varAccess.second = k->second; - } - - if(varAccess.first) - { - // Found the variable, so process it and insert it into the tree - ScriptLexer lexer; - ScriptTokenListPtr tokens = lexer.tokenize(varAccess.second, var->file); - ScriptParser parser; - ConcreteNodeListPtr cst = parser.parseChunk(tokens); - AbstractNodeListPtr ast = convertToAST(cst); - - // Set up ownership for these nodes - for(AbstractNodeList::iterator j = ast->begin(); j != ast->end(); ++j) - (*j)->parent = var->parent; - - // Recursively handle variable accesses within the variable expansion - processVariables(ast.get()); - - // Insert the nodes in place of the variable - nodes->insert(cur, ast->begin(), ast->end()); - } - else - { - // Error - addError(CE_UNDEFINEDVARIABLE, var->file, var->line); - } - - // Remove the variable node - nodes->erase(cur); - } - } - } - - void ScriptCompiler::initWordMap() - { - mIds["on"] = ID_ON; - mIds["off"] = ID_OFF; - mIds["true"] = ID_TRUE; - mIds["false"] = ID_FALSE; - mIds["yes"] = ID_YES; - mIds["no"] = ID_NO; - - // Material ids - mIds["material"] = ID_MATERIAL; - mIds["vertex_program"] = ID_VERTEX_PROGRAM; - mIds["geometry_program"] = ID_GEOMETRY_PROGRAM; - mIds["fragment_program"] = ID_FRAGMENT_PROGRAM; - mIds["tessellation_hull_program"] = ID_TESSELLATION_HULL_PROGRAM; - mIds["tessellation_domain_program"] = ID_TESSELLATION_DOMAIN_PROGRAM; - mIds["compute_program"] = ID_COMPUTE_PROGRAM; - mIds["technique"] = ID_TECHNIQUE; - mIds["pass"] = ID_PASS; - mIds["texture_unit"] = ID_TEXTURE_UNIT; - mIds["vertex_program_ref"] = ID_VERTEX_PROGRAM_REF; - mIds["geometry_program_ref"] = ID_GEOMETRY_PROGRAM_REF; - mIds["fragment_program_ref"] = ID_FRAGMENT_PROGRAM_REF; - mIds["tessellation_hull_program_ref"] = ID_TESSELLATION_HULL_PROGRAM_REF; - mIds["tessellation_domain_program_ref"] = ID_TESSELLATION_DOMAIN_PROGRAM_REF; - mIds["compute_program_ref"] = ID_COMPUTE_PROGRAM_REF; - mIds["shadow_caster_vertex_program_ref"] = ID_SHADOW_CASTER_VERTEX_PROGRAM_REF; - mIds["shadow_caster_fragment_program_ref"] = ID_SHADOW_CASTER_FRAGMENT_PROGRAM_REF; - mIds["shadow_receiver_vertex_program_ref"] = ID_SHADOW_RECEIVER_VERTEX_PROGRAM_REF; - mIds["shadow_receiver_fragment_program_ref"] = ID_SHADOW_RECEIVER_FRAGMENT_PROGRAM_REF; + } + + if (nodeHasWildcard) + { + //if the node has a wildcard it will be deleted since it was duplicated for every match + AbstractNodeList::iterator deletable=i++; + dest->children.erase(deletable); + } + else + { + ++i; //Behavior in absence of regex, just increment iterator + } + } + else + { + ++i; //Behavior in absence of replaceable object, just increment iterator to find another + } + } + + // Now make matches based on index + // Loop through destination children searching for name-matching overrides + for(AbstractNodeList::iterator i = dest->children.begin(); i != dest->children.end(); ++i) + { + if((*i)->type == ANT_OBJECT) + { + ObjectAbstractNode *node = reinterpret_cast((*i).get()); + if(!overridden[node]) + { + // Retrieve the minimum override index from the map + size_t overrideIndex = indices[node]; + + if(overrideIndex < overrides.size()) + { + // Search for minimum matching override + for(size_t j = overrideIndex; j < overrides.size(); ++j) + { + ObjectAbstractNode *temp = reinterpret_cast(overrides[j].first.get()); + if(temp->name.empty() && temp->cls == node->cls && overrides[j].second == dest->children.end()) + { + overrides[j] = std::make_pair(overrides[j].first, i); + break; + } + } + } + } + } + } + + // Loop through overrides, either inserting source nodes or overriding + insertPos = dest->children.begin(); + for(size_t i = 0; i < overrides.size(); ++i) + { + if(overrides[i].second != dest->children.end()) + { + // Override the destination with the source (base) object + overlayObject(overrides[i].first, + reinterpret_cast((*overrides[i].second).get())); + insertPos = overrides[i].second; + insertPos++; + } + else + { + // No override was possible, so insert this node at the insert position + // into the destination (child) object + AbstractNodePtr newNode(overrides[i].first->clone()); + newNode->parent = dest; + if(insertPos != dest->children.end()) + { + dest->children.insert(insertPos, newNode); + } + else + { + dest->children.push_back(newNode); + } + } + } + } + } + + bool ScriptCompiler::isNameExcluded(const String &cls, AbstractNode *parent) + { + // Run past the listener + bool excludeName = false; + ProcessNameExclusionScriptCompilerEvent evt(cls, parent); + bool processed = _fireEvent(&evt, (void*)&excludeName); + + if(!processed) + { + // Process the built-in name exclusions + if(cls == "emitter" || cls == "affector") + { + // emitters or affectors inside a particle_system are excluded + while(parent && parent->type == ANT_OBJECT) + { + ObjectAbstractNode *obj = reinterpret_cast(parent); + if(obj->cls == "particle_system") + return true; + parent = obj->parent; + } + return false; + } + else if(cls == "pass") + { + // passes inside compositors are excluded + while(parent && parent->type == ANT_OBJECT) + { + ObjectAbstractNode *obj = reinterpret_cast(parent); + if(obj->cls == "compositor") + return true; + parent = obj->parent; + } + return false; + } + else if(cls == "texture_source") + { + // Parent must be texture_unit + while(parent && parent->type == ANT_OBJECT) + { + ObjectAbstractNode *obj = reinterpret_cast(parent); + if(obj->cls == "texture_unit") + return true; + parent = obj->parent; + } + return false; + } + } + else + { + return excludeName; + } + return false; + } + + void ScriptCompiler::processVariables(Ogre::AbstractNodeList *nodes) + { + AbstractNodeList::iterator i = nodes->begin(); + while(i != nodes->end()) + { + AbstractNodeList::iterator cur = i; + ++i; + + if((*cur)->type == ANT_OBJECT) + { + // Only process if this object is not abstract + ObjectAbstractNode *obj = (ObjectAbstractNode*)(*cur).get(); + if(!obj->abstract) + { + processVariables(&obj->children); + processVariables(&obj->values); + } + } + else if((*cur)->type == ANT_PROPERTY) + { + PropertyAbstractNode *prop = (PropertyAbstractNode*)(*cur).get(); + processVariables(&prop->values); + } + else if((*cur)->type == ANT_VARIABLE_ACCESS) + { + VariableAccessAbstractNode *var = (VariableAccessAbstractNode*)(*cur).get(); + + // Look up the enclosing scope + ObjectAbstractNode *scope = 0; + AbstractNode *temp = var->parent; + while(temp) + { + if(temp->type == ANT_OBJECT) + { + scope = (ObjectAbstractNode*)temp; + break; + } + temp = temp->parent; + } + + // Look up the variable in the environment + std::pair varAccess; + if(scope) + varAccess = scope->getVariable(var->name); + if(!scope || !varAccess.first) + { + map::type::iterator k = mEnv.find(var->name); + varAccess.first = k != mEnv.end(); + if(varAccess.first) + varAccess.second = k->second; + } + + if(varAccess.first) + { + // Found the variable, so process it and insert it into the tree + ScriptLexer lexer; + ScriptTokenListPtr tokens = lexer.tokenize(varAccess.second, var->file); + ScriptParser parser; + ConcreteNodeListPtr cst = parser.parseChunk(tokens); + AbstractNodeListPtr ast = convertToAST(cst); + + // Set up ownership for these nodes + for(AbstractNodeList::iterator j = ast->begin(); j != ast->end(); ++j) + (*j)->parent = var->parent; + + // Recursively handle variable accesses within the variable expansion + processVariables(ast.get()); + + // Insert the nodes in place of the variable + nodes->insert(cur, ast->begin(), ast->end()); + } + else + { + // Error + addError(CE_UNDEFINEDVARIABLE, var->file, var->line); + } + + // Remove the variable node + nodes->erase(cur); + } + } + } + + void ScriptCompiler::initWordMap() + { + mIds["on"] = ID_ON; + mIds["off"] = ID_OFF; + mIds["true"] = ID_TRUE; + mIds["false"] = ID_FALSE; + mIds["yes"] = ID_YES; + mIds["no"] = ID_NO; + + // Material ids + mIds["material"] = ID_MATERIAL; + mIds["vertex_program"] = ID_VERTEX_PROGRAM; + mIds["geometry_program"] = ID_GEOMETRY_PROGRAM; + mIds["fragment_program"] = ID_FRAGMENT_PROGRAM; + mIds["tessellation_hull_program"] = ID_TESSELLATION_HULL_PROGRAM; + mIds["tessellation_domain_program"] = ID_TESSELLATION_DOMAIN_PROGRAM; + mIds["compute_program"] = ID_COMPUTE_PROGRAM; + mIds["technique"] = ID_TECHNIQUE; + mIds["pass"] = ID_PASS; + mIds["texture_unit"] = ID_TEXTURE_UNIT; + mIds["vertex_program_ref"] = ID_VERTEX_PROGRAM_REF; + mIds["geometry_program_ref"] = ID_GEOMETRY_PROGRAM_REF; + mIds["fragment_program_ref"] = ID_FRAGMENT_PROGRAM_REF; + mIds["tessellation_hull_program_ref"] = ID_TESSELLATION_HULL_PROGRAM_REF; + mIds["tessellation_domain_program_ref"] = ID_TESSELLATION_DOMAIN_PROGRAM_REF; + mIds["compute_program_ref"] = ID_COMPUTE_PROGRAM_REF; + mIds["shadow_caster_vertex_program_ref"] = ID_SHADOW_CASTER_VERTEX_PROGRAM_REF; + mIds["shadow_caster_fragment_program_ref"] = ID_SHADOW_CASTER_FRAGMENT_PROGRAM_REF; + mIds["shadow_receiver_vertex_program_ref"] = ID_SHADOW_RECEIVER_VERTEX_PROGRAM_REF; + mIds["shadow_receiver_fragment_program_ref"] = ID_SHADOW_RECEIVER_FRAGMENT_PROGRAM_REF; mIds["lod_values"] = ID_LOD_VALUES; mIds["lod_strategy"] = ID_LOD_STRATEGY; - mIds["lod_distances"] = ID_LOD_DISTANCES; - mIds["receive_shadows"] = ID_RECEIVE_SHADOWS; - mIds["transparency_casts_shadows"] = ID_TRANSPARENCY_CASTS_SHADOWS; - mIds["set_texture_alias"] = ID_SET_TEXTURE_ALIAS; - - mIds["source"] = ID_SOURCE; - mIds["syntax"] = ID_SYNTAX; - mIds["default_params"] = ID_DEFAULT_PARAMS; - mIds["param_indexed"] = ID_PARAM_INDEXED; - mIds["param_named"] = ID_PARAM_NAMED; - mIds["param_indexed_auto"] = ID_PARAM_INDEXED_AUTO; - mIds["param_named_auto"] = ID_PARAM_NAMED_AUTO; - - mIds["scheme"] = ID_SCHEME; - mIds["lod_index"] = ID_LOD_INDEX; - mIds["shadow_caster_material"] = ID_SHADOW_CASTER_MATERIAL; - mIds["shadow_receiver_material"] = ID_SHADOW_RECEIVER_MATERIAL; - mIds["gpu_vendor_rule"] = ID_GPU_VENDOR_RULE; - mIds["gpu_device_rule"] = ID_GPU_DEVICE_RULE; - mIds["include"] = ID_INCLUDE; - mIds["exclude"] = ID_EXCLUDE; - - mIds["ambient"] = ID_AMBIENT; - mIds["diffuse"] = ID_DIFFUSE; - mIds["specular"] = ID_SPECULAR; - mIds["emissive"] = ID_EMISSIVE; + mIds["lod_distances"] = ID_LOD_DISTANCES; + mIds["receive_shadows"] = ID_RECEIVE_SHADOWS; + mIds["transparency_casts_shadows"] = ID_TRANSPARENCY_CASTS_SHADOWS; + mIds["set_texture_alias"] = ID_SET_TEXTURE_ALIAS; + + mIds["source"] = ID_SOURCE; + mIds["syntax"] = ID_SYNTAX; + mIds["default_params"] = ID_DEFAULT_PARAMS; + mIds["param_indexed"] = ID_PARAM_INDEXED; + mIds["param_named"] = ID_PARAM_NAMED; + mIds["param_indexed_auto"] = ID_PARAM_INDEXED_AUTO; + mIds["param_named_auto"] = ID_PARAM_NAMED_AUTO; + + mIds["scheme"] = ID_SCHEME; + mIds["lod_index"] = ID_LOD_INDEX; + mIds["shadow_caster_material"] = ID_SHADOW_CASTER_MATERIAL; + mIds["shadow_receiver_material"] = ID_SHADOW_RECEIVER_MATERIAL; + mIds["gpu_vendor_rule"] = ID_GPU_VENDOR_RULE; + mIds["gpu_device_rule"] = ID_GPU_DEVICE_RULE; + mIds["include"] = ID_INCLUDE; + mIds["exclude"] = ID_EXCLUDE; + + mIds["ambient"] = ID_AMBIENT; + mIds["diffuse"] = ID_DIFFUSE; + mIds["specular"] = ID_SPECULAR; + mIds["emissive"] = ID_EMISSIVE; mIds["vertexcolour"] = ID_VERTEXCOLOUR; - mIds["scene_blend"] = ID_SCENE_BLEND; - mIds["colour_blend"] = ID_COLOUR_BLEND; + mIds["scene_blend"] = ID_SCENE_BLEND; + mIds["colour_blend"] = ID_COLOUR_BLEND; mIds["one"] = ID_ONE; mIds["zero"] = ID_ZERO; mIds["dest_colour"] = ID_DEST_COLOUR; @@ -1052,17 +1052,17 @@ namespace Ogre mIds["src_alpha"] = ID_SRC_ALPHA; mIds["one_minus_dest_alpha"] = ID_ONE_MINUS_DEST_ALPHA; mIds["one_minus_src_alpha"] = ID_ONE_MINUS_SRC_ALPHA; - mIds["separate_scene_blend"] = ID_SEPARATE_SCENE_BLEND; - mIds["scene_blend_op"] = ID_SCENE_BLEND_OP; + mIds["separate_scene_blend"] = ID_SEPARATE_SCENE_BLEND; + mIds["scene_blend_op"] = ID_SCENE_BLEND_OP; mIds["reverse_subtract"] = ID_REVERSE_SUBTRACT; mIds["min"] = ID_MIN; mIds["max"] = ID_MAX; - mIds["separate_scene_blend_op"] = ID_SEPARATE_SCENE_BLEND_OP; - mIds["depth_check"] = ID_DEPTH_CHECK; - mIds["depth_write"] = ID_DEPTH_WRITE; - mIds["depth_func"] = ID_DEPTH_FUNC; - mIds["depth_bias"] = ID_DEPTH_BIAS; - mIds["iteration_depth_bias"] = ID_ITERATION_DEPTH_BIAS; + mIds["separate_scene_blend_op"] = ID_SEPARATE_SCENE_BLEND_OP; + mIds["depth_check"] = ID_DEPTH_CHECK; + mIds["depth_write"] = ID_DEPTH_WRITE; + mIds["depth_func"] = ID_DEPTH_FUNC; + mIds["depth_bias"] = ID_DEPTH_BIAS; + mIds["iteration_depth_bias"] = ID_ITERATION_DEPTH_BIAS; mIds["always_fail"] = ID_ALWAYS_FAIL; mIds["always_pass"] = ID_ALWAYS_PASS; mIds["less_equal"] = ID_LESS_EQUAL; @@ -1071,39 +1071,39 @@ namespace Ogre mIds["not_equal"] = ID_NOT_EQUAL; mIds["greater_equal"] = ID_GREATER_EQUAL; mIds["greater"] = ID_GREATER; - mIds["alpha_rejection"] = ID_ALPHA_REJECTION; - mIds["alpha_to_coverage"] = ID_ALPHA_TO_COVERAGE; - mIds["light_scissor"] = ID_LIGHT_SCISSOR; - mIds["light_clip_planes"] = ID_LIGHT_CLIP_PLANES; - mIds["transparent_sorting"] = ID_TRANSPARENT_SORTING; - mIds["illumination_stage"] = ID_ILLUMINATION_STAGE; + mIds["alpha_rejection"] = ID_ALPHA_REJECTION; + mIds["alpha_to_coverage"] = ID_ALPHA_TO_COVERAGE; + mIds["light_scissor"] = ID_LIGHT_SCISSOR; + mIds["light_clip_planes"] = ID_LIGHT_CLIP_PLANES; + mIds["transparent_sorting"] = ID_TRANSPARENT_SORTING; + mIds["illumination_stage"] = ID_ILLUMINATION_STAGE; mIds["decal"] = ID_DECAL; - mIds["cull_hardware"] = ID_CULL_HARDWARE; + mIds["cull_hardware"] = ID_CULL_HARDWARE; mIds["clockwise"] = ID_CLOCKWISE; mIds["anticlockwise"] = ID_ANTICLOCKWISE; - mIds["cull_software"] = ID_CULL_SOFTWARE; + mIds["cull_software"] = ID_CULL_SOFTWARE; mIds["back"] = ID_BACK; mIds["front"] = ID_FRONT; - mIds["normalise_normals"] = ID_NORMALISE_NORMALS; - mIds["lighting"] = ID_LIGHTING; - mIds["shading"] = ID_SHADING; + mIds["normalise_normals"] = ID_NORMALISE_NORMALS; + mIds["lighting"] = ID_LIGHTING; + mIds["shading"] = ID_SHADING; mIds["flat"] = ID_FLAT; mIds["gouraud"] = ID_GOURAUD; mIds["phong"] = ID_PHONG; - mIds["polygon_mode"] = ID_POLYGON_MODE; + mIds["polygon_mode"] = ID_POLYGON_MODE; mIds["solid"] = ID_SOLID; mIds["wireframe"] = ID_WIREFRAME; mIds["points"] = ID_POINTS; - mIds["polygon_mode_overrideable"] = ID_POLYGON_MODE_OVERRIDEABLE; - mIds["fog_override"] = ID_FOG_OVERRIDE; + mIds["polygon_mode_overrideable"] = ID_POLYGON_MODE_OVERRIDEABLE; + mIds["fog_override"] = ID_FOG_OVERRIDE; mIds["none"] = ID_NONE; mIds["linear"] = ID_LINEAR; mIds["exp"] = ID_EXP; mIds["exp2"] = ID_EXP2; - mIds["colour_write"] = ID_COLOUR_WRITE; - mIds["max_lights"] = ID_MAX_LIGHTS; - mIds["start_light"] = ID_START_LIGHT; - mIds["iteration"] = ID_ITERATION; + mIds["colour_write"] = ID_COLOUR_WRITE; + mIds["max_lights"] = ID_MAX_LIGHTS; + mIds["start_light"] = ID_START_LIGHT; + mIds["iteration"] = ID_ITERATION; mIds["once"] = ID_ONCE; mIds["once_per_light"] = ID_ONCE_PER_LIGHT; mIds["per_n_lights"] = ID_PER_N_LIGHTS; @@ -1111,48 +1111,48 @@ namespace Ogre mIds["point"] = ID_POINT; mIds["spot"] = ID_SPOT; mIds["directional"] = ID_DIRECTIONAL; - mIds["light_mask"] = ID_LIGHT_MASK; - mIds["point_size"] = ID_POINT_SIZE; - mIds["point_sprites"] = ID_POINT_SPRITES; - mIds["point_size_min"] = ID_POINT_SIZE_MIN; - mIds["point_size_max"] = ID_POINT_SIZE_MAX; - mIds["point_size_attenuation"] = ID_POINT_SIZE_ATTENUATION; - - mIds["texture_alias"] = ID_TEXTURE_ALIAS; - mIds["texture"] = ID_TEXTURE; + mIds["light_mask"] = ID_LIGHT_MASK; + mIds["point_size"] = ID_POINT_SIZE; + mIds["point_sprites"] = ID_POINT_SPRITES; + mIds["point_size_min"] = ID_POINT_SIZE_MIN; + mIds["point_size_max"] = ID_POINT_SIZE_MAX; + mIds["point_size_attenuation"] = ID_POINT_SIZE_ATTENUATION; + + mIds["texture_alias"] = ID_TEXTURE_ALIAS; + mIds["texture"] = ID_TEXTURE; mIds["1d"] = ID_1D; mIds["2d"] = ID_2D; mIds["3d"] = ID_3D; mIds["cubic"] = ID_CUBIC; mIds["unlimited"] = ID_UNLIMITED; - mIds["2darray"] = ID_2DARRAY; + mIds["2darray"] = ID_2DARRAY; mIds["alpha"] = ID_ALPHA; mIds["gamma"] = ID_GAMMA; - mIds["anim_texture"] = ID_ANIM_TEXTURE; - mIds["cubic_texture"] = ID_CUBIC_TEXTURE; + mIds["anim_texture"] = ID_ANIM_TEXTURE; + mIds["cubic_texture"] = ID_CUBIC_TEXTURE; mIds["separateUV"] = ID_SEPARATE_UV; mIds["combinedUVW"] = ID_COMBINED_UVW; - mIds["tex_coord_set"] = ID_TEX_COORD_SET; - mIds["tex_address_mode"] = ID_TEX_ADDRESS_MODE; + mIds["tex_coord_set"] = ID_TEX_COORD_SET; + mIds["tex_address_mode"] = ID_TEX_ADDRESS_MODE; mIds["wrap"] = ID_WRAP; mIds["clamp"] = ID_CLAMP; mIds["mirror"] = ID_MIRROR; mIds["border"] = ID_BORDER; - mIds["tex_border_colour"] = ID_TEX_BORDER_COLOUR; - mIds["filtering"] = ID_FILTERING; + mIds["tex_border_colour"] = ID_TEX_BORDER_COLOUR; + mIds["filtering"] = ID_FILTERING; mIds["bilinear"] = ID_BILINEAR; mIds["trilinear"] = ID_TRILINEAR; mIds["anisotropic"] = ID_ANISOTROPIC; - mIds["compare_test"] = ID_CMPTEST; - mIds["compare_func"] = ID_CMPFUNC; - mIds["max_anisotropy"] = ID_MAX_ANISOTROPY; - mIds["mipmap_bias"] = ID_MIPMAP_BIAS; - mIds["colour_op"] = ID_COLOUR_OP; + mIds["compare_test"] = ID_CMPTEST; + mIds["compare_func"] = ID_CMPFUNC; + mIds["max_anisotropy"] = ID_MAX_ANISOTROPY; + mIds["mipmap_bias"] = ID_MIPMAP_BIAS; + mIds["colour_op"] = ID_COLOUR_OP; mIds["replace"] = ID_REPLACE; mIds["add"] = ID_ADD; mIds["modulate"] = ID_MODULATE; mIds["alpha_blend"] = ID_ALPHA_BLEND; - mIds["colour_op_ex"] = ID_COLOUR_OP_EX; + mIds["colour_op_ex"] = ID_COLOUR_OP_EX; mIds["source1"] = ID_SOURCE1; mIds["source2"] = ID_SOURCE2; mIds["modulate"] = ID_MODULATE; @@ -1173,19 +1173,19 @@ namespace Ogre mIds["src_diffuse"] = ID_SRC_DIFFUSE; mIds["src_specular"] = ID_SRC_SPECULAR; mIds["src_manual"] = ID_SRC_MANUAL; - mIds["colour_op_multipass_fallback"] = ID_COLOUR_OP_MULTIPASS_FALLBACK; - mIds["alpha_op_ex"] = ID_ALPHA_OP_EX; - mIds["env_map"] = ID_ENV_MAP; + mIds["colour_op_multipass_fallback"] = ID_COLOUR_OP_MULTIPASS_FALLBACK; + mIds["alpha_op_ex"] = ID_ALPHA_OP_EX; + mIds["env_map"] = ID_ENV_MAP; mIds["spherical"] = ID_SPHERICAL; mIds["planar"] = ID_PLANAR; mIds["cubic_reflection"] = ID_CUBIC_REFLECTION; mIds["cubic_normal"] = ID_CUBIC_NORMAL; - mIds["scroll"] = ID_SCROLL; - mIds["scroll_anim"] = ID_SCROLL_ANIM; - mIds["rotate"] = ID_ROTATE; - mIds["rotate_anim"] = ID_ROTATE_ANIM; - mIds["scale"] = ID_SCALE; - mIds["wave_xform"] = ID_WAVE_XFORM; + mIds["scroll"] = ID_SCROLL; + mIds["scroll_anim"] = ID_SCROLL_ANIM; + mIds["rotate"] = ID_ROTATE; + mIds["rotate_anim"] = ID_ROTATE_ANIM; + mIds["scale"] = ID_SCALE; + mIds["wave_xform"] = ID_WAVE_XFORM; mIds["scroll_x"] = ID_SCROLL_X; mIds["scroll_y"] = ID_SCROLL_Y; mIds["scale_x"] = ID_SCALE_X; @@ -1195,33 +1195,33 @@ namespace Ogre mIds["sawtooth"] = ID_SAWTOOTH; mIds["square"] = ID_SQUARE; mIds["inverse_sawtooth"] = ID_INVERSE_SAWTOOTH; - mIds["transform"] = ID_TRANSFORM; - mIds["binding_type"] = ID_BINDING_TYPE; + mIds["transform"] = ID_TRANSFORM; + mIds["binding_type"] = ID_BINDING_TYPE; mIds["vertex"] = ID_VERTEX; mIds["fragment"] = ID_FRAGMENT; - mIds["geometry"] = ID_GEOMETRY; - mIds["tessellation_hull"] = ID_TESSELLATION_HULL; - mIds["tessellation_domain"] = ID_TESSELLATION_DOMAIN; - mIds["compute"] = ID_COMPUTE; - mIds["content_type"] = ID_CONTENT_TYPE; + mIds["geometry"] = ID_GEOMETRY; + mIds["tessellation_hull"] = ID_TESSELLATION_HULL; + mIds["tessellation_domain"] = ID_TESSELLATION_DOMAIN; + mIds["compute"] = ID_COMPUTE; + mIds["content_type"] = ID_CONTENT_TYPE; mIds["named"] = ID_NAMED; mIds["shadow"] = ID_SHADOW; - mIds["texture_source"] = ID_TEXTURE_SOURCE; - mIds["shared_params"] = ID_SHARED_PARAMS; - mIds["shared_param_named"] = ID_SHARED_PARAM_NAMED; - mIds["shared_params_ref"] = ID_SHARED_PARAMS_REF; - - // Particle system - mIds["particle_system"] = ID_PARTICLE_SYSTEM; - mIds["emitter"] = ID_EMITTER; - mIds["affector"] = ID_AFFECTOR; - - // Compositor - mIds["compositor"] = ID_COMPOSITOR; - mIds["target"] = ID_TARGET; - mIds["target_output"] = ID_TARGET_OUTPUT; - - mIds["input"] = ID_INPUT; + mIds["texture_source"] = ID_TEXTURE_SOURCE; + mIds["shared_params"] = ID_SHARED_PARAMS; + mIds["shared_param_named"] = ID_SHARED_PARAM_NAMED; + mIds["shared_params_ref"] = ID_SHARED_PARAMS_REF; + + // Particle system + mIds["particle_system"] = ID_PARTICLE_SYSTEM; + mIds["emitter"] = ID_EMITTER; + mIds["affector"] = ID_AFFECTOR; + + // Compositor + mIds["compositor"] = ID_COMPOSITOR; + mIds["target"] = ID_TARGET; + mIds["target_output"] = ID_TARGET_OUTPUT; + + mIds["input"] = ID_INPUT; mIds["none"] = ID_NONE; mIds["previous"] = ID_PREVIOUS; mIds["target_width"] = ID_TARGET_WIDTH; @@ -1233,422 +1233,422 @@ namespace Ogre mIds["no_fsaa"] = ID_NO_FSAA; mIds["depth_pool"] = ID_DEPTH_POOL; - mIds["texture_ref"] = ID_TEXTURE_REF; - mIds["local_scope"] = ID_SCOPE_LOCAL; - mIds["chain_scope"] = ID_SCOPE_CHAIN; - mIds["global_scope"] = ID_SCOPE_GLOBAL; - mIds["compositor_logic"] = ID_COMPOSITOR_LOGIC; - - mIds["only_initial"] = ID_ONLY_INITIAL; - mIds["visibility_mask"] = ID_VISIBILITY_MASK; - mIds["lod_bias"] = ID_LOD_BIAS; - mIds["material_scheme"] = ID_MATERIAL_SCHEME; - mIds["shadows"] = ID_SHADOWS_ENABLED; - - mIds["clear"] = ID_CLEAR; - mIds["stencil"] = ID_STENCIL; - mIds["render_scene"] = ID_RENDER_SCENE; - mIds["render_quad"] = ID_RENDER_QUAD; - mIds["identifier"] = ID_IDENTIFIER; - mIds["first_render_queue"] = ID_FIRST_RENDER_QUEUE; - mIds["last_render_queue"] = ID_LAST_RENDER_QUEUE; - mIds["quad_normals"] = ID_QUAD_NORMALS; + mIds["texture_ref"] = ID_TEXTURE_REF; + mIds["local_scope"] = ID_SCOPE_LOCAL; + mIds["chain_scope"] = ID_SCOPE_CHAIN; + mIds["global_scope"] = ID_SCOPE_GLOBAL; + mIds["compositor_logic"] = ID_COMPOSITOR_LOGIC; + + mIds["only_initial"] = ID_ONLY_INITIAL; + mIds["visibility_mask"] = ID_VISIBILITY_MASK; + mIds["lod_bias"] = ID_LOD_BIAS; + mIds["material_scheme"] = ID_MATERIAL_SCHEME; + mIds["shadows"] = ID_SHADOWS_ENABLED; + + mIds["clear"] = ID_CLEAR; + mIds["stencil"] = ID_STENCIL; + mIds["render_scene"] = ID_RENDER_SCENE; + mIds["render_quad"] = ID_RENDER_QUAD; + mIds["identifier"] = ID_IDENTIFIER; + mIds["first_render_queue"] = ID_FIRST_RENDER_QUEUE; + mIds["last_render_queue"] = ID_LAST_RENDER_QUEUE; + mIds["quad_normals"] = ID_QUAD_NORMALS; mIds["camera_far_corners_view_space"] = ID_CAMERA_FAR_CORNERS_VIEW_SPACE; mIds["camera_far_corners_world_space"] = ID_CAMERA_FAR_CORNERS_WORLD_SPACE; - mIds["buffers"] = ID_BUFFERS; + mIds["buffers"] = ID_BUFFERS; mIds["colour"] = ID_COLOUR; mIds["depth"] = ID_DEPTH; - mIds["colour_value"] = ID_COLOUR_VALUE; - mIds["depth_value"] = ID_DEPTH_VALUE; - mIds["stencil_value"] = ID_STENCIL_VALUE; - - mIds["check"] = ID_CHECK; - mIds["comp_func"] = ID_COMP_FUNC; - mIds["ref_value"] = ID_REF_VALUE; - mIds["mask"] = ID_MASK; - mIds["fail_op"] = ID_FAIL_OP; + mIds["colour_value"] = ID_COLOUR_VALUE; + mIds["depth_value"] = ID_DEPTH_VALUE; + mIds["stencil_value"] = ID_STENCIL_VALUE; + + mIds["check"] = ID_CHECK; + mIds["comp_func"] = ID_COMP_FUNC; + mIds["ref_value"] = ID_REF_VALUE; + mIds["mask"] = ID_MASK; + mIds["fail_op"] = ID_FAIL_OP; mIds["keep"] = ID_KEEP; mIds["increment"] = ID_INCREMENT; mIds["decrement"] = ID_DECREMENT; mIds["increment_wrap"] = ID_INCREMENT_WRAP; mIds["decrement_wrap"] = ID_DECREMENT_WRAP; mIds["invert"] = ID_INVERT; - mIds["depth_fail_op"] = ID_DEPTH_FAIL_OP; - mIds["pass_op"] = ID_PASS_OP; - mIds["two_sided"] = ID_TWO_SIDED; - mIds["read_back_as_texture"] = ID_READ_BACK_AS_TEXTURE; + mIds["depth_fail_op"] = ID_DEPTH_FAIL_OP; + mIds["pass_op"] = ID_PASS_OP; + mIds["two_sided"] = ID_TWO_SIDED; + mIds["read_back_as_texture"] = ID_READ_BACK_AS_TEXTURE; #ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS - mIds["rtshader_system"] = ID_RT_SHADER_SYSTEM; + mIds["rtshader_system"] = ID_RT_SHADER_SYSTEM; #endif - mIds["subroutine"] = ID_SUBROUTINE; - } - - // AbstractTreeeBuilder - ScriptCompiler::AbstractTreeBuilder::AbstractTreeBuilder(ScriptCompiler *compiler) - :mNodes(OGRE_NEW_T(AbstractNodeList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T), mCurrent(0), mCompiler(compiler) - { - } - - const AbstractNodeListPtr &ScriptCompiler::AbstractTreeBuilder::getResult() const - { - return mNodes; - } - - void ScriptCompiler::AbstractTreeBuilder::visit(ConcreteNode *node) - { - AbstractNodePtr asn; - - // Import = "import" >> 2 children, mCurrent == null - if(node->type == CNT_IMPORT && mCurrent == 0) - { - if(node->children.size() > 2) - { - mCompiler->addError(CE_FEWERPARAMETERSEXPECTED, node->file, node->line); - return; - } - if(node->children.size() < 2) - { - mCompiler->addError(CE_STRINGEXPECTED, node->file, node->line); - return; - } - - ImportAbstractNode *impl = OGRE_NEW ImportAbstractNode(); - impl->line = node->line; - impl->file = node->file; - - ConcreteNodeList::iterator iter = node->children.begin(); - impl->target = (*iter)->token; - - iter++; - impl->source = (*iter)->token; - - asn = AbstractNodePtr(impl); - } - // variable set = "set" >> 2 children, children[0] == variable - else if(node->type == CNT_VARIABLE_ASSIGN) - { - if(node->children.size() > 2) - { - mCompiler->addError(CE_FEWERPARAMETERSEXPECTED, node->file, node->line); - return; - } - if(node->children.size() < 2) - { - mCompiler->addError(CE_STRINGEXPECTED, node->file, node->line); - return; - } - if(node->children.front()->type != CNT_VARIABLE) - { - mCompiler->addError(CE_VARIABLEEXPECTED, node->children.front()->file, node->children.front()->line); - return; - } - - ConcreteNodeList::iterator i = node->children.begin(); - String name = (*i)->token; - - ++i; - String value = (*i)->token; - - if(mCurrent && mCurrent->type == ANT_OBJECT) - { - ObjectAbstractNode *ptr = (ObjectAbstractNode*)mCurrent; - ptr->setVariable(name, value); - } - else - { - mCompiler->mEnv.insert(std::make_pair(name, value)); - } - } - // variable = $*, no children - else if(node->type == CNT_VARIABLE) - { - if(!node->children.empty()) - { - mCompiler->addError(CE_FEWERPARAMETERSEXPECTED, node->file, node->line); - return; - } - - VariableAccessAbstractNode *impl = OGRE_NEW VariableAccessAbstractNode(mCurrent); - impl->line = node->line; - impl->file = node->file; - impl->name = node->token; - - asn = AbstractNodePtr(impl); - } - // Handle properties and objects here - else if(!node->children.empty()) - { - // Grab the last two nodes - ConcreteNodePtr temp1, temp2; - ConcreteNodeList::reverse_iterator riter = node->children.rbegin(); - if(riter != node->children.rend()) - { - temp1 = *riter; - riter++; - } - if(riter != node->children.rend()) - temp2 = *riter; - - // object = last 2 children == { and } - if(!temp1.isNull() && !temp2.isNull() && - temp1->type == CNT_RBRACE && temp2->type == CNT_LBRACE) - { - if(node->children.size() < 2) - { - mCompiler->addError(CE_STRINGEXPECTED, node->file, node->line); - return; - } - - ObjectAbstractNode *impl = OGRE_NEW ObjectAbstractNode(mCurrent); - impl->line = node->line; - impl->file = node->file; - impl->abstract = false; - - // Create a temporary detail list - list::type temp; - if(node->token == "abstract") - { - impl->abstract = true; - for(ConcreteNodeList::const_iterator i = node->children.begin(); i != node->children.end(); ++i) - temp.push_back((*i).get()); - } - else - { - temp.push_back(node); - for(ConcreteNodeList::const_iterator i = node->children.begin(); i != node->children.end(); ++i) - temp.push_back((*i).get()); - } - - // Get the type of object - list::type::const_iterator iter = temp.begin(); - impl->cls = (*iter)->token; - ++iter; - - // Get the name - // Unless the type is in the exclusion list - if(iter != temp.end() && ((*iter)->type == CNT_WORD || (*iter)->type == CNT_QUOTE) && - !mCompiler->isNameExcluded(impl->cls, mCurrent)) - { - impl->name = (*iter)->token; - ++iter; - } - - // Everything up until the colon is a "value" of this object - while(iter != temp.end() && (*iter)->type != CNT_COLON && (*iter)->type != CNT_LBRACE) - { - if((*iter)->type == CNT_VARIABLE) - { - VariableAccessAbstractNode *var = OGRE_NEW VariableAccessAbstractNode(impl); - var->file = (*iter)->file; - var->line = (*iter)->line; - var->type = ANT_VARIABLE_ACCESS; - var->name = (*iter)->token; - impl->values.push_back(AbstractNodePtr(var)); - } - else - { - AtomAbstractNode *atom = OGRE_NEW AtomAbstractNode(impl); - atom->file = (*iter)->file; - atom->line = (*iter)->line; - atom->type = ANT_ATOM; - atom->value = (*iter)->token; - impl->values.push_back(AbstractNodePtr(atom)); - } - ++iter; - } - - // Find the bases - if(iter != temp.end() && (*iter)->type == CNT_COLON) - { - // Children of the ':' are bases - for(ConcreteNodeList::iterator j = (*iter)->children.begin(); j != (*iter)->children.end(); ++j) - impl->bases.push_back((*j)->token); + mIds["subroutine"] = ID_SUBROUTINE; + } + + // AbstractTreeeBuilder + ScriptCompiler::AbstractTreeBuilder::AbstractTreeBuilder(ScriptCompiler *compiler) + :mNodes(OGRE_NEW_T(AbstractNodeList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T), mCurrent(0), mCompiler(compiler) + { + } + + const AbstractNodeListPtr &ScriptCompiler::AbstractTreeBuilder::getResult() const + { + return mNodes; + } + + void ScriptCompiler::AbstractTreeBuilder::visit(ConcreteNode *node) + { + AbstractNodePtr asn; + + // Import = "import" >> 2 children, mCurrent == null + if(node->type == CNT_IMPORT && mCurrent == 0) + { + if(node->children.size() > 2) + { + mCompiler->addError(CE_FEWERPARAMETERSEXPECTED, node->file, node->line); + return; + } + if(node->children.size() < 2) + { + mCompiler->addError(CE_STRINGEXPECTED, node->file, node->line); + return; + } + + ImportAbstractNode *impl = OGRE_NEW ImportAbstractNode(); + impl->line = node->line; + impl->file = node->file; + + ConcreteNodeList::iterator iter = node->children.begin(); + impl->target = (*iter)->token; + + iter++; + impl->source = (*iter)->token; + + asn = AbstractNodePtr(impl); + } + // variable set = "set" >> 2 children, children[0] == variable + else if(node->type == CNT_VARIABLE_ASSIGN) + { + if(node->children.size() > 2) + { + mCompiler->addError(CE_FEWERPARAMETERSEXPECTED, node->file, node->line); + return; + } + if(node->children.size() < 2) + { + mCompiler->addError(CE_STRINGEXPECTED, node->file, node->line); + return; + } + if(node->children.front()->type != CNT_VARIABLE) + { + mCompiler->addError(CE_VARIABLEEXPECTED, node->children.front()->file, node->children.front()->line); + return; + } + + ConcreteNodeList::iterator i = node->children.begin(); + String name = (*i)->token; + + ++i; + String value = (*i)->token; + + if(mCurrent && mCurrent->type == ANT_OBJECT) + { + ObjectAbstractNode *ptr = (ObjectAbstractNode*)mCurrent; + ptr->setVariable(name, value); + } + else + { + mCompiler->mEnv.insert(std::make_pair(name, value)); + } + } + // variable = $*, no children + else if(node->type == CNT_VARIABLE) + { + if(!node->children.empty()) + { + mCompiler->addError(CE_FEWERPARAMETERSEXPECTED, node->file, node->line); + return; + } + + VariableAccessAbstractNode *impl = OGRE_NEW VariableAccessAbstractNode(mCurrent); + impl->line = node->line; + impl->file = node->file; + impl->name = node->token; + + asn = AbstractNodePtr(impl); + } + // Handle properties and objects here + else if(!node->children.empty()) + { + // Grab the last two nodes + ConcreteNodePtr temp1, temp2; + ConcreteNodeList::reverse_iterator riter = node->children.rbegin(); + if(riter != node->children.rend()) + { + temp1 = *riter; + riter++; + } + if(riter != node->children.rend()) + temp2 = *riter; + + // object = last 2 children == { and } + if(!temp1.isNull() && !temp2.isNull() && + temp1->type == CNT_RBRACE && temp2->type == CNT_LBRACE) + { + if(node->children.size() < 2) + { + mCompiler->addError(CE_STRINGEXPECTED, node->file, node->line); + return; + } + + ObjectAbstractNode *impl = OGRE_NEW ObjectAbstractNode(mCurrent); + impl->line = node->line; + impl->file = node->file; + impl->abstract = false; + + // Create a temporary detail list + list::type temp; + if(node->token == "abstract") + { + impl->abstract = true; + for(ConcreteNodeList::const_iterator i = node->children.begin(); i != node->children.end(); ++i) + temp.push_back((*i).get()); + } + else + { + temp.push_back(node); + for(ConcreteNodeList::const_iterator i = node->children.begin(); i != node->children.end(); ++i) + temp.push_back((*i).get()); + } + + // Get the type of object + list::type::const_iterator iter = temp.begin(); + impl->cls = (*iter)->token; + ++iter; + + // Get the name + // Unless the type is in the exclusion list + if(iter != temp.end() && ((*iter)->type == CNT_WORD || (*iter)->type == CNT_QUOTE) && + !mCompiler->isNameExcluded(impl->cls, mCurrent)) + { + impl->name = (*iter)->token; ++iter; - } + } - // Finally try to map the cls to an id - ScriptCompiler::IdMap::const_iterator iter2 = mCompiler->mIds.find(impl->cls); - if(iter2 != mCompiler->mIds.end()) + // Everything up until the colon is a "value" of this object + while(iter != temp.end() && (*iter)->type != CNT_COLON && (*iter)->type != CNT_LBRACE) { - impl->id = iter2->second; + if((*iter)->type == CNT_VARIABLE) + { + VariableAccessAbstractNode *var = OGRE_NEW VariableAccessAbstractNode(impl); + var->file = (*iter)->file; + var->line = (*iter)->line; + var->type = ANT_VARIABLE_ACCESS; + var->name = (*iter)->token; + impl->values.push_back(AbstractNodePtr(var)); + } + else + { + AtomAbstractNode *atom = OGRE_NEW AtomAbstractNode(impl); + atom->file = (*iter)->file; + atom->line = (*iter)->line; + atom->type = ANT_ATOM; + atom->value = (*iter)->token; + impl->values.push_back(AbstractNodePtr(atom)); + } + ++iter; + } + + // Find the bases + if(iter != temp.end() && (*iter)->type == CNT_COLON) + { + // Children of the ':' are bases + for(ConcreteNodeList::iterator j = (*iter)->children.begin(); j != (*iter)->children.end(); ++j) + impl->bases.push_back((*j)->token); + ++iter; + } + + // Finally try to map the cls to an id + ScriptCompiler::IdMap::const_iterator iter2 = mCompiler->mIds.find(impl->cls); + if(iter2 != mCompiler->mIds.end()) + { + impl->id = iter2->second; } else { mCompiler->addError(CE_UNEXPECTEDTOKEN, impl->file, impl->line, "token class, " + impl->cls + ", unrecognized."); } - asn = AbstractNodePtr(impl); - mCurrent = impl; - - // Visit the children of the { - AbstractTreeBuilder::visit(this, temp2->children); - - // Go back up the stack - mCurrent = impl->parent; - } - // Otherwise, it is a property - else - { - PropertyAbstractNode *impl = OGRE_NEW PropertyAbstractNode(mCurrent); - impl->line = node->line; - impl->file = node->file; - impl->name = node->token; - - ScriptCompiler::IdMap::const_iterator iter2 = mCompiler->mIds.find(impl->name); - if(iter2 != mCompiler->mIds.end()) - impl->id = iter2->second; - - asn = AbstractNodePtr(impl); - mCurrent = impl; - - // Visit the children of the { - AbstractTreeBuilder::visit(this, node->children); - - // Go back up the stack - mCurrent = impl->parent; - } - } - // Otherwise, it is a standard atom - else - { - AtomAbstractNode *impl = OGRE_NEW AtomAbstractNode(mCurrent); - impl->line = node->line; - impl->file = node->file; - impl->value = node->token; - - ScriptCompiler::IdMap::const_iterator iter2 = mCompiler->mIds.find(impl->value); - if(iter2 != mCompiler->mIds.end()) - impl->id = iter2->second; - - asn = AbstractNodePtr(impl); - } - - // Here, we must insert the node into the tree - if(!asn.isNull()) - { - if(mCurrent) - { - if(mCurrent->type == ANT_PROPERTY) - { - PropertyAbstractNode *impl = reinterpret_cast(mCurrent); - impl->values.push_back(asn); - } - else - { - ObjectAbstractNode *impl = reinterpret_cast(mCurrent); - impl->children.push_back(asn); - } - } - else - { - mNodes->push_back(asn); - } - } - } - - void ScriptCompiler::AbstractTreeBuilder::visit(AbstractTreeBuilder *visitor, const ConcreteNodeList &nodes) - { - for(ConcreteNodeList::const_iterator i = nodes.begin(); i != nodes.end(); ++i) - visitor->visit((*i).get()); - } - - - // ScriptCompilerManager - template<> ScriptCompilerManager *Singleton::msSingleton = 0; - - ScriptCompilerManager* ScriptCompilerManager::getSingletonPtr(void) + asn = AbstractNodePtr(impl); + mCurrent = impl; + + // Visit the children of the { + AbstractTreeBuilder::visit(this, temp2->children); + + // Go back up the stack + mCurrent = impl->parent; + } + // Otherwise, it is a property + else + { + PropertyAbstractNode *impl = OGRE_NEW PropertyAbstractNode(mCurrent); + impl->line = node->line; + impl->file = node->file; + impl->name = node->token; + + ScriptCompiler::IdMap::const_iterator iter2 = mCompiler->mIds.find(impl->name); + if(iter2 != mCompiler->mIds.end()) + impl->id = iter2->second; + + asn = AbstractNodePtr(impl); + mCurrent = impl; + + // Visit the children of the { + AbstractTreeBuilder::visit(this, node->children); + + // Go back up the stack + mCurrent = impl->parent; + } + } + // Otherwise, it is a standard atom + else + { + AtomAbstractNode *impl = OGRE_NEW AtomAbstractNode(mCurrent); + impl->line = node->line; + impl->file = node->file; + impl->value = node->token; + + ScriptCompiler::IdMap::const_iterator iter2 = mCompiler->mIds.find(impl->value); + if(iter2 != mCompiler->mIds.end()) + impl->id = iter2->second; + + asn = AbstractNodePtr(impl); + } + + // Here, we must insert the node into the tree + if(!asn.isNull()) + { + if(mCurrent) + { + if(mCurrent->type == ANT_PROPERTY) + { + PropertyAbstractNode *impl = reinterpret_cast(mCurrent); + impl->values.push_back(asn); + } + else + { + ObjectAbstractNode *impl = reinterpret_cast(mCurrent); + impl->children.push_back(asn); + } + } + else + { + mNodes->push_back(asn); + } + } + } + + void ScriptCompiler::AbstractTreeBuilder::visit(AbstractTreeBuilder *visitor, const ConcreteNodeList &nodes) + { + for(ConcreteNodeList::const_iterator i = nodes.begin(); i != nodes.end(); ++i) + visitor->visit((*i).get()); + } + + + // ScriptCompilerManager + template<> ScriptCompilerManager *Singleton::msSingleton = 0; + + ScriptCompilerManager* ScriptCompilerManager::getSingletonPtr(void) { return msSingleton; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- ScriptCompilerManager& ScriptCompilerManager::getSingleton(void) { assert( msSingleton ); return ( *msSingleton ); } - //----------------------------------------------------------------------- - ScriptCompilerManager::ScriptCompilerManager() - :mListener(0), OGRE_THREAD_POINTER_INIT(mScriptCompiler) - { + //----------------------------------------------------------------------- + ScriptCompilerManager::ScriptCompilerManager() + :mListener(0), OGRE_THREAD_POINTER_INIT(mScriptCompiler) + { OGRE_LOCK_AUTO_MUTEX; - mScriptPatterns.push_back("*.program"); - mScriptPatterns.push_back("*.material"); - mScriptPatterns.push_back("*.particle"); - mScriptPatterns.push_back("*.compositor"); + mScriptPatterns.push_back("*.program"); + mScriptPatterns.push_back("*.material"); + mScriptPatterns.push_back("*.particle"); + mScriptPatterns.push_back("*.compositor"); mScriptPatterns.push_back("*.os"); - ResourceGroupManager::getSingleton()._registerScriptLoader(this); - - OGRE_THREAD_POINTER_SET(mScriptCompiler, OGRE_NEW ScriptCompiler()); - - mBuiltinTranslatorManager = OGRE_NEW BuiltinScriptTranslatorManager(); - mManagers.push_back(mBuiltinTranslatorManager); - } - //----------------------------------------------------------------------- - ScriptCompilerManager::~ScriptCompilerManager() - { - OGRE_THREAD_POINTER_DELETE(mScriptCompiler); - OGRE_DELETE mBuiltinTranslatorManager; - } - //----------------------------------------------------------------------- - void ScriptCompilerManager::setListener(ScriptCompilerListener *listener) - { + ResourceGroupManager::getSingleton()._registerScriptLoader(this); + + OGRE_THREAD_POINTER_SET(mScriptCompiler, OGRE_NEW ScriptCompiler()); + + mBuiltinTranslatorManager = OGRE_NEW BuiltinScriptTranslatorManager(); + mManagers.push_back(mBuiltinTranslatorManager); + } + //----------------------------------------------------------------------- + ScriptCompilerManager::~ScriptCompilerManager() + { + OGRE_THREAD_POINTER_DELETE(mScriptCompiler); + OGRE_DELETE mBuiltinTranslatorManager; + } + //----------------------------------------------------------------------- + void ScriptCompilerManager::setListener(ScriptCompilerListener *listener) + { OGRE_LOCK_AUTO_MUTEX; - mListener = listener; - } - //----------------------------------------------------------------------- - ScriptCompilerListener *ScriptCompilerManager::getListener() - { - return mListener; - } - //----------------------------------------------------------------------- - void ScriptCompilerManager::addTranslatorManager(Ogre::ScriptTranslatorManager *man) - { + mListener = listener; + } + //----------------------------------------------------------------------- + ScriptCompilerListener *ScriptCompilerManager::getListener() + { + return mListener; + } + //----------------------------------------------------------------------- + void ScriptCompilerManager::addTranslatorManager(Ogre::ScriptTranslatorManager *man) + { OGRE_LOCK_AUTO_MUTEX; - mManagers.push_back(man); - } - //----------------------------------------------------------------------- - void ScriptCompilerManager::removeTranslatorManager(Ogre::ScriptTranslatorManager *man) - { + mManagers.push_back(man); + } + //----------------------------------------------------------------------- + void ScriptCompilerManager::removeTranslatorManager(Ogre::ScriptTranslatorManager *man) + { OGRE_LOCK_AUTO_MUTEX; - - for(vector::type::iterator i = mManagers.begin(); i != mManagers.end(); ++i) - { - if(*i == man) - { - mManagers.erase(i); - break; - } - } - } - //------------------------------------------------------------------------- - void ScriptCompilerManager::clearTranslatorManagers() - { - mManagers.clear(); - } - //----------------------------------------------------------------------- - ScriptTranslator *ScriptCompilerManager::getTranslator(const AbstractNodePtr &node) - { - ScriptTranslator *translator = 0; - { + + for(vector::type::iterator i = mManagers.begin(); i != mManagers.end(); ++i) + { + if(*i == man) + { + mManagers.erase(i); + break; + } + } + } + //------------------------------------------------------------------------- + void ScriptCompilerManager::clearTranslatorManagers() + { + mManagers.clear(); + } + //----------------------------------------------------------------------- + ScriptTranslator *ScriptCompilerManager::getTranslator(const AbstractNodePtr &node) + { + ScriptTranslator *translator = 0; + { OGRE_LOCK_AUTO_MUTEX; - - // Start looking from the back - for(vector::type::reverse_iterator i = mManagers.rbegin(); i != mManagers.rend(); ++i) - { - translator = (*i)->getTranslator(node); - if(translator != 0) - break; - } - } - return translator; - } - //----------------------------------------------------------------------- - void ScriptCompilerManager::addScriptPattern(const String &pattern) - { - mScriptPatterns.push_back(pattern); - } - //----------------------------------------------------------------------- + + // Start looking from the back + for(vector::type::reverse_iterator i = mManagers.rbegin(); i != mManagers.rend(); ++i) + { + translator = (*i)->getTranslator(node); + if(translator != 0) + break; + } + } + return translator; + } + //----------------------------------------------------------------------- + void ScriptCompilerManager::addScriptPattern(const String &pattern) + { + mScriptPatterns.push_back(pattern); + } + //----------------------------------------------------------------------- const StringVector& ScriptCompilerManager::getScriptPatterns(void) const { return mScriptPatterns; @@ -1663,40 +1663,40 @@ namespace Ogre void ScriptCompilerManager::parseScript(DataStreamPtr& stream, const String& groupName) { #if OGRE_THREAD_SUPPORT - // check we have an instance for this thread (should always have one for main thread) - if (!OGRE_THREAD_POINTER_GET(mScriptCompiler)) - { - // create a new instance for this thread - will get deleted when - // the thread dies - OGRE_THREAD_POINTER_SET(mScriptCompiler, OGRE_NEW ScriptCompiler()); - } + // check we have an instance for this thread (should always have one for main thread) + if (!OGRE_THREAD_POINTER_GET(mScriptCompiler)) + { + // create a new instance for this thread - will get deleted when + // the thread dies + OGRE_THREAD_POINTER_SET(mScriptCompiler, OGRE_NEW ScriptCompiler()); + } #endif - // Set the listener on the compiler before we continue - { + // Set the listener on the compiler before we continue + { OGRE_LOCK_AUTO_MUTEX; - OGRE_THREAD_POINTER_GET(mScriptCompiler)->setListener(mListener); - } + OGRE_THREAD_POINTER_GET(mScriptCompiler)->setListener(mListener); + } OGRE_THREAD_POINTER_GET(mScriptCompiler)->compile(stream->getAsString(), stream->getName(), groupName); } - //------------------------------------------------------------------------- - String PreApplyTextureAliasesScriptCompilerEvent::eventType = "preApplyTextureAliases"; - //------------------------------------------------------------------------- - String ProcessResourceNameScriptCompilerEvent::eventType = "processResourceName"; - //------------------------------------------------------------------------- - String ProcessNameExclusionScriptCompilerEvent::eventType = "processNameExclusion"; - //---------------------------------------------------------------------------- - String CreateMaterialScriptCompilerEvent::eventType = "createMaterial"; - //---------------------------------------------------------------------------- - String CreateGpuProgramScriptCompilerEvent::eventType = "createGpuProgram"; - //------------------------------------------------------------------------- - String CreateHighLevelGpuProgramScriptCompilerEvent::eventType = "createHighLevelGpuProgram"; - //------------------------------------------------------------------------- - String CreateGpuSharedParametersScriptCompilerEvent::eventType = "createGpuSharedParameters"; - //------------------------------------------------------------------------- - String CreateParticleSystemScriptCompilerEvent::eventType = "createParticleSystem"; - //------------------------------------------------------------------------- - String CreateCompositorScriptCompilerEvent::eventType = "createCompositor"; + //------------------------------------------------------------------------- + String PreApplyTextureAliasesScriptCompilerEvent::eventType = "preApplyTextureAliases"; + //------------------------------------------------------------------------- + String ProcessResourceNameScriptCompilerEvent::eventType = "processResourceName"; + //------------------------------------------------------------------------- + String ProcessNameExclusionScriptCompilerEvent::eventType = "processNameExclusion"; + //---------------------------------------------------------------------------- + String CreateMaterialScriptCompilerEvent::eventType = "createMaterial"; + //---------------------------------------------------------------------------- + String CreateGpuProgramScriptCompilerEvent::eventType = "createGpuProgram"; + //------------------------------------------------------------------------- + String CreateHighLevelGpuProgramScriptCompilerEvent::eventType = "createHighLevelGpuProgram"; + //------------------------------------------------------------------------- + String CreateGpuSharedParametersScriptCompilerEvent::eventType = "createGpuSharedParameters"; + //------------------------------------------------------------------------- + String CreateParticleSystemScriptCompilerEvent::eventType = "createParticleSystem"; + //------------------------------------------------------------------------- + String CreateCompositorScriptCompilerEvent::eventType = "createCompositor"; } diff --git a/OgreMain/src/OgreScriptLexer.cpp b/OgreMain/src/OgreScriptLexer.cpp index ee966cfeb5d..8f15156eaed 100644 --- a/OgreMain/src/OgreScriptLexer.cpp +++ b/OgreMain/src/OgreScriptLexer.cpp @@ -31,254 +31,254 @@ THE SOFTWARE. namespace Ogre{ - ScriptLexer::ScriptLexer() - { - } + ScriptLexer::ScriptLexer() + { + } - ScriptTokenListPtr ScriptLexer::tokenize(const String &str, const String &source) - { - // State enums - enum{ READY = 0, COMMENT, MULTICOMMENT, WORD, QUOTE, VAR, POSSIBLECOMMENT }; + ScriptTokenListPtr ScriptLexer::tokenize(const String &str, const String &source) + { + // State enums + enum{ READY = 0, COMMENT, MULTICOMMENT, WORD, QUOTE, VAR, POSSIBLECOMMENT }; - // Set up some constant characters of interest - const wchar_t varopener = '$', quote = '\"', slash = '/', backslash = '\\', openbrace = '{', closebrace = '}', colon = ':', star = '*', cr = '\r', lf = '\n'; - char c = 0; + // Set up some constant characters of interest + const wchar_t varopener = '$', quote = '\"', slash = '/', backslash = '\\', openbrace = '{', closebrace = '}', colon = ':', star = '*', cr = '\r', lf = '\n'; + char c = 0; - String lexeme; - uint32 line = 1, state = READY, lastQuote = 0; - ScriptTokenListPtr tokens(OGRE_NEW_T(ScriptTokenList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); + String lexeme; + uint32 line = 1, state = READY, lastQuote = 0; + ScriptTokenListPtr tokens(OGRE_NEW_T(ScriptTokenList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); - // Iterate over the input - String::const_iterator i = str.begin(), end = str.end(); - while(i != end) - { - char lastc = c; - c = *i; + // Iterate over the input + String::const_iterator i = str.begin(), end = str.end(); + while(i != end) + { + char lastc = c; + c = *i; - if(c == quote) - lastQuote = line; + if(c == quote) + lastQuote = line; - switch(state) - { - case READY: - if(c == slash && lastc == slash) - { - // Comment start, clear out the lexeme - lexeme = ""; - state = COMMENT; - } - else if(c == star && lastc == slash) - { - lexeme = ""; - state = MULTICOMMENT; - } - else if(c == quote) - { - // Clear out the lexeme ready to be filled with quotes! - lexeme = c; - state = QUOTE; - } - else if(c == varopener) - { - // Set up to read in a variable - lexeme = c; - state = VAR; - } - else if(isNewline(c)) - { - lexeme = c; - setToken(lexeme, line, source, tokens.get()); - } - else if(!isWhitespace(c)) - { - lexeme = c; - if(c == slash) - state = POSSIBLECOMMENT; - else - state = WORD; - } - break; - case COMMENT: - // This newline happens to be ignored automatically - if(isNewline(c)) - state = READY; - break; - case MULTICOMMENT: - if(c == slash && lastc == star) - state = READY; - break; - case POSSIBLECOMMENT: - if(c == slash && lastc == slash) - { - lexeme = ""; - state = COMMENT; - break; - } - else if(c == star && lastc == slash) - { - lexeme = ""; - state = MULTICOMMENT; - break; - } - else - { - state = WORD; - } - case WORD: - if(isNewline(c)) - { - setToken(lexeme, line, source, tokens.get()); - lexeme = c; - setToken(lexeme, line, source, tokens.get()); - state = READY; - } - else if(isWhitespace(c)) - { - setToken(lexeme, line, source, tokens.get()); - state = READY; - } - else if(c == openbrace || c == closebrace || c == colon) - { - setToken(lexeme, line, source, tokens.get()); - lexeme = c; - setToken(lexeme, line, source, tokens.get()); - state = READY; - } - else - { - lexeme += c; - } - break; - case QUOTE: - if(c != backslash) - { - // Allow embedded quotes with escaping - if(c == quote && lastc == backslash) - { - lexeme += c; - } - else if(c == quote) - { - lexeme += c; - setToken(lexeme, line, source, tokens.get()); - state = READY; - } - else - { - // Backtrack here and allow a backslash normally within the quote - if(lastc == backslash) - lexeme = lexeme + "\\" + c; - else - lexeme += c; - } - } - break; - case VAR: - if(isNewline(c)) - { - setToken(lexeme, line, source, tokens.get()); - lexeme = c; - setToken(lexeme, line, source, tokens.get()); - state = READY; - } - else if(isWhitespace(c)) - { - setToken(lexeme, line, source, tokens.get()); - state = READY; - } - else if(c == openbrace || c == closebrace || c == colon) - { - setToken(lexeme, line, source, tokens.get()); - lexeme = c; - setToken(lexeme, line, source, tokens.get()); - state = READY; - } - else - { - lexeme += c; - } - break; - } + switch(state) + { + case READY: + if(c == slash && lastc == slash) + { + // Comment start, clear out the lexeme + lexeme = ""; + state = COMMENT; + } + else if(c == star && lastc == slash) + { + lexeme = ""; + state = MULTICOMMENT; + } + else if(c == quote) + { + // Clear out the lexeme ready to be filled with quotes! + lexeme = c; + state = QUOTE; + } + else if(c == varopener) + { + // Set up to read in a variable + lexeme = c; + state = VAR; + } + else if(isNewline(c)) + { + lexeme = c; + setToken(lexeme, line, source, tokens.get()); + } + else if(!isWhitespace(c)) + { + lexeme = c; + if(c == slash) + state = POSSIBLECOMMENT; + else + state = WORD; + } + break; + case COMMENT: + // This newline happens to be ignored automatically + if(isNewline(c)) + state = READY; + break; + case MULTICOMMENT: + if(c == slash && lastc == star) + state = READY; + break; + case POSSIBLECOMMENT: + if(c == slash && lastc == slash) + { + lexeme = ""; + state = COMMENT; + break; + } + else if(c == star && lastc == slash) + { + lexeme = ""; + state = MULTICOMMENT; + break; + } + else + { + state = WORD; + } + case WORD: + if(isNewline(c)) + { + setToken(lexeme, line, source, tokens.get()); + lexeme = c; + setToken(lexeme, line, source, tokens.get()); + state = READY; + } + else if(isWhitespace(c)) + { + setToken(lexeme, line, source, tokens.get()); + state = READY; + } + else if(c == openbrace || c == closebrace || c == colon) + { + setToken(lexeme, line, source, tokens.get()); + lexeme = c; + setToken(lexeme, line, source, tokens.get()); + state = READY; + } + else + { + lexeme += c; + } + break; + case QUOTE: + if(c != backslash) + { + // Allow embedded quotes with escaping + if(c == quote && lastc == backslash) + { + lexeme += c; + } + else if(c == quote) + { + lexeme += c; + setToken(lexeme, line, source, tokens.get()); + state = READY; + } + else + { + // Backtrack here and allow a backslash normally within the quote + if(lastc == backslash) + lexeme = lexeme + "\\" + c; + else + lexeme += c; + } + } + break; + case VAR: + if(isNewline(c)) + { + setToken(lexeme, line, source, tokens.get()); + lexeme = c; + setToken(lexeme, line, source, tokens.get()); + state = READY; + } + else if(isWhitespace(c)) + { + setToken(lexeme, line, source, tokens.get()); + state = READY; + } + else if(c == openbrace || c == closebrace || c == colon) + { + setToken(lexeme, line, source, tokens.get()); + lexeme = c; + setToken(lexeme, line, source, tokens.get()); + state = READY; + } + else + { + lexeme += c; + } + break; + } - // Separate check for newlines just to track line numbers - if(c == cr || (c == lf && lastc != cr)) - line++; - - i++; - } + // Separate check for newlines just to track line numbers + if(c == cr || (c == lf && lastc != cr)) + line++; + + i++; + } - // Check for valid exit states - if(state == WORD || state == VAR) - { - if(!lexeme.empty()) - setToken(lexeme, line, source, tokens.get()); - } - else - { - if(state == QUOTE) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - Ogre::String("no matching \" found for \" at line ") + - Ogre::StringConverter::toString(lastQuote), - "ScriptLexer::tokenize"); - } - } + // Check for valid exit states + if(state == WORD || state == VAR) + { + if(!lexeme.empty()) + setToken(lexeme, line, source, tokens.get()); + } + else + { + if(state == QUOTE) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + Ogre::String("no matching \" found for \" at line ") + + Ogre::StringConverter::toString(lastQuote), + "ScriptLexer::tokenize"); + } + } - return tokens; - } + return tokens; + } - void ScriptLexer::setToken(const Ogre::String &lexeme, Ogre::uint32 line, const String &source, Ogre::ScriptTokenList *tokens) - { - const char openBracket = '{', closeBracket = '}', colon = ':', - quote = '\"', var = '$'; + void ScriptLexer::setToken(const Ogre::String &lexeme, Ogre::uint32 line, const String &source, Ogre::ScriptTokenList *tokens) + { + const char openBracket = '{', closeBracket = '}', colon = ':', + quote = '\"', var = '$'; - ScriptTokenPtr token(OGRE_NEW_T(ScriptToken, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); - token->lexeme = lexeme; - token->line = line; - token->file = source; - bool ignore = false; + ScriptTokenPtr token(OGRE_NEW_T(ScriptToken, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); + token->lexeme = lexeme; + token->line = line; + token->file = source; + bool ignore = false; - // Check the user token map first - if(lexeme.size() == 1 && isNewline(lexeme[0])) - { - token->type = TID_NEWLINE; - if(!tokens->empty() && tokens->back()->type == TID_NEWLINE) - ignore = true; - } - else if(lexeme.size() == 1 && lexeme[0] == openBracket) - token->type = TID_LBRACKET; - else if(lexeme.size() == 1 && lexeme[0] == closeBracket) - token->type = TID_RBRACKET; - else if(lexeme.size() == 1 && lexeme[0] == colon) - token->type = TID_COLON; - else if(lexeme[0] == var) - token->type = TID_VARIABLE; - else - { - // This is either a non-zero length phrase or quoted phrase - if(lexeme.size() >= 2 && lexeme[0] == quote && lexeme[lexeme.size() - 1] == quote) - { - token->type = TID_QUOTE; - } - else - { - token->type = TID_WORD; - } - } + // Check the user token map first + if(lexeme.size() == 1 && isNewline(lexeme[0])) + { + token->type = TID_NEWLINE; + if(!tokens->empty() && tokens->back()->type == TID_NEWLINE) + ignore = true; + } + else if(lexeme.size() == 1 && lexeme[0] == openBracket) + token->type = TID_LBRACKET; + else if(lexeme.size() == 1 && lexeme[0] == closeBracket) + token->type = TID_RBRACKET; + else if(lexeme.size() == 1 && lexeme[0] == colon) + token->type = TID_COLON; + else if(lexeme[0] == var) + token->type = TID_VARIABLE; + else + { + // This is either a non-zero length phrase or quoted phrase + if(lexeme.size() >= 2 && lexeme[0] == quote && lexeme[lexeme.size() - 1] == quote) + { + token->type = TID_QUOTE; + } + else + { + token->type = TID_WORD; + } + } - if(!ignore) - tokens->push_back(token); - } + if(!ignore) + tokens->push_back(token); + } - bool ScriptLexer::isWhitespace(Ogre::String::value_type c) const - { - return c == ' ' || c == '\r' || c == '\t'; - } + bool ScriptLexer::isWhitespace(Ogre::String::value_type c) const + { + return c == ' ' || c == '\r' || c == '\t'; + } - bool ScriptLexer::isNewline(Ogre::String::value_type c) const - { - return c == '\n' || c == '\r'; - } + bool ScriptLexer::isNewline(Ogre::String::value_type c) const + { + return c == '\n' || c == '\r'; + } } diff --git a/OgreMain/src/OgreScriptParser.cpp b/OgreMain/src/OgreScriptParser.cpp index bb31a5cd754..85be3a62e6c 100644 --- a/OgreMain/src/OgreScriptParser.cpp +++ b/OgreMain/src/OgreScriptParser.cpp @@ -32,481 +32,481 @@ THE SOFTWARE. namespace Ogre { - ScriptParser::ScriptParser() - { - } - - ConcreteNodeListPtr ScriptParser::parse(const ScriptTokenListPtr &tokens) - { - // MEMCATEGORY_GENERAL because SharedPtr can only free using that category - ConcreteNodeListPtr nodes(OGRE_NEW_T(ConcreteNodeList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); - - enum{READY, OBJECT}; - uint32 state = READY; - - ConcreteNode *parent = 0; - ConcreteNodePtr node; - ScriptToken *token = 0; - ScriptTokenList::iterator i = tokens->begin(), end = tokens->end(); - while(i != end) - { - token = (*i).get(); - - switch(state) - { - case READY: - if(token->type == TID_WORD) - { - if(token->lexeme == "import") - { - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->token = token->lexeme; - node->file = token->file; - node->line = token->line; - node->type = CNT_IMPORT; - - // The next token is the target - ++i; - if(i == end || ((*i)->type != TID_WORD && (*i)->type != TID_QUOTE)) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - Ogre::String("expected import target at line ") + - Ogre::StringConverter::toString(node->line), - "ScriptParser::parse"); - ConcreteNodePtr temp(OGRE_NEW ConcreteNode()); - temp->parent = node.get(); - temp->file = (*i)->file; - temp->line = (*i)->line; - temp->type = (*i)->type == TID_WORD ? CNT_WORD : CNT_QUOTE; - if(temp->type == CNT_QUOTE) - temp->token = (*i)->lexeme.substr(1, token->lexeme.size() - 2); - else - temp->token = (*i)->lexeme; - node->children.push_back(temp); - - // The second-next token is the source - ++i; - ++i; - if(i == end || ((*i)->type != TID_WORD && (*i)->type != TID_QUOTE)) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - Ogre::String("expected import source at line ") + - Ogre::StringConverter::toString(node->line), - "ScriptParser::parse"); - temp = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - temp->parent = node.get(); - temp->file = (*i)->file; - temp->line = (*i)->line; - temp->type = (*i)->type == TID_WORD ? CNT_WORD : CNT_QUOTE; - if(temp->type == CNT_QUOTE) - temp->token = (*i)->lexeme.substr(1, (*i)->lexeme.size() - 2); - else - temp->token = (*i)->lexeme; - node->children.push_back(temp); - - // Consume all the newlines - i = skipNewlines(i, end); - - // Insert the node - if(parent) - { - node->parent = parent; - parent->children.push_back(node); - } - else - { - node->parent = 0; - nodes->push_back(node); - } - node = ConcreteNodePtr(); - } - else if(token->lexeme == "set") - { - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->token = token->lexeme; - node->file = token->file; - node->line = token->line; - node->type = CNT_VARIABLE_ASSIGN; - - // The next token is the variable - ++i; - if(i == end || (*i)->type != TID_VARIABLE) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - Ogre::String("expected variable name at line ") + - Ogre::StringConverter::toString(node->line), - "ScriptParser::parse"); - ConcreteNodePtr temp(OGRE_NEW ConcreteNode()); - temp->parent = node.get(); - temp->file = (*i)->file; - temp->line = (*i)->line; - temp->type = CNT_VARIABLE; - temp->token = (*i)->lexeme; - node->children.push_back(temp); - - // The next token is the assignment - ++i; - if(i == end || ((*i)->type != TID_WORD && (*i)->type != TID_QUOTE)) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - Ogre::String("expected variable value at line ") + - Ogre::StringConverter::toString(node->line), - "ScriptParser::parse"); - temp = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - temp->parent = node.get(); - temp->file = (*i)->file; - temp->line = (*i)->line; - temp->type = (*i)->type == TID_WORD ? CNT_WORD : CNT_QUOTE; - if(temp->type == CNT_QUOTE) - temp->token = (*i)->lexeme.substr(1, (*i)->lexeme.size() - 2); - else - temp->token = (*i)->lexeme; - node->children.push_back(temp); - - // Consume all the newlines - i = skipNewlines(i, end); - - // Insert the node - if(parent) - { - node->parent = parent; - parent->children.push_back(node); - } - else - { - node->parent = 0; - nodes->push_back(node); - } - node = ConcreteNodePtr(); - } - else - { - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->file = token->file; - node->line = token->line; - node->type = token->type == TID_WORD ? CNT_WORD : CNT_QUOTE; - if(node->type == CNT_QUOTE) - node->token = token->lexeme.substr(1, token->lexeme.size() - 2); - else - node->token = token->lexeme; - - // Insert the node - if(parent) - { - node->parent = parent; - parent->children.push_back(node); - } - else - { - node->parent = 0; - nodes->push_back(node); - } - - // Set the parent - parent = node.get(); - - // Switch states - state = OBJECT; - - node = ConcreteNodePtr(); - } - } - else if(token->type == TID_RBRACKET) - { - // Go up one level if we can - if(parent) - parent = parent->parent; - - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->token = token->lexeme; - node->file = token->file; - node->line = token->line; - node->type = CNT_RBRACE; - - // Consume all the newlines - i = skipNewlines(i, end); - - // Insert the node - if(parent) - { - node->parent = parent; - parent->children.push_back(node); - } - else - { - node->parent = 0; - nodes->push_back(node); - } - - // Move up another level - if(parent) - parent = parent->parent; - - node = ConcreteNodePtr(); - } - break; - case OBJECT: - if(token->type == TID_NEWLINE) - { - // Look ahead to the next non-newline token and if it isn't an {, this was a property - ScriptTokenList::iterator next = skipNewlines(i, end); - if(next == end || (*next)->type != TID_LBRACKET) - { - // Ended a property here - if(parent) - parent = parent->parent; - state = READY; - } - } - else if(token->type == TID_COLON) - { - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->token = token->lexeme; - node->file = token->file; - node->line = token->line; - node->type = CNT_COLON; - - // The following token are the parent objects (base classes). + ScriptParser::ScriptParser() + { + } + + ConcreteNodeListPtr ScriptParser::parse(const ScriptTokenListPtr &tokens) + { + // MEMCATEGORY_GENERAL because SharedPtr can only free using that category + ConcreteNodeListPtr nodes(OGRE_NEW_T(ConcreteNodeList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); + + enum{READY, OBJECT}; + uint32 state = READY; + + ConcreteNode *parent = 0; + ConcreteNodePtr node; + ScriptToken *token = 0; + ScriptTokenList::iterator i = tokens->begin(), end = tokens->end(); + while(i != end) + { + token = (*i).get(); + + switch(state) + { + case READY: + if(token->type == TID_WORD) + { + if(token->lexeme == "import") + { + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->token = token->lexeme; + node->file = token->file; + node->line = token->line; + node->type = CNT_IMPORT; + + // The next token is the target + ++i; + if(i == end || ((*i)->type != TID_WORD && (*i)->type != TID_QUOTE)) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + Ogre::String("expected import target at line ") + + Ogre::StringConverter::toString(node->line), + "ScriptParser::parse"); + ConcreteNodePtr temp(OGRE_NEW ConcreteNode()); + temp->parent = node.get(); + temp->file = (*i)->file; + temp->line = (*i)->line; + temp->type = (*i)->type == TID_WORD ? CNT_WORD : CNT_QUOTE; + if(temp->type == CNT_QUOTE) + temp->token = (*i)->lexeme.substr(1, token->lexeme.size() - 2); + else + temp->token = (*i)->lexeme; + node->children.push_back(temp); + + // The second-next token is the source + ++i; + ++i; + if(i == end || ((*i)->type != TID_WORD && (*i)->type != TID_QUOTE)) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + Ogre::String("expected import source at line ") + + Ogre::StringConverter::toString(node->line), + "ScriptParser::parse"); + temp = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + temp->parent = node.get(); + temp->file = (*i)->file; + temp->line = (*i)->line; + temp->type = (*i)->type == TID_WORD ? CNT_WORD : CNT_QUOTE; + if(temp->type == CNT_QUOTE) + temp->token = (*i)->lexeme.substr(1, (*i)->lexeme.size() - 2); + else + temp->token = (*i)->lexeme; + node->children.push_back(temp); + + // Consume all the newlines + i = skipNewlines(i, end); + + // Insert the node + if(parent) + { + node->parent = parent; + parent->children.push_back(node); + } + else + { + node->parent = 0; + nodes->push_back(node); + } + node = ConcreteNodePtr(); + } + else if(token->lexeme == "set") + { + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->token = token->lexeme; + node->file = token->file; + node->line = token->line; + node->type = CNT_VARIABLE_ASSIGN; + + // The next token is the variable + ++i; + if(i == end || (*i)->type != TID_VARIABLE) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + Ogre::String("expected variable name at line ") + + Ogre::StringConverter::toString(node->line), + "ScriptParser::parse"); + ConcreteNodePtr temp(OGRE_NEW ConcreteNode()); + temp->parent = node.get(); + temp->file = (*i)->file; + temp->line = (*i)->line; + temp->type = CNT_VARIABLE; + temp->token = (*i)->lexeme; + node->children.push_back(temp); + + // The next token is the assignment + ++i; + if(i == end || ((*i)->type != TID_WORD && (*i)->type != TID_QUOTE)) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + Ogre::String("expected variable value at line ") + + Ogre::StringConverter::toString(node->line), + "ScriptParser::parse"); + temp = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + temp->parent = node.get(); + temp->file = (*i)->file; + temp->line = (*i)->line; + temp->type = (*i)->type == TID_WORD ? CNT_WORD : CNT_QUOTE; + if(temp->type == CNT_QUOTE) + temp->token = (*i)->lexeme.substr(1, (*i)->lexeme.size() - 2); + else + temp->token = (*i)->lexeme; + node->children.push_back(temp); + + // Consume all the newlines + i = skipNewlines(i, end); + + // Insert the node + if(parent) + { + node->parent = parent; + parent->children.push_back(node); + } + else + { + node->parent = 0; + nodes->push_back(node); + } + node = ConcreteNodePtr(); + } + else + { + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->file = token->file; + node->line = token->line; + node->type = token->type == TID_WORD ? CNT_WORD : CNT_QUOTE; + if(node->type == CNT_QUOTE) + node->token = token->lexeme.substr(1, token->lexeme.size() - 2); + else + node->token = token->lexeme; + + // Insert the node + if(parent) + { + node->parent = parent; + parent->children.push_back(node); + } + else + { + node->parent = 0; + nodes->push_back(node); + } + + // Set the parent + parent = node.get(); + + // Switch states + state = OBJECT; + + node = ConcreteNodePtr(); + } + } + else if(token->type == TID_RBRACKET) + { + // Go up one level if we can + if(parent) + parent = parent->parent; + + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->token = token->lexeme; + node->file = token->file; + node->line = token->line; + node->type = CNT_RBRACE; + + // Consume all the newlines + i = skipNewlines(i, end); + + // Insert the node + if(parent) + { + node->parent = parent; + parent->children.push_back(node); + } + else + { + node->parent = 0; + nodes->push_back(node); + } + + // Move up another level + if(parent) + parent = parent->parent; + + node = ConcreteNodePtr(); + } + break; + case OBJECT: + if(token->type == TID_NEWLINE) + { + // Look ahead to the next non-newline token and if it isn't an {, this was a property + ScriptTokenList::iterator next = skipNewlines(i, end); + if(next == end || (*next)->type != TID_LBRACKET) + { + // Ended a property here + if(parent) + parent = parent->parent; + state = READY; + } + } + else if(token->type == TID_COLON) + { + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->token = token->lexeme; + node->file = token->file; + node->line = token->line; + node->type = CNT_COLON; + + // The following token are the parent objects (base classes). // Require at least one of them. - ScriptTokenList::iterator j = i + 1; - j = skipNewlines(j, end); - if(j == end || ((*j)->type != TID_WORD && (*j)->type != TID_QUOTE)) { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - Ogre::String("expected object identifier at line ") + + ScriptTokenList::iterator j = i + 1; + j = skipNewlines(j, end); + if(j == end || ((*j)->type != TID_WORD && (*j)->type != TID_QUOTE)) { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + Ogre::String("expected object identifier at line ") + Ogre::StringConverter::toString(node->line), - "ScriptParser::parse"); + "ScriptParser::parse"); + } + + while(j != end && ((*j)->type == TID_WORD || (*j)->type == TID_QUOTE)) + { + ConcreteNodePtr tempNode = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + tempNode->token = (*j)->lexeme; + tempNode->file = (*j)->file; + tempNode->line = (*j)->line; + tempNode->type = (*j)->type == TID_WORD ? CNT_WORD : CNT_QUOTE; + tempNode->parent = node.get(); + node->children.push_back(tempNode); + ++j; + } + + // Move it backwards once, since the end of the loop moves it forwards again anyway + i = --j; + + // Insert the node + if(parent) + { + node->parent = parent; + parent->children.push_back(node); + } + else + { + node->parent = 0; + nodes->push_back(node); + } + node = ConcreteNodePtr(); + } + else if(token->type == TID_LBRACKET) + { + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->token = token->lexeme; + node->file = token->file; + node->line = token->line; + node->type = CNT_LBRACE; + + // Consume all the newlines + i = skipNewlines(i, end); + + // Insert the node + if(parent) + { + node->parent = parent; + parent->children.push_back(node); + } + else + { + node->parent = 0; + nodes->push_back(node); + } + + // Set the parent + parent = node.get(); + + // Change the state + state = READY; + + node = ConcreteNodePtr(); + } + else if(token->type == TID_RBRACKET) + { + // Go up one level if we can + if(parent) + parent = parent->parent; + + // If the parent is currently a { then go up again + if(parent && parent->type == CNT_LBRACE && parent->parent) + parent = parent->parent; + + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->token = token->lexeme; + node->file = token->file; + node->line = token->line; + node->type = CNT_RBRACE; + + // Consume all the newlines + i = skipNewlines(i, end); + + // Insert the node + if(parent) + { + node->parent = parent; + parent->children.push_back(node); + } + else + { + node->parent = 0; + nodes->push_back(node); } - while(j != end && ((*j)->type == TID_WORD || (*j)->type == TID_QUOTE)) - { - ConcreteNodePtr tempNode = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - tempNode->token = (*j)->lexeme; - tempNode->file = (*j)->file; - tempNode->line = (*j)->line; - tempNode->type = (*j)->type == TID_WORD ? CNT_WORD : CNT_QUOTE; - tempNode->parent = node.get(); - node->children.push_back(tempNode); - ++j; - } - - // Move it backwards once, since the end of the loop moves it forwards again anyway - i = --j; - - // Insert the node - if(parent) - { - node->parent = parent; - parent->children.push_back(node); - } - else - { - node->parent = 0; - nodes->push_back(node); - } - node = ConcreteNodePtr(); - } - else if(token->type == TID_LBRACKET) - { - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->token = token->lexeme; - node->file = token->file; - node->line = token->line; - node->type = CNT_LBRACE; - - // Consume all the newlines - i = skipNewlines(i, end); - - // Insert the node - if(parent) - { - node->parent = parent; - parent->children.push_back(node); - } - else - { - node->parent = 0; - nodes->push_back(node); - } - - // Set the parent - parent = node.get(); - - // Change the state - state = READY; - - node = ConcreteNodePtr(); - } - else if(token->type == TID_RBRACKET) - { - // Go up one level if we can - if(parent) - parent = parent->parent; - - // If the parent is currently a { then go up again - if(parent && parent->type == CNT_LBRACE && parent->parent) - parent = parent->parent; - - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->token = token->lexeme; - node->file = token->file; - node->line = token->line; - node->type = CNT_RBRACE; - - // Consume all the newlines - i = skipNewlines(i, end); - - // Insert the node - if(parent) - { - node->parent = parent; - parent->children.push_back(node); - } - else - { - node->parent = 0; - nodes->push_back(node); - } - - // Move up another level - if(parent) - parent = parent->parent; - - node = ConcreteNodePtr(); - state = READY; - } - else if(token->type == TID_VARIABLE) - { - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->token = token->lexeme; - node->file = token->file; - node->line = token->line; - node->type = CNT_VARIABLE; - - // Insert the node - if(parent) - { - node->parent = parent; - parent->children.push_back(node); - } - else - { - node->parent = 0; - nodes->push_back(node); - } - node = ConcreteNodePtr(); - } - else if(token->type == TID_QUOTE) - { - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->token = token->lexeme.substr(1, token->lexeme.size() - 2); - node->file = token->file; - node->line = token->line; - node->type = CNT_QUOTE; - - // Insert the node - if(parent) - { - node->parent = parent; - parent->children.push_back(node); - } - else - { - node->parent = 0; - nodes->push_back(node); - } - node = ConcreteNodePtr(); - } - else if(token->type == TID_WORD) - { - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->token = token->lexeme; - node->file = token->file; - node->line = token->line; - node->type = CNT_WORD; - - // Insert the node - if(parent) - { - node->parent = parent; - parent->children.push_back(node); - } - else - { - node->parent = 0; - nodes->push_back(node); - } - node = ConcreteNodePtr(); - } - break; - } - - ++i; - } - - return nodes; - } - - ConcreteNodeListPtr ScriptParser::parseChunk(const ScriptTokenListPtr &tokens) - { - // MEMCATEGORY_GENERAL because SharedPtr can only free using that category - ConcreteNodeListPtr nodes(OGRE_NEW_T(ConcreteNodeList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); - - ConcreteNodePtr node; - ScriptToken *token = 0; - for(ScriptTokenList::const_iterator i = tokens->begin(); i != tokens->end(); ++i) - { - token = (*i).get(); - - switch(token->type) - { - case TID_VARIABLE: - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->file = token->file; - node->line = token->line; - node->parent = 0; - node->token = token->lexeme; - node->type = CNT_VARIABLE; - break; - case TID_WORD: - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->file = token->file; - node->line = token->line; - node->parent = 0; - node->token = token->lexeme; - node->type = CNT_WORD; - break; - case TID_QUOTE: - node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); - node->file = token->file; - node->line = token->line; - node->parent = 0; - node->token = token->lexeme.substr(1, token->lexeme.size() - 2); - node->type = CNT_QUOTE; - default: - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - Ogre::String("unexpected token") + token->lexeme + " at line " + - Ogre::StringConverter::toString(token->line), - "ScriptParser::parseChunk"); - } - - if(!node.isNull()) - nodes->push_back(node); - } - - return nodes; - } - - ScriptToken *ScriptParser::getToken(ScriptTokenList::iterator i, ScriptTokenList::iterator end, int offset) - { - ScriptToken *token = 0; - ScriptTokenList::iterator iter = i + offset; - if(iter != end) - token = (*i).get(); - return token; - } - - ScriptTokenList::iterator ScriptParser::skipNewlines(ScriptTokenList::iterator i, ScriptTokenList::iterator end) - { - while(i != end && (*i)->type == TID_NEWLINE) - ++i; - return i; - } + // Move up another level + if(parent) + parent = parent->parent; + + node = ConcreteNodePtr(); + state = READY; + } + else if(token->type == TID_VARIABLE) + { + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->token = token->lexeme; + node->file = token->file; + node->line = token->line; + node->type = CNT_VARIABLE; + + // Insert the node + if(parent) + { + node->parent = parent; + parent->children.push_back(node); + } + else + { + node->parent = 0; + nodes->push_back(node); + } + node = ConcreteNodePtr(); + } + else if(token->type == TID_QUOTE) + { + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->token = token->lexeme.substr(1, token->lexeme.size() - 2); + node->file = token->file; + node->line = token->line; + node->type = CNT_QUOTE; + + // Insert the node + if(parent) + { + node->parent = parent; + parent->children.push_back(node); + } + else + { + node->parent = 0; + nodes->push_back(node); + } + node = ConcreteNodePtr(); + } + else if(token->type == TID_WORD) + { + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->token = token->lexeme; + node->file = token->file; + node->line = token->line; + node->type = CNT_WORD; + + // Insert the node + if(parent) + { + node->parent = parent; + parent->children.push_back(node); + } + else + { + node->parent = 0; + nodes->push_back(node); + } + node = ConcreteNodePtr(); + } + break; + } + + ++i; + } + + return nodes; + } + + ConcreteNodeListPtr ScriptParser::parseChunk(const ScriptTokenListPtr &tokens) + { + // MEMCATEGORY_GENERAL because SharedPtr can only free using that category + ConcreteNodeListPtr nodes(OGRE_NEW_T(ConcreteNodeList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); + + ConcreteNodePtr node; + ScriptToken *token = 0; + for(ScriptTokenList::const_iterator i = tokens->begin(); i != tokens->end(); ++i) + { + token = (*i).get(); + + switch(token->type) + { + case TID_VARIABLE: + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->file = token->file; + node->line = token->line; + node->parent = 0; + node->token = token->lexeme; + node->type = CNT_VARIABLE; + break; + case TID_WORD: + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->file = token->file; + node->line = token->line; + node->parent = 0; + node->token = token->lexeme; + node->type = CNT_WORD; + break; + case TID_QUOTE: + node = ConcreteNodePtr(OGRE_NEW ConcreteNode()); + node->file = token->file; + node->line = token->line; + node->parent = 0; + node->token = token->lexeme.substr(1, token->lexeme.size() - 2); + node->type = CNT_QUOTE; + default: + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + Ogre::String("unexpected token") + token->lexeme + " at line " + + Ogre::StringConverter::toString(token->line), + "ScriptParser::parseChunk"); + } + + if(!node.isNull()) + nodes->push_back(node); + } + + return nodes; + } + + ScriptToken *ScriptParser::getToken(ScriptTokenList::iterator i, ScriptTokenList::iterator end, int offset) + { + ScriptToken *token = 0; + ScriptTokenList::iterator iter = i + offset; + if(iter != end) + token = (*i).get(); + return token; + } + + ScriptTokenList::iterator ScriptParser::skipNewlines(ScriptTokenList::iterator i, ScriptTokenList::iterator end) + { + while(i != end && (*i)->type == TID_NEWLINE) + ++i; + return i; + } } diff --git a/OgreMain/src/OgreScriptTranslator.cpp b/OgreMain/src/OgreScriptTranslator.cpp index 48242ecbb43..fca72737180 100644 --- a/OgreMain/src/OgreScriptTranslator.cpp +++ b/OgreMain/src/OgreScriptTranslator.cpp @@ -64,9 +64,9 @@ namespace Ogre{ return GPT_GEOMETRY_PROGRAM; case ID_FRAGMENT_PROGRAM: return GPT_FRAGMENT_PROGRAM; - case ID_TESSELLATION_HULL_PROGRAM: + case ID_TESSELLATION_HULL_PROGRAM: return GPT_HULL_PROGRAM; - case ID_TESSELLATION_DOMAIN_PROGRAM: + case ID_TESSELLATION_DOMAIN_PROGRAM: return GPT_DOMAIN_PROGRAM; case ID_COMPUTE_PROGRAM: return GPT_COMPUTE_PROGRAM; @@ -2509,11 +2509,11 @@ namespace Ogre{ case ID_GEOMETRY_PROGRAM_REF: translateGeometryProgramRef(compiler, child); break; - case ID_TESSELLATION_HULL_PROGRAM_REF: - translateTessellationHullProgramRef(compiler, child); + case ID_TESSELLATION_HULL_PROGRAM_REF: + translateTessellationHullProgramRef(compiler, child); break; - case ID_TESSELLATION_DOMAIN_PROGRAM_REF: - translateTessellationDomainProgramRef(compiler, child); + case ID_TESSELLATION_DOMAIN_PROGRAM_REF: + translateTessellationDomainProgramRef(compiler, child); break; case ID_COMPUTE_PROGRAM_REF: translateComputeProgramRef(compiler, child); @@ -2615,7 +2615,7 @@ namespace Ogre{ } } //------------------------------------------------------------------------- - void PassTranslator::translateTessellationHullProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node) + void PassTranslator::translateTessellationHullProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node) { if(node->name.empty()) { @@ -2633,15 +2633,15 @@ namespace Ogre{ } Pass *pass = any_cast(node->parent->context); - pass->setTessellationHullProgram(evt.mName); - if(pass->getTessellationHullProgram()->isSupported()) + pass->setTessellationHullProgram(evt.mName); + if(pass->getTessellationHullProgram()->isSupported()) { - GpuProgramParametersSharedPtr params = pass->getTessellationHullProgramParameters(); + GpuProgramParametersSharedPtr params = pass->getTessellationHullProgramParameters(); GpuProgramTranslator::translateProgramParameters(compiler, params, node); } } //------------------------------------------------------------------------- - void PassTranslator::translateTessellationDomainProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node) + void PassTranslator::translateTessellationDomainProgramRef(ScriptCompiler *compiler, ObjectAbstractNode *node) { if(node->name.empty()) { @@ -2659,10 +2659,10 @@ namespace Ogre{ } Pass *pass = any_cast(node->parent->context); - pass->setTessellationDomainProgram(evt.mName); - if(pass->getTessellationDomainProgram()->isSupported()) + pass->setTessellationDomainProgram(evt.mName); + if(pass->getTessellationDomainProgram()->isSupported()) { - GpuProgramParametersSharedPtr params = pass->getTessellationDomainProgramParameters(); + GpuProgramParametersSharedPtr params = pass->getTessellationDomainProgramParameters(); GpuProgramTranslator::translateProgramParameters(compiler, params, node); } } @@ -4165,11 +4165,11 @@ namespace Ogre{ case ID_GEOMETRY: mUnit->setBindingType(TextureUnitState::BT_GEOMETRY); break; - case ID_TESSELLATION_HULL: - mUnit->setBindingType(TextureUnitState::BT_TESSELLATION_HULL); + case ID_TESSELLATION_HULL: + mUnit->setBindingType(TextureUnitState::BT_TESSELLATION_HULL); break; - case ID_TESSELLATION_DOMAIN: - mUnit->setBindingType(TextureUnitState::BT_TESSELLATION_DOMAIN); + case ID_TESSELLATION_DOMAIN: + mUnit->setBindingType(TextureUnitState::BT_TESSELLATION_DOMAIN); break; case ID_COMPUTE: mUnit->setBindingType(TextureUnitState::BT_COMPUTE); @@ -6704,20 +6704,20 @@ namespace Ogre{ compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); } break; - case ID_READ_BACK_AS_TEXTURE: - { - if(prop->values.empty()) - { - compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); - return; - } - bool val; - if(getBoolean(prop->values.front(), &val)) - mPass->setStencilReadBackAsTextureOperation(val); - else - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - } - break; + case ID_READ_BACK_AS_TEXTURE: + { + if(prop->values.empty()) + { + compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); + return; + } + bool val; + if(getBoolean(prop->values.front(), &val)) + mPass->setStencilReadBackAsTextureOperation(val); + else + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + } + break; case ID_BUFFERS: { uint32 buffers = 0; @@ -7016,8 +7016,8 @@ namespace Ogre{ else if(obj->id == ID_FRAGMENT_PROGRAM || obj->id == ID_VERTEX_PROGRAM || obj->id == ID_GEOMETRY_PROGRAM || - obj->id == ID_TESSELLATION_HULL_PROGRAM || - obj->id == ID_TESSELLATION_DOMAIN_PROGRAM || + obj->id == ID_TESSELLATION_HULL_PROGRAM || + obj->id == ID_TESSELLATION_DOMAIN_PROGRAM || obj->id == ID_COMPUTE_PROGRAM) translator = &mGpuProgramTranslator; else if(obj->id == ID_SHARED_PARAMS) diff --git a/OgreMain/src/OgreSerializer.cpp b/OgreMain/src/OgreSerializer.cpp index 8e893d709fd..2c63475119e 100644 --- a/OgreMain/src/OgreSerializer.cpp +++ b/OgreMain/src/OgreSerializer.cpp @@ -40,12 +40,12 @@ namespace Ogre { const uint16 OTHER_ENDIAN_HEADER_STREAM_ID = 0x0010; //--------------------------------------------------------------------- Serializer::Serializer() : - mVersion("[Serializer_v1.00]"), // Version number - mFlipEndian(false) + mVersion("[Serializer_v1.00]"), // Version number + mFlipEndian(false) #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - , mReportChunkErrors(true) + , mReportChunkErrors(true) #endif - { + { } //--------------------------------------------------------------------- @@ -53,19 +53,19 @@ namespace Ogre { { } //--------------------------------------------------------------------- - void Serializer::determineEndianness(DataStreamPtr& stream) - { - if (stream->tell() != 0) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Can only determine the endianness of the input stream if it " - "is at the start", "Serializer::determineEndianness"); - } - - uint16 dest; - // read header id manually (no conversion) + void Serializer::determineEndianness(DataStreamPtr& stream) + { + if (stream->tell() != 0) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Can only determine the endianness of the input stream if it " + "is at the start", "Serializer::determineEndianness"); + } + + uint16 dest; + // read header id manually (no conversion) size_t actually_read = stream->read(&dest, sizeof(uint16)); - // skip back + // skip back stream->skip(0 - (long)actually_read); if (actually_read != sizeof(uint16)) { @@ -74,45 +74,45 @@ namespace Ogre { "Couldn't read 16 bit header value from input stream.", "Serializer::determineEndianness"); } - if (dest == HEADER_STREAM_ID) - { - mFlipEndian = false; - } - else if (dest == OTHER_ENDIAN_HEADER_STREAM_ID) - { - mFlipEndian = true; - } - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Header chunk didn't match either endian: Corrupted stream?", - "Serializer::determineEndianness"); - } - } + if (dest == HEADER_STREAM_ID) + { + mFlipEndian = false; + } + else if (dest == OTHER_ENDIAN_HEADER_STREAM_ID) + { + mFlipEndian = true; + } + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Header chunk didn't match either endian: Corrupted stream?", + "Serializer::determineEndianness"); + } + } //--------------------------------------------------------------------- - void Serializer::determineEndianness(Endian requestedEndian) - { - switch(requestedEndian) - { - case ENDIAN_NATIVE: - mFlipEndian = false; - break; - case ENDIAN_BIG: + void Serializer::determineEndianness(Endian requestedEndian) + { + switch(requestedEndian) + { + case ENDIAN_NATIVE: + mFlipEndian = false; + break; + case ENDIAN_BIG: #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - mFlipEndian = false; + mFlipEndian = false; #else - mFlipEndian = true; + mFlipEndian = true; #endif - break; - case ENDIAN_LITTLE: + break; + case ENDIAN_LITTLE: #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - mFlipEndian = true; + mFlipEndian = true; #else - mFlipEndian = false; + mFlipEndian = false; #endif - break; - } - } + break; + } + } //--------------------------------------------------------------------- void Serializer::writeFileHeader(void) { @@ -127,24 +127,24 @@ namespace Ogre { void Serializer::writeChunkHeader(uint16 id, size_t size) { #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - if (!mChunkSizeStack.empty()){ - size_t pos = mStream->tell(); - if (pos != static_cast(mChunkSizeStack.back()) && mReportChunkErrors){ - LogManager::getSingleton().logMessage("Corrupted chunk detected! Stream name: '" + mStream->getName() - + "' Chunk id: " + StringConverter::toString(id)); - } - mChunkSizeStack.back() = pos + size; - } + if (!mChunkSizeStack.empty()){ + size_t pos = mStream->tell(); + if (pos != static_cast(mChunkSizeStack.back()) && mReportChunkErrors){ + LogManager::getSingleton().logMessage("Corrupted chunk detected! Stream name: '" + mStream->getName() + + "' Chunk id: " + StringConverter::toString(id)); + } + mChunkSizeStack.back() = pos + size; + } #endif writeShorts(&id, 1); - uint32 uint32size = static_cast(size); + uint32 uint32size = static_cast(size); writeInts(&uint32size, 1); } //--------------------------------------------------------------------- void Serializer::writeFloats(const float* const pFloat, size_t count) { - if (mFlipEndian) - { + if (mFlipEndian) + { float * pFloatToWrite = (float *)malloc(sizeof(float) * count); memcpy(pFloatToWrite, pFloat, sizeof(float) * count); @@ -152,37 +152,37 @@ namespace Ogre { writeData(pFloatToWrite, sizeof(float), count); free(pFloatToWrite); - } - else - { + } + else + { writeData(pFloat, sizeof(float), count); - } + } } //--------------------------------------------------------------------- void Serializer::writeFloats(const double* const pDouble, size_t count) { - // Convert to float, then write - float* tmp = OGRE_ALLOC_T(float, count, MEMCATEGORY_GENERAL); - for (unsigned int i = 0; i < count; ++i) - { - tmp[i] = static_cast(pDouble[i]); - } - if(mFlipEndian) - { + // Convert to float, then write + float* tmp = OGRE_ALLOC_T(float, count, MEMCATEGORY_GENERAL); + for (unsigned int i = 0; i < count; ++i) + { + tmp[i] = static_cast(pDouble[i]); + } + if(mFlipEndian) + { flipToLittleEndian(tmp, sizeof(float), count); writeData(tmp, sizeof(float), count); - } - else - { + } + else + { writeData(tmp, sizeof(float), count); - } - OGRE_FREE(tmp, MEMCATEGORY_GENERAL); + } + OGRE_FREE(tmp, MEMCATEGORY_GENERAL); } //--------------------------------------------------------------------- void Serializer::writeShorts(const uint16* const pShort, size_t count = 1) { - if(mFlipEndian) - { + if(mFlipEndian) + { unsigned short * pShortToWrite = (unsigned short *)malloc(sizeof(unsigned short) * count); memcpy(pShortToWrite, pShort, sizeof(unsigned short) * count); @@ -190,17 +190,17 @@ namespace Ogre { writeData(pShortToWrite, sizeof(unsigned short), count); free(pShortToWrite); - } - else - { + } + else + { writeData(pShort, sizeof(unsigned short), count); - } + } } //--------------------------------------------------------------------- void Serializer::writeInts(const uint32* const pInt, size_t count = 1) { - if(mFlipEndian) - { + if(mFlipEndian) + { uint32 * pIntToWrite = (uint32 *)malloc(sizeof(uint32) * count); memcpy(pIntToWrite, pInt, sizeof(uint32) * count); @@ -208,11 +208,11 @@ namespace Ogre { writeData(pIntToWrite, sizeof(uint32), count); free(pIntToWrite); - } - else - { + } + else + { writeData(pInt, sizeof(uint32), count); - } + } } //--------------------------------------------------------------------- //--------------------------------------------------------------------- @@ -220,7 +220,7 @@ namespace Ogre { { //no endian flipping for 1-byte bools //XXX Nasty Hack to convert to 1-byte bools -# if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS +# if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS char * pCharToWrite = (char *)malloc(sizeof(char) * count); for(unsigned int i = 0; i < count; i++) { @@ -230,25 +230,25 @@ namespace Ogre { writeData(pCharToWrite, sizeof(char), count); free(pCharToWrite); -# else +# else writeData(pBool, sizeof(bool), count); -# endif +# endif } //--------------------------------------------------------------------- void Serializer::writeData(const void* const buf, size_t size, size_t count) { - mStream->write(buf, size * count); + mStream->write(buf, size * count); } //--------------------------------------------------------------------- void Serializer::writeString(const String& string) { - // Old, backwards compatible way - \n terminated - mStream->write(string.c_str(), string.length()); - // Write terminating newline char - char terminator = '\n'; - mStream->write(&terminator, 1); + // Old, backwards compatible way - \n terminated + mStream->write(string.c_str(), string.length()); + // Write terminating newline char + char terminator = '\n'; + mStream->write(&terminator, 1); } //--------------------------------------------------------------------- void Serializer::readFileHeader(DataStreamPtr& stream) @@ -281,19 +281,19 @@ namespace Ogre { unsigned short Serializer::readChunk(DataStreamPtr& stream) { #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - size_t pos = stream->tell(); + size_t pos = stream->tell(); #endif unsigned short id; readShorts(stream, &id, 1); readInts(stream, &mCurrentstreamLen, 1); #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - if (!mChunkSizeStack.empty() && !stream->eof()){ + if (!mChunkSizeStack.empty() && !stream->eof()){ if (pos != static_cast(mChunkSizeStack.back()) && mReportChunkErrors){ - LogManager::getSingleton().logMessage("Corrupted chunk detected! Stream name: '" + stream->getName() + "' Chunk id: " + StringConverter::toString(id)); - } - mChunkSizeStack.back() = pos + mCurrentstreamLen; - } + LogManager::getSingleton().logMessage("Corrupted chunk detected! Stream name: '" + stream->getName() + "' Chunk id: " + StringConverter::toString(id)); + } + mChunkSizeStack.back() = pos + mCurrentstreamLen; + } #endif return id; } @@ -301,16 +301,16 @@ namespace Ogre { void Serializer::readBools(DataStreamPtr& stream, bool* pDest, size_t count) { //XXX Nasty Hack to convert 1 byte bools to 4 byte bools -# if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS +# if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS char * pTemp = (char *)malloc(1*count); // to hold 1-byte bools stream->read(pTemp, 1 * count); for(unsigned int i = 0; i < count; i++) *(bool *)(pDest + i) = *(char *)(pTemp + i); free (pTemp); -# else +# else stream->read(pDest, sizeof(bool) * count); -# endif +# endif //no flipping on 1-byte datatypes } //--------------------------------------------------------------------- @@ -322,17 +322,17 @@ namespace Ogre { //--------------------------------------------------------------------- void Serializer::readFloats(DataStreamPtr& stream, double* pDest, size_t count) { - // Read from float, convert to double - float* tmp = OGRE_ALLOC_T(float, count, MEMCATEGORY_GENERAL); - float* ptmp = tmp; + // Read from float, convert to double + float* tmp = OGRE_ALLOC_T(float, count, MEMCATEGORY_GENERAL); + float* ptmp = tmp; stream->read(tmp, sizeof(float) * count); flipFromLittleEndian(tmp, sizeof(float), count); - // Convert to doubles (no cast required) - while(count--) - { - *pDest++ = *ptmp++; - } - OGRE_FREE(tmp, MEMCATEGORY_GENERAL); + // Convert to doubles (no cast required) + while(count--) + { + *pDest++ = *ptmp++; + } + OGRE_FREE(tmp, MEMCATEGORY_GENERAL); } //--------------------------------------------------------------------- void Serializer::readShorts(DataStreamPtr& stream, unsigned short* pDest, size_t count) @@ -396,18 +396,18 @@ namespace Ogre { void Serializer::flipToLittleEndian(void* pData, size_t size, size_t count) { - if(mFlipEndian) - { - flipEndian(pData, size, count); - } + if(mFlipEndian) + { + flipEndian(pData, size, count); + } } void Serializer::flipFromLittleEndian(void* pData, size_t size, size_t count) { - if(mFlipEndian) - { - flipEndian(pData, size, count); - } + if(mFlipEndian) + { + flipEndian(pData, size, count); + } } void Serializer::flipEndian(void * pData, size_t size, size_t count) @@ -428,45 +428,45 @@ namespace Ogre { } } - size_t Serializer::calcChunkHeaderSize() - { - return sizeof(uint16) + sizeof(uint32); - } + size_t Serializer::calcChunkHeaderSize() + { + return sizeof(uint16) + sizeof(uint32); + } - size_t Serializer::calcStringSize( const String& string ) - { - // string + terminating \n character - return string.length() + 1; - } + size_t Serializer::calcStringSize( const String& string ) + { + // string + terminating \n character + return string.length() + 1; + } - void Serializer::pushInnerChunk(const DataStreamPtr& stream) - { + void Serializer::pushInnerChunk(const DataStreamPtr& stream) + { #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - mChunkSizeStack.push_back(stream->tell()); + mChunkSizeStack.push_back(stream->tell()); #endif - } - void Serializer::backpedalChunkHeader(DataStreamPtr& stream) - { - if (!stream->eof()){ - stream->skip(-(int)calcChunkHeaderSize()); - } + } + void Serializer::backpedalChunkHeader(DataStreamPtr& stream) + { + if (!stream->eof()){ + stream->skip(-(int)calcChunkHeaderSize()); + } #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - mChunkSizeStack.back() = stream->tell(); + mChunkSizeStack.back() = stream->tell(); #endif - } - void Serializer::popInnerChunk(const DataStreamPtr& stream) - { + } + void Serializer::popInnerChunk(const DataStreamPtr& stream) + { #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - if (!mChunkSizeStack.empty()){ - size_t pos = stream->tell(); + if (!mChunkSizeStack.empty()){ + size_t pos = stream->tell(); if (pos != static_cast(mChunkSizeStack.back()) && !stream->eof() && mReportChunkErrors){ - LogManager::getSingleton().logMessage("Corrupted chunk detected! Stream name: " + stream->getName()); - } + LogManager::getSingleton().logMessage("Corrupted chunk detected! Stream name: " + stream->getName()); + } - mChunkSizeStack.pop_back(); - } + mChunkSizeStack.pop_back(); + } #endif - } + } } diff --git a/OgreMain/src/OgreShadowCameraSetup.cpp b/OgreMain/src/OgreShadowCameraSetup.cpp index 0bc2bfe25b3..05392aaf783 100644 --- a/OgreMain/src/OgreShadowCameraSetup.cpp +++ b/OgreMain/src/OgreShadowCameraSetup.cpp @@ -37,171 +37,171 @@ THE SOFTWARE. namespace Ogre { - /// Default constructor - DefaultShadowCameraSetup::DefaultShadowCameraSetup() {} - - /// Destructor - DefaultShadowCameraSetup::~DefaultShadowCameraSetup() {} - - /// Default shadow camera setup implementation - void DefaultShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, - const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const - { - Vector3 pos, dir; - - // reset custom view / projection matrix in case already set - texCam->setCustomViewMatrix(false); - texCam->setCustomProjectionMatrix(false); - texCam->setNearClipDistance(light->_deriveShadowNearClipDistance(cam)); - texCam->setFarClipDistance(light->_deriveShadowFarClipDistance(cam)); - - // get the shadow frustum's far distance - Real shadowDist = light->getShadowFarDistance(); - if (!shadowDist) - { - // need a shadow distance, make one up - shadowDist = cam->getNearClipDistance() * 300; - } - Real shadowOffset = shadowDist * (sm->getShadowDirLightTextureOffset()); - - // Directional lights - if (light->getType() == Light::LT_DIRECTIONAL) - { - // set up the shadow texture - // Set ortho projection - texCam->setProjectionType(PT_ORTHOGRAPHIC); - // set ortho window so that texture covers far dist - texCam->setOrthoWindow(shadowDist * 2, shadowDist * 2); - - // Calculate look at position - // We want to look at a spot shadowOffset away from near plane - // 0.5 is a little too close for angles - Vector3 target = cam->getDerivedPosition() + - (cam->getDerivedDirection() * shadowOffset); - - // Calculate direction, which same as directional light direction - dir = - light->getDerivedDirection(); // backwards since point down -z - dir.normalise(); - - // Calculate position - // We want to be in the -ve direction of the light direction - // far enough to project for the dir light extrusion distance - pos = target + dir * sm->getShadowDirectionalLightExtrusionDistance(); - - // Round local x/y position based on a world-space texel; this helps to reduce - // jittering caused by the projection moving with the camera - // Viewport is 2 * near clip distance across (90 degree fov) - //~ Real worldTexelSize = (texCam->getNearClipDistance() * 20) / vp->getActualWidth(); - //~ pos.x -= fmod(pos.x, worldTexelSize); - //~ pos.y -= fmod(pos.y, worldTexelSize); - //~ pos.z -= fmod(pos.z, worldTexelSize); - Real worldTexelSize = (shadowDist * 2) / texCam->getViewport()->getActualWidth(); - - //get texCam orientation - - Vector3 up = Vector3::UNIT_Y; - // Check it's not coincident with dir - if (Math::Abs(up.dotProduct(dir)) >= 1.0f) - { - // Use camera up - up = Vector3::UNIT_Z; - } - // cross twice to rederive, only direction is unaltered - Vector3 left = dir.crossProduct(up); - left.normalise(); - up = dir.crossProduct(left); - up.normalise(); - // Derive quaternion from axes - Quaternion q; - q.FromAxes(left, up, dir); - - //convert world space camera position into light space - Vector3 lightSpacePos = q.Inverse() * pos; - - //snap to nearest texel - lightSpacePos.x -= fmod(lightSpacePos.x, worldTexelSize); - lightSpacePos.y -= fmod(lightSpacePos.y, worldTexelSize); - - //convert back to world space - pos = q * lightSpacePos; - - } - // Spotlight - else if (light->getType() == Light::LT_SPOTLIGHT) - { - // Set perspective projection - texCam->setProjectionType(PT_PERSPECTIVE); - // set FOV slightly larger than the spotlight range to ensure coverage - Radian fovy = light->getSpotlightOuterAngle()*1.2; - // limit angle - if (fovy.valueDegrees() > 175) - fovy = Degree(175); - texCam->setFOVy(fovy); - - // Calculate position, which same as spotlight position - pos = light->getDerivedPosition(); - - // Calculate direction, which same as spotlight direction - dir = - light->getDerivedDirection(); // backwards since point down -z - dir.normalise(); - } - // Point light - else - { - // Set perspective projection - texCam->setProjectionType(PT_PERSPECTIVE); - // Use 120 degree FOV for point light to ensure coverage more area - texCam->setFOVy(Degree(120)); - - // Calculate look at position - // We want to look at a spot shadowOffset away from near plane - // 0.5 is a little too close for angles - Vector3 target = cam->getDerivedPosition() + - (cam->getDerivedDirection() * shadowOffset); - - // Calculate position, which same as point light position - pos = light->getDerivedPosition(); - - dir = (pos - target); // backwards since point down -z - dir.normalise(); - } - - // Finally set position - texCam->setPosition(pos); - - // Calculate orientation based on direction calculated above - /* - // Next section (camera oriented shadow map) abandoned - // Always point in the same direction, if we don't do this then - // we get 'shadow swimming' as camera rotates - // As it is, we get swimming on moving but this is less noticeable - - // calculate up vector, we want it aligned with cam direction - Vector3 up = cam->getDerivedDirection(); - // Check it's not coincident with dir - if (up.dotProduct(dir) >= 1.0f) - { - // Use camera up - up = cam->getUp(); - } - */ - Vector3 up = Vector3::UNIT_Y; - // Check it's not coincident with dir - if (Math::Abs(up.dotProduct(dir)) >= 1.0f) - { - // Use camera up - up = Vector3::UNIT_Z; - } - // cross twice to rederive, only direction is unaltered - Vector3 left = dir.crossProduct(up); - left.normalise(); - up = dir.crossProduct(left); - up.normalise(); - // Derive quaternion from axes - Quaternion q; - q.FromAxes(left, up, dir); - texCam->setOrientation(q); - } + /// Default constructor + DefaultShadowCameraSetup::DefaultShadowCameraSetup() {} + + /// Destructor + DefaultShadowCameraSetup::~DefaultShadowCameraSetup() {} + + /// Default shadow camera setup implementation + void DefaultShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, + const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const + { + Vector3 pos, dir; + + // reset custom view / projection matrix in case already set + texCam->setCustomViewMatrix(false); + texCam->setCustomProjectionMatrix(false); + texCam->setNearClipDistance(light->_deriveShadowNearClipDistance(cam)); + texCam->setFarClipDistance(light->_deriveShadowFarClipDistance(cam)); + + // get the shadow frustum's far distance + Real shadowDist = light->getShadowFarDistance(); + if (!shadowDist) + { + // need a shadow distance, make one up + shadowDist = cam->getNearClipDistance() * 300; + } + Real shadowOffset = shadowDist * (sm->getShadowDirLightTextureOffset()); + + // Directional lights + if (light->getType() == Light::LT_DIRECTIONAL) + { + // set up the shadow texture + // Set ortho projection + texCam->setProjectionType(PT_ORTHOGRAPHIC); + // set ortho window so that texture covers far dist + texCam->setOrthoWindow(shadowDist * 2, shadowDist * 2); + + // Calculate look at position + // We want to look at a spot shadowOffset away from near plane + // 0.5 is a little too close for angles + Vector3 target = cam->getDerivedPosition() + + (cam->getDerivedDirection() * shadowOffset); + + // Calculate direction, which same as directional light direction + dir = - light->getDerivedDirection(); // backwards since point down -z + dir.normalise(); + + // Calculate position + // We want to be in the -ve direction of the light direction + // far enough to project for the dir light extrusion distance + pos = target + dir * sm->getShadowDirectionalLightExtrusionDistance(); + + // Round local x/y position based on a world-space texel; this helps to reduce + // jittering caused by the projection moving with the camera + // Viewport is 2 * near clip distance across (90 degree fov) + //~ Real worldTexelSize = (texCam->getNearClipDistance() * 20) / vp->getActualWidth(); + //~ pos.x -= fmod(pos.x, worldTexelSize); + //~ pos.y -= fmod(pos.y, worldTexelSize); + //~ pos.z -= fmod(pos.z, worldTexelSize); + Real worldTexelSize = (shadowDist * 2) / texCam->getViewport()->getActualWidth(); + + //get texCam orientation + + Vector3 up = Vector3::UNIT_Y; + // Check it's not coincident with dir + if (Math::Abs(up.dotProduct(dir)) >= 1.0f) + { + // Use camera up + up = Vector3::UNIT_Z; + } + // cross twice to rederive, only direction is unaltered + Vector3 left = dir.crossProduct(up); + left.normalise(); + up = dir.crossProduct(left); + up.normalise(); + // Derive quaternion from axes + Quaternion q; + q.FromAxes(left, up, dir); + + //convert world space camera position into light space + Vector3 lightSpacePos = q.Inverse() * pos; + + //snap to nearest texel + lightSpacePos.x -= fmod(lightSpacePos.x, worldTexelSize); + lightSpacePos.y -= fmod(lightSpacePos.y, worldTexelSize); + + //convert back to world space + pos = q * lightSpacePos; + + } + // Spotlight + else if (light->getType() == Light::LT_SPOTLIGHT) + { + // Set perspective projection + texCam->setProjectionType(PT_PERSPECTIVE); + // set FOV slightly larger than the spotlight range to ensure coverage + Radian fovy = light->getSpotlightOuterAngle()*1.2; + // limit angle + if (fovy.valueDegrees() > 175) + fovy = Degree(175); + texCam->setFOVy(fovy); + + // Calculate position, which same as spotlight position + pos = light->getDerivedPosition(); + + // Calculate direction, which same as spotlight direction + dir = - light->getDerivedDirection(); // backwards since point down -z + dir.normalise(); + } + // Point light + else + { + // Set perspective projection + texCam->setProjectionType(PT_PERSPECTIVE); + // Use 120 degree FOV for point light to ensure coverage more area + texCam->setFOVy(Degree(120)); + + // Calculate look at position + // We want to look at a spot shadowOffset away from near plane + // 0.5 is a little too close for angles + Vector3 target = cam->getDerivedPosition() + + (cam->getDerivedDirection() * shadowOffset); + + // Calculate position, which same as point light position + pos = light->getDerivedPosition(); + + dir = (pos - target); // backwards since point down -z + dir.normalise(); + } + + // Finally set position + texCam->setPosition(pos); + + // Calculate orientation based on direction calculated above + /* + // Next section (camera oriented shadow map) abandoned + // Always point in the same direction, if we don't do this then + // we get 'shadow swimming' as camera rotates + // As it is, we get swimming on moving but this is less noticeable + + // calculate up vector, we want it aligned with cam direction + Vector3 up = cam->getDerivedDirection(); + // Check it's not coincident with dir + if (up.dotProduct(dir) >= 1.0f) + { + // Use camera up + up = cam->getUp(); + } + */ + Vector3 up = Vector3::UNIT_Y; + // Check it's not coincident with dir + if (Math::Abs(up.dotProduct(dir)) >= 1.0f) + { + // Use camera up + up = Vector3::UNIT_Z; + } + // cross twice to rederive, only direction is unaltered + Vector3 left = dir.crossProduct(up); + left.normalise(); + up = dir.crossProduct(left); + up.normalise(); + // Derive quaternion from axes + Quaternion q; + q.FromAxes(left, up, dir); + texCam->setOrientation(q); + } } diff --git a/OgreMain/src/OgreShadowCameraSetupFocused.cpp b/OgreMain/src/OgreShadowCameraSetupFocused.cpp index a8adef9dec7..191ec50386a 100644 --- a/OgreMain/src/OgreShadowCameraSetupFocused.cpp +++ b/OgreMain/src/OgreShadowCameraSetupFocused.cpp @@ -5,7 +5,7 @@ This source file is part of OGRE For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd -Copyright (c) 2006 Matthias Fink, netAllied GmbH +Copyright (c) 2006 Matthias Fink, netAllied GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -38,641 +38,641 @@ THE SOFTWARE. namespace Ogre { - /** transform from normal to light space */ - const Matrix4 FocusedShadowCameraSetup::msNormalToLightSpace( - 1, 0, 0, 0, // x - 0, 0, -1, 0, // y - 0, 1, 0, 0, // z - 0, 0, 0, 1); // w - /** transform from light to normal space */ - const Matrix4 FocusedShadowCameraSetup::msLightSpaceToNormal( - 1, 0, 0, 0, // x - 0, 0, 1, 0, // y - 0, -1, 0, 0, // z - 0, 0, 0, 1); // w - - FocusedShadowCameraSetup::FocusedShadowCameraSetup(void) - : mTempFrustum(OGRE_NEW Frustum()) - , mLightFrustumCamera(OGRE_NEW Camera("TEMP LIGHT INTERSECT CAM", NULL)) - , mLightFrustumCameraCalculated(false) - , mUseAggressiveRegion(true) - { - mTempFrustum->setProjectionType(PT_PERSPECTIVE); - } - //----------------------------------------------------------------------- - FocusedShadowCameraSetup::~FocusedShadowCameraSetup(void) - { - OGRE_DELETE mTempFrustum; - OGRE_DELETE mLightFrustumCamera; - } - //----------------------------------------------------------------------- - void FocusedShadowCameraSetup::calculateShadowMappingMatrix(const SceneManager& sm, - const Camera& cam, const Light& light, Matrix4 *out_view, Matrix4 *out_proj, - Camera *out_cam) const - { - // get the shadow frustum's far distance - Real shadowDist = light.getShadowFarDistance(); - if (!shadowDist) - { - // need a shadow distance, make one up - shadowDist = cam.getNearClipDistance() * 3000; - } - Real shadowOffset = shadowDist * sm.getShadowDirLightTextureOffset(); - - - if (light.getType() == Light::LT_DIRECTIONAL) - { - // generate view matrix if requested - if (out_view != NULL) - { - Vector3 pos; - if (sm.getCameraRelativeRendering()) - { - pos = Vector3::ZERO; - } - else - { - pos = cam.getDerivedPosition(); - } - *out_view = buildViewMatrix(pos, - light.getDerivedDirection(), - cam.getDerivedUp()); - } - - // generate projection matrix if requested - if (out_proj != NULL) - { - *out_proj = Matrix4::getScale(1, 1, -1); - //*out_proj = Matrix4::IDENTITY; - } - - // set up camera if requested - if (out_cam != NULL) - { - out_cam->setProjectionType(PT_ORTHOGRAPHIC); - out_cam->setDirection(light.getDerivedDirection()); - out_cam->setPosition(cam.getDerivedPosition()); - out_cam->setFOVy(Degree(90)); - out_cam->setNearClipDistance(shadowOffset); - } - } - else if (light.getType() == Light::LT_POINT) - { - // target analogue to the default shadow textures - // Calculate look at position - // We want to look at a spot shadowOffset away from near plane - // 0.5 is a little too close for angles - Vector3 target = cam.getDerivedPosition() + - (cam.getDerivedDirection() * shadowOffset); - Vector3 lightDir = target - light.getDerivedPosition(); - lightDir.normalise(); - - // generate view matrix if requested - if (out_view != NULL) - { - *out_view = buildViewMatrix(light.getDerivedPosition(), - lightDir, - cam.getDerivedUp()); - } - - // generate projection matrix if requested - if (out_proj != NULL) - { - // set FOV to 120 degrees - mTempFrustum->setFOVy(Degree(120)); - - mTempFrustum->setNearClipDistance(light._deriveShadowNearClipDistance(&cam)); - mTempFrustum->setFarClipDistance(light._deriveShadowFarClipDistance(&cam)); - - *out_proj = mTempFrustum->getProjectionMatrix(); - } - - // set up camera if requested - if (out_cam != NULL) - { - out_cam->setProjectionType(PT_PERSPECTIVE); - out_cam->setDirection(lightDir); - out_cam->setPosition(light.getDerivedPosition()); - out_cam->setFOVy(Degree(120)); - out_cam->setNearClipDistance(light._deriveShadowNearClipDistance(&cam)); - out_cam->setFarClipDistance(light._deriveShadowFarClipDistance(&cam)); - } - } - else if (light.getType() == Light::LT_SPOTLIGHT) - { - // generate view matrix if requested - if (out_view != NULL) - { - *out_view = buildViewMatrix(light.getDerivedPosition(), - light.getDerivedDirection(), - cam.getDerivedUp()); - } - - // generate projection matrix if requested - if (out_proj != NULL) - { - // set FOV slightly larger than spotlight range - mTempFrustum->setFOVy(Ogre::Math::Clamp(light.getSpotlightOuterAngle() * 1.2, Radian(0), Radian(Math::PI/2.0f))); - - mTempFrustum->setNearClipDistance(light._deriveShadowNearClipDistance(&cam)); - mTempFrustum->setFarClipDistance(light._deriveShadowFarClipDistance(&cam)); - - *out_proj = mTempFrustum->getProjectionMatrix(); - } - - // set up camera if requested - if (out_cam != NULL) - { - out_cam->setProjectionType(PT_PERSPECTIVE); - out_cam->setDirection(light.getDerivedDirection()); - out_cam->setPosition(light.getDerivedPosition()); - out_cam->setFOVy(Ogre::Math::Clamp(light.getSpotlightOuterAngle() * 1.2, Radian(0), Radian(Math::PI/2.0f))); - out_cam->setNearClipDistance(light._deriveShadowNearClipDistance(&cam)); - out_cam->setFarClipDistance(light._deriveShadowFarClipDistance(&cam)); - } - } - } - //----------------------------------------------------------------------- - void FocusedShadowCameraSetup::calculateB(const SceneManager& sm, const Camera& cam, - const Light& light, const AxisAlignedBox& sceneBB, const AxisAlignedBox& receiverBB, - PointListBody *out_bodyB) const - { - OgreAssert(out_bodyB != NULL, "bodyB vertex list is NULL"); - - /// perform convex intersection of the form B = ((V \cap S) + l) \cap S \cap L - - // get V - mBodyB.define(cam); - - if (light.getType() != Light::LT_DIRECTIONAL) - { - // clip bodyB with sceneBB - /* Note, Matthias' original code states this: - "The procedure ((V \cap S) + l) \cap S \cap L (Wimmer et al.) leads in some - cases to disappearing shadows. Valid parts of the scene are clipped, so shadows - are partly incomplete. The cause may be the transformation into light space that - is only done for the corner points which may not contain the whole scene afterwards - any more. So we fall back to the method of Stamminger et al. (V + l) \cap S \cap L - which does not show these anomalies." - - .. leading to the commenting out of the below clip. However, ift makes a major - difference to the quality of the focus, and so far I haven't noticed - the clipping issues described. Intuitively I would have thought that - any clipping issue would be due to the findCastersForLight not being - quite right, since if the sceneBB includes those there is no reason for - this clip instruction to omit a genuine shadow caster. - - I have made this a user option since the quality effect is major and - the clipping problem only seems to occur in some specific cases. - */ - if (mUseAggressiveRegion) - mBodyB.clip(sceneBB); - - // form a convex hull of bodyB with the light position - mBodyB.extend(light.getDerivedPosition()); - - // clip bodyB with sceneBB - mBodyB.clip(sceneBB); - - // clip with the light frustum - // set up light camera to clip with the resulting frustum planes - if (!mLightFrustumCameraCalculated) - { - calculateShadowMappingMatrix(sm, cam, light, NULL, NULL, mLightFrustumCamera); - mLightFrustumCameraCalculated = true; - } - mBodyB.clip(*mLightFrustumCamera); - - // extract bodyB vertices - out_bodyB->build(mBodyB); - - } - else - { - // For directional lights, all we care about is projecting the receivers - // backwards towards the light, clipped by the camera region - mBodyB.clip(receiverBB); - - // Also clip based on shadow far distance if appropriate - Real farDist = light.getShadowFarDistance(); - if (farDist) - { - Vector3 pointOnPlane = cam.getDerivedPosition() + - (cam.getDerivedDirection() * farDist); - Plane p(cam.getDerivedDirection(), pointOnPlane); - mBodyB.clip(p); - } - - // Extrude the intersection bodyB into the inverted light direction and store - // the info in the point list. - // Maximum extrusion extent is to the shadow far distance - out_bodyB->buildAndIncludeDirection(mBodyB, - farDist ? farDist : cam.getNearClipDistance() * 3000, - -light.getDerivedDirection()); - } - } - - //----------------------------------------------------------------------- - void FocusedShadowCameraSetup::calculateLVS(const SceneManager& sm, const Camera& cam, - const Light& light, const AxisAlignedBox& sceneBB, PointListBody *out_LVS) const - { - ConvexBody bodyLVS; - - // init body with view frustum - bodyLVS.define(cam); - - // clip the body with the light frustum (point + spot) - // for a directional light the space of the intersected - // view frustum and sceneBB is always lighted and in front - // of the viewer. - if (light.getType() != Light::LT_DIRECTIONAL) - { - // clip with the light frustum - // set up light camera to clip the resulting frustum - if (!mLightFrustumCameraCalculated) - { - calculateShadowMappingMatrix(sm, cam, light, NULL, NULL, mLightFrustumCamera); - mLightFrustumCameraCalculated = true; - } - bodyLVS.clip(*mLightFrustumCamera); - } - - // clip the body with the scene bounding box - bodyLVS.clip(sceneBB); - - // extract bodyLVS vertices - out_LVS->build(bodyLVS); - } - //----------------------------------------------------------------------- - Vector3 FocusedShadowCameraSetup::getLSProjViewDir(const Matrix4& lightSpace, - const Camera& cam, const PointListBody& bodyLVS) const - { - // goal is to construct a view direction - // because parallel lines are not parallel any more after perspective projection we have to transform - // a ray to point us the viewing direction - - // fetch a point near the camera - const Vector3 e_world = getNearCameraPoint_ws(cam.getViewMatrix(), bodyLVS); - - // plus the direction results in a second point - const Vector3 b_world = e_world + cam.getDerivedDirection(); - - // transformation into light space - const Vector3 e_ls = lightSpace * e_world; - const Vector3 b_ls = lightSpace * b_world; - - // calculate the projection direction, which is the subtraction of - // b_ls from e_ls. The y component is set to 0 to project the view - // direction into the shadow map plane. - Vector3 projectionDir(b_ls - e_ls); - projectionDir.y = 0; - - // deal with Y-only vectors - return Math::RealEqual(projectionDir.length(), 0.0) ? - Vector3::NEGATIVE_UNIT_Z : projectionDir.normalisedCopy(); - } - //----------------------------------------------------------------------- - Vector3 FocusedShadowCameraSetup::getNearCameraPoint_ws(const Matrix4& viewMatrix, - const PointListBody& bodyLVS) const - { - if (bodyLVS.getPointCount() == 0) - return Vector3(0,0,0); - - Vector3 nearEye = viewMatrix * bodyLVS.getPoint(0), // for comparison - nearWorld = bodyLVS.getPoint(0); // represents the final point - - // store the vertex with the highest z-value which is the nearest point - for (size_t i = 1; i < bodyLVS.getPointCount(); ++i) - { - const Vector3& vWorld = bodyLVS.getPoint(i); - - // comparison is done from the viewer - Vector3 vEye = viewMatrix * vWorld; - - if (vEye.z > nearEye.z) - { - nearEye = vEye; - nearWorld = vWorld; - } - } - - return nearWorld; - } - //----------------------------------------------------------------------- - Matrix4 FocusedShadowCameraSetup::transformToUnitCube(const Matrix4& m, - const PointListBody& body) const - { - // map the transformed body AAB points to the unit cube (-1/-1/-1) / (+1/+1/+1) corners - AxisAlignedBox aab_trans; - - for (size_t i = 0; i < body.getPointCount(); ++i) - { - aab_trans.merge(m * body.getPoint(i)); - } - - Vector3 vMin, vMax; - - vMin = aab_trans.getMinimum(); - vMax = aab_trans.getMaximum(); - - const Vector3 trans(-(vMax.x + vMin.x) / (vMax.x - vMin.x), - -(vMax.y + vMin.y) / (vMax.y - vMin.y), - -(vMax.z + vMin.z) / (vMax.z - vMin.z)); - - const Vector3 scale(2 / (vMax.x - vMin.x), - 2 / (vMax.y - vMin.y), - 2 / (vMax.z - vMin.z)); - - Matrix4 mOut(Matrix4::IDENTITY); - mOut.setTrans(trans); - mOut.setScale(scale); - - return mOut; - } - //----------------------------------------------------------------------- - Matrix4 FocusedShadowCameraSetup::buildViewMatrix(const Vector3& pos, const Vector3& dir, - const Vector3& up) const - { - Vector3 xN = dir.crossProduct(up); - xN.normalise(); - Vector3 upN = xN.crossProduct(dir); - upN.normalise(); - - Matrix4 m(xN.x, xN.y, xN.z, -xN.dotProduct(pos), - upN.x, upN.y, upN.z, -upN.dotProduct(pos), - -dir.x, -dir.y, -dir.z, dir.dotProduct(pos), - 0.0, 0.0, 0.0, 1.0 - ); - - return m; - } - //----------------------------------------------------------------------- - void FocusedShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, - const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const - { - // check availability - viewport not needed - OgreAssert(sm != NULL, "SceneManager is NULL"); - OgreAssert(cam != NULL, "Camera (viewer) is NULL"); - OgreAssert(light != NULL, "Light is NULL"); - OgreAssert(texCam != NULL, "Camera (texture) is NULL"); - mLightFrustumCameraCalculated = false; - - texCam->setNearClipDistance(light->_deriveShadowNearClipDistance(cam)); - texCam->setFarClipDistance(light->_deriveShadowFarClipDistance(cam)); - - // calculate standard shadow mapping matrix - Matrix4 LView, LProj; - calculateShadowMappingMatrix(*sm, *cam, *light, &LView, &LProj, NULL); - - // build scene bounding box - const VisibleObjectsBoundsInfo& visInfo = sm->getVisibleObjectsBoundsInfo(texCam); - AxisAlignedBox sceneBB = visInfo.aabb; - AxisAlignedBox receiverAABB = sm->getVisibleObjectsBoundsInfo(cam).receiverAabb; - sceneBB.merge(receiverAABB); - sceneBB.merge(cam->getDerivedPosition()); - - // in case the sceneBB is empty (e.g. nothing visible to the cam) simply - // return the standard shadow mapping matrix - if (sceneBB.isNull()) - { - texCam->setCustomViewMatrix(true, LView); - texCam->setCustomProjectionMatrix(true, LProj); - return; - } - - // calculate the intersection body B - mPointListBodyB.reset(); - calculateB(*sm, *cam, *light, sceneBB, receiverAABB, &mPointListBodyB); - - // in case the bodyB is empty (e.g. nothing visible to the light or the cam) - // simply return the standard shadow mapping matrix - if (mPointListBodyB.getPointCount() == 0) - { - texCam->setCustomViewMatrix(true, LView); - texCam->setCustomProjectionMatrix(true, LProj); - return; - } - - // transform to light space: y -> -z, z -> y - LProj = msNormalToLightSpace * LProj; - - // calculate LVS so it does not need to be calculated twice - // calculate the body L \cap V \cap S to make sure all returned points are in - // front of the camera - mPointListBodyLVS.reset(); - calculateLVS(*sm, *cam, *light, sceneBB, &mPointListBodyLVS); - - // fetch the viewing direction - const Vector3 viewDir = getLSProjViewDir(LProj * LView, *cam, mPointListBodyLVS); - - // The light space will be rotated in such a way, that the projected light view - // always points upwards, so the up-vector is the y-axis (we already prepared the - // light space for this usage).The transformation matrix is set up with the - // following parameters: - // - position is the origin - // - the view direction is the calculated viewDir - // - the up vector is the y-axis - LProj = buildViewMatrix(Vector3::ZERO, viewDir, Vector3::UNIT_Y) * LProj; - - // map bodyB to unit cube - LProj = transformToUnitCube(LProj * LView, mPointListBodyB) * LProj; - - // transform from light space to normal space: y -> z, z -> -y - LProj = msLightSpaceToNormal * LProj; - - // set the two custom matrices - texCam->setCustomViewMatrix(true, LView); - texCam->setCustomProjectionMatrix(true, LProj); - } - - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //----------------------------------------------------------------------- - FocusedShadowCameraSetup::PointListBody::PointListBody() - { - // Preallocate some space - mBodyPoints.reserve(12); - } - //----------------------------------------------------------------------- - FocusedShadowCameraSetup::PointListBody::PointListBody(const ConvexBody& body) - { - build(body); - } - //----------------------------------------------------------------------- - FocusedShadowCameraSetup::PointListBody::~PointListBody() - { - } - //----------------------------------------------------------------------- - void FocusedShadowCameraSetup::PointListBody::merge(const PointListBody& plb) - { - size_t size = plb.getPointCount(); - for (size_t i = 0; i < size; ++i) - { - this->addPoint(plb.getPoint(i)); - } - } - //----------------------------------------------------------------------- - void FocusedShadowCameraSetup::PointListBody::build(const ConvexBody& body, bool filterDuplicates) - { - // erase list - mBodyPoints.clear(); - - // Try to reserve a representative amount of memory - mBodyPoints.reserve(body.getPolygonCount() * 6); - - // build new list - for (size_t i = 0; i < body.getPolygonCount(); ++i) - { - for (size_t j = 0; j < body.getVertexCount(i); ++j) - { - const Vector3 &vInsert = body.getVertex(i, j); - - // duplicates allowed? - if (filterDuplicates) - { - bool bPresent = false; - - for(Polygon::VertexList::iterator vit = mBodyPoints.begin(); - vit != mBodyPoints.end(); ++vit) - { - const Vector3& v = *vit; - - if (vInsert.positionEquals(v)) - { - bPresent = true; - break; - } - } - - if (bPresent == false) - { - mBodyPoints.push_back(body.getVertex(i, j)); - } - } - - // else insert directly - else - { - mBodyPoints.push_back(body.getVertex(i, j)); - } - } - } - - // update AAB - // no points altered, so take body AAB - mAAB = body.getAABB(); - } - //----------------------------------------------------------------------- - void FocusedShadowCameraSetup::PointListBody::buildAndIncludeDirection( - const ConvexBody& body, Real extrudeDist, const Vector3& dir) - { - // reset point list - this->reset(); - - // intersect the rays formed by the points in the list with the given direction and - // insert them into the list - - const size_t polyCount = body.getPolygonCount(); - for (size_t iPoly = 0; iPoly < polyCount; ++iPoly) - { - - // store the old inserted point and plane info - // if the currently processed point hits a different plane than the previous point an - // intersection point is calculated that lies on the two planes' intersection edge - - // fetch current polygon - const Polygon& p = body.getPolygon(iPoly); - - size_t pointCount = p.getVertexCount(); - for (size_t iPoint = 0; iPoint < pointCount ; ++iPoint) - { - // base point - const Vector3& pt = p.getVertex(iPoint); - - // add the base point - this->addPoint(pt); - - // intersection ray - Ray ray(pt, dir); - - const Vector3 ptIntersect = ray.getPoint(extrudeDist); - this->addPoint(ptIntersect); - - } // for: polygon point iteration - - } // for: polygon iteration - } - //----------------------------------------------------------------------- - const AxisAlignedBox& FocusedShadowCameraSetup::PointListBody::getAAB(void) const - { - return mAAB; - } - //----------------------------------------------------------------------- - void FocusedShadowCameraSetup::PointListBody::addPoint(const Vector3& point) - { - // don't check for doubles, simply add - mBodyPoints.push_back(point); - - // update AAB - mAAB.merge(point); - } - //----------------------------------------------------------------------- - void FocusedShadowCameraSetup::PointListBody::addAAB(const AxisAlignedBox& aab) - { - const Vector3& min = aab.getMinimum(); - const Vector3& max = aab.getMaximum(); - - Vector3 currentVertex = min; - // min min min - addPoint(currentVertex); - - // min min max - currentVertex.z = max.z; - addPoint(currentVertex); - - // min max max - currentVertex.y = max.y; - addPoint(currentVertex); - - // min max min - currentVertex.z = min.z; - addPoint(currentVertex); - - // max max min - currentVertex.x = max.x; - addPoint(currentVertex); - - // max max max - currentVertex.z = max.z; - addPoint(currentVertex); - - // max min max - currentVertex.y = min.y; - addPoint(currentVertex); - - // max min min - currentVertex.z = min.z; - addPoint(currentVertex); - - } - //----------------------------------------------------------------------- - const Vector3& FocusedShadowCameraSetup::PointListBody::getPoint(size_t cnt) const - { - OgreAssert(cnt < getPointCount(), "Search position out of range"); - - return mBodyPoints[ cnt ]; - } - //----------------------------------------------------------------------- - size_t FocusedShadowCameraSetup::PointListBody::getPointCount(void) const - { - return mBodyPoints.size(); - } - //----------------------------------------------------------------------- - void FocusedShadowCameraSetup::PointListBody::reset(void) - { - mBodyPoints.clear(); - mAAB.setNull(); - } + /** transform from normal to light space */ + const Matrix4 FocusedShadowCameraSetup::msNormalToLightSpace( + 1, 0, 0, 0, // x + 0, 0, -1, 0, // y + 0, 1, 0, 0, // z + 0, 0, 0, 1); // w + /** transform from light to normal space */ + const Matrix4 FocusedShadowCameraSetup::msLightSpaceToNormal( + 1, 0, 0, 0, // x + 0, 0, 1, 0, // y + 0, -1, 0, 0, // z + 0, 0, 0, 1); // w + + FocusedShadowCameraSetup::FocusedShadowCameraSetup(void) + : mTempFrustum(OGRE_NEW Frustum()) + , mLightFrustumCamera(OGRE_NEW Camera("TEMP LIGHT INTERSECT CAM", NULL)) + , mLightFrustumCameraCalculated(false) + , mUseAggressiveRegion(true) + { + mTempFrustum->setProjectionType(PT_PERSPECTIVE); + } + //----------------------------------------------------------------------- + FocusedShadowCameraSetup::~FocusedShadowCameraSetup(void) + { + OGRE_DELETE mTempFrustum; + OGRE_DELETE mLightFrustumCamera; + } + //----------------------------------------------------------------------- + void FocusedShadowCameraSetup::calculateShadowMappingMatrix(const SceneManager& sm, + const Camera& cam, const Light& light, Matrix4 *out_view, Matrix4 *out_proj, + Camera *out_cam) const + { + // get the shadow frustum's far distance + Real shadowDist = light.getShadowFarDistance(); + if (!shadowDist) + { + // need a shadow distance, make one up + shadowDist = cam.getNearClipDistance() * 3000; + } + Real shadowOffset = shadowDist * sm.getShadowDirLightTextureOffset(); + + + if (light.getType() == Light::LT_DIRECTIONAL) + { + // generate view matrix if requested + if (out_view != NULL) + { + Vector3 pos; + if (sm.getCameraRelativeRendering()) + { + pos = Vector3::ZERO; + } + else + { + pos = cam.getDerivedPosition(); + } + *out_view = buildViewMatrix(pos, + light.getDerivedDirection(), + cam.getDerivedUp()); + } + + // generate projection matrix if requested + if (out_proj != NULL) + { + *out_proj = Matrix4::getScale(1, 1, -1); + //*out_proj = Matrix4::IDENTITY; + } + + // set up camera if requested + if (out_cam != NULL) + { + out_cam->setProjectionType(PT_ORTHOGRAPHIC); + out_cam->setDirection(light.getDerivedDirection()); + out_cam->setPosition(cam.getDerivedPosition()); + out_cam->setFOVy(Degree(90)); + out_cam->setNearClipDistance(shadowOffset); + } + } + else if (light.getType() == Light::LT_POINT) + { + // target analogue to the default shadow textures + // Calculate look at position + // We want to look at a spot shadowOffset away from near plane + // 0.5 is a little too close for angles + Vector3 target = cam.getDerivedPosition() + + (cam.getDerivedDirection() * shadowOffset); + Vector3 lightDir = target - light.getDerivedPosition(); + lightDir.normalise(); + + // generate view matrix if requested + if (out_view != NULL) + { + *out_view = buildViewMatrix(light.getDerivedPosition(), + lightDir, + cam.getDerivedUp()); + } + + // generate projection matrix if requested + if (out_proj != NULL) + { + // set FOV to 120 degrees + mTempFrustum->setFOVy(Degree(120)); + + mTempFrustum->setNearClipDistance(light._deriveShadowNearClipDistance(&cam)); + mTempFrustum->setFarClipDistance(light._deriveShadowFarClipDistance(&cam)); + + *out_proj = mTempFrustum->getProjectionMatrix(); + } + + // set up camera if requested + if (out_cam != NULL) + { + out_cam->setProjectionType(PT_PERSPECTIVE); + out_cam->setDirection(lightDir); + out_cam->setPosition(light.getDerivedPosition()); + out_cam->setFOVy(Degree(120)); + out_cam->setNearClipDistance(light._deriveShadowNearClipDistance(&cam)); + out_cam->setFarClipDistance(light._deriveShadowFarClipDistance(&cam)); + } + } + else if (light.getType() == Light::LT_SPOTLIGHT) + { + // generate view matrix if requested + if (out_view != NULL) + { + *out_view = buildViewMatrix(light.getDerivedPosition(), + light.getDerivedDirection(), + cam.getDerivedUp()); + } + + // generate projection matrix if requested + if (out_proj != NULL) + { + // set FOV slightly larger than spotlight range + mTempFrustum->setFOVy(Ogre::Math::Clamp(light.getSpotlightOuterAngle() * 1.2, Radian(0), Radian(Math::PI/2.0f))); + + mTempFrustum->setNearClipDistance(light._deriveShadowNearClipDistance(&cam)); + mTempFrustum->setFarClipDistance(light._deriveShadowFarClipDistance(&cam)); + + *out_proj = mTempFrustum->getProjectionMatrix(); + } + + // set up camera if requested + if (out_cam != NULL) + { + out_cam->setProjectionType(PT_PERSPECTIVE); + out_cam->setDirection(light.getDerivedDirection()); + out_cam->setPosition(light.getDerivedPosition()); + out_cam->setFOVy(Ogre::Math::Clamp(light.getSpotlightOuterAngle() * 1.2, Radian(0), Radian(Math::PI/2.0f))); + out_cam->setNearClipDistance(light._deriveShadowNearClipDistance(&cam)); + out_cam->setFarClipDistance(light._deriveShadowFarClipDistance(&cam)); + } + } + } + //----------------------------------------------------------------------- + void FocusedShadowCameraSetup::calculateB(const SceneManager& sm, const Camera& cam, + const Light& light, const AxisAlignedBox& sceneBB, const AxisAlignedBox& receiverBB, + PointListBody *out_bodyB) const + { + OgreAssert(out_bodyB != NULL, "bodyB vertex list is NULL"); + + /// perform convex intersection of the form B = ((V \cap S) + l) \cap S \cap L + + // get V + mBodyB.define(cam); + + if (light.getType() != Light::LT_DIRECTIONAL) + { + // clip bodyB with sceneBB + /* Note, Matthias' original code states this: + "The procedure ((V \cap S) + l) \cap S \cap L (Wimmer et al.) leads in some + cases to disappearing shadows. Valid parts of the scene are clipped, so shadows + are partly incomplete. The cause may be the transformation into light space that + is only done for the corner points which may not contain the whole scene afterwards + any more. So we fall back to the method of Stamminger et al. (V + l) \cap S \cap L + which does not show these anomalies." + + .. leading to the commenting out of the below clip. However, ift makes a major + difference to the quality of the focus, and so far I haven't noticed + the clipping issues described. Intuitively I would have thought that + any clipping issue would be due to the findCastersForLight not being + quite right, since if the sceneBB includes those there is no reason for + this clip instruction to omit a genuine shadow caster. + + I have made this a user option since the quality effect is major and + the clipping problem only seems to occur in some specific cases. + */ + if (mUseAggressiveRegion) + mBodyB.clip(sceneBB); + + // form a convex hull of bodyB with the light position + mBodyB.extend(light.getDerivedPosition()); + + // clip bodyB with sceneBB + mBodyB.clip(sceneBB); + + // clip with the light frustum + // set up light camera to clip with the resulting frustum planes + if (!mLightFrustumCameraCalculated) + { + calculateShadowMappingMatrix(sm, cam, light, NULL, NULL, mLightFrustumCamera); + mLightFrustumCameraCalculated = true; + } + mBodyB.clip(*mLightFrustumCamera); + + // extract bodyB vertices + out_bodyB->build(mBodyB); + + } + else + { + // For directional lights, all we care about is projecting the receivers + // backwards towards the light, clipped by the camera region + mBodyB.clip(receiverBB); + + // Also clip based on shadow far distance if appropriate + Real farDist = light.getShadowFarDistance(); + if (farDist) + { + Vector3 pointOnPlane = cam.getDerivedPosition() + + (cam.getDerivedDirection() * farDist); + Plane p(cam.getDerivedDirection(), pointOnPlane); + mBodyB.clip(p); + } + + // Extrude the intersection bodyB into the inverted light direction and store + // the info in the point list. + // Maximum extrusion extent is to the shadow far distance + out_bodyB->buildAndIncludeDirection(mBodyB, + farDist ? farDist : cam.getNearClipDistance() * 3000, + -light.getDerivedDirection()); + } + } + + //----------------------------------------------------------------------- + void FocusedShadowCameraSetup::calculateLVS(const SceneManager& sm, const Camera& cam, + const Light& light, const AxisAlignedBox& sceneBB, PointListBody *out_LVS) const + { + ConvexBody bodyLVS; + + // init body with view frustum + bodyLVS.define(cam); + + // clip the body with the light frustum (point + spot) + // for a directional light the space of the intersected + // view frustum and sceneBB is always lighted and in front + // of the viewer. + if (light.getType() != Light::LT_DIRECTIONAL) + { + // clip with the light frustum + // set up light camera to clip the resulting frustum + if (!mLightFrustumCameraCalculated) + { + calculateShadowMappingMatrix(sm, cam, light, NULL, NULL, mLightFrustumCamera); + mLightFrustumCameraCalculated = true; + } + bodyLVS.clip(*mLightFrustumCamera); + } + + // clip the body with the scene bounding box + bodyLVS.clip(sceneBB); + + // extract bodyLVS vertices + out_LVS->build(bodyLVS); + } + //----------------------------------------------------------------------- + Vector3 FocusedShadowCameraSetup::getLSProjViewDir(const Matrix4& lightSpace, + const Camera& cam, const PointListBody& bodyLVS) const + { + // goal is to construct a view direction + // because parallel lines are not parallel any more after perspective projection we have to transform + // a ray to point us the viewing direction + + // fetch a point near the camera + const Vector3 e_world = getNearCameraPoint_ws(cam.getViewMatrix(), bodyLVS); + + // plus the direction results in a second point + const Vector3 b_world = e_world + cam.getDerivedDirection(); + + // transformation into light space + const Vector3 e_ls = lightSpace * e_world; + const Vector3 b_ls = lightSpace * b_world; + + // calculate the projection direction, which is the subtraction of + // b_ls from e_ls. The y component is set to 0 to project the view + // direction into the shadow map plane. + Vector3 projectionDir(b_ls - e_ls); + projectionDir.y = 0; + + // deal with Y-only vectors + return Math::RealEqual(projectionDir.length(), 0.0) ? + Vector3::NEGATIVE_UNIT_Z : projectionDir.normalisedCopy(); + } + //----------------------------------------------------------------------- + Vector3 FocusedShadowCameraSetup::getNearCameraPoint_ws(const Matrix4& viewMatrix, + const PointListBody& bodyLVS) const + { + if (bodyLVS.getPointCount() == 0) + return Vector3(0,0,0); + + Vector3 nearEye = viewMatrix * bodyLVS.getPoint(0), // for comparison + nearWorld = bodyLVS.getPoint(0); // represents the final point + + // store the vertex with the highest z-value which is the nearest point + for (size_t i = 1; i < bodyLVS.getPointCount(); ++i) + { + const Vector3& vWorld = bodyLVS.getPoint(i); + + // comparison is done from the viewer + Vector3 vEye = viewMatrix * vWorld; + + if (vEye.z > nearEye.z) + { + nearEye = vEye; + nearWorld = vWorld; + } + } + + return nearWorld; + } + //----------------------------------------------------------------------- + Matrix4 FocusedShadowCameraSetup::transformToUnitCube(const Matrix4& m, + const PointListBody& body) const + { + // map the transformed body AAB points to the unit cube (-1/-1/-1) / (+1/+1/+1) corners + AxisAlignedBox aab_trans; + + for (size_t i = 0; i < body.getPointCount(); ++i) + { + aab_trans.merge(m * body.getPoint(i)); + } + + Vector3 vMin, vMax; + + vMin = aab_trans.getMinimum(); + vMax = aab_trans.getMaximum(); + + const Vector3 trans(-(vMax.x + vMin.x) / (vMax.x - vMin.x), + -(vMax.y + vMin.y) / (vMax.y - vMin.y), + -(vMax.z + vMin.z) / (vMax.z - vMin.z)); + + const Vector3 scale(2 / (vMax.x - vMin.x), + 2 / (vMax.y - vMin.y), + 2 / (vMax.z - vMin.z)); + + Matrix4 mOut(Matrix4::IDENTITY); + mOut.setTrans(trans); + mOut.setScale(scale); + + return mOut; + } + //----------------------------------------------------------------------- + Matrix4 FocusedShadowCameraSetup::buildViewMatrix(const Vector3& pos, const Vector3& dir, + const Vector3& up) const + { + Vector3 xN = dir.crossProduct(up); + xN.normalise(); + Vector3 upN = xN.crossProduct(dir); + upN.normalise(); + + Matrix4 m(xN.x, xN.y, xN.z, -xN.dotProduct(pos), + upN.x, upN.y, upN.z, -upN.dotProduct(pos), + -dir.x, -dir.y, -dir.z, dir.dotProduct(pos), + 0.0, 0.0, 0.0, 1.0 + ); + + return m; + } + //----------------------------------------------------------------------- + void FocusedShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, + const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const + { + // check availability - viewport not needed + OgreAssert(sm != NULL, "SceneManager is NULL"); + OgreAssert(cam != NULL, "Camera (viewer) is NULL"); + OgreAssert(light != NULL, "Light is NULL"); + OgreAssert(texCam != NULL, "Camera (texture) is NULL"); + mLightFrustumCameraCalculated = false; + + texCam->setNearClipDistance(light->_deriveShadowNearClipDistance(cam)); + texCam->setFarClipDistance(light->_deriveShadowFarClipDistance(cam)); + + // calculate standard shadow mapping matrix + Matrix4 LView, LProj; + calculateShadowMappingMatrix(*sm, *cam, *light, &LView, &LProj, NULL); + + // build scene bounding box + const VisibleObjectsBoundsInfo& visInfo = sm->getVisibleObjectsBoundsInfo(texCam); + AxisAlignedBox sceneBB = visInfo.aabb; + AxisAlignedBox receiverAABB = sm->getVisibleObjectsBoundsInfo(cam).receiverAabb; + sceneBB.merge(receiverAABB); + sceneBB.merge(cam->getDerivedPosition()); + + // in case the sceneBB is empty (e.g. nothing visible to the cam) simply + // return the standard shadow mapping matrix + if (sceneBB.isNull()) + { + texCam->setCustomViewMatrix(true, LView); + texCam->setCustomProjectionMatrix(true, LProj); + return; + } + + // calculate the intersection body B + mPointListBodyB.reset(); + calculateB(*sm, *cam, *light, sceneBB, receiverAABB, &mPointListBodyB); + + // in case the bodyB is empty (e.g. nothing visible to the light or the cam) + // simply return the standard shadow mapping matrix + if (mPointListBodyB.getPointCount() == 0) + { + texCam->setCustomViewMatrix(true, LView); + texCam->setCustomProjectionMatrix(true, LProj); + return; + } + + // transform to light space: y -> -z, z -> y + LProj = msNormalToLightSpace * LProj; + + // calculate LVS so it does not need to be calculated twice + // calculate the body L \cap V \cap S to make sure all returned points are in + // front of the camera + mPointListBodyLVS.reset(); + calculateLVS(*sm, *cam, *light, sceneBB, &mPointListBodyLVS); + + // fetch the viewing direction + const Vector3 viewDir = getLSProjViewDir(LProj * LView, *cam, mPointListBodyLVS); + + // The light space will be rotated in such a way, that the projected light view + // always points upwards, so the up-vector is the y-axis (we already prepared the + // light space for this usage).The transformation matrix is set up with the + // following parameters: + // - position is the origin + // - the view direction is the calculated viewDir + // - the up vector is the y-axis + LProj = buildViewMatrix(Vector3::ZERO, viewDir, Vector3::UNIT_Y) * LProj; + + // map bodyB to unit cube + LProj = transformToUnitCube(LProj * LView, mPointListBodyB) * LProj; + + // transform from light space to normal space: y -> z, z -> -y + LProj = msLightSpaceToNormal * LProj; + + // set the two custom matrices + texCam->setCustomViewMatrix(true, LView); + texCam->setCustomProjectionMatrix(true, LProj); + } + + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //----------------------------------------------------------------------- + FocusedShadowCameraSetup::PointListBody::PointListBody() + { + // Preallocate some space + mBodyPoints.reserve(12); + } + //----------------------------------------------------------------------- + FocusedShadowCameraSetup::PointListBody::PointListBody(const ConvexBody& body) + { + build(body); + } + //----------------------------------------------------------------------- + FocusedShadowCameraSetup::PointListBody::~PointListBody() + { + } + //----------------------------------------------------------------------- + void FocusedShadowCameraSetup::PointListBody::merge(const PointListBody& plb) + { + size_t size = plb.getPointCount(); + for (size_t i = 0; i < size; ++i) + { + this->addPoint(plb.getPoint(i)); + } + } + //----------------------------------------------------------------------- + void FocusedShadowCameraSetup::PointListBody::build(const ConvexBody& body, bool filterDuplicates) + { + // erase list + mBodyPoints.clear(); + + // Try to reserve a representative amount of memory + mBodyPoints.reserve(body.getPolygonCount() * 6); + + // build new list + for (size_t i = 0; i < body.getPolygonCount(); ++i) + { + for (size_t j = 0; j < body.getVertexCount(i); ++j) + { + const Vector3 &vInsert = body.getVertex(i, j); + + // duplicates allowed? + if (filterDuplicates) + { + bool bPresent = false; + + for(Polygon::VertexList::iterator vit = mBodyPoints.begin(); + vit != mBodyPoints.end(); ++vit) + { + const Vector3& v = *vit; + + if (vInsert.positionEquals(v)) + { + bPresent = true; + break; + } + } + + if (bPresent == false) + { + mBodyPoints.push_back(body.getVertex(i, j)); + } + } + + // else insert directly + else + { + mBodyPoints.push_back(body.getVertex(i, j)); + } + } + } + + // update AAB + // no points altered, so take body AAB + mAAB = body.getAABB(); + } + //----------------------------------------------------------------------- + void FocusedShadowCameraSetup::PointListBody::buildAndIncludeDirection( + const ConvexBody& body, Real extrudeDist, const Vector3& dir) + { + // reset point list + this->reset(); + + // intersect the rays formed by the points in the list with the given direction and + // insert them into the list + + const size_t polyCount = body.getPolygonCount(); + for (size_t iPoly = 0; iPoly < polyCount; ++iPoly) + { + + // store the old inserted point and plane info + // if the currently processed point hits a different plane than the previous point an + // intersection point is calculated that lies on the two planes' intersection edge + + // fetch current polygon + const Polygon& p = body.getPolygon(iPoly); + + size_t pointCount = p.getVertexCount(); + for (size_t iPoint = 0; iPoint < pointCount ; ++iPoint) + { + // base point + const Vector3& pt = p.getVertex(iPoint); + + // add the base point + this->addPoint(pt); + + // intersection ray + Ray ray(pt, dir); + + const Vector3 ptIntersect = ray.getPoint(extrudeDist); + this->addPoint(ptIntersect); + + } // for: polygon point iteration + + } // for: polygon iteration + } + //----------------------------------------------------------------------- + const AxisAlignedBox& FocusedShadowCameraSetup::PointListBody::getAAB(void) const + { + return mAAB; + } + //----------------------------------------------------------------------- + void FocusedShadowCameraSetup::PointListBody::addPoint(const Vector3& point) + { + // don't check for doubles, simply add + mBodyPoints.push_back(point); + + // update AAB + mAAB.merge(point); + } + //----------------------------------------------------------------------- + void FocusedShadowCameraSetup::PointListBody::addAAB(const AxisAlignedBox& aab) + { + const Vector3& min = aab.getMinimum(); + const Vector3& max = aab.getMaximum(); + + Vector3 currentVertex = min; + // min min min + addPoint(currentVertex); + + // min min max + currentVertex.z = max.z; + addPoint(currentVertex); + + // min max max + currentVertex.y = max.y; + addPoint(currentVertex); + + // min max min + currentVertex.z = min.z; + addPoint(currentVertex); + + // max max min + currentVertex.x = max.x; + addPoint(currentVertex); + + // max max max + currentVertex.z = max.z; + addPoint(currentVertex); + + // max min max + currentVertex.y = min.y; + addPoint(currentVertex); + + // max min min + currentVertex.z = min.z; + addPoint(currentVertex); + + } + //----------------------------------------------------------------------- + const Vector3& FocusedShadowCameraSetup::PointListBody::getPoint(size_t cnt) const + { + OgreAssert(cnt < getPointCount(), "Search position out of range"); + + return mBodyPoints[ cnt ]; + } + //----------------------------------------------------------------------- + size_t FocusedShadowCameraSetup::PointListBody::getPointCount(void) const + { + return mBodyPoints.size(); + } + //----------------------------------------------------------------------- + void FocusedShadowCameraSetup::PointListBody::reset(void) + { + mBodyPoints.clear(); + mAAB.setNull(); + } } diff --git a/OgreMain/src/OgreShadowCameraSetupLiSPSM.cpp b/OgreMain/src/OgreShadowCameraSetupLiSPSM.cpp index e21da1060e6..a3f458a0b45 100644 --- a/OgreMain/src/OgreShadowCameraSetupLiSPSM.cpp +++ b/OgreMain/src/OgreShadowCameraSetupLiSPSM.cpp @@ -5,7 +5,7 @@ This source file is part of OGRE For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd -Copyright (c) 2006 Matthias Fink, netAllied GmbH +Copyright (c) 2006 Matthias Fink, netAllied GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -38,288 +38,288 @@ namespace Ogre { - LiSPSMShadowCameraSetup::LiSPSMShadowCameraSetup(void) - : mOptAdjustFactor(0.1f) - , mUseSimpleNOpt(true) - , mOptAdjustFactorTweak(1.0) - , mCosCamLightDirThreshold(0.9) - { - } - //----------------------------------------------------------------------- - LiSPSMShadowCameraSetup::~LiSPSMShadowCameraSetup(void) - { - } - //----------------------------------------------------------------------- - Matrix4 LiSPSMShadowCameraSetup::calculateLiSPSM(const Matrix4& lightSpace, - const PointListBody& bodyB, const PointListBody& bodyLVS, - const SceneManager& sm, const Camera& cam, const Light& light) const - { - // set up bodyB AAB in light space - AxisAlignedBox bodyBAAB_ls; - for (size_t i = 0; i < bodyB.getPointCount(); ++i) - { - bodyBAAB_ls.merge(lightSpace * bodyB.getPoint(i)); - } - - // near camera point in light space - const Vector3 e_ls = lightSpace * getNearCameraPoint_ws(cam.getViewMatrix(), bodyLVS); - - // C_start has x and y of e and z from the bodyABB_ls (we look down the negative z axis, so take the maximum z value) - const Vector3 C_start_ls(e_ls.x, e_ls.y, bodyBAAB_ls.getMaximum().z); - - // calculate the optimal distance between origin and near plane - Real n_opt; - - if (mUseSimpleNOpt) - n_opt = calculateNOptSimple(bodyLVS, cam); - else - n_opt = calculateNOpt(lightSpace, bodyBAAB_ls, bodyLVS, cam); - - // in case n_opt is null, uniform shadow mapping will be done - if (n_opt <= 0.0) - { - return Matrix4::IDENTITY; - } - - // calculate the projection center C which is n units behind the near plane of P - // we look into the negative z direction so add n - const Vector3 C(C_start_ls + n_opt * Vector3::UNIT_Z); - - // set up a transformation matrix to transform the light space to its new origin - Matrix4 lightSpaceTranslation(Matrix4::IDENTITY); - lightSpaceTranslation.setTrans(-C); - - // range from bMin to bMax; d = |B_z_far - B_z_near| - Real d = Math::Abs(bodyBAAB_ls.getMaximum().z - bodyBAAB_ls.getMinimum().z); - - // set up the LiSPSM perspective transformation - // build up frustum to map P onto the unit cube with (-1/-1/-1) and (+1/+1/+1) - Matrix4 P = buildFrustumProjection(-1, 1, -1, 1, n_opt + d, n_opt); - - return P * lightSpaceTranslation; - } - //----------------------------------------------------------------------- - Real LiSPSMShadowCameraSetup::calculateNOpt(const Matrix4& lightSpace, - const AxisAlignedBox& bodyBABB_ls, const PointListBody& bodyLVS, - const Camera& cam) const - { - // get inverse light space matrix - Matrix4 invLightSpace = lightSpace.inverse(); - - // get view matrix - const Matrix4& viewMatrix = cam.getViewMatrix(); - - // calculate z0_ls - const Vector3 e_ws = getNearCameraPoint_ws(viewMatrix, bodyLVS); - const Vector3 z0_ls = calculateZ0_ls(lightSpace, e_ws, bodyBABB_ls.getMaximum().z, cam); - - // z1_ls has the same x and y values as z0_ls and the minimum z values of bodyABB_ls - const Vector3 z1_ls = Vector3(z0_ls.x, z0_ls.y, bodyBABB_ls.getMinimum().z); - - // world - const Vector3 z0_ws = invLightSpace * z0_ls; - const Vector3 z1_ws = invLightSpace * z1_ls; - - // eye - const Vector3 z0_es = viewMatrix * z0_ws; - const Vector3 z1_es = viewMatrix * z1_ws; - - const Real z0 = z0_es.z; - const Real z1 = z1_es.z; - - // check if we have to do uniform shadow mapping - if ((z0 < 0 && z1 > 0) || - (z1 < 0 && z0 > 0)) - { - // apply uniform shadow mapping - return 0.0; - } - return cam.getNearClipDistance() + Math::Sqrt(z0 * z1) * getOptimalAdjustFactor() * mOptAdjustFactorTweak; - } - //----------------------------------------------------------------------- - Real LiSPSMShadowCameraSetup::calculateNOptSimple(const PointListBody& bodyLVS, - const Camera& cam) const - { - // get view matrix - const Matrix4& viewMatrix = cam.getViewMatrix(); - - // calculate e_es - const Vector3 e_ws = getNearCameraPoint_ws(viewMatrix, bodyLVS); - const Vector3 e_es = viewMatrix * e_ws; - - // according to the new formula (mainly for directional lights) - // n_opt = zn + sqrt(z0 * z1); - // zn is set to Abs(near eye point) - // z0 is set to the near camera clip distance - // z1 is set to the far camera clip distance - return (Math::Abs(e_es.z) + Math::Sqrt(cam.getNearClipDistance() * cam.getFarClipDistance())) * getOptimalAdjustFactor() * mOptAdjustFactorTweak; - } - //----------------------------------------------------------------------- - Vector3 LiSPSMShadowCameraSetup::calculateZ0_ls(const Matrix4& lightSpace, - const Vector3& e, Real bodyB_zMax_ls, const Camera& cam) const - { - // z0_ls lies on the intersection point between the planes 'bodyB_ls near plane - // (z = bodyB_zNear_ls)' and plane with normal UNIT_X where e_ls lies upon (x = e_ls_x) - // and the camera's near clipping plane (ls). We are looking towards the negative - // z-direction, so bodyB_zNear_ls equals bodyB_zMax_ls. - - const Vector3& camDir = cam.getDerivedDirection(); - const Vector3 e_ls = lightSpace * e; - - // set up a plane with the camera direction as normal and e as a point on the plane - Plane plane(camDir, e); - - plane = lightSpace * plane; - - // try to intersect plane with a ray from origin V3(e_ls_x, 0.0, bodyB_zNear_ls)T - // and direction +/- UNIT_Y - Ray ray(Vector3(e_ls.x, 0.0, bodyB_zMax_ls), Vector3::UNIT_Y); - std::pair< bool, Real > intersect = ray.intersects(plane); - - // we got an intersection point - if (intersect.first == true) - { - return ray.getPoint(intersect.second); - } - else - { - // try the other direction - ray = Ray(Vector3(e_ls.x, 0.0, bodyB_zMax_ls), Vector3::NEGATIVE_UNIT_Y); - intersect = ray.intersects(plane); - - // we got an intersection point - if (intersect.first == true) - { - return ray.getPoint(intersect.second); - } - else - { - // failure! - return Vector3(0.0, 0.0, 0.0); - } - } - } - //----------------------------------------------------------------------- - Matrix4 LiSPSMShadowCameraSetup::buildFrustumProjection(Real left, Real right, - Real bottom, Real top, Real nearf, Real farf) const - { - // Changed to nearf because windows defines near and far as a macros - Real m00 = 2 * nearf / (right - left), - m02 = (right + left) / (right - left), - m11 = 2 * nearf / (top - bottom), - m12 = (top + bottom) / (top - bottom), - m22 = -(farf + nearf) / (farf - nearf), - m23 = -2 * farf * nearf / (farf - nearf), - m32 = -1; - - Matrix4 m(m00, 0.0, m02, 0.0, - 0.0, m11, m12, 0.0, - 0.0, 0.0, m22, m23, - 0.0, 0.0, m32, 0.0); - - return m; - } - //----------------------------------------------------------------------- - void LiSPSMShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, - const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const - { - // check availability - viewport not needed - OgreAssert(sm != NULL, "SceneManager is NULL"); - OgreAssert(cam != NULL, "Camera (viewer) is NULL"); - OgreAssert(light != NULL, "Light is NULL"); - OgreAssert(texCam != NULL, "Camera (texture) is NULL"); - mLightFrustumCameraCalculated = false; - - - // calculate standard shadow mapping matrix - Matrix4 LView, LProj; - calculateShadowMappingMatrix(*sm, *cam, *light, &LView, &LProj, NULL); - - // if the direction of the light and the direction of the camera tend to be parallel, - // then tweak up the adjust factor - Real dot = Math::Abs(cam->getDerivedDirection().dotProduct(light->getDerivedDirection())); - if (dot >= mCosCamLightDirThreshold) - { - mOptAdjustFactorTweak = 1.0f + (20.0f * ((dot - mCosCamLightDirThreshold) / (1.0f - mCosCamLightDirThreshold)) ); - } - else - { - mOptAdjustFactorTweak = 1.0f; - } - - // build scene bounding box - const VisibleObjectsBoundsInfo& visInfo = sm->getVisibleObjectsBoundsInfo(texCam); - AxisAlignedBox sceneBB = visInfo.aabb; - AxisAlignedBox receiverAABB = sm->getVisibleObjectsBoundsInfo(cam).receiverAabb; - sceneBB.merge(receiverAABB); - sceneBB.merge(cam->getDerivedPosition()); - - // in case the sceneBB is empty (e.g. nothing visible to the cam) simply - // return the standard shadow mapping matrix - if (sceneBB.isNull()) - { - texCam->setCustomViewMatrix(true, LView); - texCam->setCustomProjectionMatrix(true, LProj); - return; - } - - // calculate the intersection body B - mPointListBodyB.reset(); - calculateB(*sm, *cam, *light, sceneBB, receiverAABB, &mPointListBodyB); - - // in case the bodyB is empty (e.g. nothing visible to the light or the cam) - // simply return the standard shadow mapping matrix - if (mPointListBodyB.getPointCount() == 0) - { - texCam->setCustomViewMatrix(true, LView); - texCam->setCustomProjectionMatrix(true, LProj); - return; - } - - // transform to light space: y -> -z, z -> y - LProj = msNormalToLightSpace * LProj; - - // calculate LVS so it does not need to be calculated twice - // calculate the body L \cap V \cap S to make sure all returned points are in - // front of the camera - calculateLVS(*sm, *cam, *light, sceneBB, &mPointListBodyLVS); - - // fetch the viewing direction - const Vector3 viewDir = getLSProjViewDir(LProj * LView, *cam, mPointListBodyLVS); - - // The light space will be rotated in such a way, that the projected light view - // always points upwards, so the up-vector is the y-axis (we already prepared the - // light space for this usage).The transformation matrix is set up with the - // following parameters: - // - position is the origin - // - the view direction is the calculated viewDir - // - the up vector is the y-axis - LProj = buildViewMatrix(Vector3::ZERO, viewDir, Vector3::UNIT_Y) * LProj; - - // calculate LiSPSM projection - LProj = calculateLiSPSM(LProj * LView, mPointListBodyB, mPointListBodyLVS, *sm, *cam, *light) * LProj; - - // map bodyB to unit cube - LProj = transformToUnitCube(LProj * LView, mPointListBodyB) * LProj; - - // transform from light space to normal space: y -> z, z -> -y - LProj = msLightSpaceToNormal * LProj; - - // LView = Lv^-1 - // LProj = Switch_{-ls} * FocusBody * P * L_r * Switch_{ls} * L_p - texCam->setCustomViewMatrix(true, LView); - texCam->setCustomProjectionMatrix(true, LProj); - } - //--------------------------------------------------------------------- - void LiSPSMShadowCameraSetup::setCameraLightDirectionThreshold(Degree angle) - { - mCosCamLightDirThreshold = Math::Cos(angle.valueRadians()); - } - //--------------------------------------------------------------------- - Degree LiSPSMShadowCameraSetup::getCameraLightDirectionThreshold() const - { - return Degree(Math::ACos(mCosCamLightDirThreshold)); - } + LiSPSMShadowCameraSetup::LiSPSMShadowCameraSetup(void) + : mOptAdjustFactor(0.1f) + , mUseSimpleNOpt(true) + , mOptAdjustFactorTweak(1.0) + , mCosCamLightDirThreshold(0.9) + { + } + //----------------------------------------------------------------------- + LiSPSMShadowCameraSetup::~LiSPSMShadowCameraSetup(void) + { + } + //----------------------------------------------------------------------- + Matrix4 LiSPSMShadowCameraSetup::calculateLiSPSM(const Matrix4& lightSpace, + const PointListBody& bodyB, const PointListBody& bodyLVS, + const SceneManager& sm, const Camera& cam, const Light& light) const + { + // set up bodyB AAB in light space + AxisAlignedBox bodyBAAB_ls; + for (size_t i = 0; i < bodyB.getPointCount(); ++i) + { + bodyBAAB_ls.merge(lightSpace * bodyB.getPoint(i)); + } + + // near camera point in light space + const Vector3 e_ls = lightSpace * getNearCameraPoint_ws(cam.getViewMatrix(), bodyLVS); + + // C_start has x and y of e and z from the bodyABB_ls (we look down the negative z axis, so take the maximum z value) + const Vector3 C_start_ls(e_ls.x, e_ls.y, bodyBAAB_ls.getMaximum().z); + + // calculate the optimal distance between origin and near plane + Real n_opt; + + if (mUseSimpleNOpt) + n_opt = calculateNOptSimple(bodyLVS, cam); + else + n_opt = calculateNOpt(lightSpace, bodyBAAB_ls, bodyLVS, cam); + + // in case n_opt is null, uniform shadow mapping will be done + if (n_opt <= 0.0) + { + return Matrix4::IDENTITY; + } + + // calculate the projection center C which is n units behind the near plane of P + // we look into the negative z direction so add n + const Vector3 C(C_start_ls + n_opt * Vector3::UNIT_Z); + + // set up a transformation matrix to transform the light space to its new origin + Matrix4 lightSpaceTranslation(Matrix4::IDENTITY); + lightSpaceTranslation.setTrans(-C); + + // range from bMin to bMax; d = |B_z_far - B_z_near| + Real d = Math::Abs(bodyBAAB_ls.getMaximum().z - bodyBAAB_ls.getMinimum().z); + + // set up the LiSPSM perspective transformation + // build up frustum to map P onto the unit cube with (-1/-1/-1) and (+1/+1/+1) + Matrix4 P = buildFrustumProjection(-1, 1, -1, 1, n_opt + d, n_opt); + + return P * lightSpaceTranslation; + } + //----------------------------------------------------------------------- + Real LiSPSMShadowCameraSetup::calculateNOpt(const Matrix4& lightSpace, + const AxisAlignedBox& bodyBABB_ls, const PointListBody& bodyLVS, + const Camera& cam) const + { + // get inverse light space matrix + Matrix4 invLightSpace = lightSpace.inverse(); + + // get view matrix + const Matrix4& viewMatrix = cam.getViewMatrix(); + + // calculate z0_ls + const Vector3 e_ws = getNearCameraPoint_ws(viewMatrix, bodyLVS); + const Vector3 z0_ls = calculateZ0_ls(lightSpace, e_ws, bodyBABB_ls.getMaximum().z, cam); + + // z1_ls has the same x and y values as z0_ls and the minimum z values of bodyABB_ls + const Vector3 z1_ls = Vector3(z0_ls.x, z0_ls.y, bodyBABB_ls.getMinimum().z); + + // world + const Vector3 z0_ws = invLightSpace * z0_ls; + const Vector3 z1_ws = invLightSpace * z1_ls; + + // eye + const Vector3 z0_es = viewMatrix * z0_ws; + const Vector3 z1_es = viewMatrix * z1_ws; + + const Real z0 = z0_es.z; + const Real z1 = z1_es.z; + + // check if we have to do uniform shadow mapping + if ((z0 < 0 && z1 > 0) || + (z1 < 0 && z0 > 0)) + { + // apply uniform shadow mapping + return 0.0; + } + return cam.getNearClipDistance() + Math::Sqrt(z0 * z1) * getOptimalAdjustFactor() * mOptAdjustFactorTweak; + } + //----------------------------------------------------------------------- + Real LiSPSMShadowCameraSetup::calculateNOptSimple(const PointListBody& bodyLVS, + const Camera& cam) const + { + // get view matrix + const Matrix4& viewMatrix = cam.getViewMatrix(); + + // calculate e_es + const Vector3 e_ws = getNearCameraPoint_ws(viewMatrix, bodyLVS); + const Vector3 e_es = viewMatrix * e_ws; + + // according to the new formula (mainly for directional lights) + // n_opt = zn + sqrt(z0 * z1); + // zn is set to Abs(near eye point) + // z0 is set to the near camera clip distance + // z1 is set to the far camera clip distance + return (Math::Abs(e_es.z) + Math::Sqrt(cam.getNearClipDistance() * cam.getFarClipDistance())) * getOptimalAdjustFactor() * mOptAdjustFactorTweak; + } + //----------------------------------------------------------------------- + Vector3 LiSPSMShadowCameraSetup::calculateZ0_ls(const Matrix4& lightSpace, + const Vector3& e, Real bodyB_zMax_ls, const Camera& cam) const + { + // z0_ls lies on the intersection point between the planes 'bodyB_ls near plane + // (z = bodyB_zNear_ls)' and plane with normal UNIT_X where e_ls lies upon (x = e_ls_x) + // and the camera's near clipping plane (ls). We are looking towards the negative + // z-direction, so bodyB_zNear_ls equals bodyB_zMax_ls. + + const Vector3& camDir = cam.getDerivedDirection(); + const Vector3 e_ls = lightSpace * e; + + // set up a plane with the camera direction as normal and e as a point on the plane + Plane plane(camDir, e); + + plane = lightSpace * plane; + + // try to intersect plane with a ray from origin V3(e_ls_x, 0.0, bodyB_zNear_ls)T + // and direction +/- UNIT_Y + Ray ray(Vector3(e_ls.x, 0.0, bodyB_zMax_ls), Vector3::UNIT_Y); + std::pair< bool, Real > intersect = ray.intersects(plane); + + // we got an intersection point + if (intersect.first == true) + { + return ray.getPoint(intersect.second); + } + else + { + // try the other direction + ray = Ray(Vector3(e_ls.x, 0.0, bodyB_zMax_ls), Vector3::NEGATIVE_UNIT_Y); + intersect = ray.intersects(plane); + + // we got an intersection point + if (intersect.first == true) + { + return ray.getPoint(intersect.second); + } + else + { + // failure! + return Vector3(0.0, 0.0, 0.0); + } + } + } + //----------------------------------------------------------------------- + Matrix4 LiSPSMShadowCameraSetup::buildFrustumProjection(Real left, Real right, + Real bottom, Real top, Real nearf, Real farf) const + { + // Changed to nearf because windows defines near and far as a macros + Real m00 = 2 * nearf / (right - left), + m02 = (right + left) / (right - left), + m11 = 2 * nearf / (top - bottom), + m12 = (top + bottom) / (top - bottom), + m22 = -(farf + nearf) / (farf - nearf), + m23 = -2 * farf * nearf / (farf - nearf), + m32 = -1; + + Matrix4 m(m00, 0.0, m02, 0.0, + 0.0, m11, m12, 0.0, + 0.0, 0.0, m22, m23, + 0.0, 0.0, m32, 0.0); + + return m; + } + //----------------------------------------------------------------------- + void LiSPSMShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, + const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const + { + // check availability - viewport not needed + OgreAssert(sm != NULL, "SceneManager is NULL"); + OgreAssert(cam != NULL, "Camera (viewer) is NULL"); + OgreAssert(light != NULL, "Light is NULL"); + OgreAssert(texCam != NULL, "Camera (texture) is NULL"); + mLightFrustumCameraCalculated = false; + + + // calculate standard shadow mapping matrix + Matrix4 LView, LProj; + calculateShadowMappingMatrix(*sm, *cam, *light, &LView, &LProj, NULL); + + // if the direction of the light and the direction of the camera tend to be parallel, + // then tweak up the adjust factor + Real dot = Math::Abs(cam->getDerivedDirection().dotProduct(light->getDerivedDirection())); + if (dot >= mCosCamLightDirThreshold) + { + mOptAdjustFactorTweak = 1.0f + (20.0f * ((dot - mCosCamLightDirThreshold) / (1.0f - mCosCamLightDirThreshold)) ); + } + else + { + mOptAdjustFactorTweak = 1.0f; + } + + // build scene bounding box + const VisibleObjectsBoundsInfo& visInfo = sm->getVisibleObjectsBoundsInfo(texCam); + AxisAlignedBox sceneBB = visInfo.aabb; + AxisAlignedBox receiverAABB = sm->getVisibleObjectsBoundsInfo(cam).receiverAabb; + sceneBB.merge(receiverAABB); + sceneBB.merge(cam->getDerivedPosition()); + + // in case the sceneBB is empty (e.g. nothing visible to the cam) simply + // return the standard shadow mapping matrix + if (sceneBB.isNull()) + { + texCam->setCustomViewMatrix(true, LView); + texCam->setCustomProjectionMatrix(true, LProj); + return; + } + + // calculate the intersection body B + mPointListBodyB.reset(); + calculateB(*sm, *cam, *light, sceneBB, receiverAABB, &mPointListBodyB); + + // in case the bodyB is empty (e.g. nothing visible to the light or the cam) + // simply return the standard shadow mapping matrix + if (mPointListBodyB.getPointCount() == 0) + { + texCam->setCustomViewMatrix(true, LView); + texCam->setCustomProjectionMatrix(true, LProj); + return; + } + + // transform to light space: y -> -z, z -> y + LProj = msNormalToLightSpace * LProj; + + // calculate LVS so it does not need to be calculated twice + // calculate the body L \cap V \cap S to make sure all returned points are in + // front of the camera + calculateLVS(*sm, *cam, *light, sceneBB, &mPointListBodyLVS); + + // fetch the viewing direction + const Vector3 viewDir = getLSProjViewDir(LProj * LView, *cam, mPointListBodyLVS); + + // The light space will be rotated in such a way, that the projected light view + // always points upwards, so the up-vector is the y-axis (we already prepared the + // light space for this usage).The transformation matrix is set up with the + // following parameters: + // - position is the origin + // - the view direction is the calculated viewDir + // - the up vector is the y-axis + LProj = buildViewMatrix(Vector3::ZERO, viewDir, Vector3::UNIT_Y) * LProj; + + // calculate LiSPSM projection + LProj = calculateLiSPSM(LProj * LView, mPointListBodyB, mPointListBodyLVS, *sm, *cam, *light) * LProj; + + // map bodyB to unit cube + LProj = transformToUnitCube(LProj * LView, mPointListBodyB) * LProj; + + // transform from light space to normal space: y -> z, z -> -y + LProj = msLightSpaceToNormal * LProj; + + // LView = Lv^-1 + // LProj = Switch_{-ls} * FocusBody * P * L_r * Switch_{ls} * L_p + texCam->setCustomViewMatrix(true, LView); + texCam->setCustomProjectionMatrix(true, LProj); + } + //--------------------------------------------------------------------- + void LiSPSMShadowCameraSetup::setCameraLightDirectionThreshold(Degree angle) + { + mCosCamLightDirThreshold = Math::Cos(angle.valueRadians()); + } + //--------------------------------------------------------------------- + Degree LiSPSMShadowCameraSetup::getCameraLightDirectionThreshold() const + { + return Degree(Math::ACos(mCosCamLightDirThreshold)); + } } diff --git a/OgreMain/src/OgreShadowCameraSetupPSSM.cpp b/OgreMain/src/OgreShadowCameraSetupPSSM.cpp index 945240538aa..de22d799b38 100644 --- a/OgreMain/src/OgreShadowCameraSetupPSSM.cpp +++ b/OgreMain/src/OgreShadowCameraSetupPSSM.cpp @@ -5,7 +5,7 @@ This source file is part of OGRE For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd -Copyright (c) 2006 Matthias Fink, netAllied GmbH +Copyright (c) 2006 Matthias Fink, netAllied GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -33,103 +33,103 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - PSSMShadowCameraSetup::PSSMShadowCameraSetup() - : mSplitPadding(1.0f), mCurrentIteration(0) - { - calculateSplitPoints(3, 100, 100000); - setOptimalAdjustFactor(0, 5); - setOptimalAdjustFactor(1, 1); - setOptimalAdjustFactor(2, 0); - - - } - //--------------------------------------------------------------------- - PSSMShadowCameraSetup::~PSSMShadowCameraSetup() - { - } - //--------------------------------------------------------------------- - void PSSMShadowCameraSetup::calculateSplitPoints(uint splitCount, Real nearDist, Real farDist, Real lambda) - { - if (splitCount < 2) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot specify less than 2 splits", - "PSSMShadowCameraSetup::calculateSplitPoints"); - - mSplitPoints.resize(splitCount + 1); - mOptimalAdjustFactors.resize(splitCount); - mSplitCount = splitCount; - - mSplitPoints[0] = nearDist; - for (size_t i = 1; i < mSplitCount; i++) - { - Real fraction = (Real)i / (Real)mSplitCount; - Real splitPoint = lambda * nearDist * Math::Pow(farDist / nearDist, fraction) + - (1.0f - lambda) * (nearDist + fraction * (farDist - nearDist)); - - mSplitPoints[i] = splitPoint; - } - mSplitPoints[splitCount] = farDist; - - } - //--------------------------------------------------------------------- - void PSSMShadowCameraSetup::setSplitPoints(const SplitPointList& newSplitPoints) - { - if (newSplitPoints.size() < 3) // 3, not 2 since splits + 1 points - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot specify less than 2 splits", - "PSSMShadowCameraSetup::setSplitPoints"); - mSplitCount = static_cast(newSplitPoints.size() - 1); - mSplitPoints = newSplitPoints; - mOptimalAdjustFactors.resize(mSplitCount); - } - //--------------------------------------------------------------------- - void PSSMShadowCameraSetup::setOptimalAdjustFactor(size_t splitIndex, Real factor) - { - if (splitIndex >= mOptimalAdjustFactors.size()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Split index out of range", - "PSSMShadowCameraSetup::setOptimalAdjustFactor"); - mOptimalAdjustFactors[splitIndex] = factor; - - } - //--------------------------------------------------------------------- - Real PSSMShadowCameraSetup::getOptimalAdjustFactor() const - { - // simplifies the overriding of the LiSPSM opt adjust factor use - return mOptimalAdjustFactors[mCurrentIteration]; - } - //--------------------------------------------------------------------- - void PSSMShadowCameraSetup::getShadowCamera(const Ogre::SceneManager *sm, const Ogre::Camera *cam, - const Ogre::Viewport *vp, const Ogre::Light *light, Ogre::Camera *texCam, size_t iteration) const - { - // apply the right clip distance. - Real nearDist = mSplitPoints[iteration]; - Real farDist = mSplitPoints[iteration + 1]; - - // Add a padding factor to internal distances so that the connecting split point will not have bad artifacts. - if (iteration > 0) - { - nearDist -= mSplitPadding; - } - if (iteration < mSplitCount - 1) - { - farDist += mSplitPadding; - } - - mCurrentIteration = iteration; - - // Ouch, I know this is hacky, but it's the easiest way to re-use LiSPSM / Focused - // functionality right now without major changes - Camera* _cam = const_cast(cam); - Real oldNear = _cam->getNearClipDistance(); - Real oldFar = _cam->getFarClipDistance(); - _cam->setNearClipDistance(nearDist); - _cam->setFarClipDistance(farDist); - - LiSPSMShadowCameraSetup::getShadowCamera(sm, cam, vp, light, texCam, iteration); - - // restore near/far - _cam->setNearClipDistance(oldNear); - _cam->setFarClipDistance(oldFar); - - - } + //--------------------------------------------------------------------- + PSSMShadowCameraSetup::PSSMShadowCameraSetup() + : mSplitPadding(1.0f), mCurrentIteration(0) + { + calculateSplitPoints(3, 100, 100000); + setOptimalAdjustFactor(0, 5); + setOptimalAdjustFactor(1, 1); + setOptimalAdjustFactor(2, 0); + + + } + //--------------------------------------------------------------------- + PSSMShadowCameraSetup::~PSSMShadowCameraSetup() + { + } + //--------------------------------------------------------------------- + void PSSMShadowCameraSetup::calculateSplitPoints(uint splitCount, Real nearDist, Real farDist, Real lambda) + { + if (splitCount < 2) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot specify less than 2 splits", + "PSSMShadowCameraSetup::calculateSplitPoints"); + + mSplitPoints.resize(splitCount + 1); + mOptimalAdjustFactors.resize(splitCount); + mSplitCount = splitCount; + + mSplitPoints[0] = nearDist; + for (size_t i = 1; i < mSplitCount; i++) + { + Real fraction = (Real)i / (Real)mSplitCount; + Real splitPoint = lambda * nearDist * Math::Pow(farDist / nearDist, fraction) + + (1.0f - lambda) * (nearDist + fraction * (farDist - nearDist)); + + mSplitPoints[i] = splitPoint; + } + mSplitPoints[splitCount] = farDist; + + } + //--------------------------------------------------------------------- + void PSSMShadowCameraSetup::setSplitPoints(const SplitPointList& newSplitPoints) + { + if (newSplitPoints.size() < 3) // 3, not 2 since splits + 1 points + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot specify less than 2 splits", + "PSSMShadowCameraSetup::setSplitPoints"); + mSplitCount = static_cast(newSplitPoints.size() - 1); + mSplitPoints = newSplitPoints; + mOptimalAdjustFactors.resize(mSplitCount); + } + //--------------------------------------------------------------------- + void PSSMShadowCameraSetup::setOptimalAdjustFactor(size_t splitIndex, Real factor) + { + if (splitIndex >= mOptimalAdjustFactors.size()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Split index out of range", + "PSSMShadowCameraSetup::setOptimalAdjustFactor"); + mOptimalAdjustFactors[splitIndex] = factor; + + } + //--------------------------------------------------------------------- + Real PSSMShadowCameraSetup::getOptimalAdjustFactor() const + { + // simplifies the overriding of the LiSPSM opt adjust factor use + return mOptimalAdjustFactors[mCurrentIteration]; + } + //--------------------------------------------------------------------- + void PSSMShadowCameraSetup::getShadowCamera(const Ogre::SceneManager *sm, const Ogre::Camera *cam, + const Ogre::Viewport *vp, const Ogre::Light *light, Ogre::Camera *texCam, size_t iteration) const + { + // apply the right clip distance. + Real nearDist = mSplitPoints[iteration]; + Real farDist = mSplitPoints[iteration + 1]; + + // Add a padding factor to internal distances so that the connecting split point will not have bad artifacts. + if (iteration > 0) + { + nearDist -= mSplitPadding; + } + if (iteration < mSplitCount - 1) + { + farDist += mSplitPadding; + } + + mCurrentIteration = iteration; + + // Ouch, I know this is hacky, but it's the easiest way to re-use LiSPSM / Focused + // functionality right now without major changes + Camera* _cam = const_cast(cam); + Real oldNear = _cam->getNearClipDistance(); + Real oldFar = _cam->getFarClipDistance(); + _cam->setNearClipDistance(nearDist); + _cam->setFarClipDistance(farDist); + + LiSPSMShadowCameraSetup::getShadowCamera(sm, cam, vp, light, texCam, iteration); + + // restore near/far + _cam->setNearClipDistance(oldNear); + _cam->setFarClipDistance(oldFar); + + + } } diff --git a/OgreMain/src/OgreShadowCameraSetupPlaneOptimal.cpp b/OgreMain/src/OgreShadowCameraSetupPlaneOptimal.cpp index 183c223e36a..da29e96721d 100644 --- a/OgreMain/src/OgreShadowCameraSetupPlaneOptimal.cpp +++ b/OgreMain/src/OgreShadowCameraSetupPlaneOptimal.cpp @@ -44,287 +44,287 @@ THE SOFTWARE. namespace Ogre { - // -------------------------------------------------------------------- - Matrix4 PlaneOptimalShadowCameraSetup::computeConstrainedProjection( - const Vector4& pinhole, - const vector::type& fpoint, - const vector::type& constraint) const - { - // NOTE: will assume the z coordinates should be decided such that - // the first 3 points (in fpoint) will have post projective - // z coordinates of about +1 and the 4th (in fpoint) will have a - // post projective z coordinate of about -1. - - // TODO: could use SVD to avoid arbitrarily choosing one - // matrix element to be 1.0 (and thereby fix the scale). - - Matrix4 ret; - int i; - bool incrPrecision = false; // use to control numerical solving - - if(fpoint.size() < 4 || constraint.size() < 4) { - return Matrix4::IDENTITY; - } - - // allocate memory - PreciseReal **mat = NULL; - PreciseReal **backmat = NULL; - { - mat = OGRE_ALLOC_T(PreciseReal*, 11, MEMCATEGORY_SCENE_CONTROL); - if(incrPrecision) - backmat = OGRE_ALLOC_T(PreciseReal*, 11, MEMCATEGORY_SCENE_CONTROL); - for(i=0; i<11; i++) - { - mat[i] = OGRE_ALLOC_T(PreciseReal, 11, MEMCATEGORY_SCENE_CONTROL); - if(incrPrecision) - backmat[i] = OGRE_ALLOC_T(PreciseReal, 11, MEMCATEGORY_SCENE_CONTROL); - } - } - - // set up linear system to solve for all rows of projective matrix - // except for the 3rd which corresponds to mapping of z values - - // we choose a nonzero element of the last row to set to the arbitrary - // constant 1.0. - int nzind = 3; - PreciseReal col[11]; - PreciseReal backcol[11]; - - // fill in light position constraints - mat[0][0] = pinhole.x; - mat[0][1] = pinhole.y; - mat[0][2] = pinhole.z; - mat[0][3] = pinhole.w; - for(i=4; i<11; i++) - mat[0][i] = 0.0; - col[0] = 0.0; - - for(i=0; i<11; i++) - mat[1][i] = 0.0; - mat[1][4] = pinhole.x; - mat[1][5] = pinhole.y; - mat[1][6] = pinhole.z; - mat[1][7] = pinhole.w; - col[1] = 0.0; - - PreciseReal larr[4]; - larr[0] = pinhole.x; - larr[1] = pinhole.y; - larr[2] = pinhole.z; - larr[3] = pinhole.w; - for(i=0; i<8; i++) - mat[2][i] = 0.0; - int ind = 8; - for(i=0; i<4; i++) - { - if(nzind == i) - continue; - mat[2][ind++] = larr[i]; - } - col[2] = -larr[nzind]; - - // fill in all the other constraints - int row=3; - for(i=0; i<4; i++) - { - int j; - larr[0] = fpoint[i].x; - larr[1] = fpoint[i].y; - larr[2] = fpoint[i].z; - larr[3] = fpoint[i].w; - - // lexel s coordinate constraint - for(j=0; j<4; j++) - mat[row][j] = larr[j]; - for(j=4; j<8; j++) - mat[row][j] = 0.0; - ind=8; - for(j=0; j<4; j++) - { - if(nzind==j) - continue; - mat[row][ind++] = larr[j] * (-constraint[i].x); - } - col[row] = larr[nzind] * constraint[i].x; - ++row; - - // lexel t coordinate constraint - for(j=0; j<4; j++) - mat[row][j] = 0.0; - for(j=4; j<8; j++) - mat[row][j] = larr[j-4]; - - ind=8; - for(j=0; j<4; j++) - { - if(nzind==j) - continue; - mat[row][ind++] = larr[j] * (-constraint[i].y); - } - col[row] = larr[nzind] * constraint[i].y; - ++row; - } - - // copy the matrix and vector for later computation - if(incrPrecision) - { - for (i=0; i<11; i++) - { - for(int j=0; j<11; j++) - backmat[i][j] = mat[i][j]; - backcol[i] = col[i]; - } - } - - // solve for the matrix elements - if(!NumericSolver::solveNxNLinearSysDestr(11, mat, col)) - { - // error solving for projective matrix (rows 1,2,4) - } - - // get a little more precision - if(incrPrecision) - { - for (int k=0; k<3; k++) - { - PreciseReal nvec[11]; - for(i=0; i<11; i++) - { - int j; - nvec[i] = backmat[i][0] * col[0]; - mat[i][0] = backmat[i][0]; - for(j=1; j<11; j++) - { - nvec[i] += backmat[i][j] * col[j]; - mat[i][j] = backmat[i][j]; - } - nvec[i] -= backcol[i]; - } - if(!NumericSolver::solveNxNLinearSysDestr(11, mat, nvec)) - { - // error solving for increased precision rows 1,2,4 - } - for(i=0; i<11; i++) - col[i] -= nvec[i]; - } - } - - PreciseReal row4[4]; - ind = 8; - for(i=0; i<4; i++) - { - if (i == nzind) - row4[i] = 1.0; - else - row4[i] = col[ind++]; - } - - - // now solve for the 3rd row which affects depth precision - PreciseReal zrow[4]; - - // we want the affine skew such that isoplanes of constant depth are parallel to - // the world plane of interest - // NOTE: recall we perturbed the last fpoint off the plane, so we'll again modify - // this one since we want 3 points on the plane = far plane, and 1 on the near plane - int nearind = 3; - for(i=0; i<3; i++) - { - mat[i][0] = fpoint[i].x; - mat[i][1] = fpoint[i].y; - mat[i][2] = fpoint[i].z; - mat[i][3] = 1.0; - zrow[i] = (row4[0] * fpoint[i].x + - row4[1] * fpoint[i].y + - row4[2] * fpoint[i].z + - row4[3]) * 0.99 ; - } - mat[3][0] = fpoint[nearind].x; - mat[3][1] = fpoint[nearind].y; - mat[3][2] = fpoint[nearind].z; - mat[3][3] = 1.0; - zrow[3] = -row4[0] * fpoint[nearind].x - - row4[1] * fpoint[nearind].y - - row4[2] * fpoint[nearind].z - - row4[3] ; - - // solve for the z row of the matrix - if(!NumericSolver::solveNxNLinearSysDestr(4, mat, zrow)) - { - // error solving for projective matrix (row 3) - } - - // set projective texture matrix - ret = Matrix4( col[0], col[1], col[2], col[3], - col[4], col[5], col[6], col[7], - zrow[0], zrow[1], zrow[2], zrow[3], - row4[0], row4[1], row4[2], row4[3] ); - - - // check for clip - Vector4 testCoord = ret * fpoint[0]; - if(testCoord.w < 0.0) - ret = ret * (-1.0); - - // free memory - for (i=0; i<11; i++) - { - if (mat[i]) - OGRE_FREE(mat[i], MEMCATEGORY_SCENE_CONTROL); - if (incrPrecision) - OGRE_FREE(backmat[i], MEMCATEGORY_SCENE_CONTROL); - } - OGRE_FREE(mat, MEMCATEGORY_SCENE_CONTROL); - if(incrPrecision) - OGRE_FREE(backmat, MEMCATEGORY_SCENE_CONTROL); - - return ret; - - } - - // -------------------------------------------------------------------- - - /// Construct object to consider a specified plane of interest - PlaneOptimalShadowCameraSetup::PlaneOptimalShadowCameraSetup(MovablePlane* plane) - { - mPlane = plane; - } - - /// Destructor - PlaneOptimalShadowCameraSetup::~PlaneOptimalShadowCameraSetup() {} - - /// Implements the plane optimal shadow camera setup algorithm - void PlaneOptimalShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, - const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const - { - // get the plane transformed by the parent node(s) - // Also, make sure the plane is normalized - Plane worldPlane = mPlane->_getDerivedPlane(); - worldPlane.normalise(); - - // get camera's projection matrix - Matrix4 camProjection = cam->getProjectionMatrix() * cam->getViewMatrix(); - - // get the world points to constrain - vector::type vhull; - cam->forwardIntersect(worldPlane, &vhull); - if (vhull.size() < 4) - return; - - // make sure the last point is a finite point (not point at infinity) + // -------------------------------------------------------------------- + Matrix4 PlaneOptimalShadowCameraSetup::computeConstrainedProjection( + const Vector4& pinhole, + const vector::type& fpoint, + const vector::type& constraint) const + { + // NOTE: will assume the z coordinates should be decided such that + // the first 3 points (in fpoint) will have post projective + // z coordinates of about +1 and the 4th (in fpoint) will have a + // post projective z coordinate of about -1. + + // TODO: could use SVD to avoid arbitrarily choosing one + // matrix element to be 1.0 (and thereby fix the scale). + + Matrix4 ret; + int i; + bool incrPrecision = false; // use to control numerical solving + + if(fpoint.size() < 4 || constraint.size() < 4) { + return Matrix4::IDENTITY; + } + + // allocate memory + PreciseReal **mat = NULL; + PreciseReal **backmat = NULL; + { + mat = OGRE_ALLOC_T(PreciseReal*, 11, MEMCATEGORY_SCENE_CONTROL); + if(incrPrecision) + backmat = OGRE_ALLOC_T(PreciseReal*, 11, MEMCATEGORY_SCENE_CONTROL); + for(i=0; i<11; i++) + { + mat[i] = OGRE_ALLOC_T(PreciseReal, 11, MEMCATEGORY_SCENE_CONTROL); + if(incrPrecision) + backmat[i] = OGRE_ALLOC_T(PreciseReal, 11, MEMCATEGORY_SCENE_CONTROL); + } + } + + // set up linear system to solve for all rows of projective matrix + // except for the 3rd which corresponds to mapping of z values + + // we choose a nonzero element of the last row to set to the arbitrary + // constant 1.0. + int nzind = 3; + PreciseReal col[11]; + PreciseReal backcol[11]; + + // fill in light position constraints + mat[0][0] = pinhole.x; + mat[0][1] = pinhole.y; + mat[0][2] = pinhole.z; + mat[0][3] = pinhole.w; + for(i=4; i<11; i++) + mat[0][i] = 0.0; + col[0] = 0.0; + + for(i=0; i<11; i++) + mat[1][i] = 0.0; + mat[1][4] = pinhole.x; + mat[1][5] = pinhole.y; + mat[1][6] = pinhole.z; + mat[1][7] = pinhole.w; + col[1] = 0.0; + + PreciseReal larr[4]; + larr[0] = pinhole.x; + larr[1] = pinhole.y; + larr[2] = pinhole.z; + larr[3] = pinhole.w; + for(i=0; i<8; i++) + mat[2][i] = 0.0; + int ind = 8; + for(i=0; i<4; i++) + { + if(nzind == i) + continue; + mat[2][ind++] = larr[i]; + } + col[2] = -larr[nzind]; + + // fill in all the other constraints + int row=3; + for(i=0; i<4; i++) + { + int j; + larr[0] = fpoint[i].x; + larr[1] = fpoint[i].y; + larr[2] = fpoint[i].z; + larr[3] = fpoint[i].w; + + // lexel s coordinate constraint + for(j=0; j<4; j++) + mat[row][j] = larr[j]; + for(j=4; j<8; j++) + mat[row][j] = 0.0; + ind=8; + for(j=0; j<4; j++) + { + if(nzind==j) + continue; + mat[row][ind++] = larr[j] * (-constraint[i].x); + } + col[row] = larr[nzind] * constraint[i].x; + ++row; + + // lexel t coordinate constraint + for(j=0; j<4; j++) + mat[row][j] = 0.0; + for(j=4; j<8; j++) + mat[row][j] = larr[j-4]; + + ind=8; + for(j=0; j<4; j++) + { + if(nzind==j) + continue; + mat[row][ind++] = larr[j] * (-constraint[i].y); + } + col[row] = larr[nzind] * constraint[i].y; + ++row; + } + + // copy the matrix and vector for later computation + if(incrPrecision) + { + for (i=0; i<11; i++) + { + for(int j=0; j<11; j++) + backmat[i][j] = mat[i][j]; + backcol[i] = col[i]; + } + } + + // solve for the matrix elements + if(!NumericSolver::solveNxNLinearSysDestr(11, mat, col)) + { + // error solving for projective matrix (rows 1,2,4) + } + + // get a little more precision + if(incrPrecision) + { + for (int k=0; k<3; k++) + { + PreciseReal nvec[11]; + for(i=0; i<11; i++) + { + int j; + nvec[i] = backmat[i][0] * col[0]; + mat[i][0] = backmat[i][0]; + for(j=1; j<11; j++) + { + nvec[i] += backmat[i][j] * col[j]; + mat[i][j] = backmat[i][j]; + } + nvec[i] -= backcol[i]; + } + if(!NumericSolver::solveNxNLinearSysDestr(11, mat, nvec)) + { + // error solving for increased precision rows 1,2,4 + } + for(i=0; i<11; i++) + col[i] -= nvec[i]; + } + } + + PreciseReal row4[4]; + ind = 8; + for(i=0; i<4; i++) + { + if (i == nzind) + row4[i] = 1.0; + else + row4[i] = col[ind++]; + } + + + // now solve for the 3rd row which affects depth precision + PreciseReal zrow[4]; + + // we want the affine skew such that isoplanes of constant depth are parallel to + // the world plane of interest + // NOTE: recall we perturbed the last fpoint off the plane, so we'll again modify + // this one since we want 3 points on the plane = far plane, and 1 on the near plane + int nearind = 3; + for(i=0; i<3; i++) + { + mat[i][0] = fpoint[i].x; + mat[i][1] = fpoint[i].y; + mat[i][2] = fpoint[i].z; + mat[i][3] = 1.0; + zrow[i] = (row4[0] * fpoint[i].x + + row4[1] * fpoint[i].y + + row4[2] * fpoint[i].z + + row4[3]) * 0.99 ; + } + mat[3][0] = fpoint[nearind].x; + mat[3][1] = fpoint[nearind].y; + mat[3][2] = fpoint[nearind].z; + mat[3][3] = 1.0; + zrow[3] = -row4[0] * fpoint[nearind].x - + row4[1] * fpoint[nearind].y - + row4[2] * fpoint[nearind].z - + row4[3] ; + + // solve for the z row of the matrix + if(!NumericSolver::solveNxNLinearSysDestr(4, mat, zrow)) + { + // error solving for projective matrix (row 3) + } + + // set projective texture matrix + ret = Matrix4( col[0], col[1], col[2], col[3], + col[4], col[5], col[6], col[7], + zrow[0], zrow[1], zrow[2], zrow[3], + row4[0], row4[1], row4[2], row4[3] ); + + + // check for clip + Vector4 testCoord = ret * fpoint[0]; + if(testCoord.w < 0.0) + ret = ret * (-1.0); + + // free memory + for (i=0; i<11; i++) + { + if (mat[i]) + OGRE_FREE(mat[i], MEMCATEGORY_SCENE_CONTROL); + if (incrPrecision) + OGRE_FREE(backmat[i], MEMCATEGORY_SCENE_CONTROL); + } + OGRE_FREE(mat, MEMCATEGORY_SCENE_CONTROL); + if(incrPrecision) + OGRE_FREE(backmat, MEMCATEGORY_SCENE_CONTROL); + + return ret; + + } + + // -------------------------------------------------------------------- + + /// Construct object to consider a specified plane of interest + PlaneOptimalShadowCameraSetup::PlaneOptimalShadowCameraSetup(MovablePlane* plane) + { + mPlane = plane; + } + + /// Destructor + PlaneOptimalShadowCameraSetup::~PlaneOptimalShadowCameraSetup() {} + + /// Implements the plane optimal shadow camera setup algorithm + void PlaneOptimalShadowCameraSetup::getShadowCamera (const SceneManager *sm, const Camera *cam, + const Viewport *vp, const Light *light, Camera *texCam, size_t iteration) const + { + // get the plane transformed by the parent node(s) + // Also, make sure the plane is normalized + Plane worldPlane = mPlane->_getDerivedPlane(); + worldPlane.normalise(); + + // get camera's projection matrix + Matrix4 camProjection = cam->getProjectionMatrix() * cam->getViewMatrix(); + + // get the world points to constrain + vector::type vhull; + cam->forwardIntersect(worldPlane, &vhull); + if (vhull.size() < 4) + return; + + // make sure the last point is a finite point (not point at infinity) if (vhull[3].w == 0.0) { - int finiteIndex = -1; - for (uint loopIndex = 0; loopIndex < vhull.size(); loopIndex++) - { - if (vhull[loopIndex].w != 0.0) + int finiteIndex = -1; + for (uint loopIndex = 0; loopIndex < vhull.size(); loopIndex++) + { + if (vhull[loopIndex].w != 0.0) { - finiteIndex = loopIndex; + finiteIndex = loopIndex; break; } - } - if (finiteIndex == -1) - { + } + if (finiteIndex == -1) + { // there are no finite points, which means camera doesn't see plane of interest. // so we don't care what the shadow map matrix is // We'll map points off the shadow map so they aren't even stored @@ -333,26 +333,26 @@ namespace Ogre 0.0, 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 1.0); texCam->setCustomViewMatrix(true, Matrix4::IDENTITY); - texCam->setCustomProjectionMatrix(true, crazyMat); + texCam->setCustomProjectionMatrix(true, crazyMat); return; - } + } // swap finite point to last point std::swap(vhull[3], vhull[finiteIndex]); } vhull.resize(4); - // get the post-projective coordinate constraints - vector::type constraint; - for (int i=0; i<4; i++) - { - Vector4 postProjPt = camProjection * vhull[i]; - postProjPt *= 1.0 / postProjPt.w; - constraint.push_back(Vector2(postProjPt.x, postProjPt.y)); - } - - // perturb one point so we don't have coplanarity - const Vector4& pinhole = light->getAs4DVector(); - const Vector4& oldPt = vhull.back(); + // get the post-projective coordinate constraints + vector::type constraint; + for (int i=0; i<4; i++) + { + Vector4 postProjPt = camProjection * vhull[i]; + postProjPt *= 1.0 / postProjPt.w; + constraint.push_back(Vector2(postProjPt.x, postProjPt.y)); + } + + // perturb one point so we don't have coplanarity + const Vector4& pinhole = light->getAs4DVector(); + const Vector4& oldPt = vhull.back(); Vector4 newPt; if (pinhole.w == 0) { @@ -363,16 +363,16 @@ namespace Ogre else { // It's point or spotlight - Vector4 displacement = oldPt - pinhole; - Vector3 displace3 = Vector3(displacement.x, displacement.y, displacement.z); - Real dotProd = fabs(displace3.dotProduct(worldPlane.normal)); - static const Real NEAR_FACTOR = 0.05; - newPt = pinhole + (displacement * (cam->getNearClipDistance() * NEAR_FACTOR / dotProd)); + Vector4 displacement = oldPt - pinhole; + Vector3 displace3 = Vector3(displacement.x, displacement.y, displacement.z); + Real dotProd = fabs(displace3.dotProduct(worldPlane.normal)); + static const Real NEAR_FACTOR = 0.05; + newPt = pinhole + (displacement * (cam->getNearClipDistance() * NEAR_FACTOR / dotProd)); } - vhull.back() = newPt; + vhull.back() = newPt; - // solve for the matrix that stabilizes the plane - Matrix4 customMatrix = computeConstrainedProjection(pinhole, vhull, constraint); + // solve for the matrix that stabilizes the plane + Matrix4 customMatrix = computeConstrainedProjection(pinhole, vhull, constraint); if (pinhole.w == 0) { @@ -386,40 +386,40 @@ namespace Ogre Vector3 tempPos = Vector3(pinhole.x, pinhole.y, pinhole.z); - // factor into view and projection pieces - Matrix4 translation(1.0, 0.0, 0.0, tempPos.x, - 0.0, 1.0, 0.0, tempPos.y, - 0.0, 0.0, 1.0, tempPos.z, - 0.0, 0.0, 0.0, 1.0); - Matrix4 invTranslation(1.0, 0.0, 0.0, -tempPos.x, - 0.0, 1.0, 0.0, -tempPos.y, - 0.0, 0.0, 1.0, -tempPos.z, - 0.0, 0.0, 0.0, 1.0); - Matrix4 tempMatrix = customMatrix * translation; - Vector3 zRow(-tempMatrix[3][0], -tempMatrix[3][1], -tempMatrix[3][2]); - zRow.normalise(); - Vector3 up; - if (zRow.y == 1.0) - up = Vector3(1,0,0); - else - up = Vector3(0,1,0); - Vector3 xDir = up.crossProduct(zRow); - xDir.normalise(); - up = zRow.crossProduct(xDir); - Matrix4 rotation(xDir.x, up.x, zRow.x, 0.0, - xDir.y, up.y, zRow.y, 0.0, - xDir.z, up.z, zRow.z, 0.0, - 0.0, 0.0, 0.0, 1.0 ); - Matrix4 customProj = tempMatrix * rotation; - Matrix4 customView = rotation.transpose() * invTranslation; - // note: now customProj * (0,0,0,1)^t = (0, 0, k, 0)^t for k some constant - // note: also customProj's 4th row is (0, 0, c, 0) for some negative c. - - - // set the shadow map camera - texCam->setCustomViewMatrix(true, customView); - texCam->setCustomProjectionMatrix(true, customProj); - } + // factor into view and projection pieces + Matrix4 translation(1.0, 0.0, 0.0, tempPos.x, + 0.0, 1.0, 0.0, tempPos.y, + 0.0, 0.0, 1.0, tempPos.z, + 0.0, 0.0, 0.0, 1.0); + Matrix4 invTranslation(1.0, 0.0, 0.0, -tempPos.x, + 0.0, 1.0, 0.0, -tempPos.y, + 0.0, 0.0, 1.0, -tempPos.z, + 0.0, 0.0, 0.0, 1.0); + Matrix4 tempMatrix = customMatrix * translation; + Vector3 zRow(-tempMatrix[3][0], -tempMatrix[3][1], -tempMatrix[3][2]); + zRow.normalise(); + Vector3 up; + if (zRow.y == 1.0) + up = Vector3(1,0,0); + else + up = Vector3(0,1,0); + Vector3 xDir = up.crossProduct(zRow); + xDir.normalise(); + up = zRow.crossProduct(xDir); + Matrix4 rotation(xDir.x, up.x, zRow.x, 0.0, + xDir.y, up.y, zRow.y, 0.0, + xDir.z, up.z, zRow.z, 0.0, + 0.0, 0.0, 0.0, 1.0 ); + Matrix4 customProj = tempMatrix * rotation; + Matrix4 customView = rotation.transpose() * invTranslation; + // note: now customProj * (0,0,0,1)^t = (0, 0, k, 0)^t for k some constant + // note: also customProj's 4th row is (0, 0, c, 0) for some negative c. + + + // set the shadow map camera + texCam->setCustomViewMatrix(true, customView); + texCam->setCustomProjectionMatrix(true, customProj); + } } diff --git a/OgreMain/src/OgreShadowCaster.cpp b/OgreMain/src/OgreShadowCaster.cpp index b9449085b65..f2b82a88dd4 100644 --- a/OgreMain/src/OgreShadowCaster.cpp +++ b/OgreMain/src/OgreShadowCaster.cpp @@ -34,463 +34,463 @@ THE SOFTWARE. #include "OgreSceneManager.h" namespace Ogre { - const LightList& ShadowRenderable::getLights(void) const - { - // return empty - static LightList ll; - return ll; - } - // ------------------------------------------------------------------------ - void ShadowCaster::updateEdgeListLightFacing(EdgeData* edgeData, - const Vector4& lightPos) - { - edgeData->updateTriangleLightFacing(lightPos); - } - // ------------------------------------------------------------------------ - void ShadowCaster::generateShadowVolume(EdgeData* edgeData, - const HardwareIndexBufferSharedPtr& indexBuffer, size_t& indexBufferUsedSize, - const Light* light, ShadowRenderableList& shadowRenderables, unsigned long flags) - { - // Edge groups should be 1:1 with shadow renderables - assert(edgeData->edgeGroups.size() == shadowRenderables.size()); - - Light::LightTypes lightType = light->getType(); - - // Whether to use the McGuire method, a triangle fan covering all silhouette - // This won't work properly with multiple separate edge groups (should be one fan per group, not implemented) + const LightList& ShadowRenderable::getLights(void) const + { + // return empty + static LightList ll; + return ll; + } + // ------------------------------------------------------------------------ + void ShadowCaster::updateEdgeListLightFacing(EdgeData* edgeData, + const Vector4& lightPos) + { + edgeData->updateTriangleLightFacing(lightPos); + } + // ------------------------------------------------------------------------ + void ShadowCaster::generateShadowVolume(EdgeData* edgeData, + const HardwareIndexBufferSharedPtr& indexBuffer, size_t& indexBufferUsedSize, + const Light* light, ShadowRenderableList& shadowRenderables, unsigned long flags) + { + // Edge groups should be 1:1 with shadow renderables + assert(edgeData->edgeGroups.size() == shadowRenderables.size()); + + Light::LightTypes lightType = light->getType(); + + // Whether to use the McGuire method, a triangle fan covering all silhouette + // This won't work properly with multiple separate edge groups (should be one fan per group, not implemented) // or when light position is inside light cap bound as extrusion could be in opposite directions // and McGuire cap could intersect near clip plane of camera frustum without being noticed. - bool useMcGuire = edgeData->edgeGroups.size() <= 1 && + bool useMcGuire = edgeData->edgeGroups.size() <= 1 && (lightType == Light::LT_DIRECTIONAL || !getLightCapBounds().contains(light->getDerivedPosition())); - EdgeData::EdgeGroupList::const_iterator egi, egiend; - ShadowRenderableList::const_iterator si; - - // pre-count the size of index data we need since it makes a big perf difference - // to GL in particular if we lock a smaller area of the index buffer - size_t preCountIndexes = 0; - - si = shadowRenderables.begin(); - egiend = edgeData->edgeGroups.end(); - for (egi = edgeData->edgeGroups.begin(); egi != egiend; ++egi, ++si) - { - const EdgeData::EdgeGroup& eg = *egi; - bool firstDarkCapTri = true; - - EdgeData::EdgeList::const_iterator i, iend; - iend = eg.edges.end(); - for (i = eg.edges.begin(); i != iend; ++i) - { - const EdgeData::Edge& edge = *i; - - // Silhouette edge, when two tris has opposite light facing, or - // degenerate edge where only tri 1 is valid and the tri light facing - char lightFacing = edgeData->triangleLightFacings[edge.triIndex[0]]; - if ((edge.degenerate && lightFacing) || - (!edge.degenerate && (lightFacing != edgeData->triangleLightFacings[edge.triIndex[1]]))) - { - - preCountIndexes += 3; - - // Are we extruding to infinity? - if (!(lightType == Light::LT_DIRECTIONAL && - flags & SRF_EXTRUDE_TO_INFINITY)) - { - preCountIndexes += 3; - } - - if(useMcGuire) - { - // Do dark cap tri - // Use McGuire et al method, a triangle fan covering all silhouette - // edges and one point (taken from the initial tri) - if (flags & SRF_INCLUDE_DARK_CAP) - { - if (firstDarkCapTri) - { - firstDarkCapTri = false; - } - else - { - preCountIndexes += 3; - } - } - } - } - - } - - if(useMcGuire) - { - // Do light cap - if (flags & SRF_INCLUDE_LIGHT_CAP) - { - // Iterate over the triangles which are using this vertex set - EdgeData::TriangleList::const_iterator ti, tiend; - EdgeData::TriangleLightFacingList::const_iterator lfi; - ti = edgeData->triangles.begin() + eg.triStart; - tiend = ti + eg.triCount; - lfi = edgeData->triangleLightFacings.begin() + eg.triStart; - for ( ; ti != tiend; ++ti, ++lfi) - { - assert(ti->vertexSet == eg.vertexSet); - // Check it's light facing - if (*lfi) - { - preCountIndexes += 3; - } - } - - } - } - else - { - // Do both caps - int increment = ((flags & SRF_INCLUDE_DARK_CAP) ? 3 : 0) + ((flags & SRF_INCLUDE_LIGHT_CAP) ? 3 : 0); - if(increment != 0) - { - // Iterate over the triangles which are using this vertex set - EdgeData::TriangleList::const_iterator ti, tiend; - EdgeData::TriangleLightFacingList::const_iterator lfi; - ti = edgeData->triangles.begin() + eg.triStart; - tiend = ti + eg.triCount; - lfi = edgeData->triangleLightFacings.begin() + eg.triStart; - for ( ; ti != tiend; ++ti, ++lfi) - { - assert(ti->vertexSet == eg.vertexSet); - // Check it's light facing - if (*lfi) - preCountIndexes += increment; - } - } - } - } - // End pre-count - - //Check if index buffer is to small - if (preCountIndexes > indexBuffer->getNumIndexes()) - { - LogManager::getSingleton().logMessage(LML_CRITICAL, - String("Warning: shadow index buffer size to small. Auto increasing buffer size to") + - StringConverter::toString(sizeof(unsigned short) * preCountIndexes)); - - SceneManager* pManager = Root::getSingleton()._getCurrentSceneManager(); - if (pManager) - { - pManager->setShadowIndexBufferSize(preCountIndexes); - } - - //Check that the index buffer size has actually increased - if (preCountIndexes > indexBuffer->getNumIndexes()) - { - //increasing index buffer size has failed - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Lock request out of bounds.", - "ShadowCaster::generateShadowVolume"); - } - } - else if(indexBufferUsedSize + preCountIndexes > indexBuffer->getNumIndexes()) - { - indexBufferUsedSize = 0; - } - - // Lock index buffer for writing, just enough length as we need - unsigned short* pIdx = static_cast( - indexBuffer->lock(sizeof(unsigned short) * indexBufferUsedSize, sizeof(unsigned short) * preCountIndexes, - indexBufferUsedSize == 0 ? HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NO_OVERWRITE)); - size_t numIndices = indexBufferUsedSize; - - // Iterate over the groups and form renderables for each based on their - // lightFacing - si = shadowRenderables.begin(); - egiend = edgeData->edgeGroups.end(); - for (egi = edgeData->edgeGroups.begin(); egi != egiend; ++egi, ++si) - { - const EdgeData::EdgeGroup& eg = *egi; - // Initialise the index start for this shadow renderable - IndexData* indexData = (*si)->getRenderOperationForUpdate()->indexData; - - if (indexData->indexBuffer != indexBuffer) - { - (*si)->rebindIndexBuffer(indexBuffer); - indexData = (*si)->getRenderOperationForUpdate()->indexData; - } - - indexData->indexStart = numIndices; - // original number of verts (without extruded copy) - size_t originalVertexCount = eg.vertexData->vertexCount; - bool firstDarkCapTri = true; - unsigned short darkCapStart = 0; - - EdgeData::EdgeList::const_iterator i, iend; - iend = eg.edges.end(); - for (i = eg.edges.begin(); i != iend; ++i) - { - const EdgeData::Edge& edge = *i; - - // Silhouette edge, when two tris has opposite light facing, or - // degenerate edge where only tri 1 is valid and the tri light facing - char lightFacing = edgeData->triangleLightFacings[edge.triIndex[0]]; - if ((edge.degenerate && lightFacing) || - (!edge.degenerate && (lightFacing != edgeData->triangleLightFacings[edge.triIndex[1]]))) - { - size_t v0 = edge.vertIndex[0]; - size_t v1 = edge.vertIndex[1]; - if (!lightFacing) - { - // Inverse edge indexes when t1 is light away - std::swap(v0, v1); - } - - /* Note edge(v0, v1) run anticlockwise along the edge from - the light facing tri so to point shadow volume tris outward, - light cap indexes have to be backwards - - We emit 2 tris if light is a point light, 1 if light - is directional, because directional lights cause all - points to converge to a single point at infinity. - - First side tri = near1, near0, far0 - Second tri = far0, far1, near1 - - 'far' indexes are 'near' index + originalVertexCount - because 'far' verts are in the second half of the - buffer - */ - assert(v1 < 65536 && v0 < 65536 && (v0 + originalVertexCount) < 65536 && - "Vertex count exceeds 16-bit index limit!"); - *pIdx++ = static_cast(v1); - *pIdx++ = static_cast(v0); - *pIdx++ = static_cast(v0 + originalVertexCount); - numIndices += 3; - - // Are we extruding to infinity? - if (!(lightType == Light::LT_DIRECTIONAL && - flags & SRF_EXTRUDE_TO_INFINITY)) - { - // additional tri to make quad - *pIdx++ = static_cast(v0 + originalVertexCount); - *pIdx++ = static_cast(v1 + originalVertexCount); - *pIdx++ = static_cast(v1); - numIndices += 3; - } - - if(useMcGuire) - { - // Do dark cap tri - // Use McGuire et al method, a triangle fan covering all silhouette - // edges and one point (taken from the initial tri) - if (flags & SRF_INCLUDE_DARK_CAP) - { - if (firstDarkCapTri) - { - darkCapStart = static_cast(v0 + originalVertexCount); - firstDarkCapTri = false; - } - else - { - *pIdx++ = darkCapStart; - *pIdx++ = static_cast(v1 + originalVertexCount); - *pIdx++ = static_cast(v0 + originalVertexCount); - numIndices += 3; - } - - } - } - } - - } - - if(!useMcGuire) - { - // Do dark cap - if (flags & SRF_INCLUDE_DARK_CAP) - { - // Iterate over the triangles which are using this vertex set - EdgeData::TriangleList::const_iterator ti, tiend; - EdgeData::TriangleLightFacingList::const_iterator lfi; - ti = edgeData->triangles.begin() + eg.triStart; - tiend = ti + eg.triCount; - lfi = edgeData->triangleLightFacings.begin() + eg.triStart; - for ( ; ti != tiend; ++ti, ++lfi) - { - const EdgeData::Triangle& t = *ti; - assert(t.vertexSet == eg.vertexSet); - // Check it's light facing - if (*lfi) - { - assert(t.vertIndex[0] < 65536 && t.vertIndex[1] < 65536 && - t.vertIndex[2] < 65536 && - "16-bit index limit exceeded!"); - *pIdx++ = static_cast(t.vertIndex[1] + originalVertexCount); - *pIdx++ = static_cast(t.vertIndex[0] + originalVertexCount); - *pIdx++ = static_cast(t.vertIndex[2] + originalVertexCount); - numIndices += 3; - } - } - - } - } - - // Do light cap - if (flags & SRF_INCLUDE_LIGHT_CAP) - { - // separate light cap? - if ((*si)->isLightCapSeparate()) - { - // update index count for this shadow renderable - indexData->indexCount = numIndices - indexData->indexStart; - - // get light cap index data for update - indexData = (*si)->getLightCapRenderable()->getRenderOperationForUpdate()->indexData; - // start indexes after the current total - indexData->indexStart = numIndices; - } - - // Iterate over the triangles which are using this vertex set - EdgeData::TriangleList::const_iterator ti, tiend; - EdgeData::TriangleLightFacingList::const_iterator lfi; - ti = edgeData->triangles.begin() + eg.triStart; - tiend = ti + eg.triCount; - lfi = edgeData->triangleLightFacings.begin() + eg.triStart; - for ( ; ti != tiend; ++ti, ++lfi) - { - const EdgeData::Triangle& t = *ti; - assert(t.vertexSet == eg.vertexSet); - // Check it's light facing - if (*lfi) - { - assert(t.vertIndex[0] < 65536 && t.vertIndex[1] < 65536 && - t.vertIndex[2] < 65536 && - "16-bit index limit exceeded!"); - *pIdx++ = static_cast(t.vertIndex[0]); - *pIdx++ = static_cast(t.vertIndex[1]); - *pIdx++ = static_cast(t.vertIndex[2]); - numIndices += 3; - } - } - - } - - // update index count for current index data (either this shadow renderable or its light cap) - indexData->indexCount = numIndices - indexData->indexStart; - - } - - // Unlock index buffer - indexBuffer->unlock(); - - // In debug mode, check we didn't overrun the index buffer - assert(numIndices == indexBufferUsedSize + preCountIndexes); - assert(numIndices <= indexBuffer->getNumIndexes() && - "Index buffer overrun while generating shadow volume!! " - "You must increase the size of the shadow index buffer."); - - indexBufferUsedSize = numIndices; - } - // ------------------------------------------------------------------------ - void ShadowCaster::extrudeVertices( - const HardwareVertexBufferSharedPtr& vertexBuffer, - size_t originalVertexCount, const Vector4& light, Real extrudeDist) - { - assert (vertexBuffer->getVertexSize() == sizeof(float) * 3 - && "Position buffer should contain only positions!"); - - // Extrude the first area of the buffer into the second area - // Lock the entire buffer for writing, even though we'll only be - // updating the latter because you can't have 2 locks on the same - // buffer - float* pSrc = static_cast( - vertexBuffer->lock(HardwareBuffer::HBL_NORMAL)); - - // TODO: We should add extra (ununsed) vertices ensure source and - // destination buffer have same alignment for slight performance gain. - float* pDest = pSrc + originalVertexCount * 3; - - OptimisedUtil::getImplementation()->extrudeVertices( - light, extrudeDist, - pSrc, pDest, originalVertexCount); - - vertexBuffer->unlock(); - - } - // ------------------------------------------------------------------------ - void ShadowCaster::extrudeBounds(AxisAlignedBox& box, const Vector4& light, Real extrudeDist) const - { - Vector3 extrusionDir; - - if (light.w == 0) - { - // Parallel projection guarantees min/max relationship remains the same - extrusionDir.x = -light.x; - extrusionDir.y = -light.y; - extrusionDir.z = -light.z; - extrusionDir.normalise(); - extrusionDir *= extrudeDist; - box.setExtents(box.getMinimum() + extrusionDir, - box.getMaximum() + extrusionDir); - } - else - { - Vector3 oldMin, oldMax, currentCorner; - // Getting the original values - oldMin = box.getMinimum(); - oldMax = box.getMaximum(); - // Starting the box again with a null content - box.setNull(); - - // merging all the extruded corners - - // 0 : min min min - currentCorner = oldMin; - extrusionDir.x = currentCorner.x - light.x; - extrusionDir.y = currentCorner.y - light.y; - extrusionDir.z = currentCorner.z - light.z; - box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); - - // 6 : min min max - // only z has changed - currentCorner.z = oldMax.z; - extrusionDir.z = currentCorner.z - light.z; - box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); - - // 5 : min max max - currentCorner.y = oldMax.y; - extrusionDir.y = currentCorner.y - light.y; - box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); - - // 1 : min max min - currentCorner.z = oldMin.z; - extrusionDir.z = currentCorner.z - light.z; - box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); - - // 2 : max max min - currentCorner.x = oldMax.x; - extrusionDir.x = currentCorner.x - light.x; - box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); - - // 4 : max max max - currentCorner.z = oldMax.z; - extrusionDir.z = currentCorner.z - light.z; - box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); - - // 7 : max min max - currentCorner.y = oldMin.y; - extrusionDir.y = currentCorner.y - light.y; - box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); - - // 3 : max min min - currentCorner.z = oldMin.z; - extrusionDir.z = currentCorner.z - light.z; - box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); - - } - - } - // ------------------------------------------------------------------------ - Real ShadowCaster::getExtrusionDistance(const Vector3& objectPos, const Light* light) const - { - Vector3 diff = objectPos - light->getDerivedPosition(); - return light->getAttenuationRange() - diff.length(); - } + EdgeData::EdgeGroupList::const_iterator egi, egiend; + ShadowRenderableList::const_iterator si; + + // pre-count the size of index data we need since it makes a big perf difference + // to GL in particular if we lock a smaller area of the index buffer + size_t preCountIndexes = 0; + + si = shadowRenderables.begin(); + egiend = edgeData->edgeGroups.end(); + for (egi = edgeData->edgeGroups.begin(); egi != egiend; ++egi, ++si) + { + const EdgeData::EdgeGroup& eg = *egi; + bool firstDarkCapTri = true; + + EdgeData::EdgeList::const_iterator i, iend; + iend = eg.edges.end(); + for (i = eg.edges.begin(); i != iend; ++i) + { + const EdgeData::Edge& edge = *i; + + // Silhouette edge, when two tris has opposite light facing, or + // degenerate edge where only tri 1 is valid and the tri light facing + char lightFacing = edgeData->triangleLightFacings[edge.triIndex[0]]; + if ((edge.degenerate && lightFacing) || + (!edge.degenerate && (lightFacing != edgeData->triangleLightFacings[edge.triIndex[1]]))) + { + + preCountIndexes += 3; + + // Are we extruding to infinity? + if (!(lightType == Light::LT_DIRECTIONAL && + flags & SRF_EXTRUDE_TO_INFINITY)) + { + preCountIndexes += 3; + } + + if(useMcGuire) + { + // Do dark cap tri + // Use McGuire et al method, a triangle fan covering all silhouette + // edges and one point (taken from the initial tri) + if (flags & SRF_INCLUDE_DARK_CAP) + { + if (firstDarkCapTri) + { + firstDarkCapTri = false; + } + else + { + preCountIndexes += 3; + } + } + } + } + + } + + if(useMcGuire) + { + // Do light cap + if (flags & SRF_INCLUDE_LIGHT_CAP) + { + // Iterate over the triangles which are using this vertex set + EdgeData::TriangleList::const_iterator ti, tiend; + EdgeData::TriangleLightFacingList::const_iterator lfi; + ti = edgeData->triangles.begin() + eg.triStart; + tiend = ti + eg.triCount; + lfi = edgeData->triangleLightFacings.begin() + eg.triStart; + for ( ; ti != tiend; ++ti, ++lfi) + { + assert(ti->vertexSet == eg.vertexSet); + // Check it's light facing + if (*lfi) + { + preCountIndexes += 3; + } + } + + } + } + else + { + // Do both caps + int increment = ((flags & SRF_INCLUDE_DARK_CAP) ? 3 : 0) + ((flags & SRF_INCLUDE_LIGHT_CAP) ? 3 : 0); + if(increment != 0) + { + // Iterate over the triangles which are using this vertex set + EdgeData::TriangleList::const_iterator ti, tiend; + EdgeData::TriangleLightFacingList::const_iterator lfi; + ti = edgeData->triangles.begin() + eg.triStart; + tiend = ti + eg.triCount; + lfi = edgeData->triangleLightFacings.begin() + eg.triStart; + for ( ; ti != tiend; ++ti, ++lfi) + { + assert(ti->vertexSet == eg.vertexSet); + // Check it's light facing + if (*lfi) + preCountIndexes += increment; + } + } + } + } + // End pre-count + + //Check if index buffer is to small + if (preCountIndexes > indexBuffer->getNumIndexes()) + { + LogManager::getSingleton().logMessage(LML_CRITICAL, + String("Warning: shadow index buffer size to small. Auto increasing buffer size to") + + StringConverter::toString(sizeof(unsigned short) * preCountIndexes)); + + SceneManager* pManager = Root::getSingleton()._getCurrentSceneManager(); + if (pManager) + { + pManager->setShadowIndexBufferSize(preCountIndexes); + } + + //Check that the index buffer size has actually increased + if (preCountIndexes > indexBuffer->getNumIndexes()) + { + //increasing index buffer size has failed + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Lock request out of bounds.", + "ShadowCaster::generateShadowVolume"); + } + } + else if(indexBufferUsedSize + preCountIndexes > indexBuffer->getNumIndexes()) + { + indexBufferUsedSize = 0; + } + + // Lock index buffer for writing, just enough length as we need + unsigned short* pIdx = static_cast( + indexBuffer->lock(sizeof(unsigned short) * indexBufferUsedSize, sizeof(unsigned short) * preCountIndexes, + indexBufferUsedSize == 0 ? HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NO_OVERWRITE)); + size_t numIndices = indexBufferUsedSize; + + // Iterate over the groups and form renderables for each based on their + // lightFacing + si = shadowRenderables.begin(); + egiend = edgeData->edgeGroups.end(); + for (egi = edgeData->edgeGroups.begin(); egi != egiend; ++egi, ++si) + { + const EdgeData::EdgeGroup& eg = *egi; + // Initialise the index start for this shadow renderable + IndexData* indexData = (*si)->getRenderOperationForUpdate()->indexData; + + if (indexData->indexBuffer != indexBuffer) + { + (*si)->rebindIndexBuffer(indexBuffer); + indexData = (*si)->getRenderOperationForUpdate()->indexData; + } + + indexData->indexStart = numIndices; + // original number of verts (without extruded copy) + size_t originalVertexCount = eg.vertexData->vertexCount; + bool firstDarkCapTri = true; + unsigned short darkCapStart = 0; + + EdgeData::EdgeList::const_iterator i, iend; + iend = eg.edges.end(); + for (i = eg.edges.begin(); i != iend; ++i) + { + const EdgeData::Edge& edge = *i; + + // Silhouette edge, when two tris has opposite light facing, or + // degenerate edge where only tri 1 is valid and the tri light facing + char lightFacing = edgeData->triangleLightFacings[edge.triIndex[0]]; + if ((edge.degenerate && lightFacing) || + (!edge.degenerate && (lightFacing != edgeData->triangleLightFacings[edge.triIndex[1]]))) + { + size_t v0 = edge.vertIndex[0]; + size_t v1 = edge.vertIndex[1]; + if (!lightFacing) + { + // Inverse edge indexes when t1 is light away + std::swap(v0, v1); + } + + /* Note edge(v0, v1) run anticlockwise along the edge from + the light facing tri so to point shadow volume tris outward, + light cap indexes have to be backwards + + We emit 2 tris if light is a point light, 1 if light + is directional, because directional lights cause all + points to converge to a single point at infinity. + + First side tri = near1, near0, far0 + Second tri = far0, far1, near1 + + 'far' indexes are 'near' index + originalVertexCount + because 'far' verts are in the second half of the + buffer + */ + assert(v1 < 65536 && v0 < 65536 && (v0 + originalVertexCount) < 65536 && + "Vertex count exceeds 16-bit index limit!"); + *pIdx++ = static_cast(v1); + *pIdx++ = static_cast(v0); + *pIdx++ = static_cast(v0 + originalVertexCount); + numIndices += 3; + + // Are we extruding to infinity? + if (!(lightType == Light::LT_DIRECTIONAL && + flags & SRF_EXTRUDE_TO_INFINITY)) + { + // additional tri to make quad + *pIdx++ = static_cast(v0 + originalVertexCount); + *pIdx++ = static_cast(v1 + originalVertexCount); + *pIdx++ = static_cast(v1); + numIndices += 3; + } + + if(useMcGuire) + { + // Do dark cap tri + // Use McGuire et al method, a triangle fan covering all silhouette + // edges and one point (taken from the initial tri) + if (flags & SRF_INCLUDE_DARK_CAP) + { + if (firstDarkCapTri) + { + darkCapStart = static_cast(v0 + originalVertexCount); + firstDarkCapTri = false; + } + else + { + *pIdx++ = darkCapStart; + *pIdx++ = static_cast(v1 + originalVertexCount); + *pIdx++ = static_cast(v0 + originalVertexCount); + numIndices += 3; + } + + } + } + } + + } + + if(!useMcGuire) + { + // Do dark cap + if (flags & SRF_INCLUDE_DARK_CAP) + { + // Iterate over the triangles which are using this vertex set + EdgeData::TriangleList::const_iterator ti, tiend; + EdgeData::TriangleLightFacingList::const_iterator lfi; + ti = edgeData->triangles.begin() + eg.triStart; + tiend = ti + eg.triCount; + lfi = edgeData->triangleLightFacings.begin() + eg.triStart; + for ( ; ti != tiend; ++ti, ++lfi) + { + const EdgeData::Triangle& t = *ti; + assert(t.vertexSet == eg.vertexSet); + // Check it's light facing + if (*lfi) + { + assert(t.vertIndex[0] < 65536 && t.vertIndex[1] < 65536 && + t.vertIndex[2] < 65536 && + "16-bit index limit exceeded!"); + *pIdx++ = static_cast(t.vertIndex[1] + originalVertexCount); + *pIdx++ = static_cast(t.vertIndex[0] + originalVertexCount); + *pIdx++ = static_cast(t.vertIndex[2] + originalVertexCount); + numIndices += 3; + } + } + + } + } + + // Do light cap + if (flags & SRF_INCLUDE_LIGHT_CAP) + { + // separate light cap? + if ((*si)->isLightCapSeparate()) + { + // update index count for this shadow renderable + indexData->indexCount = numIndices - indexData->indexStart; + + // get light cap index data for update + indexData = (*si)->getLightCapRenderable()->getRenderOperationForUpdate()->indexData; + // start indexes after the current total + indexData->indexStart = numIndices; + } + + // Iterate over the triangles which are using this vertex set + EdgeData::TriangleList::const_iterator ti, tiend; + EdgeData::TriangleLightFacingList::const_iterator lfi; + ti = edgeData->triangles.begin() + eg.triStart; + tiend = ti + eg.triCount; + lfi = edgeData->triangleLightFacings.begin() + eg.triStart; + for ( ; ti != tiend; ++ti, ++lfi) + { + const EdgeData::Triangle& t = *ti; + assert(t.vertexSet == eg.vertexSet); + // Check it's light facing + if (*lfi) + { + assert(t.vertIndex[0] < 65536 && t.vertIndex[1] < 65536 && + t.vertIndex[2] < 65536 && + "16-bit index limit exceeded!"); + *pIdx++ = static_cast(t.vertIndex[0]); + *pIdx++ = static_cast(t.vertIndex[1]); + *pIdx++ = static_cast(t.vertIndex[2]); + numIndices += 3; + } + } + + } + + // update index count for current index data (either this shadow renderable or its light cap) + indexData->indexCount = numIndices - indexData->indexStart; + + } + + // Unlock index buffer + indexBuffer->unlock(); + + // In debug mode, check we didn't overrun the index buffer + assert(numIndices == indexBufferUsedSize + preCountIndexes); + assert(numIndices <= indexBuffer->getNumIndexes() && + "Index buffer overrun while generating shadow volume!! " + "You must increase the size of the shadow index buffer."); + + indexBufferUsedSize = numIndices; + } + // ------------------------------------------------------------------------ + void ShadowCaster::extrudeVertices( + const HardwareVertexBufferSharedPtr& vertexBuffer, + size_t originalVertexCount, const Vector4& light, Real extrudeDist) + { + assert (vertexBuffer->getVertexSize() == sizeof(float) * 3 + && "Position buffer should contain only positions!"); + + // Extrude the first area of the buffer into the second area + // Lock the entire buffer for writing, even though we'll only be + // updating the latter because you can't have 2 locks on the same + // buffer + float* pSrc = static_cast( + vertexBuffer->lock(HardwareBuffer::HBL_NORMAL)); + + // TODO: We should add extra (ununsed) vertices ensure source and + // destination buffer have same alignment for slight performance gain. + float* pDest = pSrc + originalVertexCount * 3; + + OptimisedUtil::getImplementation()->extrudeVertices( + light, extrudeDist, + pSrc, pDest, originalVertexCount); + + vertexBuffer->unlock(); + + } + // ------------------------------------------------------------------------ + void ShadowCaster::extrudeBounds(AxisAlignedBox& box, const Vector4& light, Real extrudeDist) const + { + Vector3 extrusionDir; + + if (light.w == 0) + { + // Parallel projection guarantees min/max relationship remains the same + extrusionDir.x = -light.x; + extrusionDir.y = -light.y; + extrusionDir.z = -light.z; + extrusionDir.normalise(); + extrusionDir *= extrudeDist; + box.setExtents(box.getMinimum() + extrusionDir, + box.getMaximum() + extrusionDir); + } + else + { + Vector3 oldMin, oldMax, currentCorner; + // Getting the original values + oldMin = box.getMinimum(); + oldMax = box.getMaximum(); + // Starting the box again with a null content + box.setNull(); + + // merging all the extruded corners + + // 0 : min min min + currentCorner = oldMin; + extrusionDir.x = currentCorner.x - light.x; + extrusionDir.y = currentCorner.y - light.y; + extrusionDir.z = currentCorner.z - light.z; + box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); + + // 6 : min min max + // only z has changed + currentCorner.z = oldMax.z; + extrusionDir.z = currentCorner.z - light.z; + box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); + + // 5 : min max max + currentCorner.y = oldMax.y; + extrusionDir.y = currentCorner.y - light.y; + box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); + + // 1 : min max min + currentCorner.z = oldMin.z; + extrusionDir.z = currentCorner.z - light.z; + box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); + + // 2 : max max min + currentCorner.x = oldMax.x; + extrusionDir.x = currentCorner.x - light.x; + box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); + + // 4 : max max max + currentCorner.z = oldMax.z; + extrusionDir.z = currentCorner.z - light.z; + box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); + + // 7 : max min max + currentCorner.y = oldMin.y; + extrusionDir.y = currentCorner.y - light.y; + box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); + + // 3 : max min min + currentCorner.z = oldMin.z; + extrusionDir.z = currentCorner.z - light.z; + box.merge(currentCorner + extrudeDist * extrusionDir.normalisedCopy()); + + } + + } + // ------------------------------------------------------------------------ + Real ShadowCaster::getExtrusionDistance(const Vector3& objectPos, const Light* light) const + { + Vector3 diff = objectPos - light->getDerivedPosition(); + return light->getAttenuationRange() - diff.length(); + } } diff --git a/OgreMain/src/OgreShadowTextureManager.cpp b/OgreMain/src/OgreShadowTextureManager.cpp index 2776035f987..ecaf62d5991 100644 --- a/OgreMain/src/OgreShadowTextureManager.cpp +++ b/OgreMain/src/OgreShadowTextureManager.cpp @@ -35,174 +35,174 @@ Torus Knot Software Ltd. namespace Ogre { - //----------------------------------------------------------------------- - bool operator== ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ) - { - if ( lhs.width != rhs.width || - lhs.height != rhs.height || - lhs.format != rhs.format ) - { - return false; - } - - return true; - } - //----------------------------------------------------------------------- - bool operator!= ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ) - { - return !( lhs == rhs ); - } - //----------------------------------------------------------------------- - template<> ShadowTextureManager* Singleton::msSingleton = 0; - ShadowTextureManager* ShadowTextureManager::getSingletonPtr(void) - { - return msSingleton; - } - ShadowTextureManager& ShadowTextureManager::getSingleton(void) - { - assert( msSingleton ); return ( *msSingleton ); - } - //--------------------------------------------------------------------- - ShadowTextureManager::ShadowTextureManager() - : mCount(0) - { - - } - //--------------------------------------------------------------------- - ShadowTextureManager::~ShadowTextureManager() - { - clear(); - } - //--------------------------------------------------------------------- - void ShadowTextureManager::getShadowTextures(const ShadowTextureConfigList& configList, - ShadowTextureList& listToPopulate) - { - listToPopulate.clear(); - - set::type usedTextures; - - for (ShadowTextureConfigList::const_iterator c = configList.begin(); c != configList.end(); ++c) - { - const ShadowTextureConfig& config = *c; - bool found = false; - for (ShadowTextureList::iterator t = mTextureList.begin(); t != mTextureList.end(); ++t) - { - const TexturePtr& tex = *t; - // Skip if already used this one - if (usedTextures.find(tex.getPointer()) != usedTextures.end()) - continue; - - if (config.width == tex->getWidth() && config.height == tex->getHeight() - && config.format == tex->getFormat() && config.fsaa == tex->getFSAA()) - { - // Ok, a match - listToPopulate.push_back(tex); - usedTextures.insert(tex.getPointer()); - found = true; - break; - } - } - if (!found) - { - // Create a new texture - static const String baseName = "Ogre/ShadowTexture"; - String targName = baseName + StringConverter::toString(mCount++); - TexturePtr shadowTex = TextureManager::getSingleton().createManual( - targName, - ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - TEX_TYPE_2D, config.width, config.height, 0, config.format, - TU_RENDERTARGET, NULL, false, config.fsaa); - // Ensure texture loaded - shadowTex->load(); - listToPopulate.push_back(shadowTex); - usedTextures.insert(shadowTex.getPointer()); - mTextureList.push_back(shadowTex); - } - } - - } - //--------------------------------------------------------------------- - TexturePtr ShadowTextureManager::getNullShadowTexture(PixelFormat format) - { - for (ShadowTextureList::iterator t = mNullTextureList.begin(); t != mNullTextureList.end(); ++t) - { - const TexturePtr& tex = *t; - - if (format == tex->getFormat()) - { - // Ok, a match - return tex; - } - } - - // not found, create a new one - // A 1x1 texture of the correct format, not a render target - static const String baseName = "Ogre/ShadowTextureNull"; - String targName = baseName + StringConverter::toString(mCount++); - TexturePtr shadowTex = TextureManager::getSingleton().createManual( - targName, - ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - TEX_TYPE_2D, 1, 1, 0, format, TU_STATIC_WRITE_ONLY); - mNullTextureList.push_back(shadowTex); - - // lock & populate the texture based on format - shadowTex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD); - const PixelBox& box = shadowTex->getBuffer()->getCurrentLock(); - - // set high-values across all bytes of the format - PixelUtil::packColour( 1.0f, 1.0f, 1.0f, 1.0f, format, box.data ); - - shadowTex->getBuffer()->unlock(); - - return shadowTex; - - } - //--------------------------------------------------------------------- - void ShadowTextureManager::clearUnused() - { - for (ShadowTextureList::iterator i = mTextureList.begin(); i != mTextureList.end(); ) - { - // Unreferenced if only this reference and the resource system - // Any cached shadow textures should be re-bound each frame dropping - // any old references - if ((*i).useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) - { - TextureManager::getSingleton().remove((*i)->getHandle()); - i = mTextureList.erase(i); - } - else - { - ++i; - } - } - for (ShadowTextureList::iterator i = mNullTextureList.begin(); i != mNullTextureList.end(); ) - { - // Unreferenced if only this reference and the resource system - // Any cached shadow textures should be re-bound each frame dropping - // any old references - if ((*i).useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) - { - TextureManager::getSingleton().remove((*i)->getHandle()); - i = mNullTextureList.erase(i); - } - else - { - ++i; - } - } - - } - //--------------------------------------------------------------------- - void ShadowTextureManager::clear() - { - for (ShadowTextureList::iterator i = mTextureList.begin(); i != mTextureList.end(); ++i) - { - TextureManager::getSingleton().remove((*i)->getHandle()); - } - mTextureList.clear(); - - } - //--------------------------------------------------------------------- + //----------------------------------------------------------------------- + bool operator== ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ) + { + if ( lhs.width != rhs.width || + lhs.height != rhs.height || + lhs.format != rhs.format ) + { + return false; + } + + return true; + } + //----------------------------------------------------------------------- + bool operator!= ( const ShadowTextureConfig& lhs, const ShadowTextureConfig& rhs ) + { + return !( lhs == rhs ); + } + //----------------------------------------------------------------------- + template<> ShadowTextureManager* Singleton::msSingleton = 0; + ShadowTextureManager* ShadowTextureManager::getSingletonPtr(void) + { + return msSingleton; + } + ShadowTextureManager& ShadowTextureManager::getSingleton(void) + { + assert( msSingleton ); return ( *msSingleton ); + } + //--------------------------------------------------------------------- + ShadowTextureManager::ShadowTextureManager() + : mCount(0) + { + + } + //--------------------------------------------------------------------- + ShadowTextureManager::~ShadowTextureManager() + { + clear(); + } + //--------------------------------------------------------------------- + void ShadowTextureManager::getShadowTextures(const ShadowTextureConfigList& configList, + ShadowTextureList& listToPopulate) + { + listToPopulate.clear(); + + set::type usedTextures; + + for (ShadowTextureConfigList::const_iterator c = configList.begin(); c != configList.end(); ++c) + { + const ShadowTextureConfig& config = *c; + bool found = false; + for (ShadowTextureList::iterator t = mTextureList.begin(); t != mTextureList.end(); ++t) + { + const TexturePtr& tex = *t; + // Skip if already used this one + if (usedTextures.find(tex.getPointer()) != usedTextures.end()) + continue; + + if (config.width == tex->getWidth() && config.height == tex->getHeight() + && config.format == tex->getFormat() && config.fsaa == tex->getFSAA()) + { + // Ok, a match + listToPopulate.push_back(tex); + usedTextures.insert(tex.getPointer()); + found = true; + break; + } + } + if (!found) + { + // Create a new texture + static const String baseName = "Ogre/ShadowTexture"; + String targName = baseName + StringConverter::toString(mCount++); + TexturePtr shadowTex = TextureManager::getSingleton().createManual( + targName, + ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, + TEX_TYPE_2D, config.width, config.height, 0, config.format, + TU_RENDERTARGET, NULL, false, config.fsaa); + // Ensure texture loaded + shadowTex->load(); + listToPopulate.push_back(shadowTex); + usedTextures.insert(shadowTex.getPointer()); + mTextureList.push_back(shadowTex); + } + } + + } + //--------------------------------------------------------------------- + TexturePtr ShadowTextureManager::getNullShadowTexture(PixelFormat format) + { + for (ShadowTextureList::iterator t = mNullTextureList.begin(); t != mNullTextureList.end(); ++t) + { + const TexturePtr& tex = *t; + + if (format == tex->getFormat()) + { + // Ok, a match + return tex; + } + } + + // not found, create a new one + // A 1x1 texture of the correct format, not a render target + static const String baseName = "Ogre/ShadowTextureNull"; + String targName = baseName + StringConverter::toString(mCount++); + TexturePtr shadowTex = TextureManager::getSingleton().createManual( + targName, + ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, + TEX_TYPE_2D, 1, 1, 0, format, TU_STATIC_WRITE_ONLY); + mNullTextureList.push_back(shadowTex); + + // lock & populate the texture based on format + shadowTex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD); + const PixelBox& box = shadowTex->getBuffer()->getCurrentLock(); + + // set high-values across all bytes of the format + PixelUtil::packColour( 1.0f, 1.0f, 1.0f, 1.0f, format, box.data ); + + shadowTex->getBuffer()->unlock(); + + return shadowTex; + + } + //--------------------------------------------------------------------- + void ShadowTextureManager::clearUnused() + { + for (ShadowTextureList::iterator i = mTextureList.begin(); i != mTextureList.end(); ) + { + // Unreferenced if only this reference and the resource system + // Any cached shadow textures should be re-bound each frame dropping + // any old references + if ((*i).useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) + { + TextureManager::getSingleton().remove((*i)->getHandle()); + i = mTextureList.erase(i); + } + else + { + ++i; + } + } + for (ShadowTextureList::iterator i = mNullTextureList.begin(); i != mNullTextureList.end(); ) + { + // Unreferenced if only this reference and the resource system + // Any cached shadow textures should be re-bound each frame dropping + // any old references + if ((*i).useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) + { + TextureManager::getSingleton().remove((*i)->getHandle()); + i = mNullTextureList.erase(i); + } + else + { + ++i; + } + } + + } + //--------------------------------------------------------------------- + void ShadowTextureManager::clear() + { + for (ShadowTextureList::iterator i = mTextureList.begin(); i != mTextureList.end(); ++i) + { + TextureManager::getSingleton().remove((*i)->getHandle()); + } + mTextureList.clear(); + + } + //--------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreShadowVolumeExtrudeProgram.cpp b/OgreMain/src/OgreShadowVolumeExtrudeProgram.cpp index a958f024e9f..3e29496484d 100644 --- a/OgreMain/src/OgreShadowVolumeExtrudeProgram.cpp +++ b/OgreMain/src/OgreShadowVolumeExtrudeProgram.cpp @@ -66,29 +66,29 @@ namespace Ogre { "dp4 oPos.z, c2, r0\n" "dp4 oPos.w, c3, r0\n"; - String ShadowVolumeExtrudeProgram::mPointVs_4_0 = - "// Point light shadow volume extrude\n" - "struct VS_OUTPUT\n" - "{\n" - "\tfloat4 Pos : SV_POSITION;\n" - "};\n" - "VS_OUTPUT vs_main (\n" - " float4 position : POSITION,\n" - " float wcoord : TEXCOORD0,\n" - " uniform float4x4 worldviewproj_matrix,\n" - " uniform float4 light_position_object_space // homogeneous, object space\n" - " )\n" - "{\n" - " // extrusion in object space\n" - " // vertex unmodified if w==1, extruded if w==0\n" - " float4 newpos = \n" - " (wcoord.xxxx * light_position_object_space) + \n" - " float4(position.xyz - light_position_object_space.xyz, 0);\n" - "\n" - " VS_OUTPUT output = (VS_OUTPUT)0;\n" - " output.Pos = mul(worldviewproj_matrix, newpos);\n" - " return output;\n" - "}\n"; + String ShadowVolumeExtrudeProgram::mPointVs_4_0 = + "// Point light shadow volume extrude\n" + "struct VS_OUTPUT\n" + "{\n" + "\tfloat4 Pos : SV_POSITION;\n" + "};\n" + "VS_OUTPUT vs_main (\n" + " float4 position : POSITION,\n" + " float wcoord : TEXCOORD0,\n" + " uniform float4x4 worldviewproj_matrix,\n" + " uniform float4 light_position_object_space // homogeneous, object space\n" + " )\n" + "{\n" + " // extrusion in object space\n" + " // vertex unmodified if w==1, extruded if w==0\n" + " float4 newpos = \n" + " (wcoord.xxxx * light_position_object_space) + \n" + " float4(position.xyz - light_position_object_space.xyz, 0);\n" + "\n" + " VS_OUTPUT output = (VS_OUTPUT)0;\n" + " output.Pos = mul(worldviewproj_matrix, newpos);\n" + " return output;\n" + "}\n"; String ShadowVolumeExtrudeProgram::mPointVs_glsl = "#version 150\n" @@ -114,21 +114,21 @@ namespace Ogre { "precision highp int;\n" "precision lowp sampler2D;\n" "precision lowp samplerCube;\n\n" - "// Point light shadow volume extrude\n" + "// Point light shadow volume extrude\n" "attribute vec4 uv0;\n" "attribute vec4 position;\n\n" "uniform mat4 worldviewproj_matrix;\n" "uniform vec4 light_position_object_space; // homogenous, object space\n\n" - "void main()\n" - "{\n" - " // Extrusion in object space\n" - " // Vertex unmodified if w==1, extruded if w==0\n" - " vec4 newpos = \n" - " (uv0.xxxx * light_position_object_space) + \n" - " vec4(position.xyz - light_position_object_space.xyz, 0.0);\n" - "\n" - " gl_Position = worldviewproj_matrix * newpos;\n" - "}\n"; + "void main()\n" + "{\n" + " // Extrusion in object space\n" + " // Vertex unmodified if w==1, extruded if w==0\n" + " vec4 newpos = \n" + " (uv0.xxxx * light_position_object_space) + \n" + " vec4(position.xyz - light_position_object_space.xyz, 0.0);\n" + "\n" + " gl_Position = worldviewproj_matrix * newpos;\n" + "}\n"; String ShadowVolumeExtrudeProgram::mDirArbvp1 = "!!ARBvp1.0\n" @@ -156,29 +156,29 @@ namespace Ogre { "dp4 oPos.z, c2, r0\n" "dp4 oPos.w, c3, r0\n"; - String ShadowVolumeExtrudeProgram::mDirVs_4_0 = - "// Directional light extrude\n" - "struct VS_OUTPUT\n" - "{\n" - "\tfloat4 Pos : SV_POSITION;\n" - "};\n" - "VS_OUTPUT vs_main (\n" - " float4 position : POSITION,\n" - " float wcoord : TEXCOORD0,\n" - "\n" - " uniform float4x4 worldviewproj_matrix,\n" - " uniform float4 light_position_object_space // homogenous, object space\n" - " )\n" - "{\n" - " // extrusion in object space\n" - " // vertex unmodified if w==1, extruded if w==0\n" - " float4 newpos = \n" - " (wcoord.xxxx * (position + light_position_object_space)) - light_position_object_space;\n" - "\n" - " VS_OUTPUT output = (VS_OUTPUT)0;\n" - " output.Pos = mul(worldviewproj_matrix, newpos);\n" - " return output;\n" - "}\n"; + String ShadowVolumeExtrudeProgram::mDirVs_4_0 = + "// Directional light extrude\n" + "struct VS_OUTPUT\n" + "{\n" + "\tfloat4 Pos : SV_POSITION;\n" + "};\n" + "VS_OUTPUT vs_main (\n" + " float4 position : POSITION,\n" + " float wcoord : TEXCOORD0,\n" + "\n" + " uniform float4x4 worldviewproj_matrix,\n" + " uniform float4 light_position_object_space // homogenous, object space\n" + " )\n" + "{\n" + " // extrusion in object space\n" + " // vertex unmodified if w==1, extruded if w==0\n" + " float4 newpos = \n" + " (wcoord.xxxx * (position + light_position_object_space)) - light_position_object_space;\n" + "\n" + " VS_OUTPUT output = (VS_OUTPUT)0;\n" + " output.Pos = mul(worldviewproj_matrix, newpos);\n" + " return output;\n" + "}\n"; String ShadowVolumeExtrudeProgram::mDirVs_glsl = "#version 150\n" @@ -203,20 +203,20 @@ namespace Ogre { "precision highp int;\n" "precision lowp sampler2D;\n" "precision lowp samplerCube;\n\n" - "// Directional light extrude\n" + "// Directional light extrude\n" "attribute vec4 uv0;\n" "attribute vec4 position;\n\n" "uniform mat4 worldviewproj_matrix;\n" "uniform vec4 light_position_object_space; // homogenous, object space\n\n" "void main()\n" - "{\n" - " // Extrusion in object space\n" - " // Vertex unmodified if w==1, extruded if w==0\n" - " vec4 newpos = \n" - " (uv0.xxxx * (position + light_position_object_space)) - light_position_object_space;\n" - "\n" - " gl_Position = worldviewproj_matrix * newpos;\n" - "}\n"; + "{\n" + " // Extrusion in object space\n" + " // Vertex unmodified if w==1, extruded if w==0\n" + " vec4 newpos = \n" + " (uv0.xxxx * (position + light_position_object_space)) - light_position_object_space;\n" + "\n" + " gl_Position = worldviewproj_matrix * newpos;\n" + "}\n"; String ShadowVolumeExtrudeProgram::mPointArbvp1Debug = @@ -253,9 +253,9 @@ namespace Ogre { "dp4 oPos.w, c3, r0\n" "mov oD0, c6.x\n"; - String ShadowVolumeExtrudeProgram::mPointVs_4_0Debug = mPointVs_4_0; - String ShadowVolumeExtrudeProgram::mPointVs_glslDebug = mPointVs_glsl; - String ShadowVolumeExtrudeProgram::mPointVs_glslesDebug = mPointVs_glsles; + String ShadowVolumeExtrudeProgram::mPointVs_4_0Debug = mPointVs_4_0; + String ShadowVolumeExtrudeProgram::mPointVs_glslDebug = mPointVs_glsl; + String ShadowVolumeExtrudeProgram::mPointVs_glslesDebug = mPointVs_glsles; String ShadowVolumeExtrudeProgram::mDirArbvp1Debug = "!!ARBvp1.0\n" @@ -287,9 +287,9 @@ namespace Ogre { "dp4 oPos.w, c3, r0\n" "mov oD0, c5.x\n"; - String ShadowVolumeExtrudeProgram::mDirVs_4_0Debug = mDirVs_4_0; - String ShadowVolumeExtrudeProgram::mDirVs_glslDebug = mDirVs_glsl; - String ShadowVolumeExtrudeProgram::mDirVs_glslesDebug = mDirVs_glsles; + String ShadowVolumeExtrudeProgram::mDirVs_4_0Debug = mDirVs_4_0; + String ShadowVolumeExtrudeProgram::mDirVs_glslDebug = mDirVs_glsl; + String ShadowVolumeExtrudeProgram::mDirVs_glslesDebug = mDirVs_glsles; // c4 is the light position/direction in these @@ -334,35 +334,35 @@ namespace Ogre { "dp4 oPos.z, c2, r0\n" "dp4 oPos.w, c3, r0\n"; - String ShadowVolumeExtrudeProgram::mPointVs_4_0Finite = - "// Point light shadow volume extrude - FINITE\n" - "struct VS_OUTPUT\n" - "{\n" - "\tfloat4 Pos : SV_POSITION;\n" - "};\n" - "VS_OUTPUT vs_main (\n" - " float4 position : POSITION,\n" - " float wcoord : TEXCOORD0,\n" - "\n" - " uniform float4x4 worldviewproj_matrix,\n" - " uniform float4 light_position_object_space, // homogeneous, object space\n" - " uniform float shadow_extrusion_distance // how far to extrude\n" - " )\n" - "{\n" - " // extrusion in object space\n" - " // vertex unmodified if w==1, extruded if w==0\n" - " float3 extrusionDir = position.xyz - light_position_object_space.xyz;\n" - " extrusionDir = normalize(extrusionDir);\n" - " \n" - " float4 newpos = float4(position.xyz + \n" - " ((1 - wcoord.x) * shadow_extrusion_distance * extrusionDir), 1);\n" - "\n" - " VS_OUTPUT output = (VS_OUTPUT)0;\n" - " output.Pos = mul(worldviewproj_matrix, newpos);\n" - " return output;\n" + String ShadowVolumeExtrudeProgram::mPointVs_4_0Finite = + "// Point light shadow volume extrude - FINITE\n" + "struct VS_OUTPUT\n" + "{\n" + "\tfloat4 Pos : SV_POSITION;\n" + "};\n" + "VS_OUTPUT vs_main (\n" + " float4 position : POSITION,\n" + " float wcoord : TEXCOORD0,\n" + "\n" + " uniform float4x4 worldviewproj_matrix,\n" + " uniform float4 light_position_object_space, // homogeneous, object space\n" + " uniform float shadow_extrusion_distance // how far to extrude\n" + " )\n" + "{\n" + " // extrusion in object space\n" + " // vertex unmodified if w==1, extruded if w==0\n" + " float3 extrusionDir = position.xyz - light_position_object_space.xyz;\n" + " extrusionDir = normalize(extrusionDir);\n" + " \n" + " float4 newpos = float4(position.xyz + \n" + " ((1 - wcoord.x) * shadow_extrusion_distance * extrusionDir), 1);\n" + "\n" + " VS_OUTPUT output = (VS_OUTPUT)0;\n" + " output.Pos = mul(worldviewproj_matrix, newpos);\n" + " return output;\n" - "\n" - "}\n"; + "\n" + "}\n"; String ShadowVolumeExtrudeProgram::mPointVs_glslFinite = "#version 150\n" @@ -376,9 +376,9 @@ namespace Ogre { "{\n" " // Extrusion in object space\n" " // Vertex unmodified if w==1, extruded if w==0\n" - " vec3 extrusionDir = vertex.xyz - light_position_object_space.xyz;\n" - " extrusionDir = normalize(extrusionDir);\n" - " \n" + " vec3 extrusionDir = vertex.xyz - light_position_object_space.xyz;\n" + " extrusionDir = normalize(extrusionDir);\n" + " \n" " vec4 newpos = vec4(vertex.xyz + \n" " ((1.0 - uv0.x) * shadow_extrusion_distance * extrusionDir), 1.0);\n" "\n" @@ -391,24 +391,24 @@ namespace Ogre { "precision highp int;\n" "precision lowp sampler2D;\n" "precision lowp samplerCube;\n\n" - "// Point light shadow volume extrude - FINITE\n" + "// Point light shadow volume extrude - FINITE\n" "attribute vec4 uv0;\n" "attribute vec4 position;\n\n" "uniform mat4 worldviewproj_matrix;\n" "uniform vec4 light_position_object_space; // homogenous, object space\n" - "uniform float shadow_extrusion_distance; // how far to extrude\n\n" + "uniform float shadow_extrusion_distance; // how far to extrude\n\n" "void main()\n" - "{\n" - " // Extrusion in object space\n" - " // Vertex unmodified if w==1, extruded if w==0\n" - " vec3 extrusionDir = position.xyz - light_position_object_space.xyz;\n" - " extrusionDir = normalize(extrusionDir);\n" - " \n" - " vec4 newpos = vec4(position.xyz + \n" - " ((1.0 - uv0.x) * shadow_extrusion_distance * extrusionDir), 1.0);\n" - "\n" - " gl_Position = worldviewproj_matrix * newpos;\n" - "}\n"; + "{\n" + " // Extrusion in object space\n" + " // Vertex unmodified if w==1, extruded if w==0\n" + " vec3 extrusionDir = position.xyz - light_position_object_space.xyz;\n" + " extrusionDir = normalize(extrusionDir);\n" + " \n" + " vec4 newpos = vec4(position.xyz + \n" + " ((1.0 - uv0.x) * shadow_extrusion_distance * extrusionDir), 1.0);\n" + "\n" + " gl_Position = worldviewproj_matrix * newpos;\n" + "}\n"; String ShadowVolumeExtrudeProgram::mDirArbvp1Finite = "!!ARBvp1.0\n" @@ -442,32 +442,32 @@ namespace Ogre { "dp4 oPos.z, c2, r0\n" "dp4 oPos.w, c3, r0\n"; - String ShadowVolumeExtrudeProgram::mDirVs_4_0Finite = - "// Directional light extrude - FINITE\n" - "struct VS_OUTPUT\n" - "{\n" - "\tfloat4 Pos : SV_POSITION;\n" - "};\n" - "VS_OUTPUT vs_main (\n" - " float4 position : POSITION,\n" - " float wcoord : TEXCOORD0,\n" - "\n" - " uniform float4x4 worldviewproj_matrix,\n" - " uniform float4 light_position_object_space, // homogeneous, object space\n" - " uniform float shadow_extrusion_distance // how far to extrude\n" - " )\n" - "{\n" - " // extrusion in object space\n" - " // vertex unmodified if w==1, extruded if w==0\n" - " // -ve light_position_object_space is direction\n" - " float4 newpos = float4(position.xyz - \n" - " (wcoord.x * shadow_extrusion_distance * light_position_object_space.xyz), 1);\n" - "\n" - " VS_OUTPUT output = (VS_OUTPUT)0;\n" - " output.Pos = mul(worldviewproj_matrix, newpos);\n" - " return output;\n" - "\n" - "}\n"; + String ShadowVolumeExtrudeProgram::mDirVs_4_0Finite = + "// Directional light extrude - FINITE\n" + "struct VS_OUTPUT\n" + "{\n" + "\tfloat4 Pos : SV_POSITION;\n" + "};\n" + "VS_OUTPUT vs_main (\n" + " float4 position : POSITION,\n" + " float wcoord : TEXCOORD0,\n" + "\n" + " uniform float4x4 worldviewproj_matrix,\n" + " uniform float4 light_position_object_space, // homogeneous, object space\n" + " uniform float shadow_extrusion_distance // how far to extrude\n" + " )\n" + "{\n" + " // extrusion in object space\n" + " // vertex unmodified if w==1, extruded if w==0\n" + " // -ve light_position_object_space is direction\n" + " float4 newpos = float4(position.xyz - \n" + " (wcoord.x * shadow_extrusion_distance * light_position_object_space.xyz), 1);\n" + "\n" + " VS_OUTPUT output = (VS_OUTPUT)0;\n" + " output.Pos = mul(worldviewproj_matrix, newpos);\n" + " return output;\n" + "\n" + "}\n"; String ShadowVolumeExtrudeProgram::mDirVs_glslFinite = "#version 150\n" @@ -481,7 +481,7 @@ namespace Ogre { "{\n" " // Extrusion in object space\n" " // Vertex unmodified if w==1, extruded if w==0\n" - " // -ve light_position_object_space is direction\n" + " // -ve light_position_object_space is direction\n" " vec4 newpos = vec4(vertex.xyz - \n" " (uv0.x * shadow_extrusion_distance * light_position_object_space.xyz), 1.0);\n" "\n" @@ -489,13 +489,13 @@ namespace Ogre { "\n" "}\n"; - String ShadowVolumeExtrudeProgram::mDirVs_glslesFinite = + String ShadowVolumeExtrudeProgram::mDirVs_glslesFinite = "#version 100\n" "precision highp float;\n" "precision highp int;\n" "precision lowp sampler2D;\n" "precision lowp samplerCube;\n\n" - "// Directional light extrude - FINITE\n" + "// Directional light extrude - FINITE\n" "attribute vec4 uv0;\n" "attribute vec4 position;\n\n" "uniform mat4 worldviewproj_matrix;\n" @@ -503,15 +503,15 @@ namespace Ogre { "uniform float shadow_extrusion_distance; // how far to extrude\n\n" "void main()\n" "{\n" - " // Extrusion in object space\n" - " // Vertex unmodified if w==1, extruded if w==0\n" - " // -ve light_position_object_space is direction\n" - " vec4 newpos = vec4(position.xyz - \n" - " (uv0.x * shadow_extrusion_distance * light_position_object_space.xyz), 1.0);\n" - "\n" - " gl_Position = worldviewproj_matrix * newpos;\n" - "\n" - "}\n"; + " // Extrusion in object space\n" + " // Vertex unmodified if w==1, extruded if w==0\n" + " // -ve light_position_object_space is direction\n" + " vec4 newpos = vec4(position.xyz - \n" + " (uv0.x * shadow_extrusion_distance * light_position_object_space.xyz), 1.0);\n" + "\n" + " gl_Position = worldviewproj_matrix * newpos;\n" + "\n" + "}\n"; String ShadowVolumeExtrudeProgram::mPointArbvp1FiniteDebug = "!!ARBvp1.0\n" @@ -536,7 +536,7 @@ namespace Ogre { "DPH result.position.w, R0.xyzz, c0[3];\n" "END\n"; - String ShadowVolumeExtrudeProgram::mPointVs_1_1FiniteDebug = + String ShadowVolumeExtrudeProgram::mPointVs_1_1FiniteDebug = "vs_1_1\n" "def c6, 1, 0, 0, 0\n" "dcl_texcoord0 v7\n" @@ -555,9 +555,9 @@ namespace Ogre { "dp4 oPos.z, c2, r0\n" "dp4 oPos.w, c3, r0\n"; - String ShadowVolumeExtrudeProgram::mPointVs_4_0FiniteDebug = mPointVs_4_0Finite; - String ShadowVolumeExtrudeProgram::mPointVs_glslFiniteDebug = mPointVs_glslFinite; - String ShadowVolumeExtrudeProgram::mPointVs_glslesFiniteDebug = mPointVs_glslesFinite; + String ShadowVolumeExtrudeProgram::mPointVs_4_0FiniteDebug = mPointVs_4_0Finite; + String ShadowVolumeExtrudeProgram::mPointVs_glslFiniteDebug = mPointVs_glslFinite; + String ShadowVolumeExtrudeProgram::mPointVs_glslesFiniteDebug = mPointVs_glslesFinite; String ShadowVolumeExtrudeProgram::mDirArbvp1FiniteDebug = "!!ARBvp1.0\n" @@ -594,21 +594,21 @@ namespace Ogre { "dp4 oPos.w, c3, r0\n"; - String ShadowVolumeExtrudeProgram::mDirVs_4_0FiniteDebug = mDirVs_4_0Finite; - String ShadowVolumeExtrudeProgram::mDirVs_glslFiniteDebug = mDirVs_glslFinite; - String ShadowVolumeExtrudeProgram::mDirVs_glslesFiniteDebug = mDirVs_glslesFinite; + String ShadowVolumeExtrudeProgram::mDirVs_4_0FiniteDebug = mDirVs_4_0Finite; + String ShadowVolumeExtrudeProgram::mDirVs_glslFiniteDebug = mDirVs_glslFinite; + String ShadowVolumeExtrudeProgram::mDirVs_glslesFiniteDebug = mDirVs_glslesFinite; - String ShadowVolumeExtrudeProgram::mGeneralFs_4_0 = - "struct VS_OUTPUT\n" - "{\n" - "\tfloat4 Pos : SV_POSITION;\n" - "};\n" - "float4 fs_main (VS_OUTPUT input): SV_Target\n" - "{\n" - " float4 finalColor = float4(1,1,1,1);\n" - " return finalColor;\n" - "}\n"; + String ShadowVolumeExtrudeProgram::mGeneralFs_4_0 = + "struct VS_OUTPUT\n" + "{\n" + "\tfloat4 Pos : SV_POSITION;\n" + "};\n" + "float4 fs_main (VS_OUTPUT input): SV_Target\n" + "{\n" + " float4 finalColor = float4(1,1,1,1);\n" + " return finalColor;\n" + "}\n"; String ShadowVolumeExtrudeProgram::mGeneralFs_glsl = "#version 150\n" @@ -624,10 +624,10 @@ namespace Ogre { "precision highp int;\n" "precision lowp sampler2D;\n" "precision lowp samplerCube;\n\n" - "void main()\n" - "{\n" - " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" - "}\n"; + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" + "}\n"; const String ShadowVolumeExtrudeProgram::programNames[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = { @@ -641,164 +641,164 @@ namespace Ogre { "Ogre/ShadowExtrudeDirLightFiniteDebug" }; - String ShadowVolumeExtrudeProgram::frgProgramName = ""; + String ShadowVolumeExtrudeProgram::frgProgramName = ""; - bool ShadowVolumeExtrudeProgram::mInitialised = false; + bool ShadowVolumeExtrudeProgram::mInitialised = false; //--------------------------------------------------------------------- //--------------------------------------------------------------------- void ShadowVolumeExtrudeProgram::initialise(void) { - if (!mInitialised) - { - String syntax; - bool vertexProgramFinite[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = - { - false, false, false, false, - true, true, true, true - }; - bool vertexProgramDebug[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = - { - false, true, false, true, - false, true, false, true - }; - Light::LightTypes vertexProgramLightTypes[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = - { - Light::LT_POINT, Light::LT_POINT, - Light::LT_DIRECTIONAL, Light::LT_DIRECTIONAL, - Light::LT_POINT, Light::LT_POINT, - Light::LT_DIRECTIONAL, Light::LT_DIRECTIONAL - }; + if (!mInitialised) + { + String syntax; + bool vertexProgramFinite[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = + { + false, false, false, false, + true, true, true, true + }; + bool vertexProgramDebug[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = + { + false, true, false, true, + false, true, false, true + }; + Light::LightTypes vertexProgramLightTypes[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = + { + Light::LT_POINT, Light::LT_POINT, + Light::LT_DIRECTIONAL, Light::LT_DIRECTIONAL, + Light::LT_POINT, Light::LT_POINT, + Light::LT_DIRECTIONAL, Light::LT_DIRECTIONAL + }; - // load hardware extrusion programs for point & dir lights - if (GpuProgramManager::getSingleton().isSyntaxSupported("arbvp1")) - { - // ARBvp1 - syntax = "arbvp1"; - } - else if (GpuProgramManager::getSingleton().isSyntaxSupported("vs_1_1")) - { - syntax = "vs_1_1"; - } - else if ( + // load hardware extrusion programs for point & dir lights + if (GpuProgramManager::getSingleton().isSyntaxSupported("arbvp1")) + { + // ARBvp1 + syntax = "arbvp1"; + } + else if (GpuProgramManager::getSingleton().isSyntaxSupported("vs_1_1")) + { + syntax = "vs_1_1"; + } + else if ( (GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0")) || (GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0_level_9_1")) || (GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0_level_9_3")) ) - { - syntax = "vs_4_0"; - } - else if (GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) - { - syntax = "glsles"; - } - else if (GpuProgramManager::getSingleton().isSyntaxSupported("glsl")) - { - syntax = "glsl"; - } - else - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Vertex programs are supposedly supported, but neither " - "arbvp1, glsl, glsles, vs_1_1 nor vs_4_0 syntaxes are present.", - "SceneManager::initShadowVolumeMaterials"); - } - // Create all programs - for (unsigned short v = 0; v < OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS; ++v) - { - // Create debug extruders - if (GpuProgramManager::getSingleton().getByName( - programNames[v]).isNull()) - { - if (syntax == "vs_4_0") - { - HighLevelGpuProgramPtr vp = - HighLevelGpuProgramManager::getSingleton().createProgram( - programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - "hlsl", GPT_VERTEX_PROGRAM); - vp->setSource(ShadowVolumeExtrudeProgram::getProgramSource( - vertexProgramLightTypes[v], syntax, - vertexProgramFinite[v], vertexProgramDebug[v])); + { + syntax = "vs_4_0"; + } + else if (GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) + { + syntax = "glsles"; + } + else if (GpuProgramManager::getSingleton().isSyntaxSupported("glsl")) + { + syntax = "glsl"; + } + else + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Vertex programs are supposedly supported, but neither " + "arbvp1, glsl, glsles, vs_1_1 nor vs_4_0 syntaxes are present.", + "SceneManager::initShadowVolumeMaterials"); + } + // Create all programs + for (unsigned short v = 0; v < OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS; ++v) + { + // Create debug extruders + if (GpuProgramManager::getSingleton().getByName( + programNames[v]).isNull()) + { + if (syntax == "vs_4_0") + { + HighLevelGpuProgramPtr vp = + HighLevelGpuProgramManager::getSingleton().createProgram( + programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, + "hlsl", GPT_VERTEX_PROGRAM); + vp->setSource(ShadowVolumeExtrudeProgram::getProgramSource( + vertexProgramLightTypes[v], syntax, + vertexProgramFinite[v], vertexProgramDebug[v])); - vp->setParameter("target", "vs_4_0_level_9_1"); // shared subset, to be usable from microcode cache on all devices - vp->setParameter("entry_point", "vs_main"); - vp->load(); + vp->setParameter("target", "vs_4_0_level_9_1"); // shared subset, to be usable from microcode cache on all devices + vp->setParameter("entry_point", "vs_main"); + vp->load(); - if (frgProgramName.empty()) - { - frgProgramName = "Ogre/ShadowFrgProgram"; - HighLevelGpuProgramPtr fp = - HighLevelGpuProgramManager::getSingleton().createProgram( - frgProgramName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - "hlsl", GPT_FRAGMENT_PROGRAM); - fp->setSource(mGeneralFs_4_0); - fp->setParameter("target", "ps_4_0_level_9_1"); // shared subset, to be usable from microcode cache on all devices - fp->setParameter("entry_point", "fs_main"); - fp->load(); - } - } - else if (syntax == "glsles") - { - HighLevelGpuProgramPtr vp = - HighLevelGpuProgramManager::getSingleton().createProgram( - programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - "glsles", GPT_VERTEX_PROGRAM); - vp->setSource(ShadowVolumeExtrudeProgram::getProgramSource( - vertexProgramLightTypes[v], syntax, - vertexProgramFinite[v], vertexProgramDebug[v])); - vp->setParameter("target", syntax); - vp->load(); + if (frgProgramName.empty()) + { + frgProgramName = "Ogre/ShadowFrgProgram"; + HighLevelGpuProgramPtr fp = + HighLevelGpuProgramManager::getSingleton().createProgram( + frgProgramName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, + "hlsl", GPT_FRAGMENT_PROGRAM); + fp->setSource(mGeneralFs_4_0); + fp->setParameter("target", "ps_4_0_level_9_1"); // shared subset, to be usable from microcode cache on all devices + fp->setParameter("entry_point", "fs_main"); + fp->load(); + } + } + else if (syntax == "glsles") + { + HighLevelGpuProgramPtr vp = + HighLevelGpuProgramManager::getSingleton().createProgram( + programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, + "glsles", GPT_VERTEX_PROGRAM); + vp->setSource(ShadowVolumeExtrudeProgram::getProgramSource( + vertexProgramLightTypes[v], syntax, + vertexProgramFinite[v], vertexProgramDebug[v])); + vp->setParameter("target", syntax); + vp->load(); - if (frgProgramName.empty()) - { - frgProgramName = "Ogre/ShadowFrgProgram"; - HighLevelGpuProgramPtr fp = - HighLevelGpuProgramManager::getSingleton().createProgram( - frgProgramName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - "glsles", GPT_FRAGMENT_PROGRAM); - fp->setSource(mGeneralFs_glsles); - fp->setParameter("target", "glsles"); - fp->load(); - } - } - else if (syntax == "glsl") - { - HighLevelGpuProgramPtr vp = + if (frgProgramName.empty()) + { + frgProgramName = "Ogre/ShadowFrgProgram"; + HighLevelGpuProgramPtr fp = + HighLevelGpuProgramManager::getSingleton().createProgram( + frgProgramName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, + "glsles", GPT_FRAGMENT_PROGRAM); + fp->setSource(mGeneralFs_glsles); + fp->setParameter("target", "glsles"); + fp->load(); + } + } + else if (syntax == "glsl") + { + HighLevelGpuProgramPtr vp = HighLevelGpuProgramManager::getSingleton().createProgram( programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, "glsl", GPT_VERTEX_PROGRAM); - vp->setSource(ShadowVolumeExtrudeProgram::getProgramSource( + vp->setSource(ShadowVolumeExtrudeProgram::getProgramSource( vertexProgramLightTypes[v], syntax, vertexProgramFinite[v], vertexProgramDebug[v])); - vp->setParameter("target", syntax); - vp->load(); + vp->setParameter("target", syntax); + vp->load(); - if (frgProgramName.empty()) - { - frgProgramName = "Ogre/ShadowFrgProgram"; - HighLevelGpuProgramPtr fp = + if (frgProgramName.empty()) + { + frgProgramName = "Ogre/ShadowFrgProgram"; + HighLevelGpuProgramPtr fp = HighLevelGpuProgramManager::getSingleton().createProgram( frgProgramName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, "glsl", GPT_FRAGMENT_PROGRAM); - fp->setSource(mGeneralFs_glsl); - fp->setParameter("target", "glsl"); - fp->load(); - } - } - else - { - GpuProgramPtr vp = - GpuProgramManager::getSingleton().createProgramFromString( - programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, - ShadowVolumeExtrudeProgram::getProgramSource( - vertexProgramLightTypes[v], syntax, - vertexProgramFinite[v], vertexProgramDebug[v]), - GPT_VERTEX_PROGRAM, syntax); - vp->load(); - } - } - } - mInitialised = true; - } + fp->setSource(mGeneralFs_glsl); + fp->setParameter("target", "glsl"); + fp->load(); + } + } + else + { + GpuProgramPtr vp = + GpuProgramManager::getSingleton().createProgramFromString( + programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, + ShadowVolumeExtrudeProgram::getProgramSource( + vertexProgramLightTypes[v], syntax, + vertexProgramFinite[v], vertexProgramDebug[v]), + GPT_VERTEX_PROGRAM, syntax); + vp->load(); + } + } + } + mInitialised = true; + } } //--------------------------------------------------------------------- void ShadowVolumeExtrudeProgram::shutdown(void) @@ -869,31 +869,31 @@ namespace Ogre { } } } - else if (syntax == "vs_4_0") - { - if (finite) - { - if (debug) - { - return getDirectionalLightExtruderVs_4_0FiniteDebug(); - } - else - { - return getDirectionalLightExtruderVs_4_0Finite(); - } - } - else - { - if (debug) - { - return getDirectionalLightExtruderVs_4_0Debug(); - } - else - { - return getDirectionalLightExtruderVs_4_0(); - } - } - } + else if (syntax == "vs_4_0") + { + if (finite) + { + if (debug) + { + return getDirectionalLightExtruderVs_4_0FiniteDebug(); + } + else + { + return getDirectionalLightExtruderVs_4_0Finite(); + } + } + else + { + if (debug) + { + return getDirectionalLightExtruderVs_4_0Debug(); + } + else + { + return getDirectionalLightExtruderVs_4_0(); + } + } + } else if (syntax == "glsl") { if (finite) @@ -944,13 +944,13 @@ namespace Ogre { } } } - else - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Vertex programs are supposedly supported, but neither " - "arbvp1, glsl, glsles, vs_1_1 nor vs_4_0 syntaxes are present.", - "SceneManager::getProgramSource"); - } + else + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Vertex programs are supposedly supported, but neither " + "arbvp1, glsl, glsles, vs_1_1 nor vs_4_0 syntaxes are present.", + "SceneManager::getProgramSource"); + } } else @@ -1005,88 +1005,88 @@ namespace Ogre { } } } - else if (syntax == "vs_4_0") - { - if (finite) - { - if (debug) - { - return getPointLightExtruderVs_4_0FiniteDebug(); - } - else - { - return getPointLightExtruderVs_4_0Finite(); - } - } - else - { - if (debug) - { - return getPointLightExtruderVs_4_0Debug(); - } - else - { - return getPointLightExtruderVs_4_0(); - } - } - } - else if (syntax == "glsl") - { - if (finite) - { - if (debug) - { - return getPointLightExtruderVs_glslFiniteDebug(); - } - else - { - return getPointLightExtruderVs_glslFinite(); - } - } - else - { - if (debug) - { - return getPointLightExtruderVs_glslDebug(); - } - else - { - return getPointLightExtruderVs_glsl(); - } - } - } - else if (syntax == "glsles") - { - if (finite) - { - if (debug) - { - return getPointLightExtruderVs_glslesFiniteDebug(); - } - else - { - return getPointLightExtruderVs_glslesFinite(); - } - } - else - { - if (debug) - { - return getPointLightExtruderVs_glslesDebug(); - } - else - { - return getPointLightExtruderVs_glsles(); - } - } - } - else - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Vertex programs are supposedly supported, but neither " - "arbvp1, glsl, glsles, vs_1_1 nor vs_4_0 syntaxes are present.", - "SceneManager::getProgramSource"); - } + else if (syntax == "vs_4_0") + { + if (finite) + { + if (debug) + { + return getPointLightExtruderVs_4_0FiniteDebug(); + } + else + { + return getPointLightExtruderVs_4_0Finite(); + } + } + else + { + if (debug) + { + return getPointLightExtruderVs_4_0Debug(); + } + else + { + return getPointLightExtruderVs_4_0(); + } + } + } + else if (syntax == "glsl") + { + if (finite) + { + if (debug) + { + return getPointLightExtruderVs_glslFiniteDebug(); + } + else + { + return getPointLightExtruderVs_glslFinite(); + } + } + else + { + if (debug) + { + return getPointLightExtruderVs_glslDebug(); + } + else + { + return getPointLightExtruderVs_glsl(); + } + } + } + else if (syntax == "glsles") + { + if (finite) + { + if (debug) + { + return getPointLightExtruderVs_glslesFiniteDebug(); + } + else + { + return getPointLightExtruderVs_glslesFinite(); + } + } + else + { + if (debug) + { + return getPointLightExtruderVs_glslesDebug(); + } + else + { + return getPointLightExtruderVs_glsles(); + } + } + } + else + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Vertex programs are supposedly supported, but neither " + "arbvp1, glsl, glsles, vs_1_1 nor vs_4_0 syntaxes are present.", + "SceneManager::getProgramSource"); + } } } diff --git a/OgreMain/src/OgreSimpleRenderable.cpp b/OgreMain/src/OgreSimpleRenderable.cpp index bc65b67bf53..cb2db88b306 100644 --- a/OgreMain/src/OgreSimpleRenderable.cpp +++ b/OgreMain/src/OgreSimpleRenderable.cpp @@ -36,37 +36,37 @@ namespace Ogre { uint SimpleRenderable::msGenNameCount = 0; SimpleRenderable::SimpleRenderable() - : MovableObject() - , mWorldTransform(Matrix4::IDENTITY) - , mMatName("BaseWhite") + : MovableObject() + , mWorldTransform(Matrix4::IDENTITY) + , mMatName("BaseWhite") , mMaterial(MaterialManager::getSingleton().getByName("BaseWhite")) - , mParentSceneManager(NULL) - , mCamera(NULL) + , mParentSceneManager(NULL) + , mCamera(NULL) { // Generate name - StringStream name; - name << "SimpleRenderable" << msGenNameCount++; - mName = name.str(); + StringStream name; + name << "SimpleRenderable" << msGenNameCount++; + mName = name.str(); } - SimpleRenderable::SimpleRenderable(const String& name) - : MovableObject(name) - , mWorldTransform(Matrix4::IDENTITY) - , mMatName("BaseWhite") + SimpleRenderable::SimpleRenderable(const String& name) + : MovableObject(name) + , mWorldTransform(Matrix4::IDENTITY) + , mMatName("BaseWhite") , mMaterial(MaterialManager::getSingleton().getByName("BaseWhite")) - , mParentSceneManager(NULL) - , mCamera(NULL) - { - } + , mParentSceneManager(NULL) + , mCamera(NULL) + { + } void SimpleRenderable::setMaterial( const String& matName ) { mMatName = matName; mMaterial = MaterialManager::getSingleton().getByName(mMatName); - if (mMaterial.isNull()) - OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + mMatName, - "SimpleRenderable::setMaterial" ); + if (mMaterial.isNull()) + OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + mMatName, + "SimpleRenderable::setMaterial" ); // Won't load twice anyway mMaterial->load(); @@ -99,7 +99,7 @@ namespace Ogre { void SimpleRenderable::_notifyCurrentCamera(Camera* cam) { - MovableObject::_notifyCurrentCamera(cam); + MovableObject::_notifyCurrentCamera(cam); mCamera = cam; } @@ -119,11 +119,11 @@ namespace Ogre { queue->addRenderable( this, mRenderQueueID, OGRE_RENDERABLE_DEFAULT_PRIORITY); } - void SimpleRenderable::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - visitor->visit(this, 0, false); - } + void SimpleRenderable::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + visitor->visit(this, 0, false); + } SimpleRenderable::~SimpleRenderable() { diff --git a/OgreMain/src/OgreSkeleton.cpp b/OgreMain/src/OgreSkeleton.cpp index 82bd68390d4..e6e88d5f144 100644 --- a/OgreMain/src/OgreSkeleton.cpp +++ b/OgreMain/src/OgreSkeleton.cpp @@ -41,14 +41,14 @@ THE SOFTWARE. namespace Ogre { //--------------------------------------------------------------------- - Skeleton::Skeleton() - : Resource(), + Skeleton::Skeleton() + : Resource(), mBlendState(ANIMBLEND_AVERAGE), - mNextAutoHandle(0), - mManualBonesDirty(false) - { - } - //--------------------------------------------------------------------- + mNextAutoHandle(0), + mManualBonesDirty(false) + { + } + //--------------------------------------------------------------------- Skeleton::Skeleton(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) : Resource(creator, name, handle, group, isManual, loader), @@ -71,23 +71,23 @@ namespace Ogre { void Skeleton::loadImpl(void) { SkeletonSerializer serializer; - LogManager::getSingleton().stream() - << "Skeleton: Loading " << mName; + LogManager::getSingleton().stream() + << "Skeleton: Loading " << mName; DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource( - mName, mGroup, true, this); + mName, mGroup, true, this); serializer.importSkeleton(stream, this); - // Load any linked skeletons - LinkedSkeletonAnimSourceList::iterator i; - for (i = mLinkedSkeletonAnimSourceList.begin(); - i != mLinkedSkeletonAnimSourceList.end(); ++i) - { - i->pSkeleton = SkeletonManager::getSingleton().load( - i->skeletonName, mGroup).staticCast(); - } + // Load any linked skeletons + LinkedSkeletonAnimSourceList::iterator i; + for (i = mLinkedSkeletonAnimSourceList.begin(); + i != mLinkedSkeletonAnimSourceList.end(); ++i) + { + i->pSkeleton = SkeletonManager::getSingleton().load( + i->skeletonName, mGroup).staticCast(); + } } @@ -102,7 +102,7 @@ namespace Ogre { } mBoneList.clear(); mBoneListByName.clear(); - mRootBones.clear(); + mRootBones.clear(); mManualBones.clear(); mManualBonesDirty = false; @@ -213,30 +213,30 @@ namespace Ogre { // Reset bones reset(); - Real weightFactor = 1.0f; - if (mBlendState == ANIMBLEND_AVERAGE) - { - // Derive total weights so we can rebalance if > 1.0f - Real totalWeights = 0.0f; - ConstEnabledAnimationStateIterator stateIt = - animSet.getEnabledAnimationStateIterator(); - while (stateIt.hasMoreElements()) - { - const AnimationState* animState = stateIt.getNext(); - // Make sure we have an anim to match implementation - const LinkedSkeletonAnimationSource* linked = 0; - if (_getAnimationImpl(animState->getAnimationName(), &linked)) - { - totalWeights += animState->getWeight(); - } - } - - // Allow < 1.0f, allows fade out of all anims if required - if (totalWeights > 1.0f) - { - weightFactor = 1.0f / totalWeights; - } - } + Real weightFactor = 1.0f; + if (mBlendState == ANIMBLEND_AVERAGE) + { + // Derive total weights so we can rebalance if > 1.0f + Real totalWeights = 0.0f; + ConstEnabledAnimationStateIterator stateIt = + animSet.getEnabledAnimationStateIterator(); + while (stateIt.hasMoreElements()) + { + const AnimationState* animState = stateIt.getNext(); + // Make sure we have an anim to match implementation + const LinkedSkeletonAnimationSource* linked = 0; + if (_getAnimationImpl(animState->getAnimationName(), &linked)) + { + totalWeights += animState->getWeight(); + } + } + + // Allow < 1.0f, allows fade out of all anims if required + if (totalWeights > 1.0f) + { + weightFactor = 1.0f / totalWeights; + } + } // Per enabled animation state ConstEnabledAnimationStateIterator stateIt = @@ -300,7 +300,7 @@ namespace Ogre { } Animation* ret = OGRE_NEW Animation(name, length); - ret->_notifyContainer(this); + ret->_notifyContainer(this); // Add to list mAnimationsList[name] = ret; @@ -308,62 +308,62 @@ namespace Ogre { return ret; } - //--------------------------------------------------------------------- - Animation* Skeleton::getAnimation(const String& name, - const LinkedSkeletonAnimationSource** linker) const - { - Animation* ret = _getAnimationImpl(name, linker); - if (!ret) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No animation entry found named " + name, - "Skeleton::getAnimation"); - } - - return ret; - } - //--------------------------------------------------------------------- - Animation* Skeleton::getAnimation(const String& name) const - { - return getAnimation(name, 0); - } - //--------------------------------------------------------------------- - bool Skeleton::hasAnimation(const String& name) const - { - return _getAnimationImpl(name) != 0; - } + //--------------------------------------------------------------------- + Animation* Skeleton::getAnimation(const String& name, + const LinkedSkeletonAnimationSource** linker) const + { + Animation* ret = _getAnimationImpl(name, linker); + if (!ret) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "No animation entry found named " + name, + "Skeleton::getAnimation"); + } + + return ret; + } + //--------------------------------------------------------------------- + Animation* Skeleton::getAnimation(const String& name) const + { + return getAnimation(name, 0); + } + //--------------------------------------------------------------------- + bool Skeleton::hasAnimation(const String& name) const + { + return _getAnimationImpl(name) != 0; + } //--------------------------------------------------------------------- Animation* Skeleton::_getAnimationImpl(const String& name, - const LinkedSkeletonAnimationSource** linker) const + const LinkedSkeletonAnimationSource** linker) const { - Animation* ret = 0; + Animation* ret = 0; AnimationList::const_iterator i = mAnimationsList.find(name); if (i == mAnimationsList.end()) { - LinkedSkeletonAnimSourceList::const_iterator it; - for (it = mLinkedSkeletonAnimSourceList.begin(); - it != mLinkedSkeletonAnimSourceList.end() && !ret; ++it) - { - if (!it->pSkeleton.isNull()) - { - ret = it->pSkeleton->_getAnimationImpl(name); - if (ret && linker) - { - *linker = &(*it); - } - - } - } + LinkedSkeletonAnimSourceList::const_iterator it; + for (it = mLinkedSkeletonAnimSourceList.begin(); + it != mLinkedSkeletonAnimSourceList.end() && !ret; ++it) + { + if (!it->pSkeleton.isNull()) + { + ret = it->pSkeleton->_getAnimationImpl(name); + if (ret && linker) + { + *linker = &(*it); + } + + } + } } - else - { - if (linker) - *linker = 0; - ret = i->second; - } + else + { + if (linker) + *linker = 0; + ret = i->second; + } - return ret; + return ret; } //--------------------------------------------------------------------- @@ -396,64 +396,64 @@ namespace Ogre { animSet->createAnimationState(animName, 0.0, anim->getLength()); } - // Also iterate over linked animation - LinkedSkeletonAnimSourceList::iterator li; - for (li = mLinkedSkeletonAnimSourceList.begin(); - li != mLinkedSkeletonAnimSourceList.end(); ++li) - { - if (!li->pSkeleton.isNull()) - { - li->pSkeleton->_refreshAnimationState(animSet); - } - } + // Also iterate over linked animation + LinkedSkeletonAnimSourceList::iterator li; + for (li = mLinkedSkeletonAnimSourceList.begin(); + li != mLinkedSkeletonAnimSourceList.end(); ++li) + { + if (!li->pSkeleton.isNull()) + { + li->pSkeleton->_refreshAnimationState(animSet); + } + } } - //----------------------------------------------------------------------- - void Skeleton::_refreshAnimationState(AnimationStateSet* animSet) - { - // Merge in any new animations - AnimationList::iterator i; - for (i = mAnimationsList.begin(); i != mAnimationsList.end(); ++i) - { - Animation* anim = i->second; - // Create animation at time index 0, default params mean this has weight 1 and is disabled - const String& animName = anim->getName(); - if (!animSet->hasAnimationState(animName)) - { - animSet->createAnimationState(animName, 0.0, anim->getLength()); - } - else - { - // Update length incase changed - AnimationState* animState = animSet->getAnimationState(animName); - animState->setLength(anim->getLength()); - animState->setTimePosition(std::min(anim->getLength(), animState->getTimePosition())); - } - } - // Also iterate over linked animation - LinkedSkeletonAnimSourceList::iterator li; - for (li = mLinkedSkeletonAnimSourceList.begin(); - li != mLinkedSkeletonAnimSourceList.end(); ++li) - { - if (!li->pSkeleton.isNull()) - { - li->pSkeleton->_refreshAnimationState(animSet); - } - } - } - //----------------------------------------------------------------------- - void Skeleton::_notifyManualBonesDirty(void) - { - mManualBonesDirty = true; - } - //----------------------------------------------------------------------- - void Skeleton::_notifyManualBoneStateChange(Bone* bone) - { - if (bone->isManuallyControlled()) - mManualBones.insert(bone); - else - mManualBones.erase(bone); - } + //----------------------------------------------------------------------- + void Skeleton::_refreshAnimationState(AnimationStateSet* animSet) + { + // Merge in any new animations + AnimationList::iterator i; + for (i = mAnimationsList.begin(); i != mAnimationsList.end(); ++i) + { + Animation* anim = i->second; + // Create animation at time index 0, default params mean this has weight 1 and is disabled + const String& animName = anim->getName(); + if (!animSet->hasAnimationState(animName)) + { + animSet->createAnimationState(animName, 0.0, anim->getLength()); + } + else + { + // Update length incase changed + AnimationState* animState = animSet->getAnimationState(animName); + animState->setLength(anim->getLength()); + animState->setTimePosition(std::min(anim->getLength(), animState->getTimePosition())); + } + } + // Also iterate over linked animation + LinkedSkeletonAnimSourceList::iterator li; + for (li = mLinkedSkeletonAnimSourceList.begin(); + li != mLinkedSkeletonAnimSourceList.end(); ++li) + { + if (!li->pSkeleton.isNull()) + { + li->pSkeleton->_refreshAnimationState(animSet); + } + } + } + //----------------------------------------------------------------------- + void Skeleton::_notifyManualBonesDirty(void) + { + mManualBonesDirty = true; + } + //----------------------------------------------------------------------- + void Skeleton::_notifyManualBoneStateChange(Bone* bone) + { + if (bone->isManuallyControlled()) + mManualBones.insert(bone); + else + mManualBones.erase(bone); + } //----------------------------------------------------------------------- unsigned short Skeleton::getNumBones(void) const { @@ -494,12 +494,12 @@ namespace Ogre { //--------------------------------------------------------------------- Animation* Skeleton::getAnimation(unsigned short index) const { - // If you hit this assert, then the index is out of bounds. + // If you hit this assert, then the index is out of bounds. assert( index < mAnimationsList.size() ); AnimationList::const_iterator i = mAnimationsList.begin(); - std::advance(i, index); + std::advance(i, index); return i->second; } @@ -523,11 +523,11 @@ namespace Ogre { return i->second; } - //--------------------------------------------------------------------- - bool Skeleton::hasBone(const String& name) const - { - return mBoneListByName.find(name) != mBoneListByName.end(); - } + //--------------------------------------------------------------------- + bool Skeleton::hasBone(const String& name) const + { + return mBoneListByName.find(name) != mBoneListByName.end(); + } //--------------------------------------------------------------------- void Skeleton::deriveRootBone(void) const { @@ -617,15 +617,15 @@ namespace Ogre { } //--------------------------------------------------------------------- - SkeletonAnimationBlendMode Skeleton::getBlendMode() const + SkeletonAnimationBlendMode Skeleton::getBlendMode() const { - return mBlendState; - } + return mBlendState; + } //--------------------------------------------------------------------- - void Skeleton::setBlendMode(SkeletonAnimationBlendMode state) + void Skeleton::setBlendMode(SkeletonAnimationBlendMode state) { - mBlendState = state; - } + mBlendState = state; + } //--------------------------------------------------------------------- Skeleton::BoneIterator Skeleton::getRootBoneIterator(void) { @@ -649,11 +649,11 @@ namespace Ogre { { (*i)->_update(true, false); } - mManualBonesDirty = false; + mManualBonesDirty = false; } //--------------------------------------------------------------------- - void Skeleton::optimiseAllAnimations(bool preservingIdentityNodeTracks) - { + void Skeleton::optimiseAllAnimations(bool preservingIdentityNodeTracks) + { AnimationList::iterator ai, aiend; aiend = mAnimationsList.end(); @@ -684,53 +684,53 @@ namespace Ogre { for (ai = mAnimationsList.begin(); ai != aiend; ++ai) { // Don't discard identity node tracks here - ai->second->optimise(false); - } - } - //--------------------------------------------------------------------- - void Skeleton::addLinkedSkeletonAnimationSource(const String& skelName, - Real scale) - { - // Check not already linked - LinkedSkeletonAnimSourceList::iterator i; - for (i = mLinkedSkeletonAnimSourceList.begin(); - i != mLinkedSkeletonAnimSourceList.end(); ++i) - { - if (skelName == i->skeletonName) - return; // don't bother - } - - if (isLoaded()) - { - // Load immediately - SkeletonPtr skelPtr = - SkeletonManager::getSingleton().load(skelName, mGroup).staticCast(); - mLinkedSkeletonAnimSourceList.push_back( - LinkedSkeletonAnimationSource(skelName, scale, skelPtr)); - - } - else - { - // Load later - mLinkedSkeletonAnimSourceList.push_back( - LinkedSkeletonAnimationSource(skelName, scale)); - } - - } - //--------------------------------------------------------------------- - void Skeleton::removeAllLinkedSkeletonAnimationSources(void) - { - mLinkedSkeletonAnimSourceList.clear(); - } - //--------------------------------------------------------------------- - Skeleton::LinkedSkeletonAnimSourceIterator - Skeleton::getLinkedSkeletonAnimationSourceIterator(void) const - { - return LinkedSkeletonAnimSourceIterator( - mLinkedSkeletonAnimSourceList.begin(), - mLinkedSkeletonAnimSourceList.end()); - } - //--------------------------------------------------------------------- + ai->second->optimise(false); + } + } + //--------------------------------------------------------------------- + void Skeleton::addLinkedSkeletonAnimationSource(const String& skelName, + Real scale) + { + // Check not already linked + LinkedSkeletonAnimSourceList::iterator i; + for (i = mLinkedSkeletonAnimSourceList.begin(); + i != mLinkedSkeletonAnimSourceList.end(); ++i) + { + if (skelName == i->skeletonName) + return; // don't bother + } + + if (isLoaded()) + { + // Load immediately + SkeletonPtr skelPtr = + SkeletonManager::getSingleton().load(skelName, mGroup).staticCast(); + mLinkedSkeletonAnimSourceList.push_back( + LinkedSkeletonAnimationSource(skelName, scale, skelPtr)); + + } + else + { + // Load later + mLinkedSkeletonAnimSourceList.push_back( + LinkedSkeletonAnimationSource(skelName, scale)); + } + + } + //--------------------------------------------------------------------- + void Skeleton::removeAllLinkedSkeletonAnimationSources(void) + { + mLinkedSkeletonAnimSourceList.clear(); + } + //--------------------------------------------------------------------- + Skeleton::LinkedSkeletonAnimSourceIterator + Skeleton::getLinkedSkeletonAnimationSourceIterator(void) const + { + return LinkedSkeletonAnimSourceIterator( + mLinkedSkeletonAnimSourceList.begin(), + mLinkedSkeletonAnimSourceList.end()); + } + //--------------------------------------------------------------------- struct DeltaTransform { Vector3 translate; diff --git a/OgreMain/src/OgreSkeletonInstance.cpp b/OgreMain/src/OgreSkeletonInstance.cpp index f23b448e602..c1c8c4dae73 100644 --- a/OgreMain/src/OgreSkeletonInstance.cpp +++ b/OgreMain/src/OgreSkeletonInstance.cpp @@ -65,48 +65,48 @@ namespace Ogre { } //------------------------------------------------------------------------- Animation* SkeletonInstance::getAnimation(const String& name, - const LinkedSkeletonAnimationSource** linker) const + const LinkedSkeletonAnimationSource** linker) const { return mSkeleton->getAnimation(name, linker); } - //------------------------------------------------------------------------- - Animation* SkeletonInstance::_getAnimationImpl(const String& name, - const LinkedSkeletonAnimationSource** linker) const - { - return mSkeleton->_getAnimationImpl(name, linker); - } + //------------------------------------------------------------------------- + Animation* SkeletonInstance::_getAnimationImpl(const String& name, + const LinkedSkeletonAnimationSource** linker) const + { + return mSkeleton->_getAnimationImpl(name, linker); + } //------------------------------------------------------------------------- void SkeletonInstance::removeAnimation(const String& name) { mSkeleton->removeAnimation(name); } - //------------------------------------------------------------------------- - void SkeletonInstance::addLinkedSkeletonAnimationSource(const String& skelName, - Real scale) - { - mSkeleton->addLinkedSkeletonAnimationSource(skelName, scale); - } - //------------------------------------------------------------------------- - void SkeletonInstance::removeAllLinkedSkeletonAnimationSources(void) - { - mSkeleton->removeAllLinkedSkeletonAnimationSources(); - } - //------------------------------------------------------------------------- - Skeleton::LinkedSkeletonAnimSourceIterator - SkeletonInstance::getLinkedSkeletonAnimationSourceIterator(void) const - { - return mSkeleton->getLinkedSkeletonAnimationSourceIterator(); - } - //------------------------------------------------------------------------- - void SkeletonInstance::_initAnimationState(AnimationStateSet* animSet) - { - mSkeleton->_initAnimationState(animSet); - } - //------------------------------------------------------------------------- - void SkeletonInstance::_refreshAnimationState(AnimationStateSet* animSet) - { - mSkeleton->_refreshAnimationState(animSet); - } + //------------------------------------------------------------------------- + void SkeletonInstance::addLinkedSkeletonAnimationSource(const String& skelName, + Real scale) + { + mSkeleton->addLinkedSkeletonAnimationSource(skelName, scale); + } + //------------------------------------------------------------------------- + void SkeletonInstance::removeAllLinkedSkeletonAnimationSources(void) + { + mSkeleton->removeAllLinkedSkeletonAnimationSources(); + } + //------------------------------------------------------------------------- + Skeleton::LinkedSkeletonAnimSourceIterator + SkeletonInstance::getLinkedSkeletonAnimationSourceIterator(void) const + { + return mSkeleton->getLinkedSkeletonAnimationSourceIterator(); + } + //------------------------------------------------------------------------- + void SkeletonInstance::_initAnimationState(AnimationStateSet* animSet) + { + mSkeleton->_initAnimationState(animSet); + } + //------------------------------------------------------------------------- + void SkeletonInstance::_refreshAnimationState(AnimationStateSet* animSet) + { + mSkeleton->_refreshAnimationState(animSet); + } //------------------------------------------------------------------------- void SkeletonInstance::cloneBoneAndChildren(Bone* source, Bone* parent) { @@ -223,24 +223,24 @@ namespace Ogre { mFreeTagPoints.splice(mFreeTagPoints.end(), mActiveTagPoints, it); } } - //------------------------------------------------------------------------- - const String& SkeletonInstance::getName(void) const - { - // delegate - return mSkeleton->getName(); - } - //------------------------------------------------------------------------- - ResourceHandle SkeletonInstance::getHandle(void) const - { - // delegate - return mSkeleton->getHandle(); - } - //------------------------------------------------------------------------- - const String& SkeletonInstance::getGroup(void) - { - // delegate - return mSkeleton->getGroup(); - } + //------------------------------------------------------------------------- + const String& SkeletonInstance::getName(void) const + { + // delegate + return mSkeleton->getName(); + } + //------------------------------------------------------------------------- + ResourceHandle SkeletonInstance::getHandle(void) const + { + // delegate + return mSkeleton->getHandle(); + } + //------------------------------------------------------------------------- + const String& SkeletonInstance::getGroup(void) + { + // delegate + return mSkeleton->getGroup(); + } } diff --git a/OgreMain/src/OgreSkeletonSerializer.cpp b/OgreMain/src/OgreSkeletonSerializer.cpp index cfb721f0a58..4cfd6fceb48 100644 --- a/OgreMain/src/OgreSkeletonSerializer.cpp +++ b/OgreMain/src/OgreSkeletonSerializer.cpp @@ -39,8 +39,8 @@ THE SOFTWARE. namespace Ogre { /// stream overhead = ID + size const long SSTREAM_OVERHEAD_SIZE = sizeof(uint16) + sizeof(uint32); - const uint16 HEADER_STREAM_ID_EXT = 0x1000; - //--------------------------------------------------------------------- + const uint16 HEADER_STREAM_ID_EXT = 0x1000; + //--------------------------------------------------------------------- SkeletonSerializer::SkeletonSerializer() { // Version number @@ -52,38 +52,38 @@ namespace Ogre { { } - //--------------------------------------------------------------------- - void SkeletonSerializer::exportSkeleton(const Skeleton* pSkeleton, - const String& filename, SkeletonVersion ver, Endian endianMode) - { - std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); - f->open(filename.c_str(), std::ios::binary | std::ios::out); - DataStreamPtr stream(OGRE_NEW FileStreamDataStream(f)); + //--------------------------------------------------------------------- + void SkeletonSerializer::exportSkeleton(const Skeleton* pSkeleton, + const String& filename, SkeletonVersion ver, Endian endianMode) + { + std::fstream *f = OGRE_NEW_T(std::fstream, MEMCATEGORY_GENERAL)(); + f->open(filename.c_str(), std::ios::binary | std::ios::out); + DataStreamPtr stream(OGRE_NEW FileStreamDataStream(f)); - exportSkeleton(pSkeleton, stream, ver, endianMode); + exportSkeleton(pSkeleton, stream, ver, endianMode); - stream->close(); - } + stream->close(); + } //--------------------------------------------------------------------- void SkeletonSerializer::exportSkeleton(const Skeleton* pSkeleton, - DataStreamPtr stream, SkeletonVersion ver, Endian endianMode) + DataStreamPtr stream, SkeletonVersion ver, Endian endianMode) { - setWorkingVersion(ver); - // Decide on endian mode - determineEndianness(endianMode); + setWorkingVersion(ver); + // Decide on endian mode + determineEndianness(endianMode); mStream = stream; - if (!stream->isWriteable()) - { - OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, - "Unable to write to stream " + stream->getName(), - "SkeletonSerializer::exportSkeleton"); - } + if (!stream->isWriteable()) + { + OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, + "Unable to write to stream " + stream->getName(), + "SkeletonSerializer::exportSkeleton"); + } writeFileHeader(); - pushInnerChunk(mStream); + pushInnerChunk(mStream); // Write main skeleton data LogManager::getSingleton().logMessage("Exporting bones.."); writeSkeleton(pSkeleton, ver); @@ -92,50 +92,50 @@ namespace Ogre { // Write all animations unsigned short numAnims = pSkeleton->getNumAnimations(); LogManager::getSingleton().stream() - << "Exporting animations, count=" << numAnims; + << "Exporting animations, count=" << numAnims; for (unsigned short i = 0; i < numAnims; ++i) { Animation* pAnim = pSkeleton->getAnimation(i); - LogManager::getSingleton().stream() - << "Exporting animation: " << pAnim->getName(); + LogManager::getSingleton().stream() + << "Exporting animation: " << pAnim->getName(); writeAnimation(pSkeleton, pAnim, ver); LogManager::getSingleton().logMessage("Animation exported."); } - // Write links - Skeleton::LinkedSkeletonAnimSourceIterator linkIt = - pSkeleton->getLinkedSkeletonAnimationSourceIterator(); - while(linkIt.hasMoreElements()) - { - const LinkedSkeletonAnimationSource& link = linkIt.getNext(); - writeSkeletonAnimationLink(pSkeleton, link); - } - popInnerChunk(stream); + // Write links + Skeleton::LinkedSkeletonAnimSourceIterator linkIt = + pSkeleton->getLinkedSkeletonAnimationSourceIterator(); + while(linkIt.hasMoreElements()) + { + const LinkedSkeletonAnimationSource& link = linkIt.getNext(); + writeSkeletonAnimationLink(pSkeleton, link); + } + popInnerChunk(stream); } //--------------------------------------------------------------------- void SkeletonSerializer::importSkeleton(DataStreamPtr& stream, Skeleton* pSkel) { - // Determine endianness (must be the first thing we do!) - determineEndianness(stream); + // Determine endianness (must be the first thing we do!) + determineEndianness(stream); - // Check header + // Check header readFileHeader(stream); - pushInnerChunk(stream); - bool invalidChunkID = false; + pushInnerChunk(stream); + bool invalidChunkID = false; while(!stream->eof() && !invalidChunkID) { unsigned short streamID = readChunk(stream); switch (streamID) { - case SKELETON_BLENDMODE: - { - // Optional blend mode - uint16 blendMode; - readShorts(stream, &blendMode, 1); - pSkel->setBlendMode(static_cast(blendMode)); - break; - } + case SKELETON_BLENDMODE: + { + // Optional blend mode + uint16 blendMode; + readShorts(stream, &blendMode, 1); + pSkel->setBlendMode(static_cast(blendMode)); + break; + } case SKELETON_BONE: readBone(stream, pSkel); break; @@ -144,40 +144,40 @@ namespace Ogre { break; case SKELETON_ANIMATION: readAnimation(stream, pSkel); - break; - case SKELETON_ANIMATION_LINK: - readSkeletonAnimationLink(stream, pSkel); - break; - default: - invalidChunkID = true; - break; + break; + case SKELETON_ANIMATION_LINK: + readSkeletonAnimationLink(stream, pSkel); + break; + default: + invalidChunkID = true; + break; } } - // Assume bones are stored in the binding pose + // Assume bones are stored in the binding pose pSkel->setBindingPose(); - popInnerChunk(stream); + popInnerChunk(stream); } - - //--------------------------------------------------------------------- - void SkeletonSerializer::setWorkingVersion(SkeletonVersion ver) - { - if (ver == SKELETON_VERSION_1_0) - mVersion = "[Serializer_v1.10]"; - else mVersion = "[Serializer_v1.80]"; - } - //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + void SkeletonSerializer::setWorkingVersion(SkeletonVersion ver) + { + if (ver == SKELETON_VERSION_1_0) + mVersion = "[Serializer_v1.10]"; + else mVersion = "[Serializer_v1.80]"; + } + //--------------------------------------------------------------------- void SkeletonSerializer::writeSkeleton(const Skeleton* pSkel, SkeletonVersion ver) { - - // Write blend mode - if ((int)ver > (int)SKELETON_VERSION_1_0) - { - writeChunkHeader(SKELETON_BLENDMODE, SSTREAM_OVERHEAD_SIZE + sizeof(unsigned short)); - uint16 blendMode = static_cast(pSkel->getBlendMode()); - writeShorts(&blendMode, 1); - } - + + // Write blend mode + if ((int)ver > (int)SKELETON_VERSION_1_0) + { + writeChunkHeader(SKELETON_BLENDMODE, SSTREAM_OVERHEAD_SIZE + sizeof(unsigned short)); + uint16 blendMode = static_cast(pSkel->getBlendMode()); + writeShorts(&blendMode, 1); + } + // Write each bone unsigned short numBones = pSkel->getNumBones(); unsigned short i; @@ -207,8 +207,8 @@ namespace Ogre { // char* name writeString(pBone->getName()); #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - // Hack to fix chunk size validation: - mChunkSizeStack.back() += calcStringSize(pBone->getName()); + // Hack to fix chunk size validation: + mChunkSizeStack.back() += calcStringSize(pBone->getName()); #endif // unsigned short handle : handle of the bone, should be contiguous & start at 0 writeShorts(&handle, 1); @@ -245,28 +245,28 @@ namespace Ogre { // float length : Length of the animation in seconds float len = anim->getLength(); writeFloats(&len, 1); - pushInnerChunk(mStream); - { - if ((int)ver > (int)SKELETON_VERSION_1_0) - { - if (anim->getUseBaseKeyFrame()) - { - size_t size = SSTREAM_OVERHEAD_SIZE; - // char* baseAnimationName (including terminator) - size += calcStringSize(anim->getBaseKeyFrameAnimationName()); - // float baseKeyFrameTime - size += sizeof(float); - - writeChunkHeader(SKELETON_ANIMATION_BASEINFO, size); - - // char* baseAnimationName (blank for self) - writeString(anim->getBaseKeyFrameAnimationName()); - - // float baseKeyFrameTime - float t = (float)anim->getBaseKeyFrameTime(); - writeFloats(&t, 1); - } - } + pushInnerChunk(mStream); + { + if ((int)ver > (int)SKELETON_VERSION_1_0) + { + if (anim->getUseBaseKeyFrame()) + { + size_t size = SSTREAM_OVERHEAD_SIZE; + // char* baseAnimationName (including terminator) + size += calcStringSize(anim->getBaseKeyFrameAnimationName()); + // float baseKeyFrameTime + size += sizeof(float); + + writeChunkHeader(SKELETON_ANIMATION_BASEINFO, size); + + // char* baseAnimationName (blank for self) + writeString(anim->getBaseKeyFrameAnimationName()); + + // float baseKeyFrameTime + float t = (float)anim->getBaseKeyFrameTime(); + writeFloats(&t, 1); + } + } // Write all tracks Animation::NodeTrackIterator trackIt = anim->getNodeTrackIterator(); @@ -274,8 +274,8 @@ namespace Ogre { { writeAnimationTrack(pSkel, trackIt.getNext()); } - } - popInnerChunk(mStream); + } + popInnerChunk(mStream); } //--------------------------------------------------------------------- @@ -288,13 +288,13 @@ namespace Ogre { Bone* bone = static_cast(track->getAssociatedNode()); unsigned short boneid = bone->getHandle(); writeShorts(&boneid, 1); - pushInnerChunk(mStream); + pushInnerChunk(mStream); // Write all keyframes for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) { writeKeyFrame(pSkel, track->getNodeKeyFrame(i)); } - popInnerChunk(mStream); + popInnerChunk(mStream); } //--------------------------------------------------------------------- void SkeletonSerializer::writeKeyFrame(const Skeleton* pSkel, @@ -320,7 +320,7 @@ namespace Ogre { size_t SkeletonSerializer::calcBoneSize(const Skeleton* pSkel, const Bone* pBone) { - size_t size = calcBoneSizeWithoutScale(pSkel, pBone); + size_t size = calcBoneSizeWithoutScale(pSkel, pBone); // scale if (pBone->getScale() != Vector3::UNIT_SCALE) @@ -336,9 +336,9 @@ namespace Ogre { { size_t size = SSTREAM_OVERHEAD_SIZE; - // TODO: Add this for next skeleton format! - // Currently it is broken, because to determine that we have scale, it will compare chunk size. - //size += calcStringSize(pBone->getName()); + // TODO: Add this for next skeleton format! + // Currently it is broken, because to determine that we have scale, it will compare chunk size. + //size += calcStringSize(pBone->getName()); // handle size += sizeof(unsigned short); @@ -365,31 +365,31 @@ namespace Ogre { return size; } //--------------------------------------------------------------------- - size_t SkeletonSerializer::calcAnimationSize(const Skeleton* pSkel, const Animation* pAnim, SkeletonVersion ver) + size_t SkeletonSerializer::calcAnimationSize(const Skeleton* pSkel, const Animation* pAnim, SkeletonVersion ver) { size_t size = SSTREAM_OVERHEAD_SIZE; // Name, including terminator - size += calcStringSize(pAnim->getName()); + size += calcStringSize(pAnim->getName()); // length size += sizeof(float); - if ((int)ver > (int)SKELETON_VERSION_1_0) - { - if (pAnim->getUseBaseKeyFrame()) - { - size += SSTREAM_OVERHEAD_SIZE; - // char* baseAnimationName (including terminator) - size += calcStringSize(pAnim->getBaseKeyFrameAnimationName()); - // float baseKeyFrameTime - size += sizeof(float); - } - } + if ((int)ver > (int)SKELETON_VERSION_1_0) + { + if (pAnim->getUseBaseKeyFrame()) + { + size += SSTREAM_OVERHEAD_SIZE; + // char* baseAnimationName (including terminator) + size += calcStringSize(pAnim->getBaseKeyFrameAnimationName()); + // float baseKeyFrameTime + size += sizeof(float); + } + } // Nested animation tracks - Animation::NodeTrackIterator trackIt = pAnim->getNodeTrackIterator(); - while(trackIt.hasMoreElements()) - { + Animation::NodeTrackIterator trackIt = pAnim->getNodeTrackIterator(); + while(trackIt.hasMoreElements()) + { size += calcAnimationTrackSize(pSkel, trackIt.getNext()); } @@ -416,7 +416,7 @@ namespace Ogre { size_t SkeletonSerializer::calcKeyFrameSize(const Skeleton* pSkel, const TransformKeyFrame* pKey) { - size_t size = calcKeyFrameSizeWithoutScale(pSkel, pKey); + size_t size = calcKeyFrameSizeWithoutScale(pSkel, pKey); // Vector3 scale : Scale to apply at this keyframe if (pKey->getScale() != Vector3::UNIT_SCALE) @@ -441,34 +441,34 @@ namespace Ogre { return size; } - //--------------------------------------------------------------------- - void SkeletonSerializer::readFileHeader(DataStreamPtr& stream) - { - unsigned short headerID; - - // Read header ID - readShorts(stream, &headerID, 1); - - if (headerID == HEADER_STREAM_ID_EXT) - { - // Read version - String ver = readString(stream); - if ((ver != "[Serializer_v1.10]") && - (ver != "[Serializer_v1.80]")) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Invalid file: version incompatible, file reports " + String(ver), - "Serializer::readFileHeader"); - } - mVersion = ver; - } - else - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Invalid file: no header", - "Serializer::readFileHeader"); - } - } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void SkeletonSerializer::readFileHeader(DataStreamPtr& stream) + { + unsigned short headerID; + + // Read header ID + readShorts(stream, &headerID, 1); + + if (headerID == HEADER_STREAM_ID_EXT) + { + // Read version + String ver = readString(stream); + if ((ver != "[Serializer_v1.10]") && + (ver != "[Serializer_v1.80]")) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Invalid file: version incompatible, file reports " + String(ver), + "Serializer::readFileHeader"); + } + mVersion = ver; + } + else + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Invalid file: no header", + "Serializer::readFileHeader"); + } + } + //--------------------------------------------------------------------- void SkeletonSerializer::readBone(DataStreamPtr& stream, Skeleton* pSkel) { // char* name @@ -490,11 +490,11 @@ namespace Ogre { pBone->setOrientation(q); #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE - // Hack to fix chunk size validation: - mChunkSizeStack.back() += calcStringSize(name); + // Hack to fix chunk size validation: + mChunkSizeStack.back() += calcStringSize(name); #endif - // TODO: don't depend on mCurrentstreamLen in next skeleton format! - // Currently we use wrong chunk sizes, but we can't fix it, because we depend on mCurrentstreamLen + // TODO: don't depend on mCurrentstreamLen in next skeleton format! + // Currently we use wrong chunk sizes, but we can't fix it, because we depend on mCurrentstreamLen // Do we have scale? if (mCurrentstreamLen > calcBoneSizeWithoutScale(pSkel, pBone)) { @@ -502,7 +502,7 @@ namespace Ogre { readObject(stream, scale); pBone->setScale(scale); } - + } //--------------------------------------------------------------------- void SkeletonSerializer::readBoneParent(DataStreamPtr& stream, Skeleton* pSkel) @@ -538,26 +538,26 @@ namespace Ogre { // Read all tracks if (!stream->eof()) { - pushInnerChunk(stream); + pushInnerChunk(stream); unsigned short streamID = readChunk(stream); - // Optional base info is possible - if (streamID == SKELETON_ANIMATION_BASEINFO) - { - // char baseAnimationName - String baseAnimName = readString(stream); - // float baseKeyFrameTime - float baseKeyTime; - readFloats(stream, &baseKeyTime, 1); - - pAnim->setUseBaseKeyFrame(true, baseKeyTime, baseAnimName); - + // Optional base info is possible + if (streamID == SKELETON_ANIMATION_BASEINFO) + { + // char baseAnimationName + String baseAnimName = readString(stream); + // float baseKeyFrameTime + float baseKeyTime; + readFloats(stream, &baseKeyTime, 1); + + pAnim->setUseBaseKeyFrame(true, baseKeyTime, baseAnimName); + if (!stream->eof()) { // Get next stream streamID = readChunk(stream); } - } - + } + while(streamID == SKELETON_ANIMATION_TRACK && !stream->eof()) { readAnimationTrack(stream, pAnim, pSkel); @@ -573,7 +573,7 @@ namespace Ogre { // Backpedal back to start of this stream if we've found a non-track backpedalChunkHeader(stream); } - popInnerChunk(stream); + popInnerChunk(stream); } } //--------------------------------------------------------------------- @@ -593,7 +593,7 @@ namespace Ogre { // Keep looking for nested keyframes if (!stream->eof()) { - pushInnerChunk(stream); + pushInnerChunk(stream); unsigned short streamID = readChunk(stream); while(streamID == SKELETON_ANIMATION_TRACK_KEYFRAME && !stream->eof()) { @@ -608,9 +608,9 @@ namespace Ogre { if (!stream->eof()) { // Backpedal back to start of this stream if we've found a non-keyframe - backpedalChunkHeader(stream); + backpedalChunkHeader(stream); } - popInnerChunk(stream); + popInnerChunk(stream); } @@ -641,46 +641,46 @@ namespace Ogre { kf->setScale(scale); } } - //--------------------------------------------------------------------- - void SkeletonSerializer::writeSkeletonAnimationLink(const Skeleton* pSkel, - const LinkedSkeletonAnimationSource& link) - { - writeChunkHeader(SKELETON_ANIMATION_LINK, - calcSkeletonAnimationLinkSize(pSkel, link)); - - // char* skeletonName - writeString(link.skeletonName); - // float scale - writeFloats(&(link.scale), 1); - - } //--------------------------------------------------------------------- - size_t SkeletonSerializer::calcSkeletonAnimationLinkSize(const Skeleton* pSkel, - const LinkedSkeletonAnimationSource& link) - { - size_t size = SSTREAM_OVERHEAD_SIZE; - - // char* skeletonName - size += link.skeletonName.length() + 1; - // float scale - size += sizeof(float); - - return size; - - } - //--------------------------------------------------------------------- - void SkeletonSerializer::readSkeletonAnimationLink(DataStreamPtr& stream, - Skeleton* pSkel) - { - // char* skeletonName - String skelName = readString(stream); - // float scale - float scale; - readFloats(stream, &scale, 1); - - pSkel->addLinkedSkeletonAnimationSource(skelName, scale); - - } + void SkeletonSerializer::writeSkeletonAnimationLink(const Skeleton* pSkel, + const LinkedSkeletonAnimationSource& link) + { + writeChunkHeader(SKELETON_ANIMATION_LINK, + calcSkeletonAnimationLinkSize(pSkel, link)); + + // char* skeletonName + writeString(link.skeletonName); + // float scale + writeFloats(&(link.scale), 1); + + } + //--------------------------------------------------------------------- + size_t SkeletonSerializer::calcSkeletonAnimationLinkSize(const Skeleton* pSkel, + const LinkedSkeletonAnimationSource& link) + { + size_t size = SSTREAM_OVERHEAD_SIZE; + + // char* skeletonName + size += link.skeletonName.length() + 1; + // float scale + size += sizeof(float); + + return size; + + } + //--------------------------------------------------------------------- + void SkeletonSerializer::readSkeletonAnimationLink(DataStreamPtr& stream, + Skeleton* pSkel) + { + // char* skeletonName + String skelName = readString(stream); + // float scale + float scale; + readFloats(stream, &scale, 1); + + pSkel->addLinkedSkeletonAnimationSource(skelName, scale); + + } diff --git a/OgreMain/src/OgreStaticGeometry.cpp b/OgreMain/src/OgreStaticGeometry.cpp index 84ca7771d32..1d6b606dd47 100644 --- a/OgreMain/src/OgreStaticGeometry.cpp +++ b/OgreMain/src/OgreStaticGeometry.cpp @@ -46,708 +46,708 @@ THE SOFTWARE. namespace Ogre { - #define REGION_RANGE 1024 - #define REGION_HALF_RANGE 512 - #define REGION_MAX_INDEX 511 - #define REGION_MIN_INDEX -512 - - //-------------------------------------------------------------------------- - StaticGeometry::StaticGeometry(SceneManager* owner, const String& name): - mOwner(owner), - mName(name), - mBuilt(false), - mUpperDistance(0.0f), - mSquaredUpperDistance(0.0f), - mCastShadows(false), - mRegionDimensions(Vector3(1000,1000,1000)), - mHalfRegionDimensions(Vector3(500,500,500)), - mOrigin(Vector3(0,0,0)), - mVisible(true), + #define REGION_RANGE 1024 + #define REGION_HALF_RANGE 512 + #define REGION_MAX_INDEX 511 + #define REGION_MIN_INDEX -512 + + //-------------------------------------------------------------------------- + StaticGeometry::StaticGeometry(SceneManager* owner, const String& name): + mOwner(owner), + mName(name), + mBuilt(false), + mUpperDistance(0.0f), + mSquaredUpperDistance(0.0f), + mCastShadows(false), + mRegionDimensions(Vector3(1000,1000,1000)), + mHalfRegionDimensions(Vector3(500,500,500)), + mOrigin(Vector3(0,0,0)), + mVisible(true), mRenderQueueID(RENDER_QUEUE_MAIN), mRenderQueueIDSet(false), - mVisibilityFlags(Ogre::MovableObject::getDefaultVisibilityFlags()) - { - } - //-------------------------------------------------------------------------- - StaticGeometry::~StaticGeometry() - { - reset(); - } - //-------------------------------------------------------------------------- - StaticGeometry::Region* StaticGeometry::getRegion(const AxisAlignedBox& bounds, - bool autoCreate) - { - if (bounds.isNull()) - return 0; - - // Get the region which has the largest overlapping volume - const Vector3 min = bounds.getMinimum(); - const Vector3 max = bounds.getMaximum(); - - // Get the min and max region indexes - ushort minx, miny, minz; - ushort maxx, maxy, maxz; - getRegionIndexes(min, minx, miny, minz); - getRegionIndexes(max, maxx, maxy, maxz); - Real maxVolume = 0.0f; - ushort finalx = 0, finaly = 0, finalz = 0; - for (ushort x = minx; x <= maxx; ++x) - { - for (ushort y = miny; y <= maxy; ++y) - { - for (ushort z = minz; z <= maxz; ++z) - { - Real vol = getVolumeIntersection(bounds, x, y, z); - if (vol > maxVolume) - { - maxVolume = vol; - finalx = x; - finaly = y; - finalz = z; - } - - } - } - } - - assert(maxVolume > 0.0f && - "Static geometry: Problem determining closest volume match!"); - - return getRegion(finalx, finaly, finalz, autoCreate); - - } - //-------------------------------------------------------------------------- - Real StaticGeometry::getVolumeIntersection(const AxisAlignedBox& box, - ushort x, ushort y, ushort z) - { - // Get bounds of indexed region - AxisAlignedBox regionBounds = getRegionBounds(x, y, z); - AxisAlignedBox intersectBox = regionBounds.intersection(box); - // return a 'volume' which ignores zero dimensions - // since we only use this for relative comparisons of the same bounds - // this will still be internally consistent - Vector3 boxdiff = box.getMaximum() - box.getMinimum(); - Vector3 intersectDiff = intersectBox.getMaximum() - intersectBox.getMinimum(); - - return (boxdiff.x == 0 ? 1 : intersectDiff.x) * - (boxdiff.y == 0 ? 1 : intersectDiff.y) * - (boxdiff.z == 0 ? 1 : intersectDiff.z); - - } - //-------------------------------------------------------------------------- - AxisAlignedBox StaticGeometry::getRegionBounds(ushort x, ushort y, ushort z) - { - Vector3 min( - ((Real)x - REGION_HALF_RANGE) * mRegionDimensions.x + mOrigin.x, - ((Real)y - REGION_HALF_RANGE) * mRegionDimensions.y + mOrigin.y, - ((Real)z - REGION_HALF_RANGE) * mRegionDimensions.z + mOrigin.z - ); - Vector3 max = min + mRegionDimensions; - return AxisAlignedBox(min, max); - } - //-------------------------------------------------------------------------- - Vector3 StaticGeometry::getRegionCentre(ushort x, ushort y, ushort z) - { - return Vector3( - ((Real)x - REGION_HALF_RANGE) * mRegionDimensions.x + mOrigin.x - + mHalfRegionDimensions.x, - ((Real)y - REGION_HALF_RANGE) * mRegionDimensions.y + mOrigin.y - + mHalfRegionDimensions.y, - ((Real)z - REGION_HALF_RANGE) * mRegionDimensions.z + mOrigin.z - + mHalfRegionDimensions.z - ); - } - //-------------------------------------------------------------------------- - StaticGeometry::Region* StaticGeometry::getRegion( - ushort x, ushort y, ushort z, bool autoCreate) - { - uint32 index = packIndex(x, y, z); - Region* ret = getRegion(index); - if (!ret && autoCreate) - { - // Make a name - StringStream str; - str << mName << ":" << index; - // Calculate the region centre - Vector3 centre = getRegionCentre(x, y, z); - ret = OGRE_NEW Region(this, str.str(), mOwner, index, centre); - mOwner->injectMovableObject(ret); - ret->setVisible(mVisible); - ret->setCastShadows(mCastShadows); - if (mRenderQueueIDSet) - { - ret->setRenderQueueGroup(mRenderQueueID); - } - mRegionMap[index] = ret; - } - return ret; - } - //-------------------------------------------------------------------------- - StaticGeometry::Region* StaticGeometry::getRegion(uint32 index) - { - RegionMap::iterator i = mRegionMap.find(index); - if (i != mRegionMap.end()) - { - return i->second; - } - else - { - return 0; - } - - } - //-------------------------------------------------------------------------- - void StaticGeometry::getRegionIndexes(const Vector3& point, - ushort& x, ushort& y, ushort& z) - { - // Scale the point into multiples of region and adjust for origin - Vector3 scaledPoint = (point - mOrigin) / mRegionDimensions; - - // Round down to 'bottom left' point which represents the cell index - int ix = Math::IFloor(scaledPoint.x); - int iy = Math::IFloor(scaledPoint.y); - int iz = Math::IFloor(scaledPoint.z); - - // Check bounds - if (ix < REGION_MIN_INDEX || ix > REGION_MAX_INDEX - || iy < REGION_MIN_INDEX || iy > REGION_MAX_INDEX - || iz < REGION_MIN_INDEX || iz > REGION_MAX_INDEX) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Point out of bounds", - "StaticGeometry::getRegionIndexes"); - } - // Adjust for the fact that we use unsigned values for simplicity - // (requires less faffing about for negatives give 10-bit packing - x = static_cast(ix + REGION_HALF_RANGE); - y = static_cast(iy + REGION_HALF_RANGE); - z = static_cast(iz + REGION_HALF_RANGE); - - - } - //-------------------------------------------------------------------------- - uint32 StaticGeometry::packIndex(ushort x, ushort y, ushort z) - { - return x + (y << 10) + (z << 20); - } - //-------------------------------------------------------------------------- - StaticGeometry::Region* StaticGeometry::getRegion(const Vector3& point, - bool autoCreate) - { - ushort x, y, z; - getRegionIndexes(point, x, y, z); - return getRegion(x, y, z, autoCreate); - } - //-------------------------------------------------------------------------- - AxisAlignedBox StaticGeometry::calculateBounds(VertexData* vertexData, - const Vector3& position, const Quaternion& orientation, - const Vector3& scale) - { - const VertexElement* posElem = - vertexData->vertexDeclaration->findElementBySemantic( - VES_POSITION); - HardwareVertexBufferSharedPtr vbuf = - vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); - unsigned char* vertex = - static_cast( - vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); - float* pFloat; - - Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE; - bool first = true; - - for(size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) - { - posElem->baseVertexPointerToElement(vertex, &pFloat); - - Vector3 pt; - - pt.x = (*pFloat++); - pt.y = (*pFloat++); - pt.z = (*pFloat++); - // Transform to world (scale, rotate, translate) - pt = (orientation * (pt * scale)) + position; - if (first) - { - min = max = pt; - first = false; - } - else - { - min.makeFloor(pt); - max.makeCeil(pt); - } - - } - vbuf->unlock(); - return AxisAlignedBox(min, max); - } - //-------------------------------------------------------------------------- - void StaticGeometry::addEntity(Entity* ent, const Vector3& position, - const Quaternion& orientation, const Vector3& scale) - { - const MeshPtr& msh = ent->getMesh(); - // Validate - if (msh->hasManualLodLevel()) - { - LogManager::getSingleton().logMessage( - "WARNING (StaticGeometry): Manual LOD is not supported. " - "Using only highest LOD level for mesh " + msh->getName(), LML_CRITICAL); - } - - AxisAlignedBox sharedWorldBounds; - // queue this entities submeshes and choice of material - // also build the lists of geometry to be used for the source of lods - for (uint i = 0; i < ent->getNumSubEntities(); ++i) - { - SubEntity* se = ent->getSubEntity(i); - QueuedSubMesh* q = OGRE_NEW QueuedSubMesh(); - - // Get the geometry for this SubMesh - q->submesh = se->getSubMesh(); - q->geometryLodList = determineGeometry(q->submesh); - q->materialName = se->getMaterialName(); - q->orientation = orientation; - q->position = position; - q->scale = scale; - // Determine the bounds based on the highest LOD - q->worldBounds = calculateBounds( - (*q->geometryLodList)[0].vertexData, - position, orientation, scale); - - mQueuedSubMeshes.push_back(q); - } - } - //-------------------------------------------------------------------------- - StaticGeometry::SubMeshLodGeometryLinkList* - StaticGeometry::determineGeometry(SubMesh* sm) - { - // First, determine if we've already seen this submesh before - SubMeshGeometryLookup::iterator i = - mSubMeshGeometryLookup.find(sm); - if (i != mSubMeshGeometryLookup.end()) - { - return i->second; - } - // Otherwise, we have to create a new one - SubMeshLodGeometryLinkList* lodList = OGRE_NEW_T(SubMeshLodGeometryLinkList, MEMCATEGORY_GEOMETRY)(); - mSubMeshGeometryLookup[sm] = lodList; - ushort numLods = sm->parent->hasManualLodLevel() ? 1 : - sm->parent->getNumLodLevels(); - lodList->resize(numLods); - for (ushort lod = 0; lod < numLods; ++lod) - { - SubMeshLodGeometryLink& geomLink = (*lodList)[lod]; - IndexData *lodIndexData; - if (lod == 0) - { - lodIndexData = sm->indexData; - } - else - { - lodIndexData = sm->mLodFaceList[lod - 1]; - } - // Can use the original mesh geometry? - if (sm->useSharedVertices) - { - if (sm->parent->getNumSubMeshes() == 1) - { - // Ok, this is actually our own anyway - geomLink.vertexData = sm->parent->sharedVertexData; - geomLink.indexData = lodIndexData; - } - else - { - // We have to split it - splitGeometry(sm->parent->sharedVertexData, - lodIndexData, &geomLink); - } - } - else - { - if (lod == 0) - { - // Ok, we can use the existing geometry; should be in full - // use by just this SubMesh - geomLink.vertexData = sm->vertexData; - geomLink.indexData = sm->indexData; - } - else - { - // We have to split it - splitGeometry(sm->vertexData, - lodIndexData, &geomLink); - } - } - assert (geomLink.vertexData->vertexStart == 0 && - "Cannot use vertexStart > 0 on indexed geometry due to " - "rendersystem incompatibilities - see the docs!"); - } - - - return lodList; - } - //-------------------------------------------------------------------------- - void StaticGeometry::splitGeometry(VertexData* vd, IndexData* id, - StaticGeometry::SubMeshLodGeometryLink* targetGeomLink) - { - // Firstly we need to scan to see how many vertices are being used - // and while we're at it, build the remap we can use later - bool use32bitIndexes = - id->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT; - IndexRemap indexRemap; - if (use32bitIndexes) - { - uint32 *p32 = static_cast(id->indexBuffer->lock( - id->indexStart, - id->indexCount * id->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - buildIndexRemap(p32, id->indexCount, indexRemap); - id->indexBuffer->unlock(); - } - else - { - uint16 *p16 = static_cast(id->indexBuffer->lock( - id->indexStart, - id->indexCount * id->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - buildIndexRemap(p16, id->indexCount, indexRemap); - id->indexBuffer->unlock(); - } - if (indexRemap.size() == vd->vertexCount) - { - // ha, complete usage after all - targetGeomLink->vertexData = vd; - targetGeomLink->indexData = id; - return; - } - - - // Create the new vertex data records - targetGeomLink->vertexData = vd->clone(false); - // Convenience - VertexData* newvd = targetGeomLink->vertexData; - //IndexData* newid = targetGeomLink->indexData; - // Update the vertex count - newvd->vertexCount = indexRemap.size(); - - size_t numvbufs = vd->vertexBufferBinding->getBufferCount(); - // Copy buffers from old to new - for (unsigned short b = 0; b < numvbufs; ++b) - { - // Lock old buffer - HardwareVertexBufferSharedPtr oldBuf = - vd->vertexBufferBinding->getBuffer(b); - // Create new buffer - HardwareVertexBufferSharedPtr newBuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - oldBuf->getVertexSize(), - indexRemap.size(), - HardwareBuffer::HBU_STATIC); - // rebind - newvd->vertexBufferBinding->setBinding(b, newBuf); - - // Copy all the elements of the buffer across, by iterating over - // the IndexRemap which describes how to move the old vertices - // to the new ones. By nature of the map the remap is in order of - // indexes in the old buffer, but note that we're not guaranteed to - // address every vertex (which is kinda why we're here) - uchar* pSrcBase = static_cast( - oldBuf->lock(HardwareBuffer::HBL_READ_ONLY)); - uchar* pDstBase = static_cast( - newBuf->lock(HardwareBuffer::HBL_DISCARD)); - size_t vertexSize = oldBuf->getVertexSize(); - // Buffers should be the same size - assert (vertexSize == newBuf->getVertexSize()); - - for (IndexRemap::iterator r = indexRemap.begin(); - r != indexRemap.end(); ++r) - { - assert (r->first < oldBuf->getNumVertices()); - assert (r->second < newBuf->getNumVertices()); - - uchar* pSrc = pSrcBase + r->first * vertexSize; - uchar* pDst = pDstBase + r->second * vertexSize; - memcpy(pDst, pSrc, vertexSize); - } - // unlock - oldBuf->unlock(); - newBuf->unlock(); - - } - - // Now create a new index buffer - HardwareIndexBufferSharedPtr ibuf = - HardwareBufferManager::getSingleton().createIndexBuffer( - id->indexBuffer->getType(), id->indexCount, - HardwareBuffer::HBU_STATIC); - - if (use32bitIndexes) - { - uint32 *pSrc32, *pDst32; - pSrc32 = static_cast(id->indexBuffer->lock( - id->indexStart, - id->indexCount * id->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - pDst32 = static_cast(ibuf->lock( - HardwareBuffer::HBL_DISCARD)); - remapIndexes(pSrc32, pDst32, indexRemap, id->indexCount); - id->indexBuffer->unlock(); - ibuf->unlock(); - } - else - { - uint16 *pSrc16, *pDst16; - pSrc16 = static_cast(id->indexBuffer->lock( - id->indexStart, - id->indexCount * id->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - pDst16 = static_cast(ibuf->lock( - HardwareBuffer::HBL_DISCARD)); - remapIndexes(pSrc16, pDst16, indexRemap, id->indexCount); - id->indexBuffer->unlock(); - ibuf->unlock(); - } - - targetGeomLink->indexData = OGRE_NEW IndexData(); - targetGeomLink->indexData->indexStart = 0; - targetGeomLink->indexData->indexCount = id->indexCount; - targetGeomLink->indexData->indexBuffer = ibuf; - - // Store optimised geometry for deallocation later - OptimisedSubMeshGeometry *optGeom = OGRE_NEW OptimisedSubMeshGeometry(); - optGeom->indexData = targetGeomLink->indexData; - optGeom->vertexData = targetGeomLink->vertexData; - mOptimisedSubMeshGeometryList.push_back(optGeom); - } - //-------------------------------------------------------------------------- - void StaticGeometry::addSceneNode(const SceneNode* node) - { - SceneNode::ConstObjectIterator obji = node->getAttachedObjectIterator(); - while (obji.hasMoreElements()) - { - MovableObject* mobj = obji.getNext(); - if (mobj->getMovableType() == "Entity") - { - addEntity(static_cast(mobj), - node->_getDerivedPosition(), - node->_getDerivedOrientation(), - node->_getDerivedScale()); - } - } - // Iterate through all the child-nodes - SceneNode::ConstChildNodeIterator nodei = node->getChildIterator(); - - while (nodei.hasMoreElements()) - { - const SceneNode* subNode = static_cast(nodei.getNext()); - // Add this subnode and its children... - addSceneNode( subNode ); - } - } - //-------------------------------------------------------------------------- - void StaticGeometry::build(void) - { - // Make sure there's nothing from previous builds - destroy(); - - // Firstly allocate meshes to regions - for (QueuedSubMeshList::iterator qi = mQueuedSubMeshes.begin(); - qi != mQueuedSubMeshes.end(); ++qi) - { - QueuedSubMesh* qsm = *qi; - Region* region = getRegion(qsm->worldBounds, true); - region->assign(qsm); - } - bool stencilShadows = false; - if (mCastShadows && mOwner->isShadowTechniqueStencilBased()) - { - stencilShadows = true; - } - - // Now tell each region to build itself - for (RegionMap::iterator ri = mRegionMap.begin(); - ri != mRegionMap.end(); ++ri) - { - ri->second->build(stencilShadows); - - // Set the visibility flags on these regions - ri->second->setVisibilityFlags(mVisibilityFlags); - } - - } - //-------------------------------------------------------------------------- - void StaticGeometry::destroy(void) - { - // delete the regions - for (RegionMap::iterator i = mRegionMap.begin(); - i != mRegionMap.end(); ++i) - { - mOwner->extractMovableObject(i->second); - OGRE_DELETE i->second; - } - mRegionMap.clear(); - } - //-------------------------------------------------------------------------- - void StaticGeometry::reset(void) - { - destroy(); - for (QueuedSubMeshList::iterator i = mQueuedSubMeshes.begin(); - i != mQueuedSubMeshes.end(); ++i) - { - OGRE_DELETE *i; - } - mQueuedSubMeshes.clear(); - // Delete precached geoemtry lists - for (SubMeshGeometryLookup::iterator l = mSubMeshGeometryLookup.begin(); - l != mSubMeshGeometryLookup.end(); ++l) - { - OGRE_DELETE_T(l->second, SubMeshLodGeometryLinkList, MEMCATEGORY_GEOMETRY); - } - mSubMeshGeometryLookup.clear(); - // Delete optimised geometry - for (OptimisedSubMeshGeometryList::iterator o = mOptimisedSubMeshGeometryList.begin(); - o != mOptimisedSubMeshGeometryList.end(); ++o) - { - OGRE_DELETE *o; - } - mOptimisedSubMeshGeometryList.clear(); - - } - //-------------------------------------------------------------------------- - void StaticGeometry::setVisible(bool visible) - { - mVisible = visible; - // tell any existing regions - for (RegionMap::iterator ri = mRegionMap.begin(); - ri != mRegionMap.end(); ++ri) - { - ri->second->setVisible(visible); - } - } - //-------------------------------------------------------------------------- - void StaticGeometry::setCastShadows(bool castShadows) - { - mCastShadows = castShadows; - // tell any existing regions - for (RegionMap::iterator ri = mRegionMap.begin(); - ri != mRegionMap.end(); ++ri) - { - ri->second->setCastShadows(castShadows); - } - - } - //-------------------------------------------------------------------------- + mVisibilityFlags(Ogre::MovableObject::getDefaultVisibilityFlags()) + { + } + //-------------------------------------------------------------------------- + StaticGeometry::~StaticGeometry() + { + reset(); + } + //-------------------------------------------------------------------------- + StaticGeometry::Region* StaticGeometry::getRegion(const AxisAlignedBox& bounds, + bool autoCreate) + { + if (bounds.isNull()) + return 0; + + // Get the region which has the largest overlapping volume + const Vector3 min = bounds.getMinimum(); + const Vector3 max = bounds.getMaximum(); + + // Get the min and max region indexes + ushort minx, miny, minz; + ushort maxx, maxy, maxz; + getRegionIndexes(min, minx, miny, minz); + getRegionIndexes(max, maxx, maxy, maxz); + Real maxVolume = 0.0f; + ushort finalx = 0, finaly = 0, finalz = 0; + for (ushort x = minx; x <= maxx; ++x) + { + for (ushort y = miny; y <= maxy; ++y) + { + for (ushort z = minz; z <= maxz; ++z) + { + Real vol = getVolumeIntersection(bounds, x, y, z); + if (vol > maxVolume) + { + maxVolume = vol; + finalx = x; + finaly = y; + finalz = z; + } + + } + } + } + + assert(maxVolume > 0.0f && + "Static geometry: Problem determining closest volume match!"); + + return getRegion(finalx, finaly, finalz, autoCreate); + + } + //-------------------------------------------------------------------------- + Real StaticGeometry::getVolumeIntersection(const AxisAlignedBox& box, + ushort x, ushort y, ushort z) + { + // Get bounds of indexed region + AxisAlignedBox regionBounds = getRegionBounds(x, y, z); + AxisAlignedBox intersectBox = regionBounds.intersection(box); + // return a 'volume' which ignores zero dimensions + // since we only use this for relative comparisons of the same bounds + // this will still be internally consistent + Vector3 boxdiff = box.getMaximum() - box.getMinimum(); + Vector3 intersectDiff = intersectBox.getMaximum() - intersectBox.getMinimum(); + + return (boxdiff.x == 0 ? 1 : intersectDiff.x) * + (boxdiff.y == 0 ? 1 : intersectDiff.y) * + (boxdiff.z == 0 ? 1 : intersectDiff.z); + + } + //-------------------------------------------------------------------------- + AxisAlignedBox StaticGeometry::getRegionBounds(ushort x, ushort y, ushort z) + { + Vector3 min( + ((Real)x - REGION_HALF_RANGE) * mRegionDimensions.x + mOrigin.x, + ((Real)y - REGION_HALF_RANGE) * mRegionDimensions.y + mOrigin.y, + ((Real)z - REGION_HALF_RANGE) * mRegionDimensions.z + mOrigin.z + ); + Vector3 max = min + mRegionDimensions; + return AxisAlignedBox(min, max); + } + //-------------------------------------------------------------------------- + Vector3 StaticGeometry::getRegionCentre(ushort x, ushort y, ushort z) + { + return Vector3( + ((Real)x - REGION_HALF_RANGE) * mRegionDimensions.x + mOrigin.x + + mHalfRegionDimensions.x, + ((Real)y - REGION_HALF_RANGE) * mRegionDimensions.y + mOrigin.y + + mHalfRegionDimensions.y, + ((Real)z - REGION_HALF_RANGE) * mRegionDimensions.z + mOrigin.z + + mHalfRegionDimensions.z + ); + } + //-------------------------------------------------------------------------- + StaticGeometry::Region* StaticGeometry::getRegion( + ushort x, ushort y, ushort z, bool autoCreate) + { + uint32 index = packIndex(x, y, z); + Region* ret = getRegion(index); + if (!ret && autoCreate) + { + // Make a name + StringStream str; + str << mName << ":" << index; + // Calculate the region centre + Vector3 centre = getRegionCentre(x, y, z); + ret = OGRE_NEW Region(this, str.str(), mOwner, index, centre); + mOwner->injectMovableObject(ret); + ret->setVisible(mVisible); + ret->setCastShadows(mCastShadows); + if (mRenderQueueIDSet) + { + ret->setRenderQueueGroup(mRenderQueueID); + } + mRegionMap[index] = ret; + } + return ret; + } + //-------------------------------------------------------------------------- + StaticGeometry::Region* StaticGeometry::getRegion(uint32 index) + { + RegionMap::iterator i = mRegionMap.find(index); + if (i != mRegionMap.end()) + { + return i->second; + } + else + { + return 0; + } + + } + //-------------------------------------------------------------------------- + void StaticGeometry::getRegionIndexes(const Vector3& point, + ushort& x, ushort& y, ushort& z) + { + // Scale the point into multiples of region and adjust for origin + Vector3 scaledPoint = (point - mOrigin) / mRegionDimensions; + + // Round down to 'bottom left' point which represents the cell index + int ix = Math::IFloor(scaledPoint.x); + int iy = Math::IFloor(scaledPoint.y); + int iz = Math::IFloor(scaledPoint.z); + + // Check bounds + if (ix < REGION_MIN_INDEX || ix > REGION_MAX_INDEX + || iy < REGION_MIN_INDEX || iy > REGION_MAX_INDEX + || iz < REGION_MIN_INDEX || iz > REGION_MAX_INDEX) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Point out of bounds", + "StaticGeometry::getRegionIndexes"); + } + // Adjust for the fact that we use unsigned values for simplicity + // (requires less faffing about for negatives give 10-bit packing + x = static_cast(ix + REGION_HALF_RANGE); + y = static_cast(iy + REGION_HALF_RANGE); + z = static_cast(iz + REGION_HALF_RANGE); + + + } + //-------------------------------------------------------------------------- + uint32 StaticGeometry::packIndex(ushort x, ushort y, ushort z) + { + return x + (y << 10) + (z << 20); + } + //-------------------------------------------------------------------------- + StaticGeometry::Region* StaticGeometry::getRegion(const Vector3& point, + bool autoCreate) + { + ushort x, y, z; + getRegionIndexes(point, x, y, z); + return getRegion(x, y, z, autoCreate); + } + //-------------------------------------------------------------------------- + AxisAlignedBox StaticGeometry::calculateBounds(VertexData* vertexData, + const Vector3& position, const Quaternion& orientation, + const Vector3& scale) + { + const VertexElement* posElem = + vertexData->vertexDeclaration->findElementBySemantic( + VES_POSITION); + HardwareVertexBufferSharedPtr vbuf = + vertexData->vertexBufferBinding->getBuffer(posElem->getSource()); + unsigned char* vertex = + static_cast( + vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + float* pFloat; + + Vector3 min = Vector3::ZERO, max = Vector3::UNIT_SCALE; + bool first = true; + + for(size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vbuf->getVertexSize()) + { + posElem->baseVertexPointerToElement(vertex, &pFloat); + + Vector3 pt; + + pt.x = (*pFloat++); + pt.y = (*pFloat++); + pt.z = (*pFloat++); + // Transform to world (scale, rotate, translate) + pt = (orientation * (pt * scale)) + position; + if (first) + { + min = max = pt; + first = false; + } + else + { + min.makeFloor(pt); + max.makeCeil(pt); + } + + } + vbuf->unlock(); + return AxisAlignedBox(min, max); + } + //-------------------------------------------------------------------------- + void StaticGeometry::addEntity(Entity* ent, const Vector3& position, + const Quaternion& orientation, const Vector3& scale) + { + const MeshPtr& msh = ent->getMesh(); + // Validate + if (msh->hasManualLodLevel()) + { + LogManager::getSingleton().logMessage( + "WARNING (StaticGeometry): Manual LOD is not supported. " + "Using only highest LOD level for mesh " + msh->getName(), LML_CRITICAL); + } + + AxisAlignedBox sharedWorldBounds; + // queue this entities submeshes and choice of material + // also build the lists of geometry to be used for the source of lods + for (uint i = 0; i < ent->getNumSubEntities(); ++i) + { + SubEntity* se = ent->getSubEntity(i); + QueuedSubMesh* q = OGRE_NEW QueuedSubMesh(); + + // Get the geometry for this SubMesh + q->submesh = se->getSubMesh(); + q->geometryLodList = determineGeometry(q->submesh); + q->materialName = se->getMaterialName(); + q->orientation = orientation; + q->position = position; + q->scale = scale; + // Determine the bounds based on the highest LOD + q->worldBounds = calculateBounds( + (*q->geometryLodList)[0].vertexData, + position, orientation, scale); + + mQueuedSubMeshes.push_back(q); + } + } + //-------------------------------------------------------------------------- + StaticGeometry::SubMeshLodGeometryLinkList* + StaticGeometry::determineGeometry(SubMesh* sm) + { + // First, determine if we've already seen this submesh before + SubMeshGeometryLookup::iterator i = + mSubMeshGeometryLookup.find(sm); + if (i != mSubMeshGeometryLookup.end()) + { + return i->second; + } + // Otherwise, we have to create a new one + SubMeshLodGeometryLinkList* lodList = OGRE_NEW_T(SubMeshLodGeometryLinkList, MEMCATEGORY_GEOMETRY)(); + mSubMeshGeometryLookup[sm] = lodList; + ushort numLods = sm->parent->hasManualLodLevel() ? 1 : + sm->parent->getNumLodLevels(); + lodList->resize(numLods); + for (ushort lod = 0; lod < numLods; ++lod) + { + SubMeshLodGeometryLink& geomLink = (*lodList)[lod]; + IndexData *lodIndexData; + if (lod == 0) + { + lodIndexData = sm->indexData; + } + else + { + lodIndexData = sm->mLodFaceList[lod - 1]; + } + // Can use the original mesh geometry? + if (sm->useSharedVertices) + { + if (sm->parent->getNumSubMeshes() == 1) + { + // Ok, this is actually our own anyway + geomLink.vertexData = sm->parent->sharedVertexData; + geomLink.indexData = lodIndexData; + } + else + { + // We have to split it + splitGeometry(sm->parent->sharedVertexData, + lodIndexData, &geomLink); + } + } + else + { + if (lod == 0) + { + // Ok, we can use the existing geometry; should be in full + // use by just this SubMesh + geomLink.vertexData = sm->vertexData; + geomLink.indexData = sm->indexData; + } + else + { + // We have to split it + splitGeometry(sm->vertexData, + lodIndexData, &geomLink); + } + } + assert (geomLink.vertexData->vertexStart == 0 && + "Cannot use vertexStart > 0 on indexed geometry due to " + "rendersystem incompatibilities - see the docs!"); + } + + + return lodList; + } + //-------------------------------------------------------------------------- + void StaticGeometry::splitGeometry(VertexData* vd, IndexData* id, + StaticGeometry::SubMeshLodGeometryLink* targetGeomLink) + { + // Firstly we need to scan to see how many vertices are being used + // and while we're at it, build the remap we can use later + bool use32bitIndexes = + id->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT; + IndexRemap indexRemap; + if (use32bitIndexes) + { + uint32 *p32 = static_cast(id->indexBuffer->lock( + id->indexStart, + id->indexCount * id->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + buildIndexRemap(p32, id->indexCount, indexRemap); + id->indexBuffer->unlock(); + } + else + { + uint16 *p16 = static_cast(id->indexBuffer->lock( + id->indexStart, + id->indexCount * id->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + buildIndexRemap(p16, id->indexCount, indexRemap); + id->indexBuffer->unlock(); + } + if (indexRemap.size() == vd->vertexCount) + { + // ha, complete usage after all + targetGeomLink->vertexData = vd; + targetGeomLink->indexData = id; + return; + } + + + // Create the new vertex data records + targetGeomLink->vertexData = vd->clone(false); + // Convenience + VertexData* newvd = targetGeomLink->vertexData; + //IndexData* newid = targetGeomLink->indexData; + // Update the vertex count + newvd->vertexCount = indexRemap.size(); + + size_t numvbufs = vd->vertexBufferBinding->getBufferCount(); + // Copy buffers from old to new + for (unsigned short b = 0; b < numvbufs; ++b) + { + // Lock old buffer + HardwareVertexBufferSharedPtr oldBuf = + vd->vertexBufferBinding->getBuffer(b); + // Create new buffer + HardwareVertexBufferSharedPtr newBuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + oldBuf->getVertexSize(), + indexRemap.size(), + HardwareBuffer::HBU_STATIC); + // rebind + newvd->vertexBufferBinding->setBinding(b, newBuf); + + // Copy all the elements of the buffer across, by iterating over + // the IndexRemap which describes how to move the old vertices + // to the new ones. By nature of the map the remap is in order of + // indexes in the old buffer, but note that we're not guaranteed to + // address every vertex (which is kinda why we're here) + uchar* pSrcBase = static_cast( + oldBuf->lock(HardwareBuffer::HBL_READ_ONLY)); + uchar* pDstBase = static_cast( + newBuf->lock(HardwareBuffer::HBL_DISCARD)); + size_t vertexSize = oldBuf->getVertexSize(); + // Buffers should be the same size + assert (vertexSize == newBuf->getVertexSize()); + + for (IndexRemap::iterator r = indexRemap.begin(); + r != indexRemap.end(); ++r) + { + assert (r->first < oldBuf->getNumVertices()); + assert (r->second < newBuf->getNumVertices()); + + uchar* pSrc = pSrcBase + r->first * vertexSize; + uchar* pDst = pDstBase + r->second * vertexSize; + memcpy(pDst, pSrc, vertexSize); + } + // unlock + oldBuf->unlock(); + newBuf->unlock(); + + } + + // Now create a new index buffer + HardwareIndexBufferSharedPtr ibuf = + HardwareBufferManager::getSingleton().createIndexBuffer( + id->indexBuffer->getType(), id->indexCount, + HardwareBuffer::HBU_STATIC); + + if (use32bitIndexes) + { + uint32 *pSrc32, *pDst32; + pSrc32 = static_cast(id->indexBuffer->lock( + id->indexStart, + id->indexCount * id->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + pDst32 = static_cast(ibuf->lock( + HardwareBuffer::HBL_DISCARD)); + remapIndexes(pSrc32, pDst32, indexRemap, id->indexCount); + id->indexBuffer->unlock(); + ibuf->unlock(); + } + else + { + uint16 *pSrc16, *pDst16; + pSrc16 = static_cast(id->indexBuffer->lock( + id->indexStart, + id->indexCount * id->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + pDst16 = static_cast(ibuf->lock( + HardwareBuffer::HBL_DISCARD)); + remapIndexes(pSrc16, pDst16, indexRemap, id->indexCount); + id->indexBuffer->unlock(); + ibuf->unlock(); + } + + targetGeomLink->indexData = OGRE_NEW IndexData(); + targetGeomLink->indexData->indexStart = 0; + targetGeomLink->indexData->indexCount = id->indexCount; + targetGeomLink->indexData->indexBuffer = ibuf; + + // Store optimised geometry for deallocation later + OptimisedSubMeshGeometry *optGeom = OGRE_NEW OptimisedSubMeshGeometry(); + optGeom->indexData = targetGeomLink->indexData; + optGeom->vertexData = targetGeomLink->vertexData; + mOptimisedSubMeshGeometryList.push_back(optGeom); + } + //-------------------------------------------------------------------------- + void StaticGeometry::addSceneNode(const SceneNode* node) + { + SceneNode::ConstObjectIterator obji = node->getAttachedObjectIterator(); + while (obji.hasMoreElements()) + { + MovableObject* mobj = obji.getNext(); + if (mobj->getMovableType() == "Entity") + { + addEntity(static_cast(mobj), + node->_getDerivedPosition(), + node->_getDerivedOrientation(), + node->_getDerivedScale()); + } + } + // Iterate through all the child-nodes + SceneNode::ConstChildNodeIterator nodei = node->getChildIterator(); + + while (nodei.hasMoreElements()) + { + const SceneNode* subNode = static_cast(nodei.getNext()); + // Add this subnode and its children... + addSceneNode( subNode ); + } + } + //-------------------------------------------------------------------------- + void StaticGeometry::build(void) + { + // Make sure there's nothing from previous builds + destroy(); + + // Firstly allocate meshes to regions + for (QueuedSubMeshList::iterator qi = mQueuedSubMeshes.begin(); + qi != mQueuedSubMeshes.end(); ++qi) + { + QueuedSubMesh* qsm = *qi; + Region* region = getRegion(qsm->worldBounds, true); + region->assign(qsm); + } + bool stencilShadows = false; + if (mCastShadows && mOwner->isShadowTechniqueStencilBased()) + { + stencilShadows = true; + } + + // Now tell each region to build itself + for (RegionMap::iterator ri = mRegionMap.begin(); + ri != mRegionMap.end(); ++ri) + { + ri->second->build(stencilShadows); + + // Set the visibility flags on these regions + ri->second->setVisibilityFlags(mVisibilityFlags); + } + + } + //-------------------------------------------------------------------------- + void StaticGeometry::destroy(void) + { + // delete the regions + for (RegionMap::iterator i = mRegionMap.begin(); + i != mRegionMap.end(); ++i) + { + mOwner->extractMovableObject(i->second); + OGRE_DELETE i->second; + } + mRegionMap.clear(); + } + //-------------------------------------------------------------------------- + void StaticGeometry::reset(void) + { + destroy(); + for (QueuedSubMeshList::iterator i = mQueuedSubMeshes.begin(); + i != mQueuedSubMeshes.end(); ++i) + { + OGRE_DELETE *i; + } + mQueuedSubMeshes.clear(); + // Delete precached geoemtry lists + for (SubMeshGeometryLookup::iterator l = mSubMeshGeometryLookup.begin(); + l != mSubMeshGeometryLookup.end(); ++l) + { + OGRE_DELETE_T(l->second, SubMeshLodGeometryLinkList, MEMCATEGORY_GEOMETRY); + } + mSubMeshGeometryLookup.clear(); + // Delete optimised geometry + for (OptimisedSubMeshGeometryList::iterator o = mOptimisedSubMeshGeometryList.begin(); + o != mOptimisedSubMeshGeometryList.end(); ++o) + { + OGRE_DELETE *o; + } + mOptimisedSubMeshGeometryList.clear(); + + } + //-------------------------------------------------------------------------- + void StaticGeometry::setVisible(bool visible) + { + mVisible = visible; + // tell any existing regions + for (RegionMap::iterator ri = mRegionMap.begin(); + ri != mRegionMap.end(); ++ri) + { + ri->second->setVisible(visible); + } + } + //-------------------------------------------------------------------------- + void StaticGeometry::setCastShadows(bool castShadows) + { + mCastShadows = castShadows; + // tell any existing regions + for (RegionMap::iterator ri = mRegionMap.begin(); + ri != mRegionMap.end(); ++ri) + { + ri->second->setCastShadows(castShadows); + } + + } + //-------------------------------------------------------------------------- void StaticGeometry::setRenderQueueGroup(uint8 queueID) - { - assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!"); - mRenderQueueIDSet = true; - mRenderQueueID = queueID; - // tell any existing regions - for (RegionMap::iterator ri = mRegionMap.begin(); - ri != mRegionMap.end(); ++ri) - { - ri->second->setRenderQueueGroup(queueID); - } - } - //-------------------------------------------------------------------------- - uint8 StaticGeometry::getRenderQueueGroup(void) const - { - return mRenderQueueID; - } - //-------------------------------------------------------------------------- - void StaticGeometry::setVisibilityFlags(uint32 flags) - { - mVisibilityFlags = flags; - for (RegionMap::const_iterator ri = mRegionMap.begin(); - ri != mRegionMap.end(); ++ri) - { - ri->second->setVisibilityFlags(flags); - } - } - //-------------------------------------------------------------------------- - uint32 StaticGeometry::getVisibilityFlags() const - { - if(mRegionMap.empty()) - return MovableObject::getDefaultVisibilityFlags(); - - RegionMap::const_iterator ri = mRegionMap.begin(); - return ri->second->getVisibilityFlags(); - } - //-------------------------------------------------------------------------- - void StaticGeometry::dump(const String& filename) const - { - std::ofstream of(filename.c_str()); - of << "Static Geometry Report for " << mName << std::endl; - of << "-------------------------------------------------" << std::endl; - of << "Number of queued submeshes: " << mQueuedSubMeshes.size() << std::endl; - of << "Number of regions: " << mRegionMap.size() << std::endl; - of << "Region dimensions: " << mRegionDimensions << std::endl; - of << "Origin: " << mOrigin << std::endl; - of << "Max distance: " << mUpperDistance << std::endl; - of << "Casts shadows?: " << mCastShadows << std::endl; - of << std::endl; - for (RegionMap::const_iterator ri = mRegionMap.begin(); - ri != mRegionMap.end(); ++ri) - { - ri->second->dump(of); - } - of << "-------------------------------------------------" << std::endl; - } - //--------------------------------------------------------------------- - void StaticGeometry::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - for (RegionMap::const_iterator ri = mRegionMap.begin(); - ri != mRegionMap.end(); ++ri) - { - ri->second->visitRenderables(visitor, debugRenderables); - } - - } - //-------------------------------------------------------------------------- - StaticGeometry::RegionIterator StaticGeometry::getRegionIterator(void) - { - return RegionIterator(mRegionMap.begin(), mRegionMap.end()); - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - StaticGeometry::Region::Region(StaticGeometry* parent, const String& name, - SceneManager* mgr, uint32 regionID, const Vector3& centre) - : MovableObject(name), mParent(parent), mSceneMgr(mgr), mNode(0), - mRegionID(regionID), mCentre(centre), mBoundingRadius(0.0f), - mCurrentLod(0), mLodStrategy(0), mCamera(0), mSquaredViewDepth(0) - { - } - //-------------------------------------------------------------------------- - StaticGeometry::Region::~Region() - { - if (mNode) - { - mNode->getParentSceneNode()->removeChild(mNode); - mSceneMgr->destroySceneNode(mNode->getName()); - mNode = 0; - } - // delete - for (LODBucketList::iterator i = mLodBucketList.begin(); - i != mLodBucketList.end(); ++i) - { - OGRE_DELETE *i; - } - mLodBucketList.clear(); - - // no need to delete queued meshes, these are managed in StaticGeometry - - } - //-------------------------------------------------------------------------- - uint32 StaticGeometry::Region::getTypeFlags(void) const - { - return SceneManager::STATICGEOMETRY_TYPE_MASK; - } - //-------------------------------------------------------------------------- - void StaticGeometry::Region::assign(QueuedSubMesh* qmesh) - { - mQueuedSubMeshes.push_back(qmesh); + { + assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!"); + mRenderQueueIDSet = true; + mRenderQueueID = queueID; + // tell any existing regions + for (RegionMap::iterator ri = mRegionMap.begin(); + ri != mRegionMap.end(); ++ri) + { + ri->second->setRenderQueueGroup(queueID); + } + } + //-------------------------------------------------------------------------- + uint8 StaticGeometry::getRenderQueueGroup(void) const + { + return mRenderQueueID; + } + //-------------------------------------------------------------------------- + void StaticGeometry::setVisibilityFlags(uint32 flags) + { + mVisibilityFlags = flags; + for (RegionMap::const_iterator ri = mRegionMap.begin(); + ri != mRegionMap.end(); ++ri) + { + ri->second->setVisibilityFlags(flags); + } + } + //-------------------------------------------------------------------------- + uint32 StaticGeometry::getVisibilityFlags() const + { + if(mRegionMap.empty()) + return MovableObject::getDefaultVisibilityFlags(); + + RegionMap::const_iterator ri = mRegionMap.begin(); + return ri->second->getVisibilityFlags(); + } + //-------------------------------------------------------------------------- + void StaticGeometry::dump(const String& filename) const + { + std::ofstream of(filename.c_str()); + of << "Static Geometry Report for " << mName << std::endl; + of << "-------------------------------------------------" << std::endl; + of << "Number of queued submeshes: " << mQueuedSubMeshes.size() << std::endl; + of << "Number of regions: " << mRegionMap.size() << std::endl; + of << "Region dimensions: " << mRegionDimensions << std::endl; + of << "Origin: " << mOrigin << std::endl; + of << "Max distance: " << mUpperDistance << std::endl; + of << "Casts shadows?: " << mCastShadows << std::endl; + of << std::endl; + for (RegionMap::const_iterator ri = mRegionMap.begin(); + ri != mRegionMap.end(); ++ri) + { + ri->second->dump(of); + } + of << "-------------------------------------------------" << std::endl; + } + //--------------------------------------------------------------------- + void StaticGeometry::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + for (RegionMap::const_iterator ri = mRegionMap.begin(); + ri != mRegionMap.end(); ++ri) + { + ri->second->visitRenderables(visitor, debugRenderables); + } + + } + //-------------------------------------------------------------------------- + StaticGeometry::RegionIterator StaticGeometry::getRegionIterator(void) + { + return RegionIterator(mRegionMap.begin(), mRegionMap.end()); + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + StaticGeometry::Region::Region(StaticGeometry* parent, const String& name, + SceneManager* mgr, uint32 regionID, const Vector3& centre) + : MovableObject(name), mParent(parent), mSceneMgr(mgr), mNode(0), + mRegionID(regionID), mCentre(centre), mBoundingRadius(0.0f), + mCurrentLod(0), mLodStrategy(0), mCamera(0), mSquaredViewDepth(0) + { + } + //-------------------------------------------------------------------------- + StaticGeometry::Region::~Region() + { + if (mNode) + { + mNode->getParentSceneNode()->removeChild(mNode); + mSceneMgr->destroySceneNode(mNode->getName()); + mNode = 0; + } + // delete + for (LODBucketList::iterator i = mLodBucketList.begin(); + i != mLodBucketList.end(); ++i) + { + OGRE_DELETE *i; + } + mLodBucketList.clear(); + + // no need to delete queued meshes, these are managed in StaticGeometry + + } + //-------------------------------------------------------------------------- + uint32 StaticGeometry::Region::getTypeFlags(void) const + { + return SceneManager::STATICGEOMETRY_TYPE_MASK; + } + //-------------------------------------------------------------------------- + void StaticGeometry::Region::assign(QueuedSubMesh* qmesh) + { + mQueuedSubMeshes.push_back(qmesh); // Set/check LOD strategy const LodStrategy *lodStrategy = qmesh->submesh->parent->getLodStrategy(); @@ -765,70 +765,70 @@ namespace Ogre { "StaticGeometry::Region::assign"); } - // update LOD values - ushort lodLevels = qmesh->submesh->parent->getNumLodLevels(); - assert(qmesh->geometryLodList->size() == lodLevels); - - while(mLodValues.size() < lodLevels) - { - mLodValues.push_back(0.0f); - } - // Make sure LOD levels are max of all at the requested level - for (ushort lod = 1; lod < lodLevels; ++lod) - { - const MeshLodUsage& meshLod = - qmesh->submesh->parent->getLodLevel(lod); - mLodValues[lod] = std::max(mLodValues[lod], - meshLod.value); - } - - // update bounds - // Transform world bounds relative to our centre - AxisAlignedBox localBounds( - qmesh->worldBounds.getMinimum() - mCentre, - qmesh->worldBounds.getMaximum() - mCentre); - mAABB.merge(localBounds); - mBoundingRadius = Math::boundingRadiusFromAABB(mAABB); - - } - //-------------------------------------------------------------------------- - void StaticGeometry::Region::build(bool stencilShadows) - { - // Create a node - mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(mName, - mCentre); - mNode->attachObject(this); - // We need to create enough LOD buckets to deal with the highest LOD - // we encountered in all the meshes queued - for (ushort lod = 0; lod < mLodValues.size(); ++lod) - { - LODBucket* lodBucket = - OGRE_NEW LODBucket(this, lod, mLodValues[lod]); - mLodBucketList.push_back(lodBucket); - // Now iterate over the meshes and assign to LODs - // LOD bucket will pick the right LOD to use - QueuedSubMeshList::iterator qi, qiend; - qiend = mQueuedSubMeshes.end(); - for (qi = mQueuedSubMeshes.begin(); qi != qiend; ++qi) - { - lodBucket->assign(*qi, lod); - } - // now build - lodBucket->build(stencilShadows); - } - - - - } - //-------------------------------------------------------------------------- - const String& StaticGeometry::Region::getMovableType(void) const - { - static String sType = "StaticGeometry"; - return sType; - } - //-------------------------------------------------------------------------- - void StaticGeometry::Region::_notifyCurrentCamera(Camera* cam) - { + // update LOD values + ushort lodLevels = qmesh->submesh->parent->getNumLodLevels(); + assert(qmesh->geometryLodList->size() == lodLevels); + + while(mLodValues.size() < lodLevels) + { + mLodValues.push_back(0.0f); + } + // Make sure LOD levels are max of all at the requested level + for (ushort lod = 1; lod < lodLevels; ++lod) + { + const MeshLodUsage& meshLod = + qmesh->submesh->parent->getLodLevel(lod); + mLodValues[lod] = std::max(mLodValues[lod], + meshLod.value); + } + + // update bounds + // Transform world bounds relative to our centre + AxisAlignedBox localBounds( + qmesh->worldBounds.getMinimum() - mCentre, + qmesh->worldBounds.getMaximum() - mCentre); + mAABB.merge(localBounds); + mBoundingRadius = Math::boundingRadiusFromAABB(mAABB); + + } + //-------------------------------------------------------------------------- + void StaticGeometry::Region::build(bool stencilShadows) + { + // Create a node + mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(mName, + mCentre); + mNode->attachObject(this); + // We need to create enough LOD buckets to deal with the highest LOD + // we encountered in all the meshes queued + for (ushort lod = 0; lod < mLodValues.size(); ++lod) + { + LODBucket* lodBucket = + OGRE_NEW LODBucket(this, lod, mLodValues[lod]); + mLodBucketList.push_back(lodBucket); + // Now iterate over the meshes and assign to LODs + // LOD bucket will pick the right LOD to use + QueuedSubMeshList::iterator qi, qiend; + qiend = mQueuedSubMeshes.end(); + for (qi = mQueuedSubMeshes.begin(); qi != qiend; ++qi) + { + lodBucket->assign(*qi, lod); + } + // now build + lodBucket->build(stencilShadows); + } + + + + } + //-------------------------------------------------------------------------- + const String& StaticGeometry::Region::getMovableType(void) const + { + static String sType = "StaticGeometry"; + return sType; + } + //-------------------------------------------------------------------------- + void StaticGeometry::Region::_notifyCurrentCamera(Camera* cam) + { // Set camera mCamera = cam; @@ -850,484 +850,484 @@ namespace Ogre { // Get LOD index mCurrentLod = mLodStrategy->getIndex(lodValue, mLodValues); - } - //-------------------------------------------------------------------------- - const AxisAlignedBox& StaticGeometry::Region::getBoundingBox(void) const - { - return mAABB; - } - //-------------------------------------------------------------------------- - Real StaticGeometry::Region::getBoundingRadius(void) const - { - return mBoundingRadius; - } - //-------------------------------------------------------------------------- - void StaticGeometry::Region::_updateRenderQueue(RenderQueue* queue) - { - mLodBucketList[mCurrentLod]->addRenderables(queue, mRenderQueueID, - mLodValue); - } - //--------------------------------------------------------------------- - void StaticGeometry::Region::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - for (LODBucketList::iterator i = mLodBucketList.begin(); i != mLodBucketList.end(); ++i) - { - (*i)->visitRenderables(visitor, debugRenderables); - } - - } - //-------------------------------------------------------------------------- - bool StaticGeometry::Region::isVisible(void) const - { - if(!mVisible || mBeyondFarDistance) - return false; - - SceneManager* sm = Root::getSingleton()._getCurrentSceneManager(); + } + //-------------------------------------------------------------------------- + const AxisAlignedBox& StaticGeometry::Region::getBoundingBox(void) const + { + return mAABB; + } + //-------------------------------------------------------------------------- + Real StaticGeometry::Region::getBoundingRadius(void) const + { + return mBoundingRadius; + } + //-------------------------------------------------------------------------- + void StaticGeometry::Region::_updateRenderQueue(RenderQueue* queue) + { + mLodBucketList[mCurrentLod]->addRenderables(queue, mRenderQueueID, + mLodValue); + } + //--------------------------------------------------------------------- + void StaticGeometry::Region::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + for (LODBucketList::iterator i = mLodBucketList.begin(); i != mLodBucketList.end(); ++i) + { + (*i)->visitRenderables(visitor, debugRenderables); + } + + } + //-------------------------------------------------------------------------- + bool StaticGeometry::Region::isVisible(void) const + { + if(!mVisible || mBeyondFarDistance) + return false; + + SceneManager* sm = Root::getSingleton()._getCurrentSceneManager(); if (sm && !(mVisibilityFlags & sm->_getCombinedVisibilityMask())) return false; return true; - } - //-------------------------------------------------------------------------- - StaticGeometry::Region::LODIterator - StaticGeometry::Region::getLODIterator(void) - { - return LODIterator(mLodBucketList.begin(), mLodBucketList.end()); - } - //--------------------------------------------------------------------- - ShadowCaster::ShadowRenderableListIterator - StaticGeometry::Region::getShadowVolumeRenderableIterator( - ShadowTechnique shadowTechnique, const Light* light, - HardwareIndexBufferSharedPtr* indexBuffer, size_t* indexBufferUsedSize, - bool extrude, Real extrusionDistance, unsigned long flags) - { - // Calculate the object space light details - Vector4 lightPos = light->getAs4DVector(); - Matrix4 world2Obj = mParentNode->_getFullTransform().inverseAffine(); - lightPos = world2Obj.transformAffine(lightPos); - Matrix3 world2Obj3x3; - world2Obj.extract3x3Matrix(world2Obj3x3); - extrusionDistance *= Math::Sqrt(std::min(std::min(world2Obj3x3.GetColumn(0).squaredLength(), world2Obj3x3.GetColumn(1).squaredLength()), world2Obj3x3.GetColumn(2).squaredLength())); - - // per-LOD shadow lists & edge data - mLodBucketList[mCurrentLod]->updateShadowRenderables( - shadowTechnique, lightPos, indexBuffer, extrude, extrusionDistance, flags); - - EdgeData* edgeList = mLodBucketList[mCurrentLod]->getEdgeList(); - ShadowRenderableList& shadowRendList = mLodBucketList[mCurrentLod]->getShadowRenderableList(); - - // Calc triangle light facing - updateEdgeListLightFacing(edgeList, lightPos); - - // Generate indexes and update renderables - generateShadowVolume(edgeList, *indexBuffer, *indexBufferUsedSize, - light, shadowRendList, flags); - - - return ShadowCaster::ShadowRenderableListIterator(shadowRendList.begin(), shadowRendList.end()); - - } - //-------------------------------------------------------------------------- - EdgeData* StaticGeometry::Region::getEdgeList(void) - { - return mLodBucketList[mCurrentLod]->getEdgeList(); - } - //-------------------------------------------------------------------------- - bool StaticGeometry::Region::hasEdgeList(void) - { - return getEdgeList() != 0; - } - //-------------------------------------------------------------------------- - void StaticGeometry::Region::dump(std::ofstream& of) const - { - of << "Region " << mRegionID << std::endl; - of << "--------------------------" << std::endl; - of << "Centre: " << mCentre << std::endl; - of << "Local AABB: " << mAABB << std::endl; - of << "Bounding radius: " << mBoundingRadius << std::endl; - of << "Number of LODs: " << mLodBucketList.size() << std::endl; - - for (LODBucketList::const_iterator i = mLodBucketList.begin(); - i != mLodBucketList.end(); ++i) - { - (*i)->dump(of); - } - of << "--------------------------" << std::endl; - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - StaticGeometry::LODBucket::LODShadowRenderable::LODShadowRenderable( - LODBucket* parent, HardwareIndexBufferSharedPtr* indexBuffer, - const VertexData* vertexData, bool createSeparateLightCap, - bool isLightCap) - : mParent(parent) - { - // Initialise render op - mRenderOp.indexData = OGRE_NEW IndexData(); - mRenderOp.indexData->indexBuffer = *indexBuffer; - mRenderOp.indexData->indexStart = 0; - // index start and count are sorted out later - - // Create vertex data which just references position component (and 2 component) - mRenderOp.vertexData = OGRE_NEW VertexData(); - // Map in position data - mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT3, VES_POSITION); - ushort origPosBind = - vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource(); - mPositionBuffer = vertexData->vertexBufferBinding->getBuffer(origPosBind); - mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mPositionBuffer); - // Map in w-coord buffer (if present) - if(!vertexData->hardwareShadowVolWBuffer.isNull()) - { - mRenderOp.vertexData->vertexDeclaration->addElement(1,0,VET_FLOAT1, VES_TEXTURE_COORDINATES, 0); - mWBuffer = vertexData->hardwareShadowVolWBuffer; - mRenderOp.vertexData->vertexBufferBinding->setBinding(1, mWBuffer); - } - // Use same vertex start as input - mRenderOp.vertexData->vertexStart = vertexData->vertexStart; - - if (isLightCap) - { - // Use original vertex count, no extrusion - mRenderOp.vertexData->vertexCount = vertexData->vertexCount; - } - else - { - // Vertex count must take into account the doubling of the buffer, - // because second half of the buffer is the extruded copy - mRenderOp.vertexData->vertexCount = - vertexData->vertexCount * 2; - if (createSeparateLightCap) - { - // Create child light cap - mLightCap = OGRE_NEW LODShadowRenderable(parent, - indexBuffer, vertexData, false, true); - } - } - } - //-------------------------------------------------------------------------- - StaticGeometry::LODBucket::LODShadowRenderable::~LODShadowRenderable() - { - OGRE_DELETE mRenderOp.indexData; - OGRE_DELETE mRenderOp.vertexData; - } - //-------------------------------------------------------------------------- - void StaticGeometry::LODBucket::LODShadowRenderable::getWorldTransforms( - Matrix4* xform) const - { - // pretransformed - *xform = mParent->getParent()->_getParentNodeFullTransform(); - } - //----------------------------------------------------------------------- - void StaticGeometry::LODBucket::LODShadowRenderable::rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer) - { - mRenderOp.indexData->indexBuffer = indexBuffer; - if (mLightCap) mLightCap->rebindIndexBuffer(indexBuffer); - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - StaticGeometry::LODBucket::LODBucket(Region* parent, unsigned short lod, - Real lodValue) - : mParent(parent), mLod(lod), mLodValue(lodValue), mEdgeList(0) - , mVertexProgramInUse(false) - { - } - //-------------------------------------------------------------------------- - StaticGeometry::LODBucket::~LODBucket() - { - OGRE_DELETE mEdgeList; - for (ShadowCaster::ShadowRenderableList::iterator s = mShadowRenderables.begin(); - s != mShadowRenderables.end(); ++s) - { - OGRE_DELETE *s; - } - mShadowRenderables.clear(); - // delete - for (MaterialBucketMap::iterator i = mMaterialBucketMap.begin(); - i != mMaterialBucketMap.end(); ++i) - { - OGRE_DELETE i->second; - } - mMaterialBucketMap.clear(); - for(QueuedGeometryList::iterator qi = mQueuedGeometryList.begin(); - qi != mQueuedGeometryList.end(); ++qi) - { - OGRE_DELETE *qi; - } - mQueuedGeometryList.clear(); - - // no need to delete queued meshes, these are managed in StaticGeometry - } - //-------------------------------------------------------------------------- - void StaticGeometry::LODBucket::assign(QueuedSubMesh* qmesh, ushort atLod) - { - QueuedGeometry* q = OGRE_NEW QueuedGeometry(); - mQueuedGeometryList.push_back(q); - q->position = qmesh->position; - q->orientation = qmesh->orientation; - q->scale = qmesh->scale; - if (qmesh->geometryLodList->size() > atLod) - { - // This submesh has enough lods, use the right one - q->geometry = &(*qmesh->geometryLodList)[atLod]; - } - else - { - // Not enough lods, use the lowest one we have - q->geometry = - &(*qmesh->geometryLodList)[qmesh->geometryLodList->size() - 1]; - } - // Locate a material bucket - MaterialBucket* mbucket = 0; - MaterialBucketMap::iterator m = - mMaterialBucketMap.find(qmesh->materialName); - if (m != mMaterialBucketMap.end()) - { - mbucket = m->second; - } - else - { - mbucket = OGRE_NEW MaterialBucket(this, qmesh->materialName); - mMaterialBucketMap[qmesh->materialName] = mbucket; - } - mbucket->assign(q); - } - //-------------------------------------------------------------------------- - void StaticGeometry::LODBucket::build(bool stencilShadows) - { - - EdgeListBuilder eb; - size_t vertexSet = 0; - - // Just pass this on to child buckets - for (MaterialBucketMap::iterator i = mMaterialBucketMap.begin(); - i != mMaterialBucketMap.end(); ++i) - { - MaterialBucket* mat = i->second; - - mat->build(stencilShadows); - - if (stencilShadows) - { - MaterialBucket::GeometryIterator geomIt = - mat->getGeometryIterator(); - // Check if we have vertex programs here - Technique* t = mat->getMaterial()->getBestTechnique(); - if (t) - { - Pass* p = t->getPass(0); - if (p) - { - if (p->hasVertexProgram()) - { - mVertexProgramInUse = true; + } + //-------------------------------------------------------------------------- + StaticGeometry::Region::LODIterator + StaticGeometry::Region::getLODIterator(void) + { + return LODIterator(mLodBucketList.begin(), mLodBucketList.end()); + } + //--------------------------------------------------------------------- + ShadowCaster::ShadowRenderableListIterator + StaticGeometry::Region::getShadowVolumeRenderableIterator( + ShadowTechnique shadowTechnique, const Light* light, + HardwareIndexBufferSharedPtr* indexBuffer, size_t* indexBufferUsedSize, + bool extrude, Real extrusionDistance, unsigned long flags) + { + // Calculate the object space light details + Vector4 lightPos = light->getAs4DVector(); + Matrix4 world2Obj = mParentNode->_getFullTransform().inverseAffine(); + lightPos = world2Obj.transformAffine(lightPos); + Matrix3 world2Obj3x3; + world2Obj.extract3x3Matrix(world2Obj3x3); + extrusionDistance *= Math::Sqrt(std::min(std::min(world2Obj3x3.GetColumn(0).squaredLength(), world2Obj3x3.GetColumn(1).squaredLength()), world2Obj3x3.GetColumn(2).squaredLength())); + + // per-LOD shadow lists & edge data + mLodBucketList[mCurrentLod]->updateShadowRenderables( + shadowTechnique, lightPos, indexBuffer, extrude, extrusionDistance, flags); + + EdgeData* edgeList = mLodBucketList[mCurrentLod]->getEdgeList(); + ShadowRenderableList& shadowRendList = mLodBucketList[mCurrentLod]->getShadowRenderableList(); + + // Calc triangle light facing + updateEdgeListLightFacing(edgeList, lightPos); + + // Generate indexes and update renderables + generateShadowVolume(edgeList, *indexBuffer, *indexBufferUsedSize, + light, shadowRendList, flags); + + + return ShadowCaster::ShadowRenderableListIterator(shadowRendList.begin(), shadowRendList.end()); + + } + //-------------------------------------------------------------------------- + EdgeData* StaticGeometry::Region::getEdgeList(void) + { + return mLodBucketList[mCurrentLod]->getEdgeList(); + } + //-------------------------------------------------------------------------- + bool StaticGeometry::Region::hasEdgeList(void) + { + return getEdgeList() != 0; + } + //-------------------------------------------------------------------------- + void StaticGeometry::Region::dump(std::ofstream& of) const + { + of << "Region " << mRegionID << std::endl; + of << "--------------------------" << std::endl; + of << "Centre: " << mCentre << std::endl; + of << "Local AABB: " << mAABB << std::endl; + of << "Bounding radius: " << mBoundingRadius << std::endl; + of << "Number of LODs: " << mLodBucketList.size() << std::endl; + + for (LODBucketList::const_iterator i = mLodBucketList.begin(); + i != mLodBucketList.end(); ++i) + { + (*i)->dump(of); + } + of << "--------------------------" << std::endl; + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + StaticGeometry::LODBucket::LODShadowRenderable::LODShadowRenderable( + LODBucket* parent, HardwareIndexBufferSharedPtr* indexBuffer, + const VertexData* vertexData, bool createSeparateLightCap, + bool isLightCap) + : mParent(parent) + { + // Initialise render op + mRenderOp.indexData = OGRE_NEW IndexData(); + mRenderOp.indexData->indexBuffer = *indexBuffer; + mRenderOp.indexData->indexStart = 0; + // index start and count are sorted out later + + // Create vertex data which just references position component (and 2 component) + mRenderOp.vertexData = OGRE_NEW VertexData(); + // Map in position data + mRenderOp.vertexData->vertexDeclaration->addElement(0,0,VET_FLOAT3, VES_POSITION); + ushort origPosBind = + vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION)->getSource(); + mPositionBuffer = vertexData->vertexBufferBinding->getBuffer(origPosBind); + mRenderOp.vertexData->vertexBufferBinding->setBinding(0, mPositionBuffer); + // Map in w-coord buffer (if present) + if(!vertexData->hardwareShadowVolWBuffer.isNull()) + { + mRenderOp.vertexData->vertexDeclaration->addElement(1,0,VET_FLOAT1, VES_TEXTURE_COORDINATES, 0); + mWBuffer = vertexData->hardwareShadowVolWBuffer; + mRenderOp.vertexData->vertexBufferBinding->setBinding(1, mWBuffer); + } + // Use same vertex start as input + mRenderOp.vertexData->vertexStart = vertexData->vertexStart; + + if (isLightCap) + { + // Use original vertex count, no extrusion + mRenderOp.vertexData->vertexCount = vertexData->vertexCount; + } + else + { + // Vertex count must take into account the doubling of the buffer, + // because second half of the buffer is the extruded copy + mRenderOp.vertexData->vertexCount = + vertexData->vertexCount * 2; + if (createSeparateLightCap) + { + // Create child light cap + mLightCap = OGRE_NEW LODShadowRenderable(parent, + indexBuffer, vertexData, false, true); + } + } + } + //-------------------------------------------------------------------------- + StaticGeometry::LODBucket::LODShadowRenderable::~LODShadowRenderable() + { + OGRE_DELETE mRenderOp.indexData; + OGRE_DELETE mRenderOp.vertexData; + } + //-------------------------------------------------------------------------- + void StaticGeometry::LODBucket::LODShadowRenderable::getWorldTransforms( + Matrix4* xform) const + { + // pretransformed + *xform = mParent->getParent()->_getParentNodeFullTransform(); + } + //----------------------------------------------------------------------- + void StaticGeometry::LODBucket::LODShadowRenderable::rebindIndexBuffer(const HardwareIndexBufferSharedPtr& indexBuffer) + { + mRenderOp.indexData->indexBuffer = indexBuffer; + if (mLightCap) mLightCap->rebindIndexBuffer(indexBuffer); + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + StaticGeometry::LODBucket::LODBucket(Region* parent, unsigned short lod, + Real lodValue) + : mParent(parent), mLod(lod), mLodValue(lodValue), mEdgeList(0) + , mVertexProgramInUse(false) + { + } + //-------------------------------------------------------------------------- + StaticGeometry::LODBucket::~LODBucket() + { + OGRE_DELETE mEdgeList; + for (ShadowCaster::ShadowRenderableList::iterator s = mShadowRenderables.begin(); + s != mShadowRenderables.end(); ++s) + { + OGRE_DELETE *s; + } + mShadowRenderables.clear(); + // delete + for (MaterialBucketMap::iterator i = mMaterialBucketMap.begin(); + i != mMaterialBucketMap.end(); ++i) + { + OGRE_DELETE i->second; + } + mMaterialBucketMap.clear(); + for(QueuedGeometryList::iterator qi = mQueuedGeometryList.begin(); + qi != mQueuedGeometryList.end(); ++qi) + { + OGRE_DELETE *qi; + } + mQueuedGeometryList.clear(); + + // no need to delete queued meshes, these are managed in StaticGeometry + } + //-------------------------------------------------------------------------- + void StaticGeometry::LODBucket::assign(QueuedSubMesh* qmesh, ushort atLod) + { + QueuedGeometry* q = OGRE_NEW QueuedGeometry(); + mQueuedGeometryList.push_back(q); + q->position = qmesh->position; + q->orientation = qmesh->orientation; + q->scale = qmesh->scale; + if (qmesh->geometryLodList->size() > atLod) + { + // This submesh has enough lods, use the right one + q->geometry = &(*qmesh->geometryLodList)[atLod]; + } + else + { + // Not enough lods, use the lowest one we have + q->geometry = + &(*qmesh->geometryLodList)[qmesh->geometryLodList->size() - 1]; + } + // Locate a material bucket + MaterialBucket* mbucket = 0; + MaterialBucketMap::iterator m = + mMaterialBucketMap.find(qmesh->materialName); + if (m != mMaterialBucketMap.end()) + { + mbucket = m->second; + } + else + { + mbucket = OGRE_NEW MaterialBucket(this, qmesh->materialName); + mMaterialBucketMap[qmesh->materialName] = mbucket; + } + mbucket->assign(q); + } + //-------------------------------------------------------------------------- + void StaticGeometry::LODBucket::build(bool stencilShadows) + { + + EdgeListBuilder eb; + size_t vertexSet = 0; + + // Just pass this on to child buckets + for (MaterialBucketMap::iterator i = mMaterialBucketMap.begin(); + i != mMaterialBucketMap.end(); ++i) + { + MaterialBucket* mat = i->second; + + mat->build(stencilShadows); + + if (stencilShadows) + { + MaterialBucket::GeometryIterator geomIt = + mat->getGeometryIterator(); + // Check if we have vertex programs here + Technique* t = mat->getMaterial()->getBestTechnique(); + if (t) + { + Pass* p = t->getPass(0); + if (p) + { + if (p->hasVertexProgram()) + { + mVertexProgramInUse = true; } } - } - - while (geomIt.hasMoreElements()) - { - GeometryBucket* geom = geomIt.getNext(); - - // Check we're dealing with 16-bit indexes here - // Since stencil shadows can only deal with 16-bit - // More than that and stencil is probably too CPU-heavy - // in any case - assert(geom->getIndexData()->indexBuffer->getType() - == HardwareIndexBuffer::IT_16BIT && - "Only 16-bit indexes allowed when using stencil shadows"); - eb.addVertexData(geom->getVertexData()); - eb.addIndexData(geom->getIndexData(), vertexSet++); - } - - } - } - - if (stencilShadows) - { - mEdgeList = eb.build(); - } - } - //-------------------------------------------------------------------------- - void StaticGeometry::LODBucket::addRenderables(RenderQueue* queue, - uint8 group, Real lodValue) - { - // Just pass this on to child buckets - MaterialBucketMap::iterator i, iend; - iend = mMaterialBucketMap.end(); - for (i = mMaterialBucketMap.begin(); i != iend; ++i) - { - i->second->addRenderables(queue, group, lodValue); - } - } - //-------------------------------------------------------------------------- - StaticGeometry::LODBucket::MaterialIterator - StaticGeometry::LODBucket::getMaterialIterator(void) - { - return MaterialIterator( - mMaterialBucketMap.begin(), mMaterialBucketMap.end()); - } - //-------------------------------------------------------------------------- - void StaticGeometry::LODBucket::dump(std::ofstream& of) const - { - of << "LOD Bucket " << mLod << std::endl; - of << "------------------" << std::endl; - of << "LOD Value: " << mLodValue << std::endl; - of << "Number of Materials: " << mMaterialBucketMap.size() << std::endl; - for (MaterialBucketMap::const_iterator i = mMaterialBucketMap.begin(); - i != mMaterialBucketMap.end(); ++i) - { - i->second->dump(of); - } - of << "------------------" << std::endl; - - } - //--------------------------------------------------------------------- - void StaticGeometry::LODBucket::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - for (MaterialBucketMap::const_iterator i = mMaterialBucketMap.begin(); - i != mMaterialBucketMap.end(); ++i) - { - i->second->visitRenderables(visitor, debugRenderables); - } - - } - //--------------------------------------------------------------------- - void StaticGeometry::LODBucket::updateShadowRenderables( - ShadowTechnique shadowTechnique, const Vector4& lightPos, - HardwareIndexBufferSharedPtr* indexBuffer, bool extrude, - Real extrusionDistance, unsigned long flags /* = 0 */) - { - assert(indexBuffer && "Only external index buffers are supported right now"); - assert((*indexBuffer)->getType() == HardwareIndexBuffer::IT_16BIT && - "Only 16-bit indexes supported for now"); - - // We need to search the edge list for silhouette edges - if (!mEdgeList) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You enabled stencil shadows after the buid process!", - "StaticGeometry::LODBucket::getShadowVolumeRenderableIterator"); - } - - // Init shadow renderable list if required - bool init = mShadowRenderables.empty(); - - EdgeData::EdgeGroupList::iterator egi; - ShadowCaster::ShadowRenderableList::iterator si, siend; - LODShadowRenderable* esr = 0; - if (init) - mShadowRenderables.resize(mEdgeList->edgeGroups.size()); - - //bool updatedSharedGeomNormals = false; - siend = mShadowRenderables.end(); - egi = mEdgeList->edgeGroups.begin(); - for (si = mShadowRenderables.begin(); si != siend; ++si, ++egi) - { - if (init) - { - // Create a new renderable, create a separate light cap if - // we're using a vertex program (either for this model, or - // for extruding the shadow volume) since otherwise we can - // get depth-fighting on the light cap - - *si = OGRE_NEW LODShadowRenderable(this, indexBuffer, - egi->vertexData, mVertexProgramInUse || !extrude); - } - // Get shadow renderable - esr = static_cast(*si); - HardwareVertexBufferSharedPtr esrPositionBuffer = esr->getPositionBuffer(); - // Extrude vertices in software if required - if (extrude) - { - mParent->extrudeVertices(esrPositionBuffer, - egi->vertexData->vertexCount, - lightPos, extrusionDistance); - - } - - } - - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - StaticGeometry::MaterialBucket::MaterialBucket(LODBucket* parent, - const String& materialName) - : mParent(parent) - , mMaterialName(materialName) - , mTechnique(0) - { - } - //-------------------------------------------------------------------------- - StaticGeometry::MaterialBucket::~MaterialBucket() - { - // delete - for (GeometryBucketList::iterator i = mGeometryBucketList.begin(); - i != mGeometryBucketList.end(); ++i) - { - OGRE_DELETE *i; - } - mGeometryBucketList.clear(); - - // no need to delete queued meshes, these are managed in StaticGeometry - } - //-------------------------------------------------------------------------- - void StaticGeometry::MaterialBucket::assign(QueuedGeometry* qgeom) - { - // Look up any current geometry - String formatString = getGeometryFormatString(qgeom->geometry); - CurrentGeometryMap::iterator gi = mCurrentGeometryMap.find(formatString); - bool newBucket = true; - if (gi != mCurrentGeometryMap.end()) - { - // Found existing geometry, try to assign - newBucket = !gi->second->assign(qgeom); - // Note that this bucket will be replaced as the 'current' - // for this format string below since it's out of space - } - // Do we need to create a new one? - if (newBucket) - { - GeometryBucket* gbucket = OGRE_NEW GeometryBucket(this, formatString, - qgeom->geometry->vertexData, qgeom->geometry->indexData); - // Add to main list - mGeometryBucketList.push_back(gbucket); - // Also index in 'current' list - mCurrentGeometryMap[formatString] = gbucket; - if (!gbucket->assign(qgeom)) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Somehow we couldn't fit the requested geometry even in a " - "brand new GeometryBucket!! Must be a bug, please report.", - "StaticGeometry::MaterialBucket::assign"); - } - } - } - //-------------------------------------------------------------------------- - void StaticGeometry::MaterialBucket::build(bool stencilShadows) - { - mTechnique = 0; - mMaterial = MaterialManager::getSingleton().getByName(mMaterialName); - if (mMaterial.isNull()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Material '" + mMaterialName + "' not found.", - "StaticGeometry::MaterialBucket::build"); - } - mMaterial->load(); - // tell the geometry buckets to build - for (GeometryBucketList::iterator i = mGeometryBucketList.begin(); - i != mGeometryBucketList.end(); ++i) - { - (*i)->build(stencilShadows); - } - } - //-------------------------------------------------------------------------- - void StaticGeometry::MaterialBucket::addRenderables(RenderQueue* queue, - uint8 group, Real lodValue) - { + } + + while (geomIt.hasMoreElements()) + { + GeometryBucket* geom = geomIt.getNext(); + + // Check we're dealing with 16-bit indexes here + // Since stencil shadows can only deal with 16-bit + // More than that and stencil is probably too CPU-heavy + // in any case + assert(geom->getIndexData()->indexBuffer->getType() + == HardwareIndexBuffer::IT_16BIT && + "Only 16-bit indexes allowed when using stencil shadows"); + eb.addVertexData(geom->getVertexData()); + eb.addIndexData(geom->getIndexData(), vertexSet++); + } + + } + } + + if (stencilShadows) + { + mEdgeList = eb.build(); + } + } + //-------------------------------------------------------------------------- + void StaticGeometry::LODBucket::addRenderables(RenderQueue* queue, + uint8 group, Real lodValue) + { + // Just pass this on to child buckets + MaterialBucketMap::iterator i, iend; + iend = mMaterialBucketMap.end(); + for (i = mMaterialBucketMap.begin(); i != iend; ++i) + { + i->second->addRenderables(queue, group, lodValue); + } + } + //-------------------------------------------------------------------------- + StaticGeometry::LODBucket::MaterialIterator + StaticGeometry::LODBucket::getMaterialIterator(void) + { + return MaterialIterator( + mMaterialBucketMap.begin(), mMaterialBucketMap.end()); + } + //-------------------------------------------------------------------------- + void StaticGeometry::LODBucket::dump(std::ofstream& of) const + { + of << "LOD Bucket " << mLod << std::endl; + of << "------------------" << std::endl; + of << "LOD Value: " << mLodValue << std::endl; + of << "Number of Materials: " << mMaterialBucketMap.size() << std::endl; + for (MaterialBucketMap::const_iterator i = mMaterialBucketMap.begin(); + i != mMaterialBucketMap.end(); ++i) + { + i->second->dump(of); + } + of << "------------------" << std::endl; + + } + //--------------------------------------------------------------------- + void StaticGeometry::LODBucket::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + for (MaterialBucketMap::const_iterator i = mMaterialBucketMap.begin(); + i != mMaterialBucketMap.end(); ++i) + { + i->second->visitRenderables(visitor, debugRenderables); + } + + } + //--------------------------------------------------------------------- + void StaticGeometry::LODBucket::updateShadowRenderables( + ShadowTechnique shadowTechnique, const Vector4& lightPos, + HardwareIndexBufferSharedPtr* indexBuffer, bool extrude, + Real extrusionDistance, unsigned long flags /* = 0 */) + { + assert(indexBuffer && "Only external index buffers are supported right now"); + assert((*indexBuffer)->getType() == HardwareIndexBuffer::IT_16BIT && + "Only 16-bit indexes supported for now"); + + // We need to search the edge list for silhouette edges + if (!mEdgeList) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You enabled stencil shadows after the buid process!", + "StaticGeometry::LODBucket::getShadowVolumeRenderableIterator"); + } + + // Init shadow renderable list if required + bool init = mShadowRenderables.empty(); + + EdgeData::EdgeGroupList::iterator egi; + ShadowCaster::ShadowRenderableList::iterator si, siend; + LODShadowRenderable* esr = 0; + if (init) + mShadowRenderables.resize(mEdgeList->edgeGroups.size()); + + //bool updatedSharedGeomNormals = false; + siend = mShadowRenderables.end(); + egi = mEdgeList->edgeGroups.begin(); + for (si = mShadowRenderables.begin(); si != siend; ++si, ++egi) + { + if (init) + { + // Create a new renderable, create a separate light cap if + // we're using a vertex program (either for this model, or + // for extruding the shadow volume) since otherwise we can + // get depth-fighting on the light cap + + *si = OGRE_NEW LODShadowRenderable(this, indexBuffer, + egi->vertexData, mVertexProgramInUse || !extrude); + } + // Get shadow renderable + esr = static_cast(*si); + HardwareVertexBufferSharedPtr esrPositionBuffer = esr->getPositionBuffer(); + // Extrude vertices in software if required + if (extrude) + { + mParent->extrudeVertices(esrPositionBuffer, + egi->vertexData->vertexCount, + lightPos, extrusionDistance); + + } + + } + + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + StaticGeometry::MaterialBucket::MaterialBucket(LODBucket* parent, + const String& materialName) + : mParent(parent) + , mMaterialName(materialName) + , mTechnique(0) + { + } + //-------------------------------------------------------------------------- + StaticGeometry::MaterialBucket::~MaterialBucket() + { + // delete + for (GeometryBucketList::iterator i = mGeometryBucketList.begin(); + i != mGeometryBucketList.end(); ++i) + { + OGRE_DELETE *i; + } + mGeometryBucketList.clear(); + + // no need to delete queued meshes, these are managed in StaticGeometry + } + //-------------------------------------------------------------------------- + void StaticGeometry::MaterialBucket::assign(QueuedGeometry* qgeom) + { + // Look up any current geometry + String formatString = getGeometryFormatString(qgeom->geometry); + CurrentGeometryMap::iterator gi = mCurrentGeometryMap.find(formatString); + bool newBucket = true; + if (gi != mCurrentGeometryMap.end()) + { + // Found existing geometry, try to assign + newBucket = !gi->second->assign(qgeom); + // Note that this bucket will be replaced as the 'current' + // for this format string below since it's out of space + } + // Do we need to create a new one? + if (newBucket) + { + GeometryBucket* gbucket = OGRE_NEW GeometryBucket(this, formatString, + qgeom->geometry->vertexData, qgeom->geometry->indexData); + // Add to main list + mGeometryBucketList.push_back(gbucket); + // Also index in 'current' list + mCurrentGeometryMap[formatString] = gbucket; + if (!gbucket->assign(qgeom)) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Somehow we couldn't fit the requested geometry even in a " + "brand new GeometryBucket!! Must be a bug, please report.", + "StaticGeometry::MaterialBucket::assign"); + } + } + } + //-------------------------------------------------------------------------- + void StaticGeometry::MaterialBucket::build(bool stencilShadows) + { + mTechnique = 0; + mMaterial = MaterialManager::getSingleton().getByName(mMaterialName); + if (mMaterial.isNull()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Material '" + mMaterialName + "' not found.", + "StaticGeometry::MaterialBucket::build"); + } + mMaterial->load(); + // tell the geometry buckets to build + for (GeometryBucketList::iterator i = mGeometryBucketList.begin(); + i != mGeometryBucketList.end(); ++i) + { + (*i)->build(stencilShadows); + } + } + //-------------------------------------------------------------------------- + void StaticGeometry::MaterialBucket::addRenderables(RenderQueue* queue, + uint8 group, Real lodValue) + { // Get region Region *region = mParent->getParent(); @@ -1338,436 +1338,436 @@ namespace Ogre { if (materialLodStrategy != region->mLodStrategy) lodValue = materialLodStrategy->getValue(region, region->mCamera); - // Determine the current material technique - mTechnique = mMaterial->getBestTechnique( - mMaterial->getLodIndex(lodValue)); - GeometryBucketList::iterator i, iend; - iend = mGeometryBucketList.end(); - for (i = mGeometryBucketList.begin(); i != iend; ++i) - { - queue->addRenderable(*i, group); - } - - } - //-------------------------------------------------------------------------- - String StaticGeometry::MaterialBucket::getGeometryFormatString( - SubMeshLodGeometryLink* geom) - { - // Formulate an identifying string for the geometry format - // Must take into account the vertex declaration and the index type - // Format is (all lines separated by '|'): - // Index type - // Vertex element (repeating) - // source - // semantic - // type - StringStream str; - - str << geom->indexData->indexBuffer->getType() << "|"; - const VertexDeclaration::VertexElementList& elemList = - geom->vertexData->vertexDeclaration->getElements(); - VertexDeclaration::VertexElementList::const_iterator ei, eiend; - eiend = elemList.end(); - for (ei = elemList.begin(); ei != eiend; ++ei) - { - const VertexElement& elem = *ei; - str << elem.getSource() << "|"; - str << elem.getSource() << "|"; - str << elem.getSemantic() << "|"; - str << elem.getType() << "|"; - } - - return str.str(); - - } - //-------------------------------------------------------------------------- - StaticGeometry::MaterialBucket::GeometryIterator - StaticGeometry::MaterialBucket::getGeometryIterator(void) - { - return GeometryIterator( - mGeometryBucketList.begin(), mGeometryBucketList.end()); - } - //-------------------------------------------------------------------------- - void StaticGeometry::MaterialBucket::dump(std::ofstream& of) const - { - of << "Material Bucket " << mMaterialName << std::endl; - of << "--------------------------------------------------" << std::endl; - of << "Geometry buckets: " << mGeometryBucketList.size() << std::endl; - for (GeometryBucketList::const_iterator i = mGeometryBucketList.begin(); - i != mGeometryBucketList.end(); ++i) - { - (*i)->dump(of); - } - of << "--------------------------------------------------" << std::endl; - - } - //--------------------------------------------------------------------- - void StaticGeometry::MaterialBucket::visitRenderables(Renderable::Visitor* visitor, - bool debugRenderables) - { - for (GeometryBucketList::const_iterator i = mGeometryBucketList.begin(); - i != mGeometryBucketList.end(); ++i) - { - visitor->visit(*i, mParent->getLod(), false); - } - - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - StaticGeometry::GeometryBucket::GeometryBucket(MaterialBucket* parent, - const String& formatString, const VertexData* vData, - const IndexData* iData) - : Renderable(), mParent(parent), mFormatString(formatString) - { - // Clone the structure from the example - mVertexData = vData->clone(false); - mIndexData = iData->clone(false); - mVertexData->vertexCount = 0; - mVertexData->vertexStart = 0; - mIndexData->indexCount = 0; - mIndexData->indexStart = 0; - mIndexType = iData->indexBuffer->getType(); - // Derive the max vertices - if (mIndexType == HardwareIndexBuffer::IT_32BIT) - { - mMaxVertexIndex = 0xFFFFFFFF; - } - else - { - mMaxVertexIndex = 0xFFFF; - } - - // Check to see if we have blend indices / blend weights - // remove them if so, they can try to blend non-existent bones! - const VertexElement* blendIndices = - mVertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_INDICES); - const VertexElement* blendWeights = - mVertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_WEIGHTS); - if (blendIndices && blendWeights) - { - assert(blendIndices->getSource() == blendWeights->getSource() - && "Blend indices and weights should be in the same buffer"); - // Get the source - ushort source = blendIndices->getSource(); - assert(blendIndices->getSize() + blendWeights->getSize() == - mVertexData->vertexBufferBinding->getBuffer(source)->getVertexSize() - && "Blend indices and blend buffers should have buffer to themselves!"); - // Unset the buffer - mVertexData->vertexBufferBinding->unsetBinding(source); - // Remove the elements - mVertexData->vertexDeclaration->removeElement(VES_BLEND_INDICES); - mVertexData->vertexDeclaration->removeElement(VES_BLEND_WEIGHTS); + // Determine the current material technique + mTechnique = mMaterial->getBestTechnique( + mMaterial->getLodIndex(lodValue)); + GeometryBucketList::iterator i, iend; + iend = mGeometryBucketList.end(); + for (i = mGeometryBucketList.begin(); i != iend; ++i) + { + queue->addRenderable(*i, group); + } + + } + //-------------------------------------------------------------------------- + String StaticGeometry::MaterialBucket::getGeometryFormatString( + SubMeshLodGeometryLink* geom) + { + // Formulate an identifying string for the geometry format + // Must take into account the vertex declaration and the index type + // Format is (all lines separated by '|'): + // Index type + // Vertex element (repeating) + // source + // semantic + // type + StringStream str; + + str << geom->indexData->indexBuffer->getType() << "|"; + const VertexDeclaration::VertexElementList& elemList = + geom->vertexData->vertexDeclaration->getElements(); + VertexDeclaration::VertexElementList::const_iterator ei, eiend; + eiend = elemList.end(); + for (ei = elemList.begin(); ei != eiend; ++ei) + { + const VertexElement& elem = *ei; + str << elem.getSource() << "|"; + str << elem.getSource() << "|"; + str << elem.getSemantic() << "|"; + str << elem.getType() << "|"; + } + + return str.str(); + + } + //-------------------------------------------------------------------------- + StaticGeometry::MaterialBucket::GeometryIterator + StaticGeometry::MaterialBucket::getGeometryIterator(void) + { + return GeometryIterator( + mGeometryBucketList.begin(), mGeometryBucketList.end()); + } + //-------------------------------------------------------------------------- + void StaticGeometry::MaterialBucket::dump(std::ofstream& of) const + { + of << "Material Bucket " << mMaterialName << std::endl; + of << "--------------------------------------------------" << std::endl; + of << "Geometry buckets: " << mGeometryBucketList.size() << std::endl; + for (GeometryBucketList::const_iterator i = mGeometryBucketList.begin(); + i != mGeometryBucketList.end(); ++i) + { + (*i)->dump(of); + } + of << "--------------------------------------------------" << std::endl; + + } + //--------------------------------------------------------------------- + void StaticGeometry::MaterialBucket::visitRenderables(Renderable::Visitor* visitor, + bool debugRenderables) + { + for (GeometryBucketList::const_iterator i = mGeometryBucketList.begin(); + i != mGeometryBucketList.end(); ++i) + { + visitor->visit(*i, mParent->getLod(), false); + } + + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + StaticGeometry::GeometryBucket::GeometryBucket(MaterialBucket* parent, + const String& formatString, const VertexData* vData, + const IndexData* iData) + : Renderable(), mParent(parent), mFormatString(formatString) + { + // Clone the structure from the example + mVertexData = vData->clone(false); + mIndexData = iData->clone(false); + mVertexData->vertexCount = 0; + mVertexData->vertexStart = 0; + mIndexData->indexCount = 0; + mIndexData->indexStart = 0; + mIndexType = iData->indexBuffer->getType(); + // Derive the max vertices + if (mIndexType == HardwareIndexBuffer::IT_32BIT) + { + mMaxVertexIndex = 0xFFFFFFFF; + } + else + { + mMaxVertexIndex = 0xFFFF; + } + + // Check to see if we have blend indices / blend weights + // remove them if so, they can try to blend non-existent bones! + const VertexElement* blendIndices = + mVertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_INDICES); + const VertexElement* blendWeights = + mVertexData->vertexDeclaration->findElementBySemantic(VES_BLEND_WEIGHTS); + if (blendIndices && blendWeights) + { + assert(blendIndices->getSource() == blendWeights->getSource() + && "Blend indices and weights should be in the same buffer"); + // Get the source + ushort source = blendIndices->getSource(); + assert(blendIndices->getSize() + blendWeights->getSize() == + mVertexData->vertexBufferBinding->getBuffer(source)->getVertexSize() + && "Blend indices and blend buffers should have buffer to themselves!"); + // Unset the buffer + mVertexData->vertexBufferBinding->unsetBinding(source); + // Remove the elements + mVertexData->vertexDeclaration->removeElement(VES_BLEND_INDICES); + mVertexData->vertexDeclaration->removeElement(VES_BLEND_WEIGHTS); // Close gaps in bindings for effective and safely mVertexData->closeGapsInBindings(); - } - - - } - //-------------------------------------------------------------------------- - StaticGeometry::GeometryBucket::~GeometryBucket() - { - OGRE_DELETE mVertexData; - OGRE_DELETE mIndexData; - } - //-------------------------------------------------------------------------- - const MaterialPtr& StaticGeometry::GeometryBucket::getMaterial(void) const - { - return mParent->getMaterial(); - } - //-------------------------------------------------------------------------- - Technique* StaticGeometry::GeometryBucket::getTechnique(void) const - { - return mParent->getCurrentTechnique(); - } - //-------------------------------------------------------------------------- - void StaticGeometry::GeometryBucket::getRenderOperation(RenderOperation& op) - { - op.indexData = mIndexData; - op.operationType = RenderOperation::OT_TRIANGLE_LIST; - op.srcRenderable = this; - op.useIndexes = true; - op.vertexData = mVertexData; - } - //-------------------------------------------------------------------------- - void StaticGeometry::GeometryBucket::getWorldTransforms(Matrix4* xform) const - { - // Should be the identity transform, but lets allow transformation of the - // nodes the regions are attached to for kicks - *xform = mParent->getParent()->getParent()->_getParentNodeFullTransform(); - } - //-------------------------------------------------------------------------- - Real StaticGeometry::GeometryBucket::getSquaredViewDepth(const Camera* cam) const - { + } + + + } + //-------------------------------------------------------------------------- + StaticGeometry::GeometryBucket::~GeometryBucket() + { + OGRE_DELETE mVertexData; + OGRE_DELETE mIndexData; + } + //-------------------------------------------------------------------------- + const MaterialPtr& StaticGeometry::GeometryBucket::getMaterial(void) const + { + return mParent->getMaterial(); + } + //-------------------------------------------------------------------------- + Technique* StaticGeometry::GeometryBucket::getTechnique(void) const + { + return mParent->getCurrentTechnique(); + } + //-------------------------------------------------------------------------- + void StaticGeometry::GeometryBucket::getRenderOperation(RenderOperation& op) + { + op.indexData = mIndexData; + op.operationType = RenderOperation::OT_TRIANGLE_LIST; + op.srcRenderable = this; + op.useIndexes = true; + op.vertexData = mVertexData; + } + //-------------------------------------------------------------------------- + void StaticGeometry::GeometryBucket::getWorldTransforms(Matrix4* xform) const + { + // Should be the identity transform, but lets allow transformation of the + // nodes the regions are attached to for kicks + *xform = mParent->getParent()->getParent()->_getParentNodeFullTransform(); + } + //-------------------------------------------------------------------------- + Real StaticGeometry::GeometryBucket::getSquaredViewDepth(const Camera* cam) const + { const Region *region = mParent->getParent()->getParent(); if (cam == region->mCamera) return region->mSquaredViewDepth; else return region->getParentNode()->getSquaredViewDepth(cam->getLodCamera()); - } - //-------------------------------------------------------------------------- - const LightList& StaticGeometry::GeometryBucket::getLights(void) const - { - return mParent->getParent()->getParent()->queryLights(); - } - //-------------------------------------------------------------------------- - bool StaticGeometry::GeometryBucket::getCastsShadows(void) const - { - return mParent->getParent()->getParent()->getCastShadows(); - } - //-------------------------------------------------------------------------- - bool StaticGeometry::GeometryBucket::assign(QueuedGeometry* qgeom) - { - // Do we have enough space? - // -2 first to avoid overflow (-1 to adjust count to index, -1 to ensure - // no overflow at 32 bits and use >= instead of >) - if ((mVertexData->vertexCount - 2 + qgeom->geometry->vertexData->vertexCount) - >= mMaxVertexIndex) - { - return false; - } - - mQueuedGeometry.push_back(qgeom); - mVertexData->vertexCount += qgeom->geometry->vertexData->vertexCount; - mIndexData->indexCount += qgeom->geometry->indexData->indexCount; - - return true; - } - //-------------------------------------------------------------------------- - void StaticGeometry::GeometryBucket::build(bool stencilShadows) - { - // Ok, here's where we transfer the vertices and indexes to the shared - // buffers - // Shortcuts - VertexDeclaration* dcl = mVertexData->vertexDeclaration; - VertexBufferBinding* binds = mVertexData->vertexBufferBinding; - - // create index buffer, and lock - mIndexData->indexBuffer = HardwareBufferManager::getSingleton() - .createIndexBuffer(mIndexType, mIndexData->indexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - uint32* p32Dest = 0; - uint16* p16Dest = 0; - if (mIndexType == HardwareIndexBuffer::IT_32BIT) - { - p32Dest = static_cast( - mIndexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - } - else - { - p16Dest = static_cast( - mIndexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); - } - // create all vertex buffers, and lock - ushort b; - ushort posBufferIdx = dcl->findElementBySemantic(VES_POSITION)->getSource(); - - vector::type destBufferLocks; - vector::type bufferElements; - for (b = 0; b < binds->getBufferCount(); ++b) - { - size_t vertexCount = mVertexData->vertexCount; - // Need to double the vertex count for the position buffer - // if we're doing stencil shadows - if (stencilShadows && b == posBufferIdx) - { - vertexCount = vertexCount * 2; - assert(vertexCount <= mMaxVertexIndex && - "Index range exceeded when using stencil shadows, consider " - "reducing your region size or reducing poly count"); - } - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - dcl->getVertexSize(b), - vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - binds->setBinding(b, vbuf); - uchar* pLock = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD)); - destBufferLocks.push_back(pLock); - // Pre-cache vertex elements per buffer - bufferElements.push_back(dcl->findElementsBySource(b)); - } - - - // Iterate over the geometry items - size_t indexOffset = 0; - QueuedGeometryList::iterator gi, giend; - giend = mQueuedGeometry.end(); - Vector3 regionCentre = mParent->getParent()->getParent()->getCentre(); - for (gi = mQueuedGeometry.begin(); gi != giend; ++gi) - { - QueuedGeometry* geom = *gi; - // Copy indexes across with offset - IndexData* srcIdxData = geom->geometry->indexData; - if (mIndexType == HardwareIndexBuffer::IT_32BIT) - { - // Lock source indexes - uint32* pSrc = static_cast( - srcIdxData->indexBuffer->lock( - srcIdxData->indexStart, - srcIdxData->indexCount * srcIdxData->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - - copyIndexes(pSrc, p32Dest, srcIdxData->indexCount, indexOffset); - p32Dest += srcIdxData->indexCount; - srcIdxData->indexBuffer->unlock(); - } - else - { - // Lock source indexes - uint16* pSrc = static_cast( - srcIdxData->indexBuffer->lock( - srcIdxData->indexStart, - srcIdxData->indexCount * srcIdxData->indexBuffer->getIndexSize(), - HardwareBuffer::HBL_READ_ONLY)); - - copyIndexes(pSrc, p16Dest, srcIdxData->indexCount, indexOffset); - p16Dest += srcIdxData->indexCount; - srcIdxData->indexBuffer->unlock(); - } - - // Now deal with vertex buffers - // we can rely on buffer counts / formats being the same - VertexData* srcVData = geom->geometry->vertexData; - VertexBufferBinding* srcBinds = srcVData->vertexBufferBinding; - for (b = 0; b < binds->getBufferCount(); ++b) - { - // lock source - HardwareVertexBufferSharedPtr srcBuf = - srcBinds->getBuffer(b); - uchar* pSrcBase = static_cast( - srcBuf->lock(HardwareBuffer::HBL_READ_ONLY)); - // Get buffer lock pointer, we'll update this later - uchar* pDstBase = destBufferLocks[b]; - size_t bufInc = srcBuf->getVertexSize(); - - // Iterate over vertices - float *pSrcReal, *pDstReal; - Vector3 tmp; - for (size_t v = 0; v < srcVData->vertexCount; ++v) - { - // Iterate over vertex elements - VertexDeclaration::VertexElementList& elems = - bufferElements[b]; - VertexDeclaration::VertexElementList::iterator ei; - for (ei = elems.begin(); ei != elems.end(); ++ei) - { - VertexElement& elem = *ei; - elem.baseVertexPointerToElement(pSrcBase, &pSrcReal); - elem.baseVertexPointerToElement(pDstBase, &pDstReal); - switch (elem.getSemantic()) - { - case VES_POSITION: - tmp.x = *pSrcReal++; - tmp.y = *pSrcReal++; - tmp.z = *pSrcReal++; - // transform - tmp = (geom->orientation * (tmp * geom->scale)) + - geom->position; - // Adjust for region centre - tmp -= regionCentre; - *pDstReal++ = tmp.x; - *pDstReal++ = tmp.y; - *pDstReal++ = tmp.z; - break; - case VES_NORMAL: - case VES_TANGENT: - case VES_BINORMAL: - tmp.x = *pSrcReal++; - tmp.y = *pSrcReal++; - tmp.z = *pSrcReal++; - // scale (invert) - tmp = tmp / geom->scale; - tmp.normalise(); - // rotation - tmp = geom->orientation * tmp; - *pDstReal++ = tmp.x; - *pDstReal++ = tmp.y; - *pDstReal++ = tmp.z; - // copy parity for tangent. - if (elem.getType() == Ogre::VET_FLOAT4) - *pDstReal = *pSrcReal; - break; - default: - // just raw copy - memcpy(pDstReal, pSrcReal, - VertexElement::getTypeSize(elem.getType())); - break; - }; - - } - - // Increment both pointers - pDstBase += bufInc; - pSrcBase += bufInc; - - } - - // Update pointer - destBufferLocks[b] = pDstBase; - srcBuf->unlock(); - } - - indexOffset += geom->geometry->vertexData->vertexCount; - } - - // Unlock everything - mIndexData->indexBuffer->unlock(); - for (b = 0; b < binds->getBufferCount(); ++b) - { - binds->getBuffer(b)->unlock(); - } - - // If we're dealing with stencil shadows, copy the position data from - // the early half of the buffer to the latter part - if (stencilShadows) - { - HardwareVertexBufferSharedPtr buf = binds->getBuffer(posBufferIdx); - void* pSrc = buf->lock(HardwareBuffer::HBL_NORMAL); - // Point dest at second half (remember vertexcount is original count) - void* pDest = static_cast(pSrc) + - buf->getVertexSize() * mVertexData->vertexCount; - memcpy(pDest, pSrc, buf->getVertexSize() * mVertexData->vertexCount); - buf->unlock(); - - // Also set up hardware W buffer if appropriate - RenderSystem* rend = Root::getSingleton().getRenderSystem(); - if (rend && rend->getCapabilities()->hasCapability(RSC_VERTEX_PROGRAM)) - { - buf = HardwareBufferManager::getSingleton().createVertexBuffer( - sizeof(float), mVertexData->vertexCount * 2, - HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - // Fill the first half with 1.0, second half with 0.0 - float *pW = static_cast( - buf->lock(HardwareBuffer::HBL_DISCARD)); - size_t v; - for (v = 0; v < mVertexData->vertexCount; ++v) - { - *pW++ = 1.0f; - } - for (v = 0; v < mVertexData->vertexCount; ++v) - { - *pW++ = 0.0f; - } - buf->unlock(); - mVertexData->hardwareShadowVolWBuffer = buf; - } - } - - } - //-------------------------------------------------------------------------- - void StaticGeometry::GeometryBucket::dump(std::ofstream& of) const - { - of << "Geometry Bucket" << std::endl; - of << "---------------" << std::endl; - of << "Format string: " << mFormatString << std::endl; - of << "Geometry items: " << mQueuedGeometry.size() << std::endl; - of << "Vertex count: " << mVertexData->vertexCount << std::endl; - of << "Index count: " << mIndexData->indexCount << std::endl; - of << "---------------" << std::endl; - - } - //-------------------------------------------------------------------------- + } + //-------------------------------------------------------------------------- + const LightList& StaticGeometry::GeometryBucket::getLights(void) const + { + return mParent->getParent()->getParent()->queryLights(); + } + //-------------------------------------------------------------------------- + bool StaticGeometry::GeometryBucket::getCastsShadows(void) const + { + return mParent->getParent()->getParent()->getCastShadows(); + } + //-------------------------------------------------------------------------- + bool StaticGeometry::GeometryBucket::assign(QueuedGeometry* qgeom) + { + // Do we have enough space? + // -2 first to avoid overflow (-1 to adjust count to index, -1 to ensure + // no overflow at 32 bits and use >= instead of >) + if ((mVertexData->vertexCount - 2 + qgeom->geometry->vertexData->vertexCount) + >= mMaxVertexIndex) + { + return false; + } + + mQueuedGeometry.push_back(qgeom); + mVertexData->vertexCount += qgeom->geometry->vertexData->vertexCount; + mIndexData->indexCount += qgeom->geometry->indexData->indexCount; + + return true; + } + //-------------------------------------------------------------------------- + void StaticGeometry::GeometryBucket::build(bool stencilShadows) + { + // Ok, here's where we transfer the vertices and indexes to the shared + // buffers + // Shortcuts + VertexDeclaration* dcl = mVertexData->vertexDeclaration; + VertexBufferBinding* binds = mVertexData->vertexBufferBinding; + + // create index buffer, and lock + mIndexData->indexBuffer = HardwareBufferManager::getSingleton() + .createIndexBuffer(mIndexType, mIndexData->indexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + uint32* p32Dest = 0; + uint16* p16Dest = 0; + if (mIndexType == HardwareIndexBuffer::IT_32BIT) + { + p32Dest = static_cast( + mIndexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + } + else + { + p16Dest = static_cast( + mIndexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD)); + } + // create all vertex buffers, and lock + ushort b; + ushort posBufferIdx = dcl->findElementBySemantic(VES_POSITION)->getSource(); + + vector::type destBufferLocks; + vector::type bufferElements; + for (b = 0; b < binds->getBufferCount(); ++b) + { + size_t vertexCount = mVertexData->vertexCount; + // Need to double the vertex count for the position buffer + // if we're doing stencil shadows + if (stencilShadows && b == posBufferIdx) + { + vertexCount = vertexCount * 2; + assert(vertexCount <= mMaxVertexIndex && + "Index range exceeded when using stencil shadows, consider " + "reducing your region size or reducing poly count"); + } + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + dcl->getVertexSize(b), + vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + binds->setBinding(b, vbuf); + uchar* pLock = static_cast( + vbuf->lock(HardwareBuffer::HBL_DISCARD)); + destBufferLocks.push_back(pLock); + // Pre-cache vertex elements per buffer + bufferElements.push_back(dcl->findElementsBySource(b)); + } + + + // Iterate over the geometry items + size_t indexOffset = 0; + QueuedGeometryList::iterator gi, giend; + giend = mQueuedGeometry.end(); + Vector3 regionCentre = mParent->getParent()->getParent()->getCentre(); + for (gi = mQueuedGeometry.begin(); gi != giend; ++gi) + { + QueuedGeometry* geom = *gi; + // Copy indexes across with offset + IndexData* srcIdxData = geom->geometry->indexData; + if (mIndexType == HardwareIndexBuffer::IT_32BIT) + { + // Lock source indexes + uint32* pSrc = static_cast( + srcIdxData->indexBuffer->lock( + srcIdxData->indexStart, + srcIdxData->indexCount * srcIdxData->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + + copyIndexes(pSrc, p32Dest, srcIdxData->indexCount, indexOffset); + p32Dest += srcIdxData->indexCount; + srcIdxData->indexBuffer->unlock(); + } + else + { + // Lock source indexes + uint16* pSrc = static_cast( + srcIdxData->indexBuffer->lock( + srcIdxData->indexStart, + srcIdxData->indexCount * srcIdxData->indexBuffer->getIndexSize(), + HardwareBuffer::HBL_READ_ONLY)); + + copyIndexes(pSrc, p16Dest, srcIdxData->indexCount, indexOffset); + p16Dest += srcIdxData->indexCount; + srcIdxData->indexBuffer->unlock(); + } + + // Now deal with vertex buffers + // we can rely on buffer counts / formats being the same + VertexData* srcVData = geom->geometry->vertexData; + VertexBufferBinding* srcBinds = srcVData->vertexBufferBinding; + for (b = 0; b < binds->getBufferCount(); ++b) + { + // lock source + HardwareVertexBufferSharedPtr srcBuf = + srcBinds->getBuffer(b); + uchar* pSrcBase = static_cast( + srcBuf->lock(HardwareBuffer::HBL_READ_ONLY)); + // Get buffer lock pointer, we'll update this later + uchar* pDstBase = destBufferLocks[b]; + size_t bufInc = srcBuf->getVertexSize(); + + // Iterate over vertices + float *pSrcReal, *pDstReal; + Vector3 tmp; + for (size_t v = 0; v < srcVData->vertexCount; ++v) + { + // Iterate over vertex elements + VertexDeclaration::VertexElementList& elems = + bufferElements[b]; + VertexDeclaration::VertexElementList::iterator ei; + for (ei = elems.begin(); ei != elems.end(); ++ei) + { + VertexElement& elem = *ei; + elem.baseVertexPointerToElement(pSrcBase, &pSrcReal); + elem.baseVertexPointerToElement(pDstBase, &pDstReal); + switch (elem.getSemantic()) + { + case VES_POSITION: + tmp.x = *pSrcReal++; + tmp.y = *pSrcReal++; + tmp.z = *pSrcReal++; + // transform + tmp = (geom->orientation * (tmp * geom->scale)) + + geom->position; + // Adjust for region centre + tmp -= regionCentre; + *pDstReal++ = tmp.x; + *pDstReal++ = tmp.y; + *pDstReal++ = tmp.z; + break; + case VES_NORMAL: + case VES_TANGENT: + case VES_BINORMAL: + tmp.x = *pSrcReal++; + tmp.y = *pSrcReal++; + tmp.z = *pSrcReal++; + // scale (invert) + tmp = tmp / geom->scale; + tmp.normalise(); + // rotation + tmp = geom->orientation * tmp; + *pDstReal++ = tmp.x; + *pDstReal++ = tmp.y; + *pDstReal++ = tmp.z; + // copy parity for tangent. + if (elem.getType() == Ogre::VET_FLOAT4) + *pDstReal = *pSrcReal; + break; + default: + // just raw copy + memcpy(pDstReal, pSrcReal, + VertexElement::getTypeSize(elem.getType())); + break; + }; + + } + + // Increment both pointers + pDstBase += bufInc; + pSrcBase += bufInc; + + } + + // Update pointer + destBufferLocks[b] = pDstBase; + srcBuf->unlock(); + } + + indexOffset += geom->geometry->vertexData->vertexCount; + } + + // Unlock everything + mIndexData->indexBuffer->unlock(); + for (b = 0; b < binds->getBufferCount(); ++b) + { + binds->getBuffer(b)->unlock(); + } + + // If we're dealing with stencil shadows, copy the position data from + // the early half of the buffer to the latter part + if (stencilShadows) + { + HardwareVertexBufferSharedPtr buf = binds->getBuffer(posBufferIdx); + void* pSrc = buf->lock(HardwareBuffer::HBL_NORMAL); + // Point dest at second half (remember vertexcount is original count) + void* pDest = static_cast(pSrc) + + buf->getVertexSize() * mVertexData->vertexCount; + memcpy(pDest, pSrc, buf->getVertexSize() * mVertexData->vertexCount); + buf->unlock(); + + // Also set up hardware W buffer if appropriate + RenderSystem* rend = Root::getSingleton().getRenderSystem(); + if (rend && rend->getCapabilities()->hasCapability(RSC_VERTEX_PROGRAM)) + { + buf = HardwareBufferManager::getSingleton().createVertexBuffer( + sizeof(float), mVertexData->vertexCount * 2, + HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + // Fill the first half with 1.0, second half with 0.0 + float *pW = static_cast( + buf->lock(HardwareBuffer::HBL_DISCARD)); + size_t v; + for (v = 0; v < mVertexData->vertexCount; ++v) + { + *pW++ = 1.0f; + } + for (v = 0; v < mVertexData->vertexCount; ++v) + { + *pW++ = 0.0f; + } + buf->unlock(); + mVertexData->hardwareShadowVolWBuffer = buf; + } + } + + } + //-------------------------------------------------------------------------- + void StaticGeometry::GeometryBucket::dump(std::ofstream& of) const + { + of << "Geometry Bucket" << std::endl; + of << "---------------" << std::endl; + of << "Format string: " << mFormatString << std::endl; + of << "Geometry items: " << mQueuedGeometry.size() << std::endl; + of << "Vertex count: " << mVertexData->vertexCount << std::endl; + of << "Index count: " << mIndexData->indexCount << std::endl; + of << "---------------" << std::endl; + + } + //-------------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreStreamSerialiser.cpp b/OgreMain/src/OgreStreamSerialiser.cpp index 36342e87867..6002d039315 100644 --- a/OgreMain/src/OgreStreamSerialiser.cpp +++ b/OgreMain/src/OgreStreamSerialiser.cpp @@ -45,814 +45,814 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - uint32 StreamSerialiser::HEADER_ID = 0x00000001; - uint32 StreamSerialiser::REVERSE_HEADER_ID = 0x10000000; - uint32 StreamSerialiser::CHUNK_HEADER_SIZE = - sizeof(uint32) + // id - sizeof(uint16) + // version - sizeof(uint32) + // length - sizeof(uint32); // checksum - //--------------------------------------------------------------------- - StreamSerialiser::StreamSerialiser(const DataStreamPtr& stream, Endian endianMode, - bool autoHeader, RealStorageFormat realFormat) - : mStream(stream) - , mEndian(endianMode) - , mFlipEndian(false) - , mReadWriteHeader(autoHeader) - , mRealFormat(realFormat) - { - if (mEndian != ENDIAN_AUTO) - { + //--------------------------------------------------------------------- + uint32 StreamSerialiser::HEADER_ID = 0x00000001; + uint32 StreamSerialiser::REVERSE_HEADER_ID = 0x10000000; + uint32 StreamSerialiser::CHUNK_HEADER_SIZE = + sizeof(uint32) + // id + sizeof(uint16) + // version + sizeof(uint32) + // length + sizeof(uint32); // checksum + //--------------------------------------------------------------------- + StreamSerialiser::StreamSerialiser(const DataStreamPtr& stream, Endian endianMode, + bool autoHeader, RealStorageFormat realFormat) + : mStream(stream) + , mEndian(endianMode) + , mFlipEndian(false) + , mReadWriteHeader(autoHeader) + , mRealFormat(realFormat) + { + if (mEndian != ENDIAN_AUTO) + { #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - if (mEndian == ENDIAN_LITTLE) - mFlipEndian = true; + if (mEndian == ENDIAN_LITTLE) + mFlipEndian = true; #else - if (mEndian == ENDIAN_BIG) - mFlipEndian = true; + if (mEndian == ENDIAN_BIG) + mFlipEndian = true; #endif - } - - checkStream(); - - } - //--------------------------------------------------------------------- - StreamSerialiser::~StreamSerialiser() - { - // really this should be empty if read/write was complete, but be tidy - if (!mChunkStack.empty()) - { - LogManager::getSingleton().stream() << - "Warning: stream " << mStream->getName() << " was not fully read / written; " << - mChunkStack.size() << " chunks remain unterminated."; - } - for (ChunkStack::iterator i = mChunkStack.begin(); i != mChunkStack.end(); ++i) - delete *i; - mChunkStack.clear(); - - } - //--------------------------------------------------------------------- - uint32 StreamSerialiser::makeIdentifier(const String& code) - { - assert(code.length() <= 4 && "Characters after the 4th are being ignored"); - uint32 ret = 0; - size_t c = std::min((size_t)4, code.length()); - for (size_t i = 0; i < c; ++i) - { - ret += (code.at(i) << (i * 8)); - } - return ret; - - } - //--------------------------------------------------------------------- - uint32 StreamSerialiser::getCurrentChunkID() const - { - if (mChunkStack.empty()) - return 0; - else - return mChunkStack.back()->id; - } - //--------------------------------------------------------------------- - const StreamSerialiser::Chunk* StreamSerialiser::readChunkBegin() - { - // Have we figured out the endian mode yet? - if (mReadWriteHeader) - readHeader(); - - if (mEndian == ENDIAN_AUTO) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Endian mode has not been determined, did you disable header without setting?", - "StreamSerialiser::readChunkBegin"); - - Chunk* chunk = readChunkImpl(); - mChunkStack.push_back(chunk); - - return chunk; - - } - //--------------------------------------------------------------------- - const StreamSerialiser::Chunk* StreamSerialiser::readChunkBegin( - uint32 id, uint16 maxVersion, const String& msg) - { - const Chunk* c = readChunkBegin(); - if (c->id != id) - { - // rewind - undoReadChunk(c->id); - return 0; - } - else if (c->version > maxVersion) - { - LogManager::getSingleton().stream() << "Error: " << msg - << " : Data version is " << c->version << " but this software can only read " - << "up to version " << maxVersion; - // skip - readChunkEnd(c->id); - return 0; - } - - return c; - - } - //--------------------------------------------------------------------- - void StreamSerialiser::undoReadChunk(uint32 id) - { - Chunk* c = popChunk(id); - - checkStream(); - - mStream->seek(c->offset); - - OGRE_DELETE c; - - } - //--------------------------------------------------------------------- - uint32 StreamSerialiser::peekNextChunkID() - { - checkStream(); - - if (eof()) - return 0; - - // Have we figured out the endian mode yet? - if (mReadWriteHeader) - readHeader(); - - if (mEndian == ENDIAN_AUTO) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Endian mode has not been determined, did you disable header without setting?", - "StreamSerialiser::peekNextChunkID"); - - size_t homePos = mStream->tell(); - uint32 ret; - read(&ret); - mStream->seek(homePos); - - return ret; - } - //--------------------------------------------------------------------- - void StreamSerialiser::readChunkEnd(uint32 id) - { - Chunk* c = popChunk(id); - - checkStream(); - - // skip to the end of the chunk if we were not there already - // this lets us quite reading a chunk anywhere and have the read marker - // automatically skip to the next one - if (mStream->tell() < (c->offset + CHUNK_HEADER_SIZE + c->length)) - mStream->seek(c->offset + CHUNK_HEADER_SIZE + c->length); - - OGRE_DELETE c; - } - //--------------------------------------------------------------------- - bool StreamSerialiser::isEndOfChunk(uint32 id) - { - const Chunk* c = getCurrentChunk(); - assert(c->id == id); - return mStream->tell() == (c->offset + CHUNK_HEADER_SIZE + c->length); - } - //--------------------------------------------------------------------- - void StreamSerialiser::readHeader() - { - uint32 headerid; - size_t actually_read = mStream->read(&headerid, sizeof(uint32)); - // skip back - mStream->skip(0 - (long)actually_read); - // validate that this is a header chunk - if (headerid == REVERSE_HEADER_ID) - { - mFlipEndian = true; - } - else if (headerid == HEADER_ID) - { - mFlipEndian = false; - } - else - { - // no good - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Cannot determine endian mode because header is missing", - "StreamSerialiser::readHeader"); - } - determineEndianness(); - - mReadWriteHeader = false; - - const Chunk* c = readChunkBegin(); - // endian should be flipped now - assert(c->id == HEADER_ID); + } + + checkStream(); + + } + //--------------------------------------------------------------------- + StreamSerialiser::~StreamSerialiser() + { + // really this should be empty if read/write was complete, but be tidy + if (!mChunkStack.empty()) + { + LogManager::getSingleton().stream() << + "Warning: stream " << mStream->getName() << " was not fully read / written; " << + mChunkStack.size() << " chunks remain unterminated."; + } + for (ChunkStack::iterator i = mChunkStack.begin(); i != mChunkStack.end(); ++i) + delete *i; + mChunkStack.clear(); + + } + //--------------------------------------------------------------------- + uint32 StreamSerialiser::makeIdentifier(const String& code) + { + assert(code.length() <= 4 && "Characters after the 4th are being ignored"); + uint32 ret = 0; + size_t c = std::min((size_t)4, code.length()); + for (size_t i = 0; i < c; ++i) + { + ret += (code.at(i) << (i * 8)); + } + return ret; + + } + //--------------------------------------------------------------------- + uint32 StreamSerialiser::getCurrentChunkID() const + { + if (mChunkStack.empty()) + return 0; + else + return mChunkStack.back()->id; + } + //--------------------------------------------------------------------- + const StreamSerialiser::Chunk* StreamSerialiser::readChunkBegin() + { + // Have we figured out the endian mode yet? + if (mReadWriteHeader) + readHeader(); + + if (mEndian == ENDIAN_AUTO) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Endian mode has not been determined, did you disable header without setting?", + "StreamSerialiser::readChunkBegin"); + + Chunk* chunk = readChunkImpl(); + mChunkStack.push_back(chunk); + + return chunk; + + } + //--------------------------------------------------------------------- + const StreamSerialiser::Chunk* StreamSerialiser::readChunkBegin( + uint32 id, uint16 maxVersion, const String& msg) + { + const Chunk* c = readChunkBegin(); + if (c->id != id) + { + // rewind + undoReadChunk(c->id); + return 0; + } + else if (c->version > maxVersion) + { + LogManager::getSingleton().stream() << "Error: " << msg + << " : Data version is " << c->version << " but this software can only read " + << "up to version " << maxVersion; + // skip + readChunkEnd(c->id); + return 0; + } + + return c; + + } + //--------------------------------------------------------------------- + void StreamSerialiser::undoReadChunk(uint32 id) + { + Chunk* c = popChunk(id); + + checkStream(); + + mStream->seek(c->offset); + + OGRE_DELETE c; + + } + //--------------------------------------------------------------------- + uint32 StreamSerialiser::peekNextChunkID() + { + checkStream(); + + if (eof()) + return 0; + + // Have we figured out the endian mode yet? + if (mReadWriteHeader) + readHeader(); + + if (mEndian == ENDIAN_AUTO) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Endian mode has not been determined, did you disable header without setting?", + "StreamSerialiser::peekNextChunkID"); + + size_t homePos = mStream->tell(); + uint32 ret; + read(&ret); + mStream->seek(homePos); + + return ret; + } + //--------------------------------------------------------------------- + void StreamSerialiser::readChunkEnd(uint32 id) + { + Chunk* c = popChunk(id); + + checkStream(); + + // skip to the end of the chunk if we were not there already + // this lets us quite reading a chunk anywhere and have the read marker + // automatically skip to the next one + if (mStream->tell() < (c->offset + CHUNK_HEADER_SIZE + c->length)) + mStream->seek(c->offset + CHUNK_HEADER_SIZE + c->length); + + OGRE_DELETE c; + } + //--------------------------------------------------------------------- + bool StreamSerialiser::isEndOfChunk(uint32 id) + { + const Chunk* c = getCurrentChunk(); + assert(c->id == id); + return mStream->tell() == (c->offset + CHUNK_HEADER_SIZE + c->length); + } + //--------------------------------------------------------------------- + void StreamSerialiser::readHeader() + { + uint32 headerid; + size_t actually_read = mStream->read(&headerid, sizeof(uint32)); + // skip back + mStream->skip(0 - (long)actually_read); + // validate that this is a header chunk + if (headerid == REVERSE_HEADER_ID) + { + mFlipEndian = true; + } + else if (headerid == HEADER_ID) + { + mFlipEndian = false; + } + else + { + // no good + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Cannot determine endian mode because header is missing", + "StreamSerialiser::readHeader"); + } + determineEndianness(); + + mReadWriteHeader = false; + + const Chunk* c = readChunkBegin(); + // endian should be flipped now + assert(c->id == HEADER_ID); (void)c; // Silence warning - // read real storage format - bool realIsDouble; - read(&realIsDouble); - mRealFormat = realIsDouble? REAL_DOUBLE : REAL_FLOAT; + // read real storage format + bool realIsDouble; + read(&realIsDouble); + mRealFormat = realIsDouble? REAL_DOUBLE : REAL_FLOAT; - readChunkEnd(HEADER_ID); + readChunkEnd(HEADER_ID); - } - //--------------------------------------------------------------------- - void StreamSerialiser::determineEndianness() - { + } + //--------------------------------------------------------------------- + void StreamSerialiser::determineEndianness() + { #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - if (mFlipEndian) - mEndian = ENDIAN_LITTLE; - else - mEndian = ENDIAN_BIG; + if (mFlipEndian) + mEndian = ENDIAN_LITTLE; + else + mEndian = ENDIAN_BIG; #else - if (mFlipEndian) - mEndian = ENDIAN_BIG; - else - mEndian = ENDIAN_LITTLE; + if (mFlipEndian) + mEndian = ENDIAN_BIG; + else + mEndian = ENDIAN_LITTLE; #endif - } - //--------------------------------------------------------------------- - const StreamSerialiser::Chunk* StreamSerialiser::getCurrentChunk() const - { - if (mChunkStack.empty()) - return 0; - else - return mChunkStack.back(); - } - //--------------------------------------------------------------------- - bool StreamSerialiser::eof() const - { - checkStream(); - return mStream->eof(); - } - //--------------------------------------------------------------------- - void StreamSerialiser::checkStream(bool failOnEof, bool validateReadable, bool validateWriteable) const - { - if (mStream.isNull()) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Invalid operation, stream is null", "StreamSerialiser::checkStream"); - - if (failOnEof && mStream->eof()) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Invalid operation, end of file on stream", "StreamSerialiser::checkStream"); - - if (validateReadable && !mStream->isReadable()) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Invalid operation, file is not readable", "StreamSerialiser::checkStream"); - - if (validateWriteable && !mStream->isWriteable()) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Invalid operation, file is not writeable", "StreamSerialiser::checkStream"); - } - //--------------------------------------------------------------------- - void StreamSerialiser::writeHeader() - { - if (mEndian == ENDIAN_AUTO) - determineEndianness(); - - // Header chunk has zero data size - writeChunkImpl(HEADER_ID, 1); - - // real format - bool realIsDouble = (mRealFormat == REAL_DOUBLE); - write(&realIsDouble); - - writeChunkEnd(HEADER_ID); - - mReadWriteHeader = false; - } - //--------------------------------------------------------------------- - void StreamSerialiser::writeChunkBegin(uint32 id, uint16 version /* = 1 */) - { - checkStream(false, false, true); - - if (mReadWriteHeader) - writeHeader(); - - if (mEndian == ENDIAN_AUTO) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Endian mode has not been determined, did you disable header without setting?", - "StreamSerialiser::writeChunkBegin"); - - writeChunkImpl(id, version); - - } - //--------------------------------------------------------------------- - void StreamSerialiser::writeChunkEnd(uint32 id) - { - checkStream(false, false, true); - - Chunk* c = popChunk(id); - - // update the sizes - size_t currPos = mStream->tell(); - c->length = static_cast(currPos - c->offset - CHUNK_HEADER_SIZE); - - // seek to 'length' position in stream for this chunk - // skip id (32) and version (16) - mStream->seek(c->offset + sizeof(uint32) + sizeof(uint16)); - write(&c->length); - // write updated checksum - uint32 checksum = calculateChecksum(c); - write(&checksum); - - // seek back to previous position - mStream->seek(currPos); - - OGRE_DELETE c; - - } - //--------------------------------------------------------------------- - size_t StreamSerialiser::getOffsetFromChunkStart() const - { - checkStream(false, false, false); - - if (mChunkStack.empty()) - { - return 0; - } - else - { - size_t pos = mStream->tell(); - size_t diff = pos - mChunkStack.back()->offset; - if(diff >= CHUNK_HEADER_SIZE) - return diff - CHUNK_HEADER_SIZE; - else - return 0; // not in a chunk? - - } - - } - //--------------------------------------------------------------------- - StreamSerialiser::Chunk* StreamSerialiser::readChunkImpl() - { - Chunk *chunk = OGRE_NEW Chunk(); - chunk->offset = static_cast(mStream->tell()); - read(&chunk->id); - read(&chunk->version); - read(&chunk->length); - - uint32 checksum; - read(&checksum); - - if (checksum != calculateChecksum(chunk)) - { - // no good, this is an invalid chunk - uint32 off = chunk->offset; - OGRE_DELETE chunk; - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Corrupt chunk detected in stream " + mStream->getName() + " at byte " - + StringConverter::toString(off), - "StreamSerialiser::readChunkImpl"); - } - else - { - return chunk; - } - - - } - //--------------------------------------------------------------------- - void StreamSerialiser::writeChunkImpl(uint32 id, uint16 version) - { - Chunk* c = OGRE_NEW Chunk(); - c->id = id; - c->version = version; - c->offset = static_cast(mStream->tell()); - c->length = 0; - - mChunkStack.push_back(c); - - write(&c->id); - write(&c->version); - write(&c->length); - // write length again, this is just a placeholder for the checksum (to come later) - write(&c->length); - - } - //--------------------------------------------------------------------- - void StreamSerialiser::writeData(const void* buf, size_t size, size_t count) - { - checkStream(false, false, true); - - size_t totSize = size * count; - if (mFlipEndian) - { - void* pToWrite = OGRE_MALLOC(totSize, MEMCATEGORY_GENERAL); - memcpy(pToWrite, buf, totSize); - - flipEndian(pToWrite, size, count); - mStream->write(pToWrite, totSize); - - OGRE_FREE(pToWrite, MEMCATEGORY_GENERAL); - } - else - { - mStream->write(buf, totSize); - } - - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Vector2* vec, size_t count) - { - for (size_t i = 0; i < count; ++i, ++vec) - write(vec->ptr(), 2); - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Vector3* vec, size_t count) - { - for (size_t i = 0; i < count; ++i, ++vec) - write(vec->ptr(), 3); - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Vector4* vec, size_t count) - { - for (size_t i = 0; i < count; ++i, ++vec) - write(vec->ptr(), 4); - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Quaternion* q, size_t count) - { - for (size_t i = 0; i < count; ++i, ++q) - write(q->ptr(), 4); - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const String* string) - { - // uint32 of size first, then (unterminated) string - uint32 len = static_cast(string->length()); - write(&len); - mStream->write(string->c_str(), len); - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Matrix3* m, size_t count) - { - for (size_t i = 0; i < count; ++i, ++m) - write((*m)[0], 9); - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Matrix4* m, size_t count) - { - for (size_t i = 0; i < count; ++i, ++m) - write((*m)[0], 12); - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const AxisAlignedBox* aabb, size_t count) - { - for (size_t i = 0; i < count; ++i, ++aabb) - { - bool infinite = aabb->isInfinite(); - write(&infinite); - write(&aabb->getMinimum()); - write(&aabb->getMaximum()); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Sphere* sphere, size_t count) - { - - for (size_t i = 0; i < count; ++i, ++sphere) - { - write(&sphere->getCenter()); - Real radius = sphere->getRadius(); - write(&radius); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Plane* plane, size_t count) - { - for (size_t i = 0; i < count; ++i, ++plane) - { - write(&plane->normal); - write(&plane->d); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Ray* ray, size_t count) - { - for (size_t i = 0; i < count; ++i, ++ray) - { - write(&ray->getOrigin()); - write(&ray->getDirection()); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Radian* rad, size_t count) - { - for (size_t i = 0; i < count; ++i, ++rad) - { - Real r = rad->valueRadians(); - write(&r); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Node* node, size_t count) - { - for (size_t i = 0; i < count; ++i, ++node) - { - write(&node->getPosition()); - write(&node->getOrientation()); - write(&node->getScale()); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const bool* val, size_t count) - { - for (size_t i = 0; i < count; ++i, ++val) - { - char c = (*val)? 1 : 0; - write(&c); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::write(const Real* val, size_t count) - { + } + //--------------------------------------------------------------------- + const StreamSerialiser::Chunk* StreamSerialiser::getCurrentChunk() const + { + if (mChunkStack.empty()) + return 0; + else + return mChunkStack.back(); + } + //--------------------------------------------------------------------- + bool StreamSerialiser::eof() const + { + checkStream(); + return mStream->eof(); + } + //--------------------------------------------------------------------- + void StreamSerialiser::checkStream(bool failOnEof, bool validateReadable, bool validateWriteable) const + { + if (mStream.isNull()) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Invalid operation, stream is null", "StreamSerialiser::checkStream"); + + if (failOnEof && mStream->eof()) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Invalid operation, end of file on stream", "StreamSerialiser::checkStream"); + + if (validateReadable && !mStream->isReadable()) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Invalid operation, file is not readable", "StreamSerialiser::checkStream"); + + if (validateWriteable && !mStream->isWriteable()) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Invalid operation, file is not writeable", "StreamSerialiser::checkStream"); + } + //--------------------------------------------------------------------- + void StreamSerialiser::writeHeader() + { + if (mEndian == ENDIAN_AUTO) + determineEndianness(); + + // Header chunk has zero data size + writeChunkImpl(HEADER_ID, 1); + + // real format + bool realIsDouble = (mRealFormat == REAL_DOUBLE); + write(&realIsDouble); + + writeChunkEnd(HEADER_ID); + + mReadWriteHeader = false; + } + //--------------------------------------------------------------------- + void StreamSerialiser::writeChunkBegin(uint32 id, uint16 version /* = 1 */) + { + checkStream(false, false, true); + + if (mReadWriteHeader) + writeHeader(); + + if (mEndian == ENDIAN_AUTO) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Endian mode has not been determined, did you disable header without setting?", + "StreamSerialiser::writeChunkBegin"); + + writeChunkImpl(id, version); + + } + //--------------------------------------------------------------------- + void StreamSerialiser::writeChunkEnd(uint32 id) + { + checkStream(false, false, true); + + Chunk* c = popChunk(id); + + // update the sizes + size_t currPos = mStream->tell(); + c->length = static_cast(currPos - c->offset - CHUNK_HEADER_SIZE); + + // seek to 'length' position in stream for this chunk + // skip id (32) and version (16) + mStream->seek(c->offset + sizeof(uint32) + sizeof(uint16)); + write(&c->length); + // write updated checksum + uint32 checksum = calculateChecksum(c); + write(&checksum); + + // seek back to previous position + mStream->seek(currPos); + + OGRE_DELETE c; + + } + //--------------------------------------------------------------------- + size_t StreamSerialiser::getOffsetFromChunkStart() const + { + checkStream(false, false, false); + + if (mChunkStack.empty()) + { + return 0; + } + else + { + size_t pos = mStream->tell(); + size_t diff = pos - mChunkStack.back()->offset; + if(diff >= CHUNK_HEADER_SIZE) + return diff - CHUNK_HEADER_SIZE; + else + return 0; // not in a chunk? + + } + + } + //--------------------------------------------------------------------- + StreamSerialiser::Chunk* StreamSerialiser::readChunkImpl() + { + Chunk *chunk = OGRE_NEW Chunk(); + chunk->offset = static_cast(mStream->tell()); + read(&chunk->id); + read(&chunk->version); + read(&chunk->length); + + uint32 checksum; + read(&checksum); + + if (checksum != calculateChecksum(chunk)) + { + // no good, this is an invalid chunk + uint32 off = chunk->offset; + OGRE_DELETE chunk; + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Corrupt chunk detected in stream " + mStream->getName() + " at byte " + + StringConverter::toString(off), + "StreamSerialiser::readChunkImpl"); + } + else + { + return chunk; + } + + + } + //--------------------------------------------------------------------- + void StreamSerialiser::writeChunkImpl(uint32 id, uint16 version) + { + Chunk* c = OGRE_NEW Chunk(); + c->id = id; + c->version = version; + c->offset = static_cast(mStream->tell()); + c->length = 0; + + mChunkStack.push_back(c); + + write(&c->id); + write(&c->version); + write(&c->length); + // write length again, this is just a placeholder for the checksum (to come later) + write(&c->length); + + } + //--------------------------------------------------------------------- + void StreamSerialiser::writeData(const void* buf, size_t size, size_t count) + { + checkStream(false, false, true); + + size_t totSize = size * count; + if (mFlipEndian) + { + void* pToWrite = OGRE_MALLOC(totSize, MEMCATEGORY_GENERAL); + memcpy(pToWrite, buf, totSize); + + flipEndian(pToWrite, size, count); + mStream->write(pToWrite, totSize); + + OGRE_FREE(pToWrite, MEMCATEGORY_GENERAL); + } + else + { + mStream->write(buf, totSize); + } + + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Vector2* vec, size_t count) + { + for (size_t i = 0; i < count; ++i, ++vec) + write(vec->ptr(), 2); + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Vector3* vec, size_t count) + { + for (size_t i = 0; i < count; ++i, ++vec) + write(vec->ptr(), 3); + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Vector4* vec, size_t count) + { + for (size_t i = 0; i < count; ++i, ++vec) + write(vec->ptr(), 4); + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Quaternion* q, size_t count) + { + for (size_t i = 0; i < count; ++i, ++q) + write(q->ptr(), 4); + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const String* string) + { + // uint32 of size first, then (unterminated) string + uint32 len = static_cast(string->length()); + write(&len); + mStream->write(string->c_str(), len); + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Matrix3* m, size_t count) + { + for (size_t i = 0; i < count; ++i, ++m) + write((*m)[0], 9); + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Matrix4* m, size_t count) + { + for (size_t i = 0; i < count; ++i, ++m) + write((*m)[0], 12); + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const AxisAlignedBox* aabb, size_t count) + { + for (size_t i = 0; i < count; ++i, ++aabb) + { + bool infinite = aabb->isInfinite(); + write(&infinite); + write(&aabb->getMinimum()); + write(&aabb->getMaximum()); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Sphere* sphere, size_t count) + { + + for (size_t i = 0; i < count; ++i, ++sphere) + { + write(&sphere->getCenter()); + Real radius = sphere->getRadius(); + write(&radius); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Plane* plane, size_t count) + { + for (size_t i = 0; i < count; ++i, ++plane) + { + write(&plane->normal); + write(&plane->d); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Ray* ray, size_t count) + { + for (size_t i = 0; i < count; ++i, ++ray) + { + write(&ray->getOrigin()); + write(&ray->getDirection()); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Radian* rad, size_t count) + { + for (size_t i = 0; i < count; ++i, ++rad) + { + Real r = rad->valueRadians(); + write(&r); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Node* node, size_t count) + { + for (size_t i = 0; i < count; ++i, ++node) + { + write(&node->getPosition()); + write(&node->getOrientation()); + write(&node->getScale()); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const bool* val, size_t count) + { + for (size_t i = 0; i < count; ++i, ++val) + { + char c = (*val)? 1 : 0; + write(&c); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::write(const Real* val, size_t count) + { #if OGRE_DOUBLE_PRECISION - if (mRealFormat == REAL_DOUBLE) - writeData(val, sizeof(double), count); - else - writeDoublesAsFloats(val, count); + if (mRealFormat == REAL_DOUBLE) + writeData(val, sizeof(double), count); + else + writeDoublesAsFloats(val, count); #else - if (mRealFormat == REAL_FLOAT) - writeData(val, sizeof(float), count); - else - writeFloatsAsDoubles(val, count); + if (mRealFormat == REAL_FLOAT) + writeData(val, sizeof(float), count); + else + writeFloatsAsDoubles(val, count); #endif - } - //--------------------------------------------------------------------- - void StreamSerialiser::readData(void* buf, size_t size, size_t count) - { - checkStream(true, true, false); - - size_t totSize = size * count; - mStream->read(buf, totSize); - - if (mFlipEndian) - flipEndian(buf, size, count); - - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Vector2* vec, size_t count) - { - for (size_t i = 0; i < count; ++i, ++vec) - { - read(vec->ptr(), 2); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Vector3* vec, size_t count) - { - for (size_t i = 0; i < count; ++i, ++vec) - { - read(vec->ptr(), 3); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Vector4* vec, size_t count) - { - for (size_t i = 0; i < count; ++i, ++vec) - { - read(vec->ptr(), 4); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Quaternion* q, size_t count) - { - for (size_t i = 0; i < count; ++i, ++q) - { - read(q->ptr(), 4); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Matrix3* m, size_t count) - { - for (size_t i = 0; i < count; ++i, ++m) - { - read((*m)[0], 9); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Matrix4* m, size_t count) - { - for (size_t i = 0; i < count; ++i, ++m) - { - read((*m)[0], 12); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(String* string) - { - // String is stored as a uint32 character count, then string - uint32 len; - read(&len); - string->resize(len); - if (len) - read(&(*string->begin()), len); - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Real* val, size_t count) - { + } + //--------------------------------------------------------------------- + void StreamSerialiser::readData(void* buf, size_t size, size_t count) + { + checkStream(true, true, false); + + size_t totSize = size * count; + mStream->read(buf, totSize); + + if (mFlipEndian) + flipEndian(buf, size, count); + + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Vector2* vec, size_t count) + { + for (size_t i = 0; i < count; ++i, ++vec) + { + read(vec->ptr(), 2); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Vector3* vec, size_t count) + { + for (size_t i = 0; i < count; ++i, ++vec) + { + read(vec->ptr(), 3); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Vector4* vec, size_t count) + { + for (size_t i = 0; i < count; ++i, ++vec) + { + read(vec->ptr(), 4); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Quaternion* q, size_t count) + { + for (size_t i = 0; i < count; ++i, ++q) + { + read(q->ptr(), 4); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Matrix3* m, size_t count) + { + for (size_t i = 0; i < count; ++i, ++m) + { + read((*m)[0], 9); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Matrix4* m, size_t count) + { + for (size_t i = 0; i < count; ++i, ++m) + { + read((*m)[0], 12); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(String* string) + { + // String is stored as a uint32 character count, then string + uint32 len; + read(&len); + string->resize(len); + if (len) + read(&(*string->begin()), len); + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Real* val, size_t count) + { #if OGRE_DOUBLE_PRECISION - if (mRealFormat == REAL_DOUBLE) - readData(val, sizeof(double), count); - else - readFloatsAsDoubles(val, count); + if (mRealFormat == REAL_DOUBLE) + readData(val, sizeof(double), count); + else + readFloatsAsDoubles(val, count); #else - if (mRealFormat == REAL_FLOAT) - readData(val, sizeof(float), count); - else - readDoublesAsFloats(val, count); + if (mRealFormat == REAL_FLOAT) + readData(val, sizeof(float), count); + else + readDoublesAsFloats(val, count); #endif - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(AxisAlignedBox* aabb, size_t count) - { - for (size_t i = 0; i < count; ++i, ++aabb) - { - bool infinite = false; - read(&infinite); - Vector3 tmpMin, tmpMax; - read(&tmpMin); - read(&tmpMax); - - if (infinite) - aabb->setInfinite(); - else - aabb->setExtents(tmpMin, tmpMax); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Sphere* sphere, size_t count) - { - for (size_t i = 0; i < count; ++i, ++sphere) - { - Vector3 center; - Real radius; - read(¢er); - read(&radius); - sphere->setCenter(center); - sphere->setRadius(radius); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Plane* plane, size_t count) - { - for (size_t i = 0; i < count; ++i, ++plane) - { - read(&plane->normal); - read(&plane->d); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Ray* ray, size_t count) - { - for (size_t i = 0; i < count; ++i, ++ray) - { - Vector3 origin, dir; - read(&origin); - read(&dir); - ray->setOrigin(origin); - ray->setDirection(dir); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Radian* angle, size_t count) - { - for (size_t i = 0; i < count; ++i, ++angle) - { - Real rads; - read(&rads); - *angle = Radian(rads); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(Node* node, size_t count) - { - for (size_t i = 0; i < count; ++i, ++node) - { - Vector3 pos, scale; - Quaternion orient; - read(&pos); - read(&orient); - read(&scale); - node->setPosition(pos); - node->setOrientation(orient); - node->setScale(scale); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::read(bool* val, size_t count) - { - for (size_t i = 0; i < count; ++i, ++val) - { - char c; - read(&c); - *val = (c == 1); - } - } - //--------------------------------------------------------------------- - void StreamSerialiser::writeFloatsAsDoubles(const float* val, size_t count) - { - double t = 0; - writeConverted(val, t, count); - } - //--------------------------------------------------------------------- - void StreamSerialiser::writeDoublesAsFloats(const double* val, size_t count) - { - float t = 0; - writeConverted(val, t, count); - } - //--------------------------------------------------------------------- - void StreamSerialiser::readFloatsAsDoubles(double* val, size_t count) - { - float t = 0; - readConverted(val, t, count); - } - //--------------------------------------------------------------------- - void StreamSerialiser::readDoublesAsFloats(float* val, size_t count) - { - double t = 0; - readConverted(val, t, count); - } - - //--------------------------------------------------------------------- - void StreamSerialiser::flipEndian(void * pBase, size_t size, size_t count) - { - for (size_t c = 0; c < count; ++c) - { - void *pData = (void *)((intptr_t)pBase + (c * size)); - for(size_t byteIndex = 0; byteIndex < size/2; byteIndex++) - { - char swapByte = *(char *)((intptr_t)pData + byteIndex); - *(char *)((intptr_t)pData + byteIndex) = - *(char *)((intptr_t)pData + size - byteIndex - 1); - *(char *)((intptr_t)pData + size - byteIndex - 1) = swapByte; - } - } - - } - //--------------------------------------------------------------------- - void StreamSerialiser::flipEndian(void * pData, size_t size) - { - flipEndian(pData, size, 1); - } - //--------------------------------------------------------------------- - uint32 StreamSerialiser::calculateChecksum(Chunk* c) - { - // Always calculate checksums in little endian to make sure they match - // Otherwise checksums for the same data on different endians will not match - uint32 id = c->id; - uint16 version = c->version; - uint32 length = c->length; + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(AxisAlignedBox* aabb, size_t count) + { + for (size_t i = 0; i < count; ++i, ++aabb) + { + bool infinite = false; + read(&infinite); + Vector3 tmpMin, tmpMax; + read(&tmpMin); + read(&tmpMax); + + if (infinite) + aabb->setInfinite(); + else + aabb->setExtents(tmpMin, tmpMax); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Sphere* sphere, size_t count) + { + for (size_t i = 0; i < count; ++i, ++sphere) + { + Vector3 center; + Real radius; + read(¢er); + read(&radius); + sphere->setCenter(center); + sphere->setRadius(radius); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Plane* plane, size_t count) + { + for (size_t i = 0; i < count; ++i, ++plane) + { + read(&plane->normal); + read(&plane->d); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Ray* ray, size_t count) + { + for (size_t i = 0; i < count; ++i, ++ray) + { + Vector3 origin, dir; + read(&origin); + read(&dir); + ray->setOrigin(origin); + ray->setDirection(dir); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Radian* angle, size_t count) + { + for (size_t i = 0; i < count; ++i, ++angle) + { + Real rads; + read(&rads); + *angle = Radian(rads); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(Node* node, size_t count) + { + for (size_t i = 0; i < count; ++i, ++node) + { + Vector3 pos, scale; + Quaternion orient; + read(&pos); + read(&orient); + read(&scale); + node->setPosition(pos); + node->setOrientation(orient); + node->setScale(scale); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::read(bool* val, size_t count) + { + for (size_t i = 0; i < count; ++i, ++val) + { + char c; + read(&c); + *val = (c == 1); + } + } + //--------------------------------------------------------------------- + void StreamSerialiser::writeFloatsAsDoubles(const float* val, size_t count) + { + double t = 0; + writeConverted(val, t, count); + } + //--------------------------------------------------------------------- + void StreamSerialiser::writeDoublesAsFloats(const double* val, size_t count) + { + float t = 0; + writeConverted(val, t, count); + } + //--------------------------------------------------------------------- + void StreamSerialiser::readFloatsAsDoubles(double* val, size_t count) + { + float t = 0; + readConverted(val, t, count); + } + //--------------------------------------------------------------------- + void StreamSerialiser::readDoublesAsFloats(float* val, size_t count) + { + double t = 0; + readConverted(val, t, count); + } + + //--------------------------------------------------------------------- + void StreamSerialiser::flipEndian(void * pBase, size_t size, size_t count) + { + for (size_t c = 0; c < count; ++c) + { + void *pData = (void *)((intptr_t)pBase + (c * size)); + for(size_t byteIndex = 0; byteIndex < size/2; byteIndex++) + { + char swapByte = *(char *)((intptr_t)pData + byteIndex); + *(char *)((intptr_t)pData + byteIndex) = + *(char *)((intptr_t)pData + size - byteIndex - 1); + *(char *)((intptr_t)pData + size - byteIndex - 1) = swapByte; + } + } + + } + //--------------------------------------------------------------------- + void StreamSerialiser::flipEndian(void * pData, size_t size) + { + flipEndian(pData, size, 1); + } + //--------------------------------------------------------------------- + uint32 StreamSerialiser::calculateChecksum(Chunk* c) + { + // Always calculate checksums in little endian to make sure they match + // Otherwise checksums for the same data on different endians will not match + uint32 id = c->id; + uint16 version = c->version; + uint32 length = c->length; #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - flipEndian(&id, sizeof(uint32)); - flipEndian(&version, sizeof(uint16)); - flipEndian(&length, sizeof(uint32)); + flipEndian(&id, sizeof(uint32)); + flipEndian(&version, sizeof(uint16)); + flipEndian(&length, sizeof(uint32)); #endif - uint32 hashVal = FastHash((const char*)&id, sizeof(uint32)); - hashVal = FastHash((const char*)&version, sizeof(uint16), hashVal); - hashVal = FastHash((const char*)&length, sizeof(uint32), hashVal); - - return hashVal; - } - //--------------------------------------------------------------------- - StreamSerialiser::Chunk* StreamSerialiser::popChunk(uint id) - { - if (mChunkStack.empty()) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "No active chunk!", "StreamSerialiser::popChunk"); - - const Chunk* chunk = mChunkStack.back(); - if (chunk->id != id) - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, - "Incorrect chunk id!", "StreamSerialiser::popChunk"); - - Chunk* c = mChunkStack.back(); - mChunkStack.pop_back(); - return c; - - } - void StreamSerialiser::startDeflate(size_t avail_in) - { + uint32 hashVal = FastHash((const char*)&id, sizeof(uint32)); + hashVal = FastHash((const char*)&version, sizeof(uint16), hashVal); + hashVal = FastHash((const char*)&length, sizeof(uint32), hashVal); + + return hashVal; + } + //--------------------------------------------------------------------- + StreamSerialiser::Chunk* StreamSerialiser::popChunk(uint id) + { + if (mChunkStack.empty()) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "No active chunk!", "StreamSerialiser::popChunk"); + + const Chunk* chunk = mChunkStack.back(); + if (chunk->id != id) + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, + "Incorrect chunk id!", "StreamSerialiser::popChunk"); + + Chunk* c = mChunkStack.back(); + mChunkStack.pop_back(); + return c; + + } + void StreamSerialiser::startDeflate(size_t avail_in) + { #if OGRE_NO_ZIP_ARCHIVE == 0 - assert( mOriginalStream.isNull() && "Don't start (un)compressing twice!" ); - DataStreamPtr deflateStream(OGRE_NEW DeflateStream(mStream,"",avail_in)); - mOriginalStream = mStream; - mStream = deflateStream; + assert( mOriginalStream.isNull() && "Don't start (un)compressing twice!" ); + DataStreamPtr deflateStream(OGRE_NEW DeflateStream(mStream,"",avail_in)); + mOriginalStream = mStream; + mStream = deflateStream; #else OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Ogre was not built with Zip file support!", "StreamSerialiser::startDeflate"); #endif - } - void StreamSerialiser::stopDeflate() - { + } + void StreamSerialiser::stopDeflate() + { #if OGRE_NO_ZIP_ARCHIVE == 0 - assert( !mOriginalStream.isNull() && "Must start (un)compressing first!" ); - mStream = mOriginalStream; - mOriginalStream.setNull(); + assert( !mOriginalStream.isNull() && "Must start (un)compressing first!" ); + mStream = mOriginalStream; + mOriginalStream.setNull(); #else OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Ogre was not built with Zip file support!", "StreamSerialiser::stopDeflate"); #endif - } + } } diff --git a/OgreMain/src/OgreString.cpp b/OgreMain/src/OgreString.cpp index e7ee6cda8dc..16c28240a82 100644 --- a/OgreMain/src/OgreString.cpp +++ b/OgreMain/src/OgreString.cpp @@ -30,7 +30,7 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void StringUtil::trim(String& str, bool left, bool right) { /* @@ -123,67 +123,67 @@ namespace Ogre { return ret; } - //----------------------------------------------------------------------- - StringVector StringUtil::tokenise( const String& str, const String& singleDelims, const String& doubleDelims, unsigned int maxSplits) - { + //----------------------------------------------------------------------- + StringVector StringUtil::tokenise( const String& str, const String& singleDelims, const String& doubleDelims, unsigned int maxSplits) + { StringVector ret; // Pre-allocate some space for performance ret.reserve(maxSplits ? maxSplits+1 : 10); // 10 is guessed capacity for most case unsigned int numSplits = 0; - String delims = singleDelims + doubleDelims; + String delims = singleDelims + doubleDelims; - // Use STL methods + // Use STL methods size_t start, pos; - char curDoubleDelim = 0; + char curDoubleDelim = 0; start = 0; do { - if (curDoubleDelim != 0) - { - pos = str.find(curDoubleDelim, start); - } - else - { - pos = str.find_first_of(delims, start); - } + if (curDoubleDelim != 0) + { + pos = str.find(curDoubleDelim, start); + } + else + { + pos = str.find_first_of(delims, start); + } if (pos == start) { - char curDelim = str.at(pos); - if (doubleDelims.find_first_of(curDelim) != String::npos) - { - curDoubleDelim = curDelim; - } + char curDelim = str.at(pos); + if (doubleDelims.find_first_of(curDelim) != String::npos) + { + curDoubleDelim = curDelim; + } // Do nothing start = pos + 1; } else if (pos == String::npos || (maxSplits && numSplits == maxSplits)) { - if (curDoubleDelim != 0) - { - //Missing closer. Warn or throw exception? - } + if (curDoubleDelim != 0) + { + //Missing closer. Warn or throw exception? + } // Copy the rest of the string ret.push_back( str.substr(start) ); break; } else { - if (curDoubleDelim != 0) - { - curDoubleDelim = 0; - } - - // Copy up to delimiter - ret.push_back( str.substr(start, pos - start) ); - start = pos + 1; + if (curDoubleDelim != 0) + { + curDoubleDelim = 0; + } + + // Copy up to delimiter + ret.push_back( str.substr(start, pos - start) ); + start = pos + 1; + } + if (curDoubleDelim == 0) + { + // parse up to next real data + start = str.find_first_not_of(singleDelims, start); } - if (curDoubleDelim == 0) - { - // parse up to next real data - start = str.find_first_not_of(singleDelims, start); - } ++numSplits; @@ -198,7 +198,7 @@ namespace Ogre { str.begin(), str.end(), str.begin(), - tolower); + tolower); } //----------------------------------------------------------------------- @@ -208,7 +208,7 @@ namespace Ogre { str.begin(), str.end(), str.begin(), - toupper); + toupper); } //----------------------------------------------------------------------- void StringUtil::toTitleCase(String& str) @@ -233,12 +233,12 @@ namespace Ogre { String startOfThis = str.substr(0, patternLen); if (lowerCase) - { - String lowerCasePattern = pattern; + { + String lowerCasePattern = pattern; StringUtil::toLowerCase(lowerCasePattern); StringUtil::toLowerCase(startOfThis); - return (startOfThis == lowerCasePattern); - } + return (startOfThis == lowerCasePattern); + } return (startOfThis == pattern); } @@ -252,12 +252,12 @@ namespace Ogre { String endOfThis = str.substr(thisLen - patternLen, patternLen); if (lowerCase) - { - String lowerCasePattern = pattern; + { + String lowerCasePattern = pattern; StringUtil::toLowerCase(lowerCasePattern); StringUtil::toLowerCase(endOfThis); - return (endOfThis == lowerCasePattern); - } + return (endOfThis == lowerCasePattern); + } return (endOfThis == pattern); } @@ -272,91 +272,91 @@ namespace Ogre { return path; } - //----------------------------------------------------------------------- - String StringUtil::normalizeFilePath(const String& init, bool makeLowerCase) - { - const char* bufferSrc = init.c_str(); - int pathLen = (int)init.size(); - int indexSrc = 0; - int indexDst = 0; - int metaPathArea = 0; - - char reservedBuf[1024]; - char* bufferDst = reservedBuf; - bool isDestAllocated = false; - if (pathLen > 1023) - { - //if source path is to long ensure we don't do a buffer overrun by allocating some - //new memory - isDestAllocated = true; - bufferDst = new char[pathLen + 1]; - } - - //The outer loop loops over directories - while (indexSrc < pathLen) - { - if ((bufferSrc[indexSrc] == '\\') || (bufferSrc[indexSrc] == '/')) - { - //check if we have a directory delimiter if so skip it (we should already - //have written such a delimiter by this point - ++indexSrc; - continue; - } - else - { - //check if there is a directory to skip of type ".\" - if ((bufferSrc[indexSrc] == '.') && - ((bufferSrc[indexSrc + 1] == '\\') || (bufferSrc[indexSrc + 1] == '/'))) - { - indexSrc += 2; - continue; - } - - //check if there is a directory to skip of type "..\" - else if ((bufferSrc[indexSrc] == '.') && (bufferSrc[indexSrc + 1] == '.') && - ((bufferSrc[indexSrc + 2] == '\\') || (bufferSrc[indexSrc + 2] == '/'))) - { - if (indexDst > metaPathArea) - { - //skip a directory backward in the destination path - do { - --indexDst; - } - while ((indexDst > metaPathArea) && (bufferDst[indexDst - 1] != '/')); - indexSrc += 3; - continue; - } - else - { - //we are about to write "..\" to the destination buffer - //ensure we will not remove this in future "skip directories" - metaPathArea += 3; - } - } - } - - //transfer the current directory name from the source to the destination - while (indexSrc < pathLen) - { - char curChar = bufferSrc[indexSrc]; - if (makeLowerCase) curChar = tolower(curChar); - if ((curChar == '\\') || (curChar == '/')) curChar = '/'; - bufferDst[indexDst] = curChar; - ++indexDst; - ++indexSrc; - if (curChar == '/') break; - } - } - bufferDst[indexDst] = 0; - - String normalized(bufferDst); - if (isDestAllocated) - { - delete[] bufferDst; - } - - return normalized; - } + //----------------------------------------------------------------------- + String StringUtil::normalizeFilePath(const String& init, bool makeLowerCase) + { + const char* bufferSrc = init.c_str(); + int pathLen = (int)init.size(); + int indexSrc = 0; + int indexDst = 0; + int metaPathArea = 0; + + char reservedBuf[1024]; + char* bufferDst = reservedBuf; + bool isDestAllocated = false; + if (pathLen > 1023) + { + //if source path is to long ensure we don't do a buffer overrun by allocating some + //new memory + isDestAllocated = true; + bufferDst = new char[pathLen + 1]; + } + + //The outer loop loops over directories + while (indexSrc < pathLen) + { + if ((bufferSrc[indexSrc] == '\\') || (bufferSrc[indexSrc] == '/')) + { + //check if we have a directory delimiter if so skip it (we should already + //have written such a delimiter by this point + ++indexSrc; + continue; + } + else + { + //check if there is a directory to skip of type ".\" + if ((bufferSrc[indexSrc] == '.') && + ((bufferSrc[indexSrc + 1] == '\\') || (bufferSrc[indexSrc + 1] == '/'))) + { + indexSrc += 2; + continue; + } + + //check if there is a directory to skip of type "..\" + else if ((bufferSrc[indexSrc] == '.') && (bufferSrc[indexSrc + 1] == '.') && + ((bufferSrc[indexSrc + 2] == '\\') || (bufferSrc[indexSrc + 2] == '/'))) + { + if (indexDst > metaPathArea) + { + //skip a directory backward in the destination path + do { + --indexDst; + } + while ((indexDst > metaPathArea) && (bufferDst[indexDst - 1] != '/')); + indexSrc += 3; + continue; + } + else + { + //we are about to write "..\" to the destination buffer + //ensure we will not remove this in future "skip directories" + metaPathArea += 3; + } + } + } + + //transfer the current directory name from the source to the destination + while (indexSrc < pathLen) + { + char curChar = bufferSrc[indexSrc]; + if (makeLowerCase) curChar = tolower(curChar); + if ((curChar == '\\') || (curChar == '/')) curChar = '/'; + bufferDst[indexDst] = curChar; + ++indexDst; + ++indexSrc; + if (curChar == '/') break; + } + } + bufferDst[indexDst] = 0; + + String normalized(bufferDst); + if (isDestAllocated) + { + delete[] bufferDst; + } + + return normalized; + } //----------------------------------------------------------------------- void StringUtil::splitFilename(const String& qualifiedName, String& outBasename, String& outPath) @@ -370,7 +370,7 @@ namespace Ogre { if (i == String::npos) { outPath.clear(); - outBasename = qualifiedName; + outBasename = qualifiedName; } else { @@ -379,35 +379,35 @@ namespace Ogre { } } - //----------------------------------------------------------------------- - void StringUtil::splitBaseFilename(const Ogre::String& fullName, - Ogre::String& outBasename, Ogre::String& outExtention) - { - size_t i = fullName.find_last_of("."); - if (i == Ogre::String::npos) - { - outExtention.clear(); - outBasename = fullName; - } - else - { - outExtention = fullName.substr(i+1); - outBasename = fullName.substr(0, i); - } - } - // ---------------------------------------------------------------------------------------------------------------------------------------------- - void StringUtil::splitFullFilename( const Ogre::String& qualifiedName, - Ogre::String& outBasename, Ogre::String& outExtention, Ogre::String& outPath ) - { - Ogre::String fullName; - splitFilename( qualifiedName, fullName, outPath ); - splitBaseFilename( fullName, outBasename, outExtention ); - } + //----------------------------------------------------------------------- + void StringUtil::splitBaseFilename(const Ogre::String& fullName, + Ogre::String& outBasename, Ogre::String& outExtention) + { + size_t i = fullName.find_last_of("."); + if (i == Ogre::String::npos) + { + outExtention.clear(); + outBasename = fullName; + } + else + { + outExtention = fullName.substr(i+1); + outBasename = fullName.substr(0, i); + } + } + // ---------------------------------------------------------------------------------------------------------------------------------------------- + void StringUtil::splitFullFilename( const Ogre::String& qualifiedName, + Ogre::String& outBasename, Ogre::String& outExtention, Ogre::String& outPath ) + { + Ogre::String fullName; + splitFilename( qualifiedName, fullName, outPath ); + splitBaseFilename( fullName, outBasename, outExtention ); + } //----------------------------------------------------------------------- bool StringUtil::match(const String& str, const String& pattern, bool caseSensitive) { String tmpStr = str; - String tmpPattern = pattern; + String tmpPattern = pattern; if (!caseSensitive) { StringUtil::toLowerCase(tmpStr); @@ -416,22 +416,22 @@ namespace Ogre { String::const_iterator strIt = tmpStr.begin(); String::const_iterator patIt = tmpPattern.begin(); - String::const_iterator lastWildCardIt = tmpPattern.end(); + String::const_iterator lastWildCardIt = tmpPattern.end(); while (strIt != tmpStr.end() && patIt != tmpPattern.end()) { if (*patIt == '*') { - lastWildCardIt = patIt; + lastWildCardIt = patIt; // Skip over looking for next character ++patIt; if (patIt == tmpPattern.end()) - { - // Skip right to the end since * matches the entire rest of the string - strIt = tmpStr.end(); - } - else { - // scan until we find next pattern character + // Skip right to the end since * matches the entire rest of the string + strIt = tmpStr.end(); + } + else + { + // scan until we find next pattern character while(strIt != tmpStr.end() && *strIt != *patIt) ++strIt; } @@ -440,18 +440,18 @@ namespace Ogre { { if (*patIt != *strIt) { - if (lastWildCardIt != tmpPattern.end()) - { - // The last wildcard can match this incorrect sequence - // rewind pattern to wildcard and keep searching - patIt = lastWildCardIt; - lastWildCardIt = tmpPattern.end(); - } - else - { - // no wildwards left - return false; - } + if (lastWildCardIt != tmpPattern.end()) + { + // The last wildcard can match this incorrect sequence + // rewind pattern to wildcard and keep searching + patIt = lastWildCardIt; + lastWildCardIt = tmpPattern.end(); + } + else + { + // no wildwards left + return false; + } } else { @@ -461,30 +461,30 @@ namespace Ogre { } } - // If we reached the end of both the pattern and the string, we succeeded - if (patIt == tmpPattern.end() && strIt == tmpStr.end()) - { - return true; - } - else - { - return false; - } + // If we reached the end of both the pattern and the string, we succeeded + if (patIt == tmpPattern.end() && strIt == tmpStr.end()) + { + return true; + } + else + { + return false; + } } - //----------------------------------------------------------------------- - const String StringUtil::replaceAll(const String& source, const String& replaceWhat, const String& replaceWithWhat) - { - String result = source; + //----------------------------------------------------------------------- + const String StringUtil::replaceAll(const String& source, const String& replaceWhat, const String& replaceWithWhat) + { + String result = source; String::size_type pos = 0; - while(1) - { - pos = result.find(replaceWhat,pos); - if (pos == String::npos) break; - result.replace(pos,replaceWhat.size(),replaceWithWhat); + while(1) + { + pos = result.find(replaceWhat,pos); + if (pos == String::npos) break; + result.replace(pos,replaceWhat.size(),replaceWithWhat); pos += replaceWithWhat.size(); - } - return result; - } + } + return result; + } } diff --git a/OgreMain/src/OgreStringInterface.cpp b/OgreMain/src/OgreStringInterface.cpp index 7a22fb67c87..f005c097aac 100644 --- a/OgreMain/src/OgreStringInterface.cpp +++ b/OgreMain/src/OgreStringInterface.cpp @@ -63,21 +63,21 @@ namespace Ogre { // Fallback return false; } - //----------------------------------------------------------------------- - void StringInterface::setParameterList(const NameValuePairList& paramList) - { - NameValuePairList::const_iterator i, iend; - iend = paramList.end(); - for (i = paramList.begin(); i != iend; ++i) - { - setParameter(i->first, i->second); - } - } //----------------------------------------------------------------------- - void StringInterface::cleanupDictionary () - { + void StringInterface::setParameterList(const NameValuePairList& paramList) + { + NameValuePairList::const_iterator i, iend; + iend = paramList.end(); + for (i = paramList.begin(); i != iend; ++i) + { + setParameter(i->first, i->second); + } + } + //----------------------------------------------------------------------- + void StringInterface::cleanupDictionary () + { OGRE_LOCK_MUTEX( msDictionaryMutex ); - msDictionary.clear(); - } + msDictionary.clear(); + } } diff --git a/OgreMain/src/OgreSubEntity.cpp b/OgreMain/src/OgreSubEntity.cpp index 5321f6608bd..4e778985e13 100644 --- a/OgreMain/src/OgreSubEntity.cpp +++ b/OgreMain/src/OgreSubEntity.cpp @@ -39,7 +39,7 @@ namespace Ogre { //----------------------------------------------------------------------- SubEntity::SubEntity (Entity* parent, SubMesh* subMeshBasis) : Renderable(), mParentEntity(parent), //mMaterialName("BaseWhite"), - mSubMesh(subMeshBasis), mMaterialLodIndex(0), mCachedCamera(0) + mSubMesh(subMeshBasis), mMaterialLodIndex(0), mCachedCamera(0) { //mMaterialPtr = MaterialManager::getSingleton().getByName(mMaterialName, subMeshBasis->parent->getGroup()); mVisible = true; @@ -48,10 +48,10 @@ namespace Ogre { mRenderQueuePrioritySet = false; mSkelAnimVertexData = 0; mVertexAnimationAppliedThisFrame = false; - mSoftwareVertexAnimVertexData = 0; - mHardwareVertexAnimVertexData = 0; - mHardwarePoseCount = 0; - mIndexStart = 0; + mSoftwareVertexAnimVertexData = 0; + mHardwareVertexAnimVertexData = 0; + mHardwarePoseCount = 0; + mIndexStart = 0; mIndexEnd = 0; } //----------------------------------------------------------------------- @@ -69,7 +69,7 @@ namespace Ogre { //----------------------------------------------------------------------- const String& SubEntity::getMaterialName(void) const { - return !mMaterialPtr.isNull() ? mMaterialPtr->getName() : BLANKSTRING; + return !mMaterialPtr.isNull() ? mMaterialPtr->getName() : BLANKSTRING; //return mMaterialName; } //----------------------------------------------------------------------- @@ -77,42 +77,42 @@ namespace Ogre { { - MaterialPtr material = MaterialManager::getSingleton().getByName(name, groupName); + MaterialPtr material = MaterialManager::getSingleton().getByName(name, groupName); - if( material.isNull() ) - { - LogManager::getSingleton().logMessage("Can't assign material " + name + - " to SubEntity of " + mParentEntity->getName() + " because this " - "Material does not exist. Have you forgotten to define it in a " - ".material script?", LML_CRITICAL); + if( material.isNull() ) + { + LogManager::getSingleton().logMessage("Can't assign material " + name + + " to SubEntity of " + mParentEntity->getName() + " because this " + "Material does not exist. Have you forgotten to define it in a " + ".material script?", LML_CRITICAL); - material = MaterialManager::getSingleton().getByName("BaseWhite"); + material = MaterialManager::getSingleton().getByName("BaseWhite"); - if (material.isNull()) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Can't assign default material " - "to SubEntity of " + mParentEntity->getName() + ". Did " - "you forget to call MaterialManager::initialise()?", - "SubEntity::setMaterialName"); - } - } + if (material.isNull()) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Can't assign default material " + "to SubEntity of " + mParentEntity->getName() + ". Did " + "you forget to call MaterialManager::initialise()?", + "SubEntity::setMaterialName"); + } + } setMaterial( material ); } - void SubEntity::setMaterial( const MaterialPtr& material ) - { - mMaterialPtr = material; - + void SubEntity::setMaterial( const MaterialPtr& material ) + { + mMaterialPtr = material; + if (mMaterialPtr.isNull()) { - LogManager::getSingleton().logMessage("Can't assign material " + LogManager::getSingleton().logMessage("Can't assign material " " to SubEntity of " + mParentEntity->getName() + " because this " "Material does not exist. Have you forgotten to define it in a " ".material script?", LML_CRITICAL); - - mMaterialPtr = MaterialManager::getSingleton().getByName("BaseWhite"); - + + mMaterialPtr = MaterialManager::getSingleton().getByName("BaseWhite"); + if (mMaterialPtr.isNull()) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Can't assign default material " @@ -121,13 +121,13 @@ namespace Ogre { "SubEntity::setMaterial"); } } - + // Ensure new material loaded (will not load again if already loaded) mMaterialPtr->load(); // tell parent to reconsider material vertex processing options mParentEntity->reevaluateVertexProcessing(); - } + } //----------------------------------------------------------------------- const MaterialPtr& SubEntity::getMaterial(void) const @@ -142,23 +142,23 @@ namespace Ogre { //----------------------------------------------------------------------- void SubEntity::getRenderOperation(RenderOperation& op) { - // Use LOD + // Use LOD mSubMesh->_getRenderOperation(op, mParentEntity->mMeshLodIndex); - // Deal with any vertex data overrides - op.vertexData = getVertexDataForBinding(); + // Deal with any vertex data overrides + op.vertexData = getVertexDataForBinding(); - // If we use custom index position the client is responsible to set meaningful values - if(mIndexStart != mIndexEnd) - { - op.indexData->indexStart = mIndexStart; - op.indexData->indexCount = mIndexEnd; - } + // If we use custom index position the client is responsible to set meaningful values + if(mIndexStart != mIndexEnd) + { + op.indexData->indexStart = mIndexStart; + op.indexData->indexCount = mIndexEnd; + } } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void SubEntity::setIndexDataStartIndex(size_t start_index) { - if(start_index < mSubMesh->indexData->indexCount) - mIndexStart = start_index; + if(start_index < mSubMesh->indexData->indexCount) + mIndexStart = start_index; } //----------------------------------------------------------------------- size_t SubEntity::getIndexDataStartIndex() const @@ -168,8 +168,8 @@ namespace Ogre { //----------------------------------------------------------------------- void SubEntity::setIndexDataEndIndex(size_t end_index) { - if(end_index > 0 && end_index <= mSubMesh->indexData->indexCount) - mIndexEnd = end_index; + if(end_index > 0 && end_index <= mSubMesh->indexData->indexCount) + mIndexEnd = end_index; } //----------------------------------------------------------------------- size_t SubEntity::getIndexDataEndIndex() const @@ -177,39 +177,39 @@ namespace Ogre { return mIndexEnd; } //----------------------------------------------------------------------- - void SubEntity::resetIndexDataStartEndIndex() - { - mIndexStart = 0; - mIndexEnd = 0; - } - //----------------------------------------------------------------------- - VertexData* SubEntity::getVertexDataForBinding(void) - { - if (mSubMesh->useSharedVertices) - { - return mParentEntity->getVertexDataForBinding(); - } - else - { - Entity::VertexDataBindChoice c = - mParentEntity->chooseVertexDataForBinding( - mSubMesh->getVertexAnimationType() != VAT_NONE); - switch(c) - { - case Entity::BIND_ORIGINAL: - return mSubMesh->vertexData; - case Entity::BIND_HARDWARE_MORPH: - return mHardwareVertexAnimVertexData; - case Entity::BIND_SOFTWARE_MORPH: - return mSoftwareVertexAnimVertexData; - case Entity::BIND_SOFTWARE_SKELETAL: - return mSkelAnimVertexData; - }; - // keep compiler happy - return mSubMesh->vertexData; - - } - } + void SubEntity::resetIndexDataStartEndIndex() + { + mIndexStart = 0; + mIndexEnd = 0; + } + //----------------------------------------------------------------------- + VertexData* SubEntity::getVertexDataForBinding(void) + { + if (mSubMesh->useSharedVertices) + { + return mParentEntity->getVertexDataForBinding(); + } + else + { + Entity::VertexDataBindChoice c = + mParentEntity->chooseVertexDataForBinding( + mSubMesh->getVertexAnimationType() != VAT_NONE); + switch(c) + { + case Entity::BIND_ORIGINAL: + return mSubMesh->vertexData; + case Entity::BIND_HARDWARE_MORPH: + return mHardwareVertexAnimVertexData; + case Entity::BIND_SOFTWARE_MORPH: + return mSoftwareVertexAnimVertexData; + case Entity::BIND_SOFTWARE_SKELETAL: + return mSkelAnimVertexData; + }; + // keep compiler happy + return mSubMesh->vertexData; + + } + } //----------------------------------------------------------------------- void SubEntity::getWorldTransforms(Matrix4* xform) const { @@ -268,8 +268,8 @@ namespace Ogre { Real SubEntity::getSquaredViewDepth(const Camera* cam) const { // First of all, check the cached value - // NB this is manually invalidated by parent each _notifyCurrentCamera call - // Done this here rather than there since we only need this for transparent objects + // NB this is manually invalidated by parent each _notifyCurrentCamera call + // Done this here rather than there since we only need this for transparent objects if (mCachedCamera == cam) return mCachedCameraDist; @@ -280,14 +280,14 @@ namespace Ogre { { const Vector3 &cp = cam->getDerivedPosition(); const Matrix4 &l2w = mParentEntity->_getParentNodeFullTransform(); - dist = std::numeric_limits::infinity(); + dist = std::numeric_limits::infinity(); for (vector::type::const_iterator i = mSubMesh->extremityPoints.begin(); i != mSubMesh->extremityPoints.end (); ++i) { Vector3 v = l2w * (*i); Real d = (v - cp).squaredLength(); - dist = std::min(d, dist); + dist = std::min(d, dist); } } else @@ -317,166 +317,166 @@ namespace Ogre { //----------------------------------------------------------------------- void SubEntity::prepareTempBlendBuffers(void) { - if (mSubMesh->useSharedVertices) - return; + if (mSubMesh->useSharedVertices) + return; if (mSkelAnimVertexData) { OGRE_DELETE mSkelAnimVertexData; mSkelAnimVertexData = 0; } - if (mSoftwareVertexAnimVertexData) - { - OGRE_DELETE mSoftwareVertexAnimVertexData; - mSoftwareVertexAnimVertexData = 0; - } - if (mHardwareVertexAnimVertexData) - { - OGRE_DELETE mHardwareVertexAnimVertexData; - mHardwareVertexAnimVertexData = 0; - } - - if (!mSubMesh->useSharedVertices) - { - if (mSubMesh->getVertexAnimationType() != VAT_NONE) - { - // Create temporary vertex blend info - // Prepare temp vertex data if needed - // Clone without copying data, don't remove any blending info - // (since if we skeletally animate too, we need it) - mSoftwareVertexAnimVertexData = mSubMesh->vertexData->clone(false); - mParentEntity->extractTempBufferInfo(mSoftwareVertexAnimVertexData, &mTempVertexAnimInfo); - - // Also clone for hardware usage, don't remove blend info since we'll - // need it if we also hardware skeletally animate - mHardwareVertexAnimVertexData = mSubMesh->vertexData->clone(false); - } - - if (mParentEntity->hasSkeleton()) - { - // Create temporary vertex blend info - // Prepare temp vertex data if needed - // Clone without copying data, remove blending info - // (since blend is performed in software) - mSkelAnimVertexData = - mParentEntity->cloneVertexDataRemoveBlendInfo(mSubMesh->vertexData); - mParentEntity->extractTempBufferInfo(mSkelAnimVertexData, &mTempSkelAnimInfo); - - } - } + if (mSoftwareVertexAnimVertexData) + { + OGRE_DELETE mSoftwareVertexAnimVertexData; + mSoftwareVertexAnimVertexData = 0; + } + if (mHardwareVertexAnimVertexData) + { + OGRE_DELETE mHardwareVertexAnimVertexData; + mHardwareVertexAnimVertexData = 0; + } + + if (!mSubMesh->useSharedVertices) + { + if (mSubMesh->getVertexAnimationType() != VAT_NONE) + { + // Create temporary vertex blend info + // Prepare temp vertex data if needed + // Clone without copying data, don't remove any blending info + // (since if we skeletally animate too, we need it) + mSoftwareVertexAnimVertexData = mSubMesh->vertexData->clone(false); + mParentEntity->extractTempBufferInfo(mSoftwareVertexAnimVertexData, &mTempVertexAnimInfo); + + // Also clone for hardware usage, don't remove blend info since we'll + // need it if we also hardware skeletally animate + mHardwareVertexAnimVertexData = mSubMesh->vertexData->clone(false); + } + + if (mParentEntity->hasSkeleton()) + { + // Create temporary vertex blend info + // Prepare temp vertex data if needed + // Clone without copying data, remove blending info + // (since blend is performed in software) + mSkelAnimVertexData = + mParentEntity->cloneVertexDataRemoveBlendInfo(mSubMesh->vertexData); + mParentEntity->extractTempBufferInfo(mSkelAnimVertexData, &mTempSkelAnimInfo); + + } + } } //----------------------------------------------------------------------- bool SubEntity::getCastsShadows(void) const { return mParentEntity->getCastShadows(); } - //----------------------------------------------------------------------- - VertexData* SubEntity::_getSkelAnimVertexData(void) - { - assert (mSkelAnimVertexData && "Not software skinned or has no dedicated geometry!"); - return mSkelAnimVertexData; - } - //----------------------------------------------------------------------- - VertexData* SubEntity::_getSoftwareVertexAnimVertexData(void) - { - assert (mSoftwareVertexAnimVertexData && "Not vertex animated or has no dedicated geometry!"); - return mSoftwareVertexAnimVertexData; - } - //----------------------------------------------------------------------- - VertexData* SubEntity::_getHardwareVertexAnimVertexData(void) - { - assert (mHardwareVertexAnimVertexData && "Not vertex animated or has no dedicated geometry!"); - return mHardwareVertexAnimVertexData; - } - //----------------------------------------------------------------------- - TempBlendedBufferInfo* SubEntity::_getSkelAnimTempBufferInfo(void) - { - return &mTempSkelAnimInfo; - } - //----------------------------------------------------------------------- - TempBlendedBufferInfo* SubEntity::_getVertexAnimTempBufferInfo(void) - { - return &mTempVertexAnimInfo; - } - //----------------------------------------------------------------------- - void SubEntity::_updateCustomGpuParameter( - const GpuProgramParameters::AutoConstantEntry& constantEntry, - GpuProgramParameters* params) const - { - if (constantEntry.paramType == GpuProgramParameters::ACT_ANIMATION_PARAMETRIC) - { - // Set up to 4 values, or up to limit of hardware animation entries - // Pack into 4-element constants offset based on constant data index - // If there are more than 4 entries, this will be called more than once - Vector4 val(0.0f,0.0f,0.0f,0.0f); - const VertexData* vd = mHardwareVertexAnimVertexData ? mHardwareVertexAnimVertexData : mParentEntity->mHardwareVertexAnimVertexData; - - size_t animIndex = constantEntry.data * 4; - for (size_t i = 0; i < 4 && - animIndex < vd->hwAnimationDataList.size(); - ++i, ++animIndex) - { - val[i] = - vd->hwAnimationDataList[animIndex].parametric; - } - // set the parametric morph value - params->_writeRawConstant(constantEntry.physicalIndex, val); - } - else - { - // default - return Renderable::_updateCustomGpuParameter(constantEntry, params); - } - } - //----------------------------------------------------------------------------- - void SubEntity::_markBuffersUnusedForAnimation(void) - { - mVertexAnimationAppliedThisFrame = false; - } - //----------------------------------------------------------------------------- - void SubEntity::_markBuffersUsedForAnimation(void) - { - mVertexAnimationAppliedThisFrame = true; - } - //----------------------------------------------------------------------------- - void SubEntity::_restoreBuffersForUnusedAnimation(bool hardwareAnimation) - { - // Rebind original positions if: - // We didn't apply any animation and - // We're morph animated (hardware binds keyframe, software is missing) - // or we're pose animated and software (hardware is fine, still bound) - if (mSubMesh->getVertexAnimationType() != VAT_NONE && - !mSubMesh->useSharedVertices && - !mVertexAnimationAppliedThisFrame && - (!hardwareAnimation || mSubMesh->getVertexAnimationType() == VAT_MORPH)) - { - // Note, VES_POSITION is specified here but if normals are included in animation - // then these will be re-bound too (buffers must be shared) - const VertexElement* srcPosElem = - mSubMesh->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr srcBuf = - mSubMesh->vertexData->vertexBufferBinding->getBuffer( - srcPosElem->getSource()); - - // Bind to software - const VertexElement* destPosElem = - mSoftwareVertexAnimVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - mSoftwareVertexAnimVertexData->vertexBufferBinding->setBinding( - destPosElem->getSource(), srcBuf); - - } - - // rebind any missing hardware pose buffers - // Caused by not having any animations enabled, or keyframes which reference - // no poses - if (!mSubMesh->useSharedVertices && hardwareAnimation - && mSubMesh->getVertexAnimationType() == VAT_POSE) - { - mParentEntity->bindMissingHardwarePoseBuffers( - mSubMesh->vertexData, mHardwareVertexAnimVertexData); - } - - } + //----------------------------------------------------------------------- + VertexData* SubEntity::_getSkelAnimVertexData(void) + { + assert (mSkelAnimVertexData && "Not software skinned or has no dedicated geometry!"); + return mSkelAnimVertexData; + } + //----------------------------------------------------------------------- + VertexData* SubEntity::_getSoftwareVertexAnimVertexData(void) + { + assert (mSoftwareVertexAnimVertexData && "Not vertex animated or has no dedicated geometry!"); + return mSoftwareVertexAnimVertexData; + } + //----------------------------------------------------------------------- + VertexData* SubEntity::_getHardwareVertexAnimVertexData(void) + { + assert (mHardwareVertexAnimVertexData && "Not vertex animated or has no dedicated geometry!"); + return mHardwareVertexAnimVertexData; + } + //----------------------------------------------------------------------- + TempBlendedBufferInfo* SubEntity::_getSkelAnimTempBufferInfo(void) + { + return &mTempSkelAnimInfo; + } + //----------------------------------------------------------------------- + TempBlendedBufferInfo* SubEntity::_getVertexAnimTempBufferInfo(void) + { + return &mTempVertexAnimInfo; + } + //----------------------------------------------------------------------- + void SubEntity::_updateCustomGpuParameter( + const GpuProgramParameters::AutoConstantEntry& constantEntry, + GpuProgramParameters* params) const + { + if (constantEntry.paramType == GpuProgramParameters::ACT_ANIMATION_PARAMETRIC) + { + // Set up to 4 values, or up to limit of hardware animation entries + // Pack into 4-element constants offset based on constant data index + // If there are more than 4 entries, this will be called more than once + Vector4 val(0.0f,0.0f,0.0f,0.0f); + const VertexData* vd = mHardwareVertexAnimVertexData ? mHardwareVertexAnimVertexData : mParentEntity->mHardwareVertexAnimVertexData; + + size_t animIndex = constantEntry.data * 4; + for (size_t i = 0; i < 4 && + animIndex < vd->hwAnimationDataList.size(); + ++i, ++animIndex) + { + val[i] = + vd->hwAnimationDataList[animIndex].parametric; + } + // set the parametric morph value + params->_writeRawConstant(constantEntry.physicalIndex, val); + } + else + { + // default + return Renderable::_updateCustomGpuParameter(constantEntry, params); + } + } + //----------------------------------------------------------------------------- + void SubEntity::_markBuffersUnusedForAnimation(void) + { + mVertexAnimationAppliedThisFrame = false; + } + //----------------------------------------------------------------------------- + void SubEntity::_markBuffersUsedForAnimation(void) + { + mVertexAnimationAppliedThisFrame = true; + } + //----------------------------------------------------------------------------- + void SubEntity::_restoreBuffersForUnusedAnimation(bool hardwareAnimation) + { + // Rebind original positions if: + // We didn't apply any animation and + // We're morph animated (hardware binds keyframe, software is missing) + // or we're pose animated and software (hardware is fine, still bound) + if (mSubMesh->getVertexAnimationType() != VAT_NONE && + !mSubMesh->useSharedVertices && + !mVertexAnimationAppliedThisFrame && + (!hardwareAnimation || mSubMesh->getVertexAnimationType() == VAT_MORPH)) + { + // Note, VES_POSITION is specified here but if normals are included in animation + // then these will be re-bound too (buffers must be shared) + const VertexElement* srcPosElem = + mSubMesh->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr srcBuf = + mSubMesh->vertexData->vertexBufferBinding->getBuffer( + srcPosElem->getSource()); + + // Bind to software + const VertexElement* destPosElem = + mSoftwareVertexAnimVertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + mSoftwareVertexAnimVertexData->vertexBufferBinding->setBinding( + destPosElem->getSource(), srcBuf); + + } + + // rebind any missing hardware pose buffers + // Caused by not having any animations enabled, or keyframes which reference + // no poses + if (!mSubMesh->useSharedVertices && hardwareAnimation + && mSubMesh->getVertexAnimationType() == VAT_POSE) + { + mParentEntity->bindMissingHardwarePoseBuffers( + mSubMesh->vertexData, mHardwareVertexAnimVertexData); + } + + } void SubEntity::setRenderQueueGroup(uint8 queueID) { diff --git a/OgreMain/src/OgreSubMesh.cpp b/OgreMain/src/OgreSubMesh.cpp index dc9b576bd3d..0ccf1b1ed6a 100644 --- a/OgreMain/src/OgreSubMesh.cpp +++ b/OgreMain/src/OgreSubMesh.cpp @@ -41,11 +41,11 @@ namespace Ogre { , parent(0) , mMatInitialised(false) , mBoneAssignmentsOutOfDate(false) - , mVertexAnimationType(VAT_NONE) - , mVertexAnimationIncludesNormals(false) - , mBuildEdgesEnabled(true) + , mVertexAnimationType(VAT_NONE) + , mVertexAnimationIncludesNormals(false) + , mBuildEdgesEnabled(true) { - indexData = OGRE_NEW IndexData(); + indexData = OGRE_NEW IndexData(); } //----------------------------------------------------------------------- SubMesh::~SubMesh() @@ -75,18 +75,18 @@ namespace Ogre { //----------------------------------------------------------------------- void SubMesh::_getRenderOperation(RenderOperation& ro, ushort lodIndex) { - if (lodIndex > 0 && static_cast< size_t >( lodIndex - 1 ) < mLodFaceList.size()) - { - // lodIndex - 1 because we don't store full detail version in mLodFaceList - ro.indexData = mLodFaceList[lodIndex-1]; + if (lodIndex > 0 && static_cast< size_t >( lodIndex - 1 ) < mLodFaceList.size()) + { + // lodIndex - 1 because we don't store full detail version in mLodFaceList + ro.indexData = mLodFaceList[lodIndex-1]; } else { - ro.indexData = indexData; + ro.indexData = indexData; } - ro.useIndexes = ro.indexData->indexCount != 0; - ro.operationType = operationType; - ro.vertexData = useSharedVertices? parent->sharedVertexData : vertexData; + ro.useIndexes = ro.indexData->indexCount != 0; + ro.operationType = operationType; + ro.vertexData = useSharedVertices? parent->sharedVertexData : vertexData; } //----------------------------------------------------------------------- @@ -162,42 +162,42 @@ namespace Ogre { // get test result for if change will occur when the texture aliases are applied if (material->applyTextureAliases(mTextureAliases, false)) { - Ogre::String newMaterialName; - - // If this material was already derived from another material - // due to aliasing, let's strip off the aliasing suffix and - // generate a new one using our current aliasing table. - - Ogre::String::size_type pos = mMaterialName.find("?TexAlias(", 0); - if( pos != Ogre::String::npos ) - newMaterialName = mMaterialName.substr(0, pos); - else - newMaterialName = mMaterialName; - - newMaterialName += "?TexAlias("; - // Iterate deterministically over the aliases (always in the same - // order via std::map's sorted iteration nature). - AliasTextureIterator aliasIter = getAliasTextureIterator(); - while( aliasIter.hasMoreElements() ) - { - newMaterialName += aliasIter.peekNextKey(); - newMaterialName += "="; - newMaterialName += aliasIter.getNext(); - newMaterialName += " "; - } - newMaterialName += ")"; - - // Reuse the material if it's already been created. This decreases batch - // count and keeps material explosion under control. - if(!MaterialManager::getSingleton().resourceExists(newMaterialName)) - { - Ogre::MaterialPtr newMaterial = Ogre::MaterialManager::getSingleton().create( - newMaterialName, material->getGroup()); - // copy parent material details to new material - material->copyDetailsTo(newMaterial); - // apply texture aliases to new material - newMaterial->applyTextureAliases(mTextureAliases); - } + Ogre::String newMaterialName; + + // If this material was already derived from another material + // due to aliasing, let's strip off the aliasing suffix and + // generate a new one using our current aliasing table. + + Ogre::String::size_type pos = mMaterialName.find("?TexAlias(", 0); + if( pos != Ogre::String::npos ) + newMaterialName = mMaterialName.substr(0, pos); + else + newMaterialName = mMaterialName; + + newMaterialName += "?TexAlias("; + // Iterate deterministically over the aliases (always in the same + // order via std::map's sorted iteration nature). + AliasTextureIterator aliasIter = getAliasTextureIterator(); + while( aliasIter.hasMoreElements() ) + { + newMaterialName += aliasIter.peekNextKey(); + newMaterialName += "="; + newMaterialName += aliasIter.getNext(); + newMaterialName += " "; + } + newMaterialName += ")"; + + // Reuse the material if it's already been created. This decreases batch + // count and keeps material explosion under control. + if(!MaterialManager::getSingleton().resourceExists(newMaterialName)) + { + Ogre::MaterialPtr newMaterial = Ogre::MaterialManager::getSingleton().create( + newMaterialName, material->getGroup()); + // copy parent material details to new material + material->copyDetailsTo(newMaterial); + // apply texture aliases to new material + newMaterial->applyTextureAliases(mTextureAliases); + } // place new material name in submesh setMaterialName(newMaterialName); newMaterialCreated = true; @@ -210,25 +210,25 @@ namespace Ogre { void SubMesh::removeLodLevels(void) { LODFaceList::iterator lodi, lodend; - lodend = mLodFaceList.end(); - for (lodi = mLodFaceList.begin(); lodi != lodend; ++lodi) - { - OGRE_DELETE *lodi; - } + lodend = mLodFaceList.end(); + for (lodi = mLodFaceList.begin(); lodi != lodend; ++lodi) + { + OGRE_DELETE *lodi; + } mLodFaceList.clear(); } - //--------------------------------------------------------------------- - VertexAnimationType SubMesh::getVertexAnimationType(void) const - { - if(parent->_getAnimationTypesDirty()) - { - parent->_determineAnimationTypes(); - } - return mVertexAnimationType; - } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + VertexAnimationType SubMesh::getVertexAnimationType(void) const + { + if(parent->_getAnimationTypesDirty()) + { + parent->_determineAnimationTypes(); + } + return mVertexAnimationType; + } + //--------------------------------------------------------------------- /* To find as many points from different domains as we need, * such that those domains are from different parts of the mesh, * we implement a simplified Heckbert quantization algorithm. @@ -333,35 +333,35 @@ namespace Ogre { vector::type boxes; boxes.reserve (count); - // First of all, find min and max bounding box of the submesh - boxes.push_back (Cluster ()); + // First of all, find min and max bounding box of the submesh + boxes.push_back (Cluster ()); - if (indexData->indexCount > 0) - { + if (indexData->indexCount > 0) + { - uint elsz = indexData->indexBuffer->getType () == HardwareIndexBuffer::IT_32BIT ? - 4 : 2; - uint8 *idata = (uint8 *)indexData->indexBuffer->lock ( - indexData->indexStart * elsz, indexData->indexCount * elsz, - HardwareIndexBuffer::HBL_READ_ONLY); + uint elsz = indexData->indexBuffer->getType () == HardwareIndexBuffer::IT_32BIT ? + 4 : 2; + uint8 *idata = (uint8 *)indexData->indexBuffer->lock ( + indexData->indexStart * elsz, indexData->indexCount * elsz, + HardwareIndexBuffer::HBL_READ_ONLY); - for (size_t i = 0; i < indexData->indexCount; i++) - { - int idx = (elsz == 2) ? ((uint16 *)idata) [i] : ((uint32 *)idata) [i]; - boxes [0].mIndices.insert (idx); - } - indexData->indexBuffer->unlock (); + for (size_t i = 0; i < indexData->indexCount; i++) + { + int idx = (elsz == 2) ? ((uint16 *)idata) [i] : ((uint32 *)idata) [i]; + boxes [0].mIndices.insert (idx); + } + indexData->indexBuffer->unlock (); - } - else - { - // just insert all indexes - for (size_t i = vertexData->vertexStart; i < vertexData->vertexCount; i++) - { - boxes [0].mIndices.insert (static_cast(i)); - } + } + else + { + // just insert all indexes + for (size_t i = vertexData->vertexStart; i < vertexData->vertexCount; i++) + { + boxes [0].mIndices.insert (static_cast(i)); + } - } + } boxes [0].computeBBox (poselem, vdata, vsz); @@ -442,15 +442,15 @@ namespace Ogre { vbuf->unlock (); } //--------------------------------------------------------------------- - void SubMesh::setBuildEdgesEnabled(bool b) - { - mBuildEdgesEnabled = b; - if(parent) - { - parent->freeEdgeList(); - parent->setAutoBuildEdgeLists(true); - } - } + void SubMesh::setBuildEdgesEnabled(bool b) + { + mBuildEdgesEnabled = b; + if(parent) + { + parent->freeEdgeList(); + parent->setAutoBuildEdgeLists(true); + } + } //--------------------------------------------------------------------- SubMesh * SubMesh::clone(const String& newName, Mesh *parentMesh) { diff --git a/OgreMain/src/OgreTagPoint.cpp b/OgreMain/src/OgreTagPoint.cpp index 4fe4d44e853..0f6bf803914 100644 --- a/OgreMain/src/OgreTagPoint.cpp +++ b/OgreMain/src/OgreTagPoint.cpp @@ -103,7 +103,7 @@ namespace Ogre { //----------------------------------------------------------------------------- void TagPoint::needUpdate(bool forceParentUpdate) { - Bone::needUpdate(forceParentUpdate); + Bone::needUpdate(forceParentUpdate); // We need to tell parent entities node if (mParentEntity) diff --git a/OgreMain/src/OgreTangentSpaceCalc.cpp b/OgreMain/src/OgreTangentSpaceCalc.cpp index 8d4c812674c..5c84836635b 100644 --- a/OgreMain/src/OgreTangentSpaceCalc.cpp +++ b/OgreMain/src/OgreTangentSpaceCalc.cpp @@ -33,746 +33,746 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - TangentSpaceCalc::TangentSpaceCalc() - : mVData(0) - , mSplitMirrored(false) - , mSplitRotated(false) - , mStoreParityInW(false) - { - } - //--------------------------------------------------------------------- - TangentSpaceCalc::~TangentSpaceCalc() - { - - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::clear() - { - mIDataList.clear(); - mOpTypes.clear(); - mVData = 0; - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::setVertexData(VertexData* v_in) - { - mVData = v_in; - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::addIndexData(IndexData* i_in, RenderOperation::OperationType op) - { - if (op != RenderOperation::OT_TRIANGLE_FAN && - op != RenderOperation::OT_TRIANGLE_LIST && - op != RenderOperation::OT_TRIANGLE_STRIP) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Only indexed triangle (list, strip, fan) render operations are supported.", - "TangentSpaceCalc::addIndexData"); - - } - mIDataList.push_back(i_in); - mOpTypes.push_back(op); - } - //--------------------------------------------------------------------- - TangentSpaceCalc::Result TangentSpaceCalc::build( - VertexElementSemantic targetSemantic, - unsigned short sourceTexCoordSet, unsigned short index) - { - Result res; - - // Pull out all the vertex components we'll need - populateVertexArray(sourceTexCoordSet); - - // Now process the faces and calculate / add their contributions - processFaces(res); - - // Now normalise & orthogonalise - normaliseVertices(); - - // Create new final geometry - // First extend existing buffers to cope with new vertices - extendBuffers(res.vertexSplits); - - // Alter indexes - remapIndexes(res); - - // Create / identify target & write tangents - insertTangents(res, targetSemantic, sourceTexCoordSet, index); - - return res; - - - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::extendBuffers(VertexSplits& vertexSplits) - { - if (!vertexSplits.empty()) - { - // ok, need to increase the vertex buffer size, and alter some indexes - - // vertex buffers first - VertexBufferBinding* newBindings = HardwareBufferManager::getSingleton().createVertexBufferBinding(); - const VertexBufferBinding::VertexBufferBindingMap& bindmap = - mVData->vertexBufferBinding->getBindings(); - for (VertexBufferBinding::VertexBufferBindingMap::const_iterator i = - bindmap.begin(); i != bindmap.end(); ++i) - { - HardwareVertexBufferSharedPtr srcbuf = i->second; - // Derive vertex count from buffer not vertex data, in case using - // the vertexStart option in vertex data - size_t newVertexCount = srcbuf->getNumVertices() + vertexSplits.size(); - // Create new buffer & bind - HardwareVertexBufferSharedPtr newBuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - srcbuf->getVertexSize(), newVertexCount, srcbuf->getUsage(), - srcbuf->hasShadowBuffer()); - newBindings->setBinding(i->first, newBuf); - - // Copy existing contents (again, entire buffer, not just elements referenced) - newBuf->copyData(*(srcbuf.get()), 0, 0, srcbuf->getNumVertices() * srcbuf->getVertexSize(), true); - - // Split vertices, read / write from new buffer - char* pBase = static_cast(newBuf->lock(HardwareBuffer::HBL_NORMAL)); - for (VertexSplits::iterator spliti = vertexSplits.begin(); - spliti != vertexSplits.end(); ++spliti) - { - const char* pSrcBase = pBase + spliti->first * newBuf->getVertexSize(); - char* pDstBase = pBase + spliti->second * newBuf->getVertexSize(); - memcpy(pDstBase, pSrcBase, newBuf->getVertexSize()); - } - newBuf->unlock(); - - } - - // Update vertex data - // Increase vertex count according to num splits - mVData->vertexCount += vertexSplits.size(); - // Flip bindings over to new buffers (old buffers released) - HardwareBufferManager::getSingleton().destroyVertexBufferBinding(mVData->vertexBufferBinding); - mVData->vertexBufferBinding = newBindings; - - // If vertex size requires 32bit index buffer - if (mVData->vertexCount > 65536) - { - for (size_t i = 0; i < mIDataList.size(); ++i) - { - // check index size - IndexData* idata = mIDataList[i]; - HardwareIndexBufferSharedPtr srcbuf = idata->indexBuffer; - if (srcbuf->getType() == HardwareIndexBuffer::IT_16BIT) - { - size_t indexCount = srcbuf->getNumIndexes(); - - // convert index buffer to 32bit. - HardwareIndexBufferSharedPtr newBuf = - HardwareBufferManager::getSingleton().createIndexBuffer( - HardwareIndexBuffer::IT_32BIT, indexCount, - srcbuf->getUsage(), srcbuf->hasShadowBuffer()); - - uint16* pSrcBase = static_cast(srcbuf->lock(HardwareBuffer::HBL_NORMAL)); - uint32* pBase = static_cast(newBuf->lock(HardwareBuffer::HBL_NORMAL)); - - size_t j = 0; - while (j < indexCount) - { - *pBase++ = *pSrcBase++; - ++j; - } - - srcbuf->unlock(); - newBuf->unlock(); - - // assign new index buffer. - idata->indexBuffer = newBuf; - } - } - } - } - - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::remapIndexes(Result& res) - { - for (size_t i = 0; i < mIDataList.size(); ++i) - { - - IndexData* idata = mIDataList[i]; - // Now do index data - // no new buffer required, same size but some triangles remapped - if (idata->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) - { - uint32* p32 = static_cast(idata->indexBuffer->lock(HardwareBuffer::HBL_NORMAL)); - remapIndexes(p32, i, res); - } - else - { - uint16* p16 = static_cast(idata->indexBuffer->lock(HardwareBuffer::HBL_NORMAL)); - remapIndexes(p16, i, res); - } - idata->indexBuffer->unlock(); - } - - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::normaliseVertices() - { - // Just run through our complete (possibly augmented) list of vertices - // Normalise the tangents & binormals - for (VertexInfoArray::iterator i = mVertexArray.begin(); i != mVertexArray.end(); ++i) - { - VertexInfo& v = *i; - - v.tangent.normalise(); - v.binormal.normalise(); - - // Orthogonalise with the vertex normal since it's currently - // orthogonal with the face normals, but will be close to ortho - // Apply Gram-Schmidt orthogonalise - Vector3 temp = v.tangent; - v.tangent = temp - (v.norm * v.norm.dotProduct(temp)); - - temp = v.binormal; - v.binormal = temp - (v.norm * v.norm.dotProduct(temp)); - - // renormalize - v.tangent.normalise(); - v.binormal.normalise(); - - } - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::processFaces(Result& result) - { - // Quick pre-check for triangle strips / fans - for (OpTypeList::iterator ot = mOpTypes.begin(); ot != mOpTypes.end(); ++ot) - { - if (*ot != RenderOperation::OT_TRIANGLE_LIST) - { - // Can't split strips / fans - setSplitMirrored(false); - setSplitRotated(false); - } - } - - for (size_t i = 0; i < mIDataList.size(); ++i) - { - IndexData* i_in = mIDataList[i]; - RenderOperation::OperationType opType = mOpTypes[i]; - - // Read data from buffers - uint16 *p16 = 0; - uint32 *p32 = 0; - - HardwareIndexBufferSharedPtr ibuf = i_in->indexBuffer; - if (ibuf->getType() == HardwareIndexBuffer::IT_32BIT) - { - p32 = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - // offset by index start - p32 += i_in->indexStart; - } - else - { - p16 = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - // offset by index start - p16 += i_in->indexStart; - } - // current triangle - size_t vertInd[3] = { 0, 0, 0 }; - // loop through all faces to calculate the tangents and normals - size_t faceCount = opType == RenderOperation::OT_TRIANGLE_LIST ? - i_in->indexCount / 3 : i_in->indexCount - 2; - for (size_t f = 0; f < faceCount; ++f) - { - bool invertOrdering = false; - // Read 1 or 3 indexes depending on type - if (f == 0 || opType == RenderOperation::OT_TRIANGLE_LIST) - { - vertInd[0] = p32? *p32++ : *p16++; - vertInd[1] = p32? *p32++ : *p16++; - vertInd[2] = p32? *p32++ : *p16++; - } - else if (opType == RenderOperation::OT_TRIANGLE_FAN) - { - // Element 0 always remains the same - // Element 2 becomes element 1 - vertInd[1] = vertInd[2]; - // read new into element 2 - vertInd[2] = p32? *p32++ : *p16++; - } - else if (opType == RenderOperation::OT_TRIANGLE_STRIP) - { - // Shunt everything down one, but also invert the ordering on - // odd numbered triangles (== even numbered i's) - // we interpret front as anticlockwise all the time but strips alternate - if (f & 0x1) - { - // odd tris (index starts at 3, 5, 7) - invertOrdering = true; - } - vertInd[0] = vertInd[1]; - vertInd[1] = vertInd[2]; - vertInd[2] = p32? *p32++ : *p16++; - } - - // deal with strip inversion of winding - size_t localVertInd[3]; - localVertInd[0] = vertInd[0]; - if (invertOrdering) - { - localVertInd[1] = vertInd[2]; - localVertInd[2] = vertInd[1]; - } - else - { - localVertInd[1] = vertInd[1]; - localVertInd[2] = vertInd[2]; - } - - - // For each triangle - // Calculate tangent & binormal per triangle - // Note these are not normalised, are weighted by UV area - Vector3 faceTsU, faceTsV, faceNorm; - calculateFaceTangentSpace(localVertInd, faceTsU, faceTsV, faceNorm); - - // Skip invalid UV space triangles - if (faceTsU.isZeroLength() || faceTsV.isZeroLength()) - continue; - - addFaceTangentSpaceToVertices(i, f, localVertInd, faceTsU, faceTsV, faceNorm, result); - - } - - - ibuf->unlock(); - } - - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::addFaceTangentSpaceToVertices( - size_t indexSet, size_t faceIndex, size_t *localVertInd, - const Vector3& faceTsU, const Vector3& faceTsV, const Vector3& faceNorm, - Result& result) - { - // Calculate parity for this triangle - int faceParity = calculateParity(faceTsU, faceTsV, faceNorm); - // Now add these to each vertex referenced by the face - for (int v = 0; v < 3; ++v) - { - // index 0 is vertex we're calculating, 1 and 2 are the others - - // We want to re-weight these by the angle the face makes with the vertex - // in order to obtain tessellation-independent results - Real angleWeight = calculateAngleWeight(localVertInd[v], - localVertInd[(v+1)%3], localVertInd[(v+2)%3]); - - - VertexInfo* vertex = &(mVertexArray[localVertInd[v]]); - - // check parity (0 means not set) - // Locate parity-version of vertex index, or create if doesn't exist - // If parity-version of vertex index was different, record alteration - // in triangle remap - // in vertex split list - bool splitVertex = false; - size_t reusedOppositeParity = 0; - bool splitBecauseOfParity = false; - bool newVertex = false; - if (!vertex->parity) - { - // init - vertex->parity = faceParity; - newVertex = true; - } - if (mSplitMirrored) - { - if (!newVertex && faceParity != calculateParity(vertex->tangent, vertex->binormal, vertex->norm))//vertex->parity != faceParity) - { - // Check for existing alternative parity - if (vertex->oppositeParityIndex) - { - // Ok, have already split this vertex because of parity - // Use the same one again - reusedOppositeParity = vertex->oppositeParityIndex; - vertex = &(mVertexArray[reusedOppositeParity]); - } - else - { - splitVertex = true; - splitBecauseOfParity = true; - - LogManager::getSingleton().stream(LML_TRIVIAL) - << "TSC parity split - Vpar: " << vertex->parity - << " Fpar: " << faceParity - << " faceTsU: " << faceTsU - << " faceTsV: " << faceTsV - << " faceNorm: " << faceNorm - << " vertTsU:" << vertex->tangent - << " vertTsV:" << vertex->binormal - << " vertNorm:" << vertex->norm; - - } - } - } - - if (mSplitRotated) - { - - // deal with excessive tangent space rotations as well as mirroring - // same kind of split behaviour appropriate - if (!newVertex && !splitVertex) - { - // If more than 90 degrees, split - Vector3 uvCurrent = vertex->tangent + vertex->binormal; - - // project down to the plane (plane normal = face normal) - Vector3 vRotHalf = uvCurrent - faceNorm; - vRotHalf *= faceNorm.dotProduct(uvCurrent); - - if ((faceTsU + faceTsV).dotProduct(vRotHalf) < 0.0f) - { - splitVertex = true; - } - } - } - - if (splitVertex) - { - size_t newVertexIndex = mVertexArray.size(); - VertexSplit splitInfo(localVertInd[v], newVertexIndex); - result.vertexSplits.push_back(splitInfo); - // re-point opposite parity - if (splitBecauseOfParity) - { - vertex->oppositeParityIndex = newVertexIndex; - } - // copy old values but reset tangent space - VertexInfo locVertex = *vertex; - locVertex.tangent = Vector3::ZERO; - locVertex.binormal = Vector3::ZERO; - locVertex.parity = faceParity; - mVertexArray.push_back(locVertex); - result.indexesRemapped.push_back(IndexRemap(indexSet, faceIndex, splitInfo)); - - vertex = &(mVertexArray[newVertexIndex]); - - } - else if (reusedOppositeParity) - { - // didn't split again, but we do need to record the re-used remapping - VertexSplit splitInfo(localVertInd[v], reusedOppositeParity); - result.indexesRemapped.push_back(IndexRemap(indexSet, faceIndex, splitInfo)); - - } - - // Add weighted tangent & binormal - vertex->tangent += (faceTsU * angleWeight); - vertex->binormal += (faceTsV * angleWeight); - - - } - - } - //--------------------------------------------------------------------- - int TangentSpaceCalc::calculateParity(const Vector3& u, const Vector3& v, const Vector3& n) - { - // Note that this parity is the reverse of what you'd expect - this is - // because the 'V' texture coordinate is actually left handed - if (u.crossProduct(v).dotProduct(n) >= 0.0f) - return -1; - else - return 1; - - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::calculateFaceTangentSpace(const size_t* vertInd, - Vector3& tsU, Vector3& tsV, Vector3& tsN) - { - const VertexInfo& v0 = mVertexArray[vertInd[0]]; - const VertexInfo& v1 = mVertexArray[vertInd[1]]; - const VertexInfo& v2 = mVertexArray[vertInd[2]]; - Vector2 deltaUV1 = v1.uv - v0.uv; - Vector2 deltaUV2 = v2.uv - v0.uv; - Vector3 deltaPos1 = v1.pos - v0.pos; - Vector3 deltaPos2 = v2.pos - v0.pos; - - // face normal - tsN = deltaPos1.crossProduct(deltaPos2); - tsN.normalise(); - - - Real uvarea = deltaUV1.crossProduct(deltaUV2) * 0.5f; - if (Math::RealEqual(uvarea, 0.0f)) - { - // no tangent, null uv area - tsU = tsV = Vector3::ZERO; - } - else - { - - // Normalise by uvarea - Real a = deltaUV2.y / uvarea; - Real b = -deltaUV1.y / uvarea; - Real c = -deltaUV2.x / uvarea; - Real d = deltaUV1.x / uvarea; - - tsU = (deltaPos1 * a) + (deltaPos2 * b); - tsU.normalise(); - - tsV = (deltaPos1 * c) + (deltaPos2 * d); - tsV.normalise(); - - Real abs_uvarea = Math::Abs(uvarea); - tsU *= abs_uvarea; - tsV *= abs_uvarea; - - // tangent (tsU) and binormal (tsV) are now weighted by uv area - - - } - - } - //--------------------------------------------------------------------- - Real TangentSpaceCalc::calculateAngleWeight(size_t vidx0, size_t vidx1, size_t vidx2) - { - const VertexInfo& v0 = mVertexArray[vidx0]; - const VertexInfo& v1 = mVertexArray[vidx1]; - const VertexInfo& v2 = mVertexArray[vidx2]; - - Vector3 diff0 = v1.pos - v0.pos; - Vector3 diff1 = v2.pos - v1.pos; - - // Weight is just the angle - larger == better - return diff0.angleBetween(diff1).valueRadians(); - - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::populateVertexArray(unsigned short sourceTexCoordSet) - { - // Just pull data out into more friendly structures - VertexDeclaration *dcl = mVData->vertexDeclaration; - VertexBufferBinding *bind = mVData->vertexBufferBinding; - - // Get the incoming UV element - const VertexElement* uvElem = dcl->findElementBySemantic( - VES_TEXTURE_COORDINATES, sourceTexCoordSet); - - if (!uvElem || uvElem->getType() != VET_FLOAT2) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "No 2D texture coordinates with selected index, cannot calculate tangents.", - "TangentSpaceCalc::build"); - } - - HardwareVertexBufferSharedPtr uvBuf, posBuf, normBuf; - unsigned char *pUvBase, *pPosBase, *pNormBase; - size_t uvInc, posInc, normInc; - - uvBuf = bind->getBuffer(uvElem->getSource()); - pUvBase = static_cast( - uvBuf->lock(HardwareBuffer::HBL_READ_ONLY)); - uvInc = uvBuf->getVertexSize(); - // offset for vertex start - pUvBase += mVData->vertexStart * uvInc; - - // find position - const VertexElement *posElem = dcl->findElementBySemantic(VES_POSITION); - if (posElem->getSource() == uvElem->getSource()) - { - pPosBase = pUvBase; - posInc = uvInc; - } - else - { - // A different buffer - posBuf = bind->getBuffer(posElem->getSource()); - pPosBase = static_cast( - posBuf->lock(HardwareBuffer::HBL_READ_ONLY)); - posInc = posBuf->getVertexSize(); - // offset for vertex start - pPosBase += mVData->vertexStart * posInc; - } - // find a normal buffer - const VertexElement *normElem = dcl->findElementBySemantic(VES_NORMAL); - if (!normElem) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "No vertex normals found", - "TangentSpaceCalc::build"); - - if (normElem->getSource() == uvElem->getSource()) - { - pNormBase = pUvBase; - normInc = uvInc; - } - else if (normElem->getSource() == posElem->getSource()) - { - // normals are in the same buffer as position - // this condition arises when an animated(skeleton) mesh is not built with - // an edge list buffer ie no shadows being used. - pNormBase = pPosBase; - normInc = posInc; - } - else - { - // A different buffer - normBuf = bind->getBuffer(normElem->getSource()); - pNormBase = static_cast( - normBuf->lock(HardwareBuffer::HBL_READ_ONLY)); - normInc = normBuf->getVertexSize(); - // offset for vertex start - pNormBase += mVData->vertexStart * normInc; - } - - // Preinitialise vertex info - mVertexArray.clear(); - mVertexArray.resize(mVData->vertexCount); - - float* pFloat; - VertexInfo* vInfo = &(mVertexArray[0]); - for (size_t v = 0; v < mVData->vertexCount; ++v, ++vInfo) - { - posElem->baseVertexPointerToElement(pPosBase, &pFloat); - vInfo->pos.x = *pFloat++; - vInfo->pos.y = *pFloat++; - vInfo->pos.z = *pFloat++; - pPosBase += posInc; - - normElem->baseVertexPointerToElement(pNormBase, &pFloat); - vInfo->norm.x = *pFloat++; - vInfo->norm.y = *pFloat++; - vInfo->norm.z = *pFloat++; - pNormBase += normInc; - - uvElem->baseVertexPointerToElement(pUvBase, &pFloat); - vInfo->uv.x = *pFloat++; - vInfo->uv.y = *pFloat++; - pUvBase += uvInc; - - - } - - // unlock buffers - uvBuf->unlock(); - if (!posBuf.isNull()) - { - posBuf->unlock(); - } - if (!normBuf.isNull()) - { - normBuf->unlock(); - } - - } - //--------------------------------------------------------------------- - void TangentSpaceCalc::insertTangents(Result& res, - VertexElementSemantic targetSemantic, unsigned short sourceTexCoordSet, - unsigned short index) - { - // Make a new tangents semantic or find an existing one - VertexDeclaration *vDecl = mVData->vertexDeclaration ; - VertexBufferBinding *vBind = mVData->vertexBufferBinding ; - - const VertexElement *tangentsElem = vDecl->findElementBySemantic(targetSemantic, index); - bool needsToBeCreated = false; - VertexElementType tangentsType = mStoreParityInW ? VET_FLOAT4 : VET_FLOAT3; - - if (!tangentsElem) - { // no tex coords with index 1 - needsToBeCreated = true ; - } - else if (tangentsElem->getType() != tangentsType) - { - // buffer exists, but not 3D - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Target semantic set already exists but is not of the right size, therefore " - "cannot contain tangents. You should delete this existing entry first. ", - "TangentSpaceCalc::insertTangents"); - } - - HardwareVertexBufferSharedPtr targetBuffer, origBuffer; - unsigned char* pSrc = NULL; - - if (needsToBeCreated) - { - // To be most efficient with our vertex streams, - // tack the new tangents onto the same buffer as the - // source texture coord set - const VertexElement* prevTexCoordElem = - mVData->vertexDeclaration->findElementBySemantic( - VES_TEXTURE_COORDINATES, sourceTexCoordSet); - if (!prevTexCoordElem) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot locate the first texture coordinate element to " - "which to append the new tangents.", - "Mesh::orgagniseTangentsBuffer"); - } - // Find the buffer associated with this element - origBuffer = mVData->vertexBufferBinding->getBuffer( - prevTexCoordElem->getSource()); - // Now create a new buffer, which includes the previous contents - // plus extra space for the 3D coords - targetBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( - origBuffer->getVertexSize() + VertexElement::getTypeSize(tangentsType), - origBuffer->getNumVertices(), - origBuffer->getUsage(), - origBuffer->hasShadowBuffer() ); - // Add the new element - tangentsElem = &(vDecl->addElement( - prevTexCoordElem->getSource(), - origBuffer->getVertexSize(), - tangentsType, - targetSemantic, - index)); - // Set up the source pointer - pSrc = static_cast( - origBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); - // Rebind the new buffer - vBind->setBinding(prevTexCoordElem->getSource(), targetBuffer); - } - else - { - // space already there - origBuffer = mVData->vertexBufferBinding->getBuffer( - tangentsElem->getSource()); - targetBuffer = origBuffer; - } - - - unsigned char* pDest = static_cast( - targetBuffer->lock(HardwareBuffer::HBL_DISCARD)); - size_t origVertSize = origBuffer->getVertexSize(); - size_t newVertSize = targetBuffer->getVertexSize(); - for (size_t v = 0; v < origBuffer->getNumVertices(); ++v) - { - if (needsToBeCreated) - { - // Copy original vertex data as well - memcpy(pDest, pSrc, origVertSize); - pSrc += origVertSize; - } - // Write in the tangent - float* pTangent; - tangentsElem->baseVertexPointerToElement(pDest, &pTangent); - VertexInfo& vertInfo = mVertexArray[v]; - *pTangent++ = vertInfo.tangent.x; - *pTangent++ = vertInfo.tangent.y; - *pTangent++ = vertInfo.tangent.z; - if (mStoreParityInW) - *pTangent++ = (float)vertInfo.parity; - - // Next target vertex - pDest += newVertSize; - - } - targetBuffer->unlock(); - - if (needsToBeCreated) - { - origBuffer->unlock(); - } - } + //--------------------------------------------------------------------- + TangentSpaceCalc::TangentSpaceCalc() + : mVData(0) + , mSplitMirrored(false) + , mSplitRotated(false) + , mStoreParityInW(false) + { + } + //--------------------------------------------------------------------- + TangentSpaceCalc::~TangentSpaceCalc() + { + + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::clear() + { + mIDataList.clear(); + mOpTypes.clear(); + mVData = 0; + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::setVertexData(VertexData* v_in) + { + mVData = v_in; + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::addIndexData(IndexData* i_in, RenderOperation::OperationType op) + { + if (op != RenderOperation::OT_TRIANGLE_FAN && + op != RenderOperation::OT_TRIANGLE_LIST && + op != RenderOperation::OT_TRIANGLE_STRIP) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Only indexed triangle (list, strip, fan) render operations are supported.", + "TangentSpaceCalc::addIndexData"); + + } + mIDataList.push_back(i_in); + mOpTypes.push_back(op); + } + //--------------------------------------------------------------------- + TangentSpaceCalc::Result TangentSpaceCalc::build( + VertexElementSemantic targetSemantic, + unsigned short sourceTexCoordSet, unsigned short index) + { + Result res; + + // Pull out all the vertex components we'll need + populateVertexArray(sourceTexCoordSet); + + // Now process the faces and calculate / add their contributions + processFaces(res); + + // Now normalise & orthogonalise + normaliseVertices(); + + // Create new final geometry + // First extend existing buffers to cope with new vertices + extendBuffers(res.vertexSplits); + + // Alter indexes + remapIndexes(res); + + // Create / identify target & write tangents + insertTangents(res, targetSemantic, sourceTexCoordSet, index); + + return res; + + + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::extendBuffers(VertexSplits& vertexSplits) + { + if (!vertexSplits.empty()) + { + // ok, need to increase the vertex buffer size, and alter some indexes + + // vertex buffers first + VertexBufferBinding* newBindings = HardwareBufferManager::getSingleton().createVertexBufferBinding(); + const VertexBufferBinding::VertexBufferBindingMap& bindmap = + mVData->vertexBufferBinding->getBindings(); + for (VertexBufferBinding::VertexBufferBindingMap::const_iterator i = + bindmap.begin(); i != bindmap.end(); ++i) + { + HardwareVertexBufferSharedPtr srcbuf = i->second; + // Derive vertex count from buffer not vertex data, in case using + // the vertexStart option in vertex data + size_t newVertexCount = srcbuf->getNumVertices() + vertexSplits.size(); + // Create new buffer & bind + HardwareVertexBufferSharedPtr newBuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + srcbuf->getVertexSize(), newVertexCount, srcbuf->getUsage(), + srcbuf->hasShadowBuffer()); + newBindings->setBinding(i->first, newBuf); + + // Copy existing contents (again, entire buffer, not just elements referenced) + newBuf->copyData(*(srcbuf.get()), 0, 0, srcbuf->getNumVertices() * srcbuf->getVertexSize(), true); + + // Split vertices, read / write from new buffer + char* pBase = static_cast(newBuf->lock(HardwareBuffer::HBL_NORMAL)); + for (VertexSplits::iterator spliti = vertexSplits.begin(); + spliti != vertexSplits.end(); ++spliti) + { + const char* pSrcBase = pBase + spliti->first * newBuf->getVertexSize(); + char* pDstBase = pBase + spliti->second * newBuf->getVertexSize(); + memcpy(pDstBase, pSrcBase, newBuf->getVertexSize()); + } + newBuf->unlock(); + + } + + // Update vertex data + // Increase vertex count according to num splits + mVData->vertexCount += vertexSplits.size(); + // Flip bindings over to new buffers (old buffers released) + HardwareBufferManager::getSingleton().destroyVertexBufferBinding(mVData->vertexBufferBinding); + mVData->vertexBufferBinding = newBindings; + + // If vertex size requires 32bit index buffer + if (mVData->vertexCount > 65536) + { + for (size_t i = 0; i < mIDataList.size(); ++i) + { + // check index size + IndexData* idata = mIDataList[i]; + HardwareIndexBufferSharedPtr srcbuf = idata->indexBuffer; + if (srcbuf->getType() == HardwareIndexBuffer::IT_16BIT) + { + size_t indexCount = srcbuf->getNumIndexes(); + + // convert index buffer to 32bit. + HardwareIndexBufferSharedPtr newBuf = + HardwareBufferManager::getSingleton().createIndexBuffer( + HardwareIndexBuffer::IT_32BIT, indexCount, + srcbuf->getUsage(), srcbuf->hasShadowBuffer()); + + uint16* pSrcBase = static_cast(srcbuf->lock(HardwareBuffer::HBL_NORMAL)); + uint32* pBase = static_cast(newBuf->lock(HardwareBuffer::HBL_NORMAL)); + + size_t j = 0; + while (j < indexCount) + { + *pBase++ = *pSrcBase++; + ++j; + } + + srcbuf->unlock(); + newBuf->unlock(); + + // assign new index buffer. + idata->indexBuffer = newBuf; + } + } + } + } + + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::remapIndexes(Result& res) + { + for (size_t i = 0; i < mIDataList.size(); ++i) + { + + IndexData* idata = mIDataList[i]; + // Now do index data + // no new buffer required, same size but some triangles remapped + if (idata->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT) + { + uint32* p32 = static_cast(idata->indexBuffer->lock(HardwareBuffer::HBL_NORMAL)); + remapIndexes(p32, i, res); + } + else + { + uint16* p16 = static_cast(idata->indexBuffer->lock(HardwareBuffer::HBL_NORMAL)); + remapIndexes(p16, i, res); + } + idata->indexBuffer->unlock(); + } + + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::normaliseVertices() + { + // Just run through our complete (possibly augmented) list of vertices + // Normalise the tangents & binormals + for (VertexInfoArray::iterator i = mVertexArray.begin(); i != mVertexArray.end(); ++i) + { + VertexInfo& v = *i; + + v.tangent.normalise(); + v.binormal.normalise(); + + // Orthogonalise with the vertex normal since it's currently + // orthogonal with the face normals, but will be close to ortho + // Apply Gram-Schmidt orthogonalise + Vector3 temp = v.tangent; + v.tangent = temp - (v.norm * v.norm.dotProduct(temp)); + + temp = v.binormal; + v.binormal = temp - (v.norm * v.norm.dotProduct(temp)); + + // renormalize + v.tangent.normalise(); + v.binormal.normalise(); + + } + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::processFaces(Result& result) + { + // Quick pre-check for triangle strips / fans + for (OpTypeList::iterator ot = mOpTypes.begin(); ot != mOpTypes.end(); ++ot) + { + if (*ot != RenderOperation::OT_TRIANGLE_LIST) + { + // Can't split strips / fans + setSplitMirrored(false); + setSplitRotated(false); + } + } + + for (size_t i = 0; i < mIDataList.size(); ++i) + { + IndexData* i_in = mIDataList[i]; + RenderOperation::OperationType opType = mOpTypes[i]; + + // Read data from buffers + uint16 *p16 = 0; + uint32 *p32 = 0; + + HardwareIndexBufferSharedPtr ibuf = i_in->indexBuffer; + if (ibuf->getType() == HardwareIndexBuffer::IT_32BIT) + { + p32 = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + // offset by index start + p32 += i_in->indexStart; + } + else + { + p16 = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + // offset by index start + p16 += i_in->indexStart; + } + // current triangle + size_t vertInd[3] = { 0, 0, 0 }; + // loop through all faces to calculate the tangents and normals + size_t faceCount = opType == RenderOperation::OT_TRIANGLE_LIST ? + i_in->indexCount / 3 : i_in->indexCount - 2; + for (size_t f = 0; f < faceCount; ++f) + { + bool invertOrdering = false; + // Read 1 or 3 indexes depending on type + if (f == 0 || opType == RenderOperation::OT_TRIANGLE_LIST) + { + vertInd[0] = p32? *p32++ : *p16++; + vertInd[1] = p32? *p32++ : *p16++; + vertInd[2] = p32? *p32++ : *p16++; + } + else if (opType == RenderOperation::OT_TRIANGLE_FAN) + { + // Element 0 always remains the same + // Element 2 becomes element 1 + vertInd[1] = vertInd[2]; + // read new into element 2 + vertInd[2] = p32? *p32++ : *p16++; + } + else if (opType == RenderOperation::OT_TRIANGLE_STRIP) + { + // Shunt everything down one, but also invert the ordering on + // odd numbered triangles (== even numbered i's) + // we interpret front as anticlockwise all the time but strips alternate + if (f & 0x1) + { + // odd tris (index starts at 3, 5, 7) + invertOrdering = true; + } + vertInd[0] = vertInd[1]; + vertInd[1] = vertInd[2]; + vertInd[2] = p32? *p32++ : *p16++; + } + + // deal with strip inversion of winding + size_t localVertInd[3]; + localVertInd[0] = vertInd[0]; + if (invertOrdering) + { + localVertInd[1] = vertInd[2]; + localVertInd[2] = vertInd[1]; + } + else + { + localVertInd[1] = vertInd[1]; + localVertInd[2] = vertInd[2]; + } + + + // For each triangle + // Calculate tangent & binormal per triangle + // Note these are not normalised, are weighted by UV area + Vector3 faceTsU, faceTsV, faceNorm; + calculateFaceTangentSpace(localVertInd, faceTsU, faceTsV, faceNorm); + + // Skip invalid UV space triangles + if (faceTsU.isZeroLength() || faceTsV.isZeroLength()) + continue; + + addFaceTangentSpaceToVertices(i, f, localVertInd, faceTsU, faceTsV, faceNorm, result); + + } + + + ibuf->unlock(); + } + + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::addFaceTangentSpaceToVertices( + size_t indexSet, size_t faceIndex, size_t *localVertInd, + const Vector3& faceTsU, const Vector3& faceTsV, const Vector3& faceNorm, + Result& result) + { + // Calculate parity for this triangle + int faceParity = calculateParity(faceTsU, faceTsV, faceNorm); + // Now add these to each vertex referenced by the face + for (int v = 0; v < 3; ++v) + { + // index 0 is vertex we're calculating, 1 and 2 are the others + + // We want to re-weight these by the angle the face makes with the vertex + // in order to obtain tessellation-independent results + Real angleWeight = calculateAngleWeight(localVertInd[v], + localVertInd[(v+1)%3], localVertInd[(v+2)%3]); + + + VertexInfo* vertex = &(mVertexArray[localVertInd[v]]); + + // check parity (0 means not set) + // Locate parity-version of vertex index, or create if doesn't exist + // If parity-version of vertex index was different, record alteration + // in triangle remap + // in vertex split list + bool splitVertex = false; + size_t reusedOppositeParity = 0; + bool splitBecauseOfParity = false; + bool newVertex = false; + if (!vertex->parity) + { + // init + vertex->parity = faceParity; + newVertex = true; + } + if (mSplitMirrored) + { + if (!newVertex && faceParity != calculateParity(vertex->tangent, vertex->binormal, vertex->norm))//vertex->parity != faceParity) + { + // Check for existing alternative parity + if (vertex->oppositeParityIndex) + { + // Ok, have already split this vertex because of parity + // Use the same one again + reusedOppositeParity = vertex->oppositeParityIndex; + vertex = &(mVertexArray[reusedOppositeParity]); + } + else + { + splitVertex = true; + splitBecauseOfParity = true; + + LogManager::getSingleton().stream(LML_TRIVIAL) + << "TSC parity split - Vpar: " << vertex->parity + << " Fpar: " << faceParity + << " faceTsU: " << faceTsU + << " faceTsV: " << faceTsV + << " faceNorm: " << faceNorm + << " vertTsU:" << vertex->tangent + << " vertTsV:" << vertex->binormal + << " vertNorm:" << vertex->norm; + + } + } + } + + if (mSplitRotated) + { + + // deal with excessive tangent space rotations as well as mirroring + // same kind of split behaviour appropriate + if (!newVertex && !splitVertex) + { + // If more than 90 degrees, split + Vector3 uvCurrent = vertex->tangent + vertex->binormal; + + // project down to the plane (plane normal = face normal) + Vector3 vRotHalf = uvCurrent - faceNorm; + vRotHalf *= faceNorm.dotProduct(uvCurrent); + + if ((faceTsU + faceTsV).dotProduct(vRotHalf) < 0.0f) + { + splitVertex = true; + } + } + } + + if (splitVertex) + { + size_t newVertexIndex = mVertexArray.size(); + VertexSplit splitInfo(localVertInd[v], newVertexIndex); + result.vertexSplits.push_back(splitInfo); + // re-point opposite parity + if (splitBecauseOfParity) + { + vertex->oppositeParityIndex = newVertexIndex; + } + // copy old values but reset tangent space + VertexInfo locVertex = *vertex; + locVertex.tangent = Vector3::ZERO; + locVertex.binormal = Vector3::ZERO; + locVertex.parity = faceParity; + mVertexArray.push_back(locVertex); + result.indexesRemapped.push_back(IndexRemap(indexSet, faceIndex, splitInfo)); + + vertex = &(mVertexArray[newVertexIndex]); + + } + else if (reusedOppositeParity) + { + // didn't split again, but we do need to record the re-used remapping + VertexSplit splitInfo(localVertInd[v], reusedOppositeParity); + result.indexesRemapped.push_back(IndexRemap(indexSet, faceIndex, splitInfo)); + + } + + // Add weighted tangent & binormal + vertex->tangent += (faceTsU * angleWeight); + vertex->binormal += (faceTsV * angleWeight); + + + } + + } + //--------------------------------------------------------------------- + int TangentSpaceCalc::calculateParity(const Vector3& u, const Vector3& v, const Vector3& n) + { + // Note that this parity is the reverse of what you'd expect - this is + // because the 'V' texture coordinate is actually left handed + if (u.crossProduct(v).dotProduct(n) >= 0.0f) + return -1; + else + return 1; + + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::calculateFaceTangentSpace(const size_t* vertInd, + Vector3& tsU, Vector3& tsV, Vector3& tsN) + { + const VertexInfo& v0 = mVertexArray[vertInd[0]]; + const VertexInfo& v1 = mVertexArray[vertInd[1]]; + const VertexInfo& v2 = mVertexArray[vertInd[2]]; + Vector2 deltaUV1 = v1.uv - v0.uv; + Vector2 deltaUV2 = v2.uv - v0.uv; + Vector3 deltaPos1 = v1.pos - v0.pos; + Vector3 deltaPos2 = v2.pos - v0.pos; + + // face normal + tsN = deltaPos1.crossProduct(deltaPos2); + tsN.normalise(); + + + Real uvarea = deltaUV1.crossProduct(deltaUV2) * 0.5f; + if (Math::RealEqual(uvarea, 0.0f)) + { + // no tangent, null uv area + tsU = tsV = Vector3::ZERO; + } + else + { + + // Normalise by uvarea + Real a = deltaUV2.y / uvarea; + Real b = -deltaUV1.y / uvarea; + Real c = -deltaUV2.x / uvarea; + Real d = deltaUV1.x / uvarea; + + tsU = (deltaPos1 * a) + (deltaPos2 * b); + tsU.normalise(); + + tsV = (deltaPos1 * c) + (deltaPos2 * d); + tsV.normalise(); + + Real abs_uvarea = Math::Abs(uvarea); + tsU *= abs_uvarea; + tsV *= abs_uvarea; + + // tangent (tsU) and binormal (tsV) are now weighted by uv area + + + } + + } + //--------------------------------------------------------------------- + Real TangentSpaceCalc::calculateAngleWeight(size_t vidx0, size_t vidx1, size_t vidx2) + { + const VertexInfo& v0 = mVertexArray[vidx0]; + const VertexInfo& v1 = mVertexArray[vidx1]; + const VertexInfo& v2 = mVertexArray[vidx2]; + + Vector3 diff0 = v1.pos - v0.pos; + Vector3 diff1 = v2.pos - v1.pos; + + // Weight is just the angle - larger == better + return diff0.angleBetween(diff1).valueRadians(); + + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::populateVertexArray(unsigned short sourceTexCoordSet) + { + // Just pull data out into more friendly structures + VertexDeclaration *dcl = mVData->vertexDeclaration; + VertexBufferBinding *bind = mVData->vertexBufferBinding; + + // Get the incoming UV element + const VertexElement* uvElem = dcl->findElementBySemantic( + VES_TEXTURE_COORDINATES, sourceTexCoordSet); + + if (!uvElem || uvElem->getType() != VET_FLOAT2) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "No 2D texture coordinates with selected index, cannot calculate tangents.", + "TangentSpaceCalc::build"); + } + + HardwareVertexBufferSharedPtr uvBuf, posBuf, normBuf; + unsigned char *pUvBase, *pPosBase, *pNormBase; + size_t uvInc, posInc, normInc; + + uvBuf = bind->getBuffer(uvElem->getSource()); + pUvBase = static_cast( + uvBuf->lock(HardwareBuffer::HBL_READ_ONLY)); + uvInc = uvBuf->getVertexSize(); + // offset for vertex start + pUvBase += mVData->vertexStart * uvInc; + + // find position + const VertexElement *posElem = dcl->findElementBySemantic(VES_POSITION); + if (posElem->getSource() == uvElem->getSource()) + { + pPosBase = pUvBase; + posInc = uvInc; + } + else + { + // A different buffer + posBuf = bind->getBuffer(posElem->getSource()); + pPosBase = static_cast( + posBuf->lock(HardwareBuffer::HBL_READ_ONLY)); + posInc = posBuf->getVertexSize(); + // offset for vertex start + pPosBase += mVData->vertexStart * posInc; + } + // find a normal buffer + const VertexElement *normElem = dcl->findElementBySemantic(VES_NORMAL); + if (!normElem) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "No vertex normals found", + "TangentSpaceCalc::build"); + + if (normElem->getSource() == uvElem->getSource()) + { + pNormBase = pUvBase; + normInc = uvInc; + } + else if (normElem->getSource() == posElem->getSource()) + { + // normals are in the same buffer as position + // this condition arises when an animated(skeleton) mesh is not built with + // an edge list buffer ie no shadows being used. + pNormBase = pPosBase; + normInc = posInc; + } + else + { + // A different buffer + normBuf = bind->getBuffer(normElem->getSource()); + pNormBase = static_cast( + normBuf->lock(HardwareBuffer::HBL_READ_ONLY)); + normInc = normBuf->getVertexSize(); + // offset for vertex start + pNormBase += mVData->vertexStart * normInc; + } + + // Preinitialise vertex info + mVertexArray.clear(); + mVertexArray.resize(mVData->vertexCount); + + float* pFloat; + VertexInfo* vInfo = &(mVertexArray[0]); + for (size_t v = 0; v < mVData->vertexCount; ++v, ++vInfo) + { + posElem->baseVertexPointerToElement(pPosBase, &pFloat); + vInfo->pos.x = *pFloat++; + vInfo->pos.y = *pFloat++; + vInfo->pos.z = *pFloat++; + pPosBase += posInc; + + normElem->baseVertexPointerToElement(pNormBase, &pFloat); + vInfo->norm.x = *pFloat++; + vInfo->norm.y = *pFloat++; + vInfo->norm.z = *pFloat++; + pNormBase += normInc; + + uvElem->baseVertexPointerToElement(pUvBase, &pFloat); + vInfo->uv.x = *pFloat++; + vInfo->uv.y = *pFloat++; + pUvBase += uvInc; + + + } + + // unlock buffers + uvBuf->unlock(); + if (!posBuf.isNull()) + { + posBuf->unlock(); + } + if (!normBuf.isNull()) + { + normBuf->unlock(); + } + + } + //--------------------------------------------------------------------- + void TangentSpaceCalc::insertTangents(Result& res, + VertexElementSemantic targetSemantic, unsigned short sourceTexCoordSet, + unsigned short index) + { + // Make a new tangents semantic or find an existing one + VertexDeclaration *vDecl = mVData->vertexDeclaration ; + VertexBufferBinding *vBind = mVData->vertexBufferBinding ; + + const VertexElement *tangentsElem = vDecl->findElementBySemantic(targetSemantic, index); + bool needsToBeCreated = false; + VertexElementType tangentsType = mStoreParityInW ? VET_FLOAT4 : VET_FLOAT3; + + if (!tangentsElem) + { // no tex coords with index 1 + needsToBeCreated = true ; + } + else if (tangentsElem->getType() != tangentsType) + { + // buffer exists, but not 3D + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Target semantic set already exists but is not of the right size, therefore " + "cannot contain tangents. You should delete this existing entry first. ", + "TangentSpaceCalc::insertTangents"); + } + + HardwareVertexBufferSharedPtr targetBuffer, origBuffer; + unsigned char* pSrc = NULL; + + if (needsToBeCreated) + { + // To be most efficient with our vertex streams, + // tack the new tangents onto the same buffer as the + // source texture coord set + const VertexElement* prevTexCoordElem = + mVData->vertexDeclaration->findElementBySemantic( + VES_TEXTURE_COORDINATES, sourceTexCoordSet); + if (!prevTexCoordElem) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot locate the first texture coordinate element to " + "which to append the new tangents.", + "Mesh::orgagniseTangentsBuffer"); + } + // Find the buffer associated with this element + origBuffer = mVData->vertexBufferBinding->getBuffer( + prevTexCoordElem->getSource()); + // Now create a new buffer, which includes the previous contents + // plus extra space for the 3D coords + targetBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( + origBuffer->getVertexSize() + VertexElement::getTypeSize(tangentsType), + origBuffer->getNumVertices(), + origBuffer->getUsage(), + origBuffer->hasShadowBuffer() ); + // Add the new element + tangentsElem = &(vDecl->addElement( + prevTexCoordElem->getSource(), + origBuffer->getVertexSize(), + tangentsType, + targetSemantic, + index)); + // Set up the source pointer + pSrc = static_cast( + origBuffer->lock(HardwareBuffer::HBL_READ_ONLY)); + // Rebind the new buffer + vBind->setBinding(prevTexCoordElem->getSource(), targetBuffer); + } + else + { + // space already there + origBuffer = mVData->vertexBufferBinding->getBuffer( + tangentsElem->getSource()); + targetBuffer = origBuffer; + } + + + unsigned char* pDest = static_cast( + targetBuffer->lock(HardwareBuffer::HBL_DISCARD)); + size_t origVertSize = origBuffer->getVertexSize(); + size_t newVertSize = targetBuffer->getVertexSize(); + for (size_t v = 0; v < origBuffer->getNumVertices(); ++v) + { + if (needsToBeCreated) + { + // Copy original vertex data as well + memcpy(pDest, pSrc, origVertSize); + pSrc += origVertSize; + } + // Write in the tangent + float* pTangent; + tangentsElem->baseVertexPointerToElement(pDest, &pTangent); + VertexInfo& vertInfo = mVertexArray[v]; + *pTangent++ = vertInfo.tangent.x; + *pTangent++ = vertInfo.tangent.y; + *pTangent++ = vertInfo.tangent.z; + if (mStoreParityInW) + *pTangent++ = (float)vertInfo.parity; + + // Next target vertex + pDest += newVertSize; + + } + targetBuffer->unlock(); + + if (needsToBeCreated) + { + origBuffer->unlock(); + } + } } diff --git a/OgreMain/src/OgreTechnique.cpp b/OgreMain/src/OgreTechnique.cpp index 4f6ac58b71e..e6d3bc9d6a4 100644 --- a/OgreMain/src/OgreTechnique.cpp +++ b/OgreMain/src/OgreTechnique.cpp @@ -77,343 +77,343 @@ namespace Ogre { //----------------------------------------------------------------------------- String Technique::_compile(bool autoManageTextureUnits) { - StringStream errors; + StringStream errors; - mIsSupported = checkGPURules(errors); - if (mIsSupported) - { - mIsSupported = checkHardwareSupport(autoManageTextureUnits, errors); - } + mIsSupported = checkGPURules(errors); + if (mIsSupported) + { + mIsSupported = checkHardwareSupport(autoManageTextureUnits, errors); + } // Compile for categorised illumination on demand clearIlluminationPasses(); mIlluminationPassesCompilationPhase = IPS_NOT_COMPILED; - return errors.str(); - - } - //--------------------------------------------------------------------- - bool Technique::checkHardwareSupport(bool autoManageTextureUnits, StringStream& compileErrors) - { - // Go through each pass, checking requirements - Passes::iterator i; - unsigned short passNum = 0; - const RenderSystemCapabilities* caps = - Root::getSingleton().getRenderSystem()->getCapabilities(); - unsigned short numTexUnits = caps->getNumTextureUnits(); - for (i = mPasses.begin(); i != mPasses.end(); ++i, ++passNum) - { - Pass* currPass = *i; - // Adjust pass index - currPass->_notifyIndex(passNum); - // Check for advanced blending operation support - if((currPass->getSceneBlendingOperation() != SBO_ADD || currPass->getSceneBlendingOperationAlpha() != SBO_ADD) && - !caps->hasCapability(RSC_ADVANCED_BLEND_OPERATIONS)) - { - return false; - } - // Check texture unit requirements - size_t numTexUnitsRequested = currPass->getNumTextureUnitStates(); - // Don't trust getNumTextureUnits for programmable - if(!currPass->hasFragmentProgram()) - { + return errors.str(); + + } + //--------------------------------------------------------------------- + bool Technique::checkHardwareSupport(bool autoManageTextureUnits, StringStream& compileErrors) + { + // Go through each pass, checking requirements + Passes::iterator i; + unsigned short passNum = 0; + const RenderSystemCapabilities* caps = + Root::getSingleton().getRenderSystem()->getCapabilities(); + unsigned short numTexUnits = caps->getNumTextureUnits(); + for (i = mPasses.begin(); i != mPasses.end(); ++i, ++passNum) + { + Pass* currPass = *i; + // Adjust pass index + currPass->_notifyIndex(passNum); + // Check for advanced blending operation support + if((currPass->getSceneBlendingOperation() != SBO_ADD || currPass->getSceneBlendingOperationAlpha() != SBO_ADD) && + !caps->hasCapability(RSC_ADVANCED_BLEND_OPERATIONS)) + { + return false; + } + // Check texture unit requirements + size_t numTexUnitsRequested = currPass->getNumTextureUnitStates(); + // Don't trust getNumTextureUnits for programmable + if(!currPass->hasFragmentProgram()) + { #if defined(OGRE_PRETEND_TEXTURE_UNITS) && OGRE_PRETEND_TEXTURE_UNITS > 0 - if (numTexUnits > OGRE_PRETEND_TEXTURE_UNITS) - numTexUnits = OGRE_PRETEND_TEXTURE_UNITS; + if (numTexUnits > OGRE_PRETEND_TEXTURE_UNITS) + numTexUnits = OGRE_PRETEND_TEXTURE_UNITS; #endif - if (numTexUnitsRequested > numTexUnits) - { - if (!autoManageTextureUnits) - { - // The user disabled auto pass split - compileErrors << "Pass " << passNum << - ": Too many texture units for the current hardware and no splitting allowed." - << std::endl; - return false; - } - else if (currPass->hasVertexProgram()) - { - // Can't do this one, and can't split a programmable pass - compileErrors << "Pass " << passNum << - ": Too many texture units for the current hardware and " - "cannot split programmable passes." - << std::endl; - return false; - } - } - } - if (currPass->hasComputeProgram()) - { - // Check fragment program version - if (!currPass->getComputeProgram()->isSupported()) - { - // Can't do this one - compileErrors << "Pass " << passNum << - ": Compute program " << currPass->getComputeProgram()->getName() - << " cannot be used - "; - if (currPass->getComputeProgram()->hasCompileError()) - compileErrors << "compile error."; - else - compileErrors << "not supported."; - - compileErrors << std::endl; - return false; - } - } - if (currPass->hasVertexProgram()) - { - // Check vertex program version - if (!currPass->getVertexProgram()->isSupported() ) - { - // Can't do this one - compileErrors << "Pass " << passNum << - ": Vertex program " << currPass->getVertexProgram()->getName() - << " cannot be used - "; - if (currPass->getVertexProgram()->hasCompileError()) - compileErrors << "compile error."; - else - compileErrors << "not supported."; - - compileErrors << std::endl; - return false; - } - } - if (currPass->hasTessellationHullProgram()) - { - // Check tessellation control program version - if (!currPass->getTessellationHullProgram()->isSupported() ) - { - // Can't do this one - compileErrors << "Pass " << passNum << - ": Tessellation Hull program " << currPass->getTessellationHullProgram()->getName() - << " cannot be used - "; - if (currPass->getTessellationHullProgram()->hasCompileError()) - compileErrors << "compile error."; - else - compileErrors << "not supported."; - - compileErrors << std::endl; - return false; - } - } - if (currPass->hasTessellationDomainProgram()) - { - // Check tessellation control program version - if (!currPass->getTessellationDomainProgram()->isSupported() ) - { - // Can't do this one - compileErrors << "Pass " << passNum << - ": Tessellation Domain program " << currPass->getTessellationDomainProgram()->getName() - << " cannot be used - "; - if (currPass->getTessellationDomainProgram()->hasCompileError()) - compileErrors << "compile error."; - else - compileErrors << "not supported."; - - compileErrors << std::endl; - return false; - } - } - if (currPass->hasGeometryProgram()) - { - // Check geometry program version - if (!currPass->getGeometryProgram()->isSupported() ) - { - // Can't do this one - compileErrors << "Pass " << passNum << - ": Geometry program " << currPass->getGeometryProgram()->getName() - << " cannot be used - "; - if (currPass->getGeometryProgram()->hasCompileError()) - compileErrors << "compile error."; - else - compileErrors << "not supported."; - - compileErrors << std::endl; - return false; - } - } - if (currPass->hasFragmentProgram()) - { - // Check fragment program version - if (!currPass->getFragmentProgram()->isSupported()) - { - // Can't do this one - compileErrors << "Pass " << passNum << - ": Fragment program " << currPass->getFragmentProgram()->getName() - << " cannot be used - "; - if (currPass->getFragmentProgram()->hasCompileError()) - compileErrors << "compile error."; - else - compileErrors << "not supported."; - - compileErrors << std::endl; - return false; - } - } - else - { - // Check a few fixed-function options in texture layers - Pass::TextureUnitStateIterator texi = currPass->getTextureUnitStateIterator(); - size_t texUnit = 0; - while (texi.hasMoreElements()) - { - TextureUnitState* tex = texi.getNext(); - // Any Cube textures? NB we make the assumption that any - // card capable of running fragment programs can support - // cubic textures, which has to be true, surely? - if (tex->is3D() && !caps->hasCapability(RSC_CUBEMAPPING)) - { - // Fail - compileErrors << "Pass " << passNum << - " Tex " << texUnit << - ": Cube maps not supported by current environment." - << std::endl; - return false; - } - // Any 3D textures? NB we make the assumption that any - // card capable of running fragment programs can support - // 3D textures, which has to be true, surely? - if (((tex->getTextureType() == TEX_TYPE_3D) || (tex->getTextureType() == TEX_TYPE_2D_ARRAY)) && + if (numTexUnitsRequested > numTexUnits) + { + if (!autoManageTextureUnits) + { + // The user disabled auto pass split + compileErrors << "Pass " << passNum << + ": Too many texture units for the current hardware and no splitting allowed." + << std::endl; + return false; + } + else if (currPass->hasVertexProgram()) + { + // Can't do this one, and can't split a programmable pass + compileErrors << "Pass " << passNum << + ": Too many texture units for the current hardware and " + "cannot split programmable passes." + << std::endl; + return false; + } + } + } + if (currPass->hasComputeProgram()) + { + // Check fragment program version + if (!currPass->getComputeProgram()->isSupported()) + { + // Can't do this one + compileErrors << "Pass " << passNum << + ": Compute program " << currPass->getComputeProgram()->getName() + << " cannot be used - "; + if (currPass->getComputeProgram()->hasCompileError()) + compileErrors << "compile error."; + else + compileErrors << "not supported."; + + compileErrors << std::endl; + return false; + } + } + if (currPass->hasVertexProgram()) + { + // Check vertex program version + if (!currPass->getVertexProgram()->isSupported() ) + { + // Can't do this one + compileErrors << "Pass " << passNum << + ": Vertex program " << currPass->getVertexProgram()->getName() + << " cannot be used - "; + if (currPass->getVertexProgram()->hasCompileError()) + compileErrors << "compile error."; + else + compileErrors << "not supported."; + + compileErrors << std::endl; + return false; + } + } + if (currPass->hasTessellationHullProgram()) + { + // Check tessellation control program version + if (!currPass->getTessellationHullProgram()->isSupported() ) + { + // Can't do this one + compileErrors << "Pass " << passNum << + ": Tessellation Hull program " << currPass->getTessellationHullProgram()->getName() + << " cannot be used - "; + if (currPass->getTessellationHullProgram()->hasCompileError()) + compileErrors << "compile error."; + else + compileErrors << "not supported."; + + compileErrors << std::endl; + return false; + } + } + if (currPass->hasTessellationDomainProgram()) + { + // Check tessellation control program version + if (!currPass->getTessellationDomainProgram()->isSupported() ) + { + // Can't do this one + compileErrors << "Pass " << passNum << + ": Tessellation Domain program " << currPass->getTessellationDomainProgram()->getName() + << " cannot be used - "; + if (currPass->getTessellationDomainProgram()->hasCompileError()) + compileErrors << "compile error."; + else + compileErrors << "not supported."; + + compileErrors << std::endl; + return false; + } + } + if (currPass->hasGeometryProgram()) + { + // Check geometry program version + if (!currPass->getGeometryProgram()->isSupported() ) + { + // Can't do this one + compileErrors << "Pass " << passNum << + ": Geometry program " << currPass->getGeometryProgram()->getName() + << " cannot be used - "; + if (currPass->getGeometryProgram()->hasCompileError()) + compileErrors << "compile error."; + else + compileErrors << "not supported."; + + compileErrors << std::endl; + return false; + } + } + if (currPass->hasFragmentProgram()) + { + // Check fragment program version + if (!currPass->getFragmentProgram()->isSupported()) + { + // Can't do this one + compileErrors << "Pass " << passNum << + ": Fragment program " << currPass->getFragmentProgram()->getName() + << " cannot be used - "; + if (currPass->getFragmentProgram()->hasCompileError()) + compileErrors << "compile error."; + else + compileErrors << "not supported."; + + compileErrors << std::endl; + return false; + } + } + else + { + // Check a few fixed-function options in texture layers + Pass::TextureUnitStateIterator texi = currPass->getTextureUnitStateIterator(); + size_t texUnit = 0; + while (texi.hasMoreElements()) + { + TextureUnitState* tex = texi.getNext(); + // Any Cube textures? NB we make the assumption that any + // card capable of running fragment programs can support + // cubic textures, which has to be true, surely? + if (tex->is3D() && !caps->hasCapability(RSC_CUBEMAPPING)) + { + // Fail + compileErrors << "Pass " << passNum << + " Tex " << texUnit << + ": Cube maps not supported by current environment." + << std::endl; + return false; + } + // Any 3D textures? NB we make the assumption that any + // card capable of running fragment programs can support + // 3D textures, which has to be true, surely? + if (((tex->getTextureType() == TEX_TYPE_3D) || (tex->getTextureType() == TEX_TYPE_2D_ARRAY)) && !caps->hasCapability(RSC_TEXTURE_3D)) - { - // Fail - compileErrors << "Pass " << passNum << - " Tex " << texUnit << - ": Volume textures not supported by current environment." - << std::endl; - return false; - } - // Any Dot3 blending? - if (tex->getColourBlendMode().operation == LBX_DOTPRODUCT && - !caps->hasCapability(RSC_DOT3)) - { - // Fail - compileErrors << "Pass " << passNum << - " Tex " << texUnit << - ": DOT3 blending not supported by current environment." - << std::endl; - return false; - } - ++texUnit; - } - - // We're ok on operations, now we need to check # texture units - if (!currPass->hasFragmentProgram()) - { - // Keep splitting this pass so long as units requested > gpu units - while (numTexUnitsRequested > numTexUnits) - { - // chop this pass into many passes - currPass = currPass->_split(numTexUnits); - numTexUnitsRequested = currPass->getNumTextureUnitStates(); - // Advance pass number - ++passNum; - // Reset iterator - i = mPasses.begin() + passNum; - // Move the new pass to the right place (will have been created - // at the end, may be other passes in between) - assert(mPasses.back() == currPass); - std::copy_backward(i, (mPasses.end()-1), mPasses.end()); - *i = currPass; - // Adjust pass index - currPass->_notifyIndex(passNum); - } - } - } - - } - // If we got this far, we're ok - return true; - } - //--------------------------------------------------------------------- - bool Technique::checkGPURules(StringStream& errors) - { - const RenderSystemCapabilities* caps = - Root::getSingleton().getRenderSystem()->getCapabilities(); - - StringStream includeRules; - bool includeRulesPresent = false; - bool includeRuleMatched = false; - - // Check vendors first - for (GPUVendorRuleList::const_iterator i = mGPUVendorRules.begin(); - i != mGPUVendorRules.end(); ++i) - { - if (i->includeOrExclude == INCLUDE) - { - includeRulesPresent = true; - includeRules << caps->vendorToString(i->vendor) << " "; - if (i->vendor == caps->getVendor()) - includeRuleMatched = true; - } - else // EXCLUDE - { - if (i->vendor == caps->getVendor()) - { - errors << "Excluded GPU vendor: " << caps->vendorToString(i->vendor) - << std::endl; - return false; - } - - } - } - - if (includeRulesPresent && !includeRuleMatched) - { - errors << "Failed to match GPU vendor: " << includeRules.str( ) - << std::endl; - return false; - } - - // now check device names - includeRules.str(BLANKSTRING); - includeRulesPresent = false; - includeRuleMatched = false; - - for (GPUDeviceNameRuleList::const_iterator i = mGPUDeviceNameRules.begin(); - i != mGPUDeviceNameRules.end(); ++i) - { - if (i->includeOrExclude == INCLUDE) - { - includeRulesPresent = true; - includeRules << i->devicePattern << " "; - if (StringUtil::match(caps->getDeviceName(), i->devicePattern, i->caseSensitive)) - includeRuleMatched = true; - } - else // EXCLUDE - { - if (StringUtil::match(caps->getDeviceName(), i->devicePattern, i->caseSensitive)) - { - errors << "Excluded GPU device: " << i->devicePattern - << std::endl; - return false; - } - - } - } - - if (includeRulesPresent && !includeRuleMatched) - { - errors << "Failed to match GPU device: " << includeRules.str( ) - << std::endl; - return false; - } - - // passed - return true; - } + { + // Fail + compileErrors << "Pass " << passNum << + " Tex " << texUnit << + ": Volume textures not supported by current environment." + << std::endl; + return false; + } + // Any Dot3 blending? + if (tex->getColourBlendMode().operation == LBX_DOTPRODUCT && + !caps->hasCapability(RSC_DOT3)) + { + // Fail + compileErrors << "Pass " << passNum << + " Tex " << texUnit << + ": DOT3 blending not supported by current environment." + << std::endl; + return false; + } + ++texUnit; + } + + // We're ok on operations, now we need to check # texture units + if (!currPass->hasFragmentProgram()) + { + // Keep splitting this pass so long as units requested > gpu units + while (numTexUnitsRequested > numTexUnits) + { + // chop this pass into many passes + currPass = currPass->_split(numTexUnits); + numTexUnitsRequested = currPass->getNumTextureUnitStates(); + // Advance pass number + ++passNum; + // Reset iterator + i = mPasses.begin() + passNum; + // Move the new pass to the right place (will have been created + // at the end, may be other passes in between) + assert(mPasses.back() == currPass); + std::copy_backward(i, (mPasses.end()-1), mPasses.end()); + *i = currPass; + // Adjust pass index + currPass->_notifyIndex(passNum); + } + } + } + + } + // If we got this far, we're ok + return true; + } + //--------------------------------------------------------------------- + bool Technique::checkGPURules(StringStream& errors) + { + const RenderSystemCapabilities* caps = + Root::getSingleton().getRenderSystem()->getCapabilities(); + + StringStream includeRules; + bool includeRulesPresent = false; + bool includeRuleMatched = false; + + // Check vendors first + for (GPUVendorRuleList::const_iterator i = mGPUVendorRules.begin(); + i != mGPUVendorRules.end(); ++i) + { + if (i->includeOrExclude == INCLUDE) + { + includeRulesPresent = true; + includeRules << caps->vendorToString(i->vendor) << " "; + if (i->vendor == caps->getVendor()) + includeRuleMatched = true; + } + else // EXCLUDE + { + if (i->vendor == caps->getVendor()) + { + errors << "Excluded GPU vendor: " << caps->vendorToString(i->vendor) + << std::endl; + return false; + } + + } + } + + if (includeRulesPresent && !includeRuleMatched) + { + errors << "Failed to match GPU vendor: " << includeRules.str( ) + << std::endl; + return false; + } + + // now check device names + includeRules.str(BLANKSTRING); + includeRulesPresent = false; + includeRuleMatched = false; + + for (GPUDeviceNameRuleList::const_iterator i = mGPUDeviceNameRules.begin(); + i != mGPUDeviceNameRules.end(); ++i) + { + if (i->includeOrExclude == INCLUDE) + { + includeRulesPresent = true; + includeRules << i->devicePattern << " "; + if (StringUtil::match(caps->getDeviceName(), i->devicePattern, i->caseSensitive)) + includeRuleMatched = true; + } + else // EXCLUDE + { + if (StringUtil::match(caps->getDeviceName(), i->devicePattern, i->caseSensitive)) + { + errors << "Excluded GPU device: " << i->devicePattern + << std::endl; + return false; + } + + } + } + + if (includeRulesPresent && !includeRuleMatched) + { + errors << "Failed to match GPU device: " << includeRules.str( ) + << std::endl; + return false; + } + + // passed + return true; + } //----------------------------------------------------------------------------- Pass* Technique::createPass(void) { - Pass* newPass = OGRE_NEW Pass(this, static_cast(mPasses.size())); - mPasses.push_back(newPass); - return newPass; + Pass* newPass = OGRE_NEW Pass(this, static_cast(mPasses.size())); + mPasses.push_back(newPass); + return newPass; } //----------------------------------------------------------------------------- Pass* Technique::getPass(unsigned short index) { - assert(index < mPasses.size() && "Index out of bounds"); - return mPasses[index]; + assert(index < mPasses.size() && "Index out of bounds"); + return mPasses[index]; } //----------------------------------------------------------------------------- Pass* Technique::getPass(const String& name) @@ -438,20 +438,20 @@ namespace Ogre { //----------------------------------------------------------------------------- unsigned short Technique::getNumPasses(void) const { - return static_cast(mPasses.size()); + return static_cast(mPasses.size()); } //----------------------------------------------------------------------------- void Technique::removePass(unsigned short index) { - assert(index < mPasses.size() && "Index out of bounds"); - Passes::iterator i = mPasses.begin() + index; - (*i)->queueForDeletion(); - i = mPasses.erase(i); - // Adjust passes index - for (; i != mPasses.end(); ++i, ++index) - { - (*i)->_notifyIndex(index); - } + assert(index < mPasses.size() && "Index out of bounds"); + Passes::iterator i = mPasses.begin() + index; + (*i)->queueForDeletion(); + i = mPasses.erase(i); + // Adjust passes index + for (; i != mPasses.end(); ++i, ++index) + { + (*i)->_notifyIndex(index); + } } //----------------------------------------------------------------------------- void Technique::removeAllPasses(void) @@ -485,22 +485,22 @@ namespace Ogre { mPasses.insert(i, pass); - // Adjust passes index - unsigned short beginIndex, endIndex; - if (destinationIndex > sourceIndex) - { - beginIndex = sourceIndex; - endIndex = destinationIndex; - } - else - { - beginIndex = destinationIndex; - endIndex = sourceIndex; - } - for (unsigned short index = beginIndex; index <= endIndex; ++index) - { - mPasses[index]->_notifyIndex(index); - } + // Adjust passes index + unsigned short beginIndex, endIndex; + if (destinationIndex > sourceIndex) + { + beginIndex = sourceIndex; + endIndex = destinationIndex; + } + else + { + beginIndex = destinationIndex; + endIndex = sourceIndex; + } + for (unsigned short index = beginIndex; index <= endIndex; ++index) + { + mPasses[index]->_notifyIndex(index); + } moveSuccessful = true; } @@ -510,35 +510,35 @@ namespace Ogre { //----------------------------------------------------------------------------- const Technique::PassIterator Technique::getPassIterator(void) { - return PassIterator(mPasses.begin(), mPasses.end()); + return PassIterator(mPasses.begin(), mPasses.end()); } //----------------------------------------------------------------------------- Technique& Technique::operator=(const Technique& rhs) { mName = rhs.mName; - this->mIsSupported = rhs.mIsSupported; + this->mIsSupported = rhs.mIsSupported; this->mLodIndex = rhs.mLodIndex; - this->mSchemeIndex = rhs.mSchemeIndex; - this->mShadowCasterMaterial = rhs.mShadowCasterMaterial; - this->mShadowCasterMaterialName = rhs.mShadowCasterMaterialName; - this->mShadowReceiverMaterial = rhs.mShadowReceiverMaterial; - this->mShadowReceiverMaterialName = rhs.mShadowReceiverMaterialName; - this->mGPUVendorRules = rhs.mGPUVendorRules; - this->mGPUDeviceNameRules = rhs.mGPUDeviceNameRules; - - // copy passes - removeAllPasses(); - Passes::const_iterator i, iend; - iend = rhs.mPasses.end(); - for (i = rhs.mPasses.begin(); i != iend; ++i) - { - Pass* p = OGRE_NEW Pass(this, (*i)->getIndex(), *(*i)); - mPasses.push_back(p); - } + this->mSchemeIndex = rhs.mSchemeIndex; + this->mShadowCasterMaterial = rhs.mShadowCasterMaterial; + this->mShadowCasterMaterialName = rhs.mShadowCasterMaterialName; + this->mShadowReceiverMaterial = rhs.mShadowReceiverMaterial; + this->mShadowReceiverMaterialName = rhs.mShadowReceiverMaterialName; + this->mGPUVendorRules = rhs.mGPUVendorRules; + this->mGPUDeviceNameRules = rhs.mGPUDeviceNameRules; + + // copy passes + removeAllPasses(); + Passes::const_iterator i, iend; + iend = rhs.mPasses.end(); + for (i = rhs.mPasses.begin(); i != iend; ++i) + { + Pass* p = OGRE_NEW Pass(this, (*i)->getIndex(), *(*i)); + mPasses.push_back(p); + } // Compile for categorised illumination on demand clearIlluminationPasses(); mIlluminationPassesCompilationPhase = IPS_NOT_COMPILED; - return *this; + return *this; } //----------------------------------------------------------------------------- bool Technique::isTransparent(void) const @@ -621,87 +621,87 @@ namespace Ogre { //----------------------------------------------------------------------------- void Technique::_prepare(void) { - assert (mIsSupported && "This technique is not supported"); - // Load each pass - Passes::iterator i, iend; - iend = mPasses.end(); - for (i = mPasses.begin(); i != iend; ++i) - { - (*i)->_prepare(); - } - - IlluminationPassList::iterator il, ilend; - ilend = mIlluminationPasses.end(); - for (il = mIlluminationPasses.begin(); il != ilend; ++il) - { - if((*il)->pass != (*il)->originalPass) - (*il)->pass->_prepare(); - } + assert (mIsSupported && "This technique is not supported"); + // Load each pass + Passes::iterator i, iend; + iend = mPasses.end(); + for (i = mPasses.begin(); i != iend; ++i) + { + (*i)->_prepare(); + } + + IlluminationPassList::iterator il, ilend; + ilend = mIlluminationPasses.end(); + for (il = mIlluminationPasses.begin(); il != ilend; ++il) + { + if((*il)->pass != (*il)->originalPass) + (*il)->pass->_prepare(); + } } //----------------------------------------------------------------------------- void Technique::_unprepare(void) { - // Unload each pass - Passes::iterator i, iend; - iend = mPasses.end(); - for (i = mPasses.begin(); i != iend; ++i) - { - (*i)->_unprepare(); - } + // Unload each pass + Passes::iterator i, iend; + iend = mPasses.end(); + for (i = mPasses.begin(); i != iend; ++i) + { + (*i)->_unprepare(); + } } //----------------------------------------------------------------------------- void Technique::_load(void) { - assert (mIsSupported && "This technique is not supported"); - // Load each pass - Passes::iterator i, iend; - iend = mPasses.end(); - for (i = mPasses.begin(); i != iend; ++i) - { - (*i)->_load(); - } - - IlluminationPassList::iterator il, ilend; - ilend = mIlluminationPasses.end(); - for (il = mIlluminationPasses.begin(); il != ilend; ++il) - { - if((*il)->pass != (*il)->originalPass) - (*il)->pass->_load(); - } - - if (!mShadowCasterMaterial.isNull()) - { - mShadowCasterMaterial->load(); - } - else if (!mShadowCasterMaterialName.empty()) - { - // in case we could not get material as it wasn't yet parsed/existent at that time. - mShadowCasterMaterial = MaterialManager::getSingleton().getByName(mShadowCasterMaterialName); + assert (mIsSupported && "This technique is not supported"); + // Load each pass + Passes::iterator i, iend; + iend = mPasses.end(); + for (i = mPasses.begin(); i != iend; ++i) + { + (*i)->_load(); + } + + IlluminationPassList::iterator il, ilend; + ilend = mIlluminationPasses.end(); + for (il = mIlluminationPasses.begin(); il != ilend; ++il) + { + if((*il)->pass != (*il)->originalPass) + (*il)->pass->_load(); + } + + if (!mShadowCasterMaterial.isNull()) + { + mShadowCasterMaterial->load(); + } + else if (!mShadowCasterMaterialName.empty()) + { + // in case we could not get material as it wasn't yet parsed/existent at that time. + mShadowCasterMaterial = MaterialManager::getSingleton().getByName(mShadowCasterMaterialName); if (!mShadowCasterMaterial.isNull()) - mShadowCasterMaterial->load(); - } - if (!mShadowReceiverMaterial.isNull()) - { - mShadowReceiverMaterial->load(); - } - else if (!mShadowReceiverMaterialName.empty()) - { - // in case we could not get material as it wasn't yet parsed/existent at that time. - mShadowReceiverMaterial = MaterialManager::getSingleton().getByName(mShadowReceiverMaterialName); + mShadowCasterMaterial->load(); + } + if (!mShadowReceiverMaterial.isNull()) + { + mShadowReceiverMaterial->load(); + } + else if (!mShadowReceiverMaterialName.empty()) + { + // in case we could not get material as it wasn't yet parsed/existent at that time. + mShadowReceiverMaterial = MaterialManager::getSingleton().getByName(mShadowReceiverMaterialName); if (!mShadowReceiverMaterial.isNull()) - mShadowReceiverMaterial->load(); - } + mShadowReceiverMaterial->load(); + } } //----------------------------------------------------------------------------- void Technique::_unload(void) { - // Unload each pass - Passes::iterator i, iend; - iend = mPasses.end(); - for (i = mPasses.begin(); i != iend; ++i) - { - (*i)->_unload(); - } + // Unload each pass + Passes::iterator i, iend; + iend = mPasses.end(); + for (i = mPasses.begin(); i != iend; ++i) + { + (*i)->_unload(); + } } //----------------------------------------------------------------------------- bool Technique::isLoaded(void) const @@ -723,19 +723,19 @@ namespace Ogre { //----------------------------------------------------------------------- void Technique::setAmbient(Real red, Real green, Real blue) { - setAmbient(ColourValue(red, green, blue)); + setAmbient(ColourValue(red, green, blue)); } //----------------------------------------------------------------------- void Technique::setAmbient(const ColourValue& ambient) { - Passes::iterator i, iend; - iend = mPasses.end(); - for (i = mPasses.begin(); i != iend; ++i) - { - (*i)->setAmbient(ambient); - } + Passes::iterator i, iend; + iend = mPasses.end(); + for (i = mPasses.begin(); i != iend; ++i) + { + (*i)->setAmbient(ambient); + } } //----------------------------------------------------------------------- void Technique::setDiffuse(Real red, Real green, Real blue, Real alpha) @@ -785,12 +785,12 @@ namespace Ogre { //----------------------------------------------------------------------- void Technique::setSelfIllumination(const ColourValue& selfIllum) { - Passes::iterator i, iend; - iend = mPasses.end(); - for (i = mPasses.begin(); i != iend; ++i) - { - (*i)->setSelfIllumination(selfIllum); - } + Passes::iterator i, iend; + iend = mPasses.end(); + for (i = mPasses.begin(); i != iend; ++i) + { + (*i)->setSelfIllumination(selfIllum); + } } //----------------------------------------------------------------------- void Technique::setDepthCheckEnabled(bool enabled) @@ -823,7 +823,7 @@ namespace Ogre { } } //----------------------------------------------------------------------- - void Technique::setColourWriteEnabled(bool enabled) + void Technique::setColourWriteEnabled(bool enabled) { Passes::iterator i, iend; iend = mPasses.end(); @@ -925,14 +925,14 @@ namespace Ogre { } // -------------------------------------------------------------------- void Technique::setSeparateSceneBlending( const SceneBlendType sbt, const SceneBlendType sbta ) - { + { Passes::iterator i, iend; iend = mPasses.end(); for (i = mPasses.begin(); i != iend; ++i) { (*i)->setSeparateSceneBlending(sbt, sbta); } - } + } // -------------------------------------------------------------------- void Technique::setSceneBlending( const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor) @@ -946,14 +946,14 @@ namespace Ogre { } // -------------------------------------------------------------------- void Technique::setSeparateSceneBlending( const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor, const SceneBlendFactor sourceFactorAlpha, const SceneBlendFactor destFactorAlpha) - { + { Passes::iterator i, iend; iend = mPasses.end(); for (i = mPasses.begin(); i != iend; ++i) { (*i)->setSeparateSceneBlending(sourceFactor, destFactor, sourceFactorAlpha, destFactorAlpha); } - } + } // -------------------------------------------------------------------- void Technique::setName(const String& name) @@ -978,274 +978,274 @@ namespace Ogre { _notifyNeedsRecompile(); } //----------------------------------------------------------------------- - void Technique::setSchemeName(const String& schemeName) - { - mSchemeIndex = MaterialManager::getSingleton()._getSchemeIndex(schemeName); + void Technique::setSchemeName(const String& schemeName) + { + mSchemeIndex = MaterialManager::getSingleton()._getSchemeIndex(schemeName); _notifyNeedsRecompile(); - } + } //----------------------------------------------------------------------- - const String& Technique::getSchemeName(void) const - { - return MaterialManager::getSingleton()._getSchemeName(mSchemeIndex); - } + const String& Technique::getSchemeName(void) const + { + return MaterialManager::getSingleton()._getSchemeName(mSchemeIndex); + } //----------------------------------------------------------------------- - unsigned short Technique::_getSchemeIndex(void) const - { - return mSchemeIndex; - } - //--------------------------------------------------------------------- - bool Technique::checkManuallyOrganisedIlluminationPasses() - { - // first check whether all passes have manually assigned illumination - Passes::iterator i, ibegin, iend; - ibegin = mPasses.begin(); - iend = mPasses.end(); - - for (i = ibegin; i != iend; ++i) - { - if ((*i)->getIlluminationStage() == IS_UNKNOWN) - return false; - } - - // ok, all manually controlled, so just use that - for (i = ibegin; i != iend; ++i) - { - IlluminationPass* iPass = OGRE_NEW IlluminationPass(); - iPass->destroyOnShutdown = false; - iPass->originalPass = iPass->pass = *i; - iPass->stage = (*i)->getIlluminationStage(); - mIlluminationPasses.push_back(iPass); - } - - return true; - } + unsigned short Technique::_getSchemeIndex(void) const + { + return mSchemeIndex; + } + //--------------------------------------------------------------------- + bool Technique::checkManuallyOrganisedIlluminationPasses() + { + // first check whether all passes have manually assigned illumination + Passes::iterator i, ibegin, iend; + ibegin = mPasses.begin(); + iend = mPasses.end(); + + for (i = ibegin; i != iend; ++i) + { + if ((*i)->getIlluminationStage() == IS_UNKNOWN) + return false; + } + + // ok, all manually controlled, so just use that + for (i = ibegin; i != iend; ++i) + { + IlluminationPass* iPass = OGRE_NEW IlluminationPass(); + iPass->destroyOnShutdown = false; + iPass->originalPass = iPass->pass = *i; + iPass->stage = (*i)->getIlluminationStage(); + mIlluminationPasses.push_back(iPass); + } + + return true; + } //----------------------------------------------------------------------- void Technique::_compileIlluminationPasses(void) { clearIlluminationPasses(); - if (!checkManuallyOrganisedIlluminationPasses()) - { - // Build based on our own heuristics - - Passes::iterator i, iend; - iend = mPasses.end(); - i = mPasses.begin(); - - IlluminationStage iStage = IS_AMBIENT; - - bool haveAmbient = false; - while (i != iend) - { - IlluminationPass* iPass; - Pass* p = *i; - switch(iStage) - { - case IS_AMBIENT: - // Keep looking for ambient only - if (p->isAmbientOnly()) - { - // Add this pass wholesale - iPass = OGRE_NEW IlluminationPass(); - iPass->destroyOnShutdown = false; - iPass->originalPass = iPass->pass = p; - iPass->stage = iStage; - mIlluminationPasses.push_back(iPass); - haveAmbient = true; - // progress to next pass - ++i; - } - else - { - // Split off any ambient part - if (p->getAmbient() != ColourValue::Black || - p->getSelfIllumination() != ColourValue::Black || - p->getAlphaRejectFunction() != CMPF_ALWAYS_PASS) - { - // Copy existing pass - Pass* newPass = OGRE_NEW Pass(this, p->getIndex(), *p); - if (newPass->getAlphaRejectFunction() != CMPF_ALWAYS_PASS) - { - // Alpha rejection passes must retain their transparency, so - // we allow the texture units, but override the colour functions - Pass::TextureUnitStateIterator tusi = newPass->getTextureUnitStateIterator(); - while (tusi.hasMoreElements()) - { - TextureUnitState* tus = tusi.getNext(); - tus->setColourOperationEx(LBX_SOURCE1, LBS_CURRENT); - } - } - else - { - // Remove any texture units - newPass->removeAllTextureUnitStates(); - } - // Remove any fragment program - if (newPass->hasFragmentProgram()) - newPass->setFragmentProgram(""); - // We have to leave vertex program alone (if any) and - // just trust that the author is using light bindings, which - // we will ensure there are none in the ambient pass - newPass->setDiffuse(0, 0, 0, newPass->getDiffuse().a); // Preserving alpha - newPass->setSpecular(ColourValue::Black); - - // Calculate hash value for new pass, because we are compiling - // illumination passes on demand, which will loss hash calculate - // before it add to render queue first time. - newPass->_recalculateHash(); - - iPass = OGRE_NEW IlluminationPass(); - iPass->destroyOnShutdown = true; - iPass->originalPass = p; - iPass->pass = newPass; - iPass->stage = iStage; - - mIlluminationPasses.push_back(iPass); - haveAmbient = true; - - } - - if (!haveAmbient) - { - // Make up a new basic pass - Pass* newPass = OGRE_NEW Pass(this, p->getIndex()); - newPass->setAmbient(ColourValue::Black); - newPass->setDiffuse(ColourValue::Black); - - // Calculate hash value for new pass, because we are compiling - // illumination passes on demand, which will loss hash calculate - // before it add to render queue first time. - newPass->_recalculateHash(); - - iPass = OGRE_NEW IlluminationPass(); - iPass->destroyOnShutdown = true; - iPass->originalPass = p; - iPass->pass = newPass; - iPass->stage = iStage; - mIlluminationPasses.push_back(iPass); - haveAmbient = true; - } - // This means we're done with ambients, progress to per-light - iStage = IS_PER_LIGHT; - } - break; - case IS_PER_LIGHT: - if (p->getIteratePerLight()) - { - // If this is per-light already, use it directly - iPass = OGRE_NEW IlluminationPass(); - iPass->destroyOnShutdown = false; - iPass->originalPass = iPass->pass = p; - iPass->stage = iStage; - mIlluminationPasses.push_back(iPass); - // progress to next pass - ++i; - } - else - { - // Split off per-light details (can only be done for one) - if (p->getLightingEnabled() && - (p->getDiffuse() != ColourValue::Black || - p->getSpecular() != ColourValue::Black)) - { - // Copy existing pass - Pass* newPass = OGRE_NEW Pass(this, p->getIndex(), *p); - if (newPass->getAlphaRejectFunction() != CMPF_ALWAYS_PASS) - { - // Alpha rejection passes must retain their transparency, so - // we allow the texture units, but override the colour functions - Pass::TextureUnitStateIterator tusi = newPass->getTextureUnitStateIterator(); - while (tusi.hasMoreElements()) - { - TextureUnitState* tus = tusi.getNext(); - tus->setColourOperationEx(LBX_SOURCE1, LBS_CURRENT); - } - } - else - { - // remove texture units - newPass->removeAllTextureUnitStates(); - } - // remove fragment programs - if (newPass->hasFragmentProgram()) - newPass->setFragmentProgram(""); - // Cannot remove vertex program, have to assume that - // it will process diffuse lights, ambient will be turned off - newPass->setAmbient(ColourValue::Black); - newPass->setSelfIllumination(ColourValue::Black); - // must be additive - newPass->setSceneBlending(SBF_ONE, SBF_ONE); - - // Calculate hash value for new pass, because we are compiling - // illumination passes on demand, which will loss hash calculate - // before it add to render queue first time. - newPass->_recalculateHash(); - - iPass = OGRE_NEW IlluminationPass(); - iPass->destroyOnShutdown = true; - iPass->originalPass = p; - iPass->pass = newPass; - iPass->stage = iStage; - - mIlluminationPasses.push_back(iPass); - - } - // This means the end of per-light passes - iStage = IS_DECAL; - } - break; - case IS_DECAL: - // We just want a 'lighting off' pass to finish off - // and only if there are texture units - if (p->getNumTextureUnitStates() > 0) - { - if (!p->getLightingEnabled()) - { - // we assume this pass already combines as required with the scene - iPass = OGRE_NEW IlluminationPass(); - iPass->destroyOnShutdown = false; - iPass->originalPass = iPass->pass = p; - iPass->stage = iStage; - mIlluminationPasses.push_back(iPass); - } - else - { - // Copy the pass and tweak away the lighting parts - Pass* newPass = OGRE_NEW Pass(this, p->getIndex(), *p); - newPass->setAmbient(ColourValue::Black); - newPass->setDiffuse(0, 0, 0, newPass->getDiffuse().a); // Preserving alpha - newPass->setSpecular(ColourValue::Black); - newPass->setSelfIllumination(ColourValue::Black); - newPass->setLightingEnabled(false); - newPass->setIteratePerLight(false, false); - // modulate - newPass->setSceneBlending(SBF_DEST_COLOUR, SBF_ZERO); - - // Calculate hash value for new pass, because we are compiling - // illumination passes on demand, which will loss hash calculate - // before it add to render queue first time. - newPass->_recalculateHash(); - - // NB there is nothing we can do about vertex & fragment - // programs here, so people will just have to make their - // programs friendly-like if they want to use this technique - iPass = OGRE_NEW IlluminationPass(); - iPass->destroyOnShutdown = true; - iPass->originalPass = p; - iPass->pass = newPass; - iPass->stage = iStage; - mIlluminationPasses.push_back(iPass); - - } - } - ++i; // always increment on decal, since nothing more to do with this pass - - break; + if (!checkManuallyOrganisedIlluminationPasses()) + { + // Build based on our own heuristics + + Passes::iterator i, iend; + iend = mPasses.end(); + i = mPasses.begin(); + + IlluminationStage iStage = IS_AMBIENT; + + bool haveAmbient = false; + while (i != iend) + { + IlluminationPass* iPass; + Pass* p = *i; + switch(iStage) + { + case IS_AMBIENT: + // Keep looking for ambient only + if (p->isAmbientOnly()) + { + // Add this pass wholesale + iPass = OGRE_NEW IlluminationPass(); + iPass->destroyOnShutdown = false; + iPass->originalPass = iPass->pass = p; + iPass->stage = iStage; + mIlluminationPasses.push_back(iPass); + haveAmbient = true; + // progress to next pass + ++i; + } + else + { + // Split off any ambient part + if (p->getAmbient() != ColourValue::Black || + p->getSelfIllumination() != ColourValue::Black || + p->getAlphaRejectFunction() != CMPF_ALWAYS_PASS) + { + // Copy existing pass + Pass* newPass = OGRE_NEW Pass(this, p->getIndex(), *p); + if (newPass->getAlphaRejectFunction() != CMPF_ALWAYS_PASS) + { + // Alpha rejection passes must retain their transparency, so + // we allow the texture units, but override the colour functions + Pass::TextureUnitStateIterator tusi = newPass->getTextureUnitStateIterator(); + while (tusi.hasMoreElements()) + { + TextureUnitState* tus = tusi.getNext(); + tus->setColourOperationEx(LBX_SOURCE1, LBS_CURRENT); + } + } + else + { + // Remove any texture units + newPass->removeAllTextureUnitStates(); + } + // Remove any fragment program + if (newPass->hasFragmentProgram()) + newPass->setFragmentProgram(""); + // We have to leave vertex program alone (if any) and + // just trust that the author is using light bindings, which + // we will ensure there are none in the ambient pass + newPass->setDiffuse(0, 0, 0, newPass->getDiffuse().a); // Preserving alpha + newPass->setSpecular(ColourValue::Black); + + // Calculate hash value for new pass, because we are compiling + // illumination passes on demand, which will loss hash calculate + // before it add to render queue first time. + newPass->_recalculateHash(); + + iPass = OGRE_NEW IlluminationPass(); + iPass->destroyOnShutdown = true; + iPass->originalPass = p; + iPass->pass = newPass; + iPass->stage = iStage; + + mIlluminationPasses.push_back(iPass); + haveAmbient = true; + + } + + if (!haveAmbient) + { + // Make up a new basic pass + Pass* newPass = OGRE_NEW Pass(this, p->getIndex()); + newPass->setAmbient(ColourValue::Black); + newPass->setDiffuse(ColourValue::Black); + + // Calculate hash value for new pass, because we are compiling + // illumination passes on demand, which will loss hash calculate + // before it add to render queue first time. + newPass->_recalculateHash(); + + iPass = OGRE_NEW IlluminationPass(); + iPass->destroyOnShutdown = true; + iPass->originalPass = p; + iPass->pass = newPass; + iPass->stage = iStage; + mIlluminationPasses.push_back(iPass); + haveAmbient = true; + } + // This means we're done with ambients, progress to per-light + iStage = IS_PER_LIGHT; + } + break; + case IS_PER_LIGHT: + if (p->getIteratePerLight()) + { + // If this is per-light already, use it directly + iPass = OGRE_NEW IlluminationPass(); + iPass->destroyOnShutdown = false; + iPass->originalPass = iPass->pass = p; + iPass->stage = iStage; + mIlluminationPasses.push_back(iPass); + // progress to next pass + ++i; + } + else + { + // Split off per-light details (can only be done for one) + if (p->getLightingEnabled() && + (p->getDiffuse() != ColourValue::Black || + p->getSpecular() != ColourValue::Black)) + { + // Copy existing pass + Pass* newPass = OGRE_NEW Pass(this, p->getIndex(), *p); + if (newPass->getAlphaRejectFunction() != CMPF_ALWAYS_PASS) + { + // Alpha rejection passes must retain their transparency, so + // we allow the texture units, but override the colour functions + Pass::TextureUnitStateIterator tusi = newPass->getTextureUnitStateIterator(); + while (tusi.hasMoreElements()) + { + TextureUnitState* tus = tusi.getNext(); + tus->setColourOperationEx(LBX_SOURCE1, LBS_CURRENT); + } + } + else + { + // remove texture units + newPass->removeAllTextureUnitStates(); + } + // remove fragment programs + if (newPass->hasFragmentProgram()) + newPass->setFragmentProgram(""); + // Cannot remove vertex program, have to assume that + // it will process diffuse lights, ambient will be turned off + newPass->setAmbient(ColourValue::Black); + newPass->setSelfIllumination(ColourValue::Black); + // must be additive + newPass->setSceneBlending(SBF_ONE, SBF_ONE); + + // Calculate hash value for new pass, because we are compiling + // illumination passes on demand, which will loss hash calculate + // before it add to render queue first time. + newPass->_recalculateHash(); + + iPass = OGRE_NEW IlluminationPass(); + iPass->destroyOnShutdown = true; + iPass->originalPass = p; + iPass->pass = newPass; + iPass->stage = iStage; + + mIlluminationPasses.push_back(iPass); + + } + // This means the end of per-light passes + iStage = IS_DECAL; + } + break; + case IS_DECAL: + // We just want a 'lighting off' pass to finish off + // and only if there are texture units + if (p->getNumTextureUnitStates() > 0) + { + if (!p->getLightingEnabled()) + { + // we assume this pass already combines as required with the scene + iPass = OGRE_NEW IlluminationPass(); + iPass->destroyOnShutdown = false; + iPass->originalPass = iPass->pass = p; + iPass->stage = iStage; + mIlluminationPasses.push_back(iPass); + } + else + { + // Copy the pass and tweak away the lighting parts + Pass* newPass = OGRE_NEW Pass(this, p->getIndex(), *p); + newPass->setAmbient(ColourValue::Black); + newPass->setDiffuse(0, 0, 0, newPass->getDiffuse().a); // Preserving alpha + newPass->setSpecular(ColourValue::Black); + newPass->setSelfIllumination(ColourValue::Black); + newPass->setLightingEnabled(false); + newPass->setIteratePerLight(false, false); + // modulate + newPass->setSceneBlending(SBF_DEST_COLOUR, SBF_ZERO); + + // Calculate hash value for new pass, because we are compiling + // illumination passes on demand, which will loss hash calculate + // before it add to render queue first time. + newPass->_recalculateHash(); + + // NB there is nothing we can do about vertex & fragment + // programs here, so people will just have to make their + // programs friendly-like if they want to use this technique + iPass = OGRE_NEW IlluminationPass(); + iPass->destroyOnShutdown = true; + iPass->originalPass = p; + iPass->pass = newPass; + iPass->stage = iStage; + mIlluminationPasses.push_back(iPass); + + } + } + ++i; // always increment on decal, since nothing more to do with this pass + + break; case IS_UNKNOWN: break; - } - } - } + } + } + } } //----------------------------------------------------------------------- @@ -1282,10 +1282,10 @@ namespace Ogre { mIlluminationPasses.end()); } //----------------------------------------------------------------------- - const String& Technique::getResourceGroup(void) const - { - return mParent->getGroup(); - } + const String& Technique::getResourceGroup(void) const + { + return mParent->getGroup(); + } //----------------------------------------------------------------------- bool Technique::applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply) const @@ -1303,114 +1303,114 @@ namespace Ogre { return testResult; } - //----------------------------------------------------------------------- - Ogre::MaterialPtr Technique::getShadowCasterMaterial() const - { - return mShadowCasterMaterial; - } - //----------------------------------------------------------------------- - void Technique::setShadowCasterMaterial(Ogre::MaterialPtr val) - { - if (val.isNull()) - { - mShadowCasterMaterial.setNull(); - mShadowCasterMaterialName.clear(); - } - else - { - mShadowCasterMaterial = val; - mShadowCasterMaterialName = val->getName(); - } - } - //----------------------------------------------------------------------- - void Technique::setShadowCasterMaterial(const Ogre::String &name) - { - mShadowCasterMaterialName = name; - mShadowCasterMaterial = MaterialManager::getSingleton().getByName(name); - } - //----------------------------------------------------------------------- - Ogre::MaterialPtr Technique::getShadowReceiverMaterial() const - { - return mShadowReceiverMaterial; - } - //----------------------------------------------------------------------- - void Technique::setShadowReceiverMaterial(Ogre::MaterialPtr val) - { - if (val.isNull()) - { - mShadowReceiverMaterial.setNull(); - mShadowReceiverMaterialName.clear(); - } - else - { - mShadowReceiverMaterial = val; - mShadowReceiverMaterialName = val->getName(); - } - } - //----------------------------------------------------------------------- - void Technique::setShadowReceiverMaterial(const Ogre::String &name) - { - mShadowReceiverMaterialName = name; - mShadowReceiverMaterial = MaterialManager::getSingleton().getByName(name); - } - //--------------------------------------------------------------------- - void Technique::addGPUVendorRule(GPUVendor vendor, Technique::IncludeOrExclude includeOrExclude) - { - addGPUVendorRule(GPUVendorRule(vendor, includeOrExclude)); - } - //--------------------------------------------------------------------- - void Technique::addGPUVendorRule(const Technique::GPUVendorRule& rule) - { - // remove duplicates - removeGPUVendorRule(rule.vendor); - mGPUVendorRules.push_back(rule); - } - //--------------------------------------------------------------------- - void Technique::removeGPUVendorRule(GPUVendor vendor) - { - for (GPUVendorRuleList::iterator i = mGPUVendorRules.begin(); i != mGPUVendorRules.end(); ) - { - if (i->vendor == vendor) - i = mGPUVendorRules.erase(i); - else - ++i; - } - } - //--------------------------------------------------------------------- - Technique::GPUVendorRuleIterator Technique::getGPUVendorRuleIterator() const - { - return GPUVendorRuleIterator(mGPUVendorRules.begin(), mGPUVendorRules.end()); - } - //--------------------------------------------------------------------- - void Technique::addGPUDeviceNameRule(const String& devicePattern, - Technique::IncludeOrExclude includeOrExclude, bool caseSensitive) - { - addGPUDeviceNameRule(GPUDeviceNameRule(devicePattern, includeOrExclude, caseSensitive)); - } - //--------------------------------------------------------------------- - void Technique::addGPUDeviceNameRule(const Technique::GPUDeviceNameRule& rule) - { - // remove duplicates - removeGPUDeviceNameRule(rule.devicePattern); - mGPUDeviceNameRules.push_back(rule); - } - //--------------------------------------------------------------------- - void Technique::removeGPUDeviceNameRule(const String& devicePattern) - { - for (GPUDeviceNameRuleList::iterator i = mGPUDeviceNameRules.begin(); i != mGPUDeviceNameRules.end(); ) - { - if (i->devicePattern == devicePattern) - i = mGPUDeviceNameRules.erase(i); - else - ++i; - } - } - //--------------------------------------------------------------------- - Technique::GPUDeviceNameRuleIterator Technique::getGPUDeviceNameRuleIterator() const - { - return GPUDeviceNameRuleIterator(mGPUDeviceNameRules.begin(), mGPUDeviceNameRules.end()); - } - //--------------------------------------------------------------------- + //----------------------------------------------------------------------- + Ogre::MaterialPtr Technique::getShadowCasterMaterial() const + { + return mShadowCasterMaterial; + } + //----------------------------------------------------------------------- + void Technique::setShadowCasterMaterial(Ogre::MaterialPtr val) + { + if (val.isNull()) + { + mShadowCasterMaterial.setNull(); + mShadowCasterMaterialName.clear(); + } + else + { + mShadowCasterMaterial = val; + mShadowCasterMaterialName = val->getName(); + } + } + //----------------------------------------------------------------------- + void Technique::setShadowCasterMaterial(const Ogre::String &name) + { + mShadowCasterMaterialName = name; + mShadowCasterMaterial = MaterialManager::getSingleton().getByName(name); + } + //----------------------------------------------------------------------- + Ogre::MaterialPtr Technique::getShadowReceiverMaterial() const + { + return mShadowReceiverMaterial; + } + //----------------------------------------------------------------------- + void Technique::setShadowReceiverMaterial(Ogre::MaterialPtr val) + { + if (val.isNull()) + { + mShadowReceiverMaterial.setNull(); + mShadowReceiverMaterialName.clear(); + } + else + { + mShadowReceiverMaterial = val; + mShadowReceiverMaterialName = val->getName(); + } + } + //----------------------------------------------------------------------- + void Technique::setShadowReceiverMaterial(const Ogre::String &name) + { + mShadowReceiverMaterialName = name; + mShadowReceiverMaterial = MaterialManager::getSingleton().getByName(name); + } + //--------------------------------------------------------------------- + void Technique::addGPUVendorRule(GPUVendor vendor, Technique::IncludeOrExclude includeOrExclude) + { + addGPUVendorRule(GPUVendorRule(vendor, includeOrExclude)); + } + //--------------------------------------------------------------------- + void Technique::addGPUVendorRule(const Technique::GPUVendorRule& rule) + { + // remove duplicates + removeGPUVendorRule(rule.vendor); + mGPUVendorRules.push_back(rule); + } + //--------------------------------------------------------------------- + void Technique::removeGPUVendorRule(GPUVendor vendor) + { + for (GPUVendorRuleList::iterator i = mGPUVendorRules.begin(); i != mGPUVendorRules.end(); ) + { + if (i->vendor == vendor) + i = mGPUVendorRules.erase(i); + else + ++i; + } + } + //--------------------------------------------------------------------- + Technique::GPUVendorRuleIterator Technique::getGPUVendorRuleIterator() const + { + return GPUVendorRuleIterator(mGPUVendorRules.begin(), mGPUVendorRules.end()); + } + //--------------------------------------------------------------------- + void Technique::addGPUDeviceNameRule(const String& devicePattern, + Technique::IncludeOrExclude includeOrExclude, bool caseSensitive) + { + addGPUDeviceNameRule(GPUDeviceNameRule(devicePattern, includeOrExclude, caseSensitive)); + } + //--------------------------------------------------------------------- + void Technique::addGPUDeviceNameRule(const Technique::GPUDeviceNameRule& rule) + { + // remove duplicates + removeGPUDeviceNameRule(rule.devicePattern); + mGPUDeviceNameRules.push_back(rule); + } + //--------------------------------------------------------------------- + void Technique::removeGPUDeviceNameRule(const String& devicePattern) + { + for (GPUDeviceNameRuleList::iterator i = mGPUDeviceNameRules.begin(); i != mGPUDeviceNameRules.end(); ) + { + if (i->devicePattern == devicePattern) + i = mGPUDeviceNameRules.erase(i); + else + ++i; + } + } + //--------------------------------------------------------------------- + Technique::GPUDeviceNameRuleIterator Technique::getGPUDeviceNameRuleIterator() const + { + return GPUDeviceNameRuleIterator(mGPUDeviceNameRules.begin(), mGPUDeviceNameRules.end()); + } + //--------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreTexture.cpp b/OgreMain/src/OgreTexture.cpp index d91dff9e7d2..393380bd8c9 100644 --- a/OgreMain/src/OgreTexture.cpp +++ b/OgreMain/src/OgreTexture.cpp @@ -34,7 +34,7 @@ THE SOFTWARE. #include "OgreTextureManager.h" namespace Ogre { - //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- Texture::Texture(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) @@ -43,12 +43,12 @@ namespace Ogre { mHeight(512), mWidth(512), mDepth(1), - mNumRequestedMipmaps(0), + mNumRequestedMipmaps(0), mNumMipmaps(0), - mMipmapsHardwareGenerated(false), + mMipmapsHardwareGenerated(false), mGamma(1.0f), - mHwGamma(false), - mFSAA(0), + mHwGamma(false), + mFSAA(0), mTextureType(TEX_TYPE_2D), mFormat(PF_UNKNOWN), mUsage(TU_DEFAULT), @@ -70,60 +70,60 @@ namespace Ogre { // information required. } - // Set some defaults for default load path - if (TextureManager::getSingletonPtr()) - { - TextureManager& tmgr = TextureManager::getSingleton(); - setNumMipmaps(tmgr.getDefaultNumMipmaps()); - setDesiredBitDepths(tmgr.getPreferredIntegerBitDepth(), tmgr.getPreferredFloatBitDepth()); - } + // Set some defaults for default load path + if (TextureManager::getSingletonPtr()) + { + TextureManager& tmgr = TextureManager::getSingleton(); + setNumMipmaps(tmgr.getDefaultNumMipmaps()); + setDesiredBitDepths(tmgr.getPreferredIntegerBitDepth(), tmgr.getPreferredFloatBitDepth()); + } } - //-------------------------------------------------------------------------- - void Texture::loadRawData( DataStreamPtr& stream, - ushort uWidth, ushort uHeight, PixelFormat eFormat) - { - Image img; - img.loadRawData(stream, uWidth, uHeight, eFormat); - loadImage(img); - } - //-------------------------------------------------------------------------- - void Texture::loadImage( const Image &img ) - { + //-------------------------------------------------------------------------- + void Texture::loadRawData( DataStreamPtr& stream, + ushort uWidth, ushort uHeight, PixelFormat eFormat) + { + Image img; + img.loadRawData(stream, uWidth, uHeight, eFormat); + loadImage(img); + } + //-------------------------------------------------------------------------- + void Texture::loadImage( const Image &img ) + { LoadingState old = mLoadingState.get(); if (old!=LOADSTATE_UNLOADED && old!=LOADSTATE_PREPARED) return; if (!mLoadingState.cas(old,LOADSTATE_LOADING)) return; - // Scope lock for actual loading - try - { + // Scope lock for actual loading + try + { OGRE_LOCK_AUTO_MUTEX; - vector::type imagePtrs; - imagePtrs.push_back(&img); - _loadImages( imagePtrs ); - - } - catch (...) - { - // Reset loading in-progress flag in case failed for some reason - mLoadingState.set(old); - // Re-throw - throw; - } + vector::type imagePtrs; + imagePtrs.push_back(&img); + _loadImages( imagePtrs ); + + } + catch (...) + { + // Reset loading in-progress flag in case failed for some reason + mLoadingState.set(old); + // Re-throw + throw; + } mLoadingState.set(LOADSTATE_LOADED); - // Notify manager - if(mCreator) - mCreator->_notifyResourceLoaded(this); + // Notify manager + if(mCreator) + mCreator->_notifyResourceLoaded(this); - // No deferred loading events since this method is not called in background + // No deferred loading events since this method is not called in background - } + } //-------------------------------------------------------------------------- void Texture::setFormat(PixelFormat pf) { @@ -173,26 +173,26 @@ namespace Ogre { return mTreatLuminanceAsAlpha; } //-------------------------------------------------------------------------- - size_t Texture::calculateSize(void) const - { + size_t Texture::calculateSize(void) const + { return getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); - } - //-------------------------------------------------------------------------- - size_t Texture::getNumFaces(void) const - { - return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1; - } - //-------------------------------------------------------------------------- + } + //-------------------------------------------------------------------------- + size_t Texture::getNumFaces(void) const + { + return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1; + } + //-------------------------------------------------------------------------- void Texture::_loadImages( const ConstImagePtrList& images ) { - if(images.size() < 1) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot load empty vector of images", - "Texture::loadImages"); + if(images.size() < 1) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot load empty vector of images", + "Texture::loadImages"); - // Set desired texture size and properties from images[0] - mSrcWidth = mWidth = images[0]->getWidth(); - mSrcHeight = mHeight = images[0]->getHeight(); - mSrcDepth = mDepth = images[0]->getDepth(); + // Set desired texture size and properties from images[0] + mSrcWidth = mWidth = images[0]->getWidth(); + mSrcHeight = mHeight = images[0]->getHeight(); + mSrcDepth = mDepth = images[0]->getDepth(); // Get source image format and adjust if required mSrcFormat = images[0]->getFormat(); @@ -212,38 +212,38 @@ namespace Ogre { mFormat = PixelUtil::getFormatForBitDepths(mSrcFormat, mDesiredIntegerBitDepth, mDesiredFloatBitDepth); } - // The custom mipmaps in the image have priority over everything + // The custom mipmaps in the image have priority over everything uint8 imageMips = images[0]->getNumMipmaps(); - if(imageMips > 0) - { - mNumMipmaps = mNumRequestedMipmaps = images[0]->getNumMipmaps(); - // Disable flag for auto mip generation - mUsage &= ~TU_AUTOMIPMAP; - } + if(imageMips > 0) + { + mNumMipmaps = mNumRequestedMipmaps = images[0]->getNumMipmaps(); + // Disable flag for auto mip generation + mUsage &= ~TU_AUTOMIPMAP; + } // Create the texture createInternalResources(); - // Check if we're loading one image with multiple faces - // or a vector of images representing the faces - size_t faces; - bool multiImage; // Load from multiple images? - if(images.size() > 1) - { - faces = images.size(); - multiImage = true; - } - else - { - faces = images[0]->getNumFaces(); - multiImage = false; - } - - // Check whether number of faces in images exceeds number of faces - // in this texture. If so, clamp it. - if(faces > getNumFaces()) - faces = getNumFaces(); - + // Check if we're loading one image with multiple faces + // or a vector of images representing the faces + size_t faces; + bool multiImage; // Load from multiple images? + if(images.size() > 1) + { + faces = images.size(); + multiImage = true; + } + else + { + faces = images[0]->getNumFaces(); + multiImage = false; + } + + // Check whether number of faces in images exceeds number of faces + // in this texture. If so, clamp it. + if(faces > getNumFaces()) + faces = getNumFaces(); + if (TextureManager::getSingleton().getVerbose()) { // Say what we're doing StringStream str; @@ -281,8 +281,8 @@ namespace Ogre { LogManager::getSingleton().logMessage( LML_NORMAL, str.str()); } - - // Main loading loop + + // Main loading loop // imageMips == 0 if the image has no custom mipmaps, otherwise contains the number of custom mips for(size_t mip = 0; mip <= std::min(mNumMipmaps, imageMips); ++mip) { @@ -334,29 +334,29 @@ namespace Ogre { mSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); } - //----------------------------------------------------------------------------- - void Texture::createInternalResources(void) - { - if (!mInternalResourcesCreated) - { - createInternalResourcesImpl(); - mInternalResourcesCreated = true; - } - } - //----------------------------------------------------------------------------- - void Texture::freeInternalResources(void) - { - if (mInternalResourcesCreated) - { - freeInternalResourcesImpl(); - mInternalResourcesCreated = false; - } - } - //----------------------------------------------------------------------------- - void Texture::unloadImpl(void) - { - freeInternalResources(); - } + //----------------------------------------------------------------------------- + void Texture::createInternalResources(void) + { + if (!mInternalResourcesCreated) + { + createInternalResourcesImpl(); + mInternalResourcesCreated = true; + } + } + //----------------------------------------------------------------------------- + void Texture::freeInternalResources(void) + { + if (mInternalResourcesCreated) + { + freeInternalResourcesImpl(); + mInternalResourcesCreated = false; + } + } + //----------------------------------------------------------------------------- + void Texture::unloadImpl(void) + { + freeInternalResources(); + } //----------------------------------------------------------------------------- void Texture::copyToTexture( TexturePtr& target ) { @@ -377,78 +377,78 @@ namespace Ogre { } } } - //--------------------------------------------------------------------- - String Texture::getSourceFileType() const - { - if (mName.empty()) - return BLANKSTRING; - - String::size_type pos = mName.find_last_of("."); - if (pos != String::npos && pos < (mName.length() - 1)) - { - String ext = mName.substr(pos+1); - StringUtil::toLowerCase(ext); - return ext; - } - else - { - // No extension - DataStreamPtr dstream; - try - { - dstream = ResourceGroupManager::getSingleton().openResource( - mName, mGroup, true, 0); - } - catch (Exception&) - { - } - if (dstream.isNull() && getTextureType() == TEX_TYPE_CUBE_MAP) - { - // try again with one of the faces (non-dds) - try - { - dstream = ResourceGroupManager::getSingleton().openResource( - mName + "_rt", mGroup, true, 0); - } - catch (Exception&) - { - } - } - - if (!dstream.isNull()) - { - return Image::getFileExtFromMagic(dstream); - } - } - - return BLANKSTRING; - - } - //--------------------------------------------------------------------- - void Texture::convertToImage(Image& destImage, bool includeMipMaps) - { - - size_t numMips = includeMipMaps? getNumMipmaps() + 1 : 1; - size_t dataSize = Image::calculateSize(numMips, - getNumFaces(), getWidth(), getHeight(), getDepth(), getFormat()); - - void* pixData = OGRE_MALLOC(dataSize, Ogre::MEMCATEGORY_GENERAL); - // if there are multiple faces and mipmaps we must pack them into the data - // faces, then mips - void* currentPixData = pixData; - for (size_t face = 0; face < getNumFaces(); ++face) - { + //--------------------------------------------------------------------- + String Texture::getSourceFileType() const + { + if (mName.empty()) + return BLANKSTRING; + + String::size_type pos = mName.find_last_of("."); + if (pos != String::npos && pos < (mName.length() - 1)) + { + String ext = mName.substr(pos+1); + StringUtil::toLowerCase(ext); + return ext; + } + else + { + // No extension + DataStreamPtr dstream; + try + { + dstream = ResourceGroupManager::getSingleton().openResource( + mName, mGroup, true, 0); + } + catch (Exception&) + { + } + if (dstream.isNull() && getTextureType() == TEX_TYPE_CUBE_MAP) + { + // try again with one of the faces (non-dds) + try + { + dstream = ResourceGroupManager::getSingleton().openResource( + mName + "_rt", mGroup, true, 0); + } + catch (Exception&) + { + } + } + + if (!dstream.isNull()) + { + return Image::getFileExtFromMagic(dstream); + } + } + + return BLANKSTRING; + + } + //--------------------------------------------------------------------- + void Texture::convertToImage(Image& destImage, bool includeMipMaps) + { + + size_t numMips = includeMipMaps? getNumMipmaps() + 1 : 1; + size_t dataSize = Image::calculateSize(numMips, + getNumFaces(), getWidth(), getHeight(), getDepth(), getFormat()); + + void* pixData = OGRE_MALLOC(dataSize, Ogre::MEMCATEGORY_GENERAL); + // if there are multiple faces and mipmaps we must pack them into the data + // faces, then mips + void* currentPixData = pixData; + for (size_t face = 0; face < getNumFaces(); ++face) + { uint32 width = getWidth(); uint32 height = getHeight(); uint32 depth = getDepth(); - for (size_t mip = 0; mip < numMips; ++mip) - { - size_t mipDataSize = PixelUtil::getMemorySize(width, height, depth, getFormat()); + for (size_t mip = 0; mip < numMips; ++mip) + { + size_t mipDataSize = PixelUtil::getMemorySize(width, height, depth, getFormat()); - Ogre::PixelBox pixBox(width, height, depth, getFormat(), currentPixData); - getBuffer(face, mip)->blitToMemory(pixBox); + Ogre::PixelBox pixBox(width, height, depth, getFormat(), currentPixData); + getBuffer(face, mip)->blitToMemory(pixBox); - currentPixData = (void*)((char*)currentPixData + mipDataSize); + currentPixData = (void*)((char*)currentPixData + mipDataSize); if(width != 1) width /= 2; @@ -456,13 +456,13 @@ namespace Ogre { height /= 2; if(depth != 1) depth /= 2; - } - } + } + } - // load, and tell Image to delete the memory when it's done. - destImage.loadDynamicImage((Ogre::uchar*)pixData, getWidth(), getHeight(), getDepth(), getFormat(), true, - getNumFaces(), numMips - 1); - } + // load, and tell Image to delete the memory when it's done. + destImage.loadDynamicImage((Ogre::uchar*)pixData, getWidth(), getHeight(), getDepth(), getFormat(), true, + getNumFaces(), numMips - 1); + } } diff --git a/OgreMain/src/OgreTextureManager.cpp b/OgreMain/src/OgreTextureManager.cpp index c5397c425f3..6587047e17f 100644 --- a/OgreMain/src/OgreTextureManager.cpp +++ b/OgreMain/src/OgreTextureManager.cpp @@ -77,19 +77,19 @@ namespace Ogre { const NameValuePairList* createParams, TextureType texType, int numMipmaps, Real gamma, bool isAlpha, PixelFormat desiredFormat, bool hwGamma) { - ResourceCreateOrRetrieveResult res = + ResourceCreateOrRetrieveResult res = Ogre::ResourceManager::createOrRetrieve(name, group, isManual, loader, createParams); - // Was it created? - if(res.second) + // Was it created? + if(res.second) { TexturePtr tex = res.first.staticCast(); tex->setTextureType(texType); tex->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps : - static_cast(numMipmaps)); + static_cast(numMipmaps)); tex->setGamma(gamma); tex->setTreatLuminanceAsAlpha(isAlpha); tex->setFormat(desiredFormat); - tex->setHardwareGammaEnabled(hwGamma); + tex->setHardwareGammaEnabled(hwGamma); } return res; } @@ -98,10 +98,10 @@ namespace Ogre { int numMipmaps, Real gamma, bool isAlpha, PixelFormat desiredFormat, bool hwGamma) { - ResourceCreateOrRetrieveResult res = + ResourceCreateOrRetrieveResult res = createOrRetrieve(name,group,false,0,0,texType,numMipmaps,gamma,isAlpha,desiredFormat,hwGamma); TexturePtr tex = res.first.staticCast(); - tex->prepare(); + tex->prepare(); return tex; } //----------------------------------------------------------------------- @@ -109,27 +109,27 @@ namespace Ogre { int numMipmaps, Real gamma, bool isAlpha, PixelFormat desiredFormat, bool hwGamma) { - ResourceCreateOrRetrieveResult res = + ResourceCreateOrRetrieveResult res = createOrRetrieve(name,group,false,0,0,texType,numMipmaps,gamma,isAlpha,desiredFormat,hwGamma); TexturePtr tex = res.first.staticCast(); - tex->load(); + tex->load(); return tex; } //----------------------------------------------------------------------- TexturePtr TextureManager::loadImage( const String &name, const String& group, const Image &img, TextureType texType, int numMipmaps, Real gamma, bool isAlpha, - PixelFormat desiredFormat, bool hwGamma) + PixelFormat desiredFormat, bool hwGamma) { TexturePtr tex = createResource(name, group, true).staticCast(); tex->setTextureType(texType); tex->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps : - static_cast(numMipmaps)); + static_cast(numMipmaps)); tex->setGamma(gamma); tex->setTreatLuminanceAsAlpha(isAlpha); tex->setFormat(desiredFormat); - tex->setHardwareGammaEnabled(hwGamma); + tex->setHardwareGammaEnabled(hwGamma); tex->loadImage(img); return tex; @@ -139,29 +139,29 @@ namespace Ogre { DataStreamPtr& stream, ushort uWidth, ushort uHeight, PixelFormat format, TextureType texType, int numMipmaps, Real gamma, bool hwGamma) - { - TexturePtr tex = createResource(name, group, true).staticCast(); + { + TexturePtr tex = createResource(name, group, true).staticCast(); tex->setTextureType(texType); tex->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps : - static_cast(numMipmaps)); + static_cast(numMipmaps)); tex->setGamma(gamma); - tex->setHardwareGammaEnabled(hwGamma); - tex->loadRawData(stream, uWidth, uHeight, format); - + tex->setHardwareGammaEnabled(hwGamma); + tex->loadRawData(stream, uWidth, uHeight, format); + return tex; - } + } //----------------------------------------------------------------------- TexturePtr TextureManager::createManual(const String & name, const String& group, TextureType texType, uint width, uint height, uint depth, int numMipmaps, PixelFormat format, int usage, ManualResourceLoader* loader, bool hwGamma, - uint fsaa, const String& fsaaHint) + uint fsaa, const String& fsaaHint) { TexturePtr ret; ret.setNull(); // Check for 3D texture support - const RenderSystemCapabilities* caps = + const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); if (((texType == TEX_TYPE_3D) || (texType == TEX_TYPE_2D_ARRAY)) && !caps->hasCapability(RSC_TEXTURE_3D)) @@ -175,15 +175,15 @@ namespace Ogre { ret->setTextureType(texType); ret->setWidth(width); ret->setHeight(height); - ret->setDepth(depth); + ret->setDepth(depth); ret->setNumMipmaps((numMipmaps == MIP_DEFAULT)? mDefaultNumMipmaps : - static_cast(numMipmaps)); + static_cast(numMipmaps)); ret->setFormat(format); ret->setUsage(usage); - ret->setHardwareGammaEnabled(hwGamma); - ret->setFSAA(fsaa, fsaaHint); - ret->createInternalResources(); - return ret; + ret->setHardwareGammaEnabled(hwGamma); + ret->setFSAA(fsaa, fsaaHint); + ret->createInternalResources(); + return ret; } //----------------------------------------------------------------------- void TextureManager::setPreferredIntegerBitDepth(ushort bits, bool reloadTextures) @@ -277,17 +277,17 @@ namespace Ogre { mDefaultNumMipmaps = num; } //----------------------------------------------------------------------- - bool TextureManager::isFormatSupported(TextureType ttype, PixelFormat format, int usage) - { - return getNativeFormat(ttype, format, usage) == format; - } + bool TextureManager::isFormatSupported(TextureType ttype, PixelFormat format, int usage) + { + return getNativeFormat(ttype, format, usage) == format; + } //----------------------------------------------------------------------- - bool TextureManager::isEquivalentFormatSupported(TextureType ttype, PixelFormat format, int usage) - { - PixelFormat supportedFormat = getNativeFormat(ttype, format, usage); + bool TextureManager::isEquivalentFormatSupported(TextureType ttype, PixelFormat format, int usage) + { + PixelFormat supportedFormat = getNativeFormat(ttype, format, usage); - // Assume that same or greater number of bits means quality not degraded - return PixelUtil::getNumElemBits(supportedFormat) >= PixelUtil::getNumElemBits(format); - - } + // Assume that same or greater number of bits means quality not degraded + return PixelUtil::getNumElemBits(supportedFormat) >= PixelUtil::getNumElemBits(format); + + } } diff --git a/OgreMain/src/OgreTextureUnitState.cpp b/OgreMain/src/OgreTextureUnitState.cpp index 5d76018d52c..8b7d2151517 100644 --- a/OgreMain/src/OgreTextureUnitState.cpp +++ b/OgreMain/src/OgreTextureUnitState.cpp @@ -41,50 +41,50 @@ namespace Ogre { //----------------------------------------------------------------------- TextureUnitState::TextureUnitState(Pass* parent) : mCurrentFrame(0) - , mAnimDuration(0) - , mCubic(false) - , mTextureType(TEX_TYPE_2D) + , mAnimDuration(0) + , mCubic(false) + , mTextureType(TEX_TYPE_2D) , mDesiredFormat(PF_UNKNOWN) - , mTextureSrcMipmaps(MIP_DEFAULT) - , mTextureCoordSetIndex(0) - , mBorderColour(ColourValue::Black) - , mTextureLoadFailed(false) - , mIsAlpha(false) - , mHwGamma(false) - , mGamma(1) - , mRecalcTexMatrix(false) - , mUMod(0) - , mVMod(0) - , mUScale(1) - , mVScale(1) - , mRotate(0) - , mTexModMatrix(Matrix4::IDENTITY) - , mMinFilter(FO_LINEAR) - , mMagFilter(FO_LINEAR) - , mMipFilter(FO_POINT) - , mCompareEnabled(false) - , mCompareFunc(CMPF_GREATER_EQUAL) - , mMaxAniso(MaterialManager::getSingleton().getDefaultAnisotropy()) - , mMipmapBias(0) - , mIsDefaultAniso(true) - , mIsDefaultFiltering(true) - , mBindingType(BT_FRAGMENT) - , mContentType(CONTENT_NAMED) - , mParent(parent) - , mAnimController(0) - { - mColourBlendMode.blendType = LBT_COLOUR; - mAlphaBlendMode.operation = LBX_MODULATE; - mAlphaBlendMode.blendType = LBT_ALPHA; - mAlphaBlendMode.source1 = LBS_TEXTURE; - mAlphaBlendMode.source2 = LBS_CURRENT; - setColourOperation(LBO_MODULATE); - setTextureAddressingMode(TAM_WRAP); - - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } + , mTextureSrcMipmaps(MIP_DEFAULT) + , mTextureCoordSetIndex(0) + , mBorderColour(ColourValue::Black) + , mTextureLoadFailed(false) + , mIsAlpha(false) + , mHwGamma(false) + , mGamma(1) + , mRecalcTexMatrix(false) + , mUMod(0) + , mVMod(0) + , mUScale(1) + , mVScale(1) + , mRotate(0) + , mTexModMatrix(Matrix4::IDENTITY) + , mMinFilter(FO_LINEAR) + , mMagFilter(FO_LINEAR) + , mMipFilter(FO_POINT) + , mCompareEnabled(false) + , mCompareFunc(CMPF_GREATER_EQUAL) + , mMaxAniso(MaterialManager::getSingleton().getDefaultAnisotropy()) + , mMipmapBias(0) + , mIsDefaultAniso(true) + , mIsDefaultFiltering(true) + , mBindingType(BT_FRAGMENT) + , mContentType(CONTENT_NAMED) + , mParent(parent) + , mAnimController(0) + { + mColourBlendMode.blendType = LBT_COLOUR; + mAlphaBlendMode.operation = LBX_MODULATE; + mAlphaBlendMode.blendType = LBT_ALPHA; + mAlphaBlendMode.source1 = LBS_TEXTURE; + mAlphaBlendMode.source2 = LBS_CURRENT; + setColourOperation(LBO_MODULATE); + setTextureAddressingMode(TAM_WRAP); + + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } } @@ -98,52 +98,52 @@ namespace Ogre { //----------------------------------------------------------------------- TextureUnitState::TextureUnitState( Pass* parent, const String& texName, unsigned int texCoordSet) - : mCurrentFrame(0) - , mAnimDuration(0) - , mCubic(false) - , mTextureType(TEX_TYPE_2D) + : mCurrentFrame(0) + , mAnimDuration(0) + , mCubic(false) + , mTextureType(TEX_TYPE_2D) , mDesiredFormat(PF_UNKNOWN) - , mTextureSrcMipmaps(MIP_DEFAULT) - , mTextureCoordSetIndex(0) - , mBorderColour(ColourValue::Black) - , mTextureLoadFailed(false) - , mIsAlpha(false) - , mHwGamma(false) - , mGamma(1) - , mRecalcTexMatrix(false) - , mUMod(0) - , mVMod(0) - , mUScale(1) - , mVScale(1) - , mRotate(0) - , mTexModMatrix(Matrix4::IDENTITY) - , mMinFilter(FO_LINEAR) - , mMagFilter(FO_LINEAR) - , mMipFilter(FO_POINT) - , mMaxAniso(MaterialManager::getSingleton().getDefaultAnisotropy()) - , mMipmapBias(0) - , mIsDefaultAniso(true) - , mIsDefaultFiltering(true) - , mBindingType(BT_FRAGMENT) - , mContentType(CONTENT_NAMED) - , mParent(parent) - , mAnimController(0) - { - mColourBlendMode.blendType = LBT_COLOUR; - mAlphaBlendMode.operation = LBX_MODULATE; - mAlphaBlendMode.blendType = LBT_ALPHA; - mAlphaBlendMode.source1 = LBS_TEXTURE; - mAlphaBlendMode.source2 = LBS_CURRENT; - setColourOperation(LBO_MODULATE); - setTextureAddressingMode(TAM_WRAP); + , mTextureSrcMipmaps(MIP_DEFAULT) + , mTextureCoordSetIndex(0) + , mBorderColour(ColourValue::Black) + , mTextureLoadFailed(false) + , mIsAlpha(false) + , mHwGamma(false) + , mGamma(1) + , mRecalcTexMatrix(false) + , mUMod(0) + , mVMod(0) + , mUScale(1) + , mVScale(1) + , mRotate(0) + , mTexModMatrix(Matrix4::IDENTITY) + , mMinFilter(FO_LINEAR) + , mMagFilter(FO_LINEAR) + , mMipFilter(FO_POINT) + , mMaxAniso(MaterialManager::getSingleton().getDefaultAnisotropy()) + , mMipmapBias(0) + , mIsDefaultAniso(true) + , mIsDefaultFiltering(true) + , mBindingType(BT_FRAGMENT) + , mContentType(CONTENT_NAMED) + , mParent(parent) + , mAnimController(0) + { + mColourBlendMode.blendType = LBT_COLOUR; + mAlphaBlendMode.operation = LBX_MODULATE; + mAlphaBlendMode.blendType = LBT_ALPHA; + mAlphaBlendMode.source1 = LBS_TEXTURE; + mAlphaBlendMode.source2 = LBS_CURRENT; + setColourOperation(LBO_MODULATE); + setTextureAddressingMode(TAM_WRAP); setTextureName(texName); setTextureCoordSet(texCoordSet); - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } } //----------------------------------------------------------------------- @@ -163,13 +163,13 @@ namespace Ogre { memcpy( this, &oth, (const uchar *)(&oth.mFrames) - (const uchar *)(&oth) ); // copy complex members mFrames = oth.mFrames; - mFramePtrs = oth.mFramePtrs; + mFramePtrs = oth.mFramePtrs; mName = oth.mName; mEffects = oth.mEffects; mTextureNameAlias = oth.mTextureNameAlias; - mCompositorRefName = oth.mCompositorRefName; - mCompositorRefTexName = oth.mCompositorRefTexName; + mCompositorRefName = oth.mCompositorRefName; + mCompositorRefTexName = oth.mCompositorRefTexName; // Can't sharing controllers with other TUS, reset to null to avoid potential bug. for (EffectMap::iterator j = mEffects.begin(); j != mEffects.end(); ++j) { @@ -182,11 +182,11 @@ namespace Ogre { _load(); } - // Tell parent to recalculate hash - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } + // Tell parent to recalculate hash + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } return *this; } @@ -202,10 +202,10 @@ namespace Ogre { //----------------------------------------------------------------------- void TextureUnitState::setTextureName( const String& name, TextureType texType) { - setContentType(CONTENT_NAMED); - mTextureLoadFailed = false; + setContentType(CONTENT_NAMED); + mTextureLoadFailed = false; - if (texType == TEX_TYPE_CUBE_MAP) + if (texType == TEX_TYPE_CUBE_MAP) { // delegate to cubic texture implementation setCubicTextureName(name, true); @@ -213,10 +213,10 @@ namespace Ogre { else { mFrames.resize(1); - mFramePtrs.resize(1); + mFramePtrs.resize(1); mFrames[0] = name; - mFramePtrs[0].setNull(); - // defer load until used, so don't grab pointer yet + mFramePtrs[0].setNull(); + // defer load until used, so don't grab pointer yet mCurrentFrame = 0; mCubic = false; mTextureType = texType; @@ -231,84 +231,84 @@ namespace Ogre { { _load(); // reload } - // Tell parent to recalculate hash - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } - } - - } - //----------------------------------------------------------------------- - void TextureUnitState::setTexture( const TexturePtr& texPtr) - { - if (texPtr.isNull()) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Texture Pointer is empty.", - "TextureUnitState::setTexture"); - } - - setContentType(CONTENT_NAMED); - mTextureLoadFailed = false; - - if (texPtr->getTextureType() == TEX_TYPE_CUBE_MAP) - { - // delegate to cubic texture implementation - setCubicTexture(&texPtr, true); - } - else - { - mFrames.resize(1); - mFramePtrs.resize(1); - mFrames[0] = texPtr->getName(); - mFramePtrs[0] = texPtr; - // defer load until used, so don't grab pointer yet - mCurrentFrame = 0; - mCubic = false; - mTextureType = texPtr->getTextureType(); - - // Load immediately ? - if (isLoaded()) - { - _load(); // reload - } - // Tell parent to recalculate hash - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } - } - } - //----------------------------------------------------------------------- - void TextureUnitState::setBindingType(TextureUnitState::BindingType bt) - { - mBindingType = bt; - - } - //----------------------------------------------------------------------- - TextureUnitState::BindingType TextureUnitState::getBindingType(void) const - { - return mBindingType; - } - //----------------------------------------------------------------------- - void TextureUnitState::setContentType(TextureUnitState::ContentType ct) - { - mContentType = ct; - if (ct == CONTENT_SHADOW || ct == CONTENT_COMPOSITOR) - { - // Clear out texture frames, not applicable - mFrames.clear(); - // One reference space, set manually through _setTexturePtr - mFramePtrs.resize(1); - mFramePtrs[0].setNull(); - } - } - //----------------------------------------------------------------------- - TextureUnitState::ContentType TextureUnitState::getContentType(void) const - { - return mContentType; - } + // Tell parent to recalculate hash + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } + } + + } + //----------------------------------------------------------------------- + void TextureUnitState::setTexture( const TexturePtr& texPtr) + { + if (texPtr.isNull()) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Texture Pointer is empty.", + "TextureUnitState::setTexture"); + } + + setContentType(CONTENT_NAMED); + mTextureLoadFailed = false; + + if (texPtr->getTextureType() == TEX_TYPE_CUBE_MAP) + { + // delegate to cubic texture implementation + setCubicTexture(&texPtr, true); + } + else + { + mFrames.resize(1); + mFramePtrs.resize(1); + mFrames[0] = texPtr->getName(); + mFramePtrs[0] = texPtr; + // defer load until used, so don't grab pointer yet + mCurrentFrame = 0; + mCubic = false; + mTextureType = texPtr->getTextureType(); + + // Load immediately ? + if (isLoaded()) + { + _load(); // reload + } + // Tell parent to recalculate hash + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } + } + } + //----------------------------------------------------------------------- + void TextureUnitState::setBindingType(TextureUnitState::BindingType bt) + { + mBindingType = bt; + + } + //----------------------------------------------------------------------- + TextureUnitState::BindingType TextureUnitState::getBindingType(void) const + { + return mBindingType; + } + //----------------------------------------------------------------------- + void TextureUnitState::setContentType(TextureUnitState::ContentType ct) + { + mContentType = ct; + if (ct == CONTENT_SHADOW || ct == CONTENT_COMPOSITOR) + { + // Clear out texture frames, not applicable + mFrames.clear(); + // One reference space, set manually through _setTexturePtr + mFramePtrs.resize(1); + mFramePtrs[0].setNull(); + } + } + //----------------------------------------------------------------------- + TextureUnitState::ContentType TextureUnitState::getContentType(void) const + { + return mContentType; + } //----------------------------------------------------------------------- void TextureUnitState::setCubicTextureName( const String& name, bool forUVW) { @@ -318,21 +318,21 @@ namespace Ogre { } else { - setContentType(CONTENT_NAMED); - mTextureLoadFailed = false; + setContentType(CONTENT_NAMED); + mTextureLoadFailed = false; String ext; String suffixes[6] = {"_fr", "_bk", "_lf", "_rt", "_up", "_dn"}; String baseName; String fullNames[6]; size_t pos = name.find_last_of("."); - if( pos != String::npos ) - { - baseName = name.substr(0, pos); - ext = name.substr(pos); - } - else - baseName = name; + if( pos != String::npos ) + { + baseName = name.substr(0, pos); + ext = name.substr(pos); + } + else + baseName = name; for (int i = 0; i < 6; ++i) { @@ -345,12 +345,12 @@ namespace Ogre { //----------------------------------------------------------------------- void TextureUnitState::setCubicTextureName(const String* const names, bool forUVW) { - setContentType(CONTENT_NAMED); - mTextureLoadFailed = false; + setContentType(CONTENT_NAMED); + mTextureLoadFailed = false; mFrames.resize(forUVW ? 1 : 6); - // resize pointers, but don't populate until asked for + // resize pointers, but don't populate until asked for mFramePtrs.resize(forUVW ? 1 : 6); - mAnimDuration = 0; + mAnimDuration = 0; mCurrentFrame = 0; mCubic = true; mTextureType = forUVW ? TEX_TYPE_CUBE_MAP : TEX_TYPE_2D; @@ -358,31 +358,31 @@ namespace Ogre { for (unsigned int i = 0; i < mFrames.size(); ++i) { mFrames[i] = names[i]; - mFramePtrs[i].setNull(); + mFramePtrs[i].setNull(); } // Tell parent we need recompiling, will cause reload too mParent->_notifyNeedsRecompile(); } //----------------------------------------------------------------------- - void TextureUnitState::setCubicTexture( const TexturePtr* const texPtrs, bool forUVW ) + void TextureUnitState::setCubicTexture( const TexturePtr* const texPtrs, bool forUVW ) { - setContentType(CONTENT_NAMED); - mTextureLoadFailed = false; - mFrames.resize(forUVW ? 1 : 6); - // resize pointers, but don't populate until asked for - mFramePtrs.resize(forUVW ? 1 : 6); - mAnimDuration = 0; - mCurrentFrame = 0; - mCubic = true; - mTextureType = forUVW ? TEX_TYPE_CUBE_MAP : TEX_TYPE_2D; + setContentType(CONTENT_NAMED); + mTextureLoadFailed = false; + mFrames.resize(forUVW ? 1 : 6); + // resize pointers, but don't populate until asked for + mFramePtrs.resize(forUVW ? 1 : 6); + mAnimDuration = 0; + mCurrentFrame = 0; + mCubic = true; + mTextureType = forUVW ? TEX_TYPE_CUBE_MAP : TEX_TYPE_2D; - for (unsigned int i = 0; i < mFrames.size(); ++i) - { - mFrames[i] = texPtrs[i]->getName(); - mFramePtrs[i] = texPtrs[i]; - } - // Tell parent we need recompiling, will cause reload too - mParent->_notifyNeedsRecompile(); + for (unsigned int i = 0; i < mFrames.size(); ++i) + { + mFrames[i] = texPtrs[i]->getName(); + mFramePtrs[i] = texPtrs[i]; + } + // Tell parent we need recompiling, will cause reload too + mParent->_notifyNeedsRecompile(); } //----------------------------------------------------------------------- bool TextureUnitState::isCubic(void) const @@ -404,22 +404,22 @@ namespace Ogre { //----------------------------------------------------------------------- void TextureUnitState::setFrameTextureName(const String& name, unsigned int frameNumber) { - mTextureLoadFailed = false; + mTextureLoadFailed = false; if (frameNumber < mFrames.size()) { mFrames[frameNumber] = name; - // reset pointer (don't populate until requested) - mFramePtrs[frameNumber].setNull(); + // reset pointer (don't populate until requested) + mFramePtrs[frameNumber].setNull(); if (isLoaded()) { _load(); // reload } - // Tell parent to recalculate hash - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } + // Tell parent to recalculate hash + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } } else // raise exception for frameNumber out of bounds { @@ -431,29 +431,29 @@ namespace Ogre { //----------------------------------------------------------------------- void TextureUnitState::addFrameTextureName(const String& name) { - setContentType(CONTENT_NAMED); - mTextureLoadFailed = false; + setContentType(CONTENT_NAMED); + mTextureLoadFailed = false; mFrames.push_back(name); - // Add blank pointer, load on demand - mFramePtrs.push_back(TexturePtr()); + // Add blank pointer, load on demand + mFramePtrs.push_back(TexturePtr()); // Load immediately if Material loaded if (isLoaded()) { _load(); } - // Tell parent to recalculate hash - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } + // Tell parent to recalculate hash + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } } //----------------------------------------------------------------------- void TextureUnitState::deleteFrameTextureName(const size_t frameNumber) { - mTextureLoadFailed = false; + mTextureLoadFailed = false; if (frameNumber < mFrames.size()) { mFrames.erase(mFrames.begin() + frameNumber); @@ -463,11 +463,11 @@ namespace Ogre { { _load(); } - // Tell parent to recalculate hash - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } + // Tell parent to recalculate hash + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } } else { @@ -479,10 +479,10 @@ namespace Ogre { //----------------------------------------------------------------------- void TextureUnitState::setAnimatedTextureName( const String& name, unsigned int numFrames, Real duration) { - setContentType(CONTENT_NAMED); - mTextureLoadFailed = false; + setContentType(CONTENT_NAMED); + mTextureLoadFailed = false; - String ext; + String ext; String baseName; size_t pos = name.find_last_of("."); @@ -490,7 +490,7 @@ namespace Ogre { ext = name.substr(pos); mFrames.resize(numFrames); - // resize pointers, but don't populate until needed + // resize pointers, but don't populate until needed mFramePtrs.resize(numFrames); mAnimDuration = duration; mCurrentFrame = 0; @@ -498,10 +498,10 @@ namespace Ogre { for (unsigned int i = 0; i < mFrames.size(); ++i) { - StringStream str; + StringStream str; str << baseName << "_" << i << ext; mFrames[i] = str.str(); - mFramePtrs[i].setNull(); + mFramePtrs[i].setNull(); } // Load immediately if Material loaded @@ -509,21 +509,21 @@ namespace Ogre { { _load(); } - // Tell parent to recalculate hash - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } + // Tell parent to recalculate hash + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } } //----------------------------------------------------------------------- void TextureUnitState::setAnimatedTextureName(const String* const names, unsigned int numFrames, Real duration) { - setContentType(CONTENT_NAMED); - mTextureLoadFailed = false; + setContentType(CONTENT_NAMED); + mTextureLoadFailed = false; - mFrames.resize(numFrames); - // resize pointers, but don't populate until needed + mFrames.resize(numFrames); + // resize pointers, but don't populate until needed mFramePtrs.resize(numFrames); mAnimDuration = duration; mCurrentFrame = 0; @@ -532,7 +532,7 @@ namespace Ogre { for (unsigned int i = 0; i < mFrames.size(); ++i) { mFrames[i] = names[i]; - mFramePtrs[i].setNull(); + mFramePtrs[i].setNull(); } // Load immediately if Material loaded @@ -540,22 +540,22 @@ namespace Ogre { { _load(); } - // Tell parent to recalculate hash - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } + // Tell parent to recalculate hash + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } } //----------------------------------------------------------------------- std::pair< size_t, size_t > TextureUnitState::getTextureDimensions( unsigned int frame ) const { - - TexturePtr tex = _getTexturePtr(frame); - if (tex.isNull()) - OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find texture " + mFrames[ frame ], - "TextureUnitState::getTextureDimensions" ); + + TexturePtr tex = _getTexturePtr(frame); + if (tex.isNull()) + OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find texture " + mFrames[ frame ], + "TextureUnitState::getTextureDimensions" ); - return std::pair< size_t, size_t >( tex->getWidth(), tex->getHeight() ); + return std::pair< size_t, size_t >( tex->getWidth(), tex->getHeight() ); } //----------------------------------------------------------------------- void TextureUnitState::setCurrentFrame(unsigned int frameNumber) @@ -564,10 +564,10 @@ namespace Ogre { { mCurrentFrame = frameNumber; // this will affect the hash - if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) - { - mParent->_dirtyHash(); - } + if( Pass::getHashFunction() == Pass::getBuiltinHashFunction( Pass::MIN_TEXTURE_CHANGE ) ) + { + mParent->_dirtyHash(); + } } else { @@ -627,16 +627,16 @@ namespace Ogre { { return mIsAlpha; } - //----------------------------------------------------------------------- - void TextureUnitState::setHardwareGammaEnabled(bool g) - { - mHwGamma = g; - } - //----------------------------------------------------------------------- - bool TextureUnitState::isHardwareGammaEnabled() const - { - return mHwGamma; - } + //----------------------------------------------------------------------- + void TextureUnitState::setHardwareGammaEnabled(bool g) + { + mHwGamma = g; + } + //----------------------------------------------------------------------- + bool TextureUnitState::isHardwareGammaEnabled() const + { + return mHwGamma; + } //----------------------------------------------------------------------- unsigned int TextureUnitState::getTextureCoordSet(void) const { @@ -716,10 +716,10 @@ namespace Ogre { effect.controller = 0; if (effect.type == ET_ENVIRONMENT_MAP - || effect.type == ET_UVSCROLL - || effect.type == ET_USCROLL - || effect.type == ET_VSCROLL - || effect.type == ET_ROTATE + || effect.type == ET_UVSCROLL + || effect.type == ET_USCROLL + || effect.type == ET_VSCROLL + || effect.type == ET_ROTATE || effect.type == ET_PROJECTIVE_TEXTURE) { // Replace - must be unique @@ -767,10 +767,10 @@ namespace Ogre { //----------------------------------------------------------------------- bool TextureUnitState::isBlank(void) const { - if (mFrames.empty()) - return true; - else - return mFrames[0].empty() || mTextureLoadFailed; + if (mFrames.empty()) + return true; + else + return mFrames[0].empty() || mTextureLoadFailed; } //----------------------------------------------------------------------- @@ -795,13 +795,13 @@ namespace Ogre { } //----------------------------------------------------------------------- const TextureUnitState::UVWAddressingMode& - TextureUnitState::getTextureAddressingMode(void) const + TextureUnitState::getTextureAddressingMode(void) const { return mAddressMode; } //----------------------------------------------------------------------- void TextureUnitState::setTextureAddressingMode( - TextureUnitState::TextureAddressingMode tam) + TextureUnitState::TextureAddressingMode tam) { mAddressMode.u = tam; mAddressMode.v = tam; @@ -809,9 +809,9 @@ namespace Ogre { } //----------------------------------------------------------------------- void TextureUnitState::setTextureAddressingMode( - TextureUnitState::TextureAddressingMode u, - TextureUnitState::TextureAddressingMode v, - TextureUnitState::TextureAddressingMode w) + TextureUnitState::TextureAddressingMode u, + TextureUnitState::TextureAddressingMode v, + TextureUnitState::TextureAddressingMode w) { mAddressMode.u = u; mAddressMode.v = v; @@ -819,7 +819,7 @@ namespace Ogre { } //----------------------------------------------------------------------- void TextureUnitState::setTextureAddressingMode( - const TextureUnitState::UVWAddressingMode& uvw) + const TextureUnitState::UVWAddressingMode& uvw) { mAddressMode = uvw; } @@ -869,7 +869,7 @@ namespace Ogre { //----------------------------------------------------------------------- void TextureUnitState::setBlank(void) { - setTextureName(BLANKSTRING); + setTextureName(BLANKSTRING); } //----------------------------------------------------------------------- void TextureUnitState::setTextureTransform(const Matrix4& xform) @@ -994,27 +994,27 @@ namespace Ogre { // Create new effect TextureEffect eff; - if(uSpeed == vSpeed) - { - eff.type = ET_UVSCROLL; - eff.arg1 = uSpeed; - addEffect(eff); - } - else - { - if(uSpeed) - { - eff.type = ET_USCROLL; + if(uSpeed == vSpeed) + { + eff.type = ET_UVSCROLL; eff.arg1 = uSpeed; addEffect(eff); } - if(vSpeed) - { - eff.type = ET_VSCROLL; - eff.arg1 = vSpeed; - addEffect(eff); - } - } + else + { + if(uSpeed) + { + eff.type = ET_USCROLL; + eff.arg1 = uSpeed; + addEffect(eff); + } + if(vSpeed) + { + eff.type = ET_VSCROLL; + eff.arg1 = vSpeed; + addEffect(eff); + } + } } //----------------------------------------------------------------------- void TextureUnitState::setRotateAnimation(Real speed) @@ -1037,23 +1037,23 @@ namespace Ogre { WaveformType waveType, Real base, Real frequency, Real phase, Real amplitude) { // Remove existing effect - // note, only remove for subtype, not entire ET_TRANSFORM - // otherwise we won't be able to combine subtypes - // Get range of items matching this effect - for (EffectMap::iterator i = mEffects.begin(); i != mEffects.end(); ++i) - { - if (i->second.type == ET_TRANSFORM && i->second.subtype == ttype) - { - if (i->second.controller) - { - ControllerManager::getSingleton().destroyController(i->second.controller); - } - mEffects.erase(i); - - // should only be one, so jump out - break; - } - } + // note, only remove for subtype, not entire ET_TRANSFORM + // otherwise we won't be able to combine subtypes + // Get range of items matching this effect + for (EffectMap::iterator i = mEffects.begin(); i != mEffects.end(); ++i) + { + if (i->second.type == ET_TRANSFORM && i->second.subtype == ttype) + { + if (i->second.controller) + { + ControllerManager::getSingleton().destroyController(i->second.controller); + } + mEffects.erase(i); + + // should only be one, so jump out + break; + } + } // don't create an effect if the given values are all 0 if(base == 0.0f && phase == 0.0f && frequency == 0.0f && amplitude == 0.0f) @@ -1078,20 +1078,20 @@ namespace Ogre { //_unload(); // Load textures - for (unsigned int i = 0; i < mFrames.size(); ++i) - { - ensurePrepared(i); - } + for (unsigned int i = 0; i < mFrames.size(); ++i) + { + ensurePrepared(i); + } } //----------------------------------------------------------------------- void TextureUnitState::_load(void) { // Load textures - for (unsigned int i = 0; i < mFrames.size(); ++i) - { - ensureLoaded(i); - } + for (unsigned int i = 0; i < mFrames.size(); ++i) + { + ensureLoaded(i); + } // Animation controller if (mAnimDuration != 0) { @@ -1105,111 +1105,111 @@ namespace Ogre { } //----------------------------------------------------------------------- - const TexturePtr& TextureUnitState::_getTexturePtr(void) const - { - return _getTexturePtr(mCurrentFrame); - } - //----------------------------------------------------------------------- - const TexturePtr& TextureUnitState::_getTexturePtr(size_t frame) const - { - if (mContentType == CONTENT_NAMED) - { - if (frame < mFrames.size() && !mTextureLoadFailed) - { - ensureLoaded(frame); - return mFramePtrs[frame]; - } - else - { - // Silent fail with empty texture for internal method - static TexturePtr nullTexPtr; - return nullTexPtr; - } - } - else - { - // Manually bound texture, no name or loading - assert(frame < mFramePtrs.size()); - return mFramePtrs[frame]; - - } - - } - //----------------------------------------------------------------------- - void TextureUnitState::_setTexturePtr(const TexturePtr& texptr) - { - _setTexturePtr(texptr, mCurrentFrame); - } - //----------------------------------------------------------------------- - void TextureUnitState::_setTexturePtr(const TexturePtr& texptr, size_t frame) - { - assert(frame < mFramePtrs.size()); - mFramePtrs[frame] = texptr; - } - //----------------------------------------------------------------------- - void TextureUnitState::ensurePrepared(size_t frame) const - { - if (!mFrames[frame].empty() && !mTextureLoadFailed) - { - // Ensure texture is loaded, specified number of mipmaps and - // priority - if (mFramePtrs[frame].isNull()) - { - try { - mFramePtrs[frame] = - TextureManager::getSingleton().prepare(mFrames[frame], - mParent->getResourceGroup(), mTextureType, - mTextureSrcMipmaps, mGamma, mIsAlpha, mDesiredFormat, mHwGamma); - } - catch (Exception &e) { - String msg; - msg = msg + "Error loading texture " + mFrames[frame] + - ". Texture layer will be blank. Loading the texture " - "failed with the following exception: " - + e.getFullDescription(); - LogManager::getSingleton().logMessage(msg, LML_CRITICAL); - mTextureLoadFailed = true; - } - } - else - { - // Just ensure existing pointer is prepared - mFramePtrs[frame]->prepare(); - } - } - } - //----------------------------------------------------------------------- - void TextureUnitState::ensureLoaded(size_t frame) const - { - if (!mFrames[frame].empty() && !mTextureLoadFailed) - { - // Ensure texture is loaded, specified number of mipmaps and - // priority - if (mFramePtrs[frame].isNull()) - { - try { - mFramePtrs[frame] = - TextureManager::getSingleton().load(mFrames[frame], - mParent->getResourceGroup(), mTextureType, - mTextureSrcMipmaps, mGamma, mIsAlpha, mDesiredFormat, mHwGamma); - } - catch (Exception &e) { - String msg; - msg = msg + "Error loading texture " + mFrames[frame] + - ". Texture layer will be blank. Loading the texture " - "failed with the following exception: " - + e.getFullDescription(); - LogManager::getSingleton().logMessage(msg, LML_CRITICAL); - mTextureLoadFailed = true; - } - } - else - { - // Just ensure existing pointer is loaded - mFramePtrs[frame]->load(); - } - } - } + const TexturePtr& TextureUnitState::_getTexturePtr(void) const + { + return _getTexturePtr(mCurrentFrame); + } + //----------------------------------------------------------------------- + const TexturePtr& TextureUnitState::_getTexturePtr(size_t frame) const + { + if (mContentType == CONTENT_NAMED) + { + if (frame < mFrames.size() && !mTextureLoadFailed) + { + ensureLoaded(frame); + return mFramePtrs[frame]; + } + else + { + // Silent fail with empty texture for internal method + static TexturePtr nullTexPtr; + return nullTexPtr; + } + } + else + { + // Manually bound texture, no name or loading + assert(frame < mFramePtrs.size()); + return mFramePtrs[frame]; + + } + + } + //----------------------------------------------------------------------- + void TextureUnitState::_setTexturePtr(const TexturePtr& texptr) + { + _setTexturePtr(texptr, mCurrentFrame); + } + //----------------------------------------------------------------------- + void TextureUnitState::_setTexturePtr(const TexturePtr& texptr, size_t frame) + { + assert(frame < mFramePtrs.size()); + mFramePtrs[frame] = texptr; + } + //----------------------------------------------------------------------- + void TextureUnitState::ensurePrepared(size_t frame) const + { + if (!mFrames[frame].empty() && !mTextureLoadFailed) + { + // Ensure texture is loaded, specified number of mipmaps and + // priority + if (mFramePtrs[frame].isNull()) + { + try { + mFramePtrs[frame] = + TextureManager::getSingleton().prepare(mFrames[frame], + mParent->getResourceGroup(), mTextureType, + mTextureSrcMipmaps, mGamma, mIsAlpha, mDesiredFormat, mHwGamma); + } + catch (Exception &e) { + String msg; + msg = msg + "Error loading texture " + mFrames[frame] + + ". Texture layer will be blank. Loading the texture " + "failed with the following exception: " + + e.getFullDescription(); + LogManager::getSingleton().logMessage(msg, LML_CRITICAL); + mTextureLoadFailed = true; + } + } + else + { + // Just ensure existing pointer is prepared + mFramePtrs[frame]->prepare(); + } + } + } + //----------------------------------------------------------------------- + void TextureUnitState::ensureLoaded(size_t frame) const + { + if (!mFrames[frame].empty() && !mTextureLoadFailed) + { + // Ensure texture is loaded, specified number of mipmaps and + // priority + if (mFramePtrs[frame].isNull()) + { + try { + mFramePtrs[frame] = + TextureManager::getSingleton().load(mFrames[frame], + mParent->getResourceGroup(), mTextureType, + mTextureSrcMipmaps, mGamma, mIsAlpha, mDesiredFormat, mHwGamma); + } + catch (Exception &e) { + String msg; + msg = msg + "Error loading texture " + mFrames[frame] + + ". Texture layer will be blank. Loading the texture " + "failed with the following exception: " + + e.getFullDescription(); + LogManager::getSingleton().logMessage(msg, LML_CRITICAL); + mTextureLoadFailed = true; + } + } + else + { + // Just ensure existing pointer is loaded + mFramePtrs[frame]->load(); + } + } + } //----------------------------------------------------------------------- void TextureUnitState::createAnimController(void) { @@ -1255,50 +1255,50 @@ namespace Ogre { } } //----------------------------------------------------------------------- - Real TextureUnitState::getTextureUScroll(void) const + Real TextureUnitState::getTextureUScroll(void) const { - return mUMod; + return mUMod; } - //----------------------------------------------------------------------- - Real TextureUnitState::getTextureVScroll(void) const + //----------------------------------------------------------------------- + Real TextureUnitState::getTextureVScroll(void) const { - return mVMod; + return mVMod; } - //----------------------------------------------------------------------- - Real TextureUnitState::getTextureUScale(void) const + //----------------------------------------------------------------------- + Real TextureUnitState::getTextureUScale(void) const { - return mUScale; + return mUScale; } - //----------------------------------------------------------------------- - Real TextureUnitState::getTextureVScale(void) const + //----------------------------------------------------------------------- + Real TextureUnitState::getTextureVScale(void) const { - return mVScale; + return mVScale; } - //----------------------------------------------------------------------- - const Radian& TextureUnitState::getTextureRotate(void) const + //----------------------------------------------------------------------- + const Radian& TextureUnitState::getTextureRotate(void) const + { + return mRotate; + } + + //----------------------------------------------------------------------- + Real TextureUnitState::getAnimationDuration(void) const { - return mRotate; + return mAnimDuration; } - - //----------------------------------------------------------------------- - Real TextureUnitState::getAnimationDuration(void) const - { - return mAnimDuration; - } - //----------------------------------------------------------------------- - const TextureUnitState::EffectMap& TextureUnitState::getEffects(void) const - { - return mEffects; - } + //----------------------------------------------------------------------- + const TextureUnitState::EffectMap& TextureUnitState::getEffects(void) const + { + return mEffects; + } - //----------------------------------------------------------------------- - void TextureUnitState::setTextureFiltering(TextureFilterOptions filterType) - { + //----------------------------------------------------------------------- + void TextureUnitState::setTextureFiltering(TextureFilterOptions filterType) + { switch (filterType) { case TFO_NONE: @@ -1315,8 +1315,8 @@ namespace Ogre { break; } mIsDefaultFiltering = false; - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void TextureUnitState::setTextureFiltering(FilterType ft, FilterOptions fo) { switch (ft) @@ -1333,7 +1333,7 @@ namespace Ogre { } mIsDefaultFiltering = false; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void TextureUnitState::setTextureFiltering(FilterOptions minFilter, FilterOptions magFilter, FilterOptions mipFilter) { @@ -1342,9 +1342,9 @@ namespace Ogre { mMipFilter = mipFilter; mIsDefaultFiltering = false; } - //----------------------------------------------------------------------- - FilterOptions TextureUnitState::getTextureFiltering(FilterType ft) const - { + //----------------------------------------------------------------------- + FilterOptions TextureUnitState::getTextureFiltering(FilterType ft) const + { switch (ft) { @@ -1358,42 +1358,42 @@ namespace Ogre { return mIsDefaultFiltering ? MaterialManager::getSingleton().getDefaultTextureFiltering(FT_MIP) : mMipFilter; } - // to keep compiler happy - return mMinFilter; - } - //----------------------------------------------------------------------- - void TextureUnitState::setTextureCompareEnabled(bool enabled) - { - mCompareEnabled=enabled; - } - //----------------------------------------------------------------------- - bool TextureUnitState::getTextureCompareEnabled() const - { - return mCompareEnabled; - } - //----------------------------------------------------------------------- - void TextureUnitState::setTextureCompareFunction(CompareFunction function) - { - mCompareFunc=function; - } - //----------------------------------------------------------------------- - CompareFunction TextureUnitState::getTextureCompareFunction() const - { - return mCompareFunc; - } - //----------------------------------------------------------------------- - void TextureUnitState::setTextureAnisotropy(unsigned int maxAniso) - { - mMaxAniso = maxAniso; + // to keep compiler happy + return mMinFilter; + } + //----------------------------------------------------------------------- + void TextureUnitState::setTextureCompareEnabled(bool enabled) + { + mCompareEnabled=enabled; + } + //----------------------------------------------------------------------- + bool TextureUnitState::getTextureCompareEnabled() const + { + return mCompareEnabled; + } + //----------------------------------------------------------------------- + void TextureUnitState::setTextureCompareFunction(CompareFunction function) + { + mCompareFunc=function; + } + //----------------------------------------------------------------------- + CompareFunction TextureUnitState::getTextureCompareFunction() const + { + return mCompareFunc; + } + //----------------------------------------------------------------------- + void TextureUnitState::setTextureAnisotropy(unsigned int maxAniso) + { + mMaxAniso = maxAniso; mIsDefaultAniso = false; - } - //----------------------------------------------------------------------- - unsigned int TextureUnitState::getTextureAnisotropy() const - { + } + //----------------------------------------------------------------------- + unsigned int TextureUnitState::getTextureAnisotropy() const + { return mIsDefaultAniso? MaterialManager::getSingleton().getDefaultAnisotropy() : mMaxAniso; - } + } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void TextureUnitState::_unprepare(void) { // Unreference textures @@ -1404,7 +1404,7 @@ namespace Ogre { ti->setNull(); } } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void TextureUnitState::_unload(void) { // Destroy animation controller @@ -1484,8 +1484,8 @@ namespace Ogre { void TextureUnitState::setName(const String& name) { mName = name; - if (mTextureNameAlias.empty()) - mTextureNameAlias = mName; + if (mTextureNameAlias.empty()) + mTextureNameAlias = mName; } //----------------------------------------------------------------------- @@ -1524,7 +1524,7 @@ namespace Ogre { // if more than one frame then assume animated frames if (mFrames.size() > 1) setAnimatedTextureName(aliasEntry->second, - static_cast(mFrames.size()), mAnimDuration); + static_cast(mFrames.size()), mAnimDuration); else setTextureName(aliasEntry->second, mTextureType); } @@ -1535,18 +1535,18 @@ namespace Ogre { return testResult; } - //----------------------------------------------------------------------------- - void TextureUnitState::_notifyParent(Pass* parent) - { - mParent = parent; - } - //----------------------------------------------------------------------------- - void TextureUnitState::setCompositorReference(const String& compositorName, const String& textureName, size_t mrtIndex) - { - mCompositorRefName = compositorName; - mCompositorRefTexName = textureName; - mCompositorRefMrtIndex = mrtIndex; - } + //----------------------------------------------------------------------------- + void TextureUnitState::_notifyParent(Pass* parent) + { + mParent = parent; + } + //----------------------------------------------------------------------------- + void TextureUnitState::setCompositorReference(const String& compositorName, const String& textureName, size_t mrtIndex) + { + mCompositorRefName = compositorName; + mCompositorRefTexName = textureName; + mCompositorRefMrtIndex = mrtIndex; + } //----------------------------------------------------------------------- size_t TextureUnitState::calculateSize(void) const { diff --git a/OgreMain/src/OgreUTFString.cpp b/OgreMain/src/OgreUTFString.cpp index 1fee59ba428..ae35db8b984 100644 --- a/OgreMain/src/OgreUTFString.cpp +++ b/OgreMain/src/OgreUTFString.cpp @@ -32,2017 +32,2017 @@ THE SOFTWARE. namespace Ogre { - //-------------------------------------------------------------------------- - UTFString::_base_iterator::_base_iterator() - { - mString = 0; - } - //-------------------------------------------------------------------------- - void UTFString::_base_iterator::_seekFwd( size_type c ) - { - mIter += c; - } - //-------------------------------------------------------------------------- - void UTFString::_base_iterator::_seekRev( size_type c ) - { - mIter -= c; - } - //-------------------------------------------------------------------------- - void UTFString::_base_iterator::_become( const _base_iterator& i ) - { - mIter = i.mIter; - mString = i.mString; - } - //-------------------------------------------------------------------------- - bool UTFString::_base_iterator::_test_begin() const - { - return mIter == mString->mData.begin(); - } - //-------------------------------------------------------------------------- - bool UTFString::_base_iterator::_test_end() const - { - return mIter == mString->mData.end(); - } - //-------------------------------------------------------------------------- - Ogre::UTFString::size_type UTFString::_base_iterator::_get_index() const - { - return mIter - mString->mData.begin(); - } - //-------------------------------------------------------------------------- - void UTFString::_base_iterator::_jump_to( size_type index ) - { - mIter = mString->mData.begin() + index; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::unicode_char UTFString::_base_iterator::_getCharacter() const - { - size_type current_index = _get_index(); - return mString->getChar( current_index ); - } - //-------------------------------------------------------------------------- - int UTFString::_base_iterator::_setCharacter( unicode_char uc ) - { - size_type current_index = _get_index(); - int change = mString->setChar( current_index, uc ); - _jump_to( current_index ); - return change; - } - //-------------------------------------------------------------------------- - void UTFString::_base_iterator::_moveNext() - { - _seekFwd( 1 ); // move 1 code point forward - if ( _test_end() ) return; // exit if we hit the end - if ( _utf16_surrogate_follow( mIter[0] ) ) { - // landing on a follow code point means we might be part of a bigger character - // so we test for that - code_point lead_half = 0; - //NB: we can't possibly be at the beginning here, so no need to test - lead_half = mIter[-1]; // check the previous code point to see if we're part of a surrogate pair - if ( _utf16_surrogate_lead( lead_half ) ) { - _seekFwd( 1 ); // if so, then advance 1 more code point - } - } - } - //-------------------------------------------------------------------------- - void UTFString::_base_iterator::_movePrev() - { - _seekRev( 1 ); // move 1 code point backwards - if ( _test_begin() ) return; // exit if we hit the beginning - if ( _utf16_surrogate_follow( mIter[0] ) ) { - // landing on a follow code point means we might be part of a bigger character - // so we test for that - code_point lead_half = 0; - lead_half = mIter[-1]; // check the previous character to see if we're part of a surrogate pair - if ( _utf16_surrogate_lead( lead_half ) ) { - _seekRev( 1 ); // if so, then rewind 1 more code point - } - } - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - UTFString::_fwd_iterator::_fwd_iterator() - { - - } - //-------------------------------------------------------------------------- - UTFString::_fwd_iterator::_fwd_iterator( const _fwd_iterator& i ) - { - _become( i ); - } - //-------------------------------------------------------------------------- - UTFString::_fwd_iterator& UTFString::_fwd_iterator::operator++() - { - _seekFwd( 1 ); - return *this; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_fwd_iterator UTFString::_fwd_iterator::operator++( int ) - { - _fwd_iterator tmp( *this ); - _seekFwd( 1 ); - return tmp; - } - //-------------------------------------------------------------------------- - UTFString::_fwd_iterator& UTFString::_fwd_iterator::operator--() - { - _seekRev( 1 ); - return *this; - } - //-------------------------------------------------------------------------- - UTFString::_fwd_iterator UTFString::_fwd_iterator::operator--( int ) - { - _fwd_iterator tmp( *this ); - _seekRev( 1 ); - return tmp; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_fwd_iterator UTFString::_fwd_iterator::operator+( difference_type n ) - { - _fwd_iterator tmp( *this ); - if ( n < 0 ) - tmp._seekRev( -n ); - else - tmp._seekFwd( n ); - return tmp; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_fwd_iterator UTFString::_fwd_iterator::operator-( difference_type n ) - { - _fwd_iterator tmp( *this ); - if ( n < 0 ) - tmp._seekFwd( -n ); - else - tmp._seekRev( n ); - return tmp; - } - //-------------------------------------------------------------------------- - UTFString::_fwd_iterator& UTFString::_fwd_iterator::operator+=( difference_type n ) - { - if ( n < 0 ) - _seekRev( -n ); - else - _seekFwd( n ); - return *this; - } - //-------------------------------------------------------------------------- - UTFString::_fwd_iterator& UTFString::_fwd_iterator::operator-=( difference_type n ) - { - if ( n < 0 ) - _seekFwd( -n ); - else - _seekRev( n ); - return *this; - } - //-------------------------------------------------------------------------- - UTFString::value_type& UTFString::_fwd_iterator::operator*() const - { - return *mIter; - } - //-------------------------------------------------------------------------- - UTFString::value_type& UTFString::_fwd_iterator::operator[]( difference_type n ) const - { - _fwd_iterator tmp( *this ); - tmp += n; - return *tmp; - } - //-------------------------------------------------------------------------- - UTFString::_fwd_iterator& UTFString::_fwd_iterator::moveNext() - { - _moveNext(); - return *this; - } - //-------------------------------------------------------------------------- - UTFString::_fwd_iterator& UTFString::_fwd_iterator::movePrev() - { - _movePrev(); - return *this; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::unicode_char UTFString::_fwd_iterator::getCharacter() const - { - return _getCharacter(); - } - //-------------------------------------------------------------------------- - int UTFString::_fwd_iterator::setCharacter( unicode_char uc ) - { - return _setCharacter( uc ); - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - UTFString::_const_fwd_iterator::_const_fwd_iterator() - { - - } - //-------------------------------------------------------------------------- - UTFString::_const_fwd_iterator::_const_fwd_iterator( const _const_fwd_iterator& i ) - { - _become( i ); - } - //-------------------------------------------------------------------------- - UTFString::_const_fwd_iterator::_const_fwd_iterator( const _fwd_iterator& i ) - { - _become( i ); - } - //-------------------------------------------------------------------------- - UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::operator++() - { - _seekFwd( 1 ); - return *this; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_const_fwd_iterator UTFString::_const_fwd_iterator::operator++( int ) - { - _const_fwd_iterator tmp( *this ); - _seekFwd( 1 ); - return tmp; - } - //-------------------------------------------------------------------------- - UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::operator--() - { - _seekRev( 1 ); - return *this; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_const_fwd_iterator UTFString::_const_fwd_iterator::operator--( int ) - { - _const_fwd_iterator tmp( *this ); - _seekRev( 1 ); - return tmp; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_const_fwd_iterator UTFString::_const_fwd_iterator::operator+( difference_type n ) - { - _const_fwd_iterator tmp( *this ); - if ( n < 0 ) - tmp._seekRev( -n ); - else - tmp._seekFwd( n ); - return tmp; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_const_fwd_iterator UTFString::_const_fwd_iterator::operator-( difference_type n ) - { - _const_fwd_iterator tmp( *this ); - if ( n < 0 ) - tmp._seekFwd( -n ); - else - tmp._seekRev( n ); - return tmp; - } - //-------------------------------------------------------------------------- - UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::operator+=( difference_type n ) - { - if ( n < 0 ) - _seekRev( -n ); - else - _seekFwd( n ); - return *this; - } - //-------------------------------------------------------------------------- - UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::operator-=( difference_type n ) - { - if ( n < 0 ) - _seekFwd( -n ); - else - _seekRev( n ); - return *this; - } - //-------------------------------------------------------------------------- - const UTFString::value_type& UTFString::_const_fwd_iterator::operator*() const - { - return *mIter; - } - //-------------------------------------------------------------------------- - const UTFString::value_type& UTFString::_const_fwd_iterator::operator[]( difference_type n ) const - { - _const_fwd_iterator tmp( *this ); - tmp += n; - return *tmp; - } - //-------------------------------------------------------------------------- - UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::moveNext() - { - _moveNext(); - return *this; - } - //-------------------------------------------------------------------------- - UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::movePrev() - { - _movePrev(); - return *this; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::unicode_char UTFString::_const_fwd_iterator::getCharacter() const - { - return _getCharacter(); - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - UTFString::_rev_iterator::_rev_iterator() - { - - } - //-------------------------------------------------------------------------- - UTFString::_rev_iterator::_rev_iterator( const _rev_iterator& i ) - { - _become( i ); - } - //-------------------------------------------------------------------------- - UTFString::_rev_iterator& UTFString::_rev_iterator::operator++() - { - _seekRev( 1 ); - return *this; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_rev_iterator UTFString::_rev_iterator::operator++( int ) - { - _rev_iterator tmp( *this ); - _seekRev( 1 ); - return tmp; - } - //-------------------------------------------------------------------------- - UTFString::_rev_iterator& UTFString::_rev_iterator::operator--() - { - _seekFwd( 1 ); - return *this; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_rev_iterator UTFString::_rev_iterator::operator--( int ) - { - _rev_iterator tmp( *this ); - _seekFwd( 1 ); - return tmp; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_rev_iterator UTFString::_rev_iterator::operator+( difference_type n ) - { - _rev_iterator tmp( *this ); - if ( n < 0 ) - tmp._seekFwd( -n ); - else - tmp._seekRev( n ); - return tmp; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_rev_iterator UTFString::_rev_iterator::operator-( difference_type n ) - { - _rev_iterator tmp( *this ); - if ( n < 0 ) - tmp._seekRev( -n ); - else - tmp._seekFwd( n ); - return tmp; - } - //-------------------------------------------------------------------------- - UTFString::_rev_iterator& UTFString::_rev_iterator::operator+=( difference_type n ) - { - if ( n < 0 ) - _seekFwd( -n ); - else - _seekRev( n ); - return *this; - } - //-------------------------------------------------------------------------- - UTFString::_rev_iterator& UTFString::_rev_iterator::operator-=( difference_type n ) - { - if ( n < 0 ) - _seekRev( -n ); - else - _seekFwd( n ); - return *this; - } - //-------------------------------------------------------------------------- - UTFString::value_type& UTFString::_rev_iterator::operator*() const - { - return mIter[-1]; - } - //-------------------------------------------------------------------------- - UTFString::value_type& UTFString::_rev_iterator::operator[]( difference_type n ) const - { - _rev_iterator tmp( *this ); - tmp -= n; - return *tmp; - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - UTFString::_const_rev_iterator::_const_rev_iterator() - { - - } - //-------------------------------------------------------------------------- - UTFString::_const_rev_iterator::_const_rev_iterator( const _const_rev_iterator& i ) - { - _become( i ); - } - //-------------------------------------------------------------------------- - UTFString::_const_rev_iterator::_const_rev_iterator( const _rev_iterator& i ) - { - _become( i ); - } - //-------------------------------------------------------------------------- - UTFString::_const_rev_iterator& UTFString::_const_rev_iterator::operator++() - { - _seekRev( 1 ); - return *this; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_const_rev_iterator UTFString::_const_rev_iterator::operator++( int ) - { - _const_rev_iterator tmp( *this ); - _seekRev( 1 ); - return tmp; - } - //-------------------------------------------------------------------------- - UTFString::_const_rev_iterator& UTFString::_const_rev_iterator::operator--() - { - _seekFwd( 1 ); - return *this; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_const_rev_iterator UTFString::_const_rev_iterator::operator--( int ) - { - _const_rev_iterator tmp( *this ); - _seekFwd( 1 ); - return tmp; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_const_rev_iterator UTFString::_const_rev_iterator::operator+( difference_type n ) - { - _const_rev_iterator tmp( *this ); - if ( n < 0 ) - tmp._seekFwd( -n ); - else - tmp._seekRev( n ); - return tmp; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::_const_rev_iterator UTFString::_const_rev_iterator::operator-( difference_type n ) - { - _const_rev_iterator tmp( *this ); - if ( n < 0 ) - tmp._seekRev( -n ); - else - tmp._seekFwd( n ); - return tmp; - } - //-------------------------------------------------------------------------- - UTFString::_const_rev_iterator& UTFString::_const_rev_iterator::operator+=( difference_type n ) - { - if ( n < 0 ) - _seekFwd( -n ); - else - _seekRev( n ); - return *this; - } - //-------------------------------------------------------------------------- - UTFString::_const_rev_iterator& UTFString::_const_rev_iterator::operator-=( difference_type n ) - { - if ( n < 0 ) - _seekRev( -n ); - else - _seekFwd( n ); - return *this; - } - //-------------------------------------------------------------------------- - const UTFString::value_type& UTFString::_const_rev_iterator::operator*() const - { - return mIter[-1]; - } - //-------------------------------------------------------------------------- - const UTFString::value_type& UTFString::_const_rev_iterator::operator[]( difference_type n ) const - { - _const_rev_iterator tmp( *this ); - tmp -= n; - return *tmp; - } - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - //-------------------------------------------------------------------------- - UTFString::UTFString() - { - _init(); - } - //-------------------------------------------------------------------------- - UTFString::UTFString( const UTFString& copy ) - { - _init(); - mData = copy.mData; - } - //-------------------------------------------------------------------------- - UTFString::UTFString( size_type inLength, const code_point& ch ) - { - _init(); - assign( inLength, ch ); - } - //-------------------------------------------------------------------------- - UTFString::UTFString( const code_point* str ) - { - _init(); - assign( str ); - } - //-------------------------------------------------------------------------- - UTFString::UTFString( const code_point* str, size_type inLength ) - { - _init(); - assign( str, inLength ); - } - //-------------------------------------------------------------------------- - UTFString::UTFString( const UTFString& str, size_type index, size_type inLength ) - { - _init(); - assign( str, index, inLength ); - } - //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + UTFString::_base_iterator::_base_iterator() + { + mString = 0; + } + //-------------------------------------------------------------------------- + void UTFString::_base_iterator::_seekFwd( size_type c ) + { + mIter += c; + } + //-------------------------------------------------------------------------- + void UTFString::_base_iterator::_seekRev( size_type c ) + { + mIter -= c; + } + //-------------------------------------------------------------------------- + void UTFString::_base_iterator::_become( const _base_iterator& i ) + { + mIter = i.mIter; + mString = i.mString; + } + //-------------------------------------------------------------------------- + bool UTFString::_base_iterator::_test_begin() const + { + return mIter == mString->mData.begin(); + } + //-------------------------------------------------------------------------- + bool UTFString::_base_iterator::_test_end() const + { + return mIter == mString->mData.end(); + } + //-------------------------------------------------------------------------- + Ogre::UTFString::size_type UTFString::_base_iterator::_get_index() const + { + return mIter - mString->mData.begin(); + } + //-------------------------------------------------------------------------- + void UTFString::_base_iterator::_jump_to( size_type index ) + { + mIter = mString->mData.begin() + index; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::unicode_char UTFString::_base_iterator::_getCharacter() const + { + size_type current_index = _get_index(); + return mString->getChar( current_index ); + } + //-------------------------------------------------------------------------- + int UTFString::_base_iterator::_setCharacter( unicode_char uc ) + { + size_type current_index = _get_index(); + int change = mString->setChar( current_index, uc ); + _jump_to( current_index ); + return change; + } + //-------------------------------------------------------------------------- + void UTFString::_base_iterator::_moveNext() + { + _seekFwd( 1 ); // move 1 code point forward + if ( _test_end() ) return; // exit if we hit the end + if ( _utf16_surrogate_follow( mIter[0] ) ) { + // landing on a follow code point means we might be part of a bigger character + // so we test for that + code_point lead_half = 0; + //NB: we can't possibly be at the beginning here, so no need to test + lead_half = mIter[-1]; // check the previous code point to see if we're part of a surrogate pair + if ( _utf16_surrogate_lead( lead_half ) ) { + _seekFwd( 1 ); // if so, then advance 1 more code point + } + } + } + //-------------------------------------------------------------------------- + void UTFString::_base_iterator::_movePrev() + { + _seekRev( 1 ); // move 1 code point backwards + if ( _test_begin() ) return; // exit if we hit the beginning + if ( _utf16_surrogate_follow( mIter[0] ) ) { + // landing on a follow code point means we might be part of a bigger character + // so we test for that + code_point lead_half = 0; + lead_half = mIter[-1]; // check the previous character to see if we're part of a surrogate pair + if ( _utf16_surrogate_lead( lead_half ) ) { + _seekRev( 1 ); // if so, then rewind 1 more code point + } + } + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + UTFString::_fwd_iterator::_fwd_iterator() + { + + } + //-------------------------------------------------------------------------- + UTFString::_fwd_iterator::_fwd_iterator( const _fwd_iterator& i ) + { + _become( i ); + } + //-------------------------------------------------------------------------- + UTFString::_fwd_iterator& UTFString::_fwd_iterator::operator++() + { + _seekFwd( 1 ); + return *this; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_fwd_iterator UTFString::_fwd_iterator::operator++( int ) + { + _fwd_iterator tmp( *this ); + _seekFwd( 1 ); + return tmp; + } + //-------------------------------------------------------------------------- + UTFString::_fwd_iterator& UTFString::_fwd_iterator::operator--() + { + _seekRev( 1 ); + return *this; + } + //-------------------------------------------------------------------------- + UTFString::_fwd_iterator UTFString::_fwd_iterator::operator--( int ) + { + _fwd_iterator tmp( *this ); + _seekRev( 1 ); + return tmp; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_fwd_iterator UTFString::_fwd_iterator::operator+( difference_type n ) + { + _fwd_iterator tmp( *this ); + if ( n < 0 ) + tmp._seekRev( -n ); + else + tmp._seekFwd( n ); + return tmp; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_fwd_iterator UTFString::_fwd_iterator::operator-( difference_type n ) + { + _fwd_iterator tmp( *this ); + if ( n < 0 ) + tmp._seekFwd( -n ); + else + tmp._seekRev( n ); + return tmp; + } + //-------------------------------------------------------------------------- + UTFString::_fwd_iterator& UTFString::_fwd_iterator::operator+=( difference_type n ) + { + if ( n < 0 ) + _seekRev( -n ); + else + _seekFwd( n ); + return *this; + } + //-------------------------------------------------------------------------- + UTFString::_fwd_iterator& UTFString::_fwd_iterator::operator-=( difference_type n ) + { + if ( n < 0 ) + _seekFwd( -n ); + else + _seekRev( n ); + return *this; + } + //-------------------------------------------------------------------------- + UTFString::value_type& UTFString::_fwd_iterator::operator*() const + { + return *mIter; + } + //-------------------------------------------------------------------------- + UTFString::value_type& UTFString::_fwd_iterator::operator[]( difference_type n ) const + { + _fwd_iterator tmp( *this ); + tmp += n; + return *tmp; + } + //-------------------------------------------------------------------------- + UTFString::_fwd_iterator& UTFString::_fwd_iterator::moveNext() + { + _moveNext(); + return *this; + } + //-------------------------------------------------------------------------- + UTFString::_fwd_iterator& UTFString::_fwd_iterator::movePrev() + { + _movePrev(); + return *this; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::unicode_char UTFString::_fwd_iterator::getCharacter() const + { + return _getCharacter(); + } + //-------------------------------------------------------------------------- + int UTFString::_fwd_iterator::setCharacter( unicode_char uc ) + { + return _setCharacter( uc ); + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + UTFString::_const_fwd_iterator::_const_fwd_iterator() + { + + } + //-------------------------------------------------------------------------- + UTFString::_const_fwd_iterator::_const_fwd_iterator( const _const_fwd_iterator& i ) + { + _become( i ); + } + //-------------------------------------------------------------------------- + UTFString::_const_fwd_iterator::_const_fwd_iterator( const _fwd_iterator& i ) + { + _become( i ); + } + //-------------------------------------------------------------------------- + UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::operator++() + { + _seekFwd( 1 ); + return *this; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_const_fwd_iterator UTFString::_const_fwd_iterator::operator++( int ) + { + _const_fwd_iterator tmp( *this ); + _seekFwd( 1 ); + return tmp; + } + //-------------------------------------------------------------------------- + UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::operator--() + { + _seekRev( 1 ); + return *this; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_const_fwd_iterator UTFString::_const_fwd_iterator::operator--( int ) + { + _const_fwd_iterator tmp( *this ); + _seekRev( 1 ); + return tmp; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_const_fwd_iterator UTFString::_const_fwd_iterator::operator+( difference_type n ) + { + _const_fwd_iterator tmp( *this ); + if ( n < 0 ) + tmp._seekRev( -n ); + else + tmp._seekFwd( n ); + return tmp; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_const_fwd_iterator UTFString::_const_fwd_iterator::operator-( difference_type n ) + { + _const_fwd_iterator tmp( *this ); + if ( n < 0 ) + tmp._seekFwd( -n ); + else + tmp._seekRev( n ); + return tmp; + } + //-------------------------------------------------------------------------- + UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::operator+=( difference_type n ) + { + if ( n < 0 ) + _seekRev( -n ); + else + _seekFwd( n ); + return *this; + } + //-------------------------------------------------------------------------- + UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::operator-=( difference_type n ) + { + if ( n < 0 ) + _seekFwd( -n ); + else + _seekRev( n ); + return *this; + } + //-------------------------------------------------------------------------- + const UTFString::value_type& UTFString::_const_fwd_iterator::operator*() const + { + return *mIter; + } + //-------------------------------------------------------------------------- + const UTFString::value_type& UTFString::_const_fwd_iterator::operator[]( difference_type n ) const + { + _const_fwd_iterator tmp( *this ); + tmp += n; + return *tmp; + } + //-------------------------------------------------------------------------- + UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::moveNext() + { + _moveNext(); + return *this; + } + //-------------------------------------------------------------------------- + UTFString::_const_fwd_iterator& UTFString::_const_fwd_iterator::movePrev() + { + _movePrev(); + return *this; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::unicode_char UTFString::_const_fwd_iterator::getCharacter() const + { + return _getCharacter(); + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + UTFString::_rev_iterator::_rev_iterator() + { + + } + //-------------------------------------------------------------------------- + UTFString::_rev_iterator::_rev_iterator( const _rev_iterator& i ) + { + _become( i ); + } + //-------------------------------------------------------------------------- + UTFString::_rev_iterator& UTFString::_rev_iterator::operator++() + { + _seekRev( 1 ); + return *this; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_rev_iterator UTFString::_rev_iterator::operator++( int ) + { + _rev_iterator tmp( *this ); + _seekRev( 1 ); + return tmp; + } + //-------------------------------------------------------------------------- + UTFString::_rev_iterator& UTFString::_rev_iterator::operator--() + { + _seekFwd( 1 ); + return *this; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_rev_iterator UTFString::_rev_iterator::operator--( int ) + { + _rev_iterator tmp( *this ); + _seekFwd( 1 ); + return tmp; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_rev_iterator UTFString::_rev_iterator::operator+( difference_type n ) + { + _rev_iterator tmp( *this ); + if ( n < 0 ) + tmp._seekFwd( -n ); + else + tmp._seekRev( n ); + return tmp; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_rev_iterator UTFString::_rev_iterator::operator-( difference_type n ) + { + _rev_iterator tmp( *this ); + if ( n < 0 ) + tmp._seekRev( -n ); + else + tmp._seekFwd( n ); + return tmp; + } + //-------------------------------------------------------------------------- + UTFString::_rev_iterator& UTFString::_rev_iterator::operator+=( difference_type n ) + { + if ( n < 0 ) + _seekFwd( -n ); + else + _seekRev( n ); + return *this; + } + //-------------------------------------------------------------------------- + UTFString::_rev_iterator& UTFString::_rev_iterator::operator-=( difference_type n ) + { + if ( n < 0 ) + _seekRev( -n ); + else + _seekFwd( n ); + return *this; + } + //-------------------------------------------------------------------------- + UTFString::value_type& UTFString::_rev_iterator::operator*() const + { + return mIter[-1]; + } + //-------------------------------------------------------------------------- + UTFString::value_type& UTFString::_rev_iterator::operator[]( difference_type n ) const + { + _rev_iterator tmp( *this ); + tmp -= n; + return *tmp; + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + UTFString::_const_rev_iterator::_const_rev_iterator() + { + + } + //-------------------------------------------------------------------------- + UTFString::_const_rev_iterator::_const_rev_iterator( const _const_rev_iterator& i ) + { + _become( i ); + } + //-------------------------------------------------------------------------- + UTFString::_const_rev_iterator::_const_rev_iterator( const _rev_iterator& i ) + { + _become( i ); + } + //-------------------------------------------------------------------------- + UTFString::_const_rev_iterator& UTFString::_const_rev_iterator::operator++() + { + _seekRev( 1 ); + return *this; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_const_rev_iterator UTFString::_const_rev_iterator::operator++( int ) + { + _const_rev_iterator tmp( *this ); + _seekRev( 1 ); + return tmp; + } + //-------------------------------------------------------------------------- + UTFString::_const_rev_iterator& UTFString::_const_rev_iterator::operator--() + { + _seekFwd( 1 ); + return *this; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_const_rev_iterator UTFString::_const_rev_iterator::operator--( int ) + { + _const_rev_iterator tmp( *this ); + _seekFwd( 1 ); + return tmp; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_const_rev_iterator UTFString::_const_rev_iterator::operator+( difference_type n ) + { + _const_rev_iterator tmp( *this ); + if ( n < 0 ) + tmp._seekFwd( -n ); + else + tmp._seekRev( n ); + return tmp; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::_const_rev_iterator UTFString::_const_rev_iterator::operator-( difference_type n ) + { + _const_rev_iterator tmp( *this ); + if ( n < 0 ) + tmp._seekRev( -n ); + else + tmp._seekFwd( n ); + return tmp; + } + //-------------------------------------------------------------------------- + UTFString::_const_rev_iterator& UTFString::_const_rev_iterator::operator+=( difference_type n ) + { + if ( n < 0 ) + _seekFwd( -n ); + else + _seekRev( n ); + return *this; + } + //-------------------------------------------------------------------------- + UTFString::_const_rev_iterator& UTFString::_const_rev_iterator::operator-=( difference_type n ) + { + if ( n < 0 ) + _seekRev( -n ); + else + _seekFwd( n ); + return *this; + } + //-------------------------------------------------------------------------- + const UTFString::value_type& UTFString::_const_rev_iterator::operator*() const + { + return mIter[-1]; + } + //-------------------------------------------------------------------------- + const UTFString::value_type& UTFString::_const_rev_iterator::operator[]( difference_type n ) const + { + _const_rev_iterator tmp( *this ); + tmp -= n; + return *tmp; + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + UTFString::UTFString() + { + _init(); + } + //-------------------------------------------------------------------------- + UTFString::UTFString( const UTFString& copy ) + { + _init(); + mData = copy.mData; + } + //-------------------------------------------------------------------------- + UTFString::UTFString( size_type inLength, const code_point& ch ) + { + _init(); + assign( inLength, ch ); + } + //-------------------------------------------------------------------------- + UTFString::UTFString( const code_point* str ) + { + _init(); + assign( str ); + } + //-------------------------------------------------------------------------- + UTFString::UTFString( const code_point* str, size_type inLength ) + { + _init(); + assign( str, inLength ); + } + //-------------------------------------------------------------------------- + UTFString::UTFString( const UTFString& str, size_type index, size_type inLength ) + { + _init(); + assign( str, index, inLength ); + } + //-------------------------------------------------------------------------- #if OGRE_IS_NATIVE_WCHAR_T - UTFString::UTFString( const wchar_t* w_str ) - { - _init(); - assign( w_str ); - } - //-------------------------------------------------------------------------- - UTFString::UTFString( const wchar_t* w_str, size_type inLength ) - { - _init(); - assign( w_str, inLength ); - } + UTFString::UTFString( const wchar_t* w_str ) + { + _init(); + assign( w_str ); + } + //-------------------------------------------------------------------------- + UTFString::UTFString( const wchar_t* w_str, size_type inLength ) + { + _init(); + assign( w_str, inLength ); + } #endif - //-------------------------------------------------------------------------- - UTFString::UTFString( const std::wstring& wstr ) - { - _init(); - assign( wstr ); - } - //-------------------------------------------------------------------------- - UTFString::UTFString( const char* str ) - { - _init(); - assign( str ); - } - //-------------------------------------------------------------------------- - UTFString::UTFString( const char* str, size_type inLength ) - { - _init(); - assign( str, inLength ); - } - //-------------------------------------------------------------------------- - UTFString::UTFString( const std::string& str ) - { - _init(); - assign( str ); - } - //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + UTFString::UTFString( const std::wstring& wstr ) + { + _init(); + assign( wstr ); + } + //-------------------------------------------------------------------------- + UTFString::UTFString( const char* str ) + { + _init(); + assign( str ); + } + //-------------------------------------------------------------------------- + UTFString::UTFString( const char* str, size_type inLength ) + { + _init(); + assign( str, inLength ); + } + //-------------------------------------------------------------------------- + UTFString::UTFString( const std::string& str ) + { + _init(); + assign( str ); + } + //-------------------------------------------------------------------------- #if OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR - UTFString::UTFString( const Ogre::String& str ) - { - _init(); - assign( str.c_str() ); - } + UTFString::UTFString( const Ogre::String& str ) + { + _init(); + assign( str.c_str() ); + } #endif - //-------------------------------------------------------------------------- - UTFString::~UTFString() - { - _cleanBuffer(); - } - //-------------------------------------------------------------------------- - Ogre::UTFString::size_type UTFString::size() const - { - return mData.size(); - } - //-------------------------------------------------------------------------- - Ogre::UTFString::size_type UTFString::length() const - { - return size(); - } - //-------------------------------------------------------------------------- - Ogre::UTFString::size_type UTFString::length_Characters() const - { - const_iterator i = begin(), ie = end(); - size_type c = 0; - while ( i != ie ) { - i.moveNext(); - ++c; - } - return c; - } - //-------------------------------------------------------------------------- - Ogre::UTFString::size_type UTFString::max_size() const - { - return mData.max_size(); - } - //-------------------------------------------------------------------------- - void UTFString::reserve( size_type inSize ) - { - mData.reserve( inSize ); - } - //-------------------------------------------------------------------------- - void UTFString::resize( size_type num, const code_point& val /*= 0 */ ) - { - mData.resize( num, val ); - } - //-------------------------------------------------------------------------- - void UTFString::swap( UTFString& from ) - { - mData.swap( from.mData ); - } - //-------------------------------------------------------------------------- - bool UTFString::empty() const - { - return mData.empty(); - } - //-------------------------------------------------------------------------- - const UTFString::code_point* UTFString::c_str() const - { - return mData.c_str(); - } - //-------------------------------------------------------------------------- - const UTFString::code_point* UTFString::data() const - { - return c_str(); - } - //-------------------------------------------------------------------------- - Ogre::UTFString::size_type UTFString::capacity() const - { - return mData.capacity(); - } - //-------------------------------------------------------------------------- - void UTFString::clear() - { - mData.clear(); - } - //-------------------------------------------------------------------------- - Ogre::UTFString UTFString::substr( size_type index, size_type num /*= npos */ ) const - { - // this could avoid the extra copy if we used a private specialty constructor - dstring tmpData = mData.substr( index, num ); - UTFString tmp; - tmp.mData.swap( tmpData ); - return tmp; - } - //-------------------------------------------------------------------------- - void UTFString::push_back( unicode_char val ) - { - code_point cp[2] = { + //-------------------------------------------------------------------------- + UTFString::~UTFString() + { + _cleanBuffer(); + } + //-------------------------------------------------------------------------- + Ogre::UTFString::size_type UTFString::size() const + { + return mData.size(); + } + //-------------------------------------------------------------------------- + Ogre::UTFString::size_type UTFString::length() const + { + return size(); + } + //-------------------------------------------------------------------------- + Ogre::UTFString::size_type UTFString::length_Characters() const + { + const_iterator i = begin(), ie = end(); + size_type c = 0; + while ( i != ie ) { + i.moveNext(); + ++c; + } + return c; + } + //-------------------------------------------------------------------------- + Ogre::UTFString::size_type UTFString::max_size() const + { + return mData.max_size(); + } + //-------------------------------------------------------------------------- + void UTFString::reserve( size_type inSize ) + { + mData.reserve( inSize ); + } + //-------------------------------------------------------------------------- + void UTFString::resize( size_type num, const code_point& val /*= 0 */ ) + { + mData.resize( num, val ); + } + //-------------------------------------------------------------------------- + void UTFString::swap( UTFString& from ) + { + mData.swap( from.mData ); + } + //-------------------------------------------------------------------------- + bool UTFString::empty() const + { + return mData.empty(); + } + //-------------------------------------------------------------------------- + const UTFString::code_point* UTFString::c_str() const + { + return mData.c_str(); + } + //-------------------------------------------------------------------------- + const UTFString::code_point* UTFString::data() const + { + return c_str(); + } + //-------------------------------------------------------------------------- + Ogre::UTFString::size_type UTFString::capacity() const + { + return mData.capacity(); + } + //-------------------------------------------------------------------------- + void UTFString::clear() + { + mData.clear(); + } + //-------------------------------------------------------------------------- + Ogre::UTFString UTFString::substr( size_type index, size_type num /*= npos */ ) const + { + // this could avoid the extra copy if we used a private specialty constructor + dstring tmpData = mData.substr( index, num ); + UTFString tmp; + tmp.mData.swap( tmpData ); + return tmp; + } + //-------------------------------------------------------------------------- + void UTFString::push_back( unicode_char val ) + { + code_point cp[2] = { 0, 0 }; - size_t c = _utf32_to_utf16( val, cp ); - if ( c > 0 ) push_back( cp[0] ); - if ( c > 1 ) push_back( cp[1] ); - } - //-------------------------------------------------------------------------- + size_t c = _utf32_to_utf16( val, cp ); + if ( c > 0 ) push_back( cp[0] ); + if ( c > 1 ) push_back( cp[1] ); + } + //-------------------------------------------------------------------------- #if OGRE_IS_NATIVE_WCHAR_T - void UTFString::push_back( wchar_t val ) - { - // we do this because the Unicode method still preserves UTF-16 code points - mData.push_back( static_cast( val ) ); - } + void UTFString::push_back( wchar_t val ) + { + // we do this because the Unicode method still preserves UTF-16 code points + mData.push_back( static_cast( val ) ); + } #endif - //-------------------------------------------------------------------------- - void UTFString::push_back( code_point val ) - { - mData.push_back( val ); - } - - void UTFString::push_back( char val ) - { - mData.push_back( static_cast( val ) ); - } - - bool UTFString::inString( unicode_char ch ) const - { - const_iterator i, ie = end(); - for ( i = begin(); i != ie; i.moveNext() ) { - if ( i.getCharacter() == ch ) - return true; - } - return false; - } - - const std::string& UTFString::asUTF8() const - { - _load_buffer_UTF8(); - return *mBuffer.mStrBuffer; - } - - const char* UTFString::asUTF8_c_str() const - { - _load_buffer_UTF8(); - return mBuffer.mStrBuffer->c_str(); - } - - const UTFString::utf32string& UTFString::asUTF32() const - { - _load_buffer_UTF32(); - return *mBuffer.mUTF32StrBuffer; - } - - const UTFString::unicode_char* UTFString::asUTF32_c_str() const - { - _load_buffer_UTF32(); - return mBuffer.mUTF32StrBuffer->c_str(); - } - - const std::wstring& UTFString::asWStr() const - { - _load_buffer_WStr(); - return *mBuffer.mWStrBuffer; - } - - const wchar_t* UTFString::asWStr_c_str() const - { - _load_buffer_WStr(); - return mBuffer.mWStrBuffer->c_str(); - } - - UTFString::code_point& UTFString::at( size_type loc ) - { - return mData.at( loc ); - } - - const UTFString::code_point& UTFString::at( size_type loc ) const - { - return mData.at( loc ); - } - - Ogre::UTFString::unicode_char UTFString::getChar( size_type loc ) const - { - const code_point* ptr = c_str(); - unicode_char uc; - size_t l = _utf16_char_length( ptr[loc] ); - code_point cp[2] = { /* blame the code beautifier */ - 0, 0 - }; - cp[0] = ptr[loc]; - - if ( l == 2 && ( loc + 1 ) < mData.length() ) { - cp[1] = ptr[loc+1]; - } - _utf16_to_utf32( cp, uc ); - return uc; - } - - int UTFString::setChar( size_type loc, unicode_char ch ) - { - code_point cp[2] = { /* blame the code beautifier */ - 0, 0 - }; - size_t l = _utf32_to_utf16( ch, cp ); - unicode_char existingChar = getChar( loc ); - size_t existingSize = _utf16_char_length( existingChar ); - size_t newSize = _utf16_char_length( ch ); - - if ( newSize > existingSize ) { - at( loc ) = cp[0]; - insert( loc + 1, 1, cp[1] ); - return 1; - } - if ( newSize < existingSize ) { - erase( loc, 1 ); - at( loc ) = cp[0]; - return -1; - } - - // newSize == existingSize - at( loc ) = cp[0]; - if ( l == 2 ) at( loc + 1 ) = cp[1]; - return 0; - } - - Ogre::UTFString::iterator UTFString::begin() - { - iterator i; - i.mIter = mData.begin(); - i.mString = this; - return i; - } - - Ogre::UTFString::const_iterator UTFString::begin() const - { - const_iterator i; - i.mIter = const_cast( this )->mData.begin(); - i.mString = const_cast( this ); - return i; - } - - Ogre::UTFString::iterator UTFString::end() - { - iterator i; - i.mIter = mData.end(); - i.mString = this; - return i; - } - - Ogre::UTFString::const_iterator UTFString::end() const - { - const_iterator i; - i.mIter = const_cast( this )->mData.end(); - i.mString = const_cast( this ); - return i; - } - - Ogre::UTFString::reverse_iterator UTFString::rbegin() - { - reverse_iterator i; - i.mIter = mData.end(); - i.mString = this; - return i; - } - - Ogre::UTFString::const_reverse_iterator UTFString::rbegin() const - { - const_reverse_iterator i; - i.mIter = const_cast( this )->mData.end(); - i.mString = const_cast( this ); - return i; - } - - Ogre::UTFString::reverse_iterator UTFString::rend() - { - reverse_iterator i; - i.mIter = mData.begin(); - i.mString = this; - return i; - } - - Ogre::UTFString::const_reverse_iterator UTFString::rend() const - { - const_reverse_iterator i; - i.mIter = const_cast( this )->mData.begin(); - i.mString = const_cast( this ); - return i; - } - - UTFString& UTFString::assign( iterator start, iterator last ) - { - mData.assign( start.mIter, last.mIter ); - return *this; - } - - UTFString& UTFString::assign( const UTFString& str ) - { - mData.assign( str.mData ); - return *this; - } - - UTFString& UTFString::assign( const code_point* str ) - { - mData.assign( str ); - return *this; - } - - UTFString& UTFString::assign( const code_point* str, size_type num ) - { - mData.assign( str, num ); - return *this; - } - - UTFString& UTFString::assign( const UTFString& str, size_type index, size_type len ) - { - mData.assign( str.mData, index, len ); - return *this; - } - - UTFString& UTFString::assign( size_type num, const code_point& ch ) - { - mData.assign( num, ch ); - return *this; - } - - UTFString& UTFString::assign( const std::wstring& wstr ) - { - mData.clear(); - mData.reserve( wstr.length() ); // best guess bulk allocate + //-------------------------------------------------------------------------- + void UTFString::push_back( code_point val ) + { + mData.push_back( val ); + } + + void UTFString::push_back( char val ) + { + mData.push_back( static_cast( val ) ); + } + + bool UTFString::inString( unicode_char ch ) const + { + const_iterator i, ie = end(); + for ( i = begin(); i != ie; i.moveNext() ) { + if ( i.getCharacter() == ch ) + return true; + } + return false; + } + + const std::string& UTFString::asUTF8() const + { + _load_buffer_UTF8(); + return *mBuffer.mStrBuffer; + } + + const char* UTFString::asUTF8_c_str() const + { + _load_buffer_UTF8(); + return mBuffer.mStrBuffer->c_str(); + } + + const UTFString::utf32string& UTFString::asUTF32() const + { + _load_buffer_UTF32(); + return *mBuffer.mUTF32StrBuffer; + } + + const UTFString::unicode_char* UTFString::asUTF32_c_str() const + { + _load_buffer_UTF32(); + return mBuffer.mUTF32StrBuffer->c_str(); + } + + const std::wstring& UTFString::asWStr() const + { + _load_buffer_WStr(); + return *mBuffer.mWStrBuffer; + } + + const wchar_t* UTFString::asWStr_c_str() const + { + _load_buffer_WStr(); + return mBuffer.mWStrBuffer->c_str(); + } + + UTFString::code_point& UTFString::at( size_type loc ) + { + return mData.at( loc ); + } + + const UTFString::code_point& UTFString::at( size_type loc ) const + { + return mData.at( loc ); + } + + Ogre::UTFString::unicode_char UTFString::getChar( size_type loc ) const + { + const code_point* ptr = c_str(); + unicode_char uc; + size_t l = _utf16_char_length( ptr[loc] ); + code_point cp[2] = { /* blame the code beautifier */ + 0, 0 + }; + cp[0] = ptr[loc]; + + if ( l == 2 && ( loc + 1 ) < mData.length() ) { + cp[1] = ptr[loc+1]; + } + _utf16_to_utf32( cp, uc ); + return uc; + } + + int UTFString::setChar( size_type loc, unicode_char ch ) + { + code_point cp[2] = { /* blame the code beautifier */ + 0, 0 + }; + size_t l = _utf32_to_utf16( ch, cp ); + unicode_char existingChar = getChar( loc ); + size_t existingSize = _utf16_char_length( existingChar ); + size_t newSize = _utf16_char_length( ch ); + + if ( newSize > existingSize ) { + at( loc ) = cp[0]; + insert( loc + 1, 1, cp[1] ); + return 1; + } + if ( newSize < existingSize ) { + erase( loc, 1 ); + at( loc ) = cp[0]; + return -1; + } + + // newSize == existingSize + at( loc ) = cp[0]; + if ( l == 2 ) at( loc + 1 ) = cp[1]; + return 0; + } + + Ogre::UTFString::iterator UTFString::begin() + { + iterator i; + i.mIter = mData.begin(); + i.mString = this; + return i; + } + + Ogre::UTFString::const_iterator UTFString::begin() const + { + const_iterator i; + i.mIter = const_cast( this )->mData.begin(); + i.mString = const_cast( this ); + return i; + } + + Ogre::UTFString::iterator UTFString::end() + { + iterator i; + i.mIter = mData.end(); + i.mString = this; + return i; + } + + Ogre::UTFString::const_iterator UTFString::end() const + { + const_iterator i; + i.mIter = const_cast( this )->mData.end(); + i.mString = const_cast( this ); + return i; + } + + Ogre::UTFString::reverse_iterator UTFString::rbegin() + { + reverse_iterator i; + i.mIter = mData.end(); + i.mString = this; + return i; + } + + Ogre::UTFString::const_reverse_iterator UTFString::rbegin() const + { + const_reverse_iterator i; + i.mIter = const_cast( this )->mData.end(); + i.mString = const_cast( this ); + return i; + } + + Ogre::UTFString::reverse_iterator UTFString::rend() + { + reverse_iterator i; + i.mIter = mData.begin(); + i.mString = this; + return i; + } + + Ogre::UTFString::const_reverse_iterator UTFString::rend() const + { + const_reverse_iterator i; + i.mIter = const_cast( this )->mData.begin(); + i.mString = const_cast( this ); + return i; + } + + UTFString& UTFString::assign( iterator start, iterator last ) + { + mData.assign( start.mIter, last.mIter ); + return *this; + } + + UTFString& UTFString::assign( const UTFString& str ) + { + mData.assign( str.mData ); + return *this; + } + + UTFString& UTFString::assign( const code_point* str ) + { + mData.assign( str ); + return *this; + } + + UTFString& UTFString::assign( const code_point* str, size_type num ) + { + mData.assign( str, num ); + return *this; + } + + UTFString& UTFString::assign( const UTFString& str, size_type index, size_type len ) + { + mData.assign( str.mData, index, len ); + return *this; + } + + UTFString& UTFString::assign( size_type num, const code_point& ch ) + { + mData.assign( num, ch ); + return *this; + } + + UTFString& UTFString::assign( const std::wstring& wstr ) + { + mData.clear(); + mData.reserve( wstr.length() ); // best guess bulk allocate #ifdef WCHAR_UTF16 // if we're already working in UTF-16, this is easy - code_point tmp; - std::wstring::const_iterator i, ie = wstr.end(); - for ( i = wstr.begin(); i != ie; i++ ) { - tmp = static_cast( *i ); - mData.push_back( tmp ); - } + code_point tmp; + std::wstring::const_iterator i, ie = wstr.end(); + for ( i = wstr.begin(); i != ie; i++ ) { + tmp = static_cast( *i ); + mData.push_back( tmp ); + } #else // otherwise we do it the safe way (which is still 100% safe to pass UTF-16 through, just slower) - code_point cp[3] = {0, 0, 0}; - unicode_char tmp; - std::wstring::const_iterator i, ie = wstr.end(); - for ( i = wstr.begin(); i != ie; i++ ) { - tmp = static_cast( *i ); - size_t l = _utf32_to_utf16( tmp, cp ); - if ( l > 0 ) mData.push_back( cp[0] ); - if ( l > 1 ) mData.push_back( cp[1] ); - } + code_point cp[3] = {0, 0, 0}; + unicode_char tmp; + std::wstring::const_iterator i, ie = wstr.end(); + for ( i = wstr.begin(); i != ie; i++ ) { + tmp = static_cast( *i ); + size_t l = _utf32_to_utf16( tmp, cp ); + if ( l > 0 ) mData.push_back( cp[0] ); + if ( l > 1 ) mData.push_back( cp[1] ); + } #endif - return *this; - } + return *this; + } #if OGRE_IS_NATIVE_WCHAR_T - UTFString& UTFString::assign( const wchar_t* w_str ) - { - std::wstring tmp; - tmp.assign( w_str ); - return assign( tmp ); - } - - UTFString& UTFString::assign( const wchar_t* w_str, size_type num ) - { - std::wstring tmp; - tmp.assign( w_str, num ); - return assign( tmp ); - } + UTFString& UTFString::assign( const wchar_t* w_str ) + { + std::wstring tmp; + tmp.assign( w_str ); + return assign( tmp ); + } + + UTFString& UTFString::assign( const wchar_t* w_str, size_type num ) + { + std::wstring tmp; + tmp.assign( w_str, num ); + return assign( tmp ); + } #endif - UTFString& UTFString::assign( const std::string& str ) - { - size_type len = _verifyUTF8( str ); - clear(); // empty our contents, if there are any - reserve( len ); // best guess bulk capacity growth - - // This is a 3 step process, converting each byte in the UTF-8 stream to UTF-32, - // then converting it to UTF-16, then finally appending the data buffer - - unicode_char uc = 0; // temporary Unicode character buffer - unsigned char utf8buf[7]; // temporary UTF-8 buffer - utf8buf[6] = 0; - size_t utf8len; // UTF-8 length - code_point utf16buff[3]; // temporary UTF-16 buffer - utf16buff[2] = 0; - size_t utf16len; // UTF-16 length - - std::string::const_iterator i, ie = str.end(); - for ( i = str.begin(); i != ie; i++ ) { - utf8len = _utf8_char_length( static_cast( *i ) ); // estimate bytes to load - for ( size_t j = 0; j < utf8len; j++ ) { // load the needed UTF-8 bytes - utf8buf[j] = ( static_cast( *( i + j ) ) ); // we don't increment 'i' here just in case the estimate is wrong (shouldn't happen, but we're being careful) - } - utf8buf[utf8len] = 0; // nul terminate so we throw an exception before running off the end of the buffer - utf8len = _utf8_to_utf32( utf8buf, uc ); // do the UTF-8 -> UTF-32 conversion - i += utf8len - 1; // we subtract 1 for the increment of the 'for' loop - - utf16len = _utf32_to_utf16( uc, utf16buff ); // UTF-32 -> UTF-16 conversion - append( utf16buff, utf16len ); // append the characters to the string - } - return *this; - } - - UTFString& UTFString::assign( const char* str ) - { - std::string tmp( str ); - return assign( tmp ); - } - - UTFString& UTFString::assign( const char* str, size_type num ) - { - std::string tmp; - tmp.assign( str, num ); - return assign( tmp ); - } - - UTFString& UTFString::append( const UTFString& str ) - { - mData.append( str.mData ); - return *this; - } - - UTFString& UTFString::append( const code_point* str ) - { - mData.append( str ); - return *this; - } - - UTFString& UTFString::append( const UTFString& str, size_type index, size_type len ) - { - mData.append( str.mData, index, len ); - return *this; - } - - UTFString& UTFString::append( const code_point* str, size_type num ) - { - mData.append( str, num ); - return *this; - } - - UTFString& UTFString::append( size_type num, code_point ch ) - { - mData.append( num, ch ); - return *this; - } - - UTFString& UTFString::append( iterator start, iterator last ) - { - mData.append( start.mIter, last.mIter ); - return *this; - } + UTFString& UTFString::assign( const std::string& str ) + { + size_type len = _verifyUTF8( str ); + clear(); // empty our contents, if there are any + reserve( len ); // best guess bulk capacity growth + + // This is a 3 step process, converting each byte in the UTF-8 stream to UTF-32, + // then converting it to UTF-16, then finally appending the data buffer + + unicode_char uc = 0; // temporary Unicode character buffer + unsigned char utf8buf[7]; // temporary UTF-8 buffer + utf8buf[6] = 0; + size_t utf8len; // UTF-8 length + code_point utf16buff[3]; // temporary UTF-16 buffer + utf16buff[2] = 0; + size_t utf16len; // UTF-16 length + + std::string::const_iterator i, ie = str.end(); + for ( i = str.begin(); i != ie; i++ ) { + utf8len = _utf8_char_length( static_cast( *i ) ); // estimate bytes to load + for ( size_t j = 0; j < utf8len; j++ ) { // load the needed UTF-8 bytes + utf8buf[j] = ( static_cast( *( i + j ) ) ); // we don't increment 'i' here just in case the estimate is wrong (shouldn't happen, but we're being careful) + } + utf8buf[utf8len] = 0; // nul terminate so we throw an exception before running off the end of the buffer + utf8len = _utf8_to_utf32( utf8buf, uc ); // do the UTF-8 -> UTF-32 conversion + i += utf8len - 1; // we subtract 1 for the increment of the 'for' loop + + utf16len = _utf32_to_utf16( uc, utf16buff ); // UTF-32 -> UTF-16 conversion + append( utf16buff, utf16len ); // append the characters to the string + } + return *this; + } + + UTFString& UTFString::assign( const char* str ) + { + std::string tmp( str ); + return assign( tmp ); + } + + UTFString& UTFString::assign( const char* str, size_type num ) + { + std::string tmp; + tmp.assign( str, num ); + return assign( tmp ); + } + + UTFString& UTFString::append( const UTFString& str ) + { + mData.append( str.mData ); + return *this; + } + + UTFString& UTFString::append( const code_point* str ) + { + mData.append( str ); + return *this; + } + + UTFString& UTFString::append( const UTFString& str, size_type index, size_type len ) + { + mData.append( str.mData, index, len ); + return *this; + } + + UTFString& UTFString::append( const code_point* str, size_type num ) + { + mData.append( str, num ); + return *this; + } + + UTFString& UTFString::append( size_type num, code_point ch ) + { + mData.append( num, ch ); + return *this; + } + + UTFString& UTFString::append( iterator start, iterator last ) + { + mData.append( start.mIter, last.mIter ); + return *this; + } #if OGRE_IS_NATIVE_WCHAR_T - UTFString& UTFString::append( const wchar_t* w_str, size_type num ) - { - std::wstring tmp( w_str, num ); - return append( tmp ); - } - - UTFString& UTFString::append( size_type num, wchar_t ch ) - { - return append( num, static_cast( ch ) ); - } + UTFString& UTFString::append( const wchar_t* w_str, size_type num ) + { + std::wstring tmp( w_str, num ); + return append( tmp ); + } + + UTFString& UTFString::append( size_type num, wchar_t ch ) + { + return append( num, static_cast( ch ) ); + } #endif - UTFString& UTFString::append( const char* str, size_type num ) - { - UTFString tmp( str, num ); - append( tmp ); - return *this; - } - - UTFString& UTFString::append( size_type num, char ch ) - { - append( num, static_cast( ch ) ); - return *this; - } - - UTFString& UTFString::append( size_type num, unicode_char ch ) - { - code_point cp[2] = {0, 0}; - if ( _utf32_to_utf16( ch, cp ) == 2 ) { - for ( size_type i = 0; i < num; i++ ) { - append( 1, cp[0] ); - append( 1, cp[1] ); - } - } else { - for ( size_type i = 0; i < num; i++ ) { - append( 1, cp[0] ); - } - } - return *this; - } - - Ogre::UTFString::iterator UTFString::insert( iterator i, const code_point& ch ) - { - iterator ret; - ret.mIter = mData.insert( i.mIter, ch ); - ret.mString = this; - return ret; - } - - UTFString& UTFString::insert( size_type index, const UTFString& str ) - { - mData.insert( index, str.mData ); - return *this; - } - - UTFString& UTFString::insert( size_type index1, const UTFString& str, size_type index2, size_type num ) - { - mData.insert( index1, str.mData, index2, num ); - return *this; - } - - void UTFString::insert( iterator i, iterator start, iterator last ) - { - mData.insert( i.mIter, start.mIter, last.mIter ); - } - - UTFString& UTFString::insert( size_type index, const code_point* str, size_type num ) - { - mData.insert( index, str, num ); - return *this; - } + UTFString& UTFString::append( const char* str, size_type num ) + { + UTFString tmp( str, num ); + append( tmp ); + return *this; + } + + UTFString& UTFString::append( size_type num, char ch ) + { + append( num, static_cast( ch ) ); + return *this; + } + + UTFString& UTFString::append( size_type num, unicode_char ch ) + { + code_point cp[2] = {0, 0}; + if ( _utf32_to_utf16( ch, cp ) == 2 ) { + for ( size_type i = 0; i < num; i++ ) { + append( 1, cp[0] ); + append( 1, cp[1] ); + } + } else { + for ( size_type i = 0; i < num; i++ ) { + append( 1, cp[0] ); + } + } + return *this; + } + + Ogre::UTFString::iterator UTFString::insert( iterator i, const code_point& ch ) + { + iterator ret; + ret.mIter = mData.insert( i.mIter, ch ); + ret.mString = this; + return ret; + } + + UTFString& UTFString::insert( size_type index, const UTFString& str ) + { + mData.insert( index, str.mData ); + return *this; + } + + UTFString& UTFString::insert( size_type index1, const UTFString& str, size_type index2, size_type num ) + { + mData.insert( index1, str.mData, index2, num ); + return *this; + } + + void UTFString::insert( iterator i, iterator start, iterator last ) + { + mData.insert( i.mIter, start.mIter, last.mIter ); + } + + UTFString& UTFString::insert( size_type index, const code_point* str, size_type num ) + { + mData.insert( index, str, num ); + return *this; + } #if OGRE_IS_NATIVE_WCHAR_T - UTFString& UTFString::insert( size_type index, const wchar_t* w_str, size_type num ) - { - UTFString tmp( w_str, num ); - insert( index, tmp ); - return *this; - } + UTFString& UTFString::insert( size_type index, const wchar_t* w_str, size_type num ) + { + UTFString tmp( w_str, num ); + insert( index, tmp ); + return *this; + } #endif - UTFString& UTFString::insert( size_type index, const char* str, size_type num ) - { - UTFString tmp( str, num ); - insert( index, tmp ); - return *this; - } + UTFString& UTFString::insert( size_type index, const char* str, size_type num ) + { + UTFString tmp( str, num ); + insert( index, tmp ); + return *this; + } - UTFString& UTFString::insert( size_type index, size_type num, code_point ch ) - { - mData.insert( index, num, ch ); - return *this; - } + UTFString& UTFString::insert( size_type index, size_type num, code_point ch ) + { + mData.insert( index, num, ch ); + return *this; + } #if OGRE_IS_NATIVE_WCHAR_T - UTFString& UTFString::insert( size_type index, size_type num, wchar_t ch ) - { - insert( index, num, static_cast( ch ) ); - return *this; - } + UTFString& UTFString::insert( size_type index, size_type num, wchar_t ch ) + { + insert( index, num, static_cast( ch ) ); + return *this; + } #endif - UTFString& UTFString::insert( size_type index, size_type num, char ch ) - { - insert( index, num, static_cast( ch ) ); - return *this; - } - - UTFString& UTFString::insert( size_type index, size_type num, unicode_char ch ) - { - code_point cp[3] = {0, 0, 0}; - size_t l = _utf32_to_utf16( ch, cp ); - if ( l == 1 ) { - return insert( index, num, cp[0] ); - } - for ( size_type c = 0; c < num; c++ ) { - // insert in reverse order to preserve ordering after insert - insert( index, 1, cp[1] ); - insert( index, 1, cp[0] ); - } - return *this; - } - - void UTFString::insert( iterator i, size_type num, const code_point& ch ) - { - mData.insert( i.mIter, num, ch ); - } + UTFString& UTFString::insert( size_type index, size_type num, char ch ) + { + insert( index, num, static_cast( ch ) ); + return *this; + } + + UTFString& UTFString::insert( size_type index, size_type num, unicode_char ch ) + { + code_point cp[3] = {0, 0, 0}; + size_t l = _utf32_to_utf16( ch, cp ); + if ( l == 1 ) { + return insert( index, num, cp[0] ); + } + for ( size_type c = 0; c < num; c++ ) { + // insert in reverse order to preserve ordering after insert + insert( index, 1, cp[1] ); + insert( index, 1, cp[0] ); + } + return *this; + } + + void UTFString::insert( iterator i, size_type num, const code_point& ch ) + { + mData.insert( i.mIter, num, ch ); + } #if OGRE_IS_NATIVE_WCHAR_T - void UTFString::insert( iterator i, size_type num, const wchar_t& ch ) - { - insert( i, num, static_cast( ch ) ); - } + void UTFString::insert( iterator i, size_type num, const wchar_t& ch ) + { + insert( i, num, static_cast( ch ) ); + } #endif - void UTFString::insert( iterator i, size_type num, const char& ch ) - { - insert( i, num, static_cast( ch ) ); - } - - void UTFString::insert( iterator i, size_type num, const unicode_char& ch ) - { - code_point cp[3] = {0, 0, 0}; - size_t l = _utf32_to_utf16( ch, cp ); - if ( l == 1 ) { - insert( i, num, cp[0] ); - } else { - for ( size_type c = 0; c < num; c++ ) { - // insert in reverse order to preserve ordering after insert - insert( i, 1, cp[1] ); - insert( i, 1, cp[0] ); - } - } - } - - Ogre::UTFString::iterator UTFString::erase( iterator loc ) - { - iterator ret; - ret.mIter = mData.erase( loc.mIter ); - ret.mString = this; - return ret; - } - - Ogre::UTFString::iterator UTFString::erase( iterator start, iterator last ) - { - iterator ret; - ret.mIter = mData.erase( start.mIter, last.mIter ); - ret.mString = this; - return ret; - } - - UTFString& UTFString::erase( size_type index /*= 0*/, size_type num /*= npos */ ) - { - if ( num == npos ) - mData.erase( index ); - else - mData.erase( index, num ); - return *this; - } - - UTFString& UTFString::replace( size_type index1, size_type num1, const UTFString& str ) - { - mData.replace( index1, num1, str.mData, 0, npos ); - return *this; - } - - UTFString& UTFString::replace( size_type index1, size_type num1, const UTFString& str, size_type num2 ) - { - mData.replace( index1, num1, str.mData, 0, num2 ); - return *this; - } - - UTFString& UTFString::replace( size_type index1, size_type num1, const UTFString& str, size_type index2, size_type num2 ) - { - mData.replace( index1, num1, str.mData, index2, num2 ); - return *this; - } - - UTFString& UTFString::replace( iterator start, iterator last, const UTFString& str, size_type num /*= npos */ ) - { - _const_fwd_iterator st(start); //Work around for gcc, allow it to find correct overload - - size_type index1 = begin() - st; - size_type num1 = last - st; - return replace( index1, num1, str, 0, num ); - } - - UTFString& UTFString::replace( size_type index, size_type num1, size_type num2, code_point ch ) - { - mData.replace( index, num1, num2, ch ); - return *this; - } - - UTFString& UTFString::replace( iterator start, iterator last, size_type num, code_point ch ) - { - _const_fwd_iterator st(start); //Work around for gcc, allow it to find correct overload - - size_type index1 = begin() - st; - size_type num1 = last - st; - return replace( index1, num1, num, ch ); - } - - int UTFString::compare( const UTFString& str ) const - { - return mData.compare( str.mData ); - } - - int UTFString::compare( const code_point* str ) const - { - return mData.compare( str ); - } - - int UTFString::compare( size_type index, size_type inLength, const UTFString& str ) const - { - return mData.compare( index, inLength, str.mData ); - } - - int UTFString::compare( size_type index, size_type inLength, const UTFString& str, size_type index2, size_type length2 ) const - { - return mData.compare( index, inLength, str.mData, index2, length2 ); - } - - int UTFString::compare( size_type index, size_type inLength, const code_point* str, size_type length2 ) const - { - return mData.compare( index, inLength, str, length2 ); - } + void UTFString::insert( iterator i, size_type num, const char& ch ) + { + insert( i, num, static_cast( ch ) ); + } + + void UTFString::insert( iterator i, size_type num, const unicode_char& ch ) + { + code_point cp[3] = {0, 0, 0}; + size_t l = _utf32_to_utf16( ch, cp ); + if ( l == 1 ) { + insert( i, num, cp[0] ); + } else { + for ( size_type c = 0; c < num; c++ ) { + // insert in reverse order to preserve ordering after insert + insert( i, 1, cp[1] ); + insert( i, 1, cp[0] ); + } + } + } + + Ogre::UTFString::iterator UTFString::erase( iterator loc ) + { + iterator ret; + ret.mIter = mData.erase( loc.mIter ); + ret.mString = this; + return ret; + } + + Ogre::UTFString::iterator UTFString::erase( iterator start, iterator last ) + { + iterator ret; + ret.mIter = mData.erase( start.mIter, last.mIter ); + ret.mString = this; + return ret; + } + + UTFString& UTFString::erase( size_type index /*= 0*/, size_type num /*= npos */ ) + { + if ( num == npos ) + mData.erase( index ); + else + mData.erase( index, num ); + return *this; + } + + UTFString& UTFString::replace( size_type index1, size_type num1, const UTFString& str ) + { + mData.replace( index1, num1, str.mData, 0, npos ); + return *this; + } + + UTFString& UTFString::replace( size_type index1, size_type num1, const UTFString& str, size_type num2 ) + { + mData.replace( index1, num1, str.mData, 0, num2 ); + return *this; + } + + UTFString& UTFString::replace( size_type index1, size_type num1, const UTFString& str, size_type index2, size_type num2 ) + { + mData.replace( index1, num1, str.mData, index2, num2 ); + return *this; + } + + UTFString& UTFString::replace( iterator start, iterator last, const UTFString& str, size_type num /*= npos */ ) + { + _const_fwd_iterator st(start); //Work around for gcc, allow it to find correct overload + + size_type index1 = begin() - st; + size_type num1 = last - st; + return replace( index1, num1, str, 0, num ); + } + + UTFString& UTFString::replace( size_type index, size_type num1, size_type num2, code_point ch ) + { + mData.replace( index, num1, num2, ch ); + return *this; + } + + UTFString& UTFString::replace( iterator start, iterator last, size_type num, code_point ch ) + { + _const_fwd_iterator st(start); //Work around for gcc, allow it to find correct overload + + size_type index1 = begin() - st; + size_type num1 = last - st; + return replace( index1, num1, num, ch ); + } + + int UTFString::compare( const UTFString& str ) const + { + return mData.compare( str.mData ); + } + + int UTFString::compare( const code_point* str ) const + { + return mData.compare( str ); + } + + int UTFString::compare( size_type index, size_type inLength, const UTFString& str ) const + { + return mData.compare( index, inLength, str.mData ); + } + + int UTFString::compare( size_type index, size_type inLength, const UTFString& str, size_type index2, size_type length2 ) const + { + return mData.compare( index, inLength, str.mData, index2, length2 ); + } + + int UTFString::compare( size_type index, size_type inLength, const code_point* str, size_type length2 ) const + { + return mData.compare( index, inLength, str, length2 ); + } #if OGRE_IS_NATIVE_WCHAR_T - int UTFString::compare( size_type index, size_type inLength, const wchar_t* w_str, size_type length2 ) const - { - UTFString tmp( w_str, length2 ); - return compare( index, inLength, tmp ); - } + int UTFString::compare( size_type index, size_type inLength, const wchar_t* w_str, size_type length2 ) const + { + UTFString tmp( w_str, length2 ); + return compare( index, inLength, tmp ); + } #endif - int UTFString::compare( size_type index, size_type inLength, const char* str, size_type length2 ) const - { - UTFString tmp( str, length2 ); - return compare( index, inLength, tmp ); - } - - Ogre::UTFString::size_type UTFString::find( const UTFString& str, size_type index /*= 0 */ ) const - { - return mData.find( str.c_str(), index ); - } - - Ogre::UTFString::size_type UTFString::find( const code_point* cp_str, size_type index, size_type inLength ) const - { - UTFString tmp( cp_str ); - return mData.find( tmp.c_str(), index, inLength ); - } - - Ogre::UTFString::size_type UTFString::find( const char* str, size_type index, size_type inLength ) const - { - UTFString tmp( str ); - return mData.find( tmp.c_str(), index, inLength ); - } + int UTFString::compare( size_type index, size_type inLength, const char* str, size_type length2 ) const + { + UTFString tmp( str, length2 ); + return compare( index, inLength, tmp ); + } + + Ogre::UTFString::size_type UTFString::find( const UTFString& str, size_type index /*= 0 */ ) const + { + return mData.find( str.c_str(), index ); + } + + Ogre::UTFString::size_type UTFString::find( const code_point* cp_str, size_type index, size_type inLength ) const + { + UTFString tmp( cp_str ); + return mData.find( tmp.c_str(), index, inLength ); + } + + Ogre::UTFString::size_type UTFString::find( const char* str, size_type index, size_type inLength ) const + { + UTFString tmp( str ); + return mData.find( tmp.c_str(), index, inLength ); + } #if OGRE_IS_NATIVE_WCHAR_T - Ogre::UTFString::size_type UTFString::find( const wchar_t* w_str, size_type index, size_type inLength ) const - { - UTFString tmp( w_str ); - return mData.find( tmp.c_str(), index, inLength ); - } + Ogre::UTFString::size_type UTFString::find( const wchar_t* w_str, size_type index, size_type inLength ) const + { + UTFString tmp( w_str ); + return mData.find( tmp.c_str(), index, inLength ); + } #endif - Ogre::UTFString::size_type UTFString::find( char ch, size_type index /*= 0 */ ) const - { - return find( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::find( char ch, size_type index /*= 0 */ ) const + { + return find( static_cast( ch ), index ); + } - Ogre::UTFString::size_type UTFString::find( code_point ch, size_type index /*= 0 */ ) const - { - return mData.find( ch, index ); - } + Ogre::UTFString::size_type UTFString::find( code_point ch, size_type index /*= 0 */ ) const + { + return mData.find( ch, index ); + } #if OGRE_IS_NATIVE_WCHAR_T - Ogre::UTFString::size_type UTFString::find( wchar_t ch, size_type index /*= 0 */ ) const - { - return find( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::find( wchar_t ch, size_type index /*= 0 */ ) const + { + return find( static_cast( ch ), index ); + } #endif - Ogre::UTFString::size_type UTFString::find( unicode_char ch, size_type index /*= 0 */ ) const - { - code_point cp[3] = {0, 0, 0}; - size_t l = _utf32_to_utf16( ch, cp ); - return find( UTFString( cp, l ), index ); - } - - Ogre::UTFString::size_type UTFString::rfind( const UTFString& str, size_type index /*= 0 */ ) const - { - return mData.rfind( str.c_str(), index ); - } - - Ogre::UTFString::size_type UTFString::rfind( const code_point* cp_str, size_type index, size_type num ) const - { - UTFString tmp( cp_str ); - return mData.rfind( tmp.c_str(), index, num ); - } - - Ogre::UTFString::size_type UTFString::rfind( const char* str, size_type index, size_type num ) const - { - UTFString tmp( str ); - return mData.rfind( tmp.c_str(), index, num ); - } + Ogre::UTFString::size_type UTFString::find( unicode_char ch, size_type index /*= 0 */ ) const + { + code_point cp[3] = {0, 0, 0}; + size_t l = _utf32_to_utf16( ch, cp ); + return find( UTFString( cp, l ), index ); + } + + Ogre::UTFString::size_type UTFString::rfind( const UTFString& str, size_type index /*= 0 */ ) const + { + return mData.rfind( str.c_str(), index ); + } + + Ogre::UTFString::size_type UTFString::rfind( const code_point* cp_str, size_type index, size_type num ) const + { + UTFString tmp( cp_str ); + return mData.rfind( tmp.c_str(), index, num ); + } + + Ogre::UTFString::size_type UTFString::rfind( const char* str, size_type index, size_type num ) const + { + UTFString tmp( str ); + return mData.rfind( tmp.c_str(), index, num ); + } #if OGRE_IS_NATIVE_WCHAR_T - Ogre::UTFString::size_type UTFString::rfind( const wchar_t* w_str, size_type index, size_type num ) const - { - UTFString tmp( w_str ); - return mData.rfind( tmp.c_str(), index, num ); - } + Ogre::UTFString::size_type UTFString::rfind( const wchar_t* w_str, size_type index, size_type num ) const + { + UTFString tmp( w_str ); + return mData.rfind( tmp.c_str(), index, num ); + } #endif - Ogre::UTFString::size_type UTFString::rfind( char ch, size_type index /*= 0 */ ) const - { - return rfind( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::rfind( char ch, size_type index /*= 0 */ ) const + { + return rfind( static_cast( ch ), index ); + } - Ogre::UTFString::size_type UTFString::rfind( code_point ch, size_type index ) const - { - return mData.rfind( ch, index ); - } + Ogre::UTFString::size_type UTFString::rfind( code_point ch, size_type index ) const + { + return mData.rfind( ch, index ); + } #if OGRE_IS_NATIVE_WCHAR_T - Ogre::UTFString::size_type UTFString::rfind( wchar_t ch, size_type index /*= 0 */ ) const - { - return rfind( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::rfind( wchar_t ch, size_type index /*= 0 */ ) const + { + return rfind( static_cast( ch ), index ); + } #endif - Ogre::UTFString::size_type UTFString::rfind( unicode_char ch, size_type index /*= 0 */ ) const - { - code_point cp[3] = {0, 0, 0}; - size_t l = _utf32_to_utf16( ch, cp ); - return rfind( UTFString( cp, l ), index ); - } - - Ogre::UTFString::size_type UTFString::find_first_of( const UTFString &str, size_type index /*= 0*/, size_type num /*= npos */ ) const - { - size_type i = 0; - const size_type len = length(); - while ( i < num && ( index + i ) < len ) { - unicode_char ch = getChar( index + i ); - if ( str.inString( ch ) ) - return index + i; - i += _utf16_char_length( ch ); // increment by the Unicode character length - } - return npos; - } - - Ogre::UTFString::size_type UTFString::find_first_of( code_point ch, size_type index /*= 0 */ ) const - { - UTFString tmp; - tmp.assign( 1, ch ); - return find_first_of( tmp, index ); - } - - Ogre::UTFString::size_type UTFString::find_first_of( char ch, size_type index /*= 0 */ ) const - { - return find_first_of( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::rfind( unicode_char ch, size_type index /*= 0 */ ) const + { + code_point cp[3] = {0, 0, 0}; + size_t l = _utf32_to_utf16( ch, cp ); + return rfind( UTFString( cp, l ), index ); + } + + Ogre::UTFString::size_type UTFString::find_first_of( const UTFString &str, size_type index /*= 0*/, size_type num /*= npos */ ) const + { + size_type i = 0; + const size_type len = length(); + while ( i < num && ( index + i ) < len ) { + unicode_char ch = getChar( index + i ); + if ( str.inString( ch ) ) + return index + i; + i += _utf16_char_length( ch ); // increment by the Unicode character length + } + return npos; + } + + Ogre::UTFString::size_type UTFString::find_first_of( code_point ch, size_type index /*= 0 */ ) const + { + UTFString tmp; + tmp.assign( 1, ch ); + return find_first_of( tmp, index ); + } + + Ogre::UTFString::size_type UTFString::find_first_of( char ch, size_type index /*= 0 */ ) const + { + return find_first_of( static_cast( ch ), index ); + } #if OGRE_IS_NATIVE_WCHAR_T - Ogre::UTFString::size_type UTFString::find_first_of( wchar_t ch, size_type index /*= 0 */ ) const - { - return find_first_of( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::find_first_of( wchar_t ch, size_type index /*= 0 */ ) const + { + return find_first_of( static_cast( ch ), index ); + } #endif - Ogre::UTFString::size_type UTFString::find_first_of( unicode_char ch, size_type index /*= 0 */ ) const - { - code_point cp[3] = {0, 0, 0}; - size_t l = _utf32_to_utf16( ch, cp ); - return find_first_of( UTFString( cp, l ), index ); - } - - Ogre::UTFString::size_type UTFString::find_first_not_of( const UTFString& str, size_type index /*= 0*/, size_type num /*= npos */ ) const - { - size_type i = 0; - const size_type len = length(); - while ( i < num && ( index + i ) < len ) { - unicode_char ch = getChar( index + i ); - if ( !str.inString( ch ) ) - return index + i; - i += _utf16_char_length( ch ); // increment by the Unicode character length - } - return npos; - } - - Ogre::UTFString::size_type UTFString::find_first_not_of( code_point ch, size_type index /*= 0 */ ) const - { - UTFString tmp; - tmp.assign( 1, ch ); - return find_first_not_of( tmp, index ); - } - - Ogre::UTFString::size_type UTFString::find_first_not_of( char ch, size_type index /*= 0 */ ) const - { - return find_first_not_of( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::find_first_of( unicode_char ch, size_type index /*= 0 */ ) const + { + code_point cp[3] = {0, 0, 0}; + size_t l = _utf32_to_utf16( ch, cp ); + return find_first_of( UTFString( cp, l ), index ); + } + + Ogre::UTFString::size_type UTFString::find_first_not_of( const UTFString& str, size_type index /*= 0*/, size_type num /*= npos */ ) const + { + size_type i = 0; + const size_type len = length(); + while ( i < num && ( index + i ) < len ) { + unicode_char ch = getChar( index + i ); + if ( !str.inString( ch ) ) + return index + i; + i += _utf16_char_length( ch ); // increment by the Unicode character length + } + return npos; + } + + Ogre::UTFString::size_type UTFString::find_first_not_of( code_point ch, size_type index /*= 0 */ ) const + { + UTFString tmp; + tmp.assign( 1, ch ); + return find_first_not_of( tmp, index ); + } + + Ogre::UTFString::size_type UTFString::find_first_not_of( char ch, size_type index /*= 0 */ ) const + { + return find_first_not_of( static_cast( ch ), index ); + } #if OGRE_IS_NATIVE_WCHAR_T - Ogre::UTFString::size_type UTFString::find_first_not_of( wchar_t ch, size_type index /*= 0 */ ) const - { - return find_first_not_of( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::find_first_not_of( wchar_t ch, size_type index /*= 0 */ ) const + { + return find_first_not_of( static_cast( ch ), index ); + } #endif - Ogre::UTFString::size_type UTFString::find_first_not_of( unicode_char ch, size_type index /*= 0 */ ) const - { - code_point cp[3] = {0, 0, 0}; - size_t l = _utf32_to_utf16( ch, cp ); - return find_first_not_of( UTFString( cp, l ), index ); - } - - Ogre::UTFString::size_type UTFString::find_last_of( const UTFString& str, size_type index /*= npos*/, size_type num /*= npos */ ) const - { - size_type i = 0; - const size_type len = length(); - if ( index > len ) index = len - 1; - - while ( i < num && ( index - i ) != npos ) { - size_type j = index - i; - // careful to step full Unicode characters - if ( j != 0 && _utf16_surrogate_follow( at( j ) ) && _utf16_surrogate_lead( at( j - 1 ) ) ) { - j = index - ++i; - } - // and back to the usual dull test - unicode_char ch = getChar( j ); - if ( str.inString( ch ) ) - return j; - i++; - } - return npos; - } - - Ogre::UTFString::size_type UTFString::find_last_of( code_point ch, size_type index /*= npos */ ) const - { - UTFString tmp; - tmp.assign( 1, ch ); - return find_last_of( tmp, index ); - } + Ogre::UTFString::size_type UTFString::find_first_not_of( unicode_char ch, size_type index /*= 0 */ ) const + { + code_point cp[3] = {0, 0, 0}; + size_t l = _utf32_to_utf16( ch, cp ); + return find_first_not_of( UTFString( cp, l ), index ); + } + + Ogre::UTFString::size_type UTFString::find_last_of( const UTFString& str, size_type index /*= npos*/, size_type num /*= npos */ ) const + { + size_type i = 0; + const size_type len = length(); + if ( index > len ) index = len - 1; + + while ( i < num && ( index - i ) != npos ) { + size_type j = index - i; + // careful to step full Unicode characters + if ( j != 0 && _utf16_surrogate_follow( at( j ) ) && _utf16_surrogate_lead( at( j - 1 ) ) ) { + j = index - ++i; + } + // and back to the usual dull test + unicode_char ch = getChar( j ); + if ( str.inString( ch ) ) + return j; + i++; + } + return npos; + } + + Ogre::UTFString::size_type UTFString::find_last_of( code_point ch, size_type index /*= npos */ ) const + { + UTFString tmp; + tmp.assign( 1, ch ); + return find_last_of( tmp, index ); + } #if OGRE_IS_NATIVE_WCHAR_T - Ogre::UTFString::size_type UTFString::find_last_of( wchar_t ch, size_type index /*= npos */ ) const - { - return find_last_of( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::find_last_of( wchar_t ch, size_type index /*= npos */ ) const + { + return find_last_of( static_cast( ch ), index ); + } #endif - Ogre::UTFString::size_type UTFString::find_last_of( unicode_char ch, size_type index /*= npos */ ) const - { - code_point cp[3] = {0, 0, 0}; - size_t l = _utf32_to_utf16( ch, cp ); - return find_last_of( UTFString( cp, l ), index ); - } - - Ogre::UTFString::size_type UTFString::find_last_not_of( const UTFString& str, size_type index /*= npos*/, size_type num /*= npos */ ) const - { - size_type i = 0; - const size_type len = length(); - if ( index > len ) index = len - 1; - - while ( i < num && ( index - i ) != npos ) { - size_type j = index - i; - // careful to step full Unicode characters - if ( j != 0 && _utf16_surrogate_follow( at( j ) ) && _utf16_surrogate_lead( at( j - 1 ) ) ) { - j = index - ++i; - } - // and back to the usual dull test - unicode_char ch = getChar( j ); - if ( !str.inString( ch ) ) - return j; - i++; - } - return npos; - } - - Ogre::UTFString::size_type UTFString::find_last_not_of( code_point ch, size_type index /*= npos */ ) const - { - UTFString tmp; - tmp.assign( 1, ch ); - return find_last_not_of( tmp, index ); - } - - Ogre::UTFString::size_type UTFString::find_last_not_of( char ch, size_type index /*= npos */ ) const - { - return find_last_not_of( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::find_last_of( unicode_char ch, size_type index /*= npos */ ) const + { + code_point cp[3] = {0, 0, 0}; + size_t l = _utf32_to_utf16( ch, cp ); + return find_last_of( UTFString( cp, l ), index ); + } + + Ogre::UTFString::size_type UTFString::find_last_not_of( const UTFString& str, size_type index /*= npos*/, size_type num /*= npos */ ) const + { + size_type i = 0; + const size_type len = length(); + if ( index > len ) index = len - 1; + + while ( i < num && ( index - i ) != npos ) { + size_type j = index - i; + // careful to step full Unicode characters + if ( j != 0 && _utf16_surrogate_follow( at( j ) ) && _utf16_surrogate_lead( at( j - 1 ) ) ) { + j = index - ++i; + } + // and back to the usual dull test + unicode_char ch = getChar( j ); + if ( !str.inString( ch ) ) + return j; + i++; + } + return npos; + } + + Ogre::UTFString::size_type UTFString::find_last_not_of( code_point ch, size_type index /*= npos */ ) const + { + UTFString tmp; + tmp.assign( 1, ch ); + return find_last_not_of( tmp, index ); + } + + Ogre::UTFString::size_type UTFString::find_last_not_of( char ch, size_type index /*= npos */ ) const + { + return find_last_not_of( static_cast( ch ), index ); + } #if OGRE_IS_NATIVE_WCHAR_T - Ogre::UTFString::size_type UTFString::find_last_not_of( wchar_t ch, size_type index /*= npos */ ) const - { - return find_last_not_of( static_cast( ch ), index ); - } + Ogre::UTFString::size_type UTFString::find_last_not_of( wchar_t ch, size_type index /*= npos */ ) const + { + return find_last_not_of( static_cast( ch ), index ); + } #endif - Ogre::UTFString::size_type UTFString::find_last_not_of( unicode_char ch, size_type index /*= npos */ ) const - { - code_point cp[3] = {0, 0, 0}; - size_t l = _utf32_to_utf16( ch, cp ); - return find_last_not_of( UTFString( cp, l ), index ); - } - - bool UTFString::operator<( const UTFString& right ) const - { - return compare( right ) < 0; - } - - bool UTFString::operator<=( const UTFString& right ) const - { - return compare( right ) <= 0; - } - - UTFString& UTFString::operator=( const UTFString& s ) - { - return assign( s ); - } - - UTFString& UTFString::operator=( code_point ch ) - { - clear(); - return append( 1, ch ); - } - - UTFString& UTFString::operator=( char ch ) - { - clear(); - return append( 1, ch ); - } + Ogre::UTFString::size_type UTFString::find_last_not_of( unicode_char ch, size_type index /*= npos */ ) const + { + code_point cp[3] = {0, 0, 0}; + size_t l = _utf32_to_utf16( ch, cp ); + return find_last_not_of( UTFString( cp, l ), index ); + } + + bool UTFString::operator<( const UTFString& right ) const + { + return compare( right ) < 0; + } + + bool UTFString::operator<=( const UTFString& right ) const + { + return compare( right ) <= 0; + } + + UTFString& UTFString::operator=( const UTFString& s ) + { + return assign( s ); + } + + UTFString& UTFString::operator=( code_point ch ) + { + clear(); + return append( 1, ch ); + } + + UTFString& UTFString::operator=( char ch ) + { + clear(); + return append( 1, ch ); + } #if OGRE_IS_NATIVE_WCHAR_T - UTFString& UTFString::operator=( wchar_t ch ) - { - clear(); - return append( 1, ch ); - } + UTFString& UTFString::operator=( wchar_t ch ) + { + clear(); + return append( 1, ch ); + } #endif - UTFString& UTFString::operator=( unicode_char ch ) - { - clear(); - return append( 1, ch ); - } - - bool UTFString::operator>( const UTFString& right ) const - { - return compare( right ) > 0; - } - - bool UTFString::operator>=( const UTFString& right ) const - { - return compare( right ) >= 0; - } - - bool UTFString::operator==( const UTFString& right ) const - { - return compare( right ) == 0; - } - - bool UTFString::operator!=( const UTFString& right ) const - { - return !operator==( right ); - } - - UTFString::code_point& UTFString::operator[]( size_type index ) - { - return at( index ); - } - - const UTFString::code_point& UTFString::operator[]( size_type index ) const - { - return at( index ); - } - - UTFString::operator std::string() const - { - return std::string( asUTF8() ); - } - - //! implicit cast to std::wstring - UTFString::operator std::wstring() const - { - return std::wstring( asWStr() ); - } + UTFString& UTFString::operator=( unicode_char ch ) + { + clear(); + return append( 1, ch ); + } + + bool UTFString::operator>( const UTFString& right ) const + { + return compare( right ) > 0; + } + + bool UTFString::operator>=( const UTFString& right ) const + { + return compare( right ) >= 0; + } + + bool UTFString::operator==( const UTFString& right ) const + { + return compare( right ) == 0; + } + + bool UTFString::operator!=( const UTFString& right ) const + { + return !operator==( right ); + } + + UTFString::code_point& UTFString::operator[]( size_type index ) + { + return at( index ); + } + + const UTFString::code_point& UTFString::operator[]( size_type index ) const + { + return at( index ); + } + + UTFString::operator std::string() const + { + return std::string( asUTF8() ); + } + + //! implicit cast to std::wstring + UTFString::operator std::wstring() const + { + return std::wstring( asWStr() ); + } #if OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR - //! implicit cast to Ogre::String - UTFString::operator Ogre::String() const - { + //! implicit cast to Ogre::String + UTFString::operator Ogre::String() const + { #if OGRE_WCHAR_T_STRINGS - return Ogre::String( asWStr() ); + return Ogre::String( asWStr() ); #else - return Ogre::String( asUTF8().c_str() ); + return Ogre::String( asUTF8().c_str() ); #endif - } + } #endif - bool UTFString::_utf16_independent_char( code_point cp ) - { - if ( 0xD800 <= cp && cp <= 0xDFFF ) // tests if the cp is within the surrogate pair range - return false; // it matches a surrogate pair signature - return true; // everything else is a standalone code point - } - - bool UTFString::_utf16_surrogate_lead( code_point cp ) - { - if ( 0xD800 <= cp && cp <= 0xDBFF ) // tests if the cp is within the 2nd word of a surrogate pair - return true; // it is a 1st word - return false; // it isn't - } - - bool UTFString::_utf16_surrogate_follow( code_point cp ) - { - if ( 0xDC00 <= cp && cp <= 0xDFFF ) // tests if the cp is within the 2nd word of a surrogate pair - return true; // it is a 2nd word - return false; // everything else isn't - } - - size_t UTFString::_utf16_char_length( code_point cp ) - { - if ( 0xD800 <= cp && cp <= 0xDBFF ) // test if cp is the beginning of a surrogate pair - return 2; // if it is, then we are 2 words long - return 1; // otherwise we are only 1 word long - } - - size_t UTFString::_utf16_char_length( unicode_char uc ) - { - if ( uc > 0xFFFF ) // test if uc is greater than the single word maximum - return 2; // if so, we need a surrogate pair - return 1; // otherwise we can stuff it into a single word - } - - size_t UTFString::_utf16_to_utf32( const code_point in_cp[2], unicode_char& out_uc ) - { - const code_point& cp1 = in_cp[0]; - const code_point& cp2 = in_cp[1]; - bool wordPair = false; - - // does it look like a surrogate pair? - if ( 0xD800 <= cp1 && cp1 <= 0xDBFF ) { - // looks like one, but does the other half match the algorithm as well? - if ( 0xDC00 <= cp2 && cp2 <= 0xDFFF ) - wordPair = true; // yep! - } - - if ( !wordPair ) { // if we aren't a 100% authentic surrogate pair, then just copy the value - out_uc = cp1; - return 1; - } - - unsigned short cU = cp1, cL = cp2; // copy upper and lower words of surrogate pair to writable buffers - cU -= 0xD800; // remove the encoding markers - cL -= 0xDC00; - - out_uc = ( cU & 0x03FF ) << 10; // grab the 10 upper bits and set them in their proper location - out_uc |= ( cL & 0x03FF ); // combine in the lower 10 bits - out_uc += 0x10000; // add back in the value offset - - return 2; // this whole operation takes to words, so that's what we'll return - } - - size_t UTFString::_utf32_to_utf16( const unicode_char& in_uc, code_point out_cp[2] ) - { - if ( in_uc <= 0xFFFF ) { // we blindly preserve sentinel values because our decoder understands them - out_cp[0] = static_cast(in_uc); - return 1; - } - unicode_char uc = in_uc; // copy to writable buffer - unsigned short tmp; // single code point buffer - uc -= 0x10000; // subtract value offset - - //process upper word - tmp = static_cast(( uc >> 10 ) & 0x03FF); // grab the upper 10 bits - tmp += 0xD800; // add encoding offset - out_cp[0] = tmp; // write - - // process lower word - tmp = static_cast(uc & 0x03FF); // grab the lower 10 bits - tmp += 0xDC00; // add encoding offset - out_cp[1] = tmp; // write - - return 2; // return used word count (2 for surrogate pairs) - } - - bool UTFString::_utf8_start_char( unsigned char cp ) - { - return ( cp & ~_cont_mask ) != _cont; - } - - size_t UTFString::_utf8_char_length( unsigned char cp ) - { - if ( !( cp & 0x80 ) ) return 1; - if (( cp & ~_lead1_mask ) == _lead1 ) return 2; - if (( cp & ~_lead2_mask ) == _lead2 ) return 3; - if (( cp & ~_lead3_mask ) == _lead3 ) return 4; - if (( cp & ~_lead4_mask ) == _lead4 ) return 5; - if (( cp & ~_lead5_mask ) == _lead5 ) return 6; - throw invalid_data( "invalid UTF-8 sequence header value" ); - } - - size_t UTFString::_utf8_char_length( unicode_char uc ) - { - /* - 7 bit: U-00000000 - U-0000007F: 0xxxxxxx - 11 bit: U-00000080 - U-000007FF: 110xxxxx 10xxxxxx - 16 bit: U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx - 21 bit: U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - 26 bit: U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - 31 bit: U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - */ - if ( !( uc & ~0x0000007F ) ) return 1; - if ( !( uc & ~0x000007FF ) ) return 2; - if ( !( uc & ~0x0000FFFF ) ) return 3; - if ( !( uc & ~0x001FFFFF ) ) return 4; - if ( !( uc & ~0x03FFFFFF ) ) return 5; - if ( !( uc & ~0x7FFFFFFF ) ) return 6; - throw invalid_data( "invalid UTF-32 value" ); - } - - size_t UTFString::_utf8_to_utf32( const unsigned char in_cp[6], unicode_char& out_uc ) - { - size_t len = _utf8_char_length( in_cp[0] ); - if ( len == 1 ) { // if we are only 1 byte long, then just grab it and exit - out_uc = in_cp[0]; - return 1; - } - - unicode_char c = 0; // temporary buffer - size_t i = 0; - switch ( len ) { // load header byte - case 6: - c = in_cp[i] & _lead5_mask; - break; - case 5: - c = in_cp[i] & _lead4_mask; - break; - case 4: - c = in_cp[i] & _lead3_mask; - break; - case 3: - c = in_cp[i] & _lead2_mask; - break; - case 2: - c = in_cp[i] & _lead1_mask; - break; - } - - for ( ++i; i < len; i++ ) { // load each continuation byte - if (( in_cp[i] & ~_cont_mask ) != _cont ) - throw invalid_data( "bad UTF-8 continuation byte" ); - c <<= 6; - c |= ( in_cp[i] & _cont_mask ); - } - - out_uc = c; // write the final value and return the used byte length - return len; - } - - size_t UTFString::_utf32_to_utf8( const unicode_char& in_uc, unsigned char out_cp[6] ) - { - size_t len = _utf8_char_length( in_uc ); // predict byte length of sequence - unicode_char c = in_uc; // copy to temp buffer - - //stuff all of the lower bits - for ( size_t i = len - 1; i > 0; i-- ) { - out_cp[i] = static_cast((( c ) & _cont_mask ) | _cont); - c >>= 6; - } - - //now write the header byte - switch ( len ) { - case 6: - out_cp[0] = static_cast((( c ) & _lead5_mask ) | _lead5); - break; - case 5: - out_cp[0] = static_cast((( c ) & _lead4_mask ) | _lead4); - break; - case 4: - out_cp[0] = static_cast((( c ) & _lead3_mask ) | _lead3); - break; - case 3: - out_cp[0] = static_cast((( c ) & _lead2_mask ) | _lead2); - break; - case 2: - out_cp[0] = static_cast((( c ) & _lead1_mask ) | _lead1); - break; - case 1: - default: - out_cp[0] = static_cast(( c ) & 0x7F); - break; - } - - // return the byte length of the sequence - return len; - } - - Ogre::UTFString::size_type UTFString::_verifyUTF8( const unsigned char* c_str ) - { - std::string tmp( reinterpret_cast( c_str ) ); - return _verifyUTF8( tmp ); - } - - Ogre::UTFString::size_type UTFString::_verifyUTF8( const std::string& str ) - { - std::string::const_iterator i, ie = str.end(); - i = str.begin(); - size_type length = 0; - - while ( i != ie ) { - // characters pass until we find an extended sequence - if (( *i ) & 0x80 ) { - unsigned char c = ( *i ); - size_t contBytes = 0; - - // get continuation byte count and test for overlong sequences - if (( c & ~_lead1_mask ) == _lead1 ) { // 1 additional byte - if ( c == _lead1 ) throw invalid_data( "overlong UTF-8 sequence" ); - contBytes = 1; - - } else if (( c & ~_lead2_mask ) == _lead2 ) { // 2 additional bytes - contBytes = 2; - if ( c == _lead2 ) { // possible overlong UTF-8 sequence - c = ( *( i + 1 ) ); // look ahead to next byte in sequence - if (( c & _lead2 ) == _cont ) throw invalid_data( "overlong UTF-8 sequence" ); - } - - } else if (( c & ~_lead3_mask ) == _lead3 ) { // 3 additional bytes - contBytes = 3; - if ( c == _lead3 ) { // possible overlong UTF-8 sequence - c = ( *( i + 1 ) ); // look ahead to next byte in sequence - if (( c & _lead3 ) == _cont ) throw invalid_data( "overlong UTF-8 sequence" ); - } - - } else if (( c & ~_lead4_mask ) == _lead4 ) { // 4 additional bytes - contBytes = 4; - if ( c == _lead4 ) { // possible overlong UTF-8 sequence - c = ( *( i + 1 ) ); // look ahead to next byte in sequence - if (( c & _lead4 ) == _cont ) throw invalid_data( "overlong UTF-8 sequence" ); - } - - } else if (( c & ~_lead5_mask ) == _lead5 ) { // 5 additional bytes - contBytes = 5; - if ( c == _lead5 ) { // possible overlong UTF-8 sequence - c = ( *( i + 1 ) ); // look ahead to next byte in sequence - if (( c & _lead5 ) == _cont ) throw invalid_data( "overlong UTF-8 sequence" ); - } - } - - // check remaining continuation bytes for - while ( contBytes-- ) { - c = ( *( ++i ) ); // get next byte in sequence - if (( c & ~_cont_mask ) != _cont ) - throw invalid_data( "bad UTF-8 continuation byte" ); - } - } - length++; - i++; - } - return length; - } - - void UTFString::_init() - { - mBuffer.mVoidBuffer = 0; - mBufferType = bt_none; - mBufferSize = 0; - } - - void UTFString::_cleanBuffer() const - { - if ( mBuffer.mVoidBuffer != 0 ) { - switch ( mBufferType ) { - case bt_string: - delete mBuffer.mStrBuffer; - break; - case bt_wstring: - delete mBuffer.mWStrBuffer; - break; - case bt_utf32string: - delete mBuffer.mUTF32StrBuffer; - break; - case bt_none: // under the worse of circumstances, this is all we can do, and hope it works out - default: - //delete mBuffer.mVoidBuffer; - // delete void* is undefined, don't do that - assert("This should never happen - mVoidBuffer should never contain something if we " - "don't know the type"); - break; - } - mBuffer.mVoidBuffer = 0; - mBufferSize = 0; - mBufferType = bt_none; - } - } - - void UTFString::_getBufferStr() const - { - if ( mBufferType != bt_string ) { - _cleanBuffer(); - mBuffer.mStrBuffer = new std::string(); - mBufferType = bt_string; - } - mBuffer.mStrBuffer->clear(); - } - - void UTFString::_getBufferWStr() const - { - if ( mBufferType != bt_wstring ) { - _cleanBuffer(); - mBuffer.mWStrBuffer = new std::wstring(); - mBufferType = bt_wstring; - } - mBuffer.mWStrBuffer->clear(); - } - - void UTFString::_getBufferUTF32Str() const - { - if ( mBufferType != bt_utf32string ) { - _cleanBuffer(); - mBuffer.mUTF32StrBuffer = new utf32string(); - mBufferType = bt_utf32string; - } - mBuffer.mUTF32StrBuffer->clear(); - } - - void UTFString::_load_buffer_UTF8() const - { - _getBufferStr(); - std::string& buffer = ( *mBuffer.mStrBuffer ); - buffer.reserve( length() ); - - unsigned char utf8buf[6] = ""; - char* charbuf = ( char* )utf8buf; - unicode_char c; - size_t len; - - const_iterator i, ie = end(); - for ( i = begin(); i != ie; i.moveNext() ) { - c = i.getCharacter(); - len = _utf32_to_utf8( c, utf8buf ); - size_t j = 0; - while ( j < len ) - buffer.push_back( charbuf[j++] ); - } - } - - void UTFString::_load_buffer_WStr() const - { - _getBufferWStr(); - std::wstring& buffer = ( *mBuffer.mWStrBuffer ); - buffer.reserve( length() ); // may over reserve, but should be close enough + bool UTFString::_utf16_independent_char( code_point cp ) + { + if ( 0xD800 <= cp && cp <= 0xDFFF ) // tests if the cp is within the surrogate pair range + return false; // it matches a surrogate pair signature + return true; // everything else is a standalone code point + } + + bool UTFString::_utf16_surrogate_lead( code_point cp ) + { + if ( 0xD800 <= cp && cp <= 0xDBFF ) // tests if the cp is within the 2nd word of a surrogate pair + return true; // it is a 1st word + return false; // it isn't + } + + bool UTFString::_utf16_surrogate_follow( code_point cp ) + { + if ( 0xDC00 <= cp && cp <= 0xDFFF ) // tests if the cp is within the 2nd word of a surrogate pair + return true; // it is a 2nd word + return false; // everything else isn't + } + + size_t UTFString::_utf16_char_length( code_point cp ) + { + if ( 0xD800 <= cp && cp <= 0xDBFF ) // test if cp is the beginning of a surrogate pair + return 2; // if it is, then we are 2 words long + return 1; // otherwise we are only 1 word long + } + + size_t UTFString::_utf16_char_length( unicode_char uc ) + { + if ( uc > 0xFFFF ) // test if uc is greater than the single word maximum + return 2; // if so, we need a surrogate pair + return 1; // otherwise we can stuff it into a single word + } + + size_t UTFString::_utf16_to_utf32( const code_point in_cp[2], unicode_char& out_uc ) + { + const code_point& cp1 = in_cp[0]; + const code_point& cp2 = in_cp[1]; + bool wordPair = false; + + // does it look like a surrogate pair? + if ( 0xD800 <= cp1 && cp1 <= 0xDBFF ) { + // looks like one, but does the other half match the algorithm as well? + if ( 0xDC00 <= cp2 && cp2 <= 0xDFFF ) + wordPair = true; // yep! + } + + if ( !wordPair ) { // if we aren't a 100% authentic surrogate pair, then just copy the value + out_uc = cp1; + return 1; + } + + unsigned short cU = cp1, cL = cp2; // copy upper and lower words of surrogate pair to writable buffers + cU -= 0xD800; // remove the encoding markers + cL -= 0xDC00; + + out_uc = ( cU & 0x03FF ) << 10; // grab the 10 upper bits and set them in their proper location + out_uc |= ( cL & 0x03FF ); // combine in the lower 10 bits + out_uc += 0x10000; // add back in the value offset + + return 2; // this whole operation takes to words, so that's what we'll return + } + + size_t UTFString::_utf32_to_utf16( const unicode_char& in_uc, code_point out_cp[2] ) + { + if ( in_uc <= 0xFFFF ) { // we blindly preserve sentinel values because our decoder understands them + out_cp[0] = static_cast(in_uc); + return 1; + } + unicode_char uc = in_uc; // copy to writable buffer + unsigned short tmp; // single code point buffer + uc -= 0x10000; // subtract value offset + + //process upper word + tmp = static_cast(( uc >> 10 ) & 0x03FF); // grab the upper 10 bits + tmp += 0xD800; // add encoding offset + out_cp[0] = tmp; // write + + // process lower word + tmp = static_cast(uc & 0x03FF); // grab the lower 10 bits + tmp += 0xDC00; // add encoding offset + out_cp[1] = tmp; // write + + return 2; // return used word count (2 for surrogate pairs) + } + + bool UTFString::_utf8_start_char( unsigned char cp ) + { + return ( cp & ~_cont_mask ) != _cont; + } + + size_t UTFString::_utf8_char_length( unsigned char cp ) + { + if ( !( cp & 0x80 ) ) return 1; + if (( cp & ~_lead1_mask ) == _lead1 ) return 2; + if (( cp & ~_lead2_mask ) == _lead2 ) return 3; + if (( cp & ~_lead3_mask ) == _lead3 ) return 4; + if (( cp & ~_lead4_mask ) == _lead4 ) return 5; + if (( cp & ~_lead5_mask ) == _lead5 ) return 6; + throw invalid_data( "invalid UTF-8 sequence header value" ); + } + + size_t UTFString::_utf8_char_length( unicode_char uc ) + { + /* + 7 bit: U-00000000 - U-0000007F: 0xxxxxxx + 11 bit: U-00000080 - U-000007FF: 110xxxxx 10xxxxxx + 16 bit: U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + 21 bit: U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + 26 bit: U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + 31 bit: U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + */ + if ( !( uc & ~0x0000007F ) ) return 1; + if ( !( uc & ~0x000007FF ) ) return 2; + if ( !( uc & ~0x0000FFFF ) ) return 3; + if ( !( uc & ~0x001FFFFF ) ) return 4; + if ( !( uc & ~0x03FFFFFF ) ) return 5; + if ( !( uc & ~0x7FFFFFFF ) ) return 6; + throw invalid_data( "invalid UTF-32 value" ); + } + + size_t UTFString::_utf8_to_utf32( const unsigned char in_cp[6], unicode_char& out_uc ) + { + size_t len = _utf8_char_length( in_cp[0] ); + if ( len == 1 ) { // if we are only 1 byte long, then just grab it and exit + out_uc = in_cp[0]; + return 1; + } + + unicode_char c = 0; // temporary buffer + size_t i = 0; + switch ( len ) { // load header byte + case 6: + c = in_cp[i] & _lead5_mask; + break; + case 5: + c = in_cp[i] & _lead4_mask; + break; + case 4: + c = in_cp[i] & _lead3_mask; + break; + case 3: + c = in_cp[i] & _lead2_mask; + break; + case 2: + c = in_cp[i] & _lead1_mask; + break; + } + + for ( ++i; i < len; i++ ) { // load each continuation byte + if (( in_cp[i] & ~_cont_mask ) != _cont ) + throw invalid_data( "bad UTF-8 continuation byte" ); + c <<= 6; + c |= ( in_cp[i] & _cont_mask ); + } + + out_uc = c; // write the final value and return the used byte length + return len; + } + + size_t UTFString::_utf32_to_utf8( const unicode_char& in_uc, unsigned char out_cp[6] ) + { + size_t len = _utf8_char_length( in_uc ); // predict byte length of sequence + unicode_char c = in_uc; // copy to temp buffer + + //stuff all of the lower bits + for ( size_t i = len - 1; i > 0; i-- ) { + out_cp[i] = static_cast((( c ) & _cont_mask ) | _cont); + c >>= 6; + } + + //now write the header byte + switch ( len ) { + case 6: + out_cp[0] = static_cast((( c ) & _lead5_mask ) | _lead5); + break; + case 5: + out_cp[0] = static_cast((( c ) & _lead4_mask ) | _lead4); + break; + case 4: + out_cp[0] = static_cast((( c ) & _lead3_mask ) | _lead3); + break; + case 3: + out_cp[0] = static_cast((( c ) & _lead2_mask ) | _lead2); + break; + case 2: + out_cp[0] = static_cast((( c ) & _lead1_mask ) | _lead1); + break; + case 1: + default: + out_cp[0] = static_cast(( c ) & 0x7F); + break; + } + + // return the byte length of the sequence + return len; + } + + Ogre::UTFString::size_type UTFString::_verifyUTF8( const unsigned char* c_str ) + { + std::string tmp( reinterpret_cast( c_str ) ); + return _verifyUTF8( tmp ); + } + + Ogre::UTFString::size_type UTFString::_verifyUTF8( const std::string& str ) + { + std::string::const_iterator i, ie = str.end(); + i = str.begin(); + size_type length = 0; + + while ( i != ie ) { + // characters pass until we find an extended sequence + if (( *i ) & 0x80 ) { + unsigned char c = ( *i ); + size_t contBytes = 0; + + // get continuation byte count and test for overlong sequences + if (( c & ~_lead1_mask ) == _lead1 ) { // 1 additional byte + if ( c == _lead1 ) throw invalid_data( "overlong UTF-8 sequence" ); + contBytes = 1; + + } else if (( c & ~_lead2_mask ) == _lead2 ) { // 2 additional bytes + contBytes = 2; + if ( c == _lead2 ) { // possible overlong UTF-8 sequence + c = ( *( i + 1 ) ); // look ahead to next byte in sequence + if (( c & _lead2 ) == _cont ) throw invalid_data( "overlong UTF-8 sequence" ); + } + + } else if (( c & ~_lead3_mask ) == _lead3 ) { // 3 additional bytes + contBytes = 3; + if ( c == _lead3 ) { // possible overlong UTF-8 sequence + c = ( *( i + 1 ) ); // look ahead to next byte in sequence + if (( c & _lead3 ) == _cont ) throw invalid_data( "overlong UTF-8 sequence" ); + } + + } else if (( c & ~_lead4_mask ) == _lead4 ) { // 4 additional bytes + contBytes = 4; + if ( c == _lead4 ) { // possible overlong UTF-8 sequence + c = ( *( i + 1 ) ); // look ahead to next byte in sequence + if (( c & _lead4 ) == _cont ) throw invalid_data( "overlong UTF-8 sequence" ); + } + + } else if (( c & ~_lead5_mask ) == _lead5 ) { // 5 additional bytes + contBytes = 5; + if ( c == _lead5 ) { // possible overlong UTF-8 sequence + c = ( *( i + 1 ) ); // look ahead to next byte in sequence + if (( c & _lead5 ) == _cont ) throw invalid_data( "overlong UTF-8 sequence" ); + } + } + + // check remaining continuation bytes for + while ( contBytes-- ) { + c = ( *( ++i ) ); // get next byte in sequence + if (( c & ~_cont_mask ) != _cont ) + throw invalid_data( "bad UTF-8 continuation byte" ); + } + } + length++; + i++; + } + return length; + } + + void UTFString::_init() + { + mBuffer.mVoidBuffer = 0; + mBufferType = bt_none; + mBufferSize = 0; + } + + void UTFString::_cleanBuffer() const + { + if ( mBuffer.mVoidBuffer != 0 ) { + switch ( mBufferType ) { + case bt_string: + delete mBuffer.mStrBuffer; + break; + case bt_wstring: + delete mBuffer.mWStrBuffer; + break; + case bt_utf32string: + delete mBuffer.mUTF32StrBuffer; + break; + case bt_none: // under the worse of circumstances, this is all we can do, and hope it works out + default: + //delete mBuffer.mVoidBuffer; + // delete void* is undefined, don't do that + assert("This should never happen - mVoidBuffer should never contain something if we " + "don't know the type"); + break; + } + mBuffer.mVoidBuffer = 0; + mBufferSize = 0; + mBufferType = bt_none; + } + } + + void UTFString::_getBufferStr() const + { + if ( mBufferType != bt_string ) { + _cleanBuffer(); + mBuffer.mStrBuffer = new std::string(); + mBufferType = bt_string; + } + mBuffer.mStrBuffer->clear(); + } + + void UTFString::_getBufferWStr() const + { + if ( mBufferType != bt_wstring ) { + _cleanBuffer(); + mBuffer.mWStrBuffer = new std::wstring(); + mBufferType = bt_wstring; + } + mBuffer.mWStrBuffer->clear(); + } + + void UTFString::_getBufferUTF32Str() const + { + if ( mBufferType != bt_utf32string ) { + _cleanBuffer(); + mBuffer.mUTF32StrBuffer = new utf32string(); + mBufferType = bt_utf32string; + } + mBuffer.mUTF32StrBuffer->clear(); + } + + void UTFString::_load_buffer_UTF8() const + { + _getBufferStr(); + std::string& buffer = ( *mBuffer.mStrBuffer ); + buffer.reserve( length() ); + + unsigned char utf8buf[6] = ""; + char* charbuf = ( char* )utf8buf; + unicode_char c; + size_t len; + + const_iterator i, ie = end(); + for ( i = begin(); i != ie; i.moveNext() ) { + c = i.getCharacter(); + len = _utf32_to_utf8( c, utf8buf ); + size_t j = 0; + while ( j < len ) + buffer.push_back( charbuf[j++] ); + } + } + + void UTFString::_load_buffer_WStr() const + { + _getBufferWStr(); + std::wstring& buffer = ( *mBuffer.mWStrBuffer ); + buffer.reserve( length() ); // may over reserve, but should be close enough #ifdef WCHAR_UTF16 // wchar_t matches UTF-16 - const_iterator i, ie = end(); - for ( i = begin(); i != ie; ++i ) { - buffer.push_back(( wchar_t )( *i ) ); - } + const_iterator i, ie = end(); + for ( i = begin(); i != ie; ++i ) { + buffer.push_back(( wchar_t )( *i ) ); + } #else // wchar_t fits UTF-32 - unicode_char c; - const_iterator i, ie = end(); - for ( i = begin(); i != ie; i.moveNext() ) { - c = i.getCharacter(); - buffer.push_back(( wchar_t )c ); - } + unicode_char c; + const_iterator i, ie = end(); + for ( i = begin(); i != ie; i.moveNext() ) { + c = i.getCharacter(); + buffer.push_back(( wchar_t )c ); + } #endif - } - - void UTFString::_load_buffer_UTF32() const - { - _getBufferUTF32Str(); - utf32string& buffer = ( *mBuffer.mUTF32StrBuffer ); - buffer.reserve( length() ); // may over reserve, but should be close enough - - unicode_char c; - - const_iterator i, ie = end(); - for ( i = begin(); i != ie; i.moveNext() ) { - c = i.getCharacter(); - buffer.push_back( c ); - } - } + } + + void UTFString::_load_buffer_UTF32() const + { + _getBufferUTF32Str(); + utf32string& buffer = ( *mBuffer.mUTF32StrBuffer ); + buffer.reserve( length() ); // may over reserve, but should be close enough + + unicode_char c; + + const_iterator i, ie = end(); + for ( i = begin(); i != ie; i.moveNext() ) { + c = i.getCharacter(); + buffer.push_back( c ); + } + } } diff --git a/OgreMain/src/OgreUnifiedHighLevelGpuProgram.cpp b/OgreMain/src/OgreUnifiedHighLevelGpuProgram.cpp index cc84fe9a572..33a5900737e 100644 --- a/OgreMain/src/OgreUnifiedHighLevelGpuProgram.cpp +++ b/OgreMain/src/OgreUnifiedHighLevelGpuProgram.cpp @@ -32,109 +32,109 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - UnifiedHighLevelGpuProgram::CmdDelegate UnifiedHighLevelGpuProgram::msCmdDelegate; + //----------------------------------------------------------------------- + UnifiedHighLevelGpuProgram::CmdDelegate UnifiedHighLevelGpuProgram::msCmdDelegate; static const String sLanguage = "unified"; - std::map UnifiedHighLevelGpuProgram::mLanguagePriorities; + std::map UnifiedHighLevelGpuProgram::mLanguagePriorities; - int UnifiedHighLevelGpuProgram::getPriority(String shaderLanguage) - { - std::map::iterator it = mLanguagePriorities.find(shaderLanguage); - if (it == mLanguagePriorities.end()) - return -1; - else - return (*it).second; - } + int UnifiedHighLevelGpuProgram::getPriority(String shaderLanguage) + { + std::map::iterator it = mLanguagePriorities.find(shaderLanguage); + if (it == mLanguagePriorities.end()) + return -1; + else + return (*it).second; + } - void UnifiedHighLevelGpuProgram::setPrioriry(String shaderLanguage,int priority) - { - mLanguagePriorities[shaderLanguage] = priority; - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - UnifiedHighLevelGpuProgram::UnifiedHighLevelGpuProgram( - ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader) - :HighLevelGpuProgram(creator, name, handle, group, isManual, loader) - { - if (createParamDictionary("UnifiedHighLevelGpuProgram")) - { - setupBaseParamDictionary(); + void UnifiedHighLevelGpuProgram::setPrioriry(String shaderLanguage,int priority) + { + mLanguagePriorities[shaderLanguage] = priority; + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + UnifiedHighLevelGpuProgram::UnifiedHighLevelGpuProgram( + ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader) + :HighLevelGpuProgram(creator, name, handle, group, isManual, loader) + { + if (createParamDictionary("UnifiedHighLevelGpuProgram")) + { + setupBaseParamDictionary(); - ParamDictionary* dict = getParamDictionary(); + ParamDictionary* dict = getParamDictionary(); - dict->addParameter(ParameterDef("delegate", - "Additional delegate programs containing implementations.", - PT_STRING),&msCmdDelegate); - } + dict->addParameter(ParameterDef("delegate", + "Additional delegate programs containing implementations.", + PT_STRING),&msCmdDelegate); + } - } - //----------------------------------------------------------------------- - UnifiedHighLevelGpuProgram::~UnifiedHighLevelGpuProgram() - { + } + //----------------------------------------------------------------------- + UnifiedHighLevelGpuProgram::~UnifiedHighLevelGpuProgram() + { - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::chooseDelegate() const - { + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::chooseDelegate() const + { OGRE_LOCK_AUTO_MUTEX; - mChosenDelegate.setNull(); + mChosenDelegate.setNull(); - HighLevelGpuProgramPtr tmpDelegate; - tmpDelegate.setNull(); - int tmpPriority = -1; + HighLevelGpuProgramPtr tmpDelegate; + tmpDelegate.setNull(); + int tmpPriority = -1; - for (StringVector::const_iterator i = mDelegateNames.begin(); i != mDelegateNames.end(); ++i) - { - HighLevelGpuProgramPtr deleg = - HighLevelGpuProgramManager::getSingleton().getByName(*i); + for (StringVector::const_iterator i = mDelegateNames.begin(); i != mDelegateNames.end(); ++i) + { + HighLevelGpuProgramPtr deleg = + HighLevelGpuProgramManager::getSingleton().getByName(*i); - // Silently ignore missing links - if(!deleg.isNull() && deleg->isSupported()) - { - int priority = getPriority(deleg->getLanguage()); - //Find the delegate with the highest prioriry - if (priority >= tmpPriority) - { - tmpDelegate = deleg; - tmpPriority = priority; - } - } + // Silently ignore missing links + if(!deleg.isNull() && deleg->isSupported()) + { + int priority = getPriority(deleg->getLanguage()); + //Find the delegate with the highest prioriry + if (priority >= tmpPriority) + { + tmpDelegate = deleg; + tmpPriority = priority; + } + } - } + } - mChosenDelegate = tmpDelegate; - } - //----------------------------------------------------------------------- - const HighLevelGpuProgramPtr& UnifiedHighLevelGpuProgram::_getDelegate() const - { - if (mChosenDelegate.isNull()) - { - chooseDelegate(); - } - return mChosenDelegate; - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::addDelegateProgram(const String& name) - { + mChosenDelegate = tmpDelegate; + } + //----------------------------------------------------------------------- + const HighLevelGpuProgramPtr& UnifiedHighLevelGpuProgram::_getDelegate() const + { + if (mChosenDelegate.isNull()) + { + chooseDelegate(); + } + return mChosenDelegate; + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::addDelegateProgram(const String& name) + { OGRE_LOCK_AUTO_MUTEX; - mDelegateNames.push_back(name); + mDelegateNames.push_back(name); - // reset chosen delegate - mChosenDelegate.setNull(); + // reset chosen delegate + mChosenDelegate.setNull(); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::clearDelegatePrograms() - { + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::clearDelegatePrograms() + { OGRE_LOCK_AUTO_MUTEX; - mDelegateNames.clear(); - mChosenDelegate.setNull(); + mDelegateNames.clear(); + mChosenDelegate.setNull(); - } + } //----------------------------------------------------------------------------- size_t UnifiedHighLevelGpuProgram::calculateSize(void) const { @@ -143,7 +143,7 @@ namespace Ogre memSize += HighLevelGpuProgram::calculateSize(); // Delegate Names - for (StringVector::const_iterator i = mDelegateNames.begin(); i != mDelegateNames.end(); ++i) + for (StringVector::const_iterator i = mDelegateNames.begin(); i != mDelegateNames.end(); ++i) memSize += (*i).size() * sizeof(char); return memSize; @@ -153,290 +153,290 @@ namespace Ogre { return sLanguage; } - //----------------------------------------------------------------------- - GpuProgramParametersSharedPtr UnifiedHighLevelGpuProgram::createParameters(void) - { - if (isSupported()) - { - return _getDelegate()->createParameters(); - } - else - { - // return a default set - GpuProgramParametersSharedPtr params = GpuProgramManager::getSingleton().createParameters(); - // avoid any errors on parameter names that don't exist - params->setIgnoreMissingParams(true); - return params; - } - } - //----------------------------------------------------------------------- - GpuProgram* UnifiedHighLevelGpuProgram::_getBindingDelegate(void) - { - if (!_getDelegate().isNull()) - return _getDelegate()->_getBindingDelegate(); - else - return 0; - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::isSupported(void) const - { - // Supported if one of the delegates is - return !(_getDelegate().isNull()); - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::isSkeletalAnimationIncluded(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->isSkeletalAnimationIncluded(); - else - return false; - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::isMorphAnimationIncluded(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->isMorphAnimationIncluded(); - else - return false; - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::isPoseAnimationIncluded(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->isPoseAnimationIncluded(); - else - return false; - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::isVertexTextureFetchRequired(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->isVertexTextureFetchRequired(); - else - return false; - } - //----------------------------------------------------------------------- - GpuProgramParametersSharedPtr UnifiedHighLevelGpuProgram::getDefaultParameters(void) - { - if (!_getDelegate().isNull()) - return _getDelegate()->getDefaultParameters(); - else - return GpuProgramParametersSharedPtr(); - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::hasDefaultParameters(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->hasDefaultParameters(); - else - return false; - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::getPassSurfaceAndLightStates(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->getPassSurfaceAndLightStates(); - else - return HighLevelGpuProgram::getPassSurfaceAndLightStates(); - } - //--------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::getPassFogStates(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->getPassFogStates(); - else - return HighLevelGpuProgram::getPassFogStates(); - } - //--------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::getPassTransformStates(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->getPassTransformStates(); - else - return HighLevelGpuProgram::getPassTransformStates(); + //----------------------------------------------------------------------- + GpuProgramParametersSharedPtr UnifiedHighLevelGpuProgram::createParameters(void) + { + if (isSupported()) + { + return _getDelegate()->createParameters(); + } + else + { + // return a default set + GpuProgramParametersSharedPtr params = GpuProgramManager::getSingleton().createParameters(); + // avoid any errors on parameter names that don't exist + params->setIgnoreMissingParams(true); + return params; + } + } + //----------------------------------------------------------------------- + GpuProgram* UnifiedHighLevelGpuProgram::_getBindingDelegate(void) + { + if (!_getDelegate().isNull()) + return _getDelegate()->_getBindingDelegate(); + else + return 0; + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::isSupported(void) const + { + // Supported if one of the delegates is + return !(_getDelegate().isNull()); + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::isSkeletalAnimationIncluded(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->isSkeletalAnimationIncluded(); + else + return false; + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::isMorphAnimationIncluded(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->isMorphAnimationIncluded(); + else + return false; + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::isPoseAnimationIncluded(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->isPoseAnimationIncluded(); + else + return false; + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::isVertexTextureFetchRequired(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->isVertexTextureFetchRequired(); + else + return false; + } + //----------------------------------------------------------------------- + GpuProgramParametersSharedPtr UnifiedHighLevelGpuProgram::getDefaultParameters(void) + { + if (!_getDelegate().isNull()) + return _getDelegate()->getDefaultParameters(); + else + return GpuProgramParametersSharedPtr(); + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::hasDefaultParameters(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->hasDefaultParameters(); + else + return false; + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::getPassSurfaceAndLightStates(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->getPassSurfaceAndLightStates(); + else + return HighLevelGpuProgram::getPassSurfaceAndLightStates(); + } + //--------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::getPassFogStates(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->getPassFogStates(); + else + return HighLevelGpuProgram::getPassFogStates(); + } + //--------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::getPassTransformStates(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->getPassTransformStates(); + else + return HighLevelGpuProgram::getPassTransformStates(); - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::hasCompileError(void) const - { - if (_getDelegate().isNull()) - { - return false; - } - else - { - return _getDelegate()->hasCompileError(); - } - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::resetCompileError(void) - { - if (!_getDelegate().isNull()) - _getDelegate()->resetCompileError(); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::load(bool backgroundThread) - { - if (!_getDelegate().isNull()) - _getDelegate()->load(backgroundThread); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::reload(void) - { - if (!_getDelegate().isNull()) - _getDelegate()->reload(); - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::isReloadable(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->isReloadable(); - else - return true; - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::unload(void) - { - if (!_getDelegate().isNull()) - _getDelegate()->unload(); - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::isLoaded(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->isLoaded(); - else - return false; - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::isLoading() const - { - if (!_getDelegate().isNull()) - return _getDelegate()->isLoading(); - else - return false; - } - //----------------------------------------------------------------------- - Resource::LoadingState UnifiedHighLevelGpuProgram::getLoadingState() const - { - if (!_getDelegate().isNull()) - return _getDelegate()->getLoadingState(); - else - return Resource::LOADSTATE_UNLOADED; - } - //----------------------------------------------------------------------- - size_t UnifiedHighLevelGpuProgram::getSize(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->getSize(); - else - return 0; - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::touch(void) - { - if (!_getDelegate().isNull()) - _getDelegate()->touch(); - } - //----------------------------------------------------------------------- - bool UnifiedHighLevelGpuProgram::isBackgroundLoaded(void) const - { - if (!_getDelegate().isNull()) - return _getDelegate()->isBackgroundLoaded(); - else - return false; - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::setBackgroundLoaded(bool bl) - { - if (!_getDelegate().isNull()) - _getDelegate()->setBackgroundLoaded(bl); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::escalateLoading() - { - if (!_getDelegate().isNull()) - _getDelegate()->escalateLoading(); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::addListener(Resource::Listener* lis) - { - if (!_getDelegate().isNull()) - _getDelegate()->addListener(lis); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::removeListener(Resource::Listener* lis) - { - if (!_getDelegate().isNull()) - _getDelegate()->removeListener(lis); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::createLowLevelImpl(void) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This method should never get called!", - "UnifiedHighLevelGpuProgram::createLowLevelImpl"); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::unloadHighLevelImpl(void) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This method should never get called!", - "UnifiedHighLevelGpuProgram::unloadHighLevelImpl"); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::buildConstantDefinitions() const - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This method should never get called!", - "UnifiedHighLevelGpuProgram::buildConstantDefinitions"); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::loadFromSource(void) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "This method should never get called!", - "UnifiedHighLevelGpuProgram::loadFromSource"); - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - String UnifiedHighLevelGpuProgram::CmdDelegate::doGet(const void* target) const - { - // Can't do this (not one delegate), shouldn't matter - return BLANKSTRING; - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgram::CmdDelegate::doSet(void* target, const String& val) - { - static_cast(target)->addDelegateProgram(val); - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - UnifiedHighLevelGpuProgramFactory::UnifiedHighLevelGpuProgramFactory() - { - } - //----------------------------------------------------------------------- - UnifiedHighLevelGpuProgramFactory::~UnifiedHighLevelGpuProgramFactory() - { - } - //----------------------------------------------------------------------- - const String& UnifiedHighLevelGpuProgramFactory::getLanguage(void) const - { - return sLanguage; - } - //----------------------------------------------------------------------- - HighLevelGpuProgram* UnifiedHighLevelGpuProgramFactory::create(ResourceManager* creator, - const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader) - { - return OGRE_NEW UnifiedHighLevelGpuProgram(creator, name, handle, group, isManual, loader); - } - //----------------------------------------------------------------------- - void UnifiedHighLevelGpuProgramFactory::destroy(HighLevelGpuProgram* prog) - { - OGRE_DELETE prog; - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::hasCompileError(void) const + { + if (_getDelegate().isNull()) + { + return false; + } + else + { + return _getDelegate()->hasCompileError(); + } + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::resetCompileError(void) + { + if (!_getDelegate().isNull()) + _getDelegate()->resetCompileError(); + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::load(bool backgroundThread) + { + if (!_getDelegate().isNull()) + _getDelegate()->load(backgroundThread); + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::reload(void) + { + if (!_getDelegate().isNull()) + _getDelegate()->reload(); + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::isReloadable(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->isReloadable(); + else + return true; + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::unload(void) + { + if (!_getDelegate().isNull()) + _getDelegate()->unload(); + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::isLoaded(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->isLoaded(); + else + return false; + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::isLoading() const + { + if (!_getDelegate().isNull()) + return _getDelegate()->isLoading(); + else + return false; + } + //----------------------------------------------------------------------- + Resource::LoadingState UnifiedHighLevelGpuProgram::getLoadingState() const + { + if (!_getDelegate().isNull()) + return _getDelegate()->getLoadingState(); + else + return Resource::LOADSTATE_UNLOADED; + } + //----------------------------------------------------------------------- + size_t UnifiedHighLevelGpuProgram::getSize(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->getSize(); + else + return 0; + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::touch(void) + { + if (!_getDelegate().isNull()) + _getDelegate()->touch(); + } + //----------------------------------------------------------------------- + bool UnifiedHighLevelGpuProgram::isBackgroundLoaded(void) const + { + if (!_getDelegate().isNull()) + return _getDelegate()->isBackgroundLoaded(); + else + return false; + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::setBackgroundLoaded(bool bl) + { + if (!_getDelegate().isNull()) + _getDelegate()->setBackgroundLoaded(bl); + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::escalateLoading() + { + if (!_getDelegate().isNull()) + _getDelegate()->escalateLoading(); + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::addListener(Resource::Listener* lis) + { + if (!_getDelegate().isNull()) + _getDelegate()->addListener(lis); + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::removeListener(Resource::Listener* lis) + { + if (!_getDelegate().isNull()) + _getDelegate()->removeListener(lis); + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::createLowLevelImpl(void) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This method should never get called!", + "UnifiedHighLevelGpuProgram::createLowLevelImpl"); + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::unloadHighLevelImpl(void) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This method should never get called!", + "UnifiedHighLevelGpuProgram::unloadHighLevelImpl"); + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::buildConstantDefinitions() const + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This method should never get called!", + "UnifiedHighLevelGpuProgram::buildConstantDefinitions"); + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::loadFromSource(void) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "This method should never get called!", + "UnifiedHighLevelGpuProgram::loadFromSource"); + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + String UnifiedHighLevelGpuProgram::CmdDelegate::doGet(const void* target) const + { + // Can't do this (not one delegate), shouldn't matter + return BLANKSTRING; + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgram::CmdDelegate::doSet(void* target, const String& val) + { + static_cast(target)->addDelegateProgram(val); + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + UnifiedHighLevelGpuProgramFactory::UnifiedHighLevelGpuProgramFactory() + { + } + //----------------------------------------------------------------------- + UnifiedHighLevelGpuProgramFactory::~UnifiedHighLevelGpuProgramFactory() + { + } + //----------------------------------------------------------------------- + const String& UnifiedHighLevelGpuProgramFactory::getLanguage(void) const + { + return sLanguage; + } + //----------------------------------------------------------------------- + HighLevelGpuProgram* UnifiedHighLevelGpuProgramFactory::create(ResourceManager* creator, + const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader) + { + return OGRE_NEW UnifiedHighLevelGpuProgram(creator, name, handle, group, isManual, loader); + } + //----------------------------------------------------------------------- + void UnifiedHighLevelGpuProgramFactory::destroy(HighLevelGpuProgram* prog) + { + OGRE_DELETE prog; + } + //----------------------------------------------------------------------- } diff --git a/OgreMain/src/OgreUserObjectBindings.cpp b/OgreMain/src/OgreUserObjectBindings.cpp index 24c23cc6bc9..9b5abce2b39 100644 --- a/OgreMain/src/OgreUserObjectBindings.cpp +++ b/OgreMain/src/OgreUserObjectBindings.cpp @@ -30,99 +30,99 @@ THE SOFTWARE. namespace Ogre { - Any UserObjectBindings::msEmptyAny; - - //-------------------------------------------------------------------------- - UserObjectBindings::UserObjectBindings() - { - mAttributes = NULL; - } - - //-------------------------------------------------------------------------- - UserObjectBindings::~UserObjectBindings() - { - clear(); - } - - //----------------------------------------------------------------------- - void UserObjectBindings::setUserAny( const Any& anything ) - { - // Allocate attributes on demand. - if (mAttributes == NULL) - mAttributes = OGRE_NEW UserObjectBindings::Attributes; - - mAttributes->mKeylessAny = anything; - } - - //----------------------------------------------------------------------- - const Any& UserObjectBindings::getUserAny( void ) const - { - // Allocate attributes on demand. - if (mAttributes == NULL) - mAttributes = OGRE_NEW UserObjectBindings::Attributes; - - return mAttributes->mKeylessAny; - } - - //----------------------------------------------------------------------- - void UserObjectBindings::setUserAny(const String& key, const Any& anything) - { - // Allocate attributes on demand. - if (mAttributes == NULL) - mAttributes = OGRE_NEW UserObjectBindings::Attributes; - - // Case map doesn't exists. - if (mAttributes->mUserObjectsMap == NULL) - mAttributes->mUserObjectsMap = new UserObjectsMap; - - (*mAttributes->mUserObjectsMap)[key] = anything; - } - - //----------------------------------------------------------------------- - const Any& UserObjectBindings::getUserAny(const String& key) const - { - // Allocate attributes on demand. - if (mAttributes == NULL) - mAttributes = OGRE_NEW UserObjectBindings::Attributes; - - // Case map doesn't exists. - if (mAttributes->mUserObjectsMap == NULL) - return msEmptyAny; - - UserObjectsMapConstIterator it = mAttributes->mUserObjectsMap->find(key); - - // Case user data found. - if (it != mAttributes->mUserObjectsMap->end()) - { - return it->second; - } - - return msEmptyAny; - } - - //----------------------------------------------------------------------- - void UserObjectBindings::eraseUserAny(const String& key) - { - // Case attributes and map allocated. - if (mAttributes != NULL && mAttributes->mUserObjectsMap != NULL) - { - UserObjectsMapIterator it = mAttributes->mUserObjectsMap->find(key); - - // Case object found -> erase it from the map. - if (it != mAttributes->mUserObjectsMap->end()) - { - mAttributes->mUserObjectsMap->erase(it); - } - } - } - - //----------------------------------------------------------------------- - void UserObjectBindings::clear() const - { - if (mAttributes != NULL) - { - OGRE_DELETE mAttributes; - mAttributes = NULL; - } - } + Any UserObjectBindings::msEmptyAny; + + //-------------------------------------------------------------------------- + UserObjectBindings::UserObjectBindings() + { + mAttributes = NULL; + } + + //-------------------------------------------------------------------------- + UserObjectBindings::~UserObjectBindings() + { + clear(); + } + + //----------------------------------------------------------------------- + void UserObjectBindings::setUserAny( const Any& anything ) + { + // Allocate attributes on demand. + if (mAttributes == NULL) + mAttributes = OGRE_NEW UserObjectBindings::Attributes; + + mAttributes->mKeylessAny = anything; + } + + //----------------------------------------------------------------------- + const Any& UserObjectBindings::getUserAny( void ) const + { + // Allocate attributes on demand. + if (mAttributes == NULL) + mAttributes = OGRE_NEW UserObjectBindings::Attributes; + + return mAttributes->mKeylessAny; + } + + //----------------------------------------------------------------------- + void UserObjectBindings::setUserAny(const String& key, const Any& anything) + { + // Allocate attributes on demand. + if (mAttributes == NULL) + mAttributes = OGRE_NEW UserObjectBindings::Attributes; + + // Case map doesn't exists. + if (mAttributes->mUserObjectsMap == NULL) + mAttributes->mUserObjectsMap = new UserObjectsMap; + + (*mAttributes->mUserObjectsMap)[key] = anything; + } + + //----------------------------------------------------------------------- + const Any& UserObjectBindings::getUserAny(const String& key) const + { + // Allocate attributes on demand. + if (mAttributes == NULL) + mAttributes = OGRE_NEW UserObjectBindings::Attributes; + + // Case map doesn't exists. + if (mAttributes->mUserObjectsMap == NULL) + return msEmptyAny; + + UserObjectsMapConstIterator it = mAttributes->mUserObjectsMap->find(key); + + // Case user data found. + if (it != mAttributes->mUserObjectsMap->end()) + { + return it->second; + } + + return msEmptyAny; + } + + //----------------------------------------------------------------------- + void UserObjectBindings::eraseUserAny(const String& key) + { + // Case attributes and map allocated. + if (mAttributes != NULL && mAttributes->mUserObjectsMap != NULL) + { + UserObjectsMapIterator it = mAttributes->mUserObjectsMap->find(key); + + // Case object found -> erase it from the map. + if (it != mAttributes->mUserObjectsMap->end()) + { + mAttributes->mUserObjectsMap->erase(it); + } + } + } + + //----------------------------------------------------------------------- + void UserObjectBindings::clear() const + { + if (mAttributes != NULL) + { + OGRE_DELETE mAttributes; + mAttributes = NULL; + } + } } diff --git a/OgreMain/src/OgreVertexIndexData.cpp b/OgreMain/src/OgreVertexIndexData.cpp index 04c51ccae6b..5e6a219fe90 100644 --- a/OgreMain/src/OgreVertexIndexData.cpp +++ b/OgreMain/src/OgreVertexIndexData.cpp @@ -36,63 +36,63 @@ THE SOFTWARE. namespace Ogre { //----------------------------------------------------------------------- - VertexData::VertexData(HardwareBufferManagerBase* mgr) - { - mMgr = mgr ? mgr : HardwareBufferManager::getSingletonPtr(); - vertexBufferBinding = mMgr->createVertexBufferBinding(); - vertexDeclaration = mMgr->createVertexDeclaration(); - mDeleteDclBinding = true; - vertexCount = 0; - vertexStart = 0; - hwAnimDataItemsUsed = 0; - - } - //--------------------------------------------------------------------- - VertexData::VertexData(VertexDeclaration* dcl, VertexBufferBinding* bind) - { - // this is a fallback rather than actively used - mMgr = HardwareBufferManager::getSingletonPtr(); - vertexDeclaration = dcl; - vertexBufferBinding = bind; - mDeleteDclBinding = false; - vertexCount = 0; - vertexStart = 0; - hwAnimDataItemsUsed = 0; - } + VertexData::VertexData(HardwareBufferManagerBase* mgr) + { + mMgr = mgr ? mgr : HardwareBufferManager::getSingletonPtr(); + vertexBufferBinding = mMgr->createVertexBufferBinding(); + vertexDeclaration = mMgr->createVertexDeclaration(); + mDeleteDclBinding = true; + vertexCount = 0; + vertexStart = 0; + hwAnimDataItemsUsed = 0; + + } + //--------------------------------------------------------------------- + VertexData::VertexData(VertexDeclaration* dcl, VertexBufferBinding* bind) + { + // this is a fallback rather than actively used + mMgr = HardwareBufferManager::getSingletonPtr(); + vertexDeclaration = dcl; + vertexBufferBinding = bind; + mDeleteDclBinding = false; + vertexCount = 0; + vertexStart = 0; + hwAnimDataItemsUsed = 0; + } //----------------------------------------------------------------------- - VertexData::~VertexData() - { - if (mDeleteDclBinding) - { - mMgr->destroyVertexBufferBinding(vertexBufferBinding); - mMgr->destroyVertexDeclaration(vertexDeclaration); - } - } + VertexData::~VertexData() + { + if (mDeleteDclBinding) + { + mMgr->destroyVertexBufferBinding(vertexBufferBinding); + mMgr->destroyVertexDeclaration(vertexDeclaration); + } + } //----------------------------------------------------------------------- - VertexData* VertexData::clone(bool copyData, HardwareBufferManagerBase* mgr) const - { - HardwareBufferManagerBase* pManager = mgr ? mgr : mMgr; - - VertexData* dest = OGRE_NEW VertexData(mgr); - - // Copy vertex buffers in turn - const VertexBufferBinding::VertexBufferBindingMap& bindings = - this->vertexBufferBinding->getBindings(); - VertexBufferBinding::VertexBufferBindingMap::const_iterator vbi, vbend; - vbend = bindings.end(); - for (vbi = bindings.begin(); vbi != vbend; ++vbi) - { - HardwareVertexBufferSharedPtr srcbuf = vbi->second; + VertexData* VertexData::clone(bool copyData, HardwareBufferManagerBase* mgr) const + { + HardwareBufferManagerBase* pManager = mgr ? mgr : mMgr; + + VertexData* dest = OGRE_NEW VertexData(mgr); + + // Copy vertex buffers in turn + const VertexBufferBinding::VertexBufferBindingMap& bindings = + this->vertexBufferBinding->getBindings(); + VertexBufferBinding::VertexBufferBindingMap::const_iterator vbi, vbend; + vbend = bindings.end(); + for (vbi = bindings.begin(); vbi != vbend; ++vbi) + { + HardwareVertexBufferSharedPtr srcbuf = vbi->second; HardwareVertexBufferSharedPtr dstBuf; if (copyData) { - // create new buffer with the same settings - dstBuf = pManager->createVertexBuffer( - srcbuf->getVertexSize(), srcbuf->getNumVertices(), srcbuf->getUsage(), - srcbuf->hasShadowBuffer()); + // create new buffer with the same settings + dstBuf = pManager->createVertexBuffer( + srcbuf->getVertexSize(), srcbuf->getNumVertices(), srcbuf->getUsage(), + srcbuf->hasShadowBuffer()); - // copy data - dstBuf->copyData(*srcbuf, 0, 0, srcbuf->getSizeInBytes(), true); + // copy data + dstBuf->copyData(*srcbuf, 0, 0, srcbuf->getSizeInBytes(), true); } else { @@ -100,13 +100,13 @@ namespace Ogre { dstBuf = srcbuf; } - // Copy binding - dest->vertexBufferBinding->setBinding(vbi->first, dstBuf); + // Copy binding + dest->vertexBufferBinding->setBinding(vbi->first, dstBuf); } // Basic vertex info dest->vertexStart = this->vertexStart; - dest->vertexCount = this->vertexCount; + dest->vertexCount = this->vertexCount; // Copy elements const VertexDeclaration::VertexElementList elems = this->vertexDeclaration->getElements(); @@ -122,16 +122,16 @@ namespace Ogre { ei->getIndex() ); } - // Copy reference to hardware shadow buffer, no matter whether copy data or not + // Copy reference to hardware shadow buffer, no matter whether copy data or not dest->hardwareShadowVolWBuffer = hardwareShadowVolWBuffer; - // copy anim data - dest->hwAnimationDataList = hwAnimationDataList; - dest->hwAnimDataItemsUsed = hwAnimDataItemsUsed; + // copy anim data + dest->hwAnimationDataList = hwAnimationDataList; + dest->hwAnimDataItemsUsed = hwAnimDataItemsUsed; return dest; - } + } //----------------------------------------------------------------------- void VertexData::prepareForShadowVolume(void) { @@ -326,21 +326,21 @@ namespace Ogre { } } - //----------------------------------------------------------------------- - void VertexData::reorganiseBuffers(VertexDeclaration* newDeclaration, - const BufferUsageList& bufferUsages, HardwareBufferManagerBase* mgr) - { - HardwareBufferManagerBase* pManager = mgr ? mgr : mMgr; + //----------------------------------------------------------------------- + void VertexData::reorganiseBuffers(VertexDeclaration* newDeclaration, + const BufferUsageList& bufferUsages, HardwareBufferManagerBase* mgr) + { + HardwareBufferManagerBase* pManager = mgr ? mgr : mMgr; // Firstly, close up any gaps in the buffer sources which might have arisen newDeclaration->closeGapsInSource(); - // Build up a list of both old and new elements in each buffer - unsigned short buf = 0; - vector::type oldBufferLocks; + // Build up a list of both old and new elements in each buffer + unsigned short buf = 0; + vector::type oldBufferLocks; vector::type oldBufferVertexSizes; - vector::type newBufferLocks; + vector::type newBufferLocks; vector::type newBufferVertexSizes; - VertexBufferBinding* newBinding = pManager->createVertexBufferBinding(); + VertexBufferBinding* newBinding = pManager->createVertexBufferBinding(); const VertexBufferBinding::VertexBufferBindingMap& oldBindingMap = vertexBufferBinding->getBindings(); VertexBufferBinding::VertexBufferBindingMap::const_iterator itBinding; @@ -351,7 +351,7 @@ namespace Ogre { oldBufferLocks.resize(count); oldBufferVertexSizes.resize(count); } - // Lock all the old buffers for reading + // Lock all the old buffers for reading for (itBinding = oldBindingMap.begin(); itBinding != oldBindingMap.end(); ++itBinding) { assert(itBinding->second->getNumVertices() >= vertexCount); @@ -362,75 +362,75 @@ namespace Ogre { itBinding->second->lock( HardwareBuffer::HBL_READ_ONLY); } - - // Create new buffers and lock all for writing - buf = 0; - while (!newDeclaration->findElementsBySource(buf).empty()) - { + + // Create new buffers and lock all for writing + buf = 0; + while (!newDeclaration->findElementsBySource(buf).empty()) + { size_t vertexSize = newDeclaration->getVertexSize(buf); - HardwareVertexBufferSharedPtr vbuf = - pManager->createVertexBuffer( - vertexSize, - vertexCount, - bufferUsages[buf]); - newBinding->setBinding(buf, vbuf); + HardwareVertexBufferSharedPtr vbuf = + pManager->createVertexBuffer( + vertexSize, + vertexCount, + bufferUsages[buf]); + newBinding->setBinding(buf, vbuf); newBufferVertexSizes.push_back(vertexSize); - newBufferLocks.push_back( - vbuf->lock(HardwareBuffer::HBL_DISCARD)); - buf++; - } + newBufferLocks.push_back( + vbuf->lock(HardwareBuffer::HBL_DISCARD)); + buf++; + } - // Map from new to old elements + // Map from new to old elements typedef map::type NewToOldElementMap; - NewToOldElementMap newToOldElementMap; - const VertexDeclaration::VertexElementList& newElemList = newDeclaration->getElements(); - VertexDeclaration::VertexElementList::const_iterator ei, eiend; - eiend = newElemList.end(); - for (ei = newElemList.begin(); ei != eiend; ++ei) - { - // Find corresponding old element - const VertexElement* oldElem = - vertexDeclaration->findElementBySemantic( - (*ei).getSemantic(), (*ei).getIndex()); - if (!oldElem) - { - // Error, cannot create new elements with this method - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Element not found in old vertex declaration", - "VertexData::reorganiseBuffers"); - } - newToOldElementMap[&(*ei)] = oldElem; - } - // Now iterate over the new buffers, pulling data out of the old ones - // For each vertex - for (size_t v = 0; v < vertexCount; ++v) - { - // For each (new) element - for (ei = newElemList.begin(); ei != eiend; ++ei) - { - const VertexElement* newElem = &(*ei); + NewToOldElementMap newToOldElementMap; + const VertexDeclaration::VertexElementList& newElemList = newDeclaration->getElements(); + VertexDeclaration::VertexElementList::const_iterator ei, eiend; + eiend = newElemList.end(); + for (ei = newElemList.begin(); ei != eiend; ++ei) + { + // Find corresponding old element + const VertexElement* oldElem = + vertexDeclaration->findElementBySemantic( + (*ei).getSemantic(), (*ei).getIndex()); + if (!oldElem) + { + // Error, cannot create new elements with this method + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Element not found in old vertex declaration", + "VertexData::reorganiseBuffers"); + } + newToOldElementMap[&(*ei)] = oldElem; + } + // Now iterate over the new buffers, pulling data out of the old ones + // For each vertex + for (size_t v = 0; v < vertexCount; ++v) + { + // For each (new) element + for (ei = newElemList.begin(); ei != eiend; ++ei) + { + const VertexElement* newElem = &(*ei); NewToOldElementMap::iterator noi = newToOldElementMap.find(newElem); - const VertexElement* oldElem = noi->second; - unsigned short oldBufferNo = oldElem->getSource(); - unsigned short newBufferNo = newElem->getSource(); - void* pSrcBase = static_cast( - static_cast(oldBufferLocks[oldBufferNo]) - + v * oldBufferVertexSizes[oldBufferNo]); - void* pDstBase = static_cast( - static_cast(newBufferLocks[newBufferNo]) - + v * newBufferVertexSizes[newBufferNo]); - void *pSrc, *pDst; - oldElem->baseVertexPointerToElement(pSrcBase, &pSrc); - newElem->baseVertexPointerToElement(pDstBase, &pDst); - - memcpy(pDst, pSrc, newElem->getSize()); - - } - } - - // Unlock all buffers + const VertexElement* oldElem = noi->second; + unsigned short oldBufferNo = oldElem->getSource(); + unsigned short newBufferNo = newElem->getSource(); + void* pSrcBase = static_cast( + static_cast(oldBufferLocks[oldBufferNo]) + + v * oldBufferVertexSizes[oldBufferNo]); + void* pDstBase = static_cast( + static_cast(newBufferLocks[newBufferNo]) + + v * newBufferVertexSizes[newBufferNo]); + void *pSrc, *pDst; + oldElem->baseVertexPointerToElement(pSrcBase, &pSrc); + newElem->baseVertexPointerToElement(pDstBase, &pDst); + + memcpy(pDst, pSrc, newElem->getSize()); + + } + } + + // Unlock all buffers for (itBinding = oldBindingMap.begin(); itBinding != oldBindingMap.end(); ++itBinding) { itBinding->second->unlock(); @@ -440,21 +440,21 @@ namespace Ogre { newBinding->getBuffer(buf)->unlock(); } - // Delete old binding & declaration - if (mDeleteDclBinding) - { - pManager->destroyVertexBufferBinding(vertexBufferBinding); - pManager->destroyVertexDeclaration(vertexDeclaration); - } + // Delete old binding & declaration + if (mDeleteDclBinding) + { + pManager->destroyVertexBufferBinding(vertexBufferBinding); + pManager->destroyVertexDeclaration(vertexDeclaration); + } - // Assign new binding and declaration - vertexDeclaration = newDeclaration; - vertexBufferBinding = newBinding; - // after this is complete, new manager should be used - mMgr = pManager; - mDeleteDclBinding = true; // because we created these through a manager + // Assign new binding and declaration + vertexDeclaration = newDeclaration; + vertexBufferBinding = newBinding; + // after this is complete, new manager should be used + mMgr = pManager; + mDeleteDclBinding = true; // because we created these through a manager - } + } //----------------------------------------------------------------------- void VertexData::reorganiseBuffers(VertexDeclaration* newDeclaration, HardwareBufferManagerBase* mgr) { @@ -580,397 +580,397 @@ namespace Ogre { // Close gaps closeGapsInBindings(); } - //----------------------------------------------------------------------- - void VertexData::convertPackedColour( - VertexElementType srcType, VertexElementType destType) - { - if (destType != VET_COLOUR_ABGR && destType != VET_COLOUR_ARGB) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid destType parameter", "VertexData::convertPackedColour"); - } - if (srcType != VET_COLOUR_ABGR && srcType != VET_COLOUR_ARGB) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid srcType parameter", "VertexData::convertPackedColour"); - } - - const VertexBufferBinding::VertexBufferBindingMap& bindMap = - vertexBufferBinding->getBindings(); - VertexBufferBinding::VertexBufferBindingMap::const_iterator bindi; - for (bindi = bindMap.begin(); bindi != bindMap.end(); ++bindi) - { - VertexDeclaration::VertexElementList elems = - vertexDeclaration->findElementsBySource(bindi->first); - bool conversionNeeded = false; - VertexDeclaration::VertexElementList::iterator elemi; - for (elemi = elems.begin(); elemi != elems.end(); ++elemi) - { - VertexElement& elem = *elemi; - if (elem.getType() == VET_COLOUR || - ((elem.getType() == VET_COLOUR_ABGR || elem.getType() == VET_COLOUR_ARGB) - && elem.getType() != destType)) - { - conversionNeeded = true; - } - } - - if (conversionNeeded) - { - void* pBase = bindi->second->lock(HardwareBuffer::HBL_NORMAL); - - for (size_t v = 0; v < bindi->second->getNumVertices(); ++v) - { - - for (elemi = elems.begin(); elemi != elems.end(); ++elemi) - { - VertexElement& elem = *elemi; - VertexElementType currType = (elem.getType() == VET_COLOUR) ? - srcType : elem.getType(); - if (elem.getType() == VET_COLOUR || - ((elem.getType() == VET_COLOUR_ABGR || elem.getType() == VET_COLOUR_ARGB) - && elem.getType() != destType)) - { - uint32* pRGBA; - elem.baseVertexPointerToElement(pBase, &pRGBA); - VertexElement::convertColourValue(currType, destType, pRGBA); - } - } - pBase = static_cast( - static_cast(pBase) + bindi->second->getVertexSize()); - } - bindi->second->unlock(); - - // Modify the elements to reflect the changed type - const VertexDeclaration::VertexElementList& allelems = - vertexDeclaration->getElements(); - VertexDeclaration::VertexElementList::const_iterator ai; - unsigned short elemIndex = 0; - for (ai = allelems.begin(); ai != allelems.end(); ++ai, ++elemIndex) - { - const VertexElement& elem = *ai; - if (elem.getType() == VET_COLOUR || - ((elem.getType() == VET_COLOUR_ABGR || elem.getType() == VET_COLOUR_ARGB) - && elem.getType() != destType)) - { - vertexDeclaration->modifyElement(elemIndex, - elem.getSource(), elem.getOffset(), destType, - elem.getSemantic(), elem.getIndex()); - } - } - - } - - - } // each buffer - - - } - //----------------------------------------------------------------------- - ushort VertexData::allocateHardwareAnimationElements(ushort count, bool animateNormals) - { - // Find first free texture coord set - unsigned short texCoord = vertexDeclaration->getNextFreeTextureCoordinate(); - unsigned short freeCount = (ushort)(OGRE_MAX_TEXTURE_COORD_SETS - texCoord); - if (animateNormals) - // we need 2x the texture coords, round down - freeCount /= 2; - - unsigned short supportedCount = std::min(freeCount, count); - - // Increase to correct size - for (size_t c = hwAnimationDataList.size(); c < supportedCount; ++c) - { - // Create a new 3D texture coordinate set - HardwareAnimationData data; - data.targetBufferIndex = vertexBufferBinding->getNextIndex(); - vertexDeclaration->addElement(data.targetBufferIndex, 0, VET_FLOAT3, VES_TEXTURE_COORDINATES, texCoord++); - if (animateNormals) - vertexDeclaration->addElement(data.targetBufferIndex, sizeof(float)*3, VET_FLOAT3, VES_TEXTURE_COORDINATES, texCoord++); - - hwAnimationDataList.push_back(data); - // Vertex buffer will not be bound yet, we expect this to be done by the - // caller when it becomes appropriate (e.g. through a VertexAnimationTrack) - } - - return supportedCount; - } //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - IndexData::IndexData() - { - indexCount = 0; - indexStart = 0; - - } + void VertexData::convertPackedColour( + VertexElementType srcType, VertexElementType destType) + { + if (destType != VET_COLOUR_ABGR && destType != VET_COLOUR_ARGB) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid destType parameter", "VertexData::convertPackedColour"); + } + if (srcType != VET_COLOUR_ABGR && srcType != VET_COLOUR_ARGB) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid srcType parameter", "VertexData::convertPackedColour"); + } + + const VertexBufferBinding::VertexBufferBindingMap& bindMap = + vertexBufferBinding->getBindings(); + VertexBufferBinding::VertexBufferBindingMap::const_iterator bindi; + for (bindi = bindMap.begin(); bindi != bindMap.end(); ++bindi) + { + VertexDeclaration::VertexElementList elems = + vertexDeclaration->findElementsBySource(bindi->first); + bool conversionNeeded = false; + VertexDeclaration::VertexElementList::iterator elemi; + for (elemi = elems.begin(); elemi != elems.end(); ++elemi) + { + VertexElement& elem = *elemi; + if (elem.getType() == VET_COLOUR || + ((elem.getType() == VET_COLOUR_ABGR || elem.getType() == VET_COLOUR_ARGB) + && elem.getType() != destType)) + { + conversionNeeded = true; + } + } + + if (conversionNeeded) + { + void* pBase = bindi->second->lock(HardwareBuffer::HBL_NORMAL); + + for (size_t v = 0; v < bindi->second->getNumVertices(); ++v) + { + + for (elemi = elems.begin(); elemi != elems.end(); ++elemi) + { + VertexElement& elem = *elemi; + VertexElementType currType = (elem.getType() == VET_COLOUR) ? + srcType : elem.getType(); + if (elem.getType() == VET_COLOUR || + ((elem.getType() == VET_COLOUR_ABGR || elem.getType() == VET_COLOUR_ARGB) + && elem.getType() != destType)) + { + uint32* pRGBA; + elem.baseVertexPointerToElement(pBase, &pRGBA); + VertexElement::convertColourValue(currType, destType, pRGBA); + } + } + pBase = static_cast( + static_cast(pBase) + bindi->second->getVertexSize()); + } + bindi->second->unlock(); + + // Modify the elements to reflect the changed type + const VertexDeclaration::VertexElementList& allelems = + vertexDeclaration->getElements(); + VertexDeclaration::VertexElementList::const_iterator ai; + unsigned short elemIndex = 0; + for (ai = allelems.begin(); ai != allelems.end(); ++ai, ++elemIndex) + { + const VertexElement& elem = *ai; + if (elem.getType() == VET_COLOUR || + ((elem.getType() == VET_COLOUR_ABGR || elem.getType() == VET_COLOUR_ARGB) + && elem.getType() != destType)) + { + vertexDeclaration->modifyElement(elemIndex, + elem.getSource(), elem.getOffset(), destType, + elem.getSemantic(), elem.getIndex()); + } + } + + } + + + } // each buffer + + + } + //----------------------------------------------------------------------- + ushort VertexData::allocateHardwareAnimationElements(ushort count, bool animateNormals) + { + // Find first free texture coord set + unsigned short texCoord = vertexDeclaration->getNextFreeTextureCoordinate(); + unsigned short freeCount = (ushort)(OGRE_MAX_TEXTURE_COORD_SETS - texCoord); + if (animateNormals) + // we need 2x the texture coords, round down + freeCount /= 2; + + unsigned short supportedCount = std::min(freeCount, count); + + // Increase to correct size + for (size_t c = hwAnimationDataList.size(); c < supportedCount; ++c) + { + // Create a new 3D texture coordinate set + HardwareAnimationData data; + data.targetBufferIndex = vertexBufferBinding->getNextIndex(); + vertexDeclaration->addElement(data.targetBufferIndex, 0, VET_FLOAT3, VES_TEXTURE_COORDINATES, texCoord++); + if (animateNormals) + vertexDeclaration->addElement(data.targetBufferIndex, sizeof(float)*3, VET_FLOAT3, VES_TEXTURE_COORDINATES, texCoord++); + + hwAnimationDataList.push_back(data); + // Vertex buffer will not be bound yet, we expect this to be done by the + // caller when it becomes appropriate (e.g. through a VertexAnimationTrack) + } + + return supportedCount; + } //----------------------------------------------------------------------- - IndexData::~IndexData() - { - } //----------------------------------------------------------------------- - IndexData* IndexData::clone(bool copyData, HardwareBufferManagerBase* mgr) const - { - HardwareBufferManagerBase* pManager = mgr ? mgr : HardwareBufferManager::getSingletonPtr(); - IndexData* dest = OGRE_NEW IndexData(); - if (indexBuffer.get()) - { + IndexData::IndexData() + { + indexCount = 0; + indexStart = 0; + + } + //----------------------------------------------------------------------- + IndexData::~IndexData() + { + } + //----------------------------------------------------------------------- + IndexData* IndexData::clone(bool copyData, HardwareBufferManagerBase* mgr) const + { + HardwareBufferManagerBase* pManager = mgr ? mgr : HardwareBufferManager::getSingletonPtr(); + IndexData* dest = OGRE_NEW IndexData(); + if (indexBuffer.get()) + { if (copyData) { - dest->indexBuffer = pManager->createIndexBuffer(indexBuffer->getType(), indexBuffer->getNumIndexes(), - indexBuffer->getUsage(), indexBuffer->hasShadowBuffer()); - dest->indexBuffer->copyData(*indexBuffer, 0, 0, indexBuffer->getSizeInBytes(), true); + dest->indexBuffer = pManager->createIndexBuffer(indexBuffer->getType(), indexBuffer->getNumIndexes(), + indexBuffer->getUsage(), indexBuffer->hasShadowBuffer()); + dest->indexBuffer->copyData(*indexBuffer, 0, 0, indexBuffer->getSizeInBytes(), true); } else { dest->indexBuffer = indexBuffer; } } - dest->indexCount = indexCount; - dest->indexStart = indexStart; - return dest; - } + dest->indexCount = indexCount; + dest->indexStart = indexStart; + return dest; + } //----------------------------------------------------------------------- //----------------------------------------------------------------------- - // Local Utility class for vertex cache optimizer - class Triangle + // Local Utility class for vertex cache optimizer + class Triangle { public: - enum EdgeMatchType { - AB, BC, CA, ANY, NONE - }; - - uint32 a, b, c; - - inline Triangle() - { - } - - inline Triangle( uint32 ta, uint32 tb, uint32 tc ) - : a( ta ), b( tb ), c( tc ) - { - } - - inline Triangle( uint32 t[3] ) - : a( t[0] ), b( t[1] ), c( t[2] ) - { - } - - inline Triangle( const Triangle& t ) - : a( t.a ), b( t.b ), c( t.c ) - { - } - - inline bool sharesEdge(const Triangle& t) const - { - return( (a == t.a && b == t.c) || - (a == t.b && b == t.a) || - (a == t.c && b == t.b) || - (b == t.a && c == t.c) || - (b == t.b && c == t.a) || - (b == t.c && c == t.b) || - (c == t.a && a == t.c) || - (c == t.b && a == t.a) || - (c == t.c && a == t.b) ); - } - - inline bool sharesEdge(const uint32 ea, const uint32 eb, const Triangle& t) const - { - return( (ea == t.a && eb == t.c) || - (ea == t.b && eb == t.a) || - (ea == t.c && eb == t.b) ); - } - - inline bool sharesEdge(const EdgeMatchType edge, const Triangle& t) const - { - if (edge == AB) - return sharesEdge(a, b, t); - else if (edge == BC) - return sharesEdge(b, c, t); - else if (edge == CA) - return sharesEdge(c, a, t); - else - return (edge == ANY) == sharesEdge(t); - } - - inline EdgeMatchType endoSharedEdge(const Triangle& t) const - { - if (sharesEdge(a, b, t)) return AB; - if (sharesEdge(b, c, t)) return BC; - if (sharesEdge(c, a, t)) return CA; - return NONE; - } - - inline EdgeMatchType exoSharedEdge(const Triangle& t) const - { - return t.endoSharedEdge(*this); - } - - inline void shiftClockwise() - { - uint32 t = a; - a = c; - c = b; - b = t; - } - - inline void shiftCounterClockwise() - { - uint32 t = a; - a = b; - b = c; - c = t; - } - }; + enum EdgeMatchType { + AB, BC, CA, ANY, NONE + }; + + uint32 a, b, c; + + inline Triangle() + { + } + + inline Triangle( uint32 ta, uint32 tb, uint32 tc ) + : a( ta ), b( tb ), c( tc ) + { + } + + inline Triangle( uint32 t[3] ) + : a( t[0] ), b( t[1] ), c( t[2] ) + { + } + + inline Triangle( const Triangle& t ) + : a( t.a ), b( t.b ), c( t.c ) + { + } + + inline bool sharesEdge(const Triangle& t) const + { + return( (a == t.a && b == t.c) || + (a == t.b && b == t.a) || + (a == t.c && b == t.b) || + (b == t.a && c == t.c) || + (b == t.b && c == t.a) || + (b == t.c && c == t.b) || + (c == t.a && a == t.c) || + (c == t.b && a == t.a) || + (c == t.c && a == t.b) ); + } + + inline bool sharesEdge(const uint32 ea, const uint32 eb, const Triangle& t) const + { + return( (ea == t.a && eb == t.c) || + (ea == t.b && eb == t.a) || + (ea == t.c && eb == t.b) ); + } + + inline bool sharesEdge(const EdgeMatchType edge, const Triangle& t) const + { + if (edge == AB) + return sharesEdge(a, b, t); + else if (edge == BC) + return sharesEdge(b, c, t); + else if (edge == CA) + return sharesEdge(c, a, t); + else + return (edge == ANY) == sharesEdge(t); + } + + inline EdgeMatchType endoSharedEdge(const Triangle& t) const + { + if (sharesEdge(a, b, t)) return AB; + if (sharesEdge(b, c, t)) return BC; + if (sharesEdge(c, a, t)) return CA; + return NONE; + } + + inline EdgeMatchType exoSharedEdge(const Triangle& t) const + { + return t.endoSharedEdge(*this); + } + + inline void shiftClockwise() + { + uint32 t = a; + a = c; + c = b; + b = t; + } + + inline void shiftCounterClockwise() + { + uint32 t = a; + a = b; + b = c; + c = t; + } + }; //----------------------------------------------------------------------- //----------------------------------------------------------------------- - void IndexData::optimiseVertexCacheTriList(void) - { - if (indexBuffer->isLocked()) return; - - void *buffer = indexBuffer->lock(HardwareBuffer::HBL_NORMAL); - - Triangle* triangles; - - size_t nIndexes = indexCount; - size_t nTriangles = nIndexes / 3; - size_t i, j; - uint16 *source = 0; - - if (indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) - { - triangles = OGRE_ALLOC_T(Triangle, nTriangles, MEMCATEGORY_GEOMETRY); - source = (uint16 *)buffer; - uint32 *dest = (uint32 *)triangles; - for (i = 0; i < nIndexes; ++i) dest[i] = source[i]; - } - else - triangles = static_cast(buffer); - - // sort triangles based on shared edges - uint32 *destlist = OGRE_ALLOC_T(uint32, nTriangles, MEMCATEGORY_GEOMETRY); - unsigned char *visited = OGRE_ALLOC_T(unsigned char, nTriangles, MEMCATEGORY_GEOMETRY); - - for (i = 0; i < nTriangles; ++i) visited[i] = 0; - - uint32 start = 0, ti = 0, destcount = 0; - - bool found = false; - for (i = 0; i < nTriangles; ++i) - { - if (found) - found = false; - else - { - while (visited[start++]); - ti = start - 1; - } - - destlist[destcount++] = ti; - visited[ti] = 1; - - for (j = start; j < nTriangles; ++j) - { - if (visited[j]) continue; - - if (triangles[ti].sharesEdge(triangles[j])) - { - found = true; - ti = static_cast(j); - break; - } - } - } - - if (indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) - { - // reorder the indexbuffer - j = 0; - for (i = 0; i < nTriangles; ++i) - { - Triangle *t = &triangles[destlist[i]]; + void IndexData::optimiseVertexCacheTriList(void) + { + if (indexBuffer->isLocked()) return; + + void *buffer = indexBuffer->lock(HardwareBuffer::HBL_NORMAL); + + Triangle* triangles; + + size_t nIndexes = indexCount; + size_t nTriangles = nIndexes / 3; + size_t i, j; + uint16 *source = 0; + + if (indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) + { + triangles = OGRE_ALLOC_T(Triangle, nTriangles, MEMCATEGORY_GEOMETRY); + source = (uint16 *)buffer; + uint32 *dest = (uint32 *)triangles; + for (i = 0; i < nIndexes; ++i) dest[i] = source[i]; + } + else + triangles = static_cast(buffer); + + // sort triangles based on shared edges + uint32 *destlist = OGRE_ALLOC_T(uint32, nTriangles, MEMCATEGORY_GEOMETRY); + unsigned char *visited = OGRE_ALLOC_T(unsigned char, nTriangles, MEMCATEGORY_GEOMETRY); + + for (i = 0; i < nTriangles; ++i) visited[i] = 0; + + uint32 start = 0, ti = 0, destcount = 0; + + bool found = false; + for (i = 0; i < nTriangles; ++i) + { + if (found) + found = false; + else + { + while (visited[start++]); + ti = start - 1; + } + + destlist[destcount++] = ti; + visited[ti] = 1; + + for (j = start; j < nTriangles; ++j) + { + if (visited[j]) continue; + + if (triangles[ti].sharesEdge(triangles[j])) + { + found = true; + ti = static_cast(j); + break; + } + } + } + + if (indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) + { + // reorder the indexbuffer + j = 0; + for (i = 0; i < nTriangles; ++i) + { + Triangle *t = &triangles[destlist[i]]; if(source) { source[j++] = (uint16)t->a; source[j++] = (uint16)t->b; source[j++] = (uint16)t->c; } - } - OGRE_FREE(triangles, MEMCATEGORY_GEOMETRY); - } - else - { - uint32 *reflist = OGRE_ALLOC_T(uint32, nTriangles, MEMCATEGORY_GEOMETRY); - - // fill the referencebuffer - for (i = 0; i < nTriangles; ++i) - reflist[destlist[i]] = static_cast(i); - - // reorder the indexbuffer - for (i = 0; i < nTriangles; ++i) - { - j = destlist[i]; - if (i == j) continue; // do not move triangle - - // swap triangles - - Triangle t = triangles[i]; - triangles[i] = triangles[j]; - triangles[j] = t; - - // change reference - destlist[reflist[i]] = static_cast(j); - // destlist[i] = i; // not needed, it will not be used - } - - OGRE_FREE(reflist, MEMCATEGORY_GEOMETRY); - } - - OGRE_FREE(destlist, MEMCATEGORY_GEOMETRY); - OGRE_FREE(visited, MEMCATEGORY_GEOMETRY); - - indexBuffer->unlock(); - } - //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - void VertexCacheProfiler::profile(const HardwareIndexBufferSharedPtr& indexBuffer) + } + OGRE_FREE(triangles, MEMCATEGORY_GEOMETRY); + } + else + { + uint32 *reflist = OGRE_ALLOC_T(uint32, nTriangles, MEMCATEGORY_GEOMETRY); + + // fill the referencebuffer + for (i = 0; i < nTriangles; ++i) + reflist[destlist[i]] = static_cast(i); + + // reorder the indexbuffer + for (i = 0; i < nTriangles; ++i) + { + j = destlist[i]; + if (i == j) continue; // do not move triangle + + // swap triangles + + Triangle t = triangles[i]; + triangles[i] = triangles[j]; + triangles[j] = t; + + // change reference + destlist[reflist[i]] = static_cast(j); + // destlist[i] = i; // not needed, it will not be used + } + + OGRE_FREE(reflist, MEMCATEGORY_GEOMETRY); + } + + OGRE_FREE(destlist, MEMCATEGORY_GEOMETRY); + OGRE_FREE(visited, MEMCATEGORY_GEOMETRY); + + indexBuffer->unlock(); + } + //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + void VertexCacheProfiler::profile(const HardwareIndexBufferSharedPtr& indexBuffer) { - if (indexBuffer->isLocked()) return; - - uint16 *shortbuffer = (uint16 *)indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY); - - if (indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) - for (unsigned int i = 0; i < indexBuffer->getNumIndexes(); ++i) - inCache(shortbuffer[i]); - else - { - uint32 *buffer = (uint32 *)shortbuffer; - for (unsigned int i = 0; i < indexBuffer->getNumIndexes(); ++i) - inCache(buffer[i]); - } - - indexBuffer->unlock(); - } - - //----------------------------------------------------------------------- - bool VertexCacheProfiler::inCache(unsigned int index) - { - for (unsigned int i = 0; i < buffersize; ++i) - { - if (index == cache[i]) - { - hit++; - return true; - } - } - - miss++; - cache[tail++] = index; - tail %= size; - - if (buffersize < size) buffersize++; - - return false; - } - + if (indexBuffer->isLocked()) return; + + uint16 *shortbuffer = (uint16 *)indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY); + + if (indexBuffer->getType() == HardwareIndexBuffer::IT_16BIT) + for (unsigned int i = 0; i < indexBuffer->getNumIndexes(); ++i) + inCache(shortbuffer[i]); + else + { + uint32 *buffer = (uint32 *)shortbuffer; + for (unsigned int i = 0; i < indexBuffer->getNumIndexes(); ++i) + inCache(buffer[i]); + } + + indexBuffer->unlock(); + } + + //----------------------------------------------------------------------- + bool VertexCacheProfiler::inCache(unsigned int index) + { + for (unsigned int i = 0; i < buffersize; ++i) + { + if (index == cache[i]) + { + hit++; + return true; + } + } + + miss++; + cache[tail++] = index; + tail %= size; + + if (buffersize < size) buffersize++; + + return false; + } + } diff --git a/OgreMain/src/OgreViewport.cpp b/OgreMain/src/OgreViewport.cpp index 5759c28d0f3..98c6b559024 100644 --- a/OgreMain/src/OgreViewport.cpp +++ b/OgreMain/src/OgreViewport.cpp @@ -49,30 +49,30 @@ namespace Ogre { // Actual dimensions will update later , mZOrder(ZOrder) , mBackColour(ColourValue::Black) - , mDepthClearValue(1) + , mDepthClearValue(1) , mClearEveryFrame(true) - , mClearBuffers(FBT_COLOUR | FBT_DEPTH) + , mClearBuffers(FBT_COLOUR | FBT_DEPTH) , mUpdated(false) , mShowOverlays(true) , mShowSkies(true) - , mShowShadows(true) - , mVisibilityMask(0xFFFFFFFF) - , mRQSequence(0) - , mMaterialSchemeName(MaterialManager::DEFAULT_SCHEME_NAME) - , mIsAutoUpdated(true) - { + , mShowShadows(true) + , mVisibilityMask(0xFFFFFFFF) + , mRQSequence(0) + , mMaterialSchemeName(MaterialManager::DEFAULT_SCHEME_NAME) + , mIsAutoUpdated(true) + { #if OGRE_COMPILER != OGRE_COMPILER_GCCE && OGRE_PLATFORM != OGRE_PLATFORM_ANDROID - LogManager::getSingleton().stream(LML_TRIVIAL) - << "Creating viewport on target '" << target->getName() << "'" - << ", rendering from camera '" << (cam != 0 ? cam->getName() : "NULL") << "'" - << ", relative dimensions " << std::ios::fixed << std::setprecision(2) - << "L: " << left << " T: " << top << " W: " << width << " H: " << height - << " Z-order: " << ZOrder; + LogManager::getSingleton().stream(LML_TRIVIAL) + << "Creating viewport on target '" << target->getName() << "'" + << ", rendering from camera '" << (cam != 0 ? cam->getName() : "NULL") << "'" + << ", relative dimensions " << std::ios::fixed << std::setprecision(2) + << "L: " << left << " T: " << top << " W: " << width << " H: " << height + << " Z-order: " << ZOrder; #endif // Set the default orientation mode mOrientationMode = mDefaultOrientationMode; - + // Set the default material scheme RenderSystem* rs = Root::getSingleton().getRenderSystem(); mMaterialSchemeName = rs->_getDefaultViewportMaterialScheme(); @@ -86,18 +86,18 @@ namespace Ogre { //--------------------------------------------------------------------- Viewport::~Viewport() { - ListenerList listenersCopy; - std::swap(mListeners, listenersCopy); - for (ListenerList::iterator i = listenersCopy.begin(); i != listenersCopy.end(); ++i) - { - (*i)->viewportDestroyed(this); - } + ListenerList listenersCopy; + std::swap(mListeners, listenersCopy); + for (ListenerList::iterator i = listenersCopy.begin(); i != listenersCopy.end(); ++i) + { + (*i)->viewportDestroyed(this); + } - RenderSystem* rs = Root::getSingleton().getRenderSystem(); - if ((rs) && (rs->_getViewport() == this)) - { - rs->_setViewport(NULL); - } + RenderSystem* rs = Root::getSingleton().getRenderSystem(); + if ((rs) && (rs->_getViewport() == this)) + { + rs->_setViewport(NULL); + } } //--------------------------------------------------------------------- bool Viewport::_isUpdated(void) const @@ -137,25 +137,25 @@ namespace Ogre { } #if OGRE_COMPILER != OGRE_COMPILER_GCCE - LogManager::getSingleton().stream(LML_TRIVIAL) - << "Viewport for camera '" << (mCamera != 0 ? mCamera->getName() : "NULL") << "'" - << ", actual dimensions " << std::ios::fixed << std::setprecision(2) - << "L: " << mActLeft << " T: " << mActTop << " W: " << mActWidth << " H: " << mActHeight; + LogManager::getSingleton().stream(LML_TRIVIAL) + << "Viewport for camera '" << (mCamera != 0 ? mCamera->getName() : "NULL") << "'" + << ", actual dimensions " << std::ios::fixed << std::setprecision(2) + << "L: " << mActLeft << " T: " << mActTop << " W: " << mActWidth << " H: " << mActHeight; #endif - mUpdated = true; + mUpdated = true; - for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i) - { - (*i)->viewportDimensionsChanged(this); - } - } - //--------------------------------------------------------------------- - int Viewport::getZOrder(void) const - { - return mZOrder; - } - //--------------------------------------------------------------------- + for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i) + { + (*i)->viewportDimensionsChanged(this); + } + } + //--------------------------------------------------------------------- + int Viewport::getZOrder(void) const + { + return mZOrder; + } + //--------------------------------------------------------------------- RenderTarget* Viewport::getTarget(void) const { return mTarget; @@ -243,7 +243,7 @@ namespace Ogre { mCamera->setOrientationMode(mOrientationMode); } - // Update the render system config + // Update the render system config #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS RenderSystem* rs = Root::getSingleton().getRenderSystem(); if(mOrientationMode == OR_LANDSCAPELEFT) @@ -295,7 +295,7 @@ namespace Ogre { return mBackColour; } //--------------------------------------------------------------------- - void Viewport::setDepthClear( Real depth ) + void Viewport::setDepthClear( Real depth ) { mDepthClearValue = depth; } @@ -304,11 +304,11 @@ namespace Ogre { { return mDepthClearValue; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void Viewport::setClearEveryFrame(bool inClear, unsigned int inBuffers) { mClearEveryFrame = inClear; - mClearBuffers = inBuffers; + mClearBuffers = inBuffers; } //--------------------------------------------------------------------- bool Viewport::getClearEveryFrame(void) const @@ -321,23 +321,23 @@ namespace Ogre { return mClearBuffers; } //--------------------------------------------------------------------- - void Viewport::clear(unsigned int buffers, const ColourValue& col, - Real depth, unsigned short stencil) - { - RenderSystem* rs = Root::getSingleton().getRenderSystem(); - if (rs) - { - Viewport* currentvp = rs->_getViewport(); - if (currentvp && currentvp == this) - rs->clearFrameBuffer(buffers, col, depth, stencil); - else if (currentvp) - { - rs->_setViewport(this); - rs->clearFrameBuffer(buffers, col, depth, stencil); - rs->_setViewport(currentvp); - } - } - } + void Viewport::clear(unsigned int buffers, const ColourValue& col, + Real depth, unsigned short stencil) + { + RenderSystem* rs = Root::getSingleton().getRenderSystem(); + if (rs) + { + Viewport* currentvp = rs->_getViewport(); + if (currentvp && currentvp == this) + rs->clearFrameBuffer(buffers, col, depth, stencil); + else if (currentvp) + { + rs->_setViewport(this); + rs->clearFrameBuffer(buffers, col, depth, stencil); + rs->_setViewport(currentvp); + } + } + } //--------------------------------------------------------------------- void Viewport::getActualDimensions(int &left, int&top, int &width, int &height) const { @@ -350,54 +350,54 @@ namespace Ogre { //--------------------------------------------------------------------- unsigned int Viewport::_getNumRenderedFaces(void) const { - return mCamera ? mCamera->_getNumRenderedFaces() : 0; + return mCamera ? mCamera->_getNumRenderedFaces() : 0; } //--------------------------------------------------------------------- unsigned int Viewport::_getNumRenderedBatches(void) const { - return mCamera ? mCamera->_getNumRenderedBatches() : 0; - } - //--------------------------------------------------------------------- - void Viewport::setCamera(Camera* cam) - { - if(mCamera) - { - if(mCamera->getViewport() == this) - { - mCamera->_notifyViewport(0); - } - } + return mCamera ? mCamera->_getNumRenderedBatches() : 0; + } + //--------------------------------------------------------------------- + void Viewport::setCamera(Camera* cam) + { + if(mCamera) + { + if(mCamera->getViewport() == this) + { + mCamera->_notifyViewport(0); + } + } - mCamera = cam; - if (cam) - { - // update aspect ratio of new camera if needed. - if (cam->getAutoAspectRatio()) - { - cam->setAspectRatio((Real) mActWidth / (Real) mActHeight); - } + mCamera = cam; + if (cam) + { + // update aspect ratio of new camera if needed. + if (cam->getAutoAspectRatio()) + { + cam->setAspectRatio((Real) mActWidth / (Real) mActHeight); + } #if OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0 - cam->setOrientationMode(mOrientationMode); + cam->setOrientationMode(mOrientationMode); #endif - cam->_notifyViewport(this); - } + cam->_notifyViewport(this); + } - for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i) - { - (*i)->viewportCameraChanged(this); - } - } - //--------------------------------------------------------------------- - void Viewport::setAutoUpdated(bool inAutoUpdated) - { - mIsAutoUpdated = inAutoUpdated; - } - //--------------------------------------------------------------------- - bool Viewport::isAutoUpdated() const - { - return mIsAutoUpdated; - } - //--------------------------------------------------------------------- + for (ListenerList::iterator i = mListeners.begin(); i != mListeners.end(); ++i) + { + (*i)->viewportCameraChanged(this); + } + } + //--------------------------------------------------------------------- + void Viewport::setAutoUpdated(bool inAutoUpdated) + { + mIsAutoUpdated = inAutoUpdated; + } + //--------------------------------------------------------------------- + bool Viewport::isAutoUpdated() const + { + return mIsAutoUpdated; + } + //--------------------------------------------------------------------- void Viewport::setOverlaysEnabled(bool enabled) { mShowOverlays = enabled; @@ -427,36 +427,36 @@ namespace Ogre { { return mShowShadows; } - //----------------------------------------------------------------------- - void Viewport::setRenderQueueInvocationSequenceName(const String& sequenceName) - { - mRQSequenceName = sequenceName; - if (mRQSequenceName.empty()) - { - mRQSequence = 0; - } - else - { - mRQSequence = - Root::getSingleton().getRenderQueueInvocationSequence(mRQSequenceName); - } - } - //----------------------------------------------------------------------- - const String& Viewport::getRenderQueueInvocationSequenceName(void) const - { - return mRQSequenceName; - } - //----------------------------------------------------------------------- - RenderQueueInvocationSequence* Viewport::_getRenderQueueInvocationSequence(void) - { - return mRQSequence; - } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + void Viewport::setRenderQueueInvocationSequenceName(const String& sequenceName) + { + mRQSequenceName = sequenceName; + if (mRQSequenceName.empty()) + { + mRQSequence = 0; + } + else + { + mRQSequence = + Root::getSingleton().getRenderQueueInvocationSequence(mRQSequenceName); + } + } + //----------------------------------------------------------------------- + const String& Viewport::getRenderQueueInvocationSequenceName(void) const + { + return mRQSequenceName; + } + //----------------------------------------------------------------------- + RenderQueueInvocationSequence* Viewport::_getRenderQueueInvocationSequence(void) + { + return mRQSequence; + } + //----------------------------------------------------------------------- void Viewport::pointOrientedToScreen(const Vector2 &v, int orientationMode, Vector2 &outv) { pointOrientedToScreen(v.x, v.y, orientationMode, outv.x, outv.y); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void Viewport::pointOrientedToScreen(Real orientedX, Real orientedY, int orientationMode, Real &screenX, Real &screenY) { @@ -482,18 +482,18 @@ namespace Ogre { break; } } - //----------------------------------------------------------------------- - void Viewport::addListener(Listener* l) - { - if (std::find(mListeners.begin(), mListeners.end(), l) == mListeners.end()) - mListeners.push_back(l); - } - //----------------------------------------------------------------------- - void Viewport::removeListener(Listener* l) - { - ListenerList::iterator i = std::find(mListeners.begin(), mListeners.end(), l); - if (i != mListeners.end()) - mListeners.erase(i); - } + //----------------------------------------------------------------------- + void Viewport::addListener(Listener* l) + { + if (std::find(mListeners.begin(), mListeners.end(), l) == mListeners.end()) + mListeners.push_back(l); + } + //----------------------------------------------------------------------- + void Viewport::removeListener(Listener* l) + { + ListenerList::iterator i = std::find(mListeners.begin(), mListeners.end(), l); + if (i != mListeners.end()) + mListeners.erase(i); + } } diff --git a/OgreMain/src/OgreWindowEventUtilities.cpp b/OgreMain/src/OgreWindowEventUtilities.cpp index 9414be7a37f..48dd4dba679 100644 --- a/OgreMain/src/OgreWindowEventUtilities.cpp +++ b/OgreMain/src/OgreWindowEventUtilities.cpp @@ -45,93 +45,93 @@ namespace Ogre { void WindowEventUtilities::messagePump() { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - // Windows Message Loop (NULL means check all HWNDs belonging to this context) - MSG msg; - while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) - { - TranslateMessage( &msg ); - DispatchMessage( &msg ); - } + // Windows Message Loop (NULL means check all HWNDs belonging to this context) + MSG msg; + while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX - //GLX Message Pump - RenderWindowList::iterator win = _msWindows.begin(); - RenderWindowList::iterator end = _msWindows.end(); - - Display* xDisplay = 0; // same for all windows - - for (; win != end; win++) - { - XID xid; - XEvent event; - - if (!xDisplay) - (*win)->getCustomAttribute("XDISPLAY", &xDisplay); - - (*win)->getCustomAttribute("WINDOW", &xid); - - while (XCheckWindowEvent (xDisplay, xid, StructureNotifyMask | VisibilityChangeMask | FocusChangeMask, &event)) - { - GLXProc(*win, event); - } - - // The ClientMessage event does not appear under any Event Mask - while (XCheckTypedWindowEvent (xDisplay, xid, ClientMessage, &event)) - { - GLXProc(*win, event); - } - } + //GLX Message Pump + RenderWindowList::iterator win = _msWindows.begin(); + RenderWindowList::iterator end = _msWindows.end(); + + Display* xDisplay = 0; // same for all windows + + for (; win != end; win++) + { + XID xid; + XEvent event; + + if (!xDisplay) + (*win)->getCustomAttribute("XDISPLAY", &xDisplay); + + (*win)->getCustomAttribute("WINDOW", &xid); + + while (XCheckWindowEvent (xDisplay, xid, StructureNotifyMask | VisibilityChangeMask | FocusChangeMask, &event)) + { + GLXProc(*win, event); + } + + // The ClientMessage event does not appear under any Event Mask + while (XCheckTypedWindowEvent (xDisplay, xid, ClientMessage, &event)) + { + GLXProc(*win, event); + } + } #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined __LP64__ - // OSX Message Pump - EventRef event = NULL; - EventTargetRef targetWindow; - targetWindow = GetEventDispatcherTarget(); + // OSX Message Pump + EventRef event = NULL; + EventTargetRef targetWindow; + targetWindow = GetEventDispatcherTarget(); // If we are unable to get the target then we no longer care about events. if( !targetWindow ) return; // Grab the next event, process it if it is a window event - while( ReceiveNextEvent( 0, NULL, kEventDurationNoWait, true, &event ) == noErr ) - { + while( ReceiveNextEvent( 0, NULL, kEventDurationNoWait, true, &event ) == noErr ) + { // Dispatch the event - SendEventToEventTarget( event, targetWindow ); - ReleaseEvent( event ); - } + SendEventToEventTarget( event, targetWindow ); + ReleaseEvent( event ); + } #endif } //--------------------------------------------------------------------------------// void WindowEventUtilities::addWindowEventListener( RenderWindow* window, WindowEventListener* listener ) { - _msListeners.insert(std::make_pair(window, listener)); + _msListeners.insert(std::make_pair(window, listener)); } //--------------------------------------------------------------------------------// void WindowEventUtilities::removeWindowEventListener( RenderWindow* window, WindowEventListener* listener ) { - WindowEventListeners::iterator i = _msListeners.begin(), e = _msListeners.end(); - - for( ; i != e; ++i ) - { - if( i->first == window && i->second == listener ) - { - _msListeners.erase(i); - break; - } - } + WindowEventListeners::iterator i = _msListeners.begin(), e = _msListeners.end(); + + for( ; i != e; ++i ) + { + if( i->first == window && i->second == listener ) + { + _msListeners.erase(i); + break; + } + } } //--------------------------------------------------------------------------------// void WindowEventUtilities::_addRenderWindow(RenderWindow* window) { - _msWindows.push_back(window); + _msWindows.push_back(window); } //--------------------------------------------------------------------------------// void WindowEventUtilities::_removeRenderWindow(RenderWindow* window) { - RenderWindowList::iterator i = std::find(_msWindows.begin(), _msWindows.end(), window); - if( i != _msWindows.end() ) - _msWindows.erase( i ); + RenderWindowList::iterator i = std::find(_msWindows.begin(), _msWindows.end(), window); + if( i != _msWindows.end() ) + _msWindows.erase( i ); } } @@ -140,227 +140,227 @@ void WindowEventUtilities::_removeRenderWindow(RenderWindow* window) namespace Ogre { LRESULT CALLBACK WindowEventUtilities::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - if (uMsg == WM_CREATE) - { // Store pointer to Win32Window in user data area - SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams)); - return 0; - } - - // look up window instance - // note: it is possible to get a WM_SIZE before WM_CREATE - RenderWindow* win = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA); - if (!win) - return DefWindowProc(hWnd, uMsg, wParam, lParam); - - //LogManager* log = LogManager::getSingletonPtr(); - //Iterator of all listeners registered to this RenderWindow - WindowEventListeners::iterator index, + if (uMsg == WM_CREATE) + { // Store pointer to Win32Window in user data area + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams)); + return 0; + } + + // look up window instance + // note: it is possible to get a WM_SIZE before WM_CREATE + RenderWindow* win = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA); + if (!win) + return DefWindowProc(hWnd, uMsg, wParam, lParam); + + //LogManager* log = LogManager::getSingletonPtr(); + //Iterator of all listeners registered to this RenderWindow + WindowEventListeners::iterator index, start = _msListeners.lower_bound(win), end = _msListeners.upper_bound(win); - switch( uMsg ) - { - case WM_ACTIVATE: - { + switch( uMsg ) + { + case WM_ACTIVATE: + { bool active = (LOWORD(wParam) != WA_INACTIVE); if( active ) { - win->setActive( true ); + win->setActive( true ); } else { if( win->isDeactivatedOnFocusChange() ) { - win->setActive( false ); + win->setActive( false ); } } - for( ; start != end; ++start ) - (start->second)->windowFocusChange(win); - break; - } - case WM_SYSKEYDOWN: - switch( wParam ) - { - case VK_CONTROL: - case VK_SHIFT: - case VK_MENU: //ALT - //return zero to bypass defProc and signal we processed the message - return 0; - } - break; - case WM_SYSKEYUP: - switch( wParam ) - { - case VK_CONTROL: - case VK_SHIFT: - case VK_MENU: //ALT - case VK_F10: - //return zero to bypass defProc and signal we processed the message - return 0; - } - break; - case WM_SYSCHAR: - // return zero to bypass defProc and signal we processed the message, unless it's an ALT-space - if (wParam != VK_SPACE) - return 0; - break; - case WM_ENTERSIZEMOVE: - //log->logMessage("WM_ENTERSIZEMOVE"); - break; - case WM_EXITSIZEMOVE: - //log->logMessage("WM_EXITSIZEMOVE"); - break; - case WM_MOVE: - //log->logMessage("WM_MOVE"); - win->windowMovedOrResized(); - for(index = start; index != end; ++index) - (index->second)->windowMoved(win); - break; - case WM_DISPLAYCHANGE: - win->windowMovedOrResized(); - for(index = start; index != end; ++index) - (index->second)->windowResized(win); - break; - case WM_SIZE: - //log->logMessage("WM_SIZE"); - win->windowMovedOrResized(); - for(index = start; index != end; ++index) - (index->second)->windowResized(win); - break; - case WM_GETMINMAXINFO: - // Prevent the window from going smaller than some minimu size - ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100; - ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100; - break; - case WM_CLOSE: - { - //log->logMessage("WM_CLOSE"); - bool close = true; - for(index = start; index != end; ++index) - { - if (!(index->second)->windowClosing(win)) - close = false; - } - if (!close) return 0; - - for(index = _msListeners.lower_bound(win); index != end; ++index) - (index->second)->windowClosed(win); - win->destroy(); - return 0; - } - } - - return DefWindowProc( hWnd, uMsg, wParam, lParam ); + for( ; start != end; ++start ) + (start->second)->windowFocusChange(win); + break; + } + case WM_SYSKEYDOWN: + switch( wParam ) + { + case VK_CONTROL: + case VK_SHIFT: + case VK_MENU: //ALT + //return zero to bypass defProc and signal we processed the message + return 0; + } + break; + case WM_SYSKEYUP: + switch( wParam ) + { + case VK_CONTROL: + case VK_SHIFT: + case VK_MENU: //ALT + case VK_F10: + //return zero to bypass defProc and signal we processed the message + return 0; + } + break; + case WM_SYSCHAR: + // return zero to bypass defProc and signal we processed the message, unless it's an ALT-space + if (wParam != VK_SPACE) + return 0; + break; + case WM_ENTERSIZEMOVE: + //log->logMessage("WM_ENTERSIZEMOVE"); + break; + case WM_EXITSIZEMOVE: + //log->logMessage("WM_EXITSIZEMOVE"); + break; + case WM_MOVE: + //log->logMessage("WM_MOVE"); + win->windowMovedOrResized(); + for(index = start; index != end; ++index) + (index->second)->windowMoved(win); + break; + case WM_DISPLAYCHANGE: + win->windowMovedOrResized(); + for(index = start; index != end; ++index) + (index->second)->windowResized(win); + break; + case WM_SIZE: + //log->logMessage("WM_SIZE"); + win->windowMovedOrResized(); + for(index = start; index != end; ++index) + (index->second)->windowResized(win); + break; + case WM_GETMINMAXINFO: + // Prevent the window from going smaller than some minimu size + ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100; + ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100; + break; + case WM_CLOSE: + { + //log->logMessage("WM_CLOSE"); + bool close = true; + for(index = start; index != end; ++index) + { + if (!(index->second)->windowClosing(win)) + close = false; + } + if (!close) return 0; + + for(index = _msListeners.lower_bound(win); index != end; ++index) + (index->second)->windowClosed(win); + win->destroy(); + return 0; + } + } + + return DefWindowProc( hWnd, uMsg, wParam, lParam ); } } #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX //--------------------------------------------------------------------------------// void GLXProc( Ogre::RenderWindow *win, const XEvent &event ) { - //An iterator for the window listeners + //An iterator for the window listeners Ogre::WindowEventUtilities::WindowEventListeners::iterator index, - start = Ogre::WindowEventUtilities::_msListeners.lower_bound(win), - end = Ogre::WindowEventUtilities::_msListeners.upper_bound(win); - - switch(event.type) - { - case ClientMessage: - { - ::Atom atom; - win->getCustomAttribute("ATOM", &atom); - if(event.xclient.format == 32 && event.xclient.data.l[0] == (long)atom) - { //Window closed by window manager - //Send message first, to allow app chance to unregister things that need done before - //window is shutdown - bool close = true; + start = Ogre::WindowEventUtilities::_msListeners.lower_bound(win), + end = Ogre::WindowEventUtilities::_msListeners.upper_bound(win); + + switch(event.type) + { + case ClientMessage: + { + ::Atom atom; + win->getCustomAttribute("ATOM", &atom); + if(event.xclient.format == 32 && event.xclient.data.l[0] == (long)atom) + { //Window closed by window manager + //Send message first, to allow app chance to unregister things that need done before + //window is shutdown + bool close = true; for(index = start ; index != end; ++index) - { - if (!(index->second)->windowClosing(win)) - close = false; - } - if (!close) return; + { + if (!(index->second)->windowClosing(win)) + close = false; + } + if (!close) return; for(index = start ; index != end; ++index) (index->second)->windowClosed(win); - win->destroy(); - } - break; - } - case DestroyNotify: - { - if (!win->isClosed()) - { - // Window closed without window manager warning. + win->destroy(); + } + break; + } + case DestroyNotify: + { + if (!win->isClosed()) + { + // Window closed without window manager warning. for(index = start ; index != end; ++index) (index->second)->windowClosed(win); - win->destroy(); - } - break; - } - case ConfigureNotify: - { + win->destroy(); + } + break; + } + case ConfigureNotify: + { // This could be slightly more efficient if windowMovedOrResized took arguments: - unsigned int oldWidth, oldHeight, oldDepth; - int oldLeft, oldTop; - win->getMetrics(oldWidth, oldHeight, oldDepth, oldLeft, oldTop); - win->windowMovedOrResized(); + unsigned int oldWidth, oldHeight, oldDepth; + int oldLeft, oldTop; + win->getMetrics(oldWidth, oldHeight, oldDepth, oldLeft, oldTop); + win->windowMovedOrResized(); - unsigned int newWidth, newHeight, newDepth; - int newLeft, newTop; - win->getMetrics(newWidth, newHeight, newDepth, newLeft, newTop); + unsigned int newWidth, newHeight, newDepth; + int newLeft, newTop; + win->getMetrics(newWidth, newHeight, newDepth, newLeft, newTop); - if (newLeft != oldLeft || newTop != oldTop) - { + if (newLeft != oldLeft || newTop != oldTop) + { for(index = start ; index != end; ++index) (index->second)->windowMoved(win); - } + } - if (newWidth != oldWidth || newHeight != oldHeight) - { + if (newWidth != oldWidth || newHeight != oldHeight) + { for(index = start ; index != end; ++index) (index->second)->windowResized(win); - } - break; - } - case FocusIn: // Gained keyboard focus - case FocusOut: // Lost keyboard focus + } + break; + } + case FocusIn: // Gained keyboard focus + case FocusOut: // Lost keyboard focus for(index = start ; index != end; ++index) (index->second)->windowFocusChange(win); - break; - case MapNotify: //Restored - win->setActive( true ); + break; + case MapNotify: //Restored + win->setActive( true ); for(index = start ; index != end; ++index) (index->second)->windowFocusChange(win); - break; - case UnmapNotify: //Minimised - win->setActive( false ); - win->setVisible( false ); + break; + case UnmapNotify: //Minimised + win->setActive( false ); + win->setVisible( false ); for(index = start ; index != end; ++index) (index->second)->windowFocusChange(win); - break; - case VisibilityNotify: - switch(event.xvisibility.state) - { - case VisibilityUnobscured: - win->setActive( true ); - win->setVisible( true ); - break; - case VisibilityPartiallyObscured: - win->setActive( true ); - win->setVisible( true ); - break; - case VisibilityFullyObscured: - win->setActive( false ); - win->setVisible( false ); - break; - } + break; + case VisibilityNotify: + switch(event.xvisibility.state) + { + case VisibilityUnobscured: + win->setActive( true ); + win->setVisible( true ); + break; + case VisibilityPartiallyObscured: + win->setActive( true ); + win->setVisible( true ); + break; + case VisibilityFullyObscured: + win->setActive( false ); + win->setVisible( false ); + break; + } for(index = start ; index != end; ++index) (index->second)->windowFocusChange(win); - break; - default: - break; - } //End switch event.type + break; + default: + break; + } //End switch event.type } #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined __LP64__ //--------------------------------------------------------------------------------// @@ -375,7 +375,7 @@ OSStatus WindowEventUtilities::_CarbonWindowHandler(EventHandlerCallRef nextHand if(!curWindow) return eventNotHandledErr; //Iterator of all listeners registered to this RenderWindow - WindowEventListeners::iterator index, + WindowEventListeners::iterator index, start = _msListeners.lower_bound(curWindow), end = _msListeners.upper_bound(curWindow); @@ -416,31 +416,31 @@ OSStatus WindowEventUtilities::_CarbonWindowHandler(EventHandlerCallRef nextHand case kEventWindowDragCompleted: curWindow->windowMovedOrResized(); for( ; start != end; ++start ) - (start->second)->windowMoved(curWindow); + (start->second)->windowMoved(curWindow); break; case kEventWindowBoundsChanged: curWindow->windowMovedOrResized(); for( ; start != end; ++start ) - (start->second)->windowResized(curWindow); + (start->second)->windowResized(curWindow); + break; + case kEventWindowClose: + { + bool close = true; + for( ; start != end; ++start ) + { + if (!(start->second)->windowClosing(curWindow)) + close = false; + } + if (close) + // This will cause event handling to continue on to the standard handler, which calls + // DisposeWindow(), which leads to the 'kEventWindowClosed' event + status = eventNotHandledErr; break; - case kEventWindowClose: - { - bool close = true; - for( ; start != end; ++start ) - { - if (!(start->second)->windowClosing(curWindow)) - close = false; - } - if (close) - // This will cause event handling to continue on to the standard handler, which calls - // DisposeWindow(), which leads to the 'kEventWindowClosed' event - status = eventNotHandledErr; - break; - } + } case kEventWindowClosed: curWindow->destroy(); for( ; start != end; ++start ) - (start->second)->windowClosed(curWindow); + (start->second)->windowClosed(curWindow); break; default: status = eventNotHandledErr; diff --git a/OgreMain/src/OgreWireBoundingBox.cpp b/OgreMain/src/OgreWireBoundingBox.cpp index c15c2117972..824184c268a 100644 --- a/OgreMain/src/OgreWireBoundingBox.cpp +++ b/OgreMain/src/OgreWireBoundingBox.cpp @@ -35,27 +35,27 @@ THE SOFTWARE. namespace Ogre { #define POSITION_BINDING 0 - WireBoundingBox::WireBoundingBox() - : SimpleRenderable() - { - _initWireBoundingBox(); - } - - WireBoundingBox::WireBoundingBox(const String& name) - : SimpleRenderable(name) - { - _initWireBoundingBox(); - } - - void WireBoundingBox::_initWireBoundingBox() + WireBoundingBox::WireBoundingBox() + : SimpleRenderable() + { + _initWireBoundingBox(); + } + + WireBoundingBox::WireBoundingBox(const String& name) + : SimpleRenderable(name) + { + _initWireBoundingBox(); + } + + void WireBoundingBox::_initWireBoundingBox() { mRenderOp.vertexData = OGRE_NEW VertexData(); mRenderOp.indexData = 0; - mRenderOp.vertexData->vertexCount = 24; - mRenderOp.vertexData->vertexStart = 0; - mRenderOp.operationType = RenderOperation::OT_LINE_LIST; - mRenderOp.useIndexes = false; + mRenderOp.vertexData->vertexCount = 24; + mRenderOp.vertexData->vertexStart = 0; + mRenderOp.operationType = RenderOperation::OT_LINE_LIST; + mRenderOp.useIndexes = false; mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false; VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration; @@ -78,134 +78,134 @@ namespace Ogre { - } - - WireBoundingBox::~WireBoundingBox() + } + + WireBoundingBox::~WireBoundingBox() { OGRE_DELETE mRenderOp.vertexData; - } + } - void WireBoundingBox::setupBoundingBox(const AxisAlignedBox& aabb) + void WireBoundingBox::setupBoundingBox(const AxisAlignedBox& aabb) { - // init the vertices to the aabb - setupBoundingBoxVertices(aabb); + // init the vertices to the aabb + setupBoundingBoxVertices(aabb); - // setup the bounding box of this SimpleRenderable - setBoundingBox(aabb); + // setup the bounding box of this SimpleRenderable + setBoundingBox(aabb); - } + } - // Override this method to prevent parent transforms (rotation,translation,scale) + // Override this method to prevent parent transforms (rotation,translation,scale) void WireBoundingBox::getWorldTransforms( Matrix4* xform ) const { - // return identity matrix to prevent parent transforms + // return identity matrix to prevent parent transforms *xform = Matrix4::IDENTITY; } //----------------------------------------------------------------------- - void WireBoundingBox::setupBoundingBoxVertices(const AxisAlignedBox& aab) { + void WireBoundingBox::setupBoundingBoxVertices(const AxisAlignedBox& aab) { - Vector3 vmax = aab.getMaximum(); - Vector3 vmin = aab.getMinimum(); + Vector3 vmax = aab.getMaximum(); + Vector3 vmin = aab.getMinimum(); Real sqLen = std::max(vmax.squaredLength(), vmin.squaredLength()); mRadius = Math::Sqrt(sqLen); - - - - - Real maxx = vmax.x; - Real maxy = vmax.y; - Real maxz = vmax.z; - - Real minx = vmin.x; - Real miny = vmin.y; - Real minz = vmin.z; - - // fill in the Vertex buffer: 12 lines with 2 endpoints each make up a box + + + + + Real maxx = vmax.x; + Real maxy = vmax.y; + Real maxz = vmax.z; + + Real minx = vmin.x; + Real miny = vmin.y; + Real minz = vmin.z; + + // fill in the Vertex buffer: 12 lines with 2 endpoints each make up a box HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); float* pPos = static_cast( vbuf->lock(HardwareBuffer::HBL_DISCARD)); - // line 0 + // line 0 *pPos++ = minx; *pPos++ = miny; *pPos++ = minz; *pPos++ = maxx; *pPos++ = miny; *pPos++ = minz; - // line 1 + // line 1 *pPos++ = minx; *pPos++ = miny; *pPos++ = minz; *pPos++ = minx; *pPos++ = miny; *pPos++ = maxz; - // line 2 + // line 2 *pPos++ = minx; *pPos++ = miny; *pPos++ = minz; *pPos++ = minx; *pPos++ = maxy; *pPos++ = minz; - // line 3 + // line 3 *pPos++ = minx; *pPos++ = maxy; *pPos++ = minz; *pPos++ = minx; *pPos++ = maxy; *pPos++ = maxz; - // line 4 + // line 4 *pPos++ = minx; *pPos++ = maxy; *pPos++ = minz; *pPos++ = maxx; *pPos++ = maxy; *pPos++ = minz; - // line 5 + // line 5 *pPos++ = maxx; *pPos++ = miny; *pPos++ = minz; *pPos++ = maxx; *pPos++ = miny; *pPos++ = maxz; - // line 6 + // line 6 *pPos++ = maxx; *pPos++ = miny; *pPos++ = minz; *pPos++ = maxx; *pPos++ = maxy; *pPos++ = minz; - // line 7 + // line 7 *pPos++ = minx; *pPos++ = maxy; *pPos++ = maxz; *pPos++ = maxx; *pPos++ = maxy; *pPos++ = maxz; - // line 8 + // line 8 *pPos++ = minx; *pPos++ = maxy; *pPos++ = maxz; *pPos++ = minx; *pPos++ = miny; *pPos++ = maxz; - // line 9 + // line 9 *pPos++ = maxx; *pPos++ = maxy; *pPos++ = minz; *pPos++ = maxx; *pPos++ = maxy; *pPos++ = maxz; - // line 10 + // line 10 *pPos++ = maxx; *pPos++ = miny; *pPos++ = maxz; *pPos++ = maxx; *pPos++ = maxy; *pPos++ = maxz; - // line 11 + // line 11 *pPos++ = minx; *pPos++ = miny; *pPos++ = maxz; @@ -213,20 +213,20 @@ namespace Ogre { *pPos++ = miny; *pPos++ = maxz; vbuf->unlock(); - } + } //----------------------------------------------------------------------- - Real WireBoundingBox::getSquaredViewDepth(const Camera* cam) const - { - Vector3 min, max, mid, dist; - min = mBox.getMinimum(); - max = mBox.getMaximum(); - mid = ((max - min) * 0.5) + min; - dist = cam->getDerivedPosition() - mid; + Real WireBoundingBox::getSquaredViewDepth(const Camera* cam) const + { + Vector3 min, max, mid, dist; + min = mBox.getMinimum(); + max = mBox.getMaximum(); + mid = ((max - min) * 0.5) + min; + dist = cam->getDerivedPosition() - mid; - return dist.squaredLength(); - } + return dist.squaredLength(); + } diff --git a/OgreMain/src/OgreWorkQueue.cpp b/OgreMain/src/OgreWorkQueue.cpp index 50f7e428def..3bee7ea2130 100644 --- a/OgreMain/src/OgreWorkQueue.cpp +++ b/OgreMain/src/OgreWorkQueue.cpp @@ -32,733 +32,733 @@ THE SOFTWARE. #include "OgreTimer.h" namespace Ogre { - //--------------------------------------------------------------------- - uint16 WorkQueue::getChannel(const String& channelName) - { + //--------------------------------------------------------------------- + uint16 WorkQueue::getChannel(const String& channelName) + { OGRE_LOCK_MUTEX(mChannelMapMutex); - ChannelMap::iterator i = mChannelMap.find(channelName); - if (i == mChannelMap.end()) - { - i = mChannelMap.insert(ChannelMap::value_type(channelName, mNextChannel++)).first; - } - return i->second; - } - //--------------------------------------------------------------------- - WorkQueue::Request::Request(uint16 channel, uint16 rtype, const Any& rData, uint8 retry, RequestID rid) - : mChannel(channel), mType(rtype), mData(rData), mRetryCount(retry), mID(rid), mAborted(false) - { - - } - //--------------------------------------------------------------------- - WorkQueue::Request::~Request() - { - - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - WorkQueue::Response::Response(const Request* rq, bool success, const Any& data, const String& msg) - : mRequest(rq), mSuccess(success), mMessages(msg), mData(data) - { - - } - //--------------------------------------------------------------------- - WorkQueue::Response::~Response() - { - OGRE_DELETE mRequest; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - DefaultWorkQueueBase::DefaultWorkQueueBase(const String& name) - : mName(name) - , mWorkerThreadCount(1) - , mWorkerRenderSystemAccess(false) - , mIsRunning(false) - , mResposeTimeLimitMS(8) - , mWorkerFunc(0) - , mRequestCount(0) - , mPaused(false) - , mAcceptRequests(true) + ChannelMap::iterator i = mChannelMap.find(channelName); + if (i == mChannelMap.end()) + { + i = mChannelMap.insert(ChannelMap::value_type(channelName, mNextChannel++)).first; + } + return i->second; + } + //--------------------------------------------------------------------- + WorkQueue::Request::Request(uint16 channel, uint16 rtype, const Any& rData, uint8 retry, RequestID rid) + : mChannel(channel), mType(rtype), mData(rData), mRetryCount(retry), mID(rid), mAborted(false) + { + + } + //--------------------------------------------------------------------- + WorkQueue::Request::~Request() + { + + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + WorkQueue::Response::Response(const Request* rq, bool success, const Any& data, const String& msg) + : mRequest(rq), mSuccess(success), mMessages(msg), mData(data) + { + + } + //--------------------------------------------------------------------- + WorkQueue::Response::~Response() + { + OGRE_DELETE mRequest; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + DefaultWorkQueueBase::DefaultWorkQueueBase(const String& name) + : mName(name) + , mWorkerThreadCount(1) + , mWorkerRenderSystemAccess(false) + , mIsRunning(false) + , mResposeTimeLimitMS(8) + , mWorkerFunc(0) + , mRequestCount(0) + , mPaused(false) + , mAcceptRequests(true) , mShuttingDown(false) , mIdleThreadRunning(false) , mIdleProcessed(0) - { - } - //--------------------------------------------------------------------- - const String& DefaultWorkQueueBase::getName() const - { - return mName; - } - //--------------------------------------------------------------------- - size_t DefaultWorkQueueBase::getWorkerThreadCount() const - { - return mWorkerThreadCount; - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::setWorkerThreadCount(size_t c) - { - mWorkerThreadCount = c; - } - //--------------------------------------------------------------------- - bool DefaultWorkQueueBase::getWorkersCanAccessRenderSystem() const - { - return mWorkerRenderSystemAccess; - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::setWorkersCanAccessRenderSystem(bool access) - { - mWorkerRenderSystemAccess = access; - } - //--------------------------------------------------------------------- - DefaultWorkQueueBase::~DefaultWorkQueueBase() - { - //shutdown(); // can't call here; abstract function - - for (RequestQueue::iterator i = mRequestQueue.begin(); i != mRequestQueue.end(); ++i) - { - OGRE_DELETE (*i); - } - mRequestQueue.clear(); - - for (ResponseQueue::iterator i = mResponseQueue.begin(); i != mResponseQueue.end(); ++i) - { - OGRE_DELETE (*i); - } - mResponseQueue.clear(); - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::addRequestHandler(uint16 channel, RequestHandler* rh) - { + { + } + //--------------------------------------------------------------------- + const String& DefaultWorkQueueBase::getName() const + { + return mName; + } + //--------------------------------------------------------------------- + size_t DefaultWorkQueueBase::getWorkerThreadCount() const + { + return mWorkerThreadCount; + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::setWorkerThreadCount(size_t c) + { + mWorkerThreadCount = c; + } + //--------------------------------------------------------------------- + bool DefaultWorkQueueBase::getWorkersCanAccessRenderSystem() const + { + return mWorkerRenderSystemAccess; + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::setWorkersCanAccessRenderSystem(bool access) + { + mWorkerRenderSystemAccess = access; + } + //--------------------------------------------------------------------- + DefaultWorkQueueBase::~DefaultWorkQueueBase() + { + //shutdown(); // can't call here; abstract function + + for (RequestQueue::iterator i = mRequestQueue.begin(); i != mRequestQueue.end(); ++i) + { + OGRE_DELETE (*i); + } + mRequestQueue.clear(); + + for (ResponseQueue::iterator i = mResponseQueue.begin(); i != mResponseQueue.end(); ++i) + { + OGRE_DELETE (*i); + } + mResponseQueue.clear(); + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::addRequestHandler(uint16 channel, RequestHandler* rh) + { OGRE_LOCK_RW_MUTEX_WRITE(mRequestHandlerMutex); - RequestHandlerListByChannel::iterator i = mRequestHandlers.find(channel); - if (i == mRequestHandlers.end()) - i = mRequestHandlers.insert(RequestHandlerListByChannel::value_type(channel, RequestHandlerList())).first; - - RequestHandlerList& handlers = i->second; - bool duplicate = false; - for (RequestHandlerList::iterator j = handlers.begin(); j != handlers.end(); ++j) - { - if ((*j)->getHandler() == rh) - { - duplicate = true; - break; - } - } - if (!duplicate) - handlers.push_back(RequestHandlerHolderPtr(OGRE_NEW RequestHandlerHolder(rh))); - - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::removeRequestHandler(uint16 channel, RequestHandler* rh) - { - OGRE_LOCK_RW_MUTEX_WRITE(mRequestHandlerMutex); - - RequestHandlerListByChannel::iterator i = mRequestHandlers.find(channel); - if (i != mRequestHandlers.end()) - { - RequestHandlerList& handlers = i->second; - for (RequestHandlerList::iterator j = handlers.begin(); j != handlers.end(); ++j) - { - if ((*j)->getHandler() == rh) - { - // Disconnect - this will make it safe across copies of the list - // this is threadsafe and will wait for existing processes to finish - (*j)->disconnectHandler(); - handlers.erase(j); - break; - } - } - - } - - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::addResponseHandler(uint16 channel, ResponseHandler* rh) - { - ResponseHandlerListByChannel::iterator i = mResponseHandlers.find(channel); - if (i == mResponseHandlers.end()) - i = mResponseHandlers.insert(ResponseHandlerListByChannel::value_type(channel, ResponseHandlerList())).first; - - ResponseHandlerList& handlers = i->second; - if (std::find(handlers.begin(), handlers.end(), rh) == handlers.end()) - handlers.push_back(rh); - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::removeResponseHandler(uint16 channel, ResponseHandler* rh) - { - ResponseHandlerListByChannel::iterator i = mResponseHandlers.find(channel); - if (i != mResponseHandlers.end()) - { - ResponseHandlerList& handlers = i->second; - ResponseHandlerList::iterator j = std::find( - handlers.begin(), handlers.end(), rh); - if (j != handlers.end()) - handlers.erase(j); - - } - } - //--------------------------------------------------------------------- - WorkQueue::RequestID DefaultWorkQueueBase::addRequest(uint16 channel, uint16 requestType, - const Any& rData, uint8 retryCount, bool forceSynchronous, bool idleThread) - { - Request* req = 0; - RequestID rid = 0; - - { - // lock to acquire rid and push request to the queue + RequestHandlerListByChannel::iterator i = mRequestHandlers.find(channel); + if (i == mRequestHandlers.end()) + i = mRequestHandlers.insert(RequestHandlerListByChannel::value_type(channel, RequestHandlerList())).first; + + RequestHandlerList& handlers = i->second; + bool duplicate = false; + for (RequestHandlerList::iterator j = handlers.begin(); j != handlers.end(); ++j) + { + if ((*j)->getHandler() == rh) + { + duplicate = true; + break; + } + } + if (!duplicate) + handlers.push_back(RequestHandlerHolderPtr(OGRE_NEW RequestHandlerHolder(rh))); + + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::removeRequestHandler(uint16 channel, RequestHandler* rh) + { + OGRE_LOCK_RW_MUTEX_WRITE(mRequestHandlerMutex); + + RequestHandlerListByChannel::iterator i = mRequestHandlers.find(channel); + if (i != mRequestHandlers.end()) + { + RequestHandlerList& handlers = i->second; + for (RequestHandlerList::iterator j = handlers.begin(); j != handlers.end(); ++j) + { + if ((*j)->getHandler() == rh) + { + // Disconnect - this will make it safe across copies of the list + // this is threadsafe and will wait for existing processes to finish + (*j)->disconnectHandler(); + handlers.erase(j); + break; + } + } + + } + + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::addResponseHandler(uint16 channel, ResponseHandler* rh) + { + ResponseHandlerListByChannel::iterator i = mResponseHandlers.find(channel); + if (i == mResponseHandlers.end()) + i = mResponseHandlers.insert(ResponseHandlerListByChannel::value_type(channel, ResponseHandlerList())).first; + + ResponseHandlerList& handlers = i->second; + if (std::find(handlers.begin(), handlers.end(), rh) == handlers.end()) + handlers.push_back(rh); + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::removeResponseHandler(uint16 channel, ResponseHandler* rh) + { + ResponseHandlerListByChannel::iterator i = mResponseHandlers.find(channel); + if (i != mResponseHandlers.end()) + { + ResponseHandlerList& handlers = i->second; + ResponseHandlerList::iterator j = std::find( + handlers.begin(), handlers.end(), rh); + if (j != handlers.end()) + handlers.erase(j); + + } + } + //--------------------------------------------------------------------- + WorkQueue::RequestID DefaultWorkQueueBase::addRequest(uint16 channel, uint16 requestType, + const Any& rData, uint8 retryCount, bool forceSynchronous, bool idleThread) + { + Request* req = 0; + RequestID rid = 0; + + { + // lock to acquire rid and push request to the queue OGRE_LOCK_MUTEX(mRequestMutex); - if (!mAcceptRequests || mShuttingDown) - return 0; + if (!mAcceptRequests || mShuttingDown) + return 0; - rid = ++mRequestCount; - req = OGRE_NEW Request(channel, requestType, rData, retryCount, rid); + rid = ++mRequestCount; + req = OGRE_NEW Request(channel, requestType, rData, retryCount, rid); - LogManager::getSingleton().stream(LML_TRIVIAL) << - "DefaultWorkQueueBase('" << mName << "') - QUEUED(thread:" << + LogManager::getSingleton().stream(LML_TRIVIAL) << + "DefaultWorkQueueBase('" << mName << "') - QUEUED(thread:" << #if OGRE_THREAD_SUPPORT - OGRE_THREAD_CURRENT_ID + OGRE_THREAD_CURRENT_ID #else - "main" + "main" #endif - << "): ID=" << rid - << " channel=" << channel << " requestType=" << requestType; + << "): ID=" << rid + << " channel=" << channel << " requestType=" << requestType; #if OGRE_THREAD_SUPPORT - if (!forceSynchronous&& !idleThread) - { - mRequestQueue.push_back(req); - notifyWorkers(); - return rid; - } + if (!forceSynchronous&& !idleThread) + { + mRequestQueue.push_back(req); + notifyWorkers(); + return rid; + } #endif - } - if(OGRE_THREAD_SUPPORT && idleThread){ - OGRE_LOCK_MUTEX(mIdleMutex); - mIdleRequestQueue.push_back(req); - if(!mIdleThreadRunning) - { - notifyWorkers(); - } - } else { //forceSynchronous - processRequestResponse(req, true); - } - return rid; - - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::addRequestWithRID(WorkQueue::RequestID rid, uint16 channel, - uint16 requestType, const Any& rData, uint8 retryCount) - { - // lock to push request to the queue + } + if(OGRE_THREAD_SUPPORT && idleThread){ + OGRE_LOCK_MUTEX(mIdleMutex); + mIdleRequestQueue.push_back(req); + if(!mIdleThreadRunning) + { + notifyWorkers(); + } + } else { //forceSynchronous + processRequestResponse(req, true); + } + return rid; + + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::addRequestWithRID(WorkQueue::RequestID rid, uint16 channel, + uint16 requestType, const Any& rData, uint8 retryCount) + { + // lock to push request to the queue OGRE_LOCK_MUTEX(mRequestMutex); - if (mShuttingDown) - return; + if (mShuttingDown) + return; - Request* req = OGRE_NEW Request(channel, requestType, rData, retryCount, rid); + Request* req = OGRE_NEW Request(channel, requestType, rData, retryCount, rid); - LogManager::getSingleton().stream(LML_TRIVIAL) << - "DefaultWorkQueueBase('" << mName << "') - REQUEUED(thread:" << + LogManager::getSingleton().stream(LML_TRIVIAL) << + "DefaultWorkQueueBase('" << mName << "') - REQUEUED(thread:" << #if OGRE_THREAD_SUPPORT - OGRE_THREAD_CURRENT_ID + OGRE_THREAD_CURRENT_ID #else - "main" + "main" #endif - << "): ID=" << rid - << " channel=" << channel << " requestType=" << requestType; + << "): ID=" << rid + << " channel=" << channel << " requestType=" << requestType; #if OGRE_THREAD_SUPPORT - mRequestQueue.push_back(req); - notifyWorkers(); + mRequestQueue.push_back(req); + notifyWorkers(); #else - processRequestResponse(req, true); + processRequestResponse(req, true); #endif - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::abortRequest(RequestID id) - { + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::abortRequest(RequestID id) + { OGRE_LOCK_MUTEX(mProcessMutex); - // NOTE: Pending requests are exist any of RequestQueue, ProcessQueue and - // ResponseQueue when keeping ProcessMutex, so we check all of these queues. + // NOTE: Pending requests are exist any of RequestQueue, ProcessQueue and + // ResponseQueue when keeping ProcessMutex, so we check all of these queues. - for (RequestQueue::iterator i = mProcessQueue.begin(); i != mProcessQueue.end(); ++i) - { - if ((*i)->getID() == id) - { - (*i)->abortRequest(); - break; - } - } + for (RequestQueue::iterator i = mProcessQueue.begin(); i != mProcessQueue.end(); ++i) + { + if ((*i)->getID() == id) + { + (*i)->abortRequest(); + break; + } + } - { + { OGRE_LOCK_MUTEX(mRequestMutex); - for (RequestQueue::iterator i = mRequestQueue.begin(); i != mRequestQueue.end(); ++i) - { - if ((*i)->getID() == id) - { - (*i)->abortRequest(); - break; - } - } - } - - { - if(mIdleProcessed) - { - mIdleProcessed->abortRequest(); - } - - OGRE_LOCK_MUTEX(mIdleMutex); - for (RequestQueue::iterator i = mIdleRequestQueue.begin(); i != mIdleRequestQueue.end(); ++i) - { - (*i)->abortRequest(); - } - } - - { + for (RequestQueue::iterator i = mRequestQueue.begin(); i != mRequestQueue.end(); ++i) + { + if ((*i)->getID() == id) + { + (*i)->abortRequest(); + break; + } + } + } + + { + if(mIdleProcessed) + { + mIdleProcessed->abortRequest(); + } + + OGRE_LOCK_MUTEX(mIdleMutex); + for (RequestQueue::iterator i = mIdleRequestQueue.begin(); i != mIdleRequestQueue.end(); ++i) + { + (*i)->abortRequest(); + } + } + + { OGRE_LOCK_MUTEX(mResponseMutex); - for (ResponseQueue::iterator i = mResponseQueue.begin(); i != mResponseQueue.end(); ++i) - { - if( (*i)->getRequest()->getID() == id ) - { - (*i)->abortRequest(); - break; - } - } - } - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::abortRequestsByChannel(uint16 channel) - { + for (ResponseQueue::iterator i = mResponseQueue.begin(); i != mResponseQueue.end(); ++i) + { + if( (*i)->getRequest()->getID() == id ) + { + (*i)->abortRequest(); + break; + } + } + } + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::abortRequestsByChannel(uint16 channel) + { OGRE_LOCK_MUTEX(mProcessMutex); - for (RequestQueue::iterator i = mProcessQueue.begin(); i != mProcessQueue.end(); ++i) - { - if ((*i)->getChannel() == channel) - { - (*i)->abortRequest(); - } - } + for (RequestQueue::iterator i = mProcessQueue.begin(); i != mProcessQueue.end(); ++i) + { + if ((*i)->getChannel() == channel) + { + (*i)->abortRequest(); + } + } - { + { OGRE_LOCK_MUTEX(mRequestMutex); - for (RequestQueue::iterator i = mRequestQueue.begin(); i != mRequestQueue.end(); ++i) - { - if ((*i)->getChannel() == channel) - { - (*i)->abortRequest(); - } - } - } - { - if (mIdleProcessed && mIdleProcessed->getChannel() == channel) - { - mIdleProcessed->abortRequest(); - } - - OGRE_LOCK_MUTEX(mIdleMutex); - - for (RequestQueue::iterator i = mIdleRequestQueue.begin(); i != mIdleRequestQueue.end(); ++i) - { - if ((*i)->getChannel() == channel) - { - (*i)->abortRequest(); - } - } - } - - { + for (RequestQueue::iterator i = mRequestQueue.begin(); i != mRequestQueue.end(); ++i) + { + if ((*i)->getChannel() == channel) + { + (*i)->abortRequest(); + } + } + } + { + if (mIdleProcessed && mIdleProcessed->getChannel() == channel) + { + mIdleProcessed->abortRequest(); + } + + OGRE_LOCK_MUTEX(mIdleMutex); + + for (RequestQueue::iterator i = mIdleRequestQueue.begin(); i != mIdleRequestQueue.end(); ++i) + { + if ((*i)->getChannel() == channel) + { + (*i)->abortRequest(); + } + } + } + + { OGRE_LOCK_MUTEX(mResponseMutex); - for (ResponseQueue::iterator i = mResponseQueue.begin(); i != mResponseQueue.end(); ++i) - { - if( (*i)->getRequest()->getChannel() == channel ) - { - (*i)->abortRequest(); - } - } - } - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::abortPendingRequestsByChannel(uint16 channel) - { - { + for (ResponseQueue::iterator i = mResponseQueue.begin(); i != mResponseQueue.end(); ++i) + { + if( (*i)->getRequest()->getChannel() == channel ) + { + (*i)->abortRequest(); + } + } + } + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::abortPendingRequestsByChannel(uint16 channel) + { + { OGRE_LOCK_MUTEX(mRequestMutex); - for (RequestQueue::iterator i = mRequestQueue.begin(); i != mRequestQueue.end(); ++i) - { - if ((*i)->getChannel() == channel) - { - (*i)->abortRequest(); - } - } - } - { + for (RequestQueue::iterator i = mRequestQueue.begin(); i != mRequestQueue.end(); ++i) + { + if ((*i)->getChannel() == channel) + { + (*i)->abortRequest(); + } + } + } + { OGRE_LOCK_MUTEX(mIdleMutex); - for (RequestQueue::iterator i = mIdleRequestQueue.begin(); i != mIdleRequestQueue.end(); ++i) - { - if ((*i)->getChannel() == channel) - { - (*i)->abortRequest(); - } - } - } - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::abortAllRequests() - { + for (RequestQueue::iterator i = mIdleRequestQueue.begin(); i != mIdleRequestQueue.end(); ++i) + { + if ((*i)->getChannel() == channel) + { + (*i)->abortRequest(); + } + } + } + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::abortAllRequests() + { OGRE_LOCK_MUTEX(mProcessMutex); - { - for (RequestQueue::iterator i = mProcessQueue.begin(); i != mProcessQueue.end(); ++i) - { - (*i)->abortRequest(); - } - } - - - { + { + for (RequestQueue::iterator i = mProcessQueue.begin(); i != mProcessQueue.end(); ++i) + { + (*i)->abortRequest(); + } + } + + + { OGRE_LOCK_MUTEX(mRequestMutex); - for (RequestQueue::iterator i = mRequestQueue.begin(); i != mRequestQueue.end(); ++i) - { - (*i)->abortRequest(); - } - } + for (RequestQueue::iterator i = mRequestQueue.begin(); i != mRequestQueue.end(); ++i) + { + (*i)->abortRequest(); + } + } - { + { - if(mIdleProcessed) - { - mIdleProcessed->abortRequest(); - } + if(mIdleProcessed) + { + mIdleProcessed->abortRequest(); + } - OGRE_LOCK_MUTEX(mIdleMutex); + OGRE_LOCK_MUTEX(mIdleMutex); - for (RequestQueue::iterator i = mIdleRequestQueue.begin(); i != mIdleRequestQueue.end(); ++i) - { - (*i)->abortRequest(); - } - } + for (RequestQueue::iterator i = mIdleRequestQueue.begin(); i != mIdleRequestQueue.end(); ++i) + { + (*i)->abortRequest(); + } + } - { + { OGRE_LOCK_MUTEX(mResponseMutex); - for (ResponseQueue::iterator i = mResponseQueue.begin(); i != mResponseQueue.end(); ++i) - { - (*i)->abortRequest(); - } - } + for (ResponseQueue::iterator i = mResponseQueue.begin(); i != mResponseQueue.end(); ++i) + { + (*i)->abortRequest(); + } + } - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::setPaused(bool pause) - { + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::setPaused(bool pause) + { OGRE_LOCK_MUTEX(mRequestMutex); - mPaused = pause; - } - //--------------------------------------------------------------------- - bool DefaultWorkQueueBase::isPaused() const - { - return mPaused; - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::setRequestsAccepted(bool accept) - { + mPaused = pause; + } + //--------------------------------------------------------------------- + bool DefaultWorkQueueBase::isPaused() const + { + return mPaused; + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::setRequestsAccepted(bool accept) + { OGRE_LOCK_MUTEX(mRequestMutex); - mAcceptRequests = accept; - } - //--------------------------------------------------------------------- - bool DefaultWorkQueueBase::getRequestsAccepted() const - { - return mAcceptRequests; - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::_processNextRequest() - { - if(processIdleRequests()){ - // Found idle requests. - return; - } - Request* request = 0; - { - // scoped to only lock while retrieving the next request + mAcceptRequests = accept; + } + //--------------------------------------------------------------------- + bool DefaultWorkQueueBase::getRequestsAccepted() const + { + return mAcceptRequests; + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::_processNextRequest() + { + if(processIdleRequests()){ + // Found idle requests. + return; + } + Request* request = 0; + { + // scoped to only lock while retrieving the next request OGRE_LOCK_MUTEX(mProcessMutex); - { + { OGRE_LOCK_MUTEX(mRequestMutex); - if (!mRequestQueue.empty()) - { - request = mRequestQueue.front(); - mRequestQueue.pop_front(); - mProcessQueue.push_back( request ); - } - } - } - - if (request) - { - processRequestResponse(request, false); - } - - - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::processRequestResponse(Request* r, bool synchronous) - { - Response* response = processRequest(r); - - OGRE_LOCK_MUTEX(mProcessMutex); - - RequestQueue::iterator it; - for( it = mProcessQueue.begin(); it != mProcessQueue.end(); ++it ) - { - if( (*it) == r ) - { - mProcessQueue.erase( it ); - break; - } - } - if( mIdleProcessed == r ) - { - mIdleProcessed = 0; - } - if (response) - { - if (!response->succeeded()) - { - // Failed, should we retry? - const Request* req = response->getRequest(); - if (req->getRetryCount()) - { - addRequestWithRID(req->getID(), req->getChannel(), req->getType(), req->getData(), - req->getRetryCount() - 1); - // discard response (this also deletes request) - OGRE_DELETE response; - return; - } - } - if (synchronous) - { - processResponse(response); - OGRE_DELETE response; - } - else - { - if( response->getRequest()->getAborted() ) - { - // destroy response user data - response->abortRequest(); - } - // Queue response - OGRE_LOCK_MUTEX(mResponseMutex); - mResponseQueue.push_back(response); - // no need to wake thread, this is processed by the main thread - } - - } - else - { - if (!r->getAborted()) - { - // no response, delete request - LogManager::getSingleton().stream() << - "DefaultWorkQueueBase('" << mName << "') warning: no handler processed request " - << r->getID() << ", channel " << r->getChannel() - << ", type " << r->getType(); - } - OGRE_DELETE r; - } - - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::processResponses() - { - unsigned long msStart = Root::getSingleton().getTimer()->getMilliseconds(); - unsigned long msCurrent = 0; - - // keep going until we run out of responses or out of time - while(true) - { - Response* response = 0; - { + if (!mRequestQueue.empty()) + { + request = mRequestQueue.front(); + mRequestQueue.pop_front(); + mProcessQueue.push_back( request ); + } + } + } + + if (request) + { + processRequestResponse(request, false); + } + + + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::processRequestResponse(Request* r, bool synchronous) + { + Response* response = processRequest(r); + + OGRE_LOCK_MUTEX(mProcessMutex); + + RequestQueue::iterator it; + for( it = mProcessQueue.begin(); it != mProcessQueue.end(); ++it ) + { + if( (*it) == r ) + { + mProcessQueue.erase( it ); + break; + } + } + if( mIdleProcessed == r ) + { + mIdleProcessed = 0; + } + if (response) + { + if (!response->succeeded()) + { + // Failed, should we retry? + const Request* req = response->getRequest(); + if (req->getRetryCount()) + { + addRequestWithRID(req->getID(), req->getChannel(), req->getType(), req->getData(), + req->getRetryCount() - 1); + // discard response (this also deletes request) + OGRE_DELETE response; + return; + } + } + if (synchronous) + { + processResponse(response); + OGRE_DELETE response; + } + else + { + if( response->getRequest()->getAborted() ) + { + // destroy response user data + response->abortRequest(); + } + // Queue response + OGRE_LOCK_MUTEX(mResponseMutex); + mResponseQueue.push_back(response); + // no need to wake thread, this is processed by the main thread + } + + } + else + { + if (!r->getAborted()) + { + // no response, delete request + LogManager::getSingleton().stream() << + "DefaultWorkQueueBase('" << mName << "') warning: no handler processed request " + << r->getID() << ", channel " << r->getChannel() + << ", type " << r->getType(); + } + OGRE_DELETE r; + } + + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::processResponses() + { + unsigned long msStart = Root::getSingleton().getTimer()->getMilliseconds(); + unsigned long msCurrent = 0; + + // keep going until we run out of responses or out of time + while(true) + { + Response* response = 0; + { OGRE_LOCK_MUTEX(mResponseMutex); - if (mResponseQueue.empty()) - break; // exit loop - else - { - response = mResponseQueue.front(); - mResponseQueue.pop_front(); - } - } - - if (response) - { - processResponse(response); - - OGRE_DELETE response; - - } - - // time limit - if (mResposeTimeLimitMS) - { - msCurrent = Root::getSingleton().getTimer()->getMilliseconds(); - if (msCurrent - msStart > mResposeTimeLimitMS) - break; - } - } - } - //--------------------------------------------------------------------- - WorkQueue::Response* DefaultWorkQueueBase::processRequest(Request* r) - { - RequestHandlerListByChannel handlerListCopy; - { - // lock the list only to make a copy of it, to maximise parallelism + if (mResponseQueue.empty()) + break; // exit loop + else + { + response = mResponseQueue.front(); + mResponseQueue.pop_front(); + } + } + + if (response) + { + processResponse(response); + + OGRE_DELETE response; + + } + + // time limit + if (mResposeTimeLimitMS) + { + msCurrent = Root::getSingleton().getTimer()->getMilliseconds(); + if (msCurrent - msStart > mResposeTimeLimitMS) + break; + } + } + } + //--------------------------------------------------------------------- + WorkQueue::Response* DefaultWorkQueueBase::processRequest(Request* r) + { + RequestHandlerListByChannel handlerListCopy; + { + // lock the list only to make a copy of it, to maximise parallelism OGRE_LOCK_RW_MUTEX_READ(mRequestHandlerMutex); - - handlerListCopy = mRequestHandlers; - - } + + handlerListCopy = mRequestHandlers; + + } - Response* response = 0; + Response* response = 0; - StringStream dbgMsg; - dbgMsg << + StringStream dbgMsg; + dbgMsg << #if OGRE_THREAD_SUPPORT - OGRE_THREAD_CURRENT_ID + OGRE_THREAD_CURRENT_ID #else - "main" + "main" #endif - << "): ID=" << r->getID() << " channel=" << r->getChannel() - << " requestType=" << r->getType(); - - LogManager::getSingleton().stream(LML_TRIVIAL) << - "DefaultWorkQueueBase('" << mName << "') - PROCESS_REQUEST_START(" << dbgMsg.str(); - - RequestHandlerListByChannel::iterator i = handlerListCopy.find(r->getChannel()); - if (i != handlerListCopy.end()) - { - RequestHandlerList& handlers = i->second; - for (RequestHandlerList::reverse_iterator j = handlers.rbegin(); j != handlers.rend(); ++j) - { - // threadsafe call which tests canHandleRequest and calls it if so - response = (*j)->handleRequest(r, this); - - if (response) - break; - } - } - - LogManager::getSingleton().stream(LML_TRIVIAL) << - "DefaultWorkQueueBase('" << mName << "') - PROCESS_REQUEST_END(" << dbgMsg.str() - << " processed=" << (response!=0); - - return response; - - } - //--------------------------------------------------------------------- - void DefaultWorkQueueBase::processResponse(Response* r) - { - StringStream dbgMsg; - dbgMsg << "thread:" << + << "): ID=" << r->getID() << " channel=" << r->getChannel() + << " requestType=" << r->getType(); + + LogManager::getSingleton().stream(LML_TRIVIAL) << + "DefaultWorkQueueBase('" << mName << "') - PROCESS_REQUEST_START(" << dbgMsg.str(); + + RequestHandlerListByChannel::iterator i = handlerListCopy.find(r->getChannel()); + if (i != handlerListCopy.end()) + { + RequestHandlerList& handlers = i->second; + for (RequestHandlerList::reverse_iterator j = handlers.rbegin(); j != handlers.rend(); ++j) + { + // threadsafe call which tests canHandleRequest and calls it if so + response = (*j)->handleRequest(r, this); + + if (response) + break; + } + } + + LogManager::getSingleton().stream(LML_TRIVIAL) << + "DefaultWorkQueueBase('" << mName << "') - PROCESS_REQUEST_END(" << dbgMsg.str() + << " processed=" << (response!=0); + + return response; + + } + //--------------------------------------------------------------------- + void DefaultWorkQueueBase::processResponse(Response* r) + { + StringStream dbgMsg; + dbgMsg << "thread:" << #if OGRE_THREAD_SUPPORT - OGRE_THREAD_CURRENT_ID + OGRE_THREAD_CURRENT_ID #else - "main" + "main" #endif - << "): ID=" << r->getRequest()->getID() - << " success=" << r->succeeded() << " messages=[" << r->getMessages() << "] channel=" - << r->getRequest()->getChannel() << " requestType=" << r->getRequest()->getType(); - - LogManager::getSingleton().stream(LML_TRIVIAL) << - "DefaultWorkQueueBase('" << mName << "') - PROCESS_RESPONSE_START(" << dbgMsg.str(); - - ResponseHandlerListByChannel::iterator i = mResponseHandlers.find(r->getRequest()->getChannel()); - if (i != mResponseHandlers.end()) - { - ResponseHandlerList& handlers = i->second; - for (ResponseHandlerList::reverse_iterator j = handlers.rbegin(); j != handlers.rend(); ++j) - { - if ((*j)->canHandleResponse(r, this)) - { - (*j)->handleResponse(r, this); - } - } - } - LogManager::getSingleton().stream(LML_TRIVIAL) << - "DefaultWorkQueueBase('" << mName << "') - PROCESS_RESPONSE_END(" << dbgMsg.str(); - - } - - bool DefaultWorkQueueBase::processIdleRequests() - { - { + << "): ID=" << r->getRequest()->getID() + << " success=" << r->succeeded() << " messages=[" << r->getMessages() << "] channel=" + << r->getRequest()->getChannel() << " requestType=" << r->getRequest()->getType(); + + LogManager::getSingleton().stream(LML_TRIVIAL) << + "DefaultWorkQueueBase('" << mName << "') - PROCESS_RESPONSE_START(" << dbgMsg.str(); + + ResponseHandlerListByChannel::iterator i = mResponseHandlers.find(r->getRequest()->getChannel()); + if (i != mResponseHandlers.end()) + { + ResponseHandlerList& handlers = i->second; + for (ResponseHandlerList::reverse_iterator j = handlers.rbegin(); j != handlers.rend(); ++j) + { + if ((*j)->canHandleResponse(r, this)) + { + (*j)->handleResponse(r, this); + } + } + } + LogManager::getSingleton().stream(LML_TRIVIAL) << + "DefaultWorkQueueBase('" << mName << "') - PROCESS_RESPONSE_END(" << dbgMsg.str(); + + } + + bool DefaultWorkQueueBase::processIdleRequests() + { + { OGRE_LOCK_MUTEX(mIdleMutex); - if(mIdleRequestQueue.empty() || mIdleThreadRunning){ - return false; - } else { - mIdleThreadRunning = true; - } - } - try { - while(1){ - { + if(mIdleRequestQueue.empty() || mIdleThreadRunning){ + return false; + } else { + mIdleThreadRunning = true; + } + } + try { + while(1){ + { OGRE_LOCK_MUTEX(mProcessMutex); // mProcessMutex needs to be the top mutex to prevent livelocks - { + { OGRE_LOCK_MUTEX(mIdleMutex); - if(!mIdleRequestQueue.empty()){ - mIdleProcessed = mIdleRequestQueue.front(); - mIdleRequestQueue.pop_front(); - } else { - mIdleProcessed = 0; - mIdleThreadRunning = false; - return true; - } - } - } - processRequestResponse(mIdleProcessed, false); - } - } catch (...) { // Normally this should not happen. - { - // It is very important to clean up or the idle thread will be locked forever! + if(!mIdleRequestQueue.empty()){ + mIdleProcessed = mIdleRequestQueue.front(); + mIdleRequestQueue.pop_front(); + } else { + mIdleProcessed = 0; + mIdleThreadRunning = false; + return true; + } + } + } + processRequestResponse(mIdleProcessed, false); + } + } catch (...) { // Normally this should not happen. + { + // It is very important to clean up or the idle thread will be locked forever! OGRE_LOCK_MUTEX(mProcessMutex); - { + { OGRE_LOCK_MUTEX(mIdleMutex); - if(mIdleProcessed){ - mIdleProcessed->abortRequest(); - } - mIdleProcessed = 0; - mIdleThreadRunning = false; - } - } - Ogre::LogManager::getSingleton().stream() << "Exception caught in top of worker thread!"; - - return true; - } - } - - - //--------------------------------------------------------------------- - - void DefaultWorkQueueBase::WorkerFunc::operator()() - { - mQueue->_threadMain(); - } - - void DefaultWorkQueueBase::WorkerFunc::operator()() const - { - mQueue->_threadMain(); - } - - void DefaultWorkQueueBase::WorkerFunc::run() - { - mQueue->_threadMain(); - } + if(mIdleProcessed){ + mIdleProcessed->abortRequest(); + } + mIdleProcessed = 0; + mIdleThreadRunning = false; + } + } + Ogre::LogManager::getSingleton().stream() << "Exception caught in top of worker thread!"; + + return true; + } + } + + + //--------------------------------------------------------------------- + + void DefaultWorkQueueBase::WorkerFunc::operator()() + { + mQueue->_threadMain(); + } + + void DefaultWorkQueueBase::WorkerFunc::operator()() const + { + mQueue->_threadMain(); + } + + void DefaultWorkQueueBase::WorkerFunc::run() + { + mQueue->_threadMain(); + } } diff --git a/OgreMain/src/OgreZip.cpp b/OgreMain/src/OgreZip.cpp index 77f5dd5a26c..10e0dd37490 100644 --- a/OgreMain/src/OgreZip.cpp +++ b/OgreMain/src/OgreZip.cpp @@ -83,7 +83,7 @@ namespace Ogre { //----------------------------------------------------------------------- void ZipArchive::load() { - OGRE_LOCK_AUTO_MUTEX; + OGRE_LOCK_AUTO_MUTEX; if (!mZzipDir) { zzip_error_t zzipError; @@ -95,7 +95,7 @@ namespace Ogre { while (zzip_dir_read(mZzipDir, &zzipEntry)) { FileInfo info; - info.archive = this; + info.archive = this; // Get basename / path StringUtil::splitFilename(zzipEntry.d_name, info.basename, info.path); info.filename = zzipEntry.d_name; @@ -111,10 +111,10 @@ namespace Ogre { // the compressed size of a folder, and if he does, its useless anyway info.compressedSize = size_t (-1); } - else - { - info.filename = info.basename; - } + else + { + info.filename = info.basename; + } mFileList.push_back(info); } @@ -124,7 +124,7 @@ namespace Ogre { //----------------------------------------------------------------------- void ZipArchive::unload() { - OGRE_LOCK_AUTO_MUTEX; + OGRE_LOCK_AUTO_MUTEX; if (mZzipDir) { zzip_dir_close(mZzipDir); @@ -134,10 +134,10 @@ namespace Ogre { } //----------------------------------------------------------------------- - DataStreamPtr ZipArchive::open(const String& filename, bool readOnly) const + DataStreamPtr ZipArchive::open(const String& filename, bool readOnly) const { - // zziplib is not threadsafe - OGRE_LOCK_AUTO_MUTEX; + // zziplib is not threadsafe + OGRE_LOCK_AUTO_MUTEX; String lookUpFileName = filename; // Format not used here (always binary) @@ -155,40 +155,40 @@ namespace Ogre { } if (!zzipFile) - { + { int zerr = zzip_error(mZzipDir); String zzDesc = getZzipErrorDescription((zzip_error_t)zerr); LogManager::getSingleton().logMessage( mName + " - Unable to open file " + lookUpFileName + ", error was '" + zzDesc + "'", LML_CRITICAL); - // return null pointer - return DataStreamPtr(); - } + // return null pointer + return DataStreamPtr(); + } - // Get uncompressed size too - ZZIP_STAT zstat; - zzip_dir_stat(mZzipDir, lookUpFileName.c_str(), &zstat, ZZIP_CASEINSENSITIVE); + // Get uncompressed size too + ZZIP_STAT zstat; + zzip_dir_stat(mZzipDir, lookUpFileName.c_str(), &zstat, ZZIP_CASEINSENSITIVE); // Construct & return stream return DataStreamPtr(OGRE_NEW ZipDataStream(lookUpFileName, zzipFile, static_cast(zstat.st_size))); } - //--------------------------------------------------------------------- - DataStreamPtr ZipArchive::create(const String& filename) const - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "Modification of zipped archives is not supported", - "ZipArchive::create"); + //--------------------------------------------------------------------- + DataStreamPtr ZipArchive::create(const String& filename) const + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "Modification of zipped archives is not supported", + "ZipArchive::create"); - } - //--------------------------------------------------------------------- - void ZipArchive::remove(const String& filename) const - { - } + } + //--------------------------------------------------------------------- + void ZipArchive::remove(const String& filename) const + { + } //----------------------------------------------------------------------- StringVectorPtr ZipArchive::list(bool recursive, bool dirs) { - OGRE_LOCK_AUTO_MUTEX; + OGRE_LOCK_AUTO_MUTEX; StringVectorPtr ret = StringVectorPtr(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); FileInfoList::iterator i, iend; @@ -203,7 +203,7 @@ namespace Ogre { //----------------------------------------------------------------------- FileInfoListPtr ZipArchive::listFileInfo(bool recursive, bool dirs) { - OGRE_LOCK_AUTO_MUTEX; + OGRE_LOCK_AUTO_MUTEX; FileInfoList* fil = OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(); FileInfoList::const_iterator i, iend; iend = mFileList.end(); @@ -217,13 +217,13 @@ namespace Ogre { //----------------------------------------------------------------------- StringVectorPtr ZipArchive::find(const String& pattern, bool recursive, bool dirs) { - OGRE_LOCK_AUTO_MUTEX; + OGRE_LOCK_AUTO_MUTEX; StringVectorPtr ret = StringVectorPtr(OGRE_NEW_T(StringVector, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); // If pattern contains a directory name, do a full match bool full_match = (pattern.find ('/') != String::npos) || (pattern.find ('\\') != String::npos); - bool wildCard = pattern.find("*") != String::npos; - + bool wildCard = pattern.find("*") != String::npos; + FileInfoList::iterator i, iend; iend = mFileList.end(); for (i = mFileList.begin(); i != iend; ++i) @@ -236,15 +236,15 @@ namespace Ogre { return ret; } //----------------------------------------------------------------------- - FileInfoListPtr ZipArchive::findFileInfo(const String& pattern, + FileInfoListPtr ZipArchive::findFileInfo(const String& pattern, bool recursive, bool dirs) const { - OGRE_LOCK_AUTO_MUTEX; + OGRE_LOCK_AUTO_MUTEX; FileInfoListPtr ret = FileInfoListPtr(OGRE_NEW_T(FileInfoList, MEMCATEGORY_GENERAL)(), SPFM_DELETE_T); // If pattern contains a directory name, do a full match bool full_match = (pattern.find ('/') != String::npos) || (pattern.find ('\\') != String::npos); - bool wildCard = pattern.find("*") != String::npos; + bool wildCard = pattern.find("*") != String::npos; FileInfoList::const_iterator i, iend; iend = mFileList.end(); @@ -258,45 +258,45 @@ namespace Ogre { return ret; } //----------------------------------------------------------------------- - struct FileNameCompare : public std::binary_function - { - bool operator()(const Ogre::FileInfo& lhs, const String& filename) const - { - return lhs.filename == filename; - } - }; - //----------------------------------------------------------------------- - bool ZipArchive::exists(const String& filename) - { - OGRE_LOCK_AUTO_MUTEX; - String cleanName = filename; - if(filename.rfind("/") != String::npos) - { - StringVector tokens = StringUtil::split(filename, "/"); - cleanName = tokens[tokens.size() - 1]; - } - - return std::find_if (mFileList.begin(), mFileList.end(), std::bind2nd(FileNameCompare(), cleanName)) != mFileList.end(); - } - //--------------------------------------------------------------------- - time_t ZipArchive::getModifiedTime(const String& filename) - { - // Zziplib doesn't yet support getting the modification time of individual files - // so just check the mod time of the zip itself - struct stat tagStat; - bool ret = (stat(mName.c_str(), &tagStat) == 0); - - if (ret) - { - return tagStat.st_mtime; - } - else - { - return 0; - } - - } - //----------------------------------------------------------------------- + struct FileNameCompare : public std::binary_function + { + bool operator()(const Ogre::FileInfo& lhs, const String& filename) const + { + return lhs.filename == filename; + } + }; + //----------------------------------------------------------------------- + bool ZipArchive::exists(const String& filename) + { + OGRE_LOCK_AUTO_MUTEX; + String cleanName = filename; + if(filename.rfind("/") != String::npos) + { + StringVector tokens = StringUtil::split(filename, "/"); + cleanName = tokens[tokens.size() - 1]; + } + + return std::find_if (mFileList.begin(), mFileList.end(), std::bind2nd(FileNameCompare(), cleanName)) != mFileList.end(); + } + //--------------------------------------------------------------------- + time_t ZipArchive::getModifiedTime(const String& filename) + { + // Zziplib doesn't yet support getting the modification time of individual files + // so just check the mod time of the zip itself + struct stat tagStat; + bool ret = (stat(mName.c_str(), &tagStat) == 0); + + if (ret) + { + return tagStat.st_mtime; + } + else + { + return 0; + } + + } + //----------------------------------------------------------------------- void ZipArchive::checkZzipError(int zzipError, const String& operation) const { if (zzipError != ZZIP_NO_ERROR) @@ -314,83 +314,83 @@ namespace Ogre { ZipDataStream::ZipDataStream(ZZIP_FILE* zzipFile, size_t uncompressedSize) : mZzipFile(zzipFile) { - mSize = uncompressedSize; + mSize = uncompressedSize; } //----------------------------------------------------------------------- ZipDataStream::ZipDataStream(const String& name, ZZIP_FILE* zzipFile, size_t uncompressedSize) :DataStream(name), mZzipFile(zzipFile) { - mSize = uncompressedSize; + mSize = uncompressedSize; } //----------------------------------------------------------------------- - ZipDataStream::~ZipDataStream() - { - close(); - } + ZipDataStream::~ZipDataStream() + { + close(); + } //----------------------------------------------------------------------- size_t ZipDataStream::read(void* buf, size_t count) { - size_t was_avail = mCache.read(buf, count); - zzip_ssize_t r = 0; - if (was_avail < count) - { - r = zzip_file_read(mZzipFile, (char*)buf + was_avail, count - was_avail); - if (r<0) { - ZZIP_DIR *dir = zzip_dirhandle(mZzipFile); - String msg = zzip_strerror_of(dir); - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - mName+" - error from zziplib: "+msg, - "ZipDataStream::read"); - } - mCache.cacheData((char*)buf + was_avail, (size_t)r); - } - return was_avail + (size_t)r; - } - //--------------------------------------------------------------------- - size_t ZipDataStream::write(void* buf, size_t count) - { - // not supported - return 0; - } + size_t was_avail = mCache.read(buf, count); + zzip_ssize_t r = 0; + if (was_avail < count) + { + r = zzip_file_read(mZzipFile, (char*)buf + was_avail, count - was_avail); + if (r<0) { + ZZIP_DIR *dir = zzip_dirhandle(mZzipFile); + String msg = zzip_strerror_of(dir); + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + mName+" - error from zziplib: "+msg, + "ZipDataStream::read"); + } + mCache.cacheData((char*)buf + was_avail, (size_t)r); + } + return was_avail + (size_t)r; + } + //--------------------------------------------------------------------- + size_t ZipDataStream::write(void* buf, size_t count) + { + // not supported + return 0; + } //----------------------------------------------------------------------- void ZipDataStream::skip(long count) { long was_avail = static_cast(mCache.avail()); - if (count > 0) - { - if (!mCache.ff(count)) - zzip_seek(mZzipFile, static_cast(count - was_avail), SEEK_CUR); - } - else if (count < 0) - { - if (!mCache.rewind((size_t)(-count))) - zzip_seek(mZzipFile, static_cast(count + was_avail), SEEK_CUR); - } + if (count > 0) + { + if (!mCache.ff(count)) + zzip_seek(mZzipFile, static_cast(count - was_avail), SEEK_CUR); + } + else if (count < 0) + { + if (!mCache.rewind((size_t)(-count))) + zzip_seek(mZzipFile, static_cast(count + was_avail), SEEK_CUR); + } } //----------------------------------------------------------------------- void ZipDataStream::seek( size_t pos ) { - zzip_off_t newPos = static_cast(pos); - zzip_off_t prevPos = static_cast(tell()); - if (prevPos < 0) - { - // seek set after invalid pos - mCache.clear(); - zzip_seek(mZzipFile, newPos, SEEK_SET); - } - else - { - // everything is going all right, relative seek - skip((long)(newPos - prevPos)); - } + zzip_off_t newPos = static_cast(pos); + zzip_off_t prevPos = static_cast(tell()); + if (prevPos < 0) + { + // seek set after invalid pos + mCache.clear(); + zzip_seek(mZzipFile, newPos, SEEK_SET); + } + else + { + // everything is going all right, relative seek + skip((long)(newPos - prevPos)); + } } //----------------------------------------------------------------------- size_t ZipDataStream::tell(void) const { - zzip_off_t pos = zzip_tell(mZzipFile); - if (pos<0) - return (size_t)(-1); - return static_cast(pos) - mCache.avail(); + zzip_off_t pos = zzip_tell(mZzipFile); + if (pos<0) + return (size_t)(-1); + return static_cast(pos) - mCache.avail(); } //----------------------------------------------------------------------- bool ZipDataStream::eof(void) const @@ -400,12 +400,12 @@ namespace Ogre { //----------------------------------------------------------------------- void ZipDataStream::close(void) { - if (mZzipFile != 0) - { - zzip_file_close(mZzipFile); - mZzipFile = 0; - } - mCache.clear(); + if (mZzipFile != 0) + { + zzip_file_close(mZzipFile); + mZzipFile = 0; + } + mCache.clear(); } //----------------------------------------------------------------------- //----------------------------------------------------------------------- diff --git a/OgreMain/src/Threading/OgreDefaultWorkQueueStandard.cpp b/OgreMain/src/Threading/OgreDefaultWorkQueueStandard.cpp index ef4b3021052..e709beaf060 100644 --- a/OgreMain/src/Threading/OgreDefaultWorkQueueStandard.cpp +++ b/OgreMain/src/Threading/OgreDefaultWorkQueueStandard.cpp @@ -33,163 +33,163 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - DefaultWorkQueue::DefaultWorkQueue(const String& name) - : DefaultWorkQueueBase(name), mNumThreadsRegisteredWithRS(0) - { - } - //--------------------------------------------------------------------- - DefaultWorkQueue::~DefaultWorkQueue() - { - shutdown(); - } - //--------------------------------------------------------------------- - void DefaultWorkQueue::startup(bool forceRestart) - { - if (mIsRunning) - { - if (forceRestart) - shutdown(); - else - return; - } - - mShuttingDown = false; - - mWorkerFunc = OGRE_NEW_T(WorkerFunc(this), MEMCATEGORY_GENERAL); - - LogManager::getSingleton().stream() << - "DefaultWorkQueue('" << mName << "') initialising on thread " << + //--------------------------------------------------------------------- + DefaultWorkQueue::DefaultWorkQueue(const String& name) + : DefaultWorkQueueBase(name), mNumThreadsRegisteredWithRS(0) + { + } + //--------------------------------------------------------------------- + DefaultWorkQueue::~DefaultWorkQueue() + { + shutdown(); + } + //--------------------------------------------------------------------- + void DefaultWorkQueue::startup(bool forceRestart) + { + if (mIsRunning) + { + if (forceRestart) + shutdown(); + else + return; + } + + mShuttingDown = false; + + mWorkerFunc = OGRE_NEW_T(WorkerFunc(this), MEMCATEGORY_GENERAL); + + LogManager::getSingleton().stream() << + "DefaultWorkQueue('" << mName << "') initialising on thread " << #if OGRE_THREAD_SUPPORT - OGRE_THREAD_CURRENT_ID + OGRE_THREAD_CURRENT_ID #else - "main" + "main" #endif - << "."; + << "."; #if OGRE_THREAD_SUPPORT - if (mWorkerRenderSystemAccess) - Root::getSingleton().getRenderSystem()->preExtraThreadsStarted(); - - mNumThreadsRegisteredWithRS = 0; - for (uint8 i = 0; i < mWorkerThreadCount; ++i) - { - OGRE_THREAD_CREATE(t, *mWorkerFunc); - mWorkers.push_back(t); - } - - if (mWorkerRenderSystemAccess) - { + if (mWorkerRenderSystemAccess) + Root::getSingleton().getRenderSystem()->preExtraThreadsStarted(); + + mNumThreadsRegisteredWithRS = 0; + for (uint8 i = 0; i < mWorkerThreadCount; ++i) + { + OGRE_THREAD_CREATE(t, *mWorkerFunc); + mWorkers.push_back(t); + } + + if (mWorkerRenderSystemAccess) + { OGRE_LOCK_MUTEX_NAMED(mInitMutex, initLock); - // have to wait until all threads are registered with the render system - while (mNumThreadsRegisteredWithRS < mWorkerThreadCount) - OGRE_THREAD_WAIT(mInitSync, mInitMutex, initLock); + // have to wait until all threads are registered with the render system + while (mNumThreadsRegisteredWithRS < mWorkerThreadCount) + OGRE_THREAD_WAIT(mInitSync, mInitMutex, initLock); - Root::getSingleton().getRenderSystem()->postExtraThreadsStarted(); + Root::getSingleton().getRenderSystem()->postExtraThreadsStarted(); - } + } #endif - mIsRunning = true; - } - //--------------------------------------------------------------------- - void DefaultWorkQueue::notifyThreadRegistered() - { + mIsRunning = true; + } + //--------------------------------------------------------------------- + void DefaultWorkQueue::notifyThreadRegistered() + { OGRE_LOCK_MUTEX(mInitMutex); - ++mNumThreadsRegisteredWithRS; + ++mNumThreadsRegisteredWithRS; - // wake up main thread - OGRE_THREAD_NOTIFY_ALL(mInitSync); + // wake up main thread + OGRE_THREAD_NOTIFY_ALL(mInitSync); - } - //--------------------------------------------------------------------- - void DefaultWorkQueue::shutdown() - { - if( !mIsRunning ) - return; + } + //--------------------------------------------------------------------- + void DefaultWorkQueue::shutdown() + { + if( !mIsRunning ) + return; - LogManager::getSingleton().stream() << - "DefaultWorkQueue('" << mName << "') shutting down on thread " << + LogManager::getSingleton().stream() << + "DefaultWorkQueue('" << mName << "') shutting down on thread " << #if OGRE_THREAD_SUPPORT - OGRE_THREAD_CURRENT_ID + OGRE_THREAD_CURRENT_ID #else - "main" + "main" #endif - << "."; + << "."; - mShuttingDown = true; - abortAllRequests(); + mShuttingDown = true; + abortAllRequests(); #if OGRE_THREAD_SUPPORT - // wake all threads (they should check shutting down as first thing after wait) - OGRE_THREAD_NOTIFY_ALL(mRequestCondition); - - // all our threads should have been woken now, so join - for (WorkerThreadList::iterator i = mWorkers.begin(); i != mWorkers.end(); ++i) - { - (*i)->join(); - OGRE_THREAD_DESTROY(*i); - } - mWorkers.clear(); + // wake all threads (they should check shutting down as first thing after wait) + OGRE_THREAD_NOTIFY_ALL(mRequestCondition); + + // all our threads should have been woken now, so join + for (WorkerThreadList::iterator i = mWorkers.begin(); i != mWorkers.end(); ++i) + { + (*i)->join(); + OGRE_THREAD_DESTROY(*i); + } + mWorkers.clear(); #endif OGRE_DELETE_T(mWorkerFunc, WorkerFunc, MEMCATEGORY_GENERAL); mWorkerFunc = 0; - mIsRunning = false; - } - //--------------------------------------------------------------------- - void DefaultWorkQueue::notifyWorkers() - { - // wake up waiting thread + mIsRunning = false; + } + //--------------------------------------------------------------------- + void DefaultWorkQueue::notifyWorkers() + { + // wake up waiting thread OGRE_THREAD_NOTIFY_ONE(mRequestCondition); - } + } - //--------------------------------------------------------------------- - void DefaultWorkQueue::waitForNextRequest() - { + //--------------------------------------------------------------------- + void DefaultWorkQueue::waitForNextRequest() + { #if OGRE_THREAD_SUPPORT - // Lock; note that OGRE_THREAD_WAIT will free the lock + // Lock; note that OGRE_THREAD_WAIT will free the lock OGRE_LOCK_MUTEX_NAMED(mRequestMutex, queueLock); - if (mRequestQueue.empty()) - { - // frees lock and suspends the thread - OGRE_THREAD_WAIT(mRequestCondition, mRequestMutex, queueLock); - } - // When we get back here, it's because we've been notified - // and thus the thread has been woken up. Lock has also been - // re-acquired, but we won't use it. It's safe to try processing and fail - // if another thread has got in first and grabbed the request + if (mRequestQueue.empty()) + { + // frees lock and suspends the thread + OGRE_THREAD_WAIT(mRequestCondition, mRequestMutex, queueLock); + } + // When we get back here, it's because we've been notified + // and thus the thread has been woken up. Lock has also been + // re-acquired, but we won't use it. It's safe to try processing and fail + // if another thread has got in first and grabbed the request #endif - } - //--------------------------------------------------------------------- - void DefaultWorkQueue::_threadMain() - { - // default worker thread + } + //--------------------------------------------------------------------- + void DefaultWorkQueue::_threadMain() + { + // default worker thread #if OGRE_THREAD_SUPPORT - LogManager::getSingleton().stream() << - "DefaultWorkQueue('" << getName() << "')::WorkerFunc - thread " - << OGRE_THREAD_CURRENT_ID << " starting."; - - // Initialise the thread for RS if necessary - if (mWorkerRenderSystemAccess) - { - Root::getSingleton().getRenderSystem()->registerThread(); - notifyThreadRegistered(); - } - - // Spin forever until we're told to shut down - while (!isShuttingDown()) - { - waitForNextRequest(); - _processNextRequest(); - } - - LogManager::getSingleton().stream() << - "DefaultWorkQueue('" << getName() << "')::WorkerFunc - thread " - << OGRE_THREAD_CURRENT_ID << " stopped."; + LogManager::getSingleton().stream() << + "DefaultWorkQueue('" << getName() << "')::WorkerFunc - thread " + << OGRE_THREAD_CURRENT_ID << " starting."; + + // Initialise the thread for RS if necessary + if (mWorkerRenderSystemAccess) + { + Root::getSingleton().getRenderSystem()->registerThread(); + notifyThreadRegistered(); + } + + // Spin forever until we're told to shut down + while (!isShuttingDown()) + { + waitForNextRequest(); + _processNextRequest(); + } + + LogManager::getSingleton().stream() << + "DefaultWorkQueue('" << getName() << "')::WorkerFunc - thread " + << OGRE_THREAD_CURRENT_ID << " stopped."; #endif - } + } } diff --git a/OgreMain/src/Threading/OgreDefaultWorkQueueTBB.cpp b/OgreMain/src/Threading/OgreDefaultWorkQueueTBB.cpp index 0d9854138d2..903de5396ab 100644 --- a/OgreMain/src/Threading/OgreDefaultWorkQueueTBB.cpp +++ b/OgreMain/src/Threading/OgreDefaultWorkQueueTBB.cpp @@ -34,124 +34,124 @@ THE SOFTWARE. namespace Ogre { - /// Worker function to register threads with the RenderSystem, if required - struct RegisterRSWorker - { - RegisterRSWorker(DefaultWorkQueue* queue): mQueue(queue) { } - void operator() () { mQueue->_registerThreadWithRenderSystem(); } - DefaultWorkQueue* mQueue; - }; - - //--------------------------------------------------------------------- - DefaultWorkQueue::DefaultWorkQueue(const String& name) - : DefaultWorkQueueBase(name) - , mTaskScheduler(tbb::task_scheduler_init::deferred) - { - } - //--------------------------------------------------------------------- - void DefaultWorkQueue::startup(bool forceRestart) - { - if (mIsRunning) - { - if (forceRestart) - shutdown(); - else - return; - } - - mShuttingDown = false; - - mWorkerFunc = OGRE_NEW_T(WorkerFunc(this), MEMCATEGORY_GENERAL); - - LogManager::getSingleton().stream() << - "DefaultWorkQueue('" << mName << "') initialising."; - - mTaskScheduler.initialize(mWorkerThreadCount); - - if (mWorkerRenderSystemAccess) - { - Root::getSingleton().getRenderSystem()->preExtraThreadsStarted(); - RegisterRSWorker worker (this); - // current thread need not be registered - mRegisteredThreads.insert(tbb::this_tbb_thread::get_id()); - while (mRegisteredThreads.size() < mWorkerThreadCount) - { - // spawn tasks until all worker threads have registered themselves with the RS - for (size_t i = 0; i < mWorkerThreadCount*3; ++i) - { - mTaskGroup.run(worker); - } - mTaskGroup.wait(); - } - Root::getSingleton().getRenderSystem()->postExtraThreadsStarted(); - } - - mIsRunning = true; - } - //--------------------------------------------------------------------- - void DefaultWorkQueue::_registerThreadWithRenderSystem() - { - { + /// Worker function to register threads with the RenderSystem, if required + struct RegisterRSWorker + { + RegisterRSWorker(DefaultWorkQueue* queue): mQueue(queue) { } + void operator() () { mQueue->_registerThreadWithRenderSystem(); } + DefaultWorkQueue* mQueue; + }; + + //--------------------------------------------------------------------- + DefaultWorkQueue::DefaultWorkQueue(const String& name) + : DefaultWorkQueueBase(name) + , mTaskScheduler(tbb::task_scheduler_init::deferred) + { + } + //--------------------------------------------------------------------- + void DefaultWorkQueue::startup(bool forceRestart) + { + if (mIsRunning) + { + if (forceRestart) + shutdown(); + else + return; + } + + mShuttingDown = false; + + mWorkerFunc = OGRE_NEW_T(WorkerFunc(this), MEMCATEGORY_GENERAL); + + LogManager::getSingleton().stream() << + "DefaultWorkQueue('" << mName << "') initialising."; + + mTaskScheduler.initialize(mWorkerThreadCount); + + if (mWorkerRenderSystemAccess) + { + Root::getSingleton().getRenderSystem()->preExtraThreadsStarted(); + RegisterRSWorker worker (this); + // current thread need not be registered + mRegisteredThreads.insert(tbb::this_tbb_thread::get_id()); + while (mRegisteredThreads.size() < mWorkerThreadCount) + { + // spawn tasks until all worker threads have registered themselves with the RS + for (size_t i = 0; i < mWorkerThreadCount*3; ++i) + { + mTaskGroup.run(worker); + } + mTaskGroup.wait(); + } + Root::getSingleton().getRenderSystem()->postExtraThreadsStarted(); + } + + mIsRunning = true; + } + //--------------------------------------------------------------------- + void DefaultWorkQueue::_registerThreadWithRenderSystem() + { + { OGRE_LOCK_MUTEX(mRegisterRSMutex);; - tbb::tbb_thread::id cur = tbb::this_tbb_thread::get_id(); - if (mRegisteredThreads.find(cur) == mRegisteredThreads.end()) - { - Root::getSingleton().getRenderSystem()->registerThread(); - mRegisteredThreads.insert(cur); - } - } - - tbb::this_tbb_thread::yield(); - } - //--------------------------------------------------------------------- - DefaultWorkQueue::~DefaultWorkQueue() - { - shutdown(); - } - //--------------------------------------------------------------------- - void DefaultWorkQueue::shutdown() - { - LogManager::getSingleton().stream() << - "DefaultWorkQueue('" << mName << "') shutting down."; - - mShuttingDown = true; - mTaskGroup.cancel(); - abortAllRequests(); - - // wait until all tasks have finished. - mTaskGroup.wait(); - - if (mTaskScheduler.is_active()) - mTaskScheduler.terminate(); - - if (mWorkerFunc) - { - OGRE_DELETE_T(mWorkerFunc, WorkerFunc, MEMCATEGORY_GENERAL); - mWorkerFunc = 0; - } - - mIsRunning = false; - - } - //--------------------------------------------------------------------- - void DefaultWorkQueue::_threadMain() - { - //// Initialise the thread for RS if necessary - //if (mWorkerRenderSystemAccess) - //{ - // Root::getSingleton().getRenderSystem()->registerThread(); - // _notifyThreadRegistered(); - //} - - // Task main function. Process a single request. - - _processNextRequest(); - } - //--------------------------------------------------------------------- - void DefaultWorkQueue::notifyWorkers() - { - // create a new task - mTaskGroup.run(*mWorkerFunc); - } + tbb::tbb_thread::id cur = tbb::this_tbb_thread::get_id(); + if (mRegisteredThreads.find(cur) == mRegisteredThreads.end()) + { + Root::getSingleton().getRenderSystem()->registerThread(); + mRegisteredThreads.insert(cur); + } + } + + tbb::this_tbb_thread::yield(); + } + //--------------------------------------------------------------------- + DefaultWorkQueue::~DefaultWorkQueue() + { + shutdown(); + } + //--------------------------------------------------------------------- + void DefaultWorkQueue::shutdown() + { + LogManager::getSingleton().stream() << + "DefaultWorkQueue('" << mName << "') shutting down."; + + mShuttingDown = true; + mTaskGroup.cancel(); + abortAllRequests(); + + // wait until all tasks have finished. + mTaskGroup.wait(); + + if (mTaskScheduler.is_active()) + mTaskScheduler.terminate(); + + if (mWorkerFunc) + { + OGRE_DELETE_T(mWorkerFunc, WorkerFunc, MEMCATEGORY_GENERAL); + mWorkerFunc = 0; + } + + mIsRunning = false; + + } + //--------------------------------------------------------------------- + void DefaultWorkQueue::_threadMain() + { + //// Initialise the thread for RS if necessary + //if (mWorkerRenderSystemAccess) + //{ + // Root::getSingleton().getRenderSystem()->registerThread(); + // _notifyThreadRegistered(); + //} + + // Task main function. Process a single request. + + _processNextRequest(); + } + //--------------------------------------------------------------------- + void DefaultWorkQueue::notifyWorkers() + { + // create a new task + mTaskGroup.run(*mWorkerFunc); + } } diff --git a/OgreMain/src/WIN32/OgreConfigDialog.cpp b/OgreMain/src/WIN32/OgreConfigDialog.cpp index 8d4aa69017a..5328ee13a61 100644 --- a/OgreMain/src/WIN32/OgreConfigDialog.cpp +++ b/OgreMain/src/WIN32/OgreConfigDialog.cpp @@ -43,7 +43,7 @@ namespace Ogre ConfigDialog::ConfigDialog() { #ifdef OGRE_STATIC_LIB - mHInstance = GetModuleHandle( NULL ); + mHInstance = GetModuleHandle( NULL ); #else # if OGRE_DEBUG_MODE == 1 mHInstance = GetModuleHandle("OgreMain_d.dll"); @@ -54,9 +54,9 @@ namespace Ogre mSelectedRenderSystem = 0; } - ConfigDialog::~ConfigDialog() + ConfigDialog::~ConfigDialog() { - } + } #if OGRE_ARCHITECTURE_64 == OGRE_ARCH_TYPE INT_PTR ConfigDialog::DlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) diff --git a/OgreMain/src/WIN32/OgreConfigDialogWinRT.cpp b/OgreMain/src/WIN32/OgreConfigDialogWinRT.cpp index c0f56959e11..851aef434a4 100644 --- a/OgreMain/src/WIN32/OgreConfigDialogWinRT.cpp +++ b/OgreMain/src/WIN32/OgreConfigDialogWinRT.cpp @@ -45,32 +45,32 @@ namespace Ogre mSelectedRenderSystem = 0; } - ConfigDialog::~ConfigDialog() + ConfigDialog::~ConfigDialog() { - } + } bool ConfigDialog::display(void) { - if(Root::getSingleton().getRenderSystem() != NULL) - { - return true; - } + if(Root::getSingleton().getRenderSystem() != NULL) + { + return true; + } - // just select the first available render system for now. - const RenderSystemList* lstRend; - RenderSystemList::const_iterator pRend; + // just select the first available render system for now. + const RenderSystemList* lstRend; + RenderSystemList::const_iterator pRend; - lstRend = &Root::getSingleton().getAvailableRenderers(); - pRend = lstRend->begin(); + lstRend = &Root::getSingleton().getAvailableRenderers(); + pRend = lstRend->begin(); - if (pRend != lstRend->end()) - { - Root::getSingleton().setRenderSystem((*pRend)); + if (pRend != lstRend->end()) + { + Root::getSingleton().setRenderSystem((*pRend)); - return true; - } + return true; + } - return false; + return false; } } \ No newline at end of file diff --git a/OgreMain/src/WIN32/OgreErrorDialog.cpp b/OgreMain/src/WIN32/OgreErrorDialog.cpp index ce33db68d1b..cebd1b487ff 100644 --- a/OgreMain/src/WIN32/OgreErrorDialog.cpp +++ b/OgreMain/src/WIN32/OgreErrorDialog.cpp @@ -38,7 +38,7 @@ namespace Ogre ErrorDialog::ErrorDialog() { #ifdef OGRE_STATIC_LIB - mHInstance = GetModuleHandle( NULL ); + mHInstance = GetModuleHandle( NULL ); #else # if OGRE_DEBUG_MODE == 1 mHInstance = GetModuleHandle("OgreMain_d.dll"); diff --git a/OgreMain/src/WIN32/OgreErrorDialogWinRT.cpp b/OgreMain/src/WIN32/OgreErrorDialogWinRT.cpp index b63ae270c60..cd5a2aa3432 100644 --- a/OgreMain/src/WIN32/OgreErrorDialogWinRT.cpp +++ b/OgreMain/src/WIN32/OgreErrorDialogWinRT.cpp @@ -41,6 +41,6 @@ namespace Ogre void ErrorDialog::display(const String& errorMessage, String logName) { - std::cout << "*** ERROR: " << errorMessage << std::endl; + std::cout << "*** ERROR: " << errorMessage << std::endl; } } \ No newline at end of file diff --git a/OgreMain/src/WIN32/OgreFileSystemLayer.cpp b/OgreMain/src/WIN32/OgreFileSystemLayer.cpp index 8f153b328e9..4c849c7768a 100644 --- a/OgreMain/src/WIN32/OgreFileSystemLayer.cpp +++ b/OgreMain/src/WIN32/OgreFileSystemLayer.cpp @@ -30,138 +30,138 @@ #define WIN32_LEAN_AND_MEAN #include #if !((OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == PHONE)) -# include +# include #endif #include namespace Ogre { - bool widePathToOgreString(String& dest, const WCHAR* wpath) - { - // need to convert to narrow (OEM or ANSI) codepage so that fstream can use it - // properly on international systems. - char npath[MAX_PATH]; + bool widePathToOgreString(String& dest, const WCHAR* wpath) + { + // need to convert to narrow (OEM or ANSI) codepage so that fstream can use it + // properly on international systems. + char npath[MAX_PATH]; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - // Note, that on legacy CRT versions codepage for narrow CRT file functions can be changed using - // SetFileApisANSI/OEM, but on modern runtimes narrow pathes are always widened using ANSI codepage. - // We suppose that on such runtimes file APIs codepage is left in default, ANSI state. - UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; + // Note, that on legacy CRT versions codepage for narrow CRT file functions can be changed using + // SetFileApisANSI/OEM, but on modern runtimes narrow pathes are always widened using ANSI codepage. + // We suppose that on such runtimes file APIs codepage is left in default, ANSI state. + UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - // Runtime is modern, narrow calls are widened inside CRT using CP_ACP codepage. - UINT codepage = CP_ACP; + // Runtime is modern, narrow calls are widened inside CRT using CP_ACP codepage. + UINT codepage = CP_ACP; #endif - if(0 == WideCharToMultiByte(codepage, 0 /* Use default flags */, wpath, -1, npath, sizeof(npath), NULL, NULL)) - { - dest.clear(); - return false; - } + if(0 == WideCharToMultiByte(codepage, 0 /* Use default flags */, wpath, -1, npath, sizeof(npath), NULL, NULL)) + { + dest.clear(); + return false; + } - // success - dest = npath; - return true; - } + // success + dest = npath; + return true; + } - void FileSystemLayer::getConfigPaths() - { + void FileSystemLayer::getConfigPaths() + { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - // try to determine the application's path - DWORD bufsize = 256; - char* resolved = 0; - do - { - char* buf = OGRE_ALLOC_T(char, bufsize, Ogre::MEMCATEGORY_GENERAL); - DWORD retval = GetModuleFileName(NULL, buf, bufsize); - if (retval == 0) - { - // failed - OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); - break; - } + // try to determine the application's path + DWORD bufsize = 256; + char* resolved = 0; + do + { + char* buf = OGRE_ALLOC_T(char, bufsize, Ogre::MEMCATEGORY_GENERAL); + DWORD retval = GetModuleFileName(NULL, buf, bufsize); + if (retval == 0) + { + // failed + OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); + break; + } - if (retval < bufsize) - { - // operation was successful. - resolved = buf; - } - else - { - // buffer was too small, grow buffer and try again - OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); - bufsize <<= 1; - } - } while (!resolved); + if (retval < bufsize) + { + // operation was successful. + resolved = buf; + } + else + { + // buffer was too small, grow buffer and try again + OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); + bufsize <<= 1; + } + } while (!resolved); - Ogre::String appPath = resolved; - if (resolved) - OGRE_FREE(resolved, Ogre::MEMCATEGORY_GENERAL); - if (!appPath.empty()) - { - // need to strip the application filename from the path - Ogre::String::size_type pos = appPath.rfind('\\'); - if (pos != Ogre::String::npos) - appPath.erase(pos); - } - else - { - // fall back to current working dir - appPath = "."; - } + Ogre::String appPath = resolved; + if (resolved) + OGRE_FREE(resolved, Ogre::MEMCATEGORY_GENERAL); + if (!appPath.empty()) + { + // need to strip the application filename from the path + Ogre::String::size_type pos = appPath.rfind('\\'); + if (pos != Ogre::String::npos) + appPath.erase(pos); + } + else + { + // fall back to current working dir + appPath = "."; + } #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - Ogre::String appPath; - if(!widePathToOgreString(appPath, Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data())) - { - // fallback to current working dir - appPath = "."; - } + Ogre::String appPath; + if(!widePathToOgreString(appPath, Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data())) + { + // fallback to current working dir + appPath = "."; + } #endif - // use application path as config search path - mConfigPaths.push_back(appPath + '\\'); - } + // use application path as config search path + mConfigPaths.push_back(appPath + '\\'); + } //--------------------------------------------------------------------- - void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) - { - // fill mHomePath + void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) + { + // fill mHomePath #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - WCHAR wpath[MAX_PATH]; - if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, 0, wpath))) - widePathToOgreString(mHomePath, wpath); + WCHAR wpath[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, 0, wpath))) + widePathToOgreString(mHomePath, wpath); #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - widePathToOgreString(mHomePath, Windows::Storage::ApplicationData::Current->LocalFolder->Path->Data()); + widePathToOgreString(mHomePath, Windows::Storage::ApplicationData::Current->LocalFolder->Path->Data()); #endif - if(!mHomePath.empty()) - { - // create Ogre subdir - mHomePath += "\\Ogre\\"; - if (!createDirectory(mHomePath)) - { - // couldn't create directory, fall back to current working dir - mHomePath.clear(); - } - else - { - mHomePath += subdir + '\\'; - // create release subdir - if (!createDirectory(mHomePath)) - { - // couldn't create directory, fall back to current working dir - mHomePath.clear(); - } - } - } - } + if(!mHomePath.empty()) + { + // create Ogre subdir + mHomePath += "\\Ogre\\"; + if (!createDirectory(mHomePath)) + { + // couldn't create directory, fall back to current working dir + mHomePath.clear(); + } + else + { + mHomePath += subdir + '\\'; + // create release subdir + if (!createDirectory(mHomePath)) + { + // couldn't create directory, fall back to current working dir + mHomePath.clear(); + } + } + } + } //--------------------------------------------------------------------- - bool FileSystemLayer::fileExists(const Ogre::String& path) const - { - WIN32_FILE_ATTRIBUTE_DATA attr_data; - return GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &attr_data) != 0; - } + bool FileSystemLayer::fileExists(const Ogre::String& path) const + { + WIN32_FILE_ATTRIBUTE_DATA attr_data; + return GetFileAttributesExA(path.c_str(), GetFileExInfoStandard, &attr_data) != 0; + } //--------------------------------------------------------------------- - bool FileSystemLayer::createDirectory(const Ogre::String& path) - { - return CreateDirectoryA(path.c_str(), NULL) != 0 || - GetLastError() == ERROR_ALREADY_EXISTS; - } + bool FileSystemLayer::createDirectory(const Ogre::String& path) + { + return CreateDirectoryA(path.c_str(), NULL) != 0 || + GetLastError() == ERROR_ALREADY_EXISTS; + } } diff --git a/OgreMain/src/WIN32/OgreMinGWSupport.cpp b/OgreMain/src/WIN32/OgreMinGWSupport.cpp index 6266afeec4b..e15bb6a1453 100644 --- a/OgreMain/src/WIN32/OgreMinGWSupport.cpp +++ b/OgreMain/src/WIN32/OgreMinGWSupport.cpp @@ -32,20 +32,20 @@ THE SOFTWARE. // may cause linking errors when linking against the DX SDK. extern "C" { - // MSVC libs use _chkstk for stack-probing. MinGW equivalent is _alloca. - // But calling it to ensure Ogre build with D3D9 static does cause a crash. - // Might have to investige further here, later. - //void _alloca(); - void _chkstk() - { - //_alloca(); - } - - // MSVC uses security cookies to prevent some buffer overflow attacks. - // provide dummy implementations. - intptr_t __security_cookie; - - void _fastcall __security_check_cookie(intptr_t i) - { - } + // MSVC libs use _chkstk for stack-probing. MinGW equivalent is _alloca. + // But calling it to ensure Ogre build with D3D9 static does cause a crash. + // Might have to investige further here, later. + //void _alloca(); + void _chkstk() + { + //_alloca(); + } + + // MSVC uses security cookies to prevent some buffer overflow attacks. + // provide dummy implementations. + intptr_t __security_cookie; + + void _fastcall __security_check_cookie(intptr_t i) + { + } } diff --git a/OgreMain/src/WIN32/OgreOptimisedUtilDirectXMath.cpp b/OgreMain/src/WIN32/OgreOptimisedUtilDirectXMath.cpp index 46859f177eb..f6aee477ed9 100644 --- a/OgreMain/src/WIN32/OgreOptimisedUtilDirectXMath.cpp +++ b/OgreMain/src/WIN32/OgreOptimisedUtilDirectXMath.cpp @@ -72,9 +72,9 @@ namespace Ogre { Real t, const float *srcPos1, const float *srcPos2, float *dstPos, - size_t pos1VSize, size_t pos2VSize, size_t dstVSize, + size_t pos1VSize, size_t pos2VSize, size_t dstVSize, size_t numVertices, - bool morphNormals); + bool morphNormals); /// @copydoc OptimisedUtil::concatenateAffineMatrices virtual void concatenateAffineMatrices( @@ -1231,28 +1231,28 @@ static FORCEINLINE bool _isAlignedForDirectXMath(const void *p) Real t, const float *pSrc1, const float *pSrc2, float *pDst, - size_t pos1VSize, size_t pos2VSize, size_t dstVSize, + size_t pos1VSize, size_t pos2VSize, size_t dstVSize, size_t numVertices, - bool morphNormals) - { + bool morphNormals) + { XMVECTOR src01, src02, src11, src12, src21, src22; XMVECTOR dst0, dst1, dst2; XMVECTOR t4 = XMVectorReplicate(t); - // If we're morphing normals, we have twice the number of floats to process - // Positions are interleaved with normals, so we'll have to separately - // normalise just the normals later; we'll just lerp in the first pass - // We can't normalise as we go because normals & positions are only 3 floats - // each so are not aligned for DirectXMath, we'd mix the data up - size_t normalsMultiplier = morphNormals ? 2 : 1; + // If we're morphing normals, we have twice the number of floats to process + // Positions are interleaved with normals, so we'll have to separately + // normalise just the normals later; we'll just lerp in the first pass + // We can't normalise as we go because normals & positions are only 3 floats + // each so are not aligned for DirectXMath, we'd mix the data up + size_t normalsMultiplier = morphNormals ? 2 : 1; size_t numIterations = (numVertices*normalsMultiplier) / 4; - size_t numVerticesRemainder = (numVertices*normalsMultiplier) & 3; - - // Save for later - float *pStartDst = pDst; - + size_t numVerticesRemainder = (numVertices*normalsMultiplier) & 3; + + // Save for later + float *pStartDst = pDst; + // Never use meta-function technique to accessing memory because looks like // VC7.1 generate a bit inefficient binary code when put following code into // inline function. @@ -1406,36 +1406,36 @@ static FORCEINLINE bool _isAlignedForDirectXMath(const void *p) XMStoreFloat3((XMFLOAT3*)(pDst + 0), dst0); break; } - + } - - if (morphNormals) - { - - // Now we need to do and unaligned normalise on the normals data we just - // lerped; because normals are 3 elements each they're always unaligned - float *pNorm = pStartDst; - - // Offset past first position - pNorm += 3; - - // We'll do one normal each iteration, but still use DirectXMath - for (size_t n = 0; n < numVertices; ++n) - { - // normalise function - XMVECTOR norm; - - // load 3 floating-point normal values + + if (morphNormals) + { + + // Now we need to do and unaligned normalise on the normals data we just + // lerped; because normals are 3 elements each they're always unaligned + float *pNorm = pStartDst; + + // Offset past first position + pNorm += 3; + + // We'll do one normal each iteration, but still use DirectXMath + for (size_t n = 0; n < numVertices; ++n) + { + // normalise function + XMVECTOR norm; + + // load 3 floating-point normal values norm = XMLoadFloat3((XMFLOAT3*)pNorm); norm = XMVector3Normalize(norm); - - // Store back in the same place + + // Store back in the same place XMStoreFloat3((XMFLOAT3*)pNorm, norm); - - // Skip to next vertex (3x normal components, 3x position components) - pNorm += 6; - } - } + + // Skip to next vertex (3x normal components, 3x position components) + pNorm += 6; + } + } } //--------------------------------------------------------------------- void OptimisedUtilDirectXMath::concatenateAffineMatrices( diff --git a/OgreMain/src/WIN32/OgreTimer.cpp b/OgreMain/src/WIN32/OgreTimer.cpp index 2751f98a705..db7ab3355ff 100644 --- a/OgreMain/src/WIN32/OgreTimer.cpp +++ b/OgreMain/src/WIN32/OgreTimer.cpp @@ -34,10 +34,10 @@ using namespace Ogre; //------------------------------------------------------------------------- Timer::Timer() #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - : mTimerMask( 0 ) + : mTimerMask( 0 ) #endif { - reset(); + reset(); } //------------------------------------------------------------------------- @@ -49,29 +49,29 @@ Timer::~Timer() bool Timer::setOption( const String & key, const void * val ) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - if ( key == "QueryAffinityMask" ) - { - // Telling timer what core to use for a timer read - DWORD newTimerMask = * static_cast < const DWORD * > ( val ); - - // Get the current process core mask - DWORD_PTR procMask; - DWORD_PTR sysMask; - GetProcessAffinityMask(GetCurrentProcess(), &procMask, &sysMask); - - // If new mask is 0, then set to default behavior, otherwise check - // to make sure new timer core mask overlaps with process core mask - // and that new timer core mask is a power of 2 (i.e. a single core) - if( ( newTimerMask == 0 ) || - ( ( ( newTimerMask & procMask ) != 0 ) && Bitwise::isPO2( newTimerMask ) ) ) - { - mTimerMask = newTimerMask; - return true; - } - } + if ( key == "QueryAffinityMask" ) + { + // Telling timer what core to use for a timer read + DWORD newTimerMask = * static_cast < const DWORD * > ( val ); + + // Get the current process core mask + DWORD_PTR procMask; + DWORD_PTR sysMask; + GetProcessAffinityMask(GetCurrentProcess(), &procMask, &sysMask); + + // If new mask is 0, then set to default behavior, otherwise check + // to make sure new timer core mask overlaps with process core mask + // and that new timer core mask is a power of 2 (i.e. a single core) + if( ( newTimerMask == 0 ) || + ( ( ( newTimerMask & procMask ) != 0 ) && Bitwise::isPO2( newTimerMask ) ) ) + { + mTimerMask = newTimerMask; + return true; + } + } #endif - return false; + return false; } //------------------------------------------------------------------------- @@ -79,45 +79,45 @@ void Timer::reset() { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 // Get the current process core mask - DWORD_PTR procMask; - DWORD_PTR sysMask; - GetProcessAffinityMask(GetCurrentProcess(), &procMask, &sysMask); - - // If procMask is 0, consider there is only one core available - // (using 0 as procMask will cause an infinite loop below) - if (procMask == 0) - procMask = 1; - - // Find the lowest core that this process uses - if( mTimerMask == 0 ) - { - mTimerMask = 1; - while( ( mTimerMask & procMask ) == 0 ) - { - mTimerMask <<= 1; - } - } - - HANDLE thread = GetCurrentThread(); - - // Set affinity to the first core - DWORD_PTR oldMask = SetThreadAffinityMask(thread, mTimerMask); + DWORD_PTR procMask; + DWORD_PTR sysMask; + GetProcessAffinityMask(GetCurrentProcess(), &procMask, &sysMask); + + // If procMask is 0, consider there is only one core available + // (using 0 as procMask will cause an infinite loop below) + if (procMask == 0) + procMask = 1; + + // Find the lowest core that this process uses + if( mTimerMask == 0 ) + { + mTimerMask = 1; + while( ( mTimerMask & procMask ) == 0 ) + { + mTimerMask <<= 1; + } + } + + HANDLE thread = GetCurrentThread(); + + // Set affinity to the first core + DWORD_PTR oldMask = SetThreadAffinityMask(thread, mTimerMask); #endif - // Get the constant frequency - QueryPerformanceFrequency(&mFrequency); + // Get the constant frequency + QueryPerformanceFrequency(&mFrequency); - // Query the timer - QueryPerformanceCounter(&mStartTime); - mStartTick = GetTickCount(); + // Query the timer + QueryPerformanceCounter(&mStartTime); + mStartTick = GetTickCount(); #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - // Reset affinity - SetThreadAffinityMask(thread, oldMask); + // Reset affinity + SetThreadAffinityMask(thread, oldMask); #endif - mLastTime = 0; - mZeroClock = clock(); + mLastTime = 0; + mZeroClock = clock(); } //------------------------------------------------------------------------- @@ -126,18 +126,18 @@ unsigned long Timer::getMilliseconds() LARGE_INTEGER curTime; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - HANDLE thread = GetCurrentThread(); + HANDLE thread = GetCurrentThread(); - // Set affinity to the first core - DWORD_PTR oldMask = SetThreadAffinityMask(thread, mTimerMask); + // Set affinity to the first core + DWORD_PTR oldMask = SetThreadAffinityMask(thread, mTimerMask); #endif - // Query the timer - QueryPerformanceCounter(&curTime); + // Query the timer + QueryPerformanceCounter(&curTime); #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - // Reset affinity - SetThreadAffinityMask(thread, oldMask); + // Reset affinity + SetThreadAffinityMask(thread, oldMask); #endif LONGLONG newTime = curTime.QuadPart - mStartTime.QuadPart; @@ -172,21 +172,21 @@ unsigned long Timer::getMicroseconds() LARGE_INTEGER curTime; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - HANDLE thread = GetCurrentThread(); + HANDLE thread = GetCurrentThread(); - // Set affinity to the first core - DWORD_PTR oldMask = SetThreadAffinityMask(thread, mTimerMask); + // Set affinity to the first core + DWORD_PTR oldMask = SetThreadAffinityMask(thread, mTimerMask); #endif - // Query the timer - QueryPerformanceCounter(&curTime); + // Query the timer + QueryPerformanceCounter(&curTime); #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - // Reset affinity - SetThreadAffinityMask(thread, oldMask); + // Reset affinity + SetThreadAffinityMask(thread, oldMask); #endif - LONGLONG newTime = curTime.QuadPart - mStartTime.QuadPart; + LONGLONG newTime = curTime.QuadPart - mStartTime.QuadPart; // get milliseconds to check against GetTickCount unsigned long newTicks = (unsigned long) (1000 * newTime / mFrequency.QuadPart); @@ -215,13 +215,13 @@ unsigned long Timer::getMicroseconds() //------------------------------------------------------------------------- unsigned long Timer::getMillisecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)( (float)( newClock - mZeroClock ) / ( (float)CLOCKS_PER_SEC / 1000.0 ) ) ; + clock_t newClock = clock(); + return (unsigned long)( (float)( newClock - mZeroClock ) / ( (float)CLOCKS_PER_SEC / 1000.0 ) ) ; } //------------------------------------------------------------------------- unsigned long Timer::getMicrosecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)( (float)( newClock - mZeroClock ) / ( (float)CLOCKS_PER_SEC / 1000000.0 ) ) ; + clock_t newClock = clock(); + return (unsigned long)( (float)( newClock - mZeroClock ) / ( (float)CLOCKS_PER_SEC / 1000000.0 ) ) ; } diff --git a/OgreMain/src/gtk/OgreConfigDialog.cpp b/OgreMain/src/gtk/OgreConfigDialog.cpp index d9b4032bb48..01795aa009a 100644 --- a/OgreMain/src/gtk/OgreConfigDialog.cpp +++ b/OgreMain/src/gtk/OgreConfigDialog.cpp @@ -88,7 +88,7 @@ void ConfigDialog::rendererChanged (GtkComboBox *widget, gpointer data) if (strcmp (renderer, (*r)->getName ().c_str ()) == 0) { This->mSelectedRenderSystem = *r; - This->setupRendererParams (); + This->setupRendererParams (); } } @@ -133,10 +133,10 @@ void ConfigDialog::setupRendererParams () uint row = 0; for (ConfigOptionMap::iterator i = options.begin (); i != options.end (); i++, row++) { - if (i->second.possibleValues.empty()) - { - continue; - } + if (i->second.possibleValues.empty()) + { + continue; + } GtkWidget *ro_label = gtk_label_new (i->second.name.c_str ()); gtk_widget_show (ro_label); diff --git a/OgreMain/src/gtk/OgreFileSystemLayer.cpp b/OgreMain/src/gtk/OgreFileSystemLayer.cpp index 68a1320de27..7aab4d0f5c2 100644 --- a/OgreMain/src/gtk/OgreFileSystemLayer.cpp +++ b/OgreMain/src/gtk/OgreFileSystemLayer.cpp @@ -34,132 +34,132 @@ namespace Ogre { - namespace { - /** Get actual file pointed to by symlink */ - const Ogre::String resolveSymlink(const Ogre::String& symlink) - { - ssize_t bufsize = 256; - char* resolved = 0; - do - { - char* buf = OGRE_ALLOC_T(char, bufsize, Ogre::MEMCATEGORY_GENERAL); - ssize_t retval = readlink(symlink.c_str(), buf, bufsize); - if (retval == -1) - { - OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); - break; - } + namespace { + /** Get actual file pointed to by symlink */ + const Ogre::String resolveSymlink(const Ogre::String& symlink) + { + ssize_t bufsize = 256; + char* resolved = 0; + do + { + char* buf = OGRE_ALLOC_T(char, bufsize, Ogre::MEMCATEGORY_GENERAL); + ssize_t retval = readlink(symlink.c_str(), buf, bufsize); + if (retval == -1) + { + OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); + break; + } - if (retval < bufsize) - { - // operation was successful. - // readlink does not guarantee to 0-terminate, so do this manually - buf[retval] = '\0'; - resolved = buf; - } - else - { - // buffer was too small, grow buffer and try again - OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); - bufsize <<= 1; - } - } while (!resolved); + if (retval < bufsize) + { + // operation was successful. + // readlink does not guarantee to 0-terminate, so do this manually + buf[retval] = '\0'; + resolved = buf; + } + else + { + // buffer was too small, grow buffer and try again + OGRE_FREE(buf, Ogre::MEMCATEGORY_GENERAL); + bufsize <<= 1; + } + } while (!resolved); - if (resolved) - { - Ogre::String result (resolved); - OGRE_FREE(resolved, Ogre::MEMCATEGORY_GENERAL); - return result; - } - else - return ""; - } - } + if (resolved) + { + Ogre::String result (resolved); + OGRE_FREE(resolved, Ogre::MEMCATEGORY_GENERAL); + return result; + } + else + return ""; + } + } //--------------------------------------------------------------------- - void FileSystemLayer::getConfigPaths() - { - // try to determine the application's path: - // recent systems should provide the executable path via the /proc system - Ogre::String appPath = resolveSymlink("/proc/self/exe"); - if (appPath.empty()) - { - // if /proc/self/exe isn't available, try it via the program's pid - pid_t pid = getpid(); - char proc[64]; - int retval = snprintf(proc, sizeof(proc), "/proc/%llu/exe", (unsigned long long) pid); - if (retval > 0 && retval < (long)sizeof(proc)) - appPath = resolveSymlink(proc); - } + void FileSystemLayer::getConfigPaths() + { + // try to determine the application's path: + // recent systems should provide the executable path via the /proc system + Ogre::String appPath = resolveSymlink("/proc/self/exe"); + if (appPath.empty()) + { + // if /proc/self/exe isn't available, try it via the program's pid + pid_t pid = getpid(); + char proc[64]; + int retval = snprintf(proc, sizeof(proc), "/proc/%llu/exe", (unsigned long long) pid); + if (retval > 0 && retval < (long)sizeof(proc)) + appPath = resolveSymlink(proc); + } - if (!appPath.empty()) - { - // we need to strip the executable name from the path - Ogre::String::size_type pos = appPath.rfind('/'); - if (pos != Ogre::String::npos) - appPath.erase(pos); - } - else - { - // couldn't find actual executable path, assume current working dir - appPath = "."; - } + if (!appPath.empty()) + { + // we need to strip the executable name from the path + Ogre::String::size_type pos = appPath.rfind('/'); + if (pos != Ogre::String::npos) + appPath.erase(pos); + } + else + { + // couldn't find actual executable path, assume current working dir + appPath = "."; + } - // use application path as first config search path - mConfigPaths.push_back(appPath + '/'); - // then search inside ../share/OGRE - mConfigPaths.push_back(appPath + "/../share/OGRE/"); - // then try system wide /etc - mConfigPaths.push_back("/etc/OGRE/"); - } + // use application path as first config search path + mConfigPaths.push_back(appPath + '/'); + // then search inside ../share/OGRE + mConfigPaths.push_back(appPath + "/../share/OGRE/"); + // then try system wide /etc + mConfigPaths.push_back("/etc/OGRE/"); + } //--------------------------------------------------------------------- - void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) - { - struct passwd* pwd = getpwuid(getuid()); - if (pwd) - { - mHomePath = pwd->pw_dir; - } - else - { - // try the $HOME environment variable - mHomePath = getenv("HOME"); - } + void FileSystemLayer::prepareUserHome(const Ogre::String& subdir) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd) + { + mHomePath = pwd->pw_dir; + } + else + { + // try the $HOME environment variable + mHomePath = getenv("HOME"); + } - if (!mHomePath.empty()) - { - // create an .ogre subdir - mHomePath.append("/.ogre/"); - if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) - { - // can't create dir - mHomePath.clear(); - } - else - { - // now create the given subdir - mHomePath.append(subdir + '/'); - if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) - { - // can't create dir - mHomePath.clear(); - } - } - } + if (!mHomePath.empty()) + { + // create an .ogre subdir + mHomePath.append("/.ogre/"); + if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) + { + // can't create dir + mHomePath.clear(); + } + else + { + // now create the given subdir + mHomePath.append(subdir + '/'); + if (mkdir(mHomePath.c_str(), 0755) != 0 && errno != EEXIST) + { + // can't create dir + mHomePath.clear(); + } + } + } - if (mHomePath.empty()) - { - // couldn't create dir in home directory, fall back to cwd - mHomePath = "./"; - } - } + if (mHomePath.empty()) + { + // couldn't create dir in home directory, fall back to cwd + mHomePath = "./"; + } + } //--------------------------------------------------------------------- - bool FileSystemLayer::fileExists(const Ogre::String& path) const - { - return access(path.c_str(), R_OK) == 0; - } + bool FileSystemLayer::fileExists(const Ogre::String& path) const + { + return access(path.c_str(), R_OK) == 0; + } //--------------------------------------------------------------------- - bool FileSystemLayer::createDirectory(const Ogre::String& path) - { - return !mkdir(path.c_str(), 0755) || errno == EEXIST; - } + bool FileSystemLayer::createDirectory(const Ogre::String& path) + { + return !mkdir(path.c_str(), 0755) || errno == EEXIST; + } } diff --git a/OgreMain/src/iOS/OgreConfigDialog.cpp b/OgreMain/src/iOS/OgreConfigDialog.cpp index b2dd9790eaa..d3c8e37488d 100644 --- a/OgreMain/src/iOS/OgreConfigDialog.cpp +++ b/OgreMain/src/iOS/OgreConfigDialog.cpp @@ -30,33 +30,33 @@ THE SOFTWARE. namespace Ogre { - ConfigDialog* dlg = NULL; - - ConfigDialog::ConfigDialog() - { - dlg = this; - } - - ConfigDialog::~ConfigDialog() - { - } - - void ConfigDialog::initialise() + ConfigDialog* dlg = NULL; + + ConfigDialog::ConfigDialog() + { + dlg = this; + } + + ConfigDialog::~ConfigDialog() + { + } + + void ConfigDialog::initialise() + { + } + + void ConfigDialog::run() + { + + } + + void ConfigDialog::cancel() + { + } + + bool ConfigDialog::display() { - } - - void ConfigDialog::run() - { - - } - - void ConfigDialog::cancel() - { - } - - bool ConfigDialog::display() - { - return true; - } + return true; + } } diff --git a/OgreMain/src/iOS/OgreTimer.cpp b/OgreMain/src/iOS/OgreTimer.cpp index 369bd29e465..9427a907838 100644 --- a/OgreMain/src/iOS/OgreTimer.cpp +++ b/OgreMain/src/iOS/OgreTimer.cpp @@ -33,7 +33,7 @@ using namespace Ogre; //--------------------------------------------------------------------------------// Timer::Timer() { - reset(); + reset(); } //--------------------------------------------------------------------------------// @@ -44,36 +44,36 @@ Timer::~Timer() //--------------------------------------------------------------------------------// void Timer::reset() { - zeroClock = clock(); - gettimeofday(&start, NULL); + zeroClock = clock(); + gettimeofday(&start, NULL); } //--------------------------------------------------------------------------------// unsigned long Timer::getMilliseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; } //--------------------------------------------------------------------------------// unsigned long Timer::getMicroseconds() { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec-start.tv_sec)*1000000+(now.tv_usec-start.tv_usec); } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMillisecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000.0)) ; } //-- Common Across All Timers ----------------------------------------------------// unsigned long Timer::getMicrosecondsCPU() { - clock_t newClock = clock(); - return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; + clock_t newClock = clock(); + return (unsigned long)((float)(newClock-zeroClock) / ((float)CLOCKS_PER_SEC/1000000.0)) ; } diff --git a/OgreMain/src/nedmalloc/malloc.c.h b/OgreMain/src/nedmalloc/malloc.c.h index cb5a062e538..4803a782bc0 100644 --- a/OgreMain/src/nedmalloc/malloc.c.h +++ b/OgreMain/src/nedmalloc/malloc.c.h @@ -1363,7 +1363,7 @@ LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value); /* Declarations for bit scanning on win32 */ #if defined(_MSC_VER) && _MSC_VER>=1300 -#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ +#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -1788,7 +1788,7 @@ static FORCEINLINE int win32_acquire_lock (MLOCK_T *sl) { else { if (!interlockedexchange(&sl->l, 1)) { assert(!sl->threadid); - sl->c=CURRENT_THREAD; + sl->c=CURRENT_THREAD; sl->threadid = CURRENT_THREAD; sl->c = 1; return 0; @@ -1846,7 +1846,7 @@ static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER; #ifdef linux #if !defined (PTHREAD_MUTEX_RECURSIVE) && defined (PTHREAD_MUTEX_RECURSIVE_NP) extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr, - int __kind)); + int __kind)); #define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP #define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y) #endif diff --git a/OgreMain/src/nedmalloc/nedmalloc.c b/OgreMain/src/nedmalloc/nedmalloc.c index 69c78d634b7..4dfbded9f14 100644 --- a/OgreMain/src/nedmalloc/nedmalloc.c +++ b/OgreMain/src/nedmalloc/nedmalloc.c @@ -43,7 +43,7 @@ DEALINGS IN THE SOFTWARE. #define USE_LOCKS 1 #endif #define FOOTERS 1 /* Need to enable footers so frees lock the right mspace */ -#undef DEBUG /* dlmalloc wants DEBUG either 0 or 1 */ +#undef DEBUG /* dlmalloc wants DEBUG either 0 or 1 */ #ifdef _DEBUG #define DEBUG 1 #else @@ -91,27 +91,27 @@ DEALINGS IN THE SOFTWARE. #ifdef WIN32 - #define TLSVAR DWORD - #define TLSALLOC(k) (*(k)=TlsAlloc(), TLS_OUT_OF_INDEXES==*(k)) - #define TLSFREE(k) (!TlsFree(k)) - #define TLSGET(k) TlsGetValue(k) - #define TLSSET(k, a) (!TlsSetValue(k, a)) + #define TLSVAR DWORD + #define TLSALLOC(k) (*(k)=TlsAlloc(), TLS_OUT_OF_INDEXES==*(k)) + #define TLSFREE(k) (!TlsFree(k)) + #define TLSGET(k) TlsGetValue(k) + #define TLSSET(k, a) (!TlsSetValue(k, a)) #ifdef DEBUG static LPVOID ChkedTlsGetValue(DWORD idx) { - LPVOID ret=TlsGetValue(idx); - assert(S_OK==GetLastError()); - return ret; + LPVOID ret=TlsGetValue(idx); + assert(S_OK==GetLastError()); + return ret; } #undef TLSGET #define TLSGET(k) ChkedTlsGetValue(k) #endif #else - #define TLSVAR pthread_key_t - #define TLSALLOC(k) pthread_key_create(k, 0) - #define TLSFREE(k) pthread_key_delete(k) - #define TLSGET(k) pthread_getspecific(k) - #define TLSSET(k, a) pthread_setspecific(k, a) + #define TLSVAR pthread_key_t + #define TLSALLOC(k) pthread_key_create(k, 0) + #define TLSFREE(k) pthread_key_delete(k) + #define TLSGET(k) pthread_getspecific(k) + #define TLSSET(k, a) pthread_setspecific(k, a) #endif #if 0 @@ -134,80 +134,80 @@ extern "C" { size_t nedblksize(void *mem) THROWSPEC { #if 0 - /* Only enable if testing with valgrind. Causes misoperation */ - return THREADCACHEMAX; + /* Only enable if testing with valgrind. Causes misoperation */ + return THREADCACHEMAX; #else - if(mem) - { - mchunkptr p=mem2chunk(mem); - assert(cinuse(p)); /* If this fails, someone tried to free a block twice */ - if(cinuse(p)) - return chunksize(p)-overhead_for(p); - } - return 0; -#endif -} - -void nedsetvalue(void *v) THROWSPEC { nedpsetvalue(0, v); } -void * nedmalloc(size_t size) THROWSPEC { return nedpmalloc(0, size); } -void * nedcalloc(size_t no, size_t size) THROWSPEC { return nedpcalloc(0, no, size); } -void * nedrealloc(void *mem, size_t size) THROWSPEC { return nedprealloc(0, mem, size); } -void nedfree(void *mem) THROWSPEC { nedpfree(0, mem); } + if(mem) + { + mchunkptr p=mem2chunk(mem); + assert(cinuse(p)); /* If this fails, someone tried to free a block twice */ + if(cinuse(p)) + return chunksize(p)-overhead_for(p); + } + return 0; +#endif +} + +void nedsetvalue(void *v) THROWSPEC { nedpsetvalue(0, v); } +void * nedmalloc(size_t size) THROWSPEC { return nedpmalloc(0, size); } +void * nedcalloc(size_t no, size_t size) THROWSPEC { return nedpcalloc(0, no, size); } +void * nedrealloc(void *mem, size_t size) THROWSPEC { return nedprealloc(0, mem, size); } +void nedfree(void *mem) THROWSPEC { nedpfree(0, mem); } void * nedmemalign(size_t alignment, size_t bytes) THROWSPEC { return nedpmemalign(0, alignment, bytes); } #if !NO_MALLINFO -struct mallinfo nedmallinfo(void) THROWSPEC { return nedpmallinfo(0); } +struct mallinfo nedmallinfo(void) THROWSPEC { return nedpmallinfo(0); } #endif -int nedmallopt(int parno, int value) THROWSPEC { return nedpmallopt(0, parno, value); } -int nedmalloc_trim(size_t pad) THROWSPEC { return nedpmalloc_trim(0, pad); } -void nedmalloc_stats() THROWSPEC { nedpmalloc_stats(0); } -size_t nedmalloc_footprint() THROWSPEC { return nedpmalloc_footprint(0); } -void **nedindependent_calloc(size_t elemsno, size_t elemsize, void **chunks) THROWSPEC { return nedpindependent_calloc(0, elemsno, elemsize, chunks); } -void **nedindependent_comalloc(size_t elems, size_t *sizes, void **chunks) THROWSPEC { return nedpindependent_comalloc(0, elems, sizes, chunks); } +int nedmallopt(int parno, int value) THROWSPEC { return nedpmallopt(0, parno, value); } +int nedmalloc_trim(size_t pad) THROWSPEC { return nedpmalloc_trim(0, pad); } +void nedmalloc_stats() THROWSPEC { nedpmalloc_stats(0); } +size_t nedmalloc_footprint() THROWSPEC { return nedpmalloc_footprint(0); } +void **nedindependent_calloc(size_t elemsno, size_t elemsize, void **chunks) THROWSPEC { return nedpindependent_calloc(0, elemsno, elemsize, chunks); } +void **nedindependent_comalloc(size_t elems, size_t *sizes, void **chunks) THROWSPEC { return nedpindependent_comalloc(0, elems, sizes, chunks); } struct threadcacheblk_t; typedef struct threadcacheblk_t threadcacheblk; struct threadcacheblk_t -{ /* Keep less than 16 bytes on 32 bit systems and 32 bytes on 64 bit systems */ +{ /* Keep less than 16 bytes on 32 bit systems and 32 bytes on 64 bit systems */ #ifdef FULLSANITYCHECKS - unsigned int magic; + unsigned int magic; #endif - unsigned int lastUsed, size; - threadcacheblk *next, *prev; + unsigned int lastUsed, size; + threadcacheblk *next, *prev; }; typedef struct threadcache_t { #ifdef FULLSANITYCHECKS - unsigned int magic1; + unsigned int magic1; #endif - int mymspace; /* Last mspace entry this thread used */ - long threadid; - unsigned int mallocs, frees, successes; - size_t freeInCache; /* How much free space is stored in this cache */ - threadcacheblk *bins[(THREADCACHEMAXBINS+1)*2]; + int mymspace; /* Last mspace entry this thread used */ + long threadid; + unsigned int mallocs, frees, successes; + size_t freeInCache; /* How much free space is stored in this cache */ + threadcacheblk *bins[(THREADCACHEMAXBINS+1)*2]; #ifdef FULLSANITYCHECKS - unsigned int magic2; + unsigned int magic2; #endif } threadcache; struct nedpool_t { - MLOCK_T mutex; - void *uservalue; - int threads; /* Max entries in m to use */ - threadcache *caches[THREADCACHEMAXCACHES]; - TLSVAR mycache; /* Thread cache for this thread. 0 for unset, negative for use mspace-1 directly, otherwise is cache-1 */ - mstate m[MAXTHREADSINPOOL+1]; /* mspace entries for this pool */ + MLOCK_T mutex; + void *uservalue; + int threads; /* Max entries in m to use */ + threadcache *caches[THREADCACHEMAXCACHES]; + TLSVAR mycache; /* Thread cache for this thread. 0 for unset, negative for use mspace-1 directly, otherwise is cache-1 */ + mstate m[MAXTHREADSINPOOL+1]; /* mspace entries for this pool */ }; static nedpool syspool; static FORCEINLINE unsigned int size2binidx(size_t _size) THROWSPEC -{ /* 8=1000 16=10000 20=10100 24=11000 32=100000 48=110000 4096=1000000000000 */ - unsigned int topbit, size=(unsigned int)(_size>>4); - /* 16=1 20=1 24=1 32=10 48=11 64=100 96=110 128=1000 4096=100000000 */ +{ /* 8=1000 16=10000 20=10100 24=11000 32=100000 48=110000 4096=1000000000000 */ + unsigned int topbit, size=(unsigned int)(_size>>4); + /* 16=1 20=1 24=1 32=10 48=11 64=100 96=110 128=1000 4096=100000000 */ #if defined(__GNUC__) topbit = sizeof(size)*__CHAR_BIT__ - 1 - __builtin_clz(size); #elif defined(_MSC_VER) && _MSC_VER>=1300 - { + { unsigned long bsrTopBit; _BitScanReverse(&bsrTopBit, size); @@ -216,326 +216,326 @@ static FORCEINLINE unsigned int size2binidx(size_t _size) THROWSPEC } #else #if 0 - union { - unsigned asInt[2]; - double asDouble; - }; - int n; - - asDouble = (double)size + 0.5; - topbit = (asInt[!FOX_BIGENDIAN] >> 20) - 1023; + union { + unsigned asInt[2]; + double asDouble; + }; + int n; + + asDouble = (double)size + 0.5; + topbit = (asInt[!FOX_BIGENDIAN] >> 20) - 1023; #else - { - unsigned int x=size; - x = x | (x >> 1); - x = x | (x >> 2); - x = x | (x >> 4); - x = x | (x >> 8); - x = x | (x >>16); - x = ~x; - x = x - ((x >> 1) & 0x55555555); - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0F0F0F0F; - x = x + (x << 8); - x = x + (x << 16); - topbit=31 - (x >> 24); - } + { + unsigned int x=size; + x = x | (x >> 1); + x = x | (x >> 2); + x = x | (x >> 4); + x = x | (x >> 8); + x = x | (x >>16); + x = ~x; + x = x - ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0F0F0F0F; + x = x + (x << 8); + x = x + (x << 16); + topbit=31 - (x >> 24); + } #endif #endif - return topbit; + return topbit; } #ifdef FULLSANITYCHECKS static void tcsanitycheck(threadcacheblk **ptr) THROWSPEC { - assert((ptr[0] && ptr[1]) || (!ptr[0] && !ptr[1])); - if(ptr[0] && ptr[1]) - { - assert(nedblksize(ptr[0])>=sizeof(threadcacheblk)); - assert(nedblksize(ptr[1])>=sizeof(threadcacheblk)); - assert(*(unsigned int *) "NEDN"==ptr[0]->magic); - assert(*(unsigned int *) "NEDN"==ptr[1]->magic); - assert(!ptr[0]->prev); - assert(!ptr[1]->next); - if(ptr[0]==ptr[1]) - { - assert(!ptr[0]->next); - assert(!ptr[1]->prev); - } - } + assert((ptr[0] && ptr[1]) || (!ptr[0] && !ptr[1])); + if(ptr[0] && ptr[1]) + { + assert(nedblksize(ptr[0])>=sizeof(threadcacheblk)); + assert(nedblksize(ptr[1])>=sizeof(threadcacheblk)); + assert(*(unsigned int *) "NEDN"==ptr[0]->magic); + assert(*(unsigned int *) "NEDN"==ptr[1]->magic); + assert(!ptr[0]->prev); + assert(!ptr[1]->next); + if(ptr[0]==ptr[1]) + { + assert(!ptr[0]->next); + assert(!ptr[1]->prev); + } + } } static void tcfullsanitycheck(threadcache *tc) THROWSPEC { - threadcacheblk **tcbptr=tc->bins; - int n; - for(n=0; n<=THREADCACHEMAXBINS; n++, tcbptr+=2) - { - threadcacheblk *b, *ob=0; - tcsanitycheck(tcbptr); - for(b=tcbptr[0]; b; ob=b, b=b->next) - { - assert(*(unsigned int *) "NEDN"==b->magic); - assert(!ob || ob->next==b); - assert(!ob || b->prev==ob); - } - } + threadcacheblk **tcbptr=tc->bins; + int n; + for(n=0; n<=THREADCACHEMAXBINS; n++, tcbptr+=2) + { + threadcacheblk *b, *ob=0; + tcsanitycheck(tcbptr); + for(b=tcbptr[0]; b; ob=b, b=b->next) + { + assert(*(unsigned int *) "NEDN"==b->magic); + assert(!ob || ob->next==b); + assert(!ob || b->prev==ob); + } + } } #endif static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned int age) THROWSPEC { #ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); -#endif - if(tc->freeInCache) - { - threadcacheblk **tcbptr=tc->bins; - int n; - for(n=0; n<=THREADCACHEMAXBINS; n++, tcbptr+=2) - { - threadcacheblk **tcb=tcbptr+1; /* come from oldest end of list */ - /*tcsanitycheck(tcbptr);*/ - for(; *tcb && tc->frees-(*tcb)->lastUsed>=age; ) - { - threadcacheblk *f=*tcb; - size_t blksize=f->size; /*nedblksize(f);*/ - assert(blksize<=nedblksize(f)); - assert(blksize); + tcfullsanitycheck(tc); +#endif + if(tc->freeInCache) + { + threadcacheblk **tcbptr=tc->bins; + int n; + for(n=0; n<=THREADCACHEMAXBINS; n++, tcbptr+=2) + { + threadcacheblk **tcb=tcbptr+1; /* come from oldest end of list */ + /*tcsanitycheck(tcbptr);*/ + for(; *tcb && tc->frees-(*tcb)->lastUsed>=age; ) + { + threadcacheblk *f=*tcb; + size_t blksize=f->size; /*nedblksize(f);*/ + assert(blksize<=nedblksize(f)); + assert(blksize); #ifdef FULLSANITYCHECKS - assert(*(unsigned int *) "NEDN"==(*tcb)->magic); -#endif - *tcb=(*tcb)->prev; - if(*tcb) - (*tcb)->next=0; - else - *tcbptr=0; - tc->freeInCache-=blksize; - assert((long) tc->freeInCache>=0); - mspace_free(0, f); - /*tcsanitycheck(tcbptr);*/ - } - } - } + assert(*(unsigned int *) "NEDN"==(*tcb)->magic); +#endif + *tcb=(*tcb)->prev; + if(*tcb) + (*tcb)->next=0; + else + *tcbptr=0; + tc->freeInCache-=blksize; + assert((long) tc->freeInCache>=0); + mspace_free(0, f); + /*tcsanitycheck(tcbptr);*/ + } + } + } #ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); + tcfullsanitycheck(tc); #endif } static void DestroyCaches(nedpool *p) THROWSPEC { - if(p->caches) - { - threadcache *tc; - int n; - for(n=0; ncaches[n])) - { - tc->frees++; - RemoveCacheEntries(p, tc, 0); - assert(!tc->freeInCache); - tc->mymspace=-1; - tc->threadid=0; - mspace_free(0, tc); - p->caches[n]=0; - } - } - } + if(p->caches) + { + threadcache *tc; + int n; + for(n=0; ncaches[n])) + { + tc->frees++; + RemoveCacheEntries(p, tc, 0); + assert(!tc->freeInCache); + tc->mymspace=-1; + tc->threadid=0; + mspace_free(0, tc); + p->caches[n]=0; + } + } + } } static NOINLINE threadcache *AllocCache(nedpool *p) THROWSPEC { - threadcache *tc=0; - int n, end; - ACQUIRE_LOCK(&p->mutex); - for(n=0; ncaches[n]; n++); - if(THREADCACHEMAXCACHES==n) - { /* List exhausted, so disable for this thread */ - RELEASE_LOCK(&p->mutex); - return 0; - } - tc=p->caches[n]=(threadcache *) mspace_calloc(p->m[0], 1, sizeof(threadcache)); - if(!tc) - { - RELEASE_LOCK(&p->mutex); - return 0; - } + threadcache *tc=0; + int n, end; + ACQUIRE_LOCK(&p->mutex); + for(n=0; ncaches[n]; n++); + if(THREADCACHEMAXCACHES==n) + { /* List exhausted, so disable for this thread */ + RELEASE_LOCK(&p->mutex); + return 0; + } + tc=p->caches[n]=(threadcache *) mspace_calloc(p->m[0], 1, sizeof(threadcache)); + if(!tc) + { + RELEASE_LOCK(&p->mutex); + return 0; + } #ifdef FULLSANITYCHECKS - tc->magic1=*(unsigned int *)"NEDMALC1"; - tc->magic2=*(unsigned int *)"NEDMALC2"; + tc->magic1=*(unsigned int *)"NEDMALC1"; + tc->magic2=*(unsigned int *)"NEDMALC2"; #endif - tc->threadid=(long)(size_t)CURRENT_THREAD; - for(end=0; p->m[end]; end++); - tc->mymspace=tc->threadid % end; - RELEASE_LOCK(&p->mutex); - if(TLSSET(p->mycache, (void *)(size_t)(n+1))) abort(); - return tc; + tc->threadid=(long)(size_t)CURRENT_THREAD; + for(end=0; p->m[end]; end++); + tc->mymspace=tc->threadid % end; + RELEASE_LOCK(&p->mutex); + if(TLSSET(p->mycache, (void *)(size_t)(n+1))) abort(); + return tc; } static void *threadcache_malloc(nedpool *p, threadcache *tc, size_t *size) THROWSPEC { - void *ret=0; - unsigned int bestsize; - unsigned int idx=size2binidx(*size); - size_t blksize=0; - threadcacheblk *blk, **binsptr; + void *ret=0; + unsigned int bestsize; + unsigned int idx=size2binidx(*size); + size_t blksize=0; + threadcacheblk *blk, **binsptr; #ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); + tcfullsanitycheck(tc); #endif - /* Calculate best fit bin size */ - bestsize=1<<(idx+4); + /* Calculate best fit bin size */ + bestsize=1<<(idx+4); #if 0 - /* Finer grained bin fit */ - idx<<=1; - if(*size>bestsize) - { - idx++; - bestsize+=bestsize>>1; - } - if(*size>bestsize) - { - idx++; - bestsize=1<<(4+(idx>>1)); - } + /* Finer grained bin fit */ + idx<<=1; + if(*size>bestsize) + { + idx++; + bestsize+=bestsize>>1; + } + if(*size>bestsize) + { + idx++; + bestsize=1<<(4+(idx>>1)); + } #else - if(*size>bestsize) - { - idx++; - bestsize<<=1; - } -#endif - assert(bestsize>=*size); - if(*sizebins[idx*2]; - /* Try to match close, but move up a bin if necessary */ - blk=*binsptr; - if(!blk || blk->size<*size) - { /* Bump it up a bin */ - if(idxsize; /*nedblksize(blk);*/ - assert(nedblksize(blk)>=blksize); - assert(blksize>=*size); - if(blk->next) - blk->next->prev=0; - *binsptr=blk->next; - if(!*binsptr) - binsptr[1]=0; + if(*size>bestsize) + { + idx++; + bestsize<<=1; + } +#endif + assert(bestsize>=*size); + if(*sizebins[idx*2]; + /* Try to match close, but move up a bin if necessary */ + blk=*binsptr; + if(!blk || blk->size<*size) + { /* Bump it up a bin */ + if(idxsize; /*nedblksize(blk);*/ + assert(nedblksize(blk)>=blksize); + assert(blksize>=*size); + if(blk->next) + blk->next->prev=0; + *binsptr=blk->next; + if(!*binsptr) + binsptr[1]=0; #ifdef FULLSANITYCHECKS - blk->magic=0; -#endif - assert(binsptr[0]!=blk && binsptr[1]!=blk); - assert(nedblksize(blk)>=sizeof(threadcacheblk) && nedblksize(blk)<=THREADCACHEMAX+CHUNK_OVERHEAD); - /*printf("malloc: %p, %p, %p, %lu\n", p, tc, blk, (long) size);*/ - ret=(void *) blk; - } - ++tc->mallocs; - if(ret) - { - assert(blksize>=*size); - ++tc->successes; - tc->freeInCache-=blksize; - assert((long) tc->freeInCache>=0); - } + blk->magic=0; +#endif + assert(binsptr[0]!=blk && binsptr[1]!=blk); + assert(nedblksize(blk)>=sizeof(threadcacheblk) && nedblksize(blk)<=THREADCACHEMAX+CHUNK_OVERHEAD); + /*printf("malloc: %p, %p, %p, %lu\n", p, tc, blk, (long) size);*/ + ret=(void *) blk; + } + ++tc->mallocs; + if(ret) + { + assert(blksize>=*size); + ++tc->successes; + tc->freeInCache-=blksize; + assert((long) tc->freeInCache>=0); + } #if defined(DEBUG) && 0 - if(!(tc->mallocs & 0xfff)) - { - printf("*** threadcache=%u, mallocs=%u (%f), free=%u (%f), freeInCache=%u\n", (unsigned int) tc->threadid, tc->mallocs, - (float) tc->successes/tc->mallocs, tc->frees, (float) tc->successes/tc->frees, (unsigned int) tc->freeInCache); - } + if(!(tc->mallocs & 0xfff)) + { + printf("*** threadcache=%u, mallocs=%u (%f), free=%u (%f), freeInCache=%u\n", (unsigned int) tc->threadid, tc->mallocs, + (float) tc->successes/tc->mallocs, tc->frees, (float) tc->successes/tc->frees, (unsigned int) tc->freeInCache); + } #endif #ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); + tcfullsanitycheck(tc); #endif - return ret; + return ret; } static NOINLINE void ReleaseFreeInCache(nedpool *p, threadcache *tc, int mymspace) THROWSPEC { - unsigned int age=THREADCACHEMAXFREESPACE/8192; - /*ACQUIRE_LOCK(&p->m[mymspace]->mutex);*/ - while(age && tc->freeInCache>=THREADCACHEMAXFREESPACE) - { - RemoveCacheEntries(p, tc, age); - /*printf("*** Removing cache entries older than %u (%u)\n", age, (unsigned int) tc->freeInCache);*/ - age>>=1; - } - /*RELEASE_LOCK(&p->m[mymspace]->mutex);*/ + unsigned int age=THREADCACHEMAXFREESPACE/8192; + /*ACQUIRE_LOCK(&p->m[mymspace]->mutex);*/ + while(age && tc->freeInCache>=THREADCACHEMAXFREESPACE) + { + RemoveCacheEntries(p, tc, age); + /*printf("*** Removing cache entries older than %u (%u)\n", age, (unsigned int) tc->freeInCache);*/ + age>>=1; + } + /*RELEASE_LOCK(&p->m[mymspace]->mutex);*/ } static void threadcache_free(nedpool *p, threadcache *tc, int mymspace, void *mem, size_t size) THROWSPEC { - unsigned int bestsize; - unsigned int idx=size2binidx(size); - threadcacheblk **binsptr, *tck=(threadcacheblk *) mem; - assert(size>=sizeof(threadcacheblk) && size<=THREADCACHEMAX+CHUNK_OVERHEAD); + unsigned int bestsize; + unsigned int idx=size2binidx(size); + threadcacheblk **binsptr, *tck=(threadcacheblk *) mem; + assert(size>=sizeof(threadcacheblk) && size<=THREADCACHEMAX+CHUNK_OVERHEAD); #ifdef DEBUG - { /* Make sure this is a valid memory block */ - mchunkptr cp = mem2chunk(mem); - mstate fm = get_mstate_for(cp); - if (!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, cp); - return; - } - } + { /* Make sure this is a valid memory block */ + mchunkptr cp = mem2chunk(mem); + mstate fm = get_mstate_for(cp); + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, cp); + return; + } + } #endif #ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); + tcfullsanitycheck(tc); #endif - /* Calculate best fit bin size */ - bestsize=1<<(idx+4); + /* Calculate best fit bin size */ + bestsize=1<<(idx+4); #if 0 - /* Finer grained bin fit */ - idx<<=1; - if(size>bestsize) - { - unsigned int biggerbestsize=bestsize+bestsize<<1; - if(size>=biggerbestsize) - { - idx++; - bestsize=biggerbestsize; - } - } -#endif - if(bestsize!=size) /* dlmalloc can round up, so we round down to preserve indexing */ - size=bestsize; - binsptr=&tc->bins[idx*2]; - assert(idx<=THREADCACHEMAXBINS); - if(tck==*binsptr) - { + /* Finer grained bin fit */ + idx<<=1; + if(size>bestsize) + { + unsigned int biggerbestsize=bestsize+bestsize<<1; + if(size>=biggerbestsize) + { + idx++; + bestsize=biggerbestsize; + } + } +#endif + if(bestsize!=size) /* dlmalloc can round up, so we round down to preserve indexing */ + size=bestsize; + binsptr=&tc->bins[idx*2]; + assert(idx<=THREADCACHEMAXBINS); + if(tck==*binsptr) + { fprintf(stderr, "Attempt to free already freed memory block %p - aborting!\n", (void*)tck); - abort(); - } + abort(); + } #ifdef FULLSANITYCHECKS - tck->magic=*(unsigned int *) "NEDN"; -#endif - tck->lastUsed=++tc->frees; - tck->size=(unsigned int) size; - tck->next=*binsptr; - tck->prev=0; - if(tck->next) - tck->next->prev=tck; - else - binsptr[1]=tck; - assert(!*binsptr || (*binsptr)->size==tck->size); - *binsptr=tck; - assert(tck==tc->bins[idx*2]); - assert(tc->bins[idx*2+1]==tck || binsptr[0]->next->prev==tck); - /*printf("free: %p, %p, %p, %lu\n", p, tc, mem, (long) size);*/ - tc->freeInCache+=size; + tck->magic=*(unsigned int *) "NEDN"; +#endif + tck->lastUsed=++tc->frees; + tck->size=(unsigned int) size; + tck->next=*binsptr; + tck->prev=0; + if(tck->next) + tck->next->prev=tck; + else + binsptr[1]=tck; + assert(!*binsptr || (*binsptr)->size==tck->size); + *binsptr=tck; + assert(tck==tc->bins[idx*2]); + assert(tc->bins[idx*2+1]==tck || binsptr[0]->next->prev==tck); + /*printf("free: %p, %p, %p, %lu\n", p, tc, mem, (long) size);*/ + tc->freeInCache+=size; #ifdef FULLSANITYCHECKS - tcfullsanitycheck(tc); + tcfullsanitycheck(tc); #endif #if 1 - if(tc->freeInCache>=THREADCACHEMAXFREESPACE) - ReleaseFreeInCache(p, tc, mymspace); + if(tc->freeInCache>=THREADCACHEMAXFREESPACE) + ReleaseFreeInCache(p, tc, mymspace); #endif } @@ -543,169 +543,169 @@ static void threadcache_free(nedpool *p, threadcache *tc, int mymspace, void *me static NOINLINE int InitPool(nedpool *p, size_t capacity, int threads) THROWSPEC -{ /* threads is -1 for system pool */ - ensure_initialization(); - ACQUIRE_MALLOC_GLOBAL_LOCK(); - if(p->threads) goto done; - if(INITIAL_LOCK(&p->mutex)) goto err; - if(TLSALLOC(&p->mycache)) goto err; - if(!(p->m[0]=(mstate) create_mspace(capacity, 1))) goto err; - p->m[0]->extp=p; - p->threads=(threads<1 || threads>MAXTHREADSINPOOL) ? MAXTHREADSINPOOL : threads; +{ /* threads is -1 for system pool */ + ensure_initialization(); + ACQUIRE_MALLOC_GLOBAL_LOCK(); + if(p->threads) goto done; + if(INITIAL_LOCK(&p->mutex)) goto err; + if(TLSALLOC(&p->mycache)) goto err; + if(!(p->m[0]=(mstate) create_mspace(capacity, 1))) goto err; + p->m[0]->extp=p; + p->threads=(threads<1 || threads>MAXTHREADSINPOOL) ? MAXTHREADSINPOOL : threads; done: - RELEASE_MALLOC_GLOBAL_LOCK(); - return 1; + RELEASE_MALLOC_GLOBAL_LOCK(); + return 1; err: - if(threads<0) - abort(); /* If you can't allocate for system pool, we're screwed */ - DestroyCaches(p); - if(p->m[0]) - { - destroy_mspace(p->m[0]); - p->m[0]=0; - } - if(p->mycache) - { - if(TLSFREE(p->mycache)) abort(); - p->mycache=0; - } - RELEASE_MALLOC_GLOBAL_LOCK(); - return 0; + if(threads<0) + abort(); /* If you can't allocate for system pool, we're screwed */ + DestroyCaches(p); + if(p->m[0]) + { + destroy_mspace(p->m[0]); + p->m[0]=0; + } + if(p->mycache) + { + if(TLSFREE(p->mycache)) abort(); + p->mycache=0; + } + RELEASE_MALLOC_GLOBAL_LOCK(); + return 0; } static NOINLINE mstate FindMSpace(nedpool *p, threadcache *tc, int *lastUsed, size_t size) THROWSPEC -{ /* Gets called when thread's last used mspace is in use. The strategy - is to run through the list of all available mspaces looking for an - unlocked one and if we fail, we create a new one so long as we don't - exceed p->threads */ - int n, end; - for(n=end=*lastUsed+1; p->m[n]; end=++n) - { - if(TRY_LOCK(&p->m[n]->mutex)) goto found; - } - for(n=0; n<*lastUsed && p->m[n]; n++) - { - if(TRY_LOCK(&p->m[n]->mutex)) goto found; - } - if(endthreads) - { - mstate temp; - if(!(temp=(mstate) create_mspace(size, 1))) - goto badexit; - /* Now we're ready to modify the lists, we lock */ - ACQUIRE_LOCK(&p->mutex); - while(p->m[end] && endthreads) - end++; - if(end>=p->threads) - { /* Drat, must destroy it now */ - RELEASE_LOCK(&p->mutex); - destroy_mspace((mspace) temp); - goto badexit; - } - /* We really want to make sure this goes into memory now but we - have to be careful of breaking aliasing rules, so write it twice */ - *((volatile struct malloc_state **) &p->m[end])=p->m[end]=temp; - ACQUIRE_LOCK(&p->m[end]->mutex); - /*printf("Created mspace idx %d\n", end);*/ - RELEASE_LOCK(&p->mutex); - n=end; - goto found; - } - /* Let it lock on the last one it used */ +{ /* Gets called when thread's last used mspace is in use. The strategy + is to run through the list of all available mspaces looking for an + unlocked one and if we fail, we create a new one so long as we don't + exceed p->threads */ + int n, end; + for(n=end=*lastUsed+1; p->m[n]; end=++n) + { + if(TRY_LOCK(&p->m[n]->mutex)) goto found; + } + for(n=0; n<*lastUsed && p->m[n]; n++) + { + if(TRY_LOCK(&p->m[n]->mutex)) goto found; + } + if(endthreads) + { + mstate temp; + if(!(temp=(mstate) create_mspace(size, 1))) + goto badexit; + /* Now we're ready to modify the lists, we lock */ + ACQUIRE_LOCK(&p->mutex); + while(p->m[end] && endthreads) + end++; + if(end>=p->threads) + { /* Drat, must destroy it now */ + RELEASE_LOCK(&p->mutex); + destroy_mspace((mspace) temp); + goto badexit; + } + /* We really want to make sure this goes into memory now but we + have to be careful of breaking aliasing rules, so write it twice */ + *((volatile struct malloc_state **) &p->m[end])=p->m[end]=temp; + ACQUIRE_LOCK(&p->m[end]->mutex); + /*printf("Created mspace idx %d\n", end);*/ + RELEASE_LOCK(&p->mutex); + n=end; + goto found; + } + /* Let it lock on the last one it used */ badexit: - ACQUIRE_LOCK(&p->m[*lastUsed]->mutex); - return p->m[*lastUsed]; + ACQUIRE_LOCK(&p->m[*lastUsed]->mutex); + return p->m[*lastUsed]; found: - *lastUsed=n; - if(tc) - tc->mymspace=n; - else - { - if(TLSSET(p->mycache, (void *)(size_t)(-(n+1)))) abort(); - } - return p->m[n]; + *lastUsed=n; + if(tc) + tc->mymspace=n; + else + { + if(TLSSET(p->mycache, (void *)(size_t)(-(n+1)))) abort(); + } + return p->m[n]; } nedpool *nedcreatepool(size_t capacity, int threads) THROWSPEC { - nedpool *ret; - if(!(ret=(nedpool *) nedpcalloc(0, 1, sizeof(nedpool)))) return 0; - if(!InitPool(ret, capacity, threads)) - { - nedpfree(0, ret); - return 0; - } - return ret; + nedpool *ret; + if(!(ret=(nedpool *) nedpcalloc(0, 1, sizeof(nedpool)))) return 0; + if(!InitPool(ret, capacity, threads)) + { + nedpfree(0, ret); + return 0; + } + return ret; } void neddestroypool(nedpool *p) THROWSPEC { - int n; - ACQUIRE_LOCK(&p->mutex); - DestroyCaches(p); - for(n=0; p->m[n]; n++) - { - destroy_mspace(p->m[n]); - p->m[n]=0; - } - RELEASE_LOCK(&p->mutex); - if(TLSFREE(p->mycache)) abort(); - nedpfree(0, p); + int n; + ACQUIRE_LOCK(&p->mutex); + DestroyCaches(p); + for(n=0; p->m[n]; n++) + { + destroy_mspace(p->m[n]); + p->m[n]=0; + } + RELEASE_LOCK(&p->mutex); + if(TLSFREE(p->mycache)) abort(); + nedpfree(0, p); } void nedpsetvalue(nedpool *p, void *v) THROWSPEC { - if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } - p->uservalue=v; + if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } + p->uservalue=v; } void *nedgetvalue(nedpool **p, void *mem) THROWSPEC { - nedpool *np=0; - mchunkptr mcp=mem2chunk(mem); - mstate fm; - if(!(is_aligned(chunk2mem(mcp))) && mcp->head != FENCEPOST_HEAD) return 0; - if(!cinuse(mcp)) return 0; - if(!next_pinuse(mcp)) return 0; - if(!is_mmapped(mcp) && !pinuse(mcp)) - { - if(next_chunk(prev_chunk(mcp))!=mcp) return 0; - } - fm=get_mstate_for(mcp); - if(!ok_magic(fm)) return 0; - if(!ok_address(fm, mcp)) return 0; - if(!fm->extp) return 0; - np=(nedpool *) fm->extp; - if(p) *p=np; - return np->uservalue; + nedpool *np=0; + mchunkptr mcp=mem2chunk(mem); + mstate fm; + if(!(is_aligned(chunk2mem(mcp))) && mcp->head != FENCEPOST_HEAD) return 0; + if(!cinuse(mcp)) return 0; + if(!next_pinuse(mcp)) return 0; + if(!is_mmapped(mcp) && !pinuse(mcp)) + { + if(next_chunk(prev_chunk(mcp))!=mcp) return 0; + } + fm=get_mstate_for(mcp); + if(!ok_magic(fm)) return 0; + if(!ok_address(fm, mcp)) return 0; + if(!fm->extp) return 0; + np=(nedpool *) fm->extp; + if(p) *p=np; + return np->uservalue; } void neddisablethreadcache(nedpool *p) THROWSPEC { - int mycache; - if(!p) - { - p=&syspool; - if(!syspool.threads) InitPool(&syspool, 0, -1); - } - mycache=(int)(size_t) TLSGET(p->mycache); - if(!mycache) - { /* Set to mspace 0 */ - if(TLSSET(p->mycache, (void *)-1)) abort(); - } - else if(mycache>0) - { /* Set to last used mspace */ - threadcache *tc=p->caches[mycache-1]; + int mycache; + if(!p) + { + p=&syspool; + if(!syspool.threads) InitPool(&syspool, 0, -1); + } + mycache=(int)(size_t) TLSGET(p->mycache); + if(!mycache) + { /* Set to mspace 0 */ + if(TLSSET(p->mycache, (void *)-1)) abort(); + } + else if(mycache>0) + { /* Set to last used mspace */ + threadcache *tc=p->caches[mycache-1]; #if defined(DEBUG) - printf("Threadcache utilisation: %lf%% in cache with %lf%% lost to other threads\n", - 100.0*tc->successes/tc->mallocs, 100.0*((double) tc->mallocs-tc->frees)/tc->mallocs); + printf("Threadcache utilisation: %lf%% in cache with %lf%% lost to other threads\n", + 100.0*tc->successes/tc->mallocs, 100.0*((double) tc->mallocs-tc->frees)/tc->mallocs); #endif - if(TLSSET(p->mycache, (void *)(size_t)(-tc->mymspace))) abort(); - tc->frees++; - RemoveCacheEntries(p, tc, 0); - assert(!tc->freeInCache); - tc->mymspace=-1; - tc->threadid=0; - mspace_free(0, p->caches[mycache-1]); - p->caches[mycache-1]=0; - } + if(TLSSET(p->mycache, (void *)(size_t)(-tc->mymspace))) abort(); + tc->frees++; + RemoveCacheEntries(p, tc, 0); + assert(!tc->freeInCache); + tc->mymspace=-1; + tc->threadid=0; + mspace_free(0, p->caches[mycache-1]); + p->caches[mycache-1]=0; + } } #define GETMSPACE(m,p,tc,ms,s,action) \ @@ -717,232 +717,232 @@ void neddisablethreadcache(nedpool *p) THROWSPEC } while (0) static FORCEINLINE mstate GetMSpace(nedpool *p, threadcache *tc, int mymspace, size_t size) THROWSPEC -{ /* Returns a locked and ready for use mspace */ - mstate m=p->m[mymspace]; - assert(m); - if(!TRY_LOCK(&p->m[mymspace]->mutex)) m=FindMSpace(p, tc, &mymspace, size);\ - /*assert(IS_LOCKED(&p->m[mymspace]->mutex));*/ - return m; +{ /* Returns a locked and ready for use mspace */ + mstate m=p->m[mymspace]; + assert(m); + if(!TRY_LOCK(&p->m[mymspace]->mutex)) m=FindMSpace(p, tc, &mymspace, size);\ + /*assert(IS_LOCKED(&p->m[mymspace]->mutex));*/ + return m; } static FORCEINLINE void GetThreadCache(nedpool **p, threadcache **tc, int *mymspace, size_t *size) THROWSPEC { - int mycache; - if(size && *sizemycache); - if(mycache>0) - { - *tc=(*p)->caches[mycache-1]; - *mymspace=(*tc)->mymspace; - } - else if(!mycache) - { - *tc=AllocCache(*p); - if(!*tc) - { /* Disable */ - if(TLSSET((*p)->mycache, (void *)-1)) abort(); - *mymspace=0; - } - else - *mymspace=(*tc)->mymspace; - } - else - { - *tc=0; - *mymspace=-mycache-1; - } - assert(*mymspace>=0); - assert((long)(size_t)CURRENT_THREAD==(*tc)->threadid); + int mycache; + if(size && *sizemycache); + if(mycache>0) + { + *tc=(*p)->caches[mycache-1]; + *mymspace=(*tc)->mymspace; + } + else if(!mycache) + { + *tc=AllocCache(*p); + if(!*tc) + { /* Disable */ + if(TLSSET((*p)->mycache, (void *)-1)) abort(); + *mymspace=0; + } + else + *mymspace=(*tc)->mymspace; + } + else + { + *tc=0; + *mymspace=-mycache-1; + } + assert(*mymspace>=0); + assert((long)(size_t)CURRENT_THREAD==(*tc)->threadid); #ifdef FULLSANITYCHECKS - if(*tc) - { - if(*(unsigned int *)"NEDMALC1"!=(*tc)->magic1 || *(unsigned int *)"NEDMALC2"!=(*tc)->magic2) - { - abort(); - } - } + if(*tc) + { + if(*(unsigned int *)"NEDMALC1"!=(*tc)->magic1 || *(unsigned int *)"NEDMALC2"!=(*tc)->magic2) + { + abort(); + } + } #endif } void * nedpmalloc(nedpool *p, size_t size) THROWSPEC { - void *ret=0; - threadcache *tc; - int mymspace; - GetThreadCache(&p, &tc, &mymspace, &size); + void *ret=0; + threadcache *tc; + int mymspace; + GetThreadCache(&p, &tc, &mymspace, &size); #if THREADCACHEMAX - if(tc && size<=THREADCACHEMAX) - { /* Use the thread cache */ - ret=threadcache_malloc(p, tc, &size); - } + if(tc && size<=THREADCACHEMAX) + { /* Use the thread cache */ + ret=threadcache_malloc(p, tc, &size); + } #endif - if(!ret) - { /* Use this thread's mspace */ + if(!ret) + { /* Use this thread's mspace */ GETMSPACE(m, p, tc, mymspace, size, ret=mspace_malloc(m, size)); - } - return ret; + } + return ret; } void * nedpcalloc(nedpool *p, size_t no, size_t size) THROWSPEC { - size_t rsize=size*no; - void *ret=0; - threadcache *tc; - int mymspace; - GetThreadCache(&p, &tc, &mymspace, &rsize); + size_t rsize=size*no; + void *ret=0; + threadcache *tc; + int mymspace; + GetThreadCache(&p, &tc, &mymspace, &rsize); #if THREADCACHEMAX - if(tc && rsize<=THREADCACHEMAX) - { /* Use the thread cache */ - if((ret=threadcache_malloc(p, tc, &rsize))) - memset(ret, 0, rsize); - } -#endif - if(!ret) - { /* Use this thread's mspace */ + if(tc && rsize<=THREADCACHEMAX) + { /* Use the thread cache */ + if((ret=threadcache_malloc(p, tc, &rsize))) + memset(ret, 0, rsize); + } +#endif + if(!ret) + { /* Use this thread's mspace */ GETMSPACE(m, p, tc, mymspace, rsize, ret=mspace_calloc(m, 1, rsize)); - } - return ret; + } + return ret; } void * nedprealloc(nedpool *p, void *mem, size_t size) THROWSPEC { - void *ret=0; - threadcache *tc; - int mymspace; - if(!mem) return nedpmalloc(p, size); - GetThreadCache(&p, &tc, &mymspace, &size); + void *ret=0; + threadcache *tc; + int mymspace; + if(!mem) return nedpmalloc(p, size); + GetThreadCache(&p, &tc, &mymspace, &size); #if THREADCACHEMAX - if(tc && size && size<=THREADCACHEMAX) - { /* Use the thread cache */ - size_t memsize=nedblksize(mem); - assert(memsize); - if((ret=threadcache_malloc(p, tc, &size))) - { - memcpy(ret, mem, memsizem[n]; n++) - { - struct mallinfo t=mspace_mallinfo(p->m[n]); - ret.arena+=t.arena; - ret.ordblks+=t.ordblks; - ret.hblkhd+=t.hblkhd; - ret.usmblks+=t.usmblks; - ret.uordblks+=t.uordblks; - ret.fordblks+=t.fordblks; - ret.keepcost+=t.keepcost; - } - return ret; + int n; + struct mallinfo ret={0,0,0,0,0,0,0,0,0,0}; + if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } + for(n=0; p->m[n]; n++) + { + struct mallinfo t=mspace_mallinfo(p->m[n]); + ret.arena+=t.arena; + ret.ordblks+=t.ordblks; + ret.hblkhd+=t.hblkhd; + ret.usmblks+=t.usmblks; + ret.uordblks+=t.uordblks; + ret.fordblks+=t.fordblks; + ret.keepcost+=t.keepcost; + } + return ret; } #endif int nedpmallopt(nedpool *p, int parno, int value) THROWSPEC { - return mspace_mallopt(parno, value); + return mspace_mallopt(parno, value); } int nedpmalloc_trim(nedpool *p, size_t pad) THROWSPEC { - int n, ret=0; - if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } - for(n=0; p->m[n]; n++) - { - ret+=mspace_trim(p->m[n], pad); - } - return ret; + int n, ret=0; + if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } + for(n=0; p->m[n]; n++) + { + ret+=mspace_trim(p->m[n], pad); + } + return ret; } void nedpmalloc_stats(nedpool *p) THROWSPEC { - int n; - if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } - for(n=0; p->m[n]; n++) - { - mspace_malloc_stats(p->m[n]); - } + int n; + if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } + for(n=0; p->m[n]; n++) + { + mspace_malloc_stats(p->m[n]); + } } size_t nedpmalloc_footprint(nedpool *p) THROWSPEC { - size_t ret=0; - int n; - if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } - for(n=0; p->m[n]; n++) - { - ret+=mspace_footprint(p->m[n]); - } - return ret; + size_t ret=0; + int n; + if(!p) { p=&syspool; if(!syspool.threads) InitPool(&syspool, 0, -1); } + for(n=0; p->m[n]; n++) + { + ret+=mspace_footprint(p->m[n]); + } + return ret; } void **nedpindependent_calloc(nedpool *p, size_t elemsno, size_t elemsize, void **chunks) THROWSPEC { - void **ret; - threadcache *tc; - int mymspace; - GetThreadCache(&p, &tc, &mymspace, &elemsize); + void **ret; + threadcache *tc; + int mymspace; + GetThreadCache(&p, &tc, &mymspace, &elemsize); GETMSPACE(m, p, tc, mymspace, elemsno*elemsize, ret=mspace_independent_calloc(m, elemsno, elemsize, chunks)); - return ret; + return ret; } void **nedpindependent_comalloc(nedpool *p, size_t elems, size_t *sizes, void **chunks) THROWSPEC { - void **ret; - threadcache *tc; - int mymspace; + void **ret; + threadcache *tc; + int mymspace; size_t i, *adjustedsizes=(size_t *) alloca(elems*sizeof(size_t)); if(!adjustedsizes) return 0; for(i=0; i::type mPlayerStarts; + vector::type mPlayerStarts; /** Internal utility function for loading data from Quake3. */ void loadQuake3Level(const Quake3Level& q3lvl); @@ -190,25 +190,25 @@ namespace Ogre { /** Internal method for parsing chosen entities. */ void loadEntities(const Quake3Level& q3lvl); - typedef map::type >::type MovableToNodeMap; + typedef map::type >::type MovableToNodeMap; /// Map for locating the nodes a movable is currently a member of MovableToNodeMap mMovableToNodeMap; void tagNodesWithMovable(BspNode* node, const MovableObject* mov, const Vector3& pos); /// Storage of patches - typedef map::type PatchMap; + typedef map::type PatchMap; PatchMap mPatches; /// Total number of vertices required for all patches size_t mPatchVertexCount; /// Total number of indexes required for all patches size_t mPatchIndexCount; - /// Sky enabled? - bool mSkyEnabled; - /// Sky material - String mSkyMaterial; - /// Sky details - Real mSkyCurvature; + /// Sky enabled? + bool mSkyEnabled; + /// Sky material + String mSkyMaterial; + /// Sky details + Real mSkyCurvature; void initQuake3Patches(const Quake3Level & q3lvl, VertexDeclaration* decl); diff --git a/PlugIns/BSPSceneManager/include/OgreBspNode.h b/PlugIns/BSPSceneManager/include/OgreBspNode.h index b7bb41fc86b..56c4e593f05 100644 --- a/PlugIns/BSPSceneManager/include/OgreBspNode.h +++ b/PlugIns/BSPSceneManager/include/OgreBspNode.h @@ -48,7 +48,7 @@ namespace Ogre { getBack() return null pointers. If the node is a partitioning plane isLeaf() returns false and getFront() and getBack() will return the corresponding BspNode objects. */ - class BspNode : public NodeAlloc + class BspNode : public NodeAlloc { friend class BspLevel; @@ -142,14 +142,14 @@ namespace Ogre { /// Gets the signed distance to the dividing plane Real getDistance(const Vector3& pos) const; - typedef set::type IntersectingObjectSet; + typedef set::type IntersectingObjectSet; struct Brush { - list::type planes; + list::type planes; SceneQuery::WorldFragment fragment; /// For query reporting }; - typedef vector::type NodeBrushList; /// Main brush memory held on level + typedef vector::type NodeBrushList; /// Main brush memory held on level /** Get the list of solid Brushes for this node. @remarks Only applicable for leaf nodes. diff --git a/PlugIns/BSPSceneManager/include/OgreBspPrerequisites.h b/PlugIns/BSPSceneManager/include/OgreBspPrerequisites.h index bd20958a5ee..184e5162cdf 100644 --- a/PlugIns/BSPSceneManager/include/OgreBspPrerequisites.h +++ b/PlugIns/BSPSceneManager/include/OgreBspPrerequisites.h @@ -43,20 +43,20 @@ namespace Ogre { class Quake3Shader; #if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && !defined(OGRE_STATIC_LIB) -# ifdef OGRE_BSPPLUGIN_EXPORTS -# define _OgreBspPluginExport __declspec(dllexport) -# else +# ifdef OGRE_BSPPLUGIN_EXPORTS +# define _OgreBspPluginExport __declspec(dllexport) +# else # if defined( __MINGW32__ ) # define _OgreBspPluginExport # else -# define _OgreBspPluginExport __declspec(dllimport) +# define _OgreBspPluginExport __declspec(dllimport) # endif # endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgreBspPluginExport __attribute__ ((visibility("default"))) #else -# define _OgreBspPluginExport -#endif // OGRE_WIN32 +# define _OgreBspPluginExport +#endif // OGRE_WIN32 } diff --git a/PlugIns/BSPSceneManager/include/OgreBspSceneManager.h b/PlugIns/BSPSceneManager/include/OgreBspSceneManager.h index 2cdb81fc32b..668bc39a0d4 100644 --- a/PlugIns/BSPSceneManager/include/OgreBspSceneManager.h +++ b/PlugIns/BSPSceneManager/include/OgreBspSceneManager.h @@ -70,10 +70,10 @@ namespace Ogre { // State variables for rendering WIP // Set of face groups (by index) already included - typedef set::type FaceGroupSet; + typedef set::type FaceGroupSet; FaceGroupSet mFaceGroupSet; // Material -> face group hashmap - typedef map::type, materialLess >::type MaterialFaceGroupMap; + typedef map::type, materialLess >::type MaterialFaceGroupMap; MaterialFaceGroupMap mMatFaceGroupMap; RenderOperation mRenderOp; @@ -91,7 +91,7 @@ namespace Ogre { BspNode* walkTree(Camera* camera, VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters); /** Tags geometry in the leaf specified for later rendering. */ void processVisibleLeaf(BspNode* leaf, Camera* cam, - VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters); + VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters); /** Caches a face group for imminent rendering. */ unsigned int cacheGeometry(unsigned int* pIndexes, const StaticFaceGroup* faceGroup); @@ -105,13 +105,13 @@ namespace Ogre { /** Renders the static level geometry tagged in walkTree. */ void renderStaticGeometry(void); - /** @copydoc SceneManager::clearScene */ - void clearScene(void); + /** @copydoc SceneManager::clearScene */ + void clearScene(void); - // Overridden so we can manually render world geometry - bool fireRenderQueueEnded(uint8 id, const String& invocation); + // Overridden so we can manually render world geometry + bool fireRenderQueueEnded(uint8 id, const String& invocation); - typedef set::type MovablesForRendering; + typedef set::type MovablesForRendering; MovablesForRendering mMovablesForRendering; public: @@ -119,8 +119,8 @@ namespace Ogre { ~BspSceneManager(); - /// @copydoc SceneManager::getTypeName - const String& getTypeName(void) const; + /// @copydoc SceneManager::getTypeName + const String& getTypeName(void) const; /** Specialised from SceneManager to support Quake3 bsp files. */ void setWorldGeometry(const String& filename); @@ -130,13 +130,13 @@ namespace Ogre { /** Specialised from SceneManager to support Quake3 bsp files. */ void setWorldGeometry(DataStreamPtr& stream, - const String& typeName = BLANKSTRING); + const String& typeName = BLANKSTRING); /** Specialised from SceneManager to support Quake3 bsp files. */ size_t estimateWorldGeometry(DataStreamPtr& stream, - const String& typeName = BLANKSTRING); + const String& typeName = BLANKSTRING); - /** Tells the manager whether to draw the axis-aligned boxes that surround + /** Tells the manager whether to draw the axis-aligned boxes that surround nodes in the Bsp tree. For debugging purposes. */ void showNodeBoxes(bool show); @@ -148,7 +148,7 @@ namespace Ogre { /** Overridden from SceneManager. */ void _findVisibleObjects(Camera* cam, VisibleObjectsBoundsInfo* visibleBounds, - bool onlyShadowCasters); + bool onlyShadowCasters); /** Creates a specialized BspSceneNode */ SceneNode * createSceneNodeImpl ( void ); @@ -157,8 +157,8 @@ namespace Ogre { /** Internal method for tagging BspNodes with objects which intersect them. */ void _notifyObjectMoved(const MovableObject* mov, const Vector3& pos); - /** Internal method for notifying the level that an object has been detached from a node */ - void _notifyObjectDetached(const MovableObject* mov); + /** Internal method for notifying the level that an object has been detached from a node */ + void _notifyObjectDetached(const MovableObject* mov); /* Creates an AxisAlignedBoxSceneQuery for this scene manager. @remarks @@ -244,9 +244,9 @@ namespace Ogre { void execute(RaySceneQueryListener* listener); protected: /// Set for eliminating duplicates since objects can be in > 1 node - set::type mObjsThisQuery; + set::type mObjsThisQuery; /// list of the last single intersection world fragments (derived) - vector::type mSingleIntersections; + vector::type mSingleIntersections; void clearTemporaries(void); /** Internal processing of a single node. @@ -262,19 +262,19 @@ namespace Ogre { }; - /// Factory for BspSceneManager - class BspSceneManagerFactory : public SceneManagerFactory - { - protected: - void initMetaData(void) const; - public: - BspSceneManagerFactory() {} - ~BspSceneManagerFactory() {} - /// Factory type name - static const String FACTORY_TYPE_NAME; - SceneManager* createInstance(const String& instanceName); - void destroyInstance(SceneManager* instance); - }; + /// Factory for BspSceneManager + class BspSceneManagerFactory : public SceneManagerFactory + { + protected: + void initMetaData(void) const; + public: + BspSceneManagerFactory() {} + ~BspSceneManagerFactory() {} + /// Factory type name + static const String FACTORY_TYPE_NAME; + SceneManager* createInstance(const String& instanceName); + void destroyInstance(SceneManager* instance); + }; } #endif diff --git a/PlugIns/BSPSceneManager/include/OgreBspSceneManagerPlugin.h b/PlugIns/BSPSceneManager/include/OgreBspSceneManagerPlugin.h index ebba9902f4f..c3bebcc0d57 100644 --- a/PlugIns/BSPSceneManager/include/OgreBspSceneManagerPlugin.h +++ b/PlugIns/BSPSceneManager/include/OgreBspSceneManagerPlugin.h @@ -35,33 +35,33 @@ THE SOFTWARE. namespace Ogre { - /** Plugin instance for BSPSceneManager */ - class BspSceneManagerPlugin : public Plugin - { - public: - BspSceneManagerPlugin(); + /** Plugin instance for BSPSceneManager */ + class BspSceneManagerPlugin : public Plugin + { + public: + BspSceneManagerPlugin(); - /// @copydoc Plugin::getName - const String& getName() const; + /// @copydoc Plugin::getName + const String& getName() const; - /// @copydoc Plugin::install - void install(); + /// @copydoc Plugin::install + void install(); - /// @copydoc Plugin::initialise - void initialise(); + /// @copydoc Plugin::initialise + void initialise(); - /// @copydoc Plugin::shutdown - void shutdown(); + /// @copydoc Plugin::shutdown + void shutdown(); - /// @copydoc Plugin::uninstall - void uninstall(); - protected: - BspSceneManagerFactory* mBspFactory; - BspResourceManager* mBspResourceManager; + /// @copydoc Plugin::uninstall + void uninstall(); + protected: + BspSceneManagerFactory* mBspFactory; + BspResourceManager* mBspResourceManager; - }; + }; } #endif diff --git a/PlugIns/BSPSceneManager/include/OgreBspSceneNode.h b/PlugIns/BSPSceneManager/include/OgreBspSceneNode.h index 57d3a4cab22..0f4a66e3b0b 100644 --- a/PlugIns/BSPSceneManager/include/OgreBspSceneNode.h +++ b/PlugIns/BSPSceneManager/include/OgreBspSceneNode.h @@ -48,9 +48,9 @@ namespace Ogre { */ class BspSceneNode : public SceneNode { - protected: - /// Overridden from SceneNode - void setInSceneGraph(bool inGraph); + protected: + /// Overridden from SceneNode + void setInSceneGraph(bool inGraph); public: BspSceneNode(SceneManager* creator) : SceneNode(creator) {} BspSceneNode(SceneManager* creator, const String& name) diff --git a/PlugIns/BSPSceneManager/include/OgreQuake3Level.h b/PlugIns/BSPSceneManager/include/OgreQuake3Level.h index 8f82739efa9..6f8dd5276a5 100644 --- a/PlugIns/BSPSceneManager/include/OgreQuake3Level.h +++ b/PlugIns/BSPSceneManager/include/OgreQuake3Level.h @@ -59,7 +59,7 @@ namespace Ogre { be valid after the original call. This is why it has no accessor methods for reading it's internal state. */ - class Quake3Level : public ResourceAlloc + class Quake3Level : public ResourceAlloc { public: Quake3Level(); diff --git a/PlugIns/BSPSceneManager/include/OgreQuake3Shader.h b/PlugIns/BSPSceneManager/include/OgreQuake3Shader.h index ac0b0628a6c..36009200020 100644 --- a/PlugIns/BSPSceneManager/include/OgreQuake3Shader.h +++ b/PlugIns/BSPSceneManager/include/OgreQuake3Shader.h @@ -47,7 +47,7 @@ namespace Ogre { temporarily since their instantiations as Materials would use precious resources because of the automatic loading of textures etc. */ - class Quake3Shader : public ResourceAlloc + class Quake3Shader : public ResourceAlloc { protected: String getAlternateName(const String& texName); @@ -99,7 +99,7 @@ namespace Ogre { unsigned int flags; int numPasses; - typedef vector::type PassList; + typedef vector::type PassList; PassList pass; bool farbox; // Skybox String farboxName; diff --git a/PlugIns/BSPSceneManager/include/OgreQuake3ShaderManager.h b/PlugIns/BSPSceneManager/include/OgreQuake3ShaderManager.h index 50225f4c5ee..4672acb4f84 100644 --- a/PlugIns/BSPSceneManager/include/OgreQuake3ShaderManager.h +++ b/PlugIns/BSPSceneManager/include/OgreQuake3ShaderManager.h @@ -59,7 +59,7 @@ namespace Ogre { void parseShaderPassAttrib( const String& line, Quake3Shader* pShader, Quake3Shader::Pass* pPass); SceneBlendFactor convertBlendFunc( const String& q3func); - typedef map::type Quake3ShaderMap; + typedef map::type Quake3ShaderMap; Quake3ShaderMap mShaderMap; StringVector mScriptPatterns; diff --git a/PlugIns/BSPSceneManager/include/OgreQuake3Types.h b/PlugIns/BSPSceneManager/include/OgreQuake3Types.h index 470cdb49c47..2e4b7c00883 100644 --- a/PlugIns/BSPSceneManager/include/OgreQuake3Types.h +++ b/PlugIns/BSPSceneManager/include/OgreQuake3Types.h @@ -234,8 +234,8 @@ struct bsp_header_t { // Brushes sides in BSP tree // struct bsp_brushside_t { - int planenum; - int content; // ??shader?? + int planenum; + int content; // ??shader?? }; @@ -243,8 +243,8 @@ struct bsp_brushside_t { // Brushes in BSP tree // struct bsp_brush_t { - int firstside; - int numsides; - int shaderIndex; + int firstside; + int numsides; + int shaderIndex; }; #endif diff --git a/PlugIns/BSPSceneManager/src/OgreBspLevel.cpp b/PlugIns/BSPSceneManager/src/OgreBspLevel.cpp index aa7a837348e..d391f25a9ea 100644 --- a/PlugIns/BSPSceneManager/src/OgreBspLevel.cpp +++ b/PlugIns/BSPSceneManager/src/OgreBspLevel.cpp @@ -63,7 +63,7 @@ namespace Ogre { mLeafFaceGroups(0), mFaceGroups(0), mBrushes(0), - mSkyEnabled(false) + mSkyEnabled(false) { mVisData.tableData = 0; @@ -85,34 +85,34 @@ namespace Ogre { //----------------------------------------------------------------------- void BspLevel::loadImpl() { - mSkyEnabled = false; + mSkyEnabled = false; // Use Quake3 file loader Quake3Level q3; DataStreamPtr stream = - ResourceGroupManager::getSingleton().openResource(mName, - ResourceGroupManager::getSingleton().getWorldResourceGroupName()); + ResourceGroupManager::getSingleton().openResource(mName, + ResourceGroupManager::getSingleton().getWorldResourceGroupName()); q3.loadFromStream(stream); loadQuake3Level(q3); } - //----------------------------------------------------------------------- - bool BspLevel::isSkyEnabled(void) const - { - return mSkyEnabled; - } - //----------------------------------------------------------------------- - const String& BspLevel::getSkyMaterialName(void) const - { - return mSkyMaterial; - } - //----------------------------------------------------------------------- - Real BspLevel::getSkyCurvature(void) const - { - return mSkyCurvature; - } + //----------------------------------------------------------------------- + bool BspLevel::isSkyEnabled(void) const + { + return mSkyEnabled; + } + //----------------------------------------------------------------------- + const String& BspLevel::getSkyMaterialName(void) const + { + return mSkyMaterial; + } + //----------------------------------------------------------------------- + Real BspLevel::getSkyCurvature(void) const + { + return mSkyCurvature; + } //----------------------------------------------------------------------- void BspLevel::load(DataStreamPtr& stream) { @@ -138,7 +138,7 @@ namespace Ogre { if (mVisData.tableData) OGRE_FREE(mVisData.tableData, MEMCATEGORY_GEOMETRY); if (mBrushes) - OGRE_DELETE_ARRAY_T(mBrushes, Brush, (size_t)mNumBrushes, MEMCATEGORY_GEOMETRY); + OGRE_DELETE_ARRAY_T(mBrushes, Brush, (size_t)mNumBrushes, MEMCATEGORY_GEOMETRY); mVertexData = 0; mRootNode = 0; @@ -158,8 +158,8 @@ namespace Ogre { DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(levelName, ResourceGroupManager::getSingleton().getWorldResourceGroupName()); - return calculateLoadingStages(stream); - } + return calculateLoadingStages(stream); + } //----------------------------------------------------------------------- size_t BspLevel::calculateLoadingStages(DataStreamPtr& stream) { @@ -341,9 +341,9 @@ namespace Ogre { // Check to see if existing material // Format shader#lightmap int shadIdx = q3lvl.mFaces[face].shader; - StringStream tmp; - tmp << q3lvl.mShaders[shadIdx].name << "#" << q3lvl.mFaces[face].lm_texture; - shaderName = tmp.str(); + StringStream tmp; + tmp << q3lvl.mShaders[shadIdx].name << "#" << q3lvl.mFaces[face].lm_texture; + shaderName = tmp.str(); MaterialPtr shadMat = MaterialManager::getSingleton().getByName(shaderName); if (shadMat.isNull()) @@ -358,13 +358,13 @@ namespace Ogre { if (pShad) { shadMat = pShad->createAsMaterial(q3lvl.mFaces[face].lm_texture); - // Do skydome (use this material) - if (pShad->skyDome) - { - mSkyEnabled = true; - mSkyMaterial = shadMat->getName(); - mSkyCurvature = 20 - (pShad->cloudHeight / 256 * 18); - } + // Do skydome (use this material) + if (pShad->skyDome) + { + mSkyEnabled = true; + mSkyMaterial = shadMat->getName(); + mSkyCurvature = 20 - (pShad->cloudHeight / 256 * 18); + } } else { @@ -392,7 +392,7 @@ namespace Ogre { if (q3lvl.mFaces[face].lm_texture >= 0) { // Add lightmap, additive blending - StringStream lightmapName; + StringStream lightmapName; lightmapName << "@lightmap" << q3lvl.mFaces[face].lm_texture; tex = shadPass->createTextureUnitState(lightmapName.str()); // Blend @@ -438,7 +438,7 @@ namespace Ogre { // Assign plane dest->plane.normal = Vector3(src->normal[0], src->normal[1], src->normal[2]); dest->plane.d = -dest->plane.normal.dotProduct( - Vector3(src->org[0], src->org[1], src->org[2])); + Vector3(src->org[0], src->org[1], src->org[2])); // Don't rebase indexes here - Quake3 re-uses some indexes for multiple vertex // groups eg repeating small details have the same relative vertex data but @@ -472,18 +472,18 @@ namespace Ogre { } - else if (src->type == BSP_FACETYPE_MESH) - { - dest->fType = FGT_FACE_LIST; - // Assign plane - dest->plane.normal = Vector3(src->normal[0], src->normal[1], src->normal[2]); - dest->plane.d = -dest->plane.normal.dotProduct( - Vector3(src->org[0], src->org[1], src->org[2])); - } - else - { - LogManager::getSingleton().logMessage("!!! Unknown Face Type !!!", LML_CRITICAL); - } + else if (src->type == BSP_FACETYPE_MESH) + { + dest->fType = FGT_FACE_LIST; + // Assign plane + dest->plane.normal = Vector3(src->normal[0], src->normal[1], src->normal[2]); + dest->plane.d = -dest->plane.normal.dotProduct( + Vector3(src->org[0], src->org[1], src->org[2])); + } + else + { + LogManager::getSingleton().logMessage("!!! Unknown Face Type !!!", LML_CRITICAL); + } // progress reporting --progressCountdown; @@ -577,7 +577,7 @@ namespace Ogre { // Brushes //----------------------------------------------------------------------- // Reserve enough memory for all brushes, solid or not (need to maintain indexes) - mNumBrushes = q3lvl.mNumBrushes; + mNumBrushes = q3lvl.mNumBrushes; mBrushes = OGRE_NEW_ARRAY_T(BspNode::Brush, mNumBrushes, MEMCATEGORY_GEOMETRY); progressCountdown = NUM_BRUSHES_PER_PROGRESS_REPORT; progressCount = 0; @@ -614,11 +614,11 @@ namespace Ogre { // Notice how we normally invert Q3A plane distances, but here we do not // Because we want plane normals pointing out of solid brushes, not in Plane brushSide( - Vector3( - q3brushplane->normal[0], - q3brushplane->normal[1], - q3brushplane->normal[2]), - q3brushplane->dist); + Vector3( + q3brushplane->normal[0], + q3brushplane->normal[1], + q3brushplane->normal[2]), + q3brushplane->dist); pBrush->planes.push_back(brushSide); ++brushSideIdx; } @@ -880,7 +880,7 @@ namespace Ogre { { StringUtil::toLowerCase(line); // Remove quotes - while( ( pos = line.find("\"",0) ) != String::npos ) + while( ( pos = line.find("\"",0) ) != String::npos ) { line = line.substr(0,pos) + line.substr(pos+1,line.length()-(pos+1)); } @@ -929,7 +929,7 @@ namespace Ogre { MovableToNodeMap::iterator i = mMovableToNodeMap.find(mov); if (i != mMovableToNodeMap.end()) { - list::type::iterator nodeit, nodeitend; + list::type::iterator nodeit, nodeitend; nodeitend = i->second.end(); for (nodeit = i->second.begin(); nodeit != nodeitend; ++nodeit) { @@ -952,7 +952,7 @@ namespace Ogre { // Insert all the time, will get current if already there std::pair p = mMovableToNodeMap.insert( - MovableToNodeMap::value_type(mov, list::type())); + MovableToNodeMap::value_type(mov, list::type())); p.first->second.push_back(node); @@ -984,13 +984,13 @@ namespace Ogre { } } //----------------------------------------------------------------------- - void BspLevel::_notifyObjectDetached(const MovableObject* mov) - { + void BspLevel::_notifyObjectDetached(const MovableObject* mov) + { // Locate any current nodes the object is supposed to be attached to MovableToNodeMap::iterator i = mMovableToNodeMap.find(mov); if (i != mMovableToNodeMap.end()) { - list::type::iterator nodeit, nodeitend; + list::type::iterator nodeit, nodeitend; nodeitend = i->second.end(); for (nodeit = i->second.begin(); nodeit != nodeitend; ++nodeit) { @@ -1000,7 +1000,7 @@ namespace Ogre { // delete the entry for this MovableObject mMovableToNodeMap.erase(i); } - } + } //----------------------------------------------------------------------- void BspLevel::quakeVertexToBspVertex(const bsp_vertex_t* src, BspVertex* dest) { diff --git a/PlugIns/BSPSceneManager/src/OgreBspResourceManager.cpp b/PlugIns/BSPSceneManager/src/OgreBspResourceManager.cpp index b17deeb6da0..fc6e5dd9963 100644 --- a/PlugIns/BSPSceneManager/src/OgreBspResourceManager.cpp +++ b/PlugIns/BSPSceneManager/src/OgreBspResourceManager.cpp @@ -74,15 +74,15 @@ namespace Ogre { } //----------------------------------------------------------------------- ResourcePtr BspResourceManager::load(DataStreamPtr& stream, - const String& group) + const String& group) { // Only 1 BSP level allowed loaded at once removeAll(); - ResourcePtr ret = createResource("bsplevel", group, true, 0); - BspLevelPtr bspLevel = ret.staticCast(); - bspLevel->load(stream); - + ResourcePtr ret = createResource("bsplevel", group, true, 0); + BspLevelPtr bspLevel = ret.staticCast(); + bspLevel->load(stream); + return ret; } diff --git a/PlugIns/BSPSceneManager/src/OgreBspSceneManager.cpp b/PlugIns/BSPSceneManager/src/OgreBspSceneManager.cpp index 74243de5ea4..85a40837e28 100644 --- a/PlugIns/BSPSceneManager/src/OgreBspSceneManager.cpp +++ b/PlugIns/BSPSceneManager/src/OgreBspSceneManager.cpp @@ -52,7 +52,7 @@ namespace Ogre { //----------------------------------------------------------------------- BspSceneManager::BspSceneManager(const String& name) - : SceneManager(name) + : SceneManager(name) { // Set features for debugging render mShowNodeAABs = false; @@ -65,11 +65,11 @@ namespace Ogre { mLevel.setNull(); } - //----------------------------------------------------------------------- - const String& BspSceneManager::getTypeName(void) const - { - return BspSceneManagerFactory::FACTORY_TYPE_NAME; - } + //----------------------------------------------------------------------- + const String& BspSceneManager::getTypeName(void) const + { + return BspSceneManagerFactory::FACTORY_TYPE_NAME; + } //----------------------------------------------------------------------- BspSceneManager::~BspSceneManager() { @@ -84,7 +84,7 @@ namespace Ogre { } //----------------------------------------------------------------------- size_t BspSceneManager::estimateWorldGeometry(DataStreamPtr& stream, - const String& typeName) + const String& typeName) { return BspLevel::calculateLoadingStages(stream); @@ -96,41 +96,41 @@ namespace Ogre { // Check extension is .bsp char extension[6]; size_t pos = filename.find_last_of("."); - if( pos == String::npos ) + if( pos == String::npos ) OGRE_EXCEPT( - Exception::ERR_INVALIDPARAMS, + Exception::ERR_INVALIDPARAMS, "Unable to load world geometry. Invalid extension (must be .bsp).", "BspSceneManager::setWorldGeometry"); strncpy(extension, filename.substr(pos + 1, filename.length() - pos).c_str(), 5); - extension[5] = 0; + extension[5] = 0; #if OGRE_COMPILER == OGRE_COMPILER_MSVC - if (_stricmp(extension, "bsp")) + if (_stricmp(extension, "bsp")) #else - if (stricmp(extension, "bsp")) + if (stricmp(extension, "bsp")) #endif OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unable to load world geometry. Invalid extension (must be .bsp).", + "Unable to load world geometry. Invalid extension (must be .bsp).", "BspSceneManager::setWorldGeometry"); // Load using resource manager mLevel = BspResourceManager::getSingleton().load(filename, ResourceGroupManager::getSingleton().getWorldResourceGroupName()).staticCast(); - if (mLevel->isSkyEnabled()) - { - // Quake3 is always aligned with Z upwards - Quaternion q; - q.FromAngleAxis(Radian(Math::HALF_PI), Vector3::UNIT_X); - // Also draw last, and make close to camera (far clip plane is shorter) - setSkyDome(true, mLevel->getSkyMaterialName(), - mLevel->getSkyCurvature(), 12, 2000, false, q); - } - else - { - setSkyDome(false, BLANKSTRING); - } + if (mLevel->isSkyEnabled()) + { + // Quake3 is always aligned with Z upwards + Quaternion q; + q.FromAngleAxis(Radian(Math::HALF_PI), Vector3::UNIT_X); + // Also draw last, and make close to camera (far clip plane is shorter) + setSkyDome(true, mLevel->getSkyMaterialName(), + mLevel->getSkyCurvature(), 12, 2000, false, q); + } + else + { + setSkyDome(false, BLANKSTRING); + } // Init static render operation mRenderOp.vertexData = mLevel->mVertexData; @@ -152,27 +152,27 @@ namespace Ogre { } //----------------------------------------------------------------------- void BspSceneManager::setWorldGeometry(DataStreamPtr& stream, - const String& typeName) + const String& typeName) { mLevel.setNull(); // Load using resource manager mLevel = BspResourceManager::getSingleton().load(stream, - ResourceGroupManager::getSingleton().getWorldResourceGroupName()).staticCast(); - - if (mLevel->isSkyEnabled()) - { - // Quake3 is always aligned with Z upwards - Quaternion q; - q.FromAngleAxis(Radian(Math::HALF_PI), Vector3::UNIT_X); - // Also draw last, and make close to camera (far clip plane is shorter) - setSkyDome(true, mLevel->getSkyMaterialName(), - mLevel->getSkyCurvature(), 12, 2000, false, q); - } - else - { - setSkyDome(false, BLANKSTRING); - } + ResourceGroupManager::getSingleton().getWorldResourceGroupName()).staticCast(); + + if (mLevel->isSkyEnabled()) + { + // Quake3 is always aligned with Z upwards + Quaternion q; + q.FromAngleAxis(Radian(Math::HALF_PI), Vector3::UNIT_X); + // Also draw last, and make close to camera (far clip plane is shorter) + setSkyDome(true, mLevel->getSkyMaterialName(), + mLevel->getSkyCurvature(), 12, 2000, false, q); + } + else + { + setSkyDome(false, BLANKSTRING); + } // Init static render operation mRenderOp.vertexData = mLevel->mVertexData; @@ -194,41 +194,41 @@ namespace Ogre { } //----------------------------------------------------------------------- void BspSceneManager::_findVisibleObjects(Camera* cam, - VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters) + VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters) { // Clear unique list of movables for this frame mMovablesForRendering.clear(); - // Assemble an AAB on the fly which contains the scene elements visible - // by the camera. - CamVisibleObjectsMap::iterator findIt = mCamVisibleObjectsMap.find( cam ); + // Assemble an AAB on the fly which contains the scene elements visible + // by the camera. + CamVisibleObjectsMap::iterator findIt = mCamVisibleObjectsMap.find( cam ); // Walk the tree, tag static geometry, return camera's node (for info only) // Movables are now added to the render queue in processVisibleLeaf walkTree(cam, &(findIt->second), onlyShadowCasters); } - //--------------------------------------------------------------------- - bool BspSceneManager::fireRenderQueueEnded(uint8 id, const String& invocation) - { - bool repeat = SceneManager::fireRenderQueueEnded(id, invocation); - // Trigger level render just after skies - // can't trigger on mWorldGeometryRenderQueue because we're not queueing there - if (id == RENDER_QUEUE_SKIES_EARLY) - { - renderStaticGeometry(); - } - return repeat; + //--------------------------------------------------------------------- + bool BspSceneManager::fireRenderQueueEnded(uint8 id, const String& invocation) + { + bool repeat = SceneManager::fireRenderQueueEnded(id, invocation); + // Trigger level render just after skies + // can't trigger on mWorldGeometryRenderQueue because we're not queueing there + if (id == RENDER_QUEUE_SKIES_EARLY) + { + renderStaticGeometry(); + } + return repeat; - } + } //----------------------------------------------------------------------- void BspSceneManager::renderStaticGeometry(void) { - // Check we should be rendering - if (!isRenderQueueToBeProcessed(mWorldGeometryRenderQueue)) - return; + // Check we should be rendering + if (!isRenderQueueToBeProcessed(mWorldGeometryRenderQueue)) + return; // Cache vertex/face data first - vector::type::const_iterator faceGrpi; + vector::type::const_iterator faceGrpi; static RenderOperation patchOp; // no world transform required @@ -296,9 +296,9 @@ namespace Ogre { //----------------------------------------------------------------------- //----------------------------------------------------------------------- BspNode* BspSceneManager::walkTree(Camera* camera, - VisibleObjectsBoundsInfo *visibleBounds, bool onlyShadowCasters) + VisibleObjectsBoundsInfo *visibleBounds, bool onlyShadowCasters) { - if (mLevel.isNull()) return 0; + if (mLevel.isNull()) return 0; // Locate the leaf node where the camera is located BspNode* cameraNode = mLevel->findLeaf(camera->getDerivedPosition()); @@ -368,7 +368,7 @@ namespace Ogre { } //----------------------------------------------------------------------- void BspSceneManager::processVisibleLeaf(BspNode* leaf, Camera* cam, - VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters) + VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters) { MaterialPtr pMat; // Skip world geometry if we're only supposed to process shadow casters @@ -402,7 +402,7 @@ namespace Ogre { // Try to insert, will find existing if already there std::pair matgrpi; matgrpi = mMatFaceGroupMap.insert( - MaterialFaceGroupMap::value_type(pMat.getPointer(), vector::type()) + MaterialFaceGroupMap::value_type(pMat.getPointer(), vector::type()) ); // Whatever happened, matgrpi.first is map iterator // Need to get second part of that to get vector @@ -426,7 +426,7 @@ namespace Ogre { // It hasn't been seen yet MovableObject *mov = const_cast(*oi); // hacky - getRenderQueue()->processVisibleObject(mov, cam, onlyShadowCasters, visibleBounds); + getRenderQueue()->processVisibleObject(mov, cam, onlyShadowCasters, visibleBounds); } } @@ -456,11 +456,11 @@ namespace Ogre { numIdx = faceGroup->patchSurf->getCurrentIndexCount(); vertexStart = faceGroup->patchSurf->getVertexOffset(); } - else - { - // Unsupported face type - return 0; - } + else + { + // Unsupported face type + return 0; + } // Copy index data @@ -489,7 +489,7 @@ namespace Ogre { { // no need to delete index buffer, will be handled by shared pointer OGRE_DELETE mRenderOp.indexData; - mRenderOp.indexData = 0; + mRenderOp.indexData = 0; } //----------------------------------------------------------------------- void BspSceneManager::showNodeBoxes(bool show) @@ -606,27 +606,27 @@ namespace Ogre { void BspSceneManager::_notifyObjectMoved(const MovableObject* mov, const Vector3& pos) { - if (!mLevel.isNull()) - { - mLevel->_notifyObjectMoved(mov, pos); - } - } - //----------------------------------------------------------------------- - void BspSceneManager::_notifyObjectDetached(const MovableObject* mov) - { - if (!mLevel.isNull()) - { - mLevel->_notifyObjectDetached(mov); - } - } - //----------------------------------------------------------------------- - void BspSceneManager::clearScene(void) - { - SceneManager::clearScene(); - freeMemory(); - // Clear level - mLevel.setNull(); - } + if (!mLevel.isNull()) + { + mLevel->_notifyObjectMoved(mov, pos); + } + } + //----------------------------------------------------------------------- + void BspSceneManager::_notifyObjectDetached(const MovableObject* mov) + { + if (!mLevel.isNull()) + { + mLevel->_notifyObjectDetached(mov); + } + } + //----------------------------------------------------------------------- + void BspSceneManager::clearScene(void) + { + SceneManager::clearScene(); + freeMemory(); + // Clear level + mLevel.setNull(); + } //----------------------------------------------------------------------- /* AxisAlignedBoxSceneQuery* BspSceneManager:: @@ -677,7 +677,7 @@ namespace Ogre { overlap 2 leaves? */ const BspLevelPtr& lvl = ((BspSceneManager*)mParentSceneMgr)->getLevel(); - if (lvl.isNull()) return; + if (lvl.isNull()) return; BspNode* leaf = lvl->getLeafStart(); int numLeaves = lvl->getNumLeaves(); @@ -695,8 +695,8 @@ namespace Ogre { const MovableObject* aObj = *a; // Skip this object if collision not enabled if (!(aObj->getQueryFlags() & mQueryMask) || - !(aObj->getTypeFlags() & mQueryTypeMask) || - !aObj->isInScene()) + !(aObj->getTypeFlags() & mQueryTypeMask) || + !aObj->isInScene()) continue; if (oi < (numObjects-1)) @@ -708,8 +708,8 @@ namespace Ogre { const MovableObject* bObj = *b; // Apply mask to b (both must pass) if ((bObj->getQueryFlags() & mQueryMask) && - (bObj->getTypeFlags() & mQueryTypeMask) && - bObj->isInScene()) + (bObj->getTypeFlags() & mQueryTypeMask) && + bObj->isInScene()) { const AxisAlignedBox& box1 = aObj->getWorldBoundingBox(); const AxisAlignedBox& box2 = bObj->getWorldBoundingBox(); @@ -718,7 +718,7 @@ namespace Ogre { { if (!listener->queryResult(const_cast(aObj), const_cast(bObj))) - return; + return; } } } @@ -734,7 +734,7 @@ namespace Ogre { for (bi = brushes.begin(); bi != biend; ++bi) { - list::type::const_iterator planeit, planeitend; + list::type::const_iterator planeit, planeitend; planeitend = (*bi)->planes.end(); bool brushIntersect = true; // Assume intersecting for now @@ -754,7 +754,7 @@ namespace Ogre { assert((*bi)->fragment.fragmentType == SceneQuery::WFT_PLANE_BOUNDED_REGION); if (!listener->queryResult(const_cast(aObj), const_cast(&((*bi)->fragment)))) - return; + return; } } @@ -782,13 +782,13 @@ namespace Ogre { void BspRaySceneQuery::execute(RaySceneQueryListener* listener) { clearTemporaries(); - BspLevelPtr lvl = static_cast(mParentSceneMgr)->getLevel(); - if (!lvl.isNull()) - { - processNode( - lvl->getRootNode(), - mRay, listener); - } + BspLevelPtr lvl = static_cast(mParentSceneMgr)->getLevel(); + if (!lvl.isNull()) + { + processNode( + lvl->getRootNode(), + mRay, listener); + } } //----------------------------------------------------------------------- BspRaySceneQuery::~BspRaySceneQuery() @@ -799,7 +799,7 @@ namespace Ogre { void BspRaySceneQuery::clearTemporaries(void) { mObjsThisQuery.clear(); - vector::type::iterator i; + vector::type::iterator i; for (i = mSingleIntersections.begin(); i != mSingleIntersections.end(); ++i) { OGRE_FREE(*i, MEMCATEGORY_SCENE_CONTROL); @@ -872,7 +872,7 @@ namespace Ogre { MovableObject* obj = const_cast(*i); // Skip this object if not enabled if(!(obj->getQueryFlags() & mQueryMask) || - !((obj->getTypeFlags() & mQueryTypeMask))) + !((obj->getTypeFlags() & mQueryTypeMask))) continue; // check we haven't reported this one already @@ -888,7 +888,7 @@ namespace Ogre { if(result.first && result.second <= maxDistance) { if (!listener->queryResult(obj, result.second + traceDistance)) - return false; + return false; } } @@ -921,7 +921,7 @@ namespace Ogre { // save this so we can clean up later mSingleIntersections.push_back(wf); if (!listener->queryResult(wf, result.second + traceDistance)) - return false; + return false; } else if (mWorldFragmentType == SceneQuery::WFT_PLANE_BOUNDED_REGION) { @@ -929,7 +929,7 @@ namespace Ogre { assert((*bi)->fragment.fragmentType == SceneQuery::WFT_PLANE_BOUNDED_REGION); if (!listener->queryResult(const_cast(&(brush->fragment)), result.second + traceDistance)) - return false; + return false; } } @@ -944,27 +944,27 @@ namespace Ogre { } //----------------------------------------------------------------------- - //----------------------------------------------------------------------- - const String BspSceneManagerFactory::FACTORY_TYPE_NAME = "BspSceneManager"; - //----------------------------------------------------------------------- - void BspSceneManagerFactory::initMetaData(void) const - { - mMetaData.typeName = FACTORY_TYPE_NAME; - mMetaData.description = "Scene manager for loading Quake3 .bsp files."; - mMetaData.sceneTypeMask = ST_INTERIOR; - mMetaData.worldGeometrySupported = true; - } - //----------------------------------------------------------------------- - SceneManager* BspSceneManagerFactory::createInstance( - const String& instanceName) - { - return OGRE_NEW BspSceneManager(instanceName); - } - //----------------------------------------------------------------------- - void BspSceneManagerFactory::destroyInstance(SceneManager* instance) - { - OGRE_DELETE instance; - } + //----------------------------------------------------------------------- + const String BspSceneManagerFactory::FACTORY_TYPE_NAME = "BspSceneManager"; + //----------------------------------------------------------------------- + void BspSceneManagerFactory::initMetaData(void) const + { + mMetaData.typeName = FACTORY_TYPE_NAME; + mMetaData.description = "Scene manager for loading Quake3 .bsp files."; + mMetaData.sceneTypeMask = ST_INTERIOR; + mMetaData.worldGeometrySupported = true; + } + //----------------------------------------------------------------------- + SceneManager* BspSceneManagerFactory::createInstance( + const String& instanceName) + { + return OGRE_NEW BspSceneManager(instanceName); + } + //----------------------------------------------------------------------- + void BspSceneManagerFactory::destroyInstance(SceneManager* instance) + { + OGRE_DELETE instance; + } } diff --git a/PlugIns/BSPSceneManager/src/OgreBspSceneManagerDll.cpp b/PlugIns/BSPSceneManager/src/OgreBspSceneManagerDll.cpp index 8072a3cfd05..643de3f1de6 100644 --- a/PlugIns/BSPSceneManager/src/OgreBspSceneManagerDll.cpp +++ b/PlugIns/BSPSceneManager/src/OgreBspSceneManagerDll.cpp @@ -44,7 +44,7 @@ extern "C" void _OgreBspPluginExport dllStartPlugin(void) } extern "C" void _OgreBspPluginExport dllStopPlugin(void) { - Ogre::Root::getSingleton().uninstallPlugin(bspPlugin); + Ogre::Root::getSingleton().uninstallPlugin(bspPlugin); OGRE_DELETE bspPlugin; } #endif diff --git a/PlugIns/BSPSceneManager/src/OgreBspSceneManagerPlugin.cpp b/PlugIns/BSPSceneManager/src/OgreBspSceneManagerPlugin.cpp index d3a9be7301c..5e6ef9446f5 100644 --- a/PlugIns/BSPSceneManager/src/OgreBspSceneManagerPlugin.cpp +++ b/PlugIns/BSPSceneManager/src/OgreBspSceneManagerPlugin.cpp @@ -31,52 +31,52 @@ THE SOFTWARE. namespace Ogre { - const String sPluginName = "BSP Scene Manager"; - //--------------------------------------------------------------------- - BspSceneManagerPlugin::BspSceneManagerPlugin() - :mBspFactory(0), mBspResourceManager(0) - { + const String sPluginName = "BSP Scene Manager"; + //--------------------------------------------------------------------- + BspSceneManagerPlugin::BspSceneManagerPlugin() + :mBspFactory(0), mBspResourceManager(0) + { - } - //--------------------------------------------------------------------- - const String& BspSceneManagerPlugin::getName() const - { - return sPluginName; - } - //--------------------------------------------------------------------- - void BspSceneManagerPlugin::install() - { - // Create new scene manager - mBspFactory = OGRE_NEW BspSceneManagerFactory(); + } + //--------------------------------------------------------------------- + const String& BspSceneManagerPlugin::getName() const + { + return sPluginName; + } + //--------------------------------------------------------------------- + void BspSceneManagerPlugin::install() + { + // Create new scene manager + mBspFactory = OGRE_NEW BspSceneManagerFactory(); - } - //--------------------------------------------------------------------- - void BspSceneManagerPlugin::initialise() - { - // Register (factory not dependent on rsys resources) - Root::getSingleton().addSceneManagerFactory(mBspFactory); - // Create resource manager (registers itself) - mBspResourceManager = OGRE_NEW BspResourceManager(); - } - //--------------------------------------------------------------------- - void BspSceneManagerPlugin::shutdown() - { - // Unregister SM factory - Root::getSingleton().removeSceneManagerFactory(mBspFactory); + } + //--------------------------------------------------------------------- + void BspSceneManagerPlugin::initialise() + { + // Register (factory not dependent on rsys resources) + Root::getSingleton().addSceneManagerFactory(mBspFactory); + // Create resource manager (registers itself) + mBspResourceManager = OGRE_NEW BspResourceManager(); + } + //--------------------------------------------------------------------- + void BspSceneManagerPlugin::shutdown() + { + // Unregister SM factory + Root::getSingleton().removeSceneManagerFactory(mBspFactory); - // delete resource manager, will unregister itself - OGRE_DELETE mBspResourceManager; - mBspResourceManager = 0; + // delete resource manager, will unregister itself + OGRE_DELETE mBspResourceManager; + mBspResourceManager = 0; - } - //--------------------------------------------------------------------- - void BspSceneManagerPlugin::uninstall() - { + } + //--------------------------------------------------------------------- + void BspSceneManagerPlugin::uninstall() + { - OGRE_DELETE mBspFactory; - mBspFactory = 0; + OGRE_DELETE mBspFactory; + mBspFactory = 0; - } + } } diff --git a/PlugIns/BSPSceneManager/src/OgreBspSceneNode.cpp b/PlugIns/BSPSceneManager/src/OgreBspSceneNode.cpp index 6b12ec06d26..6e366f9e975 100644 --- a/PlugIns/BSPSceneManager/src/OgreBspSceneNode.cpp +++ b/PlugIns/BSPSceneManager/src/OgreBspSceneNode.cpp @@ -60,58 +60,58 @@ namespace Ogre { } } - //------------------------------------------------------------------------- - MovableObject* BspSceneNode::detachObject(unsigned short index) - { - MovableObject* ret = SceneNode::detachObject(index); - static_cast(mCreator)->_notifyObjectDetached(ret); - return ret; - - } - //------------------------------------------------------------------------- - MovableObject* BspSceneNode::detachObject(const String& name) - { - MovableObject* ret = SceneNode::detachObject(name); - static_cast(mCreator)->_notifyObjectDetached(ret); - return ret; - } - //------------------------------------------------------------------------- - void BspSceneNode::detachAllObjects(void) - { - ObjectMap::const_iterator i, iend; - iend = mObjectsByName.end(); - for (i = mObjectsByName.begin(); i != iend; ++i) - { - static_cast(mCreator) - ->_notifyObjectDetached(i->second); - } - SceneNode::detachAllObjects(); - } - //------------------------------------------------------------------------- - void BspSceneNode::setInSceneGraph(bool inGraph) - { - if (mIsInSceneGraph != inGraph) - { - ObjectMap::const_iterator i, iend; - iend = mObjectsByName.end(); - for (i = mObjectsByName.begin(); i != iend; ++i) - { - if (!inGraph) - { - // Equivalent to detaching - static_cast(mCreator) - ->_notifyObjectDetached(i->second); - } - else - { - // move deals with re-adding - static_cast(mCreator)->_notifyObjectMoved( - i->second, this->_getDerivedPosition()); - } - } - } - mIsInSceneGraph = inGraph; - } + //------------------------------------------------------------------------- + MovableObject* BspSceneNode::detachObject(unsigned short index) + { + MovableObject* ret = SceneNode::detachObject(index); + static_cast(mCreator)->_notifyObjectDetached(ret); + return ret; + + } + //------------------------------------------------------------------------- + MovableObject* BspSceneNode::detachObject(const String& name) + { + MovableObject* ret = SceneNode::detachObject(name); + static_cast(mCreator)->_notifyObjectDetached(ret); + return ret; + } + //------------------------------------------------------------------------- + void BspSceneNode::detachAllObjects(void) + { + ObjectMap::const_iterator i, iend; + iend = mObjectsByName.end(); + for (i = mObjectsByName.begin(); i != iend; ++i) + { + static_cast(mCreator) + ->_notifyObjectDetached(i->second); + } + SceneNode::detachAllObjects(); + } + //------------------------------------------------------------------------- + void BspSceneNode::setInSceneGraph(bool inGraph) + { + if (mIsInSceneGraph != inGraph) + { + ObjectMap::const_iterator i, iend; + iend = mObjectsByName.end(); + for (i = mObjectsByName.begin(); i != iend; ++i) + { + if (!inGraph) + { + // Equivalent to detaching + static_cast(mCreator) + ->_notifyObjectDetached(i->second); + } + else + { + // move deals with re-adding + static_cast(mCreator)->_notifyObjectMoved( + i->second, this->_getDerivedPosition()); + } + } + } + mIsInSceneGraph = inGraph; + } } diff --git a/PlugIns/BSPSceneManager/src/OgreQuake3Level.cpp b/PlugIns/BSPSceneManager/src/OgreQuake3Level.cpp index d4819cc3eb1..8062639a374 100644 --- a/PlugIns/BSPSceneManager/src/OgreQuake3Level.cpp +++ b/PlugIns/BSPSceneManager/src/OgreQuake3Level.cpp @@ -46,9 +46,9 @@ namespace Ogre { OGRE_NEW MemoryDataStream(pHeader, sizeof(bsp_header_t), false)); // Grab all the counts, header only initialise(true); - // Delete manually since delete and delete[] (as used by MemoryDataStream) - // are not compatible - OGRE_FREE(pHeader, MEMCATEGORY_RESOURCE); + // Delete manually since delete and delete[] (as used by MemoryDataStream) + // are not compatible + OGRE_FREE(pHeader, MEMCATEGORY_RESOURCE); } //----------------------------------------------------------------------- @@ -98,12 +98,12 @@ namespace Ogre { else { mLumpStart = ((unsigned char*)mHeader) + sizeof(mHeader); - initialisePointers(); + initialisePointers(); } #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - // swap header + // swap header SwapFourBytes ((uint32*)&mHeader->version); #endif } @@ -242,15 +242,15 @@ namespace Ogre { unsigned char* pLightmap = mLightmaps; for (int i = 0; i < mNumLightmaps; ++i) { - StringStream name; + StringStream name; name << "@lightmap" << i; // Load, no mipmaps, brighten by factor 2.5 - DataStreamPtr stream(OGRE_NEW MemoryDataStream(pLightmap, 128 * 128 * 3, false)); + DataStreamPtr stream(OGRE_NEW MemoryDataStream(pLightmap, 128 * 128 * 3, false)); Image img; - img.loadRawData( stream, 128, 128, PF_BYTE_RGB ); + img.loadRawData( stream, 128, 128, PF_BYTE_RGB ); TextureManager::getSingleton().loadImage( name.str(), - ResourceGroupManager::getSingleton().getWorldResourceGroupName(), img, TEX_TYPE_2D, 0, 4.0f ); + ResourceGroupManager::getSingleton().getWorldResourceGroupName(), img, TEX_TYPE_2D, 0, 4.0f ); pLightmap += BSP_LIGHTMAP_BANKSIZE; } diff --git a/PlugIns/BSPSceneManager/src/OgreQuake3Shader.cpp b/PlugIns/BSPSceneManager/src/OgreQuake3Shader.cpp index 8467ab105d6..e983e6d8e69 100644 --- a/PlugIns/BSPSceneManager/src/OgreQuake3Shader.cpp +++ b/PlugIns/BSPSceneManager/src/OgreQuake3Shader.cpp @@ -61,16 +61,16 @@ namespace Ogre { //----------------------------------------------------------------------- MaterialPtr Quake3Shader::createAsMaterial(int lightmapNumber) { - String matName; - StringStream str; + String matName; + StringStream str; String resourceGroup = ResourceGroupManager::getSingleton().getWorldResourceGroupName(); str << mName << "#" << lightmapNumber; - matName = str.str(); + matName = str.str(); MaterialPtr mat = MaterialManager::getSingleton().create(matName, resourceGroup); - Ogre::Pass* ogrePass = mat->getTechnique(0)->getPass(0); + Ogre::Pass* ogrePass = mat->getTechnique(0)->getPass(0); LogManager::getSingleton().logMessage("Using Q3 shader " + mName, LML_CRITICAL); for (int p = 0; p < numPasses; ++p) @@ -80,7 +80,7 @@ namespace Ogre { if (pass[p].textureName == "$lightmap") { StringStream str2; - str2 << "@lightmap" << lightmapNumber; + str2 << "@lightmap" << lightmapNumber; t = ogrePass->createTextureUnitState(str2.str()); } // Animated texture support @@ -141,9 +141,9 @@ namespace Ogre { mat->setDepthWriteEnabled(false); t->setColourOperation(LBO_REPLACE); - // Alpha mode - ogrePass->setAlphaRejectSettings( - pass[p].alphaFunc, pass[p].alphaVal); + // Alpha mode + ogrePass->setAlphaRejectSettings( + pass[p].alphaFunc, pass[p].alphaVal); } else { @@ -157,15 +157,15 @@ namespace Ogre { // simple layer blend t->setColourOperation(pass[p].blend); } - // Alpha mode, prefer 'most alphary' - CompareFunction currFunc = ogrePass->getAlphaRejectFunction(); - unsigned char currVal = ogrePass->getAlphaRejectValue(); - if (pass[p].alphaFunc > currFunc || - (pass[p].alphaFunc == currFunc && pass[p].alphaVal < currVal)) - { - ogrePass->setAlphaRejectSettings( - pass[p].alphaFunc, pass[p].alphaVal); - } + // Alpha mode, prefer 'most alphary' + CompareFunction currFunc = ogrePass->getAlphaRejectFunction(); + unsigned char currVal = ogrePass->getAlphaRejectValue(); + if (pass[p].alphaFunc > currFunc || + (pass[p].alphaFunc == currFunc && pass[p].alphaVal < currVal)) + { + ogrePass->setAlphaRejectSettings( + pass[p].alphaFunc, pass[p].alphaVal); + } } // Tex coords if (pass[p].texGen == TEXGEN_BASE) @@ -269,7 +269,7 @@ namespace Ogre { pos = texName.find_last_of("."); ext = texName.substr(pos, 4); - StringUtil::toLowerCase(ext); + StringUtil::toLowerCase(ext); base = texName.substr(0,pos); if (ext == ".jpg") { diff --git a/PlugIns/BSPSceneManager/src/OgreQuake3ShaderManager.cpp b/PlugIns/BSPSceneManager/src/OgreQuake3ShaderManager.cpp index 8d65e30448c..845068ad4cd 100644 --- a/PlugIns/BSPSceneManager/src/OgreQuake3ShaderManager.cpp +++ b/PlugIns/BSPSceneManager/src/OgreQuake3ShaderManager.cpp @@ -148,7 +148,7 @@ namespace Ogre { else { // Attribute - StringUtil::toLowerCase(line); + StringUtil::toLowerCase(line); parseShaderAttrib(line, pShader); } @@ -301,7 +301,7 @@ namespace Ogre { if (params[0] == "map") { pPass->textureName = params[1]; - StringUtil::toLowerCase(params[1]); + StringUtil::toLowerCase(params[1]); if (params[1] == "$lightmap") pPass->texGen = TEXGEN_LIGHTMAP; } @@ -309,7 +309,7 @@ namespace Ogre { if (params[0] == "clampmap") { pPass->textureName = params[1]; - StringUtil::toLowerCase(params[1]); + StringUtil::toLowerCase(params[1]); if (params[1] == "$lightmap") pPass->texGen = TEXGEN_LIGHTMAP; pPass->addressMode = TextureUnitState::TAM_CLAMP; diff --git a/PlugIns/CgProgramManager/include/OgreCgFxScriptLoader.h b/PlugIns/CgProgramManager/include/OgreCgFxScriptLoader.h index 75d03af9f15..889a6e85329 100644 --- a/PlugIns/CgProgramManager/include/OgreCgFxScriptLoader.h +++ b/PlugIns/CgProgramManager/include/OgreCgFxScriptLoader.h @@ -439,1053 +439,1053 @@ namespace Ogre { // some simple types to make working with CGstateassignment easier - struct Vector1b - { - bool x; - Vector1b(); - Vector1b( bool iX ); - Vector1b( CGstateassignment cgStateAssignment ); - operator bool() const; - }; - - struct Vector2b - { - bool x, y; - Vector2b(); - Vector2b( bool iX, bool iY , bool iZ, bool iW ); - Vector2b( CGstateassignment cgStateAssignment ); - }; - - struct Vector3b - { - bool x, y, z; - Vector3b(); - Vector3b( bool iX, bool iY , bool iZ, bool iW ); - Vector3b( CGstateassignment cgStateAssignment ); - }; - - struct Vector4b - { - bool x, y, z, w; - Vector4b(); - Vector4b( bool iX, bool iY , bool iZ, bool iW ); - Vector4b( CGstateassignment cgStateAssignment ); - }; - - struct Vector1i - { - int x; - Vector1i(); - Vector1i( int iX ); - Vector1i( CGstateassignment cgStateAssignment ); - operator int() const; - - }; - - struct Vector2i - { - int x, y; - Vector2i(); - Vector2i( int iX, int iY ); - Vector2i( CGstateassignment cgStateAssignment ); - }; - - struct Vector3i - { - int x, y, z; - Vector3i(); - Vector3i( int iX, int iY, int iZ ); - Vector3i( CGstateassignment cgStateAssignment ); - }; - - - struct Vector4i - { - int x, y, z, w; - Vector4i(); - Vector4i( int iX, int iY, int iZ, int iW ); - Vector4i( CGstateassignment cgStateAssignment ); - }; - - - struct Vector1f - { - float x; - Vector1f(); - Vector1f( float iX, float iY, float iZ ); - Vector1f( CGstateassignment cgStateAssignment ); - operator float() const; - }; - - - struct Vector2f - { - float x, y; - Vector2f(); - Vector2f( float iX, float iY, float iZ ); - Vector2f( CGstateassignment cgStateAssignment ); - }; - - - struct Vector3f - { - float x, y, z; - Vector3f(); - Vector3f( float iX, float iY, float iZ ); - Vector3f( CGstateassignment cgStateAssignment ); - }; - - struct Vector4f - { - float x, y, z, w; - Vector4f(); - Vector4f( float iX, float iY, float iZ, float iW ); - Vector4f( CGstateassignment cgStateAssignment ); - }; - - - - // simple types end - - - class CgStateListener : public GeneralAllocatedObject - { - protected: - CGstate mCgState; - CGtype mCgType; - CGcontext mCgContext; - - static CGbool cgCallBackSet( CGstateassignment cgStateAssignment ); - static CGbool cgCallBackReset( CGstateassignment cgStateAssignment ); - static CGbool cgCallBackValidate( CGstateassignment cgStateAssignment ); - - virtual CGstatecallback getCgCallBackSet(); - virtual CGstatecallback getCgCallBackReset(); - virtual CGstatecallback getCgCallBackValidate(); - - virtual void createState() = 0; - void addStateEnumerant( int value, const char *name ); - - CGparameter getCgParameter( CGstateassignment cgStateAssignment ); - - - public: - CgStateListener( CGtype cgType ); - virtual ~CgStateListener(); - virtual void init(); - CGstate getCgState() const; - }; - - typedef vector::type CgStateListenerVector; - - class CgGlobalStateListener : public CgStateListener - { - protected: - const GlobalStateType mGlobalStateType; - virtual void createState(); - public: - CgGlobalStateListener( const GlobalStateType globalStateType, CGtype cgType ); - virtual ~CgGlobalStateListener(); - - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Bool - class CgBoolGlobalStateListener : public CgGlobalStateListener - { - protected: - const Vector1b getValue( CGstateassignment cgStateAssignment ); - public: - CgBoolGlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Bool4 - class CgBool4GlobalStateListener : public CgGlobalStateListener - { - protected: - const Vector4b getValue( CGstateassignment cgStateAssignment ); - public: - CgBool4GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Float - class CgFloatGlobalStateListener : public CgGlobalStateListener - { - protected: - const Vector1f getValue( CGstateassignment cgStateAssignment ); - public: - CgFloatGlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Float2 - class CgFloat2GlobalStateListener : public CgGlobalStateListener - { - protected: - const Vector2f getValue( CGstateassignment cgStateAssignment ); - public: - CgFloat2GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Float3 - class CgFloat3GlobalStateListener : public CgGlobalStateListener - { - protected: - const Vector3f getValue( CGstateassignment cgStateAssignment ); - public: - CgFloat3GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Float4 - class CgFloat4GlobalStateListener : public CgGlobalStateListener - { - protected: - const Vector4f getValue( CGstateassignment cgStateAssignment ); - public: - CgFloat4GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Float4x2 - class CgFloat4x2GlobalStateListener : public CgGlobalStateListener - { - public: - CgFloat4x2GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Float4x3 - class CgFloat4x3GlobalStateListener : public CgGlobalStateListener - { - public: - CgFloat4x3GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Float4x4 - class CgFloat4x4GlobalStateListener : public CgGlobalStateListener - { - public: - CgFloat4x4GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Int - class CgIntGlobalStateListener : public CgGlobalStateListener - { - protected: - const Vector1i getValue( CGstateassignment cgStateAssignment ); - public: - CgIntGlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Int2 - class CgInt2GlobalStateListener : public CgGlobalStateListener - { - protected: - const Vector2i getValue( CGstateassignment cgStateAssignment ); - public: - CgInt2GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Int3 - class CgInt3GlobalStateListener : public CgGlobalStateListener - { - protected: - const Vector3i getValue( CGstateassignment cgStateAssignment ); - public: - CgInt3GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Int4 - class CgInt4GlobalStateListener : public CgGlobalStateListener - { - protected: - const Vector4i getValue( CGstateassignment cgStateAssignment ); - public: - CgInt4GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Sampler - class CgSamplerGlobalStateListener : public CgGlobalStateListener - { - public: - CgSamplerGlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Sampler2 - class CgSampler2GlobalStateListener : public CgGlobalStateListener - { - public: - CgSampler2GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Sampler3 - class CgSampler3GlobalStateListener : public CgGlobalStateListener - { - public: - CgSampler3GlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// SamplerCube - class CgSamplerCubeGlobalStateListener : public CgGlobalStateListener - { - public: - CgSamplerCubeGlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// SamplerRect - class CgSamplerRectGlobalStateListener : public CgGlobalStateListener - { - public: - CgSamplerRectGlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Texture - class CgTextureGlobalStateListener : public CgGlobalStateListener - { - public: - CgTextureGlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// Program - class CgProgramGlobalStateListener : public CgGlobalStateListener - { - public: - CgProgramGlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - /// BlendEquation - class CgBlendEquationGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum BlendEquationType - { - BET_FUNCADD, // FuncAdd - BET_FUNCSUBTRACT, // FuncSubtract - BET_MIN, // Min - BET_MAX, // Max - BET_LOGICOP // LogicOp - }; - virtual void createState(); - public: - CgBlendEquationGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// DepthFunc - class CgDepthFuncGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum DepthFuncType - { - DFT_NEVER, // Never - DFT_LESS, // Less - DFT_LEQUAL, // LEqual - DFT_EQUAL, // Equal - DFT_GREATER, // Greater - DFT_NOTEQUAL, // NotEqual - DFT_GEQUAL, // GEqual - DFT_ALWAYS // Always - }; - virtual void createState(); - public: - CgDepthFuncGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// FogDistanceMode - class CgFogDistanceModeGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum FogDistanceModeType - { - FDMT_EYERADIAL, // EyeRadial - FDMT_EYEPLANE, // EyePlane - FDMT_EYEPLANEABSOLUTE // EyePlaneAbsolute - }; - virtual void createState(); - public: - CgFogDistanceModeGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// FogMode - class CgFogModeGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum FogModeType - { - FMT_LINEAR, // Linear - FMT_EXP, // Exp - FMT_EXP2 // Exp2 - }; - virtual void createState(); - public: - CgFogModeGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - /// LightModelColorControl - class CgLightModelColorControlGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum LightModelColorControlType - { - LMCCT_SINGLECOLOR, // SingleColor - LMCCT_SEPARATESPECULAR // SeparateSpecular - }; - virtual void createState(); - public: - CgLightModelColorControlGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// LogicOp - class CgLogicOpGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum LogicOpType - { - LOT_CLEAR, // Clear - LOT_AND, // And - LOT_ANDREVERSE, // AndReverse - LOT_COPY, // Copy - LOT_ANDINVERTED, // AndInverted - LOT_NOOP, // Noop - LOT_XOR, // Xor - LOT_OR, // Or, - LOT_NOR, // Nor - LOT_EQUIV, // Equiv - LOT_INVERT, // Invert - LOT_ORREVERSE, // OrReverse - LOT_COPYINVERTED, // CopyInverted - LOT_NAND, // Nand - LOT_SET // Set - }; - virtual void createState(); - public: - CgLogicOpGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// PointSpriteCoordOrigin - class CgPointSpriteCoordOriginGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum PointSpriteCoordOriginType - { - PSCOT_LOWERLEFT, // LowerLeft - PSCOT_UPPERLEFT // UpperLeft - }; - virtual void createState(); - public: - CgPointSpriteCoordOriginGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// PointSpriteRMode - class CgPointSpriteRModeGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum PointSpriteRModeType - { - PSRMT_ZERO, // Zero - PSRMT_R, // R - PSRMT_S // S - }; - virtual void createState(); - public: - CgPointSpriteRModeGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// ShadeModel - class CgShadeModelGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum ShadeModelType - { - SMT_FLAT, // Flat - SMT_SMOOTH // Smooth - }; - virtual void createState(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - public: - CgShadeModelGlobalStateListener(); - }; - /// TexGenMode - class CgTexGenModeGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum TexGenModeType - { - TGMT_OBJECTLINEAR, // ObjectLinear - TGMT_EYELINEAR, // EyeLinear - TGMT_SPHEREMAP, // SphereMap - TGMT_REFLECTIONMAP, // ReflectionMap - TGMT_NORMALMAP // NormalMap - }; - virtual void createState(); - public: - CgTexGenModeGlobalStateListener( const GlobalStateType globalStateType ); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// TextureEnvMode - class CgTextureEnvModeGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum TextureEnvModeType - { - BET_MODULATE, // Modulate - BET_DECAL, // Decal - BET_BLEND, // Blend - BET_REPLACE, // Replace - BET_ADD // Add - }; - virtual void createState(); - public: - CgTextureEnvModeGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// MinFilter - class CgMinFilterGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum MinFilterType - { - MFT_NEAREST, // Nearest - MFT_LINEAR, // Linear - MFT_LINEARMIPMAPNEAREST, // LinearMipMapNearest - MFT_NEARESTMIPMAPNEAREST, // NearestMipMapNearest - MFT_NEARESTMIPMAPLINEAR, // NearestMipMapLinear - MFT_LINEARMIPMAPLINEAR // LinearMipMapLinear - }; - virtual void createState(); - public: - CgMinFilterGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// MagFilter - class CgMagFilterGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum MagFilterType - { - MFT_NEAREST, // Nearest - MFT_LINEAR // Linear - }; - virtual void createState(); - public: - CgMagFilterGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// FrontFace - class CgFrontFaceGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum FrontFaceType - { - FFT_CW, // CW - FFT_CCW // CCW - }; - virtual void createState(); - public: - CgFrontFaceGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// CullFaceGlobal - CullFace - class CgCullFaceGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum CullFaceType - { - CFT_FRONT, // Front - CFT_BACK, // Back - CFT_FRONTANDBACK // FrontAndBack - }; - virtual void createState(); - public: - CgCullFaceGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - /// FogCoordSrcGlobal - FogCoordSrc - class CgFogCoordSrcGlobalStateListener : public CgIntGlobalStateListener - { - protected: - enum FogCoordSrcType - { - FCST_FRAGMENTDEPTH, // FragmentDepth - FCST_FOGCOORD // FogCoord - }; - virtual void createState(); - public: - CgFogCoordSrcGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - // AlphaFuncGlobal - float2 - reference then value - class CgAlphaFuncGlobalStateListener : public CgFloat2GlobalStateListener - { - protected: - enum AlphaFuncType - { - AFT_NEVER, // Never - AFT_LESS, // Less - AFT_LEQUAL, // LEqual - AFT_EQUAL, // Equal - AFT_GREATER, // Greater - AFT_NOTEQUAL, // NotEqual - AFT_GEQUAL, // GEqual - AFT_ALWAYS // Always - }; - virtual void createState(); - public: - CgAlphaFuncGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - // BlendFuncGlobal - Int2 - src_factor, dst_factor - class CgBlendFuncGlobalStateListener : public CgInt2GlobalStateListener - { - protected: - enum BlendFuncType - { - BF_ZERO, // Zero - BF_ONE, // One - BF_DESTCOLOR, // DestColor - BF_ONEMINUSDESTCOLOR, // OneMinusDestColor - BF_SRCALPHA, // SrcAlpha - BF_ONEMINUSSRCALPHA, // OneMinusSrcAlpha - BF_DSTALPHA, // DstAlpha - BF_ONEMINUSDSTALPHA, // OneMinusDstAlpha - BF_SRCALPHASATURATE, // SrcAlphaSaturate - BF_SRCCOLOR, // SrcColor - BF_ONEMINUSSRCCOLOR, // OneMinusSrcColor - BF_CONSTANTCOLOR, // ConstantColor - BF_ONEMINUSCONSTANTCOLOR, // OneMinusConstantColor - BF_CONSTANTALPHA, // ConstantAlpha - BF_ONEMINUSCONSTANTALPHA // OneMinusConstantAlpha - }; - virtual void createState(); - public: - CgBlendFuncGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - - // BlendFuncSeparate - int4 (rgb_src, rgb_dst, a_src, a_dst) - class CgBlendFuncSeparateGlobalStateListener : public CgInt4GlobalStateListener - { - protected: - enum BlendFuncSeparateType - { - BFST_ZERO, // Zero - BFST_ONE, // One - BFST_DESTCOLOR, // DestColor - BFST_ONEMINUSDESTCOLOR, // OneMinusDestColor - BFST_SRCALPHA, // SrcAlpha - BFST_ONEMINUSSRCALPHA, // OneMinusSrcAlpha - BFST_DSTALPHA, // DstAlpha - BFST_ONEMINUSDSTALPHA, // OneMinusDstAlpha - BFST_SRCALPHASATURATE, // SrcAlphaSaturate - BFST_SRCCOLOR, // SrcColor - BFST_ONEMINUSSRCCOLOR, // OneMinusSrcColor - BFST_CONSTANTCOLOR, // ConstantColor - BFST_ONEMINUSCONSTANTCOLOR, // OneMinusConstantColor - BFST_CONSTANTALPHA, // ConstantAlpha - BFST_ONEMINUSCONSTANTALPHA // OneMinusConstantAlpha - }; - virtual void createState(); - public: - CgBlendFuncSeparateGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - // BlendEquationSeparate - int2 (rgb,alpha) - class CgBlendEquationSeparateGlobalStateListener : public CgInt2GlobalStateListener - { - protected: - enum BlendEquationSeparateType - { - BEST_FUNCADD, // FuncAdd - BEST_FUNCSUBTRACT, // FuncSubtract - BEST_MIN, // Min - BEST_MAX, // Max - BEST_LOGICOP // LogicOp - }; - virtual void createState(); - public: - CgBlendEquationSeparateGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - - // int2 - class CgColorMaterialGlobalStateListener : public CgInt2GlobalStateListener - { - protected: - enum ColorMaterialType - { - CMT_FRONT, // Front - CMT_BACK, // Back - CMT_FRONTANDBACK, // FrontAndBack - CMT_EMISSION, // Emission - CMT_AMBIENT, // Ambient - CMT_DIFFUSE, // Diffuse - CMT_SPECULAR, // Specular - CMT_AMBIENTANDDIFFUSE // AmbientAndDiffuse - }; - virtual void createState(); - public: - CgColorMaterialGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - // int2 - class CgPolygonModeGlobalStateListener : public CgInt2GlobalStateListener - { - protected: - enum PolygonModeType - { - PMT_FRONT, // Front - PMT_BACK, // Back - PMT_FRONTANDBACK, // FrontAndBack - PMT_POINT, // Point - PMT_LINE, // Line - PMT_FILL // Fill - }; - virtual void createState(); - public: - CgPolygonModeGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - // int3 - class CgStencilFuncGlobalStateListener : public CgInt3GlobalStateListener - { - protected: - enum StencilFuncType - { - SFT_NEVER, // Never - SFT_LESS, // Less - SFT_LEQUAL, // LEqual - SFT_EQUAL, // Equal - SFT_GREATER, // Greater - SFT_NOTEQUAL, // NotEqual - SFT_GEQUAL, // GEqual - SFT_ALWAYS // Always - }; - virtual void createState(); - public: - CgStencilFuncGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - // int3 - class CgStencilOpGlobalStateListener : public CgInt3GlobalStateListener - { - protected: - enum StencilOpType - { - SOT_KEEP, // Keep - SOT_ZERO, // Zero - SOT_REPLACE, // Replace - SOT_INCR, // Incr - SOT_DECR, // Decr - SOT_INVERT, // Invert - SOT_INCRWRAP, // IncrWrap - SOT_DECRWRAP // DecrWrap - }; - virtual void createState(); - public: - CgStencilOpGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - // int4 - class CgStencilFuncSeparateGlobalStateListener : public CgInt4GlobalStateListener - { - protected: - enum StencilFuncSeparateType - { - SFST_FRONT, // Front - SFST_BACK, // Back - SFST_FRONTANDBACK, // FrontAndBack - SFST_NEVER, // Never - SFST_LESS, // Less - SFST_LEQUAL, // LEqual - SFST_EQUAL, // Equal - SFST_GREATER, // Greater - SFST_NOTEQUAL, // NotEqual - SFST_GEQUAL, // GEqual - SFST_ALWAYS // Always - }; - virtual void createState(); - public: - CgStencilFuncSeparateGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - // int2 - class CgStencilMaskSeparateGlobalStateListener : public CgInt2GlobalStateListener - { - protected: - enum StencilMaskSeparateType - { - BET_FRONT, // Front - BET_BACK, // Back - BET_FRONTANDBACK // FrontAndBack - }; - virtual void createState(); - public: - CgStencilMaskSeparateGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - // int4 - class CgStencilOpSeparateGlobalStateListener : public CgInt4GlobalStateListener - { - protected: - enum StencilOpSeparateType - { - BET_KEEP, // Keep - BET_ZERO, // Zero - BET_REPLACE, // Replace - BET_INCR, // Incr - BET_DECR, // Decr - BET_INVERT, // Invert - BET_INCRWRAP, // IncrWrap - BET_DECRWRAP // DecrWrap - }; - virtual void createState(); - public: - CgStencilOpSeparateGlobalStateListener(); - virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); - }; - - - class CgSamplerStateListener : public CgStateListener - { - protected: - SamplerStateType mSamplerStateType; - virtual void createState(); - public: - CgSamplerStateListener( const SamplerStateType samplerStateType, CGtype cgType ); - virtual ~CgSamplerStateListener(); - - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// Int - class CgIntSamplerStateListener : public CgSamplerStateListener - { - protected: - const Vector1i getValue( CGstateassignment cgStateAssignment ); - public: - CgIntSamplerStateListener( const SamplerStateType samplerStateType ); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// Bool - class CgBoolSamplerStateListener : public CgSamplerStateListener - { - public: - CgBoolSamplerStateListener( const SamplerStateType samplerStateType ); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// Float - class CgFloatSamplerStateListener : public CgSamplerStateListener - { - public: - CgFloatSamplerStateListener( const SamplerStateType samplerStateType ); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// Float4 - class CgFloat4SamplerStateListener : public CgSamplerStateListener - { - public: - CgFloat4SamplerStateListener( const SamplerStateType samplerStateType ); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// Texture - class CgTextureSamplerStateListener : public CgSamplerStateListener - { - protected: - TextureType parseTextureType( CGparameter cgParameter, TextureUnitState * ogreTextureUnitState ); - void parseTextureName( CGparameter cgParameter, TextureUnitState * ogreTextureUnitState ); - public: - CgTextureSamplerStateListener(const SamplerStateType samplerStateType); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - - }; - - // Wrap = TextureAddressingMode - class CgWrapSamplerStateListener : public CgIntSamplerStateListener - { - protected: - enum WarpType - { - WT_REPEAT, // Repeat - WT_CLAMP, // Clamp - WT_CLAMPTOEDGE, // ClampToEdge - WT_CLAMPTOBORDER, // ClampToBorder - WT_MIRROREDREPEAT, // MirroredRepeat - WT_MIRRORCLAMP, // MirrorClamp - WT_MIRRORCLAMPTOEDGE, // MirrorClampToEdge - WT_MIRRORCLAMPTOBORDER // MirrorClampToBorder - }; - virtual void createState(); - TextureUnitState::TextureAddressingMode getOgreTextureAddressingMode( CGstateassignment cgStateAssignment ); - public: - CgWrapSamplerStateListener(const SamplerStateType samplerStateType); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// CompareMode - class CgCompareModeSamplerStateListener : public CgIntSamplerStateListener - { - protected: - enum CompareModeType - { - CMT_NONE, // None - CMT_COMPARERTOTEXTURE // CompareRToTexture - }; - virtual void createState(); - public: - CgCompareModeSamplerStateListener(); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// CompareFunc - class CgCompareFuncSamplerStateListener : public CgIntSamplerStateListener - { - protected: - enum CompareFuncType - { - CFT_NEVER, // Never - CFT_LESS, // Less - CFT_LEQUAL, // LEqual - CFT_EQUAL, // Equal - CFT_GREATER, // Greater - CFT_NOTEQUAL // NotEqual - }; - virtual void createState(); - public: - CgCompareFuncSamplerStateListener(); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// DepthMode - class CgDepthModeSamplerStateListener : public CgIntSamplerStateListener - { - protected: - enum DepthModeType - { - DMT_ALPHA, // Alpha - DMT_INTENSITY, // Intensity - DMT_LUMINANCE // Luminance - }; - virtual void createState(); - public: - CgDepthModeSamplerStateListener(); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// MinFilter - class CgMinFilterSamplerStateListener : public CgIntSamplerStateListener - { - protected: - enum MinFilterType - { - MINFT_NEAREST, // Nearest - MINFT_LINEAR, // Linear - MINFT_LINEARMIPMAPNEAREST, // LinearMipMapNearest - MINFT_NEARESTMIPMAPNEAREST, // NearestMipMapNearest - MINFT_NEARESTMIPMAPLINEAR, // NearestMipMapLinear - MINFT_LINEARMIPMAPLINEAR // LinearMipMapLinear - }; - - virtual void createState(); - public: - CgMinFilterSamplerStateListener(); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// MagFilter - class CgMagFilterSamplerStateListener : public CgIntSamplerStateListener - { - protected: - enum MagFilterType - { - MAGFT_NEAREST, // Nearest - MAGFT_LINEAR // Linear - - }; - - virtual void createState(); - public: - CgMagFilterSamplerStateListener(); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// MipFilter - class CgMipFilterSamplerStateListener : public CgIntSamplerStateListener - { - protected: - enum MipFilterType - { - MIPFT_NONE = 0, // filtering disabled (valid for mip filter only) - MIPFT_POINT = 1, // nearest - MIPFT_LINEAR = 2, // linear interpolation - MIPFT_ANISOTROPIC = 3, // anisotropic - MIPFT_PYRAMIDALQUAD = 6, // 4-sample tent - MIPFT_GAUSSIANQUAD = 7 // 4-sample gaussian - - }; - - virtual void createState(); - public: - CgMipFilterSamplerStateListener(); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - /// TextureAddress - class CgTextureAddressSamplerStateListener : public CgIntSamplerStateListener - { - protected: - enum TextureAddressType - { - TAT_WRAP = 1, // Wrap - TAT_MIRROR, // Mirror - TAT_CLAMP, // Clamp - TAT_BORDER, // Border - TAT_MIRRORONCE // MirrorOnce - }; - - virtual void createState(); - public: - CgTextureAddressSamplerStateListener( const SamplerStateType samplerStateType ); - virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); - }; - - typedef map::type CgGlobalStateToListenerMap; - typedef map::type CgSamplerStateToListenerMap; - - CgGlobalStateToListenerMap mCgGlobalStateToListenerMap; - CgSamplerStateToListenerMap mCgSamplerStateToListenerMap; - CgStateListenerVector mCgStateListenerVector; - CgStateListenerVector mCgSamplerStateListenerVector; - - StringVector mScriptPatterns; // for getScriptPatterns(void) - - CGcontext mCgContext; - CGcontext getCgContext() const; - - - void parseCgEffect( CGeffect cgEffect, MaterialPtr ogreMaterial ); - void parseCgEffectTechniques( CGeffect cgEffect, MaterialPtr ogreMaterial ); - void parseCgTechnique( CGtechnique cgTechnique, Technique * ogreTechnique ); - void parseCgPass( CGpass cgPass, Pass * ogrePass ); - void parseSamplerParameters(CGpass cgPass, Pass * ogrePass); - - void parsePassStateAssignments( CGpass cgPass, Pass * ogrePass ); - void parseCgProgram( CGpass cgPass, Pass * ogrePass, const GpuProgramType ogreProgramType ); - void parseCgProgramParameters( CGpass cgPass, GpuProgramParametersSharedPtr ogreProgramParameters ); - void parseCgProgramParameter( CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ); - void parseTextureUnitState( CGstateassignment cgStateAssignment, TextureUnitState * ogreTextureUnitState ); - - void parseFloatCgProgramParameter( CGtype cgParamType, CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ); - void parseIntCgProgramParameter( CGtype cgParamType, CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ); - bool parseAutoConstantParam( CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ); - bool cgSemanticToOgreAutoConstantType( const char * cgParamSemantic, const char * uiNameValue, GpuProgramParameters::AutoConstantType & ogreAutoConstantType, size_t & extraInfo ); - FXSemanticID cgSemanticStringToType( const char * cgParamSemantic ); - - void buildStateNameStringToTypeMap(); - - const char * getGlobalStateNameTypeToString( const GlobalStateType cgStateName ); - const char * getSamplerStateNameTypeToString( const SamplerStateType cgStateName ); - CgGlobalStateListener * createCgGlobalStateListener( const GlobalStateType type ); - CgSamplerStateListener * createCgSamplerStateListener( const SamplerStateType type ); + struct Vector1b + { + bool x; + Vector1b(); + Vector1b( bool iX ); + Vector1b( CGstateassignment cgStateAssignment ); + operator bool() const; + }; + + struct Vector2b + { + bool x, y; + Vector2b(); + Vector2b( bool iX, bool iY , bool iZ, bool iW ); + Vector2b( CGstateassignment cgStateAssignment ); + }; + + struct Vector3b + { + bool x, y, z; + Vector3b(); + Vector3b( bool iX, bool iY , bool iZ, bool iW ); + Vector3b( CGstateassignment cgStateAssignment ); + }; + + struct Vector4b + { + bool x, y, z, w; + Vector4b(); + Vector4b( bool iX, bool iY , bool iZ, bool iW ); + Vector4b( CGstateassignment cgStateAssignment ); + }; + + struct Vector1i + { + int x; + Vector1i(); + Vector1i( int iX ); + Vector1i( CGstateassignment cgStateAssignment ); + operator int() const; + + }; + + struct Vector2i + { + int x, y; + Vector2i(); + Vector2i( int iX, int iY ); + Vector2i( CGstateassignment cgStateAssignment ); + }; + + struct Vector3i + { + int x, y, z; + Vector3i(); + Vector3i( int iX, int iY, int iZ ); + Vector3i( CGstateassignment cgStateAssignment ); + }; + + + struct Vector4i + { + int x, y, z, w; + Vector4i(); + Vector4i( int iX, int iY, int iZ, int iW ); + Vector4i( CGstateassignment cgStateAssignment ); + }; + + + struct Vector1f + { + float x; + Vector1f(); + Vector1f( float iX, float iY, float iZ ); + Vector1f( CGstateassignment cgStateAssignment ); + operator float() const; + }; + + + struct Vector2f + { + float x, y; + Vector2f(); + Vector2f( float iX, float iY, float iZ ); + Vector2f( CGstateassignment cgStateAssignment ); + }; + + + struct Vector3f + { + float x, y, z; + Vector3f(); + Vector3f( float iX, float iY, float iZ ); + Vector3f( CGstateassignment cgStateAssignment ); + }; + + struct Vector4f + { + float x, y, z, w; + Vector4f(); + Vector4f( float iX, float iY, float iZ, float iW ); + Vector4f( CGstateassignment cgStateAssignment ); + }; + + + + // simple types end + + + class CgStateListener : public GeneralAllocatedObject + { + protected: + CGstate mCgState; + CGtype mCgType; + CGcontext mCgContext; + + static CGbool cgCallBackSet( CGstateassignment cgStateAssignment ); + static CGbool cgCallBackReset( CGstateassignment cgStateAssignment ); + static CGbool cgCallBackValidate( CGstateassignment cgStateAssignment ); + + virtual CGstatecallback getCgCallBackSet(); + virtual CGstatecallback getCgCallBackReset(); + virtual CGstatecallback getCgCallBackValidate(); + + virtual void createState() = 0; + void addStateEnumerant( int value, const char *name ); + + CGparameter getCgParameter( CGstateassignment cgStateAssignment ); + + + public: + CgStateListener( CGtype cgType ); + virtual ~CgStateListener(); + virtual void init(); + CGstate getCgState() const; + }; + + typedef vector::type CgStateListenerVector; + + class CgGlobalStateListener : public CgStateListener + { + protected: + const GlobalStateType mGlobalStateType; + virtual void createState(); + public: + CgGlobalStateListener( const GlobalStateType globalStateType, CGtype cgType ); + virtual ~CgGlobalStateListener(); + + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Bool + class CgBoolGlobalStateListener : public CgGlobalStateListener + { + protected: + const Vector1b getValue( CGstateassignment cgStateAssignment ); + public: + CgBoolGlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Bool4 + class CgBool4GlobalStateListener : public CgGlobalStateListener + { + protected: + const Vector4b getValue( CGstateassignment cgStateAssignment ); + public: + CgBool4GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Float + class CgFloatGlobalStateListener : public CgGlobalStateListener + { + protected: + const Vector1f getValue( CGstateassignment cgStateAssignment ); + public: + CgFloatGlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Float2 + class CgFloat2GlobalStateListener : public CgGlobalStateListener + { + protected: + const Vector2f getValue( CGstateassignment cgStateAssignment ); + public: + CgFloat2GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Float3 + class CgFloat3GlobalStateListener : public CgGlobalStateListener + { + protected: + const Vector3f getValue( CGstateassignment cgStateAssignment ); + public: + CgFloat3GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Float4 + class CgFloat4GlobalStateListener : public CgGlobalStateListener + { + protected: + const Vector4f getValue( CGstateassignment cgStateAssignment ); + public: + CgFloat4GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Float4x2 + class CgFloat4x2GlobalStateListener : public CgGlobalStateListener + { + public: + CgFloat4x2GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Float4x3 + class CgFloat4x3GlobalStateListener : public CgGlobalStateListener + { + public: + CgFloat4x3GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Float4x4 + class CgFloat4x4GlobalStateListener : public CgGlobalStateListener + { + public: + CgFloat4x4GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Int + class CgIntGlobalStateListener : public CgGlobalStateListener + { + protected: + const Vector1i getValue( CGstateassignment cgStateAssignment ); + public: + CgIntGlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Int2 + class CgInt2GlobalStateListener : public CgGlobalStateListener + { + protected: + const Vector2i getValue( CGstateassignment cgStateAssignment ); + public: + CgInt2GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Int3 + class CgInt3GlobalStateListener : public CgGlobalStateListener + { + protected: + const Vector3i getValue( CGstateassignment cgStateAssignment ); + public: + CgInt3GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Int4 + class CgInt4GlobalStateListener : public CgGlobalStateListener + { + protected: + const Vector4i getValue( CGstateassignment cgStateAssignment ); + public: + CgInt4GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Sampler + class CgSamplerGlobalStateListener : public CgGlobalStateListener + { + public: + CgSamplerGlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Sampler2 + class CgSampler2GlobalStateListener : public CgGlobalStateListener + { + public: + CgSampler2GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Sampler3 + class CgSampler3GlobalStateListener : public CgGlobalStateListener + { + public: + CgSampler3GlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// SamplerCube + class CgSamplerCubeGlobalStateListener : public CgGlobalStateListener + { + public: + CgSamplerCubeGlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// SamplerRect + class CgSamplerRectGlobalStateListener : public CgGlobalStateListener + { + public: + CgSamplerRectGlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Texture + class CgTextureGlobalStateListener : public CgGlobalStateListener + { + public: + CgTextureGlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// Program + class CgProgramGlobalStateListener : public CgGlobalStateListener + { + public: + CgProgramGlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + /// BlendEquation + class CgBlendEquationGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum BlendEquationType + { + BET_FUNCADD, // FuncAdd + BET_FUNCSUBTRACT, // FuncSubtract + BET_MIN, // Min + BET_MAX, // Max + BET_LOGICOP // LogicOp + }; + virtual void createState(); + public: + CgBlendEquationGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// DepthFunc + class CgDepthFuncGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum DepthFuncType + { + DFT_NEVER, // Never + DFT_LESS, // Less + DFT_LEQUAL, // LEqual + DFT_EQUAL, // Equal + DFT_GREATER, // Greater + DFT_NOTEQUAL, // NotEqual + DFT_GEQUAL, // GEqual + DFT_ALWAYS // Always + }; + virtual void createState(); + public: + CgDepthFuncGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// FogDistanceMode + class CgFogDistanceModeGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum FogDistanceModeType + { + FDMT_EYERADIAL, // EyeRadial + FDMT_EYEPLANE, // EyePlane + FDMT_EYEPLANEABSOLUTE // EyePlaneAbsolute + }; + virtual void createState(); + public: + CgFogDistanceModeGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// FogMode + class CgFogModeGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum FogModeType + { + FMT_LINEAR, // Linear + FMT_EXP, // Exp + FMT_EXP2 // Exp2 + }; + virtual void createState(); + public: + CgFogModeGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + /// LightModelColorControl + class CgLightModelColorControlGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum LightModelColorControlType + { + LMCCT_SINGLECOLOR, // SingleColor + LMCCT_SEPARATESPECULAR // SeparateSpecular + }; + virtual void createState(); + public: + CgLightModelColorControlGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// LogicOp + class CgLogicOpGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum LogicOpType + { + LOT_CLEAR, // Clear + LOT_AND, // And + LOT_ANDREVERSE, // AndReverse + LOT_COPY, // Copy + LOT_ANDINVERTED, // AndInverted + LOT_NOOP, // Noop + LOT_XOR, // Xor + LOT_OR, // Or, + LOT_NOR, // Nor + LOT_EQUIV, // Equiv + LOT_INVERT, // Invert + LOT_ORREVERSE, // OrReverse + LOT_COPYINVERTED, // CopyInverted + LOT_NAND, // Nand + LOT_SET // Set + }; + virtual void createState(); + public: + CgLogicOpGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// PointSpriteCoordOrigin + class CgPointSpriteCoordOriginGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum PointSpriteCoordOriginType + { + PSCOT_LOWERLEFT, // LowerLeft + PSCOT_UPPERLEFT // UpperLeft + }; + virtual void createState(); + public: + CgPointSpriteCoordOriginGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// PointSpriteRMode + class CgPointSpriteRModeGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum PointSpriteRModeType + { + PSRMT_ZERO, // Zero + PSRMT_R, // R + PSRMT_S // S + }; + virtual void createState(); + public: + CgPointSpriteRModeGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// ShadeModel + class CgShadeModelGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum ShadeModelType + { + SMT_FLAT, // Flat + SMT_SMOOTH // Smooth + }; + virtual void createState(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + public: + CgShadeModelGlobalStateListener(); + }; + /// TexGenMode + class CgTexGenModeGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum TexGenModeType + { + TGMT_OBJECTLINEAR, // ObjectLinear + TGMT_EYELINEAR, // EyeLinear + TGMT_SPHEREMAP, // SphereMap + TGMT_REFLECTIONMAP, // ReflectionMap + TGMT_NORMALMAP // NormalMap + }; + virtual void createState(); + public: + CgTexGenModeGlobalStateListener( const GlobalStateType globalStateType ); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// TextureEnvMode + class CgTextureEnvModeGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum TextureEnvModeType + { + BET_MODULATE, // Modulate + BET_DECAL, // Decal + BET_BLEND, // Blend + BET_REPLACE, // Replace + BET_ADD // Add + }; + virtual void createState(); + public: + CgTextureEnvModeGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// MinFilter + class CgMinFilterGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum MinFilterType + { + MFT_NEAREST, // Nearest + MFT_LINEAR, // Linear + MFT_LINEARMIPMAPNEAREST, // LinearMipMapNearest + MFT_NEARESTMIPMAPNEAREST, // NearestMipMapNearest + MFT_NEARESTMIPMAPLINEAR, // NearestMipMapLinear + MFT_LINEARMIPMAPLINEAR // LinearMipMapLinear + }; + virtual void createState(); + public: + CgMinFilterGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// MagFilter + class CgMagFilterGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum MagFilterType + { + MFT_NEAREST, // Nearest + MFT_LINEAR // Linear + }; + virtual void createState(); + public: + CgMagFilterGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// FrontFace + class CgFrontFaceGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum FrontFaceType + { + FFT_CW, // CW + FFT_CCW // CCW + }; + virtual void createState(); + public: + CgFrontFaceGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// CullFaceGlobal - CullFace + class CgCullFaceGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum CullFaceType + { + CFT_FRONT, // Front + CFT_BACK, // Back + CFT_FRONTANDBACK // FrontAndBack + }; + virtual void createState(); + public: + CgCullFaceGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + /// FogCoordSrcGlobal - FogCoordSrc + class CgFogCoordSrcGlobalStateListener : public CgIntGlobalStateListener + { + protected: + enum FogCoordSrcType + { + FCST_FRAGMENTDEPTH, // FragmentDepth + FCST_FOGCOORD // FogCoord + }; + virtual void createState(); + public: + CgFogCoordSrcGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + // AlphaFuncGlobal - float2 - reference then value + class CgAlphaFuncGlobalStateListener : public CgFloat2GlobalStateListener + { + protected: + enum AlphaFuncType + { + AFT_NEVER, // Never + AFT_LESS, // Less + AFT_LEQUAL, // LEqual + AFT_EQUAL, // Equal + AFT_GREATER, // Greater + AFT_NOTEQUAL, // NotEqual + AFT_GEQUAL, // GEqual + AFT_ALWAYS // Always + }; + virtual void createState(); + public: + CgAlphaFuncGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + // BlendFuncGlobal - Int2 - src_factor, dst_factor + class CgBlendFuncGlobalStateListener : public CgInt2GlobalStateListener + { + protected: + enum BlendFuncType + { + BF_ZERO, // Zero + BF_ONE, // One + BF_DESTCOLOR, // DestColor + BF_ONEMINUSDESTCOLOR, // OneMinusDestColor + BF_SRCALPHA, // SrcAlpha + BF_ONEMINUSSRCALPHA, // OneMinusSrcAlpha + BF_DSTALPHA, // DstAlpha + BF_ONEMINUSDSTALPHA, // OneMinusDstAlpha + BF_SRCALPHASATURATE, // SrcAlphaSaturate + BF_SRCCOLOR, // SrcColor + BF_ONEMINUSSRCCOLOR, // OneMinusSrcColor + BF_CONSTANTCOLOR, // ConstantColor + BF_ONEMINUSCONSTANTCOLOR, // OneMinusConstantColor + BF_CONSTANTALPHA, // ConstantAlpha + BF_ONEMINUSCONSTANTALPHA // OneMinusConstantAlpha + }; + virtual void createState(); + public: + CgBlendFuncGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + + // BlendFuncSeparate - int4 (rgb_src, rgb_dst, a_src, a_dst) + class CgBlendFuncSeparateGlobalStateListener : public CgInt4GlobalStateListener + { + protected: + enum BlendFuncSeparateType + { + BFST_ZERO, // Zero + BFST_ONE, // One + BFST_DESTCOLOR, // DestColor + BFST_ONEMINUSDESTCOLOR, // OneMinusDestColor + BFST_SRCALPHA, // SrcAlpha + BFST_ONEMINUSSRCALPHA, // OneMinusSrcAlpha + BFST_DSTALPHA, // DstAlpha + BFST_ONEMINUSDSTALPHA, // OneMinusDstAlpha + BFST_SRCALPHASATURATE, // SrcAlphaSaturate + BFST_SRCCOLOR, // SrcColor + BFST_ONEMINUSSRCCOLOR, // OneMinusSrcColor + BFST_CONSTANTCOLOR, // ConstantColor + BFST_ONEMINUSCONSTANTCOLOR, // OneMinusConstantColor + BFST_CONSTANTALPHA, // ConstantAlpha + BFST_ONEMINUSCONSTANTALPHA // OneMinusConstantAlpha + }; + virtual void createState(); + public: + CgBlendFuncSeparateGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + // BlendEquationSeparate - int2 (rgb,alpha) + class CgBlendEquationSeparateGlobalStateListener : public CgInt2GlobalStateListener + { + protected: + enum BlendEquationSeparateType + { + BEST_FUNCADD, // FuncAdd + BEST_FUNCSUBTRACT, // FuncSubtract + BEST_MIN, // Min + BEST_MAX, // Max + BEST_LOGICOP // LogicOp + }; + virtual void createState(); + public: + CgBlendEquationSeparateGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + + // int2 + class CgColorMaterialGlobalStateListener : public CgInt2GlobalStateListener + { + protected: + enum ColorMaterialType + { + CMT_FRONT, // Front + CMT_BACK, // Back + CMT_FRONTANDBACK, // FrontAndBack + CMT_EMISSION, // Emission + CMT_AMBIENT, // Ambient + CMT_DIFFUSE, // Diffuse + CMT_SPECULAR, // Specular + CMT_AMBIENTANDDIFFUSE // AmbientAndDiffuse + }; + virtual void createState(); + public: + CgColorMaterialGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + // int2 + class CgPolygonModeGlobalStateListener : public CgInt2GlobalStateListener + { + protected: + enum PolygonModeType + { + PMT_FRONT, // Front + PMT_BACK, // Back + PMT_FRONTANDBACK, // FrontAndBack + PMT_POINT, // Point + PMT_LINE, // Line + PMT_FILL // Fill + }; + virtual void createState(); + public: + CgPolygonModeGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + // int3 + class CgStencilFuncGlobalStateListener : public CgInt3GlobalStateListener + { + protected: + enum StencilFuncType + { + SFT_NEVER, // Never + SFT_LESS, // Less + SFT_LEQUAL, // LEqual + SFT_EQUAL, // Equal + SFT_GREATER, // Greater + SFT_NOTEQUAL, // NotEqual + SFT_GEQUAL, // GEqual + SFT_ALWAYS // Always + }; + virtual void createState(); + public: + CgStencilFuncGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + // int3 + class CgStencilOpGlobalStateListener : public CgInt3GlobalStateListener + { + protected: + enum StencilOpType + { + SOT_KEEP, // Keep + SOT_ZERO, // Zero + SOT_REPLACE, // Replace + SOT_INCR, // Incr + SOT_DECR, // Decr + SOT_INVERT, // Invert + SOT_INCRWRAP, // IncrWrap + SOT_DECRWRAP // DecrWrap + }; + virtual void createState(); + public: + CgStencilOpGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + // int4 + class CgStencilFuncSeparateGlobalStateListener : public CgInt4GlobalStateListener + { + protected: + enum StencilFuncSeparateType + { + SFST_FRONT, // Front + SFST_BACK, // Back + SFST_FRONTANDBACK, // FrontAndBack + SFST_NEVER, // Never + SFST_LESS, // Less + SFST_LEQUAL, // LEqual + SFST_EQUAL, // Equal + SFST_GREATER, // Greater + SFST_NOTEQUAL, // NotEqual + SFST_GEQUAL, // GEqual + SFST_ALWAYS // Always + }; + virtual void createState(); + public: + CgStencilFuncSeparateGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + // int2 + class CgStencilMaskSeparateGlobalStateListener : public CgInt2GlobalStateListener + { + protected: + enum StencilMaskSeparateType + { + BET_FRONT, // Front + BET_BACK, // Back + BET_FRONTANDBACK // FrontAndBack + }; + virtual void createState(); + public: + CgStencilMaskSeparateGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + // int4 + class CgStencilOpSeparateGlobalStateListener : public CgInt4GlobalStateListener + { + protected: + enum StencilOpSeparateType + { + BET_KEEP, // Keep + BET_ZERO, // Zero + BET_REPLACE, // Replace + BET_INCR, // Incr + BET_DECR, // Decr + BET_INVERT, // Invert + BET_INCRWRAP, // IncrWrap + BET_DECRWRAP // DecrWrap + }; + virtual void createState(); + public: + CgStencilOpSeparateGlobalStateListener(); + virtual void updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ); + }; + + + class CgSamplerStateListener : public CgStateListener + { + protected: + SamplerStateType mSamplerStateType; + virtual void createState(); + public: + CgSamplerStateListener( const SamplerStateType samplerStateType, CGtype cgType ); + virtual ~CgSamplerStateListener(); + + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// Int + class CgIntSamplerStateListener : public CgSamplerStateListener + { + protected: + const Vector1i getValue( CGstateassignment cgStateAssignment ); + public: + CgIntSamplerStateListener( const SamplerStateType samplerStateType ); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// Bool + class CgBoolSamplerStateListener : public CgSamplerStateListener + { + public: + CgBoolSamplerStateListener( const SamplerStateType samplerStateType ); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// Float + class CgFloatSamplerStateListener : public CgSamplerStateListener + { + public: + CgFloatSamplerStateListener( const SamplerStateType samplerStateType ); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// Float4 + class CgFloat4SamplerStateListener : public CgSamplerStateListener + { + public: + CgFloat4SamplerStateListener( const SamplerStateType samplerStateType ); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// Texture + class CgTextureSamplerStateListener : public CgSamplerStateListener + { + protected: + TextureType parseTextureType( CGparameter cgParameter, TextureUnitState * ogreTextureUnitState ); + void parseTextureName( CGparameter cgParameter, TextureUnitState * ogreTextureUnitState ); + public: + CgTextureSamplerStateListener(const SamplerStateType samplerStateType); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + + }; + + // Wrap = TextureAddressingMode + class CgWrapSamplerStateListener : public CgIntSamplerStateListener + { + protected: + enum WarpType + { + WT_REPEAT, // Repeat + WT_CLAMP, // Clamp + WT_CLAMPTOEDGE, // ClampToEdge + WT_CLAMPTOBORDER, // ClampToBorder + WT_MIRROREDREPEAT, // MirroredRepeat + WT_MIRRORCLAMP, // MirrorClamp + WT_MIRRORCLAMPTOEDGE, // MirrorClampToEdge + WT_MIRRORCLAMPTOBORDER // MirrorClampToBorder + }; + virtual void createState(); + TextureUnitState::TextureAddressingMode getOgreTextureAddressingMode( CGstateassignment cgStateAssignment ); + public: + CgWrapSamplerStateListener(const SamplerStateType samplerStateType); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// CompareMode + class CgCompareModeSamplerStateListener : public CgIntSamplerStateListener + { + protected: + enum CompareModeType + { + CMT_NONE, // None + CMT_COMPARERTOTEXTURE // CompareRToTexture + }; + virtual void createState(); + public: + CgCompareModeSamplerStateListener(); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// CompareFunc + class CgCompareFuncSamplerStateListener : public CgIntSamplerStateListener + { + protected: + enum CompareFuncType + { + CFT_NEVER, // Never + CFT_LESS, // Less + CFT_LEQUAL, // LEqual + CFT_EQUAL, // Equal + CFT_GREATER, // Greater + CFT_NOTEQUAL // NotEqual + }; + virtual void createState(); + public: + CgCompareFuncSamplerStateListener(); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// DepthMode + class CgDepthModeSamplerStateListener : public CgIntSamplerStateListener + { + protected: + enum DepthModeType + { + DMT_ALPHA, // Alpha + DMT_INTENSITY, // Intensity + DMT_LUMINANCE // Luminance + }; + virtual void createState(); + public: + CgDepthModeSamplerStateListener(); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// MinFilter + class CgMinFilterSamplerStateListener : public CgIntSamplerStateListener + { + protected: + enum MinFilterType + { + MINFT_NEAREST, // Nearest + MINFT_LINEAR, // Linear + MINFT_LINEARMIPMAPNEAREST, // LinearMipMapNearest + MINFT_NEARESTMIPMAPNEAREST, // NearestMipMapNearest + MINFT_NEARESTMIPMAPLINEAR, // NearestMipMapLinear + MINFT_LINEARMIPMAPLINEAR // LinearMipMapLinear + }; + + virtual void createState(); + public: + CgMinFilterSamplerStateListener(); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// MagFilter + class CgMagFilterSamplerStateListener : public CgIntSamplerStateListener + { + protected: + enum MagFilterType + { + MAGFT_NEAREST, // Nearest + MAGFT_LINEAR // Linear + + }; + + virtual void createState(); + public: + CgMagFilterSamplerStateListener(); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// MipFilter + class CgMipFilterSamplerStateListener : public CgIntSamplerStateListener + { + protected: + enum MipFilterType + { + MIPFT_NONE = 0, // filtering disabled (valid for mip filter only) + MIPFT_POINT = 1, // nearest + MIPFT_LINEAR = 2, // linear interpolation + MIPFT_ANISOTROPIC = 3, // anisotropic + MIPFT_PYRAMIDALQUAD = 6, // 4-sample tent + MIPFT_GAUSSIANQUAD = 7 // 4-sample gaussian + + }; + + virtual void createState(); + public: + CgMipFilterSamplerStateListener(); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + /// TextureAddress + class CgTextureAddressSamplerStateListener : public CgIntSamplerStateListener + { + protected: + enum TextureAddressType + { + TAT_WRAP = 1, // Wrap + TAT_MIRROR, // Mirror + TAT_CLAMP, // Clamp + TAT_BORDER, // Border + TAT_MIRRORONCE // MirrorOnce + }; + + virtual void createState(); + public: + CgTextureAddressSamplerStateListener( const SamplerStateType samplerStateType ); + virtual void upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ); + }; + + typedef map::type CgGlobalStateToListenerMap; + typedef map::type CgSamplerStateToListenerMap; + + CgGlobalStateToListenerMap mCgGlobalStateToListenerMap; + CgSamplerStateToListenerMap mCgSamplerStateToListenerMap; + CgStateListenerVector mCgStateListenerVector; + CgStateListenerVector mCgSamplerStateListenerVector; + + StringVector mScriptPatterns; // for getScriptPatterns(void) + + CGcontext mCgContext; + CGcontext getCgContext() const; + + + void parseCgEffect( CGeffect cgEffect, MaterialPtr ogreMaterial ); + void parseCgEffectTechniques( CGeffect cgEffect, MaterialPtr ogreMaterial ); + void parseCgTechnique( CGtechnique cgTechnique, Technique * ogreTechnique ); + void parseCgPass( CGpass cgPass, Pass * ogrePass ); + void parseSamplerParameters(CGpass cgPass, Pass * ogrePass); + + void parsePassStateAssignments( CGpass cgPass, Pass * ogrePass ); + void parseCgProgram( CGpass cgPass, Pass * ogrePass, const GpuProgramType ogreProgramType ); + void parseCgProgramParameters( CGpass cgPass, GpuProgramParametersSharedPtr ogreProgramParameters ); + void parseCgProgramParameter( CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ); + void parseTextureUnitState( CGstateassignment cgStateAssignment, TextureUnitState * ogreTextureUnitState ); + + void parseFloatCgProgramParameter( CGtype cgParamType, CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ); + void parseIntCgProgramParameter( CGtype cgParamType, CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ); + bool parseAutoConstantParam( CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ); + bool cgSemanticToOgreAutoConstantType( const char * cgParamSemantic, const char * uiNameValue, GpuProgramParameters::AutoConstantType & ogreAutoConstantType, size_t & extraInfo ); + FXSemanticID cgSemanticStringToType( const char * cgParamSemantic ); + + void buildStateNameStringToTypeMap(); + + const char * getGlobalStateNameTypeToString( const GlobalStateType cgStateName ); + const char * getSamplerStateNameTypeToString( const SamplerStateType cgStateName ); + CgGlobalStateListener * createCgGlobalStateListener( const GlobalStateType type ); + CgSamplerStateListener * createCgSamplerStateListener( const SamplerStateType type ); public: CgFxScriptLoader(); diff --git a/PlugIns/CgProgramManager/include/OgreCgPlugin.h b/PlugIns/CgProgramManager/include/OgreCgPlugin.h index 316c399f7a5..ca4abdc680d 100644 --- a/PlugIns/CgProgramManager/include/OgreCgPlugin.h +++ b/PlugIns/CgProgramManager/include/OgreCgPlugin.h @@ -34,32 +34,32 @@ namespace Ogre { class CgProgramFactory; - /** Plugin instance for Cg Program Manager */ - class CgPlugin : public Plugin - { - public: - CgPlugin(); + /** Plugin instance for Cg Program Manager */ + class CgPlugin : public Plugin + { + public: + CgPlugin(); - /// @copydoc Plugin::getName - const String& getName() const; + /// @copydoc Plugin::getName + const String& getName() const; - /// @copydoc Plugin::install - void install(); + /// @copydoc Plugin::install + void install(); - /// @copydoc Plugin::initialise - void initialise(); + /// @copydoc Plugin::initialise + void initialise(); - /// @copydoc Plugin::shutdown - void shutdown(); + /// @copydoc Plugin::shutdown + void shutdown(); - /// @copydoc Plugin::uninstall - void uninstall(); - protected: - CgProgramFactory* mCgProgramFactory; + /// @copydoc Plugin::uninstall + void uninstall(); + protected: + CgProgramFactory* mCgProgramFactory; - }; + }; } #endif diff --git a/PlugIns/CgProgramManager/include/OgreCgPrerequisites.h b/PlugIns/CgProgramManager/include/OgreCgPrerequisites.h index 666782397c5..854b033d6d0 100644 --- a/PlugIns/CgProgramManager/include/OgreCgPrerequisites.h +++ b/PlugIns/CgProgramManager/include/OgreCgPrerequisites.h @@ -42,20 +42,20 @@ namespace Ogre { #if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && !defined(__MINGW32__) && !defined(OGRE_STATIC_LIB) -# ifdef OGRE_CGPLUGIN_EXPORTS -# define _OgreCgPluginExport __declspec(dllexport) -# else +# ifdef OGRE_CGPLUGIN_EXPORTS +# define _OgreCgPluginExport __declspec(dllexport) +# else # if defined( __MINGW32__ ) # define _OgreCgPluginExport # else -# define _OgreCgPluginExport __declspec(dllimport) +# define _OgreCgPluginExport __declspec(dllimport) # endif # endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgreCgPluginExport __attribute__ ((visibility("default"))) #else -# define _OgreCgPluginExport -#endif // OGRE_WIN32 +# define _OgreCgPluginExport +#endif // OGRE_WIN32 } diff --git a/PlugIns/CgProgramManager/include/OgreCgProgram.h b/PlugIns/CgProgramManager/include/OgreCgProgram.h index 50424f6e767..ced02f9d32c 100644 --- a/PlugIns/CgProgramManager/include/OgreCgProgram.h +++ b/PlugIns/CgProgramManager/include/OgreCgProgram.h @@ -89,26 +89,26 @@ namespace Ogre { /// Load the high-level part in a thread-safe way, required for delegate functionality void loadHighLevelSafe(); - /// Recurse down structures getting data on parameters - void recurseParams(CGparameter param, size_t contextArraySize = 1); - /// Turn a Cg type into a GpuConstantType and number of elements - void mapTypeAndElementSize(CGtype cgType, bool isRegisterCombiner, GpuConstantDefinition& def) const; + /// Recurse down structures getting data on parameters + void recurseParams(CGparameter param, size_t contextArraySize = 1); + /// Turn a Cg type into a GpuConstantType and number of elements + void mapTypeAndElementSize(CGtype cgType, bool isRegisterCombiner, GpuConstantDefinition& def) const; StringVector mProfiles; String mEntryPoint; String mSelectedProfile; - String mProgramString; + String mProgramString; CGprofile mSelectedCgProfile; String mCompileArgs; // Unfortunately Cg uses char** for arguments - bleh // This is a null-terminated list of char* (each null terminated) char** mCgArguments; - - GpuConstantDefinitionMap mParametersMap; - size_t mParametersMapSizeAsBuffer; + + GpuConstantDefinitionMap mParametersMap; + size_t mParametersMapSizeAsBuffer; map::type mSamplerRegisterMap; CGenum mInputOp, mOutputOp; - + /// Internal method which works out which profile to use for this program void selectProfile(void); /// Internal method which merges manual and automatic compile arguments @@ -116,9 +116,9 @@ namespace Ogre { /// Releases memory for the horrible Cg char** void freeCgArgs(void); - void getMicrocodeFromCache(void); - void compileMicrocode(void); - void addMicrocodeToCache(); + void getMicrocodeFromCache(void); + void compileMicrocode(void); + void addMicrocodeToCache(); private: HighLevelGpuProgramPtr mDelegate; @@ -167,8 +167,8 @@ namespace Ogre { size_t getSize(void) const; void touch(void); - /// Scan the file for #include and replace with source from the OGRE resources - static String resolveCgIncludes(const String& source, Resource* resourceBeingLoaded, const String& fileName); + /// Scan the file for #include and replace with source from the OGRE resources + static String resolveCgIncludes(const String& source, Resource* resourceBeingLoaded, const String& fileName); }; } diff --git a/PlugIns/CgProgramManager/include/OgreCgProgramFactory.h b/PlugIns/CgProgramManager/include/OgreCgProgramFactory.h index 41805d55e5d..a5873b1a2f7 100644 --- a/PlugIns/CgProgramManager/include/OgreCgProgramFactory.h +++ b/PlugIns/CgProgramManager/include/OgreCgProgramFactory.h @@ -38,16 +38,16 @@ namespace Ogre { protected: CGcontext mCgContext; - static String sLanguageName; + static String sLanguageName; public: CgProgramFactory(); ~CgProgramFactory(); - /// Get the name of the language this factory creates programs for - const String& getLanguage(void) const; + /// Get the name of the language this factory creates programs for + const String& getLanguage(void) const; HighLevelGpuProgram* create(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - void destroy(HighLevelGpuProgram* prog); + void destroy(HighLevelGpuProgram* prog); }; } diff --git a/PlugIns/CgProgramManager/src/OgreCgFxScriptLoader.cpp b/PlugIns/CgProgramManager/src/OgreCgFxScriptLoader.cpp index 0dd797d6538..56494976cee 100644 --- a/PlugIns/CgProgramManager/src/OgreCgFxScriptLoader.cpp +++ b/PlugIns/CgProgramManager/src/OgreCgFxScriptLoader.cpp @@ -36,2612 +36,2612 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1b::Vector1b() : x(false) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1b::Vector1b( bool iX ) : x( iX ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1b::Vector1b( CGstateassignment cgStateAssignment ) : x( false ) - { - int nValsDummy[1]; - const CGbool * values; - values = cgGetBoolStateAssignmentValues(cgStateAssignment, nValsDummy); - assert(nValsDummy[0] == 1); + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1b::Vector1b() : x(false) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1b::Vector1b( bool iX ) : x( iX ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1b::Vector1b( CGstateassignment cgStateAssignment ) : x( false ) + { + int nValsDummy[1]; + const CGbool * values; + values = cgGetBoolStateAssignmentValues(cgStateAssignment, nValsDummy); + assert(nValsDummy[0] == 1); + +#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) +#pragma warning(push) +#pragma warning(disable: 4800) // warning C4800: 'const CGbool' : forcing value to bool 'true' or 'false' (performance warning) +#endif + x = static_cast(values[0]); +#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) +#pragma warning(pop) +#endif + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1b::operator bool() const + { + return x; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector2b::Vector2b() : x( false ), y( false ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector2b::Vector2b( bool iX, bool iY , bool iZ, bool iW ) : x( iX ), y( iY ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector2b::Vector2b( CGstateassignment cgStateAssignment ) : x( false ), y( false ) + { + int nValsDummy[1]; + const CGbool * values; + values = cgGetBoolStateAssignmentValues(cgStateAssignment, nValsDummy); + assert(nValsDummy[0] == 2); + +#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) +#pragma warning(push) +#pragma warning(disable: 4800) // warning C4800: 'const CGbool' : forcing value to bool 'true' or 'false' (performance warning) +#endif + x = static_cast(values[0]); + y = static_cast(values[1]); +#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) +#pragma warning(pop) +#endif + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //-------------------------------------------------------------------- + CgFxScriptLoader::Vector3b::Vector3b() : x( false ), y( false ), z( false ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector3b::Vector3b( bool iX, bool iY , bool iZ, bool iW ) : x( iX ), y( iY ), z( iZ ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector3b::Vector3b( CGstateassignment cgStateAssignment ) : x( false ), y( false ), z( false ) + { + int nValsDummy[1]; + const CGbool * values; + values = cgGetBoolStateAssignmentValues(cgStateAssignment, nValsDummy); + assert(nValsDummy[0] == 3); + +#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) +#pragma warning(push) +#pragma warning(disable: 4800) // warning C4800: 'const CGbool' : forcing value to bool 'true' or 'false' (performance warning) +#endif + x = static_cast(values[0]); + y = static_cast(values[1]); + z = static_cast(values[2]); +#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) +#pragma warning(pop) +#endif + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector4b::Vector4b() : x( false ), y( false ), z( false ), w( false ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector4b::Vector4b( bool iX, bool iY , bool iZ, bool iW ) : x( iX ), y( iY ), z( iZ ), w( iW ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector4b::Vector4b( CGstateassignment cgStateAssignment ) : x( false ), y( false ), z( false ), w( false ) + { + int nValsDummy[1]; + const CGbool * values; + values = cgGetBoolStateAssignmentValues(cgStateAssignment, nValsDummy); + assert(nValsDummy[0] == 4); + +#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) +#pragma warning(push) +#pragma warning(disable: 4800) // warning C4800: 'const CGbool' : forcing value to bool 'true' or 'false' (performance warning) +#endif + x = static_cast(values[0]); + y = static_cast(values[1]); + z = static_cast(values[2]); + w = static_cast(values[3]); +#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) +#pragma warning(pop) +#endif + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1i::Vector1i() : x( 0 ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1i::Vector1i( int iX ) : x( iX ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1i::Vector1i( CGstateassignment cgStateAssignment ) : x( 0 ) + { + int nValsDummy[1]; + const int * values; + values = cgGetIntStateAssignmentValues(cgStateAssignment, nValsDummy); + assert( nValsDummy[0] == 1); + + x = values[0]; + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1i::operator int() const + { + return x; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector2i::Vector2i() : x( 0 ), y( 0 ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector2i::Vector2i( int iX, int iY ) : x( iX ), y( iY ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector2i::Vector2i( CGstateassignment cgStateAssignment ) : x( 0 ), y( 0 ) + { + int nValsDummy[1]; + const int * values; + values = cgGetIntStateAssignmentValues(cgStateAssignment, nValsDummy); + assert( nValsDummy[0] == 2); + + x = values[0]; + y = values[1]; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector3i::Vector3i() : x( 0 ), y( 0 ), z( 0 ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector3i::Vector3i( int iX, int iY, int iZ ) : x( iX ), y( iY ) , z( iZ ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector3i::Vector3i( CGstateassignment cgStateAssignment ) : x( 0 ), y( 0 ), z( 0 ) + { + int nValsDummy[1]; + const int * values; + values = cgGetIntStateAssignmentValues(cgStateAssignment, nValsDummy); + assert( nValsDummy[0] == 3); + + x = values[0]; + y = values[1]; + z = values[2]; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector4i::Vector4i() : x( 0 ), y( 0 ), z( 0 ), w( 0 ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector4i::Vector4i( int iX, int iY, int iZ, int iW ) : x( iX ), y( iY ), z( iZ ), w( iW ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector4i::Vector4i( CGstateassignment cgStateAssignment ) : x( 0 ), y( 0 ), z( 0 ), w( 0 ) + { + int nValsDummy[1]; + const int * values; + values = cgGetIntStateAssignmentValues(cgStateAssignment, nValsDummy); + assert( nValsDummy[0] == 4 ); + + x = values[0]; + y = values[1]; + z = values[2]; + w = values[3]; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1f::Vector1f() : x( 0.0f ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1f::Vector1f( float iX, float iY, float iZ ) : x( iX ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1f::Vector1f( CGstateassignment cgStateAssignment ) : x( 0.0f ) + { + int nValsDummy[1]; + const float * values; + values = cgGetFloatStateAssignmentValues(cgStateAssignment, nValsDummy); + assert( nValsDummy[0] == 1 ); + + x = values[0]; + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector1f::operator float() const + { + return x; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector2f::Vector2f() : x( 0.0f ), y( 0.0f ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector2f::Vector2f( float iX, float iY, float iZ ) : x( iX ), y( iY ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector2f::Vector2f( CGstateassignment cgStateAssignment ) : x( 0.0f ), y( 0.0f ) + { + int nValsDummy[1]; + const float * values; + values = cgGetFloatStateAssignmentValues(cgStateAssignment, nValsDummy); + assert( nValsDummy[0] == 2 ); + + x = values[0]; + y = values[1]; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector3f::Vector3f() : x( 0.0f ), y( 0.0f ), z( 0.0f ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector3f::Vector3f( float iX, float iY, float iZ ) : x( iX ), y( iY ), z( iZ ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector3f::Vector3f( CGstateassignment cgStateAssignment ) : x( 0.0f ), y( 0.0f ), z( 0.0f ) + { + int nValsDummy[1]; + const float * values; + values = cgGetFloatStateAssignmentValues(cgStateAssignment, nValsDummy); + assert( nValsDummy[0] == 3 ); + + x = values[0]; + y = values[1]; + z = values[2]; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector4f::Vector4f() : x( 0.0f ), y( 0.0f ), z( 0.0f ), w( 0.0f ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector4f::Vector4f( float iX, float iY, float iZ, float iW ) : x( iX ), y( iY ), z( iZ ), w( iW ) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::Vector4f::Vector4f( CGstateassignment cgStateAssignment ) : x( 0.0f ), y( 0.0f ), z( 0.0f ), w( 0.0f ) + { + int nValsDummy[1]; + const float * values; + values = cgGetFloatStateAssignmentValues(cgStateAssignment, nValsDummy); + assert( nValsDummy[0] == 4 ); + + x = values[0]; + y = values[1]; + z = values[2]; + w = values[3]; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgStateListener::CgStateListener(CGtype cgType) + : mCgState(0), + mCgType(cgType), + mCgContext(CgFxScriptLoader::getSingleton().getCgContext()) + + + { + } + //--------------------------------------------------------------------- + CgFxScriptLoader::CgStateListener::~CgStateListener() + { + + } + //--------------------------------------------------------------------- + CGbool CgFxScriptLoader::CgStateListener::cgCallBackSet( const CGstateassignment cgStateAssignment ) + { + return CG_TRUE; + } + //--------------------------------------------------------------------- + CGbool CgFxScriptLoader::CgStateListener::cgCallBackReset( CGstateassignment cgStateAssignment ) + { + return CG_TRUE; + } + //--------------------------------------------------------------------- + CGbool CgFxScriptLoader::CgStateListener::cgCallBackValidate( CGstateassignment cgStateAssignment ) + { + return CG_TRUE; + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStateListener::init() + { + createState(); + checkForCgError("CgFxScriptLoader::CgStateListener::init", + "Unable to Set create State: ", mCgContext); + + cgSetStateCallbacks( mCgState, getCgCallBackSet(), getCgCallBackReset(), getCgCallBackValidate() ); + checkForCgError("CgFxScriptLoader::CgStateListener::init", + "Unable to Set State Callbacks: ", mCgContext); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStateListener::addStateEnumerant( int value, const char *name ) + { + cgAddStateEnumerant(mCgState, name, value); + + checkForCgError("CgFxScriptLoader::CgMinFilterSamplerStateListener::createState", + "Unable to Add State Enumerants: ", mCgContext); + + } + //--------------------------------------------------------------------- + CGstatecallback CgFxScriptLoader::CgStateListener::getCgCallBackSet() + { + return cgCallBackSet; + } + //--------------------------------------------------------------------- + CGstatecallback CgFxScriptLoader::CgStateListener::getCgCallBackReset() + { + return cgCallBackReset; + } + //--------------------------------------------------------------------- + CGstatecallback CgFxScriptLoader::CgStateListener::getCgCallBackValidate() + { + return cgCallBackValidate; + } + //--------------------------------------------------------------------- + CGstate CgFxScriptLoader::CgStateListener::getCgState() const + { + return mCgState; + } + //--------------------------------------------------------------------- + CGparameter CgFxScriptLoader::CgStateListener::getCgParameter( CGstateassignment cgStateAssignment ) + { + return cgGetTextureStateAssignmentValue(cgStateAssignment); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgGlobalStateListener::CgGlobalStateListener( const GlobalStateType globalStateType, CGtype cgType ) + : CgStateListener(cgType), + mGlobalStateType(globalStateType) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::CgGlobalStateListener::~CgGlobalStateListener() + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgGlobalStateListener::createState() + { + const char * typeNameAsString = CgFxScriptLoader::getSingleton().getGlobalStateNameTypeToString(mGlobalStateType); + mCgState = cgCreateState( mCgContext, typeNameAsString, mCgType ); + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + // todo - error + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgBoolGlobalStateListener::CgBoolGlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_BOOL) + { + + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector1b CgFxScriptLoader::CgBoolGlobalStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector1b(cgStateAssignment); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBoolGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + const bool value = getValue(cgStateAssignment); + switch( mGlobalStateType ) + { + case GST_ALPHABLENDENABLE: + break; + case GST_COLORVERTEX: + break; + case GST_DEPTHMASK: + break; + case GST_ZWRITEENABLE: + break; + case GST_INDEXEDVERTEXBLENDENABLE: + break; + case GST_LIGHTINGENABLE: + break; + case GST_LIGHTENABLE: + case GST_LIGHTING: + ogrePass->setLightingEnabled(value); + break; + case GST_LOCALVIEWER: + break; + case GST_MULTISAMPLEANTIALIAS: + break; + case GST_POINTSCALEENABLE: + break; + case GST_RANGEFOGENABLE: + break; + case GST_SPECULARENABLE: + break; + case GST_CLIPPING: + break; + case GST_POINTSPRITECOORDREPLACE: + break; + case GST_LASTPIXEL: + break; + case GST_TEXTURE1DENABLE: + break; + case GST_TEXTURE2DENABLE: + break; + case GST_TEXTURE3DENABLE: + break; + case GST_TEXTURERECTANGLEENABLE: + break; + case GST_TEXTURECUBEMAPENABLE: + break; + case GST_ALPHATESTENABLE: + break; + case GST_AUTONORMALENABLE: + break; + case GST_BLENDENABLE: + break; + case GST_COLORLOGICOPENABLE: + break; + case GST_CULLFACEENABLE: + break; + case GST_DEPTHBOUNDSENABLE: + break; + case GST_DEPTHCLAMPENABLE: + break; + case GST_DEPTHTESTENABLE: + break; + case GST_ZENABLE: + ogrePass->setDepthCheckEnabled(value); + break; + case GST_DITHERENABLE: + break; + case GST_FOGENABLE: + break; + case GST_LIGHTMODELLOCALVIEWERENABLE: + break; + case GST_LIGHTMODELTWOSIDEENABLE: + break; + case GST_LINESMOOTHENABLE: + break; + case GST_LINESTIPPLEENABLE: + break; + case GST_LOGICOPENABLE: + break; + case GST_MULTISAMPLEENABLE: + break; + case GST_NORMALIZEENABLE: + break; + case GST_NORMALIZENORMALS: + break; + case GST_POINTSMOOTHENABLE: + break; + case GST_POINTSPRITEENABLE: + break; + case GST_POLYGONOFFSETFILLENABLE: + break; + case GST_POLYGONOFFSETLINEENABLE: + break; + case GST_POLYGONOFFSETPOINTENABLE: + break; + case GST_POLYGONSMOOTHENABLE: + break; + case GST_POLYGONSTIPPLEENABLE: + break; + case GST_RESCALENORMALENABLE: + break; + case GST_SAMPLEALPHATOCOVERAGEENABLE: + break; + case GST_SAMPLEALPHATOONEENABLE: + break; + case GST_SAMPLECOVERAGEENABLE: + break; + case GST_SCISSORTESTENABLE: + break; + case GST_STENCILTESTENABLE: + break; + case GST_STENCILENABLE: + break; + case GST_STENCILTESTTWOSIDEENABLE: + break; + case GST_TEXGENSENABLE: + break; + case GST_TEXGENTENABLE: + break; + case GST_TEXGENRENABLE: + break; + case GST_TEXGENQENABLE: + break; + case GST_TWOSIDEDSTENCILMODE: + break; + case GST_SEPARATEALPHABLENDENABLE: + break; + case GST_VERTEXPROGRAMPOINTSIZEENABLE: + break; + case GST_VERTEXPROGRAMTWOSIDEENABLE: + break; + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgBool4GlobalStateListener::CgBool4GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_BOOL4) + { + + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector4b CgFxScriptLoader::CgBool4GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector4b( cgStateAssignment ); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBool4GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_COLORWRITEENABLE: + case GST_COLORMASK: + case GST_PIXELSHADERCONSTANTB: + case GST_VERTEXSHADERCONSTANTB: + case GST_COLORWRITEENABLE1: + case GST_COLORWRITEENABLE2: + case GST_COLORWRITEENABLE3: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFloatGlobalStateListener::CgFloatGlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_FLOAT) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFloatGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_ALPHAREF: + case GST_CLEARDEPTH: + case GST_DEPTHBIAS: + case GST_FOGDENSITY: + case GST_FOGSTART: + case GST_FOGEND: + case GST_LIGHTCONSTANTATTENUATION: + case GST_LIGHTATTENUATION0: + case GST_LIGHTLINEARATTENUATION: + case GST_LIGHTATTENUATION1: + case GST_LIGHTQUADRATICATTENUATION: + case GST_LIGHTATTENUATION2: + case GST_LIGHTSPOTCUTOFF: + case GST_LIGHTFALLOFF: + case GST_LIGHTPHI: + case GST_LIGHTRANGE: + case GST_LIGHTTHETA: + case GST_PATCHSEGMENTS: + case GST_POINTSCALE_A: + case GST_POINTSCALE_B: + case GST_POINTSCALE_C: + case GST_TWEENFACTOR: + case GST_LINEWIDTH: + case GST_MATERIALSHININESS: + case GST_MATERIALPOWER: + case GST_POINTFADETHRESHOLDSIZE: + case GST_POINTSIZE: + case GST_POINTSIZEMIN: + case GST_POINTSIZEMAX: + case GST_SLOPSCALEDEPTHBIAS: + case GST_BUMPENVLSCALE: + case GST_BUMPENVLOFFSET: + case GST_BUMPENVMAT00: + case GST_BUMPENVMAT01: + case GST_BUMPENVMAT10: + case GST_BUMPENVMAT11: + case GST_LIGHTSPOTEXPONENT: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector1f CgFxScriptLoader::CgFloatGlobalStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector1f( cgStateAssignment ); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFloat2GlobalStateListener::CgFloat2GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_FLOAT2) + { + + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector2f CgFxScriptLoader::CgFloat2GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector2f( cgStateAssignment ); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFloat2GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_DEPTHBOUNDS: + case GST_DEPTHRANGE: + case GST_POLYGONOFFSET: + case GST_MAXANISOTROPY: + case GST_MAXMIPLEVEL: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFloat3GlobalStateListener::CgFloat3GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_FLOAT3) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFloat3GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_POINTDISTANCEATTENUATION: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector3f CgFxScriptLoader::CgFloat3GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector3f( cgStateAssignment ); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFloat4GlobalStateListener::CgFloat4GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_FLOAT4) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFloat4GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_BLENDCOLOR: + case GST_CLEARCOLOR: + case GST_CLIPPLANE: + case GST_FOGCOLOR: + case GST_FRAGMENTENVPARAMETER: + case GST_FRAGMENTLOCALPARAMETER: + case GST_LIGHTMODELAMBIENT: + case GST_AMBIENT: + case GST_LIGHTAMBIENT: + case GST_LIGHTDIFFUSE: + case GST_LIGHTPOSITION: + case GST_LIGHTSPECULAR: + case GST_LIGHTSPOTDIRECTION: + case GST_LIGHTDIRECTION: + case GST_MATERIALAMBIENT: + case GST_MATERIALDIFFUSE: + case GST_MATERIALEMISSION: + case GST_MATERIALEMISSIVE: + case GST_MATERIALSPECULAR: + case GST_TEXGENSOBJECTPLANE: + case GST_TEXGENSEYEPLANE: + case GST_TEXGENTOBJECTPLANE: + case GST_TEXGENTEYEPLANE: + case GST_TEXGENROBJECTPLANE: + case GST_TEXGENREYEPLANE: + case GST_TEXGENQOBJECTPLANE: + case GST_TEXGENQEYEPLANE: + case GST_TEXTUREENVCOLOR: + case GST_VERTEXENVPARAMETER: + case GST_VERTEXLOCALPARAMETER: + case GST_PIXELSHADERCONSTANT1: + case GST_VERTEXSHADERCONSTANT1: + case GST_PIXELSHADERCONSTANTF: + case GST_VERTEXSHADERCONSTANTF: + case GST_BORDERCOLOR: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector4f CgFxScriptLoader::CgFloat4GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector4f( cgStateAssignment ); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFloat4x2GlobalStateListener::CgFloat4x2GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_FLOAT4x2) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFloat4x2GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_PIXELSHADERCONSTANT2: + case GST_VERTEXSHADERCONSTANT2: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFloat4x3GlobalStateListener::CgFloat4x3GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_FLOAT4x3) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFloat4x3GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_PIXELSHADERCONSTANT3: + case GST_VERTEXSHADERCONSTANT3: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFloat4x4GlobalStateListener::CgFloat4x4GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_FLOAT4x4) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFloat4x4GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_COLORMATRIX: + case GST_COLORTRANSFORM: + case GST_MODELVIEWMATRIX: + case GST_MODELVIEWTRANSFORM: + case GST_VIEWTRANSFORM: + case GST_WORLDTRANSFORM: + case GST_PROJECTIONMATRIX: + case GST_PROJECTIONTRANSFORM: + case GST_TEXTURETRANSFORM: + case GST_TEXTUREMATRIX: + case GST_PIXELSHADERCONSTANT: + case GST_VERTEXSHADERCONSTANT: + case GST_PIXELSHADERCONSTANT4: + case GST_VERTEXSHADERCONSTANT4: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgIntGlobalStateListener::CgIntGlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_INT) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgIntGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_BLENDOP: + case GST_CLEARSTENCIL: + case GST_CLIPPLANEENABLE: + case GST_CULLMODE: + case GST_ZFUNC: + case GST_FOGTABLEMODE: + case GST_FOGVERTEXMODE: + case GST_LIGHTTYPE: + case GST_MULTISAMPLEMASK: + case GST_AMBIENTMATERIALSOURCE: + case GST_DIFFUSEMATERIALSOURCE: + case GST_EMISSIVEMATERIALSOURCE: + case GST_SPECULARMATERIALSOURCE: + case GST_VERTEXBLEND: + case GST_DESTBLEND: + case GST_SRCBLEND: + case GST_STENCILMASK: + case GST_STENCILPASS: + case GST_STENCILREF: + case GST_STENCILWRITEMASK: + case GST_STENCILZFAIL: + case GST_TEXTUREFACTOR: + case GST_STENCILFAIL: + case GST_WRAP0: + case GST_WRAP1: + case GST_WRAP2: + case GST_WRAP3: + case GST_WRAP4: + case GST_WRAP5: + case GST_WRAP6: + case GST_WRAP7: + case GST_WRAP8: + case GST_WRAP9: + case GST_WRAP10: + case GST_WRAP11: + case GST_WRAP12: + case GST_WRAP13: + case GST_WRAP14: + case GST_WRAP15: + case GST_ADDRESSU: + case GST_ADDRESSV: + case GST_ADDRESSW: + case GST_MIPMAPLODBIAS: + case GST_BLENDOPALPHA: + case GST_SRCBLENDALPHA: + case GST_DESTBLENDALPHA: + case GST_ALPHAOP: + case GST_COLOROP: + case GST_ALPHAARG0: + case GST_ALPHAARG1: + case GST_ALPHAARG2: + case GST_COLORARG0: + case GST_COLORARG1: + case GST_COLORARG2: + case GST_RESULTARG: + case GST_TEXCOORDINDEX: + case GST_TEXTURETRANSFORMFLAGS: + case GST_MIPFILTER: // todo + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector1i CgFxScriptLoader::CgIntGlobalStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector1i(cgStateAssignment); + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgInt2GlobalStateListener::CgInt2GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_INT2) + { + + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector2i CgFxScriptLoader::CgInt2GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector2i(cgStateAssignment); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgInt2GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_LINESTIPPLE: + case GST_FILLMODE: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgInt3GlobalStateListener::CgInt3GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_INT3) + { + + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector3i CgFxScriptLoader::CgInt3GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector3i(cgStateAssignment); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgInt3GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + // todo - error + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgInt4GlobalStateListener::CgInt4GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_INT4) + { + + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector4i CgFxScriptLoader::CgInt4GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector4i(cgStateAssignment); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgInt4GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_SCISSOR: + case GST_PIXELSHADERCONSTANTI: + case GST_VERTEXSHADERCONSTANTI: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgSamplerGlobalStateListener::CgSamplerGlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_SAMPLER) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgSamplerGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_SAMPLER: + case GST_TEXTURE1D: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgSampler2GlobalStateListener::CgSampler2GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_SAMPLER2D) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgSampler2GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_TEXTURE2D: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgSampler3GlobalStateListener::CgSampler3GlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener( globalStateType, CG_SAMPLER3D ) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgSampler3GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_TEXTURE3D: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgSamplerCubeGlobalStateListener::CgSamplerCubeGlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_SAMPLERCUBE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgSamplerCubeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_TEXTURECUBEMAP: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgSamplerRectGlobalStateListener::CgSamplerRectGlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_SAMPLERRECT) + { + + } + + void CgFxScriptLoader::CgSamplerRectGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_TEXTURERECTANGLE: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgTextureGlobalStateListener::CgTextureGlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_TEXTURE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgTextureGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_TEXTURE: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgProgramGlobalStateListener::CgProgramGlobalStateListener( const GlobalStateType globalStateType ) + : CgGlobalStateListener(globalStateType, CG_PROGRAM_TYPE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgProgramGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( mGlobalStateType ) + { + case GST_GEOMETRYPROGRAM: + case GST_VERTEXPROGRAM: + case GST_VERTEXSHADER: + case GST_FRAGMENTPROGRAM: + case GST_PIXELSHADER: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgBlendEquationGlobalStateListener::CgBlendEquationGlobalStateListener() + : CgIntGlobalStateListener(GST_BLENDEQUATION) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBlendEquationGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)BET_FUNCADD , "FuncAdd"); + addStateEnumerant((int)BET_FUNCSUBTRACT , "FuncSubtract"); + addStateEnumerant((int)BET_MIN , "Min"); + addStateEnumerant((int)BET_MAX , "Max"); + addStateEnumerant((int)BET_LOGICOP ,"LogicOp"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBlendEquationGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case BET_FUNCADD: // FuncAdd + case BET_FUNCSUBTRACT: // FuncSubtract + case BET_MIN: // Min + case BET_MAX: // Max + case BET_LOGICOP: // LogicOp + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgDepthFuncGlobalStateListener::CgDepthFuncGlobalStateListener() + : CgIntGlobalStateListener(GST_DEPTHFUNC) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgDepthFuncGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)DFT_NEVER , "Never"); + addStateEnumerant((int)DFT_LESS , "Less"); + addStateEnumerant((int)DFT_LEQUAL , "LEqual"); + addStateEnumerant((int)DFT_EQUAL , "Equal"); + addStateEnumerant((int)DFT_GREATER , "Greater"); + addStateEnumerant((int)DFT_NOTEQUAL , "NotEqual"); + addStateEnumerant((int)DFT_GEQUAL , "GEqual"); + addStateEnumerant((int)DFT_ALWAYS , "Always"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgDepthFuncGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case DFT_NEVER: // Never + case DFT_LESS: // Less + case DFT_LEQUAL: // LEqual + case DFT_EQUAL: // Equal + case DFT_GREATER: // Greater + case DFT_NOTEQUAL: // NotEqual + case DFT_GEQUAL: // GEqual + case DFT_ALWAYS : // Always + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFogDistanceModeGlobalStateListener::CgFogDistanceModeGlobalStateListener() + : CgIntGlobalStateListener(GST_FOGDISTANCEMODE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFogDistanceModeGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)FDMT_EYERADIAL , "EyeRadial"); + addStateEnumerant((int)FDMT_EYEPLANE , "EyePlane"); + addStateEnumerant((int)FDMT_EYEPLANEABSOLUTE , "EyePlaneAbsolute"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFogDistanceModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case FDMT_EYERADIAL: // EyeRadial + case FDMT_EYEPLANE: // EyePlane + case FDMT_EYEPLANEABSOLUTE: // EyePlaneAbsolute + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFogModeGlobalStateListener::CgFogModeGlobalStateListener() + : CgIntGlobalStateListener(GST_FOGMODE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFogModeGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)FMT_LINEAR , "Linear"); + addStateEnumerant((int)FMT_EXP , "Exp"); + addStateEnumerant((int)FMT_EXP2 , "Exp2"); + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFogModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case FMT_LINEAR: // Linear + case FMT_EXP: // Exp + case FMT_EXP2: // Exp2 + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgLightModelColorControlGlobalStateListener::CgLightModelColorControlGlobalStateListener() + : CgIntGlobalStateListener(GST_LIGHTMODELCOLORCONTROL) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgLightModelColorControlGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)LMCCT_SINGLECOLOR , "SingleColor"); + addStateEnumerant((int)LMCCT_SEPARATESPECULAR , "SeparateSpecular"); + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgLightModelColorControlGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case LMCCT_SINGLECOLOR: // SingleColor + case LMCCT_SEPARATESPECULAR: // SeparateSpecular + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgLogicOpGlobalStateListener::CgLogicOpGlobalStateListener() + : CgIntGlobalStateListener(GST_LOGICOP) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgLogicOpGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)LOT_CLEAR , "Clear"); + addStateEnumerant((int)LOT_AND , "And"); + addStateEnumerant((int)LOT_ANDREVERSE , "AndReverse"); + addStateEnumerant((int)LOT_COPY , "Copy"); + addStateEnumerant((int)LOT_ANDINVERTED , "AndInverted"); + addStateEnumerant((int)LOT_NOOP , "Noop"); + addStateEnumerant((int)LOT_XOR , "Xor"); + addStateEnumerant((int)LOT_OR , "Or"); + addStateEnumerant((int)LOT_NOR , "Nor"); + addStateEnumerant((int)LOT_EQUIV , "Equiv"); + addStateEnumerant((int)LOT_INVERT , "Invert"); + addStateEnumerant((int)LOT_ORREVERSE , "OrReverse"); + addStateEnumerant((int)LOT_COPYINVERTED , "CopyInverted"); + addStateEnumerant((int)LOT_NAND , "Nand"); + addStateEnumerant((int)LOT_SET , "Set"); + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgLogicOpGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case LOT_CLEAR: // Clear + case LOT_AND: // And + case LOT_ANDREVERSE: // AndReverse + case LOT_COPY: // Copy + case LOT_ANDINVERTED: // AndInverted + case LOT_NOOP: // Noop + case LOT_XOR: // Xor + case LOT_OR: // Or, + case LOT_NOR: // Nor + case LOT_EQUIV: // Equiv + case LOT_INVERT: // Invert + case LOT_ORREVERSE: // OrReverse + case LOT_COPYINVERTED: // CopyInverted + case LOT_NAND: // Nand + case LOT_SET: // Set + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgPointSpriteCoordOriginGlobalStateListener::CgPointSpriteCoordOriginGlobalStateListener() + : CgIntGlobalStateListener(GST_POINTSPRITECOORDORIGIN) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgPointSpriteCoordOriginGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)PSCOT_LOWERLEFT , "LowerLeft"); + addStateEnumerant((int)PSCOT_UPPERLEFT , "UpperLeft"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgPointSpriteCoordOriginGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case PSCOT_LOWERLEFT: // LowerLeft + case PSCOT_UPPERLEFT: // UpperLeft + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgPointSpriteRModeGlobalStateListener::CgPointSpriteRModeGlobalStateListener() + : CgIntGlobalStateListener(GST_POINTSPRITERMODE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgPointSpriteRModeGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)PSRMT_ZERO , "Zero"); + addStateEnumerant((int)PSRMT_R , "R"); + addStateEnumerant((int)PSRMT_S , "S"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgPointSpriteRModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case PSRMT_ZERO: // Zero + case PSRMT_R: // R + case PSRMT_S: // S + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + + CgFxScriptLoader::CgShadeModelGlobalStateListener::CgShadeModelGlobalStateListener() + : CgIntGlobalStateListener(GST_SHADEMODEL) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgShadeModelGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)SMT_FLAT , "Flat"); + addStateEnumerant((int)SMT_SMOOTH , "Smooth"); + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgShadeModelGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case SMT_FLAT: // Flat + case SMT_SMOOTH: // Smooth + default: + // todo - error + break; + } + + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgTexGenModeGlobalStateListener::CgTexGenModeGlobalStateListener(const GlobalStateType globalStateType) + : CgIntGlobalStateListener(globalStateType) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgTexGenModeGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)TGMT_OBJECTLINEAR, "ObjectLinear"); + addStateEnumerant((int)TGMT_EYELINEAR, "EyeLinear"); + addStateEnumerant((int)TGMT_SPHEREMAP, "SphereMap"); + addStateEnumerant((int)TGMT_REFLECTIONMAP, "ReflectionMap"); + addStateEnumerant((int)TGMT_NORMALMAP, "NormalMap"); + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgTexGenModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case TGMT_OBJECTLINEAR: // ObjectLinear + case TGMT_EYELINEAR: // EyeLinear + case TGMT_SPHEREMAP: // SphereMap + case TGMT_REFLECTIONMAP: // ReflectionMap + case TGMT_NORMALMAP: // NormalMap + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgTextureEnvModeGlobalStateListener::CgTextureEnvModeGlobalStateListener() + : CgIntGlobalStateListener(GST_TEXTUREENVMODE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgTextureEnvModeGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)BET_MODULATE, "Modulate"); + addStateEnumerant((int)BET_DECAL, "Decal"); + addStateEnumerant((int)BET_BLEND, "Blend"); + addStateEnumerant((int)BET_REPLACE, "Replace"); + addStateEnumerant((int)BET_ADD, "Add"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgTextureEnvModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case BET_MODULATE: // Modulate + case BET_DECAL: // Decal + case BET_BLEND: // Blend + case BET_REPLACE: // Replace + case BET_ADD: // Add + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgMinFilterGlobalStateListener::CgMinFilterGlobalStateListener() + : CgIntGlobalStateListener(GST_MINFILTER) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgMinFilterGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)MFT_NEAREST, "Nearest"); + addStateEnumerant((int)MFT_LINEAR, "Linear"); + addStateEnumerant((int)MFT_LINEARMIPMAPNEAREST, "LinearMipMapNearest"); + addStateEnumerant((int)MFT_NEARESTMIPMAPNEAREST, "NearestMipMapNearest"); + addStateEnumerant((int)MFT_NEARESTMIPMAPLINEAR, "NearestMipMapLinear"); + addStateEnumerant((int)MFT_LINEARMIPMAPLINEAR, "LinearMipMapLinear"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgMinFilterGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case MFT_NEAREST: // Nearest + case MFT_LINEAR: // Linear + case MFT_LINEARMIPMAPNEAREST: // LinearMipMapNearest + case MFT_NEARESTMIPMAPNEAREST: // NearestMipMapNearest + case MFT_NEARESTMIPMAPLINEAR: // NearestMipMapLinear + case MFT_LINEARMIPMAPLINEAR: // LinearMipMapLinear + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgMagFilterGlobalStateListener::CgMagFilterGlobalStateListener() + : CgIntGlobalStateListener(GST_MAGFILTER) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgMagFilterGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)MFT_NEAREST, "Nearest"); + addStateEnumerant((int)MFT_LINEAR, "Linear"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgMagFilterGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case MFT_NEAREST: // Nearest + case MFT_LINEAR: // Linear + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFrontFaceGlobalStateListener::CgFrontFaceGlobalStateListener() + : CgIntGlobalStateListener(GST_FRONTFACE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFrontFaceGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)FFT_CW, "CW"); + addStateEnumerant((int)FFT_CCW, "CCW"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFrontFaceGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case FFT_CW: // CW + case FFT_CCW: // CCW + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgCullFaceGlobalStateListener::CgCullFaceGlobalStateListener() + : CgIntGlobalStateListener(GST_CULLFACE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgCullFaceGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)CFT_FRONT, "Front"); + addStateEnumerant((int)CFT_BACK, "Back"); + addStateEnumerant((int)CFT_FRONTANDBACK, "FrontAndBack"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgCullFaceGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case CFT_FRONT: // Front + case CFT_BACK: // Back + case CFT_FRONTANDBACK: // FrontAndBack + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFogCoordSrcGlobalStateListener::CgFogCoordSrcGlobalStateListener() + : CgIntGlobalStateListener(GST_FOGCOORDSRC) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFogCoordSrcGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)FCST_FRAGMENTDEPTH, "FragmentDepth"); + addStateEnumerant((int)FCST_FOGCOORD, "FogCoord"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFogCoordSrcGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case FCST_FRAGMENTDEPTH: // FragmentDepth + case FCST_FOGCOORD: // FogCoord + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgAlphaFuncGlobalStateListener::CgAlphaFuncGlobalStateListener() + : CgFloat2GlobalStateListener(GST_ALPHAFUNC) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgAlphaFuncGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)AFT_NEVER, "Never"); + addStateEnumerant((int)AFT_LESS, "Less"); + addStateEnumerant((int)AFT_LEQUAL, "LEqual"); + addStateEnumerant((int)AFT_EQUAL, "Equal"); + addStateEnumerant((int)AFT_GREATER, "Greater"); + addStateEnumerant((int)AFT_NOTEQUAL, "NotEqual"); + addStateEnumerant((int)AFT_GEQUAL, "GEqual"); + addStateEnumerant((int)AFT_ALWAYS, "Always"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgAlphaFuncGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( static_cast(getValue(cgStateAssignment).x) ) + { + case AFT_NEVER: // Never + case AFT_LESS: // Less + case AFT_LEQUAL: // LEqual + case AFT_EQUAL: // Equal + case AFT_GREATER: // Greater + case AFT_NOTEQUAL: // NotEqual + case AFT_GEQUAL: // GEqual + case AFT_ALWAYS: // Always + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgBlendFuncGlobalStateListener::CgBlendFuncGlobalStateListener() + : CgInt2GlobalStateListener(GST_BLENDFUNC) + { + + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBlendFuncGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)BF_ZERO, "Zero"); + addStateEnumerant((int)BF_ONE, "One"); + addStateEnumerant((int)BF_DESTCOLOR, "DestColor"); + addStateEnumerant((int)BF_ONEMINUSDESTCOLOR, "OneMinusDestColor"); + addStateEnumerant((int)BF_SRCALPHA, "SrcAlpha"); + addStateEnumerant((int)BF_ONEMINUSSRCALPHA, "OneMinusSrcAlpha"); + addStateEnumerant((int)BF_DSTALPHA, "DstAlpha"); + addStateEnumerant((int)BF_ONEMINUSDSTALPHA, "OneMinusDstAlpha"); + addStateEnumerant((int)BF_SRCALPHASATURATE, "SrcAlphaSaturate"); + addStateEnumerant((int)BF_SRCCOLOR, "SrcColor"); + addStateEnumerant((int)BF_ONEMINUSSRCCOLOR, "OneMinusSrcColor"); + addStateEnumerant((int)BF_CONSTANTCOLOR, "ConstantColor"); + addStateEnumerant((int)BF_ONEMINUSCONSTANTCOLOR, "OneMinusConstantColor"); + addStateEnumerant((int)BF_CONSTANTALPHA, "ConstantAlpha"); + addStateEnumerant((int)BF_ONEMINUSCONSTANTALPHA, "OneMinusConstantAlpha"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBlendFuncGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment).x ) + { + case BF_ZERO: // Zero + case BF_ONE: // One + case BF_DESTCOLOR: // DestColor + case BF_ONEMINUSDESTCOLOR: // OneMinusDestColor + case BF_SRCALPHA: // SrcAlpha + case BF_ONEMINUSSRCALPHA: // OneMinusSrcAlpha + case BF_DSTALPHA: // DstAlpha + case BF_ONEMINUSDSTALPHA: // OneMinusDstAlpha + case BF_SRCALPHASATURATE: // SrcAlphaSaturate + case BF_SRCCOLOR: // SrcColor + case BF_ONEMINUSSRCCOLOR: // OneMinusSrcColor + case BF_CONSTANTCOLOR: // ConstantColor + case BF_ONEMINUSCONSTANTCOLOR: // OneMinusConstantColor + case BF_CONSTANTALPHA: // ConstantAlpha + case BF_ONEMINUSCONSTANTALPHA: // OneMinusConstantAlpha + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgBlendFuncSeparateGlobalStateListener::CgBlendFuncSeparateGlobalStateListener() + : CgInt4GlobalStateListener(GST_BLENDFUNCSEPARATE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBlendFuncSeparateGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)BFST_ZERO, "Zero"); + addStateEnumerant((int)BFST_ONE, "One"); + addStateEnumerant((int)BFST_DESTCOLOR, "DestColor"); + addStateEnumerant((int)BFST_ONEMINUSDESTCOLOR, "OneMinusDestColor"); + addStateEnumerant((int)BFST_SRCALPHA, "SrcAlpha"); + addStateEnumerant((int)BFST_ONEMINUSSRCALPHA, "OneMinusSrcAlpha"); + addStateEnumerant((int)BFST_DSTALPHA, "DstAlpha"); + addStateEnumerant((int)BFST_ONEMINUSDSTALPHA, "OneMinusDstAlpha"); + addStateEnumerant((int)BFST_SRCALPHASATURATE, "SrcAlphaSaturate"); + addStateEnumerant((int)BFST_SRCCOLOR, "SrcColor"); + addStateEnumerant((int)BFST_ONEMINUSSRCCOLOR, "OneMinusSrcColor"); + addStateEnumerant((int)BFST_CONSTANTCOLOR, "ConstantColor"); + addStateEnumerant((int)BFST_ONEMINUSCONSTANTCOLOR, "OneMinusConstantColor"); + addStateEnumerant((int)BFST_CONSTANTALPHA, "ConstantAlpha"); + addStateEnumerant((int)BFST_ONEMINUSCONSTANTALPHA, "OneMinusConstantAlpha"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBlendFuncSeparateGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment).x ) + { + case BFST_ZERO: // Zero + case BFST_ONE: // One + case BFST_DESTCOLOR: // DestColor + case BFST_ONEMINUSDESTCOLOR: // OneMinusDestColor + case BFST_SRCALPHA: // SrcAlpha + case BFST_ONEMINUSSRCALPHA: // OneMinusSrcAlpha + case BFST_DSTALPHA: // DstAlpha + case BFST_ONEMINUSDSTALPHA: // OneMinusDstAlpha + case BFST_SRCALPHASATURATE: // SrcAlphaSaturate + case BFST_SRCCOLOR: // SrcColor + case BFST_ONEMINUSSRCCOLOR: // OneMinusSrcColor + case BFST_CONSTANTCOLOR: // ConstantColor + case BFST_ONEMINUSCONSTANTCOLOR: // OneMinusConstantColor + case BFST_CONSTANTALPHA: // ConstantAlpha + case BFST_ONEMINUSCONSTANTALPHA: // OneMinusConstantAlpha + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgBlendEquationSeparateGlobalStateListener::CgBlendEquationSeparateGlobalStateListener() + : CgInt2GlobalStateListener(GST_BLENDEQUATIONSEPARATE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBlendEquationSeparateGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)BEST_FUNCADD, "FuncAdd"); + addStateEnumerant((int)BEST_FUNCSUBTRACT, "FuncSubtract"); + addStateEnumerant((int)BEST_MIN, "Min"); + addStateEnumerant((int)BEST_MAX, "Max"); + addStateEnumerant((int)BEST_LOGICOP, "LogicOp"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBlendEquationSeparateGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment).x ) + { + case BEST_FUNCADD: // FuncAdd + case BEST_FUNCSUBTRACT: // FuncSubtract + case BEST_MIN: // Min + case BEST_MAX: // Max + case BEST_LOGICOP: // LogicOp + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgColorMaterialGlobalStateListener::CgColorMaterialGlobalStateListener() + : CgInt2GlobalStateListener(GST_COLORMATERIAL) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgColorMaterialGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)CMT_FRONT, "Front"); + addStateEnumerant((int)CMT_BACK, "Back"); + addStateEnumerant((int)CMT_FRONTANDBACK, "FrontAndBack"); + addStateEnumerant((int)CMT_EMISSION, "Emission"); + addStateEnumerant((int)CMT_AMBIENT, "Ambient"); + addStateEnumerant((int)CMT_DIFFUSE, "Diffuse"); + addStateEnumerant((int)CMT_SPECULAR, "Specular"); + addStateEnumerant((int)CMT_AMBIENTANDDIFFUSE, "AmbientAndDiffuse"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgColorMaterialGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment).x ) + { + case CMT_FRONT: // Front + case CMT_BACK: // Back + case CMT_FRONTANDBACK: // FrontAndBack + case CMT_EMISSION: // Emission + case CMT_AMBIENT: // Ambient + case CMT_DIFFUSE: // Diffuse + case CMT_SPECULAR: // Specular + case CMT_AMBIENTANDDIFFUSE: // AmbientAndDiffuse + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgPolygonModeGlobalStateListener::CgPolygonModeGlobalStateListener() + : CgInt2GlobalStateListener(GST_POLYGONMODE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgPolygonModeGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + + addStateEnumerant((int)PMT_FRONT, "Front"); + addStateEnumerant((int)PMT_BACK, "Back"); + addStateEnumerant((int)PMT_FRONTANDBACK, "FrontAndBack"); + addStateEnumerant((int)PMT_POINT, "Point"); + addStateEnumerant((int)PMT_LINE, "Line"); + addStateEnumerant((int)PMT_FILL, "Fill"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgPolygonModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment).x ) + { + case PMT_FRONT: // Front + case PMT_BACK: // Back + case PMT_FRONTANDBACK: // FrontAndBack + case PMT_POINT: // Point + case PMT_LINE: // Line + case PMT_FILL: // Fill + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgStencilFuncGlobalStateListener::CgStencilFuncGlobalStateListener() + : CgInt3GlobalStateListener(GST_STENCILFUNC) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStencilFuncGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + addStateEnumerant((int)SFT_NEVER, "Never"); + addStateEnumerant((int)SFT_LESS, "Less"); + addStateEnumerant((int)SFT_LEQUAL, "LEqual"); + addStateEnumerant((int)SFT_EQUAL, "Equal"); + addStateEnumerant((int)SFT_GREATER, "Greater"); + addStateEnumerant((int)SFT_NOTEQUAL, "NotEqual"); + addStateEnumerant((int)SFT_GEQUAL, "GEqual"); + addStateEnumerant((int)SFT_ALWAYS, "Always"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStencilFuncGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment).x ) + { + case SFT_NEVER: // Never + case SFT_LESS: // Less + case SFT_LEQUAL: // LEqual + case SFT_EQUAL: // Equal + case SFT_GREATER: // Greater + case SFT_NOTEQUAL: // NotEqual + case SFT_GEQUAL: // GEqual + case SFT_ALWAYS: // Always + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgStencilOpGlobalStateListener::CgStencilOpGlobalStateListener() + : CgInt3GlobalStateListener(GST_STENCILOP) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStencilOpGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + addStateEnumerant((int)SOT_KEEP, "Keep"); + addStateEnumerant((int)SOT_ZERO, "Zero"); + addStateEnumerant((int)SOT_REPLACE, "Replace"); + addStateEnumerant((int)SOT_INCR, "Incr"); + addStateEnumerant((int)SOT_DECR, "Decr"); + addStateEnumerant((int)SOT_INVERT, "Invert"); + addStateEnumerant((int)SOT_INCRWRAP, "IncrWrap"); + addStateEnumerant((int)SOT_DECRWRAP, "DecrWrap"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStencilOpGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment).x ) + { + case SOT_KEEP: // Keep + case SOT_ZERO: // Zero + case SOT_REPLACE: // Replace + case SOT_INCR: // Incr + case SOT_DECR: // Decr + case SOT_INVERT: // Invert + case SOT_INCRWRAP: // IncrWrap + case SOT_DECRWRAP: // DecrWrap + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgStencilFuncSeparateGlobalStateListener::CgStencilFuncSeparateGlobalStateListener() + : CgInt4GlobalStateListener(GST_STENCILFUNCSEPARATE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStencilFuncSeparateGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + addStateEnumerant((int)SFST_FRONT, "Front"); + addStateEnumerant((int)SFST_BACK, "Back"); + addStateEnumerant((int)SFST_FRONTANDBACK, "FrontAndBack"); + addStateEnumerant((int)SFST_NEVER, "Never"); + addStateEnumerant((int)SFST_LESS, "Less"); + addStateEnumerant((int)SFST_LEQUAL, "LEqual"); + addStateEnumerant((int)SFST_EQUAL, "Equal"); + addStateEnumerant((int)SFST_GREATER, "Greater"); + addStateEnumerant((int)SFST_NOTEQUAL, "NotEqual"); + addStateEnumerant((int)SFST_GEQUAL, "GEqual"); + addStateEnumerant((int)SFST_ALWAYS, "Always"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStencilFuncSeparateGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment).x ) + { + case SFST_FRONT: // Front + case SFST_BACK: // Back + case SFST_FRONTANDBACK: // FrontAndBack + case SFST_NEVER: // Never + case SFST_LESS: // Less + case SFST_LEQUAL: // LEqual + case SFST_EQUAL: // Equal + case SFST_GREATER: // Greater + case SFST_NOTEQUAL: // NotEqual + case SFST_GEQUAL: // GEqual + case SFST_ALWAYS: // Always + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgStencilMaskSeparateGlobalStateListener::CgStencilMaskSeparateGlobalStateListener() + : CgInt2GlobalStateListener(GST_STENCILMASKSEPARATE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStencilMaskSeparateGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + addStateEnumerant((int)BET_FRONT, "Front"); + addStateEnumerant((int)BET_BACK, "Back"); + addStateEnumerant((int)BET_FRONTANDBACK, "FrontAndBack"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStencilMaskSeparateGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment).x ) + { + case BET_FRONT: // Front + case BET_BACK: // Back + case BET_FRONTANDBACK: // FrontAndBack + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgStencilOpSeparateGlobalStateListener::CgStencilOpSeparateGlobalStateListener() + : CgInt4GlobalStateListener(GST_STENCILOPSEPARATE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStencilOpSeparateGlobalStateListener::createState() + { + CgGlobalStateListener::createState(); + addStateEnumerant((int)BET_KEEP, "Keep"); + addStateEnumerant((int)BET_ZERO, "Zero"); + addStateEnumerant((int)BET_REPLACE, "Replace"); + addStateEnumerant((int)BET_INCR, "Incr"); + addStateEnumerant((int)BET_DECR, "Decr"); + addStateEnumerant((int)BET_INVERT, "Invert"); + addStateEnumerant((int)BET_INCRWRAP, "IncrWrap"); + addStateEnumerant((int)BET_DECRWRAP, "DecrWrap"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgStencilOpSeparateGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment).x ) + { + case BET_KEEP: // Keep + case BET_ZERO: // Zero + case BET_REPLACE: // Replace + case BET_INCR: // Incr + case BET_DECR: // Decr + case BET_INVERT: // Invert + case BET_INCRWRAP: // IncrWrap + case BET_DECRWRAP: // DecrWrap + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgSamplerStateListener::CgSamplerStateListener( SamplerStateType samplerStateType, CGtype cgType ) + :CgStateListener(cgType), + mSamplerStateType(samplerStateType) + { + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::CgSamplerStateListener::~CgSamplerStateListener() + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgSamplerStateListener::createState() + { + const char * typeNameAsString = CgFxScriptLoader::getSingleton().getSamplerStateNameTypeToString(mSamplerStateType); + mCgState = cgCreateSamplerState( mCgContext, typeNameAsString, mCgType ); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgIntSamplerStateListener::CgIntSamplerStateListener(const SamplerStateType samplerStateType) + : CgSamplerStateListener(samplerStateType, CG_INT) + { + + } + //--------------------------------------------------------------------- + const CgFxScriptLoader::Vector1i CgFxScriptLoader::CgIntSamplerStateListener::getValue( CGstateassignment cgStateAssignment ) + { + return Vector1i(cgStateAssignment); + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgIntSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + + // todo - error + + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgBoolSamplerStateListener::CgBoolSamplerStateListener( const SamplerStateType samplerStateType ) + : CgSamplerStateListener(samplerStateType, CG_BOOL) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgBoolSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + switch( mSamplerStateType ) + { + case SST_GENERATEMIPMAP: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFloatSamplerStateListener::CgFloatSamplerStateListener( const SamplerStateType samplerStateType ) + : CgSamplerStateListener(samplerStateType, CG_FLOAT) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFloatSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + switch( mSamplerStateType ) + { + case SST_MIPMAPLODBIAS: + case SST_LODBIAS: + case SST_MAXMIPLEVEL: + case SST_MAXANISOTROPY: + case SST_MINMIPLEVEL: + case SST_SRGBTEXTURE: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgFloat4SamplerStateListener::CgFloat4SamplerStateListener( const SamplerStateType samplerStateType ) + : CgSamplerStateListener(samplerStateType, CG_FLOAT4) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgFloat4SamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + switch( mSamplerStateType ) + { + case SST_BORDERCOLOR: + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgTextureSamplerStateListener::CgTextureSamplerStateListener( const SamplerStateType samplerStateType ) + : CgSamplerStateListener(samplerStateType, CG_TEXTURE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgTextureSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + parseTextureName(getCgParameter(cgStateAssignment), ogreTextureUnitState); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgTextureSamplerStateListener::parseTextureName( CGparameter cgParameter, TextureUnitState * ogreTextureUnitState ) + { + CGannotation cgAnnotation = cgGetNamedParameterAnnotation(cgParameter, "ResourceName"); + if (cgAnnotation && cgGetAnnotationType(cgAnnotation) == CG_STRING) + { + const char * textureName = cgGetStringAnnotationValue(cgAnnotation); + if (textureName) + { + ogreTextureUnitState->setTextureName(textureName, parseTextureType(cgParameter, ogreTextureUnitState)); + } + } + } + //--------------------------------------------------------------------- + TextureType CgFxScriptLoader::CgTextureSamplerStateListener::parseTextureType( CGparameter cgParameter, TextureUnitState * ogreTextureUnitState ) + { + CGannotation cgAnnotation = cgGetNamedParameterAnnotation(cgParameter, "ResourceType"); + if (cgAnnotation && cgGetAnnotationType(cgAnnotation) == CG_STRING) + { + String textureType = cgGetStringAnnotationValue(cgAnnotation); + StringUtil::toLowerCase(textureType); + if ("1d" == textureType) + { + return TEX_TYPE_1D; + } + if ("2d" == textureType) + { + return TEX_TYPE_2D; + } + if ("3d" == textureType) + { + return TEX_TYPE_3D; + } + if ("cube" == textureType) + { + return TEX_TYPE_CUBE_MAP; + } + } + return TEX_TYPE_2D; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgWrapSamplerStateListener::CgWrapSamplerStateListener( const SamplerStateType samplerStateType ) + : CgIntSamplerStateListener(samplerStateType) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgWrapSamplerStateListener::createState() + { + CgSamplerStateListener::createState(); + + addStateEnumerant((int)WT_REPEAT , "Repeat"); + addStateEnumerant((int)WT_CLAMP , "Clamp"); + addStateEnumerant((int)WT_CLAMPTOEDGE , "ClampToEdge"); + addStateEnumerant((int)WT_CLAMPTOBORDER , "ClampToBorder"); + addStateEnumerant((int)WT_MIRROREDREPEAT , "MirroredRepeat"); + addStateEnumerant((int)WT_MIRRORCLAMP , "MirrorClamp"); + addStateEnumerant((int)WT_MIRRORCLAMPTOEDGE , "MirrorClampToEdge"); + addStateEnumerant((int)WT_MIRRORCLAMPTOBORDER , "MirrorClampToBorder"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgWrapSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + TextureUnitState::TextureAddressingMode ogreTextureAddressingMode = TextureUnitState::TAM_WRAP; + ogreTextureAddressingMode = getOgreTextureAddressingMode(cgStateAssignment); + + TextureUnitState::UVWAddressingMode ogreUVWAddressingMode = ogreTextureUnitState->getTextureAddressingMode(); + + switch( mSamplerStateType ) + { + case SST_WRAPS: + ogreUVWAddressingMode.u = ogreTextureAddressingMode; + break; + case SST_WRAPT: + ogreUVWAddressingMode.v = ogreTextureAddressingMode; + break; + case SST_WRAPR: + ogreUVWAddressingMode.w = ogreTextureAddressingMode; + break; + default: + // todo - error + break; + } + ogreTextureUnitState->setTextureAddressingMode( ogreUVWAddressingMode ); + + } + //--------------------------------------------------------------------- + TextureUnitState::TextureAddressingMode CgFxScriptLoader::CgWrapSamplerStateListener::getOgreTextureAddressingMode( CGstateassignment cgStateAssignment ) + { + TextureUnitState::TextureAddressingMode ogreTextureAddressingMode = TextureUnitState::TAM_WRAP; + switch( getValue( cgStateAssignment ) ) + { + case WT_REPEAT: // Repeat + ogreTextureAddressingMode = TextureUnitState::TAM_WRAP; + break; + case WT_CLAMP: // Clamp + ogreTextureAddressingMode = TextureUnitState::TAM_CLAMP; + break; + case WT_CLAMPTOEDGE: // ClampToEdge + ogreTextureAddressingMode = TextureUnitState::TAM_CLAMP; + break; + case WT_CLAMPTOBORDER: // ClampToBorder + ogreTextureAddressingMode = TextureUnitState::TAM_BORDER; + break; + case WT_MIRROREDREPEAT: // MirroredRepeat + ogreTextureAddressingMode = TextureUnitState::TAM_MIRROR; + break; + case WT_MIRRORCLAMP: // MirrorClamp + ogreTextureAddressingMode = TextureUnitState::TAM_MIRROR; + break; + case WT_MIRRORCLAMPTOEDGE: // MirrorClampToEdge + ogreTextureAddressingMode = TextureUnitState::TAM_MIRROR; + break; + case WT_MIRRORCLAMPTOBORDER: // MirrorClampToBorder + ogreTextureAddressingMode = TextureUnitState::TAM_MIRROR; + break; + default: + // todo - error + ogreTextureAddressingMode = TextureUnitState::TAM_WRAP; + break; + } + return ogreTextureAddressingMode; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgCompareModeSamplerStateListener::CgCompareModeSamplerStateListener() + : CgIntSamplerStateListener(SST_COMPAREMODE) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgCompareModeSamplerStateListener::createState() + { + CgSamplerStateListener::createState(); + + addStateEnumerant((int)CMT_NONE , "None"); + addStateEnumerant((int)CMT_COMPARERTOTEXTURE , "CompareRToTexture"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgCompareModeSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case CMT_NONE: // None + case CMT_COMPARERTOTEXTURE: // CompareRToTexture + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgCompareFuncSamplerStateListener::CgCompareFuncSamplerStateListener( ) + : CgIntSamplerStateListener(SST_COMPAREFUNC) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgCompareFuncSamplerStateListener::createState() + { + CgSamplerStateListener::createState(); + + addStateEnumerant((int)CFT_NEVER , "Never"); + addStateEnumerant((int)CFT_LESS , "Less"); + addStateEnumerant((int)CFT_LEQUAL , "LEqual"); + addStateEnumerant((int)CFT_EQUAL , "Equal"); + addStateEnumerant((int)CFT_GREATER , "Greater"); + addStateEnumerant((int)CFT_NOTEQUAL , "NotEqual"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgCompareFuncSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case CFT_NEVER: // Never + case CFT_LESS: // Less + case CFT_LEQUAL: // LEqual + case CFT_EQUAL: // Equal + case CFT_GREATER: // Greater + case CFT_NOTEQUAL: // NotEqual + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgDepthModeSamplerStateListener::CgDepthModeSamplerStateListener() + : CgIntSamplerStateListener(SST_DEPTHMODE) + { -#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) -#pragma warning(push) -#pragma warning(disable: 4800) // warning C4800: 'const CGbool' : forcing value to bool 'true' or 'false' (performance warning) -#endif - x = static_cast(values[0]); -#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) -#pragma warning(pop) -#endif - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1b::operator bool() const - { - return x; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector2b::Vector2b() : x( false ), y( false ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector2b::Vector2b( bool iX, bool iY , bool iZ, bool iW ) : x( iX ), y( iY ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector2b::Vector2b( CGstateassignment cgStateAssignment ) : x( false ), y( false ) - { - int nValsDummy[1]; - const CGbool * values; - values = cgGetBoolStateAssignmentValues(cgStateAssignment, nValsDummy); - assert(nValsDummy[0] == 2); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgDepthModeSamplerStateListener::createState() + { + CgSamplerStateListener::createState(); -#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) -#pragma warning(push) -#pragma warning(disable: 4800) // warning C4800: 'const CGbool' : forcing value to bool 'true' or 'false' (performance warning) -#endif - x = static_cast(values[0]); - y = static_cast(values[1]); -#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) -#pragma warning(pop) -#endif - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //-------------------------------------------------------------------- - CgFxScriptLoader::Vector3b::Vector3b() : x( false ), y( false ), z( false ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector3b::Vector3b( bool iX, bool iY , bool iZ, bool iW ) : x( iX ), y( iY ), z( iZ ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector3b::Vector3b( CGstateassignment cgStateAssignment ) : x( false ), y( false ), z( false ) - { - int nValsDummy[1]; - const CGbool * values; - values = cgGetBoolStateAssignmentValues(cgStateAssignment, nValsDummy); - assert(nValsDummy[0] == 3); + addStateEnumerant((int)DMT_ALPHA , "Alpha"); + addStateEnumerant((int)DMT_INTENSITY , "Intensity"); + addStateEnumerant((int)DMT_LUMINANCE , "Luminance"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgDepthModeSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case DMT_ALPHA: // Alpha + case DMT_INTENSITY: // Intensity + case DMT_LUMINANCE: // Luminance + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgMinFilterSamplerStateListener::CgMinFilterSamplerStateListener() + : CgIntSamplerStateListener(SST_MINFILTER) + { -#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) -#pragma warning(push) -#pragma warning(disable: 4800) // warning C4800: 'const CGbool' : forcing value to bool 'true' or 'false' (performance warning) -#endif - x = static_cast(values[0]); - y = static_cast(values[1]); - z = static_cast(values[2]); -#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) -#pragma warning(pop) -#endif - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector4b::Vector4b() : x( false ), y( false ), z( false ), w( false ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector4b::Vector4b( bool iX, bool iY , bool iZ, bool iW ) : x( iX ), y( iY ), z( iZ ), w( iW ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector4b::Vector4b( CGstateassignment cgStateAssignment ) : x( false ), y( false ), z( false ), w( false ) - { - int nValsDummy[1]; - const CGbool * values; - values = cgGetBoolStateAssignmentValues(cgStateAssignment, nValsDummy); - assert(nValsDummy[0] == 4); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgMinFilterSamplerStateListener::createState() + { + CgSamplerStateListener::createState(); -#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) -#pragma warning(push) -#pragma warning(disable: 4800) // warning C4800: 'const CGbool' : forcing value to bool 'true' or 'false' (performance warning) -#endif - x = static_cast(values[0]); - y = static_cast(values[1]); - z = static_cast(values[2]); - w = static_cast(values[3]); -#if ( OGRE_COMPILER == OGRE_COMPILER_MSVC ) -#pragma warning(pop) -#endif - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1i::Vector1i() : x( 0 ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1i::Vector1i( int iX ) : x( iX ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1i::Vector1i( CGstateassignment cgStateAssignment ) : x( 0 ) - { - int nValsDummy[1]; - const int * values; - values = cgGetIntStateAssignmentValues(cgStateAssignment, nValsDummy); - assert( nValsDummy[0] == 1); - - x = values[0]; - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1i::operator int() const - { - return x; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector2i::Vector2i() : x( 0 ), y( 0 ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector2i::Vector2i( int iX, int iY ) : x( iX ), y( iY ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector2i::Vector2i( CGstateassignment cgStateAssignment ) : x( 0 ), y( 0 ) - { - int nValsDummy[1]; - const int * values; - values = cgGetIntStateAssignmentValues(cgStateAssignment, nValsDummy); - assert( nValsDummy[0] == 2); - - x = values[0]; - y = values[1]; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector3i::Vector3i() : x( 0 ), y( 0 ), z( 0 ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector3i::Vector3i( int iX, int iY, int iZ ) : x( iX ), y( iY ) , z( iZ ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector3i::Vector3i( CGstateassignment cgStateAssignment ) : x( 0 ), y( 0 ), z( 0 ) - { - int nValsDummy[1]; - const int * values; - values = cgGetIntStateAssignmentValues(cgStateAssignment, nValsDummy); - assert( nValsDummy[0] == 3); - - x = values[0]; - y = values[1]; - z = values[2]; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector4i::Vector4i() : x( 0 ), y( 0 ), z( 0 ), w( 0 ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector4i::Vector4i( int iX, int iY, int iZ, int iW ) : x( iX ), y( iY ), z( iZ ), w( iW ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector4i::Vector4i( CGstateassignment cgStateAssignment ) : x( 0 ), y( 0 ), z( 0 ), w( 0 ) - { - int nValsDummy[1]; - const int * values; - values = cgGetIntStateAssignmentValues(cgStateAssignment, nValsDummy); - assert( nValsDummy[0] == 4 ); - - x = values[0]; - y = values[1]; - z = values[2]; - w = values[3]; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1f::Vector1f() : x( 0.0f ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1f::Vector1f( float iX, float iY, float iZ ) : x( iX ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1f::Vector1f( CGstateassignment cgStateAssignment ) : x( 0.0f ) - { - int nValsDummy[1]; - const float * values; - values = cgGetFloatStateAssignmentValues(cgStateAssignment, nValsDummy); - assert( nValsDummy[0] == 1 ); - - x = values[0]; - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector1f::operator float() const - { - return x; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector2f::Vector2f() : x( 0.0f ), y( 0.0f ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector2f::Vector2f( float iX, float iY, float iZ ) : x( iX ), y( iY ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector2f::Vector2f( CGstateassignment cgStateAssignment ) : x( 0.0f ), y( 0.0f ) - { - int nValsDummy[1]; - const float * values; - values = cgGetFloatStateAssignmentValues(cgStateAssignment, nValsDummy); - assert( nValsDummy[0] == 2 ); - - x = values[0]; - y = values[1]; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector3f::Vector3f() : x( 0.0f ), y( 0.0f ), z( 0.0f ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector3f::Vector3f( float iX, float iY, float iZ ) : x( iX ), y( iY ), z( iZ ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector3f::Vector3f( CGstateassignment cgStateAssignment ) : x( 0.0f ), y( 0.0f ), z( 0.0f ) - { - int nValsDummy[1]; - const float * values; - values = cgGetFloatStateAssignmentValues(cgStateAssignment, nValsDummy); - assert( nValsDummy[0] == 3 ); - - x = values[0]; - y = values[1]; - z = values[2]; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector4f::Vector4f() : x( 0.0f ), y( 0.0f ), z( 0.0f ), w( 0.0f ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector4f::Vector4f( float iX, float iY, float iZ, float iW ) : x( iX ), y( iY ), z( iZ ), w( iW ) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::Vector4f::Vector4f( CGstateassignment cgStateAssignment ) : x( 0.0f ), y( 0.0f ), z( 0.0f ), w( 0.0f ) - { - int nValsDummy[1]; - const float * values; - values = cgGetFloatStateAssignmentValues(cgStateAssignment, nValsDummy); - assert( nValsDummy[0] == 4 ); - - x = values[0]; - y = values[1]; - z = values[2]; - w = values[3]; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgStateListener::CgStateListener(CGtype cgType) - : mCgState(0), - mCgType(cgType), - mCgContext(CgFxScriptLoader::getSingleton().getCgContext()) - - - { - } - //--------------------------------------------------------------------- - CgFxScriptLoader::CgStateListener::~CgStateListener() - { - - } - //--------------------------------------------------------------------- - CGbool CgFxScriptLoader::CgStateListener::cgCallBackSet( const CGstateassignment cgStateAssignment ) - { - return CG_TRUE; - } - //--------------------------------------------------------------------- - CGbool CgFxScriptLoader::CgStateListener::cgCallBackReset( CGstateassignment cgStateAssignment ) - { - return CG_TRUE; - } - //--------------------------------------------------------------------- - CGbool CgFxScriptLoader::CgStateListener::cgCallBackValidate( CGstateassignment cgStateAssignment ) - { - return CG_TRUE; - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStateListener::init() - { - createState(); - checkForCgError("CgFxScriptLoader::CgStateListener::init", - "Unable to Set create State: ", mCgContext); - - cgSetStateCallbacks( mCgState, getCgCallBackSet(), getCgCallBackReset(), getCgCallBackValidate() ); - checkForCgError("CgFxScriptLoader::CgStateListener::init", - "Unable to Set State Callbacks: ", mCgContext); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStateListener::addStateEnumerant( int value, const char *name ) - { - cgAddStateEnumerant(mCgState, name, value); - - checkForCgError("CgFxScriptLoader::CgMinFilterSamplerStateListener::createState", - "Unable to Add State Enumerants: ", mCgContext); - - } - //--------------------------------------------------------------------- - CGstatecallback CgFxScriptLoader::CgStateListener::getCgCallBackSet() - { - return cgCallBackSet; - } - //--------------------------------------------------------------------- - CGstatecallback CgFxScriptLoader::CgStateListener::getCgCallBackReset() - { - return cgCallBackReset; - } - //--------------------------------------------------------------------- - CGstatecallback CgFxScriptLoader::CgStateListener::getCgCallBackValidate() - { - return cgCallBackValidate; - } - //--------------------------------------------------------------------- - CGstate CgFxScriptLoader::CgStateListener::getCgState() const - { - return mCgState; - } - //--------------------------------------------------------------------- - CGparameter CgFxScriptLoader::CgStateListener::getCgParameter( CGstateassignment cgStateAssignment ) - { - return cgGetTextureStateAssignmentValue(cgStateAssignment); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgGlobalStateListener::CgGlobalStateListener( const GlobalStateType globalStateType, CGtype cgType ) - : CgStateListener(cgType), - mGlobalStateType(globalStateType) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::CgGlobalStateListener::~CgGlobalStateListener() - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgGlobalStateListener::createState() - { - const char * typeNameAsString = CgFxScriptLoader::getSingleton().getGlobalStateNameTypeToString(mGlobalStateType); - mCgState = cgCreateState( mCgContext, typeNameAsString, mCgType ); - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - // todo - error - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgBoolGlobalStateListener::CgBoolGlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_BOOL) - { - - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector1b CgFxScriptLoader::CgBoolGlobalStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector1b(cgStateAssignment); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBoolGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - const bool value = getValue(cgStateAssignment); - switch( mGlobalStateType ) - { - case GST_ALPHABLENDENABLE: - break; - case GST_COLORVERTEX: - break; - case GST_DEPTHMASK: - break; - case GST_ZWRITEENABLE: - break; - case GST_INDEXEDVERTEXBLENDENABLE: - break; - case GST_LIGHTINGENABLE: - break; - case GST_LIGHTENABLE: - case GST_LIGHTING: - ogrePass->setLightingEnabled(value); - break; - case GST_LOCALVIEWER: - break; - case GST_MULTISAMPLEANTIALIAS: - break; - case GST_POINTSCALEENABLE: - break; - case GST_RANGEFOGENABLE: - break; - case GST_SPECULARENABLE: - break; - case GST_CLIPPING: - break; - case GST_POINTSPRITECOORDREPLACE: - break; - case GST_LASTPIXEL: - break; - case GST_TEXTURE1DENABLE: - break; - case GST_TEXTURE2DENABLE: - break; - case GST_TEXTURE3DENABLE: - break; - case GST_TEXTURERECTANGLEENABLE: - break; - case GST_TEXTURECUBEMAPENABLE: - break; - case GST_ALPHATESTENABLE: - break; - case GST_AUTONORMALENABLE: - break; - case GST_BLENDENABLE: - break; - case GST_COLORLOGICOPENABLE: - break; - case GST_CULLFACEENABLE: - break; - case GST_DEPTHBOUNDSENABLE: - break; - case GST_DEPTHCLAMPENABLE: - break; - case GST_DEPTHTESTENABLE: - break; - case GST_ZENABLE: - ogrePass->setDepthCheckEnabled(value); - break; - case GST_DITHERENABLE: - break; - case GST_FOGENABLE: - break; - case GST_LIGHTMODELLOCALVIEWERENABLE: - break; - case GST_LIGHTMODELTWOSIDEENABLE: - break; - case GST_LINESMOOTHENABLE: - break; - case GST_LINESTIPPLEENABLE: - break; - case GST_LOGICOPENABLE: - break; - case GST_MULTISAMPLEENABLE: - break; - case GST_NORMALIZEENABLE: - break; - case GST_NORMALIZENORMALS: - break; - case GST_POINTSMOOTHENABLE: - break; - case GST_POINTSPRITEENABLE: - break; - case GST_POLYGONOFFSETFILLENABLE: - break; - case GST_POLYGONOFFSETLINEENABLE: - break; - case GST_POLYGONOFFSETPOINTENABLE: - break; - case GST_POLYGONSMOOTHENABLE: - break; - case GST_POLYGONSTIPPLEENABLE: - break; - case GST_RESCALENORMALENABLE: - break; - case GST_SAMPLEALPHATOCOVERAGEENABLE: - break; - case GST_SAMPLEALPHATOONEENABLE: - break; - case GST_SAMPLECOVERAGEENABLE: - break; - case GST_SCISSORTESTENABLE: - break; - case GST_STENCILTESTENABLE: - break; - case GST_STENCILENABLE: - break; - case GST_STENCILTESTTWOSIDEENABLE: - break; - case GST_TEXGENSENABLE: - break; - case GST_TEXGENTENABLE: - break; - case GST_TEXGENRENABLE: - break; - case GST_TEXGENQENABLE: - break; - case GST_TWOSIDEDSTENCILMODE: - break; - case GST_SEPARATEALPHABLENDENABLE: - break; - case GST_VERTEXPROGRAMPOINTSIZEENABLE: - break; - case GST_VERTEXPROGRAMTWOSIDEENABLE: - break; - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgBool4GlobalStateListener::CgBool4GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_BOOL4) - { - - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector4b CgFxScriptLoader::CgBool4GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector4b( cgStateAssignment ); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBool4GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_COLORWRITEENABLE: - case GST_COLORMASK: - case GST_PIXELSHADERCONSTANTB: - case GST_VERTEXSHADERCONSTANTB: - case GST_COLORWRITEENABLE1: - case GST_COLORWRITEENABLE2: - case GST_COLORWRITEENABLE3: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFloatGlobalStateListener::CgFloatGlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_FLOAT) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFloatGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_ALPHAREF: - case GST_CLEARDEPTH: - case GST_DEPTHBIAS: - case GST_FOGDENSITY: - case GST_FOGSTART: - case GST_FOGEND: - case GST_LIGHTCONSTANTATTENUATION: - case GST_LIGHTATTENUATION0: - case GST_LIGHTLINEARATTENUATION: - case GST_LIGHTATTENUATION1: - case GST_LIGHTQUADRATICATTENUATION: - case GST_LIGHTATTENUATION2: - case GST_LIGHTSPOTCUTOFF: - case GST_LIGHTFALLOFF: - case GST_LIGHTPHI: - case GST_LIGHTRANGE: - case GST_LIGHTTHETA: - case GST_PATCHSEGMENTS: - case GST_POINTSCALE_A: - case GST_POINTSCALE_B: - case GST_POINTSCALE_C: - case GST_TWEENFACTOR: - case GST_LINEWIDTH: - case GST_MATERIALSHININESS: - case GST_MATERIALPOWER: - case GST_POINTFADETHRESHOLDSIZE: - case GST_POINTSIZE: - case GST_POINTSIZEMIN: - case GST_POINTSIZEMAX: - case GST_SLOPSCALEDEPTHBIAS: - case GST_BUMPENVLSCALE: - case GST_BUMPENVLOFFSET: - case GST_BUMPENVMAT00: - case GST_BUMPENVMAT01: - case GST_BUMPENVMAT10: - case GST_BUMPENVMAT11: - case GST_LIGHTSPOTEXPONENT: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector1f CgFxScriptLoader::CgFloatGlobalStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector1f( cgStateAssignment ); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFloat2GlobalStateListener::CgFloat2GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_FLOAT2) - { - - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector2f CgFxScriptLoader::CgFloat2GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector2f( cgStateAssignment ); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFloat2GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_DEPTHBOUNDS: - case GST_DEPTHRANGE: - case GST_POLYGONOFFSET: - case GST_MAXANISOTROPY: - case GST_MAXMIPLEVEL: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFloat3GlobalStateListener::CgFloat3GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_FLOAT3) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFloat3GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_POINTDISTANCEATTENUATION: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector3f CgFxScriptLoader::CgFloat3GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector3f( cgStateAssignment ); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFloat4GlobalStateListener::CgFloat4GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_FLOAT4) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFloat4GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_BLENDCOLOR: - case GST_CLEARCOLOR: - case GST_CLIPPLANE: - case GST_FOGCOLOR: - case GST_FRAGMENTENVPARAMETER: - case GST_FRAGMENTLOCALPARAMETER: - case GST_LIGHTMODELAMBIENT: - case GST_AMBIENT: - case GST_LIGHTAMBIENT: - case GST_LIGHTDIFFUSE: - case GST_LIGHTPOSITION: - case GST_LIGHTSPECULAR: - case GST_LIGHTSPOTDIRECTION: - case GST_LIGHTDIRECTION: - case GST_MATERIALAMBIENT: - case GST_MATERIALDIFFUSE: - case GST_MATERIALEMISSION: - case GST_MATERIALEMISSIVE: - case GST_MATERIALSPECULAR: - case GST_TEXGENSOBJECTPLANE: - case GST_TEXGENSEYEPLANE: - case GST_TEXGENTOBJECTPLANE: - case GST_TEXGENTEYEPLANE: - case GST_TEXGENROBJECTPLANE: - case GST_TEXGENREYEPLANE: - case GST_TEXGENQOBJECTPLANE: - case GST_TEXGENQEYEPLANE: - case GST_TEXTUREENVCOLOR: - case GST_VERTEXENVPARAMETER: - case GST_VERTEXLOCALPARAMETER: - case GST_PIXELSHADERCONSTANT1: - case GST_VERTEXSHADERCONSTANT1: - case GST_PIXELSHADERCONSTANTF: - case GST_VERTEXSHADERCONSTANTF: - case GST_BORDERCOLOR: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector4f CgFxScriptLoader::CgFloat4GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector4f( cgStateAssignment ); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFloat4x2GlobalStateListener::CgFloat4x2GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_FLOAT4x2) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFloat4x2GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_PIXELSHADERCONSTANT2: - case GST_VERTEXSHADERCONSTANT2: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFloat4x3GlobalStateListener::CgFloat4x3GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_FLOAT4x3) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFloat4x3GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_PIXELSHADERCONSTANT3: - case GST_VERTEXSHADERCONSTANT3: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFloat4x4GlobalStateListener::CgFloat4x4GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_FLOAT4x4) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFloat4x4GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_COLORMATRIX: - case GST_COLORTRANSFORM: - case GST_MODELVIEWMATRIX: - case GST_MODELVIEWTRANSFORM: - case GST_VIEWTRANSFORM: - case GST_WORLDTRANSFORM: - case GST_PROJECTIONMATRIX: - case GST_PROJECTIONTRANSFORM: - case GST_TEXTURETRANSFORM: - case GST_TEXTUREMATRIX: - case GST_PIXELSHADERCONSTANT: - case GST_VERTEXSHADERCONSTANT: - case GST_PIXELSHADERCONSTANT4: - case GST_VERTEXSHADERCONSTANT4: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgIntGlobalStateListener::CgIntGlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_INT) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgIntGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_BLENDOP: - case GST_CLEARSTENCIL: - case GST_CLIPPLANEENABLE: - case GST_CULLMODE: - case GST_ZFUNC: - case GST_FOGTABLEMODE: - case GST_FOGVERTEXMODE: - case GST_LIGHTTYPE: - case GST_MULTISAMPLEMASK: - case GST_AMBIENTMATERIALSOURCE: - case GST_DIFFUSEMATERIALSOURCE: - case GST_EMISSIVEMATERIALSOURCE: - case GST_SPECULARMATERIALSOURCE: - case GST_VERTEXBLEND: - case GST_DESTBLEND: - case GST_SRCBLEND: - case GST_STENCILMASK: - case GST_STENCILPASS: - case GST_STENCILREF: - case GST_STENCILWRITEMASK: - case GST_STENCILZFAIL: - case GST_TEXTUREFACTOR: - case GST_STENCILFAIL: - case GST_WRAP0: - case GST_WRAP1: - case GST_WRAP2: - case GST_WRAP3: - case GST_WRAP4: - case GST_WRAP5: - case GST_WRAP6: - case GST_WRAP7: - case GST_WRAP8: - case GST_WRAP9: - case GST_WRAP10: - case GST_WRAP11: - case GST_WRAP12: - case GST_WRAP13: - case GST_WRAP14: - case GST_WRAP15: - case GST_ADDRESSU: - case GST_ADDRESSV: - case GST_ADDRESSW: - case GST_MIPMAPLODBIAS: - case GST_BLENDOPALPHA: - case GST_SRCBLENDALPHA: - case GST_DESTBLENDALPHA: - case GST_ALPHAOP: - case GST_COLOROP: - case GST_ALPHAARG0: - case GST_ALPHAARG1: - case GST_ALPHAARG2: - case GST_COLORARG0: - case GST_COLORARG1: - case GST_COLORARG2: - case GST_RESULTARG: - case GST_TEXCOORDINDEX: - case GST_TEXTURETRANSFORMFLAGS: - case GST_MIPFILTER: // todo - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector1i CgFxScriptLoader::CgIntGlobalStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector1i(cgStateAssignment); - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgInt2GlobalStateListener::CgInt2GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_INT2) - { - - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector2i CgFxScriptLoader::CgInt2GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector2i(cgStateAssignment); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgInt2GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_LINESTIPPLE: - case GST_FILLMODE: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgInt3GlobalStateListener::CgInt3GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_INT3) - { - - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector3i CgFxScriptLoader::CgInt3GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector3i(cgStateAssignment); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgInt3GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - // todo - error - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgInt4GlobalStateListener::CgInt4GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_INT4) - { - - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector4i CgFxScriptLoader::CgInt4GlobalStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector4i(cgStateAssignment); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgInt4GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_SCISSOR: - case GST_PIXELSHADERCONSTANTI: - case GST_VERTEXSHADERCONSTANTI: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgSamplerGlobalStateListener::CgSamplerGlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_SAMPLER) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgSamplerGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_SAMPLER: - case GST_TEXTURE1D: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgSampler2GlobalStateListener::CgSampler2GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_SAMPLER2D) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgSampler2GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_TEXTURE2D: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgSampler3GlobalStateListener::CgSampler3GlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener( globalStateType, CG_SAMPLER3D ) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgSampler3GlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_TEXTURE3D: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgSamplerCubeGlobalStateListener::CgSamplerCubeGlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_SAMPLERCUBE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgSamplerCubeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_TEXTURECUBEMAP: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgSamplerRectGlobalStateListener::CgSamplerRectGlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_SAMPLERRECT) - { - - } - - void CgFxScriptLoader::CgSamplerRectGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_TEXTURERECTANGLE: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgTextureGlobalStateListener::CgTextureGlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_TEXTURE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgTextureGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_TEXTURE: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgProgramGlobalStateListener::CgProgramGlobalStateListener( const GlobalStateType globalStateType ) - : CgGlobalStateListener(globalStateType, CG_PROGRAM_TYPE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgProgramGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( mGlobalStateType ) - { - case GST_GEOMETRYPROGRAM: - case GST_VERTEXPROGRAM: - case GST_VERTEXSHADER: - case GST_FRAGMENTPROGRAM: - case GST_PIXELSHADER: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgBlendEquationGlobalStateListener::CgBlendEquationGlobalStateListener() - : CgIntGlobalStateListener(GST_BLENDEQUATION) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBlendEquationGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)BET_FUNCADD , "FuncAdd"); - addStateEnumerant((int)BET_FUNCSUBTRACT , "FuncSubtract"); - addStateEnumerant((int)BET_MIN , "Min"); - addStateEnumerant((int)BET_MAX , "Max"); - addStateEnumerant((int)BET_LOGICOP ,"LogicOp"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBlendEquationGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case BET_FUNCADD: // FuncAdd - case BET_FUNCSUBTRACT: // FuncSubtract - case BET_MIN: // Min - case BET_MAX: // Max - case BET_LOGICOP: // LogicOp - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgDepthFuncGlobalStateListener::CgDepthFuncGlobalStateListener() - : CgIntGlobalStateListener(GST_DEPTHFUNC) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgDepthFuncGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)DFT_NEVER , "Never"); - addStateEnumerant((int)DFT_LESS , "Less"); - addStateEnumerant((int)DFT_LEQUAL , "LEqual"); - addStateEnumerant((int)DFT_EQUAL , "Equal"); - addStateEnumerant((int)DFT_GREATER , "Greater"); - addStateEnumerant((int)DFT_NOTEQUAL , "NotEqual"); - addStateEnumerant((int)DFT_GEQUAL , "GEqual"); - addStateEnumerant((int)DFT_ALWAYS , "Always"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgDepthFuncGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case DFT_NEVER: // Never - case DFT_LESS: // Less - case DFT_LEQUAL: // LEqual - case DFT_EQUAL: // Equal - case DFT_GREATER: // Greater - case DFT_NOTEQUAL: // NotEqual - case DFT_GEQUAL: // GEqual - case DFT_ALWAYS : // Always - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFogDistanceModeGlobalStateListener::CgFogDistanceModeGlobalStateListener() - : CgIntGlobalStateListener(GST_FOGDISTANCEMODE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFogDistanceModeGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)FDMT_EYERADIAL , "EyeRadial"); - addStateEnumerant((int)FDMT_EYEPLANE , "EyePlane"); - addStateEnumerant((int)FDMT_EYEPLANEABSOLUTE , "EyePlaneAbsolute"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFogDistanceModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case FDMT_EYERADIAL: // EyeRadial - case FDMT_EYEPLANE: // EyePlane - case FDMT_EYEPLANEABSOLUTE: // EyePlaneAbsolute - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFogModeGlobalStateListener::CgFogModeGlobalStateListener() - : CgIntGlobalStateListener(GST_FOGMODE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFogModeGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)FMT_LINEAR , "Linear"); - addStateEnumerant((int)FMT_EXP , "Exp"); - addStateEnumerant((int)FMT_EXP2 , "Exp2"); - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFogModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case FMT_LINEAR: // Linear - case FMT_EXP: // Exp - case FMT_EXP2: // Exp2 - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgLightModelColorControlGlobalStateListener::CgLightModelColorControlGlobalStateListener() - : CgIntGlobalStateListener(GST_LIGHTMODELCOLORCONTROL) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgLightModelColorControlGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)LMCCT_SINGLECOLOR , "SingleColor"); - addStateEnumerant((int)LMCCT_SEPARATESPECULAR , "SeparateSpecular"); - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgLightModelColorControlGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case LMCCT_SINGLECOLOR: // SingleColor - case LMCCT_SEPARATESPECULAR: // SeparateSpecular - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgLogicOpGlobalStateListener::CgLogicOpGlobalStateListener() - : CgIntGlobalStateListener(GST_LOGICOP) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgLogicOpGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)LOT_CLEAR , "Clear"); - addStateEnumerant((int)LOT_AND , "And"); - addStateEnumerant((int)LOT_ANDREVERSE , "AndReverse"); - addStateEnumerant((int)LOT_COPY , "Copy"); - addStateEnumerant((int)LOT_ANDINVERTED , "AndInverted"); - addStateEnumerant((int)LOT_NOOP , "Noop"); - addStateEnumerant((int)LOT_XOR , "Xor"); - addStateEnumerant((int)LOT_OR , "Or"); - addStateEnumerant((int)LOT_NOR , "Nor"); - addStateEnumerant((int)LOT_EQUIV , "Equiv"); - addStateEnumerant((int)LOT_INVERT , "Invert"); - addStateEnumerant((int)LOT_ORREVERSE , "OrReverse"); - addStateEnumerant((int)LOT_COPYINVERTED , "CopyInverted"); - addStateEnumerant((int)LOT_NAND , "Nand"); - addStateEnumerant((int)LOT_SET , "Set"); - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgLogicOpGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case LOT_CLEAR: // Clear - case LOT_AND: // And - case LOT_ANDREVERSE: // AndReverse - case LOT_COPY: // Copy - case LOT_ANDINVERTED: // AndInverted - case LOT_NOOP: // Noop - case LOT_XOR: // Xor - case LOT_OR: // Or, - case LOT_NOR: // Nor - case LOT_EQUIV: // Equiv - case LOT_INVERT: // Invert - case LOT_ORREVERSE: // OrReverse - case LOT_COPYINVERTED: // CopyInverted - case LOT_NAND: // Nand - case LOT_SET: // Set - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgPointSpriteCoordOriginGlobalStateListener::CgPointSpriteCoordOriginGlobalStateListener() - : CgIntGlobalStateListener(GST_POINTSPRITECOORDORIGIN) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgPointSpriteCoordOriginGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)PSCOT_LOWERLEFT , "LowerLeft"); - addStateEnumerant((int)PSCOT_UPPERLEFT , "UpperLeft"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgPointSpriteCoordOriginGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case PSCOT_LOWERLEFT: // LowerLeft - case PSCOT_UPPERLEFT: // UpperLeft - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgPointSpriteRModeGlobalStateListener::CgPointSpriteRModeGlobalStateListener() - : CgIntGlobalStateListener(GST_POINTSPRITERMODE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgPointSpriteRModeGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)PSRMT_ZERO , "Zero"); - addStateEnumerant((int)PSRMT_R , "R"); - addStateEnumerant((int)PSRMT_S , "S"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgPointSpriteRModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case PSRMT_ZERO: // Zero - case PSRMT_R: // R - case PSRMT_S: // S - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - - CgFxScriptLoader::CgShadeModelGlobalStateListener::CgShadeModelGlobalStateListener() - : CgIntGlobalStateListener(GST_SHADEMODEL) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgShadeModelGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)SMT_FLAT , "Flat"); - addStateEnumerant((int)SMT_SMOOTH , "Smooth"); - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgShadeModelGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case SMT_FLAT: // Flat - case SMT_SMOOTH: // Smooth - default: - // todo - error - break; - } - - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgTexGenModeGlobalStateListener::CgTexGenModeGlobalStateListener(const GlobalStateType globalStateType) - : CgIntGlobalStateListener(globalStateType) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgTexGenModeGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)TGMT_OBJECTLINEAR, "ObjectLinear"); - addStateEnumerant((int)TGMT_EYELINEAR, "EyeLinear"); - addStateEnumerant((int)TGMT_SPHEREMAP, "SphereMap"); - addStateEnumerant((int)TGMT_REFLECTIONMAP, "ReflectionMap"); - addStateEnumerant((int)TGMT_NORMALMAP, "NormalMap"); - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgTexGenModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case TGMT_OBJECTLINEAR: // ObjectLinear - case TGMT_EYELINEAR: // EyeLinear - case TGMT_SPHEREMAP: // SphereMap - case TGMT_REFLECTIONMAP: // ReflectionMap - case TGMT_NORMALMAP: // NormalMap - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgTextureEnvModeGlobalStateListener::CgTextureEnvModeGlobalStateListener() - : CgIntGlobalStateListener(GST_TEXTUREENVMODE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgTextureEnvModeGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)BET_MODULATE, "Modulate"); - addStateEnumerant((int)BET_DECAL, "Decal"); - addStateEnumerant((int)BET_BLEND, "Blend"); - addStateEnumerant((int)BET_REPLACE, "Replace"); - addStateEnumerant((int)BET_ADD, "Add"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgTextureEnvModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case BET_MODULATE: // Modulate - case BET_DECAL: // Decal - case BET_BLEND: // Blend - case BET_REPLACE: // Replace - case BET_ADD: // Add - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgMinFilterGlobalStateListener::CgMinFilterGlobalStateListener() - : CgIntGlobalStateListener(GST_MINFILTER) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgMinFilterGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)MFT_NEAREST, "Nearest"); - addStateEnumerant((int)MFT_LINEAR, "Linear"); - addStateEnumerant((int)MFT_LINEARMIPMAPNEAREST, "LinearMipMapNearest"); - addStateEnumerant((int)MFT_NEARESTMIPMAPNEAREST, "NearestMipMapNearest"); - addStateEnumerant((int)MFT_NEARESTMIPMAPLINEAR, "NearestMipMapLinear"); - addStateEnumerant((int)MFT_LINEARMIPMAPLINEAR, "LinearMipMapLinear"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgMinFilterGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case MFT_NEAREST: // Nearest - case MFT_LINEAR: // Linear - case MFT_LINEARMIPMAPNEAREST: // LinearMipMapNearest - case MFT_NEARESTMIPMAPNEAREST: // NearestMipMapNearest - case MFT_NEARESTMIPMAPLINEAR: // NearestMipMapLinear - case MFT_LINEARMIPMAPLINEAR: // LinearMipMapLinear - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgMagFilterGlobalStateListener::CgMagFilterGlobalStateListener() - : CgIntGlobalStateListener(GST_MAGFILTER) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgMagFilterGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)MFT_NEAREST, "Nearest"); - addStateEnumerant((int)MFT_LINEAR, "Linear"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgMagFilterGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case MFT_NEAREST: // Nearest - case MFT_LINEAR: // Linear - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFrontFaceGlobalStateListener::CgFrontFaceGlobalStateListener() - : CgIntGlobalStateListener(GST_FRONTFACE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFrontFaceGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)FFT_CW, "CW"); - addStateEnumerant((int)FFT_CCW, "CCW"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFrontFaceGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case FFT_CW: // CW - case FFT_CCW: // CCW - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgCullFaceGlobalStateListener::CgCullFaceGlobalStateListener() - : CgIntGlobalStateListener(GST_CULLFACE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgCullFaceGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)CFT_FRONT, "Front"); - addStateEnumerant((int)CFT_BACK, "Back"); - addStateEnumerant((int)CFT_FRONTANDBACK, "FrontAndBack"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgCullFaceGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case CFT_FRONT: // Front - case CFT_BACK: // Back - case CFT_FRONTANDBACK: // FrontAndBack - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFogCoordSrcGlobalStateListener::CgFogCoordSrcGlobalStateListener() - : CgIntGlobalStateListener(GST_FOGCOORDSRC) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFogCoordSrcGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)FCST_FRAGMENTDEPTH, "FragmentDepth"); - addStateEnumerant((int)FCST_FOGCOORD, "FogCoord"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFogCoordSrcGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case FCST_FRAGMENTDEPTH: // FragmentDepth - case FCST_FOGCOORD: // FogCoord - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgAlphaFuncGlobalStateListener::CgAlphaFuncGlobalStateListener() - : CgFloat2GlobalStateListener(GST_ALPHAFUNC) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgAlphaFuncGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)AFT_NEVER, "Never"); - addStateEnumerant((int)AFT_LESS, "Less"); - addStateEnumerant((int)AFT_LEQUAL, "LEqual"); - addStateEnumerant((int)AFT_EQUAL, "Equal"); - addStateEnumerant((int)AFT_GREATER, "Greater"); - addStateEnumerant((int)AFT_NOTEQUAL, "NotEqual"); - addStateEnumerant((int)AFT_GEQUAL, "GEqual"); - addStateEnumerant((int)AFT_ALWAYS, "Always"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgAlphaFuncGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( static_cast(getValue(cgStateAssignment).x) ) - { - case AFT_NEVER: // Never - case AFT_LESS: // Less - case AFT_LEQUAL: // LEqual - case AFT_EQUAL: // Equal - case AFT_GREATER: // Greater - case AFT_NOTEQUAL: // NotEqual - case AFT_GEQUAL: // GEqual - case AFT_ALWAYS: // Always - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgBlendFuncGlobalStateListener::CgBlendFuncGlobalStateListener() - : CgInt2GlobalStateListener(GST_BLENDFUNC) - { - - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBlendFuncGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)BF_ZERO, "Zero"); - addStateEnumerant((int)BF_ONE, "One"); - addStateEnumerant((int)BF_DESTCOLOR, "DestColor"); - addStateEnumerant((int)BF_ONEMINUSDESTCOLOR, "OneMinusDestColor"); - addStateEnumerant((int)BF_SRCALPHA, "SrcAlpha"); - addStateEnumerant((int)BF_ONEMINUSSRCALPHA, "OneMinusSrcAlpha"); - addStateEnumerant((int)BF_DSTALPHA, "DstAlpha"); - addStateEnumerant((int)BF_ONEMINUSDSTALPHA, "OneMinusDstAlpha"); - addStateEnumerant((int)BF_SRCALPHASATURATE, "SrcAlphaSaturate"); - addStateEnumerant((int)BF_SRCCOLOR, "SrcColor"); - addStateEnumerant((int)BF_ONEMINUSSRCCOLOR, "OneMinusSrcColor"); - addStateEnumerant((int)BF_CONSTANTCOLOR, "ConstantColor"); - addStateEnumerant((int)BF_ONEMINUSCONSTANTCOLOR, "OneMinusConstantColor"); - addStateEnumerant((int)BF_CONSTANTALPHA, "ConstantAlpha"); - addStateEnumerant((int)BF_ONEMINUSCONSTANTALPHA, "OneMinusConstantAlpha"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBlendFuncGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment).x ) - { - case BF_ZERO: // Zero - case BF_ONE: // One - case BF_DESTCOLOR: // DestColor - case BF_ONEMINUSDESTCOLOR: // OneMinusDestColor - case BF_SRCALPHA: // SrcAlpha - case BF_ONEMINUSSRCALPHA: // OneMinusSrcAlpha - case BF_DSTALPHA: // DstAlpha - case BF_ONEMINUSDSTALPHA: // OneMinusDstAlpha - case BF_SRCALPHASATURATE: // SrcAlphaSaturate - case BF_SRCCOLOR: // SrcColor - case BF_ONEMINUSSRCCOLOR: // OneMinusSrcColor - case BF_CONSTANTCOLOR: // ConstantColor - case BF_ONEMINUSCONSTANTCOLOR: // OneMinusConstantColor - case BF_CONSTANTALPHA: // ConstantAlpha - case BF_ONEMINUSCONSTANTALPHA: // OneMinusConstantAlpha - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgBlendFuncSeparateGlobalStateListener::CgBlendFuncSeparateGlobalStateListener() - : CgInt4GlobalStateListener(GST_BLENDFUNCSEPARATE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBlendFuncSeparateGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)BFST_ZERO, "Zero"); - addStateEnumerant((int)BFST_ONE, "One"); - addStateEnumerant((int)BFST_DESTCOLOR, "DestColor"); - addStateEnumerant((int)BFST_ONEMINUSDESTCOLOR, "OneMinusDestColor"); - addStateEnumerant((int)BFST_SRCALPHA, "SrcAlpha"); - addStateEnumerant((int)BFST_ONEMINUSSRCALPHA, "OneMinusSrcAlpha"); - addStateEnumerant((int)BFST_DSTALPHA, "DstAlpha"); - addStateEnumerant((int)BFST_ONEMINUSDSTALPHA, "OneMinusDstAlpha"); - addStateEnumerant((int)BFST_SRCALPHASATURATE, "SrcAlphaSaturate"); - addStateEnumerant((int)BFST_SRCCOLOR, "SrcColor"); - addStateEnumerant((int)BFST_ONEMINUSSRCCOLOR, "OneMinusSrcColor"); - addStateEnumerant((int)BFST_CONSTANTCOLOR, "ConstantColor"); - addStateEnumerant((int)BFST_ONEMINUSCONSTANTCOLOR, "OneMinusConstantColor"); - addStateEnumerant((int)BFST_CONSTANTALPHA, "ConstantAlpha"); - addStateEnumerant((int)BFST_ONEMINUSCONSTANTALPHA, "OneMinusConstantAlpha"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBlendFuncSeparateGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment).x ) - { - case BFST_ZERO: // Zero - case BFST_ONE: // One - case BFST_DESTCOLOR: // DestColor - case BFST_ONEMINUSDESTCOLOR: // OneMinusDestColor - case BFST_SRCALPHA: // SrcAlpha - case BFST_ONEMINUSSRCALPHA: // OneMinusSrcAlpha - case BFST_DSTALPHA: // DstAlpha - case BFST_ONEMINUSDSTALPHA: // OneMinusDstAlpha - case BFST_SRCALPHASATURATE: // SrcAlphaSaturate - case BFST_SRCCOLOR: // SrcColor - case BFST_ONEMINUSSRCCOLOR: // OneMinusSrcColor - case BFST_CONSTANTCOLOR: // ConstantColor - case BFST_ONEMINUSCONSTANTCOLOR: // OneMinusConstantColor - case BFST_CONSTANTALPHA: // ConstantAlpha - case BFST_ONEMINUSCONSTANTALPHA: // OneMinusConstantAlpha - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgBlendEquationSeparateGlobalStateListener::CgBlendEquationSeparateGlobalStateListener() - : CgInt2GlobalStateListener(GST_BLENDEQUATIONSEPARATE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBlendEquationSeparateGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)BEST_FUNCADD, "FuncAdd"); - addStateEnumerant((int)BEST_FUNCSUBTRACT, "FuncSubtract"); - addStateEnumerant((int)BEST_MIN, "Min"); - addStateEnumerant((int)BEST_MAX, "Max"); - addStateEnumerant((int)BEST_LOGICOP, "LogicOp"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBlendEquationSeparateGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment).x ) - { - case BEST_FUNCADD: // FuncAdd - case BEST_FUNCSUBTRACT: // FuncSubtract - case BEST_MIN: // Min - case BEST_MAX: // Max - case BEST_LOGICOP: // LogicOp - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgColorMaterialGlobalStateListener::CgColorMaterialGlobalStateListener() - : CgInt2GlobalStateListener(GST_COLORMATERIAL) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgColorMaterialGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)CMT_FRONT, "Front"); - addStateEnumerant((int)CMT_BACK, "Back"); - addStateEnumerant((int)CMT_FRONTANDBACK, "FrontAndBack"); - addStateEnumerant((int)CMT_EMISSION, "Emission"); - addStateEnumerant((int)CMT_AMBIENT, "Ambient"); - addStateEnumerant((int)CMT_DIFFUSE, "Diffuse"); - addStateEnumerant((int)CMT_SPECULAR, "Specular"); - addStateEnumerant((int)CMT_AMBIENTANDDIFFUSE, "AmbientAndDiffuse"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgColorMaterialGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment).x ) - { - case CMT_FRONT: // Front - case CMT_BACK: // Back - case CMT_FRONTANDBACK: // FrontAndBack - case CMT_EMISSION: // Emission - case CMT_AMBIENT: // Ambient - case CMT_DIFFUSE: // Diffuse - case CMT_SPECULAR: // Specular - case CMT_AMBIENTANDDIFFUSE: // AmbientAndDiffuse - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgPolygonModeGlobalStateListener::CgPolygonModeGlobalStateListener() - : CgInt2GlobalStateListener(GST_POLYGONMODE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgPolygonModeGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - - addStateEnumerant((int)PMT_FRONT, "Front"); - addStateEnumerant((int)PMT_BACK, "Back"); - addStateEnumerant((int)PMT_FRONTANDBACK, "FrontAndBack"); - addStateEnumerant((int)PMT_POINT, "Point"); - addStateEnumerant((int)PMT_LINE, "Line"); - addStateEnumerant((int)PMT_FILL, "Fill"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgPolygonModeGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment).x ) - { - case PMT_FRONT: // Front - case PMT_BACK: // Back - case PMT_FRONTANDBACK: // FrontAndBack - case PMT_POINT: // Point - case PMT_LINE: // Line - case PMT_FILL: // Fill - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgStencilFuncGlobalStateListener::CgStencilFuncGlobalStateListener() - : CgInt3GlobalStateListener(GST_STENCILFUNC) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStencilFuncGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - addStateEnumerant((int)SFT_NEVER, "Never"); - addStateEnumerant((int)SFT_LESS, "Less"); - addStateEnumerant((int)SFT_LEQUAL, "LEqual"); - addStateEnumerant((int)SFT_EQUAL, "Equal"); - addStateEnumerant((int)SFT_GREATER, "Greater"); - addStateEnumerant((int)SFT_NOTEQUAL, "NotEqual"); - addStateEnumerant((int)SFT_GEQUAL, "GEqual"); - addStateEnumerant((int)SFT_ALWAYS, "Always"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStencilFuncGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment).x ) - { - case SFT_NEVER: // Never - case SFT_LESS: // Less - case SFT_LEQUAL: // LEqual - case SFT_EQUAL: // Equal - case SFT_GREATER: // Greater - case SFT_NOTEQUAL: // NotEqual - case SFT_GEQUAL: // GEqual - case SFT_ALWAYS: // Always - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgStencilOpGlobalStateListener::CgStencilOpGlobalStateListener() - : CgInt3GlobalStateListener(GST_STENCILOP) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStencilOpGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - addStateEnumerant((int)SOT_KEEP, "Keep"); - addStateEnumerant((int)SOT_ZERO, "Zero"); - addStateEnumerant((int)SOT_REPLACE, "Replace"); - addStateEnumerant((int)SOT_INCR, "Incr"); - addStateEnumerant((int)SOT_DECR, "Decr"); - addStateEnumerant((int)SOT_INVERT, "Invert"); - addStateEnumerant((int)SOT_INCRWRAP, "IncrWrap"); - addStateEnumerant((int)SOT_DECRWRAP, "DecrWrap"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStencilOpGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment).x ) - { - case SOT_KEEP: // Keep - case SOT_ZERO: // Zero - case SOT_REPLACE: // Replace - case SOT_INCR: // Incr - case SOT_DECR: // Decr - case SOT_INVERT: // Invert - case SOT_INCRWRAP: // IncrWrap - case SOT_DECRWRAP: // DecrWrap - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgStencilFuncSeparateGlobalStateListener::CgStencilFuncSeparateGlobalStateListener() - : CgInt4GlobalStateListener(GST_STENCILFUNCSEPARATE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStencilFuncSeparateGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - addStateEnumerant((int)SFST_FRONT, "Front"); - addStateEnumerant((int)SFST_BACK, "Back"); - addStateEnumerant((int)SFST_FRONTANDBACK, "FrontAndBack"); - addStateEnumerant((int)SFST_NEVER, "Never"); - addStateEnumerant((int)SFST_LESS, "Less"); - addStateEnumerant((int)SFST_LEQUAL, "LEqual"); - addStateEnumerant((int)SFST_EQUAL, "Equal"); - addStateEnumerant((int)SFST_GREATER, "Greater"); - addStateEnumerant((int)SFST_NOTEQUAL, "NotEqual"); - addStateEnumerant((int)SFST_GEQUAL, "GEqual"); - addStateEnumerant((int)SFST_ALWAYS, "Always"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStencilFuncSeparateGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment).x ) - { - case SFST_FRONT: // Front - case SFST_BACK: // Back - case SFST_FRONTANDBACK: // FrontAndBack - case SFST_NEVER: // Never - case SFST_LESS: // Less - case SFST_LEQUAL: // LEqual - case SFST_EQUAL: // Equal - case SFST_GREATER: // Greater - case SFST_NOTEQUAL: // NotEqual - case SFST_GEQUAL: // GEqual - case SFST_ALWAYS: // Always - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgStencilMaskSeparateGlobalStateListener::CgStencilMaskSeparateGlobalStateListener() - : CgInt2GlobalStateListener(GST_STENCILMASKSEPARATE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStencilMaskSeparateGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - addStateEnumerant((int)BET_FRONT, "Front"); - addStateEnumerant((int)BET_BACK, "Back"); - addStateEnumerant((int)BET_FRONTANDBACK, "FrontAndBack"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStencilMaskSeparateGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment).x ) - { - case BET_FRONT: // Front - case BET_BACK: // Back - case BET_FRONTANDBACK: // FrontAndBack - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgStencilOpSeparateGlobalStateListener::CgStencilOpSeparateGlobalStateListener() - : CgInt4GlobalStateListener(GST_STENCILOPSEPARATE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStencilOpSeparateGlobalStateListener::createState() - { - CgGlobalStateListener::createState(); - addStateEnumerant((int)BET_KEEP, "Keep"); - addStateEnumerant((int)BET_ZERO, "Zero"); - addStateEnumerant((int)BET_REPLACE, "Replace"); - addStateEnumerant((int)BET_INCR, "Incr"); - addStateEnumerant((int)BET_DECR, "Decr"); - addStateEnumerant((int)BET_INVERT, "Invert"); - addStateEnumerant((int)BET_INCRWRAP, "IncrWrap"); - addStateEnumerant((int)BET_DECRWRAP, "DecrWrap"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgStencilOpSeparateGlobalStateListener::updatePass( Pass * ogrePass, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment).x ) - { - case BET_KEEP: // Keep - case BET_ZERO: // Zero - case BET_REPLACE: // Replace - case BET_INCR: // Incr - case BET_DECR: // Decr - case BET_INVERT: // Invert - case BET_INCRWRAP: // IncrWrap - case BET_DECRWRAP: // DecrWrap - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgSamplerStateListener::CgSamplerStateListener( SamplerStateType samplerStateType, CGtype cgType ) - :CgStateListener(cgType), - mSamplerStateType(samplerStateType) - { - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::CgSamplerStateListener::~CgSamplerStateListener() - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgSamplerStateListener::createState() - { - const char * typeNameAsString = CgFxScriptLoader::getSingleton().getSamplerStateNameTypeToString(mSamplerStateType); - mCgState = cgCreateSamplerState( mCgContext, typeNameAsString, mCgType ); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgIntSamplerStateListener::CgIntSamplerStateListener(const SamplerStateType samplerStateType) - : CgSamplerStateListener(samplerStateType, CG_INT) - { - - } - //--------------------------------------------------------------------- - const CgFxScriptLoader::Vector1i CgFxScriptLoader::CgIntSamplerStateListener::getValue( CGstateassignment cgStateAssignment ) - { - return Vector1i(cgStateAssignment); - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgIntSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - - // todo - error - - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgBoolSamplerStateListener::CgBoolSamplerStateListener( const SamplerStateType samplerStateType ) - : CgSamplerStateListener(samplerStateType, CG_BOOL) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgBoolSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - switch( mSamplerStateType ) - { - case SST_GENERATEMIPMAP: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFloatSamplerStateListener::CgFloatSamplerStateListener( const SamplerStateType samplerStateType ) - : CgSamplerStateListener(samplerStateType, CG_FLOAT) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFloatSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - switch( mSamplerStateType ) - { - case SST_MIPMAPLODBIAS: - case SST_LODBIAS: - case SST_MAXMIPLEVEL: - case SST_MAXANISOTROPY: - case SST_MINMIPLEVEL: - case SST_SRGBTEXTURE: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgFloat4SamplerStateListener::CgFloat4SamplerStateListener( const SamplerStateType samplerStateType ) - : CgSamplerStateListener(samplerStateType, CG_FLOAT4) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgFloat4SamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - switch( mSamplerStateType ) - { - case SST_BORDERCOLOR: - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgTextureSamplerStateListener::CgTextureSamplerStateListener( const SamplerStateType samplerStateType ) - : CgSamplerStateListener(samplerStateType, CG_TEXTURE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgTextureSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - parseTextureName(getCgParameter(cgStateAssignment), ogreTextureUnitState); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgTextureSamplerStateListener::parseTextureName( CGparameter cgParameter, TextureUnitState * ogreTextureUnitState ) - { - CGannotation cgAnnotation = cgGetNamedParameterAnnotation(cgParameter, "ResourceName"); - if (cgAnnotation && cgGetAnnotationType(cgAnnotation) == CG_STRING) - { - const char * textureName = cgGetStringAnnotationValue(cgAnnotation); - if (textureName) - { - ogreTextureUnitState->setTextureName(textureName, parseTextureType(cgParameter, ogreTextureUnitState)); - } - } - } - //--------------------------------------------------------------------- - TextureType CgFxScriptLoader::CgTextureSamplerStateListener::parseTextureType( CGparameter cgParameter, TextureUnitState * ogreTextureUnitState ) - { - CGannotation cgAnnotation = cgGetNamedParameterAnnotation(cgParameter, "ResourceType"); - if (cgAnnotation && cgGetAnnotationType(cgAnnotation) == CG_STRING) - { - String textureType = cgGetStringAnnotationValue(cgAnnotation); - StringUtil::toLowerCase(textureType); - if ("1d" == textureType) - { - return TEX_TYPE_1D; - } - if ("2d" == textureType) - { - return TEX_TYPE_2D; - } - if ("3d" == textureType) - { - return TEX_TYPE_3D; - } - if ("cube" == textureType) - { - return TEX_TYPE_CUBE_MAP; - } - } - return TEX_TYPE_2D; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgWrapSamplerStateListener::CgWrapSamplerStateListener( const SamplerStateType samplerStateType ) - : CgIntSamplerStateListener(samplerStateType) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgWrapSamplerStateListener::createState() - { - CgSamplerStateListener::createState(); - - addStateEnumerant((int)WT_REPEAT , "Repeat"); - addStateEnumerant((int)WT_CLAMP , "Clamp"); - addStateEnumerant((int)WT_CLAMPTOEDGE , "ClampToEdge"); - addStateEnumerant((int)WT_CLAMPTOBORDER , "ClampToBorder"); - addStateEnumerant((int)WT_MIRROREDREPEAT , "MirroredRepeat"); - addStateEnumerant((int)WT_MIRRORCLAMP , "MirrorClamp"); - addStateEnumerant((int)WT_MIRRORCLAMPTOEDGE , "MirrorClampToEdge"); - addStateEnumerant((int)WT_MIRRORCLAMPTOBORDER , "MirrorClampToBorder"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgWrapSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - TextureUnitState::TextureAddressingMode ogreTextureAddressingMode = TextureUnitState::TAM_WRAP; - ogreTextureAddressingMode = getOgreTextureAddressingMode(cgStateAssignment); - - TextureUnitState::UVWAddressingMode ogreUVWAddressingMode = ogreTextureUnitState->getTextureAddressingMode(); - - switch( mSamplerStateType ) - { - case SST_WRAPS: - ogreUVWAddressingMode.u = ogreTextureAddressingMode; - break; - case SST_WRAPT: - ogreUVWAddressingMode.v = ogreTextureAddressingMode; - break; - case SST_WRAPR: - ogreUVWAddressingMode.w = ogreTextureAddressingMode; - break; - default: - // todo - error - break; - } - ogreTextureUnitState->setTextureAddressingMode( ogreUVWAddressingMode ); - - } - //--------------------------------------------------------------------- - TextureUnitState::TextureAddressingMode CgFxScriptLoader::CgWrapSamplerStateListener::getOgreTextureAddressingMode( CGstateassignment cgStateAssignment ) - { - TextureUnitState::TextureAddressingMode ogreTextureAddressingMode = TextureUnitState::TAM_WRAP; - switch( getValue( cgStateAssignment ) ) - { - case WT_REPEAT: // Repeat - ogreTextureAddressingMode = TextureUnitState::TAM_WRAP; - break; - case WT_CLAMP: // Clamp - ogreTextureAddressingMode = TextureUnitState::TAM_CLAMP; - break; - case WT_CLAMPTOEDGE: // ClampToEdge - ogreTextureAddressingMode = TextureUnitState::TAM_CLAMP; - break; - case WT_CLAMPTOBORDER: // ClampToBorder - ogreTextureAddressingMode = TextureUnitState::TAM_BORDER; - break; - case WT_MIRROREDREPEAT: // MirroredRepeat - ogreTextureAddressingMode = TextureUnitState::TAM_MIRROR; - break; - case WT_MIRRORCLAMP: // MirrorClamp - ogreTextureAddressingMode = TextureUnitState::TAM_MIRROR; - break; - case WT_MIRRORCLAMPTOEDGE: // MirrorClampToEdge - ogreTextureAddressingMode = TextureUnitState::TAM_MIRROR; - break; - case WT_MIRRORCLAMPTOBORDER: // MirrorClampToBorder - ogreTextureAddressingMode = TextureUnitState::TAM_MIRROR; - break; - default: - // todo - error - ogreTextureAddressingMode = TextureUnitState::TAM_WRAP; - break; - } - return ogreTextureAddressingMode; - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgCompareModeSamplerStateListener::CgCompareModeSamplerStateListener() - : CgIntSamplerStateListener(SST_COMPAREMODE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgCompareModeSamplerStateListener::createState() - { - CgSamplerStateListener::createState(); - - addStateEnumerant((int)CMT_NONE , "None"); - addStateEnumerant((int)CMT_COMPARERTOTEXTURE , "CompareRToTexture"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgCompareModeSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case CMT_NONE: // None - case CMT_COMPARERTOTEXTURE: // CompareRToTexture - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgCompareFuncSamplerStateListener::CgCompareFuncSamplerStateListener( ) - : CgIntSamplerStateListener(SST_COMPAREFUNC) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgCompareFuncSamplerStateListener::createState() - { - CgSamplerStateListener::createState(); - - addStateEnumerant((int)CFT_NEVER , "Never"); - addStateEnumerant((int)CFT_LESS , "Less"); - addStateEnumerant((int)CFT_LEQUAL , "LEqual"); - addStateEnumerant((int)CFT_EQUAL , "Equal"); - addStateEnumerant((int)CFT_GREATER , "Greater"); - addStateEnumerant((int)CFT_NOTEQUAL , "NotEqual"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgCompareFuncSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case CFT_NEVER: // Never - case CFT_LESS: // Less - case CFT_LEQUAL: // LEqual - case CFT_EQUAL: // Equal - case CFT_GREATER: // Greater - case CFT_NOTEQUAL: // NotEqual - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgDepthModeSamplerStateListener::CgDepthModeSamplerStateListener() - : CgIntSamplerStateListener(SST_DEPTHMODE) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgDepthModeSamplerStateListener::createState() - { - CgSamplerStateListener::createState(); - - addStateEnumerant((int)DMT_ALPHA , "Alpha"); - addStateEnumerant((int)DMT_INTENSITY , "Intensity"); - addStateEnumerant((int)DMT_LUMINANCE , "Luminance"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgDepthModeSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case DMT_ALPHA: // Alpha - case DMT_INTENSITY: // Intensity - case DMT_LUMINANCE: // Luminance - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgMinFilterSamplerStateListener::CgMinFilterSamplerStateListener() - : CgIntSamplerStateListener(SST_MINFILTER) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgMinFilterSamplerStateListener::createState() - { - CgSamplerStateListener::createState(); - - addStateEnumerant((int)MINFT_NEAREST , "Nearest"); - addStateEnumerant((int)MINFT_LINEAR , "Linear"); - addStateEnumerant((int)MINFT_LINEARMIPMAPNEAREST , "LinearMipMapNearest"); - addStateEnumerant((int)MINFT_NEARESTMIPMAPNEAREST , "NearestMipMapNearest"); - addStateEnumerant((int)MINFT_NEARESTMIPMAPLINEAR , "NearestMipMapLinear"); - addStateEnumerant((int)MINFT_LINEARMIPMAPLINEAR , "LinearMipMapLinear"); - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgMinFilterSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case MINFT_NEAREST: // Nearest - case MINFT_LINEAR: // Linear - case MINFT_LINEARMIPMAPNEAREST: // LinearMipMapNearest - case MINFT_NEARESTMIPMAPNEAREST: // NearestMipMapNearest - case MINFT_NEARESTMIPMAPLINEAR: // NearestMipMapLinear - case MINFT_LINEARMIPMAPLINEAR: // LinearMipMapLinear - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgMagFilterSamplerStateListener::CgMagFilterSamplerStateListener() - : CgIntSamplerStateListener(SST_MAGFILTER) - { - CgSamplerStateListener::createState(); - - addStateEnumerant((int)MAGFT_NEAREST, "Nearest"); - addStateEnumerant((int)MAGFT_LINEAR , "Linear"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgMagFilterSamplerStateListener::createState() - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgMagFilterSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case MAGFT_NEAREST: // Nearest - case MAGFT_LINEAR: // Linear - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgMipFilterSamplerStateListener::CgMipFilterSamplerStateListener() - : CgIntSamplerStateListener(SST_MIPFILTER) - { - CgSamplerStateListener::createState(); - - addStateEnumerant((int)MIPFT_NONE , "None"); - addStateEnumerant((int)MIPFT_POINT , "Point"); - addStateEnumerant((int)MIPFT_LINEAR , "Linear"); - addStateEnumerant((int)MIPFT_ANISOTROPIC , "Nisotropic"); - addStateEnumerant((int)MIPFT_PYRAMIDALQUAD , "PyramidalQuad"); - addStateEnumerant((int)MIPFT_GAUSSIANQUAD , "GaussianQuad"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgMipFilterSamplerStateListener::createState() - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgMipFilterSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - switch( getValue(cgStateAssignment) ) - { - case MIPFT_NONE: // filtering disabled (valid for mip filter only) - case MIPFT_POINT: // nearest - case MIPFT_LINEAR: // linear interpolation - case MIPFT_ANISOTROPIC: // anisotropic - case MIPFT_PYRAMIDALQUAD: // 4-sample tent - case MIPFT_GAUSSIANQUAD: // 4-sample gaussian - default: - // todo - error - break; - } - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - CgFxScriptLoader::CgTextureAddressSamplerStateListener::CgTextureAddressSamplerStateListener( const SamplerStateType samplerStateType ) - : CgIntSamplerStateListener(samplerStateType) - { - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgTextureAddressSamplerStateListener::createState() - { - CgSamplerStateListener::createState(); - - addStateEnumerant((int)TAT_WRAP, "Wrap"); - addStateEnumerant((int)TAT_MIRROR, "Mirror"); - addStateEnumerant((int)TAT_CLAMP, "Clamp"); - addStateEnumerant((int)TAT_BORDER, "Border"); - addStateEnumerant((int)TAT_MIRRORONCE, "MirrorOnce"); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::CgTextureAddressSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) - { - switch( mSamplerStateType ) - { - case SST_ADDRESSU: - case SST_ADDRESSV: - case SST_ADDRESSW: - default: - // todo - error - break; - } - - switch( getValue(cgStateAssignment) ) - { - case TAT_WRAP: // Wrap - case TAT_MIRROR: // Mirror - case TAT_CLAMP: // Clamp - case TAT_BORDER: // Border - case TAT_MIRRORONCE: // MirrorOnce - default: - // todo - error - break; - } - - } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - template<> CgFxScriptLoader *Singleton::msSingleton = 0; + addStateEnumerant((int)MINFT_NEAREST , "Nearest"); + addStateEnumerant((int)MINFT_LINEAR , "Linear"); + addStateEnumerant((int)MINFT_LINEARMIPMAPNEAREST , "LinearMipMapNearest"); + addStateEnumerant((int)MINFT_NEARESTMIPMAPNEAREST , "NearestMipMapNearest"); + addStateEnumerant((int)MINFT_NEARESTMIPMAPLINEAR , "NearestMipMapLinear"); + addStateEnumerant((int)MINFT_LINEARMIPMAPLINEAR , "LinearMipMapLinear"); + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgMinFilterSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case MINFT_NEAREST: // Nearest + case MINFT_LINEAR: // Linear + case MINFT_LINEARMIPMAPNEAREST: // LinearMipMapNearest + case MINFT_NEARESTMIPMAPNEAREST: // NearestMipMapNearest + case MINFT_NEARESTMIPMAPLINEAR: // NearestMipMapLinear + case MINFT_LINEARMIPMAPLINEAR: // LinearMipMapLinear + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgMagFilterSamplerStateListener::CgMagFilterSamplerStateListener() + : CgIntSamplerStateListener(SST_MAGFILTER) + { + CgSamplerStateListener::createState(); + + addStateEnumerant((int)MAGFT_NEAREST, "Nearest"); + addStateEnumerant((int)MAGFT_LINEAR , "Linear"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgMagFilterSamplerStateListener::createState() + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgMagFilterSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case MAGFT_NEAREST: // Nearest + case MAGFT_LINEAR: // Linear + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgMipFilterSamplerStateListener::CgMipFilterSamplerStateListener() + : CgIntSamplerStateListener(SST_MIPFILTER) + { + CgSamplerStateListener::createState(); + + addStateEnumerant((int)MIPFT_NONE , "None"); + addStateEnumerant((int)MIPFT_POINT , "Point"); + addStateEnumerant((int)MIPFT_LINEAR , "Linear"); + addStateEnumerant((int)MIPFT_ANISOTROPIC , "Nisotropic"); + addStateEnumerant((int)MIPFT_PYRAMIDALQUAD , "PyramidalQuad"); + addStateEnumerant((int)MIPFT_GAUSSIANQUAD , "GaussianQuad"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgMipFilterSamplerStateListener::createState() + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgMipFilterSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + switch( getValue(cgStateAssignment) ) + { + case MIPFT_NONE: // filtering disabled (valid for mip filter only) + case MIPFT_POINT: // nearest + case MIPFT_LINEAR: // linear interpolation + case MIPFT_ANISOTROPIC: // anisotropic + case MIPFT_PYRAMIDALQUAD: // 4-sample tent + case MIPFT_GAUSSIANQUAD: // 4-sample gaussian + default: + // todo - error + break; + } + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + CgFxScriptLoader::CgTextureAddressSamplerStateListener::CgTextureAddressSamplerStateListener( const SamplerStateType samplerStateType ) + : CgIntSamplerStateListener(samplerStateType) + { + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgTextureAddressSamplerStateListener::createState() + { + CgSamplerStateListener::createState(); + + addStateEnumerant((int)TAT_WRAP, "Wrap"); + addStateEnumerant((int)TAT_MIRROR, "Mirror"); + addStateEnumerant((int)TAT_CLAMP, "Clamp"); + addStateEnumerant((int)TAT_BORDER, "Border"); + addStateEnumerant((int)TAT_MIRRORONCE, "MirrorOnce"); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::CgTextureAddressSamplerStateListener::upateTextureUnitState( TextureUnitState * ogreTextureUnitState, CGstateassignment cgStateAssignment ) + { + switch( mSamplerStateType ) + { + case SST_ADDRESSU: + case SST_ADDRESSV: + case SST_ADDRESSW: + default: + // todo - error + break; + } + + switch( getValue(cgStateAssignment) ) + { + case TAT_WRAP: // Wrap + case TAT_MIRROR: // Mirror + case TAT_CLAMP: // Clamp + case TAT_BORDER: // Border + case TAT_MIRRORONCE: // MirrorOnce + default: + // todo - error + break; + } + + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + template<> CgFxScriptLoader *Singleton::msSingleton = 0; CgFxScriptLoader* CgFxScriptLoader::getSingletonPtr(void) { return msSingleton; @@ -2650,63 +2650,63 @@ namespace Ogre { { assert( msSingleton ); return ( *msSingleton ); } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- CgFxScriptLoader::CgFxScriptLoader() { - mCgContext = cgCreateContext(); + mCgContext = cgCreateContext(); - mCgStateListenerVector.resize(GST_COUNT); - for (int i = GST_FIRST ; i < GST_COUNT ; i++) - { - const GlobalStateType type = static_cast(i); - CgGlobalStateListener * newState = createCgGlobalStateListener(type); - mCgStateListenerVector[i] = newState; - mCgStateListenerVector[i]->init(); - mCgGlobalStateToListenerMap[mCgStateListenerVector[i]->getCgState()] = newState; - } + mCgStateListenerVector.resize(GST_COUNT); + for (int i = GST_FIRST ; i < GST_COUNT ; i++) + { + const GlobalStateType type = static_cast(i); + CgGlobalStateListener * newState = createCgGlobalStateListener(type); + mCgStateListenerVector[i] = newState; + mCgStateListenerVector[i]->init(); + mCgGlobalStateToListenerMap[mCgStateListenerVector[i]->getCgState()] = newState; + } - mCgSamplerStateListenerVector.resize(SST_COUNT); - for (int i = SST_FIRST ; i < SST_COUNT ; i++) - { - const SamplerStateType type = static_cast(i); - CgSamplerStateListener * newState = createCgSamplerStateListener(type); - mCgSamplerStateListenerVector[i] = newState; - mCgSamplerStateListenerVector[i]->init(); - mCgSamplerStateToListenerMap[mCgSamplerStateListenerVector[i]->getCgState()] = newState; + mCgSamplerStateListenerVector.resize(SST_COUNT); + for (int i = SST_FIRST ; i < SST_COUNT ; i++) + { + const SamplerStateType type = static_cast(i); + CgSamplerStateListener * newState = createCgSamplerStateListener(type); + mCgSamplerStateListenerVector[i] = newState; + mCgSamplerStateListenerVector[i]->init(); + mCgSamplerStateToListenerMap[mCgSamplerStateListenerVector[i]->getCgState()] = newState; - } + } // Scripting is supported by this manager mScriptPatterns.push_back("*.cgfx"); - ResourceGroupManager::getSingleton()._registerScriptLoader(this); + ResourceGroupManager::getSingleton()._registerScriptLoader(this); } //--------------------------------------------------------------------- CgFxScriptLoader::~CgFxScriptLoader() { - for (size_t i = 0 ; i < mCgStateListenerVector.size() ; i++) - { - OGRE_DELETE mCgStateListenerVector[i]; - } + for (size_t i = 0 ; i < mCgStateListenerVector.size() ; i++) + { + OGRE_DELETE mCgStateListenerVector[i]; + } - for (size_t i = 0 ; i < mCgSamplerStateListenerVector.size() ; i++) - { - OGRE_DELETE mCgSamplerStateListenerVector[i]; - } + for (size_t i = 0 ; i < mCgSamplerStateListenerVector.size() ; i++) + { + OGRE_DELETE mCgSamplerStateListenerVector[i]; + } - cgDestroyContext(mCgContext); + cgDestroyContext(mCgContext); - // Unregister with resource group manager - ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); + // Unregister with resource group manager + ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); + } + //--------------------------------------------------------------------- + CGcontext CgFxScriptLoader::getCgContext() const + { + return mCgContext; } - //--------------------------------------------------------------------- - CGcontext CgFxScriptLoader::getCgContext() const - { - return mCgContext; - } //--------------------------------------------------------------------- const StringVector& CgFxScriptLoader::getScriptPatterns(void) const { @@ -2715,117 +2715,117 @@ namespace Ogre { //--------------------------------------------------------------------- Real CgFxScriptLoader::getLoadingOrder(void) const { - // before the normal material manager - so a normal material can inherits from a cgfx material - return 99.0f; + // before the normal material manager - so a normal material can inherits from a cgfx material + return 99.0f; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void CgFxScriptLoader::parseScript( DataStreamPtr& stream, const String& groupName ) { - String streamAsString = stream->getAsString(); - - MaterialPtr ogreMaterial = MaterialManager::getSingleton().create(stream->getName(), groupName); - - String sourceToUse = CgProgram::resolveCgIncludes(streamAsString, ogreMaterial.getPointer(), stream->getName()); - - CGeffect cgEffect = cgCreateEffect(mCgContext, sourceToUse.c_str(), NULL); - checkForCgError("CgFxScriptLoader::parseScript", - "Unable to Create cg Effect: ", mCgContext); - - ogreMaterial->removeAllTechniques(); - parseCgEffect(cgEffect, ogreMaterial); - - cgDestroyEffect(cgEffect); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parseCgEffect( CGeffect cgEffect, MaterialPtr ogreMaterial ) - { - parseCgEffectTechniques(cgEffect, ogreMaterial); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parseCgEffectTechniques( CGeffect cgEffect, MaterialPtr ogreMaterial ) - { - CGtechnique cgTechnique = cgGetFirstTechnique(cgEffect); - while (cgTechnique) - { - Technique * ogreTechnique = ogreMaterial->createTechnique(); - - const char * cgTechniqueName = cgGetTechniqueName(cgTechnique); - if (cgTechniqueName) - { - ogreTechnique->setName(cgTechniqueName); - } - - ogreTechnique->removeAllPasses(); - - parseCgTechnique(cgTechnique, ogreTechnique); - - cgTechnique = cgGetNextTechnique(cgTechnique); - } - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parseCgTechnique( CGtechnique cgTechnique, Technique * ogreTechnique ) - { - CGpass cgPass = cgGetFirstPass(cgTechnique); - while (cgPass) - { - - Pass * ogrePass = ogreTechnique->createPass(); - const char * cgPassName = cgGetPassName(cgPass); - if (cgPassName) - { - ogrePass->setName(cgPassName); - } - - parseCgPass(cgPass, ogrePass); - parseSamplerParameters(cgPass, ogrePass); - - cgPass = cgGetNextPass(cgPass); - } - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parseCgPass( CGpass cgPass, Pass * ogrePass ) - { - parseCgProgram(cgPass, ogrePass, GPT_VERTEX_PROGRAM); - parseCgProgram(cgPass, ogrePass, GPT_FRAGMENT_PROGRAM); - - - parsePassStateAssignments(cgPass, ogrePass); - - - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parseCgProgram( CGpass cgPass, Pass * ogrePass, const GpuProgramType ogreProgramType ) - { - const char *stateName = NULL; - switch(ogreProgramType) - { - case GPT_VERTEX_PROGRAM: - stateName = "VertexProgram"; - break; - case GPT_FRAGMENT_PROGRAM: - stateName = "FragmentProgram"; - break; - case GPT_GEOMETRY_PROGRAM: - stateName = "GeometryProgram"; - break; + String streamAsString = stream->getAsString(); + + MaterialPtr ogreMaterial = MaterialManager::getSingleton().create(stream->getName(), groupName); + + String sourceToUse = CgProgram::resolveCgIncludes(streamAsString, ogreMaterial.getPointer(), stream->getName()); + + CGeffect cgEffect = cgCreateEffect(mCgContext, sourceToUse.c_str(), NULL); + checkForCgError("CgFxScriptLoader::parseScript", + "Unable to Create cg Effect: ", mCgContext); + + ogreMaterial->removeAllTechniques(); + parseCgEffect(cgEffect, ogreMaterial); + + cgDestroyEffect(cgEffect); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parseCgEffect( CGeffect cgEffect, MaterialPtr ogreMaterial ) + { + parseCgEffectTechniques(cgEffect, ogreMaterial); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parseCgEffectTechniques( CGeffect cgEffect, MaterialPtr ogreMaterial ) + { + CGtechnique cgTechnique = cgGetFirstTechnique(cgEffect); + while (cgTechnique) + { + Technique * ogreTechnique = ogreMaterial->createTechnique(); + + const char * cgTechniqueName = cgGetTechniqueName(cgTechnique); + if (cgTechniqueName) + { + ogreTechnique->setName(cgTechniqueName); + } + + ogreTechnique->removeAllPasses(); + + parseCgTechnique(cgTechnique, ogreTechnique); + + cgTechnique = cgGetNextTechnique(cgTechnique); + } + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parseCgTechnique( CGtechnique cgTechnique, Technique * ogreTechnique ) + { + CGpass cgPass = cgGetFirstPass(cgTechnique); + while (cgPass) + { + + Pass * ogrePass = ogreTechnique->createPass(); + const char * cgPassName = cgGetPassName(cgPass); + if (cgPassName) + { + ogrePass->setName(cgPassName); + } + + parseCgPass(cgPass, ogrePass); + parseSamplerParameters(cgPass, ogrePass); + + cgPass = cgGetNextPass(cgPass); + } + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parseCgPass( CGpass cgPass, Pass * ogrePass ) + { + parseCgProgram(cgPass, ogrePass, GPT_VERTEX_PROGRAM); + parseCgProgram(cgPass, ogrePass, GPT_FRAGMENT_PROGRAM); + + + parsePassStateAssignments(cgPass, ogrePass); + + + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parseCgProgram( CGpass cgPass, Pass * ogrePass, const GpuProgramType ogreProgramType ) + { + const char *stateName = NULL; + switch(ogreProgramType) + { + case GPT_VERTEX_PROGRAM: + stateName = "VertexProgram"; + break; + case GPT_FRAGMENT_PROGRAM: + stateName = "FragmentProgram"; + break; + case GPT_GEOMETRY_PROGRAM: + stateName = "GeometryProgram"; + break; case GPT_COMPUTE_PROGRAM: case GPT_DOMAIN_PROGRAM: case GPT_HULL_PROGRAM: break; - } - CGstateassignment cgStateAssignment = cgGetNamedStateAssignment(cgPass, stateName); - if (!cgStateAssignment) - { - switch(ogreProgramType) - { - case GPT_VERTEX_PROGRAM: - stateName = "VertexShader"; - break; - case GPT_FRAGMENT_PROGRAM: - stateName = "PixelShader"; - break; + } + CGstateassignment cgStateAssignment = cgGetNamedStateAssignment(cgPass, stateName); + if (!cgStateAssignment) + { + switch(ogreProgramType) + { + case GPT_VERTEX_PROGRAM: + stateName = "VertexShader"; + break; + case GPT_FRAGMENT_PROGRAM: + stateName = "PixelShader"; + break; case GPT_GEOMETRY_PROGRAM: stateName = "GeometryShader"; break; @@ -2833,1500 +2833,1500 @@ namespace Ogre { case GPT_DOMAIN_PROGRAM: case GPT_HULL_PROGRAM: break; - } - - cgStateAssignment = cgGetNamedStateAssignment(cgPass, stateName); - if (!cgStateAssignment) - { - return; - } - } - - - - CGprogram cgProgram = cgGetProgramStateAssignmentValue(cgStateAssignment); - - CGparameter cgParameter = cgGetFirstParameter(cgProgram, CG_PROGRAM); - while (cgParameter) - { - String paramName = cgGetParameterName(cgParameter); - cgParameter = cgGetNextParameter(cgParameter); - } - - - const char * source = cgGetProgramString(cgProgram, CG_PROGRAM_SOURCE); - const char * entry = cgGetProgramString(cgProgram, CG_PROGRAM_ENTRY); - const char * profile = cgGetProgramString(cgProgram, CG_PROGRAM_PROFILE); - - // The name is all the path to this shader combined with the entry point and profile so it will be unique. - StringStream programName; - programName << ogrePass->getParent()->getParent()->getName() << "|"; // Material - programName << entry << "|"; // entry - programName << profile << "|"; // profile - programName << (ogrePass->getParent()->getParent()->getNumTechniques() - 1) << "-"; // Technique number - programName << ogrePass->getParent()->getName() << "|"; // Technique - programName << (ogrePass->getParent()->getNumPasses() - 1) << "-"; // Pass number - programName << ogrePass->getName(); // Pass - - String ProgramNameAsString = programName.str(); - - HighLevelGpuProgramPtr ogreProgram = - HighLevelGpuProgramManager::getSingleton(). - createProgram(ProgramNameAsString, - ogrePass->getParent()->getParent()->getGroup(), - "cg", - ogreProgramType); - - ogreProgram->setSource(source); - ogreProgram->setParameter("entry_point", entry); - ogreProgram->setParameter("profiles", profile); - - //ogreProgram->load(); - if (ogreProgram->isSupported()) - { - - ogreProgram->load(); - ogreProgram->createParameters(); - - GpuProgramParametersSharedPtr ogreProgramParameters = ogreProgram->getDefaultParameters(); - parseCgProgramParameters(cgPass, ogreProgramParameters); - - switch(ogreProgramType) - { - case GPT_VERTEX_PROGRAM: - ogrePass->setVertexProgram(ogreProgram->getName()); - break; - case GPT_FRAGMENT_PROGRAM: - ogrePass->setFragmentProgram(ogreProgram->getName()); - break; - case GPT_GEOMETRY_PROGRAM: - ogrePass->setGeometryProgram(ogreProgram->getName()); - break; + } + + cgStateAssignment = cgGetNamedStateAssignment(cgPass, stateName); + if (!cgStateAssignment) + { + return; + } + } + + + + CGprogram cgProgram = cgGetProgramStateAssignmentValue(cgStateAssignment); + + CGparameter cgParameter = cgGetFirstParameter(cgProgram, CG_PROGRAM); + while (cgParameter) + { + String paramName = cgGetParameterName(cgParameter); + cgParameter = cgGetNextParameter(cgParameter); + } + + + const char * source = cgGetProgramString(cgProgram, CG_PROGRAM_SOURCE); + const char * entry = cgGetProgramString(cgProgram, CG_PROGRAM_ENTRY); + const char * profile = cgGetProgramString(cgProgram, CG_PROGRAM_PROFILE); + + // The name is all the path to this shader combined with the entry point and profile so it will be unique. + StringStream programName; + programName << ogrePass->getParent()->getParent()->getName() << "|"; // Material + programName << entry << "|"; // entry + programName << profile << "|"; // profile + programName << (ogrePass->getParent()->getParent()->getNumTechniques() - 1) << "-"; // Technique number + programName << ogrePass->getParent()->getName() << "|"; // Technique + programName << (ogrePass->getParent()->getNumPasses() - 1) << "-"; // Pass number + programName << ogrePass->getName(); // Pass + + String ProgramNameAsString = programName.str(); + + HighLevelGpuProgramPtr ogreProgram = + HighLevelGpuProgramManager::getSingleton(). + createProgram(ProgramNameAsString, + ogrePass->getParent()->getParent()->getGroup(), + "cg", + ogreProgramType); + + ogreProgram->setSource(source); + ogreProgram->setParameter("entry_point", entry); + ogreProgram->setParameter("profiles", profile); + + //ogreProgram->load(); + if (ogreProgram->isSupported()) + { + + ogreProgram->load(); + ogreProgram->createParameters(); + + GpuProgramParametersSharedPtr ogreProgramParameters = ogreProgram->getDefaultParameters(); + parseCgProgramParameters(cgPass, ogreProgramParameters); + + switch(ogreProgramType) + { + case GPT_VERTEX_PROGRAM: + ogrePass->setVertexProgram(ogreProgram->getName()); + break; + case GPT_FRAGMENT_PROGRAM: + ogrePass->setFragmentProgram(ogreProgram->getName()); + break; + case GPT_GEOMETRY_PROGRAM: + ogrePass->setGeometryProgram(ogreProgram->getName()); + break; case GPT_DOMAIN_PROGRAM: case GPT_COMPUTE_PROGRAM: case GPT_HULL_PROGRAM: break; - } - - } - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parseCgProgramParameters( CGpass cgPass, GpuProgramParametersSharedPtr ogreProgramParameters ) - { - CGeffect cgEffect = cgGetTechniqueEffect(cgGetPassTechnique(cgPass)); - - GpuConstantDefinitionIterator constIt = ogreProgramParameters->getConstantDefinitionIterator(); - while(constIt.hasMoreElements()) - { - // get the constant definition - const String& ogreParamName = constIt.peekNextKey(); - constIt.getNext(); - - CGparameter cgParameter = cgGetNamedEffectParameter(cgEffect, ogreParamName.c_str()); - // try to find it without case - if (!cgParameter) - { - CGparameter cgParameterToFind = cgGetFirstEffectParameter(cgEffect); - String ogreParamNameLower = ogreParamName; - Ogre::StringUtil::toLowerCase(ogreParamNameLower); - - while (cgParameterToFind) - { - String cgParamNameLower = cgGetParameterName(cgParameterToFind); - Ogre::StringUtil::toLowerCase(cgParamNameLower); - - if (cgParamNameLower == ogreParamNameLower) - { - cgParameter = cgParameterToFind; - break; - } - - cgParameterToFind = cgGetNextParameter(cgParameterToFind); - } - - } - if (cgParameter) - { - parseCgProgramParameter(cgParameter, ogreProgramParameters, ogreParamName); - } - else - { - // todo - some kind of error - } - } - - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parseCgProgramParameter( CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ) - { - - bool isAutoConstant = - parseAutoConstantParam(cgParameter, - ogreProgramParameters, - ogreParamName); - - if (!isAutoConstant) - { - - CGtype cgParamType = cgGetParameterType(cgParameter); - CGtype cgParameterBaseType = cgGetParameterBaseType(cgParameter); - - switch(cgParameterBaseType) - { - case CG_FLOAT: - parseFloatCgProgramParameter(cgParamType, cgParameter, ogreProgramParameters, ogreParamName); - break; - case CG_INT: - parseIntCgProgramParameter(cgParamType, cgParameter, ogreProgramParameters, ogreParamName); - break; - case CG_BOOL: - // todo - break; - case CG_FIXED: - // todo - break; - case CG_HALF: - // todo - break; - default: - // todo error - break; - - } - } - - } - //--------------------------------------------------------------------- - CgFxScriptLoader::FXSemanticID CgFxScriptLoader::cgSemanticStringToType( const char * cgParamSemantic ) - { - String sem = cgParamSemantic; - Ogre::StringUtil::toLowerCase(sem); - - if ("none" == sem) return FXS_NONE; - if ("unknown" == sem) return FXS_UNKNOWN; - if ("position" == sem) return FXS_POSITION; - if ("direction" == sem) return FXS_DIRECTION; - if ("color" == sem) return FXS_COLOR; - if ("diffuse" == sem) return FXS_DIFFUSE; - if ("specular" == sem) return FXS_SPECULAR; - if ("ambient" == sem) return FXS_AMBIENT; - if ("emission" == sem) return FXS_EMISSION; - if ("emissive" == sem) return FXS_EMISSIVE; - if ("specularpower" == sem) return FXS_SPECULARPOWER; - if ("refraction" == sem) return FXS_REFRACTION; - if ("opacity" == sem) return FXS_OPACITY; - if ("environment" == sem) return FXS_ENVIRONMENT; - if ("environmentnormal" == sem) return FXS_ENVIRONMENTNORMAL; - if ("normal" == sem) return FXS_NORMAL; - if ("height" == sem) return FXS_HEIGHT; - if ("attenuation" == sem) return FXS_ATTENUATION; - if ("rendercolortarget" == sem) return FXS_RENDERCOLORTARGET; - if ("renderdepthstenciltarget" == sem) return FXS_RENDERDEPTHSTENCILTARGET; - if ("viewportpixelsize" == sem) return FXS_VIEWPORTPIXELSIZE; - if ("cameraposition" == sem) return FXS_CAMERAPOSITION; - if ("time" == sem) return FXS_TIME; - if ("elapsedtime" == sem) return FXS_ELAPSEDTIME; - if ("animationtime" == sem) return FXS_ANIMATIONTIME; - if ("animationtick" == sem) return FXS_ANIMATIONTICK; - if ("mouseposition" == sem) return FXS_MOUSEPOSITION; - if ("leftmousedown" == sem) return FXS_LEFTMOUSEDOWN; - if ("world" == sem) return FXS_WORLD; - if ("view" == sem) return FXS_VIEW; - if ("projection" == sem) return FXS_PROJECTION; - if ("worldtranspose" == sem) return FXS_WORLDTRANSPOSE; - if ("viewtranspose" == sem) return FXS_VIEWTRANSPOSE; - if ("projectiontranspose" == sem) return FXS_PROJECTIONTRANSPOSE; - if ("worldview" == sem) return FXS_WORLDVIEW; - if ("worldviewprojection" == sem) return FXS_WORLDVIEWPROJECTION; - if ("worldinverse" == sem) return FXS_WORLDINVERSE; - if ("viewinverse" == sem) return FXS_VIEWINVERSE; - if ("projectioninverse" == sem) return FXS_PROJECTIONINVERSE; - if ("worldinversetranspose" == sem) return FXS_WORLDINVERSETRANSPOSE; - if ("viewinversetranspose" == sem) return FXS_VIEWINVERSETRANSPOSE; - if ("projectioninversetranspose" == sem) return FXS_PROJECTIONINVERSETRANSPOSE; - if ("worldviewinverse" == sem) return FXS_WORLDVIEWINVERSE; - if ("worldviewtranspose" == sem) return FXS_WORLDVIEWTRANSPOSE; - if ("worldviewinversetranspose" == sem) return FXS_WORLDVIEWINVERSETRANSPOSE; - if ("worldviewprojectioninverse" == sem) return FXS_WORLDVIEWPROJECTIONINVERSE; - if ("worldviewprojectiontranspose" == sem) return FXS_WORLDVIEWPROJECTIONTRANSPOSE; - if ("worldviewprojectioninversetranspose" == sem) return FXS_WORLDVIEWPROJECTIONINVERSETRANSPOSE; - if ("viewprojection" == sem) return FXS_VIEWPROJECTION; - if ("viewprojectiontranspose" == sem) return FXS_VIEWPROJECTIONTRANSPOSE; - if ("viewprojectioninverse" == sem) return FXS_VIEWPROJECTIONINVERSE; - if ("viewprojectioninversetranspose" == sem) return FXS_VIEWPROJECTIONINVERSETRANSPOSE; - if ("fxcomposer_resetpulse" == sem) return FXS_FXCOMPOSER_RESETPULSE; - if ("standardsglobal" == sem) return FXS_STANDARDSGLOBAL; - if ("unitsscale" == sem) return FXS_UNITSSCALE; - if ("power" == sem) return FXS_POWER; - if ("diffusemap" == sem) return FXS_DIFFUSEMAP; - if ("specularmap" == sem) return FXS_SPECULARMAP; - if ("envmap" == sem) return FXS_ENVMAP; - if ("lightposition" == sem) return FXS_LIGHTPOSITION; - if ("transform" == sem) return FXS_TRANSFORM; - if ("user" == sem) return FXS_USER; - if ("constantattenuation" == sem) return FXS_CONSTANTATTENUATION; - if ("linearattenuation" == sem) return FXS_LINEARATTENUATION; - if ("quadraticattenuation" == sem) return FXS_QUADRATICATTENUATION; - if ("falloffangle" == sem) return FXS_FALLOFFANGLE; - if ("falloffexponent" == sem) return FXS_FALLOFFEXPONENT; - if ("boundingradius" == sem) return FXS_BOUNDINGRADIUS; - - return FXS_UNKNOWN; - } - //--------------------------------------------------------------------- - const char * CgFxScriptLoader::getGlobalStateNameTypeToString( const GlobalStateType cgStateName ) - { - switch(cgStateName) - { - case GST_ALPHABLENDENABLE: return "AlphaBlendEnable"; - case GST_ALPHAFUNC: return "AlphaFunc"; - case GST_ALPHAREF: return "AlphaRef"; - case GST_BLENDOP: return "BlendOp"; - case GST_BLENDEQUATION: return "BlendEquation"; - case GST_BLENDFUNC: return "BlendFunc"; - case GST_BLENDFUNCSEPARATE: return "BlendFuncSeparate"; - case GST_BLENDEQUATIONSEPARATE: return "BlendEquationSeparate"; - case GST_BLENDCOLOR: return "BlendColor"; - case GST_CLEARCOLOR: return "ClearColor"; - case GST_CLEARSTENCIL: return "ClearStencil"; - case GST_CLEARDEPTH: return "ClearDepth"; - case GST_CLIPPLANE: return "ClipPlane"; - case GST_CLIPPLANEENABLE: return "ClipPlaneEnable"; - case GST_COLORWRITEENABLE: return "ColorWriteEnable"; - case GST_COLORMASK: return "ColorMask"; - case GST_COLORVERTEX: return "ColorVertex"; - case GST_COLORMATERIAL: return "ColorMaterial"; - case GST_COLORMATRIX: return "ColorMatrix"; - case GST_COLORTRANSFORM: return "ColorTransform"; - case GST_CULLFACE: return "CullFace"; - case GST_CULLMODE: return "CullMode"; - case GST_DEPTHBOUNDS: return "DepthBounds"; - case GST_DEPTHBIAS: return "DepthBias"; - case GST_DESTBLEND: return "DestBlend"; - case GST_DEPTHFUNC: return "DepthFunc"; - case GST_ZFUNC: return "ZFunc"; - case GST_DEPTHMASK: return "DepthMask"; - case GST_ZWRITEENABLE: return "ZWriteEnable"; - case GST_DEPTHRANGE: return "DepthRange"; - case GST_FOGDISTANCEMODE: return "FogDistanceMode"; - case GST_FOGMODE: return "FogMode"; - case GST_FOGTABLEMODE: return "FogTableMode"; - case GST_INDEXEDVERTEXBLENDENABLE: return "IndexedVertexBlendEnable"; - case GST_FOGDENSITY: return "FogDensity"; - case GST_FOGSTART: return "FogStart"; - case GST_FOGEND: return "FogEnd"; - case GST_FOGCOLOR: return "FogColor"; - case GST_FRAGMENTENVPARAMETER: return "FragmentEnvParameter"; - case GST_FRAGMENTLOCALPARAMETER: return "FragmentLocalParameter"; - case GST_FOGCOORDSRC: return "FogCoordSrc"; - case GST_FOGVERTEXMODE: return "FogVertexMode"; - case GST_FRONTFACE: return "FrontFace"; - case GST_LIGHTMODELAMBIENT: return "LightModelAmbient"; - case GST_AMBIENT: return "Ambient"; - case GST_LIGHTINGENABLE: return "LightingEnable"; - case GST_LIGHTENABLE: return "LightEnable"; - case GST_LIGHTAMBIENT: return "LightAmbient"; - case GST_LIGHTCONSTANTATTENUATION: return "LightConstantAttenuation"; - case GST_LIGHTATTENUATION0: return "LightAttenuation0"; - case GST_LIGHTDIFFUSE: return "LightDiffuse"; - case GST_LIGHTLINEARATTENUATION: return "LightLinearAttenuation"; - case GST_LIGHTATTENUATION1: return "LightAttenuation1"; - case GST_LIGHTPOSITION: return "LightPosition"; - case GST_LIGHTQUADRATICATTENUATION: return "LightQuadraticAttenuation"; - case GST_LIGHTATTENUATION2: return "LightAttenuation2"; - case GST_LIGHTSPECULAR: return "LightSpecular"; - case GST_LIGHTSPOTCUTOFF: return "LightSpotCutoff"; - case GST_LIGHTFALLOFF: return "LightFalloff"; - case GST_LIGHTSPOTDIRECTION: return "LightSpotDirection"; - case GST_LIGHTDIRECTION: return "LightDirection"; - case GST_LIGHTSPOTEXPONENT: return "LightSpotExponent"; - case GST_LIGHTPHI: return "LightPhi"; - case GST_LIGHTRANGE: return "LightRange"; - case GST_LIGHTTHETA: return "LightTheta"; - case GST_LIGHTTYPE: return "LightType"; - case GST_LOCALVIEWER: return "LocalViewer"; - case GST_MULTISAMPLEANTIALIAS: return "MultiSampleAntialias"; - case GST_MULTISAMPLEMASK: return "MultiSampleMask"; - case GST_PATCHSEGMENTS: return "PatchSegments"; - case GST_POINTSCALE_A: return "PointScale_A"; - case GST_POINTSCALE_B: return "PointScale_B"; - case GST_POINTSCALE_C: return "PointScale_C"; - case GST_POINTSCALEENABLE: return "PointScaleEnable"; - case GST_RANGEFOGENABLE: return "RangeFogEnable"; - case GST_SPECULARENABLE: return "SpecularEnable"; - case GST_TWEENFACTOR: return "TweenFactor"; - case GST_VERTEXBLEND: return "VertexBlend"; - case GST_AMBIENTMATERIALSOURCE: return "AmbientMaterialSource"; - case GST_DIFFUSEMATERIALSOURCE: return "DiffuseMaterialSource"; - case GST_EMISSIVEMATERIALSOURCE: return "EmissiveMaterialSource"; - case GST_SPECULARMATERIALSOURCE: return "SpecularMaterialSource"; - case GST_CLIPPING: return "Clipping"; - case GST_LIGHTMODELCOLORCONTROL: return "LightModelColorControl"; - case GST_LINESTIPPLE: return "LineStipple"; - case GST_LINEWIDTH: return "LineWidth"; - case GST_LOGICOP: return "LogicOp"; - case GST_MATERIALAMBIENT: return "MaterialAmbient"; - case GST_MATERIALDIFFUSE: return "MaterialDiffuse"; - case GST_MATERIALEMISSION: return "MaterialEmission"; - case GST_MATERIALEMISSIVE: return "MaterialEmissive"; - case GST_MATERIALSHININESS: return "MaterialShininess"; - case GST_MATERIALPOWER: return "MaterialPower"; - case GST_MATERIALSPECULAR: return "MaterialSpecular"; - case GST_MODELVIEWMATRIX: return "ModelViewMatrix"; - case GST_MODELVIEWTRANSFORM: return "ModelViewTransform"; - case GST_VIEWTRANSFORM: return "ViewTransform"; - case GST_WORLDTRANSFORM: return "WorldTransform"; - case GST_POINTDISTANCEATTENUATION: return "PointDistanceAttenuation"; - case GST_POINTFADETHRESHOLDSIZE: return "PointFadeThresholdSize"; - case GST_POINTSIZE: return "PointSize"; - case GST_POINTSIZEMIN: return "PointSizeMin"; - case GST_POINTSIZEMAX: return "PointSizeMax"; - case GST_POINTSPRITECOORDORIGIN: return "PointSpriteCoordOrigin"; - case GST_POINTSPRITECOORDREPLACE: return "PointSpriteCoordReplace"; - case GST_POINTSPRITERMODE: return "PointSpriteRMode"; - case GST_POLYGONMODE: return "PolygonMode"; - case GST_FILLMODE: return "FillMode"; - case GST_LASTPIXEL: return "LastPixel"; - case GST_POLYGONOFFSET: return "PolygonOffset"; - case GST_PROJECTIONMATRIX: return "ProjectionMatrix"; - case GST_PROJECTIONTRANSFORM: return "ProjectionTransform"; - case GST_SCISSOR: return "Scissor"; - case GST_SHADEMODEL: return "ShadeModel"; - case GST_SHADEMODE: return "ShadeMode"; - case GST_SLOPSCALEDEPTHBIAS: return "SlopScaleDepthBias"; - case GST_SRCBLEND: return "SrcBlend"; - case GST_STENCILFUNC: return "StencilFunc"; - case GST_STENCILMASK: return "StencilMask"; - case GST_STENCILPASS: return "StencilPass"; - case GST_STENCILREF: return "StencilRef"; - case GST_STENCILWRITEMASK: return "StencilWriteMask"; - case GST_STENCILZFAIL: return "StencilZFail"; - case GST_TEXTUREFACTOR: return "TextureFactor"; - case GST_STENCILOP: return "StencilOp"; - case GST_STENCILFUNCSEPARATE: return "StencilFuncSeparate"; - case GST_STENCILMASKSEPARATE: return "StencilMaskSeparate"; - case GST_STENCILOPSEPARATE: return "StencilOpSeparate"; - case GST_TEXGENSMODE: return "TexGenSMode"; - case GST_TEXGENSOBJECTPLANE: return "TexGenSObjectPlane"; - case GST_TEXGENSEYEPLANE: return "TexGenSEyePlane"; - case GST_TEXGENTMODE: return "TexGenTMode"; - case GST_TEXGENTOBJECTPLANE: return "TexGenTObjectPlane"; - case GST_TEXGENTEYEPLANE: return "TexGenTEyePlane"; - case GST_TEXGENRMODE: return "TexGenRMode"; - case GST_TEXGENROBJECTPLANE: return "TexGenRObjectPlane"; - case GST_TEXGENREYEPLANE: return "TexGenREyePlane"; - case GST_TEXGENQMODE: return "TexGenQMode"; - case GST_TEXGENQOBJECTPLANE: return "TexGenQObjectPlane"; - case GST_TEXGENQEYEPLANE: return "TexGenQEyePlane"; - case GST_TEXTUREENVCOLOR: return "TextureEnvColor"; - case GST_TEXTUREENVMODE: return "TextureEnvMode"; - case GST_TEXTURE1D: return "Texture1D"; - case GST_TEXTURE2D: return "Texture2D"; - case GST_TEXTURE3D: return "Texture3D"; - case GST_TEXTURERECTANGLE: return "TextureRectangle"; - case GST_TEXTURECUBEMAP: return "TextureCubeMap"; - case GST_TEXTURE1DENABLE: return "Texture1DEnable"; - case GST_TEXTURE2DENABLE: return "Texture2DEnable"; - case GST_TEXTURE3DENABLE: return "Texture3DEnable"; - case GST_TEXTURERECTANGLEENABLE: return "TextureRectangleEnable"; - case GST_TEXTURECUBEMAPENABLE: return "TextureCubeMapEnable"; - case GST_TEXTURETRANSFORM: return "TextureTransform"; - case GST_TEXTUREMATRIX: return "TextureMatrix"; - case GST_VERTEXENVPARAMETER: return "VertexEnvParameter"; - case GST_VERTEXLOCALPARAMETER: return "VertexLocalParameter"; - case GST_ALPHATESTENABLE: return "AlphaTestEnable"; - case GST_AUTONORMALENABLE: return "AutoNormalEnable"; - case GST_BLENDENABLE: return "BlendEnable"; - case GST_COLORLOGICOPENABLE: return "ColorLogicOpEnable"; - case GST_CULLFACEENABLE: return "CullFaceEnable"; - case GST_DEPTHBOUNDSENABLE: return "DepthBoundsEnable"; - case GST_DEPTHCLAMPENABLE: return "DepthClampEnable"; - case GST_DEPTHTESTENABLE: return "DepthTestEnable"; - case GST_ZENABLE: return "ZEnable"; - case GST_DITHERENABLE: return "DitherEnable"; - case GST_FOGENABLE: return "FogEnable"; - case GST_LIGHTMODELLOCALVIEWERENABLE: return "LightModelLocalViewerEnable"; - case GST_LIGHTMODELTWOSIDEENABLE: return "LightModelTwoSideEnable"; - case GST_LINESMOOTHENABLE: return "LineSmoothEnable"; - case GST_LINESTIPPLEENABLE: return "LineStippleEnable"; - case GST_LOGICOPENABLE: return "LogicOpEnable"; - case GST_MULTISAMPLEENABLE: return "MultisampleEnable"; - case GST_NORMALIZEENABLE: return "NormalizeEnable"; - case GST_POINTSMOOTHENABLE: return "PointSmoothEnable"; - case GST_POINTSPRITEENABLE: return "PointSpriteEnable"; - case GST_POLYGONOFFSETFILLENABLE: return "PolygonOffsetFillEnable"; - case GST_POLYGONOFFSETLINEENABLE: return "PolygonOffsetLineEnable"; - case GST_POLYGONOFFSETPOINTENABLE: return "PolygonOffsetPointEnable"; - case GST_POLYGONSMOOTHENABLE: return "PolygonSmoothEnable"; - case GST_POLYGONSTIPPLEENABLE: return "PolygonStippleEnable"; - case GST_RESCALENORMALENABLE: return "RescaleNormalEnable"; - case GST_SAMPLEALPHATOCOVERAGEENABLE: return "SampleAlphaToCoverageEnable"; - case GST_SAMPLEALPHATOONEENABLE: return "SampleAlphaToOneEnable"; - case GST_SAMPLECOVERAGEENABLE: return "SampleCoverageEnable"; - case GST_SCISSORTESTENABLE: return "ScissorTestEnable"; - case GST_STENCILTESTENABLE: return "StencilTestEnable"; - case GST_STENCILENABLE: return "StencilEnable"; - case GST_STENCILTESTTWOSIDEENABLE: return "StencilTestTwoSideEnable"; - case GST_STENCILFAIL: return "StencilFail"; - case GST_TEXGENSENABLE: return "TexGenSEnable"; - case GST_TEXGENTENABLE: return "TexGenTEnable"; - case GST_TEXGENRENABLE: return "TexGenREnable"; - case GST_TEXGENQENABLE: return "TexGenQEnable"; - case GST_WRAP0: return "Wrap0"; - case GST_WRAP1: return "Wrap1"; - case GST_WRAP2: return "Wrap2"; - case GST_WRAP3: return "Wrap3"; - case GST_WRAP4: return "Wrap4"; - case GST_WRAP5: return "Wrap5"; - case GST_WRAP6: return "Wrap6"; - case GST_WRAP7: return "Wrap7"; - case GST_WRAP8: return "Wrap8"; - case GST_WRAP9: return "Wrap9"; - case GST_WRAP10: return "Wrap10"; - case GST_WRAP11: return "Wrap11"; - case GST_WRAP12: return "Wrap12"; - case GST_WRAP13: return "Wrap13"; - case GST_WRAP14: return "Wrap14"; - case GST_WRAP15: return "Wrap15"; - case GST_VERTEXPROGRAMPOINTSIZEENABLE: return "VertexProgramPointSizeEnable"; - case GST_VERTEXPROGRAMTWOSIDEENABLE: return "VertexProgramTwoSideEnable"; - case GST_GEOMETRYPROGRAM: return "GeometryProgram"; - case GST_VERTEXPROGRAM: return "VertexProgram"; - case GST_FRAGMENTPROGRAM: return "FragmentProgram"; - case GST_VERTEXSHADER: return "VertexShader"; - case GST_PIXELSHADER: return "PixelShader"; - case GST_ALPHAOP: return "AlphaOp"; - case GST_ALPHAARG0: return "AlphaArg0"; - case GST_ALPHAARG1: return "AlphaArg1"; - case GST_ALPHAARG2: return "AlphaArg2"; - case GST_COLORARG0: return "ColorArg0"; - case GST_COLORARG1: return "ColorArg1"; - case GST_COLORARG2: return "ColorArg2"; - case GST_COLOROP: return "ColorOp"; - case GST_BUMPENVLSCALE: return "BumpEnvLScale"; - case GST_BUMPENVLOFFSET: return "BumpEnvLOffset"; - case GST_BUMPENVMAT00: return "BumpEnvMat00"; - case GST_BUMPENVMAT01: return "BumpEnvMat01"; - case GST_BUMPENVMAT10: return "BumpEnvMat10"; - case GST_BUMPENVMAT11: return "BumpEnvMat11"; - case GST_RESULTARG: return "ResultArg"; - case GST_TEXCOORDINDEX: return "TexCoordIndex"; - case GST_TEXTURETRANSFORMFLAGS: return "TextureTransformFlags"; - case GST_TWOSIDEDSTENCILMODE: return "TwoSidedStencilMode"; - case GST_SEPARATEALPHABLENDENABLE: return "SeparateAlphaBlendEnable"; - case GST_NORMALIZENORMALS: return "NormalizeNormals"; - case GST_LIGHTING: return "Lighting"; - case GST_PIXELSHADERCONSTANTB: return "PixelShaderConstantB"; - case GST_VERTEXSHADERCONSTANTB: return "VertexShaderConstantB"; - case GST_COLORWRITEENABLE1: return "ColorWriteEnable1"; - case GST_COLORWRITEENABLE2: return "ColorWriteEnable2"; - case GST_COLORWRITEENABLE3: return "ColorWriteEnable3"; - case GST_PIXELSHADERCONSTANT1: return "PixelShaderConstant1"; - case GST_VERTEXSHADERCONSTANT1: return "VertexShaderConstant1"; - case GST_PIXELSHADERCONSTANTF: return "PixelShaderConstantF"; - case GST_VERTEXSHADERCONSTANTF: return "VertexShaderConstantF"; - case GST_PIXELSHADERCONSTANT2: return "PixelShaderConstant2"; - case GST_VERTEXSHADERCONSTANT2: return "VertexShaderConstant2"; - case GST_PIXELSHADERCONSTANT3: return "PixelShaderConstant3"; - case GST_VERTEXSHADERCONSTANT3: return "VertexShaderConstant3"; - case GST_PIXELSHADERCONSTANT: return "PixelShaderConstant"; - case GST_VERTEXSHADERCONSTANT: return "VertexShaderConstant"; - case GST_PIXELSHADERCONSTANT4: return "PixelShaderConstant4"; - case GST_VERTEXSHADERCONSTANT4: return "VertexShaderConstant4"; - case GST_PIXELSHADERCONSTANTI: return "PixelShaderConstantI"; - case GST_VERTEXSHADERCONSTANTI: return "VertexShaderConstantI"; - case GST_SAMPLER: return "Sampler"; - case GST_TEXTURE: return "Texture"; - case GST_ADDRESSU: return "AddressU"; - case GST_ADDRESSV: return "AddressV"; - case GST_ADDRESSW: return "AddressW"; - case GST_BORDERCOLOR: return "BorderColor"; - case GST_MAXANISOTROPY: return "MaxAnisotropy"; - case GST_MAXMIPLEVEL: return "MaxMipLevel"; - case GST_MINFILTER: return "MinFilter"; - case GST_MAGFILTER: return "MagFilter"; - case GST_MIPFILTER: return "MipFilter"; - case GST_MIPMAPLODBIAS: return "MipMapLodBias"; - case GST_BLENDOPALPHA: return "BlendOpAlpha"; - case GST_SRCBLENDALPHA: return "SrcBlendAlpha"; - case GST_DESTBLENDALPHA: return "DestBlendAlpha"; - - case GST_UNKNOWN: - default: - return "unknown"; - } - - } - //--------------------------------------------------------------------- - const char * CgFxScriptLoader::getSamplerStateNameTypeToString( const SamplerStateType cgStateName ) - { - switch(cgStateName) - { - case SST_TEXTURE: return "Texture"; - case SST_ADDRESSU: return "AddressU"; - case SST_ADDRESSV: return "AddressV"; - case SST_ADDRESSW: return "AddressW"; - case SST_WRAPS: return "WrapS"; - case SST_WRAPT: return "WrapT"; - case SST_WRAPR: return "WrapR"; - case SST_MIPFILTER: return "MipFilter"; - case SST_MIPMAPLODBIAS: return "MipMapLodBias"; - case SST_LODBIAS: return "LODBias"; - case SST_SRGBTEXTURE: return "SRGBTexture"; - case SST_MINFILTER: return "MinFilter"; - case SST_MAGFILTER: return "MagFilter"; - case SST_BORDERCOLOR: return "BorderColor"; - case SST_MINMIPLEVEL: return "MinMipLevel"; - case SST_MAXMIPLEVEL: return "MaxMipLevel"; - case SST_MAXANISOTROPY: return "MaxAnisotropy"; - case SST_DEPTHMODE: return "DepthMode"; - case SST_COMPAREMODE: return "CompareMode"; - case SST_COMPAREFUNC: return "CompareFunc"; - case SST_GENERATEMIPMAP: return "GenerateMipmap"; - case SST_UNKNOWN: - default: - return "unknown"; - } - - } - //--------------------------------------------------------------------- - bool CgFxScriptLoader::cgSemanticToOgreAutoConstantType( const char * cgParamSemantic, const char * uiNameValue, GpuProgramParameters::AutoConstantType & ogreAutoConstantType, size_t & extraInfo ) - { - extraInfo = 0; - - FXSemanticID cgFXSemanticID = cgSemanticStringToType(cgParamSemantic); - switch(cgFXSemanticID) - { - case FXS_NONE: - return false; - case FXS_COLOR: - // todo - add to ogre - return false; - case FXS_DIFFUSE: - ogreAutoConstantType = GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR; - return true; - case FXS_SPECULAR: - ogreAutoConstantType = GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR; - return true; - case FXS_AMBIENT: - ogreAutoConstantType = GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR; - return true; - case FXS_EMISSION: - // todo - add to ogre - return false; - case FXS_EMISSIVE: - ogreAutoConstantType = GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR; - return true; - case FXS_SPECULARPOWER: - // todo - add to ogre - return false; - case FXS_REFRACTION: - // todo - add to ogre - return false; - case FXS_OPACITY: - // todo - add to ogre - return false; - case FXS_ENVIRONMENT: - // todo - add to ogre - return false; - case FXS_ENVIRONMENTNORMAL: - // todo - add to ogre - return false; - case FXS_NORMAL: - // todo - add to ogre - return false; - case FXS_HEIGHT: - // todo - add to ogre - return false; - case FXS_ATTENUATION: - // todo - in ogre ACT_LIGHT_ATTENUATION is float4 and we need float3 here - return false; - case FXS_RENDERCOLORTARGET: - // todo - add to ogre - return false; - case FXS_RENDERDEPTHSTENCILTARGET: - // todo - add to ogre - return false; - case FXS_VIEWPORTPIXELSIZE: - // todo - add to ogre - return false; - case FXS_CAMERAPOSITION: - ogreAutoConstantType = GpuProgramParameters::ACT_CAMERA_POSITION; - return true; - case FXS_TIME: - // todo - possibly this value is has the wrong units... - ogreAutoConstantType = GpuProgramParameters::ACT_TIME; - return true; - case FXS_ELAPSEDTIME: - // todo - possibly this value is has the wrong units... - ogreAutoConstantType = GpuProgramParameters::ACT_FRAME_TIME; - return true; - case FXS_ANIMATIONTIME: - // todo - add to ogre - return false; - case FXS_ANIMATIONTICK: - // todo - add to ogre - return false; - case FXS_MOUSEPOSITION: - // todo - add to ogre - return false; - case FXS_LEFTMOUSEDOWN: - // todo - add to ogre - return false; - case FXS_WORLD: - ogreAutoConstantType = GpuProgramParameters::ACT_WORLD_MATRIX; - return true; - case FXS_VIEW: - ogreAutoConstantType = GpuProgramParameters::ACT_VIEW_MATRIX; - return true; - case FXS_PROJECTION: - ogreAutoConstantType = GpuProgramParameters::ACT_PROJECTION_MATRIX; - return true; - case FXS_WORLDTRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_WORLD_MATRIX; - return true; - case FXS_VIEWTRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_VIEW_MATRIX; - return true; - case FXS_PROJECTIONTRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_PROJECTION_MATRIX; - return true; - case FXS_WORLDVIEW: - ogreAutoConstantType = GpuProgramParameters::ACT_WORLDVIEW_MATRIX; - return true; - case FXS_WORLDVIEWPROJECTION: - ogreAutoConstantType = GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX; - return true; - case FXS_WORLDINVERSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_WORLD_MATRIX; - return true; - case FXS_VIEWINVERSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_VIEW_MATRIX; - return true; - case FXS_PROJECTIONINVERSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_PROJECTION_MATRIX; - return true; - case FXS_WORLDINVERSETRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX; - return true; - case FXS_VIEWINVERSETRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_VIEW_MATRIX; - return true; - case FXS_PROJECTIONINVERSETRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_PROJECTION_MATRIX; - return true; - case FXS_WORLDVIEWINVERSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_WORLDVIEW_MATRIX; - return true; - case FXS_WORLDVIEWTRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_WORLDVIEW_MATRIX; - return true; - case FXS_WORLDVIEWINVERSETRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX; - return true; - case FXS_WORLDVIEWPROJECTIONINVERSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_WORLDVIEWPROJ_MATRIX; - return true; - case FXS_WORLDVIEWPROJECTIONTRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_WORLDVIEWPROJ_MATRIX; - return true; - case FXS_WORLDVIEWPROJECTIONINVERSETRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEWPROJ_MATRIX; - return true; - case FXS_VIEWPROJECTION: - ogreAutoConstantType = GpuProgramParameters::ACT_VIEWPROJ_MATRIX; - return true; - case FXS_VIEWPROJECTIONTRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_VIEWPROJ_MATRIX; - return true; - case FXS_VIEWPROJECTIONINVERSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_VIEWPROJ_MATRIX; - return true; - case FXS_VIEWPROJECTIONINVERSETRANSPOSE: - ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_VIEWPROJ_MATRIX; - return true; - case FXS_FXCOMPOSER_RESETPULSE: - // todo - add to ogre - return false; - case FXS_STANDARDSGLOBAL: - // todo - add to ogre - return false; - case FXS_UNITSSCALE: - // todo - add to ogre - return false; - case FXS_POWER: - // todo - add to ogre - return false; - case FXS_DIFFUSEMAP: - // todo - add to ogre - return false; - case FXS_SPECULARMAP: - // todo - add to ogre - return false; - case FXS_ENVMAP: - // todo - add to ogre - return false; - case FXS_LIGHTPOSITION: - // todo - ACT_LIGHT_POSITION - return false; - case FXS_TRANSFORM: - // todo - add to ogre - return false; - case FXS_USER: - // todo - add to ogre - return false; - case FXS_CONSTANTATTENUATION: - // todo - add to ogre - return false; - case FXS_LINEARATTENUATION: - // todo - add to ogre - return false; - case FXS_QUADRATICATTENUATION: - // todo - add to ogre - return false; - case FXS_FALLOFFANGLE: - // todo - add to ogre - return false; - case FXS_FALLOFFEXPONENT: - // todo - add to ogre - return false; - case FXS_BOUNDINGRADIUS: - // todo - add to ogre - return false; - case FXS_POSITION: - case FXS_DIRECTION: - case FXS_UNKNOWN: - if (uiNameValue) - { - String uiNameValueAsString(uiNameValue); - String theWordLight = "Light"; - if (StringUtil::startsWith(uiNameValueAsString, theWordLight, false)) - { - size_t firstSpacePos = uiNameValueAsString.find(" "); - if (firstSpacePos > 0) - { - String lightNumberAsString = uiNameValueAsString.substr(theWordLight.size(), firstSpacePos - theWordLight.size()); - - size_t lightNumber = StringConverter::parseInt(lightNumberAsString); - extraInfo = lightNumber; - - String colorPart = uiNameValueAsString.substr(firstSpacePos + 1); - if ( colorPart == "Color" ) // float4 - { - ogreAutoConstantType = GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR; - return true; - } - if ( colorPart == "Intensity" ) // float - { - ogreAutoConstantType = GpuProgramParameters::ACT_LIGHT_POWER_SCALE; - return true; - } - if ( colorPart == "Light_position" ) // float3 - { - ogreAutoConstantType = GpuProgramParameters::ACT_LIGHT_POSITION; - return true; - } - if ( colorPart == "Light_direction" ) // float3 - { - ogreAutoConstantType = GpuProgramParameters::ACT_LIGHT_DIRECTION; - return true; - } - if ( colorPart == "Distance Falloff Exponent" ) // float - { - //ogreAutoConstantType = todo: add to GpuProgramParameters; - return false; - } - if ( colorPart == "Distance Falloff Start" ) // float - { - //ogreAutoConstantType = todo: add to GpuProgramParameters; - return false; - } - if ( colorPart == "Light1 Distance Falloff Limit" ) // float - { - //ogreAutoConstantType = todo: add to GpuProgramParameters; - return false; - } - if ( colorPart == "Distance Scale" ) // float - { - //ogreAutoConstantType = todo: add to GpuProgramParameters; - return false; - } - if ( colorPart == "Spread Inner" ) // float - { - //ogreAutoConstantType = todo: add to GpuProgramParameters; - return false; - } - if ( colorPart == "Spread Falloff" ) // float - { - //ogreAutoConstantType = todo: add to GpuProgramParameters; - return false; - } - if ( colorPart == "Light_spread_cos" ) // float - { - //ogreAutoConstantType = todo: add to GpuProgramParameters; - return false; - } - } - - } - else // some other light params - { - if ( uiNameValueAsString == "Diffuse Scalar" ) // float - { - //ogreAutoConstantType = todo: add to GpuProgramParameters; - return false; - } - if ( uiNameValueAsString == "Specular Color" ) // float4 - { - ogreAutoConstantType = GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR; - return true; - } - if ( uiNameValueAsString == "Specular Scalar" ) // float - { - //ogreAutoConstantType = todo: add to GpuProgramParameters; - return false; - } - if ( uiNameValueAsString == "Specular Shininess" ) // float - { - //ogreAutoConstantType = todo: add to GpuProgramParameters; - return false; - } - } - } - return false; - default: - return false; - } - - } - - //--------------------------------------------------------------------- - bool CgFxScriptLoader::parseAutoConstantParam( CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ) - { - const char * cgParamSemantic = cgGetParameterSemantic(cgParameter); - CGannotation parameterAnnotation = cgGetFirstParameterAnnotation(cgParameter); - const char * uiNameValue = 0; - while(parameterAnnotation) - { - const char * annotationName = cgGetAnnotationName(parameterAnnotation); - if( strcmp("UIName", annotationName) == 0 ) - { - uiNameValue = cgGetStringAnnotationValue(parameterAnnotation); - } - parameterAnnotation = cgGetNextAnnotation(parameterAnnotation); - } - - bool isAutoConstant = false; - if (cgParamSemantic) - { - GpuProgramParameters::AutoConstantType ogreAutoConstantType; - size_t extraInfo = 0; - bool autoConstantTypeFound = cgSemanticToOgreAutoConstantType(cgParamSemantic, uiNameValue, ogreAutoConstantType, extraInfo); - if (autoConstantTypeFound) - { - isAutoConstant = true; - } - else - { - // todo - an error? - } - if (isAutoConstant) - { - ogreProgramParameters->setNamedAutoConstant(ogreParamName, ogreAutoConstantType, extraInfo); - } - } - return isAutoConstant; - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parseFloatCgProgramParameter( CGtype cgParamType, CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ) - { - float cgParamValue[4*4] = { - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f - }; - int paramSize = 0; - switch(cgParamType) - { - case CG_FLOAT: - paramSize = 1; - break; - case CG_FLOAT2: - paramSize = 2; - break; - case CG_FLOAT3: - paramSize = 3; - break; - case CG_FLOAT4: - paramSize = 4; - break; - case CG_FLOAT1x1: - paramSize = 1*1; - break; - case CG_FLOAT1x2: - paramSize = 1*2; - break; - case CG_FLOAT1x3: - paramSize = 1*3; - break; - case CG_FLOAT1x4: - paramSize = 1*4; - break; - case CG_FLOAT2x1: - paramSize = 2*1; - break; - case CG_FLOAT2x2: - paramSize = 2*2; - break; - case CG_FLOAT2x3: - paramSize = 2*3; - break; - case CG_FLOAT2x4: - paramSize = 2*4; - break; - case CG_FLOAT3x1: - paramSize = 3*1; - break; - case CG_FLOAT3x2: - paramSize = 3*2; - break; - case CG_FLOAT3x3: - paramSize = 3*3; - break; - case CG_FLOAT3x4: - paramSize = 3*4; - break; - case CG_FLOAT4x1: - paramSize = 4*1; - break; - case CG_FLOAT4x2: - paramSize = 4*2; - break; - case CG_FLOAT4x3: - paramSize = 4*3; - break; - case CG_FLOAT4x4: - paramSize = 4*4; - break; - default: + } + + } + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parseCgProgramParameters( CGpass cgPass, GpuProgramParametersSharedPtr ogreProgramParameters ) + { + CGeffect cgEffect = cgGetTechniqueEffect(cgGetPassTechnique(cgPass)); + + GpuConstantDefinitionIterator constIt = ogreProgramParameters->getConstantDefinitionIterator(); + while(constIt.hasMoreElements()) + { + // get the constant definition + const String& ogreParamName = constIt.peekNextKey(); + constIt.getNext(); + + CGparameter cgParameter = cgGetNamedEffectParameter(cgEffect, ogreParamName.c_str()); + // try to find it without case + if (!cgParameter) + { + CGparameter cgParameterToFind = cgGetFirstEffectParameter(cgEffect); + String ogreParamNameLower = ogreParamName; + Ogre::StringUtil::toLowerCase(ogreParamNameLower); + + while (cgParameterToFind) + { + String cgParamNameLower = cgGetParameterName(cgParameterToFind); + Ogre::StringUtil::toLowerCase(cgParamNameLower); + + if (cgParamNameLower == ogreParamNameLower) + { + cgParameter = cgParameterToFind; + break; + } + + cgParameterToFind = cgGetNextParameter(cgParameterToFind); + } + + } + if (cgParameter) + { + parseCgProgramParameter(cgParameter, ogreProgramParameters, ogreParamName); + } + else + { + // todo - some kind of error + } + } + + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parseCgProgramParameter( CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ) + { + + bool isAutoConstant = + parseAutoConstantParam(cgParameter, + ogreProgramParameters, + ogreParamName); + + if (!isAutoConstant) + { + + CGtype cgParamType = cgGetParameterType(cgParameter); + CGtype cgParameterBaseType = cgGetParameterBaseType(cgParameter); + + switch(cgParameterBaseType) + { + case CG_FLOAT: + parseFloatCgProgramParameter(cgParamType, cgParameter, ogreProgramParameters, ogreParamName); + break; + case CG_INT: + parseIntCgProgramParameter(cgParamType, cgParameter, ogreProgramParameters, ogreParamName); + break; + case CG_BOOL: + // todo + break; + case CG_FIXED: + // todo + break; + case CG_HALF: + // todo + break; + default: + // todo error + break; + + } + } + + } + //--------------------------------------------------------------------- + CgFxScriptLoader::FXSemanticID CgFxScriptLoader::cgSemanticStringToType( const char * cgParamSemantic ) + { + String sem = cgParamSemantic; + Ogre::StringUtil::toLowerCase(sem); + + if ("none" == sem) return FXS_NONE; + if ("unknown" == sem) return FXS_UNKNOWN; + if ("position" == sem) return FXS_POSITION; + if ("direction" == sem) return FXS_DIRECTION; + if ("color" == sem) return FXS_COLOR; + if ("diffuse" == sem) return FXS_DIFFUSE; + if ("specular" == sem) return FXS_SPECULAR; + if ("ambient" == sem) return FXS_AMBIENT; + if ("emission" == sem) return FXS_EMISSION; + if ("emissive" == sem) return FXS_EMISSIVE; + if ("specularpower" == sem) return FXS_SPECULARPOWER; + if ("refraction" == sem) return FXS_REFRACTION; + if ("opacity" == sem) return FXS_OPACITY; + if ("environment" == sem) return FXS_ENVIRONMENT; + if ("environmentnormal" == sem) return FXS_ENVIRONMENTNORMAL; + if ("normal" == sem) return FXS_NORMAL; + if ("height" == sem) return FXS_HEIGHT; + if ("attenuation" == sem) return FXS_ATTENUATION; + if ("rendercolortarget" == sem) return FXS_RENDERCOLORTARGET; + if ("renderdepthstenciltarget" == sem) return FXS_RENDERDEPTHSTENCILTARGET; + if ("viewportpixelsize" == sem) return FXS_VIEWPORTPIXELSIZE; + if ("cameraposition" == sem) return FXS_CAMERAPOSITION; + if ("time" == sem) return FXS_TIME; + if ("elapsedtime" == sem) return FXS_ELAPSEDTIME; + if ("animationtime" == sem) return FXS_ANIMATIONTIME; + if ("animationtick" == sem) return FXS_ANIMATIONTICK; + if ("mouseposition" == sem) return FXS_MOUSEPOSITION; + if ("leftmousedown" == sem) return FXS_LEFTMOUSEDOWN; + if ("world" == sem) return FXS_WORLD; + if ("view" == sem) return FXS_VIEW; + if ("projection" == sem) return FXS_PROJECTION; + if ("worldtranspose" == sem) return FXS_WORLDTRANSPOSE; + if ("viewtranspose" == sem) return FXS_VIEWTRANSPOSE; + if ("projectiontranspose" == sem) return FXS_PROJECTIONTRANSPOSE; + if ("worldview" == sem) return FXS_WORLDVIEW; + if ("worldviewprojection" == sem) return FXS_WORLDVIEWPROJECTION; + if ("worldinverse" == sem) return FXS_WORLDINVERSE; + if ("viewinverse" == sem) return FXS_VIEWINVERSE; + if ("projectioninverse" == sem) return FXS_PROJECTIONINVERSE; + if ("worldinversetranspose" == sem) return FXS_WORLDINVERSETRANSPOSE; + if ("viewinversetranspose" == sem) return FXS_VIEWINVERSETRANSPOSE; + if ("projectioninversetranspose" == sem) return FXS_PROJECTIONINVERSETRANSPOSE; + if ("worldviewinverse" == sem) return FXS_WORLDVIEWINVERSE; + if ("worldviewtranspose" == sem) return FXS_WORLDVIEWTRANSPOSE; + if ("worldviewinversetranspose" == sem) return FXS_WORLDVIEWINVERSETRANSPOSE; + if ("worldviewprojectioninverse" == sem) return FXS_WORLDVIEWPROJECTIONINVERSE; + if ("worldviewprojectiontranspose" == sem) return FXS_WORLDVIEWPROJECTIONTRANSPOSE; + if ("worldviewprojectioninversetranspose" == sem) return FXS_WORLDVIEWPROJECTIONINVERSETRANSPOSE; + if ("viewprojection" == sem) return FXS_VIEWPROJECTION; + if ("viewprojectiontranspose" == sem) return FXS_VIEWPROJECTIONTRANSPOSE; + if ("viewprojectioninverse" == sem) return FXS_VIEWPROJECTIONINVERSE; + if ("viewprojectioninversetranspose" == sem) return FXS_VIEWPROJECTIONINVERSETRANSPOSE; + if ("fxcomposer_resetpulse" == sem) return FXS_FXCOMPOSER_RESETPULSE; + if ("standardsglobal" == sem) return FXS_STANDARDSGLOBAL; + if ("unitsscale" == sem) return FXS_UNITSSCALE; + if ("power" == sem) return FXS_POWER; + if ("diffusemap" == sem) return FXS_DIFFUSEMAP; + if ("specularmap" == sem) return FXS_SPECULARMAP; + if ("envmap" == sem) return FXS_ENVMAP; + if ("lightposition" == sem) return FXS_LIGHTPOSITION; + if ("transform" == sem) return FXS_TRANSFORM; + if ("user" == sem) return FXS_USER; + if ("constantattenuation" == sem) return FXS_CONSTANTATTENUATION; + if ("linearattenuation" == sem) return FXS_LINEARATTENUATION; + if ("quadraticattenuation" == sem) return FXS_QUADRATICATTENUATION; + if ("falloffangle" == sem) return FXS_FALLOFFANGLE; + if ("falloffexponent" == sem) return FXS_FALLOFFEXPONENT; + if ("boundingradius" == sem) return FXS_BOUNDINGRADIUS; + + return FXS_UNKNOWN; + } + //--------------------------------------------------------------------- + const char * CgFxScriptLoader::getGlobalStateNameTypeToString( const GlobalStateType cgStateName ) + { + switch(cgStateName) + { + case GST_ALPHABLENDENABLE: return "AlphaBlendEnable"; + case GST_ALPHAFUNC: return "AlphaFunc"; + case GST_ALPHAREF: return "AlphaRef"; + case GST_BLENDOP: return "BlendOp"; + case GST_BLENDEQUATION: return "BlendEquation"; + case GST_BLENDFUNC: return "BlendFunc"; + case GST_BLENDFUNCSEPARATE: return "BlendFuncSeparate"; + case GST_BLENDEQUATIONSEPARATE: return "BlendEquationSeparate"; + case GST_BLENDCOLOR: return "BlendColor"; + case GST_CLEARCOLOR: return "ClearColor"; + case GST_CLEARSTENCIL: return "ClearStencil"; + case GST_CLEARDEPTH: return "ClearDepth"; + case GST_CLIPPLANE: return "ClipPlane"; + case GST_CLIPPLANEENABLE: return "ClipPlaneEnable"; + case GST_COLORWRITEENABLE: return "ColorWriteEnable"; + case GST_COLORMASK: return "ColorMask"; + case GST_COLORVERTEX: return "ColorVertex"; + case GST_COLORMATERIAL: return "ColorMaterial"; + case GST_COLORMATRIX: return "ColorMatrix"; + case GST_COLORTRANSFORM: return "ColorTransform"; + case GST_CULLFACE: return "CullFace"; + case GST_CULLMODE: return "CullMode"; + case GST_DEPTHBOUNDS: return "DepthBounds"; + case GST_DEPTHBIAS: return "DepthBias"; + case GST_DESTBLEND: return "DestBlend"; + case GST_DEPTHFUNC: return "DepthFunc"; + case GST_ZFUNC: return "ZFunc"; + case GST_DEPTHMASK: return "DepthMask"; + case GST_ZWRITEENABLE: return "ZWriteEnable"; + case GST_DEPTHRANGE: return "DepthRange"; + case GST_FOGDISTANCEMODE: return "FogDistanceMode"; + case GST_FOGMODE: return "FogMode"; + case GST_FOGTABLEMODE: return "FogTableMode"; + case GST_INDEXEDVERTEXBLENDENABLE: return "IndexedVertexBlendEnable"; + case GST_FOGDENSITY: return "FogDensity"; + case GST_FOGSTART: return "FogStart"; + case GST_FOGEND: return "FogEnd"; + case GST_FOGCOLOR: return "FogColor"; + case GST_FRAGMENTENVPARAMETER: return "FragmentEnvParameter"; + case GST_FRAGMENTLOCALPARAMETER: return "FragmentLocalParameter"; + case GST_FOGCOORDSRC: return "FogCoordSrc"; + case GST_FOGVERTEXMODE: return "FogVertexMode"; + case GST_FRONTFACE: return "FrontFace"; + case GST_LIGHTMODELAMBIENT: return "LightModelAmbient"; + case GST_AMBIENT: return "Ambient"; + case GST_LIGHTINGENABLE: return "LightingEnable"; + case GST_LIGHTENABLE: return "LightEnable"; + case GST_LIGHTAMBIENT: return "LightAmbient"; + case GST_LIGHTCONSTANTATTENUATION: return "LightConstantAttenuation"; + case GST_LIGHTATTENUATION0: return "LightAttenuation0"; + case GST_LIGHTDIFFUSE: return "LightDiffuse"; + case GST_LIGHTLINEARATTENUATION: return "LightLinearAttenuation"; + case GST_LIGHTATTENUATION1: return "LightAttenuation1"; + case GST_LIGHTPOSITION: return "LightPosition"; + case GST_LIGHTQUADRATICATTENUATION: return "LightQuadraticAttenuation"; + case GST_LIGHTATTENUATION2: return "LightAttenuation2"; + case GST_LIGHTSPECULAR: return "LightSpecular"; + case GST_LIGHTSPOTCUTOFF: return "LightSpotCutoff"; + case GST_LIGHTFALLOFF: return "LightFalloff"; + case GST_LIGHTSPOTDIRECTION: return "LightSpotDirection"; + case GST_LIGHTDIRECTION: return "LightDirection"; + case GST_LIGHTSPOTEXPONENT: return "LightSpotExponent"; + case GST_LIGHTPHI: return "LightPhi"; + case GST_LIGHTRANGE: return "LightRange"; + case GST_LIGHTTHETA: return "LightTheta"; + case GST_LIGHTTYPE: return "LightType"; + case GST_LOCALVIEWER: return "LocalViewer"; + case GST_MULTISAMPLEANTIALIAS: return "MultiSampleAntialias"; + case GST_MULTISAMPLEMASK: return "MultiSampleMask"; + case GST_PATCHSEGMENTS: return "PatchSegments"; + case GST_POINTSCALE_A: return "PointScale_A"; + case GST_POINTSCALE_B: return "PointScale_B"; + case GST_POINTSCALE_C: return "PointScale_C"; + case GST_POINTSCALEENABLE: return "PointScaleEnable"; + case GST_RANGEFOGENABLE: return "RangeFogEnable"; + case GST_SPECULARENABLE: return "SpecularEnable"; + case GST_TWEENFACTOR: return "TweenFactor"; + case GST_VERTEXBLEND: return "VertexBlend"; + case GST_AMBIENTMATERIALSOURCE: return "AmbientMaterialSource"; + case GST_DIFFUSEMATERIALSOURCE: return "DiffuseMaterialSource"; + case GST_EMISSIVEMATERIALSOURCE: return "EmissiveMaterialSource"; + case GST_SPECULARMATERIALSOURCE: return "SpecularMaterialSource"; + case GST_CLIPPING: return "Clipping"; + case GST_LIGHTMODELCOLORCONTROL: return "LightModelColorControl"; + case GST_LINESTIPPLE: return "LineStipple"; + case GST_LINEWIDTH: return "LineWidth"; + case GST_LOGICOP: return "LogicOp"; + case GST_MATERIALAMBIENT: return "MaterialAmbient"; + case GST_MATERIALDIFFUSE: return "MaterialDiffuse"; + case GST_MATERIALEMISSION: return "MaterialEmission"; + case GST_MATERIALEMISSIVE: return "MaterialEmissive"; + case GST_MATERIALSHININESS: return "MaterialShininess"; + case GST_MATERIALPOWER: return "MaterialPower"; + case GST_MATERIALSPECULAR: return "MaterialSpecular"; + case GST_MODELVIEWMATRIX: return "ModelViewMatrix"; + case GST_MODELVIEWTRANSFORM: return "ModelViewTransform"; + case GST_VIEWTRANSFORM: return "ViewTransform"; + case GST_WORLDTRANSFORM: return "WorldTransform"; + case GST_POINTDISTANCEATTENUATION: return "PointDistanceAttenuation"; + case GST_POINTFADETHRESHOLDSIZE: return "PointFadeThresholdSize"; + case GST_POINTSIZE: return "PointSize"; + case GST_POINTSIZEMIN: return "PointSizeMin"; + case GST_POINTSIZEMAX: return "PointSizeMax"; + case GST_POINTSPRITECOORDORIGIN: return "PointSpriteCoordOrigin"; + case GST_POINTSPRITECOORDREPLACE: return "PointSpriteCoordReplace"; + case GST_POINTSPRITERMODE: return "PointSpriteRMode"; + case GST_POLYGONMODE: return "PolygonMode"; + case GST_FILLMODE: return "FillMode"; + case GST_LASTPIXEL: return "LastPixel"; + case GST_POLYGONOFFSET: return "PolygonOffset"; + case GST_PROJECTIONMATRIX: return "ProjectionMatrix"; + case GST_PROJECTIONTRANSFORM: return "ProjectionTransform"; + case GST_SCISSOR: return "Scissor"; + case GST_SHADEMODEL: return "ShadeModel"; + case GST_SHADEMODE: return "ShadeMode"; + case GST_SLOPSCALEDEPTHBIAS: return "SlopScaleDepthBias"; + case GST_SRCBLEND: return "SrcBlend"; + case GST_STENCILFUNC: return "StencilFunc"; + case GST_STENCILMASK: return "StencilMask"; + case GST_STENCILPASS: return "StencilPass"; + case GST_STENCILREF: return "StencilRef"; + case GST_STENCILWRITEMASK: return "StencilWriteMask"; + case GST_STENCILZFAIL: return "StencilZFail"; + case GST_TEXTUREFACTOR: return "TextureFactor"; + case GST_STENCILOP: return "StencilOp"; + case GST_STENCILFUNCSEPARATE: return "StencilFuncSeparate"; + case GST_STENCILMASKSEPARATE: return "StencilMaskSeparate"; + case GST_STENCILOPSEPARATE: return "StencilOpSeparate"; + case GST_TEXGENSMODE: return "TexGenSMode"; + case GST_TEXGENSOBJECTPLANE: return "TexGenSObjectPlane"; + case GST_TEXGENSEYEPLANE: return "TexGenSEyePlane"; + case GST_TEXGENTMODE: return "TexGenTMode"; + case GST_TEXGENTOBJECTPLANE: return "TexGenTObjectPlane"; + case GST_TEXGENTEYEPLANE: return "TexGenTEyePlane"; + case GST_TEXGENRMODE: return "TexGenRMode"; + case GST_TEXGENROBJECTPLANE: return "TexGenRObjectPlane"; + case GST_TEXGENREYEPLANE: return "TexGenREyePlane"; + case GST_TEXGENQMODE: return "TexGenQMode"; + case GST_TEXGENQOBJECTPLANE: return "TexGenQObjectPlane"; + case GST_TEXGENQEYEPLANE: return "TexGenQEyePlane"; + case GST_TEXTUREENVCOLOR: return "TextureEnvColor"; + case GST_TEXTUREENVMODE: return "TextureEnvMode"; + case GST_TEXTURE1D: return "Texture1D"; + case GST_TEXTURE2D: return "Texture2D"; + case GST_TEXTURE3D: return "Texture3D"; + case GST_TEXTURERECTANGLE: return "TextureRectangle"; + case GST_TEXTURECUBEMAP: return "TextureCubeMap"; + case GST_TEXTURE1DENABLE: return "Texture1DEnable"; + case GST_TEXTURE2DENABLE: return "Texture2DEnable"; + case GST_TEXTURE3DENABLE: return "Texture3DEnable"; + case GST_TEXTURERECTANGLEENABLE: return "TextureRectangleEnable"; + case GST_TEXTURECUBEMAPENABLE: return "TextureCubeMapEnable"; + case GST_TEXTURETRANSFORM: return "TextureTransform"; + case GST_TEXTUREMATRIX: return "TextureMatrix"; + case GST_VERTEXENVPARAMETER: return "VertexEnvParameter"; + case GST_VERTEXLOCALPARAMETER: return "VertexLocalParameter"; + case GST_ALPHATESTENABLE: return "AlphaTestEnable"; + case GST_AUTONORMALENABLE: return "AutoNormalEnable"; + case GST_BLENDENABLE: return "BlendEnable"; + case GST_COLORLOGICOPENABLE: return "ColorLogicOpEnable"; + case GST_CULLFACEENABLE: return "CullFaceEnable"; + case GST_DEPTHBOUNDSENABLE: return "DepthBoundsEnable"; + case GST_DEPTHCLAMPENABLE: return "DepthClampEnable"; + case GST_DEPTHTESTENABLE: return "DepthTestEnable"; + case GST_ZENABLE: return "ZEnable"; + case GST_DITHERENABLE: return "DitherEnable"; + case GST_FOGENABLE: return "FogEnable"; + case GST_LIGHTMODELLOCALVIEWERENABLE: return "LightModelLocalViewerEnable"; + case GST_LIGHTMODELTWOSIDEENABLE: return "LightModelTwoSideEnable"; + case GST_LINESMOOTHENABLE: return "LineSmoothEnable"; + case GST_LINESTIPPLEENABLE: return "LineStippleEnable"; + case GST_LOGICOPENABLE: return "LogicOpEnable"; + case GST_MULTISAMPLEENABLE: return "MultisampleEnable"; + case GST_NORMALIZEENABLE: return "NormalizeEnable"; + case GST_POINTSMOOTHENABLE: return "PointSmoothEnable"; + case GST_POINTSPRITEENABLE: return "PointSpriteEnable"; + case GST_POLYGONOFFSETFILLENABLE: return "PolygonOffsetFillEnable"; + case GST_POLYGONOFFSETLINEENABLE: return "PolygonOffsetLineEnable"; + case GST_POLYGONOFFSETPOINTENABLE: return "PolygonOffsetPointEnable"; + case GST_POLYGONSMOOTHENABLE: return "PolygonSmoothEnable"; + case GST_POLYGONSTIPPLEENABLE: return "PolygonStippleEnable"; + case GST_RESCALENORMALENABLE: return "RescaleNormalEnable"; + case GST_SAMPLEALPHATOCOVERAGEENABLE: return "SampleAlphaToCoverageEnable"; + case GST_SAMPLEALPHATOONEENABLE: return "SampleAlphaToOneEnable"; + case GST_SAMPLECOVERAGEENABLE: return "SampleCoverageEnable"; + case GST_SCISSORTESTENABLE: return "ScissorTestEnable"; + case GST_STENCILTESTENABLE: return "StencilTestEnable"; + case GST_STENCILENABLE: return "StencilEnable"; + case GST_STENCILTESTTWOSIDEENABLE: return "StencilTestTwoSideEnable"; + case GST_STENCILFAIL: return "StencilFail"; + case GST_TEXGENSENABLE: return "TexGenSEnable"; + case GST_TEXGENTENABLE: return "TexGenTEnable"; + case GST_TEXGENRENABLE: return "TexGenREnable"; + case GST_TEXGENQENABLE: return "TexGenQEnable"; + case GST_WRAP0: return "Wrap0"; + case GST_WRAP1: return "Wrap1"; + case GST_WRAP2: return "Wrap2"; + case GST_WRAP3: return "Wrap3"; + case GST_WRAP4: return "Wrap4"; + case GST_WRAP5: return "Wrap5"; + case GST_WRAP6: return "Wrap6"; + case GST_WRAP7: return "Wrap7"; + case GST_WRAP8: return "Wrap8"; + case GST_WRAP9: return "Wrap9"; + case GST_WRAP10: return "Wrap10"; + case GST_WRAP11: return "Wrap11"; + case GST_WRAP12: return "Wrap12"; + case GST_WRAP13: return "Wrap13"; + case GST_WRAP14: return "Wrap14"; + case GST_WRAP15: return "Wrap15"; + case GST_VERTEXPROGRAMPOINTSIZEENABLE: return "VertexProgramPointSizeEnable"; + case GST_VERTEXPROGRAMTWOSIDEENABLE: return "VertexProgramTwoSideEnable"; + case GST_GEOMETRYPROGRAM: return "GeometryProgram"; + case GST_VERTEXPROGRAM: return "VertexProgram"; + case GST_FRAGMENTPROGRAM: return "FragmentProgram"; + case GST_VERTEXSHADER: return "VertexShader"; + case GST_PIXELSHADER: return "PixelShader"; + case GST_ALPHAOP: return "AlphaOp"; + case GST_ALPHAARG0: return "AlphaArg0"; + case GST_ALPHAARG1: return "AlphaArg1"; + case GST_ALPHAARG2: return "AlphaArg2"; + case GST_COLORARG0: return "ColorArg0"; + case GST_COLORARG1: return "ColorArg1"; + case GST_COLORARG2: return "ColorArg2"; + case GST_COLOROP: return "ColorOp"; + case GST_BUMPENVLSCALE: return "BumpEnvLScale"; + case GST_BUMPENVLOFFSET: return "BumpEnvLOffset"; + case GST_BUMPENVMAT00: return "BumpEnvMat00"; + case GST_BUMPENVMAT01: return "BumpEnvMat01"; + case GST_BUMPENVMAT10: return "BumpEnvMat10"; + case GST_BUMPENVMAT11: return "BumpEnvMat11"; + case GST_RESULTARG: return "ResultArg"; + case GST_TEXCOORDINDEX: return "TexCoordIndex"; + case GST_TEXTURETRANSFORMFLAGS: return "TextureTransformFlags"; + case GST_TWOSIDEDSTENCILMODE: return "TwoSidedStencilMode"; + case GST_SEPARATEALPHABLENDENABLE: return "SeparateAlphaBlendEnable"; + case GST_NORMALIZENORMALS: return "NormalizeNormals"; + case GST_LIGHTING: return "Lighting"; + case GST_PIXELSHADERCONSTANTB: return "PixelShaderConstantB"; + case GST_VERTEXSHADERCONSTANTB: return "VertexShaderConstantB"; + case GST_COLORWRITEENABLE1: return "ColorWriteEnable1"; + case GST_COLORWRITEENABLE2: return "ColorWriteEnable2"; + case GST_COLORWRITEENABLE3: return "ColorWriteEnable3"; + case GST_PIXELSHADERCONSTANT1: return "PixelShaderConstant1"; + case GST_VERTEXSHADERCONSTANT1: return "VertexShaderConstant1"; + case GST_PIXELSHADERCONSTANTF: return "PixelShaderConstantF"; + case GST_VERTEXSHADERCONSTANTF: return "VertexShaderConstantF"; + case GST_PIXELSHADERCONSTANT2: return "PixelShaderConstant2"; + case GST_VERTEXSHADERCONSTANT2: return "VertexShaderConstant2"; + case GST_PIXELSHADERCONSTANT3: return "PixelShaderConstant3"; + case GST_VERTEXSHADERCONSTANT3: return "VertexShaderConstant3"; + case GST_PIXELSHADERCONSTANT: return "PixelShaderConstant"; + case GST_VERTEXSHADERCONSTANT: return "VertexShaderConstant"; + case GST_PIXELSHADERCONSTANT4: return "PixelShaderConstant4"; + case GST_VERTEXSHADERCONSTANT4: return "VertexShaderConstant4"; + case GST_PIXELSHADERCONSTANTI: return "PixelShaderConstantI"; + case GST_VERTEXSHADERCONSTANTI: return "VertexShaderConstantI"; + case GST_SAMPLER: return "Sampler"; + case GST_TEXTURE: return "Texture"; + case GST_ADDRESSU: return "AddressU"; + case GST_ADDRESSV: return "AddressV"; + case GST_ADDRESSW: return "AddressW"; + case GST_BORDERCOLOR: return "BorderColor"; + case GST_MAXANISOTROPY: return "MaxAnisotropy"; + case GST_MAXMIPLEVEL: return "MaxMipLevel"; + case GST_MINFILTER: return "MinFilter"; + case GST_MAGFILTER: return "MagFilter"; + case GST_MIPFILTER: return "MipFilter"; + case GST_MIPMAPLODBIAS: return "MipMapLodBias"; + case GST_BLENDOPALPHA: return "BlendOpAlpha"; + case GST_SRCBLENDALPHA: return "SrcBlendAlpha"; + case GST_DESTBLENDALPHA: return "DestBlendAlpha"; + + case GST_UNKNOWN: + default: + return "unknown"; + } + + } + //--------------------------------------------------------------------- + const char * CgFxScriptLoader::getSamplerStateNameTypeToString( const SamplerStateType cgStateName ) + { + switch(cgStateName) + { + case SST_TEXTURE: return "Texture"; + case SST_ADDRESSU: return "AddressU"; + case SST_ADDRESSV: return "AddressV"; + case SST_ADDRESSW: return "AddressW"; + case SST_WRAPS: return "WrapS"; + case SST_WRAPT: return "WrapT"; + case SST_WRAPR: return "WrapR"; + case SST_MIPFILTER: return "MipFilter"; + case SST_MIPMAPLODBIAS: return "MipMapLodBias"; + case SST_LODBIAS: return "LODBias"; + case SST_SRGBTEXTURE: return "SRGBTexture"; + case SST_MINFILTER: return "MinFilter"; + case SST_MAGFILTER: return "MagFilter"; + case SST_BORDERCOLOR: return "BorderColor"; + case SST_MINMIPLEVEL: return "MinMipLevel"; + case SST_MAXMIPLEVEL: return "MaxMipLevel"; + case SST_MAXANISOTROPY: return "MaxAnisotropy"; + case SST_DEPTHMODE: return "DepthMode"; + case SST_COMPAREMODE: return "CompareMode"; + case SST_COMPAREFUNC: return "CompareFunc"; + case SST_GENERATEMIPMAP: return "GenerateMipmap"; + case SST_UNKNOWN: + default: + return "unknown"; + } + + } + //--------------------------------------------------------------------- + bool CgFxScriptLoader::cgSemanticToOgreAutoConstantType( const char * cgParamSemantic, const char * uiNameValue, GpuProgramParameters::AutoConstantType & ogreAutoConstantType, size_t & extraInfo ) + { + extraInfo = 0; + + FXSemanticID cgFXSemanticID = cgSemanticStringToType(cgParamSemantic); + switch(cgFXSemanticID) + { + case FXS_NONE: + return false; + case FXS_COLOR: + // todo - add to ogre + return false; + case FXS_DIFFUSE: + ogreAutoConstantType = GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR; + return true; + case FXS_SPECULAR: + ogreAutoConstantType = GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR; + return true; + case FXS_AMBIENT: + ogreAutoConstantType = GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR; + return true; + case FXS_EMISSION: + // todo - add to ogre + return false; + case FXS_EMISSIVE: + ogreAutoConstantType = GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR; + return true; + case FXS_SPECULARPOWER: + // todo - add to ogre + return false; + case FXS_REFRACTION: + // todo - add to ogre + return false; + case FXS_OPACITY: + // todo - add to ogre + return false; + case FXS_ENVIRONMENT: + // todo - add to ogre + return false; + case FXS_ENVIRONMENTNORMAL: + // todo - add to ogre + return false; + case FXS_NORMAL: + // todo - add to ogre + return false; + case FXS_HEIGHT: + // todo - add to ogre + return false; + case FXS_ATTENUATION: + // todo - in ogre ACT_LIGHT_ATTENUATION is float4 and we need float3 here + return false; + case FXS_RENDERCOLORTARGET: + // todo - add to ogre + return false; + case FXS_RENDERDEPTHSTENCILTARGET: + // todo - add to ogre + return false; + case FXS_VIEWPORTPIXELSIZE: + // todo - add to ogre + return false; + case FXS_CAMERAPOSITION: + ogreAutoConstantType = GpuProgramParameters::ACT_CAMERA_POSITION; + return true; + case FXS_TIME: + // todo - possibly this value is has the wrong units... + ogreAutoConstantType = GpuProgramParameters::ACT_TIME; + return true; + case FXS_ELAPSEDTIME: + // todo - possibly this value is has the wrong units... + ogreAutoConstantType = GpuProgramParameters::ACT_FRAME_TIME; + return true; + case FXS_ANIMATIONTIME: + // todo - add to ogre + return false; + case FXS_ANIMATIONTICK: + // todo - add to ogre + return false; + case FXS_MOUSEPOSITION: + // todo - add to ogre + return false; + case FXS_LEFTMOUSEDOWN: + // todo - add to ogre + return false; + case FXS_WORLD: + ogreAutoConstantType = GpuProgramParameters::ACT_WORLD_MATRIX; + return true; + case FXS_VIEW: + ogreAutoConstantType = GpuProgramParameters::ACT_VIEW_MATRIX; + return true; + case FXS_PROJECTION: + ogreAutoConstantType = GpuProgramParameters::ACT_PROJECTION_MATRIX; + return true; + case FXS_WORLDTRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_WORLD_MATRIX; + return true; + case FXS_VIEWTRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_VIEW_MATRIX; + return true; + case FXS_PROJECTIONTRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_PROJECTION_MATRIX; + return true; + case FXS_WORLDVIEW: + ogreAutoConstantType = GpuProgramParameters::ACT_WORLDVIEW_MATRIX; + return true; + case FXS_WORLDVIEWPROJECTION: + ogreAutoConstantType = GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX; + return true; + case FXS_WORLDINVERSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_WORLD_MATRIX; + return true; + case FXS_VIEWINVERSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_VIEW_MATRIX; + return true; + case FXS_PROJECTIONINVERSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_PROJECTION_MATRIX; + return true; + case FXS_WORLDINVERSETRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX; + return true; + case FXS_VIEWINVERSETRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_VIEW_MATRIX; + return true; + case FXS_PROJECTIONINVERSETRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_PROJECTION_MATRIX; + return true; + case FXS_WORLDVIEWINVERSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_WORLDVIEW_MATRIX; + return true; + case FXS_WORLDVIEWTRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_WORLDVIEW_MATRIX; + return true; + case FXS_WORLDVIEWINVERSETRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX; + return true; + case FXS_WORLDVIEWPROJECTIONINVERSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_WORLDVIEWPROJ_MATRIX; + return true; + case FXS_WORLDVIEWPROJECTIONTRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_WORLDVIEWPROJ_MATRIX; + return true; + case FXS_WORLDVIEWPROJECTIONINVERSETRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLDVIEWPROJ_MATRIX; + return true; + case FXS_VIEWPROJECTION: + ogreAutoConstantType = GpuProgramParameters::ACT_VIEWPROJ_MATRIX; + return true; + case FXS_VIEWPROJECTIONTRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_TRANSPOSE_VIEWPROJ_MATRIX; + return true; + case FXS_VIEWPROJECTIONINVERSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_VIEWPROJ_MATRIX; + return true; + case FXS_VIEWPROJECTIONINVERSETRANSPOSE: + ogreAutoConstantType = GpuProgramParameters::ACT_INVERSE_TRANSPOSE_VIEWPROJ_MATRIX; + return true; + case FXS_FXCOMPOSER_RESETPULSE: + // todo - add to ogre + return false; + case FXS_STANDARDSGLOBAL: + // todo - add to ogre + return false; + case FXS_UNITSSCALE: + // todo - add to ogre + return false; + case FXS_POWER: + // todo - add to ogre + return false; + case FXS_DIFFUSEMAP: + // todo - add to ogre + return false; + case FXS_SPECULARMAP: + // todo - add to ogre + return false; + case FXS_ENVMAP: + // todo - add to ogre + return false; + case FXS_LIGHTPOSITION: + // todo - ACT_LIGHT_POSITION + return false; + case FXS_TRANSFORM: + // todo - add to ogre + return false; + case FXS_USER: + // todo - add to ogre + return false; + case FXS_CONSTANTATTENUATION: + // todo - add to ogre + return false; + case FXS_LINEARATTENUATION: + // todo - add to ogre + return false; + case FXS_QUADRATICATTENUATION: + // todo - add to ogre + return false; + case FXS_FALLOFFANGLE: + // todo - add to ogre + return false; + case FXS_FALLOFFEXPONENT: + // todo - add to ogre + return false; + case FXS_BOUNDINGRADIUS: + // todo - add to ogre + return false; + case FXS_POSITION: + case FXS_DIRECTION: + case FXS_UNKNOWN: + if (uiNameValue) + { + String uiNameValueAsString(uiNameValue); + String theWordLight = "Light"; + if (StringUtil::startsWith(uiNameValueAsString, theWordLight, false)) + { + size_t firstSpacePos = uiNameValueAsString.find(" "); + if (firstSpacePos > 0) + { + String lightNumberAsString = uiNameValueAsString.substr(theWordLight.size(), firstSpacePos - theWordLight.size()); + + size_t lightNumber = StringConverter::parseInt(lightNumberAsString); + extraInfo = lightNumber; + + String colorPart = uiNameValueAsString.substr(firstSpacePos + 1); + if ( colorPart == "Color" ) // float4 + { + ogreAutoConstantType = GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR; + return true; + } + if ( colorPart == "Intensity" ) // float + { + ogreAutoConstantType = GpuProgramParameters::ACT_LIGHT_POWER_SCALE; + return true; + } + if ( colorPart == "Light_position" ) // float3 + { + ogreAutoConstantType = GpuProgramParameters::ACT_LIGHT_POSITION; + return true; + } + if ( colorPart == "Light_direction" ) // float3 + { + ogreAutoConstantType = GpuProgramParameters::ACT_LIGHT_DIRECTION; + return true; + } + if ( colorPart == "Distance Falloff Exponent" ) // float + { + //ogreAutoConstantType = todo: add to GpuProgramParameters; + return false; + } + if ( colorPart == "Distance Falloff Start" ) // float + { + //ogreAutoConstantType = todo: add to GpuProgramParameters; + return false; + } + if ( colorPart == "Light1 Distance Falloff Limit" ) // float + { + //ogreAutoConstantType = todo: add to GpuProgramParameters; + return false; + } + if ( colorPart == "Distance Scale" ) // float + { + //ogreAutoConstantType = todo: add to GpuProgramParameters; + return false; + } + if ( colorPart == "Spread Inner" ) // float + { + //ogreAutoConstantType = todo: add to GpuProgramParameters; + return false; + } + if ( colorPart == "Spread Falloff" ) // float + { + //ogreAutoConstantType = todo: add to GpuProgramParameters; + return false; + } + if ( colorPart == "Light_spread_cos" ) // float + { + //ogreAutoConstantType = todo: add to GpuProgramParameters; + return false; + } + } + + } + else // some other light params + { + if ( uiNameValueAsString == "Diffuse Scalar" ) // float + { + //ogreAutoConstantType = todo: add to GpuProgramParameters; + return false; + } + if ( uiNameValueAsString == "Specular Color" ) // float4 + { + ogreAutoConstantType = GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR; + return true; + } + if ( uiNameValueAsString == "Specular Scalar" ) // float + { + //ogreAutoConstantType = todo: add to GpuProgramParameters; + return false; + } + if ( uiNameValueAsString == "Specular Shininess" ) // float + { + //ogreAutoConstantType = todo: add to GpuProgramParameters; + return false; + } + } + } + return false; + default: + return false; + } + + } + + //--------------------------------------------------------------------- + bool CgFxScriptLoader::parseAutoConstantParam( CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ) + { + const char * cgParamSemantic = cgGetParameterSemantic(cgParameter); + CGannotation parameterAnnotation = cgGetFirstParameterAnnotation(cgParameter); + const char * uiNameValue = 0; + while(parameterAnnotation) + { + const char * annotationName = cgGetAnnotationName(parameterAnnotation); + if( strcmp("UIName", annotationName) == 0 ) + { + uiNameValue = cgGetStringAnnotationValue(parameterAnnotation); + } + parameterAnnotation = cgGetNextAnnotation(parameterAnnotation); + } + + bool isAutoConstant = false; + if (cgParamSemantic) + { + GpuProgramParameters::AutoConstantType ogreAutoConstantType; + size_t extraInfo = 0; + bool autoConstantTypeFound = cgSemanticToOgreAutoConstantType(cgParamSemantic, uiNameValue, ogreAutoConstantType, extraInfo); + if (autoConstantTypeFound) + { + isAutoConstant = true; + } + else + { + // todo - an error? + } + if (isAutoConstant) + { + ogreProgramParameters->setNamedAutoConstant(ogreParamName, ogreAutoConstantType, extraInfo); + } + } + return isAutoConstant; + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parseFloatCgProgramParameter( CGtype cgParamType, CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ) + { + float cgParamValue[4*4] = { + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f + }; + int paramSize = 0; + switch(cgParamType) + { + case CG_FLOAT: + paramSize = 1; + break; + case CG_FLOAT2: + paramSize = 2; + break; + case CG_FLOAT3: + paramSize = 3; + break; + case CG_FLOAT4: + paramSize = 4; + break; + case CG_FLOAT1x1: + paramSize = 1*1; + break; + case CG_FLOAT1x2: + paramSize = 1*2; + break; + case CG_FLOAT1x3: + paramSize = 1*3; + break; + case CG_FLOAT1x4: + paramSize = 1*4; + break; + case CG_FLOAT2x1: + paramSize = 2*1; + break; + case CG_FLOAT2x2: + paramSize = 2*2; + break; + case CG_FLOAT2x3: + paramSize = 2*3; + break; + case CG_FLOAT2x4: + paramSize = 2*4; + break; + case CG_FLOAT3x1: + paramSize = 3*1; + break; + case CG_FLOAT3x2: + paramSize = 3*2; + break; + case CG_FLOAT3x3: + paramSize = 3*3; + break; + case CG_FLOAT3x4: + paramSize = 3*4; + break; + case CG_FLOAT4x1: + paramSize = 4*1; + break; + case CG_FLOAT4x2: + paramSize = 4*2; + break; + case CG_FLOAT4x3: + paramSize = 4*3; + break; + case CG_FLOAT4x4: + paramSize = 4*4; + break; + default: // todo error - break; - } - cgGetParameterValuefc(cgParameter, paramSize, cgParamValue); - ogreProgramParameters->setNamedConstant(ogreParamName, cgParamValue, 1, paramSize); - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parseIntCgProgramParameter( CGtype cgParamType, CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ) - { - int cgParamValue[4*4] = { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 - }; - int paramSize = 0; - switch(cgParamType) - { - case CG_INT: - paramSize = 1; - break; - case CG_INT2: - paramSize = 2; - break; - case CG_INT3: - paramSize = 3; - break; - case CG_INT4: - paramSize = 4; - break; - case CG_INT1x1: - paramSize = 1*1; - break; - case CG_INT1x2: - paramSize = 1*2; - break; - case CG_INT1x3: - paramSize = 1*3; - break; - case CG_INT1x4: - paramSize = 1*4; - break; - case CG_INT2x1: - paramSize = 2*1; - break; - case CG_INT2x2: - paramSize = 2*2; - break; - case CG_INT2x3: - paramSize = 2*3; - break; - case CG_INT2x4: - paramSize = 2*4; - break; - case CG_INT3x1: - paramSize = 3*1; - break; - case CG_INT3x2: - paramSize = 3*2; - break; - case CG_INT3x3: - paramSize = 3*3; - break; - case CG_INT3x4: - paramSize = 3*4; - break; - case CG_INT4x1: - paramSize = 4*1; - break; - case CG_INT4x2: - paramSize = 4*2; - break; - case CG_INT4x3: - paramSize = 4*3; - break; - case CG_INT4x4: - paramSize = 4*4; - break; - default: + break; + } + cgGetParameterValuefc(cgParameter, paramSize, cgParamValue); + ogreProgramParameters->setNamedConstant(ogreParamName, cgParamValue, 1, paramSize); + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parseIntCgProgramParameter( CGtype cgParamType, CGparameter cgParameter, GpuProgramParametersSharedPtr ogreProgramParameters, const String& ogreParamName ) + { + int cgParamValue[4*4] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 + }; + int paramSize = 0; + switch(cgParamType) + { + case CG_INT: + paramSize = 1; + break; + case CG_INT2: + paramSize = 2; + break; + case CG_INT3: + paramSize = 3; + break; + case CG_INT4: + paramSize = 4; + break; + case CG_INT1x1: + paramSize = 1*1; + break; + case CG_INT1x2: + paramSize = 1*2; + break; + case CG_INT1x3: + paramSize = 1*3; + break; + case CG_INT1x4: + paramSize = 1*4; + break; + case CG_INT2x1: + paramSize = 2*1; + break; + case CG_INT2x2: + paramSize = 2*2; + break; + case CG_INT2x3: + paramSize = 2*3; + break; + case CG_INT2x4: + paramSize = 2*4; + break; + case CG_INT3x1: + paramSize = 3*1; + break; + case CG_INT3x2: + paramSize = 3*2; + break; + case CG_INT3x3: + paramSize = 3*3; + break; + case CG_INT3x4: + paramSize = 3*4; + break; + case CG_INT4x1: + paramSize = 4*1; + break; + case CG_INT4x2: + paramSize = 4*2; + break; + case CG_INT4x3: + paramSize = 4*3; + break; + case CG_INT4x4: + paramSize = 4*4; + break; + default: // todo error - break; - } - cgGetParameterValueic(cgParameter, paramSize, cgParamValue); - ogreProgramParameters->setNamedConstant(ogreParamName, cgParamValue, 1, paramSize); - } - //--------------------------------------------------------------------- - Ogre::CgFxScriptLoader::CgSamplerStateListener * CgFxScriptLoader::createCgSamplerStateListener( const SamplerStateType type ) - { - switch(type) - { - case SST_ADDRESSU: - case SST_ADDRESSV: - case SST_ADDRESSW: - return OGRE_NEW CgTextureAddressSamplerStateListener(type); - case SST_WRAPS: - case SST_WRAPT: - case SST_WRAPR: - return OGRE_NEW CgWrapSamplerStateListener(type); - case SST_BORDERCOLOR: - return OGRE_NEW CgFloat4SamplerStateListener(type); - case SST_COMPAREMODE: - return OGRE_NEW CgCompareModeSamplerStateListener(); - case SST_COMPAREFUNC: - return OGRE_NEW CgCompareFuncSamplerStateListener(); - case SST_DEPTHMODE: - return OGRE_NEW CgDepthModeSamplerStateListener(); - case SST_GENERATEMIPMAP: - return OGRE_NEW CgBoolSamplerStateListener(type); - case SST_MIPMAPLODBIAS: - case SST_LODBIAS: - case SST_MAXMIPLEVEL: - case SST_MAXANISOTROPY: - case SST_MINMIPLEVEL: - case SST_SRGBTEXTURE: - return OGRE_NEW CgFloatSamplerStateListener(type); - case SST_MINFILTER: - return OGRE_NEW CgMinFilterSamplerStateListener(); - case SST_MAGFILTER: - return OGRE_NEW CgMagFilterSamplerStateListener(); - case SST_TEXTURE: - return OGRE_NEW CgTextureSamplerStateListener(type); - case SST_MIPFILTER: - return OGRE_NEW CgMipFilterSamplerStateListener(); - default: - // TODO - this is an error.... - return OGRE_NEW CgSamplerStateListener(type, CG_STRING); - } - } - //--------------------------------------------------------------------- - Ogre::CgFxScriptLoader::CgGlobalStateListener * CgFxScriptLoader::createCgGlobalStateListener( const GlobalStateType type ) - { - switch(type) - { - case GST_ALPHABLENDENABLE: - case GST_COLORVERTEX: - case GST_DEPTHMASK: - case GST_ZWRITEENABLE: - case GST_INDEXEDVERTEXBLENDENABLE: - case GST_LIGHTINGENABLE: - case GST_LIGHTING: - case GST_LIGHTENABLE: - case GST_LOCALVIEWER: - case GST_MULTISAMPLEANTIALIAS: - case GST_POINTSCALEENABLE: - case GST_RANGEFOGENABLE: - case GST_SPECULARENABLE: - case GST_CLIPPING: - case GST_POINTSPRITECOORDREPLACE: - case GST_LASTPIXEL: - case GST_TEXTURE1DENABLE: - case GST_TEXTURE2DENABLE: - case GST_TEXTURE3DENABLE: - case GST_TEXTURERECTANGLEENABLE: - case GST_TEXTURECUBEMAPENABLE: - case GST_ALPHATESTENABLE: - case GST_AUTONORMALENABLE: - case GST_BLENDENABLE: - case GST_COLORLOGICOPENABLE: - case GST_CULLFACEENABLE: - case GST_DEPTHBOUNDSENABLE: - case GST_DEPTHCLAMPENABLE: - case GST_DEPTHTESTENABLE: - case GST_ZENABLE: - case GST_DITHERENABLE: - case GST_FOGENABLE: - case GST_LIGHTMODELLOCALVIEWERENABLE: - case GST_LIGHTMODELTWOSIDEENABLE: - case GST_LINESMOOTHENABLE: - case GST_LINESTIPPLEENABLE: - case GST_LOGICOPENABLE: - case GST_MULTISAMPLEENABLE: - case GST_NORMALIZEENABLE: - case GST_NORMALIZENORMALS: - case GST_POINTSMOOTHENABLE: - case GST_POINTSPRITEENABLE: - case GST_POLYGONOFFSETFILLENABLE: - case GST_POLYGONOFFSETLINEENABLE: - case GST_POLYGONOFFSETPOINTENABLE: - case GST_POLYGONSMOOTHENABLE: - case GST_POLYGONSTIPPLEENABLE: - case GST_RESCALENORMALENABLE: - case GST_SAMPLEALPHATOCOVERAGEENABLE: - case GST_SAMPLEALPHATOONEENABLE: - case GST_SAMPLECOVERAGEENABLE: - case GST_SCISSORTESTENABLE: - case GST_STENCILTESTENABLE: - case GST_STENCILENABLE: - case GST_STENCILTESTTWOSIDEENABLE: - case GST_TEXGENSENABLE: - case GST_TEXGENTENABLE: - case GST_TEXGENRENABLE: - case GST_TEXGENQENABLE: - case GST_TWOSIDEDSTENCILMODE: - case GST_SEPARATEALPHABLENDENABLE: - case GST_VERTEXPROGRAMPOINTSIZEENABLE: - case GST_VERTEXPROGRAMTWOSIDEENABLE: - return OGRE_NEW CgBoolGlobalStateListener(type); - case GST_COLORWRITEENABLE: - case GST_COLORMASK: - case GST_PIXELSHADERCONSTANTB: - case GST_VERTEXSHADERCONSTANTB: - case GST_COLORWRITEENABLE1: - case GST_COLORWRITEENABLE2: - case GST_COLORWRITEENABLE3: - return OGRE_NEW CgBool4GlobalStateListener(type); - case GST_ALPHAREF: - case GST_CLEARDEPTH: - case GST_DEPTHBIAS: - case GST_FOGDENSITY: - case GST_FOGSTART: - case GST_FOGEND: - case GST_LIGHTCONSTANTATTENUATION: - case GST_LIGHTATTENUATION0: - case GST_LIGHTLINEARATTENUATION: - case GST_LIGHTATTENUATION1: - case GST_LIGHTQUADRATICATTENUATION: - case GST_LIGHTATTENUATION2: - case GST_LIGHTSPOTCUTOFF: - case GST_LIGHTFALLOFF: - case GST_LIGHTPHI: - case GST_LIGHTRANGE: - case GST_LIGHTTHETA: - case GST_PATCHSEGMENTS: - case GST_POINTSCALE_A: - case GST_POINTSCALE_B: - case GST_POINTSCALE_C: - case GST_TWEENFACTOR: - case GST_LINEWIDTH: - case GST_MATERIALSHININESS: - case GST_MATERIALPOWER: - case GST_POINTFADETHRESHOLDSIZE: - case GST_POINTSIZE: - case GST_POINTSIZEMIN: - case GST_POINTSIZEMAX: - case GST_SLOPSCALEDEPTHBIAS: - case GST_BUMPENVLSCALE: - case GST_BUMPENVLOFFSET: - case GST_BUMPENVMAT00: - case GST_BUMPENVMAT01: - case GST_BUMPENVMAT10: - case GST_BUMPENVMAT11: - case GST_LIGHTSPOTEXPONENT: - return OGRE_NEW CgFloatGlobalStateListener(type); - case GST_DEPTHBOUNDS: - case GST_DEPTHRANGE: - case GST_POLYGONOFFSET: - case GST_MAXANISOTROPY: - case GST_MAXMIPLEVEL: - return OGRE_NEW CgFloat2GlobalStateListener(type); - case GST_POINTDISTANCEATTENUATION: - return OGRE_NEW CgFloat3GlobalStateListener(type); - case GST_BLENDCOLOR: - case GST_CLEARCOLOR: - case GST_CLIPPLANE: - case GST_FOGCOLOR: - case GST_FRAGMENTENVPARAMETER: - case GST_FRAGMENTLOCALPARAMETER: - case GST_LIGHTMODELAMBIENT: - case GST_AMBIENT: - case GST_LIGHTAMBIENT: - case GST_LIGHTDIFFUSE: - case GST_LIGHTPOSITION: - case GST_LIGHTSPECULAR: - case GST_LIGHTSPOTDIRECTION: - case GST_LIGHTDIRECTION: - case GST_MATERIALAMBIENT: - case GST_MATERIALDIFFUSE: - case GST_MATERIALEMISSION: - case GST_MATERIALEMISSIVE: - case GST_MATERIALSPECULAR: - case GST_TEXGENSOBJECTPLANE: - case GST_TEXGENSEYEPLANE: - case GST_TEXGENTOBJECTPLANE: - case GST_TEXGENTEYEPLANE: - case GST_TEXGENROBJECTPLANE: - case GST_TEXGENREYEPLANE: - case GST_TEXGENQOBJECTPLANE: - case GST_TEXGENQEYEPLANE: - case GST_TEXTUREENVCOLOR: - case GST_VERTEXENVPARAMETER: - case GST_VERTEXLOCALPARAMETER: - case GST_PIXELSHADERCONSTANT1: - case GST_VERTEXSHADERCONSTANT1: - case GST_PIXELSHADERCONSTANTF: - case GST_VERTEXSHADERCONSTANTF: - case GST_BORDERCOLOR: - return OGRE_NEW CgFloat4GlobalStateListener(type); - case GST_PIXELSHADERCONSTANT2: - case GST_VERTEXSHADERCONSTANT2: - return OGRE_NEW CgFloat4x2GlobalStateListener(type); - case GST_PIXELSHADERCONSTANT3: - case GST_VERTEXSHADERCONSTANT3: - return OGRE_NEW CgFloat4x3GlobalStateListener(type); - case GST_COLORMATRIX: - case GST_COLORTRANSFORM: - case GST_MODELVIEWMATRIX: - case GST_MODELVIEWTRANSFORM: - case GST_VIEWTRANSFORM: - case GST_WORLDTRANSFORM: - case GST_PROJECTIONMATRIX: - case GST_PROJECTIONTRANSFORM: - case GST_TEXTURETRANSFORM: - case GST_TEXTUREMATRIX: - case GST_PIXELSHADERCONSTANT: - case GST_VERTEXSHADERCONSTANT: - case GST_PIXELSHADERCONSTANT4: - case GST_VERTEXSHADERCONSTANT4: - return OGRE_NEW CgFloat4x4GlobalStateListener(type); - case GST_LINESTIPPLE: - case GST_FILLMODE: - return OGRE_NEW CgInt2GlobalStateListener(type); - case GST_SCISSOR: - case GST_PIXELSHADERCONSTANTI: - case GST_VERTEXSHADERCONSTANTI: - return OGRE_NEW CgInt4GlobalStateListener(type); - case GST_SAMPLER: - case GST_TEXTURE1D: - return OGRE_NEW CgSamplerGlobalStateListener(type); - case GST_TEXTURE2D: - return OGRE_NEW CgSampler2GlobalStateListener(type); - case GST_TEXTURE3D: - return OGRE_NEW CgSampler3GlobalStateListener(type); - case GST_TEXTURECUBEMAP: - return OGRE_NEW CgSamplerCubeGlobalStateListener(type); - case GST_TEXTURERECTANGLE: - return OGRE_NEW CgSamplerRectGlobalStateListener(type); - case GST_TEXTURE: - return OGRE_NEW CgTextureGlobalStateListener(type); - case GST_GEOMETRYPROGRAM: - case GST_VERTEXPROGRAM: - case GST_FRAGMENTPROGRAM: - case GST_VERTEXSHADER: - case GST_PIXELSHADER: - return OGRE_NEW CgProgramGlobalStateListener(type); - case GST_BLENDOP: - case GST_CLEARSTENCIL: - case GST_CLIPPLANEENABLE: - case GST_CULLMODE: - case GST_ZFUNC: - case GST_FOGTABLEMODE: - case GST_FOGVERTEXMODE: - case GST_LIGHTTYPE: - case GST_MULTISAMPLEMASK: - case GST_AMBIENTMATERIALSOURCE: - case GST_DIFFUSEMATERIALSOURCE: - case GST_EMISSIVEMATERIALSOURCE: - case GST_SPECULARMATERIALSOURCE: - case GST_VERTEXBLEND: - case GST_DESTBLEND: - case GST_SRCBLEND: - case GST_STENCILMASK: - case GST_STENCILPASS: - case GST_STENCILREF: - case GST_STENCILWRITEMASK: - case GST_STENCILZFAIL: - case GST_TEXTUREFACTOR: - case GST_STENCILFAIL: - case GST_WRAP0: - case GST_WRAP1: - case GST_WRAP2: - case GST_WRAP3: - case GST_WRAP4: - case GST_WRAP5: - case GST_WRAP6: - case GST_WRAP7: - case GST_WRAP8: - case GST_WRAP9: - case GST_WRAP10: - case GST_WRAP11: - case GST_WRAP12: - case GST_WRAP13: - case GST_WRAP14: - case GST_WRAP15: - case GST_ADDRESSU: - case GST_ADDRESSV: - case GST_ADDRESSW: - case GST_MIPMAPLODBIAS: - case GST_BLENDOPALPHA: - case GST_SRCBLENDALPHA: - case GST_DESTBLENDALPHA: - case GST_ALPHAOP: - case GST_COLOROP: - case GST_ALPHAARG0: - case GST_ALPHAARG1: - case GST_ALPHAARG2: - case GST_COLORARG0: - case GST_COLORARG1: - case GST_COLORARG2: - case GST_RESULTARG: - case GST_TEXCOORDINDEX: - case GST_TEXTURETRANSFORMFLAGS: - case GST_MIPFILTER: // todo - return OGRE_NEW CgIntGlobalStateListener(type); - case GST_BLENDEQUATION: - return OGRE_NEW CgBlendEquationGlobalStateListener(); - case GST_DEPTHFUNC: - return OGRE_NEW CgDepthFuncGlobalStateListener(); - case GST_FOGDISTANCEMODE: - return OGRE_NEW CgFogDistanceModeGlobalStateListener(); - case GST_FOGMODE: - return OGRE_NEW CgFogModeGlobalStateListener(); - case GST_LIGHTMODELCOLORCONTROL: - return OGRE_NEW CgLightModelColorControlGlobalStateListener(); - case GST_LOGICOP: - return OGRE_NEW CgLogicOpGlobalStateListener(); - case GST_POINTSPRITECOORDORIGIN: - return OGRE_NEW CgPointSpriteCoordOriginGlobalStateListener(); - case GST_POINTSPRITERMODE: - return OGRE_NEW CgPointSpriteRModeGlobalStateListener(); - case GST_SHADEMODEL: - case GST_SHADEMODE: - return OGRE_NEW CgShadeModelGlobalStateListener(); - case GST_TEXGENSMODE: - case GST_TEXGENTMODE: - case GST_TEXGENRMODE: - case GST_TEXGENQMODE: - return OGRE_NEW CgTexGenModeGlobalStateListener(type); - case GST_TEXTUREENVMODE: - return OGRE_NEW CgTextureEnvModeGlobalStateListener(); - case GST_MINFILTER: - return OGRE_NEW CgMinFilterGlobalStateListener(); - case GST_MAGFILTER: - return OGRE_NEW CgMagFilterGlobalStateListener(); - case GST_FRONTFACE: - return OGRE_NEW CgFrontFaceGlobalStateListener(); - case GST_CULLFACE: - return OGRE_NEW CgCullFaceGlobalStateListener(); - case GST_FOGCOORDSRC: - return OGRE_NEW CgFogCoordSrcGlobalStateListener(); - case GST_ALPHAFUNC: - return OGRE_NEW CgAlphaFuncGlobalStateListener(); - case GST_BLENDFUNC: - return OGRE_NEW CgBlendFuncGlobalStateListener(); - case GST_BLENDFUNCSEPARATE: - return OGRE_NEW CgBlendFuncSeparateGlobalStateListener(); - case GST_BLENDEQUATIONSEPARATE: - return OGRE_NEW CgBlendEquationSeparateGlobalStateListener(); - case GST_COLORMATERIAL: - return OGRE_NEW CgColorMaterialGlobalStateListener(); - case GST_POLYGONMODE: - return OGRE_NEW CgPolygonModeGlobalStateListener(); - case GST_STENCILFUNC: - return OGRE_NEW CgStencilFuncGlobalStateListener(); - case GST_STENCILOP: - return OGRE_NEW CgStencilOpGlobalStateListener(); - case GST_STENCILFUNCSEPARATE: - return OGRE_NEW CgStencilFuncSeparateGlobalStateListener(); - case GST_STENCILMASKSEPARATE: - return OGRE_NEW CgStencilMaskSeparateGlobalStateListener(); - case GST_STENCILOPSEPARATE: - return OGRE_NEW CgStencilOpSeparateGlobalStateListener(); - default: - // TODO - this is an error.... - return OGRE_NEW CgGlobalStateListener(type, CG_STRING); - } - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parsePassStateAssignments( CGpass cgPass, Pass * ogrePass ) - { - CGstateassignment cgStateAssignment = cgGetFirstStateAssignment(cgPass); - while (cgStateAssignment) - { - CGstate cgState = cgGetStateAssignmentState(cgStateAssignment); - CgGlobalStateToListenerMap::iterator stateIter = mCgGlobalStateToListenerMap.find(cgState); - if (stateIter != mCgGlobalStateToListenerMap.end()) - { - stateIter->second->updatePass(ogrePass, cgStateAssignment); - } - - cgStateAssignment = cgGetNextStateAssignment(cgStateAssignment); - } - } - //--------------------------------------------------------------------- - void CgFxScriptLoader::parseTextureUnitState( CGstateassignment cgStateAssignment, TextureUnitState * ogreTextureUnitState ) - { - CGstate cgState = cgGetSamplerStateAssignmentState(cgStateAssignment); - - checkForCgError("CgFxScriptLoader::parseTextureUnitState", - "Unable to Get State Assignment State: ", mCgContext); - - CgSamplerStateToListenerMap::iterator samplerStateIter = mCgSamplerStateToListenerMap.find(cgState); - if (samplerStateIter != mCgSamplerStateToListenerMap.end()) - { - samplerStateIter->second->upateTextureUnitState(ogreTextureUnitState, cgStateAssignment); - } - } - - void CgFxScriptLoader::parseSamplerParameters(CGpass cgPass, Pass * ogrePass) - { - CGeffect cgEffect = cgGetTechniqueEffect(cgGetPassTechnique(cgPass)); - CGparameter cgParameter = cgGetFirstEffectParameter(cgEffect); - while (cgParameter) - { - if (cgGetParameterClass(cgParameter) == CG_PARAMETERCLASS_SAMPLER) - { - CGstateassignment cgStateAssignment = cgGetFirstSamplerStateAssignment(cgParameter); - - if (cgStateAssignment) - { - TextureUnitState * ogreTextureUnitState = ogrePass->createTextureUnitState(); - - while(cgStateAssignment) - { - if(cgIsStateAssignment(cgStateAssignment)) - { - parseTextureUnitState(cgStateAssignment, ogreTextureUnitState); - } - - cgStateAssignment = cgGetNextStateAssignment(cgStateAssignment); - } - - } - } - - cgParameter = cgGetNextParameter(cgParameter); - } - - } + break; + } + cgGetParameterValueic(cgParameter, paramSize, cgParamValue); + ogreProgramParameters->setNamedConstant(ogreParamName, cgParamValue, 1, paramSize); + } + //--------------------------------------------------------------------- + Ogre::CgFxScriptLoader::CgSamplerStateListener * CgFxScriptLoader::createCgSamplerStateListener( const SamplerStateType type ) + { + switch(type) + { + case SST_ADDRESSU: + case SST_ADDRESSV: + case SST_ADDRESSW: + return OGRE_NEW CgTextureAddressSamplerStateListener(type); + case SST_WRAPS: + case SST_WRAPT: + case SST_WRAPR: + return OGRE_NEW CgWrapSamplerStateListener(type); + case SST_BORDERCOLOR: + return OGRE_NEW CgFloat4SamplerStateListener(type); + case SST_COMPAREMODE: + return OGRE_NEW CgCompareModeSamplerStateListener(); + case SST_COMPAREFUNC: + return OGRE_NEW CgCompareFuncSamplerStateListener(); + case SST_DEPTHMODE: + return OGRE_NEW CgDepthModeSamplerStateListener(); + case SST_GENERATEMIPMAP: + return OGRE_NEW CgBoolSamplerStateListener(type); + case SST_MIPMAPLODBIAS: + case SST_LODBIAS: + case SST_MAXMIPLEVEL: + case SST_MAXANISOTROPY: + case SST_MINMIPLEVEL: + case SST_SRGBTEXTURE: + return OGRE_NEW CgFloatSamplerStateListener(type); + case SST_MINFILTER: + return OGRE_NEW CgMinFilterSamplerStateListener(); + case SST_MAGFILTER: + return OGRE_NEW CgMagFilterSamplerStateListener(); + case SST_TEXTURE: + return OGRE_NEW CgTextureSamplerStateListener(type); + case SST_MIPFILTER: + return OGRE_NEW CgMipFilterSamplerStateListener(); + default: + // TODO - this is an error.... + return OGRE_NEW CgSamplerStateListener(type, CG_STRING); + } + } + //--------------------------------------------------------------------- + Ogre::CgFxScriptLoader::CgGlobalStateListener * CgFxScriptLoader::createCgGlobalStateListener( const GlobalStateType type ) + { + switch(type) + { + case GST_ALPHABLENDENABLE: + case GST_COLORVERTEX: + case GST_DEPTHMASK: + case GST_ZWRITEENABLE: + case GST_INDEXEDVERTEXBLENDENABLE: + case GST_LIGHTINGENABLE: + case GST_LIGHTING: + case GST_LIGHTENABLE: + case GST_LOCALVIEWER: + case GST_MULTISAMPLEANTIALIAS: + case GST_POINTSCALEENABLE: + case GST_RANGEFOGENABLE: + case GST_SPECULARENABLE: + case GST_CLIPPING: + case GST_POINTSPRITECOORDREPLACE: + case GST_LASTPIXEL: + case GST_TEXTURE1DENABLE: + case GST_TEXTURE2DENABLE: + case GST_TEXTURE3DENABLE: + case GST_TEXTURERECTANGLEENABLE: + case GST_TEXTURECUBEMAPENABLE: + case GST_ALPHATESTENABLE: + case GST_AUTONORMALENABLE: + case GST_BLENDENABLE: + case GST_COLORLOGICOPENABLE: + case GST_CULLFACEENABLE: + case GST_DEPTHBOUNDSENABLE: + case GST_DEPTHCLAMPENABLE: + case GST_DEPTHTESTENABLE: + case GST_ZENABLE: + case GST_DITHERENABLE: + case GST_FOGENABLE: + case GST_LIGHTMODELLOCALVIEWERENABLE: + case GST_LIGHTMODELTWOSIDEENABLE: + case GST_LINESMOOTHENABLE: + case GST_LINESTIPPLEENABLE: + case GST_LOGICOPENABLE: + case GST_MULTISAMPLEENABLE: + case GST_NORMALIZEENABLE: + case GST_NORMALIZENORMALS: + case GST_POINTSMOOTHENABLE: + case GST_POINTSPRITEENABLE: + case GST_POLYGONOFFSETFILLENABLE: + case GST_POLYGONOFFSETLINEENABLE: + case GST_POLYGONOFFSETPOINTENABLE: + case GST_POLYGONSMOOTHENABLE: + case GST_POLYGONSTIPPLEENABLE: + case GST_RESCALENORMALENABLE: + case GST_SAMPLEALPHATOCOVERAGEENABLE: + case GST_SAMPLEALPHATOONEENABLE: + case GST_SAMPLECOVERAGEENABLE: + case GST_SCISSORTESTENABLE: + case GST_STENCILTESTENABLE: + case GST_STENCILENABLE: + case GST_STENCILTESTTWOSIDEENABLE: + case GST_TEXGENSENABLE: + case GST_TEXGENTENABLE: + case GST_TEXGENRENABLE: + case GST_TEXGENQENABLE: + case GST_TWOSIDEDSTENCILMODE: + case GST_SEPARATEALPHABLENDENABLE: + case GST_VERTEXPROGRAMPOINTSIZEENABLE: + case GST_VERTEXPROGRAMTWOSIDEENABLE: + return OGRE_NEW CgBoolGlobalStateListener(type); + case GST_COLORWRITEENABLE: + case GST_COLORMASK: + case GST_PIXELSHADERCONSTANTB: + case GST_VERTEXSHADERCONSTANTB: + case GST_COLORWRITEENABLE1: + case GST_COLORWRITEENABLE2: + case GST_COLORWRITEENABLE3: + return OGRE_NEW CgBool4GlobalStateListener(type); + case GST_ALPHAREF: + case GST_CLEARDEPTH: + case GST_DEPTHBIAS: + case GST_FOGDENSITY: + case GST_FOGSTART: + case GST_FOGEND: + case GST_LIGHTCONSTANTATTENUATION: + case GST_LIGHTATTENUATION0: + case GST_LIGHTLINEARATTENUATION: + case GST_LIGHTATTENUATION1: + case GST_LIGHTQUADRATICATTENUATION: + case GST_LIGHTATTENUATION2: + case GST_LIGHTSPOTCUTOFF: + case GST_LIGHTFALLOFF: + case GST_LIGHTPHI: + case GST_LIGHTRANGE: + case GST_LIGHTTHETA: + case GST_PATCHSEGMENTS: + case GST_POINTSCALE_A: + case GST_POINTSCALE_B: + case GST_POINTSCALE_C: + case GST_TWEENFACTOR: + case GST_LINEWIDTH: + case GST_MATERIALSHININESS: + case GST_MATERIALPOWER: + case GST_POINTFADETHRESHOLDSIZE: + case GST_POINTSIZE: + case GST_POINTSIZEMIN: + case GST_POINTSIZEMAX: + case GST_SLOPSCALEDEPTHBIAS: + case GST_BUMPENVLSCALE: + case GST_BUMPENVLOFFSET: + case GST_BUMPENVMAT00: + case GST_BUMPENVMAT01: + case GST_BUMPENVMAT10: + case GST_BUMPENVMAT11: + case GST_LIGHTSPOTEXPONENT: + return OGRE_NEW CgFloatGlobalStateListener(type); + case GST_DEPTHBOUNDS: + case GST_DEPTHRANGE: + case GST_POLYGONOFFSET: + case GST_MAXANISOTROPY: + case GST_MAXMIPLEVEL: + return OGRE_NEW CgFloat2GlobalStateListener(type); + case GST_POINTDISTANCEATTENUATION: + return OGRE_NEW CgFloat3GlobalStateListener(type); + case GST_BLENDCOLOR: + case GST_CLEARCOLOR: + case GST_CLIPPLANE: + case GST_FOGCOLOR: + case GST_FRAGMENTENVPARAMETER: + case GST_FRAGMENTLOCALPARAMETER: + case GST_LIGHTMODELAMBIENT: + case GST_AMBIENT: + case GST_LIGHTAMBIENT: + case GST_LIGHTDIFFUSE: + case GST_LIGHTPOSITION: + case GST_LIGHTSPECULAR: + case GST_LIGHTSPOTDIRECTION: + case GST_LIGHTDIRECTION: + case GST_MATERIALAMBIENT: + case GST_MATERIALDIFFUSE: + case GST_MATERIALEMISSION: + case GST_MATERIALEMISSIVE: + case GST_MATERIALSPECULAR: + case GST_TEXGENSOBJECTPLANE: + case GST_TEXGENSEYEPLANE: + case GST_TEXGENTOBJECTPLANE: + case GST_TEXGENTEYEPLANE: + case GST_TEXGENROBJECTPLANE: + case GST_TEXGENREYEPLANE: + case GST_TEXGENQOBJECTPLANE: + case GST_TEXGENQEYEPLANE: + case GST_TEXTUREENVCOLOR: + case GST_VERTEXENVPARAMETER: + case GST_VERTEXLOCALPARAMETER: + case GST_PIXELSHADERCONSTANT1: + case GST_VERTEXSHADERCONSTANT1: + case GST_PIXELSHADERCONSTANTF: + case GST_VERTEXSHADERCONSTANTF: + case GST_BORDERCOLOR: + return OGRE_NEW CgFloat4GlobalStateListener(type); + case GST_PIXELSHADERCONSTANT2: + case GST_VERTEXSHADERCONSTANT2: + return OGRE_NEW CgFloat4x2GlobalStateListener(type); + case GST_PIXELSHADERCONSTANT3: + case GST_VERTEXSHADERCONSTANT3: + return OGRE_NEW CgFloat4x3GlobalStateListener(type); + case GST_COLORMATRIX: + case GST_COLORTRANSFORM: + case GST_MODELVIEWMATRIX: + case GST_MODELVIEWTRANSFORM: + case GST_VIEWTRANSFORM: + case GST_WORLDTRANSFORM: + case GST_PROJECTIONMATRIX: + case GST_PROJECTIONTRANSFORM: + case GST_TEXTURETRANSFORM: + case GST_TEXTUREMATRIX: + case GST_PIXELSHADERCONSTANT: + case GST_VERTEXSHADERCONSTANT: + case GST_PIXELSHADERCONSTANT4: + case GST_VERTEXSHADERCONSTANT4: + return OGRE_NEW CgFloat4x4GlobalStateListener(type); + case GST_LINESTIPPLE: + case GST_FILLMODE: + return OGRE_NEW CgInt2GlobalStateListener(type); + case GST_SCISSOR: + case GST_PIXELSHADERCONSTANTI: + case GST_VERTEXSHADERCONSTANTI: + return OGRE_NEW CgInt4GlobalStateListener(type); + case GST_SAMPLER: + case GST_TEXTURE1D: + return OGRE_NEW CgSamplerGlobalStateListener(type); + case GST_TEXTURE2D: + return OGRE_NEW CgSampler2GlobalStateListener(type); + case GST_TEXTURE3D: + return OGRE_NEW CgSampler3GlobalStateListener(type); + case GST_TEXTURECUBEMAP: + return OGRE_NEW CgSamplerCubeGlobalStateListener(type); + case GST_TEXTURERECTANGLE: + return OGRE_NEW CgSamplerRectGlobalStateListener(type); + case GST_TEXTURE: + return OGRE_NEW CgTextureGlobalStateListener(type); + case GST_GEOMETRYPROGRAM: + case GST_VERTEXPROGRAM: + case GST_FRAGMENTPROGRAM: + case GST_VERTEXSHADER: + case GST_PIXELSHADER: + return OGRE_NEW CgProgramGlobalStateListener(type); + case GST_BLENDOP: + case GST_CLEARSTENCIL: + case GST_CLIPPLANEENABLE: + case GST_CULLMODE: + case GST_ZFUNC: + case GST_FOGTABLEMODE: + case GST_FOGVERTEXMODE: + case GST_LIGHTTYPE: + case GST_MULTISAMPLEMASK: + case GST_AMBIENTMATERIALSOURCE: + case GST_DIFFUSEMATERIALSOURCE: + case GST_EMISSIVEMATERIALSOURCE: + case GST_SPECULARMATERIALSOURCE: + case GST_VERTEXBLEND: + case GST_DESTBLEND: + case GST_SRCBLEND: + case GST_STENCILMASK: + case GST_STENCILPASS: + case GST_STENCILREF: + case GST_STENCILWRITEMASK: + case GST_STENCILZFAIL: + case GST_TEXTUREFACTOR: + case GST_STENCILFAIL: + case GST_WRAP0: + case GST_WRAP1: + case GST_WRAP2: + case GST_WRAP3: + case GST_WRAP4: + case GST_WRAP5: + case GST_WRAP6: + case GST_WRAP7: + case GST_WRAP8: + case GST_WRAP9: + case GST_WRAP10: + case GST_WRAP11: + case GST_WRAP12: + case GST_WRAP13: + case GST_WRAP14: + case GST_WRAP15: + case GST_ADDRESSU: + case GST_ADDRESSV: + case GST_ADDRESSW: + case GST_MIPMAPLODBIAS: + case GST_BLENDOPALPHA: + case GST_SRCBLENDALPHA: + case GST_DESTBLENDALPHA: + case GST_ALPHAOP: + case GST_COLOROP: + case GST_ALPHAARG0: + case GST_ALPHAARG1: + case GST_ALPHAARG2: + case GST_COLORARG0: + case GST_COLORARG1: + case GST_COLORARG2: + case GST_RESULTARG: + case GST_TEXCOORDINDEX: + case GST_TEXTURETRANSFORMFLAGS: + case GST_MIPFILTER: // todo + return OGRE_NEW CgIntGlobalStateListener(type); + case GST_BLENDEQUATION: + return OGRE_NEW CgBlendEquationGlobalStateListener(); + case GST_DEPTHFUNC: + return OGRE_NEW CgDepthFuncGlobalStateListener(); + case GST_FOGDISTANCEMODE: + return OGRE_NEW CgFogDistanceModeGlobalStateListener(); + case GST_FOGMODE: + return OGRE_NEW CgFogModeGlobalStateListener(); + case GST_LIGHTMODELCOLORCONTROL: + return OGRE_NEW CgLightModelColorControlGlobalStateListener(); + case GST_LOGICOP: + return OGRE_NEW CgLogicOpGlobalStateListener(); + case GST_POINTSPRITECOORDORIGIN: + return OGRE_NEW CgPointSpriteCoordOriginGlobalStateListener(); + case GST_POINTSPRITERMODE: + return OGRE_NEW CgPointSpriteRModeGlobalStateListener(); + case GST_SHADEMODEL: + case GST_SHADEMODE: + return OGRE_NEW CgShadeModelGlobalStateListener(); + case GST_TEXGENSMODE: + case GST_TEXGENTMODE: + case GST_TEXGENRMODE: + case GST_TEXGENQMODE: + return OGRE_NEW CgTexGenModeGlobalStateListener(type); + case GST_TEXTUREENVMODE: + return OGRE_NEW CgTextureEnvModeGlobalStateListener(); + case GST_MINFILTER: + return OGRE_NEW CgMinFilterGlobalStateListener(); + case GST_MAGFILTER: + return OGRE_NEW CgMagFilterGlobalStateListener(); + case GST_FRONTFACE: + return OGRE_NEW CgFrontFaceGlobalStateListener(); + case GST_CULLFACE: + return OGRE_NEW CgCullFaceGlobalStateListener(); + case GST_FOGCOORDSRC: + return OGRE_NEW CgFogCoordSrcGlobalStateListener(); + case GST_ALPHAFUNC: + return OGRE_NEW CgAlphaFuncGlobalStateListener(); + case GST_BLENDFUNC: + return OGRE_NEW CgBlendFuncGlobalStateListener(); + case GST_BLENDFUNCSEPARATE: + return OGRE_NEW CgBlendFuncSeparateGlobalStateListener(); + case GST_BLENDEQUATIONSEPARATE: + return OGRE_NEW CgBlendEquationSeparateGlobalStateListener(); + case GST_COLORMATERIAL: + return OGRE_NEW CgColorMaterialGlobalStateListener(); + case GST_POLYGONMODE: + return OGRE_NEW CgPolygonModeGlobalStateListener(); + case GST_STENCILFUNC: + return OGRE_NEW CgStencilFuncGlobalStateListener(); + case GST_STENCILOP: + return OGRE_NEW CgStencilOpGlobalStateListener(); + case GST_STENCILFUNCSEPARATE: + return OGRE_NEW CgStencilFuncSeparateGlobalStateListener(); + case GST_STENCILMASKSEPARATE: + return OGRE_NEW CgStencilMaskSeparateGlobalStateListener(); + case GST_STENCILOPSEPARATE: + return OGRE_NEW CgStencilOpSeparateGlobalStateListener(); + default: + // TODO - this is an error.... + return OGRE_NEW CgGlobalStateListener(type, CG_STRING); + } + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parsePassStateAssignments( CGpass cgPass, Pass * ogrePass ) + { + CGstateassignment cgStateAssignment = cgGetFirstStateAssignment(cgPass); + while (cgStateAssignment) + { + CGstate cgState = cgGetStateAssignmentState(cgStateAssignment); + CgGlobalStateToListenerMap::iterator stateIter = mCgGlobalStateToListenerMap.find(cgState); + if (stateIter != mCgGlobalStateToListenerMap.end()) + { + stateIter->second->updatePass(ogrePass, cgStateAssignment); + } + + cgStateAssignment = cgGetNextStateAssignment(cgStateAssignment); + } + } + //--------------------------------------------------------------------- + void CgFxScriptLoader::parseTextureUnitState( CGstateassignment cgStateAssignment, TextureUnitState * ogreTextureUnitState ) + { + CGstate cgState = cgGetSamplerStateAssignmentState(cgStateAssignment); + + checkForCgError("CgFxScriptLoader::parseTextureUnitState", + "Unable to Get State Assignment State: ", mCgContext); + + CgSamplerStateToListenerMap::iterator samplerStateIter = mCgSamplerStateToListenerMap.find(cgState); + if (samplerStateIter != mCgSamplerStateToListenerMap.end()) + { + samplerStateIter->second->upateTextureUnitState(ogreTextureUnitState, cgStateAssignment); + } + } + + void CgFxScriptLoader::parseSamplerParameters(CGpass cgPass, Pass * ogrePass) + { + CGeffect cgEffect = cgGetTechniqueEffect(cgGetPassTechnique(cgPass)); + CGparameter cgParameter = cgGetFirstEffectParameter(cgEffect); + while (cgParameter) + { + if (cgGetParameterClass(cgParameter) == CG_PARAMETERCLASS_SAMPLER) + { + CGstateassignment cgStateAssignment = cgGetFirstSamplerStateAssignment(cgParameter); + + if (cgStateAssignment) + { + TextureUnitState * ogreTextureUnitState = ogrePass->createTextureUnitState(); + + while(cgStateAssignment) + { + if(cgIsStateAssignment(cgStateAssignment)) + { + parseTextureUnitState(cgStateAssignment, ogreTextureUnitState); + } + + cgStateAssignment = cgGetNextStateAssignment(cgStateAssignment); + } + + } + } + + cgParameter = cgGetNextParameter(cgParameter); + } + + } } diff --git a/PlugIns/CgProgramManager/src/OgreCgPlugin.cpp b/PlugIns/CgProgramManager/src/OgreCgPlugin.cpp index 6073429fbd5..62fa19ae42e 100644 --- a/PlugIns/CgProgramManager/src/OgreCgPlugin.cpp +++ b/PlugIns/CgProgramManager/src/OgreCgPlugin.cpp @@ -36,25 +36,25 @@ THE SOFTWARE. namespace Ogre { - const String sPluginName = "Cg Program Manager"; - //--------------------------------------------------------------------- - CgPlugin::CgPlugin() - :mCgProgramFactory(0) - { + const String sPluginName = "Cg Program Manager"; + //--------------------------------------------------------------------- + CgPlugin::CgPlugin() + :mCgProgramFactory(0) + { - } - //--------------------------------------------------------------------- - const String& CgPlugin::getName() const - { - return sPluginName; - } - //--------------------------------------------------------------------- - void CgPlugin::install() - { - } - //--------------------------------------------------------------------- - void CgPlugin::initialise() - { + } + //--------------------------------------------------------------------- + const String& CgPlugin::getName() const + { + return sPluginName; + } + //--------------------------------------------------------------------- + void CgPlugin::install() + { + } + //--------------------------------------------------------------------- + void CgPlugin::initialise() + { // Cg is also not supported on OpenGL 3+ if(Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL 3+") != String::npos) { @@ -74,24 +74,24 @@ namespace Ogre OGRE_NEW CgFxScriptLoader(); } - } - //--------------------------------------------------------------------- - void CgPlugin::shutdown() - { - // nothing to do - } - //--------------------------------------------------------------------- - void CgPlugin::uninstall() - { + } + //--------------------------------------------------------------------- + void CgPlugin::shutdown() + { + // nothing to do + } + //--------------------------------------------------------------------- + void CgPlugin::uninstall() + { if (mCgProgramFactory) { - OGRE_DELETE CgFxScriptLoader::getSingletonPtr(); + OGRE_DELETE CgFxScriptLoader::getSingletonPtr(); // Remove from manager safely if (HighLevelGpuProgramManager::getSingletonPtr()) HighLevelGpuProgramManager::getSingleton().removeFactory(mCgProgramFactory); - OGRE_DELETE mCgProgramFactory; - mCgProgramFactory = 0; + OGRE_DELETE mCgProgramFactory; + mCgProgramFactory = 0; } - } + } } diff --git a/PlugIns/CgProgramManager/src/OgreCgProgram.cpp b/PlugIns/CgProgramManager/src/OgreCgProgram.cpp index 9b121d62f55..a7b5e978cf8 100644 --- a/PlugIns/CgProgramManager/src/OgreCgProgram.cpp +++ b/PlugIns/CgProgramManager/src/OgreCgProgram.cpp @@ -56,14 +56,14 @@ namespace Ogre { bool syntaxSupported = gpuMgr.isSyntaxSupported(*i); if (!syntaxSupported && find(specialCgProfiles, specialCgProfilesEnd, *i) != specialCgProfilesEnd) { - // Cg has some "special" profiles which don't have direct equivalents - // in the GpuProgramManager's supported syntaxes. - // For now, the following works - if (gpuMgr.isSyntaxSupported(i->substr(0,4))) - { - syntaxSupported = true; - useDelegate = true; - } + // Cg has some "special" profiles which don't have direct equivalents + // in the GpuProgramManager's supported syntaxes. + // For now, the following works + if (gpuMgr.isSyntaxSupported(i->substr(0,4))) + { + syntaxSupported = true; + useDelegate = true; + } } if (syntaxSupported) { @@ -85,21 +85,21 @@ namespace Ogre { // do we need a delegate? if (useDelegate && mDelegate.isNull()) { - mDelegate = - HighLevelGpuProgramManager::getSingleton().createProgram( - mName+"/Delegate", mGroup, getHighLevelLanguage(), mType); - mDelegate->setParameter("target", getHighLevelTarget()); - mDelegate->setParameter("entry_point", "main"); - // HLSL/GLSL output uses row major matrices, so need to tell Ogre that - mDelegate->setParameter("column_major_matrices", "false"); - // HLSL output requires backwards compatibility to be enabled - mDelegate->setParameter("backwards_compatibility", "true"); + mDelegate = + HighLevelGpuProgramManager::getSingleton().createProgram( + mName+"/Delegate", mGroup, getHighLevelLanguage(), mType); + mDelegate->setParameter("target", getHighLevelTarget()); + mDelegate->setParameter("entry_point", "main"); + // HLSL/GLSL output uses row major matrices, so need to tell Ogre that + mDelegate->setParameter("column_major_matrices", "false"); + // HLSL output requires backwards compatibility to be enabled + mDelegate->setParameter("backwards_compatibility", "true"); } else if (!useDelegate && !mDelegate.isNull()) { - ResourcePtr rs (mDelegate); - HighLevelGpuProgramManager::getSingleton().remove(rs); - mDelegate.setNull(); + ResourcePtr rs (mDelegate); + HighLevelGpuProgramManager::getSingleton().remove(rs); + mDelegate.setNull(); } break; @@ -130,7 +130,7 @@ namespace Ogre { if (!dclsFound) { args.push_back("-profileopts"); - args.push_back("dcls"); + args.push_back("dcls"); } } // Now split args into that god-awful char** that Cg insists on @@ -157,7 +157,7 @@ namespace Ogre { while (current) { OGRE_FREE(current, MEMCATEGORY_RESOURCE); - mCgArguments[index] = 0; + mCgArguments[index] = 0; current = mCgArguments[++index]; } OGRE_FREE(mCgArguments, MEMCATEGORY_RESOURCE); @@ -167,16 +167,16 @@ namespace Ogre { //----------------------------------------------------------------------- void CgProgram::loadFromSource(void) { - selectProfile(); + selectProfile(); - if ( GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(String("CG_") + mName) ) - { - getMicrocodeFromCache(); - } - else - { - compileMicrocode(); - } + if ( GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(String("CG_") + mName) ) + { + getMicrocodeFromCache(); + } + else + { + compileMicrocode(); + } if (!mDelegate.isNull()) { @@ -226,46 +226,46 @@ namespace Ogre { } mDelegate->load(); } - } + } //----------------------------------------------------------------------- void CgProgram::getMicrocodeFromCache(void) { - GpuProgramManager::Microcode cacheMicrocode = - GpuProgramManager::getSingleton().getMicrocodeFromCache(String("CG_") + mName); - - cacheMicrocode->seek(0); - - // get size of string - size_t programStringSize = 0; - cacheMicrocode->read(&programStringSize, sizeof(size_t)); - - // get microcode - mProgramString.resize(programStringSize); - cacheMicrocode->read(&mProgramString[0], programStringSize); - - // get size of param map - size_t parametersMapSize = 0; - cacheMicrocode->read(¶metersMapSize, sizeof(size_t)); - - // get params - for(size_t i = 0 ; i < parametersMapSize ; i++) - { - String paramName; - size_t stringSize = 0; - GpuConstantDefinition def; - - // get string size - cacheMicrocode->read(&stringSize, sizeof(size_t)); - - // get string - paramName.resize(stringSize); - cacheMicrocode->read(¶mName[0], stringSize); - - // get def - cacheMicrocode->read( &def, sizeof(GpuConstantDefinition)); - - mParametersMap.insert(GpuConstantDefinitionMap::value_type(paramName, def)); - } + GpuProgramManager::Microcode cacheMicrocode = + GpuProgramManager::getSingleton().getMicrocodeFromCache(String("CG_") + mName); + + cacheMicrocode->seek(0); + + // get size of string + size_t programStringSize = 0; + cacheMicrocode->read(&programStringSize, sizeof(size_t)); + + // get microcode + mProgramString.resize(programStringSize); + cacheMicrocode->read(&mProgramString[0], programStringSize); + + // get size of param map + size_t parametersMapSize = 0; + cacheMicrocode->read(¶metersMapSize, sizeof(size_t)); + + // get params + for(size_t i = 0 ; i < parametersMapSize ; i++) + { + String paramName; + size_t stringSize = 0; + GpuConstantDefinition def; + + // get string size + cacheMicrocode->read(&stringSize, sizeof(size_t)); + + // get string + paramName.resize(stringSize); + cacheMicrocode->read(¶mName[0], stringSize); + + // get def + cacheMicrocode->read( &def, sizeof(GpuConstantDefinition)); + + mParametersMap.insert(GpuConstantDefinitionMap::value_type(paramName, def)); + } if (!mDelegate.isNull()) { @@ -289,7 +289,7 @@ namespace Ogre { cacheMicrocode->read(&mOutputOp, sizeof(CGenum)); } - } + } //----------------------------------------------------------------------- void CgProgram::compileMicrocode(void) { @@ -298,16 +298,16 @@ namespace Ogre { /// Program handle CGprogram cgProgram; - if (mSelectedCgProfile == CG_PROFILE_UNKNOWN) - { - LogManager::getSingleton().logMessage( - "Attempted to load Cg program '" + mName + "', but no supported " - "profile was found. "); - return; - } + if (mSelectedCgProfile == CG_PROFILE_UNKNOWN) + { + LogManager::getSingleton().logMessage( + "Attempted to load Cg program '" + mName + "', but no supported " + "profile was found. "); + return; + } buildArgs(); - // deal with includes - String sourceToUse = resolveCgIncludes(mSource, this, mFilename); + // deal with includes + String sourceToUse = resolveCgIncludes(mSource, this, mFilename); cgProgram = cgCreateProgram(mCgContext, CG_SOURCE, sourceToUse.c_str(), mSelectedCgProfile, mEntryPoint.c_str(), const_cast(mCgArguments)); @@ -322,17 +322,17 @@ namespace Ogre { CGerror error = cgGetError(); if (error == CG_NO_ERROR) { - // get program string (result of cg compile) - mProgramString = cgGetProgramString(cgProgram, CG_COMPILED_PROGRAM); + // get program string (result of cg compile) + mProgramString = cgGetProgramString(cgProgram, CG_COMPILED_PROGRAM); checkForCgError("CgProgram::compileMicrocode", "Unable to retrieve program code for Cg program " + mName + ": ", mCgContext); - // get params - mParametersMap.clear(); - mParametersMapSizeAsBuffer = 0; + // get params + mParametersMap.clear(); + mParametersMapSizeAsBuffer = 0; mSamplerRegisterMap.clear(); - recurseParams(cgGetFirstParameter(cgProgram, CG_PROGRAM)); - recurseParams(cgGetFirstParameter(cgProgram, CG_GLOBAL)); + recurseParams(cgGetFirstParameter(cgProgram, CG_PROGRAM)); + recurseParams(cgGetFirstParameter(cgProgram, CG_GLOBAL)); if (!mDelegate.isNull()) { @@ -346,66 +346,66 @@ namespace Ogre { } } - // Unload Cg Program - we don't need it anymore - cgDestroyProgram(cgProgram); - //checkForCgError("CgProgram::unloadImpl", - // "Error while unloading Cg program " + mName + ": ", - // mCgContext); - cgProgram = 0; + // Unload Cg Program - we don't need it anymore + cgDestroyProgram(cgProgram); + //checkForCgError("CgProgram::unloadImpl", + // "Error while unloading Cg program " + mName + ": ", + // mCgContext); + cgProgram = 0; if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache()) - { - addMicrocodeToCache(); - } - } + { + addMicrocodeToCache(); + } + } } //----------------------------------------------------------------------- - void CgProgram::addMicrocodeToCache() - { - String name = String("CG_") + mName; - size_t programStringSize = mProgramString.size(); + void CgProgram::addMicrocodeToCache() + { + String name = String("CG_") + mName; + size_t programStringSize = mProgramString.size(); uint32 sizeOfMicrocode = static_cast( sizeof(size_t) + // size of mProgramString programStringSize + // microcode - mProgramString sizeof(size_t) + // size of param map mParametersMapSizeAsBuffer); - // create microcode - GpuProgramManager::Microcode newMicrocode = + // create microcode + GpuProgramManager::Microcode newMicrocode = GpuProgramManager::getSingleton().createMicrocode(sizeOfMicrocode); - newMicrocode->seek(0); + newMicrocode->seek(0); - // save size of string - newMicrocode->write(&programStringSize, sizeof(size_t)); + // save size of string + newMicrocode->write(&programStringSize, sizeof(size_t)); - // save microcode - newMicrocode->write(&mProgramString[0], programStringSize); + // save microcode + newMicrocode->write(&mProgramString[0], programStringSize); - // save size of param map - size_t parametersMapSize = mParametersMap.size(); - newMicrocode->write(¶metersMapSize, sizeof(size_t)); + // save size of param map + size_t parametersMapSize = mParametersMap.size(); + newMicrocode->write(¶metersMapSize, sizeof(size_t)); - // save params - GpuConstantDefinitionMap::const_iterator iter = mParametersMap.begin(); - GpuConstantDefinitionMap::const_iterator iterE = mParametersMap.end(); - for (; iter != iterE ; iter++) - { - const String & paramName = iter->first; - const GpuConstantDefinition & def = iter->second; + // save params + GpuConstantDefinitionMap::const_iterator iter = mParametersMap.begin(); + GpuConstantDefinitionMap::const_iterator iterE = mParametersMap.end(); + for (; iter != iterE ; iter++) + { + const String & paramName = iter->first; + const GpuConstantDefinition & def = iter->second; - // save string size - size_t stringSize = paramName.size(); - newMicrocode->write(&stringSize, sizeof(size_t)); + // save string size + size_t stringSize = paramName.size(); + newMicrocode->write(&stringSize, sizeof(size_t)); - // save string - newMicrocode->write(¶mName[0], stringSize); + // save string + newMicrocode->write(¶mName[0], stringSize); - // save def - newMicrocode->write(&def, sizeof(GpuConstantDefinition)); - } + // save def + newMicrocode->write(&def, sizeof(GpuConstantDefinition)); + } if (!mDelegate.isNull()) { @@ -432,127 +432,127 @@ namespace Ogre { newMicrocode->write(&mOutputOp, sizeof(CGenum)); } - // add to the microcode to the cache - GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode); - } + // add to the microcode to the cache + GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode); + } //----------------------------------------------------------------------- void CgProgram::createLowLevelImpl(void) { if (!mDelegate.isNull()) return; - // ignore any previous error - if (mSelectedCgProfile != CG_PROFILE_UNKNOWN && !mCompileError) - { + // ignore any previous error + if (mSelectedCgProfile != CG_PROFILE_UNKNOWN && !mCompileError) + { - if ( false + if ( false // the hlsl 4 profiles are only supported in OGRE from CG 2.2 #if(CG_VERSION_NUM >= 2200) - || mSelectedCgProfile == CG_PROFILE_VS_4_0 - || mSelectedCgProfile == CG_PROFILE_PS_4_0 + || mSelectedCgProfile == CG_PROFILE_VS_4_0 + || mSelectedCgProfile == CG_PROFILE_PS_4_0 #endif #if(CG_VERSION_NUM >= 3000) - || mSelectedCgProfile == CG_PROFILE_VS_5_0 - || mSelectedCgProfile == CG_PROFILE_PS_5_0 - || mSelectedCgProfile == CG_PROFILE_DS_5_0 - || mSelectedCgProfile == CG_PROFILE_HS_5_0 + || mSelectedCgProfile == CG_PROFILE_VS_5_0 + || mSelectedCgProfile == CG_PROFILE_PS_5_0 + || mSelectedCgProfile == CG_PROFILE_DS_5_0 + || mSelectedCgProfile == CG_PROFILE_HS_5_0 #endif - ) - { - // Create a high-level program, give it the same name as us - HighLevelGpuProgramPtr vp = - HighLevelGpuProgramManager::getSingleton().createProgram( - mName, mGroup, "hlsl", mType); - vp->setSource(mProgramString); - vp->setParameter("target", mSelectedProfile); - vp->setParameter("entry_point", "main"); - - vp->load(); - - mAssemblerProgram = vp; - } - else - { + ) + { + // Create a high-level program, give it the same name as us + HighLevelGpuProgramPtr vp = + HighLevelGpuProgramManager::getSingleton().createProgram( + mName, mGroup, "hlsl", mType); + vp->setSource(mProgramString); + vp->setParameter("target", mSelectedProfile); + vp->setParameter("entry_point", "main"); + + vp->load(); + + mAssemblerProgram = vp; + } + else + { if (mType == GPT_FRAGMENT_PROGRAM) { //HACK : http://developer.nvidia.com/forums/index.php?showtopic=1063&pid=2378&mode=threaded&start=#entry2378 //Still happens in CG 2.2. Remove hack when fixed. mProgramString = StringUtil::replaceAll(mProgramString, "oDepth.z", "oDepth"); } - // Create a low-level program, give it the same name as us - mAssemblerProgram = - GpuProgramManager::getSingleton().createProgramFromString( - mName, - mGroup, - mProgramString, - mType, - mSelectedProfile); - } - // Shader params need to be forwarded to low level implementation - mAssemblerProgram->setAdjacencyInfoRequired(isAdjacencyInfoRequired()); - } + // Create a low-level program, give it the same name as us + mAssemblerProgram = + GpuProgramManager::getSingleton().createProgramFromString( + mName, + mGroup, + mProgramString, + mType, + mSelectedProfile); + } + // Shader params need to be forwarded to low level implementation + mAssemblerProgram->setAdjacencyInfoRequired(isAdjacencyInfoRequired()); + } } //----------------------------------------------------------------------- String CgProgram::getHighLevelLanguage() const { - switch (mSelectedCgProfile) - { - case CG_PROFILE_GLSLF: - case CG_PROFILE_GLSLV: - case CG_PROFILE_GLSLG: - case CG_PROFILE_GLSLC: - return "glsl"; - case CG_PROFILE_HLSLF: - case CG_PROFILE_HLSLV: - return "hlsl"; - default: - return "unknown"; - } + switch (mSelectedCgProfile) + { + case CG_PROFILE_GLSLF: + case CG_PROFILE_GLSLV: + case CG_PROFILE_GLSLG: + case CG_PROFILE_GLSLC: + return "glsl"; + case CG_PROFILE_HLSLF: + case CG_PROFILE_HLSLV: + return "hlsl"; + default: + return "unknown"; + } } //----------------------------------------------------------------------- String CgProgram::getHighLevelTarget() const { - // HLSL delegates need a target to compile to. - // Return value for GLSL delegates is ignored. - GpuProgramManager* gpuMgr = GpuProgramManager::getSingletonPtr(); + // HLSL delegates need a target to compile to. + // Return value for GLSL delegates is ignored. + GpuProgramManager* gpuMgr = GpuProgramManager::getSingletonPtr(); - if (mSelectedCgProfile == CG_PROFILE_HLSLF) - { - static const String fpProfiles[] = { + if (mSelectedCgProfile == CG_PROFILE_HLSLF) + { + static const String fpProfiles[] = { #if(CG_VERSION_NUM >= 3000) - "ps_5_0", + "ps_5_0", #endif #if(CG_VERSION_NUM >= 2200) - "ps_4_0", + "ps_4_0", #endif - "ps_3_0", "ps_2_x", "ps_2_0", "ps_1_4", "ps_1_3", "ps_1_2", "ps_1_1"}; - static const size_t numFpProfiles = sizeof(fpProfiles)/sizeof(String); - // find the highest profile available - for (size_t i = 0; i < numFpProfiles; ++i) - { - if (gpuMgr->isSyntaxSupported(fpProfiles[i])) - return fpProfiles[i]; - } - } - else if (mSelectedCgProfile == CG_PROFILE_HLSLV) - { - static const String vpProfiles[] = { + "ps_3_0", "ps_2_x", "ps_2_0", "ps_1_4", "ps_1_3", "ps_1_2", "ps_1_1"}; + static const size_t numFpProfiles = sizeof(fpProfiles)/sizeof(String); + // find the highest profile available + for (size_t i = 0; i < numFpProfiles; ++i) + { + if (gpuMgr->isSyntaxSupported(fpProfiles[i])) + return fpProfiles[i]; + } + } + else if (mSelectedCgProfile == CG_PROFILE_HLSLV) + { + static const String vpProfiles[] = { #if(CG_VERSION_NUM >= 3000) - "vs_5_0", + "vs_5_0", #endif #if(CG_VERSION_NUM >= 2200) - "vs_4_0", -#endif - "vs_3_0", "vs_2_x", "vs_2_0", "vs_1_4", "vs_1_3", "vs_1_2", "vs_1_1"}; - static const size_t numVpProfiles = sizeof(vpProfiles)/sizeof(String); - // find the highest profile available - for (size_t i = 0; i < numVpProfiles; ++i) - { - if (gpuMgr->isSyntaxSupported(vpProfiles[i])) - return vpProfiles[i]; - } - } - - return "unknown"; + "vs_4_0", +#endif + "vs_3_0", "vs_2_x", "vs_2_0", "vs_1_4", "vs_1_3", "vs_1_2", "vs_1_1"}; + static const size_t numVpProfiles = sizeof(vpProfiles)/sizeof(String); + // find the highest profile available + for (size_t i = 0; i < numVpProfiles; ++i) + { + if (gpuMgr->isSyntaxSupported(vpProfiles[i])) + return vpProfiles[i]; + } + } + + return "unknown"; } //----------------------------------------------------------------------- struct HighLevelOutputFixer @@ -587,32 +587,32 @@ namespace Ogre { while (cur < source.size()) { // look for a comment line describing a parameter name mapping - // comment format: //var type parameter : [something] : new name : [something] : [something] + // comment format: //var type parameter : [something] : new name : [something] : [something] cur = source.find("//var", cur); if (cur == String::npos) break; end = source.find('\n', cur); - vector::type cols = StringUtil::split(source.substr(cur, end-cur), ":"); + vector::type cols = StringUtil::split(source.substr(cur, end-cur), ":"); cur = end; - if (cols.size() < 3) - continue; - vector::type def = StringUtil::split(cols[0], "[ "); - if (def.size() < 3) - continue; - StringUtil::trim(cols[2]); - vector::type repl = StringUtil::split(cols[2], "[ "); - String oldName = def[2]; - String newName = repl[0]; - StringUtil::trim(oldName); - StringUtil::trim(newName); - if (newName.empty() || newName[0] != '_') - continue; - // if that name is present in our lists, mark in name translation map + if (cols.size() < 3) + continue; + vector::type def = StringUtil::split(cols[0], "[ "); + if (def.size() < 3) + continue; + StringUtil::trim(cols[2]); + vector::type repl = StringUtil::split(cols[2], "[ "); + String oldName = def[2]; + String newName = repl[0]; + StringUtil::trim(oldName); + StringUtil::trim(newName); + if (newName.empty() || newName[0] != '_') + continue; + // if that name is present in our lists, mark in name translation map GpuConstantDefinitionMap::const_iterator it = paramMap.find(oldName); - if (it != paramMap.end() || samplerMap.find(oldName) != samplerMap.end()) + if (it != paramMap.end() || samplerMap.find(oldName) != samplerMap.end()) { LogManager::getSingleton().stream() << "Replacing parameter name: " << newName << " -> " << oldName; - paramNameMap.insert(std::make_pair(oldName, newName)); + paramNameMap.insert(std::make_pair(oldName, newName)); } } // end now points at the end of the last comment, so we can strip anything before @@ -724,11 +724,11 @@ namespace Ogre { //----------------------------------------------------------------------- void CgProgram::fixHighLevelOutput(String& hlSource) { - // Cg chooses to change parameter names when translating to another + // Cg chooses to change parameter names when translating to another // high level language, possibly to avoid clashes with reserved keywords. // We need to revert that, otherwise Ogre parameter mappings fail. - // Cg logs its renamings in the comments at the beginning of the - // processed source file. We can get them from there. + // Cg logs its renamings in the comments at the beginning of the + // processed source file. We can get them from there. // We'll also get rid of those comments to trim down source code size. LogManager::getSingleton().stream() << "Cg high level output for " << getName() << ":\n" << hlSource; hlSource = HighLevelOutputFixer(hlSource, mParametersMap, mSamplerRegisterMap, @@ -742,8 +742,8 @@ namespace Ogre { void CgProgram::loadHighLevelSafe() { OGRE_LOCK_AUTO_MUTEX; - if (this->isSupported()) - loadHighLevel(); + if (this->isSupported()) + loadHighLevel(); } //----------------------------------------------------------------------- GpuProgramParametersSharedPtr CgProgram::createParameters() @@ -751,123 +751,123 @@ namespace Ogre { loadHighLevelSafe(); if (!mDelegate.isNull()) return mDelegate->createParameters(); - else - return HighLevelGpuProgram::createParameters(); + else + return HighLevelGpuProgram::createParameters(); } //----------------------------------------------------------------------- GpuProgram* CgProgram::_getBindingDelegate() { - if (!mDelegate.isNull()) - return mDelegate->_getBindingDelegate(); - else - return HighLevelGpuProgram::_getBindingDelegate(); + if (!mDelegate.isNull()) + return mDelegate->_getBindingDelegate(); + else + return HighLevelGpuProgram::_getBindingDelegate(); } //----------------------------------------------------------------------- bool CgProgram::isSkeletalAnimationIncluded(void) const { - if (!mDelegate.isNull()) - return mDelegate->isSkeletalAnimationIncluded(); - else - return HighLevelGpuProgram::isSkeletalAnimationIncluded(); + if (!mDelegate.isNull()) + return mDelegate->isSkeletalAnimationIncluded(); + else + return HighLevelGpuProgram::isSkeletalAnimationIncluded(); } //----------------------------------------------------------------------- bool CgProgram::isMorphAnimationIncluded(void) const { - if (!mDelegate.isNull()) - return mDelegate->isMorphAnimationIncluded(); - else - return HighLevelGpuProgram::isMorphAnimationIncluded(); + if (!mDelegate.isNull()) + return mDelegate->isMorphAnimationIncluded(); + else + return HighLevelGpuProgram::isMorphAnimationIncluded(); } //----------------------------------------------------------------------- bool CgProgram::isPoseAnimationIncluded(void) const { - if (!mDelegate.isNull()) - return mDelegate->isPoseAnimationIncluded(); - else - return HighLevelGpuProgram::isPoseAnimationIncluded(); + if (!mDelegate.isNull()) + return mDelegate->isPoseAnimationIncluded(); + else + return HighLevelGpuProgram::isPoseAnimationIncluded(); } //----------------------------------------------------------------------- bool CgProgram::isVertexTextureFetchRequired(void) const { - if (!mDelegate.isNull()) - return mDelegate->isVertexTextureFetchRequired(); - else - return HighLevelGpuProgram::isVertexTextureFetchRequired(); + if (!mDelegate.isNull()) + return mDelegate->isVertexTextureFetchRequired(); + else + return HighLevelGpuProgram::isVertexTextureFetchRequired(); } //----------------------------------------------------------------------- GpuProgramParametersSharedPtr CgProgram::getDefaultParameters(void) { loadHighLevelSafe(); - if (!mDelegate.isNull()) - return mDelegate->getDefaultParameters(); - else - return HighLevelGpuProgram::getDefaultParameters(); + if (!mDelegate.isNull()) + return mDelegate->getDefaultParameters(); + else + return HighLevelGpuProgram::getDefaultParameters(); } //----------------------------------------------------------------------- bool CgProgram::hasDefaultParameters(void) const { - if (!mDelegate.isNull()) - return mDelegate->hasDefaultParameters(); - else - return HighLevelGpuProgram::hasDefaultParameters(); + if (!mDelegate.isNull()) + return mDelegate->hasDefaultParameters(); + else + return HighLevelGpuProgram::hasDefaultParameters(); } //----------------------------------------------------------------------- bool CgProgram::getPassSurfaceAndLightStates(void) const { - if (!mDelegate.isNull()) - return mDelegate->getPassSurfaceAndLightStates(); - else - return HighLevelGpuProgram::getPassSurfaceAndLightStates(); + if (!mDelegate.isNull()) + return mDelegate->getPassSurfaceAndLightStates(); + else + return HighLevelGpuProgram::getPassSurfaceAndLightStates(); } //----------------------------------------------------------------------- bool CgProgram::getPassFogStates(void) const { - if (!mDelegate.isNull()) - return mDelegate->getPassFogStates(); - else - return HighLevelGpuProgram::getPassFogStates(); + if (!mDelegate.isNull()) + return mDelegate->getPassFogStates(); + else + return HighLevelGpuProgram::getPassFogStates(); } //----------------------------------------------------------------------- bool CgProgram::getPassTransformStates(void) const { - if (!mDelegate.isNull()) - return mDelegate->getPassTransformStates(); - else + if (!mDelegate.isNull()) + return mDelegate->getPassTransformStates(); + else { - return true; /* CG uses MVP matrix when -posinv argument passed */ + return true; /* CG uses MVP matrix when -posinv argument passed */ } } //----------------------------------------------------------------------- bool CgProgram::hasCompileError(void) const { - if (!mDelegate.isNull()) - return mDelegate->hasCompileError(); - else - return HighLevelGpuProgram::hasCompileError(); + if (!mDelegate.isNull()) + return mDelegate->hasCompileError(); + else + return HighLevelGpuProgram::hasCompileError(); } //----------------------------------------------------------------------- void CgProgram::resetCompileError(void) { - if (!mDelegate.isNull()) - mDelegate->resetCompileError(); - else - HighLevelGpuProgram::resetCompileError(); + if (!mDelegate.isNull()) + mDelegate->resetCompileError(); + else + HighLevelGpuProgram::resetCompileError(); } //----------------------------------------------------------------------- size_t CgProgram::getSize() const { - if (!mDelegate.isNull()) - return mDelegate->getSize(); - else - return HighLevelGpuProgram::getSize(); + if (!mDelegate.isNull()) + return mDelegate->getSize(); + else + return HighLevelGpuProgram::getSize(); } //----------------------------------------------------------------------- void CgProgram::touch() { - if (!mDelegate.isNull()) - mDelegate->touch(); - else - HighLevelGpuProgram::touch(); + if (!mDelegate.isNull()) + mDelegate->touch(); + else + HighLevelGpuProgram::touch(); } @@ -879,49 +879,49 @@ namespace Ogre { void CgProgram::buildConstantDefinitions() const { // Derive parameter names from Cg - createParameterMappingStructures(true); - - if ( mProgramString.empty() ) - return; - - mConstantDefs->floatBufferSize = mFloatLogicalToPhysical->bufferSize; - mConstantDefs->intBufferSize = mIntLogicalToPhysical->bufferSize; - - GpuConstantDefinitionMap::const_iterator iter = mParametersMap.begin(); - GpuConstantDefinitionMap::const_iterator iterE = mParametersMap.end(); - for (; iter != iterE ; iter++) - { - const String & paramName = iter->first; - GpuConstantDefinition def = iter->second; - - mConstantDefs->map.insert(GpuConstantDefinitionMap::value_type(iter->first, iter->second)); - - // Record logical / physical mapping - if (def.isFloat()) - { + createParameterMappingStructures(true); + + if ( mProgramString.empty() ) + return; + + mConstantDefs->floatBufferSize = mFloatLogicalToPhysical->bufferSize; + mConstantDefs->intBufferSize = mIntLogicalToPhysical->bufferSize; + + GpuConstantDefinitionMap::const_iterator iter = mParametersMap.begin(); + GpuConstantDefinitionMap::const_iterator iterE = mParametersMap.end(); + for (; iter != iterE ; iter++) + { + const String & paramName = iter->first; + GpuConstantDefinition def = iter->second; + + mConstantDefs->map.insert(GpuConstantDefinitionMap::value_type(iter->first, iter->second)); + + // Record logical / physical mapping + if (def.isFloat()) + { OGRE_LOCK_MUTEX(mFloatLogicalToPhysical->mutex); - mFloatLogicalToPhysical->map.insert( - GpuLogicalIndexUseMap::value_type(def.logicalIndex, - GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); - mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; - } - else - { + mFloatLogicalToPhysical->map.insert( + GpuLogicalIndexUseMap::value_type(def.logicalIndex, + GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); + mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; + } + else + { OGRE_LOCK_MUTEX(mIntLogicalToPhysical->mutex); - mIntLogicalToPhysical->map.insert( - GpuLogicalIndexUseMap::value_type(def.logicalIndex, - GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); - mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; - } - - // Deal with array indexing - mConstantDefs->generateConstantDefinitionArrayEntries(paramName, def); - } - } - //--------------------------------------------------------------------- - void CgProgram::recurseParams(CGparameter parameter, size_t contextArraySize) - { - while (parameter != 0) + mIntLogicalToPhysical->map.insert( + GpuLogicalIndexUseMap::value_type(def.logicalIndex, + GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); + mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; + } + + // Deal with array indexing + mConstantDefs->generateConstantDefinitionArrayEntries(paramName, def); + } + } + //--------------------------------------------------------------------- + void CgProgram::recurseParams(CGparameter parameter, size_t contextArraySize) + { + while (parameter != 0) { // Look for uniform parameters only // Don't bother enumerating unused parameters, especially since they will @@ -937,112 +937,112 @@ namespace Ogre { cgGetParameterDirection(parameter) != CG_OUT && cgIsParameterReferenced(parameter)) { - int arraySize; - - switch(paramType) - { - case CG_STRUCT: - recurseParams(cgGetFirstStructParameter(parameter)); - break; - case CG_ARRAY: - // Support only 1-dimensional arrays - arraySize = cgGetArraySize(parameter, 0); - recurseParams(cgGetArrayParameter(parameter, 0), (size_t)arraySize); - break; - default: - // Normal path (leaf) - String paramName = cgGetParameterName(parameter); - size_t logicalIndex = cgGetParameterResourceIndex(parameter); - - // Get the parameter resource, to calculate the physical index - CGresource res = cgGetParameterResource(parameter); - bool isRegisterCombiner = false; - size_t regCombinerPhysicalIndex = 0; - switch (res) - { - case CG_COMBINER_STAGE_CONST0: - // register combiner, const 0 - // the index relates to the texture stage; store this as (stage * 2) + 0 - regCombinerPhysicalIndex = logicalIndex * 2; - isRegisterCombiner = true; - break; - case CG_COMBINER_STAGE_CONST1: - // register combiner, const 1 - // the index relates to the texture stage; store this as (stage * 2) + 1 - regCombinerPhysicalIndex = (logicalIndex * 2) + 1; - isRegisterCombiner = true; - break; - default: - // normal constant - break; - } - - // Trim the '[0]' suffix if it exists, we will add our own indexing later - if (StringUtil::endsWith(paramName, "[0]", false)) - { - paramName.erase(paramName.size() - 3); - } - - - GpuConstantDefinition def; - def.arraySize = contextArraySize; - mapTypeAndElementSize(paramType, isRegisterCombiner, def); - - if (def.constType == GCT_UNKNOWN) - { - LogManager::getSingleton().logMessage( - "Problem parsing the following Cg Uniform: '" - + paramName + "' in file " + mName); - // next uniform - parameter = cgGetNextParameter(parameter); - continue; - } - if (isRegisterCombiner) - { - def.physicalIndex = regCombinerPhysicalIndex; - } - else - { - // base position on existing buffer contents - if (def.isFloat()) - { - def.physicalIndex = mFloatLogicalToPhysical->bufferSize; - } - else - { - def.physicalIndex = mIntLogicalToPhysical->bufferSize; - } - } - - def.logicalIndex = logicalIndex; - if( mParametersMap.find(paramName) == mParametersMap.end()) - { - mParametersMap.insert(GpuConstantDefinitionMap::value_type(paramName, def)); - mParametersMapSizeAsBuffer += sizeof(size_t); - mParametersMapSizeAsBuffer += paramName.size(); - mParametersMapSizeAsBuffer += sizeof(GpuConstantDefinition); - } - - // Record logical / physical mapping - if (def.isFloat()) - { + int arraySize; + + switch(paramType) + { + case CG_STRUCT: + recurseParams(cgGetFirstStructParameter(parameter)); + break; + case CG_ARRAY: + // Support only 1-dimensional arrays + arraySize = cgGetArraySize(parameter, 0); + recurseParams(cgGetArrayParameter(parameter, 0), (size_t)arraySize); + break; + default: + // Normal path (leaf) + String paramName = cgGetParameterName(parameter); + size_t logicalIndex = cgGetParameterResourceIndex(parameter); + + // Get the parameter resource, to calculate the physical index + CGresource res = cgGetParameterResource(parameter); + bool isRegisterCombiner = false; + size_t regCombinerPhysicalIndex = 0; + switch (res) + { + case CG_COMBINER_STAGE_CONST0: + // register combiner, const 0 + // the index relates to the texture stage; store this as (stage * 2) + 0 + regCombinerPhysicalIndex = logicalIndex * 2; + isRegisterCombiner = true; + break; + case CG_COMBINER_STAGE_CONST1: + // register combiner, const 1 + // the index relates to the texture stage; store this as (stage * 2) + 1 + regCombinerPhysicalIndex = (logicalIndex * 2) + 1; + isRegisterCombiner = true; + break; + default: + // normal constant + break; + } + + // Trim the '[0]' suffix if it exists, we will add our own indexing later + if (StringUtil::endsWith(paramName, "[0]", false)) + { + paramName.erase(paramName.size() - 3); + } + + + GpuConstantDefinition def; + def.arraySize = contextArraySize; + mapTypeAndElementSize(paramType, isRegisterCombiner, def); + + if (def.constType == GCT_UNKNOWN) + { + LogManager::getSingleton().logMessage( + "Problem parsing the following Cg Uniform: '" + + paramName + "' in file " + mName); + // next uniform + parameter = cgGetNextParameter(parameter); + continue; + } + if (isRegisterCombiner) + { + def.physicalIndex = regCombinerPhysicalIndex; + } + else + { + // base position on existing buffer contents + if (def.isFloat()) + { + def.physicalIndex = mFloatLogicalToPhysical->bufferSize; + } + else + { + def.physicalIndex = mIntLogicalToPhysical->bufferSize; + } + } + + def.logicalIndex = logicalIndex; + if( mParametersMap.find(paramName) == mParametersMap.end()) + { + mParametersMap.insert(GpuConstantDefinitionMap::value_type(paramName, def)); + mParametersMapSizeAsBuffer += sizeof(size_t); + mParametersMapSizeAsBuffer += paramName.size(); + mParametersMapSizeAsBuffer += sizeof(GpuConstantDefinition); + } + + // Record logical / physical mapping + if (def.isFloat()) + { OGRE_LOCK_MUTEX(mFloatLogicalToPhysical->mutex); - mFloatLogicalToPhysical->map.insert( - GpuLogicalIndexUseMap::value_type(def.logicalIndex, - GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); - mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; - } - else - { + mFloatLogicalToPhysical->map.insert( + GpuLogicalIndexUseMap::value_type(def.logicalIndex, + GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); + mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; + } + else + { OGRE_LOCK_MUTEX(mIntLogicalToPhysical->mutex); - mIntLogicalToPhysical->map.insert( - GpuLogicalIndexUseMap::value_type(def.logicalIndex, - GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); - mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; - } - - break; - } + mIntLogicalToPhysical->map.insert( + GpuLogicalIndexUseMap::value_type(def.logicalIndex, + GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); + mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; + } + + break; + } } // now handle uniform samplers. This is needed to fix their register positions @@ -1110,95 +1110,95 @@ namespace Ogre { } - //----------------------------------------------------------------------- - void CgProgram::mapTypeAndElementSize(CGtype cgType, bool isRegisterCombiner, - GpuConstantDefinition& def) const - { - if (isRegisterCombiner) - { - // register combiners are the only single-float entries in our buffer - def.constType = GCT_FLOAT1; - def.elementSize = 1; - } - else - { - switch(cgType) - { - case CG_FLOAT: - case CG_FLOAT1: - case CG_HALF: - case CG_HALF1: - def.constType = GCT_FLOAT1; - break; - case CG_FLOAT2: - case CG_HALF2: - def.constType = GCT_FLOAT2; - break; - case CG_FLOAT3: - case CG_HALF3: - def.constType = GCT_FLOAT3; - break; - case CG_FLOAT4: - case CG_HALF4: - def.constType = GCT_FLOAT4; - break; - case CG_FLOAT2x2: - case CG_HALF2x2: - def.constType = GCT_MATRIX_2X2; - break; - case CG_FLOAT2x3: - case CG_HALF2x3: - def.constType = GCT_MATRIX_2X3; - break; - case CG_FLOAT2x4: - case CG_HALF2x4: - def.constType = GCT_MATRIX_2X4; - break; - case CG_FLOAT3x2: - case CG_HALF3x2: - def.constType = GCT_MATRIX_3X2; - break; - case CG_FLOAT3x3: - case CG_HALF3x3: - def.constType = GCT_MATRIX_3X3; - break; - case CG_FLOAT3x4: - case CG_HALF3x4: - def.constType = GCT_MATRIX_3X4; - break; - case CG_FLOAT4x2: - case CG_HALF4x2: - def.constType = GCT_MATRIX_4X2; - break; - case CG_FLOAT4x3: - case CG_HALF4x3: - def.constType = GCT_MATRIX_4X3; - break; - case CG_FLOAT4x4: - case CG_HALF4x4: - def.constType = GCT_MATRIX_4X4; - break; - case CG_INT: - case CG_INT1: - def.constType = GCT_INT1; - break; - case CG_INT2: - def.constType = GCT_INT2; - break; - case CG_INT3: - def.constType = GCT_INT3; - break; - case CG_INT4: - def.constType = GCT_INT4; - break; - default: - def.constType = GCT_UNKNOWN; - break; - } - // Cg pads - def.elementSize = GpuConstantDefinition::getElementSize(def.constType, true); - } - } + //----------------------------------------------------------------------- + void CgProgram::mapTypeAndElementSize(CGtype cgType, bool isRegisterCombiner, + GpuConstantDefinition& def) const + { + if (isRegisterCombiner) + { + // register combiners are the only single-float entries in our buffer + def.constType = GCT_FLOAT1; + def.elementSize = 1; + } + else + { + switch(cgType) + { + case CG_FLOAT: + case CG_FLOAT1: + case CG_HALF: + case CG_HALF1: + def.constType = GCT_FLOAT1; + break; + case CG_FLOAT2: + case CG_HALF2: + def.constType = GCT_FLOAT2; + break; + case CG_FLOAT3: + case CG_HALF3: + def.constType = GCT_FLOAT3; + break; + case CG_FLOAT4: + case CG_HALF4: + def.constType = GCT_FLOAT4; + break; + case CG_FLOAT2x2: + case CG_HALF2x2: + def.constType = GCT_MATRIX_2X2; + break; + case CG_FLOAT2x3: + case CG_HALF2x3: + def.constType = GCT_MATRIX_2X3; + break; + case CG_FLOAT2x4: + case CG_HALF2x4: + def.constType = GCT_MATRIX_2X4; + break; + case CG_FLOAT3x2: + case CG_HALF3x2: + def.constType = GCT_MATRIX_3X2; + break; + case CG_FLOAT3x3: + case CG_HALF3x3: + def.constType = GCT_MATRIX_3X3; + break; + case CG_FLOAT3x4: + case CG_HALF3x4: + def.constType = GCT_MATRIX_3X4; + break; + case CG_FLOAT4x2: + case CG_HALF4x2: + def.constType = GCT_MATRIX_4X2; + break; + case CG_FLOAT4x3: + case CG_HALF4x3: + def.constType = GCT_MATRIX_4X3; + break; + case CG_FLOAT4x4: + case CG_HALF4x4: + def.constType = GCT_MATRIX_4X4; + break; + case CG_INT: + case CG_INT1: + def.constType = GCT_INT1; + break; + case CG_INT2: + def.constType = GCT_INT2; + break; + case CG_INT3: + def.constType = GCT_INT3; + break; + case CG_INT4: + def.constType = GCT_INT4; + break; + default: + def.constType = GCT_UNKNOWN; + break; + } + // Cg pads + def.elementSize = GpuConstantDefinition::getElementSize(def.constType, true); + } + } //----------------------------------------------------------------------- CgProgram::CgProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, @@ -1249,7 +1249,7 @@ namespace Ogre { if (mCompileError || !isRequiredCapabilitiesSupported()) return false; - return mSelectedCgProfile != CG_PROFILE_UNKNOWN; + return mSelectedCgProfile != CG_PROFILE_UNKNOWN; } //----------------------------------------------------------------------- void CgProgram::setProfiles(const StringVector& profiles) @@ -1257,121 +1257,121 @@ namespace Ogre { mProfiles = profiles; selectProfile(); } - //----------------------------------------------------------------------- - String CgProgram::resolveCgIncludes(const String& inSource, Resource* resourceBeingLoaded, const String& fileName) - { - String outSource; - // output will be at least this big - outSource.reserve(inSource.length()); - - size_t startMarker = 0; - size_t i = inSource.find("#include"); - while (i != String::npos) - { - size_t includePos = i; - size_t afterIncludePos = includePos + 8; - size_t newLineBefore = inSource.rfind("\n", includePos); - - // check we're not in a comment - size_t lineCommentIt = inSource.rfind("//", includePos); - if (lineCommentIt != String::npos) - { - if (newLineBefore == String::npos || lineCommentIt > newLineBefore) - { - // commented - i = inSource.find("#include", afterIncludePos); - continue; - } - - } - size_t blockCommentIt = inSource.rfind("/*", includePos); - if (blockCommentIt != String::npos) - { - size_t closeCommentIt = inSource.rfind("*/", includePos); - if (closeCommentIt == String::npos || closeCommentIt < blockCommentIt) - { - // commented - i = inSource.find("#include", afterIncludePos); - continue; - } - - } - - // find following newline (or EOF) - size_t newLineAfter = inSource.find("\n", afterIncludePos); - // find include file string container - String endDelimeter = "\""; - size_t startIt = inSource.find("\"", afterIncludePos); - if (startIt == String::npos || startIt > newLineAfter) - { - // try <> - startIt = inSource.find("<", afterIncludePos); - if (startIt == String::npos || startIt > newLineAfter) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Badly formed #include directive (expected \" or <) in file " - + fileName + ": " + inSource.substr(includePos, newLineAfter-includePos), - "CgProgram::preprocessor"); - } - else - { - endDelimeter = ">"; - } - } - size_t endIt = inSource.find(endDelimeter, startIt+1); - if (endIt == String::npos || endIt <= startIt) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Badly formed #include directive (expected " + endDelimeter + ") in file " - + fileName + ": " + inSource.substr(includePos, newLineAfter-includePos), - "CgProgram::preprocessor"); - } - - // extract filename - String filename(inSource.substr(startIt+1, endIt-startIt-1)); - - // open included file - DataStreamPtr resource = ResourceGroupManager::getSingleton(). - openResource(filename, resourceBeingLoaded->getGroup(), true, resourceBeingLoaded); - - // replace entire include directive line - // copy up to just before include - if (newLineBefore != String::npos && newLineBefore >= startMarker) - outSource.append(inSource.substr(startMarker, newLineBefore-startMarker+1)); - - size_t lineCount = 0; - size_t lineCountPos = 0; - - // Count the line number of #include statement - lineCountPos = outSource.find('\n'); - while(lineCountPos != String::npos) - { - lineCountPos = outSource.find('\n', lineCountPos+1); - lineCount++; - } - - // Add #line to the start of the included file to correct the line count - outSource.append("#line 1 \"" + filename + "\"\n"); - - outSource.append(resource->getAsString()); - - // Add #line to the end of the included file to correct the line count - outSource.append("\n#line " + Ogre::StringConverter::toString(lineCount) + - "\"" + fileName + "\"\n"); - - startMarker = newLineAfter; - - if (startMarker != String::npos) - i = inSource.find("#include", startMarker); - else - i = String::npos; - - } - // copy any remaining characters - outSource.append(inSource.substr(startMarker)); - - return outSource; - } + //----------------------------------------------------------------------- + String CgProgram::resolveCgIncludes(const String& inSource, Resource* resourceBeingLoaded, const String& fileName) + { + String outSource; + // output will be at least this big + outSource.reserve(inSource.length()); + + size_t startMarker = 0; + size_t i = inSource.find("#include"); + while (i != String::npos) + { + size_t includePos = i; + size_t afterIncludePos = includePos + 8; + size_t newLineBefore = inSource.rfind("\n", includePos); + + // check we're not in a comment + size_t lineCommentIt = inSource.rfind("//", includePos); + if (lineCommentIt != String::npos) + { + if (newLineBefore == String::npos || lineCommentIt > newLineBefore) + { + // commented + i = inSource.find("#include", afterIncludePos); + continue; + } + + } + size_t blockCommentIt = inSource.rfind("/*", includePos); + if (blockCommentIt != String::npos) + { + size_t closeCommentIt = inSource.rfind("*/", includePos); + if (closeCommentIt == String::npos || closeCommentIt < blockCommentIt) + { + // commented + i = inSource.find("#include", afterIncludePos); + continue; + } + + } + + // find following newline (or EOF) + size_t newLineAfter = inSource.find("\n", afterIncludePos); + // find include file string container + String endDelimeter = "\""; + size_t startIt = inSource.find("\"", afterIncludePos); + if (startIt == String::npos || startIt > newLineAfter) + { + // try <> + startIt = inSource.find("<", afterIncludePos); + if (startIt == String::npos || startIt > newLineAfter) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Badly formed #include directive (expected \" or <) in file " + + fileName + ": " + inSource.substr(includePos, newLineAfter-includePos), + "CgProgram::preprocessor"); + } + else + { + endDelimeter = ">"; + } + } + size_t endIt = inSource.find(endDelimeter, startIt+1); + if (endIt == String::npos || endIt <= startIt) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Badly formed #include directive (expected " + endDelimeter + ") in file " + + fileName + ": " + inSource.substr(includePos, newLineAfter-includePos), + "CgProgram::preprocessor"); + } + + // extract filename + String filename(inSource.substr(startIt+1, endIt-startIt-1)); + + // open included file + DataStreamPtr resource = ResourceGroupManager::getSingleton(). + openResource(filename, resourceBeingLoaded->getGroup(), true, resourceBeingLoaded); + + // replace entire include directive line + // copy up to just before include + if (newLineBefore != String::npos && newLineBefore >= startMarker) + outSource.append(inSource.substr(startMarker, newLineBefore-startMarker+1)); + + size_t lineCount = 0; + size_t lineCountPos = 0; + + // Count the line number of #include statement + lineCountPos = outSource.find('\n'); + while(lineCountPos != String::npos) + { + lineCountPos = outSource.find('\n', lineCountPos+1); + lineCount++; + } + + // Add #line to the start of the included file to correct the line count + outSource.append("#line 1 \"" + filename + "\"\n"); + + outSource.append(resource->getAsString()); + + // Add #line to the end of the included file to correct the line count + outSource.append("\n#line " + Ogre::StringConverter::toString(lineCount) + + "\"" + fileName + "\"\n"); + + startMarker = newLineAfter; + + if (startMarker != String::npos) + i = inSource.find("#include", startMarker); + else + i = String::npos; + + } + // copy any remaining characters + outSource.append(inSource.substr(startMarker)); + + return outSource; + } //----------------------------------------------------------------------- const String& CgProgram::getLanguage(void) const { diff --git a/PlugIns/CgProgramManager/src/OgreCgProgramFactory.cpp b/PlugIns/CgProgramManager/src/OgreCgProgramFactory.cpp index 6282714c7ab..708d42fb4f5 100644 --- a/PlugIns/CgProgramManager/src/OgreCgProgramFactory.cpp +++ b/PlugIns/CgProgramManager/src/OgreCgProgramFactory.cpp @@ -61,7 +61,7 @@ namespace Ogre { return OGRE_NEW CgProgram(creator, name, handle, group, isManual, loader, mCgContext); } //----------------------------------------------------------------------- - void CgProgramFactory::destroy(HighLevelGpuProgram* prog) + void CgProgramFactory::destroy(HighLevelGpuProgram* prog) { OGRE_DELETE prog; } diff --git a/PlugIns/CgProgramManager/src/OgreCgProgramManagerDll.cpp b/PlugIns/CgProgramManager/src/OgreCgProgramManagerDll.cpp index 1779f721282..377d659f9fb 100644 --- a/PlugIns/CgProgramManager/src/OgreCgProgramManagerDll.cpp +++ b/PlugIns/CgProgramManager/src/OgreCgProgramManagerDll.cpp @@ -47,8 +47,8 @@ namespace Ogre { } extern "C" void _OgreCgPluginExport dllStopPlugin(void) { - Root::getSingleton().uninstallPlugin(cgPlugin); - OGRE_DELETE cgPlugin; + Root::getSingleton().uninstallPlugin(cgPlugin); + OGRE_DELETE cgPlugin; } #endif diff --git a/PlugIns/EXRCodec/src/OgreEXRCodec.cpp b/PlugIns/EXRCodec/src/OgreEXRCodec.cpp index e5d5da56041..5b66eb2e948 100644 --- a/PlugIns/EXRCodec/src/OgreEXRCodec.cpp +++ b/PlugIns/EXRCodec/src/OgreEXRCodec.cpp @@ -50,53 +50,53 @@ using namespace Imf; namespace Ogre { void writeEXRHalf(OStream *ost, const float *pixels, - int width, int height, int components) + int width, int height, int components) { - //assert(components==3 || components==4); - // TODO: throw std::exception if invalid number of components - - Header header (width, height); - header.channels().insert ("R", Channel (HALF)); - header.channels().insert ("G", Channel (HALF)); - header.channels().insert ("B", Channel (HALF)); - if(components==4) - header.channels().insert ("A", Channel (HALF)); - - // Convert data to half - half *data = new half [width*height*components]; - - std::copy(pixels, pixels+(width*height*components), data); - - // And save it - OutputFile file (*ost, header); - FrameBuffer frameBuffer; - - frameBuffer.insert("R", // name - Slice (HALF, // type - ((char *) data)+0, // base - 2 * components, // xStride - 2 * components * width)); // yStride - frameBuffer.insert("G", // name - Slice (HALF, // type - ((char *) data)+2, // base - 2 * components, // xStride - 2 * components * width)); // yStride - frameBuffer.insert("B", // name - Slice (HALF, // type - ((char *) data)+4, // base - 2 * components, // xStride - 2 * components * width)); // yStride - if(components==4) { - frameBuffer.insert("A", // name - Slice (HALF, // type - ((char *) data)+6, // base - 2 * components, // xStride - 2 * components * width)); // yStride - } - - file.setFrameBuffer(frameBuffer); - file.writePixels(height); - delete data; + //assert(components==3 || components==4); + // TODO: throw std::exception if invalid number of components + + Header header (width, height); + header.channels().insert ("R", Channel (HALF)); + header.channels().insert ("G", Channel (HALF)); + header.channels().insert ("B", Channel (HALF)); + if(components==4) + header.channels().insert ("A", Channel (HALF)); + + // Convert data to half + half *data = new half [width*height*components]; + + std::copy(pixels, pixels+(width*height*components), data); + + // And save it + OutputFile file (*ost, header); + FrameBuffer frameBuffer; + + frameBuffer.insert("R", // name + Slice (HALF, // type + ((char *) data)+0, // base + 2 * components, // xStride + 2 * components * width)); // yStride + frameBuffer.insert("G", // name + Slice (HALF, // type + ((char *) data)+2, // base + 2 * components, // xStride + 2 * components * width)); // yStride + frameBuffer.insert("B", // name + Slice (HALF, // type + ((char *) data)+4, // base + 2 * components, // xStride + 2 * components * width)); // yStride + if(components==4) { + frameBuffer.insert("A", // name + Slice (HALF, // type + ((char *) data)+6, // base + 2 * components, // xStride + 2 * components * width)); // yStride + } + + file.setFrameBuffer(frameBuffer); + file.writePixels(height); + delete data; } diff --git a/PlugIns/OctreeSceneManager/include/OgreOctree.h b/PlugIns/OctreeSceneManager/include/OgreOctree.h index fc96ac4bc46..96f7439d17a 100644 --- a/PlugIns/OctreeSceneManager/include/OgreOctree.h +++ b/PlugIns/OctreeSceneManager/include/OgreOctree.h @@ -122,7 +122,7 @@ class Octree : public NodeAlloc void _getCullBounds( AxisAlignedBox * ) const; - typedef list< OctreeNode * >::type NodeList; + typedef list< OctreeNode * >::type NodeList; /** Public list of SceneNodes attached to this particular octree */ NodeList mNodes; diff --git a/PlugIns/OctreeSceneManager/include/OgreOctreeNode.h b/PlugIns/OctreeSceneManager/include/OgreOctreeNode.h index 77ceac66a5d..1ea36bed3bb 100644 --- a/PlugIns/OctreeSceneManager/include/OgreOctreeNode.h +++ b/PlugIns/OctreeSceneManager/include/OgreOctreeNode.h @@ -69,8 +69,8 @@ class _OgreOctreePluginExport OctreeNode : public SceneNode /** Overridden from Node to remove any reference to octants */ Node * removeChild( Node* child); - /** Overridden from Node to remove any reference to octants */ - void removeAllChildren(void); + /** Overridden from Node to remove any reference to octants */ + void removeAllChildren(void); /** Returns the Octree in which this OctreeNode resides */ @@ -93,7 +93,7 @@ class _OgreOctreePluginExport OctreeNode : public SceneNode /** Adds all the attached scenenodes to the render queue */ virtual void _addToRenderQueue( Camera* cam, RenderQueue * q, bool onlyShadowCasters, - VisibleObjectsBoundsInfo* visibleBounds); + VisibleObjectsBoundsInfo* visibleBounds); /** Sets up the LegacyRenderOperation for rendering this scene node as geometry. @remarks diff --git a/PlugIns/OctreeSceneManager/include/OgreOctreePlugin.h b/PlugIns/OctreeSceneManager/include/OgreOctreePlugin.h index cf5a0567f8d..b9dfca4578a 100644 --- a/PlugIns/OctreeSceneManager/include/OgreOctreePlugin.h +++ b/PlugIns/OctreeSceneManager/include/OgreOctreePlugin.h @@ -34,31 +34,31 @@ namespace Ogre { class OctreeSceneManagerFactory; - /** Plugin instance for Octree Manager */ - class OctreePlugin : public Plugin - { - public: - OctreePlugin(); + /** Plugin instance for Octree Manager */ + class OctreePlugin : public Plugin + { + public: + OctreePlugin(); - /// @copydoc Plugin::getName - const String& getName() const; + /// @copydoc Plugin::getName + const String& getName() const; - /// @copydoc Plugin::install - void install(); + /// @copydoc Plugin::install + void install(); - /// @copydoc Plugin::initialise - void initialise(); + /// @copydoc Plugin::initialise + void initialise(); - /// @copydoc Plugin::shutdown - void shutdown(); + /// @copydoc Plugin::shutdown + void shutdown(); - /// @copydoc Plugin::uninstall - void uninstall(); - protected: - OctreeSceneManagerFactory* mOctreeSMFactory; + /// @copydoc Plugin::uninstall + void uninstall(); + protected: + OctreeSceneManagerFactory* mOctreeSMFactory; - }; + }; } #endif diff --git a/PlugIns/OctreeSceneManager/include/OgreOctreePrerequisites.h b/PlugIns/OctreeSceneManager/include/OgreOctreePrerequisites.h index ee170b2993a..8a9007fddfe 100644 --- a/PlugIns/OctreeSceneManager/include/OgreOctreePrerequisites.h +++ b/PlugIns/OctreeSceneManager/include/OgreOctreePrerequisites.h @@ -46,7 +46,7 @@ THE SOFTWARE. # if defined( __MINGW32__ ) # define _OgreOctreePluginExport # else -# define _OgreOctreePluginExport __declspec(dllimport) +# define _OgreOctreePluginExport __declspec(dllimport) # endif # endif #elif defined ( OGRE_GCC_VISIBILITY ) diff --git a/PlugIns/OctreeSceneManager/include/OgreOctreeSceneManager.h b/PlugIns/OctreeSceneManager/include/OgreOctreeSceneManager.h index 9a56d4c22d9..138a74f3f2c 100644 --- a/PlugIns/OctreeSceneManager/include/OgreOctreeSceneManager.h +++ b/PlugIns/OctreeSceneManager/include/OgreOctreeSceneManager.h @@ -75,8 +75,8 @@ class _OgreOctreePluginExport OctreeSceneManager : public SceneManager /** Standard destructor */ ~OctreeSceneManager(); - /// @copydoc SceneManager::getTypeName - const String& getTypeName(void) const; + /// @copydoc SceneManager::getTypeName + const String& getTypeName(void) const; /** Initializes the manager to the given box and depth. */ @@ -98,7 +98,7 @@ class _OgreOctreePluginExport OctreeSceneManager : public SceneManager virtual void _updateSceneGraph( Camera * cam ); /** Recurses through the octree determining which nodes are visible. */ virtual void _findVisibleObjects ( Camera * cam, - VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters ); + VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters ); /** Alerts each unculled object, notifying it that it will be drawn. * Useful for doing calculations only on nodes that will be drawn, prior @@ -112,8 +112,8 @@ class _OgreOctreePluginExport OctreeSceneManager : public SceneManager all subchildren are automatically added with no visibility tests. */ void walkOctree( OctreeCamera *, RenderQueue *, Octree *, - VisibleObjectsBoundsInfo* visibleBounds, bool foundvisible, - bool onlyShadowCasters); + VisibleObjectsBoundsInfo* visibleBounds, bool foundvisible, + bool onlyShadowCasters); /** Checks the given OctreeNode, and determines if it needs to be moved * to a different octant. @@ -183,7 +183,7 @@ class _OgreOctreePluginExport OctreeSceneManager : public SceneManager protected: - Octree::NodeList mVisible; + Octree::NodeList mVisible; /// The root octree Octree *mOctree; @@ -214,14 +214,14 @@ class _OgreOctreePluginExport OctreeSceneManager : public SceneManager class OctreeSceneManagerFactory : public SceneManagerFactory { protected: - void initMetaData(void) const; + void initMetaData(void) const; public: - OctreeSceneManagerFactory() {} - ~OctreeSceneManagerFactory() {} - /// Factory type name - static const String FACTORY_TYPE_NAME; - SceneManager* createInstance(const String& instanceName); - void destroyInstance(SceneManager* instance); + OctreeSceneManagerFactory() {} + ~OctreeSceneManagerFactory() {} + /// Factory type name + static const String FACTORY_TYPE_NAME; + SceneManager* createInstance(const String& instanceName); + void destroyInstance(SceneManager* instance); }; diff --git a/PlugIns/OctreeSceneManager/src/OgreOctree.cpp b/PlugIns/OctreeSceneManager/src/OgreOctree.cpp index 8b014fd53dc..14527d9622d 100644 --- a/PlugIns/OctreeSceneManager/src/OgreOctree.cpp +++ b/PlugIns/OctreeSceneManager/src/OgreOctree.cpp @@ -45,9 +45,9 @@ namespace Ogre */ bool Octree::_isTwiceSize( const AxisAlignedBox &box ) const { - // infinite boxes never fit in a child - always root node - if (box.isInfinite()) - return false; + // infinite boxes never fit in a child - always root node + if (box.isInfinite()) + return false; Vector3 halfMBoxSize = mBox.getHalfSize(); Vector3 boxSize = box.getSize(); diff --git a/PlugIns/OctreeSceneManager/src/OgreOctreeCamera.cpp b/PlugIns/OctreeSceneManager/src/OgreOctreeCamera.cpp index e38a77a73e8..32b59355435 100644 --- a/PlugIns/OctreeSceneManager/src/OgreOctreeCamera.cpp +++ b/PlugIns/OctreeSceneManager/src/OgreOctreeCamera.cpp @@ -68,7 +68,7 @@ OctreeCamera::Visibility OctreeCamera::getVisibility( const AxisAlignedBox &boun if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0) continue; - // This updates frustum planes and deals with cull frustum + // This updates frustum planes and deals with cull frustum Plane::Side side = getFrustumPlane(plane).getSide(centre, halfSize); if(side == Plane::NEGATIVE_SIDE) return NONE; // We can't return now as the box could be later on the negative side of a plane. diff --git a/PlugIns/OctreeSceneManager/src/OgreOctreeNode.cpp b/PlugIns/OctreeSceneManager/src/OgreOctreeNode.cpp index 5c89eb486e0..111a89d2b21 100644 --- a/PlugIns/OctreeSceneManager/src/OgreOctreeNode.cpp +++ b/PlugIns/OctreeSceneManager/src/OgreOctreeNode.cpp @@ -84,17 +84,17 @@ Node * OctreeNode::removeChild( Node* child ) } void OctreeNode::removeAllChildren() { - ChildNodeMap::iterator i, iend; - iend = mChildren.end(); - for (i = mChildren.begin(); i != iend; ++i) - { - OctreeNode* on = static_cast(i->second); - on->setParent(0); - on->_removeNodeAndChildren(); - } - mChildren.clear(); - mChildrenToUpdate.clear(); - + ChildNodeMap::iterator i, iend; + iend = mChildren.end(); + for (i = mChildren.begin(); i != iend; ++i) + { + OctreeNode* on = static_cast(i->second); + on->setParent(0); + on->_removeNodeAndChildren(); + } + mChildren.clear(); + mChildrenToUpdate.clear(); + } Node * OctreeNode::removeChild( const String & name ) @@ -141,12 +141,12 @@ void OctreeNode::_updateBounds( void ) */ bool OctreeNode::_isIn( AxisAlignedBox &box ) { - // Always fail if not in the scene graph or box is null - if (!mIsInSceneGraph || box.isNull()) return false; + // Always fail if not in the scene graph or box is null + if (!mIsInSceneGraph || box.isNull()) return false; - // Always succeed if AABB is infinite - if (box.isInfinite()) - return true; + // Always succeed if AABB is infinite + if (box.isInfinite()) + return true; Vector3 center = mWorldAABB.getMaximum().midPoint( mWorldAABB.getMinimum() ); @@ -154,30 +154,30 @@ bool OctreeNode::_isIn( AxisAlignedBox &box ) Vector3 bmax = box.getMaximum(); bool centre = ( bmax > center && bmin < center ); - if (!centre) - return false; + if (!centre) + return false; - // Even if covering the centre line, need to make sure this BB is not large - // enough to require being moved up into parent. When added, bboxes would - // end up in parent due to cascade but when updating need to deal with - // bbox growing too large for this child - Vector3 octreeSize = bmax - bmin; - Vector3 nodeSize = mWorldAABB.getMaximum() - mWorldAABB.getMinimum(); - return nodeSize < octreeSize; + // Even if covering the centre line, need to make sure this BB is not large + // enough to require being moved up into parent. When added, bboxes would + // end up in parent due to cascade but when updating need to deal with + // bbox growing too large for this child + Vector3 octreeSize = bmax - bmin; + Vector3 nodeSize = mWorldAABB.getMaximum() - mWorldAABB.getMinimum(); + return nodeSize < octreeSize; } /** Adds the attached objects of this OctreeScene node into the queue. */ void OctreeNode::_addToRenderQueue( Camera* cam, RenderQueue *queue, - bool onlyShadowCasters, VisibleObjectsBoundsInfo* visibleBounds ) + bool onlyShadowCasters, VisibleObjectsBoundsInfo* visibleBounds ) { ObjectMap::iterator mit = mObjectsByName.begin(); while ( mit != mObjectsByName.end() ) { MovableObject * mo = mit->second; - - queue->processVisibleObject(mo, cam, onlyShadowCasters, visibleBounds); + + queue->processVisibleObject(mo, cam, onlyShadowCasters, visibleBounds); ++mit; } diff --git a/PlugIns/OctreeSceneManager/src/OgreOctreePlugin.cpp b/PlugIns/OctreeSceneManager/src/OgreOctreePlugin.cpp index c5fde77b1eb..91b61548008 100644 --- a/PlugIns/OctreeSceneManager/src/OgreOctreePlugin.cpp +++ b/PlugIns/OctreeSceneManager/src/OgreOctreePlugin.cpp @@ -32,46 +32,46 @@ THE SOFTWARE. namespace Ogre { - const String sPluginName = "Octree Scene Manager"; - //--------------------------------------------------------------------- - OctreePlugin::OctreePlugin() - :mOctreeSMFactory(0) - { + const String sPluginName = "Octree Scene Manager"; + //--------------------------------------------------------------------- + OctreePlugin::OctreePlugin() + :mOctreeSMFactory(0) + { - } - //--------------------------------------------------------------------- - const String& OctreePlugin::getName() const - { - return sPluginName; - } - //--------------------------------------------------------------------- - void OctreePlugin::install() - { - // Create objects - mOctreeSMFactory = OGRE_NEW OctreeSceneManagerFactory(); + } + //--------------------------------------------------------------------- + const String& OctreePlugin::getName() const + { + return sPluginName; + } + //--------------------------------------------------------------------- + void OctreePlugin::install() + { + // Create objects + mOctreeSMFactory = OGRE_NEW OctreeSceneManagerFactory(); - } - //--------------------------------------------------------------------- - void OctreePlugin::initialise() - { - // Register - Root::getSingleton().addSceneManagerFactory(mOctreeSMFactory); - } - //--------------------------------------------------------------------- - void OctreePlugin::shutdown() - { - // Unregister - Root::getSingleton().removeSceneManagerFactory(mOctreeSMFactory); - } - //--------------------------------------------------------------------- - void OctreePlugin::uninstall() - { - // destroy - OGRE_DELETE mOctreeSMFactory; - mOctreeSMFactory = 0; + } + //--------------------------------------------------------------------- + void OctreePlugin::initialise() + { + // Register + Root::getSingleton().addSceneManagerFactory(mOctreeSMFactory); + } + //--------------------------------------------------------------------- + void OctreePlugin::shutdown() + { + // Unregister + Root::getSingleton().removeSceneManagerFactory(mOctreeSMFactory); + } + //--------------------------------------------------------------------- + void OctreePlugin::uninstall() + { + // destroy + OGRE_DELETE mOctreeSMFactory; + mOctreeSMFactory = 0; - } + } } diff --git a/PlugIns/OctreeSceneManager/src/OgreOctreeSceneManager.cpp b/PlugIns/OctreeSceneManager/src/OgreOctreeSceneManager.cpp index 81c74b49c56..6210758299f 100644 --- a/PlugIns/OctreeSceneManager/src/OgreOctreeSceneManager.cpp +++ b/PlugIns/OctreeSceneManager/src/OgreOctreeSceneManager.cpp @@ -44,14 +44,14 @@ extern "C" { void findNodesInBox( Ogre::SceneManager *sm, const Ogre::AxisAlignedBox &box, - Ogre::list< Ogre::SceneNode * >::type &list, + Ogre::list< Ogre::SceneNode * >::type &list, Ogre::SceneNode *exclude ) { static_cast( sm ) -> findNodesIn( box, list, exclude ); } void findNodesInSphere( Ogre::SceneManager *sm, const Ogre::Sphere &sphere, - Ogre::list< Ogre::SceneNode * >::type &list, + Ogre::list< Ogre::SceneNode * >::type &list, Ogre::SceneNode *exclude ) { static_cast( sm ) -> findNodesIn( sphere, list, exclude ); @@ -73,8 +73,8 @@ Intersection intersect( const Ray &one, const AxisAlignedBox &two ) OctreeSceneManager::intersect_call++; // Null box? if (two.isNull()) return OUTSIDE; - // Infinite box? - if (two.isInfinite()) return INTERSECT; + // Infinite box? + if (two.isInfinite()) return INTERSECT; bool inside = true; const Vector3& twoMin = two.getMinimum(); @@ -144,8 +144,8 @@ Intersection intersect( const PlaneBoundedVolume &one, const AxisAlignedBox &two OctreeSceneManager::intersect_call++; // Null box? if (two.isNull()) return OUTSIDE; - // Infinite box? - if (two.isInfinite()) return INTERSECT; + // Infinite box? + if (two.isInfinite()) return INTERSECT; // Get centre of the box Vector3 centre = two.getCenter(); @@ -185,8 +185,8 @@ Intersection intersect( const AxisAlignedBox &one, const AxisAlignedBox &two ) OctreeSceneManager::intersect_call++; // Null box? if (one.isNull() || two.isNull()) return OUTSIDE; - if (one.isInfinite()) return INSIDE; - if (two.isInfinite()) return INTERSECT; + if (one.isInfinite()) return INSIDE; + if (two.isInfinite()) return INTERSECT; const Vector3& insideMin = two.getMinimum(); @@ -226,7 +226,7 @@ Intersection intersect( const Sphere &one, const AxisAlignedBox &two ) OctreeSceneManager::intersect_call++; // Null box? if (two.isNull()) return OUTSIDE; - if (two.isInfinite()) return INTERSECT; + if (two.isInfinite()) return INTERSECT; float sradius = one.getRadius(); @@ -307,7 +307,7 @@ OctreeSceneManager::OctreeSceneManager(const String& name, AxisAlignedBox &box, const String& OctreeSceneManager::getTypeName(void) const { - return OctreeSceneManagerFactory::FACTORY_TYPE_NAME; + return OctreeSceneManagerFactory::FACTORY_TYPE_NAME; } void OctreeSceneManager::init( AxisAlignedBox &box, int depth ) @@ -352,29 +352,29 @@ OctreeSceneManager::~OctreeSceneManager() { if ( mOctree ) - { + { OGRE_DELETE mOctree; - mOctree = 0; - } + mOctree = 0; + } } Camera * OctreeSceneManager::createCamera( const String &name ) { - // Check name not used - if (mCameras.find(name) != mCameras.end()) - { - OGRE_EXCEPT( - Exception::ERR_DUPLICATE_ITEM, - "A camera with the name " + name + " already exists", - "OctreeSceneManager::createCamera" ); - } - - Camera * c = OGRE_NEW OctreeCamera( name, this ); + // Check name not used + if (mCameras.find(name) != mCameras.end()) + { + OGRE_EXCEPT( + Exception::ERR_DUPLICATE_ITEM, + "A camera with the name " + name + " already exists", + "OctreeSceneManager::createCamera" ); + } + + Camera * c = OGRE_NEW OctreeCamera( name, this ); mCameras.insert( CameraList::value_type( name, c ) ); - // create visible bounds aab map entry - mCamVisibleObjectsMap[c] = VisibleObjectsBoundsInfo(); - + // create visible bounds aab map entry + mCamVisibleObjectsMap[c] = VisibleObjectsBoundsInfo(); + return c; } @@ -411,9 +411,9 @@ void OctreeSceneManager::_updateOctreeNode( OctreeNode * onode ) if ( box.isNull() ) return ; - // Skip if octree has been destroyed (shutdown conditions) - if (!mOctree) - return; + // Skip if octree has been destroyed (shutdown conditions) + if (!mOctree) + return; if ( onode -> getOctant() == 0 ) { @@ -441,9 +441,9 @@ void OctreeSceneManager::_updateOctreeNode( OctreeNode * onode ) */ void OctreeSceneManager::_removeOctreeNode( OctreeNode * n ) { - // Skip if octree has been destroyed (shutdown conditions) - if (!mOctree) - return; + // Skip if octree has been destroyed (shutdown conditions) + if (!mOctree) + return; Octree * oct = n -> getOctant(); @@ -459,11 +459,11 @@ void OctreeSceneManager::_removeOctreeNode( OctreeNode * n ) void OctreeSceneManager::_addOctreeNode( OctreeNode * n, Octree *octant, int depth ) { - // Skip if octree has been destroyed (shutdown conditions) - if (!mOctree) - return; + // Skip if octree has been destroyed (shutdown conditions) + if (!mOctree) + return; - const AxisAlignedBox& bx = n -> _getWorldAABB(); + const AxisAlignedBox& bx = n -> _getWorldAABB(); //if the octree is twice as big as the scene node, @@ -563,7 +563,7 @@ void OctreeSceneManager::_alertVisibleObjects( void ) } void OctreeSceneManager::_findVisibleObjects(Camera * cam, - VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters ) + VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters ) { getRenderQueue()->clear(); @@ -574,7 +574,7 @@ void OctreeSceneManager::_findVisibleObjects(Camera * cam, //walk the octree, adding all visible Octreenodes nodes to the render queue. walkOctree( static_cast < OctreeCamera * > ( cam ), getRenderQueue(), mOctree, - visibleBounds, false, onlyShadowCasters ); + visibleBounds, false, onlyShadowCasters ); // Show the octree boxes & cull camera if required if ( mShowBoxes ) @@ -587,8 +587,8 @@ void OctreeSceneManager::_findVisibleObjects(Camera * cam, } void OctreeSceneManager::walkOctree( OctreeCamera *camera, RenderQueue *queue, - Octree *octant, VisibleObjectsBoundsInfo* visibleBounds, - bool foundvisible, bool onlyShadowCasters ) + Octree *octant, VisibleObjectsBoundsInfo* visibleBounds, + bool foundvisible, bool onlyShadowCasters ) { //return immediately if nothing is in the node. @@ -692,146 +692,146 @@ void OctreeSceneManager::walkOctree( OctreeCamera *camera, RenderQueue *queue, void _findNodes( const AxisAlignedBox &t, list< SceneNode * >::type &list, SceneNode *exclude, bool full, Octree *octant ) { - if ( !full ) - { - AxisAlignedBox obox; - octant -> _getCullBounds( &obox ); + if ( !full ) + { + AxisAlignedBox obox; + octant -> _getCullBounds( &obox ); - Intersection isect = intersect( t, obox ); + Intersection isect = intersect( t, obox ); - if ( isect == OUTSIDE ) - return ; + if ( isect == OUTSIDE ) + return ; - full = ( isect == INSIDE ); - } + full = ( isect == INSIDE ); + } - Octree::NodeList::iterator it = octant -> mNodes.begin(); + Octree::NodeList::iterator it = octant -> mNodes.begin(); - while ( it != octant -> mNodes.end() ) - { - OctreeNode * on = ( *it ); + while ( it != octant -> mNodes.end() ) + { + OctreeNode * on = ( *it ); - if ( on != exclude ) - { - if ( full ) - { - list.push_back( on ); - } + if ( on != exclude ) + { + if ( full ) + { + list.push_back( on ); + } - else - { - Intersection nsect = intersect( t, on -> _getWorldAABB() ); + else + { + Intersection nsect = intersect( t, on -> _getWorldAABB() ); - if ( nsect != OUTSIDE ) - { - list.push_back( on ); - } - } + if ( nsect != OUTSIDE ) + { + list.push_back( on ); + } + } - } + } - ++it; - } + ++it; + } - Octree* child; + Octree* child; - if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); } void _findNodes( const Sphere &t, list< SceneNode * >::type &list, SceneNode *exclude, bool full, Octree *octant ) { - if ( !full ) - { - AxisAlignedBox obox; - octant -> _getCullBounds( &obox ); + if ( !full ) + { + AxisAlignedBox obox; + octant -> _getCullBounds( &obox ); - Intersection isect = intersect( t, obox ); + Intersection isect = intersect( t, obox ); - if ( isect == OUTSIDE ) - return ; + if ( isect == OUTSIDE ) + return ; - full = ( isect == INSIDE ); - } + full = ( isect == INSIDE ); + } - Octree::NodeList::iterator it = octant -> mNodes.begin(); + Octree::NodeList::iterator it = octant -> mNodes.begin(); - while ( it != octant -> mNodes.end() ) - { - OctreeNode * on = ( *it ); + while ( it != octant -> mNodes.end() ) + { + OctreeNode * on = ( *it ); - if ( on != exclude ) - { - if ( full ) - { - list.push_back( on ); - } + if ( on != exclude ) + { + if ( full ) + { + list.push_back( on ); + } - else - { - Intersection nsect = intersect( t, on -> _getWorldAABB() ); + else + { + Intersection nsect = intersect( t, on -> _getWorldAABB() ); - if ( nsect != OUTSIDE ) - { - list.push_back( on ); - } - } + if ( nsect != OUTSIDE ) + { + list.push_back( on ); + } + } - } + } - ++it; - } + ++it; + } - Octree* child; + Octree* child; - if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); } @@ -839,146 +839,146 @@ void _findNodes( const Sphere &t, list< SceneNode * >::type &list, SceneNode *ex void _findNodes( const PlaneBoundedVolume &t, list< SceneNode * >::type &list, SceneNode *exclude, bool full, Octree *octant ) { - if ( !full ) - { - AxisAlignedBox obox; - octant -> _getCullBounds( &obox ); + if ( !full ) + { + AxisAlignedBox obox; + octant -> _getCullBounds( &obox ); - Intersection isect = intersect( t, obox ); + Intersection isect = intersect( t, obox ); - if ( isect == OUTSIDE ) - return ; + if ( isect == OUTSIDE ) + return ; - full = ( isect == INSIDE ); - } + full = ( isect == INSIDE ); + } - Octree::NodeList::iterator it = octant -> mNodes.begin(); + Octree::NodeList::iterator it = octant -> mNodes.begin(); - while ( it != octant -> mNodes.end() ) - { - OctreeNode * on = ( *it ); + while ( it != octant -> mNodes.end() ) + { + OctreeNode * on = ( *it ); - if ( on != exclude ) - { - if ( full ) - { - list.push_back( on ); - } + if ( on != exclude ) + { + if ( full ) + { + list.push_back( on ); + } - else - { - Intersection nsect = intersect( t, on -> _getWorldAABB() ); + else + { + Intersection nsect = intersect( t, on -> _getWorldAABB() ); - if ( nsect != OUTSIDE ) - { - list.push_back( on ); - } - } + if ( nsect != OUTSIDE ) + { + list.push_back( on ); + } + } - } + } - ++it; - } + ++it; + } - Octree* child; + Octree* child; - if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); } void _findNodes( const Ray &t, list< SceneNode * >::type &list, SceneNode *exclude, bool full, Octree *octant ) { - if ( !full ) - { - AxisAlignedBox obox; - octant -> _getCullBounds( &obox ); + if ( !full ) + { + AxisAlignedBox obox; + octant -> _getCullBounds( &obox ); - Intersection isect = intersect( t, obox ); + Intersection isect = intersect( t, obox ); - if ( isect == OUTSIDE ) - return ; + if ( isect == OUTSIDE ) + return ; - full = ( isect == INSIDE ); - } + full = ( isect == INSIDE ); + } - Octree::NodeList::iterator it = octant -> mNodes.begin(); + Octree::NodeList::iterator it = octant -> mNodes.begin(); - while ( it != octant -> mNodes.end() ) - { - OctreeNode * on = ( *it ); + while ( it != octant -> mNodes.end() ) + { + OctreeNode * on = ( *it ); - if ( on != exclude ) - { - if ( full ) - { - list.push_back( on ); - } + if ( on != exclude ) + { + if ( full ) + { + list.push_back( on ); + } - else - { - Intersection nsect = intersect( t, on -> _getWorldAABB() ); + else + { + Intersection nsect = intersect( t, on -> _getWorldAABB() ); - if ( nsect != OUTSIDE ) - { - list.push_back( on ); - } - } + if ( nsect != OUTSIDE ) + { + list.push_back( on ); + } + } - } + } - ++it; - } + ++it; + } - Octree* child; + Octree* child; - if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); - if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) - _findNodes( t, list, exclude, full, child ); + if ( (child=octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) + _findNodes( t, list, exclude, full, child ); } @@ -1014,9 +1014,9 @@ void OctreeSceneManager::resize( const AxisAlignedBox &box ) mOctree = OGRE_NEW Octree( 0 ); mOctree->mBox = box; - const Vector3 &min = box.getMinimum(); - const Vector3 &max = box.getMaximum(); - mOctree->mHalfSize = ( max - min ) * 0.5f; + const Vector3 &min = box.getMinimum(); + const Vector3 &max = box.getMaximum(); + mOctree->mHalfSize = ( max - min ) * 0.5f; it = nodes.begin(); @@ -1041,8 +1041,8 @@ bool OctreeSceneManager::setOption( const String & key, const void * val ) else if ( key == "Depth" ) { mMaxDepth = * static_cast < const int * > ( val ); - // copy the box since resize will delete mOctree and reference won't work - AxisAlignedBox box = mOctree->mBox; + // copy the box since resize will delete mOctree and reference won't work + AxisAlignedBox box = mOctree->mBox; resize(box); return true; } @@ -1148,21 +1148,21 @@ const String OctreeSceneManagerFactory::FACTORY_TYPE_NAME = "OctreeSceneManager" //----------------------------------------------------------------------- void OctreeSceneManagerFactory::initMetaData(void) const { - mMetaData.typeName = FACTORY_TYPE_NAME; - mMetaData.description = "Scene manager organising the scene on the basis of an octree."; - mMetaData.sceneTypeMask = 0xFFFF; // support all types - mMetaData.worldGeometrySupported = false; + mMetaData.typeName = FACTORY_TYPE_NAME; + mMetaData.description = "Scene manager organising the scene on the basis of an octree."; + mMetaData.sceneTypeMask = 0xFFFF; // support all types + mMetaData.worldGeometrySupported = false; } //----------------------------------------------------------------------- SceneManager* OctreeSceneManagerFactory::createInstance( - const String& instanceName) + const String& instanceName) { - return OGRE_NEW OctreeSceneManager(instanceName); + return OGRE_NEW OctreeSceneManager(instanceName); } //----------------------------------------------------------------------- void OctreeSceneManagerFactory::destroyInstance(SceneManager* instance) { - OGRE_DELETE instance; + OGRE_DELETE instance; } diff --git a/PlugIns/OctreeSceneManager/src/OgreOctreeSceneManagerDll.cpp b/PlugIns/OctreeSceneManager/src/OgreOctreeSceneManagerDll.cpp index 320ba1ded08..d6d78a6d247 100644 --- a/PlugIns/OctreeSceneManager/src/OgreOctreeSceneManagerDll.cpp +++ b/PlugIns/OctreeSceneManager/src/OgreOctreeSceneManagerDll.cpp @@ -47,8 +47,8 @@ extern "C" void _OgreOctreePluginExport dllStartPlugin( void ) } extern "C" void _OgreOctreePluginExport dllStopPlugin( void ) { - Root::getSingleton().uninstallPlugin(octreePlugin); - OGRE_DELETE octreePlugin; + Root::getSingleton().uninstallPlugin(octreePlugin); + OGRE_DELETE octreePlugin; } } diff --git a/PlugIns/OctreeSceneManager/src/OgreOctreeSceneQuery.cpp b/PlugIns/OctreeSceneManager/src/OgreOctreeSceneQuery.cpp index f4895a4487e..b74df093abe 100644 --- a/PlugIns/OctreeSceneManager/src/OgreOctreeSceneQuery.cpp +++ b/PlugIns/OctreeSceneManager/src/OgreOctreeSceneQuery.cpp @@ -63,64 +63,64 @@ void OctreeIntersectionSceneQuery::execute(IntersectionSceneQueryListener* liste MovableSet set; - // Iterate over all movable types - Root::MovableObjectFactoryIterator factIt = - Root::getSingleton().getMovableObjectFactoryIterator(); - while(factIt.hasMoreElements()) - { - SceneManager::MovableObjectIterator it = - mParentSceneMgr->getMovableObjectIterator( - factIt.getNext()->getType()); - while( it.hasMoreElements() ) - { - - MovableObject * e = it.getNext(); - - Ogre::list< SceneNode * >::type list; - //find the nodes that intersect the AAB - static_cast( mParentSceneMgr ) -> findNodesIn( e->getWorldBoundingBox(), list, 0 ); - //grab all moveables from the node that intersect... - Ogre::list< SceneNode * >::type::iterator nit = list.begin(); - while( nit != list.end() ) - { - SceneNode::ObjectIterator oit = (*nit) -> getAttachedObjectIterator(); - while( oit.hasMoreElements() ) - { - MovableObject * m = oit.getNext(); - - if( m != e && - set.find( MovablePair(e,m)) == set.end() && - set.find( MovablePair(m,e)) == set.end() && - (m->getQueryFlags() & mQueryMask) && - (m->getTypeFlags() & mQueryTypeMask) && - m->isInScene() && - e->getWorldBoundingBox().intersects( m->getWorldBoundingBox() ) ) - { - listener -> queryResult( e, m ); - // deal with attached objects, since they are not directly attached to nodes - if (m->getMovableType() == "Entity") - { - Entity* e2 = static_cast(m); - Entity::ChildObjectListIterator childIt = e2->getAttachedObjectIterator(); - while(childIt.hasMoreElements()) - { - MovableObject* c = childIt.getNext(); - if (c->getQueryFlags() & mQueryMask && - e->getWorldBoundingBox().intersects( c->getWorldBoundingBox() )) - { - listener->queryResult(e, c); - } - } - } - } - set.insert( MovablePair(e,m) ); - - } - ++nit; - } - - } - } + // Iterate over all movable types + Root::MovableObjectFactoryIterator factIt = + Root::getSingleton().getMovableObjectFactoryIterator(); + while(factIt.hasMoreElements()) + { + SceneManager::MovableObjectIterator it = + mParentSceneMgr->getMovableObjectIterator( + factIt.getNext()->getType()); + while( it.hasMoreElements() ) + { + + MovableObject * e = it.getNext(); + + Ogre::list< SceneNode * >::type list; + //find the nodes that intersect the AAB + static_cast( mParentSceneMgr ) -> findNodesIn( e->getWorldBoundingBox(), list, 0 ); + //grab all moveables from the node that intersect... + Ogre::list< SceneNode * >::type::iterator nit = list.begin(); + while( nit != list.end() ) + { + SceneNode::ObjectIterator oit = (*nit) -> getAttachedObjectIterator(); + while( oit.hasMoreElements() ) + { + MovableObject * m = oit.getNext(); + + if( m != e && + set.find( MovablePair(e,m)) == set.end() && + set.find( MovablePair(m,e)) == set.end() && + (m->getQueryFlags() & mQueryMask) && + (m->getTypeFlags() & mQueryTypeMask) && + m->isInScene() && + e->getWorldBoundingBox().intersects( m->getWorldBoundingBox() ) ) + { + listener -> queryResult( e, m ); + // deal with attached objects, since they are not directly attached to nodes + if (m->getMovableType() == "Entity") + { + Entity* e2 = static_cast(m); + Entity::ChildObjectListIterator childIt = e2->getAttachedObjectIterator(); + while(childIt.hasMoreElements()) + { + MovableObject* c = childIt.getNext(); + if (c->getQueryFlags() & mQueryMask && + e->getWorldBoundingBox().intersects( c->getWorldBoundingBox() )) + { + listener->queryResult(e, c); + } + } + } + } + set.insert( MovablePair(e,m) ); + + } + ++nit; + } + + } + } } /** Creates a custom Octree AAB query */ OctreeAxisAlignedBoxSceneQuery::OctreeAxisAlignedBoxSceneQuery(SceneManager* creator) @@ -147,25 +147,25 @@ void OctreeAxisAlignedBoxSceneQuery::execute(SceneQueryListener* listener) { MovableObject * m = oit.getNext(); if( (m->getQueryFlags() & mQueryMask) && - (m->getTypeFlags() & mQueryTypeMask) && - m->isInScene() && - mAABB.intersects( m->getWorldBoundingBox() ) ) + (m->getTypeFlags() & mQueryTypeMask) && + m->isInScene() && + mAABB.intersects( m->getWorldBoundingBox() ) ) { listener -> queryResult( m ); - // deal with attached objects, since they are not directly attached to nodes - if (m->getMovableType() == "Entity") - { - Entity* e = static_cast(m); - Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); - while(childIt.hasMoreElements()) - { - MovableObject* c = childIt.getNext(); - if (c->getQueryFlags() & mQueryMask) - { - listener->queryResult(c); - } - } - } + // deal with attached objects, since they are not directly attached to nodes + if (m->getMovableType() == "Entity") + { + Entity* e = static_cast(m); + Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); + while(childIt.hasMoreElements()) + { + MovableObject* c = childIt.getNext(); + if (c->getQueryFlags() & mQueryMask) + { + listener->queryResult(c); + } + } + } } } @@ -198,31 +198,31 @@ void OctreeRaySceneQuery::execute(RaySceneQueryListener* listener) { MovableObject * m = oit.getNext(); if( (m->getQueryFlags() & mQueryMask) && - (m->getTypeFlags() & mQueryTypeMask) && m->isInScene() ) + (m->getTypeFlags() & mQueryTypeMask) && m->isInScene() ) { std::pair result = mRay.intersects(m->getWorldBoundingBox()); if( result.first ) { listener -> queryResult( m, result.second ); - // deal with attached objects, since they are not directly attached to nodes - if (m->getMovableType() == "Entity") - { - Entity* e = static_cast(m); - Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); - while(childIt.hasMoreElements()) - { - MovableObject* c = childIt.getNext(); - if (c->getQueryFlags() & mQueryMask) - { - result = mRay.intersects(c->getWorldBoundingBox()); - if (result.first) - { - listener->queryResult(c, result.second); - } - } - } - } + // deal with attached objects, since they are not directly attached to nodes + if (m->getMovableType() == "Entity") + { + Entity* e = static_cast(m); + Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); + while(childIt.hasMoreElements()) + { + MovableObject* c = childIt.getNext(); + if (c->getQueryFlags() & mQueryMask) + { + result = mRay.intersects(c->getWorldBoundingBox()); + if (result.first) + { + listener->queryResult(c, result.second); + } + } + } + } } } } @@ -257,26 +257,26 @@ void OctreeSphereSceneQuery::execute(SceneQueryListener* listener) { MovableObject * m = oit.getNext(); if( (m->getQueryFlags() & mQueryMask) && - (m->getTypeFlags() & mQueryTypeMask) && - m->isInScene() && - mSphere.intersects( m->getWorldBoundingBox() ) ) + (m->getTypeFlags() & mQueryTypeMask) && + m->isInScene() && + mSphere.intersects( m->getWorldBoundingBox() ) ) { listener -> queryResult( m ); - // deal with attached objects, since they are not directly attached to nodes - if (m->getMovableType() == "Entity") - { - Entity* e = static_cast(m); - Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); - while(childIt.hasMoreElements()) - { - MovableObject* c = childIt.getNext(); - if (c->getQueryFlags() & mQueryMask && - mSphere.intersects( c->getWorldBoundingBox())) - { - listener->queryResult(c); - } - } - } + // deal with attached objects, since they are not directly attached to nodes + if (m->getMovableType() == "Entity") + { + Entity* e = static_cast(m); + Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); + while(childIt.hasMoreElements()) + { + MovableObject* c = childIt.getNext(); + if (c->getQueryFlags() & mQueryMask && + mSphere.intersects( c->getWorldBoundingBox())) + { + listener->queryResult(c); + } + } + } } } @@ -319,26 +319,26 @@ void OctreePlaneBoundedVolumeListSceneQuery::execute(SceneQueryListener* listene { MovableObject * m = oit.getNext(); if( (m->getQueryFlags() & mQueryMask) && - (m->getTypeFlags() & mQueryTypeMask) && - m->isInScene() && - (*pi).intersects( m->getWorldBoundingBox() ) ) + (m->getTypeFlags() & mQueryTypeMask) && + m->isInScene() && + (*pi).intersects( m->getWorldBoundingBox() ) ) { listener -> queryResult( m ); - // deal with attached objects, since they are not directly attached to nodes - if (m->getMovableType() == "Entity") - { - Entity* e = static_cast(m); - Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); - while(childIt.hasMoreElements()) - { - MovableObject* c = childIt.getNext(); - if (c->getQueryFlags() & mQueryMask && - (*pi).intersects( c->getWorldBoundingBox())) - { - listener->queryResult(c); - } - } - } + // deal with attached objects, since they are not directly attached to nodes + if (m->getMovableType() == "Entity") + { + Entity* e = static_cast(m); + Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); + while(childIt.hasMoreElements()) + { + MovableObject* c = childIt.getNext(); + if (c->getQueryFlags() & mQueryMask && + (*pi).intersects( c->getWorldBoundingBox())) + { + listener->queryResult(c); + } + } + } } } } diff --git a/PlugIns/OctreeZone/include/OgreOctreeZone.h b/PlugIns/OctreeZone/include/OgreOctreeZone.h index f574d449d5e..44363393ed2 100644 --- a/PlugIns/OctreeZone/include/OgreOctreeZone.h +++ b/PlugIns/OctreeZone/include/OgreOctreeZone.h @@ -32,7 +32,7 @@ Octants. For details on Zones in general, see PCZone.h/cpp. begin : Mon Apr 16 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -47,18 +47,18 @@ namespace Ogre { /** Octree version of PCZone */ - class Octree; - class OctreeZoneData; + class Octree; + class OctreeZoneData; - class _OgreOctreeZonePluginExport OctreeZone : public PCZone + class _OgreOctreeZonePluginExport OctreeZone : public PCZone { public: OctreeZone( PCZSceneManager *, const String& ); virtual ~OctreeZone(); - /** Set the enclosure node for this OctreeZone - */ - virtual void setEnclosureNode(PCZSceneNode *); + /** Set the enclosure node for this OctreeZone + */ + virtual void setEnclosureNode(PCZSceneNode *); /** Adds an SceneNode to this OctreeZone. @remarks @@ -71,22 +71,22 @@ namespace Ogre */ virtual void removeNode( PCZSceneNode * ); - /** Remove all nodes from the node reference list and clear it - */ - virtual void _clearNodeLists(short nodeListTypes); + /** Remove all nodes from the node reference list and clear it + */ + virtual void _clearNodeLists(short nodeListTypes); - /** Indicates whether or not this zone requires zone-specific data for - * each scene node - */ - virtual bool requiresZoneSpecificNodeData(void); + /** Indicates whether or not this zone requires zone-specific data for + * each scene node + */ + virtual bool requiresZoneSpecificNodeData(void); - /** Create zone specific data for a node - */ - virtual void createNodeZoneData(PCZSceneNode *); + /** Create zone specific data for a node + */ + virtual void createNodeZoneData(PCZSceneNode *); - /** (recursive) Check the given node against all portals in the zone - */ - virtual void _checkNodeAgainstPortals(PCZSceneNode *, Portal * ); + /** (recursive) Check the given node against all portals in the zone + */ + virtual void _checkNodeAgainstPortals(PCZSceneNode *, Portal * ); /** (recursive) Check the given light against all portals in the zone */ @@ -95,15 +95,15 @@ namespace Ogre PCZFrustum *, Portal*); - /** Update the zone data for each portal - */ - void updatePortalsZoneData(void); + /** Update the zone data for each portal + */ + void updatePortalsZoneData(void); - /** Mark nodes dirty base on moving portals. */ - void dirtyNodeByMovingPortals(void); + /** Mark nodes dirty base on moving portals. */ + void dirtyNodeByMovingPortals(void); - /** Update a node's home zone */ - virtual PCZone * updateNodeHomeZone(PCZSceneNode * pczsn, bool allowBackTouces); + /** Update a node's home zone */ + virtual PCZone * updateNodeHomeZone(PCZSceneNode * pczsn, bool allowBackTouces); /** Find and add visible objects to the render queue. @remarks @@ -111,145 +111,145 @@ namespace Ogre This is a recursive call (the main call should be to _findVisibleObjects) */ virtual void findVisibleNodes(PCZCamera *, - NodeList & visibleNodeList, - RenderQueue * queue, - VisibleObjectsBoundsInfo* visibleBounds, - bool onlyShadowCasters, - bool displayNodes, - bool showBoundingBoxes); - - /** Functions for finding Nodes that intersect various shapes */ - virtual void _findNodes(const AxisAlignedBox &t, - PCZSceneNodeList &list, + NodeList & visibleNodeList, + RenderQueue * queue, + VisibleObjectsBoundsInfo* visibleBounds, + bool onlyShadowCasters, + bool displayNodes, + bool showBoundingBoxes); + + /** Functions for finding Nodes that intersect various shapes */ + virtual void _findNodes(const AxisAlignedBox &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude); - virtual void _findNodes(const Sphere &t, - PCZSceneNodeList &list, + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude); + virtual void _findNodes(const Sphere &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ); - virtual void _findNodes(const PlaneBoundedVolume &t, - PCZSceneNodeList &list, + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ); + virtual void _findNodes(const PlaneBoundedVolume &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ); - virtual void _findNodes(const Ray &t, - PCZSceneNodeList &list, + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ); + virtual void _findNodes(const Ray &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ); + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ); - /** Sets the given option for the Zone + /** Sets the given option for the Zone @remarks - Options are: - "Size", AxisAlignedBox *; - "Depth", int *; - "ShowOctree", bool *; - */ - virtual bool setOption( const String &, const void * ); - - /** Called when the scene manager creates a camera because - some zone managers (like TerrainZone) need the camera info. - */ - virtual void notifyCameraCreated( Camera* c ); - - /** Called by PCZSM during setWorldGeometryRenderQueue() */ - virtual void notifyWorldGeometryRenderQueue(uint8 qid); - - /** Called when a _renderScene is called in the SceneManager */ - virtual void notifyBeginRenderScene(void); - - /** Called by PCZSM during setZoneGeometry() */ - virtual void setZoneGeometry(const String &filename, PCZSceneNode * parentNode); - - /** Get the world coordinate aabb of the zone */ - virtual void getAABB(AxisAlignedBox &); - - /// Init function carried over from OctreeSceneManager - void init(AxisAlignedBox &box, int depth); - /** Resizes the octree to the given size */ - void resize( const AxisAlignedBox &box ); - /** Checks the given OctreeNode, and determines if it needs to be moved - * to a different octant. - */ - void updateNodeOctant( OctreeZoneData * zoneData ); - /** Removes the node from the octree it is in */ - void removeNodeFromOctree( PCZSceneNode * ); - /** Adds the Octree Node, starting at the given octree, and recursing at max to the specified depth. - */ - void addNodeToOctree( PCZSceneNode *, Octree *octree, int depth = 0 ); - - - protected: - /** Walks through the octree, adding any visible objects to the render queue. - @remarks - If any octant in the octree if completely within the view frustum, - all subchildren are automatically added with no visibility tests. - */ - void walkOctree( PCZCamera *, - NodeList &, - RenderQueue *, - Octree *, + Options are: + "Size", AxisAlignedBox *; + "Depth", int *; + "ShowOctree", bool *; + */ + virtual bool setOption( const String &, const void * ); + + /** Called when the scene manager creates a camera because + some zone managers (like TerrainZone) need the camera info. + */ + virtual void notifyCameraCreated( Camera* c ); + + /** Called by PCZSM during setWorldGeometryRenderQueue() */ + virtual void notifyWorldGeometryRenderQueue(uint8 qid); + + /** Called when a _renderScene is called in the SceneManager */ + virtual void notifyBeginRenderScene(void); + + /** Called by PCZSM during setZoneGeometry() */ + virtual void setZoneGeometry(const String &filename, PCZSceneNode * parentNode); + + /** Get the world coordinate aabb of the zone */ + virtual void getAABB(AxisAlignedBox &); + + /// Init function carried over from OctreeSceneManager + void init(AxisAlignedBox &box, int depth); + /** Resizes the octree to the given size */ + void resize( const AxisAlignedBox &box ); + /** Checks the given OctreeNode, and determines if it needs to be moved + * to a different octant. + */ + void updateNodeOctant( OctreeZoneData * zoneData ); + /** Removes the node from the octree it is in */ + void removeNodeFromOctree( PCZSceneNode * ); + /** Adds the Octree Node, starting at the given octree, and recursing at max to the specified depth. + */ + void addNodeToOctree( PCZSceneNode *, Octree *octree, int depth = 0 ); + + + protected: + /** Walks through the octree, adding any visible objects to the render queue. + @remarks + If any octant in the octree if completely within the view frustum, + all subchildren are automatically added with no visibility tests. + */ + void walkOctree( PCZCamera *, + NodeList &, + RenderQueue *, + Octree *, VisibleObjectsBoundsInfo* visibleBounds, - bool foundvisible, - bool onlyShadowCasters, - bool displayNodes, - bool showBoundingBoxes); - - protected: - /// The root octree - Octree *mOctree; - /// Max depth for the tree - int mMaxDepth; - /// Size of the octree - AxisAlignedBox mBox; + bool foundvisible, + bool onlyShadowCasters, + bool displayNodes, + bool showBoundingBoxes); + + protected: + /// The root octree + Octree *mOctree; + /// Max depth for the tree + int mMaxDepth; + /// Size of the octree + AxisAlignedBox mBox; }; - class _OgreOctreeZonePluginExport OctreeZoneData : public ZoneData - { - public: - /** Standard Constructor */ - OctreeZoneData(PCZSceneNode *, PCZone * ); - /** Standard destructor */ - ~OctreeZoneData(); - /** Update data */ - void update(void); - - /** Returns the Octree in which this OctreeNode resides - */ - Octree * getOctant() - { - return mOctant; - }; - /** Sets the Octree in which this OctreeNode resides - */ - void setOctant( Octree *o ) - { - mOctant = o; - }; - bool _isIn( AxisAlignedBox &box ); - - public: - /// Octree this node is attached to. - Octree * mOctant; - /// Octree-specific world bounding box (only includes attached objects, not children) - AxisAlignedBox mOctreeWorldAABB; - }; + class _OgreOctreeZonePluginExport OctreeZoneData : public ZoneData + { + public: + /** Standard Constructor */ + OctreeZoneData(PCZSceneNode *, PCZone * ); + /** Standard destructor */ + ~OctreeZoneData(); + /** Update data */ + void update(void); + + /** Returns the Octree in which this OctreeNode resides + */ + Octree * getOctant() + { + return mOctant; + }; + /** Sets the Octree in which this OctreeNode resides + */ + void setOctant( Octree *o ) + { + mOctant = o; + }; + bool _isIn( AxisAlignedBox &box ); + + public: + /// Octree this node is attached to. + Octree * mOctant; + /// Octree-specific world bounding box (only includes attached objects, not children) + AxisAlignedBox mOctreeWorldAABB; + }; /// Factory for OctreeZone class OctreeZoneFactory : public PCZoneFactory { - public: - OctreeZoneFactory(); - virtual ~OctreeZoneFactory(); + public: + OctreeZoneFactory(); + virtual ~OctreeZoneFactory(); - bool supportsPCZoneType(const String& zoneType); - PCZone* createPCZone(PCZSceneManager * pczsm, const String& zoneName); + bool supportsPCZoneType(const String& zoneType); + PCZone* createPCZone(PCZSceneManager * pczsm, const String& zoneName); }; } diff --git a/PlugIns/OctreeZone/include/OgreOctreeZoneOctree.h b/PlugIns/OctreeZone/include/OgreOctreeZoneOctree.h index c1b57429efb..bcef6f8d199 100644 --- a/PlugIns/OctreeZone/include/OgreOctreeZoneOctree.h +++ b/PlugIns/OctreeZone/include/OgreOctreeZoneOctree.h @@ -131,7 +131,7 @@ class Octree : public SceneCtlAllocatedObject void _findNodes(const AxisAlignedBox &t, PCZSceneNodeList &list, PCZSceneNode *exclude, - bool includeVisitors, + bool includeVisitors, bool full ); /* Recurse through the Octree to find the scene nodes which intersect a ray @@ -139,7 +139,7 @@ class Octree : public SceneCtlAllocatedObject void _findNodes(const Ray &t, PCZSceneNodeList &list, PCZSceneNode *exclude, - bool includeVisitors, + bool includeVisitors, bool full ); /* Recurse through the Octree to find the scene nodes which intersect a sphere @@ -147,7 +147,7 @@ class Octree : public SceneCtlAllocatedObject void _findNodes(const Sphere &t, PCZSceneNodeList &list, PCZSceneNode *exclude, - bool includeVisitors, + bool includeVisitors, bool full ); /* Recurse through the Octree to find the scene nodes which intersect a PBV @@ -155,15 +155,15 @@ class Octree : public SceneCtlAllocatedObject void _findNodes(const PlaneBoundedVolume &t, PCZSceneNodeList &list, PCZSceneNode *exclude, - bool includeVisitors, + bool includeVisitors, bool full ); /** Public list of SceneNodes attached to this particular octree */ PCZSceneNodeList mNodes; - /* Zone that this octree is in */ - PCZone * mZone; + /* Zone that this octree is in */ + PCZone * mZone; protected: diff --git a/PlugIns/OctreeZone/include/OgreOctreeZonePlugin.h b/PlugIns/OctreeZone/include/OgreOctreeZonePlugin.h index c596265dc91..d74cfeaa55e 100644 --- a/PlugIns/OctreeZone/include/OgreOctreeZonePlugin.h +++ b/PlugIns/OctreeZone/include/OgreOctreeZonePlugin.h @@ -30,7 +30,7 @@ OgreOctreeZonePlugin.h - Octree Zone Plugin class for PCZSceneManager begin : Mon Apr 16 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -43,30 +43,30 @@ namespace Ogre { class OctreeZoneFactory; - /** Plugin instance for OctreeZone */ - class OctreeZonePlugin : public Plugin - { - public: - OctreeZonePlugin(); + /** Plugin instance for OctreeZone */ + class OctreeZonePlugin : public Plugin + { + public: + OctreeZonePlugin(); - /// @copydoc Plugin::getName - const String& getName() const; + /// @copydoc Plugin::getName + const String& getName() const; - /// @copydoc Plugin::install - void install(); + /// @copydoc Plugin::install + void install(); - /// @copydoc Plugin::initialise - void initialise(); + /// @copydoc Plugin::initialise + void initialise(); - /// @copydoc Plugin::shutdown - void shutdown(); + /// @copydoc Plugin::shutdown + void shutdown(); - /// @copydoc Plugin::uninstall - void uninstall(); - protected: - OctreeZoneFactory* mOctreeZoneFactory; + /// @copydoc Plugin::uninstall + void uninstall(); + protected: + OctreeZoneFactory* mOctreeZoneFactory; - }; + }; } #endif diff --git a/PlugIns/OctreeZone/include/OgreOctreeZonePrerequisites.h b/PlugIns/OctreeZone/include/OgreOctreeZonePrerequisites.h index 6e5827c5281..9f87f49a3f0 100644 --- a/PlugIns/OctreeZone/include/OgreOctreeZonePrerequisites.h +++ b/PlugIns/OctreeZone/include/OgreOctreeZonePrerequisites.h @@ -30,7 +30,7 @@ OgreOctreeZonePrerequisites.h - Octree organized Zone for PCZSceneManager begin : Mon Apr 16 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ diff --git a/PlugIns/OctreeZone/src/OgreOctreeZone.cpp b/PlugIns/OctreeZone/src/OgreOctreeZone.cpp index 3f11c71ae5f..ed9b56ce99b 100644 --- a/PlugIns/OctreeZone/src/OgreOctreeZone.cpp +++ b/PlugIns/OctreeZone/src/OgreOctreeZone.cpp @@ -47,67 +47,67 @@ email : ericc@xenopi.com namespace Ogre { OctreeZone::OctreeZone( PCZSceneManager * creator, const String& name ) - : PCZone(creator, name) + : PCZone(creator, name) { - mZoneTypeName = "ZoneType_Octree"; - // init octree - AxisAlignedBox b( -10000, -10000, -10000, 10000, 10000, 10000 ); - int depth = 8; - mOctree = 0; - init( b, depth ); - } + mZoneTypeName = "ZoneType_Octree"; + // init octree + AxisAlignedBox b( -10000, -10000, -10000, 10000, 10000, 10000 ); + int depth = 8; + mOctree = 0; + init( b, depth ); + } OctreeZone::~OctreeZone() { - // portals & nodelist are deleted in PCZone destructor. - - // delete octree - if ( mOctree ) - { - OGRE_DELETE mOctree; - mOctree = 0; - } + // portals & nodelist are deleted in PCZone destructor. + + // delete octree + if ( mOctree ) + { + OGRE_DELETE mOctree; + mOctree = 0; + } } - /** Set the enclosure node for this OctreeZone - */ - void OctreeZone::setEnclosureNode(PCZSceneNode * node) - { - mEnclosureNode = node; - if (node) - { - // anchor the node to this zone - node->anchorToHomeZone(this); - // make sure node world bounds are up to date - node->_updateBounds(); - // resize the octree to the same size as the enclosure node bounding box - resize(node->_getWorldAABB()); - } - } + /** Set the enclosure node for this OctreeZone + */ + void OctreeZone::setEnclosureNode(PCZSceneNode * node) + { + mEnclosureNode = node; + if (node) + { + // anchor the node to this zone + node->anchorToHomeZone(this); + // make sure node world bounds are up to date + node->_updateBounds(); + // resize the octree to the same size as the enclosure node bounding box + resize(node->_getWorldAABB()); + } + } // this call adds the given node to either the zone's list - // of nodes at home in the zone, or to the list of visiting nodes - // NOTE: The list is decided by the node's homeZone value, so - // that must be set correctly before calling this function. + // of nodes at home in the zone, or to the list of visiting nodes + // NOTE: The list is decided by the node's homeZone value, so + // that must be set correctly before calling this function. void OctreeZone::_addNode( PCZSceneNode * n ) { - if (n->getHomeZone() == this) - { - // add a reference to this node in the "nodes at home in this zone" list - mHomeNodeList.insert( n ); - } - else - { - // add a reference to this node in the "nodes visiting this zone" list - mVisitorNodeList.insert( n ); - } + if (n->getHomeZone() == this) + { + // add a reference to this node in the "nodes at home in this zone" list + mHomeNodeList.insert( n ); + } + else + { + // add a reference to this node in the "nodes visiting this zone" list + mVisitorNodeList.insert( n ); + } } void OctreeZone::removeNode( PCZSceneNode * n ) { - if ( n != 0 ) + if ( n != 0 ) { - removeNodeFromOctree( n ); + removeNodeFromOctree( n ); if (n->getHomeZone() == this) { @@ -121,97 +121,97 @@ namespace Ogre } } - /** Remove all nodes from the node reference list and clear it - */ - void OctreeZone::_clearNodeLists(short nodeListTypes) - { - if (nodeListTypes & HOME_NODE_LIST) - { - PCZSceneNodeList::iterator it = mHomeNodeList.begin(); - while( it != mHomeNodeList.end()) - { - PCZSceneNode * sn = *it; - removeNodeFromOctree( sn ); - ++it; - } - mHomeNodeList.clear(); - } - if (nodeListTypes & VISITOR_NODE_LIST) - { - PCZSceneNodeList::iterator it = mVisitorNodeList.begin(); - while( it != mVisitorNodeList.end()) - { - PCZSceneNode * sn = *it; - removeNodeFromOctree( sn ); - ++it; - } - mVisitorNodeList.clear(); - } - } - - /** Indicates whether or not this zone requires zone-specific data for - * each scene node - */ - bool OctreeZone::requiresZoneSpecificNodeData(void) - { - // Octree Zones have zone specific node data - return true; - } - - /** create zone specific data for a node - */ - void OctreeZone::createNodeZoneData(PCZSceneNode * node) - { - OctreeZoneData * ozd = OGRE_NEW OctreeZoneData(node, this); - if (ozd) - { - node->setZoneData(this, ozd); - } - } - - /* Recursively check for intersection of the given scene node - * with zone portals. If the node touches a portal, then the - * connected zone is assumed to be touched. The zone adds - * the node to its node list and the node adds the zone to - * its visiting zone list. - * - * NOTE: This function assumes that the home zone of the node - * is correct. The function "_updateHomeZone" in PCZSceneManager - * takes care of this and should have been called before - * this function. - */ - - void OctreeZone::_checkNodeAgainstPortals(PCZSceneNode * pczsn, Portal * ignorePortal) - { - if (pczsn == mEnclosureNode || - pczsn->allowedToVisit() == false) - { - // don't do any checking of enclosure node versus portals - return; - } - - PCZone * connectedZone; - for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) - { - Portal * p = *it; - //Check if the portal intersects the node - if (p != ignorePortal && p->intersects(pczsn) != Portal::NO_INTERSECT) - { - // node is touching this portal - connectedZone = p->getTargetZone(); - // add zone to the nodes visiting zone list unless it is the home zone of the node - if (connectedZone != pczsn->getHomeZone() && - !pczsn->isVisitingZone(connectedZone)) - { - pczsn->addZoneToVisitingZonesMap(connectedZone); - // tell the connected zone that the node is visiting it - connectedZone->_addNode(pczsn); - //recurse into the connected zone - connectedZone->_checkNodeAgainstPortals(pczsn, p->getTargetPortal()); - } - } - } - } + /** Remove all nodes from the node reference list and clear it + */ + void OctreeZone::_clearNodeLists(short nodeListTypes) + { + if (nodeListTypes & HOME_NODE_LIST) + { + PCZSceneNodeList::iterator it = mHomeNodeList.begin(); + while( it != mHomeNodeList.end()) + { + PCZSceneNode * sn = *it; + removeNodeFromOctree( sn ); + ++it; + } + mHomeNodeList.clear(); + } + if (nodeListTypes & VISITOR_NODE_LIST) + { + PCZSceneNodeList::iterator it = mVisitorNodeList.begin(); + while( it != mVisitorNodeList.end()) + { + PCZSceneNode * sn = *it; + removeNodeFromOctree( sn ); + ++it; + } + mVisitorNodeList.clear(); + } + } + + /** Indicates whether or not this zone requires zone-specific data for + * each scene node + */ + bool OctreeZone::requiresZoneSpecificNodeData(void) + { + // Octree Zones have zone specific node data + return true; + } + + /** create zone specific data for a node + */ + void OctreeZone::createNodeZoneData(PCZSceneNode * node) + { + OctreeZoneData * ozd = OGRE_NEW OctreeZoneData(node, this); + if (ozd) + { + node->setZoneData(this, ozd); + } + } + + /* Recursively check for intersection of the given scene node + * with zone portals. If the node touches a portal, then the + * connected zone is assumed to be touched. The zone adds + * the node to its node list and the node adds the zone to + * its visiting zone list. + * + * NOTE: This function assumes that the home zone of the node + * is correct. The function "_updateHomeZone" in PCZSceneManager + * takes care of this and should have been called before + * this function. + */ + + void OctreeZone::_checkNodeAgainstPortals(PCZSceneNode * pczsn, Portal * ignorePortal) + { + if (pczsn == mEnclosureNode || + pczsn->allowedToVisit() == false) + { + // don't do any checking of enclosure node versus portals + return; + } + + PCZone * connectedZone; + for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) + { + Portal * p = *it; + //Check if the portal intersects the node + if (p != ignorePortal && p->intersects(pczsn) != Portal::NO_INTERSECT) + { + // node is touching this portal + connectedZone = p->getTargetZone(); + // add zone to the nodes visiting zone list unless it is the home zone of the node + if (connectedZone != pczsn->getHomeZone() && + !pczsn->isVisitingZone(connectedZone)) + { + pczsn->addZoneToVisitingZonesMap(connectedZone); + // tell the connected zone that the node is visiting it + connectedZone->_addNode(pczsn); + //recurse into the connected zone + connectedZone->_checkNodeAgainstPortals(pczsn, p->getTargetPortal()); + } + } + } + } /** (recursive) check the given light against all portals in the zone * NOTE: This is the default implementation, which doesn't take advantage @@ -222,46 +222,46 @@ namespace Ogre PCZFrustum *portalFrustum, Portal * ignorePortal) { - for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) - { - Portal * p = *it; - if (p != ignorePortal) - { - // calculate the direction vector from light to portal - Vector3 lightToPortal = p->getDerivedCP() - light->getDerivedPosition(); - if (portalFrustum->isVisible(p)) - { - // portal is facing the light, but some light types need to - // check illumination radius too. - PCZone * targetZone = p->getTargetZone(); - switch(light->getType()) - { - case Light::LT_POINT: - // point lights - just check if within illumination range - if (lightToPortal.length() <= light->getAttenuationRange()) - { - // if portal is quad portal it must be pointing towards the light - if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || - (p->getType() != Portal::PORTAL_TYPE_QUAD)) - { - if (!light->affectsZone(targetZone)) - { - light->addZoneToAffectedZonesList(targetZone); - if (targetZone->getLastVisibleFrame() == frameCount) - { - light->setAffectsVisibleZone(true); - } - // set culling frustum from the portal - portalFrustum->addPortalCullingPlanes(p); - // recurse into the target zone of the portal - p->getTargetZone()->_checkLightAgainstPortals(light, - frameCount, - portalFrustum, - p->getTargetPortal()); - // remove the planes added by this portal - portalFrustum->removePortalCullingPlanes(p); - } - } + for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) + { + Portal * p = *it; + if (p != ignorePortal) + { + // calculate the direction vector from light to portal + Vector3 lightToPortal = p->getDerivedCP() - light->getDerivedPosition(); + if (portalFrustum->isVisible(p)) + { + // portal is facing the light, but some light types need to + // check illumination radius too. + PCZone * targetZone = p->getTargetZone(); + switch(light->getType()) + { + case Light::LT_POINT: + // point lights - just check if within illumination range + if (lightToPortal.length() <= light->getAttenuationRange()) + { + // if portal is quad portal it must be pointing towards the light + if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || + (p->getType() != Portal::PORTAL_TYPE_QUAD)) + { + if (!light->affectsZone(targetZone)) + { + light->addZoneToAffectedZonesList(targetZone); + if (targetZone->getLastVisibleFrame() == frameCount) + { + light->setAffectsVisibleZone(true); + } + // set culling frustum from the portal + portalFrustum->addPortalCullingPlanes(p); + // recurse into the target zone of the portal + p->getTargetZone()->_checkLightAgainstPortals(light, + frameCount, + portalFrustum, + p->getTargetPortal()); + // remove the planes added by this portal + portalFrustum->removePortalCullingPlanes(p); + } + } } break; case Light::LT_DIRECTIONAL: @@ -269,28 +269,28 @@ namespace Ogre // the direction is facing the portal if (lightToPortal.dotProduct(light->getDerivedDirection()) >= 0.0) { - // if portal is quad portal it must be pointing towards the light - if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || - (p->getType() != Portal::PORTAL_TYPE_QUAD)) - { - if (!light->affectsZone(targetZone)) - { - light->addZoneToAffectedZonesList(targetZone); - if (targetZone->getLastVisibleFrame() == frameCount) - { - light->setAffectsVisibleZone(true); - } - // set culling frustum from the portal - portalFrustum->addPortalCullingPlanes(p); - // recurse into the target zone of the portal - p->getTargetZone()->_checkLightAgainstPortals(light, - frameCount, - portalFrustum, - p->getTargetPortal()); - // remove the planes added by this portal - portalFrustum->removePortalCullingPlanes(p); - } - } + // if portal is quad portal it must be pointing towards the light + if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || + (p->getType() != Portal::PORTAL_TYPE_QUAD)) + { + if (!light->affectsZone(targetZone)) + { + light->addZoneToAffectedZonesList(targetZone); + if (targetZone->getLastVisibleFrame() == frameCount) + { + light->setAffectsVisibleZone(true); + } + // set culling frustum from the portal + portalFrustum->addPortalCullingPlanes(p); + // recurse into the target zone of the portal + p->getTargetZone()->_checkLightAgainstPortals(light, + frameCount, + portalFrustum, + p->getTargetPortal()); + // remove the planes added by this portal + portalFrustum->removePortalCullingPlanes(p); + } + } } break; case Light::LT_SPOTLIGHT: @@ -300,28 +300,28 @@ namespace Ogre // as a future optimisation. if (lightToPortal.length() <= light->getAttenuationRange()) { - // if portal is quad portal it must be pointing towards the light - if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || - (p->getType() != Portal::PORTAL_TYPE_QUAD)) - { - if (!light->affectsZone(targetZone)) - { - light->addZoneToAffectedZonesList(targetZone); - if (targetZone->getLastVisibleFrame() == frameCount) - { - light->setAffectsVisibleZone(true); - } - // set culling frustum from the portal - portalFrustum->addPortalCullingPlanes(p); - // recurse into the target zone of the portal - p->getTargetZone()->_checkLightAgainstPortals(light, - frameCount, - portalFrustum, - p->getTargetPortal()); - // remove the planes added by this portal - portalFrustum->removePortalCullingPlanes(p); - } - } + // if portal is quad portal it must be pointing towards the light + if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || + (p->getType() != Portal::PORTAL_TYPE_QUAD)) + { + if (!light->affectsZone(targetZone)) + { + light->addZoneToAffectedZonesList(targetZone); + if (targetZone->getLastVisibleFrame() == frameCount) + { + light->setAffectsVisibleZone(true); + } + // set culling frustum from the portal + portalFrustum->addPortalCullingPlanes(p); + // recurse into the target zone of the portal + p->getTargetZone()->_checkLightAgainstPortals(light, + frameCount, + portalFrustum, + p->getTargetPortal()); + // remove the planes added by this portal + portalFrustum->removePortalCullingPlanes(p); + } + } } break; } @@ -330,217 +330,217 @@ namespace Ogre } } - /** Update the zone data for the portals in the zone - * NOTE: All portal spatial data must be up-to-date before calling this routine. - */ - void OctreeZone::updatePortalsZoneData(void) - { - PortalList transferPortalList; - AntiPortalList transferAntiPortalList; - // check each portal to see if it's intersecting another portal of smaller size - for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) - { - Portal * p = *it; - bool portalNeedUpdate = p->needUpdate(); - - Real pRadius = p->getRadius(); - - // First we check against portals in the SAME zone (and only if they have a - // target zone different from the home zone) - // Here we check only against portals that moved and of smaller size. - - // We do not need to check portal againts previous portals - // since it would have been already checked. - // Hence we start with the next portal after the current portal. - PortalList::iterator it2 = it; - for ( ++it2; it2 != mPortals.end(); ++it2 ) - { - Portal * p2 = (*it2); - - // Skip portal if it doesn't need updating. - // If both portals are not moving, then there's no need to check between them. - if (!portalNeedUpdate && !p2->needUpdate()) continue; - - // Skip portal if it's not pointing to another zone. - if (p2->getTargetZone() == this) continue; - - // Skip portal if it's pointing to the same target zone as this portal points to - if (p2->getTargetZone() == p->getTargetZone()) continue; - - if (pRadius > p2->getRadius()) - { - // Portal#1 is bigger than Portal#2, check for crossing - if (p2->getCurrentHomeZone() != p->getTargetZone() && p2->crossedPortal(p)) - { - // portal#2 crossed portal#1 - flag portal#2 to be moved to portal#1's target zone - p2->setNewHomeZone(p->getTargetZone()); - transferPortalList.push_back(p2); - } - } - else if (pRadius < p2->getRadius()) - { - // Portal #2 is bigger than Portal #1, check for crossing - if (p->getCurrentHomeZone() != p2->getTargetZone() && p->crossedPortal(p2)) - { - // portal#1 crossed portal#2 - flag portal#1 to be moved to portal#2's target zone - p->setNewHomeZone(p2->getTargetZone()); - transferPortalList.push_back(p); - continue; - } - } - } - - // Secondly we check againts the antiportals of this zone. - for (AntiPortalList::iterator ait = mAntiPortals.begin(); ait != mAntiPortals.end(); ++ait) - { - AntiPortal* ap = (*ait); - - // Skip portal if it doesn't need updating. - // If both portals are not moving, then there's no need to check between them. - if (!portalNeedUpdate && !ap->needUpdate()) continue; - - // only check for crossing if AntiPortal smaller than portal. - if (pRadius > ap->getRadius()) - { - // Portal#1 is bigger than AntiPortal, check for crossing - if (ap->crossedPortal(p)) - { - // AntiPortal crossed Portal#1 - flag AntiPortal to be moved to Portal#1's target zone - ap->setNewHomeZone(p->getTargetZone()); - transferAntiPortalList.push_back(ap); - } - } - } - - // Skip portal if it doesn't need updating. - if (!portalNeedUpdate) continue; - - // Thirdly we check against portals in the target zone (and only if that target - // zone is different from the home zone) - PCZone * tzone = p->getTargetZone(); - if (tzone != this) - { - for ( PortalList::iterator it3 = tzone->mPortals.begin(); it3 != tzone->mPortals.end(); ++it3 ) - { - Portal * p3 = (*it3); - // only check against bigger regular portals - if (pRadius < p3->getRadius()) - { - // Portal#3 is bigger than Portal#1, check for crossing - if (p->getCurrentHomeZone() != p3->getTargetZone() && p->crossedPortal(p3)) - { - // Portal#1 crossed Portal#3 - switch target zones for Portal#1 - p->setTargetZone(p3->getTargetZone()); - break; - } - } - } - } - } - // transfer any portals to new zones that have been flagged - for ( PortalList::iterator it = transferPortalList.begin(); it != transferPortalList.end(); ++it ) - { - Portal * p = *it; - if (p->getNewHomeZone() != 0) - { - _removePortal(p); - p->getNewHomeZone()->_addPortal(p); - p->setNewHomeZone(0); - } - } - // transfer any anti portals to new zones that have been flagged - for (AntiPortalList::iterator it = transferAntiPortalList.begin(); it != transferAntiPortalList.end(); ++it) - { - AntiPortal* p = *it; - if (p->getNewHomeZone() != 0) - { - _removeAntiPortal(p); - p->getNewHomeZone()->_addAntiPortal(p); - p->setNewHomeZone(0); - } - } - } - - /** Mark nodes dirty base on moving portals. */ - void OctreeZone::dirtyNodeByMovingPortals(void) - { - // Octree zone is a space partitioned zone. - // Hence we can smartly grab nodes of interest and flag them. - for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) - { - Portal* p = *it; - if (p->needUpdate()) - { - PCZSceneNodeList nodeList; - mOctree->_findNodes(p->getAAB(), nodeList, NULL, true, false); - PCZSceneNodeList::iterator i = nodeList.begin(); - while ( i != nodeList.end() ) - { - (*i)->setMoved(true); - ++i; - } - } - } - } + /** Update the zone data for the portals in the zone + * NOTE: All portal spatial data must be up-to-date before calling this routine. + */ + void OctreeZone::updatePortalsZoneData(void) + { + PortalList transferPortalList; + AntiPortalList transferAntiPortalList; + // check each portal to see if it's intersecting another portal of smaller size + for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) + { + Portal * p = *it; + bool portalNeedUpdate = p->needUpdate(); + + Real pRadius = p->getRadius(); + + // First we check against portals in the SAME zone (and only if they have a + // target zone different from the home zone) + // Here we check only against portals that moved and of smaller size. + + // We do not need to check portal againts previous portals + // since it would have been already checked. + // Hence we start with the next portal after the current portal. + PortalList::iterator it2 = it; + for ( ++it2; it2 != mPortals.end(); ++it2 ) + { + Portal * p2 = (*it2); + + // Skip portal if it doesn't need updating. + // If both portals are not moving, then there's no need to check between them. + if (!portalNeedUpdate && !p2->needUpdate()) continue; + + // Skip portal if it's not pointing to another zone. + if (p2->getTargetZone() == this) continue; + + // Skip portal if it's pointing to the same target zone as this portal points to + if (p2->getTargetZone() == p->getTargetZone()) continue; + + if (pRadius > p2->getRadius()) + { + // Portal#1 is bigger than Portal#2, check for crossing + if (p2->getCurrentHomeZone() != p->getTargetZone() && p2->crossedPortal(p)) + { + // portal#2 crossed portal#1 - flag portal#2 to be moved to portal#1's target zone + p2->setNewHomeZone(p->getTargetZone()); + transferPortalList.push_back(p2); + } + } + else if (pRadius < p2->getRadius()) + { + // Portal #2 is bigger than Portal #1, check for crossing + if (p->getCurrentHomeZone() != p2->getTargetZone() && p->crossedPortal(p2)) + { + // portal#1 crossed portal#2 - flag portal#1 to be moved to portal#2's target zone + p->setNewHomeZone(p2->getTargetZone()); + transferPortalList.push_back(p); + continue; + } + } + } + + // Secondly we check againts the antiportals of this zone. + for (AntiPortalList::iterator ait = mAntiPortals.begin(); ait != mAntiPortals.end(); ++ait) + { + AntiPortal* ap = (*ait); + + // Skip portal if it doesn't need updating. + // If both portals are not moving, then there's no need to check between them. + if (!portalNeedUpdate && !ap->needUpdate()) continue; + + // only check for crossing if AntiPortal smaller than portal. + if (pRadius > ap->getRadius()) + { + // Portal#1 is bigger than AntiPortal, check for crossing + if (ap->crossedPortal(p)) + { + // AntiPortal crossed Portal#1 - flag AntiPortal to be moved to Portal#1's target zone + ap->setNewHomeZone(p->getTargetZone()); + transferAntiPortalList.push_back(ap); + } + } + } + + // Skip portal if it doesn't need updating. + if (!portalNeedUpdate) continue; + + // Thirdly we check against portals in the target zone (and only if that target + // zone is different from the home zone) + PCZone * tzone = p->getTargetZone(); + if (tzone != this) + { + for ( PortalList::iterator it3 = tzone->mPortals.begin(); it3 != tzone->mPortals.end(); ++it3 ) + { + Portal * p3 = (*it3); + // only check against bigger regular portals + if (pRadius < p3->getRadius()) + { + // Portal#3 is bigger than Portal#1, check for crossing + if (p->getCurrentHomeZone() != p3->getTargetZone() && p->crossedPortal(p3)) + { + // Portal#1 crossed Portal#3 - switch target zones for Portal#1 + p->setTargetZone(p3->getTargetZone()); + break; + } + } + } + } + } + // transfer any portals to new zones that have been flagged + for ( PortalList::iterator it = transferPortalList.begin(); it != transferPortalList.end(); ++it ) + { + Portal * p = *it; + if (p->getNewHomeZone() != 0) + { + _removePortal(p); + p->getNewHomeZone()->_addPortal(p); + p->setNewHomeZone(0); + } + } + // transfer any anti portals to new zones that have been flagged + for (AntiPortalList::iterator it = transferAntiPortalList.begin(); it != transferAntiPortalList.end(); ++it) + { + AntiPortal* p = *it; + if (p->getNewHomeZone() != 0) + { + _removeAntiPortal(p); + p->getNewHomeZone()->_addAntiPortal(p); + p->setNewHomeZone(0); + } + } + } + + /** Mark nodes dirty base on moving portals. */ + void OctreeZone::dirtyNodeByMovingPortals(void) + { + // Octree zone is a space partitioned zone. + // Hence we can smartly grab nodes of interest and flag them. + for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) + { + Portal* p = *it; + if (p->needUpdate()) + { + PCZSceneNodeList nodeList; + mOctree->_findNodes(p->getAAB(), nodeList, NULL, true, false); + PCZSceneNodeList::iterator i = nodeList.begin(); + while ( i != nodeList.end() ) + { + (*i)->setMoved(true); + ++i; + } + } + } + } /* The following function checks if a node has left it's current home zone. - * This is done by checking each portal in the zone. If the node has crossed - * the portal, then the current zone is no longer the home zone of the node. The - * function then recurses into the connected zones. Once a zone is found where - * the node does NOT cross out through a portal, that zone is the new home zone. - NOTE: For this function to work, the node must start out in the proper zone to - begin with! - */ + * This is done by checking each portal in the zone. If the node has crossed + * the portal, then the current zone is no longer the home zone of the node. The + * function then recurses into the connected zones. Once a zone is found where + * the node does NOT cross out through a portal, that zone is the new home zone. + NOTE: For this function to work, the node must start out in the proper zone to + begin with! + */ PCZone* OctreeZone::updateNodeHomeZone( PCZSceneNode * pczsn, bool allowBackTouches ) { - // default to newHomeZone being the current home zone - PCZone * newHomeZone = pczsn->getHomeZone(); - - // Check all portals of the start zone for crossings! - Portal* portal; - PortalList::iterator pi, piend; - piend = mPortals.end(); - for (pi = mPortals.begin(); pi != piend; pi++) - { - portal = *pi; - - Portal::PortalIntersectResult pir = portal->intersects(pczsn); - switch (pir) - { - default: - case Portal::NO_INTERSECT: // node does not intersect portal - do nothing - case Portal::INTERSECT_NO_CROSS:// node intersects but does not cross portal - do nothing - break; - case Portal::INTERSECT_BACK_NO_CROSS:// node intersects but on the back of the portal - if (allowBackTouches) - { - // node is on wrong side of the portal - fix if we're allowing backside touches - if (portal->getTargetZone() != this && - portal->getTargetZone() != pczsn->getHomeZone()) - { - // set the home zone of the node to the target zone of the portal - pczsn->setHomeZone(portal->getTargetZone()); - // continue checking for portal crossings in the new zone - newHomeZone = portal->getTargetZone()->updateNodeHomeZone(pczsn, false); - } - } - break; - case Portal::INTERSECT_CROSS: - // node intersects and crosses the portal - recurse into that zone as new home zone - if (portal->getTargetZone() != this && - portal->getTargetZone() != pczsn->getHomeZone()) - { - // set the home zone of the node to the target zone of the portal - pczsn->setHomeZone(portal->getTargetZone()); - // continue checking for portal crossings in the new zone - newHomeZone = portal->getTargetZone()->updateNodeHomeZone(pczsn, true); - } - break; - } - } - - // return the new home zone - return newHomeZone; + // default to newHomeZone being the current home zone + PCZone * newHomeZone = pczsn->getHomeZone(); + + // Check all portals of the start zone for crossings! + Portal* portal; + PortalList::iterator pi, piend; + piend = mPortals.end(); + for (pi = mPortals.begin(); pi != piend; pi++) + { + portal = *pi; + + Portal::PortalIntersectResult pir = portal->intersects(pczsn); + switch (pir) + { + default: + case Portal::NO_INTERSECT: // node does not intersect portal - do nothing + case Portal::INTERSECT_NO_CROSS:// node intersects but does not cross portal - do nothing + break; + case Portal::INTERSECT_BACK_NO_CROSS:// node intersects but on the back of the portal + if (allowBackTouches) + { + // node is on wrong side of the portal - fix if we're allowing backside touches + if (portal->getTargetZone() != this && + portal->getTargetZone() != pczsn->getHomeZone()) + { + // set the home zone of the node to the target zone of the portal + pczsn->setHomeZone(portal->getTargetZone()); + // continue checking for portal crossings in the new zone + newHomeZone = portal->getTargetZone()->updateNodeHomeZone(pczsn, false); + } + } + break; + case Portal::INTERSECT_CROSS: + // node intersects and crosses the portal - recurse into that zone as new home zone + if (portal->getTargetZone() != this && + portal->getTargetZone() != pczsn->getHomeZone()) + { + // set the home zone of the node to the target zone of the portal + pczsn->setHomeZone(portal->getTargetZone()); + // continue checking for portal crossings in the new zone + newHomeZone = portal->getTargetZone()->updateNodeHomeZone(pczsn, true); + } + break; + } + } + + // return the new home zone + return newHomeZone; } @@ -548,780 +548,780 @@ namespace Ogre // Recursively walk the zones, adding all visible SceneNodes to the list of visible nodes. */ void OctreeZone::findVisibleNodes(PCZCamera *camera, - NodeList & visibleNodeList, - RenderQueue * queue, - VisibleObjectsBoundsInfo* visibleBounds, - bool onlyShadowCasters, - bool displayNodes, - bool showBoundingBoxes) + NodeList & visibleNodeList, + RenderQueue * queue, + VisibleObjectsBoundsInfo* visibleBounds, + bool onlyShadowCasters, + bool displayNodes, + bool showBoundingBoxes) { //return immediately if nothing is in the zone. - if (mHomeNodeList.empty() && - mVisitorNodeList.empty() && - mPortals.empty()) + if (mHomeNodeList.empty() && + mVisitorNodeList.empty() && + mPortals.empty()) return ; // Else, the zone is automatically assumed to be visible since either - // it is the camera the zone is in, or it was reached because - // a connecting portal was deemed visible to the camera. - - // enable sky if called to do so for this zone - if (mHasSky) - { - // enable sky - mPCZSM->enableSky(true); - } - - // Recursively find visible nodes in the zone - walkOctree(camera, - visibleNodeList, - queue, + // it is the camera the zone is in, or it was reached because + // a connecting portal was deemed visible to the camera. + + // enable sky if called to do so for this zone + if (mHasSky) + { + // enable sky + mPCZSM->enableSky(true); + } + + // Recursively find visible nodes in the zone + walkOctree(camera, + visibleNodeList, + queue, mOctree, - visibleBounds, + visibleBounds, false, - onlyShadowCasters, - displayNodes, - showBoundingBoxes); - - // Here we merge both portal and antiportal visible to the camera into one list. - // Then we sort them in the order from nearest to furthest from camera. - PortalBaseList sortedPortalList; - for (AntiPortalList::iterator iter = mAntiPortals.begin(); iter != mAntiPortals.end(); ++iter) - { - AntiPortal* portal = *iter; - if (camera->isVisible(portal)) - { - sortedPortalList.push_back(portal); - } - } - for (PortalList::iterator iter = mPortals.begin(); iter != mPortals.end(); ++iter) - { - Portal* portal = *iter; - if (camera->isVisible(portal)) - { - sortedPortalList.push_back(portal); - } - } - const Vector3& cameraOrigin(camera->getDerivedPosition()); - std::sort(sortedPortalList.begin(), sortedPortalList.end(), - PortalSortDistance(cameraOrigin)); - - // create a standalone frustum for anti portal use. - // we're doing this instead of using camera because we don't need - // to do camera frustum check again. - PCZFrustum antiPortalFrustum; - antiPortalFrustum.setOrigin(cameraOrigin); - antiPortalFrustum.setProjectionType(camera->getProjectionType()); - - // now we do culling check and remove hidden portals. - // whenever we get a portal in the main loop, we can be sure that it is not - // occluded by AntiPortal. So we do traversal right there and then. - // This is because the portal list has been sorted. - size_t sortedPortalListCount = sortedPortalList.size(); - for (size_t i = 0; i < sortedPortalListCount; ++i) - { - PortalBase* portalBase = sortedPortalList[i]; - if (!portalBase) continue; // skip removed portal. - - if (portalBase->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG) - { - Portal* portal = static_cast(portalBase); - // portal is visible. Add the portal as extra culling planes to camera - int planes_added = camera->addPortalCullingPlanes(portal); - // tell target zone it's visible this frame - portal->getTargetZone()->setLastVisibleFrame(mLastVisibleFrame); - portal->getTargetZone()->setLastVisibleFromCamera(camera); - // recurse into the connected zone - portal->getTargetZone()->findVisibleNodes(camera, - visibleNodeList, - queue, - visibleBounds, - onlyShadowCasters, - displayNodes, - showBoundingBoxes); - if (planes_added > 0) - { - // Then remove the extra culling planes added before going to the next portal in the list. - camera->removePortalCullingPlanes(portal); - } - } - else if (i < sortedPortalListCount) // skip antiportal test if it is the last item in the list. - { - // this is an anti portal. So we use it to test preceding portals in the list. - AntiPortal* antiPortal = static_cast(portalBase); - int planes_added = antiPortalFrustum.addPortalCullingPlanes(antiPortal); - - for (size_t j = i + 1; j < sortedPortalListCount; ++j) - { - PortalBase* otherPortal = sortedPortalList[j]; - // Since this is an antiportal, we are doing the inverse of the test. - // Here if the portal is fully visible in the anti portal fustrum, it means it's hidden. - if (otherPortal && antiPortalFrustum.isFullyVisible(otherPortal)) - sortedPortalList[j] = NULL; - } - - if (planes_added > 0) - { - // Then remove the extra culling planes added before going to the next portal in the list. - antiPortalFrustum.removePortalCullingPlanes(antiPortal); - } - } - } - } - - void OctreeZone::walkOctree(PCZCamera *camera, - NodeList & visibleNodeList, - RenderQueue *queue, + onlyShadowCasters, + displayNodes, + showBoundingBoxes); + + // Here we merge both portal and antiportal visible to the camera into one list. + // Then we sort them in the order from nearest to furthest from camera. + PortalBaseList sortedPortalList; + for (AntiPortalList::iterator iter = mAntiPortals.begin(); iter != mAntiPortals.end(); ++iter) + { + AntiPortal* portal = *iter; + if (camera->isVisible(portal)) + { + sortedPortalList.push_back(portal); + } + } + for (PortalList::iterator iter = mPortals.begin(); iter != mPortals.end(); ++iter) + { + Portal* portal = *iter; + if (camera->isVisible(portal)) + { + sortedPortalList.push_back(portal); + } + } + const Vector3& cameraOrigin(camera->getDerivedPosition()); + std::sort(sortedPortalList.begin(), sortedPortalList.end(), + PortalSortDistance(cameraOrigin)); + + // create a standalone frustum for anti portal use. + // we're doing this instead of using camera because we don't need + // to do camera frustum check again. + PCZFrustum antiPortalFrustum; + antiPortalFrustum.setOrigin(cameraOrigin); + antiPortalFrustum.setProjectionType(camera->getProjectionType()); + + // now we do culling check and remove hidden portals. + // whenever we get a portal in the main loop, we can be sure that it is not + // occluded by AntiPortal. So we do traversal right there and then. + // This is because the portal list has been sorted. + size_t sortedPortalListCount = sortedPortalList.size(); + for (size_t i = 0; i < sortedPortalListCount; ++i) + { + PortalBase* portalBase = sortedPortalList[i]; + if (!portalBase) continue; // skip removed portal. + + if (portalBase->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG) + { + Portal* portal = static_cast(portalBase); + // portal is visible. Add the portal as extra culling planes to camera + int planes_added = camera->addPortalCullingPlanes(portal); + // tell target zone it's visible this frame + portal->getTargetZone()->setLastVisibleFrame(mLastVisibleFrame); + portal->getTargetZone()->setLastVisibleFromCamera(camera); + // recurse into the connected zone + portal->getTargetZone()->findVisibleNodes(camera, + visibleNodeList, + queue, + visibleBounds, + onlyShadowCasters, + displayNodes, + showBoundingBoxes); + if (planes_added > 0) + { + // Then remove the extra culling planes added before going to the next portal in the list. + camera->removePortalCullingPlanes(portal); + } + } + else if (i < sortedPortalListCount) // skip antiportal test if it is the last item in the list. + { + // this is an anti portal. So we use it to test preceding portals in the list. + AntiPortal* antiPortal = static_cast(portalBase); + int planes_added = antiPortalFrustum.addPortalCullingPlanes(antiPortal); + + for (size_t j = i + 1; j < sortedPortalListCount; ++j) + { + PortalBase* otherPortal = sortedPortalList[j]; + // Since this is an antiportal, we are doing the inverse of the test. + // Here if the portal is fully visible in the anti portal fustrum, it means it's hidden. + if (otherPortal && antiPortalFrustum.isFullyVisible(otherPortal)) + sortedPortalList[j] = NULL; + } + + if (planes_added > 0) + { + // Then remove the extra culling planes added before going to the next portal in the list. + antiPortalFrustum.removePortalCullingPlanes(antiPortal); + } + } + } + } + + void OctreeZone::walkOctree(PCZCamera *camera, + NodeList & visibleNodeList, + RenderQueue *queue, Octree *octant, - VisibleObjectsBoundsInfo* visibleBounds, + VisibleObjectsBoundsInfo* visibleBounds, bool foundvisible, - bool onlyShadowCasters, - bool displayNodes, - bool showBoundingBoxes) - { - - //return immediately if nothing is in the node. - if ( octant -> numNodes() == 0 ) - return ; - - PCZCamera::Visibility v = PCZCamera::NONE; - - if ( foundvisible ) - { - v = PCZCamera::FULL; - } - - else if ( octant == mOctree ) - { - v = PCZCamera::PARTIAL; - } - - else - { - AxisAlignedBox box; - octant -> _getCullBounds( &box ); - v = camera -> getVisibility( box ); - } - - - // if the octant is visible, or if it's the root node... - if ( v != PCZCamera::NONE ) - { - //Add stuff to be rendered; - PCZSceneNodeList::iterator it = octant -> mNodes.begin(); - - bool vis = true; - - while ( it != octant -> mNodes.end() ) - { - PCZSceneNode * sn = *it; - // if the scene node is already visible, then we can skip it - if (sn->getLastVisibleFrame() != mLastVisibleFrame || - sn->getLastVisibleFromCamera() != camera) - { - // if this octree is partially visible, manually cull all - // scene nodes attached directly to this level. - if ( v == PCZCamera::PARTIAL ) - { - vis = camera -> isVisible( sn -> _getWorldAABB() ); - } - if ( vis ) - { - // add the node to the render queue - sn -> _addToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds ); - // add it to the list of visible nodes - visibleNodeList.push_back( sn ); - // if we are displaying nodes, add the node renderable to the queue - if ( displayNodes ) - { - queue -> addRenderable( sn->getDebugRenderable() ); - } - // if the scene manager or the node wants the bounding box shown, add it to the queue - if (sn->getShowBoundingBox() || showBoundingBoxes) - { - sn->_addBoundingBoxToQueue(queue); - } - // flag the node as being visible this frame - sn->setLastVisibleFrame(mLastVisibleFrame); - sn->setLastVisibleFromCamera(camera); - } - } - ++it; - } - - Octree* child; - bool childfoundvisible = (v == PCZCamera::FULL); - if ( (child = octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) - walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); - - if ( (child = octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) - walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); - - if ( (child = octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) - walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); - - if ( (child = octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) - walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); - - if ( (child = octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) - walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); - - if ( (child = octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) - walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); - - if ( (child = octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) - walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); - - if ( (child = octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) - walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); - - } - } + bool onlyShadowCasters, + bool displayNodes, + bool showBoundingBoxes) + { + + //return immediately if nothing is in the node. + if ( octant -> numNodes() == 0 ) + return ; + + PCZCamera::Visibility v = PCZCamera::NONE; + + if ( foundvisible ) + { + v = PCZCamera::FULL; + } + + else if ( octant == mOctree ) + { + v = PCZCamera::PARTIAL; + } + + else + { + AxisAlignedBox box; + octant -> _getCullBounds( &box ); + v = camera -> getVisibility( box ); + } + + + // if the octant is visible, or if it's the root node... + if ( v != PCZCamera::NONE ) + { + //Add stuff to be rendered; + PCZSceneNodeList::iterator it = octant -> mNodes.begin(); + + bool vis = true; + + while ( it != octant -> mNodes.end() ) + { + PCZSceneNode * sn = *it; + // if the scene node is already visible, then we can skip it + if (sn->getLastVisibleFrame() != mLastVisibleFrame || + sn->getLastVisibleFromCamera() != camera) + { + // if this octree is partially visible, manually cull all + // scene nodes attached directly to this level. + if ( v == PCZCamera::PARTIAL ) + { + vis = camera -> isVisible( sn -> _getWorldAABB() ); + } + if ( vis ) + { + // add the node to the render queue + sn -> _addToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds ); + // add it to the list of visible nodes + visibleNodeList.push_back( sn ); + // if we are displaying nodes, add the node renderable to the queue + if ( displayNodes ) + { + queue -> addRenderable( sn->getDebugRenderable() ); + } + // if the scene manager or the node wants the bounding box shown, add it to the queue + if (sn->getShowBoundingBox() || showBoundingBoxes) + { + sn->_addBoundingBoxToQueue(queue); + } + // flag the node as being visible this frame + sn->setLastVisibleFrame(mLastVisibleFrame); + sn->setLastVisibleFromCamera(camera); + } + } + ++it; + } + + Octree* child; + bool childfoundvisible = (v == PCZCamera::FULL); + if ( (child = octant -> mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) + walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); + + if ( (child = octant -> mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) + walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); + + if ( (child = octant -> mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) + walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); + + if ( (child = octant -> mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) + walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); + + if ( (child = octant -> mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) + walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); + + if ( (child = octant -> mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) + walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); + + if ( (child = octant -> mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) + walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); + + if ( (child = octant -> mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) + walkOctree( camera, visibleNodeList, queue, child, visibleBounds, childfoundvisible, onlyShadowCasters, displayNodes, showBoundingBoxes ); + + } + } // --- find nodes which intersect various types of BV's --- - void OctreeZone::_findNodes(const AxisAlignedBox &t, - PCZSceneNodeList &list, + void OctreeZone::_findNodes(const AxisAlignedBox &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ) + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ) { - // if this zone has an enclosure, check against the enclosure AABB first - if (mEnclosureNode) - { - if (!mEnclosureNode->_getWorldAABB().intersects(t)) - { - // AABB of zone does not intersect t, just return. - return; - } - } - - // use the Octree to more efficiently find nodes intersecting the aab - mOctree->_findNodes(t, list, exclude, includeVisitors, false); - - // if asked to, recurse through portals - if (recurseThruPortals) - { - PortalList::iterator pit = mPortals.begin(); - while ( pit != mPortals.end() ) - { - Portal * portal = *pit; - // check portal versus boundign box - if (portal->intersects(t)) - { - // make sure portal hasn't already been recursed through - PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); - if (pit2 == visitedPortals.end()) - { - // save portal to the visitedPortals list - visitedPortals.push_front(portal); - // recurse into the connected zone - portal->getTargetZone()->_findNodes(t, - list, - visitedPortals, - includeVisitors, - recurseThruPortals, - exclude); - } - } - pit++; - } - } - - } + // if this zone has an enclosure, check against the enclosure AABB first + if (mEnclosureNode) + { + if (!mEnclosureNode->_getWorldAABB().intersects(t)) + { + // AABB of zone does not intersect t, just return. + return; + } + } + + // use the Octree to more efficiently find nodes intersecting the aab + mOctree->_findNodes(t, list, exclude, includeVisitors, false); + + // if asked to, recurse through portals + if (recurseThruPortals) + { + PortalList::iterator pit = mPortals.begin(); + while ( pit != mPortals.end() ) + { + Portal * portal = *pit; + // check portal versus boundign box + if (portal->intersects(t)) + { + // make sure portal hasn't already been recursed through + PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); + if (pit2 == visitedPortals.end()) + { + // save portal to the visitedPortals list + visitedPortals.push_front(portal); + // recurse into the connected zone + portal->getTargetZone()->_findNodes(t, + list, + visitedPortals, + includeVisitors, + recurseThruPortals, + exclude); + } + } + pit++; + } + } + + } void OctreeZone::_findNodes(const Sphere &t, - PCZSceneNodeList &list, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ) + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ) { - // if this zone has an enclosure, check against the enclosure AABB first - if (mEnclosureNode) - { - if (!mEnclosureNode->_getWorldAABB().intersects(t)) - { - // AABB of zone does not intersect t, just return. - return; - } - } - - // use the Octree to more efficiently find nodes intersecting the sphere - mOctree->_findNodes(t, list, exclude, includeVisitors, false); - - // if asked to, recurse through portals - if (recurseThruPortals) - { - PortalList::iterator pit = mPortals.begin(); - while ( pit != mPortals.end() ) - { - Portal * portal = *pit; - // check portal versus boundign box - if (portal->intersects(t)) - { - // make sure portal hasn't already been recursed through - PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); - if (pit2 == visitedPortals.end()) - { - // save portal to the visitedPortals list - visitedPortals.push_front(portal); - // recurse into the connected zone - portal->getTargetZone()->_findNodes(t, - list, - visitedPortals, - includeVisitors, - recurseThruPortals, - exclude); - } - } - pit++; - } - } - - } + // if this zone has an enclosure, check against the enclosure AABB first + if (mEnclosureNode) + { + if (!mEnclosureNode->_getWorldAABB().intersects(t)) + { + // AABB of zone does not intersect t, just return. + return; + } + } + + // use the Octree to more efficiently find nodes intersecting the sphere + mOctree->_findNodes(t, list, exclude, includeVisitors, false); + + // if asked to, recurse through portals + if (recurseThruPortals) + { + PortalList::iterator pit = mPortals.begin(); + while ( pit != mPortals.end() ) + { + Portal * portal = *pit; + // check portal versus boundign box + if (portal->intersects(t)) + { + // make sure portal hasn't already been recursed through + PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); + if (pit2 == visitedPortals.end()) + { + // save portal to the visitedPortals list + visitedPortals.push_front(portal); + // recurse into the connected zone + portal->getTargetZone()->_findNodes(t, + list, + visitedPortals, + includeVisitors, + recurseThruPortals, + exclude); + } + } + pit++; + } + } + + } void OctreeZone::_findNodes(const PlaneBoundedVolume &t, - PCZSceneNodeList &list, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude) + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude) { - // if this zone has an enclosure, check against the enclosure AABB first - if (mEnclosureNode) - { - if (!t.intersects(mEnclosureNode->_getWorldAABB())) - { - // AABB of zone does not intersect t, just return. - return; - } - } - - // use the Octree to more efficiently find nodes intersecting the plane bounded volume - mOctree->_findNodes(t, list, exclude, includeVisitors, false); - - // if asked to, recurse through portals - if (recurseThruPortals) - { - PortalList::iterator pit = mPortals.begin(); - while ( pit != mPortals.end() ) - { - Portal * portal = *pit; - // check portal versus boundign box - if (portal->intersects(t)) - { - // make sure portal hasn't already been recursed through - PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); - if (pit2 == visitedPortals.end()) - { - // save portal to the visitedPortals list - visitedPortals.push_front(portal); - // recurse into the connected zone - portal->getTargetZone()->_findNodes(t, - list, - visitedPortals, - includeVisitors, - recurseThruPortals, - exclude); - } - } - pit++; - } - } - - } + // if this zone has an enclosure, check against the enclosure AABB first + if (mEnclosureNode) + { + if (!t.intersects(mEnclosureNode->_getWorldAABB())) + { + // AABB of zone does not intersect t, just return. + return; + } + } + + // use the Octree to more efficiently find nodes intersecting the plane bounded volume + mOctree->_findNodes(t, list, exclude, includeVisitors, false); + + // if asked to, recurse through portals + if (recurseThruPortals) + { + PortalList::iterator pit = mPortals.begin(); + while ( pit != mPortals.end() ) + { + Portal * portal = *pit; + // check portal versus boundign box + if (portal->intersects(t)) + { + // make sure portal hasn't already been recursed through + PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); + if (pit2 == visitedPortals.end()) + { + // save portal to the visitedPortals list + visitedPortals.push_front(portal); + // recurse into the connected zone + portal->getTargetZone()->_findNodes(t, + list, + visitedPortals, + includeVisitors, + recurseThruPortals, + exclude); + } + } + pit++; + } + } + + } void OctreeZone::_findNodes(const Ray &t, - PCZSceneNodeList &list, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ) + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ) + { + // if this zone has an enclosure, check against the enclosure AABB first + if (mEnclosureNode) + { + std::pair nsect = t.intersects(mEnclosureNode->_getWorldAABB()); + if (!nsect.first) + { + // AABB of zone does not intersect t, just return. + return; + } + } + + // use the Octree to more efficiently find nodes intersecting the ray + mOctree->_findNodes(t, list, exclude, includeVisitors, false); + + // if asked to, recurse through portals + if (recurseThruPortals) + { + PortalList::iterator pit = mPortals.begin(); + while ( pit != mPortals.end() ) + { + Portal * portal = *pit; + // check portal versus boundign box + if (portal->intersects(t)) + { + // make sure portal hasn't already been recursed through + PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); + if (pit2 == visitedPortals.end()) + { + // save portal to the visitedPortals list + visitedPortals.push_front(portal); + // recurse into the connected zone + portal->getTargetZone()->_findNodes(t, + list, + visitedPortals, + includeVisitors, + recurseThruPortals, + exclude); + } + } + pit++; + } + } + } + + /** called when the scene manager creates a camera because + some zone managers (like TerrainZone) need the camera info. + */ + void OctreeZone::notifyCameraCreated( Camera* c ) + { + } + //------------------------------------------------------------------------- + void OctreeZone::notifyWorldGeometryRenderQueue(uint8 qid) { - // if this zone has an enclosure, check against the enclosure AABB first - if (mEnclosureNode) - { - std::pair nsect = t.intersects(mEnclosureNode->_getWorldAABB()); - if (!nsect.first) - { - // AABB of zone does not intersect t, just return. - return; - } - } - - // use the Octree to more efficiently find nodes intersecting the ray - mOctree->_findNodes(t, list, exclude, includeVisitors, false); - - // if asked to, recurse through portals - if (recurseThruPortals) - { - PortalList::iterator pit = mPortals.begin(); - while ( pit != mPortals.end() ) - { - Portal * portal = *pit; - // check portal versus boundign box - if (portal->intersects(t)) - { - // make sure portal hasn't already been recursed through - PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); - if (pit2 == visitedPortals.end()) - { - // save portal to the visitedPortals list - visitedPortals.push_front(portal); - // recurse into the connected zone - portal->getTargetZone()->_findNodes(t, - list, - visitedPortals, - includeVisitors, - recurseThruPortals, - exclude); - } - } - pit++; - } - } - } - - /** called when the scene manager creates a camera because - some zone managers (like TerrainZone) need the camera info. - */ - void OctreeZone::notifyCameraCreated( Camera* c ) - { - } - //------------------------------------------------------------------------- - void OctreeZone::notifyWorldGeometryRenderQueue(uint8 qid) - { - } - //------------------------------------------------------------------------- + } + //------------------------------------------------------------------------- void OctreeZone::notifyBeginRenderScene(void) { - } - //------------------------------------------------------------------------- - void OctreeZone::setZoneGeometry(const String &filename, PCZSceneNode * parentNode) - { - String entityName, nodeName; - entityName = this->getName() + "_entity"; - nodeName = this->getName() + "_Node"; - Entity *ent = mPCZSM->createEntity(entityName , filename ); - // create a node for the entity - PCZSceneNode * node; - node = (PCZSceneNode*)(parentNode->createChildSceneNode(nodeName)); - // attach the entity to the node - node->attachObject(ent); - // set the node as the enclosure node - setEnclosureNode(node); - } - //------------------------------------------------------------------------- - void OctreeZone::getAABB(AxisAlignedBox & aabb) - { - // get the Octree bounding box - aabb = mOctree->mBox; - } - //------------------------------------------------------------------------- - void OctreeZone::init(AxisAlignedBox &box, int depth) - { - if ( mOctree != 0 ) - OGRE_DELETE mOctree; - - mOctree = OGRE_NEW Octree( this, 0 ); - - mMaxDepth = depth; - mBox = box; - - mOctree -> mBox = box; - - Vector3 min = box.getMinimum(); - - Vector3 max = box.getMaximum(); - - mOctree -> mHalfSize = ( max - min ) / 2; - } - - void OctreeZone::resize( const AxisAlignedBox &box ) - { - // delete the octree - OGRE_DELETE mOctree; - // create a new octree - mOctree = OGRE_NEW Octree( this, 0 ); - // set the octree bounding box - mOctree->mBox = box; - const Vector3 &min = box.getMinimum(); - const Vector3 &max = box.getMaximum(); - mOctree->mHalfSize = ( max - min ) * 0.5f; - - OctreeZoneData * ozd; - PCZSceneNodeList::iterator it = mHomeNodeList.begin(); - while ( it != mHomeNodeList.end() ) - { - PCZSceneNode * on = ( *it ); - ozd = (OctreeZoneData*)(on->getZoneData(this)); - ozd -> setOctant( 0 ); - updateNodeOctant( ozd ); - ++it; - } - - it = mVisitorNodeList.begin(); - while ( it != mVisitorNodeList.end() ) - { - PCZSceneNode * on = ( *it ); - ozd = (OctreeZoneData*)(on->getZoneData(this)); - ozd -> setOctant( 0 ); - updateNodeOctant( ozd ); - ++it; - } - - } - bool OctreeZone::setOption( const String & key, const void * val ) - { - if ( key == "Size" ) - { - resize( * static_cast < const AxisAlignedBox * > ( val ) ); - return true; - } - - else if ( key == "Depth" ) - { - mMaxDepth = * static_cast < const int * > ( val ); - // copy the box since resize will delete mOctree and reference won't work - AxisAlignedBox box = mOctree->mBox; - resize(box); - return true; - } - -/* else if ( key == "ShowOctree" ) - { - mShowBoxes = * static_cast < const bool * > ( val ); - return true; - }*/ - return false; - } - - void OctreeZone::updateNodeOctant( OctreeZoneData * zoneData ) - { - const AxisAlignedBox& box = zoneData -> mOctreeWorldAABB; - - if ( box.isNull() ) - return ; - - // Skip if octree has been destroyed (shutdown conditions) - if (!mOctree) - return; - - PCZSceneNode* node = zoneData->mAssociatedNode; - if ( zoneData->getOctant() == 0 ) - { - //if outside the octree, force into the root node. - if ( ! zoneData->_isIn( mOctree -> mBox ) ) - mOctree->_addNode( node ); - else - addNodeToOctree( node, mOctree ); - return ; - } - - if ( ! zoneData->_isIn( zoneData->getOctant()->mBox ) ) - { - - //if outside the octree, force into the root node. - if ( !zoneData->_isIn( mOctree -> mBox ) ) - { - // skip if it's already in the root node. - if (((OctreeZoneData*)node->getZoneData(this))->getOctant() == mOctree) - return; - - removeNodeFromOctree( node ); - mOctree->_addNode( node ); - } - else - addNodeToOctree( node, mOctree ); - } - } - - /** Only removes the node from the octree. It leaves the octree, even if it's empty. - */ - void OctreeZone::removeNodeFromOctree( PCZSceneNode * n ) - { - // Skip if octree has been destroyed (shutdown conditions) - if (!mOctree) - return; - - Octree * oct = ((OctreeZoneData*)n->getZoneData(this)) -> getOctant(); - - if ( oct ) - { - oct -> _removeNode( n ); - } - - ((OctreeZoneData*)n->getZoneData(this))->setOctant(0); - } - - - void OctreeZone::addNodeToOctree( PCZSceneNode * n, Octree *octant, int depth ) - { - - // Skip if octree has been destroyed (shutdown conditions) - if (!mOctree) - return; - - const AxisAlignedBox& bx = n -> _getWorldAABB(); - - - //if the octree is twice as big as the scene node, - //we will add it to a child. - if ( ( depth < mMaxDepth ) && octant -> _isTwiceSize( bx ) ) - { - int x, y, z; - octant -> _getChildIndexes( bx, &x, &y, &z ); - - if ( octant -> mChildren[ x ][ y ][ z ] == 0 ) - { - octant -> mChildren[ x ][ y ][ z ] = OGRE_NEW Octree( this, octant ); - const Vector3& octantMin = octant -> mBox.getMinimum(); - const Vector3& octantMax = octant -> mBox.getMaximum(); - Vector3 min, max; - - if ( x == 0 ) - { - min.x = octantMin.x; - max.x = ( octantMin.x + octantMax.x ) / 2; - } - - else - { - min.x = ( octantMin.x + octantMax.x ) / 2; - max.x = octantMax.x; - } - - if ( y == 0 ) - { - min.y = octantMin.y; - max.y = ( octantMin.y + octantMax.y ) / 2; - } - - else - { - min.y = ( octantMin.y + octantMax.y ) / 2; - max.y = octantMax.y; - } - - if ( z == 0 ) - { - min.z = octantMin.z; - max.z = ( octantMin.z + octantMax.z ) / 2; - } - - else - { - min.z = ( octantMin.z + octantMax.z ) / 2; - max.z = octantMax.z; - } - - octant -> mChildren[ x ][ y ][ z ] -> mBox.setExtents( min, max ); - octant -> mChildren[ x ][ y ][ z ] -> mHalfSize = ( max - min ) / 2; - } - - addNodeToOctree( n, octant -> mChildren[ x ][ y ][ z ], ++depth ); - - } - else - { - if (((OctreeZoneData*)n->getZoneData(this))->getOctant() == octant) - return; - - removeNodeFromOctree( n ); - octant -> _addNode( n ); - } - } - - /***********************************************************************\ - OctreeZoneData - OctreeZone-specific Data structure for Scene Nodes - ************************************************************************/ - - OctreeZoneData::OctreeZoneData(PCZSceneNode * node, PCZone * zone) - : ZoneData(node, zone) - { - mOctant = 0; - } - - OctreeZoneData::~OctreeZoneData() - { - } - - /* Update the octreezone specific data for a node */ - void OctreeZoneData::update(void) - { - mOctreeWorldAABB.setNull(); - - // need to use object iterator here. + } + //------------------------------------------------------------------------- + void OctreeZone::setZoneGeometry(const String &filename, PCZSceneNode * parentNode) + { + String entityName, nodeName; + entityName = this->getName() + "_entity"; + nodeName = this->getName() + "_Node"; + Entity *ent = mPCZSM->createEntity(entityName , filename ); + // create a node for the entity + PCZSceneNode * node; + node = (PCZSceneNode*)(parentNode->createChildSceneNode(nodeName)); + // attach the entity to the node + node->attachObject(ent); + // set the node as the enclosure node + setEnclosureNode(node); + } + //------------------------------------------------------------------------- + void OctreeZone::getAABB(AxisAlignedBox & aabb) + { + // get the Octree bounding box + aabb = mOctree->mBox; + } + //------------------------------------------------------------------------- + void OctreeZone::init(AxisAlignedBox &box, int depth) + { + if ( mOctree != 0 ) + OGRE_DELETE mOctree; + + mOctree = OGRE_NEW Octree( this, 0 ); + + mMaxDepth = depth; + mBox = box; + + mOctree -> mBox = box; + + Vector3 min = box.getMinimum(); + + Vector3 max = box.getMaximum(); + + mOctree -> mHalfSize = ( max - min ) / 2; + } + + void OctreeZone::resize( const AxisAlignedBox &box ) + { + // delete the octree + OGRE_DELETE mOctree; + // create a new octree + mOctree = OGRE_NEW Octree( this, 0 ); + // set the octree bounding box + mOctree->mBox = box; + const Vector3 &min = box.getMinimum(); + const Vector3 &max = box.getMaximum(); + mOctree->mHalfSize = ( max - min ) * 0.5f; + + OctreeZoneData * ozd; + PCZSceneNodeList::iterator it = mHomeNodeList.begin(); + while ( it != mHomeNodeList.end() ) + { + PCZSceneNode * on = ( *it ); + ozd = (OctreeZoneData*)(on->getZoneData(this)); + ozd -> setOctant( 0 ); + updateNodeOctant( ozd ); + ++it; + } + + it = mVisitorNodeList.begin(); + while ( it != mVisitorNodeList.end() ) + { + PCZSceneNode * on = ( *it ); + ozd = (OctreeZoneData*)(on->getZoneData(this)); + ozd -> setOctant( 0 ); + updateNodeOctant( ozd ); + ++it; + } + + } + bool OctreeZone::setOption( const String & key, const void * val ) + { + if ( key == "Size" ) + { + resize( * static_cast < const AxisAlignedBox * > ( val ) ); + return true; + } + + else if ( key == "Depth" ) + { + mMaxDepth = * static_cast < const int * > ( val ); + // copy the box since resize will delete mOctree and reference won't work + AxisAlignedBox box = mOctree->mBox; + resize(box); + return true; + } + +/* else if ( key == "ShowOctree" ) + { + mShowBoxes = * static_cast < const bool * > ( val ); + return true; + }*/ + return false; + } + + void OctreeZone::updateNodeOctant( OctreeZoneData * zoneData ) + { + const AxisAlignedBox& box = zoneData -> mOctreeWorldAABB; + + if ( box.isNull() ) + return ; + + // Skip if octree has been destroyed (shutdown conditions) + if (!mOctree) + return; + + PCZSceneNode* node = zoneData->mAssociatedNode; + if ( zoneData->getOctant() == 0 ) + { + //if outside the octree, force into the root node. + if ( ! zoneData->_isIn( mOctree -> mBox ) ) + mOctree->_addNode( node ); + else + addNodeToOctree( node, mOctree ); + return ; + } + + if ( ! zoneData->_isIn( zoneData->getOctant()->mBox ) ) + { + + //if outside the octree, force into the root node. + if ( !zoneData->_isIn( mOctree -> mBox ) ) + { + // skip if it's already in the root node. + if (((OctreeZoneData*)node->getZoneData(this))->getOctant() == mOctree) + return; + + removeNodeFromOctree( node ); + mOctree->_addNode( node ); + } + else + addNodeToOctree( node, mOctree ); + } + } + + /** Only removes the node from the octree. It leaves the octree, even if it's empty. + */ + void OctreeZone::removeNodeFromOctree( PCZSceneNode * n ) + { + // Skip if octree has been destroyed (shutdown conditions) + if (!mOctree) + return; + + Octree * oct = ((OctreeZoneData*)n->getZoneData(this)) -> getOctant(); + + if ( oct ) + { + oct -> _removeNode( n ); + } + + ((OctreeZoneData*)n->getZoneData(this))->setOctant(0); + } + + + void OctreeZone::addNodeToOctree( PCZSceneNode * n, Octree *octant, int depth ) + { + + // Skip if octree has been destroyed (shutdown conditions) + if (!mOctree) + return; + + const AxisAlignedBox& bx = n -> _getWorldAABB(); + + + //if the octree is twice as big as the scene node, + //we will add it to a child. + if ( ( depth < mMaxDepth ) && octant -> _isTwiceSize( bx ) ) + { + int x, y, z; + octant -> _getChildIndexes( bx, &x, &y, &z ); + + if ( octant -> mChildren[ x ][ y ][ z ] == 0 ) + { + octant -> mChildren[ x ][ y ][ z ] = OGRE_NEW Octree( this, octant ); + const Vector3& octantMin = octant -> mBox.getMinimum(); + const Vector3& octantMax = octant -> mBox.getMaximum(); + Vector3 min, max; + + if ( x == 0 ) + { + min.x = octantMin.x; + max.x = ( octantMin.x + octantMax.x ) / 2; + } + + else + { + min.x = ( octantMin.x + octantMax.x ) / 2; + max.x = octantMax.x; + } + + if ( y == 0 ) + { + min.y = octantMin.y; + max.y = ( octantMin.y + octantMax.y ) / 2; + } + + else + { + min.y = ( octantMin.y + octantMax.y ) / 2; + max.y = octantMax.y; + } + + if ( z == 0 ) + { + min.z = octantMin.z; + max.z = ( octantMin.z + octantMax.z ) / 2; + } + + else + { + min.z = ( octantMin.z + octantMax.z ) / 2; + max.z = octantMax.z; + } + + octant -> mChildren[ x ][ y ][ z ] -> mBox.setExtents( min, max ); + octant -> mChildren[ x ][ y ][ z ] -> mHalfSize = ( max - min ) / 2; + } + + addNodeToOctree( n, octant -> mChildren[ x ][ y ][ z ], ++depth ); + + } + else + { + if (((OctreeZoneData*)n->getZoneData(this))->getOctant() == octant) + return; + + removeNodeFromOctree( n ); + octant -> _addNode( n ); + } + } + + /***********************************************************************\ + OctreeZoneData - OctreeZone-specific Data structure for Scene Nodes + ************************************************************************/ + + OctreeZoneData::OctreeZoneData(PCZSceneNode * node, PCZone * zone) + : ZoneData(node, zone) + { + mOctant = 0; + } + + OctreeZoneData::~OctreeZoneData() + { + } + + /* Update the octreezone specific data for a node */ + void OctreeZoneData::update(void) + { + mOctreeWorldAABB.setNull(); + + // need to use object iterator here. SceneNode::ObjectIterator oit = mAssociatedNode->getAttachedObjectIterator(); - while( oit.hasMoreElements() ) - { - MovableObject * m = oit.getNext(); - // merge world bounds of object - mOctreeWorldAABB.merge( m->getWorldBoundingBox(true) ); - } - - - // update the Octant for the node because things might have moved. - // if it hasn't been added to the octree, add it, and if has moved - // enough to leave it's current node, we'll update it. - if ( ! mOctreeWorldAABB.isNull() ) - { - static_cast < OctreeZone * > ( mAssociatedZone ) -> updateNodeOctant( this ); - } - } - - /** Since we are loose, only check the center. - */ - bool OctreeZoneData::_isIn( AxisAlignedBox &box ) - { - // Always fail if not in the scene graph or box is null - if (!mAssociatedNode->isInSceneGraph() || box.isNull()) return false; - - // Always succeed if AABB is infinite - if (box.isInfinite()) - return true; - - Vector3 center = mAssociatedNode->_getWorldAABB().getMaximum().midPoint( mAssociatedNode->_getWorldAABB().getMinimum() ); - - Vector3 bmin = box.getMinimum(); - Vector3 bmax = box.getMaximum(); - - bool centre = ( bmax > center && bmin < center ); - if (!centre) - return false; - - // Even if covering the centre line, need to make sure this BB is not large - // enough to require being moved up into parent. When added, bboxes would - // end up in parent due to cascade but when updating need to deal with - // bbox growing too large for this child - Vector3 octreeSize = bmax - bmin; - Vector3 nodeSize = mAssociatedNode->_getWorldAABB().getMaximum() - mAssociatedNode->_getWorldAABB().getMinimum(); - return nodeSize < octreeSize; - } - - //------------------------------------------------------------------------- - // OctreeZoneFactory functions - //String octreeZoneString = String("ZoneType_Octree"); - OctreeZoneFactory::OctreeZoneFactory() : PCZoneFactory("ZoneType_Octree") - { - } - OctreeZoneFactory::~OctreeZoneFactory() - { - } - bool OctreeZoneFactory::supportsPCZoneType(const String& zoneType) - { - if (mFactoryTypeName == zoneType) - { - return true; - } - return false; - } - PCZone* OctreeZoneFactory::createPCZone(PCZSceneManager * pczsm, const String& zoneName) - { - return OGRE_NEW OctreeZone(pczsm, zoneName); - } + while( oit.hasMoreElements() ) + { + MovableObject * m = oit.getNext(); + // merge world bounds of object + mOctreeWorldAABB.merge( m->getWorldBoundingBox(true) ); + } + + + // update the Octant for the node because things might have moved. + // if it hasn't been added to the octree, add it, and if has moved + // enough to leave it's current node, we'll update it. + if ( ! mOctreeWorldAABB.isNull() ) + { + static_cast < OctreeZone * > ( mAssociatedZone ) -> updateNodeOctant( this ); + } + } + + /** Since we are loose, only check the center. + */ + bool OctreeZoneData::_isIn( AxisAlignedBox &box ) + { + // Always fail if not in the scene graph or box is null + if (!mAssociatedNode->isInSceneGraph() || box.isNull()) return false; + + // Always succeed if AABB is infinite + if (box.isInfinite()) + return true; + + Vector3 center = mAssociatedNode->_getWorldAABB().getMaximum().midPoint( mAssociatedNode->_getWorldAABB().getMinimum() ); + + Vector3 bmin = box.getMinimum(); + Vector3 bmax = box.getMaximum(); + + bool centre = ( bmax > center && bmin < center ); + if (!centre) + return false; + + // Even if covering the centre line, need to make sure this BB is not large + // enough to require being moved up into parent. When added, bboxes would + // end up in parent due to cascade but when updating need to deal with + // bbox growing too large for this child + Vector3 octreeSize = bmax - bmin; + Vector3 nodeSize = mAssociatedNode->_getWorldAABB().getMaximum() - mAssociatedNode->_getWorldAABB().getMinimum(); + return nodeSize < octreeSize; + } + + //------------------------------------------------------------------------- + // OctreeZoneFactory functions + //String octreeZoneString = String("ZoneType_Octree"); + OctreeZoneFactory::OctreeZoneFactory() : PCZoneFactory("ZoneType_Octree") + { + } + OctreeZoneFactory::~OctreeZoneFactory() + { + } + bool OctreeZoneFactory::supportsPCZoneType(const String& zoneType) + { + if (mFactoryTypeName == zoneType) + { + return true; + } + return false; + } + PCZone* OctreeZoneFactory::createPCZone(PCZSceneManager * pczsm, const String& zoneName) + { + return OGRE_NEW OctreeZone(pczsm, zoneName); + } } diff --git a/PlugIns/OctreeZone/src/OgreOctreeZoneDll.cpp b/PlugIns/OctreeZone/src/OgreOctreeZoneDll.cpp index 43925fed5ed..0181420d838 100644 --- a/PlugIns/OctreeZone/src/OgreOctreeZoneDll.cpp +++ b/PlugIns/OctreeZone/src/OgreOctreeZoneDll.cpp @@ -53,8 +53,8 @@ namespace Ogre } extern "C" void _OgreOctreeZonePluginExport dllStopPlugin( void ) { - Root::getSingleton().uninstallPlugin(OZPlugin); - OGRE_DELETE OZPlugin; + Root::getSingleton().uninstallPlugin(OZPlugin); + OGRE_DELETE OZPlugin; } } diff --git a/PlugIns/OctreeZone/src/OgreOctreeZoneOctree.cpp b/PlugIns/OctreeZone/src/OgreOctreeZoneOctree.cpp index ea9edd65329..a3b421ab746 100644 --- a/PlugIns/OctreeZone/src/OgreOctreeZoneOctree.cpp +++ b/PlugIns/OctreeZone/src/OgreOctreeZoneOctree.cpp @@ -57,8 +57,8 @@ namespace Ogre { // Null box? if (two.isNull()) return OUTSIDE; - // Infinite box? - if (two.isInfinite()) return INTERSECT; + // Infinite box? + if (two.isInfinite()) return INTERSECT; bool inside = true; const Vector3& twoMin = two.getMinimum(); @@ -127,8 +127,8 @@ namespace Ogre { // Null box? if (two.isNull()) return OUTSIDE; - // Infinite box? - if (two.isInfinite()) return INTERSECT; + // Infinite box? + if (two.isInfinite()) return INTERSECT; // Get centre of the box Vector3 centre = two.getCenter(); @@ -167,8 +167,8 @@ namespace Ogre { // Null box? if (one.isNull() || two.isNull()) return OUTSIDE; - if (one.isInfinite()) return INSIDE; - if (two.isInfinite()) return INTERSECT; + if (one.isInfinite()) return INSIDE; + if (two.isInfinite()) return INTERSECT; const Vector3& insideMin = two.getMinimum(); @@ -207,7 +207,7 @@ namespace Ogre { // Null box? if (two.isNull()) return OUTSIDE; - if (two.isInfinite()) return INTERSECT; + if (two.isInfinite()) return INTERSECT; float sradius = one.getRadius(); @@ -267,9 +267,9 @@ namespace Ogre */ bool Octree::_isTwiceSize( const AxisAlignedBox &box ) const { - // infinite boxes never fit in a child - always root node - if (box.isInfinite()) - return false; + // infinite boxes never fit in a child - always root node + if (box.isInfinite()) + return false; Vector3 halfMBoxSize = mBox.getHalfSize(); Vector3 boxSize = box.getSize(); @@ -319,7 +319,7 @@ namespace Ogre } } } - mZone = oz; + mZone = oz; mParent = parent; mNumNodes = 0; } @@ -358,7 +358,7 @@ namespace Ogre void Octree::_removeNode( PCZSceneNode * n ) { mNodes.erase(n); - ((OctreeZoneData*)n ->getZoneData(mZone))->setOctant( 0 ); + ((OctreeZoneData*)n ->getZoneData(mZone))->setOctant( 0 ); //update total counts. _unref(); @@ -382,231 +382,231 @@ namespace Ogre void Octree::_findNodes(const AxisAlignedBox &t, PCZSceneNodeList &list, PCZSceneNode *exclude, - bool includeVisitors, + bool includeVisitors, bool full ) { - if ( !full ) - { - AxisAlignedBox obox; - _getCullBounds( &obox ); + if ( !full ) + { + AxisAlignedBox obox; + _getCullBounds( &obox ); - Intersection isect = intersect( t, obox ); + Intersection isect = intersect( t, obox ); - if ( isect == OUTSIDE ) - return ; + if ( isect == OUTSIDE ) + return ; - full = ( isect == INSIDE ); - } + full = ( isect == INSIDE ); + } - PCZSceneNodeList::iterator it = mNodes.begin(); + PCZSceneNodeList::iterator it = mNodes.begin(); - while ( it != mNodes.end() ) - { - PCZSceneNode * on = ( *it ); + while ( it != mNodes.end() ) + { + PCZSceneNode * on = ( *it ); - if ( on != exclude && (on->getHomeZone() == mZone || includeVisitors )) - { - if ( full ) - { - // make sure the node isn't already on the list - list.insert( on ); - } + if ( on != exclude && (on->getHomeZone() == mZone || includeVisitors )) + { + if ( full ) + { + // make sure the node isn't already on the list + list.insert( on ); + } - else - { - Intersection nsect = intersect( t, on -> _getWorldAABB() ); + else + { + Intersection nsect = intersect( t, on -> _getWorldAABB() ); - if ( nsect != OUTSIDE ) - { - // make sure the node isn't already on the list - list.insert( on ); - } - } + if ( nsect != OUTSIDE ) + { + // make sure the node isn't already on the list + list.insert( on ); + } + } - } - ++it; - } + } + ++it; + } - Octree* child; + Octree* child; - if ( (child=mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); } void Octree::_findNodes(const Ray &t, PCZSceneNodeList &list, PCZSceneNode *exclude, - bool includeVisitors, + bool includeVisitors, bool full ) { - if ( !full ) - { - AxisAlignedBox obox; - _getCullBounds( &obox ); + if ( !full ) + { + AxisAlignedBox obox; + _getCullBounds( &obox ); - Intersection isect = intersect( t, obox ); + Intersection isect = intersect( t, obox ); - if ( isect == OUTSIDE ) - return ; + if ( isect == OUTSIDE ) + return ; - full = ( isect == INSIDE ); - } + full = ( isect == INSIDE ); + } - PCZSceneNodeList::iterator it = mNodes.begin(); + PCZSceneNodeList::iterator it = mNodes.begin(); - while ( it != mNodes.end() ) - { - PCZSceneNode * on = ( *it ); + while ( it != mNodes.end() ) + { + PCZSceneNode * on = ( *it ); - if ( on != exclude && (on->getHomeZone() == mZone || includeVisitors )) - { - if ( full ) - { - // make sure the node isn't already on the list - list.insert( on ); - } + if ( on != exclude && (on->getHomeZone() == mZone || includeVisitors )) + { + if ( full ) + { + // make sure the node isn't already on the list + list.insert( on ); + } - else - { - Intersection nsect = intersect( t, on -> _getWorldAABB() ); + else + { + Intersection nsect = intersect( t, on -> _getWorldAABB() ); - if ( nsect != OUTSIDE ) - { - // make sure the node isn't already on the list - list.insert( on ); - } - } + if ( nsect != OUTSIDE ) + { + // make sure the node isn't already on the list + list.insert( on ); + } + } - } - ++it; - } + } + ++it; + } - Octree* child; + Octree* child; - if ( (child=mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); } void Octree::_findNodes(const Sphere &t, PCZSceneNodeList &list, PCZSceneNode *exclude, - bool includeVisitors, + bool includeVisitors, bool full ) { - if ( !full ) - { - AxisAlignedBox obox; - _getCullBounds( &obox ); + if ( !full ) + { + AxisAlignedBox obox; + _getCullBounds( &obox ); - Intersection isect = intersect( t, obox ); + Intersection isect = intersect( t, obox ); - if ( isect == OUTSIDE ) - return ; + if ( isect == OUTSIDE ) + return ; - full = ( isect == INSIDE ); - } + full = ( isect == INSIDE ); + } - PCZSceneNodeList::iterator it = mNodes.begin(); + PCZSceneNodeList::iterator it = mNodes.begin(); - while ( it != mNodes.end() ) - { - PCZSceneNode * on = ( *it ); + while ( it != mNodes.end() ) + { + PCZSceneNode * on = ( *it ); - if ( on != exclude && (on->getHomeZone() == mZone || includeVisitors )) - { - if ( full ) - { - // make sure the node isn't already on the list - list.insert( on ); - } + if ( on != exclude && (on->getHomeZone() == mZone || includeVisitors )) + { + if ( full ) + { + // make sure the node isn't already on the list + list.insert( on ); + } - else - { - Intersection nsect = intersect( t, on -> _getWorldAABB() ); + else + { + Intersection nsect = intersect( t, on -> _getWorldAABB() ); - if ( nsect != OUTSIDE ) - { - // make sure the node isn't already on the list - list.insert( on ); - } - } + if ( nsect != OUTSIDE ) + { + // make sure the node isn't already on the list + list.insert( on ); + } + } - } - ++it; - } + } + ++it; + } - Octree* child; + Octree* child; - if ( (child=mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); } @@ -614,77 +614,77 @@ namespace Ogre void Octree::_findNodes(const PlaneBoundedVolume &t, PCZSceneNodeList &list, PCZSceneNode *exclude, - bool includeVisitors, + bool includeVisitors, bool full ) { - if ( !full ) - { - AxisAlignedBox obox; - _getCullBounds( &obox ); + if ( !full ) + { + AxisAlignedBox obox; + _getCullBounds( &obox ); - Intersection isect = intersect( t, obox ); + Intersection isect = intersect( t, obox ); - if ( isect == OUTSIDE ) - return ; + if ( isect == OUTSIDE ) + return ; - full = ( isect == INSIDE ); - } + full = ( isect == INSIDE ); + } - PCZSceneNodeList::iterator it = mNodes.begin(); + PCZSceneNodeList::iterator it = mNodes.begin(); - while ( it != mNodes.end() ) - { - PCZSceneNode * on = ( *it ); + while ( it != mNodes.end() ) + { + PCZSceneNode * on = ( *it ); - if ( on != exclude && (on->getHomeZone() == mZone || includeVisitors )) - { - if ( full ) - { - // make sure the node isn't already on the list - list.insert( on ); - } + if ( on != exclude && (on->getHomeZone() == mZone || includeVisitors )) + { + if ( full ) + { + // make sure the node isn't already on the list + list.insert( on ); + } - else - { - Intersection nsect = intersect( t, on -> _getWorldAABB() ); + else + { + Intersection nsect = intersect( t, on -> _getWorldAABB() ); - if ( nsect != OUTSIDE ) - { - // make sure the node isn't already on the list - list.insert( on ); - } - } + if ( nsect != OUTSIDE ) + { + // make sure the node isn't already on the list + list.insert( on ); + } + } - } - ++it; - } + } + ++it; + } - Octree* child; + Octree* child; - if ( (child=mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 0 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 0 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 1 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 1 ][ 0 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 0 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 0 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 0 ][ 1 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); - if ( (child=mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) - child->_findNodes( t, list, exclude, includeVisitors, full ); + if ( (child=mChildren[ 1 ][ 1 ][ 1 ]) != 0 ) + child->_findNodes( t, list, exclude, includeVisitors, full ); } diff --git a/PlugIns/OctreeZone/src/OgreOctreeZonePlugin.cpp b/PlugIns/OctreeZone/src/OgreOctreeZonePlugin.cpp index 8e7d2b924ac..66f81f5c6d3 100644 --- a/PlugIns/OctreeZone/src/OgreOctreeZonePlugin.cpp +++ b/PlugIns/OctreeZone/src/OgreOctreeZonePlugin.cpp @@ -30,7 +30,7 @@ OgreOctreeZonePlugin.cpp - Octree Zone Plugin class for PCZSceneManager begin : Mon Apr 16 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -40,45 +40,45 @@ Code Style Update : namespace Ogre { - const String sPluginName = "Octree Zone Factory"; - //--------------------------------------------------------------------- - OctreeZonePlugin::OctreeZonePlugin() - :mOctreeZoneFactory(0) - { + const String sPluginName = "Octree Zone Factory"; + //--------------------------------------------------------------------- + OctreeZonePlugin::OctreeZonePlugin() + :mOctreeZoneFactory(0) + { - } - //--------------------------------------------------------------------- - const String& OctreeZonePlugin::getName() const - { - return sPluginName; - } - //--------------------------------------------------------------------- - void OctreeZonePlugin::install() - { - // Create objects - mOctreeZoneFactory = OGRE_NEW OctreeZoneFactory(); - } - //--------------------------------------------------------------------- - void OctreeZonePlugin::initialise() - { - // Register - PCZoneFactoryManager & pczfm = PCZoneFactoryManager::getSingleton(); - pczfm.registerPCZoneFactory(mOctreeZoneFactory); - } - //--------------------------------------------------------------------- - void OctreeZonePlugin::shutdown() - { - // Unregister - PCZoneFactoryManager & pczfm = PCZoneFactoryManager::getSingleton(); - pczfm.unregisterPCZoneFactory(mOctreeZoneFactory); - } - //--------------------------------------------------------------------- - void OctreeZonePlugin::uninstall() - { - // destroy - OGRE_DELETE mOctreeZoneFactory; - mOctreeZoneFactory = 0; - } + } + //--------------------------------------------------------------------- + const String& OctreeZonePlugin::getName() const + { + return sPluginName; + } + //--------------------------------------------------------------------- + void OctreeZonePlugin::install() + { + // Create objects + mOctreeZoneFactory = OGRE_NEW OctreeZoneFactory(); + } + //--------------------------------------------------------------------- + void OctreeZonePlugin::initialise() + { + // Register + PCZoneFactoryManager & pczfm = PCZoneFactoryManager::getSingleton(); + pczfm.registerPCZoneFactory(mOctreeZoneFactory); + } + //--------------------------------------------------------------------- + void OctreeZonePlugin::shutdown() + { + // Unregister + PCZoneFactoryManager & pczfm = PCZoneFactoryManager::getSingleton(); + pczfm.unregisterPCZoneFactory(mOctreeZoneFactory); + } + //--------------------------------------------------------------------- + void OctreeZonePlugin::uninstall() + { + // destroy + OGRE_DELETE mOctreeZoneFactory; + mOctreeZoneFactory = 0; + } } diff --git a/PlugIns/PCZSceneManager/include/OgreAntiPortal.h b/PlugIns/PCZSceneManager/include/OgreAntiPortal.h index 7d3df652315..eddd61ff316 100644 --- a/PlugIns/PCZSceneManager/include/OgreAntiPortal.h +++ b/PlugIns/PCZSceneManager/include/OgreAntiPortal.h @@ -35,40 +35,40 @@ PortalBase.h - PortalBase is the base class for Portal and AntiPortal. namespace Ogre { - /** AntiPortal datastructure for occlusion culling. */ - class _OgrePCZPluginExport AntiPortal : public PortalBase - { - public: - AntiPortal(const String &name, const PORTAL_TYPE type = PORTAL_TYPE_QUAD); - virtual ~AntiPortal(); + /** AntiPortal datastructure for occlusion culling. */ + class _OgrePCZPluginExport AntiPortal : public PortalBase + { + public: + AntiPortal(const String &name, const PORTAL_TYPE type = PORTAL_TYPE_QUAD); + virtual ~AntiPortal(); - /** @copydoc MovableObject::getMovableType. */ - const String& getMovableType() const; + /** @copydoc MovableObject::getMovableType. */ + const String& getMovableType() const; - }; + }; - /** Factory object for creating AntiPortal instances */ - class _OgrePCZPluginExport AntiPortalFactory : public PortalBaseFactory - { - protected: - MovableObject* createInstanceImpl(const String& name, const NameValuePairList* params); - public: - AntiPortalFactory() {} - ~AntiPortalFactory() {} + /** Factory object for creating AntiPortal instances */ + class _OgrePCZPluginExport AntiPortalFactory : public PortalBaseFactory + { + protected: + MovableObject* createInstanceImpl(const String& name, const NameValuePairList* params); + public: + AntiPortalFactory() {} + ~AntiPortalFactory() {} - static String FACTORY_TYPE_NAME; - static unsigned long FACTORY_TYPE_FLAG; + static String FACTORY_TYPE_NAME; + static unsigned long FACTORY_TYPE_FLAG; - const String& getType() const - { return FACTORY_TYPE_NAME; } + const String& getType() const + { return FACTORY_TYPE_NAME; } - void destroyInstance(MovableObject* obj); + void destroyInstance(MovableObject* obj); - /** Return true here as we want to get a unique type flag. */ - bool requestTypeFlags() const - { return true; } + /** Return true here as we want to get a unique type flag. */ + bool requestTypeFlags() const + { return true; } - }; + }; } diff --git a/PlugIns/PCZSceneManager/include/OgreCapsule.h b/PlugIns/PCZSceneManager/include/OgreCapsule.h index 9e64689da72..a5e1f941433 100644 --- a/PlugIns/PCZSceneManager/include/OgreCapsule.h +++ b/PlugIns/PCZSceneManager/include/OgreCapsule.h @@ -30,7 +30,7 @@ Some algorithms based off code from the Wild Magic library by Dave Eberly begin : Mon Apr 02 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -42,27 +42,27 @@ Code Style Update : namespace Ogre { - class Capsule - { - public: - // construction - Capsule (); // uninitialized - Capsule (const Segment&, Real); + class Capsule + { + public: + // construction + Capsule (); // uninitialized + Capsule (const Segment&, Real); - // set values - void set(const Vector3& newOrigin, const Vector3& newEnd, Real newRadius); - void setOrigin(const Vector3& newOrigin); - void setEndPoint(const Vector3& newEndpoint); - void setRadius(Real newRadius); + // set values + void set(const Vector3& newOrigin, const Vector3& newEnd, Real newRadius); + void setOrigin(const Vector3& newOrigin); + void setEndPoint(const Vector3& newEndpoint); + void setRadius(Real newRadius); - // intersection tests - bool intersects(const Capsule&) const; - bool intersects(const Segment&) const; + // intersection tests + bool intersects(const Capsule&) const; + bool intersects(const Segment&) const; - // defining members - Segment mSegment; - Real mRadius; - }; + // defining members + Segment mSegment; + Real mRadius; + }; } #endif //CAPSULE3_H diff --git a/PlugIns/PCZSceneManager/include/OgreDefaultZone.h b/PlugIns/PCZSceneManager/include/OgreDefaultZone.h index aa1ccd0f899..e3174eae527 100644 --- a/PlugIns/PCZSceneManager/include/OgreDefaultZone.h +++ b/PlugIns/PCZSceneManager/include/OgreDefaultZone.h @@ -31,7 +31,7 @@ Default Implementation of PCZone begin : Tue Feb 20 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -45,15 +45,15 @@ namespace Ogre class PCZFrustum; struct VisibleObjectsBoundsInfo; - class _OgrePCZPluginExport DefaultZone : public PCZone + class _OgrePCZPluginExport DefaultZone : public PCZone { public: DefaultZone( PCZSceneManager *, const String& ); ~DefaultZone(); - /** Set the enclosure node for this Zone - */ - void setEnclosureNode(PCZSceneNode *); + /** Set the enclosure node for this Zone + */ + void setEnclosureNode(PCZSceneNode *); /** Adds an SceneNode to this Zone. @remarks @@ -66,14 +66,14 @@ namespace Ogre */ void removeNode( PCZSceneNode * ); - /** Indicates whether or not this zone requires zone-specific data for - * each scene node - */ - bool requiresZoneSpecificNodeData(void); + /** Indicates whether or not this zone requires zone-specific data for + * each scene node + */ + bool requiresZoneSpecificNodeData(void); - /** (recursive) check the given node against all portals in the zone - */ - void _checkNodeAgainstPortals(PCZSceneNode *, Portal * ); + /** (recursive) check the given node against all portals in the zone + */ + void _checkNodeAgainstPortals(PCZSceneNode *, Portal * ); /** (recursive) check the given light against all portals in the zone */ @@ -82,15 +82,15 @@ namespace Ogre PCZFrustum *, Portal *); - /* Update the zone data for each portal - */ - void updatePortalsZoneData(void); + /* Update the zone data for each portal + */ + void updatePortalsZoneData(void); - /** Mark nodes dirty base on moving portals. */ - void dirtyNodeByMovingPortals(void); + /** Mark nodes dirty base on moving portals. */ + void dirtyNodeByMovingPortals(void); - /* Update a node's home zone */ - PCZone * updateNodeHomeZone(PCZSceneNode * pczsn, bool allowBackTouces); + /* Update a node's home zone */ + PCZone * updateNodeHomeZone(PCZSceneNode * pczsn, bool allowBackTouces); /** Find and add visible objects to the render queue. @remarks @@ -98,54 +98,54 @@ namespace Ogre This is a recursive call (the main call should be to _findVisibleObjects) */ void findVisibleNodes(PCZCamera *, - NodeList & visibleNodeList, - RenderQueue * queue, - VisibleObjectsBoundsInfo* visibleBounds, - bool onlyShadowCasters, - bool displayNodes, - bool showBoundingBoxes); - - /* Functions for finding Nodes that intersect various shapes */ - void _findNodes( const AxisAlignedBox &t, - PCZSceneNodeList &list, + NodeList & visibleNodeList, + RenderQueue * queue, + VisibleObjectsBoundsInfo* visibleBounds, + bool onlyShadowCasters, + bool displayNodes, + bool showBoundingBoxes); + + /* Functions for finding Nodes that intersect various shapes */ + void _findNodes( const AxisAlignedBox &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude); - void _findNodes( const Sphere &t, - PCZSceneNodeList &list, + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude); + void _findNodes( const Sphere &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ); - void _findNodes( const PlaneBoundedVolume &t, - PCZSceneNodeList &list, + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ); + void _findNodes( const PlaneBoundedVolume &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ); - void _findNodes( const Ray &t, - PCZSceneNodeList &list, + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ); + void _findNodes( const Ray &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ); - - /** Sets the options for the Zone */ - bool setOption( const String &, const void * ); - - /** called when the scene manager creates a camera because - some zone managers (like TerrainZone) need the camera info. - */ - void notifyCameraCreated( Camera* c ); - /* called by PCZSM during setWorldGeometryRenderQueue() */ - virtual void notifyWorldGeometryRenderQueue(uint8 qid); - /* Called when a _renderScene is called in the SceneManager */ - virtual void notifyBeginRenderScene(void); - /* called by PCZSM during setZoneGeometry() */ - virtual void setZoneGeometry(const String &filename, PCZSceneNode * parentNode); - - protected: + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ); + + /** Sets the options for the Zone */ + bool setOption( const String &, const void * ); + + /** called when the scene manager creates a camera because + some zone managers (like TerrainZone) need the camera info. + */ + void notifyCameraCreated( Camera* c ); + /* called by PCZSM during setWorldGeometryRenderQueue() */ + virtual void notifyWorldGeometryRenderQueue(uint8 qid); + /* Called when a _renderScene is called in the SceneManager */ + virtual void notifyBeginRenderScene(void); + /* called by PCZSM during setZoneGeometry() */ + virtual void setZoneGeometry(const String &filename, PCZSceneNode * parentNode); + + protected: }; diff --git a/PlugIns/PCZSceneManager/include/OgrePCPlane.h b/PlugIns/PCZSceneManager/include/OgrePCPlane.h index 801d4cf1b88..5b218a8ad4c 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCPlane.h +++ b/PlugIns/PCZSceneManager/include/OgrePCPlane.h @@ -35,7 +35,7 @@ origin of a camera. begin : Mon Feb 26 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -55,14 +55,14 @@ namespace Ogre public: /** Standard constructor */ PCPlane(); - /** Alternative constructor */ - PCPlane (const Plane & plane); + /** Alternative constructor */ + PCPlane (const Plane & plane); /** Alternative constructor */ PCPlane (const Vector3& rkNormal, const Vector3& rkPoint); /** Alternative constructor */ PCPlane (const Vector3& rkPoint0, const Vector3& rkPoint1, const Vector3& rkPoint2); - /** Copy from an Ogre Plane */ - void setFromOgrePlane(Plane & ogrePlane); + /** Copy from an Ogre Plane */ + void setFromOgrePlane(Plane & ogrePlane); /** Standard destructor */ ~PCPlane(); diff --git a/PlugIns/PCZSceneManager/include/OgrePCZCamera.h b/PlugIns/PCZSceneManager/include/OgrePCZCamera.h index ef837140201..60f075167e4 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCZCamera.h +++ b/PlugIns/PCZSceneManager/include/OgrePCZCamera.h @@ -29,7 +29,7 @@ PCZCamera.h - description begin : Wed Feb 21 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -52,13 +52,13 @@ namespace Ogre class _OgrePCZPluginExport PCZCamera : public Camera { public: - /** Visibility types */ - enum Visibility - { - NONE, - PARTIAL, - FULL - }; + /** Visibility types */ + enum Visibility + { + NONE, + PARTIAL, + FULL + }; /* Standard constructor */ PCZCamera( const String& name, SceneManager* sm ); @@ -71,36 +71,36 @@ namespace Ogre */ virtual const AxisAlignedBox& getBoundingBox(void) const; - /* Overridden isVisible function for aabb */ - virtual bool isVisible( const AxisAlignedBox &bound, FrustumPlane *culledBy=0) const; + /* Overridden isVisible function for aabb */ + virtual bool isVisible( const AxisAlignedBox &bound, FrustumPlane *culledBy=0) const; - /* isVisible() function for portals */ - bool isVisible(PortalBase* portal, FrustumPlane* culledBy = 0) const; + /* isVisible() function for portals */ + bool isVisible(PortalBase* portal, FrustumPlane* culledBy = 0) const; /** Returns the visibility of the box */ bool isVisibile( const AxisAlignedBox &bound ); /** Returns the detailed visibility of the box - */ - PCZCamera::Visibility getVisibility( const AxisAlignedBox &bound ); + */ + PCZCamera::Visibility getVisibility( const AxisAlignedBox &bound ); - /// Sets the type of projection to use (orthographic or perspective). - void setProjectionType(ProjectionType pt); + /// Sets the type of projection to use (orthographic or perspective). + void setProjectionType(ProjectionType pt); /* Update function (currently used for making sure the origin stuff for the extra culling frustum is up to date */ void update(void); - /** Calculate extra culling planes from portal and camera - origin and add to list of extra culling planes */ - int addPortalCullingPlanes(PortalBase* portal); - /// Remove extra culling planes created from the given portal - void removePortalCullingPlanes(PortalBase* portal); - /// Remove all extra culling planes + /** Calculate extra culling planes from portal and camera + origin and add to list of extra culling planes */ + int addPortalCullingPlanes(PortalBase* portal); + /// Remove extra culling planes created from the given portal + void removePortalCullingPlanes(PortalBase* portal); + /// Remove all extra culling planes void removeAllExtraCullingPlanes(void); protected: - AxisAlignedBox mBox; + AxisAlignedBox mBox; PCZFrustum mExtraCullingFrustum; }; diff --git a/PlugIns/PCZSceneManager/include/OgrePCZFrustum.h b/PlugIns/PCZSceneManager/include/OgrePCZFrustum.h index 88fdef828e1..bf3ef16876e 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCZFrustum.h +++ b/PlugIns/PCZSceneManager/include/OgrePCZFrustum.h @@ -45,7 +45,7 @@ legal view frustum). begin : Mon May 29 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : --------------------------------------------------------------------------- */ @@ -70,63 +70,63 @@ namespace Ogre { public: // visibility types - enum Visibility - { - NONE, - PARTIAL, - FULL - }; - - /** Standard constructor */ - PCZFrustum(); - /** Standard destructor */ - ~PCZFrustum(); - - /* isVisible function for aabb */ - bool isVisible( const AxisAlignedBox &bound) const; - /* isVisible function for sphere */ - bool isVisible( const Sphere &bound) const; - /* isVisible() function for portals */ - bool isVisible(const PortalBase* portal) const; - /* special function that returns true only when aabb fully fits inside the frustum. */ - bool isFullyVisible(const AxisAlignedBox& bound) const; - /* special function that returns true only when sphere fully fits inside the frustum. */ - bool isFullyVisible(const Sphere& bound) const; - /* special function that returns true only when portal fully fits inside the frustum. */ - bool isFullyVisible(const PortalBase* portal) const; + enum Visibility + { + NONE, + PARTIAL, + FULL + }; + + /** Standard constructor */ + PCZFrustum(); + /** Standard destructor */ + ~PCZFrustum(); + + /* isVisible function for aabb */ + bool isVisible( const AxisAlignedBox &bound) const; + /* isVisible function for sphere */ + bool isVisible( const Sphere &bound) const; + /* isVisible() function for portals */ + bool isVisible(const PortalBase* portal) const; + /* special function that returns true only when aabb fully fits inside the frustum. */ + bool isFullyVisible(const AxisAlignedBox& bound) const; + /* special function that returns true only when sphere fully fits inside the frustum. */ + bool isFullyVisible(const Sphere& bound) const; + /* special function that returns true only when portal fully fits inside the frustum. */ + bool isFullyVisible(const PortalBase* portal) const; /* more detailed check for visibility of an AABB */ PCZFrustum::Visibility getVisibility(const AxisAlignedBox & bound); - /** Calculate culling planes from portal and Frustum + /** Calculate culling planes from portal and Frustum origin and add to list of culling planes */ - int addPortalCullingPlanes(PortalBase* portal); - /// Remove culling planes created from the given portal - void removePortalCullingPlanes(PortalBase* portal); - /// Remove all culling planes - void removeAllCullingPlanes(void); + int addPortalCullingPlanes(PortalBase* portal); + /// Remove culling planes created from the given portal + void removePortalCullingPlanes(PortalBase* portal); + /// Remove all culling planes + void removeAllCullingPlanes(void); /// Set the origin value void setOrigin(const Vector3 & newOrigin) {mOrigin = newOrigin;} /// Set the origin plane void setOriginPlane(const Vector3 &rkNormal, const Vector3 &rkPoint); /// Tell the frustum whether or not to use the originplane void setUseOriginPlane(bool yesno) {mUseOriginPlane = yesno;} - /// Get an unused PCPlane from the CullingPlane Reservoir - PCPlane * getUnusedCullingPlane(void); + /// Get an unused PCPlane from the CullingPlane Reservoir + PCPlane * getUnusedCullingPlane(void); - /// Set the projection type of this PCZFrustum. - inline void setProjectionType(ProjectionType projType) - { mProjType = projType; } - /// Get the projection type of this PCZFrustum. - inline ProjectionType getProjectionType() const - { return mProjType; } + /// Set the projection type of this PCZFrustum. + inline void setProjectionType(ProjectionType projType) + { mProjType = projType; } + /// Get the projection type of this PCZFrustum. + inline ProjectionType getProjectionType() const + { return mProjType; } protected: Vector3 mOrigin; Plane mOriginPlane; bool mUseOriginPlane; PCPlaneList mActiveCullingPlanes; - PCPlaneList mCullingPlaneReservoir; - ProjectionType mProjType; + PCPlaneList mCullingPlaneReservoir; + ProjectionType mProjType; }; diff --git a/PlugIns/PCZSceneManager/include/OgrePCZLight.h b/PlugIns/PCZSceneManager/include/OgrePCZLight.h index 826e5858b42..907e541e0bc 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCZLight.h +++ b/PlugIns/PCZSceneManager/include/OgrePCZLight.h @@ -29,7 +29,7 @@ PCZLight.h - description begin : Wed May 23 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -83,24 +83,24 @@ namespace Ogre */ bool affectsVisibleZone(void) {return mAffectsVisibleZone;} - /** Marks a light as affecting a visible zone */ - void setAffectsVisibleZone(bool affects) { mAffectsVisibleZone = affects; } + /** Marks a light as affecting a visible zone */ + void setAffectsVisibleZone(bool affects) { mAffectsVisibleZone = affects; } /** Update the list of zones the light affects */ void updateZones(PCZone * defaultZone, unsigned long frameCount); /// Manually remove a zone from the affected list - void removeZoneFromAffectedZonesList(PCZone * zone); + void removeZoneFromAffectedZonesList(PCZone * zone); - /// MovableObject notified when SceneNode changes - virtual void _notifyMoved(void); + /// MovableObject notified when SceneNode changes + virtual void _notifyMoved(void); - /// Clear update flag - void clearNeedsUpdate(void) { mNeedsUpdate = false; } + /// Clear update flag + void clearNeedsUpdate(void) { mNeedsUpdate = false; } - /// Get status of need for update. this checks all affected zones - bool getNeedsUpdate(void); + /// Get status of need for update. this checks all affected zones + bool getNeedsUpdate(void); protected: /** Flag indicating if any of the zones in the affectedZonesList is @@ -112,25 +112,25 @@ namespace Ogre */ ZoneList affectedZonesList; - /// Flag recording if light has moved, therefore affected list needs updating - bool mNeedsUpdate; - }; + /// Flag recording if light has moved, therefore affected list needs updating + bool mNeedsUpdate; + }; - /** Factory object for creating PCZLight instances */ - class _OgrePCZPluginExport PCZLightFactory : public MovableObjectFactory - { - protected: - MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params); - public: - PCZLightFactory() {} - ~PCZLightFactory() {} + /** Factory object for creating PCZLight instances */ + class _OgrePCZPluginExport PCZLightFactory : public MovableObjectFactory + { + protected: + MovableObject* createInstanceImpl( const String& name, const NameValuePairList* params); + public: + PCZLightFactory() {} + ~PCZLightFactory() {} - static String FACTORY_TYPE_NAME; + static String FACTORY_TYPE_NAME; - const String& getType(void) const; - void destroyInstance( MovableObject* obj); + const String& getType(void) const; + void destroyInstance( MovableObject* obj); - }; + }; } // Namespace diff --git a/PlugIns/PCZSceneManager/include/OgrePCZPlugin.h b/PlugIns/PCZSceneManager/include/OgrePCZPlugin.h index c96fd719adc..9266fc0eaf8 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCZPlugin.h +++ b/PlugIns/PCZSceneManager/include/OgrePCZPlugin.h @@ -30,7 +30,7 @@ OgrePCZPlugin.h - Portal Connected Zone Scene Manager Plugin class begin : Mon Feb 19 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -47,33 +47,33 @@ namespace Ogre class PortalFactory; class AntiPortalFactory; - /** Plugin instance for PCZ Manager */ - class PCZPlugin : public Plugin - { - public: - PCZPlugin(); + /** Plugin instance for PCZ Manager */ + class PCZPlugin : public Plugin + { + public: + PCZPlugin(); - /// @copydoc Plugin::getName - const String& getName() const; + /// @copydoc Plugin::getName + const String& getName() const; - /// @copydoc Plugin::install - void install(); + /// @copydoc Plugin::install + void install(); - /// @copydoc Plugin::initialise - void initialise(); + /// @copydoc Plugin::initialise + void initialise(); - /// @copydoc Plugin::shutdown - void shutdown(); + /// @copydoc Plugin::shutdown + void shutdown(); - /// @copydoc Plugin::uninstall - void uninstall(); - protected: - PCZSceneManagerFactory* mPCZSMFactory; - PCZoneFactoryManager* mPCZoneFactoryManager; - PCZLightFactory* mPCZLightFactory; - PortalFactory* mPortalFactory; - AntiPortalFactory* mAntiPortalFactory; - }; + /// @copydoc Plugin::uninstall + void uninstall(); + protected: + PCZSceneManagerFactory* mPCZSMFactory; + PCZoneFactoryManager* mPCZoneFactoryManager; + PCZLightFactory* mPCZLightFactory; + PortalFactory* mPortalFactory; + AntiPortalFactory* mAntiPortalFactory; + }; } #endif diff --git a/PlugIns/PCZSceneManager/include/OgrePCZPrerequisites.h b/PlugIns/PCZSceneManager/include/OgrePCZPrerequisites.h index 2e59ce20a28..67e991e6958 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCZPrerequisites.h +++ b/PlugIns/PCZSceneManager/include/OgrePCZPrerequisites.h @@ -30,7 +30,7 @@ OgrePCZPrerequisites.h - Portal Connected Zone Scene Manager prerequisites begin : Mon Feb 19 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ diff --git a/PlugIns/PCZSceneManager/include/OgrePCZSceneManager.h b/PlugIns/PCZSceneManager/include/OgrePCZSceneManager.h index 917a0330d95..a61fe77974d 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCZSceneManager.h +++ b/PlugIns/PCZSceneManager/include/OgrePCZSceneManager.h @@ -30,7 +30,7 @@ PCZSceneManager.h - Portal Connected Zone Scene Manager begin : Mon Feb 19 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -46,8 +46,8 @@ namespace Ogre class PCZoneFactoryManager; class PortalBase; - typedef vector::type NodeList; - typedef list::type BoxList; + typedef vector::type NodeList; + typedef list::type BoxList; /** Specialized SceneManager that uses Portal-Connected-Zones to divide the scene spatially. */ @@ -66,54 +66,54 @@ namespace Ogre /** Standard destructor */ ~PCZSceneManager(); - /// @copydoc SceneManager::getTypeName - const String& getTypeName(void) const; + /// @copydoc SceneManager::getTypeName + const String& getTypeName(void) const; /** Initializes the manager */ void init(const String &defaultZoneTypeName, - const String &filename = "none"); + const String &filename = "none"); - /** Create a new portal instance - */ - Portal* createPortal(const String& name, PortalBase::PORTAL_TYPE type = PortalBase::PORTAL_TYPE_QUAD); + /** Create a new portal instance + */ + Portal* createPortal(const String& name, PortalBase::PORTAL_TYPE type = PortalBase::PORTAL_TYPE_QUAD); - /** Delete a portal instance by pointer - */ - void destroyPortal(Portal * p); + /** Delete a portal instance by pointer + */ + void destroyPortal(Portal * p); - /** Delete a portal instance by name - */ - void destroyPortal(const String & portalName); + /** Delete a portal instance by name + */ + void destroyPortal(const String & portalName); - /** Create a new anti portal instance */ - AntiPortal* createAntiPortal(const String& name, PortalBase::PORTAL_TYPE type = PortalBase::PORTAL_TYPE_QUAD); + /** Create a new anti portal instance */ + AntiPortal* createAntiPortal(const String& name, PortalBase::PORTAL_TYPE type = PortalBase::PORTAL_TYPE_QUAD); - /** Delete a anti portal instance by pointer */ - void destroyAntiPortal(AntiPortal * p); + /** Delete a anti portal instance by pointer */ + void destroyAntiPortal(AntiPortal * p); - /** Delete a anti portal instance by name */ - void destroyAntiPortal(const String& portalName); + /** Delete a anti portal instance by name */ + void destroyAntiPortal(const String& portalName); - /** Create a zone from a file (type of file - * depends on the zone type - */ - PCZone * createZoneFromFile(const String &zoneTypeName, - const String &zoneName, - PCZSceneNode * parentNode, - const String & filename); + /** Create a zone from a file (type of file + * depends on the zone type + */ + PCZone * createZoneFromFile(const String &zoneTypeName, + const String &zoneName, + PCZSceneNode * parentNode, + const String & filename); - /** Set the "main" geometry of the zone */ - virtual void setZoneGeometry(const String & zoneName, - PCZSceneNode * parentNode, - const String &filename); + /** Set the "main" geometry of the zone */ + virtual void setZoneGeometry(const String & zoneName, + PCZSceneNode * parentNode, + const String &filename); /// override this to ensure specialised PCZSceneNode is used. virtual SceneNode* createSceneNodeImpl(void); /// override this to ensure their specialised PCZSceneNode is used. virtual SceneNode* createSceneNodeImpl(const String& name); /** Creates a PCZSceneNode */ - virtual SceneNode * createSceneNode ( void ); + virtual SceneNode * createSceneNode ( void ); /** Creates a PCZSceneNode */ virtual SceneNode * createSceneNode ( const String &name ); /** Creates a specialized PCZCamera */ @@ -125,28 +125,28 @@ namespace Ogre /** Deletes a scene node & corresponding PCZSceneNode */ virtual void destroySceneNode(SceneNode* sn); - /** Overridden to clean up zones - */ - virtual void clearScene(void); + /** Overridden to clean up zones + */ + virtual void clearScene(void); - /** Overridden from SceneManager */ - void setWorldGeometryRenderQueue(uint8 qid); + /** Overridden from SceneManager */ + void setWorldGeometryRenderQueue(uint8 qid); - /// Overridden from basic scene manager - void _renderScene(Camera *cam, Viewport *vp, bool includeOverlays); + /// Overridden from basic scene manager + void _renderScene(Camera *cam, Viewport *vp, bool includeOverlays); - /** Enable/disable sky rendering */ - void enableSky(bool); + /** Enable/disable sky rendering */ + void enableSky(bool); - /** Set the zone which contains the sky node */ - void setSkyZone(PCZone * zone); + /** Set the zone which contains the sky node */ + void setSkyZone(PCZone * zone); /** Update Scene Graph (does several things now) */ virtual void _updateSceneGraph( Camera * cam ); /** Recurses through the PCZTree determining which nodes are visible. */ virtual void _findVisibleObjects ( Camera * cam, - VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters ); + VisibleObjectsBoundsInfo* visibleBounds, bool onlyShadowCasters ); /** Alerts each unculled object, notifying it that it will be drawn. * Useful for doing calculations only on nodes that will be drawn, prior @@ -167,15 +167,15 @@ namespace Ogre virtual Light* createLight(const String& name); /** Returns a pointer to the named Light which has previously been added to the scene. - @note Throws an exception if the named instance does not exist + @note Throws an exception if the named instance does not exist */ virtual Light* getLight(const String& name) const; - /** Returns whether a light with the given name exists. - */ - virtual bool hasLight(const String& name) const; + /** Returns whether a light with the given name exists. + */ + virtual bool hasLight(const String& name) const; - /** Removes the named light from the scene and destroys it. + /** Removes the named light from the scene and destroys it. @remarks Any pointers held to this light after calling this method will be invalid. */ @@ -185,27 +185,27 @@ namespace Ogre */ virtual void destroyAllLights(void); - /** Check/Update the zone data for every portal in the scene. - * Essentially, this routine checks each portal for intersections - * with other portals and updates if a crossing occurs - */ - void _updatePortalZoneData(void); + /** Check/Update the zone data for every portal in the scene. + * Essentially, this routine checks each portal for intersections + * with other portals and updates if a crossing occurs + */ + void _updatePortalZoneData(void); - /** Mark nodes dirty for every zone with moving portal in the scene */ - void _dirtyNodeByMovingPortals(void); + /** Mark nodes dirty for every zone with moving portal in the scene */ + void _dirtyNodeByMovingPortals(void); - /** Update the PCZSceneNodes - */ - void _updatePCZSceneNodes(void); + /** Update the PCZSceneNodes + */ + void _updatePCZSceneNodes(void); /** Calculate which zones are affected by each light */ void _calcZonesAffectedByLights(Camera * cam); - /* Attempt to automatically connect unconnected portals to proper target zones - * by looking for matching portals in other zones which are at the same location - */ - void connectPortalsToTargetZonesByLocation(void); + /* Attempt to automatically connect unconnected portals to proper target zones + * by looking for matching portals in other zones which are at the same location + */ + void connectPortalsToTargetZonesByLocation(void); /** Checks the given SceneNode, and determines if it needs to be moved * to a different PCZone or be added to the visitors list of other PCZone(s). @@ -215,75 +215,75 @@ namespace Ogre /** Removes the given PCZSceneNode */ void removeSceneNode( SceneNode * ); - /** add a PCZSceneNode to the scene by putting it in a zone - * NOTE: This zone will be the scene node's home zone - */ - void addPCZSceneNode(PCZSceneNode * sn, PCZone * zone); + /** add a PCZSceneNode to the scene by putting it in a zone + * NOTE: This zone will be the scene node's home zone + */ + void addPCZSceneNode(PCZSceneNode * sn, PCZone * zone); - /** Create a zone with the given name */ - PCZone * createZone(const String& zoneType, const String& instanceName); + /** Create a zone with the given name */ + PCZone * createZone(const String& zoneType, const String& instanceName); - /** Destroy an existing zone within the scene */ - void destroyZone(PCZone* zone, bool destroySceneNodes); + /** Destroy an existing zone within the scene */ + void destroyZone(PCZone* zone, bool destroySceneNodes); /** Make sure the home zone for the PCZSceneNode is up-to-date */ void _updateHomeZone( PCZSceneNode *, bool ); - /// Find the smallest zone which contains the point - PCZone * findZoneForPoint(Vector3 & point); + /// Find the smallest zone which contains the point + PCZone * findZoneForPoint(Vector3 & point); - /// Create any zone-specific data necessary for all zones for the given node - void createZoneSpecificNodeData(PCZSceneNode *); + /// Create any zone-specific data necessary for all zones for the given node + void createZoneSpecificNodeData(PCZSceneNode *); - /// Create any zone-specific data necessary for all nodes for the given zone - void createZoneSpecificNodeData(PCZone *); + /// Create any zone-specific data necessary for all nodes for the given zone + void createZoneSpecificNodeData(PCZone *); - /// Set the home zone for a scene node - void setNodeHomeZone(SceneNode *, PCZone *); + /// Set the home zone for a scene node + void setNodeHomeZone(SceneNode *, PCZone *); /** Recurses the scene, adding any nodes intersecting with the box into the given list. It ignores the exclude scene node. */ void findNodesIn( const AxisAlignedBox &box, - PCZSceneNodeList &list, - PCZone * startZone, - PCZSceneNode *exclude = 0 ); + PCZSceneNodeList &list, + PCZone * startZone, + PCZSceneNode *exclude = 0 ); /** Recurses the scene, adding any nodes intersecting with the sphere into the given list. It will start in the start SceneNode if given, otherwise, it will start at the root node. */ void findNodesIn( const Sphere &sphere, - PCZSceneNodeList &list, - PCZone * startZone, - PCZSceneNode *start = 0 ); + PCZSceneNodeList &list, + PCZone * startZone, + PCZSceneNode *start = 0 ); /** Recurses the PCZTree, adding any nodes intersecting with the volume into the given list. It will start in the start SceneNode if given, otherwise, it will start at the root node. */ void findNodesIn( const PlaneBoundedVolume &volume, - PCZSceneNodeList &list, - PCZone * startZone, - PCZSceneNode *start=0 ); + PCZSceneNodeList &list, + PCZone * startZone, + PCZSceneNode *start=0 ); /** Recurses the scene, starting in the given startZone, adding any nodes intersecting with - the ray into the given list. + the ray into the given list. It will start in the start SceneNode if given, otherwise, it will start at the root node. */ void findNodesIn( const Ray &ray, - PCZSceneNodeList &list, - PCZone * startZone, - PCZSceneNode *start=0 ); - - /** Get the default zone */ - PCZone * getDefaultZone(void) - { - return mDefaultZone; - } - - /** Get a zone by name */ - PCZone * getZoneByName(const String & zoneName); - + PCZSceneNodeList &list, + PCZone * startZone, + PCZSceneNode *start=0 ); + + /** Get the default zone */ + PCZone * getDefaultZone(void) + { + return mDefaultZone; + } + + /** Get a zone by name */ + PCZone * getZoneByName(const String & zoneName); + /** Sets the portal visibility flag */ void setShowPortals( bool b ) { @@ -312,41 +312,41 @@ namespace Ogre PlaneBoundedVolumeListSceneQuery* createPlaneBoundedVolumeQuery(const PlaneBoundedVolumeList& volumes, uint32 mask = 0xFFFFFFFF); RaySceneQuery* createRayQuery(const Ray& ray, uint32 mask = 0xFFFFFFFF); IntersectionSceneQuery* createIntersectionQuery(uint32 mask = 0xFFFFFFFF); - - /// ZoneMap iterator for read-only access to the zonemap - typedef MapIterator ZoneIterator; - ZoneIterator getZoneIterator(void) {return ZoneIterator(mZones.begin(), mZones.end());} + + /// ZoneMap iterator for read-only access to the zonemap + typedef MapIterator ZoneIterator; + ZoneIterator getZoneIterator(void) {return ZoneIterator(mZones.begin(), mZones.end());} - /// Clear portal update flag from all zones - void _clearAllZonesPortalUpdateFlag(void); + /// Clear portal update flag from all zones + void _clearAllZonesPortalUpdateFlag(void); - /// @see SceneManager::prepareShadowTextures. - virtual void prepareShadowTextures(Camera* cam, Viewport* vp, const LightList* lightList = 0); + /// @see SceneManager::prepareShadowTextures. + virtual void prepareShadowTextures(Camera* cam, Viewport* vp, const LightList* lightList = 0); - protected: - /// Type of default zone to be used - String mDefaultZoneTypeName; + protected: + /// Type of default zone to be used + String mDefaultZoneTypeName; - /// Name of data file for default zone - String mDefaultZoneFileName; + /// Name of data file for default zone + String mDefaultZoneFileName; - /// List of visible nodes since last _findVisibleObjects() - NodeList mVisible; + /// List of visible nodes since last _findVisibleObjects() + NodeList mVisible; - /// Camera of last _findVisibleObjects() - Camera* mLastActiveCamera; + /// Camera of last _findVisibleObjects() + Camera* mLastActiveCamera; /// The root PCZone; PCZone *mDefaultZone; - /// The list of all PCZones - ZoneMap mZones; + /// The list of all PCZones + ZoneMap mZones; - /// Master list of Portals in the world (includes all portals) - PortalList mPortals; + /// Master list of Portals in the world (includes all portals) + PortalList mPortals; - /// Master list of AntiPortals in the world. - AntiPortalList mAntiPortals; + /// Master list of AntiPortals in the world. + AntiPortalList mAntiPortals; /// Portals visibility flag bool mShowPortals; @@ -354,39 +354,39 @@ namespace Ogre /// Frame counter used in visibility determination unsigned long mFrameCount; - /// ZoneFactoryManager instance - PCZoneFactoryManager * mZoneFactoryManager; - - /// The zone of the active camera (for shadow texture casting use); - PCZone* mActiveCameraZone; - - /** Internal method for locating a list of lights which could be affecting the frustum. - @remarks - Custom scene managers are encouraged to override this method to make use of their - scene partitioning scheme to more efficiently locate lights, and to eliminate lights - which may be occluded by word geometry. - */ - virtual void findLightsAffectingFrustum(const Camera* camera); - /// Internal method for creating shadow textures (texture-based shadows) - virtual void ensureShadowTexturesCreated(); - /// Internal method for destroying shadow textures (texture-based shadows) - virtual void destroyShadowTextures(void); - /// Internal method for firing the pre caster texture shadows event - virtual void fireShadowTexturesPreCaster(Light* light, Camera* camera, size_t iteration); + /// ZoneFactoryManager instance + PCZoneFactoryManager * mZoneFactoryManager; + + /// The zone of the active camera (for shadow texture casting use); + PCZone* mActiveCameraZone; + + /** Internal method for locating a list of lights which could be affecting the frustum. + @remarks + Custom scene managers are encouraged to override this method to make use of their + scene partitioning scheme to more efficiently locate lights, and to eliminate lights + which may be occluded by word geometry. + */ + virtual void findLightsAffectingFrustum(const Camera* camera); + /// Internal method for creating shadow textures (texture-based shadows) + virtual void ensureShadowTexturesCreated(); + /// Internal method for destroying shadow textures (texture-based shadows) + virtual void destroyShadowTextures(void); + /// Internal method for firing the pre caster texture shadows event + virtual void fireShadowTexturesPreCaster(Light* light, Camera* camera, size_t iteration); }; /// Factory for PCZSceneManager class PCZSceneManagerFactory : public SceneManagerFactory { protected: - void initMetaData(void) const; + void initMetaData(void) const; public: - PCZSceneManagerFactory() {} - ~PCZSceneManagerFactory() {} - /// Factory type name - static const String FACTORY_TYPE_NAME; - SceneManager* createInstance(const String& instanceName); - void destroyInstance(SceneManager* instance); + PCZSceneManagerFactory() {} + ~PCZSceneManagerFactory() {} + /// Factory type name + static const String FACTORY_TYPE_NAME; + SceneManager* createInstance(const String& instanceName); + void destroyInstance(SceneManager* instance); }; diff --git a/PlugIns/PCZSceneManager/include/OgrePCZSceneNode.h b/PlugIns/PCZSceneManager/include/OgrePCZSceneNode.h index 8048650c7d9..9df59ac251c 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCZSceneNode.h +++ b/PlugIns/PCZSceneManager/include/OgrePCZSceneNode.h @@ -36,7 +36,7 @@ a given scenenode's PCZSceneNode by the scene manager. begin : Sat Mar 24 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -49,24 +49,24 @@ Code Style Update : namespace Ogre { - // forward declarations - class PCZone; - class ZoneData; - class PCZCamera; + // forward declarations + class PCZone; + class ZoneData; + class PCZCamera; typedef map::type ZoneMap; - typedef map::type ZoneDataMap; + typedef map::type ZoneDataMap; - class _OgrePCZPluginExport PCZSceneNode : public SceneNode - { - public: - /** Standard constructor */ - PCZSceneNode( SceneManager* creator ); - /** Standard constructor */ - PCZSceneNode( SceneManager* creator, const String& name ); - /** Standard destructor */ - ~PCZSceneNode(); - void _update(bool updateChildren, bool parentHasChanged); - void updateFromParentImpl() const; + class _OgrePCZPluginExport PCZSceneNode : public SceneNode + { + public: + /** Standard constructor */ + PCZSceneNode( SceneManager* creator ); + /** Standard constructor */ + PCZSceneNode( SceneManager* creator, const String& name ); + /** Standard destructor */ + ~PCZSceneNode(); + void _update(bool updateChildren, bool parentHasChanged); + void updateFromParentImpl() const; /** Creates an unnamed new SceneNode as a child of this node. @param @@ -90,47 +90,47 @@ namespace Ogre virtual SceneNode* createChildSceneNode(const String& name, const Vector3& translate = Vector3::ZERO, const Quaternion& rotate = Quaternion::IDENTITY); - PCZone* getHomeZone(void); - void setHomeZone(PCZone * zone); - void anchorToHomeZone(PCZone * zone); - bool isAnchored(void) {return mAnchored;} - void allowToVisit(bool yesno) {mAllowedToVisit = yesno;} - bool allowedToVisit(void) {return mAllowedToVisit;} - void addZoneToVisitingZonesMap(PCZone * zone); - void clearVisitingZonesMap(void); - void clearNodeFromVisitedZones( void ); - void removeReferencesToZone(PCZone * zone); - bool isVisitingZone(PCZone * zone); - void _addToRenderQueue( Camera* cam, + PCZone* getHomeZone(void); + void setHomeZone(PCZone * zone); + void anchorToHomeZone(PCZone * zone); + bool isAnchored(void) {return mAnchored;} + void allowToVisit(bool yesno) {mAllowedToVisit = yesno;} + bool allowedToVisit(void) {return mAllowedToVisit;} + void addZoneToVisitingZonesMap(PCZone * zone); + void clearVisitingZonesMap(void); + void clearNodeFromVisitedZones( void ); + void removeReferencesToZone(PCZone * zone); + bool isVisitingZone(PCZone * zone); + void _addToRenderQueue( Camera* cam, RenderQueue *queue, bool onlyShadowCasters, VisibleObjectsBoundsInfo* visibleBounds ); - void savePrevPosition(void); - Vector3& getPrevPosition(void) {return mPrevPosition;} - unsigned long getLastVisibleFrame(void) {return mLastVisibleFrame;} - void setLastVisibleFrame(unsigned long newLVF) {mLastVisibleFrame = newLVF;} - void setLastVisibleFromCamera(PCZCamera * camera) {mLastVisibleFromCamera = camera;} - PCZCamera* getLastVisibleFromCamera() {return mLastVisibleFromCamera;} - void setZoneData(PCZone * zone, ZoneData * zoneData); - ZoneData* getZoneData(PCZone * zone); - void updateZoneData(void); - void enable(bool yesno) {mEnabled = yesno;} - bool isEnabled(void) {return mEnabled;} - bool isMoved(void) {return mMoved;} - void setMoved(bool value) {mMoved = value;} - protected: - mutable Vector3 mNewPosition; - PCZone * mHomeZone; - bool mAnchored; - bool mAllowedToVisit; - ZoneMap mVisitingZones; - mutable Vector3 mPrevPosition; - unsigned long mLastVisibleFrame; - PCZCamera* mLastVisibleFromCamera; - ZoneDataMap mZoneData; - bool mEnabled; - mutable bool mMoved; - }; + void savePrevPosition(void); + Vector3& getPrevPosition(void) {return mPrevPosition;} + unsigned long getLastVisibleFrame(void) {return mLastVisibleFrame;} + void setLastVisibleFrame(unsigned long newLVF) {mLastVisibleFrame = newLVF;} + void setLastVisibleFromCamera(PCZCamera * camera) {mLastVisibleFromCamera = camera;} + PCZCamera* getLastVisibleFromCamera() {return mLastVisibleFromCamera;} + void setZoneData(PCZone * zone, ZoneData * zoneData); + ZoneData* getZoneData(PCZone * zone); + void updateZoneData(void); + void enable(bool yesno) {mEnabled = yesno;} + bool isEnabled(void) {return mEnabled;} + bool isMoved(void) {return mMoved;} + void setMoved(bool value) {mMoved = value;} + protected: + mutable Vector3 mNewPosition; + PCZone * mHomeZone; + bool mAnchored; + bool mAllowedToVisit; + ZoneMap mVisitingZones; + mutable Vector3 mPrevPosition; + unsigned long mLastVisibleFrame; + PCZCamera* mLastVisibleFromCamera; + ZoneDataMap mZoneData; + bool mEnabled; + mutable bool mMoved; + }; } #endif // PCZ_SCENE_NODE_H diff --git a/PlugIns/PCZSceneManager/include/OgrePCZSceneQuery.h b/PlugIns/PCZSceneManager/include/OgrePCZSceneQuery.h index 33feb86c850..04351a09491 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCZSceneQuery.h +++ b/PlugIns/PCZSceneManager/include/OgrePCZSceneQuery.h @@ -29,7 +29,7 @@ OgrePCZSceneQuery.h - description begin : Wed Feb 21, 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -63,14 +63,14 @@ namespace Ogre /** See RaySceneQuery. */ void execute(SceneQueryListener* listener); - /** set the zone to start the scene query */ + /** set the zone to start the scene query */ void setStartZone(PCZone * startZone) {mStartZone = startZone;} /** set node to exclude from query */ void setExcludeNode(SceneNode * excludeNode) {mExcludeNode = excludeNode;} - protected: - PCZone * mStartZone; + protected: + PCZone * mStartZone; SceneNode * mExcludeNode; - }; + }; /** PCZ implementation of RaySceneQuery. */ class _OgrePCZPluginExport PCZRaySceneQuery : public DefaultRaySceneQuery { @@ -81,12 +81,12 @@ namespace Ogre /** See RayScenQuery. */ void execute(RaySceneQueryListener* listener); - /** set the zone to start the scene query */ + /** set the zone to start the scene query */ void setStartZone(PCZone * startZone) {mStartZone = startZone;} /** set node to exclude from query */ void setExcludeNode(SceneNode * excludeNode) {mExcludeNode = excludeNode;} - protected: - PCZone * mStartZone; + protected: + PCZone * mStartZone; SceneNode * mExcludeNode; }; /** PCZ implementation of SphereSceneQuery. */ @@ -99,12 +99,12 @@ namespace Ogre /** See SceneQuery. */ void execute(SceneQueryListener* listener); - /** set the zone to start the scene query */ + /** set the zone to start the scene query */ void setStartZone(PCZone * startZone) {mStartZone = startZone;} /** set node to exclude from query */ void setExcludeNode(SceneNode * excludeNode) {mExcludeNode = excludeNode;} - protected: - PCZone * mStartZone; + protected: + PCZone * mStartZone; SceneNode * mExcludeNode; }; /** PCZ implementation of PlaneBoundedVolumeListSceneQuery. */ @@ -117,14 +117,14 @@ namespace Ogre /** See SceneQuery. */ void execute(SceneQueryListener* listener); - /** set the zone to start the scene query */ + /** set the zone to start the scene query */ void setStartZone(PCZone * startZone) {mStartZone = startZone;} /** set node to exclude from query */ void setExcludeNode(SceneNode * excludeNode) {mExcludeNode = excludeNode;} - protected: - PCZone * mStartZone; + protected: + PCZone * mStartZone; SceneNode * mExcludeNode; - }; + }; } diff --git a/PlugIns/PCZSceneManager/include/OgrePCZone.h b/PlugIns/PCZSceneManager/include/OgrePCZone.h index 21ac5dc8245..224f31d3f98 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCZone.h +++ b/PlugIns/PCZSceneManager/include/OgrePCZone.h @@ -44,7 +44,7 @@ a pointer to their home zone and a list of references to zones they are begin : Tue Feb 20 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -58,8 +58,8 @@ namespace Ogre { class Portal; class AntiPortal; - class PCZSceneNode; - class PCZSceneManager; + class PCZSceneNode; + class PCZSceneManager; class PCZLight; class PCZone; class PCZCamera; @@ -67,64 +67,64 @@ namespace Ogre struct VisibleObjectsBoundsInfo; typedef map::type ZoneMap; - typedef list::type PCZoneList; - typedef list::type PortalList; - typedef list::type AntiPortalList; - typedef vector::type PortalBaseList; - typedef vector::type NodeList; - typedef set< PCZSceneNode * >::type PCZSceneNodeList; + typedef list::type PCZoneList; + typedef list::type PortalList; + typedef list::type AntiPortalList; + typedef vector::type PortalBaseList; + typedef vector::type NodeList; + typedef set< PCZSceneNode * >::type PCZSceneNodeList; typedef map::type SceneNodeList; /** Portal-Connected Zone datastructure for managing scene nodes. */ - class _OgrePCZPluginExport PCZone : public SceneCtlAllocatedObject + class _OgrePCZPluginExport PCZone : public SceneCtlAllocatedObject { public: - enum NODE_LIST_TYPE - { - HOME_NODE_LIST = 1, - VISITOR_NODE_LIST = 2 - }; + enum NODE_LIST_TYPE + { + HOME_NODE_LIST = 1, + VISITOR_NODE_LIST = 2 + }; PCZone( PCZSceneManager *, const String& ); virtual ~PCZone(); - /// @return The zone type name (ex: "ZoneType_Terrain") - const String& getZoneTypeName() const { return mZoneTypeName; } + /// @return The zone type name (ex: "ZoneType_Terrain") + const String& getZoneTypeName() const { return mZoneTypeName; } - /// @return the name of the zone - const String& getName(void) const { return mName; } + /// @return the name of the zone + const String& getName(void) const { return mName; } - /** Get a pointer to the enclosure node for this PCZone - */ - SceneNode * getEnclosureNode(void) {return mEnclosureNode;} + /** Get a pointer to the enclosure node for this PCZone + */ + SceneNode * getEnclosureNode(void) {return mEnclosureNode;} - /** If sky should be drawn with this zone - */ - void setHasSky(bool yesno) {mHasSky = yesno;} + /** If sky should be drawn with this zone + */ + void setHasSky(bool yesno) {mHasSky = yesno;} - /** @return Whether or not this zone has sky - */ - bool hasSky(void) {return mHasSky;} + /** @return Whether or not this zone has sky + */ + bool hasSky(void) {return mHasSky;} - /** Set the lastVisibleFrame counter */ - void setLastVisibleFrame(unsigned long frameCount) {mLastVisibleFrame = frameCount;} + /** Set the lastVisibleFrame counter */ + void setLastVisibleFrame(unsigned long frameCount) {mLastVisibleFrame = frameCount;} /** Get the lastVisibleFrame counter value */ unsigned long getLastVisibleFrame(void) {return mLastVisibleFrame;} - /** Set the lastVisibleFromCamera pointer */ - void setLastVisibleFromCamera(PCZCamera * camera) {mLastVisibleFromCamera = camera;} + /** Set the lastVisibleFromCamera pointer */ + void setLastVisibleFromCamera(PCZCamera * camera) {mLastVisibleFromCamera = camera;} - /** Get the lastVisibleFromCamera pointer */ - PCZCamera* getLastVisibleFromCamera() {return mLastVisibleFromCamera;} + /** Get the lastVisibleFromCamera pointer */ + PCZCamera* getLastVisibleFromCamera() {return mLastVisibleFromCamera;} - public: - /** Set the enclosure node for this PCZone - */ - virtual void setEnclosureNode(PCZSceneNode *) = 0; + public: + /** Set the enclosure node for this PCZone + */ + virtual void setEnclosureNode(PCZSceneNode *) = 0; /** Adds an SceneNode to this PCZone. @remarks @@ -137,38 +137,38 @@ namespace Ogre */ virtual void removeNode( PCZSceneNode * ) = 0; - /** Remove all nodes from the node reference list and clear it - */ - virtual void _clearNodeLists(short nodeListTypes); + /** Remove all nodes from the node reference list and clear it + */ + virtual void _clearNodeLists(short nodeListTypes); - /** Indicates whether or not this zone requires zone-specific data for - * each scene node - */ - virtual bool requiresZoneSpecificNodeData(void) = 0; + /** Indicates whether or not this zone requires zone-specific data for + * each scene node + */ + virtual bool requiresZoneSpecificNodeData(void) = 0; - /** Create zone specific data for a node - */ - virtual void createNodeZoneData(PCZSceneNode *); + /** Create zone specific data for a node + */ + virtual void createNodeZoneData(PCZSceneNode *); - /** Find a matching portal (for connecting portals) - */ - virtual Portal * findMatchingPortal(Portal *); + /** Find a matching portal (for connecting portals) + */ + virtual Portal * findMatchingPortal(Portal *); - /** Add a portal to the zone */ - virtual void _addPortal(Portal* newPortal); + /** Add a portal to the zone */ + virtual void _addPortal(Portal* newPortal); - /** Remove a portal from the zone */ - virtual void _removePortal(Portal* removePortal); + /** Remove a portal from the zone */ + virtual void _removePortal(Portal* removePortal); - /** Add an anti portal to the zone */ - virtual void _addAntiPortal(AntiPortal* newAntiPortal); + /** Add an anti portal to the zone */ + virtual void _addAntiPortal(AntiPortal* newAntiPortal); - /** Remove an anti portal from the zone */ - virtual void _removeAntiPortal(AntiPortal* removeAntiPortal); + /** Remove an anti portal from the zone */ + virtual void _removeAntiPortal(AntiPortal* removeAntiPortal); - /** (recursive) Check the given node against all portals in the zone - */ - virtual void _checkNodeAgainstPortals(PCZSceneNode *, Portal * ) = 0; + /** (recursive) Check the given node against all portals in the zone + */ + virtual void _checkNodeAgainstPortals(PCZSceneNode *, Portal * ) = 0; /** (recursive) Check the given light against all portals in the zone */ @@ -177,15 +177,15 @@ namespace Ogre PCZFrustum *, Portal *) = 0; - /** Update the zone data for each portal - */ - virtual void updatePortalsZoneData(void) = 0; + /** Update the zone data for each portal + */ + virtual void updatePortalsZoneData(void) = 0; - /** Mark nodes dirty base on moving portals. */ - virtual void dirtyNodeByMovingPortals(void) = 0; + /** Mark nodes dirty base on moving portals. */ + virtual void dirtyNodeByMovingPortals(void) = 0; - /** Update a node's home zone */ - virtual PCZone * updateNodeHomeZone(PCZSceneNode * pczsn, bool allowBackTouces) = 0; + /** Update a node's home zone */ + virtual PCZone * updateNodeHomeZone(PCZSceneNode * pczsn, bool allowBackTouces) = 0; /** Find and add visible objects to the render queue. @remarks @@ -193,119 +193,119 @@ namespace Ogre This is a recursive call (the main call should be to _findVisibleObjects) */ virtual void findVisibleNodes(PCZCamera *, - NodeList & visibleNodeList, - RenderQueue * queue, - VisibleObjectsBoundsInfo* visibleBounds, - bool onlyShadowCasters, - bool displayNodes, - bool showBoundingBoxes) = 0; - - /* Functions for finding Nodes that intersect various shapes */ - virtual void _findNodes( const AxisAlignedBox &t, - PCZSceneNodeList &list, + NodeList & visibleNodeList, + RenderQueue * queue, + VisibleObjectsBoundsInfo* visibleBounds, + bool onlyShadowCasters, + bool displayNodes, + bool showBoundingBoxes) = 0; + + /* Functions for finding Nodes that intersect various shapes */ + virtual void _findNodes( const AxisAlignedBox &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude) = 0; - virtual void _findNodes( const Sphere &t, - PCZSceneNodeList &list, + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude) = 0; + virtual void _findNodes( const Sphere &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ) = 0; - virtual void _findNodes( const PlaneBoundedVolume &t, - PCZSceneNodeList &list, + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ) = 0; + virtual void _findNodes( const PlaneBoundedVolume &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ) = 0; - virtual void _findNodes( const Ray &t, - PCZSceneNodeList &list, + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ) = 0; + virtual void _findNodes( const Ray &t, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ) = 0; - - /** Sets the options for the Zone */ - virtual bool setOption( const String &, const void * ) = 0; - /** Called when the scene manager creates a camera in order to store the first camera created as the primary - one, for determining error metrics and the 'home' terrain page. - */ - virtual void notifyCameraCreated( Camera* c ) = 0; - /** Called by PCZSM during setWorldGeometryRenderQueue() */ - virtual void notifyWorldGeometryRenderQueue(uint8 qid) = 0; - /** Called when a _renderScene is called in the SceneManager */ - virtual void notifyBeginRenderScene(void) = 0; - /** Called by PCZSM during setZoneGeometry() */ - virtual void setZoneGeometry(const String &filename, PCZSceneNode * parentNode) = 0; - /** Get the world coordinate aabb of the zone */ - virtual void getAABB(AxisAlignedBox &); - void setPortalsUpdated(bool updated) { mPortalsUpdated = updated; } - bool getPortalsUpdated(void) { return mPortalsUpdated; } - /** Get & set the user data */ - void * getUserData(void) {return mUserData;} - void setUserData(void * userData) {mUserData = userData;} - /** List of Portals which this zone contains (each portal leads to another zone) - */ - PortalList mPortals; - AntiPortalList mAntiPortals; - /// Pointer to the pcz scene manager that created this zone - PCZSceneManager * mPCZSM; - - protected: - /** Binary predicate for portal <-> camera distance sorting. */ - struct PortalSortDistance - { - const Vector3& cameraPosition; - PortalSortDistance(const Vector3& inCameraPosition) : cameraPosition(inCameraPosition) - { } - - bool _OgrePCZPluginExport operator()(const PortalBase* p1, const PortalBase* p2) const - { - Real depth1 = p1->getDerivedCP().squaredDistance(cameraPosition); - Real depth2 = p2->getDerivedCP().squaredDistance(cameraPosition); - return (depth1 < depth2); - } - }; - - /// Name of the zone (must be unique) - String mName; - /// Zone type name - String mZoneTypeName; + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ) = 0; + + /** Sets the options for the Zone */ + virtual bool setOption( const String &, const void * ) = 0; + /** Called when the scene manager creates a camera in order to store the first camera created as the primary + one, for determining error metrics and the 'home' terrain page. + */ + virtual void notifyCameraCreated( Camera* c ) = 0; + /** Called by PCZSM during setWorldGeometryRenderQueue() */ + virtual void notifyWorldGeometryRenderQueue(uint8 qid) = 0; + /** Called when a _renderScene is called in the SceneManager */ + virtual void notifyBeginRenderScene(void) = 0; + /** Called by PCZSM during setZoneGeometry() */ + virtual void setZoneGeometry(const String &filename, PCZSceneNode * parentNode) = 0; + /** Get the world coordinate aabb of the zone */ + virtual void getAABB(AxisAlignedBox &); + void setPortalsUpdated(bool updated) { mPortalsUpdated = updated; } + bool getPortalsUpdated(void) { return mPortalsUpdated; } + /** Get & set the user data */ + void * getUserData(void) {return mUserData;} + void setUserData(void * userData) {mUserData = userData;} + /** List of Portals which this zone contains (each portal leads to another zone) + */ + PortalList mPortals; + AntiPortalList mAntiPortals; + /// Pointer to the pcz scene manager that created this zone + PCZSceneManager * mPCZSM; + + protected: + /** Binary predicate for portal <-> camera distance sorting. */ + struct PortalSortDistance + { + const Vector3& cameraPosition; + PortalSortDistance(const Vector3& inCameraPosition) : cameraPosition(inCameraPosition) + { } + + bool _OgrePCZPluginExport operator()(const PortalBase* p1, const PortalBase* p2) const + { + Real depth1 = p1->getDerivedCP().squaredDistance(cameraPosition); + Real depth2 = p2->getDerivedCP().squaredDistance(cameraPosition); + return (depth1 < depth2); + } + }; + + /// Name of the zone (must be unique) + String mName; + /// Zone type name + String mZoneTypeName; /// Frame counter for visibility unsigned long mLastVisibleFrame; - /// Last camera which this zone was visible to - PCZCamera * mLastVisibleFromCamera; - /// Flag determining whether or not this zone has sky in it. - bool mHasSky; - /// SceneNode which corresponds to the enclosure for this zone - SceneNode * mEnclosureNode; - /// List of SceneNodes contained in this particular PCZone + /// Last camera which this zone was visible to + PCZCamera * mLastVisibleFromCamera; + /// Flag determining whether or not this zone has sky in it. + bool mHasSky; + /// SceneNode which corresponds to the enclosure for this zone + SceneNode * mEnclosureNode; + /// List of SceneNodes contained in this particular PCZone PCZSceneNodeList mHomeNodeList; - /// List of SceneNodes visiting this particular PCZone + /// List of SceneNodes visiting this particular PCZone PCZSceneNodeList mVisitorNodeList; - /// Flag recording whether any portals in this zone have moved - bool mPortalsUpdated; - /** User defined data pointer - NOT allocated or deallocated by the zone! + /// Flag recording whether any portals in this zone have moved + bool mPortalsUpdated; + /** User defined data pointer - NOT allocated or deallocated by the zone! you must clean it up yourself! */ - void * mUserData; + void * mUserData; }; - class _OgrePCZPluginExport ZoneData : public SceneCtlAllocatedObject - { - public: - /** Standard Constructor */ - ZoneData(PCZSceneNode *, PCZone * ); - /** Standard destructor */ - virtual ~ZoneData(); - /** Update data if necessary */ - virtual void update(void); - public: - PCZone * mAssociatedZone; - PCZSceneNode * mAssociatedNode; - - }; + class _OgrePCZPluginExport ZoneData : public SceneCtlAllocatedObject + { + public: + /** Standard Constructor */ + ZoneData(PCZSceneNode *, PCZone * ); + /** Standard destructor */ + virtual ~ZoneData(); + /** Update data if necessary */ + virtual void update(void); + public: + PCZone * mAssociatedZone; + PCZSceneNode * mAssociatedNode; + + }; } diff --git a/PlugIns/PCZSceneManager/include/OgrePCZoneFactory.h b/PlugIns/PCZSceneManager/include/OgrePCZoneFactory.h index 5ab11b63ba7..84883f59aa3 100644 --- a/PlugIns/PCZSceneManager/include/OgrePCZoneFactory.h +++ b/PlugIns/PCZSceneManager/include/OgrePCZoneFactory.h @@ -30,7 +30,7 @@ OgrePCZoneFactory.h - PCZone Factory & Factory Manager begin : Mon Apr 16 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -43,43 +43,43 @@ Code Style Update : namespace Ogre { - class PCZSceneManager; + class PCZSceneManager; class PCZone; - /// Factory for PCZones - class _OgrePCZPluginExport PCZoneFactory : public SceneCtlAllocatedObject + /// Factory for PCZones + class _OgrePCZPluginExport PCZoneFactory : public SceneCtlAllocatedObject { - public: - PCZoneFactory(const String & typeName); - virtual ~PCZoneFactory(); - virtual bool supportsPCZoneType(const String& zoneType) = 0; - virtual PCZone* createPCZone(PCZSceneManager * pczsm, const String& zoneName) = 0; - const String& getFactoryTypeName() const { return mFactoryTypeName; } - /// Factory type name - String mFactoryTypeName; + public: + PCZoneFactory(const String & typeName); + virtual ~PCZoneFactory(); + virtual bool supportsPCZoneType(const String& zoneType) = 0; + virtual PCZone* createPCZone(PCZSceneManager * pczsm, const String& zoneName) = 0; + const String& getFactoryTypeName() const { return mFactoryTypeName; } + /// Factory type name + String mFactoryTypeName; }; - // Factory for default zone - class _OgrePCZPluginExport DefaultZoneFactory : public PCZoneFactory - { - public: - DefaultZoneFactory(); - virtual ~DefaultZoneFactory(); - bool supportsPCZoneType(const String& zoneType); - PCZone* createPCZone(PCZSceneManager * pczsm, const String& zoneName); - }; + // Factory for default zone + class _OgrePCZPluginExport DefaultZoneFactory : public PCZoneFactory + { + public: + DefaultZoneFactory(); + virtual ~DefaultZoneFactory(); + bool supportsPCZoneType(const String& zoneType); + PCZone* createPCZone(PCZSceneManager * pczsm, const String& zoneName); + }; - // PCZoneFactory manager class - class _OgrePCZPluginExport PCZoneFactoryManager : public Singleton, public SceneCtlAllocatedObject - { - public: - PCZoneFactoryManager(); - ~PCZoneFactoryManager(); - void registerPCZoneFactory(PCZoneFactory* factory); - void unregisterPCZoneFactory(PCZoneFactory* factory); - PCZone* createPCZone(PCZSceneManager * pczsm, - const String& zoneType, - const String& zoneName); + // PCZoneFactory manager class + class _OgrePCZPluginExport PCZoneFactoryManager : public Singleton, public SceneCtlAllocatedObject + { + public: + PCZoneFactoryManager(); + ~PCZoneFactoryManager(); + void registerPCZoneFactory(PCZoneFactory* factory); + void unregisterPCZoneFactory(PCZoneFactory* factory); + PCZone* createPCZone(PCZSceneManager * pczsm, + const String& zoneType, + const String& zoneName); /** Override standard Singleton retrieval. @remarks Why do we do this? Well, it's because the Singleton @@ -112,17 +112,17 @@ namespace Ogre preventing link errors. */ static PCZoneFactoryManager* getSingletonPtr(void); - /* PCZoneFactory Iterator - for querying what types of PCZone - factories are available */ - typedef map::type PCZoneFactoryMap; - typedef MapIterator PCZoneFactoryIterator; - /** Return an iterator over the PCZone factories currently registered */ - PCZoneFactoryIterator getPCZoneFactoryIterator(void); + /* PCZoneFactory Iterator - for querying what types of PCZone + factories are available */ + typedef map::type PCZoneFactoryMap; + typedef MapIterator PCZoneFactoryIterator; + /** Return an iterator over the PCZone factories currently registered */ + PCZoneFactoryIterator getPCZoneFactoryIterator(void); - protected: - PCZoneFactoryMap mPCZoneFactories; - DefaultZoneFactory mDefaultFactory; - }; + protected: + PCZoneFactoryMap mPCZoneFactories; + DefaultZoneFactory mDefaultFactory; + }; } #endif diff --git a/PlugIns/PCZSceneManager/include/OgrePortal.h b/PlugIns/PCZSceneManager/include/OgrePortal.h index cbc6226f7e1..b5377747213 100644 --- a/PlugIns/PCZSceneManager/include/OgrePortal.h +++ b/PlugIns/PCZSceneManager/include/OgrePortal.h @@ -25,18 +25,18 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------------- Portal.h - Portals are special constructs which which are used to connect - two Zones in a PCZScene. Portals are defined by 4 coplanr + two Zones in a PCZScene. Portals are defined by 4 coplanr corners and a direction. Portals are contained within Zones and are essentially "one way" connectors. Objects and entities can - use them to travel to other Zones, but to return, there must be - a corresponding Portal which connects back to the original zone - from the new zone. + use them to travel to other Zones, but to return, there must be + a corresponding Portal which connects back to the original zone + from the new zone. ----------------------------------------------------------------------------- begin : Thu Feb 22 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : Apr 5, 2007 +Code Style Update : Apr 5, 2007 ----------------------------------------------------------------------------- */ @@ -47,56 +47,56 @@ Code Style Update : Apr 5, 2007 namespace Ogre { - /** Portal datastructure for connecting zones. */ - class _OgrePCZPluginExport Portal : public PortalBase - { - public: - Portal(const String &name, const PORTAL_TYPE type = PORTAL_TYPE_QUAD); - virtual ~Portal(); - - void setTargetZone(PCZone* zone); - /** Set the target portal pointer */ - void setTargetPortal(Portal* portal); - - /** Get the Zone the Portal connects to */ - PCZone* getTargetZone() {return mTargetZone;} - /** Get the connected portal (if any) */ - Portal* getTargetPortal() {return mTargetPortal;} - - /** @copydoc MovableObject::getMovableType. */ - const String& getMovableType() const; - - protected: - ///connected Zone - PCZone* mTargetZone; - /** Matching Portal in the target zone (usually in same world space - as this portal, but pointing the opposite direction) - */ - Portal* mTargetPortal; - }; - - /** Factory object for creating Portal instances */ - class _OgrePCZPluginExport PortalFactory : public PortalBaseFactory - { - protected: - MovableObject* createInstanceImpl(const String& name, const NameValuePairList* params); - public: - PortalFactory() {} - ~PortalFactory() {} - - static String FACTORY_TYPE_NAME; - static unsigned long FACTORY_TYPE_FLAG; - - const String& getType() const - { return FACTORY_TYPE_NAME; } - - void destroyInstance(MovableObject* obj); - - /** Return true here as we want to get a unique type flag. */ - bool requestTypeFlags() const - { return true; } - - }; + /** Portal datastructure for connecting zones. */ + class _OgrePCZPluginExport Portal : public PortalBase + { + public: + Portal(const String &name, const PORTAL_TYPE type = PORTAL_TYPE_QUAD); + virtual ~Portal(); + + void setTargetZone(PCZone* zone); + /** Set the target portal pointer */ + void setTargetPortal(Portal* portal); + + /** Get the Zone the Portal connects to */ + PCZone* getTargetZone() {return mTargetZone;} + /** Get the connected portal (if any) */ + Portal* getTargetPortal() {return mTargetPortal;} + + /** @copydoc MovableObject::getMovableType. */ + const String& getMovableType() const; + + protected: + ///connected Zone + PCZone* mTargetZone; + /** Matching Portal in the target zone (usually in same world space + as this portal, but pointing the opposite direction) + */ + Portal* mTargetPortal; + }; + + /** Factory object for creating Portal instances */ + class _OgrePCZPluginExport PortalFactory : public PortalBaseFactory + { + protected: + MovableObject* createInstanceImpl(const String& name, const NameValuePairList* params); + public: + PortalFactory() {} + ~PortalFactory() {} + + static String FACTORY_TYPE_NAME; + static unsigned long FACTORY_TYPE_FLAG; + + const String& getType() const + { return FACTORY_TYPE_NAME; } + + void destroyInstance(MovableObject* obj); + + /** Return true here as we want to get a unique type flag. */ + bool requestTypeFlags() const + { return true; } + + }; } diff --git a/PlugIns/PCZSceneManager/include/OgrePortalBase.h b/PlugIns/PCZSceneManager/include/OgrePortalBase.h index 6a69b6d3ee9..3679e46a9f2 100644 --- a/PlugIns/PCZSceneManager/include/OgrePortalBase.h +++ b/PlugIns/PCZSceneManager/include/OgrePortalBase.h @@ -39,264 +39,264 @@ PortalBase.h - PortalBase is the base class for Portal and AntiPortal. namespace Ogre { - class PCZSceneNode; + class PCZSceneNode; class PCZone; - /** PortalBase - Base class to Portal and AntiPortal classes. */ - class _OgrePCZPluginExport PortalBase : public MovableObject - { - public: - enum PORTAL_TYPE - { - PORTAL_TYPE_QUAD, - PORTAL_TYPE_AABB, - PORTAL_TYPE_SPHERE - }; - - /** Constructor. */ - PortalBase(const String& name, const PORTAL_TYPE type = PORTAL_TYPE_QUAD); - - /** Destructor. */ - virtual ~PortalBase(); - - /** Retrieves the axis-aligned bounding box for this object in world coordinates. */ - virtual const AxisAlignedBox& getWorldBoundingBox(bool derive = false) const; - /** Retrieves the worldspace bounding sphere for this object. */ - virtual const Sphere& getWorldBoundingSphere(bool derive = false) const; - - /** Set the SceneNode the Portal is associated with */ - void setNode(SceneNode* sn); - /** Set the current home zone of the portal */ - void setCurrentHomeZone(PCZone* zone); - /** Set the zone this portal should be moved to */ - void setNewHomeZone(PCZone* zone); - - /** Set the local coordinates of one of the portal corners */ - void setCorner(int index, const Vector3& point); - /** Set the local coordinates of all of the portal corners */ - void setCorners(const Vector3* corners); - /** Set the "inward/outward norm" direction of AAB or SPHERE portals - NOTE: UNIT_Z = "outward" norm, NEGATIVE_UNIT_Z = "inward" norm - NOTE: Remember, Portal norms always point towards the zone they are "in". - */ - void setDirection(const Vector3 &d) - { - switch (mType) - { - default: - case PORTAL_TYPE_QUAD: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Cannot setDirection on a Quad type portal", - "Portal::setDirection"); - break; - case PORTAL_TYPE_AABB: - case PORTAL_TYPE_SPHERE: - if (d != Vector3::UNIT_Z && - d != Vector3::NEGATIVE_UNIT_Z) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Valid parameters are Vector3::UNIT_Z or Vector3::NEGATIVE_UNIT_Z", - "Portal::setDirection"); - return; - } - mDirection = d; - break; - } - } - /** Calculate the local direction and radius of the portal */ - void calcDirectionAndRadius() const; - - /** Get the type of portal */ - PORTAL_TYPE getType() const {return mType;} - /** Retrieve the radius of the portal (calculates if necessary for quad portals) */ - Real getRadius() const; - - /** Get the Zone the Portal is currently "in" */ - PCZone* getCurrentHomeZone() - { return mCurrentHomeZone; } - /** Get the Zone the Portal should be moved to */ - PCZone* getNewHomeZone() - { return mNewHomeZone; } - - /** Get the coordinates of one of the portal corners in local space */ - const Vector3& getCorner(int index) const - { return mCorners[index]; } - /** Get the direction vector of the portal in local space */ - const Vector3& getDirection() const - { return mDirection; } - - /** Get the derived (world) coordinates of one of the portal corners */ - const Vector3& getDerivedCorner(int index) const - { return mDerivedCorners[index]; } - /** Get the direction of the portal in world coordinates */ - const Vector3& getDerivedDirection() const - { return mDerivedDirection; } - /** Get the position (centerpoint) of the portal in world coordinates */ - const Vector3& getDerivedCP() const - { return mDerivedCP; } - /** Get the sphere centered on the derived CP of the portal in world coordinates */ - const Sphere& getDerivedSphere() const - { return mDerivedSphere; } - /** Get the portal plane in world coordinates */ - const Plane& getDerivedPlane() const - { return mDerivedPlane; } - - /** Get the previous position (centerpoint) of the portal in world coordinates */ - const Vector3& getPrevDerivedCP() const - { return mPrevDerivedCP; } - /** Get the previous portal plane in world coordinates */ - const Plane& getPrevDerivedPlane() const - { return mPrevDerivedPlane; } - - /** Update the derived values */ - void updateDerivedValues() const; - /** Adjust the portal so that it is centered and oriented on the given node */ - void adjustNodeToMatch(SceneNode* node); - /** enable the portal */ - void setEnabled(bool value) - { mEnabled = value; } - /** Check if portal is enabled */ - bool getEnabled() const {return mEnabled;} - - - enum PortalIntersectResult - { - NO_INTERSECT, - INTERSECT_NO_CROSS, - INTERSECT_BACK_NO_CROSS, - INTERSECT_CROSS - }; - /** Check if portal intersects an aab */ - bool intersects(const AxisAlignedBox& aab); - - /** Check if portal intersects an sphere */ - bool intersects(const Sphere& sphere); - - /** Check if portal intersects a plane bounded volume */ - bool intersects(const PlaneBoundedVolume& pbv); - - /** Check if portal intersects a ray */ - bool intersects(const Ray& ray); - - /** Check for intersection between portal & scenenode (also determines - * if scenenode crosses over portal - */ - PortalIntersectResult intersects(PCZSceneNode* sn); - - /** Check if portal crossed over portal */ - bool crossedPortal(const PortalBase* otherPortal); - /** Check if portal touches another portal */ - bool closeTo(const PortalBase* otherPortal); - - /** @copydoc MovableObject::getBoundingBox. */ - const AxisAlignedBox& getBoundingBox() const; - - /** @copydoc MovableObject::getBoundingRadius. */ - Real getBoundingRadius() const - { return getRadius(); } - - /** @copydoc MovableObject::_updateRenderQueue. */ - void _updateRenderQueue(RenderQueue* queue) - { /* Draw debug info if needed? */ } - - /** @copydoc MovableObject::visitRenderables. */ - void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables = false) - { } - - /** Called when scene node moved. */ - void _notifyMoved() - { - updateDerivedValues(); - mWasMoved = true; - } - - /** Called when attached to a scene node. */ - void _notifyAttached(Node* parent, bool isTagPoint = false) - { - MovableObject::_notifyAttached(parent, isTagPoint); - mDerivedUpToDate = false; - } - - /** Returns true if portal needs update. */ - bool needUpdate(); - - /** Returns an updated capsule of the portal for intersection test. */ - const Capsule& getCapsule() const; - - /** Returns an updated AAB of the portal for intersection test. */ - const AxisAlignedBox& getAAB(); - - protected: - // Type of portal (quad, aabb, or sphere) - PORTAL_TYPE mType; - /// Zone this portal is currently owned by (in) - PCZone * mCurrentHomeZone; - /// Zone to transfer this portal to - PCZone * mNewHomeZone; - /// Corners of the portal - coordinates are relative to the sceneNode - // NOTE: there are 4 corners if the portal is a quad type - // there are 2 corners if the portal is an AABB type - // there are 2 corners if the portal is a sphere type (center and point on sphere) - Vector3 * mCorners; - /// Direction ("Norm") of the portal - - // NOTE: For a Quad portal, determined by the 1st 3 corners. - // NOTE: For AABB & SPHERE portals, we only have "inward" or "outward" cases. - // To indicate "outward", the Direction is UNIT_Z - // to indicate "inward", the Direction is NEGATIVE_UNIT_Z - mutable Vector3 mDirection; - /// Radius of the sphere enclosing the portal - // NOTE: For aabb portals, this value is the distance from the center of the aab to a corner - mutable Real mRadius; - /// Local Centerpoint of the portal - mutable Vector3 mLocalCP; - /// Derived (world coordinates) Corners of the portal - // NOTE: there are 4 corners if the portal is a quad type - // there are 2 corners if the portal is an AABB type (min corner & max corner) - // there are 2 corners if the portal is a sphere type (center and point on sphere) - Vector3 * mDerivedCorners; - /// Derived (world coordinates) direction of the portal - // NOTE: Only applicable for a Quad portal - mutable Vector3 mDerivedDirection; - /// Derived (world coordinates) of portal (center point) - mutable Vector3 mDerivedCP; - /// Sphere of the portal centered on the derived CP - mutable Sphere mDerivedSphere; - /// Derived (world coordinates) Plane of the portal - // NOTE: Only applicable for a Quad portal - mutable Plane mDerivedPlane; - /// Previous frame portal cp (in world coordinates) - mutable Vector3 mPrevDerivedCP; - /// Previous frame derived plane - // NOTE: Only applicable for a Quad portal - mutable Plane mPrevDerivedPlane; - /// Flag indicating whether or not local values are up-to-date - mutable bool mLocalsUpToDate; - /// Flag indicating whether or not derived values are up-to-date - mutable bool mDerivedUpToDate; - /// Previous world transform - mutable Matrix4 mPrevWorldTransform; - /// Flag defining if portal is enabled or disabled. - bool mEnabled; - /// Cache of portal's capsule. - mutable Capsule mPortalCapsule; - /// Cache of portal's AAB that contains the bound of portal movement. - mutable AxisAlignedBox mPortalAAB; - /// Cache of portal's previous AAB. - mutable AxisAlignedBox mPrevPortalAAB; - /// Cache of portal's local AAB. - mutable AxisAlignedBox mLocalPortalAAB; - /// Defined if portal was moved previously. - mutable bool mWasMoved; - }; - - /** Factory object for creating Portal instances */ - class _OgrePCZPluginExport PortalBaseFactory : public MovableObjectFactory - { - protected: - /** Get the portal type from name value pair. */ - PortalBase::PORTAL_TYPE getPortalType(const NameValuePairList* params); - - }; + /** PortalBase - Base class to Portal and AntiPortal classes. */ + class _OgrePCZPluginExport PortalBase : public MovableObject + { + public: + enum PORTAL_TYPE + { + PORTAL_TYPE_QUAD, + PORTAL_TYPE_AABB, + PORTAL_TYPE_SPHERE + }; + + /** Constructor. */ + PortalBase(const String& name, const PORTAL_TYPE type = PORTAL_TYPE_QUAD); + + /** Destructor. */ + virtual ~PortalBase(); + + /** Retrieves the axis-aligned bounding box for this object in world coordinates. */ + virtual const AxisAlignedBox& getWorldBoundingBox(bool derive = false) const; + /** Retrieves the worldspace bounding sphere for this object. */ + virtual const Sphere& getWorldBoundingSphere(bool derive = false) const; + + /** Set the SceneNode the Portal is associated with */ + void setNode(SceneNode* sn); + /** Set the current home zone of the portal */ + void setCurrentHomeZone(PCZone* zone); + /** Set the zone this portal should be moved to */ + void setNewHomeZone(PCZone* zone); + + /** Set the local coordinates of one of the portal corners */ + void setCorner(int index, const Vector3& point); + /** Set the local coordinates of all of the portal corners */ + void setCorners(const Vector3* corners); + /** Set the "inward/outward norm" direction of AAB or SPHERE portals + NOTE: UNIT_Z = "outward" norm, NEGATIVE_UNIT_Z = "inward" norm + NOTE: Remember, Portal norms always point towards the zone they are "in". + */ + void setDirection(const Vector3 &d) + { + switch (mType) + { + default: + case PORTAL_TYPE_QUAD: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Cannot setDirection on a Quad type portal", + "Portal::setDirection"); + break; + case PORTAL_TYPE_AABB: + case PORTAL_TYPE_SPHERE: + if (d != Vector3::UNIT_Z && + d != Vector3::NEGATIVE_UNIT_Z) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Valid parameters are Vector3::UNIT_Z or Vector3::NEGATIVE_UNIT_Z", + "Portal::setDirection"); + return; + } + mDirection = d; + break; + } + } + /** Calculate the local direction and radius of the portal */ + void calcDirectionAndRadius() const; + + /** Get the type of portal */ + PORTAL_TYPE getType() const {return mType;} + /** Retrieve the radius of the portal (calculates if necessary for quad portals) */ + Real getRadius() const; + + /** Get the Zone the Portal is currently "in" */ + PCZone* getCurrentHomeZone() + { return mCurrentHomeZone; } + /** Get the Zone the Portal should be moved to */ + PCZone* getNewHomeZone() + { return mNewHomeZone; } + + /** Get the coordinates of one of the portal corners in local space */ + const Vector3& getCorner(int index) const + { return mCorners[index]; } + /** Get the direction vector of the portal in local space */ + const Vector3& getDirection() const + { return mDirection; } + + /** Get the derived (world) coordinates of one of the portal corners */ + const Vector3& getDerivedCorner(int index) const + { return mDerivedCorners[index]; } + /** Get the direction of the portal in world coordinates */ + const Vector3& getDerivedDirection() const + { return mDerivedDirection; } + /** Get the position (centerpoint) of the portal in world coordinates */ + const Vector3& getDerivedCP() const + { return mDerivedCP; } + /** Get the sphere centered on the derived CP of the portal in world coordinates */ + const Sphere& getDerivedSphere() const + { return mDerivedSphere; } + /** Get the portal plane in world coordinates */ + const Plane& getDerivedPlane() const + { return mDerivedPlane; } + + /** Get the previous position (centerpoint) of the portal in world coordinates */ + const Vector3& getPrevDerivedCP() const + { return mPrevDerivedCP; } + /** Get the previous portal plane in world coordinates */ + const Plane& getPrevDerivedPlane() const + { return mPrevDerivedPlane; } + + /** Update the derived values */ + void updateDerivedValues() const; + /** Adjust the portal so that it is centered and oriented on the given node */ + void adjustNodeToMatch(SceneNode* node); + /** enable the portal */ + void setEnabled(bool value) + { mEnabled = value; } + /** Check if portal is enabled */ + bool getEnabled() const {return mEnabled;} + + + enum PortalIntersectResult + { + NO_INTERSECT, + INTERSECT_NO_CROSS, + INTERSECT_BACK_NO_CROSS, + INTERSECT_CROSS + }; + /** Check if portal intersects an aab */ + bool intersects(const AxisAlignedBox& aab); + + /** Check if portal intersects an sphere */ + bool intersects(const Sphere& sphere); + + /** Check if portal intersects a plane bounded volume */ + bool intersects(const PlaneBoundedVolume& pbv); + + /** Check if portal intersects a ray */ + bool intersects(const Ray& ray); + + /** Check for intersection between portal & scenenode (also determines + * if scenenode crosses over portal + */ + PortalIntersectResult intersects(PCZSceneNode* sn); + + /** Check if portal crossed over portal */ + bool crossedPortal(const PortalBase* otherPortal); + /** Check if portal touches another portal */ + bool closeTo(const PortalBase* otherPortal); + + /** @copydoc MovableObject::getBoundingBox. */ + const AxisAlignedBox& getBoundingBox() const; + + /** @copydoc MovableObject::getBoundingRadius. */ + Real getBoundingRadius() const + { return getRadius(); } + + /** @copydoc MovableObject::_updateRenderQueue. */ + void _updateRenderQueue(RenderQueue* queue) + { /* Draw debug info if needed? */ } + + /** @copydoc MovableObject::visitRenderables. */ + void visitRenderables(Renderable::Visitor* visitor, bool debugRenderables = false) + { } + + /** Called when scene node moved. */ + void _notifyMoved() + { + updateDerivedValues(); + mWasMoved = true; + } + + /** Called when attached to a scene node. */ + void _notifyAttached(Node* parent, bool isTagPoint = false) + { + MovableObject::_notifyAttached(parent, isTagPoint); + mDerivedUpToDate = false; + } + + /** Returns true if portal needs update. */ + bool needUpdate(); + + /** Returns an updated capsule of the portal for intersection test. */ + const Capsule& getCapsule() const; + + /** Returns an updated AAB of the portal for intersection test. */ + const AxisAlignedBox& getAAB(); + + protected: + // Type of portal (quad, aabb, or sphere) + PORTAL_TYPE mType; + /// Zone this portal is currently owned by (in) + PCZone * mCurrentHomeZone; + /// Zone to transfer this portal to + PCZone * mNewHomeZone; + /// Corners of the portal - coordinates are relative to the sceneNode + // NOTE: there are 4 corners if the portal is a quad type + // there are 2 corners if the portal is an AABB type + // there are 2 corners if the portal is a sphere type (center and point on sphere) + Vector3 * mCorners; + /// Direction ("Norm") of the portal - + // NOTE: For a Quad portal, determined by the 1st 3 corners. + // NOTE: For AABB & SPHERE portals, we only have "inward" or "outward" cases. + // To indicate "outward", the Direction is UNIT_Z + // to indicate "inward", the Direction is NEGATIVE_UNIT_Z + mutable Vector3 mDirection; + /// Radius of the sphere enclosing the portal + // NOTE: For aabb portals, this value is the distance from the center of the aab to a corner + mutable Real mRadius; + /// Local Centerpoint of the portal + mutable Vector3 mLocalCP; + /// Derived (world coordinates) Corners of the portal + // NOTE: there are 4 corners if the portal is a quad type + // there are 2 corners if the portal is an AABB type (min corner & max corner) + // there are 2 corners if the portal is a sphere type (center and point on sphere) + Vector3 * mDerivedCorners; + /// Derived (world coordinates) direction of the portal + // NOTE: Only applicable for a Quad portal + mutable Vector3 mDerivedDirection; + /// Derived (world coordinates) of portal (center point) + mutable Vector3 mDerivedCP; + /// Sphere of the portal centered on the derived CP + mutable Sphere mDerivedSphere; + /// Derived (world coordinates) Plane of the portal + // NOTE: Only applicable for a Quad portal + mutable Plane mDerivedPlane; + /// Previous frame portal cp (in world coordinates) + mutable Vector3 mPrevDerivedCP; + /// Previous frame derived plane + // NOTE: Only applicable for a Quad portal + mutable Plane mPrevDerivedPlane; + /// Flag indicating whether or not local values are up-to-date + mutable bool mLocalsUpToDate; + /// Flag indicating whether or not derived values are up-to-date + mutable bool mDerivedUpToDate; + /// Previous world transform + mutable Matrix4 mPrevWorldTransform; + /// Flag defining if portal is enabled or disabled. + bool mEnabled; + /// Cache of portal's capsule. + mutable Capsule mPortalCapsule; + /// Cache of portal's AAB that contains the bound of portal movement. + mutable AxisAlignedBox mPortalAAB; + /// Cache of portal's previous AAB. + mutable AxisAlignedBox mPrevPortalAAB; + /// Cache of portal's local AAB. + mutable AxisAlignedBox mLocalPortalAAB; + /// Defined if portal was moved previously. + mutable bool mWasMoved; + }; + + /** Factory object for creating Portal instances */ + class _OgrePCZPluginExport PortalBaseFactory : public MovableObjectFactory + { + protected: + /** Get the portal type from name value pair. */ + PortalBase::PORTAL_TYPE getPortalType(const NameValuePairList* params); + + }; } diff --git a/PlugIns/PCZSceneManager/include/OgreSegment.h b/PlugIns/PCZSceneManager/include/OgreSegment.h index d7521613f52..937b0df87ed 100644 --- a/PlugIns/PCZSceneManager/include/OgreSegment.h +++ b/PlugIns/PCZSceneManager/include/OgreSegment.h @@ -30,7 +30,7 @@ Some algorithms based off code from the Wild Magic library by Dave Eberly begin : Mon Apr 02 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : Apr 5, 2007 +Code Style Update : Apr 5, 2007 ----------------------------------------------------------------------------- */ @@ -41,41 +41,41 @@ Code Style Update : Apr 5, 2007 namespace Ogre { - class Capsule; + class Capsule; - class Segment - { - public: - // The segment is represented as P+t*D, where P is the segment origin, - // D is a unit-length direction vector and |t| <= e. The value e is - // referred to as the extent of the segment. The end points of the - // segment are P-e*D and P+e*D. The user must ensure that the direction - // vector is unit-length. The representation for a segment is analogous - // to that for an oriented bounding box. P is the center, D is the - // axis direction, and e is the extent. + class Segment + { + public: + // The segment is represented as P+t*D, where P is the segment origin, + // D is a unit-length direction vector and |t| <= e. The value e is + // referred to as the extent of the segment. The end points of the + // segment are P-e*D and P+e*D. The user must ensure that the direction + // vector is unit-length. The representation for a segment is analogous + // to that for an oriented bounding box. P is the center, D is the + // axis direction, and e is the extent. - // construction - Segment (); // uninitialized - Segment (const Vector3&, const Vector3&, Real); + // construction + Segment (); // uninitialized + Segment (const Vector3&, const Vector3&, Real); - // set values - void set(const Vector3& newOrigin, const Vector3& newEnd); - void setOrigin(const Vector3& newOrigin); - void setEndPoint(const Vector3& newEndpoint); + // set values + void set(const Vector3& newOrigin, const Vector3& newEnd); + void setOrigin(const Vector3& newOrigin); + void setEndPoint(const Vector3& newEndpoint); - // functions to calculate distance to another segment - Real distance(const Segment& otherSegment) const; - Real squaredDistance(const Segment& otherSegment) const; + // functions to calculate distance to another segment + Real distance(const Segment& otherSegment) const; + Real squaredDistance(const Segment& otherSegment) const; - // intersect check between segment & capsule - bool intersects(const Capsule&) const; + // intersect check between segment & capsule + bool intersects(const Capsule&) const; - // defining variables - Vector3 mOrigin; - Vector3 mDirection; - Real mExtent; - }; + // defining variables + Vector3 mOrigin; + Vector3 mDirection; + Real mExtent; + }; } #endif //SEGMENT_H diff --git a/PlugIns/PCZSceneManager/src/OgreAntiPortal.cpp b/PlugIns/PCZSceneManager/src/OgreAntiPortal.cpp index f04d61372fc..bffdd48b820 100644 --- a/PlugIns/PCZSceneManager/src/OgreAntiPortal.cpp +++ b/PlugIns/PCZSceneManager/src/OgreAntiPortal.cpp @@ -33,7 +33,7 @@ AntiPortal.cpp - using namespace Ogre; AntiPortal::AntiPortal(const String& name, const PORTAL_TYPE type) - : PortalBase(name, type) + : PortalBase(name, type) { } @@ -44,7 +44,7 @@ AntiPortal::~AntiPortal() /** @copydoc MovableObject::getMovableType. */ const String& AntiPortal::getMovableType() const { - return AntiPortalFactory::FACTORY_TYPE_NAME; + return AntiPortalFactory::FACTORY_TYPE_NAME; } //----------------------------------------------------------------------- @@ -54,10 +54,10 @@ unsigned long AntiPortalFactory::FACTORY_TYPE_FLAG = 0xFFFFFFFF; MovableObject* AntiPortalFactory::createInstanceImpl(const String& name, const NameValuePairList* params) { - return OGRE_NEW AntiPortal(name, getPortalType(params)); + return OGRE_NEW AntiPortal(name, getPortalType(params)); } void AntiPortalFactory::destroyInstance(MovableObject* obj) { - OGRE_DELETE obj; + OGRE_DELETE obj; } diff --git a/PlugIns/PCZSceneManager/src/OgreCapsule.cpp b/PlugIns/PCZSceneManager/src/OgreCapsule.cpp index 5b667ec1603..5aa2f5c9dc1 100644 --- a/PlugIns/PCZSceneManager/src/OgreCapsule.cpp +++ b/PlugIns/PCZSceneManager/src/OgreCapsule.cpp @@ -41,46 +41,46 @@ using namespace Ogre; Capsule::Capsule() { - // uninitialized + // uninitialized } //---------------------------------------------------------------------------- Capsule::Capsule(const Segment& segment, Real radius) - : mSegment(segment), - mRadius(radius) + : mSegment(segment), + mRadius(radius) { } //---------------------------------------------------------------------------- void Capsule::set(const Vector3& newOrigin, const Vector3& newEnd, Real newRadius) { - mSegment.set(newOrigin, newEnd); - mRadius = newRadius; + mSegment.set(newOrigin, newEnd); + mRadius = newRadius; } //---------------------------------------------------------------------------- void Capsule::setOrigin(const Vector3& newOrigin) { - mSegment.mOrigin = newOrigin; + mSegment.mOrigin = newOrigin; } //---------------------------------------------------------------------------- void Capsule::setEndPoint(const Vector3& newEndpoint) { - mSegment.setEndPoint(newEndpoint); + mSegment.setEndPoint(newEndpoint); } //---------------------------------------------------------------------------- void Capsule::setRadius(Real newRadius) { - mRadius = newRadius; + mRadius = newRadius; } //---------------------------------------------------------------------------- bool Capsule::intersects(const Capsule& otherCapsule) const { - Real fDistance = mSegment.distance(otherCapsule.mSegment); - Real fRSum = mRadius + otherCapsule.mRadius; - return fDistance <= fRSum; + Real fDistance = mSegment.distance(otherCapsule.mSegment); + Real fRSum = mRadius + otherCapsule.mRadius; + return fDistance <= fRSum; } //---------------------------------------------------------------------------- bool Capsule::intersects(const Segment& segment) const { - Real fDist = segment.distance(mSegment); - return fDist <= mRadius; + Real fDist = segment.distance(mSegment); + return fDist <= mRadius; } //---------------------------------------------------------------------------- diff --git a/PlugIns/PCZSceneManager/src/OgreDefaultZone.cpp b/PlugIns/PCZSceneManager/src/OgreDefaultZone.cpp index e67b571e43e..638766ff013 100644 --- a/PlugIns/PCZSceneManager/src/OgreDefaultZone.cpp +++ b/PlugIns/PCZSceneManager/src/OgreDefaultZone.cpp @@ -47,107 +47,107 @@ namespace Ogre { DefaultZone::DefaultZone( PCZSceneManager * creator, const String& name ) - : PCZone(creator, name) + : PCZone(creator, name) { - mZoneTypeName = "ZoneType_Default"; - } + mZoneTypeName = "ZoneType_Default"; + } DefaultZone::~DefaultZone() { } - /** Set the enclosure node for this Zone - */ - void DefaultZone::setEnclosureNode(PCZSceneNode * node) - { - mEnclosureNode = node; - // anchor the node to this zone - node->anchorToHomeZone(this); - } + /** Set the enclosure node for this Zone + */ + void DefaultZone::setEnclosureNode(PCZSceneNode * node) + { + mEnclosureNode = node; + // anchor the node to this zone + node->anchorToHomeZone(this); + } // this call adds the given node to either the zone's list - // of nodes at home in the zone, or to the list of visiting nodes - // NOTE: The list is decided by the node's homeZone value, so - // that must be set correctly before calling this function. + // of nodes at home in the zone, or to the list of visiting nodes + // NOTE: The list is decided by the node's homeZone value, so + // that must be set correctly before calling this function. void DefaultZone::_addNode( PCZSceneNode * n ) { - if (n->getHomeZone() == this) - { - // add a reference to this node in the "nodes at home in this zone" list - mHomeNodeList.insert( n ); - } - else - { - // add a reference to this node in the "nodes visiting this zone" list - mVisitorNodeList.insert( n ); - } + if (n->getHomeZone() == this) + { + // add a reference to this node in the "nodes at home in this zone" list + mHomeNodeList.insert( n ); + } + else + { + // add a reference to this node in the "nodes visiting this zone" list + mVisitorNodeList.insert( n ); + } } void DefaultZone::removeNode( PCZSceneNode * n ) { - if (n->getHomeZone() == this) - { - mHomeNodeList.erase( n ); - } - else - { - mVisitorNodeList.erase( n ); - } + if (n->getHomeZone() == this) + { + mHomeNodeList.erase( n ); + } + else + { + mVisitorNodeList.erase( n ); + } } - /** Indicates whether or not this zone requires zone-specific data for - * each scene node - */ - bool DefaultZone::requiresZoneSpecificNodeData(void) - { - // regular DefaultZones don't require any zone specific node data - return false; - } - - /* Recursively check for intersection of the given scene node - * with zone portals. If the node touches a portal, then the - * connected zone is assumed to be touched. The zone adds - * the node to its node list and the node adds the zone to - * its visiting zone list. - * - * NOTE: This function assumes that the home zone of the node - * is correct. The function "_updateHomeZone" in PCZSceneManager - * takes care of this and should have been called before - * this function. - */ - - void DefaultZone::_checkNodeAgainstPortals(PCZSceneNode * pczsn, Portal * ignorePortal) - { - if (pczsn == mEnclosureNode || - pczsn->allowedToVisit() == false) - { - // don't do any checking of enclosure node versus portals - return; - } - - PCZone * connectedZone; + /** Indicates whether or not this zone requires zone-specific data for + * each scene node + */ + bool DefaultZone::requiresZoneSpecificNodeData(void) + { + // regular DefaultZones don't require any zone specific node data + return false; + } + + /* Recursively check for intersection of the given scene node + * with zone portals. If the node touches a portal, then the + * connected zone is assumed to be touched. The zone adds + * the node to its node list and the node adds the zone to + * its visiting zone list. + * + * NOTE: This function assumes that the home zone of the node + * is correct. The function "_updateHomeZone" in PCZSceneManager + * takes care of this and should have been called before + * this function. + */ + + void DefaultZone::_checkNodeAgainstPortals(PCZSceneNode * pczsn, Portal * ignorePortal) + { + if (pczsn == mEnclosureNode || + pczsn->allowedToVisit() == false) + { + // don't do any checking of enclosure node versus portals + return; + } + + PCZone * connectedZone; for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) { - Portal * p = *it; - //Check if the portal intersects the node - if (p != ignorePortal && - p->intersects(pczsn) != Portal::NO_INTERSECT) - { - // node is touching this portal - connectedZone = p->getTargetZone(); - // add zone to the nodes visiting zone list unless it is the home zone of the node - if (connectedZone != pczsn->getHomeZone() && - !pczsn->isVisitingZone(connectedZone)) - { - pczsn->addZoneToVisitingZonesMap(connectedZone); - // tell the connected zone that the node is visiting it - connectedZone->_addNode(pczsn); - //recurse into the connected zone - connectedZone->_checkNodeAgainstPortals(pczsn, p->getTargetPortal()); - } - } + Portal * p = *it; + //Check if the portal intersects the node + if (p != ignorePortal && + p->intersects(pczsn) != Portal::NO_INTERSECT) + { + // node is touching this portal + connectedZone = p->getTargetZone(); + // add zone to the nodes visiting zone list unless it is the home zone of the node + if (connectedZone != pczsn->getHomeZone() && + !pczsn->isVisitingZone(connectedZone)) + { + pczsn->addZoneToVisitingZonesMap(connectedZone); + // tell the connected zone that the node is visiting it + connectedZone->_addNode(pczsn); + //recurse into the connected zone + connectedZone->_checkNodeAgainstPortals(pczsn, p->getTargetPortal()); + } + } } - } + } /** (recursive) check the given light against all portals in the zone * NOTE: This is the default implementation, which doesn't take advantage @@ -158,9 +158,9 @@ namespace Ogre PCZFrustum *portalFrustum, Portal * ignorePortal) { - for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) - { - Portal * p = *it; + for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) + { + Portal * p = *it; if (p != ignorePortal) { // calculate the direction vector from light to portal @@ -176,28 +176,28 @@ namespace Ogre // point lights - just check if within illumination range if (lightToPortal.length() <= light->getAttenuationRange()) { - // if portal is quad portal it must be pointing towards the light - if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || - (p->getType() != Portal::PORTAL_TYPE_QUAD)) - { - if (!light->affectsZone(targetZone)) - { - light->addZoneToAffectedZonesList(targetZone); - if (targetZone->getLastVisibleFrame() == frameCount) - { - light->setAffectsVisibleZone(true); - } - // set culling frustum from the portal - portalFrustum->addPortalCullingPlanes(p); - // recurse into the target zone of the portal - p->getTargetZone()->_checkLightAgainstPortals(light, - frameCount, - portalFrustum, - p->getTargetPortal()); - // remove the planes added by this portal - portalFrustum->removePortalCullingPlanes(p); - } - } + // if portal is quad portal it must be pointing towards the light + if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || + (p->getType() != Portal::PORTAL_TYPE_QUAD)) + { + if (!light->affectsZone(targetZone)) + { + light->addZoneToAffectedZonesList(targetZone); + if (targetZone->getLastVisibleFrame() == frameCount) + { + light->setAffectsVisibleZone(true); + } + // set culling frustum from the portal + portalFrustum->addPortalCullingPlanes(p); + // recurse into the target zone of the portal + p->getTargetZone()->_checkLightAgainstPortals(light, + frameCount, + portalFrustum, + p->getTargetPortal()); + // remove the planes added by this portal + portalFrustum->removePortalCullingPlanes(p); + } + } } break; case Light::LT_DIRECTIONAL: @@ -205,28 +205,28 @@ namespace Ogre // the direction is facing the portal if (lightToPortal.dotProduct(light->getDerivedDirection()) >= 0.0) { - // if portal is quad portal it must be pointing towards the light - if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || - (p->getType() != Portal::PORTAL_TYPE_QUAD)) - { - if (!light->affectsZone(targetZone)) - { - light->addZoneToAffectedZonesList(targetZone); - if (targetZone->getLastVisibleFrame() == frameCount) - { - light->setAffectsVisibleZone(true); - } - // set culling frustum from the portal - portalFrustum->addPortalCullingPlanes(p); - // recurse into the target zone of the portal - p->getTargetZone()->_checkLightAgainstPortals(light, - frameCount, - portalFrustum, - p->getTargetPortal()); - // remove the planes added by this portal - portalFrustum->removePortalCullingPlanes(p); - } - } + // if portal is quad portal it must be pointing towards the light + if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || + (p->getType() != Portal::PORTAL_TYPE_QUAD)) + { + if (!light->affectsZone(targetZone)) + { + light->addZoneToAffectedZonesList(targetZone); + if (targetZone->getLastVisibleFrame() == frameCount) + { + light->setAffectsVisibleZone(true); + } + // set culling frustum from the portal + portalFrustum->addPortalCullingPlanes(p); + // recurse into the target zone of the portal + p->getTargetZone()->_checkLightAgainstPortals(light, + frameCount, + portalFrustum, + p->getTargetPortal()); + // remove the planes added by this portal + portalFrustum->removePortalCullingPlanes(p); + } + } } break; case Light::LT_SPOTLIGHT: @@ -236,28 +236,28 @@ namespace Ogre // as a future optimisation. if (lightToPortal.length() <= light->getAttenuationRange()) { - // if portal is quad portal it must be pointing towards the light - if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || - (p->getType() != Portal::PORTAL_TYPE_QUAD)) - { - if (!light->affectsZone(targetZone)) - { - light->addZoneToAffectedZonesList(targetZone); - if (targetZone->getLastVisibleFrame() == frameCount) - { - light->setAffectsVisibleZone(true); - } - // set culling frustum from the portal - portalFrustum->addPortalCullingPlanes(p); - // recurse into the target zone of the portal - p->getTargetZone()->_checkLightAgainstPortals(light, - frameCount, - portalFrustum, - p->getTargetPortal()); - // remove the planes added by this portal - portalFrustum->removePortalCullingPlanes(p); - } - } + // if portal is quad portal it must be pointing towards the light + if ((p->getType() == Portal::PORTAL_TYPE_QUAD && lightToPortal.dotProduct(p->getDerivedDirection()) < 0.0) || + (p->getType() != Portal::PORTAL_TYPE_QUAD)) + { + if (!light->affectsZone(targetZone)) + { + light->addZoneToAffectedZonesList(targetZone); + if (targetZone->getLastVisibleFrame() == frameCount) + { + light->setAffectsVisibleZone(true); + } + // set culling frustum from the portal + portalFrustum->addPortalCullingPlanes(p); + // recurse into the target zone of the portal + p->getTargetZone()->_checkLightAgainstPortals(light, + frameCount, + portalFrustum, + p->getTargetPortal()); + // remove the planes added by this portal + portalFrustum->removePortalCullingPlanes(p); + } + } } break; } @@ -266,226 +266,226 @@ namespace Ogre } } - /** Update the zone data for the portals in the zone - * NOTE: All portal spatial data must be up-to-date before calling this routine. - */ - void DefaultZone::updatePortalsZoneData(void) - { - PortalList transferPortalList; - AntiPortalList transferAntiPortalList; - // check each portal to see if it's intersecting another portal of smaller size - for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) - { - Portal * p = *it; - bool portalNeedUpdate = p->needUpdate(); - - Real pRadius = p->getRadius(); - - // First we check against portals in the SAME zone (and only if they have a - // target zone different from the home zone) - // Here we check only against portals that moved and of smaller size. - - // We do not need to check portal againts previous portals - // since it would have been already checked. - // Hence we start with the next portal after the current portal. - PortalList::iterator it2 = it; - for ( ++it2; it2 != mPortals.end(); ++it2 ) - { - Portal * p2 = (*it2); - - // Skip portal if it doesn't need updating. - // If both portals are not moving, then there's no need to check between them. - if (!portalNeedUpdate && !p2->needUpdate()) continue; - - // Skip portal if it's not pointing to another zone. - if (p2->getTargetZone() == this) continue; - - // Skip portal if it's pointing to the same target zone as this portal points to - if (p2->getTargetZone() == p->getTargetZone()) continue; - - if (pRadius > p2->getRadius()) - { - // Portal#1 is bigger than Portal#2, check for crossing - if (p2->getCurrentHomeZone() != p->getTargetZone() && p2->crossedPortal(p)) - { - // portal#2 crossed portal#1 - flag portal#2 to be moved to portal#1's target zone - p2->setNewHomeZone(p->getTargetZone()); - transferPortalList.push_back(p2); - } - } - else if (pRadius < p2->getRadius()) - { - // Portal #2 is bigger than Portal #1, check for crossing - if (p->getCurrentHomeZone() != p2->getTargetZone() && p->crossedPortal(p2)) - { - // portal#1 crossed portal#2 - flag portal#1 to be moved to portal#2's target zone - p->setNewHomeZone(p2->getTargetZone()); - transferPortalList.push_back(p); - continue; - } - } - } - - // Secondly we check againts the antiportals of this zone. - for (AntiPortalList::iterator ait = mAntiPortals.begin(); ait != mAntiPortals.end(); ++ait) - { - AntiPortal* ap = (*ait); - - // Skip portal if it doesn't need updating. - // If both portals are not moving, then there's no need to check between them. - if (!portalNeedUpdate && !ap->needUpdate()) continue; - - // only check for crossing if AntiPortal smaller than portal. - if (pRadius > ap->getRadius()) - { - // Portal#1 is bigger than AntiPortal, check for crossing - if (ap->crossedPortal(p)) - { - // AntiPortal crossed Portal#1 - flag AntiPortal to be moved to Portal#1's target zone - ap->setNewHomeZone(p->getTargetZone()); - transferAntiPortalList.push_back(ap); - } - } - } - - // Skip portal if it doesn't need updating. - if (!portalNeedUpdate) continue; - - // Thirdly we check against portals in the target zone (and only if that target - // zone is different from the home zone) - PCZone * tzone = p->getTargetZone(); - if (tzone != this) - { - for ( PortalList::iterator it3 = tzone->mPortals.begin(); it3 != tzone->mPortals.end(); ++it3 ) - { - Portal * p3 = (*it3); - // only check against bigger regular portals - if (pRadius < p3->getRadius()) - { - // Portal#3 is bigger than Portal#1, check for crossing - if (p->getCurrentHomeZone() != p3->getTargetZone() && p->crossedPortal(p3)) - { - // Portal#1 crossed Portal#3 - switch target zones for Portal#1 - p->setTargetZone(p3->getTargetZone()); - break; - } - } - } - } - } - // transfer any portals to new zones that have been flagged - for ( PortalList::iterator it = transferPortalList.begin(); it != transferPortalList.end(); ++it ) - { - Portal * p = *it; - if (p->getNewHomeZone() != 0) - { - _removePortal(p); - p->getNewHomeZone()->_addPortal(p); - p->setNewHomeZone(0); - } - } - // transfer any anti portals to new zones that have been flagged - for (AntiPortalList::iterator it = transferAntiPortalList.begin(); it != transferAntiPortalList.end(); ++it) - { - AntiPortal* p = *it; - if (p->getNewHomeZone() != 0) - { - _removeAntiPortal(p); - p->getNewHomeZone()->_addAntiPortal(p); - p->setNewHomeZone(0); - } - } - } - - /** Mark nodes dirty base on moving portals. */ - void DefaultZone::dirtyNodeByMovingPortals(void) - { - // default zone has no space partitioning algo. - // So it's impracticle to do any AABB to find node of interest by portals. - // Hence for this case, we just mark all nodes as dirty as long as there's - // any moving portal within the zone. - for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) - { - if ((*it)->needUpdate()) - { - // Mark all home nodes. - PCZSceneNodeList::iterator it2 = mHomeNodeList.begin(); - while ( it2 != mHomeNodeList.end() ) - { - (*it2)->setMoved(true); - ++it2; - } - - // Mark all visitor nodes. - it2 = mVisitorNodeList.begin(); - while ( it2 != mVisitorNodeList.end() ) - { - (*it2)->setMoved(true); - ++it2; - } - return; - } - } - } + /** Update the zone data for the portals in the zone + * NOTE: All portal spatial data must be up-to-date before calling this routine. + */ + void DefaultZone::updatePortalsZoneData(void) + { + PortalList transferPortalList; + AntiPortalList transferAntiPortalList; + // check each portal to see if it's intersecting another portal of smaller size + for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) + { + Portal * p = *it; + bool portalNeedUpdate = p->needUpdate(); + + Real pRadius = p->getRadius(); + + // First we check against portals in the SAME zone (and only if they have a + // target zone different from the home zone) + // Here we check only against portals that moved and of smaller size. + + // We do not need to check portal againts previous portals + // since it would have been already checked. + // Hence we start with the next portal after the current portal. + PortalList::iterator it2 = it; + for ( ++it2; it2 != mPortals.end(); ++it2 ) + { + Portal * p2 = (*it2); + + // Skip portal if it doesn't need updating. + // If both portals are not moving, then there's no need to check between them. + if (!portalNeedUpdate && !p2->needUpdate()) continue; + + // Skip portal if it's not pointing to another zone. + if (p2->getTargetZone() == this) continue; + + // Skip portal if it's pointing to the same target zone as this portal points to + if (p2->getTargetZone() == p->getTargetZone()) continue; + + if (pRadius > p2->getRadius()) + { + // Portal#1 is bigger than Portal#2, check for crossing + if (p2->getCurrentHomeZone() != p->getTargetZone() && p2->crossedPortal(p)) + { + // portal#2 crossed portal#1 - flag portal#2 to be moved to portal#1's target zone + p2->setNewHomeZone(p->getTargetZone()); + transferPortalList.push_back(p2); + } + } + else if (pRadius < p2->getRadius()) + { + // Portal #2 is bigger than Portal #1, check for crossing + if (p->getCurrentHomeZone() != p2->getTargetZone() && p->crossedPortal(p2)) + { + // portal#1 crossed portal#2 - flag portal#1 to be moved to portal#2's target zone + p->setNewHomeZone(p2->getTargetZone()); + transferPortalList.push_back(p); + continue; + } + } + } + + // Secondly we check againts the antiportals of this zone. + for (AntiPortalList::iterator ait = mAntiPortals.begin(); ait != mAntiPortals.end(); ++ait) + { + AntiPortal* ap = (*ait); + + // Skip portal if it doesn't need updating. + // If both portals are not moving, then there's no need to check between them. + if (!portalNeedUpdate && !ap->needUpdate()) continue; + + // only check for crossing if AntiPortal smaller than portal. + if (pRadius > ap->getRadius()) + { + // Portal#1 is bigger than AntiPortal, check for crossing + if (ap->crossedPortal(p)) + { + // AntiPortal crossed Portal#1 - flag AntiPortal to be moved to Portal#1's target zone + ap->setNewHomeZone(p->getTargetZone()); + transferAntiPortalList.push_back(ap); + } + } + } + + // Skip portal if it doesn't need updating. + if (!portalNeedUpdate) continue; + + // Thirdly we check against portals in the target zone (and only if that target + // zone is different from the home zone) + PCZone * tzone = p->getTargetZone(); + if (tzone != this) + { + for ( PortalList::iterator it3 = tzone->mPortals.begin(); it3 != tzone->mPortals.end(); ++it3 ) + { + Portal * p3 = (*it3); + // only check against bigger regular portals + if (pRadius < p3->getRadius()) + { + // Portal#3 is bigger than Portal#1, check for crossing + if (p->getCurrentHomeZone() != p3->getTargetZone() && p->crossedPortal(p3)) + { + // Portal#1 crossed Portal#3 - switch target zones for Portal#1 + p->setTargetZone(p3->getTargetZone()); + break; + } + } + } + } + } + // transfer any portals to new zones that have been flagged + for ( PortalList::iterator it = transferPortalList.begin(); it != transferPortalList.end(); ++it ) + { + Portal * p = *it; + if (p->getNewHomeZone() != 0) + { + _removePortal(p); + p->getNewHomeZone()->_addPortal(p); + p->setNewHomeZone(0); + } + } + // transfer any anti portals to new zones that have been flagged + for (AntiPortalList::iterator it = transferAntiPortalList.begin(); it != transferAntiPortalList.end(); ++it) + { + AntiPortal* p = *it; + if (p->getNewHomeZone() != 0) + { + _removeAntiPortal(p); + p->getNewHomeZone()->_addAntiPortal(p); + p->setNewHomeZone(0); + } + } + } + + /** Mark nodes dirty base on moving portals. */ + void DefaultZone::dirtyNodeByMovingPortals(void) + { + // default zone has no space partitioning algo. + // So it's impracticle to do any AABB to find node of interest by portals. + // Hence for this case, we just mark all nodes as dirty as long as there's + // any moving portal within the zone. + for ( PortalList::iterator it = mPortals.begin(); it != mPortals.end(); ++it ) + { + if ((*it)->needUpdate()) + { + // Mark all home nodes. + PCZSceneNodeList::iterator it2 = mHomeNodeList.begin(); + while ( it2 != mHomeNodeList.end() ) + { + (*it2)->setMoved(true); + ++it2; + } + + // Mark all visitor nodes. + it2 = mVisitorNodeList.begin(); + while ( it2 != mVisitorNodeList.end() ) + { + (*it2)->setMoved(true); + ++it2; + } + return; + } + } + } /* The following function checks if a node has left it's current home zone. - * This is done by checking each portal in the zone. If the node has crossed - * the portal, then the current zone is no longer the home zone of the node. The - * function then recurses into the connected zones. Once a zone is found where - * the node does NOT cross out through a portal, that zone is the new home zone. - NOTE: For this function to work, the node must start out in the proper zone to - begin with! - */ + * This is done by checking each portal in the zone. If the node has crossed + * the portal, then the current zone is no longer the home zone of the node. The + * function then recurses into the connected zones. Once a zone is found where + * the node does NOT cross out through a portal, that zone is the new home zone. + NOTE: For this function to work, the node must start out in the proper zone to + begin with! + */ PCZone* DefaultZone::updateNodeHomeZone( PCZSceneNode * pczsn, bool allowBackTouches ) { - // default to newHomeZone being the current home zone - PCZone * newHomeZone = pczsn->getHomeZone(); - - // Check all portals of the start zone for crossings! - Portal* portal; - PortalList::iterator pi, piend; - piend = mPortals.end(); - for (pi = mPortals.begin(); pi != piend; pi++) - { - portal = *pi; - - Portal::PortalIntersectResult pir = portal->intersects(pczsn); - switch (pir) - { - default: - case Portal::NO_INTERSECT: // node does not intersect portal - do nothing - case Portal::INTERSECT_NO_CROSS:// node intersects but does not cross portal - do nothing - break; - case Portal::INTERSECT_BACK_NO_CROSS:// node intersects but on the back of the portal - if (allowBackTouches) - { - // node is on wrong side of the portal - fix if we're allowing backside touches - if (portal->getTargetZone() != this && - portal->getTargetZone() != pczsn->getHomeZone()) - { - // set the home zone of the node to the target zone of the portal - pczsn->setHomeZone(portal->getTargetZone()); - // continue checking for portal crossings in the new zone - newHomeZone = portal->getTargetZone()->updateNodeHomeZone(pczsn, false); - } - } - break; - case Portal::INTERSECT_CROSS: - // node intersects and crosses the portal - recurse into that zone as new home zone - if (portal->getTargetZone() != this && - portal->getTargetZone() != pczsn->getHomeZone()) - { - // set the home zone of the node to the target zone of the portal - pczsn->setHomeZone(portal->getTargetZone()); - // continue checking for portal crossings in the new zone - newHomeZone = portal->getTargetZone()->updateNodeHomeZone(pczsn, true); - } - break; - } - } - - // return the new home zone - return newHomeZone; + // default to newHomeZone being the current home zone + PCZone * newHomeZone = pczsn->getHomeZone(); + + // Check all portals of the start zone for crossings! + Portal* portal; + PortalList::iterator pi, piend; + piend = mPortals.end(); + for (pi = mPortals.begin(); pi != piend; pi++) + { + portal = *pi; + + Portal::PortalIntersectResult pir = portal->intersects(pczsn); + switch (pir) + { + default: + case Portal::NO_INTERSECT: // node does not intersect portal - do nothing + case Portal::INTERSECT_NO_CROSS:// node intersects but does not cross portal - do nothing + break; + case Portal::INTERSECT_BACK_NO_CROSS:// node intersects but on the back of the portal + if (allowBackTouches) + { + // node is on wrong side of the portal - fix if we're allowing backside touches + if (portal->getTargetZone() != this && + portal->getTargetZone() != pczsn->getHomeZone()) + { + // set the home zone of the node to the target zone of the portal + pczsn->setHomeZone(portal->getTargetZone()); + // continue checking for portal crossings in the new zone + newHomeZone = portal->getTargetZone()->updateNodeHomeZone(pczsn, false); + } + } + break; + case Portal::INTERSECT_CROSS: + // node intersects and crosses the portal - recurse into that zone as new home zone + if (portal->getTargetZone() != this && + portal->getTargetZone() != pczsn->getHomeZone()) + { + // set the home zone of the node to the target zone of the portal + pczsn->setHomeZone(portal->getTargetZone()); + // continue checking for portal crossings in the new zone + newHomeZone = portal->getTargetZone()->updateNodeHomeZone(pczsn, true); + } + break; + } + } + + // return the new home zone + return newHomeZone; } @@ -493,251 +493,251 @@ namespace Ogre // Recursively walk the zones, adding all visible SceneNodes to the list of visible nodes. */ void DefaultZone::findVisibleNodes(PCZCamera *camera, - NodeList & visibleNodeList, - RenderQueue * queue, - VisibleObjectsBoundsInfo* visibleBounds, - bool onlyShadowCasters, - bool displayNodes, - bool showBoundingBoxes) + NodeList & visibleNodeList, + RenderQueue * queue, + VisibleObjectsBoundsInfo* visibleBounds, + bool onlyShadowCasters, + bool displayNodes, + bool showBoundingBoxes) { //return immediately if nothing is in the zone. - if (mHomeNodeList.empty() && - mVisitorNodeList.empty() && - mPortals.empty()) + if (mHomeNodeList.empty() && + mVisitorNodeList.empty() && + mPortals.empty()) return ; // Else, the zone is automatically assumed to be visible since either - // it is the camera the zone is in, or it was reached because - // a connecting portal was deemed visible to the camera. + // it is the camera the zone is in, or it was reached because + // a connecting portal was deemed visible to the camera. - // enable sky if called to do so for this zone - if (mHasSky) - { - // enable sky - mPCZSM->enableSky(true); - } + // enable sky if called to do so for this zone + if (mHasSky) + { + // enable sky + mPCZSM->enableSky(true); + } - // find visible nodes at home in the zone + // find visible nodes at home in the zone bool vis; PCZSceneNodeList::iterator it = mHomeNodeList.begin(); while ( it != mHomeNodeList.end() ) { - PCZSceneNode * pczsn = *it; + PCZSceneNode * pczsn = *it; // if the scene node is already visible, then we can skip it if (pczsn->getLastVisibleFrame() != mLastVisibleFrame || - pczsn->getLastVisibleFromCamera() != camera) + pczsn->getLastVisibleFromCamera() != camera) { - // for a scene node, check visibility using AABB - vis = camera ->isVisible( pczsn -> _getWorldAABB() ); - if ( vis ) - { - // add it to the list of visible nodes - visibleNodeList.push_back( pczsn ); - // add the node to the render queue - pczsn -> _addToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds ); - // if we are displaying nodes, add the node renderable to the queue - if ( displayNodes ) - { - queue -> addRenderable( pczsn->getDebugRenderable() ); - } - // if the scene manager or the node wants the bounding box shown, add it to the queue - if (pczsn->getShowBoundingBox() || showBoundingBoxes) - { - pczsn->_addBoundingBoxToQueue(queue); - } - // flag the node as being visible this frame - pczsn->setLastVisibleFrame(mLastVisibleFrame); - pczsn->setLastVisibleFromCamera(camera); - } + // for a scene node, check visibility using AABB + vis = camera ->isVisible( pczsn -> _getWorldAABB() ); + if ( vis ) + { + // add it to the list of visible nodes + visibleNodeList.push_back( pczsn ); + // add the node to the render queue + pczsn -> _addToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds ); + // if we are displaying nodes, add the node renderable to the queue + if ( displayNodes ) + { + queue -> addRenderable( pczsn->getDebugRenderable() ); + } + // if the scene manager or the node wants the bounding box shown, add it to the queue + if (pczsn->getShowBoundingBox() || showBoundingBoxes) + { + pczsn->_addBoundingBoxToQueue(queue); + } + // flag the node as being visible this frame + pczsn->setLastVisibleFrame(mLastVisibleFrame); + pczsn->setLastVisibleFromCamera(camera); + } } ++it; } - // find visible visitor nodes + // find visible visitor nodes it = mVisitorNodeList.begin(); while ( it != mVisitorNodeList.end() ) { - PCZSceneNode * pczsn = *it; + PCZSceneNode * pczsn = *it; // if the scene node is already visible, then we can skip it if (pczsn->getLastVisibleFrame() != mLastVisibleFrame || - pczsn->getLastVisibleFromCamera() != camera) + pczsn->getLastVisibleFromCamera() != camera) { - // for a scene node, check visibility using AABB - vis = camera ->isVisible( pczsn -> _getWorldAABB() ); - if ( vis ) - { - // add it to the list of visible nodes - visibleNodeList.push_back( pczsn ); - // add the node to the render queue - pczsn->_addToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds ); - // if we are displaying nodes, add the node renderable to the queue - if ( displayNodes ) - { - queue -> addRenderable( pczsn->getDebugRenderable() ); - } - // if the scene manager or the node wants the bounding box shown, add it to the queue - if (pczsn->getShowBoundingBox() || showBoundingBoxes) - { - pczsn->_addBoundingBoxToQueue(queue); - } - // flag the node as being visible this frame - pczsn->setLastVisibleFrame(mLastVisibleFrame); - pczsn->setLastVisibleFromCamera(camera); - } + // for a scene node, check visibility using AABB + vis = camera ->isVisible( pczsn -> _getWorldAABB() ); + if ( vis ) + { + // add it to the list of visible nodes + visibleNodeList.push_back( pczsn ); + // add the node to the render queue + pczsn->_addToRenderQueue(camera, queue, onlyShadowCasters, visibleBounds ); + // if we are displaying nodes, add the node renderable to the queue + if ( displayNodes ) + { + queue -> addRenderable( pczsn->getDebugRenderable() ); + } + // if the scene manager or the node wants the bounding box shown, add it to the queue + if (pczsn->getShowBoundingBox() || showBoundingBoxes) + { + pczsn->_addBoundingBoxToQueue(queue); + } + // flag the node as being visible this frame + pczsn->setLastVisibleFrame(mLastVisibleFrame); + pczsn->setLastVisibleFromCamera(camera); + } } ++it; } - // Here we merge both portal and antiportal visible to the camera into one list. - // Then we sort them in the order from nearest to furthest from camera. - PortalBaseList sortedPortalList; - for (AntiPortalList::iterator iter = mAntiPortals.begin(); iter != mAntiPortals.end(); ++iter) - { - AntiPortal* portal = *iter; - if (camera->isVisible(portal)) - { - sortedPortalList.push_back(portal); - } - } - for (PortalList::iterator iter = mPortals.begin(); iter != mPortals.end(); ++iter) - { - Portal* portal = *iter; - if (camera->isVisible(portal)) - { - sortedPortalList.push_back(portal); - } - } - const Vector3& cameraOrigin(camera->getDerivedPosition()); - std::sort(sortedPortalList.begin(), sortedPortalList.end(), - PortalSortDistance(cameraOrigin)); - - // create a standalone frustum for anti portal use. - // we're doing this instead of using camera because we don't need - // to do camera frustum check again. - PCZFrustum antiPortalFrustum; - antiPortalFrustum.setOrigin(cameraOrigin); - antiPortalFrustum.setProjectionType(camera->getProjectionType()); - - // now we do culling check and remove hidden portals. - // whenever we get a portal in the main loop, we can be sure that it is not - // occluded by AntiPortal. So we do traversal right there and then. - // This is because the portal list has been sorted. - size_t sortedPortalListCount = sortedPortalList.size(); - for (size_t i = 0; i < sortedPortalListCount; ++i) - { - PortalBase* portalBase = sortedPortalList[i]; - if (!portalBase) continue; // skip removed portal. - - if (portalBase->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG) - { - Portal* portal = static_cast(portalBase); - // portal is visible. Add the portal as extra culling planes to camera - int planes_added = camera->addPortalCullingPlanes(portal); - // tell target zone it's visible this frame - portal->getTargetZone()->setLastVisibleFrame(mLastVisibleFrame); - portal->getTargetZone()->setLastVisibleFromCamera(camera); - // recurse into the connected zone - portal->getTargetZone()->findVisibleNodes(camera, - visibleNodeList, - queue, - visibleBounds, - onlyShadowCasters, - displayNodes, - showBoundingBoxes); - if (planes_added > 0) - { - // Then remove the extra culling planes added before going to the next portal in the list. - camera->removePortalCullingPlanes(portal); - } - } - else if (i < sortedPortalListCount) // skip antiportal test if it is the last item in the list. - { - // this is an anti portal. So we use it to test preceding portals in the list. - AntiPortal* antiPortal = static_cast(portalBase); - int planes_added = antiPortalFrustum.addPortalCullingPlanes(antiPortal); - - for (size_t j = i + 1; j < sortedPortalListCount; ++j) - { - PortalBase* otherPortal = sortedPortalList[j]; - // Since this is an antiportal, we are doing the inverse of the test. - // Here if the portal is fully visible in the anti portal fustrum, it means it's hidden. - if (otherPortal && antiPortalFrustum.isFullyVisible(otherPortal)) - sortedPortalList[j] = NULL; - } - - if (planes_added > 0) - { - // Then remove the extra culling planes added before going to the next portal in the list. - antiPortalFrustum.removePortalCullingPlanes(antiPortal); - } - } - } - } - - // --- find nodes which intersect various types of BV's --- - void DefaultZone::_findNodes( const AxisAlignedBox &t, - PCZSceneNodeList &list, - PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ) - { - // if this zone has an enclosure, check against the enclosure AABB first - if (mEnclosureNode) - { - if (!mEnclosureNode->_getWorldAABB().intersects(t)) - { - // AABB of zone does not intersect t, just return. - return; - } - } - - // check nodes at home in this zone - PCZSceneNodeList::iterator it = mHomeNodeList.begin(); - while ( it != mHomeNodeList.end() ) - { - PCZSceneNode * pczsn = *it; - if ( pczsn != exclude ) - { - // make sure node is not already in the list (might have been added in another - // zone it was visiting) - PCZSceneNodeList::iterator it2 = list.find(pczsn); - if (it2 == list.end()) - { - bool nsect = t.intersects( pczsn -> _getWorldAABB() ); - if ( nsect ) - { - list.insert( pczsn ); - } - } - } - ++it; - } - - if (includeVisitors) - { - // check visitor nodes - PCZSceneNodeList::iterator iter = mVisitorNodeList.begin(); - while ( iter != mVisitorNodeList.end() ) - { - PCZSceneNode * pczsn = *iter; - if ( pczsn != exclude ) - { - // make sure node is not already in the list (might have been added in another - // zone it was visiting) - PCZSceneNodeList::iterator it2 = list.find(pczsn); - if (it2 == list.end()) - { - bool nsect = t.intersects( pczsn -> _getWorldAABB() ); - if ( nsect ) - { - list.insert( pczsn ); - } - } - } - ++iter; - } - } + // Here we merge both portal and antiportal visible to the camera into one list. + // Then we sort them in the order from nearest to furthest from camera. + PortalBaseList sortedPortalList; + for (AntiPortalList::iterator iter = mAntiPortals.begin(); iter != mAntiPortals.end(); ++iter) + { + AntiPortal* portal = *iter; + if (camera->isVisible(portal)) + { + sortedPortalList.push_back(portal); + } + } + for (PortalList::iterator iter = mPortals.begin(); iter != mPortals.end(); ++iter) + { + Portal* portal = *iter; + if (camera->isVisible(portal)) + { + sortedPortalList.push_back(portal); + } + } + const Vector3& cameraOrigin(camera->getDerivedPosition()); + std::sort(sortedPortalList.begin(), sortedPortalList.end(), + PortalSortDistance(cameraOrigin)); + + // create a standalone frustum for anti portal use. + // we're doing this instead of using camera because we don't need + // to do camera frustum check again. + PCZFrustum antiPortalFrustum; + antiPortalFrustum.setOrigin(cameraOrigin); + antiPortalFrustum.setProjectionType(camera->getProjectionType()); + + // now we do culling check and remove hidden portals. + // whenever we get a portal in the main loop, we can be sure that it is not + // occluded by AntiPortal. So we do traversal right there and then. + // This is because the portal list has been sorted. + size_t sortedPortalListCount = sortedPortalList.size(); + for (size_t i = 0; i < sortedPortalListCount; ++i) + { + PortalBase* portalBase = sortedPortalList[i]; + if (!portalBase) continue; // skip removed portal. + + if (portalBase->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG) + { + Portal* portal = static_cast(portalBase); + // portal is visible. Add the portal as extra culling planes to camera + int planes_added = camera->addPortalCullingPlanes(portal); + // tell target zone it's visible this frame + portal->getTargetZone()->setLastVisibleFrame(mLastVisibleFrame); + portal->getTargetZone()->setLastVisibleFromCamera(camera); + // recurse into the connected zone + portal->getTargetZone()->findVisibleNodes(camera, + visibleNodeList, + queue, + visibleBounds, + onlyShadowCasters, + displayNodes, + showBoundingBoxes); + if (planes_added > 0) + { + // Then remove the extra culling planes added before going to the next portal in the list. + camera->removePortalCullingPlanes(portal); + } + } + else if (i < sortedPortalListCount) // skip antiportal test if it is the last item in the list. + { + // this is an anti portal. So we use it to test preceding portals in the list. + AntiPortal* antiPortal = static_cast(portalBase); + int planes_added = antiPortalFrustum.addPortalCullingPlanes(antiPortal); + + for (size_t j = i + 1; j < sortedPortalListCount; ++j) + { + PortalBase* otherPortal = sortedPortalList[j]; + // Since this is an antiportal, we are doing the inverse of the test. + // Here if the portal is fully visible in the anti portal fustrum, it means it's hidden. + if (otherPortal && antiPortalFrustum.isFullyVisible(otherPortal)) + sortedPortalList[j] = NULL; + } + + if (planes_added > 0) + { + // Then remove the extra culling planes added before going to the next portal in the list. + antiPortalFrustum.removePortalCullingPlanes(antiPortal); + } + } + } + } + + // --- find nodes which intersect various types of BV's --- + void DefaultZone::_findNodes( const AxisAlignedBox &t, + PCZSceneNodeList &list, + PortalList &visitedPortals, + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ) + { + // if this zone has an enclosure, check against the enclosure AABB first + if (mEnclosureNode) + { + if (!mEnclosureNode->_getWorldAABB().intersects(t)) + { + // AABB of zone does not intersect t, just return. + return; + } + } + + // check nodes at home in this zone + PCZSceneNodeList::iterator it = mHomeNodeList.begin(); + while ( it != mHomeNodeList.end() ) + { + PCZSceneNode * pczsn = *it; + if ( pczsn != exclude ) + { + // make sure node is not already in the list (might have been added in another + // zone it was visiting) + PCZSceneNodeList::iterator it2 = list.find(pczsn); + if (it2 == list.end()) + { + bool nsect = t.intersects( pczsn -> _getWorldAABB() ); + if ( nsect ) + { + list.insert( pczsn ); + } + } + } + ++it; + } + + if (includeVisitors) + { + // check visitor nodes + PCZSceneNodeList::iterator iter = mVisitorNodeList.begin(); + while ( iter != mVisitorNodeList.end() ) + { + PCZSceneNode * pczsn = *iter; + if ( pczsn != exclude ) + { + // make sure node is not already in the list (might have been added in another + // zone it was visiting) + PCZSceneNodeList::iterator it2 = list.find(pczsn); + if (it2 == list.end()) + { + bool nsect = t.intersects( pczsn -> _getWorldAABB() ); + if ( nsect ) + { + list.insert( pczsn ); + } + } + } + ++iter; + } + } // if asked to, recurse through portals if (recurseThruPortals) @@ -746,349 +746,349 @@ namespace Ogre while ( pit != mPortals.end() ) { Portal * portal = *pit; - // check portal versus bounding box - if (portal->intersects(t)) - { + // check portal versus bounding box + if (portal->intersects(t)) + { // make sure portal hasn't already been recursed through PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); if (pit2 == visitedPortals.end()) { // save portal to the visitedPortals list visitedPortals.push_front(portal); - // recurse into the connected zone - portal->getTargetZone()->_findNodes(t, - list, + // recurse into the connected zone + portal->getTargetZone()->_findNodes(t, + list, visitedPortals, - includeVisitors, - recurseThruPortals, - exclude); + includeVisitors, + recurseThruPortals, + exclude); } - } - pit++; - } + } + pit++; + } } } void DefaultZone::_findNodes(const Sphere &t, - PCZSceneNodeList &list, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ) + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ) { - // if this zone has an enclosure, check against the enclosure AABB first - if (mEnclosureNode) - { - if (!mEnclosureNode->_getWorldAABB().intersects(t)) - { - // AABB of zone does not intersect t, just return. - return; - } - } - - // check nodes at home in this zone - PCZSceneNodeList::iterator it = mHomeNodeList.begin(); - while ( it != mHomeNodeList.end() ) - { - PCZSceneNode * pczsn = *it; - if ( pczsn != exclude ) - { - // make sure node is not already in the list (might have been added in another - // zone it was visiting) - PCZSceneNodeList::iterator it2 = list.find(pczsn); - if (it2 == list.end()) - { - bool nsect = t.intersects( pczsn -> _getWorldAABB() ); - if ( nsect ) - { - list.insert( pczsn ); - } - } - } - ++it; - } - - if (includeVisitors) - { - // check visitor nodes - PCZSceneNodeList::iterator iter = mVisitorNodeList.begin(); - while ( iter != mVisitorNodeList.end() ) - { - PCZSceneNode * pczsn = *iter; - if ( pczsn != exclude ) - { - // make sure node is not already in the list (might have been added in another - // zone it was visiting) - PCZSceneNodeList::iterator it2 = list.find(pczsn); - if (it2 == list.end()) - { - bool nsect = t.intersects( pczsn -> _getWorldAABB() ); - if ( nsect ) - { - list.insert( pczsn ); - } - } - } - ++iter; - } - } - - // if asked to, recurse through portals - if (recurseThruPortals) - { - PortalList::iterator pit = mPortals.begin(); - while ( pit != mPortals.end() ) - { - Portal * portal = *pit; - // check portal versus boundign box - if (portal->intersects(t)) - { - // make sure portal hasn't already been recursed through - PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); - if (pit2 == visitedPortals.end()) - { - // save portal to the visitedPortals list - visitedPortals.push_front(portal); - // recurse into the connected zone - portal->getTargetZone()->_findNodes(t, - list, - visitedPortals, - includeVisitors, - recurseThruPortals, - exclude); - } - } - pit++; - } - } - - } + // if this zone has an enclosure, check against the enclosure AABB first + if (mEnclosureNode) + { + if (!mEnclosureNode->_getWorldAABB().intersects(t)) + { + // AABB of zone does not intersect t, just return. + return; + } + } + + // check nodes at home in this zone + PCZSceneNodeList::iterator it = mHomeNodeList.begin(); + while ( it != mHomeNodeList.end() ) + { + PCZSceneNode * pczsn = *it; + if ( pczsn != exclude ) + { + // make sure node is not already in the list (might have been added in another + // zone it was visiting) + PCZSceneNodeList::iterator it2 = list.find(pczsn); + if (it2 == list.end()) + { + bool nsect = t.intersects( pczsn -> _getWorldAABB() ); + if ( nsect ) + { + list.insert( pczsn ); + } + } + } + ++it; + } + + if (includeVisitors) + { + // check visitor nodes + PCZSceneNodeList::iterator iter = mVisitorNodeList.begin(); + while ( iter != mVisitorNodeList.end() ) + { + PCZSceneNode * pczsn = *iter; + if ( pczsn != exclude ) + { + // make sure node is not already in the list (might have been added in another + // zone it was visiting) + PCZSceneNodeList::iterator it2 = list.find(pczsn); + if (it2 == list.end()) + { + bool nsect = t.intersects( pczsn -> _getWorldAABB() ); + if ( nsect ) + { + list.insert( pczsn ); + } + } + } + ++iter; + } + } + + // if asked to, recurse through portals + if (recurseThruPortals) + { + PortalList::iterator pit = mPortals.begin(); + while ( pit != mPortals.end() ) + { + Portal * portal = *pit; + // check portal versus boundign box + if (portal->intersects(t)) + { + // make sure portal hasn't already been recursed through + PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); + if (pit2 == visitedPortals.end()) + { + // save portal to the visitedPortals list + visitedPortals.push_front(portal); + // recurse into the connected zone + portal->getTargetZone()->_findNodes(t, + list, + visitedPortals, + includeVisitors, + recurseThruPortals, + exclude); + } + } + pit++; + } + } + + } void DefaultZone::_findNodes( const PlaneBoundedVolume &t, - PCZSceneNodeList &list, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude) + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude) { - // if this zone has an enclosure, check against the enclosure AABB first - if (mEnclosureNode) - { - if (!t.intersects(mEnclosureNode->_getWorldAABB())) - { - // AABB of zone does not intersect t, just return. - return; - } - } - - // check nodes at home in this zone - PCZSceneNodeList::iterator it = mHomeNodeList.begin(); - while ( it != mHomeNodeList.end() ) - { - PCZSceneNode * pczsn = *it; - if ( pczsn != exclude ) - { - // make sure node is not already in the list (might have been added in another - // zone it was visiting) - PCZSceneNodeList::iterator it2 = list.find(pczsn); - if (it2 == list.end()) - { - bool nsect = t.intersects( pczsn -> _getWorldAABB() ); - if ( nsect ) - { - list.insert( pczsn ); - } - } - } - ++it; - } - - if (includeVisitors) - { - // check visitor nodes - PCZSceneNodeList::iterator iter = mVisitorNodeList.begin(); - while ( iter != mVisitorNodeList.end() ) - { - PCZSceneNode * pczsn = *iter; - if ( pczsn != exclude ) - { - // make sure node is not already in the list (might have been added in another - // zone it was visiting) - PCZSceneNodeList::iterator it2 = list.find(pczsn); - if (it2 == list.end()) - { - bool nsect = t.intersects( pczsn -> _getWorldAABB() ); - if ( nsect ) - { - list.insert( pczsn ); - } - } - } - ++iter; - } - } - - // if asked to, recurse through portals - if (recurseThruPortals) - { - PortalList::iterator pit = mPortals.begin(); - while ( pit != mPortals.end() ) - { - Portal * portal = *pit; - // check portal versus boundign box - if (portal->intersects(t)) - { - // make sure portal hasn't already been recursed through - PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); - if (pit2 == visitedPortals.end()) - { - // save portal to the visitedPortals list - visitedPortals.push_front(portal); - // recurse into the connected zone - portal->getTargetZone()->_findNodes(t, - list, - visitedPortals, - includeVisitors, - recurseThruPortals, - exclude); - } - } - pit++; - } - } - - } + // if this zone has an enclosure, check against the enclosure AABB first + if (mEnclosureNode) + { + if (!t.intersects(mEnclosureNode->_getWorldAABB())) + { + // AABB of zone does not intersect t, just return. + return; + } + } + + // check nodes at home in this zone + PCZSceneNodeList::iterator it = mHomeNodeList.begin(); + while ( it != mHomeNodeList.end() ) + { + PCZSceneNode * pczsn = *it; + if ( pczsn != exclude ) + { + // make sure node is not already in the list (might have been added in another + // zone it was visiting) + PCZSceneNodeList::iterator it2 = list.find(pczsn); + if (it2 == list.end()) + { + bool nsect = t.intersects( pczsn -> _getWorldAABB() ); + if ( nsect ) + { + list.insert( pczsn ); + } + } + } + ++it; + } + + if (includeVisitors) + { + // check visitor nodes + PCZSceneNodeList::iterator iter = mVisitorNodeList.begin(); + while ( iter != mVisitorNodeList.end() ) + { + PCZSceneNode * pczsn = *iter; + if ( pczsn != exclude ) + { + // make sure node is not already in the list (might have been added in another + // zone it was visiting) + PCZSceneNodeList::iterator it2 = list.find(pczsn); + if (it2 == list.end()) + { + bool nsect = t.intersects( pczsn -> _getWorldAABB() ); + if ( nsect ) + { + list.insert( pczsn ); + } + } + } + ++iter; + } + } + + // if asked to, recurse through portals + if (recurseThruPortals) + { + PortalList::iterator pit = mPortals.begin(); + while ( pit != mPortals.end() ) + { + Portal * portal = *pit; + // check portal versus boundign box + if (portal->intersects(t)) + { + // make sure portal hasn't already been recursed through + PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); + if (pit2 == visitedPortals.end()) + { + // save portal to the visitedPortals list + visitedPortals.push_front(portal); + // recurse into the connected zone + portal->getTargetZone()->_findNodes(t, + list, + visitedPortals, + includeVisitors, + recurseThruPortals, + exclude); + } + } + pit++; + } + } + + } void DefaultZone::_findNodes( const Ray &t, - PCZSceneNodeList &list, + PCZSceneNodeList &list, PortalList &visitedPortals, - bool includeVisitors, - bool recurseThruPortals, - PCZSceneNode *exclude ) + bool includeVisitors, + bool recurseThruPortals, + PCZSceneNode *exclude ) { - // if this zone has an enclosure, check against the enclosure AABB first - if (mEnclosureNode) - { - std::pair nsect = t.intersects(mEnclosureNode->_getWorldAABB()); - if (!nsect.first) - { - // AABB of zone does not intersect t, just return. - return; - } - } - - // check nodes at home in this zone - PCZSceneNodeList::iterator it = mHomeNodeList.begin(); - while ( it != mHomeNodeList.end() ) - { - PCZSceneNode * pczsn = *it; - if ( pczsn != exclude ) - { - // make sure node is not already in the list (might have been added in another - // zone it was visiting) - PCZSceneNodeList::iterator it2 = list.find(pczsn); - if (it2 == list.end()) - { - std::pair nsect = t.intersects( pczsn -> _getWorldAABB() ); - if ( nsect.first ) - { - list.insert( pczsn ); - } - } - } - ++it; - } - - if (includeVisitors) - { - // check visitor nodes - PCZSceneNodeList::iterator iter = mVisitorNodeList.begin(); - while ( iter != mVisitorNodeList.end() ) - { - PCZSceneNode * pczsn = *iter; - if ( pczsn != exclude ) - { - // make sure node is not already in the list (might have been added in another - // zone it was visiting) - PCZSceneNodeList::iterator it2 = list.find(pczsn); - if (it2 == list.end()) - { - std::pair nsect = t.intersects( pczsn -> _getWorldAABB() ); - if ( nsect.first ) - { - list.insert( pczsn ); - } - } - } - ++iter; - } - } - - // if asked to, recurse through portals - if (recurseThruPortals) - { - PortalList::iterator pit = mPortals.begin(); - while ( pit != mPortals.end() ) - { - Portal * portal = *pit; - // check portal versus bounding box - if (portal->intersects(t)) - { - // make sure portal hasn't already been recursed through - PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); - if (pit2 == visitedPortals.end()) - { - // save portal to the visitedPortals list - visitedPortals.push_front(portal); - // recurse into the connected zone - portal->getTargetZone()->_findNodes(t, - list, - visitedPortals, - includeVisitors, - recurseThruPortals, - exclude); - } - } - pit++; - } - } - - } - - /* Set option for the zone */ - bool DefaultZone::setOption( const String &name, const void *value ) - { - return false; - } - - /** called when the scene manager creates a camera because - some zone managers (like TerrainZone) need the camera info. - */ - void DefaultZone::notifyCameraCreated( Camera* c ) - { - } - //------------------------------------------------------------------------- - void DefaultZone::notifyWorldGeometryRenderQueue(uint8 qid) - { - } - //------------------------------------------------------------------------- + // if this zone has an enclosure, check against the enclosure AABB first + if (mEnclosureNode) + { + std::pair nsect = t.intersects(mEnclosureNode->_getWorldAABB()); + if (!nsect.first) + { + // AABB of zone does not intersect t, just return. + return; + } + } + + // check nodes at home in this zone + PCZSceneNodeList::iterator it = mHomeNodeList.begin(); + while ( it != mHomeNodeList.end() ) + { + PCZSceneNode * pczsn = *it; + if ( pczsn != exclude ) + { + // make sure node is not already in the list (might have been added in another + // zone it was visiting) + PCZSceneNodeList::iterator it2 = list.find(pczsn); + if (it2 == list.end()) + { + std::pair nsect = t.intersects( pczsn -> _getWorldAABB() ); + if ( nsect.first ) + { + list.insert( pczsn ); + } + } + } + ++it; + } + + if (includeVisitors) + { + // check visitor nodes + PCZSceneNodeList::iterator iter = mVisitorNodeList.begin(); + while ( iter != mVisitorNodeList.end() ) + { + PCZSceneNode * pczsn = *iter; + if ( pczsn != exclude ) + { + // make sure node is not already in the list (might have been added in another + // zone it was visiting) + PCZSceneNodeList::iterator it2 = list.find(pczsn); + if (it2 == list.end()) + { + std::pair nsect = t.intersects( pczsn -> _getWorldAABB() ); + if ( nsect.first ) + { + list.insert( pczsn ); + } + } + } + ++iter; + } + } + + // if asked to, recurse through portals + if (recurseThruPortals) + { + PortalList::iterator pit = mPortals.begin(); + while ( pit != mPortals.end() ) + { + Portal * portal = *pit; + // check portal versus bounding box + if (portal->intersects(t)) + { + // make sure portal hasn't already been recursed through + PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal); + if (pit2 == visitedPortals.end()) + { + // save portal to the visitedPortals list + visitedPortals.push_front(portal); + // recurse into the connected zone + portal->getTargetZone()->_findNodes(t, + list, + visitedPortals, + includeVisitors, + recurseThruPortals, + exclude); + } + } + pit++; + } + } + + } + + /* Set option for the zone */ + bool DefaultZone::setOption( const String &name, const void *value ) + { + return false; + } + + /** called when the scene manager creates a camera because + some zone managers (like TerrainZone) need the camera info. + */ + void DefaultZone::notifyCameraCreated( Camera* c ) + { + } + //------------------------------------------------------------------------- + void DefaultZone::notifyWorldGeometryRenderQueue(uint8 qid) + { + } + //------------------------------------------------------------------------- void DefaultZone::notifyBeginRenderScene(void) { - } - //------------------------------------------------------------------------- - void DefaultZone::setZoneGeometry(const String &filename, PCZSceneNode * parentNode) - { - String entityName, nodeName; - entityName = this->getName() + "_entity"; - nodeName = this->getName() + "_Node"; - Entity *ent = mPCZSM->createEntity(entityName , filename ); - // create a node for the entity - PCZSceneNode * node; - node = (PCZSceneNode*)(parentNode->createChildSceneNode(nodeName)); - // attach the entity to the node - node->attachObject(ent); - // set the node as the enclosure node - setEnclosureNode(node); - } + } + //------------------------------------------------------------------------- + void DefaultZone::setZoneGeometry(const String &filename, PCZSceneNode * parentNode) + { + String entityName, nodeName; + entityName = this->getName() + "_entity"; + nodeName = this->getName() + "_Node"; + Entity *ent = mPCZSM->createEntity(entityName , filename ); + // create a node for the entity + PCZSceneNode * node; + node = (PCZSceneNode*)(parentNode->createChildSceneNode(nodeName)); + // attach the entity to the node + node->attachObject(ent); + // set the node as the enclosure node + setEnclosureNode(node); + } } diff --git a/PlugIns/PCZSceneManager/src/OgrePCPlane.cpp b/PlugIns/PCZSceneManager/src/OgrePCPlane.cpp index 9c1d9b613a9..00d3f3985be 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCPlane.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCPlane.cpp @@ -41,11 +41,11 @@ namespace Ogre { mPortal = 0; } - PCPlane::PCPlane(const Plane & plane) - : Plane(plane) - { - mPortal = 0; - } + PCPlane::PCPlane(const Plane & plane) + : Plane(plane) + { + mPortal = 0; + } PCPlane::PCPlane(const Vector3& rkNormal, const Vector3& rkPoint) : Plane(rkNormal, rkPoint) { @@ -56,16 +56,16 @@ namespace Ogre { mPortal = 0; } - void PCPlane::setFromOgrePlane(Plane & ogrePlane) - { - d = ogrePlane.d; - normal = ogrePlane.normal; - mPortal = 0; - } + void PCPlane::setFromOgrePlane(Plane & ogrePlane) + { + d = ogrePlane.d; + normal = ogrePlane.normal; + mPortal = 0; + } PCPlane::~PCPlane() { - mPortal = 0; + mPortal = 0; } } diff --git a/PlugIns/PCZSceneManager/src/OgrePCZCamera.cpp b/PlugIns/PCZSceneManager/src/OgrePCZCamera.cpp index 7f29780f758..f7071e05e9d 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCZCamera.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCZCamera.cpp @@ -41,7 +41,7 @@ namespace Ogre { PCZCamera::PCZCamera( const String& name, SceneManager* sm ) : Camera( name, sm ) { - mBox.setExtents(-0.1, -0.1, -0.1, 0.1, 0.1, 0.1); + mBox.setExtents(-0.1, -0.1, -0.1, 0.1, 0.1, 0.1); mExtraCullingFrustum.setUseOriginPlane(true); } @@ -49,10 +49,10 @@ namespace Ogre { } - const AxisAlignedBox& PCZCamera::getBoundingBox(void) const - { - return mBox; - } + const AxisAlignedBox& PCZCamera::getBoundingBox(void) const + { + return mBox; + } // this version checks against extra culling planes bool PCZCamera::isVisible( const AxisAlignedBox &bound, FrustumPlane *culledBy) const @@ -64,7 +64,7 @@ namespace Ogre // Make any pending updates to the calculated frustum planes updateFrustumPlanes(); - // check extra culling planes + // check extra culling planes bool extraResults; extraResults = mExtraCullingFrustum.isVisible(bound); if (!extraResults) @@ -72,50 +72,50 @@ namespace Ogre return false; } - // check "regular" camera frustum - bool regcamresults = Camera::isVisible(bound, culledBy); + // check "regular" camera frustum + bool regcamresults = Camera::isVisible(bound, culledBy); - if (!regcamresults) - { - // culled by regular culling planes - return regcamresults; - } + if (!regcamresults) + { + // culled by regular culling planes + return regcamresults; + } - return true; + return true; } - /* A 'more detailed' check for visibility of an AAB. This function returns - none, partial, or full for visibility of the box. This is useful for - stuff like Octree leaf culling */ - PCZCamera::Visibility PCZCamera::getVisibility( const AxisAlignedBox &bound ) - { - - // Null boxes always invisible - if ( bound.isNull() ) - return NONE; - - // Get centre of the box - Vector3 centre = bound.getCenter(); - // Get the half-size of the box - Vector3 halfSize = bound.getHalfSize(); - - bool all_inside = true; - - for ( int plane = 0; plane < 6; ++plane ) - { - - // Skip far plane if infinite view frustum - if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0) - continue; - - // This updates frustum planes and deals with cull frustum - Plane::Side side = getFrustumPlane(plane).getSide(centre, halfSize); - if(side == Plane::NEGATIVE_SIDE) return NONE; - // We can't return now as the box could be later on the negative side of a plane. - if(side == Plane::BOTH_SIDE) - all_inside = false; - } + /* A 'more detailed' check for visibility of an AAB. This function returns + none, partial, or full for visibility of the box. This is useful for + stuff like Octree leaf culling */ + PCZCamera::Visibility PCZCamera::getVisibility( const AxisAlignedBox &bound ) + { + + // Null boxes always invisible + if ( bound.isNull() ) + return NONE; + + // Get centre of the box + Vector3 centre = bound.getCenter(); + // Get the half-size of the box + Vector3 halfSize = bound.getHalfSize(); + + bool all_inside = true; + + for ( int plane = 0; plane < 6; ++plane ) + { + + // Skip far plane if infinite view frustum + if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0) + continue; + + // This updates frustum planes and deals with cull frustum + Plane::Side side = getFrustumPlane(plane).getSide(centre, halfSize); + if(side == Plane::NEGATIVE_SIDE) return NONE; + // We can't return now as the box could be later on the negative side of a plane. + if(side == Plane::BOTH_SIDE) + all_inside = false; + } switch(mExtraCullingFrustum.getVisibility(bound)) { @@ -127,20 +127,20 @@ namespace Ogre break; } - if ( all_inside ) - return FULL; - else - return PARTIAL; + if ( all_inside ) + return FULL; + else + return PARTIAL; - } + } /* isVisible() function for portals */ // NOTE: Everything needs to be updated spatially before this function is // called including portal corners, frustum planes, etc. bool PCZCamera::isVisible(PortalBase* portal, FrustumPlane* culledBy) const { - // if portal isn't enabled, it's not visible - if (!portal->getEnabled()) return false; + // if portal isn't enabled, it's not visible + if (!portal->getEnabled()) return false; // check the extra frustum first if (!mExtraCullingFrustum.isVisible(portal)) @@ -148,40 +148,40 @@ namespace Ogre return false; } - // if portal is of type AABB or Sphere, then use simple bound check against planes - if (portal->getType() == PortalBase::PORTAL_TYPE_AABB) - { - AxisAlignedBox aabb; - aabb.setExtents(portal->getDerivedCorner(0), portal->getDerivedCorner(1)); - return Camera::isVisible(aabb, culledBy); - } - else if (portal->getType() == PortalBase::PORTAL_TYPE_SPHERE) - { - return Camera::isVisible(portal->getDerivedSphere(), culledBy); - } - - // only do this check if it's a portal. (anti portal doesn't care about facing) - if (portal->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG) - { - // check if the portal norm is facing the camera - Vector3 cameraToPortal = portal->getDerivedCP() - getDerivedPosition(); - Vector3 portalDirection = portal->getDerivedDirection(); - Real dotProduct = cameraToPortal.dotProduct(portalDirection); - if ( dotProduct > 0 ) - { - // portal is faced away from camera - return false; - } - } + // if portal is of type AABB or Sphere, then use simple bound check against planes + if (portal->getType() == PortalBase::PORTAL_TYPE_AABB) + { + AxisAlignedBox aabb; + aabb.setExtents(portal->getDerivedCorner(0), portal->getDerivedCorner(1)); + return Camera::isVisible(aabb, culledBy); + } + else if (portal->getType() == PortalBase::PORTAL_TYPE_SPHERE) + { + return Camera::isVisible(portal->getDerivedSphere(), culledBy); + } + + // only do this check if it's a portal. (anti portal doesn't care about facing) + if (portal->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG) + { + // check if the portal norm is facing the camera + Vector3 cameraToPortal = portal->getDerivedCP() - getDerivedPosition(); + Vector3 portalDirection = portal->getDerivedDirection(); + Real dotProduct = cameraToPortal.dotProduct(portalDirection); + if ( dotProduct > 0 ) + { + // portal is faced away from camera + return false; + } + } // check against regular frustum planes bool visible_flag; - if (mCullFrustum) - { + if (mCullFrustum) + { // For each frustum plane, see if all points are on the negative side // If so, object is not visible - // NOTE: We skip the NEAR plane (plane #0) because Portals need to - // be visible no matter how close you get to them. + // NOTE: We skip the NEAR plane (plane #0) because Portals need to + // be visible no matter how close you get to them. for (int plane = 1; plane < 6; ++plane) { @@ -198,7 +198,7 @@ namespace Ogre if (side != Plane::NEGATIVE_SIDE) { visible_flag = true; - break; + break; } } // if the visible_flag is still false, then this plane @@ -211,19 +211,19 @@ namespace Ogre return false; } } - } - else - { + } + else + { // Make any pending updates to the calculated frustum planes Frustum::updateFrustumPlanes(); // For each frustum plane, see if all points are on the negative side // If so, object is not visible - // NOTE: We skip the NEAR plane (plane #0) because Portals need to - // be visible no matter how close you get to them. - // BUGBUG: This can cause a false positive situation when a portal is - // behind the camera but close. This could be fixed by having another - // culling plane at the camera location with normal same as camera direction. + // NOTE: We skip the NEAR plane (plane #0) because Portals need to + // be visible no matter how close you get to them. + // BUGBUG: This can cause a false positive situation when a portal is + // behind the camera but close. This could be fixed by having another + // culling plane at the camera location with normal same as camera direction. for (int plane = 1; plane < 6; ++plane) { // set the visible flag to false @@ -239,7 +239,7 @@ namespace Ogre if (side != Plane::NEGATIVE_SIDE) { visible_flag = true; - break; + break; } } // if the visible_flag is still false, then this plane @@ -252,57 +252,57 @@ namespace Ogre return false; } } - } + } // no plane culled all the portal points and the norm // was facing the camera, so this portal is visible return true; } - /// Sets the type of projection to use (orthographic or perspective). - void PCZCamera::setProjectionType(ProjectionType pt) - { - mExtraCullingFrustum.setProjectionType(pt); - Camera::setProjectionType(pt); - } + /// Sets the type of projection to use (orthographic or perspective). + void PCZCamera::setProjectionType(ProjectionType pt) + { + mExtraCullingFrustum.setProjectionType(pt); + Camera::setProjectionType(pt); + } /* Update function (currently used for making sure the origin stuff for the extra culling frustum is up to date */ void PCZCamera::update(void) { // make sure the extra culling frustum origin stuff is up to date - if (mProjType == PT_PERSPECTIVE) - //if (!mCustomViewMatrix) - { - mExtraCullingFrustum.setUseOriginPlane(true); - mExtraCullingFrustum.setOrigin(getDerivedPosition()); - mExtraCullingFrustum.setOriginPlane(getDerivedDirection(), getDerivedPosition()); - } - else - { - // In ortho mode, we don't want to cull things behind camera. - // This helps for back casting which is useful for texture shadow projection on directional light. - mExtraCullingFrustum.setUseOriginPlane(false); - } + if (mProjType == PT_PERSPECTIVE) + //if (!mCustomViewMatrix) + { + mExtraCullingFrustum.setUseOriginPlane(true); + mExtraCullingFrustum.setOrigin(getDerivedPosition()); + mExtraCullingFrustum.setOriginPlane(getDerivedDirection(), getDerivedPosition()); + } + else + { + // In ortho mode, we don't want to cull things behind camera. + // This helps for back casting which is useful for texture shadow projection on directional light. + mExtraCullingFrustum.setUseOriginPlane(false); + } } // calculate extra culling planes from portal and camera // origin and add to list of extra culling planes - // NOTE: returns 0 if portal was completely culled by existing planes - // returns > 0 if culling planes are added (# is planes added) - int PCZCamera::addPortalCullingPlanes(PortalBase* portal) + // NOTE: returns 0 if portal was completely culled by existing planes + // returns > 0 if culling planes are added (# is planes added) + int PCZCamera::addPortalCullingPlanes(PortalBase* portal) { // add the extra culling planes from the portal return mExtraCullingFrustum.addPortalCullingPlanes(portal); } // remove extra culling planes created from the given portal - // NOTE: This should only be used during visibility traversal (backing out of a recursion) - void PCZCamera::removePortalCullingPlanes(PortalBase* portal) + // NOTE: This should only be used during visibility traversal (backing out of a recursion) + void PCZCamera::removePortalCullingPlanes(PortalBase* portal) { mExtraCullingFrustum.removePortalCullingPlanes(portal); } - // remove all extra culling planes + // remove all extra culling planes void PCZCamera::removeAllExtraCullingPlanes(void) { mExtraCullingFrustum.removeAllCullingPlanes(); diff --git a/PlugIns/PCZSceneManager/src/OgrePCZFrustum.cpp b/PlugIns/PCZSceneManager/src/OgrePCZFrustum.cpp index cc35fb1dc09..560bdb164bc 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCZFrustum.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCZFrustum.cpp @@ -57,21 +57,21 @@ email : ericc@xenopi.com namespace Ogre { - PCZFrustum::PCZFrustum() : + PCZFrustum::PCZFrustum() : mUseOriginPlane(false), mProjType(PT_PERSPECTIVE) - { } + { } PCZFrustum::~PCZFrustum() { removeAllCullingPlanes(); - // clear out the culling plane reservoir + // clear out the culling plane reservoir PCPlaneList::iterator pit = mCullingPlaneReservoir.begin(); while ( pit != mCullingPlaneReservoir.end() ) { PCPlane * plane = *pit; - // go to next entry + // go to next entry pit++; - //delete the entry in the list + //delete the entry in the list OGRE_DELETE_T(plane, PCPlane, MEMCATEGORY_SCENE_CONTROL); } mCullingPlaneReservoir.clear(); @@ -85,7 +85,7 @@ namespace Ogre // Infinite boxes are always visible if (bound.isInfinite()) return true; - // Get centre of the box + // Get centre of the box Vector3 centre = bound.getCenter(); // Get the half-size of the box Vector3 halfSize = bound.getHalfSize(); @@ -96,7 +96,7 @@ namespace Ogre Plane::Side side = mOriginPlane.getSide(centre, halfSize); if (side == Plane::NEGATIVE_SIDE) { - return false; + return false; } } @@ -109,11 +109,11 @@ namespace Ogre Plane::Side xside = plane->getSide(centre, halfSize); if (xside == Plane::NEGATIVE_SIDE) { - return false; + return false; } pit++; } - return true; + return true; } bool PCZFrustum::isVisible( const Sphere & bound) const @@ -124,11 +124,11 @@ namespace Ogre Plane::Side side = mOriginPlane.getSide(bound.getCenter()); if (side == Plane::NEGATIVE_SIDE) { - Real dist = mOriginPlane.getDistance(bound.getCenter()); - if (dist > bound.getRadius()) - { - return false; - } + Real dist = mOriginPlane.getDistance(bound.getCenter()); + if (dist > bound.getRadius()) + { + return false; + } } } @@ -141,67 +141,67 @@ namespace Ogre Plane::Side xside = plane->getSide(bound.getCenter()); if (xside == Plane::NEGATIVE_SIDE) { - Real dist = plane->getDistance(bound.getCenter()); - if (dist > bound.getRadius()) - { - return false; - } + Real dist = plane->getDistance(bound.getCenter()); + if (dist > bound.getRadius()) + { + return false; + } } pit++; } - return true; + return true; } - /* isVisible() function for portals */ - // NOTE: Everything needs to be updated spatially before this function is - // called including portal corners, frustum planes, etc. - bool PCZFrustum::isVisible(const PortalBase* portal) const - { - // if portal isn't enabled, it's not visible - if (!portal->getEnabled()) return false; + /* isVisible() function for portals */ + // NOTE: Everything needs to be updated spatially before this function is + // called including portal corners, frustum planes, etc. + bool PCZFrustum::isVisible(const PortalBase* portal) const + { + // if portal isn't enabled, it's not visible + if (!portal->getEnabled()) return false; - // if the frustum has no planes, just return true + // if the frustum has no planes, just return true if (mActiveCullingPlanes.empty()) { return true; } - // check if this portal is already in the list of active culling planes (avoid - // infinite recursion case) + // check if this portal is already in the list of active culling planes (avoid + // infinite recursion case) PCPlaneList::const_iterator pit = mActiveCullingPlanes.begin(); while ( pit != mActiveCullingPlanes.end() ) { PCPlane * plane = *pit; - if (plane->getPortal() == portal) - { - return false; - } + if (plane->getPortal() == portal) + { + return false; + } pit++; } - // if portal is of type AABB or Sphere, then use simple bound check against planes - if (portal->getType() == PortalBase::PORTAL_TYPE_AABB) - { - AxisAlignedBox aabb; - aabb.setExtents(portal->getDerivedCorner(0), portal->getDerivedCorner(1)); - return isVisible(aabb); - } - else if (portal->getType() == PortalBase::PORTAL_TYPE_SPHERE) - { - return isVisible(portal->getDerivedSphere()); - } - - // only do this check if it's a portal. (anti portal doesn't care about facing) - if (portal->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG) - { - // check if the portal norm is facing the frustum - Vector3 frustumToPortal = portal->getDerivedCP() - mOrigin; - Vector3 portalDirection = portal->getDerivedDirection(); - Real dotProduct = frustumToPortal.dotProduct(portalDirection); - if ( dotProduct > 0 ) - { - // portal is faced away from Frustum - return false; - } - } + // if portal is of type AABB or Sphere, then use simple bound check against planes + if (portal->getType() == PortalBase::PORTAL_TYPE_AABB) + { + AxisAlignedBox aabb; + aabb.setExtents(portal->getDerivedCorner(0), portal->getDerivedCorner(1)); + return isVisible(aabb); + } + else if (portal->getType() == PortalBase::PORTAL_TYPE_SPHERE) + { + return isVisible(portal->getDerivedSphere()); + } + + // only do this check if it's a portal. (anti portal doesn't care about facing) + if (portal->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG) + { + // check if the portal norm is facing the frustum + Vector3 frustumToPortal = portal->getDerivedCP() - mOrigin; + Vector3 portalDirection = portal->getDerivedDirection(); + Real dotProduct = frustumToPortal.dotProduct(portalDirection); + if ( dotProduct > 0 ) + { + // portal is faced away from Frustum + return false; + } + } // check against frustum culling planes bool visible_flag; @@ -218,7 +218,7 @@ namespace Ogre if (side != Plane::NEGATIVE_SIDE) { visible_flag = true; - break; + break; } } // if the visible_flag is still false, then the origin plane @@ -245,7 +245,7 @@ namespace Ogre if (side != Plane::NEGATIVE_SIDE) { visible_flag = true; - break; + break; } } // if the visible_flag is still false, then this plane @@ -263,171 +263,171 @@ namespace Ogre } - /* special function that returns true only when aabb fully fits inside the frustum. */ - bool PCZFrustum::isFullyVisible(const AxisAlignedBox& bound) const - { - // Null boxes are always invisible - if (bound.isNull()) return false; - - // Infinite boxes are never fully visible - if (bound.isInfinite()) return false; - - // Get centre of the box - Vector3 centre = bound.getCenter(); - // Get the half-size of the box - Vector3 halfSize = bound.getHalfSize(); - - // Check originplane if told to - if (mUseOriginPlane) - { - Plane::Side side = mOriginPlane.getSide(centre, halfSize); - if (side != Plane::POSITIVE_SIDE) return false; - } - - // For each extra active culling plane, - // see if the aabb is not on the positive side - // If so, object is not fully visible - PCPlaneList::const_iterator pit = mActiveCullingPlanes.begin(); - while ( pit != mActiveCullingPlanes.end() ) - { - PCPlane * plane = *pit; - Plane::Side xside = plane->getSide(centre, halfSize); - if (xside != Plane::POSITIVE_SIDE) - { - return false; - } - pit++; - } - return true; - } - - /* special function that returns true only when sphere fully fits inside the frustum. */ - bool PCZFrustum::isFullyVisible(const Sphere& bound) const - { - // Check originplane if told to - if (mUseOriginPlane) - { - if (mOriginPlane.getDistance(bound.getCenter()) <= bound.getRadius() || - mOriginPlane.getSide(bound.getCenter()) != Plane::POSITIVE_SIDE) - { - return false; - } - } - - // For each extra active culling plane, - // see if the sphere is not on the positive side - // If so, object is not fully visible - PCPlaneList::const_iterator pit = mActiveCullingPlanes.begin(); - while ( pit != mActiveCullingPlanes.end() ) - { - PCPlane* plane = *pit; - - if (plane->getDistance(bound.getCenter()) <= bound.getRadius() || - plane->getSide(bound.getCenter()) != Plane::POSITIVE_SIDE) - { - return false; - } - - pit++; - } - return true; - } - - /* special function that returns true only when portal fully fits inside the frustum. */ - bool PCZFrustum::isFullyVisible(const PortalBase* portal) const - { - // if portal isn't enabled, it's not visible - if (!portal->getEnabled()) return false; - - // if the frustum has no planes, just return true - if (mActiveCullingPlanes.empty()) - { - return true; - } - // check if this portal is already in the list of active culling planes (avoid - // infinite recursion case) - PCPlaneList::const_iterator pit = mActiveCullingPlanes.begin(); - while ( pit != mActiveCullingPlanes.end() ) - { - PCPlane * plane = *pit; - if (plane->getPortal() == portal) - { - return false; - } - pit++; - } - // if portal is of type AABB or Sphere, then use simple bound check against planes - if (portal->getType() == PortalBase::PORTAL_TYPE_AABB) - { - AxisAlignedBox aabb; - aabb.setExtents(portal->getDerivedCorner(0), portal->getDerivedCorner(1)); - return isFullyVisible(aabb); - } - else if (portal->getType() == PortalBase::PORTAL_TYPE_SPHERE) - { - return isFullyVisible(portal->getDerivedSphere()); - } - - // only do this check if it's a portal. (anti portal doesn't care about facing) - if (portal->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG) - { - // check if the portal norm is facing the frustum - Vector3 frustumToPortal = portal->getDerivedCP() - mOrigin; - Vector3 portalDirection = portal->getDerivedDirection(); - Real dotProduct = frustumToPortal.dotProduct(portalDirection); - if ( dotProduct > 0 ) - { - // portal is faced away from Frustum - return false; - } - } - - // Check originPlane if told to - if (mUseOriginPlane) - { - // we have to check each corner of the portal - for (int corner = 0; corner < 4; corner++) - { - Plane::Side side = mOriginPlane.getSide(portal->getDerivedCorner(corner)); - if (side == Plane::NEGATIVE_SIDE) return false; - } - } - - // For each active culling plane, see if any portal points are on the negative - // side. If so, the portal is not fully visible - pit = mActiveCullingPlanes.begin(); - while ( pit != mActiveCullingPlanes.end() ) - { - PCPlane * plane = *pit; - // we have to check each corner of the portal - for (int corner = 0; corner < 4; corner++) - { - Plane::Side side =plane->getSide(portal->getDerivedCorner(corner)); - if (side == Plane::NEGATIVE_SIDE) return false; - } - pit++; - } - // no plane culled all the portal points and the norm - // was facing the frustum, so this portal is fully visible - return true; - } - - /* A 'more detailed' check for visibility of an AAB. This function returns - none, partial, or full for visibility of the box. This is useful for - stuff like Octree leaf culling */ - PCZFrustum::Visibility PCZFrustum::getVisibility( const AxisAlignedBox &bound ) - { - - // Null boxes always invisible - if ( bound.isNull() ) - return NONE; - - // Get centre of the box - Vector3 centre = bound.getCenter(); - // Get the half-size of the box - Vector3 halfSize = bound.getHalfSize(); - - bool all_inside = true; + /* special function that returns true only when aabb fully fits inside the frustum. */ + bool PCZFrustum::isFullyVisible(const AxisAlignedBox& bound) const + { + // Null boxes are always invisible + if (bound.isNull()) return false; + + // Infinite boxes are never fully visible + if (bound.isInfinite()) return false; + + // Get centre of the box + Vector3 centre = bound.getCenter(); + // Get the half-size of the box + Vector3 halfSize = bound.getHalfSize(); + + // Check originplane if told to + if (mUseOriginPlane) + { + Plane::Side side = mOriginPlane.getSide(centre, halfSize); + if (side != Plane::POSITIVE_SIDE) return false; + } + + // For each extra active culling plane, + // see if the aabb is not on the positive side + // If so, object is not fully visible + PCPlaneList::const_iterator pit = mActiveCullingPlanes.begin(); + while ( pit != mActiveCullingPlanes.end() ) + { + PCPlane * plane = *pit; + Plane::Side xside = plane->getSide(centre, halfSize); + if (xside != Plane::POSITIVE_SIDE) + { + return false; + } + pit++; + } + return true; + } + + /* special function that returns true only when sphere fully fits inside the frustum. */ + bool PCZFrustum::isFullyVisible(const Sphere& bound) const + { + // Check originplane if told to + if (mUseOriginPlane) + { + if (mOriginPlane.getDistance(bound.getCenter()) <= bound.getRadius() || + mOriginPlane.getSide(bound.getCenter()) != Plane::POSITIVE_SIDE) + { + return false; + } + } + + // For each extra active culling plane, + // see if the sphere is not on the positive side + // If so, object is not fully visible + PCPlaneList::const_iterator pit = mActiveCullingPlanes.begin(); + while ( pit != mActiveCullingPlanes.end() ) + { + PCPlane* plane = *pit; + + if (plane->getDistance(bound.getCenter()) <= bound.getRadius() || + plane->getSide(bound.getCenter()) != Plane::POSITIVE_SIDE) + { + return false; + } + + pit++; + } + return true; + } + + /* special function that returns true only when portal fully fits inside the frustum. */ + bool PCZFrustum::isFullyVisible(const PortalBase* portal) const + { + // if portal isn't enabled, it's not visible + if (!portal->getEnabled()) return false; + + // if the frustum has no planes, just return true + if (mActiveCullingPlanes.empty()) + { + return true; + } + // check if this portal is already in the list of active culling planes (avoid + // infinite recursion case) + PCPlaneList::const_iterator pit = mActiveCullingPlanes.begin(); + while ( pit != mActiveCullingPlanes.end() ) + { + PCPlane * plane = *pit; + if (plane->getPortal() == portal) + { + return false; + } + pit++; + } + // if portal is of type AABB or Sphere, then use simple bound check against planes + if (portal->getType() == PortalBase::PORTAL_TYPE_AABB) + { + AxisAlignedBox aabb; + aabb.setExtents(portal->getDerivedCorner(0), portal->getDerivedCorner(1)); + return isFullyVisible(aabb); + } + else if (portal->getType() == PortalBase::PORTAL_TYPE_SPHERE) + { + return isFullyVisible(portal->getDerivedSphere()); + } + + // only do this check if it's a portal. (anti portal doesn't care about facing) + if (portal->getTypeFlags() == PortalFactory::FACTORY_TYPE_FLAG) + { + // check if the portal norm is facing the frustum + Vector3 frustumToPortal = portal->getDerivedCP() - mOrigin; + Vector3 portalDirection = portal->getDerivedDirection(); + Real dotProduct = frustumToPortal.dotProduct(portalDirection); + if ( dotProduct > 0 ) + { + // portal is faced away from Frustum + return false; + } + } + + // Check originPlane if told to + if (mUseOriginPlane) + { + // we have to check each corner of the portal + for (int corner = 0; corner < 4; corner++) + { + Plane::Side side = mOriginPlane.getSide(portal->getDerivedCorner(corner)); + if (side == Plane::NEGATIVE_SIDE) return false; + } + } + + // For each active culling plane, see if any portal points are on the negative + // side. If so, the portal is not fully visible + pit = mActiveCullingPlanes.begin(); + while ( pit != mActiveCullingPlanes.end() ) + { + PCPlane * plane = *pit; + // we have to check each corner of the portal + for (int corner = 0; corner < 4; corner++) + { + Plane::Side side =plane->getSide(portal->getDerivedCorner(corner)); + if (side == Plane::NEGATIVE_SIDE) return false; + } + pit++; + } + // no plane culled all the portal points and the norm + // was facing the frustum, so this portal is fully visible + return true; + } + + /* A 'more detailed' check for visibility of an AAB. This function returns + none, partial, or full for visibility of the box. This is useful for + stuff like Octree leaf culling */ + PCZFrustum::Visibility PCZFrustum::getVisibility( const AxisAlignedBox &bound ) + { + + // Null boxes always invisible + if ( bound.isNull() ) + return NONE; + + // Get centre of the box + Vector3 centre = bound.getCenter(); + // Get the half-size of the box + Vector3 halfSize = bound.getHalfSize(); + + bool all_inside = true; // Check originplane if told to if (mUseOriginPlane) @@ -435,10 +435,10 @@ namespace Ogre Plane::Side side = mOriginPlane.getSide(centre, halfSize); if (side == Plane::NEGATIVE_SIDE) { - return NONE; + return NONE; } - // We can't return now as the box could be later on the negative side of another plane. - if(side == Plane::BOTH_SIDE) + // We can't return now as the box could be later on the negative side of another plane. + if(side == Plane::BOTH_SIDE) { all_inside = false; } @@ -451,172 +451,172 @@ namespace Ogre { PCPlane * plane = *pit; Plane::Side xside = plane->getSide(centre, halfSize); - if(xside == Plane::NEGATIVE_SIDE) + if(xside == Plane::NEGATIVE_SIDE) { return NONE; } - // We can't return now as the box could be later on the negative side of a plane. - if(xside == Plane::BOTH_SIDE) + // We can't return now as the box could be later on the negative side of a plane. + if(xside == Plane::BOTH_SIDE) { all_inside = false; - break; + break; } pit++; } - if ( all_inside ) - return FULL; - else - return PARTIAL; + if ( all_inside ) + return FULL; + else + return PARTIAL; - } + } - // calculate culling planes from portal and frustum - // origin and add to list of culling planes - // NOTE: returns 0 if portal was completely culled by existing planes - // returns > 0 if culling planes are added (# is planes added) - int PCZFrustum::addPortalCullingPlanes(PortalBase* portal) - { - int addedcullingplanes = 0; + // calculate culling planes from portal and frustum + // origin and add to list of culling planes + // NOTE: returns 0 if portal was completely culled by existing planes + // returns > 0 if culling planes are added (# is planes added) + int PCZFrustum::addPortalCullingPlanes(PortalBase* portal) + { + int addedcullingplanes = 0; - // If portal is of type aabb or sphere, add a plane which is same as frustum - // origin plane (ie. redundant). We do this because we need the plane as a flag - // to prevent infinite recursion - if (portal->getType() == PortalBase::PORTAL_TYPE_AABB || - portal->getType() == PortalBase::PORTAL_TYPE_SPHERE) - { + // If portal is of type aabb or sphere, add a plane which is same as frustum + // origin plane (ie. redundant). We do this because we need the plane as a flag + // to prevent infinite recursion + if (portal->getType() == PortalBase::PORTAL_TYPE_AABB || + portal->getType() == PortalBase::PORTAL_TYPE_SPHERE) + { PCPlane * newPlane = getUnusedCullingPlane(); - newPlane->setFromOgrePlane(mOriginPlane); + newPlane->setFromOgrePlane(mOriginPlane); newPlane->setPortal(portal); mActiveCullingPlanes.push_front(newPlane); - addedcullingplanes++; - return addedcullingplanes; - } - - // only do this check if it's an anti portal since it's double facing. - bool flipPlane = false; - if (portal->getTypeFlags() == AntiPortalFactory::FACTORY_TYPE_FLAG) - { - // check if the portal norm is facing the frustum - Vector3 frustumToPortal = portal->getDerivedCP() - mOrigin; - Vector3 portalDirection = portal->getDerivedDirection(); - Real dotProduct = frustumToPortal.dotProduct(portalDirection); - - // it's facing away from the frustum. Flip the planes. - if (dotProduct > 0) flipPlane = true; - } + addedcullingplanes++; + return addedcullingplanes; + } + + // only do this check if it's an anti portal since it's double facing. + bool flipPlane = false; + if (portal->getTypeFlags() == AntiPortalFactory::FACTORY_TYPE_FLAG) + { + // check if the portal norm is facing the frustum + Vector3 frustumToPortal = portal->getDerivedCP() - mOrigin; + Vector3 portalDirection = portal->getDerivedDirection(); + Real dotProduct = frustumToPortal.dotProduct(portalDirection); + + // it's facing away from the frustum. Flip the planes. + if (dotProduct > 0) flipPlane = true; + } // For portal Quads: Up to 4 planes can be added by the sides of a portal quad. // Each plane is created from 2 corners (world space) of the portal and the // frustum origin (world space). - int i,j; - Plane::Side pt0_side, pt1_side; - bool visible; + int i,j; + Plane::Side pt0_side, pt1_side; + bool visible; PCPlaneList::iterator pit; for (i=0;i<4;i++) { // first check if both corners are outside of one of the existing planes - j = i+1; - if (j > 3) - { - j = 0; - } - visible = true; + j = i+1; + if (j > 3) + { + j = 0; + } + visible = true; pit = mActiveCullingPlanes.begin(); while ( pit != mActiveCullingPlanes.end() ) { PCPlane * plane = *pit; - pt0_side = plane->getSide(portal->getDerivedCorner(i)); - pt1_side = plane->getSide(portal->getDerivedCorner(j)); - if (pt0_side == Plane::NEGATIVE_SIDE && - pt1_side == Plane::NEGATIVE_SIDE) - { - // the portal edge was actually completely culled by one of culling planes - visible = false; - break; - } - pit++; + pt0_side = plane->getSide(portal->getDerivedCorner(i)); + pt1_side = plane->getSide(portal->getDerivedCorner(j)); + if (pt0_side == Plane::NEGATIVE_SIDE && + pt1_side == Plane::NEGATIVE_SIDE) + { + // the portal edge was actually completely culled by one of culling planes + visible = false; + break; + } + pit++; } - if (visible) - { - // add the plane created from the two portal corner points and the frustum location - // to the culling plane + if (visible) + { + // add the plane created from the two portal corner points and the frustum location + // to the culling plane PCPlane * newPlane = getUnusedCullingPlane(); - if (mProjType == PT_ORTHOGRAPHIC) // use camera direction if projection is orthographic. - { - if (flipPlane) - { - newPlane->redefine(portal->getDerivedCorner(j) + mOriginPlane.normal, - portal->getDerivedCorner(i), portal->getDerivedCorner(j)); - } - else - { - newPlane->redefine(portal->getDerivedCorner(j) + mOriginPlane.normal, - portal->getDerivedCorner(j), portal->getDerivedCorner(i)); - } - } - else - { - if (flipPlane) - { - newPlane->redefine(mOrigin, - portal->getDerivedCorner(i), - portal->getDerivedCorner(j)); - } - else - { - newPlane->redefine(mOrigin, - portal->getDerivedCorner(j), - portal->getDerivedCorner(i)); - } - } + if (mProjType == PT_ORTHOGRAPHIC) // use camera direction if projection is orthographic. + { + if (flipPlane) + { + newPlane->redefine(portal->getDerivedCorner(j) + mOriginPlane.normal, + portal->getDerivedCorner(i), portal->getDerivedCorner(j)); + } + else + { + newPlane->redefine(portal->getDerivedCorner(j) + mOriginPlane.normal, + portal->getDerivedCorner(j), portal->getDerivedCorner(i)); + } + } + else + { + if (flipPlane) + { + newPlane->redefine(mOrigin, + portal->getDerivedCorner(i), + portal->getDerivedCorner(j)); + } + else + { + newPlane->redefine(mOrigin, + portal->getDerivedCorner(j), + portal->getDerivedCorner(i)); + } + } newPlane->setPortal(portal); mActiveCullingPlanes.push_front(newPlane); - addedcullingplanes++; - } - } - // if we added ANY planes from the quad portal, we should add the plane of the - // portal itself as an additional culling plane. - if (addedcullingplanes > 0) - { - PCPlane * newPlane = getUnusedCullingPlane(); - - if (flipPlane) - { - newPlane->redefine( - portal->getDerivedCorner(2), - portal->getDerivedCorner(0), - portal->getDerivedCorner(1)); - } - else - { - newPlane->redefine( - portal->getDerivedCorner(2), - portal->getDerivedCorner(1), - portal->getDerivedCorner(0)); - } - - newPlane->setPortal(portal); - mActiveCullingPlanes.push_back(newPlane); - addedcullingplanes++; - } - return addedcullingplanes; + addedcullingplanes++; + } + } + // if we added ANY planes from the quad portal, we should add the plane of the + // portal itself as an additional culling plane. + if (addedcullingplanes > 0) + { + PCPlane * newPlane = getUnusedCullingPlane(); + + if (flipPlane) + { + newPlane->redefine( + portal->getDerivedCorner(2), + portal->getDerivedCorner(0), + portal->getDerivedCorner(1)); + } + else + { + newPlane->redefine( + portal->getDerivedCorner(2), + portal->getDerivedCorner(1), + portal->getDerivedCorner(0)); + } + + newPlane->setPortal(portal); + mActiveCullingPlanes.push_back(newPlane); + addedcullingplanes++; + } + return addedcullingplanes; } - // remove culling planes created from the given portal - void PCZFrustum::removePortalCullingPlanes(PortalBase* portal) - { + // remove culling planes created from the given portal + void PCZFrustum::removePortalCullingPlanes(PortalBase* portal) + { PCPlaneList::iterator pit = mActiveCullingPlanes.begin(); while ( pit != mActiveCullingPlanes.end() ) { PCPlane * plane = *pit; - if (plane->getPortal() == portal) - { - // put the plane back in the reservoir - mCullingPlaneReservoir.push_front(plane); - // erase the entry from the active culling plane list + if (plane->getPortal() == portal) + { + // put the plane back in the reservoir + mCullingPlaneReservoir.push_front(plane); + // erase the entry from the active culling plane list pit = mActiveCullingPlanes.erase(pit); - } + } else { pit++; @@ -625,7 +625,7 @@ namespace Ogre } - // remove all active extra culling planes + // remove all active extra culling planes // NOTE: Does not change the use of the originPlane! void PCZFrustum::removeAllCullingPlanes(void) { @@ -633,9 +633,9 @@ namespace Ogre while ( pit != mActiveCullingPlanes.end() ) { PCPlane * plane = *pit; - // put the plane back in the reservoir - mCullingPlaneReservoir.push_front(plane); - // go to next entry + // put the plane back in the reservoir + mCullingPlaneReservoir.push_front(plane); + // go to next entry pit++; } mActiveCullingPlanes.clear(); @@ -647,21 +647,21 @@ namespace Ogre mOriginPlane.redefine(rkNormal, rkPoint); } - // get an unused PCPlane from the CullingPlane Reservoir - // note that this removes the PCPlane from the reservoir! - PCPlane * PCZFrustum::getUnusedCullingPlane(void) - { - PCPlane * plane = 0; - if (mCullingPlaneReservoir.size() > 0) - { - PCPlaneList::iterator pit = mCullingPlaneReservoir.begin(); - plane = *pit; - mCullingPlaneReservoir.erase(pit); - return plane; - } - // no available planes! create one - plane = OGRE_NEW_T(PCPlane, MEMCATEGORY_SCENE_CONTROL); - return plane; - } + // get an unused PCPlane from the CullingPlane Reservoir + // note that this removes the PCPlane from the reservoir! + PCPlane * PCZFrustum::getUnusedCullingPlane(void) + { + PCPlane * plane = 0; + if (mCullingPlaneReservoir.size() > 0) + { + PCPlaneList::iterator pit = mCullingPlaneReservoir.begin(); + plane = *pit; + mCullingPlaneReservoir.erase(pit); + return plane; + } + // no available planes! create one + plane = OGRE_NEW_T(PCPlane, MEMCATEGORY_SCENE_CONTROL); + return plane; + } } diff --git a/PlugIns/PCZSceneManager/src/OgrePCZLight.cpp b/PlugIns/PCZSceneManager/src/OgrePCZLight.cpp index f5d928477b0..ebfedb199e1 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCZLight.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCZLight.cpp @@ -29,7 +29,7 @@ PCZLight.cpp - description begin : Wed May 23 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -44,12 +44,12 @@ namespace Ogre //----------------------------------------------------------------------- PCZLight::PCZLight() : Light() { - mNeedsUpdate = true; // need to update the first time, regardless of attachment or movement + mNeedsUpdate = true; // need to update the first time, regardless of attachment or movement } //----------------------------------------------------------------------- - PCZLight::PCZLight(const String& name) : Light(name) + PCZLight::PCZLight(const String& name) : Light(name) { - mNeedsUpdate = true; // need to update the first time, regardless of attachment or movement + mNeedsUpdate = true; // need to update the first time, regardless of attachment or movement } //----------------------------------------------------------------------- PCZLight::~PCZLight() @@ -59,7 +59,7 @@ namespace Ogre //----------------------------------------------------------------------- const String& PCZLight::getMovableType(void) const { - return PCZLightFactory::FACTORY_TYPE_NAME; + return PCZLightFactory::FACTORY_TYPE_NAME; } //----------------------------------------------------------------------- /** Clear the affectedZonesList @@ -140,58 +140,58 @@ namespace Ogre portalFrustum.setOrigin(v); homeZone->_checkLightAgainstPortals(this, frameCount, &portalFrustum, 0); } - //----------------------------------------------------------------------- - void PCZLight::removeZoneFromAffectedZonesList(PCZone * zone) - { - ZoneList::iterator it = std::find(affectedZonesList.begin(), affectedZonesList.end(), zone); - - if (it != affectedZonesList.end()) - { - affectedZonesList.erase( it ); // zone is in list, erase it. - } - } - //----------------------------------------------------------------------- - void PCZLight::_notifyMoved(void) - { - Light::_notifyMoved(); // inform ogre Light of movement - - mNeedsUpdate = true; // set need update flag - } - //----------------------------------------------------------------------- - bool PCZLight::getNeedsUpdate(void) - { - if(mNeedsUpdate) // if this light has moved, return true immediately - return true; - - // if any zones affected by this light have updated portals, then this light needs updating too - for (ZoneList::iterator iter = affectedZonesList.begin() ; iter != affectedZonesList.end(); iter++) - { - if((*iter)->getPortalsUpdated()) return true; // return immediately to prevent further iterating - } - - return false; // light hasn't moved, and no zones have updated portals. no light update. - } - - - //----------------------------------------------------------------------- - String PCZLightFactory::FACTORY_TYPE_NAME = "PCZLight"; - //----------------------------------------------------------------------- - const String& PCZLightFactory::getType(void) const - { - return FACTORY_TYPE_NAME; - } - //----------------------------------------------------------------------- - MovableObject* PCZLightFactory::createInstanceImpl( const String& name, - const NameValuePairList* params) - { - - return OGRE_NEW PCZLight(name); - - } - //----------------------------------------------------------------------- - void PCZLightFactory::destroyInstance( MovableObject* obj) - { - OGRE_DELETE obj; - } + //----------------------------------------------------------------------- + void PCZLight::removeZoneFromAffectedZonesList(PCZone * zone) + { + ZoneList::iterator it = std::find(affectedZonesList.begin(), affectedZonesList.end(), zone); + + if (it != affectedZonesList.end()) + { + affectedZonesList.erase( it ); // zone is in list, erase it. + } + } + //----------------------------------------------------------------------- + void PCZLight::_notifyMoved(void) + { + Light::_notifyMoved(); // inform ogre Light of movement + + mNeedsUpdate = true; // set need update flag + } + //----------------------------------------------------------------------- + bool PCZLight::getNeedsUpdate(void) + { + if(mNeedsUpdate) // if this light has moved, return true immediately + return true; + + // if any zones affected by this light have updated portals, then this light needs updating too + for (ZoneList::iterator iter = affectedZonesList.begin() ; iter != affectedZonesList.end(); iter++) + { + if((*iter)->getPortalsUpdated()) return true; // return immediately to prevent further iterating + } + + return false; // light hasn't moved, and no zones have updated portals. no light update. + } + + + //----------------------------------------------------------------------- + String PCZLightFactory::FACTORY_TYPE_NAME = "PCZLight"; + //----------------------------------------------------------------------- + const String& PCZLightFactory::getType(void) const + { + return FACTORY_TYPE_NAME; + } + //----------------------------------------------------------------------- + MovableObject* PCZLightFactory::createInstanceImpl( const String& name, + const NameValuePairList* params) + { + + return OGRE_NEW PCZLight(name); + + } + //----------------------------------------------------------------------- + void PCZLightFactory::destroyInstance( MovableObject* obj) + { + OGRE_DELETE obj; + } } // Namespace diff --git a/PlugIns/PCZSceneManager/src/OgrePCZPlugin.cpp b/PlugIns/PCZSceneManager/src/OgrePCZPlugin.cpp index 12316dc4d36..ce4cd7cb394 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCZPlugin.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCZPlugin.cpp @@ -29,7 +29,7 @@ OgrePCZPlugin.cpp - Portal Connected Zone Scene Manager Plugin class begin : Mon Feb 19 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -43,64 +43,64 @@ Code Style Update : namespace Ogre { - const String sPluginName = "Portal Connected Zone Scene Manager"; - //--------------------------------------------------------------------- - PCZPlugin::PCZPlugin() - :mPCZSMFactory(0) - { - } - //--------------------------------------------------------------------- - const String& PCZPlugin::getName() const - { - return sPluginName; - } - //--------------------------------------------------------------------- - void PCZPlugin::install() - { - // Create objects - mPCZSMFactory = OGRE_NEW PCZSceneManagerFactory(); - mPCZoneFactoryManager = OGRE_NEW PCZoneFactoryManager(); - mPCZLightFactory = OGRE_NEW PCZLightFactory(); - mPortalFactory = OGRE_NEW PortalFactory(); - mAntiPortalFactory = OGRE_NEW AntiPortalFactory(); - } - //--------------------------------------------------------------------- - void PCZPlugin::initialise() - { - // Register - Root::getSingleton().addSceneManagerFactory(mPCZSMFactory); - Root::getSingleton().addMovableObjectFactory(mPCZLightFactory); - Root::getSingleton().addMovableObjectFactory(mPortalFactory); - Root::getSingleton().addMovableObjectFactory(mAntiPortalFactory); + const String sPluginName = "Portal Connected Zone Scene Manager"; + //--------------------------------------------------------------------- + PCZPlugin::PCZPlugin() + :mPCZSMFactory(0) + { + } + //--------------------------------------------------------------------- + const String& PCZPlugin::getName() const + { + return sPluginName; + } + //--------------------------------------------------------------------- + void PCZPlugin::install() + { + // Create objects + mPCZSMFactory = OGRE_NEW PCZSceneManagerFactory(); + mPCZoneFactoryManager = OGRE_NEW PCZoneFactoryManager(); + mPCZLightFactory = OGRE_NEW PCZLightFactory(); + mPortalFactory = OGRE_NEW PortalFactory(); + mAntiPortalFactory = OGRE_NEW AntiPortalFactory(); + } + //--------------------------------------------------------------------- + void PCZPlugin::initialise() + { + // Register + Root::getSingleton().addSceneManagerFactory(mPCZSMFactory); + Root::getSingleton().addMovableObjectFactory(mPCZLightFactory); + Root::getSingleton().addMovableObjectFactory(mPortalFactory); + Root::getSingleton().addMovableObjectFactory(mAntiPortalFactory); - // set type flags to static member variable for fast access. - PortalFactory::FACTORY_TYPE_FLAG = mPortalFactory->getTypeFlags(); - AntiPortalFactory::FACTORY_TYPE_FLAG = mAntiPortalFactory->getTypeFlags(); - } - //--------------------------------------------------------------------- - void PCZPlugin::shutdown() - { - // Unregister - Root::getSingleton().removeSceneManagerFactory(mPCZSMFactory); - Root::getSingleton().removeMovableObjectFactory(mPCZLightFactory); - Root::getSingleton().removeMovableObjectFactory(mPortalFactory); - Root::getSingleton().removeMovableObjectFactory(mAntiPortalFactory); - } - //--------------------------------------------------------------------- - void PCZPlugin::uninstall() - { - // destroy - OGRE_DELETE mPCZSMFactory; - mPCZSMFactory = 0; - OGRE_DELETE mPCZoneFactoryManager; - mPCZoneFactoryManager = 0; - OGRE_DELETE mPCZLightFactory; - mPCZLightFactory = 0; - OGRE_DELETE mPortalFactory; - mPortalFactory = 0; - OGRE_DELETE mAntiPortalFactory; - mAntiPortalFactory = 0; - } + // set type flags to static member variable for fast access. + PortalFactory::FACTORY_TYPE_FLAG = mPortalFactory->getTypeFlags(); + AntiPortalFactory::FACTORY_TYPE_FLAG = mAntiPortalFactory->getTypeFlags(); + } + //--------------------------------------------------------------------- + void PCZPlugin::shutdown() + { + // Unregister + Root::getSingleton().removeSceneManagerFactory(mPCZSMFactory); + Root::getSingleton().removeMovableObjectFactory(mPCZLightFactory); + Root::getSingleton().removeMovableObjectFactory(mPortalFactory); + Root::getSingleton().removeMovableObjectFactory(mAntiPortalFactory); + } + //--------------------------------------------------------------------- + void PCZPlugin::uninstall() + { + // destroy + OGRE_DELETE mPCZSMFactory; + mPCZSMFactory = 0; + OGRE_DELETE mPCZoneFactoryManager; + mPCZoneFactoryManager = 0; + OGRE_DELETE mPCZLightFactory; + mPCZLightFactory = 0; + OGRE_DELETE mPortalFactory; + mPortalFactory = 0; + OGRE_DELETE mAntiPortalFactory; + mAntiPortalFactory = 0; + } } diff --git a/PlugIns/PCZSceneManager/src/OgrePCZSceneManager.cpp b/PlugIns/PCZSceneManager/src/OgrePCZSceneManager.cpp index a8310cd5a75..5880167ca0f 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCZSceneManager.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCZSceneManager.cpp @@ -46,296 +46,296 @@ email : ericc@xenopi.com namespace Ogre { - PCZSceneManager::PCZSceneManager(const String& name) : - SceneManager(name), - mDefaultZoneTypeName("ZoneType_Default"), - mDefaultZoneFileName("none"), - mLastActiveCamera(0), - mDefaultZone(0), - mShowPortals(false), - mZoneFactoryManager(0), - mActiveCameraZone(0) - { } + PCZSceneManager::PCZSceneManager(const String& name) : + SceneManager(name), + mDefaultZoneTypeName("ZoneType_Default"), + mDefaultZoneFileName("none"), + mLastActiveCamera(0), + mDefaultZone(0), + mShowPortals(false), + mZoneFactoryManager(0), + mActiveCameraZone(0) + { } PCZSceneManager::~PCZSceneManager() { // we don't delete the root scene node here because the // base scene manager class does that. - // delete ALL portals - Portal * p; - PortalList::iterator i = mPortals.begin(); - for (i = mPortals.begin(); i != mPortals.end(); i++) - { - p = *i; - OGRE_DELETE p; - } - mPortals.clear(); - - // delete all the zones - for (ZoneMap::iterator j = mZones.begin(); - j != mZones.end(); ++j) - { - OGRE_DELETE j->second; - } - mZones.clear(); + // delete ALL portals + Portal * p; + PortalList::iterator i = mPortals.begin(); + for (i = mPortals.begin(); i != mPortals.end(); i++) + { + p = *i; + OGRE_DELETE p; + } + mPortals.clear(); + + // delete all the zones + for (ZoneMap::iterator j = mZones.begin(); + j != mZones.end(); ++j) + { + OGRE_DELETE j->second; + } + mZones.clear(); mDefaultZone = 0; } const String& PCZSceneManager::getTypeName(void) const { - return PCZSceneManagerFactory::FACTORY_TYPE_NAME; + return PCZSceneManagerFactory::FACTORY_TYPE_NAME; } void PCZSceneManager::init( const String &defaultZoneTypeName, - const String &filename) - { - - // delete ALL portals - Portal * p; - PortalList::iterator i = mPortals.begin(); - for (i = mPortals.begin(); i != mPortals.end(); i++) - { - p = *i; - OGRE_DELETE p; - } - mPortals.clear(); - - // delete all the zones - for (ZoneMap::iterator j = mZones.begin(); - j != mZones.end(); ++j) - { - OGRE_DELETE j->second; - } - mZones.clear(); + const String &filename) + { + + // delete ALL portals + Portal * p; + PortalList::iterator i = mPortals.begin(); + for (i = mPortals.begin(); i != mPortals.end(); i++) + { + p = *i; + OGRE_DELETE p; + } + mPortals.clear(); + + // delete all the zones + for (ZoneMap::iterator j = mZones.begin(); + j != mZones.end(); ++j) + { + OGRE_DELETE j->second; + } + mZones.clear(); mFrameCount = 0; - mDefaultZoneTypeName = defaultZoneTypeName; - mDefaultZoneFileName = filename; + mDefaultZoneTypeName = defaultZoneTypeName; + mDefaultZoneFileName = filename; // create a new default zone - mZoneFactoryManager = PCZoneFactoryManager::getSingletonPtr(); - mDefaultZone = createZoneFromFile(mDefaultZoneTypeName, "Default_Zone", (PCZSceneNode*)getRootSceneNode(), mDefaultZoneFileName); - } - - // Create a portal instance - Portal* PCZSceneManager::createPortal(const String& name, PortalBase::PORTAL_TYPE type) - { - Portal* newPortal = OGRE_NEW Portal(name, type); - newPortal->_notifyCreator(Root::getSingleton().getMovableObjectFactory("Portal")); - newPortal->_notifyManager(this); - mPortals.push_front(newPortal); - return newPortal; - } - - // delete a portal instance by pointer - void PCZSceneManager::destroyPortal(Portal * p) - { - // remove the portal from it's target portal - Portal * targetPortal = p->getTargetPortal(); - if (targetPortal) - { - targetPortal->setTargetPortal(0); // the targetPortal will still have targetZone value, but targetPortal will be invalid - } - // remove the Portal from it's home zone - PCZone * homeZone = p->getCurrentHomeZone(); - if (homeZone) - { - // inform zone of portal change. Do here since PCZone is abstract - homeZone->setPortalsUpdated(true); - homeZone->_removePortal(p); - } - - // remove the portal from the master portal list - PortalList::iterator it = std::find( mPortals.begin(), mPortals.end(), p ); - if (it != mPortals.end()) - { - mPortals.erase(it); - } - // delete the portal instance - OGRE_DELETE p; - } - - // delete a portal instance by pointer - void PCZSceneManager::destroyPortal(const String & portalName) - { - // find the portal from the master portal list - Portal * p; - Portal * thePortal = 0; - PortalList::iterator it = mPortals.begin(); - while (it != mPortals.end()) - { - p = *it; - if (p->getName() == portalName) - { - thePortal = p; - // erase entry in the master list - mPortals.erase(it); - break; - } - it++; - } - if (thePortal) - { - // remove the portal from it's target portal - Portal * targetPortal = thePortal->getTargetPortal(); - if (targetPortal) - { - targetPortal->setTargetPortal(0); // the targetPortal will still have targetZone value, but targetPortal will be invalid - } - // remove the Portal from it's home zone - PCZone * homeZone = thePortal->getCurrentHomeZone(); - if (homeZone) - { - // inform zone of portal change - homeZone->setPortalsUpdated(true); - homeZone->_removePortal(thePortal); - } - - // delete the portal instance - OGRE_DELETE thePortal; - } - } - - /** Create a new anti portal instance */ - AntiPortal* PCZSceneManager::createAntiPortal(const String& name, PortalBase::PORTAL_TYPE type) - { - AntiPortal* newAntiPortal = OGRE_NEW AntiPortal(name, type); - newAntiPortal->_notifyCreator(Root::getSingleton().getMovableObjectFactory("AntiPortal")); - newAntiPortal->_notifyManager(this); - mAntiPortals.push_front(newAntiPortal); - return newAntiPortal; - } - - /** Delete a anti portal instance by pointer */ - void PCZSceneManager::destroyAntiPortal(AntiPortal * p) - { - // remove the Portal from it's home zone - PCZone* homeZone = p->getCurrentHomeZone(); - if (homeZone) - { - // inform zone of portal change. Do here since PCZone is abstract - homeZone->setPortalsUpdated(true); - homeZone->_removeAntiPortal(p); - } - - // remove the portal from the master portal list - AntiPortalList::iterator it = std::find(mAntiPortals.begin(), mAntiPortals.end(), p); - if (it != mAntiPortals.end()) mAntiPortals.erase(it); - - // delete the portal instance - OGRE_DELETE p; - } - - /** Delete a anti portal instance by name */ - void PCZSceneManager::destroyAntiPortal(const String& portalName) - { - // find the anti portal from the master portal list - AntiPortal* p; - AntiPortal* thePortal = 0; - AntiPortalList::iterator it = mAntiPortals.begin(); - while (it != mAntiPortals.end()) - { - p = *it; - if (p->getName() == portalName) - { - thePortal = p; - // erase entry in the master list - mAntiPortals.erase(it); - break; - } - it++; - } - if (thePortal) - { - // remove the Portal from it's home zone - PCZone* homeZone = thePortal->getCurrentHomeZone(); - if (homeZone) - { - // inform zone of portal change - homeZone->setPortalsUpdated(true); - homeZone->_removeAntiPortal(thePortal); - } - - // delete the portal instance - OGRE_DELETE thePortal; - } - } - - /** Create a zone from a file (type of file - * depends on the zone type - * ZoneType_Default uses an Ogre Model (.mesh) file - * ZoneType_Octree uses an Ogre Model (.mesh) file - * ZoneType_Terrain uses a Terrain.CFG file - */ - PCZone * PCZSceneManager::createZoneFromFile(const String &zoneTypeName, - const String &zoneName, - PCZSceneNode * parentNode, - const String &filename) - { - PCZone * newZone; + mZoneFactoryManager = PCZoneFactoryManager::getSingletonPtr(); + mDefaultZone = createZoneFromFile(mDefaultZoneTypeName, "Default_Zone", (PCZSceneNode*)getRootSceneNode(), mDefaultZoneFileName); + } + + // Create a portal instance + Portal* PCZSceneManager::createPortal(const String& name, PortalBase::PORTAL_TYPE type) + { + Portal* newPortal = OGRE_NEW Portal(name, type); + newPortal->_notifyCreator(Root::getSingleton().getMovableObjectFactory("Portal")); + newPortal->_notifyManager(this); + mPortals.push_front(newPortal); + return newPortal; + } + + // delete a portal instance by pointer + void PCZSceneManager::destroyPortal(Portal * p) + { + // remove the portal from it's target portal + Portal * targetPortal = p->getTargetPortal(); + if (targetPortal) + { + targetPortal->setTargetPortal(0); // the targetPortal will still have targetZone value, but targetPortal will be invalid + } + // remove the Portal from it's home zone + PCZone * homeZone = p->getCurrentHomeZone(); + if (homeZone) + { + // inform zone of portal change. Do here since PCZone is abstract + homeZone->setPortalsUpdated(true); + homeZone->_removePortal(p); + } + + // remove the portal from the master portal list + PortalList::iterator it = std::find( mPortals.begin(), mPortals.end(), p ); + if (it != mPortals.end()) + { + mPortals.erase(it); + } + // delete the portal instance + OGRE_DELETE p; + } + + // delete a portal instance by pointer + void PCZSceneManager::destroyPortal(const String & portalName) + { + // find the portal from the master portal list + Portal * p; + Portal * thePortal = 0; + PortalList::iterator it = mPortals.begin(); + while (it != mPortals.end()) + { + p = *it; + if (p->getName() == portalName) + { + thePortal = p; + // erase entry in the master list + mPortals.erase(it); + break; + } + it++; + } + if (thePortal) + { + // remove the portal from it's target portal + Portal * targetPortal = thePortal->getTargetPortal(); + if (targetPortal) + { + targetPortal->setTargetPortal(0); // the targetPortal will still have targetZone value, but targetPortal will be invalid + } + // remove the Portal from it's home zone + PCZone * homeZone = thePortal->getCurrentHomeZone(); + if (homeZone) + { + // inform zone of portal change + homeZone->setPortalsUpdated(true); + homeZone->_removePortal(thePortal); + } + + // delete the portal instance + OGRE_DELETE thePortal; + } + } + + /** Create a new anti portal instance */ + AntiPortal* PCZSceneManager::createAntiPortal(const String& name, PortalBase::PORTAL_TYPE type) + { + AntiPortal* newAntiPortal = OGRE_NEW AntiPortal(name, type); + newAntiPortal->_notifyCreator(Root::getSingleton().getMovableObjectFactory("AntiPortal")); + newAntiPortal->_notifyManager(this); + mAntiPortals.push_front(newAntiPortal); + return newAntiPortal; + } + + /** Delete a anti portal instance by pointer */ + void PCZSceneManager::destroyAntiPortal(AntiPortal * p) + { + // remove the Portal from it's home zone + PCZone* homeZone = p->getCurrentHomeZone(); + if (homeZone) + { + // inform zone of portal change. Do here since PCZone is abstract + homeZone->setPortalsUpdated(true); + homeZone->_removeAntiPortal(p); + } + + // remove the portal from the master portal list + AntiPortalList::iterator it = std::find(mAntiPortals.begin(), mAntiPortals.end(), p); + if (it != mAntiPortals.end()) mAntiPortals.erase(it); + + // delete the portal instance + OGRE_DELETE p; + } + + /** Delete a anti portal instance by name */ + void PCZSceneManager::destroyAntiPortal(const String& portalName) + { + // find the anti portal from the master portal list + AntiPortal* p; + AntiPortal* thePortal = 0; + AntiPortalList::iterator it = mAntiPortals.begin(); + while (it != mAntiPortals.end()) + { + p = *it; + if (p->getName() == portalName) + { + thePortal = p; + // erase entry in the master list + mAntiPortals.erase(it); + break; + } + it++; + } + if (thePortal) + { + // remove the Portal from it's home zone + PCZone* homeZone = thePortal->getCurrentHomeZone(); + if (homeZone) + { + // inform zone of portal change + homeZone->setPortalsUpdated(true); + homeZone->_removeAntiPortal(thePortal); + } + + // delete the portal instance + OGRE_DELETE thePortal; + } + } + + /** Create a zone from a file (type of file + * depends on the zone type + * ZoneType_Default uses an Ogre Model (.mesh) file + * ZoneType_Octree uses an Ogre Model (.mesh) file + * ZoneType_Terrain uses a Terrain.CFG file + */ + PCZone * PCZSceneManager::createZoneFromFile(const String &zoneTypeName, + const String &zoneName, + PCZSceneNode * parentNode, + const String &filename) + { + PCZone * newZone; // create a new default zone - newZone = mZoneFactoryManager->createPCZone(this, zoneTypeName, zoneName); - // add to the global list of zones - mZones[newZone->getName()] = newZone; - if (filename != "none") - { - // set the zone geometry - newZone->setZoneGeometry(filename, parentNode); - } - - return newZone; - } - - /* Get a zone by name */ - PCZone * PCZSceneManager::getZoneByName(const String & zoneName) - { - ZoneMap::iterator i; - PCZone * zone; - i = mZones.find(zoneName); - if (i != mZones.end()) - { - zone = i->second; - return zone; - } - return 0; // couldn't find the zone - } - - void PCZSceneManager::setZoneGeometry(const String & zoneName, - PCZSceneNode * parentNode, - const String & filename) - { - ZoneMap::iterator i; - PCZone * zone; - i = mZones.find(zoneName); - if (i != mZones.end()) - { - zone = i->second; - zone->setZoneGeometry( filename, parentNode ); - return; - } - - } - - SceneNode* PCZSceneManager::createSceneNodeImpl(void) - { - return OGRE_NEW PCZSceneNode(this); - } - - SceneNode* PCZSceneManager::createSceneNodeImpl(const String& name) - { - return OGRE_NEW PCZSceneNode(this, name); - } + newZone = mZoneFactoryManager->createPCZone(this, zoneTypeName, zoneName); + // add to the global list of zones + mZones[newZone->getName()] = newZone; + if (filename != "none") + { + // set the zone geometry + newZone->setZoneGeometry(filename, parentNode); + } + + return newZone; + } + + /* Get a zone by name */ + PCZone * PCZSceneManager::getZoneByName(const String & zoneName) + { + ZoneMap::iterator i; + PCZone * zone; + i = mZones.find(zoneName); + if (i != mZones.end()) + { + zone = i->second; + return zone; + } + return 0; // couldn't find the zone + } + + void PCZSceneManager::setZoneGeometry(const String & zoneName, + PCZSceneNode * parentNode, + const String & filename) + { + ZoneMap::iterator i; + PCZone * zone; + i = mZones.find(zoneName); + if (i != mZones.end()) + { + zone = i->second; + zone->setZoneGeometry( filename, parentNode ); + return; + } + + } + + SceneNode* PCZSceneManager::createSceneNodeImpl(void) + { + return OGRE_NEW PCZSceneNode(this); + } + + SceneNode* PCZSceneManager::createSceneNodeImpl(const String& name) + { + return OGRE_NEW PCZSceneNode(this, name); + } SceneNode * PCZSceneManager::createSceneNode( void ) { SceneNode * on = createSceneNodeImpl(); mSceneNodes[ on->getName() ] = on; - // create any zone-specific data necessary - createZoneSpecificNodeData((PCZSceneNode*)on); - // return pointer to the node + // create any zone-specific data necessary + createZoneSpecificNodeData((PCZSceneNode*)on); + // return pointer to the node return on; } @@ -351,38 +351,38 @@ namespace Ogre } SceneNode * on = createSceneNodeImpl( name ); mSceneNodes[ on->getName() ] = on; - // create any zone-specific data necessary - createZoneSpecificNodeData((PCZSceneNode*)on); - // return pointer to the node + // create any zone-specific data necessary + createZoneSpecificNodeData((PCZSceneNode*)on); + // return pointer to the node return on; } // Create a camera for the scene Camera * PCZSceneManager::createCamera( const String &name ) { - // Check name not used - if (mCameras.find(name) != mCameras.end()) - { - OGRE_EXCEPT( - Exception::ERR_DUPLICATE_ITEM, - "A camera with the name " + name + " already exists", - "PCZSceneManager::createCamera" ); - } + // Check name not used + if (mCameras.find(name) != mCameras.end()) + { + OGRE_EXCEPT( + Exception::ERR_DUPLICATE_ITEM, + "A camera with the name " + name + " already exists", + "PCZSceneManager::createCamera" ); + } Camera * c = OGRE_NEW PCZCamera( name, this ); mCameras.insert( CameraList::value_type( name, c ) ); - // create visible bounds aab map entry - mCamVisibleObjectsMap[c] = VisibleObjectsBoundsInfo(); - - // tell all the zones about the new camera - ZoneMap::iterator i; - PCZone * zone; - for (i = mZones.begin(); i != mZones.end(); i++) - { - zone = i->second; - zone->notifyCameraCreated( c ); - } + // create visible bounds aab map entry + mCamVisibleObjectsMap[c] = VisibleObjectsBoundsInfo(); + + // tell all the zones about the new camera + ZoneMap::iterator i; + PCZone * zone; + for (i = mZones.begin(); i != mZones.end(); i++) + { + zone = i->second; + zone->notifyCameraCreated( c ); + } return c; } @@ -393,225 +393,225 @@ namespace Ogre SceneNode * on = ( getSceneNode( name ) ); if ( on != 0 ) - { + { // destroy the node destroySceneNode( on ); - } + } } // Destroy a scene node void PCZSceneManager::destroySceneNode(SceneNode* sn) { if ( sn != 0 ) - { - // remove references to the node from zones + { + // remove references to the node from zones removeSceneNode( sn ); // destroy the node - SceneManager::destroySceneNode( sn->getName() ); - } - } - - //----------------------------------------------------------------------- - void PCZSceneManager::clearScene(void) - { - destroyAllStaticGeometry(); - destroyAllMovableObjects(); - - // Clear root node of all children - getRootSceneNode()->removeAllChildren(); - getRootSceneNode()->detachAllObjects(); - - // Delete all SceneNodes, except root that is - for (SceneNodeList::iterator i = mSceneNodes.begin(); - i != mSceneNodes.end(); ++i) - { - OGRE_DELETE i->second; - } - mSceneNodes.clear(); - mAutoTrackingSceneNodes.clear(); - - // delete all the zones - for (ZoneMap::iterator j = mZones.begin(); - j != mZones.end(); ++j) - { - OGRE_DELETE j->second; - } - mZones.clear(); - mDefaultZone = 0; - - // Clear animations - destroyAllAnimations(); - - // Remove sky nodes since they've been deleted - mSkyBoxNode = mSkyPlaneNode = mSkyDomeNode = 0; - mSkyBoxEnabled = mSkyPlaneEnabled = mSkyDomeEnabled = false; - - // Clear render queue, empty completely - if (mRenderQueue) - mRenderQueue->clear(true); - - // re-initialize + SceneManager::destroySceneNode( sn->getName() ); + } + } + + //----------------------------------------------------------------------- + void PCZSceneManager::clearScene(void) + { + destroyAllStaticGeometry(); + destroyAllMovableObjects(); + + // Clear root node of all children + getRootSceneNode()->removeAllChildren(); + getRootSceneNode()->detachAllObjects(); + + // Delete all SceneNodes, except root that is + for (SceneNodeList::iterator i = mSceneNodes.begin(); + i != mSceneNodes.end(); ++i) + { + OGRE_DELETE i->second; + } + mSceneNodes.clear(); + mAutoTrackingSceneNodes.clear(); + + // delete all the zones + for (ZoneMap::iterator j = mZones.begin(); + j != mZones.end(); ++j) + { + OGRE_DELETE j->second; + } + mZones.clear(); + mDefaultZone = 0; + + // Clear animations + destroyAllAnimations(); + + // Remove sky nodes since they've been deleted + mSkyBoxNode = mSkyPlaneNode = mSkyDomeNode = 0; + mSkyBoxEnabled = mSkyPlaneEnabled = mSkyDomeEnabled = false; + + // Clear render queue, empty completely + if (mRenderQueue) + mRenderQueue->clear(true); + + // re-initialize init(mDefaultZoneTypeName, mDefaultZoneFileName); - } - - /** Overridden from SceneManager */ - void PCZSceneManager::setWorldGeometryRenderQueue(uint8 qid) - { - // tell all the zones about the new WorldGeometryRenderQueue - ZoneMap::iterator i; - PCZone * zone; - for (i = mZones.begin(); i != mZones.end(); i++) - { - zone = i->second; - zone->notifyWorldGeometryRenderQueue( qid ); - } - // call the regular scene manager version - SceneManager::setWorldGeometryRenderQueue(qid); - - } - /** Overridden from SceneManager */ + } + + /** Overridden from SceneManager */ + void PCZSceneManager::setWorldGeometryRenderQueue(uint8 qid) + { + // tell all the zones about the new WorldGeometryRenderQueue + ZoneMap::iterator i; + PCZone * zone; + for (i = mZones.begin(); i != mZones.end(); i++) + { + zone = i->second; + zone->notifyWorldGeometryRenderQueue( qid ); + } + // call the regular scene manager version + SceneManager::setWorldGeometryRenderQueue(qid); + + } + /** Overridden from SceneManager */ void PCZSceneManager::_renderScene(Camera* cam, Viewport *vp, bool includeOverlays) { - // notify all the zones that a scene render is starting - ZoneMap::iterator i; - PCZone * zone; - for (i = mZones.begin(); i != mZones.end(); i++) - { - zone = i->second; - zone->notifyBeginRenderScene(); - } + // notify all the zones that a scene render is starting + ZoneMap::iterator i; + PCZone * zone; + for (i = mZones.begin(); i != mZones.end(); i++) + { + zone = i->second; + zone->notifyBeginRenderScene(); + } - // do the regular _renderScene + // do the regular _renderScene SceneManager::_renderScene(cam, vp, includeOverlays); } - /* enable/disable sky rendering */ - void PCZSceneManager::enableSky(bool onoff) - { - if (mSkyBoxNode) - { - mSkyBoxEnabled = onoff; - } - else if (mSkyDomeNode) - { - mSkyDomeEnabled = onoff; - } - else if (mSkyPlaneNode) - { - mSkyPlaneEnabled = onoff; - } - } - - /* Set the zone which contains the sky node */ - void PCZSceneManager::setSkyZone(PCZone * zone) - { - if (zone == 0) - { - // if no zone specified, use default zone - zone = mDefaultZone; - } - if (mSkyBoxNode) - { - ((PCZSceneNode*)mSkyBoxNode)->setHomeZone(zone); - ((PCZSceneNode*)mSkyBoxNode)->anchorToHomeZone(zone); - zone->setHasSky(true); - } - if (mSkyDomeNode) - { - ((PCZSceneNode*)mSkyDomeNode)->setHomeZone(zone); - ((PCZSceneNode*)mSkyDomeNode)->anchorToHomeZone(zone); - zone->setHasSky(true); - } - if (mSkyPlaneNode) - { - ((PCZSceneNode*)mSkyPlaneNode)->setHomeZone(zone); - ((PCZSceneNode*)mSkyPlaneNode)->anchorToHomeZone(zone); - zone->setHasSky(true); - } - - } - - //----------------------------------------------------------------------- - // THIS IS THE MAIN LOOP OF THE MANAGER - //----------------------------------------------------------------------- - /* _updateSceneGraph does several things now: - 1) standard scene graph update (transform all nodes in the node tree) - 2) update the spatial data for all zones (& portals in the zones) - 3) Update the PCZSNMap entry for every scene node - */ - void PCZSceneManager::_updateSceneGraph( Camera * cam ) - { - // First do the standard scene graph update - SceneManager::_updateSceneGraph( cam ); - // check for portal zone-related changes (portals intersecting other portals) - _updatePortalZoneData(); - // mark nodes dirty base on portals that changed. - _dirtyNodeByMovingPortals(); - // update all scene nodes - _updatePCZSceneNodes(); - // calculate zones affected by each light - _calcZonesAffectedByLights(cam); - // clear update flags at end so user triggered updated are - // not cleared prematurely - _clearAllZonesPortalUpdateFlag(); - } - - /** Update the zone data for every zone portal in the scene */ - - void PCZSceneManager::_updatePortalZoneData(void) - { - PCZone * zone; - ZoneMap::iterator zit = mZones.begin(); - - while ( zit != mZones.end() ) - { - zone = zit->second; - // this callchecks for portal zone changes & applies zone data changes as necessary - zone->updatePortalsZoneData(); - // proceed to next zone in the list - ++zit; - } - } - - /** Mark nodes dirty for every zone with moving portal in the scene */ - void PCZSceneManager::_dirtyNodeByMovingPortals(void) - { - PCZone * zone; - ZoneMap::iterator zit = mZones.begin(); - - while ( zit != mZones.end() ) - { - zone = zit->second; - // this call mark nodes dirty base on moving portals - zone->dirtyNodeByMovingPortals(); - // proceed to next zone in the list - ++zit; - } - } - - /* Update all PCZSceneNodes. - */ - void PCZSceneManager::_updatePCZSceneNodes(void) - { - SceneNodeList::iterator it = mSceneNodes.begin(); - PCZSceneNode * pczsn; - - while ( it != mSceneNodes.end() ) - { - pczsn = (PCZSceneNode*)(it->second); - if (pczsn->isMoved() && pczsn->isEnabled()) - { - // Update a single entry - _updatePCZSceneNode(pczsn); - - // reset moved state. - pczsn->setMoved(false); - } - // proceed to next entry in the list - ++it; - } - } + /* enable/disable sky rendering */ + void PCZSceneManager::enableSky(bool onoff) + { + if (mSkyBoxNode) + { + mSkyBoxEnabled = onoff; + } + else if (mSkyDomeNode) + { + mSkyDomeEnabled = onoff; + } + else if (mSkyPlaneNode) + { + mSkyPlaneEnabled = onoff; + } + } + + /* Set the zone which contains the sky node */ + void PCZSceneManager::setSkyZone(PCZone * zone) + { + if (zone == 0) + { + // if no zone specified, use default zone + zone = mDefaultZone; + } + if (mSkyBoxNode) + { + ((PCZSceneNode*)mSkyBoxNode)->setHomeZone(zone); + ((PCZSceneNode*)mSkyBoxNode)->anchorToHomeZone(zone); + zone->setHasSky(true); + } + if (mSkyDomeNode) + { + ((PCZSceneNode*)mSkyDomeNode)->setHomeZone(zone); + ((PCZSceneNode*)mSkyDomeNode)->anchorToHomeZone(zone); + zone->setHasSky(true); + } + if (mSkyPlaneNode) + { + ((PCZSceneNode*)mSkyPlaneNode)->setHomeZone(zone); + ((PCZSceneNode*)mSkyPlaneNode)->anchorToHomeZone(zone); + zone->setHasSky(true); + } + + } + + //----------------------------------------------------------------------- + // THIS IS THE MAIN LOOP OF THE MANAGER + //----------------------------------------------------------------------- + /* _updateSceneGraph does several things now: + 1) standard scene graph update (transform all nodes in the node tree) + 2) update the spatial data for all zones (& portals in the zones) + 3) Update the PCZSNMap entry for every scene node + */ + void PCZSceneManager::_updateSceneGraph( Camera * cam ) + { + // First do the standard scene graph update + SceneManager::_updateSceneGraph( cam ); + // check for portal zone-related changes (portals intersecting other portals) + _updatePortalZoneData(); + // mark nodes dirty base on portals that changed. + _dirtyNodeByMovingPortals(); + // update all scene nodes + _updatePCZSceneNodes(); + // calculate zones affected by each light + _calcZonesAffectedByLights(cam); + // clear update flags at end so user triggered updated are + // not cleared prematurely + _clearAllZonesPortalUpdateFlag(); + } + + /** Update the zone data for every zone portal in the scene */ + + void PCZSceneManager::_updatePortalZoneData(void) + { + PCZone * zone; + ZoneMap::iterator zit = mZones.begin(); + + while ( zit != mZones.end() ) + { + zone = zit->second; + // this callchecks for portal zone changes & applies zone data changes as necessary + zone->updatePortalsZoneData(); + // proceed to next zone in the list + ++zit; + } + } + + /** Mark nodes dirty for every zone with moving portal in the scene */ + void PCZSceneManager::_dirtyNodeByMovingPortals(void) + { + PCZone * zone; + ZoneMap::iterator zit = mZones.begin(); + + while ( zit != mZones.end() ) + { + zone = zit->second; + // this call mark nodes dirty base on moving portals + zone->dirtyNodeByMovingPortals(); + // proceed to next zone in the list + ++zit; + } + } + + /* Update all PCZSceneNodes. + */ + void PCZSceneManager::_updatePCZSceneNodes(void) + { + SceneNodeList::iterator it = mSceneNodes.begin(); + PCZSceneNode * pczsn; + + while ( it != mSceneNodes.end() ) + { + pczsn = (PCZSceneNode*)(it->second); + if (pczsn->isMoved() && pczsn->isEnabled()) + { + // Update a single entry + _updatePCZSceneNode(pczsn); + + // reset moved state. + pczsn->setMoved(false); + } + // proceed to next entry in the list + ++it; + } + } /* */ @@ -619,311 +619,311 @@ namespace Ogre { MovableObjectCollection* lights = getMovableObjectCollection(PCZLightFactory::FACTORY_TYPE_NAME); - { + { OGRE_LOCK_MUTEX(lights->mutex); - MovableObjectIterator it(lights->map.begin(), lights->map.end()); - - while(it.hasMoreElements()) - { - PCZLight* l = static_cast(it.getNext()); - if(l->getNeedsUpdate()) - { - // only update if necessary - l->updateZones(((PCZSceneNode*)(cam->getParentSceneNode()))->getHomeZone(), mFrameCount); - } - // clear update flag - l->clearNeedsUpdate(); + MovableObjectIterator it(lights->map.begin(), lights->map.end()); + + while(it.hasMoreElements()) + { + PCZLight* l = static_cast(it.getNext()); + if(l->getNeedsUpdate()) + { + // only update if necessary + l->updateZones(((PCZSceneNode*)(cam->getParentSceneNode()))->getHomeZone(), mFrameCount); + } + // clear update flag + l->clearNeedsUpdate(); } } } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- // Update all the zone info for a given node. This function - // makes sure the home zone of the node is correct, and references - // to any zones it is visiting are added and a reference to the - // node is added to the visitor lists of any zone it is visiting. - // - void PCZSceneManager::_updatePCZSceneNode( PCZSceneNode * pczsn ) + // makes sure the home zone of the node is correct, and references + // to any zones it is visiting are added and a reference to the + // node is added to the visitor lists of any zone it is visiting. + // + void PCZSceneManager::_updatePCZSceneNode( PCZSceneNode * pczsn ) { - // Skip if root Zone has been destroyed (shutdown conditions) - if (!mDefaultZone) - return; + // Skip if root Zone has been destroyed (shutdown conditions) + if (!mDefaultZone) + return; - // Skip if the node is the sceneroot node - if (pczsn == getRootSceneNode()) - return; + // Skip if the node is the sceneroot node + if (pczsn == getRootSceneNode()) + return; - // clear all references to visiting zones - pczsn->clearNodeFromVisitedZones(); + // clear all references to visiting zones + pczsn->clearNodeFromVisitedZones(); // Find the current home zone of the node associated with the pczsn entry. - _updateHomeZone( pczsn, false ); - - /* The following function does the following: - * 1) Check all portals in the home zone - if the node is touching the portal - * then add the node to the connected zone as a visitor - * 2) Recurse into visited zones in case the node spans several zones - */ - // (recursively) check each portal of home zone to see if the node is touching - if (pczsn->getHomeZone() && - pczsn->allowedToVisit() == true) - { - pczsn->getHomeZone()->_checkNodeAgainstPortals(pczsn, 0); - } + _updateHomeZone( pczsn, false ); + + /* The following function does the following: + * 1) Check all portals in the home zone - if the node is touching the portal + * then add the node to the connected zone as a visitor + * 2) Recurse into visited zones in case the node spans several zones + */ + // (recursively) check each portal of home zone to see if the node is touching + if (pczsn->getHomeZone() && + pczsn->allowedToVisit() == true) + { + pczsn->getHomeZone()->_checkNodeAgainstPortals(pczsn, 0); + } - // update zone-specific data for the node for any zones that require it - pczsn->updateZoneData(); + // update zone-specific data for the node for any zones that require it + pczsn->updateZoneData(); } /** Removes all references to the node from every zone in the scene. */ void PCZSceneManager::removeSceneNode( SceneNode * sn ) { - // Skip if mDefaultZone has been destroyed (shutdown conditions) - if (!mDefaultZone) - return; + // Skip if mDefaultZone has been destroyed (shutdown conditions) + if (!mDefaultZone) + return; - PCZSceneNode * pczsn = (PCZSceneNode*)sn; + PCZSceneNode * pczsn = (PCZSceneNode*)sn; - // clear all references to the node in visited zones - pczsn->clearNodeFromVisitedZones(); + // clear all references to the node in visited zones + pczsn->clearNodeFromVisitedZones(); // tell the node it's not in a zone pczsn->setHomeZone(0); } - // Set the home zone for a node - void PCZSceneManager::addPCZSceneNode(PCZSceneNode * sn, PCZone * homeZone) - { - // set the home zone - sn->setHomeZone(homeZone); - // add the node - homeZone->_addNode(sn); - } - - //----------------------------------------------------------------------- - /* Create a zone with the given name and parent zone */ - PCZone * PCZSceneManager::createZone(const String& zoneType, const String& instanceName) - { - if (mZones.find(instanceName) != mZones.end()) - { - OGRE_EXCEPT( - Exception::ERR_DUPLICATE_ITEM, - "A zone with the name " + instanceName + " already exists", - "PCZSceneManager::createZone" ); - } - PCZone * newZone = mZoneFactoryManager->createPCZone(this, zoneType, instanceName); - if (newZone) - { - // add to the global list of zones - mZones[instanceName] = newZone; + // Set the home zone for a node + void PCZSceneManager::addPCZSceneNode(PCZSceneNode * sn, PCZone * homeZone) + { + // set the home zone + sn->setHomeZone(homeZone); + // add the node + homeZone->_addNode(sn); + } + + //----------------------------------------------------------------------- + /* Create a zone with the given name and parent zone */ + PCZone * PCZSceneManager::createZone(const String& zoneType, const String& instanceName) + { + if (mZones.find(instanceName) != mZones.end()) + { + OGRE_EXCEPT( + Exception::ERR_DUPLICATE_ITEM, + "A zone with the name " + instanceName + " already exists", + "PCZSceneManager::createZone" ); + } + PCZone * newZone = mZoneFactoryManager->createPCZone(this, zoneType, instanceName); + if (newZone) + { + // add to the global list of zones + mZones[instanceName] = newZone; if (newZone->requiresZoneSpecificNodeData()) { createZoneSpecificNodeData(newZone); } - } - return newZone; - } - - /* destroy an existing zone within the scene */ - /* if destroySceneNodes is true, then all nodes which have the destroyed - zone as their homezone are desroyed too. If destroySceneNodes is false - then all scene nodes which have the zone as their homezone will have - their homezone pointer set to 0, which will allow them to be re-assigned - either by the user or via the automatic re-assignment routine */ - void PCZSceneManager::destroyZone(PCZone* zone, bool destroySceneNodes) - { - // need to remove this zone from all lights affected zones list, - // otherwise next frame _calcZonesAffectedByLights will call PCZLight::getNeedsUpdate() - // which will try to access the zone pointer and will cause an access violation - MovableObjectCollection* lights = - getMovableObjectCollection(PCZLightFactory::FACTORY_TYPE_NAME); - { + } + return newZone; + } + + /* destroy an existing zone within the scene */ + /* if destroySceneNodes is true, then all nodes which have the destroyed + zone as their homezone are desroyed too. If destroySceneNodes is false + then all scene nodes which have the zone as their homezone will have + their homezone pointer set to 0, which will allow them to be re-assigned + either by the user or via the automatic re-assignment routine */ + void PCZSceneManager::destroyZone(PCZone* zone, bool destroySceneNodes) + { + // need to remove this zone from all lights affected zones list, + // otherwise next frame _calcZonesAffectedByLights will call PCZLight::getNeedsUpdate() + // which will try to access the zone pointer and will cause an access violation + MovableObjectCollection* lights = + getMovableObjectCollection(PCZLightFactory::FACTORY_TYPE_NAME); + { OGRE_LOCK_MUTEX(lights->mutex); // Is locking necessary in destroyZone? I don't know.. - MovableObjectIterator it(lights->map.begin(), lights->map.end()); - - while(it.hasMoreElements()) - { - PCZLight* l = static_cast(it.getNext()); - if(l) - { - // no need to check, this function does that anyway. if exists, is erased. - l->removeZoneFromAffectedZonesList(zone); - } - } - } - // if not destroying scene nodes, then make sure any nodes who have - // this zone as homezone are set to have 0 for a homezone - for (SceneNodeList::iterator i = mSceneNodes.begin(); - i != mSceneNodes.end(); ++i) - { - PCZSceneNode * pczsn = (PCZSceneNode*)(i->second); - if (!destroySceneNodes) - { - if (pczsn->getHomeZone() == zone) - { - pczsn->setHomeZone(0); - } - } - // reset all node visitor lists - // note, it might be more efficient to only do this to nodes which - // are actually visiting the zone being destroyed, but visitor lists - // get cleared every frame anyway, so it's not THAT big a deal. - pczsn->clearNodeFromVisitedZones(); - } - - ZoneMap::iterator it; - it = mZones.find(zone->getName()); - if (it != mZones.end()) - { - mZones.erase(zone->getName()); - } - OGRE_DELETE zone; - } + MovableObjectIterator it(lights->map.begin(), lights->map.end()); + + while(it.hasMoreElements()) + { + PCZLight* l = static_cast(it.getNext()); + if(l) + { + // no need to check, this function does that anyway. if exists, is erased. + l->removeZoneFromAffectedZonesList(zone); + } + } + } + // if not destroying scene nodes, then make sure any nodes who have + // this zone as homezone are set to have 0 for a homezone + for (SceneNodeList::iterator i = mSceneNodes.begin(); + i != mSceneNodes.end(); ++i) + { + PCZSceneNode * pczsn = (PCZSceneNode*)(i->second); + if (!destroySceneNodes) + { + if (pczsn->getHomeZone() == zone) + { + pczsn->setHomeZone(0); + } + } + // reset all node visitor lists + // note, it might be more efficient to only do this to nodes which + // are actually visiting the zone being destroyed, but visitor lists + // get cleared every frame anyway, so it's not THAT big a deal. + pczsn->clearNodeFromVisitedZones(); + } + + ZoneMap::iterator it; + it = mZones.find(zone->getName()); + if (it != mZones.end()) + { + mZones.erase(zone->getName()); + } + OGRE_DELETE zone; + } /* The following function checks if a node has left it's current home zone. - * This is done by checking each portal in the zone. If the node has crossed - * the portal, then the current zone is no longer the home zone of the node. The - * function then recurses into the connected zones. Once a zone is found where - * the node does NOT cross out through a portal, that zone is the new home zone. + * This is done by checking each portal in the zone. If the node has crossed + * the portal, then the current zone is no longer the home zone of the node. The + * function then recurses into the connected zones. Once a zone is found where + * the node does NOT cross out through a portal, that zone is the new home zone. * When this function is done, the node should have the correct home zone already - * set. A pointer is returned to this zone as well. - * - * NOTE: If the node does not have a home zone when this function is called on it, - * the function will do its best to find the proper zone for the node using - * bounding box volume testing. This CAN fail to find the correct zone in - * some scenarios, so it is best for the user to EXPLICITLY set the home - * zone of the node when the node is added to the scene using - * PCZSceneNode::setHomeZone() - */ + * set. A pointer is returned to this zone as well. + * + * NOTE: If the node does not have a home zone when this function is called on it, + * the function will do its best to find the proper zone for the node using + * bounding box volume testing. This CAN fail to find the correct zone in + * some scenarios, so it is best for the user to EXPLICITLY set the home + * zone of the node when the node is added to the scene using + * PCZSceneNode::setHomeZone() + */ void PCZSceneManager::_updateHomeZone( PCZSceneNode * pczsn, bool allowBackTouches ) { - // Skip if root PCZoneTree has been destroyed (shutdown conditions) - if (!mDefaultZone) - return; - - PCZone * startzone; - PCZone * newHomeZone; - - // start with current home zone of the node - startzone = pczsn->getHomeZone(); - - if (startzone) - { - if (!pczsn->isAnchored()) - { - newHomeZone = startzone->updateNodeHomeZone(pczsn, false); - } - else - { - newHomeZone = startzone; - } - - if (newHomeZone != startzone) - { - // add the node to the home zone - newHomeZone->_addNode(pczsn); - } - } - else - { - // the node hasn't had it's home zone set yet, so do our best to - // find the home zone using volume testing. - Vector3 nodeCenter = pczsn->_getDerivedPosition(); - PCZone * bestZone = findZoneForPoint(nodeCenter); - // set the best zone as the node's home zone - pczsn->setHomeZone(bestZone); - // add the node to the zone - bestZone->_addNode(pczsn); - } - - return; - - } - - /* Find the best (smallest) zone that contains a point - */ - PCZone * PCZSceneManager::findZoneForPoint(Vector3 & point) - { - PCZone * zone; - PCZone * bestZone = mDefaultZone; - Real bestVolume = Ogre::Math::POS_INFINITY; - - ZoneMap::iterator zit = mZones.begin(); - - while ( zit != mZones.end() ) - { - zone = zit->second; - AxisAlignedBox aabb; - zone->getAABB(aabb); - SceneNode * enclosureNode = zone->getEnclosureNode(); - if (enclosureNode != 0) - { - // since this is the "local" AABB, add in world translation of the enclosure node - aabb.setMinimum(aabb.getMinimum() + enclosureNode->_getDerivedPosition()); - aabb.setMaximum(aabb.getMaximum() + enclosureNode->_getDerivedPosition()); - } - if (aabb.contains(point)) - { - if (aabb.volume() < bestVolume) - { - // this zone is "smaller" than the current best zone, so make it - // the new best zone - bestZone = zone; - bestVolume = aabb.volume(); - } - } - // proceed to next zone in the list - ++zit; - } - return bestZone; - } - - // create any zone-specific data necessary for all zones for the given node - void PCZSceneManager::createZoneSpecificNodeData(PCZSceneNode * node) - { - ZoneMap::iterator i; - PCZone * zone; - for (i = mZones.begin(); i != mZones.end(); i++) - { - zone = i->second; - if (zone->requiresZoneSpecificNodeData()) - { - zone->createNodeZoneData(node); - } - } - } - - // create any zone-specific data necessary for all nodes for the given zone - void PCZSceneManager::createZoneSpecificNodeData(PCZone * zone) - { - SceneNodeList::iterator it = mSceneNodes.begin(); - PCZSceneNode * pczsn; - if (zone->requiresZoneSpecificNodeData()) - { - while ( it != mSceneNodes.end() ) - { - pczsn = (PCZSceneNode*)(it->second); - // create zone specific data for the node - zone->createNodeZoneData(pczsn); - // proceed to next entry in the list - ++it; - } - } - } - - // set the home zone for a scene node - void PCZSceneManager::setNodeHomeZone(SceneNode *node, PCZone *zone) - { - // cast the Ogre::SceneNode to a PCZSceneNode - PCZSceneNode * pczsn = (PCZSceneNode*)node; - pczsn->setHomeZone(zone); - } - - // (optional) post processing for any scene node found visible for the frame + // Skip if root PCZoneTree has been destroyed (shutdown conditions) + if (!mDefaultZone) + return; + + PCZone * startzone; + PCZone * newHomeZone; + + // start with current home zone of the node + startzone = pczsn->getHomeZone(); + + if (startzone) + { + if (!pczsn->isAnchored()) + { + newHomeZone = startzone->updateNodeHomeZone(pczsn, false); + } + else + { + newHomeZone = startzone; + } + + if (newHomeZone != startzone) + { + // add the node to the home zone + newHomeZone->_addNode(pczsn); + } + } + else + { + // the node hasn't had it's home zone set yet, so do our best to + // find the home zone using volume testing. + Vector3 nodeCenter = pczsn->_getDerivedPosition(); + PCZone * bestZone = findZoneForPoint(nodeCenter); + // set the best zone as the node's home zone + pczsn->setHomeZone(bestZone); + // add the node to the zone + bestZone->_addNode(pczsn); + } + + return; + + } + + /* Find the best (smallest) zone that contains a point + */ + PCZone * PCZSceneManager::findZoneForPoint(Vector3 & point) + { + PCZone * zone; + PCZone * bestZone = mDefaultZone; + Real bestVolume = Ogre::Math::POS_INFINITY; + + ZoneMap::iterator zit = mZones.begin(); + + while ( zit != mZones.end() ) + { + zone = zit->second; + AxisAlignedBox aabb; + zone->getAABB(aabb); + SceneNode * enclosureNode = zone->getEnclosureNode(); + if (enclosureNode != 0) + { + // since this is the "local" AABB, add in world translation of the enclosure node + aabb.setMinimum(aabb.getMinimum() + enclosureNode->_getDerivedPosition()); + aabb.setMaximum(aabb.getMaximum() + enclosureNode->_getDerivedPosition()); + } + if (aabb.contains(point)) + { + if (aabb.volume() < bestVolume) + { + // this zone is "smaller" than the current best zone, so make it + // the new best zone + bestZone = zone; + bestVolume = aabb.volume(); + } + } + // proceed to next zone in the list + ++zit; + } + return bestZone; + } + + // create any zone-specific data necessary for all zones for the given node + void PCZSceneManager::createZoneSpecificNodeData(PCZSceneNode * node) + { + ZoneMap::iterator i; + PCZone * zone; + for (i = mZones.begin(); i != mZones.end(); i++) + { + zone = i->second; + if (zone->requiresZoneSpecificNodeData()) + { + zone->createNodeZoneData(node); + } + } + } + + // create any zone-specific data necessary for all nodes for the given zone + void PCZSceneManager::createZoneSpecificNodeData(PCZone * zone) + { + SceneNodeList::iterator it = mSceneNodes.begin(); + PCZSceneNode * pczsn; + if (zone->requiresZoneSpecificNodeData()) + { + while ( it != mSceneNodes.end() ) + { + pczsn = (PCZSceneNode*)(it->second); + // create zone specific data for the node + zone->createNodeZoneData(pczsn); + // proceed to next entry in the list + ++it; + } + } + } + + // set the home zone for a scene node + void PCZSceneManager::setNodeHomeZone(SceneNode *node, PCZone *zone) + { + // cast the Ogre::SceneNode to a PCZSceneNode + PCZSceneNode * pczsn = (PCZSceneNode*)node; + pczsn->setHomeZone(zone); + } + + // (optional) post processing for any scene node found visible for the frame void PCZSceneManager::_alertVisibleObjects( void ) { OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, @@ -944,300 +944,300 @@ namespace Ogre //----------------------------------------------------------------------- Light* PCZSceneManager::createLight(const String& name) { - return static_cast( - createMovableObject(name, PCZLightFactory::FACTORY_TYPE_NAME)); - } - //----------------------------------------------------------------------- - Light* PCZSceneManager::getLight(const String& name) const - { - return static_cast( - getMovableObject(name, PCZLightFactory::FACTORY_TYPE_NAME)); - } - //----------------------------------------------------------------------- - bool PCZSceneManager::hasLight(const String& name) const - { - return hasMovableObject(name, PCZLightFactory::FACTORY_TYPE_NAME); - } - //----------------------------------------------------------------------- - void PCZSceneManager::destroyLight(const String& name) - { - destroyMovableObject(name, PCZLightFactory::FACTORY_TYPE_NAME); - } - //----------------------------------------------------------------------- - void PCZSceneManager::destroyAllLights(void) - { - destroyAllMovableObjectsByType(PCZLightFactory::FACTORY_TYPE_NAME); - } - //--------------------------------------------------------------------- - void PCZSceneManager::findLightsAffectingFrustum(const Camera* camera) - { - // Similar to the basic SceneManager, we iterate through - // lights to see which ones affect the frustum. However, - // since we have camera & lights partitioned by zones, - // we can check only those lights which either affect the - // zone the camera is in, or affect zones which are visible to - // the camera - - MovableObjectCollection* lights = - getMovableObjectCollection(PCZLightFactory::FACTORY_TYPE_NAME); - - - { + return static_cast( + createMovableObject(name, PCZLightFactory::FACTORY_TYPE_NAME)); + } + //----------------------------------------------------------------------- + Light* PCZSceneManager::getLight(const String& name) const + { + return static_cast( + getMovableObject(name, PCZLightFactory::FACTORY_TYPE_NAME)); + } + //----------------------------------------------------------------------- + bool PCZSceneManager::hasLight(const String& name) const + { + return hasMovableObject(name, PCZLightFactory::FACTORY_TYPE_NAME); + } + //----------------------------------------------------------------------- + void PCZSceneManager::destroyLight(const String& name) + { + destroyMovableObject(name, PCZLightFactory::FACTORY_TYPE_NAME); + } + //----------------------------------------------------------------------- + void PCZSceneManager::destroyAllLights(void) + { + destroyAllMovableObjectsByType(PCZLightFactory::FACTORY_TYPE_NAME); + } + //--------------------------------------------------------------------- + void PCZSceneManager::findLightsAffectingFrustum(const Camera* camera) + { + // Similar to the basic SceneManager, we iterate through + // lights to see which ones affect the frustum. However, + // since we have camera & lights partitioned by zones, + // we can check only those lights which either affect the + // zone the camera is in, or affect zones which are visible to + // the camera + + MovableObjectCollection* lights = + getMovableObjectCollection(PCZLightFactory::FACTORY_TYPE_NAME); + + + { OGRE_LOCK_MUTEX(lights->mutex); - // Pre-allocate memory - mTestLightInfos.clear(); - mTestLightInfos.reserve(lights->map.size()); - - MovableObjectIterator it(lights->map.begin(), lights->map.end()); - - while(it.hasMoreElements()) - { - PCZLight* l = static_cast(it.getNext()); - if (l->isVisible() && - l->affectsVisibleZone()) - { - LightInfo lightInfo; - lightInfo.light = l; - lightInfo.type = l->getType(); - if (lightInfo.type == Light::LT_DIRECTIONAL) - { - // Always visible - lightInfo.position = Vector3::ZERO; - lightInfo.range = 0; - mTestLightInfos.push_back(lightInfo); - } - else - { - // NB treating spotlight as point for simplicity - // Just see if the lights attenuation range is within the frustum - lightInfo.range = l->getAttenuationRange(); - lightInfo.position = l->getDerivedPosition(); - Sphere sphere(lightInfo.position, lightInfo.range); - if (camera->isVisible(sphere)) - { - mTestLightInfos.push_back(lightInfo); - } - } - } - } - } // release lock on lights collection - - // from here on down this function is same as Ogre::SceneManager - - // Update lights affecting frustum if changed - if (mCachedLightInfos != mTestLightInfos) - { - mLightsAffectingFrustum.resize(mTestLightInfos.size()); - LightInfoList::const_iterator i; - LightList::iterator j = mLightsAffectingFrustum.begin(); - for (i = mTestLightInfos.begin(); i != mTestLightInfos.end(); ++i, ++j) - { - *j = i->light; - // add cam distance for sorting if texture shadows - if (isShadowTechniqueTextureBased()) - { - (*j)->_calcTempSquareDist(camera->getDerivedPosition()); - } - } - - // Sort the lights if using texture shadows, since the first 'n' will be - // used to generate shadow textures and we should pick the most appropriate - if (isShadowTechniqueTextureBased()) - { - // Allow a ShadowListener to override light sorting - // Reverse iterate so last takes precedence - bool overridden = false; - for (ListenerList::reverse_iterator ri = mListeners.rbegin(); - ri != mListeners.rend(); ++ri) - { - overridden = (*ri)->sortLightsAffectingFrustum(mLightsAffectingFrustum); - if (overridden) - break; - } - if (!overridden) - { - // default sort (stable to preserve directional light ordering - std::stable_sort( - mLightsAffectingFrustum.begin(), mLightsAffectingFrustum.end(), - lightsForShadowTextureLess()); - } - - } - - // Use swap instead of copy operator for efficiently - mCachedLightInfos.swap(mTestLightInfos); - - // notify light dirty, so all movable objects will re-populate - // their light list next time - _notifyLightsDirty(); - } - - } - //--------------------------------------------------------------------- - void PCZSceneManager::ensureShadowTexturesCreated() - { - bool shadowTextureConfigDirty = mShadowTextureConfigDirty; - SceneManager::ensureShadowTexturesCreated(); - if (!shadowTextureConfigDirty) return; - - size_t count = mShadowTextureCameras.size(); - for (size_t i = 0; i < count; ++i) - { - PCZSceneNode* node = (PCZSceneNode*)mSceneRoot->createChildSceneNode( - mShadowTextureCameras[i]->getName()); - node->attachObject(mShadowTextureCameras[i]); - addPCZSceneNode(node, mDefaultZone); - } - } - //--------------------------------------------------------------------- - void PCZSceneManager::destroyShadowTextures(void) - { - size_t count = mShadowTextureCameras.size(); - for (size_t i = 0; i < count; ++i) - { - SceneNode* node = mShadowTextureCameras[i]->getParentSceneNode(); - mSceneRoot->removeAndDestroyChild(node->getName()); - } - SceneManager::destroyShadowTextures(); - } - //--------------------------------------------------------------------- - void PCZSceneManager::fireShadowTexturesPreCaster(Light* light, Camera* camera, size_t iteration) - { - PCZSceneNode* camNode = (PCZSceneNode*)camera->getParentSceneNode(); - - if (light->getType() == Light::LT_DIRECTIONAL) - { - if (camNode->getHomeZone() != mActiveCameraZone) - addPCZSceneNode(camNode, mActiveCameraZone); - } - else - { - PCZSceneNode* lightNode = (PCZSceneNode*)light->getParentSceneNode(); - assert(lightNode); - PCZone* lightZone = lightNode->getHomeZone(); - if (camNode->getHomeZone() != lightZone) - addPCZSceneNode(camNode, lightZone); - } - - SceneManager::fireShadowTexturesPreCaster(light, camera, iteration); - } - - /* Attempt to automatically connect unconnected portals to proper target zones - * by looking for matching portals in other zones which are at the same location - */ - void PCZSceneManager::connectPortalsToTargetZonesByLocation(void) - { - // go through every zone to find portals - ZoneMap::iterator i, iend; - PCZone* zone; - iend = mZones.end(); - bool foundMatch; - for (i = mZones.begin(); i != iend; i++) - { - zone = i->second; - // go through all the portals in the zone - Portal* portal; - PortalList::iterator pi, piend; - piend = zone->mPortals.end(); - for (pi = zone->mPortals.begin(); pi != piend; pi++) - { - portal = *pi; - //portal->updateDerivedValues(); - if (portal->getTargetZone() == 0) - { - // this is a portal without a connected zone - look for - // a matching portal in another zone - PCZone* zone2; - ZoneMap::iterator j= mZones.begin(); - foundMatch = false; - while (!foundMatch && j != mZones.end()) - { - zone2 = j->second; - if (zone2 != zone) // make sure we don't look in the same zone - { - Portal * portal2 = zone2->findMatchingPortal(portal); - if (portal2) - { - // found a match! - Ogre::LogManager::getSingletonPtr()->logMessage("Connecting portal "+portal->getName()+" to portal "+portal2->getName()); - foundMatch = true; - portal->setTargetZone(zone2); - portal->setTargetPortal(portal2); - portal2->setTargetZone(zone); - portal2->setTargetPortal(portal); - } - } - j++; - } - if (foundMatch == false) - { - // error, didn't find a matching portal! - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Could not find matching portal for portal " + portal->getName(), - "PCZSceneManager::connectPortalsToTargetZonesByLocation"); - - } - } - } - } - } - - // main visibility determination & render queue filling routine - // over-ridden from base/default scene manager. This is *the* - // main call. - void PCZSceneManager::_findVisibleObjects(Camera* cam, - VisibleObjectsBoundsInfo* visibleBounds, - bool onlyShadowCasters) - { - // clear the render queue - getRenderQueue()->clear(); - - // if we are re-rendering the scene again with the same camera, we can just use the cache. - // this helps post processing compositors. - unsigned long frameCount = Root::getSingleton().getNextFrameNumber(); - if (mLastActiveCamera == cam && mFrameCount == frameCount) - { - RenderQueue* queue = getRenderQueue(); - size_t count = mVisible.size(); - for (size_t i = 0; i < count; ++i) - { - ((PCZSceneNode*)mVisible[i])->_addToRenderQueue( - cam, queue, onlyShadowCasters, visibleBounds); - } - return; - } - - // increment the visibility frame counter - mFrameCount = frameCount; - mLastActiveCamera = cam; - - // clear the list of visible nodes - mVisible.clear(); - - // turn off sky - enableSky(false); - - // remove all extra culling planes - ((PCZCamera*)cam)->removeAllExtraCullingPlanes(); - - // update the camera - ((PCZCamera*)cam)->update(); - - // get the home zone of the camera - PCZone* cameraHomeZone = ((PCZSceneNode*)(cam->getParentSceneNode()))->getHomeZone(); - - // walk the zones, starting from the camera home zone, - // adding all visible scene nodes to the mVisibles list - cameraHomeZone->setLastVisibleFrame(mFrameCount); - cameraHomeZone->findVisibleNodes((PCZCamera*)cam, - mVisible, - getRenderQueue(), - visibleBounds, - onlyShadowCasters, - mDisplayNodes, - mShowBoundingBoxes); - } + // Pre-allocate memory + mTestLightInfos.clear(); + mTestLightInfos.reserve(lights->map.size()); + + MovableObjectIterator it(lights->map.begin(), lights->map.end()); + + while(it.hasMoreElements()) + { + PCZLight* l = static_cast(it.getNext()); + if (l->isVisible() && + l->affectsVisibleZone()) + { + LightInfo lightInfo; + lightInfo.light = l; + lightInfo.type = l->getType(); + if (lightInfo.type == Light::LT_DIRECTIONAL) + { + // Always visible + lightInfo.position = Vector3::ZERO; + lightInfo.range = 0; + mTestLightInfos.push_back(lightInfo); + } + else + { + // NB treating spotlight as point for simplicity + // Just see if the lights attenuation range is within the frustum + lightInfo.range = l->getAttenuationRange(); + lightInfo.position = l->getDerivedPosition(); + Sphere sphere(lightInfo.position, lightInfo.range); + if (camera->isVisible(sphere)) + { + mTestLightInfos.push_back(lightInfo); + } + } + } + } + } // release lock on lights collection + + // from here on down this function is same as Ogre::SceneManager + + // Update lights affecting frustum if changed + if (mCachedLightInfos != mTestLightInfos) + { + mLightsAffectingFrustum.resize(mTestLightInfos.size()); + LightInfoList::const_iterator i; + LightList::iterator j = mLightsAffectingFrustum.begin(); + for (i = mTestLightInfos.begin(); i != mTestLightInfos.end(); ++i, ++j) + { + *j = i->light; + // add cam distance for sorting if texture shadows + if (isShadowTechniqueTextureBased()) + { + (*j)->_calcTempSquareDist(camera->getDerivedPosition()); + } + } + + // Sort the lights if using texture shadows, since the first 'n' will be + // used to generate shadow textures and we should pick the most appropriate + if (isShadowTechniqueTextureBased()) + { + // Allow a ShadowListener to override light sorting + // Reverse iterate so last takes precedence + bool overridden = false; + for (ListenerList::reverse_iterator ri = mListeners.rbegin(); + ri != mListeners.rend(); ++ri) + { + overridden = (*ri)->sortLightsAffectingFrustum(mLightsAffectingFrustum); + if (overridden) + break; + } + if (!overridden) + { + // default sort (stable to preserve directional light ordering + std::stable_sort( + mLightsAffectingFrustum.begin(), mLightsAffectingFrustum.end(), + lightsForShadowTextureLess()); + } + + } + + // Use swap instead of copy operator for efficiently + mCachedLightInfos.swap(mTestLightInfos); + + // notify light dirty, so all movable objects will re-populate + // their light list next time + _notifyLightsDirty(); + } + + } + //--------------------------------------------------------------------- + void PCZSceneManager::ensureShadowTexturesCreated() + { + bool shadowTextureConfigDirty = mShadowTextureConfigDirty; + SceneManager::ensureShadowTexturesCreated(); + if (!shadowTextureConfigDirty) return; + + size_t count = mShadowTextureCameras.size(); + for (size_t i = 0; i < count; ++i) + { + PCZSceneNode* node = (PCZSceneNode*)mSceneRoot->createChildSceneNode( + mShadowTextureCameras[i]->getName()); + node->attachObject(mShadowTextureCameras[i]); + addPCZSceneNode(node, mDefaultZone); + } + } + //--------------------------------------------------------------------- + void PCZSceneManager::destroyShadowTextures(void) + { + size_t count = mShadowTextureCameras.size(); + for (size_t i = 0; i < count; ++i) + { + SceneNode* node = mShadowTextureCameras[i]->getParentSceneNode(); + mSceneRoot->removeAndDestroyChild(node->getName()); + } + SceneManager::destroyShadowTextures(); + } + //--------------------------------------------------------------------- + void PCZSceneManager::fireShadowTexturesPreCaster(Light* light, Camera* camera, size_t iteration) + { + PCZSceneNode* camNode = (PCZSceneNode*)camera->getParentSceneNode(); + + if (light->getType() == Light::LT_DIRECTIONAL) + { + if (camNode->getHomeZone() != mActiveCameraZone) + addPCZSceneNode(camNode, mActiveCameraZone); + } + else + { + PCZSceneNode* lightNode = (PCZSceneNode*)light->getParentSceneNode(); + assert(lightNode); + PCZone* lightZone = lightNode->getHomeZone(); + if (camNode->getHomeZone() != lightZone) + addPCZSceneNode(camNode, lightZone); + } + + SceneManager::fireShadowTexturesPreCaster(light, camera, iteration); + } + + /* Attempt to automatically connect unconnected portals to proper target zones + * by looking for matching portals in other zones which are at the same location + */ + void PCZSceneManager::connectPortalsToTargetZonesByLocation(void) + { + // go through every zone to find portals + ZoneMap::iterator i, iend; + PCZone* zone; + iend = mZones.end(); + bool foundMatch; + for (i = mZones.begin(); i != iend; i++) + { + zone = i->second; + // go through all the portals in the zone + Portal* portal; + PortalList::iterator pi, piend; + piend = zone->mPortals.end(); + for (pi = zone->mPortals.begin(); pi != piend; pi++) + { + portal = *pi; + //portal->updateDerivedValues(); + if (portal->getTargetZone() == 0) + { + // this is a portal without a connected zone - look for + // a matching portal in another zone + PCZone* zone2; + ZoneMap::iterator j= mZones.begin(); + foundMatch = false; + while (!foundMatch && j != mZones.end()) + { + zone2 = j->second; + if (zone2 != zone) // make sure we don't look in the same zone + { + Portal * portal2 = zone2->findMatchingPortal(portal); + if (portal2) + { + // found a match! + Ogre::LogManager::getSingletonPtr()->logMessage("Connecting portal "+portal->getName()+" to portal "+portal2->getName()); + foundMatch = true; + portal->setTargetZone(zone2); + portal->setTargetPortal(portal2); + portal2->setTargetZone(zone); + portal2->setTargetPortal(portal); + } + } + j++; + } + if (foundMatch == false) + { + // error, didn't find a matching portal! + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Could not find matching portal for portal " + portal->getName(), + "PCZSceneManager::connectPortalsToTargetZonesByLocation"); + + } + } + } + } + } + + // main visibility determination & render queue filling routine + // over-ridden from base/default scene manager. This is *the* + // main call. + void PCZSceneManager::_findVisibleObjects(Camera* cam, + VisibleObjectsBoundsInfo* visibleBounds, + bool onlyShadowCasters) + { + // clear the render queue + getRenderQueue()->clear(); + + // if we are re-rendering the scene again with the same camera, we can just use the cache. + // this helps post processing compositors. + unsigned long frameCount = Root::getSingleton().getNextFrameNumber(); + if (mLastActiveCamera == cam && mFrameCount == frameCount) + { + RenderQueue* queue = getRenderQueue(); + size_t count = mVisible.size(); + for (size_t i = 0; i < count; ++i) + { + ((PCZSceneNode*)mVisible[i])->_addToRenderQueue( + cam, queue, onlyShadowCasters, visibleBounds); + } + return; + } + + // increment the visibility frame counter + mFrameCount = frameCount; + mLastActiveCamera = cam; + + // clear the list of visible nodes + mVisible.clear(); + + // turn off sky + enableSky(false); + + // remove all extra culling planes + ((PCZCamera*)cam)->removeAllExtraCullingPlanes(); + + // update the camera + ((PCZCamera*)cam)->update(); + + // get the home zone of the camera + PCZone* cameraHomeZone = ((PCZSceneNode*)(cam->getParentSceneNode()))->getHomeZone(); + + // walk the zones, starting from the camera home zone, + // adding all visible scene nodes to the mVisibles list + cameraHomeZone->setLastVisibleFrame(mFrameCount); + cameraHomeZone->findVisibleNodes((PCZCamera*)cam, + mVisible, + getRenderQueue(), + visibleBounds, + onlyShadowCasters, + mDisplayNodes, + mShowBoundingBoxes); + } void PCZSceneManager::findNodesIn( const AxisAlignedBox &box, PCZSceneNodeList &list, @@ -1245,22 +1245,22 @@ namespace Ogre PCZSceneNode *exclude ) { PortalList visitedPortals; - if (startZone) - { - // start in startzone, and recurse through portals if necessary - startZone->_findNodes(box, list, visitedPortals, true, true, exclude); - } - else - { - // no start zone specified, so check all zones - ZoneMap::iterator i; - PCZone * zone; - for (i = mZones.begin(); i != mZones.end(); i++) - { - zone = i->second; - zone->_findNodes( box, list, visitedPortals, false, false, exclude ); - } - } + if (startZone) + { + // start in startzone, and recurse through portals if necessary + startZone->_findNodes(box, list, visitedPortals, true, true, exclude); + } + else + { + // no start zone specified, so check all zones + ZoneMap::iterator i; + PCZone * zone; + for (i = mZones.begin(); i != mZones.end(); i++) + { + zone = i->second; + zone->_findNodes( box, list, visitedPortals, false, false, exclude ); + } + } } void PCZSceneManager::findNodesIn( const Sphere &sphere, @@ -1269,22 +1269,22 @@ namespace Ogre PCZSceneNode *exclude ) { PortalList visitedPortals; - if (startZone) - { - // start in startzone, and recurse through portals if necessary - startZone->_findNodes(sphere, list, visitedPortals, true, true, exclude); - } - else - { - // no start zone specified, so check all zones - ZoneMap::iterator i; - PCZone * zone; - for (i = mZones.begin(); i != mZones.end(); i++) - { - zone = i->second; - zone->_findNodes( sphere, list, visitedPortals, false, false, exclude ); - } - } + if (startZone) + { + // start in startzone, and recurse through portals if necessary + startZone->_findNodes(sphere, list, visitedPortals, true, true, exclude); + } + else + { + // no start zone specified, so check all zones + ZoneMap::iterator i; + PCZone * zone; + for (i = mZones.begin(); i != mZones.end(); i++) + { + zone = i->second; + zone->_findNodes( sphere, list, visitedPortals, false, false, exclude ); + } + } } void PCZSceneManager::findNodesIn( const PlaneBoundedVolume &volume, @@ -1293,22 +1293,22 @@ namespace Ogre PCZSceneNode *exclude ) { PortalList visitedPortals; - if (startZone) - { - // start in startzone, and recurse through portals if necessary - startZone->_findNodes(volume, list, visitedPortals, true, true, exclude); - } - else - { - // no start zone specified, so check all zones - ZoneMap::iterator i; - PCZone * zone; - for (i = mZones.begin(); i != mZones.end(); i++) - { - zone = i->second; - zone->_findNodes( volume, list, visitedPortals, false, false, exclude ); - } - } + if (startZone) + { + // start in startzone, and recurse through portals if necessary + startZone->_findNodes(volume, list, visitedPortals, true, true, exclude); + } + else + { + // no start zone specified, so check all zones + ZoneMap::iterator i; + PCZone * zone; + for (i = mZones.begin(); i != mZones.end(); i++) + { + zone = i->second; + zone->_findNodes( volume, list, visitedPortals, false, false, exclude ); + } + } } void PCZSceneManager::findNodesIn( const Ray &r, @@ -1317,21 +1317,21 @@ namespace Ogre PCZSceneNode *exclude ) { PortalList visitedPortals; - if (startZone) - { - // start in startzone, and recurse through portals if necessary - startZone->_findNodes(r, list, visitedPortals, true, true, exclude); - } - else - { - ZoneMap::iterator i; - PCZone * zone; - for (i = mZones.begin(); i != mZones.end(); i++) - { - zone = i->second; - zone->_findNodes( r, list, visitedPortals, false, false, exclude ); - } - } + if (startZone) + { + // start in startzone, and recurse through portals if necessary + startZone->_findNodes(r, list, visitedPortals, true, true, exclude); + } + else + { + ZoneMap::iterator i; + PCZone * zone; + for (i = mZones.begin(); i != mZones.end(); i++) + { + zone = i->second; + zone->_findNodes( r, list, visitedPortals, false, false, exclude ); + } + } } // get the current value of a scene manager option @@ -1363,19 +1363,19 @@ namespace Ogre mShowPortals = * static_cast < const bool * > ( val ); return true; } - // send option to each zone - ZoneMap::iterator i; - PCZone * zone; - for (i = mZones.begin(); i != mZones.end(); i++) - { - zone = i->second; - if (zone->setOption(key, val ) == true) - { - return true; - } - } - - // try regular scenemanager option + // send option to each zone + ZoneMap::iterator i; + PCZone * zone; + for (i = mZones.begin(); i != mZones.end(); i++) + { + zone = i->second; + if (zone->setOption(key, val ) == true) + { + return true; + } + } + + // try regular scenemanager option return SceneManager::setOption( key, val ); @@ -1447,45 +1447,45 @@ namespace Ogre return q; } //--------------------------------------------------------------------- - // clear portal update flag from all zones - void PCZSceneManager::_clearAllZonesPortalUpdateFlag(void) - { - ZoneMap::iterator zoneIterator = mZones.begin(); - - while ( zoneIterator != mZones.end() ) - { - (zoneIterator->second)->setPortalsUpdated(false); - zoneIterator++; - } - } - //--------------------------------------------------------------------- - /// See SceneManager::prepareShadowTextures. - void PCZSceneManager::prepareShadowTextures(Camera* cam, Viewport* vp, const LightList* lightList) - { - mActiveCameraZone = ((PCZSceneNode*)cam->getParentSceneNode())->getHomeZone(); - SceneManager::prepareShadowTextures(cam, vp); - } + // clear portal update flag from all zones + void PCZSceneManager::_clearAllZonesPortalUpdateFlag(void) + { + ZoneMap::iterator zoneIterator = mZones.begin(); + + while ( zoneIterator != mZones.end() ) + { + (zoneIterator->second)->setPortalsUpdated(false); + zoneIterator++; + } + } + //--------------------------------------------------------------------- + /// See SceneManager::prepareShadowTextures. + void PCZSceneManager::prepareShadowTextures(Camera* cam, Viewport* vp, const LightList* lightList) + { + mActiveCameraZone = ((PCZSceneNode*)cam->getParentSceneNode())->getHomeZone(); + SceneManager::prepareShadowTextures(cam, vp); + } //----------------------------------------------------------------------- const String PCZSceneManagerFactory::FACTORY_TYPE_NAME = "PCZSceneManager"; //----------------------------------------------------------------------- void PCZSceneManagerFactory::initMetaData(void) const { - mMetaData.typeName = FACTORY_TYPE_NAME; - mMetaData.description = "Scene manager organising the scene using Portal Connected Zones."; - mMetaData.sceneTypeMask = 0xFFFF; // support all types - mMetaData.worldGeometrySupported = false; + mMetaData.typeName = FACTORY_TYPE_NAME; + mMetaData.description = "Scene manager organising the scene using Portal Connected Zones."; + mMetaData.sceneTypeMask = 0xFFFF; // support all types + mMetaData.worldGeometrySupported = false; } //----------------------------------------------------------------------- SceneManager* PCZSceneManagerFactory::createInstance( - const String& instanceName) + const String& instanceName) { - return OGRE_NEW PCZSceneManager(instanceName); + return OGRE_NEW PCZSceneManager(instanceName); } //----------------------------------------------------------------------- void PCZSceneManagerFactory::destroyInstance(SceneManager* instance) { - OGRE_DELETE instance; + OGRE_DELETE instance; } diff --git a/PlugIns/PCZSceneManager/src/OgrePCZSceneManagerDll.cpp b/PlugIns/PCZSceneManager/src/OgrePCZSceneManagerDll.cpp index 6a962c97a55..8a0083fae3a 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCZSceneManagerDll.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCZSceneManagerDll.cpp @@ -53,8 +53,8 @@ namespace Ogre } extern "C" void _OgrePCZPluginExport dllStopPlugin( void ) { - Root::getSingleton().uninstallPlugin(pczPlugin); - OGRE_DELETE pczPlugin; + Root::getSingleton().uninstallPlugin(pczPlugin); + OGRE_DELETE pczPlugin; } } diff --git a/PlugIns/PCZSceneManager/src/OgrePCZSceneNode.cpp b/PlugIns/PCZSceneManager/src/OgrePCZSceneNode.cpp index c75c1ea54ea..c64a2723af8 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCZSceneNode.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCZSceneNode.cpp @@ -37,7 +37,7 @@ a given scenenode's PCZSceneNode by the scene manager. begin : Sat Mar 24 2007 author : Eric Cha email : ericc@xenopi.com -TODO : None known +TODO : None known ----------------------------------------------------------------------------- */ @@ -47,175 +47,175 @@ TODO : None known namespace Ogre { - PCZSceneNode::PCZSceneNode( SceneManager* creator ) - : SceneNode( creator ), - mHomeZone(0), - mAnchored(false), - mAllowedToVisit(true), - mLastVisibleFrame(0), - mLastVisibleFromCamera(0), - mEnabled(true), - mMoved(false) - { - } + PCZSceneNode::PCZSceneNode( SceneManager* creator ) + : SceneNode( creator ), + mHomeZone(0), + mAnchored(false), + mAllowedToVisit(true), + mLastVisibleFrame(0), + mLastVisibleFromCamera(0), + mEnabled(true), + mMoved(false) + { + } - PCZSceneNode::PCZSceneNode( SceneManager* creator, const String& name ) - : SceneNode( creator, name ), - mHomeZone(0), - mAnchored(false), - mAllowedToVisit(true), - mLastVisibleFrame(0), - mLastVisibleFromCamera(0), - mEnabled(true), - mMoved(false) - { - } + PCZSceneNode::PCZSceneNode( SceneManager* creator, const String& name ) + : SceneNode( creator, name ), + mHomeZone(0), + mAnchored(false), + mAllowedToVisit(true), + mLastVisibleFrame(0), + mLastVisibleFromCamera(0), + mEnabled(true), + mMoved(false) + { + } - PCZSceneNode::~PCZSceneNode() - { - // clear visiting zones list - mVisitingZones.clear(); + PCZSceneNode::~PCZSceneNode() + { + // clear visiting zones list + mVisitingZones.clear(); - // delete zone data - ZoneData* zoneData; - ZoneDataMap::iterator it = mZoneData.begin(); + // delete zone data + ZoneData* zoneData; + ZoneDataMap::iterator it = mZoneData.begin(); - while ( it != mZoneData.end() ) - { - zoneData = it->second; - OGRE_DELETE zoneData; - ++it; - } - mZoneData.clear(); - } - void PCZSceneNode::_update(bool updateChildren, bool parentHasChanged) - { - Node::_update(updateChildren, parentHasChanged); - if (mParent) _updateBounds(); // skip bound update if it's root scene node. Saves a lot of CPU. + while ( it != mZoneData.end() ) + { + zoneData = it->second; + OGRE_DELETE zoneData; + ++it; + } + mZoneData.clear(); + } + void PCZSceneNode::_update(bool updateChildren, bool parentHasChanged) + { + Node::_update(updateChildren, parentHasChanged); + if (mParent) _updateBounds(); // skip bound update if it's root scene node. Saves a lot of CPU. - mPrevPosition = mNewPosition; - mNewPosition = mDerivedPosition; - } - void PCZSceneNode::updateFromParentImpl() const - { - SceneNode::updateFromParentImpl(); - mMoved = true; - } + mPrevPosition = mNewPosition; + mNewPosition = mDerivedPosition; + } + void PCZSceneNode::updateFromParentImpl() const + { + SceneNode::updateFromParentImpl(); + mMoved = true; + } //----------------------------------------------------------------------- - SceneNode* PCZSceneNode::createChildSceneNode(const Vector3& inTranslate, + SceneNode* PCZSceneNode::createChildSceneNode(const Vector3& inTranslate, const Quaternion& inRotate) - { - PCZSceneNode * childSceneNode = (PCZSceneNode*)(this->createChild(inTranslate, inRotate)); - if (mHomeZone) - { - childSceneNode->setHomeZone(mHomeZone); - mHomeZone->_addNode(childSceneNode); - } - return static_cast(childSceneNode); - } + { + PCZSceneNode * childSceneNode = (PCZSceneNode*)(this->createChild(inTranslate, inRotate)); + if (mHomeZone) + { + childSceneNode->setHomeZone(mHomeZone); + mHomeZone->_addNode(childSceneNode); + } + return static_cast(childSceneNode); + } //----------------------------------------------------------------------- SceneNode* PCZSceneNode::createChildSceneNode(const String& name, const Vector3& inTranslate, - const Quaternion& inRotate) - { - PCZSceneNode * childSceneNode = (PCZSceneNode*)(this->createChild(name, inTranslate, inRotate)); - if (mHomeZone) - { - childSceneNode->setHomeZone(mHomeZone); - mHomeZone->_addNode(childSceneNode); - } - return static_cast(childSceneNode); - } + const Quaternion& inRotate) + { + PCZSceneNode * childSceneNode = (PCZSceneNode*)(this->createChild(name, inTranslate, inRotate)); + if (mHomeZone) + { + childSceneNode->setHomeZone(mHomeZone); + mHomeZone->_addNode(childSceneNode); + } + return static_cast(childSceneNode); + } - PCZone* PCZSceneNode::getHomeZone(void) - { - return mHomeZone; - } - void PCZSceneNode::setHomeZone(PCZone * zone) - { - // if the new home zone is different than the current, remove - // the node from the current home zone's list of home nodes first - if (zone != mHomeZone && mHomeZone) - { - mHomeZone->removeNode(this); - } - mHomeZone = zone; - } - void PCZSceneNode::anchorToHomeZone(PCZone * zone) - { - mHomeZone = zone; - if (zone) - { - mAnchored = true; - } - else - { - mAnchored = false; - } - } - void PCZSceneNode::addZoneToVisitingZonesMap(PCZone * zone) - { - mVisitingZones[zone->getName()] = zone; - } - void PCZSceneNode::clearVisitingZonesMap(void) - { - mVisitingZones.clear(); - } - /* The following function does the following: - * 1) Remove references to the node from zones the node is visiting - * 2) Clear the node's list of zones it is visiting - */ - void PCZSceneNode::clearNodeFromVisitedZones( void ) - { - if (mVisitingZones.size() > 0) - { - // first go through the list of zones this node is visiting - // and remove references to this node - PCZone* zone; - ZoneMap::iterator it = mVisitingZones.begin(); + PCZone* PCZSceneNode::getHomeZone(void) + { + return mHomeZone; + } + void PCZSceneNode::setHomeZone(PCZone * zone) + { + // if the new home zone is different than the current, remove + // the node from the current home zone's list of home nodes first + if (zone != mHomeZone && mHomeZone) + { + mHomeZone->removeNode(this); + } + mHomeZone = zone; + } + void PCZSceneNode::anchorToHomeZone(PCZone * zone) + { + mHomeZone = zone; + if (zone) + { + mAnchored = true; + } + else + { + mAnchored = false; + } + } + void PCZSceneNode::addZoneToVisitingZonesMap(PCZone * zone) + { + mVisitingZones[zone->getName()] = zone; + } + void PCZSceneNode::clearVisitingZonesMap(void) + { + mVisitingZones.clear(); + } + /* The following function does the following: + * 1) Remove references to the node from zones the node is visiting + * 2) Clear the node's list of zones it is visiting + */ + void PCZSceneNode::clearNodeFromVisitedZones( void ) + { + if (mVisitingZones.size() > 0) + { + // first go through the list of zones this node is visiting + // and remove references to this node + PCZone* zone; + ZoneMap::iterator it = mVisitingZones.begin(); - while ( it != mVisitingZones.end() ) - { - zone = it->second; - zone->removeNode(this); - ++it; - } + while ( it != mVisitingZones.end() ) + { + zone = it->second; + zone->removeNode(this); + ++it; + } - // second, clear the visiting zones list - mVisitingZones.clear(); + // second, clear the visiting zones list + mVisitingZones.clear(); - } - } + } + } - /* Remove all references that the node has to the given zone - */ - void PCZSceneNode::removeReferencesToZone(PCZone * zone) - { - if (mHomeZone == zone) - { - mHomeZone = 0; - } - // search the map of visiting zones and remove - ZoneMap::iterator i; - i = mVisitingZones.find(zone->getName()); - if (i != mVisitingZones.end()) - { - mVisitingZones.erase(i); - } - } - - /* returns true if zone is in the node's visiting zones map - false otherwise. - */ - bool PCZSceneNode::isVisitingZone(PCZone * zone) - { - ZoneMap::iterator i; - i = mVisitingZones.find(zone->getName()); - if (i != mVisitingZones.end()) - { - return true; - } - return false; - } + /* Remove all references that the node has to the given zone + */ + void PCZSceneNode::removeReferencesToZone(PCZone * zone) + { + if (mHomeZone == zone) + { + mHomeZone = 0; + } + // search the map of visiting zones and remove + ZoneMap::iterator i; + i = mVisitingZones.find(zone->getName()); + if (i != mVisitingZones.end()) + { + mVisitingZones.erase(i); + } + } + + /* returns true if zone is in the node's visiting zones map + false otherwise. + */ + bool PCZSceneNode::isVisitingZone(PCZone * zone) + { + ZoneMap::iterator i; + i = mVisitingZones.find(zone->getName()); + if (i != mVisitingZones.end()) + { + return true; + } + return false; + } /** Adds the attached objects of this PCZSceneNode into the queue. */ void PCZSceneNode::_addToRenderQueue( Camera* cam, @@ -223,80 +223,80 @@ namespace Ogre bool onlyShadowCasters, VisibleObjectsBoundsInfo* visibleBounds ) { - ObjectMap::iterator mit = mObjectsByName.begin(); + ObjectMap::iterator mit = mObjectsByName.begin(); - while ( mit != mObjectsByName.end() ) - { - MovableObject * mo = mit->second; + while ( mit != mObjectsByName.end() ) + { + MovableObject * mo = mit->second; - mo->_notifyCurrentCamera(cam); - if ( mo->isVisible() && - (!onlyShadowCasters || mo->getCastShadows())) - { - mo -> _updateRenderQueue( queue ); + mo->_notifyCurrentCamera(cam); + if ( mo->isVisible() && + (!onlyShadowCasters || mo->getCastShadows())) + { + mo -> _updateRenderQueue( queue ); - if (visibleBounds) - { - visibleBounds->merge(mo->getWorldBoundingBox(true), - mo->getWorldBoundingSphere(true), + if (visibleBounds) + { + visibleBounds->merge(mo->getWorldBoundingBox(true), + mo->getWorldBoundingSphere(true), cam); - } + } } - ++mit; + ++mit; } } - /** Save the node's current position as the previous position - */ - void PCZSceneNode::savePrevPosition(void) - { - mPrevPosition = _getDerivedPosition(); - } + /** Save the node's current position as the previous position + */ + void PCZSceneNode::savePrevPosition(void) + { + mPrevPosition = _getDerivedPosition(); + } - void PCZSceneNode::setZoneData(PCZone * zone, ZoneData * zoneData) - { + void PCZSceneNode::setZoneData(PCZone * zone, ZoneData * zoneData) + { - // first make sure that the data doesn't already exist - if (mZoneData.find(zone->getName()) != mZoneData.end()) - { - OGRE_EXCEPT( - Exception::ERR_DUPLICATE_ITEM, - "A ZoneData associated with zone " + zone->getName() + " already exists", - "PCZSceneNode::setZoneData" ); - } - mZoneData[zone->getName()] = zoneData; - } + // first make sure that the data doesn't already exist + if (mZoneData.find(zone->getName()) != mZoneData.end()) + { + OGRE_EXCEPT( + Exception::ERR_DUPLICATE_ITEM, + "A ZoneData associated with zone " + zone->getName() + " already exists", + "PCZSceneNode::setZoneData" ); + } + mZoneData[zone->getName()] = zoneData; + } - // get zone data for this node for given zone - // NOTE: This routine assumes that the zone data is present! - ZoneData* PCZSceneNode::getZoneData(PCZone * zone) - { - return mZoneData[zone->getName()]; - } + // get zone data for this node for given zone + // NOTE: This routine assumes that the zone data is present! + ZoneData* PCZSceneNode::getZoneData(PCZone * zone) + { + return mZoneData[zone->getName()]; + } - // update zone-specific data for any zone that the node is touching - void PCZSceneNode::updateZoneData(void) - { - ZoneData* zoneData; - PCZone * zone; - // make sure home zone data is updated - zone = mHomeZone; - if (zone->requiresZoneSpecificNodeData()) - { - zoneData = getZoneData(zone); - zoneData->update(); - } - // update zone data for any zones visited - ZoneMap::iterator it = mVisitingZones.begin(); - while ( it != mVisitingZones.end() ) - { - zone = it->second; - if (zone->requiresZoneSpecificNodeData()) - { - zoneData = getZoneData(zone); - zoneData->update(); - } - ++it; - } - } + // update zone-specific data for any zone that the node is touching + void PCZSceneNode::updateZoneData(void) + { + ZoneData* zoneData; + PCZone * zone; + // make sure home zone data is updated + zone = mHomeZone; + if (zone->requiresZoneSpecificNodeData()) + { + zoneData = getZoneData(zone); + zoneData->update(); + } + // update zone data for any zones visited + ZoneMap::iterator it = mVisitingZones.begin(); + while ( it != mVisitingZones.end() ) + { + zone = it->second; + if (zone->requiresZoneSpecificNodeData()) + { + zoneData = getZoneData(zone); + zoneData->update(); + } + ++it; + } + } } diff --git a/PlugIns/PCZSceneManager/src/OgrePCZSceneQuery.cpp b/PlugIns/PCZSceneManager/src/OgrePCZSceneQuery.cpp index 243ac2e98c5..e840f59086d 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCZSceneQuery.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCZSceneQuery.cpp @@ -61,70 +61,70 @@ namespace Ogre MovableSet set; - // Iterate over all movable types - Root::MovableObjectFactoryIterator factIt = - Root::getSingleton().getMovableObjectFactoryIterator(); - while(factIt.hasMoreElements()) - { - SceneManager::MovableObjectIterator it = - mParentSceneMgr->getMovableObjectIterator( - factIt.getNext()->getType()); - while( it.hasMoreElements() ) - { + // Iterate over all movable types + Root::MovableObjectFactoryIterator factIt = + Root::getSingleton().getMovableObjectFactoryIterator(); + while(factIt.hasMoreElements()) + { + SceneManager::MovableObjectIterator it = + mParentSceneMgr->getMovableObjectIterator( + factIt.getNext()->getType()); + while( it.hasMoreElements() ) + { - MovableObject * e = it.getNext(); + MovableObject * e = it.getNext(); PCZone * zone = ((PCZSceneNode*)(e->getParentSceneNode()))->getHomeZone(); - PCZSceneNodeList list; - //find the nodes that intersect the AAB - static_cast( mParentSceneMgr ) -> findNodesIn( e->getWorldBoundingBox(), list, zone, 0 ); - //grab all moveables from the node that intersect... - PCZSceneNodeList::iterator nit = list.begin(); - while( nit != list.end() ) - { - SceneNode::ObjectIterator oit = (*nit) -> getAttachedObjectIterator(); - while( oit.hasMoreElements() ) - { - MovableObject * m = oit.getNext(); + PCZSceneNodeList list; + //find the nodes that intersect the AAB + static_cast( mParentSceneMgr ) -> findNodesIn( e->getWorldBoundingBox(), list, zone, 0 ); + //grab all moveables from the node that intersect... + PCZSceneNodeList::iterator nit = list.begin(); + while( nit != list.end() ) + { + SceneNode::ObjectIterator oit = (*nit) -> getAttachedObjectIterator(); + while( oit.hasMoreElements() ) + { + MovableObject * m = oit.getNext(); - if( m != e && - set.find( MovablePair(e,m)) == set.end() && - set.find( MovablePair(m,e)) == set.end() && - (m->getQueryFlags() & mQueryMask) && - (m->getTypeFlags() & mQueryTypeMask) && - m->isInScene() && - e->getWorldBoundingBox().intersects( m->getWorldBoundingBox() ) ) - { - listener -> queryResult( e, m ); - // deal with attached objects, since they are not directly attached to nodes - if (m->getMovableType() == "Entity") - { - Entity* e2 = static_cast(m); - Entity::ChildObjectListIterator childIt = e2->getAttachedObjectIterator(); - while(childIt.hasMoreElements()) - { - MovableObject* c = childIt.getNext(); - if (c->getQueryFlags() & mQueryMask && - e->getWorldBoundingBox().intersects( c->getWorldBoundingBox() )) - { - listener->queryResult(e, c); - } - } - } - } - set.insert( MovablePair(e,m) ); + if( m != e && + set.find( MovablePair(e,m)) == set.end() && + set.find( MovablePair(m,e)) == set.end() && + (m->getQueryFlags() & mQueryMask) && + (m->getTypeFlags() & mQueryTypeMask) && + m->isInScene() && + e->getWorldBoundingBox().intersects( m->getWorldBoundingBox() ) ) + { + listener -> queryResult( e, m ); + // deal with attached objects, since they are not directly attached to nodes + if (m->getMovableType() == "Entity") + { + Entity* e2 = static_cast(m); + Entity::ChildObjectListIterator childIt = e2->getAttachedObjectIterator(); + while(childIt.hasMoreElements()) + { + MovableObject* c = childIt.getNext(); + if (c->getQueryFlags() & mQueryMask && + e->getWorldBoundingBox().intersects( c->getWorldBoundingBox() )) + { + listener->queryResult(e, c); + } + } + } + } + set.insert( MovablePair(e,m) ); - } - ++nit; - } + } + ++nit; + } - } - } + } + } } /** Creates a custom PCZ AAB query */ PCZAxisAlignedBoxSceneQuery::PCZAxisAlignedBoxSceneQuery(SceneManager* creator) : DefaultAxisAlignedBoxSceneQuery(creator) { - mStartZone = 0; + mStartZone = 0; mExcludeNode = 0; } /** Deletes the custom PCZ query */ @@ -147,25 +147,25 @@ namespace Ogre { MovableObject * m = oit.getNext(); if( (m->getQueryFlags() & mQueryMask) && - (m->getTypeFlags() & mQueryTypeMask) && - m->isInScene() && - mAABB.intersects( m->getWorldBoundingBox() ) ) + (m->getTypeFlags() & mQueryTypeMask) && + m->isInScene() && + mAABB.intersects( m->getWorldBoundingBox() ) ) { listener -> queryResult( m ); - // deal with attached objects, since they are not directly attached to nodes - if (m->getMovableType() == "Entity") - { - Entity* e = static_cast(m); - Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); - while(childIt.hasMoreElements()) - { - MovableObject* c = childIt.getNext(); - if (c->getQueryFlags() & mQueryMask) - { - listener->queryResult(c); - } - } - } + // deal with attached objects, since they are not directly attached to nodes + if (m->getMovableType() == "Entity") + { + Entity* e = static_cast(m); + Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); + while(childIt.hasMoreElements()) + { + MovableObject* c = childIt.getNext(); + if (c->getQueryFlags() & mQueryMask) + { + listener->queryResult(c); + } + } + } } } @@ -179,7 +179,7 @@ namespace Ogre PCZRaySceneQuery:: PCZRaySceneQuery(SceneManager* creator) : DefaultRaySceneQuery(creator) { - mStartZone = 0; + mStartZone = 0; mExcludeNode = 0; } //--------------------------------------------------------------------- @@ -201,31 +201,31 @@ namespace Ogre { MovableObject * m = oit.getNext(); if( (m->getQueryFlags() & mQueryMask) && - (m->getTypeFlags() & mQueryTypeMask) && m->isInScene() ) + (m->getTypeFlags() & mQueryTypeMask) && m->isInScene() ) { std::pair result = mRay.intersects(m->getWorldBoundingBox()); if( result.first ) { listener -> queryResult( m, result.second ); - // deal with attached objects, since they are not directly attached to nodes - if (m->getMovableType() == "Entity") - { - Entity* e = static_cast(m); - Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); - while(childIt.hasMoreElements()) - { - MovableObject* c = childIt.getNext(); - if (c->getQueryFlags() & mQueryMask) - { - result = mRay.intersects(c->getWorldBoundingBox()); - if (result.first) - { - listener->queryResult(c, result.second); - } - } - } - } + // deal with attached objects, since they are not directly attached to nodes + if (m->getMovableType() == "Entity") + { + Entity* e = static_cast(m); + Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); + while(childIt.hasMoreElements()) + { + MovableObject* c = childIt.getNext(); + if (c->getQueryFlags() & mQueryMask) + { + result = mRay.intersects(c->getWorldBoundingBox()); + if (result.first) + { + listener->queryResult(c, result.second); + } + } + } + } } } } @@ -241,7 +241,7 @@ namespace Ogre PCZSphereSceneQuery:: PCZSphereSceneQuery(SceneManager* creator) : DefaultSphereSceneQuery(creator) { - mStartZone = 0; + mStartZone = 0; mExcludeNode = 0; } //--------------------------------------------------------------------- @@ -263,26 +263,26 @@ namespace Ogre { MovableObject * m = oit.getNext(); if( (m->getQueryFlags() & mQueryMask) && - (m->getTypeFlags() & mQueryTypeMask) && - m->isInScene() && - mSphere.intersects( m->getWorldBoundingBox() ) ) + (m->getTypeFlags() & mQueryTypeMask) && + m->isInScene() && + mSphere.intersects( m->getWorldBoundingBox() ) ) { listener -> queryResult( m ); - // deal with attached objects, since they are not directly attached to nodes - if (m->getMovableType() == "Entity") - { - Entity* e = static_cast(m); - Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); - while(childIt.hasMoreElements()) - { - MovableObject* c = childIt.getNext(); - if (c->getQueryFlags() & mQueryMask && - mSphere.intersects( c->getWorldBoundingBox())) - { - listener->queryResult(c); - } - } - } + // deal with attached objects, since they are not directly attached to nodes + if (m->getMovableType() == "Entity") + { + Entity* e = static_cast(m); + Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); + while(childIt.hasMoreElements()) + { + MovableObject* c = childIt.getNext(); + if (c->getQueryFlags() & mQueryMask && + mSphere.intersects( c->getWorldBoundingBox())) + { + listener->queryResult(c); + } + } + } } } ++it; @@ -296,7 +296,7 @@ namespace Ogre PCZPlaneBoundedVolumeListSceneQuery(SceneManager* creator) : DefaultPlaneBoundedVolumeListSceneQuery(creator) { - mStartZone = 0; + mStartZone = 0; mExcludeNode = 0; } //--------------------------------------------------------------------- @@ -328,26 +328,26 @@ namespace Ogre { MovableObject * m = oit.getNext(); if( (m->getQueryFlags() & mQueryMask) && - (m->getTypeFlags() & mQueryTypeMask) && - m->isInScene() && - (*pi).intersects( m->getWorldBoundingBox() ) ) + (m->getTypeFlags() & mQueryTypeMask) && + m->isInScene() && + (*pi).intersects( m->getWorldBoundingBox() ) ) { listener -> queryResult( m ); - // deal with attached objects, since they are not directly attached to nodes - if (m->getMovableType() == "Entity") - { - Entity* e = static_cast(m); - Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); - while(childIt.hasMoreElements()) - { - MovableObject* c = childIt.getNext(); - if (c->getQueryFlags() & mQueryMask && - (*pi).intersects( c->getWorldBoundingBox())) - { - listener->queryResult(c); - } - } - } + // deal with attached objects, since they are not directly attached to nodes + if (m->getMovableType() == "Entity") + { + Entity* e = static_cast(m); + Entity::ChildObjectListIterator childIt = e->getAttachedObjectIterator(); + while(childIt.hasMoreElements()) + { + MovableObject* c = childIt.getNext(); + if (c->getQueryFlags() & mQueryMask && + (*pi).intersects( c->getWorldBoundingBox())) + { + listener->queryResult(c); + } + } + } } } } diff --git a/PlugIns/PCZSceneManager/src/OgrePCZone.cpp b/PlugIns/PCZSceneManager/src/OgrePCZone.cpp index b7b89aca527..a433cab9823 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCZone.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCZone.cpp @@ -43,160 +43,160 @@ namespace Ogre PCZone::PCZone( PCZSceneManager * creator, const String& name ) { mLastVisibleFrame = 0; - mLastVisibleFromCamera = 0; - mName = name; - mZoneTypeName = "ZoneType_Undefined"; - mEnclosureNode = 0; - mPCZSM = creator; - mHasSky = false; - } - - PCZone::~PCZone() - { - } - - /** Remove all nodes from the node reference list and clear it - */ - void PCZone::_clearNodeLists(short type) - { - if (type & HOME_NODE_LIST) - { - mHomeNodeList.clear(); - } - if (type & VISITOR_NODE_LIST) - { - mVisitorNodeList.clear(); - } - } - - Portal * PCZone::findMatchingPortal(Portal * portal) - { - // look through all the portals in zone2 for a match - Portal* portal2; - PortalList::iterator pi2, piend2; - piend2 = mPortals.end(); - for (pi2 = mPortals.begin(); pi2 != piend2; pi2++) - { - portal2 = *pi2; - //portal2->updateDerivedValues(); - if (portal2->getTargetZone() == 0 && portal2->closeTo(portal) && - portal2->getDerivedDirection().dotProduct(portal->getDerivedDirection()) < -0.9) - { - // found a match! - return portal2; - } - } - // no match - return 0; - } - - - /* Add a portal to the zone */ - void PCZone::_addPortal(Portal * newPortal) - { - if (newPortal) - { - // make sure portal is unique (at least in this zone) - PortalList::iterator it = std::find(mPortals.begin(), mPortals.end(), newPortal); - if (it != mPortals.end()) - { - OGRE_EXCEPT( - Exception::ERR_DUPLICATE_ITEM, - "A portal with the name " + newPortal->getName() + " already exists", - "PCZone::_addPortal" ); - } - - // add portal to portals list - mPortals.push_back(newPortal); - - // tell the portal which zone it's currently in - newPortal->setCurrentHomeZone(this); - } - } - - /* Remove a portal from the zone (does not erase the portal object, just removes reference) */ - void PCZone::_removePortal(Portal * removePortal) - { - if (removePortal) - { - mPortals.erase(std::find(mPortals.begin(), mPortals.end(), removePortal)); - } - } - - /* Add an anti portal to the zone */ - void PCZone::_addAntiPortal(AntiPortal* newAntiPortal) - { - if (newAntiPortal) - { - // make sure portal is unique (at least in this zone) - AntiPortalList::iterator it = std::find(mAntiPortals.begin(), mAntiPortals.end(), newAntiPortal); - if (it != mAntiPortals.end()) - { - OGRE_EXCEPT( - Exception::ERR_DUPLICATE_ITEM, - "An anti portal with the name " + newAntiPortal->getName() + " already exists", - "PCZone::_addAntiPortal" ); - } - - // add portal to portals list - mAntiPortals.push_back(newAntiPortal); - - // tell the portal which zone it's currently in - newAntiPortal->setCurrentHomeZone(this); - } - } - - /* Remove an anti portal from the zone */ - void PCZone::_removeAntiPortal(AntiPortal* removeAntiPortal) - { - if (removeAntiPortal) - { - mAntiPortals.erase(std::find(mAntiPortals.begin(), mAntiPortals.end(), removeAntiPortal)); - } - } - - /* create node specific zone data if necessary - */ - void PCZone::createNodeZoneData(PCZSceneNode *) - { - } - - /* get the aabb of the zone - default implementation - uses the enclosure node, but there are other perhaps - better ways - */ - void PCZone::getAABB(AxisAlignedBox & aabb) - { - // if there is no node, just return a null box - if (mEnclosureNode == 0) - { - aabb.setNull(); - } - else - { - aabb = mEnclosureNode->_getWorldAABB(); - // since this is the "local" AABB, subtract out any translations - aabb.setMinimum(aabb.getMinimum() - mEnclosureNode->_getDerivedPosition()); - aabb.setMaximum(aabb.getMaximum() - mEnclosureNode->_getDerivedPosition()); - } - return; - } - - /***********************************************************************\ - ZoneData - Zone-specific Data structure for Scene Nodes + mLastVisibleFromCamera = 0; + mName = name; + mZoneTypeName = "ZoneType_Undefined"; + mEnclosureNode = 0; + mPCZSM = creator; + mHasSky = false; + } + + PCZone::~PCZone() + { + } + + /** Remove all nodes from the node reference list and clear it + */ + void PCZone::_clearNodeLists(short type) + { + if (type & HOME_NODE_LIST) + { + mHomeNodeList.clear(); + } + if (type & VISITOR_NODE_LIST) + { + mVisitorNodeList.clear(); + } + } + + Portal * PCZone::findMatchingPortal(Portal * portal) + { + // look through all the portals in zone2 for a match + Portal* portal2; + PortalList::iterator pi2, piend2; + piend2 = mPortals.end(); + for (pi2 = mPortals.begin(); pi2 != piend2; pi2++) + { + portal2 = *pi2; + //portal2->updateDerivedValues(); + if (portal2->getTargetZone() == 0 && portal2->closeTo(portal) && + portal2->getDerivedDirection().dotProduct(portal->getDerivedDirection()) < -0.9) + { + // found a match! + return portal2; + } + } + // no match + return 0; + } + + + /* Add a portal to the zone */ + void PCZone::_addPortal(Portal * newPortal) + { + if (newPortal) + { + // make sure portal is unique (at least in this zone) + PortalList::iterator it = std::find(mPortals.begin(), mPortals.end(), newPortal); + if (it != mPortals.end()) + { + OGRE_EXCEPT( + Exception::ERR_DUPLICATE_ITEM, + "A portal with the name " + newPortal->getName() + " already exists", + "PCZone::_addPortal" ); + } + + // add portal to portals list + mPortals.push_back(newPortal); + + // tell the portal which zone it's currently in + newPortal->setCurrentHomeZone(this); + } + } + + /* Remove a portal from the zone (does not erase the portal object, just removes reference) */ + void PCZone::_removePortal(Portal * removePortal) + { + if (removePortal) + { + mPortals.erase(std::find(mPortals.begin(), mPortals.end(), removePortal)); + } + } + + /* Add an anti portal to the zone */ + void PCZone::_addAntiPortal(AntiPortal* newAntiPortal) + { + if (newAntiPortal) + { + // make sure portal is unique (at least in this zone) + AntiPortalList::iterator it = std::find(mAntiPortals.begin(), mAntiPortals.end(), newAntiPortal); + if (it != mAntiPortals.end()) + { + OGRE_EXCEPT( + Exception::ERR_DUPLICATE_ITEM, + "An anti portal with the name " + newAntiPortal->getName() + " already exists", + "PCZone::_addAntiPortal" ); + } + + // add portal to portals list + mAntiPortals.push_back(newAntiPortal); + + // tell the portal which zone it's currently in + newAntiPortal->setCurrentHomeZone(this); + } + } + + /* Remove an anti portal from the zone */ + void PCZone::_removeAntiPortal(AntiPortal* removeAntiPortal) + { + if (removeAntiPortal) + { + mAntiPortals.erase(std::find(mAntiPortals.begin(), mAntiPortals.end(), removeAntiPortal)); + } + } + + /* create node specific zone data if necessary + */ + void PCZone::createNodeZoneData(PCZSceneNode *) + { + } + + /* get the aabb of the zone - default implementation + uses the enclosure node, but there are other perhaps + better ways + */ + void PCZone::getAABB(AxisAlignedBox & aabb) + { + // if there is no node, just return a null box + if (mEnclosureNode == 0) + { + aabb.setNull(); + } + else + { + aabb = mEnclosureNode->_getWorldAABB(); + // since this is the "local" AABB, subtract out any translations + aabb.setMinimum(aabb.getMinimum() - mEnclosureNode->_getDerivedPosition()); + aabb.setMaximum(aabb.getMaximum() - mEnclosureNode->_getDerivedPosition()); + } + return; + } + + /***********************************************************************\ + ZoneData - Zone-specific Data structure for Scene Nodes ************************************************************************/ - ZoneData::ZoneData(PCZSceneNode * node, PCZone * zone) - { - mAssociatedZone = zone; - mAssociatedNode = node; - } + ZoneData::ZoneData(PCZSceneNode * node, PCZone * zone) + { + mAssociatedZone = zone; + mAssociatedNode = node; + } - ZoneData::~ZoneData() - { - } + ZoneData::~ZoneData() + { + } - void ZoneData::update(void) - { - } + void ZoneData::update(void) + { + } } diff --git a/PlugIns/PCZSceneManager/src/OgrePCZoneFactory.cpp b/PlugIns/PCZSceneManager/src/OgrePCZoneFactory.cpp index 1ecc0f9a5b9..39c23174ccc 100644 --- a/PlugIns/PCZSceneManager/src/OgrePCZoneFactory.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePCZoneFactory.cpp @@ -30,7 +30,7 @@ OgrePCZoneFactory.cpp - PCZone Factory & Factory Manager begin : Mon Apr 16 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -40,37 +40,37 @@ Code Style Update : namespace Ogre { - //------------------------------------------------------------------------- - // PCZoneFactory functions - PCZoneFactory::PCZoneFactory(const String & typeName) : mFactoryTypeName(typeName) - { - } - PCZoneFactory::~PCZoneFactory() - { - } - //------------------------------------------------------------------------- - // DefaultZoneFactory functions - //String defaultString = String("ZoneType_Default"); - DefaultZoneFactory::DefaultZoneFactory() : PCZoneFactory("ZoneType_Default") - { - } - DefaultZoneFactory::~DefaultZoneFactory() - { - } - bool DefaultZoneFactory::supportsPCZoneType(const String& zoneType) - { - if (mFactoryTypeName == zoneType) - { - return true; - } - return false; - } - PCZone* DefaultZoneFactory::createPCZone(PCZSceneManager * pczsm, const String& zoneName) - { - return OGRE_NEW DefaultZone(pczsm, zoneName); - } - //------------------------------------------------------------------------- - // PCZoneFactoryManager functions + //------------------------------------------------------------------------- + // PCZoneFactory functions + PCZoneFactory::PCZoneFactory(const String & typeName) : mFactoryTypeName(typeName) + { + } + PCZoneFactory::~PCZoneFactory() + { + } + //------------------------------------------------------------------------- + // DefaultZoneFactory functions + //String defaultString = String("ZoneType_Default"); + DefaultZoneFactory::DefaultZoneFactory() : PCZoneFactory("ZoneType_Default") + { + } + DefaultZoneFactory::~DefaultZoneFactory() + { + } + bool DefaultZoneFactory::supportsPCZoneType(const String& zoneType) + { + if (mFactoryTypeName == zoneType) + { + return true; + } + return false; + } + PCZone* DefaultZoneFactory::createPCZone(PCZSceneManager * pczsm, const String& zoneName) + { + return OGRE_NEW DefaultZone(pczsm, zoneName); + } + //------------------------------------------------------------------------- + // PCZoneFactoryManager functions template<> PCZoneFactoryManager* Singleton::msSingleton = 0; PCZoneFactoryManager* PCZoneFactoryManager::getSingletonPtr(void) { @@ -80,63 +80,63 @@ namespace Ogre { assert( msSingleton ); return ( *msSingleton ); } - PCZoneFactoryManager::PCZoneFactoryManager() - { + PCZoneFactoryManager::PCZoneFactoryManager() + { registerPCZoneFactory(&mDefaultFactory); - } - PCZoneFactoryManager::~PCZoneFactoryManager() - { - } + } + PCZoneFactoryManager::~PCZoneFactoryManager() + { + } - void PCZoneFactoryManager::registerPCZoneFactory(PCZoneFactory* factory) - { - String name = factory->getFactoryTypeName(); + void PCZoneFactoryManager::registerPCZoneFactory(PCZoneFactory* factory) + { + String name = factory->getFactoryTypeName(); mPCZoneFactories[name] = factory; LogManager::getSingleton().logMessage("PCZone Factory Type '" + name + "' registered"); - } - void PCZoneFactoryManager::unregisterPCZoneFactory(PCZoneFactory* factory) - { - if (factory) - { - //find and remove factory from mPCZoneFactories - // Note that this does not free the factory from memory, just removes from the factory manager - String name = factory->getFactoryTypeName(); - PCZoneFactoryMap::iterator zi = mPCZoneFactories.find(name); - if (zi != mPCZoneFactories.end()) - { - mPCZoneFactories.erase( mPCZoneFactories.find( name ) ); - LogManager::getSingleton().logMessage("PCZone Factory Type '" + name + "' unregistered"); - } - } - } - PCZone* PCZoneFactoryManager::createPCZone(PCZSceneManager * pczsm, - const String& zoneType, - const String& zoneName) - { - //find a factory that supports this zone type and then call createPCZone() on it - PCZone * inst = 0; - for(PCZoneFactoryMap::iterator i = mPCZoneFactories.begin(); i != mPCZoneFactories.end(); ++i) - { - if (i->second->supportsPCZoneType(zoneType)) - { - // use this factory - inst = i->second->createPCZone(pczsm, zoneName); - } - } - if (!inst) - { - // Error! - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "No factory found for zone of type '" + zoneType + "'", - "PCZoneFactoryManager::createPCZone"); - } - return inst; - } - //----------------------------------------------------------------------- - PCZoneFactoryManager::PCZoneFactoryIterator - PCZoneFactoryManager::getPCZoneFactoryIterator(void) - { - return PCZoneFactoryIterator(mPCZoneFactories.begin(), mPCZoneFactories.end()); - } + } + void PCZoneFactoryManager::unregisterPCZoneFactory(PCZoneFactory* factory) + { + if (factory) + { + //find and remove factory from mPCZoneFactories + // Note that this does not free the factory from memory, just removes from the factory manager + String name = factory->getFactoryTypeName(); + PCZoneFactoryMap::iterator zi = mPCZoneFactories.find(name); + if (zi != mPCZoneFactories.end()) + { + mPCZoneFactories.erase( mPCZoneFactories.find( name ) ); + LogManager::getSingleton().logMessage("PCZone Factory Type '" + name + "' unregistered"); + } + } + } + PCZone* PCZoneFactoryManager::createPCZone(PCZSceneManager * pczsm, + const String& zoneType, + const String& zoneName) + { + //find a factory that supports this zone type and then call createPCZone() on it + PCZone * inst = 0; + for(PCZoneFactoryMap::iterator i = mPCZoneFactories.begin(); i != mPCZoneFactories.end(); ++i) + { + if (i->second->supportsPCZoneType(zoneType)) + { + // use this factory + inst = i->second->createPCZone(pczsm, zoneName); + } + } + if (!inst) + { + // Error! + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "No factory found for zone of type '" + zoneType + "'", + "PCZoneFactoryManager::createPCZone"); + } + return inst; + } + //----------------------------------------------------------------------- + PCZoneFactoryManager::PCZoneFactoryIterator + PCZoneFactoryManager::getPCZoneFactoryIterator(void) + { + return PCZoneFactoryIterator(mPCZoneFactories.begin(), mPCZoneFactories.end()); + } } diff --git a/PlugIns/PCZSceneManager/src/OgrePortal.cpp b/PlugIns/PCZSceneManager/src/OgrePortal.cpp index 2d59e7cbfef..5f2f9433543 100644 --- a/PlugIns/PCZSceneManager/src/OgrePortal.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePortal.cpp @@ -38,9 +38,9 @@ current TODO's : none known using namespace Ogre; Portal::Portal(const String& name, const PORTAL_TYPE type) - : PortalBase(name, type), - mTargetZone(0), - mTargetPortal(0) + : PortalBase(name, type), + mTargetZone(0), + mTargetPortal(0) { } @@ -51,19 +51,19 @@ Portal::~Portal() // Set the 1st Zone the Portal connects to void Portal::setTargetZone(PCZone* zone) { - mTargetZone = zone; + mTargetZone = zone; } // Set the Portal the Portal connects to void Portal::setTargetPortal(Portal* portal) { - mTargetPortal = portal; + mTargetPortal = portal; } /** @copydoc MovableObject::getMovableType. */ const String& Portal::getMovableType() const { - return PortalFactory::FACTORY_TYPE_NAME; + return PortalFactory::FACTORY_TYPE_NAME; } //----------------------------------------------------------------------- @@ -73,10 +73,10 @@ unsigned long PortalFactory::FACTORY_TYPE_FLAG = 0xFFFFFFFF; MovableObject* PortalFactory::createInstanceImpl(const String& name, const NameValuePairList* params) { - return OGRE_NEW Portal(name, getPortalType(params)); + return OGRE_NEW Portal(name, getPortalType(params)); } void PortalFactory::destroyInstance(MovableObject* obj) { - OGRE_DELETE obj; + OGRE_DELETE obj; } diff --git a/PlugIns/PCZSceneManager/src/OgrePortalBase.cpp b/PlugIns/PCZSceneManager/src/OgrePortalBase.cpp index dab3ed48197..81d7fcd391f 100644 --- a/PlugIns/PCZSceneManager/src/OgrePortalBase.cpp +++ b/PlugIns/PCZSceneManager/src/OgrePortalBase.cpp @@ -36,103 +36,103 @@ PortalBase.cpp - using namespace Ogre; PortalBase::PortalBase(const String& name, const PORTAL_TYPE type) - : MovableObject(name), - mType(type), - mCurrentHomeZone(0), - mNewHomeZone(0), + : MovableObject(name), + mType(type), + mCurrentHomeZone(0), + mNewHomeZone(0), mDirection(Vector3::UNIT_Z), - mRadius(0.0), - mLocalsUpToDate(false), - mDerivedUpToDate(false), - // set prevWorldTransform to a zero'd out matrix - mPrevWorldTransform(Matrix4::ZERO), - // default to enabled - mEnabled(true), - mWasMoved(true) + mRadius(0.0), + mLocalsUpToDate(false), + mDerivedUpToDate(false), + // set prevWorldTransform to a zero'd out matrix + mPrevWorldTransform(Matrix4::ZERO), + // default to enabled + mEnabled(true), + mWasMoved(true) { - switch (mType) - { - default: - case PORTAL_TYPE_QUAD: - mCorners = OGRE_ALLOC_T(Vector3, 4, MEMCATEGORY_SCENE_CONTROL); - mDerivedCorners = OGRE_ALLOC_T(Vector3, 4, MEMCATEGORY_SCENE_CONTROL); - break; - case PORTAL_TYPE_AABB: - mCorners = OGRE_ALLOC_T(Vector3, 2, MEMCATEGORY_SCENE_CONTROL); - mDerivedCorners = OGRE_ALLOC_T(Vector3, 2, MEMCATEGORY_SCENE_CONTROL); - break; - case PORTAL_TYPE_SPHERE: - mCorners = OGRE_ALLOC_T(Vector3, 2, MEMCATEGORY_SCENE_CONTROL); - mDerivedCorners = OGRE_ALLOC_T(Vector3, 2, MEMCATEGORY_SCENE_CONTROL); - break; - } + switch (mType) + { + default: + case PORTAL_TYPE_QUAD: + mCorners = OGRE_ALLOC_T(Vector3, 4, MEMCATEGORY_SCENE_CONTROL); + mDerivedCorners = OGRE_ALLOC_T(Vector3, 4, MEMCATEGORY_SCENE_CONTROL); + break; + case PORTAL_TYPE_AABB: + mCorners = OGRE_ALLOC_T(Vector3, 2, MEMCATEGORY_SCENE_CONTROL); + mDerivedCorners = OGRE_ALLOC_T(Vector3, 2, MEMCATEGORY_SCENE_CONTROL); + break; + case PORTAL_TYPE_SPHERE: + mCorners = OGRE_ALLOC_T(Vector3, 2, MEMCATEGORY_SCENE_CONTROL); + mDerivedCorners = OGRE_ALLOC_T(Vector3, 2, MEMCATEGORY_SCENE_CONTROL); + break; + } } PortalBase::~PortalBase() { - if (mCorners) - OGRE_FREE(mCorners, MEMCATEGORY_SCENE_CONTROL); - mCorners = 0; - if (mDerivedCorners) - OGRE_FREE(mDerivedCorners, MEMCATEGORY_SCENE_CONTROL); - mDerivedCorners = 0; + if (mCorners) + OGRE_FREE(mCorners, MEMCATEGORY_SCENE_CONTROL); + mCorners = 0; + if (mDerivedCorners) + OGRE_FREE(mDerivedCorners, MEMCATEGORY_SCENE_CONTROL); + mDerivedCorners = 0; } const AxisAlignedBox& PortalBase::getWorldBoundingBox(bool derive) const { -// if (derive) -// { -// updateDerivedValues(); -// } +// if (derive) +// { +// updateDerivedValues(); +// } - return mPortalAAB; + return mPortalAAB; } const Sphere& PortalBase::getWorldBoundingSphere(bool derive) const { -// if (derive) -// { -// updateDerivedValues(); -// } +// if (derive) +// { +// updateDerivedValues(); +// } - return mDerivedSphere; + return mDerivedSphere; } // Set the SceneNode the Portal is associated with void PortalBase::setNode(SceneNode* sn) { - if (mParentNode) ((SceneNode*)mParentNode)->detachObject(this); - if (sn) sn->attachObject(this); + if (mParentNode) ((SceneNode*)mParentNode)->detachObject(this); + if (sn) sn->attachObject(this); } // Set the zone this portal is in. void PortalBase::setCurrentHomeZone(PCZone* zone) { - // do this here since more than one function calls setCurrentHomeZone - // also _addPortal is abstract, so easier to do it here. - if(zone) - { - // inform old zone of portal change. - if(mCurrentHomeZone) - { - mCurrentHomeZone->setPortalsUpdated(true); - } - zone->setPortalsUpdated(true); // inform new zone of portal change - } - mCurrentHomeZone = zone; + // do this here since more than one function calls setCurrentHomeZone + // also _addPortal is abstract, so easier to do it here. + if(zone) + { + // inform old zone of portal change. + if(mCurrentHomeZone) + { + mCurrentHomeZone->setPortalsUpdated(true); + } + zone->setPortalsUpdated(true); // inform new zone of portal change + } + mCurrentHomeZone = zone; } // Set the zone this portal should be moved to void PortalBase::setNewHomeZone(PCZone* zone) { - mNewHomeZone = zone; + mNewHomeZone = zone; } // Set the local coordinates of one of the portal corners void PortalBase::setCorner(int index, const Vector3& point) { - mCorners[index] = point; - mLocalsUpToDate = false; - mDerivedUpToDate = false; + mCorners[index] = point; + mLocalsUpToDate = false; + mDerivedUpToDate = false; } /** Set the local coordinates of all of the portal corners */ @@ -141,241 +141,241 @@ void PortalBase::setCorner(int index, const Vector3& point) // there are 2 corners if the portal is a sphere type (center and point on sphere) void PortalBase::setCorners(const Vector3* corners) { - switch (mType) - { - default: - case PORTAL_TYPE_QUAD: - mCorners[0] = corners[0]; - mCorners[1] = corners[1]; - mCorners[2] = corners[2]; - mCorners[3] = corners[3]; - break; - case PORTAL_TYPE_AABB: - mCorners[0] = corners[0]; // minimum corner - mCorners[1] = corners[1]; // maximum corner (opposite from min corner) - break; - case PORTAL_TYPE_SPHERE: - mCorners[0] = corners[0]; // center point - mCorners[1] = corners[1]; // point on sphere surface - break; - } - mLocalsUpToDate = false; - mDerivedUpToDate = false; + switch (mType) + { + default: + case PORTAL_TYPE_QUAD: + mCorners[0] = corners[0]; + mCorners[1] = corners[1]; + mCorners[2] = corners[2]; + mCorners[3] = corners[3]; + break; + case PORTAL_TYPE_AABB: + mCorners[0] = corners[0]; // minimum corner + mCorners[1] = corners[1]; // maximum corner (opposite from min corner) + break; + case PORTAL_TYPE_SPHERE: + mCorners[0] = corners[0]; // center point + mCorners[1] = corners[1]; // point on sphere surface + break; + } + mLocalsUpToDate = false; + mDerivedUpToDate = false; } // calculate the local direction of the portal from the corners void PortalBase::calcDirectionAndRadius(void) const { - Vector3 radiusVector; - Vector3 side1, side2; - - // for AAB building. - Vector3 min(Math::POS_INFINITY, Math::POS_INFINITY, Math::POS_INFINITY); - Vector3 max(Math::NEG_INFINITY, Math::NEG_INFINITY, Math::NEG_INFINITY); - - switch (mType) - { - default: - case PORTAL_TYPE_QUAD: - // first calculate local direction - side1 = mCorners[1] - mCorners[0]; - side2 = mCorners[2] - mCorners[0]; - mDirection = side1.crossProduct(side2); - mDirection.normalise(); - // calculate local cp - mLocalCP = Vector3::ZERO; - for (int i=0;i<4;i++) - { - mLocalCP += mCorners[i]; - - min.makeFloor(mCorners[i]); - max.makeCeil(mCorners[i]); - } - mLocalCP *= 0.25f; - // then calculate radius - radiusVector = mCorners[0] - mLocalCP; - mRadius = radiusVector.length(); - break; - case PORTAL_TYPE_AABB: - // "direction" is is either pointed inward or outward and is set by user, not calculated. - // calculate local cp - mLocalCP = Vector3::ZERO; - for (int i=0;i<2;i++) - { - mLocalCP += mCorners[i]; - } - mLocalCP *= 0.5f; - // for radius, use distance from corner to center point - // this gives the radius of a sphere that encapsulates the aabb - radiusVector = mCorners[0] - mLocalCP; - mRadius = radiusVector.length(); - - min = mCorners[0]; - max = mCorners[1]; - break; - case PORTAL_TYPE_SPHERE: - // "direction" is is either pointed inward or outward and is set by user, not calculated. - // local CP is same as corner point 0 - mLocalCP = mCorners[0]; - // since corner1 is point on sphere, radius is simply corner1 - center point - radiusVector = mCorners[1] - mLocalCP; - mRadius = radiusVector.length(); - - min = mDerivedCP - mRadius; - max = mDerivedCP + mRadius; - break; - } - mDerivedSphere.setRadius(mRadius); - mLocalPortalAAB.setExtents(min, max); - // locals are now up to date - mLocalsUpToDate = true; + Vector3 radiusVector; + Vector3 side1, side2; + + // for AAB building. + Vector3 min(Math::POS_INFINITY, Math::POS_INFINITY, Math::POS_INFINITY); + Vector3 max(Math::NEG_INFINITY, Math::NEG_INFINITY, Math::NEG_INFINITY); + + switch (mType) + { + default: + case PORTAL_TYPE_QUAD: + // first calculate local direction + side1 = mCorners[1] - mCorners[0]; + side2 = mCorners[2] - mCorners[0]; + mDirection = side1.crossProduct(side2); + mDirection.normalise(); + // calculate local cp + mLocalCP = Vector3::ZERO; + for (int i=0;i<4;i++) + { + mLocalCP += mCorners[i]; + + min.makeFloor(mCorners[i]); + max.makeCeil(mCorners[i]); + } + mLocalCP *= 0.25f; + // then calculate radius + radiusVector = mCorners[0] - mLocalCP; + mRadius = radiusVector.length(); + break; + case PORTAL_TYPE_AABB: + // "direction" is is either pointed inward or outward and is set by user, not calculated. + // calculate local cp + mLocalCP = Vector3::ZERO; + for (int i=0;i<2;i++) + { + mLocalCP += mCorners[i]; + } + mLocalCP *= 0.5f; + // for radius, use distance from corner to center point + // this gives the radius of a sphere that encapsulates the aabb + radiusVector = mCorners[0] - mLocalCP; + mRadius = radiusVector.length(); + + min = mCorners[0]; + max = mCorners[1]; + break; + case PORTAL_TYPE_SPHERE: + // "direction" is is either pointed inward or outward and is set by user, not calculated. + // local CP is same as corner point 0 + mLocalCP = mCorners[0]; + // since corner1 is point on sphere, radius is simply corner1 - center point + radiusVector = mCorners[1] - mLocalCP; + mRadius = radiusVector.length(); + + min = mDerivedCP - mRadius; + max = mDerivedCP + mRadius; + break; + } + mDerivedSphere.setRadius(mRadius); + mLocalPortalAAB.setExtents(min, max); + // locals are now up to date + mLocalsUpToDate = true; } // Calculate the local bounding sphere of the portal from the corner points Real PortalBase::getRadius( void ) const { - if (!mLocalsUpToDate) - { - calcDirectionAndRadius(); - } - return mRadius; + if (!mLocalsUpToDate) + { + calcDirectionAndRadius(); + } + return mRadius; } // Update (Calculate) the world spatial values void PortalBase::updateDerivedValues(void) const { - // make sure local values are up to date - if (!mLocalsUpToDate) - { - calcDirectionAndRadius(); - } - int numCorners = 4; - if (mType == PORTAL_TYPE_AABB) - numCorners = 2; - else if (mType == PORTAL_TYPE_SPHERE) - numCorners = 2; - - // calculate derived values - if (mParentNode) - { - if(mCurrentHomeZone) - { - // inform home zone that a portal has been updated - mCurrentHomeZone->setPortalsUpdated(true); - } - // save world transform - Matrix4 transform = mParentNode->_getFullTransform(); - Matrix3 rotation; - // save off the current DerivedCP - mPrevDerivedCP = mDerivedCP; - mDerivedCP = transform * mLocalCP; - mDerivedSphere.setCenter(mDerivedCP); - switch(mType) - { - case PORTAL_TYPE_QUAD: - for (int i=0;i_getWorldAABB(); - //aabb.transform(mParentNode->_getFullTransform()); - mDerivedCorners[0] = aabb.getMinimum(); - mDerivedCorners[1] = aabb.getMaximum(); - mDerivedDirection = mDirection; - } - break; - case PORTAL_TYPE_SPHERE: - { - mDerivedCorners[0] = mDerivedCP; - mDerivedCorners[1] = transform * mCorners[1]; - mDerivedDirection = mDirection; - } - break; - } - if (mPrevWorldTransform != Matrix4::ZERO) - { - // save previous calc'd plane - mPrevDerivedPlane = mDerivedPlane; - // calc new plane - mDerivedPlane = Ogre::Plane(mDerivedDirection, mDerivedCP); - // only update prevWorldTransform if did not move - // we need to add this conditional to ensure that - // the portal fully updates when it changes position. - if (mPrevDerivedPlane == mDerivedPlane && - mPrevDerivedCP == mDerivedCP) - { - mPrevWorldTransform = transform; - } - mPrevDerivedCP = mDerivedCP; - } - else - { - // calc new plane - mDerivedPlane = Ogre::Plane(mDerivedDirection, mDerivedCP); - // this is first time, so there is no previous, so prev = current. - mPrevDerivedPlane = mDerivedPlane; - mPrevDerivedCP = mDerivedCP; - mPrevWorldTransform = Matrix4::IDENTITY; - mPrevWorldTransform = transform; - } - } - else // no associated node, so just use the local values as derived values - { - if (mPrevWorldTransform != Matrix4::ZERO) - { - // save off the current DerivedCP - mPrevDerivedCP = mDerivedCP; - mDerivedCP = mLocalCP; - mDerivedSphere.setCenter(mDerivedCP); - for (int i=0;isetPortalsUpdated(true); - } - // this is the first time the derived CP has been calculated, so there - // is no "previous" value, so set previous = current. - mDerivedCP = mLocalCP; - mPrevDerivedCP = mDerivedCP; - mDerivedSphere.setCenter(mDerivedCP); - for (int i=0;isetPortalsUpdated(true); + } + // save world transform + Matrix4 transform = mParentNode->_getFullTransform(); + Matrix3 rotation; + // save off the current DerivedCP + mPrevDerivedCP = mDerivedCP; + mDerivedCP = transform * mLocalCP; + mDerivedSphere.setCenter(mDerivedCP); + switch(mType) + { + case PORTAL_TYPE_QUAD: + for (int i=0;i_getWorldAABB(); + //aabb.transform(mParentNode->_getFullTransform()); + mDerivedCorners[0] = aabb.getMinimum(); + mDerivedCorners[1] = aabb.getMaximum(); + mDerivedDirection = mDirection; + } + break; + case PORTAL_TYPE_SPHERE: + { + mDerivedCorners[0] = mDerivedCP; + mDerivedCorners[1] = transform * mCorners[1]; + mDerivedDirection = mDirection; + } + break; + } + if (mPrevWorldTransform != Matrix4::ZERO) + { + // save previous calc'd plane + mPrevDerivedPlane = mDerivedPlane; + // calc new plane + mDerivedPlane = Ogre::Plane(mDerivedDirection, mDerivedCP); + // only update prevWorldTransform if did not move + // we need to add this conditional to ensure that + // the portal fully updates when it changes position. + if (mPrevDerivedPlane == mDerivedPlane && + mPrevDerivedCP == mDerivedCP) + { + mPrevWorldTransform = transform; + } + mPrevDerivedCP = mDerivedCP; + } + else + { + // calc new plane + mDerivedPlane = Ogre::Plane(mDerivedDirection, mDerivedCP); + // this is first time, so there is no previous, so prev = current. + mPrevDerivedPlane = mDerivedPlane; + mPrevDerivedCP = mDerivedCP; + mPrevWorldTransform = Matrix4::IDENTITY; + mPrevWorldTransform = transform; + } + } + else // no associated node, so just use the local values as derived values + { + if (mPrevWorldTransform != Matrix4::ZERO) + { + // save off the current DerivedCP + mPrevDerivedCP = mDerivedCP; + mDerivedCP = mLocalCP; + mDerivedSphere.setCenter(mDerivedCP); + for (int i=0;isetPortalsUpdated(true); + } + // this is the first time the derived CP has been calculated, so there + // is no "previous" value, so set previous = current. + mDerivedCP = mLocalCP; + mPrevDerivedCP = mDerivedCP; + mDerivedSphere.setCenter(mDerivedCP); + for (int i=0;isetPosition(mLocalCP); - - // move the corner points to be relative to the node - int numCorners = 4; - if (mType == PORTAL_TYPE_AABB) - numCorners = 2; - else if (mType == PORTAL_TYPE_SPHERE) - numCorners = 2; - - for (i=0;isetOrientation(q); - } - - // set the node as the portal's associated node - setNode(node); - - return; + int i; + + // make sure local values are up to date + if (!mLocalsUpToDate) + { + calcDirectionAndRadius(); + } + // move the parent node to the center point + node->setPosition(mLocalCP); + + // move the corner points to be relative to the node + int numCorners = 4; + if (mType == PORTAL_TYPE_AABB) + numCorners = 2; + else if (mType == PORTAL_TYPE_SPHERE) + numCorners = 2; + + for (i=0;isetOrientation(q); + } + + // set the node as the portal's associated node + setNode(node); + + return; } // Check if a portal intersects an AABB // NOTE: This check is not exact. bool PortalBase::intersects(const AxisAlignedBox& aab) { - // Only check if portal is enabled - if (mEnabled) - { - switch(mType) - { - case PORTAL_TYPE_QUAD: - // since ogre doesn't have built in support for a quad, just check - // if the box intersects both the sphere of the portal and the plane - // this can result in false positives, but they will be minimal - if (!aab.intersects(mDerivedSphere)) - { - return false; - } - if (aab.intersects(mDerivedPlane)) - { - return true; - } - break; - case PORTAL_TYPE_AABB: - { - // aab to aab check - AxisAlignedBox aabb; - aabb.setExtents(mDerivedCorners[0], mDerivedCorners[1]); - return (aab.intersects(aabb)); - } - case PORTAL_TYPE_SPHERE: - // aab to sphere check - return (aab.intersects(mDerivedSphere)); - } - } - return false; + // Only check if portal is enabled + if (mEnabled) + { + switch(mType) + { + case PORTAL_TYPE_QUAD: + // since ogre doesn't have built in support for a quad, just check + // if the box intersects both the sphere of the portal and the plane + // this can result in false positives, but they will be minimal + if (!aab.intersects(mDerivedSphere)) + { + return false; + } + if (aab.intersects(mDerivedPlane)) + { + return true; + } + break; + case PORTAL_TYPE_AABB: + { + // aab to aab check + AxisAlignedBox aabb; + aabb.setExtents(mDerivedCorners[0], mDerivedCorners[1]); + return (aab.intersects(aabb)); + } + case PORTAL_TYPE_SPHERE: + // aab to sphere check + return (aab.intersects(mDerivedSphere)); + } + } + return false; } // Check if a portal intersects a sphere // NOTE: This check is not exact. bool PortalBase::intersects(const Sphere& sphere) { - // Only check if portal is enabled - if (mEnabled) - { - switch(mType) - { - case PORTAL_TYPE_QUAD: - // since ogre doesn't have built in support for a quad, just check - // if the sphere intersects both the sphere of the portal and the plane - // this can result in false positives, but they will be minimal - if (!sphere.intersects(mDerivedSphere)) - { - return false; - } - if (sphere.intersects(mDerivedPlane)) - { - return true; - } - break; - case PORTAL_TYPE_AABB: - { - // aab to aab check - AxisAlignedBox aabb; - aabb.setExtents(mDerivedCorners[0], mDerivedCorners[1]); - return (aabb.intersects(sphere)); - } - case PORTAL_TYPE_SPHERE: - return (mDerivedSphere.intersects(sphere)); - } - } - return false; + // Only check if portal is enabled + if (mEnabled) + { + switch(mType) + { + case PORTAL_TYPE_QUAD: + // since ogre doesn't have built in support for a quad, just check + // if the sphere intersects both the sphere of the portal and the plane + // this can result in false positives, but they will be minimal + if (!sphere.intersects(mDerivedSphere)) + { + return false; + } + if (sphere.intersects(mDerivedPlane)) + { + return true; + } + break; + case PORTAL_TYPE_AABB: + { + // aab to aab check + AxisAlignedBox aabb; + aabb.setExtents(mDerivedCorners[0], mDerivedCorners[1]); + return (aabb.intersects(sphere)); + } + case PORTAL_TYPE_SPHERE: + return (mDerivedSphere.intersects(sphere)); + } + } + return false; } // Check if a portal intersects a plane bounded volume @@ -498,481 +498,481 @@ bool PortalBase::intersects(const Sphere& sphere) // NOTE: UNTESTED as of 5/30/07 (EC) bool PortalBase::intersects(const PlaneBoundedVolume& pbv) { - // Only check if portal is enabled - if (mEnabled) - { - switch(mType) - { - case PORTAL_TYPE_QUAD: - { - // first check sphere of the portal - if (!pbv.intersects(mDerivedSphere)) - { - return false; - } - // if the portal corners are all outside one of the planes of the pbv, - // then the portal does not intersect the pbv. (this can result in - // some false positives, but it's the best I can do for now) - PlaneList::const_iterator it = pbv.planes.begin(); - while (it != pbv.planes.end()) - { - const Plane& plane = *it; - // check if all 4 corners of the portal are on negative side of the pbv - bool allOutside = true; - for (int i=0;i<4;i++) - { - if (plane.getSide(mDerivedCorners[i]) != pbv.outside) - { - allOutside = false; - } - } - if (allOutside) - { - return false; - } - it++; - }; - } - break; - case PORTAL_TYPE_AABB: - { - AxisAlignedBox aabb; - aabb.setExtents(mDerivedCorners[0], mDerivedCorners[1]); - if (!pbv.intersects(aabb)) - { - return false; - } - } - break; - case PORTAL_TYPE_SPHERE: - if (!pbv.intersects(mDerivedSphere)) - { - return false; - } - break; - } - } - return false; + // Only check if portal is enabled + if (mEnabled) + { + switch(mType) + { + case PORTAL_TYPE_QUAD: + { + // first check sphere of the portal + if (!pbv.intersects(mDerivedSphere)) + { + return false; + } + // if the portal corners are all outside one of the planes of the pbv, + // then the portal does not intersect the pbv. (this can result in + // some false positives, but it's the best I can do for now) + PlaneList::const_iterator it = pbv.planes.begin(); + while (it != pbv.planes.end()) + { + const Plane& plane = *it; + // check if all 4 corners of the portal are on negative side of the pbv + bool allOutside = true; + for (int i=0;i<4;i++) + { + if (plane.getSide(mDerivedCorners[i]) != pbv.outside) + { + allOutside = false; + } + } + if (allOutside) + { + return false; + } + it++; + }; + } + break; + case PORTAL_TYPE_AABB: + { + AxisAlignedBox aabb; + aabb.setExtents(mDerivedCorners[0], mDerivedCorners[1]); + if (!pbv.intersects(aabb)) + { + return false; + } + } + break; + case PORTAL_TYPE_SPHERE: + if (!pbv.intersects(mDerivedSphere)) + { + return false; + } + break; + } + } + return false; } // Check if a portal intersects a ray // NOTE: Kinda using my own invented routine here for quad portals... Better do a lot of testing! bool PortalBase::intersects(const Ray& ray ) { - // Only check if portal is enabled - if (mEnabled) - { - if (mType == PORTAL_TYPE_QUAD) - { - // since ogre doesn't have built in support for a quad, I'm going to first - // find the intersection point (if any) of the ray and the portal plane. Then - // using the intersection point, I take the cross product of each side of the portal - // (0,1,intersect), (1,2, intersect), (2,3, intersect), and (3,0,intersect). If - // all 4 cross products have vectors pointing in the same direction, then the - // intersection point is within the portal, otherwise it is outside. - - std::pair result = ray.intersects(mDerivedPlane); - - if (result.first == true) - { - // the ray intersects the plane, now walk around the edges - Vector3 isect = ray.getPoint(result.second); - Vector3 cross, vect1, vect2; - Vector3 cross2, vect3, vect4; - vect1 = mDerivedCorners[1] - mDerivedCorners[0]; - vect2 = isect - mDerivedCorners[0]; - cross = vect1.crossProduct(vect2); - vect3 = mDerivedCorners[2] - mDerivedCorners[1]; - vect4 = isect - mDerivedCorners[1]; - cross2 = vect3.crossProduct(vect4); - if (cross.dotProduct(cross2) < 0) - { - return false; - } - vect1 = mDerivedCorners[3] - mDerivedCorners[2]; - vect2 = isect - mDerivedCorners[2]; - cross = vect1.crossProduct(vect2); - if (cross.dotProduct(cross2) < 0) - { - return false; - } - vect1 = mDerivedCorners[0] - mDerivedCorners[3]; - vect2 = isect - mDerivedCorners[3]; - cross = vect1.crossProduct(vect2); - if (cross.dotProduct(cross2) < 0) - { - return false; - } - // all cross products pointing same way, so intersect - // must be on the inside of the portal! - return true; - } - - return false; - } - else if (mType == PORTAL_TYPE_AABB) - { - AxisAlignedBox aabb; - aabb.setExtents(mDerivedCorners[0], mDerivedCorners[1]); - std::pair result = ray.intersects(aabb); - return result.first; - } - else // sphere - { - std::pair result = ray.intersects(mDerivedSphere); - return result.first; - } - } - return false; + // Only check if portal is enabled + if (mEnabled) + { + if (mType == PORTAL_TYPE_QUAD) + { + // since ogre doesn't have built in support for a quad, I'm going to first + // find the intersection point (if any) of the ray and the portal plane. Then + // using the intersection point, I take the cross product of each side of the portal + // (0,1,intersect), (1,2, intersect), (2,3, intersect), and (3,0,intersect). If + // all 4 cross products have vectors pointing in the same direction, then the + // intersection point is within the portal, otherwise it is outside. + + std::pair result = ray.intersects(mDerivedPlane); + + if (result.first == true) + { + // the ray intersects the plane, now walk around the edges + Vector3 isect = ray.getPoint(result.second); + Vector3 cross, vect1, vect2; + Vector3 cross2, vect3, vect4; + vect1 = mDerivedCorners[1] - mDerivedCorners[0]; + vect2 = isect - mDerivedCorners[0]; + cross = vect1.crossProduct(vect2); + vect3 = mDerivedCorners[2] - mDerivedCorners[1]; + vect4 = isect - mDerivedCorners[1]; + cross2 = vect3.crossProduct(vect4); + if (cross.dotProduct(cross2) < 0) + { + return false; + } + vect1 = mDerivedCorners[3] - mDerivedCorners[2]; + vect2 = isect - mDerivedCorners[2]; + cross = vect1.crossProduct(vect2); + if (cross.dotProduct(cross2) < 0) + { + return false; + } + vect1 = mDerivedCorners[0] - mDerivedCorners[3]; + vect2 = isect - mDerivedCorners[3]; + cross = vect1.crossProduct(vect2); + if (cross.dotProduct(cross2) < 0) + { + return false; + } + // all cross products pointing same way, so intersect + // must be on the inside of the portal! + return true; + } + + return false; + } + else if (mType == PORTAL_TYPE_AABB) + { + AxisAlignedBox aabb; + aabb.setExtents(mDerivedCorners[0], mDerivedCorners[1]); + std::pair result = ray.intersects(aabb); + return result.first; + } + else // sphere + { + std::pair result = ray.intersects(mDerivedSphere); + return result.first; + } + } + return false; } /* Test if a scene node intersected a portal during the last time delta - * (from last frame time to current frame time). This function checks - * if the node "crossed over" the portal also. + * (from last frame time to current frame time). This function checks + * if the node "crossed over" the portal also. */ PortalBase::PortalIntersectResult PortalBase::intersects(PCZSceneNode* pczsn) { - // Only check if portal is enabled - if (mEnabled) - { - if (pczsn == mParentNode) - { - // ignore the scene node if it is the node the portal is associated with - return PortalBase::NO_INTERSECT; - } - // most complicated case - if the portal is a quad: - if (mType == PORTAL_TYPE_QUAD) - { - // the node is modelled as a line segment (prevPostion to currentPosition) - // intersection test is then between the capsule and the line segment. - Segment nodeSegment; - nodeSegment.set(pczsn->getPrevPosition(), pczsn->_getDerivedPosition()); - - // we model the portal as a line swept sphere (mPrevDerivedCP to mDerivedCP). - if (getCapsule().intersects(nodeSegment)) - { - // the portal intersected the node at some time from last frame to this frame. - // Now check if node "crossed" the portal - // a crossing occurs if the "side" of the final position of the node compared - // to the final position of the portal is negative AND the initial position - // of the node compared to the initial position of the portal is non-negative - if (mDerivedPlane.getSide(pczsn->_getDerivedPosition()) == Plane::NEGATIVE_SIDE && - mPrevDerivedPlane.getSide(pczsn->getPrevPosition()) != Plane::NEGATIVE_SIDE) - { - // safety check - make sure the node has at least one dimension which is - // small enough to fit through the portal! (avoid the "elephant fitting - // through a mouse hole" case) - Vector3 nodeHalfVector = pczsn->_getWorldAABB().getHalfSize(); - Vector3 portalBox = Vector3(mRadius, mRadius, mRadius); - portalBox.makeFloor(nodeHalfVector); - if (portalBox.x < mRadius) - { - // crossing occurred! - return PortalBase::INTERSECT_CROSS; - } - } - } - // there was no crossing of the portal by the node, but it might be touching - // the portal. We check for this by checking the bounding box of the node vs. - // the sphere of the portal - if (mDerivedSphere.intersects(pczsn->_getWorldAABB()) && - mDerivedPlane.getSide(pczsn->_getWorldAABB()) == Plane::BOTH_SIDE ) - { - // intersection but no crossing - // note this means that the node is CURRENTLY touching the portal. - if (mDerivedPlane.getSide(pczsn->_getDerivedPosition()) != Plane::NEGATIVE_SIDE) - { - // the node is on the positive (front) or exactly on the CP of the portal - return PortalBase::INTERSECT_NO_CROSS; - } - else - { - // the node is on the negative (back) side of the portal - it might be in the wrong zone! - return PortalBase::INTERSECT_BACK_NO_CROSS; - } - } - // no intersection CURRENTLY. (there might have been an intersection - // during the time between last frame and this frame, but it wasn't a portal - // crossing, and it isn't touching anymore, so it doesn't matter. - return PortalBase::NO_INTERSECT; - } - else if (mType == PORTAL_TYPE_AABB) - { - // for aabb's we check if the center point went from being inside to being outside - // the aabb (or vice versa) for crossing. - AxisAlignedBox aabb; - aabb.setExtents(mDerivedCorners[0], mDerivedCorners[1]); - //bool previousInside = aabb.contains(pczsn->getPrevPosition()); - bool currentInside = aabb.contains(pczsn->_getDerivedPosition()); - if (mDirection == Vector3::UNIT_Z) - { - // portal norm is "outward" pointing, look for going from outside to inside - //if (previousInside == false && - if (currentInside == true) - { - return PortalBase::INTERSECT_CROSS; - } - } - else - { - // portal norm is "inward" pointing, look for going from inside to outside - //if (previousInside == true && - if (currentInside == false) - { - return PortalBase::INTERSECT_CROSS; - } - } - // doesn't cross, but might be touching. This is a little tricky because we only - // care if the node aab is NOT fully contained in the portal aabb because we consider - // the surface of the portal aabb the actual 'portal'. First, check to see if the - // aab of the node intersects the aabb portal - if (aabb.intersects(pczsn->_getWorldAABB())) - { - // now check if the intersection between the two is not the same as the - // full node aabb, if so, then this means that the node is not fully "contained" - // which is what we are looking for. - AxisAlignedBox overlap = aabb.intersection(pczsn->_getWorldAABB()); - if (overlap != pczsn->_getWorldAABB()) - { - return PortalBase::INTERSECT_NO_CROSS; - } - } - return PortalBase::NO_INTERSECT; - } - else - { - // for spheres we check if the center point went from being inside to being outside - // the sphere surface (or vice versa) for crossing. - //Real previousDistance2 = mPrevDerivedCP.squaredDistance(pczsn->getPrevPosition()); - Real currentDistance2 = mDerivedCP.squaredDistance(pczsn->_getDerivedPosition()); - Real mRadius2 = mRadius * mRadius; - if (mDirection == Vector3::UNIT_Z) - { - // portal norm is "outward" pointing, look for going from outside to inside - //if (previousDistance2 >= mRadius2 && - if (currentDistance2 < mRadius2) - { - return PortalBase::INTERSECT_CROSS; - } - } - else - { - // portal norm is "inward" pointing, look for going from inside to outside - //if (previousDistance2 < mRadius2 && - if (currentDistance2 >= mRadius2) - { - return PortalBase::INTERSECT_CROSS; - } - } - // no crossing, but might be touching - check distance - if (Math::Sqrt(Math::Abs(mRadius2 - currentDistance2)) <= mRadius) - { - return PortalBase::INTERSECT_NO_CROSS; - } - return PortalBase::NO_INTERSECT; - } - } - return PortalBase::NO_INTERSECT; + // Only check if portal is enabled + if (mEnabled) + { + if (pczsn == mParentNode) + { + // ignore the scene node if it is the node the portal is associated with + return PortalBase::NO_INTERSECT; + } + // most complicated case - if the portal is a quad: + if (mType == PORTAL_TYPE_QUAD) + { + // the node is modelled as a line segment (prevPostion to currentPosition) + // intersection test is then between the capsule and the line segment. + Segment nodeSegment; + nodeSegment.set(pczsn->getPrevPosition(), pczsn->_getDerivedPosition()); + + // we model the portal as a line swept sphere (mPrevDerivedCP to mDerivedCP). + if (getCapsule().intersects(nodeSegment)) + { + // the portal intersected the node at some time from last frame to this frame. + // Now check if node "crossed" the portal + // a crossing occurs if the "side" of the final position of the node compared + // to the final position of the portal is negative AND the initial position + // of the node compared to the initial position of the portal is non-negative + if (mDerivedPlane.getSide(pczsn->_getDerivedPosition()) == Plane::NEGATIVE_SIDE && + mPrevDerivedPlane.getSide(pczsn->getPrevPosition()) != Plane::NEGATIVE_SIDE) + { + // safety check - make sure the node has at least one dimension which is + // small enough to fit through the portal! (avoid the "elephant fitting + // through a mouse hole" case) + Vector3 nodeHalfVector = pczsn->_getWorldAABB().getHalfSize(); + Vector3 portalBox = Vector3(mRadius, mRadius, mRadius); + portalBox.makeFloor(nodeHalfVector); + if (portalBox.x < mRadius) + { + // crossing occurred! + return PortalBase::INTERSECT_CROSS; + } + } + } + // there was no crossing of the portal by the node, but it might be touching + // the portal. We check for this by checking the bounding box of the node vs. + // the sphere of the portal + if (mDerivedSphere.intersects(pczsn->_getWorldAABB()) && + mDerivedPlane.getSide(pczsn->_getWorldAABB()) == Plane::BOTH_SIDE ) + { + // intersection but no crossing + // note this means that the node is CURRENTLY touching the portal. + if (mDerivedPlane.getSide(pczsn->_getDerivedPosition()) != Plane::NEGATIVE_SIDE) + { + // the node is on the positive (front) or exactly on the CP of the portal + return PortalBase::INTERSECT_NO_CROSS; + } + else + { + // the node is on the negative (back) side of the portal - it might be in the wrong zone! + return PortalBase::INTERSECT_BACK_NO_CROSS; + } + } + // no intersection CURRENTLY. (there might have been an intersection + // during the time between last frame and this frame, but it wasn't a portal + // crossing, and it isn't touching anymore, so it doesn't matter. + return PortalBase::NO_INTERSECT; + } + else if (mType == PORTAL_TYPE_AABB) + { + // for aabb's we check if the center point went from being inside to being outside + // the aabb (or vice versa) for crossing. + AxisAlignedBox aabb; + aabb.setExtents(mDerivedCorners[0], mDerivedCorners[1]); + //bool previousInside = aabb.contains(pczsn->getPrevPosition()); + bool currentInside = aabb.contains(pczsn->_getDerivedPosition()); + if (mDirection == Vector3::UNIT_Z) + { + // portal norm is "outward" pointing, look for going from outside to inside + //if (previousInside == false && + if (currentInside == true) + { + return PortalBase::INTERSECT_CROSS; + } + } + else + { + // portal norm is "inward" pointing, look for going from inside to outside + //if (previousInside == true && + if (currentInside == false) + { + return PortalBase::INTERSECT_CROSS; + } + } + // doesn't cross, but might be touching. This is a little tricky because we only + // care if the node aab is NOT fully contained in the portal aabb because we consider + // the surface of the portal aabb the actual 'portal'. First, check to see if the + // aab of the node intersects the aabb portal + if (aabb.intersects(pczsn->_getWorldAABB())) + { + // now check if the intersection between the two is not the same as the + // full node aabb, if so, then this means that the node is not fully "contained" + // which is what we are looking for. + AxisAlignedBox overlap = aabb.intersection(pczsn->_getWorldAABB()); + if (overlap != pczsn->_getWorldAABB()) + { + return PortalBase::INTERSECT_NO_CROSS; + } + } + return PortalBase::NO_INTERSECT; + } + else + { + // for spheres we check if the center point went from being inside to being outside + // the sphere surface (or vice versa) for crossing. + //Real previousDistance2 = mPrevDerivedCP.squaredDistance(pczsn->getPrevPosition()); + Real currentDistance2 = mDerivedCP.squaredDistance(pczsn->_getDerivedPosition()); + Real mRadius2 = mRadius * mRadius; + if (mDirection == Vector3::UNIT_Z) + { + // portal norm is "outward" pointing, look for going from outside to inside + //if (previousDistance2 >= mRadius2 && + if (currentDistance2 < mRadius2) + { + return PortalBase::INTERSECT_CROSS; + } + } + else + { + // portal norm is "inward" pointing, look for going from inside to outside + //if (previousDistance2 < mRadius2 && + if (currentDistance2 >= mRadius2) + { + return PortalBase::INTERSECT_CROSS; + } + } + // no crossing, but might be touching - check distance + if (Math::Sqrt(Math::Abs(mRadius2 - currentDistance2)) <= mRadius) + { + return PortalBase::INTERSECT_NO_CROSS; + } + return PortalBase::NO_INTERSECT; + } + } + return PortalBase::NO_INTERSECT; } /** check if portal crossed over portal */ bool PortalBase::crossedPortal(const PortalBase* otherPortal) { - // Only check if portal is open and is not an antiportal - if (otherPortal->getEnabled()) - { - // we model both portals as line swept spheres (mPrevDerivedCP to mDerivedCP). - // intersection test is then between the capsules. - // BUGBUG! This routine needs to check for case where one or both objects - // don't move - resulting in simple sphere tests - // BUGBUG! If one (or both) portals are aabb's this is REALLY not accurate. - const Capsule& otherPortalCapsule(otherPortal->getCapsule()); - if (getCapsule().intersects(otherPortalCapsule)) - { - // the portal intersected the other portal at some time from last frame to this frame. - // Now check if this portal "crossed" the other portal - switch (otherPortal->getType()) - { - case PORTAL_TYPE_QUAD: - // a crossing occurs if the "side" of the final position of this portal compared - // to the final position of the other portal is negative AND the initial position - // of this portal compared to the initial position of the other portal is non-negative - // NOTE: This function assumes that this portal is the smaller portal potentially crossing - // over the otherPortal which is larger. - if (otherPortal->getDerivedPlane().getSide(mDerivedCP) == Plane::NEGATIVE_SIDE && - otherPortal->getPrevDerivedPlane().getSide(mPrevDerivedCP) != Plane::NEGATIVE_SIDE) - { - // crossing occurred! - return true; - } - break; - case PORTAL_TYPE_AABB: - { - // for aabb's we check if the center point went from being inside to being outside - // the aabb (or vice versa) for crossing. - AxisAlignedBox aabb; - aabb.setExtents(otherPortal->getDerivedCorner(0), otherPortal->getDerivedCorner(1)); - //bool previousInside = aabb.contains(mPrevDerivedCP); - bool currentInside = aabb.contains(mDerivedCP); - if (otherPortal->getDerivedDirection() == Vector3::UNIT_Z) - { - // portal norm is "outward" pointing, look for going from outside to inside - //if (previousInside == false && - if (currentInside == true) - { - return true; - } - } - else - { - // portal norm is "inward" pointing, look for going from inside to outside - //if (previousInside == true && - if (currentInside == false) - { - return true; - } - } - } - break; - case PORTAL_TYPE_SPHERE: - { - // for spheres we check if the center point went from being inside to being outside - // the sphere surface (or vice versa) for crossing. - //Real previousDistance2 = mPrevDerivedCP.squaredDistance(otherPortal->getPrevDerivedCP()); - Real currentDistance2 = mDerivedCP.squaredDistance(otherPortal->getDerivedCP()); - Real mRadius2 = Math::Sqr(otherPortal->getRadius()); - if (otherPortal->getDerivedDirection() == Vector3::UNIT_Z) - { - // portal norm is "outward" pointing, look for going from outside to inside - //if (previousDistance2 >= mRadius2 && - if (currentDistance2 < mRadius2) - { - return true; - } - } - else - { - // portal norm is "inward" pointing, look for going from inside to outside - //if (previousDistance2 < mRadius2 && - if (currentDistance2 >= mRadius2) - { - return true; - } - } - } - break; - } - } - } - // there was no crossing of the portal by this portal. It might be touching - // the other portal (but we don't care currently) or the other - // portal might be an antiportal (crossing not possible) or the - // other portal might be closed. - return false; + // Only check if portal is open and is not an antiportal + if (otherPortal->getEnabled()) + { + // we model both portals as line swept spheres (mPrevDerivedCP to mDerivedCP). + // intersection test is then between the capsules. + // BUGBUG! This routine needs to check for case where one or both objects + // don't move - resulting in simple sphere tests + // BUGBUG! If one (or both) portals are aabb's this is REALLY not accurate. + const Capsule& otherPortalCapsule(otherPortal->getCapsule()); + if (getCapsule().intersects(otherPortalCapsule)) + { + // the portal intersected the other portal at some time from last frame to this frame. + // Now check if this portal "crossed" the other portal + switch (otherPortal->getType()) + { + case PORTAL_TYPE_QUAD: + // a crossing occurs if the "side" of the final position of this portal compared + // to the final position of the other portal is negative AND the initial position + // of this portal compared to the initial position of the other portal is non-negative + // NOTE: This function assumes that this portal is the smaller portal potentially crossing + // over the otherPortal which is larger. + if (otherPortal->getDerivedPlane().getSide(mDerivedCP) == Plane::NEGATIVE_SIDE && + otherPortal->getPrevDerivedPlane().getSide(mPrevDerivedCP) != Plane::NEGATIVE_SIDE) + { + // crossing occurred! + return true; + } + break; + case PORTAL_TYPE_AABB: + { + // for aabb's we check if the center point went from being inside to being outside + // the aabb (or vice versa) for crossing. + AxisAlignedBox aabb; + aabb.setExtents(otherPortal->getDerivedCorner(0), otherPortal->getDerivedCorner(1)); + //bool previousInside = aabb.contains(mPrevDerivedCP); + bool currentInside = aabb.contains(mDerivedCP); + if (otherPortal->getDerivedDirection() == Vector3::UNIT_Z) + { + // portal norm is "outward" pointing, look for going from outside to inside + //if (previousInside == false && + if (currentInside == true) + { + return true; + } + } + else + { + // portal norm is "inward" pointing, look for going from inside to outside + //if (previousInside == true && + if (currentInside == false) + { + return true; + } + } + } + break; + case PORTAL_TYPE_SPHERE: + { + // for spheres we check if the center point went from being inside to being outside + // the sphere surface (or vice versa) for crossing. + //Real previousDistance2 = mPrevDerivedCP.squaredDistance(otherPortal->getPrevDerivedCP()); + Real currentDistance2 = mDerivedCP.squaredDistance(otherPortal->getDerivedCP()); + Real mRadius2 = Math::Sqr(otherPortal->getRadius()); + if (otherPortal->getDerivedDirection() == Vector3::UNIT_Z) + { + // portal norm is "outward" pointing, look for going from outside to inside + //if (previousDistance2 >= mRadius2 && + if (currentDistance2 < mRadius2) + { + return true; + } + } + else + { + // portal norm is "inward" pointing, look for going from inside to outside + //if (previousDistance2 < mRadius2 && + if (currentDistance2 >= mRadius2) + { + return true; + } + } + } + break; + } + } + } + // there was no crossing of the portal by this portal. It might be touching + // the other portal (but we don't care currently) or the other + // portal might be an antiportal (crossing not possible) or the + // other portal might be closed. + return false; } /** check if portal touches another portal */ bool PortalBase::closeTo(const PortalBase* otherPortal) { - // only portals of the same type can be "close to" each other. - if (mType != otherPortal->getType()) - { - return false; - } - bool close = false; - switch(mType) - { - default: - case PORTAL_TYPE_QUAD: - { - // quad portals must be within 1/4 sphere of each other - Sphere quarterSphere1 = mDerivedSphere; - quarterSphere1.setRadius(quarterSphere1.getRadius()*0.25f); - Sphere quarterSphere2 = otherPortal->getDerivedSphere(); - quarterSphere2.setRadius(quarterSphere2.getRadius()*0.25f); - close = quarterSphere1.intersects(quarterSphere2); - } - break; - case PORTAL_TYPE_AABB: - // NOTE: AABB's must match perfectly - if (mDerivedCP == otherPortal->getDerivedCP() && - mCorners[0] == otherPortal->getCorner(0) && - mCorners[1] == otherPortal->getCorner(1)) - { - close = true; - } - break; - case PORTAL_TYPE_SPHERE: - // NOTE: Spheres must match perfectly - if (mDerivedCP == otherPortal->getDerivedCP() && - mRadius == otherPortal->getRadius()) - { - close = true; - } - break; - } - return close; + // only portals of the same type can be "close to" each other. + if (mType != otherPortal->getType()) + { + return false; + } + bool close = false; + switch(mType) + { + default: + case PORTAL_TYPE_QUAD: + { + // quad portals must be within 1/4 sphere of each other + Sphere quarterSphere1 = mDerivedSphere; + quarterSphere1.setRadius(quarterSphere1.getRadius()*0.25f); + Sphere quarterSphere2 = otherPortal->getDerivedSphere(); + quarterSphere2.setRadius(quarterSphere2.getRadius()*0.25f); + close = quarterSphere1.intersects(quarterSphere2); + } + break; + case PORTAL_TYPE_AABB: + // NOTE: AABB's must match perfectly + if (mDerivedCP == otherPortal->getDerivedCP() && + mCorners[0] == otherPortal->getCorner(0) && + mCorners[1] == otherPortal->getCorner(1)) + { + close = true; + } + break; + case PORTAL_TYPE_SPHERE: + // NOTE: Spheres must match perfectly + if (mDerivedCP == otherPortal->getDerivedCP() && + mRadius == otherPortal->getRadius()) + { + close = true; + } + break; + } + return close; } /** @copydoc MovableObject::getBoundingBox. */ const AxisAlignedBox& PortalBase::getBoundingBox() const { - if (!mLocalsUpToDate) - { - calcDirectionAndRadius(); - } - return mLocalPortalAAB; + if (!mLocalsUpToDate) + { + calcDirectionAndRadius(); + } + return mLocalPortalAAB; } bool PortalBase::needUpdate() { - PCZSceneNode* pczNode = (PCZSceneNode*)mParentNode; - return (!mLocalsUpToDate || (pczNode && pczNode->isMoved())); + PCZSceneNode* pczNode = (PCZSceneNode*)mParentNode; + return (!mLocalsUpToDate || (pczNode && pczNode->isMoved())); } /** Returns an updated capsule of the portal for intersection test. */ const Capsule& PortalBase::getCapsule() const { - PCZSceneNode* pczNode = (PCZSceneNode*)mParentNode; - bool justStoppedMoving = mWasMoved && (pczNode && !pczNode->isMoved()); - if (!mDerivedUpToDate || justStoppedMoving) - { - updateDerivedValues(); - mWasMoved = false; - } - return mPortalCapsule; + PCZSceneNode* pczNode = (PCZSceneNode*)mParentNode; + bool justStoppedMoving = mWasMoved && (pczNode && !pczNode->isMoved()); + if (!mDerivedUpToDate || justStoppedMoving) + { + updateDerivedValues(); + mWasMoved = false; + } + return mPortalCapsule; } /** Returns an updated AAB of the portal for intersection test. */ const AxisAlignedBox& PortalBase::getAAB() { - PCZSceneNode* pczNode = (PCZSceneNode*)mParentNode; - bool justStoppedMoving = mWasMoved && (pczNode && !pczNode->isMoved()); - if (!mDerivedUpToDate || justStoppedMoving) - { - updateDerivedValues(); - mWasMoved = false; - } - - return mPortalAAB; + PCZSceneNode* pczNode = (PCZSceneNode*)mParentNode; + bool justStoppedMoving = mWasMoved && (pczNode && !pczNode->isMoved()); + if (!mDerivedUpToDate || justStoppedMoving) + { + updateDerivedValues(); + mWasMoved = false; + } + + return mPortalAAB; } /** get the portal type from name value pair. */ PortalBase::PORTAL_TYPE PortalBaseFactory::getPortalType(const NameValuePairList* params) { - if (params) - { - NameValuePairList::const_iterator ni = params->find("type"); - if (ni != params->end()) - { - if (ni->second == "Quad") return PortalBase::PORTAL_TYPE_QUAD; - else if (ni->second == "AABB") return PortalBase::PORTAL_TYPE_AABB; - else if (ni->second == "Sphere") return PortalBase::PORTAL_TYPE_SPHERE; - } - } - - return PortalBase::PORTAL_TYPE_QUAD; + if (params) + { + NameValuePairList::const_iterator ni = params->find("type"); + if (ni != params->end()) + { + if (ni->second == "Quad") return PortalBase::PORTAL_TYPE_QUAD; + else if (ni->second == "AABB") return PortalBase::PORTAL_TYPE_AABB; + else if (ni->second == "Sphere") return PortalBase::PORTAL_TYPE_SPHERE; + } + } + + return PortalBase::PORTAL_TYPE_QUAD; } diff --git a/PlugIns/PCZSceneManager/src/OgreSegment.cpp b/PlugIns/PCZSceneManager/src/OgreSegment.cpp index 377bb790884..f0eca5b605c 100644 --- a/PlugIns/PCZSceneManager/src/OgreSegment.cpp +++ b/PlugIns/PCZSceneManager/src/OgreSegment.cpp @@ -30,7 +30,7 @@ Some algorithms based off code from the Wild Magic library by Dave Eberly begin : Mon Apr 02 2007 author : Eric Cha email : ericc@xenopi.com -Code Style Update : +Code Style Update : ----------------------------------------------------------------------------- */ @@ -39,7 +39,7 @@ Code Style Update : using namespace Ogre; -const Real PARALLEL_TOLERANCE = 0.0001; +const Real PARALLEL_TOLERANCE = 0.0001; //---------------------------------------------------------------------------- Segment::Segment () @@ -48,8 +48,8 @@ Segment::Segment () } //---------------------------------------------------------------------------- Segment::Segment (const Vector3& origin, - const Vector3& direction, - Real extent) + const Vector3& direction, + Real extent) : mOrigin(origin), mDirection(direction), @@ -59,28 +59,28 @@ Segment::Segment (const Vector3& origin, //---------------------------------------------------------------------------- void Segment::set(const Vector3& newOrigin, const Vector3& newEnd) { - mOrigin = newOrigin; - // calc the direction vector - mDirection = newEnd - mOrigin; - mExtent = mDirection.normalise(); + mOrigin = newOrigin; + // calc the direction vector + mDirection = newEnd - mOrigin; + mExtent = mDirection.normalise(); } //---------------------------------------------------------------------------- void Segment::setOrigin(const Vector3& newOrigin) { - mOrigin = newOrigin; + mOrigin = newOrigin; } //---------------------------------------------------------------------------- void Segment::setEndPoint(const Vector3& newEnd) { - // calc the direction vector - mDirection = newEnd - mOrigin; - mExtent = mDirection.normalise(); + // calc the direction vector + mDirection = newEnd - mOrigin; + mExtent = mDirection.normalise(); } //---------------------------------------------------------------------------- Real Segment::distance(const Segment& otherSegment) const { Real fSqrDist = squaredDistance(otherSegment); - return Ogre::Math::Sqrt(fSqrDist); + return Ogre::Math::Sqrt(fSqrDist); } //---------------------------------------------------------------------------- Real Segment::squaredDistance(const Segment& otherSegment) const @@ -89,11 +89,11 @@ Real Segment::squaredDistance(const Segment& otherSegment) const Real fA01 = -mDirection.dotProduct(otherSegment.mDirection); Real fB0 = kDiff.dotProduct(mDirection); Real fB1 = -kDiff.dotProduct(otherSegment.mDirection); - Real fC = kDiff.squaredLength(); - Real fDet = Math::Abs((Real)1.0 - fA01*fA01); + Real fC = kDiff.squaredLength(); + Real fDet = Math::Abs((Real)1.0 - fA01*fA01); Real fS0, fS1, fSqrDist, fExtDet0, fExtDet1, fTmpS0, fTmpS1; - if (fDet >= PARALLEL_TOLERANCE) + if (fDet >= PARALLEL_TOLERANCE) { // segments are not parallel fS0 = fA01*fB1-fB0; @@ -398,7 +398,7 @@ Real Segment::squaredDistance(const Segment& otherSegment) const // fS0 = fLambda + fSign*fS1; fSqrDist = fLambda*(fLambda + ((Real)2.0)*fB0Avr) + fC; } - // we don't need the following stuff - it's for calculating closest point + // we don't need the following stuff - it's for calculating closest point // mClosestPoint0 = mOrigin + fS0*mDirection; // mClosestPoint1 = otherSegment.mOrigin + fS1*otherSegment.mDirection; // mSegment0Parameter = fS0; diff --git a/PlugIns/ParticleFX/include/OgreColourFaderAffector2.h b/PlugIns/ParticleFX/include/OgreColourFaderAffector2.h index 5e9efebc985..d1d2822b656 100644 --- a/PlugIns/ParticleFX/include/OgreColourFaderAffector2.h +++ b/PlugIns/ParticleFX/include/OgreColourFaderAffector2.h @@ -130,7 +130,7 @@ namespace Ogre { for a smooth adjustment. */ void setAdjust1(float red, float green, float blue, float alpha = 0.0); - void setAdjust2(float red, float green, float blue, float alpha = 0.0); + void setAdjust2(float red, float green, float blue, float alpha = 0.0); /** Sets the red adjustment to be made per second to particles. @param red The adjustment to be made to the colour component per second. This @@ -138,11 +138,11 @@ namespace Ogre { for a smooth adjustment. */ void setRedAdjust1(float red); - void setRedAdjust2(float red); + void setRedAdjust2(float red); /** Gets the red adjustment to be made per second to particles. */ float getRedAdjust1(void) const; - float getRedAdjust2(void) const; + float getRedAdjust2(void) const; /** Sets the green adjustment to be made per second to particles. @param green @@ -151,10 +151,10 @@ namespace Ogre { for a smooth adjustment. */ void setGreenAdjust1(float green); - void setGreenAdjust2(float green); + void setGreenAdjust2(float green); /** Gets the green adjustment to be made per second to particles. */ float getGreenAdjust1(void) const; - float getGreenAdjust2(void) const; + float getGreenAdjust2(void) const; /** Sets the blue adjustment to be made per second to particles. @param blue The adjustment to be made to the colour component per second. This @@ -162,10 +162,10 @@ namespace Ogre { for a smooth adjustment. */ void setBlueAdjust1(float blue); - void setBlueAdjust2(float blue); + void setBlueAdjust2(float blue); /** Gets the blue adjustment to be made per second to particles. */ float getBlueAdjust1(void) const; - float getBlueAdjust2(void) const; + float getBlueAdjust2(void) const; /** Sets the alpha adjustment to be made per second to particles. @param alpha @@ -174,23 +174,23 @@ namespace Ogre { for a smooth adjustment. */ void setAlphaAdjust1(float alpha); - void setAlphaAdjust2(float alpha); + void setAlphaAdjust2(float alpha); /** Gets the alpha adjustment to be made per second to particles. */ float getAlphaAdjust1(void) const; - float getAlphaAdjust2(void) const; + float getAlphaAdjust2(void) const; void setStateChange(Real NewValue ); Real getStateChange(void) const; static CmdRedAdjust1 msRedCmd1; - static CmdRedAdjust2 msRedCmd2; + static CmdRedAdjust2 msRedCmd2; static CmdGreenAdjust1 msGreenCmd1; - static CmdGreenAdjust2 msGreenCmd2; + static CmdGreenAdjust2 msGreenCmd2; static CmdBlueAdjust1 msBlueCmd1; - static CmdBlueAdjust2 msBlueCmd2; + static CmdBlueAdjust2 msBlueCmd2; static CmdAlphaAdjust1 msAlphaCmd1; - static CmdAlphaAdjust2 msAlphaCmd2; + static CmdAlphaAdjust2 msAlphaCmd2; static CmdStateChange msStateCmd; protected: @@ -198,7 +198,7 @@ namespace Ogre { float mGreenAdj1, mGreenAdj2; float mBlueAdj1, mBlueAdj2; float mAlphaAdj1, mAlphaAdj2; - Real StateChangeVal; + Real StateChangeVal; /** Internal method for adjusting while clamping to [0,1] */ inline void applyAdjustWithClamp(float* pComponent, float adjust) diff --git a/PlugIns/ParticleFX/include/OgreColourImageAffector.h b/PlugIns/ParticleFX/include/OgreColourImageAffector.h index 11836d3cf67..8f6f52e73bc 100644 --- a/PlugIns/ParticleFX/include/OgreColourImageAffector.h +++ b/PlugIns/ParticleFX/include/OgreColourImageAffector.h @@ -40,10 +40,10 @@ namespace Ogre { class _OgreParticleFXExport ColourImageAffector : public ParticleAffector { public: - /** Command object for red adjust (see ParamCommand).*/ + /** Command object for red adjust (see ParamCommand).*/ class CmdImageAdjust : public ParamCommand { - public: + public: String doGet(const void* target) const; void doSet(void* target, const String& val); }; @@ -52,21 +52,21 @@ namespace Ogre { ColourImageAffector(ParticleSystem* psys); /** See ParticleAffector. */ - void _initParticle(Particle* pParticle); + void _initParticle(Particle* pParticle); /** See ParticleAffector. */ void _affectParticles(ParticleSystem* pSystem, Real timeElapsed); - void setImageAdjust(String name); - String getImageAdjust(void) const; + void setImageAdjust(String name); + String getImageAdjust(void) const; - static CmdImageAdjust msImageCmd; + static CmdImageAdjust msImageCmd; protected: - Image mColourImage; + Image mColourImage; bool mColourImageLoaded; - String mColourImageName; + String mColourImageName; /** Internal method to load the image */ void _loadImage(void); diff --git a/PlugIns/ParticleFX/include/OgreColourInterpolatorAffector.h b/PlugIns/ParticleFX/include/OgreColourInterpolatorAffector.h index 2b9bf1c528e..634c9abd2d8 100644 --- a/PlugIns/ParticleFX/include/OgreColourInterpolatorAffector.h +++ b/PlugIns/ParticleFX/include/OgreColourInterpolatorAffector.h @@ -39,33 +39,33 @@ namespace Ogre { class _OgreParticleFXExport ColourInterpolatorAffector : public ParticleAffector { public: - // this is something of a hack.. - // needs to be replaced with something more.. - // ..elegant - enum { MAX_STAGES = 6 }; + // this is something of a hack.. + // needs to be replaced with something more.. + // ..elegant + enum { MAX_STAGES = 6 }; /** Command object for red adjust (see ParamCommand).*/ class CmdColourAdjust : public ParamCommand { - public: - size_t mIndex; + public: + size_t mIndex; - public: + public: String doGet(const void* target) const; void doSet(void* target, const String& val); }; /** Command object for red adjust (see ParamCommand).*/ - class CmdTimeAdjust : public ParamCommand + class CmdTimeAdjust : public ParamCommand { public: - size_t mIndex; + size_t mIndex; - public: + public: String doGet(const void* target) const; void doSet(void* target, const String& val); - }; + }; /** Default constructor. */ ColourInterpolatorAffector(ParticleSystem* psys); @@ -73,19 +73,19 @@ namespace Ogre { /** See ParticleAffector. */ void _affectParticles(ParticleSystem* pSystem, Real timeElapsed); - void setColourAdjust(size_t index, ColourValue colour); - ColourValue getColourAdjust(size_t index) const; + void setColourAdjust(size_t index, ColourValue colour); + ColourValue getColourAdjust(size_t index) const; - void setTimeAdjust(size_t index, Real time); + void setTimeAdjust(size_t index, Real time); Real getTimeAdjust(size_t index) const; - static CmdColourAdjust msColourCmd[MAX_STAGES]; - static CmdTimeAdjust msTimeCmd[MAX_STAGES]; + static CmdColourAdjust msColourCmd[MAX_STAGES]; + static CmdTimeAdjust msTimeCmd[MAX_STAGES]; protected: - ColourValue mColourAdj[MAX_STAGES]; - Real mTimeAdj[MAX_STAGES]; + ColourValue mColourAdj[MAX_STAGES]; + Real mTimeAdj[MAX_STAGES]; }; diff --git a/PlugIns/ParticleFX/include/OgreDirectionRandomiserAffector.h b/PlugIns/ParticleFX/include/OgreDirectionRandomiserAffector.h index 4fa681e33d7..1673c93827d 100644 --- a/PlugIns/ParticleFX/include/OgreDirectionRandomiserAffector.h +++ b/PlugIns/ParticleFX/include/OgreDirectionRandomiserAffector.h @@ -38,11 +38,11 @@ namespace Ogre { /** This class defines a ParticleAffector which applies randomness to the movement of the particles. @remarks This affector (see ParticleAffector) applies randomness to the movement of the particles by - changing the direction vectors. + changing the direction vectors. @par The most important parameter to control the effect is randomness. It controls the range in which changes are applied to each axis of the direction vector. - The parameter scope can be used to limit the effect to a certain percentage of the particles. + The parameter scope can be used to limit the effect to a certain percentage of the particles. */ class _OgreParticleFXExport DirectionRandomiserAffector : public ParticleAffector { @@ -55,7 +55,7 @@ namespace Ogre { void doSet(void* target, const String& val); }; - /** Command object for scope (see ParamCommand).*/ + /** Command object for scope (see ParamCommand).*/ class CmdScope : public ParamCommand { public: @@ -63,7 +63,7 @@ namespace Ogre { void doSet(void* target, const String& val); }; - /** Command object for keep_velocity (see ParamCommand).*/ + /** Command object for keep_velocity (see ParamCommand).*/ class CmdKeepVelocity : public ParamCommand { public: @@ -80,27 +80,27 @@ namespace Ogre { /** Sets the randomness to apply to the particles in a system. */ void setRandomness(Real force); - /** Sets the scope (percentage of particles which are randomised). */ + /** Sets the scope (percentage of particles which are randomised). */ void setScope(Real force); - /** Set flag which detemines whether particle speed is changed. */ + /** Set flag which detemines whether particle speed is changed. */ void setKeepVelocity(bool keepVelocity); /** Gets the randomness to apply to the particles in a system. */ Real getRandomness(void) const; - /** Gets the scope (percentage of particles which are randomised). */ + /** Gets the scope (percentage of particles which are randomised). */ Real getScope(void) const; - /** Gets flag which detemines whether particle speed is changed. */ + /** Gets flag which detemines whether particle speed is changed. */ bool getKeepVelocity(void) const; /// Command objects static CmdRandomness msRandomnessCmd; - static CmdScope msScopeCmd; - static CmdKeepVelocity msKeepVelocityCmd; + static CmdScope msScopeCmd; + static CmdKeepVelocity msKeepVelocityCmd; protected: Real mRandomness; - Real mScope; - bool mKeepVelocity; + Real mScope; + bool mKeepVelocity; }; diff --git a/PlugIns/ParticleFX/include/OgreParticleFXPlugin.h b/PlugIns/ParticleFX/include/OgreParticleFXPlugin.h index 639a8a68fc5..ee8848e085f 100644 --- a/PlugIns/ParticleFX/include/OgreParticleFXPlugin.h +++ b/PlugIns/ParticleFX/include/OgreParticleFXPlugin.h @@ -35,32 +35,32 @@ THE SOFTWARE. namespace Ogre { - /** Plugin instance for ParticleFX Manager */ - class ParticleFXPlugin : public Plugin - { - public: - ParticleFXPlugin(); + /** Plugin instance for ParticleFX Manager */ + class ParticleFXPlugin : public Plugin + { + public: + ParticleFXPlugin(); - /// @copydoc Plugin::getName - const String& getName() const; + /// @copydoc Plugin::getName + const String& getName() const; - /// @copydoc Plugin::install - void install(); + /// @copydoc Plugin::install + void install(); - /// @copydoc Plugin::initialise - void initialise(); + /// @copydoc Plugin::initialise + void initialise(); - /// @copydoc Plugin::shutdown - void shutdown(); + /// @copydoc Plugin::shutdown + void shutdown(); - /// @copydoc Plugin::uninstall - void uninstall(); - protected: - vector::type mEmitterFactories; - vector::type mAffectorFactories; + /// @copydoc Plugin::uninstall + void uninstall(); + protected: + vector::type mEmitterFactories; + vector::type mAffectorFactories; - }; + }; } #endif diff --git a/PlugIns/ParticleFX/include/OgreParticleFXPrerequisites.h b/PlugIns/ParticleFX/include/OgreParticleFXPrerequisites.h index 18300a41d4e..41ff4eef824 100644 --- a/PlugIns/ParticleFX/include/OgreParticleFXPrerequisites.h +++ b/PlugIns/ParticleFX/include/OgreParticleFXPrerequisites.h @@ -40,7 +40,7 @@ THE SOFTWARE. # if defined( __MINGW32__ ) # define _OgreParticleFXExport # else -# define _OgreParticleFXExport __declspec(dllimport) +# define _OgreParticleFXExport __declspec(dllimport) # endif # endif #elif defined ( OGRE_GCC_VISIBILITY ) @@ -57,8 +57,8 @@ namespace Ogre { class PointEmitterFactory; class LinearForceAffector; class LinearForceAffectorFactory; - class DirectionRandomiserAffectorFactory; - class DeflectorPlaneAffectorFactory; + class DirectionRandomiserAffectorFactory; + class DeflectorPlaneAffectorFactory; diff --git a/PlugIns/ParticleFX/include/OgreRotationAffector.h b/PlugIns/ParticleFX/include/OgreRotationAffector.h index d077703b25e..db0b0612ff2 100644 --- a/PlugIns/ParticleFX/include/OgreRotationAffector.h +++ b/PlugIns/ParticleFX/include/OgreRotationAffector.h @@ -39,12 +39,12 @@ namespace Ogre { /** This plugin subclass of ParticleAffector allows you to alter the rotation of particles. @remarks This class supplies the ParticleAffector implementation required to make the particle expand - or contract in mid-flight. + or contract in mid-flight. */ class _OgreParticleFXExport RotationAffector : public ParticleAffector { public: - /// Command object for particle emitter - see ParamCommand + /// Command object for particle emitter - see ParamCommand class CmdRotationSpeedRangeStart : public ParamCommand { public: @@ -60,7 +60,7 @@ namespace Ogre { void doSet(void* target, const String& val); }; - /// Command object for particle emitter - see ParamCommand + /// Command object for particle emitter - see ParamCommand class CmdRotationRangeStart : public ParamCommand { public: @@ -80,14 +80,14 @@ namespace Ogre { RotationAffector(ParticleSystem* psys); /** See ParticleAffector. */ - void _initParticle(Particle* pParticle); + void _initParticle(Particle* pParticle); /** See ParticleAffector. */ void _affectParticles(ParticleSystem* pSystem, Real timeElapsed); - /** Sets the minimum rotation speed of particles to be emitted. */ + /** Sets the minimum rotation speed of particles to be emitted. */ void setRotationSpeedRangeStart(const Radian& angle); /** Sets the maximum rotation speed of particles to be emitted. */ void setRotationSpeedRangeEnd(const Radian& angle); @@ -96,8 +96,8 @@ namespace Ogre { /** Gets the maximum rotation speed of particles to be emitted. */ const Radian& getRotationSpeedRangeEnd(void) const; - - /** Sets the minimum rotation angle of particles to be emitted. */ + + /** Sets the minimum rotation angle of particles to be emitted. */ void setRotationRangeStart(const Radian& angle); /** Sets the maximum rotation angle of particles to be emitted. */ void setRotationRangeEnd(const Radian& angle); @@ -106,10 +106,10 @@ namespace Ogre { /** Gets the maximum rotation of particles to be emitted. */ const Radian& getRotationRangeEnd(void) const; - static CmdRotationSpeedRangeStart msRotationSpeedRangeStartCmd; - static CmdRotationSpeedRangeEnd msRotationSpeedRangeEndCmd; - static CmdRotationRangeStart msRotationRangeStartCmd; - static CmdRotationRangeEnd msRotationRangeEndCmd; + static CmdRotationSpeedRangeStart msRotationSpeedRangeStartCmd; + static CmdRotationSpeedRangeEnd msRotationSpeedRangeEndCmd; + static CmdRotationRangeStart msRotationRangeStartCmd; + static CmdRotationRangeEnd msRotationRangeEndCmd; protected: /// Initial rotation speed of particles (range start) diff --git a/PlugIns/ParticleFX/include/OgreScaleAffector.h b/PlugIns/ParticleFX/include/OgreScaleAffector.h index 18318df6726..b3ebd951f2e 100644 --- a/PlugIns/ParticleFX/include/OgreScaleAffector.h +++ b/PlugIns/ParticleFX/include/OgreScaleAffector.h @@ -38,7 +38,7 @@ namespace Ogre { /** This plugin subclass of ParticleAffector allows you to alter the scale of particles. @remarks This class supplies the ParticleAffector implementation required to make the particle expand - or contract in mid-flight. + or contract in mid-flight. */ class _OgreParticleFXExport ScaleAffector : public ParticleAffector { diff --git a/PlugIns/ParticleFX/src/OgreColourFaderAffector2.cpp b/PlugIns/ParticleFX/src/OgreColourFaderAffector2.cpp index 1f0f3d8b5a2..63bcf3c67ed 100644 --- a/PlugIns/ParticleFX/src/OgreColourFaderAffector2.cpp +++ b/PlugIns/ParticleFX/src/OgreColourFaderAffector2.cpp @@ -34,35 +34,35 @@ THE SOFTWARE. namespace Ogre { // init statics - // Phase 1 + // Phase 1 ColourFaderAffector2::CmdRedAdjust1 ColourFaderAffector2::msRedCmd1; ColourFaderAffector2::CmdGreenAdjust1 ColourFaderAffector2::msGreenCmd1; ColourFaderAffector2::CmdBlueAdjust1 ColourFaderAffector2::msBlueCmd1; ColourFaderAffector2::CmdAlphaAdjust1 ColourFaderAffector2::msAlphaCmd1; - // Phase 2 - ColourFaderAffector2::CmdRedAdjust2 ColourFaderAffector2::msRedCmd2; + // Phase 2 + ColourFaderAffector2::CmdRedAdjust2 ColourFaderAffector2::msRedCmd2; ColourFaderAffector2::CmdGreenAdjust2 ColourFaderAffector2::msGreenCmd2; ColourFaderAffector2::CmdBlueAdjust2 ColourFaderAffector2::msBlueCmd2; ColourFaderAffector2::CmdAlphaAdjust2 ColourFaderAffector2::msAlphaCmd2; - ColourFaderAffector2::CmdStateChange ColourFaderAffector2::msStateCmd; + ColourFaderAffector2::CmdStateChange ColourFaderAffector2::msStateCmd; //----------------------------------------------------------------------- ColourFaderAffector2::ColourFaderAffector2(ParticleSystem* psys) : ParticleAffector(psys) { mRedAdj1 = mGreenAdj1 = mBlueAdj1 = mAlphaAdj1 = 0; - mRedAdj2 = mGreenAdj2 = mBlueAdj2 = mAlphaAdj2 = 0; + mRedAdj2 = mGreenAdj2 = mBlueAdj2 = mAlphaAdj2 = 0; mType = "ColourFader2"; - StateChangeVal = 1; // Switch when there is 1 second left on the TTL + StateChangeVal = 1; // Switch when there is 1 second left on the TTL // Init parameters if (createParamDictionary("ColourFaderAffector2")) { ParamDictionary* dict = getParamDictionary(); - // Phase 1 + // Phase 1 dict->addParameter(ParameterDef("red1", "The amount by which to adjust the red component of particles per second.", PT_REAL), &msRedCmd1); @@ -76,7 +76,7 @@ namespace Ogre { "The amount by which to adjust the alpha component of particles per second.", PT_REAL), &msAlphaCmd1); - // Phase 2 + // Phase 2 dict->addParameter(ParameterDef("red2", "The amount by which to adjust the red component of particles per second.", PT_REAL), &msRedCmd2); @@ -90,7 +90,7 @@ namespace Ogre { "The amount by which to adjust the alpha component of particles per second.", PT_REAL), &msAlphaCmd2); - // State Change Value + // State Change Value dict->addParameter(ParameterDef("state_change", "When the particle has this much time to live left, it will switch to state 2.", PT_REAL), &msStateCmd); @@ -103,38 +103,38 @@ namespace Ogre { ParticleIterator pi = pSystem->_getIterator(); Particle *p; float dr1, dg1, db1, da1; - float dr2, dg2, db2, da2; + float dr2, dg2, db2, da2; - // Scale adjustments by time - dr1 = mRedAdj1 * timeElapsed; - dg1 = mGreenAdj1 * timeElapsed; - db1 = mBlueAdj1 * timeElapsed; - da1 = mAlphaAdj1 * timeElapsed; + // Scale adjustments by time + dr1 = mRedAdj1 * timeElapsed; + dg1 = mGreenAdj1 * timeElapsed; + db1 = mBlueAdj1 * timeElapsed; + da1 = mAlphaAdj1 * timeElapsed; - // Scale adjustments by time - dr2 = mRedAdj2 * timeElapsed; - dg2 = mGreenAdj2 * timeElapsed; - db2 = mBlueAdj2 * timeElapsed; - da2 = mAlphaAdj2 * timeElapsed; + // Scale adjustments by time + dr2 = mRedAdj2 * timeElapsed; + dg2 = mGreenAdj2 * timeElapsed; + db2 = mBlueAdj2 * timeElapsed; + da2 = mAlphaAdj2 * timeElapsed; while (!pi.end()) { - p = pi.getNext(); + p = pi.getNext(); - if( p->mTimeToLive > StateChangeVal ) - { - applyAdjustWithClamp(&p->mColour.r, dr1); - applyAdjustWithClamp(&p->mColour.g, dg1); - applyAdjustWithClamp(&p->mColour.b, db1); - applyAdjustWithClamp(&p->mColour.a, da1); - } - else - { - applyAdjustWithClamp(&p->mColour.r, dr2); - applyAdjustWithClamp(&p->mColour.g, dg2); - applyAdjustWithClamp(&p->mColour.b, db2); - applyAdjustWithClamp(&p->mColour.a, da2); - } + if( p->mTimeToLive > StateChangeVal ) + { + applyAdjustWithClamp(&p->mColour.r, dr1); + applyAdjustWithClamp(&p->mColour.g, dg1); + applyAdjustWithClamp(&p->mColour.b, db1); + applyAdjustWithClamp(&p->mColour.a, da1); + } + else + { + applyAdjustWithClamp(&p->mColour.r, dr2); + applyAdjustWithClamp(&p->mColour.g, dg2); + applyAdjustWithClamp(&p->mColour.b, db2); + applyAdjustWithClamp(&p->mColour.a, da2); + } } } @@ -146,7 +146,7 @@ namespace Ogre { mBlueAdj1 = blue; mAlphaAdj1 = alpha; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void ColourFaderAffector2::setAdjust2(float red, float green, float blue, float alpha) { mRedAdj2 = red; diff --git a/PlugIns/ParticleFX/src/OgreColourImageAffector.cpp b/PlugIns/ParticleFX/src/OgreColourImageAffector.cpp index 707b46e29da..8d605c283be 100644 --- a/PlugIns/ParticleFX/src/OgreColourImageAffector.cpp +++ b/PlugIns/ParticleFX/src/OgreColourImageAffector.cpp @@ -35,7 +35,7 @@ THE SOFTWARE. namespace Ogre { // init statics - ColourImageAffector::CmdImageAdjust ColourImageAffector::msImageCmd; + ColourImageAffector::CmdImageAdjust ColourImageAffector::msImageCmd; //----------------------------------------------------------------------- ColourImageAffector::ColourImageAffector(ParticleSystem* psys) @@ -48,12 +48,12 @@ namespace Ogre { { ParamDictionary* dict = getParamDictionary(); - dict->addParameter(ParameterDef("image", "image where the colours come from", PT_STRING), &msImageCmd); + dict->addParameter(ParameterDef("image", "image where the colours come from", PT_STRING), &msImageCmd); } } //----------------------------------------------------------------------- void ColourImageAffector::_initParticle(Particle* pParticle) - { + { if (!mColourImageLoaded) { _loadImage(); @@ -61,37 +61,37 @@ namespace Ogre { pParticle->mColour = mColourImage.getColourAt(0, 0, 0); - } + } //----------------------------------------------------------------------- void ColourImageAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed) { - Particle* p; - ParticleIterator pi = pSystem->_getIterator(); + Particle* p; + ParticleIterator pi = pSystem->_getIterator(); if (!mColourImageLoaded) { _loadImage(); } - int width = (int)mColourImage.getWidth() - 1; + int width = (int)mColourImage.getWidth() - 1; - while (!pi.end()) - { - p = pi.getNext(); - const Real life_time = p->mTotalTimeToLive; - Real particle_time = 1.0f - (p->mTimeToLive / life_time); + while (!pi.end()) + { + p = pi.getNext(); + const Real life_time = p->mTotalTimeToLive; + Real particle_time = 1.0f - (p->mTimeToLive / life_time); - if (particle_time > 1.0f) - particle_time = 1.0f; - if (particle_time < 0.0f) - particle_time = 0.0f; + if (particle_time > 1.0f) + particle_time = 1.0f; + if (particle_time < 0.0f) + particle_time = 0.0f; - const Real float_index = particle_time * width; - const int index = (int)float_index; + const Real float_index = particle_time * width; + const int index = (int)float_index; if(index < 0) { - p->mColour = mColourImage.getColourAt(0, 0, 0); + p->mColour = mColourImage.getColourAt(0, 0, 0); } else if(index >= width) { @@ -100,50 +100,50 @@ namespace Ogre { else { // Linear interpolation - const Real fract = float_index - (Real)index; - const Real to_colour = fract; - const Real from_colour = 1.0f - to_colour; + const Real fract = float_index - (Real)index; + const Real to_colour = fract; + const Real from_colour = 1.0f - to_colour; ColourValue from=mColourImage.getColourAt(index, 0, 0), - to=mColourImage.getColourAt(index+1, 0, 0); + to=mColourImage.getColourAt(index+1, 0, 0); - p->mColour.r = from.r*from_colour + to.r*to_colour; + p->mColour.r = from.r*from_colour + to.r*to_colour; p->mColour.g = from.g*from_colour + to.g*to_colour; p->mColour.b = from.b*from_colour + to.b*to_colour; p->mColour.a = from.a*from_colour + to.a*to_colour; - } - } + } + } } //----------------------------------------------------------------------- void ColourImageAffector::setImageAdjust(String name) { - mColourImageName = name; + mColourImageName = name; mColourImageLoaded = false; - } + } //----------------------------------------------------------------------- void ColourImageAffector::_loadImage(void) { mColourImage.load(mColourImageName, mParent->getResourceGroupName()); - PixelFormat format = mColourImage.getFormat(); + PixelFormat format = mColourImage.getFormat(); - if ( !PixelUtil::isAccessible(format) ) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Error: Image is not accessible (rgba) image.", - "ColourImageAffector::_loadImage" ); - } + if ( !PixelUtil::isAccessible(format) ) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Error: Image is not accessible (rgba) image.", + "ColourImageAffector::_loadImage" ); + } mColourImageLoaded = true; - } + } //----------------------------------------------------------------------- String ColourImageAffector::getImageAdjust(void) const { return mColourImageName; } - - //----------------------------------------------------------------------- + + //----------------------------------------------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- // Command objects diff --git a/PlugIns/ParticleFX/src/OgreColourInterpolatorAffector.cpp b/PlugIns/ParticleFX/src/OgreColourInterpolatorAffector.cpp index 191f4b6bddf..b4de1e9d4b8 100644 --- a/PlugIns/ParticleFX/src/OgreColourInterpolatorAffector.cpp +++ b/PlugIns/ParticleFX/src/OgreColourInterpolatorAffector.cpp @@ -34,20 +34,20 @@ THE SOFTWARE. namespace Ogre { // init statics - ColourInterpolatorAffector::CmdColourAdjust ColourInterpolatorAffector::msColourCmd[MAX_STAGES]; - ColourInterpolatorAffector::CmdTimeAdjust ColourInterpolatorAffector::msTimeCmd[MAX_STAGES]; + ColourInterpolatorAffector::CmdColourAdjust ColourInterpolatorAffector::msColourCmd[MAX_STAGES]; + ColourInterpolatorAffector::CmdTimeAdjust ColourInterpolatorAffector::msTimeCmd[MAX_STAGES]; //----------------------------------------------------------------------- ColourInterpolatorAffector::ColourInterpolatorAffector(ParticleSystem* psys) : ParticleAffector(psys) { - for (int i=0;iaddParameter(ParameterDef(colour_title, colour_descr, PT_COLOURVALUE), &msColourCmd[i]); - dict->addParameter(ParameterDef(time_title, time_descr, PT_REAL), &msTimeCmd[i]); - } + for (int i=0;iaddParameter(ParameterDef(colour_title, colour_descr, PT_COLOURVALUE), &msColourCmd[i]); + dict->addParameter(ParameterDef(time_title, time_descr, PT_REAL), &msTimeCmd[i]); + } } } //----------------------------------------------------------------------- void ColourInterpolatorAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed) { - Particle* p; - ParticleIterator pi = pSystem->_getIterator(); + Particle* p; + ParticleIterator pi = pSystem->_getIterator(); - while (!pi.end()) + while (!pi.end()) { p = pi.getNext(); - const Real life_time = p->mTotalTimeToLive; - Real particle_time = 1.0f - (p->mTimeToLive / life_time); - - if (particle_time <= mTimeAdj[0]) - { - p->mColour = mColourAdj[0]; - } else - if (particle_time >= mTimeAdj[MAX_STAGES - 1]) - { - p->mColour = mColourAdj[MAX_STAGES-1]; - } else - { - for (int i=0;i= mTimeAdj[i] && particle_time < mTimeAdj[i + 1]) - { - particle_time -= mTimeAdj[i]; - particle_time /= (mTimeAdj[i+1]-mTimeAdj[i]); - p->mColour.r = ((mColourAdj[i+1].r * particle_time) + (mColourAdj[i].r * (1.0f - particle_time))); - p->mColour.g = ((mColourAdj[i+1].g * particle_time) + (mColourAdj[i].g * (1.0f - particle_time))); - p->mColour.b = ((mColourAdj[i+1].b * particle_time) + (mColourAdj[i].b * (1.0f - particle_time))); - p->mColour.a = ((mColourAdj[i+1].a * particle_time) + (mColourAdj[i].a * (1.0f - particle_time))); - break; - } - } - } - } + const Real life_time = p->mTotalTimeToLive; + Real particle_time = 1.0f - (p->mTimeToLive / life_time); + + if (particle_time <= mTimeAdj[0]) + { + p->mColour = mColourAdj[0]; + } else + if (particle_time >= mTimeAdj[MAX_STAGES - 1]) + { + p->mColour = mColourAdj[MAX_STAGES-1]; + } else + { + for (int i=0;i= mTimeAdj[i] && particle_time < mTimeAdj[i + 1]) + { + particle_time -= mTimeAdj[i]; + particle_time /= (mTimeAdj[i+1]-mTimeAdj[i]); + p->mColour.r = ((mColourAdj[i+1].r * particle_time) + (mColourAdj[i].r * (1.0f - particle_time))); + p->mColour.g = ((mColourAdj[i+1].g * particle_time) + (mColourAdj[i].g * (1.0f - particle_time))); + p->mColour.b = ((mColourAdj[i+1].b * particle_time) + (mColourAdj[i].b * (1.0f - particle_time))); + p->mColour.a = ((mColourAdj[i+1].a * particle_time) + (mColourAdj[i].a * (1.0f - particle_time))); + break; + } + } + } + } } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void ColourInterpolatorAffector::setColourAdjust(size_t index, ColourValue colour) { mColourAdj[index] = colour; @@ -135,8 +135,8 @@ namespace Ogre { return mTimeAdj[index]; } - - //----------------------------------------------------------------------- + + //----------------------------------------------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- // Command objects @@ -152,7 +152,7 @@ namespace Ogre { static_cast(target)->setColourAdjust(mIndex, StringConverter::parseColourValue(val)); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- String ColourInterpolatorAffector::CmdTimeAdjust::doGet(const void* target) const { return StringConverter::toString( diff --git a/PlugIns/ParticleFX/src/OgreDeflectorPlaneAffector.cpp b/PlugIns/ParticleFX/src/OgreDeflectorPlaneAffector.cpp index 7f487f0b861..0a6718eaba0 100644 --- a/PlugIns/ParticleFX/src/OgreDeflectorPlaneAffector.cpp +++ b/PlugIns/ParticleFX/src/OgreDeflectorPlaneAffector.cpp @@ -66,7 +66,7 @@ namespace Ogre { { // precalculate distance of plane from origin Real planeDistance = - mPlaneNormal.dotProduct(mPlanePoint) / Math::Sqrt(mPlaneNormal.dotProduct(mPlaneNormal)); - Vector3 directionPart; + Vector3 directionPart; ParticleIterator pi = pSystem->_getIterator(); @@ -81,9 +81,9 @@ namespace Ogre { if (a > 0.0) { // for intersection point - directionPart = direction * (- a / direction.dotProduct( mPlaneNormal )); + directionPart = direction * (- a / direction.dotProduct( mPlaneNormal )); // set new position - p->mPosition = (p->mPosition + ( directionPart )) + (((directionPart) - direction) * mBounce); + p->mPosition = (p->mPosition + ( directionPart )) + (((directionPart) - direction) * mBounce); // reflect direction vector p->mDirection = (p->mDirection - (2.0 * p->mDirection.dotProduct( mPlaneNormal ) * mPlaneNormal)) * mBounce; diff --git a/PlugIns/ParticleFX/src/OgreHollowEllipsoidEmitter.cpp b/PlugIns/ParticleFX/src/OgreHollowEllipsoidEmitter.cpp index eb0f9aaf1cc..d110e9f21f6 100644 --- a/PlugIns/ParticleFX/src/OgreHollowEllipsoidEmitter.cpp +++ b/PlugIns/ParticleFX/src/OgreHollowEllipsoidEmitter.cpp @@ -92,7 +92,7 @@ namespace Ogre { // ellipsoid and the outer sphere (radius 1.0) // with alpha and beta we select on point on this random ellipsoid // and calculate the 3D coordinates of this point - Real sinbeta ( Math::Sin(beta) ); + Real sinbeta ( Math::Sin(beta) ); x = a * Math::Cos(alpha) * sinbeta; y = b * Math::Sin(alpha) * sinbeta; z = c * Math::Cos(beta); diff --git a/PlugIns/ParticleFX/src/OgreParticleFX.cpp b/PlugIns/ParticleFX/src/OgreParticleFX.cpp index c555a9d2fb8..e0fd2391672 100644 --- a/PlugIns/ParticleFX/src/OgreParticleFX.cpp +++ b/PlugIns/ParticleFX/src/OgreParticleFX.cpp @@ -33,19 +33,19 @@ THE SOFTWARE. namespace Ogre { - ParticleFXPlugin* plugin; + ParticleFXPlugin* plugin; //----------------------------------------------------------------------- extern "C" void _OgreParticleFXExport dllStartPlugin(void) throw() { - plugin = OGRE_NEW ParticleFXPlugin(); - Root::getSingleton().installPlugin(plugin); + plugin = OGRE_NEW ParticleFXPlugin(); + Root::getSingleton().installPlugin(plugin); } //----------------------------------------------------------------------- extern "C" void _OgreParticleFXExport dllStopPlugin(void) { - Root::getSingleton().uninstallPlugin(plugin); - OGRE_DELETE plugin; + Root::getSingleton().uninstallPlugin(plugin); + OGRE_DELETE plugin; } diff --git a/PlugIns/ParticleFX/src/OgreParticleFXPlugin.cpp b/PlugIns/ParticleFX/src/OgreParticleFXPlugin.cpp index a823abaaa39..e09dce6ac7f 100644 --- a/PlugIns/ParticleFX/src/OgreParticleFXPlugin.cpp +++ b/PlugIns/ParticleFX/src/OgreParticleFXPlugin.cpp @@ -48,131 +48,131 @@ THE SOFTWARE. namespace Ogre { - const String sPluginName = "ParticleFX"; - //--------------------------------------------------------------------- - ParticleFXPlugin::ParticleFXPlugin() - { - - } - //--------------------------------------------------------------------- - const String& ParticleFXPlugin::getName() const - { - return sPluginName; - } - //--------------------------------------------------------------------- - void ParticleFXPlugin::install() - { - // -- Create all new particle emitter factories -- - ParticleEmitterFactory* pEmitFact; - - // PointEmitter - pEmitFact = OGRE_NEW PointEmitterFactory(); - ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); - mEmitterFactories.push_back(pEmitFact); - - // BoxEmitter - pEmitFact = OGRE_NEW BoxEmitterFactory(); - ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); - mEmitterFactories.push_back(pEmitFact); - - // EllipsoidEmitter - pEmitFact = OGRE_NEW EllipsoidEmitterFactory(); - ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); - mEmitterFactories.push_back(pEmitFact); - - // CylinderEmitter - pEmitFact = OGRE_NEW CylinderEmitterFactory(); - ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); - mEmitterFactories.push_back(pEmitFact); - - // RingEmitter - pEmitFact = OGRE_NEW RingEmitterFactory(); - ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); - mEmitterFactories.push_back(pEmitFact); - - // HollowEllipsoidEmitter - pEmitFact = OGRE_NEW HollowEllipsoidEmitterFactory(); - ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); - mEmitterFactories.push_back(pEmitFact); - - // -- Create all new particle affector factories -- - ParticleAffectorFactory* pAffFact; - - // LinearForceAffector - pAffFact = OGRE_NEW LinearForceAffectorFactory(); - ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); - mAffectorFactories.push_back(pAffFact); - - // ColourFaderAffector - pAffFact = OGRE_NEW ColourFaderAffectorFactory(); - ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); - mAffectorFactories.push_back(pAffFact); - - // ColourFaderAffector2 - pAffFact = OGRE_NEW ColourFaderAffectorFactory2(); - ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); - mAffectorFactories.push_back(pAffFact); - - // ColourImageAffector - pAffFact = OGRE_NEW ColourImageAffectorFactory(); - ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); - mAffectorFactories.push_back(pAffFact); - - // ColourInterpolatorAffector - pAffFact = OGRE_NEW ColourInterpolatorAffectorFactory(); - ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); - mAffectorFactories.push_back(pAffFact); - - // ScaleAffector - pAffFact = OGRE_NEW ScaleAffectorFactory(); - ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); - mAffectorFactories.push_back(pAffFact); - - // RotationAffector - pAffFact = OGRE_NEW RotationAffectorFactory(); - ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); - mAffectorFactories.push_back(pAffFact); - - - // DirectionRandomiserAffector - pAffFact = OGRE_NEW DirectionRandomiserAffectorFactory(); - ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); - mAffectorFactories.push_back(pAffFact); - - // DeflectorPlaneAffector - pAffFact = OGRE_NEW DeflectorPlaneAffectorFactory(); - ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); - mAffectorFactories.push_back(pAffFact); - } - //--------------------------------------------------------------------- - void ParticleFXPlugin::initialise() - { - // nothing to do - } - //--------------------------------------------------------------------- - void ParticleFXPlugin::shutdown() - { - // nothing to do - } - //--------------------------------------------------------------------- - void ParticleFXPlugin::uninstall() - { - // destroy - vector::type::iterator ei; - vector::type::iterator ai; - - for (ei = mEmitterFactories.begin(); ei != mEmitterFactories.end(); ++ei) - { - OGRE_DELETE (*ei); - } - - for (ai = mAffectorFactories.begin(); ai != mAffectorFactories.end(); ++ai) - { - OGRE_DELETE (*ai); - } - - - } + const String sPluginName = "ParticleFX"; + //--------------------------------------------------------------------- + ParticleFXPlugin::ParticleFXPlugin() + { + + } + //--------------------------------------------------------------------- + const String& ParticleFXPlugin::getName() const + { + return sPluginName; + } + //--------------------------------------------------------------------- + void ParticleFXPlugin::install() + { + // -- Create all new particle emitter factories -- + ParticleEmitterFactory* pEmitFact; + + // PointEmitter + pEmitFact = OGRE_NEW PointEmitterFactory(); + ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); + mEmitterFactories.push_back(pEmitFact); + + // BoxEmitter + pEmitFact = OGRE_NEW BoxEmitterFactory(); + ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); + mEmitterFactories.push_back(pEmitFact); + + // EllipsoidEmitter + pEmitFact = OGRE_NEW EllipsoidEmitterFactory(); + ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); + mEmitterFactories.push_back(pEmitFact); + + // CylinderEmitter + pEmitFact = OGRE_NEW CylinderEmitterFactory(); + ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); + mEmitterFactories.push_back(pEmitFact); + + // RingEmitter + pEmitFact = OGRE_NEW RingEmitterFactory(); + ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); + mEmitterFactories.push_back(pEmitFact); + + // HollowEllipsoidEmitter + pEmitFact = OGRE_NEW HollowEllipsoidEmitterFactory(); + ParticleSystemManager::getSingleton().addEmitterFactory(pEmitFact); + mEmitterFactories.push_back(pEmitFact); + + // -- Create all new particle affector factories -- + ParticleAffectorFactory* pAffFact; + + // LinearForceAffector + pAffFact = OGRE_NEW LinearForceAffectorFactory(); + ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); + mAffectorFactories.push_back(pAffFact); + + // ColourFaderAffector + pAffFact = OGRE_NEW ColourFaderAffectorFactory(); + ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); + mAffectorFactories.push_back(pAffFact); + + // ColourFaderAffector2 + pAffFact = OGRE_NEW ColourFaderAffectorFactory2(); + ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); + mAffectorFactories.push_back(pAffFact); + + // ColourImageAffector + pAffFact = OGRE_NEW ColourImageAffectorFactory(); + ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); + mAffectorFactories.push_back(pAffFact); + + // ColourInterpolatorAffector + pAffFact = OGRE_NEW ColourInterpolatorAffectorFactory(); + ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); + mAffectorFactories.push_back(pAffFact); + + // ScaleAffector + pAffFact = OGRE_NEW ScaleAffectorFactory(); + ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); + mAffectorFactories.push_back(pAffFact); + + // RotationAffector + pAffFact = OGRE_NEW RotationAffectorFactory(); + ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); + mAffectorFactories.push_back(pAffFact); + + + // DirectionRandomiserAffector + pAffFact = OGRE_NEW DirectionRandomiserAffectorFactory(); + ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); + mAffectorFactories.push_back(pAffFact); + + // DeflectorPlaneAffector + pAffFact = OGRE_NEW DeflectorPlaneAffectorFactory(); + ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact); + mAffectorFactories.push_back(pAffFact); + } + //--------------------------------------------------------------------- + void ParticleFXPlugin::initialise() + { + // nothing to do + } + //--------------------------------------------------------------------- + void ParticleFXPlugin::shutdown() + { + // nothing to do + } + //--------------------------------------------------------------------- + void ParticleFXPlugin::uninstall() + { + // destroy + vector::type::iterator ei; + vector::type::iterator ai; + + for (ei = mEmitterFactories.begin(); ei != mEmitterFactories.end(); ++ei) + { + OGRE_DELETE (*ei); + } + + for (ai = mAffectorFactories.begin(); ai != mAffectorFactories.end(); ++ai) + { + OGRE_DELETE (*ai); + } + + + } } diff --git a/PlugIns/ParticleFX/src/OgreRotationAffector.cpp b/PlugIns/ParticleFX/src/OgreRotationAffector.cpp index 7efbc4ed744..f0b845011d5 100644 --- a/PlugIns/ParticleFX/src/OgreRotationAffector.cpp +++ b/PlugIns/ParticleFX/src/OgreRotationAffector.cpp @@ -34,20 +34,20 @@ THE SOFTWARE. namespace Ogre { // init statics - RotationAffector::CmdRotationSpeedRangeStart RotationAffector::msRotationSpeedRangeStartCmd; - RotationAffector::CmdRotationSpeedRangeEnd RotationAffector::msRotationSpeedRangeEndCmd; - RotationAffector::CmdRotationRangeStart RotationAffector::msRotationRangeStartCmd; - RotationAffector::CmdRotationRangeEnd RotationAffector::msRotationRangeEndCmd; + RotationAffector::CmdRotationSpeedRangeStart RotationAffector::msRotationSpeedRangeStartCmd; + RotationAffector::CmdRotationSpeedRangeEnd RotationAffector::msRotationSpeedRangeEndCmd; + RotationAffector::CmdRotationRangeStart RotationAffector::msRotationRangeStartCmd; + RotationAffector::CmdRotationRangeEnd RotationAffector::msRotationRangeEndCmd; //----------------------------------------------------------------------- - RotationAffector::RotationAffector(ParticleSystem* psys) : + RotationAffector::RotationAffector(ParticleSystem* psys) : ParticleAffector(psys), - mRotationSpeedRangeStart(0), - mRotationSpeedRangeEnd(0), - mRotationRangeStart(0), - mRotationRangeEnd(0) + mRotationSpeedRangeStart(0), + mRotationSpeedRangeEnd(0), + mRotationRangeStart(0), + mRotationRangeEnd(0) { - mType = "Rotator"; + mType = "Rotator"; // Init parameters if (createParamDictionary("RotationAffector")) @@ -55,27 +55,27 @@ namespace Ogre { ParamDictionary* dict = getParamDictionary(); dict->addParameter(ParameterDef("rotation_speed_range_start", - "The start of a range of rotation speed to be assigned to emitted particles.", PT_REAL), - &msRotationSpeedRangeStartCmd); + "The start of a range of rotation speed to be assigned to emitted particles.", PT_REAL), + &msRotationSpeedRangeStartCmd); - dict->addParameter(ParameterDef("rotation_speed_range_end", - "The end of a range of rotation speed to be assigned to emitted particles.", PT_REAL), - &msRotationSpeedRangeEndCmd); + dict->addParameter(ParameterDef("rotation_speed_range_end", + "The end of a range of rotation speed to be assigned to emitted particles.", PT_REAL), + &msRotationSpeedRangeEndCmd); - dict->addParameter(ParameterDef("rotation_range_start", - "The start of a range of rotation angles to be assigned to emitted particles.", PT_REAL), - &msRotationRangeStartCmd); + dict->addParameter(ParameterDef("rotation_range_start", + "The start of a range of rotation angles to be assigned to emitted particles.", PT_REAL), + &msRotationRangeStartCmd); - dict->addParameter(ParameterDef("rotation_range_end", - "The end of a range of rotation angles to be assigned to emitted particles.", PT_REAL), - &msRotationRangeEndCmd); + dict->addParameter(ParameterDef("rotation_range_end", + "The end of a range of rotation angles to be assigned to emitted particles.", PT_REAL), + &msRotationRangeEndCmd); } } //----------------------------------------------------------------------- - void RotationAffector::_initParticle(Particle* pParticle) - { - pParticle->setRotation( + void RotationAffector::_initParticle(Particle* pParticle) + { + pParticle->setRotation( mRotationRangeStart + (Math::UnitRandom() * (mRotationRangeEnd - mRotationRangeStart))); @@ -84,8 +84,8 @@ namespace Ogre { (Math::UnitRandom() * (mRotationSpeedRangeEnd - mRotationSpeedRangeStart)); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void RotationAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed) { ParticleIterator pi = pSystem->_getIterator(); @@ -95,14 +95,14 @@ namespace Ogre { // Rotation adjustments by time ds = timeElapsed; - Radian NewRotation; + Radian NewRotation; while (!pi.end()) { p = pi.getNext(); - NewRotation = p->mRotation + (ds * p->mRotationSpeed); - p->setRotation( NewRotation ); + NewRotation = p->mRotation + (ds * p->mRotationSpeed); + p->setRotation( NewRotation ); } } @@ -146,7 +146,7 @@ namespace Ogre { { mRotationRangeEnd = val; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- @@ -173,7 +173,7 @@ namespace Ogre { static_cast(target)->setRotationSpeedRangeStart(StringConverter::parseAngle(val)); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- String RotationAffector::CmdRotationRangeEnd::doGet(const void* target) const { return StringConverter::toString( diff --git a/PlugIns/ParticleFX/src/OgreScaleAffector.cpp b/PlugIns/ParticleFX/src/OgreScaleAffector.cpp index 4d680786ecb..5a5250e53c9 100644 --- a/PlugIns/ParticleFX/src/OgreScaleAffector.cpp +++ b/PlugIns/ParticleFX/src/OgreScaleAffector.cpp @@ -63,24 +63,24 @@ namespace Ogre { // Scale adjustments by time ds = mScaleAdj * timeElapsed; - Real NewWide, NewHigh; + Real NewWide, NewHigh; while (!pi.end()) { p = pi.getNext(); - if( p->hasOwnDimensions() == false ) - { - NewWide = pSystem->getDefaultWidth() + ds; - NewHigh = pSystem->getDefaultHeight() + ds; - - } - else - { - NewWide = p->getOwnWidth() + ds; - NewHigh = p->getOwnHeight() + ds; - } - p->setDimensions( NewWide, NewHigh ); + if( p->hasOwnDimensions() == false ) + { + NewWide = pSystem->getDefaultWidth() + ds; + NewHigh = pSystem->getDefaultHeight() + ds; + + } + else + { + NewWide = p->getOwnWidth() + ds; + NewHigh = p->getOwnHeight() + ds; + } + p->setDimensions( NewWide, NewHigh ); } } diff --git a/RenderSystems/Direct3D11/include/OgreD3D11DepthBuffer.h b/RenderSystems/Direct3D11/include/OgreD3D11DepthBuffer.h index 123ed268dcb..15066c4a2c0 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11DepthBuffer.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11DepthBuffer.h @@ -33,26 +33,26 @@ THE SOFTWARE. namespace Ogre { - class D3D11DepthBuffer : public DepthBuffer - { - public: - D3D11DepthBuffer( uint16 poolId, D3D11RenderSystem *renderSystem, - ID3D11DepthStencilView *depthBufferView, - uint32 width, uint32 height, - uint32 fsaa, uint32 multiSampleQuality, bool isManual ); - ~D3D11DepthBuffer(); - - /// @copydoc DepthBuffer::isCompatible - virtual bool isCompatible( RenderTarget *renderTarget ) const; - - ID3D11DepthStencilView* getDepthStencilView() const; - /// internal method, gets called when the renderwindow was resized - void _resized(ID3D11DepthStencilView *depthBufferView, uint32 width, uint32 height); - - protected: - ID3D11DepthStencilView *mDepthStencilView; //aka. actual "DepthBuffer" - uint32 mMultiSampleQuality; - D3D11RenderSystem *mRenderSystem; - }; + class D3D11DepthBuffer : public DepthBuffer + { + public: + D3D11DepthBuffer( uint16 poolId, D3D11RenderSystem *renderSystem, + ID3D11DepthStencilView *depthBufferView, + uint32 width, uint32 height, + uint32 fsaa, uint32 multiSampleQuality, bool isManual ); + ~D3D11DepthBuffer(); + + /// @copydoc DepthBuffer::isCompatible + virtual bool isCompatible( RenderTarget *renderTarget ) const; + + ID3D11DepthStencilView* getDepthStencilView() const; + /// internal method, gets called when the renderwindow was resized + void _resized(ID3D11DepthStencilView *depthBufferView, uint32 width, uint32 height); + + protected: + ID3D11DepthStencilView *mDepthStencilView; //aka. actual "DepthBuffer" + uint32 mMultiSampleQuality; + D3D11RenderSystem *mRenderSystem; + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11Device.h b/RenderSystems/Direct3D11/include/OgreD3D11Device.h index 1f2447fa049..be7cb54f930 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11Device.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11Device.h @@ -33,98 +33,98 @@ THE SOFTWARE. namespace Ogre { - class D3D11Device - { - private: - ID3D11DeviceN * mD3D11Device; - ID3D11DeviceContextN * mImmediateContext; + class D3D11Device + { + private: + ID3D11DeviceN * mD3D11Device; + ID3D11DeviceContextN * mImmediateContext; ID3D11InfoQueue * mInfoQueue; - // Storing class linkage - ID3D11ClassLinkage* mClassLinkage; + // Storing class linkage + ID3D11ClassLinkage* mClassLinkage; - struct ThreadInfo - { - ID3D11DeviceContextN* mContext; - void* mEventHandle; + struct ThreadInfo + { + ID3D11DeviceContextN* mContext; + void* mEventHandle; - ThreadInfo(ID3D11DeviceContextN* context) - : mContext(context) - , mEventHandle(0) - { - mEventHandle = CreateEventEx(0, TEXT("ThreadContextEvent"), 0, EVENT_ALL_ACCESS); - } + ThreadInfo(ID3D11DeviceContextN* context) + : mContext(context) + , mEventHandle(0) + { + mEventHandle = CreateEventEx(0, TEXT("ThreadContextEvent"), 0, EVENT_ALL_ACCESS); + } - ~ThreadInfo() - { - SAFE_RELEASE(mContext); + ~ThreadInfo() + { + SAFE_RELEASE(mContext); - CloseHandle(mEventHandle); - } - }; + CloseHandle(mEventHandle); + } + }; - D3D11Device(); + D3D11Device(); public: - D3D11Device(ID3D11DeviceN * device); - - ~D3D11Device(); - - inline ID3D11DeviceContextN * GetImmediateContext() - { - return mImmediateContext; - } - - inline ID3D11ClassLinkage* GetClassLinkage() - { - return mClassLinkage; - } - - inline ID3D11DeviceN * operator->() const - { - assert(mD3D11Device); - if (D3D_NO_EXCEPTION != mExceptionsErrorLevel) - { - clearStoredErrorMessages(); - } - return mD3D11Device; - } - - const void clearStoredErrorMessages( ) const; - - ID3D11DeviceN * operator=(ID3D11DeviceN * device); - const bool isNull(); - const String getErrorDescription(const HRESULT hr = NO_ERROR) const; - - inline const bool isError( ) const - { - if (D3D_NO_EXCEPTION == mExceptionsErrorLevel) - { - return false; - } - - return _getErrorsFromQueue(); - } - - const bool _getErrorsFromQueue() const; - void release(); - ID3D11DeviceN * get(); - - enum eExceptionsErrorLevel - { - D3D_NO_EXCEPTION, - D3D_CORRUPTION, - D3D_ERROR, - D3D_WARNING, - D3D_INFO, - }; - - static eExceptionsErrorLevel mExceptionsErrorLevel; - static void setExceptionsErrorLevel(const eExceptionsErrorLevel exceptionsErrorLevel); - static const eExceptionsErrorLevel getExceptionsErrorLevel(); - - - }; + D3D11Device(ID3D11DeviceN * device); + + ~D3D11Device(); + + inline ID3D11DeviceContextN * GetImmediateContext() + { + return mImmediateContext; + } + + inline ID3D11ClassLinkage* GetClassLinkage() + { + return mClassLinkage; + } + + inline ID3D11DeviceN * operator->() const + { + assert(mD3D11Device); + if (D3D_NO_EXCEPTION != mExceptionsErrorLevel) + { + clearStoredErrorMessages(); + } + return mD3D11Device; + } + + const void clearStoredErrorMessages( ) const; + + ID3D11DeviceN * operator=(ID3D11DeviceN * device); + const bool isNull(); + const String getErrorDescription(const HRESULT hr = NO_ERROR) const; + + inline const bool isError( ) const + { + if (D3D_NO_EXCEPTION == mExceptionsErrorLevel) + { + return false; + } + + return _getErrorsFromQueue(); + } + + const bool _getErrorsFromQueue() const; + void release(); + ID3D11DeviceN * get(); + + enum eExceptionsErrorLevel + { + D3D_NO_EXCEPTION, + D3D_CORRUPTION, + D3D_ERROR, + D3D_WARNING, + D3D_INFO, + }; + + static eExceptionsErrorLevel mExceptionsErrorLevel; + static void setExceptionsErrorLevel(const eExceptionsErrorLevel exceptionsErrorLevel); + static const eExceptionsErrorLevel getExceptionsErrorLevel(); + + + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11Driver.h b/RenderSystems/Direct3D11/include/OgreD3D11Driver.h index a9581d82933..40531187a2b 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11Driver.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11Driver.h @@ -33,42 +33,42 @@ THE SOFTWARE. namespace Ogre { - class D3D11VideoModeList; - class D3D11VideoMode; + class D3D11VideoModeList; + class D3D11VideoMode; - class D3D11Driver - { - private: - // D3D only allows one device per adapter, so it can safely be stored - // here as well. - unsigned int mAdapterNumber; - DXGI_ADAPTER_DESC1 mAdapterIdentifier; - DXGI_MODE_DESC mDesktopDisplayMode; - D3D11VideoModeList* mVideoModeList; - unsigned int tempNo; - static unsigned int driverCount; - IDXGIAdapterN* mDXGIAdapter; + class D3D11Driver + { + private: + // D3D only allows one device per adapter, so it can safely be stored + // here as well. + unsigned int mAdapterNumber; + DXGI_ADAPTER_DESC1 mAdapterIdentifier; + DXGI_MODE_DESC mDesktopDisplayMode; + D3D11VideoModeList* mVideoModeList; + unsigned int tempNo; + static unsigned int driverCount; + IDXGIAdapterN* mDXGIAdapter; - public: - // Constructors - D3D11Driver(); // Default - D3D11Driver( const D3D11Driver &ob ); // Copy - D3D11Driver( unsigned int adapterNumber, IDXGIAdapterN* pDXGIAdapter ); - ~D3D11Driver(); + public: + // Constructors + D3D11Driver(); // Default + D3D11Driver( const D3D11Driver &ob ); // Copy + D3D11Driver( unsigned int adapterNumber, IDXGIAdapterN* pDXGIAdapter ); + ~D3D11Driver(); - D3D11Driver& operator=(const D3D11Driver& r); + D3D11Driver& operator=(const D3D11Driver& r); - // Information accessors - String DriverName() const; - String DriverDescription() const; + // Information accessors + String DriverName() const; + String DriverDescription() const; - // change the device - unsigned int getAdapterNumber() const; - const DXGI_ADAPTER_DESC1& getAdapterIdentifier() const; - const DXGI_MODE_DESC& getDesktopMode() const; - IDXGIAdapterN* getDeviceAdapter() const; - D3D11VideoModeList* getVideoModeList(); - }; + // change the device + unsigned int getAdapterNumber() const; + const DXGI_ADAPTER_DESC1& getAdapterIdentifier() const; + const DXGI_MODE_DESC& getDesktopMode() const; + IDXGIAdapterN* getDeviceAdapter() const; + D3D11VideoModeList* getVideoModeList(); + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11DriverList.h b/RenderSystems/Direct3D11/include/OgreD3D11DriverList.h index ffd939fba96..a9aad3b3d8c 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11DriverList.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11DriverList.h @@ -34,22 +34,22 @@ THE SOFTWARE. namespace Ogre { - class D3D11DriverList - { - private: - vector::type mDriverList; + class D3D11DriverList + { + private: + vector::type mDriverList; - public: - D3D11DriverList( IDXGIFactoryN* pDXGIFactory ); - ~D3D11DriverList(); + public: + D3D11DriverList( IDXGIFactoryN* pDXGIFactory ); + ~D3D11DriverList(); - BOOL enumerate(IDXGIFactoryN* pDXGIFactory); - size_t count() const; - D3D11Driver* item( size_t index ); + BOOL enumerate(IDXGIFactoryN* pDXGIFactory); + size_t count() const; + D3D11Driver* item( size_t index ); - D3D11Driver* item( const String &name ); + D3D11Driver* item( const String &name ); - }; + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11GpuProgram.h b/RenderSystems/Direct3D11/include/OgreD3D11GpuProgram.h index 56df1412c19..b1a8edd8e51 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11GpuProgram.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11GpuProgram.h @@ -34,114 +34,114 @@ THE SOFTWARE. namespace Ogre { - /** Direct3D implementation of a few things common to low-level vertex & fragment programs. */ - class D3D11GpuProgram : public GpuProgram - { - protected: - D3D11Device & mDevice; - public: - D3D11GpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); - - protected: - /** @copydoc Resource::loadImpl */ - void loadImpl(void); - /** Overridden from GpuProgram */ - void loadFromSource(void); - /** Internal method to load from microcode, must be overridden by subclasses. */ - virtual void loadFromMicrocode(ID3D10Blob * microcode) = 0; - - - }; - - /** Direct3D implementation of low-level vertex programs. */ - class D3D11GpuVertexProgram : public D3D11GpuProgram - { - protected: - ID3D11VertexShader * mVertexShader; - public: - D3D11GpuVertexProgram(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); - ~D3D11GpuVertexProgram(); - /// Gets the vertex shader - ID3D11VertexShader * getVertexShader(void) const; - protected: - /** @copydoc Resource::unloadImpl */ - void unloadImpl(void); - void loadFromMicrocode(ID3D10Blob * microcode); - }; - - /** Direct3D implementation of low-level fragment programs. */ - class D3D11GpuFragmentProgram : public D3D11GpuProgram - { - protected: - ID3D11PixelShader * mPixelShader; - public: - D3D11GpuFragmentProgram(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); - ~D3D11GpuFragmentProgram(); - /// Gets the pixel shader - ID3D11PixelShader * getPixelShader(void) const; - protected: - /** @copydoc Resource::unloadImpl */ - void unloadImpl(void); - void loadFromMicrocode(ID3D10Blob * microcode); - }; - - /** Direct3D implementation of low-level vertex programs. */ - class D3D11GpuDomainProgram : public D3D11GpuProgram - { - protected: - ID3D11DomainShader * mDomainShader; - public: - D3D11GpuDomainProgram(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); - ~D3D11GpuDomainProgram(); - /// Gets the vertex shader - ID3D11DomainShader * getDomainShader(void) const; - protected: - /** @copydoc Resource::unloadImpl */ - void unloadImpl(void); - void loadFromMicrocode(ID3D10Blob * microcode); - }; - - /** Direct3D implementation of low-level vertex programs. */ - class D3D11GpuHullProgram : public D3D11GpuProgram - { - protected: - ID3D11HullShader * mHullShader; - public: - D3D11GpuHullProgram(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); - ~D3D11GpuHullProgram(); - /// Gets the vertex shader - ID3D11HullShader * getHullShader() const; - protected: - /** @copydoc Resource::unloadImpl */ - void unloadImpl(void); - void loadFromMicrocode(ID3D10Blob * microcode); - }; - - - /** - Direct3D implementation of low-level geometry programs. - Added due to need to accept geometry programs came from other profiles (nvgp4, for example) - */ - class D3D11GpuGeometryProgram : public D3D11GpuProgram - { - protected: - ID3D11GeometryShader * mGeometryShader; - public: - D3D11GpuGeometryProgram(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); - ~D3D11GpuGeometryProgram(); - /// Gets the geometry shader - ID3D11GeometryShader * getGeometryShader(void) const; - protected: - /** @copydoc Resource::unloadImpl */ - void unloadImpl(void); - void loadFromMicrocode(ID3D10Blob * microcode); - }; + /** Direct3D implementation of a few things common to low-level vertex & fragment programs. */ + class D3D11GpuProgram : public GpuProgram + { + protected: + D3D11Device & mDevice; + public: + D3D11GpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); + + protected: + /** @copydoc Resource::loadImpl */ + void loadImpl(void); + /** Overridden from GpuProgram */ + void loadFromSource(void); + /** Internal method to load from microcode, must be overridden by subclasses. */ + virtual void loadFromMicrocode(ID3D10Blob * microcode) = 0; + + + }; + + /** Direct3D implementation of low-level vertex programs. */ + class D3D11GpuVertexProgram : public D3D11GpuProgram + { + protected: + ID3D11VertexShader * mVertexShader; + public: + D3D11GpuVertexProgram(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); + ~D3D11GpuVertexProgram(); + /// Gets the vertex shader + ID3D11VertexShader * getVertexShader(void) const; + protected: + /** @copydoc Resource::unloadImpl */ + void unloadImpl(void); + void loadFromMicrocode(ID3D10Blob * microcode); + }; + + /** Direct3D implementation of low-level fragment programs. */ + class D3D11GpuFragmentProgram : public D3D11GpuProgram + { + protected: + ID3D11PixelShader * mPixelShader; + public: + D3D11GpuFragmentProgram(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); + ~D3D11GpuFragmentProgram(); + /// Gets the pixel shader + ID3D11PixelShader * getPixelShader(void) const; + protected: + /** @copydoc Resource::unloadImpl */ + void unloadImpl(void); + void loadFromMicrocode(ID3D10Blob * microcode); + }; + + /** Direct3D implementation of low-level vertex programs. */ + class D3D11GpuDomainProgram : public D3D11GpuProgram + { + protected: + ID3D11DomainShader * mDomainShader; + public: + D3D11GpuDomainProgram(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); + ~D3D11GpuDomainProgram(); + /// Gets the vertex shader + ID3D11DomainShader * getDomainShader(void) const; + protected: + /** @copydoc Resource::unloadImpl */ + void unloadImpl(void); + void loadFromMicrocode(ID3D10Blob * microcode); + }; + + /** Direct3D implementation of low-level vertex programs. */ + class D3D11GpuHullProgram : public D3D11GpuProgram + { + protected: + ID3D11HullShader * mHullShader; + public: + D3D11GpuHullProgram(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); + ~D3D11GpuHullProgram(); + /// Gets the vertex shader + ID3D11HullShader * getHullShader() const; + protected: + /** @copydoc Resource::unloadImpl */ + void unloadImpl(void); + void loadFromMicrocode(ID3D10Blob * microcode); + }; + + + /** + Direct3D implementation of low-level geometry programs. + Added due to need to accept geometry programs came from other profiles (nvgp4, for example) + */ + class D3D11GpuGeometryProgram : public D3D11GpuProgram + { + protected: + ID3D11GeometryShader * mGeometryShader; + public: + D3D11GpuGeometryProgram(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); + ~D3D11GpuGeometryProgram(); + /// Gets the geometry shader + ID3D11GeometryShader * getGeometryShader(void) const; + protected: + /** @copydoc Resource::unloadImpl */ + void unloadImpl(void); + void loadFromMicrocode(ID3D10Blob * microcode); + }; } diff --git a/RenderSystems/Direct3D11/include/OgreD3D11GpuProgramManager.h b/RenderSystems/Direct3D11/include/OgreD3D11GpuProgramManager.h index 7395a6c6189..65fd94c9342 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11GpuProgramManager.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11GpuProgramManager.h @@ -34,22 +34,22 @@ THE SOFTWARE. namespace Ogre { - class D3D11GpuProgramManager : public GpuProgramManager - { - protected: - D3D11Device & mDevice; - /// @copydoc ResourceManager::createImpl - Resource* createImpl(const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, - const NameValuePairList* createParams); - /// Specialised create method with specific parameters - Resource* createImpl(const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, - GpuProgramType gptype, const String& syntaxCode); - public: - D3D11GpuProgramManager(D3D11Device & device); - ~D3D11GpuProgramManager(); - }; + class D3D11GpuProgramManager : public GpuProgramManager + { + protected: + D3D11Device & mDevice; + /// @copydoc ResourceManager::createImpl + Resource* createImpl(const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, + const NameValuePairList* createParams); + /// Specialised create method with specific parameters + Resource* createImpl(const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, + GpuProgramType gptype, const String& syntaxCode); + public: + D3D11GpuProgramManager(D3D11Device & device); + ~D3D11GpuProgramManager(); + }; } diff --git a/RenderSystems/Direct3D11/include/OgreD3D11HLSLProgram.h b/RenderSystems/Direct3D11/include/OgreD3D11HLSLProgram.h index 10a84d3eec3..7cf0698c844 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11HLSLProgram.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11HLSLProgram.h @@ -35,208 +35,208 @@ THE SOFTWARE. namespace Ogre { - typedef vector::type MicroCode; - - /** Specialization of HighLevelGpuProgram to provide support for D3D11 - High-Level Shader Language (HLSL). - @remarks - Note that the syntax of D3D11 HLSL is identical to nVidia's Cg language, therefore - unless you know you will only ever be deploying on Direct3D, or you have some specific - reason for not wanting to use the Cg plugin, I suggest you use Cg instead since that - can produce programs for OpenGL too. - */ - class D3D11HLSLProgram : public HighLevelGpuProgram - { - public: - /// Command object for setting entry point - class CmdEntryPoint : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /// Command object for setting target assembler - class CmdTarget : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /// Command object for setting macro defines - class CmdPreprocessorDefines : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /// Command object for setting matrix packing in column-major order - class CmdColumnMajorMatrices : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /// Command object for setting backwards compatibility - class CmdEnableBackwardsCompatibility : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - - protected: - - static CmdEntryPoint msCmdEntryPoint; - static CmdTarget msCmdTarget; - static CmdPreprocessorDefines msCmdPreprocessorDefines; - static CmdColumnMajorMatrices msCmdColumnMajorMatrices; - static CmdEnableBackwardsCompatibility msCmdEnableBackwardsCompatibility; - - /** Internal method for creating an appropriate low-level program from this - high-level program, must be implemented by subclasses. */ - void createLowLevelImpl(void); - /// Internal unload implementation, must be implemented by subclasses - void unloadHighLevelImpl(void); - /// Populate the passed parameters with name->index map, must be overridden - void populateParameterNames(GpuProgramParametersSharedPtr params); - - // Recursive utility method for populateParameterNames - void processParamElement(String prefix, LPCSTR pName, ID3D11ShaderReflectionType* varRefType); - - void populateDef(D3D11_SHADER_TYPE_DESC& d3dDesc, GpuConstantDefinition& def) const; - - String mTarget; - String mEntryPoint; - String mPreprocessorDefines; - bool mColumnMajorMatrices; - bool mEnableBackwardsCompatibility; - - bool mErrorsInCompile; - MicroCode mMicroCode; - ID3D11Buffer* mConstantBuffer; - - D3D_SHADER_MACRO* mShaderMacros; - bool shaderMacroSet; - - D3D11Device & mDevice; - - D3D11VertexDeclaration mInputVertexDeclaration; - - ID3D11VertexShader* mVertexShader; - ID3D11PixelShader* mPixelShader; - ID3D11GeometryShader* mGeometryShader; - ID3D11DomainShader* mDomainShader; - ID3D11HullShader* mHullShader; - ID3D11ComputeShader* mComputeShader; - - struct ShaderVarWithPosInBuf - { - mutable String name; - size_t size; - size_t startOffset; - - ShaderVarWithPosInBuf& operator=(const ShaderVarWithPosInBuf& var) - { - name = var.name; - size = var.size; - startOffset = var.startOffset; - return *this; - } - }; - typedef vector::type ShaderVars; - typedef ShaderVars::iterator ShaderVarsIter; - typedef ShaderVars::const_iterator ShaderVarsConstIter; - - // A hack for cg to get the "original name" of the var in the "auto comments" - // that cg adds to the hlsl 4 output. This is to solve the issue that - // in some cases cg changes the name of the var to a new name. - void fixVariableNameFromCg(const ShaderVarWithPosInBuf& newVar); - //ShaderVars mShaderVars; - - // HACK: Multi-index emulation container to store constant buffer information by index and name at same time - // using tips from http://www.boost.org/doc/libs/1_35_0/libs/multi_index/doc/performance.html - // and http://cnx.org/content/m35767/1.2/ + typedef vector::type MicroCode; + + /** Specialization of HighLevelGpuProgram to provide support for D3D11 + High-Level Shader Language (HLSL). + @remarks + Note that the syntax of D3D11 HLSL is identical to nVidia's Cg language, therefore + unless you know you will only ever be deploying on Direct3D, or you have some specific + reason for not wanting to use the Cg plugin, I suggest you use Cg instead since that + can produce programs for OpenGL too. + */ + class D3D11HLSLProgram : public HighLevelGpuProgram + { + public: + /// Command object for setting entry point + class CmdEntryPoint : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for setting target assembler + class CmdTarget : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for setting macro defines + class CmdPreprocessorDefines : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for setting matrix packing in column-major order + class CmdColumnMajorMatrices : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for setting backwards compatibility + class CmdEnableBackwardsCompatibility : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + + protected: + + static CmdEntryPoint msCmdEntryPoint; + static CmdTarget msCmdTarget; + static CmdPreprocessorDefines msCmdPreprocessorDefines; + static CmdColumnMajorMatrices msCmdColumnMajorMatrices; + static CmdEnableBackwardsCompatibility msCmdEnableBackwardsCompatibility; + + /** Internal method for creating an appropriate low-level program from this + high-level program, must be implemented by subclasses. */ + void createLowLevelImpl(void); + /// Internal unload implementation, must be implemented by subclasses + void unloadHighLevelImpl(void); + /// Populate the passed parameters with name->index map, must be overridden + void populateParameterNames(GpuProgramParametersSharedPtr params); + + // Recursive utility method for populateParameterNames + void processParamElement(String prefix, LPCSTR pName, ID3D11ShaderReflectionType* varRefType); + + void populateDef(D3D11_SHADER_TYPE_DESC& d3dDesc, GpuConstantDefinition& def) const; + + String mTarget; + String mEntryPoint; + String mPreprocessorDefines; + bool mColumnMajorMatrices; + bool mEnableBackwardsCompatibility; + + bool mErrorsInCompile; + MicroCode mMicroCode; + ID3D11Buffer* mConstantBuffer; + + D3D_SHADER_MACRO* mShaderMacros; + bool shaderMacroSet; + + D3D11Device & mDevice; + + D3D11VertexDeclaration mInputVertexDeclaration; + + ID3D11VertexShader* mVertexShader; + ID3D11PixelShader* mPixelShader; + ID3D11GeometryShader* mGeometryShader; + ID3D11DomainShader* mDomainShader; + ID3D11HullShader* mHullShader; + ID3D11ComputeShader* mComputeShader; + + struct ShaderVarWithPosInBuf + { + mutable String name; + size_t size; + size_t startOffset; + + ShaderVarWithPosInBuf& operator=(const ShaderVarWithPosInBuf& var) + { + name = var.name; + size = var.size; + startOffset = var.startOffset; + return *this; + } + }; + typedef vector::type ShaderVars; + typedef ShaderVars::iterator ShaderVarsIter; + typedef ShaderVars::const_iterator ShaderVarsConstIter; + + // A hack for cg to get the "original name" of the var in the "auto comments" + // that cg adds to the hlsl 4 output. This is to solve the issue that + // in some cases cg changes the name of the var to a new name. + void fixVariableNameFromCg(const ShaderVarWithPosInBuf& newVar); + //ShaderVars mShaderVars; + + // HACK: Multi-index emulation container to store constant buffer information by index and name at same time + // using tips from http://www.boost.org/doc/libs/1_35_0/libs/multi_index/doc/performance.html + // and http://cnx.org/content/m35767/1.2/ #define INVALID_IDX (unsigned int)-1 - struct BufferInfo - { - static _StringHash mHash; - unsigned int mIdx; - String mName; - mutable HardwareUniformBufferSharedPtr mUniformBuffer; - mutable ShaderVars mShaderVars; - - // Default constructor - BufferInfo() : mIdx(0), mName("") { mUniformBuffer.setNull(); } - BufferInfo(unsigned int index, const String& name) - : mIdx(index), mName(name) - { - mUniformBuffer.setNull(); - } - - // Copy constructor - BufferInfo(const BufferInfo& info) - : mIdx(info.mIdx) - , mName(info.mName) - , mUniformBuffer(info.mUniformBuffer) - , mShaderVars(info.mShaderVars) - { - - } - - // Copy operator - BufferInfo& operator=(const BufferInfo& info) - { - this->mIdx = info.mIdx; - this->mName = info.mName; - mUniformBuffer = info.mUniformBuffer; - mShaderVars = info.mShaderVars; - return *this; - } - - // Constructors and operators used for search - BufferInfo(unsigned int index) : mIdx(index), mName("") { } - BufferInfo(const String& name) : mIdx(INVALID_IDX), mName(name) { } - BufferInfo& operator=(unsigned int index) { this->mIdx = index; return *this; } - BufferInfo& operator=(const String& name) { this->mName = name; return *this; } - - bool operator==(const BufferInfo& other) const - { - return mName == other.mName && mIdx == other.mIdx; - } - bool operator<(const BufferInfo& other) const - { - if (mIdx == INVALID_IDX || other.mIdx == INVALID_IDX) - { - return mName < other.mName; - } - else if (mName == "" || other.mName == "") - { - return mIdx < other.mIdx; - } - else - { - if (mName == other.mName) - { - return mIdx < other.mIdx; - } - else - { - return mName < other.mName; - } - } - } - }; - - // Make sure that objects have index and name, or some search will fail - typedef std::set BufferInfoMap; - typedef std::set::iterator BufferInfoIterator; - BufferInfoMap mBufferInfoMap; - - // Map to store interface slot position. - // Number of interface slots is size of this map. - typedef std::map SlotMap; - typedef std::map::const_iterator SlotIterator; - SlotMap mSlotMap; + struct BufferInfo + { + static _StringHash mHash; + unsigned int mIdx; + String mName; + mutable HardwareUniformBufferSharedPtr mUniformBuffer; + mutable ShaderVars mShaderVars; + + // Default constructor + BufferInfo() : mIdx(0), mName("") { mUniformBuffer.setNull(); } + BufferInfo(unsigned int index, const String& name) + : mIdx(index), mName(name) + { + mUniformBuffer.setNull(); + } + + // Copy constructor + BufferInfo(const BufferInfo& info) + : mIdx(info.mIdx) + , mName(info.mName) + , mUniformBuffer(info.mUniformBuffer) + , mShaderVars(info.mShaderVars) + { + + } + + // Copy operator + BufferInfo& operator=(const BufferInfo& info) + { + this->mIdx = info.mIdx; + this->mName = info.mName; + mUniformBuffer = info.mUniformBuffer; + mShaderVars = info.mShaderVars; + return *this; + } + + // Constructors and operators used for search + BufferInfo(unsigned int index) : mIdx(index), mName("") { } + BufferInfo(const String& name) : mIdx(INVALID_IDX), mName(name) { } + BufferInfo& operator=(unsigned int index) { this->mIdx = index; return *this; } + BufferInfo& operator=(const String& name) { this->mName = name; return *this; } + + bool operator==(const BufferInfo& other) const + { + return mName == other.mName && mIdx == other.mIdx; + } + bool operator<(const BufferInfo& other) const + { + if (mIdx == INVALID_IDX || other.mIdx == INVALID_IDX) + { + return mName < other.mName; + } + else if (mName == "" || other.mName == "") + { + return mIdx < other.mIdx; + } + else + { + if (mName == other.mName) + { + return mIdx < other.mIdx; + } + else + { + return mName < other.mName; + } + } + } + }; + + // Make sure that objects have index and name, or some search will fail + typedef std::set BufferInfoMap; + typedef std::set::iterator BufferInfoIterator; + BufferInfoMap mBufferInfoMap; + + // Map to store interface slot position. + // Number of interface slots is size of this map. + typedef std::map SlotMap; + typedef std::map::const_iterator SlotIterator; + SlotMap mSlotMap; typedef vector::type D3d11ShaderParameters; typedef D3d11ShaderParameters::iterator D3d11ShaderParametersIter; @@ -259,10 +259,10 @@ namespace Ogre { vector::type mSerStrings; - typedef vector::type D3d11ShaderBufferDescs; - typedef vector::type D3d11ShaderTypeDescs; - typedef vector::type InterfaceSlots; - typedef vector::type MemberTypeNames; + typedef vector::type D3d11ShaderBufferDescs; + typedef vector::type D3d11ShaderTypeDescs; + typedef vector::type InterfaceSlots; + typedef vector::type MemberTypeNames; UINT mConstantBufferSize; UINT mConstantBufferNr; @@ -272,97 +272,97 @@ namespace Ogre { D3d11ShaderParameters mD3d11ShaderOutputParameters; D3d11ShaderVariables mD3d11ShaderVariables; D3d11ShaderVariableSubparts mD3d11ShaderVariableSubparts; - D3d11ShaderBufferDescs mD3d11ShaderBufferDescs; - D3d11ShaderVariables mVarDescBuffer; - D3d11ShaderVariables mVarDescPointer; - D3d11ShaderTypeDescs mD3d11ShaderTypeDescs; - D3d11ShaderTypeDescs mMemberTypeDesc; - MemberTypeNames mMemberTypeName; - InterfaceSlots mInterfaceSlots; - - void createConstantBuffer(const UINT ByteWidth); - void analizeMicrocode(); - void getMicrocodeFromCache(void); - void compileMicrocode(void); - public: - D3D11HLSLProgram(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); - ~D3D11HLSLProgram(); - - /** Sets the entry point for this program ie the first method called. */ - void setEntryPoint(const String& entryPoint) { mEntryPoint = entryPoint; } - /** Gets the entry point defined for this program. */ - const String& getEntryPoint(void) const { return mEntryPoint; } - /** Sets the shader target to compile down to, e.g. 'vs_1_1'. */ - void setTarget(const String& target); - /** Gets the shader target to compile down to, e.g. 'vs_1_1'. */ - const String& getTarget(void) const { return mTarget; } - /** Gets the shader target promoted to the first compatible, e.g. 'vs_4_0' or 'ps_4_0' if backward compatibility is enabled. */ - const String& getCompatibleTarget(void) const; - /** Sets shader macros created manually*/ - void setShaderMacros(D3D_SHADER_MACRO* shaderMacros); - - /** Sets the preprocessor defines use to compile the program. */ - void setPreprocessorDefines(const String& defines) { mPreprocessorDefines = defines; } - /** Sets the preprocessor defines use to compile the program. */ - const String& getPreprocessorDefines(void) const { return mPreprocessorDefines; } - /** Sets whether matrix packing in column-major order. */ - void setColumnMajorMatrices(bool columnMajor) { mColumnMajorMatrices = columnMajor; } - /** Gets whether matrix packed in column-major order. */ - bool getColumnMajorMatrices(void) const { return mColumnMajorMatrices; } - /** Sets whether backwards compatibility is enabled. */ - void setEnableBackwardsCompatibility(bool enableBackwardsCompatibility) { mEnableBackwardsCompatibility = enableBackwardsCompatibility; } - /** Gets whether backwards compatibility is enabled. */ - bool getEnableBackwardsCompatibility(void) const { return mEnableBackwardsCompatibility; } - /// Overridden from GpuProgram - bool isSupported(void) const; - /// Overridden from GpuProgram - GpuProgramParametersSharedPtr createParameters(void); - /// Overridden from GpuProgram - const String& getLanguage(void) const; - - virtual void buildConstantDefinitions() const; - ID3D11VertexShader* getVertexShader(void) const; - ID3D11PixelShader* getPixelShader(void) const; - ID3D11GeometryShader* getGeometryShader(void) const; - ID3D11DomainShader* getDomainShader(void) const; - ID3D11HullShader* getHullShader(void) const; - ID3D11ComputeShader* getComputeShader(void) const; - const MicroCode & getMicroCode(void) const; - - ID3D11Buffer* getConstantBuffer(GpuProgramParametersSharedPtr params, uint16 variabilityMask); - - void getConstantBuffers(ID3D11Buffer** buffers, unsigned int& numBuffers, - ID3D11ClassInstance** classes, unsigned int& numInstances, - GpuProgramParametersSharedPtr params, uint16 variabilityMask); - - // Get slot for a specific interface - unsigned int getSubroutineSlot(const String& subroutineSlotName) const; - - void CreateVertexShader(); - void CreatePixelShader(); - void CreateGeometryShader(); - void CreateDomainShader(); - void CreateHullShader(); - void CreateComputeShader(); - - /** Internal load implementation, must be implemented by subclasses. - */ - void loadFromSource(void); - - D3D11VertexDeclaration & getInputVertexDeclaration() { return mInputVertexDeclaration; } - - void reinterpretGSForStreamOut(void); - bool mReinterpretingGS; + D3d11ShaderBufferDescs mD3d11ShaderBufferDescs; + D3d11ShaderVariables mVarDescBuffer; + D3d11ShaderVariables mVarDescPointer; + D3d11ShaderTypeDescs mD3d11ShaderTypeDescs; + D3d11ShaderTypeDescs mMemberTypeDesc; + MemberTypeNames mMemberTypeName; + InterfaceSlots mInterfaceSlots; + + void createConstantBuffer(const UINT ByteWidth); + void analizeMicrocode(); + void getMicrocodeFromCache(void); + void compileMicrocode(void); + public: + D3D11HLSLProgram(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device); + ~D3D11HLSLProgram(); + + /** Sets the entry point for this program ie the first method called. */ + void setEntryPoint(const String& entryPoint) { mEntryPoint = entryPoint; } + /** Gets the entry point defined for this program. */ + const String& getEntryPoint(void) const { return mEntryPoint; } + /** Sets the shader target to compile down to, e.g. 'vs_1_1'. */ + void setTarget(const String& target); + /** Gets the shader target to compile down to, e.g. 'vs_1_1'. */ + const String& getTarget(void) const { return mTarget; } + /** Gets the shader target promoted to the first compatible, e.g. 'vs_4_0' or 'ps_4_0' if backward compatibility is enabled. */ + const String& getCompatibleTarget(void) const; + /** Sets shader macros created manually*/ + void setShaderMacros(D3D_SHADER_MACRO* shaderMacros); + + /** Sets the preprocessor defines use to compile the program. */ + void setPreprocessorDefines(const String& defines) { mPreprocessorDefines = defines; } + /** Sets the preprocessor defines use to compile the program. */ + const String& getPreprocessorDefines(void) const { return mPreprocessorDefines; } + /** Sets whether matrix packing in column-major order. */ + void setColumnMajorMatrices(bool columnMajor) { mColumnMajorMatrices = columnMajor; } + /** Gets whether matrix packed in column-major order. */ + bool getColumnMajorMatrices(void) const { return mColumnMajorMatrices; } + /** Sets whether backwards compatibility is enabled. */ + void setEnableBackwardsCompatibility(bool enableBackwardsCompatibility) { mEnableBackwardsCompatibility = enableBackwardsCompatibility; } + /** Gets whether backwards compatibility is enabled. */ + bool getEnableBackwardsCompatibility(void) const { return mEnableBackwardsCompatibility; } + /// Overridden from GpuProgram + bool isSupported(void) const; + /// Overridden from GpuProgram + GpuProgramParametersSharedPtr createParameters(void); + /// Overridden from GpuProgram + const String& getLanguage(void) const; + + virtual void buildConstantDefinitions() const; + ID3D11VertexShader* getVertexShader(void) const; + ID3D11PixelShader* getPixelShader(void) const; + ID3D11GeometryShader* getGeometryShader(void) const; + ID3D11DomainShader* getDomainShader(void) const; + ID3D11HullShader* getHullShader(void) const; + ID3D11ComputeShader* getComputeShader(void) const; + const MicroCode & getMicroCode(void) const; + + ID3D11Buffer* getConstantBuffer(GpuProgramParametersSharedPtr params, uint16 variabilityMask); + + void getConstantBuffers(ID3D11Buffer** buffers, unsigned int& numBuffers, + ID3D11ClassInstance** classes, unsigned int& numInstances, + GpuProgramParametersSharedPtr params, uint16 variabilityMask); + + // Get slot for a specific interface + unsigned int getSubroutineSlot(const String& subroutineSlotName) const; + + void CreateVertexShader(); + void CreatePixelShader(); + void CreateGeometryShader(); + void CreateDomainShader(); + void CreateHullShader(); + void CreateComputeShader(); + + /** Internal load implementation, must be implemented by subclasses. + */ + void loadFromSource(void); + + D3D11VertexDeclaration & getInputVertexDeclaration() { return mInputVertexDeclaration; } + + void reinterpretGSForStreamOut(void); + bool mReinterpretingGS; - unsigned int getNumInputs(void)const; - unsigned int getNumOutputs(void)const; + unsigned int getNumInputs(void)const; + unsigned int getNumOutputs(void)const; - String getNameForMicrocodeCache(); + String getNameForMicrocodeCache(); - const D3D11_SIGNATURE_PARAMETER_DESC & getInputParamDesc(unsigned int index) const; - const D3D11_SIGNATURE_PARAMETER_DESC & getOutputParamDesc(unsigned int index) const; - }; + const D3D11_SIGNATURE_PARAMETER_DESC & getInputParamDesc(unsigned int index) const; + const D3D11_SIGNATURE_PARAMETER_DESC & getOutputParamDesc(unsigned int index) const; + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11HLSLProgramFactory.h b/RenderSystems/Direct3D11/include/OgreD3D11HLSLProgramFactory.h index 40ab4a64086..9fc39d2e674 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11HLSLProgramFactory.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11HLSLProgramFactory.h @@ -33,23 +33,23 @@ THE SOFTWARE. namespace Ogre { - /** Factory class for D3D11 HLSL programs. */ - class D3D11HLSLProgramFactory : public HighLevelGpuProgramFactory - { - protected: - static String sLanguageName; - D3D11Device & mDevice; - public: - D3D11HLSLProgramFactory(D3D11Device & device); - ~D3D11HLSLProgramFactory(); - /// Get the name of the language this factory creates programs for - const String& getLanguage(void) const; - HighLevelGpuProgram* create(ResourceManager* creator, - const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader); - void destroy(HighLevelGpuProgram* prog); - - }; + /** Factory class for D3D11 HLSL programs. */ + class D3D11HLSLProgramFactory : public HighLevelGpuProgramFactory + { + protected: + static String sLanguageName; + D3D11Device & mDevice; + public: + D3D11HLSLProgramFactory(D3D11Device & device); + ~D3D11HLSLProgramFactory(); + /// Get the name of the language this factory creates programs for + const String& getLanguage(void) const; + HighLevelGpuProgram* create(ResourceManager* creator, + const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader); + void destroy(HighLevelGpuProgram* prog); + + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11HardwareBuffer.h b/RenderSystems/Direct3D11/include/OgreD3D11HardwareBuffer.h index 512174383c0..f9338c79d60 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11HardwareBuffer.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11HardwareBuffer.h @@ -34,50 +34,50 @@ THE SOFTWARE. namespace Ogre { - /** Base implementation of a D3D11 buffer, dealing with all the common - aspects. - */ - class D3D11HardwareBuffer : public HardwareBuffer - { - public: - enum BufferType - { - VERTEX_BUFFER, - INDEX_BUFFER, - CONSTANT_BUFFER - }; - protected: - ID3D11Buffer* mlpD3DBuffer; - bool mUseTempStagingBuffer; - D3D11HardwareBuffer* mpTempStagingBuffer; - bool mStagingUploadNeeded; - BufferType mBufferType; - D3D11Device & mDevice; - D3D11_BUFFER_DESC mDesc; - - - - /** See HardwareBuffer. */ - void* lockImpl(size_t offset, size_t length, LockOptions options); - /** See HardwareBuffer. */ - void unlockImpl(void); - - public: - D3D11HardwareBuffer(BufferType btype, size_t sizeBytes, HardwareBuffer::Usage usage, - D3D11Device & device, bool useSystemMem, bool useShadowBuffer, bool streamOut); - ~D3D11HardwareBuffer(); - /** See HardwareBuffer. */ - void readData(size_t offset, size_t length, void* pDest); - /** See HardwareBuffer. */ - void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); - /** See HardwareBuffer. We perform a hardware copy here. */ - void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, - size_t dstOffset, size_t length, bool discardWholeBuffer = false); - - /// Get the D3D-specific buffer - ID3D11Buffer* getD3DBuffer(void) { return mlpD3DBuffer; } - }; + /** Base implementation of a D3D11 buffer, dealing with all the common + aspects. + */ + class D3D11HardwareBuffer : public HardwareBuffer + { + public: + enum BufferType + { + VERTEX_BUFFER, + INDEX_BUFFER, + CONSTANT_BUFFER + }; + protected: + ID3D11Buffer* mlpD3DBuffer; + bool mUseTempStagingBuffer; + D3D11HardwareBuffer* mpTempStagingBuffer; + bool mStagingUploadNeeded; + BufferType mBufferType; + D3D11Device & mDevice; + D3D11_BUFFER_DESC mDesc; + + + + /** See HardwareBuffer. */ + void* lockImpl(size_t offset, size_t length, LockOptions options); + /** See HardwareBuffer. */ + void unlockImpl(void); + + public: + D3D11HardwareBuffer(BufferType btype, size_t sizeBytes, HardwareBuffer::Usage usage, + D3D11Device & device, bool useSystemMem, bool useShadowBuffer, bool streamOut); + ~D3D11HardwareBuffer(); + /** See HardwareBuffer. */ + void readData(size_t offset, size_t length, void* pDest); + /** See HardwareBuffer. */ + void writeData(size_t offset, size_t length, const void* pSource, + bool discardWholeBuffer = false); + /** See HardwareBuffer. We perform a hardware copy here. */ + void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, + size_t dstOffset, size_t length, bool discardWholeBuffer = false); + + /// Get the D3D-specific buffer + ID3D11Buffer* getD3DBuffer(void) { return mlpD3DBuffer; } + }; } diff --git a/RenderSystems/Direct3D11/include/OgreD3D11HardwareBufferManager.h b/RenderSystems/Direct3D11/include/OgreD3D11HardwareBufferManager.h index cf717b71682..e262f6b99df 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11HardwareBufferManager.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11HardwareBufferManager.h @@ -33,67 +33,67 @@ THE SOFTWARE. namespace Ogre { - /** Implementation of HardwareBufferManager for D3D11. */ - class D3D11HardwareBufferManagerBase : public HardwareBufferManagerBase - { - protected: - D3D11Device & mlpD3DDevice; - - /// Internal method for creates a new vertex declaration, may be overridden by certain rendering APIs - VertexDeclaration* createVertexDeclarationImpl(void); - /// Internal method for destroys a vertex declaration, may be overridden by certain rendering APIs - void destroyVertexDeclarationImpl(VertexDeclaration* decl); - - public: - D3D11HardwareBufferManagerBase(D3D11Device & device); - ~D3D11HardwareBufferManagerBase(); - /// Creates a vertex buffer - HardwareVertexBufferSharedPtr - createVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// Creates a stream output vertex buffer - HardwareVertexBufferSharedPtr - createStreamOutputVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// Create a hardware vertex buffer - HardwareIndexBufferSharedPtr - createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// @copydoc HardwareBufferManager::createRenderToVertexBuffer - RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); - /// @copydoc HardwareBufferManager::createUniformBuffer - HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, - HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, - bool useShadowBuffer = false, const String& name = ""); - /// @copydoc HardwareBufferManager::createCounterBuffer - HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, + /** Implementation of HardwareBufferManager for D3D11. */ + class D3D11HardwareBufferManagerBase : public HardwareBufferManagerBase + { + protected: + D3D11Device & mlpD3DDevice; + + /// Internal method for creates a new vertex declaration, may be overridden by certain rendering APIs + VertexDeclaration* createVertexDeclarationImpl(void); + /// Internal method for destroys a vertex declaration, may be overridden by certain rendering APIs + void destroyVertexDeclarationImpl(VertexDeclaration* decl); + + public: + D3D11HardwareBufferManagerBase(D3D11Device & device); + ~D3D11HardwareBufferManagerBase(); + /// Creates a vertex buffer + HardwareVertexBufferSharedPtr + createVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer = false); + /// Creates a stream output vertex buffer + HardwareVertexBufferSharedPtr + createStreamOutputVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer = false); + /// Create a hardware vertex buffer + HardwareIndexBufferSharedPtr + createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer = false); + /// @copydoc HardwareBufferManager::createRenderToVertexBuffer + RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); + /// @copydoc HardwareBufferManager::createUniformBuffer + HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, + HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, + bool useShadowBuffer = false, const String& name = ""); + /// @copydoc HardwareBufferManager::createCounterBuffer + HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, bool useShadowBuffer = false, const String& name = ""); - /** Release all buffers in the default memory pool. - @remarks - Method for dealing with lost devices. - */ - void releaseDefaultPoolResources(void); - /** Recreate all buffers in the default memory pool. - @remarks - Method for dealing with lost devices. - */ - void recreateDefaultPoolResources(void); - - }; - - /// D3D11HardwareBufferManagerBase as a Singleton - class D3D11HardwareBufferManager : public HardwareBufferManager - { - public: - D3D11HardwareBufferManager(D3D11Device & device) - : HardwareBufferManager(OGRE_NEW D3D11HardwareBufferManagerBase(device)) - { - - } - ~D3D11HardwareBufferManager() - { - OGRE_DELETE mImpl; - } - }; + /** Release all buffers in the default memory pool. + @remarks + Method for dealing with lost devices. + */ + void releaseDefaultPoolResources(void); + /** Recreate all buffers in the default memory pool. + @remarks + Method for dealing with lost devices. + */ + void recreateDefaultPoolResources(void); + + }; + + /// D3D11HardwareBufferManagerBase as a Singleton + class D3D11HardwareBufferManager : public HardwareBufferManager + { + public: + D3D11HardwareBufferManager(D3D11Device & device) + : HardwareBufferManager(OGRE_NEW D3D11HardwareBufferManagerBase(device)) + { + + } + ~D3D11HardwareBufferManager() + { + OGRE_DELETE mImpl; + } + }; } diff --git a/RenderSystems/Direct3D11/include/OgreD3D11HardwareIndexBuffer.h b/RenderSystems/Direct3D11/include/OgreD3D11HardwareIndexBuffer.h index c675a907c72..17e6e9b2505 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11HardwareIndexBuffer.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11HardwareIndexBuffer.h @@ -35,43 +35,43 @@ THE SOFTWARE. namespace Ogre { - class D3D11HardwareIndexBuffer : public HardwareIndexBuffer - { - protected: - D3D11HardwareBuffer* mBufferImpl; - // have to implement these, but do nothing as overridden lock/unlock - void* lockImpl(size_t offset, size_t length, LockOptions options) {return 0;} - void unlockImpl(void) {} + class D3D11HardwareIndexBuffer : public HardwareIndexBuffer + { + protected: + D3D11HardwareBuffer* mBufferImpl; + // have to implement these, but do nothing as overridden lock/unlock + void* lockImpl(size_t offset, size_t length, LockOptions options) {return 0;} + void unlockImpl(void) {} - public: - D3D11HardwareIndexBuffer(HardwareBufferManagerBase* mgr, IndexType idxType, size_t numIndexes, - HardwareBuffer::Usage usage, D3D11Device & device, bool useSystemMem, bool useShadowBuffer); - ~D3D11HardwareIndexBuffer(); + public: + D3D11HardwareIndexBuffer(HardwareBufferManagerBase* mgr, IndexType idxType, size_t numIndexes, + HardwareBuffer::Usage usage, D3D11Device & device, bool useSystemMem, bool useShadowBuffer); + ~D3D11HardwareIndexBuffer(); - // override all data-gathering methods - void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); - void unlock(void); - void readData(size_t offset, size_t length, void* pDest); - void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); + // override all data-gathering methods + void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); + void unlock(void); + void readData(size_t offset, size_t length, void* pDest); + void writeData(size_t offset, size_t length, const void* pSource, + bool discardWholeBuffer = false); - void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, - size_t dstOffset, size_t length, bool discardWholeBuffer = false); - bool isLocked(void) const; + void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, + size_t dstOffset, size_t length, bool discardWholeBuffer = false); + bool isLocked(void) const; - /// For dealing with lost devices - release the resource if in the default pool - bool releaseIfDefaultPool(void); - /// For dealing with lost devices - recreate the resource if in the default pool - bool recreateIfDefaultPool(D3D11Device & device); + /// For dealing with lost devices - release the resource if in the default pool + bool releaseIfDefaultPool(void); + /// For dealing with lost devices - recreate the resource if in the default pool + bool recreateIfDefaultPool(D3D11Device & device); - /// Get the D3D-specific index buffer - ID3D11Buffer * getD3DIndexBuffer(void) const; + /// Get the D3D-specific index buffer + ID3D11Buffer * getD3DIndexBuffer(void) const; - }; + }; } diff --git a/RenderSystems/Direct3D11/include/OgreD3D11HardwareOcclusionQuery.h b/RenderSystems/Direct3D11/include/OgreD3D11HardwareOcclusionQuery.h index cd4b4b802fc..41c1b1e8d87 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11HardwareOcclusionQuery.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11HardwareOcclusionQuery.h @@ -35,58 +35,58 @@ THE SOFTWARE. namespace Ogre { - // If you use multiple rendering passes you can test only the first pass and all other passes don't have to be rendered - // if the first pass results has too few pixels visible. - - // Be sure to render all occluder first and whats out so the RenderQue don't switch places on - // the occluding objects and the tested objects because it thinks it's more effective.. - - /** - * This is a class that is the DirectX9 implementation of - * hardware occlusion testing. - * - * @author Lee Sandberg, email lee@abcmedia.se - * - * Updated on 12/7/2004 by Chris McGuirk - * Updated on 4/8/2005 by Tuan Kuranes email: tuan.kuranes@free.fr - */ - class D3D11HardwareOcclusionQuery : public HardwareOcclusionQuery - { - //---------------------------------------------------------------------- - // Public methods - //-- - public: - - /** - * Default object constructor - * - */ - D3D11HardwareOcclusionQuery( D3D11Device & device ); - - /** - * Object destructor - */ - ~D3D11HardwareOcclusionQuery(); - - //------------------------------------------------------------------ - // Occlusion query functions (see base class documentation for this) - //-- - - void beginOcclusionQuery(); - void endOcclusionQuery(); - bool pullOcclusionQuery( unsigned int* NumOfFragments); - unsigned int getLastQuerysPixelcount() { return mPixelCount; } + // If you use multiple rendering passes you can test only the first pass and all other passes don't have to be rendered + // if the first pass results has too few pixels visible. + + // Be sure to render all occluder first and whats out so the RenderQue don't switch places on + // the occluding objects and the tested objects because it thinks it's more effective.. + + /** + * This is a class that is the DirectX9 implementation of + * hardware occlusion testing. + * + * @author Lee Sandberg, email lee@abcmedia.se + * + * Updated on 12/7/2004 by Chris McGuirk + * Updated on 4/8/2005 by Tuan Kuranes email: tuan.kuranes@free.fr + */ + class D3D11HardwareOcclusionQuery : public HardwareOcclusionQuery + { + //---------------------------------------------------------------------- + // Public methods + //-- + public: + + /** + * Default object constructor + * + */ + D3D11HardwareOcclusionQuery( D3D11Device & device ); + + /** + * Object destructor + */ + ~D3D11HardwareOcclusionQuery(); + + //------------------------------------------------------------------ + // Occlusion query functions (see base class documentation for this) + //-- + + void beginOcclusionQuery(); + void endOcclusionQuery(); + bool pullOcclusionQuery( unsigned int* NumOfFragments); + unsigned int getLastQuerysPixelcount() { return mPixelCount; } bool isStillOutstanding(void); - + - //---------------------------------------------------------------------- - // private members - //-- - private: - ID3D11Query* mQuery; - D3D11Device & mDevice; - }; + //---------------------------------------------------------------------- + // private members + //-- + private: + ID3D11Query* mQuery; + D3D11Device & mDevice; + }; } diff --git a/RenderSystems/Direct3D11/include/OgreD3D11HardwarePixelBuffer.h b/RenderSystems/Direct3D11/include/OgreD3D11HardwarePixelBuffer.h index 4aa890e4d65..940617e0217 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11HardwarePixelBuffer.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11HardwarePixelBuffer.h @@ -36,83 +36,83 @@ struct ID3D11Resource; namespace Ogre { - class D3D11HardwarePixelBuffer: public HardwarePixelBuffer - { - protected: - /// Lock a box - PixelBox lockImpl(const Image::Box &lockBox, LockOptions options); + class D3D11HardwarePixelBuffer: public HardwarePixelBuffer + { + protected: + /// Lock a box + PixelBox lockImpl(const Image::Box &lockBox, LockOptions options); - /// Unlock a box - void unlockImpl(void); + /// Unlock a box + void unlockImpl(void); - /// D3DDevice pointer - D3D11Device & mDevice; + /// D3DDevice pointer + D3D11Device & mDevice; - D3D11Texture * mParentTexture; - size_t mSubresourceIndex; + D3D11Texture * mParentTexture; + size_t mSubresourceIndex; - // if the usage is static - alloc at lock then use device UpdateSubresource when unlock and free memory - int8 * mDataForStaticUsageLock; + // if the usage is static - alloc at lock then use device UpdateSubresource when unlock and free memory + int8 * mDataForStaticUsageLock; - size_t mFace; + size_t mFace; - Image::Box mLockBox; - PixelBox mCurrentLock; - LockOptions mCurrentLockOptions; + Image::Box mLockBox; + PixelBox mCurrentLock; + LockOptions mCurrentLockOptions; - D3D11_BOX OgreImageBoxToDx11Box(const Image::Box &inBox) const; + D3D11_BOX OgreImageBoxToDx11Box(const Image::Box &inBox) const; - /// Util functions to convert a D3D locked box to a pixel box - void fromD3DLock(PixelBox &rval, const DXGI_MAPPED_RECT &lrect); + /// Util functions to convert a D3D locked box to a pixel box + void fromD3DLock(PixelBox &rval, const DXGI_MAPPED_RECT &lrect); - /// Render targets - typedef vector::type SliceTRT; - SliceTRT mSliceTRT; + /// Render targets + typedef vector::type SliceTRT; + SliceTRT mSliceTRT; - void createStagingBuffer(); - bool mUsingStagingBuffer; - ID3D11Resource *mStagingBuffer; - - void _map(ID3D11Resource *res, D3D11_MAP flags, PixelBox & box); - void *_mapstagingbuffer(D3D11_MAP flags); - void *_mapstaticbuffer(PixelBox lock); - void _unmap(ID3D11Resource *res); - void _unmapstagingbuffer(bool copyback = true); - void _unmapstaticbuffer(); - public: - D3D11HardwarePixelBuffer(D3D11Texture * parentTexture, D3D11Device & device, size_t subresourceIndex, - size_t width, size_t height, size_t depth, size_t face, PixelFormat format, HardwareBuffer::Usage usage); + void createStagingBuffer(); + bool mUsingStagingBuffer; + ID3D11Resource *mStagingBuffer; + + void _map(ID3D11Resource *res, D3D11_MAP flags, PixelBox & box); + void *_mapstagingbuffer(D3D11_MAP flags); + void *_mapstaticbuffer(PixelBox lock); + void _unmap(ID3D11Resource *res); + void _unmapstagingbuffer(bool copyback = true); + void _unmapstaticbuffer(); + public: + D3D11HardwarePixelBuffer(D3D11Texture * parentTexture, D3D11Device & device, size_t subresourceIndex, + size_t width, size_t height, size_t depth, size_t face, PixelFormat format, HardwareBuffer::Usage usage); - /// @copydoc HardwarePixelBuffer::blit - void blit(const HardwarePixelBufferSharedPtr &src, const Image::Box &srcBox, const Image::Box &dstBox); + /// @copydoc HardwarePixelBuffer::blit + void blit(const HardwarePixelBufferSharedPtr &src, const Image::Box &srcBox, const Image::Box &dstBox); - /// @copydoc HardwarePixelBuffer::blitFromMemory - void blitFromMemory(const PixelBox &src, const Image::Box &dstBox); + /// @copydoc HardwarePixelBuffer::blitFromMemory + void blitFromMemory(const PixelBox &src, const Image::Box &dstBox); - /// @copydoc HardwarePixelBuffer::blitToMemory - void blitToMemory(const Image::Box &srcBox, const PixelBox &dst); + /// @copydoc HardwarePixelBuffer::blitToMemory + void blitToMemory(const Image::Box &srcBox, const PixelBox &dst); - /// Internal function to update mipmaps on update of level 0 - void _genMipmaps(); + /// Internal function to update mipmaps on update of level 0 + void _genMipmaps(); - ~D3D11HardwarePixelBuffer(); + ~D3D11HardwarePixelBuffer(); - /// Get rendertarget for z slice - RenderTexture *getRenderTarget(size_t zoffset); + /// Get rendertarget for z slice + RenderTexture *getRenderTarget(size_t zoffset); - /// Notify TextureBuffer of destruction of render target - virtual void _clearSliceRTT(size_t zoffset) - { - if (mSliceTRT.size() > zoffset) - { - mSliceTRT[zoffset] = 0; - } - } + /// Notify TextureBuffer of destruction of render target + virtual void _clearSliceRTT(size_t zoffset) + { + if (mSliceTRT.size() > zoffset) + { + mSliceTRT[zoffset] = 0; + } + } - D3D11Texture * getParentTexture() const; - size_t getSubresourceIndex() const; - size_t getFace() const; - }; + D3D11Texture * getParentTexture() const; + size_t getSubresourceIndex() const; + size_t getFace() const; + }; }; #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11HardwareUniformBuffer.h b/RenderSystems/Direct3D11/include/OgreD3D11HardwareUniformBuffer.h index 47f0514a598..876201c4767 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11HardwareUniformBuffer.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11HardwareUniformBuffer.h @@ -34,39 +34,39 @@ THE SOFTWARE. namespace Ogre { - /// Specialisation of HardwareBuffer for D3D11 - class D3D11HardwareUniformBuffer : public HardwareUniformBuffer - { - protected: - D3D11HardwareBuffer* mBufferImpl; - // have to implement these, but do nothing as overridden lock/unlock - void* lockImpl(size_t offset, size_t length, LockOptions options) {return 0;} - void unlockImpl(void) {} + /// Specialisation of HardwareBuffer for D3D11 + class D3D11HardwareUniformBuffer : public HardwareUniformBuffer + { + protected: + D3D11HardwareBuffer* mBufferImpl; + // have to implement these, but do nothing as overridden lock/unlock + void* lockImpl(size_t offset, size_t length, LockOptions options) {return 0;} + void unlockImpl(void) {} - public: - D3D11HardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, - bool useShadowBuffer, const String& name, D3D11Device & device); - ~D3D11HardwareUniformBuffer(); + public: + D3D11HardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, + bool useShadowBuffer, const String& name, D3D11Device & device); + ~D3D11HardwareUniformBuffer(); - // override all data-gathering methods - void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); - void unlock(void); - void readData(size_t offset, size_t length, void* pDest); - void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); + // override all data-gathering methods + void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); + void unlock(void); + void readData(size_t offset, size_t length, void* pDest); + void writeData(size_t offset, size_t length, const void* pSource, + bool discardWholeBuffer = false); - void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, - size_t dstOffset, size_t length, bool discardWholeBuffer = false); - bool isLocked(void) const; + void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, + size_t dstOffset, size_t length, bool discardWholeBuffer = false); + bool isLocked(void) const; - /// For dealing with lost devices - release the resource if in the default pool - bool releaseIfDefaultPool(void); - /// For dealing with lost devices - recreate the resource if in the default pool - bool recreateIfDefaultPool(D3D11Device & device); + /// For dealing with lost devices - release the resource if in the default pool + bool releaseIfDefaultPool(void); + /// For dealing with lost devices - recreate the resource if in the default pool + bool recreateIfDefaultPool(D3D11Device & device); - /// Get the D3D-specific vertex buffer - ID3D11Buffer * getD3DConstantBuffer(void) const; - }; + /// Get the D3D-specific vertex buffer + ID3D11Buffer * getD3DConstantBuffer(void) const; + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11HardwareVertexBuffer.h b/RenderSystems/Direct3D11/include/OgreD3D11HardwareVertexBuffer.h index 346329b508a..103b841bda3 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11HardwareVertexBuffer.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11HardwareVertexBuffer.h @@ -33,40 +33,40 @@ THE SOFTWARE. namespace Ogre { - /// Specialisation of HardwareVertexBuffer for D3D11 - class D3D11HardwareVertexBuffer : public HardwareVertexBuffer - { - protected: - D3D11HardwareBuffer* mBufferImpl; - // have to implement these, but do nothing as overridden lock/unlock - void* lockImpl(size_t offset, size_t length, LockOptions options) {return 0;} - void unlockImpl(void) {} + /// Specialisation of HardwareVertexBuffer for D3D11 + class D3D11HardwareVertexBuffer : public HardwareVertexBuffer + { + protected: + D3D11HardwareBuffer* mBufferImpl; + // have to implement these, but do nothing as overridden lock/unlock + void* lockImpl(size_t offset, size_t length, LockOptions options) {return 0;} + void unlockImpl(void) {} - public: - D3D11HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, - HardwareBuffer::Usage usage, D3D11Device & device, bool useSystemMem, bool useShadowBuffer, - bool streamOut); - ~D3D11HardwareVertexBuffer(); + public: + D3D11HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, + HardwareBuffer::Usage usage, D3D11Device & device, bool useSystemMem, bool useShadowBuffer, + bool streamOut); + ~D3D11HardwareVertexBuffer(); - // override all data-gathering methods - void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); - void unlock(void); - void readData(size_t offset, size_t length, void* pDest); - void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); + // override all data-gathering methods + void* lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt = HBU_DEFAULT); + void unlock(void); + void readData(size_t offset, size_t length, void* pDest); + void writeData(size_t offset, size_t length, const void* pSource, + bool discardWholeBuffer = false); - void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, - size_t dstOffset, size_t length, bool discardWholeBuffer = false); - bool isLocked(void) const; + void copyData(HardwareBuffer& srcBuffer, size_t srcOffset, + size_t dstOffset, size_t length, bool discardWholeBuffer = false); + bool isLocked(void) const; - /// For dealing with lost devices - release the resource if in the default pool - bool releaseIfDefaultPool(void); - /// For dealing with lost devices - recreate the resource if in the default pool - bool recreateIfDefaultPool(D3D11Device & device); + /// For dealing with lost devices - release the resource if in the default pool + bool releaseIfDefaultPool(void); + /// For dealing with lost devices - recreate the resource if in the default pool + bool recreateIfDefaultPool(D3D11Device & device); - /// Get the D3D-specific vertex buffer - ID3D11Buffer * getD3DVertexBuffer(void) const; - }; + /// Get the D3D-specific vertex buffer + ID3D11Buffer * getD3DVertexBuffer(void) const; + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11Mappings.h b/RenderSystems/Direct3D11/include/OgreD3D11Mappings.h index 72a28981660..797a963d52a 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11Mappings.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11Mappings.h @@ -36,91 +36,91 @@ THE SOFTWARE. namespace Ogre { - class D3D11Mappings - { - public: + class D3D11Mappings + { + public: - /// enum identifying D3D11 filter usage type - enum eD3DFilterUsage - { - /// min filter - D3D_FUSAGE_MIN, - /// mag filter - D3D_FUSAGE_MAG, - /// mip filter - D3D_FUSAGE_MIP - }; + /// enum identifying D3D11 filter usage type + enum eD3DFilterUsage + { + /// min filter + D3D_FUSAGE_MIN, + /// mag filter + D3D_FUSAGE_MAG, + /// mip filter + D3D_FUSAGE_MIP + }; - /// return a D3D11 equivalent for a Ogre ShadeOptions value - //static DWORD get(ShadeOptions so); - /// return a D3D11 equivalent for a Ogre LightTypes value - //static D3DLIGHTTYPE get(Light::LightTypes lightType); - /// return a D3D11 equivalent for a Ogre TexCoordCalsMethod value - //static DWORD get(TexCoordCalcMethod m, const D3DCAPS9& caps); - /// return a D3D11 equivalent for a Ogre TextureAddressingMode value - static D3D11_TEXTURE_ADDRESS_MODE get(TextureUnitState::TextureAddressingMode tam); - /// return a D3D11 equivalent for a Ogre LayerBlendType value - static D3D11_BLEND get(LayerBlendType lbt); - /// return a D3D11 equivalent for a Ogre LayerBlendOperationEx value - //static DWORD get(LayerBlendOperationEx lbo, const D3DCAPS9& devCaps); - /// return a D3D11 equivalent for a Ogre LayerBlendSource value - //static DWORD get(LayerBlendSource lbs); - /// return a D3D11 equivalent for a Ogre SceneBlendFactor value - static D3D11_BLEND get(SceneBlendFactor sbf, bool forAlpha); - /// return a D3D11 equivalent for a Ogre SceneBlendOperation value - static D3D11_BLEND_OP get(SceneBlendOperation sbo); - /// return a D3D11 equivalent for a Ogre CompareFunction value - static D3D11_COMPARISON_FUNC get(CompareFunction cf); - /// return a D3D11 equivalent for a Ogre CillingMode value - static D3D11_CULL_MODE get(CullingMode cm, bool flip = false); - /// return a D3D11 equivalent for a Ogre FogMode value - //static D3DFOGMODE get(FogMode fm); - /// return a D3D11 equivalent for a Ogre PolygonMode value - static D3D11_FILL_MODE get(PolygonMode level); - /// return a D3D11 equivalent for a Ogre StencilOperation value - static D3D11_STENCIL_OP get(StencilOperation op, bool invert = false); - /// return a D3D11 state type for Ogre FilterType value - static DWORD get(FilterType ft); - static D3D11_FILTER get(const FilterOptions minification, const FilterOptions magnification, const FilterOptions mips, const bool comparison = false); - /// return the combination of D3DUSAGE values for Ogre buffer usage - static DWORD get(HardwareBuffer::Usage usage); - /// Get lock options - static D3D11_MAP get(HardwareBuffer::LockOptions options, HardwareBuffer::Usage usage); - /// Get index type - static DXGI_FORMAT get(HardwareIndexBuffer::IndexType itype); - static UINT getByteWidth(HardwareIndexBuffer::IndexType itype); - static DXGI_FORMAT getFormat(HardwareIndexBuffer::IndexType itype); - /// Get vertex data type - static DXGI_FORMAT get(VertexElementType vType); - /// Get vertex semantic - static LPCSTR get(VertexElementSemantic sem); - static VertexElementSemantic get(LPCSTR sem); - /// Get dx11 color - static void get(const ColourValue& inColour, float * outColour ); + /// return a D3D11 equivalent for a Ogre ShadeOptions value + //static DWORD get(ShadeOptions so); + /// return a D3D11 equivalent for a Ogre LightTypes value + //static D3DLIGHTTYPE get(Light::LightTypes lightType); + /// return a D3D11 equivalent for a Ogre TexCoordCalsMethod value + //static DWORD get(TexCoordCalcMethod m, const D3DCAPS9& caps); + /// return a D3D11 equivalent for a Ogre TextureAddressingMode value + static D3D11_TEXTURE_ADDRESS_MODE get(TextureUnitState::TextureAddressingMode tam); + /// return a D3D11 equivalent for a Ogre LayerBlendType value + static D3D11_BLEND get(LayerBlendType lbt); + /// return a D3D11 equivalent for a Ogre LayerBlendOperationEx value + //static DWORD get(LayerBlendOperationEx lbo, const D3DCAPS9& devCaps); + /// return a D3D11 equivalent for a Ogre LayerBlendSource value + //static DWORD get(LayerBlendSource lbs); + /// return a D3D11 equivalent for a Ogre SceneBlendFactor value + static D3D11_BLEND get(SceneBlendFactor sbf, bool forAlpha); + /// return a D3D11 equivalent for a Ogre SceneBlendOperation value + static D3D11_BLEND_OP get(SceneBlendOperation sbo); + /// return a D3D11 equivalent for a Ogre CompareFunction value + static D3D11_COMPARISON_FUNC get(CompareFunction cf); + /// return a D3D11 equivalent for a Ogre CillingMode value + static D3D11_CULL_MODE get(CullingMode cm, bool flip = false); + /// return a D3D11 equivalent for a Ogre FogMode value + //static D3DFOGMODE get(FogMode fm); + /// return a D3D11 equivalent for a Ogre PolygonMode value + static D3D11_FILL_MODE get(PolygonMode level); + /// return a D3D11 equivalent for a Ogre StencilOperation value + static D3D11_STENCIL_OP get(StencilOperation op, bool invert = false); + /// return a D3D11 state type for Ogre FilterType value + static DWORD get(FilterType ft); + static D3D11_FILTER get(const FilterOptions minification, const FilterOptions magnification, const FilterOptions mips, const bool comparison = false); + /// return the combination of D3DUSAGE values for Ogre buffer usage + static DWORD get(HardwareBuffer::Usage usage); + /// Get lock options + static D3D11_MAP get(HardwareBuffer::LockOptions options, HardwareBuffer::Usage usage); + /// Get index type + static DXGI_FORMAT get(HardwareIndexBuffer::IndexType itype); + static UINT getByteWidth(HardwareIndexBuffer::IndexType itype); + static DXGI_FORMAT getFormat(HardwareIndexBuffer::IndexType itype); + /// Get vertex data type + static DXGI_FORMAT get(VertexElementType vType); + /// Get vertex semantic + static LPCSTR get(VertexElementSemantic sem); + static VertexElementSemantic get(LPCSTR sem); + /// Get dx11 color + static void get(const ColourValue& inColour, float * outColour ); - /// utility method, convert D3D11 pixel format to Ogre pixel format - static PixelFormat _getPF(DXGI_FORMAT d3dPF); - /// utility method, convert Ogre pixel format to D3D11 pixel format - static DXGI_FORMAT _getPF(PixelFormat ogrePF); - // - static D3D11_USAGE _getUsage(HardwareBuffer::Usage mUsage); - static D3D11_USAGE _getUsage(int mUsage); - static UINT _getAccessFlags(HardwareBuffer::Usage mUsage); - static UINT _getAccessFlags(int mUsage); - static bool _isDynamic(HardwareBuffer::Usage mUsage); + /// utility method, convert D3D11 pixel format to Ogre pixel format + static PixelFormat _getPF(DXGI_FORMAT d3dPF); + /// utility method, convert Ogre pixel format to D3D11 pixel format + static DXGI_FORMAT _getPF(PixelFormat ogrePF); + // + static D3D11_USAGE _getUsage(HardwareBuffer::Usage mUsage); + static D3D11_USAGE _getUsage(int mUsage); + static UINT _getAccessFlags(HardwareBuffer::Usage mUsage); + static UINT _getAccessFlags(int mUsage); + static bool _isDynamic(HardwareBuffer::Usage mUsage); - static bool _isDynamic(int mUsage); + static bool _isDynamic(int mUsage); - /// utility method, find closest Ogre pixel format that D3D11 can support - static PixelFormat _getClosestSupportedPF(PixelFormat ogrePF); + /// utility method, find closest Ogre pixel format that D3D11 can support + static PixelFormat _getClosestSupportedPF(PixelFormat ogrePF); - static TextureType _getTexType(D3D11_SRV_DIMENSION type); + static TextureType _getTexType(D3D11_SRV_DIMENSION type); - static size_t _getSizeInBytes(PixelFormat pf, size_t xcount = 1, size_t ycount = 1); + static size_t _getSizeInBytes(PixelFormat pf, size_t xcount = 1, size_t ycount = 1); - static UINT _getTextureBindFlags(DXGI_FORMAT format, bool isdynamic); - static UINT _getTextureMiscFlags(UINT bindflags, TextureType textype, bool isdynamic); - }; + static UINT _getTextureBindFlags(DXGI_FORMAT format, bool isdynamic); + static UINT _getTextureMiscFlags(UINT bindflags, TextureType textype, bool isdynamic); + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11MultiRenderTarget.h b/RenderSystems/Direct3D11/include/OgreD3D11MultiRenderTarget.h index 20c0d9b9593..aa80f8beffb 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11MultiRenderTarget.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11MultiRenderTarget.h @@ -32,30 +32,30 @@ THE SOFTWARE. #include "OgreRenderTexture.h" namespace Ogre { - class D3D11MultiRenderTarget : public MultiRenderTarget - { - public: - D3D11MultiRenderTarget(const String &name); - ~D3D11MultiRenderTarget(); + class D3D11MultiRenderTarget : public MultiRenderTarget + { + public: + D3D11MultiRenderTarget(const String &name); + ~D3D11MultiRenderTarget(); - virtual void update(void); + virtual void update(void); - virtual void getCustomAttribute( const String& name, void *pData ); + virtual void getCustomAttribute( const String& name, void *pData ); - bool requiresTextureFlipping() const { return false; } - private: - D3D11HardwarePixelBuffer *targets[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - ID3D11RenderTargetView* mRenderTargetViews[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; // Store views to accelerate bind - uint mNumberOfViews; // Store number of views to accelerate bind + bool requiresTextureFlipping() const { return false; } + private: + D3D11HardwarePixelBuffer *targets[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + ID3D11RenderTargetView* mRenderTargetViews[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; // Store views to accelerate bind + uint mNumberOfViews; // Store number of views to accelerate bind - virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); - virtual void unbindSurfaceImpl(size_t attachment); + virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); + virtual void unbindSurfaceImpl(size_t attachment); - /** Check surfaces and update RenderTarget extent */ - void checkAndUpdate(); + /** Check surfaces and update RenderTarget extent */ + void checkAndUpdate(); - Ogre::RenderTexture* mRenderTargets[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - }; + Ogre::RenderTexture* mRenderTargets[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + }; }; #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11Plugin.h b/RenderSystems/Direct3D11/include/OgreD3D11Plugin.h index bd42c1ff18c..48d26fa69b1 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11Plugin.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11Plugin.h @@ -34,30 +34,30 @@ THE SOFTWARE. namespace Ogre { - /** Plugin instance for D3D11 Manager */ - class D3D11Plugin : public Plugin - { - public: - D3D11Plugin(); + /** Plugin instance for D3D11 Manager */ + class D3D11Plugin : public Plugin + { + public: + D3D11Plugin(); - /// @copydoc Plugin::getName - const String& getName() const; + /// @copydoc Plugin::getName + const String& getName() const; - /// @copydoc Plugin::install - void install(); + /// @copydoc Plugin::install + void install(); - /// @copydoc Plugin::initialise - void initialise(); + /// @copydoc Plugin::initialise + void initialise(); - /// @copydoc Plugin::shutdown - void shutdown(); + /// @copydoc Plugin::shutdown + void shutdown(); - /// @copydoc Plugin::uninstall - void uninstall(); - protected: - D3D11RenderSystem* mRenderSystem; - }; + /// @copydoc Plugin::uninstall + void uninstall(); + protected: + D3D11RenderSystem* mRenderSystem; + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11Prerequisites.h b/RenderSystems/Direct3D11/include/OgreD3D11Prerequisites.h index ef6d2ea9a35..11a40afea2d 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11Prerequisites.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11Prerequisites.h @@ -43,11 +43,11 @@ THE SOFTWARE. #if OGRE_THREAD_SUPPORT == 1 -#define D3D11_DEVICE_ACCESS_LOCK OGRE_LOCK_RECURSIVE_MUTEX(msDeviceAccessMutex); -#define D3D11_DEVICE_ACCESS_UNLOCK OGRE_UNLOCK_RECURSIVE_MUTEX(msDeviceAccessMutex); -#define D3D11_DEVICE_ACCESS_CRITICAL_SECTION OGRE_LOCK_MUTEX(msDeviceAccessMutex) +#define D3D11_DEVICE_ACCESS_LOCK OGRE_LOCK_RECURSIVE_MUTEX(msDeviceAccessMutex); +#define D3D11_DEVICE_ACCESS_UNLOCK OGRE_UNLOCK_RECURSIVE_MUTEX(msDeviceAccessMutex); +#define D3D11_DEVICE_ACCESS_CRITICAL_SECTION OGRE_LOCK_MUTEX(msDeviceAccessMutex) #else -#define D3D11_DEVICE_ACCESS_LOCK +#define D3D11_DEVICE_ACCESS_LOCK #define D3D11_DEVICE_ACCESS_UNLOCK #define D3D11_DEVICE_ACCESS_CRITICAL_SECTION #endif @@ -67,76 +67,76 @@ THE SOFTWARE. #endif #if (OGRE_PLATFORM == OGRE_PLATFORM_WINRT && OGRE_WINRT_TARGET_TYPE == PHONE) -# include +# include #else -# include -# include +# include +# include #endif namespace Ogre { - // typedefs to work with Direct3D 11 or 11.1 as appropriate + // typedefs to work with Direct3D 11 or 11.1 as appropriate #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - typedef ID3D11Device ID3D11DeviceN; - typedef ID3D11DeviceContext ID3D11DeviceContextN; - typedef ID3D11RasterizerState ID3D11RasterizerStateN; - typedef IDXGIFactory1 IDXGIFactoryN; - typedef IDXGIAdapter1 IDXGIAdapterN; - typedef IDXGIDevice1 IDXGIDeviceN; - typedef IDXGISwapChain IDXGISwapChainN; - typedef DXGI_SWAP_CHAIN_DESC DXGI_SWAP_CHAIN_DESC_N; + typedef ID3D11Device ID3D11DeviceN; + typedef ID3D11DeviceContext ID3D11DeviceContextN; + typedef ID3D11RasterizerState ID3D11RasterizerStateN; + typedef IDXGIFactory1 IDXGIFactoryN; + typedef IDXGIAdapter1 IDXGIAdapterN; + typedef IDXGIDevice1 IDXGIDeviceN; + typedef IDXGISwapChain IDXGISwapChainN; + typedef DXGI_SWAP_CHAIN_DESC DXGI_SWAP_CHAIN_DESC_N; #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - typedef ID3D11Device1 ID3D11DeviceN; - typedef ID3D11DeviceContext1 ID3D11DeviceContextN; - typedef ID3D11RasterizerState1 ID3D11RasterizerStateN; - typedef IDXGIFactory2 IDXGIFactoryN; - typedef IDXGIAdapter1 IDXGIAdapterN; // we don`t need IDXGIAdapter2 functionality - typedef IDXGIDevice2 IDXGIDeviceN; - typedef IDXGISwapChain1 IDXGISwapChainN; - typedef DXGI_SWAP_CHAIN_DESC1 DXGI_SWAP_CHAIN_DESC_N; + typedef ID3D11Device1 ID3D11DeviceN; + typedef ID3D11DeviceContext1 ID3D11DeviceContextN; + typedef ID3D11RasterizerState1 ID3D11RasterizerStateN; + typedef IDXGIFactory2 IDXGIFactoryN; + typedef IDXGIAdapter1 IDXGIAdapterN; // we don`t need IDXGIAdapter2 functionality + typedef IDXGIDevice2 IDXGIDeviceN; + typedef IDXGISwapChain1 IDXGISwapChainN; + typedef DXGI_SWAP_CHAIN_DESC1 DXGI_SWAP_CHAIN_DESC_N; #endif - // Predefine classes - class D3D11RenderSystem; - class D3D11RenderWindowBase; - class D3D11Texture; - class D3D11TextureManager; - class D3D11DepthBuffer; - class D3D11Driver; - class D3D11DriverList; - class D3D11VideoMode; - class D3D11VideoModeList; - class D3D11GpuProgram; - class D3D11GpuProgramManager; - class D3D11HardwareBufferManager; - class D3D11HardwareIndexBuffer; - class D3D11HLSLProgramFactory; - class D3D11HLSLProgram; - class D3D11VertexDeclaration; - class D3D11Device; - class D3D11HardwareBuffer; - class D3D11HardwarePixelBuffer; + // Predefine classes + class D3D11RenderSystem; + class D3D11RenderWindowBase; + class D3D11Texture; + class D3D11TextureManager; + class D3D11DepthBuffer; + class D3D11Driver; + class D3D11DriverList; + class D3D11VideoMode; + class D3D11VideoModeList; + class D3D11GpuProgram; + class D3D11GpuProgramManager; + class D3D11HardwareBufferManager; + class D3D11HardwareIndexBuffer; + class D3D11HLSLProgramFactory; + class D3D11HLSLProgram; + class D3D11VertexDeclaration; + class D3D11Device; + class D3D11HardwareBuffer; + class D3D11HardwarePixelBuffer; typedef SharedPtr D3D11GpuProgramPtr; typedef SharedPtr D3D11HLSLProgramPtr; typedef SharedPtr D3D11TexturePtr; - //------------------------------------------- - // Windows setttings - //------------------------------------------- + //------------------------------------------- + // Windows setttings + //------------------------------------------- #if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && !defined(OGRE_STATIC_LIB) -# ifdef OGRED3DENGINEDLL_EXPORTS -# define _OgreD3D11Export __declspec(dllexport) -# else +# ifdef OGRED3DENGINEDLL_EXPORTS +# define _OgreD3D11Export __declspec(dllexport) +# else # if defined( __MINGW32__ ) # define _OgreD3D11Export # else -# define _OgreD3D11Export __declspec(dllimport) +# define _OgreD3D11Export __declspec(dllimport) # endif -# endif +# endif #else -# define _OgreD3D11Export -#endif // OGRE_WIN32 +# define _OgreD3D11Export +#endif // OGRE_WIN32 } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11RenderSystem.h b/RenderSystems/Direct3D11/include/OgreD3D11RenderSystem.h index 16baf1ea58d..3df0f24b007 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11RenderSystem.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11RenderSystem.h @@ -37,321 +37,321 @@ namespace Ogre { #define MAX_LIGHTS 8 - class D3D11DriverList; - class D3D11Driver; - - /** - Implementation of DirectX11 as a rendering system. - */ - class D3D11RenderSystem : public RenderSystem - { - private: - - // an enum to define the driver type of d3d11 - enum OGRE_D3D11_DRIVER_TYPE - { - DT_HARDWARE, // GPU based - DT_SOFTWARE, // microsoft original (slow) software driver - DT_WARP // microsoft new (faster) software driver - (Windows Advanced Rasterization Platform) - http://msdn.microsoft.com/en-us/library/dd285359.aspx - - }; - - OGRE_D3D11_DRIVER_TYPE mDriverType; // d3d11 driver type - D3D_FEATURE_LEVEL mFeatureLevel; + class D3D11DriverList; + class D3D11Driver; + + /** + Implementation of DirectX11 as a rendering system. + */ + class D3D11RenderSystem : public RenderSystem + { + private: + + // an enum to define the driver type of d3d11 + enum OGRE_D3D11_DRIVER_TYPE + { + DT_HARDWARE, // GPU based + DT_SOFTWARE, // microsoft original (slow) software driver + DT_WARP // microsoft new (faster) software driver - (Windows Advanced Rasterization Platform) - http://msdn.microsoft.com/en-us/library/dd285359.aspx + + }; + + OGRE_D3D11_DRIVER_TYPE mDriverType; // d3d11 driver type + D3D_FEATURE_LEVEL mFeatureLevel; D3D_FEATURE_LEVEL mMinRequestedFeatureLevel; D3D_FEATURE_LEVEL mMaxRequestedFeatureLevel; - /// Direct3D - //int mpD3D; - /// Direct3D rendering device - D3D11Device mDevice; - - // Stored options - ConfigOptionMap mOptions; - - /// instance - HINSTANCE mhInstance; - - /// List of D3D drivers installed (video cards) - D3D11DriverList* mDriverList; - /// Currently active driver - D3D11Driver* mActiveD3DDriver; - /// NVPerfHUD allowed? - bool mUseNVPerfHUD; - /// Per-stage constant support? (not in main caps since D3D specific & minor) - bool mPerStageConstantSupport; - - /// structure holding texture unit settings for every stage - - - D3D11DriverList* getDirect3DDrivers(void); - void refreshD3DSettings(void); + /// Direct3D + //int mpD3D; + /// Direct3D rendering device + D3D11Device mDevice; + + // Stored options + ConfigOptionMap mOptions; + + /// instance + HINSTANCE mhInstance; + + /// List of D3D drivers installed (video cards) + D3D11DriverList* mDriverList; + /// Currently active driver + D3D11Driver* mActiveD3DDriver; + /// NVPerfHUD allowed? + bool mUseNVPerfHUD; + /// Per-stage constant support? (not in main caps since D3D specific & minor) + bool mPerStageConstantSupport; + + /// structure holding texture unit settings for every stage + + + D3D11DriverList* getDirect3DDrivers(void); + void refreshD3DSettings(void); void refreshFSAAOptions(void); - void freeDevice(void); + void freeDevice(void); -// inline bool compareDecls( D3DVERTEXELEMENT9* pDecl1, D3DVERTEXELEMENT9* pDecl2, size_t size ); +// inline bool compareDecls( D3DVERTEXELEMENT9* pDecl1, D3DVERTEXELEMENT9* pDecl2, size_t size ); - void initInputDevices(void); - void processInputDevices(void); - - /// return anisotropy level - DWORD _getCurrentAnisotropy(size_t unit); - /// check if a FSAA is supported - bool _checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format); - - D3D11HardwareBufferManager* mHardwareBufferManager; - D3D11GpuProgramManager* mGpuProgramManager; + void initInputDevices(void); + void processInputDevices(void); + + /// return anisotropy level + DWORD _getCurrentAnisotropy(size_t unit); + /// check if a FSAA is supported + bool _checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format); + + D3D11HardwareBufferManager* mHardwareBufferManager; + D3D11GpuProgramManager* mGpuProgramManager; D3D11HLSLProgramFactory* mHLSLProgramFactory; - size_t mLastVertexSourceCount; + size_t mLastVertexSourceCount; - /// Internal method for populating the capabilities structure - RenderSystemCapabilities* createRenderSystemCapabilities() const; - /** See RenderSystem definition */ - void initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary); + /// Internal method for populating the capabilities structure + RenderSystemCapabilities* createRenderSystemCapabilities() const; + /** See RenderSystem definition */ + void initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary); void convertVertexShaderCaps(RenderSystemCapabilities* rsc) const; - void convertPixelShaderCaps(RenderSystemCapabilities* rsc) const; - void convertGeometryShaderCaps(RenderSystemCapabilities* rsc) const; - void convertHullShaderCaps(RenderSystemCapabilities* rsc) const; - void convertDomainShaderCaps(RenderSystemCapabilities* rsc) const; - void convertComputeShaderCaps(RenderSystemCapabilities* rsc) const; + void convertPixelShaderCaps(RenderSystemCapabilities* rsc) const; + void convertGeometryShaderCaps(RenderSystemCapabilities* rsc) const; + void convertHullShaderCaps(RenderSystemCapabilities* rsc) const; + void convertDomainShaderCaps(RenderSystemCapabilities* rsc) const; + void convertComputeShaderCaps(RenderSystemCapabilities* rsc) const; - bool checkVertexTextureFormats(void); + bool checkVertexTextureFormats(void); void detachRenderTargetImpl(const String& name); - CompareFunction mSceneAlphaRejectFunc; // should be merged with - mBlendDesc - unsigned char mSceneAlphaRejectValue; // should be merged with - mBlendDesc - bool mSceneAlphaToCoverage; - - D3D11_BLEND_DESC mBlendDesc; - - D3D11_RASTERIZER_DESC mRasterizerDesc; - - UINT mStencilRef; - D3D11_DEPTH_STENCIL_DESC mDepthStencilDesc; - - PolygonMode mPolygonMode; - - FilterOptions FilterMinification[OGRE_MAX_TEXTURE_LAYERS]; - FilterOptions FilterMagnification[OGRE_MAX_TEXTURE_LAYERS]; - FilterOptions FilterMips[OGRE_MAX_TEXTURE_LAYERS]; - bool CompareEnabled; - - D3D11_RECT mScissorRect; - - bool mReadBackAsTexture; - - D3D11HLSLProgram* mBoundVertexProgram; - D3D11HLSLProgram* mBoundFragmentProgram; - D3D11HLSLProgram* mBoundGeometryProgram; - D3D11HLSLProgram* mBoundTessellationHullProgram; - D3D11HLSLProgram* mBoundTessellationDomainProgram; - D3D11HLSLProgram* mBoundComputeProgram; - - TextureUnitState::BindingType mBindingType; - - ID3D11ShaderResourceView* mDSTResView; - ID3D11BlendState * mBoundBlendState; - ID3D11RasterizerState * mBoundRasterizer; - ID3D11DepthStencilState * mBoundDepthStencilState; - ID3D11SamplerState * mBoundSamplerStates[OGRE_MAX_TEXTURE_LAYERS]; - size_t mBoundSamplerStatesCount; - - ID3D11ShaderResourceView * mBoundTextures[OGRE_MAX_TEXTURE_LAYERS]; - size_t mBoundTexturesCount; - - // List of class instances per shader stage - ID3D11ClassInstance* mClassInstances[6][8]; - - // Number of class instances per shader stage - UINT mNumClassInstances[6]; - - // Store created shader subroutines, to prevent creation and destruction every frame - typedef std::map ClassInstanceMap; - typedef std::map::iterator ClassInstanceIterator; - ClassInstanceMap mInstanceMap; - - /// structure holding texture unit settings for every stage - struct sD3DTextureStageDesc - { - /// the type of the texture - //D3D11Mappings::eD3DTexType texType; - TextureType type; - /// which texCoordIndex to use - size_t coordIndex; - /// type of auto tex. calc. used - TexCoordCalcMethod autoTexCoordType; - /// Frustum, used if the above is projection - const Frustum *frustum; - - LayerBlendModeEx layerBlendMode; - - /// texture - ID3D11ShaderResourceView *pTex; - D3D11_SAMPLER_DESC samplerDesc; - D3D11_SAMPLER_DESC currentSamplerDesc; - //ID3D11SamplerState * pSampler; - bool used; - } mTexStageDesc[OGRE_MAX_TEXTURE_LAYERS]; - - - // What follows is a set of duplicated lists just to make it - // easier to deal with lost devices - - /// Primary window, the one used to create the device - D3D11RenderWindowBase* mPrimaryWindow; - - typedef vector::type SecondaryWindowList; - // List of additional windows after the first (swap chains) - SecondaryWindowList mSecondaryWindows; - - bool mBasicStatesInitialised; - - bool mRenderSystemWasInited; - - IDXGIFactoryN* mpDXGIFactory; - protected: - void setClipPlanesImpl(const PlaneList& clipPlanes); - - /** + CompareFunction mSceneAlphaRejectFunc; // should be merged with - mBlendDesc + unsigned char mSceneAlphaRejectValue; // should be merged with - mBlendDesc + bool mSceneAlphaToCoverage; + + D3D11_BLEND_DESC mBlendDesc; + + D3D11_RASTERIZER_DESC mRasterizerDesc; + + UINT mStencilRef; + D3D11_DEPTH_STENCIL_DESC mDepthStencilDesc; + + PolygonMode mPolygonMode; + + FilterOptions FilterMinification[OGRE_MAX_TEXTURE_LAYERS]; + FilterOptions FilterMagnification[OGRE_MAX_TEXTURE_LAYERS]; + FilterOptions FilterMips[OGRE_MAX_TEXTURE_LAYERS]; + bool CompareEnabled; + + D3D11_RECT mScissorRect; + + bool mReadBackAsTexture; + + D3D11HLSLProgram* mBoundVertexProgram; + D3D11HLSLProgram* mBoundFragmentProgram; + D3D11HLSLProgram* mBoundGeometryProgram; + D3D11HLSLProgram* mBoundTessellationHullProgram; + D3D11HLSLProgram* mBoundTessellationDomainProgram; + D3D11HLSLProgram* mBoundComputeProgram; + + TextureUnitState::BindingType mBindingType; + + ID3D11ShaderResourceView* mDSTResView; + ID3D11BlendState * mBoundBlendState; + ID3D11RasterizerState * mBoundRasterizer; + ID3D11DepthStencilState * mBoundDepthStencilState; + ID3D11SamplerState * mBoundSamplerStates[OGRE_MAX_TEXTURE_LAYERS]; + size_t mBoundSamplerStatesCount; + + ID3D11ShaderResourceView * mBoundTextures[OGRE_MAX_TEXTURE_LAYERS]; + size_t mBoundTexturesCount; + + // List of class instances per shader stage + ID3D11ClassInstance* mClassInstances[6][8]; + + // Number of class instances per shader stage + UINT mNumClassInstances[6]; + + // Store created shader subroutines, to prevent creation and destruction every frame + typedef std::map ClassInstanceMap; + typedef std::map::iterator ClassInstanceIterator; + ClassInstanceMap mInstanceMap; + + /// structure holding texture unit settings for every stage + struct sD3DTextureStageDesc + { + /// the type of the texture + //D3D11Mappings::eD3DTexType texType; + TextureType type; + /// which texCoordIndex to use + size_t coordIndex; + /// type of auto tex. calc. used + TexCoordCalcMethod autoTexCoordType; + /// Frustum, used if the above is projection + const Frustum *frustum; + + LayerBlendModeEx layerBlendMode; + + /// texture + ID3D11ShaderResourceView *pTex; + D3D11_SAMPLER_DESC samplerDesc; + D3D11_SAMPLER_DESC currentSamplerDesc; + //ID3D11SamplerState * pSampler; + bool used; + } mTexStageDesc[OGRE_MAX_TEXTURE_LAYERS]; + + + // What follows is a set of duplicated lists just to make it + // easier to deal with lost devices + + /// Primary window, the one used to create the device + D3D11RenderWindowBase* mPrimaryWindow; + + typedef vector::type SecondaryWindowList; + // List of additional windows after the first (swap chains) + SecondaryWindowList mSecondaryWindows; + + bool mBasicStatesInitialised; + + bool mRenderSystemWasInited; + + IDXGIFactoryN* mpDXGIFactory; + protected: + void setClipPlanesImpl(const PlaneList& clipPlanes); + + /** * With DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL flag render target views are unbound - * from us each Present(), and we need the way to reestablish connection. + * from us each Present(), and we need the way to reestablish connection. */ - void _setRenderTargetViews(); - - public: - // constructor - D3D11RenderSystem( ); - - // destructor - ~D3D11RenderSystem(); - - - void initRenderSystem(); - - virtual void initConfigOptions(void); - - // Overridden RenderSystem functions - ConfigOptionMap& getConfigOptions(void); - String validateConfigOptions(void); - RenderWindow* _initialise( bool autoCreateWindow, const String& windowTitle = "OGRE Render Window" ); - /// @copydoc RenderSystem::_createRenderWindow - RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0); - - /// @copydoc RenderSystem::createRenderTexture - RenderTexture * createRenderTexture( const String & name, unsigned int width, unsigned int height, - TextureType texType = TEX_TYPE_2D, PixelFormat internalFormat = PF_X8R8G8B8, - const NameValuePairList *miscParams = 0 ); - - /// @copydoc RenderSystem::createMultiRenderTarget - virtual MultiRenderTarget * createMultiRenderTarget(const String & name); - - virtual DepthBuffer* _createDepthBufferFor( RenderTarget *renderTarget ); - - /** - * This function is meant to add Depth Buffers to the pool that aren't released when the DepthBuffer - * is deleted. This is specially useful to put the Depth Buffer created along with the window's - * back buffer into the pool. All depth buffers introduced with this method go to POOL_DEFAULT - */ - DepthBuffer* _addManualDepthBuffer( ID3D11DepthStencilView *depthSurface, - uint32 width, uint32 height, uint32 fsaa, uint32 fsaaQuality ); - - /// Reverts _addManualDepthBuffer actions - void _removeManualDepthBuffer(DepthBuffer *depthBuffer); - /// @copydoc RenderSystem::detachRenderTarget - virtual RenderTarget * detachRenderTarget(const String &name); - - const String& getName(void) const; - void getCustomAttribute(const String& name, void* pData); - // Low-level overridden members - void setConfigOption( const String &name, const String &value ); - void reinitialise(); - void shutdown(); - void setAmbientLight( float r, float g, float b ); - void setShadingType( ShadeOptions so ); - void setLightingEnabled( bool enabled ); - void destroyRenderTarget(const String& name); - VertexElementType getColourVertexElementType(void) const; - void setStencilCheckEnabled(bool enabled); + void _setRenderTargetViews(); + + public: + // constructor + D3D11RenderSystem( ); + + // destructor + ~D3D11RenderSystem(); + + + void initRenderSystem(); + + virtual void initConfigOptions(void); + + // Overridden RenderSystem functions + ConfigOptionMap& getConfigOptions(void); + String validateConfigOptions(void); + RenderWindow* _initialise( bool autoCreateWindow, const String& windowTitle = "OGRE Render Window" ); + /// @copydoc RenderSystem::_createRenderWindow + RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0); + + /// @copydoc RenderSystem::createRenderTexture + RenderTexture * createRenderTexture( const String & name, unsigned int width, unsigned int height, + TextureType texType = TEX_TYPE_2D, PixelFormat internalFormat = PF_X8R8G8B8, + const NameValuePairList *miscParams = 0 ); + + /// @copydoc RenderSystem::createMultiRenderTarget + virtual MultiRenderTarget * createMultiRenderTarget(const String & name); + + virtual DepthBuffer* _createDepthBufferFor( RenderTarget *renderTarget ); + + /** + * This function is meant to add Depth Buffers to the pool that aren't released when the DepthBuffer + * is deleted. This is specially useful to put the Depth Buffer created along with the window's + * back buffer into the pool. All depth buffers introduced with this method go to POOL_DEFAULT + */ + DepthBuffer* _addManualDepthBuffer( ID3D11DepthStencilView *depthSurface, + uint32 width, uint32 height, uint32 fsaa, uint32 fsaaQuality ); + + /// Reverts _addManualDepthBuffer actions + void _removeManualDepthBuffer(DepthBuffer *depthBuffer); + /// @copydoc RenderSystem::detachRenderTarget + virtual RenderTarget * detachRenderTarget(const String &name); + + const String& getName(void) const; + void getCustomAttribute(const String& name, void* pData); + // Low-level overridden members + void setConfigOption( const String &name, const String &value ); + void reinitialise(); + void shutdown(); + void setAmbientLight( float r, float g, float b ); + void setShadingType( ShadeOptions so ); + void setLightingEnabled( bool enabled ); + void destroyRenderTarget(const String& name); + VertexElementType getColourVertexElementType(void) const; + void setStencilCheckEnabled(bool enabled); void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, uint32 refValue = 0, uint32 compareMask = 0xFFFFFFFF, uint32 writeMask = 0xFFFFFFFF, StencilOperation stencilFailOp = SOP_KEEP, StencilOperation depthFailOp = SOP_KEEP, StencilOperation passOp = SOP_KEEP, bool twoSidedOperation = false, - bool readBackAsTexture = false); + bool readBackAsTexture = false); void setNormaliseNormals(bool normalise); - virtual String getErrorDescription(long errorNumber) const; + virtual String getErrorDescription(long errorNumber) const; - // Low-level overridden members, mainly for internal use - D3D11HLSLProgram* _getBoundVertexProgram() const; - D3D11HLSLProgram* _getBoundFragmentProgram() const; - D3D11HLSLProgram* _getBoundGeometryProgram() const; - D3D11HLSLProgram* _getBoundTessellationHullProgram() const; - D3D11HLSLProgram* _getBoundTessellationDomainProgram() const; - D3D11HLSLProgram* _getBoundComputeProgram() const; + // Low-level overridden members, mainly for internal use + D3D11HLSLProgram* _getBoundVertexProgram() const; + D3D11HLSLProgram* _getBoundFragmentProgram() const; + D3D11HLSLProgram* _getBoundGeometryProgram() const; + D3D11HLSLProgram* _getBoundTessellationHullProgram() const; + D3D11HLSLProgram* _getBoundTessellationDomainProgram() const; + D3D11HLSLProgram* _getBoundComputeProgram() const; void _useLights(const LightList& lights, unsigned short limit); - void _setWorldMatrix( const Matrix4 &m ); - void _setViewMatrix( const Matrix4 &m ); - void _setProjectionMatrix( const Matrix4 &m ); - void _setSurfaceParams( const ColourValue &ambient, const ColourValue &diffuse, const ColourValue &specular, const ColourValue &emissive, Real shininess, TrackVertexColourType tracking ); - void _setPointSpritesEnabled(bool enabled); - void _setPointParameters(Real size, bool attenuationEnabled, - Real constant, Real linear, Real quadratic, Real minSize, Real maxSize); - void _setTexture(size_t unit, bool enabled, const TexturePtr &texPtr); - void _setBindingType(TextureUnitState::BindingType bindingType); - void _setVertexTexture(size_t unit, const TexturePtr& tex); - void _setGeometryTexture(size_t unit, const TexturePtr& tex); - void _setComputeTexture(size_t unit, const TexturePtr& tex); - void _setTesselationHullTexture(size_t unit, const TexturePtr& tex); - void _setTesselationDomainTexture(size_t unit, const TexturePtr& tex); - void _disableTextureUnit(size_t texUnit); - void _setTextureCoordSet( size_t unit, size_t index ); + void _setWorldMatrix( const Matrix4 &m ); + void _setViewMatrix( const Matrix4 &m ); + void _setProjectionMatrix( const Matrix4 &m ); + void _setSurfaceParams( const ColourValue &ambient, const ColourValue &diffuse, const ColourValue &specular, const ColourValue &emissive, Real shininess, TrackVertexColourType tracking ); + void _setPointSpritesEnabled(bool enabled); + void _setPointParameters(Real size, bool attenuationEnabled, + Real constant, Real linear, Real quadratic, Real minSize, Real maxSize); + void _setTexture(size_t unit, bool enabled, const TexturePtr &texPtr); + void _setBindingType(TextureUnitState::BindingType bindingType); + void _setVertexTexture(size_t unit, const TexturePtr& tex); + void _setGeometryTexture(size_t unit, const TexturePtr& tex); + void _setComputeTexture(size_t unit, const TexturePtr& tex); + void _setTesselationHullTexture(size_t unit, const TexturePtr& tex); + void _setTesselationDomainTexture(size_t unit, const TexturePtr& tex); + void _disableTextureUnit(size_t texUnit); + void _setTextureCoordSet( size_t unit, size_t index ); void _setTextureCoordCalculation(size_t unit, TexCoordCalcMethod m, const Frustum* frustum = 0); - void _setTextureBlendMode( size_t unit, const LayerBlendModeEx& bm ); + void _setTextureBlendMode( size_t unit, const LayerBlendModeEx& bm ); void _setTextureAddressingMode(size_t stage, const TextureUnitState::UVWAddressingMode& uvw); void _setTextureBorderColour(size_t stage, const ColourValue& colour); - void _setTextureMipmapBias(size_t unit, float bias); - void _setTextureMatrix( size_t unit, const Matrix4 &xform ); - void _setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op = SBO_ADD); - void _setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, - SceneBlendFactor destFactorAlpha, SceneBlendOperation op = SBO_ADD, SceneBlendOperation alphaOp = SBO_ADD); - void _setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ); - void _setViewport( Viewport *vp ); - void _beginFrame(void); - void _endFrame(void); - void _setCullingMode( CullingMode mode ); - void _setDepthBufferParams( bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL ); - void _setDepthBufferCheckEnabled( bool enabled = true ); - bool _getDepthBufferCheckEnabled( void ); - void _setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha); - void _setDepthBufferWriteEnabled(bool enabled = true); - void _setDepthBufferFunction( CompareFunction func = CMPF_LESS_EQUAL ); - void _setDepthBias(float constantBias, float slopeScaleBias); - void _setFog( FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 1.0, Real linearStart = 0.0, Real linearEnd = 1.0 ); - void _convertProjectionMatrix(const Matrix4& matrix, + void _setTextureMipmapBias(size_t unit, float bias); + void _setTextureMatrix( size_t unit, const Matrix4 &xform ); + void _setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op = SBO_ADD); + void _setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, + SceneBlendFactor destFactorAlpha, SceneBlendOperation op = SBO_ADD, SceneBlendOperation alphaOp = SBO_ADD); + void _setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ); + void _setViewport( Viewport *vp ); + void _beginFrame(void); + void _endFrame(void); + void _setCullingMode( CullingMode mode ); + void _setDepthBufferParams( bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL ); + void _setDepthBufferCheckEnabled( bool enabled = true ); + bool _getDepthBufferCheckEnabled( void ); + void _setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha); + void _setDepthBufferWriteEnabled(bool enabled = true); + void _setDepthBufferFunction( CompareFunction func = CMPF_LESS_EQUAL ); + void _setDepthBias(float constantBias, float slopeScaleBias); + void _setFog( FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 1.0, Real linearStart = 0.0, Real linearEnd = 1.0 ); + void _convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram = false); - void _makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, + void _makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram = false); - void _makeProjectionMatrix(Real left, Real right, Real bottom, Real top, Real nearPlane, + void _makeProjectionMatrix(Real left, Real right, Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram = false); - void _makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, + void _makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram = false); void _applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane, bool forGpuProgram); - void _setPolygonMode(PolygonMode level); + void _setPolygonMode(PolygonMode level); void _setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions filter); - void _setTextureUnitCompareFunction(size_t unit, CompareFunction function); - void _setTextureUnitCompareEnabled(size_t unit, bool compare); - void _setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy); - void setVertexDeclaration(VertexDeclaration* decl); - void setVertexDeclaration(VertexDeclaration* decl, VertexBufferBinding* binding); - void setVertexBufferBinding(VertexBufferBinding* binding); - void _renderUsingReadBackAsTexture(unsigned int passNr, Ogre::String variableName,unsigned int StartSlot); + void _setTextureUnitCompareFunction(size_t unit, CompareFunction function); + void _setTextureUnitCompareEnabled(size_t unit, bool compare); + void _setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy); + void setVertexDeclaration(VertexDeclaration* decl); + void setVertexDeclaration(VertexDeclaration* decl, VertexBufferBinding* binding); + void setVertexBufferBinding(VertexBufferBinding* binding); + void _renderUsingReadBackAsTexture(unsigned int passNr, Ogre::String variableName,unsigned int StartSlot); void _render(const RenderOperation& op); /** See RenderSystem @@ -374,46 +374,46 @@ namespace Ogre void clearFrameBuffer(unsigned int buffers, const ColourValue& colour = ColourValue::Black, Real depth = 1.0f, unsigned short stencil = 0); - void setClipPlane (ushort index, Real A, Real B, Real C, Real D); - void enableClipPlane (ushort index, bool enable); + void setClipPlane (ushort index, Real A, Real B, Real C, Real D); + void enableClipPlane (ushort index, bool enable); HardwareOcclusionQuery* createHardwareOcclusionQuery(void); Real getHorizontalTexelOffset(void); Real getVerticalTexelOffset(void); Real getMinimumDepthInputValue(void); Real getMaximumDepthInputValue(void); - void registerThread(); - void unregisterThread(); - void preExtraThreadsStarted(); - void postExtraThreadsStarted(); + void registerThread(); + void unregisterThread(); + void preExtraThreadsStarted(); + void postExtraThreadsStarted(); - /** + /** * Set current render target to target, enabling its GL context if needed */ - void _setRenderTarget(RenderTarget *target); + void _setRenderTarget(RenderTarget *target); /** Check whether or not filtering is supported for the precise texture format requested with the given usage options. */ bool _checkTextureFilteringSupported(TextureType ttype, PixelFormat format, int usage); - void determineFSAASettings(uint fsaa, const String& fsaaHint, DXGI_FORMAT format, DXGI_SAMPLE_DESC* outFSAASettings); + void determineFSAASettings(uint fsaa, const String& fsaaHint, DXGI_FORMAT format, DXGI_SAMPLE_DESC* outFSAASettings); - /// @copydoc RenderSystem::getDisplayMonitorCount - unsigned int getDisplayMonitorCount() const {return 1;} //todo + /// @copydoc RenderSystem::getDisplayMonitorCount + unsigned int getDisplayMonitorCount() const {return 1;} //todo - /// @copydoc RenderSystem::hasAnisotropicMipMapFilter - virtual bool hasAnisotropicMipMapFilter() const { return true; } + /// @copydoc RenderSystem::hasAnisotropicMipMapFilter + virtual bool hasAnisotropicMipMapFilter() const { return true; } - D3D11Device &_getDevice() { return mDevice; } - - + D3D11Device &_getDevice() { return mDevice; } + + D3D_FEATURE_LEVEL _getFeatureLevel() const { return mFeatureLevel; } - /// @copydoc RenderSystem::setSubroutine - void setSubroutine(GpuProgramType gptype, unsigned int slotIndex, const String& subroutineName); - - /// @copydoc RenderSystem::setSubroutineName - void setSubroutine(GpuProgramType gptype, const String& slotName, const String& subroutineName); + /// @copydoc RenderSystem::setSubroutine + void setSubroutine(GpuProgramType gptype, unsigned int slotIndex, const String& subroutineName); + + /// @copydoc RenderSystem::setSubroutineName + void setSubroutine(GpuProgramType gptype, const String& slotName, const String& subroutineName); /// @copydoc RenderSystem::beginProfileEvent virtual void beginProfileEvent( const String &eventName ); diff --git a/RenderSystems/Direct3D11/include/OgreD3D11RenderToVertexBuffer.h b/RenderSystems/Direct3D11/include/OgreD3D11RenderToVertexBuffer.h index bc0b37de761..0a3c9fef6f6 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11RenderToVertexBuffer.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11RenderToVertexBuffer.h @@ -32,40 +32,40 @@ THE SOFTWARE. #include "OgreD3D11Prerequisites.h" namespace Ogre { - /** - An object which renders geometry to a vertex. - @remarks - This is especially useful together with geometry shaders, as you can - render procedural geometry which will get saved to a vertex buffer for - reuse later, without regenerating it again. You can also create shaders - that run on previous results of those shaders, creating stateful - shaders. - */ - class D3D11RenderToVertexBuffer : - public RenderToVertexBuffer - { - public: - D3D11RenderToVertexBuffer(D3D11Device & device, D3D11HardwareBufferManagerBase * bufManager); - virtual ~D3D11RenderToVertexBuffer(void); + /** + An object which renders geometry to a vertex. + @remarks + This is especially useful together with geometry shaders, as you can + render procedural geometry which will get saved to a vertex buffer for + reuse later, without regenerating it again. You can also create shaders + that run on previous results of those shaders, creating stateful + shaders. + */ + class D3D11RenderToVertexBuffer : + public RenderToVertexBuffer + { + public: + D3D11RenderToVertexBuffer(D3D11Device & device, D3D11HardwareBufferManagerBase * bufManager); + virtual ~D3D11RenderToVertexBuffer(void); - /** - Get the render operation for this buffer - */ - virtual void getRenderOperation(RenderOperation& op); + /** + Get the render operation for this buffer + */ + virtual void getRenderOperation(RenderOperation& op); - /** - Update the contents of this vertex buffer by rendering - */ - virtual void update(SceneManager* sceneMgr); - void reallocateBuffer(size_t index); - protected: - void setupGeometryShaderLinkageToStreamOut(Pass* pass); + /** + Update the contents of this vertex buffer by rendering + */ + virtual void update(SceneManager* sceneMgr); + void reallocateBuffer(size_t index); + protected: + void setupGeometryShaderLinkageToStreamOut(Pass* pass); - ID3D11GeometryShader* mpGeometryShader; + ID3D11GeometryShader* mpGeometryShader; D3D11Device & mDevice; - HardwareVertexBufferSharedPtr mVertexBuffers[2]; - size_t mFrontBufferIndex; - D3D11HardwareBufferManagerBase * mBufManager; - }; + HardwareVertexBufferSharedPtr mVertexBuffers[2]; + size_t mFrontBufferIndex; + D3D11HardwareBufferManagerBase * mBufManager; + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11RenderWindow.h b/RenderSystems/Direct3D11/include/OgreD3D11RenderWindow.h index 0d6d1fb8d98..14e7538540b 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11RenderWindow.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11RenderWindow.h @@ -44,177 +44,177 @@ THE SOFTWARE. namespace Ogre { - class D3D11RenderWindowBase - : public RenderWindow - { - public: - D3D11RenderWindowBase(D3D11Device& device, IDXGIFactoryN* pDXGIFactory); - ~D3D11RenderWindowBase(); - virtual void create(const String& name, unsigned width, unsigned height, bool fullScreen, const NameValuePairList *miscParams); - virtual void destroy(void); - - void reposition(int left, int top) {} - void resize(unsigned int width, unsigned int height) {} - - bool isClosed() const { return mClosed; } - bool isHidden() const { return mHidden; } - - void getCustomAttribute( const String& name, void* pData ); - /** Overridden - see RenderTarget. - */ - virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); - bool requiresTextureFlipping() const { return false; } - - protected: - void _createSizeDependedD3DResources(); // assumes mpBackBuffer is already initialized - void _destroySizeDependedD3DResources(); - - IDXGIDeviceN* _queryDxgiDevice(); // release after use - - // just check if the multisampling requested is supported by the device - bool _checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format); - - void _updateViewportsDimensions(); - - protected: - D3D11Device & mDevice; // D3D11 driver - IDXGIFactoryN* mpDXGIFactory; - bool mIsExternal; // window not created by Ogre - bool mSizing; - bool mClosed; - bool mHidden; - - // ------------------------------------------------------- - // DirectX-specific - // ------------------------------------------------------- - DXGI_SAMPLE_DESC mFSAAType; - UINT mDisplayFrequency; - bool mVSync; - unsigned int mVSyncInterval; - - // Window size depended resources - must be released before swapchain resize and recreated later - ID3D11Texture2D* mpBackBuffer; - ID3D11RenderTargetView* mRenderTargetView; - ID3D11DepthStencilView* mDepthStencilView; - }; - - - class D3D11RenderWindowSwapChainBased - : public D3D11RenderWindowBase - { - public: - D3D11RenderWindowSwapChainBased(D3D11Device& device, IDXGIFactoryN* pDXGIFactory); - ~D3D11RenderWindowSwapChainBased() { destroy(); } - virtual void destroy(void); - - /// Get the presentation parameters used with this window - DXGI_SWAP_CHAIN_DESC_N* getPresentationParameters(void) { return &mSwapChainDesc; } - - void swapBuffers( ); - - protected: - void _createSizeDependedD3DResources(); // obtains mpBackBuffer from mpSwapChain - void _createSwapChain(); - virtual HRESULT _createSwapChainImpl(IDXGIDeviceN* pDXGIDevice) = 0; - void _resizeSwapChainBuffers(unsigned width, unsigned height); - - protected: - // Pointer to swap chain - IDXGISwapChainN * mpSwapChain; - DXGI_SWAP_CHAIN_DESC_N mSwapChainDesc; - }; + class D3D11RenderWindowBase + : public RenderWindow + { + public: + D3D11RenderWindowBase(D3D11Device& device, IDXGIFactoryN* pDXGIFactory); + ~D3D11RenderWindowBase(); + virtual void create(const String& name, unsigned width, unsigned height, bool fullScreen, const NameValuePairList *miscParams); + virtual void destroy(void); + + void reposition(int left, int top) {} + void resize(unsigned int width, unsigned int height) {} + + bool isClosed() const { return mClosed; } + bool isHidden() const { return mHidden; } + + void getCustomAttribute( const String& name, void* pData ); + /** Overridden - see RenderTarget. + */ + virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); + bool requiresTextureFlipping() const { return false; } + + protected: + void _createSizeDependedD3DResources(); // assumes mpBackBuffer is already initialized + void _destroySizeDependedD3DResources(); + + IDXGIDeviceN* _queryDxgiDevice(); // release after use + + // just check if the multisampling requested is supported by the device + bool _checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format); + + void _updateViewportsDimensions(); + + protected: + D3D11Device & mDevice; // D3D11 driver + IDXGIFactoryN* mpDXGIFactory; + bool mIsExternal; // window not created by Ogre + bool mSizing; + bool mClosed; + bool mHidden; + + // ------------------------------------------------------- + // DirectX-specific + // ------------------------------------------------------- + DXGI_SAMPLE_DESC mFSAAType; + UINT mDisplayFrequency; + bool mVSync; + unsigned int mVSyncInterval; + + // Window size depended resources - must be released before swapchain resize and recreated later + ID3D11Texture2D* mpBackBuffer; + ID3D11RenderTargetView* mRenderTargetView; + ID3D11DepthStencilView* mDepthStencilView; + }; + + + class D3D11RenderWindowSwapChainBased + : public D3D11RenderWindowBase + { + public: + D3D11RenderWindowSwapChainBased(D3D11Device& device, IDXGIFactoryN* pDXGIFactory); + ~D3D11RenderWindowSwapChainBased() { destroy(); } + virtual void destroy(void); + + /// Get the presentation parameters used with this window + DXGI_SWAP_CHAIN_DESC_N* getPresentationParameters(void) { return &mSwapChainDesc; } + + void swapBuffers( ); + + protected: + void _createSizeDependedD3DResources(); // obtains mpBackBuffer from mpSwapChain + void _createSwapChain(); + virtual HRESULT _createSwapChainImpl(IDXGIDeviceN* pDXGIDevice) = 0; + void _resizeSwapChainBuffers(unsigned width, unsigned height); + + protected: + // Pointer to swap chain + IDXGISwapChainN * mpSwapChain; + DXGI_SWAP_CHAIN_DESC_N mSwapChainDesc; + }; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - class D3D11RenderWindowHwnd - : public D3D11RenderWindowSwapChainBased - { - public: - D3D11RenderWindowHwnd(D3D11Device& device, IDXGIFactoryN* pDXGIFactory); - ~D3D11RenderWindowHwnd() { destroy(); } - virtual void create(const String& name, unsigned width, unsigned height, bool fullScreen, const NameValuePairList *miscParams); - virtual void destroy(void); - - bool isVisible() const; - void setHidden(bool hidden); - void reposition(int left, int top); - void resize(unsigned int width, unsigned int height); - void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); - - // Method for dealing with resize / move & 3d library - void windowMovedOrResized(); - - HWND getWindowHandle() const { return mHWnd; } - void getCustomAttribute( const String& name, void* pData ); - - protected: - /// Are we in the middle of switching between fullscreen and windowed - bool _getSwitchingFullscreen() const { return mSwitchingFullscreen; } - /// Indicate that fullscreen / windowed switching has finished - void _finishSwitchingFullscreen(); - - virtual HRESULT _createSwapChainImpl(IDXGIDeviceN* pDXGIDevice); - void setActive(bool state); - protected: - HWND mHWnd; // Win32 window handle - bool mSwitchingFullscreen; // Are we switching from fullscreen to windowed or vice versa - }; + class D3D11RenderWindowHwnd + : public D3D11RenderWindowSwapChainBased + { + public: + D3D11RenderWindowHwnd(D3D11Device& device, IDXGIFactoryN* pDXGIFactory); + ~D3D11RenderWindowHwnd() { destroy(); } + virtual void create(const String& name, unsigned width, unsigned height, bool fullScreen, const NameValuePairList *miscParams); + virtual void destroy(void); + + bool isVisible() const; + void setHidden(bool hidden); + void reposition(int left, int top); + void resize(unsigned int width, unsigned int height); + void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); + + // Method for dealing with resize / move & 3d library + void windowMovedOrResized(); + + HWND getWindowHandle() const { return mHWnd; } + void getCustomAttribute( const String& name, void* pData ); + + protected: + /// Are we in the middle of switching between fullscreen and windowed + bool _getSwitchingFullscreen() const { return mSwitchingFullscreen; } + /// Indicate that fullscreen / windowed switching has finished + void _finishSwitchingFullscreen(); + + virtual HRESULT _createSwapChainImpl(IDXGIDeviceN* pDXGIDevice); + void setActive(bool state); + protected: + HWND mHWnd; // Win32 window handle + bool mSwitchingFullscreen; // Are we switching from fullscreen to windowed or vice versa + }; #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WINRT - - class D3D11RenderWindowCoreWindow - : public D3D11RenderWindowSwapChainBased - { - public: - D3D11RenderWindowCoreWindow(D3D11Device& device, IDXGIFactoryN* pDXGIFactory); - ~D3D11RenderWindowCoreWindow() { destroy(); } - virtual void create(const String& name, unsigned width, unsigned height, bool fullScreen, const NameValuePairList *miscParams); - virtual void destroy(void); + + class D3D11RenderWindowCoreWindow + : public D3D11RenderWindowSwapChainBased + { + public: + D3D11RenderWindowCoreWindow(D3D11Device& device, IDXGIFactoryN* pDXGIFactory); + ~D3D11RenderWindowCoreWindow() { destroy(); } + virtual void create(const String& name, unsigned width, unsigned height, bool fullScreen, const NameValuePairList *miscParams); + virtual void destroy(void); - Windows::UI::Core::CoreWindow^ getCoreWindow() const { return mCoreWindow.Get(); } + Windows::UI::Core::CoreWindow^ getCoreWindow() const { return mCoreWindow.Get(); } - bool isVisible() const; + bool isVisible() const; - // Method for dealing with resize / move & 3d library - void windowMovedOrResized(); + // Method for dealing with resize / move & 3d library + void windowMovedOrResized(); - protected: - virtual HRESULT _createSwapChainImpl(IDXGIDeviceN* pDXGIDevice); + protected: + virtual HRESULT _createSwapChainImpl(IDXGIDeviceN* pDXGIDevice); - protected: - Platform::Agile mCoreWindow; - }; + protected: + Platform::Agile mCoreWindow; + }; #if (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == DESKTOP_APP) - class D3D11RenderWindowImageSource - : public D3D11RenderWindowBase - { - public: - D3D11RenderWindowImageSource(D3D11Device& device, IDXGIFactoryN* pDXGIFactory); - ~D3D11RenderWindowImageSource() { destroy(); } - virtual void create(const String& name, unsigned width, unsigned height, bool fullScreen, const NameValuePairList *miscParams); - virtual void destroy(void); + class D3D11RenderWindowImageSource + : public D3D11RenderWindowBase + { + public: + D3D11RenderWindowImageSource(D3D11Device& device, IDXGIFactoryN* pDXGIFactory); + ~D3D11RenderWindowImageSource() { destroy(); } + virtual void create(const String& name, unsigned width, unsigned height, bool fullScreen, const NameValuePairList *miscParams); + virtual void destroy(void); - virtual void resize(unsigned int width, unsigned int height); - virtual void update(bool swapBuffers = true); - virtual void swapBuffers(); + virtual void resize(unsigned int width, unsigned int height); + virtual void update(bool swapBuffers = true); + virtual void swapBuffers(); - virtual bool isVisible() const { return mImageSourceNative != NULL; } + virtual bool isVisible() const { return mImageSourceNative != NULL; } - Windows::UI::Xaml::Media::ImageBrush^ getImageBrush() const { return mBrush; } - virtual void getCustomAttribute( const String& name, void* pData ); // "ImageBrush" -> Windows::UI::Xaml::Media::ImageBrush^ + Windows::UI::Xaml::Media::ImageBrush^ getImageBrush() const { return mBrush; } + virtual void getCustomAttribute( const String& name, void* pData ); // "ImageBrush" -> Windows::UI::Xaml::Media::ImageBrush^ - protected: - void _createSizeDependedD3DResources(); // creates mpBackBuffer + protected: + void _createSizeDependedD3DResources(); // creates mpBackBuffer - protected: - Windows::UI::Xaml::Media::ImageBrush^ mBrush; // size independed - Windows::UI::Xaml::Media::Imaging::SurfaceImageSource^ mImageSource; // size depended, can be NULL - ISurfaceImageSourceNative* mImageSourceNative; // size depended, can be NULL - }; + protected: + Windows::UI::Xaml::Media::ImageBrush^ mBrush; // size independed + Windows::UI::Xaml::Media::Imaging::SurfaceImageSource^ mImageSource; // size depended, can be NULL + ISurfaceImageSourceNative* mImageSourceNative; // size depended, can be NULL + }; #endif // (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == DESKTOP_APP) #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11Texture.h b/RenderSystems/Direct3D11/include/OgreD3D11Texture.h index 081862e2d88..974e2d7872d 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11Texture.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11Texture.h @@ -40,186 +40,186 @@ THE SOFTWARE. #endif namespace Ogre { - class D3D11Texture : public Texture - { - protected: + class D3D11Texture : public Texture + { + protected: // needed to store data between prepareImpl and loadImpl typedef SharedPtr::type > LoadedStreams; - /// D3DDevice pointer - D3D11Device & mDevice; - - /// D3D11 pointer - //LPDIRECT3D11 *mpD3D; - // 1D texture pointer - ID3D11Texture1D *mp1DTex; - // 2D texture pointer - ID3D11Texture2D *mp2DTex; - /// cubic texture pointer - ID3D11Texture3D *mp3DTex; - /// actual texture pointer - ID3D11Resource *mpTex; - - ID3D11ShaderResourceView* mpShaderResourceView; - - bool mAutoMipMapGeneration; - - template - void _queryInterface(fromtype *from, totype **to) - { - HRESULT hr = from->QueryInterface(__uuidof(totype), (void **)to); - - if(FAILED(hr) || mDevice.isError()) - { - this->freeInternalResources(); - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture\nError Description:" + errorDescription, - "D3D11Texture::_queryInterface" ); - } - } - unsigned int mEffectIndex; -#ifdef USE_D3DX11_LIBRARY - void _loadDDS(DataStreamPtr &dstream); - //ID3DX11Effect mEffect; + /// D3DDevice pointer + D3D11Device & mDevice; + + /// D3D11 pointer + //LPDIRECT3D11 *mpD3D; + // 1D texture pointer + ID3D11Texture1D *mp1DTex; + // 2D texture pointer + ID3D11Texture2D *mp2DTex; + /// cubic texture pointer + ID3D11Texture3D *mp3DTex; + /// actual texture pointer + ID3D11Resource *mpTex; + + ID3D11ShaderResourceView* mpShaderResourceView; + + bool mAutoMipMapGeneration; + + template + void _queryInterface(fromtype *from, totype **to) + { + HRESULT hr = from->QueryInterface(__uuidof(totype), (void **)to); + + if(FAILED(hr) || mDevice.isError()) + { + this->freeInternalResources(); + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture\nError Description:" + errorDescription, + "D3D11Texture::_queryInterface" ); + } + } + unsigned int mEffectIndex; +#ifdef USE_D3DX11_LIBRARY + void _loadDDS(DataStreamPtr &dstream); + //ID3DX11Effect mEffect; #endif void _create1DResourceView(); - void _create2DResourceView(); - void _create3DResourceView(); - - // is dynamic - bool mIsDynamic; - - /// cube texture individual face names - String mCubeFaceNames[6]; - /// device creation parameters - //D3DDEVICE_CREATION_PARAMETERS mDevCreParams; - /// back buffer pixel format - DXGI_FORMAT mBBPixelFormat; - /// The memory pool being used - //D3DPOOL mD3DPool; - /// device capabilities pointer - //D3DCAPS9 mDevCaps; - // Dynamic textures? - bool mDynamicTextures; - /// Vector of pointers to subsurfaces - typedef vector::type SurfaceList; - SurfaceList mSurfaceList; - - D3D11_SHADER_RESOURCE_VIEW_DESC mSRVDesc; - /// internal method, load a normal texture - void _loadTex(LoadedStreams & loadedStreams); - - /// internal method, create a blank normal 1D Dtexture - void _create1DTex(); - /// internal method, create a blank normal 2D texture - void _create2DTex(); - /// internal method, create a blank cube texture - void _create3DTex(); - - /// internal method, return a D3D pixel format for texture creation - DXGI_FORMAT _chooseD3DFormat(); - - /// @copydoc Texture::createInternalResources - void createInternalResources(void); - /// @copydoc Texture::createInternalResourcesImpl - void createInternalResourcesImpl(void); - /// @copydoc Texture::freeInternalResources - void freeInternalResources(void); - /// free internal resources - void freeInternalResourcesImpl(void); - /// internal method, set Texture class source image protected attributes - void _setSrcAttributes(unsigned long width, unsigned long height, unsigned long depth, PixelFormat format); - /// internal method, set Texture class final texture protected attributes - void _setFinalAttributes(unsigned long width, unsigned long height, unsigned long depth, PixelFormat format, UINT miscflags); - - /// internal method, the cube map face name for the spec. face index - String _getCubeFaceName(unsigned char face) const - { assert(face < 6); return mCubeFaceNames[face]; } - - /// internal method, create D3D11HardwarePixelBuffers for every face and - /// mipmap level. This method must be called after the D3D texture object was created - void _createSurfaceList(void); + void _create2DResourceView(); + void _create3DResourceView(); + + // is dynamic + bool mIsDynamic; + + /// cube texture individual face names + String mCubeFaceNames[6]; + /// device creation parameters + //D3DDEVICE_CREATION_PARAMETERS mDevCreParams; + /// back buffer pixel format + DXGI_FORMAT mBBPixelFormat; + /// The memory pool being used + //D3DPOOL mD3DPool; + /// device capabilities pointer + //D3DCAPS9 mDevCaps; + // Dynamic textures? + bool mDynamicTextures; + /// Vector of pointers to subsurfaces + typedef vector::type SurfaceList; + SurfaceList mSurfaceList; + + D3D11_SHADER_RESOURCE_VIEW_DESC mSRVDesc; + /// internal method, load a normal texture + void _loadTex(LoadedStreams & loadedStreams); + + /// internal method, create a blank normal 1D Dtexture + void _create1DTex(); + /// internal method, create a blank normal 2D texture + void _create2DTex(); + /// internal method, create a blank cube texture + void _create3DTex(); + + /// internal method, return a D3D pixel format for texture creation + DXGI_FORMAT _chooseD3DFormat(); + + /// @copydoc Texture::createInternalResources + void createInternalResources(void); + /// @copydoc Texture::createInternalResourcesImpl + void createInternalResourcesImpl(void); + /// @copydoc Texture::freeInternalResources + void freeInternalResources(void); + /// free internal resources + void freeInternalResourcesImpl(void); + /// internal method, set Texture class source image protected attributes + void _setSrcAttributes(unsigned long width, unsigned long height, unsigned long depth, PixelFormat format); + /// internal method, set Texture class final texture protected attributes + void _setFinalAttributes(unsigned long width, unsigned long height, unsigned long depth, PixelFormat format, UINT miscflags); + + /// internal method, the cube map face name for the spec. face index + String _getCubeFaceName(unsigned char face) const + { assert(face < 6); return mCubeFaceNames[face]; } + + /// internal method, create D3D11HardwarePixelBuffers for every face and + /// mipmap level. This method must be called after the D3D texture object was created + void _createSurfaceList(void); /// @copydoc Resource::prepareImpl void prepareImpl(void); /// @copydoc Resource::unprepareImpl void unprepareImpl(void); - /// overridden from Resource - void loadImpl(); - /// overridden from Resource - void postLoadImpl(); + /// overridden from Resource + void loadImpl(); + /// overridden from Resource + void postLoadImpl(); /** Vector of pointers to streams that were pulled from disk by prepareImpl but have yet to be pushed into texture memory by loadImpl. Should be cleared on load and on unprepare. */ LoadedStreams mLoadedStreams; - LoadedStreams _prepareNormTex(); - LoadedStreams _prepareVolumeTex(); - LoadedStreams _prepareCubeTex(); - public: - /// constructor - D3D11Texture(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, - D3D11Device & device); - /// destructor - ~D3D11Texture(); - - /// overridden from Texture - void copyToTexture( TexturePtr& target ); - /// overridden from Texture - void loadImage( const Image &img ); - - - /// @copydoc Texture::getBuffer - HardwarePixelBufferSharedPtr getBuffer(size_t face, size_t mipmap); - - ID3D11Resource *getTextureResource() - { assert(mpTex); return mpTex; } - /// retrieves a pointer to the actual texture - ID3D11ShaderResourceView *getTexture() - { assert(mpShaderResourceView); return mpShaderResourceView; } - /*/// retrieves a pointer to the normal 1D/2D texture - IDirect3DTexture9 *getNormTexture() - { assert(mpNormTex); return mpNormTex; } - /// retrieves a pointer to the cube texture - IDirect3DCubeTexture9 *getCubeTexture() - { assert(mpCubeTex); return mpCubeTex; } - */ - - - /// For dealing with lost devices - release the resource if in the default pool (and return true) - bool releaseIfDefaultPool(void); - /// For dealing with lost devices - recreate the resource if in the default pool (and return true) - bool recreateIfDefaultPool(D3D11Device & device); - - ID3D11Texture1D * GetTex1D() {return mp1DTex;}; - ID3D11Texture2D * GetTex2D() {return mp2DTex;}; - ID3D11Texture3D * GetTex3D() {return mp3DTex;}; - - D3D11_SHADER_RESOURCE_VIEW_DESC getShaderResourceViewDesc() const; - - bool HasAutoMipMapGenerationEnabled() const { return mAutoMipMapGeneration; } - - }; - - /// RenderTexture implementation for D3D11 - class D3D11RenderTexture : public RenderTexture - { - D3D11Device & mDevice; - ID3D11RenderTargetView * mRenderTargetView; - ID3D11DepthStencilView * mDepthStencilView; - public: - D3D11RenderTexture(const String &name, D3D11HardwarePixelBuffer *buffer, D3D11Device & device ); - virtual ~D3D11RenderTexture(); - - void rebind(D3D11HardwarePixelBuffer *buffer); - - virtual void getCustomAttribute( const String& name, void *pData ); - - bool requiresTextureFlipping() const { return false; } - }; + LoadedStreams _prepareNormTex(); + LoadedStreams _prepareVolumeTex(); + LoadedStreams _prepareCubeTex(); + public: + /// constructor + D3D11Texture(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, + D3D11Device & device); + /// destructor + ~D3D11Texture(); + + /// overridden from Texture + void copyToTexture( TexturePtr& target ); + /// overridden from Texture + void loadImage( const Image &img ); + + + /// @copydoc Texture::getBuffer + HardwarePixelBufferSharedPtr getBuffer(size_t face, size_t mipmap); + + ID3D11Resource *getTextureResource() + { assert(mpTex); return mpTex; } + /// retrieves a pointer to the actual texture + ID3D11ShaderResourceView *getTexture() + { assert(mpShaderResourceView); return mpShaderResourceView; } + /*/// retrieves a pointer to the normal 1D/2D texture + IDirect3DTexture9 *getNormTexture() + { assert(mpNormTex); return mpNormTex; } + /// retrieves a pointer to the cube texture + IDirect3DCubeTexture9 *getCubeTexture() + { assert(mpCubeTex); return mpCubeTex; } + */ + + + /// For dealing with lost devices - release the resource if in the default pool (and return true) + bool releaseIfDefaultPool(void); + /// For dealing with lost devices - recreate the resource if in the default pool (and return true) + bool recreateIfDefaultPool(D3D11Device & device); + + ID3D11Texture1D * GetTex1D() {return mp1DTex;}; + ID3D11Texture2D * GetTex2D() {return mp2DTex;}; + ID3D11Texture3D * GetTex3D() {return mp3DTex;}; + + D3D11_SHADER_RESOURCE_VIEW_DESC getShaderResourceViewDesc() const; + + bool HasAutoMipMapGenerationEnabled() const { return mAutoMipMapGeneration; } + + }; + + /// RenderTexture implementation for D3D11 + class D3D11RenderTexture : public RenderTexture + { + D3D11Device & mDevice; + ID3D11RenderTargetView * mRenderTargetView; + ID3D11DepthStencilView * mDepthStencilView; + public: + D3D11RenderTexture(const String &name, D3D11HardwarePixelBuffer *buffer, D3D11Device & device ); + virtual ~D3D11RenderTexture(); + + void rebind(D3D11HardwarePixelBuffer *buffer); + + virtual void getCustomAttribute( const String& name, void *pData ); + + bool requiresTextureFlipping() const { return false; } + }; } diff --git a/RenderSystems/Direct3D11/include/OgreD3D11TextureManager.h b/RenderSystems/Direct3D11/include/OgreD3D11TextureManager.h index eb4faf25018..72a850f9c37 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11TextureManager.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11TextureManager.h @@ -33,37 +33,37 @@ THE SOFTWARE. namespace Ogre { - class D3D11TextureManager : public TextureManager - { - protected: - D3D11Device & mDevice; - /// @copydoc ResourceManager::createImpl - Resource* createImpl(const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, - const NameValuePairList* createParams); + class D3D11TextureManager : public TextureManager + { + protected: + D3D11Device & mDevice; + /// @copydoc ResourceManager::createImpl + Resource* createImpl(const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, + const NameValuePairList* createParams); - public: - D3D11TextureManager( D3D11Device & device ); - ~D3D11TextureManager(); + public: + D3D11TextureManager( D3D11Device & device ); + ~D3D11TextureManager(); - /** Release all textures in the default memory pool. - @remarks - Method for dealing with lost devices. - */ - void releaseDefaultPoolResources(void); - /** Recreate all textures in the default memory pool. - @remarks - Method for dealing with lost devices. - */ - void recreateDefaultPoolResources(void); + /** Release all textures in the default memory pool. + @remarks + Method for dealing with lost devices. + */ + void releaseDefaultPoolResources(void); + /** Recreate all textures in the default memory pool. + @remarks + Method for dealing with lost devices. + */ + void recreateDefaultPoolResources(void); - /// @copydoc TextureManager::getNativeFormat - PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage); + /// @copydoc TextureManager::getNativeFormat + PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage); - /// @copydoc TextureManager::isHardwareFilteringSupported - bool isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage, - bool preciseFormatOnly = false); + /// @copydoc TextureManager::isHardwareFilteringSupported + bool isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage, + bool preciseFormatOnly = false); - }; + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11VertexDeclaration.h b/RenderSystems/Direct3D11/include/OgreD3D11VertexDeclaration.h index 23dd91de0aa..4d51c1bb34c 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11VertexDeclaration.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11VertexDeclaration.h @@ -34,58 +34,58 @@ THE SOFTWARE. namespace Ogre { - /** Specialisation of VertexDeclaration for D3D11 */ - class D3D11VertexDeclaration : public VertexDeclaration - { - protected: - D3D11Device & mlpD3DDevice; + /** Specialisation of VertexDeclaration for D3D11 */ + class D3D11VertexDeclaration : public VertexDeclaration + { + protected: + D3D11Device & mlpD3DDevice; - bool mNeedsRebuild; + bool mNeedsRebuild; - typedef map::type ShaderToILayoutMap; - typedef ShaderToILayoutMap::iterator ShaderToILayoutMapIterator; + typedef map::type ShaderToILayoutMap; + typedef ShaderToILayoutMap::iterator ShaderToILayoutMapIterator; typedef map::type ShaderToInputDesc; typedef ShaderToInputDesc::iterator ShaderToInputDescIterator; - ShaderToInputDesc mD3delems; + ShaderToInputDesc mD3delems; - ShaderToILayoutMap mShaderToILayoutMap; + ShaderToILayoutMap mShaderToILayoutMap; - /** Gets the D3D11-specific vertex declaration. */ + /** Gets the D3D11-specific vertex declaration. */ - ID3D11InputLayout * getILayoutByShader(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding); - public: - D3D11VertexDeclaration(D3D11Device & device); - ~D3D11VertexDeclaration(); + ID3D11InputLayout * getILayoutByShader(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding); + public: + D3D11VertexDeclaration(D3D11Device & device); + ~D3D11VertexDeclaration(); - /** See VertexDeclaration */ - const VertexElement& addElement(unsigned short source, size_t offset, VertexElementType theType, - VertexElementSemantic semantic, unsigned short index = 0); + /** See VertexDeclaration */ + const VertexElement& addElement(unsigned short source, size_t offset, VertexElementType theType, + VertexElementSemantic semantic, unsigned short index = 0); - /** See VertexDeclaration */ - const VertexElement& insertElement(unsigned short atPosition, - unsigned short source, size_t offset, VertexElementType theType, - VertexElementSemantic semantic, unsigned short index = 0); + /** See VertexDeclaration */ + const VertexElement& insertElement(unsigned short atPosition, + unsigned short source, size_t offset, VertexElementType theType, + VertexElementSemantic semantic, unsigned short index = 0); - /** See VertexDeclaration */ - void removeElement(unsigned short elem_index); + /** See VertexDeclaration */ + void removeElement(unsigned short elem_index); - /** See VertexDeclaration */ - void removeElement(VertexElementSemantic semantic, unsigned short index = 0); + /** See VertexDeclaration */ + void removeElement(VertexElementSemantic semantic, unsigned short index = 0); - /** See VertexDeclaration */ - void removeAllElements(void); + /** See VertexDeclaration */ + void removeAllElements(void); - /** See VertexDeclaration */ - void modifyElement(unsigned short elem_index, unsigned short source, size_t offset, VertexElementType theType, - VertexElementSemantic semantic, unsigned short index = 0); + /** See VertexDeclaration */ + void modifyElement(unsigned short elem_index, unsigned short source, size_t offset, VertexElementType theType, + VertexElementSemantic semantic, unsigned short index = 0); - D3D11_INPUT_ELEMENT_DESC * getD3DVertexDeclaration(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding); - void bindToShader(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding); + D3D11_INPUT_ELEMENT_DESC * getD3DVertexDeclaration(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding); + void bindToShader(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding); - }; + }; } diff --git a/RenderSystems/Direct3D11/include/OgreD3D11VideoMode.h b/RenderSystems/Direct3D11/include/OgreD3D11VideoMode.h index 4b4cff5af79..5e31a3e3435 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11VideoMode.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11VideoMode.h @@ -32,30 +32,30 @@ THE SOFTWARE. namespace Ogre { - static unsigned int modeCount = 0; - - class D3D11VideoMode - { - private: - DXGI_OUTPUT_DESC mDisplayMode; - DXGI_MODE_DESC mModeDesc; - unsigned int modeNumber; - - public: - D3D11VideoMode(); - D3D11VideoMode( const D3D11VideoMode &ob ); - D3D11VideoMode( DXGI_OUTPUT_DESC d3ddm,DXGI_MODE_DESC ModeDesc ); - ~D3D11VideoMode(); - - unsigned int getWidth() const; - unsigned int getHeight() const; - DXGI_FORMAT getFormat() const; - DXGI_RATIONAL getRefreshRate() const; - unsigned int getColourDepth() const; - DXGI_OUTPUT_DESC getDisplayMode() const; - DXGI_MODE_DESC getModeDesc() const; - void increaseRefreshRate(DXGI_RATIONAL rr); - String getDescription() const; - }; + static unsigned int modeCount = 0; + + class D3D11VideoMode + { + private: + DXGI_OUTPUT_DESC mDisplayMode; + DXGI_MODE_DESC mModeDesc; + unsigned int modeNumber; + + public: + D3D11VideoMode(); + D3D11VideoMode( const D3D11VideoMode &ob ); + D3D11VideoMode( DXGI_OUTPUT_DESC d3ddm,DXGI_MODE_DESC ModeDesc ); + ~D3D11VideoMode(); + + unsigned int getWidth() const; + unsigned int getHeight() const; + DXGI_FORMAT getFormat() const; + DXGI_RATIONAL getRefreshRate() const; + unsigned int getColourDepth() const; + DXGI_OUTPUT_DESC getDisplayMode() const; + DXGI_MODE_DESC getModeDesc() const; + void increaseRefreshRate(DXGI_RATIONAL rr); + String getDescription() const; + }; } #endif diff --git a/RenderSystems/Direct3D11/include/OgreD3D11VideoModeList.h b/RenderSystems/Direct3D11/include/OgreD3D11VideoModeList.h index ead4dd51dbd..01414d24acb 100644 --- a/RenderSystems/Direct3D11/include/OgreD3D11VideoModeList.h +++ b/RenderSystems/Direct3D11/include/OgreD3D11VideoModeList.h @@ -33,22 +33,22 @@ THE SOFTWARE. namespace Ogre { - class D3D11VideoModeList - { - private: - D3D11Driver* mDriver; - vector::type mModeList; + class D3D11VideoModeList + { + private: + D3D11Driver* mDriver; + vector::type mModeList; - public: - D3D11VideoModeList( D3D11Driver* pDriver ); - ~D3D11VideoModeList(); + public: + D3D11VideoModeList( D3D11Driver* pDriver ); + ~D3D11VideoModeList(); - BOOL enumerate(); + BOOL enumerate(); - D3D11VideoMode* item( size_t index ); - size_t count(); + D3D11VideoMode* item( size_t index ); + size_t count(); - D3D11VideoMode* item( const String &name ); - }; + D3D11VideoMode* item( const String &name ); + }; } #endif diff --git a/RenderSystems/Direct3D11/src/OgreD3D11DepthBuffer.cpp b/RenderSystems/Direct3D11/src/OgreD3D11DepthBuffer.cpp index 01ff8a19f85..6b533ab50e4 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11DepthBuffer.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11DepthBuffer.cpp @@ -32,94 +32,94 @@ THE SOFTWARE. namespace Ogre { - D3D11DepthBuffer::D3D11DepthBuffer( uint16 poolId, D3D11RenderSystem *renderSystem, - ID3D11DepthStencilView *depthBufferView, - uint32 width, uint32 height, - uint32 fsaa, uint32 multiSampleQuality, bool isManual ) : - DepthBuffer( poolId, 0, width, height, fsaa, "", isManual ), - mDepthStencilView( depthBufferView ), - mMultiSampleQuality( multiSampleQuality), - mRenderSystem(renderSystem) - { - D3D11_DEPTH_STENCIL_VIEW_DESC pDesc; - mDepthStencilView->GetDesc( &pDesc ); - // Unknown PixelFormat at the moment - PixelFormat format = D3D11Mappings::_getPF(pDesc.Format); - mBitDepth = D3D11Mappings::_getSizeInBytes(format) * 8; - } + D3D11DepthBuffer::D3D11DepthBuffer( uint16 poolId, D3D11RenderSystem *renderSystem, + ID3D11DepthStencilView *depthBufferView, + uint32 width, uint32 height, + uint32 fsaa, uint32 multiSampleQuality, bool isManual ) : + DepthBuffer( poolId, 0, width, height, fsaa, "", isManual ), + mDepthStencilView( depthBufferView ), + mMultiSampleQuality( multiSampleQuality), + mRenderSystem(renderSystem) + { + D3D11_DEPTH_STENCIL_VIEW_DESC pDesc; + mDepthStencilView->GetDesc( &pDesc ); + // Unknown PixelFormat at the moment + PixelFormat format = D3D11Mappings::_getPF(pDesc.Format); + mBitDepth = D3D11Mappings::_getSizeInBytes(format) * 8; + } - D3D11DepthBuffer::~D3D11DepthBuffer() - { - if( !mManual ) - mDepthStencilView->Release(); - mDepthStencilView = 0; - } - //--------------------------------------------------------------------- - bool D3D11DepthBuffer::isCompatible( RenderTarget *renderTarget ) const - { - D3D11_TEXTURE2D_DESC BBDesc; + D3D11DepthBuffer::~D3D11DepthBuffer() + { + if( !mManual ) + mDepthStencilView->Release(); + mDepthStencilView = 0; + } + //--------------------------------------------------------------------- + bool D3D11DepthBuffer::isCompatible( RenderTarget *renderTarget ) const + { + D3D11_TEXTURE2D_DESC BBDesc; - bool isTexture = false; - renderTarget->getCustomAttribute( "isTexture", &isTexture ); + bool isTexture = false; + renderTarget->getCustomAttribute( "isTexture", &isTexture ); - if(isTexture) - { - ID3D11Texture2D *D3D11texture; - D3D11HardwarePixelBuffer *pBuffer; - renderTarget->getCustomAttribute( "BUFFER", &pBuffer ); - D3D11texture = static_cast( pBuffer->getParentTexture()->getTextureResource() ); - D3D11texture->GetDesc(&BBDesc); - } - else - { - ID3D11Texture2D* pBack[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - memset( pBack, 0, sizeof(pBack) ); - renderTarget->getCustomAttribute( "DDBACKBUFFER", &pBack ); - - if( pBack[0] ) - { - pBack[0]->GetDesc(&BBDesc); - } - else - { - ID3D11Texture2D *D3D11texture; - renderTarget->getCustomAttribute( "ID3D11Texture2D", &D3D11texture ); - D3D11texture->GetDesc( &BBDesc ); - } - } + if(isTexture) + { + ID3D11Texture2D *D3D11texture; + D3D11HardwarePixelBuffer *pBuffer; + renderTarget->getCustomAttribute( "BUFFER", &pBuffer ); + D3D11texture = static_cast( pBuffer->getParentTexture()->getTextureResource() ); + D3D11texture->GetDesc(&BBDesc); + } + else + { + ID3D11Texture2D* pBack[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + memset( pBack, 0, sizeof(pBack) ); + renderTarget->getCustomAttribute( "DDBACKBUFFER", &pBack ); + + if( pBack[0] ) + { + pBack[0]->GetDesc(&BBDesc); + } + else + { + ID3D11Texture2D *D3D11texture; + renderTarget->getCustomAttribute( "ID3D11Texture2D", &D3D11texture ); + D3D11texture->GetDesc( &BBDesc ); + } + } - /* - ID3D11Texture2D *D3D11texture = NULL; - renderTarget->getCustomAttribute( "ID3D11Texture2D", &D3D11texture ); - D3D11_TEXTURE2D_DESC BBDesc; - D3D11texture->GetDesc( &BBDesc ); - */ - //RenderSystem will determine if bitdepths match (i.e. 32 bit RT don't like 16 bit Depth) - //This is the same function used to create them. Note results are usually cached so this should - //be quick + /* + ID3D11Texture2D *D3D11texture = NULL; + renderTarget->getCustomAttribute( "ID3D11Texture2D", &D3D11texture ); + D3D11_TEXTURE2D_DESC BBDesc; + D3D11texture->GetDesc( &BBDesc ); + */ + //RenderSystem will determine if bitdepths match (i.e. 32 bit RT don't like 16 bit Depth) + //This is the same function used to create them. Note results are usually cached so this should + //be quick - //TODO: Needs to check format too! - if( mFsaa == BBDesc.SampleDesc.Count && - mMultiSampleQuality == BBDesc.SampleDesc.Quality && - this->getWidth() == renderTarget->getWidth() && - this->getHeight() == renderTarget->getHeight() ) - { - return true; - } + //TODO: Needs to check format too! + if( mFsaa == BBDesc.SampleDesc.Count && + mMultiSampleQuality == BBDesc.SampleDesc.Quality && + this->getWidth() == renderTarget->getWidth() && + this->getHeight() == renderTarget->getHeight() ) + { + return true; + } - return false; - } - //--------------------------------------------------------------------- - ID3D11DepthStencilView* D3D11DepthBuffer::getDepthStencilView() const - { - return mDepthStencilView; - } - //--------------------------------------------------------------------- - void D3D11DepthBuffer::_resized(ID3D11DepthStencilView *depthBufferView, uint32 width, uint32 height) - { - mHeight = height; - mWidth = width; + return false; + } + //--------------------------------------------------------------------- + ID3D11DepthStencilView* D3D11DepthBuffer::getDepthStencilView() const + { + return mDepthStencilView; + } + //--------------------------------------------------------------------- + void D3D11DepthBuffer::_resized(ID3D11DepthStencilView *depthBufferView, uint32 width, uint32 height) + { + mHeight = height; + mWidth = width; - mDepthStencilView = depthBufferView; - } + mDepthStencilView = depthBufferView; + } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11Device.cpp b/RenderSystems/Direct3D11/src/OgreD3D11Device.cpp index 1435bf1a0d1..d8c1cb48dea 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11Device.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11Device.cpp @@ -29,176 +29,176 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - D3D11Device::eExceptionsErrorLevel D3D11Device::mExceptionsErrorLevel = D3D11Device::D3D_NO_EXCEPTION; - //--------------------------------------------------------------------- - D3D11Device::D3D11Device( ID3D11DeviceN * D3D11device ) - : mD3D11Device(D3D11device) - , mImmediateContext(0) - , mInfoQueue(NULL) - , mClassLinkage(0) - { + //--------------------------------------------------------------------- + D3D11Device::eExceptionsErrorLevel D3D11Device::mExceptionsErrorLevel = D3D11Device::D3D_NO_EXCEPTION; + //--------------------------------------------------------------------- + D3D11Device::D3D11Device( ID3D11DeviceN * D3D11device ) + : mD3D11Device(D3D11device) + , mImmediateContext(0) + , mInfoQueue(NULL) + , mClassLinkage(0) + { if (D3D11device) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - D3D11device->GetImmediateContext(&mImmediateContext); + D3D11device->GetImmediateContext(&mImmediateContext); #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - D3D11device->GetImmediateContext1(&mImmediateContext); + D3D11device->GetImmediateContext1(&mImmediateContext); #endif HRESULT hr = mD3D11Device->QueryInterface(__uuidof(ID3D11InfoQueue), (LPVOID*)&mInfoQueue); - if (SUCCEEDED(hr)) - { - mInfoQueue->ClearStoredMessages(); - mInfoQueue->ClearRetrievalFilter(); - mInfoQueue->ClearStorageFilter(); + if (SUCCEEDED(hr)) + { + mInfoQueue->ClearStoredMessages(); + mInfoQueue->ClearRetrievalFilter(); + mInfoQueue->ClearStorageFilter(); - D3D11_INFO_QUEUE_FILTER filter; - ZeroMemory(&filter, sizeof(D3D11_INFO_QUEUE_FILTER)); - std::vector severityList; + D3D11_INFO_QUEUE_FILTER filter; + ZeroMemory(&filter, sizeof(D3D11_INFO_QUEUE_FILTER)); + std::vector severityList; - switch(mExceptionsErrorLevel) - { - case D3D_NO_EXCEPTION: - severityList.push_back(D3D11_MESSAGE_SEVERITY_CORRUPTION); - case D3D_CORRUPTION: - severityList.push_back(D3D11_MESSAGE_SEVERITY_ERROR); - case D3D_ERROR: - severityList.push_back(D3D11_MESSAGE_SEVERITY_WARNING); - case D3D_WARNING: - case D3D_INFO: - severityList.push_back(D3D11_MESSAGE_SEVERITY_INFO); - default: - break; - } + switch(mExceptionsErrorLevel) + { + case D3D_NO_EXCEPTION: + severityList.push_back(D3D11_MESSAGE_SEVERITY_CORRUPTION); + case D3D_CORRUPTION: + severityList.push_back(D3D11_MESSAGE_SEVERITY_ERROR); + case D3D_ERROR: + severityList.push_back(D3D11_MESSAGE_SEVERITY_WARNING); + case D3D_WARNING: + case D3D_INFO: + severityList.push_back(D3D11_MESSAGE_SEVERITY_INFO); + default: + break; + } - if (severityList.size() > 0) - { - filter.DenyList.NumSeverities = severityList.size(); - filter.DenyList.pSeverityList = &severityList[0]; - } + if (severityList.size() > 0) + { + filter.DenyList.NumSeverities = severityList.size(); + filter.DenyList.pSeverityList = &severityList[0]; + } - mInfoQueue->AddStorageFilterEntries(&filter); - mInfoQueue->AddRetrievalFilterEntries(&filter); - } + mInfoQueue->AddStorageFilterEntries(&filter); + mInfoQueue->AddRetrievalFilterEntries(&filter); + } - // If feature level is 11, create class linkage - SAFE_RELEASE(mClassLinkage) - if (mD3D11Device->GetFeatureLevel() == D3D_FEATURE_LEVEL_11_0) - { - HRESULT hr = mD3D11Device->CreateClassLinkage(&mClassLinkage); - } - } - } - //--------------------------------------------------------------------- - D3D11Device::D3D11Device() : mD3D11Device(0), mImmediateContext(0), mClassLinkage(0) - { - } - //--------------------------------------------------------------------- - D3D11Device::~D3D11Device() - { - } - //--------------------------------------------------------------------- - ID3D11DeviceN * D3D11Device::operator=( ID3D11DeviceN * D3D11device ) - { - mD3D11Device = D3D11device; - if (D3D11device) - { + // If feature level is 11, create class linkage + SAFE_RELEASE(mClassLinkage) + if (mD3D11Device->GetFeatureLevel() == D3D_FEATURE_LEVEL_11_0) + { + HRESULT hr = mD3D11Device->CreateClassLinkage(&mClassLinkage); + } + } + } + //--------------------------------------------------------------------- + D3D11Device::D3D11Device() : mD3D11Device(0), mImmediateContext(0), mClassLinkage(0) + { + } + //--------------------------------------------------------------------- + D3D11Device::~D3D11Device() + { + } + //--------------------------------------------------------------------- + ID3D11DeviceN * D3D11Device::operator=( ID3D11DeviceN * D3D11device ) + { + mD3D11Device = D3D11device; + if (D3D11device) + { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - D3D11device->GetImmediateContext(&mImmediateContext); + D3D11device->GetImmediateContext(&mImmediateContext); #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - D3D11device->GetImmediateContext1(&mImmediateContext); -#endif - - // If feature level is 11, create class linkage - SAFE_RELEASE(mClassLinkage); - if (mD3D11Device->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0) - { - HRESULT hr = mD3D11Device->CreateClassLinkage(&mClassLinkage); - } - - } - return mD3D11Device; - } - //--------------------------------------------------------------------- - const bool D3D11Device::isNull() - { - return mD3D11Device == 0; - } - //--------------------------------------------------------------------- - const String D3D11Device::getErrorDescription(const HRESULT lastResult /* = NO_ERROR */) const - { - if (!mD3D11Device) - { - return "NULL device"; - } + D3D11device->GetImmediateContext1(&mImmediateContext); +#endif + + // If feature level is 11, create class linkage + SAFE_RELEASE(mClassLinkage); + if (mD3D11Device->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0) + { + HRESULT hr = mD3D11Device->CreateClassLinkage(&mClassLinkage); + } + + } + return mD3D11Device; + } + //--------------------------------------------------------------------- + const bool D3D11Device::isNull() + { + return mD3D11Device == 0; + } + //--------------------------------------------------------------------- + const String D3D11Device::getErrorDescription(const HRESULT lastResult /* = NO_ERROR */) const + { + if (!mD3D11Device) + { + return "NULL device"; + } - if (D3D_NO_EXCEPTION == mExceptionsErrorLevel) - { - return "infoQ exceptions are turned off"; - } + if (D3D_NO_EXCEPTION == mExceptionsErrorLevel) + { + return "infoQ exceptions are turned off"; + } - String res; + String res; - switch (lastResult) - { - case NO_ERROR: - break; - case E_INVALIDARG: - res = res + "invalid parameters were passed.\n"; - break; - default: - ;//assert(false); // unknown HRESULT - } + switch (lastResult) + { + case NO_ERROR: + break; + case E_INVALIDARG: + res = res + "invalid parameters were passed.\n"; + break; + default: + ;//assert(false); // unknown HRESULT + } - if (mInfoQueue != NULL) - { - UINT64 numStoredMessages = mInfoQueue->GetNumStoredMessages(); - for (UINT64 i = 0 ; i < numStoredMessages ; i++ ) - { - // Get the size of the message - SIZE_T messageLength = 0; - mInfoQueue->GetMessage(i, NULL, &messageLength); - // Allocate space and get the message - D3D11_MESSAGE * pMessage = (D3D11_MESSAGE*)malloc(messageLength); - mInfoQueue->GetMessage(i, pMessage, &messageLength); - res = res + pMessage->pDescription + "\n"; - free(pMessage); - } - } + if (mInfoQueue != NULL) + { + UINT64 numStoredMessages = mInfoQueue->GetNumStoredMessages(); + for (UINT64 i = 0 ; i < numStoredMessages ; i++ ) + { + // Get the size of the message + SIZE_T messageLength = 0; + mInfoQueue->GetMessage(i, NULL, &messageLength); + // Allocate space and get the message + D3D11_MESSAGE * pMessage = (D3D11_MESSAGE*)malloc(messageLength); + mInfoQueue->GetMessage(i, pMessage, &messageLength); + res = res + pMessage->pDescription + "\n"; + free(pMessage); + } + } - return res; - } - //--------------------------------------------------------------------- - void D3D11Device::release() - { - // Clear state - if (mImmediateContext) - { - mImmediateContext->Flush(); - mImmediateContext->ClearState(); - } + return res; + } + //--------------------------------------------------------------------- + void D3D11Device::release() + { + // Clear state + if (mImmediateContext) + { + mImmediateContext->Flush(); + mImmediateContext->ClearState(); + } SAFE_RELEASE(mInfoQueue); - SAFE_RELEASE(mD3D11Device); + SAFE_RELEASE(mD3D11Device); SAFE_RELEASE(mImmediateContext); - SAFE_RELEASE(mClassLinkage); - } - //--------------------------------------------------------------------- - ID3D11DeviceN * D3D11Device::get() - { - return mD3D11Device; - } - //--------------------------------------------------------------------- - void D3D11Device::setExceptionsErrorLevel( const eExceptionsErrorLevel exceptionsErrorLevel ) - { - mExceptionsErrorLevel = exceptionsErrorLevel; - } - //--------------------------------------------------------------------- - const D3D11Device::eExceptionsErrorLevel D3D11Device::getExceptionsErrorLevel() - { - return mExceptionsErrorLevel; - } + SAFE_RELEASE(mClassLinkage); + } + //--------------------------------------------------------------------- + ID3D11DeviceN * D3D11Device::get() + { + return mD3D11Device; + } + //--------------------------------------------------------------------- + void D3D11Device::setExceptionsErrorLevel( const eExceptionsErrorLevel exceptionsErrorLevel ) + { + mExceptionsErrorLevel = exceptionsErrorLevel; + } + //--------------------------------------------------------------------- + const D3D11Device::eExceptionsErrorLevel D3D11Device::getExceptionsErrorLevel() + { + return mExceptionsErrorLevel; + } //--------------------------------------------------------------------- const bool D3D11Device::_getErrorsFromQueue() const { @@ -279,5 +279,5 @@ namespace Ogre } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- } \ No newline at end of file diff --git a/RenderSystems/Direct3D11/src/OgreD3D11Driver.cpp b/RenderSystems/Direct3D11/src/OgreD3D11Driver.cpp index 5fd1c206972..34b23455b08 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11Driver.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11Driver.cpp @@ -32,119 +32,119 @@ THE SOFTWARE. #include "OgreString.h" namespace Ogre { - //--------------------------------------------------------------------- - unsigned int D3D11Driver::driverCount = 0; - //--------------------------------------------------------------------- - D3D11Driver::D3D11Driver() - { - tempNo = ++driverCount; - ZeroMemory( &mAdapterIdentifier, sizeof(mAdapterIdentifier) ); - ZeroMemory( &mDesktopDisplayMode, sizeof(mDesktopDisplayMode) ); - mVideoModeList = NULL; - mDXGIAdapter=NULL; - } - //--------------------------------------------------------------------- - D3D11Driver::D3D11Driver( const D3D11Driver &ob ) - { - tempNo = ++driverCount; - mAdapterNumber = ob.mAdapterNumber; - mAdapterIdentifier = ob.mAdapterIdentifier; - mDesktopDisplayMode = ob.mDesktopDisplayMode; - mVideoModeList = NULL; - mDXGIAdapter=ob.mDXGIAdapter; + //--------------------------------------------------------------------- + unsigned int D3D11Driver::driverCount = 0; + //--------------------------------------------------------------------- + D3D11Driver::D3D11Driver() + { + tempNo = ++driverCount; + ZeroMemory( &mAdapterIdentifier, sizeof(mAdapterIdentifier) ); + ZeroMemory( &mDesktopDisplayMode, sizeof(mDesktopDisplayMode) ); + mVideoModeList = NULL; + mDXGIAdapter=NULL; + } + //--------------------------------------------------------------------- + D3D11Driver::D3D11Driver( const D3D11Driver &ob ) + { + tempNo = ++driverCount; + mAdapterNumber = ob.mAdapterNumber; + mAdapterIdentifier = ob.mAdapterIdentifier; + mDesktopDisplayMode = ob.mDesktopDisplayMode; + mVideoModeList = NULL; + mDXGIAdapter=ob.mDXGIAdapter; - if(mDXGIAdapter) - mDXGIAdapter->AddRef(); - } - //--------------------------------------------------------------------- - D3D11Driver::D3D11Driver( unsigned int adapterNumber, IDXGIAdapterN* pDXGIAdapter) - { - tempNo = ++driverCount; - mAdapterNumber = adapterNumber; - mVideoModeList = NULL; - mDXGIAdapter=pDXGIAdapter; - if(mDXGIAdapter) - mDXGIAdapter->AddRef(); + if(mDXGIAdapter) + mDXGIAdapter->AddRef(); + } + //--------------------------------------------------------------------- + D3D11Driver::D3D11Driver( unsigned int adapterNumber, IDXGIAdapterN* pDXGIAdapter) + { + tempNo = ++driverCount; + mAdapterNumber = adapterNumber; + mVideoModeList = NULL; + mDXGIAdapter=pDXGIAdapter; + if(mDXGIAdapter) + mDXGIAdapter->AddRef(); - // get the description of the adapter - pDXGIAdapter->GetDesc1( &mAdapterIdentifier ); + // get the description of the adapter + pDXGIAdapter->GetDesc1( &mAdapterIdentifier ); - } - //--------------------------------------------------------------------- - D3D11Driver::~D3D11Driver() - { - SAFE_DELETE( mVideoModeList ); - SAFE_RELEASE(mDXGIAdapter); - driverCount--; - } - //--------------------------------------------------------------------- - D3D11Driver& D3D11Driver::operator=(const D3D11Driver& ob) - { - tempNo = ++driverCount; - mAdapterNumber = ob.mAdapterNumber; - mAdapterIdentifier = ob.mAdapterIdentifier; - mDesktopDisplayMode = ob.mDesktopDisplayMode; - mVideoModeList = NULL; - if(ob.mDXGIAdapter) - ob.mDXGIAdapter->AddRef(); - SAFE_RELEASE(mDXGIAdapter); - mDXGIAdapter=ob.mDXGIAdapter; + } + //--------------------------------------------------------------------- + D3D11Driver::~D3D11Driver() + { + SAFE_DELETE( mVideoModeList ); + SAFE_RELEASE(mDXGIAdapter); + driverCount--; + } + //--------------------------------------------------------------------- + D3D11Driver& D3D11Driver::operator=(const D3D11Driver& ob) + { + tempNo = ++driverCount; + mAdapterNumber = ob.mAdapterNumber; + mAdapterIdentifier = ob.mAdapterIdentifier; + mDesktopDisplayMode = ob.mDesktopDisplayMode; + mVideoModeList = NULL; + if(ob.mDXGIAdapter) + ob.mDXGIAdapter->AddRef(); + SAFE_RELEASE(mDXGIAdapter); + mDXGIAdapter=ob.mDXGIAdapter; - return *this; - } - //--------------------------------------------------------------------- - String D3D11Driver::DriverName() const - { - size_t size=wcslen(mAdapterIdentifier.Description); - char * str=new char[size+1]; + return *this; + } + //--------------------------------------------------------------------- + String D3D11Driver::DriverName() const + { + size_t size=wcslen(mAdapterIdentifier.Description); + char * str=new char[size+1]; - wcstombs(str, mAdapterIdentifier.Description,size); - str[size]='\0'; - String Description=str; - delete []str; - return String(Description ); - } - //--------------------------------------------------------------------- - String D3D11Driver::DriverDescription() const - { - size_t size=wcslen(mAdapterIdentifier.Description); - char * str=new char[size+1]; + wcstombs(str, mAdapterIdentifier.Description,size); + str[size]='\0'; + String Description=str; + delete []str; + return String(Description ); + } + //--------------------------------------------------------------------- + String D3D11Driver::DriverDescription() const + { + size_t size=wcslen(mAdapterIdentifier.Description); + char * str=new char[size+1]; - wcstombs(str, mAdapterIdentifier.Description,size); - str[size]='\0'; - String driverDescription=str; - delete [] str; - StringUtil::trim(driverDescription); + wcstombs(str, mAdapterIdentifier.Description,size); + str[size]='\0'; + String driverDescription=str; + delete [] str; + StringUtil::trim(driverDescription); - return driverDescription; - } - //--------------------------------------------------------------------- - D3D11VideoModeList* D3D11Driver::getVideoModeList() - { - if( !mVideoModeList ) - mVideoModeList = new D3D11VideoModeList( this ); + return driverDescription; + } + //--------------------------------------------------------------------- + D3D11VideoModeList* D3D11Driver::getVideoModeList() + { + if( !mVideoModeList ) + mVideoModeList = new D3D11VideoModeList( this ); - return mVideoModeList; - } - //--------------------------------------------------------------------- - unsigned int D3D11Driver::getAdapterNumber() const - { - return mAdapterNumber; - } - //--------------------------------------------------------------------- - const DXGI_ADAPTER_DESC1& D3D11Driver::getAdapterIdentifier() const - { - return mAdapterIdentifier; - } - //--------------------------------------------------------------------- - const DXGI_MODE_DESC& D3D11Driver::getDesktopMode() const - { - return mDesktopDisplayMode; - } - //--------------------------------------------------------------------- - IDXGIAdapterN* D3D11Driver::getDeviceAdapter() const - { - return mDXGIAdapter; - } - //--------------------------------------------------------------------- + return mVideoModeList; + } + //--------------------------------------------------------------------- + unsigned int D3D11Driver::getAdapterNumber() const + { + return mAdapterNumber; + } + //--------------------------------------------------------------------- + const DXGI_ADAPTER_DESC1& D3D11Driver::getAdapterIdentifier() const + { + return mAdapterIdentifier; + } + //--------------------------------------------------------------------- + const DXGI_MODE_DESC& D3D11Driver::getDesktopMode() const + { + return mDesktopDisplayMode; + } + //--------------------------------------------------------------------- + IDXGIAdapterN* D3D11Driver::getDeviceAdapter() const + { + return mDXGIAdapter; + } + //--------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11DriverList.cpp b/RenderSystems/Direct3D11/src/OgreD3D11DriverList.cpp index cba96604eb5..9d3092cefa3 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11DriverList.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11DriverList.cpp @@ -32,87 +32,87 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - D3D11DriverList::D3D11DriverList( IDXGIFactoryN* pDXGIFactory ) - { - enumerate(pDXGIFactory); - } - //----------------------------------------------------------------------- - D3D11DriverList::~D3D11DriverList(void) - { - for(unsigned i = 0; i < mDriverList.size(); i++) - { - delete (mDriverList[i]); - } - mDriverList.clear(); + //----------------------------------------------------------------------- + D3D11DriverList::D3D11DriverList( IDXGIFactoryN* pDXGIFactory ) + { + enumerate(pDXGIFactory); + } + //----------------------------------------------------------------------- + D3D11DriverList::~D3D11DriverList(void) + { + for(unsigned i = 0; i < mDriverList.size(); i++) + { + delete (mDriverList[i]); + } + mDriverList.clear(); - } - //----------------------------------------------------------------------- - BOOL D3D11DriverList::enumerate(IDXGIFactoryN* pDXGIFactory) - { - LogManager::getSingleton().logMessage( "D3D11: Driver Detection Starts" ); - // Create the DXGI Factory + } + //----------------------------------------------------------------------- + BOOL D3D11DriverList::enumerate(IDXGIFactoryN* pDXGIFactory) + { + LogManager::getSingleton().logMessage( "D3D11: Driver Detection Starts" ); + // Create the DXGI Factory - for( UINT iAdapter=0; ; iAdapter++ ) - { - IDXGIAdapterN* pDXGIAdapter = NULL; - HRESULT hr = pDXGIFactory->EnumAdapters1( iAdapter, &pDXGIAdapter ); - if( DXGI_ERROR_NOT_FOUND == hr ) - { - hr = S_OK; - break; - } - if( FAILED(hr) ) - { - SAFE_RELEASE(pDXGIAdapter); - return false; - } + for( UINT iAdapter=0; ; iAdapter++ ) + { + IDXGIAdapterN* pDXGIAdapter = NULL; + HRESULT hr = pDXGIFactory->EnumAdapters1( iAdapter, &pDXGIAdapter ); + if( DXGI_ERROR_NOT_FOUND == hr ) + { + hr = S_OK; + break; + } + if( FAILED(hr) ) + { + SAFE_RELEASE(pDXGIAdapter); + return false; + } - // we don't want NVIDIA PerfHUD in the list - so - here we filter it out - DXGI_ADAPTER_DESC1 adaptDesc; - if ( SUCCEEDED( pDXGIAdapter->GetDesc1( &adaptDesc ) ) ) - { - const bool isPerfHUD = wcscmp( adaptDesc.Description, L"NVIDIA PerfHUD" ) == 0; + // we don't want NVIDIA PerfHUD in the list - so - here we filter it out + DXGI_ADAPTER_DESC1 adaptDesc; + if ( SUCCEEDED( pDXGIAdapter->GetDesc1( &adaptDesc ) ) ) + { + const bool isPerfHUD = wcscmp( adaptDesc.Description, L"NVIDIA PerfHUD" ) == 0; - if (isPerfHUD) - { - continue; - } - } + if (isPerfHUD) + { + continue; + } + } - mDriverList.push_back(new D3D11Driver(iAdapter,pDXGIAdapter) ); + mDriverList.push_back(new D3D11Driver(iAdapter,pDXGIAdapter) ); - SAFE_RELEASE(pDXGIAdapter); - } + SAFE_RELEASE(pDXGIAdapter); + } - LogManager::getSingleton().logMessage( "D3D11: Driver Detection Ends" ); + LogManager::getSingleton().logMessage( "D3D11: Driver Detection Ends" ); - return TRUE; - } - //----------------------------------------------------------------------- - size_t D3D11DriverList::count() const - { - return mDriverList.size(); - } - //----------------------------------------------------------------------- - D3D11Driver* D3D11DriverList::item( size_t index ) - { - return mDriverList.at( index ); - } - //----------------------------------------------------------------------- - D3D11Driver* D3D11DriverList::item( const String &name ) - { - vector::type::iterator it = mDriverList.begin(); - if (it == mDriverList.end()) - return NULL; + return TRUE; + } + //----------------------------------------------------------------------- + size_t D3D11DriverList::count() const + { + return mDriverList.size(); + } + //----------------------------------------------------------------------- + D3D11Driver* D3D11DriverList::item( size_t index ) + { + return mDriverList.at( index ); + } + //----------------------------------------------------------------------- + D3D11Driver* D3D11DriverList::item( const String &name ) + { + vector::type::iterator it = mDriverList.begin(); + if (it == mDriverList.end()) + return NULL; - for (;it != mDriverList.end(); ++it) - { - if ((*it)->DriverDescription() == name) - return (*it); - } + for (;it != mDriverList.end(); ++it) + { + if ((*it)->DriverDescription() == name) + return (*it); + } - return NULL; - } - //----------------------------------------------------------------------- + return NULL; + } + //----------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11EngineDll.cpp b/RenderSystems/Direct3D11/src/OgreD3D11EngineDll.cpp index 6d92c2d2b47..494f06524af 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11EngineDll.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11EngineDll.cpp @@ -31,18 +31,18 @@ THE SOFTWARE. #ifndef OGRE_STATIC_LIB namespace Ogre { - D3D11Plugin* plugin; + D3D11Plugin* plugin; - extern "C" void _OgreD3D11Export dllStartPlugin(void) throw() - { - plugin = new D3D11Plugin(); - Root::getSingleton().installPlugin(plugin); - } + extern "C" void _OgreD3D11Export dllStartPlugin(void) throw() + { + plugin = new D3D11Plugin(); + Root::getSingleton().installPlugin(plugin); + } - extern "C" void _OgreD3D11Export dllStopPlugin(void) - { - Root::getSingleton().uninstallPlugin(plugin); - delete plugin; - } + extern "C" void _OgreD3D11Export dllStopPlugin(void) + { + Root::getSingleton().uninstallPlugin(plugin); + delete plugin; + } } #endif diff --git a/RenderSystems/Direct3D11/src/OgreD3D11GpuProgram.cpp b/RenderSystems/Direct3D11/src/OgreD3D11GpuProgram.cpp index b5f5aba3ba8..2b6938762e7 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11GpuProgram.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11GpuProgram.cpp @@ -32,301 +32,301 @@ THE SOFTWARE. #include "OgreException.h" namespace Ogre { - //----------------------------------------------------------------------------- - D3D11GpuProgram::D3D11GpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device) - : GpuProgram(creator, name, handle, group, isManual, loader), - mDevice(device) - { - if (createParamDictionary("D3D11GpuProgram")) - { - setupBaseParamDictionary(); - } - } - //----------------------------------------------------------------------------- - void D3D11GpuProgram::loadImpl(void) - { - // Normal load-from-source approach - if (mLoadFromFile) - { - // find & load source code - DataStreamPtr stream = - ResourceGroupManager::getSingleton().openResource( - mFilename, mGroup, true, this); - mSource = stream->getAsString(); - } + //----------------------------------------------------------------------------- + D3D11GpuProgram::D3D11GpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, D3D11Device & device) + : GpuProgram(creator, name, handle, group, isManual, loader), + mDevice(device) + { + if (createParamDictionary("D3D11GpuProgram")) + { + setupBaseParamDictionary(); + } + } + //----------------------------------------------------------------------------- + void D3D11GpuProgram::loadImpl(void) + { + // Normal load-from-source approach + if (mLoadFromFile) + { + // find & load source code + DataStreamPtr stream = + ResourceGroupManager::getSingleton().openResource( + mFilename, mGroup, true, this); + mSource = stream->getAsString(); + } - // Call polymorphic load - loadFromSource(); - } - //----------------------------------------------------------------------------- - void D3D11GpuProgram::loadFromSource(void) - { - String message = "AIZ:D3D11 dosn't support assembly shaders. Shader name:" + mName + "\n" ; - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message, - "D3D11GpuProgram::loadFromSource"); - } - //----------------------------------------------------------------------------- - D3D11GpuVertexProgram::D3D11GpuVertexProgram(ResourceManager* creator, - const String& name, ResourceHandle handle, const String& group, - bool isManual, ManualResourceLoader* loader, D3D11Device & device) - : D3D11GpuProgram(creator, name, handle, group, isManual, loader, device) - , mVertexShader(NULL) - { - mType = GPT_VERTEX_PROGRAM; - } - //----------------------------------------------------------------------------- - D3D11GpuVertexProgram::~D3D11GpuVertexProgram() - { - // have to call this here reather than in Resource destructor - // since calling virtual methods in base destructors causes crash - unload(); - } - //----------------------------------------------------------------------------- - void D3D11GpuVertexProgram::loadFromMicrocode(ID3D10Blob * microcode) - { - if (isSupported()) - { - // Create the shader - HRESULT hr = mDevice->CreateVertexShader( - static_cast(microcode->GetBufferPointer()), - microcode->GetBufferSize(), - NULL, - &mVertexShader); + // Call polymorphic load + loadFromSource(); + } + //----------------------------------------------------------------------------- + void D3D11GpuProgram::loadFromSource(void) + { + String message = "AIZ:D3D11 dosn't support assembly shaders. Shader name:" + mName + "\n" ; + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message, + "D3D11GpuProgram::loadFromSource"); + } + //----------------------------------------------------------------------------- + D3D11GpuVertexProgram::D3D11GpuVertexProgram(ResourceManager* creator, + const String& name, ResourceHandle handle, const String& group, + bool isManual, ManualResourceLoader* loader, D3D11Device & device) + : D3D11GpuProgram(creator, name, handle, group, isManual, loader, device) + , mVertexShader(NULL) + { + mType = GPT_VERTEX_PROGRAM; + } + //----------------------------------------------------------------------------- + D3D11GpuVertexProgram::~D3D11GpuVertexProgram() + { + // have to call this here reather than in Resource destructor + // since calling virtual methods in base destructors causes crash + unload(); + } + //----------------------------------------------------------------------------- + void D3D11GpuVertexProgram::loadFromMicrocode(ID3D10Blob * microcode) + { + if (isSupported()) + { + // Create the shader + HRESULT hr = mDevice->CreateVertexShader( + static_cast(microcode->GetBufferPointer()), + microcode->GetBufferSize(), + NULL, + &mVertexShader); - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D11 vertex shader " + mName + " from microcode\nError Description:" + errorDescription, - "D3D11GpuVertexProgram::loadFromMicrocode"); + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D11 vertex shader " + mName + " from microcode\nError Description:" + errorDescription, + "D3D11GpuVertexProgram::loadFromMicrocode"); - } - } - else - { - LogManager::getSingleton().logMessage( - "Unsupported D3D11 vertex shader '" + mName + "' was not loaded."); - } - } - //----------------------------------------------------------------------------- - void D3D11GpuVertexProgram::unloadImpl(void) - { - SAFE_RELEASE(mVertexShader); - } - //----------------------------------------------------------------------------- - ID3D11VertexShader * D3D11GpuVertexProgram::getVertexShader( void ) const - { - return mVertexShader; - } - //----------------------------------------------------------------------------- - D3D11GpuFragmentProgram::D3D11GpuFragmentProgram(ResourceManager* creator, - const String& name, ResourceHandle handle, const String& group, - bool isManual, ManualResourceLoader* loader, D3D11Device & device) - : D3D11GpuProgram(creator, name, handle, group, isManual, loader, device) - , mPixelShader(NULL) - { - mType = GPT_FRAGMENT_PROGRAM; - } - //----------------------------------------------------------------------------- - D3D11GpuFragmentProgram::~D3D11GpuFragmentProgram() - { - // have to call this here reather than in Resource destructor - // since calling virtual methods in base destructors causes crash - unload(); - } - //----------------------------------------------------------------------------- - void D3D11GpuFragmentProgram::loadFromMicrocode(ID3D10Blob * microcode) - { - if (isSupported()) - { - // Create the shader - HRESULT hr = mDevice->CreatePixelShader( - static_cast(microcode->GetBufferPointer()), - microcode->GetBufferSize(), - NULL, - &mPixelShader); + } + } + else + { + LogManager::getSingleton().logMessage( + "Unsupported D3D11 vertex shader '" + mName + "' was not loaded."); + } + } + //----------------------------------------------------------------------------- + void D3D11GpuVertexProgram::unloadImpl(void) + { + SAFE_RELEASE(mVertexShader); + } + //----------------------------------------------------------------------------- + ID3D11VertexShader * D3D11GpuVertexProgram::getVertexShader( void ) const + { + return mVertexShader; + } + //----------------------------------------------------------------------------- + D3D11GpuFragmentProgram::D3D11GpuFragmentProgram(ResourceManager* creator, + const String& name, ResourceHandle handle, const String& group, + bool isManual, ManualResourceLoader* loader, D3D11Device & device) + : D3D11GpuProgram(creator, name, handle, group, isManual, loader, device) + , mPixelShader(NULL) + { + mType = GPT_FRAGMENT_PROGRAM; + } + //----------------------------------------------------------------------------- + D3D11GpuFragmentProgram::~D3D11GpuFragmentProgram() + { + // have to call this here reather than in Resource destructor + // since calling virtual methods in base destructors causes crash + unload(); + } + //----------------------------------------------------------------------------- + void D3D11GpuFragmentProgram::loadFromMicrocode(ID3D10Blob * microcode) + { + if (isSupported()) + { + // Create the shader + HRESULT hr = mDevice->CreatePixelShader( + static_cast(microcode->GetBufferPointer()), + microcode->GetBufferSize(), + NULL, + &mPixelShader); - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D11 pixel shader " + mName + " from microcode.\nError Description:" + errorDescription, - "D3D11GpuFragmentProgram::loadFromMicrocode"); - } - } - else - { - LogManager::getSingleton().logMessage( - "Unsupported D3D11 pixel shader '" + mName + "' was not loaded."); - } - } - //----------------------------------------------------------------------------- - void D3D11GpuFragmentProgram::unloadImpl(void) - { - SAFE_RELEASE(mPixelShader); - } - //----------------------------------------------------------------------------- - ID3D11PixelShader * D3D11GpuFragmentProgram::getPixelShader( void ) const - { - return mPixelShader; - } - //----------------------------------------------------------------------------- - D3D11GpuGeometryProgram::D3D11GpuGeometryProgram(ResourceManager* creator, - const String& name, ResourceHandle handle, const String& group, - bool isManual, ManualResourceLoader* loader, D3D11Device & device) - : D3D11GpuProgram(creator, name, handle, group, isManual, loader, device) - , mGeometryShader(NULL) - { - mType = GPT_GEOMETRY_PROGRAM; - } - //----------------------------------------------------------------------------- - D3D11GpuGeometryProgram::~D3D11GpuGeometryProgram() - { - // have to call this here reather than in Resource destructor - // since calling virtual methods in base destructors causes crash - unload(); - } - //----------------------------------------------------------------------------- - void D3D11GpuGeometryProgram::loadFromMicrocode(ID3D10Blob * microcode) - { - if (isSupported()) - { - // Create the shader - HRESULT hr = mDevice->CreateGeometryShader( - static_cast(microcode->GetBufferPointer()), - microcode->GetBufferSize(), - NULL, - &mGeometryShader); + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D11 pixel shader " + mName + " from microcode.\nError Description:" + errorDescription, + "D3D11GpuFragmentProgram::loadFromMicrocode"); + } + } + else + { + LogManager::getSingleton().logMessage( + "Unsupported D3D11 pixel shader '" + mName + "' was not loaded."); + } + } + //----------------------------------------------------------------------------- + void D3D11GpuFragmentProgram::unloadImpl(void) + { + SAFE_RELEASE(mPixelShader); + } + //----------------------------------------------------------------------------- + ID3D11PixelShader * D3D11GpuFragmentProgram::getPixelShader( void ) const + { + return mPixelShader; + } + //----------------------------------------------------------------------------- + D3D11GpuGeometryProgram::D3D11GpuGeometryProgram(ResourceManager* creator, + const String& name, ResourceHandle handle, const String& group, + bool isManual, ManualResourceLoader* loader, D3D11Device & device) + : D3D11GpuProgram(creator, name, handle, group, isManual, loader, device) + , mGeometryShader(NULL) + { + mType = GPT_GEOMETRY_PROGRAM; + } + //----------------------------------------------------------------------------- + D3D11GpuGeometryProgram::~D3D11GpuGeometryProgram() + { + // have to call this here reather than in Resource destructor + // since calling virtual methods in base destructors causes crash + unload(); + } + //----------------------------------------------------------------------------- + void D3D11GpuGeometryProgram::loadFromMicrocode(ID3D10Blob * microcode) + { + if (isSupported()) + { + // Create the shader + HRESULT hr = mDevice->CreateGeometryShader( + static_cast(microcode->GetBufferPointer()), + microcode->GetBufferSize(), + NULL, + &mGeometryShader); - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D11 geometry shader " + mName + " from microcode.\nError Description:" + errorDescription, - "D3D11GpuGeometryProgram::loadFromMicrocode"); - } - } - else - { - LogManager::getSingleton().logMessage( - "Unsupported D3D11 geometry shader '" + mName + "' was not loaded."); - } - } - //----------------------------------------------------------------------------- - void D3D11GpuGeometryProgram::unloadImpl(void) - { - SAFE_RELEASE(mGeometryShader); - } - //----------------------------------------------------------------------------- - ID3D11GeometryShader * D3D11GpuGeometryProgram::getGeometryShader( void ) const - { - return mGeometryShader; - } - //----------------------------------------------------------------------------- - D3D11GpuDomainProgram::D3D11GpuDomainProgram(ResourceManager* creator, - const String& name, ResourceHandle handle, const String& group, - bool isManual, ManualResourceLoader* loader, D3D11Device & device) - : D3D11GpuProgram(creator, name, handle, group, isManual, loader, device) - , mDomainShader(NULL) - { - mType = GPT_DOMAIN_PROGRAM; - } - //----------------------------------------------------------------------------- - D3D11GpuDomainProgram::~D3D11GpuDomainProgram() - { - // have to call this here reather than in Resource destructor - // since calling virtual methods in base destructors causes crash - unload(); - } - //----------------------------------------------------------------------------- - void D3D11GpuDomainProgram::loadFromMicrocode(ID3D10Blob * microcode) - { - if (isSupported()) - { - // Create the shader - HRESULT hr = mDevice->CreateDomainShader( - static_cast(microcode->GetBufferPointer()), - microcode->GetBufferSize(), - NULL, - &mDomainShader); + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D11 geometry shader " + mName + " from microcode.\nError Description:" + errorDescription, + "D3D11GpuGeometryProgram::loadFromMicrocode"); + } + } + else + { + LogManager::getSingleton().logMessage( + "Unsupported D3D11 geometry shader '" + mName + "' was not loaded."); + } + } + //----------------------------------------------------------------------------- + void D3D11GpuGeometryProgram::unloadImpl(void) + { + SAFE_RELEASE(mGeometryShader); + } + //----------------------------------------------------------------------------- + ID3D11GeometryShader * D3D11GpuGeometryProgram::getGeometryShader( void ) const + { + return mGeometryShader; + } + //----------------------------------------------------------------------------- + D3D11GpuDomainProgram::D3D11GpuDomainProgram(ResourceManager* creator, + const String& name, ResourceHandle handle, const String& group, + bool isManual, ManualResourceLoader* loader, D3D11Device & device) + : D3D11GpuProgram(creator, name, handle, group, isManual, loader, device) + , mDomainShader(NULL) + { + mType = GPT_DOMAIN_PROGRAM; + } + //----------------------------------------------------------------------------- + D3D11GpuDomainProgram::~D3D11GpuDomainProgram() + { + // have to call this here reather than in Resource destructor + // since calling virtual methods in base destructors causes crash + unload(); + } + //----------------------------------------------------------------------------- + void D3D11GpuDomainProgram::loadFromMicrocode(ID3D10Blob * microcode) + { + if (isSupported()) + { + // Create the shader + HRESULT hr = mDevice->CreateDomainShader( + static_cast(microcode->GetBufferPointer()), + microcode->GetBufferSize(), + NULL, + &mDomainShader); - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D11 domain shader " + mName + " from microcode.\nError Description:" + errorDescription, - "D3D11GpuFragmentProgram::loadFromMicrocode"); - } - } - else - { - LogManager::getSingleton().logMessage( - "Unsupported D3D11 domain shader '" + mName + "' was not loaded."); - } - } - //----------------------------------------------------------------------------- - void D3D11GpuDomainProgram::unloadImpl(void) - { - SAFE_RELEASE(mDomainShader); - } - //----------------------------------------------------------------------------- - ID3D11DomainShader * D3D11GpuDomainProgram::getDomainShader( void ) const - { - return mDomainShader; - } - //----------------------------------------------------------------------------- - D3D11GpuHullProgram::D3D11GpuHullProgram(ResourceManager* creator, - const String& name, ResourceHandle handle, const String& group, - bool isManual, ManualResourceLoader* loader, D3D11Device & device) - : D3D11GpuProgram(creator, name, handle, group, isManual, loader, device) - , mHullShader(NULL) - { - mType = GPT_HULL_PROGRAM; - } - //----------------------------------------------------------------------------- - D3D11GpuHullProgram::~D3D11GpuHullProgram() - { - // have to call this here reather than in Resource destructor - // since calling virtual methods in base destructors causes crash - unload(); - } - //----------------------------------------------------------------------------- - void D3D11GpuHullProgram::loadFromMicrocode(ID3D10Blob * microcode) - { - if (isSupported()) - { - // Create the shader - HRESULT hr = mDevice->CreateHullShader( - static_cast(microcode->GetBufferPointer()), - microcode->GetBufferSize(), - NULL, - &mHullShader); + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D11 domain shader " + mName + " from microcode.\nError Description:" + errorDescription, + "D3D11GpuFragmentProgram::loadFromMicrocode"); + } + } + else + { + LogManager::getSingleton().logMessage( + "Unsupported D3D11 domain shader '" + mName + "' was not loaded."); + } + } + //----------------------------------------------------------------------------- + void D3D11GpuDomainProgram::unloadImpl(void) + { + SAFE_RELEASE(mDomainShader); + } + //----------------------------------------------------------------------------- + ID3D11DomainShader * D3D11GpuDomainProgram::getDomainShader( void ) const + { + return mDomainShader; + } + //----------------------------------------------------------------------------- + D3D11GpuHullProgram::D3D11GpuHullProgram(ResourceManager* creator, + const String& name, ResourceHandle handle, const String& group, + bool isManual, ManualResourceLoader* loader, D3D11Device & device) + : D3D11GpuProgram(creator, name, handle, group, isManual, loader, device) + , mHullShader(NULL) + { + mType = GPT_HULL_PROGRAM; + } + //----------------------------------------------------------------------------- + D3D11GpuHullProgram::~D3D11GpuHullProgram() + { + // have to call this here reather than in Resource destructor + // since calling virtual methods in base destructors causes crash + unload(); + } + //----------------------------------------------------------------------------- + void D3D11GpuHullProgram::loadFromMicrocode(ID3D10Blob * microcode) + { + if (isSupported()) + { + // Create the shader + HRESULT hr = mDevice->CreateHullShader( + static_cast(microcode->GetBufferPointer()), + microcode->GetBufferSize(), + NULL, + &mHullShader); - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D11 hull shader " + mName + " from microcode.\nError Description:" + errorDescription, - "D3D11GpuFragmentProgram::loadFromMicrocode"); - } - } - else - { - LogManager::getSingleton().logMessage( - "Unsupported D3D11 hull shader '" + mName + "' was not loaded."); - } - } - //----------------------------------------------------------------------------- - void D3D11GpuHullProgram::unloadImpl(void) - { - SAFE_RELEASE(mHullShader); - } - //----------------------------------------------------------------------------- - ID3D11HullShader * D3D11GpuHullProgram::getHullShader( void ) const - { - return mHullShader; - } - //----------------------------------------------------------------------------- + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D11 hull shader " + mName + " from microcode.\nError Description:" + errorDescription, + "D3D11GpuFragmentProgram::loadFromMicrocode"); + } + } + else + { + LogManager::getSingleton().logMessage( + "Unsupported D3D11 hull shader '" + mName + "' was not loaded."); + } + } + //----------------------------------------------------------------------------- + void D3D11GpuHullProgram::unloadImpl(void) + { + SAFE_RELEASE(mHullShader); + } + //----------------------------------------------------------------------------- + ID3D11HullShader * D3D11GpuHullProgram::getHullShader( void ) const + { + return mHullShader; + } + //----------------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11GpuProgramManager.cpp b/RenderSystems/Direct3D11/src/OgreD3D11GpuProgramManager.cpp index ee799bf6a25..c4f37e522d5 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11GpuProgramManager.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11GpuProgramManager.cpp @@ -31,91 +31,91 @@ THE SOFTWARE. #include "OgreException.h" namespace Ogre { - //----------------------------------------------------------------------------- - D3D11GpuProgramManager::D3D11GpuProgramManager(D3D11Device & device) - :GpuProgramManager(), mDevice(device) - { - // Superclass sets up members + //----------------------------------------------------------------------------- + D3D11GpuProgramManager::D3D11GpuProgramManager(D3D11Device & device) + :GpuProgramManager(), mDevice(device) + { + // Superclass sets up members - // Register with resource group manager - ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); + // Register with resource group manager + ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); - } - //----------------------------------------------------------------------------- - D3D11GpuProgramManager::~D3D11GpuProgramManager() - { - // Unregister with resource group manager - ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); + } + //----------------------------------------------------------------------------- + D3D11GpuProgramManager::~D3D11GpuProgramManager() + { + // Unregister with resource group manager + ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); - } - //----------------------------------------------------------------------------- - Resource* D3D11GpuProgramManager::createImpl(const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, - const NameValuePairList* params) - { - NameValuePairList::const_iterator paramIt; + } + //----------------------------------------------------------------------------- + Resource* D3D11GpuProgramManager::createImpl(const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, + const NameValuePairList* params) + { + NameValuePairList::const_iterator paramIt; - if (!params || (paramIt = params->find("type")) == params->end()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "You must supply a 'type' parameter", - "D3D11GpuProgramManager::createImpl"); - } + if (!params || (paramIt = params->find("type")) == params->end()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "You must supply a 'type' parameter", + "D3D11GpuProgramManager::createImpl"); + } - if (paramIt->second == "vertex_program") - { - return new D3D11GpuVertexProgram(this, name, handle, group, - isManual, loader, mDevice); - } - else if (paramIt->second == "domain_program") - { - return new D3D11GpuDomainProgram(this, name, handle, group, - isManual, loader, mDevice); - } - else if (paramIt->second == "hull_program") - { - return new D3D11GpuHullProgram(this, name, handle, group, - isManual, loader, mDevice); - } - else if (paramIt->second == "geometry_program") - { - return new D3D11GpuGeometryProgram(this, name, handle, group, - isManual, loader, mDevice); - } - else - { - return new D3D11GpuFragmentProgram(this, name, handle, group, - isManual, loader, mDevice); - } - } - //----------------------------------------------------------------------------- - Resource* D3D11GpuProgramManager::createImpl(const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader, - GpuProgramType gptype, const String& syntaxCode) - { - if (gptype == GPT_VERTEX_PROGRAM) - { - return new D3D11GpuVertexProgram(this, name, handle, group, - isManual, loader, mDevice); - } - else if (gptype == GPT_DOMAIN_PROGRAM) - { - return new D3D11GpuDomainProgram(this, name, handle, group, - isManual, loader, mDevice); - } - else if (gptype == GPT_HULL_PROGRAM) - { - return new D3D11GpuHullProgram(this, name, handle, group, - isManual, loader, mDevice); - } - else if (gptype == GPT_GEOMETRY_PROGRAM) - { - return new D3D11GpuGeometryProgram(this, name, handle, group, - isManual, loader, mDevice); - } - { - return new D3D11GpuFragmentProgram(this, name, handle, group, - isManual, loader, mDevice); - } - } + if (paramIt->second == "vertex_program") + { + return new D3D11GpuVertexProgram(this, name, handle, group, + isManual, loader, mDevice); + } + else if (paramIt->second == "domain_program") + { + return new D3D11GpuDomainProgram(this, name, handle, group, + isManual, loader, mDevice); + } + else if (paramIt->second == "hull_program") + { + return new D3D11GpuHullProgram(this, name, handle, group, + isManual, loader, mDevice); + } + else if (paramIt->second == "geometry_program") + { + return new D3D11GpuGeometryProgram(this, name, handle, group, + isManual, loader, mDevice); + } + else + { + return new D3D11GpuFragmentProgram(this, name, handle, group, + isManual, loader, mDevice); + } + } + //----------------------------------------------------------------------------- + Resource* D3D11GpuProgramManager::createImpl(const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader, + GpuProgramType gptype, const String& syntaxCode) + { + if (gptype == GPT_VERTEX_PROGRAM) + { + return new D3D11GpuVertexProgram(this, name, handle, group, + isManual, loader, mDevice); + } + else if (gptype == GPT_DOMAIN_PROGRAM) + { + return new D3D11GpuDomainProgram(this, name, handle, group, + isManual, loader, mDevice); + } + else if (gptype == GPT_HULL_PROGRAM) + { + return new D3D11GpuHullProgram(this, name, handle, group, + isManual, loader, mDevice); + } + else if (gptype == GPT_GEOMETRY_PROGRAM) + { + return new D3D11GpuGeometryProgram(this, name, handle, group, + isManual, loader, mDevice); + } + { + return new D3D11GpuFragmentProgram(this, name, handle, group, + isManual, loader, mDevice); + } + } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp b/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp index 6d88f31532f..38de58f24ae 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgram.cpp @@ -66,39 +66,39 @@ namespace Ogre { "D3D11HLSLProgram::createConstantBuffer"); } } - //----------------------------------------------------------------------- - void D3D11HLSLProgram::fixVariableNameFromCg(const ShaderVarWithPosInBuf& newVar) - { - String varForSearch = String(" : : ") + newVar.name; - size_t startPosOfVarOrgNameInSource = 0; - size_t endPosOfVarOrgNameInSource = mSource.find(varForSearch + " "); - if(endPosOfVarOrgNameInSource == -1) - { - endPosOfVarOrgNameInSource = mSource.find(varForSearch + "["); - } - if(endPosOfVarOrgNameInSource != -1) - { - // find space before var; - for (size_t i = endPosOfVarOrgNameInSource - 1 ; i > 0 ; i-- ) - { - if (mSource[i] == ' ') - { - startPosOfVarOrgNameInSource = i + 1; - break; - } - } - if (startPosOfVarOrgNameInSource > 0) - { - newVar.name = mSource.substr(startPosOfVarOrgNameInSource, endPosOfVarOrgNameInSource - startPosOfVarOrgNameInSource); - } - } - - // hack for cg parameter with strange prefix - if (newVar.name.size() > 0 && newVar.name[0] == '_') - { - newVar.name.erase(0,1); - } - } + //----------------------------------------------------------------------- + void D3D11HLSLProgram::fixVariableNameFromCg(const ShaderVarWithPosInBuf& newVar) + { + String varForSearch = String(" : : ") + newVar.name; + size_t startPosOfVarOrgNameInSource = 0; + size_t endPosOfVarOrgNameInSource = mSource.find(varForSearch + " "); + if(endPosOfVarOrgNameInSource == -1) + { + endPosOfVarOrgNameInSource = mSource.find(varForSearch + "["); + } + if(endPosOfVarOrgNameInSource != -1) + { + // find space before var; + for (size_t i = endPosOfVarOrgNameInSource - 1 ; i > 0 ; i-- ) + { + if (mSource[i] == ' ') + { + startPosOfVarOrgNameInSource = i + 1; + break; + } + } + if (startPosOfVarOrgNameInSource > 0) + { + newVar.name = mSource.substr(startPosOfVarOrgNameInSource, endPosOfVarOrgNameInSource - startPosOfVarOrgNameInSource); + } + } + + // hack for cg parameter with strange prefix + if (newVar.name.size() > 0 && newVar.name[0] == '_') + { + newVar.name.erase(0,1); + } + } class HLSLIncludeHandler : public ID3DInclude @@ -150,76 +150,76 @@ namespace Ogre { defines.clear(); if (!stringBuffer.empty()) - { - // Split preprocessor defines and build up macro array - D3D_SHADER_MACRO macro; - String::size_type pos = 0; - while (pos != String::npos) - { - macro.Name = &stringBuffer[pos]; - macro.Definition = 0; - - String::size_type start_pos=pos; - - // Find delims - pos = stringBuffer.find_first_of(";,=", pos); - - if(start_pos==pos) - { - if(pos==stringBuffer.length()) - { - break; - } - pos++; - continue; - } - - if (pos != String::npos) - { - // Check definition part - if (stringBuffer[pos] == '=') - { - // Setup null character for macro name - stringBuffer[pos++] = '\0'; - macro.Definition = &stringBuffer[pos]; - pos = stringBuffer.find_first_of(";,", pos); - } - else - { - // No definition part, define as "1" - macro.Definition = "1"; - } - - if (pos != String::npos) - { - // Setup null character for macro name or definition - stringBuffer[pos++] = '\0'; - } - } - else - { - macro.Definition = "1"; - } - if(strlen(macro.Name)>0) - { - defines.push_back(macro); - } - else - { - break; - } - } - } - - //Add D3D11 define to all program, compiled with D3D11 RenderSystem - D3D_SHADER_MACRO macro = {"D3D11","1"}; - defines.push_back(macro); - - // Add NULL terminator - macro.Name = 0; - macro.Definition = 0; - defines.push_back(macro); - } + { + // Split preprocessor defines and build up macro array + D3D_SHADER_MACRO macro; + String::size_type pos = 0; + while (pos != String::npos) + { + macro.Name = &stringBuffer[pos]; + macro.Definition = 0; + + String::size_type start_pos=pos; + + // Find delims + pos = stringBuffer.find_first_of(";,=", pos); + + if(start_pos==pos) + { + if(pos==stringBuffer.length()) + { + break; + } + pos++; + continue; + } + + if (pos != String::npos) + { + // Check definition part + if (stringBuffer[pos] == '=') + { + // Setup null character for macro name + stringBuffer[pos++] = '\0'; + macro.Definition = &stringBuffer[pos]; + pos = stringBuffer.find_first_of(";,", pos); + } + else + { + // No definition part, define as "1" + macro.Definition = "1"; + } + + if (pos != String::npos) + { + // Setup null character for macro name or definition + stringBuffer[pos++] = '\0'; + } + } + else + { + macro.Definition = "1"; + } + if(strlen(macro.Name)>0) + { + defines.push_back(macro); + } + else + { + break; + } + } + } + + //Add D3D11 define to all program, compiled with D3D11 RenderSystem + D3D_SHADER_MACRO macro = {"D3D11","1"}; + defines.push_back(macro); + + // Add NULL terminator + macro.Name = 0; + macro.Definition = 0; + defines.push_back(macro); + } //----------------------------------------------------------------------- void D3D11HLSLProgram::loadFromSource(void) { @@ -238,46 +238,46 @@ namespace Ogre { GpuProgramManager::Microcode cacheMicrocode = GpuProgramManager::getSingleton().getMicrocodeFromCache(getNameForMicrocodeCache()); - cacheMicrocode->seek(0); + cacheMicrocode->seek(0); -#define READ_START(curlist, memberType) { \ - uint16 listSize = curlist.size(); \ - cacheMicrocode->read(&listSize, sizeof(uint16)); \ - if(listSize > 0){ \ - curlist.resize(listSize); \ - for(unsigned i = 0 ; i < curlist.size() ; i++){ \ - memberType & curItem = curlist[i]; +#define READ_START(curlist, memberType) { \ + uint16 listSize = curlist.size(); \ + cacheMicrocode->read(&listSize, sizeof(uint16)); \ + if(listSize > 0){ \ + curlist.resize(listSize); \ + for(unsigned i = 0 ; i < curlist.size() ; i++){ \ + memberType & curItem = curlist[i]; #define READ_END }}} -#define READ_UINT(member) { \ - uint32 tmpVal; \ - cacheMicrocode->read(&tmpVal, sizeof(uint32)); \ - curItem.member = tmpVal; \ - } - -#define READ_ENUM(member, enumType) { \ - uint32 tmpVal; \ - cacheMicrocode->read(&tmpVal, sizeof(uint32)); \ - curItem.member = (enumType)tmpVal; \ - } - -#define READ_BYTE(member) { \ - cacheMicrocode->read(&curItem.member, sizeof(BYTE)); \ - } - -#define READ_NAME(member) { \ - uint16 length = 0; \ - cacheMicrocode->read(&length, sizeof(uint16)); \ - curItem.member = ""; \ - if(length > 0) \ - { \ - String * inString = new String(); \ - inString->resize(length); \ - cacheMicrocode->read(&(*inString)[0], length); \ - mSerStrings.push_back(inString); \ - curItem.member = &(*inString)[0]; \ - } \ +#define READ_UINT(member) { \ + uint32 tmpVal; \ + cacheMicrocode->read(&tmpVal, sizeof(uint32)); \ + curItem.member = tmpVal; \ + } + +#define READ_ENUM(member, enumType) { \ + uint32 tmpVal; \ + cacheMicrocode->read(&tmpVal, sizeof(uint32)); \ + curItem.member = (enumType)tmpVal; \ + } + +#define READ_BYTE(member) { \ + cacheMicrocode->read(&curItem.member, sizeof(BYTE)); \ + } + +#define READ_NAME(member) { \ + uint16 length = 0; \ + cacheMicrocode->read(&length, sizeof(uint16)); \ + curItem.member = ""; \ + if(length > 0) \ + { \ + String * inString = new String(); \ + inString->resize(length); \ + cacheMicrocode->read(&(*inString)[0], length); \ + mSerStrings.push_back(inString); \ + curItem.member = &(*inString)[0]; \ + } \ } @@ -289,110 +289,110 @@ namespace Ogre { cacheMicrocode->read(&mConstantBufferSize, sizeof(uint32)); cacheMicrocode->read(&mConstantBufferNr, sizeof(uint32)); cacheMicrocode->read(&mNumSlots, sizeof(uint32)); - - READ_START(mD3d11ShaderInputParameters, D3D11_SIGNATURE_PARAMETER_DESC) - READ_NAME(SemanticName) - READ_UINT(SemanticIndex) - READ_UINT(Register) - READ_ENUM(SystemValueType,D3D_NAME) - READ_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) - READ_BYTE(Mask) - READ_BYTE(ReadWriteMask) - READ_UINT(Stream) -// READ_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK - READ_END - - READ_START(mD3d11ShaderOutputParameters, D3D11_SIGNATURE_PARAMETER_DESC) - READ_NAME(SemanticName) - READ_UINT(SemanticIndex) - READ_UINT(Register) - READ_ENUM(SystemValueType, D3D_NAME) - READ_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) - READ_BYTE(Mask) - READ_BYTE(ReadWriteMask) - READ_UINT(Stream) -// READ_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK - READ_END - - READ_START(mD3d11ShaderVariables, D3D11_SHADER_VARIABLE_DESC) - READ_NAME(Name) - READ_UINT(StartOffset) - READ_UINT(Size) - READ_UINT(uFlags) - //todo DefaultValue - READ_UINT(StartTexture) - READ_UINT(TextureSize) - READ_UINT(StartSampler) - READ_UINT(SamplerSize) - READ_END - - READ_START(mD3d11ShaderVariableSubparts, GpuConstantDefinitionWithName) - READ_NAME(Name) - READ_ENUM(constType, GpuConstantType) - READ_UINT(physicalIndex) - READ_UINT(logicalIndex) - READ_UINT(elementSize) - READ_UINT(arraySize) - READ_UINT(variability) - READ_END - - READ_START(mD3d11ShaderBufferDescs, D3D11_SHADER_BUFFER_DESC) - READ_NAME(Name) - READ_ENUM(Type, D3D_CBUFFER_TYPE) - READ_UINT(Variables) - READ_UINT(Size) - READ_UINT(uFlags) - READ_END - - READ_START(mVarDescBuffer, D3D11_SHADER_VARIABLE_DESC) - READ_NAME(Name) - READ_UINT(StartOffset) - READ_UINT(Size) - READ_UINT(uFlags) - //todo DefaultValue - READ_UINT(StartTexture) - READ_UINT(TextureSize) - READ_UINT(StartSampler) - READ_UINT(SamplerSize) - READ_END - - READ_START(mVarDescPointer, D3D11_SHADER_VARIABLE_DESC) - READ_NAME(Name) - READ_UINT(StartOffset) - READ_UINT(Size) - READ_UINT(uFlags) - //todo DefaultValue - READ_UINT(StartTexture) - READ_UINT(TextureSize) - READ_UINT(StartSampler) - READ_UINT(SamplerSize) - READ_END - - READ_START(mD3d11ShaderTypeDescs, D3D11_SHADER_TYPE_DESC) - READ_NAME(Name) - READ_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) - READ_UINT(Rows) - READ_UINT(Columns) - READ_UINT(Elements) - READ_UINT(Members) - READ_UINT(Offset) - READ_END - - READ_START(mMemberTypeDesc, D3D11_SHADER_TYPE_DESC) - READ_NAME(Name) - READ_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) - READ_UINT(Rows) - READ_UINT(Columns) - READ_UINT(Elements) - READ_UINT(Members) - READ_UINT(Offset) - READ_END - - READ_START(mMemberTypeName, MemberTypeName) - READ_NAME(Name) - READ_END - - uint16 mInterfaceSlotsSize = 0; + + READ_START(mD3d11ShaderInputParameters, D3D11_SIGNATURE_PARAMETER_DESC) + READ_NAME(SemanticName) + READ_UINT(SemanticIndex) + READ_UINT(Register) + READ_ENUM(SystemValueType,D3D_NAME) + READ_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) + READ_BYTE(Mask) + READ_BYTE(ReadWriteMask) + READ_UINT(Stream) +// READ_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK + READ_END + + READ_START(mD3d11ShaderOutputParameters, D3D11_SIGNATURE_PARAMETER_DESC) + READ_NAME(SemanticName) + READ_UINT(SemanticIndex) + READ_UINT(Register) + READ_ENUM(SystemValueType, D3D_NAME) + READ_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) + READ_BYTE(Mask) + READ_BYTE(ReadWriteMask) + READ_UINT(Stream) +// READ_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK + READ_END + + READ_START(mD3d11ShaderVariables, D3D11_SHADER_VARIABLE_DESC) + READ_NAME(Name) + READ_UINT(StartOffset) + READ_UINT(Size) + READ_UINT(uFlags) + //todo DefaultValue + READ_UINT(StartTexture) + READ_UINT(TextureSize) + READ_UINT(StartSampler) + READ_UINT(SamplerSize) + READ_END + + READ_START(mD3d11ShaderVariableSubparts, GpuConstantDefinitionWithName) + READ_NAME(Name) + READ_ENUM(constType, GpuConstantType) + READ_UINT(physicalIndex) + READ_UINT(logicalIndex) + READ_UINT(elementSize) + READ_UINT(arraySize) + READ_UINT(variability) + READ_END + + READ_START(mD3d11ShaderBufferDescs, D3D11_SHADER_BUFFER_DESC) + READ_NAME(Name) + READ_ENUM(Type, D3D_CBUFFER_TYPE) + READ_UINT(Variables) + READ_UINT(Size) + READ_UINT(uFlags) + READ_END + + READ_START(mVarDescBuffer, D3D11_SHADER_VARIABLE_DESC) + READ_NAME(Name) + READ_UINT(StartOffset) + READ_UINT(Size) + READ_UINT(uFlags) + //todo DefaultValue + READ_UINT(StartTexture) + READ_UINT(TextureSize) + READ_UINT(StartSampler) + READ_UINT(SamplerSize) + READ_END + + READ_START(mVarDescPointer, D3D11_SHADER_VARIABLE_DESC) + READ_NAME(Name) + READ_UINT(StartOffset) + READ_UINT(Size) + READ_UINT(uFlags) + //todo DefaultValue + READ_UINT(StartTexture) + READ_UINT(TextureSize) + READ_UINT(StartSampler) + READ_UINT(SamplerSize) + READ_END + + READ_START(mD3d11ShaderTypeDescs, D3D11_SHADER_TYPE_DESC) + READ_NAME(Name) + READ_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) + READ_UINT(Rows) + READ_UINT(Columns) + READ_UINT(Elements) + READ_UINT(Members) + READ_UINT(Offset) + READ_END + + READ_START(mMemberTypeDesc, D3D11_SHADER_TYPE_DESC) + READ_NAME(Name) + READ_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) + READ_UINT(Rows) + READ_UINT(Columns) + READ_UINT(Elements) + READ_UINT(Members) + READ_UINT(Offset) + READ_END + + READ_START(mMemberTypeName, MemberTypeName) + READ_NAME(Name) + READ_END + + uint16 mInterfaceSlotsSize = 0; cacheMicrocode->read(&mInterfaceSlotsSize, sizeof(uint16)); if(mInterfaceSlotsSize > 0) { @@ -406,9 +406,9 @@ namespace Ogre { //----------------------------------------------------------------------- void D3D11HLSLProgram::compileMicrocode(void) { - // If we are running from the cache, we should not be trying to compile/reflect on shaders. + // If we are running from the cache, we should not be trying to compile/reflect on shaders. #if defined(ENABLE_SHADERS_CACHE_LOAD) && (ENABLE_SHADERS_CACHE_LOAD == 1) - String message = "Cannot assemble/reflect D3D11 shader: " + mName + " in shipping code\n"; + String message = "Cannot assemble/reflect D3D11 shader: " + mName + " in shipping code\n"; OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, message, "D3D11HLSLProgram::compileMicrocode"); #else @@ -464,17 +464,17 @@ namespace Ogre { HRESULT hr = D3DCompile( - mSource.c_str(), // [in] Pointer to the shader in memory. - mSource.size(), // [in] Size of the shader in memory. - NULL, // [in] The name of the file that contains the shader code. - pDefines, // [in] Optional. Pointer to a NULL-terminated array of macro definitions. See D3D_SHADER_MACRO. If not used, set this to NULL. - &includeHandler, // [in] Optional. Pointer to an ID3DInclude Interface interface for handling include files. Setting this to NULL will cause a compile error if a shader contains a #include. + mSource.c_str(), // [in] Pointer to the shader in memory. + mSource.size(), // [in] Size of the shader in memory. + NULL, // [in] The name of the file that contains the shader code. + pDefines, // [in] Optional. Pointer to a NULL-terminated array of macro definitions. See D3D_SHADER_MACRO. If not used, set this to NULL. + &includeHandler, // [in] Optional. Pointer to an ID3DInclude Interface interface for handling include files. Setting this to NULL will cause a compile error if a shader contains a #include. mEntryPoint.c_str(),// [in] Name of the shader-entrypoint function where shader execution begins. - target, // [in] A string that specifies the shader model; can be any profile in shader model 4 or higher. - compileFlags, // [in] Effect compile flags - no D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY at the first try... - NULL, // [in] Effect compile flags - &pMicroCode, // [out] A pointer to an ID3DBlob Interface which contains the compiled shader, as well as any embedded debug and symbol-table information. - &errors // [out] A pointer to an ID3DBlob Interface which contains a listing of errors and warnings that occurred during compilation. These errors and warnings are identical to the the debug output from a debugger. + target, // [in] A string that specifies the shader model; can be any profile in shader model 4 or higher. + compileFlags, // [in] Effect compile flags - no D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY at the first try... + NULL, // [in] Effect compile flags + &pMicroCode, // [out] A pointer to an ID3DBlob Interface which contains the compiled shader, as well as any embedded debug and symbol-table information. + &errors // [out] A pointer to an ID3DBlob Interface which contains a listing of errors and warnings that occurred during compilation. These errors and warnings are identical to the the debug output from a debugger. ); #if 0 // this is how you disassemble @@ -554,106 +554,106 @@ namespace Ogre { mSerStrings.push_back(name); curParam.SemanticName = &(*name)[0]; } - /* + /* if (shaderDesc.ConstantBuffers > 1) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Multi constant buffers are not supported for now.", "D3D11HLSLProgram::loadFromSource"); }*/ - - mConstantBufferNr = shaderDesc.ConstantBuffers; - mNumSlots = shaderReflection->GetNumInterfaceSlots(); + + mConstantBufferNr = shaderDesc.ConstantBuffers; + mNumSlots = shaderReflection->GetNumInterfaceSlots(); if (shaderDesc.ConstantBuffers > 0) { - for (unsigned int v=0; v < shaderDesc.ConstantBuffers; v++) - { - ID3D11ShaderReflectionConstantBuffer* shaderReflectionConstantBuffer; - shaderReflectionConstantBuffer = shaderReflection->GetConstantBufferByIndex(v); - - D3D11_SHADER_BUFFER_DESC constantBufferDesc; - hr = shaderReflectionConstantBuffer->GetDesc(&constantBufferDesc); - if (FAILED(hr)) - { - String message = "Cannot reflect constant buffer of D3D11 high-level shader " + mName + " Errors:\n" + - static_cast(errors->GetBufferPointer()); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message, - "D3D11HLSLProgram::loadFromSource"); - } + for (unsigned int v=0; v < shaderDesc.ConstantBuffers; v++) + { + ID3D11ShaderReflectionConstantBuffer* shaderReflectionConstantBuffer; + shaderReflectionConstantBuffer = shaderReflection->GetConstantBufferByIndex(v); + + D3D11_SHADER_BUFFER_DESC constantBufferDesc; + hr = shaderReflectionConstantBuffer->GetDesc(&constantBufferDesc); + if (FAILED(hr)) + { + String message = "Cannot reflect constant buffer of D3D11 high-level shader " + mName + " Errors:\n" + + static_cast(errors->GetBufferPointer()); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message, + "D3D11HLSLProgram::loadFromSource"); + } String * name = new String(constantBufferDesc.Name); mSerStrings.push_back(name); constantBufferDesc.Name = &(*name)[0]; - mD3d11ShaderBufferDescs.push_back(constantBufferDesc); - - mConstantBufferSize += constantBufferDesc.Size; - if (v == 0) - mD3d11ShaderVariables.resize(constantBufferDesc.Variables); - else - mD3d11ShaderVariables.resize(mD3d11ShaderVariables.size() + constantBufferDesc.Variables); - - for(unsigned int i = 0; i < constantBufferDesc.Variables ; i++) - { - D3D11_SHADER_VARIABLE_DESC & curVar = mD3d11ShaderVariables[i]; - ID3D11ShaderReflectionVariable* varRef; - varRef = shaderReflectionConstantBuffer->GetVariableByIndex(i); - HRESULT hr = varRef->GetDesc(&curVar); - if (FAILED(hr)) - { - String message = "Cannot reflect constant buffer variable of D3D11 high-level shader " + mName + " Errors:\n" + - static_cast(errors->GetBufferPointer()); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message, - "D3D11HLSLProgram::loadFromSource"); - } - - String * name = new String(curVar.Name); - mSerStrings.push_back(name); - curVar.Name = &(*name)[0]; - - ID3D11ShaderReflectionType* varRefType; - varRefType = varRef->GetType(); - - // Recursively descend through the structure levels - processParamElement( "", curVar.Name, varRefType); - } - - switch (constantBufferDesc.Type) - { - case D3D_CT_INTERFACE_POINTERS: - { - for(UINT k = 0; k < constantBufferDesc.Variables; k++) - { - D3D11_SHADER_VARIABLE_DESC varDesc; - ID3D11ShaderReflectionVariable* var = shaderReflectionConstantBuffer->GetVariableByIndex(k); - var->GetDesc(&varDesc); + mD3d11ShaderBufferDescs.push_back(constantBufferDesc); + + mConstantBufferSize += constantBufferDesc.Size; + if (v == 0) + mD3d11ShaderVariables.resize(constantBufferDesc.Variables); + else + mD3d11ShaderVariables.resize(mD3d11ShaderVariables.size() + constantBufferDesc.Variables); + + for(unsigned int i = 0; i < constantBufferDesc.Variables ; i++) + { + D3D11_SHADER_VARIABLE_DESC & curVar = mD3d11ShaderVariables[i]; + ID3D11ShaderReflectionVariable* varRef; + varRef = shaderReflectionConstantBuffer->GetVariableByIndex(i); + HRESULT hr = varRef->GetDesc(&curVar); + if (FAILED(hr)) + { + String message = "Cannot reflect constant buffer variable of D3D11 high-level shader " + mName + " Errors:\n" + + static_cast(errors->GetBufferPointer()); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message, + "D3D11HLSLProgram::loadFromSource"); + } + + String * name = new String(curVar.Name); + mSerStrings.push_back(name); + curVar.Name = &(*name)[0]; + + ID3D11ShaderReflectionType* varRefType; + varRefType = varRef->GetType(); + + // Recursively descend through the structure levels + processParamElement( "", curVar.Name, varRefType); + } + + switch (constantBufferDesc.Type) + { + case D3D_CT_INTERFACE_POINTERS: + { + for(UINT k = 0; k < constantBufferDesc.Variables; k++) + { + D3D11_SHADER_VARIABLE_DESC varDesc; + ID3D11ShaderReflectionVariable* var = shaderReflectionConstantBuffer->GetVariableByIndex(k); + var->GetDesc(&varDesc); String * name = new String(varDesc.Name); mSerStrings.push_back(name); varDesc.Name = &(*name)[0]; - mVarDescPointer.push_back(varDesc); - mInterfaceSlots.push_back(var->GetInterfaceSlot(0)); - } - } - break; - case D3D_CT_CBUFFER: - case D3D_CT_TBUFFER: - { - for(unsigned int k = 0; k < constantBufferDesc.Variables ; k++) - { - D3D11_SHADER_VARIABLE_DESC varDesc; - ID3D11ShaderReflectionVariable* varRef = shaderReflectionConstantBuffer->GetVariableByIndex(k); - varRef->GetDesc(&varDesc); + mVarDescPointer.push_back(varDesc); + mInterfaceSlots.push_back(var->GetInterfaceSlot(0)); + } + } + break; + case D3D_CT_CBUFFER: + case D3D_CT_TBUFFER: + { + for(unsigned int k = 0; k < constantBufferDesc.Variables ; k++) + { + D3D11_SHADER_VARIABLE_DESC varDesc; + ID3D11ShaderReflectionVariable* varRef = shaderReflectionConstantBuffer->GetVariableByIndex(k); + varRef->GetDesc(&varDesc); String * name = new String(varDesc.Name); mSerStrings.push_back(name); varDesc.Name = &(*name)[0]; - mVarDescBuffer.push_back(varDesc); - - // Only parse if variable is used - if (varDesc.uFlags & D3D_SVF_USED) - { - D3D11_SHADER_TYPE_DESC varTypeDesc; - ID3D11ShaderReflectionType* varType = varRef->GetType(); - varType->GetDesc(&varTypeDesc); + mVarDescBuffer.push_back(varDesc); + + // Only parse if variable is used + if (varDesc.uFlags & D3D_SVF_USED) + { + D3D11_SHADER_TYPE_DESC varTypeDesc; + ID3D11ShaderReflectionType* varType = varRef->GetType(); + varType->GetDesc(&varTypeDesc); if(varTypeDesc.Name == NULL) { mSerStrings.push_back(new String()); @@ -668,14 +668,14 @@ namespace Ogre { mD3d11ShaderTypeDescs.push_back(varTypeDesc); - if (varTypeDesc.Class == D3D_SVC_STRUCT) - { - const UINT parentOffset = varDesc.StartOffset; - for(UINT m = 0; m < varTypeDesc.Members; m++) - { - D3D11_SHADER_TYPE_DESC memberTypeDesc; - ID3D11ShaderReflectionType* memberType = varType->GetMemberTypeByIndex(m); - memberType->GetDesc(&memberTypeDesc); + if (varTypeDesc.Class == D3D_SVC_STRUCT) + { + const UINT parentOffset = varDesc.StartOffset; + for(UINT m = 0; m < varTypeDesc.Members; m++) + { + D3D11_SHADER_TYPE_DESC memberTypeDesc; + ID3D11ShaderReflectionType* memberType = varType->GetMemberTypeByIndex(m); + memberType->GetDesc(&memberTypeDesc); { String * name = new String(memberTypeDesc.Name); @@ -691,13 +691,13 @@ namespace Ogre { mMemberTypeName.push_back(memberTypeName); } - } - } - } - } - } - } - } + } + } + } + } + } + } + } } SAFE_RELEASE(shaderReflection); @@ -709,7 +709,7 @@ namespace Ogre { #define SIZE_OF_DATA_END ) #define SIZE_OF_DATA_UINT(member) + sizeof(uint32) -#define SIZE_OF_DATA_ENUM(member, memberType) SIZE_OF_DATA_UINT(member) +#define SIZE_OF_DATA_ENUM(member, memberType) SIZE_OF_DATA_UINT(member) #define SIZE_OF_DATA_BYTE(member) + sizeof(BYTE) @@ -741,107 +741,107 @@ namespace Ogre { + sizeof(uint32) // mConstantBufferSize + sizeof(uint32) // mConstantBufferNr + sizeof(uint32) // mNumSlots - SIZE_OF_DATA_START(mD3d11ShaderInputParameters, D3D11_SIGNATURE_PARAMETER_DESC) - SIZE_OF_DATA_NAME(SemanticName) - SIZE_OF_DATA_UINT(SemanticIndex) - SIZE_OF_DATA_UINT(Register) - SIZE_OF_DATA_ENUM(SystemValueType,D3D_NAME) - SIZE_OF_DATA_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) - SIZE_OF_DATA_BYTE(Mask) - SIZE_OF_DATA_BYTE(ReadWriteMask) - SIZE_OF_DATA_UINT(Stream) -// SIZE_OF_DATA_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK - SIZE_OF_DATA_END - - SIZE_OF_DATA_START(mD3d11ShaderOutputParameters, D3D11_SIGNATURE_PARAMETER_DESC) - SIZE_OF_DATA_NAME(SemanticName) - SIZE_OF_DATA_UINT(SemanticIndex) - SIZE_OF_DATA_UINT(Register) - SIZE_OF_DATA_ENUM(SystemValueType, D3D_NAME) - SIZE_OF_DATA_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) - SIZE_OF_DATA_BYTE(Mask) - SIZE_OF_DATA_BYTE(ReadWriteMask) - SIZE_OF_DATA_UINT(Stream) -// SIZE_OF_DATA_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK - SIZE_OF_DATA_END - - SIZE_OF_DATA_START(mD3d11ShaderVariables, D3D11_SHADER_VARIABLE_DESC) - SIZE_OF_DATA_NAME(Name) - SIZE_OF_DATA_UINT(StartOffset) - SIZE_OF_DATA_UINT(Size) - SIZE_OF_DATA_UINT(uFlags) - //todo DefaultValue - SIZE_OF_DATA_UINT(StartTexture) - SIZE_OF_DATA_UINT(TextureSize) - SIZE_OF_DATA_UINT(StartSampler) - SIZE_OF_DATA_UINT(SamplerSize) - SIZE_OF_DATA_END - - SIZE_OF_DATA_START(mD3d11ShaderVariableSubparts, GpuConstantDefinitionWithName) - SIZE_OF_DATA_NAME(Name) - SIZE_OF_DATA_ENUM(constType, GpuConstantType) - SIZE_OF_DATA_UINT(physicalIndex) - SIZE_OF_DATA_UINT(logicalIndex) - SIZE_OF_DATA_UINT(elementSize) - SIZE_OF_DATA_UINT(arraySize) - SIZE_OF_DATA_UINT(variability) - SIZE_OF_DATA_END - - SIZE_OF_DATA_START(mD3d11ShaderBufferDescs, D3D11_SHADER_BUFFER_DESC) - SIZE_OF_DATA_NAME(Name) - SIZE_OF_DATA_ENUM(Type, D3D_CBUFFER_TYPE) - SIZE_OF_DATA_UINT(Variables) - SIZE_OF_DATA_UINT(Size) - SIZE_OF_DATA_UINT(uFlags) - SIZE_OF_DATA_END - - SIZE_OF_DATA_START(mVarDescBuffer, D3D11_SHADER_VARIABLE_DESC) - SIZE_OF_DATA_NAME(Name) - SIZE_OF_DATA_UINT(StartOffset) - SIZE_OF_DATA_UINT(Size) - SIZE_OF_DATA_UINT(uFlags) - //todo DefaultValue - SIZE_OF_DATA_UINT(StartTexture) - SIZE_OF_DATA_UINT(TextureSize) - SIZE_OF_DATA_UINT(StartSampler) - SIZE_OF_DATA_UINT(SamplerSize) - SIZE_OF_DATA_END - - SIZE_OF_DATA_START(mVarDescPointer, D3D11_SHADER_VARIABLE_DESC) - SIZE_OF_DATA_NAME(Name) - SIZE_OF_DATA_UINT(StartOffset) - SIZE_OF_DATA_UINT(Size) - SIZE_OF_DATA_UINT(uFlags) - //todo DefaultValue - SIZE_OF_DATA_UINT(StartTexture) - SIZE_OF_DATA_UINT(TextureSize) - SIZE_OF_DATA_UINT(StartSampler) - SIZE_OF_DATA_UINT(SamplerSize) - SIZE_OF_DATA_END - - SIZE_OF_DATA_START(mD3d11ShaderTypeDescs, D3D11_SHADER_TYPE_DESC) - SIZE_OF_DATA_NAME(Name) - SIZE_OF_DATA_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) - SIZE_OF_DATA_UINT(Rows) - SIZE_OF_DATA_UINT(Columns) - SIZE_OF_DATA_UINT(Elements) - SIZE_OF_DATA_UINT(Members) - SIZE_OF_DATA_UINT(Offset) - SIZE_OF_DATA_END - - SIZE_OF_DATA_START(mMemberTypeDesc, D3D11_SHADER_TYPE_DESC) - SIZE_OF_DATA_NAME(Name) - SIZE_OF_DATA_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) - SIZE_OF_DATA_UINT(Rows) - SIZE_OF_DATA_UINT(Columns) - SIZE_OF_DATA_UINT(Elements) - SIZE_OF_DATA_UINT(Members) - SIZE_OF_DATA_UINT(Offset) - SIZE_OF_DATA_END - - SIZE_OF_DATA_START(mMemberTypeName, MemberTypeName) - SIZE_OF_DATA_NAME(Name) - SIZE_OF_DATA_END + SIZE_OF_DATA_START(mD3d11ShaderInputParameters, D3D11_SIGNATURE_PARAMETER_DESC) + SIZE_OF_DATA_NAME(SemanticName) + SIZE_OF_DATA_UINT(SemanticIndex) + SIZE_OF_DATA_UINT(Register) + SIZE_OF_DATA_ENUM(SystemValueType,D3D_NAME) + SIZE_OF_DATA_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) + SIZE_OF_DATA_BYTE(Mask) + SIZE_OF_DATA_BYTE(ReadWriteMask) + SIZE_OF_DATA_UINT(Stream) +// SIZE_OF_DATA_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK + SIZE_OF_DATA_END + + SIZE_OF_DATA_START(mD3d11ShaderOutputParameters, D3D11_SIGNATURE_PARAMETER_DESC) + SIZE_OF_DATA_NAME(SemanticName) + SIZE_OF_DATA_UINT(SemanticIndex) + SIZE_OF_DATA_UINT(Register) + SIZE_OF_DATA_ENUM(SystemValueType, D3D_NAME) + SIZE_OF_DATA_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) + SIZE_OF_DATA_BYTE(Mask) + SIZE_OF_DATA_BYTE(ReadWriteMask) + SIZE_OF_DATA_UINT(Stream) +// SIZE_OF_DATA_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK + SIZE_OF_DATA_END + + SIZE_OF_DATA_START(mD3d11ShaderVariables, D3D11_SHADER_VARIABLE_DESC) + SIZE_OF_DATA_NAME(Name) + SIZE_OF_DATA_UINT(StartOffset) + SIZE_OF_DATA_UINT(Size) + SIZE_OF_DATA_UINT(uFlags) + //todo DefaultValue + SIZE_OF_DATA_UINT(StartTexture) + SIZE_OF_DATA_UINT(TextureSize) + SIZE_OF_DATA_UINT(StartSampler) + SIZE_OF_DATA_UINT(SamplerSize) + SIZE_OF_DATA_END + + SIZE_OF_DATA_START(mD3d11ShaderVariableSubparts, GpuConstantDefinitionWithName) + SIZE_OF_DATA_NAME(Name) + SIZE_OF_DATA_ENUM(constType, GpuConstantType) + SIZE_OF_DATA_UINT(physicalIndex) + SIZE_OF_DATA_UINT(logicalIndex) + SIZE_OF_DATA_UINT(elementSize) + SIZE_OF_DATA_UINT(arraySize) + SIZE_OF_DATA_UINT(variability) + SIZE_OF_DATA_END + + SIZE_OF_DATA_START(mD3d11ShaderBufferDescs, D3D11_SHADER_BUFFER_DESC) + SIZE_OF_DATA_NAME(Name) + SIZE_OF_DATA_ENUM(Type, D3D_CBUFFER_TYPE) + SIZE_OF_DATA_UINT(Variables) + SIZE_OF_DATA_UINT(Size) + SIZE_OF_DATA_UINT(uFlags) + SIZE_OF_DATA_END + + SIZE_OF_DATA_START(mVarDescBuffer, D3D11_SHADER_VARIABLE_DESC) + SIZE_OF_DATA_NAME(Name) + SIZE_OF_DATA_UINT(StartOffset) + SIZE_OF_DATA_UINT(Size) + SIZE_OF_DATA_UINT(uFlags) + //todo DefaultValue + SIZE_OF_DATA_UINT(StartTexture) + SIZE_OF_DATA_UINT(TextureSize) + SIZE_OF_DATA_UINT(StartSampler) + SIZE_OF_DATA_UINT(SamplerSize) + SIZE_OF_DATA_END + + SIZE_OF_DATA_START(mVarDescPointer, D3D11_SHADER_VARIABLE_DESC) + SIZE_OF_DATA_NAME(Name) + SIZE_OF_DATA_UINT(StartOffset) + SIZE_OF_DATA_UINT(Size) + SIZE_OF_DATA_UINT(uFlags) + //todo DefaultValue + SIZE_OF_DATA_UINT(StartTexture) + SIZE_OF_DATA_UINT(TextureSize) + SIZE_OF_DATA_UINT(StartSampler) + SIZE_OF_DATA_UINT(SamplerSize) + SIZE_OF_DATA_END + + SIZE_OF_DATA_START(mD3d11ShaderTypeDescs, D3D11_SHADER_TYPE_DESC) + SIZE_OF_DATA_NAME(Name) + SIZE_OF_DATA_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) + SIZE_OF_DATA_UINT(Rows) + SIZE_OF_DATA_UINT(Columns) + SIZE_OF_DATA_UINT(Elements) + SIZE_OF_DATA_UINT(Members) + SIZE_OF_DATA_UINT(Offset) + SIZE_OF_DATA_END + + SIZE_OF_DATA_START(mMemberTypeDesc, D3D11_SHADER_TYPE_DESC) + SIZE_OF_DATA_NAME(Name) + SIZE_OF_DATA_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) + SIZE_OF_DATA_UINT(Rows) + SIZE_OF_DATA_UINT(Columns) + SIZE_OF_DATA_UINT(Elements) + SIZE_OF_DATA_UINT(Members) + SIZE_OF_DATA_UINT(Offset) + SIZE_OF_DATA_END + + SIZE_OF_DATA_START(mMemberTypeName, MemberTypeName) + SIZE_OF_DATA_NAME(Name) + SIZE_OF_DATA_END + inputNamesSize @@ -864,28 +864,28 @@ namespace Ogre { GpuProgramManager::getSingleton().createMicrocode(sizeOfData); -#define WRITE_START(curlist, memberType) { \ - uint16 listSize = curlist.size(); \ - newMicrocode->write(&listSize, sizeof(uint16)); \ - if(listSize > 0){ \ - for(unsigned i = 0 ; i < curlist.size() ; i++){ \ - memberType & curItem = curlist[i]; +#define WRITE_START(curlist, memberType) { \ + uint16 listSize = curlist.size(); \ + newMicrocode->write(&listSize, sizeof(uint16)); \ + if(listSize > 0){ \ + for(unsigned i = 0 ; i < curlist.size() ; i++){ \ + memberType & curItem = curlist[i]; #define WRITE_END }}} -#define WRITE_UINT(member) { \ - uint32 tmpVal; \ - tmpVal = (uint32)curItem.member; \ - newMicrocode->write(&tmpVal, sizeof(uint32)); \ - } +#define WRITE_UINT(member) { \ + uint32 tmpVal; \ + tmpVal = (uint32)curItem.member; \ + newMicrocode->write(&tmpVal, sizeof(uint32)); \ + } -#define WRITE_ENUM(member, memberType) WRITE_UINT(member) +#define WRITE_ENUM(member, memberType) WRITE_UINT(member) -#define WRITE_BYTE(member) { \ - newMicrocode->write(&curItem.member, sizeof(BYTE)); \ - } +#define WRITE_BYTE(member) { \ + newMicrocode->write(&curItem.member, sizeof(BYTE)); \ + } -#define WRITE_NAME(member) { \ +#define WRITE_NAME(member) { \ uint16 length = 0; \ if(curItem.member != NULL) \ length = strlen(curItem.member); \ @@ -902,111 +902,111 @@ namespace Ogre { newMicrocode->write(&mConstantBufferNr, sizeof(uint32)); newMicrocode->write(&mNumSlots, sizeof(uint32)); - WRITE_START(mD3d11ShaderInputParameters, D3D11_SIGNATURE_PARAMETER_DESC) - WRITE_NAME(SemanticName) - WRITE_UINT(SemanticIndex) - WRITE_UINT(Register) - WRITE_ENUM(SystemValueType,D3D_NAME) - WRITE_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) - WRITE_BYTE(Mask) - WRITE_BYTE(ReadWriteMask) - WRITE_UINT(Stream) -// WRITE_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK - WRITE_END - - WRITE_START(mD3d11ShaderOutputParameters, D3D11_SIGNATURE_PARAMETER_DESC) - WRITE_NAME(SemanticName) - WRITE_UINT(SemanticIndex) - WRITE_UINT(Register) - WRITE_ENUM(SystemValueType, D3D_NAME) - WRITE_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) - WRITE_BYTE(Mask) - WRITE_BYTE(ReadWriteMask) - WRITE_UINT(Stream) -// WRITE_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK - WRITE_END - - WRITE_START(mD3d11ShaderVariables, D3D11_SHADER_VARIABLE_DESC) - WRITE_NAME(Name) - WRITE_UINT(StartOffset) - WRITE_UINT(Size) - WRITE_UINT(uFlags) - //todo DefaultValue - WRITE_UINT(StartTexture) - WRITE_UINT(TextureSize) - WRITE_UINT(StartSampler) - WRITE_UINT(SamplerSize) - WRITE_END - - WRITE_START(mD3d11ShaderVariableSubparts, GpuConstantDefinitionWithName) - WRITE_NAME(Name) - WRITE_ENUM(constType, GpuConstantType) - WRITE_UINT(physicalIndex) - WRITE_UINT(logicalIndex) - WRITE_UINT(elementSize) - WRITE_UINT(arraySize) - WRITE_UINT(variability) - WRITE_END - - WRITE_START(mD3d11ShaderBufferDescs, D3D11_SHADER_BUFFER_DESC) - WRITE_NAME(Name) - WRITE_ENUM(Type, D3D_CBUFFER_TYPE) - WRITE_UINT(Variables) - WRITE_UINT(Size) - WRITE_UINT(uFlags) - WRITE_END - - WRITE_START(mVarDescBuffer, D3D11_SHADER_VARIABLE_DESC) - WRITE_NAME(Name) - WRITE_UINT(StartOffset) - WRITE_UINT(Size) - WRITE_UINT(uFlags) - //todo DefaultValue - WRITE_UINT(StartTexture) - WRITE_UINT(TextureSize) - WRITE_UINT(StartSampler) - WRITE_UINT(SamplerSize) - WRITE_END - - WRITE_START(mVarDescPointer, D3D11_SHADER_VARIABLE_DESC) - WRITE_NAME(Name) - WRITE_UINT(StartOffset) - WRITE_UINT(Size) - WRITE_UINT(uFlags) - //todo DefaultValue - WRITE_UINT(StartTexture) - WRITE_UINT(TextureSize) - WRITE_UINT(StartSampler) - WRITE_UINT(SamplerSize) - WRITE_END - - WRITE_START(mD3d11ShaderTypeDescs, D3D11_SHADER_TYPE_DESC) - WRITE_NAME(Name) - WRITE_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) - WRITE_UINT(Rows) - WRITE_UINT(Columns) - WRITE_UINT(Elements) - WRITE_UINT(Members) - WRITE_UINT(Offset) - WRITE_END - - WRITE_START(mMemberTypeDesc, D3D11_SHADER_TYPE_DESC) - WRITE_NAME(Name) - WRITE_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) - WRITE_UINT(Rows) - WRITE_UINT(Columns) - WRITE_UINT(Elements) - WRITE_UINT(Members) - WRITE_UINT(Offset) - WRITE_END - - WRITE_START(mMemberTypeName, MemberTypeName) - WRITE_NAME(Name) - WRITE_END - - uint16 mInterfaceSlotsSize = mInterfaceSlots.size(); - newMicrocode->write(&mInterfaceSlotsSize, sizeof(uint16)); - if(mInterfaceSlotsSize > 0) + WRITE_START(mD3d11ShaderInputParameters, D3D11_SIGNATURE_PARAMETER_DESC) + WRITE_NAME(SemanticName) + WRITE_UINT(SemanticIndex) + WRITE_UINT(Register) + WRITE_ENUM(SystemValueType,D3D_NAME) + WRITE_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) + WRITE_BYTE(Mask) + WRITE_BYTE(ReadWriteMask) + WRITE_UINT(Stream) +// WRITE_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK + WRITE_END + + WRITE_START(mD3d11ShaderOutputParameters, D3D11_SIGNATURE_PARAMETER_DESC) + WRITE_NAME(SemanticName) + WRITE_UINT(SemanticIndex) + WRITE_UINT(Register) + WRITE_ENUM(SystemValueType, D3D_NAME) + WRITE_ENUM(ComponentType, D3D_REGISTER_COMPONENT_TYPE) + WRITE_BYTE(Mask) + WRITE_BYTE(ReadWriteMask) + WRITE_UINT(Stream) +// WRITE_ENUM(MinPrecision, D3D_MIN_PRECISION) // not needed and doesn't exist in June 2010 SDK + WRITE_END + + WRITE_START(mD3d11ShaderVariables, D3D11_SHADER_VARIABLE_DESC) + WRITE_NAME(Name) + WRITE_UINT(StartOffset) + WRITE_UINT(Size) + WRITE_UINT(uFlags) + //todo DefaultValue + WRITE_UINT(StartTexture) + WRITE_UINT(TextureSize) + WRITE_UINT(StartSampler) + WRITE_UINT(SamplerSize) + WRITE_END + + WRITE_START(mD3d11ShaderVariableSubparts, GpuConstantDefinitionWithName) + WRITE_NAME(Name) + WRITE_ENUM(constType, GpuConstantType) + WRITE_UINT(physicalIndex) + WRITE_UINT(logicalIndex) + WRITE_UINT(elementSize) + WRITE_UINT(arraySize) + WRITE_UINT(variability) + WRITE_END + + WRITE_START(mD3d11ShaderBufferDescs, D3D11_SHADER_BUFFER_DESC) + WRITE_NAME(Name) + WRITE_ENUM(Type, D3D_CBUFFER_TYPE) + WRITE_UINT(Variables) + WRITE_UINT(Size) + WRITE_UINT(uFlags) + WRITE_END + + WRITE_START(mVarDescBuffer, D3D11_SHADER_VARIABLE_DESC) + WRITE_NAME(Name) + WRITE_UINT(StartOffset) + WRITE_UINT(Size) + WRITE_UINT(uFlags) + //todo DefaultValue + WRITE_UINT(StartTexture) + WRITE_UINT(TextureSize) + WRITE_UINT(StartSampler) + WRITE_UINT(SamplerSize) + WRITE_END + + WRITE_START(mVarDescPointer, D3D11_SHADER_VARIABLE_DESC) + WRITE_NAME(Name) + WRITE_UINT(StartOffset) + WRITE_UINT(Size) + WRITE_UINT(uFlags) + //todo DefaultValue + WRITE_UINT(StartTexture) + WRITE_UINT(TextureSize) + WRITE_UINT(StartSampler) + WRITE_UINT(SamplerSize) + WRITE_END + + WRITE_START(mD3d11ShaderTypeDescs, D3D11_SHADER_TYPE_DESC) + WRITE_NAME(Name) + WRITE_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) + WRITE_UINT(Rows) + WRITE_UINT(Columns) + WRITE_UINT(Elements) + WRITE_UINT(Members) + WRITE_UINT(Offset) + WRITE_END + + WRITE_START(mMemberTypeDesc, D3D11_SHADER_TYPE_DESC) + WRITE_NAME(Name) + WRITE_ENUM(Type, D3D_SHADER_VARIABLE_TYPE) + WRITE_UINT(Rows) + WRITE_UINT(Columns) + WRITE_UINT(Elements) + WRITE_UINT(Members) + WRITE_UINT(Offset) + WRITE_END + + WRITE_START(mMemberTypeName, MemberTypeName) + WRITE_NAME(Name) + WRITE_END + + uint16 mInterfaceSlotsSize = mInterfaceSlots.size(); + newMicrocode->write(&mInterfaceSlotsSize, sizeof(uint16)); + if(mInterfaceSlotsSize > 0) { newMicrocode->write(&mInterfaceSlots[0], mInterfaceSlotsSize * sizeof(UINT)); } @@ -1024,12 +1024,12 @@ namespace Ogre { //----------------------------------------------------------------------- void D3D11HLSLProgram::analizeMicrocode() { - // enum parameters + // enum parameters mInputVertexDeclaration.removeAllElements(); - for (UINT i=0 ; i < mD3d11ShaderInputParameters.size() ; i++) + for (UINT i=0 ; i < mD3d11ShaderInputParameters.size() ; i++) { - D3D11_SIGNATURE_PARAMETER_DESC & paramDesc = mD3d11ShaderInputParameters[i]; + D3D11_SIGNATURE_PARAMETER_DESC & paramDesc = mD3d11ShaderInputParameters[i]; mInputVertexDeclaration.addElement( paramDesc.Register, -1, // we don't need the offset @@ -1038,128 +1038,128 @@ namespace Ogre { paramDesc.SemanticIndex); } - UINT bufferCount = 0; - UINT pointerCount = 0; - UINT typeCount = 0; - UINT memberCount = 0; - UINT interCount = 0; - UINT nameCount = 0; - - for(UINT b = 0; b < mConstantBufferNr; b++) - { - switch (mD3d11ShaderBufferDescs[b].Type) - { - // For this buffer type, all variables are interfaces, - // so just parse and store interface slots - case D3D_CT_INTERFACE_POINTERS: - { - for(UINT v = 0; v < mD3d11ShaderBufferDescs[b].Variables; v++) - { - interCount++; - pointerCount++; - // Only parse if is used - if (mVarDescPointer[pointerCount-1].uFlags & D3D_SVF_USED) - { - mSlotMap.insert(std::make_pair(mVarDescPointer[pointerCount-1].Name, mInterfaceSlots[interCount-1])); - - /* - D3D11_SHADER_TYPE_DESC typeDesc; - ID3D11ShaderReflectionType* varType = var->GetType(); - varType->GetDesc(&typeDesc); - - // Get all interface slots if inside an array - //unsigned int numInterface = varType->GetNumInterfaces(); - for(UINT ifs = 0; ifs < typeDesc.Elements; ifs++) - { - std::string name = varDesc.Name; - name += "["; - name += StringConverter::toString(ifs); - name += "]"; - mSlotMap.insert(std::make_pair(name, ifs)); - } - */ - } - } - } - break; - - // These buffers store variables and class instances, - // so parse all. - case D3D_CT_CBUFFER: - case D3D_CT_TBUFFER: - { - // Insert buffer info - BufferInfoIterator it = mBufferInfoMap.insert(BufferInfo(0, mD3d11ShaderBufferDescs[b].Name)).first; - - // Guard to create uniform buffer only once - if (it->mUniformBuffer.isNull()) - { - HardwareUniformBufferSharedPtr uBuffer = HardwareBufferManager::getSingleton().createUniformBuffer(mD3d11ShaderBufferDescs[b].Size, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false); - it->mUniformBuffer = HardwareUniformBufferSharedPtr(uBuffer); - } - else - { - assert (it->mUniformBuffer->getSizeInBytes() == mD3d11ShaderBufferDescs[b].Size); - } - - // Now, parse variables for this buffer - for(unsigned int i = 0; i < mD3d11ShaderBufferDescs[b].Variables ; i++) - { - // Only parse if variable is used - bufferCount++; - if (mVarDescBuffer[bufferCount-1].uFlags & D3D_SVF_USED) - { - typeCount++; - switch (mD3d11ShaderTypeDescs[typeCount-1].Class) - { - // Class instance variables - case D3D_SVC_STRUCT: - { - // Offset if relative to parent struct, so store offset - // of class instance, and add to offset of inner variables - const UINT parentOffset = mVarDescBuffer[bufferCount - 1].StartOffset; - for(UINT m = 0; m < mD3d11ShaderTypeDescs[typeCount-1].Members; m++) - { - ShaderVarWithPosInBuf newVar; - newVar.name = mVarDescBuffer[bufferCount - 1].Name; - newVar.name += "."; - newVar.name += mMemberTypeName[nameCount++].Name; - newVar.size = mMemberTypeDesc[memberCount].Rows * mMemberTypeDesc[memberCount].Columns * - (mMemberTypeDesc[memberCount].Type == D3D_SVT_FLOAT || - mMemberTypeDesc[memberCount].Type == D3D_SVT_INT ? 4 : 1); - newVar.startOffset = parentOffset + mMemberTypeDesc[memberCount].Offset; - memberCount++; - fixVariableNameFromCg(newVar); - it->mShaderVars.push_back(newVar); - } - } - break; - - // scalar, vector or matrix variables - case D3D_SVC_SCALAR: - case D3D_SVC_VECTOR: - case D3D_SVC_MATRIX_ROWS: - case D3D_SVC_MATRIX_COLUMNS: - { - ShaderVarWithPosInBuf newVar; - newVar.name = mVarDescBuffer[bufferCount-1].Name; - newVar.size = mVarDescBuffer[bufferCount-1].Size; - newVar.startOffset = mVarDescBuffer[bufferCount-1].StartOffset; - - fixVariableNameFromCg(newVar); - it->mShaderVars.push_back(newVar); - } - break; - }; - - } - } - } - break; - } - } - - switch(mType) + UINT bufferCount = 0; + UINT pointerCount = 0; + UINT typeCount = 0; + UINT memberCount = 0; + UINT interCount = 0; + UINT nameCount = 0; + + for(UINT b = 0; b < mConstantBufferNr; b++) + { + switch (mD3d11ShaderBufferDescs[b].Type) + { + // For this buffer type, all variables are interfaces, + // so just parse and store interface slots + case D3D_CT_INTERFACE_POINTERS: + { + for(UINT v = 0; v < mD3d11ShaderBufferDescs[b].Variables; v++) + { + interCount++; + pointerCount++; + // Only parse if is used + if (mVarDescPointer[pointerCount-1].uFlags & D3D_SVF_USED) + { + mSlotMap.insert(std::make_pair(mVarDescPointer[pointerCount-1].Name, mInterfaceSlots[interCount-1])); + + /* + D3D11_SHADER_TYPE_DESC typeDesc; + ID3D11ShaderReflectionType* varType = var->GetType(); + varType->GetDesc(&typeDesc); + + // Get all interface slots if inside an array + //unsigned int numInterface = varType->GetNumInterfaces(); + for(UINT ifs = 0; ifs < typeDesc.Elements; ifs++) + { + std::string name = varDesc.Name; + name += "["; + name += StringConverter::toString(ifs); + name += "]"; + mSlotMap.insert(std::make_pair(name, ifs)); + } + */ + } + } + } + break; + + // These buffers store variables and class instances, + // so parse all. + case D3D_CT_CBUFFER: + case D3D_CT_TBUFFER: + { + // Insert buffer info + BufferInfoIterator it = mBufferInfoMap.insert(BufferInfo(0, mD3d11ShaderBufferDescs[b].Name)).first; + + // Guard to create uniform buffer only once + if (it->mUniformBuffer.isNull()) + { + HardwareUniformBufferSharedPtr uBuffer = HardwareBufferManager::getSingleton().createUniformBuffer(mD3d11ShaderBufferDescs[b].Size, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false); + it->mUniformBuffer = HardwareUniformBufferSharedPtr(uBuffer); + } + else + { + assert (it->mUniformBuffer->getSizeInBytes() == mD3d11ShaderBufferDescs[b].Size); + } + + // Now, parse variables for this buffer + for(unsigned int i = 0; i < mD3d11ShaderBufferDescs[b].Variables ; i++) + { + // Only parse if variable is used + bufferCount++; + if (mVarDescBuffer[bufferCount-1].uFlags & D3D_SVF_USED) + { + typeCount++; + switch (mD3d11ShaderTypeDescs[typeCount-1].Class) + { + // Class instance variables + case D3D_SVC_STRUCT: + { + // Offset if relative to parent struct, so store offset + // of class instance, and add to offset of inner variables + const UINT parentOffset = mVarDescBuffer[bufferCount - 1].StartOffset; + for(UINT m = 0; m < mD3d11ShaderTypeDescs[typeCount-1].Members; m++) + { + ShaderVarWithPosInBuf newVar; + newVar.name = mVarDescBuffer[bufferCount - 1].Name; + newVar.name += "."; + newVar.name += mMemberTypeName[nameCount++].Name; + newVar.size = mMemberTypeDesc[memberCount].Rows * mMemberTypeDesc[memberCount].Columns * + (mMemberTypeDesc[memberCount].Type == D3D_SVT_FLOAT || + mMemberTypeDesc[memberCount].Type == D3D_SVT_INT ? 4 : 1); + newVar.startOffset = parentOffset + mMemberTypeDesc[memberCount].Offset; + memberCount++; + fixVariableNameFromCg(newVar); + it->mShaderVars.push_back(newVar); + } + } + break; + + // scalar, vector or matrix variables + case D3D_SVC_SCALAR: + case D3D_SVC_VECTOR: + case D3D_SVC_MATRIX_ROWS: + case D3D_SVC_MATRIX_COLUMNS: + { + ShaderVarWithPosInBuf newVar; + newVar.name = mVarDescBuffer[bufferCount-1].Name; + newVar.size = mVarDescBuffer[bufferCount-1].Size; + newVar.startOffset = mVarDescBuffer[bufferCount-1].StartOffset; + + fixVariableNameFromCg(newVar); + it->mShaderVars.push_back(newVar); + } + break; + }; + + } + } + } + break; + } + } + + switch(mType) { case GPT_VERTEX_PROGRAM: CreateVertexShader(); @@ -1193,8 +1193,8 @@ namespace Ogre { //----------------------------------------------------------------------- void D3D11HLSLProgram::unloadHighLevelImpl(void) { - mSlotMap.clear(); - mBufferInfoMap.clear(); + mSlotMap.clear(); + mBufferInfoMap.clear(); SAFE_RELEASE(mVertexShader); SAFE_RELEASE(mPixelShader); @@ -1241,39 +1241,39 @@ namespace Ogre { mConstantDefs->generateConstantDefinitionArrayEntries(def.Name, def); } } - //----------------------------------------------------------------------- - - void D3D11HLSLProgram::populateParameterNames(GpuProgramParametersSharedPtr params) - { - // Call superclass method - HighLevelGpuProgram::populateParameterNames(params); - - /* - // Construct uniform buffers for shared parameters, if any - // Also, construct uniform buffers for non-shared parameters (will be hosted inside program) - const GpuProgramParameters::GpuSharedParamUsageList& sharedParams = params->getSharedParameters(); - GpuProgramParameters::GpuSharedParamUsageList::const_iterator it, end = sharedParams.end(); - for (it = sharedParams.begin(); it != end; ++it) - { - ID3D11ShaderReflectionConstantBuffer* bufferInfo = mIShaderReflection->GetConstantBufferByName(it->getName().c_str()); - if (!bufferInfo) - { - - } - - D3D11_SHADER_BUFFER_DESC bufferDesc; - bufferInfo->GetDesc(&bufferDesc); - - HardwareUniformBufferSharedPtr uniformBuffer = - HardwareBufferManager::getSingleton() - .createUniformBuffer(bufferDesc.Size, - HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, - false, it->getName()); - it->_setRenderSystemData(Any(uniformBuffer)); - } - */ - - } + //----------------------------------------------------------------------- + + void D3D11HLSLProgram::populateParameterNames(GpuProgramParametersSharedPtr params) + { + // Call superclass method + HighLevelGpuProgram::populateParameterNames(params); + + /* + // Construct uniform buffers for shared parameters, if any + // Also, construct uniform buffers for non-shared parameters (will be hosted inside program) + const GpuProgramParameters::GpuSharedParamUsageList& sharedParams = params->getSharedParameters(); + GpuProgramParameters::GpuSharedParamUsageList::const_iterator it, end = sharedParams.end(); + for (it = sharedParams.begin(); it != end; ++it) + { + ID3D11ShaderReflectionConstantBuffer* bufferInfo = mIShaderReflection->GetConstantBufferByName(it->getName().c_str()); + if (!bufferInfo) + { + + } + + D3D11_SHADER_BUFFER_DESC bufferDesc; + bufferInfo->GetDesc(&bufferDesc); + + HardwareUniformBufferSharedPtr uniformBuffer = + HardwareBufferManager::getSingleton() + .createUniformBuffer(bufferDesc.Size, + HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, + false, it->getName()); + it->_setRenderSystemData(Any(uniformBuffer)); + } + */ + + } //----------------------------------------------------------------------- void D3D11HLSLProgram::processParamElement(String prefix, LPCSTR pName, ID3D11ShaderReflectionType* varRefType) { @@ -1420,9 +1420,9 @@ namespace Ogre { } // rows break; - case D3D_SVT_INTERFACE_POINTER: - def.constType = GCT_SUBROUTINE; - break; + case D3D_SVT_INTERFACE_POINTER: + def.constType = GCT_SUBROUTINE; + break; default: // not mapping samplers, don't need to take the space @@ -1473,7 +1473,7 @@ namespace Ogre { D3D11HLSLProgram::~D3D11HLSLProgram() { //SAFE_RELEASE(mConstantBuffer); - mBufferInfoMap.clear(); + mBufferInfoMap.clear(); // this is a hack - to solve that problem that we are the mAssemblerProgram of ourselves if ( !mAssemblerProgram.isNull() ) { @@ -1544,12 +1544,12 @@ namespace Ogre { const String& D3D11HLSLProgram::getCompatibleTarget(void) const { static const String - vs_4_0 = "vs_4_0", - vs_4_0_level_9_3 = "vs_4_0_level_9_3", - vs_4_0_level_9_1 = "vs_4_0_level_9_1", - ps_4_0 = "ps_4_0", - ps_4_0_level_9_3 = "ps_4_0_level_9_3", - ps_4_0_level_9_1 = "ps_4_0_level_9_1"; + vs_4_0 = "vs_4_0", + vs_4_0_level_9_3 = "vs_4_0_level_9_3", + vs_4_0_level_9_1 = "vs_4_0_level_9_1", + ps_4_0 = "ps_4_0", + ps_4_0_level_9_3 = "ps_4_0_level_9_3", + ps_4_0_level_9_1 = "ps_4_0_level_9_1"; if(mEnableBackwardsCompatibility) { @@ -1780,199 +1780,199 @@ namespace Ogre { "Unsupported D3D11 Geometry shader '" + mName + "' was not loaded."); } } - //----------------------------------------------------------------------- - void D3D11HLSLProgram::CreateHullShader() - { - if (isSupported()) - { - // Create the shader - HRESULT hr = mDevice->CreateHullShader( - &mMicroCode[0], - mMicroCode.size(), - mDevice.GetClassLinkage(), - &mHullShader); - - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot create D3D11 Hull shader " + mName + " from microcode.\nError Description:" + errorDescription, - "D3D11GpuPixelProgram::loadFromMicrocode"); - } - } - else - { - LogManager::getSingleton().logMessage( - "Unsupported D3D11 Hull shader '" + mName + "' was not loaded."); - } - } - //----------------------------------------------------------------------- - void D3D11HLSLProgram::CreateDomainShader() - { - if (isSupported()) - { - // Create the shader - HRESULT hr = mDevice->CreateDomainShader( - &mMicroCode[0], - mMicroCode.size(), - mDevice.GetClassLinkage(), - &mDomainShader); - - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot create D3D11 Domain shader " + mName + " from microcode.\nError Description:" + errorDescription, - "D3D11GpuPixelProgram::loadFromMicrocode"); - } - } - else - { - LogManager::getSingleton().logMessage( - "Unsupported D3D11 Domain shader '" + mName + "' was not loaded."); - } - } - //----------------------------------------------------------------------- - void D3D11HLSLProgram::CreateComputeShader() - { - if (isSupported()) - { - // Create the shader - HRESULT hr = mDevice->CreateComputeShader( - &mMicroCode[0], - mMicroCode.size(), - mDevice.GetClassLinkage(), - &mComputeShader); - - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot create D3D11 Compute shader " + mName + " from microcode.\nError Description:" + errorDescription, - "D3D11GpuPixelProgram::loadFromMicrocode"); - } - } - else - { - LogManager::getSingleton().logMessage( - "Unsupported D3D11 Compute shader '" + mName + "' was not loaded."); - } - } - //----------------------------------------------------------------------------- - unsigned int D3D11HLSLProgram::getSubroutineSlot(const String& subroutineSlotName) const - { - SlotIterator it = mSlotMap.find(subroutineSlotName); - if (it == mSlotMap.end()) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Don't exist interface slot with name " + subroutineSlotName + " in shader " + mName, - "D3D11HLSLProgram::getInterfaceSlot"); - } - - return it->second; - } - //----------------------------------------------------------------------------- - ID3D11Buffer* D3D11HLSLProgram::getConstantBuffer(GpuProgramParametersSharedPtr params, uint16 variabilityMask) - { - // Update the Constant Buffer - BufferInfoIterator it = mBufferInfoMap.find(0); - if (it != mBufferInfoMap.end()) - { - if (!it->mUniformBuffer.isNull()) - { - void* pMappedData = it->mUniformBuffer->lock(HardwareBuffer::HBL_DISCARD); - - // Only iterate through parsed variables (getting size of list) - void* src = 0; - ShaderVarWithPosInBuf* iter = &(it->mShaderVars[0]); - unsigned int lSize = it->mShaderVars.size(); - for (size_t i = 0 ; i < lSize; i++, iter++) - { - const GpuConstantDefinition& def = params->getConstantDefinition(iter->name); - // Since we are mapping with write discard, contents of the buffer are undefined. - // We must set every variable, even if it has not changed. - //if (def.variability & variabilityMask) - { - if(def.isFloat()) - { - src = (void *)&(*(params->getFloatConstantList().begin() + def.physicalIndex)); - } - else - { - src = (void *)&(*(params->getIntConstantList().begin() + def.physicalIndex)); - } - - memcpy( &(((char *)(pMappedData))[iter->startOffset]), src , iter->size); - } - } - - it->mUniformBuffer->unlock(); - - return static_cast(it->mUniformBuffer.get())->getD3DConstantBuffer(); - } - } - - return NULL; - } - //----------------------------------------------------------------------------- - void D3D11HLSLProgram::getConstantBuffers(ID3D11Buffer** buffers, unsigned int& numBuffers, - ID3D11ClassInstance** classes, unsigned int& numClasses, - GpuProgramParametersSharedPtr params, uint16 variabilityMask) - { - // Update the Constant Buffers - BufferInfoIterator it = mBufferInfoMap.begin(); - BufferInfoIterator end = mBufferInfoMap.end(); - while (it != end) - { - if (!it->mUniformBuffer.isNull()) - { - void* pMappedData = it->mUniformBuffer->lock(HardwareBuffer::HBL_DISCARD); - - // Only iterate through parsed variables (getting size of list) - void* src = 0; - ShaderVarWithPosInBuf* iter = &(it->mShaderVars[0]); - unsigned int lSize = it->mShaderVars.size(); - for (size_t i = 0 ; i < lSize; i++, iter++) - { - const GpuConstantDefinition& def = params->getConstantDefinition(iter->name); - // Since we are mapping with write discard, contents of the buffer are undefined. - // We must set every variable, even if it has not changed. - //if (def.variability & variabilityMask) - { - if(def.isFloat()) - { - src = (void *)&(*(params->getFloatConstantList().begin() + def.physicalIndex)); - } - else - { - src = (void *)&(*(params->getIntConstantList().begin() + def.physicalIndex)); - } - - memcpy( &(((char *)(pMappedData))[iter->startOffset]), src , iter->size); - } - } - - it->mUniformBuffer->unlock(); - - // Add buffer to list - buffers[numBuffers] = static_cast(it->mUniformBuffer.get())->getD3DConstantBuffer(); - // Increment number of buffers - numBuffers++; - } - } - - // Update class instances - SlotIterator sit = mSlotMap.begin(); - SlotIterator send = mSlotMap.end(); - while (sit != send) - { - // Get constant name - const GpuConstantDefinition& def = params->getConstantDefinition(sit->first); - - // Set to correct slot - //classes[sit->second] = - - // Increment class count - numClasses++; - } - } + //----------------------------------------------------------------------- + void D3D11HLSLProgram::CreateHullShader() + { + if (isSupported()) + { + // Create the shader + HRESULT hr = mDevice->CreateHullShader( + &mMicroCode[0], + mMicroCode.size(), + mDevice.GetClassLinkage(), + &mHullShader); + + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot create D3D11 Hull shader " + mName + " from microcode.\nError Description:" + errorDescription, + "D3D11GpuPixelProgram::loadFromMicrocode"); + } + } + else + { + LogManager::getSingleton().logMessage( + "Unsupported D3D11 Hull shader '" + mName + "' was not loaded."); + } + } + //----------------------------------------------------------------------- + void D3D11HLSLProgram::CreateDomainShader() + { + if (isSupported()) + { + // Create the shader + HRESULT hr = mDevice->CreateDomainShader( + &mMicroCode[0], + mMicroCode.size(), + mDevice.GetClassLinkage(), + &mDomainShader); + + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot create D3D11 Domain shader " + mName + " from microcode.\nError Description:" + errorDescription, + "D3D11GpuPixelProgram::loadFromMicrocode"); + } + } + else + { + LogManager::getSingleton().logMessage( + "Unsupported D3D11 Domain shader '" + mName + "' was not loaded."); + } + } + //----------------------------------------------------------------------- + void D3D11HLSLProgram::CreateComputeShader() + { + if (isSupported()) + { + // Create the shader + HRESULT hr = mDevice->CreateComputeShader( + &mMicroCode[0], + mMicroCode.size(), + mDevice.GetClassLinkage(), + &mComputeShader); + + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot create D3D11 Compute shader " + mName + " from microcode.\nError Description:" + errorDescription, + "D3D11GpuPixelProgram::loadFromMicrocode"); + } + } + else + { + LogManager::getSingleton().logMessage( + "Unsupported D3D11 Compute shader '" + mName + "' was not loaded."); + } + } + //----------------------------------------------------------------------------- + unsigned int D3D11HLSLProgram::getSubroutineSlot(const String& subroutineSlotName) const + { + SlotIterator it = mSlotMap.find(subroutineSlotName); + if (it == mSlotMap.end()) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Don't exist interface slot with name " + subroutineSlotName + " in shader " + mName, + "D3D11HLSLProgram::getInterfaceSlot"); + } + + return it->second; + } + //----------------------------------------------------------------------------- + ID3D11Buffer* D3D11HLSLProgram::getConstantBuffer(GpuProgramParametersSharedPtr params, uint16 variabilityMask) + { + // Update the Constant Buffer + BufferInfoIterator it = mBufferInfoMap.find(0); + if (it != mBufferInfoMap.end()) + { + if (!it->mUniformBuffer.isNull()) + { + void* pMappedData = it->mUniformBuffer->lock(HardwareBuffer::HBL_DISCARD); + + // Only iterate through parsed variables (getting size of list) + void* src = 0; + ShaderVarWithPosInBuf* iter = &(it->mShaderVars[0]); + unsigned int lSize = it->mShaderVars.size(); + for (size_t i = 0 ; i < lSize; i++, iter++) + { + const GpuConstantDefinition& def = params->getConstantDefinition(iter->name); + // Since we are mapping with write discard, contents of the buffer are undefined. + // We must set every variable, even if it has not changed. + //if (def.variability & variabilityMask) + { + if(def.isFloat()) + { + src = (void *)&(*(params->getFloatConstantList().begin() + def.physicalIndex)); + } + else + { + src = (void *)&(*(params->getIntConstantList().begin() + def.physicalIndex)); + } + + memcpy( &(((char *)(pMappedData))[iter->startOffset]), src , iter->size); + } + } + + it->mUniformBuffer->unlock(); + + return static_cast(it->mUniformBuffer.get())->getD3DConstantBuffer(); + } + } + + return NULL; + } + //----------------------------------------------------------------------------- + void D3D11HLSLProgram::getConstantBuffers(ID3D11Buffer** buffers, unsigned int& numBuffers, + ID3D11ClassInstance** classes, unsigned int& numClasses, + GpuProgramParametersSharedPtr params, uint16 variabilityMask) + { + // Update the Constant Buffers + BufferInfoIterator it = mBufferInfoMap.begin(); + BufferInfoIterator end = mBufferInfoMap.end(); + while (it != end) + { + if (!it->mUniformBuffer.isNull()) + { + void* pMappedData = it->mUniformBuffer->lock(HardwareBuffer::HBL_DISCARD); + + // Only iterate through parsed variables (getting size of list) + void* src = 0; + ShaderVarWithPosInBuf* iter = &(it->mShaderVars[0]); + unsigned int lSize = it->mShaderVars.size(); + for (size_t i = 0 ; i < lSize; i++, iter++) + { + const GpuConstantDefinition& def = params->getConstantDefinition(iter->name); + // Since we are mapping with write discard, contents of the buffer are undefined. + // We must set every variable, even if it has not changed. + //if (def.variability & variabilityMask) + { + if(def.isFloat()) + { + src = (void *)&(*(params->getFloatConstantList().begin() + def.physicalIndex)); + } + else + { + src = (void *)&(*(params->getIntConstantList().begin() + def.physicalIndex)); + } + + memcpy( &(((char *)(pMappedData))[iter->startOffset]), src , iter->size); + } + } + + it->mUniformBuffer->unlock(); + + // Add buffer to list + buffers[numBuffers] = static_cast(it->mUniformBuffer.get())->getD3DConstantBuffer(); + // Increment number of buffers + numBuffers++; + } + } + + // Update class instances + SlotIterator sit = mSlotMap.begin(); + SlotIterator send = mSlotMap.end(); + while (sit != send) + { + // Get constant name + const GpuConstantDefinition& def = params->getConstantDefinition(sit->first); + + // Set to correct slot + //classes[sit->second] = + + // Increment class count + numClasses++; + } + } //----------------------------------------------------------------------------- ID3D11VertexShader* D3D11HLSLProgram::getVertexShader(void) const { @@ -2039,10 +2039,10 @@ namespace Ogre { return mD3d11ShaderOutputParameters.size(); } //----------------------------------------------------------------------------- - String D3D11HLSLProgram::getNameForMicrocodeCache() - { - return mName + "_" + mTarget; - } + String D3D11HLSLProgram::getNameForMicrocodeCache() + { + return mName + "_" + mTarget; + } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgramFactory.cpp b/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgramFactory.cpp index fac9b6a40bc..db81c9b22bd 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgramFactory.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11HLSLProgramFactory.cpp @@ -31,33 +31,33 @@ THE SOFTWARE. #include "OgreD3D11Device.h" namespace Ogre { - //----------------------------------------------------------------------- - String D3D11HLSLProgramFactory::sLanguageName = "hlsl"; - //----------------------------------------------------------------------- - D3D11HLSLProgramFactory::D3D11HLSLProgramFactory(D3D11Device & device) : mDevice(device) - { - } - //----------------------------------------------------------------------- - D3D11HLSLProgramFactory::~D3D11HLSLProgramFactory() - { - } - //----------------------------------------------------------------------- - const String& D3D11HLSLProgramFactory::getLanguage(void) const - { - return sLanguageName; - } - //----------------------------------------------------------------------- - HighLevelGpuProgram* D3D11HLSLProgramFactory::create(ResourceManager* creator, - const String& name, ResourceHandle handle, - const String& group, bool isManual, ManualResourceLoader* loader) - { - return new D3D11HLSLProgram(creator, name, handle, group, isManual, loader, mDevice); - } - //----------------------------------------------------------------------- - void D3D11HLSLProgramFactory::destroy(HighLevelGpuProgram* prog) - { - delete prog; - } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- + String D3D11HLSLProgramFactory::sLanguageName = "hlsl"; + //----------------------------------------------------------------------- + D3D11HLSLProgramFactory::D3D11HLSLProgramFactory(D3D11Device & device) : mDevice(device) + { + } + //----------------------------------------------------------------------- + D3D11HLSLProgramFactory::~D3D11HLSLProgramFactory() + { + } + //----------------------------------------------------------------------- + const String& D3D11HLSLProgramFactory::getLanguage(void) const + { + return sLanguageName; + } + //----------------------------------------------------------------------- + HighLevelGpuProgram* D3D11HLSLProgramFactory::create(ResourceManager* creator, + const String& name, ResourceHandle handle, + const String& group, bool isManual, ManualResourceLoader* loader) + { + return new D3D11HLSLProgram(creator, name, handle, group, isManual, loader, mDevice); + } + //----------------------------------------------------------------------- + void D3D11HLSLProgramFactory::destroy(HighLevelGpuProgram* prog) + { + delete prog; + } + //----------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11HardwareBuffer.cpp b/RenderSystems/Direct3D11/src/OgreD3D11HardwareBuffer.cpp index 35e614d28ea..b7361c91471 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11HardwareBuffer.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11HardwareBuffer.cpp @@ -31,271 +31,271 @@ THE SOFTWARE. #include "OgreException.h" namespace Ogre { - //--------------------------------------------------------------------- - D3D11HardwareBuffer::D3D11HardwareBuffer( - BufferType btype, size_t sizeBytes, - HardwareBuffer::Usage usage, D3D11Device & device, - bool useSystemMemory, bool useShadowBuffer, bool streamOut) - : HardwareBuffer(usage, useSystemMemory, useShadowBuffer), - mlpD3DBuffer(0), - mpTempStagingBuffer(0), - mUseTempStagingBuffer(false), - mBufferType(btype), - mDevice(device) - { - mSizeInBytes = sizeBytes; - mDesc.ByteWidth = static_cast(sizeBytes); - mDesc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage); - mDesc.MiscFlags = 0; - - if (useSystemMemory) - { - mDesc.Usage = D3D11_USAGE_STAGING; - //A D3D11_USAGE_STAGING Resource cannot be bound to any parts of the graphics pipeline, so therefore cannot have any BindFlags bits set. - mDesc.BindFlags = 0; - mDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ ;// A D3D11_USAGE_STAGING Resource must have at least one CPUAccessFlag bit set. - - } - else - { - mDesc.Usage = D3D11Mappings::_getUsage(mUsage); - mDesc.BindFlags = btype == VERTEX_BUFFER ? D3D11_BIND_VERTEX_BUFFER : - btype == INDEX_BUFFER ? D3D11_BIND_INDEX_BUFFER : - D3D11_BIND_CONSTANT_BUFFER; - } - // Better check of stream out flag - if (streamOut && btype != CONSTANT_BUFFER) - { - mDesc.BindFlags |= D3D11_BIND_STREAM_OUTPUT; - } - - if (!useSystemMemory && (usage & HardwareBuffer::HBU_DYNAMIC)) - { - // We want to be able to map this buffer - mDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; - mDesc.Usage = D3D11_USAGE_DYNAMIC; - } - - // Note that in D3D11 you can only directly lock (map) a dynamic resource - // directly for writing. You can only map for read / write staging resources, - // which themselves cannot be used for input / output to the GPU. Thus - // for any locks except write locks on dynamic resources, we have to use - // temporary staging resources instead and use async copies. - // We use the 'useSystemMemory' option to indicate a staging resource - - - // TODO: we can explicitly initialise the buffer contents here if we like - // not doing this since OGRE doesn't support this model yet - HRESULT hr = device->CreateBuffer( &mDesc, NULL, &mlpD3DBuffer ); - if (FAILED(hr) || mDevice.isError()) - { - String msg = device.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D11 buffer: " + msg, - "D3D11HardwareBuffer::D3D11HardwareBuffer"); - } - - // Create shadow buffer - if (mUseShadowBuffer) - { - mShadowBuffer = new D3D11HardwareBuffer(mBufferType, - mSizeInBytes, mUsage, mDevice, true, false, false); - } - - } - //--------------------------------------------------------------------- - D3D11HardwareBuffer::~D3D11HardwareBuffer() - { - SAFE_RELEASE(mlpD3DBuffer); - SAFE_DELETE(mpTempStagingBuffer); // should never be nonzero unless destroyed while locked - SAFE_DELETE(mShadowBuffer); - } - //--------------------------------------------------------------------- - void* D3D11HardwareBuffer::lockImpl(size_t offset, - size_t length, LockOptions options) - { - if (length > mSizeInBytes) - { - // need to realloc - mDesc.ByteWidth = static_cast(mSizeInBytes); - SAFE_RELEASE(mlpD3DBuffer); - HRESULT hr = mDevice->CreateBuffer( &mDesc, 0, &mlpD3DBuffer ); - if (FAILED(hr) || mDevice.isError()) - { - String msg = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D11 buffer: " + msg, - "D3D11HardwareBuffer::D3D11HardwareBuffer"); - } - } - - - if (mSystemMemory || - (mUsage & HardwareBuffer::HBU_DYNAMIC && - (options == HardwareBuffer::HBL_DISCARD || options == HardwareBuffer::HBL_NO_OVERWRITE))) - { - // Staging (system memory) buffers or dynamic, write-only buffers - // are the only case where we can lock directly - // We have no 'lock for writing' but discard + locking the entire - // buffer essentially means the same thing, especially since it's - // not possible to map part of a buffer in Dx11 - - // map directly - D3D11_MAP mapType; - switch(options) - { - case HBL_DISCARD: - // To use D3D11_MAP_WRITE_DISCARD resource must have been created with write access and dynamic usage. - mapType = mSystemMemory ? D3D11_MAP_WRITE : D3D11_MAP_WRITE_DISCARD; - break; - case HBL_NO_OVERWRITE: - // To use D3D11_MAP_WRITE_NO_OVERWRITE resource must have been created with write access. - // TODO: check (mSystemMemory aka D3D11_USAGE_STAGING => D3D11_MAP_WRITE_NO_OVERWRITE) combo - it`s not forbidden by MSDN - mapType = mSystemMemory ? D3D11_MAP_WRITE : D3D11_MAP_WRITE_NO_OVERWRITE; - break; - case HBL_NORMAL: - mapType = (mDesc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) ? D3D11_MAP_READ_WRITE : D3D11_MAP_WRITE; - break; - case HBL_READ_ONLY: - mapType = D3D11_MAP_READ; - break; - case HBL_WRITE_ONLY: - mapType = D3D11_MAP_WRITE; - break; - } - - void * pRet = NULL; - D3D11_MAPPED_SUBRESOURCE mappedSubResource; - mappedSubResource.pData = NULL; - mDevice.clearStoredErrorMessages(); - HRESULT hr = mDevice.GetImmediateContext()->Map(mlpD3DBuffer, 0, mapType, 0, &mappedSubResource); - if (FAILED(hr) || mDevice.isError()) - { - String msg = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Error calling Map: " + msg, - "D3D11HardwareBuffer::lockImpl"); - } - - pRet = static_cast(static_cast(mappedSubResource.pData) + offset); - - return pRet; - - } - else - { - mUseTempStagingBuffer = true; - if (!mpTempStagingBuffer) - { - // create another buffer instance but use system memory - mpTempStagingBuffer = new D3D11HardwareBuffer(mBufferType, - mSizeInBytes, mUsage, mDevice, true, false, false); - } - - // schedule a copy to the staging - if (options != HBL_DISCARD) - mpTempStagingBuffer->copyData(*this, 0, 0, mSizeInBytes, true); - - // register whether we'll need to upload on unlock - mStagingUploadNeeded = (options != HBL_READ_ONLY); - - return mpTempStagingBuffer->lock(offset, length, options); - - - } - } - //--------------------------------------------------------------------- - void D3D11HardwareBuffer::unlockImpl(void) - { - - if (mUseTempStagingBuffer) - { - mUseTempStagingBuffer = false; - - // ok, we locked the staging buffer - mpTempStagingBuffer->unlock(); - - // copy data if needed - // this is async but driver should keep reference - if (mStagingUploadNeeded) - copyData(*mpTempStagingBuffer, 0, 0, mSizeInBytes, true); - - // delete - // not that efficient, but we should not be locking often - SAFE_DELETE(mpTempStagingBuffer); - } - else - { - // unmap - mDevice.GetImmediateContext()->Unmap(mlpD3DBuffer, 0); - } - } - //--------------------------------------------------------------------- - void D3D11HardwareBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset, - size_t dstOffset, size_t length, bool discardWholeBuffer) - { - // If we're copying same-size buffers in their entirety... - if (srcOffset == 0 && dstOffset == 0 && - length == mSizeInBytes && mSizeInBytes == srcBuffer.getSizeInBytes()) - { - // schedule hardware buffer copy - mDevice.GetImmediateContext()->CopyResource(mlpD3DBuffer, static_cast(srcBuffer).getD3DBuffer()); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot copy D3D11 resource\nError Description:" + errorDescription, - "D3D11HardwareBuffer::copyData"); - } - } - else - { - // copy subregion - D3D11_BOX srcBox; - srcBox.left = (UINT)srcOffset; - srcBox.right = (UINT)srcOffset + length; - srcBox.top = 0; - srcBox.bottom = 1; - srcBox.front = 0; - srcBox.back = 1; - - mDevice.GetImmediateContext()->CopySubresourceRegion(mlpD3DBuffer, 0, (UINT)dstOffset, 0, 0, - static_cast(srcBuffer).getD3DBuffer(), 0, &srcBox); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot copy D3D11 subresource region\nError Description:" + errorDescription, - "D3D11HardwareBuffer::copyData"); - } - } - } - //--------------------------------------------------------------------- - void D3D11HardwareBuffer::readData(size_t offset, size_t length, - void* pDest) - { - // There is no functional interface in D3D, just do via manual - // lock, copy & unlock - void* pSrc = this->lock(offset, length, HardwareBuffer::HBL_READ_ONLY); - memcpy(pDest, pSrc, length); - this->unlock(); - - } - //--------------------------------------------------------------------- - void D3D11HardwareBuffer::writeData(size_t offset, size_t length, - const void* pSource, - bool discardWholeBuffer) - { - // There is no functional interface in D3D, just do via manual - // lock, copy & unlock - void* pDst = this->lock(offset, length, - discardWholeBuffer ? HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL); - memcpy(pDst, pSource, length); - this->unlock(); - - //What if we try UpdateSubresource - //mDevice.GetImmediateContext()->UpdateSubresource(mlpD3DBuffer, 0, NULL, pSource, offset, length); - } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + D3D11HardwareBuffer::D3D11HardwareBuffer( + BufferType btype, size_t sizeBytes, + HardwareBuffer::Usage usage, D3D11Device & device, + bool useSystemMemory, bool useShadowBuffer, bool streamOut) + : HardwareBuffer(usage, useSystemMemory, useShadowBuffer), + mlpD3DBuffer(0), + mpTempStagingBuffer(0), + mUseTempStagingBuffer(false), + mBufferType(btype), + mDevice(device) + { + mSizeInBytes = sizeBytes; + mDesc.ByteWidth = static_cast(sizeBytes); + mDesc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage); + mDesc.MiscFlags = 0; + + if (useSystemMemory) + { + mDesc.Usage = D3D11_USAGE_STAGING; + //A D3D11_USAGE_STAGING Resource cannot be bound to any parts of the graphics pipeline, so therefore cannot have any BindFlags bits set. + mDesc.BindFlags = 0; + mDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ ;// A D3D11_USAGE_STAGING Resource must have at least one CPUAccessFlag bit set. + + } + else + { + mDesc.Usage = D3D11Mappings::_getUsage(mUsage); + mDesc.BindFlags = btype == VERTEX_BUFFER ? D3D11_BIND_VERTEX_BUFFER : + btype == INDEX_BUFFER ? D3D11_BIND_INDEX_BUFFER : + D3D11_BIND_CONSTANT_BUFFER; + } + // Better check of stream out flag + if (streamOut && btype != CONSTANT_BUFFER) + { + mDesc.BindFlags |= D3D11_BIND_STREAM_OUTPUT; + } + + if (!useSystemMemory && (usage & HardwareBuffer::HBU_DYNAMIC)) + { + // We want to be able to map this buffer + mDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; + mDesc.Usage = D3D11_USAGE_DYNAMIC; + } + + // Note that in D3D11 you can only directly lock (map) a dynamic resource + // directly for writing. You can only map for read / write staging resources, + // which themselves cannot be used for input / output to the GPU. Thus + // for any locks except write locks on dynamic resources, we have to use + // temporary staging resources instead and use async copies. + // We use the 'useSystemMemory' option to indicate a staging resource + + + // TODO: we can explicitly initialise the buffer contents here if we like + // not doing this since OGRE doesn't support this model yet + HRESULT hr = device->CreateBuffer( &mDesc, NULL, &mlpD3DBuffer ); + if (FAILED(hr) || mDevice.isError()) + { + String msg = device.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D11 buffer: " + msg, + "D3D11HardwareBuffer::D3D11HardwareBuffer"); + } + + // Create shadow buffer + if (mUseShadowBuffer) + { + mShadowBuffer = new D3D11HardwareBuffer(mBufferType, + mSizeInBytes, mUsage, mDevice, true, false, false); + } + + } + //--------------------------------------------------------------------- + D3D11HardwareBuffer::~D3D11HardwareBuffer() + { + SAFE_RELEASE(mlpD3DBuffer); + SAFE_DELETE(mpTempStagingBuffer); // should never be nonzero unless destroyed while locked + SAFE_DELETE(mShadowBuffer); + } + //--------------------------------------------------------------------- + void* D3D11HardwareBuffer::lockImpl(size_t offset, + size_t length, LockOptions options) + { + if (length > mSizeInBytes) + { + // need to realloc + mDesc.ByteWidth = static_cast(mSizeInBytes); + SAFE_RELEASE(mlpD3DBuffer); + HRESULT hr = mDevice->CreateBuffer( &mDesc, 0, &mlpD3DBuffer ); + if (FAILED(hr) || mDevice.isError()) + { + String msg = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D11 buffer: " + msg, + "D3D11HardwareBuffer::D3D11HardwareBuffer"); + } + } + + + if (mSystemMemory || + (mUsage & HardwareBuffer::HBU_DYNAMIC && + (options == HardwareBuffer::HBL_DISCARD || options == HardwareBuffer::HBL_NO_OVERWRITE))) + { + // Staging (system memory) buffers or dynamic, write-only buffers + // are the only case where we can lock directly + // We have no 'lock for writing' but discard + locking the entire + // buffer essentially means the same thing, especially since it's + // not possible to map part of a buffer in Dx11 + + // map directly + D3D11_MAP mapType; + switch(options) + { + case HBL_DISCARD: + // To use D3D11_MAP_WRITE_DISCARD resource must have been created with write access and dynamic usage. + mapType = mSystemMemory ? D3D11_MAP_WRITE : D3D11_MAP_WRITE_DISCARD; + break; + case HBL_NO_OVERWRITE: + // To use D3D11_MAP_WRITE_NO_OVERWRITE resource must have been created with write access. + // TODO: check (mSystemMemory aka D3D11_USAGE_STAGING => D3D11_MAP_WRITE_NO_OVERWRITE) combo - it`s not forbidden by MSDN + mapType = mSystemMemory ? D3D11_MAP_WRITE : D3D11_MAP_WRITE_NO_OVERWRITE; + break; + case HBL_NORMAL: + mapType = (mDesc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) ? D3D11_MAP_READ_WRITE : D3D11_MAP_WRITE; + break; + case HBL_READ_ONLY: + mapType = D3D11_MAP_READ; + break; + case HBL_WRITE_ONLY: + mapType = D3D11_MAP_WRITE; + break; + } + + void * pRet = NULL; + D3D11_MAPPED_SUBRESOURCE mappedSubResource; + mappedSubResource.pData = NULL; + mDevice.clearStoredErrorMessages(); + HRESULT hr = mDevice.GetImmediateContext()->Map(mlpD3DBuffer, 0, mapType, 0, &mappedSubResource); + if (FAILED(hr) || mDevice.isError()) + { + String msg = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Error calling Map: " + msg, + "D3D11HardwareBuffer::lockImpl"); + } + + pRet = static_cast(static_cast(mappedSubResource.pData) + offset); + + return pRet; + + } + else + { + mUseTempStagingBuffer = true; + if (!mpTempStagingBuffer) + { + // create another buffer instance but use system memory + mpTempStagingBuffer = new D3D11HardwareBuffer(mBufferType, + mSizeInBytes, mUsage, mDevice, true, false, false); + } + + // schedule a copy to the staging + if (options != HBL_DISCARD) + mpTempStagingBuffer->copyData(*this, 0, 0, mSizeInBytes, true); + + // register whether we'll need to upload on unlock + mStagingUploadNeeded = (options != HBL_READ_ONLY); + + return mpTempStagingBuffer->lock(offset, length, options); + + + } + } + //--------------------------------------------------------------------- + void D3D11HardwareBuffer::unlockImpl(void) + { + + if (mUseTempStagingBuffer) + { + mUseTempStagingBuffer = false; + + // ok, we locked the staging buffer + mpTempStagingBuffer->unlock(); + + // copy data if needed + // this is async but driver should keep reference + if (mStagingUploadNeeded) + copyData(*mpTempStagingBuffer, 0, 0, mSizeInBytes, true); + + // delete + // not that efficient, but we should not be locking often + SAFE_DELETE(mpTempStagingBuffer); + } + else + { + // unmap + mDevice.GetImmediateContext()->Unmap(mlpD3DBuffer, 0); + } + } + //--------------------------------------------------------------------- + void D3D11HardwareBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset, + size_t dstOffset, size_t length, bool discardWholeBuffer) + { + // If we're copying same-size buffers in their entirety... + if (srcOffset == 0 && dstOffset == 0 && + length == mSizeInBytes && mSizeInBytes == srcBuffer.getSizeInBytes()) + { + // schedule hardware buffer copy + mDevice.GetImmediateContext()->CopyResource(mlpD3DBuffer, static_cast(srcBuffer).getD3DBuffer()); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot copy D3D11 resource\nError Description:" + errorDescription, + "D3D11HardwareBuffer::copyData"); + } + } + else + { + // copy subregion + D3D11_BOX srcBox; + srcBox.left = (UINT)srcOffset; + srcBox.right = (UINT)srcOffset + length; + srcBox.top = 0; + srcBox.bottom = 1; + srcBox.front = 0; + srcBox.back = 1; + + mDevice.GetImmediateContext()->CopySubresourceRegion(mlpD3DBuffer, 0, (UINT)dstOffset, 0, 0, + static_cast(srcBuffer).getD3DBuffer(), 0, &srcBox); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot copy D3D11 subresource region\nError Description:" + errorDescription, + "D3D11HardwareBuffer::copyData"); + } + } + } + //--------------------------------------------------------------------- + void D3D11HardwareBuffer::readData(size_t offset, size_t length, + void* pDest) + { + // There is no functional interface in D3D, just do via manual + // lock, copy & unlock + void* pSrc = this->lock(offset, length, HardwareBuffer::HBL_READ_ONLY); + memcpy(pDest, pSrc, length); + this->unlock(); + + } + //--------------------------------------------------------------------- + void D3D11HardwareBuffer::writeData(size_t offset, size_t length, + const void* pSource, + bool discardWholeBuffer) + { + // There is no functional interface in D3D, just do via manual + // lock, copy & unlock + void* pDst = this->lock(offset, length, + discardWholeBuffer ? HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL); + memcpy(pDst, pSource, length); + this->unlock(); + + //What if we try UpdateSubresource + //mDevice.GetImmediateContext()->UpdateSubresource(mlpD3DBuffer, 0, NULL, pSource, offset, length); + } + //--------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11HardwareBufferManager.cpp b/RenderSystems/Direct3D11/src/OgreD3D11HardwareBufferManager.cpp index 2658be7220a..fdcb9a505b7 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11HardwareBufferManager.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11HardwareBufferManager.cpp @@ -36,237 +36,237 @@ THE SOFTWARE. #include "OgreD3D11Device.h" namespace Ogre { - //----------------------------------------------------------------------- - D3D11HardwareBufferManagerBase::D3D11HardwareBufferManagerBase(D3D11Device & device) - : mlpD3DDevice(device) - { - } - //----------------------------------------------------------------------- - D3D11HardwareBufferManagerBase::~D3D11HardwareBufferManagerBase() - { - destroyAllDeclarations(); - destroyAllBindings(); - } - //----------------------------------------------------------------------- - HardwareVertexBufferSharedPtr - D3D11HardwareBufferManagerBase:: - createVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, - bool useShadowBuffer) - { - assert (numVerts > 0); - D3D11HardwareVertexBuffer* vbuf = new D3D11HardwareVertexBuffer( - this, vertexSize, numVerts, usage, mlpD3DDevice, false, useShadowBuffer, false); - { + //----------------------------------------------------------------------- + D3D11HardwareBufferManagerBase::D3D11HardwareBufferManagerBase(D3D11Device & device) + : mlpD3DDevice(device) + { + } + //----------------------------------------------------------------------- + D3D11HardwareBufferManagerBase::~D3D11HardwareBufferManagerBase() + { + destroyAllDeclarations(); + destroyAllBindings(); + } + //----------------------------------------------------------------------- + HardwareVertexBufferSharedPtr + D3D11HardwareBufferManagerBase:: + createVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, + bool useShadowBuffer) + { + assert (numVerts > 0); + D3D11HardwareVertexBuffer* vbuf = new D3D11HardwareVertexBuffer( + this, vertexSize, numVerts, usage, mlpD3DDevice, false, useShadowBuffer, false); + { OGRE_LOCK_MUTEX(mVertexBuffersMutex); - mVertexBuffers.insert(vbuf); - } - return HardwareVertexBufferSharedPtr(vbuf); - } - //----------------------------------------------------------------------- - HardwareVertexBufferSharedPtr - D3D11HardwareBufferManagerBase:: - createStreamOutputVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, - bool useShadowBuffer) - { - assert (numVerts > 0); - D3D11HardwareVertexBuffer* vbuf = new D3D11HardwareVertexBuffer( - this, vertexSize, numVerts, usage, mlpD3DDevice, false, useShadowBuffer, true); - { + mVertexBuffers.insert(vbuf); + } + return HardwareVertexBufferSharedPtr(vbuf); + } + //----------------------------------------------------------------------- + HardwareVertexBufferSharedPtr + D3D11HardwareBufferManagerBase:: + createStreamOutputVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, + bool useShadowBuffer) + { + assert (numVerts > 0); + D3D11HardwareVertexBuffer* vbuf = new D3D11HardwareVertexBuffer( + this, vertexSize, numVerts, usage, mlpD3DDevice, false, useShadowBuffer, true); + { OGRE_LOCK_MUTEX(mVertexBuffersMutex); - mVertexBuffers.insert(vbuf); - } - return HardwareVertexBufferSharedPtr(vbuf); - } - //----------------------------------------------------------------------- - HardwareIndexBufferSharedPtr - D3D11HardwareBufferManagerBase:: - createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, - HardwareBuffer::Usage usage, bool useShadowBuffer) - { - assert (numIndexes > 0); - D3D11HardwareIndexBuffer* idx = new D3D11HardwareIndexBuffer( - this, itype, numIndexes, usage, mlpD3DDevice, false, useShadowBuffer); - { + mVertexBuffers.insert(vbuf); + } + return HardwareVertexBufferSharedPtr(vbuf); + } + //----------------------------------------------------------------------- + HardwareIndexBufferSharedPtr + D3D11HardwareBufferManagerBase:: + createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, + HardwareBuffer::Usage usage, bool useShadowBuffer) + { + assert (numIndexes > 0); + D3D11HardwareIndexBuffer* idx = new D3D11HardwareIndexBuffer( + this, itype, numIndexes, usage, mlpD3DDevice, false, useShadowBuffer); + { OGRE_LOCK_MUTEX(mIndexBuffersMutex); - mIndexBuffers.insert(idx); - } - return HardwareIndexBufferSharedPtr(idx); + mIndexBuffers.insert(idx); + } + return HardwareIndexBufferSharedPtr(idx); - } - //----------------------------------------------------------------------- - RenderToVertexBufferSharedPtr - D3D11HardwareBufferManagerBase::createRenderToVertexBuffer() - { - return RenderToVertexBufferSharedPtr(new D3D11RenderToVertexBuffer(mlpD3DDevice, this)); - } - //----------------------------------------------------------------------- - HardwareUniformBufferSharedPtr - D3D11HardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - { - assert (sizeBytes > 0); - D3D11HardwareUniformBuffer* uni = 0; - /* - if (name != "") - { - SharedUniformBufferMap::iterator it = mSharedUniformBuffers.find(name); - if (it != mSharedUniformBuffers.end()) - { - uni = static_cast(it->second); - assert (uni->getSizeInBytes() == sizeBytes); - assert (uni->getUsage() == usage); - } - else - { - uni = new D3D11HardwareUniformBuffer(this, sizeBytes, usage, useShadowBuffer, name, mlpD3DDevice); - { - OGRE_LOCK_MUTEX(mUniformBuffersMutex) - mUniformBuffers.insert(uni); - //mSharedUniformBuffers.insert(std::make_pair(name, uni)); - } - } - } - else - {*/ - uni = new D3D11HardwareUniformBuffer(this, sizeBytes, usage, useShadowBuffer, name, mlpD3DDevice); - { - OGRE_LOCK_MUTEX(mUniformBuffersMutex); - mUniformBuffers.insert(uni); - } - //} + } + //----------------------------------------------------------------------- + RenderToVertexBufferSharedPtr + D3D11HardwareBufferManagerBase::createRenderToVertexBuffer() + { + return RenderToVertexBufferSharedPtr(new D3D11RenderToVertexBuffer(mlpD3DDevice, this)); + } + //----------------------------------------------------------------------- + HardwareUniformBufferSharedPtr + D3D11HardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) + { + assert (sizeBytes > 0); + D3D11HardwareUniformBuffer* uni = 0; + /* + if (name != "") + { + SharedUniformBufferMap::iterator it = mSharedUniformBuffers.find(name); + if (it != mSharedUniformBuffers.end()) + { + uni = static_cast(it->second); + assert (uni->getSizeInBytes() == sizeBytes); + assert (uni->getUsage() == usage); + } + else + { + uni = new D3D11HardwareUniformBuffer(this, sizeBytes, usage, useShadowBuffer, name, mlpD3DDevice); + { + OGRE_LOCK_MUTEX(mUniformBuffersMutex) + mUniformBuffers.insert(uni); + //mSharedUniformBuffers.insert(std::make_pair(name, uni)); + } + } + } + else + {*/ + uni = new D3D11HardwareUniformBuffer(this, sizeBytes, usage, useShadowBuffer, name, mlpD3DDevice); + { + OGRE_LOCK_MUTEX(mUniformBuffersMutex); + mUniformBuffers.insert(uni); + } + //} - return HardwareUniformBufferSharedPtr(uni); - } + return HardwareUniformBufferSharedPtr(uni); + } //----------------------------------------------------------------------- - HardwareCounterBufferSharedPtr + HardwareCounterBufferSharedPtr D3D11HardwareBufferManagerBase::createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - { + { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "*** not implemented ***", "D3D11HardwareBufferManagerBase::createCounterBuffer"); - } - //----------------------------------------------------------------------- - VertexDeclaration* D3D11HardwareBufferManagerBase::createVertexDeclarationImpl(void) - { - return new D3D11VertexDeclaration(mlpD3DDevice); - } - //----------------------------------------------------------------------- - void D3D11HardwareBufferManagerBase::destroyVertexDeclarationImpl(VertexDeclaration* decl) - { - delete decl; - } - //----------------------------------------------------------------------- - void D3D11HardwareBufferManagerBase::releaseDefaultPoolResources(void) - { - size_t iCount = 0; - size_t vCount = 0; - size_t uCount = 0; + } + //----------------------------------------------------------------------- + VertexDeclaration* D3D11HardwareBufferManagerBase::createVertexDeclarationImpl(void) + { + return new D3D11VertexDeclaration(mlpD3DDevice); + } + //----------------------------------------------------------------------- + void D3D11HardwareBufferManagerBase::destroyVertexDeclarationImpl(VertexDeclaration* decl) + { + delete decl; + } + //----------------------------------------------------------------------- + void D3D11HardwareBufferManagerBase::releaseDefaultPoolResources(void) + { + size_t iCount = 0; + size_t vCount = 0; + size_t uCount = 0; - { + { OGRE_LOCK_MUTEX(mVertexBuffersMutex); - VertexBufferList::iterator v, vend; - vend = mVertexBuffers.end(); - for (v = mVertexBuffers.begin(); v != vend; ++v) - { - D3D11HardwareVertexBuffer* vbuf = - static_cast(*v); - if (vbuf->releaseIfDefaultPool()) - vCount++; - } - } + VertexBufferList::iterator v, vend; + vend = mVertexBuffers.end(); + for (v = mVertexBuffers.begin(); v != vend; ++v) + { + D3D11HardwareVertexBuffer* vbuf = + static_cast(*v); + if (vbuf->releaseIfDefaultPool()) + vCount++; + } + } - { + { OGRE_LOCK_MUTEX(mIndexBuffersMutex); - IndexBufferList::iterator i, iend; - iend = mIndexBuffers.end(); - for (i = mIndexBuffers.begin(); i != iend; ++i) - { - D3D11HardwareIndexBuffer* ibuf = - static_cast(*i); - if (ibuf->releaseIfDefaultPool()) - iCount++; + IndexBufferList::iterator i, iend; + iend = mIndexBuffers.end(); + for (i = mIndexBuffers.begin(); i != iend; ++i) + { + D3D11HardwareIndexBuffer* ibuf = + static_cast(*i); + if (ibuf->releaseIfDefaultPool()) + iCount++; - } - } + } + } - { - OGRE_LOCK_MUTEX(mUniformBuffersMutex); - UniformBufferList::iterator i, iend; - iend = mUniformBuffers.end(); - for (i = mUniformBuffers.begin(); i != iend; ++i) - { - D3D11HardwareUniformBuffer* ubuf = - static_cast(*i); - if (ubuf->releaseIfDefaultPool()) - uCount++; + { + OGRE_LOCK_MUTEX(mUniformBuffersMutex); + UniformBufferList::iterator i, iend; + iend = mUniformBuffers.end(); + for (i = mUniformBuffers.begin(); i != iend; ++i) + { + D3D11HardwareUniformBuffer* ubuf = + static_cast(*i); + if (ubuf->releaseIfDefaultPool()) + uCount++; - } - } + } + } - LogManager::getSingleton().logMessage("D3D11HardwareBufferManagerBase released:"); - LogManager::getSingleton().logMessage( - StringConverter::toString(vCount) + " unmanaged vertex buffers"); - LogManager::getSingleton().logMessage( - StringConverter::toString(iCount) + " unmanaged index buffers"); - LogManager::getSingleton().logMessage( - StringConverter::toString(uCount) + " unmanaged uniform buffers"); - } - //----------------------------------------------------------------------- - void D3D11HardwareBufferManagerBase::recreateDefaultPoolResources(void) - { - size_t iCount = 0; - size_t vCount = 0; - size_t uCount = 0; + LogManager::getSingleton().logMessage("D3D11HardwareBufferManagerBase released:"); + LogManager::getSingleton().logMessage( + StringConverter::toString(vCount) + " unmanaged vertex buffers"); + LogManager::getSingleton().logMessage( + StringConverter::toString(iCount) + " unmanaged index buffers"); + LogManager::getSingleton().logMessage( + StringConverter::toString(uCount) + " unmanaged uniform buffers"); + } + //----------------------------------------------------------------------- + void D3D11HardwareBufferManagerBase::recreateDefaultPoolResources(void) + { + size_t iCount = 0; + size_t vCount = 0; + size_t uCount = 0; - { + { OGRE_LOCK_MUTEX(mVertexBuffersMutex); - VertexBufferList::iterator v, vend; - vend = mVertexBuffers.end(); - for (v = mVertexBuffers.begin(); v != vend; ++v) - { - D3D11HardwareVertexBuffer* vbuf = - static_cast(*v); - if (vbuf->recreateIfDefaultPool(mlpD3DDevice)) - vCount++; - } - } + VertexBufferList::iterator v, vend; + vend = mVertexBuffers.end(); + for (v = mVertexBuffers.begin(); v != vend; ++v) + { + D3D11HardwareVertexBuffer* vbuf = + static_cast(*v); + if (vbuf->recreateIfDefaultPool(mlpD3DDevice)) + vCount++; + } + } - { + { OGRE_LOCK_MUTEX(mIndexBuffersMutex); - IndexBufferList::iterator i, iend; - iend = mIndexBuffers.end(); - for (i = mIndexBuffers.begin(); i != iend; ++i) - { - D3D11HardwareIndexBuffer* ibuf = - static_cast(*i); - if (ibuf->recreateIfDefaultPool(mlpD3DDevice)) - iCount++; + IndexBufferList::iterator i, iend; + iend = mIndexBuffers.end(); + for (i = mIndexBuffers.begin(); i != iend; ++i) + { + D3D11HardwareIndexBuffer* ibuf = + static_cast(*i); + if (ibuf->recreateIfDefaultPool(mlpD3DDevice)) + iCount++; - } - } + } + } - { - OGRE_LOCK_MUTEX(mUniformBuffersMutex); - UniformBufferList::iterator i, iend; - iend = mUniformBuffers.end(); - for (i = mUniformBuffers.begin(); i != iend; ++i) - { - D3D11HardwareUniformBuffer* ubuf = - static_cast(*i); - if (ubuf->releaseIfDefaultPool()) - uCount++; + { + OGRE_LOCK_MUTEX(mUniformBuffersMutex); + UniformBufferList::iterator i, iend; + iend = mUniformBuffers.end(); + for (i = mUniformBuffers.begin(); i != iend; ++i) + { + D3D11HardwareUniformBuffer* ubuf = + static_cast(*i); + if (ubuf->releaseIfDefaultPool()) + uCount++; - } - } + } + } - LogManager::getSingleton().logMessage("D3D11HardwareBufferManagerBase recreated:"); - LogManager::getSingleton().logMessage( - StringConverter::toString(vCount) + " unmanaged vertex buffers"); - LogManager::getSingleton().logMessage( - StringConverter::toString(iCount) + " unmanaged index buffers"); - LogManager::getSingleton().logMessage( - StringConverter::toString(uCount) + " unmanaged uniform buffers"); - } - //----------------------------------------------------------------------- + LogManager::getSingleton().logMessage("D3D11HardwareBufferManagerBase recreated:"); + LogManager::getSingleton().logMessage( + StringConverter::toString(vCount) + " unmanaged vertex buffers"); + LogManager::getSingleton().logMessage( + StringConverter::toString(iCount) + " unmanaged index buffers"); + LogManager::getSingleton().logMessage( + StringConverter::toString(uCount) + " unmanaged uniform buffers"); + } + //----------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11HardwareIndexBuffer.cpp b/RenderSystems/Direct3D11/src/OgreD3D11HardwareIndexBuffer.cpp index 8257a1a2b74..88c105b1537 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11HardwareIndexBuffer.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11HardwareIndexBuffer.cpp @@ -30,102 +30,102 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - D3D11HardwareIndexBuffer::D3D11HardwareIndexBuffer(HardwareBufferManagerBase* mgr, HardwareIndexBuffer::IndexType idxType, - size_t numIndexes, HardwareBuffer::Usage usage, D3D11Device & device, - bool useSystemMemory, bool useShadowBuffer) - : HardwareIndexBuffer(mgr, idxType, numIndexes, usage, useSystemMemory, useShadowBuffer) - { - // everything is done via internal generalisation - mBufferImpl = new D3D11HardwareBuffer(D3D11HardwareBuffer::INDEX_BUFFER, - mSizeInBytes, mUsage, device, useSystemMemory, useShadowBuffer, false); + //--------------------------------------------------------------------- + D3D11HardwareIndexBuffer::D3D11HardwareIndexBuffer(HardwareBufferManagerBase* mgr, HardwareIndexBuffer::IndexType idxType, + size_t numIndexes, HardwareBuffer::Usage usage, D3D11Device & device, + bool useSystemMemory, bool useShadowBuffer) + : HardwareIndexBuffer(mgr, idxType, numIndexes, usage, useSystemMemory, useShadowBuffer) + { + // everything is done via internal generalisation + mBufferImpl = new D3D11HardwareBuffer(D3D11HardwareBuffer::INDEX_BUFFER, + mSizeInBytes, mUsage, device, useSystemMemory, useShadowBuffer, false); - } - //--------------------------------------------------------------------- - D3D11HardwareIndexBuffer::~D3D11HardwareIndexBuffer() - { - delete mBufferImpl; - } - //--------------------------------------------------------------------- - void* D3D11HardwareIndexBuffer::lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt) - { - return mBufferImpl->lock(offset, length, options); - } - //--------------------------------------------------------------------- - void D3D11HardwareIndexBuffer::unlock(void) - { - mBufferImpl->unlock(); - } - //--------------------------------------------------------------------- - void D3D11HardwareIndexBuffer::readData(size_t offset, size_t length, void* pDest) - { - mBufferImpl->readData(offset, length, pDest); - } - //--------------------------------------------------------------------- - void D3D11HardwareIndexBuffer::writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer) - { - mBufferImpl->writeData(offset, length, pSource, discardWholeBuffer); - } - //--------------------------------------------------------------------- - void D3D11HardwareIndexBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset, - size_t dstOffset, size_t length, bool discardWholeBuffer) - { - D3D11HardwareIndexBuffer& d3dBuf = static_cast(srcBuffer); + } + //--------------------------------------------------------------------- + D3D11HardwareIndexBuffer::~D3D11HardwareIndexBuffer() + { + delete mBufferImpl; + } + //--------------------------------------------------------------------- + void* D3D11HardwareIndexBuffer::lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt) + { + return mBufferImpl->lock(offset, length, options); + } + //--------------------------------------------------------------------- + void D3D11HardwareIndexBuffer::unlock(void) + { + mBufferImpl->unlock(); + } + //--------------------------------------------------------------------- + void D3D11HardwareIndexBuffer::readData(size_t offset, size_t length, void* pDest) + { + mBufferImpl->readData(offset, length, pDest); + } + //--------------------------------------------------------------------- + void D3D11HardwareIndexBuffer::writeData(size_t offset, size_t length, const void* pSource, + bool discardWholeBuffer) + { + mBufferImpl->writeData(offset, length, pSource, discardWholeBuffer); + } + //--------------------------------------------------------------------- + void D3D11HardwareIndexBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset, + size_t dstOffset, size_t length, bool discardWholeBuffer) + { + D3D11HardwareIndexBuffer& d3dBuf = static_cast(srcBuffer); - mBufferImpl->copyData(*(d3dBuf.mBufferImpl), srcOffset, dstOffset, length, discardWholeBuffer); - } - //--------------------------------------------------------------------- - bool D3D11HardwareIndexBuffer::isLocked(void) const - { - return mBufferImpl->isLocked(); - } - //--------------------------------------------------------------------- - bool D3D11HardwareIndexBuffer::releaseIfDefaultPool(void) - { - /* if (mD3DPool == D3DPOOL_DEFAULT) - { - SAFE_RELEASE(mlpD3DBuffer); - return true; - } - return false; - */ - return true; - } - //--------------------------------------------------------------------- - bool D3D11HardwareIndexBuffer::recreateIfDefaultPool(D3D11Device & device) - { - /* if (mD3DPool == D3DPOOL_DEFAULT) - { - // Create the Index buffer - HRESULT hr = device->CreateIndexBuffer( - static_cast(mSizeInBytes), - D3D11Mappings::get(mUsage), - D3D11Mappings::get(mIndexType), - mD3DPool, - &mlpD3DBuffer, - NULL - ); + mBufferImpl->copyData(*(d3dBuf.mBufferImpl), srcOffset, dstOffset, length, discardWholeBuffer); + } + //--------------------------------------------------------------------- + bool D3D11HardwareIndexBuffer::isLocked(void) const + { + return mBufferImpl->isLocked(); + } + //--------------------------------------------------------------------- + bool D3D11HardwareIndexBuffer::releaseIfDefaultPool(void) + { + /* if (mD3DPool == D3DPOOL_DEFAULT) + { + SAFE_RELEASE(mlpD3DBuffer); + return true; + } + return false; + */ + return true; + } + //--------------------------------------------------------------------- + bool D3D11HardwareIndexBuffer::recreateIfDefaultPool(D3D11Device & device) + { + /* if (mD3DPool == D3DPOOL_DEFAULT) + { + // Create the Index buffer + HRESULT hr = device->CreateIndexBuffer( + static_cast(mSizeInBytes), + D3D11Mappings::get(mUsage), + D3D11Mappings::get(mIndexType), + mD3DPool, + &mlpD3DBuffer, + NULL + ); - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D11 Index buffer: " + msg, - "D3D11HardwareIndexBuffer::D3D11HardwareIndexBuffer"); - } + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D11 Index buffer: " + msg, + "D3D11HardwareIndexBuffer::D3D11HardwareIndexBuffer"); + } - return true; - } - return false; - */ - return true; - } - //--------------------------------------------------------------------- - ID3D11Buffer * D3D11HardwareIndexBuffer::getD3DIndexBuffer( void ) const - { - return mBufferImpl->getD3DBuffer(); - } - //--------------------------------------------------------------------- + return true; + } + return false; + */ + return true; + } + //--------------------------------------------------------------------- + ID3D11Buffer * D3D11HardwareIndexBuffer::getD3DIndexBuffer( void ) const + { + return mBufferImpl->getD3DBuffer(); + } + //--------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11HardwareOcclusionQuery.cpp b/RenderSystems/Direct3D11/src/OgreD3D11HardwareOcclusionQuery.cpp index fd4d3dc1711..202bef434c6 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11HardwareOcclusionQuery.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11HardwareOcclusionQuery.cpp @@ -31,70 +31,70 @@ THE SOFTWARE. #include "OgreD3D11Device.h" namespace Ogre { - /** - * This is a class that is the DirectX9 implementation of - * hardware occlusion testing. - * - * @author Lee Sandberg - * - * Updated on 12/7/2004 by Chris McGuirk - * Updated on 4/8/2005 by Tuan Kuranes email: tuan.kuranes@free.fr - */ + /** + * This is a class that is the DirectX9 implementation of + * hardware occlusion testing. + * + * @author Lee Sandberg + * + * Updated on 12/7/2004 by Chris McGuirk + * Updated on 4/8/2005 by Tuan Kuranes email: tuan.kuranes@free.fr + */ - /** - * Default object constructor - */ + /** + * Default object constructor + */ D3D11HardwareOcclusionQuery::D3D11HardwareOcclusionQuery( D3D11Device & device ) : mDevice(device) - { - D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_OCCLUSION; + { + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = D3D11_QUERY_OCCLUSION; queryDesc.MiscFlags = 0; - // create the occlusion query - const HRESULT hr = mDevice->CreateQuery(&queryDesc, &mQuery); + // create the occlusion query + const HRESULT hr = mDevice->CreateQuery(&queryDesc, &mQuery); - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Cannot allocate a Hardware query. This video card doesn't supports it, sorry.\nError Description:" + errorDescription, - "D3D11HardwareOcclusionQuery::D3D11HardwareOcclusionQuery"); - } - } + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Cannot allocate a Hardware query. This video card doesn't supports it, sorry.\nError Description:" + errorDescription, + "D3D11HardwareOcclusionQuery::D3D11HardwareOcclusionQuery"); + } + } - /** - * Object destructor - */ - D3D11HardwareOcclusionQuery::~D3D11HardwareOcclusionQuery() - { - SAFE_RELEASE(mQuery); - } + /** + * Object destructor + */ + D3D11HardwareOcclusionQuery::~D3D11HardwareOcclusionQuery() + { + SAFE_RELEASE(mQuery); + } - //------------------------------------------------------------------ - // Occlusion query functions (see base class documentation for this) - //-- - void D3D11HardwareOcclusionQuery::beginOcclusionQuery() - { - mDevice.GetImmediateContext()->Begin(mQuery);//Issue(D3DISSUE_BEGIN); + //------------------------------------------------------------------ + // Occlusion query functions (see base class documentation for this) + //-- + void D3D11HardwareOcclusionQuery::beginOcclusionQuery() + { + mDevice.GetImmediateContext()->Begin(mQuery);//Issue(D3DISSUE_BEGIN); mIsQueryResultStillOutstanding = true; mPixelCount = 0; - } + } - void D3D11HardwareOcclusionQuery::endOcclusionQuery() - { - mDevice.GetImmediateContext()->End(mQuery);//Issue(D3DISSUE_END); - } + void D3D11HardwareOcclusionQuery::endOcclusionQuery() + { + mDevice.GetImmediateContext()->End(mQuery);//Issue(D3DISSUE_END); + } - //------------------------------------------------------------------ - bool D3D11HardwareOcclusionQuery::pullOcclusionQuery( unsigned int* NumOfFragments ) - { + //------------------------------------------------------------------ + bool D3D11HardwareOcclusionQuery::pullOcclusionQuery( unsigned int* NumOfFragments ) + { // in case you didn't check if query arrived and want the result now. if (mIsQueryResultStillOutstanding) { // Loop until the data becomes available UINT64 pixels; const size_t dataSize = sizeof( UINT64 ); - while (1) + while (1) { const HRESULT hr = mDevice.GetImmediateContext()->GetData(mQuery, (void *)&pixels, dataSize, 0);//D3DGETDATA_FLUSH @@ -106,17 +106,17 @@ namespace Ogre { *NumOfFragments = pixels; break; } - //in directx10 the device will never be lost + //in directx10 the device will never be lost /* if (hr == D3DERR_DEVICELOST) { *NumOfFragments = 100000; mPixelCount = 100000; - D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_OCCLUSION; - mDevice->CreateQuery(%queryDesc, &mQuery); + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = D3D11_QUERY_OCCLUSION; + mDevice->CreateQuery(%queryDesc, &mQuery); break; } - */ + */ } mIsQueryResultStillOutstanding = false; } @@ -124,9 +124,9 @@ namespace Ogre { { // we already stored result from last frames. *NumOfFragments = mPixelCount; - } - return true; - } + } + return true; + } //------------------------------------------------------------------ bool D3D11HardwareOcclusionQuery::isStillOutstanding(void) { @@ -144,10 +144,10 @@ namespace Ogre { { mPixelCount = 100000; D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_OCCLUSION; - mDevice->CreateQuery(&queryDesc, &mQuery); + queryDesc.Query = D3D11_QUERY_OCCLUSION; + mDevice->CreateQuery(&queryDesc, &mQuery); } - */ + */ mPixelCount = pixels; mIsQueryResultStillOutstanding = false; return false; diff --git a/RenderSystems/Direct3D11/src/OgreD3D11HardwarePixelBuffer.cpp b/RenderSystems/Direct3D11/src/OgreD3D11HardwarePixelBuffer.cpp index 1af71d408b2..6e83cc6feee 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11HardwarePixelBuffer.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11HardwarePixelBuffer.cpp @@ -43,865 +43,865 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------------- - - D3D11HardwarePixelBuffer::D3D11HardwarePixelBuffer(D3D11Texture * parentTexture, D3D11Device & device, size_t subresourceIndex, - size_t width, size_t height, size_t depth, size_t face, PixelFormat format, HardwareBuffer::Usage usage): - HardwarePixelBuffer(width, height, depth, format, usage, false, false), - mParentTexture(parentTexture), - mDevice(device), - mSubresourceIndex(subresourceIndex), - mFace(face), - mDataForStaticUsageLock(0), - mStagingBuffer(NULL) - { - if(mUsage & TU_RENDERTARGET) - { - // Create render target for each slice - mSliceTRT.reserve(mDepth); - for(size_t zoffset=0; zoffsetgetName(); - - RenderTexture *trt = new D3D11RenderTexture(name, this, mDevice); - mSliceTRT.push_back(trt); - Root::getSingleton().getRenderSystem()->attachRenderTarget(*trt); - } - } - } - D3D11HardwarePixelBuffer::~D3D11HardwarePixelBuffer() - { - if(!mSliceTRT.empty()) - { - // Delete all render targets that are not yet deleted via _clearSliceRTT - for(size_t zoffset=0; zoffsetdestroyRenderTarget(mSliceTRT[zoffset]->getName()); - } - } - - //if (mDataForStaticUsageLock != NULL) - { - SAFE_DELETE_ARRAY(mDataForStaticUsageLock) ; - } - SAFE_RELEASE(mStagingBuffer); - } - //----------------------------------------------------------------------------- - // Util functions to convert a D3D locked box to a pixel box - void D3D11HardwarePixelBuffer::fromD3DLock(PixelBox &rval, const DXGI_MAPPED_RECT &lrect) - { - rval.rowPitch = lrect.Pitch / PixelUtil::getNumElemBytes(rval.format); - rval.slicePitch = rval.rowPitch * rval.getHeight(); - assert((lrect.Pitch % PixelUtil::getNumElemBytes(rval.format))==0); - rval.data = lrect.pBits; - } + //----------------------------------------------------------------------------- + + D3D11HardwarePixelBuffer::D3D11HardwarePixelBuffer(D3D11Texture * parentTexture, D3D11Device & device, size_t subresourceIndex, + size_t width, size_t height, size_t depth, size_t face, PixelFormat format, HardwareBuffer::Usage usage): + HardwarePixelBuffer(width, height, depth, format, usage, false, false), + mParentTexture(parentTexture), + mDevice(device), + mSubresourceIndex(subresourceIndex), + mFace(face), + mDataForStaticUsageLock(0), + mStagingBuffer(NULL) + { + if(mUsage & TU_RENDERTARGET) + { + // Create render target for each slice + mSliceTRT.reserve(mDepth); + for(size_t zoffset=0; zoffsetgetName(); + + RenderTexture *trt = new D3D11RenderTexture(name, this, mDevice); + mSliceTRT.push_back(trt); + Root::getSingleton().getRenderSystem()->attachRenderTarget(*trt); + } + } + } + D3D11HardwarePixelBuffer::~D3D11HardwarePixelBuffer() + { + if(!mSliceTRT.empty()) + { + // Delete all render targets that are not yet deleted via _clearSliceRTT + for(size_t zoffset=0; zoffsetdestroyRenderTarget(mSliceTRT[zoffset]->getName()); + } + } + + //if (mDataForStaticUsageLock != NULL) + { + SAFE_DELETE_ARRAY(mDataForStaticUsageLock) ; + } + SAFE_RELEASE(mStagingBuffer); + } + //----------------------------------------------------------------------------- + // Util functions to convert a D3D locked box to a pixel box + void D3D11HardwarePixelBuffer::fromD3DLock(PixelBox &rval, const DXGI_MAPPED_RECT &lrect) + { + rval.rowPitch = lrect.Pitch / PixelUtil::getNumElemBytes(rval.format); + rval.slicePitch = rval.rowPitch * rval.getHeight(); + assert((lrect.Pitch % PixelUtil::getNumElemBytes(rval.format))==0); + rval.data = lrect.pBits; + } //----------------------------------------------------------------------------- - void D3D11HardwarePixelBuffer::_map(ID3D11Resource *res, D3D11_MAP flags, PixelBox & box) - { - mDevice.clearStoredErrorMessages(); - - D3D11_MAPPED_SUBRESOURCE pMappedResource; - pMappedResource.pData = NULL; - - switch(mParentTexture->getTextureType()) - { - case TEX_TYPE_1D: - { - mDevice.GetImmediateContext()->Map(res, static_cast(mSubresourceIndex), flags, 0, &pMappedResource); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot map 1D texture\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::_map"); - } - } - break; - case TEX_TYPE_CUBE_MAP: - case TEX_TYPE_2D: - { - mDevice.GetImmediateContext()->Map(res, D3D11CalcSubresource(static_cast(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), - flags, 0, &pMappedResource); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot map 2D texture\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::_map"); - } - } - break; - case TEX_TYPE_2D_ARRAY: - { - mDevice.GetImmediateContext()->Map(res, D3D11CalcSubresource(static_cast(mSubresourceIndex), mLockBox.front, mParentTexture->getNumMipmaps()+1), - flags, 0, &pMappedResource); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot map 2D texture array\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::_map"); - } - } - break; - case TEX_TYPE_3D: - { - mDevice.GetImmediateContext()->Map(res, static_cast(mSubresourceIndex), flags, 0, &pMappedResource); - - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot map 3D texture\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::lockImpl"); - } - } - break; - } - - box.data = pMappedResource.pData; + void D3D11HardwarePixelBuffer::_map(ID3D11Resource *res, D3D11_MAP flags, PixelBox & box) + { + mDevice.clearStoredErrorMessages(); + + D3D11_MAPPED_SUBRESOURCE pMappedResource; + pMappedResource.pData = NULL; + + switch(mParentTexture->getTextureType()) + { + case TEX_TYPE_1D: + { + mDevice.GetImmediateContext()->Map(res, static_cast(mSubresourceIndex), flags, 0, &pMappedResource); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot map 1D texture\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::_map"); + } + } + break; + case TEX_TYPE_CUBE_MAP: + case TEX_TYPE_2D: + { + mDevice.GetImmediateContext()->Map(res, D3D11CalcSubresource(static_cast(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), + flags, 0, &pMappedResource); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot map 2D texture\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::_map"); + } + } + break; + case TEX_TYPE_2D_ARRAY: + { + mDevice.GetImmediateContext()->Map(res, D3D11CalcSubresource(static_cast(mSubresourceIndex), mLockBox.front, mParentTexture->getNumMipmaps()+1), + flags, 0, &pMappedResource); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot map 2D texture array\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::_map"); + } + } + break; + case TEX_TYPE_3D: + { + mDevice.GetImmediateContext()->Map(res, static_cast(mSubresourceIndex), flags, 0, &pMappedResource); + + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot map 3D texture\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::lockImpl"); + } + } + break; + } + + box.data = pMappedResource.pData; box.rowPitch = pMappedResource.RowPitch; box.slicePitch = pMappedResource.DepthPitch; - } - //----------------------------------------------------------------------------- - void *D3D11HardwarePixelBuffer::_mapstaticbuffer(PixelBox lock) - { - // for static usage just alloc - size_t sizeOfImage = lock.getConsecutiveSize(); - - mDataForStaticUsageLock = new int8[sizeOfImage]; - return mDataForStaticUsageLock; - } - //----------------------------------------------------------------------------- - void *D3D11HardwarePixelBuffer::_mapstagingbuffer(D3D11_MAP flags) - { - if(!mStagingBuffer) - createStagingBuffer(); - - if(flags == D3D11_MAP_READ_WRITE || flags == D3D11_MAP_READ || flags == D3D11_MAP_WRITE) - { - if(mLockBox.getHeight() == mParentTexture->getHeight() && mLockBox.getWidth() == mParentTexture->getWidth()) - mDevice.GetImmediateContext()->CopyResource(mStagingBuffer, mParentTexture->getTextureResource()); - else - { - D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(mLockBox); - dstBoxDx11.front = 0; - dstBoxDx11.back = mLockBox.getDepth(); - - unsigned int subresource = D3D11CalcSubresource(mSubresourceIndex, mLockBox.front, mParentTexture->getNumMipmaps()+1); - mDevice.GetImmediateContext()->CopySubresourceRegion(mStagingBuffer, subresource, mLockBox.left, mLockBox.top, mSubresourceIndex, mParentTexture->getTextureResource(), subresource, &dstBoxDx11); - } - } - else if(flags == D3D11_MAP_WRITE_DISCARD) - flags = D3D11_MAP_WRITE; // stagingbuffer doesn't support discarding + } + //----------------------------------------------------------------------------- + void *D3D11HardwarePixelBuffer::_mapstaticbuffer(PixelBox lock) + { + // for static usage just alloc + size_t sizeOfImage = lock.getConsecutiveSize(); + + mDataForStaticUsageLock = new int8[sizeOfImage]; + return mDataForStaticUsageLock; + } + //----------------------------------------------------------------------------- + void *D3D11HardwarePixelBuffer::_mapstagingbuffer(D3D11_MAP flags) + { + if(!mStagingBuffer) + createStagingBuffer(); + + if(flags == D3D11_MAP_READ_WRITE || flags == D3D11_MAP_READ || flags == D3D11_MAP_WRITE) + { + if(mLockBox.getHeight() == mParentTexture->getHeight() && mLockBox.getWidth() == mParentTexture->getWidth()) + mDevice.GetImmediateContext()->CopyResource(mStagingBuffer, mParentTexture->getTextureResource()); + else + { + D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(mLockBox); + dstBoxDx11.front = 0; + dstBoxDx11.back = mLockBox.getDepth(); + + unsigned int subresource = D3D11CalcSubresource(mSubresourceIndex, mLockBox.front, mParentTexture->getNumMipmaps()+1); + mDevice.GetImmediateContext()->CopySubresourceRegion(mStagingBuffer, subresource, mLockBox.left, mLockBox.top, mSubresourceIndex, mParentTexture->getTextureResource(), subresource, &dstBoxDx11); + } + } + else if(flags == D3D11_MAP_WRITE_DISCARD) + flags = D3D11_MAP_WRITE; // stagingbuffer doesn't support discarding PixelBox box; _map(mStagingBuffer, flags, box); - return box.data; - } - //----------------------------------------------------------------------------- - PixelBox D3D11HardwarePixelBuffer::lockImpl(const Image::Box &lockBox, LockOptions options) - { - // Check for misuse - if(mUsage & TU_RENDERTARGET) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "DirectX does not allow locking of or directly writing to RenderTargets. Use blitFromMemory if you need the contents.", - "D3D11HardwarePixelBuffer::lockImpl"); - - mLockBox = lockBox; - - // Set extents and format - // Note that we do not carry over the left/top/front here, since the returned - // PixelBox will be re-based from the locking point onwards - PixelBox rval(lockBox.getWidth(), lockBox.getHeight(), lockBox.getDepth(), mFormat); - // Set locking flags according to options - D3D11_MAP flags = D3D11_MAP_WRITE_DISCARD ; - switch(options) - { - case HBL_NO_OVERWRITE: - flags = D3D11_MAP_WRITE_NO_OVERWRITE; - break; - case HBL_NORMAL: - flags = D3D11_MAP_READ_WRITE; - break; - case HBL_DISCARD: - flags = D3D11_MAP_WRITE_DISCARD; - break; - case HBL_READ_ONLY: - flags = D3D11_MAP_READ; - break; - case HBL_WRITE_ONLY: - flags = D3D11_MAP_WRITE; - break; - default: - break; - }; - - size_t offset = 0; - - if(mUsage == HBU_STATIC || mUsage & HBU_DYNAMIC) - { - if(mUsage == HBU_STATIC || options == HBL_READ_ONLY || options == HBL_NORMAL || options == HBL_WRITE_ONLY) - rval.data = _mapstagingbuffer(flags); - else - _map(mParentTexture->getTextureResource(), flags, rval); - - // calculate the offset in bytes - offset = D3D11Mappings::_getSizeInBytes(rval.format, rval.left, rval.front); - // add the offset, so the right memory will be changed - //rval.data = static_cast(rval.data) + offset; - } - else - { - size_t sizeOfImage = rval.getConsecutiveSize(); + return box.data; + } + //----------------------------------------------------------------------------- + PixelBox D3D11HardwarePixelBuffer::lockImpl(const Image::Box &lockBox, LockOptions options) + { + // Check for misuse + if(mUsage & TU_RENDERTARGET) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "DirectX does not allow locking of or directly writing to RenderTargets. Use blitFromMemory if you need the contents.", + "D3D11HardwarePixelBuffer::lockImpl"); + + mLockBox = lockBox; + + // Set extents and format + // Note that we do not carry over the left/top/front here, since the returned + // PixelBox will be re-based from the locking point onwards + PixelBox rval(lockBox.getWidth(), lockBox.getHeight(), lockBox.getDepth(), mFormat); + // Set locking flags according to options + D3D11_MAP flags = D3D11_MAP_WRITE_DISCARD ; + switch(options) + { + case HBL_NO_OVERWRITE: + flags = D3D11_MAP_WRITE_NO_OVERWRITE; + break; + case HBL_NORMAL: + flags = D3D11_MAP_READ_WRITE; + break; + case HBL_DISCARD: + flags = D3D11_MAP_WRITE_DISCARD; + break; + case HBL_READ_ONLY: + flags = D3D11_MAP_READ; + break; + case HBL_WRITE_ONLY: + flags = D3D11_MAP_WRITE; + break; + default: + break; + }; + + size_t offset = 0; + + if(mUsage == HBU_STATIC || mUsage & HBU_DYNAMIC) + { + if(mUsage == HBU_STATIC || options == HBL_READ_ONLY || options == HBL_NORMAL || options == HBL_WRITE_ONLY) + rval.data = _mapstagingbuffer(flags); + else + _map(mParentTexture->getTextureResource(), flags, rval); + + // calculate the offset in bytes + offset = D3D11Mappings::_getSizeInBytes(rval.format, rval.left, rval.front); + // add the offset, so the right memory will be changed + //rval.data = static_cast(rval.data) + offset; + } + else + { + size_t sizeOfImage = rval.getConsecutiveSize(); mDataForStaticUsageLock = new int8[sizeOfImage]; rval.data = mDataForStaticUsageLock; - } - // save without offset - mCurrentLock = rval; - mCurrentLockOptions = options; - - // add the offset, so the right memory will be changed - rval.data = static_cast(rval.data) + offset; - - return rval; - } - //----------------------------------------------------------------------------- - void D3D11HardwarePixelBuffer::_unmap(ID3D11Resource *res) - { - switch(mParentTexture->getTextureType()) { - case TEX_TYPE_1D: - { - mDevice.GetImmediateContext()->Unmap(res, mSubresourceIndex); - } - break; - case TEX_TYPE_CUBE_MAP: - case TEX_TYPE_2D: - { - mDevice.GetImmediateContext()->Unmap(res, D3D11CalcSubresource(static_cast(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1)); - } - break; - case TEX_TYPE_2D_ARRAY: - { - mDevice.GetImmediateContext()->Unmap(res, D3D11CalcSubresource(static_cast(mSubresourceIndex), mLockBox.front, mParentTexture->getNumMipmaps()+1)); - } - break; - case TEX_TYPE_3D: - { - mDevice.GetImmediateContext()->Unmap(res, mSubresourceIndex); - } - break; - } - - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device unmap resource\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::_unmap"); - } - } - //----------------------------------------------------------------------------- - void D3D11HardwarePixelBuffer::_unmapstaticbuffer() - { - D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(mLockBox); - dstBoxDx11.front = 0; - dstBoxDx11.back = mLockBox.getDepth(); - - size_t rowWidth = D3D11Mappings::_getSizeInBytes(mCurrentLock.format, mCurrentLock.getWidth()); - - switch(mParentTexture->getTextureType()) { - case TEX_TYPE_1D: - { - - mDevice.GetImmediateContext()->UpdateSubresource(mParentTexture->GetTex1D(), - static_cast(mSubresourceIndex), &dstBoxDx11, - mDataForStaticUsageLock, rowWidth, 0); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot map 1D texture\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::_unmapstaticbuffer"); - } - } - break; - case TEX_TYPE_CUBE_MAP: - case TEX_TYPE_2D: - { - mDevice.GetImmediateContext()->UpdateSubresource(mParentTexture->GetTex2D(), - D3D11CalcSubresource(static_cast(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), - &dstBoxDx11, - mDataForStaticUsageLock, rowWidth, 0); - - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot map 2D texture\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::_unmapstaticbuffer"); - } - } - break; - case TEX_TYPE_2D_ARRAY: - { - mDevice.GetImmediateContext()->UpdateSubresource(mParentTexture->GetTex2D(), - D3D11CalcSubresource(static_cast(mSubresourceIndex), mLockBox.front, mParentTexture->getNumMipmaps()+1), - &dstBoxDx11, mDataForStaticUsageLock, rowWidth, 0); - - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot map 2D texture array\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::_unmapstaticbuffer"); - } - } - break; - case TEX_TYPE_3D: - { - size_t sliceWidth = D3D11Mappings::_getSizeInBytes(mCurrentLock.format, mCurrentLock.getWidth(), mCurrentLock.getHeight()); - - mDevice.GetImmediateContext()->UpdateSubresource(mParentTexture->GetTex3D(), static_cast(mSubresourceIndex), - &dstBoxDx11, mDataForStaticUsageLock, rowWidth, sliceWidth); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot map 3D texture\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::_unmapstaticbuffer"); - } - } - break; - } - - SAFE_DELETE_ARRAY(mDataForStaticUsageLock) ; - } - //----------------------------------------------------------------------------- - void D3D11HardwarePixelBuffer::_unmapstagingbuffer(bool copyback) - { - _unmap(mStagingBuffer); - - if(copyback) - { - if(mLockBox.getHeight() == mParentTexture->getHeight() && mLockBox.getWidth() == mParentTexture->getWidth()) - mDevice.GetImmediateContext()->CopyResource(mParentTexture->getTextureResource(), mStagingBuffer); - else - { - D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(mLockBox); - dstBoxDx11.front = 0; - dstBoxDx11.back = mLockBox.getDepth(); - - unsigned int subresource = D3D11CalcSubresource(mSubresourceIndex, mLockBox.front, mParentTexture->getNumMipmaps()+1); - mDevice.GetImmediateContext()->CopySubresourceRegion(mParentTexture->getTextureResource(), subresource, mLockBox.left, mLockBox.top, mSubresourceIndex, mStagingBuffer, subresource, &dstBoxDx11); - } - } - } - //----------------------------------------------------------------------------- - void D3D11HardwarePixelBuffer::unlockImpl(void) - { - if(mUsage == HBU_STATIC) - _unmapstagingbuffer(); - else if(mUsage & HBU_DYNAMIC) - { - if(mCurrentLockOptions == HBL_READ_ONLY || mCurrentLockOptions == HBL_NORMAL || mCurrentLockOptions == HBL_WRITE_ONLY) - { - size_t sizeinbytes = D3D11Mappings::_getSizeInBytes(mParentTexture->getFormat(), mParentTexture->getWidth(), mParentTexture->getHeight()); + } + // save without offset + mCurrentLock = rval; + mCurrentLockOptions = options; + + // add the offset, so the right memory will be changed + rval.data = static_cast(rval.data) + offset; + + return rval; + } + //----------------------------------------------------------------------------- + void D3D11HardwarePixelBuffer::_unmap(ID3D11Resource *res) + { + switch(mParentTexture->getTextureType()) { + case TEX_TYPE_1D: + { + mDevice.GetImmediateContext()->Unmap(res, mSubresourceIndex); + } + break; + case TEX_TYPE_CUBE_MAP: + case TEX_TYPE_2D: + { + mDevice.GetImmediateContext()->Unmap(res, D3D11CalcSubresource(static_cast(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1)); + } + break; + case TEX_TYPE_2D_ARRAY: + { + mDevice.GetImmediateContext()->Unmap(res, D3D11CalcSubresource(static_cast(mSubresourceIndex), mLockBox.front, mParentTexture->getNumMipmaps()+1)); + } + break; + case TEX_TYPE_3D: + { + mDevice.GetImmediateContext()->Unmap(res, mSubresourceIndex); + } + break; + } + + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device unmap resource\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::_unmap"); + } + } + //----------------------------------------------------------------------------- + void D3D11HardwarePixelBuffer::_unmapstaticbuffer() + { + D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(mLockBox); + dstBoxDx11.front = 0; + dstBoxDx11.back = mLockBox.getDepth(); + + size_t rowWidth = D3D11Mappings::_getSizeInBytes(mCurrentLock.format, mCurrentLock.getWidth()); + + switch(mParentTexture->getTextureType()) { + case TEX_TYPE_1D: + { + + mDevice.GetImmediateContext()->UpdateSubresource(mParentTexture->GetTex1D(), + static_cast(mSubresourceIndex), &dstBoxDx11, + mDataForStaticUsageLock, rowWidth, 0); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot map 1D texture\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::_unmapstaticbuffer"); + } + } + break; + case TEX_TYPE_CUBE_MAP: + case TEX_TYPE_2D: + { + mDevice.GetImmediateContext()->UpdateSubresource(mParentTexture->GetTex2D(), + D3D11CalcSubresource(static_cast(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), + &dstBoxDx11, + mDataForStaticUsageLock, rowWidth, 0); + + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot map 2D texture\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::_unmapstaticbuffer"); + } + } + break; + case TEX_TYPE_2D_ARRAY: + { + mDevice.GetImmediateContext()->UpdateSubresource(mParentTexture->GetTex2D(), + D3D11CalcSubresource(static_cast(mSubresourceIndex), mLockBox.front, mParentTexture->getNumMipmaps()+1), + &dstBoxDx11, mDataForStaticUsageLock, rowWidth, 0); + + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot map 2D texture array\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::_unmapstaticbuffer"); + } + } + break; + case TEX_TYPE_3D: + { + size_t sliceWidth = D3D11Mappings::_getSizeInBytes(mCurrentLock.format, mCurrentLock.getWidth(), mCurrentLock.getHeight()); + + mDevice.GetImmediateContext()->UpdateSubresource(mParentTexture->GetTex3D(), static_cast(mSubresourceIndex), + &dstBoxDx11, mDataForStaticUsageLock, rowWidth, sliceWidth); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot map 3D texture\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::_unmapstaticbuffer"); + } + } + break; + } + + SAFE_DELETE_ARRAY(mDataForStaticUsageLock) ; + } + //----------------------------------------------------------------------------- + void D3D11HardwarePixelBuffer::_unmapstagingbuffer(bool copyback) + { + _unmap(mStagingBuffer); + + if(copyback) + { + if(mLockBox.getHeight() == mParentTexture->getHeight() && mLockBox.getWidth() == mParentTexture->getWidth()) + mDevice.GetImmediateContext()->CopyResource(mParentTexture->getTextureResource(), mStagingBuffer); + else + { + D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(mLockBox); + dstBoxDx11.front = 0; + dstBoxDx11.back = mLockBox.getDepth(); + + unsigned int subresource = D3D11CalcSubresource(mSubresourceIndex, mLockBox.front, mParentTexture->getNumMipmaps()+1); + mDevice.GetImmediateContext()->CopySubresourceRegion(mParentTexture->getTextureResource(), subresource, mLockBox.left, mLockBox.top, mSubresourceIndex, mStagingBuffer, subresource, &dstBoxDx11); + } + } + } + //----------------------------------------------------------------------------- + void D3D11HardwarePixelBuffer::unlockImpl(void) + { + if(mUsage == HBU_STATIC) + _unmapstagingbuffer(); + else if(mUsage & HBU_DYNAMIC) + { + if(mCurrentLockOptions == HBL_READ_ONLY || mCurrentLockOptions == HBL_NORMAL || mCurrentLockOptions == HBL_WRITE_ONLY) + { + size_t sizeinbytes = D3D11Mappings::_getSizeInBytes(mParentTexture->getFormat(), mParentTexture->getWidth(), mParentTexture->getHeight()); PixelBox box; _map(mParentTexture->getTextureResource(), D3D11_MAP_WRITE_DISCARD, box); - void *data = box.data; - - memcpy(data, mCurrentLock.data, sizeinbytes); - - // unmap the texture and the staging buffer - _unmap(mParentTexture->getTextureResource()); - - _unmapstagingbuffer(false); - } - else - _unmap(mParentTexture->getTextureResource()); - } - else - _unmapstaticbuffer(); - - _genMipmaps(); - } - //----------------------------------------------------------------------------- - D3D11_BOX D3D11HardwarePixelBuffer::OgreImageBoxToDx11Box(const Image::Box &inBox) const - { - D3D11_BOX res; - res.left = static_cast(inBox.left); - res.top = static_cast(inBox.top); - res.front = static_cast(inBox.front); - res.right = static_cast(inBox.right); - res.bottom = static_cast(inBox.bottom); - res.back = static_cast(inBox.back); - - return res; - } - - //----------------------------------------------------------------------------- - - void D3D11HardwarePixelBuffer::blit(const HardwarePixelBufferSharedPtr &rsrc, const Image::Box &srcBox, const Image::Box &dstBox) - { - if ( - (srcBox.getWidth() != dstBox.getWidth()) - || (srcBox.getHeight() != dstBox.getHeight()) - || (srcBox.getDepth() != dstBox.getDepth()) - ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot copy a subresource - source and dest size are not the same and they have to be the same in DX11.", - "D3D11HardwarePixelBuffer::blit"); - } - - D3D11_BOX srcBoxDx11 = OgreImageBoxToDx11Box(srcBox); - - - D3D11HardwarePixelBuffer * rsrcDx11 = static_cast(rsrc.get()); - - switch(mParentTexture->getTextureType()) { - case TEX_TYPE_1D: - { - - mDevice.GetImmediateContext()->CopySubresourceRegion( - mParentTexture->GetTex1D(), - static_cast(mSubresourceIndex), - static_cast(dstBox.left), - 0, - 0, - rsrcDx11->mParentTexture->GetTex1D(), - static_cast(rsrcDx11->mSubresourceIndex), - &srcBoxDx11); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot copy 1d subresource Region\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::blit"); - } - } - break; - case TEX_TYPE_CUBE_MAP: - case TEX_TYPE_2D: - { - mDevice.GetImmediateContext()->CopySubresourceRegion( - mParentTexture->GetTex2D(), - D3D11CalcSubresource(static_cast(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), - static_cast(dstBox.left), - static_cast(dstBox.top), - mFace, - rsrcDx11->mParentTexture->GetTex2D(), - static_cast(rsrcDx11->mSubresourceIndex), - &srcBoxDx11); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot copy 2d subresource Region\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::blit"); - } - } - break; - case TEX_TYPE_2D_ARRAY: - { - mDevice.GetImmediateContext()->CopySubresourceRegion( - mParentTexture->GetTex2D(), - D3D11CalcSubresource(static_cast(mSubresourceIndex), srcBox.front, mParentTexture->getNumMipmaps()+1), - static_cast(dstBox.left), - static_cast(dstBox.top), - srcBox.front, - rsrcDx11->mParentTexture->GetTex2D(), - static_cast(rsrcDx11->mSubresourceIndex), - &srcBoxDx11); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot copy 2d subresource Region\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::blit"); - } - } - break; - case TEX_TYPE_3D: - { - mDevice.GetImmediateContext()->CopySubresourceRegion( - mParentTexture->GetTex3D(), - static_cast(mSubresourceIndex), - static_cast(dstBox.left), - static_cast(dstBox.top), - static_cast(dstBox.front), - rsrcDx11->mParentTexture->GetTex3D(), - static_cast(rsrcDx11->mSubresourceIndex), - &srcBoxDx11); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot copy 3d subresource Region\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::blit"); - } - } - break; - } - - _genMipmaps(); - } - //----------------------------------------------------------------------------- - void D3D11HardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox) - { - bool isDds = false; - switch(mFormat) - { - case PF_DXT1: - case PF_DXT2: - case PF_DXT3: - case PF_DXT4: - case PF_DXT5: - isDds = true; - break; - default: - - break; - } - - if (isDds && (dstBox.getWidth() % 4 != 0 || dstBox.getHeight() % 4 != 0 )) - { - return; - } - - - // for scoped deletion of conversion buffer - MemoryDataStreamPtr buf; - PixelBox converted = src; - - D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(dstBox); - dstBoxDx11.front = 0; - dstBoxDx11.back = converted.getDepth(); - - // convert to pixelbuffer's native format if necessary - if (src.format != mFormat) - { - buf.bind(new MemoryDataStream( - PixelUtil::getMemorySize(src.getWidth(), src.getHeight(), src.getDepth(), - mFormat))); - converted = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), mFormat, buf->getPtr()); - PixelUtil::bulkPixelConversion(src, converted); - } - - if (mUsage & HBU_DYNAMIC) - { - size_t sizeinbytes; - if (PixelUtil::isCompressed(converted.format)) - { - // D3D wants the width of one row of cells in bytes - if (converted.format == PF_DXT1) - { - // 64 bits (8 bytes) per 4x4 block - sizeinbytes = std::max(1, converted.getWidth() / 4) * std::max(1, converted.getHeight() / 4) * 8; - } - else - { - // 128 bits (16 bytes) per 4x4 block - sizeinbytes = std::max(1, converted.getWidth() / 4) * std::max(1, converted.getHeight() / 4) * 16; - } - } - else - { - sizeinbytes = converted.getHeight() * converted.getWidth() * PixelUtil::getNumElemBytes(converted.format); - } - - const Ogre::PixelBox &locked = lock(dstBox, HBL_DISCARD); - - int srcRowPitch = converted.rowPitch * PixelUtil::getNumElemBytes(converted.format); - int destRowPitch = locked.rowPitch; - - byte *src = (byte*)converted.data; - byte *dst = (byte*)locked.data; - - for (int row = 0 ; row < converted.getHeight() ; row ++ ) - { - memcpy((void*)dst,(void*)src,srcRowPitch); - src += srcRowPitch; - dst += destRowPitch; - } - unlock(); - } - else - { - size_t rowWidth; - if (PixelUtil::isCompressed(converted.format)) - { - // D3D wants the width of one row of cells in bytes - if (converted.format == PF_DXT1) - { - // 64 bits (8 bytes) per 4x4 block - rowWidth = (converted.rowPitch / 4) * 8; - } - else - { - // 128 bits (16 bytes) per 4x4 block - rowWidth = (converted.rowPitch / 4) * 16; - } - } - else - { - rowWidth = converted.rowPitch * PixelUtil::getNumElemBytes(converted.format); - } - - switch(mParentTexture->getTextureType()) { - case TEX_TYPE_1D: - { - D3D11RenderSystem* rsys = reinterpret_cast(Root::getSingleton().getRenderSystem()); - if (rsys->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) - { - mDevice.GetImmediateContext()->UpdateSubresource( - mParentTexture->GetTex1D(), - 0, - &dstBoxDx11, - converted.data, - rowWidth, - 0 ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot update 1d subresource\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::blitFromMemory"); - } - break; // For Feature levels that do not support 1D textures, revert to creating a 2D texture. - } - } - case TEX_TYPE_CUBE_MAP: - case TEX_TYPE_2D: - { - mDevice.GetImmediateContext()->UpdateSubresource( - mParentTexture->GetTex2D(), - D3D11CalcSubresource(static_cast(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), - &dstBoxDx11, - converted.data, - rowWidth, - 0 ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot update 2d subresource\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::blitFromMemory"); - } - } - break; - case TEX_TYPE_2D_ARRAY: - { - mDevice.GetImmediateContext()->UpdateSubresource( - mParentTexture->GetTex2D(), - D3D11CalcSubresource(static_cast(mSubresourceIndex), src.front, mParentTexture->getNumMipmaps()+1), - &dstBoxDx11, - converted.data, - rowWidth, - 0 ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot update 2d array subresource\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::blitFromMemory"); - } - } - break; - case TEX_TYPE_3D: - { - // copied from dx9 - size_t sliceWidth; - if (PixelUtil::isCompressed(converted.format)) - { - // D3D wants the width of one slice of cells in bytes - if (converted.format == PF_DXT1) - { - // 64 bits (8 bytes) per 4x4 block - sliceWidth = (converted.slicePitch / 16) * 8; - } - else - { - // 128 bits (16 bytes) per 4x4 block - sliceWidth = (converted.slicePitch / 16) * 16; - } - - } - else - { - sliceWidth = converted.slicePitch * PixelUtil::getNumElemBytes(converted.format); - } + void *data = box.data; + + memcpy(data, mCurrentLock.data, sizeinbytes); + + // unmap the texture and the staging buffer + _unmap(mParentTexture->getTextureResource()); + + _unmapstagingbuffer(false); + } + else + _unmap(mParentTexture->getTextureResource()); + } + else + _unmapstaticbuffer(); + + _genMipmaps(); + } + //----------------------------------------------------------------------------- + D3D11_BOX D3D11HardwarePixelBuffer::OgreImageBoxToDx11Box(const Image::Box &inBox) const + { + D3D11_BOX res; + res.left = static_cast(inBox.left); + res.top = static_cast(inBox.top); + res.front = static_cast(inBox.front); + res.right = static_cast(inBox.right); + res.bottom = static_cast(inBox.bottom); + res.back = static_cast(inBox.back); + + return res; + } + + //----------------------------------------------------------------------------- + + void D3D11HardwarePixelBuffer::blit(const HardwarePixelBufferSharedPtr &rsrc, const Image::Box &srcBox, const Image::Box &dstBox) + { + if ( + (srcBox.getWidth() != dstBox.getWidth()) + || (srcBox.getHeight() != dstBox.getHeight()) + || (srcBox.getDepth() != dstBox.getDepth()) + ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot copy a subresource - source and dest size are not the same and they have to be the same in DX11.", + "D3D11HardwarePixelBuffer::blit"); + } + + D3D11_BOX srcBoxDx11 = OgreImageBoxToDx11Box(srcBox); + + + D3D11HardwarePixelBuffer * rsrcDx11 = static_cast(rsrc.get()); + + switch(mParentTexture->getTextureType()) { + case TEX_TYPE_1D: + { + + mDevice.GetImmediateContext()->CopySubresourceRegion( + mParentTexture->GetTex1D(), + static_cast(mSubresourceIndex), + static_cast(dstBox.left), + 0, + 0, + rsrcDx11->mParentTexture->GetTex1D(), + static_cast(rsrcDx11->mSubresourceIndex), + &srcBoxDx11); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot copy 1d subresource Region\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::blit"); + } + } + break; + case TEX_TYPE_CUBE_MAP: + case TEX_TYPE_2D: + { + mDevice.GetImmediateContext()->CopySubresourceRegion( + mParentTexture->GetTex2D(), + D3D11CalcSubresource(static_cast(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), + static_cast(dstBox.left), + static_cast(dstBox.top), + mFace, + rsrcDx11->mParentTexture->GetTex2D(), + static_cast(rsrcDx11->mSubresourceIndex), + &srcBoxDx11); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot copy 2d subresource Region\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::blit"); + } + } + break; + case TEX_TYPE_2D_ARRAY: + { + mDevice.GetImmediateContext()->CopySubresourceRegion( + mParentTexture->GetTex2D(), + D3D11CalcSubresource(static_cast(mSubresourceIndex), srcBox.front, mParentTexture->getNumMipmaps()+1), + static_cast(dstBox.left), + static_cast(dstBox.top), + srcBox.front, + rsrcDx11->mParentTexture->GetTex2D(), + static_cast(rsrcDx11->mSubresourceIndex), + &srcBoxDx11); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot copy 2d subresource Region\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::blit"); + } + } + break; + case TEX_TYPE_3D: + { + mDevice.GetImmediateContext()->CopySubresourceRegion( + mParentTexture->GetTex3D(), + static_cast(mSubresourceIndex), + static_cast(dstBox.left), + static_cast(dstBox.top), + static_cast(dstBox.front), + rsrcDx11->mParentTexture->GetTex3D(), + static_cast(rsrcDx11->mSubresourceIndex), + &srcBoxDx11); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot copy 3d subresource Region\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::blit"); + } + } + break; + } + + _genMipmaps(); + } + //----------------------------------------------------------------------------- + void D3D11HardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox) + { + bool isDds = false; + switch(mFormat) + { + case PF_DXT1: + case PF_DXT2: + case PF_DXT3: + case PF_DXT4: + case PF_DXT5: + isDds = true; + break; + default: + + break; + } + + if (isDds && (dstBox.getWidth() % 4 != 0 || dstBox.getHeight() % 4 != 0 )) + { + return; + } + + + // for scoped deletion of conversion buffer + MemoryDataStreamPtr buf; + PixelBox converted = src; + + D3D11_BOX dstBoxDx11 = OgreImageBoxToDx11Box(dstBox); + dstBoxDx11.front = 0; + dstBoxDx11.back = converted.getDepth(); + + // convert to pixelbuffer's native format if necessary + if (src.format != mFormat) + { + buf.bind(new MemoryDataStream( + PixelUtil::getMemorySize(src.getWidth(), src.getHeight(), src.getDepth(), + mFormat))); + converted = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), mFormat, buf->getPtr()); + PixelUtil::bulkPixelConversion(src, converted); + } + + if (mUsage & HBU_DYNAMIC) + { + size_t sizeinbytes; + if (PixelUtil::isCompressed(converted.format)) + { + // D3D wants the width of one row of cells in bytes + if (converted.format == PF_DXT1) + { + // 64 bits (8 bytes) per 4x4 block + sizeinbytes = std::max(1, converted.getWidth() / 4) * std::max(1, converted.getHeight() / 4) * 8; + } + else + { + // 128 bits (16 bytes) per 4x4 block + sizeinbytes = std::max(1, converted.getWidth() / 4) * std::max(1, converted.getHeight() / 4) * 16; + } + } + else + { + sizeinbytes = converted.getHeight() * converted.getWidth() * PixelUtil::getNumElemBytes(converted.format); + } + + const Ogre::PixelBox &locked = lock(dstBox, HBL_DISCARD); + + int srcRowPitch = converted.rowPitch * PixelUtil::getNumElemBytes(converted.format); + int destRowPitch = locked.rowPitch; + + byte *src = (byte*)converted.data; + byte *dst = (byte*)locked.data; + + for (int row = 0 ; row < converted.getHeight() ; row ++ ) + { + memcpy((void*)dst,(void*)src,srcRowPitch); + src += srcRowPitch; + dst += destRowPitch; + } + unlock(); + } + else + { + size_t rowWidth; + if (PixelUtil::isCompressed(converted.format)) + { + // D3D wants the width of one row of cells in bytes + if (converted.format == PF_DXT1) + { + // 64 bits (8 bytes) per 4x4 block + rowWidth = (converted.rowPitch / 4) * 8; + } + else + { + // 128 bits (16 bytes) per 4x4 block + rowWidth = (converted.rowPitch / 4) * 16; + } + } + else + { + rowWidth = converted.rowPitch * PixelUtil::getNumElemBytes(converted.format); + } + + switch(mParentTexture->getTextureType()) { + case TEX_TYPE_1D: + { + D3D11RenderSystem* rsys = reinterpret_cast(Root::getSingleton().getRenderSystem()); + if (rsys->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) + { + mDevice.GetImmediateContext()->UpdateSubresource( + mParentTexture->GetTex1D(), + 0, + &dstBoxDx11, + converted.data, + rowWidth, + 0 ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot update 1d subresource\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::blitFromMemory"); + } + break; // For Feature levels that do not support 1D textures, revert to creating a 2D texture. + } + } + case TEX_TYPE_CUBE_MAP: + case TEX_TYPE_2D: + { + mDevice.GetImmediateContext()->UpdateSubresource( + mParentTexture->GetTex2D(), + D3D11CalcSubresource(static_cast(mSubresourceIndex), mFace, mParentTexture->getNumMipmaps()+1), + &dstBoxDx11, + converted.data, + rowWidth, + 0 ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot update 2d subresource\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::blitFromMemory"); + } + } + break; + case TEX_TYPE_2D_ARRAY: + { + mDevice.GetImmediateContext()->UpdateSubresource( + mParentTexture->GetTex2D(), + D3D11CalcSubresource(static_cast(mSubresourceIndex), src.front, mParentTexture->getNumMipmaps()+1), + &dstBoxDx11, + converted.data, + rowWidth, + 0 ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot update 2d array subresource\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::blitFromMemory"); + } + } + break; + case TEX_TYPE_3D: + { + // copied from dx9 + size_t sliceWidth; + if (PixelUtil::isCompressed(converted.format)) + { + // D3D wants the width of one slice of cells in bytes + if (converted.format == PF_DXT1) + { + // 64 bits (8 bytes) per 4x4 block + sliceWidth = (converted.slicePitch / 16) * 8; + } + else + { + // 128 bits (16 bytes) per 4x4 block + sliceWidth = (converted.slicePitch / 16) * 16; + } + + } + else + { + sliceWidth = converted.slicePitch * PixelUtil::getNumElemBytes(converted.format); + } - mDevice.GetImmediateContext()->UpdateSubresource( - mParentTexture->GetTex3D(), - static_cast(mSubresourceIndex), - &dstBoxDx11, - converted.data, - rowWidth, - sliceWidth - ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot update 3d subresource\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::blitFromMemory"); - } - } - break; - } + mDevice.GetImmediateContext()->UpdateSubresource( + mParentTexture->GetTex3D(), + static_cast(mSubresourceIndex), + &dstBoxDx11, + converted.data, + rowWidth, + sliceWidth + ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot update 3d subresource\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::blitFromMemory"); + } + } + break; + } - if (!isDds) - { + if (!isDds) + { _genMipmaps(); - } - } - - } - //----------------------------------------------------------------------------- - void D3D11HardwarePixelBuffer::blitToMemory(const Image::Box &srcBox, const PixelBox &dst) - { - // Decide on pixel format of temp surface - PixelFormat tmpFormat = mFormat; - if(D3D11Mappings::_getPF(dst.format) != DXGI_FORMAT_UNKNOWN) - { - tmpFormat = dst.format; - } - assert(srcBox.getDepth() == 1 && dst.getDepth() == 1); - - //This is a pointer to the texture we're trying to copy - //Only implemented for 2D at the moment... - ID3D11Texture2D *textureResource = mParentTexture->GetTex2D(); - - // get the description of the texture - D3D11_TEXTURE2D_DESC desc = {0}; - textureResource->GetDesc( &desc ); - //Alter the description to set up a staging texture - desc.Usage = D3D11_USAGE_STAGING; - //This texture is not bound to any part of the pipeline - desc.BindFlags = 0; - //Allow CPU Access - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - //No Misc Flags - desc.MiscFlags = 0; - //Create the staging texture - ID3D11Texture2D* pStagingTexture = NULL; - mDevice->CreateTexture2D( &desc, NULL, &pStagingTexture ); - //Copy our texture into the staging texture - mDevice.GetImmediateContext()->CopyResource( pStagingTexture, textureResource ); - //Create a mapped resource and map the staging texture to the resource - D3D11_MAPPED_SUBRESOURCE mapped = {0}; - mDevice.GetImmediateContext()->Map( pStagingTexture, 0, D3D11_MAP_READ , 0, &mapped ); - - // read the data out of the texture. - unsigned int rPitch = mapped.RowPitch; - BYTE *data = ((BYTE *)mapped.pData); - - //Using existing OGRE functions - DXGI_MAPPED_RECT lrect; - lrect.pBits = data; - lrect.Pitch = rPitch; - - - PixelBox locked(dst.getWidth(), dst.getHeight(), dst.getDepth(), tmpFormat); - fromD3DLock(locked, lrect); - PixelUtil::bulkPixelConversion(locked, dst); - - //Release the staging texture - mDevice.GetImmediateContext()->Unmap( pStagingTexture, 0 ); + } + } + + } + //----------------------------------------------------------------------------- + void D3D11HardwarePixelBuffer::blitToMemory(const Image::Box &srcBox, const PixelBox &dst) + { + // Decide on pixel format of temp surface + PixelFormat tmpFormat = mFormat; + if(D3D11Mappings::_getPF(dst.format) != DXGI_FORMAT_UNKNOWN) + { + tmpFormat = dst.format; + } + assert(srcBox.getDepth() == 1 && dst.getDepth() == 1); + + //This is a pointer to the texture we're trying to copy + //Only implemented for 2D at the moment... + ID3D11Texture2D *textureResource = mParentTexture->GetTex2D(); + + // get the description of the texture + D3D11_TEXTURE2D_DESC desc = {0}; + textureResource->GetDesc( &desc ); + //Alter the description to set up a staging texture + desc.Usage = D3D11_USAGE_STAGING; + //This texture is not bound to any part of the pipeline + desc.BindFlags = 0; + //Allow CPU Access + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + //No Misc Flags + desc.MiscFlags = 0; + //Create the staging texture + ID3D11Texture2D* pStagingTexture = NULL; + mDevice->CreateTexture2D( &desc, NULL, &pStagingTexture ); + //Copy our texture into the staging texture + mDevice.GetImmediateContext()->CopyResource( pStagingTexture, textureResource ); + //Create a mapped resource and map the staging texture to the resource + D3D11_MAPPED_SUBRESOURCE mapped = {0}; + mDevice.GetImmediateContext()->Map( pStagingTexture, 0, D3D11_MAP_READ , 0, &mapped ); + + // read the data out of the texture. + unsigned int rPitch = mapped.RowPitch; + BYTE *data = ((BYTE *)mapped.pData); + + //Using existing OGRE functions + DXGI_MAPPED_RECT lrect; + lrect.pBits = data; + lrect.Pitch = rPitch; + + + PixelBox locked(dst.getWidth(), dst.getHeight(), dst.getDepth(), tmpFormat); + fromD3DLock(locked, lrect); + PixelUtil::bulkPixelConversion(locked, dst); + + //Release the staging texture + mDevice.GetImmediateContext()->Unmap( pStagingTexture, 0 ); pStagingTexture->Release(); - } + } - //----------------------------------------------------------------------------- - void D3D11HardwarePixelBuffer::_genMipmaps() - { + //----------------------------------------------------------------------------- + void D3D11HardwarePixelBuffer::_genMipmaps() + { if(mParentTexture->HasAutoMipMapGenerationEnabled()) - { + { ID3D11ShaderResourceView *pShaderResourceView = mParentTexture->getTexture(); ID3D11DeviceContextN * context = mDevice.GetImmediateContext(); - context->GenerateMips(pShaderResourceView); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot generate mips\nError Description:" + errorDescription, - "D3D11HardwarePixelBuffer::_genMipmaps"); - } - } - - } - //----------------------------------------------------------------------------- - RenderTexture *D3D11HardwarePixelBuffer::getRenderTarget(size_t zoffset) - { - assert(mUsage & TU_RENDERTARGET); - assert(zoffset < mDepth); - return mSliceTRT[zoffset]; - } - //----------------------------------------------------------------------------- - D3D11Texture * D3D11HardwarePixelBuffer::getParentTexture() const - { - return mParentTexture; - } - //----------------------------------------------------------------------------- - size_t D3D11HardwarePixelBuffer::getSubresourceIndex() const - { - return mSubresourceIndex; - } - //----------------------------------------------------------------------------- - size_t D3D11HardwarePixelBuffer::getFace() const - { - return mFace; - } - //----------------------------------------------------------------------------- - void D3D11HardwarePixelBuffer::createStagingBuffer() - { - D3D11Texture *tex = static_cast(mParentTexture); - - switch (mParentTexture->getTextureType()) - { - case TEX_TYPE_1D: - { - D3D11_TEXTURE1D_DESC desc; - tex->GetTex1D()->GetDesc(&desc); - - desc.BindFlags = 0; - desc.MiscFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; - desc.Usage = D3D11_USAGE_STAGING; - - mDevice->CreateTexture1D(&desc, NULL, (ID3D11Texture1D**)(&mStagingBuffer)); - } - break; - case TEX_TYPE_2D: - case TEX_TYPE_CUBE_MAP: - case TEX_TYPE_2D_ARRAY: - { - D3D11_TEXTURE2D_DESC desc; - tex->GetTex2D()->GetDesc(&desc); - - desc.BindFlags = 0; - desc.MiscFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; - desc.Usage = D3D11_USAGE_STAGING; - - mDevice->CreateTexture2D(&desc, NULL, (ID3D11Texture2D**)(&mStagingBuffer)); - } - break; - case TEX_TYPE_3D: - { - D3D11_TEXTURE3D_DESC desc; - tex->GetTex3D()->GetDesc(&desc); - - desc.BindFlags = 0; - desc.MiscFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; - desc.Usage = D3D11_USAGE_STAGING; - - mDevice->CreateTexture3D(&desc, NULL, (ID3D11Texture3D**)(&mStagingBuffer)); - } - break; - } - } + context->GenerateMips(pShaderResourceView); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot generate mips\nError Description:" + errorDescription, + "D3D11HardwarePixelBuffer::_genMipmaps"); + } + } + + } + //----------------------------------------------------------------------------- + RenderTexture *D3D11HardwarePixelBuffer::getRenderTarget(size_t zoffset) + { + assert(mUsage & TU_RENDERTARGET); + assert(zoffset < mDepth); + return mSliceTRT[zoffset]; + } + //----------------------------------------------------------------------------- + D3D11Texture * D3D11HardwarePixelBuffer::getParentTexture() const + { + return mParentTexture; + } + //----------------------------------------------------------------------------- + size_t D3D11HardwarePixelBuffer::getSubresourceIndex() const + { + return mSubresourceIndex; + } + //----------------------------------------------------------------------------- + size_t D3D11HardwarePixelBuffer::getFace() const + { + return mFace; + } + //----------------------------------------------------------------------------- + void D3D11HardwarePixelBuffer::createStagingBuffer() + { + D3D11Texture *tex = static_cast(mParentTexture); + + switch (mParentTexture->getTextureType()) + { + case TEX_TYPE_1D: + { + D3D11_TEXTURE1D_DESC desc; + tex->GetTex1D()->GetDesc(&desc); + + desc.BindFlags = 0; + desc.MiscFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; + desc.Usage = D3D11_USAGE_STAGING; + + mDevice->CreateTexture1D(&desc, NULL, (ID3D11Texture1D**)(&mStagingBuffer)); + } + break; + case TEX_TYPE_2D: + case TEX_TYPE_CUBE_MAP: + case TEX_TYPE_2D_ARRAY: + { + D3D11_TEXTURE2D_DESC desc; + tex->GetTex2D()->GetDesc(&desc); + + desc.BindFlags = 0; + desc.MiscFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; + desc.Usage = D3D11_USAGE_STAGING; + + mDevice->CreateTexture2D(&desc, NULL, (ID3D11Texture2D**)(&mStagingBuffer)); + } + break; + case TEX_TYPE_3D: + { + D3D11_TEXTURE3D_DESC desc; + tex->GetTex3D()->GetDesc(&desc); + + desc.BindFlags = 0; + desc.MiscFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; + desc.Usage = D3D11_USAGE_STAGING; + + mDevice->CreateTexture3D(&desc, NULL, (ID3D11Texture3D**)(&mStagingBuffer)); + } + break; + } + } }; diff --git a/RenderSystems/Direct3D11/src/OgreD3D11HardwareUniformBuffer.cpp b/RenderSystems/Direct3D11/src/OgreD3D11HardwareUniformBuffer.cpp index 824d410b054..44736f20849 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11HardwareUniformBuffer.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11HardwareUniformBuffer.cpp @@ -31,80 +31,80 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - D3D11HardwareUniformBuffer::D3D11HardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, - bool useShadowBuffer, const String& name, D3D11Device & device) - : HardwareUniformBuffer(mgr, sizeBytes, usage, useShadowBuffer, name) - , mBufferImpl(0) - - { - // everything is done via internal generalisation - mBufferImpl = new D3D11HardwareBuffer(D3D11HardwareBuffer::CONSTANT_BUFFER, - mSizeInBytes, mUsage, device, false, useShadowBuffer, false); + //--------------------------------------------------------------------- + D3D11HardwareUniformBuffer::D3D11HardwareUniformBuffer(HardwareBufferManagerBase* mgr, size_t sizeBytes, HardwareBuffer::Usage usage, + bool useShadowBuffer, const String& name, D3D11Device & device) + : HardwareUniformBuffer(mgr, sizeBytes, usage, useShadowBuffer, name) + , mBufferImpl(0) + + { + // everything is done via internal generalisation + mBufferImpl = new D3D11HardwareBuffer(D3D11HardwareBuffer::CONSTANT_BUFFER, + mSizeInBytes, mUsage, device, false, useShadowBuffer, false); - } - //--------------------------------------------------------------------- - D3D11HardwareUniformBuffer::~D3D11HardwareUniformBuffer() - { - SAFE_DELETE(mBufferImpl); - } - //--------------------------------------------------------------------- - void* D3D11HardwareUniformBuffer::lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt) - { - return mBufferImpl->lock(offset, length, options); - } - //--------------------------------------------------------------------- - void D3D11HardwareUniformBuffer::unlock(void) - { - mBufferImpl->unlock(); - } - //--------------------------------------------------------------------- - void D3D11HardwareUniformBuffer::readData(size_t offset, size_t length, void* pDest) - { - mBufferImpl->readData(offset, length, pDest); - } - //--------------------------------------------------------------------- - void D3D11HardwareUniformBuffer::writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer) - { - mBufferImpl->writeData(offset, length, pSource, discardWholeBuffer); - } - //--------------------------------------------------------------------- - void D3D11HardwareUniformBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset, - size_t dstOffset, size_t length, bool discardWholeBuffer) - { - // check if the other buffer is also a D3D11HardwareVertexBuffer - if (srcBuffer.isSystemMemory()) - { - // src is not a D3D11HardwareVertexBuffer - use default copy - HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer); - } - else - { - // src is a D3D11HardwareUniformBuffer use d3d11 optimized copy - D3D11HardwareUniformBuffer& d3dBuf = static_cast(srcBuffer); - mBufferImpl->copyData(*(d3dBuf.mBufferImpl), srcOffset, dstOffset, length, discardWholeBuffer); - } - } - //--------------------------------------------------------------------- - bool D3D11HardwareUniformBuffer::isLocked(void) const - { - return mBufferImpl->isLocked(); - } - //--------------------------------------------------------------------- - bool D3D11HardwareUniformBuffer::releaseIfDefaultPool(void) - { - return true; - } - //--------------------------------------------------------------------- - bool D3D11HardwareUniformBuffer::recreateIfDefaultPool(D3D11Device & device) - { - return true; - } - //--------------------------------------------------------------------- - ID3D11Buffer * D3D11HardwareUniformBuffer::getD3DConstantBuffer( void ) const - { - return mBufferImpl->getD3DBuffer(); - } + } + //--------------------------------------------------------------------- + D3D11HardwareUniformBuffer::~D3D11HardwareUniformBuffer() + { + SAFE_DELETE(mBufferImpl); + } + //--------------------------------------------------------------------- + void* D3D11HardwareUniformBuffer::lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt) + { + return mBufferImpl->lock(offset, length, options); + } + //--------------------------------------------------------------------- + void D3D11HardwareUniformBuffer::unlock(void) + { + mBufferImpl->unlock(); + } + //--------------------------------------------------------------------- + void D3D11HardwareUniformBuffer::readData(size_t offset, size_t length, void* pDest) + { + mBufferImpl->readData(offset, length, pDest); + } + //--------------------------------------------------------------------- + void D3D11HardwareUniformBuffer::writeData(size_t offset, size_t length, const void* pSource, + bool discardWholeBuffer) + { + mBufferImpl->writeData(offset, length, pSource, discardWholeBuffer); + } + //--------------------------------------------------------------------- + void D3D11HardwareUniformBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset, + size_t dstOffset, size_t length, bool discardWholeBuffer) + { + // check if the other buffer is also a D3D11HardwareVertexBuffer + if (srcBuffer.isSystemMemory()) + { + // src is not a D3D11HardwareVertexBuffer - use default copy + HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer); + } + else + { + // src is a D3D11HardwareUniformBuffer use d3d11 optimized copy + D3D11HardwareUniformBuffer& d3dBuf = static_cast(srcBuffer); + mBufferImpl->copyData(*(d3dBuf.mBufferImpl), srcOffset, dstOffset, length, discardWholeBuffer); + } + } + //--------------------------------------------------------------------- + bool D3D11HardwareUniformBuffer::isLocked(void) const + { + return mBufferImpl->isLocked(); + } + //--------------------------------------------------------------------- + bool D3D11HardwareUniformBuffer::releaseIfDefaultPool(void) + { + return true; + } + //--------------------------------------------------------------------- + bool D3D11HardwareUniformBuffer::recreateIfDefaultPool(D3D11Device & device) + { + return true; + } + //--------------------------------------------------------------------- + ID3D11Buffer * D3D11HardwareUniformBuffer::getD3DConstantBuffer( void ) const + { + return mBufferImpl->getD3DBuffer(); + } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11HardwareVertexBuffer.cpp b/RenderSystems/Direct3D11/src/OgreD3D11HardwareVertexBuffer.cpp index 05db2552147..5ee2111b445 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11HardwareVertexBuffer.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11HardwareVertexBuffer.cpp @@ -31,113 +31,113 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - D3D11HardwareVertexBuffer::D3D11HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, - size_t numVertices, HardwareBuffer::Usage usage, D3D11Device & device, - bool useSystemMemory, bool useShadowBuffer, bool streamOut) - : HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, useSystemMemory, useShadowBuffer), - mBufferImpl(0) - - { - // everything is done via internal generalisation - mBufferImpl = new D3D11HardwareBuffer(D3D11HardwareBuffer::VERTEX_BUFFER, - mSizeInBytes, mUsage, device, useSystemMemory, useShadowBuffer, streamOut); + //--------------------------------------------------------------------- + D3D11HardwareVertexBuffer::D3D11HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, + size_t numVertices, HardwareBuffer::Usage usage, D3D11Device & device, + bool useSystemMemory, bool useShadowBuffer, bool streamOut) + : HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, useSystemMemory, useShadowBuffer), + mBufferImpl(0) + + { + // everything is done via internal generalisation + mBufferImpl = new D3D11HardwareBuffer(D3D11HardwareBuffer::VERTEX_BUFFER, + mSizeInBytes, mUsage, device, useSystemMemory, useShadowBuffer, streamOut); - } - //--------------------------------------------------------------------- - D3D11HardwareVertexBuffer::~D3D11HardwareVertexBuffer() - { - SAFE_DELETE(mBufferImpl); - } - //--------------------------------------------------------------------- - void* D3D11HardwareVertexBuffer::lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt) - { - return mBufferImpl->lock(offset, length, options); - } - //--------------------------------------------------------------------- - void D3D11HardwareVertexBuffer::unlock(void) - { - mBufferImpl->unlock(); - } - //--------------------------------------------------------------------- - void D3D11HardwareVertexBuffer::readData(size_t offset, size_t length, void* pDest) - { - mBufferImpl->readData(offset, length, pDest); - } - //--------------------------------------------------------------------- - void D3D11HardwareVertexBuffer::writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer) - { - mBufferImpl->writeData(offset, length, pSource, discardWholeBuffer); - } - //--------------------------------------------------------------------- - void D3D11HardwareVertexBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset, - size_t dstOffset, size_t length, bool discardWholeBuffer) - { - // check if the other buffer is also a D3D11HardwareVertexBuffer - if (srcBuffer.isSystemMemory()) - { - // src is not a D3D11HardwareVertexBuffer - use default copy - HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer); - } - else - { - // src is a D3D11HardwareVertexBuffer use d3d11 optimized copy - D3D11HardwareVertexBuffer& d3dBuf = static_cast(srcBuffer); + } + //--------------------------------------------------------------------- + D3D11HardwareVertexBuffer::~D3D11HardwareVertexBuffer() + { + SAFE_DELETE(mBufferImpl); + } + //--------------------------------------------------------------------- + void* D3D11HardwareVertexBuffer::lock(size_t offset, size_t length, LockOptions options, UploadOptions uploadOpt) + { + return mBufferImpl->lock(offset, length, options); + } + //--------------------------------------------------------------------- + void D3D11HardwareVertexBuffer::unlock(void) + { + mBufferImpl->unlock(); + } + //--------------------------------------------------------------------- + void D3D11HardwareVertexBuffer::readData(size_t offset, size_t length, void* pDest) + { + mBufferImpl->readData(offset, length, pDest); + } + //--------------------------------------------------------------------- + void D3D11HardwareVertexBuffer::writeData(size_t offset, size_t length, const void* pSource, + bool discardWholeBuffer) + { + mBufferImpl->writeData(offset, length, pSource, discardWholeBuffer); + } + //--------------------------------------------------------------------- + void D3D11HardwareVertexBuffer::copyData(HardwareBuffer& srcBuffer, size_t srcOffset, + size_t dstOffset, size_t length, bool discardWholeBuffer) + { + // check if the other buffer is also a D3D11HardwareVertexBuffer + if (srcBuffer.isSystemMemory()) + { + // src is not a D3D11HardwareVertexBuffer - use default copy + HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer); + } + else + { + // src is a D3D11HardwareVertexBuffer use d3d11 optimized copy + D3D11HardwareVertexBuffer& d3dBuf = static_cast(srcBuffer); - mBufferImpl->copyData(*(d3dBuf.mBufferImpl), srcOffset, dstOffset, length, discardWholeBuffer); - } - } - //--------------------------------------------------------------------- - bool D3D11HardwareVertexBuffer::isLocked(void) const - { - return mBufferImpl->isLocked(); - } - //--------------------------------------------------------------------- - bool D3D11HardwareVertexBuffer::releaseIfDefaultPool(void) - { - /* if (mD3DPool == D3DPOOL_DEFAULT) - { - SAFE_RELEASE(mlpD3DBuffer); - return true; - } - return false; - */ - return true; - } - //--------------------------------------------------------------------- - bool D3D11HardwareVertexBuffer::recreateIfDefaultPool(D3D11Device & device) - { - /* if (mD3DPool == D3DPOOL_DEFAULT) - { - // Create the Index buffer - HRESULT hr = device->CreateIndexBuffer( - static_cast(mSizeInBytes), - D3D11Mappings::get(mUsage), - D3D11Mappings::get(mIndexType), - mD3DPool, - &mlpD3DBuffer, - NULL - ); + mBufferImpl->copyData(*(d3dBuf.mBufferImpl), srcOffset, dstOffset, length, discardWholeBuffer); + } + } + //--------------------------------------------------------------------- + bool D3D11HardwareVertexBuffer::isLocked(void) const + { + return mBufferImpl->isLocked(); + } + //--------------------------------------------------------------------- + bool D3D11HardwareVertexBuffer::releaseIfDefaultPool(void) + { + /* if (mD3DPool == D3DPOOL_DEFAULT) + { + SAFE_RELEASE(mlpD3DBuffer); + return true; + } + return false; + */ + return true; + } + //--------------------------------------------------------------------- + bool D3D11HardwareVertexBuffer::recreateIfDefaultPool(D3D11Device & device) + { + /* if (mD3DPool == D3DPOOL_DEFAULT) + { + // Create the Index buffer + HRESULT hr = device->CreateIndexBuffer( + static_cast(mSizeInBytes), + D3D11Mappings::get(mUsage), + D3D11Mappings::get(mIndexType), + mD3DPool, + &mlpD3DBuffer, + NULL + ); - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D11 Index buffer: " + msg, - "D3D11HardwareVertexBuffer::D3D11HardwareVertexBuffer"); - } + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D11 Index buffer: " + msg, + "D3D11HardwareVertexBuffer::D3D11HardwareVertexBuffer"); + } - return true; - } - return false; - */ - return true; - } - //--------------------------------------------------------------------- - ID3D11Buffer * D3D11HardwareVertexBuffer::getD3DVertexBuffer( void ) const - { - return mBufferImpl->getD3DBuffer(); - } + return true; + } + return false; + */ + return true; + } + //--------------------------------------------------------------------- + ID3D11Buffer * D3D11HardwareVertexBuffer::getD3DVertexBuffer( void ) const + { + return mBufferImpl->getD3DBuffer(); + } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11Mappings.cpp b/RenderSystems/Direct3D11/src/OgreD3D11Mappings.cpp index b19fc54415e..80d1d5abb12 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11Mappings.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11Mappings.cpp @@ -31,946 +31,946 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - /*DWORD D3D11Mappings::get(ShadeOptions so) - { - switch( so ) - { - case SO_FLAT: - return D3DSHADE_FLAT; - case SO_GOURAUD: - return D3DSHADE_GOURAUD; - case SO_PHONG: - return D3DSHADE_PHONG; - } - return 0; - }*/ - //--------------------------------------------------------------------- - /*D3DLIGHTTYPE D3D11Mappings::get(Light::LightTypes lightType) - { - switch( lightType ) - { - case Light::LT_POINT: - return D3DLIGHT_POINT; - case Light::LT_DIRECTIONAL: - return D3DLIGHT_DIRECTIONAL; - case Light::LT_SPOTLIGHT: - return D3DLIGHT_SPOT; - } - return D3DLIGHT_FORCE_DWORD; - }*/ - //--------------------------------------------------------------------- - /*DWORD D3D11Mappings::get(TexCoordCalcMethod m, const D3DCAPS9& caps) - { - switch( m ) - { - case TEXCALC_NONE: - return D3DTSS_TCI_PASSTHRU; - case TEXCALC_ENVIRONMENT_MAP_REFLECTION: - return D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR; - case TEXCALC_ENVIRONMENT_MAP_PLANAR: - if (caps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN_SPHEREMAP) - { - // Use sphere map if available - return D3DTSS_TCI_SPHEREMAP; - } - else - { - // If not, fall back on camera space reflection vector which isn't as good - return D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR; - } - case TEXCALC_ENVIRONMENT_MAP_NORMAL: - return D3DTSS_TCI_CAMERASPACENORMAL; - case TEXCALC_ENVIRONMENT_MAP: - if (caps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN_SPHEREMAP) - { - // Use sphere map if available - return D3DTSS_TCI_SPHEREMAP; - } - else - { - // If not, fall back on camera space normal which isn't as good - return D3DTSS_TCI_CAMERASPACENORMAL; - } - case TEXCALC_PROJECTIVE_TEXTURE: - return D3DTSS_TCI_CAMERASPACEPOSITION; - } - return 0; - }*/ - //--------------------------------------------------------------------- - D3D11_TEXTURE_ADDRESS_MODE D3D11Mappings::get(TextureUnitState::TextureAddressingMode tam) - { + //--------------------------------------------------------------------- + /*DWORD D3D11Mappings::get(ShadeOptions so) + { + switch( so ) + { + case SO_FLAT: + return D3DSHADE_FLAT; + case SO_GOURAUD: + return D3DSHADE_GOURAUD; + case SO_PHONG: + return D3DSHADE_PHONG; + } + return 0; + }*/ + //--------------------------------------------------------------------- + /*D3DLIGHTTYPE D3D11Mappings::get(Light::LightTypes lightType) + { + switch( lightType ) + { + case Light::LT_POINT: + return D3DLIGHT_POINT; + case Light::LT_DIRECTIONAL: + return D3DLIGHT_DIRECTIONAL; + case Light::LT_SPOTLIGHT: + return D3DLIGHT_SPOT; + } + return D3DLIGHT_FORCE_DWORD; + }*/ + //--------------------------------------------------------------------- + /*DWORD D3D11Mappings::get(TexCoordCalcMethod m, const D3DCAPS9& caps) + { + switch( m ) + { + case TEXCALC_NONE: + return D3DTSS_TCI_PASSTHRU; + case TEXCALC_ENVIRONMENT_MAP_REFLECTION: + return D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR; + case TEXCALC_ENVIRONMENT_MAP_PLANAR: + if (caps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN_SPHEREMAP) + { + // Use sphere map if available + return D3DTSS_TCI_SPHEREMAP; + } + else + { + // If not, fall back on camera space reflection vector which isn't as good + return D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR; + } + case TEXCALC_ENVIRONMENT_MAP_NORMAL: + return D3DTSS_TCI_CAMERASPACENORMAL; + case TEXCALC_ENVIRONMENT_MAP: + if (caps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN_SPHEREMAP) + { + // Use sphere map if available + return D3DTSS_TCI_SPHEREMAP; + } + else + { + // If not, fall back on camera space normal which isn't as good + return D3DTSS_TCI_CAMERASPACENORMAL; + } + case TEXCALC_PROJECTIVE_TEXTURE: + return D3DTSS_TCI_CAMERASPACEPOSITION; + } + return 0; + }*/ + //--------------------------------------------------------------------- + D3D11_TEXTURE_ADDRESS_MODE D3D11Mappings::get(TextureUnitState::TextureAddressingMode tam) + { D3D11RenderSystem* rsys = reinterpret_cast(Root::getSingleton().getRenderSystem()); if (rsys->_getFeatureLevel() == D3D_FEATURE_LEVEL_9_1) - return D3D11_TEXTURE_ADDRESS_WRAP; + return D3D11_TEXTURE_ADDRESS_WRAP; - //return D3D11_TEXTURE_ADDRESS_WRAP; - switch( tam ) - { - case TextureUnitState::TAM_WRAP: - return D3D11_TEXTURE_ADDRESS_WRAP; - case TextureUnitState::TAM_MIRROR: - return D3D11_TEXTURE_ADDRESS_MIRROR; - case TextureUnitState::TAM_CLAMP: - return D3D11_TEXTURE_ADDRESS_CLAMP; - case TextureUnitState::TAM_BORDER: - return D3D11_TEXTURE_ADDRESS_BORDER; - } - return D3D11_TEXTURE_ADDRESS_MIRROR_ONCE; - } - //--------------------------------------------------------------------- - D3D11_BLEND D3D11Mappings::get(LayerBlendType lbt) - { - switch( lbt ) - { - case LBT_COLOUR: - return D3D11_BLEND_SRC_COLOR; - case LBT_ALPHA: - return D3D11_BLEND_SRC_ALPHA; - } - return D3D11_BLEND_ZERO; - } - //--------------------------------------------------------------------- - /*DWORD D3D11Mappings::get(LayerBlendSource lbs) - { - switch( lbs ) - { - case LBS_CURRENT: - return D3DTA_CURRENT; - case LBS_TEXTURE: - return D3DTA_TEXTURE; - case LBS_DIFFUSE: - return D3DTA_DIFFUSE; - case LBS_SPECULAR: - return D3DTA_SPECULAR; - case LBS_MANUAL: - return D3DTA_TFACTOR; - } - return 0; - }*/ - //--------------------------------------------------------------------- - /*DWORD D3D11Mappings::get(LayerBlendOperationEx lbo, const D3DCAPS9& devCaps) - { - switch( lbo ) - { - case LBX_SOURCE1: - return D3DTOP_SELECTARG1; - case LBX_SOURCE2: - return D3DTOP_SELECTARG2; - case LBX_MODULATE: - return D3DTOP_MODULATE; - case LBX_MODULATE_X2: - return D3DTOP_MODULATE2X; - case LBX_MODULATE_X4: - return D3DTOP_MODULATE4X; - case LBX_ADD: - return D3DTOP_ADD; - case LBX_ADD_SIGNED: - return D3DTOP_ADDSIGNED; - case LBX_ADD_SMOOTH: - return D3DTOP_ADDSMOOTH; - case LBX_SUBTRACT: - return D3DTOP_SUBTRACT; - case LBX_BLEND_DIFFUSE_ALPHA: - return D3DTOP_BLENDDIFFUSEALPHA; - case LBX_BLEND_TEXTURE_ALPHA: - return D3DTOP_BLENDTEXTUREALPHA; - case LBX_BLEND_CURRENT_ALPHA: - return D3DTOP_BLENDCURRENTALPHA; - case LBX_BLEND_MANUAL: - return D3DTOP_BLENDFACTORALPHA; - case LBX_DOTPRODUCT: - if (devCaps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) - return D3DTOP_DOTPRODUCT3; - else - return D3DTOP_MODULATE; - case LBX_BLEND_DIFFUSE_COLOUR: - if (devCaps.TextureOpCaps & D3DTEXOPCAPS_LERP) - return D3DTOP_LERP; - else - return D3DTOP_MODULATE; - } - return 0; - }*/ - //--------------------------------------------------------------------- - D3D11_BLEND D3D11Mappings::get(SceneBlendFactor sbf, bool forAlpha) - { - switch( sbf ) - { - case SBF_ONE: return D3D11_BLEND_ONE; - case SBF_ZERO: return D3D11_BLEND_ZERO; - case SBF_DEST_COLOUR: return forAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR; - case SBF_SOURCE_COLOUR: return forAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR; - case SBF_ONE_MINUS_DEST_COLOUR: return forAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR; - case SBF_ONE_MINUS_SOURCE_COLOUR: return forAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR; - case SBF_DEST_ALPHA: return D3D11_BLEND_DEST_ALPHA; - case SBF_SOURCE_ALPHA: return D3D11_BLEND_SRC_ALPHA; - case SBF_ONE_MINUS_DEST_ALPHA: return D3D11_BLEND_INV_DEST_ALPHA; - case SBF_ONE_MINUS_SOURCE_ALPHA: return D3D11_BLEND_INV_SRC_ALPHA; - } - return D3D11_BLEND_ZERO; - } - //--------------------------------------------------------------------- - D3D11_BLEND_OP D3D11Mappings::get(SceneBlendOperation sbo) - { - switch( sbo ) - { - case SBO_ADD: - return D3D11_BLEND_OP_ADD; - case SBO_SUBTRACT: - return D3D11_BLEND_OP_SUBTRACT; - case SBO_REVERSE_SUBTRACT: - return D3D11_BLEND_OP_REV_SUBTRACT; - case SBO_MIN: - return D3D11_BLEND_OP_MIN; - case SBO_MAX: - return D3D11_BLEND_OP_MAX; - } - return D3D11_BLEND_OP_ADD; - } - //--------------------------------------------------------------------- - D3D11_COMPARISON_FUNC D3D11Mappings::get(CompareFunction cf) - { - switch( cf ) - { - case CMPF_ALWAYS_FAIL: - return D3D11_COMPARISON_NEVER; - case CMPF_ALWAYS_PASS: - return D3D11_COMPARISON_ALWAYS; - case CMPF_LESS: - return D3D11_COMPARISON_LESS; - case CMPF_LESS_EQUAL: - return D3D11_COMPARISON_LESS_EQUAL; - case CMPF_EQUAL: - return D3D11_COMPARISON_EQUAL; - case CMPF_NOT_EQUAL: - return D3D11_COMPARISON_NOT_EQUAL; - case CMPF_GREATER_EQUAL: - return D3D11_COMPARISON_GREATER_EQUAL; - case CMPF_GREATER: - return D3D11_COMPARISON_GREATER; - }; - return D3D11_COMPARISON_ALWAYS; - } - //--------------------------------------------------------------------- - D3D11_CULL_MODE D3D11Mappings::get(CullingMode cm, bool flip) - { - switch( cm ) - { - case CULL_NONE: - return D3D11_CULL_NONE; - case CULL_CLOCKWISE: - if( flip ) - return D3D11_CULL_FRONT; - else - return D3D11_CULL_BACK; - case CULL_ANTICLOCKWISE: - if( flip ) - return D3D11_CULL_BACK; - else - return D3D11_CULL_FRONT; - } - return D3D11_CULL_NONE; - } - //--------------------------------------------------------------------- - /*D3DFOGMODE D3D11Mappings::get(FogMode fm) - { - switch( fm ) - { - case FOG_EXP: - return D3DFOG_EXP; - case FOG_EXP2: - return D3DFOG_EXP2; - case FOG_LINEAR: - return D3DFOG_LINEAR; - } - return D3DFOG_FORCE_DWORD; - }*/ - //--------------------------------------------------------------------- - D3D11_FILL_MODE D3D11Mappings::get(PolygonMode level) - { - switch(level) - { - case PM_POINTS: - return D3D11_FILL_SOLID; // this will done in a geometry shader like in the FixedFuncEMU sample and the shader needs solid - case PM_WIREFRAME: - return D3D11_FILL_WIREFRAME; - case PM_SOLID: - return D3D11_FILL_SOLID; - } - return D3D11_FILL_SOLID; - } - //--------------------------------------------------------------------- - D3D11_STENCIL_OP D3D11Mappings::get(StencilOperation op, bool invert) - { - // D3D11_STENCIL_OP - switch(op) - { - case SOP_KEEP: - return D3D11_STENCIL_OP_KEEP; - case SOP_ZERO: - return D3D11_STENCIL_OP_ZERO; - case SOP_REPLACE: - return D3D11_STENCIL_OP_REPLACE; - case SOP_INCREMENT: - return invert? D3D11_STENCIL_OP_DECR_SAT : D3D11_STENCIL_OP_INCR_SAT; - case SOP_DECREMENT: - return invert? D3D11_STENCIL_OP_INCR_SAT : D3D11_STENCIL_OP_DECR_SAT; - case SOP_INCREMENT_WRAP: - return invert? D3D11_STENCIL_OP_DECR : D3D11_STENCIL_OP_INCR; - case SOP_DECREMENT_WRAP: - return invert? D3D11_STENCIL_OP_INCR : D3D11_STENCIL_OP_DECR; - case SOP_INVERT: - return D3D11_STENCIL_OP_INVERT; - } - return D3D11_STENCIL_OP_KEEP; - } - //--------------------------------------------------------------------- - DWORD D3D11Mappings::get(FilterType ft) - { - switch (ft) - { - case FT_MIN: - return D3D11_MIN_FILTER_SHIFT; - break; - case FT_MAG: - return D3D11_MAG_FILTER_SHIFT; - break; - case FT_MIP: - return D3D11_MIP_FILTER_SHIFT; - break; - } + //return D3D11_TEXTURE_ADDRESS_WRAP; + switch( tam ) + { + case TextureUnitState::TAM_WRAP: + return D3D11_TEXTURE_ADDRESS_WRAP; + case TextureUnitState::TAM_MIRROR: + return D3D11_TEXTURE_ADDRESS_MIRROR; + case TextureUnitState::TAM_CLAMP: + return D3D11_TEXTURE_ADDRESS_CLAMP; + case TextureUnitState::TAM_BORDER: + return D3D11_TEXTURE_ADDRESS_BORDER; + } + return D3D11_TEXTURE_ADDRESS_MIRROR_ONCE; + } + //--------------------------------------------------------------------- + D3D11_BLEND D3D11Mappings::get(LayerBlendType lbt) + { + switch( lbt ) + { + case LBT_COLOUR: + return D3D11_BLEND_SRC_COLOR; + case LBT_ALPHA: + return D3D11_BLEND_SRC_ALPHA; + } + return D3D11_BLEND_ZERO; + } + //--------------------------------------------------------------------- + /*DWORD D3D11Mappings::get(LayerBlendSource lbs) + { + switch( lbs ) + { + case LBS_CURRENT: + return D3DTA_CURRENT; + case LBS_TEXTURE: + return D3DTA_TEXTURE; + case LBS_DIFFUSE: + return D3DTA_DIFFUSE; + case LBS_SPECULAR: + return D3DTA_SPECULAR; + case LBS_MANUAL: + return D3DTA_TFACTOR; + } + return 0; + }*/ + //--------------------------------------------------------------------- + /*DWORD D3D11Mappings::get(LayerBlendOperationEx lbo, const D3DCAPS9& devCaps) + { + switch( lbo ) + { + case LBX_SOURCE1: + return D3DTOP_SELECTARG1; + case LBX_SOURCE2: + return D3DTOP_SELECTARG2; + case LBX_MODULATE: + return D3DTOP_MODULATE; + case LBX_MODULATE_X2: + return D3DTOP_MODULATE2X; + case LBX_MODULATE_X4: + return D3DTOP_MODULATE4X; + case LBX_ADD: + return D3DTOP_ADD; + case LBX_ADD_SIGNED: + return D3DTOP_ADDSIGNED; + case LBX_ADD_SMOOTH: + return D3DTOP_ADDSMOOTH; + case LBX_SUBTRACT: + return D3DTOP_SUBTRACT; + case LBX_BLEND_DIFFUSE_ALPHA: + return D3DTOP_BLENDDIFFUSEALPHA; + case LBX_BLEND_TEXTURE_ALPHA: + return D3DTOP_BLENDTEXTUREALPHA; + case LBX_BLEND_CURRENT_ALPHA: + return D3DTOP_BLENDCURRENTALPHA; + case LBX_BLEND_MANUAL: + return D3DTOP_BLENDFACTORALPHA; + case LBX_DOTPRODUCT: + if (devCaps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) + return D3DTOP_DOTPRODUCT3; + else + return D3DTOP_MODULATE; + case LBX_BLEND_DIFFUSE_COLOUR: + if (devCaps.TextureOpCaps & D3DTEXOPCAPS_LERP) + return D3DTOP_LERP; + else + return D3DTOP_MODULATE; + } + return 0; + }*/ + //--------------------------------------------------------------------- + D3D11_BLEND D3D11Mappings::get(SceneBlendFactor sbf, bool forAlpha) + { + switch( sbf ) + { + case SBF_ONE: return D3D11_BLEND_ONE; + case SBF_ZERO: return D3D11_BLEND_ZERO; + case SBF_DEST_COLOUR: return forAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR; + case SBF_SOURCE_COLOUR: return forAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR; + case SBF_ONE_MINUS_DEST_COLOUR: return forAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR; + case SBF_ONE_MINUS_SOURCE_COLOUR: return forAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR; + case SBF_DEST_ALPHA: return D3D11_BLEND_DEST_ALPHA; + case SBF_SOURCE_ALPHA: return D3D11_BLEND_SRC_ALPHA; + case SBF_ONE_MINUS_DEST_ALPHA: return D3D11_BLEND_INV_DEST_ALPHA; + case SBF_ONE_MINUS_SOURCE_ALPHA: return D3D11_BLEND_INV_SRC_ALPHA; + } + return D3D11_BLEND_ZERO; + } + //--------------------------------------------------------------------- + D3D11_BLEND_OP D3D11Mappings::get(SceneBlendOperation sbo) + { + switch( sbo ) + { + case SBO_ADD: + return D3D11_BLEND_OP_ADD; + case SBO_SUBTRACT: + return D3D11_BLEND_OP_SUBTRACT; + case SBO_REVERSE_SUBTRACT: + return D3D11_BLEND_OP_REV_SUBTRACT; + case SBO_MIN: + return D3D11_BLEND_OP_MIN; + case SBO_MAX: + return D3D11_BLEND_OP_MAX; + } + return D3D11_BLEND_OP_ADD; + } + //--------------------------------------------------------------------- + D3D11_COMPARISON_FUNC D3D11Mappings::get(CompareFunction cf) + { + switch( cf ) + { + case CMPF_ALWAYS_FAIL: + return D3D11_COMPARISON_NEVER; + case CMPF_ALWAYS_PASS: + return D3D11_COMPARISON_ALWAYS; + case CMPF_LESS: + return D3D11_COMPARISON_LESS; + case CMPF_LESS_EQUAL: + return D3D11_COMPARISON_LESS_EQUAL; + case CMPF_EQUAL: + return D3D11_COMPARISON_EQUAL; + case CMPF_NOT_EQUAL: + return D3D11_COMPARISON_NOT_EQUAL; + case CMPF_GREATER_EQUAL: + return D3D11_COMPARISON_GREATER_EQUAL; + case CMPF_GREATER: + return D3D11_COMPARISON_GREATER; + }; + return D3D11_COMPARISON_ALWAYS; + } + //--------------------------------------------------------------------- + D3D11_CULL_MODE D3D11Mappings::get(CullingMode cm, bool flip) + { + switch( cm ) + { + case CULL_NONE: + return D3D11_CULL_NONE; + case CULL_CLOCKWISE: + if( flip ) + return D3D11_CULL_FRONT; + else + return D3D11_CULL_BACK; + case CULL_ANTICLOCKWISE: + if( flip ) + return D3D11_CULL_BACK; + else + return D3D11_CULL_FRONT; + } + return D3D11_CULL_NONE; + } + //--------------------------------------------------------------------- + /*D3DFOGMODE D3D11Mappings::get(FogMode fm) + { + switch( fm ) + { + case FOG_EXP: + return D3DFOG_EXP; + case FOG_EXP2: + return D3DFOG_EXP2; + case FOG_LINEAR: + return D3DFOG_LINEAR; + } + return D3DFOG_FORCE_DWORD; + }*/ + //--------------------------------------------------------------------- + D3D11_FILL_MODE D3D11Mappings::get(PolygonMode level) + { + switch(level) + { + case PM_POINTS: + return D3D11_FILL_SOLID; // this will done in a geometry shader like in the FixedFuncEMU sample and the shader needs solid + case PM_WIREFRAME: + return D3D11_FILL_WIREFRAME; + case PM_SOLID: + return D3D11_FILL_SOLID; + } + return D3D11_FILL_SOLID; + } + //--------------------------------------------------------------------- + D3D11_STENCIL_OP D3D11Mappings::get(StencilOperation op, bool invert) + { + // D3D11_STENCIL_OP + switch(op) + { + case SOP_KEEP: + return D3D11_STENCIL_OP_KEEP; + case SOP_ZERO: + return D3D11_STENCIL_OP_ZERO; + case SOP_REPLACE: + return D3D11_STENCIL_OP_REPLACE; + case SOP_INCREMENT: + return invert? D3D11_STENCIL_OP_DECR_SAT : D3D11_STENCIL_OP_INCR_SAT; + case SOP_DECREMENT: + return invert? D3D11_STENCIL_OP_INCR_SAT : D3D11_STENCIL_OP_DECR_SAT; + case SOP_INCREMENT_WRAP: + return invert? D3D11_STENCIL_OP_DECR : D3D11_STENCIL_OP_INCR; + case SOP_DECREMENT_WRAP: + return invert? D3D11_STENCIL_OP_INCR : D3D11_STENCIL_OP_DECR; + case SOP_INVERT: + return D3D11_STENCIL_OP_INVERT; + } + return D3D11_STENCIL_OP_KEEP; + } + //--------------------------------------------------------------------- + DWORD D3D11Mappings::get(FilterType ft) + { + switch (ft) + { + case FT_MIN: + return D3D11_MIN_FILTER_SHIFT; + break; + case FT_MAG: + return D3D11_MAG_FILTER_SHIFT; + break; + case FT_MIP: + return D3D11_MIP_FILTER_SHIFT; + break; + } - // to keep compiler happy - return D3D11_MIP_FILTER_SHIFT; - } - //--------------------------------------------------------------------- - D3D11_FILTER D3D11Mappings::get(const FilterOptions min, const FilterOptions mag, const FilterOptions mip, const bool comparison) - { + // to keep compiler happy + return D3D11_MIP_FILTER_SHIFT; + } + //--------------------------------------------------------------------- + D3D11_FILTER D3D11Mappings::get(const FilterOptions min, const FilterOptions mag, const FilterOptions mip, const bool comparison) + { - D3D11_FILTER res; + D3D11_FILTER res; #define MARGE_FOR_SWITCH(_comparison_, _min_ , _mag_, _mip_ ) ((_comparison_ << 16) | (_min_ << 8) | (_mag_ << 4) | (_mip_)) - switch((MARGE_FOR_SWITCH(comparison, min, mag, mip))) - { - case MARGE_FOR_SWITCH(true, FO_POINT, FO_POINT, FO_POINT): - res = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT; - break; - case MARGE_FOR_SWITCH(true, FO_POINT, FO_POINT, FO_LINEAR): - res = D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR; - break; - case MARGE_FOR_SWITCH(true, FO_POINT, FO_LINEAR, FO_POINT): - res = D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT; - break; - case MARGE_FOR_SWITCH(true, FO_POINT, FO_LINEAR, FO_LINEAR): - res = D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR; - break; - case MARGE_FOR_SWITCH(true, FO_LINEAR, FO_POINT, FO_POINT): - res = D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT; - break; - case MARGE_FOR_SWITCH(true, FO_LINEAR, FO_POINT, FO_LINEAR): - res = D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR; - break; - case MARGE_FOR_SWITCH(true, FO_LINEAR, FO_LINEAR, FO_POINT): - res = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; - break; - case MARGE_FOR_SWITCH(true, FO_LINEAR, FO_LINEAR, FO_LINEAR): - res = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; - break; - case MARGE_FOR_SWITCH(true, FO_ANISOTROPIC, FO_ANISOTROPIC, FO_ANISOTROPIC): - res = D3D11_FILTER_COMPARISON_ANISOTROPIC; - break; - case MARGE_FOR_SWITCH(true, FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR): - res = D3D11_FILTER_COMPARISON_ANISOTROPIC; - break; - case MARGE_FOR_SWITCH(false, FO_POINT, FO_POINT, FO_POINT): - res = D3D11_FILTER_MIN_MAG_MIP_POINT; - break; - case MARGE_FOR_SWITCH(false, FO_POINT, FO_POINT, FO_LINEAR): - res = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; - break; - case MARGE_FOR_SWITCH(false, FO_POINT, FO_LINEAR, FO_POINT): - res = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; - break; - case MARGE_FOR_SWITCH(false, FO_POINT, FO_LINEAR, FO_LINEAR): - res = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR; - break; - case MARGE_FOR_SWITCH(false, FO_LINEAR, FO_POINT, FO_POINT): - res = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; - break; - case MARGE_FOR_SWITCH(false, FO_LINEAR, FO_POINT, FO_LINEAR): - res = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; - break; - case MARGE_FOR_SWITCH(false, FO_LINEAR, FO_LINEAR, FO_POINT): - res = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; - break; - case MARGE_FOR_SWITCH(false, FO_LINEAR, FO_LINEAR, FO_LINEAR): - res = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - break; - case MARGE_FOR_SWITCH(false, FO_ANISOTROPIC, FO_ANISOTROPIC, FO_ANISOTROPIC): - res = D3D11_FILTER_ANISOTROPIC; - break; - case MARGE_FOR_SWITCH(false, FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR): - res = D3D11_FILTER_ANISOTROPIC; - break; - default: - res = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - } - - return res; - } - //--------------------------------------------------------------------- - DWORD D3D11Mappings::get(HardwareBuffer::Usage usage) - { - DWORD ret = 0; - if (usage & HardwareBuffer::HBU_DYNAMIC) - { - ret |= D3D11_USAGE_DYNAMIC; - } - if (usage & HardwareBuffer::HBU_WRITE_ONLY) - { - ret |= D3D11_USAGE_DYNAMIC; - } - return ret; - } - //--------------------------------------------------------------------- - D3D11_MAP D3D11Mappings::get(HardwareBuffer::LockOptions options, HardwareBuffer::Usage usage) - { - D3D11_MAP ret = D3D11_MAP_READ_WRITE; - if (options == HardwareBuffer::HBL_DISCARD) - { - // D3D doesn't like discard or no_overwrite on non-dynamic buffers - if (usage & HardwareBuffer::HBU_DYNAMIC) - ret = D3D11_MAP_WRITE_DISCARD; - } - if (options == HardwareBuffer::HBL_READ_ONLY) - { - // D3D debug runtime doesn't like you locking managed buffers readonly - // when they were created with write-only (even though you CAN read - // from the software backed version) - if (!(usage & HardwareBuffer::HBU_WRITE_ONLY)) - ret = D3D11_MAP_READ; + switch((MARGE_FOR_SWITCH(comparison, min, mag, mip))) + { + case MARGE_FOR_SWITCH(true, FO_POINT, FO_POINT, FO_POINT): + res = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT; + break; + case MARGE_FOR_SWITCH(true, FO_POINT, FO_POINT, FO_LINEAR): + res = D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR; + break; + case MARGE_FOR_SWITCH(true, FO_POINT, FO_LINEAR, FO_POINT): + res = D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT; + break; + case MARGE_FOR_SWITCH(true, FO_POINT, FO_LINEAR, FO_LINEAR): + res = D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR; + break; + case MARGE_FOR_SWITCH(true, FO_LINEAR, FO_POINT, FO_POINT): + res = D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT; + break; + case MARGE_FOR_SWITCH(true, FO_LINEAR, FO_POINT, FO_LINEAR): + res = D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + break; + case MARGE_FOR_SWITCH(true, FO_LINEAR, FO_LINEAR, FO_POINT): + res = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; + break; + case MARGE_FOR_SWITCH(true, FO_LINEAR, FO_LINEAR, FO_LINEAR): + res = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR; + break; + case MARGE_FOR_SWITCH(true, FO_ANISOTROPIC, FO_ANISOTROPIC, FO_ANISOTROPIC): + res = D3D11_FILTER_COMPARISON_ANISOTROPIC; + break; + case MARGE_FOR_SWITCH(true, FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR): + res = D3D11_FILTER_COMPARISON_ANISOTROPIC; + break; + case MARGE_FOR_SWITCH(false, FO_POINT, FO_POINT, FO_POINT): + res = D3D11_FILTER_MIN_MAG_MIP_POINT; + break; + case MARGE_FOR_SWITCH(false, FO_POINT, FO_POINT, FO_LINEAR): + res = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; + break; + case MARGE_FOR_SWITCH(false, FO_POINT, FO_LINEAR, FO_POINT): + res = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; + break; + case MARGE_FOR_SWITCH(false, FO_POINT, FO_LINEAR, FO_LINEAR): + res = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR; + break; + case MARGE_FOR_SWITCH(false, FO_LINEAR, FO_POINT, FO_POINT): + res = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; + break; + case MARGE_FOR_SWITCH(false, FO_LINEAR, FO_POINT, FO_LINEAR): + res = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + break; + case MARGE_FOR_SWITCH(false, FO_LINEAR, FO_LINEAR, FO_POINT): + res = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; + break; + case MARGE_FOR_SWITCH(false, FO_LINEAR, FO_LINEAR, FO_LINEAR): + res = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + break; + case MARGE_FOR_SWITCH(false, FO_ANISOTROPIC, FO_ANISOTROPIC, FO_ANISOTROPIC): + res = D3D11_FILTER_ANISOTROPIC; + break; + case MARGE_FOR_SWITCH(false, FO_ANISOTROPIC, FO_ANISOTROPIC, FO_LINEAR): + res = D3D11_FILTER_ANISOTROPIC; + break; + default: + res = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + } + + return res; + } + //--------------------------------------------------------------------- + DWORD D3D11Mappings::get(HardwareBuffer::Usage usage) + { + DWORD ret = 0; + if (usage & HardwareBuffer::HBU_DYNAMIC) + { + ret |= D3D11_USAGE_DYNAMIC; + } + if (usage & HardwareBuffer::HBU_WRITE_ONLY) + { + ret |= D3D11_USAGE_DYNAMIC; + } + return ret; + } + //--------------------------------------------------------------------- + D3D11_MAP D3D11Mappings::get(HardwareBuffer::LockOptions options, HardwareBuffer::Usage usage) + { + D3D11_MAP ret = D3D11_MAP_READ_WRITE; + if (options == HardwareBuffer::HBL_DISCARD) + { + // D3D doesn't like discard or no_overwrite on non-dynamic buffers + if (usage & HardwareBuffer::HBU_DYNAMIC) + ret = D3D11_MAP_WRITE_DISCARD; + } + if (options == HardwareBuffer::HBL_READ_ONLY) + { + // D3D debug runtime doesn't like you locking managed buffers readonly + // when they were created with write-only (even though you CAN read + // from the software backed version) + if (!(usage & HardwareBuffer::HBU_WRITE_ONLY)) + ret = D3D11_MAP_READ; - } - if (options == HardwareBuffer::HBL_NO_OVERWRITE) - { - // D3D doesn't like discard or no_overwrite on non-dynamic buffers - if (usage & HardwareBuffer::HBU_DYNAMIC) - ret = D3D11_MAP_WRITE_NO_OVERWRITE; - } + } + if (options == HardwareBuffer::HBL_NO_OVERWRITE) + { + // D3D doesn't like discard or no_overwrite on non-dynamic buffers + if (usage & HardwareBuffer::HBU_DYNAMIC) + ret = D3D11_MAP_WRITE_NO_OVERWRITE; + } - return ret; - } - //--------------------------------------------------------------------- - UINT D3D11Mappings::getByteWidth(HardwareIndexBuffer::IndexType itype) - { - if (itype == HardwareIndexBuffer::IT_32BIT) - { - return sizeof(long); - } - else - { - return sizeof(short); - } - } - //--------------------------------------------------------------------- - DXGI_FORMAT D3D11Mappings::getFormat(HardwareIndexBuffer::IndexType itype) - { - if (itype == HardwareIndexBuffer::IT_32BIT) - { - return DXGI_FORMAT_R32_UINT; - } - else - { - return DXGI_FORMAT_R16_UINT; - } - } - //--------------------------------------------------------------------- - DXGI_FORMAT D3D11Mappings::get(VertexElementType vType) - { - switch (vType) - { - case VET_COLOUR: - case VET_COLOUR_ABGR: - case VET_COLOUR_ARGB: - return DXGI_FORMAT_R8G8B8A8_UNORM; - break; - case VET_FLOAT1: - return DXGI_FORMAT_R32_FLOAT; - break; - case VET_FLOAT2: - return DXGI_FORMAT_R32G32_FLOAT; - break; - case VET_FLOAT3: - return DXGI_FORMAT_R32G32B32_FLOAT; - break; - case VET_FLOAT4: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - break; - case VET_SHORT2: - return DXGI_FORMAT_R16G16_SINT; - break; - case VET_SHORT4: - return DXGI_FORMAT_R16G16B16A16_SINT; - break; - case VET_UBYTE4: - return DXGI_FORMAT_R8G8B8A8_UINT; - break; - } - // to keep compiler happy - return DXGI_FORMAT_R32G32B32_FLOAT; - } - //--------------------------------------------------------------------- - VertexElementSemantic D3D11Mappings::get(LPCSTR sem) - { - // todo - add to ogre - POSITIONT and PSIZE ("Transformed vertex position" and "Point size") + return ret; + } + //--------------------------------------------------------------------- + UINT D3D11Mappings::getByteWidth(HardwareIndexBuffer::IndexType itype) + { + if (itype == HardwareIndexBuffer::IT_32BIT) + { + return sizeof(long); + } + else + { + return sizeof(short); + } + } + //--------------------------------------------------------------------- + DXGI_FORMAT D3D11Mappings::getFormat(HardwareIndexBuffer::IndexType itype) + { + if (itype == HardwareIndexBuffer::IT_32BIT) + { + return DXGI_FORMAT_R32_UINT; + } + else + { + return DXGI_FORMAT_R16_UINT; + } + } + //--------------------------------------------------------------------- + DXGI_FORMAT D3D11Mappings::get(VertexElementType vType) + { + switch (vType) + { + case VET_COLOUR: + case VET_COLOUR_ABGR: + case VET_COLOUR_ARGB: + return DXGI_FORMAT_R8G8B8A8_UNORM; + break; + case VET_FLOAT1: + return DXGI_FORMAT_R32_FLOAT; + break; + case VET_FLOAT2: + return DXGI_FORMAT_R32G32_FLOAT; + break; + case VET_FLOAT3: + return DXGI_FORMAT_R32G32B32_FLOAT; + break; + case VET_FLOAT4: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + break; + case VET_SHORT2: + return DXGI_FORMAT_R16G16_SINT; + break; + case VET_SHORT4: + return DXGI_FORMAT_R16G16B16A16_SINT; + break; + case VET_UBYTE4: + return DXGI_FORMAT_R8G8B8A8_UINT; + break; + } + // to keep compiler happy + return DXGI_FORMAT_R32G32B32_FLOAT; + } + //--------------------------------------------------------------------- + VertexElementSemantic D3D11Mappings::get(LPCSTR sem) + { + // todo - add to ogre - POSITIONT and PSIZE ("Transformed vertex position" and "Point size") - if( strcmp(sem, "BLENDINDICES") == 0 ) - return VES_BLEND_INDICES; - if( strcmp(sem, "BLENDWEIGHT") == 0 ) - return VES_BLEND_WEIGHTS; - if( strcmp(sem, "COLOR") == 0 ) - return VES_DIFFUSE; -// if( strcmp(sem, "COLOR") == 0 ) -// return VES_SPECULAR; - if( strcmp(sem, "NORMAL") == 0 ) - return VES_NORMAL; - if( strcmp(sem, "POSITION") == 0 ) - return VES_POSITION; - if( strcmp(sem, "TEXCOORD") == 0 ) - return VES_TEXTURE_COORDINATES; - if( strcmp(sem, "BINORMAL") == 0 ) - return VES_BINORMAL; - if( strcmp(sem, "TANGENT") == 0 ) - return VES_TANGENT; + if( strcmp(sem, "BLENDINDICES") == 0 ) + return VES_BLEND_INDICES; + if( strcmp(sem, "BLENDWEIGHT") == 0 ) + return VES_BLEND_WEIGHTS; + if( strcmp(sem, "COLOR") == 0 ) + return VES_DIFFUSE; +// if( strcmp(sem, "COLOR") == 0 ) +// return VES_SPECULAR; + if( strcmp(sem, "NORMAL") == 0 ) + return VES_NORMAL; + if( strcmp(sem, "POSITION") == 0 ) + return VES_POSITION; + if( strcmp(sem, "TEXCOORD") == 0 ) + return VES_TEXTURE_COORDINATES; + if( strcmp(sem, "BINORMAL") == 0 ) + return VES_BINORMAL; + if( strcmp(sem, "TANGENT") == 0 ) + return VES_TANGENT; - // to keep compiler happy - return VES_POSITION; - } - //--------------------------------------------------------------------- - LPCSTR D3D11Mappings::get(VertexElementSemantic sem) - { - // todo - add to ogre - POSITIONT and PSIZE ("Transformed vertex position" and "Point size") - switch (sem) - { - case VES_BLEND_INDICES: - return "BLENDINDICES"; - break; - case VES_BLEND_WEIGHTS: - return "BLENDWEIGHT"; - break; - case VES_DIFFUSE: - return "COLOR"; // NB index will differentiate - break; - case VES_SPECULAR: - return "COLOR"; // NB index will differentiate - break; - case VES_NORMAL: - return "NORMAL"; - break; - case VES_POSITION: - return "POSITION"; - break; - case VES_TEXTURE_COORDINATES: - return "TEXCOORD"; - break; - case VES_BINORMAL: - return "BINORMAL"; - break; - case VES_TANGENT: - return "TANGENT"; - break; - } - // to keep compiler happy - return ""; - } - //--------------------------------------------------------------------- - void D3D11Mappings::get(const ColourValue& inColour, float * outColour ) - { - outColour[0] = inColour.r; - outColour[1] = inColour.g; - outColour[2] = inColour.b; - outColour[3] = inColour.a; - } - //--------------------------------------------------------------------- - PixelFormat D3D11Mappings::_getPF(DXGI_FORMAT d3dPF) - { - switch(d3dPF) - { - case DXGI_FORMAT_UNKNOWN: return PF_UNKNOWN; - case DXGI_FORMAT_R32G32B32A32_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_R32G32B32A32_FLOAT: return PF_FLOAT32_RGBA; - case DXGI_FORMAT_R32G32B32A32_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R32G32B32A32_SINT: return PF_UNKNOWN; - case DXGI_FORMAT_R32G32B32_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_R32G32B32_FLOAT: return PF_FLOAT32_RGB; - case DXGI_FORMAT_R32G32B32_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R32G32B32_SINT: return PF_UNKNOWN; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_R16G16B16A16_FLOAT: return PF_FLOAT16_RGBA; - case DXGI_FORMAT_R16G16B16A16_UNORM: return PF_SHORT_RGBA; - case DXGI_FORMAT_R16G16B16A16_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R16G16B16A16_SNORM: return PF_UNKNOWN; - case DXGI_FORMAT_R16G16B16A16_SINT: return PF_UNKNOWN; - case DXGI_FORMAT_R32G32_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_R32G32_FLOAT: return PF_UNKNOWN; - case DXGI_FORMAT_R32G32_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R32G32_SINT: return PF_UNKNOWN; - case DXGI_FORMAT_R32G8X24_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_R10G10B10A2_UNORM: return PF_A2B10G10R10; - case DXGI_FORMAT_R10G10B10A2_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R11G11B10_FLOAT: return PF_UNKNOWN; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_R8G8B8A8_UNORM: return PF_A8B8G8R8; - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return PF_A8B8G8R8; - case DXGI_FORMAT_R8G8B8A8_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R8G8B8A8_SNORM: return PF_UNKNOWN; - case DXGI_FORMAT_R8G8B8A8_SINT: return PF_UNKNOWN; - case DXGI_FORMAT_R16G16_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_R16G16_FLOAT: return PF_UNKNOWN; - case DXGI_FORMAT_R16G16_UNORM: return PF_SHORT_GR; - case DXGI_FORMAT_R16G16_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R16G16_SNORM: return PF_UNKNOWN; - case DXGI_FORMAT_R16G16_SINT: return PF_R16G16_SINT; - case DXGI_FORMAT_R32_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_D32_FLOAT: return PF_DEPTH; - case DXGI_FORMAT_R32_FLOAT: return PF_FLOAT32_R; - case DXGI_FORMAT_R32_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R32_SINT: return PF_UNKNOWN; - case DXGI_FORMAT_R24G8_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_D24_UNORM_S8_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R8G8_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_R8G8_UNORM: return PF_UNKNOWN; - case DXGI_FORMAT_R8G8_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R8G8_SNORM: return PF_UNKNOWN; - case DXGI_FORMAT_R8G8_SINT: return PF_UNKNOWN; - case DXGI_FORMAT_R16_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_R16_FLOAT: return PF_FLOAT16_R; - case DXGI_FORMAT_D16_UNORM: return PF_UNKNOWN; - case DXGI_FORMAT_R16_UNORM: return PF_L16; - case DXGI_FORMAT_R16_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R16_SNORM: return PF_UNKNOWN; - case DXGI_FORMAT_R16_SINT: return PF_UNKNOWN; - case DXGI_FORMAT_R8_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_R8_UNORM: return PF_L8; - case DXGI_FORMAT_R8_UINT: return PF_UNKNOWN; - case DXGI_FORMAT_R8_SNORM: return PF_UNKNOWN; - case DXGI_FORMAT_R8_SINT: return PF_UNKNOWN; - case DXGI_FORMAT_A8_UNORM: return PF_A8; - case DXGI_FORMAT_R1_UNORM: return PF_UNKNOWN; - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: return PF_UNKNOWN; - case DXGI_FORMAT_R8G8_B8G8_UNORM: return PF_UNKNOWN; - case DXGI_FORMAT_G8R8_G8B8_UNORM: return PF_UNKNOWN; - case DXGI_FORMAT_BC1_TYPELESS: return PF_DXT1; - case DXGI_FORMAT_BC1_UNORM: return PF_DXT1; - case DXGI_FORMAT_BC1_UNORM_SRGB: return PF_DXT1; - case DXGI_FORMAT_BC2_TYPELESS: return PF_DXT2; - case DXGI_FORMAT_BC2_UNORM: return PF_DXT2; - case DXGI_FORMAT_BC2_UNORM_SRGB: return PF_DXT2; - case DXGI_FORMAT_BC3_TYPELESS: return PF_DXT3; - case DXGI_FORMAT_BC3_UNORM: return PF_DXT3; - case DXGI_FORMAT_BC3_UNORM_SRGB: return PF_DXT3; - case DXGI_FORMAT_BC4_TYPELESS: return PF_DXT4; - case DXGI_FORMAT_BC4_UNORM: return PF_DXT4; - case DXGI_FORMAT_BC4_SNORM: return PF_DXT4; - case DXGI_FORMAT_BC5_TYPELESS: return PF_DXT5; - case DXGI_FORMAT_BC5_UNORM: return PF_DXT5; - case DXGI_FORMAT_BC5_SNORM: return PF_DXT5; - case DXGI_FORMAT_B5G6R5_UNORM: return PF_R5G6B5; - case DXGI_FORMAT_B5G5R5A1_UNORM: return PF_A1R5G5B5; - case DXGI_FORMAT_B8G8R8A8_UNORM: return PF_A8R8G8B8; - case DXGI_FORMAT_B8G8R8X8_UNORM: return PF_X8R8G8B8; - case DXGI_FORMAT_BC6H_TYPELESS: return PF_BC6H_SF16; - case DXGI_FORMAT_BC6H_UF16: return PF_BC6H_UF16; - case DXGI_FORMAT_BC6H_SF16: return PF_BC6H_SF16; - case DXGI_FORMAT_BC7_TYPELESS: return PF_BC7_UNORM; - case DXGI_FORMAT_BC7_UNORM: return PF_BC7_UNORM; - case DXGI_FORMAT_BC7_UNORM_SRGB: return PF_BC7_UNORM_SRGB; + // to keep compiler happy + return VES_POSITION; + } + //--------------------------------------------------------------------- + LPCSTR D3D11Mappings::get(VertexElementSemantic sem) + { + // todo - add to ogre - POSITIONT and PSIZE ("Transformed vertex position" and "Point size") + switch (sem) + { + case VES_BLEND_INDICES: + return "BLENDINDICES"; + break; + case VES_BLEND_WEIGHTS: + return "BLENDWEIGHT"; + break; + case VES_DIFFUSE: + return "COLOR"; // NB index will differentiate + break; + case VES_SPECULAR: + return "COLOR"; // NB index will differentiate + break; + case VES_NORMAL: + return "NORMAL"; + break; + case VES_POSITION: + return "POSITION"; + break; + case VES_TEXTURE_COORDINATES: + return "TEXCOORD"; + break; + case VES_BINORMAL: + return "BINORMAL"; + break; + case VES_TANGENT: + return "TANGENT"; + break; + } + // to keep compiler happy + return ""; + } + //--------------------------------------------------------------------- + void D3D11Mappings::get(const ColourValue& inColour, float * outColour ) + { + outColour[0] = inColour.r; + outColour[1] = inColour.g; + outColour[2] = inColour.b; + outColour[3] = inColour.a; + } + //--------------------------------------------------------------------- + PixelFormat D3D11Mappings::_getPF(DXGI_FORMAT d3dPF) + { + switch(d3dPF) + { + case DXGI_FORMAT_UNKNOWN: return PF_UNKNOWN; + case DXGI_FORMAT_R32G32B32A32_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_R32G32B32A32_FLOAT: return PF_FLOAT32_RGBA; + case DXGI_FORMAT_R32G32B32A32_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R32G32B32A32_SINT: return PF_UNKNOWN; + case DXGI_FORMAT_R32G32B32_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_R32G32B32_FLOAT: return PF_FLOAT32_RGB; + case DXGI_FORMAT_R32G32B32_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R32G32B32_SINT: return PF_UNKNOWN; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_R16G16B16A16_FLOAT: return PF_FLOAT16_RGBA; + case DXGI_FORMAT_R16G16B16A16_UNORM: return PF_SHORT_RGBA; + case DXGI_FORMAT_R16G16B16A16_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R16G16B16A16_SNORM: return PF_UNKNOWN; + case DXGI_FORMAT_R16G16B16A16_SINT: return PF_UNKNOWN; + case DXGI_FORMAT_R32G32_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_R32G32_FLOAT: return PF_UNKNOWN; + case DXGI_FORMAT_R32G32_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R32G32_SINT: return PF_UNKNOWN; + case DXGI_FORMAT_R32G8X24_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_R10G10B10A2_UNORM: return PF_A2B10G10R10; + case DXGI_FORMAT_R10G10B10A2_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R11G11B10_FLOAT: return PF_UNKNOWN; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_R8G8B8A8_UNORM: return PF_A8B8G8R8; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return PF_A8B8G8R8; + case DXGI_FORMAT_R8G8B8A8_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R8G8B8A8_SNORM: return PF_UNKNOWN; + case DXGI_FORMAT_R8G8B8A8_SINT: return PF_UNKNOWN; + case DXGI_FORMAT_R16G16_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_R16G16_FLOAT: return PF_UNKNOWN; + case DXGI_FORMAT_R16G16_UNORM: return PF_SHORT_GR; + case DXGI_FORMAT_R16G16_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R16G16_SNORM: return PF_UNKNOWN; + case DXGI_FORMAT_R16G16_SINT: return PF_R16G16_SINT; + case DXGI_FORMAT_R32_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_D32_FLOAT: return PF_DEPTH; + case DXGI_FORMAT_R32_FLOAT: return PF_FLOAT32_R; + case DXGI_FORMAT_R32_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R32_SINT: return PF_UNKNOWN; + case DXGI_FORMAT_R24G8_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_D24_UNORM_S8_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R8G8_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_R8G8_UNORM: return PF_UNKNOWN; + case DXGI_FORMAT_R8G8_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R8G8_SNORM: return PF_UNKNOWN; + case DXGI_FORMAT_R8G8_SINT: return PF_UNKNOWN; + case DXGI_FORMAT_R16_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_R16_FLOAT: return PF_FLOAT16_R; + case DXGI_FORMAT_D16_UNORM: return PF_UNKNOWN; + case DXGI_FORMAT_R16_UNORM: return PF_L16; + case DXGI_FORMAT_R16_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R16_SNORM: return PF_UNKNOWN; + case DXGI_FORMAT_R16_SINT: return PF_UNKNOWN; + case DXGI_FORMAT_R8_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_R8_UNORM: return PF_L8; + case DXGI_FORMAT_R8_UINT: return PF_UNKNOWN; + case DXGI_FORMAT_R8_SNORM: return PF_UNKNOWN; + case DXGI_FORMAT_R8_SINT: return PF_UNKNOWN; + case DXGI_FORMAT_A8_UNORM: return PF_A8; + case DXGI_FORMAT_R1_UNORM: return PF_UNKNOWN; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: return PF_UNKNOWN; + case DXGI_FORMAT_R8G8_B8G8_UNORM: return PF_UNKNOWN; + case DXGI_FORMAT_G8R8_G8B8_UNORM: return PF_UNKNOWN; + case DXGI_FORMAT_BC1_TYPELESS: return PF_DXT1; + case DXGI_FORMAT_BC1_UNORM: return PF_DXT1; + case DXGI_FORMAT_BC1_UNORM_SRGB: return PF_DXT1; + case DXGI_FORMAT_BC2_TYPELESS: return PF_DXT2; + case DXGI_FORMAT_BC2_UNORM: return PF_DXT2; + case DXGI_FORMAT_BC2_UNORM_SRGB: return PF_DXT2; + case DXGI_FORMAT_BC3_TYPELESS: return PF_DXT3; + case DXGI_FORMAT_BC3_UNORM: return PF_DXT3; + case DXGI_FORMAT_BC3_UNORM_SRGB: return PF_DXT3; + case DXGI_FORMAT_BC4_TYPELESS: return PF_DXT4; + case DXGI_FORMAT_BC4_UNORM: return PF_DXT4; + case DXGI_FORMAT_BC4_SNORM: return PF_DXT4; + case DXGI_FORMAT_BC5_TYPELESS: return PF_DXT5; + case DXGI_FORMAT_BC5_UNORM: return PF_DXT5; + case DXGI_FORMAT_BC5_SNORM: return PF_DXT5; + case DXGI_FORMAT_B5G6R5_UNORM: return PF_R5G6B5; + case DXGI_FORMAT_B5G5R5A1_UNORM: return PF_A1R5G5B5; + case DXGI_FORMAT_B8G8R8A8_UNORM: return PF_A8R8G8B8; + case DXGI_FORMAT_B8G8R8X8_UNORM: return PF_X8R8G8B8; + case DXGI_FORMAT_BC6H_TYPELESS: return PF_BC6H_SF16; + case DXGI_FORMAT_BC6H_UF16: return PF_BC6H_UF16; + case DXGI_FORMAT_BC6H_SF16: return PF_BC6H_SF16; + case DXGI_FORMAT_BC7_TYPELESS: return PF_BC7_UNORM; + case DXGI_FORMAT_BC7_UNORM: return PF_BC7_UNORM; + case DXGI_FORMAT_BC7_UNORM_SRGB: return PF_BC7_UNORM_SRGB; #if defined(_WIN32_WINNT_WIN8) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8) && defined(DXGI_FORMAT_AYUV) - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:return PF_UNKNOWN; - case DXGI_FORMAT_B8G8R8A8_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return PF_A8R8G8B8; - case DXGI_FORMAT_B8G8R8X8_TYPELESS: return PF_UNKNOWN; - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return PF_X8R8G8B8; - case DXGI_FORMAT_AYUV: return PF_UNKNOWN; - case DXGI_FORMAT_Y410: return PF_UNKNOWN; - case DXGI_FORMAT_Y416: return PF_UNKNOWN; - case DXGI_FORMAT_NV12: return PF_UNKNOWN; - case DXGI_FORMAT_P010: return PF_UNKNOWN; - case DXGI_FORMAT_P016: return PF_UNKNOWN; - case DXGI_FORMAT_420_OPAQUE: return PF_UNKNOWN; - case DXGI_FORMAT_YUY2: return PF_UNKNOWN; - case DXGI_FORMAT_Y210: return PF_UNKNOWN; - case DXGI_FORMAT_Y216: return PF_UNKNOWN; - case DXGI_FORMAT_NV11: return PF_UNKNOWN; - case DXGI_FORMAT_AI44: return PF_UNKNOWN; - case DXGI_FORMAT_IA44: return PF_UNKNOWN; - case DXGI_FORMAT_P8: return PF_UNKNOWN; - case DXGI_FORMAT_A8P8: return PF_UNKNOWN; - case DXGI_FORMAT_B4G4R4A4_UNORM: return PF_A4R4G4B4; + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:return PF_UNKNOWN; + case DXGI_FORMAT_B8G8R8A8_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return PF_A8R8G8B8; + case DXGI_FORMAT_B8G8R8X8_TYPELESS: return PF_UNKNOWN; + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return PF_X8R8G8B8; + case DXGI_FORMAT_AYUV: return PF_UNKNOWN; + case DXGI_FORMAT_Y410: return PF_UNKNOWN; + case DXGI_FORMAT_Y416: return PF_UNKNOWN; + case DXGI_FORMAT_NV12: return PF_UNKNOWN; + case DXGI_FORMAT_P010: return PF_UNKNOWN; + case DXGI_FORMAT_P016: return PF_UNKNOWN; + case DXGI_FORMAT_420_OPAQUE: return PF_UNKNOWN; + case DXGI_FORMAT_YUY2: return PF_UNKNOWN; + case DXGI_FORMAT_Y210: return PF_UNKNOWN; + case DXGI_FORMAT_Y216: return PF_UNKNOWN; + case DXGI_FORMAT_NV11: return PF_UNKNOWN; + case DXGI_FORMAT_AI44: return PF_UNKNOWN; + case DXGI_FORMAT_IA44: return PF_UNKNOWN; + case DXGI_FORMAT_P8: return PF_UNKNOWN; + case DXGI_FORMAT_A8P8: return PF_UNKNOWN; + case DXGI_FORMAT_B4G4R4A4_UNORM: return PF_A4R4G4B4; #endif - default: return PF_UNKNOWN; - } - } - //--------------------------------------------------------------------- - DXGI_FORMAT D3D11Mappings::_getPF(PixelFormat ogrePF) - { - switch(ogrePF) - { - case PF_L8: return DXGI_FORMAT_R8_UNORM; - case PF_L16: return DXGI_FORMAT_R16_UNORM; - case PF_A8: return DXGI_FORMAT_A8_UNORM; - case PF_A4L4: return DXGI_FORMAT_UNKNOWN; - case PF_BYTE_LA: return DXGI_FORMAT_UNKNOWN; - case PF_R3G3B2: return DXGI_FORMAT_UNKNOWN; - case PF_A1R5G5B5: return DXGI_FORMAT_UNKNOWN; - case PF_R5G6B5: return DXGI_FORMAT_UNKNOWN; - case PF_A4R4G4B4: return DXGI_FORMAT_UNKNOWN; - case PF_R8G8B8: return DXGI_FORMAT_UNKNOWN; - case PF_A8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM; - case PF_A8B8G8R8: return DXGI_FORMAT_R8G8B8A8_UNORM; - case PF_X8R8G8B8: return DXGI_FORMAT_UNKNOWN; - case PF_X8B8G8R8: return DXGI_FORMAT_UNKNOWN; - case PF_A2B10G10R10: return DXGI_FORMAT_R10G10B10A2_TYPELESS; - case PF_A2R10G10B10: return DXGI_FORMAT_UNKNOWN; - case PF_FLOAT16_R: return DXGI_FORMAT_R16_FLOAT; - case PF_FLOAT16_RGBA: return DXGI_FORMAT_R16G16B16A16_FLOAT; - case PF_FLOAT32_R: return DXGI_FORMAT_R32_FLOAT; - case PF_FLOAT32_RGBA: return DXGI_FORMAT_R32G32B32A32_FLOAT; - case PF_SHORT_RGBA: return DXGI_FORMAT_R16G16B16A16_UNORM; - case PF_DXT1: return DXGI_FORMAT_BC1_UNORM; - case PF_DXT2: return DXGI_FORMAT_BC2_UNORM; - case PF_DXT3: return DXGI_FORMAT_BC3_UNORM; - case PF_DXT4: return DXGI_FORMAT_BC4_UNORM; - case PF_DXT5: return DXGI_FORMAT_BC5_UNORM; - case PF_BC6H_UF16: return DXGI_FORMAT_BC6H_UF16; - case PF_BC6H_SF16: return DXGI_FORMAT_BC6H_SF16; - case PF_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM; - case PF_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_UNORM_SRGB; - case PF_R16G16_SINT: return DXGI_FORMAT_R16G16_SINT; - case PF_UNKNOWN: - default: return DXGI_FORMAT_UNKNOWN; - } - } - //--------------------------------------------------------------------- - PixelFormat D3D11Mappings::_getClosestSupportedPF(PixelFormat ogrePF) - { - if (_getPF(ogrePF) != DXGI_FORMAT_UNKNOWN) - { - return ogrePF; - } - switch(ogrePF) - { - case PF_FLOAT16_RGB: - return PF_FLOAT16_RGBA; - case PF_FLOAT32_RGB: - return PF_FLOAT32_RGBA; - case PF_UNKNOWN: - default: - return PF_A8B8G8R8; - } - } - //--------------------------------------------------------------------- - D3D11_USAGE D3D11Mappings::_getUsage(HardwareBuffer::Usage mUsage) - { - if (_isDynamic(mUsage)) - { - return D3D11_USAGE_DYNAMIC; - } - else - { - return D3D11_USAGE_DEFAULT; - } - } - //--------------------------------------------------------------------- - bool D3D11Mappings::_isDynamic(HardwareBuffer::Usage mUsage) - { - switch ( mUsage) - { - case HardwareBuffer::HBU_DYNAMIC: - case HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY: - case HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE: - return true; - } + default: return PF_UNKNOWN; + } + } + //--------------------------------------------------------------------- + DXGI_FORMAT D3D11Mappings::_getPF(PixelFormat ogrePF) + { + switch(ogrePF) + { + case PF_L8: return DXGI_FORMAT_R8_UNORM; + case PF_L16: return DXGI_FORMAT_R16_UNORM; + case PF_A8: return DXGI_FORMAT_A8_UNORM; + case PF_A4L4: return DXGI_FORMAT_UNKNOWN; + case PF_BYTE_LA: return DXGI_FORMAT_UNKNOWN; + case PF_R3G3B2: return DXGI_FORMAT_UNKNOWN; + case PF_A1R5G5B5: return DXGI_FORMAT_UNKNOWN; + case PF_R5G6B5: return DXGI_FORMAT_UNKNOWN; + case PF_A4R4G4B4: return DXGI_FORMAT_UNKNOWN; + case PF_R8G8B8: return DXGI_FORMAT_UNKNOWN; + case PF_A8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM; + case PF_A8B8G8R8: return DXGI_FORMAT_R8G8B8A8_UNORM; + case PF_X8R8G8B8: return DXGI_FORMAT_UNKNOWN; + case PF_X8B8G8R8: return DXGI_FORMAT_UNKNOWN; + case PF_A2B10G10R10: return DXGI_FORMAT_R10G10B10A2_TYPELESS; + case PF_A2R10G10B10: return DXGI_FORMAT_UNKNOWN; + case PF_FLOAT16_R: return DXGI_FORMAT_R16_FLOAT; + case PF_FLOAT16_RGBA: return DXGI_FORMAT_R16G16B16A16_FLOAT; + case PF_FLOAT32_R: return DXGI_FORMAT_R32_FLOAT; + case PF_FLOAT32_RGBA: return DXGI_FORMAT_R32G32B32A32_FLOAT; + case PF_SHORT_RGBA: return DXGI_FORMAT_R16G16B16A16_UNORM; + case PF_DXT1: return DXGI_FORMAT_BC1_UNORM; + case PF_DXT2: return DXGI_FORMAT_BC2_UNORM; + case PF_DXT3: return DXGI_FORMAT_BC3_UNORM; + case PF_DXT4: return DXGI_FORMAT_BC4_UNORM; + case PF_DXT5: return DXGI_FORMAT_BC5_UNORM; + case PF_BC6H_UF16: return DXGI_FORMAT_BC6H_UF16; + case PF_BC6H_SF16: return DXGI_FORMAT_BC6H_SF16; + case PF_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM; + case PF_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_UNORM_SRGB; + case PF_R16G16_SINT: return DXGI_FORMAT_R16G16_SINT; + case PF_UNKNOWN: + default: return DXGI_FORMAT_UNKNOWN; + } + } + //--------------------------------------------------------------------- + PixelFormat D3D11Mappings::_getClosestSupportedPF(PixelFormat ogrePF) + { + if (_getPF(ogrePF) != DXGI_FORMAT_UNKNOWN) + { + return ogrePF; + } + switch(ogrePF) + { + case PF_FLOAT16_RGB: + return PF_FLOAT16_RGBA; + case PF_FLOAT32_RGB: + return PF_FLOAT32_RGBA; + case PF_UNKNOWN: + default: + return PF_A8B8G8R8; + } + } + //--------------------------------------------------------------------- + D3D11_USAGE D3D11Mappings::_getUsage(HardwareBuffer::Usage mUsage) + { + if (_isDynamic(mUsage)) + { + return D3D11_USAGE_DYNAMIC; + } + else + { + return D3D11_USAGE_DEFAULT; + } + } + //--------------------------------------------------------------------- + bool D3D11Mappings::_isDynamic(HardwareBuffer::Usage mUsage) + { + switch ( mUsage) + { + case HardwareBuffer::HBU_DYNAMIC: + case HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY: + case HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE: + return true; + } - return false; - } - //--------------------------------------------------------------------- - bool D3D11Mappings::_isDynamic(int mUsage) - { - return _isDynamic(static_cast(mUsage)); - } - //--------------------------------------------------------------------- - D3D11_USAGE D3D11Mappings::_getUsage(int mUsage) - { - return _getUsage(static_cast(mUsage)); - } - //--------------------------------------------------------------------- - UINT D3D11Mappings::_getAccessFlags(int mUsage) - { - return _getAccessFlags(static_cast(mUsage)); - } - //--------------------------------------------------------------------- - UINT D3D11Mappings::_getAccessFlags(HardwareBuffer::Usage mUsage) - { - if(_isDynamic(mUsage)) - return D3D11_CPU_ACCESS_WRITE; - else - return 0; - } - //--------------------------------------------------------------------- - DXGI_FORMAT D3D11Mappings::get(HardwareIndexBuffer::IndexType itype) - { - if (itype == HardwareIndexBuffer::IT_32BIT) - { - //AIZTODO: PUT THOSE VALUES AND FIND OUT WHY WE WANT THEM - return DXGI_FORMAT_R32_UINT;//return D3DFMT_INDEX32; - } - else - { - return DXGI_FORMAT_R16_UINT;//return D3DFMT_INDEX16; - } - } - //--------------------------------------------------------------------- - TextureType D3D11Mappings::_getTexType(D3D11_SRV_DIMENSION type) - { - switch(type) - { - case D3D_SRV_DIMENSION_TEXTURE1D: - return TEX_TYPE_1D; - case D3D_SRV_DIMENSION_TEXTURE2D: - case D3D_SRV_DIMENSION_TEXTURE2DMS: - return TEX_TYPE_2D; - case D3D_SRV_DIMENSION_TEXTURE2DARRAY: - case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: - return TEX_TYPE_2D_ARRAY; - case D3D_SRV_DIMENSION_TEXTURE3D: - return TEX_TYPE_3D; - case D3D_SRV_DIMENSION_TEXTURECUBE: - return TEX_TYPE_CUBE_MAP; - default: - // unknown - return static_cast(0); - } - } - //--------------------------------------------------------------------- - size_t D3D11Mappings::_getSizeInBytes(PixelFormat pf, size_t xcount, size_t ycount) - { - if(xcount == 0 || ycount == 0) - return 0; + return false; + } + //--------------------------------------------------------------------- + bool D3D11Mappings::_isDynamic(int mUsage) + { + return _isDynamic(static_cast(mUsage)); + } + //--------------------------------------------------------------------- + D3D11_USAGE D3D11Mappings::_getUsage(int mUsage) + { + return _getUsage(static_cast(mUsage)); + } + //--------------------------------------------------------------------- + UINT D3D11Mappings::_getAccessFlags(int mUsage) + { + return _getAccessFlags(static_cast(mUsage)); + } + //--------------------------------------------------------------------- + UINT D3D11Mappings::_getAccessFlags(HardwareBuffer::Usage mUsage) + { + if(_isDynamic(mUsage)) + return D3D11_CPU_ACCESS_WRITE; + else + return 0; + } + //--------------------------------------------------------------------- + DXGI_FORMAT D3D11Mappings::get(HardwareIndexBuffer::IndexType itype) + { + if (itype == HardwareIndexBuffer::IT_32BIT) + { + //AIZTODO: PUT THOSE VALUES AND FIND OUT WHY WE WANT THEM + return DXGI_FORMAT_R32_UINT;//return D3DFMT_INDEX32; + } + else + { + return DXGI_FORMAT_R16_UINT;//return D3DFMT_INDEX16; + } + } + //--------------------------------------------------------------------- + TextureType D3D11Mappings::_getTexType(D3D11_SRV_DIMENSION type) + { + switch(type) + { + case D3D_SRV_DIMENSION_TEXTURE1D: + return TEX_TYPE_1D; + case D3D_SRV_DIMENSION_TEXTURE2D: + case D3D_SRV_DIMENSION_TEXTURE2DMS: + return TEX_TYPE_2D; + case D3D_SRV_DIMENSION_TEXTURE2DARRAY: + case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY: + return TEX_TYPE_2D_ARRAY; + case D3D_SRV_DIMENSION_TEXTURE3D: + return TEX_TYPE_3D; + case D3D_SRV_DIMENSION_TEXTURECUBE: + return TEX_TYPE_CUBE_MAP; + default: + // unknown + return static_cast(0); + } + } + //--------------------------------------------------------------------- + size_t D3D11Mappings::_getSizeInBytes(PixelFormat pf, size_t xcount, size_t ycount) + { + if(xcount == 0 || ycount == 0) + return 0; - if(PixelUtil::isCompressed(pf)) - { - // D3D wants the width of one row of cells in bytes - if (pf == PF_DXT1) - { - // 64 bits (8 bytes) per 4x4 block - return std::max(1, xcount / 4) * std::max(1, ycount / 4) * 8; - } - else - { - // 128 bits (16 bytes) per 4x4 block - return std::max(1, xcount / 4) * std::max(1, ycount / 4) * 16; - } - } - else - { - return xcount * ycount * PixelUtil::getNumElemBytes(pf); - } - } + if(PixelUtil::isCompressed(pf)) + { + // D3D wants the width of one row of cells in bytes + if (pf == PF_DXT1) + { + // 64 bits (8 bytes) per 4x4 block + return std::max(1, xcount / 4) * std::max(1, ycount / 4) * 8; + } + else + { + // 128 bits (16 bytes) per 4x4 block + return std::max(1, xcount / 4) * std::max(1, ycount / 4) * 16; + } + } + else + { + return xcount * ycount * PixelUtil::getNumElemBytes(pf); + } + } - UINT D3D11Mappings::_getTextureBindFlags(DXGI_FORMAT format, bool isdynamic) - { - if(isdynamic) - return D3D11_BIND_SHADER_RESOURCE; + UINT D3D11Mappings::_getTextureBindFlags(DXGI_FORMAT format, bool isdynamic) + { + if(isdynamic) + return D3D11_BIND_SHADER_RESOURCE; - switch(format) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R32G32B32_SINT: - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return D3D11_BIND_SHADER_RESOURCE; - default: - return D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; - } - } + switch(format) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return D3D11_BIND_SHADER_RESOURCE; + default: + return D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + } + } - UINT D3D11Mappings::_getTextureMiscFlags(UINT bindflags, TextureType textype, bool isdynamic) - { - if(isdynamic) - return 0; + UINT D3D11Mappings::_getTextureMiscFlags(UINT bindflags, TextureType textype, bool isdynamic) + { + if(isdynamic) + return 0; - UINT flags = 0; + UINT flags = 0; D3D11RenderSystem* rsys = reinterpret_cast(Root::getSingleton().getRenderSystem()); - if(bindflags & D3D11_BIND_RENDER_TARGET) + if(bindflags & D3D11_BIND_RENDER_TARGET) //#if OGRE_PLATFORM == OGRE_PLATFORM_WINRT // if (rsys->_getFeatureLevel() == D3D_FEATURE_LEVEL_9_1) //#else // if (rsys->_getFeatureLevel() <= D3D_FEATURE_LEVEL_9_3) //#endif - flags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; + flags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; - if(textype == TEX_TYPE_CUBE_MAP) - flags |= D3D11_RESOURCE_MISC_TEXTURECUBE; + if(textype == TEX_TYPE_CUBE_MAP) + flags |= D3D11_RESOURCE_MISC_TEXTURECUBE; - return flags; - } + return flags; + } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11MultiRenderTarget.cpp b/RenderSystems/Direct3D11/src/OgreD3D11MultiRenderTarget.cpp index d5d48e602ce..c852c389ad4 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11MultiRenderTarget.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11MultiRenderTarget.cpp @@ -33,142 +33,142 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - D3D11MultiRenderTarget::D3D11MultiRenderTarget(const String &name) : - //--------------------------------------------------------------------- - MultiRenderTarget(name), mNumberOfViews(0) - { - /// Clear targets - for(size_t x=0; xgetCustomAttribute("BUFFER", &buffer); - assert(buffer); - - /// Find first non-null target - int y; - for(y=0; ygetWidth() != buffer->getWidth() || - targets[y]->getHeight() != buffer->getHeight() || - PixelUtil::getNumElemBits(targets[y]->getFormat()) != - PixelUtil::getNumElemBits(buffer->getFormat())) - { - OGRE_EXCEPT( - Exception::ERR_INVALIDPARAMS, - "MultiRenderTarget surfaces are not of same size or bit depth", - "D3D11MultiRenderTarget::bindSurface" - ); - } - } - - targets[attachment] = buffer; - mRenderTargets[attachment] = target; - - ID3D11RenderTargetView** v; - target->getCustomAttribute( "ID3D11RenderTargetView", &v ); - mRenderTargetViews[attachment] = *v; - - if(mNumberOfViews >= OGRE_MAX_MULTIPLE_RENDER_TARGETS) - mNumberOfViews++; - - checkAndUpdate(); - } - //--------------------------------------------------------------------- - void D3D11MultiRenderTarget::unbindSurfaceImpl(size_t attachment) - { - assert(attachment(Root::getSingleton().getRenderSystem()); - - MultiRenderTarget::update(); - } - //--------------------------------------------------------------------- - void D3D11MultiRenderTarget::getCustomAttribute(const String& name, void *pData) - { - if(name == "DDBACKBUFFER") - { - ID3D11Texture2D ** pSurf = (ID3D11Texture2D **)pData; - /// Transfer surfaces - for(size_t x=0; xgetParentTexture()->GetTex2D(); - } - return; - } - else if(name == "ID3D11RenderTargetView") - { - //*static_cast(pData) = mRenderTargetViews; - ID3D11RenderTargetView ** pRTView = (ID3D11RenderTargetView**)pData; - - memset(pRTView,0,sizeof(pRTView)); - - for(int y=0; ygetCustomAttribute("ID3D11RenderTargetView",&view); - pRTView[y]=view; - } - return; - } - else if( name == "numberOfViews" ) - { - uint* n = reinterpret_cast(pData); - *n = mNumberOfViews; - return; - } - else if(name == "isTexture") - { - bool *b = reinterpret_cast< bool * >( pData ); - *b = false; - return; - } - - MultiRenderTarget::getCustomAttribute(name, pData); - } - //--------------------------------------------------------------------- - void D3D11MultiRenderTarget::checkAndUpdate() - { - if(targets[0]) - { - mWidth = static_cast(targets[0]->getWidth()); - mHeight = static_cast(targets[0]->getHeight()); - } - else - { - mWidth = 0; - mHeight = 0; - } - } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + D3D11MultiRenderTarget::D3D11MultiRenderTarget(const String &name) : + //--------------------------------------------------------------------- + MultiRenderTarget(name), mNumberOfViews(0) + { + /// Clear targets + for(size_t x=0; xgetCustomAttribute("BUFFER", &buffer); + assert(buffer); + + /// Find first non-null target + int y; + for(y=0; ygetWidth() != buffer->getWidth() || + targets[y]->getHeight() != buffer->getHeight() || + PixelUtil::getNumElemBits(targets[y]->getFormat()) != + PixelUtil::getNumElemBits(buffer->getFormat())) + { + OGRE_EXCEPT( + Exception::ERR_INVALIDPARAMS, + "MultiRenderTarget surfaces are not of same size or bit depth", + "D3D11MultiRenderTarget::bindSurface" + ); + } + } + + targets[attachment] = buffer; + mRenderTargets[attachment] = target; + + ID3D11RenderTargetView** v; + target->getCustomAttribute( "ID3D11RenderTargetView", &v ); + mRenderTargetViews[attachment] = *v; + + if(mNumberOfViews >= OGRE_MAX_MULTIPLE_RENDER_TARGETS) + mNumberOfViews++; + + checkAndUpdate(); + } + //--------------------------------------------------------------------- + void D3D11MultiRenderTarget::unbindSurfaceImpl(size_t attachment) + { + assert(attachment(Root::getSingleton().getRenderSystem()); + + MultiRenderTarget::update(); + } + //--------------------------------------------------------------------- + void D3D11MultiRenderTarget::getCustomAttribute(const String& name, void *pData) + { + if(name == "DDBACKBUFFER") + { + ID3D11Texture2D ** pSurf = (ID3D11Texture2D **)pData; + /// Transfer surfaces + for(size_t x=0; xgetParentTexture()->GetTex2D(); + } + return; + } + else if(name == "ID3D11RenderTargetView") + { + //*static_cast(pData) = mRenderTargetViews; + ID3D11RenderTargetView ** pRTView = (ID3D11RenderTargetView**)pData; + + memset(pRTView,0,sizeof(pRTView)); + + for(int y=0; ygetCustomAttribute("ID3D11RenderTargetView",&view); + pRTView[y]=view; + } + return; + } + else if( name == "numberOfViews" ) + { + uint* n = reinterpret_cast(pData); + *n = mNumberOfViews; + return; + } + else if(name == "isTexture") + { + bool *b = reinterpret_cast< bool * >( pData ); + *b = false; + return; + } + + MultiRenderTarget::getCustomAttribute(name, pData); + } + //--------------------------------------------------------------------- + void D3D11MultiRenderTarget::checkAndUpdate() + { + if(targets[0]) + { + mWidth = static_cast(targets[0]->getWidth()); + mHeight = static_cast(targets[0]->getHeight()); + } + else + { + mWidth = 0; + mHeight = 0; + } + } + //--------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11Plugin.cpp b/RenderSystems/Direct3D11/src/OgreD3D11Plugin.cpp index b5487558e8a..c43d0441d35 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11Plugin.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11Plugin.cpp @@ -30,42 +30,42 @@ THE SOFTWARE. namespace Ogre { - const String sPluginName = "D3D11 RenderSystem"; - //--------------------------------------------------------------------- - D3D11Plugin::D3D11Plugin() - : mRenderSystem(0) - { + const String sPluginName = "D3D11 RenderSystem"; + //--------------------------------------------------------------------- + D3D11Plugin::D3D11Plugin() + : mRenderSystem(0) + { - } - //--------------------------------------------------------------------- - const String& D3D11Plugin::getName() const - { - return sPluginName; - } - //--------------------------------------------------------------------- - void D3D11Plugin::install() - { - // Create the DirectX 11 rendering api - mRenderSystem = new D3D11RenderSystem(); - // Register the render system - Root::getSingleton().addRenderSystem( mRenderSystem ); - } - //--------------------------------------------------------------------- - void D3D11Plugin::initialise() - { - // nothing to do - } - //--------------------------------------------------------------------- - void D3D11Plugin::shutdown() - { - // nothing to do - } - //--------------------------------------------------------------------- - void D3D11Plugin::uninstall() - { - delete mRenderSystem; - mRenderSystem = 0; - } + } + //--------------------------------------------------------------------- + const String& D3D11Plugin::getName() const + { + return sPluginName; + } + //--------------------------------------------------------------------- + void D3D11Plugin::install() + { + // Create the DirectX 11 rendering api + mRenderSystem = new D3D11RenderSystem(); + // Register the render system + Root::getSingleton().addRenderSystem( mRenderSystem ); + } + //--------------------------------------------------------------------- + void D3D11Plugin::initialise() + { + // nothing to do + } + //--------------------------------------------------------------------- + void D3D11Plugin::shutdown() + { + // nothing to do + } + //--------------------------------------------------------------------- + void D3D11Plugin::uninstall() + { + delete mRenderSystem; + mRenderSystem = 0; + } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp b/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp index 8c1bbeb9da3..974d664d35e 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11RenderSystem.cpp @@ -71,82 +71,82 @@ THE SOFTWARE. #define FLOAT2DWORD(f) *((DWORD*)&f) #ifndef D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT -# define D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT 4 +# define D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT 4 #endif #ifndef D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT -# define D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT 1 +# define D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT 1 #endif //--------------------------------------------------------------------- #include namespace Ogre { - inline HRESULT WINAPI D3D11CreateDeviceN( - _In_opt_ IDXGIAdapter* pAdapter, - D3D_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - /*_In_reads_opt_( FeatureLevels )*/ CONST D3D_FEATURE_LEVEL* pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - _Out_opt_ ID3D11DeviceN** ppDevice, - _Out_opt_ D3D_FEATURE_LEVEL* pFeatureLevel, - _Out_opt_ ID3D11DeviceContextN** ppImmediateContext ) - { + inline HRESULT WINAPI D3D11CreateDeviceN( + _In_opt_ IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + /*_In_reads_opt_( FeatureLevels )*/ CONST D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + _Out_opt_ ID3D11DeviceN** ppDevice, + _Out_opt_ D3D_FEATURE_LEVEL* pFeatureLevel, + _Out_opt_ ID3D11DeviceContextN** ppImmediateContext ) + { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - return D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext); + return D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext); #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - ID3D11Device * device = NULL; - ID3D11DeviceContext * context = NULL; - ID3D11DeviceN * deviceN = NULL; - ID3D11DeviceContextN * contextN = NULL; - D3D_FEATURE_LEVEL featureLevel; + ID3D11Device * device = NULL; + ID3D11DeviceContext * context = NULL; + ID3D11DeviceN * deviceN = NULL; + ID3D11DeviceContextN * contextN = NULL; + D3D_FEATURE_LEVEL featureLevel; - HRESULT hr = D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, - (ppDevice ? &device : NULL), &featureLevel, (ppImmediateContext ? &context : NULL)); - if(FAILED(hr)) goto bail; + HRESULT hr = D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, + (ppDevice ? &device : NULL), &featureLevel, (ppImmediateContext ? &context : NULL)); + if(FAILED(hr)) goto bail; - hr = device ? device->QueryInterface(__uuidof(ID3D11DeviceN), (void **)&deviceN) : hr; - if(FAILED(hr)) goto bail; + hr = device ? device->QueryInterface(__uuidof(ID3D11DeviceN), (void **)&deviceN) : hr; + if(FAILED(hr)) goto bail; - hr = context ? context->QueryInterface(__uuidof(ID3D11DeviceContextN), (void **)&contextN) : hr; - if(FAILED(hr)) goto bail; + hr = context ? context->QueryInterface(__uuidof(ID3D11DeviceContextN), (void **)&contextN) : hr; + if(FAILED(hr)) goto bail; - if(ppDevice) { *ppDevice = deviceN; deviceN = NULL; } - if(pFeatureLevel) { *pFeatureLevel = featureLevel; } - if(ppImmediateContext) { *ppImmediateContext = contextN; contextN = NULL; } + if(ppDevice) { *ppDevice = deviceN; deviceN = NULL; } + if(pFeatureLevel) { *pFeatureLevel = featureLevel; } + if(ppImmediateContext) { *ppImmediateContext = contextN; contextN = NULL; } bail: - SAFE_RELEASE(deviceN); - SAFE_RELEASE(contextN); - SAFE_RELEASE(device); - SAFE_RELEASE(context); - return hr; + SAFE_RELEASE(deviceN); + SAFE_RELEASE(contextN); + SAFE_RELEASE(device); + SAFE_RELEASE(context); + return hr; #endif - } + } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- D3D11RenderSystem::D3D11RenderSystem() : mDevice(NULL) - { - LogManager::getSingleton().logMessage( "D3D11 : " + getName() + " created." ); + { + LogManager::getSingleton().logMessage( "D3D11 : " + getName() + " created." ); - mEnableFixedPipeline = false; + mEnableFixedPipeline = false; - mRenderSystemWasInited = false; - initRenderSystem(); + mRenderSystemWasInited = false; + initRenderSystem(); - // set config options defaults - initConfigOptions(); + // set config options defaults + initConfigOptions(); - // Clear class instance storage - memset(mClassInstances, 0, sizeof(mClassInstances)); - memset(mNumClassInstances, 0, sizeof(mNumClassInstances)); - } - //--------------------------------------------------------------------- - D3D11RenderSystem::~D3D11RenderSystem() - { + // Clear class instance storage + memset(mClassInstances, 0, sizeof(mClassInstances)); + memset(mNumClassInstances, 0, sizeof(mNumClassInstances)); + } + //--------------------------------------------------------------------- + D3D11RenderSystem::~D3D11RenderSystem() + { shutdown(); // Deleting the HLSL program factory @@ -159,129 +159,129 @@ namespace Ogre mHLSLProgramFactory = 0; } - //SAFE_RELEASE( mpD3D ); - - LogManager::getSingleton().logMessage( "D3D11 : " + getName() + " destroyed." ); - } - //--------------------------------------------------------------------- - const String& D3D11RenderSystem::getName() const - { - static String strName( "Direct3D11 Rendering Subsystem"); - return strName; - } - //--------------------------------------------------------------------- - D3D11DriverList* D3D11RenderSystem::getDirect3DDrivers() - { - if( !mDriverList ) - mDriverList = new D3D11DriverList( mpDXGIFactory ); - - return mDriverList; - } - //--------------------------------------------------------------------- - bool D3D11RenderSystem::_checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format) - { - // TODO: check if we need this function - HRESULT hr; - hr = mDevice->CheckMultisampleQualityLevels( - format, - SampleCount, - outQuality); - - if (SUCCEEDED(hr) && *outQuality > 0) - return true; - else - return false; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::initConfigOptions() - { - D3D11DriverList* driverList; - D3D11Driver* driver; - - ConfigOption optDevice; - ConfigOption optVideoMode; - ConfigOption optFullScreen; - ConfigOption optVSync; - ConfigOption optVSyncInterval; - ConfigOption optAA; - ConfigOption optFPUMode; - ConfigOption optNVPerfHUD; - ConfigOption optSRGB; + //SAFE_RELEASE( mpD3D ); + + LogManager::getSingleton().logMessage( "D3D11 : " + getName() + " destroyed." ); + } + //--------------------------------------------------------------------- + const String& D3D11RenderSystem::getName() const + { + static String strName( "Direct3D11 Rendering Subsystem"); + return strName; + } + //--------------------------------------------------------------------- + D3D11DriverList* D3D11RenderSystem::getDirect3DDrivers() + { + if( !mDriverList ) + mDriverList = new D3D11DriverList( mpDXGIFactory ); + + return mDriverList; + } + //--------------------------------------------------------------------- + bool D3D11RenderSystem::_checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format) + { + // TODO: check if we need this function + HRESULT hr; + hr = mDevice->CheckMultisampleQualityLevels( + format, + SampleCount, + outQuality); + + if (SUCCEEDED(hr) && *outQuality > 0) + return true; + else + return false; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::initConfigOptions() + { + D3D11DriverList* driverList; + D3D11Driver* driver; + + ConfigOption optDevice; + ConfigOption optVideoMode; + ConfigOption optFullScreen; + ConfigOption optVSync; + ConfigOption optVSyncInterval; + ConfigOption optAA; + ConfigOption optFPUMode; + ConfigOption optNVPerfHUD; + ConfigOption optSRGB; ConfigOption optMinFeatureLevels; ConfigOption optMaxFeatureLevels; - ConfigOption optExceptionsErrorLevel; - ConfigOption optDriverType; - - - - driverList = this->getDirect3DDrivers(); - - optDevice.name = "Rendering Device"; - optDevice.currentValue.clear(); - optDevice.possibleValues.clear(); - optDevice.immutable = false; - - optVideoMode.name = "Video Mode"; - optVideoMode.currentValue = "800 x 600 @ 32-bit colour"; - optVideoMode.immutable = false; - - optFullScreen.name = "Full Screen"; - optFullScreen.possibleValues.push_back( "Yes" ); - optFullScreen.possibleValues.push_back( "No" ); - optFullScreen.currentValue = "Yes"; - optFullScreen.immutable = false; - - for( unsigned j=0; j < driverList->count(); j++ ) - { - driver = driverList->item(j); - optDevice.possibleValues.push_back( driver->DriverDescription() ); - // Make first one default - if( j==0 ) - optDevice.currentValue = driver->DriverDescription(); - } - - optVSync.name = "VSync"; - optVSync.immutable = false; - optVSync.possibleValues.push_back( "Yes" ); - optVSync.possibleValues.push_back( "No" ); - optVSync.currentValue = "No"; - - optVSyncInterval.name = "VSync Interval"; - optVSyncInterval.immutable = false; - optVSyncInterval.possibleValues.push_back( "1" ); - optVSyncInterval.possibleValues.push_back( "2" ); - optVSyncInterval.possibleValues.push_back( "3" ); - optVSyncInterval.possibleValues.push_back( "4" ); - optVSyncInterval.currentValue = "1"; - - optAA.name = "FSAA"; - optAA.immutable = false; - optAA.possibleValues.push_back( "None" ); - optAA.currentValue = "None"; - - optFPUMode.name = "Floating-point mode"; + ConfigOption optExceptionsErrorLevel; + ConfigOption optDriverType; + + + + driverList = this->getDirect3DDrivers(); + + optDevice.name = "Rendering Device"; + optDevice.currentValue.clear(); + optDevice.possibleValues.clear(); + optDevice.immutable = false; + + optVideoMode.name = "Video Mode"; + optVideoMode.currentValue = "800 x 600 @ 32-bit colour"; + optVideoMode.immutable = false; + + optFullScreen.name = "Full Screen"; + optFullScreen.possibleValues.push_back( "Yes" ); + optFullScreen.possibleValues.push_back( "No" ); + optFullScreen.currentValue = "Yes"; + optFullScreen.immutable = false; + + for( unsigned j=0; j < driverList->count(); j++ ) + { + driver = driverList->item(j); + optDevice.possibleValues.push_back( driver->DriverDescription() ); + // Make first one default + if( j==0 ) + optDevice.currentValue = driver->DriverDescription(); + } + + optVSync.name = "VSync"; + optVSync.immutable = false; + optVSync.possibleValues.push_back( "Yes" ); + optVSync.possibleValues.push_back( "No" ); + optVSync.currentValue = "No"; + + optVSyncInterval.name = "VSync Interval"; + optVSyncInterval.immutable = false; + optVSyncInterval.possibleValues.push_back( "1" ); + optVSyncInterval.possibleValues.push_back( "2" ); + optVSyncInterval.possibleValues.push_back( "3" ); + optVSyncInterval.possibleValues.push_back( "4" ); + optVSyncInterval.currentValue = "1"; + + optAA.name = "FSAA"; + optAA.immutable = false; + optAA.possibleValues.push_back( "None" ); + optAA.currentValue = "None"; + + optFPUMode.name = "Floating-point mode"; #if OGRE_DOUBLE_PRECISION - optFPUMode.currentValue = "Consistent"; + optFPUMode.currentValue = "Consistent"; #else - optFPUMode.currentValue = "Fastest"; + optFPUMode.currentValue = "Fastest"; #endif - optFPUMode.possibleValues.clear(); - optFPUMode.possibleValues.push_back("Fastest"); - optFPUMode.possibleValues.push_back("Consistent"); - optFPUMode.immutable = false; - - optNVPerfHUD.currentValue = "No"; - optNVPerfHUD.immutable = false; - optNVPerfHUD.name = "Allow NVPerfHUD"; - optNVPerfHUD.possibleValues.push_back( "Yes" ); - optNVPerfHUD.possibleValues.push_back( "No" ); - - // SRGB on auto window - optSRGB.name = "sRGB Gamma Conversion"; - optSRGB.possibleValues.push_back("Yes"); - optSRGB.possibleValues.push_back("No"); - optSRGB.currentValue = "No"; - optSRGB.immutable = false; + optFPUMode.possibleValues.clear(); + optFPUMode.possibleValues.push_back("Fastest"); + optFPUMode.possibleValues.push_back("Consistent"); + optFPUMode.immutable = false; + + optNVPerfHUD.currentValue = "No"; + optNVPerfHUD.immutable = false; + optNVPerfHUD.name = "Allow NVPerfHUD"; + optNVPerfHUD.possibleValues.push_back( "Yes" ); + optNVPerfHUD.possibleValues.push_back( "No" ); + + // SRGB on auto window + optSRGB.name = "sRGB Gamma Conversion"; + optSRGB.possibleValues.push_back("Yes"); + optSRGB.possibleValues.push_back("No"); + optSRGB.currentValue = "No"; + optSRGB.immutable = false; // min feature level optMinFeatureLevels; @@ -292,8 +292,8 @@ namespace Ogre optMinFeatureLevels.possibleValues.push_back("10.1"); optMinFeatureLevels.possibleValues.push_back("11.0"); - optMinFeatureLevels.currentValue = "9.1"; - optMinFeatureLevels.immutable = false; + optMinFeatureLevels.currentValue = "9.1"; + optMinFeatureLevels.immutable = false; // max feature level @@ -302,7 +302,7 @@ namespace Ogre optMaxFeatureLevels.possibleValues.push_back("9.1"); #if OGRE_PLATFORM == OGRE_PLATFORM_WINRT -# if OGRE_WINRT_TARGET_TYPE == PHONE +# if OGRE_WINRT_TARGET_TYPE == PHONE optMaxFeatureLevels.possibleValues.push_back("9.2"); # endif optMaxFeatureLevels.possibleValues.push_back("9.3"); @@ -315,77 +315,77 @@ namespace Ogre optMaxFeatureLevels.currentValue = "11.0"; #endif - optMaxFeatureLevels.immutable = false; + optMaxFeatureLevels.immutable = false; // Exceptions Error Level - optExceptionsErrorLevel.name = "Information Queue Exceptions Bottom Level"; - optExceptionsErrorLevel.possibleValues.push_back("No information queue exceptions"); - optExceptionsErrorLevel.possibleValues.push_back("Corruption"); - optExceptionsErrorLevel.possibleValues.push_back("Error"); - optExceptionsErrorLevel.possibleValues.push_back("Warning"); - optExceptionsErrorLevel.possibleValues.push_back("Info (exception on any message)"); + optExceptionsErrorLevel.name = "Information Queue Exceptions Bottom Level"; + optExceptionsErrorLevel.possibleValues.push_back("No information queue exceptions"); + optExceptionsErrorLevel.possibleValues.push_back("Corruption"); + optExceptionsErrorLevel.possibleValues.push_back("Error"); + optExceptionsErrorLevel.possibleValues.push_back("Warning"); + optExceptionsErrorLevel.possibleValues.push_back("Info (exception on any message)"); #if OGRE_DEBUG_MODE - optExceptionsErrorLevel.currentValue = "Info (exception on any message)"; + optExceptionsErrorLevel.currentValue = "Info (exception on any message)"; #else - optExceptionsErrorLevel.currentValue = "No information queue exceptions"; + optExceptionsErrorLevel.currentValue = "No information queue exceptions"; #endif - optExceptionsErrorLevel.immutable = false; - - - // Driver type - optDriverType.name = "Driver type"; - optDriverType.possibleValues.push_back("Hardware"); - optDriverType.possibleValues.push_back("Software"); - optDriverType.possibleValues.push_back("Warp"); - optDriverType.currentValue = "Hardware"; - optDriverType.immutable = false; - - - mOptions[optDevice.name] = optDevice; - mOptions[optVideoMode.name] = optVideoMode; - mOptions[optFullScreen.name] = optFullScreen; - mOptions[optVSync.name] = optVSync; - mOptions[optVSyncInterval.name] = optVSyncInterval; - mOptions[optAA.name] = optAA; - mOptions[optFPUMode.name] = optFPUMode; - mOptions[optNVPerfHUD.name] = optNVPerfHUD; - mOptions[optSRGB.name] = optSRGB; + optExceptionsErrorLevel.immutable = false; + + + // Driver type + optDriverType.name = "Driver type"; + optDriverType.possibleValues.push_back("Hardware"); + optDriverType.possibleValues.push_back("Software"); + optDriverType.possibleValues.push_back("Warp"); + optDriverType.currentValue = "Hardware"; + optDriverType.immutable = false; + + + mOptions[optDevice.name] = optDevice; + mOptions[optVideoMode.name] = optVideoMode; + mOptions[optFullScreen.name] = optFullScreen; + mOptions[optVSync.name] = optVSync; + mOptions[optVSyncInterval.name] = optVSyncInterval; + mOptions[optAA.name] = optAA; + mOptions[optFPUMode.name] = optFPUMode; + mOptions[optNVPerfHUD.name] = optNVPerfHUD; + mOptions[optSRGB.name] = optSRGB; mOptions[optMinFeatureLevels.name] = optMinFeatureLevels; mOptions[optMaxFeatureLevels.name] = optMaxFeatureLevels; - mOptions[optExceptionsErrorLevel.name] = optExceptionsErrorLevel; - mOptions[optDriverType.name] = optDriverType; - - refreshD3DSettings(); - - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::refreshD3DSettings() - { - ConfigOption* optVideoMode; - D3D11Driver* driver = 0; - D3D11VideoMode* videoMode; - - ConfigOptionMap::iterator opt = mOptions.find( "Rendering Device" ); - if( opt != mOptions.end() ) - { - for( unsigned j=0; j < getDirect3DDrivers()->count(); j++ ) - { - driver = getDirect3DDrivers()->item(j); - if( driver->DriverDescription() == opt->second.currentValue ) - break; - } - - if (driver) - { - opt = mOptions.find( "Video Mode" ); - optVideoMode = &opt->second; - optVideoMode->possibleValues.clear(); - // get vide modes for this device - for( unsigned k=0; k < driver->getVideoModeList()->count(); k++ ) - { - videoMode = driver->getVideoModeList()->item( k ); - optVideoMode->possibleValues.push_back( videoMode->getDescription() ); - } + mOptions[optExceptionsErrorLevel.name] = optExceptionsErrorLevel; + mOptions[optDriverType.name] = optDriverType; + + refreshD3DSettings(); + + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::refreshD3DSettings() + { + ConfigOption* optVideoMode; + D3D11Driver* driver = 0; + D3D11VideoMode* videoMode; + + ConfigOptionMap::iterator opt = mOptions.find( "Rendering Device" ); + if( opt != mOptions.end() ) + { + for( unsigned j=0; j < getDirect3DDrivers()->count(); j++ ) + { + driver = getDirect3DDrivers()->item(j); + if( driver->DriverDescription() == opt->second.currentValue ) + break; + } + + if (driver) + { + opt = mOptions.find( "Video Mode" ); + optVideoMode = &opt->second; + optVideoMode->possibleValues.clear(); + // get vide modes for this device + for( unsigned k=0; k < driver->getVideoModeList()->count(); k++ ) + { + videoMode = driver->getVideoModeList()->item( k ); + optVideoMode->possibleValues.push_back( videoMode->getDescription() ); + } // Reset video mode to default if previous doesn't avail in new possible values StringVector::const_iterator itValue = @@ -399,47 +399,47 @@ namespace Ogre // Also refresh FSAA options refreshFSAAOptions(); - } - } + } + } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setConfigOption( const String &name, const String &value ) - { - initRenderSystem(); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setConfigOption( const String &name, const String &value ) + { + initRenderSystem(); - LogManager::getSingleton().stream() - << "D3D11 : RenderSystem Option: " << name << " = " << value; + LogManager::getSingleton().stream() + << "D3D11 : RenderSystem Option: " << name << " = " << value; bool viewModeChanged = false; - // Find option - ConfigOptionMap::iterator it = mOptions.find( name ); + // Find option + ConfigOptionMap::iterator it = mOptions.find( name ); - // Update - if( it != mOptions.end() ) - it->second.currentValue = value; - else - { - StringStream str; + // Update + if( it != mOptions.end() ) + it->second.currentValue = value; + else + { + StringStream str; str << "Option named '" << name << "' does not exist."; - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, str.str(), "D3D11RenderSystem::setConfigOption" ); - } + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, str.str(), "D3D11RenderSystem::setConfigOption" ); + } - // Refresh other options if D3DDriver changed - if( name == "Rendering Device" ) - refreshD3DSettings(); + // Refresh other options if D3DDriver changed + if( name == "Rendering Device" ) + refreshD3DSettings(); - if( name == "Full Screen" ) - { - // Video mode is applicable - it = mOptions.find( "Video Mode" ); - if (it->second.currentValue.empty()) + if( name == "Full Screen" ) + { + // Video mode is applicable + it = mOptions.find( "Video Mode" ); + if (it->second.currentValue.empty()) { - it->second.currentValue = "800 x 600 @ 32-bit colour"; + it->second.currentValue = "800 x 600 @ 32-bit colour"; viewModeChanged = true; } - } + } if( name == "Min Requested Feature Levels" ) { @@ -481,21 +481,21 @@ namespace Ogre #endif } - if( name == "Allow NVPerfHUD" ) - { - if (value == "Yes") - mUseNVPerfHUD = true; - else - mUseNVPerfHUD = false; - } + if( name == "Allow NVPerfHUD" ) + { + if (value == "Yes") + mUseNVPerfHUD = true; + else + mUseNVPerfHUD = false; + } - if (viewModeChanged || name == "Video Mode") - { + if (viewModeChanged || name == "Video Mode") + { refreshFSAAOptions(); - } + } - } - //--------------------------------------------------------------------- + } + //--------------------------------------------------------------------- void D3D11RenderSystem::refreshFSAAOptions(void) { @@ -513,7 +513,7 @@ namespace Ogre if (videoMode) { UINT numLevels = 0; - bool bOK=false; + bool bOK=false; // set maskable levels supported for (unsigned int n = 1; n < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; n++) { @@ -523,13 +523,13 @@ namespace Ogre videoMode->getFormat() ); if (bOK) - { + { optFSAA->possibleValues.push_back(StringConverter::toString(n)); - if (n >=8) - { - optFSAA->possibleValues.push_back(StringConverter::toString(n) + " [Quality]"); - } - } + if (n >=8) + { + optFSAA->possibleValues.push_back(StringConverter::toString(n) + " [Quality]"); + } + } } } } @@ -545,120 +545,120 @@ namespace Ogre } } - //--------------------------------------------------------------------- - String D3D11RenderSystem::validateConfigOptions() - { - ConfigOptionMap::iterator it; - - // check if video mode is selected - it = mOptions.find( "Video Mode" ); - if (it->second.currentValue.empty()) - return "A video mode must be selected."; - - it = mOptions.find( "Rendering Device" ); - bool foundDriver = false; - D3D11DriverList* driverList = getDirect3DDrivers(); - for( ushort j=0; j < driverList->count(); j++ ) - { - if( driverList->item(j)->DriverDescription() == it->second.currentValue ) - { - foundDriver = true; - break; - } - } - - if (!foundDriver) - { - // Just pick the first driver - setConfigOption("Rendering Device", driverList->item(0)->DriverDescription()); - return "Your DirectX driver name has changed since the last time you ran OGRE; " - "the 'Rendering Device' has been changed."; - } + //--------------------------------------------------------------------- + String D3D11RenderSystem::validateConfigOptions() + { + ConfigOptionMap::iterator it; + + // check if video mode is selected + it = mOptions.find( "Video Mode" ); + if (it->second.currentValue.empty()) + return "A video mode must be selected."; + + it = mOptions.find( "Rendering Device" ); + bool foundDriver = false; + D3D11DriverList* driverList = getDirect3DDrivers(); + for( ushort j=0; j < driverList->count(); j++ ) + { + if( driverList->item(j)->DriverDescription() == it->second.currentValue ) + { + foundDriver = true; + break; + } + } + + if (!foundDriver) + { + // Just pick the first driver + setConfigOption("Rendering Device", driverList->item(0)->DriverDescription()); + return "Your DirectX driver name has changed since the last time you ran OGRE; " + "the 'Rendering Device' has been changed."; + } return BLANKSTRING; - } - //--------------------------------------------------------------------- - ConfigOptionMap& D3D11RenderSystem::getConfigOptions() - { - // return a COPY of the current config options - return mOptions; - } - //--------------------------------------------------------------------- - RenderWindow* D3D11RenderSystem::_initialise( bool autoCreateWindow, const String& windowTitle ) - { - RenderWindow* autoWindow = NULL; - LogManager::getSingleton().logMessage( "D3D11 : Subsystem Initialising" ); - - // Init using current settings - mActiveD3DDriver = NULL; - ConfigOptionMap::iterator opt = mOptions.find( "Rendering Device" ); - for( unsigned j=0; j < getDirect3DDrivers()->count(); j++ ) - { - if( getDirect3DDrivers()->item(j)->DriverDescription() == opt->second.currentValue ) - { - mActiveD3DDriver = getDirect3DDrivers()->item(j); - break; - } - } - - if( !mActiveD3DDriver ) - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Problems finding requested Direct3D driver!", "D3D11RenderSystem::initialise" ); - - //AIZ:recreate the device for the selected adapter - { - if (!mDevice.isNull()) - { - mDevice.release(); - } - - - opt = mOptions.find( "Information Queue Exceptions Bottom Level" ); - if( opt == mOptions.end() ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find Information Queue Exceptions Bottom Level option!", "D3D11RenderSystem::initialise" ); - String infoQType = opt->second.currentValue; - - if ("No information queue exceptions" == infoQType) - { - D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_NO_EXCEPTION); - } - else if ("Corruption" == infoQType) - { - D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_CORRUPTION); - } - else if ("Error" == infoQType) - { - D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_ERROR); - } - else if ("Warning" == infoQType) - { - D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_WARNING); - } - else if ("Info (exception on any message)" == infoQType) - { - D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_INFO); - } - - - - // Driver type - opt = mOptions.find( "Driver type" ); - if( opt == mOptions.end() ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find driver type!", "D3D11RenderSystem::initialise" ); - String driverTypeName = opt->second.currentValue; - - mDriverType = DT_HARDWARE; - if ("Hardware" == driverTypeName) - { - mDriverType = DT_HARDWARE; - } - if ("Software" == driverTypeName) - { - mDriverType = DT_SOFTWARE; - } - if ("Warp" == driverTypeName) - { - mDriverType = DT_WARP; - } + } + //--------------------------------------------------------------------- + ConfigOptionMap& D3D11RenderSystem::getConfigOptions() + { + // return a COPY of the current config options + return mOptions; + } + //--------------------------------------------------------------------- + RenderWindow* D3D11RenderSystem::_initialise( bool autoCreateWindow, const String& windowTitle ) + { + RenderWindow* autoWindow = NULL; + LogManager::getSingleton().logMessage( "D3D11 : Subsystem Initialising" ); + + // Init using current settings + mActiveD3DDriver = NULL; + ConfigOptionMap::iterator opt = mOptions.find( "Rendering Device" ); + for( unsigned j=0; j < getDirect3DDrivers()->count(); j++ ) + { + if( getDirect3DDrivers()->item(j)->DriverDescription() == opt->second.currentValue ) + { + mActiveD3DDriver = getDirect3DDrivers()->item(j); + break; + } + } + + if( !mActiveD3DDriver ) + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Problems finding requested Direct3D driver!", "D3D11RenderSystem::initialise" ); + + //AIZ:recreate the device for the selected adapter + { + if (!mDevice.isNull()) + { + mDevice.release(); + } + + + opt = mOptions.find( "Information Queue Exceptions Bottom Level" ); + if( opt == mOptions.end() ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find Information Queue Exceptions Bottom Level option!", "D3D11RenderSystem::initialise" ); + String infoQType = opt->second.currentValue; + + if ("No information queue exceptions" == infoQType) + { + D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_NO_EXCEPTION); + } + else if ("Corruption" == infoQType) + { + D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_CORRUPTION); + } + else if ("Error" == infoQType) + { + D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_ERROR); + } + else if ("Warning" == infoQType) + { + D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_WARNING); + } + else if ("Info (exception on any message)" == infoQType) + { + D3D11Device::setExceptionsErrorLevel(D3D11Device::D3D_INFO); + } + + + + // Driver type + opt = mOptions.find( "Driver type" ); + if( opt == mOptions.end() ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find driver type!", "D3D11RenderSystem::initialise" ); + String driverTypeName = opt->second.currentValue; + + mDriverType = DT_HARDWARE; + if ("Hardware" == driverTypeName) + { + mDriverType = DT_HARDWARE; + } + if ("Software" == driverTypeName) + { + mDriverType = DT_SOFTWARE; + } + if ("Warp" == driverTypeName) + { + mDriverType = DT_WARP; + } UINT deviceFlags = 0; #if OGRE_PLATFORM == OGRE_PLATFORM_WINRT @@ -669,69 +669,69 @@ namespace Ogre { deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; } - if (!OGRE_THREAD_SUPPORT) - { - deviceFlags |= D3D11_CREATE_DEVICE_SINGLETHREADED; - } - D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_UNKNOWN ; - - // Search for a PerfHUD adapter - UINT nAdapter = 0; - IDXGIAdapterN* pAdapter = NULL; - IDXGIAdapterN* pSelectedAdapter = mActiveD3DDriver->getDeviceAdapter(); - if(pSelectedAdapter) - pSelectedAdapter->AddRef(); - if ( mUseNVPerfHUD ) - { - // Search for a PerfHUD adapter - while( mpDXGIFactory->EnumAdapters1( nAdapter, &pAdapter ) != DXGI_ERROR_NOT_FOUND ) - { - if ( pAdapter ) - { - DXGI_ADAPTER_DESC1 adaptDesc; - if ( SUCCEEDED( pAdapter->GetDesc1( &adaptDesc ) ) ) - { - const bool isPerfHUD = wcscmp( adaptDesc.Description, L"NVIDIA PerfHUD" ) == 0; - if ( isPerfHUD ) - { - SAFE_RELEASE(pSelectedAdapter); - pSelectedAdapter = pAdapter; - pSelectedAdapter->AddRef(); - driverType = D3D_DRIVER_TYPE_REFERENCE; - } - } - SAFE_RELEASE(pAdapter); - ++nAdapter; - } - } - - } - - if (mDriverType == DT_SOFTWARE) - { - driverType = D3D_DRIVER_TYPE_SOFTWARE; - SAFE_RELEASE(pSelectedAdapter); - } - - if (mDriverType == DT_WARP) - { - driverType = D3D_DRIVER_TYPE_WARP; - SAFE_RELEASE(pSelectedAdapter); - } - - D3D_FEATURE_LEVEL requestedLevels[] = { + if (!OGRE_THREAD_SUPPORT) + { + deviceFlags |= D3D11_CREATE_DEVICE_SINGLETHREADED; + } + D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_UNKNOWN ; + + // Search for a PerfHUD adapter + UINT nAdapter = 0; + IDXGIAdapterN* pAdapter = NULL; + IDXGIAdapterN* pSelectedAdapter = mActiveD3DDriver->getDeviceAdapter(); + if(pSelectedAdapter) + pSelectedAdapter->AddRef(); + if ( mUseNVPerfHUD ) + { + // Search for a PerfHUD adapter + while( mpDXGIFactory->EnumAdapters1( nAdapter, &pAdapter ) != DXGI_ERROR_NOT_FOUND ) + { + if ( pAdapter ) + { + DXGI_ADAPTER_DESC1 adaptDesc; + if ( SUCCEEDED( pAdapter->GetDesc1( &adaptDesc ) ) ) + { + const bool isPerfHUD = wcscmp( adaptDesc.Description, L"NVIDIA PerfHUD" ) == 0; + if ( isPerfHUD ) + { + SAFE_RELEASE(pSelectedAdapter); + pSelectedAdapter = pAdapter; + pSelectedAdapter->AddRef(); + driverType = D3D_DRIVER_TYPE_REFERENCE; + } + } + SAFE_RELEASE(pAdapter); + ++nAdapter; + } + } + + } + + if (mDriverType == DT_SOFTWARE) + { + driverType = D3D_DRIVER_TYPE_SOFTWARE; + SAFE_RELEASE(pSelectedAdapter); + } + + if (mDriverType == DT_WARP) + { + driverType = D3D_DRIVER_TYPE_WARP; + SAFE_RELEASE(pSelectedAdapter); + } + + D3D_FEATURE_LEVEL requestedLevels[] = { #if (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == DESKTOP_APP) D3D_FEATURE_LEVEL_11_1, #endif // (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == DESKTOP_APP) #if !( (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == PHONE) ) - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, #endif // !( (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == PHONE) ) - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1 - }; + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1 + }; unsigned int requestedLevelsSize = sizeof( requestedLevels ) / sizeof( requestedLevels[0] ); @@ -757,141 +757,141 @@ namespace Ogre } - ID3D11DeviceN * device; - // But, if creating WARP or software, don't use a selected adapter, it will be selected automatically - - HRESULT hr = D3D11CreateDeviceN(pSelectedAdapter, - driverType, - NULL, - deviceFlags, - requestedLevels + maxRequestedFeatureLevelIndex, - minRequestedFeatureLevelIndex - maxRequestedFeatureLevelIndex + 1, - D3D11_SDK_VERSION, - &device, - &mFeatureLevel, - 0); - - if(FAILED(hr)) - { - StringStream error; + ID3D11DeviceN * device; + // But, if creating WARP or software, don't use a selected adapter, it will be selected automatically + + HRESULT hr = D3D11CreateDeviceN(pSelectedAdapter, + driverType, + NULL, + deviceFlags, + requestedLevels + maxRequestedFeatureLevelIndex, + minRequestedFeatureLevelIndex - maxRequestedFeatureLevelIndex + 1, + D3D11_SDK_VERSION, + &device, + &mFeatureLevel, + 0); + + if(FAILED(hr)) + { + StringStream error; #ifdef USE_DXERR_LIBRARY - error<<"Failed to create Direct3D11 object."<QueryInterface(__uuidof(IDXGIDeviceN), (void **)&pDXGIDevice); - - IDXGIAdapterN * pDXGIAdapter; - pDXGIDevice->GetParent(__uuidof(IDXGIAdapterN), (void **)&pDXGIAdapter); - - if (mDriverType != DT_HARDWARE) - { - // get the IDXGIFactoryN from the device for software drivers - // Remark(dec-09): - // Seems that IDXGIFactoryN::CreateSoftwareAdapter doesn't work with - // D3D11CreateDevice - so I needed to create with pSelectedAdapter = 0. - // If pSelectedAdapter == 0 then you have to get the IDXGIFactory1 from - // the device - else CreateSwapChain fails later. - // Update (Jun 12, 2012) - // If using WARP driver, get factory from created device - SAFE_RELEASE(mpDXGIFactory); + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + error.str(), + "D3D11RenderSystem::D3D11RenderSystem" ); + } + + SAFE_RELEASE(pSelectedAdapter); + + IDXGIDeviceN * pDXGIDevice; + device->QueryInterface(__uuidof(IDXGIDeviceN), (void **)&pDXGIDevice); + + IDXGIAdapterN * pDXGIAdapter; + pDXGIDevice->GetParent(__uuidof(IDXGIAdapterN), (void **)&pDXGIAdapter); + + if (mDriverType != DT_HARDWARE) + { + // get the IDXGIFactoryN from the device for software drivers + // Remark(dec-09): + // Seems that IDXGIFactoryN::CreateSoftwareAdapter doesn't work with + // D3D11CreateDevice - so I needed to create with pSelectedAdapter = 0. + // If pSelectedAdapter == 0 then you have to get the IDXGIFactory1 from + // the device - else CreateSwapChain fails later. + // Update (Jun 12, 2012) + // If using WARP driver, get factory from created device + SAFE_RELEASE(mpDXGIFactory); pDXGIAdapter->GetParent(__uuidof(IDXGIFactoryN), (void **)&mpDXGIFactory); - } - - // We intentionally check for ID3D10Device support instead of ID3D11Device as CheckInterfaceSupport() is not supported for later. - // We hope, that there would be one UMD for both D3D10 and D3D11, or two different but with the same version number, - // or with different but correlated version numbers, so that blacklisting could be done with high confidence level. - LARGE_INTEGER driverVersion; - if(SUCCEEDED(pDXGIAdapter->CheckInterfaceSupport(IID_ID3D10Device /* intentionally D3D10, not D3D11 */, &driverVersion))) - { - mDriverVersion.major = HIWORD(driverVersion.HighPart); - mDriverVersion.minor = LOWORD(driverVersion.HighPart); - mDriverVersion.release = HIWORD(driverVersion.LowPart); - mDriverVersion.build = LOWORD(driverVersion.LowPart); - } - - SAFE_RELEASE(pDXGIAdapter); - SAFE_RELEASE(pDXGIDevice); - - mDevice = D3D11Device(device) ; - } - - if( autoCreateWindow ) - { - bool fullScreen; - opt = mOptions.find( "Full Screen" ); - if( opt == mOptions.end() ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find full screen option!", "D3D11RenderSystem::initialise" ); - fullScreen = opt->second.currentValue == "Yes"; - - D3D11VideoMode* videoMode = NULL; - unsigned int width, height; - String temp; - - opt = mOptions.find( "Video Mode" ); - if( opt == mOptions.end() ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find Video Mode option!", "D3D11RenderSystem::initialise" ); - - // The string we are manipulating looks like this :width x height @ colourDepth - // Pull out the colour depth by getting what comes after the @ and a space - String colourDepth = opt->second.currentValue.substr(opt->second.currentValue.rfind('@')+1); - // Now we know that the width starts a 0, so if we can find the end we can parse that out - String::size_type widthEnd = opt->second.currentValue.find(' '); - // we know that the height starts 3 characters after the width and goes until the next space - String::size_type heightEnd = opt->second.currentValue.find(' ', widthEnd+3); - // Now we can parse out the values - width = StringConverter::parseInt(opt->second.currentValue.substr(0, widthEnd)); - height = StringConverter::parseInt(opt->second.currentValue.substr(widthEnd+3, heightEnd)); - - for( unsigned j=0; j < mActiveD3DDriver->getVideoModeList()->count(); j++ ) - { - temp = mActiveD3DDriver->getVideoModeList()->item(j)->getDescription(); - - // In full screen we only want to allow supported resolutions, so temp and opt->second.currentValue need to - // match exactly, but in windowed mode we can allow for arbitrary window sized, so we only need - // to match the colour values - if(fullScreen && (temp == opt->second.currentValue) || - !fullScreen && (temp.substr(temp.rfind('@')+1) == colourDepth)) - { - videoMode = mActiveD3DDriver->getVideoModeList()->item(j); - break; - } - } - - if( !videoMode ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find requested video mode.", "D3D11RenderSystem::initialise" ); - - // sRGB window option - bool hwGamma = false; - opt = mOptions.find( "sRGB Gamma Conversion" ); - if( opt == mOptions.end() ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find sRGB option!", "D3D11RenderSystem::initialise" ); - hwGamma = opt->second.currentValue == "Yes"; - uint fsaa = 0; - String fsaaHint; - if( (opt = mOptions.find("FSAA")) != mOptions.end() ) - { - StringVector values = StringUtil::split(opt->second.currentValue, " ", 1); - fsaa = StringConverter::parseUnsignedInt(values[0]); - if (values.size() > 1) - fsaaHint = values[1]; - } - - NameValuePairList miscParams; - miscParams["colourDepth"] = StringConverter::toString(videoMode->getColourDepth()); - miscParams["FSAA"] = StringConverter::toString(fsaa); - miscParams["FSAAHint"] = fsaaHint; - miscParams["useNVPerfHUD"] = StringConverter::toString(mUseNVPerfHUD); - miscParams["gamma"] = StringConverter::toString(hwGamma); + } + + // We intentionally check for ID3D10Device support instead of ID3D11Device as CheckInterfaceSupport() is not supported for later. + // We hope, that there would be one UMD for both D3D10 and D3D11, or two different but with the same version number, + // or with different but correlated version numbers, so that blacklisting could be done with high confidence level. + LARGE_INTEGER driverVersion; + if(SUCCEEDED(pDXGIAdapter->CheckInterfaceSupport(IID_ID3D10Device /* intentionally D3D10, not D3D11 */, &driverVersion))) + { + mDriverVersion.major = HIWORD(driverVersion.HighPart); + mDriverVersion.minor = LOWORD(driverVersion.HighPart); + mDriverVersion.release = HIWORD(driverVersion.LowPart); + mDriverVersion.build = LOWORD(driverVersion.LowPart); + } + + SAFE_RELEASE(pDXGIAdapter); + SAFE_RELEASE(pDXGIDevice); + + mDevice = D3D11Device(device) ; + } + + if( autoCreateWindow ) + { + bool fullScreen; + opt = mOptions.find( "Full Screen" ); + if( opt == mOptions.end() ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find full screen option!", "D3D11RenderSystem::initialise" ); + fullScreen = opt->second.currentValue == "Yes"; + + D3D11VideoMode* videoMode = NULL; + unsigned int width, height; + String temp; + + opt = mOptions.find( "Video Mode" ); + if( opt == mOptions.end() ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find Video Mode option!", "D3D11RenderSystem::initialise" ); + + // The string we are manipulating looks like this :width x height @ colourDepth + // Pull out the colour depth by getting what comes after the @ and a space + String colourDepth = opt->second.currentValue.substr(opt->second.currentValue.rfind('@')+1); + // Now we know that the width starts a 0, so if we can find the end we can parse that out + String::size_type widthEnd = opt->second.currentValue.find(' '); + // we know that the height starts 3 characters after the width and goes until the next space + String::size_type heightEnd = opt->second.currentValue.find(' ', widthEnd+3); + // Now we can parse out the values + width = StringConverter::parseInt(opt->second.currentValue.substr(0, widthEnd)); + height = StringConverter::parseInt(opt->second.currentValue.substr(widthEnd+3, heightEnd)); + + for( unsigned j=0; j < mActiveD3DDriver->getVideoModeList()->count(); j++ ) + { + temp = mActiveD3DDriver->getVideoModeList()->item(j)->getDescription(); + + // In full screen we only want to allow supported resolutions, so temp and opt->second.currentValue need to + // match exactly, but in windowed mode we can allow for arbitrary window sized, so we only need + // to match the colour values + if(fullScreen && (temp == opt->second.currentValue) || + !fullScreen && (temp.substr(temp.rfind('@')+1) == colourDepth)) + { + videoMode = mActiveD3DDriver->getVideoModeList()->item(j); + break; + } + } + + if( !videoMode ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find requested video mode.", "D3D11RenderSystem::initialise" ); + + // sRGB window option + bool hwGamma = false; + opt = mOptions.find( "sRGB Gamma Conversion" ); + if( opt == mOptions.end() ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find sRGB option!", "D3D11RenderSystem::initialise" ); + hwGamma = opt->second.currentValue == "Yes"; + uint fsaa = 0; + String fsaaHint; + if( (opt = mOptions.find("FSAA")) != mOptions.end() ) + { + StringVector values = StringUtil::split(opt->second.currentValue, " ", 1); + fsaa = StringConverter::parseUnsignedInt(values[0]); + if (values.size() > 1) + fsaaHint = values[1]; + } + + NameValuePairList miscParams; + miscParams["colourDepth"] = StringConverter::toString(videoMode->getColourDepth()); + miscParams["FSAA"] = StringConverter::toString(fsaa); + miscParams["FSAAHint"] = fsaaHint; + miscParams["useNVPerfHUD"] = StringConverter::toString(mUseNVPerfHUD); + miscParams["gamma"] = StringConverter::toString(hwGamma); opt = mOptions.find("VSync"); if (opt == mOptions.end()) @@ -904,8 +904,8 @@ namespace Ogre OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync Interval options!", "D3D11RenderSystem::initialise"); miscParams["vsyncInterval"] = opt->second.currentValue; - autoWindow = this->_createRenderWindow( windowTitle, width, height, - fullScreen, &miscParams ); + autoWindow = this->_createRenderWindow( windowTitle, width, height, + fullScreen, &miscParams ); // If we have 16bit depth buffer enable w-buffering. assert( autoWindow ); @@ -916,329 +916,329 @@ namespace Ogre else { mWBuffer = false; - } - } - - LogManager::getSingleton().logMessage("***************************************"); - LogManager::getSingleton().logMessage("*** D3D11 : Subsystem Initialized OK ***"); - LogManager::getSingleton().logMessage("***************************************"); - - // call superclass method - RenderSystem::_initialise( autoCreateWindow ); - - - return autoWindow; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::reinitialise() - { - LogManager::getSingleton().logMessage( "D3D11 : Reinitializing" ); - this->shutdown(); - // this->initialise( true ); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::shutdown() - { - RenderSystem::shutdown(); - - mRenderSystemWasInited = false; - - mPrimaryWindow = NULL; // primary window deleted by base class. - freeDevice(); - SAFE_DELETE( mDriverList ); - SAFE_RELEASE( mpDXGIFactory ); - mActiveD3DDriver = NULL; - mDevice = NULL; - mBasicStatesInitialised = false; - LogManager::getSingleton().logMessage("D3D11 : Shutting down cleanly."); - SAFE_DELETE( mTextureManager ); - SAFE_DELETE( mHardwareBufferManager ); - SAFE_DELETE( mGpuProgramManager ); - - } - //--------------------------------------------------------------------- - RenderWindow* D3D11RenderSystem::_createRenderWindow(const String &name, - unsigned int width, unsigned int height, bool fullScreen, - const NameValuePairList *miscParams) - { - - // Check we're not creating a secondary window when the primary - // was fullscreen - if (mPrimaryWindow && mPrimaryWindow->isFullScreen()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Cannot create secondary windows when the primary is full screen", - "D3D11RenderSystem::_createRenderWindow"); - } - if (mPrimaryWindow && fullScreen) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Cannot create full screen secondary windows", - "D3D11RenderSystem::_createRenderWindow"); - } - - // Log a message - StringStream ss; - ss << "D3D11RenderSystem::_createRenderWindow \"" << name << "\", " << - width << "x" << height << " "; - if(fullScreen) - ss << "fullscreen "; - else - ss << "windowed "; - if(miscParams) - { - ss << " miscParams: "; - NameValuePairList::const_iterator it; - for(it=miscParams->begin(); it!=miscParams->end(); ++it) - { - ss << it->first << "=" << it->second << " "; - } - LogManager::getSingleton().logMessage(ss.str()); - } - - String msg; - - // Make sure we don't already have a render target of the - // sam name as the one supplied - if( mRenderTargets.find( name ) != mRenderTargets.end() ) - { - msg = "A render target of the same name '" + name + "' already " - "exists. You cannot create a new window with this name."; - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, msg, "D3D11RenderSystem::_createRenderWindow" ); - } + } + } + + LogManager::getSingleton().logMessage("***************************************"); + LogManager::getSingleton().logMessage("*** D3D11 : Subsystem Initialized OK ***"); + LogManager::getSingleton().logMessage("***************************************"); + + // call superclass method + RenderSystem::_initialise( autoCreateWindow ); + + + return autoWindow; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::reinitialise() + { + LogManager::getSingleton().logMessage( "D3D11 : Reinitializing" ); + this->shutdown(); + // this->initialise( true ); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::shutdown() + { + RenderSystem::shutdown(); + + mRenderSystemWasInited = false; + + mPrimaryWindow = NULL; // primary window deleted by base class. + freeDevice(); + SAFE_DELETE( mDriverList ); + SAFE_RELEASE( mpDXGIFactory ); + mActiveD3DDriver = NULL; + mDevice = NULL; + mBasicStatesInitialised = false; + LogManager::getSingleton().logMessage("D3D11 : Shutting down cleanly."); + SAFE_DELETE( mTextureManager ); + SAFE_DELETE( mHardwareBufferManager ); + SAFE_DELETE( mGpuProgramManager ); + + } + //--------------------------------------------------------------------- + RenderWindow* D3D11RenderSystem::_createRenderWindow(const String &name, + unsigned int width, unsigned int height, bool fullScreen, + const NameValuePairList *miscParams) + { + + // Check we're not creating a secondary window when the primary + // was fullscreen + if (mPrimaryWindow && mPrimaryWindow->isFullScreen()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Cannot create secondary windows when the primary is full screen", + "D3D11RenderSystem::_createRenderWindow"); + } + if (mPrimaryWindow && fullScreen) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Cannot create full screen secondary windows", + "D3D11RenderSystem::_createRenderWindow"); + } + + // Log a message + StringStream ss; + ss << "D3D11RenderSystem::_createRenderWindow \"" << name << "\", " << + width << "x" << height << " "; + if(fullScreen) + ss << "fullscreen "; + else + ss << "windowed "; + if(miscParams) + { + ss << " miscParams: "; + NameValuePairList::const_iterator it; + for(it=miscParams->begin(); it!=miscParams->end(); ++it) + { + ss << it->first << "=" << it->second << " "; + } + LogManager::getSingleton().logMessage(ss.str()); + } + + String msg; + + // Make sure we don't already have a render target of the + // sam name as the one supplied + if( mRenderTargets.find( name ) != mRenderTargets.end() ) + { + msg = "A render target of the same name '" + name + "' already " + "exists. You cannot create a new window with this name."; + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, msg, "D3D11RenderSystem::_createRenderWindow" ); + } #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - D3D11RenderWindowBase* win = new D3D11RenderWindowHwnd(mDevice, mpDXGIFactory); + D3D11RenderWindowBase* win = new D3D11RenderWindowHwnd(mDevice, mpDXGIFactory); #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - String windowType; - if(miscParams) - { - // Get variable-length params - NameValuePairList::const_iterator opt = miscParams->find("windowType"); - if(opt != miscParams->end()) - windowType = opt->second; - } - - D3D11RenderWindowBase* win = NULL; + String windowType; + if(miscParams) + { + // Get variable-length params + NameValuePairList::const_iterator opt = miscParams->find("windowType"); + if(opt != miscParams->end()) + windowType = opt->second; + } + + D3D11RenderWindowBase* win = NULL; #if (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == DESKTOP_APP) - if(win == NULL && windowType == "SurfaceImageSource") - win = new D3D11RenderWindowImageSource(mDevice, mpDXGIFactory); + if(win == NULL && windowType == "SurfaceImageSource") + win = new D3D11RenderWindowImageSource(mDevice, mpDXGIFactory); #endif // (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == DESKTOP_APP) - if(win == NULL) - win = new D3D11RenderWindowCoreWindow(mDevice, mpDXGIFactory); + if(win == NULL) + win = new D3D11RenderWindowCoreWindow(mDevice, mpDXGIFactory); #endif - win->create( name, width, height, fullScreen, miscParams); - - attachRenderTarget( *win ); - - // If this is the first window, get the D3D device and create the texture manager - if( !mPrimaryWindow ) - { - mPrimaryWindow = win; - win->getCustomAttribute( "D3DDEVICE", &mDevice ); - - // Create the texture manager for use by others - mTextureManager = new D3D11TextureManager( mDevice ); + win->create( name, width, height, fullScreen, miscParams); + + attachRenderTarget( *win ); + + // If this is the first window, get the D3D device and create the texture manager + if( !mPrimaryWindow ) + { + mPrimaryWindow = win; + win->getCustomAttribute( "D3DDEVICE", &mDevice ); + + // Create the texture manager for use by others + mTextureManager = new D3D11TextureManager( mDevice ); // Also create hardware buffer manager mHardwareBufferManager = new D3D11HardwareBufferManager(mDevice); - // Create the GPU program manager - mGpuProgramManager = new D3D11GpuProgramManager(mDevice); + // Create the GPU program manager + mGpuProgramManager = new D3D11GpuProgramManager(mDevice); // create & register HLSL factory - if (mHLSLProgramFactory == NULL) - mHLSLProgramFactory = new D3D11HLSLProgramFactory(mDevice); - mRealCapabilities = createRenderSystemCapabilities(); - mRealCapabilities->addShaderProfile("hlsl"); - - // if we are using custom capabilities, then - // mCurrentCapabilities has already been loaded - if(!mUseCustomCapabilities) - mCurrentCapabilities = mRealCapabilities; - - fireEvent("RenderSystemCapabilitiesCreated"); - - initialiseFromRenderSystemCapabilities(mCurrentCapabilities, mPrimaryWindow); - - } - else - { - mSecondaryWindows.push_back(win); - } - - return win; - - } - //--------------------------------------------------------------------- - RenderSystemCapabilities* D3D11RenderSystem::createRenderSystemCapabilities() const - { - RenderSystemCapabilities* rsc = new RenderSystemCapabilities(); - rsc->setDriverVersion(mDriverVersion); - rsc->setDeviceName(mActiveD3DDriver->DriverDescription()); - rsc->setRenderSystemName(getName()); - - // Does NOT support fixed-function! - //rsc->setCapability(RSC_FIXED_FUNCTION); - - rsc->setCapability(RSC_HWSTENCIL); - rsc->setStencilBufferBitDepth(8); - - rsc->setCapability(RSC_VBO); - UINT formatSupport; - if(mFeatureLevel >= D3D_FEATURE_LEVEL_9_2 - || SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_R32_UINT, &formatSupport)) && 0 != (formatSupport & D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER)) - rsc->setCapability(RSC_32BIT_INDEX); - - // Set number of texture units, always 16 - rsc->setNumTextureUnits(16); - rsc->setCapability(RSC_ANISOTROPY); - rsc->setCapability(RSC_AUTOMIPMAP); - rsc->setCapability(RSC_BLENDING); - rsc->setCapability(RSC_DOT3); - // Cube map - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { - rsc->setCapability(RSC_CUBEMAPPING); - rsc->setCapability(RSC_READ_BACK_AS_TEXTURE); - } - - // We always support compression, D3DX will decompress if device does not support - rsc->setCapability(RSC_TEXTURE_COMPRESSION); - rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT); - rsc->setCapability(RSC_SCISSOR_TEST); - rsc->setCapability(RSC_TWO_SIDED_STENCIL); - rsc->setCapability(RSC_STENCIL_WRAP); - rsc->setCapability(RSC_HWOCCLUSION); - rsc->setCapability(RSC_HWOCCLUSION_ASYNCHRONOUS); - - convertVertexShaderCaps(rsc); - convertPixelShaderCaps(rsc); - convertGeometryShaderCaps(rsc); - convertHullShaderCaps(rsc); - convertDomainShaderCaps(rsc); - convertComputeShaderCaps(rsc); - - // Check support for dynamic linkage - if (mFeatureLevel >= D3D_FEATURE_LEVEL_11_0) - { - rsc->setCapability(RSC_SHADER_SUBROUTINE); - } - - rsc->setCapability(RSC_USER_CLIP_PLANES); - rsc->setCapability(RSC_VERTEX_FORMAT_UBYTE4); - - rsc->setCapability(RSC_RTT_SEPARATE_DEPTHBUFFER); - rsc->setCapability(RSC_RTT_MAIN_DEPTHBUFFER_ATTACHABLE); - - - // Adapter details - const DXGI_ADAPTER_DESC1& adapterID = mActiveD3DDriver->getAdapterIdentifier(); - - switch(mDriverType) { - case DT_HARDWARE: - // determine vendor - // Full list of vendors here: http://www.pcidatabase.com/vendors.php?sort=id - switch(adapterID.VendorId) - { - case 0x10DE: - rsc->setVendor(GPU_NVIDIA); - break; - case 0x1002: - rsc->setVendor(GPU_AMD); - break; - case 0x163C: - case 0x8086: - rsc->setVendor(GPU_INTEL); - break; - case 0x5333: - rsc->setVendor(GPU_S3); - break; - case 0x3D3D: - rsc->setVendor(GPU_3DLABS); - break; - case 0x102B: - rsc->setVendor(GPU_MATROX); - break; - default: - rsc->setVendor(GPU_UNKNOWN); - break; - }; - break; - case DT_SOFTWARE: - rsc->setVendor(GPU_MS_SOFTWARE); - break; - case DT_WARP: - rsc->setVendor(GPU_MS_WARP); - break; - default: - rsc->setVendor(GPU_UNKNOWN); - break; - } - - rsc->setCapability(RSC_INFINITE_FAR_PLANE); - - rsc->setCapability(RSC_TEXTURE_3D); - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { - rsc->setCapability(RSC_NON_POWER_OF_2_TEXTURES); - rsc->setCapability(RSC_HWRENDER_TO_TEXTURE_3D); - rsc->setCapability(RSC_TEXTURE_1D); - rsc->setCapability(RSC_TEXTURE_COMPRESSION_BC6H_BC7); - rsc->setCapability(RSC_COMPLETE_TEXTURE_BINDING); - } - - rsc->setCapability(RSC_HWRENDER_TO_TEXTURE); - rsc->setCapability(RSC_TEXTURE_FLOAT); + if (mHLSLProgramFactory == NULL) + mHLSLProgramFactory = new D3D11HLSLProgramFactory(mDevice); + mRealCapabilities = createRenderSystemCapabilities(); + mRealCapabilities->addShaderProfile("hlsl"); + + // if we are using custom capabilities, then + // mCurrentCapabilities has already been loaded + if(!mUseCustomCapabilities) + mCurrentCapabilities = mRealCapabilities; + + fireEvent("RenderSystemCapabilitiesCreated"); + + initialiseFromRenderSystemCapabilities(mCurrentCapabilities, mPrimaryWindow); + + } + else + { + mSecondaryWindows.push_back(win); + } + + return win; + + } + //--------------------------------------------------------------------- + RenderSystemCapabilities* D3D11RenderSystem::createRenderSystemCapabilities() const + { + RenderSystemCapabilities* rsc = new RenderSystemCapabilities(); + rsc->setDriverVersion(mDriverVersion); + rsc->setDeviceName(mActiveD3DDriver->DriverDescription()); + rsc->setRenderSystemName(getName()); + + // Does NOT support fixed-function! + //rsc->setCapability(RSC_FIXED_FUNCTION); + + rsc->setCapability(RSC_HWSTENCIL); + rsc->setStencilBufferBitDepth(8); + + rsc->setCapability(RSC_VBO); + UINT formatSupport; + if(mFeatureLevel >= D3D_FEATURE_LEVEL_9_2 + || SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_R32_UINT, &formatSupport)) && 0 != (formatSupport & D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER)) + rsc->setCapability(RSC_32BIT_INDEX); + + // Set number of texture units, always 16 + rsc->setNumTextureUnits(16); + rsc->setCapability(RSC_ANISOTROPY); + rsc->setCapability(RSC_AUTOMIPMAP); + rsc->setCapability(RSC_BLENDING); + rsc->setCapability(RSC_DOT3); + // Cube map + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { + rsc->setCapability(RSC_CUBEMAPPING); + rsc->setCapability(RSC_READ_BACK_AS_TEXTURE); + } + + // We always support compression, D3DX will decompress if device does not support + rsc->setCapability(RSC_TEXTURE_COMPRESSION); + rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT); + rsc->setCapability(RSC_SCISSOR_TEST); + rsc->setCapability(RSC_TWO_SIDED_STENCIL); + rsc->setCapability(RSC_STENCIL_WRAP); + rsc->setCapability(RSC_HWOCCLUSION); + rsc->setCapability(RSC_HWOCCLUSION_ASYNCHRONOUS); + + convertVertexShaderCaps(rsc); + convertPixelShaderCaps(rsc); + convertGeometryShaderCaps(rsc); + convertHullShaderCaps(rsc); + convertDomainShaderCaps(rsc); + convertComputeShaderCaps(rsc); + + // Check support for dynamic linkage + if (mFeatureLevel >= D3D_FEATURE_LEVEL_11_0) + { + rsc->setCapability(RSC_SHADER_SUBROUTINE); + } + + rsc->setCapability(RSC_USER_CLIP_PLANES); + rsc->setCapability(RSC_VERTEX_FORMAT_UBYTE4); + + rsc->setCapability(RSC_RTT_SEPARATE_DEPTHBUFFER); + rsc->setCapability(RSC_RTT_MAIN_DEPTHBUFFER_ATTACHABLE); + + + // Adapter details + const DXGI_ADAPTER_DESC1& adapterID = mActiveD3DDriver->getAdapterIdentifier(); + + switch(mDriverType) { + case DT_HARDWARE: + // determine vendor + // Full list of vendors here: http://www.pcidatabase.com/vendors.php?sort=id + switch(adapterID.VendorId) + { + case 0x10DE: + rsc->setVendor(GPU_NVIDIA); + break; + case 0x1002: + rsc->setVendor(GPU_AMD); + break; + case 0x163C: + case 0x8086: + rsc->setVendor(GPU_INTEL); + break; + case 0x5333: + rsc->setVendor(GPU_S3); + break; + case 0x3D3D: + rsc->setVendor(GPU_3DLABS); + break; + case 0x102B: + rsc->setVendor(GPU_MATROX); + break; + default: + rsc->setVendor(GPU_UNKNOWN); + break; + }; + break; + case DT_SOFTWARE: + rsc->setVendor(GPU_MS_SOFTWARE); + break; + case DT_WARP: + rsc->setVendor(GPU_MS_WARP); + break; + default: + rsc->setVendor(GPU_UNKNOWN); + break; + } + + rsc->setCapability(RSC_INFINITE_FAR_PLANE); + + rsc->setCapability(RSC_TEXTURE_3D); + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { + rsc->setCapability(RSC_NON_POWER_OF_2_TEXTURES); + rsc->setCapability(RSC_HWRENDER_TO_TEXTURE_3D); + rsc->setCapability(RSC_TEXTURE_1D); + rsc->setCapability(RSC_TEXTURE_COMPRESSION_BC6H_BC7); + rsc->setCapability(RSC_COMPLETE_TEXTURE_BINDING); + } + + rsc->setCapability(RSC_HWRENDER_TO_TEXTURE); + rsc->setCapability(RSC_TEXTURE_FLOAT); #ifdef D3D_FEATURE_LEVEL_9_3 - int numMultiRenderTargets = (mFeatureLevel > D3D_FEATURE_LEVEL_9_3) ? D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT : // 8 - (mFeatureLevel == D3D_FEATURE_LEVEL_9_3) ? 4/*D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT*/ : // 4 - 1/*D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT*/; // 1 + int numMultiRenderTargets = (mFeatureLevel > D3D_FEATURE_LEVEL_9_3) ? D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT : // 8 + (mFeatureLevel == D3D_FEATURE_LEVEL_9_3) ? 4/*D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT*/ : // 4 + 1/*D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT*/; // 1 #else - int numMultiRenderTargets = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8 + int numMultiRenderTargets = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8 #endif - rsc->setNumMultiRenderTargets(std::min(numMultiRenderTargets, (int)OGRE_MAX_MULTIPLE_RENDER_TARGETS)); - rsc->setCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS); - - rsc->setCapability(RSC_POINT_SPRITES); - rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS); - rsc->setMaxPointSize(256); // TODO: guess! - - rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH); - rsc->setNumVertexTextureUnits(4); - rsc->setVertexTextureUnitsShared(false); - - rsc->setCapability(RSC_MIPMAP_LOD_BIAS); - - // actually irrelevant, but set - rsc->setCapability(RSC_PERSTAGECONSTANT); - - rsc->setCapability(RSC_VERTEX_BUFFER_INSTANCE_DATA); - rsc->setCapability(RSC_CAN_GET_COMPILED_SHADER_BUFFER); - - return rsc; - - } - //----------------------------------------------------------------------- - void D3D11RenderSystem::initialiseFromRenderSystemCapabilities( - RenderSystemCapabilities* caps, RenderTarget* primary) - { - if(caps->getRenderSystemName() != getName()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Trying to initialize D3D11RenderSystem from RenderSystemCapabilities that do not support Direct3D11", - "D3D11RenderSystem::initialiseFromRenderSystemCapabilities"); - } - - // add hlsl - HighLevelGpuProgramManager::getSingleton().addFactory(mHLSLProgramFactory); - - Log* defaultLog = LogManager::getSingleton().getDefaultLog(); - if (defaultLog) - { - caps->log(defaultLog); - } - } + rsc->setNumMultiRenderTargets(std::min(numMultiRenderTargets, (int)OGRE_MAX_MULTIPLE_RENDER_TARGETS)); + rsc->setCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS); + + rsc->setCapability(RSC_POINT_SPRITES); + rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS); + rsc->setMaxPointSize(256); // TODO: guess! + + rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH); + rsc->setNumVertexTextureUnits(4); + rsc->setVertexTextureUnitsShared(false); + + rsc->setCapability(RSC_MIPMAP_LOD_BIAS); + + // actually irrelevant, but set + rsc->setCapability(RSC_PERSTAGECONSTANT); + + rsc->setCapability(RSC_VERTEX_BUFFER_INSTANCE_DATA); + rsc->setCapability(RSC_CAN_GET_COMPILED_SHADER_BUFFER); + + return rsc; + + } + //----------------------------------------------------------------------- + void D3D11RenderSystem::initialiseFromRenderSystemCapabilities( + RenderSystemCapabilities* caps, RenderTarget* primary) + { + if(caps->getRenderSystemName() != getName()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Trying to initialize D3D11RenderSystem from RenderSystemCapabilities that do not support Direct3D11", + "D3D11RenderSystem::initialiseFromRenderSystemCapabilities"); + } + + // add hlsl + HighLevelGpuProgramManager::getSingleton().addFactory(mHLSLProgramFactory); + + Log* defaultLog = LogManager::getSingleton().getDefaultLog(); + if (defaultLog) + { + caps->log(defaultLog); + } + } //--------------------------------------------------------------------- void D3D11RenderSystem::convertVertexShaderCaps(RenderSystemCapabilities* rsc) const { @@ -1252,21 +1252,21 @@ namespace Ogre } if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) { - rsc->addShaderProfile("vs_4_0"); + rsc->addShaderProfile("vs_4_0"); + } + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_1) + { + rsc->addShaderProfile("vs_4_1"); + } + if (mFeatureLevel >= D3D_FEATURE_LEVEL_11_0) + { + rsc->addShaderProfile("vs_5_0"); } - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_1) - { - rsc->addShaderProfile("vs_4_1"); - } - if (mFeatureLevel >= D3D_FEATURE_LEVEL_11_0) - { - rsc->addShaderProfile("vs_5_0"); - } - rsc->setCapability(RSC_VERTEX_PROGRAM); + rsc->setCapability(RSC_VERTEX_PROGRAM); - // TODO: constant buffers have no limits but lower models do - // 16 boolean params allowed + // TODO: constant buffers have no limits but lower models do + // 16 boolean params allowed rsc->setVertexProgramConstantBoolCount(16); // 16 integer params allowed, 4D rsc->setVertexProgramConstantIntCount(16); @@ -1299,60 +1299,60 @@ namespace Ogre } - rsc->setCapability(RSC_FRAGMENT_PROGRAM); + rsc->setCapability(RSC_FRAGMENT_PROGRAM); - // TODO: constant buffers have no limits but lower models do - // 16 boolean params allowed - rsc->setFragmentProgramConstantBoolCount(16); - // 16 integer params allowed, 4D - rsc->setFragmentProgramConstantIntCount(16); - // float params, always 4D - rsc->setFragmentProgramConstantFloatCount(512); + // TODO: constant buffers have no limits but lower models do + // 16 boolean params allowed + rsc->setFragmentProgramConstantBoolCount(16); + // 16 integer params allowed, 4D + rsc->setFragmentProgramConstantIntCount(16); + // float params, always 4D + rsc->setFragmentProgramConstantFloatCount(512); } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void D3D11RenderSystem::convertHullShaderCaps(RenderSystemCapabilities* rsc) const { - // Only for shader model 5.0 - if (mFeatureLevel >= D3D_FEATURE_LEVEL_11_0) - { - rsc->addShaderProfile("hs_5_0"); - - rsc->setCapability(RSC_TESSELLATION_HULL_PROGRAM); - - // TODO: constant buffers have no limits but lower models do - // 16 boolean params allowed - rsc->setTessellationHullProgramConstantBoolCount(16); - // 16 integer params allowed, 4D - rsc->setTessellationHullProgramConstantIntCount(16); - // float params, always 4D - rsc->setTessellationHullProgramConstantFloatCount(512); - } + // Only for shader model 5.0 + if (mFeatureLevel >= D3D_FEATURE_LEVEL_11_0) + { + rsc->addShaderProfile("hs_5_0"); + + rsc->setCapability(RSC_TESSELLATION_HULL_PROGRAM); + + // TODO: constant buffers have no limits but lower models do + // 16 boolean params allowed + rsc->setTessellationHullProgramConstantBoolCount(16); + // 16 integer params allowed, 4D + rsc->setTessellationHullProgramConstantIntCount(16); + // float params, always 4D + rsc->setTessellationHullProgramConstantFloatCount(512); + } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void D3D11RenderSystem::convertDomainShaderCaps(RenderSystemCapabilities* rsc) const { - // Only for shader model 5.0 - if (mFeatureLevel >= D3D_FEATURE_LEVEL_11_0) - { - rsc->addShaderProfile("ds_5_0"); + // Only for shader model 5.0 + if (mFeatureLevel >= D3D_FEATURE_LEVEL_11_0) + { + rsc->addShaderProfile("ds_5_0"); - rsc->setCapability(RSC_TESSELLATION_DOMAIN_PROGRAM); + rsc->setCapability(RSC_TESSELLATION_DOMAIN_PROGRAM); - // TODO: constant buffers have no limits but lower models do - // 16 boolean params allowed - rsc->setTessellationDomainProgramConstantBoolCount(16); - // 16 integer params allowed, 4D - rsc->setTessellationDomainProgramConstantIntCount(16); - // float params, always 4D - rsc->setTessellationDomainProgramConstantFloatCount(512); - } + // TODO: constant buffers have no limits but lower models do + // 16 boolean params allowed + rsc->setTessellationDomainProgramConstantBoolCount(16); + // 16 integer params allowed, 4D + rsc->setTessellationDomainProgramConstantIntCount(16); + // float params, always 4D + rsc->setTessellationDomainProgramConstantFloatCount(512); + } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void D3D11RenderSystem::convertComputeShaderCaps(RenderSystemCapabilities* rsc) const { @@ -1372,18 +1372,18 @@ namespace Ogre - // TODO: constant buffers have no limits but lower models do - // 16 boolean params allowed - rsc->setComputeProgramConstantBoolCount(16); - // 16 integer params allowed, 4D - rsc->setComputeProgramConstantIntCount(16); - // float params, always 4D - rsc->setComputeProgramConstantFloatCount(512); + // TODO: constant buffers have no limits but lower models do + // 16 boolean params allowed + rsc->setComputeProgramConstantBoolCount(16); + // 16 integer params allowed, 4D + rsc->setComputeProgramConstantIntCount(16); + // float params, always 4D + rsc->setComputeProgramConstantFloatCount(512); } - //--------------------------------------------------------------------- - void D3D11RenderSystem::convertGeometryShaderCaps(RenderSystemCapabilities* rsc) const - { + //--------------------------------------------------------------------- + void D3D11RenderSystem::convertGeometryShaderCaps(RenderSystemCapabilities* rsc) const + { if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) { rsc->addShaderProfile("gs_4_0"); @@ -1399,135 +1399,135 @@ namespace Ogre rsc->addShaderProfile("gs_5_0"); } - rsc->setGeometryProgramConstantFloatCount(512); - rsc->setGeometryProgramConstantIntCount(16); - rsc->setGeometryProgramConstantBoolCount(16); - rsc->setGeometryProgramNumOutputVertices(1024); - } - //----------------------------------------------------------------------- - bool D3D11RenderSystem::checkVertexTextureFormats(void) - { - return true; - } - //----------------------------------------------------------------------- + rsc->setGeometryProgramConstantFloatCount(512); + rsc->setGeometryProgramConstantIntCount(16); + rsc->setGeometryProgramConstantBoolCount(16); + rsc->setGeometryProgramNumOutputVertices(1024); + } + //----------------------------------------------------------------------- + bool D3D11RenderSystem::checkVertexTextureFormats(void) + { + return true; + } + //----------------------------------------------------------------------- bool D3D11RenderSystem::_checkTextureFilteringSupported(TextureType ttype, PixelFormat format, int usage) { - return true; - } - //----------------------------------------------------------------------- - MultiRenderTarget * D3D11RenderSystem::createMultiRenderTarget(const String & name) - { - MultiRenderTarget *retval; - retval = new D3D11MultiRenderTarget(name); - attachRenderTarget(*retval); - - return retval; - } - //----------------------------------------------------------------------- - DepthBuffer* D3D11RenderSystem::_createDepthBufferFor( RenderTarget *renderTarget ) - { - //Get surface data (mainly to get MSAA data) - D3D11HardwarePixelBuffer *pBuffer; - renderTarget->getCustomAttribute( "BUFFER", &pBuffer ); - D3D11_TEXTURE2D_DESC BBDesc; - static_cast(pBuffer->getParentTexture()->getTextureResource())->GetDesc( &BBDesc ); - - // Create depth stencil texture - ID3D11Texture2D* pDepthStencil = NULL; - D3D11_TEXTURE2D_DESC descDepth; - - descDepth.Width = renderTarget->getWidth(); - descDepth.Height = renderTarget->getHeight(); - descDepth.MipLevels = 1; - descDepth.ArraySize = BBDesc.ArraySize; - - if ( mFeatureLevel < D3D_FEATURE_LEVEL_10_0) - descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - else - descDepth.Format = DXGI_FORMAT_R32_TYPELESS; - - descDepth.SampleDesc.Count = BBDesc.SampleDesc.Count; - descDepth.SampleDesc.Quality = BBDesc.SampleDesc.Quality; - descDepth.Usage = D3D11_USAGE_DEFAULT; - descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; - - // If we tell we want to use it as a Shader Resource when in MSAA, we will fail - // This is a recomandation from NVidia. - if(!mReadBackAsTexture && mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && BBDesc.SampleDesc.Count == 1) - descDepth.BindFlags |= D3D11_BIND_SHADER_RESOURCE; - - descDepth.CPUAccessFlags = 0; - descDepth.MiscFlags = 0; - - if (descDepth.ArraySize == 6) - { - descDepth.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; - } - - - HRESULT hr = mDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil ); - if( FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create depth texture\nError Description:" + errorDescription, - "D3D11RenderSystem::_createDepthBufferFor"); - } - - // - // Create the View of the texture - // If MSAA is used, we cannot do this - // - if(!mReadBackAsTexture && mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && BBDesc.SampleDesc.Count == 1) - { - D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; - viewDesc.Format = DXGI_FORMAT_R32_FLOAT; - viewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; - viewDesc.Texture2D.MostDetailedMip = 0; - viewDesc.Texture2D.MipLevels = 1; - SAFE_RELEASE(mDSTResView); - HRESULT hr = mDevice->CreateShaderResourceView( pDepthStencil, &viewDesc, &mDSTResView); - if( FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create the view of the depth texture \nError Description:" + errorDescription, - "D3D11RenderSystem::_createDepthBufferFor"); - } - } - - // Create the depth stencil view - ID3D11DepthStencilView *depthStencilView; - D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; - ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) ); - - if (mFeatureLevel < D3D_FEATURE_LEVEL_10_0) - descDSV.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - else - descDSV.Format = DXGI_FORMAT_D32_FLOAT; - - descDSV.ViewDimension = (BBDesc.SampleDesc.Count > 1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; - descDSV.Flags = 0 /* D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL */; // TODO: Allows bind depth buffer as depth view AND texture simultaneously. - // TODO: Decide how to expose this feature - descDSV.Texture2D.MipSlice = 0; - hr = mDevice->CreateDepthStencilView( pDepthStencil, &descDSV, &depthStencilView ); - SAFE_RELEASE( pDepthStencil ); - if( FAILED(hr) ) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create depth stencil view\nError Description:" + errorDescription, - "D3D11RenderSystem::_createDepthBufferFor"); - } - - //Create the abstract container - D3D11DepthBuffer *newDepthBuffer = new D3D11DepthBuffer( DepthBuffer::POOL_DEFAULT, this, depthStencilView, - descDepth.Width, descDepth.Height, - descDepth.SampleDesc.Count, descDepth.SampleDesc.Quality, - false ); - - return newDepthBuffer; - } + return true; + } + //----------------------------------------------------------------------- + MultiRenderTarget * D3D11RenderSystem::createMultiRenderTarget(const String & name) + { + MultiRenderTarget *retval; + retval = new D3D11MultiRenderTarget(name); + attachRenderTarget(*retval); + + return retval; + } + //----------------------------------------------------------------------- + DepthBuffer* D3D11RenderSystem::_createDepthBufferFor( RenderTarget *renderTarget ) + { + //Get surface data (mainly to get MSAA data) + D3D11HardwarePixelBuffer *pBuffer; + renderTarget->getCustomAttribute( "BUFFER", &pBuffer ); + D3D11_TEXTURE2D_DESC BBDesc; + static_cast(pBuffer->getParentTexture()->getTextureResource())->GetDesc( &BBDesc ); + + // Create depth stencil texture + ID3D11Texture2D* pDepthStencil = NULL; + D3D11_TEXTURE2D_DESC descDepth; + + descDepth.Width = renderTarget->getWidth(); + descDepth.Height = renderTarget->getHeight(); + descDepth.MipLevels = 1; + descDepth.ArraySize = BBDesc.ArraySize; + + if ( mFeatureLevel < D3D_FEATURE_LEVEL_10_0) + descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + else + descDepth.Format = DXGI_FORMAT_R32_TYPELESS; + + descDepth.SampleDesc.Count = BBDesc.SampleDesc.Count; + descDepth.SampleDesc.Quality = BBDesc.SampleDesc.Quality; + descDepth.Usage = D3D11_USAGE_DEFAULT; + descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; + + // If we tell we want to use it as a Shader Resource when in MSAA, we will fail + // This is a recomandation from NVidia. + if(!mReadBackAsTexture && mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && BBDesc.SampleDesc.Count == 1) + descDepth.BindFlags |= D3D11_BIND_SHADER_RESOURCE; + + descDepth.CPUAccessFlags = 0; + descDepth.MiscFlags = 0; + + if (descDepth.ArraySize == 6) + { + descDepth.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; + } + + + HRESULT hr = mDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil ); + if( FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create depth texture\nError Description:" + errorDescription, + "D3D11RenderSystem::_createDepthBufferFor"); + } + + // + // Create the View of the texture + // If MSAA is used, we cannot do this + // + if(!mReadBackAsTexture && mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && BBDesc.SampleDesc.Count == 1) + { + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + viewDesc.Format = DXGI_FORMAT_R32_FLOAT; + viewDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; + viewDesc.Texture2D.MostDetailedMip = 0; + viewDesc.Texture2D.MipLevels = 1; + SAFE_RELEASE(mDSTResView); + HRESULT hr = mDevice->CreateShaderResourceView( pDepthStencil, &viewDesc, &mDSTResView); + if( FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create the view of the depth texture \nError Description:" + errorDescription, + "D3D11RenderSystem::_createDepthBufferFor"); + } + } + + // Create the depth stencil view + ID3D11DepthStencilView *depthStencilView; + D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; + ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) ); + + if (mFeatureLevel < D3D_FEATURE_LEVEL_10_0) + descDSV.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + else + descDSV.Format = DXGI_FORMAT_D32_FLOAT; + + descDSV.ViewDimension = (BBDesc.SampleDesc.Count > 1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; + descDSV.Flags = 0 /* D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL */; // TODO: Allows bind depth buffer as depth view AND texture simultaneously. + // TODO: Decide how to expose this feature + descDSV.Texture2D.MipSlice = 0; + hr = mDevice->CreateDepthStencilView( pDepthStencil, &descDSV, &depthStencilView ); + SAFE_RELEASE( pDepthStencil ); + if( FAILED(hr) ) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create depth stencil view\nError Description:" + errorDescription, + "D3D11RenderSystem::_createDepthBufferFor"); + } + + //Create the abstract container + D3D11DepthBuffer *newDepthBuffer = new D3D11DepthBuffer( DepthBuffer::POOL_DEFAULT, this, depthStencilView, + descDepth.Width, descDepth.Height, + descDepth.SampleDesc.Count, descDepth.SampleDesc.Quality, + false ); + + return newDepthBuffer; + } //--------------------------------------------------------------------- void D3D11RenderSystem::_removeManualDepthBuffer(DepthBuffer *depthBuffer) { @@ -1537,33 +1537,33 @@ namespace Ogre pool.erase(std::remove(pool.begin(), pool.end(), depthBuffer), pool.end()); } } - //--------------------------------------------------------------------- - DepthBuffer* D3D11RenderSystem::_addManualDepthBuffer( ID3D11DepthStencilView *depthSurface, - uint32 width, uint32 height, - uint32 fsaa, uint32 fsaaQuality ) - { - //If this depth buffer was already added, return that one - DepthBufferVec::const_iterator itor = mDepthBufferPool[DepthBuffer::POOL_DEFAULT].begin(); - DepthBufferVec::const_iterator end = mDepthBufferPool[DepthBuffer::POOL_DEFAULT].end(); + //--------------------------------------------------------------------- + DepthBuffer* D3D11RenderSystem::_addManualDepthBuffer( ID3D11DepthStencilView *depthSurface, + uint32 width, uint32 height, + uint32 fsaa, uint32 fsaaQuality ) + { + //If this depth buffer was already added, return that one + DepthBufferVec::const_iterator itor = mDepthBufferPool[DepthBuffer::POOL_DEFAULT].begin(); + DepthBufferVec::const_iterator end = mDepthBufferPool[DepthBuffer::POOL_DEFAULT].end(); - while( itor != end ) - { - if( static_cast(*itor)->getDepthStencilView() == depthSurface ) - return *itor; + while( itor != end ) + { + if( static_cast(*itor)->getDepthStencilView() == depthSurface ) + return *itor; - ++itor; - } + ++itor; + } - //Create a new container for it - D3D11DepthBuffer *newDepthBuffer = new D3D11DepthBuffer( DepthBuffer::POOL_DEFAULT, this, depthSurface, - width, height, fsaa, fsaaQuality, true ); + //Create a new container for it + D3D11DepthBuffer *newDepthBuffer = new D3D11DepthBuffer( DepthBuffer::POOL_DEFAULT, this, depthSurface, + width, height, fsaa, fsaaQuality, true ); - //Add the 'main' depth buffer to the pool - mDepthBufferPool[newDepthBuffer->getPoolId()].push_back( newDepthBuffer ); + //Add the 'main' depth buffer to the pool + mDepthBufferPool[newDepthBuffer->getPoolId()].push_back( newDepthBuffer ); - return newDepthBuffer; - } - //--------------------------------------------------------------------- + return newDepthBuffer; + } + //--------------------------------------------------------------------- RenderTarget* D3D11RenderSystem::detachRenderTarget(const String &name) { RenderTarget* target = RenderSystem::detachRenderTarget(name); @@ -1574,70 +1574,70 @@ namespace Ogre void D3D11RenderSystem::detachRenderTargetImpl(const String& name) { // Check in specialized lists - if (mPrimaryWindow->getName() == name) - { - // We're destroying the primary window, so reset device and window - mPrimaryWindow = 0; - } - else - { - // Check secondary windows - SecondaryWindowList::iterator sw; - for (sw = mSecondaryWindows.begin(); sw != mSecondaryWindows.end(); ++sw) - { - if ((*sw)->getName() == name) - { - mSecondaryWindows.erase(sw); - break; - } - } - } + if (mPrimaryWindow->getName() == name) + { + // We're destroying the primary window, so reset device and window + mPrimaryWindow = 0; + } + else + { + // Check secondary windows + SecondaryWindowList::iterator sw; + for (sw = mSecondaryWindows.begin(); sw != mSecondaryWindows.end(); ++sw) + { + if ((*sw)->getName() == name) + { + mSecondaryWindows.erase(sw); + break; + } + } + } } //--------------------------------------------------------------------- void D3D11RenderSystem::destroyRenderTarget(const String& name) { detachRenderTargetImpl(name); - // Do the real removal - RenderSystem::destroyRenderTarget(name); - - // Did we destroy the primary? - if (!mPrimaryWindow) - { - // device is no longer valid, so free it all up - freeDevice(); - } - - } - //----------------------------------------------------------------------- - void D3D11RenderSystem::freeDevice(void) - { - if (!mDevice.isNull() && mCurrentCapabilities) - { - // Set all texture units to nothing to release texture surfaces - _disableTextureUnitsFrom(0); - // Unbind any vertex streams to avoid memory leaks - /*for (unsigned int i = 0; i < mLastVertexSourceCount; ++i) - { - HRESULT hr = mDevice->SetStreamSource(i, NULL, 0, 0); - } - */ - // Clean up depth stencil surfaces - mDevice.release(); - //mActiveD3DDriver->setDevice(D3D11Device(NULL)); - mDevice = 0; - - } - - - } - //--------------------------------------------------------------------- - VertexElementType D3D11RenderSystem::getColourVertexElementType(void) const - { - return VET_COLOUR_ABGR; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_convertProjectionMatrix(const Matrix4& matrix, + // Do the real removal + RenderSystem::destroyRenderTarget(name); + + // Did we destroy the primary? + if (!mPrimaryWindow) + { + // device is no longer valid, so free it all up + freeDevice(); + } + + } + //----------------------------------------------------------------------- + void D3D11RenderSystem::freeDevice(void) + { + if (!mDevice.isNull() && mCurrentCapabilities) + { + // Set all texture units to nothing to release texture surfaces + _disableTextureUnitsFrom(0); + // Unbind any vertex streams to avoid memory leaks + /*for (unsigned int i = 0; i < mLastVertexSourceCount; ++i) + { + HRESULT hr = mDevice->SetStreamSource(i, NULL, 0, 0); + } + */ + // Clean up depth stencil surfaces + mDevice.release(); + //mActiveD3DDriver->setDevice(D3D11Device(NULL)); + mDevice = 0; + + } + + + } + //--------------------------------------------------------------------- + VertexElementType D3D11RenderSystem::getColourVertexElementType(void) const + { + return VET_COLOUR_ABGR; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram) { dest = matrix; @@ -1657,14 +1657,14 @@ namespace Ogre dest[3][2] = -dest[3][2]; } } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, + //--------------------------------------------------------------------- + void D3D11RenderSystem::_makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram) - { + { Radian theta ( fovy * 0.5 ); - Real h = 1 / Math::Tan(theta); - Real w = h / aspect; - Real q, qn; + Real h = 1 / Math::Tan(theta); + Real w = h / aspect; + Real q, qn; if (farPlane == 0) { q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST; @@ -1676,14 +1676,14 @@ namespace Ogre qn = -q * nearPlane; } - dest = Matrix4::ZERO; - dest[0][0] = w; - dest[1][1] = h; + dest = Matrix4::ZERO; + dest[0][0] = w; + dest[1][1] = h; if (forGpuProgram) { dest[2][2] = -q; - dest[3][2] = -1.0f; + dest[3][2] = -1.0f; } else { @@ -1692,11 +1692,11 @@ namespace Ogre } dest[2][3] = qn; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, - Matrix4& dest, bool forGpuProgram ) - { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, + Matrix4& dest, bool forGpuProgram ) + { Radian thetaY (fovy / 2.0f); Real tanThetaY = Math::Tan(thetaY); @@ -1727,1886 +1727,1886 @@ namespace Ogre { dest[2][2] = -dest[2][2]; } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setAmbientLight( float r, float g, float b ) - { - } - //--------------------------------------------------------------------- + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setAmbientLight( float r, float g, float b ) + { + } + //--------------------------------------------------------------------- void D3D11RenderSystem::_useLights(const LightList& lights, unsigned short limit) { } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setShadingType( ShadeOptions so ) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setLightingEnabled( bool enabled ) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setViewMatrix( const Matrix4 &m ) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setProjectionMatrix( const Matrix4 &m ) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setWorldMatrix( const Matrix4 &m ) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setSurfaceParams( const ColourValue &ambient, const ColourValue &diffuse, - const ColourValue &specular, const ColourValue &emissive, Real shininess, + //--------------------------------------------------------------------- + void D3D11RenderSystem::setShadingType( ShadeOptions so ) + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setLightingEnabled( bool enabled ) + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setViewMatrix( const Matrix4 &m ) + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setProjectionMatrix( const Matrix4 &m ) + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setWorldMatrix( const Matrix4 &m ) + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setSurfaceParams( const ColourValue &ambient, const ColourValue &diffuse, + const ColourValue &specular, const ColourValue &emissive, Real shininess, TrackVertexColourType tracking ) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setPointParameters(Real size, - bool attenuationEnabled, Real constant, Real linear, Real quadratic, - Real minSize, Real maxSize) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setPointSpritesEnabled(bool enabled) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTexture( size_t stage, bool enabled, const TexturePtr& tex ) - { - static D3D11TexturePtr dt; - dt = tex.staticCast(); - if (enabled && !dt.isNull() && dt->getSize() > 0) - { - // note used - dt->touch(); - ID3D11ShaderResourceView * pTex = dt->getTexture(); - mTexStageDesc[stage].pTex = pTex; - mTexStageDesc[stage].used = true; - mTexStageDesc[stage].type = dt->getTextureType(); - } - else - { - mTexStageDesc[stage].used = false; - } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setBindingType(TextureUnitState::BindingType bindingType) - { - mBindingType = bindingType; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setVertexTexture(size_t stage, const TexturePtr& tex) - { - if (tex.isNull()) - _setTexture(stage, false, tex); + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setPointParameters(Real size, + bool attenuationEnabled, Real constant, Real linear, Real quadratic, + Real minSize, Real maxSize) + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setPointSpritesEnabled(bool enabled) + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTexture( size_t stage, bool enabled, const TexturePtr& tex ) + { + static D3D11TexturePtr dt; + dt = tex.staticCast(); + if (enabled && !dt.isNull() && dt->getSize() > 0) + { + // note used + dt->touch(); + ID3D11ShaderResourceView * pTex = dt->getTexture(); + mTexStageDesc[stage].pTex = pTex; + mTexStageDesc[stage].used = true; + mTexStageDesc[stage].type = dt->getTextureType(); + } + else + { + mTexStageDesc[stage].used = false; + } + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setBindingType(TextureUnitState::BindingType bindingType) + { + mBindingType = bindingType; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setVertexTexture(size_t stage, const TexturePtr& tex) + { + if (tex.isNull()) + _setTexture(stage, false, tex); else - _setTexture(stage, true, tex); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setGeometryTexture(size_t stage, const TexturePtr& tex) - { - if (tex.isNull()) - _setTexture(stage, false, tex); + _setTexture(stage, true, tex); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setGeometryTexture(size_t stage, const TexturePtr& tex) + { + if (tex.isNull()) + _setTexture(stage, false, tex); else - _setTexture(stage, true, tex); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setComputeTexture(size_t stage, const TexturePtr& tex) - { - if (tex.isNull()) - _setTexture(stage, false, tex); + _setTexture(stage, true, tex); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setComputeTexture(size_t stage, const TexturePtr& tex) + { + if (tex.isNull()) + _setTexture(stage, false, tex); else - _setTexture(stage, true, tex); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTesselationHullTexture(size_t stage, const TexturePtr& tex) - { - if (tex.isNull()) - _setTexture(stage, false, tex); + _setTexture(stage, true, tex); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTesselationHullTexture(size_t stage, const TexturePtr& tex) + { + if (tex.isNull()) + _setTexture(stage, false, tex); else - _setTexture(stage, true, tex); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTesselationDomainTexture(size_t stage, const TexturePtr& tex) - { - if (tex.isNull()) - _setTexture(stage, false, tex); + _setTexture(stage, true, tex); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTesselationDomainTexture(size_t stage, const TexturePtr& tex) + { + if (tex.isNull()) + _setTexture(stage, false, tex); else - _setTexture(stage, true, tex); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_disableTextureUnit(size_t texUnit) - { - RenderSystem::_disableTextureUnit(texUnit); - // also disable vertex texture unit - static TexturePtr nullPtr; - _setVertexTexture(texUnit, nullPtr); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTextureCoordSet( size_t stage, size_t index ) - { - mTexStageDesc[stage].coordIndex = index; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTextureCoordCalculation( size_t stage, TexCoordCalcMethod m, + _setTexture(stage, true, tex); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_disableTextureUnit(size_t texUnit) + { + RenderSystem::_disableTextureUnit(texUnit); + // also disable vertex texture unit + static TexturePtr nullPtr; + _setVertexTexture(texUnit, nullPtr); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTextureCoordSet( size_t stage, size_t index ) + { + mTexStageDesc[stage].coordIndex = index; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTextureCoordCalculation( size_t stage, TexCoordCalcMethod m, const Frustum* frustum) - { - // record the stage state - mTexStageDesc[stage].autoTexCoordType = m; - mTexStageDesc[stage].frustum = frustum; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTextureMipmapBias(size_t unit, float bias) - { - mTexStageDesc[unit].samplerDesc.MipLODBias = bias; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTextureMatrix( size_t stage, const Matrix4& xForm ) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTextureAddressingMode( size_t stage, - const TextureUnitState::UVWAddressingMode& uvw ) - { - // record the stage state - mTexStageDesc[stage].samplerDesc.AddressU = D3D11Mappings::get(uvw.u); - mTexStageDesc[stage].samplerDesc.AddressV = D3D11Mappings::get(uvw.v); - mTexStageDesc[stage].samplerDesc.AddressW = D3D11Mappings::get(uvw.w); - } + { + // record the stage state + mTexStageDesc[stage].autoTexCoordType = m; + mTexStageDesc[stage].frustum = frustum; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTextureMipmapBias(size_t unit, float bias) + { + mTexStageDesc[unit].samplerDesc.MipLODBias = bias; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTextureMatrix( size_t stage, const Matrix4& xForm ) + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTextureAddressingMode( size_t stage, + const TextureUnitState::UVWAddressingMode& uvw ) + { + // record the stage state + mTexStageDesc[stage].samplerDesc.AddressU = D3D11Mappings::get(uvw.u); + mTexStageDesc[stage].samplerDesc.AddressV = D3D11Mappings::get(uvw.v); + mTexStageDesc[stage].samplerDesc.AddressW = D3D11Mappings::get(uvw.w); + } //----------------------------------------------------------------------------- void D3D11RenderSystem::_setTextureBorderColour(size_t stage, const ColourValue& colour) { - D3D11Mappings::get(colour, mTexStageDesc[stage].samplerDesc.BorderColor); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTextureBlendMode( size_t stage, const LayerBlendModeEx& bm ) - { - if (bm.blendType == LBT_COLOUR) - { - mTexStageDesc[stage].layerBlendMode = bm; - } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op /*= SBO_ADD*/ ) - { - if( sourceFactor == SBF_ONE && destFactor == SBF_ZERO) - { - mBlendDesc.RenderTarget[0].BlendEnable = FALSE; - } - else - { - mBlendDesc.RenderTarget[0].BlendEnable = TRUE; + D3D11Mappings::get(colour, mTexStageDesc[stage].samplerDesc.BorderColor); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTextureBlendMode( size_t stage, const LayerBlendModeEx& bm ) + { + if (bm.blendType == LBT_COLOUR) + { + mTexStageDesc[stage].layerBlendMode = bm; + } + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op /*= SBO_ADD*/ ) + { + if( sourceFactor == SBF_ONE && destFactor == SBF_ZERO) + { + mBlendDesc.RenderTarget[0].BlendEnable = FALSE; + } + else + { + mBlendDesc.RenderTarget[0].BlendEnable = TRUE; mBlendDesc.RenderTarget[0].SrcBlend = D3D11Mappings::get(sourceFactor, false); mBlendDesc.RenderTarget[0].DestBlend = D3D11Mappings::get(destFactor, false); mBlendDesc.RenderTarget[0].SrcBlendAlpha = D3D11Mappings::get(sourceFactor, true); mBlendDesc.RenderTarget[0].DestBlendAlpha = D3D11Mappings::get(destFactor, true); mBlendDesc.RenderTarget[0].BlendOp = mBlendDesc.RenderTarget[0].BlendOpAlpha = D3D11Mappings::get(op); - // feature level 9 and below does not support alpha to coverage. - if (mFeatureLevel < D3D_FEATURE_LEVEL_10_0) - mBlendDesc.AlphaToCoverageEnable = false; - else - mBlendDesc.AlphaToCoverageEnable = mSceneAlphaToCoverage; - - mBlendDesc.RenderTarget[0].RenderTargetWriteMask = 0x0F; - } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op /*= SBO_ADD*/, SceneBlendOperation alphaOp /*= SBO_ADD*/ ) - { - if( sourceFactor == SBF_ONE && destFactor == SBF_ZERO) - { - mBlendDesc.RenderTarget[0].BlendEnable = FALSE; - } - else - { - mBlendDesc.RenderTarget[0].BlendEnable = TRUE; - mBlendDesc.RenderTarget[0].SrcBlend = D3D11Mappings::get(sourceFactor, false); - mBlendDesc.RenderTarget[0].DestBlend = D3D11Mappings::get(destFactor, false); - mBlendDesc.RenderTarget[0].BlendOp = D3D11Mappings::get(op) ; - mBlendDesc.RenderTarget[0].SrcBlendAlpha = D3D11Mappings::get(sourceFactorAlpha, true); - mBlendDesc.RenderTarget[0].DestBlendAlpha = D3D11Mappings::get(destFactorAlpha, true); - mBlendDesc.RenderTarget[0].BlendOpAlpha = D3D11Mappings::get(alphaOp) ; - mBlendDesc.AlphaToCoverageEnable = false; - - mBlendDesc.RenderTarget[0].RenderTargetWriteMask = 0x0F; - } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ) - { - mSceneAlphaRejectFunc = func; - mSceneAlphaRejectValue = value; - mSceneAlphaToCoverage = alphaToCoverage; - mBlendDesc.AlphaToCoverageEnable = alphaToCoverage; - - // Do nothing, alpha rejection unavailable in Direct3D11 - // hacky, but it works - if(func != CMPF_ALWAYS_PASS && !alphaToCoverage && mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { mMinRequestedFeatureLevel = D3D_FEATURE_LEVEL_9_1; - // Actually we should do it in pixel shader in dx11. - mBlendDesc.AlphaToCoverageEnable = true; - } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setCullingMode( CullingMode mode ) - { - mCullingMode = mode; - - // TODO: invert culling mode based on mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping() - mRasterizerDesc.CullMode = D3D11Mappings::get(mode); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setDepthBufferParams( bool depthTest, bool depthWrite, CompareFunction depthFunction ) - { - _setDepthBufferCheckEnabled( depthTest ); - _setDepthBufferWriteEnabled( depthWrite ); - _setDepthBufferFunction( depthFunction ); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setDepthBufferCheckEnabled( bool enabled ) - { - mDepthStencilDesc.DepthEnable = enabled; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setDepthBufferWriteEnabled( bool enabled ) - { - if (enabled) - { - mDepthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - } - else - { - mDepthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setDepthBufferFunction( CompareFunction func ) - { - mDepthStencilDesc.DepthFunc = D3D11Mappings::get(func); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setDepthBias(float constantBias, float slopeScaleBias) - { - mRasterizerDesc.DepthBiasClamp = constantBias; - mRasterizerDesc.SlopeScaledDepthBias = slopeScaleBias; - - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setColourBufferWriteEnabled(bool red, bool green, - bool blue, bool alpha) - { - UINT8 val = 0; - if (red) - val |= D3D11_COLOR_WRITE_ENABLE_RED; - if (green) - val |= D3D11_COLOR_WRITE_ENABLE_GREEN; - if (blue) - val |= D3D11_COLOR_WRITE_ENABLE_BLUE; - if (alpha) - val |= D3D11_COLOR_WRITE_ENABLE_ALPHA; - - mBlendDesc.RenderTarget[0].RenderTargetWriteMask = val; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setFog( FogMode mode, const ColourValue& colour, Real densitiy, Real start, Real end ) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setPolygonMode(PolygonMode level) - { - mPolygonMode = level; - mRasterizerDesc.FillMode = D3D11Mappings::get(mPolygonMode); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setStencilCheckEnabled(bool enabled) - { - mDepthStencilDesc.StencilEnable = enabled; - } + // feature level 9 and below does not support alpha to coverage. + if (mFeatureLevel < D3D_FEATURE_LEVEL_10_0) + mBlendDesc.AlphaToCoverageEnable = false; + else + mBlendDesc.AlphaToCoverageEnable = mSceneAlphaToCoverage; + + mBlendDesc.RenderTarget[0].RenderTargetWriteMask = 0x0F; + } + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op /*= SBO_ADD*/, SceneBlendOperation alphaOp /*= SBO_ADD*/ ) + { + if( sourceFactor == SBF_ONE && destFactor == SBF_ZERO) + { + mBlendDesc.RenderTarget[0].BlendEnable = FALSE; + } + else + { + mBlendDesc.RenderTarget[0].BlendEnable = TRUE; + mBlendDesc.RenderTarget[0].SrcBlend = D3D11Mappings::get(sourceFactor, false); + mBlendDesc.RenderTarget[0].DestBlend = D3D11Mappings::get(destFactor, false); + mBlendDesc.RenderTarget[0].BlendOp = D3D11Mappings::get(op) ; + mBlendDesc.RenderTarget[0].SrcBlendAlpha = D3D11Mappings::get(sourceFactorAlpha, true); + mBlendDesc.RenderTarget[0].DestBlendAlpha = D3D11Mappings::get(destFactorAlpha, true); + mBlendDesc.RenderTarget[0].BlendOpAlpha = D3D11Mappings::get(alphaOp) ; + mBlendDesc.AlphaToCoverageEnable = false; + + mBlendDesc.RenderTarget[0].RenderTargetWriteMask = 0x0F; + } + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ) + { + mSceneAlphaRejectFunc = func; + mSceneAlphaRejectValue = value; + mSceneAlphaToCoverage = alphaToCoverage; + mBlendDesc.AlphaToCoverageEnable = alphaToCoverage; + + // Do nothing, alpha rejection unavailable in Direct3D11 + // hacky, but it works + if(func != CMPF_ALWAYS_PASS && !alphaToCoverage && mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { mMinRequestedFeatureLevel = D3D_FEATURE_LEVEL_9_1; + // Actually we should do it in pixel shader in dx11. + mBlendDesc.AlphaToCoverageEnable = true; + } + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setCullingMode( CullingMode mode ) + { + mCullingMode = mode; + + // TODO: invert culling mode based on mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping() + mRasterizerDesc.CullMode = D3D11Mappings::get(mode); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setDepthBufferParams( bool depthTest, bool depthWrite, CompareFunction depthFunction ) + { + _setDepthBufferCheckEnabled( depthTest ); + _setDepthBufferWriteEnabled( depthWrite ); + _setDepthBufferFunction( depthFunction ); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setDepthBufferCheckEnabled( bool enabled ) + { + mDepthStencilDesc.DepthEnable = enabled; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setDepthBufferWriteEnabled( bool enabled ) + { + if (enabled) + { + mDepthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + } + else + { + mDepthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + } + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setDepthBufferFunction( CompareFunction func ) + { + mDepthStencilDesc.DepthFunc = D3D11Mappings::get(func); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setDepthBias(float constantBias, float slopeScaleBias) + { + mRasterizerDesc.DepthBiasClamp = constantBias; + mRasterizerDesc.SlopeScaledDepthBias = slopeScaleBias; + + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setColourBufferWriteEnabled(bool red, bool green, + bool blue, bool alpha) + { + UINT8 val = 0; + if (red) + val |= D3D11_COLOR_WRITE_ENABLE_RED; + if (green) + val |= D3D11_COLOR_WRITE_ENABLE_GREEN; + if (blue) + val |= D3D11_COLOR_WRITE_ENABLE_BLUE; + if (alpha) + val |= D3D11_COLOR_WRITE_ENABLE_ALPHA; + + mBlendDesc.RenderTarget[0].RenderTargetWriteMask = val; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setFog( FogMode mode, const ColourValue& colour, Real densitiy, Real start, Real end ) + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setPolygonMode(PolygonMode level) + { + mPolygonMode = level; + mRasterizerDesc.FillMode = D3D11Mappings::get(mPolygonMode); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setStencilCheckEnabled(bool enabled) + { + mDepthStencilDesc.StencilEnable = enabled; + } //--------------------------------------------------------------------- void D3D11RenderSystem::setStencilBufferParams(CompareFunction func, uint32 refValue, uint32 compareMask, uint32 writeMask, StencilOperation stencilFailOp, StencilOperation depthFailOp, StencilOperation passOp, bool twoSidedOperation, bool readBackAsTexture) { - bool flip = false; // TODO: determine from mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping() + bool flip = false; // TODO: determine from mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping() + + mDepthStencilDesc.FrontFace.StencilFunc = D3D11Mappings::get(func); + mDepthStencilDesc.BackFace.StencilFunc = D3D11Mappings::get(func); + + mStencilRef = refValue; + mDepthStencilDesc.StencilReadMask = compareMask; + mDepthStencilDesc.StencilWriteMask = writeMask; + + mDepthStencilDesc.FrontFace.StencilFailOp = D3D11Mappings::get(stencilFailOp, flip); + mDepthStencilDesc.BackFace.StencilFailOp = D3D11Mappings::get(stencilFailOp, !flip); + + mDepthStencilDesc.FrontFace.StencilDepthFailOp = D3D11Mappings::get(depthFailOp, flip); + mDepthStencilDesc.BackFace.StencilDepthFailOp = D3D11Mappings::get(depthFailOp, !flip); + + mDepthStencilDesc.FrontFace.StencilPassOp = D3D11Mappings::get(passOp, flip); + mDepthStencilDesc.BackFace.StencilPassOp = D3D11Mappings::get(passOp, !flip); + + if (!twoSidedOperation) + { + mDepthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_NEVER; + } + + mReadBackAsTexture = readBackAsTexture; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTextureUnitFiltering(size_t unit, FilterType ftype, + FilterOptions filter) + { + switch(ftype) { + case FT_MIN: + FilterMinification[unit] = filter; + break; + case FT_MAG: + FilterMagnification[unit] = filter; + break; + case FT_MIP: + FilterMips[unit] = filter; + break; + } + + mTexStageDesc[unit].samplerDesc.Filter = D3D11Mappings::get(FilterMinification[unit], FilterMagnification[unit], FilterMips[unit],CompareEnabled); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTextureUnitCompareEnabled(size_t unit, bool compare) + { + CompareEnabled = compare; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTextureUnitCompareFunction(size_t unit, CompareFunction function) + { + mTexStageDesc[unit].samplerDesc.ComparisonFunc = D3D11Mappings::get(function); + } + //--------------------------------------------------------------------- + DWORD D3D11RenderSystem::_getCurrentAnisotropy(size_t unit) + { + return mTexStageDesc[unit].samplerDesc.MaxAnisotropy;; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) + { + mTexStageDesc[unit].samplerDesc.MaxAnisotropy = maxAnisotropy; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setRenderTarget(RenderTarget *target) + { + mActiveRenderTarget = target; + if (mActiveRenderTarget) + { + // we need to clear the state + mDevice.GetImmediateContext()->ClearState(); + + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot Clear State\nError Description:" + errorDescription, + "D3D11RenderSystem::_setRenderTarget"); + } + + _setRenderTargetViews(); + } + } + + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setRenderTargetViews() + { + RenderTarget *target = mActiveRenderTarget; + + if (target) + { + ID3D11RenderTargetView * pRTView[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + memset(pRTView, 0, sizeof(pRTView)); + + target->getCustomAttribute( "ID3D11RenderTargetView", &pRTView ); + + uint numberOfViews; + target->getCustomAttribute( "numberOfViews", &numberOfViews ); + + //Retrieve depth buffer + D3D11DepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); + + if( target->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH && !depthBuffer ) + { + //Depth is automatically managed and there is no depth buffer attached to this RT + //or the Current D3D device doesn't match the one this Depth buffer was created + setDepthBufferFor( target ); + } + + //Retrieve depth buffer again (it may have changed) + depthBuffer = static_cast(target->getDepthBuffer()); + + // now switch to the new render target + mDevice.GetImmediateContext()->OMSetRenderTargets( + numberOfViews, + pRTView, + depthBuffer ? depthBuffer->getDepthStencilView() : 0 ); + + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set render target\nError Description:" + errorDescription, + "D3D11RenderSystem::_setRenderTargetViews"); + } + } + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_setViewport( Viewport *vp ) + { + if (!vp) + { + mActiveViewport = NULL; + _setRenderTarget(NULL); + } + else if( vp != mActiveViewport || vp->_isUpdated() ) + { + mActiveViewport = vp; + + // ok, it's different, time to set render target and viewport params + D3D11_VIEWPORT d3dvp; + + // Set render target + RenderTarget* target; + target = vp->getTarget(); + + _setRenderTarget(target); + _setCullingMode( mCullingMode ); + + // set viewport dimensions + d3dvp.TopLeftX = static_cast(vp->getActualLeft()); + d3dvp.TopLeftY = static_cast(vp->getActualTop()); + d3dvp.Width = static_cast(vp->getActualWidth()); + d3dvp.Height = static_cast(vp->getActualHeight()); + if (target->requiresTextureFlipping()) + { + // Convert "top-left" to "bottom-left" + d3dvp.TopLeftY = target->getHeight() - d3dvp.Height - d3dvp.TopLeftY; + } + + // Z-values from 0.0 to 1.0 (TODO: standardise with OpenGL) + d3dvp.MinDepth = 0.0f; + d3dvp.MaxDepth = 1.0f; + + mDevice.GetImmediateContext()->RSSetViewports(1, &d3dvp); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set viewports\nError Description:" + errorDescription, + "D3D11RenderSystem::_setViewport"); + } + + // Set sRGB write mode + //__SetRenderState(D3DRS_SRGBWRITEENABLE, target->isHardwareGammaEnabled()); + // TODO where has sRGB state gone? + + vp->_clearUpdatedFlag(); + } +#if OGRE_PLATFORM == OGRE_PLATFORM_WINRT + // as swapchain was created with DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL we need to reestablish render target views + else + { + _setRenderTargetViews(); + } +#endif + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_beginFrame() + { + + if( !mActiveViewport ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Cannot begin frame - no viewport selected.", "D3D11RenderSystem::_beginFrame" ); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_endFrame() + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setVertexDeclaration(VertexDeclaration* decl) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Cannot directly call setVertexDeclaration in the d3d11 render system - cast then use 'setVertexDeclaration(VertexDeclaration* decl, VertexBufferBinding* binding)' .", + "D3D11RenderSystem::setVertexDeclaration" ); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setVertexDeclaration(VertexDeclaration* decl, VertexBufferBinding* binding) + { + D3D11VertexDeclaration* d3ddecl = + static_cast(decl); + + d3ddecl->bindToShader(mBoundVertexProgram, binding); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setVertexBufferBinding(VertexBufferBinding* binding) + { + // TODO: attempt to detect duplicates + const VertexBufferBinding::VertexBufferBindingMap& binds = binding->getBindings(); + VertexBufferBinding::VertexBufferBindingMap::const_iterator i, iend; + iend = binds.end(); + for (i = binds.begin(); i != iend; ++i) + { + const D3D11HardwareVertexBuffer* d3d11buf = + static_cast(i->second.get()); + + UINT stride = static_cast(d3d11buf->getVertexSize()); + UINT offset = 0; // no stream offset, this is handled in _render instead + UINT slot = static_cast(i->first); + ID3D11Buffer * pVertexBuffers = d3d11buf->getD3DVertexBuffer(); + mDevice.GetImmediateContext()->IASetVertexBuffers( + slot, // The first input slot for binding. + 1, // The number of vertex buffers in the array. + &pVertexBuffers, + &stride, + &offset + ); + + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set vertex buffers\nError Description:" + errorDescription, + "D3D11RenderSystem::setVertexBufferBinding"); + } + } + + mLastVertexSourceCount = binds.size(); + } + + //--------------------------------------------------------------------- + // TODO: Move this class to the right place. + class D3D11RenderOperationState : public Renderable::RenderSystemData + { + public: + ID3D11BlendState * mBlendState; + ID3D11RasterizerState * mRasterizer; + ID3D11DepthStencilState * mDepthStencilState; + + ID3D11SamplerState * mSamplerStates[OGRE_MAX_TEXTURE_LAYERS]; + size_t mSamplerStatesCount; + + ID3D11ShaderResourceView * mTextures[OGRE_MAX_TEXTURE_LAYERS]; + size_t mTexturesCount; + + D3D11RenderOperationState() : + mBlendState(NULL) + , mRasterizer(NULL) + , mDepthStencilState(NULL) + , mSamplerStatesCount(0) + , mTexturesCount(0) + { + for (size_t i = 0 ; i < OGRE_MAX_TEXTURE_LAYERS ; i++) + { + mSamplerStates[i] = 0; + } + } + + + ~D3D11RenderOperationState() + { + SAFE_RELEASE( mBlendState ); + SAFE_RELEASE( mRasterizer ); + SAFE_RELEASE( mDepthStencilState ); + + for (size_t i = 0 ; i < OGRE_MAX_TEXTURE_LAYERS ; i++) + { + SAFE_RELEASE( mSamplerStates[i] ); + } + } + }; + + //--------------------------------------------------------------------- + void D3D11RenderSystem::_render(const RenderOperation& op) + { + + // Exit immediately if there is nothing to render + if (op.vertexData==0 || op.vertexData->vertexCount == 0) + { + return; + } + + HardwareVertexBufferSharedPtr globalInstanceVertexBuffer = getGlobalInstanceVertexBuffer(); + VertexDeclaration* globalVertexDeclaration = getGlobalInstanceVertexBufferVertexDeclaration(); + + bool hasInstanceData = op.useGlobalInstancingVertexBufferIsAvailable && + !globalInstanceVertexBuffer.isNull() && globalVertexDeclaration != NULL + || op.vertexData->vertexBufferBinding->getHasInstanceData(); + + size_t numberOfInstances = op.numberOfInstances; + + if (op.useGlobalInstancingVertexBufferIsAvailable) + { + numberOfInstances *= getGlobalNumberOfInstances(); + } + + // Call super class + RenderSystem::_render(op); + + D3D11RenderOperationState stackOpState; + D3D11RenderOperationState * opState = &stackOpState; + + //if(!opState) + { + //opState = new D3D11RenderOperationState; + + HRESULT hr = mDevice->CreateBlendState(&mBlendDesc, &opState->mBlendState) ; + if (FAILED(hr)) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Failed to create blend state\nError Description:" + errorDescription, + "D3D11RenderSystem::_render" ); + } + + if (mFeatureLevel < D3D_FEATURE_LEVEL_10_0) + { + // should we enable it all the time and not only for lower the level 10? + mRasterizerDesc.DepthClipEnable = true; + } + + hr = mDevice->CreateRasterizerState(&mRasterizerDesc, &opState->mRasterizer) ; + if (FAILED(hr)) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Failed to create rasterizer state\nError Description:" + errorDescription, + "D3D11RenderSystem::_render" ); + } + + hr = mDevice->CreateDepthStencilState(&mDepthStencilDesc, &opState->mDepthStencilState) ; + if (FAILED(hr)) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Failed to create depth stencil state\nError Description:" + errorDescription, + "D3D11RenderSystem::_render" ); + } + + // samplers mapping + size_t numberOfSamplers = OGRE_MAX_TEXTURE_LAYERS + 1; + + //find the maximum number of samplers + while (--numberOfSamplers >= 1 && mTexStageDesc[numberOfSamplers - 1].used == false) ; + + opState->mSamplerStatesCount = numberOfSamplers; + opState->mTexturesCount = numberOfSamplers; + + + + for (size_t n = 0; n < numberOfSamplers; n++) + { + ID3D11SamplerState * samplerState = NULL; + ID3D11ShaderResourceView *texture = NULL; + sD3DTextureStageDesc & stage = mTexStageDesc[n]; + if(!stage.used) + { + samplerState = NULL; + texture = NULL; + } + else + { + texture = stage.pTex; + + stage.samplerDesc.Filter = D3D11Mappings::get(FilterMinification[n], FilterMagnification[n], + FilterMips[n],false ); + stage.samplerDesc.ComparisonFunc = D3D11Mappings::get(mSceneAlphaRejectFunc); + stage.samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + stage.samplerDesc.MinLOD = 0; + stage.samplerDesc.MipLODBias = 0.f; + stage.currentSamplerDesc = stage.samplerDesc; + + HRESULT hr = mDevice->CreateSamplerState(&stage.samplerDesc, &samplerState) ; + if (FAILED(hr)) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Failed to create sampler state\nError Description:" + errorDescription, + "D3D11RenderSystem::_render" ); + } + + } + opState->mSamplerStates[n] = samplerState; + opState->mTextures[n] = texture; + } + } + + for (size_t n = opState->mTexturesCount; n < OGRE_MAX_TEXTURE_LAYERS; n++) + { + opState->mTextures[n] = NULL; + } + + //if (opState->mBlendState != mBoundBlendState) + { + mBoundBlendState = opState->mBlendState ; + mDevice.GetImmediateContext()->OMSetBlendState(opState->mBlendState, 0, 0xffffffff); // TODO - find out where to get the parameters + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set blend state\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + if (mBoundGeometryProgram && mBindingType == TextureUnitState::BindingType::BT_GEOMETRY) + { + { + mDevice.GetImmediateContext()->GSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set pixel shader samplers\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + mDevice.GetImmediateContext()->GSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + } + + //if (opState->mRasterizer != mBoundRasterizer) + { + mBoundRasterizer = opState->mRasterizer ; + + mDevice.GetImmediateContext()->RSSetState(opState->mRasterizer); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set rasterizer state\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + + + //if (opState->mDepthStencilState != mBoundDepthStencilState) + { + mBoundDepthStencilState = opState->mDepthStencilState ; + + mDevice.GetImmediateContext()->OMSetDepthStencilState(opState->mDepthStencilState, mStencilRef); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set depth stencil state\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + + if (opState->mSamplerStatesCount > 0 ) // if the NumSamplers is 0, the operation effectively does nothing. + { + /// Pixel Shader binding + { + // Assaf: seem I have better performance without this check... TODO - remove? + // if ((mBoundSamplerStatesCount != opState->mSamplerStatesCount) || ( 0 != memcmp(opState->mSamplerStates, mBoundSamplerStates, mBoundSamplerStatesCount) ) ) + { + //mBoundSamplerStatesCount = opState->mSamplerStatesCount; + //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount); + mDevice.GetImmediateContext()->PSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set pixel shader samplers\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + + mDevice.GetImmediateContext()->PSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + + /// Vertex Shader binding + if (mBindingType == TextureUnitState::BindingType::BT_VERTEX) + { + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { + //mBoundSamplerStatesCount = opState->mSamplerStatesCount; + //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount); + mDevice.GetImmediateContext()->VSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set pixel shader samplers\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { + mDevice.GetImmediateContext()->VSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + } + + /// Compute Shader binding + if (mBoundComputeProgram && mBindingType == TextureUnitState::BindingType::BT_COMPUTE) + { + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { + //mBoundSamplerStatesCount = opState->mSamplerStatesCount; + //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount); + mDevice.GetImmediateContext()->CSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set compute shader samplers\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { + mDevice.GetImmediateContext()->CSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set compute shader resources\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + } + + /// Hull Shader binding + if (mBoundTessellationHullProgram && mBindingType == TextureUnitState::BindingType::BT_TESSELLATION_HULL) + { + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { + //mBoundSamplerStatesCount = opState->mSamplerStatesCount; + //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount); + mDevice.GetImmediateContext()->HSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set hull shader samplers\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { + mDevice.GetImmediateContext()->HSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set hull shader resources\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + } + + /// Domain Shader binding + if (mBoundTessellationDomainProgram && mBindingType == TextureUnitState::BindingType::BT_TESSELLATION_DOMAIN) + { + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { + //mBoundSamplerStatesCount = opState->mSamplerStatesCount; + //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount); + mDevice.GetImmediateContext()->DSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set domain shader samplers\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) + { + mDevice.GetImmediateContext()->DSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set domain shader resources\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + } + } + + ID3D11Buffer* pSOTarget=0; + // Mustn't bind a emulated vertex, pixel shader (see below), if we are rendering to a stream out buffer + mDevice.GetImmediateContext()->SOGetTargets(1, &pSOTarget); + + //check consistency of vertex-fragment shaders + if (!mBoundVertexProgram || + (!mBoundFragmentProgram && op.operationType != RenderOperation::OT_POINT_LIST && pSOTarget==0 ) + ) + { + + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Attempted to render to a D3D11 device without both vertex and fragment shaders there is no fixed pipeline in d3d11 - use the RTSS or write custom shaders.", + "D3D11RenderSystem::_render"); + } + + // Check consistency of tessellation shaders + if( (mBoundTessellationHullProgram && !mBoundTessellationDomainProgram) || + (!mBoundTessellationHullProgram && mBoundTessellationDomainProgram) ) + { + if (mBoundTessellationHullProgram && !mBoundTessellationDomainProgram) { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Attempted to use tessellation, but domain shader is missing", + "D3D11RenderSystem::_render"); + } + else { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Attempted to use tessellation, but hull shader is missing", + "D3D11RenderSystem::_render"); } + } + + if (mDevice.isError()) + { + // this will never happen but we want to be consistent with the error checks... + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set geometry shader to null\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + + // Defer program bind to here because we must bind shader class instances, + // and this can only be made in SetShader calls. + // Also, bind shader resources + if (mBoundVertexProgram) + { + mDevice.GetImmediateContext()->VSSetShader(mBoundVertexProgram->getVertexShader(), + mClassInstances[GPT_VERTEX_PROGRAM], + mNumClassInstances[GPT_VERTEX_PROGRAM]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set vertex shader\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + if (mBoundFragmentProgram) + { + mDevice.GetImmediateContext()->PSSetShader(mBoundFragmentProgram->getPixelShader(), + mClassInstances[GPT_FRAGMENT_PROGRAM], + mNumClassInstances[GPT_FRAGMENT_PROGRAM]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set pixel shader\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + if (mBoundGeometryProgram) + { + mDevice.GetImmediateContext()->GSSetShader(mBoundGeometryProgram->getGeometryShader(), + mClassInstances[GPT_GEOMETRY_PROGRAM], + mNumClassInstances[GPT_GEOMETRY_PROGRAM]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set geometry shader\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + if (mBoundTessellationHullProgram) + { + mDevice.GetImmediateContext()->HSSetShader(mBoundTessellationHullProgram->getHullShader(), + mClassInstances[GPT_HULL_PROGRAM], + mNumClassInstances[GPT_HULL_PROGRAM]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set hull shader\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + if (mBoundTessellationDomainProgram) + { + mDevice.GetImmediateContext()->DSSetShader(mBoundTessellationDomainProgram->getDomainShader(), + mClassInstances[GPT_DOMAIN_PROGRAM], + mNumClassInstances[GPT_DOMAIN_PROGRAM]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set domain shader\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + if (mBoundComputeProgram) + { + mDevice.GetImmediateContext()->CSSetShader(mBoundComputeProgram->getComputeShader(), + mClassInstances[GPT_COMPUTE_PROGRAM], + mNumClassInstances[GPT_COMPUTE_PROGRAM]); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set compute shader\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + + + setVertexDeclaration(op.vertexData->vertexDeclaration, op.vertexData->vertexBufferBinding); + setVertexBufferBinding(op.vertexData->vertexBufferBinding); + + + // Determine rendering operation + D3D11_PRIMITIVE_TOPOLOGY primType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + DWORD primCount = 0; + + // Handle computing + if(mBoundComputeProgram) + { + // Bound unordered access views + mDevice.GetImmediateContext()->Dispatch(1, 1, 1); + + ID3D11UnorderedAccessView* views[] = { 0 }; + ID3D11ShaderResourceView* srvs[] = { 0 }; + mDevice.GetImmediateContext()->CSSetShaderResources( 0, 1, srvs ); + mDevice.GetImmediateContext()->CSSetUnorderedAccessViews( 0, 1, views, NULL ); + mDevice.GetImmediateContext()->CSSetShader( NULL, NULL, 0 ); + + return; + } + else if(mBoundTessellationHullProgram && mBoundTessellationDomainProgram) + { + // useful primitives for tessellation + switch( op.operationType ) + { + case RenderOperation::OT_LINE_LIST: + primType = D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST; + primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 2; + break; + + case RenderOperation::OT_LINE_STRIP: + primType = D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST; + primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 1; + break; + + case RenderOperation::OT_TRIANGLE_LIST: + primType = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST; + primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 3; + break; + + case RenderOperation::OT_TRIANGLE_STRIP: + primType = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST; + primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2; + break; + } + } + else + { + //rendering without tessellation. + bool useAdjacency = (mGeometryProgramBound && mBoundGeometryProgram && mBoundGeometryProgram->isAdjacencyInfoRequired()); + switch( op.operationType ) + { + case RenderOperation::OT_POINT_LIST: + primType = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount); + break; + + case RenderOperation::OT_LINE_LIST: + primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ : D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 2; + break; + + case RenderOperation::OT_LINE_STRIP: + primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ : D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP; + primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 1; + break; + + case RenderOperation::OT_TRIANGLE_LIST: + primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ : D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 3; + break; + + case RenderOperation::OT_TRIANGLE_STRIP: + primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ : D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2; + break; + + case RenderOperation::OT_TRIANGLE_FAN: + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error - DX11 render - no support for triangle fan (OT_TRIANGLE_FAN)", "D3D11RenderSystem::_render"); + primType = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; // todo - no TRIANGLE_FAN in DX 11 + primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2; + break; + } + } + + if (primCount) + { + // Issue the op + //HRESULT hr; + if( op.useIndexes ) + { + D3D11HardwareIndexBuffer* d3dIdxBuf = + static_cast(op.indexData->indexBuffer.get()); + mDevice.GetImmediateContext()->IASetIndexBuffer( d3dIdxBuf->getD3DIndexBuffer(), D3D11Mappings::getFormat(d3dIdxBuf->getType()), 0 ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set index buffer\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + + do + { + // do indexed draw operation + mDevice.GetImmediateContext()->IASetPrimitiveTopology( primType ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set primitive topology\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + + if (hasInstanceData) + { + mDevice.GetImmediateContext()->DrawIndexedInstanced( + static_cast(op.indexData->indexCount), + static_cast(numberOfInstances), + static_cast(op.indexData->indexStart), + static_cast(op.vertexData->vertexStart), + 0 + ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot draw indexed instanced\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + } + else + { + mDevice.GetImmediateContext()->DrawIndexed( + static_cast(op.indexData->indexCount), + static_cast(op.indexData->indexStart), + static_cast(op.vertexData->vertexStart) + ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot draw indexed\nError Description:" + errorDescription + + "Active OGRE vertex shader name: " + mBoundVertexProgram->getName() + + "\nActive OGRE fragment shader name: " + mBoundFragmentProgram->getName(), + "D3D11RenderSystem::_render"); + } + } + } while (updatePassIterationRenderState()); + } + else + { + // nfz: gpu_iterate + do + { + // Unindexed, a little simpler! + mDevice.GetImmediateContext()->IASetPrimitiveTopology( primType ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set primitive topology\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + + if (op.vertexData->vertexCount == -1) // -1 is a sign to use DrawAuto + { + mDevice.GetImmediateContext()->DrawAuto(); + } + else + { + if (hasInstanceData) + { + mDevice.GetImmediateContext()->DrawInstanced( + static_cast(numberOfInstances), + static_cast(op.vertexData->vertexCount), + static_cast(op.vertexData->vertexStart), + 0 + ); + } + else + { + mDevice.GetImmediateContext()->Draw( + static_cast(op.vertexData->vertexCount), + static_cast(op.vertexData->vertexStart) + ); + } + } + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot draw\nError Description:" + errorDescription, + "D3D11RenderSystem::_render"); + } + + + } while (updatePassIterationRenderState()); + } + } + + + if (true) // for now - clear the render state + { + mDevice.GetImmediateContext()->OMSetBlendState(0, 0, 0xffffffff); + mDevice.GetImmediateContext()->RSSetState(0); + mDevice.GetImmediateContext()->OMSetDepthStencilState(0, 0); +// mDevice->PSSetSamplers(static_cast(0), static_cast(0), 0); + + // Clear class instance storage + memset(mClassInstances, 0, sizeof(mClassInstances)); + memset(mNumClassInstances, 0, sizeof(mNumClassInstances)); + } + + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::_renderUsingReadBackAsTexture(unsigned int passNr, Ogre::String variableName, unsigned int StartSlot) + { + RenderTarget *target = mActiveRenderTarget; + switch (passNr) + { + case 1: + if (target) + { + ID3D11RenderTargetView * pRTView[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + memset(pRTView, 0, sizeof(pRTView)); + + target->getCustomAttribute( "ID3D11RenderTargetView", &pRTView ); + + uint numberOfViews; + target->getCustomAttribute( "numberOfViews", &numberOfViews ); + + //Retrieve depth buffer + D3D11DepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); + + // now switch to the new render target + mDevice.GetImmediateContext()->OMSetRenderTargets( + numberOfViews, + pRTView, + depthBuffer->getDepthStencilView()); + + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set render target\nError Description:" + errorDescription, + "D3D11RenderSystem::_renderUsingReadBackAsTexture"); + } + + mDevice.GetImmediateContext()->ClearDepthStencilView(depthBuffer->getDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0); + + float ClearColor[4]; + //D3D11Mappings::get(colour, ClearColor); + // Clear all views + mActiveRenderTarget->getCustomAttribute( "numberOfViews", &numberOfViews ); + if( numberOfViews == 1 ) + mDevice.GetImmediateContext()->ClearRenderTargetView( pRTView[0], ClearColor ); + else + { + for( uint i = 0; i < numberOfViews; ++i ) + mDevice.GetImmediateContext()->ClearRenderTargetView( pRTView[i], ClearColor ); + } + + } + break; + case 2: + if (target) + { + // + // We need to remove the the DST from the Render Targets if we want to use it as a texture : + // + ID3D11RenderTargetView * pRTView[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + memset(pRTView, 0, sizeof(pRTView)); + + target->getCustomAttribute( "ID3D11RenderTargetView", &pRTView ); + + uint numberOfViews; + target->getCustomAttribute( "numberOfViews", &numberOfViews ); + + //Retrieve depth buffer + D3D11DepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); + + // now switch to the new render target + mDevice.GetImmediateContext()->OMSetRenderTargets( + numberOfViews, + pRTView, + NULL); + //mTextureManager->mEffect->GetVariableByName(variableName.c_str())->AsShaderResource()->SetResource(mDSTResView); + + mDevice.GetImmediateContext()->PSSetShaderResources(static_cast(StartSlot), static_cast(numberOfViews), &mDSTResView); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription, + "D3D11RenderSystem::_renderUsingReadBackAsTexture"); + } + + } + break; + case 3: + // + // We need to unbind mDSTResView from the given variable because this buffer + // will be used later as the typical depth buffer, again + // must call Apply(0) here : to flush SetResource(NULL) + // + + if (target) + { + uint numberOfViews; + target->getCustomAttribute( "numberOfViews", &numberOfViews ); + + mDevice.GetImmediateContext()->PSSetShaderResources(static_cast(StartSlot), static_cast(numberOfViews), NULL); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription, + "D3D11RenderSystem::_renderUsingReadBackAsTexture"); + } + } + + break; + } + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setNormaliseNormals(bool normalise) + { + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::bindGpuProgram(GpuProgram* prg) + { + if (!prg) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Null program bound.", + "D3D11RenderSystem::bindGpuProgram"); + } + + switch (prg->getType()) + { + case GPT_VERTEX_PROGRAM: + { + // get the shader + mBoundVertexProgram = static_cast(prg); +/* ID3D11VertexShader * vsShaderToSet = mBoundVertexProgram->getVertexShader(); + + // set the shader + mDevice.GetImmediateContext()->VSSetShader(vsShaderToSet, NULL, 0); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set vertex shader\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgram"); + }*/ + } + break; + case GPT_FRAGMENT_PROGRAM: + { + mBoundFragmentProgram = static_cast(prg); +/* ID3D11PixelShader* psShaderToSet = mBoundFragmentProgram->getPixelShader(); + + mDevice.GetImmediateContext()->PSSetShader(psShaderToSet, NULL, 0); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set fragment shader\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgram"); + }*/ + } + break; + case GPT_GEOMETRY_PROGRAM: + { + mBoundGeometryProgram = static_cast(prg); +/* ID3D11GeometryShader* gsShaderToSet = mBoundGeometryProgram->getGeometryShader(); + + mDevice.GetImmediateContext()->GSSetShader(gsShaderToSet, NULL, 0); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set geometry shader\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgram"); + }*/ - mDepthStencilDesc.FrontFace.StencilFunc = D3D11Mappings::get(func); - mDepthStencilDesc.BackFace.StencilFunc = D3D11Mappings::get(func); + } + break; + case GPT_HULL_PROGRAM: + { + mBoundTessellationHullProgram = static_cast(prg); +/* ID3D11HullShader* gsShaderToSet = mBoundTessellationHullProgram->getHullShader(); - mStencilRef = refValue; - mDepthStencilDesc.StencilReadMask = compareMask; - mDepthStencilDesc.StencilWriteMask = writeMask; + mDevice.GetImmediateContext()->HSSetShader(gsShaderToSet, NULL, 0); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set hull shader\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgram"); + } */ - mDepthStencilDesc.FrontFace.StencilFailOp = D3D11Mappings::get(stencilFailOp, flip); - mDepthStencilDesc.BackFace.StencilFailOp = D3D11Mappings::get(stencilFailOp, !flip); - - mDepthStencilDesc.FrontFace.StencilDepthFailOp = D3D11Mappings::get(depthFailOp, flip); - mDepthStencilDesc.BackFace.StencilDepthFailOp = D3D11Mappings::get(depthFailOp, !flip); - - mDepthStencilDesc.FrontFace.StencilPassOp = D3D11Mappings::get(passOp, flip); - mDepthStencilDesc.BackFace.StencilPassOp = D3D11Mappings::get(passOp, !flip); + } + break; + case GPT_DOMAIN_PROGRAM: + { + mBoundTessellationDomainProgram = static_cast(prg); +/* ID3D11DomainShader* gsShaderToSet = mBoundTessellationDomainProgram->getDomainShader(); - if (!twoSidedOperation) - { - mDepthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_NEVER; - } + mDevice.GetImmediateContext()->DSSetShader(gsShaderToSet, NULL, 0); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set domain shader\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgram"); + }*/ - mReadBackAsTexture = readBackAsTexture; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTextureUnitFiltering(size_t unit, FilterType ftype, - FilterOptions filter) - { - switch(ftype) { - case FT_MIN: - FilterMinification[unit] = filter; - break; - case FT_MAG: - FilterMagnification[unit] = filter; - break; - case FT_MIP: - FilterMips[unit] = filter; - break; - } - - mTexStageDesc[unit].samplerDesc.Filter = D3D11Mappings::get(FilterMinification[unit], FilterMagnification[unit], FilterMips[unit],CompareEnabled); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTextureUnitCompareEnabled(size_t unit, bool compare) - { - CompareEnabled = compare; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTextureUnitCompareFunction(size_t unit, CompareFunction function) - { - mTexStageDesc[unit].samplerDesc.ComparisonFunc = D3D11Mappings::get(function); - } - //--------------------------------------------------------------------- - DWORD D3D11RenderSystem::_getCurrentAnisotropy(size_t unit) - { - return mTexStageDesc[unit].samplerDesc.MaxAnisotropy;; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) - { - mTexStageDesc[unit].samplerDesc.MaxAnisotropy = maxAnisotropy; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setRenderTarget(RenderTarget *target) - { - mActiveRenderTarget = target; - if (mActiveRenderTarget) - { - // we need to clear the state - mDevice.GetImmediateContext()->ClearState(); - - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot Clear State\nError Description:" + errorDescription, - "D3D11RenderSystem::_setRenderTarget"); - } - - _setRenderTargetViews(); - } - } - - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setRenderTargetViews() - { - RenderTarget *target = mActiveRenderTarget; - - if (target) - { - ID3D11RenderTargetView * pRTView[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - memset(pRTView, 0, sizeof(pRTView)); - - target->getCustomAttribute( "ID3D11RenderTargetView", &pRTView ); - - uint numberOfViews; - target->getCustomAttribute( "numberOfViews", &numberOfViews ); - - //Retrieve depth buffer - D3D11DepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); - - if( target->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH && !depthBuffer ) - { - //Depth is automatically managed and there is no depth buffer attached to this RT - //or the Current D3D device doesn't match the one this Depth buffer was created - setDepthBufferFor( target ); - } - - //Retrieve depth buffer again (it may have changed) - depthBuffer = static_cast(target->getDepthBuffer()); - - // now switch to the new render target - mDevice.GetImmediateContext()->OMSetRenderTargets( - numberOfViews, - pRTView, - depthBuffer ? depthBuffer->getDepthStencilView() : 0 ); - - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set render target\nError Description:" + errorDescription, - "D3D11RenderSystem::_setRenderTargetViews"); - } - } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_setViewport( Viewport *vp ) - { - if (!vp) - { - mActiveViewport = NULL; - _setRenderTarget(NULL); - } - else if( vp != mActiveViewport || vp->_isUpdated() ) - { - mActiveViewport = vp; - - // ok, it's different, time to set render target and viewport params - D3D11_VIEWPORT d3dvp; - - // Set render target - RenderTarget* target; - target = vp->getTarget(); - - _setRenderTarget(target); - _setCullingMode( mCullingMode ); - - // set viewport dimensions - d3dvp.TopLeftX = static_cast(vp->getActualLeft()); - d3dvp.TopLeftY = static_cast(vp->getActualTop()); - d3dvp.Width = static_cast(vp->getActualWidth()); - d3dvp.Height = static_cast(vp->getActualHeight()); - if (target->requiresTextureFlipping()) - { - // Convert "top-left" to "bottom-left" - d3dvp.TopLeftY = target->getHeight() - d3dvp.Height - d3dvp.TopLeftY; } + break; + case GPT_COMPUTE_PROGRAM: + { + mBoundComputeProgram = static_cast(prg); +/* ID3D11ComputeShader* gsShaderToSet = mBoundComputeProgram->getComputeShader(); - // Z-values from 0.0 to 1.0 (TODO: standardise with OpenGL) - d3dvp.MinDepth = 0.0f; - d3dvp.MaxDepth = 1.0f; - - mDevice.GetImmediateContext()->RSSetViewports(1, &d3dvp); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set viewports\nError Description:" + errorDescription, - "D3D11RenderSystem::_setViewport"); - } - - // Set sRGB write mode - //__SetRenderState(D3DRS_SRGBWRITEENABLE, target->isHardwareGammaEnabled()); - // TODO where has sRGB state gone? - - vp->_clearUpdatedFlag(); - } -#if OGRE_PLATFORM == OGRE_PLATFORM_WINRT - // as swapchain was created with DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL we need to reestablish render target views - else - { - _setRenderTargetViews(); - } -#endif - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_beginFrame() - { - - if( !mActiveViewport ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Cannot begin frame - no viewport selected.", "D3D11RenderSystem::_beginFrame" ); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_endFrame() - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setVertexDeclaration(VertexDeclaration* decl) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Cannot directly call setVertexDeclaration in the d3d11 render system - cast then use 'setVertexDeclaration(VertexDeclaration* decl, VertexBufferBinding* binding)' .", - "D3D11RenderSystem::setVertexDeclaration" ); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setVertexDeclaration(VertexDeclaration* decl, VertexBufferBinding* binding) - { - D3D11VertexDeclaration* d3ddecl = - static_cast(decl); - - d3ddecl->bindToShader(mBoundVertexProgram, binding); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setVertexBufferBinding(VertexBufferBinding* binding) - { - // TODO: attempt to detect duplicates - const VertexBufferBinding::VertexBufferBindingMap& binds = binding->getBindings(); - VertexBufferBinding::VertexBufferBindingMap::const_iterator i, iend; - iend = binds.end(); - for (i = binds.begin(); i != iend; ++i) - { - const D3D11HardwareVertexBuffer* d3d11buf = - static_cast(i->second.get()); - - UINT stride = static_cast(d3d11buf->getVertexSize()); - UINT offset = 0; // no stream offset, this is handled in _render instead - UINT slot = static_cast(i->first); - ID3D11Buffer * pVertexBuffers = d3d11buf->getD3DVertexBuffer(); - mDevice.GetImmediateContext()->IASetVertexBuffers( - slot, // The first input slot for binding. - 1, // The number of vertex buffers in the array. - &pVertexBuffers, - &stride, - &offset - ); - - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set vertex buffers\nError Description:" + errorDescription, - "D3D11RenderSystem::setVertexBufferBinding"); - } - } - - mLastVertexSourceCount = binds.size(); - } - - //--------------------------------------------------------------------- - // TODO: Move this class to the right place. - class D3D11RenderOperationState : public Renderable::RenderSystemData - { - public: - ID3D11BlendState * mBlendState; - ID3D11RasterizerState * mRasterizer; - ID3D11DepthStencilState * mDepthStencilState; - - ID3D11SamplerState * mSamplerStates[OGRE_MAX_TEXTURE_LAYERS]; - size_t mSamplerStatesCount; - - ID3D11ShaderResourceView * mTextures[OGRE_MAX_TEXTURE_LAYERS]; - size_t mTexturesCount; - - D3D11RenderOperationState() : - mBlendState(NULL) - , mRasterizer(NULL) - , mDepthStencilState(NULL) - , mSamplerStatesCount(0) - , mTexturesCount(0) - { - for (size_t i = 0 ; i < OGRE_MAX_TEXTURE_LAYERS ; i++) - { - mSamplerStates[i] = 0; - } - } - - - ~D3D11RenderOperationState() - { - SAFE_RELEASE( mBlendState ); - SAFE_RELEASE( mRasterizer ); - SAFE_RELEASE( mDepthStencilState ); - - for (size_t i = 0 ; i < OGRE_MAX_TEXTURE_LAYERS ; i++) - { - SAFE_RELEASE( mSamplerStates[i] ); - } - } - }; + mDevice.GetImmediateContext()->CSSetShader(gsShaderToSet, NULL, 0); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set compute shader\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgram"); + }*/ + } + break; + }; + + RenderSystem::bindGpuProgram(prg); + } //--------------------------------------------------------------------- - void D3D11RenderSystem::_render(const RenderOperation& op) - { + void D3D11RenderSystem::unbindGpuProgram(GpuProgramType gptype) + { + + switch(gptype) + { + case GPT_VERTEX_PROGRAM: + { + mActiveVertexGpuProgramParameters.setNull(); + mBoundVertexProgram = NULL; + //mDevice->VSSetShader(NULL); + mDevice.GetImmediateContext()->VSSetShader(NULL, NULL, 0); + } + break; + case GPT_FRAGMENT_PROGRAM: + { + mActiveFragmentGpuProgramParameters.setNull(); + mBoundFragmentProgram = NULL; + //mDevice->PSSetShader(NULL); + mDevice.GetImmediateContext()->PSSetShader(NULL, NULL, 0); + } - // Exit immediately if there is nothing to render - if (op.vertexData==0 || op.vertexData->vertexCount == 0) + break; + case GPT_GEOMETRY_PROGRAM: + { + mActiveGeometryGpuProgramParameters.setNull(); + mBoundGeometryProgram = NULL; + mDevice.GetImmediateContext()->GSSetShader( NULL, NULL, 0 ); + } + break; + case GPT_HULL_PROGRAM: + { + mActiveGeometryGpuProgramParameters.setNull(); + mBoundTessellationHullProgram = NULL; + mDevice.GetImmediateContext()->HSSetShader( NULL, NULL, 0 ); + } + break; + case GPT_DOMAIN_PROGRAM: + { + mActiveGeometryGpuProgramParameters.setNull(); + mBoundTessellationDomainProgram = NULL; + mDevice.GetImmediateContext()->DSSetShader( NULL, NULL, 0 ); + } + break; + case GPT_COMPUTE_PROGRAM: + { + mActiveGeometryGpuProgramParameters.setNull(); + mBoundComputeProgram = NULL; + mDevice.GetImmediateContext()->CSSetShader( NULL, NULL, 0 ); + } + break; + default: + assert(false && "Undefined Program Type!"); + }; + RenderSystem::unbindGpuProgram(gptype); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params, uint16 mask) + { + if (mask & (uint16)GPV_GLOBAL) { - return; + // TODO: Dx11 supports shared constant buffers, so use them + // check the match to constant buffers & use rendersystem data hooks to store + // for now, just copy + params->_copySharedParams(); } - HardwareVertexBufferSharedPtr globalInstanceVertexBuffer = getGlobalInstanceVertexBuffer(); - VertexDeclaration* globalVertexDeclaration = getGlobalInstanceVertexBufferVertexDeclaration(); + // Do everything here in Dx11, since deal with via buffers anyway so number of calls + // is actually the same whether we categorise the updates or not + ID3D11Buffer* pBuffers[1] ; + switch(gptype) + { + case GPT_VERTEX_PROGRAM: + { + // if (params->getAutoConstantCount() > 0) + //{ + if (mBoundVertexProgram) + { + pBuffers[0] = mBoundVertexProgram->getConstantBuffer(params, mask); + mDevice.GetImmediateContext()->VSSetConstantBuffers( 0, 1, pBuffers ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set vertex shader constant buffers\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgramParameters"); + } - bool hasInstanceData = op.useGlobalInstancingVertexBufferIsAvailable && - !globalInstanceVertexBuffer.isNull() && globalVertexDeclaration != NULL - || op.vertexData->vertexBufferBinding->getHasInstanceData(); + } + } + break; + case GPT_FRAGMENT_PROGRAM: + { + //if (params->getAutoConstantCount() > 0) + //{ + if (mBoundFragmentProgram) + { + pBuffers[0] = mBoundFragmentProgram->getConstantBuffer(params, mask); + mDevice.GetImmediateContext()->PSSetConstantBuffers( 0, 1, pBuffers ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set fragment shader constant buffers\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgramParameters"); + } - size_t numberOfInstances = op.numberOfInstances; + } + } + break; + case GPT_GEOMETRY_PROGRAM: + { + if (mBoundGeometryProgram) + { + pBuffers[0] = mBoundGeometryProgram->getConstantBuffer(params, mask); + mDevice.GetImmediateContext()->GSSetConstantBuffers( 0, 1, pBuffers ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set Geometry shader constant buffers\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgramParameters"); + } - if (op.useGlobalInstancingVertexBufferIsAvailable) - { - numberOfInstances *= getGlobalNumberOfInstances(); - } + } + } + break; + case GPT_HULL_PROGRAM: + { + if (mBoundTessellationHullProgram) + { + pBuffers[0] = mBoundTessellationHullProgram->getConstantBuffer(params, mask); + mDevice.GetImmediateContext()->HSSetConstantBuffers( 0, 1, pBuffers ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set Hull shader constant buffers\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgramParameters"); + } - // Call super class - RenderSystem::_render(op); - - D3D11RenderOperationState stackOpState; - D3D11RenderOperationState * opState = &stackOpState; - - //if(!opState) - { - //opState = new D3D11RenderOperationState; - - HRESULT hr = mDevice->CreateBlendState(&mBlendDesc, &opState->mBlendState) ; - if (FAILED(hr)) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Failed to create blend state\nError Description:" + errorDescription, - "D3D11RenderSystem::_render" ); - } - - if (mFeatureLevel < D3D_FEATURE_LEVEL_10_0) + } + } + break; + case GPT_DOMAIN_PROGRAM: { - // should we enable it all the time and not only for lower the level 10? - mRasterizerDesc.DepthClipEnable = true; + if (mBoundTessellationDomainProgram) + { + pBuffers[0] = mBoundTessellationDomainProgram->getConstantBuffer(params, mask); + mDevice.GetImmediateContext()->DSSetConstantBuffers( 0, 1, pBuffers ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set Domain shader constant buffers\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgramParameters"); + } + + } } + break; + case GPT_COMPUTE_PROGRAM: + { + if (mBoundComputeProgram) + { + pBuffers[0] = mBoundComputeProgram->getConstantBuffer(params, mask); + mDevice.GetImmediateContext()->CSSetConstantBuffers( 0, 1, pBuffers ); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set Compute shader constant buffers\nError Description:" + errorDescription, + "D3D11RenderSystem::bindGpuProgramParameters"); + } - hr = mDevice->CreateRasterizerState(&mRasterizerDesc, &opState->mRasterizer) ; - if (FAILED(hr)) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Failed to create rasterizer state\nError Description:" + errorDescription, - "D3D11RenderSystem::_render" ); - } - - hr = mDevice->CreateDepthStencilState(&mDepthStencilDesc, &opState->mDepthStencilState) ; - if (FAILED(hr)) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Failed to create depth stencil state\nError Description:" + errorDescription, - "D3D11RenderSystem::_render" ); - } - - // samplers mapping - size_t numberOfSamplers = OGRE_MAX_TEXTURE_LAYERS + 1; - - //find the maximum number of samplers - while (--numberOfSamplers >= 1 && mTexStageDesc[numberOfSamplers - 1].used == false) ; - - opState->mSamplerStatesCount = numberOfSamplers; - opState->mTexturesCount = numberOfSamplers; - - - - for (size_t n = 0; n < numberOfSamplers; n++) - { - ID3D11SamplerState * samplerState = NULL; - ID3D11ShaderResourceView *texture = NULL; - sD3DTextureStageDesc & stage = mTexStageDesc[n]; - if(!stage.used) - { - samplerState = NULL; - texture = NULL; - } - else - { - texture = stage.pTex; - - stage.samplerDesc.Filter = D3D11Mappings::get(FilterMinification[n], FilterMagnification[n], - FilterMips[n],false ); - stage.samplerDesc.ComparisonFunc = D3D11Mappings::get(mSceneAlphaRejectFunc); - stage.samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; - stage.samplerDesc.MinLOD = 0; - stage.samplerDesc.MipLODBias = 0.f; - stage.currentSamplerDesc = stage.samplerDesc; - - HRESULT hr = mDevice->CreateSamplerState(&stage.samplerDesc, &samplerState) ; - if (FAILED(hr)) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Failed to create sampler state\nError Description:" + errorDescription, - "D3D11RenderSystem::_render" ); - } - - } - opState->mSamplerStates[n] = samplerState; - opState->mTextures[n] = texture; - } - } - - for (size_t n = opState->mTexturesCount; n < OGRE_MAX_TEXTURE_LAYERS; n++) - { - opState->mTextures[n] = NULL; - } - - //if (opState->mBlendState != mBoundBlendState) - { - mBoundBlendState = opState->mBlendState ; - mDevice.GetImmediateContext()->OMSetBlendState(opState->mBlendState, 0, 0xffffffff); // TODO - find out where to get the parameters - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set blend state\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - if (mBoundGeometryProgram && mBindingType == TextureUnitState::BindingType::BT_GEOMETRY) - { - { - mDevice.GetImmediateContext()->GSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set pixel shader samplers\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - mDevice.GetImmediateContext()->GSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - } - - //if (opState->mRasterizer != mBoundRasterizer) - { - mBoundRasterizer = opState->mRasterizer ; - - mDevice.GetImmediateContext()->RSSetState(opState->mRasterizer); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set rasterizer state\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - - - //if (opState->mDepthStencilState != mBoundDepthStencilState) - { - mBoundDepthStencilState = opState->mDepthStencilState ; - - mDevice.GetImmediateContext()->OMSetDepthStencilState(opState->mDepthStencilState, mStencilRef); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set depth stencil state\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - - if (opState->mSamplerStatesCount > 0 ) // if the NumSamplers is 0, the operation effectively does nothing. - { - /// Pixel Shader binding - { - // Assaf: seem I have better performance without this check... TODO - remove? - // if ((mBoundSamplerStatesCount != opState->mSamplerStatesCount) || ( 0 != memcmp(opState->mSamplerStates, mBoundSamplerStates, mBoundSamplerStatesCount) ) ) - { - //mBoundSamplerStatesCount = opState->mSamplerStatesCount; - //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount); - mDevice.GetImmediateContext()->PSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set pixel shader samplers\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - - mDevice.GetImmediateContext()->PSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - - /// Vertex Shader binding - if (mBindingType == TextureUnitState::BindingType::BT_VERTEX) - { - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { - //mBoundSamplerStatesCount = opState->mSamplerStatesCount; - //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount); - mDevice.GetImmediateContext()->VSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set pixel shader samplers\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { - mDevice.GetImmediateContext()->VSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - } - - /// Compute Shader binding - if (mBoundComputeProgram && mBindingType == TextureUnitState::BindingType::BT_COMPUTE) - { - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { - //mBoundSamplerStatesCount = opState->mSamplerStatesCount; - //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount); - mDevice.GetImmediateContext()->CSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set compute shader samplers\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { - mDevice.GetImmediateContext()->CSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set compute shader resources\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - } - - /// Hull Shader binding - if (mBoundTessellationHullProgram && mBindingType == TextureUnitState::BindingType::BT_TESSELLATION_HULL) - { - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { - //mBoundSamplerStatesCount = opState->mSamplerStatesCount; - //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount); - mDevice.GetImmediateContext()->HSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set hull shader samplers\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { - mDevice.GetImmediateContext()->HSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set hull shader resources\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - } - - /// Domain Shader binding - if (mBoundTessellationDomainProgram && mBindingType == TextureUnitState::BindingType::BT_TESSELLATION_DOMAIN) - { - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { - //mBoundSamplerStatesCount = opState->mSamplerStatesCount; - //memcpy(mBoundSamplerStates,opState->mSamplerStates, mBoundSamplerStatesCount); - mDevice.GetImmediateContext()->DSSetSamplers(static_cast(0), static_cast(opState->mSamplerStatesCount), opState->mSamplerStates); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set domain shader samplers\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0) - { - mDevice.GetImmediateContext()->DSSetShaderResources(static_cast(0), static_cast(opState->mTexturesCount), &opState->mTextures[0]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set domain shader resources\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - } - } - - ID3D11Buffer* pSOTarget=0; - // Mustn't bind a emulated vertex, pixel shader (see below), if we are rendering to a stream out buffer - mDevice.GetImmediateContext()->SOGetTargets(1, &pSOTarget); - - //check consistency of vertex-fragment shaders - if (!mBoundVertexProgram || - (!mBoundFragmentProgram && op.operationType != RenderOperation::OT_POINT_LIST && pSOTarget==0 ) - ) - { - - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Attempted to render to a D3D11 device without both vertex and fragment shaders there is no fixed pipeline in d3d11 - use the RTSS or write custom shaders.", - "D3D11RenderSystem::_render"); - } - - // Check consistency of tessellation shaders - if( (mBoundTessellationHullProgram && !mBoundTessellationDomainProgram) || - (!mBoundTessellationHullProgram && mBoundTessellationDomainProgram) ) - { - if (mBoundTessellationHullProgram && !mBoundTessellationDomainProgram) { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Attempted to use tessellation, but domain shader is missing", - "D3D11RenderSystem::_render"); - } - else { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Attempted to use tessellation, but hull shader is missing", - "D3D11RenderSystem::_render"); } - } - - if (mDevice.isError()) - { - // this will never happen but we want to be consistent with the error checks... - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set geometry shader to null\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - - // Defer program bind to here because we must bind shader class instances, - // and this can only be made in SetShader calls. - // Also, bind shader resources - if (mBoundVertexProgram) - { - mDevice.GetImmediateContext()->VSSetShader(mBoundVertexProgram->getVertexShader(), - mClassInstances[GPT_VERTEX_PROGRAM], - mNumClassInstances[GPT_VERTEX_PROGRAM]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set vertex shader\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - if (mBoundFragmentProgram) - { - mDevice.GetImmediateContext()->PSSetShader(mBoundFragmentProgram->getPixelShader(), - mClassInstances[GPT_FRAGMENT_PROGRAM], - mNumClassInstances[GPT_FRAGMENT_PROGRAM]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set pixel shader\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - if (mBoundGeometryProgram) - { - mDevice.GetImmediateContext()->GSSetShader(mBoundGeometryProgram->getGeometryShader(), - mClassInstances[GPT_GEOMETRY_PROGRAM], - mNumClassInstances[GPT_GEOMETRY_PROGRAM]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set geometry shader\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - if (mBoundTessellationHullProgram) - { - mDevice.GetImmediateContext()->HSSetShader(mBoundTessellationHullProgram->getHullShader(), - mClassInstances[GPT_HULL_PROGRAM], - mNumClassInstances[GPT_HULL_PROGRAM]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set hull shader\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - if (mBoundTessellationDomainProgram) - { - mDevice.GetImmediateContext()->DSSetShader(mBoundTessellationDomainProgram->getDomainShader(), - mClassInstances[GPT_DOMAIN_PROGRAM], - mNumClassInstances[GPT_DOMAIN_PROGRAM]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set domain shader\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - if (mBoundComputeProgram) - { - mDevice.GetImmediateContext()->CSSetShader(mBoundComputeProgram->getComputeShader(), - mClassInstances[GPT_COMPUTE_PROGRAM], - mNumClassInstances[GPT_COMPUTE_PROGRAM]); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set compute shader\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - - - setVertexDeclaration(op.vertexData->vertexDeclaration, op.vertexData->vertexBufferBinding); - setVertexBufferBinding(op.vertexData->vertexBufferBinding); - - - // Determine rendering operation - D3D11_PRIMITIVE_TOPOLOGY primType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - DWORD primCount = 0; - - // Handle computing - if(mBoundComputeProgram) - { - // Bound unordered access views - mDevice.GetImmediateContext()->Dispatch(1, 1, 1); - - ID3D11UnorderedAccessView* views[] = { 0 }; - ID3D11ShaderResourceView* srvs[] = { 0 }; - mDevice.GetImmediateContext()->CSSetShaderResources( 0, 1, srvs ); - mDevice.GetImmediateContext()->CSSetUnorderedAccessViews( 0, 1, views, NULL ); - mDevice.GetImmediateContext()->CSSetShader( NULL, NULL, 0 ); - - return; - } - else if(mBoundTessellationHullProgram && mBoundTessellationDomainProgram) - { - // useful primitives for tessellation - switch( op.operationType ) - { - case RenderOperation::OT_LINE_LIST: - primType = D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST; - primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 2; - break; - - case RenderOperation::OT_LINE_STRIP: - primType = D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST; - primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 1; - break; - - case RenderOperation::OT_TRIANGLE_LIST: - primType = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST; - primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 3; - break; - - case RenderOperation::OT_TRIANGLE_STRIP: - primType = D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST; - primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2; - break; - } - } - else - { - //rendering without tessellation. - bool useAdjacency = (mGeometryProgramBound && mBoundGeometryProgram && mBoundGeometryProgram->isAdjacencyInfoRequired()); - switch( op.operationType ) - { - case RenderOperation::OT_POINT_LIST: - primType = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; - primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount); - break; - - case RenderOperation::OT_LINE_LIST: - primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ : D3D11_PRIMITIVE_TOPOLOGY_LINELIST; - primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 2; - break; - - case RenderOperation::OT_LINE_STRIP: - primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ : D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP; - primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 1; - break; - - case RenderOperation::OT_TRIANGLE_LIST: - primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ : D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 3; - break; - - case RenderOperation::OT_TRIANGLE_STRIP: - primType = useAdjacency ? D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ : D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; - primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2; - break; - - case RenderOperation::OT_TRIANGLE_FAN: - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error - DX11 render - no support for triangle fan (OT_TRIANGLE_FAN)", "D3D11RenderSystem::_render"); - primType = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; // todo - no TRIANGLE_FAN in DX 11 - primCount = (DWORD)(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2; - break; - } - } - - if (primCount) - { - // Issue the op - //HRESULT hr; - if( op.useIndexes ) - { - D3D11HardwareIndexBuffer* d3dIdxBuf = - static_cast(op.indexData->indexBuffer.get()); - mDevice.GetImmediateContext()->IASetIndexBuffer( d3dIdxBuf->getD3DIndexBuffer(), D3D11Mappings::getFormat(d3dIdxBuf->getType()), 0 ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set index buffer\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - - do - { - // do indexed draw operation - mDevice.GetImmediateContext()->IASetPrimitiveTopology( primType ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set primitive topology\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - - if (hasInstanceData) - { - mDevice.GetImmediateContext()->DrawIndexedInstanced( - static_cast(op.indexData->indexCount), - static_cast(numberOfInstances), - static_cast(op.indexData->indexStart), - static_cast(op.vertexData->vertexStart), - 0 - ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot draw indexed instanced\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - } - else - { - mDevice.GetImmediateContext()->DrawIndexed( - static_cast(op.indexData->indexCount), - static_cast(op.indexData->indexStart), - static_cast(op.vertexData->vertexStart) - ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot draw indexed\nError Description:" + errorDescription + - "Active OGRE vertex shader name: " + mBoundVertexProgram->getName() + - "\nActive OGRE fragment shader name: " + mBoundFragmentProgram->getName(), - "D3D11RenderSystem::_render"); - } - } - } while (updatePassIterationRenderState()); - } - else - { - // nfz: gpu_iterate - do - { - // Unindexed, a little simpler! - mDevice.GetImmediateContext()->IASetPrimitiveTopology( primType ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set primitive topology\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - - if (op.vertexData->vertexCount == -1) // -1 is a sign to use DrawAuto - { - mDevice.GetImmediateContext()->DrawAuto(); - } - else - { - if (hasInstanceData) - { - mDevice.GetImmediateContext()->DrawInstanced( - static_cast(numberOfInstances), - static_cast(op.vertexData->vertexCount), - static_cast(op.vertexData->vertexStart), - 0 - ); - } - else - { - mDevice.GetImmediateContext()->Draw( - static_cast(op.vertexData->vertexCount), - static_cast(op.vertexData->vertexStart) - ); - } - } - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot draw\nError Description:" + errorDescription, - "D3D11RenderSystem::_render"); - } - - - } while (updatePassIterationRenderState()); - } - } - - - if (true) // for now - clear the render state - { - mDevice.GetImmediateContext()->OMSetBlendState(0, 0, 0xffffffff); - mDevice.GetImmediateContext()->RSSetState(0); - mDevice.GetImmediateContext()->OMSetDepthStencilState(0, 0); -// mDevice->PSSetSamplers(static_cast(0), static_cast(0), 0); - - // Clear class instance storage - memset(mClassInstances, 0, sizeof(mClassInstances)); - memset(mNumClassInstances, 0, sizeof(mNumClassInstances)); - } - - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::_renderUsingReadBackAsTexture(unsigned int passNr, Ogre::String variableName, unsigned int StartSlot) - { - RenderTarget *target = mActiveRenderTarget; - switch (passNr) - { - case 1: - if (target) - { - ID3D11RenderTargetView * pRTView[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - memset(pRTView, 0, sizeof(pRTView)); - - target->getCustomAttribute( "ID3D11RenderTargetView", &pRTView ); - - uint numberOfViews; - target->getCustomAttribute( "numberOfViews", &numberOfViews ); - - //Retrieve depth buffer - D3D11DepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); - - // now switch to the new render target - mDevice.GetImmediateContext()->OMSetRenderTargets( - numberOfViews, - pRTView, - depthBuffer->getDepthStencilView()); - - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set render target\nError Description:" + errorDescription, - "D3D11RenderSystem::_renderUsingReadBackAsTexture"); - } - - mDevice.GetImmediateContext()->ClearDepthStencilView(depthBuffer->getDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0); - - float ClearColor[4]; - //D3D11Mappings::get(colour, ClearColor); - // Clear all views - mActiveRenderTarget->getCustomAttribute( "numberOfViews", &numberOfViews ); - if( numberOfViews == 1 ) - mDevice.GetImmediateContext()->ClearRenderTargetView( pRTView[0], ClearColor ); - else - { - for( uint i = 0; i < numberOfViews; ++i ) - mDevice.GetImmediateContext()->ClearRenderTargetView( pRTView[i], ClearColor ); - } - - } - break; - case 2: - if (target) - { - // - // We need to remove the the DST from the Render Targets if we want to use it as a texture : - // - ID3D11RenderTargetView * pRTView[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - memset(pRTView, 0, sizeof(pRTView)); - - target->getCustomAttribute( "ID3D11RenderTargetView", &pRTView ); - - uint numberOfViews; - target->getCustomAttribute( "numberOfViews", &numberOfViews ); - - //Retrieve depth buffer - D3D11DepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); - - // now switch to the new render target - mDevice.GetImmediateContext()->OMSetRenderTargets( - numberOfViews, - pRTView, - NULL); - //mTextureManager->mEffect->GetVariableByName(variableName.c_str())->AsShaderResource()->SetResource(mDSTResView); - - mDevice.GetImmediateContext()->PSSetShaderResources(static_cast(StartSlot), static_cast(numberOfViews), &mDSTResView); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription, - "D3D11RenderSystem::_renderUsingReadBackAsTexture"); - } - - } - break; - case 3: - // - // We need to unbind mDSTResView from the given variable because this buffer - // will be used later as the typical depth buffer, again - // must call Apply(0) here : to flush SetResource(NULL) - // - - if (target) - { - uint numberOfViews; - target->getCustomAttribute( "numberOfViews", &numberOfViews ); - - mDevice.GetImmediateContext()->PSSetShaderResources(static_cast(StartSlot), static_cast(numberOfViews), NULL); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set pixel shader resources\nError Description:" + errorDescription, - "D3D11RenderSystem::_renderUsingReadBackAsTexture"); - } - } - - break; - } - } + } + } + break; + }; + + // Now, set class instances + const GpuProgramParameters::SubroutineMap& subroutineMap = params->getSubroutineMap(); + if (subroutineMap.empty()) + return; + + GpuProgramParameters::SubroutineIterator it; + GpuProgramParameters::SubroutineIterator end = subroutineMap.end(); + for(it = subroutineMap.begin(); it != end; ++it) + { + setSubroutine(gptype, it->first, it->second); + } + } //--------------------------------------------------------------------- - void D3D11RenderSystem::setNormaliseNormals(bool normalise) - { - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::bindGpuProgram(GpuProgram* prg) - { - if (!prg) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Null program bound.", - "D3D11RenderSystem::bindGpuProgram"); - } - - switch (prg->getType()) - { - case GPT_VERTEX_PROGRAM: - { - // get the shader - mBoundVertexProgram = static_cast(prg); -/* ID3D11VertexShader * vsShaderToSet = mBoundVertexProgram->getVertexShader(); - - // set the shader - mDevice.GetImmediateContext()->VSSetShader(vsShaderToSet, NULL, 0); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set vertex shader\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgram"); - }*/ - } - break; - case GPT_FRAGMENT_PROGRAM: - { - mBoundFragmentProgram = static_cast(prg); -/* ID3D11PixelShader* psShaderToSet = mBoundFragmentProgram->getPixelShader(); - - mDevice.GetImmediateContext()->PSSetShader(psShaderToSet, NULL, 0); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set fragment shader\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgram"); - }*/ - } - break; - case GPT_GEOMETRY_PROGRAM: - { - mBoundGeometryProgram = static_cast(prg); -/* ID3D11GeometryShader* gsShaderToSet = mBoundGeometryProgram->getGeometryShader(); - - mDevice.GetImmediateContext()->GSSetShader(gsShaderToSet, NULL, 0); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set geometry shader\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgram"); - }*/ - - } - break; - case GPT_HULL_PROGRAM: - { - mBoundTessellationHullProgram = static_cast(prg); -/* ID3D11HullShader* gsShaderToSet = mBoundTessellationHullProgram->getHullShader(); - - mDevice.GetImmediateContext()->HSSetShader(gsShaderToSet, NULL, 0); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set hull shader\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgram"); - } */ - - } - break; - case GPT_DOMAIN_PROGRAM: - { - mBoundTessellationDomainProgram = static_cast(prg); -/* ID3D11DomainShader* gsShaderToSet = mBoundTessellationDomainProgram->getDomainShader(); - - mDevice.GetImmediateContext()->DSSetShader(gsShaderToSet, NULL, 0); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set domain shader\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgram"); - }*/ - - } - break; - case GPT_COMPUTE_PROGRAM: - { - mBoundComputeProgram = static_cast(prg); -/* ID3D11ComputeShader* gsShaderToSet = mBoundComputeProgram->getComputeShader(); - - mDevice.GetImmediateContext()->CSSetShader(gsShaderToSet, NULL, 0); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set compute shader\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgram"); - }*/ - - } - break; - }; - - RenderSystem::bindGpuProgram(prg); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::unbindGpuProgram(GpuProgramType gptype) + void D3D11RenderSystem::bindGpuProgramPassIterationParameters(GpuProgramType gptype) { - switch(gptype) - { - case GPT_VERTEX_PROGRAM: - { - mActiveVertexGpuProgramParameters.setNull(); - mBoundVertexProgram = NULL; - //mDevice->VSSetShader(NULL); - mDevice.GetImmediateContext()->VSSetShader(NULL, NULL, 0); - } - break; - case GPT_FRAGMENT_PROGRAM: - { - mActiveFragmentGpuProgramParameters.setNull(); - mBoundFragmentProgram = NULL; - //mDevice->PSSetShader(NULL); - mDevice.GetImmediateContext()->PSSetShader(NULL, NULL, 0); - } - - break; - case GPT_GEOMETRY_PROGRAM: - { - mActiveGeometryGpuProgramParameters.setNull(); - mBoundGeometryProgram = NULL; - mDevice.GetImmediateContext()->GSSetShader( NULL, NULL, 0 ); - } - break; - case GPT_HULL_PROGRAM: - { - mActiveGeometryGpuProgramParameters.setNull(); - mBoundTessellationHullProgram = NULL; - mDevice.GetImmediateContext()->HSSetShader( NULL, NULL, 0 ); - } - break; - case GPT_DOMAIN_PROGRAM: - { - mActiveGeometryGpuProgramParameters.setNull(); - mBoundTessellationDomainProgram = NULL; - mDevice.GetImmediateContext()->DSSetShader( NULL, NULL, 0 ); - } - break; - case GPT_COMPUTE_PROGRAM: - { - mActiveGeometryGpuProgramParameters.setNull(); - mBoundComputeProgram = NULL; - mDevice.GetImmediateContext()->CSSetShader( NULL, NULL, 0 ); - } - break; - default: - assert(false && "Undefined Program Type!"); - }; - RenderSystem::unbindGpuProgram(gptype); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params, uint16 mask) - { - if (mask & (uint16)GPV_GLOBAL) - { - // TODO: Dx11 supports shared constant buffers, so use them - // check the match to constant buffers & use rendersystem data hooks to store - // for now, just copy - params->_copySharedParams(); - } - - // Do everything here in Dx11, since deal with via buffers anyway so number of calls - // is actually the same whether we categorise the updates or not - ID3D11Buffer* pBuffers[1] ; - switch(gptype) - { - case GPT_VERTEX_PROGRAM: - { - // if (params->getAutoConstantCount() > 0) - //{ - if (mBoundVertexProgram) - { - pBuffers[0] = mBoundVertexProgram->getConstantBuffer(params, mask); - mDevice.GetImmediateContext()->VSSetConstantBuffers( 0, 1, pBuffers ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set vertex shader constant buffers\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgramParameters"); - } - - } - } - break; - case GPT_FRAGMENT_PROGRAM: - { - //if (params->getAutoConstantCount() > 0) - //{ - if (mBoundFragmentProgram) - { - pBuffers[0] = mBoundFragmentProgram->getConstantBuffer(params, mask); - mDevice.GetImmediateContext()->PSSetConstantBuffers( 0, 1, pBuffers ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set fragment shader constant buffers\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgramParameters"); - } - - } - } - break; - case GPT_GEOMETRY_PROGRAM: - { - if (mBoundGeometryProgram) - { - pBuffers[0] = mBoundGeometryProgram->getConstantBuffer(params, mask); - mDevice.GetImmediateContext()->GSSetConstantBuffers( 0, 1, pBuffers ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set Geometry shader constant buffers\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgramParameters"); - } - - } - } - break; - case GPT_HULL_PROGRAM: - { - if (mBoundTessellationHullProgram) - { - pBuffers[0] = mBoundTessellationHullProgram->getConstantBuffer(params, mask); - mDevice.GetImmediateContext()->HSSetConstantBuffers( 0, 1, pBuffers ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set Hull shader constant buffers\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgramParameters"); - } - - } - } - break; - case GPT_DOMAIN_PROGRAM: - { - if (mBoundTessellationDomainProgram) - { - pBuffers[0] = mBoundTessellationDomainProgram->getConstantBuffer(params, mask); - mDevice.GetImmediateContext()->DSSetConstantBuffers( 0, 1, pBuffers ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set Domain shader constant buffers\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgramParameters"); - } - - } - } - break; - case GPT_COMPUTE_PROGRAM: - { - if (mBoundComputeProgram) - { - pBuffers[0] = mBoundComputeProgram->getConstantBuffer(params, mask); - mDevice.GetImmediateContext()->CSSetConstantBuffers( 0, 1, pBuffers ); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set Compute shader constant buffers\nError Description:" + errorDescription, - "D3D11RenderSystem::bindGpuProgramParameters"); - } - - } - } - break; - }; - - // Now, set class instances - const GpuProgramParameters::SubroutineMap& subroutineMap = params->getSubroutineMap(); - if (subroutineMap.empty()) - return; - - GpuProgramParameters::SubroutineIterator it; - GpuProgramParameters::SubroutineIterator end = subroutineMap.end(); - for(it = subroutineMap.begin(); it != end; ++it) - { - setSubroutine(gptype, it->first, it->second); - } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::bindGpuProgramPassIterationParameters(GpuProgramType gptype) + switch(gptype) + { + case GPT_VERTEX_PROGRAM: + bindGpuProgramParameters(gptype, mActiveVertexGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); + break; + + case GPT_FRAGMENT_PROGRAM: + bindGpuProgramParameters(gptype, mActiveFragmentGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); + break; + case GPT_GEOMETRY_PROGRAM: + bindGpuProgramParameters(gptype, mActiveGeometryGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); + break; + case GPT_HULL_PROGRAM: + bindGpuProgramParameters(gptype, mActiveTessellationHullGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); + break; + case GPT_DOMAIN_PROGRAM: + bindGpuProgramParameters(gptype, mActiveTessellationDomainGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); + break; + case GPT_COMPUTE_PROGRAM: + bindGpuProgramParameters(gptype, mActiveComputeGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); + break; + } + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setSubroutine(GpuProgramType gptype, unsigned int slotIndex, const String& subroutineName) { + ID3D11ClassInstance* instance = 0; + + ClassInstanceIterator it = mInstanceMap.find(subroutineName); + if (it == mInstanceMap.end()) + { + // try to get instance already created (must have at least one field) + HRESULT hr = mDevice.GetClassLinkage()->GetClassInstance(subroutineName.c_str(), 0, &instance); + if (FAILED(hr) || instance == 0) + { + // probably class don't have a field, try create a new + hr = mDevice.GetClassLinkage()->CreateClassInstance(subroutineName.c_str(), 0, 0, 0, 0, &instance); + if (FAILED(hr) || instance == 0) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Shader subroutine with name " + subroutineName + " doesn't exist.", + "D3D11RenderSystem::setSubroutineName"); + } + } - switch(gptype) - { - case GPT_VERTEX_PROGRAM: - bindGpuProgramParameters(gptype, mActiveVertexGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); - break; - - case GPT_FRAGMENT_PROGRAM: - bindGpuProgramParameters(gptype, mActiveFragmentGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); - break; - case GPT_GEOMETRY_PROGRAM: - bindGpuProgramParameters(gptype, mActiveGeometryGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); - break; - case GPT_HULL_PROGRAM: - bindGpuProgramParameters(gptype, mActiveTessellationHullGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); - break; - case GPT_DOMAIN_PROGRAM: - bindGpuProgramParameters(gptype, mActiveTessellationDomainGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); - break; - case GPT_COMPUTE_PROGRAM: - bindGpuProgramParameters(gptype, mActiveComputeGpuProgramParameters, (uint16)GPV_PASS_ITERATION_NUMBER); - break; - } - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setSubroutine(GpuProgramType gptype, unsigned int slotIndex, const String& subroutineName) - { - ID3D11ClassInstance* instance = 0; - - ClassInstanceIterator it = mInstanceMap.find(subroutineName); - if (it == mInstanceMap.end()) - { - // try to get instance already created (must have at least one field) - HRESULT hr = mDevice.GetClassLinkage()->GetClassInstance(subroutineName.c_str(), 0, &instance); - if (FAILED(hr) || instance == 0) - { - // probably class don't have a field, try create a new - hr = mDevice.GetClassLinkage()->CreateClassInstance(subroutineName.c_str(), 0, 0, 0, 0, &instance); - if (FAILED(hr) || instance == 0) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Shader subroutine with name " + subroutineName + " doesn't exist.", - "D3D11RenderSystem::setSubroutineName"); - } - } - - // Store class instance - mInstanceMap.insert(std::make_pair(subroutineName, instance)); - } - else - { - instance = it->second; - } - - // If already created, store class instance - mClassInstances[gptype][slotIndex] = instance; - mNumClassInstances[gptype] = mNumClassInstances[gptype] + 1; - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setSubroutine(GpuProgramType gptype, const String& slotName, const String& subroutineName) - { - unsigned int slotIdx = 0; - switch(gptype) - { - case GPT_VERTEX_PROGRAM: - { - if (mBoundVertexProgram) - { - slotIdx = mBoundVertexProgram->getSubroutineSlot(slotName); - } - } - break; - case GPT_FRAGMENT_PROGRAM: - { - if (mBoundFragmentProgram) - { - slotIdx = mBoundFragmentProgram->getSubroutineSlot(slotName); - } - } - break; - case GPT_GEOMETRY_PROGRAM: - { - if (mBoundGeometryProgram) - { - slotIdx = mBoundGeometryProgram->getSubroutineSlot(slotName); - } - } - break; - case GPT_HULL_PROGRAM: - { - if (mBoundTessellationHullProgram) - { - slotIdx = mBoundTessellationHullProgram->getSubroutineSlot(slotName); - } - } - break; - case GPT_DOMAIN_PROGRAM: - { - if (mBoundTessellationDomainProgram) - { - slotIdx = mBoundTessellationDomainProgram->getSubroutineSlot(slotName); - } - } - break; - case GPT_COMPUTE_PROGRAM: - { - if (mBoundComputeProgram) - { - slotIdx = mBoundComputeProgram->getSubroutineSlot(slotName); - } - } - break; - }; - - // Set subroutine for slot - setSubroutine(gptype, slotIdx, subroutineName); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::setClipPlanesImpl(const PlaneList& clipPlanes) - { - } - //--------------------------------------------------------------------- + // Store class instance + mInstanceMap.insert(std::make_pair(subroutineName, instance)); + } + else + { + instance = it->second; + } + + // If already created, store class instance + mClassInstances[gptype][slotIndex] = instance; + mNumClassInstances[gptype] = mNumClassInstances[gptype] + 1; + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setSubroutine(GpuProgramType gptype, const String& slotName, const String& subroutineName) + { + unsigned int slotIdx = 0; + switch(gptype) + { + case GPT_VERTEX_PROGRAM: + { + if (mBoundVertexProgram) + { + slotIdx = mBoundVertexProgram->getSubroutineSlot(slotName); + } + } + break; + case GPT_FRAGMENT_PROGRAM: + { + if (mBoundFragmentProgram) + { + slotIdx = mBoundFragmentProgram->getSubroutineSlot(slotName); + } + } + break; + case GPT_GEOMETRY_PROGRAM: + { + if (mBoundGeometryProgram) + { + slotIdx = mBoundGeometryProgram->getSubroutineSlot(slotName); + } + } + break; + case GPT_HULL_PROGRAM: + { + if (mBoundTessellationHullProgram) + { + slotIdx = mBoundTessellationHullProgram->getSubroutineSlot(slotName); + } + } + break; + case GPT_DOMAIN_PROGRAM: + { + if (mBoundTessellationDomainProgram) + { + slotIdx = mBoundTessellationDomainProgram->getSubroutineSlot(slotName); + } + } + break; + case GPT_COMPUTE_PROGRAM: + { + if (mBoundComputeProgram) + { + slotIdx = mBoundComputeProgram->getSubroutineSlot(slotName); + } + } + break; + }; + + // Set subroutine for slot + setSubroutine(gptype, slotIdx, subroutineName); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::setClipPlanesImpl(const PlaneList& clipPlanes) + { + } + //--------------------------------------------------------------------- void D3D11RenderSystem::setScissorTest(bool enabled, size_t left, size_t top, size_t right, size_t bottom) { - mRasterizerDesc.ScissorEnable = enabled; - mScissorRect.left = static_cast(left); - mScissorRect.top = static_cast(top); - mScissorRect.right = static_cast(right); - mScissorRect.bottom =static_cast( bottom); - - mDevice.GetImmediateContext()->RSSetScissorRects(1, &mScissorRect); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot set scissor rects\nError Description:" + errorDescription, - "D3D11RenderSystem::setScissorTest"); - } - } + mRasterizerDesc.ScissorEnable = enabled; + mScissorRect.left = static_cast(left); + mScissorRect.top = static_cast(top); + mScissorRect.right = static_cast(right); + mScissorRect.bottom =static_cast( bottom); + + mDevice.GetImmediateContext()->RSSetScissorRects(1, &mScissorRect); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot set scissor rects\nError Description:" + errorDescription, + "D3D11RenderSystem::setScissorTest"); + } + } //--------------------------------------------------------------------- void D3D11RenderSystem::clearFrameBuffer(unsigned int buffers, const ColourValue& colour, Real depth, unsigned short stencil) { - if (mActiveRenderTarget) - { - ID3D11RenderTargetView * pRTView[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - memset(pRTView, 0, sizeof(pRTView)); - - mActiveRenderTarget->getCustomAttribute( "ID3D11RenderTargetView", &pRTView ); - - if (buffers & FBT_COLOUR) - { - float ClearColor[4]; - D3D11Mappings::get(colour, ClearColor); - - // Clear all views - uint numberOfViews; - mActiveRenderTarget->getCustomAttribute( "numberOfViews", &numberOfViews ); - if( numberOfViews == 1 ) - mDevice.GetImmediateContext()->ClearRenderTargetView( pRTView[0], ClearColor ); - else - { - for( uint i = 0; i < numberOfViews; ++i ) - mDevice.GetImmediateContext()->ClearRenderTargetView( pRTView[i], ClearColor ); - } - - } - UINT ClearFlags = 0; - if (buffers & FBT_DEPTH) - { - ClearFlags |= D3D11_CLEAR_DEPTH; - } - if (buffers & FBT_STENCIL) - { - ClearFlags |= D3D11_CLEAR_STENCIL; - } - - if (ClearFlags) - { - D3D11DepthBuffer *depthBuffer = static_cast(mActiveRenderTarget-> - getDepthBuffer()); - if( depthBuffer ) - { - mDevice.GetImmediateContext()->ClearDepthStencilView( - depthBuffer->getDepthStencilView(), - ClearFlags, depth, static_cast(stencil) ); - } - } - } - } + if (mActiveRenderTarget) + { + ID3D11RenderTargetView * pRTView[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + memset(pRTView, 0, sizeof(pRTView)); + + mActiveRenderTarget->getCustomAttribute( "ID3D11RenderTargetView", &pRTView ); + + if (buffers & FBT_COLOUR) + { + float ClearColor[4]; + D3D11Mappings::get(colour, ClearColor); + + // Clear all views + uint numberOfViews; + mActiveRenderTarget->getCustomAttribute( "numberOfViews", &numberOfViews ); + if( numberOfViews == 1 ) + mDevice.GetImmediateContext()->ClearRenderTargetView( pRTView[0], ClearColor ); + else + { + for( uint i = 0; i < numberOfViews; ++i ) + mDevice.GetImmediateContext()->ClearRenderTargetView( pRTView[i], ClearColor ); + } + + } + UINT ClearFlags = 0; + if (buffers & FBT_DEPTH) + { + ClearFlags |= D3D11_CLEAR_DEPTH; + } + if (buffers & FBT_STENCIL) + { + ClearFlags |= D3D11_CLEAR_STENCIL; + } + + if (ClearFlags) + { + D3D11DepthBuffer *depthBuffer = static_cast(mActiveRenderTarget-> + getDepthBuffer()); + if( depthBuffer ) + { + mDevice.GetImmediateContext()->ClearDepthStencilView( + depthBuffer->getDepthStencilView(), + ClearFlags, depth, static_cast(stencil) ); + } + } + } + } //--------------------------------------------------------------------- void D3D11RenderSystem::_makeProjectionMatrix(Real left, Real right, Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest, @@ -3667,21 +3667,21 @@ namespace Ogre //--------------------------------------------------------------------- HardwareOcclusionQuery* D3D11RenderSystem::createHardwareOcclusionQuery(void) { - D3D11HardwareOcclusionQuery* ret = new D3D11HardwareOcclusionQuery (mDevice); - mHwOcclusionQueries.push_back(ret); - return ret; + D3D11HardwareOcclusionQuery* ret = new D3D11HardwareOcclusionQuery (mDevice); + mHwOcclusionQueries.push_back(ret); + return ret; } //--------------------------------------------------------------------- Real D3D11RenderSystem::getHorizontalTexelOffset(void) { // D3D11 is now like GL - return 0.0f; + return 0.0f; } //--------------------------------------------------------------------- Real D3D11RenderSystem::getVerticalTexelOffset(void) { // D3D11 is now like GL - return 0.0f; + return 0.0f; } //--------------------------------------------------------------------- void D3D11RenderSystem::_applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane, @@ -3743,166 +3743,166 @@ namespace Ogre // D3D inverts even identity view matrices, so maximum INPUT is -1.0 return -1.0f; } - //--------------------------------------------------------------------- - void D3D11RenderSystem::registerThread() - { - // nothing to do - D3D11 shares rendering context already - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::unregisterThread() - { - // nothing to do - D3D11 shares rendering context already - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::preExtraThreadsStarted() - { - // nothing to do - D3D11 shares rendering context already - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::postExtraThreadsStarted() - { - // nothing to do - D3D11 shares rendering context already - } - //--------------------------------------------------------------------- - String D3D11RenderSystem::getErrorDescription( long errorNumber ) const - { - return mDevice.getErrorDescription(errorNumber); - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::determineFSAASettings(uint fsaa, const String& fsaaHint, - DXGI_FORMAT format, DXGI_SAMPLE_DESC* outFSAASettings) - { - bool ok = false; - bool qualityHint = fsaaHint.find("Quality") != String::npos; - size_t origFSAA = fsaa; - bool tryCSAA = false; - // NVIDIA, prefer CSAA if available for 8+ - // it would be tempting to use getCapabilities()->getVendor() == GPU_NVIDIA but - // if this is the first window, caps will not be initialised yet - - if (mActiveD3DDriver->getAdapterIdentifier().VendorId == 0x10DE && - fsaa >= 8) - { - tryCSAA = true; - } - - while (!ok) - { - // Deal with special cases - if (tryCSAA) - { - // see http://developer.nvidia.com/object/coverage-sampled-aa.html - switch(fsaa) - { - case 8: - if (qualityHint) - { - outFSAASettings->Count = 8; - outFSAASettings->Quality = 8; - } - else - { - outFSAASettings->Count = 4; - outFSAASettings->Quality = 8; - } - break; - case 16: - if (qualityHint) - { - outFSAASettings->Count = 8; - outFSAASettings->Quality = 16; - } - else - { - outFSAASettings->Count = 4; - outFSAASettings->Quality = 16; - } - break; - } - } - else // !CSAA - { - outFSAASettings->Count = fsaa == 0 ? 1 : fsaa; - outFSAASettings->Quality = 0; - } - - - HRESULT hr; - UINT outQuality; - hr = mDevice->CheckMultisampleQualityLevels( - format, - outFSAASettings->Count, - &outQuality); - - if (SUCCEEDED(hr) && - (!tryCSAA || outQuality > outFSAASettings->Quality)) - { - ok = true; - } - else - { - // downgrade - if (tryCSAA && fsaa == 8) - { - // for CSAA, we'll try downgrading with quality mode at all samples. - // then try without quality, then drop CSAA - if (qualityHint) - { - // drop quality first - qualityHint = false; - } - else - { - // drop CSAA entirely - tryCSAA = false; - } - // return to original requested samples - fsaa = static_cast(origFSAA); - } - else - { - // drop samples - --fsaa; - - if (fsaa == 1) - { - // ran out of options, no FSAA - fsaa = 0; - ok = true; - } - } - } - - } // while !ok - - } - //--------------------------------------------------------------------- - void D3D11RenderSystem::initRenderSystem() - { - if (mRenderSystemWasInited) - { - return; - } + //--------------------------------------------------------------------- + void D3D11RenderSystem::registerThread() + { + // nothing to do - D3D11 shares rendering context already + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::unregisterThread() + { + // nothing to do - D3D11 shares rendering context already + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::preExtraThreadsStarted() + { + // nothing to do - D3D11 shares rendering context already + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::postExtraThreadsStarted() + { + // nothing to do - D3D11 shares rendering context already + } + //--------------------------------------------------------------------- + String D3D11RenderSystem::getErrorDescription( long errorNumber ) const + { + return mDevice.getErrorDescription(errorNumber); + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::determineFSAASettings(uint fsaa, const String& fsaaHint, + DXGI_FORMAT format, DXGI_SAMPLE_DESC* outFSAASettings) + { + bool ok = false; + bool qualityHint = fsaaHint.find("Quality") != String::npos; + size_t origFSAA = fsaa; + bool tryCSAA = false; + // NVIDIA, prefer CSAA if available for 8+ + // it would be tempting to use getCapabilities()->getVendor() == GPU_NVIDIA but + // if this is the first window, caps will not be initialised yet + + if (mActiveD3DDriver->getAdapterIdentifier().VendorId == 0x10DE && + fsaa >= 8) + { + tryCSAA = true; + } + + while (!ok) + { + // Deal with special cases + if (tryCSAA) + { + // see http://developer.nvidia.com/object/coverage-sampled-aa.html + switch(fsaa) + { + case 8: + if (qualityHint) + { + outFSAASettings->Count = 8; + outFSAASettings->Quality = 8; + } + else + { + outFSAASettings->Count = 4; + outFSAASettings->Quality = 8; + } + break; + case 16: + if (qualityHint) + { + outFSAASettings->Count = 8; + outFSAASettings->Quality = 16; + } + else + { + outFSAASettings->Count = 4; + outFSAASettings->Quality = 16; + } + break; + } + } + else // !CSAA + { + outFSAASettings->Count = fsaa == 0 ? 1 : fsaa; + outFSAASettings->Quality = 0; + } + + + HRESULT hr; + UINT outQuality; + hr = mDevice->CheckMultisampleQualityLevels( + format, + outFSAASettings->Count, + &outQuality); + + if (SUCCEEDED(hr) && + (!tryCSAA || outQuality > outFSAASettings->Quality)) + { + ok = true; + } + else + { + // downgrade + if (tryCSAA && fsaa == 8) + { + // for CSAA, we'll try downgrading with quality mode at all samples. + // then try without quality, then drop CSAA + if (qualityHint) + { + // drop quality first + qualityHint = false; + } + else + { + // drop CSAA entirely + tryCSAA = false; + } + // return to original requested samples + fsaa = static_cast(origFSAA); + } + else + { + // drop samples + --fsaa; + + if (fsaa == 1) + { + // ran out of options, no FSAA + fsaa = 0; + ok = true; + } + } + } + + } // while !ok + + } + //--------------------------------------------------------------------- + void D3D11RenderSystem::initRenderSystem() + { + if (mRenderSystemWasInited) + { + return; + } mRenderSystemWasInited = true; - // set pointers to NULL - mpDXGIFactory = NULL; - HRESULT hr; - hr = CreateDXGIFactory1( __uuidof(IDXGIFactoryN), (void**)&mpDXGIFactory ); - if( FAILED(hr) ) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Failed to create Direct3D11 DXGIFactory1", - "D3D11RenderSystem::D3D11RenderSystem" ); - } - - mDriverList = NULL; - mActiveD3DDriver = NULL; - mTextureManager = NULL; - mHardwareBufferManager = NULL; - mGpuProgramManager = NULL; - mPrimaryWindow = NULL; - mBasicStatesInitialised = false; + // set pointers to NULL + mpDXGIFactory = NULL; + HRESULT hr; + hr = CreateDXGIFactory1( __uuidof(IDXGIFactoryN), (void**)&mpDXGIFactory ); + if( FAILED(hr) ) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Failed to create Direct3D11 DXGIFactory1", + "D3D11RenderSystem::D3D11RenderSystem" ); + } + + mDriverList = NULL; + mActiveD3DDriver = NULL; + mTextureManager = NULL; + mHardwareBufferManager = NULL; + mGpuProgramManager = NULL; + mPrimaryWindow = NULL; + mBasicStatesInitialised = false; mMinRequestedFeatureLevel = D3D_FEATURE_LEVEL_9_1; #if OGRE_PLATFORM == OGRE_PLATFORM_WINRT @@ -3912,167 +3912,167 @@ namespace Ogre mMaxRequestedFeatureLevel = D3D_FEATURE_LEVEL_11_1; # endif #else - mMaxRequestedFeatureLevel = D3D_FEATURE_LEVEL_11_0; + mMaxRequestedFeatureLevel = D3D_FEATURE_LEVEL_11_0; #endif - mUseNVPerfHUD = false; - mHLSLProgramFactory = NULL; + mUseNVPerfHUD = false; + mHLSLProgramFactory = NULL; - mBoundVertexProgram = NULL; - mBoundFragmentProgram = NULL; - mBoundGeometryProgram = NULL; - mBoundTessellationHullProgram = NULL; - mBoundTessellationDomainProgram = NULL; - mBoundComputeProgram = NULL; + mBoundVertexProgram = NULL; + mBoundFragmentProgram = NULL; + mBoundGeometryProgram = NULL; + mBoundTessellationHullProgram = NULL; + mBoundTessellationDomainProgram = NULL; + mBoundComputeProgram = NULL; - mBindingType = TextureUnitState::BT_FRAGMENT; + mBindingType = TextureUnitState::BT_FRAGMENT; - ZeroMemory( &mBlendDesc, sizeof(mBlendDesc)); + ZeroMemory( &mBlendDesc, sizeof(mBlendDesc)); - ZeroMemory( &mRasterizerDesc, sizeof(mRasterizerDesc)); - mRasterizerDesc.FrontCounterClockwise = true; - mRasterizerDesc.DepthClipEnable = false; - mRasterizerDesc.MultisampleEnable = true; + ZeroMemory( &mRasterizerDesc, sizeof(mRasterizerDesc)); + mRasterizerDesc.FrontCounterClockwise = true; + mRasterizerDesc.DepthClipEnable = false; + mRasterizerDesc.MultisampleEnable = true; - ZeroMemory( &mDepthStencilDesc, sizeof(mDepthStencilDesc)); + ZeroMemory( &mDepthStencilDesc, sizeof(mDepthStencilDesc)); - ZeroMemory( &mDepthStencilDesc, sizeof(mDepthStencilDesc)); - ZeroMemory( &mScissorRect, sizeof(mScissorRect)); + ZeroMemory( &mDepthStencilDesc, sizeof(mDepthStencilDesc)); + ZeroMemory( &mScissorRect, sizeof(mScissorRect)); - // set filters to defaults - for (size_t n = 0; n < OGRE_MAX_TEXTURE_LAYERS; n++) - { - FilterMinification[n] = FO_NONE; - FilterMagnification[n] = FO_NONE; - FilterMips[n] = FO_NONE; - } + // set filters to defaults + for (size_t n = 0; n < OGRE_MAX_TEXTURE_LAYERS; n++) + { + FilterMinification[n] = FO_NONE; + FilterMagnification[n] = FO_NONE; + FilterMips[n] = FO_NONE; + } - mPolygonMode = PM_SOLID; + mPolygonMode = PM_SOLID; - ZeroMemory(mTexStageDesc, OGRE_MAX_TEXTURE_LAYERS * sizeof(sD3DTextureStageDesc)); + ZeroMemory(mTexStageDesc, OGRE_MAX_TEXTURE_LAYERS * sizeof(sD3DTextureStageDesc)); - UINT deviceFlags = 0; + UINT deviceFlags = 0; #if OGRE_PLATFORM == OGRE_PLATFORM_WINRT - // This flag is required in order to enable compatibility with Direct2D. - deviceFlags |= D3D11_CREATE_DEVICE_BGRA_SUPPORT; + // This flag is required in order to enable compatibility with Direct2D. + deviceFlags |= D3D11_CREATE_DEVICE_BGRA_SUPPORT; #endif - if (D3D11Device::D3D_NO_EXCEPTION != D3D11Device::getExceptionsErrorLevel() && OGRE_DEBUG_MODE) - { - deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; - } + if (D3D11Device::D3D_NO_EXCEPTION != D3D11Device::getExceptionsErrorLevel() && OGRE_DEBUG_MODE) + { + deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + } #if OGRE_PLATFORM != OGRE_PLATFORM_WINRT - if (!OGRE_THREAD_SUPPORT) - { - deviceFlags |= D3D11_CREATE_DEVICE_SINGLETHREADED; - } + if (!OGRE_THREAD_SUPPORT) + { + deviceFlags |= D3D11_CREATE_DEVICE_SINGLETHREADED; + } #endif - ID3D11DeviceN * device; + ID3D11DeviceN * device; - hr = D3D11CreateDeviceN(NULL, D3D_DRIVER_TYPE_HARDWARE ,0,deviceFlags, NULL, 0, D3D11_SDK_VERSION, &device, 0 , 0); + hr = D3D11CreateDeviceN(NULL, D3D_DRIVER_TYPE_HARDWARE ,0,deviceFlags, NULL, 0, D3D11_SDK_VERSION, &device, 0 , 0); - if(FAILED(hr)) - { - StringStream error; + if(FAILED(hr)) + { + StringStream error; #ifdef USE_DXERR_LIBRARY - error<<"Failed to create Direct3D11 object."<::type result(eventName.length() + 1, '\0'); -// (void)MultiByteToWideChar(CP_ACP, 0, eventName.data(), eventName.length(), &result[0], result.size()); -// (void)D3DPERF_BeginEvent(D3DCOLOR_ARGB(1, 0, 1, 0), &result[0]); +// vector::type result(eventName.length() + 1, '\0'); +// (void)MultiByteToWideChar(CP_ACP, 0, eventName.data(), eventName.length(), &result[0], result.size()); +// (void)D3DPERF_BeginEvent(D3DCOLOR_ARGB(1, 0, 1, 0), &result[0]); //#endif } //--------------------------------------------------------------------- void D3D11RenderSystem::endProfileEvent( void ) { //#ifdef OGRE_PROFILING == 1 -// (void)D3DPERF_EndEvent(); +// (void)D3DPERF_EndEvent(); //#endif } //--------------------------------------------------------------------- void D3D11RenderSystem::markProfileEvent( const String &eventName ) { //#ifdef OGRE_PROFILING == 1 -// if( eventName.empty() ) -// return; +// if( eventName.empty() ) +// return; // -// vector::type result(eventName.length() + 1, '\0'); -// (void)MultiByteToWideChar(CP_ACP, 0, eventName.data(), eventName.length(), &result[0], result.size()); -// (void)D3DPERF_SetMarker(D3DCOLOR_ARGB(1, 0, 1, 0), &result[0]); +// vector::type result(eventName.length() + 1, '\0'); +// (void)MultiByteToWideChar(CP_ACP, 0, eventName.data(), eventName.length(), &result[0], result.size()); +// (void)D3DPERF_SetMarker(D3DCOLOR_ARGB(1, 0, 1, 0), &result[0]); //#endif } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11RenderToVertexBuffer.cpp b/RenderSystems/Direct3D11/src/OgreD3D11RenderToVertexBuffer.cpp index 05ab619437c..dee5b7f7a9a 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11RenderToVertexBuffer.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11RenderToVertexBuffer.cpp @@ -41,141 +41,141 @@ THE SOFTWARE. namespace Ogre { - D3D11RenderToVertexBuffer::D3D11RenderToVertexBuffer(D3D11Device & device, - D3D11HardwareBufferManagerBase * bufManager) - : mDevice(device) + D3D11RenderToVertexBuffer::D3D11RenderToVertexBuffer(D3D11Device & device, + D3D11HardwareBufferManagerBase * bufManager) + : mDevice(device) , mFrontBufferIndex(-1) , mBufManager(bufManager) , mpGeometryShader(0) - { - mVertexBuffers[0].setNull(); - mVertexBuffers[1].setNull(); - } - - D3D11RenderToVertexBuffer::~D3D11RenderToVertexBuffer(void) - { - } - - void D3D11RenderToVertexBuffer::getRenderOperation(RenderOperation& op) - { - op.operationType = mOperationType; - op.useIndexes = false; + { + mVertexBuffers[0].setNull(); + mVertexBuffers[1].setNull(); + } + + D3D11RenderToVertexBuffer::~D3D11RenderToVertexBuffer(void) + { + } + + void D3D11RenderToVertexBuffer::getRenderOperation(RenderOperation& op) + { + op.operationType = mOperationType; + op.useIndexes = false; op.useGlobalInstancingVertexBufferIsAvailable = false; - op.vertexData = mVertexData; - } + op.vertexData = mVertexData; + } void D3D11RenderToVertexBuffer::setupGeometryShaderLinkageToStreamOut(Pass* pass) - { - static bool done = false; - - if (done) - return; - - assert(pass->hasGeometryProgram()); - const GpuProgramPtr& program = pass->getGeometryProgram(); - - D3D11HLSLProgram* dx11Program = 0; - if (program->getSyntaxCode()=="unified") - { - dx11Program = static_cast(program->_getBindingDelegate()); - } - else - { - dx11Program = static_cast(program.getPointer()); - } - dx11Program->reinterpretGSForStreamOut(); - - done = true; - - } - void D3D11RenderToVertexBuffer::update(SceneManager* sceneMgr) - { - //Single pass only for now - Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); - - setupGeometryShaderLinkageToStreamOut(r2vbPass); - - size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; - if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) - { - //Buffers don't match. Need to reallocate. - mResetRequested = true; - } - - //Set pass before binding buffers to activate the GPU programs - sceneMgr->_setPass(r2vbPass); - - RenderOperation renderOp; - size_t targetBufferIndex; - if (mResetRequested || mResetsEveryUpdate) - { - //Use source data to render to first buffer - mSourceRenderable->getRenderOperation(renderOp); - targetBufferIndex = 0; - } - else - { - //Use current front buffer to render to back buffer - renderOp.operationType = mOperationType; - renderOp.useIndexes = false; - renderOp.vertexData = mVertexData; - targetBufferIndex = 1 - mFrontBufferIndex; - } - - if (mVertexBuffers[targetBufferIndex].isNull() || - mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) - { - reallocateBuffer(targetBufferIndex); - } - - RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); - - //Draw the object - targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); - targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); - targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); - - D3D11HardwareVertexBuffer* vertexBuffer = static_cast(mVertexBuffers[targetBufferIndex].getPointer()); - - UINT offset[1] = { 0 }; - ID3D11Buffer* iBuffer[1]; - iBuffer[0] = vertexBuffer->getD3DVertexBuffer(); - mDevice.GetImmediateContext()->SOSetTargets( 1, iBuffer, offset ); - - if (r2vbPass->hasVertexProgram()) - { - targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, - r2vbPass->getVertexProgramParameters(), GPV_ALL); - } - if (r2vbPass->hasGeometryProgram()) - { - targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, - r2vbPass->getGeometryProgramParameters(), GPV_ALL); - } - - // Remove fragment program - mDevice.GetImmediateContext()->PSSetShader(NULL, NULL, 0); - - targetRenderSystem->_render(renderOp); - - //Switch the vertex binding if necessary - if (targetBufferIndex != mFrontBufferIndex) - { - mVertexData->vertexBufferBinding->unsetAllBindings(); - mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); - mFrontBufferIndex = targetBufferIndex; - } - - // Remove stream output buffer - iBuffer[0]=NULL; - mDevice.GetImmediateContext()->SOSetTargets( 1, iBuffer, offset ); - //Clear the reset flag - mResetRequested = false; - - // Enable DrawAuto - mVertexData->vertexCount = -1; - } - //----------------------------------------------------------------------------- + { + static bool done = false; + + if (done) + return; + + assert(pass->hasGeometryProgram()); + const GpuProgramPtr& program = pass->getGeometryProgram(); + + D3D11HLSLProgram* dx11Program = 0; + if (program->getSyntaxCode()=="unified") + { + dx11Program = static_cast(program->_getBindingDelegate()); + } + else + { + dx11Program = static_cast(program.getPointer()); + } + dx11Program->reinterpretGSForStreamOut(); + + done = true; + + } + void D3D11RenderToVertexBuffer::update(SceneManager* sceneMgr) + { + //Single pass only for now + Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); + + setupGeometryShaderLinkageToStreamOut(r2vbPass); + + size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; + if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) + { + //Buffers don't match. Need to reallocate. + mResetRequested = true; + } + + //Set pass before binding buffers to activate the GPU programs + sceneMgr->_setPass(r2vbPass); + + RenderOperation renderOp; + size_t targetBufferIndex; + if (mResetRequested || mResetsEveryUpdate) + { + //Use source data to render to first buffer + mSourceRenderable->getRenderOperation(renderOp); + targetBufferIndex = 0; + } + else + { + //Use current front buffer to render to back buffer + renderOp.operationType = mOperationType; + renderOp.useIndexes = false; + renderOp.vertexData = mVertexData; + targetBufferIndex = 1 - mFrontBufferIndex; + } + + if (mVertexBuffers[targetBufferIndex].isNull() || + mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) + { + reallocateBuffer(targetBufferIndex); + } + + RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); + + //Draw the object + targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); + targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); + targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); + + D3D11HardwareVertexBuffer* vertexBuffer = static_cast(mVertexBuffers[targetBufferIndex].getPointer()); + + UINT offset[1] = { 0 }; + ID3D11Buffer* iBuffer[1]; + iBuffer[0] = vertexBuffer->getD3DVertexBuffer(); + mDevice.GetImmediateContext()->SOSetTargets( 1, iBuffer, offset ); + + if (r2vbPass->hasVertexProgram()) + { + targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, + r2vbPass->getVertexProgramParameters(), GPV_ALL); + } + if (r2vbPass->hasGeometryProgram()) + { + targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, + r2vbPass->getGeometryProgramParameters(), GPV_ALL); + } + + // Remove fragment program + mDevice.GetImmediateContext()->PSSetShader(NULL, NULL, 0); + + targetRenderSystem->_render(renderOp); + + //Switch the vertex binding if necessary + if (targetBufferIndex != mFrontBufferIndex) + { + mVertexData->vertexBufferBinding->unsetAllBindings(); + mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); + mFrontBufferIndex = targetBufferIndex; + } + + // Remove stream output buffer + iBuffer[0]=NULL; + mDevice.GetImmediateContext()->SOSetTargets( 1, iBuffer, offset ); + //Clear the reset flag + mResetRequested = false; + + // Enable DrawAuto + mVertexData->vertexCount = -1; + } + //----------------------------------------------------------------------------- void D3D11RenderToVertexBuffer::reallocateBuffer(size_t index) { assert(index == 0 || index == 1); @@ -184,9 +184,9 @@ namespace Ogre { mVertexBuffers[index].setNull(); } - mVertexBuffers[index] = mBufManager->createStreamOutputVertexBuffer( + mVertexBuffers[index] = mBufManager->createStreamOutputVertexBuffer( mVertexData->vertexDeclaration->getVertexSize(0), mMaxVertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY + HardwareBuffer::HBU_STATIC_WRITE_ONLY ); } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11RenderWindow.cpp b/RenderSystems/Direct3D11/src/OgreD3D11RenderWindow.cpp index 8cecf7d96d2..0dd3038f389 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11RenderWindow.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11RenderWindow.cpp @@ -38,299 +38,299 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - // class D3D11RenderWindowBase - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + // class D3D11RenderWindowBase + //--------------------------------------------------------------------- #pragma region D3D11RenderWindowBase - D3D11RenderWindowBase::D3D11RenderWindowBase(D3D11Device & device, IDXGIFactoryN* pDXGIFactory) - : mDevice(device) - , mpDXGIFactory(pDXGIFactory) - { - mIsFullScreen = false; - mIsExternal = false; - mActive = false; - mSizing = false; - mClosed = false; - mHidden = false; - mDisplayFrequency = 0; - mRenderTargetView = 0; - mDepthStencilView = 0; - mpBackBuffer = 0; - } + D3D11RenderWindowBase::D3D11RenderWindowBase(D3D11Device & device, IDXGIFactoryN* pDXGIFactory) + : mDevice(device) + , mpDXGIFactory(pDXGIFactory) + { + mIsFullScreen = false; + mIsExternal = false; + mActive = false; + mSizing = false; + mClosed = false; + mHidden = false; + mDisplayFrequency = 0; + mRenderTargetView = 0; + mDepthStencilView = 0; + mpBackBuffer = 0; + } //--------------------------------------------------------------------- D3D11RenderWindowBase::~D3D11RenderWindowBase() { destroy(); } - //--------------------------------------------------------------------- - bool D3D11RenderWindowBase::_checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format) - { - //TODO :CheckMultisampleQualityLevels - if (SUCCEEDED(mDevice->CheckMultisampleQualityLevels(//CheckDeviceMultiSampleType( - format, - SampleCount, - outQuality))) - { - return true; - } - else - return false; - } - //--------------------------------------------------------------------- - void D3D11RenderWindowBase::create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) - { - mFSAAType.Count = 1; - mFSAAType.Quality = 0; - mFSAA = 0; - mFSAAHint = ""; - mVSync = false; - mVSyncInterval = 1; - - unsigned int colourDepth = 32; - bool depthBuffer = true; - - if(miscParams) - { - // Get variable-length params - NameValuePairList::const_iterator opt; - // vsync [parseBool] - opt = miscParams->find("vsync"); - if(opt != miscParams->end()) - mVSync = StringConverter::parseBool(opt->second); - // vsyncInterval [parseUnsignedInt] - opt = miscParams->find("vsyncInterval"); - if(opt != miscParams->end()) - mVSyncInterval = StringConverter::parseUnsignedInt(opt->second); - // hidden [parseBool] - opt = miscParams->find("hidden"); - if(opt != miscParams->end()) - mHidden = StringConverter::parseBool(opt->second); - // displayFrequency - opt = miscParams->find("displayFrequency"); - if(opt != miscParams->end()) - mDisplayFrequency = StringConverter::parseUnsignedInt(opt->second); - // colourDepth - opt = miscParams->find("colourDepth"); - if(opt != miscParams->end()) - colourDepth = StringConverter::parseUnsignedInt(opt->second); - // depthBuffer [parseBool] - opt = miscParams->find("depthBuffer"); - if(opt != miscParams->end()) - depthBuffer = StringConverter::parseBool(opt->second); - // FSAA type - opt = miscParams->find("FSAA"); - if(opt != miscParams->end()) - mFSAA = StringConverter::parseUnsignedInt(opt->second); - // FSAA quality - opt = miscParams->find("FSAAHint"); - if(opt != miscParams->end()) - mFSAAHint = opt->second; - // sRGB? - opt = miscParams->find("gamma"); - if(opt != miscParams->end()) - mHwGamma = StringConverter::parseBool(opt->second); - } - - mName = name; - mDepthBufferPoolId = depthBuffer ? DepthBuffer::POOL_DEFAULT : DepthBuffer::POOL_NO_DEPTH; - mIsFullScreen = fullScreen; - mColourDepth = colourDepth; - - mWidth = mHeight = mLeft = mTop = 0; - - mActive = true; - mClosed = false; - } - //--------------------------------------------------------------------- - void D3D11RenderWindowBase::_createSizeDependedD3DResources(void) - { - assert(mpBackBuffer && !mRenderTargetView && !mDepthStencilView); - - HRESULT hr; - - // get the backbuffer desc - D3D11_TEXTURE2D_DESC BBDesc; - mpBackBuffer->GetDesc( &BBDesc ); - - // create the render target view - D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; - ZeroMemory( &RTVDesc, sizeof(RTVDesc) ); - - RTVDesc.Format = BBDesc.Format; - RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D; - RTVDesc.Texture2D.MipSlice = 0; - hr = mDevice->CreateRenderTargetView( mpBackBuffer, &RTVDesc, &mRenderTargetView ); - - if( FAILED(hr) ) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create rendertagert view\nError Description:" + errorDescription, - "D3D11RenderWindow::_createSizeDependedD3DResources"); - } - - - if( mDepthBufferPoolId != DepthBuffer::POOL_NO_DEPTH ) - { - // Create depth stencil texture - ID3D11Texture2D* pDepthStencil = NULL; - D3D11_TEXTURE2D_DESC descDepth; - - descDepth.Width = BBDesc.Width; - descDepth.Height = BBDesc.Height; - descDepth.MipLevels = 1; - descDepth.ArraySize = 1; - descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - descDepth.SampleDesc.Count = mFSAAType.Count; - descDepth.SampleDesc.Quality = mFSAAType.Quality; - descDepth.Usage = D3D11_USAGE_DEFAULT; - descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; - descDepth.CPUAccessFlags = 0; - descDepth.MiscFlags = 0; - - hr = mDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil ); - if( FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create depth texture\nError Description:" + errorDescription, - "D3D11RenderWindow::_createSizeDependedD3DResources"); - } - - // Create the depth stencil view - D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; - ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) ); - - descDSV.Format = descDepth.Format; - descDSV.ViewDimension = mFSAA ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; - descDSV.Texture2D.MipSlice = 0; - hr = mDevice->CreateDepthStencilView( pDepthStencil, &descDSV, &mDepthStencilView ); + //--------------------------------------------------------------------- + bool D3D11RenderWindowBase::_checkMultiSampleQuality(UINT SampleCount, UINT *outQuality, DXGI_FORMAT format) + { + //TODO :CheckMultisampleQualityLevels + if (SUCCEEDED(mDevice->CheckMultisampleQualityLevels(//CheckDeviceMultiSampleType( + format, + SampleCount, + outQuality))) + { + return true; + } + else + return false; + } + //--------------------------------------------------------------------- + void D3D11RenderWindowBase::create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams) + { + mFSAAType.Count = 1; + mFSAAType.Quality = 0; + mFSAA = 0; + mFSAAHint = ""; + mVSync = false; + mVSyncInterval = 1; + + unsigned int colourDepth = 32; + bool depthBuffer = true; + + if(miscParams) + { + // Get variable-length params + NameValuePairList::const_iterator opt; + // vsync [parseBool] + opt = miscParams->find("vsync"); + if(opt != miscParams->end()) + mVSync = StringConverter::parseBool(opt->second); + // vsyncInterval [parseUnsignedInt] + opt = miscParams->find("vsyncInterval"); + if(opt != miscParams->end()) + mVSyncInterval = StringConverter::parseUnsignedInt(opt->second); + // hidden [parseBool] + opt = miscParams->find("hidden"); + if(opt != miscParams->end()) + mHidden = StringConverter::parseBool(opt->second); + // displayFrequency + opt = miscParams->find("displayFrequency"); + if(opt != miscParams->end()) + mDisplayFrequency = StringConverter::parseUnsignedInt(opt->second); + // colourDepth + opt = miscParams->find("colourDepth"); + if(opt != miscParams->end()) + colourDepth = StringConverter::parseUnsignedInt(opt->second); + // depthBuffer [parseBool] + opt = miscParams->find("depthBuffer"); + if(opt != miscParams->end()) + depthBuffer = StringConverter::parseBool(opt->second); + // FSAA type + opt = miscParams->find("FSAA"); + if(opt != miscParams->end()) + mFSAA = StringConverter::parseUnsignedInt(opt->second); + // FSAA quality + opt = miscParams->find("FSAAHint"); + if(opt != miscParams->end()) + mFSAAHint = opt->second; + // sRGB? + opt = miscParams->find("gamma"); + if(opt != miscParams->end()) + mHwGamma = StringConverter::parseBool(opt->second); + } + + mName = name; + mDepthBufferPoolId = depthBuffer ? DepthBuffer::POOL_DEFAULT : DepthBuffer::POOL_NO_DEPTH; + mIsFullScreen = fullScreen; + mColourDepth = colourDepth; + + mWidth = mHeight = mLeft = mTop = 0; + + mActive = true; + mClosed = false; + } + //--------------------------------------------------------------------- + void D3D11RenderWindowBase::_createSizeDependedD3DResources(void) + { + assert(mpBackBuffer && !mRenderTargetView && !mDepthStencilView); + + HRESULT hr; + + // get the backbuffer desc + D3D11_TEXTURE2D_DESC BBDesc; + mpBackBuffer->GetDesc( &BBDesc ); + + // create the render target view + D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; + ZeroMemory( &RTVDesc, sizeof(RTVDesc) ); + + RTVDesc.Format = BBDesc.Format; + RTVDesc.ViewDimension = mFSAA ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D; + RTVDesc.Texture2D.MipSlice = 0; + hr = mDevice->CreateRenderTargetView( mpBackBuffer, &RTVDesc, &mRenderTargetView ); + + if( FAILED(hr) ) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create rendertagert view\nError Description:" + errorDescription, + "D3D11RenderWindow::_createSizeDependedD3DResources"); + } + + + if( mDepthBufferPoolId != DepthBuffer::POOL_NO_DEPTH ) + { + // Create depth stencil texture + ID3D11Texture2D* pDepthStencil = NULL; + D3D11_TEXTURE2D_DESC descDepth; + + descDepth.Width = BBDesc.Width; + descDepth.Height = BBDesc.Height; + descDepth.MipLevels = 1; + descDepth.ArraySize = 1; + descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + descDepth.SampleDesc.Count = mFSAAType.Count; + descDepth.SampleDesc.Quality = mFSAAType.Quality; + descDepth.Usage = D3D11_USAGE_DEFAULT; + descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; + descDepth.CPUAccessFlags = 0; + descDepth.MiscFlags = 0; + + hr = mDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil ); + if( FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create depth texture\nError Description:" + errorDescription, + "D3D11RenderWindow::_createSizeDependedD3DResources"); + } + + // Create the depth stencil view + D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; + ZeroMemory( &descDSV, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC) ); + + descDSV.Format = descDepth.Format; + descDSV.ViewDimension = mFSAA ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; + descDSV.Texture2D.MipSlice = 0; + hr = mDevice->CreateDepthStencilView( pDepthStencil, &descDSV, &mDepthStencilView ); SAFE_RELEASE(pDepthStencil); - if( FAILED(hr) ) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create depth stencil view\nError Description:" + errorDescription, - "D3D11RenderWindow::_createSizeDependedD3DResources"); - } - - D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); - DepthBuffer *depthBuf = rsys->_addManualDepthBuffer( mDepthStencilView, mWidth, mHeight, - mFSAAType.Count, mFSAAType.Quality ); - - //Don't forget we want this window to use _this_ depth buffer - this->attachDepthBuffer( depthBuf ); - } - } - //--------------------------------------------------------------------- - void D3D11RenderWindowBase::_destroySizeDependedD3DResources() - { - SAFE_RELEASE(mpBackBuffer); - SAFE_RELEASE(mRenderTargetView); - - // delete manual depth buffer (depth buffer view non-owning wrapper) - DepthBuffer* depthBuf = this->getDepthBuffer(); - detachDepthBuffer(); - D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); - rsys->_removeManualDepthBuffer(depthBuf); - delete depthBuf; - - SAFE_RELEASE(mDepthStencilView); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowBase::destroy() - { - _destroySizeDependedD3DResources(); - - mActive = false; - mClosed = true; - } - //--------------------------------------------------------------------- - void D3D11RenderWindowBase::_updateViewportsDimensions() - { - // Notify viewports of resize - ViewportList::iterator it = mViewportList.begin(); - while( it != mViewportList.end() ) - (*it++).second->_updateDimensions(); - } - //--------------------------------------------------------------------- - IDXGIDeviceN* D3D11RenderWindowBase::_queryDxgiDevice() - { - if (mDevice.isNull()) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "D3D11Device is NULL!", - "D3D11RenderWindowBase::_queryDxgiDevice"); - } - - IDXGIDeviceN* pDXGIDevice = NULL; - HRESULT hr = mDevice->QueryInterface( __uuidof(IDXGIDeviceN), (void**)&pDXGIDevice ); - if( FAILED(hr) ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to query a DXGIDevice", - "D3D11RenderWindowBase::_queryDxgiDevice"); - } - - return pDXGIDevice; - } - //--------------------------------------------------------------------- - void D3D11RenderWindowBase::getCustomAttribute( const String& name, void* pData ) - { - // Valid attributes and their equvalent native functions: - // D3DDEVICE : getD3DDevice - // WINDOW : getWindowHandle - - if( name == "D3DDEVICE" ) - { - ID3D11DeviceN **device = (ID3D11DeviceN **)pData; - *device = mDevice.get(); - return; - } - else if( name == "isTexture" ) - { - bool *b = reinterpret_cast< bool * >( pData ); - *b = false; - return; - } - else if( name == "ID3D11RenderTargetView" ) - { - *static_cast(pData) = mRenderTargetView; - return; - } - else if( name == "ID3D11Texture2D" ) - { - ID3D11Texture2D **pBackBuffer = (ID3D11Texture2D**)pData; - *pBackBuffer = mpBackBuffer; - return; - } - else if( name == "numberOfViews" ) - { - unsigned int* n = reinterpret_cast(pData); - *n = 1; - return; - } - else if( name == "DDBACKBUFFER" ) - { - ID3D11Texture2D **ppBackBuffer = (ID3D11Texture2D**) pData; - ppBackBuffer[0] = NULL; - return; - } - - RenderWindow::getCustomAttribute(name, pData); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowBase::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) - { - if(mpBackBuffer == NULL) - return; - - // get the backbuffer desc - D3D11_TEXTURE2D_DESC BBDesc; - mpBackBuffer->GetDesc( &BBDesc ); + if( FAILED(hr) ) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create depth stencil view\nError Description:" + errorDescription, + "D3D11RenderWindow::_createSizeDependedD3DResources"); + } + + D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); + DepthBuffer *depthBuf = rsys->_addManualDepthBuffer( mDepthStencilView, mWidth, mHeight, + mFSAAType.Count, mFSAAType.Quality ); + + //Don't forget we want this window to use _this_ depth buffer + this->attachDepthBuffer( depthBuf ); + } + } + //--------------------------------------------------------------------- + void D3D11RenderWindowBase::_destroySizeDependedD3DResources() + { + SAFE_RELEASE(mpBackBuffer); + SAFE_RELEASE(mRenderTargetView); + + // delete manual depth buffer (depth buffer view non-owning wrapper) + DepthBuffer* depthBuf = this->getDepthBuffer(); + detachDepthBuffer(); + D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); + rsys->_removeManualDepthBuffer(depthBuf); + delete depthBuf; + + SAFE_RELEASE(mDepthStencilView); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowBase::destroy() + { + _destroySizeDependedD3DResources(); + + mActive = false; + mClosed = true; + } + //--------------------------------------------------------------------- + void D3D11RenderWindowBase::_updateViewportsDimensions() + { + // Notify viewports of resize + ViewportList::iterator it = mViewportList.begin(); + while( it != mViewportList.end() ) + (*it++).second->_updateDimensions(); + } + //--------------------------------------------------------------------- + IDXGIDeviceN* D3D11RenderWindowBase::_queryDxgiDevice() + { + if (mDevice.isNull()) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "D3D11Device is NULL!", + "D3D11RenderWindowBase::_queryDxgiDevice"); + } + + IDXGIDeviceN* pDXGIDevice = NULL; + HRESULT hr = mDevice->QueryInterface( __uuidof(IDXGIDeviceN), (void**)&pDXGIDevice ); + if( FAILED(hr) ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to query a DXGIDevice", + "D3D11RenderWindowBase::_queryDxgiDevice"); + } + + return pDXGIDevice; + } + //--------------------------------------------------------------------- + void D3D11RenderWindowBase::getCustomAttribute( const String& name, void* pData ) + { + // Valid attributes and their equvalent native functions: + // D3DDEVICE : getD3DDevice + // WINDOW : getWindowHandle + + if( name == "D3DDEVICE" ) + { + ID3D11DeviceN **device = (ID3D11DeviceN **)pData; + *device = mDevice.get(); + return; + } + else if( name == "isTexture" ) + { + bool *b = reinterpret_cast< bool * >( pData ); + *b = false; + return; + } + else if( name == "ID3D11RenderTargetView" ) + { + *static_cast(pData) = mRenderTargetView; + return; + } + else if( name == "ID3D11Texture2D" ) + { + ID3D11Texture2D **pBackBuffer = (ID3D11Texture2D**)pData; + *pBackBuffer = mpBackBuffer; + return; + } + else if( name == "numberOfViews" ) + { + unsigned int* n = reinterpret_cast(pData); + *n = 1; + return; + } + else if( name == "DDBACKBUFFER" ) + { + ID3D11Texture2D **ppBackBuffer = (ID3D11Texture2D**) pData; + ppBackBuffer[0] = NULL; + return; + } + + RenderWindow::getCustomAttribute(name, pData); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowBase::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) + { + if(mpBackBuffer == NULL) + return; + + // get the backbuffer desc + D3D11_TEXTURE2D_DESC BBDesc; + mpBackBuffer->GetDesc( &BBDesc ); ID3D11Texture2D *backbuffer = NULL; @@ -360,16 +360,16 @@ namespace Ogre } - // change the parameters of the texture so we can read it - BBDesc.Usage = D3D11_USAGE_STAGING; - BBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - BBDesc.BindFlags = 0; - BBDesc.SampleDesc.Quality = 0; + // change the parameters of the texture so we can read it + BBDesc.Usage = D3D11_USAGE_STAGING; + BBDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + BBDesc.BindFlags = 0; + BBDesc.SampleDesc.Quality = 0; BBDesc.SampleDesc.Count = 1; - // create a temp buffer to copy to - ID3D11Texture2D * pTempTexture2D; - HRESULT hr = mDevice->CreateTexture2D( + // create a temp buffer to copy to + ID3D11Texture2D * pTempTexture2D; + HRESULT hr = mDevice->CreateTexture2D( &BBDesc, NULL, &pTempTexture2D); @@ -381,550 +381,550 @@ namespace Ogre "Error creating texture\nError Description:" + errorDescription, "D3D11RenderWindow::copyContentsToMemory" ); } - // copy the back buffer - mDevice.GetImmediateContext()->CopyResource(pTempTexture2D, backbuffer != NULL ? backbuffer : mpBackBuffer); + // copy the back buffer + mDevice.GetImmediateContext()->CopyResource(pTempTexture2D, backbuffer != NULL ? backbuffer : mpBackBuffer); - // map the copied texture - D3D11_MAPPED_SUBRESOURCE mappedTex2D; - mDevice.GetImmediateContext()->Map(pTempTexture2D, 0,D3D11_MAP_READ, 0, &mappedTex2D); + // map the copied texture + D3D11_MAPPED_SUBRESOURCE mappedTex2D; + mDevice.GetImmediateContext()->Map(pTempTexture2D, 0,D3D11_MAP_READ, 0, &mappedTex2D); - // copy the the texture to the dest - PixelUtil::bulkPixelConversion( - PixelBox(mWidth, mHeight, 1, D3D11Mappings::_getPF(BBDesc.Format), mappedTex2D.pData), - dst); + // copy the the texture to the dest + PixelUtil::bulkPixelConversion( + PixelBox(mWidth, mHeight, 1, D3D11Mappings::_getPF(BBDesc.Format), mappedTex2D.pData), + dst); - // unmap the temp buffer - mDevice.GetImmediateContext()->Unmap(pTempTexture2D, 0); + // unmap the temp buffer + mDevice.GetImmediateContext()->Unmap(pTempTexture2D, 0); - // Release the temp buffer - SAFE_RELEASE(pTempTexture2D); - SAFE_RELEASE(backbuffer); - } + // Release the temp buffer + SAFE_RELEASE(pTempTexture2D); + SAFE_RELEASE(backbuffer); + } #pragma endregion - //--------------------------------------------------------------------- - // class D3D11RenderWindowSwapChainBased - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + // class D3D11RenderWindowSwapChainBased + //--------------------------------------------------------------------- #pragma region D3D11RenderWindowSwapChainBased - D3D11RenderWindowSwapChainBased::D3D11RenderWindowSwapChainBased(D3D11Device & device, IDXGIFactoryN* pDXGIFactory) - : D3D11RenderWindowBase(device, pDXGIFactory) - , mpSwapChain(NULL) - { - ZeroMemory( &mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC_N) ); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowSwapChainBased::destroy() - { + D3D11RenderWindowSwapChainBased::D3D11RenderWindowSwapChainBased(D3D11Device & device, IDXGIFactoryN* pDXGIFactory) + : D3D11RenderWindowBase(device, pDXGIFactory) + , mpSwapChain(NULL) + { + ZeroMemory( &mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC_N) ); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowSwapChainBased::destroy() + { if(mIsFullScreen && mpSwapChain != NULL) { mpSwapChain->SetFullscreenState(false, NULL); // get back from fullscreen mIsFullScreen = false; } - SAFE_RELEASE(mpSwapChain); + SAFE_RELEASE(mpSwapChain); - D3D11RenderWindowBase::destroy(); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowSwapChainBased::_createSwapChain(void) - { - ZeroMemory( &mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC_N) ); + D3D11RenderWindowBase::destroy(); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowSwapChainBased::_createSwapChain(void) + { + ZeroMemory( &mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC_N) ); - // get the dxgi device - IDXGIDeviceN* pDXGIDevice = _queryDxgiDevice(); - // here the mSwapChainDesc and mpSwapChain are initialized - HRESULT hr = _createSwapChainImpl(pDXGIDevice); + // get the dxgi device + IDXGIDeviceN* pDXGIDevice = _queryDxgiDevice(); + // here the mSwapChainDesc and mpSwapChain are initialized + HRESULT hr = _createSwapChainImpl(pDXGIDevice); - SAFE_RELEASE(pDXGIDevice); + SAFE_RELEASE(pDXGIDevice); if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create swap chain", - "D3D11RenderWindowSwapChainBased::_createSwapChain"); - } - } - - void D3D11RenderWindowSwapChainBased::_createSizeDependedD3DResources() - { - // obtain back buffer - SAFE_RELEASE(mpBackBuffer); - - HRESULT hr = mpSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&mpBackBuffer ); - if( FAILED(hr) ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to Get Back Buffer for swap chain", - "D3D11RenderWindow::_createSizeDependedD3DResources"); - } - - // create all other size depended resources - D3D11RenderWindowBase::_createSizeDependedD3DResources(); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowSwapChainBased::_resizeSwapChainBuffers(unsigned width, unsigned height) - { - _destroySizeDependedD3DResources(); - - // width and height can be zero to autodetect size, therefore do not rely on them + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create swap chain", + "D3D11RenderWindowSwapChainBased::_createSwapChain"); + } + } + + void D3D11RenderWindowSwapChainBased::_createSizeDependedD3DResources() + { + // obtain back buffer + SAFE_RELEASE(mpBackBuffer); + + HRESULT hr = mpSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&mpBackBuffer ); + if( FAILED(hr) ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to Get Back Buffer for swap chain", + "D3D11RenderWindow::_createSizeDependedD3DResources"); + } + + // create all other size depended resources + D3D11RenderWindowBase::_createSizeDependedD3DResources(); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowSwapChainBased::_resizeSwapChainBuffers(unsigned width, unsigned height) + { + _destroySizeDependedD3DResources(); + + // width and height can be zero to autodetect size, therefore do not rely on them #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - UINT Flags = mIsFullScreen ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0; - mpSwapChain->ResizeBuffers(mSwapChainDesc.BufferCount, width, height, mSwapChainDesc.BufferDesc.Format, Flags); - mpSwapChain->GetDesc(&mSwapChainDesc); - mWidth = mSwapChainDesc.BufferDesc.Width; - mHeight = mSwapChainDesc.BufferDesc.Height; - mIsFullScreen = (0 == mSwapChainDesc.Windowed); // Alt-Enter together with SetWindowAssociation() can change this state + UINT Flags = mIsFullScreen ? DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH : 0; + mpSwapChain->ResizeBuffers(mSwapChainDesc.BufferCount, width, height, mSwapChainDesc.BufferDesc.Format, Flags); + mpSwapChain->GetDesc(&mSwapChainDesc); + mWidth = mSwapChainDesc.BufferDesc.Width; + mHeight = mSwapChainDesc.BufferDesc.Height; + mIsFullScreen = (0 == mSwapChainDesc.Windowed); // Alt-Enter together with SetWindowAssociation() can change this state #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - mpSwapChain->ResizeBuffers(mSwapChainDesc.BufferCount, width, height, mSwapChainDesc.Format, 0); - mpSwapChain->GetDesc1(&mSwapChainDesc); - mWidth = mSwapChainDesc.Width; - mHeight = mSwapChainDesc.Height; + mpSwapChain->ResizeBuffers(mSwapChainDesc.BufferCount, width, height, mSwapChainDesc.Format, 0); + mpSwapChain->GetDesc1(&mSwapChainDesc); + mWidth = mSwapChainDesc.Width; + mHeight = mSwapChainDesc.Height; #endif - _createSizeDependedD3DResources(); + _createSizeDependedD3DResources(); - // Notify viewports of resize - _updateViewportsDimensions(); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowSwapChainBased::swapBuffers( ) - { - if( !mDevice.isNull() ) - { + // Notify viewports of resize + _updateViewportsDimensions(); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowSwapChainBased::swapBuffers( ) + { + if( !mDevice.isNull() ) + { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - HRESULT hr = mpSwapChain->Present(mVSync ? mVSyncInterval : 0, 0); + HRESULT hr = mpSwapChain->Present(mVSync ? mVSyncInterval : 0, 0); #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - HRESULT hr = mpSwapChain->Present(1, 0); // flip presentation model swap chains have another semantic for first parameter + HRESULT hr = mpSwapChain->Present(1, 0); // flip presentation model swap chains have another semantic for first parameter #endif - if( FAILED(hr) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error Presenting surfaces", "D3D11RenderWindowSwapChainBased::swapBuffers" ); - } - } - //--------------------------------------------------------------------- + if( FAILED(hr) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error Presenting surfaces", "D3D11RenderWindowSwapChainBased::swapBuffers" ); + } + } + //--------------------------------------------------------------------- #pragma endregion #pragma region D3D11RenderWindowHwnd #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - //--------------------------------------------------------------------- - // class D3D11RenderWindowHwnd - //--------------------------------------------------------------------- - D3D11RenderWindowHwnd::D3D11RenderWindowHwnd(D3D11Device & device, IDXGIFactoryN* pDXGIFactory) - : D3D11RenderWindowSwapChainBased(device, pDXGIFactory) - { - mHWnd = 0; - mSwitchingFullscreen = false; - } - //--------------------------------------------------------------------- - void D3D11RenderWindowHwnd::create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) - { - D3D11RenderWindowSwapChainBased::create(name, width, height, fullScreen, miscParams); - - HWND parentHWnd = 0; - HWND externalHandle = 0; - String title = name; - int left = -1; // Defaults to screen center - int top = -1; // Defaults to screen center - String border = ""; - bool outerSize = false; - bool enableDoubleClick = false; - - if(miscParams) - { - // Get variable-length params - NameValuePairList::const_iterator opt; - // left (x) - opt = miscParams->find("left"); - if(opt != miscParams->end()) - left = StringConverter::parseInt(opt->second); - // top (y) - opt = miscParams->find("top"); - if(opt != miscParams->end()) - top = StringConverter::parseInt(opt->second); - // Window title - opt = miscParams->find("title"); - if(opt != miscParams->end()) - title = opt->second; - // parentWindowHandle -> parentHWnd - opt = miscParams->find("parentWindowHandle"); - if(opt != miscParams->end()) - parentHWnd = (HWND)StringConverter::parseSizeT(opt->second); - // externalWindowHandle -> externalHandle - opt = miscParams->find("externalWindowHandle"); - if(opt != miscParams->end()) - externalHandle = (HWND)StringConverter::parseSizeT(opt->second); - // window border style - opt = miscParams->find("border"); - if(opt != miscParams->end()) - border = opt->second; - // set outer dimensions? - opt = miscParams->find("outerDimensions"); - if(opt != miscParams->end()) - outerSize = StringConverter::parseBool(opt->second); - // enable double click messages - opt = miscParams->find("enableDoubleClick"); - if(opt != miscParams->end()) - enableDoubleClick = StringConverter::parseBool(opt->second); - - } - - // Destroy current window if any - if( mHWnd ) - destroy(); - - if (!externalHandle) - { - DWORD dwStyle = (mHidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN; - RECT rc; - - mWidth = width; - mHeight = height; - mTop = top; - mLeft = left; - - if (!fullScreen) - { - if (parentHWnd) - { - dwStyle |= WS_CHILD; - } - else - { - if (border == "none") - dwStyle |= WS_POPUP; - else if (border == "fixed") - dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | - WS_SYSMENU | WS_MINIMIZEBOX; - else - dwStyle |= WS_OVERLAPPEDWINDOW; - } - - if (!outerSize) - { - // Calculate window dimensions required - // to get the requested client area - SetRect(&rc, 0, 0, mWidth, mHeight); - AdjustWindowRect(&rc, dwStyle, false); - mWidth = rc.right - rc.left; - mHeight = rc.bottom - rc.top; - - // Clamp width and height to the desktop dimensions - int screenw = GetSystemMetrics(SM_CXSCREEN); - int screenh = GetSystemMetrics(SM_CYSCREEN); - if ((int)mWidth > screenw) - mWidth = screenw; - if ((int)mHeight > screenh) - mHeight = screenh; - if (mLeft < 0) - mLeft = (screenw - mWidth) / 2; - if (mTop < 0) - mTop = (screenh - mHeight) / 2; - } - } - else - { - dwStyle |= WS_POPUP; - mTop = mLeft = 0; - } - - UINT classStyle = 0; - if (enableDoubleClick) - classStyle |= CS_DBLCLKS; - - HINSTANCE hInst = NULL; - - // Register the window class - // NB allow 4 bytes of window data for D3D11RenderWindow pointer - WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst, - LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), - (HBRUSH)GetStockObject(BLACK_BRUSH), 0, "OgreD3D11Wnd" }; + //--------------------------------------------------------------------- + // class D3D11RenderWindowHwnd + //--------------------------------------------------------------------- + D3D11RenderWindowHwnd::D3D11RenderWindowHwnd(D3D11Device & device, IDXGIFactoryN* pDXGIFactory) + : D3D11RenderWindowSwapChainBased(device, pDXGIFactory) + { + mHWnd = 0; + mSwitchingFullscreen = false; + } + //--------------------------------------------------------------------- + void D3D11RenderWindowHwnd::create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams) + { + D3D11RenderWindowSwapChainBased::create(name, width, height, fullScreen, miscParams); + + HWND parentHWnd = 0; + HWND externalHandle = 0; + String title = name; + int left = -1; // Defaults to screen center + int top = -1; // Defaults to screen center + String border = ""; + bool outerSize = false; + bool enableDoubleClick = false; + + if(miscParams) + { + // Get variable-length params + NameValuePairList::const_iterator opt; + // left (x) + opt = miscParams->find("left"); + if(opt != miscParams->end()) + left = StringConverter::parseInt(opt->second); + // top (y) + opt = miscParams->find("top"); + if(opt != miscParams->end()) + top = StringConverter::parseInt(opt->second); + // Window title + opt = miscParams->find("title"); + if(opt != miscParams->end()) + title = opt->second; + // parentWindowHandle -> parentHWnd + opt = miscParams->find("parentWindowHandle"); + if(opt != miscParams->end()) + parentHWnd = (HWND)StringConverter::parseSizeT(opt->second); + // externalWindowHandle -> externalHandle + opt = miscParams->find("externalWindowHandle"); + if(opt != miscParams->end()) + externalHandle = (HWND)StringConverter::parseSizeT(opt->second); + // window border style + opt = miscParams->find("border"); + if(opt != miscParams->end()) + border = opt->second; + // set outer dimensions? + opt = miscParams->find("outerDimensions"); + if(opt != miscParams->end()) + outerSize = StringConverter::parseBool(opt->second); + // enable double click messages + opt = miscParams->find("enableDoubleClick"); + if(opt != miscParams->end()) + enableDoubleClick = StringConverter::parseBool(opt->second); + + } + + // Destroy current window if any + if( mHWnd ) + destroy(); + + if (!externalHandle) + { + DWORD dwStyle = (mHidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN; + RECT rc; + + mWidth = width; + mHeight = height; + mTop = top; + mLeft = left; + + if (!fullScreen) + { + if (parentHWnd) + { + dwStyle |= WS_CHILD; + } + else + { + if (border == "none") + dwStyle |= WS_POPUP; + else if (border == "fixed") + dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | + WS_SYSMENU | WS_MINIMIZEBOX; + else + dwStyle |= WS_OVERLAPPEDWINDOW; + } + + if (!outerSize) + { + // Calculate window dimensions required + // to get the requested client area + SetRect(&rc, 0, 0, mWidth, mHeight); + AdjustWindowRect(&rc, dwStyle, false); + mWidth = rc.right - rc.left; + mHeight = rc.bottom - rc.top; + + // Clamp width and height to the desktop dimensions + int screenw = GetSystemMetrics(SM_CXSCREEN); + int screenh = GetSystemMetrics(SM_CYSCREEN); + if ((int)mWidth > screenw) + mWidth = screenw; + if ((int)mHeight > screenh) + mHeight = screenh; + if (mLeft < 0) + mLeft = (screenw - mWidth) / 2; + if (mTop < 0) + mTop = (screenh - mHeight) / 2; + } + } + else + { + dwStyle |= WS_POPUP; + mTop = mLeft = 0; + } + + UINT classStyle = 0; + if (enableDoubleClick) + classStyle |= CS_DBLCLKS; + + HINSTANCE hInst = NULL; + + // Register the window class + // NB allow 4 bytes of window data for D3D11RenderWindow pointer + WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst, + LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), + (HBRUSH)GetStockObject(BLACK_BRUSH), 0, "OgreD3D11Wnd" }; - RegisterClass(&wc); - - // Create our main window - // Pass pointer to self - mIsExternal = false; - mHWnd = CreateWindow("OgreD3D11Wnd", title.c_str(), dwStyle, - mLeft, mTop, mWidth, mHeight, parentHWnd, 0, hInst, this); - - WindowEventUtilities::_addRenderWindow(this); - } - else - { - mHWnd = externalHandle; - mIsExternal = true; - } - - RECT rc; - // top and left represent outer window coordinates - GetWindowRect(mHWnd, &rc); - mTop = rc.top; - mLeft = rc.left; - // width and height represent interior drawable area - GetClientRect(mHWnd, &rc); - mWidth = rc.right; - mHeight = rc.bottom; - - LogManager::getSingleton().stream() - << "D3D11 : Created D3D11 Rendering Window '" - << mName << "' : " << mWidth << "x" << mHeight - << ", " << mColourDepth << "bpp"; - - _createSwapChain(); - _createSizeDependedD3DResources(); - mpDXGIFactory->MakeWindowAssociation(mHWnd, NULL); - setHidden(mHidden); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowHwnd::destroy() - { - D3D11RenderWindowSwapChainBased::destroy(); - - if (mHWnd && !mIsExternal) - { - WindowEventUtilities::_removeRenderWindow(this); - DestroyWindow(mHWnd); - } - - mHWnd = NULL; - } - //--------------------------------------------------------------------- - HRESULT D3D11RenderWindowHwnd::_createSwapChainImpl(IDXGIDeviceN* pDXGIDevice) - { - ZeroMemory( &mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC_N) ); - DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; - mSwapChainDesc.BufferDesc.Width = mWidth; - mSwapChainDesc.BufferDesc.Height = mHeight; - mSwapChainDesc.BufferDesc.Format = format; - - mSwapChainDesc.BufferDesc.RefreshRate.Numerator=0; - mSwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; - - mSwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - mSwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - mSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ; - - // triple buffer if VSync is on - mSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - mSwapChainDesc.BufferCount = mVSync ? 2 : 1; - mSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD ; - - mSwapChainDesc.OutputWindow = mHWnd; - mSwapChainDesc.Windowed = !mIsFullScreen; - - D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); - rsys->determineFSAASettings(mFSAA, mFSAAHint, format, &mFSAAType); - mSwapChainDesc.SampleDesc.Count = mFSAAType.Count; - mSwapChainDesc.SampleDesc.Quality = mFSAAType.Quality; - - if (!mVSync && !mIsFullScreen) - { - // NB not using vsync in windowed mode in D3D11 can cause jerking at low - // frame rates no matter what buffering modes are used (odd - perhaps a - // timer issue in D3D11 since GL doesn't suffer from this) - // low is < 200fps in this context - LogManager::getSingleton().logMessage("D3D11 : WARNING - " - "disabling VSync in windowed mode can cause timing issues at lower " - "frame rates, turn VSync on if you observe this problem."); - } - - HRESULT hr; - - // Create swap chain - hr = mpDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mpSwapChain); + RegisterClass(&wc); + + // Create our main window + // Pass pointer to self + mIsExternal = false; + mHWnd = CreateWindow("OgreD3D11Wnd", title.c_str(), dwStyle, + mLeft, mTop, mWidth, mHeight, parentHWnd, 0, hInst, this); + + WindowEventUtilities::_addRenderWindow(this); + } + else + { + mHWnd = externalHandle; + mIsExternal = true; + } + + RECT rc; + // top and left represent outer window coordinates + GetWindowRect(mHWnd, &rc); + mTop = rc.top; + mLeft = rc.left; + // width and height represent interior drawable area + GetClientRect(mHWnd, &rc); + mWidth = rc.right; + mHeight = rc.bottom; + + LogManager::getSingleton().stream() + << "D3D11 : Created D3D11 Rendering Window '" + << mName << "' : " << mWidth << "x" << mHeight + << ", " << mColourDepth << "bpp"; + + _createSwapChain(); + _createSizeDependedD3DResources(); + mpDXGIFactory->MakeWindowAssociation(mHWnd, NULL); + setHidden(mHidden); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowHwnd::destroy() + { + D3D11RenderWindowSwapChainBased::destroy(); + + if (mHWnd && !mIsExternal) + { + WindowEventUtilities::_removeRenderWindow(this); + DestroyWindow(mHWnd); + } + + mHWnd = NULL; + } + //--------------------------------------------------------------------- + HRESULT D3D11RenderWindowHwnd::_createSwapChainImpl(IDXGIDeviceN* pDXGIDevice) + { + ZeroMemory( &mSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC_N) ); + DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; + mSwapChainDesc.BufferDesc.Width = mWidth; + mSwapChainDesc.BufferDesc.Height = mHeight; + mSwapChainDesc.BufferDesc.Format = format; + + mSwapChainDesc.BufferDesc.RefreshRate.Numerator=0; + mSwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; + + mSwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + mSwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + mSwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH ; + + // triple buffer if VSync is on + mSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + mSwapChainDesc.BufferCount = mVSync ? 2 : 1; + mSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD ; + + mSwapChainDesc.OutputWindow = mHWnd; + mSwapChainDesc.Windowed = !mIsFullScreen; + + D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); + rsys->determineFSAASettings(mFSAA, mFSAAHint, format, &mFSAAType); + mSwapChainDesc.SampleDesc.Count = mFSAAType.Count; + mSwapChainDesc.SampleDesc.Quality = mFSAAType.Quality; + + if (!mVSync && !mIsFullScreen) + { + // NB not using vsync in windowed mode in D3D11 can cause jerking at low + // frame rates no matter what buffering modes are used (odd - perhaps a + // timer issue in D3D11 since GL doesn't suffer from this) + // low is < 200fps in this context + LogManager::getSingleton().logMessage("D3D11 : WARNING - " + "disabling VSync in windowed mode can cause timing issues at lower " + "frame rates, turn VSync on if you observe this problem."); + } + + HRESULT hr; + + // Create swap chain + hr = mpDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mpSwapChain); - if (FAILED(hr)) - { - // Try a second time, may fail the first time due to back buffer count, - // which will be corrected by the runtime - hr = mpDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mpSwapChain); - } - - return hr; - } - //--------------------------------------------------------------------- - bool D3D11RenderWindowHwnd::isVisible() const - { - return (mHWnd && !IsIconic(mHWnd)); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowHwnd::setHidden(bool hidden) - { - mHidden = hidden; - if (!mIsExternal) - { - if (hidden) - ShowWindow(mHWnd, SW_HIDE); - else - ShowWindow(mHWnd, SW_SHOWNORMAL); - } - } - //--------------------------------------------------------------------- - void D3D11RenderWindowHwnd::reposition(int top, int left) - { - if (mHWnd && !mIsFullScreen) - { - SetWindowPos(mHWnd, 0, top, left, 0, 0, - SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - } - } - //--------------------------------------------------------------------- - void D3D11RenderWindowHwnd::resize(unsigned int width, unsigned int height) - { - if (!mIsExternal) - { - if (mHWnd && !mIsFullScreen) - { - RECT rc = { 0, 0, width, height }; - AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false); - width = rc.right - rc.left; - height = rc.bottom - rc.top; - SetWindowPos(mHWnd, 0, 0, 0, width, height, - SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); - } - } - else - windowMovedOrResized(); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowHwnd::windowMovedOrResized() - { - if (!mHWnd || IsIconic(mHWnd)) - return; - - RECT rc; - // top and left represent outer window position - GetWindowRect(mHWnd, &rc); - mTop = rc.top; - mLeft = rc.left; - // width and height represent drawable area only - GetClientRect(mHWnd, &rc); - unsigned int width = rc.right - rc.left; - unsigned int height = rc.bottom - rc.top; - - if (width == 0) - width = 1; - if (height == 0) - height = 1; - - if (mWidth == width && mHeight == height) - return; - - _resizeSwapChainBuffers(width, height); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowHwnd::getCustomAttribute( const String& name, void* pData ) - { - // Valid attributes and their equvalent native functions: - // D3DDEVICE : getD3DDevice - // WINDOW : getWindowHandle - - if( name == "WINDOW" ) - { - HWND *pWnd = (HWND*)pData; - *pWnd = mHWnd; - return; - } - - D3D11RenderWindowSwapChainBased::getCustomAttribute(name, pData); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowHwnd::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) - { - if (fullScreen != mIsFullScreen || width != mWidth || height != mHeight) - { - - if (fullScreen != mIsFullScreen) - mSwitchingFullscreen = true; - - DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN; - - bool oldFullscreen = mIsFullScreen; - mIsFullScreen = fullScreen; - - if (fullScreen) - { - dwStyle |= WS_POPUP; - mTop = mLeft = 0; - mWidth = width; - mHeight = height; - // need different ordering here - - if (oldFullscreen) - { - // was previously fullscreen, just changing the resolution - SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE); - } - else - { - SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE); - //MoveWindow(mHWnd, mLeft, mTop, mWidth, mHeight, FALSE); - SetWindowLong(mHWnd, GWL_STYLE, dwStyle); - SetWindowPos(mHWnd, 0, 0,0, 0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); - } - } - else - { - dwStyle |= WS_OVERLAPPEDWINDOW; - // Calculate window dimensions required - // to get the requested client area - RECT rc; - SetRect(&rc, 0, 0, width, height); - AdjustWindowRect(&rc, dwStyle, false); - unsigned int winWidth = rc.right - rc.left; - unsigned int winHeight = rc.bottom - rc.top; - - SetWindowLong(mHWnd, GWL_STYLE, dwStyle); - SetWindowPos(mHWnd, HWND_NOTOPMOST, 0, 0, winWidth, winHeight, - SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE); - // Note that we also set the position in the restoreLostDevice method - // via _finishSwitchingFullScreen - } - - mSwapChainDesc.Windowed = !fullScreen; - mSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; - mSwapChainDesc.BufferDesc.RefreshRate.Denominator=0; - mSwapChainDesc.BufferDesc.Height = height; - mSwapChainDesc.BufferDesc.Width = width; - - if ((oldFullscreen && fullScreen) || mIsExternal) - { - // Notify viewports of resize - _updateViewportsDimensions(); - } - } - } - //--------------------------------------------------------------------- - void D3D11RenderWindowHwnd::_finishSwitchingFullscreen() - { - if(mIsFullScreen) - { - // Need to reset the region on the window sometimes, when the - // windowed mode was constrained by desktop - HRGN hRgn = CreateRectRgn(0,0,mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height); - SetWindowRgn(mHWnd, hRgn, FALSE); - } - else - { - // When switching back to windowed mode, need to reset window size - // after device has been restored - RECT rc; - SetRect(&rc, 0, 0, mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height); - AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false); - unsigned int winWidth = rc.right - rc.left; - unsigned int winHeight = rc.bottom - rc.top; - int screenw = GetSystemMetrics(SM_CXSCREEN); - int screenh = GetSystemMetrics(SM_CYSCREEN); - int left = (screenw - winWidth) / 2; - int top = (screenh - winHeight) / 2; - SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight, - SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE); - - } - mpSwapChain->SetFullscreenState(mIsFullScreen, NULL); - mSwitchingFullscreen = false; - } + if (FAILED(hr)) + { + // Try a second time, may fail the first time due to back buffer count, + // which will be corrected by the runtime + hr = mpDXGIFactory->CreateSwapChain(pDXGIDevice, &mSwapChainDesc, &mpSwapChain); + } + + return hr; + } + //--------------------------------------------------------------------- + bool D3D11RenderWindowHwnd::isVisible() const + { + return (mHWnd && !IsIconic(mHWnd)); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowHwnd::setHidden(bool hidden) + { + mHidden = hidden; + if (!mIsExternal) + { + if (hidden) + ShowWindow(mHWnd, SW_HIDE); + else + ShowWindow(mHWnd, SW_SHOWNORMAL); + } + } + //--------------------------------------------------------------------- + void D3D11RenderWindowHwnd::reposition(int top, int left) + { + if (mHWnd && !mIsFullScreen) + { + SetWindowPos(mHWnd, 0, top, left, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + //--------------------------------------------------------------------- + void D3D11RenderWindowHwnd::resize(unsigned int width, unsigned int height) + { + if (!mIsExternal) + { + if (mHWnd && !mIsFullScreen) + { + RECT rc = { 0, 0, width, height }; + AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false); + width = rc.right - rc.left; + height = rc.bottom - rc.top; + SetWindowPos(mHWnd, 0, 0, 0, width, height, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + else + windowMovedOrResized(); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowHwnd::windowMovedOrResized() + { + if (!mHWnd || IsIconic(mHWnd)) + return; + + RECT rc; + // top and left represent outer window position + GetWindowRect(mHWnd, &rc); + mTop = rc.top; + mLeft = rc.left; + // width and height represent drawable area only + GetClientRect(mHWnd, &rc); + unsigned int width = rc.right - rc.left; + unsigned int height = rc.bottom - rc.top; + + if (width == 0) + width = 1; + if (height == 0) + height = 1; + + if (mWidth == width && mHeight == height) + return; + + _resizeSwapChainBuffers(width, height); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowHwnd::getCustomAttribute( const String& name, void* pData ) + { + // Valid attributes and their equvalent native functions: + // D3DDEVICE : getD3DDevice + // WINDOW : getWindowHandle + + if( name == "WINDOW" ) + { + HWND *pWnd = (HWND*)pData; + *pWnd = mHWnd; + return; + } + + D3D11RenderWindowSwapChainBased::getCustomAttribute(name, pData); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowHwnd::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) + { + if (fullScreen != mIsFullScreen || width != mWidth || height != mHeight) + { + + if (fullScreen != mIsFullScreen) + mSwitchingFullscreen = true; + + DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN; + + bool oldFullscreen = mIsFullScreen; + mIsFullScreen = fullScreen; + + if (fullScreen) + { + dwStyle |= WS_POPUP; + mTop = mLeft = 0; + mWidth = width; + mHeight = height; + // need different ordering here + + if (oldFullscreen) + { + // was previously fullscreen, just changing the resolution + SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE); + } + else + { + SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOACTIVATE); + //MoveWindow(mHWnd, mLeft, mTop, mWidth, mHeight, FALSE); + SetWindowLong(mHWnd, GWL_STYLE, dwStyle); + SetWindowPos(mHWnd, 0, 0,0, 0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); + } + } + else + { + dwStyle |= WS_OVERLAPPEDWINDOW; + // Calculate window dimensions required + // to get the requested client area + RECT rc; + SetRect(&rc, 0, 0, width, height); + AdjustWindowRect(&rc, dwStyle, false); + unsigned int winWidth = rc.right - rc.left; + unsigned int winHeight = rc.bottom - rc.top; + + SetWindowLong(mHWnd, GWL_STYLE, dwStyle); + SetWindowPos(mHWnd, HWND_NOTOPMOST, 0, 0, winWidth, winHeight, + SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE); + // Note that we also set the position in the restoreLostDevice method + // via _finishSwitchingFullScreen + } + + mSwapChainDesc.Windowed = !fullScreen; + mSwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; + mSwapChainDesc.BufferDesc.RefreshRate.Denominator=0; + mSwapChainDesc.BufferDesc.Height = height; + mSwapChainDesc.BufferDesc.Width = width; + + if ((oldFullscreen && fullScreen) || mIsExternal) + { + // Notify viewports of resize + _updateViewportsDimensions(); + } + } + } + //--------------------------------------------------------------------- + void D3D11RenderWindowHwnd::_finishSwitchingFullscreen() + { + if(mIsFullScreen) + { + // Need to reset the region on the window sometimes, when the + // windowed mode was constrained by desktop + HRGN hRgn = CreateRectRgn(0,0,mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height); + SetWindowRgn(mHWnd, hRgn, FALSE); + } + else + { + // When switching back to windowed mode, need to reset window size + // after device has been restored + RECT rc; + SetRect(&rc, 0, 0, mSwapChainDesc.BufferDesc.Width, mSwapChainDesc.BufferDesc.Height); + AdjustWindowRect(&rc, GetWindowLong(mHWnd, GWL_STYLE), false); + unsigned int winWidth = rc.right - rc.left; + unsigned int winHeight = rc.bottom - rc.top; + int screenw = GetSystemMetrics(SM_CXSCREEN); + int screenh = GetSystemMetrics(SM_CYSCREEN); + int left = (screenw - winWidth) / 2; + int top = (screenh - winHeight) / 2; + SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight, + SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE); + + } + mpSwapChain->SetFullscreenState(mIsFullScreen, NULL); + mSwitchingFullscreen = false; + } //--------------------------------------------------------------------- void D3D11RenderWindowHwnd::setActive(bool state) { @@ -948,310 +948,310 @@ namespace Ogre #pragma endregion #pragma region D3D11RenderWindowCoreWindow #if OGRE_PLATFORM == OGRE_PLATFORM_WINRT - //--------------------------------------------------------------------- - // class D3D11RenderWindowCoreWindow - //--------------------------------------------------------------------- - D3D11RenderWindowCoreWindow::D3D11RenderWindowCoreWindow(D3D11Device & device, IDXGIFactoryN* pDXGIFactory) - : D3D11RenderWindowSwapChainBased(device, pDXGIFactory) - { - } - void D3D11RenderWindowCoreWindow::create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) - { - D3D11RenderWindowSwapChainBased::create(name, width, height, fullScreen, miscParams); - - Windows::UI::Core::CoreWindow^ externalHandle = nullptr; - - if(miscParams) - { - // Get variable-length params - NameValuePairList::const_iterator opt; - // externalWindowHandle -> externalHandle - opt = miscParams->find("externalWindowHandle"); - if(opt != miscParams->end()) - externalHandle = reinterpret_cast((void*)StringConverter::parseSizeT(opt->second)); - } - - // Reset current window if any - mCoreWindow = nullptr; - - if (!externalHandle) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "External window handle is not specified.", "D3D11RenderWindow::create" ); - } - else - { - mCoreWindow = externalHandle; - mIsExternal = true; - } - - Windows::Foundation::Rect rc = mCoreWindow->Bounds; - float scale = Windows::Graphics::Display::DisplayProperties::LogicalDpi / 96; - mLeft = (int)(rc.X * scale); - mTop = (int)(rc.Y * scale); - mWidth = (int)(rc.Width * scale); - mHeight = (int)(rc.Height * scale); - - LogManager::getSingleton().stream() - << "D3D11 : Created D3D11 Rendering Window '" - << mName << "' : " << mWidth << "x" << mHeight - << ", " << mColourDepth << "bpp"; - - _createSwapChain(); - _createSizeDependedD3DResources(); - } - - //--------------------------------------------------------------------- - void D3D11RenderWindowCoreWindow::destroy() - { - D3D11RenderWindowSwapChainBased::destroy(); - - if (mCoreWindow.Get() && !mIsExternal) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Only external window handles are supported." - , "D3D11RenderWindow::destroy" ); - } - - mCoreWindow = nullptr; - } - //--------------------------------------------------------------------- - HRESULT D3D11RenderWindowCoreWindow::_createSwapChainImpl(IDXGIDeviceN* pDXGIDevice) - { - DXGI_FORMAT format = DXGI_FORMAT_B8G8R8A8_UNORM; - mSwapChainDesc.Width = 0; // Use automatic sizing. - mSwapChainDesc.Height = 0; - mSwapChainDesc.Format = format; - mSwapChainDesc.Stereo = false; - - // triple buffer if VSync is on - mSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + //--------------------------------------------------------------------- + // class D3D11RenderWindowCoreWindow + //--------------------------------------------------------------------- + D3D11RenderWindowCoreWindow::D3D11RenderWindowCoreWindow(D3D11Device & device, IDXGIFactoryN* pDXGIFactory) + : D3D11RenderWindowSwapChainBased(device, pDXGIFactory) + { + } + void D3D11RenderWindowCoreWindow::create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams) + { + D3D11RenderWindowSwapChainBased::create(name, width, height, fullScreen, miscParams); + + Windows::UI::Core::CoreWindow^ externalHandle = nullptr; + + if(miscParams) + { + // Get variable-length params + NameValuePairList::const_iterator opt; + // externalWindowHandle -> externalHandle + opt = miscParams->find("externalWindowHandle"); + if(opt != miscParams->end()) + externalHandle = reinterpret_cast((void*)StringConverter::parseSizeT(opt->second)); + } + + // Reset current window if any + mCoreWindow = nullptr; + + if (!externalHandle) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "External window handle is not specified.", "D3D11RenderWindow::create" ); + } + else + { + mCoreWindow = externalHandle; + mIsExternal = true; + } + + Windows::Foundation::Rect rc = mCoreWindow->Bounds; + float scale = Windows::Graphics::Display::DisplayProperties::LogicalDpi / 96; + mLeft = (int)(rc.X * scale); + mTop = (int)(rc.Y * scale); + mWidth = (int)(rc.Width * scale); + mHeight = (int)(rc.Height * scale); + + LogManager::getSingleton().stream() + << "D3D11 : Created D3D11 Rendering Window '" + << mName << "' : " << mWidth << "x" << mHeight + << ", " << mColourDepth << "bpp"; + + _createSwapChain(); + _createSizeDependedD3DResources(); + } + + //--------------------------------------------------------------------- + void D3D11RenderWindowCoreWindow::destroy() + { + D3D11RenderWindowSwapChainBased::destroy(); + + if (mCoreWindow.Get() && !mIsExternal) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Only external window handles are supported." + , "D3D11RenderWindow::destroy" ); + } + + mCoreWindow = nullptr; + } + //--------------------------------------------------------------------- + HRESULT D3D11RenderWindowCoreWindow::_createSwapChainImpl(IDXGIDeviceN* pDXGIDevice) + { + DXGI_FORMAT format = DXGI_FORMAT_B8G8R8A8_UNORM; + mSwapChainDesc.Width = 0; // Use automatic sizing. + mSwapChainDesc.Height = 0; + mSwapChainDesc.Format = format; + mSwapChainDesc.Stereo = false; + + // triple buffer if VSync is on + mSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; #if (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == PHONE) - mSwapChainDesc.BufferCount = 1; // WP8: One buffer. - mSwapChainDesc.Scaling = DXGI_SCALING_STRETCH; // WP8: Must be stretch scaling mode. - mSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // WP8: No swap effect. + mSwapChainDesc.BufferCount = 1; // WP8: One buffer. + mSwapChainDesc.Scaling = DXGI_SCALING_STRETCH; // WP8: Must be stretch scaling mode. + mSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // WP8: No swap effect. #else - mSwapChainDesc.BufferCount = 2; // Use two buffers to enable flip effect. - mSwapChainDesc.Scaling = DXGI_SCALING_NONE; // Otherwise stretch would be used by default. - mSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // MS recommends using this swap effect for all applications. + mSwapChainDesc.BufferCount = 2; // Use two buffers to enable flip effect. + mSwapChainDesc.Scaling = DXGI_SCALING_NONE; // Otherwise stretch would be used by default. + mSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // MS recommends using this swap effect for all applications. #endif - mSwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + mSwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; - D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); - rsys->determineFSAASettings(mFSAA, mFSAAHint, format, &mFSAAType); - mSwapChainDesc.SampleDesc.Count = mFSAAType.Count; - mSwapChainDesc.SampleDesc.Quality = mFSAAType.Quality; + D3D11RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); + rsys->determineFSAASettings(mFSAA, mFSAAHint, format, &mFSAAType); + mSwapChainDesc.SampleDesc.Count = mFSAAType.Count; + mSwapChainDesc.SampleDesc.Quality = mFSAAType.Quality; - // Create swap chain - HRESULT hr = mpDXGIFactory->CreateSwapChainForCoreWindow(pDXGIDevice, reinterpret_cast(mCoreWindow.Get()), &mSwapChainDesc, NULL, &mpSwapChain); + // Create swap chain + HRESULT hr = mpDXGIFactory->CreateSwapChainForCoreWindow(pDXGIDevice, reinterpret_cast(mCoreWindow.Get()), &mSwapChainDesc, NULL, &mpSwapChain); - if (FAILED(hr)) - { - // Try a second time, may fail the first time due to back buffer count, - // which will be corrected by the runtime - hr = mpDXGIFactory->CreateSwapChainForCoreWindow(pDXGIDevice, reinterpret_cast(mCoreWindow.Get()), &mSwapChainDesc, NULL, &mpSwapChain); - } - if (FAILED(hr)) - return hr; + if (FAILED(hr)) + { + // Try a second time, may fail the first time due to back buffer count, + // which will be corrected by the runtime + hr = mpDXGIFactory->CreateSwapChainForCoreWindow(pDXGIDevice, reinterpret_cast(mCoreWindow.Get()), &mSwapChainDesc, NULL, &mpSwapChain); + } + if (FAILED(hr)) + return hr; // Ensure that DXGI does not queue more than one frame at a time. This both reduces // latency and ensures that the application will only render after each VSync, minimizing // power consumption. hr = pDXGIDevice->SetMaximumFrameLatency(1); - return hr; - } - //--------------------------------------------------------------------- - bool D3D11RenderWindowCoreWindow::isVisible() const - { - return (mCoreWindow.Get() && Windows::UI::Core::CoreWindow::GetForCurrentThread() == mCoreWindow.Get()); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowCoreWindow::windowMovedOrResized() - { - Windows::Foundation::Rect rc = mCoreWindow->Bounds; - float scale = Windows::Graphics::Display::DisplayProperties::LogicalDpi / 96; - mLeft = (int)(rc.X * scale); - mTop = (int)(rc.Y * scale); - mWidth = (int)(rc.Width * scale); - mHeight = (int)(rc.Height * scale); - - _resizeSwapChainBuffers(0, 0); // pass zero to autodetect size - } - //--------------------------------------------------------------------- + return hr; + } + //--------------------------------------------------------------------- + bool D3D11RenderWindowCoreWindow::isVisible() const + { + return (mCoreWindow.Get() && Windows::UI::Core::CoreWindow::GetForCurrentThread() == mCoreWindow.Get()); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowCoreWindow::windowMovedOrResized() + { + Windows::Foundation::Rect rc = mCoreWindow->Bounds; + float scale = Windows::Graphics::Display::DisplayProperties::LogicalDpi / 96; + mLeft = (int)(rc.X * scale); + mTop = (int)(rc.Y * scale); + mWidth = (int)(rc.Width * scale); + mHeight = (int)(rc.Height * scale); + + _resizeSwapChainBuffers(0, 0); // pass zero to autodetect size + } + //--------------------------------------------------------------------- #endif #pragma endregion - //--------------------------------------------------------------------- - // class D3D11RenderWindowImageSource - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + // class D3D11RenderWindowImageSource + //--------------------------------------------------------------------- #pragma region D3D11RenderWindowImageSource #if (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == DESKTOP_APP) - //--------------------------------------------------------------------- - D3D11RenderWindowImageSource::D3D11RenderWindowImageSource(D3D11Device& device, IDXGIFactoryN* pDXGIFactory) - : D3D11RenderWindowBase(device, pDXGIFactory) - , mImageSourceNative(NULL) - { - } - //--------------------------------------------------------------------- - void D3D11RenderWindowImageSource::create(const String& name, unsigned width, unsigned height, bool fullScreen, const NameValuePairList *miscParams) - { - D3D11RenderWindowBase::create(name, width, height, fullScreen, miscParams); - - mWidth = width; - mHeight = height; - - bool isOpaque = true; - if(miscParams) - { - // Get variable-length params - NameValuePairList::const_iterator opt; - // isOpaque - opt = miscParams->find("isOpaque"); - if(opt != miscParams->end()) - isOpaque = StringConverter::parseBool(opt->second); - } - - // create brush - // TODO: obtain from miscParams optional placeholder image and set inside the brush till first render??? - mBrush = ref new Windows::UI::Xaml::Media::ImageBrush; - - _createSizeDependedD3DResources(); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowImageSource::destroy(void) - { - D3D11RenderWindowBase::destroy(); - - SAFE_RELEASE(mImageSourceNative); - mImageSource = nullptr; - mBrush = nullptr; - } - //--------------------------------------------------------------------- - void D3D11RenderWindowImageSource::_createSizeDependedD3DResources() - { - SAFE_RELEASE(mpBackBuffer); - SAFE_RELEASE(mImageSourceNative); - - if(mWidth <= 0 || mHeight <= 0) - { - mImageSource = nullptr; - mBrush->ImageSource = nullptr; - return; - } - - // create back buffer - ID3D11Texture2D - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = mWidth; - desc.Height = mHeight; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_RENDER_TARGET; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - HRESULT hr = mDevice->CreateTexture2D(&desc, NULL, &mpBackBuffer); - if( FAILED(hr) ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to Create Back Buffer", - "D3D11RenderWindowImageSource::_createSizeDependedD3DResources"); - } - - // create front buffer - SurfaceImageSource - mImageSource = ref new Windows::UI::Xaml::Media::Imaging::SurfaceImageSource(mWidth, mHeight, true); - reinterpret_cast(mImageSource)->QueryInterface(__uuidof(ISurfaceImageSourceNative), (void **)&mImageSourceNative); - - // set DXGI device for the front buffer - IDXGIDeviceN* pDXGIDevice = _queryDxgiDevice(); - mImageSourceNative->SetDevice(pDXGIDevice); - SAFE_RELEASE(pDXGIDevice); - - // create all other size depended resources - D3D11RenderWindowBase::_createSizeDependedD3DResources(); - - mBrush->ImageSource = mImageSource; - } - //--------------------------------------------------------------------- - void D3D11RenderWindowImageSource::update(bool swapBuffers) - { - if(mImageSourceNative == NULL) - return; - - D3D11RenderWindowBase::update(swapBuffers); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowImageSource::swapBuffers() - { - if(mImageSourceNative == NULL) - return; - - IDXGISurface* dxgiSurface = NULL; - RECT updateRect = { 0, 0, mWidth, mHeight }; - POINT offset = { 0, 0 }; - - HRESULT hr = mImageSourceNative->BeginDraw(updateRect, &dxgiSurface, &offset); - if(hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) - return; - - if(FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to Get DXGI surface for SurfaceImageSource", - "D3D11RenderWindowImageSource::swapBuffers"); - } - - ID3D11Texture2D* destTexture = NULL; - hr = dxgiSurface->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&destTexture); - SAFE_RELEASE(dxgiSurface); - if(FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to convert DXGI surface to D3D11 texture", - "D3D11RenderWindowImageSource::swapBuffers"); - } - - mDevice.GetImmediateContext()->CopySubresourceRegion1(destTexture, 0, offset.x, offset.y, 0, mpBackBuffer, 0, NULL, 0); - - hr = mImageSourceNative->EndDraw(); - - SAFE_RELEASE(destTexture); - - if( FAILED(hr) ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Drawing into SurfaceImageSource failed", - "D3D11RenderWindowImageSource::swapBuffers"); - } - } - //--------------------------------------------------------------------- - void D3D11RenderWindowImageSource::resize(unsigned width, unsigned height) - { - _destroySizeDependedD3DResources(); - - mWidth = width; - mHeight = height; - - _createSizeDependedD3DResources(); - - // Notify viewports of resize - _updateViewportsDimensions(); - } - //--------------------------------------------------------------------- - void D3D11RenderWindowImageSource::getCustomAttribute( const String& name, void* pData ) - { - if( name == "ImageBrush" ) - { - IUnknown** pUnk = (IUnknown **)pData; - *pUnk = reinterpret_cast(mBrush); - return; - } - - D3D11RenderWindowBase::getCustomAttribute(name, pData); - } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + D3D11RenderWindowImageSource::D3D11RenderWindowImageSource(D3D11Device& device, IDXGIFactoryN* pDXGIFactory) + : D3D11RenderWindowBase(device, pDXGIFactory) + , mImageSourceNative(NULL) + { + } + //--------------------------------------------------------------------- + void D3D11RenderWindowImageSource::create(const String& name, unsigned width, unsigned height, bool fullScreen, const NameValuePairList *miscParams) + { + D3D11RenderWindowBase::create(name, width, height, fullScreen, miscParams); + + mWidth = width; + mHeight = height; + + bool isOpaque = true; + if(miscParams) + { + // Get variable-length params + NameValuePairList::const_iterator opt; + // isOpaque + opt = miscParams->find("isOpaque"); + if(opt != miscParams->end()) + isOpaque = StringConverter::parseBool(opt->second); + } + + // create brush + // TODO: obtain from miscParams optional placeholder image and set inside the brush till first render??? + mBrush = ref new Windows::UI::Xaml::Media::ImageBrush; + + _createSizeDependedD3DResources(); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowImageSource::destroy(void) + { + D3D11RenderWindowBase::destroy(); + + SAFE_RELEASE(mImageSourceNative); + mImageSource = nullptr; + mBrush = nullptr; + } + //--------------------------------------------------------------------- + void D3D11RenderWindowImageSource::_createSizeDependedD3DResources() + { + SAFE_RELEASE(mpBackBuffer); + SAFE_RELEASE(mImageSourceNative); + + if(mWidth <= 0 || mHeight <= 0) + { + mImageSource = nullptr; + mBrush->ImageSource = nullptr; + return; + } + + // create back buffer - ID3D11Texture2D + D3D11_TEXTURE2D_DESC desc = {0}; + desc.Width = mWidth; + desc.Height = mHeight; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT hr = mDevice->CreateTexture2D(&desc, NULL, &mpBackBuffer); + if( FAILED(hr) ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to Create Back Buffer", + "D3D11RenderWindowImageSource::_createSizeDependedD3DResources"); + } + + // create front buffer - SurfaceImageSource + mImageSource = ref new Windows::UI::Xaml::Media::Imaging::SurfaceImageSource(mWidth, mHeight, true); + reinterpret_cast(mImageSource)->QueryInterface(__uuidof(ISurfaceImageSourceNative), (void **)&mImageSourceNative); + + // set DXGI device for the front buffer + IDXGIDeviceN* pDXGIDevice = _queryDxgiDevice(); + mImageSourceNative->SetDevice(pDXGIDevice); + SAFE_RELEASE(pDXGIDevice); + + // create all other size depended resources + D3D11RenderWindowBase::_createSizeDependedD3DResources(); + + mBrush->ImageSource = mImageSource; + } + //--------------------------------------------------------------------- + void D3D11RenderWindowImageSource::update(bool swapBuffers) + { + if(mImageSourceNative == NULL) + return; + + D3D11RenderWindowBase::update(swapBuffers); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowImageSource::swapBuffers() + { + if(mImageSourceNative == NULL) + return; + + IDXGISurface* dxgiSurface = NULL; + RECT updateRect = { 0, 0, mWidth, mHeight }; + POINT offset = { 0, 0 }; + + HRESULT hr = mImageSourceNative->BeginDraw(updateRect, &dxgiSurface, &offset); + if(hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) + return; + + if(FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to Get DXGI surface for SurfaceImageSource", + "D3D11RenderWindowImageSource::swapBuffers"); + } + + ID3D11Texture2D* destTexture = NULL; + hr = dxgiSurface->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&destTexture); + SAFE_RELEASE(dxgiSurface); + if(FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to convert DXGI surface to D3D11 texture", + "D3D11RenderWindowImageSource::swapBuffers"); + } + + mDevice.GetImmediateContext()->CopySubresourceRegion1(destTexture, 0, offset.x, offset.y, 0, mpBackBuffer, 0, NULL, 0); + + hr = mImageSourceNative->EndDraw(); + + SAFE_RELEASE(destTexture); + + if( FAILED(hr) ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Drawing into SurfaceImageSource failed", + "D3D11RenderWindowImageSource::swapBuffers"); + } + } + //--------------------------------------------------------------------- + void D3D11RenderWindowImageSource::resize(unsigned width, unsigned height) + { + _destroySizeDependedD3DResources(); + + mWidth = width; + mHeight = height; + + _createSizeDependedD3DResources(); + + // Notify viewports of resize + _updateViewportsDimensions(); + } + //--------------------------------------------------------------------- + void D3D11RenderWindowImageSource::getCustomAttribute( const String& name, void* pData ) + { + if( name == "ImageBrush" ) + { + IUnknown** pUnk = (IUnknown **)pData; + *pUnk = reinterpret_cast(mBrush); + return; + } + + D3D11RenderWindowBase::getCustomAttribute(name, pData); + } + //--------------------------------------------------------------------- #endif // (OGRE_PLATFORM == OGRE_PLATFORM_WINRT) && (OGRE_WINRT_TARGET_TYPE == DESKTOP_APP) #pragma endregion } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11Texture.cpp b/RenderSystems/Direct3D11/src/OgreD3D11Texture.cpp index e635d5f2f1e..26e2bdbc5f2 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11Texture.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11Texture.cpp @@ -45,454 +45,454 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - D3D11Texture::D3D11Texture(ResourceManager* creator, const String& name, - ResourceHandle handle, const String& group, bool isManual, - ManualResourceLoader* loader, D3D11Device & device) - :Texture(creator, name, handle, group, isManual, loader), - mDevice(device), - mpTex(NULL), - mpShaderResourceView(NULL), - mp1DTex(NULL), - mp2DTex(NULL), - mp3DTex(NULL), - mDynamicTextures(false), - mAutoMipMapGeneration(false) -//#ifdef USE_D3DX11_LIBRARY -// , mEffect(NULL) -// , mEffectIndex(0) + //--------------------------------------------------------------------- + D3D11Texture::D3D11Texture(ResourceManager* creator, const String& name, + ResourceHandle handle, const String& group, bool isManual, + ManualResourceLoader* loader, D3D11Device & device) + :Texture(creator, name, handle, group, isManual, loader), + mDevice(device), + mpTex(NULL), + mpShaderResourceView(NULL), + mp1DTex(NULL), + mp2DTex(NULL), + mp3DTex(NULL), + mDynamicTextures(false), + mAutoMipMapGeneration(false) +//#ifdef USE_D3DX11_LIBRARY +// , mEffect(NULL) +// , mEffectIndex(0) //#endif - { - } - //--------------------------------------------------------------------- - D3D11Texture::~D3D11Texture() - { - // have to call this here reather than in Resource destructor - // since calling virtual methods in base destructors causes crash - if (isLoaded()) - { - unload(); - } - else - { - freeInternalResources(); - } - } - //--------------------------------------------------------------------- - void D3D11Texture::copyToTexture(TexturePtr& target) - { - // check if this & target are the same format and type - // blitting from or to cube textures is not supported yet - if (target->getUsage() != this->getUsage() || - target->getTextureType() != this->getTextureType()) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Src. and dest. textures must be of same type and must have the same usage !!!", - "D3D11Texture::copyToTexture" ); - } - - - D3D11Texture *other; - // get the target - other = reinterpret_cast< D3D11Texture * >( target.get() ); - - mDevice.GetImmediateContext()->CopyResource(other->getTextureResource(), mpTex); - if (mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device cannot copy resource\nError Description:" + errorDescription, - "D3D11Texture::copyToTexture"); - } - - } - //--------------------------------------------------------------------- - void D3D11Texture::loadImage( const Image &img ) - { - // Use OGRE its own codecs - vector::type imagePtrs; - imagePtrs.push_back(&img); - _loadImages( imagePtrs ); - } - //--------------------------------------------------------------------- - void D3D11Texture::loadImpl() - { - if (mUsage & TU_RENDERTARGET) - { - createInternalResources(); - return; - } - - // Make sure streams prepared. - if (mLoadedStreams.isNull()) - { - prepareImpl(); - } - - // Set reading positions of loaded streams to the beginning. - for (uint i = 0; i < mLoadedStreams->size(); ++i) - { - MemoryDataStreamPtr curDataStream = (*mLoadedStreams)[i]; - - curDataStream->seek(0); - } - - // only copy is on the stack so well-behaved if exception thrown - LoadedStreams loadedStreams = mLoadedStreams; - - this->_loadTex(loadedStreams); - - } - //--------------------------------------------------------------------- - void D3D11Texture::freeInternalResources(void) - { - freeInternalResourcesImpl(); - } - //--------------------------------------------------------------------- - void D3D11Texture::freeInternalResourcesImpl() - { - SAFE_RELEASE(mpTex); + { + } + //--------------------------------------------------------------------- + D3D11Texture::~D3D11Texture() + { + // have to call this here reather than in Resource destructor + // since calling virtual methods in base destructors causes crash + if (isLoaded()) + { + unload(); + } + else + { + freeInternalResources(); + } + } + //--------------------------------------------------------------------- + void D3D11Texture::copyToTexture(TexturePtr& target) + { + // check if this & target are the same format and type + // blitting from or to cube textures is not supported yet + if (target->getUsage() != this->getUsage() || + target->getTextureType() != this->getTextureType()) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Src. and dest. textures must be of same type and must have the same usage !!!", + "D3D11Texture::copyToTexture" ); + } + + + D3D11Texture *other; + // get the target + other = reinterpret_cast< D3D11Texture * >( target.get() ); + + mDevice.GetImmediateContext()->CopyResource(other->getTextureResource(), mpTex); + if (mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device cannot copy resource\nError Description:" + errorDescription, + "D3D11Texture::copyToTexture"); + } + + } + //--------------------------------------------------------------------- + void D3D11Texture::loadImage( const Image &img ) + { + // Use OGRE its own codecs + vector::type imagePtrs; + imagePtrs.push_back(&img); + _loadImages( imagePtrs ); + } + //--------------------------------------------------------------------- + void D3D11Texture::loadImpl() + { + if (mUsage & TU_RENDERTARGET) + { + createInternalResources(); + return; + } + + // Make sure streams prepared. + if (mLoadedStreams.isNull()) + { + prepareImpl(); + } + + // Set reading positions of loaded streams to the beginning. + for (uint i = 0; i < mLoadedStreams->size(); ++i) + { + MemoryDataStreamPtr curDataStream = (*mLoadedStreams)[i]; + + curDataStream->seek(0); + } + + // only copy is on the stack so well-behaved if exception thrown + LoadedStreams loadedStreams = mLoadedStreams; + + this->_loadTex(loadedStreams); + + } + //--------------------------------------------------------------------- + void D3D11Texture::freeInternalResources(void) + { + freeInternalResourcesImpl(); + } + //--------------------------------------------------------------------- + void D3D11Texture::freeInternalResourcesImpl() + { + SAFE_RELEASE(mpTex); SAFE_RELEASE(mpShaderResourceView); - SAFE_RELEASE(mp1DTex); - SAFE_RELEASE(mp2DTex); - SAFE_RELEASE(mp3DTex); -//#ifdef USE_D3DX11_LIBRARY -// SAFE_RELEASE(mEffect(NULL)); + SAFE_RELEASE(mp1DTex); + SAFE_RELEASE(mp2DTex); + SAFE_RELEASE(mp3DTex); +//#ifdef USE_D3DX11_LIBRARY +// SAFE_RELEASE(mEffect(NULL)); //#endif - } - //--------------------------------------------------------------------- - void D3D11Texture::_loadTex(LoadedStreams & loadedStreams) - { - size_t pos = mName.find_last_of("."); - String ext = mName.substr(pos+1); - String baseName = mName.substr(0, pos); - if((getSourceFileType() != "dds") && (this->getTextureType() == TEX_TYPE_CUBE_MAP)) - { - // Load from 6 separate files - // Use OGRE its own codecs - // String baseName; - // size_t pos = mName.find_last_of("."); - - // if ( pos != String::npos ) - // ext = mName.substr(pos+1); - vector::type images(6); - ConstImagePtrList imagePtrs; - static const String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"}; + } + //--------------------------------------------------------------------- + void D3D11Texture::_loadTex(LoadedStreams & loadedStreams) + { + size_t pos = mName.find_last_of("."); + String ext = mName.substr(pos+1); + String baseName = mName.substr(0, pos); + if((getSourceFileType() != "dds") && (this->getTextureType() == TEX_TYPE_CUBE_MAP)) + { + // Load from 6 separate files + // Use OGRE its own codecs + // String baseName; + // size_t pos = mName.find_last_of("."); + + // if ( pos != String::npos ) + // ext = mName.substr(pos+1); + vector::type images(6); + ConstImagePtrList imagePtrs; + static const String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"}; assert(loadedStreams->size()==6); - for(size_t i = 0; i < 6; i++) - { - String fullName = baseName + suffixes[i]; - if (!ext.empty()) - fullName = fullName + "." + ext; + for(size_t i = 0; i < 6; i++) + { + String fullName = baseName + suffixes[i]; + if (!ext.empty()) + fullName = fullName + "." + ext; - // find & load resource data intro stream to allow resource - // group changes if required - DataStreamPtr stream((*loadedStreams)[i]); + // find & load resource data intro stream to allow resource + // group changes if required + DataStreamPtr stream((*loadedStreams)[i]); - images[i].load(stream, ext); + images[i].load(stream, ext); - size_t imageMips = images[i].getNumMipmaps(); + size_t imageMips = images[i].getNumMipmaps(); - if(imageMips < mNumMipmaps) { - mNumMipmaps = imageMips; - } + if(imageMips < mNumMipmaps) { + mNumMipmaps = imageMips; + } - imagePtrs.push_back(&images[i]); - } + imagePtrs.push_back(&images[i]); + } - _loadImages( imagePtrs ); + _loadImages( imagePtrs ); - } - else - { + } + else + { assert(loadedStreams->size()==1); - Image img; - DataStreamPtr dstream((*loadedStreams)[0]); -#ifdef USE_D3DX11_LIBRARY - if(ext=="dds") - { - _loadDDS(dstream); - } - else + Image img; + DataStreamPtr dstream((*loadedStreams)[0]); +#ifdef USE_D3DX11_LIBRARY + if(ext=="dds") + { + _loadDDS(dstream); + } + else #endif - { - img.load(dstream, ext); - loadImage(img); - } - } + { + img.load(dstream, ext); + loadImage(img); + } + } _setSrcAttributes(mWidth, mHeight, mDepth, mFormat); - } - //--------------------------------------------------------------------- -#ifdef USE_D3DX11_LIBRARY - void D3D11Texture::_loadDDS(DataStreamPtr &dstream) - { - HRESULT hr; + } + //--------------------------------------------------------------------- +#ifdef USE_D3DX11_LIBRARY + void D3D11Texture::_loadDDS(DataStreamPtr &dstream) + { + HRESULT hr; - MemoryDataStreamPtr memoryptr=MemoryDataStreamPtr(new MemoryDataStream(dstream)); + MemoryDataStreamPtr memoryptr=MemoryDataStreamPtr(new MemoryDataStream(dstream)); D3DX11_IMAGE_LOAD_INFO loadInfo; loadInfo.Usage = D3D11Mappings::_getUsage(mUsage); loadInfo.CpuAccessFlags = D3D11Mappings::_getAccessFlags(mUsage); - if(mUsage & TU_DYNAMIC) + if(mUsage & TU_DYNAMIC) { loadInfo.MipLevels = 1; } - // TO DO: check cpu access flags and use loadInfo only when it is needed. - // this is the first try - - // Load the Texture - if (loadInfo.CpuAccessFlags == D3D11_CPU_ACCESS_WRITE) - { - hr = D3DX11CreateTextureFromMemory( mDevice.get(), - memoryptr->getPtr(), - memoryptr->size(), - &loadInfo, - NULL, - &mpTex, - NULL ); - } - else - { - hr = D3DX11CreateTextureFromMemory( mDevice.get(), - memoryptr->getPtr(), - memoryptr->size(), - NULL, - NULL, - &mpTex, - NULL ); - } - - if( FAILED( hr ) ) - { - LogManager::getSingleton().logMessage("D3D11 : " + mName + " Could not be loaded"); - return; - } - - D3D11_RESOURCE_DIMENSION dimension; - mpTex->GetType(&dimension); - - switch (dimension) - { - case D3D11_RESOURCE_DIMENSION_TEXTURE1D: - { - _queryInterface(mpTex, &mp1DTex); - - D3D11_TEXTURE1D_DESC desc; - mp1DTex->GetDesc(&desc); - - mFormat = D3D11Mappings::_getPF(desc.Format); - mTextureType = TEX_TYPE_1D; - - _create1DResourceView(); - } - break; - case D3D11_RESOURCE_DIMENSION_TEXTURE2D: - { - _queryInterface(mpTex, &mp2DTex); - - D3D11_TEXTURE2D_DESC desc; - mp2DTex->GetDesc(&desc); - - mFormat = D3D11Mappings::_getPF(desc.Format); - - if(desc.ArraySize % 6 == 0 && desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) - mTextureType = TEX_TYPE_CUBE_MAP; //2darray cubemap - else if(desc.ArraySize > 1) - mTextureType = TEX_TYPE_2D_ARRAY; - else - mTextureType = TEX_TYPE_2D; - - _create2DResourceView(); - } - break; - case D3D11_RESOURCE_DIMENSION_TEXTURE3D: - { - _queryInterface(mpTex, &mp3DTex); - - D3D11_TEXTURE3D_DESC desc; - mp3DTex->GetDesc(&desc); - - mFormat = D3D11Mappings::_getPF(desc.Format); - mTextureType = TEX_TYPE_3D; - - _create3DResourceView(); - } - break; - } - } + // TO DO: check cpu access flags and use loadInfo only when it is needed. + // this is the first try + + // Load the Texture + if (loadInfo.CpuAccessFlags == D3D11_CPU_ACCESS_WRITE) + { + hr = D3DX11CreateTextureFromMemory( mDevice.get(), + memoryptr->getPtr(), + memoryptr->size(), + &loadInfo, + NULL, + &mpTex, + NULL ); + } + else + { + hr = D3DX11CreateTextureFromMemory( mDevice.get(), + memoryptr->getPtr(), + memoryptr->size(), + NULL, + NULL, + &mpTex, + NULL ); + } + + if( FAILED( hr ) ) + { + LogManager::getSingleton().logMessage("D3D11 : " + mName + " Could not be loaded"); + return; + } + + D3D11_RESOURCE_DIMENSION dimension; + mpTex->GetType(&dimension); + + switch (dimension) + { + case D3D11_RESOURCE_DIMENSION_TEXTURE1D: + { + _queryInterface(mpTex, &mp1DTex); + + D3D11_TEXTURE1D_DESC desc; + mp1DTex->GetDesc(&desc); + + mFormat = D3D11Mappings::_getPF(desc.Format); + mTextureType = TEX_TYPE_1D; + + _create1DResourceView(); + } + break; + case D3D11_RESOURCE_DIMENSION_TEXTURE2D: + { + _queryInterface(mpTex, &mp2DTex); + + D3D11_TEXTURE2D_DESC desc; + mp2DTex->GetDesc(&desc); + + mFormat = D3D11Mappings::_getPF(desc.Format); + + if(desc.ArraySize % 6 == 0 && desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) + mTextureType = TEX_TYPE_CUBE_MAP; //2darray cubemap + else if(desc.ArraySize > 1) + mTextureType = TEX_TYPE_2D_ARRAY; + else + mTextureType = TEX_TYPE_2D; + + _create2DResourceView(); + } + break; + case D3D11_RESOURCE_DIMENSION_TEXTURE3D: + { + _queryInterface(mpTex, &mp3DTex); + + D3D11_TEXTURE3D_DESC desc; + mp3DTex->GetDesc(&desc); + + mFormat = D3D11Mappings::_getPF(desc.Format); + mTextureType = TEX_TYPE_3D; + + _create3DResourceView(); + } + break; + } + } #endif //--------------------------------------------------------------------- - void D3D11Texture::createInternalResources(void) - { - createInternalResourcesImpl(); - } - - //--------------------------------------------------------------------- - void D3D11Texture::createInternalResourcesImpl(void) - { - // If mSrcWidth and mSrcHeight are zero, the requested extents have probably been set - // through setWidth and setHeight, which set mWidth and mHeight. Take those values. - if(mSrcWidth == 0 || mSrcHeight == 0) { - mSrcWidth = mWidth; - mSrcHeight = mHeight; - } - - // Determine D3D pool to use - // Use managed unless we're a render target or user has asked for - // a dynamic texture - if (//(mUsage & TU_RENDERTARGET) || - (mUsage & TU_DYNAMIC)) - { - mIsDynamic = true; - } - else - { - mIsDynamic = false; - } - // load based on tex.type - switch (this->getTextureType()) - { - case TEX_TYPE_1D: - { - D3D11RenderSystem* rs = (D3D11RenderSystem*)Root::getSingleton().getRenderSystem(); - if(rs->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) - { - this->_create1DTex(); - break; // For Feature levels that do not support 1D textures, revert to creating a 2D texture. - } - } - case TEX_TYPE_2D: - case TEX_TYPE_CUBE_MAP: - case TEX_TYPE_2D_ARRAY: - this->_create2DTex(); - break; - case TEX_TYPE_3D: - this->_create3DTex(); - break; - default: - this->freeInternalResources(); - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D11Texture::createInternalResources" ); - } - } - //--------------------------------------------------------------------- - void D3D11Texture::_create1DTex() - { - // we must have those defined here - assert(mSrcWidth > 0 || mSrcHeight > 0); - - // determine which D3D11 pixel format we'll use - HRESULT hr; - DXGI_FORMAT d3dPF = this->_chooseD3DFormat(); - - // determine total number of mipmaps including main one (d3d11 convention) - UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED || (1U << mNumRequestedMipmaps) > mSrcWidth) ? 0 : mNumRequestedMipmaps + 1; - - D3D11_TEXTURE1D_DESC desc; - desc.Width = static_cast(mSrcWidth); - desc.MipLevels = numMips; - desc.ArraySize = 1; - desc.Format = d3dPF; - desc.Usage = D3D11Mappings::_getUsage(mUsage); - desc.BindFlags = D3D11Mappings::_getTextureBindFlags(d3dPF, mIsDynamic); - desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage); - desc.MiscFlags = D3D11Mappings::_getTextureMiscFlags(desc.BindFlags, getTextureType(), mIsDynamic); - - // create the texture - hr = mDevice->CreateTexture1D( - &desc, - NULL, - &mp1DTex); // data pointer - // check result and except if failed - if (FAILED(hr) || mDevice.isError()) - { - this->freeInternalResources(); - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture\nError Description:" + errorDescription, - "D3D11Texture::_create1DTex" ); - } - - _queryInterface(mp1DTex, &mpTex); - _create1DResourceView(); - } - //--------------------------------------------------------------------- - void D3D11Texture::_create1DResourceView() - { - // set final tex. attributes from tex. description - // they may differ from the source image !!! - HRESULT hr; - D3D11_TEXTURE1D_DESC desc; - - // set final tex. attributes from tex. description - // they may differ from the source image !!! - mp1DTex->GetDesc(&desc); - mNumMipmaps = desc.MipLevels - 1; - - ZeroMemory( &mSRVDesc, sizeof(mSRVDesc) ); - mSRVDesc.Format = desc.Format; - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; - mSRVDesc.Texture1D.MipLevels = desc.MipLevels; - hr = mDevice->CreateShaderResourceView( mp1DTex, &mSRVDesc, &mpShaderResourceView ); - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device can't create shader resource view.\nError Description:" + errorDescription, - "D3D11Texture::_create1DTex"); - } + void D3D11Texture::createInternalResources(void) + { + createInternalResourcesImpl(); + } + + //--------------------------------------------------------------------- + void D3D11Texture::createInternalResourcesImpl(void) + { + // If mSrcWidth and mSrcHeight are zero, the requested extents have probably been set + // through setWidth and setHeight, which set mWidth and mHeight. Take those values. + if(mSrcWidth == 0 || mSrcHeight == 0) { + mSrcWidth = mWidth; + mSrcHeight = mHeight; + } + + // Determine D3D pool to use + // Use managed unless we're a render target or user has asked for + // a dynamic texture + if (//(mUsage & TU_RENDERTARGET) || + (mUsage & TU_DYNAMIC)) + { + mIsDynamic = true; + } + else + { + mIsDynamic = false; + } + // load based on tex.type + switch (this->getTextureType()) + { + case TEX_TYPE_1D: + { + D3D11RenderSystem* rs = (D3D11RenderSystem*)Root::getSingleton().getRenderSystem(); + if(rs->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) + { + this->_create1DTex(); + break; // For Feature levels that do not support 1D textures, revert to creating a 2D texture. + } + } + case TEX_TYPE_2D: + case TEX_TYPE_CUBE_MAP: + case TEX_TYPE_2D_ARRAY: + this->_create2DTex(); + break; + case TEX_TYPE_3D: + this->_create3DTex(); + break; + default: + this->freeInternalResources(); + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D11Texture::createInternalResources" ); + } + } + //--------------------------------------------------------------------- + void D3D11Texture::_create1DTex() + { + // we must have those defined here + assert(mSrcWidth > 0 || mSrcHeight > 0); + + // determine which D3D11 pixel format we'll use + HRESULT hr; + DXGI_FORMAT d3dPF = this->_chooseD3DFormat(); + + // determine total number of mipmaps including main one (d3d11 convention) + UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED || (1U << mNumRequestedMipmaps) > mSrcWidth) ? 0 : mNumRequestedMipmaps + 1; + + D3D11_TEXTURE1D_DESC desc; + desc.Width = static_cast(mSrcWidth); + desc.MipLevels = numMips; + desc.ArraySize = 1; + desc.Format = d3dPF; + desc.Usage = D3D11Mappings::_getUsage(mUsage); + desc.BindFlags = D3D11Mappings::_getTextureBindFlags(d3dPF, mIsDynamic); + desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage); + desc.MiscFlags = D3D11Mappings::_getTextureMiscFlags(desc.BindFlags, getTextureType(), mIsDynamic); + + // create the texture + hr = mDevice->CreateTexture1D( + &desc, + NULL, + &mp1DTex); // data pointer + // check result and except if failed + if (FAILED(hr) || mDevice.isError()) + { + this->freeInternalResources(); + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture\nError Description:" + errorDescription, + "D3D11Texture::_create1DTex" ); + } + + _queryInterface(mp1DTex, &mpTex); + _create1DResourceView(); + } + //--------------------------------------------------------------------- + void D3D11Texture::_create1DResourceView() + { + // set final tex. attributes from tex. description + // they may differ from the source image !!! + HRESULT hr; + D3D11_TEXTURE1D_DESC desc; + + // set final tex. attributes from tex. description + // they may differ from the source image !!! + mp1DTex->GetDesc(&desc); + mNumMipmaps = desc.MipLevels - 1; + + ZeroMemory( &mSRVDesc, sizeof(mSRVDesc) ); + mSRVDesc.Format = desc.Format; + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; + mSRVDesc.Texture1D.MipLevels = desc.MipLevels; + hr = mDevice->CreateShaderResourceView( mp1DTex, &mSRVDesc, &mpShaderResourceView ); + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device can't create shader resource view.\nError Description:" + errorDescription, + "D3D11Texture::_create1DTex"); + } //#ifdef USE_D3DX11_LIBRARY -// ID3DX11EffectVariable *v = mEffect->GetVariableByIndex(mEffectIndex++); -// v->AsShaderResource()->SetResource(mpShaderResourceView); +// ID3DX11EffectVariable *v = mEffect->GetVariableByIndex(mEffectIndex++); +// v->AsShaderResource()->SetResource(mpShaderResourceView); //#endif - this->_setFinalAttributes(desc.Width, 1, 1, D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); + this->_setFinalAttributes(desc.Width, 1, 1, D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); - } + } + //--------------------------------------------------------------------- + inline bool IsPowerOfTwo(unsigned int n) { return ((n&(n-1))==0); } //--------------------------------------------------------------------- - inline bool IsPowerOfTwo(unsigned int n) { return ((n&(n-1))==0); } - //--------------------------------------------------------------------- - void D3D11Texture::_create2DTex() - { - // we must have those defined here - assert(mSrcWidth > 0 || mSrcHeight > 0); - - // determine which D3D11 pixel format we'll use - HRESULT hr; - DXGI_FORMAT d3dPF = this->_chooseD3DFormat(); - - bool isBinaryCompressedFormat = - d3dPF == DXGI_FORMAT_BC1_TYPELESS || d3dPF == DXGI_FORMAT_BC1_UNORM || d3dPF == DXGI_FORMAT_BC1_UNORM_SRGB || - d3dPF == DXGI_FORMAT_BC2_TYPELESS || d3dPF == DXGI_FORMAT_BC2_UNORM || d3dPF == DXGI_FORMAT_BC2_UNORM_SRGB || - d3dPF == DXGI_FORMAT_BC3_TYPELESS || d3dPF == DXGI_FORMAT_BC3_UNORM || d3dPF == DXGI_FORMAT_BC3_UNORM_SRGB || - d3dPF == DXGI_FORMAT_BC4_TYPELESS || d3dPF == DXGI_FORMAT_BC4_UNORM || d3dPF == DXGI_FORMAT_BC4_SNORM || - d3dPF == DXGI_FORMAT_BC5_TYPELESS || d3dPF == DXGI_FORMAT_BC5_UNORM || d3dPF == DXGI_FORMAT_BC5_SNORM || + void D3D11Texture::_create2DTex() + { + // we must have those defined here + assert(mSrcWidth > 0 || mSrcHeight > 0); + + // determine which D3D11 pixel format we'll use + HRESULT hr; + DXGI_FORMAT d3dPF = this->_chooseD3DFormat(); + + bool isBinaryCompressedFormat = + d3dPF == DXGI_FORMAT_BC1_TYPELESS || d3dPF == DXGI_FORMAT_BC1_UNORM || d3dPF == DXGI_FORMAT_BC1_UNORM_SRGB || + d3dPF == DXGI_FORMAT_BC2_TYPELESS || d3dPF == DXGI_FORMAT_BC2_UNORM || d3dPF == DXGI_FORMAT_BC2_UNORM_SRGB || + d3dPF == DXGI_FORMAT_BC3_TYPELESS || d3dPF == DXGI_FORMAT_BC3_UNORM || d3dPF == DXGI_FORMAT_BC3_UNORM_SRGB || + d3dPF == DXGI_FORMAT_BC4_TYPELESS || d3dPF == DXGI_FORMAT_BC4_UNORM || d3dPF == DXGI_FORMAT_BC4_SNORM || + d3dPF == DXGI_FORMAT_BC5_TYPELESS || d3dPF == DXGI_FORMAT_BC5_UNORM || d3dPF == DXGI_FORMAT_BC5_SNORM || #if OGRE_PLATFORM == OGRE_PLATFORM_WINRT #endif - d3dPF == DXGI_FORMAT_BC6H_TYPELESS || d3dPF == DXGI_FORMAT_BC6H_UF16 || d3dPF == DXGI_FORMAT_BC6H_SF16 || - d3dPF == DXGI_FORMAT_BC7_TYPELESS || d3dPF == DXGI_FORMAT_BC7_UNORM || d3dPF == DXGI_FORMAT_BC7_UNORM_SRGB || + d3dPF == DXGI_FORMAT_BC6H_TYPELESS || d3dPF == DXGI_FORMAT_BC6H_UF16 || d3dPF == DXGI_FORMAT_BC6H_SF16 || + d3dPF == DXGI_FORMAT_BC7_TYPELESS || d3dPF == DXGI_FORMAT_BC7_UNORM || d3dPF == DXGI_FORMAT_BC7_UNORM_SRGB || - 0; + 0; - // determine total number of mipmaps including main one (d3d11 convention) - UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED || (1U << mNumRequestedMipmaps) > std::max(mSrcWidth, mSrcHeight)) ? 0 : mNumRequestedMipmaps + 1; - if(isBinaryCompressedFormat && numMips > 1) - numMips = std::max(1U, numMips - 2); + // determine total number of mipmaps including main one (d3d11 convention) + UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED || (1U << mNumRequestedMipmaps) > std::max(mSrcWidth, mSrcHeight)) ? 0 : mNumRequestedMipmaps + 1; + if(isBinaryCompressedFormat && numMips > 1) + numMips = std::max(1U, numMips - 2); - D3D11_TEXTURE2D_DESC desc; - desc.Width = static_cast(mSrcWidth); - desc.Height = static_cast(mSrcHeight); - desc.MipLevels = numMips; - desc.ArraySize = mDepth == 0 ? 1 : mDepth; - desc.Format = d3dPF; + D3D11_TEXTURE2D_DESC desc; + desc.Width = static_cast(mSrcWidth); + desc.Height = static_cast(mSrcHeight); + desc.MipLevels = numMips; + desc.ArraySize = mDepth == 0 ? 1 : mDepth; + desc.Format = d3dPF; - // Handle multisampled render target + // Handle multisampled render target if (mUsage & TU_RENDERTARGET && (mFSAA > 1 || atoi(mFSAAHint.c_str()) > 0)) { desc.SampleDesc.Count = mFSAA; @@ -520,7 +520,7 @@ namespace Ogre desc.ArraySize = 6; } - if( isBinaryCompressedFormat ) + if( isBinaryCompressedFormat ) { desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; @@ -543,647 +543,647 @@ namespace Ogre #endif } - // create the texture - hr = mDevice->CreateTexture2D( - &desc, - NULL,// data pointer - &mp2DTex); - // check result and except if failed - if (FAILED(hr) || mDevice.isError()) - { - this->freeInternalResources(); - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Error creating texture\nError Description:" + errorDescription, - "D3D11Texture::_create2DTex" ); - } - - //set the base texture we'll use in the render system - _queryInterface(mp2DTex, &mpTex); - - _create2DResourceView(); - } - //---------------------------------------------------------------------------- - void D3D11Texture::_create2DResourceView() - { - // set final tex. attributes from tex. description - // they may differ from the source image !!! - HRESULT hr; - D3D11_TEXTURE2D_DESC desc; - mp2DTex->GetDesc(&desc); - mNumMipmaps = desc.MipLevels - 1; - - ZeroMemory( &mSRVDesc, sizeof(mSRVDesc) ); - mSRVDesc.Format = desc.Format; - - switch(this->getTextureType()) - { - case TEX_TYPE_CUBE_MAP: - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - mSRVDesc.TextureCube.MipLevels = desc.MipLevels; - mSRVDesc.TextureCube.MostDetailedMip = 0; - break; - - case TEX_TYPE_2D_ARRAY: - if (mUsage & TU_RENDERTARGET && (mFSAA > 1 || atoi(mFSAAHint.c_str()) > 0)) - { - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; - mSRVDesc.Texture2DMSArray.FirstArraySlice = 0; - mSRVDesc.Texture2DMSArray.ArraySize = desc.ArraySize; - } - else - { - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - mSRVDesc.Texture2DArray.MostDetailedMip = 0; - mSRVDesc.Texture2DArray.MipLevels = desc.MipLevels; - mSRVDesc.Texture2DArray.FirstArraySlice = 0; - mSRVDesc.Texture2DArray.ArraySize = desc.ArraySize; - } - break; - - case TEX_TYPE_2D: - case TEX_TYPE_1D: // For Feature levels that do not support 1D textures, revert to creating a 2D texture. - if (mUsage & TU_RENDERTARGET && (mFSAA > 1 || atoi(mFSAAHint.c_str()) > 0)) - { - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; - } - else - { - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - mSRVDesc.Texture2D.MostDetailedMip = 0; - mSRVDesc.Texture2D.MipLevels = desc.MipLevels; - } - break; - } - - hr = mDevice->CreateShaderResourceView( mp2DTex, &mSRVDesc, &mpShaderResourceView ); - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device can't create shader resource view.\nError Description:" + errorDescription, - "D3D11Texture::_create2DTex"); - } + // create the texture + hr = mDevice->CreateTexture2D( + &desc, + NULL,// data pointer + &mp2DTex); + // check result and except if failed + if (FAILED(hr) || mDevice.isError()) + { + this->freeInternalResources(); + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Error creating texture\nError Description:" + errorDescription, + "D3D11Texture::_create2DTex" ); + } + + //set the base texture we'll use in the render system + _queryInterface(mp2DTex, &mpTex); + + _create2DResourceView(); + } + //---------------------------------------------------------------------------- + void D3D11Texture::_create2DResourceView() + { + // set final tex. attributes from tex. description + // they may differ from the source image !!! + HRESULT hr; + D3D11_TEXTURE2D_DESC desc; + mp2DTex->GetDesc(&desc); + mNumMipmaps = desc.MipLevels - 1; + + ZeroMemory( &mSRVDesc, sizeof(mSRVDesc) ); + mSRVDesc.Format = desc.Format; + + switch(this->getTextureType()) + { + case TEX_TYPE_CUBE_MAP: + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + mSRVDesc.TextureCube.MipLevels = desc.MipLevels; + mSRVDesc.TextureCube.MostDetailedMip = 0; + break; + + case TEX_TYPE_2D_ARRAY: + if (mUsage & TU_RENDERTARGET && (mFSAA > 1 || atoi(mFSAAHint.c_str()) > 0)) + { + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + mSRVDesc.Texture2DMSArray.FirstArraySlice = 0; + mSRVDesc.Texture2DMSArray.ArraySize = desc.ArraySize; + } + else + { + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + mSRVDesc.Texture2DArray.MostDetailedMip = 0; + mSRVDesc.Texture2DArray.MipLevels = desc.MipLevels; + mSRVDesc.Texture2DArray.FirstArraySlice = 0; + mSRVDesc.Texture2DArray.ArraySize = desc.ArraySize; + } + break; + + case TEX_TYPE_2D: + case TEX_TYPE_1D: // For Feature levels that do not support 1D textures, revert to creating a 2D texture. + if (mUsage & TU_RENDERTARGET && (mFSAA > 1 || atoi(mFSAAHint.c_str()) > 0)) + { + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + } + else + { + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + mSRVDesc.Texture2D.MostDetailedMip = 0; + mSRVDesc.Texture2D.MipLevels = desc.MipLevels; + } + break; + } + + hr = mDevice->CreateShaderResourceView( mp2DTex, &mSRVDesc, &mpShaderResourceView ); + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device can't create shader resource view.\nError Description:" + errorDescription, + "D3D11Texture::_create2DTex"); + } //#ifdef USE_D3DX11_LIBRARY -// ID3DX11EffectVariable *v = mEffect->GetVariableByIndex(mEffectIndex++); -// v->AsShaderResource()->SetResource(mpShaderResourceView); +// ID3DX11EffectVariable *v = mEffect->GetVariableByIndex(mEffectIndex++); +// v->AsShaderResource()->SetResource(mpShaderResourceView); //#endif - this->_setFinalAttributes(desc.Width, desc.Height, desc.ArraySize, D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); - } - //--------------------------------------------------------------------- - void D3D11Texture::_create3DTex() - { - // we must have those defined here - assert(mWidth > 0 && mHeight > 0 && mDepth>0); - - // determine which D3D11 pixel format we'll use - HRESULT hr; - DXGI_FORMAT d3dPF = this->_chooseD3DFormat(); - - // determine total number of mipmaps including main one (d3d11 convention) - UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED || (1U << mNumRequestedMipmaps) > std::max(std::max(mSrcWidth, mSrcHeight), mDepth)) ? 0 : mNumRequestedMipmaps + 1; - - D3D11_TEXTURE3D_DESC desc; - desc.Width = static_cast(mSrcWidth); - desc.Height = static_cast(mSrcHeight); - desc.Depth = static_cast(mDepth); - desc.MipLevels = numMips; - desc.Format = d3dPF; - desc.Usage = D3D11Mappings::_getUsage(mUsage); - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - - D3D11RenderSystem* rsys = reinterpret_cast(Root::getSingleton().getRenderSystem()); - if (rsys->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) - desc.BindFlags |= D3D11_BIND_RENDER_TARGET; - - desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage); - desc.MiscFlags = 0; - if (mIsDynamic) - { - desc.Usage = D3D11_USAGE_DYNAMIC; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE ; - } - - // create the texture - hr = mDevice->CreateTexture3D( - &desc, - NULL, - &mp3DTex); // data pointer - // check result and except if failed - if (FAILED(hr) || mDevice.isError()) - { - this->freeInternalResources(); - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Error creating texture\nError Description:" + errorDescription, - "D3D11Texture::_create3DTex" ); - } - - _queryInterface(mp3DTex, &mpTex); - _create3DResourceView(); - } - //------------------------------------------------------------------------------- - void D3D11Texture::_create3DResourceView() - { - // set final tex. attributes from tex. description - // they may differ from the source image !!! - HRESULT hr; - D3D11_TEXTURE3D_DESC desc; - mp3DTex->GetDesc(&desc); - mNumMipmaps = desc.MipLevels - 1; - - ZeroMemory( &mSRVDesc, sizeof(mSRVDesc) ); - mSRVDesc.Format = desc.Format; - mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; - mSRVDesc.Texture3D.MostDetailedMip = 0; - mSRVDesc.Texture3D.MipLevels = desc.MipLevels; - hr = mDevice->CreateShaderResourceView( mp3DTex, &mSRVDesc, &mpShaderResourceView ); - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "D3D11 device can't create shader resource view.\nError Description:" + errorDescription, - "D3D11Texture::_create3DTex"); - } + this->_setFinalAttributes(desc.Width, desc.Height, desc.ArraySize, D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); + } + //--------------------------------------------------------------------- + void D3D11Texture::_create3DTex() + { + // we must have those defined here + assert(mWidth > 0 && mHeight > 0 && mDepth>0); + + // determine which D3D11 pixel format we'll use + HRESULT hr; + DXGI_FORMAT d3dPF = this->_chooseD3DFormat(); + + // determine total number of mipmaps including main one (d3d11 convention) + UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED || (1U << mNumRequestedMipmaps) > std::max(std::max(mSrcWidth, mSrcHeight), mDepth)) ? 0 : mNumRequestedMipmaps + 1; + + D3D11_TEXTURE3D_DESC desc; + desc.Width = static_cast(mSrcWidth); + desc.Height = static_cast(mSrcHeight); + desc.Depth = static_cast(mDepth); + desc.MipLevels = numMips; + desc.Format = d3dPF; + desc.Usage = D3D11Mappings::_getUsage(mUsage); + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + + D3D11RenderSystem* rsys = reinterpret_cast(Root::getSingleton().getRenderSystem()); + if (rsys->_getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) + desc.BindFlags |= D3D11_BIND_RENDER_TARGET; + + desc.CPUAccessFlags = D3D11Mappings::_getAccessFlags(mUsage); + desc.MiscFlags = 0; + if (mIsDynamic) + { + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE ; + } + + // create the texture + hr = mDevice->CreateTexture3D( + &desc, + NULL, + &mp3DTex); // data pointer + // check result and except if failed + if (FAILED(hr) || mDevice.isError()) + { + this->freeInternalResources(); + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Error creating texture\nError Description:" + errorDescription, + "D3D11Texture::_create3DTex" ); + } + + _queryInterface(mp3DTex, &mpTex); + _create3DResourceView(); + } + //------------------------------------------------------------------------------- + void D3D11Texture::_create3DResourceView() + { + // set final tex. attributes from tex. description + // they may differ from the source image !!! + HRESULT hr; + D3D11_TEXTURE3D_DESC desc; + mp3DTex->GetDesc(&desc); + mNumMipmaps = desc.MipLevels - 1; + + ZeroMemory( &mSRVDesc, sizeof(mSRVDesc) ); + mSRVDesc.Format = desc.Format; + mSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + mSRVDesc.Texture3D.MostDetailedMip = 0; + mSRVDesc.Texture3D.MipLevels = desc.MipLevels; + hr = mDevice->CreateShaderResourceView( mp3DTex, &mSRVDesc, &mpShaderResourceView ); + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "D3D11 device can't create shader resource view.\nError Description:" + errorDescription, + "D3D11Texture::_create3DTex"); + } //#ifdef USE_D3DX11_LIBRARY -// ID3DX11EffectVariable *v = mEffect->GetVariableByIndex(mEffectIndex++); -// v->AsShaderResource()->SetResource(mpShaderResourceView); +// ID3DX11EffectVariable *v = mEffect->GetVariableByIndex(mEffectIndex++); +// v->AsShaderResource()->SetResource(mpShaderResourceView); //#endif - this->_setFinalAttributes(desc.Width, desc.Height, desc.Depth, D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); - } - //------------------------------------------------------------------------------- - void D3D11Texture::_setFinalAttributes(unsigned long width, unsigned long height, - unsigned long depth, PixelFormat format, UINT miscflags) - { - // set target texture attributes - mHeight = height; - mWidth = width; - mDepth = depth; - mFormat = format; - mAutoMipMapGeneration = miscflags & D3D11_RESOURCE_MISC_GENERATE_MIPS; - - // Update size (the final size, including temp space because in consumed memory) - // this is needed in Resource class - mSize = calculateSize(); - - // say to the world what we are doing - if (mWidth != mSrcWidth || - mHeight != mSrcHeight) - { - LogManager::getSingleton().logMessage("D3D11 : ***** Dimensions altered by the render system"); - LogManager::getSingleton().logMessage("D3D11 : ***** Source image dimensions : " + StringConverter::toString(mSrcWidth) + "x" + StringConverter::toString(mSrcHeight)); - LogManager::getSingleton().logMessage("D3D11 : ***** Texture dimensions : " + StringConverter::toString(mWidth) + "x" + StringConverter::toString(mHeight)); - } - - // Create list of subsurfaces for getBuffer() - _createSurfaceList(); - } - //--------------------------------------------------------------------- - void D3D11Texture::_setSrcAttributes(unsigned long width, unsigned long height, - unsigned long depth, PixelFormat format) - { - // set source image attributes - mSrcWidth = width; - mSrcHeight = height; - mSrcDepth = depth; - mSrcFormat = format; - // say to the world what we are doing - switch (this->getTextureType()) - { - case TEX_TYPE_1D: - if (mUsage & TU_RENDERTARGET) - LogManager::getSingleton().logMessage("D3D11 : Creating 1D RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - else - LogManager::getSingleton().logMessage("D3D11 : Loading 1D Texture, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - break; - case TEX_TYPE_2D: - if (mUsage & TU_RENDERTARGET) - LogManager::getSingleton().logMessage("D3D11 : Creating 2D RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - else - LogManager::getSingleton().logMessage("D3D11 : Loading 2D Texture, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - break; - case TEX_TYPE_2D_ARRAY: - if (mUsage & TU_RENDERTARGET) - LogManager::getSingleton().logMessage("D3D11 : Creating 2D array RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - else - LogManager::getSingleton().logMessage("D3D11 : Loading 2D Texture array, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - break; - case TEX_TYPE_3D: - if (mUsage & TU_RENDERTARGET) - LogManager::getSingleton().logMessage("D3D11 : Creating 3D RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - else - LogManager::getSingleton().logMessage("D3D11 : Loading 3D Texture, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - break; - case TEX_TYPE_CUBE_MAP: - if (mUsage & TU_RENDERTARGET) - LogManager::getSingleton().logMessage("D3D11 : Creating Cube map RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - else - LogManager::getSingleton().logMessage("D3D11 : Loading Cube Texture, base image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - break; - default: - this->freeInternalResources(); - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D11Texture::_setSrcAttributes" ); - } - } - //--------------------------------------------------------------------- - DXGI_FORMAT D3D11Texture::_chooseD3DFormat() - { - // Choose frame buffer pixel format in case PF_UNKNOWN was requested - if(mFormat == PF_UNKNOWN) - return mBBPixelFormat; - - D3D11RenderSystem* rsys = reinterpret_cast(Root::getSingleton().getRenderSystem()); - if (rsys->_getFeatureLevel() < D3D_FEATURE_LEVEL_10_0 && mFormat == PF_L8) - { - // For 3D textures, PF_L8, which maps to DXGI_FORMAT_R8_UNORM, is not supported but PF_A8, which maps to DXGI_FORMAT_R8_UNORM is supported. - mFormat = PF_A8; - mNumRequestedMipmaps = 0; - } - - // Choose closest supported D3D format as a D3D format - return D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat)); - - } - //--------------------------------------------------------------------- - void D3D11Texture::_createSurfaceList(void) - { - unsigned int bufusage; - if ((mUsage & TU_DYNAMIC)) - { - bufusage = HardwareBuffer::HBU_DYNAMIC; - } - else - { - bufusage = HardwareBuffer::HBU_STATIC; - } - if (mUsage & TU_RENDERTARGET) - { - bufusage |= TU_RENDERTARGET; - } - - bool updateOldList = mSurfaceList.size() == (getNumFaces() * (mNumMipmaps + 1)); - if(!updateOldList) - { - // Create new list of surfaces - mSurfaceList.clear(); - PixelFormat format = D3D11Mappings::_getClosestSupportedPF(mSrcFormat); - size_t depth = mDepth; - - for(size_t face=0; face 0) - { - subresourceIndex = mip; - - } - buffer = new D3D11HardwarePixelBuffer( - this, // parentTexture - mDevice, // device - subresourceIndex, // subresourceIndex - width, - height, - depth, - face, - format, - (HardwareBuffer::Usage)bufusage // usage - ); - - mSurfaceList.push_back( - HardwarePixelBufferSharedPtr(buffer) - ); - width /= 2; - height /= 2; - } - } - } - - // do we need to bind? - - } - //--------------------------------------------------------------------- - HardwarePixelBufferSharedPtr D3D11Texture::getBuffer(size_t face, size_t mipmap) - { - if(face >= getNumFaces()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "A three dimensional cube has six faces", - "D3D11Texture::getBuffer"); - if(mipmap > mNumMipmaps) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range", - "D3D11Texture::getBuffer"); - size_t idx = face*(mNumMipmaps+1) + mipmap; - assert(idx < mSurfaceList.size()); - return mSurfaceList[idx]; - } - //--------------------------------------------------------------------- - bool D3D11Texture::releaseIfDefaultPool(void) - { - if(mIsDynamic) - { - LogManager::getSingleton().logMessage( - "Releasing D3D11 default pool texture: " + mName); - // Just free any internal resources, don't call unload() here - // because we want the un-touched resource to keep its unloaded status - // after device reset. - freeInternalResources(); - LogManager::getSingleton().logMessage( - "Released D3D11 default pool texture: " + mName); - return true; - } - return false; - } - //--------------------------------------------------------------------- - bool D3D11Texture::recreateIfDefaultPool(D3D11Device & device) - { - bool ret = false; - if(mIsDynamic) - { - ret = true; - LogManager::getSingleton().logMessage( - "Recreating D3D11 default pool texture: " + mName); - // We just want to create the texture resources if: - // 1. This is a render texture, or - // 2. This is a manual texture with no loader, or - // 3. This was an unloaded regular texture (preserve unloaded state) - if ((mIsManual && !mLoader) || (mUsage & TU_RENDERTARGET) || !isLoaded()) - { - // just recreate any internal resources - createInternalResources(); - } - // Otherwise, this is a regular loaded texture, or a manual texture with a loader - else - { - // The internal resources already freed, need unload/load here: - // 1. Make sure resource memory usage statistic correction. - // 2. Don't call unload() in releaseIfDefaultPool() because we want - // the un-touched resource keep unload status after device reset. - unload(); - // if manual, we need to recreate internal resources since load() won't do that - if (mIsManual) - createInternalResources(); - load(); - } - LogManager::getSingleton().logMessage( - "Recreated D3D11 default pool texture: " + mName); - } - - return ret; - - } - //--------------------------------------------------------------------- - D3D11_SHADER_RESOURCE_VIEW_DESC D3D11Texture::getShaderResourceViewDesc() const - { - return mSRVDesc; - } - //--------------------------------------------------------------------- - void D3D11Texture::prepareImpl( void ) - { - if (mUsage & TU_RENDERTARGET || isManuallyLoaded()) - { - return; - } - - //D3D11_DEVICE_ACCESS_CRITICAL_SECTION - + this->_setFinalAttributes(desc.Width, desc.Height, desc.Depth, D3D11Mappings::_getPF(desc.Format), desc.MiscFlags); + } + //------------------------------------------------------------------------------- + void D3D11Texture::_setFinalAttributes(unsigned long width, unsigned long height, + unsigned long depth, PixelFormat format, UINT miscflags) + { + // set target texture attributes + mHeight = height; + mWidth = width; + mDepth = depth; + mFormat = format; + mAutoMipMapGeneration = miscflags & D3D11_RESOURCE_MISC_GENERATE_MIPS; + + // Update size (the final size, including temp space because in consumed memory) + // this is needed in Resource class + mSize = calculateSize(); + + // say to the world what we are doing + if (mWidth != mSrcWidth || + mHeight != mSrcHeight) + { + LogManager::getSingleton().logMessage("D3D11 : ***** Dimensions altered by the render system"); + LogManager::getSingleton().logMessage("D3D11 : ***** Source image dimensions : " + StringConverter::toString(mSrcWidth) + "x" + StringConverter::toString(mSrcHeight)); + LogManager::getSingleton().logMessage("D3D11 : ***** Texture dimensions : " + StringConverter::toString(mWidth) + "x" + StringConverter::toString(mHeight)); + } + + // Create list of subsurfaces for getBuffer() + _createSurfaceList(); + } + //--------------------------------------------------------------------- + void D3D11Texture::_setSrcAttributes(unsigned long width, unsigned long height, + unsigned long depth, PixelFormat format) + { + // set source image attributes + mSrcWidth = width; + mSrcHeight = height; + mSrcDepth = depth; + mSrcFormat = format; + // say to the world what we are doing + switch (this->getTextureType()) + { + case TEX_TYPE_1D: + if (mUsage & TU_RENDERTARGET) + LogManager::getSingleton().logMessage("D3D11 : Creating 1D RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + else + LogManager::getSingleton().logMessage("D3D11 : Loading 1D Texture, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + break; + case TEX_TYPE_2D: + if (mUsage & TU_RENDERTARGET) + LogManager::getSingleton().logMessage("D3D11 : Creating 2D RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + else + LogManager::getSingleton().logMessage("D3D11 : Loading 2D Texture, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + break; + case TEX_TYPE_2D_ARRAY: + if (mUsage & TU_RENDERTARGET) + LogManager::getSingleton().logMessage("D3D11 : Creating 2D array RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + else + LogManager::getSingleton().logMessage("D3D11 : Loading 2D Texture array, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + break; + case TEX_TYPE_3D: + if (mUsage & TU_RENDERTARGET) + LogManager::getSingleton().logMessage("D3D11 : Creating 3D RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + else + LogManager::getSingleton().logMessage("D3D11 : Loading 3D Texture, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + break; + case TEX_TYPE_CUBE_MAP: + if (mUsage & TU_RENDERTARGET) + LogManager::getSingleton().logMessage("D3D11 : Creating Cube map RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + else + LogManager::getSingleton().logMessage("D3D11 : Loading Cube Texture, base image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + break; + default: + this->freeInternalResources(); + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D11Texture::_setSrcAttributes" ); + } + } + //--------------------------------------------------------------------- + DXGI_FORMAT D3D11Texture::_chooseD3DFormat() + { + // Choose frame buffer pixel format in case PF_UNKNOWN was requested + if(mFormat == PF_UNKNOWN) + return mBBPixelFormat; + + D3D11RenderSystem* rsys = reinterpret_cast(Root::getSingleton().getRenderSystem()); + if (rsys->_getFeatureLevel() < D3D_FEATURE_LEVEL_10_0 && mFormat == PF_L8) + { + // For 3D textures, PF_L8, which maps to DXGI_FORMAT_R8_UNORM, is not supported but PF_A8, which maps to DXGI_FORMAT_R8_UNORM is supported. + mFormat = PF_A8; + mNumRequestedMipmaps = 0; + } + + // Choose closest supported D3D format as a D3D format + return D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat)); + + } + //--------------------------------------------------------------------- + void D3D11Texture::_createSurfaceList(void) + { + unsigned int bufusage; + if ((mUsage & TU_DYNAMIC)) + { + bufusage = HardwareBuffer::HBU_DYNAMIC; + } + else + { + bufusage = HardwareBuffer::HBU_STATIC; + } + if (mUsage & TU_RENDERTARGET) + { + bufusage |= TU_RENDERTARGET; + } + + bool updateOldList = mSurfaceList.size() == (getNumFaces() * (mNumMipmaps + 1)); + if(!updateOldList) + { + // Create new list of surfaces + mSurfaceList.clear(); + PixelFormat format = D3D11Mappings::_getClosestSupportedPF(mSrcFormat); + size_t depth = mDepth; + + for(size_t face=0; face 0) + { + subresourceIndex = mip; + + } + buffer = new D3D11HardwarePixelBuffer( + this, // parentTexture + mDevice, // device + subresourceIndex, // subresourceIndex + width, + height, + depth, + face, + format, + (HardwareBuffer::Usage)bufusage // usage + ); + + mSurfaceList.push_back( + HardwarePixelBufferSharedPtr(buffer) + ); + width /= 2; + height /= 2; + } + } + } + + // do we need to bind? + + } + //--------------------------------------------------------------------- + HardwarePixelBufferSharedPtr D3D11Texture::getBuffer(size_t face, size_t mipmap) + { + if(face >= getNumFaces()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "A three dimensional cube has six faces", + "D3D11Texture::getBuffer"); + if(mipmap > mNumMipmaps) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range", + "D3D11Texture::getBuffer"); + size_t idx = face*(mNumMipmaps+1) + mipmap; + assert(idx < mSurfaceList.size()); + return mSurfaceList[idx]; + } + //--------------------------------------------------------------------- + bool D3D11Texture::releaseIfDefaultPool(void) + { + if(mIsDynamic) + { + LogManager::getSingleton().logMessage( + "Releasing D3D11 default pool texture: " + mName); + // Just free any internal resources, don't call unload() here + // because we want the un-touched resource to keep its unloaded status + // after device reset. + freeInternalResources(); + LogManager::getSingleton().logMessage( + "Released D3D11 default pool texture: " + mName); + return true; + } + return false; + } + //--------------------------------------------------------------------- + bool D3D11Texture::recreateIfDefaultPool(D3D11Device & device) + { + bool ret = false; + if(mIsDynamic) + { + ret = true; + LogManager::getSingleton().logMessage( + "Recreating D3D11 default pool texture: " + mName); + // We just want to create the texture resources if: + // 1. This is a render texture, or + // 2. This is a manual texture with no loader, or + // 3. This was an unloaded regular texture (preserve unloaded state) + if ((mIsManual && !mLoader) || (mUsage & TU_RENDERTARGET) || !isLoaded()) + { + // just recreate any internal resources + createInternalResources(); + } + // Otherwise, this is a regular loaded texture, or a manual texture with a loader + else + { + // The internal resources already freed, need unload/load here: + // 1. Make sure resource memory usage statistic correction. + // 2. Don't call unload() in releaseIfDefaultPool() because we want + // the un-touched resource keep unload status after device reset. + unload(); + // if manual, we need to recreate internal resources since load() won't do that + if (mIsManual) + createInternalResources(); + load(); + } + LogManager::getSingleton().logMessage( + "Recreated D3D11 default pool texture: " + mName); + } + + return ret; + + } + //--------------------------------------------------------------------- + D3D11_SHADER_RESOURCE_VIEW_DESC D3D11Texture::getShaderResourceViewDesc() const + { + return mSRVDesc; + } + //--------------------------------------------------------------------- + void D3D11Texture::prepareImpl( void ) + { + if (mUsage & TU_RENDERTARGET || isManuallyLoaded()) + { + return; + } + + //D3D11_DEVICE_ACCESS_CRITICAL_SECTION + LoadedStreams loadedStreams; - // prepare load based on tex.type - switch (getTextureType()) - { - case TEX_TYPE_1D: - case TEX_TYPE_2D: - case TEX_TYPE_2D_ARRAY: - loadedStreams = _prepareNormTex(); - break; - case TEX_TYPE_3D: - loadedStreams = _prepareVolumeTex(); - break; - case TEX_TYPE_CUBE_MAP: - loadedStreams = _prepareCubeTex(); - break; - default: - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D11Texture::prepareImpl" ); - } - - mLoadedStreams = loadedStreams; - } - //--------------------------------------------------------------------- - D3D11Texture::LoadedStreams D3D11Texture::_prepareCubeTex() - { - assert(getTextureType() == TEX_TYPE_CUBE_MAP); + // prepare load based on tex.type + switch (getTextureType()) + { + case TEX_TYPE_1D: + case TEX_TYPE_2D: + case TEX_TYPE_2D_ARRAY: + loadedStreams = _prepareNormTex(); + break; + case TEX_TYPE_3D: + loadedStreams = _prepareVolumeTex(); + break; + case TEX_TYPE_CUBE_MAP: + loadedStreams = _prepareCubeTex(); + break; + default: + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D11Texture::prepareImpl" ); + } + + mLoadedStreams = loadedStreams; + } + //--------------------------------------------------------------------- + D3D11Texture::LoadedStreams D3D11Texture::_prepareCubeTex() + { + assert(getTextureType() == TEX_TYPE_CUBE_MAP); LoadedStreams loadedStreams = LoadedStreams(OGRE_NEW_T (vector::type, MEMCATEGORY_GENERAL), SPFM_DELETE_T ); // DDS load? - if (getSourceFileType() == "dds") - { + if (getSourceFileType() == "dds") + { // find & load resource data - DataStreamPtr dstream = - ResourceGroupManager::getSingleton().openResource( - mName, mGroup, true, this); + DataStreamPtr dstream = + ResourceGroupManager::getSingleton().openResource( + mName, mGroup, true, this); loadedStreams->push_back(MemoryDataStreamPtr(OGRE_NEW MemoryDataStream(dstream))); } else { - // Load from 6 separate files - // Use OGRE its own codecs - String baseName, ext; - size_t pos = mName.find_last_of("."); - baseName = mName.substr(0, pos); - if ( pos != String::npos ) - ext = mName.substr(pos+1); - static const String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"}; - - for(size_t i = 0; i < 6; i++) - { - String fullName = baseName + suffixes[i]; - if (!ext.empty()) - fullName = fullName + "." + ext; - - // find & load resource data intro stream to allow resource - // group changes if required - DataStreamPtr dstream = - ResourceGroupManager::getSingleton().openResource( - fullName, mGroup, true, this); + // Load from 6 separate files + // Use OGRE its own codecs + String baseName, ext; + size_t pos = mName.find_last_of("."); + baseName = mName.substr(0, pos); + if ( pos != String::npos ) + ext = mName.substr(pos+1); + static const String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"}; + + for(size_t i = 0; i < 6; i++) + { + String fullName = baseName + suffixes[i]; + if (!ext.empty()) + fullName = fullName + "." + ext; + + // find & load resource data intro stream to allow resource + // group changes if required + DataStreamPtr dstream = + ResourceGroupManager::getSingleton().openResource( + fullName, mGroup, true, this); loadedStreams->push_back(MemoryDataStreamPtr(OGRE_NEW MemoryDataStream(dstream))); - } + } } return loadedStreams; - } - //--------------------------------------------------------------------- - D3D11Texture::LoadedStreams D3D11Texture::_prepareVolumeTex() - { - assert(getTextureType() == TEX_TYPE_3D); + } + //--------------------------------------------------------------------- + D3D11Texture::LoadedStreams D3D11Texture::_prepareVolumeTex() + { + assert(getTextureType() == TEX_TYPE_3D); - // find & load resource data - DataStreamPtr dstream = - ResourceGroupManager::getSingleton().openResource( - mName, mGroup, true, this); + // find & load resource data + DataStreamPtr dstream = + ResourceGroupManager::getSingleton().openResource( + mName, mGroup, true, this); LoadedStreams loadedStreams = LoadedStreams(OGRE_NEW_T (vector::type, MEMCATEGORY_GENERAL), SPFM_DELETE_T); loadedStreams->push_back(MemoryDataStreamPtr(OGRE_NEW MemoryDataStream(dstream))); return loadedStreams; } - //--------------------------------------------------------------------- - D3D11Texture::LoadedStreams D3D11Texture::_prepareNormTex() - { - assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D || getTextureType() == TEX_TYPE_2D_ARRAY); + //--------------------------------------------------------------------- + D3D11Texture::LoadedStreams D3D11Texture::_prepareNormTex() + { + assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D || getTextureType() == TEX_TYPE_2D_ARRAY); - // find & load resource data - DataStreamPtr dstream = - ResourceGroupManager::getSingleton().openResource( - mName, mGroup, true, this); + // find & load resource data + DataStreamPtr dstream = + ResourceGroupManager::getSingleton().openResource( + mName, mGroup, true, this); LoadedStreams loadedStreams = LoadedStreams(OGRE_NEW_T (vector::type, MEMCATEGORY_GENERAL), SPFM_DELETE_T); loadedStreams->push_back(MemoryDataStreamPtr(OGRE_NEW MemoryDataStream(dstream))); return loadedStreams; - } - //--------------------------------------------------------------------- - void D3D11Texture::unprepareImpl( void ) - { - if (mUsage & TU_RENDERTARGET || isManuallyLoaded()) - { - return; - } - } - //--------------------------------------------------------------------- - void D3D11Texture::postLoadImpl() - { - //D3D11_DEVICE_ACCESS_CRITICAL_SECTION - mLoadedStreams.setNull(); - } - //--------------------------------------------------------------------- - // D3D11RenderTexture - //--------------------------------------------------------------------- - void D3D11RenderTexture::rebind( D3D11HardwarePixelBuffer *buffer ) - { - mBuffer = buffer; - mWidth = (unsigned int) mBuffer->getWidth(); - mHeight = (unsigned int) mBuffer->getHeight(); - mColourDepth = (unsigned int) PixelUtil::getNumElemBits(mBuffer->getFormat()); - - ID3D11Resource * pBackBuffer = buffer->getParentTexture()->getTextureResource(); - - D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; - ZeroMemory( &RTVDesc, sizeof(RTVDesc) ); - - RTVDesc.Format = buffer->getParentTexture()->getShaderResourceViewDesc().Format; - switch(buffer->getParentTexture()->getShaderResourceViewDesc().ViewDimension) - { - case D3D11_SRV_DIMENSION_BUFFER: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER; - break; - case D3D11_SRV_DIMENSION_TEXTURE1D: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; - break; - case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; - break; - case D3D11_SRV_DIMENSION_TEXTURECUBE: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - RTVDesc.Texture2DArray.FirstArraySlice = buffer->getFace(); - RTVDesc.Texture2DArray.ArraySize = 1; - RTVDesc.Texture2DArray.MipSlice = 0; - break; - case D3D11_SRV_DIMENSION_TEXTURE2D: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - break; - case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - break; - case D3D11_SRV_DIMENSION_TEXTURE2DMS: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; - break; - case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; - break; - case D3D11_SRV_DIMENSION_TEXTURE3D: - RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - break; - default: - assert(false); - } - HRESULT hr = mDevice->CreateRenderTargetView( pBackBuffer, &RTVDesc, &mRenderTargetView ); - - if (FAILED(hr) || mDevice.isError()) - { - String errorDescription = mDevice.getErrorDescription(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating Render Target View\nError Description:" + errorDescription, - "D3D11RenderTexture::rebind" ); - } - } - //--------------------------------------------------------------------- - void D3D11RenderTexture::getCustomAttribute( const String& name, void *pData ) - { - if(name == "DDBACKBUFFER") - { - //IDXGISurface ** pSurf = (IDXGISurface **)pData; - //*pSurf = static_cast(mBuffer)->getSurface(); - *static_cast(pData) = mBuffer; - return; - } - else if(name == "HWND") - { - HWND *pHwnd = (HWND*)pData; - *pHwnd = NULL; - return; - } - else if(name == "isTexture") - { - bool *b = reinterpret_cast< bool * >( pData ); - *b = true; - return; - } - else if(name == "BUFFER") - { - *static_cast(pData) = mBuffer; - return; - } - else if( name == "ID3D11Texture2D" ) - { - ID3D11Texture2D **pBackBuffer = (ID3D11Texture2D**)pData; - *pBackBuffer = static_cast(mBuffer)->getParentTexture()->GetTex2D(); - return; - } - else if(name == "ID3D11RenderTargetView") - { - *static_cast(pData) = mRenderTargetView; - //*static_cast(pData) = &mRenderTargetView; - return; - } - else if( name == "numberOfViews" ) - { - unsigned int* n = reinterpret_cast(pData); - *n = 1; - return; - } - - RenderTexture::getCustomAttribute(name, pData); - } - //--------------------------------------------------------------------- - D3D11RenderTexture::D3D11RenderTexture( const String &name, D3D11HardwarePixelBuffer *buffer, D3D11Device & device ) : mDevice(device), - RenderTexture(buffer, 0) - { - mName = name; - - rebind(buffer); - } - - //--------------------------------------------------------------------- - - D3D11RenderTexture::~D3D11RenderTexture() - { - - } + } + //--------------------------------------------------------------------- + void D3D11Texture::unprepareImpl( void ) + { + if (mUsage & TU_RENDERTARGET || isManuallyLoaded()) + { + return; + } + } + //--------------------------------------------------------------------- + void D3D11Texture::postLoadImpl() + { + //D3D11_DEVICE_ACCESS_CRITICAL_SECTION + mLoadedStreams.setNull(); + } + //--------------------------------------------------------------------- + // D3D11RenderTexture + //--------------------------------------------------------------------- + void D3D11RenderTexture::rebind( D3D11HardwarePixelBuffer *buffer ) + { + mBuffer = buffer; + mWidth = (unsigned int) mBuffer->getWidth(); + mHeight = (unsigned int) mBuffer->getHeight(); + mColourDepth = (unsigned int) PixelUtil::getNumElemBits(mBuffer->getFormat()); + + ID3D11Resource * pBackBuffer = buffer->getParentTexture()->getTextureResource(); + + D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; + ZeroMemory( &RTVDesc, sizeof(RTVDesc) ); + + RTVDesc.Format = buffer->getParentTexture()->getShaderResourceViewDesc().Format; + switch(buffer->getParentTexture()->getShaderResourceViewDesc().ViewDimension) + { + case D3D11_SRV_DIMENSION_BUFFER: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER; + break; + case D3D11_SRV_DIMENSION_TEXTURE1D: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; + break; + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY; + break; + case D3D11_SRV_DIMENSION_TEXTURECUBE: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + RTVDesc.Texture2DArray.FirstArraySlice = buffer->getFace(); + RTVDesc.Texture2DArray.ArraySize = 1; + RTVDesc.Texture2DArray.MipSlice = 0; + break; + case D3D11_SRV_DIMENSION_TEXTURE2D: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DMS: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + break; + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; + break; + case D3D11_SRV_DIMENSION_TEXTURE3D: + RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + break; + default: + assert(false); + } + HRESULT hr = mDevice->CreateRenderTargetView( pBackBuffer, &RTVDesc, &mRenderTargetView ); + + if (FAILED(hr) || mDevice.isError()) + { + String errorDescription = mDevice.getErrorDescription(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating Render Target View\nError Description:" + errorDescription, + "D3D11RenderTexture::rebind" ); + } + } + //--------------------------------------------------------------------- + void D3D11RenderTexture::getCustomAttribute( const String& name, void *pData ) + { + if(name == "DDBACKBUFFER") + { + //IDXGISurface ** pSurf = (IDXGISurface **)pData; + //*pSurf = static_cast(mBuffer)->getSurface(); + *static_cast(pData) = mBuffer; + return; + } + else if(name == "HWND") + { + HWND *pHwnd = (HWND*)pData; + *pHwnd = NULL; + return; + } + else if(name == "isTexture") + { + bool *b = reinterpret_cast< bool * >( pData ); + *b = true; + return; + } + else if(name == "BUFFER") + { + *static_cast(pData) = mBuffer; + return; + } + else if( name == "ID3D11Texture2D" ) + { + ID3D11Texture2D **pBackBuffer = (ID3D11Texture2D**)pData; + *pBackBuffer = static_cast(mBuffer)->getParentTexture()->GetTex2D(); + return; + } + else if(name == "ID3D11RenderTargetView") + { + *static_cast(pData) = mRenderTargetView; + //*static_cast(pData) = &mRenderTargetView; + return; + } + else if( name == "numberOfViews" ) + { + unsigned int* n = reinterpret_cast(pData); + *n = 1; + return; + } + + RenderTexture::getCustomAttribute(name, pData); + } + //--------------------------------------------------------------------- + D3D11RenderTexture::D3D11RenderTexture( const String &name, D3D11HardwarePixelBuffer *buffer, D3D11Device & device ) : mDevice(device), + RenderTexture(buffer, 0) + { + mName = name; + + rebind(buffer); + } + + //--------------------------------------------------------------------- + + D3D11RenderTexture::~D3D11RenderTexture() + { + + } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11TextureManager.cpp b/RenderSystems/Direct3D11/src/OgreD3D11TextureManager.cpp index 9aa33879a5d..4f13a5aec8a 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11TextureManager.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11TextureManager.cpp @@ -34,81 +34,81 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - D3D11TextureManager::D3D11TextureManager( D3D11Device & device ) : TextureManager(), mDevice (device) - { - if( mDevice.isNull()) - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Invalid Direct3DDevice passed", "D3D11TextureManager::D3D11TextureManager" ); - // register with group manager - ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); - } - //--------------------------------------------------------------------- - D3D11TextureManager::~D3D11TextureManager() - { - // unregister with group manager - ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); + //--------------------------------------------------------------------- + D3D11TextureManager::D3D11TextureManager( D3D11Device & device ) : TextureManager(), mDevice (device) + { + if( mDevice.isNull()) + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Invalid Direct3DDevice passed", "D3D11TextureManager::D3D11TextureManager" ); + // register with group manager + ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); + } + //--------------------------------------------------------------------- + D3D11TextureManager::~D3D11TextureManager() + { + // unregister with group manager + ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); - } - //--------------------------------------------------------------------- - Resource* D3D11TextureManager::createImpl(const String& name, - ResourceHandle handle, const String& group, bool isManual, - ManualResourceLoader* loader, const NameValuePairList* createParams) - { - return new D3D11Texture(this, name, handle, group, isManual, loader, mDevice); - } - //--------------------------------------------------------------------- - void D3D11TextureManager::releaseDefaultPoolResources(void) - { - size_t count = 0; + } + //--------------------------------------------------------------------- + Resource* D3D11TextureManager::createImpl(const String& name, + ResourceHandle handle, const String& group, bool isManual, + ManualResourceLoader* loader, const NameValuePairList* createParams) + { + return new D3D11Texture(this, name, handle, group, isManual, loader, mDevice); + } + //--------------------------------------------------------------------- + void D3D11TextureManager::releaseDefaultPoolResources(void) + { + size_t count = 0; - ResourceMap::iterator r, rend; - rend = mResources.end(); - for (r = mResources.begin(); r != rend; ++r) - { - D3D11TexturePtr t = r->second.staticCast(); - if (t->releaseIfDefaultPool()) - count++; - } - LogManager::getSingleton().logMessage("D3D11TextureManager released:"); - LogManager::getSingleton().logMessage( - StringConverter::toString(count) + " unmanaged textures"); - } - //--------------------------------------------------------------------- - void D3D11TextureManager::recreateDefaultPoolResources(void) - { - size_t count = 0; + ResourceMap::iterator r, rend; + rend = mResources.end(); + for (r = mResources.begin(); r != rend; ++r) + { + D3D11TexturePtr t = r->second.staticCast(); + if (t->releaseIfDefaultPool()) + count++; + } + LogManager::getSingleton().logMessage("D3D11TextureManager released:"); + LogManager::getSingleton().logMessage( + StringConverter::toString(count) + " unmanaged textures"); + } + //--------------------------------------------------------------------- + void D3D11TextureManager::recreateDefaultPoolResources(void) + { + size_t count = 0; - ResourceMap::iterator r, rend; - rend = mResources.end(); - for (r = mResources.begin(); r != rend; ++r) - { - D3D11TexturePtr t = r->second.staticCast(); - if(t->recreateIfDefaultPool(mDevice)) - count++; - } - LogManager::getSingleton().logMessage("D3D11TextureManager recreated:"); - LogManager::getSingleton().logMessage( - StringConverter::toString(count) + " unmanaged textures"); - } - //--------------------------------------------------------------------- - PixelFormat D3D11TextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage) - { - // Basic filtering - DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(format)); + ResourceMap::iterator r, rend; + rend = mResources.end(); + for (r = mResources.begin(); r != rend; ++r) + { + D3D11TexturePtr t = r->second.staticCast(); + if(t->recreateIfDefaultPool(mDevice)) + count++; + } + LogManager::getSingleton().logMessage("D3D11TextureManager recreated:"); + LogManager::getSingleton().logMessage( + StringConverter::toString(count) + " unmanaged textures"); + } + //--------------------------------------------------------------------- + PixelFormat D3D11TextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage) + { + // Basic filtering + DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(format)); - return D3D11Mappings::_getPF(d3dPF); - } - //--------------------------------------------------------------------- - bool D3D11TextureManager::isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage, - bool preciseFormatOnly) - { - if (!preciseFormatOnly) - format = getNativeFormat(ttype, format, usage); + return D3D11Mappings::_getPF(d3dPF); + } + //--------------------------------------------------------------------- + bool D3D11TextureManager::isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage, + bool preciseFormatOnly) + { + if (!preciseFormatOnly) + format = getNativeFormat(ttype, format, usage); - D3D11RenderSystem* rs = static_cast( - Root::getSingleton().getRenderSystem()); + D3D11RenderSystem* rs = static_cast( + Root::getSingleton().getRenderSystem()); - return rs->_checkTextureFilteringSupported(ttype, format, usage); - } - //--------------------------------------------------------------------- + return rs->_checkTextureFilteringSupported(ttype, format, usage); + } + //--------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11VertexDeclaration.cpp b/RenderSystems/Direct3D11/src/OgreD3D11VertexDeclaration.cpp index 3f457d53cf4..d8e213307bd 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11VertexDeclaration.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11VertexDeclaration.cpp @@ -33,25 +33,25 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - D3D11VertexDeclaration::D3D11VertexDeclaration(D3D11Device & device) - : - mlpD3DDevice(device) - , mNeedsRebuild(true) - { - - } - //----------------------------------------------------------------------- - D3D11VertexDeclaration::~D3D11VertexDeclaration() - { + //----------------------------------------------------------------------- + D3D11VertexDeclaration::D3D11VertexDeclaration(D3D11Device & device) + : + mlpD3DDevice(device) + , mNeedsRebuild(true) + { + + } + //----------------------------------------------------------------------- + D3D11VertexDeclaration::~D3D11VertexDeclaration() + { { - ShaderToILayoutMapIterator iter = mShaderToILayoutMap.begin(); - ShaderToILayoutMapIterator iterE = mShaderToILayoutMap.end(); + ShaderToILayoutMapIterator iter = mShaderToILayoutMap.begin(); + ShaderToILayoutMapIterator iterE = mShaderToILayoutMap.end(); - for ( ; iter != iterE ; iter++) - { - iter->second->Release(); - } + for ( ; iter != iterE ; iter++) + { + iter->second->Release(); + } } { @@ -65,71 +65,71 @@ namespace Ogre { } - } - //----------------------------------------------------------------------- - const VertexElement& D3D11VertexDeclaration::addElement(unsigned short source, - size_t offset, VertexElementType theType, - VertexElementSemantic semantic, unsigned short index) - { - mNeedsRebuild = true; - return VertexDeclaration::addElement(source, offset, theType, semantic, index); - } - //----------------------------------------------------------------------------- - const VertexElement& D3D11VertexDeclaration::insertElement(unsigned short atPosition, - unsigned short source, size_t offset, VertexElementType theType, - VertexElementSemantic semantic, unsigned short index) - { - mNeedsRebuild = true; - return VertexDeclaration::insertElement(atPosition, source, offset, theType, semantic, index); - } - //----------------------------------------------------------------------- - void D3D11VertexDeclaration::removeElement(unsigned short elem_index) - { - VertexDeclaration::removeElement(elem_index); - mNeedsRebuild = true; - } - //----------------------------------------------------------------------- - void D3D11VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index) - { - VertexDeclaration::removeElement(semantic, index); - mNeedsRebuild = true; - } - //----------------------------------------------------------------------- - void D3D11VertexDeclaration::removeAllElements(void) - { - VertexDeclaration::removeAllElements(); - mNeedsRebuild = true; - } - //----------------------------------------------------------------------- - void D3D11VertexDeclaration::modifyElement(unsigned short elem_index, - unsigned short source, size_t offset, VertexElementType theType, - VertexElementSemantic semantic, unsigned short index) - { - VertexDeclaration::modifyElement(elem_index, source, offset, theType, semantic, index); - mNeedsRebuild = true; - } - //----------------------------------------------------------------------- - D3D11_INPUT_ELEMENT_DESC * D3D11VertexDeclaration::getD3DVertexDeclaration(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding) - { - // Create D3D elements - size_t iNumElements = boundVertexProgram->getNumInputs(); - - if (mD3delems.find(boundVertexProgram) == mD3delems.end()) - { - D3D11_INPUT_ELEMENT_DESC* D3delems = new D3D11_INPUT_ELEMENT_DESC[iNumElements]; + } + //----------------------------------------------------------------------- + const VertexElement& D3D11VertexDeclaration::addElement(unsigned short source, + size_t offset, VertexElementType theType, + VertexElementSemantic semantic, unsigned short index) + { + mNeedsRebuild = true; + return VertexDeclaration::addElement(source, offset, theType, semantic, index); + } + //----------------------------------------------------------------------------- + const VertexElement& D3D11VertexDeclaration::insertElement(unsigned short atPosition, + unsigned short source, size_t offset, VertexElementType theType, + VertexElementSemantic semantic, unsigned short index) + { + mNeedsRebuild = true; + return VertexDeclaration::insertElement(atPosition, source, offset, theType, semantic, index); + } + //----------------------------------------------------------------------- + void D3D11VertexDeclaration::removeElement(unsigned short elem_index) + { + VertexDeclaration::removeElement(elem_index); + mNeedsRebuild = true; + } + //----------------------------------------------------------------------- + void D3D11VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index) + { + VertexDeclaration::removeElement(semantic, index); + mNeedsRebuild = true; + } + //----------------------------------------------------------------------- + void D3D11VertexDeclaration::removeAllElements(void) + { + VertexDeclaration::removeAllElements(); + mNeedsRebuild = true; + } + //----------------------------------------------------------------------- + void D3D11VertexDeclaration::modifyElement(unsigned short elem_index, + unsigned short source, size_t offset, VertexElementType theType, + VertexElementSemantic semantic, unsigned short index) + { + VertexDeclaration::modifyElement(elem_index, source, offset, theType, semantic, index); + mNeedsRebuild = true; + } + //----------------------------------------------------------------------- + D3D11_INPUT_ELEMENT_DESC * D3D11VertexDeclaration::getD3DVertexDeclaration(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding) + { + // Create D3D elements + size_t iNumElements = boundVertexProgram->getNumInputs(); + + if (mD3delems.find(boundVertexProgram) == mD3delems.end()) + { + D3D11_INPUT_ELEMENT_DESC* D3delems = new D3D11_INPUT_ELEMENT_DESC[iNumElements]; ZeroMemory(D3delems, sizeof(D3D11_INPUT_ELEMENT_DESC) * iNumElements); - unsigned int idx; - for (idx = 0; idx < iNumElements; ++idx) - { + unsigned int idx; + for (idx = 0; idx < iNumElements; ++idx) + { D3D11_SIGNATURE_PARAMETER_DESC inputDesc = boundVertexProgram->getInputParamDesc(idx); - VertexElementList::const_iterator i, iend; - iend = mElementList.end(); + VertexElementList::const_iterator i, iend; + iend = mElementList.end(); bool found = false; - for (i = mElementList.begin(); i != iend; ++i) + for (i = mElementList.begin(); i != iend; ++i) { - LPCSTR semanticName = D3D11Mappings::get(i->getSemantic()); - UINT semanticIndex = i->getIndex(); + LPCSTR semanticName = D3D11Mappings::get(i->getSemantic()); + UINT semanticIndex = i->getIndex(); if( strcmp(semanticName, inputDesc.SemanticName) == 0 && semanticIndex == inputDesc.SemanticIndex @@ -156,96 +156,96 @@ namespace Ogre { if(!found) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D11 vertex declaration" , - "D3D11VertexDeclaration::getILayoutByShader"); + "D3D11VertexDeclaration::getILayoutByShader"); + } + + D3delems[idx].SemanticName = inputDesc.SemanticName; + D3delems[idx].SemanticIndex = inputDesc.SemanticIndex; + D3delems[idx].Format = D3D11Mappings::get(i->getType()); + D3delems[idx].InputSlot = i->getSource(); + D3delems[idx].AlignedByteOffset = static_cast(i->getOffset()); + D3delems[idx].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + D3delems[idx].InstanceDataStepRate = 0; + + VertexBufferBinding::VertexBufferBindingMap::const_iterator foundIter; + foundIter = binding->getBindings().find(i->getSource()); + if ( foundIter != binding->getBindings().end() ) + { + HardwareVertexBufferSharedPtr bufAtSlot = foundIter->second; + if ( bufAtSlot->getIsInstanceData() ) + { + D3delems[idx].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; + D3delems[idx].InstanceDataStepRate = bufAtSlot->getInstanceDataStepRate(); + } } + else + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to found a bound vertex for a slot that is used in the vertex declaration." , + "D3D11VertexDeclaration::getD3DVertexDeclaration"); - D3delems[idx].SemanticName = inputDesc.SemanticName; - D3delems[idx].SemanticIndex = inputDesc.SemanticIndex; - D3delems[idx].Format = D3D11Mappings::get(i->getType()); - D3delems[idx].InputSlot = i->getSource(); - D3delems[idx].AlignedByteOffset = static_cast(i->getOffset()); - D3delems[idx].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - D3delems[idx].InstanceDataStepRate = 0; - - VertexBufferBinding::VertexBufferBindingMap::const_iterator foundIter; - foundIter = binding->getBindings().find(i->getSource()); - if ( foundIter != binding->getBindings().end() ) - { - HardwareVertexBufferSharedPtr bufAtSlot = foundIter->second; - if ( bufAtSlot->getIsInstanceData() ) - { - D3delems[idx].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; - D3delems[idx].InstanceDataStepRate = bufAtSlot->getInstanceDataStepRate(); - } - } - else - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to found a bound vertex for a slot that is used in the vertex declaration." , - "D3D11VertexDeclaration::getD3DVertexDeclaration"); - - } - } - - mD3delems[boundVertexProgram] = D3delems; - - } - - return mD3delems[boundVertexProgram]; - } - //----------------------------------------------------------------------- - ID3D11InputLayout* D3D11VertexDeclaration::getILayoutByShader(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding) - { - ShaderToILayoutMapIterator foundIter = mShaderToILayoutMap.find(boundVertexProgram); - - ID3D11InputLayout* pVertexLayout = 0; - - if (foundIter == mShaderToILayoutMap.end()) - { - // if not found - create - - DWORD dwShaderFlags = 0; - const MicroCode & vSBuf = boundVertexProgram->getMicroCode(); - - D3D11_INPUT_ELEMENT_DESC * pVertexDecl=getD3DVertexDeclaration(boundVertexProgram, binding); - - // bad bug tracing. see what will happen next. - //if (pVertexDecl->Format == DXGI_FORMAT_R16G16_SINT) - // pVertexDecl->Format = DXGI_FORMAT_R16G16_FLOAT; - HRESULT hr = mlpD3DDevice->CreateInputLayout( - pVertexDecl, - boundVertexProgram->getNumInputs(), - &vSBuf[0], - vSBuf.size(), - &pVertexLayout ); - - if (FAILED(hr)|| mlpD3DDevice.isError()) - { - String errorDescription = mlpD3DDevice.getErrorDescription(); + } + } + + mD3delems[boundVertexProgram] = D3delems; + + } + + return mD3delems[boundVertexProgram]; + } + //----------------------------------------------------------------------- + ID3D11InputLayout* D3D11VertexDeclaration::getILayoutByShader(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding) + { + ShaderToILayoutMapIterator foundIter = mShaderToILayoutMap.find(boundVertexProgram); + + ID3D11InputLayout* pVertexLayout = 0; + + if (foundIter == mShaderToILayoutMap.end()) + { + // if not found - create + + DWORD dwShaderFlags = 0; + const MicroCode & vSBuf = boundVertexProgram->getMicroCode(); + + D3D11_INPUT_ELEMENT_DESC * pVertexDecl=getD3DVertexDeclaration(boundVertexProgram, binding); + + // bad bug tracing. see what will happen next. + //if (pVertexDecl->Format == DXGI_FORMAT_R16G16_SINT) + // pVertexDecl->Format = DXGI_FORMAT_R16G16_FLOAT; + HRESULT hr = mlpD3DDevice->CreateInputLayout( + pVertexDecl, + boundVertexProgram->getNumInputs(), + &vSBuf[0], + vSBuf.size(), + &pVertexLayout ); + + if (FAILED(hr)|| mlpD3DDevice.isError()) + { + String errorDescription = mlpD3DDevice.getErrorDescription(); errorDescription += "\nBound shader name: " + boundVertexProgram->getName(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D11 vertex declaration"+errorDescription , - "D3D11VertexDeclaration::getILayoutByShader"); - } + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D11 vertex declaration"+errorDescription , + "D3D11VertexDeclaration::getILayoutByShader"); + } - mShaderToILayoutMap[boundVertexProgram] = pVertexLayout; + mShaderToILayoutMap[boundVertexProgram] = pVertexLayout; - } - else - { - pVertexLayout = foundIter->second; - } + } + else + { + pVertexLayout = foundIter->second; + } - return pVertexLayout; - } - //----------------------------------------------------------------------- - void D3D11VertexDeclaration::bindToShader(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding) - { - ID3D11InputLayout* pVertexLayout = getILayoutByShader(boundVertexProgram, binding); + return pVertexLayout; + } + //----------------------------------------------------------------------- + void D3D11VertexDeclaration::bindToShader(D3D11HLSLProgram* boundVertexProgram, VertexBufferBinding* binding) + { + ID3D11InputLayout* pVertexLayout = getILayoutByShader(boundVertexProgram, binding); - // Set the input layout - mlpD3DDevice.GetImmediateContext()->IASetInputLayout( pVertexLayout); - } + // Set the input layout + mlpD3DDevice.GetImmediateContext()->IASetInputLayout( pVertexLayout); + } } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11VideoMode.cpp b/RenderSystems/Direct3D11/src/OgreD3D11VideoMode.cpp index 49aab911e90..86c6c242038 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11VideoMode.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11VideoMode.cpp @@ -29,97 +29,97 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - String D3D11VideoMode::getDescription() const - { - char tmp[128]; - unsigned int colourDepth = 16; - if( mModeDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM || - mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_TYPELESS || - mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT || - mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_UINT || - mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_SINT || - mModeDesc.Format == DXGI_FORMAT_R32G32B32_TYPELESS || - mModeDesc.Format == DXGI_FORMAT_R32G32B32_FLOAT || - mModeDesc.Format == DXGI_FORMAT_R32G32B32_UINT || - mModeDesc.Format == DXGI_FORMAT_R32G32B32_SINT - ) - colourDepth = 32; + //--------------------------------------------------------------------- + String D3D11VideoMode::getDescription() const + { + char tmp[128]; + unsigned int colourDepth = 16; + if( mModeDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM || + mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_TYPELESS || + mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT || + mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_UINT || + mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_SINT || + mModeDesc.Format == DXGI_FORMAT_R32G32B32_TYPELESS || + mModeDesc.Format == DXGI_FORMAT_R32G32B32_FLOAT || + mModeDesc.Format == DXGI_FORMAT_R32G32B32_UINT || + mModeDesc.Format == DXGI_FORMAT_R32G32B32_SINT + ) + colourDepth = 32; - sprintf( tmp, "%d x %d @ %d-bit colour", mModeDesc.Width, mModeDesc.Height, colourDepth ); - return String(tmp); - } - //--------------------------------------------------------------------- - unsigned int D3D11VideoMode::getColourDepth() const - { - unsigned int colourDepth = 16; - if( mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_TYPELESS || - mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT || - mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_UINT || - mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_SINT || - mModeDesc.Format == DXGI_FORMAT_R32G32B32_TYPELESS || - mModeDesc.Format == DXGI_FORMAT_R32G32B32_FLOAT || - mModeDesc.Format == DXGI_FORMAT_R32G32B32_UINT || - mModeDesc.Format == DXGI_FORMAT_R32G32B32_SINT - ) - colourDepth = 32; + sprintf( tmp, "%d x %d @ %d-bit colour", mModeDesc.Width, mModeDesc.Height, colourDepth ); + return String(tmp); + } + //--------------------------------------------------------------------- + unsigned int D3D11VideoMode::getColourDepth() const + { + unsigned int colourDepth = 16; + if( mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_TYPELESS || + mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT || + mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_UINT || + mModeDesc.Format == DXGI_FORMAT_R32G32B32A32_SINT || + mModeDesc.Format == DXGI_FORMAT_R32G32B32_TYPELESS || + mModeDesc.Format == DXGI_FORMAT_R32G32B32_FLOAT || + mModeDesc.Format == DXGI_FORMAT_R32G32B32_UINT || + mModeDesc.Format == DXGI_FORMAT_R32G32B32_SINT + ) + colourDepth = 32; - return colourDepth; - } - //--------------------------------------------------------------------- - unsigned int D3D11VideoMode::getWidth() const - { - return mModeDesc.Width; - } - //--------------------------------------------------------------------- - unsigned int D3D11VideoMode::getHeight() const - { - return mModeDesc.Height; - } - //--------------------------------------------------------------------- - DXGI_FORMAT D3D11VideoMode::getFormat() const - { - return mModeDesc.Format; - } - //--------------------------------------------------------------------- - DXGI_RATIONAL D3D11VideoMode::getRefreshRate() const - { - return mModeDesc.RefreshRate; - } - //--------------------------------------------------------------------- - DXGI_OUTPUT_DESC D3D11VideoMode::getDisplayMode() const - { - return mDisplayMode; - } - //--------------------------------------------------------------------- - DXGI_MODE_DESC D3D11VideoMode::getModeDesc() const - { - return mModeDesc; - } - //--------------------------------------------------------------------- - void D3D11VideoMode::increaseRefreshRate( DXGI_RATIONAL rr ) - { - mModeDesc.RefreshRate = rr; - } - //--------------------------------------------------------------------- - D3D11VideoMode::D3D11VideoMode( DXGI_OUTPUT_DESC d3ddm,DXGI_MODE_DESC ModeDesc ) - { - modeNumber = ++modeCount; mDisplayMode = d3ddm;mModeDesc=ModeDesc; - } - //--------------------------------------------------------------------- - D3D11VideoMode::D3D11VideoMode( const D3D11VideoMode &ob ) - { - modeNumber = ++modeCount; mDisplayMode = ob.mDisplayMode;mModeDesc=ob.mModeDesc; - } - //--------------------------------------------------------------------- - D3D11VideoMode::D3D11VideoMode() - { - modeNumber = ++modeCount; ZeroMemory( &mDisplayMode, sizeof(DXGI_OUTPUT_DESC) );ZeroMemory( &mModeDesc, sizeof(DXGI_MODE_DESC) ); - } - //--------------------------------------------------------------------- - D3D11VideoMode::~D3D11VideoMode() - { - modeCount--; - } - //--------------------------------------------------------------------- + return colourDepth; + } + //--------------------------------------------------------------------- + unsigned int D3D11VideoMode::getWidth() const + { + return mModeDesc.Width; + } + //--------------------------------------------------------------------- + unsigned int D3D11VideoMode::getHeight() const + { + return mModeDesc.Height; + } + //--------------------------------------------------------------------- + DXGI_FORMAT D3D11VideoMode::getFormat() const + { + return mModeDesc.Format; + } + //--------------------------------------------------------------------- + DXGI_RATIONAL D3D11VideoMode::getRefreshRate() const + { + return mModeDesc.RefreshRate; + } + //--------------------------------------------------------------------- + DXGI_OUTPUT_DESC D3D11VideoMode::getDisplayMode() const + { + return mDisplayMode; + } + //--------------------------------------------------------------------- + DXGI_MODE_DESC D3D11VideoMode::getModeDesc() const + { + return mModeDesc; + } + //--------------------------------------------------------------------- + void D3D11VideoMode::increaseRefreshRate( DXGI_RATIONAL rr ) + { + mModeDesc.RefreshRate = rr; + } + //--------------------------------------------------------------------- + D3D11VideoMode::D3D11VideoMode( DXGI_OUTPUT_DESC d3ddm,DXGI_MODE_DESC ModeDesc ) + { + modeNumber = ++modeCount; mDisplayMode = d3ddm;mModeDesc=ModeDesc; + } + //--------------------------------------------------------------------- + D3D11VideoMode::D3D11VideoMode( const D3D11VideoMode &ob ) + { + modeNumber = ++modeCount; mDisplayMode = ob.mDisplayMode;mModeDesc=ob.mModeDesc; + } + //--------------------------------------------------------------------- + D3D11VideoMode::D3D11VideoMode() + { + modeNumber = ++modeCount; ZeroMemory( &mDisplayMode, sizeof(DXGI_OUTPUT_DESC) );ZeroMemory( &mModeDesc, sizeof(DXGI_MODE_DESC) ); + } + //--------------------------------------------------------------------- + D3D11VideoMode::~D3D11VideoMode() + { + modeCount--; + } + //--------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D11/src/OgreD3D11VideoModeList.cpp b/RenderSystems/Direct3D11/src/OgreD3D11VideoModeList.cpp index 92b3cf717af..1fe409de9da 100644 --- a/RenderSystems/Direct3D11/src/OgreD3D11VideoModeList.cpp +++ b/RenderSystems/Direct3D11/src/OgreD3D11VideoModeList.cpp @@ -32,46 +32,46 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - D3D11VideoModeList::D3D11VideoModeList( D3D11Driver* pDriver ) - { - if( NULL == pDriver ) - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "pDriver parameter is NULL", "D3D11VideoModeList::D3D11VideoModeList" ); - - mDriver = pDriver; - enumerate(); - } - //--------------------------------------------------------------------- - D3D11VideoModeList::~D3D11VideoModeList() - { - mDriver = NULL; - mModeList.clear(); - } - //--------------------------------------------------------------------- - BOOL D3D11VideoModeList::enumerate() - { - // int pD3D = mDriver->getD3D(); - UINT adapter = mDriver->getAdapterNumber(); - HRESULT hr; - IDXGIOutput *pOutput; - for( int iOutput = 0; ; ++iOutput ) - { - //AIZTODO: one output for a single monitor ,to be handled for mulimon - hr = mDriver->getDeviceAdapter()->EnumOutputs( iOutput, &pOutput ); - if( DXGI_ERROR_NOT_FOUND == hr ) - { - return false; - } - else if (FAILED(hr)) - { - return false; //Something bad happened. - } - else //Success! - { - DXGI_OUTPUT_DESC OutputDesc; - pOutput->GetDesc(&OutputDesc); - - UINT NumModes = 0; + //--------------------------------------------------------------------- + D3D11VideoModeList::D3D11VideoModeList( D3D11Driver* pDriver ) + { + if( NULL == pDriver ) + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "pDriver parameter is NULL", "D3D11VideoModeList::D3D11VideoModeList" ); + + mDriver = pDriver; + enumerate(); + } + //--------------------------------------------------------------------- + D3D11VideoModeList::~D3D11VideoModeList() + { + mDriver = NULL; + mModeList.clear(); + } + //--------------------------------------------------------------------- + BOOL D3D11VideoModeList::enumerate() + { + // int pD3D = mDriver->getD3D(); + UINT adapter = mDriver->getAdapterNumber(); + HRESULT hr; + IDXGIOutput *pOutput; + for( int iOutput = 0; ; ++iOutput ) + { + //AIZTODO: one output for a single monitor ,to be handled for mulimon + hr = mDriver->getDeviceAdapter()->EnumOutputs( iOutput, &pOutput ); + if( DXGI_ERROR_NOT_FOUND == hr ) + { + return false; + } + else if (FAILED(hr)) + { + return false; //Something bad happened. + } + else //Success! + { + DXGI_OUTPUT_DESC OutputDesc; + pOutput->GetDesc(&OutputDesc); + + UINT NumModes = 0; hr = pOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, 0, &NumModes, @@ -79,159 +79,159 @@ namespace Ogre DXGI_MODE_DESC *pDesc = new DXGI_MODE_DESC[ NumModes ]; ZeroMemory(pDesc, sizeof(DXGI_MODE_DESC) * NumModes); - hr = pOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, - 0, - &NumModes, - pDesc ); - - SAFE_RELEASE(pOutput); - - // display mode list can not be obtained when working over terminal session - if(FAILED(hr)) - { - NumModes = 0; - - if(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) - { - pDesc[0].Width = 800; - pDesc[0].Height = 600; - pDesc[0].RefreshRate.Numerator = 60; - pDesc[0].RefreshRate.Denominator = 1; - pDesc[0].Format = DXGI_FORMAT_R8G8B8A8_UNORM; - pDesc[0].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE; - pDesc[0].Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - - NumModes = 1; - } - } - - for( UINT m=0; m::type::iterator it; - for( it = mModeList.begin(); it != mModeList.end(); it++ ) - { - DXGI_OUTPUT_DESC oldOutput= it->getDisplayMode(); - DXGI_MODE_DESC oldDisp = it->getModeDesc(); - if(//oldOutput.Monitor==OutputDesc.Monitor && - oldDisp.Width == displayMode.Width && - oldDisp.Height == displayMode.Height// && - //oldDisp.Format == displayMode.Format - ) - { - // Check refresh rate and favour higher if poss - //if (oldDisp.RefreshRate < displayMode.RefreshRate) - // it->increaseRefreshRate(displayMode.RefreshRate); - found = TRUE; - break; - } - } - - if( !found ) - mModeList.push_back( D3D11VideoMode( OutputDesc,displayMode ) ); - - } + hr = pOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, + 0, + &NumModes, + pDesc ); + + SAFE_RELEASE(pOutput); + + // display mode list can not be obtained when working over terminal session + if(FAILED(hr)) + { + NumModes = 0; + + if(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) + { + pDesc[0].Width = 800; + pDesc[0].Height = 600; + pDesc[0].RefreshRate.Numerator = 60; + pDesc[0].RefreshRate.Denominator = 1; + pDesc[0].Format = DXGI_FORMAT_R8G8B8A8_UNORM; + pDesc[0].ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE; + pDesc[0].Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + + NumModes = 1; + } + } + + for( UINT m=0; m::type::iterator it; + for( it = mModeList.begin(); it != mModeList.end(); it++ ) + { + DXGI_OUTPUT_DESC oldOutput= it->getDisplayMode(); + DXGI_MODE_DESC oldDisp = it->getModeDesc(); + if(//oldOutput.Monitor==OutputDesc.Monitor && + oldDisp.Width == displayMode.Width && + oldDisp.Height == displayMode.Height// && + //oldDisp.Format == displayMode.Format + ) + { + // Check refresh rate and favour higher if poss + //if (oldDisp.RefreshRate < displayMode.RefreshRate) + // it->increaseRefreshRate(displayMode.RefreshRate); + found = TRUE; + break; + } + } + + if( !found ) + mModeList.push_back( D3D11VideoMode( OutputDesc,displayMode ) ); + + } delete [] pDesc; - } - } - /* - UINT iMode; - for( iMode=0; iMode < pD3D->GetAdapterModeCount( adapter, D3DFMT_R5G6B5 ); iMode++ ) - { - DXGI_OUTPUT_DESC displayMode; - pD3D->EnumAdapterModes( adapter, D3DFMT_R5G6B5, iMode, &displayMode ); - - // Filter out low-resolutions - if( displayMode.Width < 640 || displayMode.Height < 400 ) - continue; - - // Check to see if it is already in the list (to filter out refresh rates) - BOOL found = FALSE; - vector::type::iterator it; - for( it = mModeList.begin(); it != mModeList.end(); it++ ) - { - DXGI_OUTPUT_DESC oldDisp = it->getDisplayMode(); - if( oldDisp.Width == displayMode.Width && - oldDisp.Height == displayMode.Height && - oldDisp.Format == displayMode.Format ) - { - // Check refresh rate and favour higher if poss - if (oldDisp.RefreshRate < displayMode.RefreshRate) - it->increaseRefreshRate(displayMode.RefreshRate); - found = TRUE; - break; - } - } - - if( !found ) - mModeList.push_back( D3D11VideoMode( displayMode ) ); - } - - for( iMode=0; iMode < pD3D->GetAdapterModeCount( adapter, D3DFMT_X8R8G8B8 ); iMode++ ) - { - DXGI_OUTPUT_DESC displayMode; - pD3D->EnumAdapterModes( adapter, D3DFMT_X8R8G8B8, iMode, &displayMode ); - - // Filter out low-resolutions - if( displayMode.Width < 640 || displayMode.Height < 400 ) - continue; - - // Check to see if it is already in the list (to filter out refresh rates) - BOOL found = FALSE; - vector::type::iterator it; - for( it = mModeList.begin(); it != mModeList.end(); it++ ) - { - DXGI_OUTPUT_DESC oldDisp = it->getDisplayMode(); - if( oldDisp.Width == displayMode.Width && - oldDisp.Height == displayMode.Height && - oldDisp.Format == displayMode.Format ) - { - // Check refresh rate and favour higher if poss - if (oldDisp.RefreshRate < displayMode.RefreshRate) - it->increaseRefreshRate(displayMode.RefreshRate); - found = TRUE; - break; - } - } - - if( !found ) - mModeList.push_back( D3D11VideoMode( displayMode ) ); - } - */ - return TRUE; - } - //--------------------------------------------------------------------- - size_t D3D11VideoModeList::count() - { - return mModeList.size(); - } - //--------------------------------------------------------------------- - D3D11VideoMode* D3D11VideoModeList::item( size_t index ) - { - vector::type::iterator p = mModeList.begin(); - - return &p[index]; - } - //--------------------------------------------------------------------- - D3D11VideoMode* D3D11VideoModeList::item( const String &name ) - { - vector::type::iterator it = mModeList.begin(); - if (it == mModeList.end()) - return NULL; - - for (;it != mModeList.end(); ++it) - { - if (it->getDescription() == name) - return &(*it); - } - - return NULL; - } - //--------------------------------------------------------------------- + } + } + /* + UINT iMode; + for( iMode=0; iMode < pD3D->GetAdapterModeCount( adapter, D3DFMT_R5G6B5 ); iMode++ ) + { + DXGI_OUTPUT_DESC displayMode; + pD3D->EnumAdapterModes( adapter, D3DFMT_R5G6B5, iMode, &displayMode ); + + // Filter out low-resolutions + if( displayMode.Width < 640 || displayMode.Height < 400 ) + continue; + + // Check to see if it is already in the list (to filter out refresh rates) + BOOL found = FALSE; + vector::type::iterator it; + for( it = mModeList.begin(); it != mModeList.end(); it++ ) + { + DXGI_OUTPUT_DESC oldDisp = it->getDisplayMode(); + if( oldDisp.Width == displayMode.Width && + oldDisp.Height == displayMode.Height && + oldDisp.Format == displayMode.Format ) + { + // Check refresh rate and favour higher if poss + if (oldDisp.RefreshRate < displayMode.RefreshRate) + it->increaseRefreshRate(displayMode.RefreshRate); + found = TRUE; + break; + } + } + + if( !found ) + mModeList.push_back( D3D11VideoMode( displayMode ) ); + } + + for( iMode=0; iMode < pD3D->GetAdapterModeCount( adapter, D3DFMT_X8R8G8B8 ); iMode++ ) + { + DXGI_OUTPUT_DESC displayMode; + pD3D->EnumAdapterModes( adapter, D3DFMT_X8R8G8B8, iMode, &displayMode ); + + // Filter out low-resolutions + if( displayMode.Width < 640 || displayMode.Height < 400 ) + continue; + + // Check to see if it is already in the list (to filter out refresh rates) + BOOL found = FALSE; + vector::type::iterator it; + for( it = mModeList.begin(); it != mModeList.end(); it++ ) + { + DXGI_OUTPUT_DESC oldDisp = it->getDisplayMode(); + if( oldDisp.Width == displayMode.Width && + oldDisp.Height == displayMode.Height && + oldDisp.Format == displayMode.Format ) + { + // Check refresh rate and favour higher if poss + if (oldDisp.RefreshRate < displayMode.RefreshRate) + it->increaseRefreshRate(displayMode.RefreshRate); + found = TRUE; + break; + } + } + + if( !found ) + mModeList.push_back( D3D11VideoMode( displayMode ) ); + } + */ + return TRUE; + } + //--------------------------------------------------------------------- + size_t D3D11VideoModeList::count() + { + return mModeList.size(); + } + //--------------------------------------------------------------------- + D3D11VideoMode* D3D11VideoModeList::item( size_t index ) + { + vector::type::iterator p = mModeList.begin(); + + return &p[index]; + } + //--------------------------------------------------------------------- + D3D11VideoMode* D3D11VideoModeList::item( const String &name ) + { + vector::type::iterator it = mModeList.begin(); + if (it == mModeList.end()) + return NULL; + + for (;it != mModeList.end(); ++it) + { + if (it->getDescription() == name) + return &(*it); + } + + return NULL; + } + //--------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D9/include/OgreD3D9DepthBuffer.h b/RenderSystems/Direct3D9/include/OgreD3D9DepthBuffer.h index dae0def67b0..46cec04ab97 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9DepthBuffer.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9DepthBuffer.h @@ -33,27 +33,27 @@ THE SOFTWARE. namespace Ogre { - class D3D9DepthBuffer : public DepthBuffer - { - public: - D3D9DepthBuffer( uint16 poolId, D3D9RenderSystem *renderSystem, IDirect3DDevice9 *creator, - IDirect3DSurface9 *depthBufferSurf, - D3DFORMAT fmt, uint32 width, uint32 height, - uint32 fsaa, uint32 multiSampleQuality, bool isManual ); - ~D3D9DepthBuffer(); - - /// @copydoc DepthBuffer::isCompatible - virtual bool isCompatible( RenderTarget *renderTarget ) const; - - IDirect3DDevice9* getDeviceCreator() const; - IDirect3DSurface9* getDepthBufferSurface() const; - - protected: - IDirect3DSurface9 *mDepthBuffer; - IDirect3DDevice9 *mCreator; - uint32 mMultiSampleQuality; - D3DFORMAT mD3DFormat; - D3D9RenderSystem *mRenderSystem; - }; + class D3D9DepthBuffer : public DepthBuffer + { + public: + D3D9DepthBuffer( uint16 poolId, D3D9RenderSystem *renderSystem, IDirect3DDevice9 *creator, + IDirect3DSurface9 *depthBufferSurf, + D3DFORMAT fmt, uint32 width, uint32 height, + uint32 fsaa, uint32 multiSampleQuality, bool isManual ); + ~D3D9DepthBuffer(); + + /// @copydoc DepthBuffer::isCompatible + virtual bool isCompatible( RenderTarget *renderTarget ) const; + + IDirect3DDevice9* getDeviceCreator() const; + IDirect3DSurface9* getDepthBufferSurface() const; + + protected: + IDirect3DSurface9 *mDepthBuffer; + IDirect3DDevice9 *mCreator; + uint32 mMultiSampleQuality; + D3DFORMAT mD3DFormat; + D3D9RenderSystem *mRenderSystem; + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9Device.h b/RenderSystems/Direct3D9/include/OgreD3D9Device.h index d11992d44c7..a86da48271a 100755 --- a/RenderSystems/Direct3D9/include/OgreD3D9Device.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9Device.h @@ -33,126 +33,126 @@ THE SOFTWARE. namespace Ogre { - class D3D9RenderWindow; - class D3D9DeviceManager; - - /** High level interface of Direct3D9 Device. - Provide useful methods for device handling. - */ - class _OgreD3D9Export D3D9Device : public ResourceAlloc - { - - // Interface. - public: - void attachRenderWindow (D3D9RenderWindow* renderWindow); - void detachRenderWindow (D3D9RenderWindow* renderWindow); - - bool acquire (); - - void release (); - void destroy (); - - bool isDeviceLost (); - IDirect3DDevice9* getD3D9Device (); - - UINT getAdapterNumber () const; - D3DDEVTYPE getDeviceType () const; - bool isMultihead () const; - bool isAutoDepthStencil () const; - bool isFullScreen () const; - - const D3DCAPS9& getD3D9DeviceCaps () const; - D3DFORMAT getBackBufferFormat () const; - - bool validate (D3D9RenderWindow* renderWindow); - void invalidate (D3D9RenderWindow* renderWindow); - - void present (D3D9RenderWindow* renderWindow); - - IDirect3DSurface9* getDepthBuffer (D3D9RenderWindow* renderWindow); - IDirect3DSurface9* getBackBuffer (D3D9RenderWindow* renderWindow); - - uint getRenderWindowCount () const; - D3D9RenderWindow* getRenderWindow (uint index); - uint getLastPresentFrame () const { return mLastPresentFrame; } - - void setAdapterOrdinalIndex (D3D9RenderWindow* renderWindow, uint adapterOrdinalInGroupIndex); - void copyContentsToMemory(D3D9RenderWindow* window, const PixelBox &dst, RenderTarget::FrameBuffer buffer); - void clearDeviceStreams (); - int getVBlankMissCount (D3D9RenderWindow* renderWindow); - - public: - D3D9Device (D3D9DeviceManager* deviceManager, - UINT adapterNumber, - HMONITOR hMonitor, - D3DDEVTYPE devType, - DWORD behaviorFlags); - ~D3D9Device (); - - protected: - D3D9DeviceManager* mDeviceManager; // The manager of this device instance. - IDirect3DDevice9* mDevice; // Will hold the device interface. - UINT mAdapterNumber; // The adapter that this device belongs to. - HMONITOR mMonitor; // The monitor that this device belongs to. - D3DDEVTYPE mDeviceType; // Device type. - static HWND msSharedFocusWindow; // The shared focus window in case of multiple full screen render windows. - HWND mFocusWindow; // The focus window this device attached to. - DWORD mBehaviorFlags; // The behavior of this device. - D3DPRESENT_PARAMETERS* mPresentationParams; // Presentation parameters which the device was created with. May be - // an array of presentation parameters in case of multi-head device. - UINT mPresentationParamsCount; // Number of presentation parameters elements. - D3DCAPS9 mD3D9DeviceCaps; // Device caps. - bool mD3D9DeviceCapsValid; // True if device caps initialized. - D3DDEVICE_CREATION_PARAMETERS mCreationParams; // Creation parameters. - uint mLastPresentFrame; // Last frame that this device present method called. - bool mDeviceLost; // True if device entered lost state. - D3DPRESENTSTATS mPreviousPresentStats; // We save the previous present stats - so we can detect a "vblank miss" - bool mPreviousPresentStatsIsValid; // Does mLastPresentStats data is valid (it isn't if when you start or resize the window) - uint mVBlankMissCount; // Number of times we missed the v sync blank - - struct RenderWindowResources - { - IDirect3DSwapChain9* swapChain; // Swap chain interface. - IDirect3DSwapChain9Ex * swapChain9Ex; // The 9Ex version of the chain is needed for the v synk blank stats - uint adapterOrdinalInGroupIndex; // Relative index of the render window in the group. - uint presentParametersIndex; // Index of present parameter in the shared array of the device. - IDirect3DSurface9* backBuffer; // The back buffer of the render window. - IDirect3DSurface9* depthBuffer; // The depth buffer of the render window. - D3DPRESENT_PARAMETERS presentParameters; // Present parameters of the render window. - bool acquired; // True if resources acquired. - }; - typedef map::type RenderWindowToResourcesMap; - typedef RenderWindowToResourcesMap::iterator RenderWindowToResourcesIterator; - - RenderWindowToResourcesMap mMapRenderWindowToResources; // Map between render window to resources. - - - protected: - RenderWindowToResourcesIterator getRenderWindowIterator (D3D9RenderWindow* renderWindow); - - bool acquire (D3D9RenderWindow* renderWindow); - bool reset (); - void updatePresentationParameters (); - void updateRenderWindowsIndices (); - - void createD3D9Device (); - void releaseD3D9Device (); - void releaseRenderWindowResources (RenderWindowResources* renderWindowResources); - void acquireRenderWindowResources (RenderWindowToResourcesIterator it); - void setupDeviceStates (); - void notifyDeviceLost (); - - void validateFocusWindow (); - void validateBackBufferSize (D3D9RenderWindow* renderWindow); - bool validateDisplayMonitor (D3D9RenderWindow* renderWindow); - bool validateDeviceState (D3D9RenderWindow* renderWindow); - bool isSwapChainWindow (D3D9RenderWindow* renderWindow); - D3D9RenderWindow* getPrimaryWindow (); - void setSharedWindowHandle (HWND hSharedHWND); - - private: - friend class D3D9DeviceManager; - friend class D3D9RenderSystem; - }; + class D3D9RenderWindow; + class D3D9DeviceManager; + + /** High level interface of Direct3D9 Device. + Provide useful methods for device handling. + */ + class _OgreD3D9Export D3D9Device : public ResourceAlloc + { + + // Interface. + public: + void attachRenderWindow (D3D9RenderWindow* renderWindow); + void detachRenderWindow (D3D9RenderWindow* renderWindow); + + bool acquire (); + + void release (); + void destroy (); + + bool isDeviceLost (); + IDirect3DDevice9* getD3D9Device (); + + UINT getAdapterNumber () const; + D3DDEVTYPE getDeviceType () const; + bool isMultihead () const; + bool isAutoDepthStencil () const; + bool isFullScreen () const; + + const D3DCAPS9& getD3D9DeviceCaps () const; + D3DFORMAT getBackBufferFormat () const; + + bool validate (D3D9RenderWindow* renderWindow); + void invalidate (D3D9RenderWindow* renderWindow); + + void present (D3D9RenderWindow* renderWindow); + + IDirect3DSurface9* getDepthBuffer (D3D9RenderWindow* renderWindow); + IDirect3DSurface9* getBackBuffer (D3D9RenderWindow* renderWindow); + + uint getRenderWindowCount () const; + D3D9RenderWindow* getRenderWindow (uint index); + uint getLastPresentFrame () const { return mLastPresentFrame; } + + void setAdapterOrdinalIndex (D3D9RenderWindow* renderWindow, uint adapterOrdinalInGroupIndex); + void copyContentsToMemory(D3D9RenderWindow* window, const PixelBox &dst, RenderTarget::FrameBuffer buffer); + void clearDeviceStreams (); + int getVBlankMissCount (D3D9RenderWindow* renderWindow); + + public: + D3D9Device (D3D9DeviceManager* deviceManager, + UINT adapterNumber, + HMONITOR hMonitor, + D3DDEVTYPE devType, + DWORD behaviorFlags); + ~D3D9Device (); + + protected: + D3D9DeviceManager* mDeviceManager; // The manager of this device instance. + IDirect3DDevice9* mDevice; // Will hold the device interface. + UINT mAdapterNumber; // The adapter that this device belongs to. + HMONITOR mMonitor; // The monitor that this device belongs to. + D3DDEVTYPE mDeviceType; // Device type. + static HWND msSharedFocusWindow; // The shared focus window in case of multiple full screen render windows. + HWND mFocusWindow; // The focus window this device attached to. + DWORD mBehaviorFlags; // The behavior of this device. + D3DPRESENT_PARAMETERS* mPresentationParams; // Presentation parameters which the device was created with. May be + // an array of presentation parameters in case of multi-head device. + UINT mPresentationParamsCount; // Number of presentation parameters elements. + D3DCAPS9 mD3D9DeviceCaps; // Device caps. + bool mD3D9DeviceCapsValid; // True if device caps initialized. + D3DDEVICE_CREATION_PARAMETERS mCreationParams; // Creation parameters. + uint mLastPresentFrame; // Last frame that this device present method called. + bool mDeviceLost; // True if device entered lost state. + D3DPRESENTSTATS mPreviousPresentStats; // We save the previous present stats - so we can detect a "vblank miss" + bool mPreviousPresentStatsIsValid; // Does mLastPresentStats data is valid (it isn't if when you start or resize the window) + uint mVBlankMissCount; // Number of times we missed the v sync blank + + struct RenderWindowResources + { + IDirect3DSwapChain9* swapChain; // Swap chain interface. + IDirect3DSwapChain9Ex * swapChain9Ex; // The 9Ex version of the chain is needed for the v synk blank stats + uint adapterOrdinalInGroupIndex; // Relative index of the render window in the group. + uint presentParametersIndex; // Index of present parameter in the shared array of the device. + IDirect3DSurface9* backBuffer; // The back buffer of the render window. + IDirect3DSurface9* depthBuffer; // The depth buffer of the render window. + D3DPRESENT_PARAMETERS presentParameters; // Present parameters of the render window. + bool acquired; // True if resources acquired. + }; + typedef map::type RenderWindowToResourcesMap; + typedef RenderWindowToResourcesMap::iterator RenderWindowToResourcesIterator; + + RenderWindowToResourcesMap mMapRenderWindowToResources; // Map between render window to resources. + + + protected: + RenderWindowToResourcesIterator getRenderWindowIterator (D3D9RenderWindow* renderWindow); + + bool acquire (D3D9RenderWindow* renderWindow); + bool reset (); + void updatePresentationParameters (); + void updateRenderWindowsIndices (); + + void createD3D9Device (); + void releaseD3D9Device (); + void releaseRenderWindowResources (RenderWindowResources* renderWindowResources); + void acquireRenderWindowResources (RenderWindowToResourcesIterator it); + void setupDeviceStates (); + void notifyDeviceLost (); + + void validateFocusWindow (); + void validateBackBufferSize (D3D9RenderWindow* renderWindow); + bool validateDisplayMonitor (D3D9RenderWindow* renderWindow); + bool validateDeviceState (D3D9RenderWindow* renderWindow); + bool isSwapChainWindow (D3D9RenderWindow* renderWindow); + D3D9RenderWindow* getPrimaryWindow (); + void setSharedWindowHandle (HWND hSharedHWND); + + private: + friend class D3D9DeviceManager; + friend class D3D9RenderSystem; + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9DeviceManager.h b/RenderSystems/Direct3D9/include/OgreD3D9DeviceManager.h index 724891cc075..cc8c944adc6 100755 --- a/RenderSystems/Direct3D9/include/OgreD3D9DeviceManager.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9DeviceManager.h @@ -32,45 +32,45 @@ THE SOFTWARE. namespace Ogre { - class D3D9Device; - class D3D9RenderWindow; + class D3D9Device; + class D3D9RenderWindow; - /** Device manager interface. - */ - class _OgreD3D9Export D3D9DeviceManager : public ResourceAlloc - { + /** Device manager interface. + */ + class _OgreD3D9Export D3D9DeviceManager : public ResourceAlloc + { - // Interface. - public: - void setActiveDevice (D3D9Device* device); - D3D9Device* getActiveDevice (); - void setActiveRenderTargetDevice (D3D9Device* device); - D3D9Device* getActiveRenderTargetDevice (); - UINT getDeviceCount (); - D3D9Device* getDevice (UINT index); - void linkRenderWindow (D3D9RenderWindow* renderWindow); - void destroyInactiveRenderDevices (); - void notifyOnDeviceDestroy (D3D9Device* device); - D3D9Device* getDeviceFromD3D9Device (IDirect3DDevice9* d3d9Device); - - public: - D3D9DeviceManager (); - ~D3D9DeviceManager (); + // Interface. + public: + void setActiveDevice (D3D9Device* device); + D3D9Device* getActiveDevice (); + void setActiveRenderTargetDevice (D3D9Device* device); + D3D9Device* getActiveRenderTargetDevice (); + UINT getDeviceCount (); + D3D9Device* getDevice (UINT index); + void linkRenderWindow (D3D9RenderWindow* renderWindow); + void destroyInactiveRenderDevices (); + void notifyOnDeviceDestroy (D3D9Device* device); + D3D9Device* getDeviceFromD3D9Device (IDirect3DDevice9* d3d9Device); + + public: + D3D9DeviceManager (); + ~D3D9DeviceManager (); - protected: - typedef vector::type DeviceList; - typedef DeviceList::iterator DeviceIterator; - typedef DeviceList::const_iterator ConstDeviceIterator; - typedef vector::type D3D9RenderWindowList; + protected: + typedef vector::type DeviceList; + typedef DeviceList::iterator DeviceIterator; + typedef DeviceList::const_iterator ConstDeviceIterator; + typedef vector::type D3D9RenderWindowList; - protected: - D3D9Device* selectDevice (D3D9RenderWindow* renderWindow, D3D9RenderWindowList& renderWindowsGroup); - D3D9Driver* findDriver (D3D9RenderWindow* renderWindow); + protected: + D3D9Device* selectDevice (D3D9RenderWindow* renderWindow, D3D9RenderWindowList& renderWindowsGroup); + D3D9Driver* findDriver (D3D9RenderWindow* renderWindow); - - DeviceList mRenderDevices; - D3D9Device* mActiveDevice; - D3D9Device* mActiveRenderWindowDevice; - }; + + DeviceList mRenderDevices; + D3D9Device* mActiveDevice; + D3D9Device* mActiveRenderWindowDevice; + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9Driver.h b/RenderSystems/Direct3D9/include/OgreD3D9Driver.h index 42da1e76a76..4acb398074d 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9Driver.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9Driver.h @@ -34,47 +34,47 @@ THE SOFTWARE. namespace Ogre { - class D3D9VideoModeList; - class D3D9VideoMode; + class D3D9VideoModeList; + class D3D9VideoMode; - class _OgreD3D9Export D3D9Driver : public ResourceAlloc - { - - public: - // Constructors - D3D9Driver(); // Default - D3D9Driver( const D3D9Driver &ob ); // Copy - D3D9Driver( unsigned int adapterNumber, - const D3DCAPS9& deviceCaps, - const D3DADAPTER_IDENTIFIER9& adapterIdentifer, - const D3DDISPLAYMODE& desktopDisplayMode); - ~D3D9Driver(); + class _OgreD3D9Export D3D9Driver : public ResourceAlloc + { + + public: + // Constructors + D3D9Driver(); // Default + D3D9Driver( const D3D9Driver &ob ); // Copy + D3D9Driver( unsigned int adapterNumber, + const D3DCAPS9& deviceCaps, + const D3DADAPTER_IDENTIFIER9& adapterIdentifer, + const D3DDISPLAYMODE& desktopDisplayMode); + ~D3D9Driver(); - - const D3DCAPS9& getD3D9DeviceCaps () const { return mD3D9DeviceCaps; } - String DriverName () const; - String DriverDescription () const; - - unsigned int getAdapterNumber () const { return mAdapterNumber; } - const D3DADAPTER_IDENTIFIER9& getAdapterIdentifier() const { return mAdapterIdentifier; } - const D3DDISPLAYMODE& getDesktopMode () const { return mDesktopDisplayMode; } - D3D9VideoModeList* getVideoModeList (); - - private: - // Adapter number. - unsigned int mAdapterNumber; - - // Device caps. - D3DCAPS9 mD3D9DeviceCaps; - - // Adapter identifier - D3DADAPTER_IDENTIFIER9 mAdapterIdentifier; + + const D3DCAPS9& getD3D9DeviceCaps () const { return mD3D9DeviceCaps; } + String DriverName () const; + String DriverDescription () const; + + unsigned int getAdapterNumber () const { return mAdapterNumber; } + const D3DADAPTER_IDENTIFIER9& getAdapterIdentifier() const { return mAdapterIdentifier; } + const D3DDISPLAYMODE& getDesktopMode () const { return mDesktopDisplayMode; } + D3D9VideoModeList* getVideoModeList (); + + private: + // Adapter number. + unsigned int mAdapterNumber; + + // Device caps. + D3DCAPS9 mD3D9DeviceCaps; + + // Adapter identifier + D3DADAPTER_IDENTIFIER9 mAdapterIdentifier; - // Desktop display mode. - D3DDISPLAYMODE mDesktopDisplayMode; + // Desktop display mode. + D3DDISPLAYMODE mDesktopDisplayMode; - // Video modes list. - D3D9VideoModeList* mVideoModeList; - }; + // Video modes list. + D3D9VideoModeList* mVideoModeList; + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9DriverList.h b/RenderSystems/Direct3D9/include/OgreD3D9DriverList.h index b82be4b7131..dbd9a074f69 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9DriverList.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9DriverList.h @@ -33,20 +33,20 @@ THE SOFTWARE. namespace Ogre { - class _OgreD3D9Export D3D9DriverList : public ResourceAlloc - { - private: - vector::type mDriverList; - - public: - D3D9DriverList(); - ~D3D9DriverList(); - - BOOL enumerate(); - size_t count() const; - D3D9Driver* item( size_t index ); - - D3D9Driver* item( const String &name ); - }; + class _OgreD3D9Export D3D9DriverList : public ResourceAlloc + { + private: + vector::type mDriverList; + + public: + D3D9DriverList(); + ~D3D9DriverList(); + + BOOL enumerate(); + size_t count() const; + D3D9Driver* item( size_t index ); + + D3D9Driver* item( const String &name ); + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9GpuProgram.h b/RenderSystems/Direct3D9/include/OgreD3D9GpuProgram.h index 916a9b27d1c..c12c9d3a3e3 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9GpuProgram.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9GpuProgram.h @@ -38,7 +38,7 @@ namespace Ogre { /** Direct3D implementation of a few things common to low-level vertex & fragment programs. */ class _OgreD3D9Export D3D9GpuProgram : public GpuProgram, public D3D9Resource { - public: + public: /// Command object for setting matrix packing in column-major order class CmdColumnMajorMatrices : public ParamCommand { @@ -46,16 +46,16 @@ namespace Ogre { String doGet(const void* target) const; void doSet(void* target, const String& val); }; - /// Command object for getting/setting external micro code (void*) - class CmdExternalMicrocode : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - protected: - static CmdColumnMajorMatrices msCmdColumnMajorMatrices; - static CmdExternalMicrocode msCmdExternalMicrocode; + /// Command object for getting/setting external micro code (void*) + class CmdExternalMicrocode : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + protected: + static CmdColumnMajorMatrices msCmdColumnMajorMatrices; + static CmdExternalMicrocode msCmdExternalMicrocode; public: D3D9GpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); @@ -67,9 +67,9 @@ namespace Ogre { /** Gets whether matrix packed in column-major order. */ bool getColumnMajorMatrices(void) const { return mColumnMajorMatrices; } - /** Tells the program to load from some externally created microcode instead of a file or source. - */ - void setExternalMicrocode(const void* pMicrocode, size_t size); + /** Tells the program to load from some externally created microcode instead of a file or source. + */ + void setExternalMicrocode(const void* pMicrocode, size_t size); /** Tells the program to load from some externally created microcode instead of a file or source. @remarks add ref count to pMicrocode when setting @@ -80,15 +80,15 @@ namespace Ogre { protected: /** @copydoc Resource::loadImpl */ void loadImpl(void); - /** Loads this program to specified device */ - void loadImpl(IDirect3DDevice9* d3d9Device); - /** Overridden from GpuProgram */ - void unloadImpl(void); + /** Loads this program to specified device */ + void loadImpl(IDirect3DDevice9* d3d9Device); + /** Overridden from GpuProgram */ + void unloadImpl(void); /** Overridden from GpuProgram */ void loadFromSource(void); - /** Loads this program from source to specified device */ - void loadFromSource(IDirect3DDevice9* d3d9Device); - /** Loads this program from microcode, must be overridden by subclasses. */ + /** Loads this program from source to specified device */ + void loadFromSource(IDirect3DDevice9* d3d9Device); + /** Loads this program from microcode, must be overridden by subclasses. */ virtual void loadFromMicrocode(IDirect3DDevice9* d3d9Device, ID3DXBuffer* microcode) = 0; @@ -100,12 +100,12 @@ namespace Ogre { they are appropriate. */ virtual GpuProgramParametersSharedPtr createParameters(void); - protected: - bool mColumnMajorMatrices; - ID3DXBuffer* mExternalMicrocode; + protected: + bool mColumnMajorMatrices; + ID3DXBuffer* mExternalMicrocode; - void getMicrocodeFromCache( IDirect3DDevice9* d3d9Device ); - void compileMicrocode( IDirect3DDevice9* d3d9Device ); + void getMicrocodeFromCache( IDirect3DDevice9* d3d9Device ); + void compileMicrocode( IDirect3DDevice9* d3d9Device ); }; /** Direct3D implementation of low-level vertex programs. */ @@ -114,27 +114,27 @@ namespace Ogre { public: D3D9GpuVertexProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - ~D3D9GpuVertexProgram(); + ~D3D9GpuVertexProgram(); - /// Gets the vertex shader + /// Gets the vertex shader IDirect3DVertexShader9* getVertexShader(void); - // Called immediately after the Direct3D device has been created. - virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); + // Called immediately after the Direct3D device has been created. + virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); - // Called before the Direct3D device is going to be destroyed. - virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); + // Called before the Direct3D device is going to be destroyed. + virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); protected: /** @copydoc Resource::unloadImpl */ void unloadImpl(void); void loadFromMicrocode(IDirect3DDevice9* d3d9Device, ID3DXBuffer* microcode); - protected: - typedef map::type DeviceToVertexShaderMap; - typedef DeviceToVertexShaderMap::iterator DeviceToVertexShaderIterator; - - DeviceToVertexShaderMap mMapDeviceToVertexShader; + protected: + typedef map::type DeviceToVertexShaderMap; + typedef DeviceToVertexShaderMap::iterator DeviceToVertexShaderIterator; + + DeviceToVertexShaderMap mMapDeviceToVertexShader; }; /** Direct3D implementation of low-level fragment programs. */ @@ -143,26 +143,26 @@ namespace Ogre { public: D3D9GpuFragmentProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - ~D3D9GpuFragmentProgram(); + ~D3D9GpuFragmentProgram(); /// Gets the pixel shader IDirect3DPixelShader9* getPixelShader(void); - // Called immediately after the Direct3D device has been created. - virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); + // Called immediately after the Direct3D device has been created. + virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); - // Called before the Direct3D device is going to be destroyed. - virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); + // Called before the Direct3D device is going to be destroyed. + virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); protected: /** @copydoc Resource::unloadImpl */ void unloadImpl(void); void loadFromMicrocode(IDirect3DDevice9* d3d9Device, ID3DXBuffer* microcode); - protected: - typedef map::type DeviceToPixelShaderMap; - typedef DeviceToPixelShaderMap::iterator DeviceToPixelShaderIterator; + protected: + typedef map::type DeviceToPixelShaderMap; + typedef DeviceToPixelShaderMap::iterator DeviceToPixelShaderIterator; - DeviceToPixelShaderMap mMapDeviceToPixelShader; + DeviceToPixelShaderMap mMapDeviceToPixelShader; }; } diff --git a/RenderSystems/Direct3D9/include/OgreD3D9GpuProgramManager.h b/RenderSystems/Direct3D9/include/OgreD3D9GpuProgramManager.h index 5a1f75c9d1f..b9329ff0a05 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9GpuProgramManager.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9GpuProgramManager.h @@ -46,7 +46,7 @@ namespace Ogre { GpuProgramType gptype, const String& syntaxCode); public: D3D9GpuProgramManager(); - ~D3D9GpuProgramManager(); + ~D3D9GpuProgramManager(); }; } diff --git a/RenderSystems/Direct3D9/include/OgreD3D9HLSLProgram.h b/RenderSystems/Direct3D9/include/OgreD3D9HLSLProgram.h index 8c72f49a765..b0679173a5c 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9HLSLProgram.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9HLSLProgram.h @@ -71,37 +71,37 @@ namespace Ogre { String doGet(const void* target) const; void doSet(void* target, const String& val); }; - /// Command object for setting optimisation level - class CmdOptimisation : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - - /// Command object for getting/setting micro code - class CmdMicrocode : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - - /// Command object for getting/setting assembler code - class CmdAssemblerCode : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - - /// Command object for enabling backwards compatibility - class CmdBackwardsCompatibility : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; + /// Command object for setting optimisation level + class CmdOptimisation : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + + /// Command object for getting/setting micro code + class CmdMicrocode : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + + /// Command object for getting/setting assembler code + class CmdAssemblerCode : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + + /// Command object for enabling backwards compatibility + class CmdBackwardsCompatibility : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; protected: @@ -109,9 +109,9 @@ namespace Ogre { static CmdTarget msCmdTarget; static CmdPreprocessorDefines msCmdPreprocessorDefines; static CmdColumnMajorMatrices msCmdColumnMajorMatrices; - static CmdOptimisation msCmdOptimisation; - static CmdMicrocode msCmdMicrocode; - static CmdAssemblerCode msCmdAssemblerCode; + static CmdOptimisation msCmdOptimisation; + static CmdMicrocode msCmdMicrocode; + static CmdAssemblerCode msCmdAssemblerCode; static CmdBackwardsCompatibility msCmdBackwardsCompatibility; /** Internal load implementation, must be implemented by subclasses. @@ -127,7 +127,7 @@ namespace Ogre { // Recursive utility method for buildParamNameMap void processParamElement(LPD3DXCONSTANTTABLE pConstTable, D3DXHANDLE parent, String prefix, unsigned int index); - void populateDef(D3DXCONSTANT_DESC& d3dDesc, GpuConstantDefinition& def) const; + void populateDef(D3DXCONSTANT_DESC& d3dDesc, GpuConstantDefinition& def) const; String mTarget; String mEntryPoint; @@ -137,37 +137,37 @@ namespace Ogre { LPD3DXBUFFER mMicroCode; - GpuConstantDefinitionMap mParametersMap; - size_t mParametersMapSizeAsBuffer; - - public: - LPD3DXBUFFER getMicroCode(); - public: - /// Shader optimisation level - enum OptimisationLevel - { - /// default - no optimisation in debug mode, OPT_1 in release mode - OPT_DEFAULT, - /// No optimisation - OPT_NONE, - /// Optimisation level 0 - OPT_0, - /// Optimisation level 1 - OPT_1, - /// Optimisation level 2 - OPT_2, - /// Optimisation level 3 - OPT_3 - }; - protected: - OptimisationLevel mOptimisationLevel; + GpuConstantDefinitionMap mParametersMap; + size_t mParametersMapSizeAsBuffer; + + public: + LPD3DXBUFFER getMicroCode(); + public: + /// Shader optimisation level + enum OptimisationLevel + { + /// default - no optimisation in debug mode, OPT_1 in release mode + OPT_DEFAULT, + /// No optimisation + OPT_NONE, + /// Optimisation level 0 + OPT_0, + /// Optimisation level 1 + OPT_1, + /// Optimisation level 2 + OPT_2, + /// Optimisation level 3 + OPT_3 + }; + protected: + OptimisationLevel mOptimisationLevel; /** Gets the microcode from the microcode cache. */ - void getMicrocodeFromCache(void); + void getMicrocodeFromCache(void); /** Compiles the microcode from the program source. */ - void compileMicrocode(void); - void addMicrocodeToCache(); - public: + void compileMicrocode(void); + void addMicrocodeToCache(); + public: D3D9HLSLProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); ~D3D9HLSLProgram(); @@ -188,17 +188,17 @@ namespace Ogre { void setColumnMajorMatrices(bool columnMajor) { mColumnMajorMatrices = columnMajor; } /** Gets whether matrix packed in column-major order. */ bool getColumnMajorMatrices(void) const { return mColumnMajorMatrices; } - /** Sets whether backwards compatibility mode should be enabled. */ - void setBackwardsCompatibility(bool compat) { mBackwardsCompatibility = compat; } - /** Gets whether backwards compatibility mode should be enabled. */ - bool getBackwardsCompatibility(void) const { return mBackwardsCompatibility; } - /** Sets the optimisation level to use. - @param opt Optimisation level - */ - void setOptimisationLevel(OptimisationLevel opt) { mOptimisationLevel = opt; } - - /** Gets the optimisation level to use. */ - OptimisationLevel getOptimisationLevel() const { return mOptimisationLevel; } + /** Sets whether backwards compatibility mode should be enabled. */ + void setBackwardsCompatibility(bool compat) { mBackwardsCompatibility = compat; } + /** Gets whether backwards compatibility mode should be enabled. */ + bool getBackwardsCompatibility(void) const { return mBackwardsCompatibility; } + /** Sets the optimisation level to use. + @param opt Optimisation level + */ + void setOptimisationLevel(OptimisationLevel opt) { mOptimisationLevel = opt; } + + /** Gets the optimisation level to use. */ + OptimisationLevel getOptimisationLevel() const { return mOptimisationLevel; } /// Overridden from GpuProgram bool isSupported(void) const; @@ -206,7 +206,7 @@ namespace Ogre { GpuProgramParametersSharedPtr createParameters(void); /// Overridden from GpuProgram const String& getLanguage(void) const; - }; + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9HLSLProgramFactory.h b/RenderSystems/Direct3D9/include/OgreD3D9HLSLProgramFactory.h index 456dc30d9e3..de9c3430f75 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9HLSLProgramFactory.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9HLSLProgramFactory.h @@ -37,16 +37,16 @@ namespace Ogre class _OgreD3D9Export D3D9HLSLProgramFactory : public HighLevelGpuProgramFactory { protected: - static String sLanguageName; + static String sLanguageName; public: D3D9HLSLProgramFactory(); ~D3D9HLSLProgramFactory(); - /// Get the name of the language this factory creates programs for - const String& getLanguage(void) const; + /// Get the name of the language this factory creates programs for + const String& getLanguage(void) const; HighLevelGpuProgram* create(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - void destroy(HighLevelGpuProgram* prog); + void destroy(HighLevelGpuProgram* prog); }; } diff --git a/RenderSystems/Direct3D9/include/OgreD3D9HardwareBufferManager.h b/RenderSystems/Direct3D9/include/OgreD3D9HardwareBufferManager.h index 83bcf231b67..d8e0c35a7be 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9HardwareBufferManager.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9HardwareBufferManager.h @@ -46,36 +46,36 @@ namespace Ogre { D3D9HardwareBufferManagerBase(); ~D3D9HardwareBufferManagerBase(); /// Creates a vertex buffer - HardwareVertexBufferSharedPtr + HardwareVertexBufferSharedPtr createVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// Create a hardware vertex buffer - HardwareIndexBufferSharedPtr + /// Create a hardware vertex buffer + HardwareIndexBufferSharedPtr createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// Create a render to vertex buffer - RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); - - HardwareUniformBufferSharedPtr - createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name = ""); + /// Create a render to vertex buffer + RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); + + HardwareUniformBufferSharedPtr + createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name = ""); - HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, + HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, bool useShadowBuffer = false, const String& name = ""); }; - /// D3D9HardwareBufferManagerBase as a Singleton - class _OgreD3D9Export D3D9HardwareBufferManager : public HardwareBufferManager - { - public: - D3D9HardwareBufferManager() - : HardwareBufferManager(OGRE_NEW D3D9HardwareBufferManagerBase()) - { + /// D3D9HardwareBufferManagerBase as a Singleton + class _OgreD3D9Export D3D9HardwareBufferManager : public HardwareBufferManager + { + public: + D3D9HardwareBufferManager() + : HardwareBufferManager(OGRE_NEW D3D9HardwareBufferManagerBase()) + { - } - ~D3D9HardwareBufferManager() - { - OGRE_DELETE mImpl; - } - }; + } + ~D3D9HardwareBufferManager() + { + OGRE_DELETE mImpl; + } + }; } diff --git a/RenderSystems/Direct3D9/include/OgreD3D9HardwareIndexBuffer.h b/RenderSystems/Direct3D9/include/OgreD3D9HardwareIndexBuffer.h index 1f97f12a875..38ca64fdee0 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9HardwareIndexBuffer.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9HardwareIndexBuffer.h @@ -39,71 +39,71 @@ namespace Ogre { { public: - D3D9HardwareIndexBuffer(HardwareBufferManagerBase* mgr, IndexType idxType, size_t numIndexes, - HardwareBuffer::Usage usage, bool useSystemMem, bool useShadowBuffer); + D3D9HardwareIndexBuffer(HardwareBufferManagerBase* mgr, IndexType idxType, size_t numIndexes, + HardwareBuffer::Usage usage, bool useSystemMem, bool useShadowBuffer); ~D3D9HardwareIndexBuffer(); /** See HardwareBuffer. */ void readData(size_t offset, size_t length, void* pDest); /** See HardwareBuffer. */ void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); - - // Called immediately after the Direct3D device has been created. - virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); - - // Called before the Direct3D device is going to be destroyed. - virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); - - // Called immediately after the Direct3D device has entered a lost state. - virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device); - - // Called immediately after the Direct3D device has been reset - virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device); - - // Create the actual index buffer. - void createBuffer(IDirect3DDevice9* d3d9Device, D3DPOOL ePool, bool updateNewBuffer); - - /// Get the D3D-specific index buffer - IDirect3DIndexBuffer9* getD3DIndexBuffer(void); - - protected: - struct BufferResources - { - IDirect3DIndexBuffer9* mBuffer; - bool mOutOfDate; - size_t mLockOffset; - size_t mLockLength; - LockOptions mLockOptions; - uint mLastUsedFrame; - }; - - protected: - /** See HardwareBuffer. */ - void* lockImpl(size_t offset, size_t length, LockOptions options); - - /** See HardwareBuffer. */ - void unlockImpl(void); - - /** Update the given buffer content.*/ - void updateBufferContent(BufferResources* bufferResources); - - // updates buffer resources from system memory buffer. - bool updateBufferResources(const char* systemMemoryBuffer, BufferResources* bufferResources); - - /** Internal buffer lock method. */ - char* _lockBuffer(BufferResources* bufferResources, size_t offset, size_t length); - - /** Internal buffer unlock method. */ - void _unlockBuffer(BufferResources* bufferResources); - - protected: - typedef map::type DeviceToBufferResourcesMap; - typedef DeviceToBufferResourcesMap::iterator DeviceToBufferResourcesIterator; - - DeviceToBufferResourcesMap mMapDeviceToBufferResources; // Map between device to buffer resources. - D3DINDEXBUFFER_DESC mBufferDesc; // Buffer description. - BufferResources* mSourceBuffer; // Source buffer resources when working with multiple devices. - char* mSourceLockedBytes; // Source buffer locked bytes. + bool discardWholeBuffer = false); + + // Called immediately after the Direct3D device has been created. + virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); + + // Called before the Direct3D device is going to be destroyed. + virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); + + // Called immediately after the Direct3D device has entered a lost state. + virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device); + + // Called immediately after the Direct3D device has been reset + virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device); + + // Create the actual index buffer. + void createBuffer(IDirect3DDevice9* d3d9Device, D3DPOOL ePool, bool updateNewBuffer); + + /// Get the D3D-specific index buffer + IDirect3DIndexBuffer9* getD3DIndexBuffer(void); + + protected: + struct BufferResources + { + IDirect3DIndexBuffer9* mBuffer; + bool mOutOfDate; + size_t mLockOffset; + size_t mLockLength; + LockOptions mLockOptions; + uint mLastUsedFrame; + }; + + protected: + /** See HardwareBuffer. */ + void* lockImpl(size_t offset, size_t length, LockOptions options); + + /** See HardwareBuffer. */ + void unlockImpl(void); + + /** Update the given buffer content.*/ + void updateBufferContent(BufferResources* bufferResources); + + // updates buffer resources from system memory buffer. + bool updateBufferResources(const char* systemMemoryBuffer, BufferResources* bufferResources); + + /** Internal buffer lock method. */ + char* _lockBuffer(BufferResources* bufferResources, size_t offset, size_t length); + + /** Internal buffer unlock method. */ + void _unlockBuffer(BufferResources* bufferResources); + + protected: + typedef map::type DeviceToBufferResourcesMap; + typedef DeviceToBufferResourcesMap::iterator DeviceToBufferResourcesIterator; + + DeviceToBufferResourcesMap mMapDeviceToBufferResources; // Map between device to buffer resources. + D3DINDEXBUFFER_DESC mBufferDesc; // Buffer description. + BufferResources* mSourceBuffer; // Source buffer resources when working with multiple devices. + char* mSourceLockedBytes; // Source buffer locked bytes. }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9HardwareOcclusionQuery.h b/RenderSystems/Direct3D9/include/OgreD3D9HardwareOcclusionQuery.h index 36c33ec3deb..cf8104adae3 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9HardwareOcclusionQuery.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9HardwareOcclusionQuery.h @@ -36,77 +36,77 @@ THE SOFTWARE. namespace Ogre { - // If you use multiple rendering passes you can test only the first pass and all other passes don't have to be rendered - // if the first pass results has too few pixels visible. - - // Be sure to render all occluder first and whats out so the RenderQue don't switch places on - // the occluding objects and the tested objects because it thinks it's more effective.. - - /** - * This is a class that is the DirectX9 implementation of - * hardware occlusion testing. - * - * @author Lee Sandberg, email lee@abcmedia.se - * - * Updated on 12/7/2004 by Chris McGuirk - * Updated on 4/8/2005 by Tuan Kuranes email: tuan.kuranes@free.fr - */ - class _OgreD3D9Export D3D9HardwareOcclusionQuery : public HardwareOcclusionQuery, public D3D9Resource - { - //---------------------------------------------------------------------- - // Public methods - //-- - public: - - /** - * Default object constructor - * - */ - D3D9HardwareOcclusionQuery(); - - /** - * Object destructor - */ - ~D3D9HardwareOcclusionQuery(); - - //------------------------------------------------------------------ - // Occlusion query functions (see base class documentation for this) - //-- - - void beginOcclusionQuery(); - void endOcclusionQuery(); - bool pullOcclusionQuery( unsigned int* NumOfFragments); - unsigned int getLastQuerysPixelcount(); + // If you use multiple rendering passes you can test only the first pass and all other passes don't have to be rendered + // if the first pass results has too few pixels visible. + + // Be sure to render all occluder first and whats out so the RenderQue don't switch places on + // the occluding objects and the tested objects because it thinks it's more effective.. + + /** + * This is a class that is the DirectX9 implementation of + * hardware occlusion testing. + * + * @author Lee Sandberg, email lee@abcmedia.se + * + * Updated on 12/7/2004 by Chris McGuirk + * Updated on 4/8/2005 by Tuan Kuranes email: tuan.kuranes@free.fr + */ + class _OgreD3D9Export D3D9HardwareOcclusionQuery : public HardwareOcclusionQuery, public D3D9Resource + { + //---------------------------------------------------------------------- + // Public methods + //-- + public: + + /** + * Default object constructor + * + */ + D3D9HardwareOcclusionQuery(); + + /** + * Object destructor + */ + ~D3D9HardwareOcclusionQuery(); + + //------------------------------------------------------------------ + // Occlusion query functions (see base class documentation for this) + //-- + + void beginOcclusionQuery(); + void endOcclusionQuery(); + bool pullOcclusionQuery( unsigned int* NumOfFragments); + unsigned int getLastQuerysPixelcount(); bool isStillOutstanding(void); - - // Called immediately after the Direct3D device has been created. - virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); - - // Called before the Direct3D device is going to be destroyed. - virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); - - // Called immediately after the Direct3D device has entered a lost state. - // This is the place to release non-managed resources. - virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device); - - // Called immediately after the Direct3D device has been reset. - // This is the place to create non-managed resources. - virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device); - - - private: - void createQuery(IDirect3DDevice9* d3d9Device); - void releaseQuery(IDirect3DDevice9* d3d9Device); - - //---------------------------------------------------------------------- - // private members - //-- - private: - typedef map::type DeviceToQueryMap; - typedef DeviceToQueryMap::iterator DeviceToQueryIterator; - - DeviceToQueryMap mMapDeviceToQuery; - }; + + // Called immediately after the Direct3D device has been created. + virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); + + // Called before the Direct3D device is going to be destroyed. + virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); + + // Called immediately after the Direct3D device has entered a lost state. + // This is the place to release non-managed resources. + virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device); + + // Called immediately after the Direct3D device has been reset. + // This is the place to create non-managed resources. + virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device); + + + private: + void createQuery(IDirect3DDevice9* d3d9Device); + void releaseQuery(IDirect3DDevice9* d3d9Device); + + //---------------------------------------------------------------------- + // private members + //-- + private: + typedef map::type DeviceToQueryMap; + typedef DeviceToQueryMap::iterator DeviceToQueryIterator; + + DeviceToQueryMap mMapDeviceToQuery; + }; } diff --git a/RenderSystems/Direct3D9/include/OgreD3D9HardwarePixelBuffer.h b/RenderSystems/Direct3D9/include/OgreD3D9HardwarePixelBuffer.h index 27a9bea08e6..6e0bc969e02 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9HardwarePixelBuffer.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9HardwarePixelBuffer.h @@ -34,125 +34,125 @@ THE SOFTWARE. namespace Ogre { - class D3D9Texture; - class D3D9RenderTexture; - - class _OgreD3D9Export D3D9HardwarePixelBuffer: public HardwarePixelBuffer - { - protected: - struct BufferResources - { - /// Surface abstracted by this buffer - IDirect3DSurface9* surface; - /// AA Surface abstracted by this buffer - IDirect3DSurface9* fSAASurface; - /// Volume abstracted by this buffer - IDirect3DVolume9* volume; - /// Temporary surface in main memory if direct locking of mSurface is not possible - IDirect3DSurface9* tempSurface; - /// Temporary volume in main memory if direct locking of mVolume is not possible - IDirect3DVolume9* tempVolume; - /// Mip map texture. - IDirect3DBaseTexture9 *mipTex; - }; - - typedef map::type DeviceToBufferResourcesMap; - typedef DeviceToBufferResourcesMap::iterator DeviceToBufferResourcesIterator; - - /// Map between device to buffer resources. - DeviceToBufferResourcesMap mMapDeviceToBufferResources; - - /// Mipmapping - bool mDoMipmapGen; - bool mHWMipmaps; - - /// Render target - D3D9RenderTexture* mRenderTexture; - - // The owner texture if exists. - D3D9Texture* mOwnerTexture; - - // The current lock flags of this surface. - DWORD mLockFlags; - - // Device access mutex. - OGRE_STATIC_MUTEX(msDeviceAccessMutex); - protected: - /// Lock a box - PixelBox lockImpl(const Image::Box &lockBox, LockOptions options); - PixelBox lockBuffer(BufferResources* bufferResources, const Image::Box &lockBox, DWORD flags); - - /// Unlock a box - void unlockImpl(void); - void unlockBuffer(BufferResources* bufferResources); - - BufferResources* getBufferResources(IDirect3DDevice9* d3d9Device); - BufferResources* createBufferResources(); - - /// updates render texture. - void updateRenderTexture(bool writeGamma, uint fsaa, const String& srcName); - /// destroy render texture. - void destroyRenderTexture(); - - void blit(IDirect3DDevice9* d3d9Device, const HardwarePixelBufferSharedPtr &src, - const Image::Box &srcBox, const Image::Box &dstBox, - BufferResources* srcBufferResources, - BufferResources* dstBufferResources); - void blitFromMemory(const PixelBox &src, const Image::Box &dstBox, BufferResources* dstBufferResources); - - void blitToMemory(const Image::Box &srcBox, const PixelBox &dst, BufferResources* srcBufferResources, IDirect3DDevice9* d3d9Device); - - public: - D3D9HardwarePixelBuffer(HardwareBuffer::Usage usage, - D3D9Texture* ownerTexture); - ~D3D9HardwarePixelBuffer(); - - /// Call this to associate a D3D surface or volume with this pixel buffer - void bind(IDirect3DDevice9 *dev, IDirect3DSurface9 *mSurface, IDirect3DSurface9* fsaaSurface, - bool writeGamma, uint fsaa, const String& srcName, IDirect3DBaseTexture9 *mipTex); - void bind(IDirect3DDevice9 *dev, IDirect3DVolume9 *mVolume, IDirect3DBaseTexture9 *mipTex); - - /// @copydoc HardwarePixelBuffer::blit + class D3D9Texture; + class D3D9RenderTexture; + + class _OgreD3D9Export D3D9HardwarePixelBuffer: public HardwarePixelBuffer + { + protected: + struct BufferResources + { + /// Surface abstracted by this buffer + IDirect3DSurface9* surface; + /// AA Surface abstracted by this buffer + IDirect3DSurface9* fSAASurface; + /// Volume abstracted by this buffer + IDirect3DVolume9* volume; + /// Temporary surface in main memory if direct locking of mSurface is not possible + IDirect3DSurface9* tempSurface; + /// Temporary volume in main memory if direct locking of mVolume is not possible + IDirect3DVolume9* tempVolume; + /// Mip map texture. + IDirect3DBaseTexture9 *mipTex; + }; + + typedef map::type DeviceToBufferResourcesMap; + typedef DeviceToBufferResourcesMap::iterator DeviceToBufferResourcesIterator; + + /// Map between device to buffer resources. + DeviceToBufferResourcesMap mMapDeviceToBufferResources; + + /// Mipmapping + bool mDoMipmapGen; + bool mHWMipmaps; + + /// Render target + D3D9RenderTexture* mRenderTexture; + + // The owner texture if exists. + D3D9Texture* mOwnerTexture; + + // The current lock flags of this surface. + DWORD mLockFlags; + + // Device access mutex. + OGRE_STATIC_MUTEX(msDeviceAccessMutex); + protected: + /// Lock a box + PixelBox lockImpl(const Image::Box &lockBox, LockOptions options); + PixelBox lockBuffer(BufferResources* bufferResources, const Image::Box &lockBox, DWORD flags); + + /// Unlock a box + void unlockImpl(void); + void unlockBuffer(BufferResources* bufferResources); + + BufferResources* getBufferResources(IDirect3DDevice9* d3d9Device); + BufferResources* createBufferResources(); + + /// updates render texture. + void updateRenderTexture(bool writeGamma, uint fsaa, const String& srcName); + /// destroy render texture. + void destroyRenderTexture(); + + void blit(IDirect3DDevice9* d3d9Device, const HardwarePixelBufferSharedPtr &src, + const Image::Box &srcBox, const Image::Box &dstBox, + BufferResources* srcBufferResources, + BufferResources* dstBufferResources); + void blitFromMemory(const PixelBox &src, const Image::Box &dstBox, BufferResources* dstBufferResources); + + void blitToMemory(const Image::Box &srcBox, const PixelBox &dst, BufferResources* srcBufferResources, IDirect3DDevice9* d3d9Device); + + public: + D3D9HardwarePixelBuffer(HardwareBuffer::Usage usage, + D3D9Texture* ownerTexture); + ~D3D9HardwarePixelBuffer(); + + /// Call this to associate a D3D surface or volume with this pixel buffer + void bind(IDirect3DDevice9 *dev, IDirect3DSurface9 *mSurface, IDirect3DSurface9* fsaaSurface, + bool writeGamma, uint fsaa, const String& srcName, IDirect3DBaseTexture9 *mipTex); + void bind(IDirect3DDevice9 *dev, IDirect3DVolume9 *mVolume, IDirect3DBaseTexture9 *mipTex); + + /// @copydoc HardwarePixelBuffer::blit void blit(const HardwarePixelBufferSharedPtr &src, const Image::Box &srcBox, const Image::Box &dstBox); - - /// @copydoc HardwarePixelBuffer::blitFromMemory - void blitFromMemory(const PixelBox &src, const Image::Box &dstBox); - - /// @copydoc HardwarePixelBuffer::blitToMemory - void blitToMemory(const Image::Box &srcBox, const PixelBox &dst); - - /// Internal function to update mipmaps on update of level 0 - void _genMipmaps(IDirect3DBaseTexture9* mipTex); - - /// Function to set mipmap generation - void _setMipmapping(bool doMipmapGen, bool HWMipmaps); - - - /// Get rendertarget for z slice - RenderTexture *getRenderTarget(size_t zoffset); - - /// Accessor for surface - IDirect3DSurface9 *getSurface(IDirect3DDevice9* d3d9Device); - - /// Accessor for AA surface - IDirect3DSurface9 *getFSAASurface(IDirect3DDevice9* d3d9Device); - - /// Notify TextureBuffer of destruction of render target + + /// @copydoc HardwarePixelBuffer::blitFromMemory + void blitFromMemory(const PixelBox &src, const Image::Box &dstBox); + + /// @copydoc HardwarePixelBuffer::blitToMemory + void blitToMemory(const Image::Box &srcBox, const PixelBox &dst); + + /// Internal function to update mipmaps on update of level 0 + void _genMipmaps(IDirect3DBaseTexture9* mipTex); + + /// Function to set mipmap generation + void _setMipmapping(bool doMipmapGen, bool HWMipmaps); + + + /// Get rendertarget for z slice + RenderTexture *getRenderTarget(size_t zoffset); + + /// Accessor for surface + IDirect3DSurface9 *getSurface(IDirect3DDevice9* d3d9Device); + + /// Accessor for AA surface + IDirect3DSurface9 *getFSAASurface(IDirect3DDevice9* d3d9Device); + + /// Notify TextureBuffer of destruction of render target virtual void _clearSliceRTT(size_t zoffset); - /// Release surfaces held by this pixel buffer. - void releaseSurfaces(IDirect3DDevice9* d3d9Device); + /// Release surfaces held by this pixel buffer. + void releaseSurfaces(IDirect3DDevice9* d3d9Device); - /// Destroy resources associated with the given device. - void destroyBufferResources(IDirect3DDevice9* d3d9Device); + /// Destroy resources associated with the given device. + void destroyBufferResources(IDirect3DDevice9* d3d9Device); - // Called when device state is changing. Access to any device should be locked. - // Relevant for multi thread application. - static void lockDeviceAccess(); + // Called when device state is changing. Access to any device should be locked. + // Relevant for multi thread application. + static void lockDeviceAccess(); - // Called when device state change completed. Access to any device is allowed. - // Relevant for multi thread application. - static void unlockDeviceAccess(); - }; + // Called when device state change completed. Access to any device is allowed. + // Relevant for multi thread application. + static void unlockDeviceAccess(); + }; }; #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9HardwareVertexBuffer.h b/RenderSystems/Direct3D9/include/OgreD3D9HardwareVertexBuffer.h index 9a6750678ca..b117ee7cfe4 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9HardwareVertexBuffer.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9HardwareVertexBuffer.h @@ -39,72 +39,72 @@ namespace Ogre { { public: - D3D9HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, - size_t numVertices, HardwareBuffer::Usage usage, bool useSystemMem, bool useShadowBuffer); + D3D9HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, + size_t numVertices, HardwareBuffer::Usage usage, bool useSystemMem, bool useShadowBuffer); ~D3D9HardwareVertexBuffer(); /** See HardwareBuffer. */ void readData(size_t offset, size_t length, void* pDest); /** See HardwareBuffer. */ void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); - - // Called immediately after the Direct3D device has been created. - virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); + bool discardWholeBuffer = false); + + // Called immediately after the Direct3D device has been created. + virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); - // Called before the Direct3D device is going to be destroyed. - virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); + // Called before the Direct3D device is going to be destroyed. + virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); - // Called immediately after the Direct3D device has entered a lost state. - virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device); + // Called immediately after the Direct3D device has entered a lost state. + virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device); - // Called immediately after the Direct3D device has been reset - virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device); + // Called immediately after the Direct3D device has been reset + virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device); - // Create the actual vertex buffer. - void createBuffer(IDirect3DDevice9* d3d9Device, D3DPOOL ePool, bool updateNewBuffer); - + // Create the actual vertex buffer. + void createBuffer(IDirect3DDevice9* d3d9Device, D3DPOOL ePool, bool updateNewBuffer); + /// Get D3D9-specific vertex buffer IDirect3DVertexBuffer9* getD3D9VertexBuffer(void); - protected: - struct BufferResources - { - IDirect3DVertexBuffer9* mBuffer; - bool mOutOfDate; - size_t mLockOffset; - size_t mLockLength; - LockOptions mLockOptions; - uint mLastUsedFrame; - }; - - protected: - /** See HardwareBuffer. */ - void* lockImpl(size_t offset, size_t length, LockOptions options); - - /** See HardwareBuffer. */ - void unlockImpl(void); - - /** Update the given buffer content.*/ - void updateBufferContent(BufferResources* bufferResources); - - // updates buffer resources from system memory buffer. - bool updateBufferResources(const char* systemMemoryBuffer, BufferResources* bufferResources); - - /** Internal buffer lock method. */ - char* _lockBuffer(BufferResources* bufferResources, size_t offset, size_t length); - - /** Internal buffer unlock method. */ - void _unlockBuffer(BufferResources* bufferResources); - - - protected: - typedef map::type DeviceToBufferResourcesMap; - typedef DeviceToBufferResourcesMap::iterator DeviceToBufferResourcesIterator; - - DeviceToBufferResourcesMap mMapDeviceToBufferResources; // Map between device to buffer resources. - D3DVERTEXBUFFER_DESC mBufferDesc; // Buffer description. - BufferResources* mSourceBuffer; // Source buffer resources when working with multiple devices. - char* mSourceLockedBytes; // Source buffer locked bytes. + protected: + struct BufferResources + { + IDirect3DVertexBuffer9* mBuffer; + bool mOutOfDate; + size_t mLockOffset; + size_t mLockLength; + LockOptions mLockOptions; + uint mLastUsedFrame; + }; + + protected: + /** See HardwareBuffer. */ + void* lockImpl(size_t offset, size_t length, LockOptions options); + + /** See HardwareBuffer. */ + void unlockImpl(void); + + /** Update the given buffer content.*/ + void updateBufferContent(BufferResources* bufferResources); + + // updates buffer resources from system memory buffer. + bool updateBufferResources(const char* systemMemoryBuffer, BufferResources* bufferResources); + + /** Internal buffer lock method. */ + char* _lockBuffer(BufferResources* bufferResources, size_t offset, size_t length); + + /** Internal buffer unlock method. */ + void _unlockBuffer(BufferResources* bufferResources); + + + protected: + typedef map::type DeviceToBufferResourcesMap; + typedef DeviceToBufferResourcesMap::iterator DeviceToBufferResourcesIterator; + + DeviceToBufferResourcesMap mMapDeviceToBufferResources; // Map between device to buffer resources. + D3DVERTEXBUFFER_DESC mBufferDesc; // Buffer description. + BufferResources* mSourceBuffer; // Source buffer resources when working with multiple devices. + char* mSourceLockedBytes; // Source buffer locked bytes. }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9Mappings.h b/RenderSystems/Direct3D9/include/OgreD3D9Mappings.h index a3345e070fe..6f051660873 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9Mappings.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9Mappings.h @@ -38,88 +38,88 @@ THE SOFTWARE. namespace Ogre { - class _OgreD3D9Export D3D9Mappings - { - public: - /// enum identifying D3D9 tex. types - enum eD3DTexType - { - /// standard texture - D3D_TEX_TYPE_NORMAL, - /// cube texture - D3D_TEX_TYPE_CUBE, - /// volume texture - D3D_TEX_TYPE_VOLUME, - /// just to have it... - D3D_TEX_TYPE_NONE - }; + class _OgreD3D9Export D3D9Mappings + { + public: + /// enum identifying D3D9 tex. types + enum eD3DTexType + { + /// standard texture + D3D_TEX_TYPE_NORMAL, + /// cube texture + D3D_TEX_TYPE_CUBE, + /// volume texture + D3D_TEX_TYPE_VOLUME, + /// just to have it... + D3D_TEX_TYPE_NONE + }; - /// enum identifying D3D9 filter usage type - enum eD3DFilterUsage - { - /// min filter - D3D_FUSAGE_MIN, - /// mag filter - D3D_FUSAGE_MAG, - /// mip filter - D3D_FUSAGE_MIP - }; + /// enum identifying D3D9 filter usage type + enum eD3DFilterUsage + { + /// min filter + D3D_FUSAGE_MIN, + /// mag filter + D3D_FUSAGE_MAG, + /// mip filter + D3D_FUSAGE_MIP + }; - /// return a D3D9 equivalent for a Ogre ShadeOptions value - static DWORD get(ShadeOptions so); - /// return a D3D9 equivalent for a Ogre LightTypes value - static D3DLIGHTTYPE get(Ogre::Light::LightTypes lightType); - /// return a D3D9 equivalent for a Ogre TexCoordCalsMethod value - static DWORD get(TexCoordCalcMethod m, const D3DCAPS9& caps); - /// return a D3D9 equivalent for a Ogre TextureAddressingMode value - static D3DTEXTUREADDRESS get(TextureUnitState::TextureAddressingMode tam, const D3DCAPS9& devCaps); - /// return a D3D9 equivalent for a Ogre LayerBlendType value - static D3DTEXTURESTAGESTATETYPE get(LayerBlendType lbt); - /// return a D3D9 equivalent for a Ogre LayerBlendOperationEx value - static DWORD get(LayerBlendOperationEx lbo, const D3DCAPS9& devCaps); - /// return a D3D9 equivalent for a Ogre LayerBlendSource value - static DWORD get(LayerBlendSource lbs, bool perStageConstants); - /// return a D3D9 equivalent for a Ogre SceneBlendFactor value - static D3DBLEND get(SceneBlendFactor sbf); - /// return a D3D9 equivalent for a Ogre SceneBlendOperation value - static D3DBLENDOP get(SceneBlendOperation sbo); - /// return a D3D9 equivalent for a Ogre CompareFunction value - static DWORD get(CompareFunction cf); - /// return a D3D9 equivalent for a Ogre CillingMode value - static DWORD get(CullingMode cm, bool flip); - /// return a D3D9 equivalent for a Ogre FogMode value - static D3DFOGMODE get(FogMode fm); - /// return a D3D9 equivalent for a Ogre PolygonMode value - static D3DFILLMODE get(PolygonMode level); - /// return a D3D9 equivalent for a Ogre StencilOperation value - static DWORD get(StencilOperation op, bool invert = false); - /// return a D3D9 state type for Ogre FilterType value - static D3DSAMPLERSTATETYPE get(FilterType ft); - /// return a D3D9 filter option for Ogre FilterType & FilterOption value - static DWORD get(FilterType ft, FilterOptions fo, const D3DCAPS9& devCaps, eD3DTexType texType); - /// return the D3DtexType equivalent of a Ogre tex. type - static eD3DTexType get(TextureType ogreTexType); + /// return a D3D9 equivalent for a Ogre ShadeOptions value + static DWORD get(ShadeOptions so); + /// return a D3D9 equivalent for a Ogre LightTypes value + static D3DLIGHTTYPE get(Ogre::Light::LightTypes lightType); + /// return a D3D9 equivalent for a Ogre TexCoordCalsMethod value + static DWORD get(TexCoordCalcMethod m, const D3DCAPS9& caps); + /// return a D3D9 equivalent for a Ogre TextureAddressingMode value + static D3DTEXTUREADDRESS get(TextureUnitState::TextureAddressingMode tam, const D3DCAPS9& devCaps); + /// return a D3D9 equivalent for a Ogre LayerBlendType value + static D3DTEXTURESTAGESTATETYPE get(LayerBlendType lbt); + /// return a D3D9 equivalent for a Ogre LayerBlendOperationEx value + static DWORD get(LayerBlendOperationEx lbo, const D3DCAPS9& devCaps); + /// return a D3D9 equivalent for a Ogre LayerBlendSource value + static DWORD get(LayerBlendSource lbs, bool perStageConstants); + /// return a D3D9 equivalent for a Ogre SceneBlendFactor value + static D3DBLEND get(SceneBlendFactor sbf); + /// return a D3D9 equivalent for a Ogre SceneBlendOperation value + static D3DBLENDOP get(SceneBlendOperation sbo); + /// return a D3D9 equivalent for a Ogre CompareFunction value + static DWORD get(CompareFunction cf); + /// return a D3D9 equivalent for a Ogre CillingMode value + static DWORD get(CullingMode cm, bool flip); + /// return a D3D9 equivalent for a Ogre FogMode value + static D3DFOGMODE get(FogMode fm); + /// return a D3D9 equivalent for a Ogre PolygonMode value + static D3DFILLMODE get(PolygonMode level); + /// return a D3D9 equivalent for a Ogre StencilOperation value + static DWORD get(StencilOperation op, bool invert = false); + /// return a D3D9 state type for Ogre FilterType value + static D3DSAMPLERSTATETYPE get(FilterType ft); + /// return a D3D9 filter option for Ogre FilterType & FilterOption value + static DWORD get(FilterType ft, FilterOptions fo, const D3DCAPS9& devCaps, eD3DTexType texType); + /// return the D3DtexType equivalent of a Ogre tex. type + static eD3DTexType get(TextureType ogreTexType); /// return the combination of D3DUSAGE values for Ogre buffer usage static DWORD get(HardwareBuffer::Usage usage); /// Get lock options static DWORD get(HardwareBuffer::LockOptions options, HardwareBuffer::Usage usage); /// Get index type static D3DFORMAT get(HardwareIndexBuffer::IndexType itype); - /// Get vertex data type - static D3DDECLTYPE get(VertexElementType vType); - /// Get vertex semantic - static D3DDECLUSAGE get(VertexElementSemantic sem); + /// Get vertex data type + static D3DDECLTYPE get(VertexElementType vType); + /// Get vertex semantic + static D3DDECLUSAGE get(VertexElementSemantic sem); // Convert matrix to D3D style - static D3DXMATRIX makeD3DXMatrix( const Matrix4& mat ); + static D3DXMATRIX makeD3DXMatrix( const Matrix4& mat ); // Convert matrix from D3D style static Matrix4 convertD3DXMatrix( const D3DXMATRIX& mat ); - /// utility method, convert D3D9 pixel format to Ogre pixel format - static PixelFormat _getPF(D3DFORMAT d3dPF); - /// utility method, convert Ogre pixel format to D3D9 pixel format - static D3DFORMAT _getPF(PixelFormat ogrePF); - /// utility method, find closest Ogre pixel format that D3D9 can support - static PixelFormat _getClosestSupportedPF(PixelFormat ogrePF); - }; + /// utility method, convert D3D9 pixel format to Ogre pixel format + static PixelFormat _getPF(D3DFORMAT d3dPF); + /// utility method, convert Ogre pixel format to D3D9 pixel format + static D3DFORMAT _getPF(PixelFormat ogrePF); + /// utility method, find closest Ogre pixel format that D3D9 can support + static PixelFormat _getClosestSupportedPF(PixelFormat ogrePF); + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9MultiRenderTarget.h b/RenderSystems/Direct3D9/include/OgreD3D9MultiRenderTarget.h index 1d224174e80..8bc5bbf5756 100755 --- a/RenderSystems/Direct3D9/include/OgreD3D9MultiRenderTarget.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9MultiRenderTarget.h @@ -36,25 +36,25 @@ THE SOFTWARE. #include "OgreD3D9HardwarePixelBuffer.h" namespace Ogre { - class _OgreD3D9Export D3D9MultiRenderTarget : public MultiRenderTarget - { - public: - D3D9MultiRenderTarget(const String &name); - ~D3D9MultiRenderTarget(); + class _OgreD3D9Export D3D9MultiRenderTarget : public MultiRenderTarget + { + public: + D3D9MultiRenderTarget(const String &name); + ~D3D9MultiRenderTarget(); virtual void update(bool swapBuffers); - virtual void getCustomAttribute( const String& name, void *pData ); + virtual void getCustomAttribute( const String& name, void *pData ); - bool requiresTextureFlipping() const { return false; } - private: - D3D9HardwarePixelBuffer *mRenderTargets[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); - virtual void unbindSurfaceImpl(size_t attachment); + bool requiresTextureFlipping() const { return false; } + private: + D3D9HardwarePixelBuffer *mRenderTargets[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); + virtual void unbindSurfaceImpl(size_t attachment); - /** Check surfaces and update RenderTarget extent */ - void checkAndUpdate(); - }; + /** Check surfaces and update RenderTarget extent */ + void checkAndUpdate(); + }; }; #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9Plugin.h b/RenderSystems/Direct3D9/include/OgreD3D9Plugin.h index 4275cc67158..399b6ecadf7 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9Plugin.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9Plugin.h @@ -34,30 +34,30 @@ THE SOFTWARE. namespace Ogre { - /** Plugin instance for D3D9 Manager */ - class _OgreD3D9Export D3D9Plugin : public Plugin - { - public: - D3D9Plugin(); + /** Plugin instance for D3D9 Manager */ + class _OgreD3D9Export D3D9Plugin : public Plugin + { + public: + D3D9Plugin(); - /// @copydoc Plugin::getName - const String& getName() const; + /// @copydoc Plugin::getName + const String& getName() const; - /// @copydoc Plugin::install - void install(); + /// @copydoc Plugin::install + void install(); - /// @copydoc Plugin::initialise - void initialise(); + /// @copydoc Plugin::initialise + void initialise(); - /// @copydoc Plugin::shutdown - void shutdown(); + /// @copydoc Plugin::shutdown + void shutdown(); - /// @copydoc Plugin::uninstall - void uninstall(); - protected: - D3D9RenderSystem* mRenderSystem; - }; + /// @copydoc Plugin::uninstall + void uninstall(); + protected: + D3D9RenderSystem* mRenderSystem; + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9Prerequisites.h b/RenderSystems/Direct3D9/include/OgreD3D9Prerequisites.h index 5b55aa9e71f..49f0fe9df65 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9Prerequisites.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9Prerequisites.h @@ -44,11 +44,11 @@ THE SOFTWARE. #endif #if OGRE_THREAD_SUPPORT == 1 -# define D3D9_DEVICE_ACCESS_LOCK OGRE_LOCK_RECURSIVE_MUTEX(msDeviceAccessMutex); -# define D3D9_DEVICE_ACCESS_UNLOCK OGRE_UNLOCK_RECURSIVE_MUTEX(msDeviceAccessMutex); -# define D3D9_DEVICE_ACCESS_CRITICAL_SECTION OGRE_LOCK_MUTEX(msDeviceAccessMutex); +# define D3D9_DEVICE_ACCESS_LOCK OGRE_LOCK_RECURSIVE_MUTEX(msDeviceAccessMutex); +# define D3D9_DEVICE_ACCESS_UNLOCK OGRE_UNLOCK_RECURSIVE_MUTEX(msDeviceAccessMutex); +# define D3D9_DEVICE_ACCESS_CRITICAL_SECTION OGRE_LOCK_MUTEX(msDeviceAccessMutex); #else -# define D3D9_DEVICE_ACCESS_LOCK +# define D3D9_DEVICE_ACCESS_LOCK # define D3D9_DEVICE_ACCESS_UNLOCK # define D3D9_DEVICE_ACCESS_CRITICAL_SECTION #endif @@ -63,12 +63,12 @@ THE SOFTWARE. // enable extended d3d debug #if OGRE_DEBUG_MODE -# define D3D_DEBUG_INFO +# define D3D_DEBUG_INFO #endif #define WIN32_LEAN_AND_MEAN #if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min #endif #include #include @@ -77,24 +77,24 @@ THE SOFTWARE. namespace Ogre { - // Predefine classes - class D3D9DepthBuffer; - class D3D9RenderSystem; - class D3D9RenderWindow; - class D3D9Texture; - class D3D9TextureManager; - class D3D9Driver; - class D3D9DriverList; - class D3D9VideoMode; - class D3D9VideoModeList; - class D3D9GpuProgram; - class D3D9GpuProgramManager; + // Predefine classes + class D3D9DepthBuffer; + class D3D9RenderSystem; + class D3D9RenderWindow; + class D3D9Texture; + class D3D9TextureManager; + class D3D9Driver; + class D3D9DriverList; + class D3D9VideoMode; + class D3D9VideoModeList; + class D3D9GpuProgram; + class D3D9GpuProgramManager; class D3D9HardwareBufferManager; class D3D9HardwareIndexBuffer; class D3D9HLSLProgramFactory; class D3D9HLSLProgram; class D3D9VertexDeclaration; - class D3D9Resource; + class D3D9Resource; typedef SharedPtr D3D9GpuProgramPtr; typedef SharedPtr D3D9HLSLProgramPtr; @@ -106,20 +106,20 @@ namespace Ogre #define OGRE_D3D_MANAGE_BUFFERS 1 //------------------------------------------- - // Windows setttings - //------------------------------------------- + // Windows setttings + //------------------------------------------- #if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) && !defined(OGRE_STATIC_LIB) -# ifdef OGRED3DENGINEDLL_EXPORTS -# define _OgreD3D9Export __declspec(dllexport) -# else +# ifdef OGRED3DENGINEDLL_EXPORTS +# define _OgreD3D9Export __declspec(dllexport) +# else # if defined( __MINGW32__ ) # define _OgreD3D9Export # else -# define _OgreD3D9Export __declspec(dllimport) +# define _OgreD3D9Export __declspec(dllimport) # endif -# endif +# endif #else -# define _OgreD3D9Export -#endif // OGRE_WIN32 +# define _OgreD3D9Export +#endif // OGRE_WIN32 } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9RenderSystem.h b/RenderSystems/Direct3D9/include/OgreD3D9RenderSystem.h index b5cbb652278..cc00c082a0d 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9RenderSystem.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9RenderSystem.h @@ -39,278 +39,278 @@ namespace Ogre { #define MAX_LIGHTS 8 - class D3D9DriverList; - class D3D9Driver; - class D3D9Device; - class D3D9DeviceManager; - class D3D9ResourceManager; - - /** - Implementation of DirectX9 as a rendering system. - */ - class _OgreD3D9Export D3D9RenderSystem : public RenderSystem - { - public: - enum MultiheadUseType - { - mutAuto, - mutYes, - mutNo - }; - - private: - /// Direct3D - IDirect3D9* mD3D; - // Stored options - ConfigOptionMap mOptions; - size_t mFSAASamples; - String mFSAAHint; - - /// instance - HINSTANCE mhInstance; - - /// List of D3D drivers installed (video cards) - D3D9DriverList* mDriverList; - /// Currently active driver - D3D9Driver* mActiveD3DDriver; - /// NVPerfHUD allowed? - bool mUseNVPerfHUD; - /// Per-stage constant support? (not in main caps since D3D specific & minor) - bool mPerStageConstantSupport; - /// Fast singleton access. - static D3D9RenderSystem* msD3D9RenderSystem; - /// Tells whether to attempt to initialize the system with DirectX 9Ex driver - /// Read more in http://msdn.microsoft.com/en-us/library/windows/desktop/ee890072(v=vs.85).aspx - bool mAllowDirectX9Ex; - /// Tells whether the system is initialized with DirectX 9Ex driver - /// Read more in http://msdn.microsoft.com/en-us/library/windows/desktop/ee890072(v=vs.85).aspx - bool mIsDirectX9Ex; - - /// structure holding texture unit settings for every stage - struct sD3DTextureStageDesc - { - /// the type of the texture - D3D9Mappings::eD3DTexType texType; - /// which texCoordIndex to use - size_t coordIndex; - /// type of auto tex. calc. used - TexCoordCalcMethod autoTexCoordType; + class D3D9DriverList; + class D3D9Driver; + class D3D9Device; + class D3D9DeviceManager; + class D3D9ResourceManager; + + /** + Implementation of DirectX9 as a rendering system. + */ + class _OgreD3D9Export D3D9RenderSystem : public RenderSystem + { + public: + enum MultiheadUseType + { + mutAuto, + mutYes, + mutNo + }; + + private: + /// Direct3D + IDirect3D9* mD3D; + // Stored options + ConfigOptionMap mOptions; + size_t mFSAASamples; + String mFSAAHint; + + /// instance + HINSTANCE mhInstance; + + /// List of D3D drivers installed (video cards) + D3D9DriverList* mDriverList; + /// Currently active driver + D3D9Driver* mActiveD3DDriver; + /// NVPerfHUD allowed? + bool mUseNVPerfHUD; + /// Per-stage constant support? (not in main caps since D3D specific & minor) + bool mPerStageConstantSupport; + /// Fast singleton access. + static D3D9RenderSystem* msD3D9RenderSystem; + /// Tells whether to attempt to initialize the system with DirectX 9Ex driver + /// Read more in http://msdn.microsoft.com/en-us/library/windows/desktop/ee890072(v=vs.85).aspx + bool mAllowDirectX9Ex; + /// Tells whether the system is initialized with DirectX 9Ex driver + /// Read more in http://msdn.microsoft.com/en-us/library/windows/desktop/ee890072(v=vs.85).aspx + bool mIsDirectX9Ex; + + /// structure holding texture unit settings for every stage + struct sD3DTextureStageDesc + { + /// the type of the texture + D3D9Mappings::eD3DTexType texType; + /// which texCoordIndex to use + size_t coordIndex; + /// type of auto tex. calc. used + TexCoordCalcMethod autoTexCoordType; /// Frustum, used if the above is projection const Frustum *frustum; - /// texture - IDirect3DBaseTexture9 *pTex; - /// vertex texture - IDirect3DBaseTexture9 *pVertexTex; - } mTexStageDesc[OGRE_MAX_TEXTURE_LAYERS]; - - // Array of up to 8 lights, indexed as per API - // Note that a null value indicates a free slot - Light* mLights[MAX_LIGHTS]; - D3D9DriverList* getDirect3DDrivers(); - void refreshD3DSettings(); + /// texture + IDirect3DBaseTexture9 *pTex; + /// vertex texture + IDirect3DBaseTexture9 *pVertexTex; + } mTexStageDesc[OGRE_MAX_TEXTURE_LAYERS]; + + // Array of up to 8 lights, indexed as per API + // Note that a null value indicates a free slot + Light* mLights[MAX_LIGHTS]; + D3D9DriverList* getDirect3DDrivers(); + void refreshD3DSettings(); void refreshFSAAOptions(); - - void setD3D9Light( size_t index, Light* light ); - - // state management methods, very primitive !!! - HRESULT __SetRenderState(D3DRENDERSTATETYPE state, DWORD value); - HRESULT __SetSamplerState(DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value); - HRESULT __SetTextureStageState(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value); - - HRESULT __SetFloatRenderState(D3DRENDERSTATETYPE state, Real value) - { + + void setD3D9Light( size_t index, Light* light ); + + // state management methods, very primitive !!! + HRESULT __SetRenderState(D3DRENDERSTATETYPE state, DWORD value); + HRESULT __SetSamplerState(DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value); + HRESULT __SetTextureStageState(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value); + + HRESULT __SetFloatRenderState(D3DRENDERSTATETYPE state, Real value) + { #if OGRE_DOUBLE_PRECISION == 1 - float temp = static_cast(value); - return __SetRenderState(state, *((LPDWORD)(&temp))); + float temp = static_cast(value); + return __SetRenderState(state, *((LPDWORD)(&temp))); #else - return __SetRenderState(state, *((LPDWORD)(&value))); + return __SetRenderState(state, *((LPDWORD)(&value))); #endif - } - - /// return anisotropy level - DWORD _getCurrentAnisotropy(size_t unit); - /// check if a FSAA is supported - bool _checkMultiSampleQuality(D3DMULTISAMPLE_TYPE type, DWORD *outQuality, D3DFORMAT format, UINT adapterNum, D3DDEVTYPE deviceType, BOOL fullScreen); - - D3D9HardwareBufferManager* mHardwareBufferManager; - D3D9GpuProgramManager* mGpuProgramManager; + } + + /// return anisotropy level + DWORD _getCurrentAnisotropy(size_t unit); + /// check if a FSAA is supported + bool _checkMultiSampleQuality(D3DMULTISAMPLE_TYPE type, DWORD *outQuality, D3DFORMAT format, UINT adapterNum, D3DDEVTYPE deviceType, BOOL fullScreen); + + D3D9HardwareBufferManager* mHardwareBufferManager; + D3D9GpuProgramManager* mGpuProgramManager; D3D9HLSLProgramFactory* mHLSLProgramFactory; - D3D9ResourceManager* mResourceManager; - D3D9DeviceManager* mDeviceManager; + D3D9ResourceManager* mResourceManager; + D3D9DeviceManager* mDeviceManager; - size_t mLastVertexSourceCount; + size_t mLastVertexSourceCount; /// Internal method for populating the capabilities structure - virtual RenderSystemCapabilities* createRenderSystemCapabilities() const; - RenderSystemCapabilities* updateRenderSystemCapabilities(D3D9RenderWindow* renderWindow); + virtual RenderSystemCapabilities* createRenderSystemCapabilities() const; + RenderSystemCapabilities* updateRenderSystemCapabilities(D3D9RenderWindow* renderWindow); - /** See RenderSystem definition */ - virtual void initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary); + /** See RenderSystem definition */ + virtual void initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary); void convertVertexShaderCaps(RenderSystemCapabilities* rsc) const; void convertPixelShaderCaps(RenderSystemCapabilities* rsc) const; - bool checkVertexTextureFormats(D3D9RenderWindow* renderWindow) const; - void detachRenderTargetImpl(const String& name); - + bool checkVertexTextureFormats(D3D9RenderWindow* renderWindow) const; + void detachRenderTargetImpl(const String& name); + HashMap mCurrentLights; /// Saved last view matrix Matrix4 mViewMatrix; - D3DXMATRIX mDxViewMat, mDxProjMat, mDxWorldMat; - - typedef vector::type D3D9RenderWindowList; - // List of additional windows after the first (swap chains) - D3D9RenderWindowList mRenderWindows; - - /** Mapping of texture format -> DepthStencil. Used as cache by _getDepthStencilFormatFor - */ - typedef HashMap DepthStencilHash; - DepthStencilHash mDepthStencilHash; - - MultiheadUseType mMultiheadUse; - - protected: - void setClipPlanesImpl(const PlaneList& clipPlanes); - public: - // constructor - D3D9RenderSystem( HINSTANCE hInstance ); - // destructor - ~D3D9RenderSystem(); - - virtual void initConfigOptions(); - - // Overridden RenderSystem functions - ConfigOptionMap& getConfigOptions(); - String validateConfigOptions(); - RenderWindow* _initialise( bool autoCreateWindow, const String& windowTitle = "OGRE Render Window" ); - /// @copydoc RenderSystem::_createRenderWindow - RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0); - - /// @copydoc RenderSystem::_createRenderWindows - bool _createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, - RenderWindowList& createdWindows); - - /// @copydoc RenderSystem::_createDepthBufferFor - DepthBuffer* _createDepthBufferFor( RenderTarget *renderTarget ); - - /** - * This function is meant to add Depth Buffers to the pool that aren't released when the DepthBuffer - * is deleted. This is specially useful to put the Depth Buffer created along with the window's - * back buffer into the pool. All depth buffers introduced with this method go to POOL_DEFAULT - */ - DepthBuffer* _addManualDepthBuffer( IDirect3DDevice9* depthSurfaceDevice, IDirect3DSurface9 *surf ); - - /** - * This function does NOT override RenderSystem::_cleanupDepthBuffers(bool) functionality. - * On multi monitor setups, when a device becomes "inactive" (it has no RenderWindows; like - * when the window was moved from one monitor to another); the Device will be destroyed, - * meaning all it's depth buffers (auto & manual) should be removed from the pool, - * but only selectively removing those created by that D3D9Device. - * @param: - * Creator device to compare against. Shouldn't be null - */ - using RenderSystem::_cleanupDepthBuffers; - void _cleanupDepthBuffers( IDirect3DDevice9 *creator ); - - /** - * This function does NOT override RenderSystem::_cleanupDepthBuffers(bool) functionality. - * Manually created surfaces may be released arbitrarely without being pulled out from the pool - * (specially RenderWindows) this function takes care of that. - * @param manualSurface - * Depth buffer surface to compare against. Shouldn't be null - */ - void _cleanupDepthBuffers( IDirect3DSurface9 *manualSurface ); - - /** + D3DXMATRIX mDxViewMat, mDxProjMat, mDxWorldMat; + + typedef vector::type D3D9RenderWindowList; + // List of additional windows after the first (swap chains) + D3D9RenderWindowList mRenderWindows; + + /** Mapping of texture format -> DepthStencil. Used as cache by _getDepthStencilFormatFor + */ + typedef HashMap DepthStencilHash; + DepthStencilHash mDepthStencilHash; + + MultiheadUseType mMultiheadUse; + + protected: + void setClipPlanesImpl(const PlaneList& clipPlanes); + public: + // constructor + D3D9RenderSystem( HINSTANCE hInstance ); + // destructor + ~D3D9RenderSystem(); + + virtual void initConfigOptions(); + + // Overridden RenderSystem functions + ConfigOptionMap& getConfigOptions(); + String validateConfigOptions(); + RenderWindow* _initialise( bool autoCreateWindow, const String& windowTitle = "OGRE Render Window" ); + /// @copydoc RenderSystem::_createRenderWindow + RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0); + + /// @copydoc RenderSystem::_createRenderWindows + bool _createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, + RenderWindowList& createdWindows); + + /// @copydoc RenderSystem::_createDepthBufferFor + DepthBuffer* _createDepthBufferFor( RenderTarget *renderTarget ); + + /** + * This function is meant to add Depth Buffers to the pool that aren't released when the DepthBuffer + * is deleted. This is specially useful to put the Depth Buffer created along with the window's + * back buffer into the pool. All depth buffers introduced with this method go to POOL_DEFAULT + */ + DepthBuffer* _addManualDepthBuffer( IDirect3DDevice9* depthSurfaceDevice, IDirect3DSurface9 *surf ); + + /** + * This function does NOT override RenderSystem::_cleanupDepthBuffers(bool) functionality. + * On multi monitor setups, when a device becomes "inactive" (it has no RenderWindows; like + * when the window was moved from one monitor to another); the Device will be destroyed, + * meaning all it's depth buffers (auto & manual) should be removed from the pool, + * but only selectively removing those created by that D3D9Device. + * @param: + * Creator device to compare against. Shouldn't be null + */ + using RenderSystem::_cleanupDepthBuffers; + void _cleanupDepthBuffers( IDirect3DDevice9 *creator ); + + /** + * This function does NOT override RenderSystem::_cleanupDepthBuffers(bool) functionality. + * Manually created surfaces may be released arbitrarely without being pulled out from the pool + * (specially RenderWindows) this function takes care of that. + * @param manualSurface + * Depth buffer surface to compare against. Shouldn't be null + */ + void _cleanupDepthBuffers( IDirect3DSurface9 *manualSurface ); + + /** * Set current render target to target, enabling its GL context if needed */ - void _setRenderTarget(RenderTarget *target); - - /// @copydoc RenderSystem::createMultiRenderTarget - virtual MultiRenderTarget * createMultiRenderTarget(const String & name); - - /// @copydoc RenderSystem::detachRenderTarget - virtual RenderTarget * detachRenderTarget(const String &name); - - String getErrorDescription( long errorNumber ) const; - const String& getName() const; - // Low-level overridden members - void setConfigOption( const String &name, const String &value ); - void reinitialise(); - void shutdown(); - void setAmbientLight( float r, float g, float b ); - void setShadingType( ShadeOptions so ); - void setLightingEnabled( bool enabled ); - void destroyRenderTarget(const String& name); - VertexElementType getColourVertexElementType() const; - void setStencilCheckEnabled(bool enabled); + void _setRenderTarget(RenderTarget *target); + + /// @copydoc RenderSystem::createMultiRenderTarget + virtual MultiRenderTarget * createMultiRenderTarget(const String & name); + + /// @copydoc RenderSystem::detachRenderTarget + virtual RenderTarget * detachRenderTarget(const String &name); + + String getErrorDescription( long errorNumber ) const; + const String& getName() const; + // Low-level overridden members + void setConfigOption( const String &name, const String &value ); + void reinitialise(); + void shutdown(); + void setAmbientLight( float r, float g, float b ); + void setShadingType( ShadeOptions so ); + void setLightingEnabled( bool enabled ); + void destroyRenderTarget(const String& name); + VertexElementType getColourVertexElementType() const; + void setStencilCheckEnabled(bool enabled); void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, uint32 refValue = 0, uint32 compareMask = 0xFFFFFFFF, uint32 writeMask = 0xFFFFFFFF, StencilOperation stencilFailOp = SOP_KEEP, StencilOperation depthFailOp = SOP_KEEP, StencilOperation passOp = SOP_KEEP, - bool twoSidedOperation = false, - bool readBackAsTexture = false); + bool twoSidedOperation = false, + bool readBackAsTexture = false); void setNormaliseNormals(bool normalise); - // Low-level overridden members, mainly for internal use + // Low-level overridden members, mainly for internal use void _useLights(const LightList& lights, unsigned short limit); - void _setWorldMatrix( const Matrix4 &m ); - void _setViewMatrix( const Matrix4 &m ); - void _setProjectionMatrix( const Matrix4 &m ); - void _setSurfaceParams( const ColourValue &ambient, const ColourValue &diffuse, const ColourValue &specular, const ColourValue &emissive, Real shininess, TrackVertexColourType tracking ); - void _setPointSpritesEnabled(bool enabled); - void _setPointParameters(Real size, bool attenuationEnabled, - Real constant, Real linear, Real quadratic, Real minSize, Real maxSize); - void _setTexture(size_t unit, bool enabled, const TexturePtr &texPtr); - void _setVertexTexture(size_t unit, const TexturePtr& tex); - void _disableTextureUnit(size_t texUnit); - void _setTextureCoordSet( size_t unit, size_t index ); + void _setWorldMatrix( const Matrix4 &m ); + void _setViewMatrix( const Matrix4 &m ); + void _setProjectionMatrix( const Matrix4 &m ); + void _setSurfaceParams( const ColourValue &ambient, const ColourValue &diffuse, const ColourValue &specular, const ColourValue &emissive, Real shininess, TrackVertexColourType tracking ); + void _setPointSpritesEnabled(bool enabled); + void _setPointParameters(Real size, bool attenuationEnabled, + Real constant, Real linear, Real quadratic, Real minSize, Real maxSize); + void _setTexture(size_t unit, bool enabled, const TexturePtr &texPtr); + void _setVertexTexture(size_t unit, const TexturePtr& tex); + void _disableTextureUnit(size_t texUnit); + void _setTextureCoordSet( size_t unit, size_t index ); void _setTextureCoordCalculation(size_t unit, TexCoordCalcMethod m, const Frustum* frustum = 0); - void _setTextureBlendMode( size_t unit, const LayerBlendModeEx& bm ); + void _setTextureBlendMode( size_t unit, const LayerBlendModeEx& bm ); void _setTextureAddressingMode(size_t stage, const TextureUnitState::UVWAddressingMode& uvw); void _setTextureBorderColour(size_t stage, const ColourValue& colour); - void _setTextureMipmapBias(size_t unit, float bias); - void _setTextureMatrix( size_t unit, const Matrix4 &xform ); - void _setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op ); - void _setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ); - void _setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ); - void _setViewport( Viewport *vp ); - void _beginFrame(); - virtual RenderSystemContext* _pauseFrame(void); - virtual void _resumeFrame(RenderSystemContext* context); - void _endFrame(); - void _setCullingMode( CullingMode mode ); - void _setDepthBufferParams( bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL ); - void _setDepthBufferCheckEnabled( bool enabled = true ); - void _setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha); - void _setDepthBufferWriteEnabled(bool enabled = true); - void _setDepthBufferFunction( CompareFunction func = CMPF_LESS_EQUAL ); - void _setDepthBias(float constantBias, float slopeScaleBias); - void _setFog( FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 1.0, Real linearStart = 0.0, Real linearEnd = 1.0 ); - void _convertProjectionMatrix(const Matrix4& matrix, + void _setTextureMipmapBias(size_t unit, float bias); + void _setTextureMatrix( size_t unit, const Matrix4 &xform ); + void _setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op ); + void _setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ); + void _setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ); + void _setViewport( Viewport *vp ); + void _beginFrame(); + virtual RenderSystemContext* _pauseFrame(void); + virtual void _resumeFrame(RenderSystemContext* context); + void _endFrame(); + void _setCullingMode( CullingMode mode ); + void _setDepthBufferParams( bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL ); + void _setDepthBufferCheckEnabled( bool enabled = true ); + void _setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha); + void _setDepthBufferWriteEnabled(bool enabled = true); + void _setDepthBufferFunction( CompareFunction func = CMPF_LESS_EQUAL ); + void _setDepthBias(float constantBias, float slopeScaleBias); + void _setFog( FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 1.0, Real linearStart = 0.0, Real linearEnd = 1.0 ); + void _convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram = false); - void _makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, + void _makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram = false); - void _makeProjectionMatrix(Real left, Real right, Real bottom, Real top, Real nearPlane, + void _makeProjectionMatrix(Real left, Real right, Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram = false); - void _makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, + void _makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram = false); void _applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane, bool forGpuProgram); - void _setPolygonMode(PolygonMode level); + void _setPolygonMode(PolygonMode level); void _setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions filter); - void _setTextureUnitCompareFunction(size_t unit, CompareFunction function); - void _setTextureUnitCompareEnabled(size_t unit, bool compare); - void _setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy); - void setVertexDeclaration(VertexDeclaration* decl); - void setVertexDeclaration(VertexDeclaration* decl, bool useGlobalInstancingVertexBufferIsAvailable); - void setVertexBufferBinding(VertexBufferBinding* binding); - void setVertexBufferBinding(VertexBufferBinding* binding, size_t numberOfInstances, bool useGlobalInstancingVertexBufferIsAvailable, bool indexesUsed); + void _setTextureUnitCompareFunction(size_t unit, CompareFunction function); + void _setTextureUnitCompareEnabled(size_t unit, bool compare); + void _setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy); + void setVertexDeclaration(VertexDeclaration* decl); + void setVertexDeclaration(VertexDeclaration* decl, bool useGlobalInstancingVertexBufferIsAvailable); + void setVertexBufferBinding(VertexBufferBinding* binding); + void setVertexBufferBinding(VertexBufferBinding* binding, size_t numberOfInstances, bool useGlobalInstancingVertexBufferIsAvailable, bool indexesUsed); void _render(const RenderOperation& op); /** See RenderSystem @@ -323,89 +323,89 @@ namespace Ogre /** See RenderSystem */ - void bindGpuProgramParameters(GpuProgramType gptype, - GpuProgramParametersSharedPtr params, uint16 variabilityMask); + void bindGpuProgramParameters(GpuProgramType gptype, + GpuProgramParametersSharedPtr params, uint16 variabilityMask); void bindGpuProgramPassIterationParameters(GpuProgramType gptype); void setScissorTest(bool enabled, size_t left = 0, size_t top = 0, size_t right = 800, size_t bottom = 600); void clearFrameBuffer(unsigned int buffers, const ColourValue& colour = ColourValue::Black, Real depth = 1.0f, unsigned short stencil = 0); - void setClipPlane (ushort index, Real A, Real B, Real C, Real D); - void enableClipPlane (ushort index, bool enable); + void setClipPlane (ushort index, Real A, Real B, Real C, Real D); + void enableClipPlane (ushort index, bool enable); HardwareOcclusionQuery* createHardwareOcclusionQuery(); Real getHorizontalTexelOffset(); Real getVerticalTexelOffset(); Real getMinimumDepthInputValue(); Real getMaximumDepthInputValue(); - void registerThread(); - void unregisterThread(); - void preExtraThreadsStarted(); - void postExtraThreadsStarted(); - - /* - Returns whether under the current render system buffers marked as TU_STATIC can be locked for update - */ - virtual bool isStaticBufferLockable() const { return !mIsDirectX9Ex; } - - /// Tells whether the system is initialized with DirectX 9Ex driver - /// Read more in http://msdn.microsoft.com/en-us/library/windows/desktop/ee890072(v=vs.85).aspx - static bool isDirectX9Ex() { return msD3D9RenderSystem->mIsDirectX9Ex; } - - static D3D9ResourceManager* getResourceManager(); - static D3D9DeviceManager* getDeviceManager(); - static IDirect3D9* getDirect3D9(); - static UINT getResourceCreationDeviceCount(); - static IDirect3DDevice9* getResourceCreationDevice(UINT index); - static IDirect3DDevice9* getActiveD3D9Device(); - static IDirect3DDevice9* getActiveD3D9DeviceIfExists(); - - /** Check which depthStencil formats can be used with a certain pixel format, - and return the best suited. - */ - D3DFORMAT _getDepthStencilFormatFor(D3DFORMAT fmt); + void registerThread(); + void unregisterThread(); + void preExtraThreadsStarted(); + void postExtraThreadsStarted(); + + /* + Returns whether under the current render system buffers marked as TU_STATIC can be locked for update + */ + virtual bool isStaticBufferLockable() const { return !mIsDirectX9Ex; } + + /// Tells whether the system is initialized with DirectX 9Ex driver + /// Read more in http://msdn.microsoft.com/en-us/library/windows/desktop/ee890072(v=vs.85).aspx + static bool isDirectX9Ex() { return msD3D9RenderSystem->mIsDirectX9Ex; } + + static D3D9ResourceManager* getResourceManager(); + static D3D9DeviceManager* getDeviceManager(); + static IDirect3D9* getDirect3D9(); + static UINT getResourceCreationDeviceCount(); + static IDirect3DDevice9* getResourceCreationDevice(UINT index); + static IDirect3DDevice9* getActiveD3D9Device(); + static IDirect3DDevice9* getActiveD3D9DeviceIfExists(); + + /** Check which depthStencil formats can be used with a certain pixel format, + and return the best suited. + */ + D3DFORMAT _getDepthStencilFormatFor(D3DFORMAT fmt); /** Check whether or not filtering is supported for the precise texture format requested with the given usage options. */ bool _checkTextureFilteringSupported(TextureType ttype, PixelFormat format, int usage); - /// Take in some requested FSAA settings and output supported D3D settings - void determineFSAASettings(IDirect3DDevice9* d3d9Device, size_t fsaa, const String& fsaaHint, D3DFORMAT d3dPixelFormat, - bool fullScreen, D3DMULTISAMPLE_TYPE *outMultisampleType, DWORD *outMultisampleQuality); + /// Take in some requested FSAA settings and output supported D3D settings + void determineFSAASettings(IDirect3DDevice9* d3d9Device, size_t fsaa, const String& fsaaHint, D3DFORMAT d3dPixelFormat, + bool fullScreen, D3DMULTISAMPLE_TYPE *outMultisampleType, DWORD *outMultisampleQuality); - /// @copydoc RenderSystem::getDisplayMonitorCount - unsigned int getDisplayMonitorCount() const; - /// @copydoc RenderSystem::hasAnisotropicMipMapFilter - virtual bool hasAnisotropicMipMapFilter() const { return false; } + /// @copydoc RenderSystem::getDisplayMonitorCount + unsigned int getDisplayMonitorCount() const; + /// @copydoc RenderSystem::hasAnisotropicMipMapFilter + virtual bool hasAnisotropicMipMapFilter() const { return false; } - /// @copydoc RenderSystem::beginProfileEvent + /// @copydoc RenderSystem::beginProfileEvent virtual void beginProfileEvent( const String &eventName ); - /// @copydoc RenderSystem::endProfileEvent + /// @copydoc RenderSystem::endProfileEvent virtual void endProfileEvent( void ); - /// @copydoc RenderSystem::markProfileEvent + /// @copydoc RenderSystem::markProfileEvent virtual void markProfileEvent( const String &eventName ); - - /// Fires a device related event - void fireDeviceEvent( D3D9Device* device, const String & name ); - - /// Returns how multihead should be activated - MultiheadUseType getMultiheadUse() const { return mMultiheadUse; } - protected: - /// Returns the sampler id for a given unit texture number - DWORD getSamplerId(size_t unit); - - /// Notify when a device has been lost. - void notifyOnDeviceLost(D3D9Device* device); - - /// Notify when a device has been reset. - void notifyOnDeviceReset(D3D9Device* device); - - private: - friend class D3D9Device; - friend class D3D9DeviceManager; - }; + + /// Fires a device related event + void fireDeviceEvent( D3D9Device* device, const String & name ); + + /// Returns how multihead should be activated + MultiheadUseType getMultiheadUse() const { return mMultiheadUse; } + protected: + /// Returns the sampler id for a given unit texture number + DWORD getSamplerId(size_t unit); + + /// Notify when a device has been lost. + void notifyOnDeviceLost(D3D9Device* device); + + /// Notify when a device has been reset. + void notifyOnDeviceReset(D3D9Device* device); + + private: + friend class D3D9Device; + friend class D3D9DeviceManager; + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9RenderWindow.h b/RenderSystems/Direct3D9/include/OgreD3D9RenderWindow.h index a5dfe203a1e..ec239fca8c8 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9RenderWindow.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9RenderWindow.h @@ -34,111 +34,111 @@ THE SOFTWARE. namespace Ogre { - class _OgreD3D9Export D3D9RenderWindow : public RenderWindow - { - public: - /** Constructor. - @param instance The application instance - */ - D3D9RenderWindow (HINSTANCE instance); - ~D3D9RenderWindow (); - - void create (const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams); - void setFullscreen (bool fullScreen, unsigned int width, unsigned int height); - void destroy (void); - bool isActive () const; - bool isVisible () const; - bool isClosed () const { return mClosed; } - bool isVSync () const { return mVSync; } - bool isAA () const { return mFSAA != 0; } - bool isHidden () const { return mHidden; } - void setHidden (bool hidden); - void setVSyncEnabled (bool vsync); - bool isVSyncEnabled () const; - void setVSyncInterval (unsigned int interval); - unsigned int getVSyncInterval () const; - void reposition (int left, int top); - void resize (unsigned int width, unsigned int height); - void swapBuffers (); - HWND getWindowHandle () const { return mHWnd; } - IDirect3DDevice9* getD3D9Device (); - D3D9Device* getDevice (); - void setDevice (D3D9Device* device); - - void getCustomAttribute (const String& name, void* pData); - - /** Overridden - see RenderTarget. - */ - void copyContentsToMemory (const PixelBox &dst, FrameBuffer buffer); - bool requiresTextureFlipping () const { return false; } - - // Method for dealing with resize / move & 3d library - void windowMovedOrResized (); - - /// Build the presentation parameters used with this window - void buildPresentParameters (D3DPRESENT_PARAMETERS* presentParams); - - - /// @copydoc RenderTarget::_beginUpdate - void _beginUpdate(); - - /// @copydoc RenderTarget::_updateViewport(Viewport* viewport, bool updateStatistics) - void _updateViewport(Viewport* viewport, bool updateStatistics = true); - - /// @copydoc RenderTarget::_endUpdate - void _endUpdate(); - - /// Accessor for render surface - IDirect3DSurface9* getRenderSurface(); - - /// Are we in the middle of switching between fullscreen and windowed - bool _getSwitchingFullscreen() const; - - /// Indicate that fullscreen / windowed switching has finished - void _finishSwitchingFullscreen(); - - /// Returns true if this window use depth buffer. - bool isDepthBuffered() const; - - /// Returns true if this window should use NV Perf HUD adapter. - bool isNvPerfHUDEnable() const; - - /** Validate the device for this window. */ - bool _validateDevice(); - - void adjustWindow(unsigned int clientWidth, unsigned int clientHeight, - unsigned int* winWidth, unsigned int* winHeight); - - protected: - /** Update the window rect. */ - void updateWindowRect(); - - /** Return the target window style depending on the fullscreen parameter. */ - DWORD getWindowStyle(bool fullScreen) const { if (fullScreen) return mFullscreenWinStyle; return mWindowedWinStyle; } - - // Overridden see RenderTarget - virtual void updateStats(void); - - protected: - HINSTANCE mInstance; // Process instance - D3D9Device* mDevice; // D3D9 device wrapper class. - bool mDeviceValid; // Device was validation succeeded. - HWND mHWnd; // Win32 Window handle - bool mIsExternal; // window not created by Ogre - bool mClosed; // Is this window destroyed. - bool mHidden; // True if this is hidden render window. - bool mSwitchingFullscreen; // Are we switching from fullscreen to windowed or vice versa - D3DMULTISAMPLE_TYPE mFSAAType; // AA type. - DWORD mFSAAQuality; // AA quality. - UINT mDisplayFrequency; // Display frequency. - bool mVSync; // Use vertical sync or not. - unsigned int mVSyncInterval; // The vsync interval. - bool mUseNVPerfHUD; // Use NV Perf HUD. - DWORD mWindowedWinStyle; // Windowed mode window style flags. - DWORD mFullscreenWinStyle; // Fullscreen mode window style flags. - unsigned int mDesiredWidth; // Desired width after resizing - unsigned int mDesiredHeight; // Desired height after resizing - }; + class _OgreD3D9Export D3D9RenderWindow : public RenderWindow + { + public: + /** Constructor. + @param instance The application instance + */ + D3D9RenderWindow (HINSTANCE instance); + ~D3D9RenderWindow (); + + void create (const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams); + void setFullscreen (bool fullScreen, unsigned int width, unsigned int height); + void destroy (void); + bool isActive () const; + bool isVisible () const; + bool isClosed () const { return mClosed; } + bool isVSync () const { return mVSync; } + bool isAA () const { return mFSAA != 0; } + bool isHidden () const { return mHidden; } + void setHidden (bool hidden); + void setVSyncEnabled (bool vsync); + bool isVSyncEnabled () const; + void setVSyncInterval (unsigned int interval); + unsigned int getVSyncInterval () const; + void reposition (int left, int top); + void resize (unsigned int width, unsigned int height); + void swapBuffers (); + HWND getWindowHandle () const { return mHWnd; } + IDirect3DDevice9* getD3D9Device (); + D3D9Device* getDevice (); + void setDevice (D3D9Device* device); + + void getCustomAttribute (const String& name, void* pData); + + /** Overridden - see RenderTarget. + */ + void copyContentsToMemory (const PixelBox &dst, FrameBuffer buffer); + bool requiresTextureFlipping () const { return false; } + + // Method for dealing with resize / move & 3d library + void windowMovedOrResized (); + + /// Build the presentation parameters used with this window + void buildPresentParameters (D3DPRESENT_PARAMETERS* presentParams); + + + /// @copydoc RenderTarget::_beginUpdate + void _beginUpdate(); + + /// @copydoc RenderTarget::_updateViewport(Viewport* viewport, bool updateStatistics) + void _updateViewport(Viewport* viewport, bool updateStatistics = true); + + /// @copydoc RenderTarget::_endUpdate + void _endUpdate(); + + /// Accessor for render surface + IDirect3DSurface9* getRenderSurface(); + + /// Are we in the middle of switching between fullscreen and windowed + bool _getSwitchingFullscreen() const; + + /// Indicate that fullscreen / windowed switching has finished + void _finishSwitchingFullscreen(); + + /// Returns true if this window use depth buffer. + bool isDepthBuffered() const; + + /// Returns true if this window should use NV Perf HUD adapter. + bool isNvPerfHUDEnable() const; + + /** Validate the device for this window. */ + bool _validateDevice(); + + void adjustWindow(unsigned int clientWidth, unsigned int clientHeight, + unsigned int* winWidth, unsigned int* winHeight); + + protected: + /** Update the window rect. */ + void updateWindowRect(); + + /** Return the target window style depending on the fullscreen parameter. */ + DWORD getWindowStyle(bool fullScreen) const { if (fullScreen) return mFullscreenWinStyle; return mWindowedWinStyle; } + + // Overridden see RenderTarget + virtual void updateStats(void); + + protected: + HINSTANCE mInstance; // Process instance + D3D9Device* mDevice; // D3D9 device wrapper class. + bool mDeviceValid; // Device was validation succeeded. + HWND mHWnd; // Win32 Window handle + bool mIsExternal; // window not created by Ogre + bool mClosed; // Is this window destroyed. + bool mHidden; // True if this is hidden render window. + bool mSwitchingFullscreen; // Are we switching from fullscreen to windowed or vice versa + D3DMULTISAMPLE_TYPE mFSAAType; // AA type. + DWORD mFSAAQuality; // AA quality. + UINT mDisplayFrequency; // Display frequency. + bool mVSync; // Use vertical sync or not. + unsigned int mVSyncInterval; // The vsync interval. + bool mUseNVPerfHUD; // Use NV Perf HUD. + DWORD mWindowedWinStyle; // Windowed mode window style flags. + DWORD mFullscreenWinStyle; // Fullscreen mode window style flags. + unsigned int mDesiredWidth; // Desired width after resizing + unsigned int mDesiredHeight; // Desired height after resizing + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9Resource.h b/RenderSystems/Direct3D9/include/OgreD3D9Resource.h index d641d2d0d23..143becdb472 100755 --- a/RenderSystems/Direct3D9/include/OgreD3D9Resource.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9Resource.h @@ -33,45 +33,45 @@ THE SOFTWARE. namespace Ogre { - /** Represents a Direct3D rendering resource. - Provide unified interface to - handle various device states. - */ - class _OgreD3D9Export D3D9Resource - { + /** Represents a Direct3D rendering resource. + Provide unified interface to + handle various device states. + */ + class _OgreD3D9Export D3D9Resource + { - // Interface. - public: + // Interface. + public: - // Called immediately after the Direct3D device has been created. - virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) {} + // Called immediately after the Direct3D device has been created. + virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) {} - // Called before the Direct3D device is going to be destroyed. - virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) {} + // Called before the Direct3D device is going to be destroyed. + virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) {} - // Called immediately after the Direct3D device has entered a lost state. - // This is the place to release non-managed resources. - virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) {} + // Called immediately after the Direct3D device has entered a lost state. + // This is the place to release non-managed resources. + virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) {} - // Called immediately after the Direct3D device has been reset. - // This is the place to create non-managed resources. - virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) {} + // Called immediately after the Direct3D device has been reset. + // This is the place to create non-managed resources. + virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) {} - // Called when device state is changing. Access to any device should be locked. - // Relevant for multi thread application. - static void lockDeviceAccess(); + // Called when device state is changing. Access to any device should be locked. + // Relevant for multi thread application. + static void lockDeviceAccess(); - // Called when device state change completed. Access to any device is allowed. - // Relevant for multi thread application. - static void unlockDeviceAccess(); + // Called when device state change completed. Access to any device is allowed. + // Relevant for multi thread application. + static void unlockDeviceAccess(); - public: - D3D9Resource (); - virtual ~D3D9Resource (); + public: + D3D9Resource (); + virtual ~D3D9Resource (); - protected: - OGRE_STATIC_MUTEX(msDeviceAccessMutex); - }; + protected: + OGRE_STATIC_MUTEX(msDeviceAccessMutex); + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9ResourceManager.h b/RenderSystems/Direct3D9/include/OgreD3D9ResourceManager.h index 626515a430c..62b2cbc275b 100755 --- a/RenderSystems/Direct3D9/include/OgreD3D9ResourceManager.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9ResourceManager.h @@ -32,93 +32,93 @@ THE SOFTWARE. namespace Ogre { - enum D3D9ResourceCreationPolicy - { - // Creates the rendering resource on the current active device that needs it. - // This policy should be used when video memory consumption should be minimized but - // it might cause some performance issues when using loader resource thread since - // a resource that was not created on specified device will be created on demand during - // the rendering process and might cause the FPS to drop down. - RCP_CREATE_ON_ACTIVE_DEVICE, - - // Create the rendering resource on every existing device. - // This policy should be used when working intensively with a background loader thread. - // In that case when multiple devices exist, the resource will be created on each device - // and will be ready to use in the rendering thread. - // The draw back can be some video memory waste in case that each device render different - // scene and doesn't really need all the resources. - RCP_CREATE_ON_ALL_DEVICES - }; - - class _OgreD3D9Export D3D9ResourceManager : public ResourceAlloc - { - - // Interface. - public: - - // Called immediately after the Direct3D device has been created. - void notifyOnDeviceCreate (IDirect3DDevice9* d3d9Device); - - // Called before the Direct3D device is going to be destroyed. - void notifyOnDeviceDestroy (IDirect3DDevice9* d3d9Device); - - // Called immediately after the Direct3D device has entered a lost state. - void notifyOnDeviceLost (IDirect3DDevice9* d3d9Device); - - // Called immediately after the Direct3D device has been reset. - void notifyOnDeviceReset (IDirect3DDevice9* d3d9Device); - - // Called when device state is changing. Access to any device should be locked. - // Relevant for multi thread application. - void lockDeviceAccess (); - - // Called when device state change completed. Access to any device is allowed. - // Relevant for multi thread application. - void unlockDeviceAccess (); - - D3D9ResourceManager (); - ~D3D9ResourceManager (); - - void setCreationPolicy (D3D9ResourceCreationPolicy creationPolicy); - D3D9ResourceCreationPolicy getCreationPolicy () const; - - /** - Set/Get automatic hardware buffers management. - This has affect only when multiple devices involved during the runtime. - When enabled, an explicit system memory backup is created for buffers with no read caps - so in case of device swaps - the content of the buffers can be restored from this copy. - The default is false in order to reduce system memory consumption. - */ - void setAutoHardwareBufferManagement(bool autoManagement) { mAutoHardwareBufferManagement = autoManagement; } - bool getAutoHardwareBufferManagement() const { return mAutoHardwareBufferManagement; } - - // Friends. - protected: - friend class D3D9Resource; - - // Types. - protected: - typedef set::type ResourceContainer; - typedef ResourceContainer::iterator ResourceContainerIterator; - - // Protected methods. - protected: - - // Called when new resource created. - void _notifyResourceCreated (D3D9Resource* pResource); - - // Called when resource is about to be destroyed. - void _notifyResourceDestroyed (D3D9Resource* pResource); - - - // Attributes. - protected: - OGRE_MUTEX(mResourcesMutex); - ResourceContainer mResources; - D3D9ResourceCreationPolicy mResourceCreationPolicy; - long mDeviceAccessLockCount; - bool mAutoHardwareBufferManagement; - }; + enum D3D9ResourceCreationPolicy + { + // Creates the rendering resource on the current active device that needs it. + // This policy should be used when video memory consumption should be minimized but + // it might cause some performance issues when using loader resource thread since + // a resource that was not created on specified device will be created on demand during + // the rendering process and might cause the FPS to drop down. + RCP_CREATE_ON_ACTIVE_DEVICE, + + // Create the rendering resource on every existing device. + // This policy should be used when working intensively with a background loader thread. + // In that case when multiple devices exist, the resource will be created on each device + // and will be ready to use in the rendering thread. + // The draw back can be some video memory waste in case that each device render different + // scene and doesn't really need all the resources. + RCP_CREATE_ON_ALL_DEVICES + }; + + class _OgreD3D9Export D3D9ResourceManager : public ResourceAlloc + { + + // Interface. + public: + + // Called immediately after the Direct3D device has been created. + void notifyOnDeviceCreate (IDirect3DDevice9* d3d9Device); + + // Called before the Direct3D device is going to be destroyed. + void notifyOnDeviceDestroy (IDirect3DDevice9* d3d9Device); + + // Called immediately after the Direct3D device has entered a lost state. + void notifyOnDeviceLost (IDirect3DDevice9* d3d9Device); + + // Called immediately after the Direct3D device has been reset. + void notifyOnDeviceReset (IDirect3DDevice9* d3d9Device); + + // Called when device state is changing. Access to any device should be locked. + // Relevant for multi thread application. + void lockDeviceAccess (); + + // Called when device state change completed. Access to any device is allowed. + // Relevant for multi thread application. + void unlockDeviceAccess (); + + D3D9ResourceManager (); + ~D3D9ResourceManager (); + + void setCreationPolicy (D3D9ResourceCreationPolicy creationPolicy); + D3D9ResourceCreationPolicy getCreationPolicy () const; + + /** + Set/Get automatic hardware buffers management. + This has affect only when multiple devices involved during the runtime. + When enabled, an explicit system memory backup is created for buffers with no read caps - so in case of device swaps + the content of the buffers can be restored from this copy. + The default is false in order to reduce system memory consumption. + */ + void setAutoHardwareBufferManagement(bool autoManagement) { mAutoHardwareBufferManagement = autoManagement; } + bool getAutoHardwareBufferManagement() const { return mAutoHardwareBufferManagement; } + + // Friends. + protected: + friend class D3D9Resource; + + // Types. + protected: + typedef set::type ResourceContainer; + typedef ResourceContainer::iterator ResourceContainerIterator; + + // Protected methods. + protected: + + // Called when new resource created. + void _notifyResourceCreated (D3D9Resource* pResource); + + // Called when resource is about to be destroyed. + void _notifyResourceDestroyed (D3D9Resource* pResource); + + + // Attributes. + protected: + OGRE_MUTEX(mResourcesMutex); + ResourceContainer mResources; + D3D9ResourceCreationPolicy mResourceCreationPolicy; + long mDeviceAccessLockCount; + bool mAutoHardwareBufferManagement; + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9Texture.h b/RenderSystems/Direct3D9/include/OgreD3D9Texture.h index 0c9bcac65d8..beea7f0c7fa 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9Texture.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9Texture.h @@ -37,133 +37,133 @@ THE SOFTWARE. #include "OgreD3D9Resource.h" namespace Ogre { - class _OgreD3D9Export D3D9Texture : public Texture, public D3D9Resource - { - protected: - - struct TextureResources - { - /// 1D/2D normal texture pointer - IDirect3DTexture9* pNormTex; - /// cubic texture pointer - IDirect3DCubeTexture9* pCubeTex; - /// Volume texture - IDirect3DVolumeTexture9* pVolumeTex; - /// actual texture pointer - IDirect3DBaseTexture9* pBaseTex; - /// Optional FSAA surface - IDirect3DSurface9* pFSAASurface; - }; - - typedef map::type DeviceToTextureResourcesMap; - typedef DeviceToTextureResourcesMap::iterator DeviceToTextureResourcesIterator; - - /// Map between device to texture resources. - DeviceToTextureResourcesMap mMapDeviceToTextureResources; - - - /// Vector of pointers to subsurfaces - typedef vector::type SurfaceList; - SurfaceList mSurfaceList; - /// cube texture individual face names - String mCubeFaceNames[6]; - /// The memory pool being used - D3DPOOL mD3DPool; - // Dynamic textures? - bool mDynamicTextures; - - /// Is hardware gamma supported (read)? - bool mHwGammaReadSupported; - /// Is hardware gamma supported (write)? - bool mHwGammaWriteSupported; - D3DMULTISAMPLE_TYPE mFSAAType; - DWORD mFSAAQuality; - + class _OgreD3D9Export D3D9Texture : public Texture, public D3D9Resource + { + protected: + + struct TextureResources + { + /// 1D/2D normal texture pointer + IDirect3DTexture9* pNormTex; + /// cubic texture pointer + IDirect3DCubeTexture9* pCubeTex; + /// Volume texture + IDirect3DVolumeTexture9* pVolumeTex; + /// actual texture pointer + IDirect3DBaseTexture9* pBaseTex; + /// Optional FSAA surface + IDirect3DSurface9* pFSAASurface; + }; + + typedef map::type DeviceToTextureResourcesMap; + typedef DeviceToTextureResourcesMap::iterator DeviceToTextureResourcesIterator; + + /// Map between device to texture resources. + DeviceToTextureResourcesMap mMapDeviceToTextureResources; + + + /// Vector of pointers to subsurfaces + typedef vector::type SurfaceList; + SurfaceList mSurfaceList; + /// cube texture individual face names + String mCubeFaceNames[6]; + /// The memory pool being used + D3DPOOL mD3DPool; + // Dynamic textures? + bool mDynamicTextures; + + /// Is hardware gamma supported (read)? + bool mHwGammaReadSupported; + /// Is hardware gamma supported (write)? + bool mHwGammaWriteSupported; + D3DMULTISAMPLE_TYPE mFSAAType; + DWORD mFSAAQuality; + // needed to store data between prepareImpl and loadImpl typedef SharedPtr::type > LoadedStreams; - /// internal method, load a cube texture - void _loadCubeTex(IDirect3DDevice9* d3d9Device, const LoadedStreams &loadedStreams); - /// internal method, load a normal texture - void _loadNormTex(IDirect3DDevice9* d3d9Device, const LoadedStreams &loadedStreams); - /// internal method, load a volume texture - void _loadVolumeTex(IDirect3DDevice9* d3d9Device, const LoadedStreams &loadedStreams); - - /// internal method, prepare a cube texture - LoadedStreams _prepareCubeTex(); - /// internal method, prepare a normal texture - LoadedStreams _prepareNormTex(); - /// internal method, prepare a volume texture - LoadedStreams _prepareVolumeTex(); - - /// internal method, create a blank normal 1D/2D texture - void _createNormTex(IDirect3DDevice9* d3d9Device); - /// internal method, create a blank cube texture - void _createCubeTex(IDirect3DDevice9* d3d9Device); - /// internal method, create a blank cube texture - void _createVolumeTex(IDirect3DDevice9* d3d9Device); - - /// internal method, return a D3D pixel format for texture creation - D3DFORMAT _chooseD3DFormat(IDirect3DDevice9* d3d9Device); - - /// @copydoc Resource::calculateSize - size_t calculateSize(void) const; - /// @copydoc Texture::createInternalResources - void createInternalResources(void); - /// @copydoc Texture::freeInternalResources - void freeInternalResources(void); - /// @copydoc Texture::createInternalResourcesImpl - void createInternalResourcesImpl(void); - /// Creates this texture resources on the specified device. - void createInternalResourcesImpl(IDirect3DDevice9* d3d9Device); - /// free internal resources - void freeInternalResourcesImpl(void); - /// internal method, set Texture class source image protected attributes - void _setSrcAttributes(unsigned long width, unsigned long height, unsigned long depth, PixelFormat format); - /// internal method, set Texture class final texture protected attributes - void _setFinalAttributes(IDirect3DDevice9* d3d9Device, TextureResources* textureResources, - unsigned long width, unsigned long height, unsigned long depth, PixelFormat format); - /// internal method, return the best by hardware supported filter method - D3DTEXTUREFILTERTYPE _getBestFilterMethod(IDirect3DDevice9* d3d9Device); - /// internal method, return true if the device/texture combination can use dynamic textures - bool _canUseDynamicTextures(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat); - /// internal method, return true if the device/texture combination can auto gen. mip maps - bool _canAutoGenMipmaps(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat); - /// internal method, return true if the device/texture combination can use hardware gamma - bool _canUseHardwareGammaCorrection(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat, bool forwriting); - - /// internal method, the cube map face name for the spec. face index - String _getCubeFaceName(unsigned char face) const - { assert(face < 6); return mCubeFaceNames[face]; } - - /// internal method, create D3D9HardwarePixelBuffers for every face and - /// mipmap level. This method must be called after the D3D texture object was created - void _createSurfaceList(IDirect3DDevice9* d3d9Device, TextureResources* textureResources); + /// internal method, load a cube texture + void _loadCubeTex(IDirect3DDevice9* d3d9Device, const LoadedStreams &loadedStreams); + /// internal method, load a normal texture + void _loadNormTex(IDirect3DDevice9* d3d9Device, const LoadedStreams &loadedStreams); + /// internal method, load a volume texture + void _loadVolumeTex(IDirect3DDevice9* d3d9Device, const LoadedStreams &loadedStreams); + + /// internal method, prepare a cube texture + LoadedStreams _prepareCubeTex(); + /// internal method, prepare a normal texture + LoadedStreams _prepareNormTex(); + /// internal method, prepare a volume texture + LoadedStreams _prepareVolumeTex(); + + /// internal method, create a blank normal 1D/2D texture + void _createNormTex(IDirect3DDevice9* d3d9Device); + /// internal method, create a blank cube texture + void _createCubeTex(IDirect3DDevice9* d3d9Device); + /// internal method, create a blank cube texture + void _createVolumeTex(IDirect3DDevice9* d3d9Device); + + /// internal method, return a D3D pixel format for texture creation + D3DFORMAT _chooseD3DFormat(IDirect3DDevice9* d3d9Device); + + /// @copydoc Resource::calculateSize + size_t calculateSize(void) const; + /// @copydoc Texture::createInternalResources + void createInternalResources(void); + /// @copydoc Texture::freeInternalResources + void freeInternalResources(void); + /// @copydoc Texture::createInternalResourcesImpl + void createInternalResourcesImpl(void); + /// Creates this texture resources on the specified device. + void createInternalResourcesImpl(IDirect3DDevice9* d3d9Device); + /// free internal resources + void freeInternalResourcesImpl(void); + /// internal method, set Texture class source image protected attributes + void _setSrcAttributes(unsigned long width, unsigned long height, unsigned long depth, PixelFormat format); + /// internal method, set Texture class final texture protected attributes + void _setFinalAttributes(IDirect3DDevice9* d3d9Device, TextureResources* textureResources, + unsigned long width, unsigned long height, unsigned long depth, PixelFormat format); + /// internal method, return the best by hardware supported filter method + D3DTEXTUREFILTERTYPE _getBestFilterMethod(IDirect3DDevice9* d3d9Device); + /// internal method, return true if the device/texture combination can use dynamic textures + bool _canUseDynamicTextures(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat); + /// internal method, return true if the device/texture combination can auto gen. mip maps + bool _canAutoGenMipmaps(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat); + /// internal method, return true if the device/texture combination can use hardware gamma + bool _canUseHardwareGammaCorrection(IDirect3DDevice9* d3d9Device, DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat, bool forwriting); + + /// internal method, the cube map face name for the spec. face index + String _getCubeFaceName(unsigned char face) const + { assert(face < 6); return mCubeFaceNames[face]; } + + /// internal method, create D3D9HardwarePixelBuffers for every face and + /// mipmap level. This method must be called after the D3D texture object was created + void _createSurfaceList(IDirect3DDevice9* d3d9Device, TextureResources* textureResources); /// overridden from Resource - void loadImpl(); - /// Loads this texture into the specified device. - void loadImpl(IDirect3DDevice9* d3d9Device); + void loadImpl(); + /// Loads this texture into the specified device. + void loadImpl(IDirect3DDevice9* d3d9Device); /// overridden from Resource void prepareImpl(); /// overridden from Resource void unprepareImpl(); - /// overridden from Resource - void postLoadImpl(); + /// overridden from Resource + void postLoadImpl(); - /// gets the texture resources attached to the given device. - TextureResources* getTextureResources(IDirect3DDevice9* d3d9Device); + /// gets the texture resources attached to the given device. + TextureResources* getTextureResources(IDirect3DDevice9* d3d9Device); - /// allocates new texture resources structure attached to the given device. - TextureResources* allocateTextureResources(IDirect3DDevice9* d3d9Device); + /// allocates new texture resources structure attached to the given device. + TextureResources* allocateTextureResources(IDirect3DDevice9* d3d9Device); - /// creates this texture resources according to the current settings. - void createTextureResources(IDirect3DDevice9* d3d9Device); + /// creates this texture resources according to the current settings. + void createTextureResources(IDirect3DDevice9* d3d9Device); - /// frees the given texture resources. - void freeTextureResources(IDirect3DDevice9* d3d9Device, TextureResources* textureResources); + /// frees the given texture resources. + void freeTextureResources(IDirect3DDevice9* d3d9Device, TextureResources* textureResources); - void determinePool(); + void determinePool(); /** Vector of pointers to streams that were pulled from disk by prepareImpl but have yet to be pushed into texture memory @@ -171,70 +171,70 @@ namespace Ogre { */ LoadedStreams mLoadedStreams; - friend class D3D9HardwarePixelBuffer; - public: - /// constructor + friend class D3D9HardwarePixelBuffer; + public: + /// constructor D3D9Texture(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - /// destructor - ~D3D9Texture(); - - /// overridden from Texture - void copyToTexture( TexturePtr& target ); - - - /// @copydoc Texture::getBuffer - HardwarePixelBufferSharedPtr getBuffer(size_t face, size_t mipmap); - - /// retrieves a pointer to the actual texture - IDirect3DBaseTexture9 *getTexture(); - /// retrieves a pointer to the normal 1D/2D texture - IDirect3DTexture9 *getNormTexture(); - /// retrieves a pointer to the cube texture - IDirect3DCubeTexture9 *getCubeTexture(); - - /** Indicates whether the hardware gamma is actually enabled and supported. - @remarks - Because hardware gamma might not actually be supported, we need to - ignore it sometimes. Because D3D doesn't encode sRGB in the format but - as a sampler state, and we don't want to change the original requested - hardware gamma flag (e.g. serialisation) we need another indicator. - */ - bool isHardwareGammaReadToBeUsed() const { return mHwGamma && mHwGammaReadSupported; } - - /// Will this texture need to be in the default pool? - bool useDefaultPool(); - - // Called immediately after the Direct3D device has been created. - virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); - - // Called before the Direct3D device is going to be destroyed. - virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); - - // Called immediately after the Direct3D device has entered a lost state. - virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device); - - // Called immediately after the Direct3D device has been reset - virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device); + /// destructor + ~D3D9Texture(); + + /// overridden from Texture + void copyToTexture( TexturePtr& target ); + + + /// @copydoc Texture::getBuffer + HardwarePixelBufferSharedPtr getBuffer(size_t face, size_t mipmap); + + /// retrieves a pointer to the actual texture + IDirect3DBaseTexture9 *getTexture(); + /// retrieves a pointer to the normal 1D/2D texture + IDirect3DTexture9 *getNormTexture(); + /// retrieves a pointer to the cube texture + IDirect3DCubeTexture9 *getCubeTexture(); + + /** Indicates whether the hardware gamma is actually enabled and supported. + @remarks + Because hardware gamma might not actually be supported, we need to + ignore it sometimes. Because D3D doesn't encode sRGB in the format but + as a sampler state, and we don't want to change the original requested + hardware gamma flag (e.g. serialisation) we need another indicator. + */ + bool isHardwareGammaReadToBeUsed() const { return mHwGamma && mHwGammaReadSupported; } + + /// Will this texture need to be in the default pool? + bool useDefaultPool(); + + // Called immediately after the Direct3D device has been created. + virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); + + // Called before the Direct3D device is going to be destroyed. + virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); + + // Called immediately after the Direct3D device has entered a lost state. + virtual void notifyOnDeviceLost(IDirect3DDevice9* d3d9Device); + + // Called immediately after the Direct3D device has been reset + virtual void notifyOnDeviceReset(IDirect3DDevice9* d3d9Device); }; /// RenderTexture implementation for D3D9 class _OgreD3D9Export D3D9RenderTexture : public RenderTexture { public: - D3D9RenderTexture(const String &name, D3D9HardwarePixelBuffer *buffer, bool writeGamma, uint fsaa); + D3D9RenderTexture(const String &name, D3D9HardwarePixelBuffer *buffer, bool writeGamma, uint fsaa); ~D3D9RenderTexture() {} - virtual void update(bool swap); + virtual void update(bool swap); - virtual void getCustomAttribute( const String& name, void *pData ); + virtual void getCustomAttribute( const String& name, void *pData ); - bool requiresTextureFlipping() const { return false; } + bool requiresTextureFlipping() const { return false; } - /// Override needed to deal with FSAA - void swapBuffers(); + /// Override needed to deal with FSAA + void swapBuffers(); - }; + }; } diff --git a/RenderSystems/Direct3D9/include/OgreD3D9TextureManager.h b/RenderSystems/Direct3D9/include/OgreD3D9TextureManager.h index d4f4c227686..2d478ab1025 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9TextureManager.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9TextureManager.h @@ -33,25 +33,25 @@ THE SOFTWARE. namespace Ogre { - class _OgreD3D9Export D3D9TextureManager : public TextureManager - { - protected: + class _OgreD3D9Export D3D9TextureManager : public TextureManager + { + protected: /// @copydoc ResourceManager::createImpl Resource* createImpl(const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* createParams); - public: - D3D9TextureManager(); - ~D3D9TextureManager(); + public: + D3D9TextureManager(); + ~D3D9TextureManager(); - /// @copydoc TextureManager::getNativeFormat - PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage); + /// @copydoc TextureManager::getNativeFormat + PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage); /// @copydoc TextureManager::isHardwareFilteringSupported bool isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage, - bool preciseFormatOnly = false); - }; + bool preciseFormatOnly = false); + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9VertexDeclaration.h b/RenderSystems/Direct3D9/include/OgreD3D9VertexDeclaration.h index 5ec5402ca06..e71bac13b0b 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9VertexDeclaration.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9VertexDeclaration.h @@ -53,38 +53,38 @@ namespace Ogre { /** See VertexDeclaration */ void removeElement(unsigned short elem_index); - - /** See VertexDeclaration */ - void removeElement(VertexElementSemantic semantic, unsigned short index = 0); + + /** See VertexDeclaration */ + void removeElement(VertexElementSemantic semantic, unsigned short index = 0); - /** See VertexDeclaration */ - void removeAllElements(void); + /** See VertexDeclaration */ + void removeAllElements(void); /** See VertexDeclaration */ void modifyElement(unsigned short elem_index, unsigned short source, size_t offset, VertexElementType theType, VertexElementSemantic semantic, unsigned short index = 0); - // Called immediately after the Direct3D device has been created. - virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); + // Called immediately after the Direct3D device has been created. + virtual void notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device); - // Called before the Direct3D device is going to be destroyed. - virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); + // Called before the Direct3D device is going to be destroyed. + virtual void notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device); /** Gets the D3D9-specific vertex declaration. */ IDirect3DVertexDeclaration9* getD3DVertexDeclaration(VertexDeclaration * globalDeclaration, bool useGlobalInstancingVertexBufferIsAvailable); - protected: - void releaseDeclaration(); + protected: + void releaseDeclaration(); void convertElement( const VertexElement & element, D3DVERTEXELEMENT9 & dxElement ); - protected: - typedef map::type DeviceToDeclarationMap; - typedef DeviceToDeclarationMap::iterator DeviceToDeclarationIterator; + protected: + typedef map::type DeviceToDeclarationMap; + typedef DeviceToDeclarationMap::iterator DeviceToDeclarationIterator; - DeviceToDeclarationMap mMapDeviceToDeclaration; - VertexDeclaration * mLastUsedGlobalDeclaration; - bool mUsedGlobalDeclaration; + DeviceToDeclarationMap mMapDeviceToDeclaration; + VertexDeclaration * mLastUsedGlobalDeclaration; + bool mUsedGlobalDeclaration; }; } diff --git a/RenderSystems/Direct3D9/include/OgreD3D9VideoMode.h b/RenderSystems/Direct3D9/include/OgreD3D9VideoMode.h index 22d50c4c969..d236b236452 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9VideoMode.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9VideoMode.h @@ -33,31 +33,31 @@ THE SOFTWARE. namespace Ogre { - static unsigned int modeCount = 0; - - class _OgreD3D9Export D3D9VideoMode - { - private: - D3DDISPLAYMODE mDisplayMode; - unsigned int modeNumber; - - public: - D3D9VideoMode() { modeNumber = ++modeCount; ZeroMemory( &mDisplayMode, sizeof(D3DDISPLAYMODE) ); } - D3D9VideoMode( const D3D9VideoMode &ob ) { modeNumber = ++modeCount; mDisplayMode = ob.mDisplayMode; } - D3D9VideoMode( D3DDISPLAYMODE d3ddm ) { modeNumber = ++modeCount; mDisplayMode = d3ddm; } - ~D3D9VideoMode() - { - modeCount--; - } - - unsigned int getWidth() const { return mDisplayMode.Width; } - unsigned int getHeight() const { return mDisplayMode.Height; } - D3DFORMAT getFormat() const { return mDisplayMode.Format; } - unsigned int getRefreshRate() const { return mDisplayMode.RefreshRate; } - unsigned int getColourDepth() const; - D3DDISPLAYMODE getDisplayMode() const { return mDisplayMode; } - void increaseRefreshRate(unsigned int rr) { mDisplayMode.RefreshRate = rr; } - String getDescription() const; - }; + static unsigned int modeCount = 0; + + class _OgreD3D9Export D3D9VideoMode + { + private: + D3DDISPLAYMODE mDisplayMode; + unsigned int modeNumber; + + public: + D3D9VideoMode() { modeNumber = ++modeCount; ZeroMemory( &mDisplayMode, sizeof(D3DDISPLAYMODE) ); } + D3D9VideoMode( const D3D9VideoMode &ob ) { modeNumber = ++modeCount; mDisplayMode = ob.mDisplayMode; } + D3D9VideoMode( D3DDISPLAYMODE d3ddm ) { modeNumber = ++modeCount; mDisplayMode = d3ddm; } + ~D3D9VideoMode() + { + modeCount--; + } + + unsigned int getWidth() const { return mDisplayMode.Width; } + unsigned int getHeight() const { return mDisplayMode.Height; } + D3DFORMAT getFormat() const { return mDisplayMode.Format; } + unsigned int getRefreshRate() const { return mDisplayMode.RefreshRate; } + unsigned int getColourDepth() const; + D3DDISPLAYMODE getDisplayMode() const { return mDisplayMode; } + void increaseRefreshRate(unsigned int rr) { mDisplayMode.RefreshRate = rr; } + String getDescription() const; + }; } #endif diff --git a/RenderSystems/Direct3D9/include/OgreD3D9VideoModeList.h b/RenderSystems/Direct3D9/include/OgreD3D9VideoModeList.h index 318f5d6627d..cd80625c333 100644 --- a/RenderSystems/Direct3D9/include/OgreD3D9VideoModeList.h +++ b/RenderSystems/Direct3D9/include/OgreD3D9VideoModeList.h @@ -34,22 +34,22 @@ THE SOFTWARE. namespace Ogre { - class _OgreD3D9Export D3D9VideoModeList : public RenderSysAlloc - { - private: - D3D9Driver* mDriver; - vector::type mModeList; + class _OgreD3D9Export D3D9VideoModeList : public RenderSysAlloc + { + private: + D3D9Driver* mDriver; + vector::type mModeList; - public: - D3D9VideoModeList( D3D9Driver* pDriver ); - ~D3D9VideoModeList(); + public: + D3D9VideoModeList( D3D9Driver* pDriver ); + ~D3D9VideoModeList(); - BOOL enumerate(); + BOOL enumerate(); - D3D9VideoMode* item( size_t index ); - size_t count(); + D3D9VideoMode* item( size_t index ); + size_t count(); - D3D9VideoMode* item( const String &name ); - }; + D3D9VideoMode* item( const String &name ); + }; } #endif diff --git a/RenderSystems/Direct3D9/src/OgreD3D9DepthBuffer.cpp b/RenderSystems/Direct3D9/src/OgreD3D9DepthBuffer.cpp index 14c2764ba15..25d02eb691c 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9DepthBuffer.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9DepthBuffer.cpp @@ -31,82 +31,82 @@ THE SOFTWARE. namespace Ogre { - D3D9DepthBuffer::D3D9DepthBuffer( uint16 poolId, D3D9RenderSystem *renderSystem, - IDirect3DDevice9 *creator, IDirect3DSurface9 *depthBufferSurf, - D3DFORMAT fmt, uint32 width, uint32 height, - uint32 fsaa, uint32 multiSampleQuality, bool isManual ) : - DepthBuffer( poolId, 0, width, height, fsaa, "", isManual ), - mDepthBuffer( depthBufferSurf ), - mCreator( creator ), - mMultiSampleQuality( multiSampleQuality ), - mD3DFormat( fmt ), - mRenderSystem( renderSystem ) - { - switch( fmt ) - { - case D3DFMT_D16_LOCKABLE: - case D3DFMT_D15S1: - case D3DFMT_D16: - mBitDepth = 16; - break; - case D3DFMT_D32: - case D3DFMT_D24S8: - case D3DFMT_D24X8: - case D3DFMT_D24X4S4: - case D3DFMT_D32F_LOCKABLE: - case D3DFMT_D24FS8: - mBitDepth = 32; - break; - } - } + D3D9DepthBuffer::D3D9DepthBuffer( uint16 poolId, D3D9RenderSystem *renderSystem, + IDirect3DDevice9 *creator, IDirect3DSurface9 *depthBufferSurf, + D3DFORMAT fmt, uint32 width, uint32 height, + uint32 fsaa, uint32 multiSampleQuality, bool isManual ) : + DepthBuffer( poolId, 0, width, height, fsaa, "", isManual ), + mDepthBuffer( depthBufferSurf ), + mCreator( creator ), + mMultiSampleQuality( multiSampleQuality ), + mD3DFormat( fmt ), + mRenderSystem( renderSystem ) + { + switch( fmt ) + { + case D3DFMT_D16_LOCKABLE: + case D3DFMT_D15S1: + case D3DFMT_D16: + mBitDepth = 16; + break; + case D3DFMT_D32: + case D3DFMT_D24S8: + case D3DFMT_D24X8: + case D3DFMT_D24X4S4: + case D3DFMT_D32F_LOCKABLE: + case D3DFMT_D24FS8: + mBitDepth = 32; + break; + } + } - D3D9DepthBuffer::~D3D9DepthBuffer() - { - if( !mManual ) - mDepthBuffer->Release(); - mDepthBuffer = 0; + D3D9DepthBuffer::~D3D9DepthBuffer() + { + if( !mManual ) + mDepthBuffer->Release(); + mDepthBuffer = 0; - mCreator = 0; - } - //--------------------------------------------------------------------- - bool D3D9DepthBuffer::isCompatible( RenderTarget *renderTarget ) const - { - IDirect3DSurface9* pBack[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - memset( pBack, 0, sizeof(pBack) ); - renderTarget->getCustomAttribute( "DDBACKBUFFER", &pBack ); - if( !pBack[0] ) - return false; + mCreator = 0; + } + //--------------------------------------------------------------------- + bool D3D9DepthBuffer::isCompatible( RenderTarget *renderTarget ) const + { + IDirect3DSurface9* pBack[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + memset( pBack, 0, sizeof(pBack) ); + renderTarget->getCustomAttribute( "DDBACKBUFFER", &pBack ); + if( !pBack[0] ) + return false; - D3DSURFACE_DESC srfDesc; - if( SUCCEEDED(pBack[0]->GetDesc(&srfDesc)) ) - { - //RenderSystem will determine if bitdepths match (i.e. 32 bit RT don't like 16 bit Depth) - //This is the same function used to create them. Note results are usually cached so this should - //be quick - D3DFORMAT fmt = mRenderSystem->_getDepthStencilFormatFor( srfDesc.Format ); - IDirect3DDevice9 *activeDevice = mRenderSystem->getActiveD3D9Device(); + D3DSURFACE_DESC srfDesc; + if( SUCCEEDED(pBack[0]->GetDesc(&srfDesc)) ) + { + //RenderSystem will determine if bitdepths match (i.e. 32 bit RT don't like 16 bit Depth) + //This is the same function used to create them. Note results are usually cached so this should + //be quick + D3DFORMAT fmt = mRenderSystem->_getDepthStencilFormatFor( srfDesc.Format ); + IDirect3DDevice9 *activeDevice = mRenderSystem->getActiveD3D9Device(); - if( mCreator == activeDevice && - fmt == mD3DFormat && - mFsaa == srfDesc.MultiSampleType && - mMultiSampleQuality == srfDesc.MultiSampleQuality && - this->getWidth() >= renderTarget->getWidth() && - this->getHeight() >= renderTarget->getHeight() ) - { - return true; - } - } + if( mCreator == activeDevice && + fmt == mD3DFormat && + mFsaa == srfDesc.MultiSampleType && + mMultiSampleQuality == srfDesc.MultiSampleQuality && + this->getWidth() >= renderTarget->getWidth() && + this->getHeight() >= renderTarget->getHeight() ) + { + return true; + } + } - return false; - } - //--------------------------------------------------------------------- - IDirect3DDevice9* D3D9DepthBuffer::getDeviceCreator() const - { - return mCreator; - } - //--------------------------------------------------------------------- - IDirect3DSurface9* D3D9DepthBuffer::getDepthBufferSurface() const - { - return mDepthBuffer; - } + return false; + } + //--------------------------------------------------------------------- + IDirect3DDevice9* D3D9DepthBuffer::getDeviceCreator() const + { + return mCreator; + } + //--------------------------------------------------------------------- + IDirect3DSurface9* D3D9DepthBuffer::getDepthBufferSurface() const + { + return mDepthBuffer; + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9Device.cpp b/RenderSystems/Direct3D9/src/OgreD3D9Device.cpp index 1c1640cc1a3..43e800bcadc 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9Device.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9Device.cpp @@ -37,1538 +37,1538 @@ THE SOFTWARE. namespace Ogre { - HWND D3D9Device::msSharedFocusWindow = NULL; - - //--------------------------------------------------------------------- - D3D9Device::D3D9Device(D3D9DeviceManager* deviceManager, - UINT adapterNumber, - HMONITOR hMonitor, - D3DDEVTYPE devType, - DWORD behaviorFlags) - { - mDeviceManager = deviceManager; - mDevice = NULL; - mAdapterNumber = adapterNumber; - mMonitor = hMonitor; - mDeviceType = devType; - mFocusWindow = NULL; - mBehaviorFlags = behaviorFlags; - mD3D9DeviceCapsValid = false; - mDeviceLost = false; - mPresentationParamsCount = 0; - mPresentationParams = NULL; - memset(&mD3D9DeviceCaps, 0, sizeof(mD3D9DeviceCaps)); - memset(&mCreationParams, 0, sizeof(mCreationParams)); - memset(&mPreviousPresentStats, 0, sizeof(mPreviousPresentStats)); - mPreviousPresentStatsIsValid = false; - mVBlankMissCount = 0; - } - - //--------------------------------------------------------------------- - D3D9Device::~D3D9Device() - { - - } - - //--------------------------------------------------------------------- - D3D9Device::RenderWindowToResourcesIterator D3D9Device::getRenderWindowIterator(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.find(renderWindow); - - if (it == mMapRenderWindowToResources.end()) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Render window was not attached to this device !!", - "D3D9Device::getRenderWindowIterator" ); - } - - return it; - } - - - //--------------------------------------------------------------------- - void D3D9Device::attachRenderWindow(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.find(renderWindow); - - if (it == mMapRenderWindowToResources.end()) - { - RenderWindowResources* renderWindowResources = OGRE_NEW_T(RenderWindowResources, MEMCATEGORY_RENDERSYS); - - memset(renderWindowResources, 0, sizeof(RenderWindowResources)); - renderWindowResources->adapterOrdinalInGroupIndex = 0; - renderWindowResources->acquired = false; - mMapRenderWindowToResources[renderWindow] = renderWindowResources; - } - updateRenderWindowsIndices(); - } - - //--------------------------------------------------------------------- - void D3D9Device::detachRenderWindow(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.find(renderWindow); - - if (it != mMapRenderWindowToResources.end()) - { - // The focus window in which the d3d9 device created on is detached. - // resources must be acquired again. - if (mFocusWindow == renderWindow->getWindowHandle()) - { - mFocusWindow = NULL; - } - - // Case this is the shared focus window. - if (renderWindow->getWindowHandle() == msSharedFocusWindow) - setSharedWindowHandle(NULL); - - RenderWindowResources* renderWindowResources = it->second; - - releaseRenderWindowResources(renderWindowResources); - - OGRE_DELETE_T(renderWindowResources, RenderWindowResources, MEMCATEGORY_RENDERSYS); - - mMapRenderWindowToResources.erase(it); - } - updateRenderWindowsIndices(); - } - - //--------------------------------------------------------------------- - bool D3D9Device::acquire() - { - updatePresentationParameters(); - - bool resetDevice = false; - - // Create device if need to. - if (mDevice == NULL) - { - createD3D9Device(); - } - - // Case device already exists. - else - { - RenderWindowToResourcesIterator itPrimary = getRenderWindowIterator(getPrimaryWindow()); - - if (itPrimary->second->swapChain != NULL) - { - D3DPRESENT_PARAMETERS currentPresentParams; - HRESULT hr; - - hr = itPrimary->second->swapChain->GetPresentParameters(¤tPresentParams); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "GetPresentParameters failed", - "D3D9RenderWindow::acquire"); - } - - // Desired parameters are different then current parameters. - // Possible scenario is that primary window resized and in the mean while another - // window attached to this device. - if (memcmp(¤tPresentParams, &mPresentationParams[0], sizeof(D3DPRESENT_PARAMETERS)) != 0) - { - resetDevice = true; - } - } - - // Make sure depth stencil is set to valid surface. It is going to be - // grabbed by the primary window using the GetDepthStencilSurface method. - if (resetDevice == false) - { - mDevice->SetDepthStencilSurface(itPrimary->second->depthBuffer); - } - - } - - // Reset device will update all render window resources. - if (resetDevice) - { - reset(); - } - - // No need to reset -> just acquire resources. - else - { - // Update resources of each window. - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); - - while (it != mMapRenderWindowToResources.end()) - { - acquireRenderWindowResources(it); - ++it; - } - } - - return true; - } - - //--------------------------------------------------------------------- - void D3D9Device::release() - { - if (mDevice != NULL) - { - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); - - while (it != mMapRenderWindowToResources.end()) - { - RenderWindowResources* renderWindowResources = it->second; - - releaseRenderWindowResources(renderWindowResources); - ++it; - } - - releaseD3D9Device(); - } - } - - //--------------------------------------------------------------------- - bool D3D9Device::acquire(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - - acquireRenderWindowResources(it); - - return true; - } - - //--------------------------------------------------------------------- - void D3D9Device::notifyDeviceLost() - { - // Case this device is already in lost state. - if (mDeviceLost) - return; - - // Case we just moved from valid state to lost state. - mDeviceLost = true; - - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - - renderSystem->notifyOnDeviceLost(this); - } - - //--------------------------------------------------------------------- - IDirect3DSurface9* D3D9Device::getDepthBuffer(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - - return it->second->depthBuffer; - } - - //--------------------------------------------------------------------- - IDirect3DSurface9* D3D9Device::getBackBuffer(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - - return it->second->backBuffer; - } - - //--------------------------------------------------------------------- - uint D3D9Device::getRenderWindowCount() const - { - return static_cast(mMapRenderWindowToResources.size()); - } - - //--------------------------------------------------------------------- - D3D9RenderWindow* D3D9Device::getRenderWindow(uint index) - { - if (index >= mMapRenderWindowToResources.size()) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Index of render window is out of bounds!", - "D3D9RenderWindow::getRenderWindow"); - } - - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); - - while (it != mMapRenderWindowToResources.end()) - { - if (index == 0) - break; - - --index; - ++it; - } - - return it->first; - } - - //--------------------------------------------------------------------- - void D3D9Device::setAdapterOrdinalIndex(D3D9RenderWindow* renderWindow, uint adapterOrdinalInGroupIndex) - { - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - - it->second->adapterOrdinalInGroupIndex = adapterOrdinalInGroupIndex; - - updateRenderWindowsIndices(); - } - - //--------------------------------------------------------------------- - void D3D9Device::destroy() - { - // Lock access to rendering device. - D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); - - //Remove _all_ depth buffers created by this device - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - renderSystem->_cleanupDepthBuffers( mDevice ); - - release(); - - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); - - while (it != mMapRenderWindowToResources.end()) - { - if (it->first->getWindowHandle() == msSharedFocusWindow) - setSharedWindowHandle(NULL); - - OGRE_DELETE_T(it->second, RenderWindowResources, MEMCATEGORY_RENDERSYS); - ++it; - } - mMapRenderWindowToResources.clear(); - - // Reset dynamic attributes. - mFocusWindow = NULL; - mD3D9DeviceCapsValid = false; - - if (mPresentationParams != NULL) - { - OGRE_FREE (mPresentationParams, MEMCATEGORY_RENDERSYS); - mPresentationParams = NULL; - } - mPresentationParamsCount = 0; - - // Notify the device manager on this instance destruction. - mDeviceManager->notifyOnDeviceDestroy(this); - - // UnLock access to rendering device. - D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); - } - - //--------------------------------------------------------------------- - bool D3D9Device::isDeviceLost() - { - HRESULT hr; - - hr = mDevice->TestCooperativeLevel(); - - if (hr == D3DERR_DEVICELOST || - hr == D3DERR_DEVICENOTRESET) - { - return true; - } - - return false; - } - - //--------------------------------------------------------------------- - bool D3D9Device::reset() - { - HRESULT hr; - - // Check that device is in valid state for reset. - hr = mDevice->TestCooperativeLevel(); - if (hr == D3DERR_DEVICELOST || - hr == D3DERR_DRIVERINTERNALERROR) - { - return false; - } - - // Lock access to rendering device. - D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); - - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - - // Inform all resources that device lost. - D3D9RenderSystem::getResourceManager()->notifyOnDeviceLost(mDevice); - - // Notify all listener before device is rested - renderSystem->notifyOnDeviceLost(this); - - // Release all automatic temporary buffers and free unused - // temporary buffers, so we doesn't need to recreate them, - // and they will reallocate on demand. This save a lot of - // release/recreate of non-managed vertex buffers which - // wasn't need at all. - HardwareBufferManager::getSingleton()._releaseBufferCopies(true); - - - // Cleanup depth stencils surfaces. - renderSystem->_cleanupDepthBuffers(); - - updatePresentationParameters(); - - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); - - while (it != mMapRenderWindowToResources.end()) - { - RenderWindowResources* renderWindowResources = it->second; - - releaseRenderWindowResources(renderWindowResources); - ++it; - } - - clearDeviceStreams(); - - renderSystem->fireDeviceEvent(this, "BeforeDeviceReset"); - - // Reset the device using the presentation parameters. - hr = mDevice->Reset(mPresentationParams); - - renderSystem->fireDeviceEvent(this, "AfterDeviceReset"); - - if (hr == D3DERR_DEVICELOST) - { - // UnLock access to rendering device. - D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); - - // Don't continue - return false; - } - else if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot reset device!", - "D3D9RenderWindow::reset"); - } - - mDeviceLost = false; - - // Initialize device states. - setupDeviceStates(); - - // Update resources of each window. - it = mMapRenderWindowToResources.begin(); - - while (it != mMapRenderWindowToResources.end()) - { - acquireRenderWindowResources(it); - ++it; - } - - D3D9Device* pCurActiveDevice = mDeviceManager->getActiveDevice(); - - mDeviceManager->setActiveDevice(this); - - // Inform all resources that device has been reset. - D3D9RenderSystem::getResourceManager()->notifyOnDeviceReset(mDevice); - - mDeviceManager->setActiveDevice(pCurActiveDevice); - - renderSystem->notifyOnDeviceReset(this); - - // UnLock access to rendering device. - D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); - - return true; - } - - //--------------------------------------------------------------------- - bool D3D9Device::isAutoDepthStencil() const - { - const D3DPRESENT_PARAMETERS& primaryPresentationParams = mPresentationParams[0]; - - // Check if auto depth stencil can be used. - for (unsigned int i = 1; i < mPresentationParamsCount; i++) - { - // disable AutoDepthStencil if these parameters are not all the same. - if(primaryPresentationParams.BackBufferHeight != mPresentationParams[i].BackBufferHeight || - primaryPresentationParams.BackBufferWidth != mPresentationParams[i].BackBufferWidth || - primaryPresentationParams.BackBufferFormat != mPresentationParams[i].BackBufferFormat || - primaryPresentationParams.AutoDepthStencilFormat != mPresentationParams[i].AutoDepthStencilFormat || - primaryPresentationParams.MultiSampleQuality != mPresentationParams[i].MultiSampleQuality || - primaryPresentationParams.MultiSampleType != mPresentationParams[i].MultiSampleType) - { - return false; - } - } - - return true; - } - - //--------------------------------------------------------------------- - bool D3D9Device::isFullScreen() const - { - if (mPresentationParamsCount > 0 && mPresentationParams[0].Windowed == FALSE) - return true; - - return false; - } - - //--------------------------------------------------------------------- - const D3DCAPS9& D3D9Device::getD3D9DeviceCaps() const - { - if (mD3D9DeviceCapsValid == false) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Device caps are invalid!", - "D3D9Device::getD3D9DeviceCaps" ); - } - - return mD3D9DeviceCaps; - } - - //--------------------------------------------------------------------- - D3DFORMAT D3D9Device::getBackBufferFormat() const - { - if (mPresentationParams == NULL || mPresentationParamsCount == 0) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Presentation parameters are invalid!", - "D3D9Device::getBackBufferFormat" ); - } - - return mPresentationParams[0].BackBufferFormat; - } - - //--------------------------------------------------------------------- - IDirect3DDevice9* D3D9Device::getD3D9Device() - { - return mDevice; - } - - //--------------------------------------------------------------------- - void D3D9Device::updatePresentationParameters() - { - // Clear old presentation parameters. - if (mPresentationParams != NULL) - { - OGRE_FREE (mPresentationParams, MEMCATEGORY_RENDERSYS); - mPresentationParams = NULL; - } - mPresentationParamsCount = 0; - - if (mMapRenderWindowToResources.size() > 0) - { - mPresentationParams = OGRE_ALLOC_T(D3DPRESENT_PARAMETERS, mMapRenderWindowToResources.size(), MEMCATEGORY_RENDERSYS); - - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); - - while (it != mMapRenderWindowToResources.end()) - { - D3D9RenderWindow* renderWindow = it->first; - RenderWindowResources* renderWindowResources = it->second; - - // Ask the render window to build it's own parameters. - renderWindow->buildPresentParameters(&renderWindowResources->presentParameters); - - - // Update shared focus window handle. - if (renderWindow->isFullScreen() && - renderWindowResources->presentParametersIndex == 0 && - msSharedFocusWindow == NULL) - setSharedWindowHandle(renderWindow->getWindowHandle()); - - // This is the primary window or a full screen window that is part of multi head device. - if (renderWindowResources->presentParametersIndex == 0 || - renderWindow->isFullScreen()) - { - mPresentationParams[renderWindowResources->presentParametersIndex] = renderWindowResources->presentParameters; - mPresentationParamsCount++; - } - - ++it; - } - } - - // Case we have to cancel auto depth stencil. - if (isMultihead() && isAutoDepthStencil() == false) - { - for(unsigned int i = 0; i < mPresentationParamsCount; i++) - { - mPresentationParams[i].EnableAutoDepthStencil = false; - } - } - } - - //--------------------------------------------------------------------- - UINT D3D9Device::getAdapterNumber() const - { - return mAdapterNumber; - } - - //--------------------------------------------------------------------- - D3DDEVTYPE D3D9Device::getDeviceType() const - { - return mDeviceType; - } - - //--------------------------------------------------------------------- - bool D3D9Device::isMultihead() const - { - RenderWindowToResourcesMap::const_iterator it = mMapRenderWindowToResources.begin(); - - while (it != mMapRenderWindowToResources.end()) - { - RenderWindowResources* renderWindowResources = it->second; - - if (renderWindowResources->adapterOrdinalInGroupIndex > 0 && - it->first->isFullScreen()) - { - return true; - } - - ++it; - } - - return false; - } - - //--------------------------------------------------------------------- - void D3D9Device::clearDeviceStreams() - { - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - - // Set all texture units to nothing to release texture surfaces - for (DWORD stage = 0; stage < mD3D9DeviceCaps.MaxSimultaneousTextures; ++stage) - { - DWORD dwCurValue = D3DTOP_FORCE_DWORD; - HRESULT hr; - - hr = mDevice->SetTexture(stage, NULL); - if( hr != S_OK ) - { - String str = "Unable to disable texture '" + StringConverter::toString((unsigned int)stage) + "' in D3D9"; - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9Device::clearDeviceStreams" ); - } - - mDevice->GetTextureStageState(static_cast(stage), D3DTSS_COLOROP, &dwCurValue); - - if (dwCurValue != D3DTOP_DISABLE) - { - hr = mDevice->SetTextureStageState(static_cast(stage), D3DTSS_COLOROP, D3DTOP_DISABLE); - if( hr != S_OK ) - { - String str = "Unable to disable texture '" + StringConverter::toString((unsigned)stage) + "' in D3D9"; - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9Device::clearDeviceStreams" ); - } - } - - - // set stage desc. to defaults - renderSystem->mTexStageDesc[stage].pTex = 0; - renderSystem->mTexStageDesc[stage].autoTexCoordType = TEXCALC_NONE; - renderSystem->mTexStageDesc[stage].coordIndex = 0; - renderSystem->mTexStageDesc[stage].texType = D3D9Mappings::D3D_TEX_TYPE_NORMAL; - } - - // Unbind any vertex streams to avoid memory leaks - for (unsigned int i = 0; i < mD3D9DeviceCaps.MaxStreams; ++i) - { - mDevice->SetStreamSource(i, NULL, 0, 0); - } - } - - //--------------------------------------------------------------------- - void D3D9Device::createD3D9Device() - { - // Update focus window. - D3D9RenderWindow* primaryRenderWindow = getPrimaryWindow(); - - // Case we have to share the same focus window. - if (msSharedFocusWindow != NULL) - mFocusWindow = msSharedFocusWindow; - else - mFocusWindow = primaryRenderWindow->getWindowHandle(); - - IDirect3D9* pD3D9 = D3D9RenderSystem::getDirect3D9(); - HRESULT hr; - - - if (isMultihead()) - { - mBehaviorFlags |= D3DCREATE_ADAPTERGROUP_DEVICE; - } - else - { - mBehaviorFlags &= ~D3DCREATE_ADAPTERGROUP_DEVICE; - } - - if(mPresentationParams->SwapEffect == D3DSWAPEFFECT_FLIPEX) - { - mBehaviorFlags |= D3DCREATE_ENABLE_PRESENTSTATS; - } - - - // Try to create the device with hardware vertex processing. - mBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; - hr = pD3D9->CreateDevice(mAdapterNumber, mDeviceType, mFocusWindow, - mBehaviorFlags, mPresentationParams, &mDevice); - - if (FAILED(hr)) - { - // Try a second time, may fail the first time due to back buffer count, - // which will be corrected down to 1 by the runtime - hr = pD3D9->CreateDevice(mAdapterNumber, mDeviceType, mFocusWindow, - mBehaviorFlags, mPresentationParams, &mDevice); - } - - // Case hardware vertex processing failed. - if( FAILED( hr ) ) - { - // Try to create the device with mixed vertex processing. - mBehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING; - mBehaviorFlags |= D3DCREATE_MIXED_VERTEXPROCESSING; - - hr = pD3D9->CreateDevice(mAdapterNumber, mDeviceType, mFocusWindow, - mBehaviorFlags, mPresentationParams, &mDevice); - } - - if( FAILED( hr ) ) - { - // try to create the device with software vertex processing. - mBehaviorFlags &= ~D3DCREATE_MIXED_VERTEXPROCESSING; - mBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; - hr = pD3D9->CreateDevice(mAdapterNumber, mDeviceType, mFocusWindow, - mBehaviorFlags, mPresentationParams, &mDevice); - } - - if ( FAILED( hr ) ) - { - // try reference device - mDeviceType = D3DDEVTYPE_REF; - hr = pD3D9->CreateDevice(mAdapterNumber, mDeviceType, mFocusWindow, - mBehaviorFlags, mPresentationParams, &mDevice); - - if ( FAILED( hr ) ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create device!", - "D3D9Device::createD3D9Device" ); - } - } - - // Get current device caps. - hr = mDevice->GetDeviceCaps(&mD3D9DeviceCaps); - if( FAILED( hr ) ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot get device caps!", - "D3D9Device::createD3D9Device" ); - } - - // Get current creation parameters caps. - hr = mDevice->GetCreationParameters(&mCreationParams); - if ( FAILED(hr) ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Error Get Creation Parameters", - "D3D9Device:createD3D9Device" ); - } - - mD3D9DeviceCapsValid = true; - - // Initialize device states. - setupDeviceStates(); - - // Lock access to rendering device. - D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); - - D3D9Device* pCurActiveDevice = mDeviceManager->getActiveDevice(); - - mDeviceManager->setActiveDevice(this); - - // Inform all resources that new device created. - D3D9RenderSystem::getResourceManager()->notifyOnDeviceCreate(mDevice); - - mDeviceManager->setActiveDevice(pCurActiveDevice); - - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - renderSystem->fireDeviceEvent(this, "DeviceCreated"); - - // UnLock access to rendering device. - D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); - } - - //--------------------------------------------------------------------- - void D3D9Device::releaseD3D9Device() - { - if (mDevice != NULL) - { - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - renderSystem->fireDeviceEvent(this, "DeviceReleased"); - - // Lock access to rendering device. - D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); - - D3D9Device* pCurActiveDevice = mDeviceManager->getActiveDevice(); - - mDeviceManager->setActiveDevice(this); - - // Inform all resources that device is going to be destroyed. - D3D9RenderSystem::getResourceManager()->notifyOnDeviceDestroy(mDevice); - - mDeviceManager->setActiveDevice(pCurActiveDevice); - - clearDeviceStreams(); - - // Release device. - SAFE_RELEASE(mDevice); - - // UnLock access to rendering device. - D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); - } - } - - //--------------------------------------------------------------------- - void D3D9Device::releaseRenderWindowResources(RenderWindowResources* renderWindowResources) - { - if( renderWindowResources->depthBuffer ) - { - D3D9RenderSystem* renderSystem = static_cast - (Root::getSingleton().getRenderSystem()); - renderSystem->_cleanupDepthBuffers( renderWindowResources->depthBuffer ); - } - - SAFE_RELEASE(renderWindowResources->backBuffer); - SAFE_RELEASE(renderWindowResources->depthBuffer); - SAFE_RELEASE(renderWindowResources->swapChain); - SAFE_RELEASE(renderWindowResources->swapChain9Ex); - renderWindowResources->acquired = false; - } - - //--------------------------------------------------------------------- - void D3D9Device::invalidate(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - - it->second->acquired = false; - } - - //--------------------------------------------------------------------- - bool D3D9Device::validate(D3D9RenderWindow* renderWindow) - { - // Validate that the render window should run on this device. - if (false == validateDisplayMonitor(renderWindow)) - return false; - - // Validate that this device created on the correct target focus window handle - validateFocusWindow(); - - // Validate that the render window dimensions matches to back buffer dimensions. - validateBackBufferSize(renderWindow); - - // Validate that this device is in valid rendering state. - if (false == validateDeviceState(renderWindow)) - return false; - - return true; - } - - //--------------------------------------------------------------------- - void D3D9Device::validateFocusWindow() - { - // Focus window changed -> device should be re-acquired. - if ((msSharedFocusWindow != NULL && mCreationParams.hFocusWindow != msSharedFocusWindow) || - (msSharedFocusWindow == NULL && mCreationParams.hFocusWindow != getPrimaryWindow()->getWindowHandle())) - { - // Lock access to rendering device. - D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); - - release(); - acquire(); - - // UnLock access to rendering device. - D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); - } - } - - //--------------------------------------------------------------------- - bool D3D9Device::validateDeviceState(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - RenderWindowResources* renderWindowResources = it->second; - HRESULT hr; - - hr = mDevice->TestCooperativeLevel(); - - // Case device is not valid for rendering. - if (FAILED(hr)) - { - // device lost, and we can't reset - // can't do anything about it here, wait until we get - // D3DERR_DEVICENOTRESET; rendering calls will silently fail until - // then (except Present, but we ignore device lost there too) - if (hr == D3DERR_DEVICELOST) - { - releaseRenderWindowResources(renderWindowResources); - notifyDeviceLost(); - return false; - } - - // device lost, and we can reset - else if (hr == D3DERR_DEVICENOTRESET) - { - bool deviceRestored = reset(); - - // Device was not restored yet. - if (deviceRestored == false) - { - // Wait a while - Sleep(50); - return false; - } - } - } - - // Render window resources explicitly invalidated. (Resize or window mode switch) - if (renderWindowResources->acquired == false) - { - if (getPrimaryWindow() == renderWindow) - { - bool deviceRestored = reset(); - - // Device was not restored yet. - if (deviceRestored == false) - { - // Wait a while - Sleep(50); - return false; - } - } - else - { - acquire(renderWindow); - } - } - - return true; - } - - - //--------------------------------------------------------------------- - void D3D9Device::validateBackBufferSize(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - RenderWindowResources* renderWindowResources = it->second; - - - // Case size has been changed. - if (renderWindow->getWidth() != renderWindowResources->presentParameters.BackBufferWidth || - renderWindow->getHeight() != renderWindowResources->presentParameters.BackBufferHeight) - { - if (renderWindow->getWidth() > 0) - renderWindowResources->presentParameters.BackBufferWidth = renderWindow->getWidth(); - - if (renderWindow->getHeight() > 0) - renderWindowResources->presentParameters.BackBufferHeight = renderWindow->getHeight(); - - invalidate(renderWindow); - } - } - - //--------------------------------------------------------------------- - bool D3D9Device::validateDisplayMonitor(D3D9RenderWindow* renderWindow) - { - // Ignore full screen since it doesn't really move and it is possible - // that it created using multi-head adapter so for a subordinate the - // native monitor handle and this device handle will be different. - if (renderWindow->isFullScreen()) - return true; - - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - HMONITOR hRenderWindowMonitor = NULL; - - // Find the monitor this render window belongs to. - hRenderWindowMonitor = MonitorFromWindow(renderWindow->getWindowHandle(), MONITOR_DEFAULTTONULL); - - // This window doesn't intersect with any of the display monitor - if (hRenderWindowMonitor == NULL) - return false; - - - // Case this window changed monitor. - if (hRenderWindowMonitor != mMonitor) - { - // Lock access to rendering device. - D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); - - mDeviceManager->linkRenderWindow(renderWindow); - - // UnLock access to rendering device. - D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); - - return false; - } - - return true; - } - - //--------------------------------------------------------------------- - void D3D9Device::present(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - RenderWindowResources* renderWindowResources = it->second; - - - // Skip present while current device state is invalid. - if (mDeviceLost || - renderWindowResources->acquired == false || - isDeviceLost()) - return; - - - HRESULT hr; - - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - renderSystem->fireDeviceEvent(this, "BeforeDevicePresent"); - - if (isMultihead()) - { - // Only the master will call present method results in synchronized - // buffer swap for the rest of the implicit swap chain. - if (getPrimaryWindow() == renderWindow) - hr = mDevice->Present( NULL, NULL, NULL, NULL ); - else - hr = S_OK; - } - else - { - hr = renderWindowResources->swapChain->Present(NULL, NULL, NULL, NULL, 0); - } - - - if( D3DERR_DEVICELOST == hr) - { - releaseRenderWindowResources(renderWindowResources); - notifyDeviceLost(); - } - else if( FAILED(hr) ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Error Presenting surfaces", - "D3D9Device::present" ); - } - else - mLastPresentFrame = Root::getSingleton().getNextFrameNumber(); - } - - //--------------------------------------------------------------------- - void D3D9Device::acquireRenderWindowResources(RenderWindowToResourcesIterator it) - { - RenderWindowResources* renderWindowResources = it->second; - D3D9RenderWindow* renderWindow = it->first; - - releaseRenderWindowResources(renderWindowResources); - - // Create additional swap chain - if (isSwapChainWindow(renderWindow) && !isMultihead()) - { - // Create swap chain - HRESULT hr = mDevice->CreateAdditionalSwapChain(&renderWindowResources->presentParameters, - &renderWindowResources->swapChain); - - if (FAILED(hr)) - { - // Try a second time, may fail the first time due to back buffer count, - // which will be corrected by the runtime - hr = mDevice->CreateAdditionalSwapChain(&renderWindowResources->presentParameters, - &renderWindowResources->swapChain); - } - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create an additional swap chain", - "D3D9RenderWindow::acquireRenderWindowResources"); - } - - renderWindowResources->swapChain9Ex = NULL; - } - else - { - // The swap chain is already created by the device - HRESULT hr = mDevice->GetSwapChain(renderWindowResources->presentParametersIndex, - &renderWindowResources->swapChain); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to get the swap chain", - "D3D9RenderWindow::acquireRenderWindowResources"); - } - - renderWindowResources->swapChain9Ex = NULL; - } - - // Store references to buffers for convenience - renderWindowResources->swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, - &renderWindowResources->backBuffer); - - // Additional swap chains need their own depth buffer - // to support resizing them - if (renderWindow->isDepthBuffered()) - { - // if multihead is enabled, depth buffer can be created automatically for - // all the adapters. if multihead is not enabled, depth buffer is just - // created for the main swap chain - if (isMultihead() && isAutoDepthStencil() || - isMultihead() == false && isSwapChainWindow(renderWindow) == false) - { - mDevice->GetDepthStencilSurface(&renderWindowResources->depthBuffer); - } - else - { - uint targetWidth = renderWindow->getWidth(); - uint targetHeight = renderWindow->getHeight(); - - if (targetWidth == 0) - targetWidth = 1; - - if (targetHeight == 0) - targetHeight = 1; - - HRESULT hr = mDevice->CreateDepthStencilSurface( - targetWidth, targetHeight, - renderWindowResources->presentParameters.AutoDepthStencilFormat, - renderWindowResources->presentParameters.MultiSampleType, - renderWindowResources->presentParameters.MultiSampleQuality, - (renderWindowResources->presentParameters.Flags & D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL), - &renderWindowResources->depthBuffer, NULL - ); - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create a depth buffer for the swap chain", - "D3D9RenderWindow::acquireRenderWindowResources"); - } - - if (isSwapChainWindow(renderWindow) == false) - { - mDevice->SetDepthStencilSurface(renderWindowResources->depthBuffer); - } - } - - if (renderWindowResources->depthBuffer) - { - //Tell the RS we have a depth buffer we created it needs to add to the default pool - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - DepthBuffer *depthBuf = renderSystem->_addManualDepthBuffer( mDevice, renderWindowResources->depthBuffer ); - - //Don't forget we want this window to use _this_ depth buffer - renderWindow->attachDepthBuffer( depthBuf ); - } - else - { - LogManager::getSingleton().logMessage("D3D9 : WARNING - Depth buffer could not be acquired."); - } - } - - renderWindowResources->acquired = true; - } - - //--------------------------------------------------------------------- - void D3D9Device::setupDeviceStates() - { - HRESULT hr = mDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE); - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to apply render state: D3DRS_SPECULARENABLE <- TRUE", - "D3D9Device::setupDeviceStates"); - } - } - - //--------------------------------------------------------------------- - bool D3D9Device::isSwapChainWindow(D3D9RenderWindow* renderWindow) - { - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - - if (it->second->presentParametersIndex == 0 || renderWindow->isFullScreen()) - return false; - - return true; - } - - //--------------------------------------------------------------------- - D3D9RenderWindow* D3D9Device::getPrimaryWindow() - { - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); - - while (it != mMapRenderWindowToResources.end() && it->second->presentParametersIndex != 0) - ++it; - - assert(it != mMapRenderWindowToResources.end()); - - return it->first; - } - - //--------------------------------------------------------------------- - void D3D9Device::setSharedWindowHandle(HWND hSharedHWND) - { - if (hSharedHWND != msSharedFocusWindow) - msSharedFocusWindow = hSharedHWND; - } - - //--------------------------------------------------------------------- - void D3D9Device::updateRenderWindowsIndices() - { - // Update present parameters index attribute per render window. - if (isMultihead()) - { - RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); - - // Multi head device case - - // Present parameter index is based on adapter ordinal in group index. - while (it != mMapRenderWindowToResources.end()) - { - it->second->presentParametersIndex = it->second->adapterOrdinalInGroupIndex; - ++it; - } - } - else - { - // Single head device case - - // Just assign index in incremental order - - // NOTE: It suppose to cover both cases that possible here: - // 1. Single full screen window - only one allowed per device (this is not multi-head case). - // 2. Multiple window mode windows. - - uint nextPresParamIndex = 0; - - RenderWindowToResourcesIterator it; - D3D9RenderWindow* deviceFocusWindow = NULL; - - // In case a d3d9 device exists - try to keep the present parameters order - // so that the window that the device is focused on will stay the same and we - // will avoid device re-creation. - if (mDevice != NULL) - { - it = mMapRenderWindowToResources.begin(); - while (it != mMapRenderWindowToResources.end()) - { - //This "if" handles the common case of a single device - if (it->first->getWindowHandle() == mCreationParams.hFocusWindow) - { - deviceFocusWindow = it->first; - it->second->presentParametersIndex = nextPresParamIndex; - ++nextPresParamIndex; - break; - } - //This "if" handles multiple devices when a shared window is used - if ((it->second->presentParametersIndex == 0) && (it->second->acquired == true)) - { - deviceFocusWindow = it->first; - ++nextPresParamIndex; - } - ++it; - } - } - - - - it = mMapRenderWindowToResources.begin(); - while (it != mMapRenderWindowToResources.end()) - { - if (it->first != deviceFocusWindow) - { - it->second->presentParametersIndex = nextPresParamIndex; - ++nextPresParamIndex; - } - ++it; - } - } - } - //--------------------------------------------------------------------- - void D3D9Device::copyContentsToMemory(D3D9RenderWindow* renderWindow, - const PixelBox &dst, RenderTarget::FrameBuffer buffer) - { - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - RenderWindowResources* resources = it->second; - bool swapChain = isSwapChainWindow(renderWindow); - - - - if ((dst.left < 0) || (dst.right > renderWindow->getWidth()) || - (dst.top < 0) || (dst.bottom > renderWindow->getHeight()) || - (dst.front != 0) || (dst.back != 1)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid box.", - "D3D9Device::copyContentsToMemory" ); - } - - HRESULT hr; - IDirect3DSurface9* pSurf = NULL; - IDirect3DSurface9* pTempSurf = NULL; - D3DSURFACE_DESC desc; - D3DLOCKED_RECT lockedRect; - - - if (buffer == RenderTarget::FB_AUTO) - { - //buffer = mIsFullScreen? FB_FRONT : FB_BACK; - buffer = RenderTarget::FB_BACK; - } - - if (buffer == RenderTarget::FB_FRONT) - { - D3DDISPLAYMODE dm; - - if (FAILED(hr = mDevice->GetDisplayMode(0, &dm))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't get display mode: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - - desc.Width = dm.Width; - desc.Height = dm.Height; - desc.Format = D3DFMT_A8R8G8B8; - if (FAILED(hr = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, - desc.Format, - D3DPOOL_SYSTEMMEM, - &pTempSurf, - 0))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't create offscreen buffer: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - - if (FAILED(hr = swapChain ? resources->swapChain->GetFrontBufferData(pTempSurf) : - mDevice->GetFrontBufferData(0, pTempSurf))) - { - SAFE_RELEASE(pTempSurf); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't get front buffer: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - - if(renderWindow->isFullScreen()) - { - if ((dst.left == 0) && (dst.right == renderWindow->getWidth()) && (dst.top == 0) && (dst.bottom == renderWindow->getHeight())) - { - hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); - } - else - { - RECT rect; - - rect.left = static_cast(dst.left); - rect.right = static_cast(dst.right); - rect.top = static_cast(dst.top); - rect.bottom = static_cast(dst.bottom); - - hr = pTempSurf->LockRect(&lockedRect, &rect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); - } - if (FAILED(hr)) - { - SAFE_RELEASE(pTempSurf); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't lock rect: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - } - else - { - RECT srcRect; - //GetClientRect(mHWnd, &srcRect); - srcRect.left = static_cast(dst.left); - srcRect.top = static_cast(dst.top); - srcRect.right = static_cast(dst.right); - srcRect.bottom = static_cast(dst.bottom); - POINT point; - point.x = srcRect.left; - point.y = srcRect.top; - ClientToScreen(renderWindow->getWindowHandle(), &point); - srcRect.top = point.y; - srcRect.left = point.x; - srcRect.bottom += point.y; - srcRect.right += point.x; - - desc.Width = srcRect.right - srcRect.left; - desc.Height = srcRect.bottom - srcRect.top; - - if (FAILED(hr = pTempSurf->LockRect(&lockedRect, &srcRect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK))) - { - SAFE_RELEASE(pTempSurf); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't lock rect: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - } - } - else - { - SAFE_RELEASE(pSurf); - if(FAILED(hr = swapChain? resources->swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurf) : - mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurf))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't get back buffer: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - - if(FAILED(hr = pSurf->GetDesc(&desc))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't get description: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - - if (FAILED(hr = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, - desc.Format, - D3DPOOL_SYSTEMMEM, - &pTempSurf, - 0))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't create offscreen surface: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - - if (desc.MultiSampleType == D3DMULTISAMPLE_NONE) - { - if (FAILED(hr = mDevice->GetRenderTargetData(pSurf, pTempSurf))) - { - SAFE_RELEASE(pTempSurf); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't get render target data: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - } - else - { - IDirect3DSurface9* pStretchSurf = 0; - - if (FAILED(hr = mDevice->CreateRenderTarget(desc.Width, desc.Height, - desc.Format, - D3DMULTISAMPLE_NONE, - 0, - false, - &pStretchSurf, - 0))) - { - SAFE_RELEASE(pTempSurf); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't create render target: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - - if (FAILED(hr = mDevice->StretchRect(pSurf, 0, pStretchSurf, 0, D3DTEXF_NONE))) - { - SAFE_RELEASE(pTempSurf); - SAFE_RELEASE(pStretchSurf); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't stretch rect: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - if (FAILED(hr = mDevice->GetRenderTargetData(pStretchSurf, pTempSurf))) - { - SAFE_RELEASE(pTempSurf); - SAFE_RELEASE(pStretchSurf); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't get render target data: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - SAFE_RELEASE(pStretchSurf); - } - - if ((dst.left == 0) && (dst.right == renderWindow->getWidth()) && (dst.top == 0) && (dst.bottom == renderWindow->getHeight())) - { - hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); - } - else - { - RECT rect; - - rect.left = static_cast(dst.left); - rect.right = static_cast(dst.right); - rect.top = static_cast(dst.top); - rect.bottom = static_cast(dst.bottom); - - hr = pTempSurf->LockRect(&lockedRect, &rect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); - } - if (FAILED(hr)) - { - SAFE_RELEASE(pTempSurf); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't lock rect: " + Root::getSingleton().getErrorDescription(hr), - "D3D9Device::copyContentsToMemory"); - } - } - - PixelFormat format = Ogre::D3D9Mappings::_getPF(desc.Format); - - if (format == PF_UNKNOWN) - { - SAFE_RELEASE(pTempSurf); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unsupported format", "D3D9Device::copyContentsToMemory"); - } - - PixelBox src(dst.getWidth(), dst.getHeight(), 1, format, lockedRect.pBits); - src.rowPitch = lockedRect.Pitch / PixelUtil::getNumElemBytes(format); - src.slicePitch = desc.Height * src.rowPitch; - - PixelUtil::bulkPixelConversion(src, dst); - - SAFE_RELEASE(pTempSurf); - SAFE_RELEASE(pSurf); - - - } - - int D3D9Device::getVBlankMissCount(D3D9RenderWindow* renderWindow) - { - // the stat only works with no AA, VSync and 9Ex. - if(renderWindow->isAA() || - renderWindow->isVSyncEnabled() == false || - D3D9RenderSystem::isDirectX9Ex() == false) - { - return -1; - } - - RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); - RenderWindowResources* renderWindowResources = it->second; - - // The 9Ex swap chain is set to NULL when we create the RenderWindowResources, now we need it - // to get the stats - so we try to get it from the original d3d9 swap chain by using - // COM's QueryInterface - if(renderWindowResources->swapChain9Ex == NULL) - { - if (FAILED(renderWindowResources->swapChain->QueryInterface(IID_IDirect3DSwapChain9Ex, (void**)&renderWindowResources->swapChain9Ex))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Can't get Direct3DSwapChain9Ex from Direct3DSwapChain.", - "D3D9Device::getVBlankMissCount"); - } - } - - // Get Present Stats info for glitch detection - D3DPRESENTSTATS currentPresentStats; - ZeroMemory(¤tPresentStats, sizeof(currentPresentStats)); - // Obtain present statistics information for successfully displayed presents - HRESULT hr = renderWindowResources->swapChain9Ex->GetPresentStats(¤tPresentStats); - - // check if the call to GetPresentStats got us the stats - if(FAILED(hr) || currentPresentStats.PresentRefreshCount == 0) - { - mPreviousPresentStatsIsValid = false; - } - else - { - if(mPreviousPresentStatsIsValid == true) - { - // add the vblank misses since the last call to getVBlankMissCount - int currentVBlankMissCount = (currentPresentStats.PresentRefreshCount - mPreviousPresentStats.PresentRefreshCount) - - (currentPresentStats.PresentCount - mPreviousPresentStats.PresentCount); - - if(currentVBlankMissCount > 0) - { - mVBlankMissCount += currentVBlankMissCount; - } - } - - // save the current to be the next time previous - mPreviousPresentStats = currentPresentStats; - mPreviousPresentStatsIsValid = true; - } - - return mVBlankMissCount; - } + HWND D3D9Device::msSharedFocusWindow = NULL; + + //--------------------------------------------------------------------- + D3D9Device::D3D9Device(D3D9DeviceManager* deviceManager, + UINT adapterNumber, + HMONITOR hMonitor, + D3DDEVTYPE devType, + DWORD behaviorFlags) + { + mDeviceManager = deviceManager; + mDevice = NULL; + mAdapterNumber = adapterNumber; + mMonitor = hMonitor; + mDeviceType = devType; + mFocusWindow = NULL; + mBehaviorFlags = behaviorFlags; + mD3D9DeviceCapsValid = false; + mDeviceLost = false; + mPresentationParamsCount = 0; + mPresentationParams = NULL; + memset(&mD3D9DeviceCaps, 0, sizeof(mD3D9DeviceCaps)); + memset(&mCreationParams, 0, sizeof(mCreationParams)); + memset(&mPreviousPresentStats, 0, sizeof(mPreviousPresentStats)); + mPreviousPresentStatsIsValid = false; + mVBlankMissCount = 0; + } + + //--------------------------------------------------------------------- + D3D9Device::~D3D9Device() + { + + } + + //--------------------------------------------------------------------- + D3D9Device::RenderWindowToResourcesIterator D3D9Device::getRenderWindowIterator(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.find(renderWindow); + + if (it == mMapRenderWindowToResources.end()) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Render window was not attached to this device !!", + "D3D9Device::getRenderWindowIterator" ); + } + + return it; + } + + + //--------------------------------------------------------------------- + void D3D9Device::attachRenderWindow(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.find(renderWindow); + + if (it == mMapRenderWindowToResources.end()) + { + RenderWindowResources* renderWindowResources = OGRE_NEW_T(RenderWindowResources, MEMCATEGORY_RENDERSYS); + + memset(renderWindowResources, 0, sizeof(RenderWindowResources)); + renderWindowResources->adapterOrdinalInGroupIndex = 0; + renderWindowResources->acquired = false; + mMapRenderWindowToResources[renderWindow] = renderWindowResources; + } + updateRenderWindowsIndices(); + } + + //--------------------------------------------------------------------- + void D3D9Device::detachRenderWindow(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.find(renderWindow); + + if (it != mMapRenderWindowToResources.end()) + { + // The focus window in which the d3d9 device created on is detached. + // resources must be acquired again. + if (mFocusWindow == renderWindow->getWindowHandle()) + { + mFocusWindow = NULL; + } + + // Case this is the shared focus window. + if (renderWindow->getWindowHandle() == msSharedFocusWindow) + setSharedWindowHandle(NULL); + + RenderWindowResources* renderWindowResources = it->second; + + releaseRenderWindowResources(renderWindowResources); + + OGRE_DELETE_T(renderWindowResources, RenderWindowResources, MEMCATEGORY_RENDERSYS); + + mMapRenderWindowToResources.erase(it); + } + updateRenderWindowsIndices(); + } + + //--------------------------------------------------------------------- + bool D3D9Device::acquire() + { + updatePresentationParameters(); + + bool resetDevice = false; + + // Create device if need to. + if (mDevice == NULL) + { + createD3D9Device(); + } + + // Case device already exists. + else + { + RenderWindowToResourcesIterator itPrimary = getRenderWindowIterator(getPrimaryWindow()); + + if (itPrimary->second->swapChain != NULL) + { + D3DPRESENT_PARAMETERS currentPresentParams; + HRESULT hr; + + hr = itPrimary->second->swapChain->GetPresentParameters(¤tPresentParams); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "GetPresentParameters failed", + "D3D9RenderWindow::acquire"); + } + + // Desired parameters are different then current parameters. + // Possible scenario is that primary window resized and in the mean while another + // window attached to this device. + if (memcmp(¤tPresentParams, &mPresentationParams[0], sizeof(D3DPRESENT_PARAMETERS)) != 0) + { + resetDevice = true; + } + } + + // Make sure depth stencil is set to valid surface. It is going to be + // grabbed by the primary window using the GetDepthStencilSurface method. + if (resetDevice == false) + { + mDevice->SetDepthStencilSurface(itPrimary->second->depthBuffer); + } + + } + + // Reset device will update all render window resources. + if (resetDevice) + { + reset(); + } + + // No need to reset -> just acquire resources. + else + { + // Update resources of each window. + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); + + while (it != mMapRenderWindowToResources.end()) + { + acquireRenderWindowResources(it); + ++it; + } + } + + return true; + } + + //--------------------------------------------------------------------- + void D3D9Device::release() + { + if (mDevice != NULL) + { + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); + + while (it != mMapRenderWindowToResources.end()) + { + RenderWindowResources* renderWindowResources = it->second; + + releaseRenderWindowResources(renderWindowResources); + ++it; + } + + releaseD3D9Device(); + } + } + + //--------------------------------------------------------------------- + bool D3D9Device::acquire(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + + acquireRenderWindowResources(it); + + return true; + } + + //--------------------------------------------------------------------- + void D3D9Device::notifyDeviceLost() + { + // Case this device is already in lost state. + if (mDeviceLost) + return; + + // Case we just moved from valid state to lost state. + mDeviceLost = true; + + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + + renderSystem->notifyOnDeviceLost(this); + } + + //--------------------------------------------------------------------- + IDirect3DSurface9* D3D9Device::getDepthBuffer(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + + return it->second->depthBuffer; + } + + //--------------------------------------------------------------------- + IDirect3DSurface9* D3D9Device::getBackBuffer(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + + return it->second->backBuffer; + } + + //--------------------------------------------------------------------- + uint D3D9Device::getRenderWindowCount() const + { + return static_cast(mMapRenderWindowToResources.size()); + } + + //--------------------------------------------------------------------- + D3D9RenderWindow* D3D9Device::getRenderWindow(uint index) + { + if (index >= mMapRenderWindowToResources.size()) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Index of render window is out of bounds!", + "D3D9RenderWindow::getRenderWindow"); + } + + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); + + while (it != mMapRenderWindowToResources.end()) + { + if (index == 0) + break; + + --index; + ++it; + } + + return it->first; + } + + //--------------------------------------------------------------------- + void D3D9Device::setAdapterOrdinalIndex(D3D9RenderWindow* renderWindow, uint adapterOrdinalInGroupIndex) + { + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + + it->second->adapterOrdinalInGroupIndex = adapterOrdinalInGroupIndex; + + updateRenderWindowsIndices(); + } + + //--------------------------------------------------------------------- + void D3D9Device::destroy() + { + // Lock access to rendering device. + D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); + + //Remove _all_ depth buffers created by this device + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + renderSystem->_cleanupDepthBuffers( mDevice ); + + release(); + + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); + + while (it != mMapRenderWindowToResources.end()) + { + if (it->first->getWindowHandle() == msSharedFocusWindow) + setSharedWindowHandle(NULL); + + OGRE_DELETE_T(it->second, RenderWindowResources, MEMCATEGORY_RENDERSYS); + ++it; + } + mMapRenderWindowToResources.clear(); + + // Reset dynamic attributes. + mFocusWindow = NULL; + mD3D9DeviceCapsValid = false; + + if (mPresentationParams != NULL) + { + OGRE_FREE (mPresentationParams, MEMCATEGORY_RENDERSYS); + mPresentationParams = NULL; + } + mPresentationParamsCount = 0; + + // Notify the device manager on this instance destruction. + mDeviceManager->notifyOnDeviceDestroy(this); + + // UnLock access to rendering device. + D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); + } + + //--------------------------------------------------------------------- + bool D3D9Device::isDeviceLost() + { + HRESULT hr; + + hr = mDevice->TestCooperativeLevel(); + + if (hr == D3DERR_DEVICELOST || + hr == D3DERR_DEVICENOTRESET) + { + return true; + } + + return false; + } + + //--------------------------------------------------------------------- + bool D3D9Device::reset() + { + HRESULT hr; + + // Check that device is in valid state for reset. + hr = mDevice->TestCooperativeLevel(); + if (hr == D3DERR_DEVICELOST || + hr == D3DERR_DRIVERINTERNALERROR) + { + return false; + } + + // Lock access to rendering device. + D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); + + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + + // Inform all resources that device lost. + D3D9RenderSystem::getResourceManager()->notifyOnDeviceLost(mDevice); + + // Notify all listener before device is rested + renderSystem->notifyOnDeviceLost(this); + + // Release all automatic temporary buffers and free unused + // temporary buffers, so we doesn't need to recreate them, + // and they will reallocate on demand. This save a lot of + // release/recreate of non-managed vertex buffers which + // wasn't need at all. + HardwareBufferManager::getSingleton()._releaseBufferCopies(true); + + + // Cleanup depth stencils surfaces. + renderSystem->_cleanupDepthBuffers(); + + updatePresentationParameters(); + + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); + + while (it != mMapRenderWindowToResources.end()) + { + RenderWindowResources* renderWindowResources = it->second; + + releaseRenderWindowResources(renderWindowResources); + ++it; + } + + clearDeviceStreams(); + + renderSystem->fireDeviceEvent(this, "BeforeDeviceReset"); + + // Reset the device using the presentation parameters. + hr = mDevice->Reset(mPresentationParams); + + renderSystem->fireDeviceEvent(this, "AfterDeviceReset"); + + if (hr == D3DERR_DEVICELOST) + { + // UnLock access to rendering device. + D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); + + // Don't continue + return false; + } + else if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot reset device!", + "D3D9RenderWindow::reset"); + } + + mDeviceLost = false; + + // Initialize device states. + setupDeviceStates(); + + // Update resources of each window. + it = mMapRenderWindowToResources.begin(); + + while (it != mMapRenderWindowToResources.end()) + { + acquireRenderWindowResources(it); + ++it; + } + + D3D9Device* pCurActiveDevice = mDeviceManager->getActiveDevice(); + + mDeviceManager->setActiveDevice(this); + + // Inform all resources that device has been reset. + D3D9RenderSystem::getResourceManager()->notifyOnDeviceReset(mDevice); + + mDeviceManager->setActiveDevice(pCurActiveDevice); + + renderSystem->notifyOnDeviceReset(this); + + // UnLock access to rendering device. + D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); + + return true; + } + + //--------------------------------------------------------------------- + bool D3D9Device::isAutoDepthStencil() const + { + const D3DPRESENT_PARAMETERS& primaryPresentationParams = mPresentationParams[0]; + + // Check if auto depth stencil can be used. + for (unsigned int i = 1; i < mPresentationParamsCount; i++) + { + // disable AutoDepthStencil if these parameters are not all the same. + if(primaryPresentationParams.BackBufferHeight != mPresentationParams[i].BackBufferHeight || + primaryPresentationParams.BackBufferWidth != mPresentationParams[i].BackBufferWidth || + primaryPresentationParams.BackBufferFormat != mPresentationParams[i].BackBufferFormat || + primaryPresentationParams.AutoDepthStencilFormat != mPresentationParams[i].AutoDepthStencilFormat || + primaryPresentationParams.MultiSampleQuality != mPresentationParams[i].MultiSampleQuality || + primaryPresentationParams.MultiSampleType != mPresentationParams[i].MultiSampleType) + { + return false; + } + } + + return true; + } + + //--------------------------------------------------------------------- + bool D3D9Device::isFullScreen() const + { + if (mPresentationParamsCount > 0 && mPresentationParams[0].Windowed == FALSE) + return true; + + return false; + } + + //--------------------------------------------------------------------- + const D3DCAPS9& D3D9Device::getD3D9DeviceCaps() const + { + if (mD3D9DeviceCapsValid == false) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Device caps are invalid!", + "D3D9Device::getD3D9DeviceCaps" ); + } + + return mD3D9DeviceCaps; + } + + //--------------------------------------------------------------------- + D3DFORMAT D3D9Device::getBackBufferFormat() const + { + if (mPresentationParams == NULL || mPresentationParamsCount == 0) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Presentation parameters are invalid!", + "D3D9Device::getBackBufferFormat" ); + } + + return mPresentationParams[0].BackBufferFormat; + } + + //--------------------------------------------------------------------- + IDirect3DDevice9* D3D9Device::getD3D9Device() + { + return mDevice; + } + + //--------------------------------------------------------------------- + void D3D9Device::updatePresentationParameters() + { + // Clear old presentation parameters. + if (mPresentationParams != NULL) + { + OGRE_FREE (mPresentationParams, MEMCATEGORY_RENDERSYS); + mPresentationParams = NULL; + } + mPresentationParamsCount = 0; + + if (mMapRenderWindowToResources.size() > 0) + { + mPresentationParams = OGRE_ALLOC_T(D3DPRESENT_PARAMETERS, mMapRenderWindowToResources.size(), MEMCATEGORY_RENDERSYS); + + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); + + while (it != mMapRenderWindowToResources.end()) + { + D3D9RenderWindow* renderWindow = it->first; + RenderWindowResources* renderWindowResources = it->second; + + // Ask the render window to build it's own parameters. + renderWindow->buildPresentParameters(&renderWindowResources->presentParameters); + + + // Update shared focus window handle. + if (renderWindow->isFullScreen() && + renderWindowResources->presentParametersIndex == 0 && + msSharedFocusWindow == NULL) + setSharedWindowHandle(renderWindow->getWindowHandle()); + + // This is the primary window or a full screen window that is part of multi head device. + if (renderWindowResources->presentParametersIndex == 0 || + renderWindow->isFullScreen()) + { + mPresentationParams[renderWindowResources->presentParametersIndex] = renderWindowResources->presentParameters; + mPresentationParamsCount++; + } + + ++it; + } + } + + // Case we have to cancel auto depth stencil. + if (isMultihead() && isAutoDepthStencil() == false) + { + for(unsigned int i = 0; i < mPresentationParamsCount; i++) + { + mPresentationParams[i].EnableAutoDepthStencil = false; + } + } + } + + //--------------------------------------------------------------------- + UINT D3D9Device::getAdapterNumber() const + { + return mAdapterNumber; + } + + //--------------------------------------------------------------------- + D3DDEVTYPE D3D9Device::getDeviceType() const + { + return mDeviceType; + } + + //--------------------------------------------------------------------- + bool D3D9Device::isMultihead() const + { + RenderWindowToResourcesMap::const_iterator it = mMapRenderWindowToResources.begin(); + + while (it != mMapRenderWindowToResources.end()) + { + RenderWindowResources* renderWindowResources = it->second; + + if (renderWindowResources->adapterOrdinalInGroupIndex > 0 && + it->first->isFullScreen()) + { + return true; + } + + ++it; + } + + return false; + } + + //--------------------------------------------------------------------- + void D3D9Device::clearDeviceStreams() + { + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + + // Set all texture units to nothing to release texture surfaces + for (DWORD stage = 0; stage < mD3D9DeviceCaps.MaxSimultaneousTextures; ++stage) + { + DWORD dwCurValue = D3DTOP_FORCE_DWORD; + HRESULT hr; + + hr = mDevice->SetTexture(stage, NULL); + if( hr != S_OK ) + { + String str = "Unable to disable texture '" + StringConverter::toString((unsigned int)stage) + "' in D3D9"; + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9Device::clearDeviceStreams" ); + } + + mDevice->GetTextureStageState(static_cast(stage), D3DTSS_COLOROP, &dwCurValue); + + if (dwCurValue != D3DTOP_DISABLE) + { + hr = mDevice->SetTextureStageState(static_cast(stage), D3DTSS_COLOROP, D3DTOP_DISABLE); + if( hr != S_OK ) + { + String str = "Unable to disable texture '" + StringConverter::toString((unsigned)stage) + "' in D3D9"; + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9Device::clearDeviceStreams" ); + } + } + + + // set stage desc. to defaults + renderSystem->mTexStageDesc[stage].pTex = 0; + renderSystem->mTexStageDesc[stage].autoTexCoordType = TEXCALC_NONE; + renderSystem->mTexStageDesc[stage].coordIndex = 0; + renderSystem->mTexStageDesc[stage].texType = D3D9Mappings::D3D_TEX_TYPE_NORMAL; + } + + // Unbind any vertex streams to avoid memory leaks + for (unsigned int i = 0; i < mD3D9DeviceCaps.MaxStreams; ++i) + { + mDevice->SetStreamSource(i, NULL, 0, 0); + } + } + + //--------------------------------------------------------------------- + void D3D9Device::createD3D9Device() + { + // Update focus window. + D3D9RenderWindow* primaryRenderWindow = getPrimaryWindow(); + + // Case we have to share the same focus window. + if (msSharedFocusWindow != NULL) + mFocusWindow = msSharedFocusWindow; + else + mFocusWindow = primaryRenderWindow->getWindowHandle(); + + IDirect3D9* pD3D9 = D3D9RenderSystem::getDirect3D9(); + HRESULT hr; + + + if (isMultihead()) + { + mBehaviorFlags |= D3DCREATE_ADAPTERGROUP_DEVICE; + } + else + { + mBehaviorFlags &= ~D3DCREATE_ADAPTERGROUP_DEVICE; + } + + if(mPresentationParams->SwapEffect == D3DSWAPEFFECT_FLIPEX) + { + mBehaviorFlags |= D3DCREATE_ENABLE_PRESENTSTATS; + } + + + // Try to create the device with hardware vertex processing. + mBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; + hr = pD3D9->CreateDevice(mAdapterNumber, mDeviceType, mFocusWindow, + mBehaviorFlags, mPresentationParams, &mDevice); + + if (FAILED(hr)) + { + // Try a second time, may fail the first time due to back buffer count, + // which will be corrected down to 1 by the runtime + hr = pD3D9->CreateDevice(mAdapterNumber, mDeviceType, mFocusWindow, + mBehaviorFlags, mPresentationParams, &mDevice); + } + + // Case hardware vertex processing failed. + if( FAILED( hr ) ) + { + // Try to create the device with mixed vertex processing. + mBehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING; + mBehaviorFlags |= D3DCREATE_MIXED_VERTEXPROCESSING; + + hr = pD3D9->CreateDevice(mAdapterNumber, mDeviceType, mFocusWindow, + mBehaviorFlags, mPresentationParams, &mDevice); + } + + if( FAILED( hr ) ) + { + // try to create the device with software vertex processing. + mBehaviorFlags &= ~D3DCREATE_MIXED_VERTEXPROCESSING; + mBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; + hr = pD3D9->CreateDevice(mAdapterNumber, mDeviceType, mFocusWindow, + mBehaviorFlags, mPresentationParams, &mDevice); + } + + if ( FAILED( hr ) ) + { + // try reference device + mDeviceType = D3DDEVTYPE_REF; + hr = pD3D9->CreateDevice(mAdapterNumber, mDeviceType, mFocusWindow, + mBehaviorFlags, mPresentationParams, &mDevice); + + if ( FAILED( hr ) ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create device!", + "D3D9Device::createD3D9Device" ); + } + } + + // Get current device caps. + hr = mDevice->GetDeviceCaps(&mD3D9DeviceCaps); + if( FAILED( hr ) ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot get device caps!", + "D3D9Device::createD3D9Device" ); + } + + // Get current creation parameters caps. + hr = mDevice->GetCreationParameters(&mCreationParams); + if ( FAILED(hr) ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Error Get Creation Parameters", + "D3D9Device:createD3D9Device" ); + } + + mD3D9DeviceCapsValid = true; + + // Initialize device states. + setupDeviceStates(); + + // Lock access to rendering device. + D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); + + D3D9Device* pCurActiveDevice = mDeviceManager->getActiveDevice(); + + mDeviceManager->setActiveDevice(this); + + // Inform all resources that new device created. + D3D9RenderSystem::getResourceManager()->notifyOnDeviceCreate(mDevice); + + mDeviceManager->setActiveDevice(pCurActiveDevice); + + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + renderSystem->fireDeviceEvent(this, "DeviceCreated"); + + // UnLock access to rendering device. + D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); + } + + //--------------------------------------------------------------------- + void D3D9Device::releaseD3D9Device() + { + if (mDevice != NULL) + { + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + renderSystem->fireDeviceEvent(this, "DeviceReleased"); + + // Lock access to rendering device. + D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); + + D3D9Device* pCurActiveDevice = mDeviceManager->getActiveDevice(); + + mDeviceManager->setActiveDevice(this); + + // Inform all resources that device is going to be destroyed. + D3D9RenderSystem::getResourceManager()->notifyOnDeviceDestroy(mDevice); + + mDeviceManager->setActiveDevice(pCurActiveDevice); + + clearDeviceStreams(); + + // Release device. + SAFE_RELEASE(mDevice); + + // UnLock access to rendering device. + D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); + } + } + + //--------------------------------------------------------------------- + void D3D9Device::releaseRenderWindowResources(RenderWindowResources* renderWindowResources) + { + if( renderWindowResources->depthBuffer ) + { + D3D9RenderSystem* renderSystem = static_cast + (Root::getSingleton().getRenderSystem()); + renderSystem->_cleanupDepthBuffers( renderWindowResources->depthBuffer ); + } + + SAFE_RELEASE(renderWindowResources->backBuffer); + SAFE_RELEASE(renderWindowResources->depthBuffer); + SAFE_RELEASE(renderWindowResources->swapChain); + SAFE_RELEASE(renderWindowResources->swapChain9Ex); + renderWindowResources->acquired = false; + } + + //--------------------------------------------------------------------- + void D3D9Device::invalidate(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + + it->second->acquired = false; + } + + //--------------------------------------------------------------------- + bool D3D9Device::validate(D3D9RenderWindow* renderWindow) + { + // Validate that the render window should run on this device. + if (false == validateDisplayMonitor(renderWindow)) + return false; + + // Validate that this device created on the correct target focus window handle + validateFocusWindow(); + + // Validate that the render window dimensions matches to back buffer dimensions. + validateBackBufferSize(renderWindow); + + // Validate that this device is in valid rendering state. + if (false == validateDeviceState(renderWindow)) + return false; + + return true; + } + + //--------------------------------------------------------------------- + void D3D9Device::validateFocusWindow() + { + // Focus window changed -> device should be re-acquired. + if ((msSharedFocusWindow != NULL && mCreationParams.hFocusWindow != msSharedFocusWindow) || + (msSharedFocusWindow == NULL && mCreationParams.hFocusWindow != getPrimaryWindow()->getWindowHandle())) + { + // Lock access to rendering device. + D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); + + release(); + acquire(); + + // UnLock access to rendering device. + D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); + } + } + + //--------------------------------------------------------------------- + bool D3D9Device::validateDeviceState(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + RenderWindowResources* renderWindowResources = it->second; + HRESULT hr; + + hr = mDevice->TestCooperativeLevel(); + + // Case device is not valid for rendering. + if (FAILED(hr)) + { + // device lost, and we can't reset + // can't do anything about it here, wait until we get + // D3DERR_DEVICENOTRESET; rendering calls will silently fail until + // then (except Present, but we ignore device lost there too) + if (hr == D3DERR_DEVICELOST) + { + releaseRenderWindowResources(renderWindowResources); + notifyDeviceLost(); + return false; + } + + // device lost, and we can reset + else if (hr == D3DERR_DEVICENOTRESET) + { + bool deviceRestored = reset(); + + // Device was not restored yet. + if (deviceRestored == false) + { + // Wait a while + Sleep(50); + return false; + } + } + } + + // Render window resources explicitly invalidated. (Resize or window mode switch) + if (renderWindowResources->acquired == false) + { + if (getPrimaryWindow() == renderWindow) + { + bool deviceRestored = reset(); + + // Device was not restored yet. + if (deviceRestored == false) + { + // Wait a while + Sleep(50); + return false; + } + } + else + { + acquire(renderWindow); + } + } + + return true; + } + + + //--------------------------------------------------------------------- + void D3D9Device::validateBackBufferSize(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + RenderWindowResources* renderWindowResources = it->second; + + + // Case size has been changed. + if (renderWindow->getWidth() != renderWindowResources->presentParameters.BackBufferWidth || + renderWindow->getHeight() != renderWindowResources->presentParameters.BackBufferHeight) + { + if (renderWindow->getWidth() > 0) + renderWindowResources->presentParameters.BackBufferWidth = renderWindow->getWidth(); + + if (renderWindow->getHeight() > 0) + renderWindowResources->presentParameters.BackBufferHeight = renderWindow->getHeight(); + + invalidate(renderWindow); + } + } + + //--------------------------------------------------------------------- + bool D3D9Device::validateDisplayMonitor(D3D9RenderWindow* renderWindow) + { + // Ignore full screen since it doesn't really move and it is possible + // that it created using multi-head adapter so for a subordinate the + // native monitor handle and this device handle will be different. + if (renderWindow->isFullScreen()) + return true; + + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + HMONITOR hRenderWindowMonitor = NULL; + + // Find the monitor this render window belongs to. + hRenderWindowMonitor = MonitorFromWindow(renderWindow->getWindowHandle(), MONITOR_DEFAULTTONULL); + + // This window doesn't intersect with any of the display monitor + if (hRenderWindowMonitor == NULL) + return false; + + + // Case this window changed monitor. + if (hRenderWindowMonitor != mMonitor) + { + // Lock access to rendering device. + D3D9RenderSystem::getResourceManager()->lockDeviceAccess(); + + mDeviceManager->linkRenderWindow(renderWindow); + + // UnLock access to rendering device. + D3D9RenderSystem::getResourceManager()->unlockDeviceAccess(); + + return false; + } + + return true; + } + + //--------------------------------------------------------------------- + void D3D9Device::present(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + RenderWindowResources* renderWindowResources = it->second; + + + // Skip present while current device state is invalid. + if (mDeviceLost || + renderWindowResources->acquired == false || + isDeviceLost()) + return; + + + HRESULT hr; + + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + renderSystem->fireDeviceEvent(this, "BeforeDevicePresent"); + + if (isMultihead()) + { + // Only the master will call present method results in synchronized + // buffer swap for the rest of the implicit swap chain. + if (getPrimaryWindow() == renderWindow) + hr = mDevice->Present( NULL, NULL, NULL, NULL ); + else + hr = S_OK; + } + else + { + hr = renderWindowResources->swapChain->Present(NULL, NULL, NULL, NULL, 0); + } + + + if( D3DERR_DEVICELOST == hr) + { + releaseRenderWindowResources(renderWindowResources); + notifyDeviceLost(); + } + else if( FAILED(hr) ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Error Presenting surfaces", + "D3D9Device::present" ); + } + else + mLastPresentFrame = Root::getSingleton().getNextFrameNumber(); + } + + //--------------------------------------------------------------------- + void D3D9Device::acquireRenderWindowResources(RenderWindowToResourcesIterator it) + { + RenderWindowResources* renderWindowResources = it->second; + D3D9RenderWindow* renderWindow = it->first; + + releaseRenderWindowResources(renderWindowResources); + + // Create additional swap chain + if (isSwapChainWindow(renderWindow) && !isMultihead()) + { + // Create swap chain + HRESULT hr = mDevice->CreateAdditionalSwapChain(&renderWindowResources->presentParameters, + &renderWindowResources->swapChain); + + if (FAILED(hr)) + { + // Try a second time, may fail the first time due to back buffer count, + // which will be corrected by the runtime + hr = mDevice->CreateAdditionalSwapChain(&renderWindowResources->presentParameters, + &renderWindowResources->swapChain); + } + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create an additional swap chain", + "D3D9RenderWindow::acquireRenderWindowResources"); + } + + renderWindowResources->swapChain9Ex = NULL; + } + else + { + // The swap chain is already created by the device + HRESULT hr = mDevice->GetSwapChain(renderWindowResources->presentParametersIndex, + &renderWindowResources->swapChain); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to get the swap chain", + "D3D9RenderWindow::acquireRenderWindowResources"); + } + + renderWindowResources->swapChain9Ex = NULL; + } + + // Store references to buffers for convenience + renderWindowResources->swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, + &renderWindowResources->backBuffer); + + // Additional swap chains need their own depth buffer + // to support resizing them + if (renderWindow->isDepthBuffered()) + { + // if multihead is enabled, depth buffer can be created automatically for + // all the adapters. if multihead is not enabled, depth buffer is just + // created for the main swap chain + if (isMultihead() && isAutoDepthStencil() || + isMultihead() == false && isSwapChainWindow(renderWindow) == false) + { + mDevice->GetDepthStencilSurface(&renderWindowResources->depthBuffer); + } + else + { + uint targetWidth = renderWindow->getWidth(); + uint targetHeight = renderWindow->getHeight(); + + if (targetWidth == 0) + targetWidth = 1; + + if (targetHeight == 0) + targetHeight = 1; + + HRESULT hr = mDevice->CreateDepthStencilSurface( + targetWidth, targetHeight, + renderWindowResources->presentParameters.AutoDepthStencilFormat, + renderWindowResources->presentParameters.MultiSampleType, + renderWindowResources->presentParameters.MultiSampleQuality, + (renderWindowResources->presentParameters.Flags & D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL), + &renderWindowResources->depthBuffer, NULL + ); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create a depth buffer for the swap chain", + "D3D9RenderWindow::acquireRenderWindowResources"); + } + + if (isSwapChainWindow(renderWindow) == false) + { + mDevice->SetDepthStencilSurface(renderWindowResources->depthBuffer); + } + } + + if (renderWindowResources->depthBuffer) + { + //Tell the RS we have a depth buffer we created it needs to add to the default pool + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + DepthBuffer *depthBuf = renderSystem->_addManualDepthBuffer( mDevice, renderWindowResources->depthBuffer ); + + //Don't forget we want this window to use _this_ depth buffer + renderWindow->attachDepthBuffer( depthBuf ); + } + else + { + LogManager::getSingleton().logMessage("D3D9 : WARNING - Depth buffer could not be acquired."); + } + } + + renderWindowResources->acquired = true; + } + + //--------------------------------------------------------------------- + void D3D9Device::setupDeviceStates() + { + HRESULT hr = mDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to apply render state: D3DRS_SPECULARENABLE <- TRUE", + "D3D9Device::setupDeviceStates"); + } + } + + //--------------------------------------------------------------------- + bool D3D9Device::isSwapChainWindow(D3D9RenderWindow* renderWindow) + { + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + + if (it->second->presentParametersIndex == 0 || renderWindow->isFullScreen()) + return false; + + return true; + } + + //--------------------------------------------------------------------- + D3D9RenderWindow* D3D9Device::getPrimaryWindow() + { + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); + + while (it != mMapRenderWindowToResources.end() && it->second->presentParametersIndex != 0) + ++it; + + assert(it != mMapRenderWindowToResources.end()); + + return it->first; + } + + //--------------------------------------------------------------------- + void D3D9Device::setSharedWindowHandle(HWND hSharedHWND) + { + if (hSharedHWND != msSharedFocusWindow) + msSharedFocusWindow = hSharedHWND; + } + + //--------------------------------------------------------------------- + void D3D9Device::updateRenderWindowsIndices() + { + // Update present parameters index attribute per render window. + if (isMultihead()) + { + RenderWindowToResourcesIterator it = mMapRenderWindowToResources.begin(); + + // Multi head device case - + // Present parameter index is based on adapter ordinal in group index. + while (it != mMapRenderWindowToResources.end()) + { + it->second->presentParametersIndex = it->second->adapterOrdinalInGroupIndex; + ++it; + } + } + else + { + // Single head device case - + // Just assign index in incremental order - + // NOTE: It suppose to cover both cases that possible here: + // 1. Single full screen window - only one allowed per device (this is not multi-head case). + // 2. Multiple window mode windows. + + uint nextPresParamIndex = 0; + + RenderWindowToResourcesIterator it; + D3D9RenderWindow* deviceFocusWindow = NULL; + + // In case a d3d9 device exists - try to keep the present parameters order + // so that the window that the device is focused on will stay the same and we + // will avoid device re-creation. + if (mDevice != NULL) + { + it = mMapRenderWindowToResources.begin(); + while (it != mMapRenderWindowToResources.end()) + { + //This "if" handles the common case of a single device + if (it->first->getWindowHandle() == mCreationParams.hFocusWindow) + { + deviceFocusWindow = it->first; + it->second->presentParametersIndex = nextPresParamIndex; + ++nextPresParamIndex; + break; + } + //This "if" handles multiple devices when a shared window is used + if ((it->second->presentParametersIndex == 0) && (it->second->acquired == true)) + { + deviceFocusWindow = it->first; + ++nextPresParamIndex; + } + ++it; + } + } + + + + it = mMapRenderWindowToResources.begin(); + while (it != mMapRenderWindowToResources.end()) + { + if (it->first != deviceFocusWindow) + { + it->second->presentParametersIndex = nextPresParamIndex; + ++nextPresParamIndex; + } + ++it; + } + } + } + //--------------------------------------------------------------------- + void D3D9Device::copyContentsToMemory(D3D9RenderWindow* renderWindow, + const PixelBox &dst, RenderTarget::FrameBuffer buffer) + { + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + RenderWindowResources* resources = it->second; + bool swapChain = isSwapChainWindow(renderWindow); + + + + if ((dst.left < 0) || (dst.right > renderWindow->getWidth()) || + (dst.top < 0) || (dst.bottom > renderWindow->getHeight()) || + (dst.front != 0) || (dst.back != 1)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid box.", + "D3D9Device::copyContentsToMemory" ); + } + + HRESULT hr; + IDirect3DSurface9* pSurf = NULL; + IDirect3DSurface9* pTempSurf = NULL; + D3DSURFACE_DESC desc; + D3DLOCKED_RECT lockedRect; + + + if (buffer == RenderTarget::FB_AUTO) + { + //buffer = mIsFullScreen? FB_FRONT : FB_BACK; + buffer = RenderTarget::FB_BACK; + } + + if (buffer == RenderTarget::FB_FRONT) + { + D3DDISPLAYMODE dm; + + if (FAILED(hr = mDevice->GetDisplayMode(0, &dm))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't get display mode: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + + desc.Width = dm.Width; + desc.Height = dm.Height; + desc.Format = D3DFMT_A8R8G8B8; + if (FAILED(hr = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, + desc.Format, + D3DPOOL_SYSTEMMEM, + &pTempSurf, + 0))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't create offscreen buffer: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + + if (FAILED(hr = swapChain ? resources->swapChain->GetFrontBufferData(pTempSurf) : + mDevice->GetFrontBufferData(0, pTempSurf))) + { + SAFE_RELEASE(pTempSurf); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't get front buffer: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + + if(renderWindow->isFullScreen()) + { + if ((dst.left == 0) && (dst.right == renderWindow->getWidth()) && (dst.top == 0) && (dst.bottom == renderWindow->getHeight())) + { + hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); + } + else + { + RECT rect; + + rect.left = static_cast(dst.left); + rect.right = static_cast(dst.right); + rect.top = static_cast(dst.top); + rect.bottom = static_cast(dst.bottom); + + hr = pTempSurf->LockRect(&lockedRect, &rect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); + } + if (FAILED(hr)) + { + SAFE_RELEASE(pTempSurf); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't lock rect: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + } + else + { + RECT srcRect; + //GetClientRect(mHWnd, &srcRect); + srcRect.left = static_cast(dst.left); + srcRect.top = static_cast(dst.top); + srcRect.right = static_cast(dst.right); + srcRect.bottom = static_cast(dst.bottom); + POINT point; + point.x = srcRect.left; + point.y = srcRect.top; + ClientToScreen(renderWindow->getWindowHandle(), &point); + srcRect.top = point.y; + srcRect.left = point.x; + srcRect.bottom += point.y; + srcRect.right += point.x; + + desc.Width = srcRect.right - srcRect.left; + desc.Height = srcRect.bottom - srcRect.top; + + if (FAILED(hr = pTempSurf->LockRect(&lockedRect, &srcRect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK))) + { + SAFE_RELEASE(pTempSurf); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't lock rect: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + } + } + else + { + SAFE_RELEASE(pSurf); + if(FAILED(hr = swapChain? resources->swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurf) : + mDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurf))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't get back buffer: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + + if(FAILED(hr = pSurf->GetDesc(&desc))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't get description: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + + if (FAILED(hr = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, + desc.Format, + D3DPOOL_SYSTEMMEM, + &pTempSurf, + 0))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't create offscreen surface: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + + if (desc.MultiSampleType == D3DMULTISAMPLE_NONE) + { + if (FAILED(hr = mDevice->GetRenderTargetData(pSurf, pTempSurf))) + { + SAFE_RELEASE(pTempSurf); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't get render target data: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + } + else + { + IDirect3DSurface9* pStretchSurf = 0; + + if (FAILED(hr = mDevice->CreateRenderTarget(desc.Width, desc.Height, + desc.Format, + D3DMULTISAMPLE_NONE, + 0, + false, + &pStretchSurf, + 0))) + { + SAFE_RELEASE(pTempSurf); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't create render target: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + + if (FAILED(hr = mDevice->StretchRect(pSurf, 0, pStretchSurf, 0, D3DTEXF_NONE))) + { + SAFE_RELEASE(pTempSurf); + SAFE_RELEASE(pStretchSurf); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't stretch rect: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + if (FAILED(hr = mDevice->GetRenderTargetData(pStretchSurf, pTempSurf))) + { + SAFE_RELEASE(pTempSurf); + SAFE_RELEASE(pStretchSurf); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't get render target data: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + SAFE_RELEASE(pStretchSurf); + } + + if ((dst.left == 0) && (dst.right == renderWindow->getWidth()) && (dst.top == 0) && (dst.bottom == renderWindow->getHeight())) + { + hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); + } + else + { + RECT rect; + + rect.left = static_cast(dst.left); + rect.right = static_cast(dst.right); + rect.top = static_cast(dst.top); + rect.bottom = static_cast(dst.bottom); + + hr = pTempSurf->LockRect(&lockedRect, &rect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); + } + if (FAILED(hr)) + { + SAFE_RELEASE(pTempSurf); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't lock rect: " + Root::getSingleton().getErrorDescription(hr), + "D3D9Device::copyContentsToMemory"); + } + } + + PixelFormat format = Ogre::D3D9Mappings::_getPF(desc.Format); + + if (format == PF_UNKNOWN) + { + SAFE_RELEASE(pTempSurf); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unsupported format", "D3D9Device::copyContentsToMemory"); + } + + PixelBox src(dst.getWidth(), dst.getHeight(), 1, format, lockedRect.pBits); + src.rowPitch = lockedRect.Pitch / PixelUtil::getNumElemBytes(format); + src.slicePitch = desc.Height * src.rowPitch; + + PixelUtil::bulkPixelConversion(src, dst); + + SAFE_RELEASE(pTempSurf); + SAFE_RELEASE(pSurf); + + + } + + int D3D9Device::getVBlankMissCount(D3D9RenderWindow* renderWindow) + { + // the stat only works with no AA, VSync and 9Ex. + if(renderWindow->isAA() || + renderWindow->isVSyncEnabled() == false || + D3D9RenderSystem::isDirectX9Ex() == false) + { + return -1; + } + + RenderWindowToResourcesIterator it = getRenderWindowIterator(renderWindow); + RenderWindowResources* renderWindowResources = it->second; + + // The 9Ex swap chain is set to NULL when we create the RenderWindowResources, now we need it + // to get the stats - so we try to get it from the original d3d9 swap chain by using + // COM's QueryInterface + if(renderWindowResources->swapChain9Ex == NULL) + { + if (FAILED(renderWindowResources->swapChain->QueryInterface(IID_IDirect3DSwapChain9Ex, (void**)&renderWindowResources->swapChain9Ex))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Can't get Direct3DSwapChain9Ex from Direct3DSwapChain.", + "D3D9Device::getVBlankMissCount"); + } + } + + // Get Present Stats info for glitch detection + D3DPRESENTSTATS currentPresentStats; + ZeroMemory(¤tPresentStats, sizeof(currentPresentStats)); + // Obtain present statistics information for successfully displayed presents + HRESULT hr = renderWindowResources->swapChain9Ex->GetPresentStats(¤tPresentStats); + + // check if the call to GetPresentStats got us the stats + if(FAILED(hr) || currentPresentStats.PresentRefreshCount == 0) + { + mPreviousPresentStatsIsValid = false; + } + else + { + if(mPreviousPresentStatsIsValid == true) + { + // add the vblank misses since the last call to getVBlankMissCount + int currentVBlankMissCount = (currentPresentStats.PresentRefreshCount - mPreviousPresentStats.PresentRefreshCount) + - (currentPresentStats.PresentCount - mPreviousPresentStats.PresentCount); + + if(currentVBlankMissCount > 0) + { + mVBlankMissCount += currentVBlankMissCount; + } + } + + // save the current to be the next time previous + mPreviousPresentStats = currentPresentStats; + mPreviousPresentStatsIsValid = true; + } + + return mVBlankMissCount; + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9DeviceManager.cpp b/RenderSystems/Direct3D9/src/OgreD3D9DeviceManager.cpp index 3be831699ce..0e374f207bc 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9DeviceManager.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9DeviceManager.cpp @@ -36,479 +36,479 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - D3D9DeviceManager::D3D9DeviceManager() - { - mActiveDevice = NULL; - mActiveRenderWindowDevice = NULL; - } - - //--------------------------------------------------------------------- - D3D9DeviceManager::~D3D9DeviceManager() - { - DeviceIterator itDevice = mRenderDevices.begin(); - while (mRenderDevices.size() > 0) - { - mRenderDevices[0]->destroy(); - } - - mActiveDevice = NULL; - mActiveRenderWindowDevice = NULL; - } - - //--------------------------------------------------------------------- - void D3D9DeviceManager::setActiveDevice(D3D9Device* device) - { - if (mActiveDevice != device) - { - mActiveDevice = device; - - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - D3D9DriverList* driverList = renderSystem->getDirect3DDrivers(); - - // Update the active driver member. - for (uint i=0; i < driverList->count(); ++i) - { - D3D9Driver* currDriver = driverList->item(i); - if (currDriver->getAdapterNumber() == mActiveDevice->getAdapterNumber()) - { - renderSystem->mActiveD3DDriver = currDriver; - break; - } - } - - // Invalidate active view port. - renderSystem->mActiveViewport = NULL; - } - } - - //--------------------------------------------------------------------- - D3D9Device* D3D9DeviceManager::getActiveDevice() - { - if (mActiveDevice == NULL) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Current active device is NULL !!!", - "D3D9RenderSystem::getActiveDevice" ); - } - - return mActiveDevice; - } - - //--------------------------------------------------------------------- - void D3D9DeviceManager::setActiveRenderTargetDevice(D3D9Device* device) - { - mActiveRenderWindowDevice = device; - if (mActiveRenderWindowDevice != NULL) - setActiveDevice(mActiveRenderWindowDevice); - } - - //--------------------------------------------------------------------- - D3D9Device* D3D9DeviceManager::getActiveRenderTargetDevice() - { - return mActiveRenderWindowDevice; - } - - //--------------------------------------------------------------------- - UINT D3D9DeviceManager::getDeviceCount() - { - return static_cast(mRenderDevices.size()); - } - - //--------------------------------------------------------------------- - D3D9Device* D3D9DeviceManager::getDevice(UINT index) - { - return mRenderDevices[index]; - } - - //--------------------------------------------------------------------- - void D3D9DeviceManager::linkRenderWindow(D3D9RenderWindow* renderWindow) - { - D3D9Device* renderDevice; - - // Detach from previous device. - renderDevice = renderWindow->getDevice(); - if (renderDevice != NULL) - renderDevice->detachRenderWindow(renderWindow); - - D3D9RenderWindowList renderWindowsGroup; - - // Select new device for this window. - renderDevice = selectDevice(renderWindow, renderWindowsGroup); - - // Link the windows group to the new device. - for (uint i = 0; i < renderWindowsGroup.size(); ++i) - { - D3D9RenderWindow* currWindow = renderWindowsGroup[i]; - - currWindow->setDevice(renderDevice); - renderDevice->attachRenderWindow(currWindow); - renderDevice->setAdapterOrdinalIndex(currWindow, i); - } - - renderDevice->acquire(); - if (mActiveDevice == NULL) - setActiveDevice(renderDevice); - } - - //--------------------------------------------------------------------- - D3D9Device* D3D9DeviceManager::selectDevice(D3D9RenderWindow* renderWindow, D3D9RenderWindowList& renderWindowsGroup) - { - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - D3D9Device* renderDevice = NULL; - IDirect3D9* direct3D9 = D3D9RenderSystem::getDirect3D9(); - UINT nAdapterOrdinal = D3DADAPTER_DEFAULT; - D3DDEVTYPE devType = D3DDEVTYPE_HAL; - DWORD extraFlags = 0; - D3D9DriverList* driverList = renderSystem->getDirect3DDrivers(); - bool nvAdapterFound = false; - - - // Default group includes at least the given render window. - renderWindowsGroup.push_back(renderWindow); - - // Case we use nvidia performance HUD, override the device settings. - if (renderWindow->isNvPerfHUDEnable()) - { - // Look for 'NVIDIA NVPerfHUD' adapter (<= v4) - // or 'NVIDIA PerfHUD' (v5) - // If it is present, override default settings - for (UINT adapter=0; adapter < direct3D9->GetAdapterCount(); ++adapter) - { - D3D9Driver* currDriver = driverList->item(adapter); - const D3DADAPTER_IDENTIFIER9& currAdapterIdentifier = currDriver->getAdapterIdentifier(); - - if(strstr(currAdapterIdentifier.Description, "PerfHUD") != NULL) - { - renderDevice = NULL; - nAdapterOrdinal = adapter; - renderSystem->mActiveD3DDriver = currDriver; - devType = D3DDEVTYPE_REF; - nvAdapterFound = true; - break; - } - } - } - - // No special adapter should be used. - if (nvAdapterFound == false) - { - renderSystem->mActiveD3DDriver = findDriver(renderWindow); - nAdapterOrdinal = renderSystem->mActiveD3DDriver->getAdapterNumber(); - - bool bTryUsingMultiheadDevice = false; - - if (renderWindow->isFullScreen()) - { - bTryUsingMultiheadDevice = true; - if (renderSystem->getMultiheadUse() == D3D9RenderSystem::mutAuto) - { - OSVERSIONINFO osVersionInfo; - - osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - // Case version info failed -> assume we run on XP. - if (FALSE == GetVersionEx(&osVersionInfo)) - { - osVersionInfo.dwMajorVersion = 5; - } - - // XP and below - multi-head will cause artifacts when vsync is on. - if (osVersionInfo.dwMajorVersion <= 5 && renderWindow->isVSync()) - { - bTryUsingMultiheadDevice = false; - LogManager::getSingleton().logMessage("D3D9 : Multi head disabled. It causes horizontal line when used in XP + VSync combination"); - } - - // Vista and SP1 or SP2 - multi-head device can not be reset - it causes memory corruption. - if (osVersionInfo.dwMajorVersion == 6 && - (_stricmp(osVersionInfo.szCSDVersion, "Service Pack 1") == 0 || - _stricmp(osVersionInfo.szCSDVersion, "Service Pack 2") == 0)) - - { - bTryUsingMultiheadDevice = false; - LogManager::getSingleton().logMessage("D3D9 : Multi head disabled. It causes application run time crashes when used in Vista + SP 1 or 2 combination"); - } - } - else - { - bTryUsingMultiheadDevice = renderSystem->getMultiheadUse() == D3D9RenderSystem::mutYes ? true : false; - } - } - - - // Check if we can create a group of render windows - // on the same device using the multi-head feature. - if (bTryUsingMultiheadDevice) - { - const D3DCAPS9& targetAdapterCaps = renderSystem->mActiveD3DDriver->getD3D9DeviceCaps(); - D3DCAPS9 masterAdapterCaps; - - // Find the master device caps. - if (targetAdapterCaps.MasterAdapterOrdinal == targetAdapterCaps.AdapterOrdinal) - { - masterAdapterCaps = targetAdapterCaps; - } - else - { - for (uint i = 0; i < driverList->count(); ++i) - { - D3D9Driver* currDriver = driverList->item(i); - const D3DCAPS9& currDeviceCaps = currDriver->getD3D9DeviceCaps(); - - if (currDeviceCaps.AdapterOrdinal == targetAdapterCaps.MasterAdapterOrdinal) - { - masterAdapterCaps = currDeviceCaps; - break; - } - } - } - - // Case the master adapter can handle multiple adapters. - if (masterAdapterCaps.NumberOfAdaptersInGroup > 1) - { - // Create empty list of render windows composing this group. - renderWindowsGroup.resize(masterAdapterCaps.NumberOfAdaptersInGroup); - for (uint i = 0; i < renderWindowsGroup.size(); ++i) - renderWindowsGroup[i] = NULL; - - - // Assign the current render window to it's place in the group. - renderWindowsGroup[targetAdapterCaps.AdapterOrdinalInGroup] = renderWindow; - - - // For each existing window - check if it belongs to the group. - for (uint i = 0; i < renderSystem->mRenderWindows.size(); ++i) - { - D3D9RenderWindow* currRenderWindow = renderSystem->mRenderWindows[i]; - - if (currRenderWindow->isFullScreen()) - { - D3D9Driver* currDriver = findDriver(currRenderWindow); - const D3DCAPS9& currDeviceCaps = currDriver->getD3D9DeviceCaps(); - - if (currDeviceCaps.MasterAdapterOrdinal == masterAdapterCaps.AdapterOrdinal) - { - renderWindowsGroup[currDeviceCaps.AdapterOrdinalInGroup] = currRenderWindow; - break; - } - } - } - - bool bDeviceGroupFull = true; - - - // Check if render windows group is full and ready to be driven by - // the master device. - for (uint i = 0; i < renderWindowsGroup.size(); ++i) - { - // This group misses required window -> go back to default. - if (renderWindowsGroup[i] == NULL) - { - bDeviceGroupFull = false; - renderWindowsGroup.clear(); - renderWindowsGroup.push_back(renderWindow); - break; - } - } - - // Case device group is full -> we can use multi head device. - if (bDeviceGroupFull) - { - bool validateAllDevices = false; - - for (uint i = 0; i < renderWindowsGroup.size(); ++i) - { - D3D9RenderWindow* currRenderWindow = renderWindowsGroup[i]; - D3D9Device* currDevice = currRenderWindow->getDevice(); - - // This is the master window - if (i == 0) - { - // If master device exists - just release it. - if (currDevice != NULL) - { - renderDevice = currDevice; - renderDevice->release(); - } - } - - // This is subordinate window. - else - { - // If subordinate device exists - destroy it. - if (currDevice != NULL) - { - currDevice->destroy(); - validateAllDevices = true; - } - } - } - - // In case some device was destroyed - make sure all other devices are valid. - // A possible scenario is that full screen window has been destroyed and it's handle - // was used and the shared focus handle. All other devices used this handle and must be - // recreated using other handles otherwise create device will fail. - if (validateAllDevices) - { - for (uint i = 0; i < mRenderDevices.size(); ++i) - mRenderDevices[i]->validateFocusWindow(); - } - } - } - } - } - - - - // Do we want to preserve the FPU mode? Might be useful for scientific apps - ConfigOptionMap& options = renderSystem->getConfigOptions(); - ConfigOptionMap::iterator opti = options.find("Floating-point mode"); - if (opti != options.end() && opti->second.currentValue == "Consistent") - extraFlags |= D3DCREATE_FPU_PRESERVE; + //--------------------------------------------------------------------- + D3D9DeviceManager::D3D9DeviceManager() + { + mActiveDevice = NULL; + mActiveRenderWindowDevice = NULL; + } + + //--------------------------------------------------------------------- + D3D9DeviceManager::~D3D9DeviceManager() + { + DeviceIterator itDevice = mRenderDevices.begin(); + while (mRenderDevices.size() > 0) + { + mRenderDevices[0]->destroy(); + } + + mActiveDevice = NULL; + mActiveRenderWindowDevice = NULL; + } + + //--------------------------------------------------------------------- + void D3D9DeviceManager::setActiveDevice(D3D9Device* device) + { + if (mActiveDevice != device) + { + mActiveDevice = device; + + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + D3D9DriverList* driverList = renderSystem->getDirect3DDrivers(); + + // Update the active driver member. + for (uint i=0; i < driverList->count(); ++i) + { + D3D9Driver* currDriver = driverList->item(i); + if (currDriver->getAdapterNumber() == mActiveDevice->getAdapterNumber()) + { + renderSystem->mActiveD3DDriver = currDriver; + break; + } + } + + // Invalidate active view port. + renderSystem->mActiveViewport = NULL; + } + } + + //--------------------------------------------------------------------- + D3D9Device* D3D9DeviceManager::getActiveDevice() + { + if (mActiveDevice == NULL) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Current active device is NULL !!!", + "D3D9RenderSystem::getActiveDevice" ); + } + + return mActiveDevice; + } + + //--------------------------------------------------------------------- + void D3D9DeviceManager::setActiveRenderTargetDevice(D3D9Device* device) + { + mActiveRenderWindowDevice = device; + if (mActiveRenderWindowDevice != NULL) + setActiveDevice(mActiveRenderWindowDevice); + } + + //--------------------------------------------------------------------- + D3D9Device* D3D9DeviceManager::getActiveRenderTargetDevice() + { + return mActiveRenderWindowDevice; + } + + //--------------------------------------------------------------------- + UINT D3D9DeviceManager::getDeviceCount() + { + return static_cast(mRenderDevices.size()); + } + + //--------------------------------------------------------------------- + D3D9Device* D3D9DeviceManager::getDevice(UINT index) + { + return mRenderDevices[index]; + } + + //--------------------------------------------------------------------- + void D3D9DeviceManager::linkRenderWindow(D3D9RenderWindow* renderWindow) + { + D3D9Device* renderDevice; + + // Detach from previous device. + renderDevice = renderWindow->getDevice(); + if (renderDevice != NULL) + renderDevice->detachRenderWindow(renderWindow); + + D3D9RenderWindowList renderWindowsGroup; + + // Select new device for this window. + renderDevice = selectDevice(renderWindow, renderWindowsGroup); + + // Link the windows group to the new device. + for (uint i = 0; i < renderWindowsGroup.size(); ++i) + { + D3D9RenderWindow* currWindow = renderWindowsGroup[i]; + + currWindow->setDevice(renderDevice); + renderDevice->attachRenderWindow(currWindow); + renderDevice->setAdapterOrdinalIndex(currWindow, i); + } + + renderDevice->acquire(); + if (mActiveDevice == NULL) + setActiveDevice(renderDevice); + } + + //--------------------------------------------------------------------- + D3D9Device* D3D9DeviceManager::selectDevice(D3D9RenderWindow* renderWindow, D3D9RenderWindowList& renderWindowsGroup) + { + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + D3D9Device* renderDevice = NULL; + IDirect3D9* direct3D9 = D3D9RenderSystem::getDirect3D9(); + UINT nAdapterOrdinal = D3DADAPTER_DEFAULT; + D3DDEVTYPE devType = D3DDEVTYPE_HAL; + DWORD extraFlags = 0; + D3D9DriverList* driverList = renderSystem->getDirect3DDrivers(); + bool nvAdapterFound = false; + + + // Default group includes at least the given render window. + renderWindowsGroup.push_back(renderWindow); + + // Case we use nvidia performance HUD, override the device settings. + if (renderWindow->isNvPerfHUDEnable()) + { + // Look for 'NVIDIA NVPerfHUD' adapter (<= v4) + // or 'NVIDIA PerfHUD' (v5) + // If it is present, override default settings + for (UINT adapter=0; adapter < direct3D9->GetAdapterCount(); ++adapter) + { + D3D9Driver* currDriver = driverList->item(adapter); + const D3DADAPTER_IDENTIFIER9& currAdapterIdentifier = currDriver->getAdapterIdentifier(); + + if(strstr(currAdapterIdentifier.Description, "PerfHUD") != NULL) + { + renderDevice = NULL; + nAdapterOrdinal = adapter; + renderSystem->mActiveD3DDriver = currDriver; + devType = D3DDEVTYPE_REF; + nvAdapterFound = true; + break; + } + } + } + + // No special adapter should be used. + if (nvAdapterFound == false) + { + renderSystem->mActiveD3DDriver = findDriver(renderWindow); + nAdapterOrdinal = renderSystem->mActiveD3DDriver->getAdapterNumber(); + + bool bTryUsingMultiheadDevice = false; + + if (renderWindow->isFullScreen()) + { + bTryUsingMultiheadDevice = true; + if (renderSystem->getMultiheadUse() == D3D9RenderSystem::mutAuto) + { + OSVERSIONINFO osVersionInfo; + + osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + // Case version info failed -> assume we run on XP. + if (FALSE == GetVersionEx(&osVersionInfo)) + { + osVersionInfo.dwMajorVersion = 5; + } + + // XP and below - multi-head will cause artifacts when vsync is on. + if (osVersionInfo.dwMajorVersion <= 5 && renderWindow->isVSync()) + { + bTryUsingMultiheadDevice = false; + LogManager::getSingleton().logMessage("D3D9 : Multi head disabled. It causes horizontal line when used in XP + VSync combination"); + } + + // Vista and SP1 or SP2 - multi-head device can not be reset - it causes memory corruption. + if (osVersionInfo.dwMajorVersion == 6 && + (_stricmp(osVersionInfo.szCSDVersion, "Service Pack 1") == 0 || + _stricmp(osVersionInfo.szCSDVersion, "Service Pack 2") == 0)) + + { + bTryUsingMultiheadDevice = false; + LogManager::getSingleton().logMessage("D3D9 : Multi head disabled. It causes application run time crashes when used in Vista + SP 1 or 2 combination"); + } + } + else + { + bTryUsingMultiheadDevice = renderSystem->getMultiheadUse() == D3D9RenderSystem::mutYes ? true : false; + } + } + + + // Check if we can create a group of render windows + // on the same device using the multi-head feature. + if (bTryUsingMultiheadDevice) + { + const D3DCAPS9& targetAdapterCaps = renderSystem->mActiveD3DDriver->getD3D9DeviceCaps(); + D3DCAPS9 masterAdapterCaps; + + // Find the master device caps. + if (targetAdapterCaps.MasterAdapterOrdinal == targetAdapterCaps.AdapterOrdinal) + { + masterAdapterCaps = targetAdapterCaps; + } + else + { + for (uint i = 0; i < driverList->count(); ++i) + { + D3D9Driver* currDriver = driverList->item(i); + const D3DCAPS9& currDeviceCaps = currDriver->getD3D9DeviceCaps(); + + if (currDeviceCaps.AdapterOrdinal == targetAdapterCaps.MasterAdapterOrdinal) + { + masterAdapterCaps = currDeviceCaps; + break; + } + } + } + + // Case the master adapter can handle multiple adapters. + if (masterAdapterCaps.NumberOfAdaptersInGroup > 1) + { + // Create empty list of render windows composing this group. + renderWindowsGroup.resize(masterAdapterCaps.NumberOfAdaptersInGroup); + for (uint i = 0; i < renderWindowsGroup.size(); ++i) + renderWindowsGroup[i] = NULL; + + + // Assign the current render window to it's place in the group. + renderWindowsGroup[targetAdapterCaps.AdapterOrdinalInGroup] = renderWindow; + + + // For each existing window - check if it belongs to the group. + for (uint i = 0; i < renderSystem->mRenderWindows.size(); ++i) + { + D3D9RenderWindow* currRenderWindow = renderSystem->mRenderWindows[i]; + + if (currRenderWindow->isFullScreen()) + { + D3D9Driver* currDriver = findDriver(currRenderWindow); + const D3DCAPS9& currDeviceCaps = currDriver->getD3D9DeviceCaps(); + + if (currDeviceCaps.MasterAdapterOrdinal == masterAdapterCaps.AdapterOrdinal) + { + renderWindowsGroup[currDeviceCaps.AdapterOrdinalInGroup] = currRenderWindow; + break; + } + } + } + + bool bDeviceGroupFull = true; + + + // Check if render windows group is full and ready to be driven by + // the master device. + for (uint i = 0; i < renderWindowsGroup.size(); ++i) + { + // This group misses required window -> go back to default. + if (renderWindowsGroup[i] == NULL) + { + bDeviceGroupFull = false; + renderWindowsGroup.clear(); + renderWindowsGroup.push_back(renderWindow); + break; + } + } + + // Case device group is full -> we can use multi head device. + if (bDeviceGroupFull) + { + bool validateAllDevices = false; + + for (uint i = 0; i < renderWindowsGroup.size(); ++i) + { + D3D9RenderWindow* currRenderWindow = renderWindowsGroup[i]; + D3D9Device* currDevice = currRenderWindow->getDevice(); + + // This is the master window + if (i == 0) + { + // If master device exists - just release it. + if (currDevice != NULL) + { + renderDevice = currDevice; + renderDevice->release(); + } + } + + // This is subordinate window. + else + { + // If subordinate device exists - destroy it. + if (currDevice != NULL) + { + currDevice->destroy(); + validateAllDevices = true; + } + } + } + + // In case some device was destroyed - make sure all other devices are valid. + // A possible scenario is that full screen window has been destroyed and it's handle + // was used and the shared focus handle. All other devices used this handle and must be + // recreated using other handles otherwise create device will fail. + if (validateAllDevices) + { + for (uint i = 0; i < mRenderDevices.size(); ++i) + mRenderDevices[i]->validateFocusWindow(); + } + } + } + } + } + + + + // Do we want to preserve the FPU mode? Might be useful for scientific apps + ConfigOptionMap& options = renderSystem->getConfigOptions(); + ConfigOptionMap::iterator opti = options.find("Floating-point mode"); + if (opti != options.end() && opti->second.currentValue == "Consistent") + extraFlags |= D3DCREATE_FPU_PRESERVE; #if OGRE_THREAD_SUPPORT == 1 - extraFlags |= D3DCREATE_MULTITHREADED; + extraFlags |= D3DCREATE_MULTITHREADED; #endif - // Try to find a matching device from current device list. - if (renderDevice == NULL) - { - for (uint i = 0; i < mRenderDevices.size(); ++i) - { - D3D9Device* currDevice = mRenderDevices[i]; - - if (currDevice->getAdapterNumber() == nAdapterOrdinal && - currDevice->getDeviceType() == devType && - currDevice->isFullScreen() == renderWindow->isFullScreen()) - { - renderDevice = currDevice; - break; - } - } - } - - // No matching device found -> try reference device type (might have been - // previously created as a fallback, but don't change devType because HAL - // should be preferred on creation) - if (renderDevice == NULL) - { - for (uint i = 0; i < mRenderDevices.size(); ++i) - { - D3D9Device* currDevice = mRenderDevices[i]; - - if (currDevice->getAdapterNumber() == nAdapterOrdinal && - currDevice->getDeviceType() == D3DDEVTYPE_REF) - { - renderDevice = currDevice; - break; - } - } - } - - - // No matching device found -> create new one. - if (renderDevice == NULL) - { - renderDevice = OGRE_NEW D3D9Device(this, nAdapterOrdinal, direct3D9->GetAdapterMonitor(nAdapterOrdinal), devType, extraFlags); - mRenderDevices.push_back(renderDevice); - if (mActiveDevice == NULL) - setActiveDevice(renderDevice); - } - - return renderDevice; - } - - //----------------------------------------------------------------------- - D3D9Driver* D3D9DeviceManager::findDriver(D3D9RenderWindow* renderWindow) - { - D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - IDirect3D9* direct3D9 = D3D9RenderSystem::getDirect3D9(); - UINT nAdapterOrdinal = D3DADAPTER_DEFAULT; - HMONITOR hRenderWindowMonitor = NULL; - D3D9DriverList* driverList = renderSystem->getDirect3DDrivers(); - - // Find the monitor this render window belongs to. - hRenderWindowMonitor = MonitorFromWindow(renderWindow->getWindowHandle(), MONITOR_DEFAULTTONEAREST); - - - // Find the matching driver using window monitor handle. - for (uint i = 0; i < driverList->count(); ++i) - { - D3D9Driver* currDriver = driverList->item(i); - HMONITOR hCurrAdpaterMonitor = direct3D9->GetAdapterMonitor(currDriver->getAdapterNumber()); - - if (hCurrAdpaterMonitor == hRenderWindowMonitor) - { - return currDriver; - } - } - - return NULL; - } - - //----------------------------------------------------------------------- - void D3D9DeviceManager::notifyOnDeviceDestroy(D3D9Device* device) - { - if (device != NULL) - { - if (device == mActiveDevice) - mActiveDevice = NULL; - - DeviceIterator itDevice = mRenderDevices.begin(); - while (itDevice != mRenderDevices.end()) - { - if (*itDevice == device) - { - OGRE_DELETE device; - mRenderDevices.erase(itDevice); - break; - } - ++itDevice; - } - - if (mActiveDevice == NULL) - { - DeviceIterator itDevice = mRenderDevices.begin(); - if (itDevice != mRenderDevices.end()) - mActiveDevice = (*itDevice); - } - } - } - - //--------------------------------------------------------------------- - D3D9Device* D3D9DeviceManager::getDeviceFromD3D9Device(IDirect3DDevice9* d3d9Device) - { - DeviceIterator itDevice = mRenderDevices.begin(); - while (itDevice != mRenderDevices.end()) - { - if ((*itDevice)->getD3D9Device() == d3d9Device) - { - return *itDevice; - } - ++itDevice; - } - - return NULL; - } - - //--------------------------------------------------------------------- - void D3D9DeviceManager::destroyInactiveRenderDevices() - { - DeviceIterator itDevice = mRenderDevices.begin(); - while (itDevice != mRenderDevices.end()) - { - if ((*itDevice)->getRenderWindowCount() == 0 && - (*itDevice)->getLastPresentFrame() + 1 < Root::getSingleton().getNextFrameNumber()) - { - if (*itDevice == mActiveRenderWindowDevice) - setActiveRenderTargetDevice(NULL); - (*itDevice)->destroy(); - break; - } - ++itDevice; - } - } + // Try to find a matching device from current device list. + if (renderDevice == NULL) + { + for (uint i = 0; i < mRenderDevices.size(); ++i) + { + D3D9Device* currDevice = mRenderDevices[i]; + + if (currDevice->getAdapterNumber() == nAdapterOrdinal && + currDevice->getDeviceType() == devType && + currDevice->isFullScreen() == renderWindow->isFullScreen()) + { + renderDevice = currDevice; + break; + } + } + } + + // No matching device found -> try reference device type (might have been + // previously created as a fallback, but don't change devType because HAL + // should be preferred on creation) + if (renderDevice == NULL) + { + for (uint i = 0; i < mRenderDevices.size(); ++i) + { + D3D9Device* currDevice = mRenderDevices[i]; + + if (currDevice->getAdapterNumber() == nAdapterOrdinal && + currDevice->getDeviceType() == D3DDEVTYPE_REF) + { + renderDevice = currDevice; + break; + } + } + } + + + // No matching device found -> create new one. + if (renderDevice == NULL) + { + renderDevice = OGRE_NEW D3D9Device(this, nAdapterOrdinal, direct3D9->GetAdapterMonitor(nAdapterOrdinal), devType, extraFlags); + mRenderDevices.push_back(renderDevice); + if (mActiveDevice == NULL) + setActiveDevice(renderDevice); + } + + return renderDevice; + } + + //----------------------------------------------------------------------- + D3D9Driver* D3D9DeviceManager::findDriver(D3D9RenderWindow* renderWindow) + { + D3D9RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + IDirect3D9* direct3D9 = D3D9RenderSystem::getDirect3D9(); + UINT nAdapterOrdinal = D3DADAPTER_DEFAULT; + HMONITOR hRenderWindowMonitor = NULL; + D3D9DriverList* driverList = renderSystem->getDirect3DDrivers(); + + // Find the monitor this render window belongs to. + hRenderWindowMonitor = MonitorFromWindow(renderWindow->getWindowHandle(), MONITOR_DEFAULTTONEAREST); + + + // Find the matching driver using window monitor handle. + for (uint i = 0; i < driverList->count(); ++i) + { + D3D9Driver* currDriver = driverList->item(i); + HMONITOR hCurrAdpaterMonitor = direct3D9->GetAdapterMonitor(currDriver->getAdapterNumber()); + + if (hCurrAdpaterMonitor == hRenderWindowMonitor) + { + return currDriver; + } + } + + return NULL; + } + + //----------------------------------------------------------------------- + void D3D9DeviceManager::notifyOnDeviceDestroy(D3D9Device* device) + { + if (device != NULL) + { + if (device == mActiveDevice) + mActiveDevice = NULL; + + DeviceIterator itDevice = mRenderDevices.begin(); + while (itDevice != mRenderDevices.end()) + { + if (*itDevice == device) + { + OGRE_DELETE device; + mRenderDevices.erase(itDevice); + break; + } + ++itDevice; + } + + if (mActiveDevice == NULL) + { + DeviceIterator itDevice = mRenderDevices.begin(); + if (itDevice != mRenderDevices.end()) + mActiveDevice = (*itDevice); + } + } + } + + //--------------------------------------------------------------------- + D3D9Device* D3D9DeviceManager::getDeviceFromD3D9Device(IDirect3DDevice9* d3d9Device) + { + DeviceIterator itDevice = mRenderDevices.begin(); + while (itDevice != mRenderDevices.end()) + { + if ((*itDevice)->getD3D9Device() == d3d9Device) + { + return *itDevice; + } + ++itDevice; + } + + return NULL; + } + + //--------------------------------------------------------------------- + void D3D9DeviceManager::destroyInactiveRenderDevices() + { + DeviceIterator itDevice = mRenderDevices.begin(); + while (itDevice != mRenderDevices.end()) + { + if ((*itDevice)->getRenderWindowCount() == 0 && + (*itDevice)->getLastPresentFrame() + 1 < Root::getSingleton().getNextFrameNumber()) + { + if (*itDevice == mActiveRenderWindowDevice) + setActiveRenderTargetDevice(NULL); + (*itDevice)->destroy(); + break; + } + ++itDevice; + } + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9Driver.cpp b/RenderSystems/Direct3D9/src/OgreD3D9Driver.cpp index f6e6aadf924..d09ec675c4e 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9Driver.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9Driver.cpp @@ -31,65 +31,65 @@ THE SOFTWARE. namespace Ogre { - D3D9Driver::D3D9Driver() - { - mAdapterNumber = 0; - ZeroMemory( &mD3D9DeviceCaps, sizeof(mD3D9DeviceCaps) ); - ZeroMemory( &mAdapterIdentifier, sizeof(mAdapterIdentifier) ); - ZeroMemory( &mDesktopDisplayMode, sizeof(mDesktopDisplayMode) ); - mVideoModeList = NULL; - } + D3D9Driver::D3D9Driver() + { + mAdapterNumber = 0; + ZeroMemory( &mD3D9DeviceCaps, sizeof(mD3D9DeviceCaps) ); + ZeroMemory( &mAdapterIdentifier, sizeof(mAdapterIdentifier) ); + ZeroMemory( &mDesktopDisplayMode, sizeof(mDesktopDisplayMode) ); + mVideoModeList = NULL; + } - D3D9Driver::D3D9Driver( const D3D9Driver &ob ) - { - mAdapterNumber = ob.mAdapterNumber; - mD3D9DeviceCaps = ob.mD3D9DeviceCaps; - mAdapterIdentifier = ob.mAdapterIdentifier; - mDesktopDisplayMode = ob.mDesktopDisplayMode; - mVideoModeList = NULL; - } + D3D9Driver::D3D9Driver( const D3D9Driver &ob ) + { + mAdapterNumber = ob.mAdapterNumber; + mD3D9DeviceCaps = ob.mD3D9DeviceCaps; + mAdapterIdentifier = ob.mAdapterIdentifier; + mDesktopDisplayMode = ob.mDesktopDisplayMode; + mVideoModeList = NULL; + } - D3D9Driver::D3D9Driver( unsigned int adapterNumber, - const D3DCAPS9& deviceCaps, - const D3DADAPTER_IDENTIFIER9& adapterIdentifier, - const D3DDISPLAYMODE& desktopDisplayMode ) - { - mAdapterNumber = adapterNumber; - mD3D9DeviceCaps = deviceCaps; - mAdapterIdentifier = adapterIdentifier; - mDesktopDisplayMode = desktopDisplayMode; - mVideoModeList = NULL; - } + D3D9Driver::D3D9Driver( unsigned int adapterNumber, + const D3DCAPS9& deviceCaps, + const D3DADAPTER_IDENTIFIER9& adapterIdentifier, + const D3DDISPLAYMODE& desktopDisplayMode ) + { + mAdapterNumber = adapterNumber; + mD3D9DeviceCaps = deviceCaps; + mAdapterIdentifier = adapterIdentifier; + mDesktopDisplayMode = desktopDisplayMode; + mVideoModeList = NULL; + } - D3D9Driver::~D3D9Driver() - { - if (mVideoModeList != NULL) - { - OGRE_DELETE mVideoModeList; - mVideoModeList = NULL; - } - } + D3D9Driver::~D3D9Driver() + { + if (mVideoModeList != NULL) + { + OGRE_DELETE mVideoModeList; + mVideoModeList = NULL; + } + } - String D3D9Driver::DriverName() const - { - return String(mAdapterIdentifier.Driver); - } + String D3D9Driver::DriverName() const + { + return String(mAdapterIdentifier.Driver); + } - String D3D9Driver::DriverDescription() const - { - StringStream str; - str << "Monitor-" << (mAdapterNumber+1) << "-" << mAdapterIdentifier.Description; - String driverDescription(str.str()); - StringUtil::trim(driverDescription); + String D3D9Driver::DriverDescription() const + { + StringStream str; + str << "Monitor-" << (mAdapterNumber+1) << "-" << mAdapterIdentifier.Description; + String driverDescription(str.str()); + StringUtil::trim(driverDescription); return driverDescription; - } + } - D3D9VideoModeList* D3D9Driver::getVideoModeList() - { - if( !mVideoModeList ) - mVideoModeList = OGRE_NEW D3D9VideoModeList( this ); + D3D9VideoModeList* D3D9Driver::getVideoModeList() + { + if( !mVideoModeList ) + mVideoModeList = OGRE_NEW D3D9VideoModeList( this ); - return mVideoModeList; - } + return mVideoModeList; + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9DriverList.cpp b/RenderSystems/Direct3D9/src/OgreD3D9DriverList.cpp index a3423325930..21f4d9429a7 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9DriverList.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9DriverList.cpp @@ -32,61 +32,61 @@ THE SOFTWARE. namespace Ogre { - D3D9DriverList::D3D9DriverList() - { - enumerate(); - } - - D3D9DriverList::~D3D9DriverList(void) - { - mDriverList.clear(); - } - - BOOL D3D9DriverList::enumerate() - { - IDirect3D9* lpD3D9 = D3D9RenderSystem::getDirect3D9(); - - LogManager::getSingleton().logMessage( "D3D9: Driver Detection Starts" ); - for( UINT iAdapter=0; iAdapter < lpD3D9->GetAdapterCount(); ++iAdapter ) - { - D3DADAPTER_IDENTIFIER9 adapterIdentifier; - D3DDISPLAYMODE d3ddm; - D3DCAPS9 d3dcaps9; - - lpD3D9->GetAdapterIdentifier( iAdapter, 0, &adapterIdentifier ); - lpD3D9->GetAdapterDisplayMode( iAdapter, &d3ddm ); - lpD3D9->GetDeviceCaps( iAdapter, D3DDEVTYPE_HAL, &d3dcaps9 ); - - mDriverList.push_back( D3D9Driver( iAdapter, d3dcaps9, adapterIdentifier, d3ddm ) ); - } - - LogManager::getSingleton().logMessage( "D3D9: Driver Detection Ends" ); - - return TRUE; - } - - size_t D3D9DriverList::count() const - { - return mDriverList.size(); - } - - D3D9Driver* D3D9DriverList::item( size_t index ) - { - return &mDriverList.at( index ); - } - - D3D9Driver* D3D9DriverList::item( const String &name ) - { - vector::type::iterator it = mDriverList.begin(); - if (it == mDriverList.end()) - return NULL; - - for (;it != mDriverList.end(); ++it) - { - if (it->DriverDescription() == name) - return &(*it); - } - - return NULL; - } + D3D9DriverList::D3D9DriverList() + { + enumerate(); + } + + D3D9DriverList::~D3D9DriverList(void) + { + mDriverList.clear(); + } + + BOOL D3D9DriverList::enumerate() + { + IDirect3D9* lpD3D9 = D3D9RenderSystem::getDirect3D9(); + + LogManager::getSingleton().logMessage( "D3D9: Driver Detection Starts" ); + for( UINT iAdapter=0; iAdapter < lpD3D9->GetAdapterCount(); ++iAdapter ) + { + D3DADAPTER_IDENTIFIER9 adapterIdentifier; + D3DDISPLAYMODE d3ddm; + D3DCAPS9 d3dcaps9; + + lpD3D9->GetAdapterIdentifier( iAdapter, 0, &adapterIdentifier ); + lpD3D9->GetAdapterDisplayMode( iAdapter, &d3ddm ); + lpD3D9->GetDeviceCaps( iAdapter, D3DDEVTYPE_HAL, &d3dcaps9 ); + + mDriverList.push_back( D3D9Driver( iAdapter, d3dcaps9, adapterIdentifier, d3ddm ) ); + } + + LogManager::getSingleton().logMessage( "D3D9: Driver Detection Ends" ); + + return TRUE; + } + + size_t D3D9DriverList::count() const + { + return mDriverList.size(); + } + + D3D9Driver* D3D9DriverList::item( size_t index ) + { + return &mDriverList.at( index ); + } + + D3D9Driver* D3D9DriverList::item( const String &name ) + { + vector::type::iterator it = mDriverList.begin(); + if (it == mDriverList.end()) + return NULL; + + for (;it != mDriverList.end(); ++it) + { + if (it->DriverDescription() == name) + return &(*it); + } + + return NULL; + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9EngineDll.cpp b/RenderSystems/Direct3D9/src/OgreD3D9EngineDll.cpp index 29cadd7f09f..aff3311d677 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9EngineDll.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9EngineDll.cpp @@ -32,18 +32,18 @@ THE SOFTWARE. namespace Ogre { - D3D9Plugin* plugin; - - extern "C" void _OgreD3D9Export dllStartPlugin(void) throw() - { - plugin = OGRE_NEW D3D9Plugin(); - Root::getSingleton().installPlugin(plugin); - } - - extern "C" void _OgreD3D9Export dllStopPlugin(void) - { - Root::getSingleton().uninstallPlugin(plugin); - OGRE_DELETE plugin; - } + D3D9Plugin* plugin; + + extern "C" void _OgreD3D9Export dllStartPlugin(void) throw() + { + plugin = OGRE_NEW D3D9Plugin(); + Root::getSingleton().installPlugin(plugin); + } + + extern "C" void _OgreD3D9Export dllStopPlugin(void) + { + Root::getSingleton().uninstallPlugin(plugin); + OGRE_DELETE plugin; + } } #endif \ No newline at end of file diff --git a/RenderSystems/Direct3D9/src/OgreD3D9GpuProgram.cpp b/RenderSystems/Direct3D9/src/OgreD3D9GpuProgram.cpp index 311a34683e7..804b5cf731e 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9GpuProgram.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9GpuProgram.cpp @@ -37,7 +37,7 @@ THE SOFTWARE. namespace Ogre { D3D9GpuProgram::CmdColumnMajorMatrices D3D9GpuProgram::msCmdColumnMajorMatrices; - D3D9GpuProgram::CmdExternalMicrocode D3D9GpuProgram::msCmdExternalMicrocode; + D3D9GpuProgram::CmdExternalMicrocode D3D9GpuProgram::msCmdExternalMicrocode; //----------------------------------------------------------------------- String D3D9GpuProgram::CmdColumnMajorMatrices::doGet(const void *target) const @@ -51,23 +51,23 @@ namespace Ogre { //----------------------------------------------------------------------- String D3D9GpuProgram::CmdExternalMicrocode::doGet(const void *target) const { - //D3D9GpuProgram* program=const_cast(static_cast(target)); - //LPD3DXBUFFER ptr=program->getExternalMicrocode(); - //nothing to do - return String(); + //D3D9GpuProgram* program=const_cast(static_cast(target)); + //LPD3DXBUFFER ptr=program->getExternalMicrocode(); + //nothing to do + return String(); } void D3D9GpuProgram::CmdExternalMicrocode::doSet(void *target, const String& val) { - D3D9GpuProgram* program = const_cast(static_cast(target)); - const void* buffer = val.data(); - program->setExternalMicrocode(buffer, val.size()); + D3D9GpuProgram* program = const_cast(static_cast(target)); + const void* buffer = val.data(); + program->setExternalMicrocode(buffer, val.size()); } //----------------------------------------------------------------------------- D3D9GpuProgram::D3D9GpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) : GpuProgram(creator, name, handle, group, isManual, loader), mExternalMicrocode(NULL), mColumnMajorMatrices(false) - { + { if (createParamDictionary("D3D9GpuProgram")) { setupBaseParamDictionary(); @@ -76,173 +76,173 @@ namespace Ogre { dict->addParameter(ParameterDef("column_major_matrices", "Whether matrix packing in column-major order.", PT_BOOL),&msCmdColumnMajorMatrices); - dict->addParameter(ParameterDef("external_micro_code", - "the cached external micro code data.", - PT_STRING),&msCmdExternalMicrocode); + dict->addParameter(ParameterDef("external_micro_code", + "the cached external micro code data.", + PT_STRING),&msCmdExternalMicrocode); } } - //----------------------------------------------------------------------------- - D3D9GpuProgram::~D3D9GpuProgram() - { + //----------------------------------------------------------------------------- + D3D9GpuProgram::~D3D9GpuProgram() + { - } + } - //----------------------------------------------------------------------------- - void D3D9GpuProgram::setExternalMicrocode(const void* pMicrocode, size_t size) - { - LPD3DXBUFFER pBuffer=0; - HRESULT hr=D3DXCreateBuffer(size, &pBuffer); - if(pBuffer) - { - memcpy(pBuffer->GetBufferPointer(), pMicrocode, size); - this->setExternalMicrocode(pBuffer); - SAFE_RELEASE(pBuffer); - } - } - //----------------------------------------------------------------------------- - void D3D9GpuProgram::setExternalMicrocode(ID3DXBuffer* pMicrocode) - { - SAFE_RELEASE(mExternalMicrocode); - mExternalMicrocode = pMicrocode; - if(mExternalMicrocode) - { - mExternalMicrocode->AddRef(); - } - } //----------------------------------------------------------------------------- - LPD3DXBUFFER D3D9GpuProgram::getExternalMicrocode(void) - { - return mExternalMicrocode; - } + void D3D9GpuProgram::setExternalMicrocode(const void* pMicrocode, size_t size) + { + LPD3DXBUFFER pBuffer=0; + HRESULT hr=D3DXCreateBuffer(size, &pBuffer); + if(pBuffer) + { + memcpy(pBuffer->GetBufferPointer(), pMicrocode, size); + this->setExternalMicrocode(pBuffer); + SAFE_RELEASE(pBuffer); + } + } + //----------------------------------------------------------------------------- + void D3D9GpuProgram::setExternalMicrocode(ID3DXBuffer* pMicrocode) + { + SAFE_RELEASE(mExternalMicrocode); + mExternalMicrocode = pMicrocode; + if(mExternalMicrocode) + { + mExternalMicrocode->AddRef(); + } + } + //----------------------------------------------------------------------------- + LPD3DXBUFFER D3D9GpuProgram::getExternalMicrocode(void) + { + return mExternalMicrocode; + } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void D3D9GpuProgram::loadImpl(void) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) - { - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); + for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) + { + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); - loadImpl(d3d9Device); - } + loadImpl(d3d9Device); + } } - //----------------------------------------------------------------------------- - void D3D9GpuProgram::loadImpl(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if (mExternalMicrocode) - { - loadFromMicrocode(d3d9Device, mExternalMicrocode); - } - else - { - // Normal load-from-source approach - if (mLoadFromFile) - { - // find & load source code - DataStreamPtr stream = - ResourceGroupManager::getSingleton().openResource( - mFilename, mGroup, true, this); - mSource = stream->getAsString(); - } - - // Call polymorphic load - loadFromSource(d3d9Device); - } - } - //----------------------------------------------------------------------------- - void D3D9GpuProgram::unloadImpl(void) - { - SAFE_RELEASE(mExternalMicrocode); - } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + void D3D9GpuProgram::loadImpl(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if (mExternalMicrocode) + { + loadFromMicrocode(d3d9Device, mExternalMicrocode); + } + else + { + // Normal load-from-source approach + if (mLoadFromFile) + { + // find & load source code + DataStreamPtr stream = + ResourceGroupManager::getSingleton().openResource( + mFilename, mGroup, true, this); + mSource = stream->getAsString(); + } + + // Call polymorphic load + loadFromSource(d3d9Device); + } + } + //----------------------------------------------------------------------------- + void D3D9GpuProgram::unloadImpl(void) + { + SAFE_RELEASE(mExternalMicrocode); + } + //----------------------------------------------------------------------------- void D3D9GpuProgram::loadFromSource(void) { - loadFromSource(NULL); + loadFromSource(NULL); } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void D3D9GpuProgram::loadFromSource( IDirect3DDevice9* d3d9Device ) { - if ( GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(mName) ) - { - getMicrocodeFromCache( d3d9Device ); - } - else - { - compileMicrocode( d3d9Device ); - } - } + if ( GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(mName) ) + { + getMicrocodeFromCache( d3d9Device ); + } + else + { + compileMicrocode( d3d9Device ); + } + } //----------------------------------------------------------------------- void D3D9GpuProgram::getMicrocodeFromCache( IDirect3DDevice9* d3d9Device ) { - GpuProgramManager::Microcode cacheMicrocode = - GpuProgramManager::getSingleton().getMicrocodeFromCache(mName); - - LPD3DXBUFFER microcode; - HRESULT hr=D3DXCreateBuffer(cacheMicrocode->size(), µcode); - - if(microcode) - { - memcpy(microcode->GetBufferPointer(), cacheMicrocode->getPtr(), cacheMicrocode->size()); - } - - loadFromMicrocode(d3d9Device, microcode); - } + GpuProgramManager::Microcode cacheMicrocode = + GpuProgramManager::getSingleton().getMicrocodeFromCache(mName); + + LPD3DXBUFFER microcode; + HRESULT hr=D3DXCreateBuffer(cacheMicrocode->size(), µcode); + + if(microcode) + { + memcpy(microcode->GetBufferPointer(), cacheMicrocode->getPtr(), cacheMicrocode->size()); + } + + loadFromMicrocode(d3d9Device, microcode); + } //----------------------------------------------------------------------- void D3D9GpuProgram::compileMicrocode( IDirect3DDevice9* d3d9Device ) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - // Populate compile flags + // Populate compile flags DWORD compileFlags = 0; - // Create the shader - // Assemble source into microcode - LPD3DXBUFFER microcode; - LPD3DXBUFFER errors; - HRESULT hr = D3DXAssembleShader( - mSource.c_str(), - static_cast(mSource.length()), - NULL, // no #define support - NULL, // no #include support - compileFlags, // standard compile options - µcode, - &errors); - - if (FAILED(hr)) - { - String message = "Cannot assemble D3D9 shader " + mName + " Errors:\n" + - static_cast(errors->GetBufferPointer()); - errors->Release(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message, - "D3D9GpuProgram::loadFromSource"); - } - else - { - if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() ) - { - // create microcode - GpuProgramManager::Microcode newMicrocode = + // Create the shader + // Assemble source into microcode + LPD3DXBUFFER microcode; + LPD3DXBUFFER errors; + HRESULT hr = D3DXAssembleShader( + mSource.c_str(), + static_cast(mSource.length()), + NULL, // no #define support + NULL, // no #include support + compileFlags, // standard compile options + µcode, + &errors); + + if (FAILED(hr)) + { + String message = "Cannot assemble D3D9 shader " + mName + " Errors:\n" + + static_cast(errors->GetBufferPointer()); + errors->Release(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message, + "D3D9GpuProgram::loadFromSource"); + } + else + { + if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() ) + { + // create microcode + GpuProgramManager::Microcode newMicrocode = GpuProgramManager::getSingleton().createMicrocode(microcode->GetBufferSize()); - // save microcode - memcpy(newMicrocode->getPtr(), microcode->GetBufferPointer(), microcode->GetBufferSize()); + // save microcode + memcpy(newMicrocode->getPtr(), microcode->GetBufferPointer(), microcode->GetBufferSize()); - // add to the microcode to the cache - GpuProgramManager::getSingleton().addMicrocodeToCache(mName, newMicrocode); - } - } + // add to the microcode to the cache + GpuProgramManager::getSingleton().addMicrocodeToCache(mName, newMicrocode); + } + } - loadFromMicrocode(d3d9Device, microcode); - - SAFE_RELEASE(microcode); - SAFE_RELEASE(errors); - } + loadFromMicrocode(d3d9Device, microcode); + + SAFE_RELEASE(microcode); + SAFE_RELEASE(errors); + } //----------------------------------------------------------------------- GpuProgramParametersSharedPtr D3D9GpuProgram::createParameters(void) { @@ -253,145 +253,145 @@ namespace Ogre { params->setTransposeMatrices(mColumnMajorMatrices); return params; - } - //----------------------------------------------------------------------------- + } + //----------------------------------------------------------------------------- D3D9GpuVertexProgram::D3D9GpuVertexProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) : D3D9GpuProgram(creator, name, handle, group, isManual, loader) { - mType = GPT_VERTEX_PROGRAM; + mType = GPT_VERTEX_PROGRAM; + } + //----------------------------------------------------------------------------- + D3D9GpuVertexProgram::~D3D9GpuVertexProgram() + { + // have to call this here reather than in Resource destructor + // since calling virtual methods in base destructors causes crash + unload(); } - //----------------------------------------------------------------------------- - D3D9GpuVertexProgram::~D3D9GpuVertexProgram() - { - // have to call this here reather than in Resource destructor - // since calling virtual methods in base destructors causes crash - unload(); - } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void D3D9GpuVertexProgram::loadFromMicrocode(IDirect3DDevice9* d3d9Device, ID3DXBuffer* microcode) - { - if (d3d9Device == NULL) - { - for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) - { - IDirect3DDevice9* curD3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); - - loadFromMicrocode(curD3d9Device, microcode); - } - } - - DeviceToVertexShaderIterator it = mMapDeviceToVertexShader.find(d3d9Device); - - if (it != mMapDeviceToVertexShader.end()) - SAFE_RELEASE(it->second); - - if (isSupported()) - { - // Create the shader - IDirect3DVertexShader9* pVertexShader; - HRESULT hr; - - hr = d3d9Device->CreateVertexShader( - static_cast(microcode->GetBufferPointer()), - &pVertexShader); - - if (FAILED(hr)) - { - String errMsg = "Cannot create D3D9 vertex shader " + mName + " from microcode "; - switch (hr) - { - case D3DERR_INVALIDCALL: - errMsg += "(D3DERR_INVALIDCALL)"; - break; - case D3DERR_OUTOFVIDEOMEMORY: - errMsg += "(D3DERR_OUTOFVIDEOMEMORY)"; - break; - case E_OUTOFMEMORY: - errMsg += "(E_OUTOFMEMORY)"; - break; - default: - break; - } - - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - errMsg, - "D3D9GpuVertexProgram::loadFromMicrocode"); - - } - - mMapDeviceToVertexShader[d3d9Device] = pVertexShader; - } - else - { - LogManager::getSingleton().logMessage( - "Unsupported D3D9 vertex shader '" + mName + "' was not loaded."); - - mMapDeviceToVertexShader[d3d9Device] = NULL; - } + { + if (d3d9Device == NULL) + { + for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) + { + IDirect3DDevice9* curD3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); + + loadFromMicrocode(curD3d9Device, microcode); + } + } + + DeviceToVertexShaderIterator it = mMapDeviceToVertexShader.find(d3d9Device); + + if (it != mMapDeviceToVertexShader.end()) + SAFE_RELEASE(it->second); + + if (isSupported()) + { + // Create the shader + IDirect3DVertexShader9* pVertexShader; + HRESULT hr; + + hr = d3d9Device->CreateVertexShader( + static_cast(microcode->GetBufferPointer()), + &pVertexShader); + + if (FAILED(hr)) + { + String errMsg = "Cannot create D3D9 vertex shader " + mName + " from microcode "; + switch (hr) + { + case D3DERR_INVALIDCALL: + errMsg += "(D3DERR_INVALIDCALL)"; + break; + case D3DERR_OUTOFVIDEOMEMORY: + errMsg += "(D3DERR_OUTOFVIDEOMEMORY)"; + break; + case E_OUTOFMEMORY: + errMsg += "(E_OUTOFMEMORY)"; + break; + default: + break; + } + + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + errMsg, + "D3D9GpuVertexProgram::loadFromMicrocode"); + + } + + mMapDeviceToVertexShader[d3d9Device] = pVertexShader; + } + else + { + LogManager::getSingleton().logMessage( + "Unsupported D3D9 vertex shader '" + mName + "' was not loaded."); + + mMapDeviceToVertexShader[d3d9Device] = NULL; + } } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void D3D9GpuVertexProgram::unloadImpl(void) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + D3D9_DEVICE_ACCESS_CRITICAL_SECTION DeviceToVertexShaderIterator it = mMapDeviceToVertexShader.begin(); - while (it != mMapDeviceToVertexShader.end()) - { - SAFE_RELEASE(it->second); - ++it; - } - mMapDeviceToVertexShader.clear(); - D3D9GpuProgram::unloadImpl(); + while (it != mMapDeviceToVertexShader.end()) + { + SAFE_RELEASE(it->second); + ++it; + } + mMapDeviceToVertexShader.clear(); + D3D9GpuProgram::unloadImpl(); + } + + //----------------------------------------------------------------------------- + void D3D9GpuVertexProgram::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) + { + + } + + //----------------------------------------------------------------------------- + void D3D9GpuVertexProgram::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToVertexShaderIterator it; + + // Find the shader of this device. + it = mMapDeviceToVertexShader.find(d3d9Device); + + // Case shader found -> release it and erase from map. + if (it != mMapDeviceToVertexShader.end()) + { + SAFE_RELEASE(it->second); + mMapDeviceToVertexShader.erase(it); + } + } + + //----------------------------------------------------------------------------- + IDirect3DVertexShader9* D3D9GpuVertexProgram::getVertexShader( void ) + { + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); + DeviceToVertexShaderIterator it; + + // Find the shader of this device. + it = mMapDeviceToVertexShader.find(d3d9Device); + + // Shader was not found -> load it. + if (it == mMapDeviceToVertexShader.end()) + { + loadImpl(d3d9Device); + it = mMapDeviceToVertexShader.find(d3d9Device); + } + + return it->second; } - //----------------------------------------------------------------------------- - void D3D9GpuVertexProgram::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) - { - - } - - //----------------------------------------------------------------------------- - void D3D9GpuVertexProgram::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToVertexShaderIterator it; - - // Find the shader of this device. - it = mMapDeviceToVertexShader.find(d3d9Device); - - // Case shader found -> release it and erase from map. - if (it != mMapDeviceToVertexShader.end()) - { - SAFE_RELEASE(it->second); - mMapDeviceToVertexShader.erase(it); - } - } - - //----------------------------------------------------------------------------- - IDirect3DVertexShader9* D3D9GpuVertexProgram::getVertexShader( void ) - { - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); - DeviceToVertexShaderIterator it; - - // Find the shader of this device. - it = mMapDeviceToVertexShader.find(d3d9Device); - - // Shader was not found -> load it. - if (it == mMapDeviceToVertexShader.end()) - { - loadImpl(d3d9Device); - it = mMapDeviceToVertexShader.find(d3d9Device); - } - - return it->second; - } - - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- D3D9GpuFragmentProgram::D3D9GpuFragmentProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) @@ -399,107 +399,107 @@ namespace Ogre { { mType = GPT_FRAGMENT_PROGRAM; } - //----------------------------------------------------------------------------- - D3D9GpuFragmentProgram::~D3D9GpuFragmentProgram() - { - // have to call this here reather than in Resource destructor - // since calling virtual methods in base destructors causes crash - unload(); - } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + D3D9GpuFragmentProgram::~D3D9GpuFragmentProgram() + { + // have to call this here reather than in Resource destructor + // since calling virtual methods in base destructors causes crash + unload(); + } + //----------------------------------------------------------------------------- void D3D9GpuFragmentProgram::loadFromMicrocode(IDirect3DDevice9* d3d9Device, ID3DXBuffer* microcode) { - DeviceToPixelShaderIterator it = mMapDeviceToPixelShader.find(d3d9Device); - - if (it != mMapDeviceToPixelShader.end()) - SAFE_RELEASE(it->second); - - if (isSupported()) - { - // Create the shader - IDirect3DPixelShader9* pPixelShader; - HRESULT hr; - - hr = d3d9Device->CreatePixelShader( - static_cast(microcode->GetBufferPointer()), - &pPixelShader); - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D9 pixel shader " + mName + " from microcode.", - "D3D9GpuFragmentProgram::loadFromMicrocode"); - - } - - mMapDeviceToPixelShader[d3d9Device] = pPixelShader; - } - else - { - LogManager::getSingleton().logMessage( - "Unsupported D3D9 pixel shader '" + mName + "' was not loaded."); - - mMapDeviceToPixelShader[d3d9Device] = NULL; - } + DeviceToPixelShaderIterator it = mMapDeviceToPixelShader.find(d3d9Device); + + if (it != mMapDeviceToPixelShader.end()) + SAFE_RELEASE(it->second); + + if (isSupported()) + { + // Create the shader + IDirect3DPixelShader9* pPixelShader; + HRESULT hr; + + hr = d3d9Device->CreatePixelShader( + static_cast(microcode->GetBufferPointer()), + &pPixelShader); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D9 pixel shader " + mName + " from microcode.", + "D3D9GpuFragmentProgram::loadFromMicrocode"); + + } + + mMapDeviceToPixelShader[d3d9Device] = pPixelShader; + } + else + { + LogManager::getSingleton().logMessage( + "Unsupported D3D9 pixel shader '" + mName + "' was not loaded."); + + mMapDeviceToPixelShader[d3d9Device] = NULL; + } } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void D3D9GpuFragmentProgram::unloadImpl(void) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - DeviceToPixelShaderIterator it = mMapDeviceToPixelShader.begin(); + DeviceToPixelShaderIterator it = mMapDeviceToPixelShader.begin(); - while (it != mMapDeviceToPixelShader.end()) - { - SAFE_RELEASE(it->second); - ++it; - } - mMapDeviceToPixelShader.clear(); - D3D9GpuProgram::unloadImpl(); + while (it != mMapDeviceToPixelShader.end()) + { + SAFE_RELEASE(it->second); + ++it; + } + mMapDeviceToPixelShader.clear(); + D3D9GpuProgram::unloadImpl(); } - //----------------------------------------------------------------------------- - void D3D9GpuFragmentProgram::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) - { - - } - - //----------------------------------------------------------------------------- - void D3D9GpuFragmentProgram::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToPixelShaderIterator it; - - // Find the shader of this device. - it = mMapDeviceToPixelShader.find(d3d9Device); - - // Case shader found -> release it and erase from map. - if (it != mMapDeviceToPixelShader.end()) - { - SAFE_RELEASE(it->second); - mMapDeviceToPixelShader.erase(it); - } - } - - //----------------------------------------------------------------------------- - IDirect3DPixelShader9* D3D9GpuFragmentProgram::getPixelShader( void ) - { - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); - DeviceToPixelShaderIterator it; - - // Find the shader of this device. - it = mMapDeviceToPixelShader.find(d3d9Device); - - // Shader was not found -> load it. - if (it == mMapDeviceToPixelShader.end()) - { - loadImpl(d3d9Device); - it = mMapDeviceToPixelShader.find(d3d9Device); - } - - return it->second; - } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- + void D3D9GpuFragmentProgram::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) + { + + } + + //----------------------------------------------------------------------------- + void D3D9GpuFragmentProgram::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToPixelShaderIterator it; + + // Find the shader of this device. + it = mMapDeviceToPixelShader.find(d3d9Device); + + // Case shader found -> release it and erase from map. + if (it != mMapDeviceToPixelShader.end()) + { + SAFE_RELEASE(it->second); + mMapDeviceToPixelShader.erase(it); + } + } + + //----------------------------------------------------------------------------- + IDirect3DPixelShader9* D3D9GpuFragmentProgram::getPixelShader( void ) + { + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); + DeviceToPixelShaderIterator it; + + // Find the shader of this device. + it = mMapDeviceToPixelShader.find(d3d9Device); + + // Shader was not found -> load it. + if (it == mMapDeviceToPixelShader.end()) + { + loadImpl(d3d9Device); + it = mMapDeviceToPixelShader.find(d3d9Device); + } + + return it->second; + } + //----------------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9HLSLProgram.cpp b/RenderSystems/Direct3D9/src/OgreD3D9HLSLProgram.cpp index 39245eeee6c..3f807c0b4dd 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9HLSLProgram.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9HLSLProgram.cpp @@ -37,106 +37,106 @@ namespace Ogre { D3D9HLSLProgram::CmdTarget D3D9HLSLProgram::msCmdTarget; D3D9HLSLProgram::CmdPreprocessorDefines D3D9HLSLProgram::msCmdPreprocessorDefines; D3D9HLSLProgram::CmdColumnMajorMatrices D3D9HLSLProgram::msCmdColumnMajorMatrices; - D3D9HLSLProgram::CmdOptimisation D3D9HLSLProgram::msCmdOptimisation; - D3D9HLSLProgram::CmdMicrocode D3D9HLSLProgram::msCmdMicrocode; - D3D9HLSLProgram::CmdAssemblerCode D3D9HLSLProgram::msCmdAssemblerCode; + D3D9HLSLProgram::CmdOptimisation D3D9HLSLProgram::msCmdOptimisation; + D3D9HLSLProgram::CmdMicrocode D3D9HLSLProgram::msCmdMicrocode; + D3D9HLSLProgram::CmdAssemblerCode D3D9HLSLProgram::msCmdAssemblerCode; D3D9HLSLProgram::CmdBackwardsCompatibility D3D9HLSLProgram::msCmdBackwardsCompatibility; - class _OgreD3D9Export HLSLIncludeHandler : public ID3DXInclude - { - public: - HLSLIncludeHandler(Resource* sourceProgram) - : mProgram(sourceProgram) {} - ~HLSLIncludeHandler() {} - - STDMETHOD(Open)(D3DXINCLUDE_TYPE IncludeType, - LPCSTR pFileName, - LPCVOID pParentData, - LPCVOID *ppData, - UINT *pByteLen - ) - { - // find & load source code - DataStreamPtr stream = - ResourceGroupManager::getSingleton().openResource( - String(pFileName), mProgram->getGroup(), true, mProgram); - - String source = stream->getAsString(); - // copy into separate c-string - // Note - must NOT copy the null terminator, otherwise this will terminate - // the entire program string! - *pByteLen = static_cast(source.length()); - char* pChar = OGRE_ALLOC_T(char, *pByteLen, MEMCATEGORY_RESOURCE); - memcpy(pChar, source.c_str(), *pByteLen); - *ppData = pChar; - - return S_OK; - } - - STDMETHOD(Close)(LPCVOID pData) - { - OGRE_FREE(pData, MEMCATEGORY_RESOURCE); - return S_OK; - } - protected: - Resource* mProgram; - - - }; + class _OgreD3D9Export HLSLIncludeHandler : public ID3DXInclude + { + public: + HLSLIncludeHandler(Resource* sourceProgram) + : mProgram(sourceProgram) {} + ~HLSLIncludeHandler() {} + + STDMETHOD(Open)(D3DXINCLUDE_TYPE IncludeType, + LPCSTR pFileName, + LPCVOID pParentData, + LPCVOID *ppData, + UINT *pByteLen + ) + { + // find & load source code + DataStreamPtr stream = + ResourceGroupManager::getSingleton().openResource( + String(pFileName), mProgram->getGroup(), true, mProgram); + + String source = stream->getAsString(); + // copy into separate c-string + // Note - must NOT copy the null terminator, otherwise this will terminate + // the entire program string! + *pByteLen = static_cast(source.length()); + char* pChar = OGRE_ALLOC_T(char, *pByteLen, MEMCATEGORY_RESOURCE); + memcpy(pChar, source.c_str(), *pByteLen); + *ppData = pChar; + + return S_OK; + } + + STDMETHOD(Close)(LPCVOID pData) + { + OGRE_FREE(pData, MEMCATEGORY_RESOURCE); + return S_OK; + } + protected: + Resource* mProgram; + + + }; //----------------------------------------------------------------------- //----------------------------------------------------------------------- void D3D9HLSLProgram::loadFromSource(void) { - if ( GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(String("D3D9_HLSL_") + mName) ) - { - getMicrocodeFromCache(); - } - else - { - compileMicrocode(); - } - } + if ( GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(String("D3D9_HLSL_") + mName) ) + { + getMicrocodeFromCache(); + } + else + { + compileMicrocode(); + } + } //----------------------------------------------------------------------- void D3D9HLSLProgram::getMicrocodeFromCache(void) { - GpuProgramManager::Microcode cacheMicrocode = - GpuProgramManager::getSingleton().getMicrocodeFromCache(String("D3D9_HLSL_") + mName); - - cacheMicrocode->seek(0); - - // get size the microcode - size_t microcodeSize = 0; - cacheMicrocode->read(µcodeSize, sizeof(size_t)); - - // get microcode - HRESULT hr=D3DXCreateBuffer(microcodeSize, &mMicroCode); - cacheMicrocode->read(mMicroCode->GetBufferPointer(), microcodeSize); - - // get size of param map - size_t parametersMapSize = 0; - cacheMicrocode->read(¶metersMapSize, sizeof(size_t)); - - // get params - for(size_t i = 0 ; i < parametersMapSize ; i++) - { - String paramName; - size_t stringSize = 0; - GpuConstantDefinition def; - - // get string size - cacheMicrocode->read(&stringSize, sizeof(size_t)); - - // get string - paramName.resize(stringSize); - cacheMicrocode->read(¶mName[0], stringSize); - - // get def - cacheMicrocode->read( &def, sizeof(GpuConstantDefinition)); - - mParametersMap.insert(GpuConstantDefinitionMap::value_type(paramName, def)); - } - } + GpuProgramManager::Microcode cacheMicrocode = + GpuProgramManager::getSingleton().getMicrocodeFromCache(String("D3D9_HLSL_") + mName); + + cacheMicrocode->seek(0); + + // get size the microcode + size_t microcodeSize = 0; + cacheMicrocode->read(µcodeSize, sizeof(size_t)); + + // get microcode + HRESULT hr=D3DXCreateBuffer(microcodeSize, &mMicroCode); + cacheMicrocode->read(mMicroCode->GetBufferPointer(), microcodeSize); + + // get size of param map + size_t parametersMapSize = 0; + cacheMicrocode->read(¶metersMapSize, sizeof(size_t)); + + // get params + for(size_t i = 0 ; i < parametersMapSize ; i++) + { + String paramName; + size_t stringSize = 0; + GpuConstantDefinition def; + + // get string size + cacheMicrocode->read(&stringSize, sizeof(size_t)); + + // get string + paramName.resize(stringSize); + cacheMicrocode->read(¶mName[0], stringSize); + + // get def + cacheMicrocode->read( &def, sizeof(GpuConstantDefinition)); + + mParametersMap.insert(GpuConstantDefinitionMap::value_type(paramName, def)); + } + } //----------------------------------------------------------------------- void D3D9HLSLProgram::compileMicrocode(void) { @@ -157,20 +157,20 @@ namespace Ogre { macro.Name = &stringBuffer[pos]; macro.Definition = 0; - String::size_type start_pos=pos; + String::size_type start_pos=pos; // Find delims pos = stringBuffer.find_first_of(";,=", pos); - if(start_pos==pos) - { - if( pos >= stringBuffer.length() - 1 ) - { - break; - } - ++pos; - continue; - } + if(start_pos==pos) + { + if( pos >= stringBuffer.length() - 1 ) + { + break; + } + ++pos; + continue; + } if (pos != String::npos) { @@ -194,18 +194,18 @@ namespace Ogre { stringBuffer[pos++] = '\0'; } } - else - { - macro.Definition = "1"; - } - if(strlen(macro.Name)>0) - { - defines.push_back(macro); - } - else - { - break; - } + else + { + macro.Definition = "1"; + } + if(strlen(macro.Name)>0) + { + defines.push_back(macro); + } + else + { + break; + } } // Add NULL terminator @@ -226,35 +226,35 @@ namespace Ogre { compileFlags |= D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY; #if OGRE_DEBUG_MODE - compileFlags |= D3DXSHADER_DEBUG; + compileFlags |= D3DXSHADER_DEBUG; #endif - switch (mOptimisationLevel) - { - case OPT_DEFAULT: - compileFlags |= D3DXSHADER_OPTIMIZATION_LEVEL1; - break; - case OPT_NONE: - compileFlags |= D3DXSHADER_SKIPOPTIMIZATION; - break; - case OPT_0: - compileFlags |= D3DXSHADER_OPTIMIZATION_LEVEL0; - break; - case OPT_1: - compileFlags |= D3DXSHADER_OPTIMIZATION_LEVEL1; - break; - case OPT_2: - compileFlags |= D3DXSHADER_OPTIMIZATION_LEVEL2; - break; - case OPT_3: - compileFlags |= D3DXSHADER_OPTIMIZATION_LEVEL3; - break; - } + switch (mOptimisationLevel) + { + case OPT_DEFAULT: + compileFlags |= D3DXSHADER_OPTIMIZATION_LEVEL1; + break; + case OPT_NONE: + compileFlags |= D3DXSHADER_SKIPOPTIMIZATION; + break; + case OPT_0: + compileFlags |= D3DXSHADER_OPTIMIZATION_LEVEL0; + break; + case OPT_1: + compileFlags |= D3DXSHADER_OPTIMIZATION_LEVEL1; + break; + case OPT_2: + compileFlags |= D3DXSHADER_OPTIMIZATION_LEVEL2; + break; + case OPT_3: + compileFlags |= D3DXSHADER_OPTIMIZATION_LEVEL3; + break; + } LPD3DXBUFFER errors = 0; - // include handler - HLSLIncludeHandler includeHandler(this); + // include handler + HLSLIncludeHandler includeHandler(this); LPD3DXCONSTANTTABLE pConstTable; @@ -274,109 +274,109 @@ namespace Ogre { if (FAILED(hr)) { String message = "Cannot assemble D3D9 high-level shader " + mName; - - if( errors ) - { - message += String(" Errors:\n") + static_cast(errors->GetBufferPointer()); - errors->Release(); - } + + if( errors ) + { + message += String(" Errors:\n") + static_cast(errors->GetBufferPointer()); + errors->Release(); + } OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, message, "D3D9HLSLProgram::loadFromSource"); } - else - { + else + { - // Get contents of the constant table - D3DXCONSTANTTABLE_DESC desc; - HRESULT hr = pConstTable->GetDesc(&desc); + // Get contents of the constant table + D3DXCONSTANTTABLE_DESC desc; + HRESULT hr = pConstTable->GetDesc(&desc); - createParameterMappingStructures(true); + createParameterMappingStructures(true); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Cannot retrieve constant descriptions from HLSL program.", - "D3D9HLSLProgram::buildParameterNameMap"); - } - // Iterate over the constants - for (unsigned int i = 0; i < desc.Constants; ++i) - { - // Recursively descend through the structure levels - processParamElement(pConstTable, NULL, "", i); - } + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Cannot retrieve constant descriptions from HLSL program.", + "D3D9HLSLProgram::buildParameterNameMap"); + } + // Iterate over the constants + for (unsigned int i = 0; i < desc.Constants; ++i) + { + // Recursively descend through the structure levels + processParamElement(pConstTable, NULL, "", i); + } - SAFE_RELEASE(pConstTable); + SAFE_RELEASE(pConstTable); - if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() ) - { - addMicrocodeToCache(); - } - } + if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() ) + { + addMicrocodeToCache(); + } + } } //----------------------------------------------------------------------- - void D3D9HLSLProgram::addMicrocodeToCache() - { - // add to the microcode to the cache - String name = String("D3D9_HLSL_") + mName; + void D3D9HLSLProgram::addMicrocodeToCache() + { + // add to the microcode to the cache + String name = String("D3D9_HLSL_") + mName; - size_t sizeOfBuffer = sizeof(size_t) + mMicroCode->GetBufferSize() + sizeof(size_t) + mParametersMapSizeAsBuffer; - + size_t sizeOfBuffer = sizeof(size_t) + mMicroCode->GetBufferSize() + sizeof(size_t) + mParametersMapSizeAsBuffer; + // create microcode GpuProgramManager::Microcode newMicrocode = GpuProgramManager::getSingleton().createMicrocode(sizeOfBuffer); - // save size of microcode - size_t microcodeSize = mMicroCode->GetBufferSize(); - newMicrocode->write(µcodeSize, sizeof(size_t)); + // save size of microcode + size_t microcodeSize = mMicroCode->GetBufferSize(); + newMicrocode->write(µcodeSize, sizeof(size_t)); - // save microcode - newMicrocode->write(mMicroCode->GetBufferPointer(), microcodeSize); + // save microcode + newMicrocode->write(mMicroCode->GetBufferPointer(), microcodeSize); - // save size of param map - size_t parametersMapSize = mParametersMap.size(); - newMicrocode->write(¶metersMapSize, sizeof(size_t)); + // save size of param map + size_t parametersMapSize = mParametersMap.size(); + newMicrocode->write(¶metersMapSize, sizeof(size_t)); - // save params - GpuConstantDefinitionMap::const_iterator iter = mParametersMap.begin(); - GpuConstantDefinitionMap::const_iterator iterE = mParametersMap.end(); - for (; iter != iterE ; ++iter) - { - const String & paramName = iter->first; - const GpuConstantDefinition & def = iter->second; + // save params + GpuConstantDefinitionMap::const_iterator iter = mParametersMap.begin(); + GpuConstantDefinitionMap::const_iterator iterE = mParametersMap.end(); + for (; iter != iterE ; ++iter) + { + const String & paramName = iter->first; + const GpuConstantDefinition & def = iter->second; - // save string size - size_t stringSize = paramName.size(); - newMicrocode->write(&stringSize, sizeof(size_t)); + // save string size + size_t stringSize = paramName.size(); + newMicrocode->write(&stringSize, sizeof(size_t)); - // save string - newMicrocode->write(¶mName[0], stringSize); + // save string + newMicrocode->write(¶mName[0], stringSize); - // save def - newMicrocode->write(&def, sizeof(GpuConstantDefinition)); - } + // save def + newMicrocode->write(&def, sizeof(GpuConstantDefinition)); + } - // add to the microcode to the cache - GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode); - } + // add to the microcode to the cache + GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode); + } //----------------------------------------------------------------------- void D3D9HLSLProgram::createLowLevelImpl(void) { - if (!mCompileError) - { - // Create a low-level program, give it the same name as us - mAssemblerProgram = - GpuProgramManager::getSingleton().createProgramFromString( - mName, - mGroup, - "",// dummy source, since we'll be using microcode - mType, - mTarget); - static_cast(mAssemblerProgram.get())->setExternalMicrocode(mMicroCode); - } + if (!mCompileError) + { + // Create a low-level program, give it the same name as us + mAssemblerProgram = + GpuProgramManager::getSingleton().createProgramFromString( + mName, + mGroup, + "",// dummy source, since we'll be using microcode + mType, + mTarget); + static_cast(mAssemblerProgram.get())->setExternalMicrocode(mMicroCode); + } } //----------------------------------------------------------------------- @@ -389,39 +389,39 @@ namespace Ogre { //----------------------------------------------------------------------- void D3D9HLSLProgram::buildConstantDefinitions() const { - mConstantDefs->floatBufferSize = mFloatLogicalToPhysical->bufferSize; - mConstantDefs->intBufferSize = mIntLogicalToPhysical->bufferSize; + mConstantDefs->floatBufferSize = mFloatLogicalToPhysical->bufferSize; + mConstantDefs->intBufferSize = mIntLogicalToPhysical->bufferSize; - GpuConstantDefinitionMap::const_iterator iter = mParametersMap.begin(); - GpuConstantDefinitionMap::const_iterator iterE = mParametersMap.end(); - for (; iter != iterE ; ++iter) - { - const String & paramName = iter->first; - GpuConstantDefinition def = iter->second; + GpuConstantDefinitionMap::const_iterator iter = mParametersMap.begin(); + GpuConstantDefinitionMap::const_iterator iterE = mParametersMap.end(); + for (; iter != iterE ; ++iter) + { + const String & paramName = iter->first; + GpuConstantDefinition def = iter->second; - mConstantDefs->map.insert(GpuConstantDefinitionMap::value_type(iter->first, iter->second)); + mConstantDefs->map.insert(GpuConstantDefinitionMap::value_type(iter->first, iter->second)); - // Record logical / physical mapping - if (def.isFloat()) - { + // Record logical / physical mapping + if (def.isFloat()) + { OGRE_LOCK_MUTEX(mFloatLogicalToPhysical->mutex); - mFloatLogicalToPhysical->map.insert( - GpuLogicalIndexUseMap::value_type(def.logicalIndex, - GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); - mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; - } - else - { + mFloatLogicalToPhysical->map.insert( + GpuLogicalIndexUseMap::value_type(def.logicalIndex, + GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); + mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; + } + else + { OGRE_LOCK_MUTEX(mIntLogicalToPhysical->mutex); - mIntLogicalToPhysical->map.insert( - GpuLogicalIndexUseMap::value_type(def.logicalIndex, - GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); - mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; - } - - // Deal with array indexing - mConstantDefs->generateConstantDefinitionArrayEntries(paramName, def); - } + mIntLogicalToPhysical->map.insert( + GpuLogicalIndexUseMap::value_type(def.logicalIndex, + GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); + mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; + } + + // Deal with array indexing + mConstantDefs->generateConstantDefinitionArrayEntries(paramName, def); + } } //----------------------------------------------------------------------- @@ -448,11 +448,11 @@ namespace Ogre { if (paramName.at(0) == '$') paramName.erase(paramName.begin()); - // Also trim the '[0]' suffix if it exists, we will add our own indexing later - if (StringUtil::endsWith(paramName, "[0]", false)) - { - paramName.erase(paramName.size() - 3); - } + // Also trim the '[0]' suffix if it exists, we will add our own indexing later + if (StringUtil::endsWith(paramName, "[0]", false)) + { + paramName.erase(paramName.size() - 3); + } if (desc.Class == D3DXPC_STRUCT) @@ -473,171 +473,171 @@ namespace Ogre { size_t paramIndex = desc.RegisterIndex; String name = prefix + paramName; - GpuConstantDefinition def; - def.logicalIndex = paramIndex; - // populate type, array size & element size - populateDef(desc, def); - if (def.isFloat()) - { - def.physicalIndex = mFloatLogicalToPhysical->bufferSize; - OGRE_LOCK_MUTEX(mFloatLogicalToPhysical->mutex); - mFloatLogicalToPhysical->map.insert( - GpuLogicalIndexUseMap::value_type(paramIndex, - GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); - mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; - } - else - { - def.physicalIndex = mIntLogicalToPhysical->bufferSize; - OGRE_LOCK_MUTEX(mIntLogicalToPhysical->mutex); - mIntLogicalToPhysical->map.insert( - GpuLogicalIndexUseMap::value_type(paramIndex, - GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); - mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; - } - - if( mParametersMap.find(name) == mParametersMap.end()) - { - mParametersMap.insert(GpuConstantDefinitionMap::value_type(name, def)); - mParametersMapSizeAsBuffer += sizeof(size_t); - mParametersMapSizeAsBuffer += name.size(); - mParametersMapSizeAsBuffer += sizeof(GpuConstantDefinition); - } + GpuConstantDefinition def; + def.logicalIndex = paramIndex; + // populate type, array size & element size + populateDef(desc, def); + if (def.isFloat()) + { + def.physicalIndex = mFloatLogicalToPhysical->bufferSize; + OGRE_LOCK_MUTEX(mFloatLogicalToPhysical->mutex); + mFloatLogicalToPhysical->map.insert( + GpuLogicalIndexUseMap::value_type(paramIndex, + GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); + mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; + } + else + { + def.physicalIndex = mIntLogicalToPhysical->bufferSize; + OGRE_LOCK_MUTEX(mIntLogicalToPhysical->mutex); + mIntLogicalToPhysical->map.insert( + GpuLogicalIndexUseMap::value_type(paramIndex, + GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL))); + mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize; + } + + if( mParametersMap.find(name) == mParametersMap.end()) + { + mParametersMap.insert(GpuConstantDefinitionMap::value_type(name, def)); + mParametersMapSizeAsBuffer += sizeof(size_t); + mParametersMapSizeAsBuffer += name.size(); + mParametersMapSizeAsBuffer += sizeof(GpuConstantDefinition); + } } } } - //----------------------------------------------------------------------- - void D3D9HLSLProgram::populateDef(D3DXCONSTANT_DESC& d3dDesc, GpuConstantDefinition& def) const - { - def.arraySize = d3dDesc.Elements; - switch(d3dDesc.Type) - { - case D3DXPT_INT: - switch(d3dDesc.Columns) - { - case 1: - def.constType = GCT_INT1; - break; - case 2: - def.constType = GCT_INT2; - break; - case 3: - def.constType = GCT_INT3; - break; - case 4: - def.constType = GCT_INT4; - break; - } // columns - break; - case D3DXPT_FLOAT: - switch(d3dDesc.Class) - { - case D3DXPC_MATRIX_COLUMNS: - case D3DXPC_MATRIX_ROWS: - { - int firstDim, secondDim; - firstDim = d3dDesc.RegisterCount / d3dDesc.Elements; - if (d3dDesc.Class == D3DXPC_MATRIX_ROWS) - { - secondDim = d3dDesc.Columns; - } - else - { - secondDim = d3dDesc.Rows; - } - switch(firstDim) - { - case 2: - switch(secondDim) - { - case 2: - def.constType = GCT_MATRIX_2X2; - def.elementSize = 8; // HLSL always packs - break; - case 3: - def.constType = GCT_MATRIX_2X3; - def.elementSize = 8; // HLSL always packs - break; - case 4: - def.constType = GCT_MATRIX_2X4; - def.elementSize = 8; - break; - } // columns - break; - case 3: - switch(secondDim) - { - case 2: - def.constType = GCT_MATRIX_3X2; - def.elementSize = 12; // HLSL always packs - break; - case 3: - def.constType = GCT_MATRIX_3X3; - def.elementSize = 12; // HLSL always packs - break; - case 4: - def.constType = GCT_MATRIX_3X4; - def.elementSize = 12; - break; - } // columns - break; - case 4: - switch(secondDim) - { - case 2: - def.constType = GCT_MATRIX_4X2; - def.elementSize = 16; // HLSL always packs - break; - case 3: - def.constType = GCT_MATRIX_4X3; - def.elementSize = 16; // HLSL always packs - break; - case 4: - def.constType = GCT_MATRIX_4X4; - def.elementSize = 16; - break; - } // secondDim - break; - - } // firstDim - } - break; - case D3DXPC_SCALAR: - case D3DXPC_VECTOR: - switch(d3dDesc.Columns) - { - case 1: - def.constType = GCT_FLOAT1; - break; - case 2: - def.constType = GCT_FLOAT2; - break; - case 3: - def.constType = GCT_FLOAT3; - break; - case 4: - def.constType = GCT_FLOAT4; - break; - } // columns - break; - } - default: - // not mapping samplers, don't need to take the space - break; - }; - - // D3D9 pads to 4 elements - def.elementSize = GpuConstantDefinition::getElementSize(def.constType, true); - - - } - - LPD3DXBUFFER D3D9HLSLProgram::getMicroCode() - { - return mMicroCode; - } + //----------------------------------------------------------------------- + void D3D9HLSLProgram::populateDef(D3DXCONSTANT_DESC& d3dDesc, GpuConstantDefinition& def) const + { + def.arraySize = d3dDesc.Elements; + switch(d3dDesc.Type) + { + case D3DXPT_INT: + switch(d3dDesc.Columns) + { + case 1: + def.constType = GCT_INT1; + break; + case 2: + def.constType = GCT_INT2; + break; + case 3: + def.constType = GCT_INT3; + break; + case 4: + def.constType = GCT_INT4; + break; + } // columns + break; + case D3DXPT_FLOAT: + switch(d3dDesc.Class) + { + case D3DXPC_MATRIX_COLUMNS: + case D3DXPC_MATRIX_ROWS: + { + int firstDim, secondDim; + firstDim = d3dDesc.RegisterCount / d3dDesc.Elements; + if (d3dDesc.Class == D3DXPC_MATRIX_ROWS) + { + secondDim = d3dDesc.Columns; + } + else + { + secondDim = d3dDesc.Rows; + } + switch(firstDim) + { + case 2: + switch(secondDim) + { + case 2: + def.constType = GCT_MATRIX_2X2; + def.elementSize = 8; // HLSL always packs + break; + case 3: + def.constType = GCT_MATRIX_2X3; + def.elementSize = 8; // HLSL always packs + break; + case 4: + def.constType = GCT_MATRIX_2X4; + def.elementSize = 8; + break; + } // columns + break; + case 3: + switch(secondDim) + { + case 2: + def.constType = GCT_MATRIX_3X2; + def.elementSize = 12; // HLSL always packs + break; + case 3: + def.constType = GCT_MATRIX_3X3; + def.elementSize = 12; // HLSL always packs + break; + case 4: + def.constType = GCT_MATRIX_3X4; + def.elementSize = 12; + break; + } // columns + break; + case 4: + switch(secondDim) + { + case 2: + def.constType = GCT_MATRIX_4X2; + def.elementSize = 16; // HLSL always packs + break; + case 3: + def.constType = GCT_MATRIX_4X3; + def.elementSize = 16; // HLSL always packs + break; + case 4: + def.constType = GCT_MATRIX_4X4; + def.elementSize = 16; + break; + } // secondDim + break; + + } // firstDim + } + break; + case D3DXPC_SCALAR: + case D3DXPC_VECTOR: + switch(d3dDesc.Columns) + { + case 1: + def.constType = GCT_FLOAT1; + break; + case 2: + def.constType = GCT_FLOAT2; + break; + case 3: + def.constType = GCT_FLOAT3; + break; + case 4: + def.constType = GCT_FLOAT4; + break; + } // columns + break; + } + default: + // not mapping samplers, don't need to take the space + break; + }; + + // D3D9 pads to 4 elements + def.elementSize = GpuConstantDefinition::getElementSize(def.constType, true); + + + } + + LPD3DXBUFFER D3D9HLSLProgram::getMicroCode() + { + return mMicroCode; + } //----------------------------------------------------------------------- D3D9HLSLProgram::D3D9HLSLProgram(ResourceManager* creator, const String& name, @@ -650,8 +650,8 @@ namespace Ogre { , mColumnMajorMatrices(true) , mBackwardsCompatibility(false) , mMicroCode(NULL) - , mOptimisationLevel(OPT_DEFAULT) - , mParametersMapSizeAsBuffer(0) + , mOptimisationLevel(OPT_DEFAULT) + , mParametersMapSizeAsBuffer(0) { if (createParamDictionary("D3D9HLSLProgram")) { @@ -670,15 +670,15 @@ namespace Ogre { dict->addParameter(ParameterDef("column_major_matrices", "Whether matrix packing in column-major order.", PT_BOOL),&msCmdColumnMajorMatrices); - dict->addParameter(ParameterDef("optimisation_level", - "The optimisation level to use.", - PT_STRING),&msCmdOptimisation); - dict->addParameter(ParameterDef("micro_code", - "the micro code.", - PT_STRING),&msCmdMicrocode); - dict->addParameter(ParameterDef("assemble_code", - "the assemble code.", - PT_STRING),&msCmdAssemblerCode); + dict->addParameter(ParameterDef("optimisation_level", + "The optimisation level to use.", + PT_STRING),&msCmdOptimisation); + dict->addParameter(ParameterDef("micro_code", + "the micro code.", + PT_STRING),&msCmdMicrocode); + dict->addParameter(ParameterDef("assemble_code", + "the assemble code.", + PT_STRING),&msCmdAssemblerCode); dict->addParameter(ParameterDef("backwards_compatibility", "Enable backwards compatibility mode.", PT_BOOL),&msCmdBackwardsCompatibility); @@ -721,24 +721,24 @@ namespace Ogre { //----------------------------------------------------------------------- void D3D9HLSLProgram::setTarget(const String& target) { - mTarget = ""; - vector::type profiles = StringUtil::split(target, " "); + mTarget = ""; + vector::type profiles = StringUtil::split(target, " "); - for(int i = 0 ; i < profiles.size() ; i++) - { - String & currentProfile = profiles[i]; - if(GpuProgramManager::getSingleton().isSyntaxSupported(currentProfile)) - { - mTarget = currentProfile; - break; - } - } + for(int i = 0 ; i < profiles.size() ; i++) + { + String & currentProfile = profiles[i]; + if(GpuProgramManager::getSingleton().isSyntaxSupported(currentProfile)) + { + mTarget = currentProfile; + break; + } + } - if(mTarget == "") - { - LogManager::getSingleton().logMessage( - "Invalid target for D3D11 shader '" + mName + "' - '" + target + "'"); - } + if(mTarget == "") + { + LogManager::getSingleton().logMessage( + "Invalid target for D3D11 shader '" + mName + "' - '" + target + "'"); + } } //----------------------------------------------------------------------- @@ -794,94 +794,94 @@ namespace Ogre { { static_cast(target)->setBackwardsCompatibility(StringConverter::parseBool(val)); } - //----------------------------------------------------------------------- - String D3D9HLSLProgram::CmdOptimisation::doGet(const void *target) const - { - switch(static_cast(target)->getOptimisationLevel()) - { - default: - case OPT_DEFAULT: - return "default"; - case OPT_NONE: - return "none"; - case OPT_0: - return "0"; - case OPT_1: - return "1"; - case OPT_2: - return "2"; - case OPT_3: - return "3"; - } - } - void D3D9HLSLProgram::CmdOptimisation::doSet(void *target, const String& val) - { - if (StringUtil::startsWith(val, "default", true)) - static_cast(target)->setOptimisationLevel(OPT_DEFAULT); - else if (StringUtil::startsWith(val, "none", true)) - static_cast(target)->setOptimisationLevel(OPT_NONE); - else if (StringUtil::startsWith(val, "0", true)) - static_cast(target)->setOptimisationLevel(OPT_0); - else if (StringUtil::startsWith(val, "1", true)) - static_cast(target)->setOptimisationLevel(OPT_1); - else if (StringUtil::startsWith(val, "2", true)) - static_cast(target)->setOptimisationLevel(OPT_2); - else if (StringUtil::startsWith(val, "3", true)) - static_cast(target)->setOptimisationLevel(OPT_3); - } + //----------------------------------------------------------------------- + String D3D9HLSLProgram::CmdOptimisation::doGet(const void *target) const + { + switch(static_cast(target)->getOptimisationLevel()) + { + default: + case OPT_DEFAULT: + return "default"; + case OPT_NONE: + return "none"; + case OPT_0: + return "0"; + case OPT_1: + return "1"; + case OPT_2: + return "2"; + case OPT_3: + return "3"; + } + } + void D3D9HLSLProgram::CmdOptimisation::doSet(void *target, const String& val) + { + if (StringUtil::startsWith(val, "default", true)) + static_cast(target)->setOptimisationLevel(OPT_DEFAULT); + else if (StringUtil::startsWith(val, "none", true)) + static_cast(target)->setOptimisationLevel(OPT_NONE); + else if (StringUtil::startsWith(val, "0", true)) + static_cast(target)->setOptimisationLevel(OPT_0); + else if (StringUtil::startsWith(val, "1", true)) + static_cast(target)->setOptimisationLevel(OPT_1); + else if (StringUtil::startsWith(val, "2", true)) + static_cast(target)->setOptimisationLevel(OPT_2); + else if (StringUtil::startsWith(val, "3", true)) + static_cast(target)->setOptimisationLevel(OPT_3); + } //----------------------------------------------------------------------- String D3D9HLSLProgram::CmdMicrocode::doGet(const void *target) const { - D3D9HLSLProgram* program=const_cast(static_cast(target)); - LPD3DXBUFFER buffer=program->getMicroCode(); - if(buffer) - { - char* str =static_cast(buffer->GetBufferPointer()); - size_t size=static_cast(buffer->GetBufferSize()); - Ogre::String code; - code.assign(str,size); - return code; - } - else - { - return String(); - } + D3D9HLSLProgram* program=const_cast(static_cast(target)); + LPD3DXBUFFER buffer=program->getMicroCode(); + if(buffer) + { + char* str =static_cast(buffer->GetBufferPointer()); + size_t size=static_cast(buffer->GetBufferSize()); + Ogre::String code; + code.assign(str,size); + return code; + } + else + { + return String(); + } } void D3D9HLSLProgram::CmdMicrocode::doSet(void *target, const String& val) { - //nothing to do - //static_cast(target)->setColumnMajorMatrices(StringConverter::parseBool(val)); + //nothing to do + //static_cast(target)->setColumnMajorMatrices(StringConverter::parseBool(val)); } //----------------------------------------------------------------------- String D3D9HLSLProgram::CmdAssemblerCode::doGet(const void *target) const { - D3D9HLSLProgram* program=const_cast(static_cast(target)); - LPD3DXBUFFER buffer=program->getMicroCode(); - if(buffer) - { - CONST DWORD* code =static_cast(buffer->GetBufferPointer()); - LPD3DXBUFFER pDisassembly=0; - HRESULT hr=D3DXDisassembleShader(code,FALSE,"// assemble code from D3D9HLSLProgram\n",&pDisassembly); - if(pDisassembly) - { - char* str =static_cast(pDisassembly->GetBufferPointer()); - size_t size=static_cast(pDisassembly->GetBufferSize()); - Ogre::String assemble_code; - assemble_code.assign(str,size); - pDisassembly->Release(); - return assemble_code; - } - return String(); - } - else - { - return String(); - } + D3D9HLSLProgram* program=const_cast(static_cast(target)); + LPD3DXBUFFER buffer=program->getMicroCode(); + if(buffer) + { + CONST DWORD* code =static_cast(buffer->GetBufferPointer()); + LPD3DXBUFFER pDisassembly=0; + HRESULT hr=D3DXDisassembleShader(code,FALSE,"// assemble code from D3D9HLSLProgram\n",&pDisassembly); + if(pDisassembly) + { + char* str =static_cast(pDisassembly->GetBufferPointer()); + size_t size=static_cast(pDisassembly->GetBufferSize()); + Ogre::String assemble_code; + assemble_code.assign(str,size); + pDisassembly->Release(); + return assemble_code; + } + return String(); + } + else + { + return String(); + } } void D3D9HLSLProgram::CmdAssemblerCode::doSet(void *target, const String& val) { - //nothing to do - //static_cast(target)->setColumnMajorMatrices(StringConverter::parseBool(val)); + //nothing to do + //static_cast(target)->setColumnMajorMatrices(StringConverter::parseBool(val)); } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9HLSLProgramFactory.cpp b/RenderSystems/Direct3D9/src/OgreD3D9HLSLProgramFactory.cpp index 9bb255cc324..9f9416b53d4 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9HLSLProgramFactory.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9HLSLProgramFactory.cpp @@ -54,7 +54,7 @@ namespace Ogre { return OGRE_NEW D3D9HLSLProgram(creator, name, handle, group, isManual, loader); } //----------------------------------------------------------------------- - void D3D9HLSLProgramFactory::destroy(HighLevelGpuProgram* prog) + void D3D9HLSLProgramFactory::destroy(HighLevelGpuProgram* prog) { OGRE_DELETE prog; } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9HardwareBufferManager.cpp b/RenderSystems/Direct3D9/src/OgreD3D9HardwareBufferManager.cpp index 45dbe1f91a9..ed0c6101e35 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9HardwareBufferManager.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9HardwareBufferManager.cpp @@ -49,19 +49,19 @@ namespace Ogre { HardwareVertexBufferSharedPtr D3D9HardwareBufferManagerBase:: createVertexBuffer(size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, - bool useShadowBuffer) + bool useShadowBuffer) { - assert (numVerts > 0); + assert (numVerts > 0); #if OGRE_D3D_MANAGE_BUFFERS // Override shadow buffer setting; managed buffers are automatically // backed by system memory // Don't override shadow buffer if discardable, since then we use // unmanaged buffers for speed (avoids write-through overhead) - // Don't override if we use directX9EX, since then we don't have managed - // pool. And creating non-write only default pool causes a performance warning. - if (useShadowBuffer && !(usage & HardwareBuffer::HBU_DISCARDABLE) && - !D3D9RenderSystem::isDirectX9Ex()) - { + // Don't override if we use directX9EX, since then we don't have managed + // pool. And creating non-write only default pool causes a performance warning. + if (useShadowBuffer && !(usage & HardwareBuffer::HBU_DISCARDABLE) && + !D3D9RenderSystem::isDirectX9Ex()) + { useShadowBuffer = false; // Also drop any WRITE_ONLY so we can read direct if (usage == HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY) @@ -73,39 +73,39 @@ namespace Ogre { usage = HardwareBuffer::HBU_STATIC; } } - //If we have write only buffers in DirectX9Ex we will turn on the discardable flag. - //Otherwise Ogre will operates in far less framerate - if (D3D9RenderSystem::isDirectX9Ex() && (usage & HardwareBuffer::HBU_WRITE_ONLY)) - { - usage = (HardwareBuffer::Usage) - ((unsigned int)usage | (unsigned int)HardwareBuffer::HBU_DISCARDABLE); - } + //If we have write only buffers in DirectX9Ex we will turn on the discardable flag. + //Otherwise Ogre will operates in far less framerate + if (D3D9RenderSystem::isDirectX9Ex() && (usage & HardwareBuffer::HBU_WRITE_ONLY)) + { + usage = (HardwareBuffer::Usage) + ((unsigned int)usage | (unsigned int)HardwareBuffer::HBU_DISCARDABLE); + } #endif - D3D9HardwareVertexBuffer* vbuf = OGRE_NEW D3D9HardwareVertexBuffer( - this, vertexSize, numVerts, usage, false, useShadowBuffer); - { + D3D9HardwareVertexBuffer* vbuf = OGRE_NEW D3D9HardwareVertexBuffer( + this, vertexSize, numVerts, usage, false, useShadowBuffer); + { OGRE_LOCK_MUTEX(mVertexBuffersMutex); - mVertexBuffers.insert(vbuf); - } + mVertexBuffers.insert(vbuf); + } return HardwareVertexBufferSharedPtr(vbuf); } //----------------------------------------------------------------------- - HardwareIndexBufferSharedPtr + HardwareIndexBufferSharedPtr D3D9HardwareBufferManagerBase:: createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer) { - assert (numIndexes > 0); + assert (numIndexes > 0); #if OGRE_D3D_MANAGE_BUFFERS // Override shadow buffer setting; managed buffers are automatically // backed by system memory - // Don't override shadow buffer if discardable, since then we use - // unmanaged buffers for speed (avoids write-through overhead) - // Don't override if we use directX9EX, since then we don't have managed - // pool. And creating non-write only default pool causes a performance warning. - if (useShadowBuffer && !(usage & HardwareBuffer::HBU_DISCARDABLE) && - !D3D9RenderSystem::isDirectX9Ex()) - { + // Don't override shadow buffer if discardable, since then we use + // unmanaged buffers for speed (avoids write-through overhead) + // Don't override if we use directX9EX, since then we don't have managed + // pool. And creating non-write only default pool causes a performance warning. + if (useShadowBuffer && !(usage & HardwareBuffer::HBU_DISCARDABLE) && + !D3D9RenderSystem::isDirectX9Ex()) + { useShadowBuffer = false; // Also drop any WRITE_ONLY so we can read direct if (usage == HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY) @@ -117,21 +117,21 @@ namespace Ogre { usage = HardwareBuffer::HBU_STATIC; } } - //If we have write only buffers in DirectX9Ex we will turn on the discardable flag. - //Otherwise Ogre will operates in far less framerate - if (D3D9RenderSystem::isDirectX9Ex() && (usage & HardwareBuffer::HBU_WRITE_ONLY)) - { - usage = (HardwareBuffer::Usage) - ((unsigned int)usage | (unsigned int)HardwareBuffer::HBU_DISCARDABLE); - } + //If we have write only buffers in DirectX9Ex we will turn on the discardable flag. + //Otherwise Ogre will operates in far less framerate + if (D3D9RenderSystem::isDirectX9Ex() && (usage & HardwareBuffer::HBU_WRITE_ONLY)) + { + usage = (HardwareBuffer::Usage) + ((unsigned int)usage | (unsigned int)HardwareBuffer::HBU_DISCARDABLE); + } #endif - D3D9HardwareIndexBuffer* idx = OGRE_NEW D3D9HardwareIndexBuffer( - this, itype, numIndexes, usage, false, useShadowBuffer); - { + D3D9HardwareIndexBuffer* idx = OGRE_NEW D3D9HardwareIndexBuffer( + this, itype, numIndexes, usage, false, useShadowBuffer); + { OGRE_LOCK_MUTEX(mIndexBuffersMutex); - mIndexBuffers.insert(idx); - } - return HardwareIndexBufferSharedPtr(idx); + mIndexBuffers.insert(idx); + } + return HardwareIndexBufferSharedPtr(idx); } //----------------------------------------------------------------------- @@ -141,24 +141,24 @@ namespace Ogre { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Direct3D9 does not support render to vertex buffer objects", "D3D9HardwareBufferManagerBase::createRenderToVertexBuffer"); - } - //--------------------------------------------------------------------- - HardwareUniformBufferSharedPtr - D3D9HardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Uniform buffer not supported in Direct3D 9 RenderSystem.", - "D3D9HardwareBufferManagerBase::createUniformBuffer"); - } + } + //--------------------------------------------------------------------- + HardwareUniformBufferSharedPtr + D3D9HardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Uniform buffer not supported in Direct3D 9 RenderSystem.", + "D3D9HardwareBufferManagerBase::createUniformBuffer"); + } //----------------------------------------------------------------------- - HardwareCounterBufferSharedPtr + HardwareCounterBufferSharedPtr D3D9HardwareBufferManagerBase::createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - { + { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D9 does not support atomic counter buffers", "D3D9HardwareBufferManagerBase::createCounterBuffer"); - } + } //----------------------------------------------------------------------- VertexDeclaration* D3D9HardwareBufferManagerBase::createVertexDeclarationImpl(void) { diff --git a/RenderSystems/Direct3D9/src/OgreD3D9HardwareIndexBuffer.cpp b/RenderSystems/Direct3D9/src/OgreD3D9HardwareIndexBuffer.cpp index 1659c7848bc..9b5c8568577 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9HardwareIndexBuffer.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9HardwareIndexBuffer.cpp @@ -36,146 +36,146 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- D3D9HardwareIndexBuffer::D3D9HardwareIndexBuffer(HardwareBufferManagerBase* mgr, HardwareIndexBuffer::IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage, bool useSystemMemory, bool useShadowBuffer) : HardwareIndexBuffer(mgr, idxType, numIndexes, usage, useSystemMemory, - useShadowBuffer || - // Allocate the system memory buffer for restoring after device lost. - (((usage & HardwareBuffer::HBU_WRITE_ONLY) != 0) && - D3D9RenderSystem::getResourceManager()->getAutoHardwareBufferManagement())) + useShadowBuffer || + // Allocate the system memory buffer for restoring after device lost. + (((usage & HardwareBuffer::HBU_WRITE_ONLY) != 0) && + D3D9RenderSystem::getResourceManager()->getAutoHardwareBufferManagement())) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - D3DPOOL eResourcePool; + D3DPOOL eResourcePool; #if OGRE_D3D_MANAGE_BUFFERS - eResourcePool = useSystemMemory? D3DPOOL_SYSTEMMEM : - // If not system mem, use managed pool UNLESS buffer is discardable - // if discardable, keeping the software backing is expensive - ((usage & HardwareBuffer::HBU_DISCARDABLE) || (D3D9RenderSystem::isDirectX9Ex())) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; + eResourcePool = useSystemMemory? D3DPOOL_SYSTEMMEM : + // If not system mem, use managed pool UNLESS buffer is discardable + // if discardable, keeping the software backing is expensive + ((usage & HardwareBuffer::HBU_DISCARDABLE) || (D3D9RenderSystem::isDirectX9Ex())) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; #else - eResourcePool = useSystemMemory? D3DPOOL_SYSTEMMEM : D3DPOOL_DEFAULT; + eResourcePool = useSystemMemory? D3DPOOL_SYSTEMMEM : D3DPOOL_DEFAULT; #endif - // Set the desired memory pool. - mBufferDesc.Pool = eResourcePool; - - // Set source buffer to NULL. - mSourceBuffer = NULL; - mSourceLockedBytes = NULL; + // Set the desired memory pool. + mBufferDesc.Pool = eResourcePool; + + // Set source buffer to NULL. + mSourceBuffer = NULL; + mSourceLockedBytes = NULL; - // Create buffer resource(s). - for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) - { - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); + // Create buffer resource(s). + for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) + { + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); - createBuffer(d3d9Device, mBufferDesc.Pool, false); - } + createBuffer(d3d9Device, mBufferDesc.Pool, false); + } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- D3D9HardwareIndexBuffer::~D3D9HardwareIndexBuffer() { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - - while (it != mMapDeviceToBufferResources.end()) - { - SAFE_RELEASE(it->second->mBuffer); - if (it->second != NULL) - { - OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); - it->second = NULL; - } - ++it; - } - mMapDeviceToBufferResources.clear(); - } - //--------------------------------------------------------------------- + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + + while (it != mMapDeviceToBufferResources.end()) + { + SAFE_RELEASE(it->second->mBuffer); + if (it->second != NULL) + { + OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); + it->second = NULL; + } + ++it; + } + mMapDeviceToBufferResources.clear(); + } + //--------------------------------------------------------------------- void* D3D9HardwareIndexBuffer::lockImpl(size_t offset, size_t length, LockOptions options) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9DeviceIfExists(); - - while (it != mMapDeviceToBufferResources.end()) - { - BufferResources* bufferResources = it->second; - - if (options != HBL_READ_ONLY) - bufferResources->mOutOfDate = true; - - // Case it is the first buffer lock in this frame. - if (bufferResources->mLockLength == 0) - { - if (offset < bufferResources->mLockOffset) - bufferResources->mLockOffset = offset; - if (length > bufferResources->mLockLength) - bufferResources->mLockLength = length; - } - - // Case buffer already locked in this frame. - else - { - size_t highPoint = std::max( offset + length, - bufferResources->mLockOffset + bufferResources->mLockLength ); - bufferResources->mLockOffset = std::min( bufferResources->mLockOffset, offset ); - bufferResources->mLockLength = highPoint - bufferResources->mLockOffset; - } - - bufferResources->mLockOptions = options; - - //We will switch the source buffer to the active d3d9device as we may decide to only update it during unlock - if (it->first == d3d9Device) - mSourceBuffer = it->second; - - ++it; - } - - // Lock the source buffer. - mSourceLockedBytes = _lockBuffer(mSourceBuffer, mSourceBuffer->mLockOffset, mSourceBuffer->mLockLength); - - return mSourceLockedBytes; - } - //--------------------------------------------------------------------- - void D3D9HardwareIndexBuffer::unlockImpl(void) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - //check if we can delay the update of secondary buffer resources - //if the user requested it and we have a shadow buffer we can always recreate the buffer later - if ((mShadowBuffer == NULL) || ((mLockUploadOption & HBU_ON_DEMAND) == 0)) - { - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - uint nextFrameNumber = Root::getSingleton().getNextFrameNumber(); - - while (it != mMapDeviceToBufferResources.end()) - { - BufferResources* bufferResources = it->second; - - if (bufferResources->mOutOfDate && - bufferResources->mBuffer != NULL && - nextFrameNumber - bufferResources->mLastUsedFrame <= 1) - { - if (mSourceBuffer != bufferResources) - { - updateBufferResources(mSourceLockedBytes, bufferResources); - } - } - - ++it; - } - } - - // Unlock the source buffer. - _unlockBuffer(mSourceBuffer); - mSourceLockedBytes = NULL; - } - //--------------------------------------------------------------------- + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9DeviceIfExists(); + + while (it != mMapDeviceToBufferResources.end()) + { + BufferResources* bufferResources = it->second; + + if (options != HBL_READ_ONLY) + bufferResources->mOutOfDate = true; + + // Case it is the first buffer lock in this frame. + if (bufferResources->mLockLength == 0) + { + if (offset < bufferResources->mLockOffset) + bufferResources->mLockOffset = offset; + if (length > bufferResources->mLockLength) + bufferResources->mLockLength = length; + } + + // Case buffer already locked in this frame. + else + { + size_t highPoint = std::max( offset + length, + bufferResources->mLockOffset + bufferResources->mLockLength ); + bufferResources->mLockOffset = std::min( bufferResources->mLockOffset, offset ); + bufferResources->mLockLength = highPoint - bufferResources->mLockOffset; + } + + bufferResources->mLockOptions = options; + + //We will switch the source buffer to the active d3d9device as we may decide to only update it during unlock + if (it->first == d3d9Device) + mSourceBuffer = it->second; + + ++it; + } + + // Lock the source buffer. + mSourceLockedBytes = _lockBuffer(mSourceBuffer, mSourceBuffer->mLockOffset, mSourceBuffer->mLockLength); + + return mSourceLockedBytes; + } + //--------------------------------------------------------------------- + void D3D9HardwareIndexBuffer::unlockImpl(void) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + //check if we can delay the update of secondary buffer resources + //if the user requested it and we have a shadow buffer we can always recreate the buffer later + if ((mShadowBuffer == NULL) || ((mLockUploadOption & HBU_ON_DEMAND) == 0)) + { + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + uint nextFrameNumber = Root::getSingleton().getNextFrameNumber(); + + while (it != mMapDeviceToBufferResources.end()) + { + BufferResources* bufferResources = it->second; + + if (bufferResources->mOutOfDate && + bufferResources->mBuffer != NULL && + nextFrameNumber - bufferResources->mLastUsedFrame <= 1) + { + if (mSourceBuffer != bufferResources) + { + updateBufferResources(mSourceLockedBytes, bufferResources); + } + } + + ++it; + } + } + + // Unlock the source buffer. + _unlockBuffer(mSourceBuffer); + mSourceLockedBytes = NULL; + } + //--------------------------------------------------------------------- void D3D9HardwareIndexBuffer::readData(size_t offset, size_t length, void* pDest) { @@ -186,10 +186,10 @@ namespace Ogre { this->unlock(); } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void D3D9HardwareIndexBuffer::writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer) + bool discardWholeBuffer) { // There is no functional interface in D3D, just do via manual // lock, copy & unlock @@ -197,248 +197,248 @@ namespace Ogre { discardWholeBuffer ? HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL); memcpy(pDst, pSource, length); this->unlock(); - } - //--------------------------------------------------------------------- - void D3D9HardwareIndexBuffer::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if (D3D9RenderSystem::getResourceManager()->getCreationPolicy() == RCP_CREATE_ON_ALL_DEVICES) - createBuffer(d3d9Device, mBufferDesc.Pool, true); - - } - //--------------------------------------------------------------------- - void D3D9HardwareIndexBuffer::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); - - if (it != mMapDeviceToBufferResources.end()) - { - // Case this is the source buffer. - if (it->second == mSourceBuffer) - { - mSourceBuffer = NULL; - } - - SAFE_RELEASE(it->second->mBuffer); - if (it->second != NULL) - { - OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); - it->second = NULL; - } - mMapDeviceToBufferResources.erase(it); - - // Case source buffer just destroyed -> switch to another one if exits. - if (mSourceBuffer == NULL && mMapDeviceToBufferResources.size() > 0) - { - mSourceBuffer = mMapDeviceToBufferResources.begin()->second; - } - } - } - //--------------------------------------------------------------------- - void D3D9HardwareIndexBuffer::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if (mBufferDesc.Pool == D3DPOOL_DEFAULT) - { - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); - - if (it != mMapDeviceToBufferResources.end()) - { - SAFE_RELEASE(it->second->mBuffer); - } - } - } - //--------------------------------------------------------------------- - void D3D9HardwareIndexBuffer::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if (mBufferDesc.Pool == D3DPOOL_DEFAULT) - { - createBuffer(d3d9Device, mBufferDesc.Pool, true); - } - } - //--------------------------------------------------------------------- - void D3D9HardwareIndexBuffer::createBuffer(IDirect3DDevice9* d3d9Device, D3DPOOL ePool, bool updateNewBuffer) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - BufferResources* bufferResources; - HRESULT hr; - - DeviceToBufferResourcesIterator it; - - // Find the vertex buffer of this device. - it = mMapDeviceToBufferResources.find(d3d9Device); - if (it != mMapDeviceToBufferResources.end()) - { - bufferResources = it->second; - SAFE_RELEASE(bufferResources->mBuffer); - } - else - { - bufferResources = OGRE_ALLOC_T(BufferResources, 1, MEMCATEGORY_RENDERSYS); - mMapDeviceToBufferResources[d3d9Device] = bufferResources; - } - - bufferResources->mBuffer = NULL; - bufferResources->mOutOfDate = true; - bufferResources->mLockOffset = 0; - bufferResources->mLockLength = getSizeInBytes(); - bufferResources->mLockOptions = HBL_NORMAL; - bufferResources->mLastUsedFrame = Root::getSingleton().getNextFrameNumber(); - - // Create the Index buffer - hr = d3d9Device->CreateIndexBuffer( - static_cast(mSizeInBytes), - D3D9Mappings::get(mUsage), - D3D9Mappings::get(mIndexType), - ePool, - &bufferResources->mBuffer, - NULL - ); - - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create D3D9 Index buffer: " + msg, - "D3D9HardwareIndexBuffer::createBuffer"); - } - - hr = bufferResources->mBuffer->GetDesc(&mBufferDesc); - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot get D3D9 Index buffer desc: " + msg, - "D3D9HardwareIndexBuffer::createBuffer"); - } - // Update source buffer if need to. - if (mSourceBuffer == NULL) - { - mSourceBuffer = bufferResources; - } - - // This is a new buffer and source buffer exists we must update the content now - // to prevent situation where the source buffer will be destroyed and we won't be able to restore its content. - // This is except for during the creation process of the class when there is no data yet to update. - else if (updateNewBuffer) - { - updateBufferContent(bufferResources); - } - } - //--------------------------------------------------------------------- - IDirect3DIndexBuffer9* D3D9HardwareIndexBuffer::getD3DIndexBuffer(void) - { - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); - DeviceToBufferResourcesIterator it; - - // Find the index buffer of this device. - it = mMapDeviceToBufferResources.find(d3d9Device); - - // Case index buffer was not found for the current device -> create it. - if (it == mMapDeviceToBufferResources.end() || it->second->mBuffer == NULL) - { - createBuffer(d3d9Device, mBufferDesc.Pool, true); - it = mMapDeviceToBufferResources.find(d3d9Device); - } - - // Make sure that the buffer content is updated. - updateBufferContent(it->second); - - it->second->mLastUsedFrame = Root::getSingleton().getNextFrameNumber(); - - return it->second->mBuffer; - } - - //--------------------------------------------------------------------- - void D3D9HardwareIndexBuffer::updateBufferContent(BufferResources* bufferResources) - { - if (bufferResources->mOutOfDate) - { - if (mShadowBuffer != NULL) - { - const char* shadowData = (const char*)mShadowBuffer->lock(bufferResources->mLockOffset, bufferResources->mLockLength, HBL_NORMAL); - updateBufferResources(shadowData, bufferResources); - mShadowBuffer->unlock(); - } - else if (mSourceBuffer != bufferResources && (mUsage & HardwareBuffer::HBU_WRITE_ONLY) == 0) - { - mSourceBuffer->mLockOptions = HBL_READ_ONLY; - mSourceLockedBytes = _lockBuffer(mSourceBuffer, bufferResources->mLockOffset, bufferResources->mLockLength); - updateBufferResources(mSourceLockedBytes, bufferResources); - _unlockBuffer(mSourceBuffer); - mSourceLockedBytes = NULL; - } - } - } - - //--------------------------------------------------------------------- - bool D3D9HardwareIndexBuffer::updateBufferResources(const char* systemMemoryBuffer, - BufferResources* bufferResources) - { - assert(bufferResources != NULL); - assert(bufferResources->mBuffer != NULL); - assert(bufferResources->mOutOfDate); - - - char* dstBytes = _lockBuffer(bufferResources, bufferResources->mLockOffset, bufferResources->mLockLength); - memcpy(dstBytes, systemMemoryBuffer, bufferResources->mLockLength); - _unlockBuffer(bufferResources); - - return true; - } - - //--------------------------------------------------------------------- - char* D3D9HardwareIndexBuffer::_lockBuffer(BufferResources* bufferResources, size_t offset, size_t length) - { - HRESULT hr; - char* pSourceBytes; - - - // Lock the buffer. - hr = bufferResources->mBuffer->Lock( - static_cast(offset), - static_cast(length), - (void**)&pSourceBytes, - D3D9Mappings::get(mSourceBuffer->mLockOptions, mUsage)); - - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot lock D3D9 vertex buffer: " + msg, - "D3D9HardwareVertexBuffer::_lockBuffer"); - } - - return pSourceBytes; - } - - //--------------------------------------------------------------------- - void D3D9HardwareIndexBuffer::_unlockBuffer( BufferResources* bufferResources ) - { - HRESULT hr; - - // Unlock the buffer. - hr = bufferResources->mBuffer->Unlock(); - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot unlock D3D9 vertex buffer: " + msg, - "D3D9HardwareVertexBuffer::_unlockBuffer"); - } - - // Reset attributes. - bufferResources->mOutOfDate = false; - bufferResources->mLockOffset = mSizeInBytes; - bufferResources->mLockLength = 0; - bufferResources->mLockOptions = HBL_NORMAL; - - } + } + //--------------------------------------------------------------------- + void D3D9HardwareIndexBuffer::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if (D3D9RenderSystem::getResourceManager()->getCreationPolicy() == RCP_CREATE_ON_ALL_DEVICES) + createBuffer(d3d9Device, mBufferDesc.Pool, true); + + } + //--------------------------------------------------------------------- + void D3D9HardwareIndexBuffer::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); + + if (it != mMapDeviceToBufferResources.end()) + { + // Case this is the source buffer. + if (it->second == mSourceBuffer) + { + mSourceBuffer = NULL; + } + + SAFE_RELEASE(it->second->mBuffer); + if (it->second != NULL) + { + OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); + it->second = NULL; + } + mMapDeviceToBufferResources.erase(it); + + // Case source buffer just destroyed -> switch to another one if exits. + if (mSourceBuffer == NULL && mMapDeviceToBufferResources.size() > 0) + { + mSourceBuffer = mMapDeviceToBufferResources.begin()->second; + } + } + } + //--------------------------------------------------------------------- + void D3D9HardwareIndexBuffer::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if (mBufferDesc.Pool == D3DPOOL_DEFAULT) + { + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); + + if (it != mMapDeviceToBufferResources.end()) + { + SAFE_RELEASE(it->second->mBuffer); + } + } + } + //--------------------------------------------------------------------- + void D3D9HardwareIndexBuffer::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if (mBufferDesc.Pool == D3DPOOL_DEFAULT) + { + createBuffer(d3d9Device, mBufferDesc.Pool, true); + } + } + //--------------------------------------------------------------------- + void D3D9HardwareIndexBuffer::createBuffer(IDirect3DDevice9* d3d9Device, D3DPOOL ePool, bool updateNewBuffer) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + BufferResources* bufferResources; + HRESULT hr; + + DeviceToBufferResourcesIterator it; + + // Find the vertex buffer of this device. + it = mMapDeviceToBufferResources.find(d3d9Device); + if (it != mMapDeviceToBufferResources.end()) + { + bufferResources = it->second; + SAFE_RELEASE(bufferResources->mBuffer); + } + else + { + bufferResources = OGRE_ALLOC_T(BufferResources, 1, MEMCATEGORY_RENDERSYS); + mMapDeviceToBufferResources[d3d9Device] = bufferResources; + } + + bufferResources->mBuffer = NULL; + bufferResources->mOutOfDate = true; + bufferResources->mLockOffset = 0; + bufferResources->mLockLength = getSizeInBytes(); + bufferResources->mLockOptions = HBL_NORMAL; + bufferResources->mLastUsedFrame = Root::getSingleton().getNextFrameNumber(); + + // Create the Index buffer + hr = d3d9Device->CreateIndexBuffer( + static_cast(mSizeInBytes), + D3D9Mappings::get(mUsage), + D3D9Mappings::get(mIndexType), + ePool, + &bufferResources->mBuffer, + NULL + ); + + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create D3D9 Index buffer: " + msg, + "D3D9HardwareIndexBuffer::createBuffer"); + } + + hr = bufferResources->mBuffer->GetDesc(&mBufferDesc); + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot get D3D9 Index buffer desc: " + msg, + "D3D9HardwareIndexBuffer::createBuffer"); + } + // Update source buffer if need to. + if (mSourceBuffer == NULL) + { + mSourceBuffer = bufferResources; + } + + // This is a new buffer and source buffer exists we must update the content now + // to prevent situation where the source buffer will be destroyed and we won't be able to restore its content. + // This is except for during the creation process of the class when there is no data yet to update. + else if (updateNewBuffer) + { + updateBufferContent(bufferResources); + } + } + //--------------------------------------------------------------------- + IDirect3DIndexBuffer9* D3D9HardwareIndexBuffer::getD3DIndexBuffer(void) + { + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); + DeviceToBufferResourcesIterator it; + + // Find the index buffer of this device. + it = mMapDeviceToBufferResources.find(d3d9Device); + + // Case index buffer was not found for the current device -> create it. + if (it == mMapDeviceToBufferResources.end() || it->second->mBuffer == NULL) + { + createBuffer(d3d9Device, mBufferDesc.Pool, true); + it = mMapDeviceToBufferResources.find(d3d9Device); + } + + // Make sure that the buffer content is updated. + updateBufferContent(it->second); + + it->second->mLastUsedFrame = Root::getSingleton().getNextFrameNumber(); + + return it->second->mBuffer; + } + + //--------------------------------------------------------------------- + void D3D9HardwareIndexBuffer::updateBufferContent(BufferResources* bufferResources) + { + if (bufferResources->mOutOfDate) + { + if (mShadowBuffer != NULL) + { + const char* shadowData = (const char*)mShadowBuffer->lock(bufferResources->mLockOffset, bufferResources->mLockLength, HBL_NORMAL); + updateBufferResources(shadowData, bufferResources); + mShadowBuffer->unlock(); + } + else if (mSourceBuffer != bufferResources && (mUsage & HardwareBuffer::HBU_WRITE_ONLY) == 0) + { + mSourceBuffer->mLockOptions = HBL_READ_ONLY; + mSourceLockedBytes = _lockBuffer(mSourceBuffer, bufferResources->mLockOffset, bufferResources->mLockLength); + updateBufferResources(mSourceLockedBytes, bufferResources); + _unlockBuffer(mSourceBuffer); + mSourceLockedBytes = NULL; + } + } + } + + //--------------------------------------------------------------------- + bool D3D9HardwareIndexBuffer::updateBufferResources(const char* systemMemoryBuffer, + BufferResources* bufferResources) + { + assert(bufferResources != NULL); + assert(bufferResources->mBuffer != NULL); + assert(bufferResources->mOutOfDate); + + + char* dstBytes = _lockBuffer(bufferResources, bufferResources->mLockOffset, bufferResources->mLockLength); + memcpy(dstBytes, systemMemoryBuffer, bufferResources->mLockLength); + _unlockBuffer(bufferResources); + + return true; + } + + //--------------------------------------------------------------------- + char* D3D9HardwareIndexBuffer::_lockBuffer(BufferResources* bufferResources, size_t offset, size_t length) + { + HRESULT hr; + char* pSourceBytes; + + + // Lock the buffer. + hr = bufferResources->mBuffer->Lock( + static_cast(offset), + static_cast(length), + (void**)&pSourceBytes, + D3D9Mappings::get(mSourceBuffer->mLockOptions, mUsage)); + + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot lock D3D9 vertex buffer: " + msg, + "D3D9HardwareVertexBuffer::_lockBuffer"); + } + + return pSourceBytes; + } + + //--------------------------------------------------------------------- + void D3D9HardwareIndexBuffer::_unlockBuffer( BufferResources* bufferResources ) + { + HRESULT hr; + + // Unlock the buffer. + hr = bufferResources->mBuffer->Unlock(); + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot unlock D3D9 vertex buffer: " + msg, + "D3D9HardwareVertexBuffer::_unlockBuffer"); + } + + // Reset attributes. + bufferResources->mOutOfDate = false; + bufferResources->mLockOffset = mSizeInBytes; + bufferResources->mLockLength = 0; + bufferResources->mLockOptions = HBL_NORMAL; + + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9HardwareOcclusionQuery.cpp b/RenderSystems/Direct3D9/src/OgreD3D9HardwareOcclusionQuery.cpp index 1f178e81bea..c4a186de4c1 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9HardwareOcclusionQuery.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9HardwareOcclusionQuery.cpp @@ -32,93 +32,93 @@ THE SOFTWARE. namespace Ogre { - /** - * This is a class that is the DirectX9 implementation of - * hardware occlusion testing. - * - * @author Lee Sandberg - * - * Updated on 12/7/2004 by Chris McGuirk - * Updated on 4/8/2005 by Tuan Kuranes email: tuan.kuranes@free.fr - */ - - /** - * Default object constructor - */ + /** + * This is a class that is the DirectX9 implementation of + * hardware occlusion testing. + * + * @author Lee Sandberg + * + * Updated on 12/7/2004 by Chris McGuirk + * Updated on 4/8/2005 by Tuan Kuranes email: tuan.kuranes@free.fr + */ + + /** + * Default object constructor + */ D3D9HardwareOcclusionQuery::D3D9HardwareOcclusionQuery() - { - - } - - /** - * Object destructor - */ - D3D9HardwareOcclusionQuery::~D3D9HardwareOcclusionQuery() - { - DeviceToQueryIterator it = mMapDeviceToQuery.begin(); - - while (it != mMapDeviceToQuery.end()) - { - SAFE_RELEASE(it->second); - ++it; - } - mMapDeviceToQuery.clear(); - } - - //------------------------------------------------------------------ - // Occlusion query functions (see base class documentation for this) - //-- - void D3D9HardwareOcclusionQuery::beginOcclusionQuery() - { - IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); - DeviceToQueryIterator it = mMapDeviceToQuery.find(pCurDevice); - - // No resource exits for current device -> create it. - if (it == mMapDeviceToQuery.end() || it->second == NULL) - createQuery(pCurDevice); - - - // Grab the query of the current device. - IDirect3DQuery9* pOccQuery = mMapDeviceToQuery[pCurDevice]; - - - if (pOccQuery != NULL) - { - pOccQuery->Issue(D3DISSUE_BEGIN); - mIsQueryResultStillOutstanding = true; - mPixelCount = 0; - } - } - - void D3D9HardwareOcclusionQuery::endOcclusionQuery() - { - IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); - DeviceToQueryIterator it = mMapDeviceToQuery.find(pCurDevice); - - if (it == mMapDeviceToQuery.end()) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "End occlusion called without matching begin call !!", - "D3D9HardwareOcclusionQuery::endOcclusionQuery" ); - } - - IDirect3DQuery9* pOccQuery = mMapDeviceToQuery[pCurDevice]; - - if (pOccQuery != NULL) - pOccQuery->Issue(D3DISSUE_END); - } - - //------------------------------------------------------------------ - bool D3D9HardwareOcclusionQuery::pullOcclusionQuery( unsigned int* NumOfFragments ) - { - IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); - DeviceToQueryIterator it = mMapDeviceToQuery.find(pCurDevice); - - if (it == mMapDeviceToQuery.end()) - return false; - - if (it->second == NULL) - return false; + { + + } + + /** + * Object destructor + */ + D3D9HardwareOcclusionQuery::~D3D9HardwareOcclusionQuery() + { + DeviceToQueryIterator it = mMapDeviceToQuery.begin(); + + while (it != mMapDeviceToQuery.end()) + { + SAFE_RELEASE(it->second); + ++it; + } + mMapDeviceToQuery.clear(); + } + + //------------------------------------------------------------------ + // Occlusion query functions (see base class documentation for this) + //-- + void D3D9HardwareOcclusionQuery::beginOcclusionQuery() + { + IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); + DeviceToQueryIterator it = mMapDeviceToQuery.find(pCurDevice); + + // No resource exits for current device -> create it. + if (it == mMapDeviceToQuery.end() || it->second == NULL) + createQuery(pCurDevice); + + + // Grab the query of the current device. + IDirect3DQuery9* pOccQuery = mMapDeviceToQuery[pCurDevice]; + + + if (pOccQuery != NULL) + { + pOccQuery->Issue(D3DISSUE_BEGIN); + mIsQueryResultStillOutstanding = true; + mPixelCount = 0; + } + } + + void D3D9HardwareOcclusionQuery::endOcclusionQuery() + { + IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); + DeviceToQueryIterator it = mMapDeviceToQuery.find(pCurDevice); + + if (it == mMapDeviceToQuery.end()) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "End occlusion called without matching begin call !!", + "D3D9HardwareOcclusionQuery::endOcclusionQuery" ); + } + + IDirect3DQuery9* pOccQuery = mMapDeviceToQuery[pCurDevice]; + + if (pOccQuery != NULL) + pOccQuery->Issue(D3DISSUE_END); + } + + //------------------------------------------------------------------ + bool D3D9HardwareOcclusionQuery::pullOcclusionQuery( unsigned int* NumOfFragments ) + { + IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); + DeviceToQueryIterator it = mMapDeviceToQuery.find(pCurDevice); + + if (it == mMapDeviceToQuery.end()) + return false; + + if (it->second == NULL) + return false; // in case you didn't check if query arrived and want the result now. if (mIsQueryResultStillOutstanding) @@ -126,7 +126,7 @@ namespace Ogre { // Loop until the data becomes available DWORD pixels; const size_t dataSize = sizeof( DWORD ); - while (1) + while (1) { const HRESULT hr = it->second->GetData((void *)&pixels, dataSize, D3DGETDATA_FLUSH); @@ -152,15 +152,15 @@ namespace Ogre { { // we already stored result from last frames. *NumOfFragments = mPixelCount; - } - return true; - } + } + return true; + } - //------------------------------------------------------------------ - unsigned int D3D9HardwareOcclusionQuery::getLastQuerysPixelcount() - { - return mPixelCount; - } + //------------------------------------------------------------------ + unsigned int D3D9HardwareOcclusionQuery::getLastQuerysPixelcount() + { + return mPixelCount; + } //------------------------------------------------------------------ bool D3D9HardwareOcclusionQuery::isStillOutstanding(void) @@ -169,14 +169,14 @@ namespace Ogre { if (!mIsQueryResultStillOutstanding) return false; - IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); - DeviceToQueryIterator it = mMapDeviceToQuery.find(pCurDevice); + IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); + DeviceToQueryIterator it = mMapDeviceToQuery.find(pCurDevice); - if (it == mMapDeviceToQuery.end()) - return false; + if (it == mMapDeviceToQuery.end()) + return false; - if (it->second == NULL) - return false; + if (it->second == NULL) + return false; DWORD pixels; @@ -188,68 +188,68 @@ namespace Ogre { if (hr == D3DERR_DEVICELOST) { mPixelCount = 100000; - SAFE_RELEASE(it->second); + SAFE_RELEASE(it->second); } mPixelCount = pixels; mIsQueryResultStillOutstanding = false; return false; - } - - //------------------------------------------------------------------ - void D3D9HardwareOcclusionQuery::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) - { - - } - - //------------------------------------------------------------------ - void D3D9HardwareOcclusionQuery::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) - { - releaseQuery(d3d9Device); - } - - //------------------------------------------------------------------ - void D3D9HardwareOcclusionQuery::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) - { - releaseQuery(d3d9Device); - } - - //------------------------------------------------------------------ - void D3D9HardwareOcclusionQuery::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) - { - - } - - //------------------------------------------------------------------ - void D3D9HardwareOcclusionQuery::createQuery(IDirect3DDevice9* d3d9Device) - { - HRESULT hr; - - // Check if query supported. - hr = d3d9Device->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL); - if (FAILED(hr)) - { - mMapDeviceToQuery[d3d9Device] = NULL; - return; - } - - // create the occlusion query. - IDirect3DQuery9* pCurQuery; - hr = d3d9Device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &pCurQuery); - - mMapDeviceToQuery[d3d9Device] = pCurQuery; - } - - //------------------------------------------------------------------ - void D3D9HardwareOcclusionQuery::releaseQuery(IDirect3DDevice9* d3d9Device) - { - DeviceToQueryIterator it = mMapDeviceToQuery.find(d3d9Device); - - // Remove from query resource map. - if (it != mMapDeviceToQuery.end()) - { - SAFE_RELEASE(it->second); - mMapDeviceToQuery.erase(it); - } - } + } + + //------------------------------------------------------------------ + void D3D9HardwareOcclusionQuery::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) + { + + } + + //------------------------------------------------------------------ + void D3D9HardwareOcclusionQuery::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) + { + releaseQuery(d3d9Device); + } + + //------------------------------------------------------------------ + void D3D9HardwareOcclusionQuery::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) + { + releaseQuery(d3d9Device); + } + + //------------------------------------------------------------------ + void D3D9HardwareOcclusionQuery::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) + { + + } + + //------------------------------------------------------------------ + void D3D9HardwareOcclusionQuery::createQuery(IDirect3DDevice9* d3d9Device) + { + HRESULT hr; + + // Check if query supported. + hr = d3d9Device->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL); + if (FAILED(hr)) + { + mMapDeviceToQuery[d3d9Device] = NULL; + return; + } + + // create the occlusion query. + IDirect3DQuery9* pCurQuery; + hr = d3d9Device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &pCurQuery); + + mMapDeviceToQuery[d3d9Device] = pCurQuery; + } + + //------------------------------------------------------------------ + void D3D9HardwareOcclusionQuery::releaseQuery(IDirect3DDevice9* d3d9Device) + { + DeviceToQueryIterator it = mMapDeviceToQuery.find(d3d9Device); + + // Remove from query resource map. + if (it != mMapDeviceToQuery.end()) + { + SAFE_RELEASE(it->second); + mMapDeviceToQuery.erase(it); + } + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9HardwarePixelBuffer.cpp b/RenderSystems/Direct3D9/src/OgreD3D9HardwarePixelBuffer.cpp index ebae8019c18..734ee14730a 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9HardwarePixelBuffer.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9HardwarePixelBuffer.cpp @@ -41,977 +41,977 @@ namespace Ogre { //----------------------------------------------------------------------------- D3D9HardwarePixelBuffer::D3D9HardwarePixelBuffer(HardwareBuffer::Usage usage, - D3D9Texture* ownerTexture): - HardwarePixelBuffer(0, 0, 0, PF_UNKNOWN, usage, false, false), - mDoMipmapGen(false), mHWMipmaps(false), mOwnerTexture(ownerTexture), - mRenderTexture(NULL) -{ + D3D9Texture* ownerTexture): + HardwarePixelBuffer(0, 0, 0, PF_UNKNOWN, usage, false, false), + mDoMipmapGen(false), mHWMipmaps(false), mOwnerTexture(ownerTexture), + mRenderTexture(NULL) +{ } D3D9HardwarePixelBuffer::~D3D9HardwarePixelBuffer() { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - destroyRenderTexture(); - - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - - while (it != mMapDeviceToBufferResources.end()) - { - SAFE_RELEASE(it->second->surface); - SAFE_RELEASE(it->second->volume); - if (it->second != NULL) - { - OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); - it->second = NULL; - } - DeviceToBufferResourcesIterator deadi = it++; - mMapDeviceToBufferResources.erase(deadi); - } + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + destroyRenderTexture(); + + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + + while (it != mMapDeviceToBufferResources.end()) + { + SAFE_RELEASE(it->second->surface); + SAFE_RELEASE(it->second->volume); + if (it->second != NULL) + { + OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); + it->second = NULL; + } + DeviceToBufferResourcesIterator deadi = it++; + mMapDeviceToBufferResources.erase(deadi); + } } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::bind(IDirect3DDevice9 *dev, IDirect3DSurface9 *surface, - IDirect3DSurface9* fsaaSurface, - bool writeGamma, uint fsaa, const String& srcName, - IDirect3DBaseTexture9 *mipTex) + IDirect3DSurface9* fsaaSurface, + bool writeGamma, uint fsaa, const String& srcName, + IDirect3DBaseTexture9 *mipTex) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - BufferResources* bufferResources = getBufferResources(dev); - bool isNewBuffer = false; - - if (bufferResources == NULL) - { - bufferResources = createBufferResources(); - mMapDeviceToBufferResources[dev] = bufferResources; - isNewBuffer = true; - } - - bufferResources->mipTex = mipTex; - bufferResources->surface = surface; - bufferResources->surface->AddRef(); - bufferResources->fSAASurface = fsaaSurface; - - D3DSURFACE_DESC desc; - if(surface->GetDesc(&desc) != D3D_OK) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information", - "D3D9HardwarePixelBuffer::D3D9HardwarePixelBuffer"); - - mWidth = desc.Width; - mHeight = desc.Height; - mDepth = 1; - mFormat = D3D9Mappings::_getPF(desc.Format); - // Default - mRowPitch = mWidth; - mSlicePitch = mHeight*mWidth; - mSizeInBytes = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); - - if(mUsage & TU_RENDERTARGET) - updateRenderTexture(writeGamma, fsaa, srcName); - - if (isNewBuffer && mOwnerTexture->isLoaded() && mOwnerTexture->isManuallyLoaded()) - { - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - - while (it != mMapDeviceToBufferResources.end()) - { - if (it->second != bufferResources && - it->second->surface != NULL && - it->first->TestCooperativeLevel() == D3D_OK && - dev->TestCooperativeLevel() == D3D_OK) - { - Box fullBufferBox(0,0,0,mWidth,mHeight,mDepth); - PixelBox dstBox(fullBufferBox, mFormat); - - dstBox.data = OGRE_MALLOC (getSizeInBytes(), MEMCATEGORY_RESOURCE); - blitToMemory(fullBufferBox, dstBox, it->second, it->first); - blitFromMemory(dstBox, fullBufferBox, bufferResources); - OGRE_FREE(dstBox.data, MEMCATEGORY_RESOURCE); - break; - } - ++it; - } - } + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + BufferResources* bufferResources = getBufferResources(dev); + bool isNewBuffer = false; + + if (bufferResources == NULL) + { + bufferResources = createBufferResources(); + mMapDeviceToBufferResources[dev] = bufferResources; + isNewBuffer = true; + } + + bufferResources->mipTex = mipTex; + bufferResources->surface = surface; + bufferResources->surface->AddRef(); + bufferResources->fSAASurface = fsaaSurface; + + D3DSURFACE_DESC desc; + if(surface->GetDesc(&desc) != D3D_OK) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information", + "D3D9HardwarePixelBuffer::D3D9HardwarePixelBuffer"); + + mWidth = desc.Width; + mHeight = desc.Height; + mDepth = 1; + mFormat = D3D9Mappings::_getPF(desc.Format); + // Default + mRowPitch = mWidth; + mSlicePitch = mHeight*mWidth; + mSizeInBytes = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); + + if(mUsage & TU_RENDERTARGET) + updateRenderTexture(writeGamma, fsaa, srcName); + + if (isNewBuffer && mOwnerTexture->isLoaded() && mOwnerTexture->isManuallyLoaded()) + { + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + + while (it != mMapDeviceToBufferResources.end()) + { + if (it->second != bufferResources && + it->second->surface != NULL && + it->first->TestCooperativeLevel() == D3D_OK && + dev->TestCooperativeLevel() == D3D_OK) + { + Box fullBufferBox(0,0,0,mWidth,mHeight,mDepth); + PixelBox dstBox(fullBufferBox, mFormat); + + dstBox.data = OGRE_MALLOC (getSizeInBytes(), MEMCATEGORY_RESOURCE); + blitToMemory(fullBufferBox, dstBox, it->second, it->first); + blitFromMemory(dstBox, fullBufferBox, bufferResources); + OGRE_FREE(dstBox.data, MEMCATEGORY_RESOURCE); + break; + } + ++it; + } + } } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::bind(IDirect3DDevice9 *dev, IDirect3DVolume9 *volume, IDirect3DBaseTexture9 *mipTex) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - BufferResources* bufferResources = getBufferResources(dev); - bool isNewBuffer = false; - - if (bufferResources == NULL) - { - bufferResources = createBufferResources(); - mMapDeviceToBufferResources[dev] = bufferResources; - isNewBuffer = true; - } - - bufferResources->mipTex = mipTex; - bufferResources->volume = volume; - bufferResources->volume->AddRef(); - - D3DVOLUME_DESC desc; - if(volume->GetDesc(&desc) != D3D_OK) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get volume information", - "D3D9HardwarePixelBuffer::D3D9HardwarePixelBuffer"); - mWidth = desc.Width; - mHeight = desc.Height; - mDepth = desc.Depth; - mFormat = D3D9Mappings::_getPF(desc.Format); - // Default - mRowPitch = mWidth; - mSlicePitch = mHeight*mWidth; - mSizeInBytes = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); - - if (isNewBuffer && mOwnerTexture->isManuallyLoaded()) - { - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - - while (it != mMapDeviceToBufferResources.end()) - { - if (it->second != bufferResources && - it->second->volume != NULL && - it->first->TestCooperativeLevel() == D3D_OK && - dev->TestCooperativeLevel() == D3D_OK) - { - Box fullBufferBox(0,0,0,mWidth,mHeight,mDepth); - PixelBox dstBox(fullBufferBox, mFormat); - - dstBox.data = OGRE_MALLOC(getSizeInBytes(), MEMCATEGORY_RESOURCE); - blitToMemory(fullBufferBox, dstBox, it->second, it->first); - blitFromMemory(dstBox, fullBufferBox, bufferResources); - OGRE_FREE(dstBox.data, MEMCATEGORY_RESOURCE); - break; - } - ++it; - } - } + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + BufferResources* bufferResources = getBufferResources(dev); + bool isNewBuffer = false; + + if (bufferResources == NULL) + { + bufferResources = createBufferResources(); + mMapDeviceToBufferResources[dev] = bufferResources; + isNewBuffer = true; + } + + bufferResources->mipTex = mipTex; + bufferResources->volume = volume; + bufferResources->volume->AddRef(); + + D3DVOLUME_DESC desc; + if(volume->GetDesc(&desc) != D3D_OK) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get volume information", + "D3D9HardwarePixelBuffer::D3D9HardwarePixelBuffer"); + mWidth = desc.Width; + mHeight = desc.Height; + mDepth = desc.Depth; + mFormat = D3D9Mappings::_getPF(desc.Format); + // Default + mRowPitch = mWidth; + mSlicePitch = mHeight*mWidth; + mSizeInBytes = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); + + if (isNewBuffer && mOwnerTexture->isManuallyLoaded()) + { + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + + while (it != mMapDeviceToBufferResources.end()) + { + if (it->second != bufferResources && + it->second->volume != NULL && + it->first->TestCooperativeLevel() == D3D_OK && + dev->TestCooperativeLevel() == D3D_OK) + { + Box fullBufferBox(0,0,0,mWidth,mHeight,mDepth); + PixelBox dstBox(fullBufferBox, mFormat); + + dstBox.data = OGRE_MALLOC(getSizeInBytes(), MEMCATEGORY_RESOURCE); + blitToMemory(fullBufferBox, dstBox, it->second, it->first); + blitFromMemory(dstBox, fullBufferBox, bufferResources); + OGRE_FREE(dstBox.data, MEMCATEGORY_RESOURCE); + break; + } + ++it; + } + } } //----------------------------------------------------------------------------- D3D9HardwarePixelBuffer::BufferResources* D3D9HardwarePixelBuffer::getBufferResources(IDirect3DDevice9* d3d9Device) { - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); - if (it != mMapDeviceToBufferResources.end()) - return it->second; - - return NULL; + if (it != mMapDeviceToBufferResources.end()) + return it->second; + + return NULL; } //----------------------------------------------------------------------------- D3D9HardwarePixelBuffer::BufferResources* D3D9HardwarePixelBuffer::createBufferResources() { - BufferResources* newResources = OGRE_ALLOC_T(BufferResources, 1, MEMCATEGORY_RENDERSYS); + BufferResources* newResources = OGRE_ALLOC_T(BufferResources, 1, MEMCATEGORY_RENDERSYS); - memset(newResources, 0, sizeof(BufferResources)); + memset(newResources, 0, sizeof(BufferResources)); - return newResources; + return newResources; } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::destroyBufferResources(IDirect3DDevice9* d3d9Device) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); - if (it != mMapDeviceToBufferResources.end()) - { - SAFE_RELEASE(it->second->surface); - SAFE_RELEASE(it->second->volume); - if (it->second != NULL) - { - OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); - it->second = NULL; - } - mMapDeviceToBufferResources.erase(it); - } + if (it != mMapDeviceToBufferResources.end()) + { + SAFE_RELEASE(it->second->surface); + SAFE_RELEASE(it->second->volume); + if (it->second != NULL) + { + OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); + it->second = NULL; + } + mMapDeviceToBufferResources.erase(it); + } } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::lockDeviceAccess() { - D3D9_DEVICE_ACCESS_LOCK; + D3D9_DEVICE_ACCESS_LOCK; } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::unlockDeviceAccess() { - D3D9_DEVICE_ACCESS_UNLOCK; + D3D9_DEVICE_ACCESS_UNLOCK; } //----------------------------------------------------------------------------- // Util functions to convert a D3D locked box to a pixel box void fromD3DLock(PixelBox &rval, const D3DLOCKED_RECT &lrect) { - size_t bpp = PixelUtil::getNumElemBytes(rval.format); - if (bpp != 0) - { - rval.rowPitch = lrect.Pitch / bpp; - rval.slicePitch = rval.rowPitch * rval.getHeight(); - assert((lrect.Pitch % bpp)==0); - } - else if (PixelUtil::isCompressed(rval.format)) - { - rval.rowPitch = rval.getWidth(); - rval.slicePitch = rval.getWidth() * rval.getHeight(); - } - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid pixel format", "fromD3DLock"); - } - - rval.data = lrect.pBits; + size_t bpp = PixelUtil::getNumElemBytes(rval.format); + if (bpp != 0) + { + rval.rowPitch = lrect.Pitch / bpp; + rval.slicePitch = rval.rowPitch * rval.getHeight(); + assert((lrect.Pitch % bpp)==0); + } + else if (PixelUtil::isCompressed(rval.format)) + { + rval.rowPitch = rval.getWidth(); + rval.slicePitch = rval.getWidth() * rval.getHeight(); + } + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid pixel format", "fromD3DLock"); + } + + rval.data = lrect.pBits; } void fromD3DLock(PixelBox &rval, const D3DLOCKED_BOX &lbox) { - size_t bpp = PixelUtil::getNumElemBytes(rval.format); - if (bpp != 0) - { - rval.rowPitch = lbox.RowPitch / bpp; - rval.slicePitch = lbox.SlicePitch / bpp; - assert((lbox.RowPitch % bpp)==0); - assert((lbox.SlicePitch % bpp)==0); - } - else if (PixelUtil::isCompressed(rval.format)) - { - rval.rowPitch = rval.getWidth(); - rval.slicePitch = rval.getWidth() * rval.getHeight(); - } - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid pixel format", "fromD3DLock"); - } - rval.data = lbox.pBits; + size_t bpp = PixelUtil::getNumElemBytes(rval.format); + if (bpp != 0) + { + rval.rowPitch = lbox.RowPitch / bpp; + rval.slicePitch = lbox.SlicePitch / bpp; + assert((lbox.RowPitch % bpp)==0); + assert((lbox.SlicePitch % bpp)==0); + } + else if (PixelUtil::isCompressed(rval.format)) + { + rval.rowPitch = rval.getWidth(); + rval.slicePitch = rval.getWidth() * rval.getHeight(); + } + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid pixel format", "fromD3DLock"); + } + rval.data = lbox.pBits; } // Convert Ogre integer Box to D3D rectangle RECT toD3DRECT(const Box &lockBox) { - RECT prect; - assert(lockBox.getDepth() == 1); - prect.left = static_cast(lockBox.left); - prect.right = static_cast(lockBox.right); - prect.top = static_cast(lockBox.top); - prect.bottom = static_cast(lockBox.bottom); - return prect; + RECT prect; + assert(lockBox.getDepth() == 1); + prect.left = static_cast(lockBox.left); + prect.right = static_cast(lockBox.right); + prect.top = static_cast(lockBox.top); + prect.bottom = static_cast(lockBox.bottom); + return prect; } // Convert Ogre integer Box to D3D box D3DBOX toD3DBOX(const Box &lockBox) { - D3DBOX pbox; - - pbox.Left = static_cast(lockBox.left); - pbox.Right = static_cast(lockBox.right); - pbox.Top = static_cast(lockBox.top); - pbox.Bottom = static_cast(lockBox.bottom); - pbox.Front = static_cast(lockBox.front); - pbox.Back = static_cast(lockBox.back); - return pbox; + D3DBOX pbox; + + pbox.Left = static_cast(lockBox.left); + pbox.Right = static_cast(lockBox.right); + pbox.Top = static_cast(lockBox.top); + pbox.Bottom = static_cast(lockBox.bottom); + pbox.Front = static_cast(lockBox.front); + pbox.Back = static_cast(lockBox.back); + return pbox; } // Convert Ogre pixelbox extent to D3D rectangle RECT toD3DRECTExtent(const PixelBox &lockBox) { - RECT prect; - assert(lockBox.getDepth() == 1); - prect.left = 0; - prect.right = static_cast(lockBox.getWidth()); - prect.top = 0; - prect.bottom = static_cast(lockBox.getHeight()); - return prect; + RECT prect; + assert(lockBox.getDepth() == 1); + prect.left = 0; + prect.right = static_cast(lockBox.getWidth()); + prect.top = 0; + prect.bottom = static_cast(lockBox.getHeight()); + return prect; } // Convert Ogre pixelbox extent to D3D box D3DBOX toD3DBOXExtent(const PixelBox &lockBox) { - D3DBOX pbox; - pbox.Left = 0; - pbox.Right = static_cast(lockBox.getWidth()); - pbox.Top = 0; - pbox.Bottom = static_cast(lockBox.getHeight()); - pbox.Front = 0; - pbox.Back = static_cast(lockBox.getDepth()); - return pbox; + D3DBOX pbox; + pbox.Left = 0; + pbox.Right = static_cast(lockBox.getWidth()); + pbox.Top = 0; + pbox.Bottom = static_cast(lockBox.getHeight()); + pbox.Front = 0; + pbox.Back = static_cast(lockBox.getDepth()); + return pbox; } //----------------------------------------------------------------------------- PixelBox D3D9HardwarePixelBuffer::lockImpl(const Image::Box &lockBox, LockOptions options) -{ - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - // Check for misuse - if(mUsage & TU_RENDERTARGET) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "DirectX does not allow locking of or directly writing to RenderTargets. Use blitFromMemory if you need the contents.", - "D3D9HardwarePixelBuffer::lockImpl"); - // Set locking flags according to options - DWORD flags = 0; - switch(options) - { - case HBL_DISCARD: - // D3D only likes D3DLOCK_DISCARD if you created the texture with D3DUSAGE_DYNAMIC - // debug runtime flags this up, could cause problems on some drivers - if (mUsage & HBU_DYNAMIC) - flags |= D3DLOCK_DISCARD; - break; - case HBL_READ_ONLY: - flags |= D3DLOCK_READONLY; - break; - default: - break; - }; - - if (mMapDeviceToBufferResources.size() == 0) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "There are no resources attached to this pixel buffer !!", - "D3D9HardwarePixelBuffer::lockImpl"); - } - - mLockedBox = lockBox; - mLockFlags = flags; - - BufferResources* bufferResources = mMapDeviceToBufferResources.begin()->second; - - // Lock the source buffer. - return lockBuffer(bufferResources, lockBox, flags); +{ + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + // Check for misuse + if(mUsage & TU_RENDERTARGET) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "DirectX does not allow locking of or directly writing to RenderTargets. Use blitFromMemory if you need the contents.", + "D3D9HardwarePixelBuffer::lockImpl"); + // Set locking flags according to options + DWORD flags = 0; + switch(options) + { + case HBL_DISCARD: + // D3D only likes D3DLOCK_DISCARD if you created the texture with D3DUSAGE_DYNAMIC + // debug runtime flags this up, could cause problems on some drivers + if (mUsage & HBU_DYNAMIC) + flags |= D3DLOCK_DISCARD; + break; + case HBL_READ_ONLY: + flags |= D3DLOCK_READONLY; + break; + default: + break; + }; + + if (mMapDeviceToBufferResources.size() == 0) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "There are no resources attached to this pixel buffer !!", + "D3D9HardwarePixelBuffer::lockImpl"); + } + + mLockedBox = lockBox; + mLockFlags = flags; + + BufferResources* bufferResources = mMapDeviceToBufferResources.begin()->second; + + // Lock the source buffer. + return lockBuffer(bufferResources, lockBox, flags); } //----------------------------------------------------------------------------- Ogre::PixelBox D3D9HardwarePixelBuffer::lockBuffer(BufferResources* bufferResources, - const Image::Box &lockBox, - DWORD flags) + const Image::Box &lockBox, + DWORD flags) { - // Set extents and format - // Note that we do not carry over the left/top/front here, since the returned - // PixelBox will be re-based from the locking point onwards - PixelBox rval(lockBox.getWidth(), lockBox.getHeight(), lockBox.getDepth(), mFormat); - - - if (bufferResources->surface != NULL) - { - // Surface - D3DLOCKED_RECT lrect; // Filled in by D3D - HRESULT hr; - - if (lockBox.left == 0 && lockBox.top == 0 - && lockBox.right == mWidth && lockBox.bottom == mHeight) - { - // Lock whole surface - hr = bufferResources->surface->LockRect(&lrect, NULL, flags); - } - else - { - RECT prect = toD3DRECT(lockBox); // specify range to lock - hr = bufferResources->surface->LockRect(&lrect, &prect, flags); - } - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Surface locking failed", - "D3D9HardwarePixelBuffer::lockImpl"); - fromD3DLock(rval, lrect); - } - else if(bufferResources->volume) - { - // Volume - D3DLOCKED_BOX lbox; // Filled in by D3D - HRESULT hr; - - if (lockBox.left == 0 && lockBox.top == 0 && lockBox.front == 0 && - lockBox.right == mWidth && lockBox.bottom == mHeight && lockBox.back == mDepth) - { - hr = bufferResources->volume->LockBox(&lbox, NULL, flags); - } - else - { - D3DBOX pbox = toD3DBOX(lockBox); // specify range to lock - hr = bufferResources->volume->LockBox(&lbox, &pbox, flags); - } - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Volume locking failed", - "D3D9HardwarePixelBuffer::lockImpl"); - } - fromD3DLock(rval, lbox); - } - - - return rval; + // Set extents and format + // Note that we do not carry over the left/top/front here, since the returned + // PixelBox will be re-based from the locking point onwards + PixelBox rval(lockBox.getWidth(), lockBox.getHeight(), lockBox.getDepth(), mFormat); + + + if (bufferResources->surface != NULL) + { + // Surface + D3DLOCKED_RECT lrect; // Filled in by D3D + HRESULT hr; + + if (lockBox.left == 0 && lockBox.top == 0 + && lockBox.right == mWidth && lockBox.bottom == mHeight) + { + // Lock whole surface + hr = bufferResources->surface->LockRect(&lrect, NULL, flags); + } + else + { + RECT prect = toD3DRECT(lockBox); // specify range to lock + hr = bufferResources->surface->LockRect(&lrect, &prect, flags); + } + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Surface locking failed", + "D3D9HardwarePixelBuffer::lockImpl"); + fromD3DLock(rval, lrect); + } + else if(bufferResources->volume) + { + // Volume + D3DLOCKED_BOX lbox; // Filled in by D3D + HRESULT hr; + + if (lockBox.left == 0 && lockBox.top == 0 && lockBox.front == 0 && + lockBox.right == mWidth && lockBox.bottom == mHeight && lockBox.back == mDepth) + { + hr = bufferResources->volume->LockBox(&lbox, NULL, flags); + } + else + { + D3DBOX pbox = toD3DBOX(lockBox); // specify range to lock + hr = bufferResources->volume->LockBox(&lbox, &pbox, flags); + } + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Volume locking failed", + "D3D9HardwarePixelBuffer::lockImpl"); + } + fromD3DLock(rval, lbox); + } + + + return rval; } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::unlockImpl(void) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if (mMapDeviceToBufferResources.size() == 0) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "There are no resources attached to this pixel buffer !!", - "D3D9HardwarePixelBuffer::lockImpl"); - } - - DeviceToBufferResourcesIterator it; - - // 1. Update duplicates buffers. - it = mMapDeviceToBufferResources.begin(); - ++it; - while (it != mMapDeviceToBufferResources.end()) - { - BufferResources* bufferResources = it->second; - - // Update duplicated buffer from the from the locked buffer content. - blitFromMemory(mCurrentLock, mLockedBox, bufferResources); - ++it; - } - - // 2. Unlock the locked buffer. - it = mMapDeviceToBufferResources.begin(); - unlockBuffer( it->second); - if(mDoMipmapGen) - _genMipmaps(it->second->mipTex); + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if (mMapDeviceToBufferResources.size() == 0) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "There are no resources attached to this pixel buffer !!", + "D3D9HardwarePixelBuffer::lockImpl"); + } + + DeviceToBufferResourcesIterator it; + + // 1. Update duplicates buffers. + it = mMapDeviceToBufferResources.begin(); + ++it; + while (it != mMapDeviceToBufferResources.end()) + { + BufferResources* bufferResources = it->second; + + // Update duplicated buffer from the from the locked buffer content. + blitFromMemory(mCurrentLock, mLockedBox, bufferResources); + ++it; + } + + // 2. Unlock the locked buffer. + it = mMapDeviceToBufferResources.begin(); + unlockBuffer( it->second); + if(mDoMipmapGen) + _genMipmaps(it->second->mipTex); } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::unlockBuffer(BufferResources* bufferResources) { - if(bufferResources->surface) - { - // Surface - bufferResources->surface->UnlockRect(); - } - else if(bufferResources->volume) - { - // Volume - bufferResources->volume->UnlockBox(); - } + if(bufferResources->surface) + { + // Surface + bufferResources->surface->UnlockRect(); + } + else if(bufferResources->volume) + { + // Volume + bufferResources->volume->UnlockBox(); + } } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::blit(const HardwarePixelBufferSharedPtr &rsrc, - const Image::Box &srcBox, - const Image::Box &dstBox) + const Image::Box &srcBox, + const Image::Box &dstBox) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - D3D9HardwarePixelBuffer *src = static_cast(rsrc.getPointer()); - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + D3D9HardwarePixelBuffer *src = static_cast(rsrc.getPointer()); + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - // Update all the buffer copies. - while (it != mMapDeviceToBufferResources.end()) - { - BufferResources* srcBufferResources = src->getBufferResources(it->first); - BufferResources* dstBufferResources = it->second; + // Update all the buffer copies. + while (it != mMapDeviceToBufferResources.end()) + { + BufferResources* srcBufferResources = src->getBufferResources(it->first); + BufferResources* dstBufferResources = it->second; - if (srcBufferResources == NULL) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "There are no matching resources attached to the source pixel buffer !!", - "D3D9HardwarePixelBuffer::blit"); - } + if (srcBufferResources == NULL) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "There are no matching resources attached to the source pixel buffer !!", + "D3D9HardwarePixelBuffer::blit"); + } - blit(it->first, rsrc, srcBox, dstBox, srcBufferResources, dstBufferResources); - ++it; - } + blit(it->first, rsrc, srcBox, dstBox, srcBufferResources, dstBufferResources); + ++it; + } } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::blit(IDirect3DDevice9* d3d9Device, - const HardwarePixelBufferSharedPtr &rsrc, - const Image::Box &srcBox, - const Image::Box &dstBox, - BufferResources* srcBufferResources, - BufferResources* dstBufferResources) + const HardwarePixelBufferSharedPtr &rsrc, + const Image::Box &srcBox, + const Image::Box &dstBox, + BufferResources* srcBufferResources, + BufferResources* dstBufferResources) { - if(dstBufferResources->surface && srcBufferResources->surface) - { - // Surface-to-surface - RECT dsrcRect = toD3DRECT(srcBox); - RECT ddestRect = toD3DRECT(dstBox); - - D3DSURFACE_DESC srcDesc; - if(srcBufferResources->surface->GetDesc(&srcDesc) != D3D_OK) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information", - "D3D9HardwarePixelBuffer::blit"); - - // If we're blitting from a RTT, try GetRenderTargetData - // if we're going to try to use GetRenderTargetData, need to use system mem pool - bool tryGetRenderTargetData = false; - if ((srcDesc.Usage & D3DUSAGE_RENDERTARGET) != 0 - && srcDesc.MultiSampleType == D3DMULTISAMPLE_NONE) - { - - // Temp texture - IDirect3DTexture9 *tmptex; - IDirect3DSurface9 *tmpsurface; - - if(D3DXCreateTexture( - d3d9Device, - srcDesc.Width, srcDesc.Height, - 1, // 1 mip level ie topmost, generate no mipmaps - 0, srcDesc.Format, D3DPOOL_SYSTEMMEM, - &tmptex - ) != D3D_OK) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Create temporary texture failed", - "D3D9HardwarePixelBuffer::blit"); - } - if(tmptex->GetSurfaceLevel(0, &tmpsurface) != D3D_OK) - { - tmptex->Release(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get surface level failed", - "D3D9HardwarePixelBuffer::blit"); - } - if(d3d9Device->GetRenderTargetData(srcBufferResources->surface, tmpsurface) == D3D_OK) - { - // Hey, it worked - // Copy from this surface instead - if(D3DXLoadSurfaceFromSurface( - dstBufferResources->surface, NULL, &ddestRect, - tmpsurface, NULL, &dsrcRect, - D3DX_DEFAULT, 0) != D3D_OK) - { - tmpsurface->Release(); - tmptex->Release(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadSurfaceFromSurface failed", - "D3D9HardwarePixelBuffer::blit"); - } - tmpsurface->Release(); - tmptex->Release(); - return; - } - - } - - // Otherwise, try the normal method - - // D3DXLoadSurfaceFromSurface - if(D3DXLoadSurfaceFromSurface( - dstBufferResources->surface, NULL, &ddestRect, - srcBufferResources->surface, NULL, &dsrcRect, - D3DX_DEFAULT, 0) != D3D_OK) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadSurfaceFromSurface failed", - "D3D9HardwarePixelBuffer::blit"); - } - } - else if(dstBufferResources->volume && srcBufferResources->volume) - { - // Volume-to-volume - D3DBOX dsrcBox = toD3DBOX(srcBox); - D3DBOX ddestBox = toD3DBOX(dstBox); - - // D3DXLoadVolumeFromVolume - if(D3DXLoadVolumeFromVolume( - dstBufferResources->volume, NULL, &ddestBox, - srcBufferResources->volume, NULL, &dsrcBox, - D3DX_DEFAULT, 0) != D3D_OK) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadVolumeFromVolume failed", - "D3D9HardwarePixelBuffer::blit"); - } - } - else - { - // Software fallback - HardwarePixelBuffer::blit(rsrc, srcBox, dstBox); - } + if(dstBufferResources->surface && srcBufferResources->surface) + { + // Surface-to-surface + RECT dsrcRect = toD3DRECT(srcBox); + RECT ddestRect = toD3DRECT(dstBox); + + D3DSURFACE_DESC srcDesc; + if(srcBufferResources->surface->GetDesc(&srcDesc) != D3D_OK) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information", + "D3D9HardwarePixelBuffer::blit"); + + // If we're blitting from a RTT, try GetRenderTargetData + // if we're going to try to use GetRenderTargetData, need to use system mem pool + bool tryGetRenderTargetData = false; + if ((srcDesc.Usage & D3DUSAGE_RENDERTARGET) != 0 + && srcDesc.MultiSampleType == D3DMULTISAMPLE_NONE) + { + + // Temp texture + IDirect3DTexture9 *tmptex; + IDirect3DSurface9 *tmpsurface; + + if(D3DXCreateTexture( + d3d9Device, + srcDesc.Width, srcDesc.Height, + 1, // 1 mip level ie topmost, generate no mipmaps + 0, srcDesc.Format, D3DPOOL_SYSTEMMEM, + &tmptex + ) != D3D_OK) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Create temporary texture failed", + "D3D9HardwarePixelBuffer::blit"); + } + if(tmptex->GetSurfaceLevel(0, &tmpsurface) != D3D_OK) + { + tmptex->Release(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get surface level failed", + "D3D9HardwarePixelBuffer::blit"); + } + if(d3d9Device->GetRenderTargetData(srcBufferResources->surface, tmpsurface) == D3D_OK) + { + // Hey, it worked + // Copy from this surface instead + if(D3DXLoadSurfaceFromSurface( + dstBufferResources->surface, NULL, &ddestRect, + tmpsurface, NULL, &dsrcRect, + D3DX_DEFAULT, 0) != D3D_OK) + { + tmpsurface->Release(); + tmptex->Release(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadSurfaceFromSurface failed", + "D3D9HardwarePixelBuffer::blit"); + } + tmpsurface->Release(); + tmptex->Release(); + return; + } + + } + + // Otherwise, try the normal method + + // D3DXLoadSurfaceFromSurface + if(D3DXLoadSurfaceFromSurface( + dstBufferResources->surface, NULL, &ddestRect, + srcBufferResources->surface, NULL, &dsrcRect, + D3DX_DEFAULT, 0) != D3D_OK) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadSurfaceFromSurface failed", + "D3D9HardwarePixelBuffer::blit"); + } + } + else if(dstBufferResources->volume && srcBufferResources->volume) + { + // Volume-to-volume + D3DBOX dsrcBox = toD3DBOX(srcBox); + D3DBOX ddestBox = toD3DBOX(dstBox); + + // D3DXLoadVolumeFromVolume + if(D3DXLoadVolumeFromVolume( + dstBufferResources->volume, NULL, &ddestBox, + srcBufferResources->volume, NULL, &dsrcBox, + D3DX_DEFAULT, 0) != D3D_OK) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadVolumeFromVolume failed", + "D3D9HardwarePixelBuffer::blit"); + } + } + else + { + // Software fallback + HardwarePixelBuffer::blit(rsrc, srcBox, dstBox); + } } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox) -{ - D3D9_DEVICE_ACCESS_CRITICAL_SECTION +{ + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - while (it != mMapDeviceToBufferResources.end()) - { - BufferResources* dstBufferResources = it->second; - - blitFromMemory(src, dstBox, dstBufferResources); - ++it; - } + while (it != mMapDeviceToBufferResources.end()) + { + BufferResources* dstBufferResources = it->second; + + blitFromMemory(src, dstBox, dstBufferResources); + ++it; + } } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox, BufferResources* dstBufferResources) { - // for scoped deletion of conversion buffer - MemoryDataStreamPtr buf; - PixelBox converted = src; - - // convert to pixelbuffer's native format if necessary - if (D3D9Mappings::_getPF(src.format) == D3DFMT_UNKNOWN) - { - buf.bind(OGRE_NEW MemoryDataStream( - PixelUtil::getMemorySize(src.getWidth(), src.getHeight(), src.getDepth(), - mFormat))); - converted = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), mFormat, buf->getPtr()); - PixelUtil::bulkPixelConversion(src, converted); - } - - size_t rowWidth; - if (PixelUtil::isCompressed(converted.format)) - { - // if the row doesn't divide by 4 - there is padding to 4 - if(converted.rowPitch % 4 > 0) - { - converted.rowPitch += 4; - } - - // D3D wants the width of one row of cells in bytes - if (converted.format == PF_DXT1) - { - // 64 bits (8 bytes) per 4x4 block - rowWidth = (converted.rowPitch / 4) * 8; - } - else - { - // 128 bits (16 bytes) per 4x4 block - rowWidth = (converted.rowPitch / 4) * 16; - } - - } - else - { - rowWidth = converted.rowPitch * PixelUtil::getNumElemBytes(converted.format); - } - - if (dstBufferResources->surface) - { - RECT destRect, srcRect; - srcRect = toD3DRECT(converted); - destRect = toD3DRECT(dstBox); - - if(converted.getWidth() != dstBox.getWidth() || converted.getHeight() != dstBox.getHeight() ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Source and dest size are different", - "D3D9HardwarePixelBuffer::blitFromMemory"); - } - - if(D3DXLoadSurfaceFromMemory(dstBufferResources->surface, NULL, &destRect, - converted.data, D3D9Mappings::_getPF(converted.format), - static_cast(rowWidth), - NULL, &srcRect, D3DX_DEFAULT, 0) != D3D_OK) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadSurfaceFromMemory failed", - "D3D9HardwarePixelBuffer::blitFromMemory"); - } - } - else if (dstBufferResources->volume) - { - D3DBOX destBox, srcBox; - srcBox = toD3DBOX(converted); - destBox = toD3DBOX(dstBox); - size_t sliceWidth; - if (PixelUtil::isCompressed(converted.format)) - { - // D3D wants the width of one slice of cells in bytes - if (converted.format == PF_DXT1) - { - // 64 bits (8 bytes) per 4x4 block - sliceWidth = (converted.slicePitch / 16) * 8; - } - else - { - // 128 bits (16 bytes) per 4x4 block - sliceWidth = (converted.slicePitch / 16) * 16; - } - - } - else - { - sliceWidth = converted.slicePitch * PixelUtil::getNumElemBytes(converted.format); - } - - if(D3DXLoadVolumeFromMemory(dstBufferResources->volume, NULL, &destBox, - converted.data, D3D9Mappings::_getPF(converted.format), - static_cast(rowWidth), static_cast(sliceWidth), - NULL, &srcBox, D3DX_DEFAULT, 0) != D3D_OK) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadSurfaceFromMemory failed", - "D3D9HardwarePixelBuffer::blitFromMemory"); - } - } - - if(mDoMipmapGen) - _genMipmaps(dstBufferResources->mipTex); + // for scoped deletion of conversion buffer + MemoryDataStreamPtr buf; + PixelBox converted = src; + + // convert to pixelbuffer's native format if necessary + if (D3D9Mappings::_getPF(src.format) == D3DFMT_UNKNOWN) + { + buf.bind(OGRE_NEW MemoryDataStream( + PixelUtil::getMemorySize(src.getWidth(), src.getHeight(), src.getDepth(), + mFormat))); + converted = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), mFormat, buf->getPtr()); + PixelUtil::bulkPixelConversion(src, converted); + } + + size_t rowWidth; + if (PixelUtil::isCompressed(converted.format)) + { + // if the row doesn't divide by 4 - there is padding to 4 + if(converted.rowPitch % 4 > 0) + { + converted.rowPitch += 4; + } + + // D3D wants the width of one row of cells in bytes + if (converted.format == PF_DXT1) + { + // 64 bits (8 bytes) per 4x4 block + rowWidth = (converted.rowPitch / 4) * 8; + } + else + { + // 128 bits (16 bytes) per 4x4 block + rowWidth = (converted.rowPitch / 4) * 16; + } + + } + else + { + rowWidth = converted.rowPitch * PixelUtil::getNumElemBytes(converted.format); + } + + if (dstBufferResources->surface) + { + RECT destRect, srcRect; + srcRect = toD3DRECT(converted); + destRect = toD3DRECT(dstBox); + + if(converted.getWidth() != dstBox.getWidth() || converted.getHeight() != dstBox.getHeight() ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Source and dest size are different", + "D3D9HardwarePixelBuffer::blitFromMemory"); + } + + if(D3DXLoadSurfaceFromMemory(dstBufferResources->surface, NULL, &destRect, + converted.data, D3D9Mappings::_getPF(converted.format), + static_cast(rowWidth), + NULL, &srcRect, D3DX_DEFAULT, 0) != D3D_OK) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadSurfaceFromMemory failed", + "D3D9HardwarePixelBuffer::blitFromMemory"); + } + } + else if (dstBufferResources->volume) + { + D3DBOX destBox, srcBox; + srcBox = toD3DBOX(converted); + destBox = toD3DBOX(dstBox); + size_t sliceWidth; + if (PixelUtil::isCompressed(converted.format)) + { + // D3D wants the width of one slice of cells in bytes + if (converted.format == PF_DXT1) + { + // 64 bits (8 bytes) per 4x4 block + sliceWidth = (converted.slicePitch / 16) * 8; + } + else + { + // 128 bits (16 bytes) per 4x4 block + sliceWidth = (converted.slicePitch / 16) * 16; + } + + } + else + { + sliceWidth = converted.slicePitch * PixelUtil::getNumElemBytes(converted.format); + } + + if(D3DXLoadVolumeFromMemory(dstBufferResources->volume, NULL, &destBox, + converted.data, D3D9Mappings::_getPF(converted.format), + static_cast(rowWidth), static_cast(sliceWidth), + NULL, &srcBox, D3DX_DEFAULT, 0) != D3D_OK) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadSurfaceFromMemory failed", + "D3D9HardwarePixelBuffer::blitFromMemory"); + } + } + + if(mDoMipmapGen) + _genMipmaps(dstBufferResources->mipTex); } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::blitToMemory(const Image::Box &srcBox, const PixelBox &dst) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - BufferResources* bufferResources = it->second; + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + BufferResources* bufferResources = it->second; - blitToMemory(srcBox, dst, bufferResources, it->first); + blitToMemory(srcBox, dst, bufferResources, it->first); } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::blitToMemory(const Image::Box &srcBox, const PixelBox &dst, - BufferResources* srcBufferResources, - IDirect3DDevice9* d3d9Device) + BufferResources* srcBufferResources, + IDirect3DDevice9* d3d9Device) { - // Decide on pixel format of temp surface - PixelFormat tmpFormat = mFormat; - if(D3D9Mappings::_getPF(dst.format) != D3DFMT_UNKNOWN) - { - tmpFormat = dst.format; - } - - if (srcBufferResources->surface) - { - assert(srcBox.getDepth() == 1 && dst.getDepth() == 1); - // Create temp texture - IDirect3DTexture9 *tmp; - IDirect3DSurface9 *surface; - - D3DSURFACE_DESC srcDesc; - if(srcBufferResources->surface->GetDesc(&srcDesc) != D3D_OK) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information", - "D3D9HardwarePixelBuffer::blitToMemory"); - - D3DPOOL temppool = D3DPOOL_SCRATCH; - // if we're going to try to use GetRenderTargetData, need to use system mem pool - bool tryGetRenderTargetData = false; - if (((srcDesc.Usage & D3DUSAGE_RENDERTARGET) != 0) && - (srcBox.getWidth() == dst.getWidth()) && (srcBox.getHeight() == dst.getHeight()) && - (srcBox.getWidth() == getWidth()) && (srcBox.getHeight() == getHeight()) && - (mFormat == tmpFormat)) - { - tryGetRenderTargetData = true; - temppool = D3DPOOL_SYSTEMMEM; - } - - if(D3DXCreateTexture( - d3d9Device, - static_cast(dst.getWidth()), static_cast(dst.getHeight()), - 1, // 1 mip level ie topmost, generate no mipmaps - 0, D3D9Mappings::_getPF(tmpFormat), temppool, - &tmp - ) != D3D_OK) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Create temporary texture failed", - "D3D9HardwarePixelBuffer::blitToMemory"); - } - if(tmp->GetSurfaceLevel(0, &surface) != D3D_OK) - { - tmp->Release(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get surface level failed", - "D3D9HardwarePixelBuffer::blitToMemory"); - } - // Copy texture to this temp surface - RECT destRect, srcRect; - srcRect = toD3DRECT(srcBox); - destRect = toD3DRECTExtent(dst); - - // Get the real temp surface format - D3DSURFACE_DESC dstDesc; - if(surface->GetDesc(&dstDesc) != D3D_OK) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information", - "D3D9HardwarePixelBuffer::blitToMemory"); - tmpFormat = D3D9Mappings::_getPF(dstDesc.Format); - - // Use fast GetRenderTargetData if we are in its usage conditions - bool fastLoadSuccess = false; - if (tryGetRenderTargetData) - { - if(d3d9Device->GetRenderTargetData(srcBufferResources->surface, surface) == D3D_OK) - { - fastLoadSuccess = true; - } - } - if (!fastLoadSuccess) - { - if(D3DXLoadSurfaceFromSurface( - surface, NULL, &destRect, - srcBufferResources->surface, NULL, &srcRect, - D3DX_DEFAULT, 0) != D3D_OK) - { - surface->Release(); - tmp->Release(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadSurfaceFromSurface failed", - "D3D9HardwarePixelBuffer::blitToMemory"); - } - } - - // Lock temp surface and copy it to memory - D3DLOCKED_RECT lrect; // Filled in by D3D - if(surface->LockRect(&lrect, NULL, D3DLOCK_READONLY) != D3D_OK) - { - surface->Release(); - tmp->Release(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "surface->LockRect", - "D3D9HardwarePixelBuffer::blitToMemory"); - } - // Copy it - PixelBox locked(dst.getWidth(), dst.getHeight(), dst.getDepth(), tmpFormat); - fromD3DLock(locked, lrect); - PixelUtil::bulkPixelConversion(locked, dst); - surface->UnlockRect(); - // Release temporary surface and texture - surface->Release(); - tmp->Release(); - } - else if (srcBufferResources->volume) - { - // Create temp texture - IDirect3DVolumeTexture9 *tmp; - IDirect3DVolume9 *surface; - - if(D3DXCreateVolumeTexture( - d3d9Device, - static_cast(dst.getWidth()), - static_cast(dst.getHeight()), - static_cast(dst.getDepth()), 0, - 0, D3D9Mappings::_getPF(tmpFormat), D3DPOOL_SCRATCH, - &tmp - ) != D3D_OK) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Create temporary texture failed", - "D3D9HardwarePixelBuffer::blitToMemory"); - } - if(tmp->GetVolumeLevel(0, &surface) != D3D_OK) - { - tmp->Release(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get volume level failed", - "D3D9HardwarePixelBuffer::blitToMemory"); - } - // Volume - D3DBOX ddestBox, dsrcBox; - ddestBox = toD3DBOXExtent(dst); - dsrcBox = toD3DBOX(srcBox); - - if(D3DXLoadVolumeFromVolume( - surface, NULL, &ddestBox, - srcBufferResources->volume, NULL, &dsrcBox, - D3DX_DEFAULT, 0) != D3D_OK) - { - surface->Release(); - tmp->Release(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadVolumeFromVolume failed", - "D3D9HardwarePixelBuffer::blitToMemory"); - } - // Lock temp surface and copy it to memory - D3DLOCKED_BOX lbox; // Filled in by D3D - if(surface->LockBox(&lbox, NULL, D3DLOCK_READONLY) != D3D_OK) - { - surface->Release(); - tmp->Release(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "surface->LockBox", - "D3D9HardwarePixelBuffer::blitToMemory"); - } - // Copy it - PixelBox locked(dst.getWidth(), dst.getHeight(), dst.getDepth(), tmpFormat); - fromD3DLock(locked, lbox); - PixelUtil::bulkPixelConversion(locked, dst); - surface->UnlockBox(); - // Release temporary surface and texture - surface->Release(); - tmp->Release(); - } + // Decide on pixel format of temp surface + PixelFormat tmpFormat = mFormat; + if(D3D9Mappings::_getPF(dst.format) != D3DFMT_UNKNOWN) + { + tmpFormat = dst.format; + } + + if (srcBufferResources->surface) + { + assert(srcBox.getDepth() == 1 && dst.getDepth() == 1); + // Create temp texture + IDirect3DTexture9 *tmp; + IDirect3DSurface9 *surface; + + D3DSURFACE_DESC srcDesc; + if(srcBufferResources->surface->GetDesc(&srcDesc) != D3D_OK) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information", + "D3D9HardwarePixelBuffer::blitToMemory"); + + D3DPOOL temppool = D3DPOOL_SCRATCH; + // if we're going to try to use GetRenderTargetData, need to use system mem pool + bool tryGetRenderTargetData = false; + if (((srcDesc.Usage & D3DUSAGE_RENDERTARGET) != 0) && + (srcBox.getWidth() == dst.getWidth()) && (srcBox.getHeight() == dst.getHeight()) && + (srcBox.getWidth() == getWidth()) && (srcBox.getHeight() == getHeight()) && + (mFormat == tmpFormat)) + { + tryGetRenderTargetData = true; + temppool = D3DPOOL_SYSTEMMEM; + } + + if(D3DXCreateTexture( + d3d9Device, + static_cast(dst.getWidth()), static_cast(dst.getHeight()), + 1, // 1 mip level ie topmost, generate no mipmaps + 0, D3D9Mappings::_getPF(tmpFormat), temppool, + &tmp + ) != D3D_OK) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Create temporary texture failed", + "D3D9HardwarePixelBuffer::blitToMemory"); + } + if(tmp->GetSurfaceLevel(0, &surface) != D3D_OK) + { + tmp->Release(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get surface level failed", + "D3D9HardwarePixelBuffer::blitToMemory"); + } + // Copy texture to this temp surface + RECT destRect, srcRect; + srcRect = toD3DRECT(srcBox); + destRect = toD3DRECTExtent(dst); + + // Get the real temp surface format + D3DSURFACE_DESC dstDesc; + if(surface->GetDesc(&dstDesc) != D3D_OK) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information", + "D3D9HardwarePixelBuffer::blitToMemory"); + tmpFormat = D3D9Mappings::_getPF(dstDesc.Format); + + // Use fast GetRenderTargetData if we are in its usage conditions + bool fastLoadSuccess = false; + if (tryGetRenderTargetData) + { + if(d3d9Device->GetRenderTargetData(srcBufferResources->surface, surface) == D3D_OK) + { + fastLoadSuccess = true; + } + } + if (!fastLoadSuccess) + { + if(D3DXLoadSurfaceFromSurface( + surface, NULL, &destRect, + srcBufferResources->surface, NULL, &srcRect, + D3DX_DEFAULT, 0) != D3D_OK) + { + surface->Release(); + tmp->Release(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadSurfaceFromSurface failed", + "D3D9HardwarePixelBuffer::blitToMemory"); + } + } + + // Lock temp surface and copy it to memory + D3DLOCKED_RECT lrect; // Filled in by D3D + if(surface->LockRect(&lrect, NULL, D3DLOCK_READONLY) != D3D_OK) + { + surface->Release(); + tmp->Release(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "surface->LockRect", + "D3D9HardwarePixelBuffer::blitToMemory"); + } + // Copy it + PixelBox locked(dst.getWidth(), dst.getHeight(), dst.getDepth(), tmpFormat); + fromD3DLock(locked, lrect); + PixelUtil::bulkPixelConversion(locked, dst); + surface->UnlockRect(); + // Release temporary surface and texture + surface->Release(); + tmp->Release(); + } + else if (srcBufferResources->volume) + { + // Create temp texture + IDirect3DVolumeTexture9 *tmp; + IDirect3DVolume9 *surface; + + if(D3DXCreateVolumeTexture( + d3d9Device, + static_cast(dst.getWidth()), + static_cast(dst.getHeight()), + static_cast(dst.getDepth()), 0, + 0, D3D9Mappings::_getPF(tmpFormat), D3DPOOL_SCRATCH, + &tmp + ) != D3D_OK) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Create temporary texture failed", + "D3D9HardwarePixelBuffer::blitToMemory"); + } + if(tmp->GetVolumeLevel(0, &surface) != D3D_OK) + { + tmp->Release(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get volume level failed", + "D3D9HardwarePixelBuffer::blitToMemory"); + } + // Volume + D3DBOX ddestBox, dsrcBox; + ddestBox = toD3DBOXExtent(dst); + dsrcBox = toD3DBOX(srcBox); + + if(D3DXLoadVolumeFromVolume( + surface, NULL, &ddestBox, + srcBufferResources->volume, NULL, &dsrcBox, + D3DX_DEFAULT, 0) != D3D_OK) + { + surface->Release(); + tmp->Release(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3DXLoadVolumeFromVolume failed", + "D3D9HardwarePixelBuffer::blitToMemory"); + } + // Lock temp surface and copy it to memory + D3DLOCKED_BOX lbox; // Filled in by D3D + if(surface->LockBox(&lbox, NULL, D3DLOCK_READONLY) != D3D_OK) + { + surface->Release(); + tmp->Release(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "surface->LockBox", + "D3D9HardwarePixelBuffer::blitToMemory"); + } + // Copy it + PixelBox locked(dst.getWidth(), dst.getHeight(), dst.getDepth(), tmpFormat); + fromD3DLock(locked, lbox); + PixelUtil::bulkPixelConversion(locked, dst); + surface->UnlockBox(); + // Release temporary surface and texture + surface->Release(); + tmp->Release(); + } } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::_genMipmaps(IDirect3DBaseTexture9* mipTex) { - assert(mipTex); - - // Mipmapping - if (mHWMipmaps) - { - // Hardware mipmaps - mipTex->GenerateMipSubLevels(); - } - else - { - // Software mipmaps - if( D3DXFilterTexture( mipTex, NULL, D3DX_DEFAULT, D3DX_DEFAULT ) != D3D_OK ) - { - OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, - "Failed to filter texture (generate mipmaps)", - "D3D9HardwarePixelBuffer::_genMipmaps" ); - } - } + assert(mipTex); + + // Mipmapping + if (mHWMipmaps) + { + // Hardware mipmaps + mipTex->GenerateMipSubLevels(); + } + else + { + // Software mipmaps + if( D3DXFilterTexture( mipTex, NULL, D3DX_DEFAULT, D3DX_DEFAULT ) != D3D_OK ) + { + OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, + "Failed to filter texture (generate mipmaps)", + "D3D9HardwarePixelBuffer::_genMipmaps" ); + } + } } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::_setMipmapping(bool doMipmapGen, - bool HWMipmaps) -{ - mDoMipmapGen = doMipmapGen; - mHWMipmaps = HWMipmaps; + bool HWMipmaps) +{ + mDoMipmapGen = doMipmapGen; + mHWMipmaps = HWMipmaps; } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::_clearSliceRTT(size_t zoffset) { - mRenderTexture = NULL; + mRenderTexture = NULL; } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::releaseSurfaces(IDirect3DDevice9* d3d9Device) { - BufferResources* bufferResources = getBufferResources(d3d9Device); + BufferResources* bufferResources = getBufferResources(d3d9Device); - if (bufferResources != NULL) - { - SAFE_RELEASE(bufferResources->surface); - SAFE_RELEASE(bufferResources->volume); - } + if (bufferResources != NULL) + { + SAFE_RELEASE(bufferResources->surface); + SAFE_RELEASE(bufferResources->volume); + } } //----------------------------------------------------------------------------- IDirect3DSurface9* D3D9HardwarePixelBuffer::getSurface(IDirect3DDevice9* d3d9Device) { - BufferResources* bufferResources = getBufferResources(d3d9Device); + BufferResources* bufferResources = getBufferResources(d3d9Device); - if (bufferResources == NULL) - { - mOwnerTexture->createTextureResources(d3d9Device); - bufferResources = getBufferResources(d3d9Device); - } + if (bufferResources == NULL) + { + mOwnerTexture->createTextureResources(d3d9Device); + bufferResources = getBufferResources(d3d9Device); + } - return bufferResources->surface; + return bufferResources->surface; } //----------------------------------------------------------------------------- IDirect3DSurface9* D3D9HardwarePixelBuffer::getFSAASurface(IDirect3DDevice9* d3d9Device) { - BufferResources* bufferResources = getBufferResources(d3d9Device); + BufferResources* bufferResources = getBufferResources(d3d9Device); - if (bufferResources == NULL) - { - mOwnerTexture->createTextureResources(d3d9Device); - bufferResources = getBufferResources(d3d9Device); - } - - return bufferResources->fSAASurface; + if (bufferResources == NULL) + { + mOwnerTexture->createTextureResources(d3d9Device); + bufferResources = getBufferResources(d3d9Device); + } + + return bufferResources->fSAASurface; } //----------------------------------------------------------------------------- RenderTexture *D3D9HardwarePixelBuffer::getRenderTarget(size_t zoffset) { assert(mUsage & TU_RENDERTARGET); - assert(mRenderTexture != NULL); - return mRenderTexture; + assert(mRenderTexture != NULL); + return mRenderTexture; } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::updateRenderTexture(bool writeGamma, uint fsaa, const String& srcName) { - if (mRenderTexture == NULL) - { - String name; - name = "rtt/" +Ogre::StringConverter::toString((size_t)this) + "/" + srcName; + if (mRenderTexture == NULL) + { + String name; + name = "rtt/" +Ogre::StringConverter::toString((size_t)this) + "/" + srcName; - mRenderTexture = OGRE_NEW D3D9RenderTexture(name, this, writeGamma, fsaa); - Root::getSingleton().getRenderSystem()->attachRenderTarget(*mRenderTexture); - } + mRenderTexture = OGRE_NEW D3D9RenderTexture(name, this, writeGamma, fsaa); + Root::getSingleton().getRenderSystem()->attachRenderTarget(*mRenderTexture); + } } //----------------------------------------------------------------------------- void D3D9HardwarePixelBuffer::destroyRenderTexture() { - if (mRenderTexture != NULL) - { - Root::getSingleton().getRenderSystem()->destroyRenderTarget(mRenderTexture->getName()); - mRenderTexture = NULL; - } + if (mRenderTexture != NULL) + { + Root::getSingleton().getRenderSystem()->destroyRenderTarget(mRenderTexture->getName()); + mRenderTexture = NULL; + } } }; diff --git a/RenderSystems/Direct3D9/src/OgreD3D9HardwareVertexBuffer.cpp b/RenderSystems/Direct3D9/src/OgreD3D9HardwareVertexBuffer.cpp index 412f87eb6e0..40d26f3a118 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9HardwareVertexBuffer.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9HardwareVertexBuffer.cpp @@ -36,144 +36,144 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- D3D9HardwareVertexBuffer::D3D9HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage, bool useSystemMemory, bool useShadowBuffer) : HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, useSystemMemory, - useShadowBuffer || - // Allocate the system memory buffer for restoring after device lost. - (((usage & HardwareBuffer::HBU_WRITE_ONLY) != 0) && - D3D9RenderSystem::getResourceManager()->getAutoHardwareBufferManagement())) + useShadowBuffer || + // Allocate the system memory buffer for restoring after device lost. + (((usage & HardwareBuffer::HBU_WRITE_ONLY) != 0) && + D3D9RenderSystem::getResourceManager()->getAutoHardwareBufferManagement())) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - D3DPOOL eResourcePool; - + D3DPOOL eResourcePool; + #if OGRE_D3D_MANAGE_BUFFERS - eResourcePool = useSystemMemory? D3DPOOL_SYSTEMMEM : - // If not system mem, use managed pool UNLESS buffer is discardable - // if discardable, keeping the software backing is expensive - ((usage & HardwareBuffer::HBU_DISCARDABLE) || (D3D9RenderSystem::isDirectX9Ex())) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; + eResourcePool = useSystemMemory? D3DPOOL_SYSTEMMEM : + // If not system mem, use managed pool UNLESS buffer is discardable + // if discardable, keeping the software backing is expensive + ((usage & HardwareBuffer::HBU_DISCARDABLE) || (D3D9RenderSystem::isDirectX9Ex())) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; #else - eResourcePool = useSystemMemory? D3DPOOL_SYSTEMMEM : D3DPOOL_DEFAULT; -#endif + eResourcePool = useSystemMemory? D3DPOOL_SYSTEMMEM : D3DPOOL_DEFAULT; +#endif - // Set the desired memory pool. - mBufferDesc.Pool = eResourcePool; + // Set the desired memory pool. + mBufferDesc.Pool = eResourcePool; - // Set source buffer to NULL. - mSourceBuffer = NULL; - mSourceLockedBytes = NULL; + // Set source buffer to NULL. + mSourceBuffer = NULL; + mSourceLockedBytes = NULL; - // Create buffer resource(s). - for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) - { - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); + // Create buffer resource(s). + for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) + { + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); - createBuffer(d3d9Device, mBufferDesc.Pool, false); - } + createBuffer(d3d9Device, mBufferDesc.Pool, false); + } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- D3D9HardwareVertexBuffer::~D3D9HardwareVertexBuffer() - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - - while (it != mMapDeviceToBufferResources.end()) - { - SAFE_RELEASE(it->second->mBuffer); - if (it->second != NULL) - { - OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); - it->second = NULL; - } - ++it; - } - mMapDeviceToBufferResources.clear(); - } - //--------------------------------------------------------------------- + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + + while (it != mMapDeviceToBufferResources.end()) + { + SAFE_RELEASE(it->second->mBuffer); + if (it->second != NULL) + { + OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); + it->second = NULL; + } + ++it; + } + mMapDeviceToBufferResources.clear(); + } + //--------------------------------------------------------------------- void* D3D9HardwareVertexBuffer::lockImpl(size_t offset, size_t length, LockOptions options) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9DeviceIfExists(); - - while (it != mMapDeviceToBufferResources.end()) - { - BufferResources* bufferResources = it->second; - - if (options != HBL_READ_ONLY) - bufferResources->mOutOfDate = true; - - // Case it is the first buffer lock in this frame. - if (bufferResources->mLockLength == 0) - { - if (offset < bufferResources->mLockOffset) - bufferResources->mLockOffset = offset; - if (length > bufferResources->mLockLength) - bufferResources->mLockLength = length; - } - - // Case buffer already locked in this frame. - else - { - size_t highPoint = std::max( offset + length, - bufferResources->mLockOffset + bufferResources->mLockLength ); - bufferResources->mLockOffset = std::min( bufferResources->mLockOffset, offset ); - bufferResources->mLockLength = highPoint - bufferResources->mLockOffset; - } - - bufferResources->mLockOptions = options; - - //We will switch the source buffer to the active d3d9device as we may decide to only update it during unlock - if (it->first == d3d9Device) - mSourceBuffer = it->second; - - ++it; - } - - // Lock the source buffer. - mSourceLockedBytes = _lockBuffer(mSourceBuffer, mSourceBuffer->mLockOffset, mSourceBuffer->mLockLength); - return mSourceLockedBytes; + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9DeviceIfExists(); + + while (it != mMapDeviceToBufferResources.end()) + { + BufferResources* bufferResources = it->second; + + if (options != HBL_READ_ONLY) + bufferResources->mOutOfDate = true; + + // Case it is the first buffer lock in this frame. + if (bufferResources->mLockLength == 0) + { + if (offset < bufferResources->mLockOffset) + bufferResources->mLockOffset = offset; + if (length > bufferResources->mLockLength) + bufferResources->mLockLength = length; + } + + // Case buffer already locked in this frame. + else + { + size_t highPoint = std::max( offset + length, + bufferResources->mLockOffset + bufferResources->mLockLength ); + bufferResources->mLockOffset = std::min( bufferResources->mLockOffset, offset ); + bufferResources->mLockLength = highPoint - bufferResources->mLockOffset; + } + + bufferResources->mLockOptions = options; + + //We will switch the source buffer to the active d3d9device as we may decide to only update it during unlock + if (it->first == d3d9Device) + mSourceBuffer = it->second; + + ++it; + } + + // Lock the source buffer. + mSourceLockedBytes = _lockBuffer(mSourceBuffer, mSourceBuffer->mLockOffset, mSourceBuffer->mLockLength); + return mSourceLockedBytes; } - //--------------------------------------------------------------------- - void D3D9HardwareVertexBuffer::unlockImpl(void) + //--------------------------------------------------------------------- + void D3D9HardwareVertexBuffer::unlockImpl(void) { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - //check if we can delay the update of secondary buffer resources - //if the user requested it and we have a shadow buffer we can always recreate the buffer later - if ((mShadowBuffer == NULL) || ((mLockUploadOption & HBU_ON_DEMAND) == 0)) - { - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); - uint nextFrameNumber = Root::getSingleton().getNextFrameNumber(); - - while (it != mMapDeviceToBufferResources.end()) - { - BufferResources* bufferResources = it->second; - - if (bufferResources->mOutOfDate && - bufferResources->mBuffer != NULL && - nextFrameNumber - bufferResources->mLastUsedFrame <= 1) - { - if (mSourceBuffer != bufferResources) - { - updateBufferResources(mSourceLockedBytes, bufferResources); - } - } - - ++it; - } - } - - _unlockBuffer(mSourceBuffer); - mSourceLockedBytes = NULL; - } - //--------------------------------------------------------------------- + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + //check if we can delay the update of secondary buffer resources + //if the user requested it and we have a shadow buffer we can always recreate the buffer later + if ((mShadowBuffer == NULL) || ((mLockUploadOption & HBU_ON_DEMAND) == 0)) + { + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin(); + uint nextFrameNumber = Root::getSingleton().getNextFrameNumber(); + + while (it != mMapDeviceToBufferResources.end()) + { + BufferResources* bufferResources = it->second; + + if (bufferResources->mOutOfDate && + bufferResources->mBuffer != NULL && + nextFrameNumber - bufferResources->mLastUsedFrame <= 1) + { + if (mSourceBuffer != bufferResources) + { + updateBufferResources(mSourceLockedBytes, bufferResources); + } + } + + ++it; + } + } + + _unlockBuffer(mSourceBuffer); + mSourceLockedBytes = NULL; + } + //--------------------------------------------------------------------- void D3D9HardwareVertexBuffer::readData(size_t offset, size_t length, void* pDest) { @@ -184,258 +184,258 @@ namespace Ogre { this->unlock(); } - //--------------------------------------------------------------------- - void D3D9HardwareVertexBuffer::writeData(size_t offset, size_t length, - const void* pSource, - bool discardWholeBuffer) - { - // There is no functional interface in D3D, just do via manual - // lock, copy & unlock - void* pDst = this->lock(offset, length, - discardWholeBuffer ? HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL); - memcpy(pDst, pSource, length); - this->unlock(); - } - //--------------------------------------------------------------------- - void D3D9HardwareVertexBuffer::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if (D3D9RenderSystem::getResourceManager()->getCreationPolicy() == RCP_CREATE_ON_ALL_DEVICES) - createBuffer(d3d9Device, mBufferDesc.Pool, true); - } - //--------------------------------------------------------------------- - void D3D9HardwareVertexBuffer::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); - - if (it != mMapDeviceToBufferResources.end()) - { - // Case this is the source buffer. - if (it->second == mSourceBuffer) - { - mSourceBuffer = NULL; - } - - SAFE_RELEASE(it->second->mBuffer); - if (it->second != NULL) - { - OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); - it->second = NULL; - } - mMapDeviceToBufferResources.erase(it); - - // Case source buffer just destroyed -> switch to another one if exits. - if (mSourceBuffer == NULL && mMapDeviceToBufferResources.size() > 0) - { - mSourceBuffer = mMapDeviceToBufferResources.begin()->second; - } - } - } - //--------------------------------------------------------------------- - void D3D9HardwareVertexBuffer::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if (mBufferDesc.Pool == D3DPOOL_DEFAULT) - { - DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); - - if (it != mMapDeviceToBufferResources.end()) - { - SAFE_RELEASE(it->second->mBuffer); - } - } - } - //--------------------------------------------------------------------- - void D3D9HardwareVertexBuffer::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + //--------------------------------------------------------------------- + void D3D9HardwareVertexBuffer::writeData(size_t offset, size_t length, + const void* pSource, + bool discardWholeBuffer) + { + // There is no functional interface in D3D, just do via manual + // lock, copy & unlock + void* pDst = this->lock(offset, length, + discardWholeBuffer ? HardwareBuffer::HBL_DISCARD : HardwareBuffer::HBL_NORMAL); + memcpy(pDst, pSource, length); + this->unlock(); + } + //--------------------------------------------------------------------- + void D3D9HardwareVertexBuffer::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if (D3D9RenderSystem::getResourceManager()->getCreationPolicy() == RCP_CREATE_ON_ALL_DEVICES) + createBuffer(d3d9Device, mBufferDesc.Pool, true); + } + //--------------------------------------------------------------------- + void D3D9HardwareVertexBuffer::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); + + if (it != mMapDeviceToBufferResources.end()) + { + // Case this is the source buffer. + if (it->second == mSourceBuffer) + { + mSourceBuffer = NULL; + } + + SAFE_RELEASE(it->second->mBuffer); + if (it->second != NULL) + { + OGRE_FREE (it->second, MEMCATEGORY_RENDERSYS); + it->second = NULL; + } + mMapDeviceToBufferResources.erase(it); + + // Case source buffer just destroyed -> switch to another one if exits. + if (mSourceBuffer == NULL && mMapDeviceToBufferResources.size() > 0) + { + mSourceBuffer = mMapDeviceToBufferResources.begin()->second; + } + } + } + //--------------------------------------------------------------------- + void D3D9HardwareVertexBuffer::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if (mBufferDesc.Pool == D3DPOOL_DEFAULT) + { + DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.find(d3d9Device); + + if (it != mMapDeviceToBufferResources.end()) + { + SAFE_RELEASE(it->second->mBuffer); + } + } + } + //--------------------------------------------------------------------- + void D3D9HardwareVertexBuffer::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - if (mBufferDesc.Pool == D3DPOOL_DEFAULT) - { - createBuffer(d3d9Device, mBufferDesc.Pool, true); - } - } - //--------------------------------------------------------------------- - void D3D9HardwareVertexBuffer::createBuffer(IDirect3DDevice9* d3d9Device, D3DPOOL ePool, bool updateNewBuffer) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - BufferResources* bufferResources; - HRESULT hr; - - DeviceToBufferResourcesIterator it; - - // Find the vertex buffer of this device. - it = mMapDeviceToBufferResources.find(d3d9Device); - if (it != mMapDeviceToBufferResources.end()) - { - bufferResources = it->second; - SAFE_RELEASE(bufferResources->mBuffer); - } - else - { - bufferResources = OGRE_ALLOC_T(BufferResources, 1, MEMCATEGORY_RENDERSYS); - mMapDeviceToBufferResources[d3d9Device] = bufferResources; - } - - bufferResources->mBuffer = NULL; - bufferResources->mOutOfDate = true; - bufferResources->mLockOffset = 0; - bufferResources->mLockLength = getSizeInBytes(); - bufferResources->mLockOptions = HBL_NORMAL; - bufferResources->mLastUsedFrame = Root::getSingleton().getNextFrameNumber(); - - // Create the vertex buffer - hr = d3d9Device->CreateVertexBuffer( - static_cast(mSizeInBytes), - D3D9Mappings::get(mUsage), - 0, // No FVF here, thank you. - ePool, - &bufferResources->mBuffer, - NULL); - - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot restore D3D9 vertex buffer: " + msg, - "D3D9HardwareVertexBuffer::createBuffer"); - } - - hr = bufferResources->mBuffer->GetDesc(&mBufferDesc); - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot get D3D9 Vertex buffer desc: " + msg, - "D3D9HardwareVertexBuffer::createBuffer"); - } - - // Update source buffer if need to. - if (mSourceBuffer == NULL) - { - mSourceBuffer = bufferResources; - } - - // This is a new buffer and source buffer exists we must update the content now - // to prevent situation where the source buffer will be destroyed and we won't be able to restore its content. - // This is except for during the creation process of the class when there is no data yet to update. - else if (updateNewBuffer) - { - updateBufferContent(bufferResources); - } - } - //--------------------------------------------------------------------- - IDirect3DVertexBuffer9* D3D9HardwareVertexBuffer::getD3D9VertexBuffer(void) - { - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); - DeviceToBufferResourcesIterator it; - - // Find the vertex buffer of this device. - it = mMapDeviceToBufferResources.find(d3d9Device); - - // Case vertex buffer was not found for the current device -> create it. - if (it == mMapDeviceToBufferResources.end() || it->second->mBuffer == NULL) - { - createBuffer(d3d9Device, mBufferDesc.Pool, true); - it = mMapDeviceToBufferResources.find(d3d9Device); - } - - // Make sure that the buffer content is updated. - updateBufferContent(it->second); - - it->second->mLastUsedFrame = Root::getSingleton().getNextFrameNumber(); - - return it->second->mBuffer; - } - - //--------------------------------------------------------------------- - void D3D9HardwareVertexBuffer::updateBufferContent(BufferResources* bufferResources) - { - if (bufferResources->mOutOfDate) - { - if (mShadowBuffer != NULL) - { - const char* shadowData = (const char*)mShadowBuffer->lock(bufferResources->mLockOffset, bufferResources->mLockLength, HBL_NORMAL); - updateBufferResources(shadowData, bufferResources); - mShadowBuffer->unlock(); - } - else if (mSourceBuffer != bufferResources && (mUsage & HardwareBuffer::HBU_WRITE_ONLY) == 0) - { - mSourceBuffer->mLockOptions = HBL_READ_ONLY; - mSourceLockedBytes = _lockBuffer(mSourceBuffer, bufferResources->mLockOffset, bufferResources->mLockLength); - updateBufferResources(mSourceLockedBytes, bufferResources); - _unlockBuffer(mSourceBuffer); - mSourceLockedBytes = NULL; - } - } - } - - //--------------------------------------------------------------------- - bool D3D9HardwareVertexBuffer::updateBufferResources(const char* systemMemoryBuffer, - BufferResources* bufferResources) - { - assert(bufferResources != NULL); - assert(bufferResources->mBuffer != NULL); - assert(bufferResources->mOutOfDate); - - - char* dstBytes = _lockBuffer(bufferResources, bufferResources->mLockOffset, bufferResources->mLockLength); - memcpy(dstBytes, systemMemoryBuffer, bufferResources->mLockLength); - _unlockBuffer(bufferResources); - - return true; - } - - //--------------------------------------------------------------------- - char* D3D9HardwareVertexBuffer::_lockBuffer(BufferResources* bufferResources, size_t offset, size_t length) - { - HRESULT hr; - char* pSourceBytes; - - - // Lock the buffer. - hr = bufferResources->mBuffer->Lock( - static_cast(offset), - static_cast(length), - (void**)&pSourceBytes, - D3D9Mappings::get(mSourceBuffer->mLockOptions, mUsage)); - - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot lock D3D9 vertex buffer: " + msg, - "D3D9HardwareVertexBuffer::_lockBuffer"); - } - - return pSourceBytes; - } - - //--------------------------------------------------------------------- - void D3D9HardwareVertexBuffer::_unlockBuffer( BufferResources* bufferResources ) - { - HRESULT hr; - - // Unlock the buffer. - hr = bufferResources->mBuffer->Unlock(); - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot unlock D3D9 vertex buffer: " + msg, - "D3D9HardwareVertexBuffer::_unlockBuffer"); - } - - // Reset attributes. - bufferResources->mOutOfDate = false; - bufferResources->mLockOffset = mSizeInBytes; - bufferResources->mLockLength = 0; - bufferResources->mLockOptions = HBL_NORMAL; - - } + if (mBufferDesc.Pool == D3DPOOL_DEFAULT) + { + createBuffer(d3d9Device, mBufferDesc.Pool, true); + } + } + //--------------------------------------------------------------------- + void D3D9HardwareVertexBuffer::createBuffer(IDirect3DDevice9* d3d9Device, D3DPOOL ePool, bool updateNewBuffer) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + BufferResources* bufferResources; + HRESULT hr; + + DeviceToBufferResourcesIterator it; + + // Find the vertex buffer of this device. + it = mMapDeviceToBufferResources.find(d3d9Device); + if (it != mMapDeviceToBufferResources.end()) + { + bufferResources = it->second; + SAFE_RELEASE(bufferResources->mBuffer); + } + else + { + bufferResources = OGRE_ALLOC_T(BufferResources, 1, MEMCATEGORY_RENDERSYS); + mMapDeviceToBufferResources[d3d9Device] = bufferResources; + } + + bufferResources->mBuffer = NULL; + bufferResources->mOutOfDate = true; + bufferResources->mLockOffset = 0; + bufferResources->mLockLength = getSizeInBytes(); + bufferResources->mLockOptions = HBL_NORMAL; + bufferResources->mLastUsedFrame = Root::getSingleton().getNextFrameNumber(); + + // Create the vertex buffer + hr = d3d9Device->CreateVertexBuffer( + static_cast(mSizeInBytes), + D3D9Mappings::get(mUsage), + 0, // No FVF here, thank you. + ePool, + &bufferResources->mBuffer, + NULL); + + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot restore D3D9 vertex buffer: " + msg, + "D3D9HardwareVertexBuffer::createBuffer"); + } + + hr = bufferResources->mBuffer->GetDesc(&mBufferDesc); + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot get D3D9 Vertex buffer desc: " + msg, + "D3D9HardwareVertexBuffer::createBuffer"); + } + + // Update source buffer if need to. + if (mSourceBuffer == NULL) + { + mSourceBuffer = bufferResources; + } + + // This is a new buffer and source buffer exists we must update the content now + // to prevent situation where the source buffer will be destroyed and we won't be able to restore its content. + // This is except for during the creation process of the class when there is no data yet to update. + else if (updateNewBuffer) + { + updateBufferContent(bufferResources); + } + } + //--------------------------------------------------------------------- + IDirect3DVertexBuffer9* D3D9HardwareVertexBuffer::getD3D9VertexBuffer(void) + { + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); + DeviceToBufferResourcesIterator it; + + // Find the vertex buffer of this device. + it = mMapDeviceToBufferResources.find(d3d9Device); + + // Case vertex buffer was not found for the current device -> create it. + if (it == mMapDeviceToBufferResources.end() || it->second->mBuffer == NULL) + { + createBuffer(d3d9Device, mBufferDesc.Pool, true); + it = mMapDeviceToBufferResources.find(d3d9Device); + } + + // Make sure that the buffer content is updated. + updateBufferContent(it->second); + + it->second->mLastUsedFrame = Root::getSingleton().getNextFrameNumber(); + + return it->second->mBuffer; + } + + //--------------------------------------------------------------------- + void D3D9HardwareVertexBuffer::updateBufferContent(BufferResources* bufferResources) + { + if (bufferResources->mOutOfDate) + { + if (mShadowBuffer != NULL) + { + const char* shadowData = (const char*)mShadowBuffer->lock(bufferResources->mLockOffset, bufferResources->mLockLength, HBL_NORMAL); + updateBufferResources(shadowData, bufferResources); + mShadowBuffer->unlock(); + } + else if (mSourceBuffer != bufferResources && (mUsage & HardwareBuffer::HBU_WRITE_ONLY) == 0) + { + mSourceBuffer->mLockOptions = HBL_READ_ONLY; + mSourceLockedBytes = _lockBuffer(mSourceBuffer, bufferResources->mLockOffset, bufferResources->mLockLength); + updateBufferResources(mSourceLockedBytes, bufferResources); + _unlockBuffer(mSourceBuffer); + mSourceLockedBytes = NULL; + } + } + } + + //--------------------------------------------------------------------- + bool D3D9HardwareVertexBuffer::updateBufferResources(const char* systemMemoryBuffer, + BufferResources* bufferResources) + { + assert(bufferResources != NULL); + assert(bufferResources->mBuffer != NULL); + assert(bufferResources->mOutOfDate); + + + char* dstBytes = _lockBuffer(bufferResources, bufferResources->mLockOffset, bufferResources->mLockLength); + memcpy(dstBytes, systemMemoryBuffer, bufferResources->mLockLength); + _unlockBuffer(bufferResources); + + return true; + } + + //--------------------------------------------------------------------- + char* D3D9HardwareVertexBuffer::_lockBuffer(BufferResources* bufferResources, size_t offset, size_t length) + { + HRESULT hr; + char* pSourceBytes; + + + // Lock the buffer. + hr = bufferResources->mBuffer->Lock( + static_cast(offset), + static_cast(length), + (void**)&pSourceBytes, + D3D9Mappings::get(mSourceBuffer->mLockOptions, mUsage)); + + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot lock D3D9 vertex buffer: " + msg, + "D3D9HardwareVertexBuffer::_lockBuffer"); + } + + return pSourceBytes; + } + + //--------------------------------------------------------------------- + void D3D9HardwareVertexBuffer::_unlockBuffer( BufferResources* bufferResources ) + { + HRESULT hr; + + // Unlock the buffer. + hr = bufferResources->mBuffer->Unlock(); + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot unlock D3D9 vertex buffer: " + msg, + "D3D9HardwareVertexBuffer::_unlockBuffer"); + } + + // Reset attributes. + bufferResources->mOutOfDate = false; + bufferResources->mLockOffset = mSizeInBytes; + bufferResources->mLockLength = 0; + bufferResources->mLockOptions = HBL_NORMAL; + + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9Mappings.cpp b/RenderSystems/Direct3D9/src/OgreD3D9Mappings.cpp index 28967572fba..d95e8a61f92 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9Mappings.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9Mappings.cpp @@ -33,310 +33,310 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- - DWORD D3D9Mappings::get(ShadeOptions so) - { - switch( so ) - { - case SO_FLAT: - return D3DSHADE_FLAT; - case SO_GOURAUD: - return D3DSHADE_GOURAUD; - case SO_PHONG: - return D3DSHADE_PHONG; - } - return 0; - } - //--------------------------------------------------------------------- - D3DLIGHTTYPE D3D9Mappings::get(Ogre::Light::LightTypes lightType) - { - switch( lightType ) - { - case Light::LT_POINT: - return D3DLIGHT_POINT; - case Light::LT_DIRECTIONAL: - return D3DLIGHT_DIRECTIONAL; - case Light::LT_SPOTLIGHT: - return D3DLIGHT_SPOT; - } - return D3DLIGHT_FORCE_DWORD; - } - //--------------------------------------------------------------------- - DWORD D3D9Mappings::get(TexCoordCalcMethod m, const D3DCAPS9& caps) - { - switch( m ) - { - case TEXCALC_NONE: - return D3DTSS_TCI_PASSTHRU; - case TEXCALC_ENVIRONMENT_MAP_REFLECTION: - return D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR; - case TEXCALC_ENVIRONMENT_MAP_PLANAR: - if (caps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN_SPHEREMAP) - { - // Use sphere map if available - return D3DTSS_TCI_SPHEREMAP; - } - else - { - // If not, fall back on camera space reflection vector which isn't as good + //--------------------------------------------------------------------- + DWORD D3D9Mappings::get(ShadeOptions so) + { + switch( so ) + { + case SO_FLAT: + return D3DSHADE_FLAT; + case SO_GOURAUD: + return D3DSHADE_GOURAUD; + case SO_PHONG: + return D3DSHADE_PHONG; + } + return 0; + } + //--------------------------------------------------------------------- + D3DLIGHTTYPE D3D9Mappings::get(Ogre::Light::LightTypes lightType) + { + switch( lightType ) + { + case Light::LT_POINT: + return D3DLIGHT_POINT; + case Light::LT_DIRECTIONAL: + return D3DLIGHT_DIRECTIONAL; + case Light::LT_SPOTLIGHT: + return D3DLIGHT_SPOT; + } + return D3DLIGHT_FORCE_DWORD; + } + //--------------------------------------------------------------------- + DWORD D3D9Mappings::get(TexCoordCalcMethod m, const D3DCAPS9& caps) + { + switch( m ) + { + case TEXCALC_NONE: + return D3DTSS_TCI_PASSTHRU; + case TEXCALC_ENVIRONMENT_MAP_REFLECTION: + return D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR; + case TEXCALC_ENVIRONMENT_MAP_PLANAR: + if (caps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN_SPHEREMAP) + { + // Use sphere map if available + return D3DTSS_TCI_SPHEREMAP; + } + else + { + // If not, fall back on camera space reflection vector which isn't as good return D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR; - } - case TEXCALC_ENVIRONMENT_MAP_NORMAL: - return D3DTSS_TCI_CAMERASPACENORMAL; - case TEXCALC_ENVIRONMENT_MAP: - if (caps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN_SPHEREMAP) - { - // Use sphere map if available - return D3DTSS_TCI_SPHEREMAP; - } - else - { - // If not, fall back on camera space normal which isn't as good - return D3DTSS_TCI_CAMERASPACENORMAL; - } + } + case TEXCALC_ENVIRONMENT_MAP_NORMAL: + return D3DTSS_TCI_CAMERASPACENORMAL; + case TEXCALC_ENVIRONMENT_MAP: + if (caps.VertexProcessingCaps & D3DVTXPCAPS_TEXGEN_SPHEREMAP) + { + // Use sphere map if available + return D3DTSS_TCI_SPHEREMAP; + } + else + { + // If not, fall back on camera space normal which isn't as good + return D3DTSS_TCI_CAMERASPACENORMAL; + } case TEXCALC_PROJECTIVE_TEXTURE: return D3DTSS_TCI_CAMERASPACEPOSITION; - } - return 0; - } - //--------------------------------------------------------------------- - D3DTEXTUREADDRESS D3D9Mappings::get(TextureUnitState::TextureAddressingMode tam, const D3DCAPS9& devCaps) - { - switch( tam ) - { - case TextureUnitState::TAM_WRAP: - return D3DTADDRESS_WRAP; - case TextureUnitState::TAM_MIRROR: - return D3DTADDRESS_MIRROR; - case TextureUnitState::TAM_CLAMP: - return D3DTADDRESS_CLAMP; + } + return 0; + } + //--------------------------------------------------------------------- + D3DTEXTUREADDRESS D3D9Mappings::get(TextureUnitState::TextureAddressingMode tam, const D3DCAPS9& devCaps) + { + switch( tam ) + { + case TextureUnitState::TAM_WRAP: + return D3DTADDRESS_WRAP; + case TextureUnitState::TAM_MIRROR: + return D3DTADDRESS_MIRROR; + case TextureUnitState::TAM_CLAMP: + return D3DTADDRESS_CLAMP; case TextureUnitState::TAM_BORDER: if (devCaps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER) return D3DTADDRESS_BORDER; else return D3DTADDRESS_CLAMP; - } - return D3DTADDRESS_FORCE_DWORD; - } - //--------------------------------------------------------------------- - D3DTEXTURESTAGESTATETYPE D3D9Mappings::get(LayerBlendType lbt) - { - switch( lbt ) - { - case LBT_COLOUR: - return D3DTSS_COLOROP; - case LBT_ALPHA: - return D3DTSS_ALPHAOP; - } - return D3DTSS_FORCE_DWORD; - } - //--------------------------------------------------------------------- - DWORD D3D9Mappings::get(LayerBlendSource lbs, bool perStageConstants) - { - switch( lbs ) - { - case LBS_CURRENT: - return D3DTA_CURRENT; - case LBS_TEXTURE: - return D3DTA_TEXTURE; - case LBS_DIFFUSE: - return D3DTA_DIFFUSE; - case LBS_SPECULAR: - return D3DTA_SPECULAR; - case LBS_MANUAL: - return perStageConstants ? D3DTA_CONSTANT : D3DTA_TFACTOR; - } - return 0; - } - //--------------------------------------------------------------------- - DWORD D3D9Mappings::get(LayerBlendOperationEx lbo, const D3DCAPS9& devCaps) - { - switch( lbo ) - { - case LBX_SOURCE1: - return D3DTOP_SELECTARG1; - case LBX_SOURCE2: - return D3DTOP_SELECTARG2; - case LBX_MODULATE: - return D3DTOP_MODULATE; - case LBX_MODULATE_X2: - return D3DTOP_MODULATE2X; - case LBX_MODULATE_X4: - return D3DTOP_MODULATE4X; - case LBX_ADD: - return D3DTOP_ADD; - case LBX_ADD_SIGNED: - return D3DTOP_ADDSIGNED; - case LBX_ADD_SMOOTH: - return D3DTOP_ADDSMOOTH; - case LBX_SUBTRACT: - return D3DTOP_SUBTRACT; - case LBX_BLEND_DIFFUSE_ALPHA: - return D3DTOP_BLENDDIFFUSEALPHA; - case LBX_BLEND_TEXTURE_ALPHA: - return D3DTOP_BLENDTEXTUREALPHA; - case LBX_BLEND_CURRENT_ALPHA: - return D3DTOP_BLENDCURRENTALPHA; - case LBX_BLEND_MANUAL: - return D3DTOP_BLENDFACTORALPHA; - case LBX_DOTPRODUCT: - if (devCaps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) - return D3DTOP_DOTPRODUCT3; - else - return D3DTOP_MODULATE; - case LBX_BLEND_DIFFUSE_COLOUR: - if (devCaps.TextureOpCaps & D3DTEXOPCAPS_LERP) - return D3DTOP_LERP; - else - return D3DTOP_MODULATE; - } - return 0; - } - //--------------------------------------------------------------------- - D3DBLEND D3D9Mappings::get(SceneBlendFactor sbf) - { - switch( sbf ) - { - case SBF_ONE: - return D3DBLEND_ONE; - case SBF_ZERO: - return D3DBLEND_ZERO; - case SBF_DEST_COLOUR: - return D3DBLEND_DESTCOLOR; - case SBF_SOURCE_COLOUR: - return D3DBLEND_SRCCOLOR; - case SBF_ONE_MINUS_DEST_COLOUR: - return D3DBLEND_INVDESTCOLOR; - case SBF_ONE_MINUS_SOURCE_COLOUR: - return D3DBLEND_INVSRCCOLOR; - case SBF_DEST_ALPHA: - return D3DBLEND_DESTALPHA; - case SBF_SOURCE_ALPHA: - return D3DBLEND_SRCALPHA; - case SBF_ONE_MINUS_DEST_ALPHA: - return D3DBLEND_INVDESTALPHA; - case SBF_ONE_MINUS_SOURCE_ALPHA: - return D3DBLEND_INVSRCALPHA; - } - return D3DBLEND_FORCE_DWORD; - } - //--------------------------------------------------------------------- - D3DBLENDOP D3D9Mappings::get(Ogre::SceneBlendOperation sbo) - { - switch(sbo) - { - case SBO_ADD: - return D3DBLENDOP_ADD; - case SBO_SUBTRACT: - return D3DBLENDOP_SUBTRACT; - case SBO_REVERSE_SUBTRACT: - return D3DBLENDOP_REVSUBTRACT; - case SBO_MIN: - return D3DBLENDOP_MIN; - case SBO_MAX: - return D3DBLENDOP_MAX; - } + } + return D3DTADDRESS_FORCE_DWORD; + } + //--------------------------------------------------------------------- + D3DTEXTURESTAGESTATETYPE D3D9Mappings::get(LayerBlendType lbt) + { + switch( lbt ) + { + case LBT_COLOUR: + return D3DTSS_COLOROP; + case LBT_ALPHA: + return D3DTSS_ALPHAOP; + } + return D3DTSS_FORCE_DWORD; + } + //--------------------------------------------------------------------- + DWORD D3D9Mappings::get(LayerBlendSource lbs, bool perStageConstants) + { + switch( lbs ) + { + case LBS_CURRENT: + return D3DTA_CURRENT; + case LBS_TEXTURE: + return D3DTA_TEXTURE; + case LBS_DIFFUSE: + return D3DTA_DIFFUSE; + case LBS_SPECULAR: + return D3DTA_SPECULAR; + case LBS_MANUAL: + return perStageConstants ? D3DTA_CONSTANT : D3DTA_TFACTOR; + } + return 0; + } + //--------------------------------------------------------------------- + DWORD D3D9Mappings::get(LayerBlendOperationEx lbo, const D3DCAPS9& devCaps) + { + switch( lbo ) + { + case LBX_SOURCE1: + return D3DTOP_SELECTARG1; + case LBX_SOURCE2: + return D3DTOP_SELECTARG2; + case LBX_MODULATE: + return D3DTOP_MODULATE; + case LBX_MODULATE_X2: + return D3DTOP_MODULATE2X; + case LBX_MODULATE_X4: + return D3DTOP_MODULATE4X; + case LBX_ADD: + return D3DTOP_ADD; + case LBX_ADD_SIGNED: + return D3DTOP_ADDSIGNED; + case LBX_ADD_SMOOTH: + return D3DTOP_ADDSMOOTH; + case LBX_SUBTRACT: + return D3DTOP_SUBTRACT; + case LBX_BLEND_DIFFUSE_ALPHA: + return D3DTOP_BLENDDIFFUSEALPHA; + case LBX_BLEND_TEXTURE_ALPHA: + return D3DTOP_BLENDTEXTUREALPHA; + case LBX_BLEND_CURRENT_ALPHA: + return D3DTOP_BLENDCURRENTALPHA; + case LBX_BLEND_MANUAL: + return D3DTOP_BLENDFACTORALPHA; + case LBX_DOTPRODUCT: + if (devCaps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) + return D3DTOP_DOTPRODUCT3; + else + return D3DTOP_MODULATE; + case LBX_BLEND_DIFFUSE_COLOUR: + if (devCaps.TextureOpCaps & D3DTEXOPCAPS_LERP) + return D3DTOP_LERP; + else + return D3DTOP_MODULATE; + } + return 0; + } + //--------------------------------------------------------------------- + D3DBLEND D3D9Mappings::get(SceneBlendFactor sbf) + { + switch( sbf ) + { + case SBF_ONE: + return D3DBLEND_ONE; + case SBF_ZERO: + return D3DBLEND_ZERO; + case SBF_DEST_COLOUR: + return D3DBLEND_DESTCOLOR; + case SBF_SOURCE_COLOUR: + return D3DBLEND_SRCCOLOR; + case SBF_ONE_MINUS_DEST_COLOUR: + return D3DBLEND_INVDESTCOLOR; + case SBF_ONE_MINUS_SOURCE_COLOUR: + return D3DBLEND_INVSRCCOLOR; + case SBF_DEST_ALPHA: + return D3DBLEND_DESTALPHA; + case SBF_SOURCE_ALPHA: + return D3DBLEND_SRCALPHA; + case SBF_ONE_MINUS_DEST_ALPHA: + return D3DBLEND_INVDESTALPHA; + case SBF_ONE_MINUS_SOURCE_ALPHA: + return D3DBLEND_INVSRCALPHA; + } + return D3DBLEND_FORCE_DWORD; + } + //--------------------------------------------------------------------- + D3DBLENDOP D3D9Mappings::get(Ogre::SceneBlendOperation sbo) + { + switch(sbo) + { + case SBO_ADD: + return D3DBLENDOP_ADD; + case SBO_SUBTRACT: + return D3DBLENDOP_SUBTRACT; + case SBO_REVERSE_SUBTRACT: + return D3DBLENDOP_REVSUBTRACT; + case SBO_MIN: + return D3DBLENDOP_MIN; + case SBO_MAX: + return D3DBLENDOP_MAX; + } - return D3DBLENDOP_FORCE_DWORD; - } - //--------------------------------------------------------------------- - DWORD D3D9Mappings::get(CompareFunction cf) - { - switch( cf ) - { - case CMPF_ALWAYS_FAIL: - return D3DCMP_NEVER; - case CMPF_ALWAYS_PASS: - return D3DCMP_ALWAYS; - case CMPF_LESS: - return D3DCMP_LESS; - case CMPF_LESS_EQUAL: - return D3DCMP_LESSEQUAL; - case CMPF_EQUAL: - return D3DCMP_EQUAL; - case CMPF_NOT_EQUAL: - return D3DCMP_NOTEQUAL; - case CMPF_GREATER_EQUAL: - return D3DCMP_GREATEREQUAL; - case CMPF_GREATER: - return D3DCMP_GREATER; - }; - return 0; - } - //--------------------------------------------------------------------- - DWORD D3D9Mappings::get(CullingMode cm, bool flip) - { - switch( cm ) - { - case CULL_NONE: - return D3DCULL_NONE; - case CULL_CLOCKWISE: - if( flip ) - return D3DCULL_CCW; - else - return D3DCULL_CW; - case CULL_ANTICLOCKWISE: - if( flip ) - return D3DCULL_CW; - else - return D3DCULL_CCW; - } - return 0; - } - //--------------------------------------------------------------------- - D3DFOGMODE D3D9Mappings::get(FogMode fm) - { - switch( fm ) - { - case FOG_EXP: - return D3DFOG_EXP; - case FOG_EXP2: - return D3DFOG_EXP2; - case FOG_LINEAR: - return D3DFOG_LINEAR; - } - return D3DFOG_FORCE_DWORD; - } - //--------------------------------------------------------------------- - D3DFILLMODE D3D9Mappings::get(PolygonMode level) - { - switch(level) - { - case PM_POINTS: - return D3DFILL_POINT; - case PM_WIREFRAME: - return D3DFILL_WIREFRAME; - case PM_SOLID: - return D3DFILL_SOLID; - } - return D3DFILL_FORCE_DWORD; - } - //--------------------------------------------------------------------- - DWORD D3D9Mappings::get(StencilOperation op, bool invert) - { - switch(op) - { - case SOP_KEEP: - return D3DSTENCILOP_KEEP; - case SOP_ZERO: - return D3DSTENCILOP_ZERO; - case SOP_REPLACE: - return D3DSTENCILOP_REPLACE; - case SOP_INCREMENT: + return D3DBLENDOP_FORCE_DWORD; + } + //--------------------------------------------------------------------- + DWORD D3D9Mappings::get(CompareFunction cf) + { + switch( cf ) + { + case CMPF_ALWAYS_FAIL: + return D3DCMP_NEVER; + case CMPF_ALWAYS_PASS: + return D3DCMP_ALWAYS; + case CMPF_LESS: + return D3DCMP_LESS; + case CMPF_LESS_EQUAL: + return D3DCMP_LESSEQUAL; + case CMPF_EQUAL: + return D3DCMP_EQUAL; + case CMPF_NOT_EQUAL: + return D3DCMP_NOTEQUAL; + case CMPF_GREATER_EQUAL: + return D3DCMP_GREATEREQUAL; + case CMPF_GREATER: + return D3DCMP_GREATER; + }; + return 0; + } + //--------------------------------------------------------------------- + DWORD D3D9Mappings::get(CullingMode cm, bool flip) + { + switch( cm ) + { + case CULL_NONE: + return D3DCULL_NONE; + case CULL_CLOCKWISE: + if( flip ) + return D3DCULL_CCW; + else + return D3DCULL_CW; + case CULL_ANTICLOCKWISE: + if( flip ) + return D3DCULL_CW; + else + return D3DCULL_CCW; + } + return 0; + } + //--------------------------------------------------------------------- + D3DFOGMODE D3D9Mappings::get(FogMode fm) + { + switch( fm ) + { + case FOG_EXP: + return D3DFOG_EXP; + case FOG_EXP2: + return D3DFOG_EXP2; + case FOG_LINEAR: + return D3DFOG_LINEAR; + } + return D3DFOG_FORCE_DWORD; + } + //--------------------------------------------------------------------- + D3DFILLMODE D3D9Mappings::get(PolygonMode level) + { + switch(level) + { + case PM_POINTS: + return D3DFILL_POINT; + case PM_WIREFRAME: + return D3DFILL_WIREFRAME; + case PM_SOLID: + return D3DFILL_SOLID; + } + return D3DFILL_FORCE_DWORD; + } + //--------------------------------------------------------------------- + DWORD D3D9Mappings::get(StencilOperation op, bool invert) + { + switch(op) + { + case SOP_KEEP: + return D3DSTENCILOP_KEEP; + case SOP_ZERO: + return D3DSTENCILOP_ZERO; + case SOP_REPLACE: + return D3DSTENCILOP_REPLACE; + case SOP_INCREMENT: return invert? D3DSTENCILOP_DECRSAT : D3DSTENCILOP_INCRSAT; - case SOP_DECREMENT: + case SOP_DECREMENT: return invert? D3DSTENCILOP_INCRSAT : D3DSTENCILOP_DECRSAT; - case SOP_INCREMENT_WRAP: + case SOP_INCREMENT_WRAP: return invert? D3DSTENCILOP_DECR : D3DSTENCILOP_INCR; - case SOP_DECREMENT_WRAP: + case SOP_DECREMENT_WRAP: return invert? D3DSTENCILOP_INCR : D3DSTENCILOP_DECR; - case SOP_INVERT: - return D3DSTENCILOP_INVERT; - } - return 0; - } - //--------------------------------------------------------------------- - D3DSAMPLERSTATETYPE D3D9Mappings::get(FilterType ft) + case SOP_INVERT: + return D3DSTENCILOP_INVERT; + } + return 0; + } + //--------------------------------------------------------------------- + D3DSAMPLERSTATETYPE D3D9Mappings::get(FilterType ft) { switch (ft) { @@ -354,25 +354,25 @@ namespace Ogre // to keep compiler happy return D3DSAMP_MINFILTER; } - //--------------------------------------------------------------------- - DWORD D3D9Mappings::get(FilterType ft, FilterOptions fo, const D3DCAPS9& devCaps, + //--------------------------------------------------------------------- + DWORD D3D9Mappings::get(FilterType ft, FilterOptions fo, const D3DCAPS9& devCaps, eD3DTexType texType) - { - // Assume normal - DWORD capsType = devCaps.TextureFilterCaps; + { + // Assume normal + DWORD capsType = devCaps.TextureFilterCaps; - switch( texType ) - { - case D3D_TEX_TYPE_NORMAL: - capsType = devCaps.TextureFilterCaps; - break; - case D3D_TEX_TYPE_CUBE: - capsType = devCaps.CubeTextureFilterCaps; - break; - case D3D_TEX_TYPE_VOLUME: - capsType = devCaps.VolumeTextureFilterCaps; - break; - } + switch( texType ) + { + case D3D_TEX_TYPE_NORMAL: + capsType = devCaps.TextureFilterCaps; + break; + case D3D_TEX_TYPE_CUBE: + capsType = devCaps.CubeTextureFilterCaps; + break; + case D3D_TEX_TYPE_VOLUME: + capsType = devCaps.VolumeTextureFilterCaps; + break; + } switch (ft) { @@ -446,23 +446,23 @@ namespace Ogre // should never get here return 0; - } - //--------------------------------------------------------------------- - D3D9Mappings::eD3DTexType D3D9Mappings::get(TextureType ogreTexType) - { - switch( ogreTexType ) - { - case TEX_TYPE_1D : - case TEX_TYPE_2D : - return D3D9Mappings::D3D_TEX_TYPE_NORMAL; - case TEX_TYPE_CUBE_MAP : - return D3D9Mappings::D3D_TEX_TYPE_CUBE; - case TEX_TYPE_3D : + } + //--------------------------------------------------------------------- + D3D9Mappings::eD3DTexType D3D9Mappings::get(TextureType ogreTexType) + { + switch( ogreTexType ) + { + case TEX_TYPE_1D : + case TEX_TYPE_2D : + return D3D9Mappings::D3D_TEX_TYPE_NORMAL; + case TEX_TYPE_CUBE_MAP : + return D3D9Mappings::D3D_TEX_TYPE_CUBE; + case TEX_TYPE_3D : return D3D9Mappings::D3D_TEX_TYPE_VOLUME; - } - return D3D9Mappings::D3D_TEX_TYPE_NONE; - } - //--------------------------------------------------------------------- + } + return D3D9Mappings::D3D_TEX_TYPE_NONE; + } + //--------------------------------------------------------------------- DWORD D3D9Mappings::get(HardwareBuffer::Usage usage) { DWORD ret = 0; @@ -483,7 +483,7 @@ namespace Ogre } return ret; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- DWORD D3D9Mappings::get(HardwareBuffer::LockOptions options, HardwareBuffer::Usage usage) { DWORD ret = 0; @@ -502,11 +502,11 @@ namespace Ogre } if (options == HardwareBuffer::HBL_READ_ONLY) { - // D3D debug runtime doesn't like you locking managed buffers readonly - // when they were created with write-only (even though you CAN read - // from the software backed version) - if (!(usage & HardwareBuffer::HBU_WRITE_ONLY)) - ret |= D3DLOCK_READONLY; + // D3D debug runtime doesn't like you locking managed buffers readonly + // when they were created with write-only (even though you CAN read + // from the software backed version) + if (!(usage & HardwareBuffer::HBU_WRITE_ONLY)) + ret |= D3DLOCK_READONLY; } if (options == HardwareBuffer::HBL_NO_OVERWRITE) @@ -525,7 +525,7 @@ namespace Ogre return ret; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- D3DFORMAT D3D9Mappings::get(HardwareIndexBuffer::IndexType itype) { if (itype == HardwareIndexBuffer::IT_32BIT) @@ -537,258 +537,258 @@ namespace Ogre return D3DFMT_INDEX16; } } - //--------------------------------------------------------------------- - D3DDECLTYPE D3D9Mappings::get(VertexElementType vType) - { - switch (vType) - { - case VET_COLOUR: - case VET_COLOUR_ABGR: - case VET_COLOUR_ARGB: - return D3DDECLTYPE_D3DCOLOR; - break; - case VET_FLOAT1: - return D3DDECLTYPE_FLOAT1; - break; - case VET_FLOAT2: - return D3DDECLTYPE_FLOAT2; - break; - case VET_FLOAT3: - return D3DDECLTYPE_FLOAT3; - break; - case VET_FLOAT4: - return D3DDECLTYPE_FLOAT4; - break; + //--------------------------------------------------------------------- + D3DDECLTYPE D3D9Mappings::get(VertexElementType vType) + { + switch (vType) + { + case VET_COLOUR: + case VET_COLOUR_ABGR: + case VET_COLOUR_ARGB: + return D3DDECLTYPE_D3DCOLOR; + break; + case VET_FLOAT1: + return D3DDECLTYPE_FLOAT1; + break; + case VET_FLOAT2: + return D3DDECLTYPE_FLOAT2; + break; + case VET_FLOAT3: + return D3DDECLTYPE_FLOAT3; + break; + case VET_FLOAT4: + return D3DDECLTYPE_FLOAT4; + break; case VET_SHORT2: - return D3DDECLTYPE_SHORT2; - break; + return D3DDECLTYPE_SHORT2; + break; case VET_SHORT4: - return D3DDECLTYPE_SHORT4; - break; + return D3DDECLTYPE_SHORT4; + break; case VET_UBYTE4: return D3DDECLTYPE_UBYTE4; break; - } - // to keep compiler happy - return D3DDECLTYPE_FLOAT3; - } - //--------------------------------------------------------------------- - D3DDECLUSAGE D3D9Mappings::get(VertexElementSemantic sem) - { - switch (sem) - { - case VES_BLEND_INDICES: - return D3DDECLUSAGE_BLENDINDICES; - break; - case VES_BLEND_WEIGHTS: - return D3DDECLUSAGE_BLENDWEIGHT; - break; - case VES_DIFFUSE: - return D3DDECLUSAGE_COLOR; // NB index will differentiate - break; - case VES_SPECULAR: - return D3DDECLUSAGE_COLOR; // NB index will differentiate - break; - case VES_NORMAL: - return D3DDECLUSAGE_NORMAL; - break; - case VES_POSITION: - return D3DDECLUSAGE_POSITION; - break; - case VES_TEXTURE_COORDINATES: - return D3DDECLUSAGE_TEXCOORD; - break; - case VES_BINORMAL: - return D3DDECLUSAGE_BINORMAL; - break; - case VES_TANGENT: - return D3DDECLUSAGE_TANGENT; - break; - } - // to keep compiler happy - return D3DDECLUSAGE_POSITION; - } - //--------------------------------------------------------------------- - D3DXMATRIX D3D9Mappings::makeD3DXMatrix( const Matrix4& mat ) - { - // Transpose matrix - // D3D9 uses row vectors i.e. V*M - // Ogre, OpenGL and everything else uses column vectors i.e. M*V - return D3DXMATRIX( + } + // to keep compiler happy + return D3DDECLTYPE_FLOAT3; + } + //--------------------------------------------------------------------- + D3DDECLUSAGE D3D9Mappings::get(VertexElementSemantic sem) + { + switch (sem) + { + case VES_BLEND_INDICES: + return D3DDECLUSAGE_BLENDINDICES; + break; + case VES_BLEND_WEIGHTS: + return D3DDECLUSAGE_BLENDWEIGHT; + break; + case VES_DIFFUSE: + return D3DDECLUSAGE_COLOR; // NB index will differentiate + break; + case VES_SPECULAR: + return D3DDECLUSAGE_COLOR; // NB index will differentiate + break; + case VES_NORMAL: + return D3DDECLUSAGE_NORMAL; + break; + case VES_POSITION: + return D3DDECLUSAGE_POSITION; + break; + case VES_TEXTURE_COORDINATES: + return D3DDECLUSAGE_TEXCOORD; + break; + case VES_BINORMAL: + return D3DDECLUSAGE_BINORMAL; + break; + case VES_TANGENT: + return D3DDECLUSAGE_TANGENT; + break; + } + // to keep compiler happy + return D3DDECLUSAGE_POSITION; + } + //--------------------------------------------------------------------- + D3DXMATRIX D3D9Mappings::makeD3DXMatrix( const Matrix4& mat ) + { + // Transpose matrix + // D3D9 uses row vectors i.e. V*M + // Ogre, OpenGL and everything else uses column vectors i.e. M*V + return D3DXMATRIX( mat[0][0], mat[1][0], mat[2][0], mat[3][0], mat[0][1], mat[1][1], mat[2][1], mat[3][1], mat[0][2], mat[1][2], mat[2][2], mat[3][2], mat[0][3], mat[1][3], mat[2][3], mat[3][3]); - } - //--------------------------------------------------------------------- - Matrix4 D3D9Mappings::convertD3DXMatrix( const D3DXMATRIX& mat ) - { - return Matrix4( + } + //--------------------------------------------------------------------- + Matrix4 D3D9Mappings::convertD3DXMatrix( const D3DXMATRIX& mat ) + { + return Matrix4( mat.m[0][0], mat.m[1][0], mat.m[2][0], mat.m[3][0], mat.m[0][1], mat.m[1][1], mat.m[2][1], mat.m[3][1], mat.m[0][2], mat.m[1][2], mat.m[2][2], mat.m[3][2], mat.m[0][3], mat.m[1][3], mat.m[2][3], mat.m[3][3]); - } - /****************************************************************************************/ - PixelFormat D3D9Mappings::_getPF(D3DFORMAT d3dPF) - { - switch(d3dPF) - { - case D3DFMT_A8: - return PF_A8; - case D3DFMT_L8: - return PF_L8; - case D3DFMT_L16: - return PF_L16; - case D3DFMT_A4L4: - return PF_A4L4; - case D3DFMT_A8L8: - return PF_BYTE_LA; // Assume little endian here - case D3DFMT_R3G3B2: - return PF_R3G3B2; - case D3DFMT_A1R5G5B5: - return PF_A1R5G5B5; - case D3DFMT_A4R4G4B4: - return PF_A4R4G4B4; - case D3DFMT_R5G6B5: - return PF_R5G6B5; - case D3DFMT_R8G8B8: - return PF_R8G8B8; - case D3DFMT_X8R8G8B8: - return PF_X8R8G8B8; - case D3DFMT_A8R8G8B8: - return PF_A8R8G8B8; - case D3DFMT_X8B8G8R8: - return PF_X8B8G8R8; - case D3DFMT_A8B8G8R8: - return PF_A8B8G8R8; - case D3DFMT_A2R10G10B10: - return PF_A2R10G10B10; + } + /****************************************************************************************/ + PixelFormat D3D9Mappings::_getPF(D3DFORMAT d3dPF) + { + switch(d3dPF) + { + case D3DFMT_A8: + return PF_A8; + case D3DFMT_L8: + return PF_L8; + case D3DFMT_L16: + return PF_L16; + case D3DFMT_A4L4: + return PF_A4L4; + case D3DFMT_A8L8: + return PF_BYTE_LA; // Assume little endian here + case D3DFMT_R3G3B2: + return PF_R3G3B2; + case D3DFMT_A1R5G5B5: + return PF_A1R5G5B5; + case D3DFMT_A4R4G4B4: + return PF_A4R4G4B4; + case D3DFMT_R5G6B5: + return PF_R5G6B5; + case D3DFMT_R8G8B8: + return PF_R8G8B8; + case D3DFMT_X8R8G8B8: + return PF_X8R8G8B8; + case D3DFMT_A8R8G8B8: + return PF_A8R8G8B8; + case D3DFMT_X8B8G8R8: + return PF_X8B8G8R8; + case D3DFMT_A8B8G8R8: + return PF_A8B8G8R8; + case D3DFMT_A2R10G10B10: + return PF_A2R10G10B10; case D3DFMT_A2B10G10R10: return PF_A2B10G10R10; - case D3DFMT_R16F: - return PF_FLOAT16_R; - case D3DFMT_A16B16G16R16F: - return PF_FLOAT16_RGBA; - case D3DFMT_R32F: - return PF_FLOAT32_R; - case D3DFMT_G32R32F: - return PF_FLOAT32_GR; - case D3DFMT_A32B32G32R32F: - return PF_FLOAT32_RGBA; - case D3DFMT_G16R16F: - return PF_FLOAT16_GR; - case D3DFMT_A16B16G16R16: - return PF_SHORT_RGBA; - case D3DFMT_G16R16: - return PF_SHORT_GR; - case D3DFMT_DXT1: - return PF_DXT1; - case D3DFMT_DXT2: - return PF_DXT2; - case D3DFMT_DXT3: - return PF_DXT3; - case D3DFMT_DXT4: - return PF_DXT4; - case D3DFMT_DXT5: - return PF_DXT5; - default: - return PF_UNKNOWN; - } - } - /****************************************************************************************/ - D3DFORMAT D3D9Mappings::_getPF(PixelFormat ogrePF) - { - switch(ogrePF) - { - case PF_L8: - return D3DFMT_L8; - case PF_L16: - return D3DFMT_L16; - case PF_A8: - return D3DFMT_A8; - case PF_A4L4: - return D3DFMT_A4L4; - case PF_BYTE_LA: - return D3DFMT_A8L8; // Assume little endian here - case PF_R3G3B2: - return D3DFMT_R3G3B2; - case PF_A1R5G5B5: - return D3DFMT_A1R5G5B5; - case PF_R5G6B5: - return D3DFMT_R5G6B5; - case PF_A4R4G4B4: - return D3DFMT_A4R4G4B4; - case PF_R8G8B8: - return D3DFMT_R8G8B8; - case PF_A8R8G8B8: - return D3DFMT_A8R8G8B8; - case PF_A8B8G8R8: - return D3DFMT_A8B8G8R8; - case PF_X8R8G8B8: - return D3DFMT_X8R8G8B8; - case PF_X8B8G8R8: - return D3DFMT_X8B8G8R8; - case PF_A2B10G10R10: + case D3DFMT_R16F: + return PF_FLOAT16_R; + case D3DFMT_A16B16G16R16F: + return PF_FLOAT16_RGBA; + case D3DFMT_R32F: + return PF_FLOAT32_R; + case D3DFMT_G32R32F: + return PF_FLOAT32_GR; + case D3DFMT_A32B32G32R32F: + return PF_FLOAT32_RGBA; + case D3DFMT_G16R16F: + return PF_FLOAT16_GR; + case D3DFMT_A16B16G16R16: + return PF_SHORT_RGBA; + case D3DFMT_G16R16: + return PF_SHORT_GR; + case D3DFMT_DXT1: + return PF_DXT1; + case D3DFMT_DXT2: + return PF_DXT2; + case D3DFMT_DXT3: + return PF_DXT3; + case D3DFMT_DXT4: + return PF_DXT4; + case D3DFMT_DXT5: + return PF_DXT5; + default: + return PF_UNKNOWN; + } + } + /****************************************************************************************/ + D3DFORMAT D3D9Mappings::_getPF(PixelFormat ogrePF) + { + switch(ogrePF) + { + case PF_L8: + return D3DFMT_L8; + case PF_L16: + return D3DFMT_L16; + case PF_A8: + return D3DFMT_A8; + case PF_A4L4: + return D3DFMT_A4L4; + case PF_BYTE_LA: + return D3DFMT_A8L8; // Assume little endian here + case PF_R3G3B2: + return D3DFMT_R3G3B2; + case PF_A1R5G5B5: + return D3DFMT_A1R5G5B5; + case PF_R5G6B5: + return D3DFMT_R5G6B5; + case PF_A4R4G4B4: + return D3DFMT_A4R4G4B4; + case PF_R8G8B8: + return D3DFMT_R8G8B8; + case PF_A8R8G8B8: + return D3DFMT_A8R8G8B8; + case PF_A8B8G8R8: + return D3DFMT_A8B8G8R8; + case PF_X8R8G8B8: + return D3DFMT_X8R8G8B8; + case PF_X8B8G8R8: + return D3DFMT_X8B8G8R8; + case PF_A2B10G10R10: return D3DFMT_A2B10G10R10; - case PF_A2R10G10B10: - return D3DFMT_A2R10G10B10; - case PF_FLOAT16_R: - return D3DFMT_R16F; - case PF_FLOAT16_GR: - return D3DFMT_G16R16F; - case PF_FLOAT16_RGBA: - return D3DFMT_A16B16G16R16F; - case PF_FLOAT32_R: - return D3DFMT_R32F; - case PF_FLOAT32_GR: - return D3DFMT_G32R32F; - case PF_FLOAT32_RGBA: - return D3DFMT_A32B32G32R32F; - case PF_SHORT_RGBA: - return D3DFMT_A16B16G16R16; - case PF_SHORT_GR: - return D3DFMT_G16R16; - case PF_DXT1: - return D3DFMT_DXT1; - case PF_DXT2: - return D3DFMT_DXT2; - case PF_DXT3: - return D3DFMT_DXT3; - case PF_DXT4: - return D3DFMT_DXT4; - case PF_DXT5: - return D3DFMT_DXT5; - case PF_UNKNOWN: - default: - return D3DFMT_UNKNOWN; - } - } - /****************************************************************************************/ - PixelFormat D3D9Mappings::_getClosestSupportedPF(PixelFormat ogrePF) - { - if (_getPF(ogrePF) != D3DFMT_UNKNOWN) - { - return ogrePF; - } - switch(ogrePF) - { - case PF_B5G6R5: - return PF_R5G6B5; - case PF_B8G8R8: - return PF_R8G8B8; - case PF_B8G8R8A8: - return PF_A8R8G8B8; + case PF_A2R10G10B10: + return D3DFMT_A2R10G10B10; + case PF_FLOAT16_R: + return D3DFMT_R16F; + case PF_FLOAT16_GR: + return D3DFMT_G16R16F; + case PF_FLOAT16_RGBA: + return D3DFMT_A16B16G16R16F; + case PF_FLOAT32_R: + return D3DFMT_R32F; + case PF_FLOAT32_GR: + return D3DFMT_G32R32F; + case PF_FLOAT32_RGBA: + return D3DFMT_A32B32G32R32F; + case PF_SHORT_RGBA: + return D3DFMT_A16B16G16R16; + case PF_SHORT_GR: + return D3DFMT_G16R16; + case PF_DXT1: + return D3DFMT_DXT1; + case PF_DXT2: + return D3DFMT_DXT2; + case PF_DXT3: + return D3DFMT_DXT3; + case PF_DXT4: + return D3DFMT_DXT4; + case PF_DXT5: + return D3DFMT_DXT5; + case PF_UNKNOWN: + default: + return D3DFMT_UNKNOWN; + } + } + /****************************************************************************************/ + PixelFormat D3D9Mappings::_getClosestSupportedPF(PixelFormat ogrePF) + { + if (_getPF(ogrePF) != D3DFMT_UNKNOWN) + { + return ogrePF; + } + switch(ogrePF) + { + case PF_B5G6R5: + return PF_R5G6B5; + case PF_B8G8R8: + return PF_R8G8B8; + case PF_B8G8R8A8: + return PF_A8R8G8B8; case PF_SHORT_RGB: return PF_SHORT_RGBA; - case PF_FLOAT16_RGB: - return PF_FLOAT16_RGBA; - case PF_FLOAT32_RGB: - return PF_FLOAT32_RGBA; - case PF_UNKNOWN: - default: - return PF_A8R8G8B8; - } - } + case PF_FLOAT16_RGB: + return PF_FLOAT16_RGBA; + case PF_FLOAT32_RGB: + return PF_FLOAT32_RGBA; + case PF_UNKNOWN: + default: + return PF_A8R8G8B8; + } + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9MultiRenderTarget.cpp b/RenderSystems/Direct3D9/src/OgreD3D9MultiRenderTarget.cpp index 2fe53f4c5f8..42647b6325f 100755 --- a/RenderSystems/Direct3D9/src/OgreD3D9MultiRenderTarget.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9MultiRenderTarget.cpp @@ -38,119 +38,119 @@ THE SOFTWARE. namespace Ogre { - D3D9MultiRenderTarget::D3D9MultiRenderTarget(const String &name): - MultiRenderTarget(name) - { - /// Clear targets - for(size_t x=0; xgetCustomAttribute("BUFFER", &buffer); - assert(buffer); - - /// Find first non-null target - int y; - for(y=0; ygetWidth() != buffer->getWidth() || - mRenderTargets[y]->getHeight() != buffer->getHeight()) - { - OGRE_EXCEPT( - Exception::ERR_INVALIDPARAMS, - "MultiRenderTarget surfaces are not of same size", - "D3D9MultiRenderTarget::bindSurface"); - } - - if (!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS) - && (PixelUtil::getNumElemBits(mRenderTargets[y]->getFormat()) != - PixelUtil::getNumElemBits(buffer->getFormat()))) - { - OGRE_EXCEPT( - Exception::ERR_INVALIDPARAMS, - "MultiRenderTarget surfaces are not of same bit depth and hardware requires it", - "D3D9MultiRenderTarget::bindSurface" - ); - } - } - - mRenderTargets[attachment] = buffer; - checkAndUpdate(); - } - - void D3D9MultiRenderTarget::unbindSurfaceImpl(size_t attachment) - { - assert(attachmentgetCustomAttribute("BUFFER", &buffer); + assert(buffer); + + /// Find first non-null target + int y; + for(y=0; ygetWidth() != buffer->getWidth() || + mRenderTargets[y]->getHeight() != buffer->getHeight()) + { + OGRE_EXCEPT( + Exception::ERR_INVALIDPARAMS, + "MultiRenderTarget surfaces are not of same size", + "D3D9MultiRenderTarget::bindSurface"); + } + + if (!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS) + && (PixelUtil::getNumElemBits(mRenderTargets[y]->getFormat()) != + PixelUtil::getNumElemBits(buffer->getFormat()))) + { + OGRE_EXCEPT( + Exception::ERR_INVALIDPARAMS, + "MultiRenderTarget surfaces are not of same bit depth and hardware requires it", + "D3D9MultiRenderTarget::bindSurface" + ); + } + } + + mRenderTargets[attachment] = buffer; + checkAndUpdate(); + } + + void D3D9MultiRenderTarget::unbindSurfaceImpl(size_t attachment) + { + assert(attachmentgetActiveRenderTargetDevice(); - - if (currRenderWindowDevice != NULL) - { - if (currRenderWindowDevice->isDeviceLost() == false) - MultiRenderTarget::update(swapBuffers); - } - else - { - for (UINT i=0; i < deviceManager->getDeviceCount(); ++i) - { - D3D9Device* device = deviceManager->getDevice(i); - - if (device->isDeviceLost() == false) - { - deviceManager->setActiveRenderTargetDevice(device); - MultiRenderTarget::update(swapBuffers); - deviceManager->setActiveRenderTargetDevice(NULL); - } - } - } + D3D9DeviceManager* deviceManager = D3D9RenderSystem::getDeviceManager(); + D3D9Device* currRenderWindowDevice = deviceManager->getActiveRenderTargetDevice(); + + if (currRenderWindowDevice != NULL) + { + if (currRenderWindowDevice->isDeviceLost() == false) + MultiRenderTarget::update(swapBuffers); + } + else + { + for (UINT i=0; i < deviceManager->getDeviceCount(); ++i) + { + D3D9Device* device = deviceManager->getDevice(i); + + if (device->isDeviceLost() == false) + { + deviceManager->setActiveRenderTargetDevice(device); + MultiRenderTarget::update(swapBuffers); + deviceManager->setActiveRenderTargetDevice(NULL); + } + } + } } - void D3D9MultiRenderTarget::getCustomAttribute(const String& name, void *pData) + void D3D9MultiRenderTarget::getCustomAttribute(const String& name, void *pData) { - if(name == "DDBACKBUFFER") + if(name == "DDBACKBUFFER") { IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData; - /// Transfer surfaces - for(size_t x=0; xgetSurface(D3D9RenderSystem::getActiveD3D9Device()); - } - return; + /// Transfer surfaces + for(size_t x=0; xgetSurface(D3D9RenderSystem::getActiveD3D9Device()); + } + return; } - } - - void D3D9MultiRenderTarget::checkAndUpdate() - { - if(mRenderTargets[0]) - { - mWidth = (unsigned int)mRenderTargets[0]->getWidth(); - mHeight = (unsigned int)mRenderTargets[0]->getHeight(); - } - else - { - mWidth = 0; - mHeight = 0; - } - } + } + + void D3D9MultiRenderTarget::checkAndUpdate() + { + if(mRenderTargets[0]) + { + mWidth = (unsigned int)mRenderTargets[0]->getWidth(); + mHeight = (unsigned int)mRenderTargets[0]->getHeight(); + } + else + { + mWidth = 0; + mHeight = 0; + } + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9Plugin.cpp b/RenderSystems/Direct3D9/src/OgreD3D9Plugin.cpp index faf68743e71..cd8c2dfa261 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9Plugin.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9Plugin.cpp @@ -34,68 +34,68 @@ extern "C" { #include "WIN32/OgreMinGWSupport.h" void _chkstk(); void _fastcall __security_check_cookie(intptr_t i); -} +} #endif namespace Ogre { - const String sPluginName = "D3D9 RenderSystem"; - //--------------------------------------------------------------------- - D3D9Plugin::D3D9Plugin() - : mRenderSystem(0) - { + const String sPluginName = "D3D9 RenderSystem"; + //--------------------------------------------------------------------- + D3D9Plugin::D3D9Plugin() + : mRenderSystem(0) + { - } - //--------------------------------------------------------------------- - const String& D3D9Plugin::getName() const - { - return sPluginName; - } - - //--------------------------------------------------------------------- - void D3D9Plugin::install() - { - // When building with MinGW, we need to call dummy implementations - // of missing MinGW DirectX functions to make sure they are carried over - // in dynamic AND static builds + } + //--------------------------------------------------------------------- + const String& D3D9Plugin::getName() const + { + return sPluginName; + } + + //--------------------------------------------------------------------- + void D3D9Plugin::install() + { + // When building with MinGW, we need to call dummy implementations + // of missing MinGW DirectX functions to make sure they are carried over + // in dynamic AND static builds #ifdef __MINGW32__ _chkstk(); __security_check_cookie((intptr_t)NULL); #endif - // Create the DirectX 9 rendering api + // Create the DirectX 9 rendering api #ifdef OGRE_STATIC_LIB - HINSTANCE hInst = GetModuleHandle( NULL ); + HINSTANCE hInst = GetModuleHandle( NULL ); #else # if OGRE_DEBUG_MODE == 1 - HINSTANCE hInst = GetModuleHandle( "RenderSystem_Direct3D9_d.dll" ); + HINSTANCE hInst = GetModuleHandle( "RenderSystem_Direct3D9_d.dll" ); # else - HINSTANCE hInst = GetModuleHandle( "RenderSystem_Direct3D9.dll" ); + HINSTANCE hInst = GetModuleHandle( "RenderSystem_Direct3D9.dll" ); # endif #endif - mRenderSystem = OGRE_NEW D3D9RenderSystem( hInst ); - // Register the render system - Root::getSingleton().addRenderSystem( mRenderSystem ); - } - //--------------------------------------------------------------------- - void D3D9Plugin::initialise() - { - // nothing to do - } - //--------------------------------------------------------------------- - void D3D9Plugin::shutdown() - { - // nothing to do - } - //--------------------------------------------------------------------- - void D3D9Plugin::uninstall() - { - if (mRenderSystem != NULL) - { - OGRE_DELETE mRenderSystem; - mRenderSystem = NULL; - } - } + mRenderSystem = OGRE_NEW D3D9RenderSystem( hInst ); + // Register the render system + Root::getSingleton().addRenderSystem( mRenderSystem ); + } + //--------------------------------------------------------------------- + void D3D9Plugin::initialise() + { + // nothing to do + } + //--------------------------------------------------------------------- + void D3D9Plugin::shutdown() + { + // nothing to do + } + //--------------------------------------------------------------------- + void D3D9Plugin::uninstall() + { + if (mRenderSystem != NULL) + { + OGRE_DELETE mRenderSystem; + mRenderSystem = NULL; + } + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9RenderSystem.cpp b/RenderSystems/Direct3D9/src/OgreD3D9RenderSystem.cpp index f8fd70a1823..934aef4fdda 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9RenderSystem.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9RenderSystem.cpp @@ -58,641 +58,641 @@ THE SOFTWARE. namespace Ogre { - D3D9RenderSystem* D3D9RenderSystem::msD3D9RenderSystem = NULL; - - //--------------------------------------------------------------------- - D3D9RenderSystem::D3D9RenderSystem( HINSTANCE hInstance ) : - mMultiheadUse(mutAuto), - mAllowDirectX9Ex(false), - mIsDirectX9Ex(false) - { - LogManager::getSingleton().logMessage( "D3D9 : " + getName() + " created." ); - - // update singleton access pointer. - msD3D9RenderSystem = this; - - // set the instance being passed - mhInstance = hInstance; - - // set pointers to NULL - mD3D = NULL; - mDriverList = NULL; - mActiveD3DDriver = NULL; - mTextureManager = NULL; - mHardwareBufferManager = NULL; - mGpuProgramManager = NULL; - mUseNVPerfHUD = false; - mHLSLProgramFactory = NULL; - mDeviceManager = NULL; - mPerStageConstantSupport = false; - - // Create the resource manager. - mResourceManager = OGRE_NEW D3D9ResourceManager(); - - - // init lights - for(int i = 0; i < MAX_LIGHTS; i++ ) - mLights[i] = 0; - - // Create our Direct3D object - if( NULL == (mD3D = Direct3DCreate9(D3D_SDK_VERSION)) ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Failed to create Direct3D9 object", "D3D9RenderSystem::D3D9RenderSystem" ); - - // set config options defaults - initConfigOptions(); - - // fsaa options - mFSAAHint = ""; - mFSAASamples = 0; - - // set stages desc. to defaults - for (size_t n = 0; n < OGRE_MAX_TEXTURE_LAYERS; n++) - { - mTexStageDesc[n].autoTexCoordType = TEXCALC_NONE; - mTexStageDesc[n].coordIndex = 0; - mTexStageDesc[n].texType = D3D9Mappings::D3D_TEX_TYPE_NORMAL; - mTexStageDesc[n].pTex = 0; - mTexStageDesc[n].pVertexTex = 0; - } - - mLastVertexSourceCount = 0; - - mCurrentLights.clear(); - - // Enumerate events - mEventNames.push_back("DeviceLost"); - mEventNames.push_back("DeviceRestored"); - } - //--------------------------------------------------------------------- - D3D9RenderSystem::~D3D9RenderSystem() - { - shutdown(); - - // Deleting the HLSL program factory - if (mHLSLProgramFactory) - { - // Remove from manager safely - if (HighLevelGpuProgramManager::getSingletonPtr()) - HighLevelGpuProgramManager::getSingleton().removeFactory(mHLSLProgramFactory); - OGRE_DELETE mHLSLProgramFactory; - mHLSLProgramFactory = 0; - } - - SAFE_RELEASE( mD3D ); - - if (mResourceManager != NULL) - { - OGRE_DELETE mResourceManager; - mResourceManager = NULL; - } - - LogManager::getSingleton().logMessage( "D3D9 : " + getName() + " destroyed." ); - - msD3D9RenderSystem = NULL; - } - //--------------------------------------------------------------------- - const String& D3D9RenderSystem::getName() const - { - static String strName( "Direct3D9 Rendering Subsystem"); - return strName; - } - //--------------------------------------------------------------------- - D3D9DriverList* D3D9RenderSystem::getDirect3DDrivers() - { - if( !mDriverList ) - mDriverList = OGRE_NEW D3D9DriverList(); - - return mDriverList; - } - //--------------------------------------------------------------------- - bool D3D9RenderSystem::_checkMultiSampleQuality(D3DMULTISAMPLE_TYPE type, DWORD *outQuality, D3DFORMAT format, UINT adapterNum, D3DDEVTYPE deviceType, BOOL fullScreen) - { - HRESULT hr; - hr = mD3D->CheckDeviceMultiSampleType( - adapterNum, - deviceType, - format, - fullScreen, - type, - outQuality); - - if (SUCCEEDED(hr)) - return true; - else - return false; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::initConfigOptions() - { - D3D9DriverList* driverList; - D3D9Driver* driver; - - ConfigOption optDevice; - ConfigOption optAllowDirectX9Ex; - ConfigOption optVideoMode; - ConfigOption optFullScreen; - ConfigOption optMultihead; - ConfigOption optVSync; - ConfigOption optVSyncInterval; - ConfigOption optAA; - ConfigOption optFPUMode; - ConfigOption optNVPerfHUD; - ConfigOption optSRGB; - ConfigOption optResourceCeationPolicy; - ConfigOption optMultiDeviceMemHint; - ConfigOption optEnableFixedPipeline; - - driverList = this->getDirect3DDrivers(); - - optDevice.name = "Rendering Device"; - optDevice.currentValue.clear(); - optDevice.possibleValues.clear(); - optDevice.immutable = false; - - optAllowDirectX9Ex.name = "Allow DirectX9Ex"; - optAllowDirectX9Ex.possibleValues.push_back( "Yes" ); - optAllowDirectX9Ex.possibleValues.push_back( "No" ); - optAllowDirectX9Ex.currentValue = "No"; - optAllowDirectX9Ex.immutable = false; - - optVideoMode.name = "Video Mode"; - optVideoMode.currentValue = "800 x 600 @ 32-bit colour"; - optVideoMode.immutable = false; - - optFullScreen.name = "Full Screen"; - optFullScreen.possibleValues.push_back( "Yes" ); - optFullScreen.possibleValues.push_back( "No" ); - optFullScreen.currentValue = "Yes"; - optFullScreen.immutable = false; - - optMultihead.name = "Use Multihead"; - optMultihead.possibleValues.push_back( "Auto" ); - optMultihead.possibleValues.push_back( "Yes" ); - optMultihead.possibleValues.push_back( "No" ); - optMultihead.currentValue = "Auto"; - optMultihead.immutable = false; - - optResourceCeationPolicy.name = "Resource Creation Policy"; - optResourceCeationPolicy.possibleValues.push_back( "Create on all devices" ); - optResourceCeationPolicy.possibleValues.push_back( "Create on active device" ); - - if (mResourceManager->getCreationPolicy() == RCP_CREATE_ON_ACTIVE_DEVICE) - optResourceCeationPolicy.currentValue = "Create on active device"; - else if (mResourceManager->getCreationPolicy() == RCP_CREATE_ON_ALL_DEVICES) - optResourceCeationPolicy.currentValue = "Create on all devices"; - else - optResourceCeationPolicy.currentValue = "N/A"; - optResourceCeationPolicy.immutable = false; - - for( unsigned j=0; j < driverList->count(); j++ ) - { - driver = driverList->item(j); - optDevice.possibleValues.push_back( driver->DriverDescription() ); - // Make first one default - if( j==0 ) - optDevice.currentValue = driver->DriverDescription(); - } - - optVSync.name = "VSync"; - optVSync.immutable = false; - optVSync.possibleValues.push_back( "Yes" ); - optVSync.possibleValues.push_back( "No" ); - optVSync.currentValue = "No"; - - optVSyncInterval.name = "VSync Interval"; - optVSyncInterval.immutable = false; - optVSyncInterval.possibleValues.push_back( "1" ); - optVSyncInterval.possibleValues.push_back( "2" ); - optVSyncInterval.possibleValues.push_back( "3" ); - optVSyncInterval.possibleValues.push_back( "4" ); - optVSyncInterval.currentValue = "1"; - - optAA.name = "FSAA"; - optAA.immutable = false; - optAA.possibleValues.push_back( "None" ); - optAA.currentValue = "None"; - - optFPUMode.name = "Floating-point mode"; + D3D9RenderSystem* D3D9RenderSystem::msD3D9RenderSystem = NULL; + + //--------------------------------------------------------------------- + D3D9RenderSystem::D3D9RenderSystem( HINSTANCE hInstance ) : + mMultiheadUse(mutAuto), + mAllowDirectX9Ex(false), + mIsDirectX9Ex(false) + { + LogManager::getSingleton().logMessage( "D3D9 : " + getName() + " created." ); + + // update singleton access pointer. + msD3D9RenderSystem = this; + + // set the instance being passed + mhInstance = hInstance; + + // set pointers to NULL + mD3D = NULL; + mDriverList = NULL; + mActiveD3DDriver = NULL; + mTextureManager = NULL; + mHardwareBufferManager = NULL; + mGpuProgramManager = NULL; + mUseNVPerfHUD = false; + mHLSLProgramFactory = NULL; + mDeviceManager = NULL; + mPerStageConstantSupport = false; + + // Create the resource manager. + mResourceManager = OGRE_NEW D3D9ResourceManager(); + + + // init lights + for(int i = 0; i < MAX_LIGHTS; i++ ) + mLights[i] = 0; + + // Create our Direct3D object + if( NULL == (mD3D = Direct3DCreate9(D3D_SDK_VERSION)) ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Failed to create Direct3D9 object", "D3D9RenderSystem::D3D9RenderSystem" ); + + // set config options defaults + initConfigOptions(); + + // fsaa options + mFSAAHint = ""; + mFSAASamples = 0; + + // set stages desc. to defaults + for (size_t n = 0; n < OGRE_MAX_TEXTURE_LAYERS; n++) + { + mTexStageDesc[n].autoTexCoordType = TEXCALC_NONE; + mTexStageDesc[n].coordIndex = 0; + mTexStageDesc[n].texType = D3D9Mappings::D3D_TEX_TYPE_NORMAL; + mTexStageDesc[n].pTex = 0; + mTexStageDesc[n].pVertexTex = 0; + } + + mLastVertexSourceCount = 0; + + mCurrentLights.clear(); + + // Enumerate events + mEventNames.push_back("DeviceLost"); + mEventNames.push_back("DeviceRestored"); + } + //--------------------------------------------------------------------- + D3D9RenderSystem::~D3D9RenderSystem() + { + shutdown(); + + // Deleting the HLSL program factory + if (mHLSLProgramFactory) + { + // Remove from manager safely + if (HighLevelGpuProgramManager::getSingletonPtr()) + HighLevelGpuProgramManager::getSingleton().removeFactory(mHLSLProgramFactory); + OGRE_DELETE mHLSLProgramFactory; + mHLSLProgramFactory = 0; + } + + SAFE_RELEASE( mD3D ); + + if (mResourceManager != NULL) + { + OGRE_DELETE mResourceManager; + mResourceManager = NULL; + } + + LogManager::getSingleton().logMessage( "D3D9 : " + getName() + " destroyed." ); + + msD3D9RenderSystem = NULL; + } + //--------------------------------------------------------------------- + const String& D3D9RenderSystem::getName() const + { + static String strName( "Direct3D9 Rendering Subsystem"); + return strName; + } + //--------------------------------------------------------------------- + D3D9DriverList* D3D9RenderSystem::getDirect3DDrivers() + { + if( !mDriverList ) + mDriverList = OGRE_NEW D3D9DriverList(); + + return mDriverList; + } + //--------------------------------------------------------------------- + bool D3D9RenderSystem::_checkMultiSampleQuality(D3DMULTISAMPLE_TYPE type, DWORD *outQuality, D3DFORMAT format, UINT adapterNum, D3DDEVTYPE deviceType, BOOL fullScreen) + { + HRESULT hr; + hr = mD3D->CheckDeviceMultiSampleType( + adapterNum, + deviceType, + format, + fullScreen, + type, + outQuality); + + if (SUCCEEDED(hr)) + return true; + else + return false; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::initConfigOptions() + { + D3D9DriverList* driverList; + D3D9Driver* driver; + + ConfigOption optDevice; + ConfigOption optAllowDirectX9Ex; + ConfigOption optVideoMode; + ConfigOption optFullScreen; + ConfigOption optMultihead; + ConfigOption optVSync; + ConfigOption optVSyncInterval; + ConfigOption optAA; + ConfigOption optFPUMode; + ConfigOption optNVPerfHUD; + ConfigOption optSRGB; + ConfigOption optResourceCeationPolicy; + ConfigOption optMultiDeviceMemHint; + ConfigOption optEnableFixedPipeline; + + driverList = this->getDirect3DDrivers(); + + optDevice.name = "Rendering Device"; + optDevice.currentValue.clear(); + optDevice.possibleValues.clear(); + optDevice.immutable = false; + + optAllowDirectX9Ex.name = "Allow DirectX9Ex"; + optAllowDirectX9Ex.possibleValues.push_back( "Yes" ); + optAllowDirectX9Ex.possibleValues.push_back( "No" ); + optAllowDirectX9Ex.currentValue = "No"; + optAllowDirectX9Ex.immutable = false; + + optVideoMode.name = "Video Mode"; + optVideoMode.currentValue = "800 x 600 @ 32-bit colour"; + optVideoMode.immutable = false; + + optFullScreen.name = "Full Screen"; + optFullScreen.possibleValues.push_back( "Yes" ); + optFullScreen.possibleValues.push_back( "No" ); + optFullScreen.currentValue = "Yes"; + optFullScreen.immutable = false; + + optMultihead.name = "Use Multihead"; + optMultihead.possibleValues.push_back( "Auto" ); + optMultihead.possibleValues.push_back( "Yes" ); + optMultihead.possibleValues.push_back( "No" ); + optMultihead.currentValue = "Auto"; + optMultihead.immutable = false; + + optResourceCeationPolicy.name = "Resource Creation Policy"; + optResourceCeationPolicy.possibleValues.push_back( "Create on all devices" ); + optResourceCeationPolicy.possibleValues.push_back( "Create on active device" ); + + if (mResourceManager->getCreationPolicy() == RCP_CREATE_ON_ACTIVE_DEVICE) + optResourceCeationPolicy.currentValue = "Create on active device"; + else if (mResourceManager->getCreationPolicy() == RCP_CREATE_ON_ALL_DEVICES) + optResourceCeationPolicy.currentValue = "Create on all devices"; + else + optResourceCeationPolicy.currentValue = "N/A"; + optResourceCeationPolicy.immutable = false; + + for( unsigned j=0; j < driverList->count(); j++ ) + { + driver = driverList->item(j); + optDevice.possibleValues.push_back( driver->DriverDescription() ); + // Make first one default + if( j==0 ) + optDevice.currentValue = driver->DriverDescription(); + } + + optVSync.name = "VSync"; + optVSync.immutable = false; + optVSync.possibleValues.push_back( "Yes" ); + optVSync.possibleValues.push_back( "No" ); + optVSync.currentValue = "No"; + + optVSyncInterval.name = "VSync Interval"; + optVSyncInterval.immutable = false; + optVSyncInterval.possibleValues.push_back( "1" ); + optVSyncInterval.possibleValues.push_back( "2" ); + optVSyncInterval.possibleValues.push_back( "3" ); + optVSyncInterval.possibleValues.push_back( "4" ); + optVSyncInterval.currentValue = "1"; + + optAA.name = "FSAA"; + optAA.immutable = false; + optAA.possibleValues.push_back( "None" ); + optAA.currentValue = "None"; + + optFPUMode.name = "Floating-point mode"; #if OGRE_DOUBLE_PRECISION - optFPUMode.currentValue = "Consistent"; + optFPUMode.currentValue = "Consistent"; #else - optFPUMode.currentValue = "Fastest"; + optFPUMode.currentValue = "Fastest"; #endif - optFPUMode.possibleValues.clear(); - optFPUMode.possibleValues.push_back("Fastest"); - optFPUMode.possibleValues.push_back("Consistent"); - optFPUMode.immutable = false; - - optNVPerfHUD.currentValue = "No"; - optNVPerfHUD.immutable = false; - optNVPerfHUD.name = "Allow NVPerfHUD"; - optNVPerfHUD.possibleValues.push_back( "Yes" ); - optNVPerfHUD.possibleValues.push_back( "No" ); - - - // SRGB on auto window - optSRGB.name = "sRGB Gamma Conversion"; - optSRGB.possibleValues.push_back("Yes"); - optSRGB.possibleValues.push_back("No"); - optSRGB.currentValue = "No"; - optSRGB.immutable = false; - - // Multiple device memory usage hint. - optMultiDeviceMemHint.name = "Multi device memory hint"; - optMultiDeviceMemHint.possibleValues.push_back("Use minimum system memory"); - optMultiDeviceMemHint.possibleValues.push_back("Auto hardware buffers management"); - optMultiDeviceMemHint.currentValue = "Use minimum system memory"; - optMultiDeviceMemHint.immutable = false; - - optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; - optEnableFixedPipeline.possibleValues.push_back( "Yes" ); - optEnableFixedPipeline.possibleValues.push_back( "No" ); - optEnableFixedPipeline.currentValue = "Yes"; - optEnableFixedPipeline.immutable = false; - - mOptions[optDevice.name] = optDevice; - mOptions[optAllowDirectX9Ex.name] = optAllowDirectX9Ex; - mOptions[optVideoMode.name] = optVideoMode; - mOptions[optFullScreen.name] = optFullScreen; - mOptions[optMultihead.name] = optMultihead; - mOptions[optVSync.name] = optVSync; - mOptions[optVSyncInterval.name] = optVSyncInterval; - mOptions[optAA.name] = optAA; - mOptions[optFPUMode.name] = optFPUMode; - mOptions[optNVPerfHUD.name] = optNVPerfHUD; - mOptions[optSRGB.name] = optSRGB; - mOptions[optResourceCeationPolicy.name] = optResourceCeationPolicy; - mOptions[optMultiDeviceMemHint.name] = optMultiDeviceMemHint; - mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; - - refreshD3DSettings(); - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::refreshD3DSettings() - { - ConfigOption* optVideoMode; - D3D9Driver* driver = 0; - D3D9VideoMode* videoMode; - - ConfigOptionMap::iterator opt = mOptions.find( "Rendering Device" ); - if( opt != mOptions.end() ) - { - for( unsigned j=0; j < getDirect3DDrivers()->count(); j++ ) - { - D3D9Driver* curDriver = getDirect3DDrivers()->item(j); - if( curDriver->DriverDescription() == opt->second.currentValue ) - { - driver = curDriver; - break; - } - } - - if (driver) - { - opt = mOptions.find( "Video Mode" ); - optVideoMode = &opt->second; - optVideoMode->possibleValues.clear(); - // get vide modes for this device - for( unsigned k=0; k < driver->getVideoModeList()->count(); k++ ) - { - videoMode = driver->getVideoModeList()->item( k ); - optVideoMode->possibleValues.push_back( videoMode->getDescription() ); - } - - // Reset video mode to default if previous doesn't avail in new possible values - StringVector::const_iterator itValue = - std::find(optVideoMode->possibleValues.begin(), - optVideoMode->possibleValues.end(), - optVideoMode->currentValue); - if (itValue == optVideoMode->possibleValues.end()) - { - optVideoMode->currentValue = "800 x 600 @ 32-bit colour"; - } - - // Also refresh FSAA options - refreshFSAAOptions(); - } - } - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setConfigOption( const String &name, const String &value ) - { - - LogManager::getSingleton().stream() - << "D3D9 : RenderSystem Option: " << name << " = " << value; - - bool viewModeChanged = false; - - // Find option - ConfigOptionMap::iterator it = mOptions.find( name ); - - // Update - if( it != mOptions.end() ) - it->second.currentValue = value; - else - { - StringStream str; - str << "Option named '" << name << "' does not exist."; - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, str.str(), "D3D9RenderSystem::setConfigOption" ); - } - - // Refresh other options if D3DDriver changed - if( name == "Rendering Device" ) - refreshD3DSettings(); - - if ( name == "Allow DirectX9Ex" ) - { - if (value == "Yes") - mAllowDirectX9Ex = true; - else mAllowDirectX9Ex = false; - - // Create our Direct3D object - if (mAllowDirectX9Ex && !mIsDirectX9Ex) - { - SAFE_RELEASE(mD3D); - HMODULE hD3D = LoadLibrary(TEXT("d3d9.dll")); - if (hD3D) - { - typedef HRESULT (WINAPI *DIRECT3DCREATE9EXFUNCTION)(UINT, IDirect3D9Ex**); - DIRECT3DCREATE9EXFUNCTION pfnCreate9Ex = (DIRECT3DCREATE9EXFUNCTION)GetProcAddress(hD3D, "Direct3DCreate9Ex"); - if (pfnCreate9Ex) - { - IDirect3D9Ex* d3dEx = NULL; - (*pfnCreate9Ex)(D3D_SDK_VERSION, &d3dEx); - d3dEx->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast(&mD3D)); - mIsDirectX9Ex = true; - } - FreeLibrary(hD3D); - } - } - if ((mD3D == NULL) || (!mAllowDirectX9Ex && mIsDirectX9Ex)) - { - if ( NULL == (mD3D = Direct3DCreate9(D3D_SDK_VERSION)) ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Failed to create Direct3D9 object", "D3D9RenderSystem::D3D9RenderSystem" ); - } - } - - if( name == "Full Screen" ) - { - // Video mode is applicable - it = mOptions.find( "Video Mode" ); - if (it->second.currentValue.empty()) - { - it->second.currentValue = "800 x 600 @ 32-bit colour"; - viewModeChanged = true; - } - } - - if( name == "Use Multihead" ) - { - if (value == "Yes") - mMultiheadUse = mutYes; - else if (value == "No") - mMultiheadUse = mutNo; - else mMultiheadUse = mutAuto; - } - - if( name == "FSAA" ) - { - StringVector values = StringUtil::split(value, " ", 1); - mFSAASamples = StringConverter::parseUnsignedInt(values[0]); - if (values.size() > 1) - mFSAAHint = values[1]; - - } - - if( name == "Allow NVPerfHUD" ) - { - if (value == "Yes") - mUseNVPerfHUD = true; - else - mUseNVPerfHUD = false; - } - - if (viewModeChanged || name == "Video Mode") - { - refreshFSAAOptions(); - } - - if (name == "Resource Creation Policy") - { - if (value == "Create on active device") - mResourceManager->setCreationPolicy(RCP_CREATE_ON_ACTIVE_DEVICE); - else if (value == "Create on all devices") - mResourceManager->setCreationPolicy(RCP_CREATE_ON_ALL_DEVICES); - } - - if (name == "Multi device memory hint") - { - if (value == "Use minimum system memory") - mResourceManager->setAutoHardwareBufferManagement(false); - else if (value == "Auto hardware buffers management") - mResourceManager->setAutoHardwareBufferManagement(true); - } - - if (name == "Fixed Pipeline Enabled") - { - if (value == "Yes") - { - mEnableFixedPipeline = true; - } - else - mEnableFixedPipeline = false; - } - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::refreshFSAAOptions() - { - - ConfigOptionMap::iterator it = mOptions.find( "FSAA" ); - ConfigOption* optFSAA = &it->second; - optFSAA->possibleValues.clear(); - optFSAA->possibleValues.push_back("0"); - - it = mOptions.find("Rendering Device"); - D3D9Driver *driver = getDirect3DDrivers()->item(it->second.currentValue); - if (driver) - { - it = mOptions.find("Video Mode"); - D3D9VideoMode *videoMode = driver->getVideoModeList()->item(it->second.currentValue); - if (videoMode) - { - DWORD numLevels = 0; - bool bOK; - - for (unsigned int n = (unsigned int)D3DMULTISAMPLE_2_SAMPLES; n <= (unsigned int)D3DMULTISAMPLE_16_SAMPLES; n++) - { - bOK = this->_checkMultiSampleQuality( - (D3DMULTISAMPLE_TYPE)n, - &numLevels, - videoMode->getFormat(), - driver->getAdapterNumber(), - D3DDEVTYPE_HAL, - TRUE); - if (bOK) - { - optFSAA->possibleValues.push_back(StringConverter::toString(n)); - if (n >= 8) - optFSAA->possibleValues.push_back(StringConverter::toString(n) + " [Quality]"); - } - } - - } - } - - // Reset FSAA to none if previous doesn't avail in new possible values - StringVector::const_iterator itValue = - std::find(optFSAA->possibleValues.begin(), - optFSAA->possibleValues.end(), - optFSAA->currentValue); - if (itValue == optFSAA->possibleValues.end()) - { - optFSAA->currentValue = "0"; - } - - } - //--------------------------------------------------------------------- - String D3D9RenderSystem::validateConfigOptions() - { - ConfigOptionMap::iterator it; - - // check if video mode is selected - it = mOptions.find( "Video Mode" ); - if (it->second.currentValue.empty()) - return "A video mode must be selected."; - - it = mOptions.find( "Rendering Device" ); - bool foundDriver = false; - D3D9DriverList* driverList = getDirect3DDrivers(); - for( ushort j=0; j < driverList->count(); j++ ) - { - if( driverList->item(j)->DriverDescription() == it->second.currentValue ) - { - foundDriver = true; - break; - } - } - - if (!foundDriver) - { - // Just pick the first driver - setConfigOption("Rendering Device", driverList->item(0)->DriverDescription()); - return "Your DirectX driver name has changed since the last time you ran OGRE; " - "the 'Rendering Device' has been changed."; - } - - return BLANKSTRING; - } - //--------------------------------------------------------------------- - ConfigOptionMap& D3D9RenderSystem::getConfigOptions() - { - // return a COPY of the current config options - return mOptions; - } - //--------------------------------------------------------------------- - RenderWindow* D3D9RenderSystem::_initialise( bool autoCreateWindow, const String& windowTitle ) - { - RenderWindow* autoWindow = NULL; - LogManager::getSingleton().logMessage( "D3D9 : Subsystem Initialising" ); - - // Init using current settings - mActiveD3DDriver = NULL; - ConfigOptionMap::iterator opt = mOptions.find( "Rendering Device" ); - for( uint j=0; j < getDirect3DDrivers()->count(); j++ ) - { - if( getDirect3DDrivers()->item(j)->DriverDescription() == opt->second.currentValue ) - { - mActiveD3DDriver = getDirect3DDrivers()->item(j); - break; - } - } - - if( !mActiveD3DDriver ) - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Problems finding requested Direct3D driver!", "D3D9RenderSystem::initialise" ); - - // get driver version - mDriverVersion.major = HIWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.HighPart); - mDriverVersion.minor = LOWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.HighPart); - mDriverVersion.release = HIWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.LowPart); - mDriverVersion.build = LOWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.LowPart); - - // Create the device manager. - mDeviceManager = OGRE_NEW D3D9DeviceManager(); - - // Create the texture manager for use by others - mTextureManager = OGRE_NEW D3D9TextureManager(); - - // Also create hardware buffer manager - mHardwareBufferManager = OGRE_NEW D3D9HardwareBufferManager(); - - // Create the GPU program manager - mGpuProgramManager = OGRE_NEW D3D9GpuProgramManager(); - - // Create & register HLSL factory - mHLSLProgramFactory = OGRE_NEW D3D9HLSLProgramFactory(); - - if( autoCreateWindow ) - { - bool fullScreen; - opt = mOptions.find( "Full Screen" ); - if( opt == mOptions.end() ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find full screen option!", "D3D9RenderSystem::initialise" ); - fullScreen = opt->second.currentValue == "Yes"; - - D3D9VideoMode* videoMode = NULL; - unsigned int width, height; - String temp; - - opt = mOptions.find( "Video Mode" ); - if( opt == mOptions.end() ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find Video Mode option!", "D3D9RenderSystem::initialise" ); - - // The string we are manipulating looks like this :width x height @ colourDepth - // Pull out the colour depth by getting what comes after the @ and a space - String colourDepth = opt->second.currentValue.substr(opt->second.currentValue.rfind('@')+1); - // Now we know that the width starts a 0, so if we can find the end we can parse that out - String::size_type widthEnd = opt->second.currentValue.find(' '); - // we know that the height starts 3 characters after the width and goes until the next space - String::size_type heightEnd = opt->second.currentValue.find(' ', widthEnd+3); - // Now we can parse out the values - width = StringConverter::parseInt(opt->second.currentValue.substr(0, widthEnd)); - height = StringConverter::parseInt(opt->second.currentValue.substr(widthEnd+3, heightEnd)); - - for( unsigned j=0; j < mActiveD3DDriver->getVideoModeList()->count(); j++ ) - { - temp = mActiveD3DDriver->getVideoModeList()->item(j)->getDescription(); - - // In full screen we only want to allow supported resolutions, so temp and opt->second.currentValue need to - // match exactly, but in windowed mode we can allow for arbitrary window sized, so we only need - // to match the colour values - if(fullScreen && (temp == opt->second.currentValue) || - !fullScreen && (temp.substr(temp.rfind('@')+1) == colourDepth)) - { - videoMode = mActiveD3DDriver->getVideoModeList()->item(j); - break; - } - } - - if( !videoMode ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find requested video mode.", "D3D9RenderSystem::initialise" ); - - // sRGB window option - bool hwGamma = false; - opt = mOptions.find( "sRGB Gamma Conversion" ); - if( opt == mOptions.end() ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find sRGB option!", "D3D9RenderSystem::initialise" ); - hwGamma = opt->second.currentValue == "Yes"; - - NameValuePairList miscParams; - miscParams["colourDepth"] = StringConverter::toString(videoMode->getColourDepth()); - miscParams["FSAA"] = StringConverter::toString(mFSAASamples); - miscParams["FSAAHint"] = mFSAAHint; - miscParams["useNVPerfHUD"] = StringConverter::toString(mUseNVPerfHUD); - miscParams["gamma"] = StringConverter::toString(hwGamma); - miscParams["monitorIndex"] = StringConverter::toString(static_cast(mActiveD3DDriver->getAdapterNumber())); + optFPUMode.possibleValues.clear(); + optFPUMode.possibleValues.push_back("Fastest"); + optFPUMode.possibleValues.push_back("Consistent"); + optFPUMode.immutable = false; + + optNVPerfHUD.currentValue = "No"; + optNVPerfHUD.immutable = false; + optNVPerfHUD.name = "Allow NVPerfHUD"; + optNVPerfHUD.possibleValues.push_back( "Yes" ); + optNVPerfHUD.possibleValues.push_back( "No" ); + + + // SRGB on auto window + optSRGB.name = "sRGB Gamma Conversion"; + optSRGB.possibleValues.push_back("Yes"); + optSRGB.possibleValues.push_back("No"); + optSRGB.currentValue = "No"; + optSRGB.immutable = false; + + // Multiple device memory usage hint. + optMultiDeviceMemHint.name = "Multi device memory hint"; + optMultiDeviceMemHint.possibleValues.push_back("Use minimum system memory"); + optMultiDeviceMemHint.possibleValues.push_back("Auto hardware buffers management"); + optMultiDeviceMemHint.currentValue = "Use minimum system memory"; + optMultiDeviceMemHint.immutable = false; + + optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; + optEnableFixedPipeline.possibleValues.push_back( "Yes" ); + optEnableFixedPipeline.possibleValues.push_back( "No" ); + optEnableFixedPipeline.currentValue = "Yes"; + optEnableFixedPipeline.immutable = false; + + mOptions[optDevice.name] = optDevice; + mOptions[optAllowDirectX9Ex.name] = optAllowDirectX9Ex; + mOptions[optVideoMode.name] = optVideoMode; + mOptions[optFullScreen.name] = optFullScreen; + mOptions[optMultihead.name] = optMultihead; + mOptions[optVSync.name] = optVSync; + mOptions[optVSyncInterval.name] = optVSyncInterval; + mOptions[optAA.name] = optAA; + mOptions[optFPUMode.name] = optFPUMode; + mOptions[optNVPerfHUD.name] = optNVPerfHUD; + mOptions[optSRGB.name] = optSRGB; + mOptions[optResourceCeationPolicy.name] = optResourceCeationPolicy; + mOptions[optMultiDeviceMemHint.name] = optMultiDeviceMemHint; + mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; + + refreshD3DSettings(); + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::refreshD3DSettings() + { + ConfigOption* optVideoMode; + D3D9Driver* driver = 0; + D3D9VideoMode* videoMode; + + ConfigOptionMap::iterator opt = mOptions.find( "Rendering Device" ); + if( opt != mOptions.end() ) + { + for( unsigned j=0; j < getDirect3DDrivers()->count(); j++ ) + { + D3D9Driver* curDriver = getDirect3DDrivers()->item(j); + if( curDriver->DriverDescription() == opt->second.currentValue ) + { + driver = curDriver; + break; + } + } + + if (driver) + { + opt = mOptions.find( "Video Mode" ); + optVideoMode = &opt->second; + optVideoMode->possibleValues.clear(); + // get vide modes for this device + for( unsigned k=0; k < driver->getVideoModeList()->count(); k++ ) + { + videoMode = driver->getVideoModeList()->item( k ); + optVideoMode->possibleValues.push_back( videoMode->getDescription() ); + } + + // Reset video mode to default if previous doesn't avail in new possible values + StringVector::const_iterator itValue = + std::find(optVideoMode->possibleValues.begin(), + optVideoMode->possibleValues.end(), + optVideoMode->currentValue); + if (itValue == optVideoMode->possibleValues.end()) + { + optVideoMode->currentValue = "800 x 600 @ 32-bit colour"; + } + + // Also refresh FSAA options + refreshFSAAOptions(); + } + } + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setConfigOption( const String &name, const String &value ) + { + + LogManager::getSingleton().stream() + << "D3D9 : RenderSystem Option: " << name << " = " << value; + + bool viewModeChanged = false; + + // Find option + ConfigOptionMap::iterator it = mOptions.find( name ); + + // Update + if( it != mOptions.end() ) + it->second.currentValue = value; + else + { + StringStream str; + str << "Option named '" << name << "' does not exist."; + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, str.str(), "D3D9RenderSystem::setConfigOption" ); + } + + // Refresh other options if D3DDriver changed + if( name == "Rendering Device" ) + refreshD3DSettings(); + + if ( name == "Allow DirectX9Ex" ) + { + if (value == "Yes") + mAllowDirectX9Ex = true; + else mAllowDirectX9Ex = false; + + // Create our Direct3D object + if (mAllowDirectX9Ex && !mIsDirectX9Ex) + { + SAFE_RELEASE(mD3D); + HMODULE hD3D = LoadLibrary(TEXT("d3d9.dll")); + if (hD3D) + { + typedef HRESULT (WINAPI *DIRECT3DCREATE9EXFUNCTION)(UINT, IDirect3D9Ex**); + DIRECT3DCREATE9EXFUNCTION pfnCreate9Ex = (DIRECT3DCREATE9EXFUNCTION)GetProcAddress(hD3D, "Direct3DCreate9Ex"); + if (pfnCreate9Ex) + { + IDirect3D9Ex* d3dEx = NULL; + (*pfnCreate9Ex)(D3D_SDK_VERSION, &d3dEx); + d3dEx->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast(&mD3D)); + mIsDirectX9Ex = true; + } + FreeLibrary(hD3D); + } + } + if ((mD3D == NULL) || (!mAllowDirectX9Ex && mIsDirectX9Ex)) + { + if ( NULL == (mD3D = Direct3DCreate9(D3D_SDK_VERSION)) ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Failed to create Direct3D9 object", "D3D9RenderSystem::D3D9RenderSystem" ); + } + } + + if( name == "Full Screen" ) + { + // Video mode is applicable + it = mOptions.find( "Video Mode" ); + if (it->second.currentValue.empty()) + { + it->second.currentValue = "800 x 600 @ 32-bit colour"; + viewModeChanged = true; + } + } + + if( name == "Use Multihead" ) + { + if (value == "Yes") + mMultiheadUse = mutYes; + else if (value == "No") + mMultiheadUse = mutNo; + else mMultiheadUse = mutAuto; + } + + if( name == "FSAA" ) + { + StringVector values = StringUtil::split(value, " ", 1); + mFSAASamples = StringConverter::parseUnsignedInt(values[0]); + if (values.size() > 1) + mFSAAHint = values[1]; + + } + + if( name == "Allow NVPerfHUD" ) + { + if (value == "Yes") + mUseNVPerfHUD = true; + else + mUseNVPerfHUD = false; + } + + if (viewModeChanged || name == "Video Mode") + { + refreshFSAAOptions(); + } + + if (name == "Resource Creation Policy") + { + if (value == "Create on active device") + mResourceManager->setCreationPolicy(RCP_CREATE_ON_ACTIVE_DEVICE); + else if (value == "Create on all devices") + mResourceManager->setCreationPolicy(RCP_CREATE_ON_ALL_DEVICES); + } + + if (name == "Multi device memory hint") + { + if (value == "Use minimum system memory") + mResourceManager->setAutoHardwareBufferManagement(false); + else if (value == "Auto hardware buffers management") + mResourceManager->setAutoHardwareBufferManagement(true); + } + + if (name == "Fixed Pipeline Enabled") + { + if (value == "Yes") + { + mEnableFixedPipeline = true; + } + else + mEnableFixedPipeline = false; + } + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::refreshFSAAOptions() + { + + ConfigOptionMap::iterator it = mOptions.find( "FSAA" ); + ConfigOption* optFSAA = &it->second; + optFSAA->possibleValues.clear(); + optFSAA->possibleValues.push_back("0"); + + it = mOptions.find("Rendering Device"); + D3D9Driver *driver = getDirect3DDrivers()->item(it->second.currentValue); + if (driver) + { + it = mOptions.find("Video Mode"); + D3D9VideoMode *videoMode = driver->getVideoModeList()->item(it->second.currentValue); + if (videoMode) + { + DWORD numLevels = 0; + bool bOK; + + for (unsigned int n = (unsigned int)D3DMULTISAMPLE_2_SAMPLES; n <= (unsigned int)D3DMULTISAMPLE_16_SAMPLES; n++) + { + bOK = this->_checkMultiSampleQuality( + (D3DMULTISAMPLE_TYPE)n, + &numLevels, + videoMode->getFormat(), + driver->getAdapterNumber(), + D3DDEVTYPE_HAL, + TRUE); + if (bOK) + { + optFSAA->possibleValues.push_back(StringConverter::toString(n)); + if (n >= 8) + optFSAA->possibleValues.push_back(StringConverter::toString(n) + " [Quality]"); + } + } + + } + } + + // Reset FSAA to none if previous doesn't avail in new possible values + StringVector::const_iterator itValue = + std::find(optFSAA->possibleValues.begin(), + optFSAA->possibleValues.end(), + optFSAA->currentValue); + if (itValue == optFSAA->possibleValues.end()) + { + optFSAA->currentValue = "0"; + } + + } + //--------------------------------------------------------------------- + String D3D9RenderSystem::validateConfigOptions() + { + ConfigOptionMap::iterator it; + + // check if video mode is selected + it = mOptions.find( "Video Mode" ); + if (it->second.currentValue.empty()) + return "A video mode must be selected."; + + it = mOptions.find( "Rendering Device" ); + bool foundDriver = false; + D3D9DriverList* driverList = getDirect3DDrivers(); + for( ushort j=0; j < driverList->count(); j++ ) + { + if( driverList->item(j)->DriverDescription() == it->second.currentValue ) + { + foundDriver = true; + break; + } + } + + if (!foundDriver) + { + // Just pick the first driver + setConfigOption("Rendering Device", driverList->item(0)->DriverDescription()); + return "Your DirectX driver name has changed since the last time you ran OGRE; " + "the 'Rendering Device' has been changed."; + } + + return BLANKSTRING; + } + //--------------------------------------------------------------------- + ConfigOptionMap& D3D9RenderSystem::getConfigOptions() + { + // return a COPY of the current config options + return mOptions; + } + //--------------------------------------------------------------------- + RenderWindow* D3D9RenderSystem::_initialise( bool autoCreateWindow, const String& windowTitle ) + { + RenderWindow* autoWindow = NULL; + LogManager::getSingleton().logMessage( "D3D9 : Subsystem Initialising" ); + + // Init using current settings + mActiveD3DDriver = NULL; + ConfigOptionMap::iterator opt = mOptions.find( "Rendering Device" ); + for( uint j=0; j < getDirect3DDrivers()->count(); j++ ) + { + if( getDirect3DDrivers()->item(j)->DriverDescription() == opt->second.currentValue ) + { + mActiveD3DDriver = getDirect3DDrivers()->item(j); + break; + } + } + + if( !mActiveD3DDriver ) + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Problems finding requested Direct3D driver!", "D3D9RenderSystem::initialise" ); + + // get driver version + mDriverVersion.major = HIWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.HighPart); + mDriverVersion.minor = LOWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.HighPart); + mDriverVersion.release = HIWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.LowPart); + mDriverVersion.build = LOWORD(mActiveD3DDriver->getAdapterIdentifier().DriverVersion.LowPart); + + // Create the device manager. + mDeviceManager = OGRE_NEW D3D9DeviceManager(); + + // Create the texture manager for use by others + mTextureManager = OGRE_NEW D3D9TextureManager(); + + // Also create hardware buffer manager + mHardwareBufferManager = OGRE_NEW D3D9HardwareBufferManager(); + + // Create the GPU program manager + mGpuProgramManager = OGRE_NEW D3D9GpuProgramManager(); + + // Create & register HLSL factory + mHLSLProgramFactory = OGRE_NEW D3D9HLSLProgramFactory(); + + if( autoCreateWindow ) + { + bool fullScreen; + opt = mOptions.find( "Full Screen" ); + if( opt == mOptions.end() ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find full screen option!", "D3D9RenderSystem::initialise" ); + fullScreen = opt->second.currentValue == "Yes"; + + D3D9VideoMode* videoMode = NULL; + unsigned int width, height; + String temp; + + opt = mOptions.find( "Video Mode" ); + if( opt == mOptions.end() ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find Video Mode option!", "D3D9RenderSystem::initialise" ); + + // The string we are manipulating looks like this :width x height @ colourDepth + // Pull out the colour depth by getting what comes after the @ and a space + String colourDepth = opt->second.currentValue.substr(opt->second.currentValue.rfind('@')+1); + // Now we know that the width starts a 0, so if we can find the end we can parse that out + String::size_type widthEnd = opt->second.currentValue.find(' '); + // we know that the height starts 3 characters after the width and goes until the next space + String::size_type heightEnd = opt->second.currentValue.find(' ', widthEnd+3); + // Now we can parse out the values + width = StringConverter::parseInt(opt->second.currentValue.substr(0, widthEnd)); + height = StringConverter::parseInt(opt->second.currentValue.substr(widthEnd+3, heightEnd)); + + for( unsigned j=0; j < mActiveD3DDriver->getVideoModeList()->count(); j++ ) + { + temp = mActiveD3DDriver->getVideoModeList()->item(j)->getDescription(); + + // In full screen we only want to allow supported resolutions, so temp and opt->second.currentValue need to + // match exactly, but in windowed mode we can allow for arbitrary window sized, so we only need + // to match the colour values + if(fullScreen && (temp == opt->second.currentValue) || + !fullScreen && (temp.substr(temp.rfind('@')+1) == colourDepth)) + { + videoMode = mActiveD3DDriver->getVideoModeList()->item(j); + break; + } + } + + if( !videoMode ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find requested video mode.", "D3D9RenderSystem::initialise" ); + + // sRGB window option + bool hwGamma = false; + opt = mOptions.find( "sRGB Gamma Conversion" ); + if( opt == mOptions.end() ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't find sRGB option!", "D3D9RenderSystem::initialise" ); + hwGamma = opt->second.currentValue == "Yes"; + + NameValuePairList miscParams; + miscParams["colourDepth"] = StringConverter::toString(videoMode->getColourDepth()); + miscParams["FSAA"] = StringConverter::toString(mFSAASamples); + miscParams["FSAAHint"] = mFSAAHint; + miscParams["useNVPerfHUD"] = StringConverter::toString(mUseNVPerfHUD); + miscParams["gamma"] = StringConverter::toString(hwGamma); + miscParams["monitorIndex"] = StringConverter::toString(static_cast(mActiveD3DDriver->getAdapterNumber())); opt = mOptions.find("VSync"); if (opt == mOptions.end()) @@ -700,3548 +700,3548 @@ namespace Ogre bool vsync = (opt->second.currentValue == "Yes"); miscParams["vsync"] = StringConverter::toString(vsync); - opt = mOptions.find("VSync Interval"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync Interval options!", "D3D9RenderSystem::initialise"); - miscParams["vsyncInterval"] = opt->second.currentValue; + opt = mOptions.find("VSync Interval"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync Interval options!", "D3D9RenderSystem::initialise"); + miscParams["vsyncInterval"] = opt->second.currentValue; + + autoWindow = _createRenderWindow( windowTitle, width, height, + fullScreen, &miscParams ); + + // If we have 16bit depth buffer enable w-buffering. + assert( autoWindow ); + if ( autoWindow->getColourDepth() == 16 ) + { + mWBuffer = true; + } + else + { + mWBuffer = false; + } + } + + LogManager::getSingleton().logMessage("***************************************"); + LogManager::getSingleton().logMessage("*** D3D9 : Subsystem Initialised OK ***"); + LogManager::getSingleton().logMessage("***************************************"); + + // call superclass method + RenderSystem::_initialise( autoCreateWindow ); + + + return autoWindow; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::reinitialise() + { + LogManager::getSingleton().logMessage( "D3D9 : Reinitialising" ); + this->shutdown(); + this->_initialise( true ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::shutdown() + { + RenderSystem::shutdown(); + + if (mDeviceManager != NULL) + { + OGRE_DELETE mDeviceManager; + mDeviceManager = NULL; + } + + if (mDriverList != NULL) + { + OGRE_DELETE mDriverList; + mDriverList = NULL; + } + mActiveD3DDriver = NULL; + + LogManager::getSingleton().logMessage("D3D9 : Shutting down cleanly."); + + if (mTextureManager != NULL) + { + OGRE_DELETE mTextureManager; + mTextureManager = NULL; + } + + if (mHardwareBufferManager != NULL) + { + OGRE_DELETE mHardwareBufferManager; + mHardwareBufferManager = NULL; + } + + if (mGpuProgramManager != NULL) + { + OGRE_DELETE mGpuProgramManager; + mGpuProgramManager = NULL; + } + } + //--------------------------------------------------------------------- + RenderWindow* D3D9RenderSystem::_createRenderWindow(const String &name, + unsigned int width, unsigned int height, bool fullScreen, + const NameValuePairList *miscParams) + { + // Log a message + StringStream ss; + ss << "D3D9RenderSystem::_createRenderWindow \"" << name << "\", " << + width << "x" << height << " "; + + if(fullScreen) + ss << "fullscreen "; + else + ss << "windowed "; + + if(miscParams) + { + ss << " miscParams: "; + NameValuePairList::const_iterator it; + for(it=miscParams->begin(); it!=miscParams->end(); ++it) + { + ss << it->first << "=" << it->second << " "; + } + LogManager::getSingleton().logMessage(ss.str()); + } + + String msg; + + // Make sure we don't already have a render target of the + // same name as the one supplied + if( mRenderTargets.find( name ) != mRenderTargets.end() ) + { + msg = "A render target of the same name '" + name + "' already " + "exists. You cannot create a new window with this name."; + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, msg, "D3D9RenderSystem::_createRenderWindow" ); + } + + D3D9RenderWindow* renderWindow = OGRE_NEW D3D9RenderWindow(mhInstance); + + renderWindow->create(name, width, height, fullScreen, miscParams); + + mResourceManager->lockDeviceAccess(); + + try + { + mDeviceManager->linkRenderWindow(renderWindow); + } + catch (const Ogre::RenderingAPIException&) + { + // after catching the exception, clean up + mResourceManager->unlockDeviceAccess(); + renderWindow->destroy(); + + // re-throw + throw; + } + + mResourceManager->unlockDeviceAccess(); + + mRenderWindows.push_back(renderWindow); + + updateRenderSystemCapabilities(renderWindow); + + attachRenderTarget( *renderWindow ); + + return renderWindow; + } + //--------------------------------------------------------------------- + bool D3D9RenderSystem::_createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, + RenderWindowList& createdWindows) + { + // Call base render system method. + if (false == RenderSystem::_createRenderWindows(renderWindowDescriptions, createdWindows)) + return false; + + // Simply call _createRenderWindow in a loop. + for (size_t i = 0; i < renderWindowDescriptions.size(); ++i) + { + const RenderWindowDescription& curRenderWindowDescription = renderWindowDescriptions[i]; + RenderWindow* curWindow = NULL; + + curWindow = _createRenderWindow(curRenderWindowDescription.name, + curRenderWindowDescription.width, + curRenderWindowDescription.height, + curRenderWindowDescription.useFullScreen, + &curRenderWindowDescription.miscParams); + + createdWindows.push_back(curWindow); + } + + return true; + } + + //--------------------------------------------------------------------- + RenderSystemCapabilities* D3D9RenderSystem::updateRenderSystemCapabilities(D3D9RenderWindow* renderWindow) + { + RenderSystemCapabilities* rsc = mRealCapabilities; + if (rsc == NULL) + rsc = OGRE_NEW RenderSystemCapabilities(); + + rsc->setCategoryRelevant(CAPS_CATEGORY_D3D9, true); + rsc->setDriverVersion(mDriverVersion); + rsc->setDeviceName(mActiveD3DDriver->DriverDescription()); + rsc->setRenderSystemName(getName()); + + if(mEnableFixedPipeline) + { + // Supports fixed-function + rsc->setCapability(RSC_FIXED_FUNCTION); + } + + + // Init caps to maximum. + rsc->setNumTextureUnits(1024); + rsc->setCapability(RSC_ANISOTROPY); + rsc->setCapability(RSC_AUTOMIPMAP); + rsc->setCapability(RSC_DOT3); + rsc->setCapability(RSC_CUBEMAPPING); + rsc->setCapability(RSC_SCISSOR_TEST); + rsc->setCapability(RSC_TWO_SIDED_STENCIL); + rsc->setCapability(RSC_STENCIL_WRAP); + rsc->setCapability(RSC_HWOCCLUSION); + rsc->setCapability(RSC_USER_CLIP_PLANES); + rsc->setCapability(RSC_32BIT_INDEX); + rsc->setCapability(RSC_VERTEX_FORMAT_UBYTE4); + rsc->setCapability(RSC_TEXTURE_1D); + rsc->setCapability(RSC_TEXTURE_3D); + rsc->setCapability(RSC_NON_POWER_OF_2_TEXTURES); + rsc->setNonPOW2TexturesLimited(false); + rsc->setNumMultiRenderTargets(OGRE_MAX_MULTIPLE_RENDER_TARGETS); + rsc->setCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS); + rsc->setCapability(RSC_POINT_SPRITES); + rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS); + rsc->setMaxPointSize(2.19902e+012f); + rsc->setCapability(RSC_MIPMAP_LOD_BIAS); + rsc->setCapability(RSC_PERSTAGECONSTANT); + rsc->setCapability(RSC_HWSTENCIL); + rsc->setStencilBufferBitDepth(8); + rsc->setCapability(RSC_ADVANCED_BLEND_OPERATIONS); + rsc->setCapability(RSC_RTT_SEPARATE_DEPTHBUFFER); + rsc->setCapability(RSC_RTT_MAIN_DEPTHBUFFER_ATTACHABLE); + rsc->setCapability(RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL); + rsc->setCapability(RSC_VERTEX_BUFFER_INSTANCE_DATA); + rsc->setCapability(RSC_CAN_GET_COMPILED_SHADER_BUFFER); + + for (uint i=0; i < mDeviceManager->getDeviceCount(); ++i) + { + D3D9Device* device = mDeviceManager->getDevice(i); + IDirect3DDevice9* d3d9Device = device->getD3D9Device(); + + IDirect3DSurface9* pSurf; + + + // Check for hardware stencil support + d3d9Device->GetDepthStencilSurface(&pSurf); + + if (pSurf != NULL) + { + D3DSURFACE_DESC surfDesc; + + pSurf->GetDesc(&surfDesc); + pSurf->Release(); + + if (surfDesc.Format != D3DFMT_D15S1 && + surfDesc.Format != D3DFMT_D24S8 && + surfDesc.Format != D3DFMT_D24X4S4 && + surfDesc.Format != D3DFMT_D24FS8) + rsc->unsetCapability(RSC_HWSTENCIL); + } + + // Check for hardware occlusion support + HRESULT hr = d3d9Device->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL); + + if (FAILED(hr)) + rsc->unsetCapability(RSC_HWOCCLUSION); + } + + // Update RS caps using the minimum value found in adapter list. + for (unsigned int i=0; i < mDriverList->count(); ++i) + { + D3D9Driver* pCurDriver = mDriverList->item(i); + const D3DCAPS9& rkCurCaps = pCurDriver->getD3D9DeviceCaps(); + + if (rkCurCaps.MaxSimultaneousTextures < rsc->getNumTextureUnits()) + { + rsc->setNumTextureUnits(static_cast(rkCurCaps.MaxSimultaneousTextures)); + } + + // Check for Anisotropy. + if (rkCurCaps.MaxAnisotropy <= 1) + rsc->unsetCapability(RSC_ANISOTROPY); + + // Check automatic mipmap generation. + if ((rkCurCaps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) == 0) + rsc->unsetCapability(RSC_AUTOMIPMAP); + + // Check Dot product 3. + if ((rkCurCaps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) == 0) + rsc->unsetCapability(RSC_DOT3); + + // Scissor test + if ((rkCurCaps.RasterCaps & D3DPRASTERCAPS_SCISSORTEST) == 0) + rsc->unsetCapability(RSC_SCISSOR_TEST); + + + // Two-sided stencil + if ((rkCurCaps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) == 0) + rsc->unsetCapability(RSC_TWO_SIDED_STENCIL); + + // stencil wrap + if ((rkCurCaps.StencilCaps & D3DSTENCILCAPS_INCR) == 0 || + (rkCurCaps.StencilCaps & D3DSTENCILCAPS_DECR) == 0) + rsc->unsetCapability(RSC_STENCIL_WRAP); + + // User clip planes + if (rkCurCaps.MaxUserClipPlanes == 0) + rsc->unsetCapability(RSC_USER_CLIP_PLANES); + + // D3DFMT_INDEX32 type? + if (rkCurCaps.MaxVertexIndex <= 0xFFFF) + rsc->unsetCapability(RSC_32BIT_INDEX); + + // UBYTE4 type? + if ((rkCurCaps.DeclTypes & D3DDTCAPS_UBYTE4) == 0) + rsc->unsetCapability(RSC_VERTEX_FORMAT_UBYTE4); + + // Check cube map support. + if ((rkCurCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) == 0) + rsc->unsetCapability(RSC_CUBEMAPPING); + + // 3D textures? + if ((rkCurCaps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) == 0) + rsc->unsetCapability(RSC_TEXTURE_3D); + + if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_POW2) + { + // Conditional support for non POW2 + if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) + rsc->setNonPOW2TexturesLimited(true); + + // Only power of 2 supported. + else + rsc->unsetCapability(RSC_NON_POWER_OF_2_TEXTURES); + } + + // Number of render targets + if (rkCurCaps.NumSimultaneousRTs < rsc->getNumMultiRenderTargets()) + { + rsc->setNumMultiRenderTargets(std::min((ushort)rkCurCaps.NumSimultaneousRTs, (ushort)OGRE_MAX_MULTIPLE_RENDER_TARGETS)); + } + + if((rkCurCaps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS) == 0) + { + rsc->unsetCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS); + } + + // Point sprites + if (rkCurCaps.MaxPointSize <= 1.0f) + { + rsc->unsetCapability(RSC_POINT_SPRITES); + // sprites and extended parameters go together in D3D + rsc->unsetCapability(RSC_POINT_EXTENDED_PARAMETERS); + } + + // Take the minimum point size. + if (rkCurCaps.MaxPointSize < rsc->getMaxPointSize()) + rsc->setMaxPointSize(rkCurCaps.MaxPointSize); + + // Mipmap LOD biasing? + if ((rkCurCaps.RasterCaps & D3DPRASTERCAPS_MIPMAPLODBIAS) == 0) + rsc->unsetCapability(RSC_MIPMAP_LOD_BIAS); + + + // Do we support per-stage src_manual constants? + // HACK - ATI drivers seem to be buggy and don't support per-stage constants properly? + // TODO: move this to RSC + if((rkCurCaps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT) == 0) + rsc->unsetCapability(RSC_PERSTAGECONSTANT); + + // Advanced blend operations? min max subtract rev + if((rkCurCaps.PrimitiveMiscCaps & D3DPMISCCAPS_BLENDOP) == 0) + rsc->unsetCapability(RSC_ADVANCED_BLEND_OPERATIONS); + } + + // Blending between stages supported + rsc->setCapability(RSC_BLENDING); + + + // We always support compression, D3DX will decompress if device does not support + rsc->setCapability(RSC_TEXTURE_COMPRESSION); + rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT); + + // We always support VBOs + rsc->setCapability(RSC_VBO); + + + convertVertexShaderCaps(rsc); + convertPixelShaderCaps(rsc); + + // Adapter details + const D3DADAPTER_IDENTIFIER9& adapterID = mActiveD3DDriver->getAdapterIdentifier(); + + // determine vendor + // Full list of vendors here: http://www.pcidatabase.com/vendors.php?sort=id + switch(adapterID.VendorId) + { + case 0x10DE: + rsc->setVendor(GPU_NVIDIA); + break; + case 0x1002: + rsc->setVendor(GPU_AMD); + break; + case 0x163C: + case 0x8086: + rsc->setVendor(GPU_INTEL); + break; + case 0x5333: + rsc->setVendor(GPU_S3); + break; + case 0x3D3D: + rsc->setVendor(GPU_3DLABS); + break; + case 0x102B: + rsc->setVendor(GPU_MATROX); + break; + case 0x1039: + rsc->setVendor(GPU_SIS); + break; + default: + rsc->setVendor(GPU_UNKNOWN); + break; + }; + + // Infinite projection? + // We have no capability for this, so we have to base this on our + // experience and reports from users + // Non-vertex program capable hardware does not appear to support it + if (rsc->hasCapability(RSC_VERTEX_PROGRAM)) + { + // GeForce4 Ti (and presumably GeForce3) does not + // render infinite projection properly, even though it does in GL + // So exclude all cards prior to the FX range from doing infinite + if (rsc->getVendor() != GPU_NVIDIA || // not nVidia + !((adapterID.DeviceId >= 0x200 && adapterID.DeviceId <= 0x20F) || //gf3 + (adapterID.DeviceId >= 0x250 && adapterID.DeviceId <= 0x25F) || //gf4ti + (adapterID.DeviceId >= 0x280 && adapterID.DeviceId <= 0x28F) || //gf4ti + (adapterID.DeviceId >= 0x170 && adapterID.DeviceId <= 0x18F) || //gf4 go + (adapterID.DeviceId >= 0x280 && adapterID.DeviceId <= 0x28F))) //gf4ti go + { + rsc->setCapability(RSC_INFINITE_FAR_PLANE); + } + + } + + // We always support rendertextures bigger than the frame buffer + rsc->setCapability(RSC_HWRENDER_TO_TEXTURE); + + // Determine if any floating point texture format is supported + D3DFORMAT floatFormats[6] = {D3DFMT_R16F, D3DFMT_G16R16F, + D3DFMT_A16B16G16R16F, D3DFMT_R32F, D3DFMT_G32R32F, + D3DFMT_A32B32G32R32F}; + IDirect3DSurface9* bbSurf; + renderWindow->getCustomAttribute("DDBACKBUFFER", &bbSurf); + D3DSURFACE_DESC bbSurfDesc; + bbSurf->GetDesc(&bbSurfDesc); + + for (int i = 0; i < 6; ++i) + { + if (SUCCEEDED(mD3D->CheckDeviceFormat(mActiveD3DDriver->getAdapterNumber(), + D3DDEVTYPE_HAL, bbSurfDesc.Format, + 0, D3DRTYPE_TEXTURE, floatFormats[i]))) + { + rsc->setCapability(RSC_TEXTURE_FLOAT); + break; + } + + } + + + // TODO: make convertVertex/Fragment fill in rsc + // TODO: update the below line to use rsc + // Vertex textures + if (rsc->isShaderProfileSupported("vs_3_0")) + { + // Run through all the texture formats looking for any which support + // vertex texture fetching. Must have at least one! + // All ATI Radeon up to X1n00 say they support vs_3_0, + // but they support no texture formats for vertex texture fetch (cheaters!) + if (checkVertexTextureFormats(renderWindow)) + { + rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH); + // always 4 vertex texture units in vs_3_0, and never shared + rsc->setNumVertexTextureUnits(4); + rsc->setVertexTextureUnitsShared(false); + } + } + else + { + //True HW Instancing is supported since Shader model 3.0 ATI has a nasty + //hack for enabling it in their SM 2.0 cards, but we don't (and won't) support it + rsc->unsetCapability( RSC_VERTEX_BUFFER_INSTANCE_DATA ); + } + + // Check alpha to coverage support + // this varies per vendor! But at least SM3 is required + if (rsc->isShaderProfileSupported("ps_3_0")) + { + // NVIDIA needs a separate check + if (rsc->getVendor() == GPU_NVIDIA) + { + if (mD3D->CheckDeviceFormat( + D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE, + (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')) == S_OK) + { + rsc->setCapability(RSC_ALPHA_TO_COVERAGE); + } + + } + else if (rsc->getVendor() == GPU_AMD) + { + // There is no check on ATI, we have to assume SM3 == support + rsc->setCapability(RSC_ALPHA_TO_COVERAGE); + } + + // no other cards have Dx9 hacks for alpha to coverage, as far as I know + } + + + if (mRealCapabilities == NULL) + { + mRealCapabilities = rsc; + mRealCapabilities->addShaderProfile("hlsl"); + + // if we are using custom capabilities, then + // mCurrentCapabilities has already been loaded + if(!mUseCustomCapabilities) + mCurrentCapabilities = mRealCapabilities; + + fireEvent("RenderSystemCapabilitiesCreated"); + + initialiseFromRenderSystemCapabilities(mCurrentCapabilities, renderWindow); + } + + return rsc; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::convertVertexShaderCaps(RenderSystemCapabilities* rsc) const + { + ushort major = 0xFF; + ushort minor = 0xFF; + D3DCAPS9 minVSCaps; + + // Find the device with the lowest vertex shader caps. + for (unsigned int i=0; i < mDriverList->count(); ++i) + { + D3D9Driver* pCurDriver = mDriverList->item(i); + const D3DCAPS9& rkCurCaps = pCurDriver->getD3D9DeviceCaps(); + ushort currMajor = static_cast((rkCurCaps.VertexShaderVersion & 0x0000FF00) >> 8); + ushort currMinor = static_cast(rkCurCaps.VertexShaderVersion & 0x000000FF); + + if (currMajor < major) + { + major = currMajor; + minor = currMinor; + minVSCaps = rkCurCaps; + } + else if (currMajor == major && currMinor < minor) + { + minor = currMinor; + minVSCaps = rkCurCaps; + } + } + + // In case we didn't found any vertex shader support + // try the IDirect3DDevice9 caps instead of the IDirect3D9 + // software vertex processing is reported there + if (major == 0 && minor == 0) + { + IDirect3DDevice9* lpD3DDevice9 = getActiveD3D9Device(); + D3DCAPS9 d3dDeviceCaps9; + lpD3DDevice9->GetDeviceCaps(&d3dDeviceCaps9); + major = static_cast((d3dDeviceCaps9.VertexShaderVersion & 0x0000FF00) >> 8); + minor = static_cast(d3dDeviceCaps9.VertexShaderVersion & 0x000000FF); + } + + bool vs2x = false; + bool vs2a = false; + + // Special case detection for vs_2_x/a support + if (major >= 2) + { + if ((minVSCaps.VS20Caps.Caps & D3DVS20CAPS_PREDICATION) && + (minVSCaps.VS20Caps.DynamicFlowControlDepth > 0) && + (minVSCaps.VS20Caps.NumTemps >= 12)) + { + vs2x = true; + } + + if ((minVSCaps.VS20Caps.Caps & D3DVS20CAPS_PREDICATION) && + (minVSCaps.VS20Caps.DynamicFlowControlDepth > 0) && + (minVSCaps.VS20Caps.NumTemps >= 13)) + { + vs2a = true; + } + } + + // Populate max param count + switch (major) + { + case 1: + // No boolean params allowed + rsc->setVertexProgramConstantBoolCount(0); + // No integer params allowed + rsc->setVertexProgramConstantIntCount(0); + // float params, always 4D + rsc->setVertexProgramConstantFloatCount(static_cast(minVSCaps.MaxVertexShaderConst)); + + break; + case 2: + // 16 boolean params allowed + rsc->setVertexProgramConstantBoolCount(16); + // 16 integer params allowed, 4D + rsc->setVertexProgramConstantIntCount(16); + // float params, always 4D + rsc->setVertexProgramConstantFloatCount(static_cast(minVSCaps.MaxVertexShaderConst)); + break; + case 3: + // 16 boolean params allowed + rsc->setVertexProgramConstantBoolCount(16); + // 16 integer params allowed, 4D + rsc->setVertexProgramConstantIntCount(16); + // float params, always 4D + rsc->setVertexProgramConstantFloatCount(static_cast(minVSCaps.MaxVertexShaderConst)); + break; + } + + // populate syntax codes in program manager (no breaks in this one so it falls through) + switch(major) + { + case 3: + rsc->addShaderProfile("vs_3_0"); + case 2: + if (vs2x) + rsc->addShaderProfile("vs_2_x"); + if (vs2a) + rsc->addShaderProfile("vs_2_a"); + + rsc->addShaderProfile("vs_2_0"); + case 1: + rsc->addShaderProfile("vs_1_1"); + rsc->setCapability(RSC_VERTEX_PROGRAM); + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::convertPixelShaderCaps(RenderSystemCapabilities* rsc) const + { + ushort major = 0xFF; + ushort minor = 0xFF; + D3DCAPS9 minPSCaps; + + // Find the device with the lowest pixel shader caps. + for (unsigned int i=0; i < mDriverList->count(); ++i) + { + D3D9Driver* pCurDriver = mDriverList->item(i); + const D3DCAPS9& currCaps = pCurDriver->getD3D9DeviceCaps(); + ushort currMajor = static_cast((currCaps.PixelShaderVersion & 0x0000FF00) >> 8); + ushort currMinor = static_cast(currCaps.PixelShaderVersion & 0x000000FF); + + if (currMajor < major) + { + major = currMajor; + minor = currMinor; + minPSCaps = currCaps; + } + else if (currMajor == major && currMinor < minor) + { + minor = currMinor; + minPSCaps = currCaps; + } + } + + bool ps2a = false; + bool ps2b = false; + bool ps2x = false; + + // Special case detection for ps_2_x/a/b support + if (major >= 2) + { + if ((minPSCaps.PS20Caps.Caps & D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT) && + (minPSCaps.PS20Caps.NumTemps >= 32)) + { + ps2b = true; + } + + if ((minPSCaps.PS20Caps.Caps & D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT) && + (minPSCaps.PS20Caps.Caps & D3DPS20CAPS_NODEPENDENTREADLIMIT) && + (minPSCaps.PS20Caps.Caps & D3DPS20CAPS_ARBITRARYSWIZZLE) && + (minPSCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) && + (minPSCaps.PS20Caps.Caps & D3DPS20CAPS_PREDICATION) && + (minPSCaps.PS20Caps.NumTemps >= 22)) + { + ps2a = true; + } + + // Does this enough? + if (ps2a || ps2b) + { + ps2x = true; + } + } + + switch (major) + { + case 1: + // no boolean params allowed + rsc->setFragmentProgramConstantBoolCount(0); + // no integer params allowed + rsc->setFragmentProgramConstantIntCount(0); + // float params, always 4D + // NB in ps_1_x these are actually stored as fixed point values, + // but they are entered as floats + rsc->setFragmentProgramConstantFloatCount(8); + break; + case 2: + // 16 boolean params allowed + rsc->setFragmentProgramConstantBoolCount(16); + // 16 integer params allowed, 4D + rsc->setFragmentProgramConstantIntCount(16); + // float params, always 4D + rsc->setFragmentProgramConstantFloatCount(32); + break; + case 3: + // 16 boolean params allowed + rsc->setFragmentProgramConstantBoolCount(16); + // 16 integer params allowed, 4D + rsc->setFragmentProgramConstantIntCount(16); + // float params, always 4D + rsc->setFragmentProgramConstantFloatCount(224); + break; + } + + // populate syntax codes in program manager (no breaks in this one so it falls through) + switch(major) + { + case 3: + if (minor > 0) + rsc->addShaderProfile("ps_3_x"); + + rsc->addShaderProfile("ps_3_0"); + case 2: + if (ps2x) + rsc->addShaderProfile("ps_2_x"); + if (ps2a) + rsc->addShaderProfile("ps_2_a"); + if (ps2b) + rsc->addShaderProfile("ps_2_b"); + + rsc->addShaderProfile("ps_2_0"); + case 1: + if (major > 1 || minor >= 4) + rsc->addShaderProfile("ps_1_4"); + if (major > 1 || minor >= 3) + rsc->addShaderProfile("ps_1_3"); + if (major > 1 || minor >= 2) + rsc->addShaderProfile("ps_1_2"); + + rsc->addShaderProfile("ps_1_1"); + rsc->setCapability(RSC_FRAGMENT_PROGRAM); + } + } + //----------------------------------------------------------------------- + bool D3D9RenderSystem::checkVertexTextureFormats(D3D9RenderWindow* renderWindow) const + { + bool anySupported = false; + + IDirect3DSurface9* bbSurf; + renderWindow->getCustomAttribute("DDBACKBUFFER", &bbSurf); + D3DSURFACE_DESC bbSurfDesc; + bbSurf->GetDesc(&bbSurfDesc); + + for (uint ipf = static_cast(PF_L8); ipf < static_cast(PF_COUNT); ++ipf) + { + PixelFormat pf = (PixelFormat)ipf; + + D3DFORMAT fmt = + D3D9Mappings::_getPF(D3D9Mappings::_getClosestSupportedPF(pf)); + + if (SUCCEEDED(mD3D->CheckDeviceFormat( + mActiveD3DDriver->getAdapterNumber(), D3DDEVTYPE_HAL, bbSurfDesc.Format, + D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, fmt))) + { + // cool, at least one supported + anySupported = true; + LogManager::getSingleton().stream() + << "D3D9: Vertex texture format supported - " + << PixelUtil::getFormatName(pf); + } + } + + return anySupported; + + } + //----------------------------------------------------------------------- + void D3D9RenderSystem::initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary) + { + if (caps->getRenderSystemName() != getName()) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Trying to initialize D3D9RenderSystem from RenderSystemCapabilities that do not support Direct3D9", + "D3D9RenderSystem::initialiseFromRenderSystemCapabilities"); + } + if (caps->isShaderProfileSupported("hlsl")) + HighLevelGpuProgramManager::getSingleton().addFactory(mHLSLProgramFactory); + + Log* defaultLog = LogManager::getSingleton().getDefaultLog(); + if (defaultLog) + { + caps->log(defaultLog); + } + } + + //----------------------------------------------------------------------- + bool D3D9RenderSystem::_checkTextureFilteringSupported(TextureType ttype, PixelFormat format, int usage) + { + // Gets D3D format + D3DFORMAT d3dPF = D3D9Mappings::_getPF(format); + if (d3dPF == D3DFMT_UNKNOWN) + return false; + + for (uint i = 0; i < mDeviceManager->getDeviceCount(); ++i) + { + D3D9Device* currDevice = mDeviceManager->getDevice(i); + D3D9RenderWindow* currDevicePrimaryWindow = currDevice->getPrimaryWindow(); + IDirect3DSurface9* pSurface = currDevicePrimaryWindow->getRenderSurface(); + D3DSURFACE_DESC srfDesc; + + // Get surface desc + if (FAILED(pSurface->GetDesc(&srfDesc))) + return false; + + // Calculate usage + DWORD d3dusage = D3DUSAGE_QUERY_FILTER; + if (usage & TU_RENDERTARGET) + d3dusage |= D3DUSAGE_RENDERTARGET; + if (usage & TU_DYNAMIC) + d3dusage |= D3DUSAGE_DYNAMIC; + + // Detect resource type + D3DRESOURCETYPE rtype; + switch(ttype) + { + case TEX_TYPE_1D: + case TEX_TYPE_2D: + rtype = D3DRTYPE_TEXTURE; + break; + case TEX_TYPE_3D: + rtype = D3DRTYPE_VOLUMETEXTURE; + break; + case TEX_TYPE_CUBE_MAP: + rtype = D3DRTYPE_CUBETEXTURE; + break; + default: + return false; + } + + HRESULT hr = mD3D->CheckDeviceFormat( + currDevice->getAdapterNumber(), + currDevice->getDeviceType(), + srfDesc.Format, + d3dusage, + rtype, + d3dPF); + + if (FAILED(hr)) + return false; + } + + return true; + } + //----------------------------------------------------------------------- + MultiRenderTarget * D3D9RenderSystem::createMultiRenderTarget(const String & name) + { + MultiRenderTarget *retval; + retval = OGRE_NEW D3D9MultiRenderTarget(name); + attachRenderTarget(*retval); + + return retval; + } + //--------------------------------------------------------------------- + RenderTarget* D3D9RenderSystem::detachRenderTarget(const String &name) + { + RenderTarget* target = RenderSystem::detachRenderTarget(name); + detachRenderTargetImpl(name); + return target; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::detachRenderTargetImpl(const String& name) + { + // Check render windows + D3D9RenderWindowList::iterator sw; + for (sw = mRenderWindows.begin(); sw != mRenderWindows.end(); ++sw) + { + if ((*sw)->getName() == name) + { + mRenderWindows.erase(sw); + break; + } + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::destroyRenderTarget(const String& name) + { + detachRenderTargetImpl(name); + + // Do the real removal + RenderSystem::destroyRenderTarget(name); + } + //--------------------------------------------------------------------- + String D3D9RenderSystem::getErrorDescription( long errorNumber ) const + { + const String errMsg = DXGetErrorDescription( errorNumber ); + return errMsg; + } + //--------------------------------------------------------------------- + VertexElementType D3D9RenderSystem::getColourVertexElementType() const + { + return VET_COLOUR_ARGB; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_convertProjectionMatrix(const Matrix4& matrix, + Matrix4& dest, bool forGpuProgram) + { + dest = matrix; + + // Convert depth range from [-1,+1] to [0,1] + dest[2][0] = (dest[2][0] + dest[3][0]) / 2; + dest[2][1] = (dest[2][1] + dest[3][1]) / 2; + dest[2][2] = (dest[2][2] + dest[3][2]) / 2; + dest[2][3] = (dest[2][3] + dest[3][3]) / 2; + + if (!forGpuProgram) + { + // Convert right-handed to left-handed + dest[0][2] = -dest[0][2]; + dest[1][2] = -dest[1][2]; + dest[2][2] = -dest[2][2]; + dest[3][2] = -dest[3][2]; + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, + Real farPlane, Matrix4& dest, bool forGpuProgram) + { + Radian theta ( fovy * 0.5 ); + Real h = 1 / Math::Tan(theta); + Real w = h / aspect; + Real q, qn; + if (farPlane == 0) + { + q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST; + qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 1); + } + else + { + q = farPlane / ( farPlane - nearPlane ); + qn = -q * nearPlane; + } + + dest = Matrix4::ZERO; + dest[0][0] = w; + dest[1][1] = h; + + if (forGpuProgram) + { + dest[2][2] = -q; + dest[3][2] = -1.0f; + } + else + { + dest[2][2] = q; + dest[3][2] = 1.0f; + } + + dest[2][3] = qn; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, + Matrix4& dest, bool forGpuProgram ) + { + Radian thetaY (fovy / 2.0f); + Real tanThetaY = Math::Tan(thetaY); + + //Real thetaX = thetaY * aspect; + Real tanThetaX = tanThetaY * aspect; //Math::Tan(thetaX); + Real half_w = tanThetaX * nearPlane; + Real half_h = tanThetaY * nearPlane; + Real iw = static_cast(1.0 / half_w); + Real ih = static_cast(1.0 / half_h); + Real q; + if (farPlane == 0) + { + q = 0; + } + else + { + q = static_cast(1.0 / (farPlane - nearPlane)); + } + + dest = Matrix4::ZERO; + dest[0][0] = iw; + dest[1][1] = ih; + dest[2][2] = q; + dest[2][3] = -nearPlane / (farPlane - nearPlane); + dest[3][3] = 1; + + if (forGpuProgram) + { + dest[2][2] = -dest[2][2]; + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setAmbientLight( float r, float g, float b ) + { + HRESULT hr = __SetRenderState( D3DRS_AMBIENT, D3DCOLOR_COLORVALUE( r, g, b, 1.0f ) ); + if( FAILED( hr ) ) + OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, + "Failed to set render stat D3DRS_AMBIENT", "D3D9RenderSystem::setAmbientLight" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_useLights(const LightList& lights, unsigned short limit) + { + IDirect3DDevice9* activeDevice = getActiveD3D9Device(); + LightList::const_iterator i, iend; + iend = lights.end(); + unsigned short num = 0; + for (i = lights.begin(); i != iend && num < limit; ++i, ++num) + { + setD3D9Light(num, *i); + } + // Disable extra lights + for (; num < mCurrentLights[activeDevice]; ++num) + { + setD3D9Light(num, NULL); + } + mCurrentLights[activeDevice] = std::min(limit, static_cast(lights.size())); + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setShadingType( ShadeOptions so ) + { + HRESULT hr = __SetRenderState( D3DRS_SHADEMODE, D3D9Mappings::get(so) ); + if( FAILED( hr ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Failed to set render stat D3DRS_SHADEMODE", "D3D9RenderSystem::setShadingType" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setLightingEnabled( bool enabled ) + { + HRESULT hr; + if( FAILED( hr = __SetRenderState( D3DRS_LIGHTING, enabled ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Failed to set render state D3DRS_LIGHTING", "D3D9RenderSystem::setLightingEnabled" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setD3D9Light( size_t index, Light* lt ) + { + HRESULT hr; + + D3DLIGHT9 d3dLight; + ZeroMemory( &d3dLight, sizeof(d3dLight) ); + + if (!lt) + { + if( FAILED( hr = getActiveD3D9Device()->LightEnable( static_cast(index), FALSE) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to disable light", "D3D9RenderSystem::setD3D9Light" ); + } + else + { + switch( lt->getType() ) + { + case Light::LT_POINT: + d3dLight.Type = D3DLIGHT_POINT; + break; + + case Light::LT_DIRECTIONAL: + d3dLight.Type = D3DLIGHT_DIRECTIONAL; + break; + + case Light::LT_SPOTLIGHT: + d3dLight.Type = D3DLIGHT_SPOT; + d3dLight.Falloff = lt->getSpotlightFalloff(); + d3dLight.Theta = lt->getSpotlightInnerAngle().valueRadians(); + d3dLight.Phi = lt->getSpotlightOuterAngle().valueRadians(); + break; + } + + ColourValue col; + col = lt->getDiffuseColour(); + d3dLight.Diffuse = D3DXCOLOR( col.r, col.g, col.b, col.a ); + + col = lt->getSpecularColour(); + d3dLight.Specular = D3DXCOLOR( col.r, col.g, col.b, col.a ); + + Vector3 vec; + if( lt->getType() != Light::LT_DIRECTIONAL ) + { + vec = lt->getDerivedPosition(true); + d3dLight.Position = D3DXVECTOR3( vec.x, vec.y, vec.z ); + } + if( lt->getType() != Light::LT_POINT ) + { + vec = lt->getDerivedDirection(); + d3dLight.Direction = D3DXVECTOR3( vec.x, vec.y, vec.z ); + } + + d3dLight.Range = lt->getAttenuationRange(); + d3dLight.Attenuation0 = lt->getAttenuationConstant(); + d3dLight.Attenuation1 = lt->getAttenuationLinear(); + d3dLight.Attenuation2 = lt->getAttenuationQuadric(); + + if( FAILED( hr = getActiveD3D9Device()->SetLight( static_cast(index), &d3dLight ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set light details", "D3D9RenderSystem::setD3D9Light" ); + + if( FAILED( hr = getActiveD3D9Device()->LightEnable( static_cast(index), TRUE ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to enable light", "D3D9RenderSystem::setD3D9Light" ); + } + + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setViewMatrix( const Matrix4 &m ) + { + // save latest view matrix + mViewMatrix = m; + mViewMatrix[2][0] = -mViewMatrix[2][0]; + mViewMatrix[2][1] = -mViewMatrix[2][1]; + mViewMatrix[2][2] = -mViewMatrix[2][2]; + mViewMatrix[2][3] = -mViewMatrix[2][3]; + + mDxViewMat = D3D9Mappings::makeD3DXMatrix( mViewMatrix ); + + HRESULT hr; + if( FAILED( hr = getActiveD3D9Device()->SetTransform( D3DTS_VIEW, &mDxViewMat ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot set D3D9 view matrix", "D3D9RenderSystem::_setViewMatrix" ); + + // also mark clip planes dirty + if (!mClipPlanes.empty()) + mClipPlanesDirty = true; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setProjectionMatrix( const Matrix4 &m ) + { + // save latest matrix + mDxProjMat = D3D9Mappings::makeD3DXMatrix( m ); + + if( mActiveRenderTarget->requiresTextureFlipping() ) + { + // Invert transformed y + mDxProjMat._12 = - mDxProjMat._12; + mDxProjMat._22 = - mDxProjMat._22; + mDxProjMat._32 = - mDxProjMat._32; + mDxProjMat._42 = - mDxProjMat._42; + } + + HRESULT hr; + if( FAILED( hr = getActiveD3D9Device()->SetTransform( D3DTS_PROJECTION, &mDxProjMat ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot set D3D9 projection matrix", "D3D9RenderSystem::_setProjectionMatrix" ); + + // also mark clip planes dirty + if (!mClipPlanes.empty()) + mClipPlanesDirty = true; + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setWorldMatrix( const Matrix4 &m ) + { + // save latest matrix + mDxWorldMat = D3D9Mappings::makeD3DXMatrix( m ); + + HRESULT hr; + if( FAILED( hr = getActiveD3D9Device()->SetTransform( D3DTS_WORLD, &mDxWorldMat ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot set D3D9 world matrix", "D3D9RenderSystem::_setWorldMatrix" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setSurfaceParams( const ColourValue &ambient, const ColourValue &diffuse, + const ColourValue &specular, const ColourValue &emissive, Real shininess, + TrackVertexColourType tracking ) + { + + D3DMATERIAL9 material; + material.Diffuse = D3DXCOLOR( diffuse.r, diffuse.g, diffuse.b, diffuse.a ); + material.Ambient = D3DXCOLOR( ambient.r, ambient.g, ambient.b, ambient.a ); + material.Specular = D3DXCOLOR( specular.r, specular.g, specular.b, specular.a ); + material.Emissive = D3DXCOLOR( emissive.r, emissive.g, emissive.b, emissive.a ); + material.Power = shininess; + + HRESULT hr = getActiveD3D9Device()->SetMaterial( &material ); + if( FAILED( hr ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting D3D material", "D3D9RenderSystem::_setSurfaceParams" ); + + + if(tracking != TVC_NONE) + { + __SetRenderState(D3DRS_COLORVERTEX, TRUE); + __SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, (tracking&TVC_AMBIENT)?D3DMCS_COLOR1:D3DMCS_MATERIAL); + __SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, (tracking&TVC_DIFFUSE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); + __SetRenderState(D3DRS_SPECULARMATERIALSOURCE, (tracking&TVC_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL); + __SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, (tracking&TVC_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); + } + else + { + __SetRenderState(D3DRS_COLORVERTEX, FALSE); + } + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setPointParameters(Real size, + bool attenuationEnabled, Real constant, Real linear, Real quadratic, + Real minSize, Real maxSize) + { + if(attenuationEnabled) + { + // scaling required + __SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); + __SetFloatRenderState(D3DRS_POINTSCALE_A, constant); + __SetFloatRenderState(D3DRS_POINTSCALE_B, linear); + __SetFloatRenderState(D3DRS_POINTSCALE_C, quadratic); + } + else + { + // no scaling required + __SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); + } + __SetFloatRenderState(D3DRS_POINTSIZE, size); + __SetFloatRenderState(D3DRS_POINTSIZE_MIN, minSize); + if (maxSize == 0.0f) + maxSize = mCurrentCapabilities->getMaxPointSize(); + __SetFloatRenderState(D3DRS_POINTSIZE_MAX, maxSize); + + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setPointSpritesEnabled(bool enabled) + { + if (enabled) + { + __SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); + } + else + { + __SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTexture( size_t stage, bool enabled, const TexturePtr& tex ) + { + HRESULT hr; + D3D9TexturePtr dt = tex.staticCast(); + if (enabled && !dt.isNull()) + { + // note used + dt->touch(); + + IDirect3DBaseTexture9 *pTex = dt->getTexture(); + if (mTexStageDesc[stage].pTex != pTex) + { + hr = getActiveD3D9Device()->SetTexture(static_cast(stage), pTex); + if( hr != S_OK ) + { + String str = "Unable to set texture '" + tex->getName() + "' in D3D9"; + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9RenderSystem::_setTexture" ); + } + + // set stage desc. + mTexStageDesc[stage].pTex = pTex; + mTexStageDesc[stage].texType = D3D9Mappings::get(dt->getTextureType()); + + // Set gamma now too + if (dt->isHardwareGammaReadToBeUsed()) + { + __SetSamplerState(getSamplerId(stage), D3DSAMP_SRGBTEXTURE, TRUE); + } + else + { + __SetSamplerState(getSamplerId(stage), D3DSAMP_SRGBTEXTURE, FALSE); + } + } + } + else + { + if (mTexStageDesc[stage].pTex != 0) + { + hr = getActiveD3D9Device()->SetTexture(static_cast(stage), 0); + if( hr != S_OK ) + { + String str = "Unable to disable texture '" + StringConverter::toString(stage) + "' in D3D9"; + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9RenderSystem::_setTexture" ); + } + } + + hr = __SetTextureStageState(static_cast(stage), D3DTSS_COLOROP, D3DTOP_DISABLE); + if( hr != S_OK ) + { + String str = "Unable to disable texture '" + StringConverter::toString(stage) + "' in D3D9"; + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9RenderSystem::_setTexture" ); + } + + // set stage desc. to defaults + mTexStageDesc[stage].pTex = 0; + mTexStageDesc[stage].autoTexCoordType = TEXCALC_NONE; + mTexStageDesc[stage].coordIndex = 0; + mTexStageDesc[stage].texType = D3D9Mappings::D3D_TEX_TYPE_NORMAL; + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setVertexTexture(size_t stage, const TexturePtr& tex) + { + if (tex.isNull()) + { + + if (mTexStageDesc[stage].pVertexTex != 0) + { + HRESULT hr = getActiveD3D9Device()->SetTexture(D3DVERTEXTEXTURESAMPLER0 + static_cast(stage), 0); + if( hr != S_OK ) + { + String str = "Unable to disable vertex texture '" + + StringConverter::toString(stage) + "' in D3D9"; + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9RenderSystem::_setVertexTexture" ); + } + } + + // set stage desc. to defaults + mTexStageDesc[stage].pVertexTex = 0; + } + else + { + D3D9TexturePtr dt = tex.staticCast(); + // note used + dt->touch(); + + IDirect3DBaseTexture9 *pTex = dt->getTexture(); + if (mTexStageDesc[stage].pVertexTex != pTex) + { + HRESULT hr = getActiveD3D9Device()->SetTexture(D3DVERTEXTEXTURESAMPLER0 + static_cast(stage), pTex); + if( hr != S_OK ) + { + String str = "Unable to set vertex texture '" + tex->getName() + "' in D3D9"; + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9RenderSystem::_setVertexTexture" ); + } + + // set stage desc. + mTexStageDesc[stage].pVertexTex = pTex; + } + + } + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_disableTextureUnit(size_t texUnit) + { + RenderSystem::_disableTextureUnit(texUnit); + // also disable vertex texture unit + static TexturePtr nullPtr; + _setVertexTexture(texUnit, nullPtr); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureCoordSet( size_t stage, size_t index ) + { + // if vertex shader is being used, stage and index must match + if (mVertexProgramBound) + index = stage; + + HRESULT hr; + // Record settings + mTexStageDesc[stage].coordIndex = index; + + if (mVertexProgramBound) + hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXCOORDINDEX, index ); + else + hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXCOORDINDEX, D3D9Mappings::get(mTexStageDesc[stage].autoTexCoordType, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) | index ); + if( FAILED( hr ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set texture coord. set index", "D3D9RenderSystem::_setTextureCoordSet" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureCoordCalculation( size_t stage, TexCoordCalcMethod m, + const Frustum* frustum) + { + HRESULT hr; + // record the stage state + mTexStageDesc[stage].autoTexCoordType = m; + mTexStageDesc[stage].frustum = frustum; + + if (mVertexProgramBound) + hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXCOORDINDEX, mTexStageDesc[stage].coordIndex ); + else + hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXCOORDINDEX, D3D9Mappings::get(m, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) | mTexStageDesc[stage].coordIndex ); + if(FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set texture auto tex.coord. generation mode", "D3D9RenderSystem::_setTextureCoordCalculation" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureMipmapBias(size_t unit, float bias) + { + if (mCurrentCapabilities->hasCapability(RSC_MIPMAP_LOD_BIAS)) + { + // ugh - have to pass float data through DWORD with no conversion + HRESULT hr = __SetSamplerState(getSamplerId(unit), D3DSAMP_MIPMAPLODBIAS, + *(DWORD*)&bias); + if(FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set texture mipmap bias", + "D3D9RenderSystem::_setTextureMipmapBias" ); + + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureMatrix( size_t stage, const Matrix4& xForm ) + { + HRESULT hr; + D3DXMATRIX d3dMat; // the matrix we'll maybe apply + Matrix4 newMat = xForm; // the matrix we'll apply after conv. to D3D format + // Cache texcoord calc method to register + TexCoordCalcMethod autoTexCoordType = mTexStageDesc[stage].autoTexCoordType; + + // if a vertex program is bound, we mustn't set texture transforms + if (mVertexProgramBound) + { + hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + if( FAILED( hr ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to disable texture coordinate transform", "D3D9RenderSystem::_setTextureMatrix" ); + return; + } + + + if (autoTexCoordType == TEXCALC_ENVIRONMENT_MAP) + { + if (mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().VertexProcessingCaps & D3DVTXPCAPS_TEXGEN_SPHEREMAP) + { + /** Invert the texture for the spheremap */ + Matrix4 ogreMatEnvMap = Matrix4::IDENTITY; + // set env_map values + ogreMatEnvMap[1][1] = -1.0f; + // concatenate with the xForm + newMat = newMat.concatenate(ogreMatEnvMap); + } + else + { + /* If envmap is applied, but device doesn't support spheremap, + then we have to use texture transform to make the camera space normal + reference the envmap properly. This isn't exactly the same as spheremap + (it looks nasty on flat areas because the camera space normals are the same) + but it's the best approximation we have in the absence of a proper spheremap */ + // concatenate with the xForm + newMat = newMat.concatenate(Matrix4::CLIPSPACE2DTOIMAGESPACE); + } + } + + // If this is a cubic reflection, we need to modify using the view matrix + if (autoTexCoordType == TEXCALC_ENVIRONMENT_MAP_REFLECTION) + { + // Get transposed 3x3 + // We want to transpose since that will invert an orthonormal matrix ie rotation + Matrix4 ogreViewTransposed; + ogreViewTransposed[0][0] = mViewMatrix[0][0]; + ogreViewTransposed[0][1] = mViewMatrix[1][0]; + ogreViewTransposed[0][2] = mViewMatrix[2][0]; + ogreViewTransposed[0][3] = 0.0f; + + ogreViewTransposed[1][0] = mViewMatrix[0][1]; + ogreViewTransposed[1][1] = mViewMatrix[1][1]; + ogreViewTransposed[1][2] = mViewMatrix[2][1]; + ogreViewTransposed[1][3] = 0.0f; + + ogreViewTransposed[2][0] = mViewMatrix[0][2]; + ogreViewTransposed[2][1] = mViewMatrix[1][2]; + ogreViewTransposed[2][2] = mViewMatrix[2][2]; + ogreViewTransposed[2][3] = 0.0f; + + ogreViewTransposed[3][0] = 0.0f; + ogreViewTransposed[3][1] = 0.0f; + ogreViewTransposed[3][2] = 0.0f; + ogreViewTransposed[3][3] = 1.0f; + + newMat = newMat.concatenate(ogreViewTransposed); + } + + if (autoTexCoordType == TEXCALC_PROJECTIVE_TEXTURE) + { + // Derive camera space to projector space transform + // To do this, we need to undo the camera view matrix, then + // apply the projector view & projection matrices + newMat = mViewMatrix.inverse(); + if(mTexProjRelative) + { + Matrix4 viewMatrix; + mTexStageDesc[stage].frustum->calcViewMatrixRelative(mTexProjRelativeOrigin, viewMatrix); + newMat = viewMatrix * newMat; + } + else + { + newMat = mTexStageDesc[stage].frustum->getViewMatrix() * newMat; + } + newMat = mTexStageDesc[stage].frustum->getProjectionMatrix() * newMat; + newMat = Matrix4::CLIPSPACE2DTOIMAGESPACE * newMat; + newMat = xForm * newMat; + } + + // need this if texture is a cube map, to invert D3D's z coord + if (autoTexCoordType != TEXCALC_NONE && + autoTexCoordType != TEXCALC_PROJECTIVE_TEXTURE) + { + newMat[2][0] = -newMat[2][0]; + newMat[2][1] = -newMat[2][1]; + newMat[2][2] = -newMat[2][2]; + newMat[2][3] = -newMat[2][3]; + } + + // convert our matrix to D3D format + d3dMat = D3D9Mappings::makeD3DXMatrix(newMat); + + // set the matrix if it's not the identity + if (!D3DXMatrixIsIdentity(&d3dMat)) + { + /* It's seems D3D automatically add a texture coordinate with value 1, + and fill up the remaining texture coordinates with 0 for the input + texture coordinates before pass to texture coordinate transformation. + + NOTE: It's difference with D3DDECLTYPE enumerated type expand in + DirectX SDK documentation! + + So we should prepare the texcoord transform, make the transformation + just like standardized vector expand, thus, fill w with value 1 and + others with 0. + */ + if (autoTexCoordType == TEXCALC_NONE) + { + /* FIXME: The actually input texture coordinate dimensions should + be determine by texture coordinate vertex element. Now, just trust + user supplied texture type matches texture coordinate vertex element. + */ + if (mTexStageDesc[stage].texType == D3D9Mappings::D3D_TEX_TYPE_NORMAL) + { + /* It's 2D input texture coordinate: + + texcoord in vertex buffer D3D expanded to We are adjusted to + --> --> + (u, v) (u, v, 1, 0) (u, v, 0, 1) + */ + std::swap(d3dMat._31, d3dMat._41); + std::swap(d3dMat._32, d3dMat._42); + std::swap(d3dMat._33, d3dMat._43); + std::swap(d3dMat._34, d3dMat._44); + } + } + else + { + // All texgen generate 3D input texture coordinates. + } + + // tell D3D the dimension of tex. coord. + int texCoordDim = D3DTTFF_COUNT2; + if (mTexStageDesc[stage].autoTexCoordType == TEXCALC_PROJECTIVE_TEXTURE) + { + /* We want texcoords (u, v, w, q) always get divided by q, but D3D + projected texcoords is divided by the last element (in the case of + 2D texcoord, is w). So we tweak the transform matrix, transform the + texcoords with w and q swapped: (u, v, q, w), and then D3D will + divide u, v by q. The w and q just ignored as it wasn't used by + rasterizer. + */ + switch (mTexStageDesc[stage].texType) + { + case D3D9Mappings::D3D_TEX_TYPE_NORMAL: + std::swap(d3dMat._13, d3dMat._14); + std::swap(d3dMat._23, d3dMat._24); + std::swap(d3dMat._33, d3dMat._34); + std::swap(d3dMat._43, d3dMat._44); + + texCoordDim = D3DTTFF_PROJECTED | D3DTTFF_COUNT3; + break; + + case D3D9Mappings::D3D_TEX_TYPE_CUBE: + case D3D9Mappings::D3D_TEX_TYPE_VOLUME: + // Yes, we support 3D projective texture. + texCoordDim = D3DTTFF_PROJECTED | D3DTTFF_COUNT4; + break; + } + } + else + { + switch (mTexStageDesc[stage].texType) + { + case D3D9Mappings::D3D_TEX_TYPE_NORMAL: + texCoordDim = D3DTTFF_COUNT2; + break; + case D3D9Mappings::D3D_TEX_TYPE_CUBE: + case D3D9Mappings::D3D_TEX_TYPE_VOLUME: + texCoordDim = D3DTTFF_COUNT3; + break; + } + } + + hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXTURETRANSFORMFLAGS, texCoordDim ); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set texture coord. dimension", "D3D9RenderSystem::_setTextureMatrix" ); + + hr = getActiveD3D9Device()->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + stage), &d3dMat ); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set texture matrix", "D3D9RenderSystem::_setTextureMatrix" ); + } + else + { + // disable all of this + hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); + if( FAILED( hr ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to disable texture coordinate transform", "D3D9RenderSystem::_setTextureMatrix" ); + + // Needless to sets texture transform here, it's never used at all + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureAddressingMode( size_t stage, + const TextureUnitState::UVWAddressingMode& uvw ) + { + HRESULT hr; + if( FAILED( hr = __SetSamplerState( getSamplerId(stage), D3DSAMP_ADDRESSU, D3D9Mappings::get(uvw.u, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set texture addressing mode for U", "D3D9RenderSystem::_setTextureAddressingMode" ); + if( FAILED( hr = __SetSamplerState( getSamplerId(stage), D3DSAMP_ADDRESSV, D3D9Mappings::get(uvw.v, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set texture addressing mode for V", "D3D9RenderSystem::_setTextureAddressingMode" ); + if( FAILED( hr = __SetSamplerState( getSamplerId(stage), D3DSAMP_ADDRESSW, D3D9Mappings::get(uvw.w, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set texture addressing mode for W", "D3D9RenderSystem::_setTextureAddressingMode" ); + } + //----------------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureBorderColour(size_t stage, + const ColourValue& colour) + { + HRESULT hr; + if( FAILED( hr = __SetSamplerState( getSamplerId(stage), D3DSAMP_BORDERCOLOR, colour.getAsARGB()) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set texture border colour", "D3D9RenderSystem::_setTextureBorderColour" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureBlendMode( size_t stage, const LayerBlendModeEx& bm ) + { + HRESULT hr = S_OK; + D3DTEXTURESTAGESTATETYPE tss; + D3DCOLOR manualD3D; + + // choose type of blend. + if( bm.blendType == LBT_COLOUR ) + tss = D3DTSS_COLOROP; + else if( bm.blendType == LBT_ALPHA ) + tss = D3DTSS_ALPHAOP; + else + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid blend type", "D3D9RenderSystem::_setTextureBlendMode"); + + // set manual factor if required by operation + if (bm.operation == LBX_BLEND_MANUAL) + { + hr = __SetRenderState( D3DRS_TEXTUREFACTOR, D3DXCOLOR(0.0, 0.0, 0.0, bm.factor) ); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set manual factor", "D3D9RenderSystem::_setTextureBlendMode" ); + } + // set operation + hr = __SetTextureStageState( static_cast(stage), tss, D3D9Mappings::get(bm.operation, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) ); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set operation", "D3D9RenderSystem::_setTextureBlendMode" ); + + // choose source 1 + if( bm.blendType == LBT_COLOUR ) + { + tss = D3DTSS_COLORARG1; + manualD3D = D3DXCOLOR( bm.colourArg1.r, bm.colourArg1.g, bm.colourArg1.b, bm.colourArg1.a ); + mManualBlendColours[stage][0] = bm.colourArg1; + } + else if( bm.blendType == LBT_ALPHA ) + { + tss = D3DTSS_ALPHAARG1; + manualD3D = D3DXCOLOR( mManualBlendColours[stage][0].r, + mManualBlendColours[stage][0].g, + mManualBlendColours[stage][0].b, bm.alphaArg1 ); + } + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid blend type", "D3D9RenderSystem::_setTextureBlendMode"); + } + // Set manual factor if required + if (bm.source1 == LBS_MANUAL) + { + if (mCurrentCapabilities->hasCapability(RSC_PERSTAGECONSTANT)) + { + // Per-stage state + hr = __SetTextureStageState(static_cast(stage), D3DTSS_CONSTANT, manualD3D); + } + else + { + // Global state + hr = __SetRenderState( D3DRS_TEXTUREFACTOR, manualD3D ); + } + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set manual factor", "D3D9RenderSystem::_setTextureBlendMode" ); + } + // set source 1 + hr = __SetTextureStageState( static_cast(stage), tss, D3D9Mappings::get(bm.source1, mCurrentCapabilities->hasCapability(RSC_PERSTAGECONSTANT)) ); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set source1", "D3D9RenderSystem::_setTextureBlendMode" ); + + // choose source 2 + if( bm.blendType == LBT_COLOUR ) + { + tss = D3DTSS_COLORARG2; + manualD3D = D3DXCOLOR( bm.colourArg2.r, bm.colourArg2.g, bm.colourArg2.b, bm.colourArg2.a ); + mManualBlendColours[stage][1] = bm.colourArg2; + } + else if( bm.blendType == LBT_ALPHA ) + { + tss = D3DTSS_ALPHAARG2; + manualD3D = D3DXCOLOR( mManualBlendColours[stage][1].r, + mManualBlendColours[stage][1].g, + mManualBlendColours[stage][1].b, + bm.alphaArg2 ); + } + // Set manual factor if required + if (bm.source2 == LBS_MANUAL) + { + if (mCurrentCapabilities->hasCapability(RSC_PERSTAGECONSTANT)) + { + // Per-stage state + hr = __SetTextureStageState(static_cast(stage), D3DTSS_CONSTANT, manualD3D); + } + else + { + hr = __SetRenderState( D3DRS_TEXTUREFACTOR, manualD3D ); + } + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set manual factor", "D3D9RenderSystem::_setTextureBlendMode" ); + } + // Now set source 2 + hr = __SetTextureStageState( static_cast(stage), tss, D3D9Mappings::get(bm.source2, mCurrentCapabilities->hasCapability(RSC_PERSTAGECONSTANT)) ); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set source 2", "D3D9RenderSystem::_setTextureBlendMode" ); + + // Set interpolation factor if lerping + if (bm.operation == LBX_BLEND_DIFFUSE_COLOUR && + mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().TextureOpCaps & D3DTEXOPCAPS_LERP) + { + // choose source 0 (lerp factor) + if( bm.blendType == LBT_COLOUR ) + { + tss = D3DTSS_COLORARG0; + } + else if( bm.blendType == LBT_ALPHA ) + { + tss = D3DTSS_ALPHAARG0; + } + hr = __SetTextureStageState(static_cast(stage), tss, D3DTA_DIFFUSE); + + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set lerp source 0", + "D3D9RenderSystem::_setTextureBlendMode" ); + + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op ) + { + HRESULT hr; + if( sourceFactor == SBF_ONE && destFactor == SBF_ZERO) + { + if (FAILED(hr = __SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE))) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha blending option", "D3D9RenderSystem::_setSceneBlending" ); + } + else + { + if (FAILED(hr = __SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE))) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha blending option", "D3D9RenderSystem::_setSceneBlending" ); + if (FAILED(hr = __SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE))) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set separate alpha blending option", "D3D9RenderSystem::_setSceneBlending" ); + if( FAILED( hr = __SetRenderState( D3DRS_SRCBLEND, D3D9Mappings::get(sourceFactor) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set source blend", "D3D9RenderSystem::_setSceneBlending" ); + if( FAILED( hr = __SetRenderState( D3DRS_DESTBLEND, D3D9Mappings::get(destFactor) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set destination blend", "D3D9RenderSystem::_setSceneBlending" ); + } + + if (FAILED(hr = __SetRenderState(D3DRS_BLENDOP, D3D9Mappings::get(op)))) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set scene blending operation option", "D3D9RenderSystem::_setSceneBlendingOperation" ); + if (FAILED(hr = __SetRenderState(D3DRS_BLENDOPALPHA, D3D9Mappings::get(op)))) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set scene blending operation option", "D3D9RenderSystem::_setSceneBlendingOperation" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, + SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ) + { + HRESULT hr; + if( sourceFactor == SBF_ONE && destFactor == SBF_ZERO && + sourceFactorAlpha == SBF_ONE && destFactorAlpha == SBF_ZERO) + { + if (FAILED(hr = __SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE))) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha blending option", "D3D9RenderSystem::_setSceneBlending" ); + } + else + { + if (FAILED(hr = __SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE))) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha blending option", "D3D9RenderSystem::_setSeperateSceneBlending" ); + if (FAILED(hr = __SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE))) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set separate alpha blending option", "D3D9RenderSystem::_setSeperateSceneBlending" ); + if( FAILED( hr = __SetRenderState( D3DRS_SRCBLEND, D3D9Mappings::get(sourceFactor) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set source blend", "D3D9RenderSystem::_setSeperateSceneBlending" ); + if( FAILED( hr = __SetRenderState( D3DRS_DESTBLEND, D3D9Mappings::get(destFactor) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set destination blend", "D3D9RenderSystem::_setSeperateSceneBlending" ); + if( FAILED( hr = __SetRenderState( D3DRS_SRCBLENDALPHA, D3D9Mappings::get(sourceFactorAlpha) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha source blend", "D3D9RenderSystem::_setSeperateSceneBlending" ); + if( FAILED( hr = __SetRenderState( D3DRS_DESTBLENDALPHA, D3D9Mappings::get(destFactorAlpha) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha destination blend", "D3D9RenderSystem::_setSeperateSceneBlending" ); + } + + if (FAILED(hr = __SetRenderState(D3DRS_BLENDOP, D3D9Mappings::get(op)))) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set scene blending operation option", "D3D9RenderSystem::_setSceneBlendingOperation" ); + if (FAILED(hr = __SetRenderState(D3DRS_BLENDOPALPHA, D3D9Mappings::get(alphaOp)))) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha scene blending operation option", "D3D9RenderSystem::_setSceneBlendingOperation" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ) + { + HRESULT hr; + bool a2c = false; + static bool lasta2c = false; + + if (func != CMPF_ALWAYS_PASS) + { + if( FAILED( hr = __SetRenderState( D3DRS_ALPHATESTENABLE, TRUE ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to enable alpha testing", + "D3D9RenderSystem::_setAlphaRejectSettings" ); + + a2c = alphaToCoverage; + } + else + { + if( FAILED( hr = __SetRenderState( D3DRS_ALPHATESTENABLE, FALSE ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to disable alpha testing", + "D3D9RenderSystem::_setAlphaRejectSettings" ); + } + // Set always just be sure + if( FAILED( hr = __SetRenderState( D3DRS_ALPHAFUNC, D3D9Mappings::get(func) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha reject function", "D3D9RenderSystem::_setAlphaRejectSettings" ); + if( FAILED( hr = __SetRenderState( D3DRS_ALPHAREF, value ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set render state D3DRS_ALPHAREF", "D3D9RenderSystem::_setAlphaRejectSettings" ); + + // Alpha to coverage + if (getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE)) + { + // Vendor-specific hacks on renderstate, gotta love 'em + if (getCapabilities()->getVendor() == GPU_NVIDIA) + { + if (a2c) + { + if( FAILED( hr = __SetRenderState( D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C') ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha to coverage option", "D3D9RenderSystem::_setAlphaRejectSettings" ); + } + else + { + if( FAILED( hr = __SetRenderState( D3DRS_ADAPTIVETESS_Y, D3DFMT_UNKNOWN ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha to coverage option", "D3D9RenderSystem::_setAlphaRejectSettings" ); + } + + } + else if ((getCapabilities()->getVendor() == GPU_AMD)) + { + if (a2c) + { + if( FAILED( hr = __SetRenderState( D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','1') ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha to coverage option", "D3D9RenderSystem::_setAlphaRejectSettings" ); + } + else + { + // discovered this through trial and error, seems to work + if( FAILED( hr = __SetRenderState( D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','0') ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha to coverage option", "D3D9RenderSystem::_setAlphaRejectSettings" ); + } + } + // no hacks available for any other vendors? + lasta2c = a2c; + } + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setCullingMode( CullingMode mode ) + { + mCullingMode = mode; + HRESULT hr; + bool flip = ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) || + (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)); + + if( FAILED (hr = __SetRenderState(D3DRS_CULLMODE, + D3D9Mappings::get(mode, flip))) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set culling mode", "D3D9RenderSystem::_setCullingMode" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setDepthBufferParams( bool depthTest, bool depthWrite, CompareFunction depthFunction ) + { + _setDepthBufferCheckEnabled( depthTest ); + _setDepthBufferWriteEnabled( depthWrite ); + _setDepthBufferFunction( depthFunction ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setDepthBufferCheckEnabled( bool enabled ) + { + HRESULT hr; + + if( enabled ) + { + // Use w-buffer if available and enabled + if( mWBuffer && mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_WBUFFER ) + hr = __SetRenderState( D3DRS_ZENABLE, D3DZB_USEW ); + else + hr = __SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); + } + else + hr = __SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE ); + + if( FAILED( hr ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting depth buffer test state", "D3D9RenderSystem::_setDepthBufferCheckEnabled" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setDepthBufferWriteEnabled( bool enabled ) + { + HRESULT hr; + + if( FAILED( hr = __SetRenderState( D3DRS_ZWRITEENABLE, enabled ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting depth buffer write state", "D3D9RenderSystem::_setDepthBufferWriteEnabled" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setDepthBufferFunction( CompareFunction func ) + { + HRESULT hr; + if( FAILED( hr = __SetRenderState( D3DRS_ZFUNC, D3D9Mappings::get(func) ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting depth buffer test function", "D3D9RenderSystem::_setDepthBufferFunction" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setDepthBias(float constantBias, float slopeScaleBias) + { + + if ((mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0) + { + // Negate bias since D3D is backward + // D3D also expresses the constant bias as an absolute value, rather than + // relative to minimum depth unit, so scale to fit + constantBias = -constantBias / 250000.0f; + HRESULT hr = __SetRenderState(D3DRS_DEPTHBIAS, FLOAT2DWORD(constantBias)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting constant depth bias", + "D3D9RenderSystem::_setDepthBias"); + } + + if ((mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) != 0) + { + // Negate bias since D3D is backward + slopeScaleBias = -slopeScaleBias; + HRESULT hr = __SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FLOAT2DWORD(slopeScaleBias)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting slope scale depth bias", + "D3D9RenderSystem::_setDepthBias"); + } + + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setColourBufferWriteEnabled(bool red, bool green, + bool blue, bool alpha) + { + DWORD val = 0; + if (red) + val |= D3DCOLORWRITEENABLE_RED; + if (green) + val |= D3DCOLORWRITEENABLE_GREEN; + if (blue) + val |= D3DCOLORWRITEENABLE_BLUE; + if (alpha) + val |= D3DCOLORWRITEENABLE_ALPHA; + HRESULT hr = __SetRenderState(D3DRS_COLORWRITEENABLE, val); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting colour write enable flags", + "D3D9RenderSystem::_setColourBufferWriteEnabled"); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setFog( FogMode mode, const ColourValue& colour, Real densitiy, Real start, Real end ) + { + HRESULT hr; + + D3DRENDERSTATETYPE fogType, fogTypeNot; + + if (mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_FOGTABLE) + { + fogType = D3DRS_FOGTABLEMODE; + fogTypeNot = D3DRS_FOGVERTEXMODE; + } + else + { + fogType = D3DRS_FOGVERTEXMODE; + fogTypeNot = D3DRS_FOGTABLEMODE; + } + + if( mode == FOG_NONE) + { + // just disable + hr = __SetRenderState(fogType, D3DFOG_NONE ); + hr = __SetRenderState(D3DRS_FOGENABLE, FALSE); + } + else + { + // Allow fog + hr = __SetRenderState( D3DRS_FOGENABLE, TRUE ); + hr = __SetRenderState( fogTypeNot, D3DFOG_NONE ); + hr = __SetRenderState( fogType, D3D9Mappings::get(mode) ); + + hr = __SetRenderState( D3DRS_FOGCOLOR, colour.getAsARGB() ); + hr = __SetFloatRenderState( D3DRS_FOGSTART, start ); + hr = __SetFloatRenderState( D3DRS_FOGEND, end ); + hr = __SetFloatRenderState( D3DRS_FOGDENSITY, densitiy ); + } + + if( FAILED( hr ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting render state", "D3D9RenderSystem::_setFog" ); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setPolygonMode(PolygonMode level) + { + HRESULT hr = __SetRenderState(D3DRS_FILLMODE, D3D9Mappings::get(level)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting polygon mode.", "D3D9RenderSystem::setPolygonMode"); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setStencilCheckEnabled(bool enabled) + { + // Allow stencilling + HRESULT hr = __SetRenderState(D3DRS_STENCILENABLE, enabled); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error enabling / disabling stencilling.", + "D3D9RenderSystem::setStencilCheckEnabled"); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setStencilBufferParams(CompareFunction func, + uint32 refValue, uint32 compareMask, uint32 writeMask, StencilOperation stencilFailOp, + StencilOperation depthFailOp, StencilOperation passOp, + bool twoSidedOperation, bool readBackAsTexture) + { + HRESULT hr; + bool flip; + + // 2-sided operation + if (twoSidedOperation) + { + if (!mCurrentCapabilities->hasCapability(RSC_TWO_SIDED_STENCIL)) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "2-sided stencils are not supported", + "D3D9RenderSystem::setStencilBufferParams"); + hr = __SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting 2-sided stencil mode.", + "D3D9RenderSystem::setStencilBufferParams"); + // NB: We should always treat CCW as front face for consistent with default + // culling mode. Therefore, we must take care with two-sided stencil settings. + flip = (mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping()) || + (!mInvertVertexWinding && !mActiveRenderTarget->requiresTextureFlipping()); + + // Set alternative versions of ops + // fail op + hr = __SetRenderState(D3DRS_CCW_STENCILFAIL, D3D9Mappings::get(stencilFailOp, !flip)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil fail operation (2-sided).", + "D3D9RenderSystem::setStencilBufferParams"); + + // depth fail op + hr = __SetRenderState(D3DRS_CCW_STENCILZFAIL, D3D9Mappings::get(depthFailOp, !flip)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil depth fail operation (2-sided).", + "D3D9RenderSystem::setStencilBufferParams"); + + // pass op + hr = __SetRenderState(D3DRS_CCW_STENCILPASS, D3D9Mappings::get(passOp, !flip)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil pass operation (2-sided).", + "D3D9RenderSystem::setStencilBufferParams"); + } + else + { + hr = __SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting 1-sided stencil mode.", + "D3D9RenderSystem::setStencilBufferParams"); + flip = false; + } + + // func + hr = __SetRenderState(D3DRS_STENCILFUNC, D3D9Mappings::get(func)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil buffer test function.", + "D3D9RenderSystem::setStencilBufferParams"); + + // reference value + hr = __SetRenderState(D3DRS_STENCILREF, refValue); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil buffer reference value.", + "D3D9RenderSystem::setStencilBufferParams"); + + // compare mask + hr = __SetRenderState(D3DRS_STENCILMASK, compareMask); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil buffer compare mask.", + "D3D9RenderSystem::setStencilBufferParams"); + + // compare mask + hr = __SetRenderState(D3DRS_STENCILWRITEMASK, writeMask); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil buffer write mask.", + "D3D9RenderSystem::setStencilBufferParams"); + + // fail op + hr = __SetRenderState(D3DRS_STENCILFAIL, D3D9Mappings::get(stencilFailOp, flip)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil fail operation.", + "D3D9RenderSystem::setStencilBufferParams"); + + // depth fail op + hr = __SetRenderState(D3DRS_STENCILZFAIL, D3D9Mappings::get(depthFailOp, flip)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil depth fail operation.", + "D3D9RenderSystem::setStencilBufferParams"); + + // pass op + hr = __SetRenderState(D3DRS_STENCILPASS, D3D9Mappings::get(passOp, flip)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil pass operation.", + "D3D9RenderSystem::setStencilBufferParams"); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureUnitFiltering(size_t unit, FilterType ftype, + FilterOptions filter) + { + HRESULT hr; + D3D9Mappings::eD3DTexType texType = mTexStageDesc[unit].texType; + hr = __SetSamplerState( getSamplerId(unit), D3D9Mappings::get(ftype), + D3D9Mappings::get(ftype, filter, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps(), texType)); + if (FAILED(hr)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set texture filter ", "D3D9RenderSystem::_setTextureUnitFiltering"); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureUnitCompareFunction(size_t unit, CompareFunction function) + { + //no effect in directX9 rendersystem + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureUnitCompareEnabled(size_t unit, bool compare) + { + //no effect in directX9 rendersystem + } + //--------------------------------------------------------------------- + DWORD D3D9RenderSystem::_getCurrentAnisotropy(size_t unit) + { + DWORD oldVal; + getActiveD3D9Device()->GetSamplerState(static_cast(unit), D3DSAMP_MAXANISOTROPY, &oldVal); + return oldVal; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) + { + if (static_cast(maxAnisotropy) > mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().MaxAnisotropy) + maxAnisotropy = mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().MaxAnisotropy; + + if (_getCurrentAnisotropy(unit) != maxAnisotropy) + __SetSamplerState( getSamplerId(unit), D3DSAMP_MAXANISOTROPY, maxAnisotropy ); + } + //--------------------------------------------------------------------- + HRESULT D3D9RenderSystem::__SetRenderState(D3DRENDERSTATETYPE state, DWORD value) + { + HRESULT hr; + DWORD oldVal; + + if ( FAILED( hr = getActiveD3D9Device()->GetRenderState(state, &oldVal) ) ) + return hr; + if ( oldVal == value ) + return D3D_OK; + else + return getActiveD3D9Device()->SetRenderState(state, value); + } + //--------------------------------------------------------------------- + HRESULT D3D9RenderSystem::__SetSamplerState(DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value) + { + HRESULT hr; + DWORD oldVal; + + if ( FAILED( hr = getActiveD3D9Device()->GetSamplerState(sampler, type, &oldVal) ) ) + return hr; + if ( oldVal == value ) + return D3D_OK; + else + return getActiveD3D9Device()->SetSamplerState(sampler, type, value); + } + //--------------------------------------------------------------------- + HRESULT D3D9RenderSystem::__SetTextureStageState(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value) + { + HRESULT hr; + DWORD oldVal; + + // can only set fixed-function texture stage state + if (stage < 8) + { + if ( FAILED( hr = getActiveD3D9Device()->GetTextureStageState(stage, type, &oldVal) ) ) + return hr; + if ( oldVal == value ) + return D3D_OK; + else + return getActiveD3D9Device()->SetTextureStageState(stage, type, value); + } + else + { + return D3D_OK; + } + } + //--------------------------------------------------------------------- + DepthBuffer* D3D9RenderSystem::_createDepthBufferFor( RenderTarget *renderTarget ) + { + IDirect3DSurface9* pBack[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + memset (pBack, 0, sizeof(pBack) ); + renderTarget->getCustomAttribute( "DDBACKBUFFER", &pBack ); + if( !pBack[0] ) + return 0; + + D3DSURFACE_DESC srfDesc; + if( FAILED(pBack[0]->GetDesc(&srfDesc)) ) + { + OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, + "Failed to retrieve Surface Description from BackBuffer. RenderTarget: " + + renderTarget->getName(), + "D3D9RenderSystem::_createDepthBufferFor" ); + } + + //Find an appropiarte format for this depth buffer that best matches the RenderTarget's + D3DFORMAT dsfmt = _getDepthStencilFormatFor( srfDesc.Format ); + + //Create the depthstencil surface + IDirect3DSurface9 *depthBufferSurface = NULL; + IDirect3DDevice9* activeDevice = getActiveD3D9Device(); + HRESULT hr = activeDevice->CreateDepthStencilSurface( + srfDesc.Width, srfDesc.Height, dsfmt, + srfDesc.MultiSampleType, srfDesc.MultiSampleQuality, + TRUE, // discard true or false? + &depthBufferSurface, NULL); + if( FAILED(hr) ) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, + "Error CreateDepthStencilSurface : " + msg, + "D3D9RenderSystem::_createDepthBufferFor" ); + } + + D3D9DepthBuffer *newDepthBuffer = OGRE_NEW D3D9DepthBuffer( DepthBuffer::POOL_DEFAULT, this, + activeDevice, depthBufferSurface, + dsfmt, srfDesc.Width, srfDesc.Height, + srfDesc.MultiSampleType, srfDesc.MultiSampleQuality, false ); + + return newDepthBuffer; + } + + //--------------------------------------------------------------------- + DepthBuffer* D3D9RenderSystem::_addManualDepthBuffer( IDirect3DDevice9* depthSurfaceDevice, IDirect3DSurface9 *depthSurface ) + { + //If this depth buffer was already added, return that one + DepthBufferVec::const_iterator itor = mDepthBufferPool[DepthBuffer::POOL_DEFAULT].begin(); + DepthBufferVec::const_iterator end = mDepthBufferPool[DepthBuffer::POOL_DEFAULT].end(); + + while( itor != end ) + { + if( static_cast(*itor)->getDepthBufferSurface() == depthSurface ) + return *itor; + + ++itor; + } + + //Nope, get the info about this depth buffer and create a new container fot it + D3DSURFACE_DESC dsDesc; + if( FAILED(depthSurface->GetDesc(&dsDesc)) ) + return 0; + + D3D9DepthBuffer *newDepthBuffer = OGRE_NEW D3D9DepthBuffer( DepthBuffer::POOL_DEFAULT, this, + depthSurfaceDevice, depthSurface, + dsDesc.Format, dsDesc.Width, dsDesc.Height, + dsDesc.MultiSampleType, dsDesc.MultiSampleQuality, true ); + + //Add the 'main' depth buffer to the pool + mDepthBufferPool[newDepthBuffer->getPoolId()].push_back( newDepthBuffer ); + + return newDepthBuffer; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_cleanupDepthBuffers( IDirect3DDevice9 *creator ) + { + assert( creator ); + + DepthBufferMap::iterator itMap = mDepthBufferPool.begin(); + DepthBufferMap::iterator enMap = mDepthBufferPool.end(); + + while( itMap != enMap ) + { + DepthBufferVec::iterator itor = itMap->second.begin(); + DepthBufferVec::iterator end = itMap->second.end(); + + while( itor != end ) + { + //Only delete those who match the specified creator + if( static_cast(*itor)->getDeviceCreator() == creator ) + { + OGRE_DELETE *itor; + + //Erasing a vector invalidates iterators, we need to recalculate + //to avoid memory corruption and asserts. The new itor will point + //to the next iterator + const size_t idx = itor - itMap->second.begin(); + itMap->second.erase( itor ); //Erase + itor = itMap->second.begin() + idx; + end = itMap->second.end(); + } + else + ++itor; + } + + //Erase the pool if it's now empty. Note erasing from a map is + //valid while iterating through it + if( itMap->second.empty() ) + { + DepthBufferMap::iterator deadi = itMap++; + mDepthBufferPool.erase( deadi ); + } + else + ++itMap; + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_cleanupDepthBuffers( IDirect3DSurface9 *manualSurface ) + { + assert( manualSurface ); + + DepthBufferMap::iterator itMap = mDepthBufferPool.begin(); + DepthBufferMap::iterator enMap = mDepthBufferPool.end(); + + while( itMap != enMap ) + { + DepthBufferVec::iterator itor = itMap->second.begin(); + DepthBufferVec::iterator end = itMap->second.end(); + + while( itor != end ) + { + //Only delete those who match the specified surface + if( static_cast(*itor)->getDepthBufferSurface() == manualSurface ) + { + OGRE_DELETE *itor; + + //Erasing a vector invalidates iterators, we need to recalculate + //to avoid memory corruption and asserts. The new itor will point + //to the next iterator + const size_t idx = itor - itMap->second.begin(); + itMap->second.erase( itor ); //Erase + itor = itMap->second.begin() + idx; + end = itMap->second.end(); + } + else + ++itor; + } + + //Erase the pool if it's now empty. Note erasing from a map is + //valid while iterating through it + if( itMap->second.empty() ) + { + DepthBufferMap::iterator deadi = itMap++; + mDepthBufferPool.erase( deadi ); + } + else + ++itMap; + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setRenderTarget(RenderTarget *target) + { + mActiveRenderTarget = target; + + if (mActiveRenderTarget) + { + HRESULT hr; + + // If this is called without going through RenderWindow::update, then + // the device will not have been set. Calling it twice is safe, the + // implementation ensures nothing happens if the same device is set twice + if (std::find(mRenderWindows.begin(), mRenderWindows.end(), target) != mRenderWindows.end()) + { + D3D9RenderWindow *window = static_cast(target); + mDeviceManager->setActiveRenderTargetDevice(window->getDevice()); + // also make sure we validate the device; if this never went + // through update() it won't be set + window->_validateDevice(); + } + + // Retrieve render surfaces (up to OGRE_MAX_MULTIPLE_RENDER_TARGETS) + IDirect3DSurface9* pBack[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; + memset(pBack, 0, sizeof(pBack)); + target->getCustomAttribute( "DDBACKBUFFER", &pBack ); + if (!pBack[0]) + return; + + D3D9DepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); + + if( target->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH && + (!depthBuffer || depthBuffer->getDeviceCreator() != getActiveD3D9Device() ) ) + { + //Depth is automatically managed and there is no depth buffer attached to this RT + //or the Current D3D device doesn't match the one this Depth buffer was created + setDepthBufferFor( target ); + + //Retrieve depth buffer again + depthBuffer = static_cast(target->getDepthBuffer()); + } + + if ((depthBuffer != NULL) && ( depthBuffer->getDeviceCreator() != getActiveD3D9Device())) + { + OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, + "Can't use a depth buffer from a different device!", + "D3D9RenderSystem::_setRenderTarget" ); + } + + IDirect3DSurface9 *depthSurface = depthBuffer ? depthBuffer->getDepthBufferSurface() : NULL; + + // Bind render targets + uint count = mCurrentCapabilities->getNumMultiRenderTargets(); + for(uint x=0; xSetRenderTarget(x, pBack[x]); + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to setRenderTarget : " + msg, "D3D9RenderSystem::_setViewport" ); + } + } + hr = getActiveD3D9Device()->SetDepthStencilSurface( depthSurface ); + if (FAILED(hr)) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to setDepthStencil : " + msg, "D3D9RenderSystem::_setViewport" ); + } + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_setViewport( Viewport *vp ) + { + if (!vp) + { + mActiveViewport = NULL; + _setRenderTarget(NULL); + } + else if( vp != mActiveViewport || vp->_isUpdated() ) + { + mActiveViewport = vp; + + // ok, it's different, time to set render target and viewport params + D3DVIEWPORT9 d3dvp; + HRESULT hr; + + // Set render target + RenderTarget* target = vp->getTarget(); + _setRenderTarget(target); + + //Reset the viewport after the render target has been set. If the device + //had been reset the viewport would have been set to NULL. + mActiveViewport = vp; + + _setCullingMode( mCullingMode ); + + // set viewport dimensions + d3dvp.X = vp->getActualLeft(); + d3dvp.Y = vp->getActualTop(); + d3dvp.Width = vp->getActualWidth(); + d3dvp.Height = vp->getActualHeight(); + if (target->requiresTextureFlipping()) + { + // Convert "top-left" to "bottom-left" + d3dvp.Y = target->getHeight() - d3dvp.Height - d3dvp.Y; + } + + // Z-values from 0.0 to 1.0 (TODO: standardise with OpenGL) + d3dvp.MinZ = 0.0f; + d3dvp.MaxZ = 1.0f; + + if( FAILED( hr = getActiveD3D9Device()->SetViewport( &d3dvp ) ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set viewport.", "D3D9RenderSystem::_setViewport" ); + + // Set sRGB write mode + __SetRenderState(D3DRS_SRGBWRITEENABLE, target->isHardwareGammaEnabled()); + + vp->_clearUpdatedFlag(); + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_beginFrame() + { + HRESULT hr; + + if( !mActiveViewport ) + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Cannot begin frame - no viewport selected.", "D3D9RenderSystem::_beginFrame" ); + + if( FAILED( hr = getActiveD3D9Device()->BeginScene() ) ) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error beginning frame :" + msg, "D3D9RenderSystem::_beginFrame" ); + } + + mLastVertexSourceCount = 0; + + // Clear left overs of previous viewport. + // I.E: Viewport A can use 3 different textures and light states + // When trying to render viewport B these settings should be cleared, otherwise + // graphical artifacts might occur. + mDeviceManager->getActiveDevice()->clearDeviceStreams(); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_endFrame() + { + HRESULT hr; + if( FAILED( hr = getActiveD3D9Device()->EndScene() ) ) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error ending frame", "D3D9RenderSystem::_endFrame" ); + + mDeviceManager->destroyInactiveRenderDevices(); + } + //--------------------------------------------------------------------- + struct D3D9RenderContext : public RenderSystem::RenderSystemContext + { + RenderTarget* target; + }; + //--------------------------------------------------------------------- + RenderSystem::RenderSystemContext* D3D9RenderSystem::_pauseFrame(void) + { + //Stop rendering + _endFrame(); + + D3D9RenderContext* context = OGRE_ALLOC_T(D3D9RenderContext, 1, MEMCATEGORY_RENDERSYS); + context->target = mActiveRenderTarget; + + + return context; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_resumeFrame(RenderSystemContext* context) + { + //Resume rendering + _beginFrame(); + D3D9RenderContext* d3dContext = static_cast(context); + + OGRE_FREE(context, MEMCATEGORY_RENDERSYS); + } + void D3D9RenderSystem::setVertexDeclaration(VertexDeclaration* decl) + { + setVertexDeclaration(decl, true); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setVertexDeclaration(VertexDeclaration* decl, bool useGlobalInstancingVertexBufferIsAvailable) + { + HRESULT hr; + + D3D9VertexDeclaration* d3ddecl = + static_cast(decl); + + if (FAILED(hr = getActiveD3D9Device()->SetVertexDeclaration(d3ddecl->getD3DVertexDeclaration(getGlobalInstanceVertexBufferVertexDeclaration(), useGlobalInstancingVertexBufferIsAvailable)))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D9 vertex declaration", + "D3D9RenderSystem::setVertexDeclaration"); + } + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setVertexBufferBinding(VertexBufferBinding* binding) + { + setVertexBufferBinding(binding, 1, true, false); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setVertexBufferBinding( + VertexBufferBinding* binding, size_t numberOfInstances, bool useGlobalInstancingVertexBufferIsAvailable, bool indexesUsed) + { + /*if (!prg) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Null program bound.", + "D3D9RenderSystem::bindGpuProgram"); + }*/ + + HRESULT hr; + + if (useGlobalInstancingVertexBufferIsAvailable) + { + numberOfInstances *= getGlobalNumberOfInstances(); + } + + HardwareVertexBufferSharedPtr globalInstanceVertexBuffer = getGlobalInstanceVertexBuffer(); + VertexDeclaration* globalVertexDeclaration = getGlobalInstanceVertexBufferVertexDeclaration(); + bool hasInstanceData = useGlobalInstancingVertexBufferIsAvailable && + !globalInstanceVertexBuffer.isNull() && globalVertexDeclaration != NULL + || binding->getHasInstanceData(); + + + // TODO: attempt to detect duplicates + const VertexBufferBinding::VertexBufferBindingMap& binds = binding->getBindings(); + VertexBufferBinding::VertexBufferBindingMap::const_iterator i, iend; + size_t source = 0; + iend = binds.end(); + for (i = binds.begin(); i != iend; ++i, ++source) + { + D3D9HardwareVertexBuffer* d3d9buf = + static_cast(i->second.get()); + + // Unbind gap sources + for ( ; source < i->first; ++source) + { + hr = getActiveD3D9Device()->SetStreamSource(static_cast(source), NULL, 0, 0); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to reset unused D3D9 stream source", + "D3D9RenderSystem::setVertexBufferBinding"); + } + } + + hr = getActiveD3D9Device()->SetStreamSource( + static_cast(source), + d3d9buf->getD3D9VertexBuffer(), + 0, // no stream offset, this is handled in _render instead + static_cast(d3d9buf->getVertexSize()) // stride + ); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D9 stream source for buffer binding", + "D3D9RenderSystem::setVertexBufferBinding"); + } + + // SetStreamSourceFreq + if ( hasInstanceData ) + { + if ( d3d9buf->getIsInstanceData() ) + { + hr = getActiveD3D9Device()->SetStreamSourceFreq( static_cast(source), D3DSTREAMSOURCE_INSTANCEDATA | d3d9buf->getInstanceDataStepRate() ); + } + else + { + if ( !indexesUsed ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Instance data used without index data.", + "D3D9RenderSystem::setVertexBufferBinding"); + } + hr = getActiveD3D9Device()->SetStreamSourceFreq( static_cast(source), D3DSTREAMSOURCE_INDEXEDDATA | numberOfInstances ); + } + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D9 stream source Freq", + "D3D9RenderSystem::setVertexBufferBinding"); + } + } + else + { + hr = getActiveD3D9Device()->SetStreamSourceFreq( static_cast(source), 1 ); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to reset unused D3D9 stream source Freq", + "D3D9RenderSystem::setVertexBufferBinding"); + } + } + + } + + if (useGlobalInstancingVertexBufferIsAvailable) + { + // bind global instance buffer if exist + if( !globalInstanceVertexBuffer.isNull() ) + { + if ( !indexesUsed ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Instance data used without index data.", + "D3D9RenderSystem::setVertexBufferBinding"); + } + + D3D9HardwareVertexBuffer * d3d9buf = + static_cast(globalInstanceVertexBuffer.get()); + + hr = getActiveD3D9Device()->SetStreamSource( + static_cast(source), + d3d9buf->getD3D9VertexBuffer(), + 0, // no stream offset, this is handled in _render instead + static_cast(d3d9buf->getVertexSize()) // stride + ); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D9 stream source for buffer binding", + "D3D9RenderSystem::setVertexBufferBinding"); + } + + hr = getActiveD3D9Device()->SetStreamSourceFreq( static_cast(source), D3DSTREAMSOURCE_INSTANCEDATA | d3d9buf->getInstanceDataStepRate() ); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D9 stream source Freq", + "D3D9RenderSystem::setVertexBufferBinding"); + } + } + + } + + // Unbind any unused sources + for (size_t unused = source; unused < mLastVertexSourceCount; ++unused) + { + + hr = getActiveD3D9Device()->SetStreamSource(static_cast(unused), NULL, 0, 0); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to reset unused D3D9 stream source", + "D3D9RenderSystem::setVertexBufferBinding"); + } + + hr = getActiveD3D9Device()->SetStreamSourceFreq( static_cast(unused), 1 ); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to reset unused D3D9 stream source Freq", + "D3D9RenderSystem::setVertexBufferBinding"); + } + + } + mLastVertexSourceCount = source; + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_render(const RenderOperation& op) + { + // Exit immediately if there is nothing to render + // This caused a problem on FireGL 8800 + if (op.vertexData->vertexCount == 0) + return; + + // Call super class + RenderSystem::_render(op); + + + if ( !mEnableFixedPipeline && !mRealCapabilities->hasCapability(RSC_FIXED_FUNCTION) + && + ( + ( !mVertexProgramBound ) || + (!mFragmentProgramBound && op.operationType != RenderOperation::OT_POINT_LIST) + ) + ) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Attempted to render using the fixed pipeline when it is disabled.", + "D3D9RenderSystem::_render"); + } + + // To think about: possibly remove setVertexDeclaration and + // setVertexBufferBinding from RenderSystem since the sequence is + // a bit too D3D9-specific? + setVertexDeclaration(op.vertexData->vertexDeclaration, op.useGlobalInstancingVertexBufferIsAvailable); + setVertexBufferBinding(op.vertexData->vertexBufferBinding, op.numberOfInstances, op.useGlobalInstancingVertexBufferIsAvailable, op.useIndexes); + + // Determine rendering operation + D3DPRIMITIVETYPE primType = D3DPT_TRIANGLELIST; + DWORD primCount = 0; + switch( op.operationType ) + { + case RenderOperation::OT_POINT_LIST: + primType = D3DPT_POINTLIST; + primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount); + break; + + case RenderOperation::OT_LINE_LIST: + primType = D3DPT_LINELIST; + primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 2; + break; + + case RenderOperation::OT_LINE_STRIP: + primType = D3DPT_LINESTRIP; + primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 1; + break; + + case RenderOperation::OT_TRIANGLE_LIST: + primType = D3DPT_TRIANGLELIST; + primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 3; + break; + + case RenderOperation::OT_TRIANGLE_STRIP: + primType = D3DPT_TRIANGLESTRIP; + primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2; + break; + + case RenderOperation::OT_TRIANGLE_FAN: + primType = D3DPT_TRIANGLEFAN; + primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2; + break; + } + + if (!primCount) + return; + + // Issue the op + HRESULT hr; + if( op.useIndexes ) + { + D3D9HardwareIndexBuffer* d3dIdxBuf = + static_cast(op.indexData->indexBuffer.get()); + hr = getActiveD3D9Device()->SetIndices( d3dIdxBuf->getD3DIndexBuffer() ); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set index buffer", "D3D9RenderSystem::_render" ); + } + + do + { + // Update derived depth bias + if (mDerivedDepthBias && mCurrentPassIterationNum > 0) + { + _setDepthBias(mDerivedDepthBiasBase + + mDerivedDepthBiasMultiplier * mCurrentPassIterationNum, + mDerivedDepthBiasSlopeScale); + } + // do indexed draw operation + hr = getActiveD3D9Device()->DrawIndexedPrimitive( + primType, + static_cast(op.vertexData->vertexStart), + 0, // Min vertex index - assume we can go right down to 0 + static_cast(op.vertexData->vertexCount), + static_cast(op.indexData->indexStart), + static_cast(primCount) + ); + + } while (updatePassIterationRenderState()); + } + else + { + // nfz: gpu_iterate + do + { + // Update derived depth bias + if (mDerivedDepthBias && mCurrentPassIterationNum > 0) + { + _setDepthBias(mDerivedDepthBiasBase + + mDerivedDepthBiasMultiplier * mCurrentPassIterationNum, + mDerivedDepthBiasSlopeScale); + } + // Unindexed, a little simpler! + hr = getActiveD3D9Device()->DrawPrimitive( + primType, + static_cast(op.vertexData->vertexStart), + static_cast(primCount) + ); + + } while (updatePassIterationRenderState()); + } + + if( FAILED( hr ) ) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to DrawPrimitive : " + msg, "D3D9RenderSystem::_render" ); + } + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setNormaliseNormals(bool normalise) + { + __SetRenderState(D3DRS_NORMALIZENORMALS, + normalise ? TRUE : FALSE); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::bindGpuProgram(GpuProgram* prg) + { + if (!prg) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Null program bound.", + "D3D9RenderSystem::bindGpuProgram"); + } + + HRESULT hr; + switch (prg->getType()) + { + case GPT_VERTEX_PROGRAM: + hr = getActiveD3D9Device()->SetVertexShader( + static_cast(prg)->getVertexShader()); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error calling SetVertexShader", "D3D9RenderSystem::bindGpuProgram"); + } + break; + case GPT_FRAGMENT_PROGRAM: + hr = getActiveD3D9Device()->SetPixelShader( + static_cast(prg)->getPixelShader()); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error calling SetPixelShader", "D3D9RenderSystem::bindGpuProgram"); + } + break; + }; + + // Make sure texcoord index is equal to stage value, As SDK Doc suggests: + // "When rendering using vertex shaders, each stage's texture coordinate index must be set to its default value." + // This solves such an errors when working with the Debug runtime - + // "Direct3D9: (ERROR) :Stage 1 - Texture coordinate index in the stage must be equal to the stage index when programmable vertex pipeline is used". + for (unsigned int nStage=0; nStage < 8; ++nStage) + __SetTextureStageState(nStage, D3DTSS_TEXCOORDINDEX, nStage); + + RenderSystem::bindGpuProgram(prg); + + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::unbindGpuProgram(GpuProgramType gptype) + { + /*if (!prg) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Null program bound.", + "D3D9RenderSystem::bindGpuProgram"); + }*/ + + HRESULT hr; + switch(gptype) + { + case GPT_VERTEX_PROGRAM: + mActiveVertexGpuProgramParameters.setNull(); + hr = getActiveD3D9Device()->SetVertexShader(NULL); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error resetting SetVertexShader to NULL", + "D3D9RenderSystem::unbindGpuProgram"); + } + break; + case GPT_FRAGMENT_PROGRAM: + mActiveFragmentGpuProgramParameters.setNull(); + hr = getActiveD3D9Device()->SetPixelShader(NULL); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error resetting SetPixelShader to NULL", + "D3D9RenderSystem::unbindGpuProgram"); + } + break; + }; + RenderSystem::unbindGpuProgram(gptype); + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::bindGpuProgramParameters(GpuProgramType gptype, + GpuProgramParametersSharedPtr params, uint16 variability) + { + // special case pass iteration + if (variability == (uint16)GPV_PASS_ITERATION_NUMBER) + { + bindGpuProgramPassIterationParameters(gptype); + return; + } + + if (variability & (uint16)GPV_GLOBAL) + { + // D3D9 doesn't support shared constant buffers, so use copy routine + params->_copySharedParams(); + } + + HRESULT hr; + GpuLogicalBufferStructPtr floatLogical = params->getFloatLogicalBufferStruct(); + GpuLogicalBufferStructPtr intLogical = params->getIntLogicalBufferStruct(); + + switch(gptype) + { + case GPT_VERTEX_PROGRAM: + mActiveVertexGpuProgramParameters = params; + { + OGRE_LOCK_MUTEX(floatLogical->mutex); + + for (GpuLogicalIndexUseMap::const_iterator i = floatLogical->map.begin(); + i != floatLogical->map.end(); ++i) + { + if (i->second.variability & variability) + { + size_t logicalIndex = i->first; + const float* pFloat = params->getFloatPointer(i->second.physicalIndex); + size_t slotCount = i->second.currentSize / 4; + assert (i->second.currentSize % 4 == 0 && "Should not have any " + "elements less than 4 wide for D3D9"); + + if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantF( + (UINT)logicalIndex, pFloat, (UINT)slotCount))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to upload vertex shader float parameters", + "D3D9RenderSystem::bindGpuProgramParameters"); + } + } + + } + + } + // bind ints + { + OGRE_LOCK_MUTEX(intLogical->mutex); + + for (GpuLogicalIndexUseMap::const_iterator i = intLogical->map.begin(); + i != intLogical->map.end(); ++i) + { + if (i->second.variability & variability) + { + size_t logicalIndex = i->first; + const int* pInt = params->getIntPointer(i->second.physicalIndex); + size_t slotCount = i->second.currentSize / 4; + assert (i->second.currentSize % 4 == 0 && "Should not have any " + "elements less than 4 wide for D3D9"); + + if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantI( + static_cast(logicalIndex), pInt, static_cast(slotCount)))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to upload vertex shader int parameters", + "D3D9RenderSystem::bindGpuProgramParameters"); + } + } + } + + } + + break; + case GPT_FRAGMENT_PROGRAM: + mActiveFragmentGpuProgramParameters = params; + { + OGRE_LOCK_MUTEX(floatLogical->mutex); + + for (GpuLogicalIndexUseMap::const_iterator i = floatLogical->map.begin(); + i != floatLogical->map.end(); ++i) + { + if (i->second.variability & variability) + { + size_t logicalIndex = i->first; + const float* pFloat = params->getFloatPointer(i->second.physicalIndex); + size_t slotCount = i->second.currentSize / 4; + assert (i->second.currentSize % 4 == 0 && "Should not have any " + "elements less than 4 wide for D3D9"); + + if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantF( + static_cast(logicalIndex), pFloat, static_cast(slotCount)))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to upload pixel shader float parameters", + "D3D9RenderSystem::bindGpuProgramParameters"); + } + } + } + + } + // bind ints + { + OGRE_LOCK_MUTEX(intLogical->mutex); + + for (GpuLogicalIndexUseMap::const_iterator i = intLogical->map.begin(); + i != intLogical->map.end(); ++i) + { + if (i->second.variability & variability) + { + size_t logicalIndex = i->first; + const int* pInt = params->getIntPointer(i->second.physicalIndex); + size_t slotCount = i->second.currentSize / 4; + assert (i->second.currentSize % 4 == 0 && "Should not have any " + "elements less than 4 wide for D3D9"); + + if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantI( + static_cast(logicalIndex), pInt, static_cast(slotCount)))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to upload pixel shader int parameters", + "D3D9RenderSystem::bindGpuProgramParameters"); + } + } + + } + + } + break; + }; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::bindGpuProgramPassIterationParameters(GpuProgramType gptype) + { + + HRESULT hr; + size_t physicalIndex = 0; + size_t logicalIndex = 0; + const float* pFloat; + + switch(gptype) + { + case GPT_VERTEX_PROGRAM: + if (mActiveVertexGpuProgramParameters->hasPassIterationNumber()) + { + physicalIndex = mActiveVertexGpuProgramParameters->getPassIterationNumberIndex(); + logicalIndex = mActiveVertexGpuProgramParameters->getFloatLogicalIndexForPhysicalIndex(physicalIndex); + pFloat = mActiveVertexGpuProgramParameters->getFloatPointer(physicalIndex); + + if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantF( + static_cast(logicalIndex), pFloat, 1))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to upload vertex shader multi pass parameters", + "D3D9RenderSystem::bindGpuProgramMultiPassParameters"); + } + } + break; + + case GPT_FRAGMENT_PROGRAM: + if (mActiveFragmentGpuProgramParameters->hasPassIterationNumber()) + { + physicalIndex = mActiveFragmentGpuProgramParameters->getPassIterationNumberIndex(); + logicalIndex = mActiveFragmentGpuProgramParameters->getFloatLogicalIndexForPhysicalIndex(physicalIndex); + pFloat = mActiveFragmentGpuProgramParameters->getFloatPointer(physicalIndex); + if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantF( + static_cast(logicalIndex), pFloat, 1))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to upload pixel shader multi pass parameters", + "D3D9RenderSystem::bindGpuProgramMultiPassParameters"); + } + } + break; + + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setClipPlanesImpl(const PlaneList& clipPlanes) + { + size_t i; + size_t numClipPlanes; + D3DXPLANE dx9ClipPlane; + DWORD mask = 0; + HRESULT hr; + + numClipPlanes = clipPlanes.size(); + for (i = 0; i < numClipPlanes; ++i) + { + const Plane& plane = clipPlanes[i]; + + dx9ClipPlane.a = plane.normal.x; + dx9ClipPlane.b = plane.normal.y; + dx9ClipPlane.c = plane.normal.z; + dx9ClipPlane.d = plane.d; + + if (mVertexProgramBound) + { + // programmable clips in clip space (ugh) + // must transform worldspace planes by view/proj + D3DXMATRIX xform; + D3DXMatrixMultiply(&xform, &mDxViewMat, &mDxProjMat); + D3DXMatrixInverse(&xform, NULL, &xform); + D3DXMatrixTranspose(&xform, &xform); + D3DXPlaneTransform(&dx9ClipPlane, &dx9ClipPlane, &xform); + } - autoWindow = _createRenderWindow( windowTitle, width, height, - fullScreen, &miscParams ); - - // If we have 16bit depth buffer enable w-buffering. - assert( autoWindow ); - if ( autoWindow->getColourDepth() == 16 ) - { - mWBuffer = true; - } - else - { - mWBuffer = false; - } - } - - LogManager::getSingleton().logMessage("***************************************"); - LogManager::getSingleton().logMessage("*** D3D9 : Subsystem Initialised OK ***"); - LogManager::getSingleton().logMessage("***************************************"); - - // call superclass method - RenderSystem::_initialise( autoCreateWindow ); - - - return autoWindow; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::reinitialise() - { - LogManager::getSingleton().logMessage( "D3D9 : Reinitialising" ); - this->shutdown(); - this->_initialise( true ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::shutdown() - { - RenderSystem::shutdown(); - - if (mDeviceManager != NULL) - { - OGRE_DELETE mDeviceManager; - mDeviceManager = NULL; - } - - if (mDriverList != NULL) - { - OGRE_DELETE mDriverList; - mDriverList = NULL; - } - mActiveD3DDriver = NULL; - - LogManager::getSingleton().logMessage("D3D9 : Shutting down cleanly."); - - if (mTextureManager != NULL) - { - OGRE_DELETE mTextureManager; - mTextureManager = NULL; - } - - if (mHardwareBufferManager != NULL) - { - OGRE_DELETE mHardwareBufferManager; - mHardwareBufferManager = NULL; - } - - if (mGpuProgramManager != NULL) - { - OGRE_DELETE mGpuProgramManager; - mGpuProgramManager = NULL; - } - } - //--------------------------------------------------------------------- - RenderWindow* D3D9RenderSystem::_createRenderWindow(const String &name, - unsigned int width, unsigned int height, bool fullScreen, - const NameValuePairList *miscParams) - { - // Log a message - StringStream ss; - ss << "D3D9RenderSystem::_createRenderWindow \"" << name << "\", " << - width << "x" << height << " "; - - if(fullScreen) - ss << "fullscreen "; - else - ss << "windowed "; - - if(miscParams) - { - ss << " miscParams: "; - NameValuePairList::const_iterator it; - for(it=miscParams->begin(); it!=miscParams->end(); ++it) - { - ss << it->first << "=" << it->second << " "; - } - LogManager::getSingleton().logMessage(ss.str()); - } - - String msg; - - // Make sure we don't already have a render target of the - // same name as the one supplied - if( mRenderTargets.find( name ) != mRenderTargets.end() ) - { - msg = "A render target of the same name '" + name + "' already " - "exists. You cannot create a new window with this name."; - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, msg, "D3D9RenderSystem::_createRenderWindow" ); - } - - D3D9RenderWindow* renderWindow = OGRE_NEW D3D9RenderWindow(mhInstance); - - renderWindow->create(name, width, height, fullScreen, miscParams); - - mResourceManager->lockDeviceAccess(); + hr = getActiveD3D9Device()->SetClipPlane(static_cast(i), dx9ClipPlane); + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set clip plane", + "D3D9RenderSystem::setClipPlanes"); + } - try + mask |= (1 << i); + } + + hr = __SetRenderState(D3DRS_CLIPPLANEENABLE, mask); + if (FAILED(hr)) { - mDeviceManager->linkRenderWindow(renderWindow); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set render state for clip planes", + "D3D9RenderSystem::setClipPlanes"); } - catch (const Ogre::RenderingAPIException&) + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::setScissorTest(bool enabled, size_t left, size_t top, size_t right, + size_t bottom) + { + HRESULT hr; + if (enabled) { - // after catching the exception, clean up - mResourceManager->unlockDeviceAccess(); - renderWindow->destroy(); - - // re-throw - throw; + if (FAILED(hr = __SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to enable scissor rendering state; " + getErrorDescription(hr), + "D3D9RenderSystem::setScissorTest"); + } + RECT rect; + rect.left = static_cast(left); + rect.top = static_cast(top); + rect.bottom = static_cast(bottom); + rect.right = static_cast(right); + if (FAILED(hr = getActiveD3D9Device()->SetScissorRect(&rect))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set scissor rectangle; " + getErrorDescription(hr), + "D3D9RenderSystem::setScissorTest"); + } + } + else + { + if (FAILED(hr = __SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE))) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to disable scissor rendering state; " + getErrorDescription(hr), + "D3D9RenderSystem::setScissorTest"); + } + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::clearFrameBuffer(unsigned int buffers, + const ColourValue& colour, Real depth, unsigned short stencil) + { + DWORD flags = 0; + if (buffers & FBT_COLOUR) + { + flags |= D3DCLEAR_TARGET; + } + if (buffers & FBT_DEPTH) + { + flags |= D3DCLEAR_ZBUFFER; } + // Only try to clear the stencil buffer if supported + if (buffers & FBT_STENCIL && mCurrentCapabilities->hasCapability(RSC_HWSTENCIL)) + { + flags |= D3DCLEAR_STENCIL; + } + HRESULT hr; + if( FAILED( hr = getActiveD3D9Device()->Clear( + 0, + NULL, + flags, + colour.getAsARGB(), + depth, + stencil ) ) ) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error clearing frame buffer : " + + msg, "D3D9RenderSystem::clearFrameBuffer" ); + } + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_makeProjectionMatrix(Real left, Real right, + Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest, + bool forGpuProgram) + { + // Correct position for off-axis projection matrix + if (!forGpuProgram) + { + Real offsetX = left + right; + Real offsetY = top + bottom; - mResourceManager->unlockDeviceAccess(); - - mRenderWindows.push_back(renderWindow); - - updateRenderSystemCapabilities(renderWindow); - - attachRenderTarget( *renderWindow ); - - return renderWindow; - } - //--------------------------------------------------------------------- - bool D3D9RenderSystem::_createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions, - RenderWindowList& createdWindows) - { - // Call base render system method. - if (false == RenderSystem::_createRenderWindows(renderWindowDescriptions, createdWindows)) - return false; - - // Simply call _createRenderWindow in a loop. - for (size_t i = 0; i < renderWindowDescriptions.size(); ++i) - { - const RenderWindowDescription& curRenderWindowDescription = renderWindowDescriptions[i]; - RenderWindow* curWindow = NULL; - - curWindow = _createRenderWindow(curRenderWindowDescription.name, - curRenderWindowDescription.width, - curRenderWindowDescription.height, - curRenderWindowDescription.useFullScreen, - &curRenderWindowDescription.miscParams); - - createdWindows.push_back(curWindow); - } - - return true; - } - - //--------------------------------------------------------------------- - RenderSystemCapabilities* D3D9RenderSystem::updateRenderSystemCapabilities(D3D9RenderWindow* renderWindow) - { - RenderSystemCapabilities* rsc = mRealCapabilities; - if (rsc == NULL) - rsc = OGRE_NEW RenderSystemCapabilities(); - - rsc->setCategoryRelevant(CAPS_CATEGORY_D3D9, true); - rsc->setDriverVersion(mDriverVersion); - rsc->setDeviceName(mActiveD3DDriver->DriverDescription()); - rsc->setRenderSystemName(getName()); - - if(mEnableFixedPipeline) - { - // Supports fixed-function - rsc->setCapability(RSC_FIXED_FUNCTION); - } - - - // Init caps to maximum. - rsc->setNumTextureUnits(1024); - rsc->setCapability(RSC_ANISOTROPY); - rsc->setCapability(RSC_AUTOMIPMAP); - rsc->setCapability(RSC_DOT3); - rsc->setCapability(RSC_CUBEMAPPING); - rsc->setCapability(RSC_SCISSOR_TEST); - rsc->setCapability(RSC_TWO_SIDED_STENCIL); - rsc->setCapability(RSC_STENCIL_WRAP); - rsc->setCapability(RSC_HWOCCLUSION); - rsc->setCapability(RSC_USER_CLIP_PLANES); - rsc->setCapability(RSC_32BIT_INDEX); - rsc->setCapability(RSC_VERTEX_FORMAT_UBYTE4); - rsc->setCapability(RSC_TEXTURE_1D); - rsc->setCapability(RSC_TEXTURE_3D); - rsc->setCapability(RSC_NON_POWER_OF_2_TEXTURES); - rsc->setNonPOW2TexturesLimited(false); - rsc->setNumMultiRenderTargets(OGRE_MAX_MULTIPLE_RENDER_TARGETS); - rsc->setCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS); - rsc->setCapability(RSC_POINT_SPRITES); - rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS); - rsc->setMaxPointSize(2.19902e+012f); - rsc->setCapability(RSC_MIPMAP_LOD_BIAS); - rsc->setCapability(RSC_PERSTAGECONSTANT); - rsc->setCapability(RSC_HWSTENCIL); - rsc->setStencilBufferBitDepth(8); - rsc->setCapability(RSC_ADVANCED_BLEND_OPERATIONS); - rsc->setCapability(RSC_RTT_SEPARATE_DEPTHBUFFER); - rsc->setCapability(RSC_RTT_MAIN_DEPTHBUFFER_ATTACHABLE); - rsc->setCapability(RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL); - rsc->setCapability(RSC_VERTEX_BUFFER_INSTANCE_DATA); - rsc->setCapability(RSC_CAN_GET_COMPILED_SHADER_BUFFER); - - for (uint i=0; i < mDeviceManager->getDeviceCount(); ++i) - { - D3D9Device* device = mDeviceManager->getDevice(i); - IDirect3DDevice9* d3d9Device = device->getD3D9Device(); - - IDirect3DSurface9* pSurf; - - - // Check for hardware stencil support - d3d9Device->GetDepthStencilSurface(&pSurf); - - if (pSurf != NULL) - { - D3DSURFACE_DESC surfDesc; - - pSurf->GetDesc(&surfDesc); - pSurf->Release(); - - if (surfDesc.Format != D3DFMT_D15S1 && - surfDesc.Format != D3DFMT_D24S8 && - surfDesc.Format != D3DFMT_D24X4S4 && - surfDesc.Format != D3DFMT_D24FS8) - rsc->unsetCapability(RSC_HWSTENCIL); - } - - // Check for hardware occlusion support - HRESULT hr = d3d9Device->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL); - - if (FAILED(hr)) - rsc->unsetCapability(RSC_HWOCCLUSION); - } - - // Update RS caps using the minimum value found in adapter list. - for (unsigned int i=0; i < mDriverList->count(); ++i) - { - D3D9Driver* pCurDriver = mDriverList->item(i); - const D3DCAPS9& rkCurCaps = pCurDriver->getD3D9DeviceCaps(); - - if (rkCurCaps.MaxSimultaneousTextures < rsc->getNumTextureUnits()) - { - rsc->setNumTextureUnits(static_cast(rkCurCaps.MaxSimultaneousTextures)); - } - - // Check for Anisotropy. - if (rkCurCaps.MaxAnisotropy <= 1) - rsc->unsetCapability(RSC_ANISOTROPY); - - // Check automatic mipmap generation. - if ((rkCurCaps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) == 0) - rsc->unsetCapability(RSC_AUTOMIPMAP); - - // Check Dot product 3. - if ((rkCurCaps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) == 0) - rsc->unsetCapability(RSC_DOT3); - - // Scissor test - if ((rkCurCaps.RasterCaps & D3DPRASTERCAPS_SCISSORTEST) == 0) - rsc->unsetCapability(RSC_SCISSOR_TEST); - - - // Two-sided stencil - if ((rkCurCaps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) == 0) - rsc->unsetCapability(RSC_TWO_SIDED_STENCIL); - - // stencil wrap - if ((rkCurCaps.StencilCaps & D3DSTENCILCAPS_INCR) == 0 || - (rkCurCaps.StencilCaps & D3DSTENCILCAPS_DECR) == 0) - rsc->unsetCapability(RSC_STENCIL_WRAP); - - // User clip planes - if (rkCurCaps.MaxUserClipPlanes == 0) - rsc->unsetCapability(RSC_USER_CLIP_PLANES); - - // D3DFMT_INDEX32 type? - if (rkCurCaps.MaxVertexIndex <= 0xFFFF) - rsc->unsetCapability(RSC_32BIT_INDEX); - - // UBYTE4 type? - if ((rkCurCaps.DeclTypes & D3DDTCAPS_UBYTE4) == 0) - rsc->unsetCapability(RSC_VERTEX_FORMAT_UBYTE4); - - // Check cube map support. - if ((rkCurCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) == 0) - rsc->unsetCapability(RSC_CUBEMAPPING); - - // 3D textures? - if ((rkCurCaps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) == 0) - rsc->unsetCapability(RSC_TEXTURE_3D); - - if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_POW2) - { - // Conditional support for non POW2 - if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) - rsc->setNonPOW2TexturesLimited(true); - - // Only power of 2 supported. - else - rsc->unsetCapability(RSC_NON_POWER_OF_2_TEXTURES); - } - - // Number of render targets - if (rkCurCaps.NumSimultaneousRTs < rsc->getNumMultiRenderTargets()) - { - rsc->setNumMultiRenderTargets(std::min((ushort)rkCurCaps.NumSimultaneousRTs, (ushort)OGRE_MAX_MULTIPLE_RENDER_TARGETS)); - } - - if((rkCurCaps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS) == 0) - { - rsc->unsetCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS); - } - - // Point sprites - if (rkCurCaps.MaxPointSize <= 1.0f) - { - rsc->unsetCapability(RSC_POINT_SPRITES); - // sprites and extended parameters go together in D3D - rsc->unsetCapability(RSC_POINT_EXTENDED_PARAMETERS); - } - - // Take the minimum point size. - if (rkCurCaps.MaxPointSize < rsc->getMaxPointSize()) - rsc->setMaxPointSize(rkCurCaps.MaxPointSize); - - // Mipmap LOD biasing? - if ((rkCurCaps.RasterCaps & D3DPRASTERCAPS_MIPMAPLODBIAS) == 0) - rsc->unsetCapability(RSC_MIPMAP_LOD_BIAS); - - - // Do we support per-stage src_manual constants? - // HACK - ATI drivers seem to be buggy and don't support per-stage constants properly? - // TODO: move this to RSC - if((rkCurCaps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT) == 0) - rsc->unsetCapability(RSC_PERSTAGECONSTANT); - - // Advanced blend operations? min max subtract rev - if((rkCurCaps.PrimitiveMiscCaps & D3DPMISCCAPS_BLENDOP) == 0) - rsc->unsetCapability(RSC_ADVANCED_BLEND_OPERATIONS); - } - - // Blending between stages supported - rsc->setCapability(RSC_BLENDING); - - - // We always support compression, D3DX will decompress if device does not support - rsc->setCapability(RSC_TEXTURE_COMPRESSION); - rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT); - - // We always support VBOs - rsc->setCapability(RSC_VBO); - - - convertVertexShaderCaps(rsc); - convertPixelShaderCaps(rsc); - - // Adapter details - const D3DADAPTER_IDENTIFIER9& adapterID = mActiveD3DDriver->getAdapterIdentifier(); - - // determine vendor - // Full list of vendors here: http://www.pcidatabase.com/vendors.php?sort=id - switch(adapterID.VendorId) - { - case 0x10DE: - rsc->setVendor(GPU_NVIDIA); - break; - case 0x1002: - rsc->setVendor(GPU_AMD); - break; - case 0x163C: - case 0x8086: - rsc->setVendor(GPU_INTEL); - break; - case 0x5333: - rsc->setVendor(GPU_S3); - break; - case 0x3D3D: - rsc->setVendor(GPU_3DLABS); - break; - case 0x102B: - rsc->setVendor(GPU_MATROX); - break; - case 0x1039: - rsc->setVendor(GPU_SIS); - break; - default: - rsc->setVendor(GPU_UNKNOWN); - break; - }; - - // Infinite projection? - // We have no capability for this, so we have to base this on our - // experience and reports from users - // Non-vertex program capable hardware does not appear to support it - if (rsc->hasCapability(RSC_VERTEX_PROGRAM)) - { - // GeForce4 Ti (and presumably GeForce3) does not - // render infinite projection properly, even though it does in GL - // So exclude all cards prior to the FX range from doing infinite - if (rsc->getVendor() != GPU_NVIDIA || // not nVidia - !((adapterID.DeviceId >= 0x200 && adapterID.DeviceId <= 0x20F) || //gf3 - (adapterID.DeviceId >= 0x250 && adapterID.DeviceId <= 0x25F) || //gf4ti - (adapterID.DeviceId >= 0x280 && adapterID.DeviceId <= 0x28F) || //gf4ti - (adapterID.DeviceId >= 0x170 && adapterID.DeviceId <= 0x18F) || //gf4 go - (adapterID.DeviceId >= 0x280 && adapterID.DeviceId <= 0x28F))) //gf4ti go - { - rsc->setCapability(RSC_INFINITE_FAR_PLANE); - } - - } - - // We always support rendertextures bigger than the frame buffer - rsc->setCapability(RSC_HWRENDER_TO_TEXTURE); - - // Determine if any floating point texture format is supported - D3DFORMAT floatFormats[6] = {D3DFMT_R16F, D3DFMT_G16R16F, - D3DFMT_A16B16G16R16F, D3DFMT_R32F, D3DFMT_G32R32F, - D3DFMT_A32B32G32R32F}; - IDirect3DSurface9* bbSurf; - renderWindow->getCustomAttribute("DDBACKBUFFER", &bbSurf); - D3DSURFACE_DESC bbSurfDesc; - bbSurf->GetDesc(&bbSurfDesc); - - for (int i = 0; i < 6; ++i) - { - if (SUCCEEDED(mD3D->CheckDeviceFormat(mActiveD3DDriver->getAdapterNumber(), - D3DDEVTYPE_HAL, bbSurfDesc.Format, - 0, D3DRTYPE_TEXTURE, floatFormats[i]))) - { - rsc->setCapability(RSC_TEXTURE_FLOAT); - break; - } - - } - - - // TODO: make convertVertex/Fragment fill in rsc - // TODO: update the below line to use rsc - // Vertex textures - if (rsc->isShaderProfileSupported("vs_3_0")) - { - // Run through all the texture formats looking for any which support - // vertex texture fetching. Must have at least one! - // All ATI Radeon up to X1n00 say they support vs_3_0, - // but they support no texture formats for vertex texture fetch (cheaters!) - if (checkVertexTextureFormats(renderWindow)) - { - rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH); - // always 4 vertex texture units in vs_3_0, and never shared - rsc->setNumVertexTextureUnits(4); - rsc->setVertexTextureUnitsShared(false); - } - } - else - { - //True HW Instancing is supported since Shader model 3.0 ATI has a nasty - //hack for enabling it in their SM 2.0 cards, but we don't (and won't) support it - rsc->unsetCapability( RSC_VERTEX_BUFFER_INSTANCE_DATA ); - } - - // Check alpha to coverage support - // this varies per vendor! But at least SM3 is required - if (rsc->isShaderProfileSupported("ps_3_0")) - { - // NVIDIA needs a separate check - if (rsc->getVendor() == GPU_NVIDIA) - { - if (mD3D->CheckDeviceFormat( - D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE, - (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')) == S_OK) - { - rsc->setCapability(RSC_ALPHA_TO_COVERAGE); - } - - } - else if (rsc->getVendor() == GPU_AMD) - { - // There is no check on ATI, we have to assume SM3 == support - rsc->setCapability(RSC_ALPHA_TO_COVERAGE); - } - - // no other cards have Dx9 hacks for alpha to coverage, as far as I know - } - - - if (mRealCapabilities == NULL) - { - mRealCapabilities = rsc; - mRealCapabilities->addShaderProfile("hlsl"); - - // if we are using custom capabilities, then - // mCurrentCapabilities has already been loaded - if(!mUseCustomCapabilities) - mCurrentCapabilities = mRealCapabilities; + left -= offsetX; + right -= offsetX; + top -= offsetY; + bottom -= offsetY; + } - fireEvent("RenderSystemCapabilitiesCreated"); + Real width = right - left; + Real height = top - bottom; + Real q, qn; + if (farPlane == 0) + { + q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST; + qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 1); + } + else + { + q = farPlane / ( farPlane - nearPlane ); + qn = -q * nearPlane; + } + dest = Matrix4::ZERO; + dest[0][0] = 2 * nearPlane / width; + dest[0][2] = (right+left) / width; + dest[1][1] = 2 * nearPlane / height; + dest[1][2] = (top+bottom) / height; + if (forGpuProgram) + { + dest[2][2] = -q; + dest[3][2] = -1.0f; + } + else + { + dest[2][2] = q; + dest[3][2] = 1.0f; + } + dest[2][3] = qn; + } - initialiseFromRenderSystemCapabilities(mCurrentCapabilities, renderWindow); - } - - return rsc; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::convertVertexShaderCaps(RenderSystemCapabilities* rsc) const - { - ushort major = 0xFF; - ushort minor = 0xFF; - D3DCAPS9 minVSCaps; - - // Find the device with the lowest vertex shader caps. - for (unsigned int i=0; i < mDriverList->count(); ++i) - { - D3D9Driver* pCurDriver = mDriverList->item(i); - const D3DCAPS9& rkCurCaps = pCurDriver->getD3D9DeviceCaps(); - ushort currMajor = static_cast((rkCurCaps.VertexShaderVersion & 0x0000FF00) >> 8); - ushort currMinor = static_cast(rkCurCaps.VertexShaderVersion & 0x000000FF); - - if (currMajor < major) - { - major = currMajor; - minor = currMinor; - minVSCaps = rkCurCaps; - } - else if (currMajor == major && currMinor < minor) - { - minor = currMinor; - minVSCaps = rkCurCaps; - } - } - - // In case we didn't found any vertex shader support - // try the IDirect3DDevice9 caps instead of the IDirect3D9 - // software vertex processing is reported there - if (major == 0 && minor == 0) - { - IDirect3DDevice9* lpD3DDevice9 = getActiveD3D9Device(); - D3DCAPS9 d3dDeviceCaps9; - lpD3DDevice9->GetDeviceCaps(&d3dDeviceCaps9); - major = static_cast((d3dDeviceCaps9.VertexShaderVersion & 0x0000FF00) >> 8); - minor = static_cast(d3dDeviceCaps9.VertexShaderVersion & 0x000000FF); - } - - bool vs2x = false; - bool vs2a = false; - - // Special case detection for vs_2_x/a support - if (major >= 2) - { - if ((minVSCaps.VS20Caps.Caps & D3DVS20CAPS_PREDICATION) && - (minVSCaps.VS20Caps.DynamicFlowControlDepth > 0) && - (minVSCaps.VS20Caps.NumTemps >= 12)) - { - vs2x = true; - } - - if ((minVSCaps.VS20Caps.Caps & D3DVS20CAPS_PREDICATION) && - (minVSCaps.VS20Caps.DynamicFlowControlDepth > 0) && - (minVSCaps.VS20Caps.NumTemps >= 13)) - { - vs2a = true; - } - } - - // Populate max param count - switch (major) - { - case 1: - // No boolean params allowed - rsc->setVertexProgramConstantBoolCount(0); - // No integer params allowed - rsc->setVertexProgramConstantIntCount(0); - // float params, always 4D - rsc->setVertexProgramConstantFloatCount(static_cast(minVSCaps.MaxVertexShaderConst)); - - break; - case 2: - // 16 boolean params allowed - rsc->setVertexProgramConstantBoolCount(16); - // 16 integer params allowed, 4D - rsc->setVertexProgramConstantIntCount(16); - // float params, always 4D - rsc->setVertexProgramConstantFloatCount(static_cast(minVSCaps.MaxVertexShaderConst)); - break; - case 3: - // 16 boolean params allowed - rsc->setVertexProgramConstantBoolCount(16); - // 16 integer params allowed, 4D - rsc->setVertexProgramConstantIntCount(16); - // float params, always 4D - rsc->setVertexProgramConstantFloatCount(static_cast(minVSCaps.MaxVertexShaderConst)); - break; - } - - // populate syntax codes in program manager (no breaks in this one so it falls through) - switch(major) - { - case 3: - rsc->addShaderProfile("vs_3_0"); - case 2: - if (vs2x) - rsc->addShaderProfile("vs_2_x"); - if (vs2a) - rsc->addShaderProfile("vs_2_a"); - - rsc->addShaderProfile("vs_2_0"); - case 1: - rsc->addShaderProfile("vs_1_1"); - rsc->setCapability(RSC_VERTEX_PROGRAM); - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::convertPixelShaderCaps(RenderSystemCapabilities* rsc) const - { - ushort major = 0xFF; - ushort minor = 0xFF; - D3DCAPS9 minPSCaps; - - // Find the device with the lowest pixel shader caps. - for (unsigned int i=0; i < mDriverList->count(); ++i) - { - D3D9Driver* pCurDriver = mDriverList->item(i); - const D3DCAPS9& currCaps = pCurDriver->getD3D9DeviceCaps(); - ushort currMajor = static_cast((currCaps.PixelShaderVersion & 0x0000FF00) >> 8); - ushort currMinor = static_cast(currCaps.PixelShaderVersion & 0x000000FF); - - if (currMajor < major) - { - major = currMajor; - minor = currMinor; - minPSCaps = currCaps; - } - else if (currMajor == major && currMinor < minor) - { - minor = currMinor; - minPSCaps = currCaps; - } - } - - bool ps2a = false; - bool ps2b = false; - bool ps2x = false; - - // Special case detection for ps_2_x/a/b support - if (major >= 2) - { - if ((minPSCaps.PS20Caps.Caps & D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT) && - (minPSCaps.PS20Caps.NumTemps >= 32)) - { - ps2b = true; - } - - if ((minPSCaps.PS20Caps.Caps & D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT) && - (minPSCaps.PS20Caps.Caps & D3DPS20CAPS_NODEPENDENTREADLIMIT) && - (minPSCaps.PS20Caps.Caps & D3DPS20CAPS_ARBITRARYSWIZZLE) && - (minPSCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) && - (minPSCaps.PS20Caps.Caps & D3DPS20CAPS_PREDICATION) && - (minPSCaps.PS20Caps.NumTemps >= 22)) - { - ps2a = true; - } - - // Does this enough? - if (ps2a || ps2b) - { - ps2x = true; - } - } - - switch (major) - { - case 1: - // no boolean params allowed - rsc->setFragmentProgramConstantBoolCount(0); - // no integer params allowed - rsc->setFragmentProgramConstantIntCount(0); - // float params, always 4D - // NB in ps_1_x these are actually stored as fixed point values, - // but they are entered as floats - rsc->setFragmentProgramConstantFloatCount(8); - break; - case 2: - // 16 boolean params allowed - rsc->setFragmentProgramConstantBoolCount(16); - // 16 integer params allowed, 4D - rsc->setFragmentProgramConstantIntCount(16); - // float params, always 4D - rsc->setFragmentProgramConstantFloatCount(32); - break; - case 3: - // 16 boolean params allowed - rsc->setFragmentProgramConstantBoolCount(16); - // 16 integer params allowed, 4D - rsc->setFragmentProgramConstantIntCount(16); - // float params, always 4D - rsc->setFragmentProgramConstantFloatCount(224); - break; - } - - // populate syntax codes in program manager (no breaks in this one so it falls through) - switch(major) - { - case 3: - if (minor > 0) - rsc->addShaderProfile("ps_3_x"); - - rsc->addShaderProfile("ps_3_0"); - case 2: - if (ps2x) - rsc->addShaderProfile("ps_2_x"); - if (ps2a) - rsc->addShaderProfile("ps_2_a"); - if (ps2b) - rsc->addShaderProfile("ps_2_b"); - - rsc->addShaderProfile("ps_2_0"); - case 1: - if (major > 1 || minor >= 4) - rsc->addShaderProfile("ps_1_4"); - if (major > 1 || minor >= 3) - rsc->addShaderProfile("ps_1_3"); - if (major > 1 || minor >= 2) - rsc->addShaderProfile("ps_1_2"); - - rsc->addShaderProfile("ps_1_1"); - rsc->setCapability(RSC_FRAGMENT_PROGRAM); - } - } - //----------------------------------------------------------------------- - bool D3D9RenderSystem::checkVertexTextureFormats(D3D9RenderWindow* renderWindow) const - { - bool anySupported = false; - - IDirect3DSurface9* bbSurf; - renderWindow->getCustomAttribute("DDBACKBUFFER", &bbSurf); - D3DSURFACE_DESC bbSurfDesc; - bbSurf->GetDesc(&bbSurfDesc); - - for (uint ipf = static_cast(PF_L8); ipf < static_cast(PF_COUNT); ++ipf) - { - PixelFormat pf = (PixelFormat)ipf; - - D3DFORMAT fmt = - D3D9Mappings::_getPF(D3D9Mappings::_getClosestSupportedPF(pf)); - - if (SUCCEEDED(mD3D->CheckDeviceFormat( - mActiveD3DDriver->getAdapterNumber(), D3DDEVTYPE_HAL, bbSurfDesc.Format, - D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, fmt))) - { - // cool, at least one supported - anySupported = true; - LogManager::getSingleton().stream() - << "D3D9: Vertex texture format supported - " - << PixelUtil::getFormatName(pf); - } - } - - return anySupported; - - } - //----------------------------------------------------------------------- - void D3D9RenderSystem::initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary) - { - if (caps->getRenderSystemName() != getName()) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Trying to initialize D3D9RenderSystem from RenderSystemCapabilities that do not support Direct3D9", - "D3D9RenderSystem::initialiseFromRenderSystemCapabilities"); - } - if (caps->isShaderProfileSupported("hlsl")) - HighLevelGpuProgramManager::getSingleton().addFactory(mHLSLProgramFactory); - - Log* defaultLog = LogManager::getSingleton().getDefaultLog(); - if (defaultLog) - { - caps->log(defaultLog); - } - } - - //----------------------------------------------------------------------- - bool D3D9RenderSystem::_checkTextureFilteringSupported(TextureType ttype, PixelFormat format, int usage) - { - // Gets D3D format - D3DFORMAT d3dPF = D3D9Mappings::_getPF(format); - if (d3dPF == D3DFMT_UNKNOWN) - return false; - - for (uint i = 0; i < mDeviceManager->getDeviceCount(); ++i) - { - D3D9Device* currDevice = mDeviceManager->getDevice(i); - D3D9RenderWindow* currDevicePrimaryWindow = currDevice->getPrimaryWindow(); - IDirect3DSurface9* pSurface = currDevicePrimaryWindow->getRenderSurface(); - D3DSURFACE_DESC srfDesc; - - // Get surface desc - if (FAILED(pSurface->GetDesc(&srfDesc))) - return false; - - // Calculate usage - DWORD d3dusage = D3DUSAGE_QUERY_FILTER; - if (usage & TU_RENDERTARGET) - d3dusage |= D3DUSAGE_RENDERTARGET; - if (usage & TU_DYNAMIC) - d3dusage |= D3DUSAGE_DYNAMIC; - - // Detect resource type - D3DRESOURCETYPE rtype; - switch(ttype) - { - case TEX_TYPE_1D: - case TEX_TYPE_2D: - rtype = D3DRTYPE_TEXTURE; - break; - case TEX_TYPE_3D: - rtype = D3DRTYPE_VOLUMETEXTURE; - break; - case TEX_TYPE_CUBE_MAP: - rtype = D3DRTYPE_CUBETEXTURE; - break; - default: - return false; - } - - HRESULT hr = mD3D->CheckDeviceFormat( - currDevice->getAdapterNumber(), - currDevice->getDeviceType(), - srfDesc.Format, - d3dusage, - rtype, - d3dPF); - - if (FAILED(hr)) - return false; - } - - return true; - } - //----------------------------------------------------------------------- - MultiRenderTarget * D3D9RenderSystem::createMultiRenderTarget(const String & name) - { - MultiRenderTarget *retval; - retval = OGRE_NEW D3D9MultiRenderTarget(name); - attachRenderTarget(*retval); - - return retval; - } - //--------------------------------------------------------------------- - RenderTarget* D3D9RenderSystem::detachRenderTarget(const String &name) - { - RenderTarget* target = RenderSystem::detachRenderTarget(name); - detachRenderTargetImpl(name); - return target; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::detachRenderTargetImpl(const String& name) - { - // Check render windows - D3D9RenderWindowList::iterator sw; - for (sw = mRenderWindows.begin(); sw != mRenderWindows.end(); ++sw) - { - if ((*sw)->getName() == name) - { - mRenderWindows.erase(sw); - break; - } - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::destroyRenderTarget(const String& name) - { - detachRenderTargetImpl(name); - - // Do the real removal - RenderSystem::destroyRenderTarget(name); - } - //--------------------------------------------------------------------- - String D3D9RenderSystem::getErrorDescription( long errorNumber ) const - { - const String errMsg = DXGetErrorDescription( errorNumber ); - return errMsg; - } - //--------------------------------------------------------------------- - VertexElementType D3D9RenderSystem::getColourVertexElementType() const - { - return VET_COLOUR_ARGB; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_convertProjectionMatrix(const Matrix4& matrix, - Matrix4& dest, bool forGpuProgram) - { - dest = matrix; - - // Convert depth range from [-1,+1] to [0,1] - dest[2][0] = (dest[2][0] + dest[3][0]) / 2; - dest[2][1] = (dest[2][1] + dest[3][1]) / 2; - dest[2][2] = (dest[2][2] + dest[3][2]) / 2; - dest[2][3] = (dest[2][3] + dest[3][3]) / 2; - - if (!forGpuProgram) - { - // Convert right-handed to left-handed - dest[0][2] = -dest[0][2]; - dest[1][2] = -dest[1][2]; - dest[2][2] = -dest[2][2]; - dest[3][2] = -dest[3][2]; - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_makeProjectionMatrix(const Radian& fovy, Real aspect, Real nearPlane, - Real farPlane, Matrix4& dest, bool forGpuProgram) - { - Radian theta ( fovy * 0.5 ); - Real h = 1 / Math::Tan(theta); - Real w = h / aspect; - Real q, qn; - if (farPlane == 0) - { - q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST; - qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 1); - } - else - { - q = farPlane / ( farPlane - nearPlane ); - qn = -q * nearPlane; - } - - dest = Matrix4::ZERO; - dest[0][0] = w; - dest[1][1] = h; - - if (forGpuProgram) - { - dest[2][2] = -q; - dest[3][2] = -1.0f; - } - else - { - dest[2][2] = q; - dest[3][2] = 1.0f; - } - - dest[2][3] = qn; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, - Matrix4& dest, bool forGpuProgram ) - { - Radian thetaY (fovy / 2.0f); - Real tanThetaY = Math::Tan(thetaY); - - //Real thetaX = thetaY * aspect; - Real tanThetaX = tanThetaY * aspect; //Math::Tan(thetaX); - Real half_w = tanThetaX * nearPlane; - Real half_h = tanThetaY * nearPlane; - Real iw = static_cast(1.0 / half_w); - Real ih = static_cast(1.0 / half_h); - Real q; - if (farPlane == 0) - { - q = 0; - } - else - { - q = static_cast(1.0 / (farPlane - nearPlane)); - } - - dest = Matrix4::ZERO; - dest[0][0] = iw; - dest[1][1] = ih; - dest[2][2] = q; - dest[2][3] = -nearPlane / (farPlane - nearPlane); - dest[3][3] = 1; - - if (forGpuProgram) - { - dest[2][2] = -dest[2][2]; - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setAmbientLight( float r, float g, float b ) - { - HRESULT hr = __SetRenderState( D3DRS_AMBIENT, D3DCOLOR_COLORVALUE( r, g, b, 1.0f ) ); - if( FAILED( hr ) ) - OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, - "Failed to set render stat D3DRS_AMBIENT", "D3D9RenderSystem::setAmbientLight" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_useLights(const LightList& lights, unsigned short limit) - { - IDirect3DDevice9* activeDevice = getActiveD3D9Device(); - LightList::const_iterator i, iend; - iend = lights.end(); - unsigned short num = 0; - for (i = lights.begin(); i != iend && num < limit; ++i, ++num) - { - setD3D9Light(num, *i); - } - // Disable extra lights - for (; num < mCurrentLights[activeDevice]; ++num) - { - setD3D9Light(num, NULL); - } - mCurrentLights[activeDevice] = std::min(limit, static_cast(lights.size())); - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setShadingType( ShadeOptions so ) - { - HRESULT hr = __SetRenderState( D3DRS_SHADEMODE, D3D9Mappings::get(so) ); - if( FAILED( hr ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Failed to set render stat D3DRS_SHADEMODE", "D3D9RenderSystem::setShadingType" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setLightingEnabled( bool enabled ) - { - HRESULT hr; - if( FAILED( hr = __SetRenderState( D3DRS_LIGHTING, enabled ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Failed to set render state D3DRS_LIGHTING", "D3D9RenderSystem::setLightingEnabled" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setD3D9Light( size_t index, Light* lt ) - { - HRESULT hr; - - D3DLIGHT9 d3dLight; - ZeroMemory( &d3dLight, sizeof(d3dLight) ); - - if (!lt) - { - if( FAILED( hr = getActiveD3D9Device()->LightEnable( static_cast(index), FALSE) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to disable light", "D3D9RenderSystem::setD3D9Light" ); - } - else - { - switch( lt->getType() ) - { - case Light::LT_POINT: - d3dLight.Type = D3DLIGHT_POINT; - break; - - case Light::LT_DIRECTIONAL: - d3dLight.Type = D3DLIGHT_DIRECTIONAL; - break; - - case Light::LT_SPOTLIGHT: - d3dLight.Type = D3DLIGHT_SPOT; - d3dLight.Falloff = lt->getSpotlightFalloff(); - d3dLight.Theta = lt->getSpotlightInnerAngle().valueRadians(); - d3dLight.Phi = lt->getSpotlightOuterAngle().valueRadians(); - break; - } - - ColourValue col; - col = lt->getDiffuseColour(); - d3dLight.Diffuse = D3DXCOLOR( col.r, col.g, col.b, col.a ); - - col = lt->getSpecularColour(); - d3dLight.Specular = D3DXCOLOR( col.r, col.g, col.b, col.a ); - - Vector3 vec; - if( lt->getType() != Light::LT_DIRECTIONAL ) - { - vec = lt->getDerivedPosition(true); - d3dLight.Position = D3DXVECTOR3( vec.x, vec.y, vec.z ); - } - if( lt->getType() != Light::LT_POINT ) - { - vec = lt->getDerivedDirection(); - d3dLight.Direction = D3DXVECTOR3( vec.x, vec.y, vec.z ); - } - - d3dLight.Range = lt->getAttenuationRange(); - d3dLight.Attenuation0 = lt->getAttenuationConstant(); - d3dLight.Attenuation1 = lt->getAttenuationLinear(); - d3dLight.Attenuation2 = lt->getAttenuationQuadric(); - - if( FAILED( hr = getActiveD3D9Device()->SetLight( static_cast(index), &d3dLight ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set light details", "D3D9RenderSystem::setD3D9Light" ); - - if( FAILED( hr = getActiveD3D9Device()->LightEnable( static_cast(index), TRUE ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to enable light", "D3D9RenderSystem::setD3D9Light" ); - } - - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setViewMatrix( const Matrix4 &m ) - { - // save latest view matrix - mViewMatrix = m; - mViewMatrix[2][0] = -mViewMatrix[2][0]; - mViewMatrix[2][1] = -mViewMatrix[2][1]; - mViewMatrix[2][2] = -mViewMatrix[2][2]; - mViewMatrix[2][3] = -mViewMatrix[2][3]; - - mDxViewMat = D3D9Mappings::makeD3DXMatrix( mViewMatrix ); - - HRESULT hr; - if( FAILED( hr = getActiveD3D9Device()->SetTransform( D3DTS_VIEW, &mDxViewMat ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot set D3D9 view matrix", "D3D9RenderSystem::_setViewMatrix" ); - - // also mark clip planes dirty - if (!mClipPlanes.empty()) - mClipPlanesDirty = true; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setProjectionMatrix( const Matrix4 &m ) - { - // save latest matrix - mDxProjMat = D3D9Mappings::makeD3DXMatrix( m ); - - if( mActiveRenderTarget->requiresTextureFlipping() ) - { - // Invert transformed y - mDxProjMat._12 = - mDxProjMat._12; - mDxProjMat._22 = - mDxProjMat._22; - mDxProjMat._32 = - mDxProjMat._32; - mDxProjMat._42 = - mDxProjMat._42; - } - - HRESULT hr; - if( FAILED( hr = getActiveD3D9Device()->SetTransform( D3DTS_PROJECTION, &mDxProjMat ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot set D3D9 projection matrix", "D3D9RenderSystem::_setProjectionMatrix" ); - - // also mark clip planes dirty - if (!mClipPlanes.empty()) - mClipPlanesDirty = true; - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setWorldMatrix( const Matrix4 &m ) - { - // save latest matrix - mDxWorldMat = D3D9Mappings::makeD3DXMatrix( m ); - - HRESULT hr; - if( FAILED( hr = getActiveD3D9Device()->SetTransform( D3DTS_WORLD, &mDxWorldMat ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot set D3D9 world matrix", "D3D9RenderSystem::_setWorldMatrix" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setSurfaceParams( const ColourValue &ambient, const ColourValue &diffuse, - const ColourValue &specular, const ColourValue &emissive, Real shininess, - TrackVertexColourType tracking ) - { - - D3DMATERIAL9 material; - material.Diffuse = D3DXCOLOR( diffuse.r, diffuse.g, diffuse.b, diffuse.a ); - material.Ambient = D3DXCOLOR( ambient.r, ambient.g, ambient.b, ambient.a ); - material.Specular = D3DXCOLOR( specular.r, specular.g, specular.b, specular.a ); - material.Emissive = D3DXCOLOR( emissive.r, emissive.g, emissive.b, emissive.a ); - material.Power = shininess; - - HRESULT hr = getActiveD3D9Device()->SetMaterial( &material ); - if( FAILED( hr ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting D3D material", "D3D9RenderSystem::_setSurfaceParams" ); - - - if(tracking != TVC_NONE) - { - __SetRenderState(D3DRS_COLORVERTEX, TRUE); - __SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, (tracking&TVC_AMBIENT)?D3DMCS_COLOR1:D3DMCS_MATERIAL); - __SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, (tracking&TVC_DIFFUSE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); - __SetRenderState(D3DRS_SPECULARMATERIALSOURCE, (tracking&TVC_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL); - __SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, (tracking&TVC_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); - } - else - { - __SetRenderState(D3DRS_COLORVERTEX, FALSE); - } - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setPointParameters(Real size, - bool attenuationEnabled, Real constant, Real linear, Real quadratic, - Real minSize, Real maxSize) - { - if(attenuationEnabled) - { - // scaling required - __SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); - __SetFloatRenderState(D3DRS_POINTSCALE_A, constant); - __SetFloatRenderState(D3DRS_POINTSCALE_B, linear); - __SetFloatRenderState(D3DRS_POINTSCALE_C, quadratic); - } - else - { - // no scaling required - __SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); - } - __SetFloatRenderState(D3DRS_POINTSIZE, size); - __SetFloatRenderState(D3DRS_POINTSIZE_MIN, minSize); - if (maxSize == 0.0f) - maxSize = mCurrentCapabilities->getMaxPointSize(); - __SetFloatRenderState(D3DRS_POINTSIZE_MAX, maxSize); - - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setPointSpritesEnabled(bool enabled) - { - if (enabled) - { - __SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); - } - else - { - __SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTexture( size_t stage, bool enabled, const TexturePtr& tex ) - { - HRESULT hr; - D3D9TexturePtr dt = tex.staticCast(); - if (enabled && !dt.isNull()) - { - // note used - dt->touch(); - - IDirect3DBaseTexture9 *pTex = dt->getTexture(); - if (mTexStageDesc[stage].pTex != pTex) - { - hr = getActiveD3D9Device()->SetTexture(static_cast(stage), pTex); - if( hr != S_OK ) - { - String str = "Unable to set texture '" + tex->getName() + "' in D3D9"; - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9RenderSystem::_setTexture" ); - } - - // set stage desc. - mTexStageDesc[stage].pTex = pTex; - mTexStageDesc[stage].texType = D3D9Mappings::get(dt->getTextureType()); - - // Set gamma now too - if (dt->isHardwareGammaReadToBeUsed()) - { - __SetSamplerState(getSamplerId(stage), D3DSAMP_SRGBTEXTURE, TRUE); - } - else - { - __SetSamplerState(getSamplerId(stage), D3DSAMP_SRGBTEXTURE, FALSE); - } - } - } - else - { - if (mTexStageDesc[stage].pTex != 0) - { - hr = getActiveD3D9Device()->SetTexture(static_cast(stage), 0); - if( hr != S_OK ) - { - String str = "Unable to disable texture '" + StringConverter::toString(stage) + "' in D3D9"; - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9RenderSystem::_setTexture" ); - } - } - - hr = __SetTextureStageState(static_cast(stage), D3DTSS_COLOROP, D3DTOP_DISABLE); - if( hr != S_OK ) - { - String str = "Unable to disable texture '" + StringConverter::toString(stage) + "' in D3D9"; - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9RenderSystem::_setTexture" ); - } - - // set stage desc. to defaults - mTexStageDesc[stage].pTex = 0; - mTexStageDesc[stage].autoTexCoordType = TEXCALC_NONE; - mTexStageDesc[stage].coordIndex = 0; - mTexStageDesc[stage].texType = D3D9Mappings::D3D_TEX_TYPE_NORMAL; - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setVertexTexture(size_t stage, const TexturePtr& tex) - { - if (tex.isNull()) - { - - if (mTexStageDesc[stage].pVertexTex != 0) - { - HRESULT hr = getActiveD3D9Device()->SetTexture(D3DVERTEXTEXTURESAMPLER0 + static_cast(stage), 0); - if( hr != S_OK ) - { - String str = "Unable to disable vertex texture '" - + StringConverter::toString(stage) + "' in D3D9"; - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9RenderSystem::_setVertexTexture" ); - } - } - - // set stage desc. to defaults - mTexStageDesc[stage].pVertexTex = 0; - } - else - { - D3D9TexturePtr dt = tex.staticCast(); - // note used - dt->touch(); - - IDirect3DBaseTexture9 *pTex = dt->getTexture(); - if (mTexStageDesc[stage].pVertexTex != pTex) - { - HRESULT hr = getActiveD3D9Device()->SetTexture(D3DVERTEXTEXTURESAMPLER0 + static_cast(stage), pTex); - if( hr != S_OK ) - { - String str = "Unable to set vertex texture '" + tex->getName() + "' in D3D9"; - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9RenderSystem::_setVertexTexture" ); - } - - // set stage desc. - mTexStageDesc[stage].pVertexTex = pTex; - } - - } - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_disableTextureUnit(size_t texUnit) - { - RenderSystem::_disableTextureUnit(texUnit); - // also disable vertex texture unit - static TexturePtr nullPtr; - _setVertexTexture(texUnit, nullPtr); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureCoordSet( size_t stage, size_t index ) - { - // if vertex shader is being used, stage and index must match - if (mVertexProgramBound) - index = stage; - - HRESULT hr; - // Record settings - mTexStageDesc[stage].coordIndex = index; + // ------------------------------------------------------------------ + void D3D9RenderSystem::setClipPlane (ushort index, Real A, Real B, Real C, Real D) + { + float plane[4] = { A, B, C, D }; + getActiveD3D9Device()->SetClipPlane (index, plane); + } - if (mVertexProgramBound) - hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXCOORDINDEX, index ); + // ------------------------------------------------------------------ + void D3D9RenderSystem::enableClipPlane (ushort index, bool enable) + { + DWORD prev; + getActiveD3D9Device()->GetRenderState(D3DRS_CLIPPLANEENABLE, &prev); + __SetRenderState(D3DRS_CLIPPLANEENABLE, enable? + (prev | (1 << index)) : (prev & ~(1 << index))); + } + //--------------------------------------------------------------------- + HardwareOcclusionQuery* D3D9RenderSystem::createHardwareOcclusionQuery() + { + D3D9HardwareOcclusionQuery* ret = OGRE_NEW D3D9HardwareOcclusionQuery(); + mHwOcclusionQueries.push_back(ret); + return ret; + } + //--------------------------------------------------------------------- + Real D3D9RenderSystem::getHorizontalTexelOffset() + { + // D3D considers the origin to be in the center of a pixel + return -0.5f; + } + //--------------------------------------------------------------------- + Real D3D9RenderSystem::getVerticalTexelOffset() + { + // D3D considers the origin to be in the center of a pixel + return -0.5f; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::_applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane, + bool forGpuProgram) + { + // Thanks to Eric Lenyel for posting this calculation at www.terathon.com + + // Calculate the clip-space corner point opposite the clipping plane + // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and + // transform it into camera space by multiplying it + // by the inverse of the projection matrix + + /* generalised version + Vector4 q = matrix.inverse() * + Vector4(Math::Sign(plane.normal.x), Math::Sign(plane.normal.y), 1.0f, 1.0f); + */ + Vector4 q; + q.x = Math::Sign(plane.normal.x) / matrix[0][0]; + q.y = Math::Sign(plane.normal.y) / matrix[1][1]; + q.z = 1.0F; + // flip the next bit from Lengyel since we're right-handed + if (forGpuProgram) + { + q.w = (1.0F - matrix[2][2]) / matrix[2][3]; + } else - hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXCOORDINDEX, D3D9Mappings::get(mTexStageDesc[stage].autoTexCoordType, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) | index ); - if( FAILED( hr ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set texture coord. set index", "D3D9RenderSystem::_setTextureCoordSet" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureCoordCalculation( size_t stage, TexCoordCalcMethod m, - const Frustum* frustum) - { - HRESULT hr; - // record the stage state - mTexStageDesc[stage].autoTexCoordType = m; - mTexStageDesc[stage].frustum = frustum; + { + q.w = (1.0F + matrix[2][2]) / matrix[2][3]; + } - if (mVertexProgramBound) - hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXCOORDINDEX, mTexStageDesc[stage].coordIndex ); + // Calculate the scaled plane vector + Vector4 clipPlane4d(plane.normal.x, plane.normal.y, plane.normal.z, plane.d); + Vector4 c = clipPlane4d * (1.0F / (clipPlane4d.dotProduct(q))); + + // Replace the third row of the projection matrix + matrix[2][0] = c.x; + matrix[2][1] = c.y; + // flip the next bit from Lengyel since we're right-handed + if (forGpuProgram) + { + matrix[2][2] = c.z; + } else - hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXCOORDINDEX, D3D9Mappings::get(m, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) | mTexStageDesc[stage].coordIndex ); - if(FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set texture auto tex.coord. generation mode", "D3D9RenderSystem::_setTextureCoordCalculation" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureMipmapBias(size_t unit, float bias) - { - if (mCurrentCapabilities->hasCapability(RSC_MIPMAP_LOD_BIAS)) - { - // ugh - have to pass float data through DWORD with no conversion - HRESULT hr = __SetSamplerState(getSamplerId(unit), D3DSAMP_MIPMAPLODBIAS, - *(DWORD*)&bias); - if(FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set texture mipmap bias", - "D3D9RenderSystem::_setTextureMipmapBias" ); - - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureMatrix( size_t stage, const Matrix4& xForm ) - { - HRESULT hr; - D3DXMATRIX d3dMat; // the matrix we'll maybe apply - Matrix4 newMat = xForm; // the matrix we'll apply after conv. to D3D format - // Cache texcoord calc method to register - TexCoordCalcMethod autoTexCoordType = mTexStageDesc[stage].autoTexCoordType; - - // if a vertex program is bound, we mustn't set texture transforms - if (mVertexProgramBound) - { - hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); - if( FAILED( hr ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to disable texture coordinate transform", "D3D9RenderSystem::_setTextureMatrix" ); - return; - } - - - if (autoTexCoordType == TEXCALC_ENVIRONMENT_MAP) - { - if (mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().VertexProcessingCaps & D3DVTXPCAPS_TEXGEN_SPHEREMAP) - { - /** Invert the texture for the spheremap */ - Matrix4 ogreMatEnvMap = Matrix4::IDENTITY; - // set env_map values - ogreMatEnvMap[1][1] = -1.0f; - // concatenate with the xForm - newMat = newMat.concatenate(ogreMatEnvMap); - } - else - { - /* If envmap is applied, but device doesn't support spheremap, - then we have to use texture transform to make the camera space normal - reference the envmap properly. This isn't exactly the same as spheremap - (it looks nasty on flat areas because the camera space normals are the same) - but it's the best approximation we have in the absence of a proper spheremap */ - // concatenate with the xForm - newMat = newMat.concatenate(Matrix4::CLIPSPACE2DTOIMAGESPACE); - } - } - - // If this is a cubic reflection, we need to modify using the view matrix - if (autoTexCoordType == TEXCALC_ENVIRONMENT_MAP_REFLECTION) - { - // Get transposed 3x3 - // We want to transpose since that will invert an orthonormal matrix ie rotation - Matrix4 ogreViewTransposed; - ogreViewTransposed[0][0] = mViewMatrix[0][0]; - ogreViewTransposed[0][1] = mViewMatrix[1][0]; - ogreViewTransposed[0][2] = mViewMatrix[2][0]; - ogreViewTransposed[0][3] = 0.0f; - - ogreViewTransposed[1][0] = mViewMatrix[0][1]; - ogreViewTransposed[1][1] = mViewMatrix[1][1]; - ogreViewTransposed[1][2] = mViewMatrix[2][1]; - ogreViewTransposed[1][3] = 0.0f; - - ogreViewTransposed[2][0] = mViewMatrix[0][2]; - ogreViewTransposed[2][1] = mViewMatrix[1][2]; - ogreViewTransposed[2][2] = mViewMatrix[2][2]; - ogreViewTransposed[2][3] = 0.0f; - - ogreViewTransposed[3][0] = 0.0f; - ogreViewTransposed[3][1] = 0.0f; - ogreViewTransposed[3][2] = 0.0f; - ogreViewTransposed[3][3] = 1.0f; - - newMat = newMat.concatenate(ogreViewTransposed); - } - - if (autoTexCoordType == TEXCALC_PROJECTIVE_TEXTURE) - { - // Derive camera space to projector space transform - // To do this, we need to undo the camera view matrix, then - // apply the projector view & projection matrices - newMat = mViewMatrix.inverse(); - if(mTexProjRelative) - { - Matrix4 viewMatrix; - mTexStageDesc[stage].frustum->calcViewMatrixRelative(mTexProjRelativeOrigin, viewMatrix); - newMat = viewMatrix * newMat; - } - else - { - newMat = mTexStageDesc[stage].frustum->getViewMatrix() * newMat; - } - newMat = mTexStageDesc[stage].frustum->getProjectionMatrix() * newMat; - newMat = Matrix4::CLIPSPACE2DTOIMAGESPACE * newMat; - newMat = xForm * newMat; - } - - // need this if texture is a cube map, to invert D3D's z coord - if (autoTexCoordType != TEXCALC_NONE && - autoTexCoordType != TEXCALC_PROJECTIVE_TEXTURE) - { - newMat[2][0] = -newMat[2][0]; - newMat[2][1] = -newMat[2][1]; - newMat[2][2] = -newMat[2][2]; - newMat[2][3] = -newMat[2][3]; - } - - // convert our matrix to D3D format - d3dMat = D3D9Mappings::makeD3DXMatrix(newMat); - - // set the matrix if it's not the identity - if (!D3DXMatrixIsIdentity(&d3dMat)) - { - /* It's seems D3D automatically add a texture coordinate with value 1, - and fill up the remaining texture coordinates with 0 for the input - texture coordinates before pass to texture coordinate transformation. - - NOTE: It's difference with D3DDECLTYPE enumerated type expand in - DirectX SDK documentation! - - So we should prepare the texcoord transform, make the transformation - just like standardized vector expand, thus, fill w with value 1 and - others with 0. - */ - if (autoTexCoordType == TEXCALC_NONE) - { - /* FIXME: The actually input texture coordinate dimensions should - be determine by texture coordinate vertex element. Now, just trust - user supplied texture type matches texture coordinate vertex element. - */ - if (mTexStageDesc[stage].texType == D3D9Mappings::D3D_TEX_TYPE_NORMAL) - { - /* It's 2D input texture coordinate: - - texcoord in vertex buffer D3D expanded to We are adjusted to - --> --> - (u, v) (u, v, 1, 0) (u, v, 0, 1) - */ - std::swap(d3dMat._31, d3dMat._41); - std::swap(d3dMat._32, d3dMat._42); - std::swap(d3dMat._33, d3dMat._43); - std::swap(d3dMat._34, d3dMat._44); - } - } - else - { - // All texgen generate 3D input texture coordinates. - } - - // tell D3D the dimension of tex. coord. - int texCoordDim = D3DTTFF_COUNT2; - if (mTexStageDesc[stage].autoTexCoordType == TEXCALC_PROJECTIVE_TEXTURE) - { - /* We want texcoords (u, v, w, q) always get divided by q, but D3D - projected texcoords is divided by the last element (in the case of - 2D texcoord, is w). So we tweak the transform matrix, transform the - texcoords with w and q swapped: (u, v, q, w), and then D3D will - divide u, v by q. The w and q just ignored as it wasn't used by - rasterizer. - */ - switch (mTexStageDesc[stage].texType) - { - case D3D9Mappings::D3D_TEX_TYPE_NORMAL: - std::swap(d3dMat._13, d3dMat._14); - std::swap(d3dMat._23, d3dMat._24); - std::swap(d3dMat._33, d3dMat._34); - std::swap(d3dMat._43, d3dMat._44); - - texCoordDim = D3DTTFF_PROJECTED | D3DTTFF_COUNT3; - break; - - case D3D9Mappings::D3D_TEX_TYPE_CUBE: - case D3D9Mappings::D3D_TEX_TYPE_VOLUME: - // Yes, we support 3D projective texture. - texCoordDim = D3DTTFF_PROJECTED | D3DTTFF_COUNT4; - break; - } - } - else - { - switch (mTexStageDesc[stage].texType) - { - case D3D9Mappings::D3D_TEX_TYPE_NORMAL: - texCoordDim = D3DTTFF_COUNT2; - break; - case D3D9Mappings::D3D_TEX_TYPE_CUBE: - case D3D9Mappings::D3D_TEX_TYPE_VOLUME: - texCoordDim = D3DTTFF_COUNT3; - break; - } - } - - hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXTURETRANSFORMFLAGS, texCoordDim ); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set texture coord. dimension", "D3D9RenderSystem::_setTextureMatrix" ); - - hr = getActiveD3D9Device()->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + stage), &d3dMat ); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set texture matrix", "D3D9RenderSystem::_setTextureMatrix" ); - } - else - { - // disable all of this - hr = __SetTextureStageState( static_cast(stage), D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); - if( FAILED( hr ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to disable texture coordinate transform", "D3D9RenderSystem::_setTextureMatrix" ); - - // Needless to sets texture transform here, it's never used at all - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureAddressingMode( size_t stage, - const TextureUnitState::UVWAddressingMode& uvw ) - { - HRESULT hr; - if( FAILED( hr = __SetSamplerState( getSamplerId(stage), D3DSAMP_ADDRESSU, D3D9Mappings::get(uvw.u, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set texture addressing mode for U", "D3D9RenderSystem::_setTextureAddressingMode" ); - if( FAILED( hr = __SetSamplerState( getSamplerId(stage), D3DSAMP_ADDRESSV, D3D9Mappings::get(uvw.v, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set texture addressing mode for V", "D3D9RenderSystem::_setTextureAddressingMode" ); - if( FAILED( hr = __SetSamplerState( getSamplerId(stage), D3DSAMP_ADDRESSW, D3D9Mappings::get(uvw.w, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set texture addressing mode for W", "D3D9RenderSystem::_setTextureAddressingMode" ); - } - //----------------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureBorderColour(size_t stage, - const ColourValue& colour) - { - HRESULT hr; - if( FAILED( hr = __SetSamplerState( getSamplerId(stage), D3DSAMP_BORDERCOLOR, colour.getAsARGB()) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set texture border colour", "D3D9RenderSystem::_setTextureBorderColour" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureBlendMode( size_t stage, const LayerBlendModeEx& bm ) - { - HRESULT hr = S_OK; - D3DTEXTURESTAGESTATETYPE tss; - D3DCOLOR manualD3D; - - // choose type of blend. - if( bm.blendType == LBT_COLOUR ) - tss = D3DTSS_COLOROP; - else if( bm.blendType == LBT_ALPHA ) - tss = D3DTSS_ALPHAOP; - else - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid blend type", "D3D9RenderSystem::_setTextureBlendMode"); - - // set manual factor if required by operation - if (bm.operation == LBX_BLEND_MANUAL) - { - hr = __SetRenderState( D3DRS_TEXTUREFACTOR, D3DXCOLOR(0.0, 0.0, 0.0, bm.factor) ); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set manual factor", "D3D9RenderSystem::_setTextureBlendMode" ); - } - // set operation - hr = __SetTextureStageState( static_cast(stage), tss, D3D9Mappings::get(bm.operation, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps()) ); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set operation", "D3D9RenderSystem::_setTextureBlendMode" ); - - // choose source 1 - if( bm.blendType == LBT_COLOUR ) - { - tss = D3DTSS_COLORARG1; - manualD3D = D3DXCOLOR( bm.colourArg1.r, bm.colourArg1.g, bm.colourArg1.b, bm.colourArg1.a ); - mManualBlendColours[stage][0] = bm.colourArg1; - } - else if( bm.blendType == LBT_ALPHA ) - { - tss = D3DTSS_ALPHAARG1; - manualD3D = D3DXCOLOR( mManualBlendColours[stage][0].r, - mManualBlendColours[stage][0].g, - mManualBlendColours[stage][0].b, bm.alphaArg1 ); - } - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid blend type", "D3D9RenderSystem::_setTextureBlendMode"); - } - // Set manual factor if required - if (bm.source1 == LBS_MANUAL) - { - if (mCurrentCapabilities->hasCapability(RSC_PERSTAGECONSTANT)) - { - // Per-stage state - hr = __SetTextureStageState(static_cast(stage), D3DTSS_CONSTANT, manualD3D); - } - else - { - // Global state - hr = __SetRenderState( D3DRS_TEXTUREFACTOR, manualD3D ); - } - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set manual factor", "D3D9RenderSystem::_setTextureBlendMode" ); - } - // set source 1 - hr = __SetTextureStageState( static_cast(stage), tss, D3D9Mappings::get(bm.source1, mCurrentCapabilities->hasCapability(RSC_PERSTAGECONSTANT)) ); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set source1", "D3D9RenderSystem::_setTextureBlendMode" ); - - // choose source 2 - if( bm.blendType == LBT_COLOUR ) - { - tss = D3DTSS_COLORARG2; - manualD3D = D3DXCOLOR( bm.colourArg2.r, bm.colourArg2.g, bm.colourArg2.b, bm.colourArg2.a ); - mManualBlendColours[stage][1] = bm.colourArg2; - } - else if( bm.blendType == LBT_ALPHA ) - { - tss = D3DTSS_ALPHAARG2; - manualD3D = D3DXCOLOR( mManualBlendColours[stage][1].r, - mManualBlendColours[stage][1].g, - mManualBlendColours[stage][1].b, - bm.alphaArg2 ); - } - // Set manual factor if required - if (bm.source2 == LBS_MANUAL) - { - if (mCurrentCapabilities->hasCapability(RSC_PERSTAGECONSTANT)) - { - // Per-stage state - hr = __SetTextureStageState(static_cast(stage), D3DTSS_CONSTANT, manualD3D); - } - else - { - hr = __SetRenderState( D3DRS_TEXTUREFACTOR, manualD3D ); - } - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set manual factor", "D3D9RenderSystem::_setTextureBlendMode" ); - } - // Now set source 2 - hr = __SetTextureStageState( static_cast(stage), tss, D3D9Mappings::get(bm.source2, mCurrentCapabilities->hasCapability(RSC_PERSTAGECONSTANT)) ); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set source 2", "D3D9RenderSystem::_setTextureBlendMode" ); - - // Set interpolation factor if lerping - if (bm.operation == LBX_BLEND_DIFFUSE_COLOUR && - mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().TextureOpCaps & D3DTEXOPCAPS_LERP) - { - // choose source 0 (lerp factor) - if( bm.blendType == LBT_COLOUR ) - { - tss = D3DTSS_COLORARG0; - } - else if( bm.blendType == LBT_ALPHA ) - { - tss = D3DTSS_ALPHAARG0; - } - hr = __SetTextureStageState(static_cast(stage), tss, D3DTA_DIFFUSE); - - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set lerp source 0", - "D3D9RenderSystem::_setTextureBlendMode" ); - - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op ) - { - HRESULT hr; - if( sourceFactor == SBF_ONE && destFactor == SBF_ZERO) - { - if (FAILED(hr = __SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE))) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha blending option", "D3D9RenderSystem::_setSceneBlending" ); - } - else - { - if (FAILED(hr = __SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE))) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha blending option", "D3D9RenderSystem::_setSceneBlending" ); - if (FAILED(hr = __SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE))) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set separate alpha blending option", "D3D9RenderSystem::_setSceneBlending" ); - if( FAILED( hr = __SetRenderState( D3DRS_SRCBLEND, D3D9Mappings::get(sourceFactor) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set source blend", "D3D9RenderSystem::_setSceneBlending" ); - if( FAILED( hr = __SetRenderState( D3DRS_DESTBLEND, D3D9Mappings::get(destFactor) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set destination blend", "D3D9RenderSystem::_setSceneBlending" ); - } - - if (FAILED(hr = __SetRenderState(D3DRS_BLENDOP, D3D9Mappings::get(op)))) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set scene blending operation option", "D3D9RenderSystem::_setSceneBlendingOperation" ); - if (FAILED(hr = __SetRenderState(D3DRS_BLENDOPALPHA, D3D9Mappings::get(op)))) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set scene blending operation option", "D3D9RenderSystem::_setSceneBlendingOperation" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, - SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ) - { - HRESULT hr; - if( sourceFactor == SBF_ONE && destFactor == SBF_ZERO && - sourceFactorAlpha == SBF_ONE && destFactorAlpha == SBF_ZERO) - { - if (FAILED(hr = __SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE))) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha blending option", "D3D9RenderSystem::_setSceneBlending" ); - } - else - { - if (FAILED(hr = __SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE))) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha blending option", "D3D9RenderSystem::_setSeperateSceneBlending" ); - if (FAILED(hr = __SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE))) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set separate alpha blending option", "D3D9RenderSystem::_setSeperateSceneBlending" ); - if( FAILED( hr = __SetRenderState( D3DRS_SRCBLEND, D3D9Mappings::get(sourceFactor) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set source blend", "D3D9RenderSystem::_setSeperateSceneBlending" ); - if( FAILED( hr = __SetRenderState( D3DRS_DESTBLEND, D3D9Mappings::get(destFactor) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set destination blend", "D3D9RenderSystem::_setSeperateSceneBlending" ); - if( FAILED( hr = __SetRenderState( D3DRS_SRCBLENDALPHA, D3D9Mappings::get(sourceFactorAlpha) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha source blend", "D3D9RenderSystem::_setSeperateSceneBlending" ); - if( FAILED( hr = __SetRenderState( D3DRS_DESTBLENDALPHA, D3D9Mappings::get(destFactorAlpha) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha destination blend", "D3D9RenderSystem::_setSeperateSceneBlending" ); - } - - if (FAILED(hr = __SetRenderState(D3DRS_BLENDOP, D3D9Mappings::get(op)))) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set scene blending operation option", "D3D9RenderSystem::_setSceneBlendingOperation" ); - if (FAILED(hr = __SetRenderState(D3DRS_BLENDOPALPHA, D3D9Mappings::get(alphaOp)))) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha scene blending operation option", "D3D9RenderSystem::_setSceneBlendingOperation" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ) - { - HRESULT hr; - bool a2c = false; - static bool lasta2c = false; - - if (func != CMPF_ALWAYS_PASS) - { - if( FAILED( hr = __SetRenderState( D3DRS_ALPHATESTENABLE, TRUE ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to enable alpha testing", - "D3D9RenderSystem::_setAlphaRejectSettings" ); - - a2c = alphaToCoverage; - } - else - { - if( FAILED( hr = __SetRenderState( D3DRS_ALPHATESTENABLE, FALSE ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to disable alpha testing", - "D3D9RenderSystem::_setAlphaRejectSettings" ); - } - // Set always just be sure - if( FAILED( hr = __SetRenderState( D3DRS_ALPHAFUNC, D3D9Mappings::get(func) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha reject function", "D3D9RenderSystem::_setAlphaRejectSettings" ); - if( FAILED( hr = __SetRenderState( D3DRS_ALPHAREF, value ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set render state D3DRS_ALPHAREF", "D3D9RenderSystem::_setAlphaRejectSettings" ); - - // Alpha to coverage - if (getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE)) - { - // Vendor-specific hacks on renderstate, gotta love 'em - if (getCapabilities()->getVendor() == GPU_NVIDIA) - { - if (a2c) - { - if( FAILED( hr = __SetRenderState( D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C') ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha to coverage option", "D3D9RenderSystem::_setAlphaRejectSettings" ); - } - else - { - if( FAILED( hr = __SetRenderState( D3DRS_ADAPTIVETESS_Y, D3DFMT_UNKNOWN ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha to coverage option", "D3D9RenderSystem::_setAlphaRejectSettings" ); - } - - } - else if ((getCapabilities()->getVendor() == GPU_AMD)) - { - if (a2c) - { - if( FAILED( hr = __SetRenderState( D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','1') ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha to coverage option", "D3D9RenderSystem::_setAlphaRejectSettings" ); - } - else - { - // discovered this through trial and error, seems to work - if( FAILED( hr = __SetRenderState( D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','0') ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set alpha to coverage option", "D3D9RenderSystem::_setAlphaRejectSettings" ); - } - } - // no hacks available for any other vendors? - lasta2c = a2c; - } - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setCullingMode( CullingMode mode ) - { - mCullingMode = mode; - HRESULT hr; - bool flip = ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) || - (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding)); - - if( FAILED (hr = __SetRenderState(D3DRS_CULLMODE, - D3D9Mappings::get(mode, flip))) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set culling mode", "D3D9RenderSystem::_setCullingMode" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setDepthBufferParams( bool depthTest, bool depthWrite, CompareFunction depthFunction ) - { - _setDepthBufferCheckEnabled( depthTest ); - _setDepthBufferWriteEnabled( depthWrite ); - _setDepthBufferFunction( depthFunction ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setDepthBufferCheckEnabled( bool enabled ) - { - HRESULT hr; - - if( enabled ) - { - // Use w-buffer if available and enabled - if( mWBuffer && mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_WBUFFER ) - hr = __SetRenderState( D3DRS_ZENABLE, D3DZB_USEW ); - else - hr = __SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); - } - else - hr = __SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE ); - - if( FAILED( hr ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting depth buffer test state", "D3D9RenderSystem::_setDepthBufferCheckEnabled" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setDepthBufferWriteEnabled( bool enabled ) - { - HRESULT hr; - - if( FAILED( hr = __SetRenderState( D3DRS_ZWRITEENABLE, enabled ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting depth buffer write state", "D3D9RenderSystem::_setDepthBufferWriteEnabled" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setDepthBufferFunction( CompareFunction func ) - { - HRESULT hr; - if( FAILED( hr = __SetRenderState( D3DRS_ZFUNC, D3D9Mappings::get(func) ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting depth buffer test function", "D3D9RenderSystem::_setDepthBufferFunction" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setDepthBias(float constantBias, float slopeScaleBias) - { - - if ((mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0) - { - // Negate bias since D3D is backward - // D3D also expresses the constant bias as an absolute value, rather than - // relative to minimum depth unit, so scale to fit - constantBias = -constantBias / 250000.0f; - HRESULT hr = __SetRenderState(D3DRS_DEPTHBIAS, FLOAT2DWORD(constantBias)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting constant depth bias", - "D3D9RenderSystem::_setDepthBias"); - } - - if ((mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) != 0) - { - // Negate bias since D3D is backward - slopeScaleBias = -slopeScaleBias; - HRESULT hr = __SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, FLOAT2DWORD(slopeScaleBias)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting slope scale depth bias", - "D3D9RenderSystem::_setDepthBias"); - } - - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setColourBufferWriteEnabled(bool red, bool green, - bool blue, bool alpha) - { - DWORD val = 0; - if (red) - val |= D3DCOLORWRITEENABLE_RED; - if (green) - val |= D3DCOLORWRITEENABLE_GREEN; - if (blue) - val |= D3DCOLORWRITEENABLE_BLUE; - if (alpha) - val |= D3DCOLORWRITEENABLE_ALPHA; - HRESULT hr = __SetRenderState(D3DRS_COLORWRITEENABLE, val); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting colour write enable flags", - "D3D9RenderSystem::_setColourBufferWriteEnabled"); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setFog( FogMode mode, const ColourValue& colour, Real densitiy, Real start, Real end ) - { - HRESULT hr; - - D3DRENDERSTATETYPE fogType, fogTypeNot; - - if (mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().RasterCaps & D3DPRASTERCAPS_FOGTABLE) - { - fogType = D3DRS_FOGTABLEMODE; - fogTypeNot = D3DRS_FOGVERTEXMODE; - } - else - { - fogType = D3DRS_FOGVERTEXMODE; - fogTypeNot = D3DRS_FOGTABLEMODE; - } - - if( mode == FOG_NONE) - { - // just disable - hr = __SetRenderState(fogType, D3DFOG_NONE ); - hr = __SetRenderState(D3DRS_FOGENABLE, FALSE); - } - else - { - // Allow fog - hr = __SetRenderState( D3DRS_FOGENABLE, TRUE ); - hr = __SetRenderState( fogTypeNot, D3DFOG_NONE ); - hr = __SetRenderState( fogType, D3D9Mappings::get(mode) ); - - hr = __SetRenderState( D3DRS_FOGCOLOR, colour.getAsARGB() ); - hr = __SetFloatRenderState( D3DRS_FOGSTART, start ); - hr = __SetFloatRenderState( D3DRS_FOGEND, end ); - hr = __SetFloatRenderState( D3DRS_FOGDENSITY, densitiy ); - } - - if( FAILED( hr ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting render state", "D3D9RenderSystem::_setFog" ); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setPolygonMode(PolygonMode level) - { - HRESULT hr = __SetRenderState(D3DRS_FILLMODE, D3D9Mappings::get(level)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting polygon mode.", "D3D9RenderSystem::setPolygonMode"); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setStencilCheckEnabled(bool enabled) - { - // Allow stencilling - HRESULT hr = __SetRenderState(D3DRS_STENCILENABLE, enabled); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error enabling / disabling stencilling.", - "D3D9RenderSystem::setStencilCheckEnabled"); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setStencilBufferParams(CompareFunction func, - uint32 refValue, uint32 compareMask, uint32 writeMask, StencilOperation stencilFailOp, - StencilOperation depthFailOp, StencilOperation passOp, - bool twoSidedOperation, bool readBackAsTexture) - { - HRESULT hr; - bool flip; - - // 2-sided operation - if (twoSidedOperation) - { - if (!mCurrentCapabilities->hasCapability(RSC_TWO_SIDED_STENCIL)) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "2-sided stencils are not supported", - "D3D9RenderSystem::setStencilBufferParams"); - hr = __SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting 2-sided stencil mode.", - "D3D9RenderSystem::setStencilBufferParams"); - // NB: We should always treat CCW as front face for consistent with default - // culling mode. Therefore, we must take care with two-sided stencil settings. - flip = (mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping()) || - (!mInvertVertexWinding && !mActiveRenderTarget->requiresTextureFlipping()); - - // Set alternative versions of ops - // fail op - hr = __SetRenderState(D3DRS_CCW_STENCILFAIL, D3D9Mappings::get(stencilFailOp, !flip)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil fail operation (2-sided).", - "D3D9RenderSystem::setStencilBufferParams"); - - // depth fail op - hr = __SetRenderState(D3DRS_CCW_STENCILZFAIL, D3D9Mappings::get(depthFailOp, !flip)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil depth fail operation (2-sided).", - "D3D9RenderSystem::setStencilBufferParams"); - - // pass op - hr = __SetRenderState(D3DRS_CCW_STENCILPASS, D3D9Mappings::get(passOp, !flip)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil pass operation (2-sided).", - "D3D9RenderSystem::setStencilBufferParams"); - } - else - { - hr = __SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting 1-sided stencil mode.", - "D3D9RenderSystem::setStencilBufferParams"); - flip = false; - } - - // func - hr = __SetRenderState(D3DRS_STENCILFUNC, D3D9Mappings::get(func)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil buffer test function.", - "D3D9RenderSystem::setStencilBufferParams"); - - // reference value - hr = __SetRenderState(D3DRS_STENCILREF, refValue); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil buffer reference value.", - "D3D9RenderSystem::setStencilBufferParams"); - - // compare mask - hr = __SetRenderState(D3DRS_STENCILMASK, compareMask); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil buffer compare mask.", - "D3D9RenderSystem::setStencilBufferParams"); - - // compare mask - hr = __SetRenderState(D3DRS_STENCILWRITEMASK, writeMask); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil buffer write mask.", - "D3D9RenderSystem::setStencilBufferParams"); - - // fail op - hr = __SetRenderState(D3DRS_STENCILFAIL, D3D9Mappings::get(stencilFailOp, flip)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil fail operation.", - "D3D9RenderSystem::setStencilBufferParams"); - - // depth fail op - hr = __SetRenderState(D3DRS_STENCILZFAIL, D3D9Mappings::get(depthFailOp, flip)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil depth fail operation.", - "D3D9RenderSystem::setStencilBufferParams"); - - // pass op - hr = __SetRenderState(D3DRS_STENCILPASS, D3D9Mappings::get(passOp, flip)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error setting stencil pass operation.", - "D3D9RenderSystem::setStencilBufferParams"); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureUnitFiltering(size_t unit, FilterType ftype, - FilterOptions filter) - { - HRESULT hr; - D3D9Mappings::eD3DTexType texType = mTexStageDesc[unit].texType; - hr = __SetSamplerState( getSamplerId(unit), D3D9Mappings::get(ftype), - D3D9Mappings::get(ftype, filter, mDeviceManager->getActiveDevice()->getD3D9DeviceCaps(), texType)); - if (FAILED(hr)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set texture filter ", "D3D9RenderSystem::_setTextureUnitFiltering"); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureUnitCompareFunction(size_t unit, CompareFunction function) - { - //no effect in directX9 rendersystem - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureUnitCompareEnabled(size_t unit, bool compare) - { - //no effect in directX9 rendersystem - } - //--------------------------------------------------------------------- - DWORD D3D9RenderSystem::_getCurrentAnisotropy(size_t unit) - { - DWORD oldVal; - getActiveD3D9Device()->GetSamplerState(static_cast(unit), D3DSAMP_MAXANISOTROPY, &oldVal); - return oldVal; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) - { - if (static_cast(maxAnisotropy) > mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().MaxAnisotropy) - maxAnisotropy = mDeviceManager->getActiveDevice()->getD3D9DeviceCaps().MaxAnisotropy; - - if (_getCurrentAnisotropy(unit) != maxAnisotropy) - __SetSamplerState( getSamplerId(unit), D3DSAMP_MAXANISOTROPY, maxAnisotropy ); - } - //--------------------------------------------------------------------- - HRESULT D3D9RenderSystem::__SetRenderState(D3DRENDERSTATETYPE state, DWORD value) - { - HRESULT hr; - DWORD oldVal; - - if ( FAILED( hr = getActiveD3D9Device()->GetRenderState(state, &oldVal) ) ) - return hr; - if ( oldVal == value ) - return D3D_OK; - else - return getActiveD3D9Device()->SetRenderState(state, value); - } - //--------------------------------------------------------------------- - HRESULT D3D9RenderSystem::__SetSamplerState(DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value) - { - HRESULT hr; - DWORD oldVal; - - if ( FAILED( hr = getActiveD3D9Device()->GetSamplerState(sampler, type, &oldVal) ) ) - return hr; - if ( oldVal == value ) - return D3D_OK; - else - return getActiveD3D9Device()->SetSamplerState(sampler, type, value); - } - //--------------------------------------------------------------------- - HRESULT D3D9RenderSystem::__SetTextureStageState(DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value) - { - HRESULT hr; - DWORD oldVal; - - // can only set fixed-function texture stage state - if (stage < 8) - { - if ( FAILED( hr = getActiveD3D9Device()->GetTextureStageState(stage, type, &oldVal) ) ) - return hr; - if ( oldVal == value ) - return D3D_OK; - else - return getActiveD3D9Device()->SetTextureStageState(stage, type, value); - } - else - { - return D3D_OK; - } - } - //--------------------------------------------------------------------- - DepthBuffer* D3D9RenderSystem::_createDepthBufferFor( RenderTarget *renderTarget ) - { - IDirect3DSurface9* pBack[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - memset (pBack, 0, sizeof(pBack) ); - renderTarget->getCustomAttribute( "DDBACKBUFFER", &pBack ); - if( !pBack[0] ) - return 0; - - D3DSURFACE_DESC srfDesc; - if( FAILED(pBack[0]->GetDesc(&srfDesc)) ) - { - OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, - "Failed to retrieve Surface Description from BackBuffer. RenderTarget: " + - renderTarget->getName(), - "D3D9RenderSystem::_createDepthBufferFor" ); - } - - //Find an appropiarte format for this depth buffer that best matches the RenderTarget's - D3DFORMAT dsfmt = _getDepthStencilFormatFor( srfDesc.Format ); - - //Create the depthstencil surface - IDirect3DSurface9 *depthBufferSurface = NULL; - IDirect3DDevice9* activeDevice = getActiveD3D9Device(); - HRESULT hr = activeDevice->CreateDepthStencilSurface( - srfDesc.Width, srfDesc.Height, dsfmt, - srfDesc.MultiSampleType, srfDesc.MultiSampleQuality, - TRUE, // discard true or false? - &depthBufferSurface, NULL); - if( FAILED(hr) ) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, - "Error CreateDepthStencilSurface : " + msg, - "D3D9RenderSystem::_createDepthBufferFor" ); - } - - D3D9DepthBuffer *newDepthBuffer = OGRE_NEW D3D9DepthBuffer( DepthBuffer::POOL_DEFAULT, this, - activeDevice, depthBufferSurface, - dsfmt, srfDesc.Width, srfDesc.Height, - srfDesc.MultiSampleType, srfDesc.MultiSampleQuality, false ); - - return newDepthBuffer; - } - - //--------------------------------------------------------------------- - DepthBuffer* D3D9RenderSystem::_addManualDepthBuffer( IDirect3DDevice9* depthSurfaceDevice, IDirect3DSurface9 *depthSurface ) - { - //If this depth buffer was already added, return that one - DepthBufferVec::const_iterator itor = mDepthBufferPool[DepthBuffer::POOL_DEFAULT].begin(); - DepthBufferVec::const_iterator end = mDepthBufferPool[DepthBuffer::POOL_DEFAULT].end(); - - while( itor != end ) - { - if( static_cast(*itor)->getDepthBufferSurface() == depthSurface ) - return *itor; - - ++itor; - } - - //Nope, get the info about this depth buffer and create a new container fot it - D3DSURFACE_DESC dsDesc; - if( FAILED(depthSurface->GetDesc(&dsDesc)) ) - return 0; - - D3D9DepthBuffer *newDepthBuffer = OGRE_NEW D3D9DepthBuffer( DepthBuffer::POOL_DEFAULT, this, - depthSurfaceDevice, depthSurface, - dsDesc.Format, dsDesc.Width, dsDesc.Height, - dsDesc.MultiSampleType, dsDesc.MultiSampleQuality, true ); - - //Add the 'main' depth buffer to the pool - mDepthBufferPool[newDepthBuffer->getPoolId()].push_back( newDepthBuffer ); - - return newDepthBuffer; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_cleanupDepthBuffers( IDirect3DDevice9 *creator ) - { - assert( creator ); - - DepthBufferMap::iterator itMap = mDepthBufferPool.begin(); - DepthBufferMap::iterator enMap = mDepthBufferPool.end(); - - while( itMap != enMap ) - { - DepthBufferVec::iterator itor = itMap->second.begin(); - DepthBufferVec::iterator end = itMap->second.end(); - - while( itor != end ) - { - //Only delete those who match the specified creator - if( static_cast(*itor)->getDeviceCreator() == creator ) - { - OGRE_DELETE *itor; - - //Erasing a vector invalidates iterators, we need to recalculate - //to avoid memory corruption and asserts. The new itor will point - //to the next iterator - const size_t idx = itor - itMap->second.begin(); - itMap->second.erase( itor ); //Erase - itor = itMap->second.begin() + idx; - end = itMap->second.end(); - } - else - ++itor; - } - - //Erase the pool if it's now empty. Note erasing from a map is - //valid while iterating through it - if( itMap->second.empty() ) - { - DepthBufferMap::iterator deadi = itMap++; - mDepthBufferPool.erase( deadi ); - } - else - ++itMap; - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_cleanupDepthBuffers( IDirect3DSurface9 *manualSurface ) - { - assert( manualSurface ); - - DepthBufferMap::iterator itMap = mDepthBufferPool.begin(); - DepthBufferMap::iterator enMap = mDepthBufferPool.end(); - - while( itMap != enMap ) - { - DepthBufferVec::iterator itor = itMap->second.begin(); - DepthBufferVec::iterator end = itMap->second.end(); - - while( itor != end ) - { - //Only delete those who match the specified surface - if( static_cast(*itor)->getDepthBufferSurface() == manualSurface ) - { - OGRE_DELETE *itor; - - //Erasing a vector invalidates iterators, we need to recalculate - //to avoid memory corruption and asserts. The new itor will point - //to the next iterator - const size_t idx = itor - itMap->second.begin(); - itMap->second.erase( itor ); //Erase - itor = itMap->second.begin() + idx; - end = itMap->second.end(); - } - else - ++itor; - } - - //Erase the pool if it's now empty. Note erasing from a map is - //valid while iterating through it - if( itMap->second.empty() ) - { - DepthBufferMap::iterator deadi = itMap++; - mDepthBufferPool.erase( deadi ); - } - else - ++itMap; - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setRenderTarget(RenderTarget *target) - { - mActiveRenderTarget = target; - - if (mActiveRenderTarget) - { - HRESULT hr; - - // If this is called without going through RenderWindow::update, then - // the device will not have been set. Calling it twice is safe, the - // implementation ensures nothing happens if the same device is set twice - if (std::find(mRenderWindows.begin(), mRenderWindows.end(), target) != mRenderWindows.end()) - { - D3D9RenderWindow *window = static_cast(target); - mDeviceManager->setActiveRenderTargetDevice(window->getDevice()); - // also make sure we validate the device; if this never went - // through update() it won't be set - window->_validateDevice(); - } - - // Retrieve render surfaces (up to OGRE_MAX_MULTIPLE_RENDER_TARGETS) - IDirect3DSurface9* pBack[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - memset(pBack, 0, sizeof(pBack)); - target->getCustomAttribute( "DDBACKBUFFER", &pBack ); - if (!pBack[0]) - return; - - D3D9DepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); - - if( target->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH && - (!depthBuffer || depthBuffer->getDeviceCreator() != getActiveD3D9Device() ) ) - { - //Depth is automatically managed and there is no depth buffer attached to this RT - //or the Current D3D device doesn't match the one this Depth buffer was created - setDepthBufferFor( target ); - - //Retrieve depth buffer again - depthBuffer = static_cast(target->getDepthBuffer()); - } - - if ((depthBuffer != NULL) && ( depthBuffer->getDeviceCreator() != getActiveD3D9Device())) - { - OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, - "Can't use a depth buffer from a different device!", - "D3D9RenderSystem::_setRenderTarget" ); - } - - IDirect3DSurface9 *depthSurface = depthBuffer ? depthBuffer->getDepthBufferSurface() : NULL; - - // Bind render targets - uint count = mCurrentCapabilities->getNumMultiRenderTargets(); - for(uint x=0; xSetRenderTarget(x, pBack[x]); - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to setRenderTarget : " + msg, "D3D9RenderSystem::_setViewport" ); - } - } - hr = getActiveD3D9Device()->SetDepthStencilSurface( depthSurface ); - if (FAILED(hr)) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to setDepthStencil : " + msg, "D3D9RenderSystem::_setViewport" ); - } - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_setViewport( Viewport *vp ) - { - if (!vp) - { - mActiveViewport = NULL; - _setRenderTarget(NULL); - } - else if( vp != mActiveViewport || vp->_isUpdated() ) - { - mActiveViewport = vp; - - // ok, it's different, time to set render target and viewport params - D3DVIEWPORT9 d3dvp; - HRESULT hr; - - // Set render target - RenderTarget* target = vp->getTarget(); - _setRenderTarget(target); - - //Reset the viewport after the render target has been set. If the device - //had been reset the viewport would have been set to NULL. - mActiveViewport = vp; - - _setCullingMode( mCullingMode ); - - // set viewport dimensions - d3dvp.X = vp->getActualLeft(); - d3dvp.Y = vp->getActualTop(); - d3dvp.Width = vp->getActualWidth(); - d3dvp.Height = vp->getActualHeight(); - if (target->requiresTextureFlipping()) - { - // Convert "top-left" to "bottom-left" - d3dvp.Y = target->getHeight() - d3dvp.Height - d3dvp.Y; - } - - // Z-values from 0.0 to 1.0 (TODO: standardise with OpenGL) - d3dvp.MinZ = 0.0f; - d3dvp.MaxZ = 1.0f; - - if( FAILED( hr = getActiveD3D9Device()->SetViewport( &d3dvp ) ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set viewport.", "D3D9RenderSystem::_setViewport" ); - - // Set sRGB write mode - __SetRenderState(D3DRS_SRGBWRITEENABLE, target->isHardwareGammaEnabled()); - - vp->_clearUpdatedFlag(); - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_beginFrame() - { - HRESULT hr; - - if( !mActiveViewport ) - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Cannot begin frame - no viewport selected.", "D3D9RenderSystem::_beginFrame" ); - - if( FAILED( hr = getActiveD3D9Device()->BeginScene() ) ) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error beginning frame :" + msg, "D3D9RenderSystem::_beginFrame" ); - } - - mLastVertexSourceCount = 0; - - // Clear left overs of previous viewport. - // I.E: Viewport A can use 3 different textures and light states - // When trying to render viewport B these settings should be cleared, otherwise - // graphical artifacts might occur. - mDeviceManager->getActiveDevice()->clearDeviceStreams(); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_endFrame() - { - HRESULT hr; - if( FAILED( hr = getActiveD3D9Device()->EndScene() ) ) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error ending frame", "D3D9RenderSystem::_endFrame" ); - - mDeviceManager->destroyInactiveRenderDevices(); - } - //--------------------------------------------------------------------- - struct D3D9RenderContext : public RenderSystem::RenderSystemContext - { - RenderTarget* target; - }; - //--------------------------------------------------------------------- - RenderSystem::RenderSystemContext* D3D9RenderSystem::_pauseFrame(void) - { - //Stop rendering - _endFrame(); - - D3D9RenderContext* context = OGRE_ALLOC_T(D3D9RenderContext, 1, MEMCATEGORY_RENDERSYS); - context->target = mActiveRenderTarget; - - - return context; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_resumeFrame(RenderSystemContext* context) - { - //Resume rendering - _beginFrame(); - D3D9RenderContext* d3dContext = static_cast(context); - - OGRE_FREE(context, MEMCATEGORY_RENDERSYS); - } - void D3D9RenderSystem::setVertexDeclaration(VertexDeclaration* decl) - { - setVertexDeclaration(decl, true); + { + matrix[2][2] = -c.z; + } + matrix[2][3] = c.w; } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setVertexDeclaration(VertexDeclaration* decl, bool useGlobalInstancingVertexBufferIsAvailable) - { - HRESULT hr; - - D3D9VertexDeclaration* d3ddecl = - static_cast(decl); - - if (FAILED(hr = getActiveD3D9Device()->SetVertexDeclaration(d3ddecl->getD3DVertexDeclaration(getGlobalInstanceVertexBufferVertexDeclaration(), useGlobalInstancingVertexBufferIsAvailable)))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D9 vertex declaration", - "D3D9RenderSystem::setVertexDeclaration"); - } - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setVertexBufferBinding(VertexBufferBinding* binding) - { - setVertexBufferBinding(binding, 1, true, false); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setVertexBufferBinding( - VertexBufferBinding* binding, size_t numberOfInstances, bool useGlobalInstancingVertexBufferIsAvailable, bool indexesUsed) - { - /*if (!prg) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Null program bound.", - "D3D9RenderSystem::bindGpuProgram"); - }*/ + //--------------------------------------------------------------------- + Real D3D9RenderSystem::getMinimumDepthInputValue() + { + // Range [0.0f, 1.0f] + return 0.0f; + } + //--------------------------------------------------------------------- + Real D3D9RenderSystem::getMaximumDepthInputValue() + { + // Range [0.0f, 1.0f] + // D3D inverts even identity view matrices, so maximum INPUT is -1.0 + return -1.0f; + } + //--------------------------------------------------------------------- + IDirect3D9* D3D9RenderSystem::getDirect3D9() + { + IDirect3D9* pDirect3D9 = msD3D9RenderSystem->mD3D; + + if (pDirect3D9 == NULL) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Direct3D9 interface is NULL !!!", + "D3D9RenderSystem::getDirect3D9" ); + } - HRESULT hr; + return pDirect3D9; + } - if (useGlobalInstancingVertexBufferIsAvailable) + //--------------------------------------------------------------------- + UINT D3D9RenderSystem::getResourceCreationDeviceCount() + { + D3D9ResourceCreationPolicy creationPolicy = msD3D9RenderSystem->mResourceManager->getCreationPolicy(); + + if (creationPolicy == RCP_CREATE_ON_ACTIVE_DEVICE) { - numberOfInstances *= getGlobalNumberOfInstances(); + return 1; + } + else if (creationPolicy == RCP_CREATE_ON_ALL_DEVICES) + { + return msD3D9RenderSystem->mDeviceManager->getDeviceCount(); } - - HardwareVertexBufferSharedPtr globalInstanceVertexBuffer = getGlobalInstanceVertexBuffer(); - VertexDeclaration* globalVertexDeclaration = getGlobalInstanceVertexBufferVertexDeclaration(); - bool hasInstanceData = useGlobalInstancingVertexBufferIsAvailable && - !globalInstanceVertexBuffer.isNull() && globalVertexDeclaration != NULL - || binding->getHasInstanceData(); + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Invalid resource creation policy !!!", + "D3D9RenderSystem::getResourceCreationDeviceCount" ); - // TODO: attempt to detect duplicates - const VertexBufferBinding::VertexBufferBindingMap& binds = binding->getBindings(); - VertexBufferBinding::VertexBufferBindingMap::const_iterator i, iend; - size_t source = 0; - iend = binds.end(); - for (i = binds.begin(); i != iend; ++i, ++source) - { - D3D9HardwareVertexBuffer* d3d9buf = - static_cast(i->second.get()); - - // Unbind gap sources - for ( ; source < i->first; ++source) - { - hr = getActiveD3D9Device()->SetStreamSource(static_cast(source), NULL, 0, 0); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to reset unused D3D9 stream source", - "D3D9RenderSystem::setVertexBufferBinding"); - } - } - - hr = getActiveD3D9Device()->SetStreamSource( - static_cast(source), - d3d9buf->getD3D9VertexBuffer(), - 0, // no stream offset, this is handled in _render instead - static_cast(d3d9buf->getVertexSize()) // stride - ); - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D9 stream source for buffer binding", - "D3D9RenderSystem::setVertexBufferBinding"); - } + return 0; + } - // SetStreamSourceFreq - if ( hasInstanceData ) - { - if ( d3d9buf->getIsInstanceData() ) - { - hr = getActiveD3D9Device()->SetStreamSourceFreq( static_cast(source), D3DSTREAMSOURCE_INSTANCEDATA | d3d9buf->getInstanceDataStepRate() ); - } - else - { - if ( !indexesUsed ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Instance data used without index data.", - "D3D9RenderSystem::setVertexBufferBinding"); - } - hr = getActiveD3D9Device()->SetStreamSourceFreq( static_cast(source), D3DSTREAMSOURCE_INDEXEDDATA | numberOfInstances ); - } - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D9 stream source Freq", - "D3D9RenderSystem::setVertexBufferBinding"); - } - } - else - { - hr = getActiveD3D9Device()->SetStreamSourceFreq( static_cast(source), 1 ); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to reset unused D3D9 stream source Freq", - "D3D9RenderSystem::setVertexBufferBinding"); - } - } + //--------------------------------------------------------------------- + IDirect3DDevice9* D3D9RenderSystem::getResourceCreationDevice(UINT index) + { + D3D9ResourceCreationPolicy creationPolicy = msD3D9RenderSystem->mResourceManager->getCreationPolicy(); + IDirect3DDevice9* d3d9Device = NULL; - } - - if (useGlobalInstancingVertexBufferIsAvailable) + if (creationPolicy == RCP_CREATE_ON_ACTIVE_DEVICE) { - // bind global instance buffer if exist - if( !globalInstanceVertexBuffer.isNull() ) + d3d9Device = msD3D9RenderSystem->getActiveD3D9Device(); + } + else if (creationPolicy == RCP_CREATE_ON_ALL_DEVICES) { - if ( !indexesUsed ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Instance data used without index data.", - "D3D9RenderSystem::setVertexBufferBinding"); - } + d3d9Device = msD3D9RenderSystem->mDeviceManager->getDevice(index)->getD3D9Device(); + } + else + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Invalid resource creation policy !!!", + "D3D9RenderSystem::getResourceCreationDevice" ); + } - D3D9HardwareVertexBuffer * d3d9buf = - static_cast(globalInstanceVertexBuffer.get()); + return d3d9Device; + } - hr = getActiveD3D9Device()->SetStreamSource( - static_cast(source), - d3d9buf->getD3D9VertexBuffer(), - 0, // no stream offset, this is handled in _render instead - static_cast(d3d9buf->getVertexSize()) // stride - ); + //--------------------------------------------------------------------- + IDirect3DDevice9* D3D9RenderSystem::getActiveD3D9Device() + { + D3D9Device* activeDevice = msD3D9RenderSystem->mDeviceManager->getActiveDevice(); + IDirect3DDevice9* d3d9Device; - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D9 stream source for buffer binding", - "D3D9RenderSystem::setVertexBufferBinding"); - } + d3d9Device = activeDevice->getD3D9Device(); - hr = getActiveD3D9Device()->SetStreamSourceFreq( static_cast(source), D3DSTREAMSOURCE_INSTANCEDATA | d3d9buf->getInstanceDataStepRate() ); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set D3D9 stream source Freq", - "D3D9RenderSystem::setVertexBufferBinding"); - } + if (d3d9Device == NULL) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Current d3d9 device is NULL !!!", + "D3D9RenderSystem::getActiveD3D9Device" ); } - } - - // Unbind any unused sources - for (size_t unused = source; unused < mLastVertexSourceCount; ++unused) - { - - hr = getActiveD3D9Device()->SetStreamSource(static_cast(unused), NULL, 0, 0); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to reset unused D3D9 stream source", - "D3D9RenderSystem::setVertexBufferBinding"); - } - - hr = getActiveD3D9Device()->SetStreamSourceFreq( static_cast(unused), 1 ); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to reset unused D3D9 stream source Freq", - "D3D9RenderSystem::setVertexBufferBinding"); - } - - } - mLastVertexSourceCount = source; - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_render(const RenderOperation& op) - { - // Exit immediately if there is nothing to render - // This caused a problem on FireGL 8800 - if (op.vertexData->vertexCount == 0) - return; - - // Call super class - RenderSystem::_render(op); - - - if ( !mEnableFixedPipeline && !mRealCapabilities->hasCapability(RSC_FIXED_FUNCTION) - && - ( - ( !mVertexProgramBound ) || - (!mFragmentProgramBound && op.operationType != RenderOperation::OT_POINT_LIST) - ) - ) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Attempted to render using the fixed pipeline when it is disabled.", - "D3D9RenderSystem::_render"); - } - - // To think about: possibly remove setVertexDeclaration and - // setVertexBufferBinding from RenderSystem since the sequence is - // a bit too D3D9-specific? - setVertexDeclaration(op.vertexData->vertexDeclaration, op.useGlobalInstancingVertexBufferIsAvailable); - setVertexBufferBinding(op.vertexData->vertexBufferBinding, op.numberOfInstances, op.useGlobalInstancingVertexBufferIsAvailable, op.useIndexes); - - // Determine rendering operation - D3DPRIMITIVETYPE primType = D3DPT_TRIANGLELIST; - DWORD primCount = 0; - switch( op.operationType ) - { - case RenderOperation::OT_POINT_LIST: - primType = D3DPT_POINTLIST; - primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount); - break; - - case RenderOperation::OT_LINE_LIST: - primType = D3DPT_LINELIST; - primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 2; - break; - - case RenderOperation::OT_LINE_STRIP: - primType = D3DPT_LINESTRIP; - primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 1; - break; - - case RenderOperation::OT_TRIANGLE_LIST: - primType = D3DPT_TRIANGLELIST; - primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) / 3; - break; - - case RenderOperation::OT_TRIANGLE_STRIP: - primType = D3DPT_TRIANGLESTRIP; - primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2; - break; - - case RenderOperation::OT_TRIANGLE_FAN: - primType = D3DPT_TRIANGLEFAN; - primCount = static_cast(op.useIndexes ? op.indexData->indexCount : op.vertexData->vertexCount) - 2; - break; - } - - if (!primCount) - return; - - // Issue the op - HRESULT hr; - if( op.useIndexes ) - { - D3D9HardwareIndexBuffer* d3dIdxBuf = - static_cast(op.indexData->indexBuffer.get()); - hr = getActiveD3D9Device()->SetIndices( d3dIdxBuf->getD3DIndexBuffer() ); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to set index buffer", "D3D9RenderSystem::_render" ); - } - - do - { - // Update derived depth bias - if (mDerivedDepthBias && mCurrentPassIterationNum > 0) - { - _setDepthBias(mDerivedDepthBiasBase + - mDerivedDepthBiasMultiplier * mCurrentPassIterationNum, - mDerivedDepthBiasSlopeScale); - } - // do indexed draw operation - hr = getActiveD3D9Device()->DrawIndexedPrimitive( - primType, - static_cast(op.vertexData->vertexStart), - 0, // Min vertex index - assume we can go right down to 0 - static_cast(op.vertexData->vertexCount), - static_cast(op.indexData->indexStart), - static_cast(primCount) - ); - - } while (updatePassIterationRenderState()); - } - else - { - // nfz: gpu_iterate - do - { - // Update derived depth bias - if (mDerivedDepthBias && mCurrentPassIterationNum > 0) - { - _setDepthBias(mDerivedDepthBiasBase + - mDerivedDepthBiasMultiplier * mCurrentPassIterationNum, - mDerivedDepthBiasSlopeScale); - } - // Unindexed, a little simpler! - hr = getActiveD3D9Device()->DrawPrimitive( - primType, - static_cast(op.vertexData->vertexStart), - static_cast(primCount) - ); - - } while (updatePassIterationRenderState()); - } - - if( FAILED( hr ) ) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to DrawPrimitive : " + msg, "D3D9RenderSystem::_render" ); - } - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setNormaliseNormals(bool normalise) - { - __SetRenderState(D3DRS_NORMALIZENORMALS, - normalise ? TRUE : FALSE); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::bindGpuProgram(GpuProgram* prg) - { - if (!prg) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Null program bound.", - "D3D9RenderSystem::bindGpuProgram"); - } - - HRESULT hr; - switch (prg->getType()) - { - case GPT_VERTEX_PROGRAM: - hr = getActiveD3D9Device()->SetVertexShader( - static_cast(prg)->getVertexShader()); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error calling SetVertexShader", "D3D9RenderSystem::bindGpuProgram"); - } - break; - case GPT_FRAGMENT_PROGRAM: - hr = getActiveD3D9Device()->SetPixelShader( - static_cast(prg)->getPixelShader()); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error calling SetPixelShader", "D3D9RenderSystem::bindGpuProgram"); - } - break; - }; - - // Make sure texcoord index is equal to stage value, As SDK Doc suggests: - // "When rendering using vertex shaders, each stage's texture coordinate index must be set to its default value." - // This solves such an errors when working with the Debug runtime - - // "Direct3D9: (ERROR) :Stage 1 - Texture coordinate index in the stage must be equal to the stage index when programmable vertex pipeline is used". - for (unsigned int nStage=0; nStage < 8; ++nStage) - __SetTextureStageState(nStage, D3DTSS_TEXCOORDINDEX, nStage); - - RenderSystem::bindGpuProgram(prg); - - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::unbindGpuProgram(GpuProgramType gptype) - { - /*if (!prg) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Null program bound.", - "D3D9RenderSystem::bindGpuProgram"); - }*/ - - HRESULT hr; - switch(gptype) - { - case GPT_VERTEX_PROGRAM: - mActiveVertexGpuProgramParameters.setNull(); - hr = getActiveD3D9Device()->SetVertexShader(NULL); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error resetting SetVertexShader to NULL", - "D3D9RenderSystem::unbindGpuProgram"); - } - break; - case GPT_FRAGMENT_PROGRAM: - mActiveFragmentGpuProgramParameters.setNull(); - hr = getActiveD3D9Device()->SetPixelShader(NULL); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error resetting SetPixelShader to NULL", - "D3D9RenderSystem::unbindGpuProgram"); - } - break; - }; - RenderSystem::unbindGpuProgram(gptype); - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::bindGpuProgramParameters(GpuProgramType gptype, - GpuProgramParametersSharedPtr params, uint16 variability) - { - // special case pass iteration - if (variability == (uint16)GPV_PASS_ITERATION_NUMBER) - { - bindGpuProgramPassIterationParameters(gptype); - return; - } - - if (variability & (uint16)GPV_GLOBAL) - { - // D3D9 doesn't support shared constant buffers, so use copy routine - params->_copySharedParams(); - } - - HRESULT hr; - GpuLogicalBufferStructPtr floatLogical = params->getFloatLogicalBufferStruct(); - GpuLogicalBufferStructPtr intLogical = params->getIntLogicalBufferStruct(); - - switch(gptype) - { - case GPT_VERTEX_PROGRAM: - mActiveVertexGpuProgramParameters = params; - { - OGRE_LOCK_MUTEX(floatLogical->mutex); + return d3d9Device; + } - for (GpuLogicalIndexUseMap::const_iterator i = floatLogical->map.begin(); - i != floatLogical->map.end(); ++i) - { - if (i->second.variability & variability) - { - size_t logicalIndex = i->first; - const float* pFloat = params->getFloatPointer(i->second.physicalIndex); - size_t slotCount = i->second.currentSize / 4; - assert (i->second.currentSize % 4 == 0 && "Should not have any " - "elements less than 4 wide for D3D9"); - - if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantF( - (UINT)logicalIndex, pFloat, (UINT)slotCount))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to upload vertex shader float parameters", - "D3D9RenderSystem::bindGpuProgramParameters"); - } - } - - } - - } - // bind ints - { - OGRE_LOCK_MUTEX(intLogical->mutex); + //--------------------------------------------------------------------- + IDirect3DDevice9* D3D9RenderSystem::getActiveD3D9DeviceIfExists() + { + D3D9Device* activeDevice = msD3D9RenderSystem->mDeviceManager->getActiveDevice(); + return activeDevice ? activeDevice->getD3D9Device() : NULL; + } - for (GpuLogicalIndexUseMap::const_iterator i = intLogical->map.begin(); - i != intLogical->map.end(); ++i) - { - if (i->second.variability & variability) - { - size_t logicalIndex = i->first; - const int* pInt = params->getIntPointer(i->second.physicalIndex); - size_t slotCount = i->second.currentSize / 4; - assert (i->second.currentSize % 4 == 0 && "Should not have any " - "elements less than 4 wide for D3D9"); - - if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantI( - static_cast(logicalIndex), pInt, static_cast(slotCount)))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to upload vertex shader int parameters", - "D3D9RenderSystem::bindGpuProgramParameters"); - } - } - } - - } - - break; - case GPT_FRAGMENT_PROGRAM: - mActiveFragmentGpuProgramParameters = params; - { - OGRE_LOCK_MUTEX(floatLogical->mutex); + //--------------------------------------------------------------------- + // Formats to try, in decreasing order of preference + D3DFORMAT ddDepthStencilFormats[]={ + D3DFMT_D24FS8, + D3DFMT_D24S8, + D3DFMT_D24X4S4, + D3DFMT_D24X8, + D3DFMT_D15S1, + D3DFMT_D16, + D3DFMT_D32 + }; +#define NDSFORMATS (sizeof(ddDepthStencilFormats)/sizeof(D3DFORMAT)) - for (GpuLogicalIndexUseMap::const_iterator i = floatLogical->map.begin(); - i != floatLogical->map.end(); ++i) - { - if (i->second.variability & variability) - { - size_t logicalIndex = i->first; - const float* pFloat = params->getFloatPointer(i->second.physicalIndex); - size_t slotCount = i->second.currentSize / 4; - assert (i->second.currentSize % 4 == 0 && "Should not have any " - "elements less than 4 wide for D3D9"); - - if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantF( - static_cast(logicalIndex), pFloat, static_cast(slotCount)))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to upload pixel shader float parameters", - "D3D9RenderSystem::bindGpuProgramParameters"); - } - } - } - - } - // bind ints - { - OGRE_LOCK_MUTEX(intLogical->mutex); + D3DFORMAT D3D9RenderSystem::_getDepthStencilFormatFor(D3DFORMAT fmt) + { + /// Check if result is cached + DepthStencilHash::iterator i = mDepthStencilHash.find((unsigned int)fmt); + if(i != mDepthStencilHash.end()) + return i->second; + /// If not, probe with CheckDepthStencilMatch + D3DFORMAT dsfmt = D3DFMT_UNKNOWN; + + /// Get description of primary render target + D3D9Device* activeDevice = mDeviceManager->getActiveDevice(); + IDirect3DSurface9* mSurface = activeDevice->getPrimaryWindow()->getRenderSurface(); + D3DSURFACE_DESC srfDesc; + + if(mSurface && SUCCEEDED(mSurface->GetDesc(&srfDesc))) + { + /// Probe all depth stencil formats + /// Break on first one that matches + for(size_t x=0; xCheckDeviceFormat( + activeDevice->getAdapterNumber(), + activeDevice->getDeviceType(), + srfDesc.Format, + D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, + ddDepthStencilFormats[x]) != D3D_OK) + { + continue; + } + // Verify that the depth format is compatible + if(mD3D->CheckDepthStencilMatch( + activeDevice->getAdapterNumber(), + activeDevice->getDeviceType(), + srfDesc.Format, + fmt, ddDepthStencilFormats[x]) == D3D_OK) + { + dsfmt = ddDepthStencilFormats[x]; + break; + } + } + } + /// Cache result + mDepthStencilHash[(unsigned int)fmt] = dsfmt; + return dsfmt; + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::registerThread() + { + // nothing to do - D3D9 shares rendering context already + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::unregisterThread() + { + // nothing to do - D3D9 shares rendering context already + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::preExtraThreadsStarted() + { + // nothing to do - D3D9 shares rendering context already + } + //--------------------------------------------------------------------- + void D3D9RenderSystem::postExtraThreadsStarted() + { + // nothing to do - D3D9 shares rendering context already + } + //--------------------------------------------------------------------- + D3D9ResourceManager* D3D9RenderSystem::getResourceManager() + { + return msD3D9RenderSystem->mResourceManager; + } - for (GpuLogicalIndexUseMap::const_iterator i = intLogical->map.begin(); - i != intLogical->map.end(); ++i) - { - if (i->second.variability & variability) - { - size_t logicalIndex = i->first; - const int* pInt = params->getIntPointer(i->second.physicalIndex); - size_t slotCount = i->second.currentSize / 4; - assert (i->second.currentSize % 4 == 0 && "Should not have any " - "elements less than 4 wide for D3D9"); - - if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantI( - static_cast(logicalIndex), pInt, static_cast(slotCount)))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to upload pixel shader int parameters", - "D3D9RenderSystem::bindGpuProgramParameters"); - } - } - - } - - } - break; - }; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::bindGpuProgramPassIterationParameters(GpuProgramType gptype) - { - - HRESULT hr; - size_t physicalIndex = 0; - size_t logicalIndex = 0; - const float* pFloat; - - switch(gptype) - { - case GPT_VERTEX_PROGRAM: - if (mActiveVertexGpuProgramParameters->hasPassIterationNumber()) - { - physicalIndex = mActiveVertexGpuProgramParameters->getPassIterationNumberIndex(); - logicalIndex = mActiveVertexGpuProgramParameters->getFloatLogicalIndexForPhysicalIndex(physicalIndex); - pFloat = mActiveVertexGpuProgramParameters->getFloatPointer(physicalIndex); - - if (FAILED(hr = getActiveD3D9Device()->SetVertexShaderConstantF( - static_cast(logicalIndex), pFloat, 1))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to upload vertex shader multi pass parameters", - "D3D9RenderSystem::bindGpuProgramMultiPassParameters"); - } - } - break; - - case GPT_FRAGMENT_PROGRAM: - if (mActiveFragmentGpuProgramParameters->hasPassIterationNumber()) - { - physicalIndex = mActiveFragmentGpuProgramParameters->getPassIterationNumberIndex(); - logicalIndex = mActiveFragmentGpuProgramParameters->getFloatLogicalIndexForPhysicalIndex(physicalIndex); - pFloat = mActiveFragmentGpuProgramParameters->getFloatPointer(physicalIndex); - if (FAILED(hr = getActiveD3D9Device()->SetPixelShaderConstantF( - static_cast(logicalIndex), pFloat, 1))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to upload pixel shader multi pass parameters", - "D3D9RenderSystem::bindGpuProgramMultiPassParameters"); - } - } - break; - - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setClipPlanesImpl(const PlaneList& clipPlanes) - { - size_t i; - size_t numClipPlanes; - D3DXPLANE dx9ClipPlane; - DWORD mask = 0; - HRESULT hr; - - numClipPlanes = clipPlanes.size(); - for (i = 0; i < numClipPlanes; ++i) - { - const Plane& plane = clipPlanes[i]; - - dx9ClipPlane.a = plane.normal.x; - dx9ClipPlane.b = plane.normal.y; - dx9ClipPlane.c = plane.normal.z; - dx9ClipPlane.d = plane.d; - - if (mVertexProgramBound) - { - // programmable clips in clip space (ugh) - // must transform worldspace planes by view/proj - D3DXMATRIX xform; - D3DXMatrixMultiply(&xform, &mDxViewMat, &mDxProjMat); - D3DXMatrixInverse(&xform, NULL, &xform); - D3DXMatrixTranspose(&xform, &xform); - D3DXPlaneTransform(&dx9ClipPlane, &dx9ClipPlane, &xform); - } - - hr = getActiveD3D9Device()->SetClipPlane(static_cast(i), dx9ClipPlane); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set clip plane", - "D3D9RenderSystem::setClipPlanes"); - } - - mask |= (1 << i); - } - - hr = __SetRenderState(D3DRS_CLIPPLANEENABLE, mask); - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set render state for clip planes", - "D3D9RenderSystem::setClipPlanes"); - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::setScissorTest(bool enabled, size_t left, size_t top, size_t right, - size_t bottom) - { - HRESULT hr; - if (enabled) - { - if (FAILED(hr = __SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to enable scissor rendering state; " + getErrorDescription(hr), - "D3D9RenderSystem::setScissorTest"); - } - RECT rect; - rect.left = static_cast(left); - rect.top = static_cast(top); - rect.bottom = static_cast(bottom); - rect.right = static_cast(right); - if (FAILED(hr = getActiveD3D9Device()->SetScissorRect(&rect))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to set scissor rectangle; " + getErrorDescription(hr), - "D3D9RenderSystem::setScissorTest"); - } - } - else - { - if (FAILED(hr = __SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE))) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to disable scissor rendering state; " + getErrorDescription(hr), - "D3D9RenderSystem::setScissorTest"); - } - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::clearFrameBuffer(unsigned int buffers, - const ColourValue& colour, Real depth, unsigned short stencil) - { - DWORD flags = 0; - if (buffers & FBT_COLOUR) - { - flags |= D3DCLEAR_TARGET; - } - if (buffers & FBT_DEPTH) - { - flags |= D3DCLEAR_ZBUFFER; - } - // Only try to clear the stencil buffer if supported - if (buffers & FBT_STENCIL && mCurrentCapabilities->hasCapability(RSC_HWSTENCIL)) - { - flags |= D3DCLEAR_STENCIL; - } - HRESULT hr; - if( FAILED( hr = getActiveD3D9Device()->Clear( - 0, - NULL, - flags, - colour.getAsARGB(), - depth, - stencil ) ) ) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error clearing frame buffer : " - + msg, "D3D9RenderSystem::clearFrameBuffer" ); - } - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_makeProjectionMatrix(Real left, Real right, - Real bottom, Real top, Real nearPlane, Real farPlane, Matrix4& dest, - bool forGpuProgram) - { - // Correct position for off-axis projection matrix - if (!forGpuProgram) - { - Real offsetX = left + right; - Real offsetY = top + bottom; - - left -= offsetX; - right -= offsetX; - top -= offsetY; - bottom -= offsetY; - } - - Real width = right - left; - Real height = top - bottom; - Real q, qn; - if (farPlane == 0) - { - q = 1 - Frustum::INFINITE_FAR_PLANE_ADJUST; - qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 1); - } - else - { - q = farPlane / ( farPlane - nearPlane ); - qn = -q * nearPlane; - } - dest = Matrix4::ZERO; - dest[0][0] = 2 * nearPlane / width; - dest[0][2] = (right+left) / width; - dest[1][1] = 2 * nearPlane / height; - dest[1][2] = (top+bottom) / height; - if (forGpuProgram) - { - dest[2][2] = -q; - dest[3][2] = -1.0f; - } - else - { - dest[2][2] = q; - dest[3][2] = 1.0f; - } - dest[2][3] = qn; - } - - // ------------------------------------------------------------------ - void D3D9RenderSystem::setClipPlane (ushort index, Real A, Real B, Real C, Real D) - { - float plane[4] = { A, B, C, D }; - getActiveD3D9Device()->SetClipPlane (index, plane); - } - - // ------------------------------------------------------------------ - void D3D9RenderSystem::enableClipPlane (ushort index, bool enable) - { - DWORD prev; - getActiveD3D9Device()->GetRenderState(D3DRS_CLIPPLANEENABLE, &prev); - __SetRenderState(D3DRS_CLIPPLANEENABLE, enable? - (prev | (1 << index)) : (prev & ~(1 << index))); - } - //--------------------------------------------------------------------- - HardwareOcclusionQuery* D3D9RenderSystem::createHardwareOcclusionQuery() - { - D3D9HardwareOcclusionQuery* ret = OGRE_NEW D3D9HardwareOcclusionQuery(); - mHwOcclusionQueries.push_back(ret); - return ret; - } - //--------------------------------------------------------------------- - Real D3D9RenderSystem::getHorizontalTexelOffset() - { - // D3D considers the origin to be in the center of a pixel - return -0.5f; - } - //--------------------------------------------------------------------- - Real D3D9RenderSystem::getVerticalTexelOffset() - { - // D3D considers the origin to be in the center of a pixel - return -0.5f; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::_applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane, - bool forGpuProgram) - { - // Thanks to Eric Lenyel for posting this calculation at www.terathon.com - - // Calculate the clip-space corner point opposite the clipping plane - // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and - // transform it into camera space by multiplying it - // by the inverse of the projection matrix - - /* generalised version - Vector4 q = matrix.inverse() * - Vector4(Math::Sign(plane.normal.x), Math::Sign(plane.normal.y), 1.0f, 1.0f); - */ - Vector4 q; - q.x = Math::Sign(plane.normal.x) / matrix[0][0]; - q.y = Math::Sign(plane.normal.y) / matrix[1][1]; - q.z = 1.0F; - // flip the next bit from Lengyel since we're right-handed - if (forGpuProgram) - { - q.w = (1.0F - matrix[2][2]) / matrix[2][3]; - } - else - { - q.w = (1.0F + matrix[2][2]) / matrix[2][3]; - } - - // Calculate the scaled plane vector - Vector4 clipPlane4d(plane.normal.x, plane.normal.y, plane.normal.z, plane.d); - Vector4 c = clipPlane4d * (1.0F / (clipPlane4d.dotProduct(q))); - - // Replace the third row of the projection matrix - matrix[2][0] = c.x; - matrix[2][1] = c.y; - // flip the next bit from Lengyel since we're right-handed - if (forGpuProgram) - { - matrix[2][2] = c.z; - } - else - { - matrix[2][2] = -c.z; - } - matrix[2][3] = c.w; - } - //--------------------------------------------------------------------- - Real D3D9RenderSystem::getMinimumDepthInputValue() - { - // Range [0.0f, 1.0f] - return 0.0f; - } - //--------------------------------------------------------------------- - Real D3D9RenderSystem::getMaximumDepthInputValue() - { - // Range [0.0f, 1.0f] - // D3D inverts even identity view matrices, so maximum INPUT is -1.0 - return -1.0f; - } - //--------------------------------------------------------------------- - IDirect3D9* D3D9RenderSystem::getDirect3D9() - { - IDirect3D9* pDirect3D9 = msD3D9RenderSystem->mD3D; - - if (pDirect3D9 == NULL) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Direct3D9 interface is NULL !!!", - "D3D9RenderSystem::getDirect3D9" ); - } - - return pDirect3D9; - } - - //--------------------------------------------------------------------- - UINT D3D9RenderSystem::getResourceCreationDeviceCount() - { - D3D9ResourceCreationPolicy creationPolicy = msD3D9RenderSystem->mResourceManager->getCreationPolicy(); - - if (creationPolicy == RCP_CREATE_ON_ACTIVE_DEVICE) - { - return 1; - } - else if (creationPolicy == RCP_CREATE_ON_ALL_DEVICES) - { - return msD3D9RenderSystem->mDeviceManager->getDeviceCount(); - } - - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Invalid resource creation policy !!!", - "D3D9RenderSystem::getResourceCreationDeviceCount" ); - - return 0; - } - - //--------------------------------------------------------------------- - IDirect3DDevice9* D3D9RenderSystem::getResourceCreationDevice(UINT index) - { - D3D9ResourceCreationPolicy creationPolicy = msD3D9RenderSystem->mResourceManager->getCreationPolicy(); - IDirect3DDevice9* d3d9Device = NULL; - - if (creationPolicy == RCP_CREATE_ON_ACTIVE_DEVICE) - { - d3d9Device = msD3D9RenderSystem->getActiveD3D9Device(); - } - else if (creationPolicy == RCP_CREATE_ON_ALL_DEVICES) - { - d3d9Device = msD3D9RenderSystem->mDeviceManager->getDevice(index)->getD3D9Device(); - } - else - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Invalid resource creation policy !!!", - "D3D9RenderSystem::getResourceCreationDevice" ); - } - - return d3d9Device; - } - - //--------------------------------------------------------------------- - IDirect3DDevice9* D3D9RenderSystem::getActiveD3D9Device() - { - D3D9Device* activeDevice = msD3D9RenderSystem->mDeviceManager->getActiveDevice(); - IDirect3DDevice9* d3d9Device; - - d3d9Device = activeDevice->getD3D9Device(); - - if (d3d9Device == NULL) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Current d3d9 device is NULL !!!", - "D3D9RenderSystem::getActiveD3D9Device" ); - } - - return d3d9Device; - } - - //--------------------------------------------------------------------- - IDirect3DDevice9* D3D9RenderSystem::getActiveD3D9DeviceIfExists() - { - D3D9Device* activeDevice = msD3D9RenderSystem->mDeviceManager->getActiveDevice(); - return activeDevice ? activeDevice->getD3D9Device() : NULL; - } - - //--------------------------------------------------------------------- - // Formats to try, in decreasing order of preference - D3DFORMAT ddDepthStencilFormats[]={ - D3DFMT_D24FS8, - D3DFMT_D24S8, - D3DFMT_D24X4S4, - D3DFMT_D24X8, - D3DFMT_D15S1, - D3DFMT_D16, - D3DFMT_D32 - }; -#define NDSFORMATS (sizeof(ddDepthStencilFormats)/sizeof(D3DFORMAT)) + //--------------------------------------------------------------------- + D3D9DeviceManager* D3D9RenderSystem::getDeviceManager() + { + return msD3D9RenderSystem->mDeviceManager; + } - D3DFORMAT D3D9RenderSystem::_getDepthStencilFormatFor(D3DFORMAT fmt) - { - /// Check if result is cached - DepthStencilHash::iterator i = mDepthStencilHash.find((unsigned int)fmt); - if(i != mDepthStencilHash.end()) - return i->second; - /// If not, probe with CheckDepthStencilMatch - D3DFORMAT dsfmt = D3DFMT_UNKNOWN; - - /// Get description of primary render target - D3D9Device* activeDevice = mDeviceManager->getActiveDevice(); - IDirect3DSurface9* mSurface = activeDevice->getPrimaryWindow()->getRenderSurface(); - D3DSURFACE_DESC srfDesc; - - if(mSurface && SUCCEEDED(mSurface->GetDesc(&srfDesc))) - { - /// Probe all depth stencil formats - /// Break on first one that matches - for(size_t x=0; xCheckDeviceFormat( - activeDevice->getAdapterNumber(), - activeDevice->getDeviceType(), - srfDesc.Format, - D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, - ddDepthStencilFormats[x]) != D3D_OK) - { - continue; - } - // Verify that the depth format is compatible - if(mD3D->CheckDepthStencilMatch( - activeDevice->getAdapterNumber(), - activeDevice->getDeviceType(), - srfDesc.Format, - fmt, ddDepthStencilFormats[x]) == D3D_OK) - { - dsfmt = ddDepthStencilFormats[x]; - break; - } - } - } - /// Cache result - mDepthStencilHash[(unsigned int)fmt] = dsfmt; - return dsfmt; - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::registerThread() - { - // nothing to do - D3D9 shares rendering context already - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::unregisterThread() - { - // nothing to do - D3D9 shares rendering context already - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::preExtraThreadsStarted() - { - // nothing to do - D3D9 shares rendering context already - } - //--------------------------------------------------------------------- - void D3D9RenderSystem::postExtraThreadsStarted() - { - // nothing to do - D3D9 shares rendering context already - } - //--------------------------------------------------------------------- - D3D9ResourceManager* D3D9RenderSystem::getResourceManager() - { - return msD3D9RenderSystem->mResourceManager; - } - - //--------------------------------------------------------------------- - D3D9DeviceManager* D3D9RenderSystem::getDeviceManager() - { - return msD3D9RenderSystem->mDeviceManager; - } - - //--------------------------------------------------------------------- - RenderSystemCapabilities* D3D9RenderSystem::createRenderSystemCapabilities() const - { - return mRealCapabilities; - } - - //--------------------------------------------------------------------- - unsigned int D3D9RenderSystem::getDisplayMonitorCount() const - { - return mD3D->GetAdapterCount(); - } + //--------------------------------------------------------------------- + RenderSystemCapabilities* D3D9RenderSystem::createRenderSystemCapabilities() const + { + return mRealCapabilities; + } + + //--------------------------------------------------------------------- + unsigned int D3D9RenderSystem::getDisplayMonitorCount() const + { + return mD3D->GetAdapterCount(); + } //--------------------------------------------------------------------- void D3D9RenderSystem::beginProfileEvent( const String &eventName ) @@ -4271,197 +4271,197 @@ namespace Ogre (void)D3DPERF_SetMarker(D3DCOLOR_ARGB(1, 0, 1, 0), &result[0]); } - //--------------------------------------------------------------------- - DWORD D3D9RenderSystem::getSamplerId(size_t unit) - { - return static_cast(unit) + - ((mTexStageDesc[unit].pVertexTex == NULL) ? 0 : D3DVERTEXTEXTURESAMPLER0); - } - - //--------------------------------------------------------------------- - void D3D9RenderSystem::notifyOnDeviceLost(D3D9Device* device) - { - StringStream ss; - - ss << "D3D9 Device 0x[" << device->getD3D9Device() << "] entered lost state"; - LogManager::getSingleton().logMessage(ss.str()); - - fireDeviceEvent(device, "DeviceLost"); - - } - - //--------------------------------------------------------------------- - void D3D9RenderSystem::notifyOnDeviceReset(D3D9Device* device) - { - // Reset state attributes. - mVertexProgramBound = false; - mFragmentProgramBound = false; - mLastVertexSourceCount = 0; - - - // Force all compositors to reconstruct their internal resources - // render textures will have been changed without their knowledge - CompositorManager::getSingleton()._reconstructAllCompositorResources(); - - // Restore previous active device. - - // Invalidate active view port. - mActiveViewport = NULL; - - StringStream ss; - - // Reset the texture stages, they will need to be rebound - for (size_t i = 0; i < OGRE_MAX_TEXTURE_LAYERS; ++i) - _setTexture(i, false, TexturePtr()); - - LogManager::getSingleton().logMessage("!!! Direct3D Device successfully restored."); - - ss << "D3D9 device: 0x[" << device->getD3D9Device() << "] was reset"; - LogManager::getSingleton().logMessage(ss.str()); - - fireDeviceEvent(device, "DeviceRestored"); - - } - - //--------------------------------------------------------------------- - void D3D9RenderSystem::determineFSAASettings(IDirect3DDevice9* d3d9Device, - size_t fsaa, const String& fsaaHint, D3DFORMAT d3dPixelFormat, - bool fullScreen, D3DMULTISAMPLE_TYPE *outMultisampleType, DWORD *outMultisampleQuality) - { - bool ok = false; - bool qualityHint = fsaaHint.find("Quality") != String::npos; - size_t origFSAA = fsaa; - - D3D9DriverList* driverList = getDirect3DDrivers(); - D3D9Driver* deviceDriver = mActiveD3DDriver; - D3D9Device* device = mDeviceManager->getDeviceFromD3D9Device(d3d9Device); - - for (uint i = 0; i < driverList->count(); ++i) - { - D3D9Driver* currDriver = driverList->item(i); - - if (currDriver->getAdapterNumber() == device->getAdapterNumber()) - { - deviceDriver = currDriver; - break; - } - } - - bool tryCSAA = false; - // NVIDIA, prefer CSAA if available for 8+ - // it would be tempting to use getCapabilities()->getVendor() == GPU_NVIDIA but - // if this is the first window, caps will not be initialised yet - if (deviceDriver->getAdapterIdentifier().VendorId == 0x10DE && - fsaa >= 8) - { - tryCSAA = true; - } - - while (!ok) - { - // Deal with special cases - if (tryCSAA) - { - // see http://developer.nvidia.com/object/coverage-sampled-aa.html - switch(fsaa) - { - case 8: - if (qualityHint) - { - *outMultisampleType = D3DMULTISAMPLE_8_SAMPLES; - *outMultisampleQuality = 0; - } - else - { - *outMultisampleType = D3DMULTISAMPLE_4_SAMPLES; - *outMultisampleQuality = 2; - } - break; - case 16: - if (qualityHint) - { - *outMultisampleType = D3DMULTISAMPLE_8_SAMPLES; - *outMultisampleQuality = 2; - } - else - { - *outMultisampleType = D3DMULTISAMPLE_4_SAMPLES; - *outMultisampleQuality = 4; - } - break; - } - } - else // !CSAA - { - *outMultisampleType = (D3DMULTISAMPLE_TYPE)fsaa; - *outMultisampleQuality = 0; - } - - - HRESULT hr; - DWORD outQuality; - hr = mD3D->CheckDeviceMultiSampleType( - deviceDriver->getAdapterNumber(), - D3DDEVTYPE_HAL, - d3dPixelFormat, - fullScreen, - *outMultisampleType, - &outQuality); - - if (SUCCEEDED(hr) && - (!tryCSAA || outQuality > *outMultisampleQuality)) - { - ok = true; - } - else - { - // downgrade - if (tryCSAA && fsaa == 8) - { - // for CSAA, we'll try downgrading with quality mode at all samples. - // then try without quality, then drop CSAA - if (qualityHint) - { - // drop quality first - qualityHint = false; - } - else - { - // drop CSAA entirely - tryCSAA = false; - } - // return to original requested samples - fsaa = origFSAA; - } - else - { - // drop samples - --fsaa; - - OgreAssert(fsaa > 0, "FSAA underflow: infinite loop (this should never happen)"); - - if (fsaa <= 1) - { - // ran out of options, no FSAA - fsaa = 0; - ok = true; - - *outMultisampleType = D3DMULTISAMPLE_NONE; - *outMultisampleQuality = 0; - } - } - } - - } // while !ok - } - - //--------------------------------------------------------------------- - void D3D9RenderSystem::fireDeviceEvent( D3D9Device* device, const String & name ) - { - NameValuePairList params; - params["D3DDEVICE"] = StringConverter::toString((size_t)device->getD3D9Device()); - params["DEVICE_ADAPTER_NUMBER"] = StringConverter::toString(device->getAdapterNumber()); - - fireEvent(name, ¶ms); - } + //--------------------------------------------------------------------- + DWORD D3D9RenderSystem::getSamplerId(size_t unit) + { + return static_cast(unit) + + ((mTexStageDesc[unit].pVertexTex == NULL) ? 0 : D3DVERTEXTEXTURESAMPLER0); + } + + //--------------------------------------------------------------------- + void D3D9RenderSystem::notifyOnDeviceLost(D3D9Device* device) + { + StringStream ss; + + ss << "D3D9 Device 0x[" << device->getD3D9Device() << "] entered lost state"; + LogManager::getSingleton().logMessage(ss.str()); + + fireDeviceEvent(device, "DeviceLost"); + + } + + //--------------------------------------------------------------------- + void D3D9RenderSystem::notifyOnDeviceReset(D3D9Device* device) + { + // Reset state attributes. + mVertexProgramBound = false; + mFragmentProgramBound = false; + mLastVertexSourceCount = 0; + + + // Force all compositors to reconstruct their internal resources + // render textures will have been changed without their knowledge + CompositorManager::getSingleton()._reconstructAllCompositorResources(); + + // Restore previous active device. + + // Invalidate active view port. + mActiveViewport = NULL; + + StringStream ss; + + // Reset the texture stages, they will need to be rebound + for (size_t i = 0; i < OGRE_MAX_TEXTURE_LAYERS; ++i) + _setTexture(i, false, TexturePtr()); + + LogManager::getSingleton().logMessage("!!! Direct3D Device successfully restored."); + + ss << "D3D9 device: 0x[" << device->getD3D9Device() << "] was reset"; + LogManager::getSingleton().logMessage(ss.str()); + + fireDeviceEvent(device, "DeviceRestored"); + + } + + //--------------------------------------------------------------------- + void D3D9RenderSystem::determineFSAASettings(IDirect3DDevice9* d3d9Device, + size_t fsaa, const String& fsaaHint, D3DFORMAT d3dPixelFormat, + bool fullScreen, D3DMULTISAMPLE_TYPE *outMultisampleType, DWORD *outMultisampleQuality) + { + bool ok = false; + bool qualityHint = fsaaHint.find("Quality") != String::npos; + size_t origFSAA = fsaa; + + D3D9DriverList* driverList = getDirect3DDrivers(); + D3D9Driver* deviceDriver = mActiveD3DDriver; + D3D9Device* device = mDeviceManager->getDeviceFromD3D9Device(d3d9Device); + + for (uint i = 0; i < driverList->count(); ++i) + { + D3D9Driver* currDriver = driverList->item(i); + + if (currDriver->getAdapterNumber() == device->getAdapterNumber()) + { + deviceDriver = currDriver; + break; + } + } + + bool tryCSAA = false; + // NVIDIA, prefer CSAA if available for 8+ + // it would be tempting to use getCapabilities()->getVendor() == GPU_NVIDIA but + // if this is the first window, caps will not be initialised yet + if (deviceDriver->getAdapterIdentifier().VendorId == 0x10DE && + fsaa >= 8) + { + tryCSAA = true; + } + + while (!ok) + { + // Deal with special cases + if (tryCSAA) + { + // see http://developer.nvidia.com/object/coverage-sampled-aa.html + switch(fsaa) + { + case 8: + if (qualityHint) + { + *outMultisampleType = D3DMULTISAMPLE_8_SAMPLES; + *outMultisampleQuality = 0; + } + else + { + *outMultisampleType = D3DMULTISAMPLE_4_SAMPLES; + *outMultisampleQuality = 2; + } + break; + case 16: + if (qualityHint) + { + *outMultisampleType = D3DMULTISAMPLE_8_SAMPLES; + *outMultisampleQuality = 2; + } + else + { + *outMultisampleType = D3DMULTISAMPLE_4_SAMPLES; + *outMultisampleQuality = 4; + } + break; + } + } + else // !CSAA + { + *outMultisampleType = (D3DMULTISAMPLE_TYPE)fsaa; + *outMultisampleQuality = 0; + } + + + HRESULT hr; + DWORD outQuality; + hr = mD3D->CheckDeviceMultiSampleType( + deviceDriver->getAdapterNumber(), + D3DDEVTYPE_HAL, + d3dPixelFormat, + fullScreen, + *outMultisampleType, + &outQuality); + + if (SUCCEEDED(hr) && + (!tryCSAA || outQuality > *outMultisampleQuality)) + { + ok = true; + } + else + { + // downgrade + if (tryCSAA && fsaa == 8) + { + // for CSAA, we'll try downgrading with quality mode at all samples. + // then try without quality, then drop CSAA + if (qualityHint) + { + // drop quality first + qualityHint = false; + } + else + { + // drop CSAA entirely + tryCSAA = false; + } + // return to original requested samples + fsaa = origFSAA; + } + else + { + // drop samples + --fsaa; + + OgreAssert(fsaa > 0, "FSAA underflow: infinite loop (this should never happen)"); + + if (fsaa <= 1) + { + // ran out of options, no FSAA + fsaa = 0; + ok = true; + + *outMultisampleType = D3DMULTISAMPLE_NONE; + *outMultisampleQuality = 0; + } + } + } + + } // while !ok + } + + //--------------------------------------------------------------------- + void D3D9RenderSystem::fireDeviceEvent( D3D9Device* device, const String & name ) + { + NameValuePairList params; + params["D3DDEVICE"] = StringConverter::toString((size_t)device->getD3D9Device()); + params["DEVICE_ADAPTER_NUMBER"] = StringConverter::toString(device->getAdapterNumber()); + + fireEvent(name, ¶ms); + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9RenderWindow.cpp b/RenderSystems/Direct3D9/src/OgreD3D9RenderWindow.cpp index 906ca682b7a..67103875cb2 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9RenderWindow.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9RenderWindow.cpp @@ -41,922 +41,922 @@ THE SOFTWARE. namespace Ogre { - D3D9RenderWindow::D3D9RenderWindow(HINSTANCE instance) + D3D9RenderWindow::D3D9RenderWindow(HINSTANCE instance) : mInstance(instance) - { - mDevice = NULL; - mIsFullScreen = false; - mIsExternal = false; - mHWnd = 0; - mActive = false; - mClosed = false; - mHidden = false; - mSwitchingFullscreen = false; - mDisplayFrequency = 0; - mDeviceValid = false; - mUseNVPerfHUD = false; - mWindowedWinStyle = 0; - mFullscreenWinStyle = 0; - } - - D3D9RenderWindow::~D3D9RenderWindow() - { - destroy(); - } - - void D3D9RenderWindow::create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) - { - HINSTANCE hInst = mInstance; - - HWND parentHWnd = 0; - HWND externalHandle = 0; - mFSAAType = D3DMULTISAMPLE_NONE; - mFSAAQuality = 0; - mFSAA = 0; - mVSync = false; - mVSyncInterval = 1; - String title = name; - unsigned int colourDepth = 32; - int left = INT_MAX; // Defaults to screen center - int top = INT_MAX; // Defaults to screen center - bool depthBuffer = true; - String border = ""; - bool outerSize = false; - mUseNVPerfHUD = false; - size_t fsaaSamples = 0; - String fsaaHint; - bool enableDoubleClick = false; - int monitorIndex = -1; //Default by detecting the adapter from left / top position - - - if(miscParams) - { - // Get variable-length params - NameValuePairList::const_iterator opt; - // left (x) - opt = miscParams->find("left"); - if(opt != miscParams->end()) - left = StringConverter::parseInt(opt->second); - // top (y) - opt = miscParams->find("top"); - if(opt != miscParams->end()) - top = StringConverter::parseInt(opt->second); - // Window title - opt = miscParams->find("title"); - if(opt != miscParams->end()) - title = opt->second; - // parentWindowHandle -> parentHWnd - opt = miscParams->find("parentWindowHandle"); - if(opt != miscParams->end()) - parentHWnd = (HWND)StringConverter::parseSizeT(opt->second); - // externalWindowHandle -> externalHandle - opt = miscParams->find("externalWindowHandle"); - if(opt != miscParams->end()) - externalHandle = (HWND)StringConverter::parseSizeT(opt->second); - // vsync [parseBool] - opt = miscParams->find("vsync"); - if(opt != miscParams->end()) - mVSync = StringConverter::parseBool(opt->second); - // hidden [parseBool] - opt = miscParams->find("hidden"); - if(opt != miscParams->end()) - mHidden = StringConverter::parseBool(opt->second); - // vsyncInterval [parseUnsignedInt] - opt = miscParams->find("vsyncInterval"); - if(opt != miscParams->end()) - mVSyncInterval = StringConverter::parseUnsignedInt(opt->second); - // displayFrequency - opt = miscParams->find("displayFrequency"); - if(opt != miscParams->end()) - mDisplayFrequency = StringConverter::parseUnsignedInt(opt->second); - // colourDepth - opt = miscParams->find("colourDepth"); - if(opt != miscParams->end()) - colourDepth = StringConverter::parseUnsignedInt(opt->second); - // depthBuffer [parseBool] - opt = miscParams->find("depthBuffer"); - if(opt != miscParams->end()) - depthBuffer = StringConverter::parseBool(opt->second); - // FSAA settings - opt = miscParams->find("FSAA"); - if(opt != miscParams->end()) - { - mFSAA = StringConverter::parseUnsignedInt(opt->second); - } - opt = miscParams->find("FSAAHint"); - if(opt != miscParams->end()) - { - mFSAAHint = opt->second; - } - - // window border style - opt = miscParams->find("border"); - if(opt != miscParams->end()) - border = opt->second; - // set outer dimensions? - opt = miscParams->find("outerDimensions"); - if(opt != miscParams->end()) - outerSize = StringConverter::parseBool(opt->second); - // NV perf HUD? - opt = miscParams->find("useNVPerfHUD"); - if(opt != miscParams->end()) - mUseNVPerfHUD = StringConverter::parseBool(opt->second); - // sRGB? - opt = miscParams->find("gamma"); - if(opt != miscParams->end()) - mHwGamma = StringConverter::parseBool(opt->second); - // monitor index - opt = miscParams->find("monitorIndex"); - if(opt != miscParams->end()) - monitorIndex = StringConverter::parseInt(opt->second); - opt = miscParams->find("show"); - if(opt != miscParams->end()) - mHidden = !StringConverter::parseBool(opt->second); - // enable double click messages - opt = miscParams->find("enableDoubleClick"); - if(opt != miscParams->end()) - enableDoubleClick = StringConverter::parseBool(opt->second); - - } - mIsFullScreen = fullScreen; - - // Destroy current window if any - if( mHWnd ) - destroy(); - - if (!externalHandle) - { - DWORD dwStyleEx = 0; - HMONITOR hMonitor = NULL; - MONITORINFO monitorInfo; - RECT rc; - - // If we specified which adapter we want to use - find it's monitor. - if (monitorIndex != -1) - { - IDirect3D9* direct3D9 = D3D9RenderSystem::getDirect3D9(); - - for (uint i=0; i < direct3D9->GetAdapterCount(); ++i) - { - if (i == monitorIndex) - { - hMonitor = direct3D9->GetAdapterMonitor(i); - break; - } - } - } - - // If we didn't specified the adapter index, or if it didn't find it - if (hMonitor == NULL) - { - POINT windowAnchorPoint; - - // Fill in anchor point. - windowAnchorPoint.x = left; - windowAnchorPoint.y = top; - - - // Get the nearest monitor to this window. - hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTONEAREST); - } - - // Get the target monitor info - memset(&monitorInfo, 0, sizeof(MONITORINFO)); - monitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hMonitor, &monitorInfo); - - // Update window style flags. - mFullscreenWinStyle = WS_CLIPCHILDREN | WS_POPUP; - mWindowedWinStyle = WS_CLIPCHILDREN; - - if (!mHidden) - { - mFullscreenWinStyle |= WS_VISIBLE; - mWindowedWinStyle |= WS_VISIBLE; - } - - if (parentHWnd) - { - mWindowedWinStyle |= WS_CHILD; - } - else - { - if (border == "none") - mWindowedWinStyle |= WS_POPUP; - else if (border == "fixed") - mWindowedWinStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | - WS_SYSMENU | WS_MINIMIZEBOX; - else - mWindowedWinStyle |= WS_OVERLAPPEDWINDOW; - } - - unsigned int winWidth, winHeight; - winWidth = width; - winHeight = height; - - - // No specified top left -> Center the window in the middle of the monitor - if (left == INT_MAX || top == INT_MAX) - { - uint32 screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left; - uint32 screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; - - // clamp window dimensions to screen size - uint32 outerw = (winWidth < screenw)? winWidth : screenw; - uint32 outerh = (winHeight < screenh)? winHeight : screenh; - - if (left == INT_MAX) - left = monitorInfo.rcWork.left + (screenw - outerw) / 2; - else if (monitorIndex != -1) - left += monitorInfo.rcWork.left; - - if (top == INT_MAX) - top = monitorInfo.rcWork.top + (screenh - outerh) / 2; - else if (monitorIndex != -1) - top += monitorInfo.rcWork.top; - } - else if (monitorIndex != -1) - { - left += monitorInfo.rcWork.left; - top += monitorInfo.rcWork.top; - } - - mWidth = mDesiredWidth = width; - mHeight = mDesiredHeight = height; - mTop = top; - mLeft = left; - - if (fullScreen) - { - dwStyleEx |= WS_EX_TOPMOST; - mTop = monitorInfo.rcMonitor.top; - mLeft = monitorInfo.rcMonitor.left; - } - else - { + { + mDevice = NULL; + mIsFullScreen = false; + mIsExternal = false; + mHWnd = 0; + mActive = false; + mClosed = false; + mHidden = false; + mSwitchingFullscreen = false; + mDisplayFrequency = 0; + mDeviceValid = false; + mUseNVPerfHUD = false; + mWindowedWinStyle = 0; + mFullscreenWinStyle = 0; + } + + D3D9RenderWindow::~D3D9RenderWindow() + { + destroy(); + } + + void D3D9RenderWindow::create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams) + { + HINSTANCE hInst = mInstance; + + HWND parentHWnd = 0; + HWND externalHandle = 0; + mFSAAType = D3DMULTISAMPLE_NONE; + mFSAAQuality = 0; + mFSAA = 0; + mVSync = false; + mVSyncInterval = 1; + String title = name; + unsigned int colourDepth = 32; + int left = INT_MAX; // Defaults to screen center + int top = INT_MAX; // Defaults to screen center + bool depthBuffer = true; + String border = ""; + bool outerSize = false; + mUseNVPerfHUD = false; + size_t fsaaSamples = 0; + String fsaaHint; + bool enableDoubleClick = false; + int monitorIndex = -1; //Default by detecting the adapter from left / top position + + + if(miscParams) + { + // Get variable-length params + NameValuePairList::const_iterator opt; + // left (x) + opt = miscParams->find("left"); + if(opt != miscParams->end()) + left = StringConverter::parseInt(opt->second); + // top (y) + opt = miscParams->find("top"); + if(opt != miscParams->end()) + top = StringConverter::parseInt(opt->second); + // Window title + opt = miscParams->find("title"); + if(opt != miscParams->end()) + title = opt->second; + // parentWindowHandle -> parentHWnd + opt = miscParams->find("parentWindowHandle"); + if(opt != miscParams->end()) + parentHWnd = (HWND)StringConverter::parseSizeT(opt->second); + // externalWindowHandle -> externalHandle + opt = miscParams->find("externalWindowHandle"); + if(opt != miscParams->end()) + externalHandle = (HWND)StringConverter::parseSizeT(opt->second); + // vsync [parseBool] + opt = miscParams->find("vsync"); + if(opt != miscParams->end()) + mVSync = StringConverter::parseBool(opt->second); + // hidden [parseBool] + opt = miscParams->find("hidden"); + if(opt != miscParams->end()) + mHidden = StringConverter::parseBool(opt->second); + // vsyncInterval [parseUnsignedInt] + opt = miscParams->find("vsyncInterval"); + if(opt != miscParams->end()) + mVSyncInterval = StringConverter::parseUnsignedInt(opt->second); + // displayFrequency + opt = miscParams->find("displayFrequency"); + if(opt != miscParams->end()) + mDisplayFrequency = StringConverter::parseUnsignedInt(opt->second); + // colourDepth + opt = miscParams->find("colourDepth"); + if(opt != miscParams->end()) + colourDepth = StringConverter::parseUnsignedInt(opt->second); + // depthBuffer [parseBool] + opt = miscParams->find("depthBuffer"); + if(opt != miscParams->end()) + depthBuffer = StringConverter::parseBool(opt->second); + // FSAA settings + opt = miscParams->find("FSAA"); + if(opt != miscParams->end()) + { + mFSAA = StringConverter::parseUnsignedInt(opt->second); + } + opt = miscParams->find("FSAAHint"); + if(opt != miscParams->end()) + { + mFSAAHint = opt->second; + } + + // window border style + opt = miscParams->find("border"); + if(opt != miscParams->end()) + border = opt->second; + // set outer dimensions? + opt = miscParams->find("outerDimensions"); + if(opt != miscParams->end()) + outerSize = StringConverter::parseBool(opt->second); + // NV perf HUD? + opt = miscParams->find("useNVPerfHUD"); + if(opt != miscParams->end()) + mUseNVPerfHUD = StringConverter::parseBool(opt->second); + // sRGB? + opt = miscParams->find("gamma"); + if(opt != miscParams->end()) + mHwGamma = StringConverter::parseBool(opt->second); + // monitor index + opt = miscParams->find("monitorIndex"); + if(opt != miscParams->end()) + monitorIndex = StringConverter::parseInt(opt->second); + opt = miscParams->find("show"); + if(opt != miscParams->end()) + mHidden = !StringConverter::parseBool(opt->second); + // enable double click messages + opt = miscParams->find("enableDoubleClick"); + if(opt != miscParams->end()) + enableDoubleClick = StringConverter::parseBool(opt->second); + + } + mIsFullScreen = fullScreen; + + // Destroy current window if any + if( mHWnd ) + destroy(); + + if (!externalHandle) + { + DWORD dwStyleEx = 0; + HMONITOR hMonitor = NULL; + MONITORINFO monitorInfo; + RECT rc; + + // If we specified which adapter we want to use - find it's monitor. + if (monitorIndex != -1) + { + IDirect3D9* direct3D9 = D3D9RenderSystem::getDirect3D9(); + + for (uint i=0; i < direct3D9->GetAdapterCount(); ++i) + { + if (i == monitorIndex) + { + hMonitor = direct3D9->GetAdapterMonitor(i); + break; + } + } + } + + // If we didn't specified the adapter index, or if it didn't find it + if (hMonitor == NULL) + { + POINT windowAnchorPoint; + + // Fill in anchor point. + windowAnchorPoint.x = left; + windowAnchorPoint.y = top; + + + // Get the nearest monitor to this window. + hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTONEAREST); + } + + // Get the target monitor info + memset(&monitorInfo, 0, sizeof(MONITORINFO)); + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hMonitor, &monitorInfo); + + // Update window style flags. + mFullscreenWinStyle = WS_CLIPCHILDREN | WS_POPUP; + mWindowedWinStyle = WS_CLIPCHILDREN; + + if (!mHidden) + { + mFullscreenWinStyle |= WS_VISIBLE; + mWindowedWinStyle |= WS_VISIBLE; + } + + if (parentHWnd) + { + mWindowedWinStyle |= WS_CHILD; + } + else + { + if (border == "none") + mWindowedWinStyle |= WS_POPUP; + else if (border == "fixed") + mWindowedWinStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | + WS_SYSMENU | WS_MINIMIZEBOX; + else + mWindowedWinStyle |= WS_OVERLAPPEDWINDOW; + } + + unsigned int winWidth, winHeight; + winWidth = width; + winHeight = height; + + + // No specified top left -> Center the window in the middle of the monitor + if (left == INT_MAX || top == INT_MAX) + { + uint32 screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left; + uint32 screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; + + // clamp window dimensions to screen size + uint32 outerw = (winWidth < screenw)? winWidth : screenw; + uint32 outerh = (winHeight < screenh)? winHeight : screenh; + + if (left == INT_MAX) + left = monitorInfo.rcWork.left + (screenw - outerw) / 2; + else if (monitorIndex != -1) + left += monitorInfo.rcWork.left; + + if (top == INT_MAX) + top = monitorInfo.rcWork.top + (screenh - outerh) / 2; + else if (monitorIndex != -1) + top += monitorInfo.rcWork.top; + } + else if (monitorIndex != -1) + { + left += monitorInfo.rcWork.left; + top += monitorInfo.rcWork.top; + } + + mWidth = mDesiredWidth = width; + mHeight = mDesiredHeight = height; + mTop = top; + mLeft = left; + + if (fullScreen) + { + dwStyleEx |= WS_EX_TOPMOST; + mTop = monitorInfo.rcMonitor.top; + mLeft = monitorInfo.rcMonitor.left; + } + else + { adjustWindow(width, height, &winWidth, &winHeight); - if (!outerSize) - { - // Calculate window dimensions required - // to get the requested client area - SetRect(&rc, 0, 0, mWidth, mHeight); - AdjustWindowRect(&rc, getWindowStyle(fullScreen), false); - mWidth = rc.right - rc.left; - mHeight = rc.bottom - rc.top; - - // Clamp window rect to the nearest display monitor. - if (mLeft < monitorInfo.rcWork.left) - mLeft = monitorInfo.rcWork.left; - - if (mTop < monitorInfo.rcWork.top) - mTop = monitorInfo.rcWork.top; - - if (static_cast(winWidth) > monitorInfo.rcWork.right - mLeft) - winWidth = monitorInfo.rcWork.right - mLeft; - - if (static_cast(winHeight) > monitorInfo.rcWork.bottom - mTop) - winHeight = monitorInfo.rcWork.bottom - mTop; - } - } - - UINT classStyle = 0; - if (enableDoubleClick) - classStyle |= CS_DBLCLKS; - - - // Register the window class - // NB allow 4 bytes of window data for D3D9RenderWindow pointer - WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst, - LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), - (HBRUSH)GetStockObject(BLACK_BRUSH), 0, "OgreD3D9Wnd" }; - RegisterClass(&wc); - - // Create our main window - // Pass pointer to self - mIsExternal = false; - mHWnd = CreateWindowEx(dwStyleEx, "OgreD3D9Wnd", title.c_str(), getWindowStyle(fullScreen), - mLeft, mTop, winWidth, winHeight, parentHWnd, 0, hInst, this); - - WindowEventUtilities::_addRenderWindow(this); - } - else - { - mHWnd = externalHandle; - mIsExternal = true; - } - - RECT rc; - // top and left represent outer window coordinates - GetWindowRect(mHWnd, &rc); - mTop = rc.top; - mLeft = rc.left; - // width and height represent interior drawable area - GetClientRect(mHWnd, &rc); - mWidth = rc.right; - mHeight = rc.bottom; - - mName = name; - mDepthBufferPoolId = depthBuffer ? DepthBuffer::POOL_DEFAULT : DepthBuffer::POOL_NO_DEPTH; - mDepthBuffer = 0; - mColourDepth = colourDepth; - - LogManager::getSingleton().stream() - << "D3D9 : Created D3D9 Rendering Window '" - << mName << "' : " << mWidth << "x" << mHeight - << ", " << mColourDepth << "bpp"; - - mActive = true; - mClosed = false; - setHidden(mHidden); - } - - void D3D9RenderWindow::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) - { - if (fullScreen != mIsFullScreen || width != mWidth || height != mHeight) - { - if (fullScreen != mIsFullScreen) - mSwitchingFullscreen = true; - - bool oldFullscreen = mIsFullScreen; - mIsFullScreen = fullScreen; - mWidth = mDesiredWidth = width; - mHeight = mDesiredHeight = height; - - if (fullScreen) - { - // Get the nearest monitor to this window. - HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); - - // Get monitor info - MONITORINFO monitorInfo; - - memset(&monitorInfo, 0, sizeof(MONITORINFO)); - monitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hMonitor, &monitorInfo); - - mTop = monitorInfo.rcMonitor.top; - mLeft = monitorInfo.rcMonitor.left; - - // need different ordering here - - if (oldFullscreen) - { - // was previously fullscreen, just changing the resolution - SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, width, height, SWP_NOACTIVATE); - } - else - { - SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, width, height, SWP_NOACTIVATE); - //MoveWindow(mHWnd, mLeft, mTop, mWidth, mHeight, FALSE); - SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); - SetWindowPos(mHWnd, 0, 0,0, 0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - } - } - else - { - // Calculate window dimensions required - // to get the requested client area - unsigned int winWidth, winHeight; - winWidth = mWidth; - winHeight = mHeight; - - adjustWindow(mWidth, mHeight, &winWidth, &winHeight); - - SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); - SetWindowPos(mHWnd, HWND_NOTOPMOST, 0, 0, winWidth, winHeight, - SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE); - // Note that we also set the position in the restoreLostDevice method - // via _finishSwitchingFullScreen - - // Update the current rect. - updateWindowRect(); - } - - // Have to release & trigger device reset - // NB don't use windowMovedOrResized since Win32 doesn't know - // about the size change yet - mDevice->invalidate(this); - // Notify viewports of resize - ViewportList::iterator it = mViewportList.begin(); - while( it != mViewportList.end() ) - (*it++).second->_updateDimensions(); - } - } - - void D3D9RenderWindow::adjustWindow(unsigned int clientWidth, unsigned int clientHeight, - unsigned int* winWidth, unsigned int* winHeight) - { - // NB only call this for non full screen - RECT rc; - SetRect(&rc, 0, 0, clientWidth, clientHeight); - AdjustWindowRect(&rc, getWindowStyle(mIsFullScreen), false); - *winWidth = rc.right - rc.left; - *winHeight = rc.bottom - rc.top; - } - - void D3D9RenderWindow::_finishSwitchingFullscreen() - { - if(mIsFullScreen) - { - // Need to reset the region on the window sometimes, when the - // windowed mode was constrained by desktop - HRGN hRgn = CreateRectRgn(0,0,mWidth, mHeight); - SetWindowRgn(mHWnd, hRgn, FALSE); - } - else - { - // When switching back to windowed mode, need to reset window size - // after device has been restored - // We may have had a resize event which polluted our desired sizes - if (mWidth != mDesiredWidth || - mHeight != mDesiredHeight) - { - mWidth = mDesiredWidth; - mHeight = mDesiredHeight; - } - unsigned int winWidth, winHeight; - adjustWindow(mWidth, mHeight, &winWidth, &winHeight); - - // deal with centering when switching down to smaller resolution - HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); - MONITORINFO monitorInfo; - memset(&monitorInfo, 0, sizeof(MONITORINFO)); - monitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hMonitor, &monitorInfo); - - ULONG screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left; - ULONG screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; - - int left = screenw > winWidth ? ((screenw - winWidth) / 2) : 0; - int top = screenh > winHeight ? ((screenh - winHeight) / 2) : 0; - SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight, - SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE); - - updateWindowRect(); - } - mSwitchingFullscreen = false; - } - - void D3D9RenderWindow::buildPresentParameters(D3DPRESENT_PARAMETERS* presentParams) - { - // Set up the presentation parameters - IDirect3D9* pD3D = D3D9RenderSystem::getDirect3D9(); - D3DDEVTYPE devType = D3DDEVTYPE_HAL; - - if (mDevice != NULL) - devType = mDevice->getDeviceType(); - - - ZeroMemory( presentParams, sizeof(D3DPRESENT_PARAMETERS) ); - presentParams->Windowed = !mIsFullScreen; - - DWORD version = GetVersion(); - DWORD major = (DWORD) (LOBYTE(LOWORD(version))); - DWORD minor = (DWORD) (HIBYTE(LOWORD(version))); - bool isWindows7 = (major > 6) || ((major == 6) && (minor >= 1)); - - // http://msdn.microsoft.com/en-us/library/windows/desktop/bb172574%28v=vs.85%29.aspx - // Multisampling is valid only on a swap chain that is being created or reset with the D3DSWAPEFFECT_DISCARD swap effect. - bool useFlipSwap = D3D9RenderSystem::isDirectX9Ex() && isWindows7 && (isAA() == false); - - presentParams->SwapEffect = useFlipSwap ? D3DSWAPEFFECT_FLIPEX : D3DSWAPEFFECT_DISCARD; - // triple buffer if VSync is on or if flip swap is used. Otherwise we may get a performance penalty. - presentParams->BackBufferCount = mVSync || useFlipSwap ? 2 : 1; - presentParams->EnableAutoDepthStencil = (mDepthBufferPoolId != DepthBuffer::POOL_NO_DEPTH); - presentParams->hDeviceWindow = mHWnd; - presentParams->BackBufferWidth = mWidth; - presentParams->BackBufferHeight = mHeight; - presentParams->FullScreen_RefreshRateInHz = mIsFullScreen ? mDisplayFrequency : 0; - - if (presentParams->BackBufferWidth == 0) - presentParams->BackBufferWidth = 1; - - if (presentParams->BackBufferHeight == 0) - presentParams->BackBufferHeight = 1; - - - if (mVSync) - { - // D3D9 only seems to support 2-4 presentation intervals in fullscreen - if (mIsFullScreen) - { - switch(mVSyncInterval) - { - case 1: - default: - presentParams->PresentationInterval = D3DPRESENT_INTERVAL_ONE; - break; - case 2: - presentParams->PresentationInterval = D3DPRESENT_INTERVAL_TWO; - break; - case 3: - presentParams->PresentationInterval = D3DPRESENT_INTERVAL_THREE; - break; - case 4: - presentParams->PresentationInterval = D3DPRESENT_INTERVAL_FOUR; - break; - }; - // check that the interval was supported, revert to 1 to be safe otherwise - D3DCAPS9 caps; - pD3D->GetDeviceCaps(mDevice->getAdapterNumber(), devType, &caps); - if (!(caps.PresentationIntervals & presentParams->PresentationInterval)) - presentParams->PresentationInterval = D3DPRESENT_INTERVAL_ONE; - - } - else - { - presentParams->PresentationInterval = D3DPRESENT_INTERVAL_ONE; - } - - } - else - { - // NB not using vsync in windowed mode in D3D9 can cause jerking at low - // frame rates no matter what buffering modes are used (odd - perhaps a - // timer issue in D3D9 since GL doesn't suffer from this) - // low is < 200fps in this context - if (!mIsFullScreen) - { - LogManager::getSingleton().logMessage("D3D9 : WARNING - " - "disabling VSync in windowed mode can cause timing issues at lower " - "frame rates, turn VSync on if you observe this problem."); - } - presentParams->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - } - - presentParams->BackBufferFormat = D3DFMT_R5G6B5; - if( mColourDepth > 16 ) - presentParams->BackBufferFormat = D3DFMT_X8R8G8B8; - - if (mColourDepth > 16 ) - { - // Try to create a 32-bit depth, 8-bit stencil - if( FAILED( pD3D->CheckDeviceFormat(mDevice->getAdapterNumber(), - devType, presentParams->BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, D3DFMT_D24S8 ))) - { - // Bugger, no 8-bit hardware stencil, just try 32-bit zbuffer - if( FAILED( pD3D->CheckDeviceFormat(mDevice->getAdapterNumber(), - devType, presentParams->BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, - D3DRTYPE_SURFACE, D3DFMT_D32 ))) - { - // Jeez, what a naff card. Fall back on 16-bit depth buffering - presentParams->AutoDepthStencilFormat = D3DFMT_D16; - } - else - presentParams->AutoDepthStencilFormat = D3DFMT_D32; - } - else - { - // Woohoo! - if( SUCCEEDED( pD3D->CheckDepthStencilMatch( mDevice->getAdapterNumber(), devType, - presentParams->BackBufferFormat, presentParams->BackBufferFormat, D3DFMT_D24S8 ) ) ) - { - presentParams->AutoDepthStencilFormat = D3DFMT_D24S8; - } - else - presentParams->AutoDepthStencilFormat = D3DFMT_D24X8; - } - } - else - // 16-bit depth, software stencil - presentParams->AutoDepthStencilFormat = D3DFMT_D16; - - - D3D9RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); - - rsys->determineFSAASettings(mDevice->getD3D9Device(), - mFSAA, mFSAAHint, presentParams->BackBufferFormat, mIsFullScreen, - &mFSAAType, &mFSAAQuality); - - presentParams->MultiSampleType = mFSAAType; - presentParams->MultiSampleQuality = (mFSAAQuality == 0) ? 0 : mFSAAQuality; - - // Check sRGB - if (mHwGamma) - { - /* hmm, this never succeeds even when device does support?? - if(FAILED(pD3D->CheckDeviceFormat(mDriver->getAdapterNumber(), - devType, presentParams->BackBufferFormat, D3DUSAGE_QUERY_SRGBWRITE, - D3DRTYPE_SURFACE, presentParams->BackBufferFormat ))) - { - // disable - not supported - mHwGamma = false; - } - */ - - } - } - - void D3D9RenderWindow::destroy() - { - if (mDevice != NULL) - { - mDevice->detachRenderWindow(this); - mDevice = NULL; - } - - if (mHWnd && !mIsExternal) - { - WindowEventUtilities::_removeRenderWindow(this); - DestroyWindow(mHWnd); - } - - mHWnd = 0; - mActive = false; - mClosed = true; - } - - bool D3D9RenderWindow::isActive() const - { - if (isFullScreen()) - return isVisible(); - - return mActive && isVisible(); - } - - bool D3D9RenderWindow::isVisible() const - { - return (mHWnd && !IsIconic(mHWnd)); - } - - void D3D9RenderWindow::setHidden(bool hidden) - { - mHidden = hidden; - if (!mIsExternal) - { - if (hidden) - ShowWindow(mHWnd, SW_HIDE); - else - ShowWindow(mHWnd, SW_SHOWNORMAL); - } - } - - void D3D9RenderWindow::setVSyncEnabled(bool vsync) - { - mVSync = vsync; - if (!mIsExternal) - { - // we need to reset the device with new vsync params - // invalidate the window to trigger this - mDevice->invalidate(this); - } - } - - bool D3D9RenderWindow::isVSyncEnabled() const - { - return mVSync; - } - - void D3D9RenderWindow::setVSyncInterval(unsigned int interval) - { - mVSyncInterval = interval; - if (mVSync) - setVSyncEnabled(true); - } - - unsigned int D3D9RenderWindow::getVSyncInterval() const - { - return mVSyncInterval; - } - - void D3D9RenderWindow::reposition(int top, int left) - { - if (mHWnd && !mIsFullScreen) - { - SetWindowPos(mHWnd, 0, top, left, 0, 0, - SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - } - } - - void D3D9RenderWindow::resize(unsigned int width, unsigned int height) - { - if (!mIsExternal) - { - if (mHWnd && !mIsFullScreen) - { - unsigned int winWidth, winHeight; - adjustWindow(width, height, &winWidth, &winHeight); - SetWindowPos(mHWnd, 0, 0, 0, winWidth, winHeight, - SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); - } - } - else - updateWindowRect(); - } - - void D3D9RenderWindow::windowMovedOrResized() - { - if (!mHWnd || IsIconic(mHWnd)) - return; - - updateWindowRect(); - } - - void D3D9RenderWindow::swapBuffers( ) - { - if (mDeviceValid) - mDevice->present(this); - } - - void D3D9RenderWindow::getCustomAttribute( const String& name, void* pData ) - { - // Valid attributes and their equvalent native functions: - // D3DDEVICE : getD3DDevice - // WINDOW : getWindowHandle - - if( name == "D3DDEVICE" ) - { - IDirect3DDevice9* *pDev = (IDirect3DDevice9**)pData; - *pDev = getD3D9Device(); - return; - } - else if( name == "WINDOW" ) - { - HWND *pHwnd = (HWND*)pData; - *pHwnd = getWindowHandle(); - return; - } - else if( name == "isTexture" ) - { - bool *b = reinterpret_cast< bool * >( pData ); - *b = false; - - return; - } - else if( name == "D3DZBUFFER" ) - { - IDirect3DSurface9* *pSurf = (IDirect3DSurface9**)pData; - *pSurf = mDevice->getDepthBuffer(this); - return; - } - else if( name == "DDBACKBUFFER" ) - { - IDirect3DSurface9* *pSurf = (IDirect3DSurface9**)pData; - *pSurf = mDevice->getBackBuffer(this); - return; - } - else if( name == "DDFRONTBUFFER" ) - { - IDirect3DSurface9* *pSurf = (IDirect3DSurface9**)pData; - *pSurf = mDevice->getBackBuffer(this); - return; - } - } - - void D3D9RenderWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) - { - mDevice->copyContentsToMemory(this, dst, buffer); - } - //----------------------------------------------------------------------------- - void D3D9RenderWindow::_beginUpdate() - { - // External windows should update per frame - // since it dosen't get the window resize/move messages. - if (mIsExternal) - { - updateWindowRect(); - } - - if (mWidth == 0 || mHeight == 0) - { - mDeviceValid = false; - return; - } - - D3D9RenderSystem::getDeviceManager()->setActiveRenderTargetDevice(mDevice); - - // Check that device can be used for rendering operations. - mDeviceValid = mDevice->validate(this); - if (mDeviceValid) - { - // Finish window / fullscreen mode switch. - if (_getSwitchingFullscreen()) - { - _finishSwitchingFullscreen(); - // have to re-validate since this may have altered dimensions - mDeviceValid = mDevice->validate(this); - } - } - - RenderWindow::_beginUpdate(); - } - //--------------------------------------------------------------------- - void D3D9RenderWindow::_updateViewport(Viewport* viewport, bool updateStatistics) - { - if (mDeviceValid) - { - RenderWindow::_updateViewport(viewport, updateStatistics); - } - } - //--------------------------------------------------------------------- - void D3D9RenderWindow::_endUpdate() - { - RenderWindow::_endUpdate(); - - D3D9RenderSystem::getDeviceManager()->setActiveRenderTargetDevice(NULL); - - } - //----------------------------------------------------------------------------- - IDirect3DDevice9* D3D9RenderWindow::getD3D9Device() - { - return mDevice->getD3D9Device(); - } - - //----------------------------------------------------------------------------- - IDirect3DSurface9* D3D9RenderWindow::getRenderSurface() - { - return mDevice->getBackBuffer(this); - } - - //----------------------------------------------------------------------------- - bool D3D9RenderWindow::_getSwitchingFullscreen() const - { - return mSwitchingFullscreen; - } - - //----------------------------------------------------------------------------- - D3D9Device* D3D9RenderWindow::getDevice() - { - return mDevice; - } - - //----------------------------------------------------------------------------- - void D3D9RenderWindow::setDevice(D3D9Device* device) - { - mDevice = device; - mDeviceValid = false; - } - - //----------------------------------------------------------------------------- - bool D3D9RenderWindow::isDepthBuffered() const - { - return (mDepthBufferPoolId != DepthBuffer::POOL_NO_DEPTH); - } - - //----------------------------------------------------------------------------- - void D3D9RenderWindow::updateWindowRect() - { - RECT rc; - BOOL result; - - // Update top left parameters - result = GetWindowRect(mHWnd, &rc); - if (result == FALSE) - { - mTop = 0; - mLeft = 0; - mWidth = 0; - mHeight = 0; - return; - } - - mTop = rc.top; - mLeft = rc.left; - - // width and height represent drawable area only - result = GetClientRect(mHWnd, &rc); - if (result == FALSE) - { - mTop = 0; - mLeft = 0; - mWidth = 0; - mHeight = 0; - return; - } - unsigned int width = rc.right - rc.left; - unsigned int height = rc.bottom - rc.top; - - // Case window resized. - if (width != mWidth || height != mHeight) - { - mWidth = rc.right - rc.left; - mHeight = rc.bottom - rc.top; - - // Notify viewports of resize - ViewportList::iterator it = mViewportList.begin(); - while( it != mViewportList.end() ) - (*it++).second->_updateDimensions(); - } - - } - //----------------------------------------------------------------------------- - void D3D9RenderWindow::updateStats( void ) - { - RenderTarget::updateStats(); - mStats.vBlankMissCount = mDevice->getVBlankMissCount(this); - } - //----------------------------------------------------------------------------- - bool D3D9RenderWindow::isNvPerfHUDEnable() const - { - return mUseNVPerfHUD; - } - //--------------------------------------------------------------------- - bool D3D9RenderWindow::_validateDevice() - { - mDeviceValid = mDevice->validate(this); - return mDeviceValid; - } + if (!outerSize) + { + // Calculate window dimensions required + // to get the requested client area + SetRect(&rc, 0, 0, mWidth, mHeight); + AdjustWindowRect(&rc, getWindowStyle(fullScreen), false); + mWidth = rc.right - rc.left; + mHeight = rc.bottom - rc.top; + + // Clamp window rect to the nearest display monitor. + if (mLeft < monitorInfo.rcWork.left) + mLeft = monitorInfo.rcWork.left; + + if (mTop < monitorInfo.rcWork.top) + mTop = monitorInfo.rcWork.top; + + if (static_cast(winWidth) > monitorInfo.rcWork.right - mLeft) + winWidth = monitorInfo.rcWork.right - mLeft; + + if (static_cast(winHeight) > monitorInfo.rcWork.bottom - mTop) + winHeight = monitorInfo.rcWork.bottom - mTop; + } + } + + UINT classStyle = 0; + if (enableDoubleClick) + classStyle |= CS_DBLCLKS; + + + // Register the window class + // NB allow 4 bytes of window data for D3D9RenderWindow pointer + WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst, + LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), + (HBRUSH)GetStockObject(BLACK_BRUSH), 0, "OgreD3D9Wnd" }; + RegisterClass(&wc); + + // Create our main window + // Pass pointer to self + mIsExternal = false; + mHWnd = CreateWindowEx(dwStyleEx, "OgreD3D9Wnd", title.c_str(), getWindowStyle(fullScreen), + mLeft, mTop, winWidth, winHeight, parentHWnd, 0, hInst, this); + + WindowEventUtilities::_addRenderWindow(this); + } + else + { + mHWnd = externalHandle; + mIsExternal = true; + } + + RECT rc; + // top and left represent outer window coordinates + GetWindowRect(mHWnd, &rc); + mTop = rc.top; + mLeft = rc.left; + // width and height represent interior drawable area + GetClientRect(mHWnd, &rc); + mWidth = rc.right; + mHeight = rc.bottom; + + mName = name; + mDepthBufferPoolId = depthBuffer ? DepthBuffer::POOL_DEFAULT : DepthBuffer::POOL_NO_DEPTH; + mDepthBuffer = 0; + mColourDepth = colourDepth; + + LogManager::getSingleton().stream() + << "D3D9 : Created D3D9 Rendering Window '" + << mName << "' : " << mWidth << "x" << mHeight + << ", " << mColourDepth << "bpp"; + + mActive = true; + mClosed = false; + setHidden(mHidden); + } + + void D3D9RenderWindow::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) + { + if (fullScreen != mIsFullScreen || width != mWidth || height != mHeight) + { + if (fullScreen != mIsFullScreen) + mSwitchingFullscreen = true; + + bool oldFullscreen = mIsFullScreen; + mIsFullScreen = fullScreen; + mWidth = mDesiredWidth = width; + mHeight = mDesiredHeight = height; + + if (fullScreen) + { + // Get the nearest monitor to this window. + HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); + + // Get monitor info + MONITORINFO monitorInfo; + + memset(&monitorInfo, 0, sizeof(MONITORINFO)); + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hMonitor, &monitorInfo); + + mTop = monitorInfo.rcMonitor.top; + mLeft = monitorInfo.rcMonitor.left; + + // need different ordering here + + if (oldFullscreen) + { + // was previously fullscreen, just changing the resolution + SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, width, height, SWP_NOACTIVATE); + } + else + { + SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, width, height, SWP_NOACTIVATE); + //MoveWindow(mHWnd, mLeft, mTop, mWidth, mHeight, FALSE); + SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); + SetWindowPos(mHWnd, 0, 0,0, 0,0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + } + } + else + { + // Calculate window dimensions required + // to get the requested client area + unsigned int winWidth, winHeight; + winWidth = mWidth; + winHeight = mHeight; + + adjustWindow(mWidth, mHeight, &winWidth, &winHeight); + + SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); + SetWindowPos(mHWnd, HWND_NOTOPMOST, 0, 0, winWidth, winHeight, + SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOACTIVATE); + // Note that we also set the position in the restoreLostDevice method + // via _finishSwitchingFullScreen + + // Update the current rect. + updateWindowRect(); + } + + // Have to release & trigger device reset + // NB don't use windowMovedOrResized since Win32 doesn't know + // about the size change yet + mDevice->invalidate(this); + // Notify viewports of resize + ViewportList::iterator it = mViewportList.begin(); + while( it != mViewportList.end() ) + (*it++).second->_updateDimensions(); + } + } + + void D3D9RenderWindow::adjustWindow(unsigned int clientWidth, unsigned int clientHeight, + unsigned int* winWidth, unsigned int* winHeight) + { + // NB only call this for non full screen + RECT rc; + SetRect(&rc, 0, 0, clientWidth, clientHeight); + AdjustWindowRect(&rc, getWindowStyle(mIsFullScreen), false); + *winWidth = rc.right - rc.left; + *winHeight = rc.bottom - rc.top; + } + + void D3D9RenderWindow::_finishSwitchingFullscreen() + { + if(mIsFullScreen) + { + // Need to reset the region on the window sometimes, when the + // windowed mode was constrained by desktop + HRGN hRgn = CreateRectRgn(0,0,mWidth, mHeight); + SetWindowRgn(mHWnd, hRgn, FALSE); + } + else + { + // When switching back to windowed mode, need to reset window size + // after device has been restored + // We may have had a resize event which polluted our desired sizes + if (mWidth != mDesiredWidth || + mHeight != mDesiredHeight) + { + mWidth = mDesiredWidth; + mHeight = mDesiredHeight; + } + unsigned int winWidth, winHeight; + adjustWindow(mWidth, mHeight, &winWidth, &winHeight); + + // deal with centering when switching down to smaller resolution + HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); + MONITORINFO monitorInfo; + memset(&monitorInfo, 0, sizeof(MONITORINFO)); + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hMonitor, &monitorInfo); + + ULONG screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left; + ULONG screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; + + int left = screenw > winWidth ? ((screenw - winWidth) / 2) : 0; + int top = screenh > winHeight ? ((screenh - winHeight) / 2) : 0; + SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight, + SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE); + + updateWindowRect(); + } + mSwitchingFullscreen = false; + } + + void D3D9RenderWindow::buildPresentParameters(D3DPRESENT_PARAMETERS* presentParams) + { + // Set up the presentation parameters + IDirect3D9* pD3D = D3D9RenderSystem::getDirect3D9(); + D3DDEVTYPE devType = D3DDEVTYPE_HAL; + + if (mDevice != NULL) + devType = mDevice->getDeviceType(); + + + ZeroMemory( presentParams, sizeof(D3DPRESENT_PARAMETERS) ); + presentParams->Windowed = !mIsFullScreen; + + DWORD version = GetVersion(); + DWORD major = (DWORD) (LOBYTE(LOWORD(version))); + DWORD minor = (DWORD) (HIBYTE(LOWORD(version))); + bool isWindows7 = (major > 6) || ((major == 6) && (minor >= 1)); + + // http://msdn.microsoft.com/en-us/library/windows/desktop/bb172574%28v=vs.85%29.aspx + // Multisampling is valid only on a swap chain that is being created or reset with the D3DSWAPEFFECT_DISCARD swap effect. + bool useFlipSwap = D3D9RenderSystem::isDirectX9Ex() && isWindows7 && (isAA() == false); + + presentParams->SwapEffect = useFlipSwap ? D3DSWAPEFFECT_FLIPEX : D3DSWAPEFFECT_DISCARD; + // triple buffer if VSync is on or if flip swap is used. Otherwise we may get a performance penalty. + presentParams->BackBufferCount = mVSync || useFlipSwap ? 2 : 1; + presentParams->EnableAutoDepthStencil = (mDepthBufferPoolId != DepthBuffer::POOL_NO_DEPTH); + presentParams->hDeviceWindow = mHWnd; + presentParams->BackBufferWidth = mWidth; + presentParams->BackBufferHeight = mHeight; + presentParams->FullScreen_RefreshRateInHz = mIsFullScreen ? mDisplayFrequency : 0; + + if (presentParams->BackBufferWidth == 0) + presentParams->BackBufferWidth = 1; + + if (presentParams->BackBufferHeight == 0) + presentParams->BackBufferHeight = 1; + + + if (mVSync) + { + // D3D9 only seems to support 2-4 presentation intervals in fullscreen + if (mIsFullScreen) + { + switch(mVSyncInterval) + { + case 1: + default: + presentParams->PresentationInterval = D3DPRESENT_INTERVAL_ONE; + break; + case 2: + presentParams->PresentationInterval = D3DPRESENT_INTERVAL_TWO; + break; + case 3: + presentParams->PresentationInterval = D3DPRESENT_INTERVAL_THREE; + break; + case 4: + presentParams->PresentationInterval = D3DPRESENT_INTERVAL_FOUR; + break; + }; + // check that the interval was supported, revert to 1 to be safe otherwise + D3DCAPS9 caps; + pD3D->GetDeviceCaps(mDevice->getAdapterNumber(), devType, &caps); + if (!(caps.PresentationIntervals & presentParams->PresentationInterval)) + presentParams->PresentationInterval = D3DPRESENT_INTERVAL_ONE; + + } + else + { + presentParams->PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } + + } + else + { + // NB not using vsync in windowed mode in D3D9 can cause jerking at low + // frame rates no matter what buffering modes are used (odd - perhaps a + // timer issue in D3D9 since GL doesn't suffer from this) + // low is < 200fps in this context + if (!mIsFullScreen) + { + LogManager::getSingleton().logMessage("D3D9 : WARNING - " + "disabling VSync in windowed mode can cause timing issues at lower " + "frame rates, turn VSync on if you observe this problem."); + } + presentParams->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + + presentParams->BackBufferFormat = D3DFMT_R5G6B5; + if( mColourDepth > 16 ) + presentParams->BackBufferFormat = D3DFMT_X8R8G8B8; + + if (mColourDepth > 16 ) + { + // Try to create a 32-bit depth, 8-bit stencil + if( FAILED( pD3D->CheckDeviceFormat(mDevice->getAdapterNumber(), + devType, presentParams->BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, D3DFMT_D24S8 ))) + { + // Bugger, no 8-bit hardware stencil, just try 32-bit zbuffer + if( FAILED( pD3D->CheckDeviceFormat(mDevice->getAdapterNumber(), + devType, presentParams->BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, + D3DRTYPE_SURFACE, D3DFMT_D32 ))) + { + // Jeez, what a naff card. Fall back on 16-bit depth buffering + presentParams->AutoDepthStencilFormat = D3DFMT_D16; + } + else + presentParams->AutoDepthStencilFormat = D3DFMT_D32; + } + else + { + // Woohoo! + if( SUCCEEDED( pD3D->CheckDepthStencilMatch( mDevice->getAdapterNumber(), devType, + presentParams->BackBufferFormat, presentParams->BackBufferFormat, D3DFMT_D24S8 ) ) ) + { + presentParams->AutoDepthStencilFormat = D3DFMT_D24S8; + } + else + presentParams->AutoDepthStencilFormat = D3DFMT_D24X8; + } + } + else + // 16-bit depth, software stencil + presentParams->AutoDepthStencilFormat = D3DFMT_D16; + + + D3D9RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); + + rsys->determineFSAASettings(mDevice->getD3D9Device(), + mFSAA, mFSAAHint, presentParams->BackBufferFormat, mIsFullScreen, + &mFSAAType, &mFSAAQuality); + + presentParams->MultiSampleType = mFSAAType; + presentParams->MultiSampleQuality = (mFSAAQuality == 0) ? 0 : mFSAAQuality; + + // Check sRGB + if (mHwGamma) + { + /* hmm, this never succeeds even when device does support?? + if(FAILED(pD3D->CheckDeviceFormat(mDriver->getAdapterNumber(), + devType, presentParams->BackBufferFormat, D3DUSAGE_QUERY_SRGBWRITE, + D3DRTYPE_SURFACE, presentParams->BackBufferFormat ))) + { + // disable - not supported + mHwGamma = false; + } + */ + + } + } + + void D3D9RenderWindow::destroy() + { + if (mDevice != NULL) + { + mDevice->detachRenderWindow(this); + mDevice = NULL; + } + + if (mHWnd && !mIsExternal) + { + WindowEventUtilities::_removeRenderWindow(this); + DestroyWindow(mHWnd); + } + + mHWnd = 0; + mActive = false; + mClosed = true; + } + + bool D3D9RenderWindow::isActive() const + { + if (isFullScreen()) + return isVisible(); + + return mActive && isVisible(); + } + + bool D3D9RenderWindow::isVisible() const + { + return (mHWnd && !IsIconic(mHWnd)); + } + + void D3D9RenderWindow::setHidden(bool hidden) + { + mHidden = hidden; + if (!mIsExternal) + { + if (hidden) + ShowWindow(mHWnd, SW_HIDE); + else + ShowWindow(mHWnd, SW_SHOWNORMAL); + } + } + + void D3D9RenderWindow::setVSyncEnabled(bool vsync) + { + mVSync = vsync; + if (!mIsExternal) + { + // we need to reset the device with new vsync params + // invalidate the window to trigger this + mDevice->invalidate(this); + } + } + + bool D3D9RenderWindow::isVSyncEnabled() const + { + return mVSync; + } + + void D3D9RenderWindow::setVSyncInterval(unsigned int interval) + { + mVSyncInterval = interval; + if (mVSync) + setVSyncEnabled(true); + } + + unsigned int D3D9RenderWindow::getVSyncInterval() const + { + return mVSyncInterval; + } + + void D3D9RenderWindow::reposition(int top, int left) + { + if (mHWnd && !mIsFullScreen) + { + SetWindowPos(mHWnd, 0, top, left, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + + void D3D9RenderWindow::resize(unsigned int width, unsigned int height) + { + if (!mIsExternal) + { + if (mHWnd && !mIsFullScreen) + { + unsigned int winWidth, winHeight; + adjustWindow(width, height, &winWidth, &winHeight); + SetWindowPos(mHWnd, 0, 0, 0, winWidth, winHeight, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + else + updateWindowRect(); + } + + void D3D9RenderWindow::windowMovedOrResized() + { + if (!mHWnd || IsIconic(mHWnd)) + return; + + updateWindowRect(); + } + + void D3D9RenderWindow::swapBuffers( ) + { + if (mDeviceValid) + mDevice->present(this); + } + + void D3D9RenderWindow::getCustomAttribute( const String& name, void* pData ) + { + // Valid attributes and their equvalent native functions: + // D3DDEVICE : getD3DDevice + // WINDOW : getWindowHandle + + if( name == "D3DDEVICE" ) + { + IDirect3DDevice9* *pDev = (IDirect3DDevice9**)pData; + *pDev = getD3D9Device(); + return; + } + else if( name == "WINDOW" ) + { + HWND *pHwnd = (HWND*)pData; + *pHwnd = getWindowHandle(); + return; + } + else if( name == "isTexture" ) + { + bool *b = reinterpret_cast< bool * >( pData ); + *b = false; + + return; + } + else if( name == "D3DZBUFFER" ) + { + IDirect3DSurface9* *pSurf = (IDirect3DSurface9**)pData; + *pSurf = mDevice->getDepthBuffer(this); + return; + } + else if( name == "DDBACKBUFFER" ) + { + IDirect3DSurface9* *pSurf = (IDirect3DSurface9**)pData; + *pSurf = mDevice->getBackBuffer(this); + return; + } + else if( name == "DDFRONTBUFFER" ) + { + IDirect3DSurface9* *pSurf = (IDirect3DSurface9**)pData; + *pSurf = mDevice->getBackBuffer(this); + return; + } + } + + void D3D9RenderWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) + { + mDevice->copyContentsToMemory(this, dst, buffer); + } + //----------------------------------------------------------------------------- + void D3D9RenderWindow::_beginUpdate() + { + // External windows should update per frame + // since it dosen't get the window resize/move messages. + if (mIsExternal) + { + updateWindowRect(); + } + + if (mWidth == 0 || mHeight == 0) + { + mDeviceValid = false; + return; + } + + D3D9RenderSystem::getDeviceManager()->setActiveRenderTargetDevice(mDevice); + + // Check that device can be used for rendering operations. + mDeviceValid = mDevice->validate(this); + if (mDeviceValid) + { + // Finish window / fullscreen mode switch. + if (_getSwitchingFullscreen()) + { + _finishSwitchingFullscreen(); + // have to re-validate since this may have altered dimensions + mDeviceValid = mDevice->validate(this); + } + } + + RenderWindow::_beginUpdate(); + } + //--------------------------------------------------------------------- + void D3D9RenderWindow::_updateViewport(Viewport* viewport, bool updateStatistics) + { + if (mDeviceValid) + { + RenderWindow::_updateViewport(viewport, updateStatistics); + } + } + //--------------------------------------------------------------------- + void D3D9RenderWindow::_endUpdate() + { + RenderWindow::_endUpdate(); + + D3D9RenderSystem::getDeviceManager()->setActiveRenderTargetDevice(NULL); + + } + //----------------------------------------------------------------------------- + IDirect3DDevice9* D3D9RenderWindow::getD3D9Device() + { + return mDevice->getD3D9Device(); + } + + //----------------------------------------------------------------------------- + IDirect3DSurface9* D3D9RenderWindow::getRenderSurface() + { + return mDevice->getBackBuffer(this); + } + + //----------------------------------------------------------------------------- + bool D3D9RenderWindow::_getSwitchingFullscreen() const + { + return mSwitchingFullscreen; + } + + //----------------------------------------------------------------------------- + D3D9Device* D3D9RenderWindow::getDevice() + { + return mDevice; + } + + //----------------------------------------------------------------------------- + void D3D9RenderWindow::setDevice(D3D9Device* device) + { + mDevice = device; + mDeviceValid = false; + } + + //----------------------------------------------------------------------------- + bool D3D9RenderWindow::isDepthBuffered() const + { + return (mDepthBufferPoolId != DepthBuffer::POOL_NO_DEPTH); + } + + //----------------------------------------------------------------------------- + void D3D9RenderWindow::updateWindowRect() + { + RECT rc; + BOOL result; + + // Update top left parameters + result = GetWindowRect(mHWnd, &rc); + if (result == FALSE) + { + mTop = 0; + mLeft = 0; + mWidth = 0; + mHeight = 0; + return; + } + + mTop = rc.top; + mLeft = rc.left; + + // width and height represent drawable area only + result = GetClientRect(mHWnd, &rc); + if (result == FALSE) + { + mTop = 0; + mLeft = 0; + mWidth = 0; + mHeight = 0; + return; + } + unsigned int width = rc.right - rc.left; + unsigned int height = rc.bottom - rc.top; + + // Case window resized. + if (width != mWidth || height != mHeight) + { + mWidth = rc.right - rc.left; + mHeight = rc.bottom - rc.top; + + // Notify viewports of resize + ViewportList::iterator it = mViewportList.begin(); + while( it != mViewportList.end() ) + (*it++).second->_updateDimensions(); + } + + } + //----------------------------------------------------------------------------- + void D3D9RenderWindow::updateStats( void ) + { + RenderTarget::updateStats(); + mStats.vBlankMissCount = mDevice->getVBlankMissCount(this); + } + //----------------------------------------------------------------------------- + bool D3D9RenderWindow::isNvPerfHUDEnable() const + { + return mUseNVPerfHUD; + } + //--------------------------------------------------------------------- + bool D3D9RenderWindow::_validateDevice() + { + mDeviceValid = mDevice->validate(this); + return mDeviceValid; + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9Resource.cpp b/RenderSystems/Direct3D9/src/OgreD3D9Resource.cpp index 6af9a90e158..022b764206a 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9Resource.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9Resource.cpp @@ -33,23 +33,23 @@ namespace Ogre { OGRE_STATIC_MUTEX_INSTANCE(D3D9Resource::msDeviceAccessMutex); - D3D9Resource::D3D9Resource() - { - D3D9RenderSystem::getResourceManager()->_notifyResourceCreated(static_cast(this)); - } + D3D9Resource::D3D9Resource() + { + D3D9RenderSystem::getResourceManager()->_notifyResourceCreated(static_cast(this)); + } - D3D9Resource::~D3D9Resource() - { - D3D9RenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast(this)); - } - - void D3D9Resource::lockDeviceAccess() - { - D3D9_DEVICE_ACCESS_LOCK; - } - - void D3D9Resource::unlockDeviceAccess() - { - D3D9_DEVICE_ACCESS_UNLOCK; - } + D3D9Resource::~D3D9Resource() + { + D3D9RenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast(this)); + } + + void D3D9Resource::lockDeviceAccess() + { + D3D9_DEVICE_ACCESS_LOCK; + } + + void D3D9Resource::unlockDeviceAccess() + { + D3D9_DEVICE_ACCESS_UNLOCK; + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9ResourceManager.cpp b/RenderSystems/Direct3D9/src/OgreD3D9ResourceManager.cpp index b084ec797fc..61cfec1a3f6 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9ResourceManager.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9ResourceManager.cpp @@ -31,123 +31,123 @@ THE SOFTWARE. namespace Ogre { - - //----------------------------------------------------------------------- - D3D9ResourceManager::D3D9ResourceManager() - { - mResourceCreationPolicy = RCP_CREATE_ON_ALL_DEVICES; - mDeviceAccessLockCount = 0; - mAutoHardwareBufferManagement = false; - } - - //----------------------------------------------------------------------- - D3D9ResourceManager::~D3D9ResourceManager() - { - - } + + //----------------------------------------------------------------------- + D3D9ResourceManager::D3D9ResourceManager() + { + mResourceCreationPolicy = RCP_CREATE_ON_ALL_DEVICES; + mDeviceAccessLockCount = 0; + mAutoHardwareBufferManagement = false; + } + + //----------------------------------------------------------------------- + D3D9ResourceManager::~D3D9ResourceManager() + { + + } - //----------------------------------------------------------------------- - void D3D9ResourceManager::setCreationPolicy(D3D9ResourceCreationPolicy creationPolicy) - { - mResourceCreationPolicy = creationPolicy; - } - - //----------------------------------------------------------------------- - D3D9ResourceCreationPolicy D3D9ResourceManager::getCreationPolicy() const - { - return mResourceCreationPolicy; - } - - //----------------------------------------------------------------------- - void D3D9ResourceManager::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) - { + //----------------------------------------------------------------------- + void D3D9ResourceManager::setCreationPolicy(D3D9ResourceCreationPolicy creationPolicy) + { + mResourceCreationPolicy = creationPolicy; + } + + //----------------------------------------------------------------------- + D3D9ResourceCreationPolicy D3D9ResourceManager::getCreationPolicy() const + { + return mResourceCreationPolicy; + } + + //----------------------------------------------------------------------- + void D3D9ResourceManager::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) + { OGRE_LOCK_MUTEX(mResourcesMutex); - ResourceContainerIterator it = mResources.begin(); - while (it != mResources.end()) - { - (*it)->notifyOnDeviceCreate(d3d9Device); - ++it; - } - } - - //----------------------------------------------------------------------- - void D3D9ResourceManager::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) - { + ResourceContainerIterator it = mResources.begin(); + while (it != mResources.end()) + { + (*it)->notifyOnDeviceCreate(d3d9Device); + ++it; + } + } + + //----------------------------------------------------------------------- + void D3D9ResourceManager::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) + { OGRE_LOCK_MUTEX(mResourcesMutex); - ResourceContainerIterator it = mResources.begin(); - while (it != mResources.end()) - { - (*it)->notifyOnDeviceDestroy(d3d9Device); - ++it; - } - } - - //----------------------------------------------------------------------- - void D3D9ResourceManager::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) - { + ResourceContainerIterator it = mResources.begin(); + while (it != mResources.end()) + { + (*it)->notifyOnDeviceDestroy(d3d9Device); + ++it; + } + } + + //----------------------------------------------------------------------- + void D3D9ResourceManager::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) + { OGRE_LOCK_MUTEX(mResourcesMutex); - ResourceContainerIterator it = mResources.begin(); - while (it != mResources.end()) - { - (*it)->notifyOnDeviceLost(d3d9Device); - ++it; - } - } - - //----------------------------------------------------------------------- - void D3D9ResourceManager::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) - { + ResourceContainerIterator it = mResources.begin(); + while (it != mResources.end()) + { + (*it)->notifyOnDeviceLost(d3d9Device); + ++it; + } + } + + //----------------------------------------------------------------------- + void D3D9ResourceManager::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) + { OGRE_LOCK_MUTEX(mResourcesMutex); - ResourceContainerIterator it = mResources.begin(); - while (it != mResources.end()) - { - (*it)->notifyOnDeviceReset(d3d9Device); - ++it; - } - } - - //----------------------------------------------------------------------- - void D3D9ResourceManager::_notifyResourceCreated(D3D9Resource* pResource) - { + ResourceContainerIterator it = mResources.begin(); + while (it != mResources.end()) + { + (*it)->notifyOnDeviceReset(d3d9Device); + ++it; + } + } + + //----------------------------------------------------------------------- + void D3D9ResourceManager::_notifyResourceCreated(D3D9Resource* pResource) + { OGRE_LOCK_MUTEX(mResourcesMutex); - mResources.insert(pResource); - } - - //----------------------------------------------------------------------- - void D3D9ResourceManager::_notifyResourceDestroyed(D3D9Resource* pResource) - { + mResources.insert(pResource); + } + + //----------------------------------------------------------------------- + void D3D9ResourceManager::_notifyResourceDestroyed(D3D9Resource* pResource) + { OGRE_LOCK_MUTEX(mResourcesMutex); - mResources.erase(pResource); - } - - //----------------------------------------------------------------------- - void D3D9ResourceManager::lockDeviceAccess() - { - assert(mDeviceAccessLockCount >= 0); - mDeviceAccessLockCount++; - if (mDeviceAccessLockCount == 1) - { - OGRE_LOCK_RECURSIVE_MUTEX(mResourcesMutex); - D3D9Resource::lockDeviceAccess(); - D3D9HardwarePixelBuffer::lockDeviceAccess(); - } - } - - //----------------------------------------------------------------------- - void D3D9ResourceManager::unlockDeviceAccess() - { - assert(mDeviceAccessLockCount > 0); - mDeviceAccessLockCount--; - if (mDeviceAccessLockCount == 0) - { - D3D9HardwarePixelBuffer::unlockDeviceAccess(); - D3D9Resource::unlockDeviceAccess(); - OGRE_UNLOCK_RECURSIVE_MUTEX(mResourcesMutex); - } - } + mResources.erase(pResource); + } + + //----------------------------------------------------------------------- + void D3D9ResourceManager::lockDeviceAccess() + { + assert(mDeviceAccessLockCount >= 0); + mDeviceAccessLockCount++; + if (mDeviceAccessLockCount == 1) + { + OGRE_LOCK_RECURSIVE_MUTEX(mResourcesMutex); + D3D9Resource::lockDeviceAccess(); + D3D9HardwarePixelBuffer::lockDeviceAccess(); + } + } + + //----------------------------------------------------------------------- + void D3D9ResourceManager::unlockDeviceAccess() + { + assert(mDeviceAccessLockCount > 0); + mDeviceAccessLockCount--; + if (mDeviceAccessLockCount == 0) + { + D3D9HardwarePixelBuffer::unlockDeviceAccess(); + D3D9Resource::unlockDeviceAccess(); + OGRE_UNLOCK_RECURSIVE_MUTEX(mResourcesMutex); + } + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9Texture.cpp b/RenderSystems/Direct3D9/src/OgreD3D9Texture.cpp index d9c5bfc9ab4..13df86cc402 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9Texture.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9Texture.cpp @@ -41,489 +41,489 @@ THE SOFTWARE. namespace Ogre { - /****************************************************************************************/ + /****************************************************************************************/ D3D9Texture::D3D9Texture(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) :Texture(creator, name, handle, group, isManual, loader), - mD3DPool(D3D9RenderSystem::isDirectX9Ex() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED), - mDynamicTextures(false), - mHwGammaReadSupported(false), - mHwGammaWriteSupported(false), - mFSAAType(D3DMULTISAMPLE_NONE), - mFSAAQuality(0) - { + mD3DPool(D3D9RenderSystem::isDirectX9Ex() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED), + mDynamicTextures(false), + mHwGammaReadSupported(false), + mHwGammaWriteSupported(false), + mFSAAType(D3DMULTISAMPLE_NONE), + mFSAAQuality(0) + { - } - /****************************************************************************************/ - D3D9Texture::~D3D9Texture() - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - + } + /****************************************************************************************/ + D3D9Texture::~D3D9Texture() + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + // have to call this here reather than in Resource destructor // since calling virtual methods in base destructors causes crash - if (isLoaded()) - { - unload(); - } - else - { - freeInternalResources(); - } - - // Free memory allocated per device. - DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin(); - while (it != mMapDeviceToTextureResources.end()) - { - TextureResources* textureResource = it->second; - - OGRE_DELETE_T(textureResource, TextureResources, MEMCATEGORY_RENDERSYS); - ++it; - } - mMapDeviceToTextureResources.clear(); - mSurfaceList.clear(); - } - /****************************************************************************************/ - void D3D9Texture::copyToTexture(TexturePtr& target) - { + if (isLoaded()) + { + unload(); + } + else + { + freeInternalResources(); + } + + // Free memory allocated per device. + DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin(); + while (it != mMapDeviceToTextureResources.end()) + { + TextureResources* textureResource = it->second; + + OGRE_DELETE_T(textureResource, TextureResources, MEMCATEGORY_RENDERSYS); + ++it; + } + mMapDeviceToTextureResources.clear(); + mSurfaceList.clear(); + } + /****************************************************************************************/ + void D3D9Texture::copyToTexture(TexturePtr& target) + { // check if this & target are the same format and type - // blitting from or to cube textures is not supported yet - if (target->getUsage() != getUsage() || - target->getTextureType() != getTextureType()) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "Src. and dest. textures must be of same type and must have the same usage !!!", - "D3D9Texture::copyToTexture" ); - } + // blitting from or to cube textures is not supported yet + if (target->getUsage() != getUsage() || + target->getTextureType() != getTextureType()) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "Src. and dest. textures must be of same type and must have the same usage !!!", + "D3D9Texture::copyToTexture" ); + } HRESULT hr; D3D9Texture *other; - // get the target - other = reinterpret_cast< D3D9Texture * >( target.get() ); - // target rectangle (whole surface) - RECT dstRC = {0, 0, static_cast(other->getWidth()), static_cast(other->getHeight())}; - - DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin(); - while (it != mMapDeviceToTextureResources.end()) - { - TextureResources* srcTextureResource = it->second; - TextureResources* dstTextureResource = other->getTextureResources(it->first); - - - // do it plain for normal texture - if (getTextureType() == TEX_TYPE_2D && - srcTextureResource->pNormTex && - dstTextureResource->pNormTex) - { - // get our source surface - IDirect3DSurface9 *pSrcSurface = 0; - if( FAILED( hr = srcTextureResource->pNormTex->GetSurfaceLevel(0, &pSrcSurface) ) ) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); - } - - // get our target surface - IDirect3DSurface9 *pDstSurface = 0; - if( FAILED( hr = dstTextureResource->pNormTex->GetSurfaceLevel(0, &pDstSurface) ) ) - { - String msg = DXGetErrorDescription(hr); - SAFE_RELEASE(pSrcSurface); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); - } - - // do the blit, it's called StretchRect in D3D9 :) - if( FAILED( hr = it->first->StretchRect( pSrcSurface, NULL, pDstSurface, &dstRC, D3DTEXF_NONE) ) ) - { - String msg = DXGetErrorDescription(hr); - SAFE_RELEASE(pSrcSurface); - SAFE_RELEASE(pDstSurface); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); - } - - // release temp. surfaces - SAFE_RELEASE(pSrcSurface); - SAFE_RELEASE(pDstSurface); - } - else if (getTextureType() == TEX_TYPE_CUBE_MAP && - srcTextureResource->pCubeTex && - dstTextureResource->pCubeTex) - { - // blit to 6 cube faces - for (size_t face = 0; face < 6; face++) - { - // get our source surface - IDirect3DSurface9 *pSrcSurface = 0; - if( FAILED( hr =srcTextureResource->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, 0, &pSrcSurface) ) ) - { - String msg = DXGetErrorDescription(hr); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); - } - - // get our target surface - IDirect3DSurface9 *pDstSurface = 0; - if( FAILED( hr = dstTextureResource->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, 0, &pDstSurface) ) ) - { - String msg = DXGetErrorDescription(hr); - SAFE_RELEASE(pSrcSurface); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); - } - - // do the blit, it's called StretchRect in D3D9 :) - if( FAILED( hr = it->first->StretchRect( pSrcSurface, NULL, pDstSurface, &dstRC, D3DTEXF_NONE) ) ) - { - String msg = DXGetErrorDescription(hr); - SAFE_RELEASE(pSrcSurface); - SAFE_RELEASE(pDstSurface); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); - } - - // release temp. surfaces - SAFE_RELEASE(pSrcSurface); - SAFE_RELEASE(pDstSurface); - } - } - else - { - OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, - "Copy to texture is implemented only for 2D and cube textures !!!", - "D3D9Texture::copyToTexture" ); - } - - ++it; - } - } - /****************************************************************************************/ - void D3D9Texture::loadImpl() - { - if (!mInternalResourcesCreated) - { - // NB: Need to initialise pool to some value other than D3DPOOL_DEFAULT, - // otherwise, if the texture loading failed, it might re-create as empty - // texture when device lost/restore. The actual pool will determine later. - // - // In directX9Ex this is not the case there is no managed pool and no device loss - mD3DPool = D3D9RenderSystem::isDirectX9Ex() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; - } - - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) - { - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); - - loadImpl(d3d9Device); - } - } - - /****************************************************************************************/ - void D3D9Texture::loadImpl(IDirect3DDevice9* d3d9Device) - { - if (mUsage & TU_RENDERTARGET) - { - createInternalResourcesImpl(d3d9Device); - return; - } - - // Make sure streams prepared. - if (mLoadedStreams.isNull()) - { - prepareImpl(); - } - - - // Set reading positions of loaded streams to the beginning. - for (uint i = 0; i < mLoadedStreams->size(); ++i) - { - MemoryDataStreamPtr curDataStream = (*mLoadedStreams)[i]; - - curDataStream->seek(0); - } - - // only copy is on the stack so well-behaved if exception thrown - LoadedStreams loadedStreams = mLoadedStreams; - - // load based on tex.type - switch (getTextureType()) - { - case TEX_TYPE_1D: - case TEX_TYPE_2D: - _loadNormTex(d3d9Device, loadedStreams); - break; - case TEX_TYPE_3D: - _loadVolumeTex(d3d9Device, loadedStreams); - break; - case TEX_TYPE_CUBE_MAP: - _loadCubeTex(d3d9Device, loadedStreams); - break; - default: - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::loadImpl" ); - } - } - /****************************************************************************************/ - void D3D9Texture::prepareImpl() - { - if (mUsage & TU_RENDERTARGET || isManuallyLoaded()) - { - return; - } - - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - + // get the target + other = reinterpret_cast< D3D9Texture * >( target.get() ); + // target rectangle (whole surface) + RECT dstRC = {0, 0, static_cast(other->getWidth()), static_cast(other->getHeight())}; + + DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin(); + while (it != mMapDeviceToTextureResources.end()) + { + TextureResources* srcTextureResource = it->second; + TextureResources* dstTextureResource = other->getTextureResources(it->first); + + + // do it plain for normal texture + if (getTextureType() == TEX_TYPE_2D && + srcTextureResource->pNormTex && + dstTextureResource->pNormTex) + { + // get our source surface + IDirect3DSurface9 *pSrcSurface = 0; + if( FAILED( hr = srcTextureResource->pNormTex->GetSurfaceLevel(0, &pSrcSurface) ) ) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); + } + + // get our target surface + IDirect3DSurface9 *pDstSurface = 0; + if( FAILED( hr = dstTextureResource->pNormTex->GetSurfaceLevel(0, &pDstSurface) ) ) + { + String msg = DXGetErrorDescription(hr); + SAFE_RELEASE(pSrcSurface); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); + } + + // do the blit, it's called StretchRect in D3D9 :) + if( FAILED( hr = it->first->StretchRect( pSrcSurface, NULL, pDstSurface, &dstRC, D3DTEXF_NONE) ) ) + { + String msg = DXGetErrorDescription(hr); + SAFE_RELEASE(pSrcSurface); + SAFE_RELEASE(pDstSurface); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); + } + + // release temp. surfaces + SAFE_RELEASE(pSrcSurface); + SAFE_RELEASE(pDstSurface); + } + else if (getTextureType() == TEX_TYPE_CUBE_MAP && + srcTextureResource->pCubeTex && + dstTextureResource->pCubeTex) + { + // blit to 6 cube faces + for (size_t face = 0; face < 6; face++) + { + // get our source surface + IDirect3DSurface9 *pSrcSurface = 0; + if( FAILED( hr =srcTextureResource->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, 0, &pSrcSurface) ) ) + { + String msg = DXGetErrorDescription(hr); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); + } + + // get our target surface + IDirect3DSurface9 *pDstSurface = 0; + if( FAILED( hr = dstTextureResource->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, 0, &pDstSurface) ) ) + { + String msg = DXGetErrorDescription(hr); + SAFE_RELEASE(pSrcSurface); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); + } + + // do the blit, it's called StretchRect in D3D9 :) + if( FAILED( hr = it->first->StretchRect( pSrcSurface, NULL, pDstSurface, &dstRC, D3DTEXF_NONE) ) ) + { + String msg = DXGetErrorDescription(hr); + SAFE_RELEASE(pSrcSurface); + SAFE_RELEASE(pDstSurface); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" ); + } + + // release temp. surfaces + SAFE_RELEASE(pSrcSurface); + SAFE_RELEASE(pDstSurface); + } + } + else + { + OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, + "Copy to texture is implemented only for 2D and cube textures !!!", + "D3D9Texture::copyToTexture" ); + } + + ++it; + } + } + /****************************************************************************************/ + void D3D9Texture::loadImpl() + { + if (!mInternalResourcesCreated) + { + // NB: Need to initialise pool to some value other than D3DPOOL_DEFAULT, + // otherwise, if the texture loading failed, it might re-create as empty + // texture when device lost/restore. The actual pool will determine later. + // + // In directX9Ex this is not the case there is no managed pool and no device loss + mD3DPool = D3D9RenderSystem::isDirectX9Ex() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; + } + + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) + { + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); + + loadImpl(d3d9Device); + } + } + + /****************************************************************************************/ + void D3D9Texture::loadImpl(IDirect3DDevice9* d3d9Device) + { + if (mUsage & TU_RENDERTARGET) + { + createInternalResourcesImpl(d3d9Device); + return; + } + + // Make sure streams prepared. + if (mLoadedStreams.isNull()) + { + prepareImpl(); + } + + + // Set reading positions of loaded streams to the beginning. + for (uint i = 0; i < mLoadedStreams->size(); ++i) + { + MemoryDataStreamPtr curDataStream = (*mLoadedStreams)[i]; + + curDataStream->seek(0); + } + + // only copy is on the stack so well-behaved if exception thrown + LoadedStreams loadedStreams = mLoadedStreams; + + // load based on tex.type + switch (getTextureType()) + { + case TEX_TYPE_1D: + case TEX_TYPE_2D: + _loadNormTex(d3d9Device, loadedStreams); + break; + case TEX_TYPE_3D: + _loadVolumeTex(d3d9Device, loadedStreams); + break; + case TEX_TYPE_CUBE_MAP: + _loadCubeTex(d3d9Device, loadedStreams); + break; + default: + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::loadImpl" ); + } + } + /****************************************************************************************/ + void D3D9Texture::prepareImpl() + { + if (mUsage & TU_RENDERTARGET || isManuallyLoaded()) + { + return; + } + + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + LoadedStreams loadedStreams; - // prepare load based on tex.type - switch (getTextureType()) - { - case TEX_TYPE_1D: - case TEX_TYPE_2D: - loadedStreams = _prepareNormTex(); - break; - case TEX_TYPE_3D: - loadedStreams = _prepareVolumeTex(); - break; - case TEX_TYPE_CUBE_MAP: - loadedStreams = _prepareCubeTex(); - break; - default: - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::prepareImpl" ); - } - - mLoadedStreams = loadedStreams; - } + // prepare load based on tex.type + switch (getTextureType()) + { + case TEX_TYPE_1D: + case TEX_TYPE_2D: + loadedStreams = _prepareNormTex(); + break; + case TEX_TYPE_3D: + loadedStreams = _prepareVolumeTex(); + break; + case TEX_TYPE_CUBE_MAP: + loadedStreams = _prepareCubeTex(); + break; + default: + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::prepareImpl" ); + } + + mLoadedStreams = loadedStreams; + } /****************************************************************************************/ - D3D9Texture::LoadedStreams D3D9Texture::_prepareCubeTex() - { - assert(getTextureType() == TEX_TYPE_CUBE_MAP); + D3D9Texture::LoadedStreams D3D9Texture::_prepareCubeTex() + { + assert(getTextureType() == TEX_TYPE_CUBE_MAP); LoadedStreams loadedStreams = LoadedStreams(OGRE_NEW_T (vector::type, MEMCATEGORY_GENERAL), SPFM_DELETE_T ); // DDS load? - if (getSourceFileType() == "dds") - { + if (getSourceFileType() == "dds") + { // find & load resource data - DataStreamPtr dstream = - ResourceGroupManager::getSingleton().openResource( - mName, mGroup, true, this); + DataStreamPtr dstream = + ResourceGroupManager::getSingleton().openResource( + mName, mGroup, true, this); loadedStreams->push_back(MemoryDataStreamPtr(OGRE_NEW MemoryDataStream(dstream))); } else { - // Load from 6 separate files - // Use OGRE its own codecs - String baseName, ext; - size_t pos = mName.find_last_of("."); - baseName = mName.substr(0, pos); - if ( pos != String::npos ) - ext = mName.substr(pos+1); - static const String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"}; - - for(size_t i = 0; i < 6; i++) - { - String fullName = baseName + suffixes[i]; - if (!ext.empty()) - fullName = fullName + "." + ext; - - // find & load resource data intro stream to allow resource - // group changes if required - DataStreamPtr dstream = - ResourceGroupManager::getSingleton().openResource( - fullName, mGroup, true, this); + // Load from 6 separate files + // Use OGRE its own codecs + String baseName, ext; + size_t pos = mName.find_last_of("."); + baseName = mName.substr(0, pos); + if ( pos != String::npos ) + ext = mName.substr(pos+1); + static const String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"}; + + for(size_t i = 0; i < 6; i++) + { + String fullName = baseName + suffixes[i]; + if (!ext.empty()) + fullName = fullName + "." + ext; + + // find & load resource data intro stream to allow resource + // group changes if required + DataStreamPtr dstream = + ResourceGroupManager::getSingleton().openResource( + fullName, mGroup, true, this); loadedStreams->push_back(MemoryDataStreamPtr(OGRE_NEW MemoryDataStream(dstream))); - } + } } return loadedStreams; - } - /****************************************************************************************/ - D3D9Texture::LoadedStreams D3D9Texture::_prepareVolumeTex() - { - assert(getTextureType() == TEX_TYPE_3D); + } + /****************************************************************************************/ + D3D9Texture::LoadedStreams D3D9Texture::_prepareVolumeTex() + { + assert(getTextureType() == TEX_TYPE_3D); - // find & load resource data - DataStreamPtr dstream = - ResourceGroupManager::getSingleton().openResource( - mName, mGroup, true, this); + // find & load resource data + DataStreamPtr dstream = + ResourceGroupManager::getSingleton().openResource( + mName, mGroup, true, this); LoadedStreams loadedStreams = LoadedStreams(OGRE_NEW_T (vector::type, MEMCATEGORY_GENERAL), SPFM_DELETE_T); loadedStreams->push_back(MemoryDataStreamPtr(OGRE_NEW MemoryDataStream(dstream))); return loadedStreams; } - /****************************************************************************************/ - D3D9Texture::LoadedStreams D3D9Texture::_prepareNormTex() - { - assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D); + /****************************************************************************************/ + D3D9Texture::LoadedStreams D3D9Texture::_prepareNormTex() + { + assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D); - // find & load resource data - DataStreamPtr dstream = - ResourceGroupManager::getSingleton().openResource( - mName, mGroup, true, this); + // find & load resource data + DataStreamPtr dstream = + ResourceGroupManager::getSingleton().openResource( + mName, mGroup, true, this); LoadedStreams loadedStreams = LoadedStreams(OGRE_NEW_T (vector::type, MEMCATEGORY_GENERAL), SPFM_DELETE_T); loadedStreams->push_back(MemoryDataStreamPtr(OGRE_NEW MemoryDataStream(dstream))); return loadedStreams; - } - /****************************************************************************************/ - void D3D9Texture::unprepareImpl() - { - if (mUsage & TU_RENDERTARGET || isManuallyLoaded()) - { - return; - } - } - - /****************************************************************************************/ - void D3D9Texture::postLoadImpl(void) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - mLoadedStreams.setNull(); - } - - /****************************************************************************************/ - void D3D9Texture::freeInternalResources(void) - { - freeInternalResourcesImpl(); - } - - /****************************************************************************************/ - void D3D9Texture::freeInternalResourcesImpl() - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin(); - - while (it != mMapDeviceToTextureResources.end()) - { - TextureResources* textureResource = it->second; - - freeTextureResources(it->first, textureResource); - ++it; - } - } - - /****************************************************************************************/ - D3D9Texture::TextureResources* D3D9Texture::getTextureResources(IDirect3DDevice9* d3d9Device) - { - DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.find(d3d9Device); - - if (it == mMapDeviceToTextureResources.end()) - return NULL; - - return it->second; - } - - /****************************************************************************************/ - D3D9Texture::TextureResources* D3D9Texture::allocateTextureResources(IDirect3DDevice9* d3d9Device) - { - assert(mMapDeviceToTextureResources.find(d3d9Device) == mMapDeviceToTextureResources.end()); - - TextureResources* textureResources = OGRE_NEW_T(TextureResources, MEMCATEGORY_RENDERSYS); - - textureResources->pNormTex = NULL; - textureResources->pCubeTex = NULL; - textureResources->pVolumeTex = NULL; - textureResources->pBaseTex = NULL; - textureResources->pFSAASurface = NULL; - - mMapDeviceToTextureResources[d3d9Device] = textureResources; - - return textureResources; - } - - /****************************************************************************************/ - void D3D9Texture::createTextureResources(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if (mIsManual) - { - preLoadImpl(); - - // create the internal resources. - createInternalResourcesImpl(d3d9Device); - - // Load from manual loader - if (mLoader != NULL) - { - mLoader->loadResource(this); - } - postLoadImpl(); - } - else - { - prepareImpl(); - - preLoadImpl(); - - loadImpl(d3d9Device); - - postLoadImpl(); - } - } - - /****************************************************************************************/ - void D3D9Texture::freeTextureResources(IDirect3DDevice9* d3d9Device, D3D9Texture::TextureResources* textureResources) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - // Release surfaces from each mip level. - for(unsigned int i = 0; i < mSurfaceList.size(); ++i) - { - D3D9HardwarePixelBuffer* pixelBuffer = static_cast(mSurfaceList[i].get()); - - pixelBuffer->releaseSurfaces(d3d9Device); - } - - // Release the rest of the resources. - SAFE_RELEASE(textureResources->pBaseTex); - SAFE_RELEASE(textureResources->pNormTex); - SAFE_RELEASE(textureResources->pCubeTex); - SAFE_RELEASE(textureResources->pVolumeTex); - SAFE_RELEASE(textureResources->pFSAASurface); - } - - /****************************************************************************************/ - void D3D9Texture::_loadCubeTex(IDirect3DDevice9* d3d9Device, const D3D9Texture::LoadedStreams &loadedStreams) - { - assert(getTextureType() == TEX_TYPE_CUBE_MAP); + } + /****************************************************************************************/ + void D3D9Texture::unprepareImpl() + { + if (mUsage & TU_RENDERTARGET || isManuallyLoaded()) + { + return; + } + } + + /****************************************************************************************/ + void D3D9Texture::postLoadImpl(void) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + mLoadedStreams.setNull(); + } + + /****************************************************************************************/ + void D3D9Texture::freeInternalResources(void) + { + freeInternalResourcesImpl(); + } + + /****************************************************************************************/ + void D3D9Texture::freeInternalResourcesImpl() + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.begin(); + + while (it != mMapDeviceToTextureResources.end()) + { + TextureResources* textureResource = it->second; + + freeTextureResources(it->first, textureResource); + ++it; + } + } + + /****************************************************************************************/ + D3D9Texture::TextureResources* D3D9Texture::getTextureResources(IDirect3DDevice9* d3d9Device) + { + DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.find(d3d9Device); + + if (it == mMapDeviceToTextureResources.end()) + return NULL; + + return it->second; + } + + /****************************************************************************************/ + D3D9Texture::TextureResources* D3D9Texture::allocateTextureResources(IDirect3DDevice9* d3d9Device) + { + assert(mMapDeviceToTextureResources.find(d3d9Device) == mMapDeviceToTextureResources.end()); + + TextureResources* textureResources = OGRE_NEW_T(TextureResources, MEMCATEGORY_RENDERSYS); + + textureResources->pNormTex = NULL; + textureResources->pCubeTex = NULL; + textureResources->pVolumeTex = NULL; + textureResources->pBaseTex = NULL; + textureResources->pFSAASurface = NULL; + + mMapDeviceToTextureResources[d3d9Device] = textureResources; + + return textureResources; + } + + /****************************************************************************************/ + void D3D9Texture::createTextureResources(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if (mIsManual) + { + preLoadImpl(); + + // create the internal resources. + createInternalResourcesImpl(d3d9Device); + + // Load from manual loader + if (mLoader != NULL) + { + mLoader->loadResource(this); + } + postLoadImpl(); + } + else + { + prepareImpl(); + + preLoadImpl(); + + loadImpl(d3d9Device); + + postLoadImpl(); + } + } + + /****************************************************************************************/ + void D3D9Texture::freeTextureResources(IDirect3DDevice9* d3d9Device, D3D9Texture::TextureResources* textureResources) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + // Release surfaces from each mip level. + for(unsigned int i = 0; i < mSurfaceList.size(); ++i) + { + D3D9HardwarePixelBuffer* pixelBuffer = static_cast(mSurfaceList[i].get()); + + pixelBuffer->releaseSurfaces(d3d9Device); + } + + // Release the rest of the resources. + SAFE_RELEASE(textureResources->pBaseTex); + SAFE_RELEASE(textureResources->pNormTex); + SAFE_RELEASE(textureResources->pCubeTex); + SAFE_RELEASE(textureResources->pVolumeTex); + SAFE_RELEASE(textureResources->pFSAASurface); + } + + /****************************************************************************************/ + void D3D9Texture::_loadCubeTex(IDirect3DDevice9* d3d9Device, const D3D9Texture::LoadedStreams &loadedStreams) + { + assert(getTextureType() == TEX_TYPE_CUBE_MAP); // DDS load? - if (getSourceFileType() == "dds") - { + if (getSourceFileType() == "dds") + { // find & load resource data assert(loadedStreams->size()==1); - DWORD usage = 0; - UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? - D3DX_DEFAULT : mNumRequestedMipmaps + 1; - - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); - - // check if mip map volume textures are supported - if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP)) - { - // no mip map support for this kind of textures :( - mNumMipmaps = 0; - numMips = 1; - } - - // Check dynamic textures - if (mUsage & TU_DYNAMIC) - { - D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); - if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF)) - { - usage |= D3DUSAGE_DYNAMIC; - mDynamicTextures = true; - } - else - { - mDynamicTextures = false; - } - } - - // Determine D3D pool to use + DWORD usage = 0; + UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? + D3DX_DEFAULT : mNumRequestedMipmaps + 1; + + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); + + // check if mip map volume textures are supported + if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP)) + { + // no mip map support for this kind of textures :( + mNumMipmaps = 0; + numMips = 1; + } + + // Check dynamic textures + if (mUsage & TU_DYNAMIC) + { + D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); + if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF)) + { + usage |= D3DUSAGE_DYNAMIC; + mDynamicTextures = true; + } + else + { + mDynamicTextures = false; + } + } + + // Determine D3D pool to use D3DPOOL pool; if (useDefaultPool()) { @@ -533,49 +533,49 @@ namespace Ogre { pool = D3DPOOL_MANAGED; } - - TextureResources* textureResources; - - // Get or create new texture resources structure. - textureResources = getTextureResources(d3d9Device); - if (textureResources != NULL) - freeTextureResources(d3d9Device, textureResources); - else - textureResources = allocateTextureResources(d3d9Device); - - HRESULT hr; - - hr = D3DXCreateCubeTextureFromFileInMemoryEx( - d3d9Device, - (*loadedStreams)[0]->getPtr(), - static_cast((*loadedStreams)[0]->size()), - D3DX_DEFAULT, // dims (square) - numMips, - usage, - D3DFMT_UNKNOWN, - pool, - D3DX_DEFAULT, - D3DX_DEFAULT, - 0, // colour key - NULL, // src box - NULL, // palette - &textureResources->pCubeTex); + + TextureResources* textureResources; + + // Get or create new texture resources structure. + textureResources = getTextureResources(d3d9Device); + if (textureResources != NULL) + freeTextureResources(d3d9Device, textureResources); + else + textureResources = allocateTextureResources(d3d9Device); + + HRESULT hr; + + hr = D3DXCreateCubeTextureFromFileInMemoryEx( + d3d9Device, + (*loadedStreams)[0]->getPtr(), + static_cast((*loadedStreams)[0]->size()), + D3DX_DEFAULT, // dims (square) + numMips, + usage, + D3DFMT_UNKNOWN, + pool, + D3DX_DEFAULT, + D3DX_DEFAULT, + 0, // colour key + NULL, // src box + NULL, // palette + &textureResources->pCubeTex); if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't create cube texture: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_loadCubeTex" ); - } + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't create cube texture: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_loadCubeTex" ); + } hr = textureResources->pCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_loadCubeTex" ); - } + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_loadCubeTex" ); + } D3DSURFACE_DESC texDesc; textureResources->pCubeTex->GetLevelDesc(0, &texDesc); @@ -583,81 +583,81 @@ namespace Ogre // set src and dest attributes to the same, we can't know _setSrcAttributes(texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format)); _setFinalAttributes(d3d9Device, textureResources, - texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format)); + texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format)); - if( mHwGamma ) - { - mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage, - D3DRTYPE_CUBETEXTURE, - texDesc.Format, false); - } + if( mHwGamma ) + { + mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage, + D3DRTYPE_CUBETEXTURE, + texDesc.Format, false); + } - mInternalResourcesCreated = true; + mInternalResourcesCreated = true; } else { assert(loadedStreams->size()==6); - String ext; - size_t pos = mName.find_last_of("."); - if ( pos != String::npos ) - ext = mName.substr(pos+1); + String ext; + size_t pos = mName.find_last_of("."); + if ( pos != String::npos ) + ext = mName.substr(pos+1); - vector::type images(6); - ConstImagePtrList imagePtrs; + vector::type images(6); + ConstImagePtrList imagePtrs; - for(size_t i = 0; i < 6; i++) - { - DataStreamPtr stream((*loadedStreams)[i]); - images[i].load(stream, ext); + for(size_t i = 0; i < 6; i++) + { + DataStreamPtr stream((*loadedStreams)[i]); + images[i].load(stream, ext); - imagePtrs.push_back(&images[i]); - } + imagePtrs.push_back(&images[i]); + } _loadImages( imagePtrs ); } - } - /****************************************************************************************/ - void D3D9Texture::_loadVolumeTex(IDirect3DDevice9* d3d9Device, const D3D9Texture::LoadedStreams &loadedStreams) - { - assert(getTextureType() == TEX_TYPE_3D); - // DDS load? - if (getSourceFileType() == "dds") - { - // find & load resource data + } + /****************************************************************************************/ + void D3D9Texture::_loadVolumeTex(IDirect3DDevice9* d3d9Device, const D3D9Texture::LoadedStreams &loadedStreams) + { + assert(getTextureType() == TEX_TYPE_3D); + // DDS load? + if (getSourceFileType() == "dds") + { + // find & load resource data assert(loadedStreams->size()==1); - - DWORD usage = 0; - UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? - D3DX_DEFAULT : mNumRequestedMipmaps + 1; - - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); - - // check if mip map volume textures are supported - if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP)) - { - // no mip map support for this kind of textures :( - mNumMipmaps = 0; - numMips = 1; - } - - // Check dynamic textures - if (mUsage & TU_DYNAMIC) - { - D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); - if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF)) - { - usage |= D3DUSAGE_DYNAMIC; - mDynamicTextures = true; - } - else - { - mDynamicTextures = false; - } - } - - // Determine D3D pool to use + + DWORD usage = 0; + UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? + D3DX_DEFAULT : mNumRequestedMipmaps + 1; + + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); + + // check if mip map volume textures are supported + if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP)) + { + // no mip map support for this kind of textures :( + mNumMipmaps = 0; + numMips = 1; + } + + // Check dynamic textures + if (mUsage & TU_DYNAMIC) + { + D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); + if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF)) + { + usage |= D3DUSAGE_DYNAMIC; + mDynamicTextures = true; + } + else + { + mDynamicTextures = false; + } + } + + // Determine D3D pool to use D3DPOOL pool; if (useDefaultPool()) { @@ -667,154 +667,154 @@ namespace Ogre { pool = D3DPOOL_MANAGED; } - - TextureResources* textureResources; - - // Get or create new texture resources structure. - textureResources = getTextureResources(d3d9Device); - if (textureResources != NULL) - freeTextureResources(d3d9Device, textureResources); - else - textureResources = allocateTextureResources(d3d9Device); - - HRESULT hr; - - hr = D3DXCreateVolumeTextureFromFileInMemoryEx( - d3d9Device, - (*loadedStreams)[0]->getPtr(), - static_cast((*loadedStreams)[0]->size()), - D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, // dims - numMips, - usage, - D3DFMT_UNKNOWN, - pool, - D3DX_DEFAULT, - D3DX_DEFAULT, - 0, // colour key - NULL, // src box - NULL, // palette - &textureResources->pVolumeTex); - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Unable to load volume texture from " + getName() + ": " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_loadVolumeTex"); - } - - hr = textureResources->pVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); - - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_loadVolumeTex" ); - } - - D3DVOLUME_DESC texDesc; - hr = textureResources->pVolumeTex->GetLevelDesc(0, &texDesc); + + TextureResources* textureResources; + + // Get or create new texture resources structure. + textureResources = getTextureResources(d3d9Device); + if (textureResources != NULL) + freeTextureResources(d3d9Device, textureResources); + else + textureResources = allocateTextureResources(d3d9Device); + + HRESULT hr; + + hr = D3DXCreateVolumeTextureFromFileInMemoryEx( + d3d9Device, + (*loadedStreams)[0]->getPtr(), + static_cast((*loadedStreams)[0]->size()), + D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, // dims + numMips, + usage, + D3DFMT_UNKNOWN, + pool, + D3DX_DEFAULT, + D3DX_DEFAULT, + 0, // colour key + NULL, // src box + NULL, // palette + &textureResources->pVolumeTex); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Unable to load volume texture from " + getName() + ": " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_loadVolumeTex"); + } + + hr = textureResources->pVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); + + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_loadVolumeTex" ); + } + + D3DVOLUME_DESC texDesc; + hr = textureResources->pVolumeTex->GetLevelDesc(0, &texDesc); mD3DPool = texDesc.Pool; - // set src and dest attributes to the same, we can't know - _setSrcAttributes(texDesc.Width, texDesc.Height, texDesc.Depth, D3D9Mappings::_getPF(texDesc.Format)); - _setFinalAttributes(d3d9Device, textureResources, - texDesc.Width, texDesc.Height, texDesc.Depth, D3D9Mappings::_getPF(texDesc.Format)); + // set src and dest attributes to the same, we can't know + _setSrcAttributes(texDesc.Width, texDesc.Height, texDesc.Depth, D3D9Mappings::_getPF(texDesc.Format)); + _setFinalAttributes(d3d9Device, textureResources, + texDesc.Width, texDesc.Height, texDesc.Depth, D3D9Mappings::_getPF(texDesc.Format)); - if( mHwGamma ) - { - mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage, - D3DRTYPE_VOLUMETEXTURE, - texDesc.Format, false); - } + if( mHwGamma ) + { + mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage, + D3DRTYPE_VOLUMETEXTURE, + texDesc.Format, false); + } - mInternalResourcesCreated = true; + mInternalResourcesCreated = true; } - else - { - Image img; + else + { + Image img; assert(loadedStreams->size()==1); - size_t pos = mName.find_last_of("."); - String ext; - if ( pos != String::npos ) - ext = mName.substr(pos+1); - - DataStreamPtr stream((*loadedStreams)[0]); - img.load(stream, ext); - - if (img.getHeight() == 0) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Image height == 0 in " + getName(), - "D3D9Texture::_loadVolumeTex"); - } - - if (img.getWidth() == 0) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Image width == 0 in " + getName(), - "D3D9Texture::_loadVolumeTex"); - } - - if (img.getDepth() == 0) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Image depth == 0 in " + getName(), - "D3D9Texture::_loadVolumeTex"); - } - // Call internal _loadImages, not loadImage since that's external and - // will determine load status etc again - ConstImagePtrList imagePtrs; - imagePtrs.push_back(&img); - _loadImages( imagePtrs ); - } + size_t pos = mName.find_last_of("."); + String ext; + if ( pos != String::npos ) + ext = mName.substr(pos+1); + + DataStreamPtr stream((*loadedStreams)[0]); + img.load(stream, ext); + + if (img.getHeight() == 0) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Image height == 0 in " + getName(), + "D3D9Texture::_loadVolumeTex"); + } + + if (img.getWidth() == 0) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Image width == 0 in " + getName(), + "D3D9Texture::_loadVolumeTex"); + } + + if (img.getDepth() == 0) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Image depth == 0 in " + getName(), + "D3D9Texture::_loadVolumeTex"); + } + // Call internal _loadImages, not loadImage since that's external and + // will determine load status etc again + ConstImagePtrList imagePtrs; + imagePtrs.push_back(&img); + _loadImages( imagePtrs ); + } } - /****************************************************************************************/ - void D3D9Texture::_loadNormTex(IDirect3DDevice9* d3d9Device, const D3D9Texture::LoadedStreams &loadedStreams) - { - assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D); - // DDS load? - if (getSourceFileType() == "dds") - { - // Use D3DX + /****************************************************************************************/ + void D3D9Texture::_loadNormTex(IDirect3DDevice9* d3d9Device, const D3D9Texture::LoadedStreams &loadedStreams) + { + assert(getTextureType() == TEX_TYPE_1D || getTextureType() == TEX_TYPE_2D); + // DDS load? + if (getSourceFileType() == "dds") + { + // Use D3DX assert(loadedStreams->size()==1); - - DWORD usage = 0; - UINT numMips; - - if (mNumRequestedMipmaps == MIP_UNLIMITED) - numMips = D3DX_DEFAULT; - else if (mNumRequestedMipmaps == 0) - numMips = D3DX_FROM_FILE; - else - numMips = static_cast(mNumRequestedMipmaps + 1); - - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); - - - // check if mip map volume textures are supported - if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)) - { - // no mip map support for this kind of textures :( - mNumMipmaps = 0; - numMips = 1; - } - - // Check dynamic textures - if (mUsage & TU_DYNAMIC) - { - D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); - if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF)) - { - usage |= D3DUSAGE_DYNAMIC; - mDynamicTextures = true; - } - else - { - mDynamicTextures = false; - } - } + + DWORD usage = 0; + UINT numMips; + + if (mNumRequestedMipmaps == MIP_UNLIMITED) + numMips = D3DX_DEFAULT; + else if (mNumRequestedMipmaps == 0) + numMips = D3DX_FROM_FILE; + else + numMips = static_cast(mNumRequestedMipmaps + 1); + + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); + + + // check if mip map volume textures are supported + if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)) + { + // no mip map support for this kind of textures :( + mNumMipmaps = 0; + numMips = 1; + } + + // Check dynamic textures + if (mUsage & TU_DYNAMIC) + { + D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); + if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF)) + { + usage |= D3DUSAGE_DYNAMIC; + mDynamicTextures = true; + } + else + { + mDynamicTextures = false; + } + } // Determine D3D pool to use D3DPOOL pool; @@ -826,1289 +826,1289 @@ namespace Ogre { pool = D3DPOOL_MANAGED; } - - TextureResources* textureResources; - - // Get or create new texture resources structure. - textureResources = getTextureResources(d3d9Device); - if (textureResources != NULL) - freeTextureResources(d3d9Device, textureResources); - else - textureResources = allocateTextureResources(d3d9Device); - - HRESULT hr; - - UINT autoWidthHeight = Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_NON_POWER_OF_2_TEXTURES) ? - D3DX_DEFAULT_NONPOW2 : D3DX_DEFAULT; - - hr = D3DXCreateTextureFromFileInMemoryEx( - d3d9Device, - (*loadedStreams)[0]->getPtr(), - static_cast((*loadedStreams)[0]->size()), - autoWidthHeight, autoWidthHeight, // dims - numMips, - usage, - D3DFMT_UNKNOWN, - pool, - D3DX_DEFAULT, - D3DX_DEFAULT, - 0, // colour key - NULL, // src box - NULL, // palette - &textureResources->pNormTex); - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Unable to load texture from " + getName() + " :" + String(DXGetErrorDescription(hr)), - "D3D9Texture::_loadNormTex"); - } - - hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); - - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_loadNormTex" ); - } - - D3DSURFACE_DESC texDesc; - textureResources->pNormTex->GetLevelDesc(0, &texDesc); + + TextureResources* textureResources; + + // Get or create new texture resources structure. + textureResources = getTextureResources(d3d9Device); + if (textureResources != NULL) + freeTextureResources(d3d9Device, textureResources); + else + textureResources = allocateTextureResources(d3d9Device); + + HRESULT hr; + + UINT autoWidthHeight = Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_NON_POWER_OF_2_TEXTURES) ? + D3DX_DEFAULT_NONPOW2 : D3DX_DEFAULT; + + hr = D3DXCreateTextureFromFileInMemoryEx( + d3d9Device, + (*loadedStreams)[0]->getPtr(), + static_cast((*loadedStreams)[0]->size()), + autoWidthHeight, autoWidthHeight, // dims + numMips, + usage, + D3DFMT_UNKNOWN, + pool, + D3DX_DEFAULT, + D3DX_DEFAULT, + 0, // colour key + NULL, // src box + NULL, // palette + &textureResources->pNormTex); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Unable to load texture from " + getName() + " :" + String(DXGetErrorDescription(hr)), + "D3D9Texture::_loadNormTex"); + } + + hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); + + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_loadNormTex" ); + } + + D3DSURFACE_DESC texDesc; + textureResources->pNormTex->GetLevelDesc(0, &texDesc); mD3DPool = texDesc.Pool; - // set src and dest attributes to the same, we can't know - _setSrcAttributes(texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format)); - _setFinalAttributes(d3d9Device, textureResources, - texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format)); - - if( mHwGamma ) - { - mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage, - D3DRTYPE_TEXTURE, - texDesc.Format, false); - } - mInternalResourcesCreated = true; - } - else - { - Image img; - // find & load resource data intro stream to allow resource - // group changes if required - assert(loadedStreams->size()==1); - - size_t pos = mName.find_last_of("."); - String ext; - if ( pos != String::npos ) - ext = mName.substr(pos+1); - - DataStreamPtr stream((*loadedStreams)[0]); - img.load(stream, ext); - - if (img.getHeight() == 0) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Image height == 0 in " + getName(), - "D3D9Texture::_loadNormTex"); - } - - if (img.getWidth() == 0) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Image width == 0 in " + getName(), - "D3D9Texture::_loadNormTex"); - } - - // Call internal _loadImages, not loadImage since that's external and - // will determine load status etc again - ConstImagePtrList imagePtrs; - imagePtrs.push_back(&img); - _loadImages( imagePtrs ); - } - - } - - /****************************************************************************************/ - size_t D3D9Texture::calculateSize(void) const - { - size_t instanceSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); - - return instanceSize * mMapDeviceToTextureResources.size(); - } - - /****************************************************************************************/ - void D3D9Texture::createInternalResources(void) - { - createInternalResourcesImpl(); - } - - /****************************************************************************************/ - void D3D9Texture::determinePool() - { - if (useDefaultPool()) - { - mD3DPool = D3DPOOL_DEFAULT; - } - else - { - mD3DPool = D3DPOOL_MANAGED; - } - - } - /****************************************************************************************/ - void D3D9Texture::createInternalResourcesImpl(void) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) - { - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); - - createInternalResourcesImpl(d3d9Device); - } - } - - /****************************************************************************************/ - void D3D9Texture::createInternalResourcesImpl(IDirect3DDevice9* d3d9Device) - { - TextureResources* textureResources; - - // Check if resources already exist. - textureResources = getTextureResources(d3d9Device); - if (textureResources != NULL && textureResources->pBaseTex != NULL) - return; - - - // If mSrcWidth and mSrcHeight are zero, the requested extents have probably been set - // through setWidth and setHeight, which set mWidth and mHeight. Take those values. - if(mSrcWidth == 0 || mSrcHeight == 0) { - mSrcWidth = mWidth; - mSrcHeight = mHeight; - } - - // load based on tex.type - switch (getTextureType()) - { - case TEX_TYPE_1D: - case TEX_TYPE_2D: - _createNormTex(d3d9Device); - break; - case TEX_TYPE_CUBE_MAP: - _createCubeTex(d3d9Device); - break; - case TEX_TYPE_3D: - _createVolumeTex(d3d9Device); - break; - default: - freeInternalResources(); - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::createInternalResources" ); - } - } - - /****************************************************************************************/ - void D3D9Texture::_createNormTex(IDirect3DDevice9* d3d9Device) - { - // we must have those defined here - assert(mSrcWidth > 0 || mSrcHeight > 0); - - // determine which D3D9 pixel format we'll use - HRESULT hr; - D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); - - // let's D3DX check the corrected pixel format - hr = D3DXCheckTextureRequirements(d3d9Device, NULL, NULL, NULL, 0, &d3dPF, mD3DPool); - - // Use D3DX to help us create the texture, this way it can adjust any relevant sizes - DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0; - UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? - D3DX_DEFAULT : mNumRequestedMipmaps + 1; - // Check dynamic textures - if (mUsage & TU_DYNAMIC) - { - if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF)) - { - usage |= D3DUSAGE_DYNAMIC; - mDynamicTextures = true; - } - else - { - mDynamicTextures = false; - } - } - // Check sRGB support - if (mHwGamma) - { - mHwGammaReadSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF, false); - if (mUsage & TU_RENDERTARGET) - mHwGammaWriteSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF, true); - } - // Check FSAA level - if (mUsage & TU_RENDERTARGET) - { - D3D9RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); - rsys->determineFSAASettings(d3d9Device, mFSAA, mFSAAHint, d3dPF, false, - &mFSAAType, &mFSAAQuality); - } - else - { - mFSAAType = D3DMULTISAMPLE_NONE; - mFSAAQuality = 0; - } - - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); - - - // check if mip maps are supported on hardware - mMipmapsHardwareGenerated = false; - if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) - { - if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0) - { - // use auto.gen. if available, and if desired - mMipmapsHardwareGenerated = _canAutoGenMipmaps(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF); - if (mMipmapsHardwareGenerated) - { - usage |= D3DUSAGE_AUTOGENMIPMAP; - numMips = 0; - } - } - } - else - { - // no mip map support for this kind of textures :( - mNumMipmaps = 0; - numMips = 1; - } - - // derive the pool to use - determinePool(); - - TextureResources* textureResources; - - // Get or create new texture resources structure. - textureResources = getTextureResources(d3d9Device); - if (textureResources != NULL) - freeTextureResources(d3d9Device, textureResources); - else - textureResources = allocateTextureResources(d3d9Device); - - - // create the texture - hr = D3DXCreateTexture( - d3d9Device, // device - static_cast(mSrcWidth), // width - static_cast(mSrcHeight), // height - numMips, // number of mip map levels - usage, // usage - d3dPF, // pixel format - mD3DPool, - &textureResources->pNormTex); // data pointer - // check result and except if failed - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createNormTex" ); - } - - // set the base texture we'll use in the render system - hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createNormTex" ); - } - - // set final tex. attributes from tex. description - // they may differ from the source image !!! - D3DSURFACE_DESC desc; - hr = textureResources->pNormTex->GetLevelDesc(0, &desc); - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createNormTex" ); - } - - if (mFSAAType) - { - // create AA surface - HRESULT hr = d3d9Device->CreateRenderTarget(desc.Width, desc.Height, d3dPF, - mFSAAType, - mFSAAQuality, - FALSE, // not lockable - &textureResources->pFSAASurface, NULL); - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create AA render target: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createNormTex"); - } - - } - - _setFinalAttributes(d3d9Device, textureResources, - desc.Width, desc.Height, 1, D3D9Mappings::_getPF(desc.Format)); - - // Set best filter type - if(mMipmapsHardwareGenerated) - { - hr = textureResources->pBaseTex->SetAutoGenFilterType(_getBestFilterMethod(d3d9Device)); - if(FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createNormTex" ); - } - } - - } - /****************************************************************************************/ - void D3D9Texture::_createCubeTex(IDirect3DDevice9* d3d9Device) - { - // we must have those defined here - assert(mSrcWidth > 0 || mSrcHeight > 0); - - // determine which D3D9 pixel format we'll use - HRESULT hr; - D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); - - // let's D3DX check the corrected pixel format - hr = D3DXCheckCubeTextureRequirements(d3d9Device, NULL, NULL, 0, &d3dPF, mD3DPool); - - // Use D3DX to help us create the texture, this way it can adjust any relevant sizes - DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0; - UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? - D3DX_DEFAULT : mNumRequestedMipmaps + 1; - // Check dynamic textures - if (mUsage & TU_DYNAMIC) - { - if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF)) - { - usage |= D3DUSAGE_DYNAMIC; - mDynamicTextures = true; - } - else - { - mDynamicTextures = false; - } - } - // Check sRGB support - if (mHwGamma) - { - mHwGammaReadSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF, false); - if (mUsage & TU_RENDERTARGET) - mHwGammaWriteSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF, true); - } - // Check FSAA level - if (mUsage & TU_RENDERTARGET) - { - D3D9RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); - rsys->determineFSAASettings(d3d9Device, mFSAA, mFSAAHint, d3dPF, false, - &mFSAAType, &mFSAAQuality); - } - else - { - mFSAAType = D3DMULTISAMPLE_NONE; - mFSAAQuality = 0; - } - - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); - - // check if mip map cube textures are supported - mMipmapsHardwareGenerated = false; - if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP) - { - if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0) - { - // use auto.gen. if available - mMipmapsHardwareGenerated = _canAutoGenMipmaps(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF); - if (mMipmapsHardwareGenerated) - { - usage |= D3DUSAGE_AUTOGENMIPMAP; - numMips = 0; - } - } - } - else - { - // no mip map support for this kind of textures :( - mNumMipmaps = 0; - numMips = 1; - } - - // derive the pool to use - determinePool(); - TextureResources* textureResources; - - // Get or create new texture resources structure. - textureResources = getTextureResources(d3d9Device); - if (textureResources != NULL) - freeTextureResources(d3d9Device, textureResources); - else - textureResources = allocateTextureResources(d3d9Device); - - - // create the texture - hr = D3DXCreateCubeTexture( - d3d9Device, // device - static_cast(mSrcWidth), // dimension - numMips, // number of mip map levels - usage, // usage - d3dPF, // pixel format - mD3DPool, - &textureResources->pCubeTex); // data pointer - // check result and except if failed - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createCubeTex" ); - } - - // set the base texture we'll use in the render system - hr = textureResources->pCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createCubeTex" ); - } - - // set final tex. attributes from tex. description - // they may differ from the source image !!! - D3DSURFACE_DESC desc; - hr = textureResources->pCubeTex->GetLevelDesc(0, &desc); - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createCubeTex" ); - } - - if (mFSAAType) - { - // create AA surface - HRESULT hr = d3d9Device->CreateRenderTarget(desc.Width, desc.Height, d3dPF, - mFSAAType, - mFSAAQuality, - FALSE, // not lockable - &textureResources->pFSAASurface, NULL); - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create AA render target: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createCubeTex"); - } - } - - _setFinalAttributes(d3d9Device, textureResources, - desc.Width, desc.Height, 1, D3D9Mappings::_getPF(desc.Format)); - - // Set best filter type - if(mMipmapsHardwareGenerated) - { - hr = textureResources->pBaseTex->SetAutoGenFilterType(_getBestFilterMethod(d3d9Device)); - if(FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createCubeTex" ); - } - } - - } - /****************************************************************************************/ - void D3D9Texture::_createVolumeTex(IDirect3DDevice9* d3d9Device) - { - // we must have those defined here - assert(mWidth > 0 && mHeight > 0 && mDepth>0); - - if (mUsage & TU_RENDERTARGET) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D9 Volume texture can not be created as render target !!", - "D3D9Texture::_createVolumeTex" ); - } - - // determine which D3D9 pixel format we'll use - HRESULT hr; - D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); - // let's D3DX check the corrected pixel format - hr = D3DXCheckVolumeTextureRequirements(d3d9Device, NULL, NULL, NULL, NULL, 0, &d3dPF, mD3DPool); - - // Use D3DX to help us create the texture, this way it can adjust any relevant sizes - DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0; - UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? - D3DX_DEFAULT : mNumRequestedMipmaps + 1; - // Check dynamic textures - if (mUsage & TU_DYNAMIC) - { - if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF)) - { - usage |= D3DUSAGE_DYNAMIC; - mDynamicTextures = true; - } - else - { - mDynamicTextures = false; - } - } - // Check sRGB support - if (mHwGamma) - { - mHwGammaReadSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF, false); - if (mUsage & TU_RENDERTARGET) - mHwGammaWriteSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF, true); - } - - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); - - - // check if mip map volume textures are supported - mMipmapsHardwareGenerated = false; - if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP) - { - if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0) - { - // use auto.gen. if available - mMipmapsHardwareGenerated = _canAutoGenMipmaps(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF); - if (mMipmapsHardwareGenerated) - { - usage |= D3DUSAGE_AUTOGENMIPMAP; - numMips = 0; - } - } - } - else - { - // no mip map support for this kind of textures :( - mNumMipmaps = 0; - numMips = 1; - } - - // derive the pool to use - determinePool(); - TextureResources* textureResources; - - // Get or create new texture resources structure. - textureResources = getTextureResources(d3d9Device); - if (textureResources != NULL) - freeTextureResources(d3d9Device, textureResources); - else - textureResources = allocateTextureResources(d3d9Device); - - - // create the texture - hr = D3DXCreateVolumeTexture( - d3d9Device, // device - static_cast(mWidth), // dimension - static_cast(mHeight), - static_cast(mDepth), - numMips, // number of mip map levels - usage, // usage - d3dPF, // pixel format - mD3DPool, - &textureResources->pVolumeTex); // data pointer - // check result and except if failed - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createVolumeTex" ); - } - - // set the base texture we'll use in the render system - hr = textureResources->pVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createVolumeTex" ); - } - - // set final tex. attributes from tex. description - // they may differ from the source image !!! - D3DVOLUME_DESC desc; - hr = textureResources->pVolumeTex->GetLevelDesc(0, &desc); - if (FAILED(hr)) - { - freeInternalResources(); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createVolumeTex" ); - } - _setFinalAttributes(d3d9Device, textureResources, - desc.Width, desc.Height, desc.Depth, D3D9Mappings::_getPF(desc.Format)); - - // Set best filter type - if(mMipmapsHardwareGenerated) - { - hr = textureResources->pBaseTex->SetAutoGenFilterType(_getBestFilterMethod(d3d9Device)); - if(FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type: " + String(DXGetErrorDescription(hr)), - "D3D9Texture::_createCubeTex" ); - } - } - } - - /****************************************************************************************/ - void D3D9Texture::_setFinalAttributes(IDirect3DDevice9* d3d9Device, - TextureResources* textureResources, - unsigned long width, unsigned long height, - unsigned long depth, PixelFormat format) - { - // set target texture attributes - mHeight = height; - mWidth = width; - mDepth = depth; - mFormat = format; - - // Update size (the final size, including temp space because in consumed memory) - // this is needed in Resource class - mSize = calculateSize(); - - // say to the world what we are doing - if (mWidth != mSrcWidth || - mHeight != mSrcHeight) - { - LogManager::getSingleton().logMessage("D3D9 : ***** Dimensions altered by the render system"); - LogManager::getSingleton().logMessage("D3D9 : ***** Source image dimensions : " + StringConverter::toString(mSrcWidth) + "x" + StringConverter::toString(mSrcHeight)); - LogManager::getSingleton().logMessage("D3D9 : ***** Texture dimensions : " + StringConverter::toString(mWidth) + "x" + StringConverter::toString(mHeight)); - } - - // Create list of subsurfaces for getBuffer() - _createSurfaceList(d3d9Device, textureResources); - } - /****************************************************************************************/ - void D3D9Texture::_setSrcAttributes(unsigned long width, unsigned long height, - unsigned long depth, PixelFormat format) - { - // set source image attributes - mSrcWidth = width; - mSrcHeight = height; - mSrcDepth = depth; - mSrcFormat = format; - // say to the world what we are doing - if (!TextureManager::getSingleton().getVerbose()) return; - switch (getTextureType()) - { - case TEX_TYPE_1D: - if (mUsage & TU_RENDERTARGET) - LogManager::getSingleton().logMessage("D3D9 : Creating 1D RenderTarget, name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - else - LogManager::getSingleton().logMessage("D3D9 : Loading 1D Texture, image name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - break; - case TEX_TYPE_2D: - if (mUsage & TU_RENDERTARGET) - LogManager::getSingleton().logMessage("D3D9 : Creating 2D RenderTarget, name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - else - LogManager::getSingleton().logMessage("D3D9 : Loading 2D Texture, image name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - break; - case TEX_TYPE_3D: - if (mUsage & TU_RENDERTARGET) - LogManager::getSingleton().logMessage("D3D9 : Creating 3D RenderTarget, name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - else - LogManager::getSingleton().logMessage("D3D9 : Loading 3D Texture, image name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - break; - case TEX_TYPE_CUBE_MAP: - if (mUsage & TU_RENDERTARGET) - LogManager::getSingleton().logMessage("D3D9 : Creating Cube map RenderTarget, name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - else - LogManager::getSingleton().logMessage("D3D9 : Loading Cube Texture, base image name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); - break; - default: - freeInternalResources(); - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::_setSrcAttributes" ); - } - } - /****************************************************************************************/ - D3DTEXTUREFILTERTYPE D3D9Texture::_getBestFilterMethod(IDirect3DDevice9* d3d9Device) - { - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); - - - DWORD filterCaps = 0; - // Minification filter is used for mipmap generation - // Pick the best one supported for this tex type - switch (getTextureType()) - { - case TEX_TYPE_1D: // Same as 2D - case TEX_TYPE_2D: filterCaps = rkCurCaps.TextureFilterCaps; break; - case TEX_TYPE_3D: filterCaps = rkCurCaps.VolumeTextureFilterCaps; break; - case TEX_TYPE_CUBE_MAP: filterCaps = rkCurCaps.CubeTextureFilterCaps; break; - } - if(filterCaps & D3DPTFILTERCAPS_MINFGAUSSIANQUAD) - return D3DTEXF_GAUSSIANQUAD; - - if(filterCaps & D3DPTFILTERCAPS_MINFPYRAMIDALQUAD) - return D3DTEXF_PYRAMIDALQUAD; - - if(filterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) - return D3DTEXF_ANISOTROPIC; - - if(filterCaps & D3DPTFILTERCAPS_MINFLINEAR) - return D3DTEXF_LINEAR; - - if(filterCaps & D3DPTFILTERCAPS_MINFPOINT) - return D3DTEXF_POINT; - - return D3DTEXF_POINT; - } - /****************************************************************************************/ - bool D3D9Texture::_canUseDynamicTextures(IDirect3DDevice9* d3d9Device, - DWORD srcUsage, - D3DRESOURCETYPE srcType, - D3DFORMAT srcFormat) - { - HRESULT hr; - IDirect3D9* pD3D = NULL; - - hr = d3d9Device->GetDirect3D(&pD3D); - if (FAILED(hr)) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "GetDirect3D failed !!!", - "D3D9Texture::_canUseDynamicTextures" ); - } - if (pD3D != NULL) - pD3D->Release(); - - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); - D3DFORMAT eBackBufferFormat = device->getBackBufferFormat(); - - - // Check for dynamic texture support - - // check for auto gen. mip maps support - hr = pD3D->CheckDeviceFormat( - rkCurCaps.AdapterOrdinal, - rkCurCaps.DeviceType, - eBackBufferFormat, - srcUsage | D3DUSAGE_DYNAMIC, - srcType, - srcFormat); - - if (hr == D3D_OK) - return true; - else - return false; - } - /****************************************************************************************/ - bool D3D9Texture::_canUseHardwareGammaCorrection(IDirect3DDevice9* d3d9Device, - DWORD srcUsage, - D3DRESOURCETYPE srcType, D3DFORMAT srcFormat, bool forwriting) - { - HRESULT hr; - IDirect3D9* pD3D = NULL; - - hr = d3d9Device->GetDirect3D(&pD3D); - if (FAILED(hr)) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "GetDirect3D failed !!!", - "D3D9Texture::_canUseDynamicTextures" ); - } - if (pD3D != NULL) - pD3D->Release(); - - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); - D3DFORMAT eBackBufferFormat = device->getBackBufferFormat(); - - - // Always check 'read' capability here - // We will check 'write' capability only in the context of a render target - if (forwriting) - srcUsage |= D3DUSAGE_QUERY_SRGBWRITE; - else - srcUsage |= D3DUSAGE_QUERY_SRGBREAD; - - // Check for sRGB support - // check for auto gen. mip maps support - hr = pD3D->CheckDeviceFormat( - rkCurCaps.AdapterOrdinal, - rkCurCaps.DeviceType, - eBackBufferFormat, - srcUsage, - srcType, - srcFormat); - if (hr == D3D_OK) - return true; - else - return false; - - } - /****************************************************************************************/ - bool D3D9Texture::_canAutoGenMipmaps(IDirect3DDevice9* d3d9Device, - DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat) - { - HRESULT hr; - IDirect3D9* pD3D = NULL; - - hr = d3d9Device->GetDirect3D(&pD3D); - if (FAILED(hr)) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, - "GetDirect3D failed !!!", - "D3D9Texture::_canUseDynamicTextures" ); - } - if (pD3D != NULL) - pD3D->Release(); - - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); - D3DFORMAT eBackBufferFormat = device->getBackBufferFormat(); - - - // Hacky override - many (all?) cards seem to not be able to autogen on - // textures which are not a power of two - // Can we even mipmap on 3D textures? Well - if ((mWidth & mWidth-1) || (mHeight & mHeight-1) || (mDepth & mDepth-1)) - return false; - - if (rkCurCaps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) - { - HRESULT hr; - // check for auto gen. mip maps support - hr = pD3D->CheckDeviceFormat( - rkCurCaps.AdapterOrdinal, - rkCurCaps.DeviceType, - eBackBufferFormat, - srcUsage | D3DUSAGE_AUTOGENMIPMAP, - srcType, - srcFormat); - // this HR could a SUCCES - // but mip maps will not be generated - if (hr == D3D_OK) - return true; - else - return false; - } - else - return false; - } - /****************************************************************************************/ - D3DFORMAT D3D9Texture::_chooseD3DFormat(IDirect3DDevice9* d3d9Device) - { - // Choose frame buffer pixel format in case PF_UNKNOWN was requested - if(mFormat == PF_UNKNOWN) - { - D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); - - return device->getBackBufferFormat(); - } - - // Choose closest supported D3D format as a D3D format - return D3D9Mappings::_getPF(D3D9Mappings::_getClosestSupportedPF(mFormat)); - } - /****************************************************************************************/ - // Macro to hide ugly cast - #define GETLEVEL(face,mip) \ - static_cast(mSurfaceList[face*(mNumMipmaps+1)+mip].get()) - void D3D9Texture::_createSurfaceList(IDirect3DDevice9* d3d9Device, TextureResources* textureResources) - { - IDirect3DSurface9 *surface; - IDirect3DVolume9 *volume; - D3D9HardwarePixelBuffer *buffer; - size_t mip, face; - - - assert(textureResources != NULL); - assert(textureResources->pBaseTex); - // Make sure number of mips is right - mNumMipmaps = textureResources->pBaseTex->GetLevelCount() - 1; - // Need to know static / dynamic - unsigned int bufusage; - if ((mUsage & TU_DYNAMIC) && mDynamicTextures) - { - bufusage = HardwareBuffer::HBU_DYNAMIC; - } - else - { - bufusage = HardwareBuffer::HBU_STATIC; - } - if (mUsage & TU_RENDERTARGET) - { - bufusage |= TU_RENDERTARGET; - } - - uint surfaceCount = static_cast((getNumFaces() * (mNumMipmaps + 1))); - bool updateOldList = mSurfaceList.size() == surfaceCount; - if(!updateOldList) - { - // Create new list of surfaces - mSurfaceList.clear(); - for(size_t face=0; facepNormTex); - // For all mipmaps, store surfaces as HardwarePixelBufferSharedPtr - for(mip=0; mip<=mNumMipmaps; ++mip) - { - if(textureResources->pNormTex->GetSurfaceLevel(static_cast(mip), &surface) != D3D_OK) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get surface level failed", - "D3D9Texture::_createSurfaceList"); - - D3D9HardwarePixelBuffer* currPixelBuffer = GETLEVEL(0, mip); - - if (mip == 0 && mNumRequestedMipmaps != 0 && (mUsage & TU_AUTOMIPMAP)) - currPixelBuffer->_setMipmapping(true, mMipmapsHardwareGenerated); - - currPixelBuffer->bind(d3d9Device, surface, textureResources->pFSAASurface, - mHwGammaWriteSupported, mFSAA, mName, textureResources->pBaseTex); - - // decrement reference count, the GetSurfaceLevel call increments this - // this is safe because the pixel buffer keeps a reference as well - surface->Release(); - } - - break; - case TEX_TYPE_CUBE_MAP: - assert(textureResources->pCubeTex); - // For all faces and mipmaps, store surfaces as HardwarePixelBufferSharedPtr - for(face=0; face<6; ++face) - { - for(mip=0; mip<=mNumMipmaps; ++mip) - { - if(textureResources->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, static_cast(mip), &surface) != D3D_OK) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get cubemap surface failed", - "D3D9Texture::getBuffer"); - - D3D9HardwarePixelBuffer* currPixelBuffer = GETLEVEL(face, mip); - - - if (mip == 0 && mNumRequestedMipmaps != 0 && (mUsage & TU_AUTOMIPMAP)) - currPixelBuffer->_setMipmapping(true, mMipmapsHardwareGenerated); - - currPixelBuffer->bind(d3d9Device, surface, textureResources->pFSAASurface, - mHwGammaWriteSupported, mFSAA, mName, textureResources->pBaseTex); - - // decrement reference count, the GetSurfaceLevel call increments this - // this is safe because the pixel buffer keeps a reference as well - surface->Release(); - } - } - break; - case TEX_TYPE_3D: - assert(textureResources->pVolumeTex); - // For all mipmaps, store surfaces as HardwarePixelBufferSharedPtr - for(mip=0; mip<=mNumMipmaps; ++mip) - { - if(textureResources->pVolumeTex->GetVolumeLevel(static_cast(mip), &volume) != D3D_OK) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get volume level failed", - "D3D9Texture::getBuffer"); - - D3D9HardwarePixelBuffer* currPixelBuffer = GETLEVEL(0, mip); - - currPixelBuffer->bind(d3d9Device, volume, textureResources->pBaseTex); - - if (mip == 0 && mNumRequestedMipmaps != 0 && (mUsage & TU_AUTOMIPMAP)) - currPixelBuffer->_setMipmapping(true, mMipmapsHardwareGenerated); - - // decrement reference count, the GetSurfaceLevel call increments this - // this is safe because the pixel buffer keeps a reference as well - volume->Release(); - } - break; - }; - } - #undef GETLEVEL - /****************************************************************************************/ - HardwarePixelBufferSharedPtr D3D9Texture::getBuffer(size_t face, size_t mipmap) - { - if(face >= getNumFaces()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "A three dimensional cube has six faces", - "D3D9Texture::getBuffer"); - if(mipmap > mNumMipmaps) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range", - "D3D9Texture::getBuffer"); - size_t idx = face*(mNumMipmaps+1) + mipmap; - - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); - TextureResources* textureResources = getTextureResources(d3d9Device); - if (textureResources == NULL || textureResources->pBaseTex == NULL) - { - createTextureResources(d3d9Device); - textureResources = getTextureResources(d3d9Device); - } - - assert(textureResources != NULL); - assert(idx < mSurfaceList.size()); - return mSurfaceList[idx]; - } - //--------------------------------------------------------------------- - bool D3D9Texture::useDefaultPool() - { - // Determine D3D pool to use - // Use managed unless we're a render target or user has asked for - // a dynamic texture, and device supports D3DUSAGE_DYNAMIC (because default pool - // resources without the dynamic flag are not lockable) - // or use if we are using directX9Ex as there is no managed pool under it. - return (D3D9RenderSystem::isDirectX9Ex()) || (mUsage & TU_RENDERTARGET) || ((mUsage & TU_DYNAMIC) && mDynamicTextures); - } - - //--------------------------------------------------------------------- - void D3D9Texture::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if (D3D9RenderSystem::getResourceManager()->getCreationPolicy() == RCP_CREATE_ON_ALL_DEVICES) + // set src and dest attributes to the same, we can't know + _setSrcAttributes(texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format)); + _setFinalAttributes(d3d9Device, textureResources, + texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format)); + + if( mHwGamma ) + { + mHwGammaReadSupported = _canUseHardwareGammaCorrection( d3d9Device, texDesc.Usage, + D3DRTYPE_TEXTURE, + texDesc.Format, false); + } + mInternalResourcesCreated = true; + } + else { - try + Image img; + // find & load resource data intro stream to allow resource + // group changes if required + assert(loadedStreams->size()==1); + + size_t pos = mName.find_last_of("."); + String ext; + if ( pos != String::npos ) + ext = mName.substr(pos+1); + + DataStreamPtr stream((*loadedStreams)[0]); + img.load(stream, ext); + + if (img.getHeight() == 0) { - createTextureResources(d3d9Device); + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Image height == 0 in " + getName(), + "D3D9Texture::_loadNormTex"); } - catch (...) + + if (img.getWidth() == 0) { - mLoadingState.set(LOADSTATE_UNLOADED); - LogManager::getSingleton().stream() << "Warning: Failed to restore texture " << getName() - << " on DeviceCreate."; + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Image width == 0 in " + getName(), + "D3D9Texture::_loadNormTex"); } + + // Call internal _loadImages, not loadImage since that's external and + // will determine load status etc again + ConstImagePtrList imagePtrs; + imagePtrs.push_back(&img); + _loadImages( imagePtrs ); } - } - - //--------------------------------------------------------------------- - void D3D9Texture::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.find(d3d9Device); - - if (it != mMapDeviceToTextureResources.end()) - { - StringStream ss; - - ss << "D3D9 device: 0x[" << d3d9Device << "] destroy. Releasing D3D9 texture: " << mName; - LogManager::getSingleton().logMessage(ss.str()); - - TextureResources* textureResource = it->second; - - // Destroy surfaces from each mip level. - for(unsigned int i = 0; i < mSurfaceList.size(); ++i) - { - D3D9HardwarePixelBuffer* pixelBuffer = static_cast(mSurfaceList[i].get()); - - pixelBuffer->destroyBufferResources(d3d9Device); - } - - // Just free any internal resources, don't call unload() here - // because we want the un-touched resource to keep its unloaded status - // after device reset. - freeTextureResources(d3d9Device, textureResource); - - OGRE_DELETE_T(textureResource, TextureResources, MEMCATEGORY_RENDERSYS); - - mMapDeviceToTextureResources.erase(it); - - LogManager::getSingleton().logMessage("Released D3D9 texture: " + mName); - } - } - - //--------------------------------------------------------------------- - void D3D9Texture::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if(mD3DPool == D3DPOOL_DEFAULT) - { - DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.find(d3d9Device); - - if (it != mMapDeviceToTextureResources.end()) - { - StringStream ss; - - ss << "D3D9 device: 0x[" << d3d9Device << "] lost. Releasing D3D9 texture: " << mName; - LogManager::getSingleton().logMessage(ss.str()); - - TextureResources* textureResource = it->second; - - // Just free any internal resources, don't call unload() here - // because we want the un-touched resource to keep its unloaded status - // after device reset. - freeTextureResources(d3d9Device, textureResource); - - LogManager::getSingleton().logMessage("Released D3D9 texture: " + mName); - } - } - } - - //--------------------------------------------------------------------- - void D3D9Texture::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - if(mD3DPool == D3DPOOL_DEFAULT) - { - createTextureResources(d3d9Device); - } - } - - //--------------------------------------------------------------------- - IDirect3DBaseTexture9* D3D9Texture::getTexture() - { - TextureResources* textureResources; - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); - - textureResources = getTextureResources(d3d9Device); - if (textureResources == NULL || textureResources->pBaseTex == NULL) - { - createTextureResources(d3d9Device); - textureResources = getTextureResources(d3d9Device); - } - assert(textureResources); - assert(textureResources->pBaseTex); - - return textureResources->pBaseTex; - } - - //--------------------------------------------------------------------- - IDirect3DTexture9* D3D9Texture::getNormTexture() - { - TextureResources* textureResources; - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); - - textureResources = getTextureResources(d3d9Device); - if (textureResources == NULL || textureResources->pNormTex == NULL) - { - createTextureResources(d3d9Device); - textureResources = getTextureResources(d3d9Device); - } - assert(textureResources); - assert(textureResources->pNormTex); - - return textureResources->pNormTex; - } - - //--------------------------------------------------------------------- - IDirect3DCubeTexture9* D3D9Texture::getCubeTexture() - { - TextureResources* textureResources; - IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); - - textureResources = getTextureResources(d3d9Device); - if (textureResources == NULL || textureResources->pCubeTex) - { - createTextureResources(d3d9Device); - textureResources = getTextureResources(d3d9Device); - } - assert(textureResources); - assert(textureResources->pCubeTex); - - return textureResources->pCubeTex; - } - - /****************************************************************************************/ - D3D9RenderTexture::D3D9RenderTexture(const String &name, - D3D9HardwarePixelBuffer *buffer, - bool writeGamma, - uint fsaa) : RenderTexture(buffer, 0) - { - mName = name; - mHwGamma = writeGamma; - mFSAA = fsaa; - } - //--------------------------------------------------------------------- - void D3D9RenderTexture::update(bool swap) + + } + + /****************************************************************************************/ + size_t D3D9Texture::calculateSize(void) const + { + size_t instanceSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); + + return instanceSize * mMapDeviceToTextureResources.size(); + } + + /****************************************************************************************/ + void D3D9Texture::createInternalResources(void) + { + createInternalResourcesImpl(); + } + + /****************************************************************************************/ + void D3D9Texture::determinePool() + { + if (useDefaultPool()) + { + mD3DPool = D3DPOOL_DEFAULT; + } + else + { + mD3DPool = D3DPOOL_MANAGED; + } + + } + /****************************************************************************************/ + void D3D9Texture::createInternalResourcesImpl(void) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + for (uint i = 0; i < D3D9RenderSystem::getResourceCreationDeviceCount(); ++i) + { + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getResourceCreationDevice(i); + + createInternalResourcesImpl(d3d9Device); + } + } + + /****************************************************************************************/ + void D3D9Texture::createInternalResourcesImpl(IDirect3DDevice9* d3d9Device) + { + TextureResources* textureResources; + + // Check if resources already exist. + textureResources = getTextureResources(d3d9Device); + if (textureResources != NULL && textureResources->pBaseTex != NULL) + return; + + + // If mSrcWidth and mSrcHeight are zero, the requested extents have probably been set + // through setWidth and setHeight, which set mWidth and mHeight. Take those values. + if(mSrcWidth == 0 || mSrcHeight == 0) { + mSrcWidth = mWidth; + mSrcHeight = mHeight; + } + + // load based on tex.type + switch (getTextureType()) + { + case TEX_TYPE_1D: + case TEX_TYPE_2D: + _createNormTex(d3d9Device); + break; + case TEX_TYPE_CUBE_MAP: + _createCubeTex(d3d9Device); + break; + case TEX_TYPE_3D: + _createVolumeTex(d3d9Device); + break; + default: + freeInternalResources(); + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::createInternalResources" ); + } + } + + /****************************************************************************************/ + void D3D9Texture::_createNormTex(IDirect3DDevice9* d3d9Device) { - D3D9DeviceManager* deviceManager = D3D9RenderSystem::getDeviceManager(); - D3D9Device* currRenderWindowDevice = deviceManager->getActiveRenderTargetDevice(); - - if (currRenderWindowDevice != NULL) - { - if (currRenderWindowDevice->isDeviceLost() == false) - RenderTexture::update(swap); - } - else - { - for (UINT i=0; i < deviceManager->getDeviceCount(); ++i) - { - D3D9Device* device = deviceManager->getDevice(i); - - if (device->isDeviceLost() == false) - { - deviceManager->setActiveRenderTargetDevice(device); - RenderTexture::update(swap); - deviceManager->setActiveRenderTargetDevice(NULL); - } - } - } - } - //--------------------------------------------------------------------- - void D3D9RenderTexture::getCustomAttribute( const String& name, void *pData ) - { - if(name == "DDBACKBUFFER") - { - if (mFSAA > 0) - { - // rendering to AA surface - IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData; - *pSurf = static_cast(mBuffer)->getFSAASurface(D3D9RenderSystem::getActiveD3D9Device()); - return; - } - else - { - IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData; - *pSurf = static_cast(mBuffer)->getSurface(D3D9RenderSystem::getActiveD3D9Device()); - return; - } - } - else if(name == "HWND") - { - HWND *pHwnd = (HWND*)pData; - *pHwnd = NULL; - return; - } - else if(name == "BUFFER") - { - *static_cast(pData) = mBuffer; - return; - } - } - //--------------------------------------------------------------------- - void D3D9RenderTexture::swapBuffers() - { - // Only needed if we have to blit from AA surface - if (mFSAA > 0) - { - D3D9DeviceManager* deviceManager = D3D9RenderSystem::getDeviceManager(); - D3D9HardwarePixelBuffer* buf = static_cast(mBuffer); - - for (UINT i=0; i < deviceManager->getDeviceCount(); ++i) - { - D3D9Device* device = deviceManager->getDevice(i); - - if (device->isDeviceLost() == false) - { - IDirect3DDevice9* d3d9Device = device->getD3D9Device(); - - HRESULT hr = d3d9Device->StretchRect(buf->getFSAASurface(d3d9Device), 0, - buf->getSurface(d3d9Device), 0, D3DTEXF_NONE); - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Unable to copy AA buffer to final buffer: " + String(DXGetErrorDescription(hr)), - "D3D9RenderTexture::swapBuffers"); - } - } - } - } - } + // we must have those defined here + assert(mSrcWidth > 0 || mSrcHeight > 0); + + // determine which D3D9 pixel format we'll use + HRESULT hr; + D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); + + // let's D3DX check the corrected pixel format + hr = D3DXCheckTextureRequirements(d3d9Device, NULL, NULL, NULL, 0, &d3dPF, mD3DPool); + + // Use D3DX to help us create the texture, this way it can adjust any relevant sizes + DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0; + UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? + D3DX_DEFAULT : mNumRequestedMipmaps + 1; + // Check dynamic textures + if (mUsage & TU_DYNAMIC) + { + if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF)) + { + usage |= D3DUSAGE_DYNAMIC; + mDynamicTextures = true; + } + else + { + mDynamicTextures = false; + } + } + // Check sRGB support + if (mHwGamma) + { + mHwGammaReadSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF, false); + if (mUsage & TU_RENDERTARGET) + mHwGammaWriteSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF, true); + } + // Check FSAA level + if (mUsage & TU_RENDERTARGET) + { + D3D9RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); + rsys->determineFSAASettings(d3d9Device, mFSAA, mFSAAHint, d3dPF, false, + &mFSAAType, &mFSAAQuality); + } + else + { + mFSAAType = D3DMULTISAMPLE_NONE; + mFSAAQuality = 0; + } + + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); + + + // check if mip maps are supported on hardware + mMipmapsHardwareGenerated = false; + if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) + { + if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0) + { + // use auto.gen. if available, and if desired + mMipmapsHardwareGenerated = _canAutoGenMipmaps(d3d9Device, usage, D3DRTYPE_TEXTURE, d3dPF); + if (mMipmapsHardwareGenerated) + { + usage |= D3DUSAGE_AUTOGENMIPMAP; + numMips = 0; + } + } + } + else + { + // no mip map support for this kind of textures :( + mNumMipmaps = 0; + numMips = 1; + } + + // derive the pool to use + determinePool(); + + TextureResources* textureResources; + + // Get or create new texture resources structure. + textureResources = getTextureResources(d3d9Device); + if (textureResources != NULL) + freeTextureResources(d3d9Device, textureResources); + else + textureResources = allocateTextureResources(d3d9Device); + + + // create the texture + hr = D3DXCreateTexture( + d3d9Device, // device + static_cast(mSrcWidth), // width + static_cast(mSrcHeight), // height + numMips, // number of mip map levels + usage, // usage + d3dPF, // pixel format + mD3DPool, + &textureResources->pNormTex); // data pointer + // check result and except if failed + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createNormTex" ); + } + + // set the base texture we'll use in the render system + hr = textureResources->pNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createNormTex" ); + } + + // set final tex. attributes from tex. description + // they may differ from the source image !!! + D3DSURFACE_DESC desc; + hr = textureResources->pNormTex->GetLevelDesc(0, &desc); + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createNormTex" ); + } + + if (mFSAAType) + { + // create AA surface + HRESULT hr = d3d9Device->CreateRenderTarget(desc.Width, desc.Height, d3dPF, + mFSAAType, + mFSAAQuality, + FALSE, // not lockable + &textureResources->pFSAASurface, NULL); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create AA render target: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createNormTex"); + } + + } + + _setFinalAttributes(d3d9Device, textureResources, + desc.Width, desc.Height, 1, D3D9Mappings::_getPF(desc.Format)); + + // Set best filter type + if(mMipmapsHardwareGenerated) + { + hr = textureResources->pBaseTex->SetAutoGenFilterType(_getBestFilterMethod(d3d9Device)); + if(FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createNormTex" ); + } + } + + } + /****************************************************************************************/ + void D3D9Texture::_createCubeTex(IDirect3DDevice9* d3d9Device) + { + // we must have those defined here + assert(mSrcWidth > 0 || mSrcHeight > 0); + + // determine which D3D9 pixel format we'll use + HRESULT hr; + D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); + + // let's D3DX check the corrected pixel format + hr = D3DXCheckCubeTextureRequirements(d3d9Device, NULL, NULL, 0, &d3dPF, mD3DPool); + + // Use D3DX to help us create the texture, this way it can adjust any relevant sizes + DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0; + UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? + D3DX_DEFAULT : mNumRequestedMipmaps + 1; + // Check dynamic textures + if (mUsage & TU_DYNAMIC) + { + if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF)) + { + usage |= D3DUSAGE_DYNAMIC; + mDynamicTextures = true; + } + else + { + mDynamicTextures = false; + } + } + // Check sRGB support + if (mHwGamma) + { + mHwGammaReadSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF, false); + if (mUsage & TU_RENDERTARGET) + mHwGammaWriteSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF, true); + } + // Check FSAA level + if (mUsage & TU_RENDERTARGET) + { + D3D9RenderSystem* rsys = static_cast(Root::getSingleton().getRenderSystem()); + rsys->determineFSAASettings(d3d9Device, mFSAA, mFSAAHint, d3dPF, false, + &mFSAAType, &mFSAAQuality); + } + else + { + mFSAAType = D3DMULTISAMPLE_NONE; + mFSAAQuality = 0; + } + + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); + + // check if mip map cube textures are supported + mMipmapsHardwareGenerated = false; + if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP) + { + if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0) + { + // use auto.gen. if available + mMipmapsHardwareGenerated = _canAutoGenMipmaps(d3d9Device, usage, D3DRTYPE_CUBETEXTURE, d3dPF); + if (mMipmapsHardwareGenerated) + { + usage |= D3DUSAGE_AUTOGENMIPMAP; + numMips = 0; + } + } + } + else + { + // no mip map support for this kind of textures :( + mNumMipmaps = 0; + numMips = 1; + } + + // derive the pool to use + determinePool(); + TextureResources* textureResources; + + // Get or create new texture resources structure. + textureResources = getTextureResources(d3d9Device); + if (textureResources != NULL) + freeTextureResources(d3d9Device, textureResources); + else + textureResources = allocateTextureResources(d3d9Device); + + + // create the texture + hr = D3DXCreateCubeTexture( + d3d9Device, // device + static_cast(mSrcWidth), // dimension + numMips, // number of mip map levels + usage, // usage + d3dPF, // pixel format + mD3DPool, + &textureResources->pCubeTex); // data pointer + // check result and except if failed + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createCubeTex" ); + } + + // set the base texture we'll use in the render system + hr = textureResources->pCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createCubeTex" ); + } + + // set final tex. attributes from tex. description + // they may differ from the source image !!! + D3DSURFACE_DESC desc; + hr = textureResources->pCubeTex->GetLevelDesc(0, &desc); + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createCubeTex" ); + } + + if (mFSAAType) + { + // create AA surface + HRESULT hr = d3d9Device->CreateRenderTarget(desc.Width, desc.Height, d3dPF, + mFSAAType, + mFSAAQuality, + FALSE, // not lockable + &textureResources->pFSAASurface, NULL); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create AA render target: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createCubeTex"); + } + } + + _setFinalAttributes(d3d9Device, textureResources, + desc.Width, desc.Height, 1, D3D9Mappings::_getPF(desc.Format)); + + // Set best filter type + if(mMipmapsHardwareGenerated) + { + hr = textureResources->pBaseTex->SetAutoGenFilterType(_getBestFilterMethod(d3d9Device)); + if(FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createCubeTex" ); + } + } + + } + /****************************************************************************************/ + void D3D9Texture::_createVolumeTex(IDirect3DDevice9* d3d9Device) + { + // we must have those defined here + assert(mWidth > 0 && mHeight > 0 && mDepth>0); + + if (mUsage & TU_RENDERTARGET) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "D3D9 Volume texture can not be created as render target !!", + "D3D9Texture::_createVolumeTex" ); + } + + // determine which D3D9 pixel format we'll use + HRESULT hr; + D3DFORMAT d3dPF = _chooseD3DFormat(d3d9Device); + // let's D3DX check the corrected pixel format + hr = D3DXCheckVolumeTextureRequirements(d3d9Device, NULL, NULL, NULL, NULL, 0, &d3dPF, mD3DPool); + + // Use D3DX to help us create the texture, this way it can adjust any relevant sizes + DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0; + UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? + D3DX_DEFAULT : mNumRequestedMipmaps + 1; + // Check dynamic textures + if (mUsage & TU_DYNAMIC) + { + if (_canUseDynamicTextures(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF)) + { + usage |= D3DUSAGE_DYNAMIC; + mDynamicTextures = true; + } + else + { + mDynamicTextures = false; + } + } + // Check sRGB support + if (mHwGamma) + { + mHwGammaReadSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF, false); + if (mUsage & TU_RENDERTARGET) + mHwGammaWriteSupported = _canUseHardwareGammaCorrection(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF, true); + } + + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); + + + // check if mip map volume textures are supported + mMipmapsHardwareGenerated = false; + if (rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP) + { + if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0) + { + // use auto.gen. if available + mMipmapsHardwareGenerated = _canAutoGenMipmaps(d3d9Device, usage, D3DRTYPE_VOLUMETEXTURE, d3dPF); + if (mMipmapsHardwareGenerated) + { + usage |= D3DUSAGE_AUTOGENMIPMAP; + numMips = 0; + } + } + } + else + { + // no mip map support for this kind of textures :( + mNumMipmaps = 0; + numMips = 1; + } + + // derive the pool to use + determinePool(); + TextureResources* textureResources; + + // Get or create new texture resources structure. + textureResources = getTextureResources(d3d9Device); + if (textureResources != NULL) + freeTextureResources(d3d9Device, textureResources); + else + textureResources = allocateTextureResources(d3d9Device); + + + // create the texture + hr = D3DXCreateVolumeTexture( + d3d9Device, // device + static_cast(mWidth), // dimension + static_cast(mHeight), + static_cast(mDepth), + numMips, // number of mip map levels + usage, // usage + d3dPF, // pixel format + mD3DPool, + &textureResources->pVolumeTex); // data pointer + // check result and except if failed + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createVolumeTex" ); + } + + // set the base texture we'll use in the render system + hr = textureResources->pVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&textureResources->pBaseTex); + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createVolumeTex" ); + } + + // set final tex. attributes from tex. description + // they may differ from the source image !!! + D3DVOLUME_DESC desc; + hr = textureResources->pVolumeTex->GetLevelDesc(0, &desc); + if (FAILED(hr)) + { + freeInternalResources(); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createVolumeTex" ); + } + _setFinalAttributes(d3d9Device, textureResources, + desc.Width, desc.Height, desc.Depth, D3D9Mappings::_getPF(desc.Format)); + + // Set best filter type + if(mMipmapsHardwareGenerated) + { + hr = textureResources->pBaseTex->SetAutoGenFilterType(_getBestFilterMethod(d3d9Device)); + if(FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type: " + String(DXGetErrorDescription(hr)), + "D3D9Texture::_createCubeTex" ); + } + } + } + + /****************************************************************************************/ + void D3D9Texture::_setFinalAttributes(IDirect3DDevice9* d3d9Device, + TextureResources* textureResources, + unsigned long width, unsigned long height, + unsigned long depth, PixelFormat format) + { + // set target texture attributes + mHeight = height; + mWidth = width; + mDepth = depth; + mFormat = format; + + // Update size (the final size, including temp space because in consumed memory) + // this is needed in Resource class + mSize = calculateSize(); + + // say to the world what we are doing + if (mWidth != mSrcWidth || + mHeight != mSrcHeight) + { + LogManager::getSingleton().logMessage("D3D9 : ***** Dimensions altered by the render system"); + LogManager::getSingleton().logMessage("D3D9 : ***** Source image dimensions : " + StringConverter::toString(mSrcWidth) + "x" + StringConverter::toString(mSrcHeight)); + LogManager::getSingleton().logMessage("D3D9 : ***** Texture dimensions : " + StringConverter::toString(mWidth) + "x" + StringConverter::toString(mHeight)); + } + + // Create list of subsurfaces for getBuffer() + _createSurfaceList(d3d9Device, textureResources); + } + /****************************************************************************************/ + void D3D9Texture::_setSrcAttributes(unsigned long width, unsigned long height, + unsigned long depth, PixelFormat format) + { + // set source image attributes + mSrcWidth = width; + mSrcHeight = height; + mSrcDepth = depth; + mSrcFormat = format; + // say to the world what we are doing + if (!TextureManager::getSingleton().getVerbose()) return; + switch (getTextureType()) + { + case TEX_TYPE_1D: + if (mUsage & TU_RENDERTARGET) + LogManager::getSingleton().logMessage("D3D9 : Creating 1D RenderTarget, name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + else + LogManager::getSingleton().logMessage("D3D9 : Loading 1D Texture, image name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + break; + case TEX_TYPE_2D: + if (mUsage & TU_RENDERTARGET) + LogManager::getSingleton().logMessage("D3D9 : Creating 2D RenderTarget, name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + else + LogManager::getSingleton().logMessage("D3D9 : Loading 2D Texture, image name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + break; + case TEX_TYPE_3D: + if (mUsage & TU_RENDERTARGET) + LogManager::getSingleton().logMessage("D3D9 : Creating 3D RenderTarget, name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + else + LogManager::getSingleton().logMessage("D3D9 : Loading 3D Texture, image name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + break; + case TEX_TYPE_CUBE_MAP: + if (mUsage & TU_RENDERTARGET) + LogManager::getSingleton().logMessage("D3D9 : Creating Cube map RenderTarget, name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + else + LogManager::getSingleton().logMessage("D3D9 : Loading Cube Texture, base image name : '" + getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels"); + break; + default: + freeInternalResources(); + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::_setSrcAttributes" ); + } + } + /****************************************************************************************/ + D3DTEXTUREFILTERTYPE D3D9Texture::_getBestFilterMethod(IDirect3DDevice9* d3d9Device) + { + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); + + + DWORD filterCaps = 0; + // Minification filter is used for mipmap generation + // Pick the best one supported for this tex type + switch (getTextureType()) + { + case TEX_TYPE_1D: // Same as 2D + case TEX_TYPE_2D: filterCaps = rkCurCaps.TextureFilterCaps; break; + case TEX_TYPE_3D: filterCaps = rkCurCaps.VolumeTextureFilterCaps; break; + case TEX_TYPE_CUBE_MAP: filterCaps = rkCurCaps.CubeTextureFilterCaps; break; + } + if(filterCaps & D3DPTFILTERCAPS_MINFGAUSSIANQUAD) + return D3DTEXF_GAUSSIANQUAD; + + if(filterCaps & D3DPTFILTERCAPS_MINFPYRAMIDALQUAD) + return D3DTEXF_PYRAMIDALQUAD; + + if(filterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) + return D3DTEXF_ANISOTROPIC; + + if(filterCaps & D3DPTFILTERCAPS_MINFLINEAR) + return D3DTEXF_LINEAR; + + if(filterCaps & D3DPTFILTERCAPS_MINFPOINT) + return D3DTEXF_POINT; + + return D3DTEXF_POINT; + } + /****************************************************************************************/ + bool D3D9Texture::_canUseDynamicTextures(IDirect3DDevice9* d3d9Device, + DWORD srcUsage, + D3DRESOURCETYPE srcType, + D3DFORMAT srcFormat) + { + HRESULT hr; + IDirect3D9* pD3D = NULL; + + hr = d3d9Device->GetDirect3D(&pD3D); + if (FAILED(hr)) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "GetDirect3D failed !!!", + "D3D9Texture::_canUseDynamicTextures" ); + } + if (pD3D != NULL) + pD3D->Release(); + + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); + D3DFORMAT eBackBufferFormat = device->getBackBufferFormat(); + + + // Check for dynamic texture support + + // check for auto gen. mip maps support + hr = pD3D->CheckDeviceFormat( + rkCurCaps.AdapterOrdinal, + rkCurCaps.DeviceType, + eBackBufferFormat, + srcUsage | D3DUSAGE_DYNAMIC, + srcType, + srcFormat); + + if (hr == D3D_OK) + return true; + else + return false; + } + /****************************************************************************************/ + bool D3D9Texture::_canUseHardwareGammaCorrection(IDirect3DDevice9* d3d9Device, + DWORD srcUsage, + D3DRESOURCETYPE srcType, D3DFORMAT srcFormat, bool forwriting) + { + HRESULT hr; + IDirect3D9* pD3D = NULL; + + hr = d3d9Device->GetDirect3D(&pD3D); + if (FAILED(hr)) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "GetDirect3D failed !!!", + "D3D9Texture::_canUseDynamicTextures" ); + } + if (pD3D != NULL) + pD3D->Release(); + + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); + D3DFORMAT eBackBufferFormat = device->getBackBufferFormat(); + + + // Always check 'read' capability here + // We will check 'write' capability only in the context of a render target + if (forwriting) + srcUsage |= D3DUSAGE_QUERY_SRGBWRITE; + else + srcUsage |= D3DUSAGE_QUERY_SRGBREAD; + + // Check for sRGB support + // check for auto gen. mip maps support + hr = pD3D->CheckDeviceFormat( + rkCurCaps.AdapterOrdinal, + rkCurCaps.DeviceType, + eBackBufferFormat, + srcUsage, + srcType, + srcFormat); + if (hr == D3D_OK) + return true; + else + return false; + + } + /****************************************************************************************/ + bool D3D9Texture::_canAutoGenMipmaps(IDirect3DDevice9* d3d9Device, + DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat) + { + HRESULT hr; + IDirect3D9* pD3D = NULL; + + hr = d3d9Device->GetDirect3D(&pD3D); + if (FAILED(hr)) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, + "GetDirect3D failed !!!", + "D3D9Texture::_canUseDynamicTextures" ); + } + if (pD3D != NULL) + pD3D->Release(); + + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + const D3DCAPS9& rkCurCaps = device->getD3D9DeviceCaps(); + D3DFORMAT eBackBufferFormat = device->getBackBufferFormat(); + + + // Hacky override - many (all?) cards seem to not be able to autogen on + // textures which are not a power of two + // Can we even mipmap on 3D textures? Well + if ((mWidth & mWidth-1) || (mHeight & mHeight-1) || (mDepth & mDepth-1)) + return false; + + if (rkCurCaps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) + { + HRESULT hr; + // check for auto gen. mip maps support + hr = pD3D->CheckDeviceFormat( + rkCurCaps.AdapterOrdinal, + rkCurCaps.DeviceType, + eBackBufferFormat, + srcUsage | D3DUSAGE_AUTOGENMIPMAP, + srcType, + srcFormat); + // this HR could a SUCCES + // but mip maps will not be generated + if (hr == D3D_OK) + return true; + else + return false; + } + else + return false; + } + /****************************************************************************************/ + D3DFORMAT D3D9Texture::_chooseD3DFormat(IDirect3DDevice9* d3d9Device) + { + // Choose frame buffer pixel format in case PF_UNKNOWN was requested + if(mFormat == PF_UNKNOWN) + { + D3D9Device* device = D3D9RenderSystem::getDeviceManager()->getDeviceFromD3D9Device(d3d9Device); + + return device->getBackBufferFormat(); + } + + // Choose closest supported D3D format as a D3D format + return D3D9Mappings::_getPF(D3D9Mappings::_getClosestSupportedPF(mFormat)); + } + /****************************************************************************************/ + // Macro to hide ugly cast + #define GETLEVEL(face,mip) \ + static_cast(mSurfaceList[face*(mNumMipmaps+1)+mip].get()) + void D3D9Texture::_createSurfaceList(IDirect3DDevice9* d3d9Device, TextureResources* textureResources) + { + IDirect3DSurface9 *surface; + IDirect3DVolume9 *volume; + D3D9HardwarePixelBuffer *buffer; + size_t mip, face; + + + assert(textureResources != NULL); + assert(textureResources->pBaseTex); + // Make sure number of mips is right + mNumMipmaps = textureResources->pBaseTex->GetLevelCount() - 1; + // Need to know static / dynamic + unsigned int bufusage; + if ((mUsage & TU_DYNAMIC) && mDynamicTextures) + { + bufusage = HardwareBuffer::HBU_DYNAMIC; + } + else + { + bufusage = HardwareBuffer::HBU_STATIC; + } + if (mUsage & TU_RENDERTARGET) + { + bufusage |= TU_RENDERTARGET; + } + + uint surfaceCount = static_cast((getNumFaces() * (mNumMipmaps + 1))); + bool updateOldList = mSurfaceList.size() == surfaceCount; + if(!updateOldList) + { + // Create new list of surfaces + mSurfaceList.clear(); + for(size_t face=0; facepNormTex); + // For all mipmaps, store surfaces as HardwarePixelBufferSharedPtr + for(mip=0; mip<=mNumMipmaps; ++mip) + { + if(textureResources->pNormTex->GetSurfaceLevel(static_cast(mip), &surface) != D3D_OK) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get surface level failed", + "D3D9Texture::_createSurfaceList"); + + D3D9HardwarePixelBuffer* currPixelBuffer = GETLEVEL(0, mip); + + if (mip == 0 && mNumRequestedMipmaps != 0 && (mUsage & TU_AUTOMIPMAP)) + currPixelBuffer->_setMipmapping(true, mMipmapsHardwareGenerated); + + currPixelBuffer->bind(d3d9Device, surface, textureResources->pFSAASurface, + mHwGammaWriteSupported, mFSAA, mName, textureResources->pBaseTex); + + // decrement reference count, the GetSurfaceLevel call increments this + // this is safe because the pixel buffer keeps a reference as well + surface->Release(); + } + + break; + case TEX_TYPE_CUBE_MAP: + assert(textureResources->pCubeTex); + // For all faces and mipmaps, store surfaces as HardwarePixelBufferSharedPtr + for(face=0; face<6; ++face) + { + for(mip=0; mip<=mNumMipmaps; ++mip) + { + if(textureResources->pCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, static_cast(mip), &surface) != D3D_OK) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get cubemap surface failed", + "D3D9Texture::getBuffer"); + + D3D9HardwarePixelBuffer* currPixelBuffer = GETLEVEL(face, mip); + + + if (mip == 0 && mNumRequestedMipmaps != 0 && (mUsage & TU_AUTOMIPMAP)) + currPixelBuffer->_setMipmapping(true, mMipmapsHardwareGenerated); + + currPixelBuffer->bind(d3d9Device, surface, textureResources->pFSAASurface, + mHwGammaWriteSupported, mFSAA, mName, textureResources->pBaseTex); + + // decrement reference count, the GetSurfaceLevel call increments this + // this is safe because the pixel buffer keeps a reference as well + surface->Release(); + } + } + break; + case TEX_TYPE_3D: + assert(textureResources->pVolumeTex); + // For all mipmaps, store surfaces as HardwarePixelBufferSharedPtr + for(mip=0; mip<=mNumMipmaps; ++mip) + { + if(textureResources->pVolumeTex->GetVolumeLevel(static_cast(mip), &volume) != D3D_OK) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get volume level failed", + "D3D9Texture::getBuffer"); + + D3D9HardwarePixelBuffer* currPixelBuffer = GETLEVEL(0, mip); + + currPixelBuffer->bind(d3d9Device, volume, textureResources->pBaseTex); + + if (mip == 0 && mNumRequestedMipmaps != 0 && (mUsage & TU_AUTOMIPMAP)) + currPixelBuffer->_setMipmapping(true, mMipmapsHardwareGenerated); + + // decrement reference count, the GetSurfaceLevel call increments this + // this is safe because the pixel buffer keeps a reference as well + volume->Release(); + } + break; + }; + } + #undef GETLEVEL + /****************************************************************************************/ + HardwarePixelBufferSharedPtr D3D9Texture::getBuffer(size_t face, size_t mipmap) + { + if(face >= getNumFaces()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "A three dimensional cube has six faces", + "D3D9Texture::getBuffer"); + if(mipmap > mNumMipmaps) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range", + "D3D9Texture::getBuffer"); + size_t idx = face*(mNumMipmaps+1) + mipmap; + + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); + TextureResources* textureResources = getTextureResources(d3d9Device); + if (textureResources == NULL || textureResources->pBaseTex == NULL) + { + createTextureResources(d3d9Device); + textureResources = getTextureResources(d3d9Device); + } + + assert(textureResources != NULL); + assert(idx < mSurfaceList.size()); + return mSurfaceList[idx]; + } + //--------------------------------------------------------------------- + bool D3D9Texture::useDefaultPool() + { + // Determine D3D pool to use + // Use managed unless we're a render target or user has asked for + // a dynamic texture, and device supports D3DUSAGE_DYNAMIC (because default pool + // resources without the dynamic flag are not lockable) + // or use if we are using directX9Ex as there is no managed pool under it. + return (D3D9RenderSystem::isDirectX9Ex()) || (mUsage & TU_RENDERTARGET) || ((mUsage & TU_DYNAMIC) && mDynamicTextures); + } + + //--------------------------------------------------------------------- + void D3D9Texture::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if (D3D9RenderSystem::getResourceManager()->getCreationPolicy() == RCP_CREATE_ON_ALL_DEVICES) + { + try + { + createTextureResources(d3d9Device); + } + catch (...) + { + mLoadingState.set(LOADSTATE_UNLOADED); + LogManager::getSingleton().stream() << "Warning: Failed to restore texture " << getName() + << " on DeviceCreate."; + } + } + } + + //--------------------------------------------------------------------- + void D3D9Texture::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.find(d3d9Device); + + if (it != mMapDeviceToTextureResources.end()) + { + StringStream ss; + + ss << "D3D9 device: 0x[" << d3d9Device << "] destroy. Releasing D3D9 texture: " << mName; + LogManager::getSingleton().logMessage(ss.str()); + + TextureResources* textureResource = it->second; + + // Destroy surfaces from each mip level. + for(unsigned int i = 0; i < mSurfaceList.size(); ++i) + { + D3D9HardwarePixelBuffer* pixelBuffer = static_cast(mSurfaceList[i].get()); + + pixelBuffer->destroyBufferResources(d3d9Device); + } + + // Just free any internal resources, don't call unload() here + // because we want the un-touched resource to keep its unloaded status + // after device reset. + freeTextureResources(d3d9Device, textureResource); + + OGRE_DELETE_T(textureResource, TextureResources, MEMCATEGORY_RENDERSYS); + + mMapDeviceToTextureResources.erase(it); + + LogManager::getSingleton().logMessage("Released D3D9 texture: " + mName); + } + } + + //--------------------------------------------------------------------- + void D3D9Texture::notifyOnDeviceLost(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if(mD3DPool == D3DPOOL_DEFAULT) + { + DeviceToTextureResourcesIterator it = mMapDeviceToTextureResources.find(d3d9Device); + + if (it != mMapDeviceToTextureResources.end()) + { + StringStream ss; + + ss << "D3D9 device: 0x[" << d3d9Device << "] lost. Releasing D3D9 texture: " << mName; + LogManager::getSingleton().logMessage(ss.str()); + + TextureResources* textureResource = it->second; + + // Just free any internal resources, don't call unload() here + // because we want the un-touched resource to keep its unloaded status + // after device reset. + freeTextureResources(d3d9Device, textureResource); + + LogManager::getSingleton().logMessage("Released D3D9 texture: " + mName); + } + } + } + + //--------------------------------------------------------------------- + void D3D9Texture::notifyOnDeviceReset(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + if(mD3DPool == D3DPOOL_DEFAULT) + { + createTextureResources(d3d9Device); + } + } + + //--------------------------------------------------------------------- + IDirect3DBaseTexture9* D3D9Texture::getTexture() + { + TextureResources* textureResources; + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); + + textureResources = getTextureResources(d3d9Device); + if (textureResources == NULL || textureResources->pBaseTex == NULL) + { + createTextureResources(d3d9Device); + textureResources = getTextureResources(d3d9Device); + } + assert(textureResources); + assert(textureResources->pBaseTex); + + return textureResources->pBaseTex; + } + + //--------------------------------------------------------------------- + IDirect3DTexture9* D3D9Texture::getNormTexture() + { + TextureResources* textureResources; + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); + + textureResources = getTextureResources(d3d9Device); + if (textureResources == NULL || textureResources->pNormTex == NULL) + { + createTextureResources(d3d9Device); + textureResources = getTextureResources(d3d9Device); + } + assert(textureResources); + assert(textureResources->pNormTex); + + return textureResources->pNormTex; + } + + //--------------------------------------------------------------------- + IDirect3DCubeTexture9* D3D9Texture::getCubeTexture() + { + TextureResources* textureResources; + IDirect3DDevice9* d3d9Device = D3D9RenderSystem::getActiveD3D9Device(); + + textureResources = getTextureResources(d3d9Device); + if (textureResources == NULL || textureResources->pCubeTex) + { + createTextureResources(d3d9Device); + textureResources = getTextureResources(d3d9Device); + } + assert(textureResources); + assert(textureResources->pCubeTex); + + return textureResources->pCubeTex; + } + + /****************************************************************************************/ + D3D9RenderTexture::D3D9RenderTexture(const String &name, + D3D9HardwarePixelBuffer *buffer, + bool writeGamma, + uint fsaa) : RenderTexture(buffer, 0) + { + mName = name; + mHwGamma = writeGamma; + mFSAA = fsaa; + } + //--------------------------------------------------------------------- + void D3D9RenderTexture::update(bool swap) + { + D3D9DeviceManager* deviceManager = D3D9RenderSystem::getDeviceManager(); + D3D9Device* currRenderWindowDevice = deviceManager->getActiveRenderTargetDevice(); + + if (currRenderWindowDevice != NULL) + { + if (currRenderWindowDevice->isDeviceLost() == false) + RenderTexture::update(swap); + } + else + { + for (UINT i=0; i < deviceManager->getDeviceCount(); ++i) + { + D3D9Device* device = deviceManager->getDevice(i); + + if (device->isDeviceLost() == false) + { + deviceManager->setActiveRenderTargetDevice(device); + RenderTexture::update(swap); + deviceManager->setActiveRenderTargetDevice(NULL); + } + } + } + } + //--------------------------------------------------------------------- + void D3D9RenderTexture::getCustomAttribute( const String& name, void *pData ) + { + if(name == "DDBACKBUFFER") + { + if (mFSAA > 0) + { + // rendering to AA surface + IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData; + *pSurf = static_cast(mBuffer)->getFSAASurface(D3D9RenderSystem::getActiveD3D9Device()); + return; + } + else + { + IDirect3DSurface9 ** pSurf = (IDirect3DSurface9 **)pData; + *pSurf = static_cast(mBuffer)->getSurface(D3D9RenderSystem::getActiveD3D9Device()); + return; + } + } + else if(name == "HWND") + { + HWND *pHwnd = (HWND*)pData; + *pHwnd = NULL; + return; + } + else if(name == "BUFFER") + { + *static_cast(pData) = mBuffer; + return; + } + } + //--------------------------------------------------------------------- + void D3D9RenderTexture::swapBuffers() + { + // Only needed if we have to blit from AA surface + if (mFSAA > 0) + { + D3D9DeviceManager* deviceManager = D3D9RenderSystem::getDeviceManager(); + D3D9HardwarePixelBuffer* buf = static_cast(mBuffer); + + for (UINT i=0; i < deviceManager->getDeviceCount(); ++i) + { + D3D9Device* device = deviceManager->getDevice(i); + + if (device->isDeviceLost() == false) + { + IDirect3DDevice9* d3d9Device = device->getD3D9Device(); + + HRESULT hr = d3d9Device->StretchRect(buf->getFSAASurface(d3d9Device), 0, + buf->getSurface(d3d9Device), 0, D3DTEXF_NONE); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Unable to copy AA buffer to final buffer: " + String(DXGetErrorDescription(hr)), + "D3D9RenderTexture::swapBuffers"); + } + } + } + } + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9TextureManager.cpp b/RenderSystems/Direct3D9/src/OgreD3D9TextureManager.cpp index 21409513ed3..4b8ee209f01 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9TextureManager.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9TextureManager.cpp @@ -36,69 +36,69 @@ THE SOFTWARE. namespace Ogre { - D3D9TextureManager::D3D9TextureManager() : TextureManager() - { + D3D9TextureManager::D3D9TextureManager() : TextureManager() + { // register with group manager ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); - } - - D3D9TextureManager::~D3D9TextureManager() - { + } + + D3D9TextureManager::~D3D9TextureManager() + { // unregister with group manager ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); - } + } Resource* D3D9TextureManager::createImpl(const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* createParams) { - D3D9Texture* ret = OGRE_NEW D3D9Texture(this, name, handle, group, isManual, loader); - return ret; + D3D9Texture* ret = OGRE_NEW D3D9Texture(this, name, handle, group, isManual, loader); + return ret; } - PixelFormat D3D9TextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage) - { - // Basic filtering - D3DFORMAT d3dPF = D3D9Mappings::_getPF(D3D9Mappings::_getClosestSupportedPF(format)); + PixelFormat D3D9TextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage) + { + // Basic filtering + D3DFORMAT d3dPF = D3D9Mappings::_getPF(D3D9Mappings::_getClosestSupportedPF(format)); - // Calculate usage - DWORD d3dusage = 0; - D3DPOOL pool = D3DPOOL_MANAGED; - if (D3D9RenderSystem::isDirectX9Ex()) - { - pool = D3DPOOL_DEFAULT; - } - if (usage & TU_RENDERTARGET) - { - d3dusage |= D3DUSAGE_RENDERTARGET; - pool = D3DPOOL_DEFAULT; - } - if (usage & TU_DYNAMIC) - { - d3dusage |= D3DUSAGE_DYNAMIC; - pool = D3DPOOL_DEFAULT; - } + // Calculate usage + DWORD d3dusage = 0; + D3DPOOL pool = D3DPOOL_MANAGED; + if (D3D9RenderSystem::isDirectX9Ex()) + { + pool = D3DPOOL_DEFAULT; + } + if (usage & TU_RENDERTARGET) + { + d3dusage |= D3DUSAGE_RENDERTARGET; + pool = D3DPOOL_DEFAULT; + } + if (usage & TU_DYNAMIC) + { + d3dusage |= D3DUSAGE_DYNAMIC; + pool = D3DPOOL_DEFAULT; + } - IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); + IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); - // Use D3DX to adjust pixel format - switch(ttype) - { - case TEX_TYPE_1D: - case TEX_TYPE_2D: - D3DXCheckTextureRequirements(pCurDevice, NULL, NULL, NULL, d3dusage, &d3dPF, pool); - break; - case TEX_TYPE_3D: - D3DXCheckVolumeTextureRequirements(pCurDevice, NULL, NULL, NULL, NULL, d3dusage, &d3dPF, pool); - break; - case TEX_TYPE_CUBE_MAP: - D3DXCheckCubeTextureRequirements(pCurDevice, NULL, NULL, d3dusage, &d3dPF, pool); - break; - }; + // Use D3DX to adjust pixel format + switch(ttype) + { + case TEX_TYPE_1D: + case TEX_TYPE_2D: + D3DXCheckTextureRequirements(pCurDevice, NULL, NULL, NULL, d3dusage, &d3dPF, pool); + break; + case TEX_TYPE_3D: + D3DXCheckVolumeTextureRequirements(pCurDevice, NULL, NULL, NULL, NULL, d3dusage, &d3dPF, pool); + break; + case TEX_TYPE_CUBE_MAP: + D3DXCheckCubeTextureRequirements(pCurDevice, NULL, NULL, d3dusage, &d3dPF, pool); + break; + }; - return D3D9Mappings::_getPF(d3dPF); - } + return D3D9Mappings::_getPF(d3dPF); + } bool D3D9TextureManager::isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage, bool preciseFormatOnly) diff --git a/RenderSystems/Direct3D9/src/OgreD3D9VertexDeclaration.cpp b/RenderSystems/Direct3D9/src/OgreD3D9VertexDeclaration.cpp index efd0caba758..0f0a407030f 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9VertexDeclaration.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9VertexDeclaration.cpp @@ -34,7 +34,7 @@ THE SOFTWARE. namespace Ogre { //----------------------------------------------------------------------- - D3D9VertexDeclaration::D3D9VertexDeclaration() : mLastUsedGlobalDeclaration(0), mUsedGlobalDeclaration(false) + D3D9VertexDeclaration::D3D9VertexDeclaration() : mLastUsedGlobalDeclaration(0), mUsedGlobalDeclaration(false) { } @@ -65,79 +65,79 @@ namespace Ogre { VertexDeclaration::removeElement(elem_index); releaseDeclaration(); } - //----------------------------------------------------------------------- - void D3D9VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index) - { - VertexDeclaration::removeElement(semantic, index); - releaseDeclaration(); - } - //----------------------------------------------------------------------- - void D3D9VertexDeclaration::removeAllElements(void) - { - VertexDeclaration::removeAllElements(); - releaseDeclaration(); - } + //----------------------------------------------------------------------- + void D3D9VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index) + { + VertexDeclaration::removeElement(semantic, index); + releaseDeclaration(); + } + //----------------------------------------------------------------------- + void D3D9VertexDeclaration::removeAllElements(void) + { + VertexDeclaration::removeAllElements(); + releaseDeclaration(); + } //----------------------------------------------------------------------- void D3D9VertexDeclaration::modifyElement(unsigned short elem_index, unsigned short source, size_t offset, VertexElementType theType, VertexElementSemantic semantic, unsigned short index) { VertexDeclaration::modifyElement(elem_index, source, offset, theType, semantic, index); - releaseDeclaration(); + releaseDeclaration(); } - //----------------------------------------------------------------------- - void D3D9VertexDeclaration::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) - { - - } + //----------------------------------------------------------------------- + void D3D9VertexDeclaration::notifyOnDeviceCreate(IDirect3DDevice9* d3d9Device) + { + + } - //----------------------------------------------------------------------- - void D3D9VertexDeclaration::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION + //----------------------------------------------------------------------- + void D3D9VertexDeclaration::notifyOnDeviceDestroy(IDirect3DDevice9* d3d9Device) + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION - DeviceToDeclarationIterator it = mMapDeviceToDeclaration.find(d3d9Device); + DeviceToDeclarationIterator it = mMapDeviceToDeclaration.find(d3d9Device); - if (it != mMapDeviceToDeclaration.end()) - { - SAFE_RELEASE(it->second); - mMapDeviceToDeclaration.erase(it); - } - } + if (it != mMapDeviceToDeclaration.end()) + { + SAFE_RELEASE(it->second); + mMapDeviceToDeclaration.erase(it); + } + } //----------------------------------------------------------------------- IDirect3DVertexDeclaration9* D3D9VertexDeclaration::getD3DVertexDeclaration( VertexDeclaration * globalDeclaration, bool useGlobalInstancingVertexBufferIsAvailable) { - if (mLastUsedGlobalDeclaration != globalDeclaration || + if (mLastUsedGlobalDeclaration != globalDeclaration || useGlobalInstancingVertexBufferIsAvailable != mUsedGlobalDeclaration ) - { - releaseDeclaration(); - mLastUsedGlobalDeclaration = globalDeclaration; + { + releaseDeclaration(); + mLastUsedGlobalDeclaration = globalDeclaration; mUsedGlobalDeclaration = useGlobalInstancingVertexBufferIsAvailable; - } + } - IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); - DeviceToDeclarationIterator it = mMapDeviceToDeclaration.find(pCurDevice); - IDirect3DVertexDeclaration9* lpVertDecl = NULL; + IDirect3DDevice9* pCurDevice = D3D9RenderSystem::getActiveD3D9Device(); + DeviceToDeclarationIterator it = mMapDeviceToDeclaration.find(pCurDevice); + IDirect3DVertexDeclaration9* lpVertDecl = NULL; - // Case we have to create the declaration for this device. - if (it == mMapDeviceToDeclaration.end() || it->second == NULL) - { + // Case we have to create the declaration for this device. + if (it == mMapDeviceToDeclaration.end() || it->second == NULL) + { size_t d3delemsSize = mElementList.size() + 1; if(mLastUsedGlobalDeclaration != NULL && mUsedGlobalDeclaration ) { d3delemsSize += globalDeclaration->getElementCount(); } - D3DVERTEXELEMENT9* d3delems = OGRE_ALLOC_T(D3DVERTEXELEMENT9, d3delemsSize, MEMCATEGORY_RENDERSYS); + D3DVERTEXELEMENT9* d3delems = OGRE_ALLOC_T(D3DVERTEXELEMENT9, d3delemsSize, MEMCATEGORY_RENDERSYS); - VertexElementList::const_iterator i, iend; - unsigned int idx; + VertexElementList::const_iterator i, iend; + unsigned int idx; size_t maxSource = 0; - iend = mElementList.end(); - for (idx = 0, i = mElementList.begin(); i != iend; ++i, ++idx) - { + iend = mElementList.end(); + for (idx = 0, i = mElementList.begin(); i != iend; ++i, ++idx) + { const VertexElement & element = *i; D3DVERTEXELEMENT9 & dxElement = d3delems[idx]; convertElement(element, dxElement); @@ -145,67 +145,67 @@ namespace Ogre { { maxSource = element.getSource(); } - } + } if(mLastUsedGlobalDeclaration != NULL && mUsedGlobalDeclaration ) { iend = globalDeclaration->getElements().end(); - for (i = globalDeclaration->getElements().begin(); i != iend; ++i, ++idx) - { + for (i = globalDeclaration->getElements().begin(); i != iend; ++i, ++idx) + { const VertexElement & element = *i; D3DVERTEXELEMENT9 & dxElement = d3delems[idx]; convertElement(element, dxElement); dxElement.Stream = maxSource + 1; - } + } } - // Add terminator - d3delems[idx].Stream = 0xff; - d3delems[idx].Offset = 0; - d3delems[idx].Type = D3DDECLTYPE_UNUSED; - d3delems[idx].Method = 0; - d3delems[idx].Usage = 0; - d3delems[idx].UsageIndex = 0; - - - HRESULT hr = pCurDevice->CreateVertexDeclaration(d3delems, &lpVertDecl); - - if (FAILED(hr)) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Cannot create D3D9 vertex declaration: " + - Root::getSingleton().getErrorDescription(hr), - "Direct3D9VertexDeclaration::getD3DVertexDeclaration"); - } - - OGRE_FREE(d3delems, MEMCATEGORY_RENDERSYS); - - mMapDeviceToDeclaration[pCurDevice] = lpVertDecl; - } - - // Declaration already exits. - else - { - lpVertDecl = mMapDeviceToDeclaration[pCurDevice]; - } - + // Add terminator + d3delems[idx].Stream = 0xff; + d3delems[idx].Offset = 0; + d3delems[idx].Type = D3DDECLTYPE_UNUSED; + d3delems[idx].Method = 0; + d3delems[idx].Usage = 0; + d3delems[idx].UsageIndex = 0; + + + HRESULT hr = pCurDevice->CreateVertexDeclaration(d3delems, &lpVertDecl); + + if (FAILED(hr)) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Cannot create D3D9 vertex declaration: " + + Root::getSingleton().getErrorDescription(hr), + "Direct3D9VertexDeclaration::getD3DVertexDeclaration"); + } + + OGRE_FREE(d3delems, MEMCATEGORY_RENDERSYS); + + mMapDeviceToDeclaration[pCurDevice] = lpVertDecl; + } + + // Declaration already exits. + else + { + lpVertDecl = mMapDeviceToDeclaration[pCurDevice]; + } + return lpVertDecl; } //----------------------------------------------------------------------- - void D3D9VertexDeclaration::releaseDeclaration() - { - D3D9_DEVICE_ACCESS_CRITICAL_SECTION - - DeviceToDeclarationIterator it = mMapDeviceToDeclaration.begin(); - - while (it != mMapDeviceToDeclaration.end()) - { - SAFE_RELEASE(it->second); - ++it; - } - mMapDeviceToDeclaration.clear(); - } + void D3D9VertexDeclaration::releaseDeclaration() + { + D3D9_DEVICE_ACCESS_CRITICAL_SECTION + + DeviceToDeclarationIterator it = mMapDeviceToDeclaration.begin(); + + while (it != mMapDeviceToDeclaration.end()) + { + SAFE_RELEASE(it->second); + ++it; + } + mMapDeviceToDeclaration.clear(); + } //----------------------------------------------------------------------- void D3D9VertexDeclaration::convertElement( const VertexElement & element, D3DVERTEXELEMENT9 & dxElement ) { @@ -229,7 +229,7 @@ namespace Ogre { dxElement.UsageIndex = static_cast(element.getIndex()); } } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9VideoMode.cpp b/RenderSystems/Direct3D9/src/OgreD3D9VideoMode.cpp index 4b741b767d3..38b2387b84a 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9VideoMode.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9VideoMode.cpp @@ -29,27 +29,27 @@ THE SOFTWARE. namespace Ogre { - String D3D9VideoMode::getDescription() const - { - char tmp[128]; - unsigned int colourDepth = 16; - if( mDisplayMode.Format == D3DFMT_X8R8G8B8 || - mDisplayMode.Format == D3DFMT_A8R8G8B8 || - mDisplayMode.Format == D3DFMT_R8G8B8 ) - colourDepth = 32; - - sprintf( tmp, "%d x %d @ %d-bit colour", mDisplayMode.Width, mDisplayMode.Height, colourDepth ); - return String(tmp); - } - - unsigned int D3D9VideoMode::getColourDepth() const - { - unsigned int colourDepth = 16; - if( mDisplayMode.Format == D3DFMT_X8R8G8B8 || - mDisplayMode.Format == D3DFMT_A8R8G8B8 || - mDisplayMode.Format == D3DFMT_R8G8B8 ) - colourDepth = 32; - - return colourDepth; - } + String D3D9VideoMode::getDescription() const + { + char tmp[128]; + unsigned int colourDepth = 16; + if( mDisplayMode.Format == D3DFMT_X8R8G8B8 || + mDisplayMode.Format == D3DFMT_A8R8G8B8 || + mDisplayMode.Format == D3DFMT_R8G8B8 ) + colourDepth = 32; + + sprintf( tmp, "%d x %d @ %d-bit colour", mDisplayMode.Width, mDisplayMode.Height, colourDepth ); + return String(tmp); + } + + unsigned int D3D9VideoMode::getColourDepth() const + { + unsigned int colourDepth = 16; + if( mDisplayMode.Format == D3DFMT_X8R8G8B8 || + mDisplayMode.Format == D3DFMT_A8R8G8B8 || + mDisplayMode.Format == D3DFMT_R8G8B8 ) + colourDepth = 32; + + return colourDepth; + } } diff --git a/RenderSystems/Direct3D9/src/OgreD3D9VideoModeList.cpp b/RenderSystems/Direct3D9/src/OgreD3D9VideoModeList.cpp index 7215a63ba56..8605617d389 100644 --- a/RenderSystems/Direct3D9/src/OgreD3D9VideoModeList.cpp +++ b/RenderSystems/Direct3D9/src/OgreD3D9VideoModeList.cpp @@ -31,116 +31,116 @@ THE SOFTWARE. namespace Ogre { - D3D9VideoModeList::D3D9VideoModeList( D3D9Driver* pDriver ) - { - if( NULL == pDriver ) - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "pDriver parameter is NULL", "D3D9VideoModeList::D3D9VideoModeList" ); - - mDriver = pDriver; - enumerate(); - } - - D3D9VideoModeList::~D3D9VideoModeList() - { - mDriver = NULL; - mModeList.clear(); - } - - BOOL D3D9VideoModeList::enumerate() - { - UINT iMode; - IDirect3D9* pD3D = D3D9RenderSystem::getDirect3D9(); - UINT adapter = mDriver->getAdapterNumber(); - - for( iMode=0; iMode < pD3D->GetAdapterModeCount( adapter, D3DFMT_R5G6B5 ); iMode++ ) - { - D3DDISPLAYMODE displayMode; - pD3D->EnumAdapterModes( adapter, D3DFMT_R5G6B5, iMode, &displayMode ); - - // Filter out low-resolutions - if( displayMode.Width < 640 || displayMode.Height < 400 ) - continue; - - // Check to see if it is already in the list (to filter out refresh rates) - BOOL found = FALSE; - vector::type::iterator it; - for( it = mModeList.begin(); it != mModeList.end(); ++it ) - { - D3DDISPLAYMODE oldDisp = it->getDisplayMode(); - if( oldDisp.Width == displayMode.Width && - oldDisp.Height == displayMode.Height && - oldDisp.Format == displayMode.Format ) - { - // Check refresh rate and favour higher if poss - if (oldDisp.RefreshRate < displayMode.RefreshRate) - it->increaseRefreshRate(displayMode.RefreshRate); - found = TRUE; - break; - } - } - - if( !found ) - mModeList.push_back( D3D9VideoMode( displayMode ) ); - } - - for( iMode=0; iMode < pD3D->GetAdapterModeCount( adapter, D3DFMT_X8R8G8B8 ); iMode++ ) - { - D3DDISPLAYMODE displayMode; - pD3D->EnumAdapterModes( adapter, D3DFMT_X8R8G8B8, iMode, &displayMode ); - - // Filter out low-resolutions - if( displayMode.Width < 640 || displayMode.Height < 400 ) - continue; - - // Check to see if it is already in the list (to filter out refresh rates) - BOOL found = FALSE; - vector::type::iterator it; - for( it = mModeList.begin(); it != mModeList.end(); ++it ) - { - D3DDISPLAYMODE oldDisp = it->getDisplayMode(); - if( oldDisp.Width == displayMode.Width && - oldDisp.Height == displayMode.Height && - oldDisp.Format == displayMode.Format ) - { - // Check refresh rate and favour higher if poss - if (oldDisp.RefreshRate < displayMode.RefreshRate) - it->increaseRefreshRate(displayMode.RefreshRate); - found = TRUE; - break; - } - } - - if( !found ) - mModeList.push_back( D3D9VideoMode( displayMode ) ); - } - - return TRUE; - } - - size_t D3D9VideoModeList::count() - { - return mModeList.size(); - } - - D3D9VideoMode* D3D9VideoModeList::item( size_t index ) - { - vector::type::iterator p = mModeList.begin(); - - return &p[index]; - } - - D3D9VideoMode* D3D9VideoModeList::item( const String &name ) - { - vector::type::iterator it = mModeList.begin(); - if (it == mModeList.end()) - return NULL; - - for (;it != mModeList.end(); ++it) - { - if (it->getDescription() == name) - return &(*it); - } - - return NULL; - } + D3D9VideoModeList::D3D9VideoModeList( D3D9Driver* pDriver ) + { + if( NULL == pDriver ) + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "pDriver parameter is NULL", "D3D9VideoModeList::D3D9VideoModeList" ); + + mDriver = pDriver; + enumerate(); + } + + D3D9VideoModeList::~D3D9VideoModeList() + { + mDriver = NULL; + mModeList.clear(); + } + + BOOL D3D9VideoModeList::enumerate() + { + UINT iMode; + IDirect3D9* pD3D = D3D9RenderSystem::getDirect3D9(); + UINT adapter = mDriver->getAdapterNumber(); + + for( iMode=0; iMode < pD3D->GetAdapterModeCount( adapter, D3DFMT_R5G6B5 ); iMode++ ) + { + D3DDISPLAYMODE displayMode; + pD3D->EnumAdapterModes( adapter, D3DFMT_R5G6B5, iMode, &displayMode ); + + // Filter out low-resolutions + if( displayMode.Width < 640 || displayMode.Height < 400 ) + continue; + + // Check to see if it is already in the list (to filter out refresh rates) + BOOL found = FALSE; + vector::type::iterator it; + for( it = mModeList.begin(); it != mModeList.end(); ++it ) + { + D3DDISPLAYMODE oldDisp = it->getDisplayMode(); + if( oldDisp.Width == displayMode.Width && + oldDisp.Height == displayMode.Height && + oldDisp.Format == displayMode.Format ) + { + // Check refresh rate and favour higher if poss + if (oldDisp.RefreshRate < displayMode.RefreshRate) + it->increaseRefreshRate(displayMode.RefreshRate); + found = TRUE; + break; + } + } + + if( !found ) + mModeList.push_back( D3D9VideoMode( displayMode ) ); + } + + for( iMode=0; iMode < pD3D->GetAdapterModeCount( adapter, D3DFMT_X8R8G8B8 ); iMode++ ) + { + D3DDISPLAYMODE displayMode; + pD3D->EnumAdapterModes( adapter, D3DFMT_X8R8G8B8, iMode, &displayMode ); + + // Filter out low-resolutions + if( displayMode.Width < 640 || displayMode.Height < 400 ) + continue; + + // Check to see if it is already in the list (to filter out refresh rates) + BOOL found = FALSE; + vector::type::iterator it; + for( it = mModeList.begin(); it != mModeList.end(); ++it ) + { + D3DDISPLAYMODE oldDisp = it->getDisplayMode(); + if( oldDisp.Width == displayMode.Width && + oldDisp.Height == displayMode.Height && + oldDisp.Format == displayMode.Format ) + { + // Check refresh rate and favour higher if poss + if (oldDisp.RefreshRate < displayMode.RefreshRate) + it->increaseRefreshRate(displayMode.RefreshRate); + found = TRUE; + break; + } + } + + if( !found ) + mModeList.push_back( D3D9VideoMode( displayMode ) ); + } + + return TRUE; + } + + size_t D3D9VideoModeList::count() + { + return mModeList.size(); + } + + D3D9VideoMode* D3D9VideoModeList::item( size_t index ) + { + vector::type::iterator p = mModeList.begin(); + + return &p[index]; + } + + D3D9VideoMode* D3D9VideoModeList::item( const String &name ) + { + vector::type::iterator it = mModeList.begin(); + if (it == mModeList.end()) + return NULL; + + for (;it != mModeList.end(); ++it) + { + if (it->getDescription() == name) + return &(*it); + } + + return NULL; + } } diff --git a/RenderSystems/GL/include/GL/glext.h b/RenderSystems/GL/include/GL/glext.h index e11736d6428..337cd6c9ecd 100644 --- a/RenderSystems/GL/include/GL/glext.h +++ b/RenderSystems/GL/include/GL/glext.h @@ -2864,8 +2864,8 @@ typedef ptrdiff_t GLsizeiptrARB; #ifndef GL_ARB_shader_objects /* GL types for handling shader object handles and characters */ -typedef char GLcharARB; /* native character */ -typedef unsigned int GLhandleARB; /* shader object handle */ +typedef char GLcharARB; /* native character */ +typedef unsigned int GLhandleARB; /* shader object handle */ #endif #ifndef GL_NV_half_float diff --git a/RenderSystems/GL/include/GL/glxext.h b/RenderSystems/GL/include/GL/glxext.h index 758cf83a4a2..ee206987ec8 100644 --- a/RenderSystems/GL/include/GL/glxext.h +++ b/RenderSystems/GL/include/GL/glxext.h @@ -318,16 +318,16 @@ typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; typedef XID GLXPbufferSGIX; typedef struct { int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came for SendEvent request */ - Display *display; /* display the event was read from */ - GLXDrawable drawable; /* i.d. of Drawable */ - int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ - int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ - unsigned int mask; /* mask indicating which buffers are affected*/ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* i.d. of Drawable */ + int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ + int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ + unsigned int mask; /* mask indicating which buffers are affected*/ int x, y; int width, height; - int count; /* if nonzero, at least this many more */ + int count; /* if nonzero, at least this many more */ } GLXBufferClobberEventSGIX; #endif diff --git a/RenderSystems/GL/include/GL/glxtokens.h b/RenderSystems/GL/include/GL/glxtokens.h index e30c579b3e8..d151f7351ca 100644 --- a/RenderSystems/GL/include/GL/glxtokens.h +++ b/RenderSystems/GL/include/GL/glxtokens.h @@ -48,54 +48,54 @@ extern "C" { /* ** Visual Config Attributes (glXGetConfig, glXGetFBConfigAttrib) */ -#define GLX_USE_GL 1 /* support GLX rendering */ -#define GLX_BUFFER_SIZE 2 /* depth of the color buffer */ -#define GLX_LEVEL 3 /* level in plane stacking */ -#define GLX_RGBA 4 /* true if RGBA mode */ -#define GLX_DOUBLEBUFFER 5 /* double buffering supported */ -#define GLX_STEREO 6 /* stereo buffering supported */ -#define GLX_AUX_BUFFERS 7 /* number of aux buffers */ -#define GLX_RED_SIZE 8 /* number of red component bits */ -#define GLX_GREEN_SIZE 9 /* number of green component bits */ -#define GLX_BLUE_SIZE 10 /* number of blue component bits */ -#define GLX_ALPHA_SIZE 11 /* number of alpha component bits */ -#define GLX_DEPTH_SIZE 12 /* number of depth bits */ -#define GLX_STENCIL_SIZE 13 /* number of stencil bits */ -#define GLX_ACCUM_RED_SIZE 14 /* number of red accum bits */ -#define GLX_ACCUM_GREEN_SIZE 15 /* number of green accum bits */ -#define GLX_ACCUM_BLUE_SIZE 16 /* number of blue accum bits */ -#define GLX_ACCUM_ALPHA_SIZE 17 /* number of alpha accum bits */ +#define GLX_USE_GL 1 /* support GLX rendering */ +#define GLX_BUFFER_SIZE 2 /* depth of the color buffer */ +#define GLX_LEVEL 3 /* level in plane stacking */ +#define GLX_RGBA 4 /* true if RGBA mode */ +#define GLX_DOUBLEBUFFER 5 /* double buffering supported */ +#define GLX_STEREO 6 /* stereo buffering supported */ +#define GLX_AUX_BUFFERS 7 /* number of aux buffers */ +#define GLX_RED_SIZE 8 /* number of red component bits */ +#define GLX_GREEN_SIZE 9 /* number of green component bits */ +#define GLX_BLUE_SIZE 10 /* number of blue component bits */ +#define GLX_ALPHA_SIZE 11 /* number of alpha component bits */ +#define GLX_DEPTH_SIZE 12 /* number of depth bits */ +#define GLX_STENCIL_SIZE 13 /* number of stencil bits */ +#define GLX_ACCUM_RED_SIZE 14 /* number of red accum bits */ +#define GLX_ACCUM_GREEN_SIZE 15 /* number of green accum bits */ +#define GLX_ACCUM_BLUE_SIZE 16 /* number of blue accum bits */ +#define GLX_ACCUM_ALPHA_SIZE 17 /* number of alpha accum bits */ /* ** FBConfig-specific attributes */ -#define GLX_X_VISUAL_TYPE 0x22 -#define GLX_CONFIG_CAVEAT 0x20 /* Like visual_info VISUAL_CAVEAT_EXT */ -#define GLX_TRANSPARENT_TYPE 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE 0x24 -#define GLX_TRANSPARENT_RED_VALUE 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 -#define GLX_DRAWABLE_TYPE 0x8010 -#define GLX_RENDER_TYPE 0x8011 -#define GLX_X_RENDERABLE 0x8012 -#define GLX_FBCONFIG_ID 0x8013 -#define GLX_MAX_PBUFFER_WIDTH 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT 0x8017 -#define GLX_MAX_PBUFFER_PIXELS 0x8018 -#define GLX_VISUAL_ID 0x800B +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_CONFIG_CAVEAT 0x20 /* Like visual_info VISUAL_CAVEAT_EXT */ +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_VISUAL_ID 0x800B /* ** Error return values from glXGetConfig. Success is indicated by ** a value of 0. */ -#define GLX_BAD_SCREEN 1 /* screen # is bad */ -#define GLX_BAD_ATTRIBUTE 2 /* attribute to get is bad */ -#define GLX_NO_EXTENSION 3 /* no glx extension on server */ -#define GLX_BAD_VISUAL 4 /* visual # not known by GLX */ -#define GLX_BAD_CONTEXT 5 /* returned only by import_context EXT? */ -#define GLX_BAD_VALUE 6 /* returned only by glXSwapIntervalSGI? */ -#define GLX_BAD_ENUM 7 /* unused? */ +#define GLX_BAD_SCREEN 1 /* screen # is bad */ +#define GLX_BAD_ATTRIBUTE 2 /* attribute to get is bad */ +#define GLX_NO_EXTENSION 3 /* no glx extension on server */ +#define GLX_BAD_VISUAL 4 /* visual # not known by GLX */ +#define GLX_BAD_CONTEXT 5 /* returned only by import_context EXT? */ +#define GLX_BAD_VALUE 6 /* returned only by glXSwapIntervalSGI? */ +#define GLX_BAD_ENUM 7 /* unused? */ /* FBConfig attribute values */ @@ -103,120 +103,120 @@ extern "C" { ** Generic "don't care" value for glX ChooseFBConfig attributes (except ** GLX_LEVEL) */ -#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_DONT_CARE 0xFFFFFFFF /* GLX_RENDER_TYPE bits */ -#define GLX_RGBA_BIT 0x00000001 -#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 /* GLX_DRAWABLE_TYPE bits */ -#define GLX_WINDOW_BIT 0x00000001 -#define GLX_PIXMAP_BIT 0x00000002 -#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PBUFFER_BIT 0x00000004 /* GLX_CONFIG_CAVEAT attribute values */ -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_NON_CONFORMANT_CONFIG 0x800D /* GLX_X_VISUAL_TYPE attribute values */ -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_PSEUDO_COLOR 0x8004 -#define GLX_STATIC_COLOR 0x8005 -#define GLX_GRAY_SCALE 0x8006 -#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 /* GLX_TRANSPARENT_TYPE attribute values */ -/* #define GLX_NONE 0x8000 */ -#define GLX_TRANSPARENT_RGB 0x8008 -#define GLX_TRANSPARENT_INDEX 0x8009 +/* #define GLX_NONE 0x8000 */ +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 /* glXCreateGLXPbuffer attributes */ -#define GLX_PRESERVED_CONTENTS 0x801B -#define GLX_LARGEST_PBUFFER 0x801C -#define GLX_PBUFFER_HEIGHT 0x8040 /* New for GLX 1.3 */ -#define GLX_PBUFFER_WIDTH 0x8041 /* New for GLX 1.3 */ +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_PBUFFER_HEIGHT 0x8040 /* New for GLX 1.3 */ +#define GLX_PBUFFER_WIDTH 0x8041 /* New for GLX 1.3 */ /* glXQueryGLXPBuffer attributes */ -#define GLX_WIDTH 0x801D -#define GLX_HEIGHT 0x801E -#define GLX_EVENT_MASK 0x801F +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F /* glXCreateNewContext render_type attribute values */ -#define GLX_RGBA_TYPE 0x8014 -#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 /* glXQueryContext attributes */ -/* #define GLX_FBCONFIG_ID 0x8013 */ -/* #define GLX_RENDER_TYPE 0x8011 */ -#define GLX_SCREEN 0x800C +/* #define GLX_FBCONFIG_ID 0x8013 */ +/* #define GLX_RENDER_TYPE 0x8011 */ +#define GLX_SCREEN 0x800C /* glXSelectEvent event mask bits */ -#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 /* GLXPbufferClobberEvent event_type values */ -#define GLX_DAMAGED 0x8020 -#define GLX_SAVED 0x8021 +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 /* GLXPbufferClobberEvent draw_type values */ -#define GLX_WINDOW 0x8022 -#define GLX_PBUFFER 0x8023 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 /* GLXPbufferClobberEvent buffer_mask bits */ -#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 -#define GLX_AUX_BUFFERS_BIT 0x00000010 -#define GLX_DEPTH_BUFFER_BIT 0x00000020 -#define GLX_STENCIL_BUFFER_BIT 0x00000040 -#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 /* ** Extension return values from glXGetConfig. These are also ** accepted as parameter values for glXChooseVisual. */ -#define GLX_X_VISUAL_TYPE_EXT 0x22 /* visual_info extension type */ -#define GLX_TRANSPARENT_TYPE_EXT 0x23 /* visual_info extension */ -#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 /* visual_info extension */ -#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 /* visual_info extension */ -#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 /* visual_info extension */ -#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 /* visual_info extension */ -#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 /* visual_info extension */ +#define GLX_X_VISUAL_TYPE_EXT 0x22 /* visual_info extension type */ +#define GLX_TRANSPARENT_TYPE_EXT 0x23 /* visual_info extension */ +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 /* visual_info extension */ +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 /* visual_info extension */ +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 /* visual_info extension */ +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 /* visual_info extension */ +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 /* visual_info extension */ /* Property values for visual_type */ -#define GLX_TRUE_COLOR_EXT 0x8002 -#define GLX_DIRECT_COLOR_EXT 0x8003 -#define GLX_PSEUDO_COLOR_EXT 0x8004 -#define GLX_STATIC_COLOR_EXT 0x8005 -#define GLX_GRAY_SCALE_EXT 0x8006 -#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 /* Property values for transparent pixel */ -#define GLX_NONE_EXT 0x8000 -#define GLX_TRANSPARENT_RGB_EXT 0x8008 -#define GLX_TRANSPARENT_INDEX_EXT 0x8009 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 /* Property values for visual_rating */ -#define GLX_VISUAL_CAVEAT_EXT 0x20 /* visual_rating extension type */ -#define GLX_SLOW_VISUAL_EXT 0x8001 -#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +#define GLX_VISUAL_CAVEAT_EXT 0x20 /* visual_rating extension type */ +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D /* ** Names for attributes to glXGetClientString. */ -#define GLX_VENDOR 0x1 -#define GLX_VERSION 0x2 -#define GLX_EXTENSIONS 0x3 +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_EXTENSIONS 0x3 /* ** Names for attributes to glXQueryContextInfoEXT. */ -#define GLX_SHARE_CONTEXT_EXT 0x800A /* id of share context */ -#define GLX_VISUAL_ID_EXT 0x800B /* id of context's visual */ -#define GLX_SCREEN_EXT 0x800C /* screen number */ +#define GLX_SHARE_CONTEXT_EXT 0x800A /* id of share context */ +#define GLX_VISUAL_ID_EXT 0x800B /* id of context's visual */ +#define GLX_SCREEN_EXT 0x800C /* screen number */ /* * GLX 1.4 and later: diff --git a/RenderSystems/GL/include/GLX/OgreGLXContext.h b/RenderSystems/GL/include/GLX/OgreGLXContext.h index b38bd03174a..fb8dc00177c 100644 --- a/RenderSystems/GL/include/GLX/OgreGLXContext.h +++ b/RenderSystems/GL/include/GLX/OgreGLXContext.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- This source file is part of OGRE - (Object-oriented Graphics Rendering Engine) + (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd @@ -33,30 +33,30 @@ THE SOFTWARE. namespace Ogre { - class _OgrePrivate GLXContext: public GLContext - { - public: - GLXContext(GLXGLSupport* glsupport, ::GLXFBConfig fbconfig, ::GLXDrawable drawable, ::GLXContext context = 0); - - virtual ~GLXContext(); - - /// @copydoc GLContext::setCurrent - virtual void setCurrent(); - - /// @copydoc GLContext::endCurrent - virtual void endCurrent(); - - /// @copydoc GLContext::clone - GLContext* clone() const; - - ::GLXDrawable mDrawable; - ::GLXContext mContext; - - private: - ::GLXFBConfig mFBConfig; - GLXGLSupport* mGLSupport; - bool mExternalContext; - }; + class _OgrePrivate GLXContext: public GLContext + { + public: + GLXContext(GLXGLSupport* glsupport, ::GLXFBConfig fbconfig, ::GLXDrawable drawable, ::GLXContext context = 0); + + virtual ~GLXContext(); + + /// @copydoc GLContext::setCurrent + virtual void setCurrent(); + + /// @copydoc GLContext::endCurrent + virtual void endCurrent(); + + /// @copydoc GLContext::clone + GLContext* clone() const; + + ::GLXDrawable mDrawable; + ::GLXContext mContext; + + private: + ::GLXFBConfig mFBConfig; + GLXGLSupport* mGLSupport; + bool mExternalContext; + }; } #endif diff --git a/RenderSystems/GL/include/GLX/OgreGLXGLSupport.h b/RenderSystems/GL/include/GLX/OgreGLXGLSupport.h index bd48f24e734..5c3f0ec3d6f 100644 --- a/RenderSystems/GL/include/GLX/OgreGLXGLSupport.h +++ b/RenderSystems/GL/include/GLX/OgreGLXGLSupport.h @@ -35,192 +35,192 @@ THE SOFTWARE. namespace Ogre { - class _OgrePrivate GLXGLSupport : public GLSupport - { - public: - GLXGLSupport(); - ~GLXGLSupport(); - - Atom mAtomDeleteWindow; - Atom mAtomFullScreen; - Atom mAtomState; - - /** @copydoc GLSupport::addConfig */ - void addConfig(void); - - /** @copydoc GLSupport::validateConfig */ - String validateConfig(void); - - /** @copydoc GLSupport::setConfigOption */ - void setConfigOption(const String &name, const String &value); - - /// @copydoc GLSupport::createWindow - RenderWindow* createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle); - - /// @copydoc RenderSystem::createRenderWindow - RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0); - - /// @copydoc GLSupport::createPBuffer - GLPBuffer* createPBuffer(PixelComponentType format, size_t width, size_t height); - - /** @copydoc GLSupport::start */ - void start(); - - /** @copydoc GLSupport::stop */ - void stop(); - - /** @copydoc GLSupport::initialiseExtensions */ - void initialiseExtensions(); - - /** @copydoc GLSupport::getProcAddress */ - void* getProcAddress(const String& procname); - - // The remaining functions are internal to the GLX Rendersystem: - - /** - * Get the name of the display and screen used for rendering - * - * Ogre normally opens its own connection to the X server - * and renders onto the screen where the user logged in - * - * However, if Ogre is passed a current GL context when the first - * RenderTarget is created, then it will connect to the X server - * using the same connection as that GL context and direct all - * subsequent rendering to the screen targeted by that GL context. - * - * @return Display name. - */ - String getDisplayName (void); - - /** - * Get the Display connection used for rendering - * - * This function establishes the initial connection when necessary. - * - * @return Display connection - */ - Display* getGLDisplay(void); - - /** - * Get the Display connection used for window management & events - * - * @return Display connection - */ - Display* getXDisplay(void); - - /** - * Switch video modes - * - * @param width Receiver for requested and final width - * @param height Receiver for requested and final drawable height - * @param frequency Receiver for requested and final drawable frequency - */ - void switchMode (uint& width, uint& height, short& frequency); - - /** - * Switch back to original video mode - */ - void switchMode (void); - - /** - * Loads an icon from an Ogre resource into the X Server. This currently only - * works for 24 and 32 bit displays. The image must be findable by the Ogre - * resource system, and of format PF_A8R8G8B8. - * - * @param name Name of image to load - * @param pix Receiver for the output pixmap - * @param mask Receiver for the output mask (alpha bitmap) - * @return true on success - */ - bool loadIcon(const String &name, Pixmap *pix, Pixmap *mask); - - /** - * Get the GLXFBConfig used to create a GLXContext - * - * @param context GLXContext - * @return GLXFBConfig used to create the context - */ - GLXFBConfig getFBConfigFromContext (::GLXContext context); - - /** - * Get the GLXFBConfig used to create a GLXDrawable. - * Caveat: GLX version 1.3 is needed when the drawable is a GLXPixmap - * - * @param drawable GLXDrawable - * @param width Receiver for the drawable width - * @param height Receiver for the drawable height - * @return GLXFBConfig used to create the drawable - */ - GLXFBConfig getFBConfigFromDrawable (GLXDrawable drawable, unsigned int *width, unsigned int *height); - - /** - * Select an FBConfig given a list of required and a list of desired properties - * - * @param minAttribs FBConfig attributes that must be provided with minimum values - * @param maxAttribs FBConfig attributes that are desirable with maximum values - * @return GLXFBConfig with attributes or 0 when unsupported. - */ - GLXFBConfig selectFBConfig(const int *minAttribs, const int *maxAttribs); - - /** - * Gets a GLXFBConfig compatible with a VisualID - * - * Some platforms fail to implement glXGetFBconfigFromVisualSGIX as - * part of the GLX_SGIX_fbconfig extension, but this portable - * alternative suffices for the creation of compatible contexts. - * - * @param visualid VisualID - * @return FBConfig for VisualID - */ - GLXFBConfig getFBConfigFromVisualID(VisualID visualid); - - /** - * Portable replacement for glXChooseFBConfig - */ - GLXFBConfig* chooseFBConfig(const GLint *attribList, GLint *nElements); - - /** - * Portable replacement for glXCreateNewContext - */ - ::GLXContext createNewContext(GLXFBConfig fbConfig, GLint renderType, ::GLXContext shareList, GLboolean direct) const; - - /** - * Portable replacement for glXGetFBConfigAttrib - */ - GLint getFBConfigAttrib(GLXFBConfig fbConfig, GLint attribute, GLint *value); - - /** - * Portable replacement for glXGetVisualFromFBConfig - */ - XVisualInfo* getVisualFromFBConfig(GLXFBConfig fbConfig); - - private: - /** - * Initialise GLXEW without requiring a current GL context - */ - void initialiseGLXEW(void); - - /** - * Refresh config options to reflect dependencies - */ - void refreshConfig(void); - - Display* mGLDisplay; // used for GL/GLX commands - Display* mXDisplay; // used for other X commands and events - bool mIsExternalDisplay; - - typedef std::pair ScreenSize; - typedef short Rate; - typedef std::pair VideoMode; - typedef std::vector VideoModes; - - VideoModes mVideoModes; - VideoMode mOriginalMode; - VideoMode mCurrentMode; - - StringVector mSampleLevels; - }; + class _OgrePrivate GLXGLSupport : public GLSupport + { + public: + GLXGLSupport(); + ~GLXGLSupport(); + + Atom mAtomDeleteWindow; + Atom mAtomFullScreen; + Atom mAtomState; + + /** @copydoc GLSupport::addConfig */ + void addConfig(void); + + /** @copydoc GLSupport::validateConfig */ + String validateConfig(void); + + /** @copydoc GLSupport::setConfigOption */ + void setConfigOption(const String &name, const String &value); + + /// @copydoc GLSupport::createWindow + RenderWindow* createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle); + + /// @copydoc RenderSystem::createRenderWindow + RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0); + + /// @copydoc GLSupport::createPBuffer + GLPBuffer* createPBuffer(PixelComponentType format, size_t width, size_t height); + + /** @copydoc GLSupport::start */ + void start(); + + /** @copydoc GLSupport::stop */ + void stop(); + + /** @copydoc GLSupport::initialiseExtensions */ + void initialiseExtensions(); + + /** @copydoc GLSupport::getProcAddress */ + void* getProcAddress(const String& procname); + + // The remaining functions are internal to the GLX Rendersystem: + + /** + * Get the name of the display and screen used for rendering + * + * Ogre normally opens its own connection to the X server + * and renders onto the screen where the user logged in + * + * However, if Ogre is passed a current GL context when the first + * RenderTarget is created, then it will connect to the X server + * using the same connection as that GL context and direct all + * subsequent rendering to the screen targeted by that GL context. + * + * @return Display name. + */ + String getDisplayName (void); + + /** + * Get the Display connection used for rendering + * + * This function establishes the initial connection when necessary. + * + * @return Display connection + */ + Display* getGLDisplay(void); + + /** + * Get the Display connection used for window management & events + * + * @return Display connection + */ + Display* getXDisplay(void); + + /** + * Switch video modes + * + * @param width Receiver for requested and final width + * @param height Receiver for requested and final drawable height + * @param frequency Receiver for requested and final drawable frequency + */ + void switchMode (uint& width, uint& height, short& frequency); + + /** + * Switch back to original video mode + */ + void switchMode (void); + + /** + * Loads an icon from an Ogre resource into the X Server. This currently only + * works for 24 and 32 bit displays. The image must be findable by the Ogre + * resource system, and of format PF_A8R8G8B8. + * + * @param name Name of image to load + * @param pix Receiver for the output pixmap + * @param mask Receiver for the output mask (alpha bitmap) + * @return true on success + */ + bool loadIcon(const String &name, Pixmap *pix, Pixmap *mask); + + /** + * Get the GLXFBConfig used to create a GLXContext + * + * @param context GLXContext + * @return GLXFBConfig used to create the context + */ + GLXFBConfig getFBConfigFromContext (::GLXContext context); + + /** + * Get the GLXFBConfig used to create a GLXDrawable. + * Caveat: GLX version 1.3 is needed when the drawable is a GLXPixmap + * + * @param drawable GLXDrawable + * @param width Receiver for the drawable width + * @param height Receiver for the drawable height + * @return GLXFBConfig used to create the drawable + */ + GLXFBConfig getFBConfigFromDrawable (GLXDrawable drawable, unsigned int *width, unsigned int *height); + + /** + * Select an FBConfig given a list of required and a list of desired properties + * + * @param minAttribs FBConfig attributes that must be provided with minimum values + * @param maxAttribs FBConfig attributes that are desirable with maximum values + * @return GLXFBConfig with attributes or 0 when unsupported. + */ + GLXFBConfig selectFBConfig(const int *minAttribs, const int *maxAttribs); + + /** + * Gets a GLXFBConfig compatible with a VisualID + * + * Some platforms fail to implement glXGetFBconfigFromVisualSGIX as + * part of the GLX_SGIX_fbconfig extension, but this portable + * alternative suffices for the creation of compatible contexts. + * + * @param visualid VisualID + * @return FBConfig for VisualID + */ + GLXFBConfig getFBConfigFromVisualID(VisualID visualid); + + /** + * Portable replacement for glXChooseFBConfig + */ + GLXFBConfig* chooseFBConfig(const GLint *attribList, GLint *nElements); + + /** + * Portable replacement for glXCreateNewContext + */ + ::GLXContext createNewContext(GLXFBConfig fbConfig, GLint renderType, ::GLXContext shareList, GLboolean direct) const; + + /** + * Portable replacement for glXGetFBConfigAttrib + */ + GLint getFBConfigAttrib(GLXFBConfig fbConfig, GLint attribute, GLint *value); + + /** + * Portable replacement for glXGetVisualFromFBConfig + */ + XVisualInfo* getVisualFromFBConfig(GLXFBConfig fbConfig); + + private: + /** + * Initialise GLXEW without requiring a current GL context + */ + void initialiseGLXEW(void); + + /** + * Refresh config options to reflect dependencies + */ + void refreshConfig(void); + + Display* mGLDisplay; // used for GL/GLX commands + Display* mXDisplay; // used for other X commands and events + bool mIsExternalDisplay; + + typedef std::pair ScreenSize; + typedef short Rate; + typedef std::pair VideoMode; + typedef std::vector VideoModes; + + VideoModes mVideoModes; + VideoMode mOriginalMode; + VideoMode mCurrentMode; + + StringVector mSampleLevels; + }; #if OGRE_THREAD_SUPPORT == 1 GLXEWContext* glxewGetContext(); diff --git a/RenderSystems/GL/include/GLX/OgreGLXRenderTexture.h b/RenderSystems/GL/include/GLX/OgreGLXRenderTexture.h index ae01399451e..ff708b4f994 100644 --- a/RenderSystems/GL/include/GLX/OgreGLXRenderTexture.h +++ b/RenderSystems/GL/include/GLX/OgreGLXRenderTexture.h @@ -36,17 +36,17 @@ THE SOFTWARE. namespace Ogre { - class _OgrePrivate GLXPBuffer : public GLPBuffer - { - public: - GLXPBuffer(GLXGLSupport* glsupport, PixelComponentType format, size_t width, size_t height); - ~GLXPBuffer(); - - virtual GLContext *getContext(); - - protected: - GLXContext* mContext; - GLXGLSupport* mGLSupport; - }; + class _OgrePrivate GLXPBuffer : public GLPBuffer + { + public: + GLXPBuffer(GLXGLSupport* glsupport, PixelComponentType format, size_t width, size_t height); + ~GLXPBuffer(); + + virtual GLContext *getContext(); + + protected: + GLXContext* mContext; + GLXGLSupport* mGLSupport; + }; } #endif diff --git a/RenderSystems/GL/include/GLX/OgreGLXUtils.h b/RenderSystems/GL/include/GLX/OgreGLXUtils.h index c73ab82a39f..5f65da324c2 100644 --- a/RenderSystems/GL/include/GLX/OgreGLXUtils.h +++ b/RenderSystems/GL/include/GLX/OgreGLXUtils.h @@ -34,68 +34,68 @@ THE SOFTWARE. namespace Ogre { - class _OgrePrivate GLXUtils - { - public: - // Portable replacements for some GLX 1.3 function pointers - - static PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig; - static PFNGLXCREATENEWCONTEXTPROC createNewContext; - static PFNGLXGETFBCONFIGATTRIBPROC getFBConfigAttrib; - static PFNGLXGETVISUALFROMFBCONFIGPROC getVisualFromFBConfig; - - /** - * Get the GLXFBConfig used to create a GLXContext - * - * @param display X Display - * @param context GLXContext - * @return GLXFBConfig used to create the context - */ - static GLXFBConfig getFBConfigFromContext (Display *display, ::GLXContext context); - - /** - * Get the GLXFBConfig used to create a GLXDrawable. - * Caveat: GLX version 1.3 is needed when the drawable is a GLXPixmap - * - * @param display X Display - * @param drawable GLXDrawable - * @param width Receiver for the drawable width - * @param height Receiver for the drawable height - * @return GLXFBConfig used to create the drawable - */ - static GLXFBConfig getFBConfigFromDrawable (Display *display, GLXDrawable drawable, - unsigned int *width, unsigned int *height); - - /** - * Initialise the parts of GLXEW needed to create a GL Context - * - * @param display X Display - */ - static void initialiseGLXEW (Display *display); - - /** - * Select an FBConfig given a list of required and a list of desired properties - * - * @param display X Display - * @param minAttribs FBConfig attributes that must be provided with minimum values - * @param maxAttribs FBConfig attributes that are preferred with maximum values - * @return GLXFBConfig with attributes or 0 when unsupported. - */ - static GLXFBConfig selectFBConfig(Display *display, const int *minAttribs, const int *maxAttribs); - - /** - * Loads an icon from an Ogre resource into the X Server. This currently only - * works for 24 and 32 bit displays. The image must be findable by the Ogre - * resource system, and of format PF_A8R8G8B8. - * - * @param display X display - * @param name Name of image to load - * @param pix Receiver for the output pixmap - * @param mask Receiver for the output mask (alpha bitmap) - * @return true on success - */ - static bool loadIcon(Display *display, const std::string &name, Pixmap *pix, Pixmap *mask); - }; + class _OgrePrivate GLXUtils + { + public: + // Portable replacements for some GLX 1.3 function pointers + + static PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig; + static PFNGLXCREATENEWCONTEXTPROC createNewContext; + static PFNGLXGETFBCONFIGATTRIBPROC getFBConfigAttrib; + static PFNGLXGETVISUALFROMFBCONFIGPROC getVisualFromFBConfig; + + /** + * Get the GLXFBConfig used to create a GLXContext + * + * @param display X Display + * @param context GLXContext + * @return GLXFBConfig used to create the context + */ + static GLXFBConfig getFBConfigFromContext (Display *display, ::GLXContext context); + + /** + * Get the GLXFBConfig used to create a GLXDrawable. + * Caveat: GLX version 1.3 is needed when the drawable is a GLXPixmap + * + * @param display X Display + * @param drawable GLXDrawable + * @param width Receiver for the drawable width + * @param height Receiver for the drawable height + * @return GLXFBConfig used to create the drawable + */ + static GLXFBConfig getFBConfigFromDrawable (Display *display, GLXDrawable drawable, + unsigned int *width, unsigned int *height); + + /** + * Initialise the parts of GLXEW needed to create a GL Context + * + * @param display X Display + */ + static void initialiseGLXEW (Display *display); + + /** + * Select an FBConfig given a list of required and a list of desired properties + * + * @param display X Display + * @param minAttribs FBConfig attributes that must be provided with minimum values + * @param maxAttribs FBConfig attributes that are preferred with maximum values + * @return GLXFBConfig with attributes or 0 when unsupported. + */ + static GLXFBConfig selectFBConfig(Display *display, const int *minAttribs, const int *maxAttribs); + + /** + * Loads an icon from an Ogre resource into the X Server. This currently only + * works for 24 and 32 bit displays. The image must be findable by the Ogre + * resource system, and of format PF_A8R8G8B8. + * + * @param display X display + * @param name Name of image to load + * @param pix Receiver for the output pixmap + * @param mask Receiver for the output mask (alpha bitmap) + * @return true on success + */ + static bool loadIcon(Display *display, const std::string &name, Pixmap *pix, Pixmap *mask); + }; } diff --git a/RenderSystems/GL/include/GLX/OgreGLXWindow.h b/RenderSystems/GL/include/GLX/OgreGLXWindow.h index b8520fdf4e0..92ef40f6ae1 100644 --- a/RenderSystems/GL/include/GLX/OgreGLXWindow.h +++ b/RenderSystems/GL/include/GLX/OgreGLXWindow.h @@ -36,91 +36,91 @@ THE SOFTWARE. namespace Ogre { - class _OgrePrivate GLXWindow : public RenderWindow - { - public: - GLXWindow(GLXGLSupport* glsupport); - ~GLXWindow(); - - void create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams); - - /** @copydoc RenderWindow::setFullscreen */ - void setFullscreen (bool fullscreen, uint width, uint height); - - /** @copydoc RenderWindow::destroy */ - void destroy(void); - - /** @copydoc RenderWindow::isClosed */ - bool isClosed(void) const; - - /** @copydoc RenderWindow::isVisible */ - bool isVisible(void) const; - - /** @copydoc RenderWindow::setVisible */ - void setVisible(bool visible); - - /** @copydoc RenderWindow::isHidden */ - bool isHidden(void) const { return mHidden; } - - /** @copydoc RenderWindow::setHidden */ - void setHidden(bool hidden); - - /** @copydoc RenderWindow::setVSyncEnabled */ - void setVSyncEnabled(bool vsync); - - /** @copydoc RenderWindow::isVSyncEnabled */ - bool isVSyncEnabled() const; - - /** @copydoc RenderWindow::setVSyncInterval */ - void setVSyncInterval(unsigned int interval); - - /** @copydoc RenderWindow::getVSyncInterval */ - unsigned int getVSyncInterval() const; - - /** @copydoc RenderWindow::reposition */ - void reposition(int left, int top); - - /** @copydoc RenderWindow::resize */ - void resize(unsigned int width, unsigned int height); - - /** @copydoc RenderWindow::windowMovedOrResized */ - void windowMovedOrResized(); - - /** @copydoc RenderWindow::swapBuffers */ - void swapBuffers(); - - /** @copydoc RenderTarget::copyContentsToMemory */ - void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); - - /** - @remarks - * Get custom attribute; the following attributes are valid: - * WINDOW The X Window target for rendering. - * GLCONTEXT The Ogre GLContext used for rendering. - * DISPLAY The X Display connection behind that context. - * DISPLAYNAME The X Server name for the connected display. - * ATOM The X Atom used in client delete events. - */ - void getCustomAttribute(const String& name, void* pData); - - bool requiresTextureFlipping() const { return false; } - - private: - bool mClosed; - bool mVisible; - bool mHidden; - bool mIsTopLevel; - bool mIsExternal; - bool mIsExternalGLControl; - bool mVSync; - int mVSyncInterval; - - GLXGLSupport* mGLSupport; - ::Window mWindow; - GLXContext* mContext; - void switchFullScreen(bool fullscreen); - }; + class _OgrePrivate GLXWindow : public RenderWindow + { + public: + GLXWindow(GLXGLSupport* glsupport); + ~GLXWindow(); + + void create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams); + + /** @copydoc RenderWindow::setFullscreen */ + void setFullscreen (bool fullscreen, uint width, uint height); + + /** @copydoc RenderWindow::destroy */ + void destroy(void); + + /** @copydoc RenderWindow::isClosed */ + bool isClosed(void) const; + + /** @copydoc RenderWindow::isVisible */ + bool isVisible(void) const; + + /** @copydoc RenderWindow::setVisible */ + void setVisible(bool visible); + + /** @copydoc RenderWindow::isHidden */ + bool isHidden(void) const { return mHidden; } + + /** @copydoc RenderWindow::setHidden */ + void setHidden(bool hidden); + + /** @copydoc RenderWindow::setVSyncEnabled */ + void setVSyncEnabled(bool vsync); + + /** @copydoc RenderWindow::isVSyncEnabled */ + bool isVSyncEnabled() const; + + /** @copydoc RenderWindow::setVSyncInterval */ + void setVSyncInterval(unsigned int interval); + + /** @copydoc RenderWindow::getVSyncInterval */ + unsigned int getVSyncInterval() const; + + /** @copydoc RenderWindow::reposition */ + void reposition(int left, int top); + + /** @copydoc RenderWindow::resize */ + void resize(unsigned int width, unsigned int height); + + /** @copydoc RenderWindow::windowMovedOrResized */ + void windowMovedOrResized(); + + /** @copydoc RenderWindow::swapBuffers */ + void swapBuffers(); + + /** @copydoc RenderTarget::copyContentsToMemory */ + void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); + + /** + @remarks + * Get custom attribute; the following attributes are valid: + * WINDOW The X Window target for rendering. + * GLCONTEXT The Ogre GLContext used for rendering. + * DISPLAY The X Display connection behind that context. + * DISPLAYNAME The X Server name for the connected display. + * ATOM The X Atom used in client delete events. + */ + void getCustomAttribute(const String& name, void* pData); + + bool requiresTextureFlipping() const { return false; } + + private: + bool mClosed; + bool mVisible; + bool mHidden; + bool mIsTopLevel; + bool mIsExternal; + bool mIsExternalGLControl; + bool mVSync; + int mVSyncInterval; + + GLXGLSupport* mGLSupport; + ::Window mWindow; + GLXContext* mContext; + void switchFullScreen(bool fullscreen); + }; } #endif diff --git a/RenderSystems/GL/include/OSX/OgreOSXCGLContext.h b/RenderSystems/GL/include/OSX/OgreOSXCGLContext.h index 43eaae366fc..d41d5e57369 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXCGLContext.h +++ b/RenderSystems/GL/include/OSX/OgreOSXCGLContext.h @@ -37,31 +37,31 @@ namespace Ogre { class OSXCGLContext: public OSXContext, public GeneralAllocatedObject { public: - OSXCGLContext(CGLContextObj cglContext, CGLPixelFormatObj pixelFormat); + OSXCGLContext(CGLContextObj cglContext, CGLPixelFormatObj pixelFormat); virtual ~OSXCGLContext(); /** See GLContext */ virtual void setCurrent(); - /** + /** * This is called before another context is made current. By default, * nothing is done here. */ virtual void endCurrent(); - /** Create a new context based on the same window/pbuffer as this - context - mostly useful for additional threads. - @note The caller is responsible for deleting the returned context. - */ - virtual GLContext* clone() const; - /** - * Return value will be "CGL" - */ - virtual String getContextType(); + /** Create a new context based on the same window/pbuffer as this + context - mostly useful for additional threads. + @note The caller is responsible for deleting the returned context. + */ + virtual GLContext* clone() const; + /** + * Return value will be "CGL" + */ + virtual String getContextType(); - /** Grab the CGLContext if it exists */ - CGLContextObj getContext() { return mCGLContext; } + /** Grab the CGLContext if it exists */ + CGLContextObj getContext() { return mCGLContext; } - private: - CGLContextObj mCGLContext; + private: + CGLContextObj mCGLContext; CGLPixelFormatObj mPixelFormat; }; } diff --git a/RenderSystems/GL/include/OSX/OgreOSXCarbonContext.h b/RenderSystems/GL/include/OSX/OgreOSXCarbonContext.h index 05b6642bf6c..633d7e121b1 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXCarbonContext.h +++ b/RenderSystems/GL/include/OSX/OgreOSXCarbonContext.h @@ -43,26 +43,26 @@ namespace Ogre { /** See GLContext */ virtual void setCurrent(); - /** + /** * This is called before another context is made current. By default, * nothing is done here. */ virtual void endCurrent(); - /** Create a new context based on the same window/pbuffer as this - context - mostly useful for additional threads. - @note The caller is responsible for deleting the returned context. - */ - virtual GLContext* clone() const; - /** - * Return value will be "AGL" - */ - virtual String getContextType(); + /** Create a new context based on the same window/pbuffer as this + context - mostly useful for additional threads. + @note The caller is responsible for deleting the returned context. + */ + virtual GLContext* clone() const; + /** + * Return value will be "AGL" + */ + virtual String getContextType(); - /** Grab the AGLContext if it exists */ - AGLContext getContext() { return mAGLContext; } + /** Grab the AGLContext if it exists */ + AGLContext getContext() { return mAGLContext; } - private: - AGLContext mAGLContext; + private: + AGLContext mAGLContext; AGLPixelFormat mPixelFormat; }; } diff --git a/RenderSystems/GL/include/OSX/OgreOSXCarbonWindow.h b/RenderSystems/GL/include/OSX/OgreOSXCarbonWindow.h index e6f50c8d2dc..fcf006ca5b8 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXCarbonWindow.h +++ b/RenderSystems/GL/include/OSX/OgreOSXCarbonWindow.h @@ -39,20 +39,20 @@ THE SOFTWARE. namespace Ogre { - class OSXCarbonWindow : public OSXWindow - { - public: - OSXCarbonWindow(); - virtual ~OSXCarbonWindow(); - - virtual void create( const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams ); + class OSXCarbonWindow : public OSXWindow + { + public: + OSXCarbonWindow(); + virtual ~OSXCarbonWindow(); + + virtual void create( const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams ); /** Overridden - see RenderWindow */ - virtual void destroy( void ); + virtual void destroy( void ); /** Overridden - see RenderWindow */ - virtual bool isActive( void ) const; + virtual bool isActive( void ) const; /** Overridden - see RenderWindow */ - virtual bool isClosed( void ) const; + virtual bool isClosed( void ) const; /** @copydoc RenderWindow::isHidden */ bool isHidden(void) const { return mHidden; } /** @copydoc RenderWindow::setHidden */ @@ -62,40 +62,40 @@ namespace Ogre /** @copydoc RenderWindow::isVSyncEnabled */ bool isVSyncEnabled() const; /** Overridden - see RenderWindow */ - virtual void reposition( int left, int top ); + virtual void reposition( int left, int top ); /** Overridden - see RenderWindow */ - virtual void resize( unsigned int width, unsigned int height ); + virtual void resize( unsigned int width, unsigned int height ); /** Overridden - see RenderWindow */ - virtual void setVisible( bool visible ); + virtual void setVisible( bool visible ); /** Overridden - see RenderWindow */ - virtual bool isVisible(void) const; + virtual bool isVisible(void) const; /** Overridden - see RenderWindow */ - virtual void swapBuffers( ); + virtual void swapBuffers( ); /** Overridden - see RenderWindow */ virtual void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); - /** Overridden - see RenderTarget */ - virtual void windowMovedOrResized(); + /** Overridden - see RenderTarget */ + virtual void windowMovedOrResized(); - bool requiresTextureFlipping(void) const { return false; } - - void windowResized(void); - void windowHasResized(void); - - void getCustomAttribute( const String& name, void* pData ); + bool requiresTextureFlipping(void) const { return false; } + + void windowResized(void); + void windowHasResized(void); + + void getCustomAttribute( const String& name, void* pData ); - private: - void createNewWindow(unsigned int width, unsigned int height, String title); + private: + void createNewWindow(unsigned int width, unsigned int height, String title); void createWindowFromExternal(HIViewRef viewRef); void createAGLContext(size_t fsaa_samples, int depth); - WindowRef mWindow; + WindowRef mWindow; EventHandlerRef mEventHandlerRef; - HIViewRef mView; - AGLContext mAGLContext; + HIViewRef mView; + AGLContext mAGLContext; AGLPixelFormat mAGLPixelFormat; String mWindowTitle; - OSXCGLContext* mCGLContext; - OSXCarbonContext* mCarbonContext; + OSXCGLContext* mCGLContext; + OSXCarbonContext* mCarbonContext; bool mVSync; bool mActive; bool mClosed; @@ -104,7 +104,7 @@ namespace Ogre bool mHasResized; bool mIsExternal; bool mVisible; - }; + }; } #endif // __LP64__ diff --git a/RenderSystems/GL/include/OSX/OgreOSXCocoaContext.h b/RenderSystems/GL/include/OSX/OgreOSXCocoaContext.h index 099bcd9a53f..417cc617303 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXCocoaContext.h +++ b/RenderSystems/GL/include/OSX/OgreOSXCocoaContext.h @@ -42,34 +42,34 @@ namespace Ogre { /** See GLContext */ virtual void setCurrent(); - /** + /** * This is called before another context is made current. By default, * nothing is done here. */ virtual void endCurrent(); - /** Create a new context based on the same window/pbuffer as this - context - mostly useful for additional threads. - @note The caller is responsible for deleting the returned context. - */ - virtual GLContext* clone() const; - /** - * Return value will be "NSOpenGL" - */ - virtual String getContextType(); - - /** Grab the NSOpenGLContext if it exists */ - NSOpenGLContext* getContext(); - - /** Grab the NSOpenGLPixelFormat if it exists */ - NSOpenGLPixelFormat* getPixelFormat(); - + /** Create a new context based on the same window/pbuffer as this + context - mostly useful for additional threads. + @note The caller is responsible for deleting the returned context. + */ + virtual GLContext* clone() const; + /** + * Return value will be "NSOpenGL" + */ + virtual String getContextType(); + + /** Grab the NSOpenGLContext if it exists */ + NSOpenGLContext* getContext(); + + /** Grab the NSOpenGLPixelFormat if it exists */ + NSOpenGLPixelFormat* getPixelFormat(); + /* The pixel dimensions of the backbuffer */ GLint mBackingWidth; GLint mBackingHeight; - private: - NSOpenGLContext* mNSGLContext; - NSOpenGLPixelFormat *mNSGLPixelFormat; + private: + NSOpenGLContext* mNSGLContext; + NSOpenGLPixelFormat *mNSGLPixelFormat; }; } diff --git a/RenderSystems/GL/include/OSX/OgreOSXCocoaView.h b/RenderSystems/GL/include/OSX/OgreOSXCocoaView.h index e7da5661d31..a82917b33be 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXCocoaView.h +++ b/RenderSystems/GL/include/OSX/OgreOSXCocoaView.h @@ -34,7 +34,7 @@ THE SOFTWARE. @interface OgreView : NSView { - Ogre::RenderWindow *window; + Ogre::RenderWindow *window; } - (id)initWithFrame:(NSRect)f; diff --git a/RenderSystems/GL/include/OSX/OgreOSXCocoaWindow.h b/RenderSystems/GL/include/OSX/OgreOSXCocoaWindow.h index 43555112fdb..b00b85c338d 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXCocoaWindow.h +++ b/RenderSystems/GL/include/OSX/OgreOSXCocoaWindow.h @@ -59,7 +59,7 @@ namespace Ogre { bool mClosed; bool mHidden; bool mVSync; - bool mHasResized; + bool mHasResized; bool mIsExternal; String mWindowTitle; bool mUseNSView; @@ -70,15 +70,15 @@ namespace Ogre { public: OSXCocoaWindow(); ~OSXCocoaWindow(); - - NSView* ogreView() const { return mView; }; - NSWindow* ogreWindow() const { return mWindow; }; - NSOpenGLContext* nsopenGLContext() const { return mGLContext; }; - NSOpenGLPixelFormat* nsopenGLPixelFormat() const { return mGLPixelFormat; }; - void createWithView(OgreView *view); - - void create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams); + + NSView* ogreView() const { return mView; }; + NSWindow* ogreWindow() const { return mWindow; }; + NSOpenGLContext* nsopenGLContext() const { return mGLContext; }; + NSOpenGLPixelFormat* nsopenGLPixelFormat() const { return mGLPixelFormat; }; + void createWithView(OgreView *view); + + void create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams); /** Overridden - see RenderWindow */ void destroy(void); /** Overridden - see RenderWindow */ @@ -108,14 +108,14 @@ namespace Ogre { /** Overridden - see RenderWindow */ virtual unsigned int getHeight(void) const; /** Overridden - see RenderWindow */ - void windowMovedOrResized(void); - void windowResized(void); - void windowHasResized(void); - void createNewWindow(unsigned int width, unsigned int height, String title); + void windowMovedOrResized(void); + void windowResized(void); + void windowHasResized(void); + void createNewWindow(unsigned int width, unsigned int height, String title); void createWindowFromExternal(NSView *viewRef); - bool requiresTextureFlipping() const { return false; } - void getCustomAttribute( const String& name, void* pData ); + bool requiresTextureFlipping() const { return false; } + void getCustomAttribute( const String& name, void* pData ); }; } diff --git a/RenderSystems/GL/include/OSX/OgreOSXCocoaWindowDelegate.h b/RenderSystems/GL/include/OSX/OgreOSXCocoaWindowDelegate.h index a662a8fa041..7feb188e56c 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXCocoaWindowDelegate.h +++ b/RenderSystems/GL/include/OSX/OgreOSXCocoaWindowDelegate.h @@ -34,7 +34,7 @@ { @private Ogre::RenderWindow *ogreWindow; - NSWindow *window; + NSWindow *window; } -(id)initWithNSWindow:(NSWindow*)nswin ogreWindow:(Ogre::RenderWindow*)ogrewin; diff --git a/RenderSystems/GL/include/OSX/OgreOSXContext.h b/RenderSystems/GL/include/OSX/OgreOSXContext.h index ddc0063acdc..5b08f07f4f5 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXContext.h +++ b/RenderSystems/GL/include/OSX/OgreOSXContext.h @@ -32,7 +32,7 @@ THE SOFTWARE. namespace Ogre { - /** + /** * Class that encapsulates an GL context. (IE a window/pbuffer). This is a * virtual base class which should be implemented in a GLSupport. * This object can also be used to cache renderstate if we decide to do so @@ -46,27 +46,27 @@ namespace Ogre /** See GLContext */ virtual void setCurrent() = 0; - /** + /** * This is called before another context is made current. By default, * nothing is done here. */ virtual void endCurrent() = 0; - /** Create a new context based on the same window/pbuffer as this - context - mostly useful for additional threads. - @note The caller is responsible for deleting the returned context. - */ - virtual GLContext* clone() const = 0; - /** - * Return the type of context currently assoiciated with this OSXContext, - * this is needed because OSX has several different types of contexts - * depending on the application needs. - @note Return value will be "AGL", "CGL", or "NSOpenGL" accordingly. - */ - virtual String getContextType() = 0; - - protected: - /** Must be called from destructor of final descendant. */ - void _unregisterContext(); + /** Create a new context based on the same window/pbuffer as this + context - mostly useful for additional threads. + @note The caller is responsible for deleting the returned context. + */ + virtual GLContext* clone() const = 0; + /** + * Return the type of context currently assoiciated with this OSXContext, + * this is needed because OSX has several different types of contexts + * depending on the application needs. + @note Return value will be "AGL", "CGL", or "NSOpenGL" accordingly. + */ + virtual String getContextType() = 0; + + protected: + /** Must be called from destructor of final descendant. */ + void _unregisterContext(); }; } diff --git a/RenderSystems/GL/include/OSX/OgreOSXGLSupport.h b/RenderSystems/GL/include/OSX/OgreOSXGLSupport.h index 1f7094815cd..79153d13955 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXGLSupport.h +++ b/RenderSystems/GL/include/OSX/OgreOSXGLSupport.h @@ -37,61 +37,61 @@ namespace Ogre class OSXGLSupport : public GLSupport { public: - OSXGLSupport(); - ~OSXGLSupport(); - - /** - * Add any special config values to the system. - * Must have a "Full Screen" value that is a bool and a "Video Mode" value - * that is a string in the form of wxh - */ - void addConfig( void ); - - /** - * Make sure all the extra options are valid - */ - String validateConfig( void ); - - /// @copydoc GLSupport::createWindow - RenderWindow* createWindow( bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle ); - - /// @copydoc Root::createRenderWindow - virtual RenderWindow* newWindow( const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0 ); - - /** - * Start anything special - */ - void start(); - - /** - * Stop anything special - */ - void stop(); - - /** - * Get the address of a function - */ - void* getProcAddress( const char *name ); - void* getProcAddress( const String& procname ); - - virtual bool supportsPBuffers(); - virtual GLPBuffer* createPBuffer( PixelComponentType format, uint32 width, uint32 height ); - - // Core Foundation Array callback function for sorting, must be static for the function ptr - static CFComparisonResult _compareModes (const void *val1, const void *val2, void *context); - // Core Fondation Dictionary helper functions, also static for ease of use in above static - static Boolean _getDictionaryBoolean(CFDictionaryRef dict, const void* key); - static long _getDictionaryLong(CFDictionaryRef dict, const void* key); + OSXGLSupport(); + ~OSXGLSupport(); + + /** + * Add any special config values to the system. + * Must have a "Full Screen" value that is a bool and a "Video Mode" value + * that is a string in the form of wxh + */ + void addConfig( void ); + + /** + * Make sure all the extra options are valid + */ + String validateConfig( void ); + + /// @copydoc GLSupport::createWindow + RenderWindow* createWindow( bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle ); + + /// @copydoc Root::createRenderWindow + virtual RenderWindow* newWindow( const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0 ); + + /** + * Start anything special + */ + void start(); + + /** + * Stop anything special + */ + void stop(); + + /** + * Get the address of a function + */ + void* getProcAddress( const char *name ); + void* getProcAddress( const String& procname ); + + virtual bool supportsPBuffers(); + virtual GLPBuffer* createPBuffer( PixelComponentType format, uint32 width, uint32 height ); + + // Core Foundation Array callback function for sorting, must be static for the function ptr + static CFComparisonResult _compareModes (const void *val1, const void *val2, void *context); + // Core Fondation Dictionary helper functions, also static for ease of use in above static + static Boolean _getDictionaryBoolean(CFDictionaryRef dict, const void* key); + static long _getDictionaryLong(CFDictionaryRef dict, const void* key); bool OSVersionIsAtLeast(String newVersion); protected: - String mAPI; - String mContextType; + String mAPI; + String mContextType; //Implement this in .mm and put all obj.c objects there class OSXGLSupportImpl * mImpl; - + }; // class OSXGLSupport } // namespace Ogre diff --git a/RenderSystems/GL/include/OSX/OgreOSXRenderTexture.h b/RenderSystems/GL/include/OSX/OgreOSXRenderTexture.h index 46770384ef9..8800edb662f 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXRenderTexture.h +++ b/RenderSystems/GL/include/OSX/OgreOSXRenderTexture.h @@ -45,12 +45,12 @@ namespace Ogre protected: void createPBuffer(); - void destroyPBuffer(); + void destroyPBuffer(); - private: - AGLPbuffer mPBuffer; - AGLContext mAGLContext; - OSXCarbonContext* mContext; + private: + AGLPbuffer mPBuffer; + AGLContext mAGLContext; + OSXCarbonContext* mContext; }; } #endif diff --git a/RenderSystems/GL/include/OSX/OgreOSXWindow.h b/RenderSystems/GL/include/OSX/OgreOSXWindow.h index d08c6f5f4df..87d1425103c 100644 --- a/RenderSystems/GL/include/OSX/OgreOSXWindow.h +++ b/RenderSystems/GL/include/OSX/OgreOSXWindow.h @@ -37,15 +37,15 @@ THE SOFTWARE. namespace Ogre { - class OSXWindow : public RenderWindow - { - public: - OSXWindow(); - virtual ~OSXWindow(); - - /** Overridden - see RenderWindow */ - void create( const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams ) = 0; + class OSXWindow : public RenderWindow + { + public: + OSXWindow(); + virtual ~OSXWindow(); + + /** Overridden - see RenderWindow */ + void create( const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams ) = 0; /** Overridden - see RenderWindow */ virtual void destroy( void ) = 0; /** Overridden - see RenderWindow */ @@ -62,28 +62,28 @@ namespace Ogre virtual void swapBuffers( ) = 0; /** Overridden - see RenderTarget */ virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); - /** Overridden - see RenderTarget */ - virtual void windowMovedOrResized() {}; + /** Overridden - see RenderTarget */ + virtual void windowMovedOrResized() {}; - protected: - OSXContext* mContext; - CGLContextObj mCGLContextObj; + protected: + OSXContext* mContext; + CGLContextObj mCGLContextObj; #if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 CGDisplayModeRef mOriginalDisplayMode; #else CFDictionaryRef mOriginalDisplayMode; #endif - /** Switch to full screen mode using CGL */ - void createCGLFullscreen(unsigned int width, unsigned int height, unsigned int depth, unsigned int fsaa, CGLContextObj sharedContext); - /** Kill full screen mode, and return to default windowed mode */ - void destroyCGLFullscreen(void); - /** Update the full screen context */ - void swapCGLBuffers(void); + /** Switch to full screen mode using CGL */ + void createCGLFullscreen(unsigned int width, unsigned int height, unsigned int depth, unsigned int fsaa, CGLContextObj sharedContext); + /** Kill full screen mode, and return to default windowed mode */ + void destroyCGLFullscreen(void); + /** Update the full screen context */ + void swapCGLBuffers(void); #if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6 uint32 bitDepthFromDisplayMode(CGDisplayModeRef mode); #endif - }; + }; #define ENABLE_CG_CHECK 0 #if ENABLE_CG_CHECK diff --git a/RenderSystems/GL/include/OgreGLATIFSInit.h b/RenderSystems/GL/include/OgreGLATIFSInit.h index 4ad652cf033..f792e40d8ea 100644 --- a/RenderSystems/GL/include/OgreGLATIFSInit.h +++ b/RenderSystems/GL/include/OgreGLATIFSInit.h @@ -1,7 +1,7 @@ /* - ATI fragment shader Extension header file. - setup by NFZ - extracted from ATI 8500 SDK + ATI fragment shader Extension header file. + setup by NFZ + extracted from ATI 8500 SDK ** GL_ATI_fragment_shader ** @@ -37,5 +37,5 @@ extern PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glSetFragmentShaderConstantATI_ptr; bool InitATIFragmentShaderExtensions(Ogre::GLSupport& glSupport); -#endif //_GL_ATI_FRAGMENT_SHADER_H_ +#endif //_GL_ATI_FRAGMENT_SHADER_H_ diff --git a/RenderSystems/GL/include/OgreGLContext.h b/RenderSystems/GL/include/OgreGLContext.h index 48688244bb8..be2b4b06ce5 100644 --- a/RenderSystems/GL/include/OgreGLContext.h +++ b/RenderSystems/GL/include/OgreGLContext.h @@ -57,16 +57,16 @@ namespace Ogre { bool getInitialized() { return initialized; }; void setInitialized() { initialized = true; }; - /** Create a new context based on the same window/pbuffer as this - context - mostly useful for additional threads. - @note The caller is responsible for deleting the returned context. - */ - virtual GLContext* clone() const = 0; + /** Create a new context based on the same window/pbuffer as this + context - mostly useful for additional threads. + @note The caller is responsible for deleting the returned context. + */ + virtual GLContext* clone() const = 0; - /** - * Release the render context. - */ - virtual void releaseContext() {} + /** + * Release the render context. + */ + virtual void releaseContext() {} protected: bool initialized; }; diff --git a/RenderSystems/GL/include/OgreGLDefaultHardwareBufferManager.h b/RenderSystems/GL/include/OgreGLDefaultHardwareBufferManager.h index 134f2f4356f..975341292e7 100644 --- a/RenderSystems/GL/include/OgreGLDefaultHardwareBufferManager.h +++ b/RenderSystems/GL/include/OgreGLDefaultHardwareBufferManager.h @@ -40,16 +40,16 @@ namespace Ogre { /// Specialisation of HardwareVertexBuffer for emulation class _OgreGLExport GLDefaultHardwareVertexBuffer : public HardwareVertexBuffer { - protected: - unsigned char* mData; + protected: + unsigned char* mData; /// @copydoc HardwareBuffer::lock void* lockImpl(size_t offset, size_t length, LockOptions options); /// @copydoc HardwareBuffer::unlock void unlockImpl(void); public: - GLDefaultHardwareVertexBuffer(size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage); - GLDefaultHardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, + GLDefaultHardwareVertexBuffer(size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage); + GLDefaultHardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage); ~GLDefaultHardwareVertexBuffer(); /// @copydoc HardwareBuffer::readData @@ -57,33 +57,33 @@ namespace Ogre { /// @copydoc HardwareBuffer::writeData void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); + bool discardWholeBuffer = false); /** Override HardwareBuffer to turn off all shadowing. */ - void* lock(size_t offset, size_t length, LockOptions options, HardwareBuffer::UploadOptions uploadOpt = HBU_DEFAULT); + void* lock(size_t offset, size_t length, LockOptions options, HardwareBuffer::UploadOptions uploadOpt = HBU_DEFAULT); /** Override HardwareBuffer to turn off all shadowing. */ - void unlock(void); + void unlock(void); //void* getDataPtr(void) const { return (void*)mData; } void* getDataPtr(size_t offset) const { return (void*)(mData + offset); } }; - /// Specialisation of HardwareIndexBuffer for emulation + /// Specialisation of HardwareIndexBuffer for emulation class _OgreGLExport GLDefaultHardwareIndexBuffer : public HardwareIndexBuffer { - protected: - unsigned char* mData; + protected: + unsigned char* mData; /// @copydoc HardwareBuffer::lock void* lockImpl(size_t offset, size_t length, LockOptions options); /// @copydoc HardwareBuffer::unlock void unlockImpl(void); public: - GLDefaultHardwareIndexBuffer(IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage); + GLDefaultHardwareIndexBuffer(IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage); ~GLDefaultHardwareIndexBuffer(); /// @copydoc HardwareBuffer::readData void readData(size_t offset, size_t length, void* pDest); /// @copydoc HardwareBuffer::writeData void writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer = false); + bool discardWholeBuffer = false); /** Override HardwareBuffer to turn off all shadowing. */ void* lock(size_t offset, size_t length, LockOptions options, HardwareBuffer::UploadOptions uploadOpt = HBU_DEFAULT); /** Override HardwareBuffer to turn off all shadowing. */ @@ -92,50 +92,50 @@ namespace Ogre { void* getDataPtr(size_t offset) const { return (void*)(mData + offset); } }; - /** Specialisation of HardwareBufferManager to emulate hardware buffers. - @remarks - You might want to instantiate this class if you want to utilise - classes like MeshSerializer without having initialised the - rendering system (which is required to create a 'real' hardware - buffer manager. - */ - class _OgreGLExport GLDefaultHardwareBufferManagerBase : public HardwareBufferManagerBase - { + /** Specialisation of HardwareBufferManager to emulate hardware buffers. + @remarks + You might want to instantiate this class if you want to utilise + classes like MeshSerializer without having initialised the + rendering system (which is required to create a 'real' hardware + buffer manager. + */ + class _OgreGLExport GLDefaultHardwareBufferManagerBase : public HardwareBufferManagerBase + { public: GLDefaultHardwareBufferManagerBase(); ~GLDefaultHardwareBufferManagerBase(); /// Creates a vertex buffer - HardwareVertexBufferSharedPtr + HardwareVertexBufferSharedPtr createVertexBuffer(size_t vertexSize, size_t numVerts, - HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// Create a hardware index buffer - HardwareIndexBufferSharedPtr + HardwareBuffer::Usage usage, bool useShadowBuffer = false); + /// Create a hardware index buffer + HardwareIndexBufferSharedPtr createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, - HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// Create a render to vertex buffer - RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); - /// Create a uniform buffer - HardwareUniformBufferSharedPtr - createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name = ""); - HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, + HardwareBuffer::Usage usage, bool useShadowBuffer = false); + /// Create a render to vertex buffer + RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); + /// Create a uniform buffer + HardwareUniformBufferSharedPtr + createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name = ""); + HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, bool useShadowBuffer = false, const String& name = ""); }; - /// GLDefaultHardwareBufferManagerBase as a Singleton - class _OgreGLExport GLDefaultHardwareBufferManager : public HardwareBufferManager - { - public: - GLDefaultHardwareBufferManager() - : HardwareBufferManager(OGRE_NEW GLDefaultHardwareBufferManagerBase()) - { - - } - ~GLDefaultHardwareBufferManager() - { - OGRE_DELETE mImpl; - } - }; + /// GLDefaultHardwareBufferManagerBase as a Singleton + class _OgreGLExport GLDefaultHardwareBufferManager : public HardwareBufferManager + { + public: + GLDefaultHardwareBufferManager() + : HardwareBufferManager(OGRE_NEW GLDefaultHardwareBufferManagerBase()) + { + + } + ~GLDefaultHardwareBufferManager() + { + OGRE_DELETE mImpl; + } + }; } #endif diff --git a/RenderSystems/GL/include/OgreGLDepthBuffer.h b/RenderSystems/GL/include/OgreGLDepthBuffer.h index 029fb8ba165..17ab2439daa 100644 --- a/RenderSystems/GL/include/OgreGLDepthBuffer.h +++ b/RenderSystems/GL/include/OgreGLDepthBuffer.h @@ -33,39 +33,39 @@ THE SOFTWARE. namespace Ogre { - /** - @copydoc DepthBuffer + /** + @copydoc DepthBuffer - OpenGL supports 3 different methods: FBO, pbuffer & Copy. - Each one has it's own limitations. Non-FBO methods are solved using "dummy" DepthBuffers. - That is, a DepthBuffer pointer is attached to the RenderTarget (for the sake of consistency) - but it doesn't actually contain a Depth surface/renderbuffer (mDepthBuffer & mStencilBuffer are - null pointers all the time) Those dummy DepthBuffers are identified thanks to their GL context. - Note that FBOs don't allow sharing with the main window's depth buffer. Therefore even - when FBO is enabled, a dummy DepthBuffer is still used to manage the windows. - */ - class GLDepthBuffer : public DepthBuffer - { - public: - GLDepthBuffer( uint16 poolId, GLRenderSystem *renderSystem, GLContext *creatorContext, - GLRenderBuffer *depth, GLRenderBuffer *stencil, - uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, - bool isManual ); - ~GLDepthBuffer(); + OpenGL supports 3 different methods: FBO, pbuffer & Copy. + Each one has it's own limitations. Non-FBO methods are solved using "dummy" DepthBuffers. + That is, a DepthBuffer pointer is attached to the RenderTarget (for the sake of consistency) + but it doesn't actually contain a Depth surface/renderbuffer (mDepthBuffer & mStencilBuffer are + null pointers all the time) Those dummy DepthBuffers are identified thanks to their GL context. + Note that FBOs don't allow sharing with the main window's depth buffer. Therefore even + when FBO is enabled, a dummy DepthBuffer is still used to manage the windows. + */ + class GLDepthBuffer : public DepthBuffer + { + public: + GLDepthBuffer( uint16 poolId, GLRenderSystem *renderSystem, GLContext *creatorContext, + GLRenderBuffer *depth, GLRenderBuffer *stencil, + uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, + bool isManual ); + ~GLDepthBuffer(); - /// @copydoc DepthBuffer::isCompatible - virtual bool isCompatible( RenderTarget *renderTarget ) const; + /// @copydoc DepthBuffer::isCompatible + virtual bool isCompatible( RenderTarget *renderTarget ) const; - GLContext* getGLContext() const { return mCreatorContext; } - GLRenderBuffer* getDepthBuffer() const { return mDepthBuffer; } - GLRenderBuffer* getStencilBuffer() const { return mStencilBuffer; } + GLContext* getGLContext() const { return mCreatorContext; } + GLRenderBuffer* getDepthBuffer() const { return mDepthBuffer; } + GLRenderBuffer* getStencilBuffer() const { return mStencilBuffer; } - protected: - uint32 mMultiSampleQuality; - GLContext *mCreatorContext; - GLRenderBuffer *mDepthBuffer; - GLRenderBuffer *mStencilBuffer; - GLRenderSystem *mRenderSystem; - }; + protected: + uint32 mMultiSampleQuality; + GLContext *mCreatorContext; + GLRenderBuffer *mDepthBuffer; + GLRenderBuffer *mStencilBuffer; + GLRenderSystem *mRenderSystem; + }; } #endif diff --git a/RenderSystems/GL/include/OgreGLFBOMultiRenderTarget.h b/RenderSystems/GL/include/OgreGLFBOMultiRenderTarget.h index 0d2caf38e17..e53db221119 100755 --- a/RenderSystems/GL/include/OgreGLFBOMultiRenderTarget.h +++ b/RenderSystems/GL/include/OgreGLFBOMultiRenderTarget.h @@ -32,27 +32,27 @@ THE SOFTWARE. #include "OgreGLFrameBufferObject.h" namespace Ogre { - /** MultiRenderTarget for GL. Requires the FBO extension. - */ - class _OgreGLExport GLFBOMultiRenderTarget : public MultiRenderTarget - { - public: - GLFBOMultiRenderTarget(GLFBOManager *manager, const String &name); - ~GLFBOMultiRenderTarget(); - - virtual void getCustomAttribute( const String& name, void *pData ); - - bool requiresTextureFlipping() const { return true; } - - /// Override so we can attach the depth buffer to the FBO - virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); - virtual void detachDepthBuffer(); - virtual void _detachDepthBuffer(); - private: - virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); - virtual void unbindSurfaceImpl(size_t attachment); - GLFrameBufferObject fbo; - }; + /** MultiRenderTarget for GL. Requires the FBO extension. + */ + class _OgreGLExport GLFBOMultiRenderTarget : public MultiRenderTarget + { + public: + GLFBOMultiRenderTarget(GLFBOManager *manager, const String &name); + ~GLFBOMultiRenderTarget(); + + virtual void getCustomAttribute( const String& name, void *pData ); + + bool requiresTextureFlipping() const { return true; } + + /// Override so we can attach the depth buffer to the FBO + virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); + virtual void detachDepthBuffer(); + virtual void _detachDepthBuffer(); + private: + virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); + virtual void unbindSurfaceImpl(size_t attachment); + GLFrameBufferObject fbo; + }; } diff --git a/RenderSystems/GL/include/OgreGLFBORenderTexture.h b/RenderSystems/GL/include/OgreGLFBORenderTexture.h index 76a957bb3a6..1651c141fd3 100644 --- a/RenderSystems/GL/include/OgreGLFBORenderTexture.h +++ b/RenderSystems/GL/include/OgreGLFBORenderTexture.h @@ -48,13 +48,13 @@ namespace Ogre { virtual void getCustomAttribute(const String& name, void* pData); - /// Override needed to deal with multisample buffers - virtual void swapBuffers(); + /// Override needed to deal with multisample buffers + virtual void swapBuffers(); - /// Override so we can attach the depth buffer to the FBO - virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); - virtual void detachDepthBuffer(); - virtual void _detachDepthBuffer(); + /// Override so we can attach the depth buffer to the FBO + virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); + virtual void detachDepthBuffer(); + virtual void _detachDepthBuffer(); protected: GLFrameBufferObject mFB; }; @@ -65,7 +65,7 @@ namespace Ogre { { public: GLFBOManager(bool atimode); - ~GLFBOManager(); + ~GLFBOManager(); /** Bind a certain render target if it is a FBO. If it is not a FBO, bind the main frame buffer. @@ -83,11 +83,11 @@ namespace Ogre { /** Create a texture rendertarget object */ virtual GLFBORenderTexture *createRenderTexture(const String &name, - const GLSurfaceDesc &target, bool writeGamma, uint fsaa); + const GLSurfaceDesc &target, bool writeGamma, uint fsaa); - /** Create a multi render target - */ - virtual MultiRenderTarget* createMultiRenderTarget(const String & name); + /** Create a multi render target + */ + virtual MultiRenderTarget* createMultiRenderTarget(const String & name); /** Request a render buffer. If format is GL_NONE, return a zero buffer. */ @@ -141,7 +141,7 @@ namespace Ogre { GLenum format; size_t width; size_t height; - uint samples; + uint samples; // Overloaded comparison operator for usage in map bool operator < (const RBFormat &other) const { @@ -159,11 +159,11 @@ namespace Ogre { { if(height < other.height) return true; - else if (height == other.height) - { - if (samples < other.samples) - return true; - } + else if (height == other.height) + { + if (samples < other.samples) + return true; + } } } return false; @@ -186,8 +186,8 @@ namespace Ogre { */ GLuint mTempFBO; - /// Buggy ATI driver? - bool mATIMode; + /// Buggy ATI driver? + bool mATIMode; /** Detect allowed FBO formats */ void detectFBOFormats(); diff --git a/RenderSystems/GL/include/OgreGLFrameBufferObject.h b/RenderSystems/GL/include/OgreGLFrameBufferObject.h index 6273f28aa93..c14ccb8e61c 100755 --- a/RenderSystems/GL/include/OgreGLFrameBufferObject.h +++ b/RenderSystems/GL/include/OgreGLFrameBufferObject.h @@ -53,44 +53,44 @@ namespace Ogre { */ void bind(); - /** Swap buffers - only useful when using multisample buffers. - */ - void swapBuffers(); + /** Swap buffers - only useful when using multisample buffers. + */ + void swapBuffers(); - /** This function acts very similar to @see GLFBORenderTexture::attachDepthBuffer - The difference between D3D & OGL is that D3D setups the DepthBuffer before rendering, - while OGL setups the DepthBuffer per FBO. So the DepthBuffer (RenderBuffer) needs to - be attached for OGL. - */ - void attachDepthBuffer( DepthBuffer *depthBuffer ); - void detachDepthBuffer(); - - /// Get the GL id for the FBO - GLuint getGLFBOID() const { return mFB; } - /// Get the GL id for the multisample FBO - GLuint getGLMultisampleFBOID() const { return mMultisampleFB; } + /** This function acts very similar to @see GLFBORenderTexture::attachDepthBuffer + The difference between D3D & OGL is that D3D setups the DepthBuffer before rendering, + while OGL setups the DepthBuffer per FBO. So the DepthBuffer (RenderBuffer) needs to + be attached for OGL. + */ + void attachDepthBuffer( DepthBuffer *depthBuffer ); + void detachDepthBuffer(); + + /// Get the GL id for the FBO + GLuint getGLFBOID() const { return mFB; } + /// Get the GL id for the multisample FBO + GLuint getGLMultisampleFBOID() const { return mMultisampleFB; } /// Accessors uint32 getWidth(); uint32 getHeight(); PixelFormat getFormat(); - GLsizei getFSAA(); + GLsizei getFSAA(); GLFBOManager *getManager() { return mManager; } - const GLSurfaceDesc &getSurface(size_t attachment) { return mColour[attachment]; } + const GLSurfaceDesc &getSurface(size_t attachment) { return mColour[attachment]; } private: GLFBOManager *mManager; - GLsizei mNumSamples; + GLsizei mNumSamples; GLuint mFB; - GLuint mMultisampleFB; - GLSurfaceDesc mMultisampleColourBuffer; + GLuint mMultisampleFB; + GLSurfaceDesc mMultisampleColourBuffer; GLSurfaceDesc mDepth; GLSurfaceDesc mStencil; // Arbitrary number of texture surfaces GLSurfaceDesc mColour[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - /** Initialise object (find suitable depth and stencil format). + /** Initialise object (find suitable depth and stencil format). Must be called every time the bindings change. It fails with an exception (ERR_INVALIDPARAMS) if: - Attachment point 0 has no binding diff --git a/RenderSystems/GL/include/OgreGLGpuNvparseProgram.h b/RenderSystems/GL/include/OgreGLGpuNvparseProgram.h index 12135149327..4fbee089e58 100644 --- a/RenderSystems/GL/include/OgreGLGpuNvparseProgram.h +++ b/RenderSystems/GL/include/OgreGLGpuNvparseProgram.h @@ -48,7 +48,7 @@ class _OgreGLExport GLGpuNvparseProgram : public GLGpuProgram /// Execute the unbinding functions for this program void unbindProgram(void); /// Execute the param binding functions for this program - void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask); + void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask); /// Get the assigned GL program id GLuint getProgramID(void) const diff --git a/RenderSystems/GL/include/OgreGLGpuProgram.h b/RenderSystems/GL/include/OgreGLGpuProgram.h index 234e25ba8db..f3d6e25e60b 100644 --- a/RenderSystems/GL/include/OgreGLGpuProgram.h +++ b/RenderSystems/GL/include/OgreGLGpuProgram.h @@ -49,9 +49,9 @@ namespace Ogre { virtual void unbindProgram(void) {} /// Execute the param binding functions for this program - virtual void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask) {} - /// Bind just the pass iteration parameters - virtual void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) {} + virtual void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask) {} + /// Bind just the pass iteration parameters + virtual void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) {} /// @copydoc Resource::calculateSize virtual size_t calculateSize(void) const; @@ -60,22 +60,22 @@ namespace Ogre { GLuint getProgramID(void) const { return mProgramID; } - /** Get the attribute index for a given semantic. - @remarks - This can be used to identify the attribute index to bind non-builtin - attributes like tangent and binormal. - */ - virtual GLuint getAttributeIndex(VertexElementSemantic semantic, uint index); - /** Test whether attribute index for a given semantic is valid. - */ - virtual bool isAttributeValid(VertexElementSemantic semantic, uint index); + /** Get the attribute index for a given semantic. + @remarks + This can be used to identify the attribute index to bind non-builtin + attributes like tangent and binormal. + */ + virtual GLuint getAttributeIndex(VertexElementSemantic semantic, uint index); + /** Test whether attribute index for a given semantic is valid. + */ + virtual bool isAttributeValid(VertexElementSemantic semantic, uint index); - /** Get the fixed attribute bindings normally used by GL for a semantic. */ - static GLuint getFixedAttributeIndex(VertexElementSemantic semantic, uint index); + /** Get the fixed attribute bindings normally used by GL for a semantic. */ + static GLuint getFixedAttributeIndex(VertexElementSemantic semantic, uint index); protected: - /** Overridden from GpuProgram, do nothing */ - void loadFromSource(void) {} + /** Overridden from GpuProgram, do nothing */ + void loadFromSource(void) {} /// @copydoc Resource::unloadImpl void unloadImpl(void) {} @@ -100,9 +100,9 @@ namespace Ogre { /// Execute the unbinding functions for this program void unbindProgram(void); /// Execute the param binding functions for this program - void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask); - /// Bind just the pass iteration parameters - void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params); + void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask); + /// Bind just the pass iteration parameters + void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params); /// Get the GL type for the program GLuint getProgramType(void) const diff --git a/RenderSystems/GL/include/OgreGLHardwareBufferManager.h b/RenderSystems/GL/include/OgreGLHardwareBufferManager.h index 0369dadb512..ac9fb15d26e 100644 --- a/RenderSystems/GL/include/OgreGLHardwareBufferManager.h +++ b/RenderSystems/GL/include/OgreGLHardwareBufferManager.h @@ -36,16 +36,16 @@ namespace Ogre { class GLStateCacheManager; // Default threshold at which glMapBuffer becomes more efficient than glBufferSubData (32k?) -# define OGRE_GL_DEFAULT_MAP_BUFFER_THRESHOLD (1024 * 32) +# define OGRE_GL_DEFAULT_MAP_BUFFER_THRESHOLD (1024 * 32) /** Implementation of HardwareBufferManager for OpenGL. */ class _OgreGLExport GLHardwareBufferManagerBase : public HardwareBufferManagerBase { - protected: + protected: GLStateCacheManager* mStateCacheManager; - char* mScratchBufferPool; - OGRE_MUTEX(mScratchMutex); - size_t mMapBufferThreshold; + char* mScratchBufferPool; + OGRE_MUTEX(mScratchMutex); + size_t mMapBufferThreshold; public: GLHardwareBufferManagerBase(); @@ -59,9 +59,9 @@ namespace Ogre { HardwareBuffer::Usage usage, bool useShadowBuffer = false); /// Create a render to vertex buffer RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); - /// Create a uniform buffer - HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name = ""); - HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, + /// Create a uniform buffer + HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name = ""); + HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, bool useShadowBuffer = false, const String& name = ""); /// Utility function to get the correct GL usage based on HBU's @@ -72,78 +72,78 @@ namespace Ogre { GLStateCacheManager * getStateCacheManager() { return mStateCacheManager; } - /** Allocator method to allow us to use a pool of memory as a scratch - area for hardware buffers. This is because glMapBuffer is incredibly - inefficient, seemingly no matter what options we give it. So for the - period of lock/unlock, we will instead allocate a section of a local - memory pool, and use glBufferSubDataARB / glGetBufferSubDataARB - instead. - */ - void* allocateScratch(uint32 size); - - /// @see allocateScratch - void deallocateScratch(void* ptr); - - /** Threshold after which glMapBuffer is used and not glBufferSubData - */ - size_t getGLMapBufferThreshold() const; - void setGLMapBufferThreshold( const size_t value ); + /** Allocator method to allow us to use a pool of memory as a scratch + area for hardware buffers. This is because glMapBuffer is incredibly + inefficient, seemingly no matter what options we give it. So for the + period of lock/unlock, we will instead allocate a section of a local + memory pool, and use glBufferSubDataARB / glGetBufferSubDataARB + instead. + */ + void* allocateScratch(uint32 size); + + /// @see allocateScratch + void deallocateScratch(void* ptr); + + /** Threshold after which glMapBuffer is used and not glBufferSubData + */ + size_t getGLMapBufferThreshold() const; + void setGLMapBufferThreshold( const size_t value ); }; - /// GLHardwareBufferManagerBase as a Singleton - class _OgreGLExport GLHardwareBufferManager : public HardwareBufferManager - { - public: - GLHardwareBufferManager() - : HardwareBufferManager(OGRE_NEW GLHardwareBufferManagerBase()) - { - - } - ~GLHardwareBufferManager() - { - OGRE_DELETE mImpl; - } - - - - /// Utility function to get the correct GL usage based on HBU's - static GLenum getGLUsage(unsigned int usage) - { return GLHardwareBufferManagerBase::getGLUsage(usage); } - - /// Utility function to get the correct GL type based on VET's - static GLenum getGLType(unsigned int type) - { return GLHardwareBufferManagerBase::getGLType(type); } - - /** Allocator method to allow us to use a pool of memory as a scratch - area for hardware buffers. This is because glMapBuffer is incredibly - inefficient, seemingly no matter what options we give it. So for the - period of lock/unlock, we will instead allocate a section of a local - memory pool, and use glBufferSubDataARB / glGetBufferSubDataARB - instead. - */ - void* allocateScratch(uint32 size) - { - return static_cast(mImpl)->allocateScratch(size); - } - - /// @see allocateScratch - void deallocateScratch(void* ptr) - { - static_cast(mImpl)->deallocateScratch(ptr); - } - - /** Threshold after which glMapBuffer is used and not glBufferSubData - */ - size_t getGLMapBufferThreshold() const - { - return static_cast(mImpl)->getGLMapBufferThreshold(); - } - void setGLMapBufferThreshold( const size_t value ) - { - static_cast(mImpl)->setGLMapBufferThreshold(value); - } - - }; + /// GLHardwareBufferManagerBase as a Singleton + class _OgreGLExport GLHardwareBufferManager : public HardwareBufferManager + { + public: + GLHardwareBufferManager() + : HardwareBufferManager(OGRE_NEW GLHardwareBufferManagerBase()) + { + + } + ~GLHardwareBufferManager() + { + OGRE_DELETE mImpl; + } + + + + /// Utility function to get the correct GL usage based on HBU's + static GLenum getGLUsage(unsigned int usage) + { return GLHardwareBufferManagerBase::getGLUsage(usage); } + + /// Utility function to get the correct GL type based on VET's + static GLenum getGLType(unsigned int type) + { return GLHardwareBufferManagerBase::getGLType(type); } + + /** Allocator method to allow us to use a pool of memory as a scratch + area for hardware buffers. This is because glMapBuffer is incredibly + inefficient, seemingly no matter what options we give it. So for the + period of lock/unlock, we will instead allocate a section of a local + memory pool, and use glBufferSubDataARB / glGetBufferSubDataARB + instead. + */ + void* allocateScratch(uint32 size) + { + return static_cast(mImpl)->allocateScratch(size); + } + + /// @see allocateScratch + void deallocateScratch(void* ptr) + { + static_cast(mImpl)->deallocateScratch(ptr); + } + + /** Threshold after which glMapBuffer is used and not glBufferSubData + */ + size_t getGLMapBufferThreshold() const + { + return static_cast(mImpl)->getGLMapBufferThreshold(); + } + void setGLMapBufferThreshold( const size_t value ) + { + static_cast(mImpl)->setGLMapBufferThreshold(value); + } + + }; } diff --git a/RenderSystems/GL/include/OgreGLHardwareIndexBuffer.h b/RenderSystems/GL/include/OgreGLHardwareIndexBuffer.h index 25ac649102a..5ca99392fe1 100644 --- a/RenderSystems/GL/include/OgreGLHardwareIndexBuffer.h +++ b/RenderSystems/GL/include/OgreGLHardwareIndexBuffer.h @@ -38,12 +38,12 @@ namespace Ogre { { private: GLuint mBufferId; - // Scratch buffer handling - bool mLockedToScratch; - size_t mScratchOffset; - size_t mScratchSize; - void* mScratchPtr; - bool mScratchUploadOnUnlock; + // Scratch buffer handling + bool mLockedToScratch; + size_t mScratchOffset; + size_t mScratchSize; + void* mScratchPtr; + bool mScratchUploadOnUnlock; protected: /** See HardwareBuffer. */ void* lockImpl(size_t offset, size_t length, LockOptions options); diff --git a/RenderSystems/GL/include/OgreGLHardwareOcclusionQuery.h b/RenderSystems/GL/include/OgreGLHardwareOcclusionQuery.h index c1f897e4b19..b667594dd6e 100644 --- a/RenderSystems/GL/include/OgreGLHardwareOcclusionQuery.h +++ b/RenderSystems/GL/include/OgreGLHardwareOcclusionQuery.h @@ -75,23 +75,23 @@ class _OgreGLExport GLHardwareOcclusionQuery : public HardwareOcclusionQuery // Public methods //-- public: - /** - * Default object constructor - * - */ - GLHardwareOcclusionQuery(); - /** - * Object destructor - */ - ~GLHardwareOcclusionQuery(); - - //------------------------------------------------------------------ - // Occlusion query functions (see base class documentation for this) - //-- - void beginOcclusionQuery(); - void endOcclusionQuery(); - bool pullOcclusionQuery( unsigned int* NumOfFragments); - bool isStillOutstanding(void); + /** + * Default object constructor + * + */ + GLHardwareOcclusionQuery(); + /** + * Object destructor + */ + ~GLHardwareOcclusionQuery(); + + //------------------------------------------------------------------ + // Occlusion query functions (see base class documentation for this) + //-- + void beginOcclusionQuery(); + void endOcclusionQuery(); + bool pullOcclusionQuery( unsigned int* NumOfFragments); + bool isStillOutstanding(void); //---------------------------------------------------------------------- @@ -99,7 +99,7 @@ class _OgreGLExport GLHardwareOcclusionQuery : public HardwareOcclusionQuery //-- private: - GLuint mQueryID; + GLuint mQueryID; }; } diff --git a/RenderSystems/GL/include/OgreGLHardwarePixelBuffer.h b/RenderSystems/GL/include/OgreGLHardwarePixelBuffer.h index 25f41f5be5d..26a4ebea879 100644 --- a/RenderSystems/GL/include/OgreGLHardwarePixelBuffer.h +++ b/RenderSystems/GL/include/OgreGLHardwarePixelBuffer.h @@ -32,56 +32,56 @@ THE SOFTWARE. #include "OgreHardwarePixelBuffer.h" namespace Ogre { - class _OgreGLExport GLHardwarePixelBuffer: public HardwarePixelBuffer - { - protected: - /// Lock a box - PixelBox lockImpl(const Image::Box &lockBox, LockOptions options); + class _OgreGLExport GLHardwarePixelBuffer: public HardwarePixelBuffer + { + protected: + /// Lock a box + PixelBox lockImpl(const Image::Box &lockBox, LockOptions options); - /// Unlock a box - void unlockImpl(void); + /// Unlock a box + void unlockImpl(void); - /** Internal buffer; either on-card or in system memory, freed/allocated on demand + /** Internal buffer; either on-card or in system memory, freed/allocated on demand depending on buffer usage */ - PixelBox mBuffer; + PixelBox mBuffer; GLenum mGLInternalFormat; /// GL internal format - LockOptions mCurrentLockOptions; - - /// Buffer allocation/freeage - void allocateBuffer(); - void freeBuffer(); - /// Upload a box of pixels to this buffer on the card - virtual void upload(const PixelBox &data, const Image::Box &dest); - /// Download a box of pixels from the card - virtual void download(const PixelBox &data); - public: + LockOptions mCurrentLockOptions; + + /// Buffer allocation/freeage + void allocateBuffer(); + void freeBuffer(); + /// Upload a box of pixels to this buffer on the card + virtual void upload(const PixelBox &data, const Image::Box &dest); + /// Download a box of pixels from the card + virtual void download(const PixelBox &data); + public: /// Should be called by HardwareBufferManager GLHardwarePixelBuffer(uint32 mWidth, uint32 mHeight, uint32 mDepth, PixelFormat mFormat, HardwareBuffer::Usage usage); - - /// @copydoc HardwarePixelBuffer::blitFromMemory - void blitFromMemory(const PixelBox &src, const Image::Box &dstBox); - - /// @copydoc HardwarePixelBuffer::blitToMemory - void blitToMemory(const Image::Box &srcBox, const PixelBox &dst); - - ~GLHardwarePixelBuffer(); + + /// @copydoc HardwarePixelBuffer::blitFromMemory + void blitFromMemory(const PixelBox &src, const Image::Box &dstBox); + + /// @copydoc HardwarePixelBuffer::blitToMemory + void blitToMemory(const Image::Box &srcBox, const PixelBox &dst); + + ~GLHardwarePixelBuffer(); /** Bind surface to frame buffer. Needs FBO extension. */ virtual void bindToFramebuffer(GLenum attachment, uint32 zoffset); GLenum getGLFormat() { return mGLInternalFormat; } - }; + }; /** Texture surface. */ class _OgreGLExport GLTextureBuffer: public GLHardwarePixelBuffer - { + { public: /** Texture constructor */ GLTextureBuffer(GLSupport& support, const String &baseName, GLenum target, GLuint id, GLint face, - GLint level, Usage usage, bool softwareMipmap, bool writeGamma, uint fsaa); + GLint level, Usage usage, bool softwareMipmap, bool writeGamma, uint fsaa); ~GLTextureBuffer(); /// @copydoc GLHardwarePixelBuffer::bindToFramebuffer @@ -89,9 +89,9 @@ namespace Ogre { /// @copydoc HardwarePixelBuffer::getRenderTarget RenderTexture* getRenderTarget(size_t slice); /// Upload a box of pixels to this buffer on the card - virtual void upload(const PixelBox &data, const Image::Box &dest); - /// Download a box of pixels from the card - virtual void download(const PixelBox &data); + virtual void upload(const PixelBox &data, const Image::Box &dest); + /// Download a box of pixels from the card + virtual void download(const PixelBox &data); /// Hardware implementation of blitFromMemory virtual void blitFromMemory(const PixelBox &src_orig, const Image::Box &dstBox); @@ -109,12 +109,12 @@ namespace Ogre { void blitFromTexture(GLTextureBuffer *src, const Image::Box &srcBox, const Image::Box &dstBox); protected: // In case this is a texture level - GLenum mTarget; - GLenum mFaceTarget; // same as mTarget in case of GL_TEXTURE_xD, but cubemap face for cubemaps - GLuint mTextureID; - GLint mFace; - GLint mLevel; - bool mSoftwareMipmap; // Use GLU for mip mapping + GLenum mTarget; + GLenum mFaceTarget; // same as mTarget in case of GL_TEXTURE_xD, but cubemap face for cubemaps + GLuint mTextureID; + GLint mFace; + GLint mLevel; + bool mSoftwareMipmap; // Use GLU for mip mapping bool mHwGamma; typedef vector::type SliceTRT; @@ -125,7 +125,7 @@ namespace Ogre { /** Renderbuffer surface. Needs FBO extension. */ class _OgreGLExport GLRenderBuffer: public GLHardwarePixelBuffer - { + { public: GLRenderBuffer(GLenum format, uint32 width, uint32 height, GLsizei numSamples); ~GLRenderBuffer(); diff --git a/RenderSystems/GL/include/OgreGLHardwareVertexBuffer.h b/RenderSystems/GL/include/OgreGLHardwareVertexBuffer.h index 7deb960b93d..e64a0d0060d 100644 --- a/RenderSystems/GL/include/OgreGLHardwareVertexBuffer.h +++ b/RenderSystems/GL/include/OgreGLHardwareVertexBuffer.h @@ -38,12 +38,12 @@ namespace Ogre { { private: GLuint mBufferId; - // Scratch buffer handling - bool mLockedToScratch; - size_t mScratchOffset; - size_t mScratchSize; - void* mScratchPtr; - bool mScratchUploadOnUnlock; + // Scratch buffer handling + bool mLockedToScratch; + size_t mScratchOffset; + size_t mScratchSize; + void* mScratchPtr; + bool mScratchUploadOnUnlock; protected: /** See HardwareBuffer. */ diff --git a/RenderSystems/GL/include/OgreGLPBRenderTexture.h b/RenderSystems/GL/include/OgreGLPBRenderTexture.h index 889d60d7407..fe1f67a5f8e 100755 --- a/RenderSystems/GL/include/OgreGLPBRenderTexture.h +++ b/RenderSystems/GL/include/OgreGLPBRenderTexture.h @@ -59,7 +59,7 @@ namespace Ogre { /** @copydoc GLRTTManager::createRenderTexture */ virtual RenderTexture *createRenderTexture(const String &name, - const GLSurfaceDesc &target, bool writeGamma, uint fsaa); + const GLSurfaceDesc &target, bool writeGamma, uint fsaa); /** @copydoc GLRTTManager::checkFormat */ @@ -87,10 +87,10 @@ namespace Ogre { protected: /** GLSupport reference, used to create PBuffers */ GLSupport *mSupport; - /** Primary window reference */ - RenderTarget *mMainWindow; - /** Primary window context */ - GLContext *mMainContext; + /** Primary window reference */ + RenderTarget *mMainWindow; + /** Primary window context */ + GLContext *mMainContext; /** Reference to a PBuffer, with refcount */ struct PBRef { diff --git a/RenderSystems/GL/include/OgreGLPixelFormat.h b/RenderSystems/GL/include/OgreGLPixelFormat.h index 9272cf0eab5..00ec6046766 100644 --- a/RenderSystems/GL/include/OgreGLPixelFormat.h +++ b/RenderSystems/GL/include/OgreGLPixelFormat.h @@ -32,69 +32,69 @@ THE SOFTWARE. #include "OgrePixelFormat.h" namespace Ogre { - /** - * Class to do pixel format mapping between GL and OGRE - */ - class _OgreGLExport GLPixelUtil - { - public: - /** Takes the OGRE pixel format and returns the appropriate GL one - @return a GLenum describing the format, or 0 if there is no exactly matching - one (and conversion is needed) - */ - static GLenum getGLOriginFormat(PixelFormat mFormat); - - /** Takes the OGRE pixel format and returns type that must be provided - to GL as data type for reading it into the GPU - @return a GLenum describing the data type, or 0 if there is no exactly matching - one (and conversion is needed) - */ - static GLenum getGLOriginDataType(PixelFormat mFormat); + /** + * Class to do pixel format mapping between GL and OGRE + */ + class _OgreGLExport GLPixelUtil + { + public: + /** Takes the OGRE pixel format and returns the appropriate GL one + @return a GLenum describing the format, or 0 if there is no exactly matching + one (and conversion is needed) + */ + static GLenum getGLOriginFormat(PixelFormat mFormat); + + /** Takes the OGRE pixel format and returns type that must be provided + to GL as data type for reading it into the GPU + @return a GLenum describing the data type, or 0 if there is no exactly matching + one (and conversion is needed) + */ + static GLenum getGLOriginDataType(PixelFormat mFormat); + + /** Takes the OGRE pixel format and returns the type that must be provided + to GL as internal format. GL_NONE if no match exists. + @param mFormat The pixel format + @param hwGamma Whether a hardware gamma-corrected version is requested + */ + static GLenum getGLInternalFormat(PixelFormat mFormat, bool hwGamma = false); + + /** Takes the OGRE pixel format and returns the type that must be provided + to GL as internal format. If no match exists, returns the closest match. + @param mFormat The pixel format + @param hwGamma Whether a hardware gamma-corrected version is requested + */ + static GLenum getClosestGLInternalFormat(PixelFormat mFormat, bool hwGamma = false); - /** Takes the OGRE pixel format and returns the type that must be provided - to GL as internal format. GL_NONE if no match exists. - @param mFormat The pixel format - @param hwGamma Whether a hardware gamma-corrected version is requested - */ - static GLenum getGLInternalFormat(PixelFormat mFormat, bool hwGamma = false); - - /** Takes the OGRE pixel format and returns the type that must be provided - to GL as internal format. If no match exists, returns the closest match. - @param mFormat The pixel format - @param hwGamma Whether a hardware gamma-corrected version is requested - */ - static GLenum getClosestGLInternalFormat(PixelFormat mFormat, bool hwGamma = false); - - /** Function to get the closest matching OGRE format to an internal GL format. To be - precise, the format will be chosen that is most efficient to transfer to the card - without losing precision. - @remarks It is valid for this function to always return PF_A8R8G8B8. - */ - static PixelFormat getClosestOGREFormat(GLenum fmt); - - /** Returns the maximum number of Mipmaps that can be generated until we reach - the mininum format possible. This does not count the base level. - @param width - The width of the area - @param height - The height of the area - @param depth - The depth of the area - @param format - The format of the area - @remarks - In case that the format is non-compressed, this simply returns - how many times we can divide this texture in 2 until we reach 1x1. - For compressed formats, constraints apply on minimum size and alignment - so this might differ. - */ - static size_t getMaxMipmaps(uint32 width, uint32 height, uint32 depth, PixelFormat format); + /** Function to get the closest matching OGRE format to an internal GL format. To be + precise, the format will be chosen that is most efficient to transfer to the card + without losing precision. + @remarks It is valid for this function to always return PF_A8R8G8B8. + */ + static PixelFormat getClosestOGREFormat(GLenum fmt); + + /** Returns the maximum number of Mipmaps that can be generated until we reach + the mininum format possible. This does not count the base level. + @param width + The width of the area + @param height + The height of the area + @param depth + The depth of the area + @param format + The format of the area + @remarks + In case that the format is non-compressed, this simply returns + how many times we can divide this texture in 2 until we reach 1x1. + For compressed formats, constraints apply on minimum size and alignment + so this might differ. + */ + static size_t getMaxMipmaps(uint32 width, uint32 height, uint32 depth, PixelFormat format); /** Returns next power-of-two size if required by render system, in case RSC_NON_POWER_OF_2_TEXTURES is supported it returns value as-is. */ static uint32 optionalPO2(uint32 value); - }; + }; } #endif diff --git a/RenderSystems/GL/include/OgreGLPlugin.h b/RenderSystems/GL/include/OgreGLPlugin.h index b86ea5dcc6b..2763764a323 100644 --- a/RenderSystems/GL/include/OgreGLPlugin.h +++ b/RenderSystems/GL/include/OgreGLPlugin.h @@ -34,30 +34,30 @@ THE SOFTWARE. namespace Ogre { - /** Plugin instance for GL Manager */ - class GLPlugin : public Plugin - { - public: - GLPlugin(); + /** Plugin instance for GL Manager */ + class GLPlugin : public Plugin + { + public: + GLPlugin(); - /// @copydoc Plugin::getName - const String& getName() const; + /// @copydoc Plugin::getName + const String& getName() const; - /// @copydoc Plugin::install - void install(); + /// @copydoc Plugin::install + void install(); - /// @copydoc Plugin::initialise - void initialise(); + /// @copydoc Plugin::initialise + void initialise(); - /// @copydoc Plugin::shutdown - void shutdown(); + /// @copydoc Plugin::shutdown + void shutdown(); - /// @copydoc Plugin::uninstall - void uninstall(); - protected: - GLRenderSystem* mRenderSystem; - }; + /// @copydoc Plugin::uninstall + void uninstall(); + protected: + GLRenderSystem* mRenderSystem; + }; } #endif diff --git a/RenderSystems/GL/include/OgreGLPrerequisites.h b/RenderSystems/GL/include/OgreGLPrerequisites.h index 405dc34d1b7..463d19a17ef 100644 --- a/RenderSystems/GL/include/OgreGLPrerequisites.h +++ b/RenderSystems/GL/include/OgreGLPrerequisites.h @@ -42,21 +42,21 @@ namespace Ogre { class GLFBOManager; class GLHardwarePixelBuffer; class GLRenderBuffer; - class GLDepthBuffer; + class GLDepthBuffer; typedef SharedPtr GLGpuProgramPtr; typedef SharedPtr GLTexturePtr; } #if OGRE_THREAD_SUPPORT == 1 -# define GLEW_MX +# define GLEW_MX #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #if !defined( __MINGW32__ ) # define WIN32_LEAN_AND_MEAN # ifndef NOMINMAX -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif #endif # include @@ -74,13 +74,13 @@ namespace Ogre { #endif #if OGRE_THREAD_SUPPORT == 1 - // implemented in OgreGLContext.cpp - GLEWContext * glewGetContext(); + // implemented in OgreGLContext.cpp + GLEWContext * glewGetContext(); -# if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - // implemented in OgreWin32Context.cpp - WGLEWContext * wglewGetContext(); -# endif +# if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 + // implemented in OgreWin32Context.cpp + WGLEWContext * wglewGetContext(); +# endif #endif @@ -90,15 +90,15 @@ namespace Ogre { #endif #if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) && !defined(__MINGW32__) && !defined(OGRE_STATIC_LIB) -# ifdef OGRE_GLPLUGIN_EXPORTS -# define _OgreGLExport __declspec(dllexport) -# else +# ifdef OGRE_GLPLUGIN_EXPORTS +# define _OgreGLExport __declspec(dllexport) +# else # if defined( __MINGW32__ ) # define _OgreGLExport # else -# define _OgreGLExport __declspec(dllimport) +# define _OgreGLExport __declspec(dllimport) # endif -# endif +# endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgreGLExport __attribute__ ((visibility("default"))) #else diff --git a/RenderSystems/GL/include/OgreGLRenderSystem.h b/RenderSystems/GL/include/OgreGLRenderSystem.h index 3334ed38c7e..fa555e084f0 100644 --- a/RenderSystems/GL/include/OgreGLRenderSystem.h +++ b/RenderSystems/GL/include/OgreGLRenderSystem.h @@ -45,7 +45,7 @@ namespace Ogre { class GLStateCacheManager; - /** + /** Implementation of GL as a rendering system. */ class _OgreGLExport GLRenderSystem : public RenderSystem @@ -86,27 +86,27 @@ namespace Ogre { void makeGLMatrix(GLfloat gl_matrix[16], const Matrix4& m); GLint getBlendMode(SceneBlendFactor ogreBlend) const; - GLint getTextureAddressingMode(TextureUnitState::TextureAddressingMode tam) const; - void initialiseContext(RenderWindow* primary); + GLint getTextureAddressingMode(TextureUnitState::TextureAddressingMode tam) const; + void initialiseContext(RenderWindow* primary); void setLights(); /// Store last depth write state bool mDepthWrite; - /// Store last stencil mask state - uint32 mStencilWriteMask; - /// Store last colour write state - bool mColourWrite[4]; + /// Store last stencil mask state + uint32 mStencilWriteMask; + /// Store last colour write state + bool mColourWrite[4]; - /// Store scissor box - int mScissorBox[4]; + /// Store scissor box + int mScissorBox[4]; GLint convertCompareFunction(CompareFunction func) const; GLint convertStencilOp(StencilOperation op, bool invert = false) const; - /// Internal method for anisotropy validation - GLfloat _getCurrentAnisotropy(size_t unit); - + /// Internal method for anisotropy validation + GLfloat _getCurrentAnisotropy(size_t unit); + /// GL support class, used for creating windows etc. GLSupport* mGLSupport; @@ -129,22 +129,22 @@ namespace Ogre { GLGpuProgram* mCurrentVertexProgram; GLGpuProgram* mCurrentFragmentProgram; - GLGpuProgram* mCurrentGeometryProgram; + GLGpuProgram* mCurrentGeometryProgram; - /* The main GL context - main thread only */ + /* The main GL context - main thread only */ GLContext *mMainContext; /* The current GL context - main thread only */ GLContext *mCurrentContext; - typedef list::type GLContextList; - /// List of background thread contexts - GLContextList mBackgroundContextList; + typedef list::type GLContextList; + /// List of background thread contexts + GLContextList mBackgroundContextList; - GLStateCacheManager* mStateCacheManager; + GLStateCacheManager* mStateCacheManager; /** Manager object for creating render textures. Direct render to texture via GL_EXT_framebuffer_object is preferable - to pbuffers, which depend on the GL support used and are generally - unwieldy and slow. However, FBO support for stencil buffers is poor. + to pbuffers, which depend on the GL support used and are generally + unwieldy and slow. However, FBO support for stencil buffers is poor. */ GLRTTManager *mRTTManager; @@ -156,8 +156,8 @@ namespace Ogre { vector::type mRenderInstanceAttribsBound; - protected: - void setClipPlanesImpl(const PlaneList& clipPlanes); + protected: + void setClipPlanesImpl(const PlaneList& clipPlanes); void bindVertexElementToGpu( const VertexElement &elem, HardwareVertexBufferSharedPtr vertexBuffer, const size_t vertexStart, vector::type &attribsBound, vector::type &instanceAttribsBound ); @@ -233,10 +233,10 @@ namespace Ogre { /// Mimics D3D9RenderSystem::_getDepthStencilFormatFor, if no FBO RTT manager, outputs GL_NONE void _getDepthStencilFormatFor( GLenum internalColourFormat, GLenum *depthFormat, GLenum *stencilFormat ); - + /// @copydoc RenderSystem::createMultiRenderTarget virtual MultiRenderTarget * createMultiRenderTarget(const String & name); - + /** See RenderSystem */ @@ -265,7 +265,7 @@ namespace Ogre { /** See RenderSystem */ - bool areFixedFunctionLightsInViewSpace() const { return true; } + bool areFixedFunctionLightsInViewSpace() const { return true; } /** See RenderSystem */ @@ -288,33 +288,33 @@ namespace Ogre { /** See RenderSystem */ - void _setPointParameters(Real size, bool attenuationEnabled, - Real constant, Real linear, Real quadratic, Real minSize, Real maxSize); + void _setPointParameters(Real size, bool attenuationEnabled, + Real constant, Real linear, Real quadratic, Real minSize, Real maxSize); /** See RenderSystem */ - void _setPointSpritesEnabled(bool enabled); - /** See + void _setPointSpritesEnabled(bool enabled); + /** See RenderSystem */ void _setTexture(size_t unit, bool enabled, const TexturePtr &tex); - /** See + /** See RenderSystem */ - void _setVertexTexture(size_t unit, const TexturePtr &tex); - /** See + void _setVertexTexture(size_t unit, const TexturePtr &tex); + /** See RenderSystem */ void _setGeometryTexture(size_t unit, const TexturePtr &tex); - /** See + /** See RenderSystem */ void _setComputeTexture(size_t unit, const TexturePtr &tex); - /** See + /** See RenderSystem */ void _setTesselationHullTexture(size_t unit, const TexturePtr &tex); - /** See + /** See RenderSystem */ void _setTesselationDomainTexture(size_t unit, const TexturePtr &tex); @@ -339,10 +339,10 @@ namespace Ogre { RenderSystem */ void _setTextureBorderColour(size_t stage, const ColourValue& colour); - /** See - RenderSystem - */ - void _setTextureMipmapBias(size_t unit, float bias); + /** See + RenderSystem + */ + void _setTextureMipmapBias(size_t unit, float bias); /** See RenderSystem */ @@ -354,16 +354,16 @@ namespace Ogre { /** See RenderSystem */ - void _setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ); + void _setSeparateSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ); /** See RenderSystem */ - void _setSceneBlendingOperation(SceneBlendOperation op); - /** See + void _setSceneBlendingOperation(SceneBlendOperation op); + /** See RenderSystem */ - void _setSeparateSceneBlendingOperation(SceneBlendOperation op, SceneBlendOperation alphaOp); - /** See + void _setSeparateSceneBlendingOperation(SceneBlendOperation op, SceneBlendOperation alphaOp); + /** See RenderSystem */ void _setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage); @@ -407,7 +407,7 @@ namespace Ogre { RenderSystem */ void _setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha); - /** See + /** See RenderSystem */ void _setFog(FogMode mode, const ColourValue& colour, Real density, Real start, Real end); @@ -429,7 +429,7 @@ namespace Ogre { /** See RenderSystem */ - void _makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, + void _makeOrthoMatrix(const Radian& fovy, Real aspect, Real nearPlane, Real farPlane, Matrix4& dest, bool forGpuProgram = false); /** See RenderSystem @@ -457,35 +457,35 @@ namespace Ogre { */ void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS, uint32 refValue = 0, uint32 compareMask = 0xFFFFFFFF, uint32 writeMask = 0xFFFFFFFF, - StencilOperation stencilFailOp = SOP_KEEP, + StencilOperation stencilFailOp = SOP_KEEP, StencilOperation depthFailOp = SOP_KEEP, StencilOperation passOp = SOP_KEEP, - bool twoSidedOperation = false, - bool readBackAsTexture = false); + bool twoSidedOperation = false, + bool readBackAsTexture = false); /** See RenderSystem */ void _setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions filter); - /** See + /** See RenderSystem */ - void _setTextureUnitCompareFunction(size_t unit, CompareFunction function); - /** See + void _setTextureUnitCompareFunction(size_t unit, CompareFunction function); + /** See RenderSystem */ - void _setTextureUnitCompareEnabled(size_t unit, bool compare); + void _setTextureUnitCompareEnabled(size_t unit, bool compare); /** See RenderSystem */ - void _setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy); + void _setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy); /** See RenderSystem */ - void setVertexDeclaration(VertexDeclaration* decl); + void setVertexDeclaration(VertexDeclaration* decl); /** See RenderSystem */ - void setVertexBufferBinding(VertexBufferBinding* binding); + void setVertexBufferBinding(VertexBufferBinding* binding); /** See RenderSystem */ @@ -549,22 +549,22 @@ namespace Ogre { GLContext. */ void _unregisterContext(GLContext *context); - /** Returns the main context */ - GLContext* _getMainContext() {return mMainContext;} + /** Returns the main context */ + GLContext* _getMainContext() {return mMainContext;} - /// @copydoc RenderSystem::getDisplayMonitorCount - unsigned int getDisplayMonitorCount() const; + /// @copydoc RenderSystem::getDisplayMonitorCount + unsigned int getDisplayMonitorCount() const; - /// @copydoc RenderSystem::hasAnisotropicMipMapFilter - virtual bool hasAnisotropicMipMapFilter() const { return false; } + /// @copydoc RenderSystem::hasAnisotropicMipMapFilter + virtual bool hasAnisotropicMipMapFilter() const { return false; } - /// @copydoc RenderSystem::beginProfileEvent + /// @copydoc RenderSystem::beginProfileEvent virtual void beginProfileEvent( const String &eventName ); - /// @copydoc RenderSystem::endProfileEvent + /// @copydoc RenderSystem::endProfileEvent virtual void endProfileEvent( void ); - /// @copydoc RenderSystem::markProfileEvent + /// @copydoc RenderSystem::markProfileEvent virtual void markProfileEvent( const String &eventName ); }; } diff --git a/RenderSystems/GL/include/OgreGLRenderTexture.h b/RenderSystems/GL/include/OgreGLRenderTexture.h index c7c6a306480..d2e8c545e8d 100755 --- a/RenderSystems/GL/include/OgreGLRenderTexture.h +++ b/RenderSystems/GL/include/OgreGLRenderTexture.h @@ -39,9 +39,9 @@ namespace Ogre { public: GLHardwarePixelBuffer *buffer; uint32 zoffset; - uint numSamples; + uint numSamples; - GLSurfaceDesc() :buffer(0), zoffset(0), numSamples(0) {} + GLSurfaceDesc() :buffer(0), zoffset(0), numSamples(0) {} }; /** Base class for GL Render Textures @@ -84,15 +84,15 @@ namespace Ogre { */ virtual void unbind(RenderTarget *target) = 0; - virtual void getBestDepthStencil(GLenum internalFormat, GLenum *depthFormat, GLenum *stencilFormat) - { - *depthFormat = GL_NONE; - *stencilFormat = GL_NONE; - } + virtual void getBestDepthStencil(GLenum internalFormat, GLenum *depthFormat, GLenum *stencilFormat) + { + *depthFormat = GL_NONE; + *stencilFormat = GL_NONE; + } - /** Create a multi render target - */ - virtual MultiRenderTarget* createMultiRenderTarget(const String & name); + /** Create a multi render target + */ + virtual MultiRenderTarget* createMultiRenderTarget(const String & name); /** Get the closest supported alternative format. If format is supported, returns format. */ @@ -106,7 +106,7 @@ namespace Ogre { { public: GLCopyingRenderTexture(GLCopyingRTTManager *manager, const String &name, const GLSurfaceDesc &target, - bool writeGamma, uint fsaa); + bool writeGamma, uint fsaa); virtual void getCustomAttribute(const String& name, void* pData); }; diff --git a/RenderSystems/GL/include/OgreGLRenderToVertexBuffer.h b/RenderSystems/GL/include/OgreGLRenderToVertexBuffer.h index 671d1816924..94ee959811f 100644 --- a/RenderSystems/GL/include/OgreGLRenderToVertexBuffer.h +++ b/RenderSystems/GL/include/OgreGLRenderToVertexBuffer.h @@ -41,12 +41,12 @@ namespace Ogre { that run on previous results of those shaders, creating stateful shaders. */ - class _OgreGLExport GLRenderToVertexBuffer : public RenderToVertexBuffer + class _OgreGLExport GLRenderToVertexBuffer : public RenderToVertexBuffer { public: - /** C'tor */ - GLRenderToVertexBuffer(); - /** D'tor */ + /** C'tor */ + GLRenderToVertexBuffer(); + /** D'tor */ virtual ~GLRenderToVertexBuffer(); /** @@ -58,14 +58,14 @@ namespace Ogre { Update the contents of this vertex buffer by rendering */ virtual void update(SceneManager* sceneMgr); - protected: - void reallocateBuffer(size_t index); - void bindVerticesOutput(Pass* pass); - GLint getGLSemanticType(VertexElementSemantic semantic); - String getSemanticVaryingName(VertexElementSemantic semantic, unsigned short index); - HardwareVertexBufferSharedPtr mVertexBuffers[2]; - size_t mFrontBufferIndex; - GLuint mPrimitivesDrawnQuery; + protected: + void reallocateBuffer(size_t index); + void bindVerticesOutput(Pass* pass); + GLint getGLSemanticType(VertexElementSemantic semantic); + String getSemanticVaryingName(VertexElementSemantic semantic, unsigned short index); + HardwareVertexBufferSharedPtr mVertexBuffers[2]; + size_t mFrontBufferIndex; + GLuint mPrimitivesDrawnQuery; }; } diff --git a/RenderSystems/GL/include/OgreGLStateCacheManager.h b/RenderSystems/GL/include/OgreGLStateCacheManager.h index 696fcf713c8..e42c9f1843e 100644 --- a/RenderSystems/GL/include/OgreGLStateCacheManager.h +++ b/RenderSystems/GL/include/OgreGLStateCacheManager.h @@ -37,7 +37,7 @@ typedef Ogre::GeneralAllocatedObject StateCacheAlloc; namespace Ogre { - class GLStateCacheManagerImp; + class GLStateCacheManagerImp; /** An in memory cache of the OpenGL state. @remarks @@ -55,11 +55,11 @@ namespace Ogre class _OgreGLExport GLStateCacheManager : public StateCacheAlloc { private: - GLStateCacheManagerImp* mImp; + GLStateCacheManagerImp* mImp; typedef map::type CachesMap; typedef MapIterator CachesMapIterator; - CachesMap mCaches; + CachesMap mCaches; public: GLStateCacheManager(void); @@ -79,22 +79,22 @@ namespace Ogre /** Clears all cached values */ void clearCache(); - - /** Bind an OpenGL buffer of any type. + + /** Bind an OpenGL buffer of any type. @param target The buffer target. @param buffer The buffer ID. @param force Optional parameter to force an update. */ void bindGLBuffer(GLenum target, GLuint buffer, bool force = false); - /** Delete an OpenGL buffer of any type. + /** Delete an OpenGL buffer of any type. @param target The buffer target. @param buffer The buffer ID. @param force Optional parameter to force an update. */ void deleteGLBuffer(GLenum target, GLuint buffer, bool force = false); - /** Bind an OpenGL texture of any type. + /** Bind an OpenGL texture of any type. @param target The texture target. @param texture The texture ID. */ @@ -161,7 +161,7 @@ namespace Ogre */ void setDepthFunc(GLenum func); - /** Gets the clear depth in the range from [0..1]. + /** Gets the clear depth in the range from [0..1]. @return The current clearing depth. */ GLclampf getClearDepth(void) const; diff --git a/RenderSystems/GL/include/OgreGLSupport.h b/RenderSystems/GL/include/OgreGLSupport.h index d67478effb1..6969b39ceb7 100644 --- a/RenderSystems/GL/include/OgreGLSupport.h +++ b/RenderSystems/GL/include/OgreGLSupport.h @@ -53,7 +53,7 @@ class _OgreGLExport GLSupport */ virtual void addConfig() = 0; - virtual void setConfigOption(const String &name, const String &value); + virtual void setConfigOption(const String &name, const String &value); /** * Make sure all the extra options are valid @@ -61,13 +61,13 @@ class _OgreGLExport GLSupport */ virtual String validateConfig() = 0; - virtual ConfigOptionMap& getConfigOptions(void); + virtual ConfigOptionMap& getConfigOptions(void); - virtual RenderWindow* createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle) = 0; + virtual RenderWindow* createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle) = 0; - /// @copydoc RenderSystem::_createRenderWindow - virtual RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0) = 0; + /// @copydoc RenderSystem::_createRenderWindow + virtual RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0) = 0; virtual bool supportsPBuffers(); virtual GLPBuffer *createPBuffer(PixelComponentType format, size_t width, size_t height); @@ -126,17 +126,17 @@ class _OgreGLExport GLSupport */ virtual void initialiseExtensions(); - /// @copydoc RenderSystem::getDisplayMonitorCount - virtual unsigned int getDisplayMonitorCount() const - { - return 1; - } + /// @copydoc RenderSystem::getDisplayMonitorCount + virtual unsigned int getDisplayMonitorCount() const + { + return 1; + } protected: - // Stored options + // Stored options ConfigOptionMap mOptions; - // This contains the complete list of supported extensions + // This contains the complete list of supported extensions set::type extensionList; private: String mVersion; diff --git a/RenderSystems/GL/include/OgreGLTexture.h b/RenderSystems/GL/include/OgreGLTexture.h index 0f474d2bc89..13926d47362 100644 --- a/RenderSystems/GL/include/OgreGLTexture.h +++ b/RenderSystems/GL/include/OgreGLTexture.h @@ -49,9 +49,9 @@ namespace Ogre { virtual ~GLTexture(); void createRenderTexture(); - - /// @copydoc Texture::getBuffer - HardwarePixelBufferSharedPtr getBuffer(size_t face, size_t mipmap); + + /// @copydoc Texture::getBuffer + HardwarePixelBufferSharedPtr getBuffer(size_t face, size_t mipmap); /// Takes the OGRE texture type (1d/2d/3d/cube) and returns the appropriate GL one GLenum getGLTextureTarget(void) const; @@ -60,12 +60,12 @@ namespace Ogre { { return mTextureID; } - - void getCustomAttribute(const String& name, void* pData); + + void getCustomAttribute(const String& name, void* pData); protected: - /// @copydoc Texture::createInternalResourcesImpl - void createInternalResourcesImpl(void); + /// @copydoc Texture::createInternalResourcesImpl + void createInternalResourcesImpl(void); /// @copydoc Resource::prepareImpl void prepareImpl(void); /// @copydoc Resource::unprepareImpl @@ -75,12 +75,12 @@ namespace Ogre { /// @copydoc Texture::freeInternalResourcesImpl void freeInternalResourcesImpl(void); - /** internal method, create GLHardwarePixelBuffers for every face and - mipmap level. This method must be called after the GL texture object was created, - the number of mipmaps was set (GL_TEXTURE_MAX_LEVEL) and glTexImageXD was called to - actually allocate the buffer - */ - void _createSurfaceList(); + /** internal method, create GLHardwarePixelBuffers for every face and + mipmap level. This method must be called after the GL texture object was created, + the number of mipmaps was set (GL_TEXTURE_MAX_LEVEL) and glTexImageXD was called to + actually allocate the buffer + */ + void _createSurfaceList(); /// Used to hold images between calls to prepare and load. typedef SharedPtr::type > LoadedImages; @@ -95,10 +95,10 @@ namespace Ogre { private: GLuint mTextureID; GLSupport& mGLSupport; - - /// Vector of pointers to subsurfaces - typedef vector::type SurfaceList; - SurfaceList mSurfaceList; + + /// Vector of pointers to subsurfaces + typedef vector::type SurfaceList; + SurfaceList mSurfaceList; }; } diff --git a/RenderSystems/GL/include/OgreGLTextureManager.h b/RenderSystems/GL/include/OgreGLTextureManager.h index c3f91f9d7d9..ce155a29aa9 100644 --- a/RenderSystems/GL/include/OgreGLTextureManager.h +++ b/RenderSystems/GL/include/OgreGLTextureManager.h @@ -42,28 +42,28 @@ namespace Ogre { GLTextureManager(GLSupport& support); virtual ~GLTextureManager(); - GLuint getWarningTextureID() { return mWarningTextureID; } + GLuint getWarningTextureID() { return mWarningTextureID; } - /// @copydoc TextureManager::getNativeFormat - PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage); + /// @copydoc TextureManager::getNativeFormat + PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage); /// @copydoc TextureManager::isHardwareFilteringSupported bool isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage, bool preciseFormatOnly = false); protected: - friend class GLRenderSystem; + friend class GLRenderSystem; /// @copydoc ResourceManager::createImpl Resource* createImpl(const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader, const NameValuePairList* createParams); - /// Internal method to create a warning texture (bound when a texture unit is blank) - void createWarningTexture(); + /// Internal method to create a warning texture (bound when a texture unit is blank) + void createWarningTexture(); GLSupport& mGLSupport; - GLuint mWarningTextureID; + GLuint mWarningTextureID; }; } #endif diff --git a/RenderSystems/GL/include/OgreGLUniformCache.h b/RenderSystems/GL/include/OgreGLUniformCache.h index bffb3aefdff..fec2aaa1d77 100644 --- a/RenderSystems/GL/include/OgreGLUniformCache.h +++ b/RenderSystems/GL/include/OgreGLUniformCache.h @@ -35,13 +35,13 @@ typedef Ogre::GeneralAllocatedObject UniformCacheAlloc; namespace Ogre { - class GLUniformCacheImp; + class GLUniformCacheImp; /** An in memory cache of the OpenGL uniforms. */ class _OgreGLExport GLUniformCache : public UniformCacheAlloc { private: - GLUniformCacheImp* mImp; + GLUniformCacheImp* mImp; public: GLUniformCache(void); @@ -50,7 +50,7 @@ namespace Ogre /** Clears all cached values */ void clearCache(); - + /** Update a uniform @return A boolean value indicating whether this uniform needs to be updated in the GL. */ diff --git a/RenderSystems/GL/include/OgreSDLGLSupport.h b/RenderSystems/GL/include/OgreSDLGLSupport.h index edd09f38416..4a512b7f673 100644 --- a/RenderSystems/GL/include/OgreSDLGLSupport.h +++ b/RenderSystems/GL/include/OgreSDLGLSupport.h @@ -26,9 +26,9 @@ class _OgrePrivate SDLGLSupport : public GLSupport virtual RenderWindow* createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle); - /// @copydoc RenderSystem::createRenderWindow - virtual RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0); + /// @copydoc RenderSystem::createRenderWindow + virtual RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0); /** * Start anything special diff --git a/RenderSystems/GL/include/OgreSDLPrerequisites.h b/RenderSystems/GL/include/OgreSDLPrerequisites.h index c0abef959a6..e931ec35b3a 100644 --- a/RenderSystems/GL/include/OgreSDLPrerequisites.h +++ b/RenderSystems/GL/include/OgreSDLPrerequisites.h @@ -31,9 +31,9 @@ THE SOFTWARE. #include "OgrePlatform.h" #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE -# include +# include #else -# include +# include #endif #include "OgreGLPrerequisites.h" diff --git a/RenderSystems/GL/include/OgreSDLWindow.h b/RenderSystems/GL/include/OgreSDLWindow.h index e6790d74668..ea106e0f661 100644 --- a/RenderSystems/GL/include/OgreSDLWindow.h +++ b/RenderSystems/GL/include/OgreSDLWindow.h @@ -51,8 +51,8 @@ namespace Ogre { SDLWindow(); ~SDLWindow(); - void create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams); + void create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams); /** Overridden - see RenderWindow */ void destroy(void); /** Overridden - see RenderWindow */ diff --git a/RenderSystems/GL/include/Win32/OgreWin32Context.h b/RenderSystems/GL/include/Win32/OgreWin32Context.h index cdbe14f22c4..5a1ae325fcc 100644 --- a/RenderSystems/GL/include/Win32/OgreWin32Context.h +++ b/RenderSystems/GL/include/Win32/OgreWin32Context.h @@ -42,16 +42,16 @@ namespace Ogre { /** See GLContext */ virtual void setCurrent(); - /** See GLContext */ - virtual void endCurrent(); - /// @copydoc GLContext::clone - GLContext* clone() const; + /** See GLContext */ + virtual void endCurrent(); + /// @copydoc GLContext::clone + GLContext* clone() const; - virtual void releaseContext(); - - HGLRC getGlrc() const; + virtual void releaseContext(); + + HGLRC getGlrc() const; - protected: + protected: HDC mHDC; HGLRC mGlrc; }; diff --git a/RenderSystems/GL/include/Win32/OgreWin32GLSupport.h b/RenderSystems/GL/include/Win32/OgreWin32GLSupport.h index a1dbbcbefe7..9daff70ced3 100644 --- a/RenderSystems/GL/include/Win32/OgreWin32GLSupport.h +++ b/RenderSystems/GL/include/Win32/OgreWin32GLSupport.h @@ -35,82 +35,82 @@ namespace Ogre { - class _OgreGLExport Win32GLSupport : public GLSupport - { - public: + class _OgreGLExport Win32GLSupport : public GLSupport + { + public: Win32GLSupport(); - /** - * Add any special config values to the system. - * Must have a "Full Screen" value that is a bool and a "Video Mode" value - * that is a string in the form of wxhxb - */ - void addConfig(); - - void setConfigOption(const String &name, const String &value); - - /** - * Make sure all the extra options are valid - */ - String validateConfig(); - - virtual RenderWindow* createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle = "OGRE Render Window"); - - /// @copydoc RenderSystem::_createRenderWindow - virtual RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0); - - - /** - * Start anything special - */ - void start(); - /** - * Stop anything special - */ - void stop(); - - /** - * Get the address of a function - */ - void* getProcAddress(const String& procname); - - /** - * Initialise extensions - */ - virtual void initialiseExtensions(); - - - bool selectPixelFormat(HDC hdc, int colourDepth, int multisample, bool hwGamma); - - virtual bool supportsPBuffers(); - virtual GLPBuffer *createPBuffer(PixelComponentType format, size_t width, size_t height); - virtual unsigned int getDisplayMonitorCount() const; - private: - // Allowed video modes - vector::type mDevModes; - Win32Window *mInitialWindow; - vector::type mFSAALevels; - bool mHasPixelFormatARB; + /** + * Add any special config values to the system. + * Must have a "Full Screen" value that is a bool and a "Video Mode" value + * that is a string in the form of wxhxb + */ + void addConfig(); + + void setConfigOption(const String &name, const String &value); + + /** + * Make sure all the extra options are valid + */ + String validateConfig(); + + virtual RenderWindow* createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle = "OGRE Render Window"); + + /// @copydoc RenderSystem::_createRenderWindow + virtual RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0); + + + /** + * Start anything special + */ + void start(); + /** + * Stop anything special + */ + void stop(); + + /** + * Get the address of a function + */ + void* getProcAddress(const String& procname); + + /** + * Initialise extensions + */ + virtual void initialiseExtensions(); + + + bool selectPixelFormat(HDC hdc, int colourDepth, int multisample, bool hwGamma); + + virtual bool supportsPBuffers(); + virtual GLPBuffer *createPBuffer(PixelComponentType format, size_t width, size_t height); + virtual unsigned int getDisplayMonitorCount() const; + private: + // Allowed video modes + vector::type mDevModes; + Win32Window *mInitialWindow; + vector::type mFSAALevels; + bool mHasPixelFormatARB; bool mHasMultisample; - bool mHasHardwareGamma; + bool mHasHardwareGamma; - struct DisplayMonitorInfo - { - HMONITOR hMonitor; - MONITORINFOEX monitorInfoEx; - }; + struct DisplayMonitorInfo + { + HMONITOR hMonitor; + MONITORINFOEX monitorInfoEx; + }; - typedef vector::type DisplayMonitorInfoList; - typedef DisplayMonitorInfoList::iterator DisplayMonitorInfoIterator; + typedef vector::type DisplayMonitorInfoList; + typedef DisplayMonitorInfoList::iterator DisplayMonitorInfoIterator; - DisplayMonitorInfoList mMonitorInfoList; + DisplayMonitorInfoList mMonitorInfoList; - void refreshConfig(); - void initialiseWGL(); - static LRESULT CALLBACK dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp); - static BOOL CALLBACK sCreateMonitorsInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, - LPRECT lprcMonitor, LPARAM dwData); - }; + void refreshConfig(); + void initialiseWGL(); + static LRESULT CALLBACK dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp); + static BOOL CALLBACK sCreateMonitorsInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, + LPRECT lprcMonitor, LPARAM dwData); + }; } diff --git a/RenderSystems/GL/include/Win32/OgreWin32Prerequisites.h b/RenderSystems/GL/include/Win32/OgreWin32Prerequisites.h index 115cbf4a519..4efbd9a9753 100644 --- a/RenderSystems/GL/include/Win32/OgreWin32Prerequisites.h +++ b/RenderSystems/GL/include/Win32/OgreWin32Prerequisites.h @@ -40,8 +40,8 @@ namespace Ogre { class Win32Context; - // Useful error method implemented in Win32GLSupport - String translateWGLError(); + // Useful error method implemented in Win32GLSupport + String translateWGLError(); } diff --git a/RenderSystems/GL/include/Win32/OgreWin32RenderTexture.h b/RenderSystems/GL/include/Win32/OgreWin32RenderTexture.h index 01f0300969b..70c2006ddca 100644 --- a/RenderSystems/GL/include/Win32/OgreWin32RenderTexture.h +++ b/RenderSystems/GL/include/Win32/OgreWin32RenderTexture.h @@ -36,18 +36,18 @@ THE SOFTWARE. namespace Ogre { class _OgreGLExport Win32PBuffer : public GLPBuffer { - public: - Win32PBuffer(PixelComponentType format, size_t width, size_t height); - ~Win32PBuffer(); - - virtual GLContext *getContext() { return mContext; } + public: + Win32PBuffer(PixelComponentType format, size_t width, size_t height); + ~Win32PBuffer(); + + virtual GLContext *getContext() { return mContext; } protected: void createPBuffer(); - void destroyPBuffer(); + void destroyPBuffer(); - HDC mHDC; - HGLRC mGlrc; - HPBUFFERARB mPBuffer; + HDC mHDC; + HGLRC mGlrc; + HPBUFFERARB mPBuffer; Win32Context *mContext; }; } diff --git a/RenderSystems/GL/include/Win32/OgreWin32Window.h b/RenderSystems/GL/include/Win32/OgreWin32Window.h index 0b9b828ce03..463a59e107b 100644 --- a/RenderSystems/GL/include/Win32/OgreWin32Window.h +++ b/RenderSystems/GL/include/Win32/OgreWin32Window.h @@ -39,69 +39,69 @@ namespace Ogre { Win32Window(Win32GLSupport &glsupport); ~Win32Window(); - void create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams); - void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); + void create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams); + void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); void destroy(void); - bool isActive(void) const; + bool isActive(void) const; bool isVisible() const; - bool isHidden() const { return mHidden; } - void setHidden(bool hidden); - void setVSyncEnabled(bool vsync); - bool isVSyncEnabled() const; - void setVSyncInterval(unsigned int interval); - unsigned int getVSyncInterval() const; + bool isHidden() const { return mHidden; } + void setHidden(bool hidden); + void setVSyncEnabled(bool vsync); + bool isVSyncEnabled() const; + void setVSyncInterval(unsigned int interval); + unsigned int getVSyncInterval() const; bool isClosed(void) const; void reposition(int left, int top); void resize(unsigned int width, unsigned int height); void swapBuffers(); - /** Overridden - see RenderTarget. */ - virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); + /** Overridden - see RenderTarget. */ + virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); - bool requiresTextureFlipping() const { return false; } + bool requiresTextureFlipping() const { return false; } - HWND getWindowHandle() const { return mHWnd; } - HDC getHDC() const { return mHDC; } - - // Method for dealing with resize / move & 3d library - virtual void windowMovedOrResized(void); + HWND getWindowHandle() const { return mHWnd; } + HDC getHDC() const { return mHDC; } + + // Method for dealing with resize / move & 3d library + virtual void windowMovedOrResized(void); - void getCustomAttribute( const String& name, void* pData ); + void getCustomAttribute( const String& name, void* pData ); /** Used to set the active state of the render target. */ virtual void setActive( bool state ); - void adjustWindow(unsigned int clientWidth, unsigned int clientHeight, - unsigned int* winWidth, unsigned int* winHeight); + void adjustWindow(unsigned int clientWidth, unsigned int clientHeight, + unsigned int* winWidth, unsigned int* winHeight); - protected: - - /** Update the window rect. */ - void updateWindowRect(); + protected: + + /** Update the window rect. */ + void updateWindowRect(); - /** Return the target window style depending on the fullscreen parameter. */ - DWORD getWindowStyle(bool fullScreen) const { if (fullScreen) return mFullscreenWinStyle; return mWindowedWinStyle; } + /** Return the target window style depending on the fullscreen parameter. */ + DWORD getWindowStyle(bool fullScreen) const { if (fullScreen) return mFullscreenWinStyle; return mWindowedWinStyle; } - protected: - Win32GLSupport &mGLSupport; - HWND mHWnd; // Win32 Window handle - HDC mHDC; - HGLRC mGlrc; + protected: + Win32GLSupport &mGLSupport; + HWND mHWnd; // Win32 Window handle + HDC mHDC; + HGLRC mGlrc; bool mIsExternal; - char* mDeviceName; - bool mIsExternalGLControl; - bool mIsExternalGLContext; + char* mDeviceName; + bool mIsExternalGLControl; + bool mIsExternalGLContext; bool mSizing; - bool mClosed; - bool mHidden; - bool mVSync; - unsigned int mVSyncInterval; + bool mClosed; + bool mHidden; + bool mVSync; + unsigned int mVSyncInterval; int mDisplayFrequency; // fullscreen only, to restore display Win32Context *mContext; - DWORD mWindowedWinStyle; // Windowed mode window style flags. - DWORD mFullscreenWinStyle; // Fullscreen mode window style flags. + DWORD mWindowedWinStyle; // Windowed mode window style flags. + DWORD mFullscreenWinStyle; // Fullscreen mode window style flags. }; } diff --git a/RenderSystems/GL/include/gtk/OgreGTKWindow.h b/RenderSystems/GL/include/gtk/OgreGTKWindow.h index 18c926eaddb..af2fcd4f934 100644 --- a/RenderSystems/GL/include/gtk/OgreGTKWindow.h +++ b/RenderSystems/GL/include/gtk/OgreGTKWindow.h @@ -66,7 +66,7 @@ class GTKWindow : public RenderWindow, public SigC::Object bool fullScreen, int left, int top, bool depthBuffer, void* miscParam, ...); - void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); + void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); void destroy(void); bool isActive(void) const; bool isClosed(void) const; @@ -77,12 +77,12 @@ class GTKWindow : public RenderWindow, public SigC::Object bool requiresTextureFlipping() const { return false; } - /** - * Get a custom, GTK specific attribute. The specific attributes - * are: - * GTKMMWINDOW The Gtk::Window instance (Rendering window) - * GTKGLMMWIDGET The Gtk::GL::DrawingArea instance (Ogre widget) - */ + /** + * Get a custom, GTK specific attribute. The specific attributes + * are: + * GTKMMWINDOW The Gtk::Window instance (Rendering window) + * GTKGLMMWIDGET The Gtk::GL::DrawingArea instance (Ogre widget) + */ void getCustomAttribute( const String& name, void* pData ); protected: // Signal handlers diff --git a/RenderSystems/GL/src/GLSL/include/OgreGLSLExtSupport.h b/RenderSystems/GL/src/GLSL/include/OgreGLSLExtSupport.h index 6c522678da2..faf4ca0c7a0 100644 --- a/RenderSystems/GL/src/GLSL/include/OgreGLSLExtSupport.h +++ b/RenderSystems/GL/src/GLSL/include/OgreGLSLExtSupport.h @@ -41,25 +41,25 @@ namespace Ogre namespace GLSL { // forward declarations - class GLSLProgram; - class GLSLGpuProgram; - class GLSLLinkProgram; - class GLSLLinkProgramManager; - class GLSLProgramFactory; + class GLSLProgram; + class GLSLGpuProgram; + class GLSLLinkProgram; + class GLSLLinkProgramManager; + class GLSLProgramFactory; - /** Check for GL errors and report them in the Ogre Log. + /** Check for GL errors and report them in the Ogre Log. - @param forceInfoLog if true then message from GL info log is obtained - @param forceException if true then exception is generated if a GL error found - */ + @param forceInfoLog if true then message from GL info log is obtained + @param forceException if true then exception is generated if a GL error found + */ void reportGLSLError(GLenum glErr, const String& ogreMethod, const String& errorTextPrefix, const GLhandleARB obj, const bool forceInfoLog = false, const bool forceException = false); - /** if there is a message in GL info log then post it in the Ogre Log - @param msg the info log message string is appended to this string - @param obj the GL object that is used to retrieve the info log - */ - String logObjectInfo(const String& msg, const GLhandleARB obj); + /** if there is a message in GL info log then post it in the Ogre Log + @param msg the info log message string is appended to this string + @param obj the GL object that is used to retrieve the info log + */ + String logObjectInfo(const String& msg, const GLhandleARB obj); } } // namespace Ogre diff --git a/RenderSystems/GL/src/GLSL/include/OgreGLSLGpuProgram.h b/RenderSystems/GL/src/GLSL/include/OgreGLSLGpuProgram.h index b1a41c8d4e6..d4565b2c7d1 100644 --- a/RenderSystems/GL/src/GLSL/include/OgreGLSLGpuProgram.h +++ b/RenderSystems/GL/src/GLSL/include/OgreGLSLGpuProgram.h @@ -36,61 +36,61 @@ THE SOFTWARE. namespace Ogre { namespace GLSL { /** GLSL low level compiled shader object - this class is used to get at the linked program object - and provide an interface for GLRenderSystem calls. GLSL does not provide access to the - low level code of the shader so this class is really just a dummy place holder. - GLSL uses a program object to represent the active vertex and fragment programs used - but Ogre materials maintain separate instances of the active vertex and fragment programs - which creates a small problem for GLSL integration. The GLSLGpuProgram class provides the - interface between the GLSLLinkProgramManager , GLRenderSystem, and the active GLSLProgram - instances. - */ + and provide an interface for GLRenderSystem calls. GLSL does not provide access to the + low level code of the shader so this class is really just a dummy place holder. + GLSL uses a program object to represent the active vertex and fragment programs used + but Ogre materials maintain separate instances of the active vertex and fragment programs + which creates a small problem for GLSL integration. The GLSLGpuProgram class provides the + interface between the GLSLLinkProgramManager , GLRenderSystem, and the active GLSLProgram + instances. + */ class _OgreGLExport GLSLGpuProgram : public GLGpuProgram { private: - /// GL Handle for the shader object - GLSLProgram* mGLSLProgram; + /// GL Handle for the shader object + GLSLProgram* mGLSLProgram; - /// Keep track of the number of vertex shaders created - static GLuint mVertexShaderCount; - /// Keep track of the number of fragment shaders created - static GLuint mFragmentShaderCount; - /// keep track of the number of geometry shaders created - static GLuint mGeometryShaderCount; + /// Keep track of the number of vertex shaders created + static GLuint mVertexShaderCount; + /// Keep track of the number of fragment shaders created + static GLuint mFragmentShaderCount; + /// keep track of the number of geometry shaders created + static GLuint mGeometryShaderCount; - public: + public: GLSLGpuProgram(GLSLProgram* parent); - ~GLSLGpuProgram(); + ~GLSLGpuProgram(); - /// Execute the binding functions for this program - void bindProgram(void); - /// Execute the unbinding functions for this program - void unbindProgram(void); - /// Execute the param binding functions for this program - void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask); - /// Execute the pass iteration param binding functions for this program - void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params); + /// Execute the binding functions for this program + void bindProgram(void); + /// Execute the unbinding functions for this program + void unbindProgram(void); + /// Execute the param binding functions for this program + void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask); + /// Execute the pass iteration param binding functions for this program + void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params); - /// Get the assigned GL program id - GLuint getProgramID(void) const - { return mProgramID; } + /// Get the assigned GL program id + GLuint getProgramID(void) const + { return mProgramID; } - /// Get the GLSLProgram for the shader object - GLSLProgram* getGLSLProgram(void) const { return mGLSLProgram; } + /// Get the GLSLProgram for the shader object + GLSLProgram* getGLSLProgram(void) const { return mGLSLProgram; } - /// @copydoc GLGpuProgram::getAttributeIndex - GLuint getAttributeIndex(VertexElementSemantic semantic, uint index); - - /// @copydoc GLGpuProgram::isAttributeValid - bool isAttributeValid(VertexElementSemantic semantic, uint index); + /// @copydoc GLGpuProgram::getAttributeIndex + GLuint getAttributeIndex(VertexElementSemantic semantic, uint index); + + /// @copydoc GLGpuProgram::isAttributeValid + bool isAttributeValid(VertexElementSemantic semantic, uint index); protected: /// Overridden from GpuProgram void loadFromSource(void); - /// @copydoc Resource::unloadImpl - void unloadImpl(void); - /// @copydoc Resource::loadImpl - void loadImpl(void); + /// @copydoc Resource::unloadImpl + void unloadImpl(void); + /// @copydoc Resource::loadImpl + void loadImpl(void); }; } diff --git a/RenderSystems/GL/src/GLSL/include/OgreGLSLLinkProgram.h b/RenderSystems/GL/src/GLSL/include/OgreGLSLLinkProgram.h index fe41e8c8f5c..c2eb1d3c04e 100644 --- a/RenderSystems/GL/src/GLSL/include/OgreGLSLLinkProgram.h +++ b/RenderSystems/GL/src/GLSL/include/OgreGLSLLinkProgram.h @@ -37,93 +37,93 @@ namespace Ogre { namespace GLSL { /// Structure used to keep track of named uniforms in the linked program object - struct GLUniformReference - { - /// GL location handle - GLint mLocation; - /// Which type of program params will this value come from? - GpuProgramType mSourceProgType; - /// The constant definition it relates to - const GpuConstantDefinition* mConstantDef; - }; - - typedef vector::type GLUniformReferenceList; - typedef GLUniformReferenceList::iterator GLUniformReferenceIterator; - - /** C++ encapsulation of GLSL Program Object - - */ - - class _OgreGLExport GLSLLinkProgram - { - private: - /// Container of uniform references that are active in the program object - GLUniformReferenceList mGLUniformReferences; - - /// Linked vertex program - GLSLGpuProgram* mVertexProgram; - /// Linked geometry program - GLSLGpuProgram* mGeometryProgram; - /// Linked fragment program - GLSLGpuProgram* mFragmentProgram; + struct GLUniformReference + { + /// GL location handle + GLint mLocation; + /// Which type of program params will this value come from? + GpuProgramType mSourceProgType; + /// The constant definition it relates to + const GpuConstantDefinition* mConstantDef; + }; + + typedef vector::type GLUniformReferenceList; + typedef GLUniformReferenceList::iterator GLUniformReferenceIterator; + + /** C++ encapsulation of GLSL Program Object + + */ + + class _OgreGLExport GLSLLinkProgram + { + private: + /// Container of uniform references that are active in the program object + GLUniformReferenceList mGLUniformReferences; + + /// Linked vertex program + GLSLGpuProgram* mVertexProgram; + /// Linked geometry program + GLSLGpuProgram* mGeometryProgram; + /// Linked fragment program + GLSLGpuProgram* mFragmentProgram; GLUniformCache *mUniformCache; - /// Flag to indicate that uniform references have already been built - bool mUniformRefsBuilt; - /// GL handle for the program object - GLhandleARB mGLHandle; - /// Flag indicating that the program object has been successfully linked - GLint mLinked; - /// Flag indicating that the program object has tried to link and failed - bool mTriedToLinkAndFailed; - /// Flag indicating skeletal animation is being performed - bool mSkeletalAnimation; - - /// Build uniform references from active named uniforms - void buildGLUniformReferences(void); - /// Extract attributes - void extractAttributes(void); - - typedef set::type AttributeSet; - /// Custom attribute bindings - AttributeSet mValidAttributes; - - /// Name / attribute list - struct CustomAttribute - { - String name; - GLuint attrib; - CustomAttribute(const String& _name, GLuint _attrib) - :name(_name), attrib(_attrib) {} - }; - - static CustomAttribute msCustomAttributes[]; - - String getCombinedName(); - /// Compiles and links the the vertex and fragment programs - void compileAndLink(); - /// Get the the binary data of a program from the microcode cache - void getMicrocodeFromCache(); - public: - /// Constructor should only be used by GLSLLinkProgramManager - GLSLLinkProgram(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* geometryProgram, GLSLGpuProgram* fragmentProgram); - ~GLSLLinkProgram(void); - - /** Makes a program object active by making sure it is linked and then putting it in use. - - */ - void activate(void); - - /** Updates program object uniforms using data from GpuProgramParameters. - normally called by GLSLGpuProgram::bindParameters() just before rendering occurs. - */ - void updateUniforms(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType); - /** Updates program object uniforms using data from pass iteration GpuProgramParameters. - normally called by GLSLGpuProgram::bindMultiPassParameters() just before multi pass rendering occurs. - */ - void updatePassIterationUniforms(GpuProgramParametersSharedPtr params); - /// Get the GL Handle for the program object - GLhandleARB getGLHandle(void) const { return mGLHandle; } + /// Flag to indicate that uniform references have already been built + bool mUniformRefsBuilt; + /// GL handle for the program object + GLhandleARB mGLHandle; + /// Flag indicating that the program object has been successfully linked + GLint mLinked; + /// Flag indicating that the program object has tried to link and failed + bool mTriedToLinkAndFailed; + /// Flag indicating skeletal animation is being performed + bool mSkeletalAnimation; + + /// Build uniform references from active named uniforms + void buildGLUniformReferences(void); + /// Extract attributes + void extractAttributes(void); + + typedef set::type AttributeSet; + /// Custom attribute bindings + AttributeSet mValidAttributes; + + /// Name / attribute list + struct CustomAttribute + { + String name; + GLuint attrib; + CustomAttribute(const String& _name, GLuint _attrib) + :name(_name), attrib(_attrib) {} + }; + + static CustomAttribute msCustomAttributes[]; + + String getCombinedName(); + /// Compiles and links the the vertex and fragment programs + void compileAndLink(); + /// Get the the binary data of a program from the microcode cache + void getMicrocodeFromCache(); + public: + /// Constructor should only be used by GLSLLinkProgramManager + GLSLLinkProgram(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* geometryProgram, GLSLGpuProgram* fragmentProgram); + ~GLSLLinkProgram(void); + + /** Makes a program object active by making sure it is linked and then putting it in use. + + */ + void activate(void); + + /** Updates program object uniforms using data from GpuProgramParameters. + normally called by GLSLGpuProgram::bindParameters() just before rendering occurs. + */ + void updateUniforms(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType); + /** Updates program object uniforms using data from pass iteration GpuProgramParameters. + normally called by GLSLGpuProgram::bindMultiPassParameters() just before multi pass rendering occurs. + */ + void updatePassIterationUniforms(GpuProgramParametersSharedPtr params); + /// Get the GL Handle for the program object + GLhandleARB getGLHandle(void) const { return mGLHandle; } /** Sets whether the linked program includes the required instructions to perform skeletal animation. @remarks @@ -141,12 +141,12 @@ namespace Ogre { */ bool isSkeletalAnimationIncluded(void) const { return mSkeletalAnimation; } - /// Get the index of a non-standard attribute bound in the linked code - GLuint getAttributeIndex(VertexElementSemantic semantic, uint index); - /// Is a non-standard attribute bound in the linked code? - bool isAttributeValid(VertexElementSemantic semantic, uint index); + /// Get the index of a non-standard attribute bound in the linked code + GLuint getAttributeIndex(VertexElementSemantic semantic, uint index); + /// Is a non-standard attribute bound in the linked code? + bool isAttributeValid(VertexElementSemantic semantic, uint index); - }; + }; } } diff --git a/RenderSystems/GL/src/GLSL/include/OgreGLSLLinkProgramManager.h b/RenderSystems/GL/src/GLSL/include/OgreGLSLLinkProgramManager.h index 7dd05887392..b3599936c27 100644 --- a/RenderSystems/GL/src/GLSL/include/OgreGLSLLinkProgramManager.h +++ b/RenderSystems/GL/src/GLSL/include/OgreGLSLLinkProgramManager.h @@ -38,107 +38,107 @@ namespace Ogre { namespace GLSL { - /** Ogre assumes that there are separate vertex and fragment programs to deal with but - GLSL has one program object that represents the active vertex and fragment shader objects - during a rendering state. GLSL Vertex and fragment - shader objects are compiled separately and then attached to a program object and then the - program object is linked. Since Ogre can only handle one vertex program and one fragment - program being active in a pass, the GLSL Link Program Manager does the same. The GLSL Link - program manager acts as a state machine and activates a program object based on the active - vertex and fragment program. Previously created program objects are stored along with a unique - key in a hash_map for quick retrieval the next time the program object is required. - - */ - - class _OgreGLExport GLSLLinkProgramManager : public Singleton - { - - private: - - typedef map::type LinkProgramMap; - typedef LinkProgramMap::iterator LinkProgramIterator; - - /// container holding previously created program objects - LinkProgramMap mLinkPrograms; - - /// active objects defining the active rendering gpu state - GLSLGpuProgram* mActiveVertexGpuProgram; - GLSLGpuProgram* mActiveGeometryGpuProgram; - GLSLGpuProgram* mActiveFragmentGpuProgram; - GLSLLinkProgram* mActiveLinkProgram; - - typedef map::type StringToEnumMap; - StringToEnumMap mTypeEnumMap; - - /// Use type to complete other information - void completeDefInfo(GLenum gltype, GpuConstantDefinition& defToUpdate); - /// Find where the data for a specific uniform should come from, populate - bool completeParamSource(const String& paramName, - const GpuConstantDefinitionMap* vertexConstantDefs, - const GpuConstantDefinitionMap* geometryConstantDefs, - const GpuConstantDefinitionMap* fragmentConstantDefs, - GLUniformReference& refToUpdate); - - public: - - GLSLLinkProgramManager(void); - - ~GLSLLinkProgramManager(void); - - /** - Get the program object that links the two active shader objects together - if a program object was not already created and linked a new one is created and linked - */ - GLSLLinkProgram* getActiveLinkProgram(void); - - /** Set the active fragment shader for the next rendering state. - The active program object will be cleared. - Normally called from the GLSLGpuProgram::bindProgram and unbindProgram methods - */ - void setActiveFragmentShader(GLSLGpuProgram* fragmentGpuProgram); - /** Set the active geometry shader for the next rendering state. - The active program object will be cleared. - Normally called from the GLSLGpuProgram::bindProgram and unbindProgram methods - */ - void setActiveGeometryShader(GLSLGpuProgram* geometryGpuProgram); - /** Set the active vertex shader for the next rendering state. - The active program object will be cleared. - Normally called from the GLSLGpuProgram::bindProgram and unbindProgram methods - */ - void setActiveVertexShader(GLSLGpuProgram* vertexGpuProgram); - - /** Populate a list of uniforms based on a program object. - @param programObject Handle to the program object to query - @param vertexConstantDefs Definition of the constants extracted from the - vertex program, used to match up physical buffer indexes with program - uniforms. May be null if there is no vertex program. - @param geometryConstantDefs Definition of the constants extracted from the - geometry program, used to match up physical buffer indexes with program - uniforms. May be null if there is no geometry program. - @param fragmentConstantDefs Definition of the constants extracted from the - fragment program, used to match up physical buffer indexes with program - uniforms. May be null if there is no fragment program. - @param list The list to populate (will not be cleared before adding, clear - it yourself before calling this if that's what you want). - */ - void extractUniforms(GLhandleARB programObject, - const GpuConstantDefinitionMap* vertexConstantDefs, - const GpuConstantDefinitionMap* geometryConstantDefs, - const GpuConstantDefinitionMap* fragmentConstantDefs, - GLUniformReferenceList& list); - /** Populate a list of uniforms based on GLSL source. - @param src Reference to the source code - @param constantDefs The defs to populate (will not be cleared before adding, clear - it yourself before calling this if that's what you want). - @param filename The file name this came from, for logging errors. - */ - void extractConstantDefs(const String& src, GpuNamedConstants& constantDefs, - const String& filename); - - static GLSLLinkProgramManager& getSingleton(void); + /** Ogre assumes that there are separate vertex and fragment programs to deal with but + GLSL has one program object that represents the active vertex and fragment shader objects + during a rendering state. GLSL Vertex and fragment + shader objects are compiled separately and then attached to a program object and then the + program object is linked. Since Ogre can only handle one vertex program and one fragment + program being active in a pass, the GLSL Link Program Manager does the same. The GLSL Link + program manager acts as a state machine and activates a program object based on the active + vertex and fragment program. Previously created program objects are stored along with a unique + key in a hash_map for quick retrieval the next time the program object is required. + + */ + + class _OgreGLExport GLSLLinkProgramManager : public Singleton + { + + private: + + typedef map::type LinkProgramMap; + typedef LinkProgramMap::iterator LinkProgramIterator; + + /// container holding previously created program objects + LinkProgramMap mLinkPrograms; + + /// active objects defining the active rendering gpu state + GLSLGpuProgram* mActiveVertexGpuProgram; + GLSLGpuProgram* mActiveGeometryGpuProgram; + GLSLGpuProgram* mActiveFragmentGpuProgram; + GLSLLinkProgram* mActiveLinkProgram; + + typedef map::type StringToEnumMap; + StringToEnumMap mTypeEnumMap; + + /// Use type to complete other information + void completeDefInfo(GLenum gltype, GpuConstantDefinition& defToUpdate); + /// Find where the data for a specific uniform should come from, populate + bool completeParamSource(const String& paramName, + const GpuConstantDefinitionMap* vertexConstantDefs, + const GpuConstantDefinitionMap* geometryConstantDefs, + const GpuConstantDefinitionMap* fragmentConstantDefs, + GLUniformReference& refToUpdate); + + public: + + GLSLLinkProgramManager(void); + + ~GLSLLinkProgramManager(void); + + /** + Get the program object that links the two active shader objects together + if a program object was not already created and linked a new one is created and linked + */ + GLSLLinkProgram* getActiveLinkProgram(void); + + /** Set the active fragment shader for the next rendering state. + The active program object will be cleared. + Normally called from the GLSLGpuProgram::bindProgram and unbindProgram methods + */ + void setActiveFragmentShader(GLSLGpuProgram* fragmentGpuProgram); + /** Set the active geometry shader for the next rendering state. + The active program object will be cleared. + Normally called from the GLSLGpuProgram::bindProgram and unbindProgram methods + */ + void setActiveGeometryShader(GLSLGpuProgram* geometryGpuProgram); + /** Set the active vertex shader for the next rendering state. + The active program object will be cleared. + Normally called from the GLSLGpuProgram::bindProgram and unbindProgram methods + */ + void setActiveVertexShader(GLSLGpuProgram* vertexGpuProgram); + + /** Populate a list of uniforms based on a program object. + @param programObject Handle to the program object to query + @param vertexConstantDefs Definition of the constants extracted from the + vertex program, used to match up physical buffer indexes with program + uniforms. May be null if there is no vertex program. + @param geometryConstantDefs Definition of the constants extracted from the + geometry program, used to match up physical buffer indexes with program + uniforms. May be null if there is no geometry program. + @param fragmentConstantDefs Definition of the constants extracted from the + fragment program, used to match up physical buffer indexes with program + uniforms. May be null if there is no fragment program. + @param list The list to populate (will not be cleared before adding, clear + it yourself before calling this if that's what you want). + */ + void extractUniforms(GLhandleARB programObject, + const GpuConstantDefinitionMap* vertexConstantDefs, + const GpuConstantDefinitionMap* geometryConstantDefs, + const GpuConstantDefinitionMap* fragmentConstantDefs, + GLUniformReferenceList& list); + /** Populate a list of uniforms based on GLSL source. + @param src Reference to the source code + @param constantDefs The defs to populate (will not be cleared before adding, clear + it yourself before calling this if that's what you want). + @param filename The file name this came from, for logging errors. + */ + void extractConstantDefs(const String& src, GpuNamedConstants& constantDefs, + const String& filename); + + static GLSLLinkProgramManager& getSingleton(void); static GLSLLinkProgramManager* getSingletonPtr(void); - }; + }; } } diff --git a/RenderSystems/GL/src/GLSL/include/OgreGLSLProgram.h b/RenderSystems/GL/src/GLSL/include/OgreGLSLProgram.h index f50837d060b..92d9c622bfe 100644 --- a/RenderSystems/GL/src/GLSL/include/OgreGLSLProgram.h +++ b/RenderSystems/GL/src/GLSL/include/OgreGLSLProgram.h @@ -37,22 +37,22 @@ namespace Ogre { /** Specialisation of HighLevelGpuProgram to provide support for OpenGL Shader Language (GLSL). @remarks - GLSL has no target assembler or entry point specification like DirectX 9 HLSL. - Vertex and Fragment shaders only have one entry point called "main". - When a shader is compiled, microcode is generated but can not be accessed by - the application. - GLSL also does not provide assembler low level output after compiling. The GL Render - system assumes that the Gpu program is a GL Gpu program so GLSLProgram will create a - GLSLGpuProgram that is subclassed from GLGpuProgram for the low level implementation. - The GLSLProgram class will create a shader object and compile the source but will - not create a program object. It's up to GLSLGpuProgram class to request a program object - to link the shader object to. - - @note - GLSL supports multiple modular shader objects that can be attached to one program - object to form a single shader. This is supported through the "attach" material script - command. All the modules to be attached are listed on the same line as the attach command - separated by white space. + GLSL has no target assembler or entry point specification like DirectX 9 HLSL. + Vertex and Fragment shaders only have one entry point called "main". + When a shader is compiled, microcode is generated but can not be accessed by + the application. + GLSL also does not provide assembler low level output after compiling. The GL Render + system assumes that the Gpu program is a GL Gpu program so GLSLProgram will create a + GLSLGpuProgram that is subclassed from GLGpuProgram for the low level implementation. + The GLSLProgram class will create a shader object and compile the source but will + not create a program object. It's up to GLSLGpuProgram class to request a program object + to link the shader object to. + + @note + GLSL supports multiple modular shader objects that can be attached to one program + object to form a single shader. This is supported through the "attach" material script + command. All the modules to be attached are listed on the same line as the attach command + separated by white space. */ class _OgreGLExport GLSLProgram : public HighLevelGpuProgram @@ -76,24 +76,24 @@ namespace Ogre { GLSLProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - ~GLSLProgram(); + ~GLSLProgram(); - GLhandleARB getGLHandle() const { return mGLHandle; } - void attachToProgramObject( const GLhandleARB programObject ); - void detachFromProgramObject( const GLhandleARB programObject ); - String getAttachedShaderNames() const { return mAttachedShaderNames; } + GLhandleARB getGLHandle() const { return mGLHandle; } + void attachToProgramObject( const GLhandleARB programObject ); + void detachFromProgramObject( const GLhandleARB programObject ); + String getAttachedShaderNames() const { return mAttachedShaderNames; } - /// Overridden - bool getPassTransformStates(void) const; - bool getPassSurfaceAndLightStates(void) const; + /// Overridden + bool getPassTransformStates(void) const; + bool getPassSurfaceAndLightStates(void) const; /** Attach another GLSL Shader to this one. */ void attachChildShader(const String& name); - /** Sets the preprocessor defines use to compile the program. */ - void setPreprocessorDefines(const String& defines) { mPreprocessorDefines = defines; } - /** Sets the preprocessor defines use to compile the program. */ - const String& getPreprocessorDefines(void) const { return mPreprocessorDefines; } + /** Sets the preprocessor defines use to compile the program. */ + void setPreprocessorDefines(const String& defines) { mPreprocessorDefines = defines; } + /** Sets the preprocessor defines use to compile the program. */ + const String& getPreprocessorDefines(void) const { return mPreprocessorDefines; } /// Overridden from GpuProgram const String& getLanguage(void) const; @@ -104,110 +104,110 @@ namespace Ogre { bool getColumnMajorMatrices(void) const { return mColumnMajorMatrices; } /** Returns the operation type that this geometry program expects to - receive as input - */ - virtual RenderOperation::OperationType getInputOperationType(void) const - { return mInputOperationType; } - /** Returns the operation type that this geometry program will emit - */ - virtual RenderOperation::OperationType getOutputOperationType(void) const - { return mOutputOperationType; } - /** Returns the maximum number of vertices that this geometry program can - output in a single run - */ - virtual int getMaxOutputVertices(void) const { return mMaxOutputVertices; } - - /** Sets the operation type that this geometry program expects to receive - */ - virtual void setInputOperationType(RenderOperation::OperationType operationType) - { mInputOperationType = operationType; } - /** Set the operation type that this geometry program will emit - */ - virtual void setOutputOperationType(RenderOperation::OperationType operationType) - { mOutputOperationType = operationType; } - /** Set the maximum number of vertices that a single run of this geometry program - can emit. - */ - virtual void setMaxOutputVertices(int maxOutputVertices) - { mMaxOutputVertices = maxOutputVertices; } - - /// compile source into shader object - bool compile( const bool checkErrors = true); - - /// Command object for setting macro defines - class CmdPreprocessorDefines : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /// Command object for setting the input operation type (geometry shader only) - class _OgreGLExport CmdInputOperationType : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /// Command object for setting the output operation type (geometry shader only) - class _OgreGLExport CmdOutputOperationType : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - /// Command object for setting the maximum output vertices (geometry shader only) - class _OgreGLExport CmdMaxOutputVertices : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; - protected: - static CmdPreprocessorDefines msCmdPreprocessorDefines; + receive as input + */ + virtual RenderOperation::OperationType getInputOperationType(void) const + { return mInputOperationType; } + /** Returns the operation type that this geometry program will emit + */ + virtual RenderOperation::OperationType getOutputOperationType(void) const + { return mOutputOperationType; } + /** Returns the maximum number of vertices that this geometry program can + output in a single run + */ + virtual int getMaxOutputVertices(void) const { return mMaxOutputVertices; } + + /** Sets the operation type that this geometry program expects to receive + */ + virtual void setInputOperationType(RenderOperation::OperationType operationType) + { mInputOperationType = operationType; } + /** Set the operation type that this geometry program will emit + */ + virtual void setOutputOperationType(RenderOperation::OperationType operationType) + { mOutputOperationType = operationType; } + /** Set the maximum number of vertices that a single run of this geometry program + can emit. + */ + virtual void setMaxOutputVertices(int maxOutputVertices) + { mMaxOutputVertices = maxOutputVertices; } + + /// compile source into shader object + bool compile( const bool checkErrors = true); + + /// Command object for setting macro defines + class CmdPreprocessorDefines : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for setting the input operation type (geometry shader only) + class _OgreGLExport CmdInputOperationType : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for setting the output operation type (geometry shader only) + class _OgreGLExport CmdOutputOperationType : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + /// Command object for setting the maximum output vertices (geometry shader only) + class _OgreGLExport CmdMaxOutputVertices : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; + protected: + static CmdPreprocessorDefines msCmdPreprocessorDefines; static CmdAttach msCmdAttach; static CmdColumnMajorMatrices msCmdColumnMajorMatrices; - static CmdInputOperationType msInputOperationTypeCmd; - static CmdOutputOperationType msOutputOperationTypeCmd; - static CmdMaxOutputVertices msMaxOutputVerticesCmd; + static CmdInputOperationType msInputOperationTypeCmd; + static CmdOutputOperationType msOutputOperationTypeCmd; + static CmdMaxOutputVertices msMaxOutputVerticesCmd; /** Internal load implementation, must be implemented by subclasses. */ void loadFromSource(void); /** Internal method for creating a dummy low-level program for this - high-level program. GLSL does not give access to the low level implementation of the - shader so this method creates an object sub-classed from GLGpuProgram just to be - compatible with GLRenderSystem. - */ - void createLowLevelImpl(void); + high-level program. GLSL does not give access to the low level implementation of the + shader so this method creates an object sub-classed from GLGpuProgram just to be + compatible with GLRenderSystem. + */ + void createLowLevelImpl(void); /// Internal unload implementation, must be implemented by subclasses void unloadHighLevelImpl(void); - /// Overridden from HighLevelGpuProgram - void unloadImpl(void); + /// Overridden from HighLevelGpuProgram + void unloadImpl(void); /// Populate the passed parameters with name->index map void populateParameterNames(GpuProgramParametersSharedPtr params); /// Populate the passed parameters with name->index map, must be overridden void buildConstantDefinitions() const; - private: - /// GL handle for shader object - GLhandleARB mGLHandle; - /// Flag indicating if shader object successfully compiled - GLint mCompiled; - /// The input operation type for this (geometry) program - RenderOperation::OperationType mInputOperationType; - /// The output operation type for this (geometry) program - RenderOperation::OperationType mOutputOperationType; - /// The maximum amount of vertices that this (geometry) program can output - int mMaxOutputVertices; - /// Attached Shader names - String mAttachedShaderNames; - /// Preprocessor options - String mPreprocessorDefines; - /// Container of attached programs - typedef vector< GLSLProgram* >::type GLSLProgramContainer; - typedef GLSLProgramContainer::iterator GLSLProgramContainerIterator; - GLSLProgramContainer mAttachedGLSLPrograms; + private: + /// GL handle for shader object + GLhandleARB mGLHandle; + /// Flag indicating if shader object successfully compiled + GLint mCompiled; + /// The input operation type for this (geometry) program + RenderOperation::OperationType mInputOperationType; + /// The output operation type for this (geometry) program + RenderOperation::OperationType mOutputOperationType; + /// The maximum amount of vertices that this (geometry) program can output + int mMaxOutputVertices; + /// Attached Shader names + String mAttachedShaderNames; + /// Preprocessor options + String mPreprocessorDefines; + /// Container of attached programs + typedef vector< GLSLProgram* >::type GLSLProgramContainer; + typedef GLSLProgramContainer::iterator GLSLProgramContainerIterator; + GLSLProgramContainer mAttachedGLSLPrograms; /// Matrix in column major pack format? bool mColumnMajorMatrices; diff --git a/RenderSystems/GL/src/GLSL/include/OgreGLSLProgramFactory.h b/RenderSystems/GL/src/GLSL/include/OgreGLSLProgramFactory.h index 4da41384403..e1c7db2e467 100644 --- a/RenderSystems/GL/src/GLSL/include/OgreGLSLProgramFactory.h +++ b/RenderSystems/GL/src/GLSL/include/OgreGLSLProgramFactory.h @@ -41,20 +41,20 @@ namespace Ogre class _OgreGLExport GLSLProgramFactory : public HighLevelGpuProgramFactory { protected: - static String sLanguageName; + static String sLanguageName; public: GLSLProgramFactory(void); ~GLSLProgramFactory(void); - /// Get the name of the language this factory creates programs for - const String& getLanguage(void) const; - /// Create an instance of GLSLProgram + /// Get the name of the language this factory creates programs for + const String& getLanguage(void) const; + /// Create an instance of GLSLProgram HighLevelGpuProgram* create(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - void destroy(HighLevelGpuProgram* prog); + void destroy(HighLevelGpuProgram* prog); - private: - GLSLLinkProgramManager* mLinkProgramManager; + private: + GLSLLinkProgramManager* mLinkProgramManager; }; } diff --git a/RenderSystems/GL/src/GLSL/src/OgreGLSLExtSupport.cpp b/RenderSystems/GL/src/GLSL/src/OgreGLSLExtSupport.cpp index a60a3a322d0..0c22faab2fc 100644 --- a/RenderSystems/GL/src/GLSL/src/OgreGLSLExtSupport.cpp +++ b/RenderSystems/GL/src/GLSL/src/OgreGLSLExtSupport.cpp @@ -38,66 +38,66 @@ namespace Ogre //----------------------------------------------------------------------------- void reportGLSLError(GLenum glErr, const String& ogreMethod, const String& errorTextPrefix, const GLhandleARB obj, const bool forceInfoLog, const bool forceException) { - bool errorsFound = false; - String msg = errorTextPrefix; + bool errorsFound = false; + String msg = errorTextPrefix; - // get all the GL errors - while (glErr != GL_NO_ERROR) + // get all the GL errors + while (glErr != GL_NO_ERROR) { - const char* glerrStr = (const char*)gluErrorString(glErr); - if (glerrStr) - { - msg += String(glerrStr); - } - glErr = glGetError(); - errorsFound = true; + const char* glerrStr = (const char*)gluErrorString(glErr); + if (glerrStr) + { + msg += String(glerrStr); + } + glErr = glGetError(); + errorsFound = true; } - // if errors were found then put them in the Log and raise and exception - if (errorsFound || forceInfoLog) - { - // if shader or program object then get the log message and send to the log manager - msg += logObjectInfo( msg, obj ); + // if errors were found then put them in the Log and raise and exception + if (errorsFound || forceInfoLog) + { + // if shader or program object then get the log message and send to the log manager + msg += logObjectInfo( msg, obj ); if (forceException) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, msg, ogreMethod); - } - } + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, msg, ogreMethod); + } + } } //----------------------------------------------------------------------------- - String logObjectInfo(const String& msg, const GLhandleARB obj) - { - String logMessage = msg; + String logObjectInfo(const String& msg, const GLhandleARB obj) + { + String logMessage = msg; - if (obj > 0) - { - GLint infologLength = 0; + if (obj > 0) + { + GLint infologLength = 0; if(glIsProgram(obj)) glValidateProgram(obj); - glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength); + glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength); - if (infologLength > 0) - { - GLint charsWritten = 0; + if (infologLength > 0) + { + GLint charsWritten = 0; - GLcharARB * infoLog = new GLcharARB[infologLength]; + GLcharARB * infoLog = new GLcharARB[infologLength]; - glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog); - logMessage += String(infoLog); - LogManager::getSingleton().logMessage(logMessage); + glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog); + logMessage += String(infoLog); + LogManager::getSingleton().logMessage(logMessage); - delete [] infoLog; - } - } + delete [] infoLog; + } + } - return logMessage; + return logMessage; - } + } } // namespace GLSL } // namespace Ogre diff --git a/RenderSystems/GL/src/GLSL/src/OgreGLSLGpuProgram.cpp b/RenderSystems/GL/src/GLSL/src/OgreGLSLGpuProgram.cpp index ca6a801594d..cbbd864b134 100644 --- a/RenderSystems/GL/src/GLSL/src/OgreGLSLGpuProgram.cpp +++ b/RenderSystems/GL/src/GLSL/src/OgreGLSLGpuProgram.cpp @@ -34,34 +34,34 @@ THE SOFTWARE. namespace Ogre { namespace GLSL { - GLuint GLSLGpuProgram::mVertexShaderCount = 0; - GLuint GLSLGpuProgram::mFragmentShaderCount = 0; - GLuint GLSLGpuProgram::mGeometryShaderCount = 0; + GLuint GLSLGpuProgram::mVertexShaderCount = 0; + GLuint GLSLGpuProgram::mFragmentShaderCount = 0; + GLuint GLSLGpuProgram::mGeometryShaderCount = 0; //----------------------------------------------------------------------------- - GLSLGpuProgram::GLSLGpuProgram(GLSLProgram* parent) : + GLSLGpuProgram::GLSLGpuProgram(GLSLProgram* parent) : GLGpuProgram(parent->getCreator(), parent->getName(), parent->getHandle(), parent->getGroup(), false, 0), mGLSLProgram(parent) { mType = parent->getType(); mSyntaxCode = "glsl"; - if (parent->getType() == GPT_VERTEX_PROGRAM) - { - mProgramID = ++mVertexShaderCount; - } - else if (parent->getType() == GPT_FRAGMENT_PROGRAM) - { - mProgramID = ++mFragmentShaderCount; - } - else - { - mProgramID = ++mGeometryShaderCount; - } + if (parent->getType() == GPT_VERTEX_PROGRAM) + { + mProgramID = ++mVertexShaderCount; + } + else if (parent->getType() == GPT_FRAGMENT_PROGRAM) + { + mProgramID = ++mFragmentShaderCount; + } + else + { + mProgramID = ++mGeometryShaderCount; + } // transfer skeletal animation status from parent mSkeletalAnimation = mGLSLProgram->isSkeletalAnimationIncluded(); - // there is nothing to load - mLoadFromFile = false; + // there is nothing to load + mLoadFromFile = false; } //----------------------------------------------------------------------- GLSLGpuProgram::~GLSLGpuProgram() @@ -70,120 +70,120 @@ namespace Ogre { // since calling virtual methods in base destructors causes crash unload(); } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void GLSLGpuProgram::loadImpl(void) { - // nothing to load + // nothing to load } - //----------------------------------------------------------------------------- - void GLSLGpuProgram::unloadImpl(void) - { - // nothing to unload - } + //----------------------------------------------------------------------------- + void GLSLGpuProgram::unloadImpl(void) + { + // nothing to unload + } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void GLSLGpuProgram::loadFromSource(void) { - // nothing to load - } - - //----------------------------------------------------------------------------- - void GLSLGpuProgram::bindProgram(void) - { - // Tell the Link Program Manager what shader is to become active - switch (mType) - { - case GPT_VERTEX_PROGRAM: - GLSLLinkProgramManager::getSingleton().setActiveVertexShader( this ); - break; - case GPT_FRAGMENT_PROGRAM: - GLSLLinkProgramManager::getSingleton().setActiveFragmentShader( this ); - break; - case GPT_GEOMETRY_PROGRAM: - GLSLLinkProgramManager::getSingleton().setActiveGeometryShader( this ); - break; - default: - break; - } - } - - //----------------------------------------------------------------------------- - void GLSLGpuProgram::unbindProgram(void) - { - // Tell the Link Program Manager what shader is to become inactive - if (mType == GPT_VERTEX_PROGRAM) - { - GLSLLinkProgramManager::getSingleton().setActiveVertexShader( NULL ); - } - else if (mType == GPT_GEOMETRY_PROGRAM) - { - GLSLLinkProgramManager::getSingleton().setActiveGeometryShader( NULL ); - } - else // its a fragment shader - { - GLSLLinkProgramManager::getSingleton().setActiveFragmentShader( NULL ); - } - - } - - //----------------------------------------------------------------------------- - void GLSLGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask) - { - // link can throw exceptions, ignore them at this point - try - { - // activate the link program object - GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); - // pass on parameters from params to program object uniforms - linkProgram->updateUniforms(params, mask, mType); - } - catch (Exception& e) {} - - } - - //----------------------------------------------------------------------------- - void GLSLGpuProgram::bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) - { - // activate the link program object - GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); - // pass on parameters from params to program object uniforms - linkProgram->updatePassIterationUniforms( params ); - - } - //----------------------------------------------------------------------------- - GLuint GLSLGpuProgram::getAttributeIndex(VertexElementSemantic semantic, uint index) - { - // get link program - only call this in the context of bound program - GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); - - if (linkProgram->isAttributeValid(semantic, index)) - { - return linkProgram->getAttributeIndex(semantic, index); - } - else - { - // fall back to default implementation, allow default bindings - return GLGpuProgram::getAttributeIndex(semantic, index); - } - - } - //----------------------------------------------------------------------------- - bool GLSLGpuProgram::isAttributeValid(VertexElementSemantic semantic, uint index) - { - // get link program - only call this in the context of bound program - GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); - - if (linkProgram->isAttributeValid(semantic, index)) - { - return true; - } - else - { - // fall back to default implementation, allow default bindings - return GLGpuProgram::isAttributeValid(semantic, index); - } - } + // nothing to load + } + + //----------------------------------------------------------------------------- + void GLSLGpuProgram::bindProgram(void) + { + // Tell the Link Program Manager what shader is to become active + switch (mType) + { + case GPT_VERTEX_PROGRAM: + GLSLLinkProgramManager::getSingleton().setActiveVertexShader( this ); + break; + case GPT_FRAGMENT_PROGRAM: + GLSLLinkProgramManager::getSingleton().setActiveFragmentShader( this ); + break; + case GPT_GEOMETRY_PROGRAM: + GLSLLinkProgramManager::getSingleton().setActiveGeometryShader( this ); + break; + default: + break; + } + } + + //----------------------------------------------------------------------------- + void GLSLGpuProgram::unbindProgram(void) + { + // Tell the Link Program Manager what shader is to become inactive + if (mType == GPT_VERTEX_PROGRAM) + { + GLSLLinkProgramManager::getSingleton().setActiveVertexShader( NULL ); + } + else if (mType == GPT_GEOMETRY_PROGRAM) + { + GLSLLinkProgramManager::getSingleton().setActiveGeometryShader( NULL ); + } + else // its a fragment shader + { + GLSLLinkProgramManager::getSingleton().setActiveFragmentShader( NULL ); + } + + } + + //----------------------------------------------------------------------------- + void GLSLGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask) + { + // link can throw exceptions, ignore them at this point + try + { + // activate the link program object + GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); + // pass on parameters from params to program object uniforms + linkProgram->updateUniforms(params, mask, mType); + } + catch (Exception& e) {} + + } + + //----------------------------------------------------------------------------- + void GLSLGpuProgram::bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) + { + // activate the link program object + GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); + // pass on parameters from params to program object uniforms + linkProgram->updatePassIterationUniforms( params ); + + } + //----------------------------------------------------------------------------- + GLuint GLSLGpuProgram::getAttributeIndex(VertexElementSemantic semantic, uint index) + { + // get link program - only call this in the context of bound program + GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); + + if (linkProgram->isAttributeValid(semantic, index)) + { + return linkProgram->getAttributeIndex(semantic, index); + } + else + { + // fall back to default implementation, allow default bindings + return GLGpuProgram::getAttributeIndex(semantic, index); + } + + } + //----------------------------------------------------------------------------- + bool GLSLGpuProgram::isAttributeValid(VertexElementSemantic semantic, uint index) + { + // get link program - only call this in the context of bound program + GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); + + if (linkProgram->isAttributeValid(semantic, index)) + { + return true; + } + else + { + // fall back to default implementation, allow default bindings + return GLGpuProgram::isAttributeValid(semantic, index); + } + } } diff --git a/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgram.cpp b/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgram.cpp index 809621f6bd2..50ced705d30 100644 --- a/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgram.cpp +++ b/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgram.cpp @@ -38,161 +38,161 @@ THE SOFTWARE. namespace Ogre { namespace GLSL { - // a builtin custom attrib name - // ---------------------------------------------- - // 0 gl_Vertex vertex - // 1 n/a blendWeights - // 2 gl_Normal normal - // 3 gl_Color colour - // 4 gl_SecondaryColor secondary_colour - // 5 gl_FogCoord fog_coord - // 7 n/a blendIndices - // 8 gl_MultiTexCoord0 uv0 - // 9 gl_MultiTexCoord1 uv1 - // 10 gl_MultiTexCoord2 uv2 - // 11 gl_MultiTexCoord3 uv3 - // 12 gl_MultiTexCoord4 uv4 - // 13 gl_MultiTexCoord5 uv5 - // 14 gl_MultiTexCoord6 uv6, tangent - // 15 gl_MultiTexCoord7 uv7, binormal - GLSLLinkProgram::CustomAttribute GLSLLinkProgram::msCustomAttributes[] = { - CustomAttribute("vertex", GLGpuProgram::getFixedAttributeIndex(VES_POSITION, 0)), - CustomAttribute("blendWeights", GLGpuProgram::getFixedAttributeIndex(VES_BLEND_WEIGHTS, 0)), - CustomAttribute("normal", GLGpuProgram::getFixedAttributeIndex(VES_NORMAL, 0)), - CustomAttribute("colour", GLGpuProgram::getFixedAttributeIndex(VES_DIFFUSE, 0)), - CustomAttribute("secondary_colour", GLGpuProgram::getFixedAttributeIndex(VES_SPECULAR, 0)), - CustomAttribute("blendIndices", GLGpuProgram::getFixedAttributeIndex(VES_BLEND_INDICES, 0)), - CustomAttribute("uv0", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 0)), - CustomAttribute("uv1", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 1)), - CustomAttribute("uv2", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 2)), - CustomAttribute("uv3", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 3)), - CustomAttribute("uv4", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 4)), - CustomAttribute("uv5", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 5)), - CustomAttribute("uv6", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 6)), - CustomAttribute("uv7", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 7)), - CustomAttribute("tangent", GLGpuProgram::getFixedAttributeIndex(VES_TANGENT, 0)), - CustomAttribute("binormal", GLGpuProgram::getFixedAttributeIndex(VES_BINORMAL, 0)), - }; - - GLint getGLGeometryInputPrimitiveType(RenderOperation::OperationType operationType, bool requiresAdjacency) - { - switch (operationType) - { - case RenderOperation::OT_POINT_LIST: - return GL_POINTS; - case RenderOperation::OT_LINE_LIST: - case RenderOperation::OT_LINE_STRIP: - return requiresAdjacency ? GL_LINES_ADJACENCY_EXT : GL_LINES; - default: - case RenderOperation::OT_TRIANGLE_LIST: - case RenderOperation::OT_TRIANGLE_STRIP: - case RenderOperation::OT_TRIANGLE_FAN: - return requiresAdjacency ? GL_TRIANGLES_ADJACENCY_EXT : GL_TRIANGLES; - } - } - //----------------------------------------------------------------------- - GLint getGLGeometryOutputPrimitiveType(RenderOperation::OperationType operationType) - { - switch (operationType) - { - case RenderOperation::OT_POINT_LIST: - return GL_POINTS; - case RenderOperation::OT_LINE_STRIP: - return GL_LINE_STRIP; - case RenderOperation::OT_TRIANGLE_STRIP: - return GL_TRIANGLE_STRIP; - default: - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Geometry shader output operation type can only be point list," - "line strip or triangle strip", + // a builtin custom attrib name + // ---------------------------------------------- + // 0 gl_Vertex vertex + // 1 n/a blendWeights + // 2 gl_Normal normal + // 3 gl_Color colour + // 4 gl_SecondaryColor secondary_colour + // 5 gl_FogCoord fog_coord + // 7 n/a blendIndices + // 8 gl_MultiTexCoord0 uv0 + // 9 gl_MultiTexCoord1 uv1 + // 10 gl_MultiTexCoord2 uv2 + // 11 gl_MultiTexCoord3 uv3 + // 12 gl_MultiTexCoord4 uv4 + // 13 gl_MultiTexCoord5 uv5 + // 14 gl_MultiTexCoord6 uv6, tangent + // 15 gl_MultiTexCoord7 uv7, binormal + GLSLLinkProgram::CustomAttribute GLSLLinkProgram::msCustomAttributes[] = { + CustomAttribute("vertex", GLGpuProgram::getFixedAttributeIndex(VES_POSITION, 0)), + CustomAttribute("blendWeights", GLGpuProgram::getFixedAttributeIndex(VES_BLEND_WEIGHTS, 0)), + CustomAttribute("normal", GLGpuProgram::getFixedAttributeIndex(VES_NORMAL, 0)), + CustomAttribute("colour", GLGpuProgram::getFixedAttributeIndex(VES_DIFFUSE, 0)), + CustomAttribute("secondary_colour", GLGpuProgram::getFixedAttributeIndex(VES_SPECULAR, 0)), + CustomAttribute("blendIndices", GLGpuProgram::getFixedAttributeIndex(VES_BLEND_INDICES, 0)), + CustomAttribute("uv0", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 0)), + CustomAttribute("uv1", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 1)), + CustomAttribute("uv2", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 2)), + CustomAttribute("uv3", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 3)), + CustomAttribute("uv4", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 4)), + CustomAttribute("uv5", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 5)), + CustomAttribute("uv6", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 6)), + CustomAttribute("uv7", GLGpuProgram::getFixedAttributeIndex(VES_TEXTURE_COORDINATES, 7)), + CustomAttribute("tangent", GLGpuProgram::getFixedAttributeIndex(VES_TANGENT, 0)), + CustomAttribute("binormal", GLGpuProgram::getFixedAttributeIndex(VES_BINORMAL, 0)), + }; + + GLint getGLGeometryInputPrimitiveType(RenderOperation::OperationType operationType, bool requiresAdjacency) + { + switch (operationType) + { + case RenderOperation::OT_POINT_LIST: + return GL_POINTS; + case RenderOperation::OT_LINE_LIST: + case RenderOperation::OT_LINE_STRIP: + return requiresAdjacency ? GL_LINES_ADJACENCY_EXT : GL_LINES; + default: + case RenderOperation::OT_TRIANGLE_LIST: + case RenderOperation::OT_TRIANGLE_STRIP: + case RenderOperation::OT_TRIANGLE_FAN: + return requiresAdjacency ? GL_TRIANGLES_ADJACENCY_EXT : GL_TRIANGLES; + } + } + //----------------------------------------------------------------------- + GLint getGLGeometryOutputPrimitiveType(RenderOperation::OperationType operationType) + { + switch (operationType) + { + case RenderOperation::OT_POINT_LIST: + return GL_POINTS; + case RenderOperation::OT_LINE_STRIP: + return GL_LINE_STRIP; + case RenderOperation::OT_TRIANGLE_STRIP: + return GL_TRIANGLE_STRIP; + default: + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Geometry shader output operation type can only be point list," + "line strip or triangle strip", "GLSLLinkProgram::getGLGeometryOutputPrimitiveType"); - } - } + } + } - //----------------------------------------------------------------------- - GLSLLinkProgram::GLSLLinkProgram(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* geometryProgram, GLSLGpuProgram* fragmentProgram) + //----------------------------------------------------------------------- + GLSLLinkProgram::GLSLLinkProgram(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* geometryProgram, GLSLGpuProgram* fragmentProgram) : mVertexProgram(vertexProgram) - , mGeometryProgram(geometryProgram) - , mFragmentProgram(fragmentProgram) - , mUniformRefsBuilt(false) + , mGeometryProgram(geometryProgram) + , mFragmentProgram(fragmentProgram) + , mUniformRefsBuilt(false) , mLinked(false) - , mTriedToLinkAndFailed(false) + , mTriedToLinkAndFailed(false) , mSkeletalAnimation(false) - { + { // Initialise uniform cache - mUniformCache = new GLUniformCache(); - } + mUniformCache = new GLUniformCache(); + } - //----------------------------------------------------------------------- - GLSLLinkProgram::~GLSLLinkProgram(void) - { - glDeleteObjectARB(mGLHandle); + //----------------------------------------------------------------------- + GLSLLinkProgram::~GLSLLinkProgram(void) + { + glDeleteObjectARB(mGLHandle); delete mUniformCache; mUniformCache = 0; - } + } - //----------------------------------------------------------------------- - void GLSLLinkProgram::activate(void) - { - if (!mLinked && !mTriedToLinkAndFailed) - { - glGetError(); //Clean up the error. Otherwise will flood log. + //----------------------------------------------------------------------- + void GLSLLinkProgram::activate(void) + { + if (!mLinked && !mTriedToLinkAndFailed) + { + glGetError(); //Clean up the error. Otherwise will flood log. - mGLHandle = glCreateProgramObjectARB(); + mGLHandle = glCreateProgramObjectARB(); GLenum glErr = glGetError(); if(glErr != GL_NO_ERROR) { - reportGLSLError( glErr, "GLSLLinkProgram::activate", "Error Creating GLSL Program Object", 0 ); + reportGLSLError( glErr, "GLSLLinkProgram::activate", "Error Creating GLSL Program Object", 0 ); + } + + if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() && + GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) ) + { + getMicrocodeFromCache(); } + else + { + compileAndLink(); - if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() && - GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) ) - { - getMicrocodeFromCache(); - } - else - { - compileAndLink(); - - } - buildGLUniformReferences(); - extractAttributes(); - } - if (mLinked) - { + } + buildGLUniformReferences(); + extractAttributes(); + } + if (mLinked) + { GLenum glErr = glGetError(); if(glErr != GL_NO_ERROR) { - reportGLSLError( glErr, "GLSLLinkProgram::Activate", - "Error prior to using GLSL Program Object : ", mGLHandle, false, false); + reportGLSLError( glErr, "GLSLLinkProgram::Activate", + "Error prior to using GLSL Program Object : ", mGLHandle, false, false); } - glUseProgramObjectARB( mGLHandle ); + glUseProgramObjectARB( mGLHandle ); glErr = glGetError(); if(glErr != GL_NO_ERROR) { - reportGLSLError( glErr, "GLSLLinkProgram::Activate", - "Error using GLSL Program Object : ", mGLHandle, false, false); + reportGLSLError( glErr, "GLSLLinkProgram::Activate", + "Error using GLSL Program Object : ", mGLHandle, false, false); } } - } + } //----------------------------------------------------------------------- void GLSLLinkProgram::getMicrocodeFromCache(void) { - GpuProgramManager::Microcode cacheMicrocode = - GpuProgramManager::getSingleton().getMicrocodeFromCache(getCombinedName()); - - GLenum binaryFormat = *((GLenum *)(cacheMicrocode->getPtr())); - uint8 * programBuffer = cacheMicrocode->getPtr() + sizeof(GLenum); - size_t sizeOfBuffer = cacheMicrocode->size() - sizeof(GLenum); - glProgramBinary(mGLHandle, - binaryFormat, - programBuffer, - static_cast(sizeOfBuffer) - ); + GpuProgramManager::Microcode cacheMicrocode = + GpuProgramManager::getSingleton().getMicrocodeFromCache(getCombinedName()); + + GLenum binaryFormat = *((GLenum *)(cacheMicrocode->getPtr())); + uint8 * programBuffer = cacheMicrocode->getPtr() + sizeof(GLenum); + size_t sizeOfBuffer = cacheMicrocode->size() - sizeof(GLenum); + glProgramBinary(mGLHandle, + binaryFormat, + programBuffer, + static_cast(sizeOfBuffer) + ); glGetProgramiv(mGLHandle, GL_LINK_STATUS, &mLinked); if (!mLinked) @@ -202,70 +202,70 @@ namespace Ogre { // were cached away. Fallback to source shader loading path, // and then retrieve and cache new program binaries once again. // - compileAndLink(); + compileAndLink(); + } + } + //----------------------------------------------------------------------- + void GLSLLinkProgram::extractAttributes(void) + { + size_t numAttribs = sizeof(msCustomAttributes)/sizeof(CustomAttribute); + + for (size_t i = 0; i < numAttribs; ++i) + { + const CustomAttribute& a = msCustomAttributes[i]; + GLint attrib = glGetAttribLocationARB(mGLHandle, a.name.c_str()); + + if (attrib != -1) + { + mValidAttributes.insert(a.attrib); + } + } + } + //----------------------------------------------------------------------- + GLuint GLSLLinkProgram::getAttributeIndex(VertexElementSemantic semantic, uint index) + { + return GLGpuProgram::getFixedAttributeIndex(semantic, index); + } + //----------------------------------------------------------------------- + bool GLSLLinkProgram::isAttributeValid(VertexElementSemantic semantic, uint index) + { + return mValidAttributes.find(getAttributeIndex(semantic, index)) != mValidAttributes.end(); + } + //----------------------------------------------------------------------- + void GLSLLinkProgram::buildGLUniformReferences(void) + { + if (!mUniformRefsBuilt) + { + const GpuConstantDefinitionMap* vertParams = 0; + const GpuConstantDefinitionMap* fragParams = 0; + const GpuConstantDefinitionMap* geomParams = 0; + if (mVertexProgram) + { + vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map); + } + if (mGeometryProgram) + { + geomParams = &(mGeometryProgram->getGLSLProgram()->getConstantDefinitions().map); + } + if (mFragmentProgram) + { + fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map); + } + + GLSLLinkProgramManager::getSingleton().extractUniforms( + mGLHandle, vertParams, geomParams, fragParams, mGLUniformReferences); + + mUniformRefsBuilt = true; } - } - //----------------------------------------------------------------------- - void GLSLLinkProgram::extractAttributes(void) - { - size_t numAttribs = sizeof(msCustomAttributes)/sizeof(CustomAttribute); - - for (size_t i = 0; i < numAttribs; ++i) - { - const CustomAttribute& a = msCustomAttributes[i]; - GLint attrib = glGetAttribLocationARB(mGLHandle, a.name.c_str()); - - if (attrib != -1) - { - mValidAttributes.insert(a.attrib); - } - } - } - //----------------------------------------------------------------------- - GLuint GLSLLinkProgram::getAttributeIndex(VertexElementSemantic semantic, uint index) - { - return GLGpuProgram::getFixedAttributeIndex(semantic, index); - } - //----------------------------------------------------------------------- - bool GLSLLinkProgram::isAttributeValid(VertexElementSemantic semantic, uint index) - { - return mValidAttributes.find(getAttributeIndex(semantic, index)) != mValidAttributes.end(); - } - //----------------------------------------------------------------------- - void GLSLLinkProgram::buildGLUniformReferences(void) - { - if (!mUniformRefsBuilt) - { - const GpuConstantDefinitionMap* vertParams = 0; - const GpuConstantDefinitionMap* fragParams = 0; - const GpuConstantDefinitionMap* geomParams = 0; - if (mVertexProgram) - { - vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map); - } - if (mGeometryProgram) - { - geomParams = &(mGeometryProgram->getGLSLProgram()->getConstantDefinitions().map); - } - if (mFragmentProgram) - { - fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map); - } - - GLSLLinkProgramManager::getSingleton().extractUniforms( - mGLHandle, vertParams, geomParams, fragParams, mGLUniformReferences); - - mUniformRefsBuilt = true; - } - } - - //----------------------------------------------------------------------- - void GLSLLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params, - uint16 mask, GpuProgramType fromProgType) - { - // iterate through uniform reference list and update uniform values - GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); - GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); + } + + //----------------------------------------------------------------------- + void GLSLLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params, + uint16 mask, GpuProgramType fromProgType) + { + // iterate through uniform reference list and update uniform values + GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); + GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); // determine if we need to transpose matrices when binding int transpose = GL_TRUE; @@ -276,18 +276,18 @@ namespace Ogre { transpose = GL_FALSE; } - for (;currentUniform != endUniform; ++currentUniform) - { - // Only pull values from buffer it's supposed to be in (vertex or fragment) - // This method will be called twice, once for vertex program params, - // and once for fragment program params. - if (fromProgType == currentUniform->mSourceProgType) - { - const GpuConstantDefinition* def = currentUniform->mConstantDef; - if (def->variability & mask) - { + for (;currentUniform != endUniform; ++currentUniform) + { + // Only pull values from buffer it's supposed to be in (vertex or fragment) + // This method will be called twice, once for vertex program params, + // and once for fragment program params. + if (fromProgType == currentUniform->mSourceProgType) + { + const GpuConstantDefinition* def = currentUniform->mConstantDef; + if (def->variability & mask) + { - GLsizei glArraySize = (GLsizei)def->arraySize; + GLsizei glArraySize = (GLsizei)def->arraySize; bool shouldUpdate = true; @@ -318,318 +318,318 @@ namespace Ogre { if(!shouldUpdate) continue; - // get the index in the parameter real list - switch (def->constType) - { - case GCT_FLOAT1: - glUniform1fvARB(currentUniform->mLocation, glArraySize, - params->getFloatPointer(def->physicalIndex)); - break; - case GCT_FLOAT2: - glUniform2fvARB(currentUniform->mLocation, glArraySize, - params->getFloatPointer(def->physicalIndex)); - break; - case GCT_FLOAT3: - glUniform3fvARB(currentUniform->mLocation, glArraySize, - params->getFloatPointer(def->physicalIndex)); - break; - case GCT_FLOAT4: - glUniform4fvARB(currentUniform->mLocation, glArraySize, - params->getFloatPointer(def->physicalIndex)); - break; - case GCT_MATRIX_2X2: - glUniformMatrix2fvARB(currentUniform->mLocation, glArraySize, - transpose, params->getFloatPointer(def->physicalIndex)); - break; - case GCT_MATRIX_2X3: - if (GLEW_VERSION_2_1) - { - glUniformMatrix2x3fv(currentUniform->mLocation, glArraySize, - transpose, params->getFloatPointer(def->physicalIndex)); - } - break; - case GCT_MATRIX_2X4: - if (GLEW_VERSION_2_1) - { - glUniformMatrix2x4fv(currentUniform->mLocation, glArraySize, - transpose, params->getFloatPointer(def->physicalIndex)); - } - break; - case GCT_MATRIX_3X2: - if (GLEW_VERSION_2_1) - { - glUniformMatrix3x2fv(currentUniform->mLocation, glArraySize, - transpose, params->getFloatPointer(def->physicalIndex)); - } - break; - case GCT_MATRIX_3X3: - glUniformMatrix3fvARB(currentUniform->mLocation, glArraySize, - transpose, params->getFloatPointer(def->physicalIndex)); - break; - case GCT_MATRIX_3X4: - if (GLEW_VERSION_2_1) - { - glUniformMatrix3x4fv(currentUniform->mLocation, glArraySize, - transpose, params->getFloatPointer(def->physicalIndex)); - } - break; - case GCT_MATRIX_4X2: - if (GLEW_VERSION_2_1) - { - glUniformMatrix4x2fv(currentUniform->mLocation, glArraySize, - transpose, params->getFloatPointer(def->physicalIndex)); - } - break; - case GCT_MATRIX_4X3: - if (GLEW_VERSION_2_1) - { - glUniformMatrix4x3fv(currentUniform->mLocation, glArraySize, - transpose, params->getFloatPointer(def->physicalIndex)); - } - break; - case GCT_MATRIX_4X4: - glUniformMatrix4fvARB(currentUniform->mLocation, glArraySize, - transpose, params->getFloatPointer(def->physicalIndex)); - break; - case GCT_INT1: - glUniform1ivARB(currentUniform->mLocation, glArraySize, - (GLint*)params->getIntPointer(def->physicalIndex)); - break; - case GCT_INT2: - glUniform2ivARB(currentUniform->mLocation, glArraySize, - (GLint*)params->getIntPointer(def->physicalIndex)); - break; - case GCT_INT3: - glUniform3ivARB(currentUniform->mLocation, glArraySize, - (GLint*)params->getIntPointer(def->physicalIndex)); - break; - case GCT_INT4: - glUniform4ivARB(currentUniform->mLocation, glArraySize, - (GLint*)params->getIntPointer(def->physicalIndex)); - break; - case GCT_SAMPLER1D: - case GCT_SAMPLER1DSHADOW: - case GCT_SAMPLER2D: - case GCT_SAMPLER2DSHADOW: + // get the index in the parameter real list + switch (def->constType) + { + case GCT_FLOAT1: + glUniform1fvARB(currentUniform->mLocation, glArraySize, + params->getFloatPointer(def->physicalIndex)); + break; + case GCT_FLOAT2: + glUniform2fvARB(currentUniform->mLocation, glArraySize, + params->getFloatPointer(def->physicalIndex)); + break; + case GCT_FLOAT3: + glUniform3fvARB(currentUniform->mLocation, glArraySize, + params->getFloatPointer(def->physicalIndex)); + break; + case GCT_FLOAT4: + glUniform4fvARB(currentUniform->mLocation, glArraySize, + params->getFloatPointer(def->physicalIndex)); + break; + case GCT_MATRIX_2X2: + glUniformMatrix2fvARB(currentUniform->mLocation, glArraySize, + transpose, params->getFloatPointer(def->physicalIndex)); + break; + case GCT_MATRIX_2X3: + if (GLEW_VERSION_2_1) + { + glUniformMatrix2x3fv(currentUniform->mLocation, glArraySize, + transpose, params->getFloatPointer(def->physicalIndex)); + } + break; + case GCT_MATRIX_2X4: + if (GLEW_VERSION_2_1) + { + glUniformMatrix2x4fv(currentUniform->mLocation, glArraySize, + transpose, params->getFloatPointer(def->physicalIndex)); + } + break; + case GCT_MATRIX_3X2: + if (GLEW_VERSION_2_1) + { + glUniformMatrix3x2fv(currentUniform->mLocation, glArraySize, + transpose, params->getFloatPointer(def->physicalIndex)); + } + break; + case GCT_MATRIX_3X3: + glUniformMatrix3fvARB(currentUniform->mLocation, glArraySize, + transpose, params->getFloatPointer(def->physicalIndex)); + break; + case GCT_MATRIX_3X4: + if (GLEW_VERSION_2_1) + { + glUniformMatrix3x4fv(currentUniform->mLocation, glArraySize, + transpose, params->getFloatPointer(def->physicalIndex)); + } + break; + case GCT_MATRIX_4X2: + if (GLEW_VERSION_2_1) + { + glUniformMatrix4x2fv(currentUniform->mLocation, glArraySize, + transpose, params->getFloatPointer(def->physicalIndex)); + } + break; + case GCT_MATRIX_4X3: + if (GLEW_VERSION_2_1) + { + glUniformMatrix4x3fv(currentUniform->mLocation, glArraySize, + transpose, params->getFloatPointer(def->physicalIndex)); + } + break; + case GCT_MATRIX_4X4: + glUniformMatrix4fvARB(currentUniform->mLocation, glArraySize, + transpose, params->getFloatPointer(def->physicalIndex)); + break; + case GCT_INT1: + glUniform1ivARB(currentUniform->mLocation, glArraySize, + (GLint*)params->getIntPointer(def->physicalIndex)); + break; + case GCT_INT2: + glUniform2ivARB(currentUniform->mLocation, glArraySize, + (GLint*)params->getIntPointer(def->physicalIndex)); + break; + case GCT_INT3: + glUniform3ivARB(currentUniform->mLocation, glArraySize, + (GLint*)params->getIntPointer(def->physicalIndex)); + break; + case GCT_INT4: + glUniform4ivARB(currentUniform->mLocation, glArraySize, + (GLint*)params->getIntPointer(def->physicalIndex)); + break; + case GCT_SAMPLER1D: + case GCT_SAMPLER1DSHADOW: + case GCT_SAMPLER2D: + case GCT_SAMPLER2DSHADOW: case GCT_SAMPLER2DARRAY: - case GCT_SAMPLER3D: - case GCT_SAMPLERCUBE: - // samplers handled like 1-element ints - glUniform1ivARB(currentUniform->mLocation, 1, - (GLint*)params->getIntPointer(def->physicalIndex)); - break; + case GCT_SAMPLER3D: + case GCT_SAMPLERCUBE: + // samplers handled like 1-element ints + glUniform1ivARB(currentUniform->mLocation, 1, + (GLint*)params->getIntPointer(def->physicalIndex)); + break; case GCT_UNKNOWN: default: break; - } // end switch - #if OGRE_DEBUG_MODE + } // end switch + #if OGRE_DEBUG_MODE GLenum glErr = glGetError(); if(glErr != GL_NO_ERROR) { - reportGLSLError( glErr, "GLSLLinkProgram::updateUniforms", "Error updating uniform", 0 ); + reportGLSLError( glErr, "GLSLLinkProgram::updateUniforms", "Error updating uniform", 0 ); } - #endif - } // variability & mask - } // fromProgType == currentUniform->mSourceProgType + #endif + } // variability & mask + } // fromProgType == currentUniform->mSourceProgType - } // end for - } - //----------------------------------------------------------------------- - void GLSLLinkProgram::updatePassIterationUniforms(GpuProgramParametersSharedPtr params) - { - if (params->hasPassIterationNumber()) - { - size_t index = params->getPassIterationNumberIndex(); - - GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); - GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); - - // need to find the uniform that matches the multi pass entry - for (;currentUniform != endUniform; ++currentUniform) - { - // get the index in the parameter real list - if (index == currentUniform->mConstantDef->physicalIndex) - { + } // end for + } + //----------------------------------------------------------------------- + void GLSLLinkProgram::updatePassIterationUniforms(GpuProgramParametersSharedPtr params) + { + if (params->hasPassIterationNumber()) + { + size_t index = params->getPassIterationNumberIndex(); + + GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); + GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); + + // need to find the uniform that matches the multi pass entry + for (;currentUniform != endUniform; ++currentUniform) + { + // get the index in the parameter real list + if (index == currentUniform->mConstantDef->physicalIndex) + { if(!mUniformCache->updateUniform(currentUniform->mLocation, params->getFloatPointer(index), static_cast(currentUniform->mConstantDef->elementSize * currentUniform->mConstantDef->arraySize * sizeof(float)))) return; - } - } - } + } + } + } } - //----------------------------------------------------------------------- - Ogre::String GLSLLinkProgram::getCombinedName() - { - String name; - if (mVertexProgram) - { - name += "Vertex Program:" ; - name += mVertexProgram->getName(); - } - if (mFragmentProgram) - { - name += " Fragment Program:" ; - name += mFragmentProgram->getName(); - } - if (mGeometryProgram) - { - name += " Geometry Program:" ; - name += mGeometryProgram->getName(); - } - return name; - } - //----------------------------------------------------------------------- - void GLSLLinkProgram::compileAndLink() - { - if (mVertexProgram) - { - // compile and attach Vertex Program - if (!mVertexProgram->getGLSLProgram()->compile(true)) - { - // todo error - return; - } - mVertexProgram->getGLSLProgram()->attachToProgramObject(mGLHandle); - setSkeletalAnimationIncluded(mVertexProgram->isSkeletalAnimationIncluded()); - - // Some drivers (e.g. OS X on nvidia) incorrectly determine the attribute binding automatically - - // and end up aliasing existing built-ins. So avoid! - // Bind all used attribs - not all possible ones otherwise we'll get - // lots of warnings in the log, and also may end up aliasing names used - // as varyings by accident - // Because we can't ask GL whether an attribute is used in the shader - // until it is linked (chicken and egg!) we have to parse the source - - size_t numAttribs = sizeof(msCustomAttributes)/sizeof(CustomAttribute); - const String& vpSource = mVertexProgram->getGLSLProgram()->getSource(); - for (size_t i = 0; i < numAttribs; ++i) - { - const CustomAttribute& a = msCustomAttributes[i]; - - // we're looking for either: - // attribute vec - // in vec - // The latter is recommended in GLSL 1.3 onwards - // be slightly flexible about formatting - String::size_type pos = vpSource.find(a.name); + //----------------------------------------------------------------------- + Ogre::String GLSLLinkProgram::getCombinedName() + { + String name; + if (mVertexProgram) + { + name += "Vertex Program:" ; + name += mVertexProgram->getName(); + } + if (mFragmentProgram) + { + name += " Fragment Program:" ; + name += mFragmentProgram->getName(); + } + if (mGeometryProgram) + { + name += " Geometry Program:" ; + name += mGeometryProgram->getName(); + } + return name; + } + //----------------------------------------------------------------------- + void GLSLLinkProgram::compileAndLink() + { + if (mVertexProgram) + { + // compile and attach Vertex Program + if (!mVertexProgram->getGLSLProgram()->compile(true)) + { + // todo error + return; + } + mVertexProgram->getGLSLProgram()->attachToProgramObject(mGLHandle); + setSkeletalAnimationIncluded(mVertexProgram->isSkeletalAnimationIncluded()); + + // Some drivers (e.g. OS X on nvidia) incorrectly determine the attribute binding automatically + + // and end up aliasing existing built-ins. So avoid! + // Bind all used attribs - not all possible ones otherwise we'll get + // lots of warnings in the log, and also may end up aliasing names used + // as varyings by accident + // Because we can't ask GL whether an attribute is used in the shader + // until it is linked (chicken and egg!) we have to parse the source + + size_t numAttribs = sizeof(msCustomAttributes)/sizeof(CustomAttribute); + const String& vpSource = mVertexProgram->getGLSLProgram()->getSource(); + for (size_t i = 0; i < numAttribs; ++i) + { + const CustomAttribute& a = msCustomAttributes[i]; + + // we're looking for either: + // attribute vec + // in vec + // The latter is recommended in GLSL 1.3 onwards + // be slightly flexible about formatting + String::size_type pos = vpSource.find(a.name); bool foundAttr = false; - while (pos != String::npos && !foundAttr) - { - String::size_type startpos = vpSource.find("attribute", pos < 20 ? 0 : pos-20); - if (startpos == String::npos) - startpos = vpSource.find("in", pos-20); - if (startpos != String::npos && startpos < pos) - { - // final check - String expr = vpSource.substr(startpos, pos + a.name.length() - startpos); - StringVector vec = StringUtil::split(expr); - if ((vec[0] == "in" || vec[0] == "attribute") && vec[2] == a.name) + while (pos != String::npos && !foundAttr) + { + String::size_type startpos = vpSource.find("attribute", pos < 20 ? 0 : pos-20); + if (startpos == String::npos) + startpos = vpSource.find("in", pos-20); + if (startpos != String::npos && startpos < pos) + { + // final check + String expr = vpSource.substr(startpos, pos + a.name.length() - startpos); + StringVector vec = StringUtil::split(expr); + if ((vec[0] == "in" || vec[0] == "attribute") && vec[2] == a.name) { - glBindAttribLocationARB(mGLHandle, a.attrib, a.name.c_str()); + glBindAttribLocationARB(mGLHandle, a.attrib, a.name.c_str()); foundAttr = true; } - } + } // Find the position of the next occurrence if needed pos = vpSource.find(a.name, pos + a.name.length()); - } - } - } - - if (mGeometryProgram) - { - // compile and attach Geometry Program - if (!mGeometryProgram->getGLSLProgram()->compile(true)) - { - // todo error - return; - } - - mGeometryProgram->getGLSLProgram()->attachToProgramObject(mGLHandle); - - //Don't set adjacency flag. We handle it internally and expose "false" - - RenderOperation::OperationType inputOperationType = mGeometryProgram->getGLSLProgram()->getInputOperationType(); - glProgramParameteriEXT(mGLHandle, GL_GEOMETRY_INPUT_TYPE_EXT, - getGLGeometryInputPrimitiveType(inputOperationType, mGeometryProgram->isAdjacencyInfoRequired())); - - RenderOperation::OperationType outputOperationType = mGeometryProgram->getGLSLProgram()->getOutputOperationType(); - - glProgramParameteriEXT(mGLHandle, GL_GEOMETRY_OUTPUT_TYPE_EXT, - getGLGeometryOutputPrimitiveType(outputOperationType)); - - glProgramParameteriEXT(mGLHandle, GL_GEOMETRY_VERTICES_OUT_EXT, - mGeometryProgram->getGLSLProgram()->getMaxOutputVertices()); - } - - if (mFragmentProgram) - { - // compile and attach Fragment Program - if (!mFragmentProgram->getGLSLProgram()->compile(true)) - { - // todo error - return; - } - mFragmentProgram->getGLSLProgram()->attachToProgramObject(mGLHandle); - } - - - // now the link - - glLinkProgramARB( mGLHandle ); - glGetObjectParameterivARB( mGLHandle, GL_OBJECT_LINK_STATUS_ARB, &mLinked ); - mTriedToLinkAndFailed = !mLinked; - - // force logging and raise exception if not linked + } + } + } + + if (mGeometryProgram) + { + // compile and attach Geometry Program + if (!mGeometryProgram->getGLSLProgram()->compile(true)) + { + // todo error + return; + } + + mGeometryProgram->getGLSLProgram()->attachToProgramObject(mGLHandle); + + //Don't set adjacency flag. We handle it internally and expose "false" + + RenderOperation::OperationType inputOperationType = mGeometryProgram->getGLSLProgram()->getInputOperationType(); + glProgramParameteriEXT(mGLHandle, GL_GEOMETRY_INPUT_TYPE_EXT, + getGLGeometryInputPrimitiveType(inputOperationType, mGeometryProgram->isAdjacencyInfoRequired())); + + RenderOperation::OperationType outputOperationType = mGeometryProgram->getGLSLProgram()->getOutputOperationType(); + + glProgramParameteriEXT(mGLHandle, GL_GEOMETRY_OUTPUT_TYPE_EXT, + getGLGeometryOutputPrimitiveType(outputOperationType)); + + glProgramParameteriEXT(mGLHandle, GL_GEOMETRY_VERTICES_OUT_EXT, + mGeometryProgram->getGLSLProgram()->getMaxOutputVertices()); + } + + if (mFragmentProgram) + { + // compile and attach Fragment Program + if (!mFragmentProgram->getGLSLProgram()->compile(true)) + { + // todo error + return; + } + mFragmentProgram->getGLSLProgram()->attachToProgramObject(mGLHandle); + } + + + // now the link + + glLinkProgramARB( mGLHandle ); + glGetObjectParameterivARB( mGLHandle, GL_OBJECT_LINK_STATUS_ARB, &mLinked ); + mTriedToLinkAndFailed = !mLinked; + + // force logging and raise exception if not linked GLenum glErr = glGetError(); if(glErr != GL_NO_ERROR) { - reportGLSLError( glErr, "GLSLLinkProgram::compileAndLink", - "Error linking GLSL Program Object : ", mGLHandle, !mLinked, !mLinked ); + reportGLSLError( glErr, "GLSLLinkProgram::compileAndLink", + "Error linking GLSL Program Object : ", mGLHandle, !mLinked, !mLinked ); + } + + if(mLinked) + { + logObjectInfo( getCombinedName() + String(" GLSL link result : "), mGLHandle ); } - - if(mLinked) - { - logObjectInfo( getCombinedName() + String(" GLSL link result : "), mGLHandle ); - } - - if (mLinked) - { - if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() ) - { - // add to the microcode to the cache - String name; - name = getCombinedName(); - - // get buffer size - GLint binaryLength = 0; - glGetProgramiv(mGLHandle, GL_PROGRAM_BINARY_LENGTH, &binaryLength); - - // turns out we need this param when loading - // it will be the first bytes of the array in the microcode - GLenum binaryFormat = 0; + + if (mLinked) + { + if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() ) + { + // add to the microcode to the cache + String name; + name = getCombinedName(); + + // get buffer size + GLint binaryLength = 0; + glGetProgramiv(mGLHandle, GL_PROGRAM_BINARY_LENGTH, &binaryLength); + + // turns out we need this param when loading + // it will be the first bytes of the array in the microcode + GLenum binaryFormat = 0; // create microcode GpuProgramManager::Microcode newMicrocode = GpuProgramManager::getSingleton().createMicrocode(binaryLength + sizeof(GLenum)); - // get binary - uint8 * programBuffer = newMicrocode->getPtr() + sizeof(GLenum); - glGetProgramBinary(mGLHandle, binaryLength, NULL, &binaryFormat, programBuffer); + // get binary + uint8 * programBuffer = newMicrocode->getPtr() + sizeof(GLenum); + glGetProgramBinary(mGLHandle, binaryLength, NULL, &binaryFormat, programBuffer); // save binary format - memcpy(newMicrocode->getPtr(), &binaryFormat, sizeof(GLenum)); - - // add to the microcode to the cache - GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode); - } - } - } - //----------------------------------------------------------------------- + memcpy(newMicrocode->getPtr(), &binaryFormat, sizeof(GLenum)); + + // add to the microcode to the cache + GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode); + } + } + } + //----------------------------------------------------------------------- } // namespace GLSL } // namespace Ogre diff --git a/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgramManager.cpp b/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgramManager.cpp index 7cd5bb38fe0..29b8f34a231 100644 --- a/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgramManager.cpp +++ b/RenderSystems/GL/src/GLSL/src/OgreGLSLLinkProgramManager.cpp @@ -34,501 +34,501 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - template<> GLSL::GLSLLinkProgramManager* Singleton::msSingleton = 0; + //----------------------------------------------------------------------- + template<> GLSL::GLSLLinkProgramManager* Singleton::msSingleton = 0; namespace GLSL { - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- GLSLLinkProgramManager* GLSLLinkProgramManager::getSingletonPtr(void) { return msSingleton; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- GLSLLinkProgramManager& GLSLLinkProgramManager::getSingleton(void) { assert( msSingleton ); return ( *msSingleton ); } - //----------------------------------------------------------------------- - GLSLLinkProgramManager::GLSLLinkProgramManager(void) : mActiveVertexGpuProgram(NULL), - mActiveGeometryGpuProgram(NULL), mActiveFragmentGpuProgram(NULL), mActiveLinkProgram(NULL) - { - // Fill in the relationship between type names and enums - mTypeEnumMap.insert(StringToEnumMap::value_type("float", GL_FLOAT)); - mTypeEnumMap.insert(StringToEnumMap::value_type("vec2", GL_FLOAT_VEC2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("vec3", GL_FLOAT_VEC3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("vec4", GL_FLOAT_VEC4)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler1D", GL_SAMPLER_1D)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2D", GL_SAMPLER_2D)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler3D", GL_SAMPLER_3D)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DArray", GL_SAMPLER_2D_ARRAY_EXT)); - mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCube", GL_SAMPLER_CUBE)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler1DShadow", GL_SAMPLER_1D_SHADOW)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DShadow", GL_SAMPLER_2D_SHADOW)); - mTypeEnumMap.insert(StringToEnumMap::value_type("int", GL_INT)); - mTypeEnumMap.insert(StringToEnumMap::value_type("ivec2", GL_INT_VEC2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("ivec3", GL_INT_VEC3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("ivec4", GL_INT_VEC4)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat2", GL_FLOAT_MAT2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat3", GL_FLOAT_MAT3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat4", GL_FLOAT_MAT4)); - // GL 2.1 - mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x2", GL_FLOAT_MAT2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x3", GL_FLOAT_MAT3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x4", GL_FLOAT_MAT4)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x3", GL_FLOAT_MAT2x3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x2", GL_FLOAT_MAT3x2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x4", GL_FLOAT_MAT3x4)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x3", GL_FLOAT_MAT4x3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x4", GL_FLOAT_MAT2x4)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x2", GL_FLOAT_MAT4x2)); - - } - - //----------------------------------------------------------------------- - GLSLLinkProgramManager::~GLSLLinkProgramManager(void) - { - // iterate through map container and delete link programs - for (LinkProgramIterator currentProgram = mLinkPrograms.begin(); - currentProgram != mLinkPrograms.end(); ++currentProgram) - { - delete currentProgram->second; - } - - } - - //----------------------------------------------------------------------- - GLSLLinkProgram* GLSLLinkProgramManager::getActiveLinkProgram(void) - { - // if there is an active link program then return it - if (mActiveLinkProgram) - return mActiveLinkProgram; - - // no active link program so find one or make a new one - // is there an active key? - uint64 activeKey = 0; - - if (mActiveVertexGpuProgram) - { - activeKey = static_cast(mActiveVertexGpuProgram->getProgramID()) << 32; - } - if (mActiveGeometryGpuProgram) - { - activeKey += static_cast(mActiveGeometryGpuProgram->getProgramID()) << 16; - } - if (mActiveFragmentGpuProgram) - { - activeKey += static_cast(mActiveFragmentGpuProgram->getProgramID()); - } - - // only return a link program object if a vertex, geometry or fragment program exist - if (activeKey > 0) - { - // find the key in the hash map - LinkProgramIterator programFound = mLinkPrograms.find(activeKey); - // program object not found for key so need to create it - if (programFound == mLinkPrograms.end()) - { - mActiveLinkProgram = new GLSLLinkProgram(mActiveVertexGpuProgram, mActiveGeometryGpuProgram,mActiveFragmentGpuProgram); - mLinkPrograms[activeKey] = mActiveLinkProgram; - } - else - { - // found a link program in map container so make it active - mActiveLinkProgram = programFound->second; - } - - } - // make the program object active - if (mActiveLinkProgram) mActiveLinkProgram->activate(); - - return mActiveLinkProgram; - - } - - //----------------------------------------------------------------------- - void GLSLLinkProgramManager::setActiveFragmentShader(GLSLGpuProgram* fragmentGpuProgram) - { - if (fragmentGpuProgram != mActiveFragmentGpuProgram) - { - mActiveFragmentGpuProgram = fragmentGpuProgram; - // ActiveLinkProgram is no longer valid - mActiveLinkProgram = NULL; - // change back to fixed pipeline - glUseProgramObjectARB(0); - } - } - - //----------------------------------------------------------------------- - void GLSLLinkProgramManager::setActiveVertexShader(GLSLGpuProgram* vertexGpuProgram) - { - if (vertexGpuProgram != mActiveVertexGpuProgram) - { - mActiveVertexGpuProgram = vertexGpuProgram; - // ActiveLinkProgram is no longer valid - mActiveLinkProgram = NULL; - // change back to fixed pipeline - glUseProgramObjectARB(0); - } - } - //----------------------------------------------------------------------- - void GLSLLinkProgramManager::setActiveGeometryShader(GLSLGpuProgram* geometryGpuProgram) - { - if (geometryGpuProgram != mActiveGeometryGpuProgram) - { - mActiveGeometryGpuProgram = geometryGpuProgram; - // ActiveLinkProgram is no longer valid - mActiveLinkProgram = NULL; - // change back to fixed pipeline - glUseProgramObjectARB(0); - } - } - //--------------------------------------------------------------------- - void GLSLLinkProgramManager::completeDefInfo(GLenum gltype, - GpuConstantDefinition& defToUpdate) - { - // decode uniform size and type - // Note GLSL never packs rows into float4's(from an API perspective anyway) - // therefore all values are tight in the buffer - switch (gltype) - { - case GL_FLOAT: - defToUpdate.constType = GCT_FLOAT1; - break; - case GL_FLOAT_VEC2: - defToUpdate.constType = GCT_FLOAT2; - break; - - case GL_FLOAT_VEC3: - defToUpdate.constType = GCT_FLOAT3; - break; - - case GL_FLOAT_VEC4: - defToUpdate.constType = GCT_FLOAT4; - break; - case GL_SAMPLER_1D: - // need to record samplers for GLSL - defToUpdate.constType = GCT_SAMPLER1D; - break; - case GL_SAMPLER_2D: - case GL_SAMPLER_2D_RECT_ARB: - defToUpdate.constType = GCT_SAMPLER2D; - break; + //----------------------------------------------------------------------- + GLSLLinkProgramManager::GLSLLinkProgramManager(void) : mActiveVertexGpuProgram(NULL), + mActiveGeometryGpuProgram(NULL), mActiveFragmentGpuProgram(NULL), mActiveLinkProgram(NULL) + { + // Fill in the relationship between type names and enums + mTypeEnumMap.insert(StringToEnumMap::value_type("float", GL_FLOAT)); + mTypeEnumMap.insert(StringToEnumMap::value_type("vec2", GL_FLOAT_VEC2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("vec3", GL_FLOAT_VEC3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("vec4", GL_FLOAT_VEC4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler1D", GL_SAMPLER_1D)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2D", GL_SAMPLER_2D)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler3D", GL_SAMPLER_3D)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DArray", GL_SAMPLER_2D_ARRAY_EXT)); + mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCube", GL_SAMPLER_CUBE)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler1DShadow", GL_SAMPLER_1D_SHADOW)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DShadow", GL_SAMPLER_2D_SHADOW)); + mTypeEnumMap.insert(StringToEnumMap::value_type("int", GL_INT)); + mTypeEnumMap.insert(StringToEnumMap::value_type("ivec2", GL_INT_VEC2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("ivec3", GL_INT_VEC3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("ivec4", GL_INT_VEC4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat2", GL_FLOAT_MAT2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat3", GL_FLOAT_MAT3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat4", GL_FLOAT_MAT4)); + // GL 2.1 + mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x2", GL_FLOAT_MAT2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x3", GL_FLOAT_MAT3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x4", GL_FLOAT_MAT4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x3", GL_FLOAT_MAT2x3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x2", GL_FLOAT_MAT3x2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x4", GL_FLOAT_MAT3x4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x3", GL_FLOAT_MAT4x3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x4", GL_FLOAT_MAT2x4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x2", GL_FLOAT_MAT4x2)); + + } + + //----------------------------------------------------------------------- + GLSLLinkProgramManager::~GLSLLinkProgramManager(void) + { + // iterate through map container and delete link programs + for (LinkProgramIterator currentProgram = mLinkPrograms.begin(); + currentProgram != mLinkPrograms.end(); ++currentProgram) + { + delete currentProgram->second; + } + + } + + //----------------------------------------------------------------------- + GLSLLinkProgram* GLSLLinkProgramManager::getActiveLinkProgram(void) + { + // if there is an active link program then return it + if (mActiveLinkProgram) + return mActiveLinkProgram; + + // no active link program so find one or make a new one + // is there an active key? + uint64 activeKey = 0; + + if (mActiveVertexGpuProgram) + { + activeKey = static_cast(mActiveVertexGpuProgram->getProgramID()) << 32; + } + if (mActiveGeometryGpuProgram) + { + activeKey += static_cast(mActiveGeometryGpuProgram->getProgramID()) << 16; + } + if (mActiveFragmentGpuProgram) + { + activeKey += static_cast(mActiveFragmentGpuProgram->getProgramID()); + } + + // only return a link program object if a vertex, geometry or fragment program exist + if (activeKey > 0) + { + // find the key in the hash map + LinkProgramIterator programFound = mLinkPrograms.find(activeKey); + // program object not found for key so need to create it + if (programFound == mLinkPrograms.end()) + { + mActiveLinkProgram = new GLSLLinkProgram(mActiveVertexGpuProgram, mActiveGeometryGpuProgram,mActiveFragmentGpuProgram); + mLinkPrograms[activeKey] = mActiveLinkProgram; + } + else + { + // found a link program in map container so make it active + mActiveLinkProgram = programFound->second; + } + + } + // make the program object active + if (mActiveLinkProgram) mActiveLinkProgram->activate(); + + return mActiveLinkProgram; + + } + + //----------------------------------------------------------------------- + void GLSLLinkProgramManager::setActiveFragmentShader(GLSLGpuProgram* fragmentGpuProgram) + { + if (fragmentGpuProgram != mActiveFragmentGpuProgram) + { + mActiveFragmentGpuProgram = fragmentGpuProgram; + // ActiveLinkProgram is no longer valid + mActiveLinkProgram = NULL; + // change back to fixed pipeline + glUseProgramObjectARB(0); + } + } + + //----------------------------------------------------------------------- + void GLSLLinkProgramManager::setActiveVertexShader(GLSLGpuProgram* vertexGpuProgram) + { + if (vertexGpuProgram != mActiveVertexGpuProgram) + { + mActiveVertexGpuProgram = vertexGpuProgram; + // ActiveLinkProgram is no longer valid + mActiveLinkProgram = NULL; + // change back to fixed pipeline + glUseProgramObjectARB(0); + } + } + //----------------------------------------------------------------------- + void GLSLLinkProgramManager::setActiveGeometryShader(GLSLGpuProgram* geometryGpuProgram) + { + if (geometryGpuProgram != mActiveGeometryGpuProgram) + { + mActiveGeometryGpuProgram = geometryGpuProgram; + // ActiveLinkProgram is no longer valid + mActiveLinkProgram = NULL; + // change back to fixed pipeline + glUseProgramObjectARB(0); + } + } + //--------------------------------------------------------------------- + void GLSLLinkProgramManager::completeDefInfo(GLenum gltype, + GpuConstantDefinition& defToUpdate) + { + // decode uniform size and type + // Note GLSL never packs rows into float4's(from an API perspective anyway) + // therefore all values are tight in the buffer + switch (gltype) + { + case GL_FLOAT: + defToUpdate.constType = GCT_FLOAT1; + break; + case GL_FLOAT_VEC2: + defToUpdate.constType = GCT_FLOAT2; + break; + + case GL_FLOAT_VEC3: + defToUpdate.constType = GCT_FLOAT3; + break; + + case GL_FLOAT_VEC4: + defToUpdate.constType = GCT_FLOAT4; + break; + case GL_SAMPLER_1D: + // need to record samplers for GLSL + defToUpdate.constType = GCT_SAMPLER1D; + break; + case GL_SAMPLER_2D: + case GL_SAMPLER_2D_RECT_ARB: + defToUpdate.constType = GCT_SAMPLER2D; + break; case GL_SAMPLER_2D_ARRAY_EXT: defToUpdate.constType = GCT_SAMPLER2DARRAY; break; - case GL_SAMPLER_3D: - defToUpdate.constType = GCT_SAMPLER3D; - break; - case GL_SAMPLER_CUBE: - defToUpdate.constType = GCT_SAMPLERCUBE; - break; - case GL_SAMPLER_1D_SHADOW: - defToUpdate.constType = GCT_SAMPLER1DSHADOW; - break; - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_2D_RECT_SHADOW_ARB: - defToUpdate.constType = GCT_SAMPLER2DSHADOW; - break; - case GL_INT: - defToUpdate.constType = GCT_INT1; - break; - case GL_INT_VEC2: - defToUpdate.constType = GCT_INT2; - break; - case GL_INT_VEC3: - defToUpdate.constType = GCT_INT3; - break; - case GL_INT_VEC4: - defToUpdate.constType = GCT_INT4; - break; - case GL_FLOAT_MAT2: - defToUpdate.constType = GCT_MATRIX_2X2; - break; - case GL_FLOAT_MAT3: - defToUpdate.constType = GCT_MATRIX_3X3; - break; - case GL_FLOAT_MAT4: - defToUpdate.constType = GCT_MATRIX_4X4; - break; - case GL_FLOAT_MAT2x3: - defToUpdate.constType = GCT_MATRIX_2X3; - break; - case GL_FLOAT_MAT3x2: - defToUpdate.constType = GCT_MATRIX_3X2; - break; - case GL_FLOAT_MAT2x4: - defToUpdate.constType = GCT_MATRIX_2X4; - break; - case GL_FLOAT_MAT4x2: - defToUpdate.constType = GCT_MATRIX_4X2; - break; - case GL_FLOAT_MAT3x4: - defToUpdate.constType = GCT_MATRIX_3X4; - break; - case GL_FLOAT_MAT4x3: - defToUpdate.constType = GCT_MATRIX_4X3; - break; - default: - defToUpdate.constType = GCT_UNKNOWN; - break; - - } - - // GL doesn't pad - defToUpdate.elementSize = GpuConstantDefinition::getElementSize(defToUpdate.constType, false); - - - } - //--------------------------------------------------------------------- - bool GLSLLinkProgramManager::completeParamSource( - const String& paramName, - const GpuConstantDefinitionMap* vertexConstantDefs, - const GpuConstantDefinitionMap* geometryConstantDefs, - const GpuConstantDefinitionMap* fragmentConstantDefs, - GLUniformReference& refToUpdate) - { - if (vertexConstantDefs) - { - GpuConstantDefinitionMap::const_iterator parami = - vertexConstantDefs->find(paramName); - if (parami != vertexConstantDefs->end()) - { - refToUpdate.mSourceProgType = GPT_VERTEX_PROGRAM; - refToUpdate.mConstantDef = &(parami->second); - return true; - } - - } - if (geometryConstantDefs) - { - GpuConstantDefinitionMap::const_iterator parami = - geometryConstantDefs->find(paramName); - if (parami != geometryConstantDefs->end()) - { - refToUpdate.mSourceProgType = GPT_GEOMETRY_PROGRAM; - refToUpdate.mConstantDef = &(parami->second); - return true; - } - - } - if (fragmentConstantDefs) - { - GpuConstantDefinitionMap::const_iterator parami = - fragmentConstantDefs->find(paramName); - if (parami != fragmentConstantDefs->end()) - { - refToUpdate.mSourceProgType = GPT_FRAGMENT_PROGRAM; - refToUpdate.mConstantDef = &(parami->second); - return true; - } - } - return false; - - - } - //--------------------------------------------------------------------- - void GLSLLinkProgramManager::extractUniforms(GLhandleARB programObject, - const GpuConstantDefinitionMap* vertexConstantDefs, - const GpuConstantDefinitionMap* geometryConstantDefs, - const GpuConstantDefinitionMap* fragmentConstantDefs, - GLUniformReferenceList& list) - { - // scan through the active uniforms and add them to the reference list - GLint uniformCount = 0; - - #define BUFFERSIZE 200 - char uniformName[BUFFERSIZE] = ""; - //GLint location; - GLUniformReference newGLUniformReference; - - // get the number of active uniforms - glGetObjectParameterivARB(programObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, - &uniformCount); - - // Loop over each of the active uniforms, and add them to the reference container - // only do this for user defined uniforms, ignore built in gl state uniforms - for (int index = 0; index < uniformCount; index++) - { - GLint arraySize = 0; - GLenum glType; - glGetActiveUniformARB(programObject, index, BUFFERSIZE, NULL, - &arraySize, &glType, uniformName); - // don't add built in uniforms - newGLUniformReference.mLocation = glGetUniformLocationARB(programObject, uniformName); - if (newGLUniformReference.mLocation >= 0) - { - // user defined uniform found, add it to the reference list - String paramName = String( uniformName ); - - // Current ATI drivers (Catalyst 7.2 and earlier) and older NVidia drivers will include all array elements as uniforms but we only want the root array name and location - // Also note that ATI Catalyst 6.8 to 7.2 there is a bug with glUniform that does not allow you to update a uniform array past the first uniform array element - // ie you can't start updating an array starting at element 1, must always be element 0. - - // if the uniform name has a "[" in it then its an array element uniform. - String::size_type arrayStart = paramName.find("["); - if (arrayStart != String::npos) - { - // if not the first array element then skip it and continue to the next uniform - if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0) continue; - paramName = paramName.substr(0, arrayStart); - } - - // find out which params object this comes from - bool foundSource = completeParamSource(paramName, - vertexConstantDefs, geometryConstantDefs, fragmentConstantDefs, newGLUniformReference); - - // only add this parameter if we found the source - if (foundSource) - { - assert(size_t (arraySize) == newGLUniformReference.mConstantDef->arraySize - && "GL doesn't agree with our array size!"); - list.push_back(newGLUniformReference); - } - - // Don't bother adding individual array params, they will be - // picked up in the 'parent' parameter can copied all at once - // anyway, individual indexes are only needed for lookup from - // user params - } // end if - } // end for - - } - //--------------------------------------------------------------------- - void GLSLLinkProgramManager::extractConstantDefs(const String& src, - GpuNamedConstants& defs, const String& filename) - { - // Parse the output string and collect all uniforms - // NOTE this relies on the source already having been preprocessed - // which is done in GLSLProgram::loadFromSource - String line; - String::size_type currPos = src.find("uniform"); - while (currPos != String::npos) - { - GpuConstantDefinition def; - String paramName; - - // Now check for using the word 'uniform' in a larger string & ignore - bool inLargerString = false; - if (currPos != 0) - { - char prev = src.at(currPos - 1); - if (prev != ' ' && prev != '\t' && prev != '\r' && prev != '\n' - && prev != ';') - inLargerString = true; - } - if (!inLargerString && currPos + 7 < src.size()) - { - char next = src.at(currPos + 7); - if (next != ' ' && next != '\t' && next != '\r' && next != '\n') - inLargerString = true; - } - - // skip 'uniform' - currPos += 7; - - if (!inLargerString) - { - // find terminating semicolon - String::size_type endPos = src.find(";", currPos); - if (endPos == String::npos) - { - // problem, missing semicolon, abort - break; - } - line = src.substr(currPos, endPos - currPos); - - // Remove spaces before opening square braces, otherwise - // the following split() can split the line at inappropriate - // places (e.g. "vec3 something [3]" won't work). - for (String::size_type sqp = line.find (" ["); sqp != String::npos; - sqp = line.find (" [")) - line.erase (sqp, 1); - // Split into tokens - StringVector parts = StringUtil::split(line, ", \t\r\n"); - - for (StringVector::iterator i = parts.begin(); i != parts.end(); ++i) - { - // Is this a type? - StringToEnumMap::iterator typei = mTypeEnumMap.find(*i); - if (typei != mTypeEnumMap.end()) - { - completeDefInfo(typei->second, def); - } - else - { - // if this is not a type, and not empty, it should be a name - StringUtil::trim(*i); - if (i->empty()) continue; - - String::size_type arrayStart = i->find("[", 0); - if (arrayStart != String::npos) - { - // potential name (if butted up to array) - String name = i->substr(0, arrayStart); - StringUtil::trim(name); - if (!name.empty()) - paramName = name; - - String::size_type arrayEnd = i->find("]", arrayStart); - String arrayDimTerm = i->substr(arrayStart + 1, arrayEnd - arrayStart - 1); - StringUtil::trim(arrayDimTerm); - // the array term might be a simple number or it might be - // an expression (e.g. 24*3) or refer to a constant expression - // we'd have to evaluate the expression which could get nasty - // TODO - def.arraySize = StringConverter::parseInt(arrayDimTerm); - - } - else - { - paramName = *i; - def.arraySize = 1; - } - - // Name should be after the type, so complete def and add - // We do this now so that comma-separated params will do - // this part once for each name mentioned - if (def.constType == GCT_UNKNOWN) - { - LogManager::getSingleton().logMessage( - "Problem parsing the following GLSL Uniform: '" - + line + "' in file " + filename, LML_CRITICAL); - // next uniform - break; - } - - // Complete def and add - // increment physical buffer location - def.logicalIndex = 0; // not valid in GLSL - if (def.isFloat()) - { - def.physicalIndex = defs.floatBufferSize; - defs.floatBufferSize += def.arraySize * def.elementSize; - } - else - { - def.physicalIndex = defs.intBufferSize; - defs.intBufferSize += def.arraySize * def.elementSize; - } - defs.map.insert(GpuConstantDefinitionMap::value_type(paramName, def)); - - // Generate array accessors - defs.generateConstantDefinitionArrayEntries(paramName, def); - } - - } - - } // not commented or a larger symbol - - // Find next one - currPos = src.find("uniform", currPos); - - } - - } + case GL_SAMPLER_3D: + defToUpdate.constType = GCT_SAMPLER3D; + break; + case GL_SAMPLER_CUBE: + defToUpdate.constType = GCT_SAMPLERCUBE; + break; + case GL_SAMPLER_1D_SHADOW: + defToUpdate.constType = GCT_SAMPLER1DSHADOW; + break; + case GL_SAMPLER_2D_SHADOW: + case GL_SAMPLER_2D_RECT_SHADOW_ARB: + defToUpdate.constType = GCT_SAMPLER2DSHADOW; + break; + case GL_INT: + defToUpdate.constType = GCT_INT1; + break; + case GL_INT_VEC2: + defToUpdate.constType = GCT_INT2; + break; + case GL_INT_VEC3: + defToUpdate.constType = GCT_INT3; + break; + case GL_INT_VEC4: + defToUpdate.constType = GCT_INT4; + break; + case GL_FLOAT_MAT2: + defToUpdate.constType = GCT_MATRIX_2X2; + break; + case GL_FLOAT_MAT3: + defToUpdate.constType = GCT_MATRIX_3X3; + break; + case GL_FLOAT_MAT4: + defToUpdate.constType = GCT_MATRIX_4X4; + break; + case GL_FLOAT_MAT2x3: + defToUpdate.constType = GCT_MATRIX_2X3; + break; + case GL_FLOAT_MAT3x2: + defToUpdate.constType = GCT_MATRIX_3X2; + break; + case GL_FLOAT_MAT2x4: + defToUpdate.constType = GCT_MATRIX_2X4; + break; + case GL_FLOAT_MAT4x2: + defToUpdate.constType = GCT_MATRIX_4X2; + break; + case GL_FLOAT_MAT3x4: + defToUpdate.constType = GCT_MATRIX_3X4; + break; + case GL_FLOAT_MAT4x3: + defToUpdate.constType = GCT_MATRIX_4X3; + break; + default: + defToUpdate.constType = GCT_UNKNOWN; + break; + + } + + // GL doesn't pad + defToUpdate.elementSize = GpuConstantDefinition::getElementSize(defToUpdate.constType, false); + + + } + //--------------------------------------------------------------------- + bool GLSLLinkProgramManager::completeParamSource( + const String& paramName, + const GpuConstantDefinitionMap* vertexConstantDefs, + const GpuConstantDefinitionMap* geometryConstantDefs, + const GpuConstantDefinitionMap* fragmentConstantDefs, + GLUniformReference& refToUpdate) + { + if (vertexConstantDefs) + { + GpuConstantDefinitionMap::const_iterator parami = + vertexConstantDefs->find(paramName); + if (parami != vertexConstantDefs->end()) + { + refToUpdate.mSourceProgType = GPT_VERTEX_PROGRAM; + refToUpdate.mConstantDef = &(parami->second); + return true; + } + + } + if (geometryConstantDefs) + { + GpuConstantDefinitionMap::const_iterator parami = + geometryConstantDefs->find(paramName); + if (parami != geometryConstantDefs->end()) + { + refToUpdate.mSourceProgType = GPT_GEOMETRY_PROGRAM; + refToUpdate.mConstantDef = &(parami->second); + return true; + } + + } + if (fragmentConstantDefs) + { + GpuConstantDefinitionMap::const_iterator parami = + fragmentConstantDefs->find(paramName); + if (parami != fragmentConstantDefs->end()) + { + refToUpdate.mSourceProgType = GPT_FRAGMENT_PROGRAM; + refToUpdate.mConstantDef = &(parami->second); + return true; + } + } + return false; + + + } + //--------------------------------------------------------------------- + void GLSLLinkProgramManager::extractUniforms(GLhandleARB programObject, + const GpuConstantDefinitionMap* vertexConstantDefs, + const GpuConstantDefinitionMap* geometryConstantDefs, + const GpuConstantDefinitionMap* fragmentConstantDefs, + GLUniformReferenceList& list) + { + // scan through the active uniforms and add them to the reference list + GLint uniformCount = 0; + + #define BUFFERSIZE 200 + char uniformName[BUFFERSIZE] = ""; + //GLint location; + GLUniformReference newGLUniformReference; + + // get the number of active uniforms + glGetObjectParameterivARB(programObject, GL_OBJECT_ACTIVE_UNIFORMS_ARB, + &uniformCount); + + // Loop over each of the active uniforms, and add them to the reference container + // only do this for user defined uniforms, ignore built in gl state uniforms + for (int index = 0; index < uniformCount; index++) + { + GLint arraySize = 0; + GLenum glType; + glGetActiveUniformARB(programObject, index, BUFFERSIZE, NULL, + &arraySize, &glType, uniformName); + // don't add built in uniforms + newGLUniformReference.mLocation = glGetUniformLocationARB(programObject, uniformName); + if (newGLUniformReference.mLocation >= 0) + { + // user defined uniform found, add it to the reference list + String paramName = String( uniformName ); + + // Current ATI drivers (Catalyst 7.2 and earlier) and older NVidia drivers will include all array elements as uniforms but we only want the root array name and location + // Also note that ATI Catalyst 6.8 to 7.2 there is a bug with glUniform that does not allow you to update a uniform array past the first uniform array element + // ie you can't start updating an array starting at element 1, must always be element 0. + + // if the uniform name has a "[" in it then its an array element uniform. + String::size_type arrayStart = paramName.find("["); + if (arrayStart != String::npos) + { + // if not the first array element then skip it and continue to the next uniform + if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0) continue; + paramName = paramName.substr(0, arrayStart); + } + + // find out which params object this comes from + bool foundSource = completeParamSource(paramName, + vertexConstantDefs, geometryConstantDefs, fragmentConstantDefs, newGLUniformReference); + + // only add this parameter if we found the source + if (foundSource) + { + assert(size_t (arraySize) == newGLUniformReference.mConstantDef->arraySize + && "GL doesn't agree with our array size!"); + list.push_back(newGLUniformReference); + } + + // Don't bother adding individual array params, they will be + // picked up in the 'parent' parameter can copied all at once + // anyway, individual indexes are only needed for lookup from + // user params + } // end if + } // end for + + } + //--------------------------------------------------------------------- + void GLSLLinkProgramManager::extractConstantDefs(const String& src, + GpuNamedConstants& defs, const String& filename) + { + // Parse the output string and collect all uniforms + // NOTE this relies on the source already having been preprocessed + // which is done in GLSLProgram::loadFromSource + String line; + String::size_type currPos = src.find("uniform"); + while (currPos != String::npos) + { + GpuConstantDefinition def; + String paramName; + + // Now check for using the word 'uniform' in a larger string & ignore + bool inLargerString = false; + if (currPos != 0) + { + char prev = src.at(currPos - 1); + if (prev != ' ' && prev != '\t' && prev != '\r' && prev != '\n' + && prev != ';') + inLargerString = true; + } + if (!inLargerString && currPos + 7 < src.size()) + { + char next = src.at(currPos + 7); + if (next != ' ' && next != '\t' && next != '\r' && next != '\n') + inLargerString = true; + } + + // skip 'uniform' + currPos += 7; + + if (!inLargerString) + { + // find terminating semicolon + String::size_type endPos = src.find(";", currPos); + if (endPos == String::npos) + { + // problem, missing semicolon, abort + break; + } + line = src.substr(currPos, endPos - currPos); + + // Remove spaces before opening square braces, otherwise + // the following split() can split the line at inappropriate + // places (e.g. "vec3 something [3]" won't work). + for (String::size_type sqp = line.find (" ["); sqp != String::npos; + sqp = line.find (" [")) + line.erase (sqp, 1); + // Split into tokens + StringVector parts = StringUtil::split(line, ", \t\r\n"); + + for (StringVector::iterator i = parts.begin(); i != parts.end(); ++i) + { + // Is this a type? + StringToEnumMap::iterator typei = mTypeEnumMap.find(*i); + if (typei != mTypeEnumMap.end()) + { + completeDefInfo(typei->second, def); + } + else + { + // if this is not a type, and not empty, it should be a name + StringUtil::trim(*i); + if (i->empty()) continue; + + String::size_type arrayStart = i->find("[", 0); + if (arrayStart != String::npos) + { + // potential name (if butted up to array) + String name = i->substr(0, arrayStart); + StringUtil::trim(name); + if (!name.empty()) + paramName = name; + + String::size_type arrayEnd = i->find("]", arrayStart); + String arrayDimTerm = i->substr(arrayStart + 1, arrayEnd - arrayStart - 1); + StringUtil::trim(arrayDimTerm); + // the array term might be a simple number or it might be + // an expression (e.g. 24*3) or refer to a constant expression + // we'd have to evaluate the expression which could get nasty + // TODO + def.arraySize = StringConverter::parseInt(arrayDimTerm); + + } + else + { + paramName = *i; + def.arraySize = 1; + } + + // Name should be after the type, so complete def and add + // We do this now so that comma-separated params will do + // this part once for each name mentioned + if (def.constType == GCT_UNKNOWN) + { + LogManager::getSingleton().logMessage( + "Problem parsing the following GLSL Uniform: '" + + line + "' in file " + filename, LML_CRITICAL); + // next uniform + break; + } + + // Complete def and add + // increment physical buffer location + def.logicalIndex = 0; // not valid in GLSL + if (def.isFloat()) + { + def.physicalIndex = defs.floatBufferSize; + defs.floatBufferSize += def.arraySize * def.elementSize; + } + else + { + def.physicalIndex = defs.intBufferSize; + defs.intBufferSize += def.arraySize * def.elementSize; + } + defs.map.insert(GpuConstantDefinitionMap::value_type(paramName, def)); + + // Generate array accessors + defs.generateConstantDefinitionArrayEntries(paramName, def); + } + + } + + } // not commented or a larger symbol + + // Find next one + currPos = src.find("uniform", currPos); + + } + + } } } diff --git a/RenderSystems/GL/src/GLSL/src/OgreGLSLPreprocessor.cpp b/RenderSystems/GL/src/GLSL/src/OgreGLSLPreprocessor.cpp index 0701020285b..0001a25a601 100644 --- a/RenderSystems/GL/src/GLSL/src/OgreGLSLPreprocessor.cpp +++ b/RenderSystems/GL/src/GLSL/src/OgreGLSLPreprocessor.cpp @@ -40,7 +40,7 @@ namespace Ogre { #define MAX_MACRO_ARGS 16 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 && !defined( __MINGW32__ ) - #define snprintf _snprintf + #define snprintf _snprintf #endif //---------------------------------------------------------------------------// @@ -1111,7 +1111,7 @@ CPreprocessor::Token CPreprocessor::HandleDirective (Token &iToken, int iLine) #define IS_DIRECTIVE(s) \ (dirlen == strlen(s) && (strncmp (directive, s, strlen(s)) == 0)) - bool outputEnabled = ((EnableOutput & (EnableOutput + 1)) == 0); + bool outputEnabled = ((EnableOutput & (EnableOutput + 1)) == 0); bool rc; if (IS_DIRECTIVE ("define") && outputEnabled) diff --git a/RenderSystems/GL/src/GLSL/src/OgreGLSLProgram.cpp b/RenderSystems/GL/src/GLSL/src/OgreGLSLProgram.cpp index 20342e85a0f..b6ce141d08a 100644 --- a/RenderSystems/GL/src/GLSL/src/OgreGLSLProgram.cpp +++ b/RenderSystems/GL/src/GLSL/src/OgreGLSLProgram.cpp @@ -44,12 +44,12 @@ namespace Ogre { namespace GLSL { //----------------------------------------------------------------------- - GLSLProgram::CmdPreprocessorDefines GLSLProgram::msCmdPreprocessorDefines; + GLSLProgram::CmdPreprocessorDefines GLSLProgram::msCmdPreprocessorDefines; GLSLProgram::CmdAttach GLSLProgram::msCmdAttach; GLSLProgram::CmdColumnMajorMatrices GLSLProgram::msCmdColumnMajorMatrices; - GLSLProgram::CmdInputOperationType GLSLProgram::msInputOperationTypeCmd; - GLSLProgram::CmdOutputOperationType GLSLProgram::msOutputOperationTypeCmd; - GLSLProgram::CmdMaxOutputVertices GLSLProgram::msMaxOutputVerticesCmd; + GLSLProgram::CmdInputOperationType GLSLProgram::msInputOperationTypeCmd; + GLSLProgram::CmdOutputOperationType GLSLProgram::msOutputOperationTypeCmd; + GLSLProgram::CmdMaxOutputVertices GLSLProgram::msMaxOutputVerticesCmd; //----------------------------------------------------------------------- //--------------------------------------------------------------------------- @@ -67,357 +67,357 @@ namespace Ogre { } } //----------------------------------------------------------------------- - void GLSLProgram::loadFromSource(void) - { - // Preprocess the GLSL shader in order to get a clean source - CPreprocessor cpp; - - // Pass all user-defined macros to preprocessor - if (!mPreprocessorDefines.empty ()) - { - String::size_type pos = 0; - while (pos != String::npos) - { - // Find delims - String::size_type endPos = mPreprocessorDefines.find_first_of(";,=", pos); - if (endPos != String::npos) - { - String::size_type macro_name_start = pos; - size_t macro_name_len = endPos - pos; - pos = endPos; - - // Check definition part - if (mPreprocessorDefines[pos] == '=') - { - // set up a definition, skip delim - ++pos; - String::size_type macro_val_start = pos; - size_t macro_val_len; - - endPos = mPreprocessorDefines.find_first_of(";,", pos); - if (endPos == String::npos) - { - macro_val_len = mPreprocessorDefines.size () - pos; - pos = endPos; - } - else - { - macro_val_len = endPos - pos; - pos = endPos+1; - } - cpp.Define ( - mPreprocessorDefines.c_str () + macro_name_start, macro_name_len, - mPreprocessorDefines.c_str () + macro_val_start, macro_val_len); - } - else - { - // No definition part, define as "1" - ++pos; - cpp.Define ( - mPreprocessorDefines.c_str () + macro_name_start, macro_name_len, 1); - } - } - else - pos = endPos; - } - } - - size_t out_size = 0; - const char *src = mSource.c_str (); - size_t src_len = mSource.size (); - char *out = cpp.Parse (src, src_len, out_size); - if (!out || !out_size) - // Failed to preprocess, break out - OGRE_EXCEPT (Exception::ERR_RENDERINGAPI_ERROR, - "Failed to preprocess shader " + mName, - __FUNCTION__); - - mSource = String (out, out_size); - if (out < src || out > src + src_len) - free (out); - } + void GLSLProgram::loadFromSource(void) + { + // Preprocess the GLSL shader in order to get a clean source + CPreprocessor cpp; + + // Pass all user-defined macros to preprocessor + if (!mPreprocessorDefines.empty ()) + { + String::size_type pos = 0; + while (pos != String::npos) + { + // Find delims + String::size_type endPos = mPreprocessorDefines.find_first_of(";,=", pos); + if (endPos != String::npos) + { + String::size_type macro_name_start = pos; + size_t macro_name_len = endPos - pos; + pos = endPos; + + // Check definition part + if (mPreprocessorDefines[pos] == '=') + { + // set up a definition, skip delim + ++pos; + String::size_type macro_val_start = pos; + size_t macro_val_len; + + endPos = mPreprocessorDefines.find_first_of(";,", pos); + if (endPos == String::npos) + { + macro_val_len = mPreprocessorDefines.size () - pos; + pos = endPos; + } + else + { + macro_val_len = endPos - pos; + pos = endPos+1; + } + cpp.Define ( + mPreprocessorDefines.c_str () + macro_name_start, macro_name_len, + mPreprocessorDefines.c_str () + macro_val_start, macro_val_len); + } + else + { + // No definition part, define as "1" + ++pos; + cpp.Define ( + mPreprocessorDefines.c_str () + macro_name_start, macro_name_len, 1); + } + } + else + pos = endPos; + } + } + + size_t out_size = 0; + const char *src = mSource.c_str (); + size_t src_len = mSource.size (); + char *out = cpp.Parse (src, src_len, out_size); + if (!out || !out_size) + // Failed to preprocess, break out + OGRE_EXCEPT (Exception::ERR_RENDERINGAPI_ERROR, + "Failed to preprocess shader " + mName, + __FUNCTION__); + + mSource = String (out, out_size); + if (out < src || out > src + src_len) + free (out); + } //--------------------------------------------------------------------------- - bool GLSLProgram::compile(const bool checkErrors) - { - if (mCompiled == 1) - { - return true; - } - - // only create a shader object if glsl is supported - if (isSupported()) - { - // create shader object - GLenum shaderType = 0x0000; - switch (mType) - { - case GPT_VERTEX_PROGRAM: - shaderType = GL_VERTEX_SHADER_ARB; - break; - case GPT_FRAGMENT_PROGRAM: - shaderType = GL_FRAGMENT_SHADER_ARB; - break; - case GPT_GEOMETRY_PROGRAM: - shaderType = GL_GEOMETRY_SHADER_EXT; - break; + bool GLSLProgram::compile(const bool checkErrors) + { + if (mCompiled == 1) + { + return true; + } + + // only create a shader object if glsl is supported + if (isSupported()) + { + // create shader object + GLenum shaderType = 0x0000; + switch (mType) + { + case GPT_VERTEX_PROGRAM: + shaderType = GL_VERTEX_SHADER_ARB; + break; + case GPT_FRAGMENT_PROGRAM: + shaderType = GL_FRAGMENT_SHADER_ARB; + break; + case GPT_GEOMETRY_PROGRAM: + shaderType = GL_GEOMETRY_SHADER_EXT; + break; case GPT_COMPUTE_PROGRAM: case GPT_DOMAIN_PROGRAM: case GPT_HULL_PROGRAM: break; - } - mGLHandle = glCreateShaderObjectARB(shaderType); - } - - // Add preprocessor extras and main source - if (!mSource.empty()) - { - const char *source = mSource.c_str(); - glShaderSourceARB(mGLHandle, 1, &source, NULL); - } - - if (checkErrors) + } + mGLHandle = glCreateShaderObjectARB(shaderType); + } + + // Add preprocessor extras and main source + if (!mSource.empty()) + { + const char *source = mSource.c_str(); + glShaderSourceARB(mGLHandle, 1, &source, NULL); + } + + if (checkErrors) { logObjectInfo("GLSL compiling: " + mName, mGLHandle); } - glCompileShaderARB(mGLHandle); - // check for compile errors - glGetObjectParameterivARB(mGLHandle, GL_OBJECT_COMPILE_STATUS_ARB, &mCompiled); + glCompileShaderARB(mGLHandle); + // check for compile errors + glGetObjectParameterivARB(mGLHandle, GL_OBJECT_COMPILE_STATUS_ARB, &mCompiled); if(checkErrors) - { + { logObjectInfo(mCompiled ? "GLSL compiled: " : "GLSL compile log: " + mName, mGLHandle); - } + } - return (mCompiled == 1); - } + return (mCompiled == 1); + } - //----------------------------------------------------------------------- - void GLSLProgram::createLowLevelImpl(void) - { - mAssemblerProgram = GpuProgramPtr(OGRE_NEW GLSLGpuProgram( this )); + //----------------------------------------------------------------------- + void GLSLProgram::createLowLevelImpl(void) + { + mAssemblerProgram = GpuProgramPtr(OGRE_NEW GLSLGpuProgram( this )); // Shader params need to be forwarded to low level implementation mAssemblerProgram->setAdjacencyInfoRequired(isAdjacencyInfoRequired()); - } - //--------------------------------------------------------------------------- - void GLSLProgram::unloadImpl() - { - // We didn't create mAssemblerProgram through a manager, so override this - // implementation so that we don't try to remove it from one. Since getCreator() - // is used, it might target a different matching handle! - mAssemblerProgram.setNull(); - - unloadHighLevel(); - } - //----------------------------------------------------------------------- - void GLSLProgram::unloadHighLevelImpl(void) - { - if (isSupported()) - { - glDeleteObjectARB(mGLHandle); - mCompiled = 0; - mGLHandle = 0; - } - } - - //----------------------------------------------------------------------- - void GLSLProgram::populateParameterNames(GpuProgramParametersSharedPtr params) - { - getConstantDefinitions(); - params->_setNamedConstants(mConstantDefs); - // Don't set logical / physical maps here, as we can't access parameters by logical index in GLHL. - } - //----------------------------------------------------------------------- - void GLSLProgram::buildConstantDefinitions() const - { - // We need an accurate list of all the uniforms in the shader, but we - // can't get at them until we link all the shaders into a program object. - - - // Therefore instead, parse the source code manually and extract the uniforms - createParameterMappingStructures(true); - GLSLLinkProgramManager::getSingleton().extractConstantDefs( - mSource, *mConstantDefs.get(), mName); - - // Also parse any attached sources - for (GLSLProgramContainer::const_iterator i = mAttachedGLSLPrograms.begin(); - i != mAttachedGLSLPrograms.end(); ++i) - { - GLSLProgram* childShader = *i; - - GLSLLinkProgramManager::getSingleton().extractConstantDefs( - childShader->getSource(), *mConstantDefs.get(), childShader->getName()); - - } - } - - //----------------------------------------------------------------------- + } + //--------------------------------------------------------------------------- + void GLSLProgram::unloadImpl() + { + // We didn't create mAssemblerProgram through a manager, so override this + // implementation so that we don't try to remove it from one. Since getCreator() + // is used, it might target a different matching handle! + mAssemblerProgram.setNull(); + + unloadHighLevel(); + } + //----------------------------------------------------------------------- + void GLSLProgram::unloadHighLevelImpl(void) + { + if (isSupported()) + { + glDeleteObjectARB(mGLHandle); + mCompiled = 0; + mGLHandle = 0; + } + } + + //----------------------------------------------------------------------- + void GLSLProgram::populateParameterNames(GpuProgramParametersSharedPtr params) + { + getConstantDefinitions(); + params->_setNamedConstants(mConstantDefs); + // Don't set logical / physical maps here, as we can't access parameters by logical index in GLHL. + } + //----------------------------------------------------------------------- + void GLSLProgram::buildConstantDefinitions() const + { + // We need an accurate list of all the uniforms in the shader, but we + // can't get at them until we link all the shaders into a program object. + + + // Therefore instead, parse the source code manually and extract the uniforms + createParameterMappingStructures(true); + GLSLLinkProgramManager::getSingleton().extractConstantDefs( + mSource, *mConstantDefs.get(), mName); + + // Also parse any attached sources + for (GLSLProgramContainer::const_iterator i = mAttachedGLSLPrograms.begin(); + i != mAttachedGLSLPrograms.end(); ++i) + { + GLSLProgram* childShader = *i; + + GLSLLinkProgramManager::getSingleton().extractConstantDefs( + childShader->getSource(), *mConstantDefs.get(), childShader->getName()); + + } + } + + //----------------------------------------------------------------------- GLSLProgram::GLSLProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) : HighLevelGpuProgram(creator, name, handle, group, isManual, loader) , mGLHandle(0) , mCompiled(0) - , mInputOperationType(RenderOperation::OT_TRIANGLE_LIST) + , mInputOperationType(RenderOperation::OT_TRIANGLE_LIST) , mOutputOperationType(RenderOperation::OT_TRIANGLE_LIST) - , mMaxOutputVertices(3) + , mMaxOutputVertices(3) , mColumnMajorMatrices(true) { - // add parameter command "attach" to the material serializer dictionary + // add parameter command "attach" to the material serializer dictionary if (createParamDictionary("GLSLProgram")) { setupBaseParamDictionary(); ParamDictionary* dict = getParamDictionary(); - dict->addParameter(ParameterDef("preprocessor_defines", - "Preprocessor defines use to compile the program.", - PT_STRING),&msCmdPreprocessorDefines); + dict->addParameter(ParameterDef("preprocessor_defines", + "Preprocessor defines use to compile the program.", + PT_STRING),&msCmdPreprocessorDefines); dict->addParameter(ParameterDef("attach", "name of another GLSL program needed by this program", PT_STRING),&msCmdAttach); dict->addParameter(ParameterDef("column_major_matrices", "Whether matrix packing in column-major order.", PT_BOOL),&msCmdColumnMajorMatrices); - dict->addParameter( - ParameterDef("input_operation_type", - "The input operation type for this geometry program. \ - Can be 'point_list', 'line_list', 'line_strip', 'triangle_list', \ - 'triangle_strip' or 'triangle_fan'", PT_STRING), - &msInputOperationTypeCmd); - dict->addParameter( - ParameterDef("output_operation_type", - "The input operation type for this geometry program. \ - Can be 'point_list', 'line_strip' or 'triangle_strip'", - PT_STRING), - &msOutputOperationTypeCmd); - dict->addParameter( - ParameterDef("max_output_vertices", - "The maximum number of vertices a single run of this geometry program can output", - PT_INT),&msMaxOutputVerticesCmd); + dict->addParameter( + ParameterDef("input_operation_type", + "The input operation type for this geometry program. \ + Can be 'point_list', 'line_list', 'line_strip', 'triangle_list', \ + 'triangle_strip' or 'triangle_fan'", PT_STRING), + &msInputOperationTypeCmd); + dict->addParameter( + ParameterDef("output_operation_type", + "The input operation type for this geometry program. \ + Can be 'point_list', 'line_strip' or 'triangle_strip'", + PT_STRING), + &msOutputOperationTypeCmd); + dict->addParameter( + ParameterDef("max_output_vertices", + "The maximum number of vertices a single run of this geometry program can output", + PT_INT),&msMaxOutputVerticesCmd); } // Manually assign language now since we use it immediately mSyntaxCode = "glsl"; } - //--------------------------------------------------------------------- - bool GLSLProgram::getPassSurfaceAndLightStates(void) const - { - // scenemanager should pass on light & material state to the rendersystem - return true; - } - //--------------------------------------------------------------------- - bool GLSLProgram::getPassTransformStates(void) const - { - // scenemanager should pass on transform state to the rendersystem - return true; - } - //----------------------------------------------------------------------- + //--------------------------------------------------------------------- + bool GLSLProgram::getPassSurfaceAndLightStates(void) const + { + // scenemanager should pass on light & material state to the rendersystem + return true; + } + //--------------------------------------------------------------------- + bool GLSLProgram::getPassTransformStates(void) const + { + // scenemanager should pass on transform state to the rendersystem + return true; + } + //----------------------------------------------------------------------- String GLSLProgram::CmdAttach::doGet(const void *target) const { return (static_cast(target))->getAttachedShaderNames(); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void GLSLProgram::CmdAttach::doSet(void *target, const String& shaderNames) { - //get all the shader program names: there could be more than one - StringVector vecShaderNames = StringUtil::split(shaderNames, " \t", 0); - - size_t programNameCount = vecShaderNames.size(); - for ( size_t i = 0; i < programNameCount; ++i ) - { - static_cast(target)->attachChildShader(vecShaderNames[i]); - } + //get all the shader program names: there could be more than one + StringVector vecShaderNames = StringUtil::split(shaderNames, " \t", 0); + + size_t programNameCount = vecShaderNames.size(); + for ( size_t i = 0; i < programNameCount; ++i ) + { + static_cast(target)->attachChildShader(vecShaderNames[i]); + } + } + //----------------------------------------------------------------------- + String GLSLProgram::CmdPreprocessorDefines::doGet(const void *target) const + { + return static_cast(target)->getPreprocessorDefines(); } - //----------------------------------------------------------------------- - String GLSLProgram::CmdPreprocessorDefines::doGet(const void *target) const - { - return static_cast(target)->getPreprocessorDefines(); - } - void GLSLProgram::CmdPreprocessorDefines::doSet(void *target, const String& val) - { - static_cast(target)->setPreprocessorDefines(val); - } - - //----------------------------------------------------------------------- + void GLSLProgram::CmdPreprocessorDefines::doSet(void *target, const String& val) + { + static_cast(target)->setPreprocessorDefines(val); + } + + //----------------------------------------------------------------------- void GLSLProgram::attachChildShader(const String& name) - { - // is the name valid and already loaded? - // check with the high level program manager to see if it was loaded - HighLevelGpuProgramPtr hlProgram = HighLevelGpuProgramManager::getSingleton().getByName(name); - if (!hlProgram.isNull()) - { - if (hlProgram->getSyntaxCode() == "glsl") - { - // make sure attached program source gets loaded and compiled - // don't need a low level implementation for attached shader objects - // loadHighLevelImpl will only load the source and compile once - // so don't worry about calling it several times - GLSLProgram* childShader = static_cast(hlProgram.getPointer()); - // load the source and attach the child shader only if supported - if (isSupported()) - { - childShader->loadHighLevelImpl(); - // add to the container - mAttachedGLSLPrograms.push_back( childShader ); - mAttachedShaderNames += name + " "; - } - } - } - } - - //----------------------------------------------------------------------- - void GLSLProgram::attachToProgramObject( const GLhandleARB programObject ) - { - // attach child objects - GLSLProgramContainerIterator childprogramcurrent = mAttachedGLSLPrograms.begin(); - GLSLProgramContainerIterator childprogramend = mAttachedGLSLPrograms.end(); - - while (childprogramcurrent != childprogramend) - { - - GLSLProgram* childShader = *childprogramcurrent; - // bug in ATI GLSL linker : modules without main function must be recompiled each time - // they are linked to a different program object - // don't check for compile errors since there won't be any - // *** minor inconvenience until ATI fixes there driver - childShader->compile(false); - - childShader->attachToProgramObject( programObject ); - - ++childprogramcurrent; - } - glAttachObjectARB( programObject, mGLHandle ); + { + // is the name valid and already loaded? + // check with the high level program manager to see if it was loaded + HighLevelGpuProgramPtr hlProgram = HighLevelGpuProgramManager::getSingleton().getByName(name); + if (!hlProgram.isNull()) + { + if (hlProgram->getSyntaxCode() == "glsl") + { + // make sure attached program source gets loaded and compiled + // don't need a low level implementation for attached shader objects + // loadHighLevelImpl will only load the source and compile once + // so don't worry about calling it several times + GLSLProgram* childShader = static_cast(hlProgram.getPointer()); + // load the source and attach the child shader only if supported + if (isSupported()) + { + childShader->loadHighLevelImpl(); + // add to the container + mAttachedGLSLPrograms.push_back( childShader ); + mAttachedShaderNames += name + " "; + } + } + } + } + + //----------------------------------------------------------------------- + void GLSLProgram::attachToProgramObject( const GLhandleARB programObject ) + { + // attach child objects + GLSLProgramContainerIterator childprogramcurrent = mAttachedGLSLPrograms.begin(); + GLSLProgramContainerIterator childprogramend = mAttachedGLSLPrograms.end(); + + while (childprogramcurrent != childprogramend) + { + + GLSLProgram* childShader = *childprogramcurrent; + // bug in ATI GLSL linker : modules without main function must be recompiled each time + // they are linked to a different program object + // don't check for compile errors since there won't be any + // *** minor inconvenience until ATI fixes there driver + childShader->compile(false); + + childShader->attachToProgramObject( programObject ); + + ++childprogramcurrent; + } + glAttachObjectARB( programObject, mGLHandle ); GLenum glErr = glGetError(); if(glErr != GL_NO_ERROR) { - reportGLSLError( glErr, "GLSLProgram::attachToProgramObject", - "Error attaching " + mName + " shader object to GLSL Program Object", programObject ); + reportGLSLError( glErr, "GLSLProgram::attachToProgramObject", + "Error attaching " + mName + " shader object to GLSL Program Object", programObject ); } - } - //----------------------------------------------------------------------- - void GLSLProgram::detachFromProgramObject( const GLhandleARB programObject ) - { - glDetachObjectARB(programObject, mGLHandle); + } + //----------------------------------------------------------------------- + void GLSLProgram::detachFromProgramObject( const GLhandleARB programObject ) + { + glDetachObjectARB(programObject, mGLHandle); GLenum glErr = glGetError(); if(glErr != GL_NO_ERROR) { - reportGLSLError( glErr, "GLSLProgram::detachFromProgramObject", - "Error detaching " + mName + " shader object from GLSL Program Object", programObject ); + reportGLSLError( glErr, "GLSLProgram::detachFromProgramObject", + "Error detaching " + mName + " shader object from GLSL Program Object", programObject ); } - // attach child objects - GLSLProgramContainerIterator childprogramcurrent = mAttachedGLSLPrograms.begin(); - GLSLProgramContainerIterator childprogramend = mAttachedGLSLPrograms.end(); + // attach child objects + GLSLProgramContainerIterator childprogramcurrent = mAttachedGLSLPrograms.begin(); + GLSLProgramContainerIterator childprogramend = mAttachedGLSLPrograms.end(); - while (childprogramcurrent != childprogramend) - { - GLSLProgram* childShader = *childprogramcurrent; - childShader->detachFromProgramObject( programObject ); - ++childprogramcurrent; - } + while (childprogramcurrent != childprogramend) + { + GLSLProgram* childShader = *childprogramcurrent; + childShader->detachFromProgramObject( programObject ); + ++childprogramcurrent; + } - } + } //----------------------------------------------------------------------- const String& GLSLProgram::getLanguage(void) const @@ -426,61 +426,61 @@ namespace Ogre { return language; } - //----------------------------------------------------------------------- - RenderOperation::OperationType parseOperationType(const String& val) - { - if (val == "point_list") - { - return RenderOperation::OT_POINT_LIST; - } - else if (val == "line_list") - { - return RenderOperation::OT_LINE_LIST; - } - else if (val == "line_strip") - { - return RenderOperation::OT_LINE_STRIP; - } - else if (val == "triangle_strip") - { - return RenderOperation::OT_TRIANGLE_STRIP; - } - else if (val == "triangle_fan") - { - return RenderOperation::OT_TRIANGLE_FAN; - } - else - { - //Triangle list is the default fallback. Keep it this way? - return RenderOperation::OT_TRIANGLE_LIST; - } - } - //----------------------------------------------------------------------- - String operationTypeToString(RenderOperation::OperationType val) - { - switch (val) - { - case RenderOperation::OT_POINT_LIST: - return "point_list"; - break; - case RenderOperation::OT_LINE_LIST: - return "line_list"; - break; - case RenderOperation::OT_LINE_STRIP: - return "line_strip"; - break; - case RenderOperation::OT_TRIANGLE_STRIP: - return "triangle_strip"; - break; - case RenderOperation::OT_TRIANGLE_FAN: - return "triangle_fan"; - break; - case RenderOperation::OT_TRIANGLE_LIST: - default: - return "triangle_list"; - break; - } - } + //----------------------------------------------------------------------- + RenderOperation::OperationType parseOperationType(const String& val) + { + if (val == "point_list") + { + return RenderOperation::OT_POINT_LIST; + } + else if (val == "line_list") + { + return RenderOperation::OT_LINE_LIST; + } + else if (val == "line_strip") + { + return RenderOperation::OT_LINE_STRIP; + } + else if (val == "triangle_strip") + { + return RenderOperation::OT_TRIANGLE_STRIP; + } + else if (val == "triangle_fan") + { + return RenderOperation::OT_TRIANGLE_FAN; + } + else + { + //Triangle list is the default fallback. Keep it this way? + return RenderOperation::OT_TRIANGLE_LIST; + } + } + //----------------------------------------------------------------------- + String operationTypeToString(RenderOperation::OperationType val) + { + switch (val) + { + case RenderOperation::OT_POINT_LIST: + return "point_list"; + break; + case RenderOperation::OT_LINE_LIST: + return "line_list"; + break; + case RenderOperation::OT_LINE_STRIP: + return "line_strip"; + break; + case RenderOperation::OT_TRIANGLE_STRIP: + return "triangle_strip"; + break; + case RenderOperation::OT_TRIANGLE_FAN: + return "triangle_fan"; + break; + case RenderOperation::OT_TRIANGLE_LIST: + default: + return "triangle_list"; + break; + } + } //----------------------------------------------------------------------- String GLSLProgram::CmdColumnMajorMatrices::doGet(const void *target) const { @@ -490,39 +490,39 @@ namespace Ogre { { static_cast(target)->setColumnMajorMatrices(StringConverter::parseBool(val)); } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- String GLSLProgram::CmdInputOperationType::doGet(const void* target) const { const GLSLProgram* t = static_cast(target); - return operationTypeToString(t->getInputOperationType()); + return operationTypeToString(t->getInputOperationType()); } void GLSLProgram::CmdInputOperationType::doSet(void* target, const String& val) { GLSLProgram* t = static_cast(target); - t->setInputOperationType(parseOperationType(val)); + t->setInputOperationType(parseOperationType(val)); } - //----------------------------------------------------------------------- - String GLSLProgram::CmdOutputOperationType::doGet(const void* target) const + //----------------------------------------------------------------------- + String GLSLProgram::CmdOutputOperationType::doGet(const void* target) const { const GLSLProgram* t = static_cast(target); - return operationTypeToString(t->getOutputOperationType()); + return operationTypeToString(t->getOutputOperationType()); } void GLSLProgram::CmdOutputOperationType::doSet(void* target, const String& val) { GLSLProgram* t = static_cast(target); - t->setOutputOperationType(parseOperationType(val)); + t->setOutputOperationType(parseOperationType(val)); + } + //----------------------------------------------------------------------- + String GLSLProgram::CmdMaxOutputVertices::doGet(const void* target) const + { + const GLSLProgram* t = static_cast(target); + return StringConverter::toString(t->getMaxOutputVertices()); + } + void GLSLProgram::CmdMaxOutputVertices::doSet(void* target, const String& val) + { + GLSLProgram* t = static_cast(target); + t->setMaxOutputVertices(StringConverter::parseInt(val)); } - //----------------------------------------------------------------------- - String GLSLProgram::CmdMaxOutputVertices::doGet(const void* target) const - { - const GLSLProgram* t = static_cast(target); - return StringConverter::toString(t->getMaxOutputVertices()); - } - void GLSLProgram::CmdMaxOutputVertices::doSet(void* target, const String& val) - { - GLSLProgram* t = static_cast(target); - t->setMaxOutputVertices(StringConverter::parseInt(val)); - } } } diff --git a/RenderSystems/GL/src/GLSL/src/OgreGLSLProgramFactory.cpp b/RenderSystems/GL/src/GLSL/src/OgreGLSLProgramFactory.cpp index a70f2de69aa..0ba19e637e8 100644 --- a/RenderSystems/GL/src/GLSL/src/OgreGLSLProgramFactory.cpp +++ b/RenderSystems/GL/src/GLSL/src/OgreGLSLProgramFactory.cpp @@ -35,15 +35,15 @@ namespace Ogre { //----------------------------------------------------------------------- String GLSLProgramFactory::sLanguageName = "glsl"; //----------------------------------------------------------------------- - GLSLProgramFactory::GLSLProgramFactory(void) + GLSLProgramFactory::GLSLProgramFactory(void) { - mLinkProgramManager = new GLSLLinkProgramManager(); + mLinkProgramManager = new GLSLLinkProgramManager(); } //----------------------------------------------------------------------- GLSLProgramFactory::~GLSLProgramFactory(void) { - if (mLinkProgramManager) - delete mLinkProgramManager; + if (mLinkProgramManager) + delete mLinkProgramManager; } //----------------------------------------------------------------------- const String& GLSLProgramFactory::getLanguage(void) const @@ -58,7 +58,7 @@ namespace Ogre { return new GLSLProgram(creator, name, handle, group, isManual, loader); } //----------------------------------------------------------------------- - void GLSLProgramFactory::destroy(HighLevelGpuProgram* prog) + void GLSLProgramFactory::destroy(HighLevelGpuProgram* prog) { delete prog; } diff --git a/RenderSystems/GL/src/GLX/OgreGLXContext.cpp b/RenderSystems/GL/src/GLX/OgreGLXContext.cpp index de12273503e..fc5ddf9c05d 100644 --- a/RenderSystems/GL/src/GLX/OgreGLXContext.cpp +++ b/RenderSystems/GL/src/GLX/OgreGLXContext.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- This source file is part of OGRE - (Object-oriented Graphics Rendering Engine) + (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd @@ -34,56 +34,56 @@ THE SOFTWARE. namespace Ogre { - GLXContext::GLXContext(GLXGLSupport* glsupport, ::GLXFBConfig fbconfig, ::GLXDrawable drawable, ::GLXContext context) : - mDrawable(drawable), mContext(0), mFBConfig(fbconfig), mGLSupport(glsupport), mExternalContext(false) - { - GLRenderSystem *renderSystem = static_cast(Root::getSingleton().getRenderSystem()); - GLXContext* mainContext = static_cast(renderSystem->_getMainContext()); - ::GLXContext shareContext = 0; - - if (mainContext) - { - shareContext = mainContext->mContext; - } - - if (context) - { - mContext = context; - mExternalContext = true; - } - else - { - mContext = mGLSupport->createNewContext(mFBConfig, GLX_RGBA_TYPE, shareContext, GL_TRUE); - } + GLXContext::GLXContext(GLXGLSupport* glsupport, ::GLXFBConfig fbconfig, ::GLXDrawable drawable, ::GLXContext context) : + mDrawable(drawable), mContext(0), mFBConfig(fbconfig), mGLSupport(glsupport), mExternalContext(false) + { + GLRenderSystem *renderSystem = static_cast(Root::getSingleton().getRenderSystem()); + GLXContext* mainContext = static_cast(renderSystem->_getMainContext()); + ::GLXContext shareContext = 0; + + if (mainContext) + { + shareContext = mainContext->mContext; + } + + if (context) + { + mContext = context; + mExternalContext = true; + } + else + { + mContext = mGLSupport->createNewContext(mFBConfig, GLX_RGBA_TYPE, shareContext, GL_TRUE); + } - if (! mContext) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create a suitable GLXContext", "GLXContext::GLXContext"); - } - } - - GLXContext::~GLXContext() - { - GLRenderSystem *rs = static_cast(Root::getSingleton().getRenderSystem()); + if (! mContext) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create a suitable GLXContext", "GLXContext::GLXContext"); + } + } + + GLXContext::~GLXContext() + { + GLRenderSystem *rs = static_cast(Root::getSingleton().getRenderSystem()); - if (!mExternalContext) + if (!mExternalContext) glXDestroyContext(mGLSupport->getGLDisplay(), mContext); - rs->_unregisterContext(this); - } - - void GLXContext::setCurrent() - { - glXMakeCurrent(mGLSupport->getGLDisplay(), mDrawable, mContext); - } - - void GLXContext::endCurrent() - { - glXMakeCurrent(mGLSupport->getGLDisplay(), None, None); - } - - GLContext* GLXContext::clone() const - { - return new GLXContext(mGLSupport, mFBConfig, mDrawable); - } + rs->_unregisterContext(this); + } + + void GLXContext::setCurrent() + { + glXMakeCurrent(mGLSupport->getGLDisplay(), mDrawable, mContext); + } + + void GLXContext::endCurrent() + { + glXMakeCurrent(mGLSupport->getGLDisplay(), None, None); + } + + GLContext* GLXContext::clone() const + { + return new GLXContext(mGLSupport, mFBConfig, mDrawable); + } } diff --git a/RenderSystems/GL/src/GLX/OgreGLXGLSupport.cpp b/RenderSystems/GL/src/GLX/OgreGLXGLSupport.cpp index a13ec861166..bdcfb8920c9 100644 --- a/RenderSystems/GL/src/GLX/OgreGLXGLSupport.cpp +++ b/RenderSystems/GL/src/GLX/OgreGLXGLSupport.cpp @@ -47,968 +47,968 @@ static Display *_getCurrentDisplay(void) { return _currentDisplay; } namespace Ogre { - //-------------------------------------------------------------------------------------------------// - template void remove_duplicates(C& c) - { - std::sort(c.begin(), c.end()); - typename C::iterator p = std::unique(c.begin(), c.end()); - c.erase(p, c.end()); - } - - //-------------------------------------------------------------------------------------------------// - GLXGLSupport::GLXGLSupport() : mGLDisplay(0), mXDisplay(0) - { - // A connection that might be shared with the application for GL rendering: - mGLDisplay = getGLDisplay(); - - // A connection that is NOT shared to enable independent event processing: - mXDisplay = getXDisplay(); - - int dummy; - - if (XQueryExtension(mXDisplay, "RANDR", &dummy, &dummy, &dummy)) - { - XRRScreenConfiguration *screenConfig; - - screenConfig = XRRGetScreenInfo(mXDisplay, DefaultRootWindow(mXDisplay)); - - if (screenConfig) - { - XRRScreenSize *screenSizes; - int nSizes = 0; - Rotation currentRotation; - int currentSizeID = XRRConfigCurrentConfiguration(screenConfig, ¤tRotation); - - screenSizes = XRRConfigSizes(screenConfig, &nSizes); - - mCurrentMode.first.first = screenSizes[currentSizeID].width; - mCurrentMode.first.second = screenSizes[currentSizeID].height; - mCurrentMode.second = XRRConfigCurrentRate(screenConfig); - - mOriginalMode = mCurrentMode; - - for(int sizeID = 0; sizeID < nSizes; sizeID++) - { - short *rates; - int nRates = 0; - - rates = XRRConfigRates(screenConfig, sizeID, &nRates); - - for (int rate = 0; rate < nRates; rate++) - { - VideoMode mode; - - mode.first.first = screenSizes[sizeID].width; - mode.first.second = screenSizes[sizeID].height; - mode.second = rates[rate]; - - mVideoModes.push_back(mode); - } - } - XRRFreeScreenConfigInfo(screenConfig); - } - } - else - { - mCurrentMode.first.first = DisplayWidth(mXDisplay, DefaultScreen(mXDisplay)); - mCurrentMode.first.second = DisplayHeight(mXDisplay, DefaultScreen(mXDisplay)); - mCurrentMode.second = 0; - - mOriginalMode = mCurrentMode; - - mVideoModes.push_back(mCurrentMode); - } - - GLXFBConfig *fbConfigs; - int config, nConfigs = 0; - - fbConfigs = chooseFBConfig(NULL, &nConfigs); - - for (config = 0; config < nConfigs; config++) - { - int caveat, samples; - - getFBConfigAttrib (fbConfigs[config], GLX_CONFIG_CAVEAT, &caveat); - - if (caveat != GLX_SLOW_CONFIG) - { - getFBConfigAttrib (fbConfigs[config], GLX_SAMPLES, &samples); - mSampleLevels.push_back(StringConverter::toString(samples)); - } - } - - XFree (fbConfigs); - - remove_duplicates(mSampleLevels); - } - - //-------------------------------------------------------------------------------------------------// - GLXGLSupport::~GLXGLSupport() - { - if (mXDisplay) - XCloseDisplay(mXDisplay); - - if (! mIsExternalDisplay && mGLDisplay) - XCloseDisplay(mGLDisplay); - } - - //-------------------------------------------------------------------------------------------------// - void GLXGLSupport::addConfig(void) - { - ConfigOption optFullScreen; - ConfigOption optVideoMode; - ConfigOption optColourDepth; - ConfigOption optDisplayFrequency; - ConfigOption optVSync; - ConfigOption optFSAA; - ConfigOption optRTTMode; - ConfigOption optSRGB; - ConfigOption optEnableFixedPipeline; - - optFullScreen.name = "Full Screen"; - optFullScreen.immutable = false; - - optVideoMode.name = "Video Mode"; - optVideoMode.immutable = false; - - optDisplayFrequency.name = "Display Frequency"; - optDisplayFrequency.immutable = false; - - optColourDepth.name = "Colour Depth"; - optColourDepth.immutable = false; - optColourDepth.currentValue.clear(); - - optVSync.name = "VSync"; - optVSync.immutable = false; - - optFSAA.name = "FSAA"; - optFSAA.immutable = false; - - optRTTMode.name = "RTT Preferred Mode"; - optRTTMode.immutable = false; - - optSRGB.name = "sRGB Gamma Conversion"; - optSRGB.immutable = false; - - optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; - optEnableFixedPipeline.possibleValues.push_back( "Yes" ); - optEnableFixedPipeline.possibleValues.push_back( "No" ); - optEnableFixedPipeline.currentValue = "Yes"; - optEnableFixedPipeline.immutable = false; - - optFullScreen.possibleValues.push_back("No"); - optFullScreen.possibleValues.push_back("Yes"); - - optFullScreen.currentValue = optFullScreen.possibleValues[1]; - - VideoModes::const_iterator value = mVideoModes.begin(); - VideoModes::const_iterator end = mVideoModes.end(); - - for (; value != end; value++) - { - String mode = StringConverter::toString(value->first.first,4) + " x " + StringConverter::toString(value->first.second,4); - - optVideoMode.possibleValues.push_back(mode); - } - - remove_duplicates(optVideoMode.possibleValues); - - optVideoMode.currentValue = StringConverter::toString(mCurrentMode.first.first,4) + " x " + StringConverter::toString(mCurrentMode.first.second,4); - - refreshConfig(); - - if (GLXEW_SGI_swap_control) - { - optVSync.possibleValues.push_back("No"); - optVSync.possibleValues.push_back("Yes"); - - optVSync.currentValue = optVSync.possibleValues[0]; - } - - // Is it worth checking for GL_EXT_framebuffer_object ? - optRTTMode.possibleValues.push_back("FBO"); - - if (GLXEW_VERSION_1_3) - { - optRTTMode.possibleValues.push_back("PBuffer"); - } - - optRTTMode.possibleValues.push_back("Copy"); - - optRTTMode.currentValue = optRTTMode.possibleValues[0]; - - if (! mSampleLevels.empty()) - { - StringVector::const_iterator value_ = mSampleLevels.begin(); - StringVector::const_iterator end_ = mSampleLevels.end(); - - for (; value_ != end_; value_++) - { - optFSAA.possibleValues.push_back(*value_); - } - - optFSAA.currentValue = optFSAA.possibleValues[0]; - } - - if (GLXEW_EXT_framebuffer_sRGB) - { - optSRGB.possibleValues.push_back("No"); - optSRGB.possibleValues.push_back("Yes"); - - optSRGB.currentValue = optSRGB.possibleValues[0]; - } - - mOptions[optFullScreen.name] = optFullScreen; - mOptions[optVideoMode.name] = optVideoMode; - mOptions[optColourDepth.name] = optColourDepth; - mOptions[optDisplayFrequency.name] = optDisplayFrequency; - mOptions[optVSync.name] = optVSync; - mOptions[optRTTMode.name] = optRTTMode; - mOptions[optFSAA.name] = optFSAA; - mOptions[optSRGB.name] = optSRGB; - mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; - - refreshConfig(); - } - - //-------------------------------------------------------------------------------------------------// - void GLXGLSupport::refreshConfig(void) - { - ConfigOptionMap::iterator optVideoMode = mOptions.find("Video Mode"); - ConfigOptionMap::iterator optDisplayFrequency = mOptions.find("Display Frequency"); - - if (optVideoMode != mOptions.end() && optDisplayFrequency != mOptions.end()) - { - optDisplayFrequency->second.possibleValues.clear(); - - VideoModes::const_iterator value = mVideoModes.begin(); - VideoModes::const_iterator end = mVideoModes.end(); - - for (; value != end; value++) - { - String mode = StringConverter::toString(value->first.first,4) + " x " + StringConverter::toString(value->first.second,4); - - if (mode == optVideoMode->second.currentValue) - { - String frequency = StringConverter::toString(value->second) + " Hz"; - - optDisplayFrequency->second.possibleValues.push_back(frequency); - } - } - - if (! optDisplayFrequency->second.possibleValues.empty()) - { - optDisplayFrequency->second.currentValue = optDisplayFrequency->second.possibleValues[0]; - } - else - { - optVideoMode->second.currentValue = StringConverter::toString(mVideoModes[0].first.first,4) + " x " + StringConverter::toString(mVideoModes[0].first.second,4); - optDisplayFrequency->second.currentValue = StringConverter::toString(mVideoModes[0].second) + " Hz"; - } - } - } - - //-------------------------------------------------------------------------------------------------// - void GLXGLSupport::setConfigOption(const String &name, const String &value) - { - ConfigOptionMap::iterator option = mOptions.find(name); - - if(option == mOptions.end()) - { - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Option named " + name + " does not exist.", "GLXGLSupport::setConfigOption" ); - } - else - { - option->second.currentValue = value; - } - - if (name == "Video Mode") - { - ConfigOptionMap::iterator opt; - if((opt = mOptions.find("Full Screen")) != mOptions.end()) - { - if (opt->second.currentValue == "Yes") - refreshConfig(); - } - } - } - - //-------------------------------------------------------------------------------------------------// - String GLXGLSupport::validateConfig(void) - { - // TO DO - return BLANKSTRING; - } - - //-------------------------------------------------------------------------------------------------// - RenderWindow* GLXGLSupport::createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle) - { - RenderWindow *window = 0; - - if (autoCreateWindow) - { - ConfigOptionMap::iterator opt; - ConfigOptionMap::iterator end = mOptions.end(); - NameValuePairList miscParams; - - bool fullscreen = false; - uint w = 800, h = 600; - - if((opt = mOptions.find("Full Screen")) != end) - fullscreen = (opt->second.currentValue == "Yes"); - - if((opt = mOptions.find("Display Frequency")) != end) - miscParams["displayFrequency"] = opt->second.currentValue; - - if((opt = mOptions.find("Video Mode")) != end) - { - String val = opt->second.currentValue; - String::size_type pos = val.find('x'); - - if (pos != String::npos) - { - w = StringConverter::parseUnsignedInt(val.substr(0, pos)); - h = StringConverter::parseUnsignedInt(val.substr(pos + 1)); - } - } - - if((opt = mOptions.find("FSAA")) != end) - miscParams["FSAA"] = opt->second.currentValue; - - if((opt = mOptions.find("VSync")) != end) - miscParams["vsync"] = opt->second.currentValue; - - if((opt = mOptions.find("sRGB Gamma Conversion")) != end) - miscParams["gamma"] = opt->second.currentValue; - - opt = mOptions.find("Fixed Pipeline Enabled"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow"); - bool enableFixedPipeline = (opt->second.currentValue == "Yes"); - renderSystem->setFixedPipelineEnabled(enableFixedPipeline); - - window = renderSystem->_createRenderWindow(windowTitle, w, h, fullscreen, &miscParams); - } - - return window; - } - - //-------------------------------------------------------------------------------------------------// - RenderWindow* GLXGLSupport::newWindow(const String &name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams) - { - GLXWindow* window = new GLXWindow(this); - - window->create(name, width, height, fullScreen, miscParams); - - return window; - } - - //-------------------------------------------------------------------------------------------------// - GLPBuffer *GLXGLSupport::createPBuffer(PixelComponentType format, size_t width, size_t height) - { - return new GLXPBuffer(this, format, width, height); - } - - //-------------------------------------------------------------------------------------------------// - void GLXGLSupport::start() - { - LogManager::getSingleton().logMessage( - "******************************\n" - "*** Starting GLX Subsystem ***\n" - "******************************"); - } - - //-------------------------------------------------------------------------------------------------// - void GLXGLSupport::stop() - { - LogManager::getSingleton().logMessage( - "******************************\n" - "*** Stopping GLX Subsystem ***\n" - "******************************"); - } - - //-------------------------------------------------------------------------------------------------// - void* GLXGLSupport::getProcAddress(const String& procname) { - return (void*)glXGetProcAddressARB((const GLubyte*)procname.c_str()); - } - - //-------------------------------------------------------------------------------------------------// - void GLXGLSupport::initialiseExtensions(void) - { - assert (mGLDisplay); - - GLSupport::initialiseExtensions(); - - const char* extensionsString; - - // This is more realistic than using glXGetClientString: - extensionsString = glXQueryExtensionsString(mGLDisplay, DefaultScreen(mGLDisplay)); - - LogManager::getSingleton().stream() << "Supported GLX extensions: " << extensionsString; - - StringStream ext; - String instr; - - ext << extensionsString; - - while(ext >> instr) - { - extensionList.insert(instr); - } - } - - //-------------------------------------------------------------------------------------------------// - // Returns the FBConfig behind a GLXContext + //-------------------------------------------------------------------------------------------------// + template void remove_duplicates(C& c) + { + std::sort(c.begin(), c.end()); + typename C::iterator p = std::unique(c.begin(), c.end()); + c.erase(p, c.end()); + } + + //-------------------------------------------------------------------------------------------------// + GLXGLSupport::GLXGLSupport() : mGLDisplay(0), mXDisplay(0) + { + // A connection that might be shared with the application for GL rendering: + mGLDisplay = getGLDisplay(); + + // A connection that is NOT shared to enable independent event processing: + mXDisplay = getXDisplay(); + + int dummy; + + if (XQueryExtension(mXDisplay, "RANDR", &dummy, &dummy, &dummy)) + { + XRRScreenConfiguration *screenConfig; + + screenConfig = XRRGetScreenInfo(mXDisplay, DefaultRootWindow(mXDisplay)); + + if (screenConfig) + { + XRRScreenSize *screenSizes; + int nSizes = 0; + Rotation currentRotation; + int currentSizeID = XRRConfigCurrentConfiguration(screenConfig, ¤tRotation); + + screenSizes = XRRConfigSizes(screenConfig, &nSizes); + + mCurrentMode.first.first = screenSizes[currentSizeID].width; + mCurrentMode.first.second = screenSizes[currentSizeID].height; + mCurrentMode.second = XRRConfigCurrentRate(screenConfig); + + mOriginalMode = mCurrentMode; + + for(int sizeID = 0; sizeID < nSizes; sizeID++) + { + short *rates; + int nRates = 0; + + rates = XRRConfigRates(screenConfig, sizeID, &nRates); + + for (int rate = 0; rate < nRates; rate++) + { + VideoMode mode; + + mode.first.first = screenSizes[sizeID].width; + mode.first.second = screenSizes[sizeID].height; + mode.second = rates[rate]; + + mVideoModes.push_back(mode); + } + } + XRRFreeScreenConfigInfo(screenConfig); + } + } + else + { + mCurrentMode.first.first = DisplayWidth(mXDisplay, DefaultScreen(mXDisplay)); + mCurrentMode.first.second = DisplayHeight(mXDisplay, DefaultScreen(mXDisplay)); + mCurrentMode.second = 0; + + mOriginalMode = mCurrentMode; + + mVideoModes.push_back(mCurrentMode); + } + + GLXFBConfig *fbConfigs; + int config, nConfigs = 0; + + fbConfigs = chooseFBConfig(NULL, &nConfigs); + + for (config = 0; config < nConfigs; config++) + { + int caveat, samples; + + getFBConfigAttrib (fbConfigs[config], GLX_CONFIG_CAVEAT, &caveat); + + if (caveat != GLX_SLOW_CONFIG) + { + getFBConfigAttrib (fbConfigs[config], GLX_SAMPLES, &samples); + mSampleLevels.push_back(StringConverter::toString(samples)); + } + } + + XFree (fbConfigs); + + remove_duplicates(mSampleLevels); + } + + //-------------------------------------------------------------------------------------------------// + GLXGLSupport::~GLXGLSupport() + { + if (mXDisplay) + XCloseDisplay(mXDisplay); + + if (! mIsExternalDisplay && mGLDisplay) + XCloseDisplay(mGLDisplay); + } + + //-------------------------------------------------------------------------------------------------// + void GLXGLSupport::addConfig(void) + { + ConfigOption optFullScreen; + ConfigOption optVideoMode; + ConfigOption optColourDepth; + ConfigOption optDisplayFrequency; + ConfigOption optVSync; + ConfigOption optFSAA; + ConfigOption optRTTMode; + ConfigOption optSRGB; + ConfigOption optEnableFixedPipeline; + + optFullScreen.name = "Full Screen"; + optFullScreen.immutable = false; + + optVideoMode.name = "Video Mode"; + optVideoMode.immutable = false; + + optDisplayFrequency.name = "Display Frequency"; + optDisplayFrequency.immutable = false; + + optColourDepth.name = "Colour Depth"; + optColourDepth.immutable = false; + optColourDepth.currentValue.clear(); + + optVSync.name = "VSync"; + optVSync.immutable = false; + + optFSAA.name = "FSAA"; + optFSAA.immutable = false; + + optRTTMode.name = "RTT Preferred Mode"; + optRTTMode.immutable = false; + + optSRGB.name = "sRGB Gamma Conversion"; + optSRGB.immutable = false; + + optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; + optEnableFixedPipeline.possibleValues.push_back( "Yes" ); + optEnableFixedPipeline.possibleValues.push_back( "No" ); + optEnableFixedPipeline.currentValue = "Yes"; + optEnableFixedPipeline.immutable = false; + + optFullScreen.possibleValues.push_back("No"); + optFullScreen.possibleValues.push_back("Yes"); + + optFullScreen.currentValue = optFullScreen.possibleValues[1]; + + VideoModes::const_iterator value = mVideoModes.begin(); + VideoModes::const_iterator end = mVideoModes.end(); + + for (; value != end; value++) + { + String mode = StringConverter::toString(value->first.first,4) + " x " + StringConverter::toString(value->first.second,4); + + optVideoMode.possibleValues.push_back(mode); + } + + remove_duplicates(optVideoMode.possibleValues); + + optVideoMode.currentValue = StringConverter::toString(mCurrentMode.first.first,4) + " x " + StringConverter::toString(mCurrentMode.first.second,4); + + refreshConfig(); + + if (GLXEW_SGI_swap_control) + { + optVSync.possibleValues.push_back("No"); + optVSync.possibleValues.push_back("Yes"); + + optVSync.currentValue = optVSync.possibleValues[0]; + } + + // Is it worth checking for GL_EXT_framebuffer_object ? + optRTTMode.possibleValues.push_back("FBO"); + + if (GLXEW_VERSION_1_3) + { + optRTTMode.possibleValues.push_back("PBuffer"); + } + + optRTTMode.possibleValues.push_back("Copy"); + + optRTTMode.currentValue = optRTTMode.possibleValues[0]; + + if (! mSampleLevels.empty()) + { + StringVector::const_iterator value_ = mSampleLevels.begin(); + StringVector::const_iterator end_ = mSampleLevels.end(); + + for (; value_ != end_; value_++) + { + optFSAA.possibleValues.push_back(*value_); + } + + optFSAA.currentValue = optFSAA.possibleValues[0]; + } + + if (GLXEW_EXT_framebuffer_sRGB) + { + optSRGB.possibleValues.push_back("No"); + optSRGB.possibleValues.push_back("Yes"); + + optSRGB.currentValue = optSRGB.possibleValues[0]; + } + + mOptions[optFullScreen.name] = optFullScreen; + mOptions[optVideoMode.name] = optVideoMode; + mOptions[optColourDepth.name] = optColourDepth; + mOptions[optDisplayFrequency.name] = optDisplayFrequency; + mOptions[optVSync.name] = optVSync; + mOptions[optRTTMode.name] = optRTTMode; + mOptions[optFSAA.name] = optFSAA; + mOptions[optSRGB.name] = optSRGB; + mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; + + refreshConfig(); + } + + //-------------------------------------------------------------------------------------------------// + void GLXGLSupport::refreshConfig(void) + { + ConfigOptionMap::iterator optVideoMode = mOptions.find("Video Mode"); + ConfigOptionMap::iterator optDisplayFrequency = mOptions.find("Display Frequency"); + + if (optVideoMode != mOptions.end() && optDisplayFrequency != mOptions.end()) + { + optDisplayFrequency->second.possibleValues.clear(); + + VideoModes::const_iterator value = mVideoModes.begin(); + VideoModes::const_iterator end = mVideoModes.end(); + + for (; value != end; value++) + { + String mode = StringConverter::toString(value->first.first,4) + " x " + StringConverter::toString(value->first.second,4); + + if (mode == optVideoMode->second.currentValue) + { + String frequency = StringConverter::toString(value->second) + " Hz"; + + optDisplayFrequency->second.possibleValues.push_back(frequency); + } + } + + if (! optDisplayFrequency->second.possibleValues.empty()) + { + optDisplayFrequency->second.currentValue = optDisplayFrequency->second.possibleValues[0]; + } + else + { + optVideoMode->second.currentValue = StringConverter::toString(mVideoModes[0].first.first,4) + " x " + StringConverter::toString(mVideoModes[0].first.second,4); + optDisplayFrequency->second.currentValue = StringConverter::toString(mVideoModes[0].second) + " Hz"; + } + } + } + + //-------------------------------------------------------------------------------------------------// + void GLXGLSupport::setConfigOption(const String &name, const String &value) + { + ConfigOptionMap::iterator option = mOptions.find(name); + + if(option == mOptions.end()) + { + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Option named " + name + " does not exist.", "GLXGLSupport::setConfigOption" ); + } + else + { + option->second.currentValue = value; + } + + if (name == "Video Mode") + { + ConfigOptionMap::iterator opt; + if((opt = mOptions.find("Full Screen")) != mOptions.end()) + { + if (opt->second.currentValue == "Yes") + refreshConfig(); + } + } + } + + //-------------------------------------------------------------------------------------------------// + String GLXGLSupport::validateConfig(void) + { + // TO DO + return BLANKSTRING; + } + + //-------------------------------------------------------------------------------------------------// + RenderWindow* GLXGLSupport::createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle) + { + RenderWindow *window = 0; + + if (autoCreateWindow) + { + ConfigOptionMap::iterator opt; + ConfigOptionMap::iterator end = mOptions.end(); + NameValuePairList miscParams; + + bool fullscreen = false; + uint w = 800, h = 600; + + if((opt = mOptions.find("Full Screen")) != end) + fullscreen = (opt->second.currentValue == "Yes"); + + if((opt = mOptions.find("Display Frequency")) != end) + miscParams["displayFrequency"] = opt->second.currentValue; + + if((opt = mOptions.find("Video Mode")) != end) + { + String val = opt->second.currentValue; + String::size_type pos = val.find('x'); + + if (pos != String::npos) + { + w = StringConverter::parseUnsignedInt(val.substr(0, pos)); + h = StringConverter::parseUnsignedInt(val.substr(pos + 1)); + } + } + + if((opt = mOptions.find("FSAA")) != end) + miscParams["FSAA"] = opt->second.currentValue; + + if((opt = mOptions.find("VSync")) != end) + miscParams["vsync"] = opt->second.currentValue; + + if((opt = mOptions.find("sRGB Gamma Conversion")) != end) + miscParams["gamma"] = opt->second.currentValue; + + opt = mOptions.find("Fixed Pipeline Enabled"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow"); + bool enableFixedPipeline = (opt->second.currentValue == "Yes"); + renderSystem->setFixedPipelineEnabled(enableFixedPipeline); + + window = renderSystem->_createRenderWindow(windowTitle, w, h, fullscreen, &miscParams); + } + + return window; + } + + //-------------------------------------------------------------------------------------------------// + RenderWindow* GLXGLSupport::newWindow(const String &name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams) + { + GLXWindow* window = new GLXWindow(this); + + window->create(name, width, height, fullScreen, miscParams); + + return window; + } + + //-------------------------------------------------------------------------------------------------// + GLPBuffer *GLXGLSupport::createPBuffer(PixelComponentType format, size_t width, size_t height) + { + return new GLXPBuffer(this, format, width, height); + } + + //-------------------------------------------------------------------------------------------------// + void GLXGLSupport::start() + { + LogManager::getSingleton().logMessage( + "******************************\n" + "*** Starting GLX Subsystem ***\n" + "******************************"); + } + + //-------------------------------------------------------------------------------------------------// + void GLXGLSupport::stop() + { + LogManager::getSingleton().logMessage( + "******************************\n" + "*** Stopping GLX Subsystem ***\n" + "******************************"); + } + + //-------------------------------------------------------------------------------------------------// + void* GLXGLSupport::getProcAddress(const String& procname) { + return (void*)glXGetProcAddressARB((const GLubyte*)procname.c_str()); + } + + //-------------------------------------------------------------------------------------------------// + void GLXGLSupport::initialiseExtensions(void) + { + assert (mGLDisplay); + + GLSupport::initialiseExtensions(); + + const char* extensionsString; + + // This is more realistic than using glXGetClientString: + extensionsString = glXQueryExtensionsString(mGLDisplay, DefaultScreen(mGLDisplay)); + + LogManager::getSingleton().stream() << "Supported GLX extensions: " << extensionsString; + + StringStream ext; + String instr; + + ext << extensionsString; + + while(ext >> instr) + { + extensionList.insert(instr); + } + } + + //-------------------------------------------------------------------------------------------------// + // Returns the FBConfig behind a GLXContext - GLXFBConfig GLXGLSupport::getFBConfigFromContext(::GLXContext context) - { - GLXFBConfig fbConfig = 0; - - if (GLXEW_VERSION_1_3) - { - int fbConfigAttrib[] = { - GLX_FBCONFIG_ID, 0, - None - }; - GLXFBConfig *fbConfigs; - int nElements = 0; - - glXQueryContext(mGLDisplay, context, GLX_FBCONFIG_ID, &fbConfigAttrib[1]); - fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), fbConfigAttrib, &nElements); - - if (nElements) - { - fbConfig = fbConfigs[0]; - XFree(fbConfigs); - } - } - else if (GLXEW_EXT_import_context && GLXEW_SGIX_fbconfig) - { - VisualID visualid; - - if (glXQueryContextInfoEXT(mGLDisplay, context, GLX_VISUAL_ID, (int*)&visualid)) - { - fbConfig = getFBConfigFromVisualID(visualid); - } - } - - return fbConfig; - } - - //-------------------------------------------------------------------------------------------------// - // Returns the FBConfig behind a GLXDrawable, or returns 0 when - // missing GLX_SGIX_fbconfig and drawable is Window (unlikely), OR - // missing GLX_VERSION_1_3 and drawable is a GLXPixmap (possible). - - GLXFBConfig GLXGLSupport::getFBConfigFromDrawable(GLXDrawable drawable, unsigned int *width, unsigned int *height) - { - GLXFBConfig fbConfig = 0; - - if (GLXEW_VERSION_1_3) - { - int fbConfigAttrib[] = { - GLX_FBCONFIG_ID, 0, - None - }; - GLXFBConfig *fbConfigs; - int nElements = 0; - - glXQueryDrawable (mGLDisplay, drawable, GLX_FBCONFIG_ID, (unsigned int*)&fbConfigAttrib[1]); - - fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), fbConfigAttrib, &nElements); - - if (nElements) - { - fbConfig = fbConfigs[0]; - XFree (fbConfigs); - - glXQueryDrawable(mGLDisplay, drawable, GLX_WIDTH, width); - glXQueryDrawable(mGLDisplay, drawable, GLX_HEIGHT, height); - } - } - - if (! fbConfig && GLXEW_SGIX_fbconfig) - { - XWindowAttributes windowAttrib; - - if (XGetWindowAttributes(mGLDisplay, drawable, &windowAttrib)) - { - VisualID visualid = XVisualIDFromVisual(windowAttrib.visual); - - fbConfig = getFBConfigFromVisualID(visualid); - - *width = windowAttrib.width; - *height = windowAttrib.height; - } - } - - return fbConfig; - } - - //-------------------------------------------------------------------------------------------------// - // Finds a GLXFBConfig compatible with a given VisualID. - - GLXFBConfig GLXGLSupport::getFBConfigFromVisualID(VisualID visualid) - { - GLXFBConfig fbConfig = 0; - - if (GLXEW_SGIX_fbconfig && glXGetFBConfigFromVisualSGIX) - { - XVisualInfo visualInfo; - - visualInfo.screen = DefaultScreen(mGLDisplay); - visualInfo.depth = DefaultDepth(mGLDisplay, DefaultScreen(mGLDisplay)); - visualInfo.visualid = visualid; - - fbConfig = glXGetFBConfigFromVisualSGIX(mGLDisplay, &visualInfo); - } - - if (! fbConfig) - { - int minAttribs[] = { - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT || GLX_PIXMAP_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_RED_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_GREEN_SIZE, 1, - None - }; - int nConfigs = 0; - - GLXFBConfig *fbConfigs = chooseFBConfig(minAttribs, &nConfigs); - - for (int i = 0; i < nConfigs && ! fbConfig; i++) - { - XVisualInfo *visualInfo = getVisualFromFBConfig(fbConfigs[i]); - - if (visualInfo->visualid == visualid) - fbConfig = fbConfigs[i]; - - XFree(visualInfo); - } - - XFree(fbConfigs); - } - - return fbConfig; - } - - //-------------------------------------------------------------------------------------------------// - // A helper class for the implementation of selectFBConfig - - class FBConfigAttribs - { - public: - FBConfigAttribs(const int* attribs) - { - fields[GLX_CONFIG_CAVEAT] = GLX_NONE; - - for (int i = 0; attribs[2*i]; i++) - { - fields[attribs[2*i]] = attribs[2*i+1]; - } - } - - void load(GLXGLSupport* const glSupport, GLXFBConfig fbConfig) - { - std::map::iterator it; - - for (it = fields.begin(); it != fields.end(); it++) - { - it->second = 0; - - glSupport->getFBConfigAttrib(fbConfig, it->first, &it->second); - } - } - - bool operator>(FBConfigAttribs& alternative) - { - // Caveats are best avoided, but might be needed for anti-aliasing - - if (fields[GLX_CONFIG_CAVEAT] != alternative.fields[GLX_CONFIG_CAVEAT]) - { - if (fields[GLX_CONFIG_CAVEAT] == GLX_SLOW_CONFIG) - return false; - - if (fields.find(GLX_SAMPLES) != fields.end() && - fields[GLX_SAMPLES] < alternative.fields[GLX_SAMPLES]) - return false; - } - - std::map::iterator it; - - for (it = fields.begin(); it != fields.end(); it++) - { - if (it->first != GLX_CONFIG_CAVEAT && fields[it->first] > alternative.fields[it->first]) - return true; - } - - return false; - } - - std::map fields; - }; - - //-------------------------------------------------------------------------------------------------// - // Finds an FBConfig that possesses each of minAttribs and gets as close - // as possible to each of the maxAttribs without exceeding them. - // Resembles glXChooseFBConfig, but is forgiving to platforms - // that do not support the attributes listed in the maxAttribs. - - GLXFBConfig GLXGLSupport::selectFBConfig (const int* minAttribs, const int *maxAttribs) - { - GLXFBConfig *fbConfigs; - GLXFBConfig fbConfig = 0; - int config, nConfigs = 0; - - fbConfigs = chooseFBConfig(minAttribs, &nConfigs); - - // this is a fix for cases where chooseFBConfig is not supported. - // On the 10/2010 chooseFBConfig was not supported on VirtualBox - // http://www.virtualbox.org/ticket/7195 - if (!nConfigs) - { - fbConfigs = glXGetFBConfigs(mGLDisplay, DefaultScreen(mGLDisplay), &nConfigs); - } - - if (! nConfigs) - return 0; - - fbConfig = fbConfigs[0]; - - if (maxAttribs) - { - FBConfigAttribs maximum(maxAttribs); - FBConfigAttribs best(maxAttribs); - FBConfigAttribs candidate(maxAttribs); - - best.load(this, fbConfig); - - for (config = 1; config < nConfigs; config++) - { - candidate.load(this, fbConfigs[config]); - - if (candidate > maximum) - continue; - - if (candidate > best) - { - fbConfig = fbConfigs[config]; - - best.load(this, fbConfig); - } - } - } - - XFree (fbConfigs); - return fbConfig; - } - - //-------------------------------------------------------------------------------------------------// - bool GLXGLSupport::loadIcon(const String &name, Pixmap *pixmap, Pixmap *bitmap) - { - Image image; - int width, height; - char* imageData; + GLXFBConfig GLXGLSupport::getFBConfigFromContext(::GLXContext context) + { + GLXFBConfig fbConfig = 0; + + if (GLXEW_VERSION_1_3) + { + int fbConfigAttrib[] = { + GLX_FBCONFIG_ID, 0, + None + }; + GLXFBConfig *fbConfigs; + int nElements = 0; + + glXQueryContext(mGLDisplay, context, GLX_FBCONFIG_ID, &fbConfigAttrib[1]); + fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), fbConfigAttrib, &nElements); + + if (nElements) + { + fbConfig = fbConfigs[0]; + XFree(fbConfigs); + } + } + else if (GLXEW_EXT_import_context && GLXEW_SGIX_fbconfig) + { + VisualID visualid; + + if (glXQueryContextInfoEXT(mGLDisplay, context, GLX_VISUAL_ID, (int*)&visualid)) + { + fbConfig = getFBConfigFromVisualID(visualid); + } + } + + return fbConfig; + } + + //-------------------------------------------------------------------------------------------------// + // Returns the FBConfig behind a GLXDrawable, or returns 0 when + // missing GLX_SGIX_fbconfig and drawable is Window (unlikely), OR + // missing GLX_VERSION_1_3 and drawable is a GLXPixmap (possible). + + GLXFBConfig GLXGLSupport::getFBConfigFromDrawable(GLXDrawable drawable, unsigned int *width, unsigned int *height) + { + GLXFBConfig fbConfig = 0; + + if (GLXEW_VERSION_1_3) + { + int fbConfigAttrib[] = { + GLX_FBCONFIG_ID, 0, + None + }; + GLXFBConfig *fbConfigs; + int nElements = 0; + + glXQueryDrawable (mGLDisplay, drawable, GLX_FBCONFIG_ID, (unsigned int*)&fbConfigAttrib[1]); + + fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), fbConfigAttrib, &nElements); + + if (nElements) + { + fbConfig = fbConfigs[0]; + XFree (fbConfigs); + + glXQueryDrawable(mGLDisplay, drawable, GLX_WIDTH, width); + glXQueryDrawable(mGLDisplay, drawable, GLX_HEIGHT, height); + } + } + + if (! fbConfig && GLXEW_SGIX_fbconfig) + { + XWindowAttributes windowAttrib; + + if (XGetWindowAttributes(mGLDisplay, drawable, &windowAttrib)) + { + VisualID visualid = XVisualIDFromVisual(windowAttrib.visual); + + fbConfig = getFBConfigFromVisualID(visualid); + + *width = windowAttrib.width; + *height = windowAttrib.height; + } + } + + return fbConfig; + } + + //-------------------------------------------------------------------------------------------------// + // Finds a GLXFBConfig compatible with a given VisualID. + + GLXFBConfig GLXGLSupport::getFBConfigFromVisualID(VisualID visualid) + { + GLXFBConfig fbConfig = 0; + + if (GLXEW_SGIX_fbconfig && glXGetFBConfigFromVisualSGIX) + { + XVisualInfo visualInfo; + + visualInfo.screen = DefaultScreen(mGLDisplay); + visualInfo.depth = DefaultDepth(mGLDisplay, DefaultScreen(mGLDisplay)); + visualInfo.visualid = visualid; + + fbConfig = glXGetFBConfigFromVisualSGIX(mGLDisplay, &visualInfo); + } + + if (! fbConfig) + { + int minAttribs[] = { + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT || GLX_PIXMAP_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_RED_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_GREEN_SIZE, 1, + None + }; + int nConfigs = 0; + + GLXFBConfig *fbConfigs = chooseFBConfig(minAttribs, &nConfigs); + + for (int i = 0; i < nConfigs && ! fbConfig; i++) + { + XVisualInfo *visualInfo = getVisualFromFBConfig(fbConfigs[i]); + + if (visualInfo->visualid == visualid) + fbConfig = fbConfigs[i]; + + XFree(visualInfo); + } + + XFree(fbConfigs); + } + + return fbConfig; + } + + //-------------------------------------------------------------------------------------------------// + // A helper class for the implementation of selectFBConfig + + class FBConfigAttribs + { + public: + FBConfigAttribs(const int* attribs) + { + fields[GLX_CONFIG_CAVEAT] = GLX_NONE; + + for (int i = 0; attribs[2*i]; i++) + { + fields[attribs[2*i]] = attribs[2*i+1]; + } + } + + void load(GLXGLSupport* const glSupport, GLXFBConfig fbConfig) + { + std::map::iterator it; + + for (it = fields.begin(); it != fields.end(); it++) + { + it->second = 0; + + glSupport->getFBConfigAttrib(fbConfig, it->first, &it->second); + } + } + + bool operator>(FBConfigAttribs& alternative) + { + // Caveats are best avoided, but might be needed for anti-aliasing + + if (fields[GLX_CONFIG_CAVEAT] != alternative.fields[GLX_CONFIG_CAVEAT]) + { + if (fields[GLX_CONFIG_CAVEAT] == GLX_SLOW_CONFIG) + return false; + + if (fields.find(GLX_SAMPLES) != fields.end() && + fields[GLX_SAMPLES] < alternative.fields[GLX_SAMPLES]) + return false; + } + + std::map::iterator it; + + for (it = fields.begin(); it != fields.end(); it++) + { + if (it->first != GLX_CONFIG_CAVEAT && fields[it->first] > alternative.fields[it->first]) + return true; + } + + return false; + } + + std::map fields; + }; + + //-------------------------------------------------------------------------------------------------// + // Finds an FBConfig that possesses each of minAttribs and gets as close + // as possible to each of the maxAttribs without exceeding them. + // Resembles glXChooseFBConfig, but is forgiving to platforms + // that do not support the attributes listed in the maxAttribs. + + GLXFBConfig GLXGLSupport::selectFBConfig (const int* minAttribs, const int *maxAttribs) + { + GLXFBConfig *fbConfigs; + GLXFBConfig fbConfig = 0; + int config, nConfigs = 0; + + fbConfigs = chooseFBConfig(minAttribs, &nConfigs); + + // this is a fix for cases where chooseFBConfig is not supported. + // On the 10/2010 chooseFBConfig was not supported on VirtualBox + // http://www.virtualbox.org/ticket/7195 + if (!nConfigs) + { + fbConfigs = glXGetFBConfigs(mGLDisplay, DefaultScreen(mGLDisplay), &nConfigs); + } + + if (! nConfigs) + return 0; + + fbConfig = fbConfigs[0]; + + if (maxAttribs) + { + FBConfigAttribs maximum(maxAttribs); + FBConfigAttribs best(maxAttribs); + FBConfigAttribs candidate(maxAttribs); + + best.load(this, fbConfig); + + for (config = 1; config < nConfigs; config++) + { + candidate.load(this, fbConfigs[config]); + + if (candidate > maximum) + continue; + + if (candidate > best) + { + fbConfig = fbConfigs[config]; + + best.load(this, fbConfig); + } + } + } + + XFree (fbConfigs); + return fbConfig; + } + + //-------------------------------------------------------------------------------------------------// + bool GLXGLSupport::loadIcon(const String &name, Pixmap *pixmap, Pixmap *bitmap) + { + Image image; + int width, height; + char* imageData; if (! Ogre::ResourceGroupManager::getSingleton().resourceExists(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, name)) return false; - try - { - // Try to load image - image.load(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - if(image.getFormat() != PF_A8R8G8B8) - { - // Image format must be RGBA - return false; - } - - width = image.getWidth(); - height = image.getHeight(); - imageData = (char*)image.getData(); - } - catch(Exception &e) - { - // Could not find image; never mind - return false; - } - - int bitmapLineLength = (width + 7) / 8; - int pixmapLineLength = 4 * width; - - char* bitmapData = (char*)malloc(bitmapLineLength * height); - char* pixmapData = (char*)malloc(pixmapLineLength * height); - - int sptr = 0, dptr = 0; - - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - if (ImageByteOrder(mXDisplay) == MSBFirst) - { - pixmapData[dptr + 0] = 0; - pixmapData[dptr + 1] = imageData[sptr + 0]; - pixmapData[dptr + 2] = imageData[sptr + 1]; - pixmapData[dptr + 3] = imageData[sptr + 2]; - } - else - { - pixmapData[dptr + 3] = 0; - pixmapData[dptr + 2] = imageData[sptr + 0]; - pixmapData[dptr + 1] = imageData[sptr + 1]; - pixmapData[dptr + 0] = imageData[sptr + 2]; - } - - if(((unsigned char)imageData[sptr + 3])<128) - { - bitmapData[y*bitmapLineLength+(x>>3)] &= ~(1<<(x&7)); - } - else - { - bitmapData[y*bitmapLineLength+(x>>3)] |= 1<<(x&7); - } - sptr += 4; - dptr += 4; - } - } - - // Create bitmap on server and copy over bitmapData - *bitmap = XCreateBitmapFromData(mXDisplay, DefaultRootWindow(mXDisplay), bitmapData, width, height); - - free(bitmapData); - - // Create pixmap on server and copy over pixmapData (via pixmapXImage) - *pixmap = XCreatePixmap(mXDisplay, DefaultRootWindow(mXDisplay), width, height, 24); - - GC gc = XCreateGC (mXDisplay, DefaultRootWindow(mXDisplay), 0, NULL); - XImage *pixmapXImage = XCreateImage(mXDisplay, NULL, 24, ZPixmap, 0, pixmapData, width, height, 8, width*4); - XPutImage(mXDisplay, *pixmap, gc, pixmapXImage, 0, 0, 0, 0, width, height); - XDestroyImage(pixmapXImage); - XFreeGC(mXDisplay, gc); - - return true; - } - - //-------------------------------------------------------------------------------------------------// - Display* GLXGLSupport::getGLDisplay(void) - { - if (! mGLDisplay) - { - glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)getProcAddress("glXGetCurrentDisplay"); - - mGLDisplay = glXGetCurrentDisplay(); - mIsExternalDisplay = true; - - if (! mGLDisplay) - { - mGLDisplay = XOpenDisplay(0); - mIsExternalDisplay = false; - } - - if(! mGLDisplay) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn`t open X display " + String((const char*)XDisplayName (0)), "GLXGLSupport::getGLDisplay"); - } - - initialiseGLXEW(); - - if (! GLXEW_VERSION_1_3 && ! (GLXEW_SGIX_fbconfig && GLXEW_EXT_import_context)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "No GLX FBConfig support on your display", "GLXGLSupport::GLXGLSupport"); - } - } - - return mGLDisplay; - } - - //-------------------------------------------------------------------------------------------------// - Display* GLXGLSupport::getXDisplay(void) - { - if (! mXDisplay) - { - char* displayString = mGLDisplay ? DisplayString(mGLDisplay) : 0; - - mXDisplay = XOpenDisplay(displayString); - - if (! mXDisplay) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn`t open X display " + String((const char*)displayString), "GLXGLSupport::getXDisplay"); - } - - mAtomDeleteWindow = XInternAtom(mXDisplay, "WM_DELETE_WINDOW", True); - mAtomFullScreen = XInternAtom(mXDisplay, "_NET_WM_STATE_FULLSCREEN", True); - mAtomState = XInternAtom(mXDisplay, "_NET_WM_STATE", True); - } - - return mXDisplay; - } - - //-------------------------------------------------------------------------------------------------// - String GLXGLSupport::getDisplayName(void) - { - return String((const char*)XDisplayName(DisplayString(mGLDisplay))); - } - - //-------------------------------------------------------------------------------------------------// - GLXFBConfig* GLXGLSupport::chooseFBConfig(const GLint *attribList, GLint *nElements) - { - GLXFBConfig *fbConfigs; - - if (GLXEW_VERSION_1_3) - fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements); - else - fbConfigs = glXChooseFBConfigSGIX(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements); - - return fbConfigs; - } - - //-------------------------------------------------------------------------------------------------// - ::GLXContext GLXGLSupport::createNewContext(GLXFBConfig fbConfig, GLint renderType, ::GLXContext shareList, GLboolean direct) const - { - ::GLXContext glxContext; - - if (GLXEW_VERSION_1_3) - glxContext = glXCreateNewContext(mGLDisplay, fbConfig, renderType, shareList, direct); - else - glxContext = glXCreateContextWithConfigSGIX(mGLDisplay, fbConfig, renderType, shareList, direct); - - return glxContext; - } - - //-------------------------------------------------------------------------------------------------// - GLint GLXGLSupport::getFBConfigAttrib(GLXFBConfig fbConfig, GLint attribute, GLint *value) - { - GLint status; - - if (GLXEW_VERSION_1_3) - status = glXGetFBConfigAttrib(mGLDisplay, fbConfig, attribute, value); - else - status = glXGetFBConfigAttribSGIX(mGLDisplay, fbConfig, attribute, value); - - return status; - } - - //-------------------------------------------------------------------------------------------------// - XVisualInfo* GLXGLSupport::getVisualFromFBConfig(GLXFBConfig fbConfig) - { - XVisualInfo *visualInfo; - - if (GLXEW_VERSION_1_3) - visualInfo = glXGetVisualFromFBConfig(mGLDisplay, fbConfig); - else - visualInfo = glXGetVisualFromFBConfigSGIX(mGLDisplay, fbConfig); - - return visualInfo; - } - - //-------------------------------------------------------------------------------------------------// - void GLXGLSupport::switchMode(uint& width, uint& height, short& frequency) - { - int size = 0; - int newSize = -1; - - VideoModes::iterator mode; - VideoModes::iterator end = mVideoModes.end(); - VideoMode *newMode = 0; - - for(mode = mVideoModes.begin(); mode != end; size++) - { - if (mode->first.first >= width && - mode->first.second >= height) - { - if (! newMode || - mode->first.first < newMode->first.first || - mode->first.second < newMode->first.second) - { - newSize = size; - newMode = &(*mode); - } - } - - VideoMode *lastMode = &(*mode); - - while (++mode != end && mode->first == lastMode->first) - { - if (lastMode == newMode && mode->second == frequency) - { - newMode = &(*mode); - } - } - } - - if (newMode && *newMode != mCurrentMode) - { - XRRScreenConfiguration *screenConfig = XRRGetScreenInfo (mXDisplay, DefaultRootWindow(mXDisplay)); - - if (screenConfig) - { - Rotation currentRotation; - - XRRConfigCurrentConfiguration (screenConfig, ¤tRotation); - - XRRSetScreenConfigAndRate(mXDisplay, screenConfig, DefaultRootWindow(mXDisplay), newSize, currentRotation, newMode->second, CurrentTime); - - XRRFreeScreenConfigInfo(screenConfig); - - mCurrentMode = *newMode; - - LogManager::getSingleton().logMessage("Entered video mode " + StringConverter::toString(mCurrentMode.first.first) + "x" + StringConverter::toString(mCurrentMode.first.second) + " @ " + StringConverter::toString(mCurrentMode.second) + "Hz"); - } - } - } - - //-------------------------------------------------------------------------------------------------// - void GLXGLSupport::switchMode(void) - { - return switchMode(mOriginalMode.first.first, mOriginalMode.first.second, mOriginalMode.second); - } - - //-------------------------------------------------------------------------------------------------// - // Initialise GLXEW - // - // Overloading glXGetCurrentDisplay allows us to call glxewContextInit - // before establishing a GL context. This approach is a bit of a hack, - // but it minimises the patches required between glew.c and glew.cpp. - - void GLXGLSupport::initialiseGLXEW(void) - { - _currentDisplay = mGLDisplay; - - glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)_getCurrentDisplay; - + try + { + // Try to load image + image.load(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + if(image.getFormat() != PF_A8R8G8B8) + { + // Image format must be RGBA + return false; + } + + width = image.getWidth(); + height = image.getHeight(); + imageData = (char*)image.getData(); + } + catch(Exception &e) + { + // Could not find image; never mind + return false; + } + + int bitmapLineLength = (width + 7) / 8; + int pixmapLineLength = 4 * width; + + char* bitmapData = (char*)malloc(bitmapLineLength * height); + char* pixmapData = (char*)malloc(pixmapLineLength * height); + + int sptr = 0, dptr = 0; + + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + if (ImageByteOrder(mXDisplay) == MSBFirst) + { + pixmapData[dptr + 0] = 0; + pixmapData[dptr + 1] = imageData[sptr + 0]; + pixmapData[dptr + 2] = imageData[sptr + 1]; + pixmapData[dptr + 3] = imageData[sptr + 2]; + } + else + { + pixmapData[dptr + 3] = 0; + pixmapData[dptr + 2] = imageData[sptr + 0]; + pixmapData[dptr + 1] = imageData[sptr + 1]; + pixmapData[dptr + 0] = imageData[sptr + 2]; + } + + if(((unsigned char)imageData[sptr + 3])<128) + { + bitmapData[y*bitmapLineLength+(x>>3)] &= ~(1<<(x&7)); + } + else + { + bitmapData[y*bitmapLineLength+(x>>3)] |= 1<<(x&7); + } + sptr += 4; + dptr += 4; + } + } + + // Create bitmap on server and copy over bitmapData + *bitmap = XCreateBitmapFromData(mXDisplay, DefaultRootWindow(mXDisplay), bitmapData, width, height); + + free(bitmapData); + + // Create pixmap on server and copy over pixmapData (via pixmapXImage) + *pixmap = XCreatePixmap(mXDisplay, DefaultRootWindow(mXDisplay), width, height, 24); + + GC gc = XCreateGC (mXDisplay, DefaultRootWindow(mXDisplay), 0, NULL); + XImage *pixmapXImage = XCreateImage(mXDisplay, NULL, 24, ZPixmap, 0, pixmapData, width, height, 8, width*4); + XPutImage(mXDisplay, *pixmap, gc, pixmapXImage, 0, 0, 0, 0, width, height); + XDestroyImage(pixmapXImage); + XFreeGC(mXDisplay, gc); + + return true; + } + + //-------------------------------------------------------------------------------------------------// + Display* GLXGLSupport::getGLDisplay(void) + { + if (! mGLDisplay) + { + glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)getProcAddress("glXGetCurrentDisplay"); + + mGLDisplay = glXGetCurrentDisplay(); + mIsExternalDisplay = true; + + if (! mGLDisplay) + { + mGLDisplay = XOpenDisplay(0); + mIsExternalDisplay = false; + } + + if(! mGLDisplay) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn`t open X display " + String((const char*)XDisplayName (0)), "GLXGLSupport::getGLDisplay"); + } + + initialiseGLXEW(); + + if (! GLXEW_VERSION_1_3 && ! (GLXEW_SGIX_fbconfig && GLXEW_EXT_import_context)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "No GLX FBConfig support on your display", "GLXGLSupport::GLXGLSupport"); + } + } + + return mGLDisplay; + } + + //-------------------------------------------------------------------------------------------------// + Display* GLXGLSupport::getXDisplay(void) + { + if (! mXDisplay) + { + char* displayString = mGLDisplay ? DisplayString(mGLDisplay) : 0; + + mXDisplay = XOpenDisplay(displayString); + + if (! mXDisplay) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn`t open X display " + String((const char*)displayString), "GLXGLSupport::getXDisplay"); + } + + mAtomDeleteWindow = XInternAtom(mXDisplay, "WM_DELETE_WINDOW", True); + mAtomFullScreen = XInternAtom(mXDisplay, "_NET_WM_STATE_FULLSCREEN", True); + mAtomState = XInternAtom(mXDisplay, "_NET_WM_STATE", True); + } + + return mXDisplay; + } + + //-------------------------------------------------------------------------------------------------// + String GLXGLSupport::getDisplayName(void) + { + return String((const char*)XDisplayName(DisplayString(mGLDisplay))); + } + + //-------------------------------------------------------------------------------------------------// + GLXFBConfig* GLXGLSupport::chooseFBConfig(const GLint *attribList, GLint *nElements) + { + GLXFBConfig *fbConfigs; + + if (GLXEW_VERSION_1_3) + fbConfigs = glXChooseFBConfig(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements); + else + fbConfigs = glXChooseFBConfigSGIX(mGLDisplay, DefaultScreen(mGLDisplay), attribList, nElements); + + return fbConfigs; + } + + //-------------------------------------------------------------------------------------------------// + ::GLXContext GLXGLSupport::createNewContext(GLXFBConfig fbConfig, GLint renderType, ::GLXContext shareList, GLboolean direct) const + { + ::GLXContext glxContext; + + if (GLXEW_VERSION_1_3) + glxContext = glXCreateNewContext(mGLDisplay, fbConfig, renderType, shareList, direct); + else + glxContext = glXCreateContextWithConfigSGIX(mGLDisplay, fbConfig, renderType, shareList, direct); + + return glxContext; + } + + //-------------------------------------------------------------------------------------------------// + GLint GLXGLSupport::getFBConfigAttrib(GLXFBConfig fbConfig, GLint attribute, GLint *value) + { + GLint status; + + if (GLXEW_VERSION_1_3) + status = glXGetFBConfigAttrib(mGLDisplay, fbConfig, attribute, value); + else + status = glXGetFBConfigAttribSGIX(mGLDisplay, fbConfig, attribute, value); + + return status; + } + + //-------------------------------------------------------------------------------------------------// + XVisualInfo* GLXGLSupport::getVisualFromFBConfig(GLXFBConfig fbConfig) + { + XVisualInfo *visualInfo; + + if (GLXEW_VERSION_1_3) + visualInfo = glXGetVisualFromFBConfig(mGLDisplay, fbConfig); + else + visualInfo = glXGetVisualFromFBConfigSGIX(mGLDisplay, fbConfig); + + return visualInfo; + } + + //-------------------------------------------------------------------------------------------------// + void GLXGLSupport::switchMode(uint& width, uint& height, short& frequency) + { + int size = 0; + int newSize = -1; + + VideoModes::iterator mode; + VideoModes::iterator end = mVideoModes.end(); + VideoMode *newMode = 0; + + for(mode = mVideoModes.begin(); mode != end; size++) + { + if (mode->first.first >= width && + mode->first.second >= height) + { + if (! newMode || + mode->first.first < newMode->first.first || + mode->first.second < newMode->first.second) + { + newSize = size; + newMode = &(*mode); + } + } + + VideoMode *lastMode = &(*mode); + + while (++mode != end && mode->first == lastMode->first) + { + if (lastMode == newMode && mode->second == frequency) + { + newMode = &(*mode); + } + } + } + + if (newMode && *newMode != mCurrentMode) + { + XRRScreenConfiguration *screenConfig = XRRGetScreenInfo (mXDisplay, DefaultRootWindow(mXDisplay)); + + if (screenConfig) + { + Rotation currentRotation; + + XRRConfigCurrentConfiguration (screenConfig, ¤tRotation); + + XRRSetScreenConfigAndRate(mXDisplay, screenConfig, DefaultRootWindow(mXDisplay), newSize, currentRotation, newMode->second, CurrentTime); + + XRRFreeScreenConfigInfo(screenConfig); + + mCurrentMode = *newMode; + + LogManager::getSingleton().logMessage("Entered video mode " + StringConverter::toString(mCurrentMode.first.first) + "x" + StringConverter::toString(mCurrentMode.first.second) + " @ " + StringConverter::toString(mCurrentMode.second) + "Hz"); + } + } + } + + //-------------------------------------------------------------------------------------------------// + void GLXGLSupport::switchMode(void) + { + return switchMode(mOriginalMode.first.first, mOriginalMode.first.second, mOriginalMode.second); + } + + //-------------------------------------------------------------------------------------------------// + // Initialise GLXEW + // + // Overloading glXGetCurrentDisplay allows us to call glxewContextInit + // before establishing a GL context. This approach is a bit of a hack, + // but it minimises the patches required between glew.c and glew.cpp. + + void GLXGLSupport::initialiseGLXEW(void) + { + _currentDisplay = mGLDisplay; + + glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)_getCurrentDisplay; + #if OGRE_THREAD_SUPPORT != 1 - if (glxewContextInit(this) != GLEW_OK) + if (glxewContextInit(this) != GLEW_OK) #else - if (glxewContextInit(glxewGetContext()) != GLEW_OK) + if (glxewContextInit(glxewGetContext()) != GLEW_OK) #endif - { - XCloseDisplay (mGLDisplay); - XCloseDisplay (mXDisplay); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "No GLX 1.1 support on your platform", "GLXGLSupport::initialiseGLXEW"); - } - - glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)getProcAddress("glXGetCurrentDisplay"); - } + { + XCloseDisplay (mGLDisplay); + XCloseDisplay (mXDisplay); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "No GLX 1.1 support on your platform", "GLXGLSupport::initialiseGLXEW"); + } + + glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)getProcAddress("glXGetCurrentDisplay"); + } #if OGRE_THREAD_SUPPORT == 1 - GLXEWContext* glxewGetContext() - { - using namespace Ogre; - static OGRE_THREAD_POINTER_VAR(GLXEWContext, GLXEWContextsPtr); - - GLXEWContext * currentGLXEWContextsPtr = OGRE_THREAD_POINTER_GET(GLXEWContextsPtr); - if (currentGLXEWContextsPtr == NULL) - { - currentGLXEWContextsPtr = new GLXEWContext(); - OGRE_THREAD_POINTER_SET(GLXEWContextsPtr, currentGLXEWContextsPtr); - memset(currentGLXEWContextsPtr, 0, sizeof(GLXEWContext)); - glxewInit(); - } - return currentGLXEWContextsPtr; - } + GLXEWContext* glxewGetContext() + { + using namespace Ogre; + static OGRE_THREAD_POINTER_VAR(GLXEWContext, GLXEWContextsPtr); + + GLXEWContext * currentGLXEWContextsPtr = OGRE_THREAD_POINTER_GET(GLXEWContextsPtr); + if (currentGLXEWContextsPtr == NULL) + { + currentGLXEWContextsPtr = new GLXEWContext(); + OGRE_THREAD_POINTER_SET(GLXEWContextsPtr, currentGLXEWContextsPtr); + memset(currentGLXEWContextsPtr, 0, sizeof(GLXEWContext)); + glxewInit(); + } + return currentGLXEWContextsPtr; + } #endif } diff --git a/RenderSystems/GL/src/GLX/OgreGLXRenderTexture.cpp b/RenderSystems/GL/src/GLX/OgreGLXRenderTexture.cpp index c39a8f5a97b..133e966fdd0 100644 --- a/RenderSystems/GL/src/GLX/OgreGLXRenderTexture.cpp +++ b/RenderSystems/GL/src/GLX/OgreGLXRenderTexture.cpp @@ -43,127 +43,127 @@ THE SOFTWARE. namespace Ogre { - //-------------------------------------------------------------------------------------------------// - GLXPBuffer::GLXPBuffer(GLXGLSupport* glsupport, PixelComponentType format, size_t width, size_t height): - GLPBuffer(format, width, height), mContext(0), mGLSupport(glsupport) - { - Display *glDisplay = mGLSupport->getGLDisplay(); - ::GLXDrawable glxDrawable = 0; - ::GLXFBConfig fbConfig = 0; - - int bits = 0; - - switch (mFormat) - { - case PCT_BYTE: - bits = 8; - break; - - case PCT_SHORT: - bits = 16; - break; - - case PCT_FLOAT16: - bits = 16; - break; - - case PCT_FLOAT32: - bits = 32; - break; - - default: - break; - } - - int renderAttrib = GLX_RENDER_TYPE; - int renderValue = GLX_RGBA_BIT; - - if (mFormat == PCT_FLOAT16 || mFormat == PCT_FLOAT32) - { - if (GLXEW_NV_float_buffer) - { - renderAttrib = GLX_FLOAT_COMPONENTS_NV; - renderValue = GL_TRUE; - } - - if (GLXEW_ATI_pixel_format_float) - { - renderAttrib = GLX_RENDER_TYPE; - renderValue = GLX_RGBA_FLOAT_ATI_BIT; - } - - if (GLXEW_ARB_fbconfig_float) - { - renderAttrib = GLX_RENDER_TYPE; - renderValue = GLX_RGBA_FLOAT_BIT; - } - - if (renderAttrib == GLX_RENDER_TYPE && renderValue == GLX_RGBA_BIT) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "No support for Floating point PBuffers", "GLRenderTexture::createPBuffer"); - } - } - - int minAttribs[] = { - GLX_DRAWABLE_TYPE, GLX_PBUFFER, - renderAttrib, renderValue, - GLX_DOUBLEBUFFER, 0, - None - }; - - int maxAttribs[] = { - GLX_RED_SIZE, bits, - GLX_GREEN_SIZE, bits, - GLX_BLUE_SIZE, bits, - GLX_ALPHA_SIZE, bits, - GLX_STENCIL_SIZE, INT_MAX, - None - }; - - int pBufferAttribs[] = { - GLX_PBUFFER_WIDTH, (int)mWidth, - GLX_PBUFFER_HEIGHT, (int)mHeight, - GLX_PRESERVED_CONTENTS, GL_TRUE, - None - }; - - fbConfig = mGLSupport->selectFBConfig(minAttribs, maxAttribs); - - glxDrawable = glXCreatePbuffer(glDisplay, fbConfig, pBufferAttribs); - - if (! fbConfig || ! glxDrawable) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create Pbuffer", "GLXPBuffer::GLXPBuffer"); - } - - GLint fbConfigID; - GLuint iWidth, iHeight; - - glXGetFBConfigAttrib(glDisplay, fbConfig, GLX_FBCONFIG_ID, &fbConfigID); - glXQueryDrawable(glDisplay, glxDrawable, GLX_WIDTH, &iWidth); - glXQueryDrawable(glDisplay, glxDrawable, GLX_HEIGHT, &iHeight); - - mWidth = iWidth; - mHeight = iHeight; - LogManager::getSingleton().logMessage(LML_NORMAL, "GLXPBuffer::create used final dimensions " + StringConverter::toString(mWidth) + " x " + StringConverter::toString(mHeight)); - LogManager::getSingleton().logMessage("GLXPBuffer::create used FBConfigID " + StringConverter::toString(fbConfigID)); - - mContext = new GLXContext(mGLSupport, fbConfig, glxDrawable); - } - - //-------------------------------------------------------------------------------------------------// - GLXPBuffer::~GLXPBuffer() - { - glXDestroyPbuffer(mGLSupport->getGLDisplay(), mContext->mDrawable); - - delete mContext; - - LogManager::getSingleton().logMessage(LML_NORMAL, "GLXPBuffer::PBuffer destroyed"); - } - - //-------------------------------------------------------------------------------------------------// - GLContext *GLXPBuffer::getContext() - { - return mContext; - } + //-------------------------------------------------------------------------------------------------// + GLXPBuffer::GLXPBuffer(GLXGLSupport* glsupport, PixelComponentType format, size_t width, size_t height): + GLPBuffer(format, width, height), mContext(0), mGLSupport(glsupport) + { + Display *glDisplay = mGLSupport->getGLDisplay(); + ::GLXDrawable glxDrawable = 0; + ::GLXFBConfig fbConfig = 0; + + int bits = 0; + + switch (mFormat) + { + case PCT_BYTE: + bits = 8; + break; + + case PCT_SHORT: + bits = 16; + break; + + case PCT_FLOAT16: + bits = 16; + break; + + case PCT_FLOAT32: + bits = 32; + break; + + default: + break; + } + + int renderAttrib = GLX_RENDER_TYPE; + int renderValue = GLX_RGBA_BIT; + + if (mFormat == PCT_FLOAT16 || mFormat == PCT_FLOAT32) + { + if (GLXEW_NV_float_buffer) + { + renderAttrib = GLX_FLOAT_COMPONENTS_NV; + renderValue = GL_TRUE; + } + + if (GLXEW_ATI_pixel_format_float) + { + renderAttrib = GLX_RENDER_TYPE; + renderValue = GLX_RGBA_FLOAT_ATI_BIT; + } + + if (GLXEW_ARB_fbconfig_float) + { + renderAttrib = GLX_RENDER_TYPE; + renderValue = GLX_RGBA_FLOAT_BIT; + } + + if (renderAttrib == GLX_RENDER_TYPE && renderValue == GLX_RGBA_BIT) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "No support for Floating point PBuffers", "GLRenderTexture::createPBuffer"); + } + } + + int minAttribs[] = { + GLX_DRAWABLE_TYPE, GLX_PBUFFER, + renderAttrib, renderValue, + GLX_DOUBLEBUFFER, 0, + None + }; + + int maxAttribs[] = { + GLX_RED_SIZE, bits, + GLX_GREEN_SIZE, bits, + GLX_BLUE_SIZE, bits, + GLX_ALPHA_SIZE, bits, + GLX_STENCIL_SIZE, INT_MAX, + None + }; + + int pBufferAttribs[] = { + GLX_PBUFFER_WIDTH, (int)mWidth, + GLX_PBUFFER_HEIGHT, (int)mHeight, + GLX_PRESERVED_CONTENTS, GL_TRUE, + None + }; + + fbConfig = mGLSupport->selectFBConfig(minAttribs, maxAttribs); + + glxDrawable = glXCreatePbuffer(glDisplay, fbConfig, pBufferAttribs); + + if (! fbConfig || ! glxDrawable) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create Pbuffer", "GLXPBuffer::GLXPBuffer"); + } + + GLint fbConfigID; + GLuint iWidth, iHeight; + + glXGetFBConfigAttrib(glDisplay, fbConfig, GLX_FBCONFIG_ID, &fbConfigID); + glXQueryDrawable(glDisplay, glxDrawable, GLX_WIDTH, &iWidth); + glXQueryDrawable(glDisplay, glxDrawable, GLX_HEIGHT, &iHeight); + + mWidth = iWidth; + mHeight = iHeight; + LogManager::getSingleton().logMessage(LML_NORMAL, "GLXPBuffer::create used final dimensions " + StringConverter::toString(mWidth) + " x " + StringConverter::toString(mHeight)); + LogManager::getSingleton().logMessage("GLXPBuffer::create used FBConfigID " + StringConverter::toString(fbConfigID)); + + mContext = new GLXContext(mGLSupport, fbConfig, glxDrawable); + } + + //-------------------------------------------------------------------------------------------------// + GLXPBuffer::~GLXPBuffer() + { + glXDestroyPbuffer(mGLSupport->getGLDisplay(), mContext->mDrawable); + + delete mContext; + + LogManager::getSingleton().logMessage(LML_NORMAL, "GLXPBuffer::PBuffer destroyed"); + } + + //-------------------------------------------------------------------------------------------------// + GLContext *GLXPBuffer::getContext() + { + return mContext; + } } diff --git a/RenderSystems/GL/src/GLX/OgreGLXWindow.cpp b/RenderSystems/GL/src/GLX/OgreGLXWindow.cpp index ee05f5b1efb..d9fd4e5bd85 100644 --- a/RenderSystems/GL/src/GLX/OgreGLXWindow.cpp +++ b/RenderSystems/GL/src/GLX/OgreGLXWindow.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- This source file is part of OGRE - (Object-oriented Graphics Rendering Engine) + (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd @@ -51,738 +51,738 @@ THE SOFTWARE. extern "C" { - int - safeXErrorHandler (Display *display, XErrorEvent *event) - { - // Ignore all XErrorEvents - return 0; - } - int (*oldXErrorHandler)(Display *, XErrorEvent*); + int + safeXErrorHandler (Display *display, XErrorEvent *event) + { + // Ignore all XErrorEvents + return 0; + } + int (*oldXErrorHandler)(Display *, XErrorEvent*); } namespace Ogre { - //-------------------------------------------------------------------------------------------------// - GLXWindow::GLXWindow(GLXGLSupport *glsupport) : - mGLSupport(glsupport), mContext(0) - { - mWindow = 0; - - mIsTopLevel = false; - mIsFullScreen = false; - mIsExternal = false; - mIsExternalGLControl = false; - mClosed = false; - mActive = false; - mHidden = false; - mVSync = false; - mVSyncInterval = 1; - } - - //-------------------------------------------------------------------------------------------------// - GLXWindow::~GLXWindow() - { - Display* xDisplay = mGLSupport->getXDisplay(); - - destroy(); - - // Ignore fatal XErrorEvents from stale handles. - oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); - - if (mWindow) - { - XDestroyWindow(xDisplay, mWindow); - } - - if (mContext) - { - delete mContext; - } - - XSetErrorHandler(oldXErrorHandler); - - mContext = 0; - mWindow = 0; - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::create(const String& name, uint width, uint height, - bool fullScreen, const NameValuePairList *miscParams) - { - Display *xDisplay = mGLSupport->getXDisplay(); - String title = name; - uint samples = 0; - short frequency = 0; - bool vsync = false; - bool hidden = false; - unsigned int vsyncInterval = 1; - int gamma = 0; - ::GLXContext glxContext = 0; - ::GLXDrawable glxDrawable = 0; - Window externalWindow = 0; - Window parentWindow = DefaultRootWindow(xDisplay); - int left = DisplayWidth(xDisplay, DefaultScreen(xDisplay))/2 - width/2; - int top = DisplayHeight(xDisplay, DefaultScreen(xDisplay))/2 - height/2; - String border; - - mIsFullScreen = fullScreen; - - if(miscParams) - { - NameValuePairList::const_iterator opt; - NameValuePairList::const_iterator end = miscParams->end(); - - // NB: Do not try to implement the externalGLContext option. - // - // Accepting a non-current context would expose us to the - // risk of segfaults when we made it current. Since the - // application programmers would be responsible for these - // segfaults, they are better discovering them in their code. - - if ((opt = miscParams->find("currentGLContext")) != end && - StringConverter::parseBool(opt->second)) - { - if (! glXGetCurrentContext()) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "currentGLContext was specified with no current GL context", "GLXWindow::create"); - } - - glxContext = glXGetCurrentContext(); - glxDrawable = glXGetCurrentDrawable(); - } - - // Note: Some platforms support AA inside ordinary windows - if((opt = miscParams->find("FSAA")) != end) - samples = StringConverter::parseUnsignedInt(opt->second); - - if((opt = miscParams->find("displayFrequency")) != end) - frequency = (short)StringConverter::parseInt(opt->second); - - if((opt = miscParams->find("vsync")) != end) - vsync = StringConverter::parseBool(opt->second); - - if((opt = miscParams->find("hidden")) != end) - hidden = StringConverter::parseBool(opt->second); - - if((opt = miscParams->find("vsyncInterval")) != end) - vsyncInterval = StringConverter::parseUnsignedInt(opt->second); - - if ((opt = miscParams->find("gamma")) != end) - gamma = StringConverter::parseBool(opt->second); - - if((opt = miscParams->find("left")) != end) - left = StringConverter::parseInt(opt->second); - - if((opt = miscParams->find("top")) != end) - top = StringConverter::parseInt(opt->second); - - if((opt = miscParams->find("title")) != end) - title = opt->second; - - if ((opt = miscParams->find("externalGLControl")) != end) - mIsExternalGLControl = StringConverter::parseBool(opt->second); - - if((opt = miscParams->find("parentWindowHandle")) != end) - { - vector::type tokens = StringUtil::split(opt->second, " :"); - - if (tokens.size() == 3) - { - // deprecated display:screen:xid format - parentWindow = StringConverter::parseUnsignedLong(tokens[2]); - } - else - { - // xid format - parentWindow = StringConverter::parseUnsignedLong(tokens[0]); - } - } - else if((opt = miscParams->find("externalWindowHandle")) != end) - { - vector::type tokens = StringUtil::split(opt->second, " :"); - - LogManager::getSingleton().logMessage( - "GLXWindow::create: The externalWindowHandle parameter is deprecated.\n" - "Use the parentWindowHandle or currentGLContext parameter instead."); - - if (tokens.size() == 3) - { - // Old display:screen:xid format - // The old GLX code always created a "parent" window in this case: - parentWindow = StringConverter::parseUnsignedLong(tokens[2]); - } - else if (tokens.size() == 4) - { - // Old display:screen:xid:visualinfo format - externalWindow = StringConverter::parseUnsignedLong(tokens[2]); - } - else - { - // xid format - externalWindow = StringConverter::parseUnsignedLong(tokens[0]); - } - } - - if ((opt = miscParams->find("border")) != end) - border = opt->second; - } - - // Ignore fatal XErrorEvents during parameter validation: - oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); - // Validate parentWindowHandle - - if (parentWindow != DefaultRootWindow(xDisplay)) - { - XWindowAttributes windowAttrib; - - if (! XGetWindowAttributes(xDisplay, parentWindow, &windowAttrib) || - windowAttrib.root != DefaultRootWindow(xDisplay)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid parentWindowHandle (wrong server or screen)", "GLXWindow::create"); - } - } - - // Validate externalWindowHandle - - if (externalWindow != 0) - { - XWindowAttributes windowAttrib; - - if (! XGetWindowAttributes(xDisplay, externalWindow, &windowAttrib) || - windowAttrib.root != DefaultRootWindow(xDisplay)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid externalWindowHandle (wrong server or screen)", "GLXWindow::create"); - } - glxDrawable = externalWindow; - } - - // Derive fbConfig - - ::GLXFBConfig fbConfig = 0; - - if (glxDrawable) - { - fbConfig = mGLSupport->getFBConfigFromDrawable (glxDrawable, &width, &height); - } - - if (! fbConfig && glxContext) - { - fbConfig = mGLSupport->getFBConfigFromContext (glxContext); - } - - mIsExternal = (glxDrawable != 0); - - XSetErrorHandler(oldXErrorHandler); - - if (! fbConfig) - { - int minAttribs[] = { - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_RED_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_GREEN_SIZE, 1, - None - }; - - int maxAttribs[] = { - GLX_SAMPLES, static_cast(samples), - GLX_DOUBLEBUFFER, 1, - GLX_STENCIL_SIZE, INT_MAX, - GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, 1, - None - }; - - fbConfig = mGLSupport->selectFBConfig(minAttribs, maxAttribs); - - // Now check the actual supported fsaa value - GLint maxSamples; - mGLSupport->getFBConfigAttrib(fbConfig, GLX_SAMPLES, &maxSamples); - mFSAA = maxSamples; - - if (gamma != 0) - { - mGLSupport->getFBConfigAttrib(fbConfig, GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &gamma); - } - - mHwGamma = (gamma != 0); - } - + //-------------------------------------------------------------------------------------------------// + GLXWindow::GLXWindow(GLXGLSupport *glsupport) : + mGLSupport(glsupport), mContext(0) + { + mWindow = 0; + + mIsTopLevel = false; + mIsFullScreen = false; + mIsExternal = false; + mIsExternalGLControl = false; + mClosed = false; + mActive = false; + mHidden = false; + mVSync = false; + mVSyncInterval = 1; + } + + //-------------------------------------------------------------------------------------------------// + GLXWindow::~GLXWindow() + { + Display* xDisplay = mGLSupport->getXDisplay(); + + destroy(); + + // Ignore fatal XErrorEvents from stale handles. + oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); + + if (mWindow) + { + XDestroyWindow(xDisplay, mWindow); + } + + if (mContext) + { + delete mContext; + } + + XSetErrorHandler(oldXErrorHandler); + + mContext = 0; + mWindow = 0; + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::create(const String& name, uint width, uint height, + bool fullScreen, const NameValuePairList *miscParams) + { + Display *xDisplay = mGLSupport->getXDisplay(); + String title = name; + uint samples = 0; + short frequency = 0; + bool vsync = false; + bool hidden = false; + unsigned int vsyncInterval = 1; + int gamma = 0; + ::GLXContext glxContext = 0; + ::GLXDrawable glxDrawable = 0; + Window externalWindow = 0; + Window parentWindow = DefaultRootWindow(xDisplay); + int left = DisplayWidth(xDisplay, DefaultScreen(xDisplay))/2 - width/2; + int top = DisplayHeight(xDisplay, DefaultScreen(xDisplay))/2 - height/2; + String border; + + mIsFullScreen = fullScreen; + + if(miscParams) + { + NameValuePairList::const_iterator opt; + NameValuePairList::const_iterator end = miscParams->end(); + + // NB: Do not try to implement the externalGLContext option. + // + // Accepting a non-current context would expose us to the + // risk of segfaults when we made it current. Since the + // application programmers would be responsible for these + // segfaults, they are better discovering them in their code. + + if ((opt = miscParams->find("currentGLContext")) != end && + StringConverter::parseBool(opt->second)) + { + if (! glXGetCurrentContext()) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "currentGLContext was specified with no current GL context", "GLXWindow::create"); + } + + glxContext = glXGetCurrentContext(); + glxDrawable = glXGetCurrentDrawable(); + } + + // Note: Some platforms support AA inside ordinary windows + if((opt = miscParams->find("FSAA")) != end) + samples = StringConverter::parseUnsignedInt(opt->second); + + if((opt = miscParams->find("displayFrequency")) != end) + frequency = (short)StringConverter::parseInt(opt->second); + + if((opt = miscParams->find("vsync")) != end) + vsync = StringConverter::parseBool(opt->second); + + if((opt = miscParams->find("hidden")) != end) + hidden = StringConverter::parseBool(opt->second); + + if((opt = miscParams->find("vsyncInterval")) != end) + vsyncInterval = StringConverter::parseUnsignedInt(opt->second); + + if ((opt = miscParams->find("gamma")) != end) + gamma = StringConverter::parseBool(opt->second); + + if((opt = miscParams->find("left")) != end) + left = StringConverter::parseInt(opt->second); + + if((opt = miscParams->find("top")) != end) + top = StringConverter::parseInt(opt->second); + + if((opt = miscParams->find("title")) != end) + title = opt->second; + + if ((opt = miscParams->find("externalGLControl")) != end) + mIsExternalGLControl = StringConverter::parseBool(opt->second); + + if((opt = miscParams->find("parentWindowHandle")) != end) + { + vector::type tokens = StringUtil::split(opt->second, " :"); + + if (tokens.size() == 3) + { + // deprecated display:screen:xid format + parentWindow = StringConverter::parseUnsignedLong(tokens[2]); + } + else + { + // xid format + parentWindow = StringConverter::parseUnsignedLong(tokens[0]); + } + } + else if((opt = miscParams->find("externalWindowHandle")) != end) + { + vector::type tokens = StringUtil::split(opt->second, " :"); + + LogManager::getSingleton().logMessage( + "GLXWindow::create: The externalWindowHandle parameter is deprecated.\n" + "Use the parentWindowHandle or currentGLContext parameter instead."); + + if (tokens.size() == 3) + { + // Old display:screen:xid format + // The old GLX code always created a "parent" window in this case: + parentWindow = StringConverter::parseUnsignedLong(tokens[2]); + } + else if (tokens.size() == 4) + { + // Old display:screen:xid:visualinfo format + externalWindow = StringConverter::parseUnsignedLong(tokens[2]); + } + else + { + // xid format + externalWindow = StringConverter::parseUnsignedLong(tokens[0]); + } + } + + if ((opt = miscParams->find("border")) != end) + border = opt->second; + } + + // Ignore fatal XErrorEvents during parameter validation: + oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); + // Validate parentWindowHandle + + if (parentWindow != DefaultRootWindow(xDisplay)) + { + XWindowAttributes windowAttrib; + + if (! XGetWindowAttributes(xDisplay, parentWindow, &windowAttrib) || + windowAttrib.root != DefaultRootWindow(xDisplay)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid parentWindowHandle (wrong server or screen)", "GLXWindow::create"); + } + } + + // Validate externalWindowHandle + + if (externalWindow != 0) + { + XWindowAttributes windowAttrib; + + if (! XGetWindowAttributes(xDisplay, externalWindow, &windowAttrib) || + windowAttrib.root != DefaultRootWindow(xDisplay)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid externalWindowHandle (wrong server or screen)", "GLXWindow::create"); + } + glxDrawable = externalWindow; + } + + // Derive fbConfig + + ::GLXFBConfig fbConfig = 0; + + if (glxDrawable) + { + fbConfig = mGLSupport->getFBConfigFromDrawable (glxDrawable, &width, &height); + } + + if (! fbConfig && glxContext) + { + fbConfig = mGLSupport->getFBConfigFromContext (glxContext); + } + + mIsExternal = (glxDrawable != 0); + + XSetErrorHandler(oldXErrorHandler); + + if (! fbConfig) + { + int minAttribs[] = { + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_RED_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_GREEN_SIZE, 1, + None + }; + + int maxAttribs[] = { + GLX_SAMPLES, static_cast(samples), + GLX_DOUBLEBUFFER, 1, + GLX_STENCIL_SIZE, INT_MAX, + GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, 1, + None + }; + + fbConfig = mGLSupport->selectFBConfig(minAttribs, maxAttribs); + + // Now check the actual supported fsaa value + GLint maxSamples; + mGLSupport->getFBConfigAttrib(fbConfig, GLX_SAMPLES, &maxSamples); + mFSAA = maxSamples; + + if (gamma != 0) + { + mGLSupport->getFBConfigAttrib(fbConfig, GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &gamma); + } + + mHwGamma = (gamma != 0); + } + if (! fbConfig) { // This should never happen. OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unexpected failure to determine a GLXFBConfig","GLXWindow::create"); } - - mIsTopLevel = (! mIsExternal && parentWindow == DefaultRootWindow(xDisplay)); - - if (! mIsTopLevel) - { - mIsFullScreen = false; - left = top = 0; - } - - if (mIsFullScreen) - { - mGLSupport->switchMode (width, height, frequency); - } - - if (! mIsExternal) - { - XSetWindowAttributes attr; - ulong mask; - XVisualInfo *visualInfo = mGLSupport->getVisualFromFBConfig (fbConfig); - - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap(xDisplay, DefaultRootWindow(xDisplay), visualInfo->visual, AllocNone); - attr.event_mask = StructureNotifyMask | VisibilityChangeMask | FocusChangeMask; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - - if(mIsFullScreen && mGLSupport->mAtomFullScreen == None) - { - LogManager::getSingleton().logMessage("GLXWindow::switchFullScreen: Your WM has no fullscreen support"); - - // A second best approach for outdated window managers - attr.backing_store = NotUseful; - attr.save_under = False; - attr.override_redirect = True; - mask |= CWSaveUnder | CWBackingStore | CWOverrideRedirect; - left = top = 0; - } - - // Create window on server - mWindow = XCreateWindow(xDisplay, parentWindow, left, top, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, mask, &attr); - - XFree(visualInfo); - - if(!mWindow) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create an X Window", "GLXWindow::create"); - } - - if (mIsTopLevel) - { - XWMHints *wmHints; - XSizeHints *sizeHints; - - if ((wmHints = XAllocWMHints()) != NULL) - { - wmHints->initial_state = NormalState; - wmHints->input = True; - wmHints->flags = StateHint | InputHint; - - int depth = DisplayPlanes(xDisplay, DefaultScreen(xDisplay)); - - // Check if we can give it an icon - if(depth == 24 || depth == 32) - { - if(mGLSupport->loadIcon("GLX_icon.png", &wmHints->icon_pixmap, &wmHints->icon_mask)) - { - wmHints->flags |= IconPixmapHint | IconMaskHint; - } - } - } - - if ((sizeHints = XAllocSizeHints()) != NULL) - { - // Is this really necessary ? Which broken WM might need it? - sizeHints->flags = USPosition; - - if(!fullScreen && border == "fixed") - { - sizeHints->min_width = sizeHints->max_width = width; - sizeHints->min_height = sizeHints->max_height = height; - sizeHints->flags |= PMaxSize | PMinSize; - } - } - - XTextProperty titleprop; - vector::type title_ (title.begin(), title.end()); - title_.push_back(0); - - char *lst = &title_[0]; - XStringListToTextProperty((char **)&lst, 1, &titleprop); - XSetWMProperties(xDisplay, mWindow, &titleprop, NULL, NULL, 0, sizeHints, wmHints, NULL); - - XFree(titleprop.value); - XFree(wmHints); - XFree(sizeHints); - - XSetWMProtocols(xDisplay, mWindow, &mGLSupport->mAtomDeleteWindow, 1); - - XWindowAttributes windowAttrib; - - XGetWindowAttributes(xDisplay, mWindow, &windowAttrib); - - left = windowAttrib.x; - top = windowAttrib.y; - width = windowAttrib.width; - height = windowAttrib.height; - } - - glxDrawable = mWindow; - - // setHidden takes care of mapping or unmapping the window - // and also calls setFullScreen if appropriate. - setHidden(hidden); - XFlush(xDisplay); - - WindowEventUtilities::_addRenderWindow(this); - } - - mContext = new GLXContext(mGLSupport, fbConfig, glxDrawable, glxContext); - - // apply vsync settings. call setVSyncInterval first to avoid - // setting vsync more than once. - setVSyncInterval(vsyncInterval); - setVSyncEnabled(vsync); - - int fbConfigID; - - mGLSupport->getFBConfigAttrib(fbConfig, GLX_FBCONFIG_ID, &fbConfigID); - - LogManager::getSingleton().logMessage("GLXWindow::create used FBConfigID = " + StringConverter::toString(fbConfigID)); - - mName = name; - mWidth = width; - mHeight = height; - mLeft = left; - mTop = top; - mActive = true; - mClosed = false; - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::destroy(void) - { - if (mClosed) - return; - - mClosed = true; - mActive = false; - - if (! mIsExternal) - WindowEventUtilities::_removeRenderWindow(this); - - if (mIsFullScreen) - { - mGLSupport->switchMode(); - switchFullScreen(false); - } - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::setFullscreen(bool fullscreen, uint width, uint height) - { - short frequency = 0; - - if (mClosed || ! mIsTopLevel) - return; - - if (fullscreen == mIsFullScreen && width == mWidth && height == mHeight) - return; - - if (mIsFullScreen != fullscreen && &mGLSupport->mAtomFullScreen == None) - { - // Without WM support it is best to give up. - LogManager::getSingleton().logMessage("GLXWindow::switchFullScreen: Your WM has no fullscreen support"); - return; - } - else if (fullscreen) - { - mGLSupport->switchMode(width, height, frequency); - } - else - { - mGLSupport->switchMode(); - } - - if (mIsFullScreen != fullscreen) - { - switchFullScreen(fullscreen); - } - - if (! mIsFullScreen) - { - resize(width, height); - reposition(mLeft, mTop); - } - } - - //-------------------------------------------------------------------------------------------------// - bool GLXWindow::isClosed() const - { - return mClosed; - } - - //-------------------------------------------------------------------------------------------------// - bool GLXWindow::isVisible() const - { - return mVisible; - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::setVisible(bool visible) - { - mVisible = visible; - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::setHidden(bool hidden) - { - mHidden = hidden; - // ignore for external windows as these should handle - // this externally - if (mIsExternal) - return; - - if (hidden) - { - XUnmapWindow(mGLSupport->getXDisplay(), mWindow); - } - else - { - XMapWindow(mGLSupport->getXDisplay(), mWindow); - if (mIsFullScreen) - { - switchFullScreen(true); - } - } - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::setVSyncInterval(unsigned int interval) - { - mVSyncInterval = interval; - if (mVSync) - setVSyncEnabled(true); - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::setVSyncEnabled(bool vsync) - { - mVSync = vsync; - // we need to make our context current to set vsync - // store previous context to restore when finished. - ::GLXDrawable oldDrawable = glXGetCurrentDrawable(); - ::GLXContext oldContext = glXGetCurrentContext(); - - mContext->setCurrent(); - - if (! mIsExternalGLControl) - { - if (GLXEW_MESA_swap_control) - glXSwapIntervalMESA (vsync ? mVSyncInterval : 0); - else if (GLXEW_EXT_swap_control) - glXSwapIntervalEXT (mGLSupport->getGLDisplay(), glXGetCurrentDrawable(), - vsync ? mVSyncInterval : 0); - else if (GLXEW_SGI_swap_control) - if (vsync && mVSyncInterval) - glXSwapIntervalSGI (mVSyncInterval); - } - - mContext->endCurrent(); - - glXMakeCurrent (mGLSupport->getGLDisplay(), oldDrawable, oldContext); - } - - //-------------------------------------------------------------------------------------------------// - bool GLXWindow::isVSyncEnabled() const - { - return mVSync; - } - - //-------------------------------------------------------------------------------------------------// - unsigned int GLXWindow::getVSyncInterval() const - { - return mVSyncInterval; - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::reposition(int left, int top) - { - if (mClosed || ! mIsTopLevel) - return; - - XMoveWindow(mGLSupport->getXDisplay(), mWindow, left, top); - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::resize(uint width, uint height) - { - if (mClosed) - return; - - if(mWidth == width && mHeight == height) - return; - - if(width != 0 && height != 0) - { - if (!mIsExternal) - { - XResizeWindow(mGLSupport->getXDisplay(), mWindow, width, height); - } - else - { - mWidth = width; - mHeight = height; - - for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) - (*it).second->_updateDimensions(); - } - } - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::windowMovedOrResized() - { - if (mClosed || !mWindow) - return; - - Display* xDisplay = mGLSupport->getXDisplay(); - XWindowAttributes windowAttrib; - - if (mIsTopLevel && !mIsFullScreen) - { - Window parent, root, *children; - uint nChildren; - - XQueryTree(xDisplay, mWindow, &root, &parent, &children, &nChildren); - - if (children) - XFree(children); - - XGetWindowAttributes(xDisplay, parent, &windowAttrib); - - mLeft = windowAttrib.x; - mTop = windowAttrib.y; - } - - XGetWindowAttributes(xDisplay, mWindow, &windowAttrib); - - if (mWidth == (unsigned)windowAttrib.width && mHeight == (unsigned)windowAttrib.height) - return; - - mWidth = windowAttrib.width; - mHeight = windowAttrib.height; - - for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) - (*it).second->_updateDimensions(); - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::swapBuffers() - { - if (mClosed || mIsExternalGLControl) - return; - - glXSwapBuffers(mGLSupport->getGLDisplay(), mContext->mDrawable); - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::getCustomAttribute( const String& name, void* pData ) - { - if( name == "DISPLAY NAME" ) - { - *static_cast(pData) = mGLSupport->getDisplayName(); - return; - } - else if( name == "DISPLAY" ) - { - *static_cast(pData) = mGLSupport->getGLDisplay(); - return; - } - else if( name == "GLCONTEXT" ) - { - *static_cast(pData) = mContext; - return; - } - else if( name == "XDISPLAY" ) - { - *static_cast(pData) = mGLSupport->getXDisplay(); - return; - } - else if( name == "ATOM" ) - { - *static_cast< ::Atom* >(pData) = mGLSupport->mAtomDeleteWindow; - return; - } - else if( name == "WINDOW" ) - { - *static_cast(pData) = mWindow; - return; - } - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) - { - if (mClosed) - return; - - if ((dst.right > mWidth) || - (dst.bottom > mHeight) || - (dst.front != 0) || (dst.back != 1)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid box.", "GLXWindow::copyContentsToMemory" ); - } - - if (buffer == FB_AUTO) - { - buffer = mIsFullScreen? FB_FRONT : FB_BACK; - } - - GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format); - GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format); - - if ((format == GL_NONE) || (type == 0)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported format.", "GLXWindow::copyContentsToMemory" ); - } - - // Switch context if different from current one - RenderSystem* rsys = Root::getSingleton().getRenderSystem(); - rsys->_setViewport(this->getViewport(0)); - + + mIsTopLevel = (! mIsExternal && parentWindow == DefaultRootWindow(xDisplay)); + + if (! mIsTopLevel) + { + mIsFullScreen = false; + left = top = 0; + } + + if (mIsFullScreen) + { + mGLSupport->switchMode (width, height, frequency); + } + + if (! mIsExternal) + { + XSetWindowAttributes attr; + ulong mask; + XVisualInfo *visualInfo = mGLSupport->getVisualFromFBConfig (fbConfig); + + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap(xDisplay, DefaultRootWindow(xDisplay), visualInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | VisibilityChangeMask | FocusChangeMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + if(mIsFullScreen && mGLSupport->mAtomFullScreen == None) + { + LogManager::getSingleton().logMessage("GLXWindow::switchFullScreen: Your WM has no fullscreen support"); + + // A second best approach for outdated window managers + attr.backing_store = NotUseful; + attr.save_under = False; + attr.override_redirect = True; + mask |= CWSaveUnder | CWBackingStore | CWOverrideRedirect; + left = top = 0; + } + + // Create window on server + mWindow = XCreateWindow(xDisplay, parentWindow, left, top, width, height, 0, visualInfo->depth, InputOutput, visualInfo->visual, mask, &attr); + + XFree(visualInfo); + + if(!mWindow) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unable to create an X Window", "GLXWindow::create"); + } + + if (mIsTopLevel) + { + XWMHints *wmHints; + XSizeHints *sizeHints; + + if ((wmHints = XAllocWMHints()) != NULL) + { + wmHints->initial_state = NormalState; + wmHints->input = True; + wmHints->flags = StateHint | InputHint; + + int depth = DisplayPlanes(xDisplay, DefaultScreen(xDisplay)); + + // Check if we can give it an icon + if(depth == 24 || depth == 32) + { + if(mGLSupport->loadIcon("GLX_icon.png", &wmHints->icon_pixmap, &wmHints->icon_mask)) + { + wmHints->flags |= IconPixmapHint | IconMaskHint; + } + } + } + + if ((sizeHints = XAllocSizeHints()) != NULL) + { + // Is this really necessary ? Which broken WM might need it? + sizeHints->flags = USPosition; + + if(!fullScreen && border == "fixed") + { + sizeHints->min_width = sizeHints->max_width = width; + sizeHints->min_height = sizeHints->max_height = height; + sizeHints->flags |= PMaxSize | PMinSize; + } + } + + XTextProperty titleprop; + vector::type title_ (title.begin(), title.end()); + title_.push_back(0); + + char *lst = &title_[0]; + XStringListToTextProperty((char **)&lst, 1, &titleprop); + XSetWMProperties(xDisplay, mWindow, &titleprop, NULL, NULL, 0, sizeHints, wmHints, NULL); + + XFree(titleprop.value); + XFree(wmHints); + XFree(sizeHints); + + XSetWMProtocols(xDisplay, mWindow, &mGLSupport->mAtomDeleteWindow, 1); + + XWindowAttributes windowAttrib; + + XGetWindowAttributes(xDisplay, mWindow, &windowAttrib); + + left = windowAttrib.x; + top = windowAttrib.y; + width = windowAttrib.width; + height = windowAttrib.height; + } + + glxDrawable = mWindow; + + // setHidden takes care of mapping or unmapping the window + // and also calls setFullScreen if appropriate. + setHidden(hidden); + XFlush(xDisplay); + + WindowEventUtilities::_addRenderWindow(this); + } + + mContext = new GLXContext(mGLSupport, fbConfig, glxDrawable, glxContext); + + // apply vsync settings. call setVSyncInterval first to avoid + // setting vsync more than once. + setVSyncInterval(vsyncInterval); + setVSyncEnabled(vsync); + + int fbConfigID; + + mGLSupport->getFBConfigAttrib(fbConfig, GLX_FBCONFIG_ID, &fbConfigID); + + LogManager::getSingleton().logMessage("GLXWindow::create used FBConfigID = " + StringConverter::toString(fbConfigID)); + + mName = name; + mWidth = width; + mHeight = height; + mLeft = left; + mTop = top; + mActive = true; + mClosed = false; + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::destroy(void) + { + if (mClosed) + return; + + mClosed = true; + mActive = false; + + if (! mIsExternal) + WindowEventUtilities::_removeRenderWindow(this); + + if (mIsFullScreen) + { + mGLSupport->switchMode(); + switchFullScreen(false); + } + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::setFullscreen(bool fullscreen, uint width, uint height) + { + short frequency = 0; + + if (mClosed || ! mIsTopLevel) + return; + + if (fullscreen == mIsFullScreen && width == mWidth && height == mHeight) + return; + + if (mIsFullScreen != fullscreen && &mGLSupport->mAtomFullScreen == None) + { + // Without WM support it is best to give up. + LogManager::getSingleton().logMessage("GLXWindow::switchFullScreen: Your WM has no fullscreen support"); + return; + } + else if (fullscreen) + { + mGLSupport->switchMode(width, height, frequency); + } + else + { + mGLSupport->switchMode(); + } + + if (mIsFullScreen != fullscreen) + { + switchFullScreen(fullscreen); + } + + if (! mIsFullScreen) + { + resize(width, height); + reposition(mLeft, mTop); + } + } + + //-------------------------------------------------------------------------------------------------// + bool GLXWindow::isClosed() const + { + return mClosed; + } + + //-------------------------------------------------------------------------------------------------// + bool GLXWindow::isVisible() const + { + return mVisible; + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::setVisible(bool visible) + { + mVisible = visible; + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::setHidden(bool hidden) + { + mHidden = hidden; + // ignore for external windows as these should handle + // this externally + if (mIsExternal) + return; + + if (hidden) + { + XUnmapWindow(mGLSupport->getXDisplay(), mWindow); + } + else + { + XMapWindow(mGLSupport->getXDisplay(), mWindow); + if (mIsFullScreen) + { + switchFullScreen(true); + } + } + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::setVSyncInterval(unsigned int interval) + { + mVSyncInterval = interval; + if (mVSync) + setVSyncEnabled(true); + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::setVSyncEnabled(bool vsync) + { + mVSync = vsync; + // we need to make our context current to set vsync + // store previous context to restore when finished. + ::GLXDrawable oldDrawable = glXGetCurrentDrawable(); + ::GLXContext oldContext = glXGetCurrentContext(); + + mContext->setCurrent(); + + if (! mIsExternalGLControl) + { + if (GLXEW_MESA_swap_control) + glXSwapIntervalMESA (vsync ? mVSyncInterval : 0); + else if (GLXEW_EXT_swap_control) + glXSwapIntervalEXT (mGLSupport->getGLDisplay(), glXGetCurrentDrawable(), + vsync ? mVSyncInterval : 0); + else if (GLXEW_SGI_swap_control) + if (vsync && mVSyncInterval) + glXSwapIntervalSGI (mVSyncInterval); + } + + mContext->endCurrent(); + + glXMakeCurrent (mGLSupport->getGLDisplay(), oldDrawable, oldContext); + } + + //-------------------------------------------------------------------------------------------------// + bool GLXWindow::isVSyncEnabled() const + { + return mVSync; + } + + //-------------------------------------------------------------------------------------------------// + unsigned int GLXWindow::getVSyncInterval() const + { + return mVSyncInterval; + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::reposition(int left, int top) + { + if (mClosed || ! mIsTopLevel) + return; + + XMoveWindow(mGLSupport->getXDisplay(), mWindow, left, top); + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::resize(uint width, uint height) + { + if (mClosed) + return; + + if(mWidth == width && mHeight == height) + return; + + if(width != 0 && height != 0) + { + if (!mIsExternal) + { + XResizeWindow(mGLSupport->getXDisplay(), mWindow, width, height); + } + else + { + mWidth = width; + mHeight = height; + + for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) + (*it).second->_updateDimensions(); + } + } + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::windowMovedOrResized() + { + if (mClosed || !mWindow) + return; + + Display* xDisplay = mGLSupport->getXDisplay(); + XWindowAttributes windowAttrib; + + if (mIsTopLevel && !mIsFullScreen) + { + Window parent, root, *children; + uint nChildren; + + XQueryTree(xDisplay, mWindow, &root, &parent, &children, &nChildren); + + if (children) + XFree(children); + + XGetWindowAttributes(xDisplay, parent, &windowAttrib); + + mLeft = windowAttrib.x; + mTop = windowAttrib.y; + } + + XGetWindowAttributes(xDisplay, mWindow, &windowAttrib); + + if (mWidth == (unsigned)windowAttrib.width && mHeight == (unsigned)windowAttrib.height) + return; + + mWidth = windowAttrib.width; + mHeight = windowAttrib.height; + + for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) + (*it).second->_updateDimensions(); + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::swapBuffers() + { + if (mClosed || mIsExternalGLControl) + return; + + glXSwapBuffers(mGLSupport->getGLDisplay(), mContext->mDrawable); + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::getCustomAttribute( const String& name, void* pData ) + { + if( name == "DISPLAY NAME" ) + { + *static_cast(pData) = mGLSupport->getDisplayName(); + return; + } + else if( name == "DISPLAY" ) + { + *static_cast(pData) = mGLSupport->getGLDisplay(); + return; + } + else if( name == "GLCONTEXT" ) + { + *static_cast(pData) = mContext; + return; + } + else if( name == "XDISPLAY" ) + { + *static_cast(pData) = mGLSupport->getXDisplay(); + return; + } + else if( name == "ATOM" ) + { + *static_cast< ::Atom* >(pData) = mGLSupport->mAtomDeleteWindow; + return; + } + else if( name == "WINDOW" ) + { + *static_cast(pData) = mWindow; + return; + } + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) + { + if (mClosed) + return; + + if ((dst.right > mWidth) || + (dst.bottom > mHeight) || + (dst.front != 0) || (dst.back != 1)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid box.", "GLXWindow::copyContentsToMemory" ); + } + + if (buffer == FB_AUTO) + { + buffer = mIsFullScreen? FB_FRONT : FB_BACK; + } + + GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format); + GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format); + + if ((format == GL_NONE) || (type == 0)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unsupported format.", "GLXWindow::copyContentsToMemory" ); + } + + // Switch context if different from current one + RenderSystem* rsys = Root::getSingleton().getRenderSystem(); + rsys->_setViewport(this->getViewport(0)); + if(dst.getWidth() != dst.rowPitch) glPixelStorei(GL_PACK_ROW_LENGTH, dst.rowPitch); - // Must change the packing to ensure no overruns! - glPixelStorei(GL_PACK_ALIGNMENT, 1); - - glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); + // Must change the packing to ensure no overruns! + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); glReadPixels((GLint)0, (GLint)(mHeight - dst.getHeight()), (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(), format, type, dst.getTopLeftFrontPixelPtr()); - - // restore default alignment - glPixelStorei(GL_PACK_ALIGNMENT, 4); + + // restore default alignment + glPixelStorei(GL_PACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ROW_LENGTH, 0); PixelUtil::bulkPixelVerticalFlip(dst); - } - - //-------------------------------------------------------------------------------------------------// - void GLXWindow::switchFullScreen(bool fullscreen) - { - if (&mGLSupport->mAtomFullScreen != None) - { - Display* xDisplay = mGLSupport->getXDisplay(); - XClientMessageEvent xMessage; - - xMessage.type = ClientMessage; - xMessage.serial = 0; - xMessage.send_event = True; - xMessage.window = mWindow; - xMessage.message_type = mGLSupport->mAtomState; - xMessage.format = 32; - xMessage.data.l[0] = (fullscreen ? 1 : 0); - xMessage.data.l[1] = mGLSupport->mAtomFullScreen; - xMessage.data.l[2] = 0; - - XSendEvent(xDisplay, DefaultRootWindow(xDisplay), False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&xMessage); - - mIsFullScreen = fullscreen; - } - } + } + + //-------------------------------------------------------------------------------------------------// + void GLXWindow::switchFullScreen(bool fullscreen) + { + if (&mGLSupport->mAtomFullScreen != None) + { + Display* xDisplay = mGLSupport->getXDisplay(); + XClientMessageEvent xMessage; + + xMessage.type = ClientMessage; + xMessage.serial = 0; + xMessage.send_event = True; + xMessage.window = mWindow; + xMessage.message_type = mGLSupport->mAtomState; + xMessage.format = 32; + xMessage.data.l[0] = (fullscreen ? 1 : 0); + xMessage.data.l[1] = mGLSupport->mAtomFullScreen; + xMessage.data.l[2] = 0; + + XSendEvent(xDisplay, DefaultRootWindow(xDisplay), False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent*)&xMessage); + + mIsFullScreen = fullscreen; + } + } } diff --git a/RenderSystems/GL/src/OSX/OgreOSXCGLContext.cpp b/RenderSystems/GL/src/OSX/OgreOSXCGLContext.cpp index 60cd842c138..129e0f0a8f8 100644 --- a/RenderSystems/GL/src/OSX/OgreOSXCGLContext.cpp +++ b/RenderSystems/GL/src/OSX/OgreOSXCGLContext.cpp @@ -32,14 +32,14 @@ THE SOFTWARE. namespace Ogre { - - OSXCGLContext::OSXCGLContext(CGLContextObj cglContext, CGLPixelFormatObj pixelFormat) : + + OSXCGLContext::OSXCGLContext(CGLContextObj cglContext, CGLPixelFormatObj pixelFormat) : mCGLContext(cglContext), mPixelFormat(pixelFormat) {} - OSXCGLContext::~OSXCGLContext() - { - _unregisterContext(); - + OSXCGLContext::~OSXCGLContext() + { + _unregisterContext(); + if(mPixelFormat != NULL) { CGLDestroyPixelFormat(mPixelFormat); @@ -48,25 +48,25 @@ namespace Ogre } void OSXCGLContext::setCurrent() - { - CGLSetCurrentContext(mCGLContext); + { + CGLSetCurrentContext(mCGLContext); + } + + void OSXCGLContext::endCurrent() + { + CGLSetCurrentContext(NULL); } - - void OSXCGLContext::endCurrent() - { - CGLSetCurrentContext(NULL); - } - - GLContext* OSXCGLContext::clone() const - { - CGLContextObj cglCtxShare; + + GLContext* OSXCGLContext::clone() const + { + CGLContextObj cglCtxShare; CGLCreateContext(mPixelFormat, mCGLContext, &cglCtxShare); - return OGRE_NEW OSXCGLContext(cglCtxShare, mPixelFormat); - } - - String OSXCGLContext::getContextType() - { - return "CGL"; - } + return OGRE_NEW OSXCGLContext(cglCtxShare, mPixelFormat); + } + + String OSXCGLContext::getContextType() + { + return "CGL"; + } } diff --git a/RenderSystems/GL/src/OSX/OgreOSXCarbonContext.cpp b/RenderSystems/GL/src/OSX/OgreOSXCarbonContext.cpp index 3620471ec8b..751eaa1fa35 100644 --- a/RenderSystems/GL/src/OSX/OgreOSXCarbonContext.cpp +++ b/RenderSystems/GL/src/OSX/OgreOSXCarbonContext.cpp @@ -34,38 +34,38 @@ namespace Ogre OSXCarbonContext::OSXCarbonContext(AGLContext aglContext, AGLPixelFormat pixelFormat) : mAGLContext(aglContext), mPixelFormat(pixelFormat) {} - - OSXCarbonContext::~OSXCarbonContext() - { - _unregisterContext(); - + + OSXCarbonContext::~OSXCarbonContext() + { + _unregisterContext(); + if(mPixelFormat != NULL) aglDestroyPixelFormat(mPixelFormat); } void OSXCarbonContext::setCurrent() - { - // Apple's docs claim that you may need to force the context to null - // before setting current, especially when using pBuffers. - aglSetCurrentContext(NULL); - aglSetCurrentContext(mAGLContext); + { + // Apple's docs claim that you may need to force the context to null + // before setting current, especially when using pBuffers. + aglSetCurrentContext(NULL); + aglSetCurrentContext(mAGLContext); + } + + void OSXCarbonContext::endCurrent() + { + aglSetCurrentContext(NULL); } - - void OSXCarbonContext::endCurrent() - { - aglSetCurrentContext(NULL); - } - - GLContext* OSXCarbonContext::clone() const - { + + GLContext* OSXCarbonContext::clone() const + { aglSetCurrentContext(NULL); - AGLContext aglCtxShare = aglCreateContext(mPixelFormat, mAGLContext); - return OGRE_NEW OSXCarbonContext(aglCtxShare, mPixelFormat); - } - - String OSXCarbonContext::getContextType() - { - return "AGL"; - } + AGLContext aglCtxShare = aglCreateContext(mPixelFormat, mAGLContext); + return OGRE_NEW OSXCarbonContext(aglCtxShare, mPixelFormat); + } + + String OSXCarbonContext::getContextType() + { + return "AGL"; + } } diff --git a/RenderSystems/GL/src/OSX/OgreOSXCarbonWindow.cpp b/RenderSystems/GL/src/OSX/OgreOSXCarbonWindow.cpp index db3e3786d08..d4a1c2e80c5 100644 --- a/RenderSystems/GL/src/OSX/OgreOSXCarbonWindow.cpp +++ b/RenderSystems/GL/src/OSX/OgreOSXCarbonWindow.cpp @@ -93,7 +93,7 @@ namespace Ogre hidden = StringConverter::parseBool(opt->second); if((opt = miscParams->find("gamma")) != end) - mHwGamma = StringConverter::parseBool(opt->second); + mHwGamma = StringConverter::parseBool(opt->second); if((opt = miscParams->find("depthBuffer")) != end) hasDepthBuffer = StringConverter::parseBool( opt->second ); @@ -142,7 +142,7 @@ namespace Ogre } // Apply vsync settings. call setVSyncInterval first to avoid - // setting vsync more than once. + // setting vsync more than once. setVSyncEnabled(vsync); setHidden(hidden); @@ -303,9 +303,9 @@ namespace Ogre GetControlBounds(mView, &ctrlBounds); GLint bufferRect[4]; - bufferRect[0] = ctrlBounds.left; // left edge - bufferRect[1] = ctrlBounds.bottom; // bottom edge - bufferRect[2] = ctrlBounds.right - ctrlBounds.left; // width of buffer rect + bufferRect[0] = ctrlBounds.left; // left edge + bufferRect[1] = ctrlBounds.bottom; // bottom edge + bufferRect[2] = ctrlBounds.right - ctrlBounds.left; // width of buffer rect bufferRect[3] = ctrlBounds.bottom - ctrlBounds.top; // height of buffer rect aglSetInteger(mAGLContext, AGL_BUFFER_RECT, bufferRect); @@ -397,8 +397,8 @@ namespace Ogre } //-------------------------------------------------------------------------------------------------// - void OSXCarbonWindow::setVSyncEnabled(bool vsync) - { + void OSXCarbonWindow::setVSyncEnabled(bool vsync) + { mVSync = vsync; mContext->setCurrent(); @@ -420,13 +420,13 @@ namespace Ogre if(share != CGLGetCurrentContext()) CGLSetCurrentContext(share); } - } + } //-------------------------------------------------------------------------------------------------// - bool OSXCarbonWindow::isVSyncEnabled() const - { + bool OSXCarbonWindow::isVSyncEnabled() const + { return mVSync; - } + } //-------------------------------------------------------------------------------------------------// void OSXCarbonWindow::reposition(int left, int top) diff --git a/RenderSystems/GL/src/OSX/OgreOSXContext.cpp b/RenderSystems/GL/src/OSX/OgreOSXContext.cpp index 98e3360d368..d0335366e0b 100644 --- a/RenderSystems/GL/src/OSX/OgreOSXContext.cpp +++ b/RenderSystems/GL/src/OSX/OgreOSXContext.cpp @@ -32,19 +32,19 @@ THE SOFTWARE. namespace Ogre { - OSXContext::OSXContext() - { - } - - OSXContext::~OSXContext() - { + OSXContext::OSXContext() + { + } + + OSXContext::~OSXContext() + { + } + + void OSXContext::_unregisterContext() + { + // NB have to do this is subclass to ensure any methods called back + // are on this subclass and not half-destructed superclass + GLRenderSystem *rs = static_cast(Root::getSingleton().getRenderSystem()); + rs->_unregisterContext(this); } - - void OSXContext::_unregisterContext() - { - // NB have to do this is subclass to ensure any methods called back - // are on this subclass and not half-destructed superclass - GLRenderSystem *rs = static_cast(Root::getSingleton().getRenderSystem()); - rs->_unregisterContext(this); - } } diff --git a/RenderSystems/GL/src/OSX/OgreOSXRenderTexture.cpp b/RenderSystems/GL/src/OSX/OgreOSXRenderTexture.cpp index 37434e68e0a..006594280d9 100644 --- a/RenderSystems/GL/src/OSX/OgreOSXRenderTexture.cpp +++ b/RenderSystems/GL/src/OSX/OgreOSXRenderTexture.cpp @@ -45,47 +45,47 @@ THE SOFTWARE. namespace Ogre { - OSXPBuffer::OSXPBuffer( PixelComponentType format, uint32 width, uint32 height ) : GLPBuffer( format, width, height ), mContext( NULL ) - { - LogManager::getSingleton().logMessage( "OSXPBuffer::OSXPBuffer()" ); - createPBuffer(); - // Create context - //mContext = OGRE_NEW OSXCarbonContext(mAGLContext); + OSXPBuffer::OSXPBuffer( PixelComponentType format, uint32 width, uint32 height ) : GLPBuffer( format, width, height ), mContext( NULL ) + { + LogManager::getSingleton().logMessage( "OSXPBuffer::OSXPBuffer()" ); + createPBuffer(); + // Create context + //mContext = OGRE_NEW OSXCarbonContext(mAGLContext); + } + + OSXPBuffer::~OSXPBuffer() + { + LogManager::getSingleton().logMessage( "OSXPBuffer::~OSXPBuffer()" ); + OGRE_DELETE mContext; + destroyPBuffer(); } - - OSXPBuffer::~OSXPBuffer() - { - LogManager::getSingleton().logMessage( "OSXPBuffer::~OSXPBuffer()" ); - OGRE_DELETE mContext; - destroyPBuffer(); - } - GLContext* OSXPBuffer::getContext() - { - LogManager::getSingleton().logMessage( "OSXPBuffer::getContext()" ); - return mContext; - } - - void OSXPBuffer::createPBuffer() - { - LogManager::getSingleton().logMessage( "OSXPBuffer::createPBuffer()" ); - - GLint attrib[] = { AGL_NO_RECOVERY, GL_TRUE, AGL_ACCELERATED, GL_TRUE, AGL_RGBA, AGL_NONE }; - AGLPixelFormat pixelFormat = aglChoosePixelFormat(NULL, 0, attrib); - mAGLContext = aglCreateContext(pixelFormat, NULL); - - //mAGLContext = aglGetCurrentContext(); - aglCreatePBuffer( mWidth, mHeight, GL_TEXTURE_2D, GL_RGBA, 0, &mPBuffer ); - - GLint vs = aglGetVirtualScreen( mAGLContext ); - aglSetPBuffer( mAGLContext, mPBuffer, 0, 0, vs ); + GLContext* OSXPBuffer::getContext() + { + LogManager::getSingleton().logMessage( "OSXPBuffer::getContext()" ); + return mContext; + } + + void OSXPBuffer::createPBuffer() + { + LogManager::getSingleton().logMessage( "OSXPBuffer::createPBuffer()" ); + + GLint attrib[] = { AGL_NO_RECOVERY, GL_TRUE, AGL_ACCELERATED, GL_TRUE, AGL_RGBA, AGL_NONE }; + AGLPixelFormat pixelFormat = aglChoosePixelFormat(NULL, 0, attrib); + mAGLContext = aglCreateContext(pixelFormat, NULL); + + //mAGLContext = aglGetCurrentContext(); + aglCreatePBuffer( mWidth, mHeight, GL_TEXTURE_2D, GL_RGBA, 0, &mPBuffer ); + + GLint vs = aglGetVirtualScreen( mAGLContext ); + aglSetPBuffer( mAGLContext, mPBuffer, 0, 0, vs ); mContext = OGRE_NEW OSXCarbonContext(mAGLContext, pixelFormat); - } - - void OSXPBuffer::destroyPBuffer() - { - LogManager::getSingleton().logMessage( "OSXPBuffer::destroyPBuffer()" ); - aglDestroyPBuffer( mPBuffer ); - } + } + + void OSXPBuffer::destroyPBuffer() + { + LogManager::getSingleton().logMessage( "OSXPBuffer::destroyPBuffer()" ); + aglDestroyPBuffer( mPBuffer ); + } } diff --git a/RenderSystems/GL/src/OSX/OgreOSXWindow.cpp b/RenderSystems/GL/src/OSX/OgreOSXWindow.cpp index 44231ab5a40..0aa62e9959b 100644 --- a/RenderSystems/GL/src/OSX/OgreOSXWindow.cpp +++ b/RenderSystems/GL/src/OSX/OgreOSXWindow.cpp @@ -101,8 +101,8 @@ namespace Ogre } // Switch context if different from current one - RenderSystem* rsys = Root::getSingleton().getRenderSystem(); - rsys->_setViewport(this->getViewport(0)); + RenderSystem* rsys = Root::getSingleton().getRenderSystem(); + rsys->_setViewport(this->getViewport(0)); if(dst.getWidth() != dst.rowPitch) { diff --git a/RenderSystems/GL/src/OgreGLATIFSInit.cpp b/RenderSystems/GL/src/OgreGLATIFSInit.cpp index 07ed9484164..33e80a28f7c 100644 --- a/RenderSystems/GL/src/OgreGLATIFSInit.cpp +++ b/RenderSystems/GL/src/OgreGLATIFSInit.cpp @@ -1,7 +1,7 @@ /* - ATI fragment shader Extension program file. - setup by NFZ - extracted from ATI 8500 SDK + ATI fragment shader Extension program file. + setup by NFZ + extracted from ATI 8500 SDK ** GL_ATI_fragment_shader ** @@ -39,66 +39,66 @@ bool InitATIFragmentShaderExtensions(Ogre::GLSupport& glSupport) if(init) return init; - - /* confirm that the version of OpenGL supports ATI fragment shader */ - /* done in GLRenderSystem + + /* confirm that the version of OpenGL supports ATI fragment shader */ + /* done in GLRenderSystem extList = (char *)glGetString(GL_EXTENSIONS); if (strstr(extList, "GL_ATI_fragment_shader") == NULL) { - //MessageBox(NULL, "GL_ATI_fragment_shader extension not supported", "GL Extension error", MB_OK); - // ** should raise exception - init = false; - return false; + //MessageBox(NULL, "GL_ATI_fragment_shader extension not supported", "GL Extension error", MB_OK); + // ** should raise exception + init = false; + return false; } - */ + */ - glGenFragmentShadersATI_ptr = (PFNGLGENFRAGMENTSHADERSATIPROC) glSupport.getProcAddress("glGenFragmentShadersATI"); - glBindFragmentShaderATI_ptr = (PFNGLBINDFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glBindFragmentShaderATI"); - glDeleteFragmentShaderATI_ptr = (PFNGLDELETEFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glDeleteFragmentShaderATI"); - glBeginFragmentShaderATI_ptr = (PFNGLBEGINFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glBeginFragmentShaderATI"); - glEndFragmentShaderATI_ptr = (PFNGLENDFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glEndFragmentShaderATI"); - glPassTexCoordATI_ptr = (PFNGLPASSTEXCOORDATIPROC) glSupport.getProcAddress("glPassTexCoordATI"); - glSampleMapATI_ptr = (PFNGLSAMPLEMAPATIPROC) glSupport.getProcAddress("glSampleMapATI"); - glColorFragmentOp1ATI_ptr = (PFNGLCOLORFRAGMENTOP1ATIPROC) glSupport.getProcAddress("glColorFragmentOp1ATI"); - glColorFragmentOp2ATI_ptr = (PFNGLCOLORFRAGMENTOP2ATIPROC) glSupport.getProcAddress("glColorFragmentOp2ATI"); - glColorFragmentOp3ATI_ptr = (PFNGLCOLORFRAGMENTOP3ATIPROC) glSupport.getProcAddress("glColorFragmentOp3ATI"); - glAlphaFragmentOp1ATI_ptr = (PFNGLALPHAFRAGMENTOP1ATIPROC) glSupport.getProcAddress("glAlphaFragmentOp1ATI"); - glAlphaFragmentOp2ATI_ptr = (PFNGLALPHAFRAGMENTOP2ATIPROC) glSupport.getProcAddress("glAlphaFragmentOp2ATI"); - glAlphaFragmentOp3ATI_ptr = (PFNGLALPHAFRAGMENTOP3ATIPROC) glSupport.getProcAddress("glAlphaFragmentOp3ATI"); - glSetFragmentShaderConstantATI_ptr = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) glSupport.getProcAddress("glSetFragmentShaderConstantATI"); + glGenFragmentShadersATI_ptr = (PFNGLGENFRAGMENTSHADERSATIPROC) glSupport.getProcAddress("glGenFragmentShadersATI"); + glBindFragmentShaderATI_ptr = (PFNGLBINDFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glBindFragmentShaderATI"); + glDeleteFragmentShaderATI_ptr = (PFNGLDELETEFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glDeleteFragmentShaderATI"); + glBeginFragmentShaderATI_ptr = (PFNGLBEGINFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glBeginFragmentShaderATI"); + glEndFragmentShaderATI_ptr = (PFNGLENDFRAGMENTSHADERATIPROC) glSupport.getProcAddress("glEndFragmentShaderATI"); + glPassTexCoordATI_ptr = (PFNGLPASSTEXCOORDATIPROC) glSupport.getProcAddress("glPassTexCoordATI"); + glSampleMapATI_ptr = (PFNGLSAMPLEMAPATIPROC) glSupport.getProcAddress("glSampleMapATI"); + glColorFragmentOp1ATI_ptr = (PFNGLCOLORFRAGMENTOP1ATIPROC) glSupport.getProcAddress("glColorFragmentOp1ATI"); + glColorFragmentOp2ATI_ptr = (PFNGLCOLORFRAGMENTOP2ATIPROC) glSupport.getProcAddress("glColorFragmentOp2ATI"); + glColorFragmentOp3ATI_ptr = (PFNGLCOLORFRAGMENTOP3ATIPROC) glSupport.getProcAddress("glColorFragmentOp3ATI"); + glAlphaFragmentOp1ATI_ptr = (PFNGLALPHAFRAGMENTOP1ATIPROC) glSupport.getProcAddress("glAlphaFragmentOp1ATI"); + glAlphaFragmentOp2ATI_ptr = (PFNGLALPHAFRAGMENTOP2ATIPROC) glSupport.getProcAddress("glAlphaFragmentOp2ATI"); + glAlphaFragmentOp3ATI_ptr = (PFNGLALPHAFRAGMENTOP3ATIPROC) glSupport.getProcAddress("glAlphaFragmentOp3ATI"); + glSetFragmentShaderConstantATI_ptr = (PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) glSupport.getProcAddress("glSetFragmentShaderConstantATI"); - if (glGenFragmentShadersATI_ptr == NULL) return false; + if (glGenFragmentShadersATI_ptr == NULL) return false; - if (glBindFragmentShaderATI_ptr == NULL) return false; + if (glBindFragmentShaderATI_ptr == NULL) return false; - if (glDeleteFragmentShaderATI_ptr == NULL) return false; + if (glDeleteFragmentShaderATI_ptr == NULL) return false; - if (glBeginFragmentShaderATI_ptr == NULL) return false; + if (glBeginFragmentShaderATI_ptr == NULL) return false; - if (glEndFragmentShaderATI_ptr == NULL) return false; + if (glEndFragmentShaderATI_ptr == NULL) return false; - if (glPassTexCoordATI_ptr == NULL) return false; + if (glPassTexCoordATI_ptr == NULL) return false; - if (glColorFragmentOp1ATI_ptr == NULL) return false; + if (glColorFragmentOp1ATI_ptr == NULL) return false; - if (glColorFragmentOp2ATI_ptr == NULL) return false; + if (glColorFragmentOp2ATI_ptr == NULL) return false; - if (glColorFragmentOp3ATI_ptr == NULL) return false; + if (glColorFragmentOp3ATI_ptr == NULL) return false; - if (glAlphaFragmentOp1ATI_ptr == NULL) return false; + if (glAlphaFragmentOp1ATI_ptr == NULL) return false; - if (glAlphaFragmentOp2ATI_ptr == NULL) return false; + if (glAlphaFragmentOp2ATI_ptr == NULL) return false; - if (glAlphaFragmentOp2ATI_ptr == NULL) return false; + if (glAlphaFragmentOp2ATI_ptr == NULL) return false; - if (glAlphaFragmentOp3ATI_ptr == NULL) return false; + if (glAlphaFragmentOp3ATI_ptr == NULL) return false; - if (glSetFragmentShaderConstantATI_ptr == NULL) return false; + if (glSetFragmentShaderConstantATI_ptr == NULL) return false; init = true; - return true; + return true; } diff --git a/RenderSystems/GL/src/OgreGLContext.cpp b/RenderSystems/GL/src/OgreGLContext.cpp index 677511f92bd..c6e5a4ced68 100644 --- a/RenderSystems/GL/src/OgreGLContext.cpp +++ b/RenderSystems/GL/src/OgreGLContext.cpp @@ -49,17 +49,17 @@ namespace Ogre { // declared in OgreGLPrerequisites.h GLEWContext * glewGetContext() { - using namespace Ogre; - static OGRE_THREAD_POINTER_VAR(GLEWContext, GLEWContextsPtr); + using namespace Ogre; + static OGRE_THREAD_POINTER_VAR(GLEWContext, GLEWContextsPtr); - GLEWContext * currentGLEWContextsPtr = OGRE_THREAD_POINTER_GET(GLEWContextsPtr); - if (currentGLEWContextsPtr == NULL) - { - currentGLEWContextsPtr = new GLEWContext(); - OGRE_THREAD_POINTER_SET(GLEWContextsPtr, currentGLEWContextsPtr); - memset(currentGLEWContextsPtr, 0, sizeof(GLEWContext)); - glewInit(); - } - return currentGLEWContextsPtr; + GLEWContext * currentGLEWContextsPtr = OGRE_THREAD_POINTER_GET(GLEWContextsPtr); + if (currentGLEWContextsPtr == NULL) + { + currentGLEWContextsPtr = new GLEWContext(); + OGRE_THREAD_POINTER_SET(GLEWContextsPtr, currentGLEWContextsPtr); + memset(currentGLEWContextsPtr, 0, sizeof(GLEWContext)); + glewInit(); + } + return currentGLEWContextsPtr; } #endif diff --git a/RenderSystems/GL/src/OgreGLDefaultHardwareBufferManager.cpp b/RenderSystems/GL/src/OgreGLDefaultHardwareBufferManager.cpp index d338aed0584..755e095df6a 100644 --- a/RenderSystems/GL/src/OgreGLDefaultHardwareBufferManager.cpp +++ b/RenderSystems/GL/src/OgreGLDefaultHardwareBufferManager.cpp @@ -30,167 +30,167 @@ THE SOFTWARE. namespace Ogre { - GLDefaultHardwareVertexBuffer::GLDefaultHardwareVertexBuffer(size_t vertexSize, size_t numVertices, - HardwareBuffer::Usage usage) - : HardwareVertexBuffer(0, vertexSize, numVertices, usage, true, false) // always software, never shadowed - { + GLDefaultHardwareVertexBuffer::GLDefaultHardwareVertexBuffer(size_t vertexSize, size_t numVertices, + HardwareBuffer::Usage usage) + : HardwareVertexBuffer(0, vertexSize, numVertices, usage, true, false) // always software, never shadowed + { mData = static_cast(OGRE_MALLOC_SIMD(mSizeInBytes, MEMCATEGORY_GEOMETRY)); - } - //----------------------------------------------------------------------- - GLDefaultHardwareVertexBuffer::GLDefaultHardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, - HardwareBuffer::Usage usage) + } + //----------------------------------------------------------------------- + GLDefaultHardwareVertexBuffer::GLDefaultHardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, + HardwareBuffer::Usage usage) : HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, true, false) // always software, never shadowed - { + { mData = static_cast(OGRE_MALLOC_SIMD(mSizeInBytes, MEMCATEGORY_GEOMETRY)); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- GLDefaultHardwareVertexBuffer::~GLDefaultHardwareVertexBuffer() - { - OGRE_FREE_SIMD(mData, MEMCATEGORY_GEOMETRY); - } - //----------------------------------------------------------------------- + { + OGRE_FREE_SIMD(mData, MEMCATEGORY_GEOMETRY); + } + //----------------------------------------------------------------------- void* GLDefaultHardwareVertexBuffer::lockImpl(size_t offset, size_t length, LockOptions options) - { + { // Only for use internally, no 'locking' as such - return mData + offset; - } - //----------------------------------------------------------------------- - void GLDefaultHardwareVertexBuffer::unlockImpl(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void GLDefaultHardwareVertexBuffer::unlockImpl(void) + { // Nothing to do - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void* GLDefaultHardwareVertexBuffer::lock(size_t offset, size_t length, LockOptions options, HardwareBuffer::UploadOptions uploadOpt) - { + { mIsLocked = true; - return mData + offset; - } - //----------------------------------------------------------------------- - void GLDefaultHardwareVertexBuffer::unlock(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void GLDefaultHardwareVertexBuffer::unlock(void) + { mIsLocked = false; // Nothing to do - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void GLDefaultHardwareVertexBuffer::readData(size_t offset, size_t length, void* pDest) - { - assert((offset + length) <= mSizeInBytes); - memcpy(pDest, mData + offset, length); - } - //----------------------------------------------------------------------- + { + assert((offset + length) <= mSizeInBytes); + memcpy(pDest, mData + offset, length); + } + //----------------------------------------------------------------------- void GLDefaultHardwareVertexBuffer::writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer) - { - assert((offset + length) <= mSizeInBytes); - // ignore discard, memory is not guaranteed to be zeroised - memcpy(mData + offset, pSource, length); + bool discardWholeBuffer) + { + assert((offset + length) <= mSizeInBytes); + // ignore discard, memory is not guaranteed to be zeroised + memcpy(mData + offset, pSource, length); - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- - GLDefaultHardwareIndexBuffer::GLDefaultHardwareIndexBuffer(IndexType idxType, - size_t numIndexes, HardwareBuffer::Usage usage) - : HardwareIndexBuffer(0, idxType, numIndexes, usage, true, false) // always software, never shadowed - { - mData = new unsigned char[mSizeInBytes]; - } - //----------------------------------------------------------------------- + GLDefaultHardwareIndexBuffer::GLDefaultHardwareIndexBuffer(IndexType idxType, + size_t numIndexes, HardwareBuffer::Usage usage) + : HardwareIndexBuffer(0, idxType, numIndexes, usage, true, false) // always software, never shadowed + { + mData = new unsigned char[mSizeInBytes]; + } + //----------------------------------------------------------------------- GLDefaultHardwareIndexBuffer::~GLDefaultHardwareIndexBuffer() - { - delete [] mData; - } - //----------------------------------------------------------------------- + { + delete [] mData; + } + //----------------------------------------------------------------------- void* GLDefaultHardwareIndexBuffer::lockImpl(size_t offset, size_t length, LockOptions options) - { + { // Only for use internally, no 'locking' as such - return mData + offset; - } - //----------------------------------------------------------------------- - void GLDefaultHardwareIndexBuffer::unlockImpl(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void GLDefaultHardwareIndexBuffer::unlockImpl(void) + { // Nothing to do - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void* GLDefaultHardwareIndexBuffer::lock(size_t offset, size_t length, LockOptions options, HardwareBuffer::UploadOptions uploadOpt) - { - + { + mIsLocked = true; - return mData + offset; - } - //----------------------------------------------------------------------- - void GLDefaultHardwareIndexBuffer::unlock(void) - { + return mData + offset; + } + //----------------------------------------------------------------------- + void GLDefaultHardwareIndexBuffer::unlock(void) + { mIsLocked = false; // Nothing to do - } - //----------------------------------------------------------------------- + } + //----------------------------------------------------------------------- void GLDefaultHardwareIndexBuffer::readData(size_t offset, size_t length, void* pDest) - { - assert((offset + length) <= mSizeInBytes); - memcpy(pDest, mData + offset, length); - } - //----------------------------------------------------------------------- + { + assert((offset + length) <= mSizeInBytes); + memcpy(pDest, mData + offset, length); + } + //----------------------------------------------------------------------- void GLDefaultHardwareIndexBuffer::writeData(size_t offset, size_t length, const void* pSource, - bool discardWholeBuffer) - { - assert((offset + length) <= mSizeInBytes); - // ignore discard, memory is not guaranteed to be zeroised - memcpy(mData + offset, pSource, length); + bool discardWholeBuffer) + { + assert((offset + length) <= mSizeInBytes); + // ignore discard, memory is not guaranteed to be zeroised + memcpy(mData + offset, pSource, length); - } - //----------------------------------------------------------------------- - - + } + //----------------------------------------------------------------------- + + //----------------------------------------------------------------------- GLDefaultHardwareBufferManagerBase::GLDefaultHardwareBufferManagerBase() - { - } + { + } //----------------------------------------------------------------------- GLDefaultHardwareBufferManagerBase::~GLDefaultHardwareBufferManagerBase() - { + { destroyAllDeclarations(); destroyAllBindings(); - } + } //----------------------------------------------------------------------- - HardwareVertexBufferSharedPtr + HardwareVertexBufferSharedPtr GLDefaultHardwareBufferManagerBase::createVertexBuffer(size_t vertexSize, - size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer) - { - return HardwareVertexBufferSharedPtr( - new GLDefaultHardwareVertexBuffer(this, vertexSize, numVerts, usage)); - } + size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer) + { + return HardwareVertexBufferSharedPtr( + new GLDefaultHardwareVertexBuffer(this, vertexSize, numVerts, usage)); + } //----------------------------------------------------------------------- - HardwareIndexBufferSharedPtr + HardwareIndexBufferSharedPtr GLDefaultHardwareBufferManagerBase::createIndexBuffer(HardwareIndexBuffer::IndexType itype, - size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer) - { - return HardwareIndexBufferSharedPtr( - new GLDefaultHardwareIndexBuffer(itype, numIndexes, usage) ); - } - //----------------------------------------------------------------------- - RenderToVertexBufferSharedPtr - GLDefaultHardwareBufferManagerBase::createRenderToVertexBuffer() - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create RenderToVertexBuffer in GLDefaultHardwareBufferManagerBase", - "GLDefaultHardwareBufferManagerBase::createRenderToVertexBuffer"); - } - //----------------------------------------------------------------------- - HardwareUniformBufferSharedPtr - GLDefaultHardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Cannot create UniformBuffer in GLDefaultHardwareBufferManagerBase", - "GLDefaultHardwareBufferManagerBase::createUniformBuffer"); - } - //----------------------------------------------------------------------- + size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer) + { + return HardwareIndexBufferSharedPtr( + new GLDefaultHardwareIndexBuffer(itype, numIndexes, usage) ); + } + //----------------------------------------------------------------------- + RenderToVertexBufferSharedPtr + GLDefaultHardwareBufferManagerBase::createRenderToVertexBuffer() + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create RenderToVertexBuffer in GLDefaultHardwareBufferManagerBase", + "GLDefaultHardwareBufferManagerBase::createRenderToVertexBuffer"); + } + //----------------------------------------------------------------------- + HardwareUniformBufferSharedPtr + GLDefaultHardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Cannot create UniformBuffer in GLDefaultHardwareBufferManagerBase", + "GLDefaultHardwareBufferManagerBase::createUniformBuffer"); + } + //----------------------------------------------------------------------- HardwareCounterBufferSharedPtr GLDefaultHardwareBufferManagerBase::createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Counter buffers not supported in OpenGL RenderSystem.", "GLDefaultHardwareBufferManagerBase::createCounterBuffer"); - } + } } diff --git a/RenderSystems/GL/src/OgreGLDepthBuffer.cpp b/RenderSystems/GL/src/OgreGLDepthBuffer.cpp index 8d2d628874a..3a8dd0c90f2 100644 --- a/RenderSystems/GL/src/OgreGLDepthBuffer.cpp +++ b/RenderSystems/GL/src/OgreGLDepthBuffer.cpp @@ -32,96 +32,96 @@ THE SOFTWARE. namespace Ogre { - GLDepthBuffer::GLDepthBuffer( uint16 poolId, GLRenderSystem *renderSystem, GLContext *creatorContext, - GLRenderBuffer *depth, GLRenderBuffer *stencil, - uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, - bool manual ) : - DepthBuffer( poolId, 0, width, height, fsaa, "", manual ), - mMultiSampleQuality( multiSampleQuality ), - mCreatorContext( creatorContext ), - mDepthBuffer( depth ), - mStencilBuffer( stencil ), - mRenderSystem( renderSystem ) - { - if( mDepthBuffer ) - { - switch( mDepthBuffer->getGLFormat() ) - { - case GL_DEPTH_COMPONENT16: - mBitDepth = 16; - break; - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: - case GL_DEPTH24_STENCIL8_EXT: - mBitDepth = 32; - break; - } - } - } - - GLDepthBuffer::~GLDepthBuffer() - { - if( mStencilBuffer && mStencilBuffer != mDepthBuffer ) - { - delete mStencilBuffer; - mStencilBuffer = 0; - } - - if( mDepthBuffer ) - { - delete mDepthBuffer; - mDepthBuffer = 0; - } - } - //--------------------------------------------------------------------- - bool GLDepthBuffer::isCompatible( RenderTarget *renderTarget ) const - { - bool retVal = false; - - //Check standard stuff first. - if( mRenderSystem->getCapabilities()->hasCapability( RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL ) ) - { - if( !DepthBuffer::isCompatible( renderTarget ) ) - return false; - } - else - { - if( this->getWidth() != renderTarget->getWidth() || - this->getHeight() != renderTarget->getHeight() || - this->getFsaa() != renderTarget->getFSAA() ) - return false; - } - - //Now check this is the appropriate format - GLFrameBufferObject *fbo = 0; + GLDepthBuffer::GLDepthBuffer( uint16 poolId, GLRenderSystem *renderSystem, GLContext *creatorContext, + GLRenderBuffer *depth, GLRenderBuffer *stencil, + uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, + bool manual ) : + DepthBuffer( poolId, 0, width, height, fsaa, "", manual ), + mMultiSampleQuality( multiSampleQuality ), + mCreatorContext( creatorContext ), + mDepthBuffer( depth ), + mStencilBuffer( stencil ), + mRenderSystem( renderSystem ) + { + if( mDepthBuffer ) + { + switch( mDepthBuffer->getGLFormat() ) + { + case GL_DEPTH_COMPONENT16: + mBitDepth = 16; + break; + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + case GL_DEPTH24_STENCIL8_EXT: + mBitDepth = 32; + break; + } + } + } + + GLDepthBuffer::~GLDepthBuffer() + { + if( mStencilBuffer && mStencilBuffer != mDepthBuffer ) + { + delete mStencilBuffer; + mStencilBuffer = 0; + } + + if( mDepthBuffer ) + { + delete mDepthBuffer; + mDepthBuffer = 0; + } + } + //--------------------------------------------------------------------- + bool GLDepthBuffer::isCompatible( RenderTarget *renderTarget ) const + { + bool retVal = false; + + //Check standard stuff first. + if( mRenderSystem->getCapabilities()->hasCapability( RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL ) ) + { + if( !DepthBuffer::isCompatible( renderTarget ) ) + return false; + } + else + { + if( this->getWidth() != renderTarget->getWidth() || + this->getHeight() != renderTarget->getHeight() || + this->getFsaa() != renderTarget->getFSAA() ) + return false; + } + + //Now check this is the appropriate format + GLFrameBufferObject *fbo = 0; renderTarget->getCustomAttribute(GLRenderTexture::CustomAttributeString_FBO, &fbo); - if( !fbo ) - { - GLContext *windowContext = 0; - renderTarget->getCustomAttribute( GLRenderTexture::CustomAttributeString_GLCONTEXT, &windowContext ); - - //Non-FBO targets and FBO depth surfaces don't play along, only dummies which match the same - //context - if( !mDepthBuffer && !mStencilBuffer && mCreatorContext == windowContext ) - retVal = true; - } - else - { - //Check this isn't a dummy non-FBO depth buffer with an FBO target, don't mix them. - //If you don't want depth buffer, use a Null Depth Buffer, not a dummy one. - if( mDepthBuffer || mStencilBuffer ) - { - GLenum internalFormat = fbo->getFormat(); - GLenum depthFormat, stencilFormat; - mRenderSystem->_getDepthStencilFormatFor( internalFormat, &depthFormat, &stencilFormat ); - - bool bSameDepth = false; - - if( mDepthBuffer ) - bSameDepth |= mDepthBuffer->getGLFormat() == depthFormat; - - bool bSameStencil = false; + if( !fbo ) + { + GLContext *windowContext = 0; + renderTarget->getCustomAttribute( GLRenderTexture::CustomAttributeString_GLCONTEXT, &windowContext ); + + //Non-FBO targets and FBO depth surfaces don't play along, only dummies which match the same + //context + if( !mDepthBuffer && !mStencilBuffer && mCreatorContext == windowContext ) + retVal = true; + } + else + { + //Check this isn't a dummy non-FBO depth buffer with an FBO target, don't mix them. + //If you don't want depth buffer, use a Null Depth Buffer, not a dummy one. + if( mDepthBuffer || mStencilBuffer ) + { + GLenum internalFormat = fbo->getFormat(); + GLenum depthFormat, stencilFormat; + mRenderSystem->_getDepthStencilFormatFor( internalFormat, &depthFormat, &stencilFormat ); + + bool bSameDepth = false; + + if( mDepthBuffer ) + bSameDepth |= mDepthBuffer->getGLFormat() == depthFormat; + + bool bSameStencil = false; if( !mStencilBuffer || mStencilBuffer == mDepthBuffer ) bSameStencil = stencilFormat == GL_NONE; @@ -131,10 +131,10 @@ namespace Ogre bSameStencil = stencilFormat == mStencilBuffer->getGLFormat(); } - retVal = bSameDepth && bSameStencil; - } - } + retVal = bSameDepth && bSameStencil; + } + } - return retVal; - } + return retVal; + } } diff --git a/RenderSystems/GL/src/OgreGLFBOMultiRenderTarget.cpp b/RenderSystems/GL/src/OgreGLFBOMultiRenderTarget.cpp index 6de78d019c3..5eb6c77affc 100755 --- a/RenderSystems/GL/src/OgreGLFBOMultiRenderTarget.cpp +++ b/RenderSystems/GL/src/OgreGLFBOMultiRenderTarget.cpp @@ -35,64 +35,64 @@ THE SOFTWARE. namespace Ogre { - GLFBOMultiRenderTarget::GLFBOMultiRenderTarget(GLFBOManager *manager, const String &name): - MultiRenderTarget(name), - fbo(manager, 0 /* TODO: multisampling on MRTs? */) - { - } + GLFBOMultiRenderTarget::GLFBOMultiRenderTarget(GLFBOManager *manager, const String &name): + MultiRenderTarget(name), + fbo(manager, 0 /* TODO: multisampling on MRTs? */) + { + } - GLFBOMultiRenderTarget::~GLFBOMultiRenderTarget() - { - } + GLFBOMultiRenderTarget::~GLFBOMultiRenderTarget() + { + } - void GLFBOMultiRenderTarget::bindSurfaceImpl(size_t attachment, RenderTexture *target) - { - /// Check if the render target is in the rendertarget->FBO map + void GLFBOMultiRenderTarget::bindSurfaceImpl(size_t attachment, RenderTexture *target) + { + /// Check if the render target is in the rendertarget->FBO map GLFrameBufferObject *fbobj = 0; target->getCustomAttribute(GLRenderTexture::CustomAttributeString_FBO, &fbobj); - assert(fbobj); - fbo.bindSurface(attachment, fbobj->getSurface(0)); + assert(fbobj); + fbo.bindSurface(attachment, fbobj->getSurface(0)); - // Set width and height - mWidth = fbo.getWidth(); - mHeight = fbo.getHeight(); - } + // Set width and height + mWidth = fbo.getWidth(); + mHeight = fbo.getHeight(); + } - void GLFBOMultiRenderTarget::unbindSurfaceImpl(size_t attachment) - { - fbo.unbindSurface(attachment); + void GLFBOMultiRenderTarget::unbindSurfaceImpl(size_t attachment) + { + fbo.unbindSurface(attachment); - // Set width and height - mWidth = fbo.getWidth(); - mHeight = fbo.getHeight(); - } + // Set width and height + mWidth = fbo.getWidth(); + mHeight = fbo.getHeight(); + } - void GLFBOMultiRenderTarget::getCustomAttribute( const String& name, void *pData ) - { - if( name == GLRenderTexture::CustomAttributeString_FBO ) + void GLFBOMultiRenderTarget::getCustomAttribute( const String& name, void *pData ) + { + if( name == GLRenderTexture::CustomAttributeString_FBO ) { *static_cast(pData) = &fbo; } - } - //----------------------------------------------------------------------------- - bool GLFBOMultiRenderTarget::attachDepthBuffer( DepthBuffer *depthBuffer ) - { - bool result; - if( (result = MultiRenderTarget::attachDepthBuffer( depthBuffer )) ) - fbo.attachDepthBuffer( depthBuffer ); + } + //----------------------------------------------------------------------------- + bool GLFBOMultiRenderTarget::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + bool result; + if( (result = MultiRenderTarget::attachDepthBuffer( depthBuffer )) ) + fbo.attachDepthBuffer( depthBuffer ); - return result; - } - //----------------------------------------------------------------------------- - void GLFBOMultiRenderTarget::detachDepthBuffer() - { - fbo.detachDepthBuffer(); - MultiRenderTarget::detachDepthBuffer(); - } - //----------------------------------------------------------------------------- - void GLFBOMultiRenderTarget::_detachDepthBuffer() - { - fbo.detachDepthBuffer(); - MultiRenderTarget::_detachDepthBuffer(); - } + return result; + } + //----------------------------------------------------------------------------- + void GLFBOMultiRenderTarget::detachDepthBuffer() + { + fbo.detachDepthBuffer(); + MultiRenderTarget::detachDepthBuffer(); + } + //----------------------------------------------------------------------------- + void GLFBOMultiRenderTarget::_detachDepthBuffer() + { + fbo.detachDepthBuffer(); + MultiRenderTarget::_detachDepthBuffer(); + } } diff --git a/RenderSystems/GL/src/OgreGLFBORenderTexture.cpp b/RenderSystems/GL/src/OgreGLFBORenderTexture.cpp index ef26b359b5b..095e235df23 100644 --- a/RenderSystems/GL/src/OgreGLFBORenderTexture.cpp +++ b/RenderSystems/GL/src/OgreGLFBORenderTexture.cpp @@ -55,41 +55,41 @@ namespace Ogre { { *static_cast(pData) = &mFB; } - else if (name == "GL_FBOID") - { + else if (name == "GL_FBOID") + { *static_cast(pData) = mFB.getGLFBOID(); - } - else if (name == "GL_MULTISAMPLEFBOID") - { + } + else if (name == "GL_MULTISAMPLEFBOID") + { *static_cast(pData) = mFB.getGLMultisampleFBOID(); - } + } + } + + void GLFBORenderTexture::swapBuffers() + { + mFB.swapBuffers(); } + //----------------------------------------------------------------------------- + bool GLFBORenderTexture::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + bool result; + if( (result = GLRenderTexture::attachDepthBuffer( depthBuffer )) ) + mFB.attachDepthBuffer( depthBuffer ); - void GLFBORenderTexture::swapBuffers() - { - mFB.swapBuffers(); - } - //----------------------------------------------------------------------------- - bool GLFBORenderTexture::attachDepthBuffer( DepthBuffer *depthBuffer ) - { - bool result; - if( (result = GLRenderTexture::attachDepthBuffer( depthBuffer )) ) - mFB.attachDepthBuffer( depthBuffer ); - - return result; - } - //----------------------------------------------------------------------------- - void GLFBORenderTexture::detachDepthBuffer() - { - mFB.detachDepthBuffer(); - GLRenderTexture::detachDepthBuffer(); - } - //----------------------------------------------------------------------------- - void GLFBORenderTexture::_detachDepthBuffer() - { - mFB.detachDepthBuffer(); - GLRenderTexture::_detachDepthBuffer(); - } + return result; + } + //----------------------------------------------------------------------------- + void GLFBORenderTexture::detachDepthBuffer() + { + mFB.detachDepthBuffer(); + GLRenderTexture::detachDepthBuffer(); + } + //----------------------------------------------------------------------------- + void GLFBORenderTexture::_detachDepthBuffer() + { + mFB.detachDepthBuffer(); + GLRenderTexture::_detachDepthBuffer(); + } /// Size of probe texture #define PROBE_SIZE 16 @@ -123,23 +123,23 @@ static const size_t depthBits[] = }; #define DEPTHFORMAT_COUNT (sizeof(depthFormats)/sizeof(GLenum)) - GLFBOManager::GLFBOManager(bool atimode): - mATIMode(atimode) + GLFBOManager::GLFBOManager(bool atimode): + mATIMode(atimode) { detectFBOFormats(); glGenFramebuffersEXT(1, &mTempFBO); } - GLFBOManager::~GLFBOManager() - { - if(!mRenderBufferMap.empty()) - { - LogManager::getSingleton().logMessage("GL: Warning! GLFBOManager destructor called, but not all renderbuffers were released.", LML_CRITICAL); - } + GLFBOManager::~GLFBOManager() + { + if(!mRenderBufferMap.empty()) + { + LogManager::getSingleton().logMessage("GL: Warning! GLFBOManager destructor called, but not all renderbuffers were released.", LML_CRITICAL); + } glDeleteFramebuffersEXT(1, &mTempFBO); - } + } void GLFBOManager::_createTempFramebuffer(GLuint fmt, GLuint &fb, GLuint &tid) { @@ -293,20 +293,20 @@ static const size_t depthBits[] = { mProps[x].valid = false; - // Fetch GL format token - GLenum fmt = GLPixelUtil::getGLInternalFormat((PixelFormat)x); + // Fetch GL format token + GLenum fmt = GLPixelUtil::getGLInternalFormat((PixelFormat)x); if(fmt == GL_NONE && x != 0) continue; - // No test for compressed formats - if(PixelUtil::isCompressed((PixelFormat)x)) - continue; + // No test for compressed formats + if(PixelUtil::isCompressed((PixelFormat)x)) + continue; - // Buggy ATI cards *crash* on non-RGB(A) formats - int depths[4]; - PixelUtil::getBitDepths((PixelFormat)x, depths); - if(fmt!=GL_NONE && mATIMode && (!depths[0] || !depths[1] || !depths[2])) - continue; + // Buggy ATI cards *crash* on non-RGB(A) formats + int depths[4]; + PixelUtil::getBitDepths((PixelFormat)x, depths); + if(fmt!=GL_NONE && mATIMode && (!depths[0] || !depths[1] || !depths[2])) + continue; // Create and attach framebuffer _createTempFramebuffer(fmt, fb, tid); @@ -314,15 +314,15 @@ static const size_t depthBits[] = // Check status GLuint status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - // Ignore status in case of fmt==GL_NONE, because no implementation will accept - // a buffer without *any* attachment. Buffers with only stencil and depth attachment - // might still be supported, so we must continue probing. + // Ignore status in case of fmt==GL_NONE, because no implementation will accept + // a buffer without *any* attachment. Buffers with only stencil and depth attachment + // might still be supported, so we must continue probing. if(fmt == GL_NONE || status == GL_FRAMEBUFFER_COMPLETE_EXT) { mProps[x].valid = true; - StringStream str; - str << "FBO " << PixelUtil::getFormatName((PixelFormat)x) - << " depth/stencil support: "; + StringStream str; + str << "FBO " << PixelUtil::getFormatName((PixelFormat)x) + << " depth/stencil support: "; // For each depth/stencil formats for (size_t depth = 0; depth < DEPTHFORMAT_COUNT; ++depth) @@ -335,8 +335,8 @@ static const size_t depthBits[] = { //StringStream l; //l << "Trying " << PixelUtil::getFormatName((PixelFormat)x) - // << " D" << depthBits[depth] - // << "S" << stencilBits[stencil]; + // << " D" << depthBits[depth] + // << "S" << stencilBits[stencil]; //LogManager::getSingleton().logMessage(l.str()); if (_tryFormat(depthFormats[depth], stencilFormats[stencil])) @@ -411,11 +411,11 @@ static const size_t depthBits[] = // Delete texture and framebuffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glDeleteFramebuffersEXT(1, &fb); - - // Workaround for NVIDIA / Linux 169.21 driver problem - // see http://www.ogre3d.org/phpBB2/viewtopic.php?t=38037&start=25 - glFinish(); - + + // Workaround for NVIDIA / Linux 169.21 driver problem + // see http://www.ogre3d.org/phpBB2/viewtopic.php?t=38037&start=25 + glFinish(); + if (fmt != GL_NONE) { glDeleteTextures(1, &tid); @@ -428,7 +428,7 @@ static const size_t depthBits[] = glDrawBuffer(old_drawbuffer); glReadBuffer(old_readbuffer); - String fmtstring = ""; + String fmtstring = ""; for(size_t x=0; xbestscore) @@ -482,16 +482,16 @@ static const size_t depthBits[] = } GLFBORenderTexture *GLFBOManager::createRenderTexture(const String &name, - const GLSurfaceDesc &target, bool writeGamma, uint fsaa) + const GLSurfaceDesc &target, bool writeGamma, uint fsaa) { GLFBORenderTexture *retval = new GLFBORenderTexture(this, name, target, writeGamma, fsaa); return retval; } - MultiRenderTarget *GLFBOManager::createMultiRenderTarget(const String & name) - { - return new GLFBOMultiRenderTarget(this, name); - } - //--------------------------------------------------------------------- + MultiRenderTarget *GLFBOManager::createMultiRenderTarget(const String & name) + { + return new GLFBOMultiRenderTarget(this, name); + } + //--------------------------------------------------------------------- void GLFBOManager::bind(RenderTarget *target) { /// Check if the render target is in the rendertarget->FBO map @@ -516,7 +516,7 @@ static const size_t depthBits[] = { retval.buffer = it->second.buffer; retval.zoffset = 0; - retval.numSamples = fsaa; + retval.numSamples = fsaa; // Increase refcount ++it->second.refcount; } @@ -527,7 +527,7 @@ static const size_t depthBits[] = mRenderBufferMap[key] = RBRef(rb); retval.buffer = rb; retval.zoffset = 0; - retval.numSamples = fsaa; + retval.numSamples = fsaa; } } //std::cerr << "Requested renderbuffer with format " << std::hex << format << std::dec << " of " << width << "x" << height << " :" << retval.buffer << std::endl; @@ -556,17 +556,17 @@ static const size_t depthBits[] = RBFormat key(surface.buffer->getGLFormat(), surface.buffer->getWidth(), surface.buffer->getHeight(), surface.numSamples); RenderBufferMap::iterator it = mRenderBufferMap.find(key); if(it != mRenderBufferMap.end()) - { - // Decrease refcount - --it->second.refcount; - if(it->second.refcount==0) - { - // If refcount reaches zero, delete buffer and remove from map - delete it->second.buffer; - mRenderBufferMap.erase(it); - //std::cerr << "Destroyed renderbuffer of format " << std::hex << key.format << std::dec - // << " of " << key.width << "x" << key.height << std::endl; - } - } + { + // Decrease refcount + --it->second.refcount; + if(it->second.refcount==0) + { + // If refcount reaches zero, delete buffer and remove from map + delete it->second.buffer; + mRenderBufferMap.erase(it); + //std::cerr << "Destroyed renderbuffer of format " << std::hex << key.format << std::dec + // << " of " << key.width << "x" << key.height << std::endl; + } + } } } diff --git a/RenderSystems/GL/src/OgreGLFrameBufferObject.cpp b/RenderSystems/GL/src/OgreGLFrameBufferObject.cpp index 3e297401780..c080cb7d0af 100755 --- a/RenderSystems/GL/src/OgreGLFrameBufferObject.cpp +++ b/RenderSystems/GL/src/OgreGLFrameBufferObject.cpp @@ -43,29 +43,29 @@ namespace Ogre { { // Generate framebuffer object glGenFramebuffersEXT(1, &mFB); - // check multisampling - if (GLEW_EXT_framebuffer_blit && GLEW_EXT_framebuffer_multisample) - { - // check samples supported - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFB); - GLint maxSamples; - glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - mNumSamples = std::min(mNumSamples, (GLsizei)maxSamples); - } - else - { - mNumSamples = 0; - } - // will we need a second FBO to do multisampling? - if (mNumSamples) - { - glGenFramebuffersEXT(1, &mMultisampleFB); - } - else - { - mMultisampleFB = 0; - } + // check multisampling + if (GLEW_EXT_framebuffer_blit && GLEW_EXT_framebuffer_multisample) + { + // check samples supported + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFB); + GLint maxSamples; + glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSamples); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + mNumSamples = std::min(mNumSamples, (GLsizei)maxSamples); + } + else + { + mNumSamples = 0; + } + // will we need a second FBO to do multisampling? + if (mNumSamples) + { + glGenFramebuffersEXT(1, &mMultisampleFB); + } + else + { + mMultisampleFB = 0; + } // Initialise state mDepth.buffer=0; mStencil.buffer=0; @@ -78,49 +78,49 @@ namespace Ogre { { mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); - mManager->releaseRenderBuffer(mMultisampleColourBuffer); + mManager->releaseRenderBuffer(mMultisampleColourBuffer); // Delete framebuffer object glDeleteFramebuffersEXT(1, &mFB); - if (mMultisampleFB) - glDeleteFramebuffersEXT(1, &mMultisampleFB); + if (mMultisampleFB) + glDeleteFramebuffersEXT(1, &mMultisampleFB); } void GLFrameBufferObject::bindSurface(size_t attachment, const GLSurfaceDesc &target) { assert(attachment < OGRE_MAX_MULTIPLE_RENDER_TARGETS); mColour[attachment] = target; - // Re-initialise - if(mColour[0].buffer) - initialise(); + // Re-initialise + if(mColour[0].buffer) + initialise(); } void GLFrameBufferObject::unbindSurface(size_t attachment) { assert(attachment < OGRE_MAX_MULTIPLE_RENDER_TARGETS); mColour[attachment].buffer = 0; - // Re-initialise if buffer 0 still bound - if(mColour[0].buffer) - { - initialise(); - } + // Re-initialise if buffer 0 still bound + if(mColour[0].buffer) + { + initialise(); + } } void GLFrameBufferObject::initialise() { - // Release depth and stencil, if they were bound + // Release depth and stencil, if they were bound mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); - mManager->releaseRenderBuffer(mMultisampleColourBuffer); + mManager->releaseRenderBuffer(mMultisampleColourBuffer); // First buffer must be bound if(!mColour[0].buffer) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Attachment 0 must have surface attached", - "GLFrameBufferObject::initialise"); + "GLFrameBufferObject::initialise"); } - // If we're doing multisampling, then we need another FBO which contains a - // renderbuffer which is set up to multisample, and we'll blit it to the final - // FBO afterwards to perform the multisample resolve. In that case, the - // mMultisampleFB is bound during rendering and is the one with a depth/stencil + // If we're doing multisampling, then we need another FBO which contains a + // renderbuffer which is set up to multisample, and we'll blit it to the final + // FBO afterwards to perform the multisample resolve. In that case, the + // mMultisampleFB is bound during rendering and is the one with a depth/stencil // Store basic stats uint32 width = mColour[0].buffer->getWidth(); @@ -128,8 +128,8 @@ namespace Ogre { GLuint format = mColour[0].buffer->getGLFormat(); ushort maxSupportedMRTs = Root::getSingleton().getRenderSystem()->getCapabilities()->getNumMultiRenderTargets(); - // Bind simple buffer to add colour attachments - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFB); + // Bind simple buffer to add colour attachments + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFB); // Bind all attachment points to frame buffer for(unsigned int x=0; xbindToFramebuffer(GL_COLOR_ATTACHMENT0_EXT+x, mColour[x].zoffset); + mColour[x].buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_EXT+x, mColour[x].zoffset); } else { @@ -162,66 +162,66 @@ namespace Ogre { } } - // Now deal with depth / stencil - if (mMultisampleFB) - { - // Bind multisample buffer - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mMultisampleFB); + // Now deal with depth / stencil + if (mMultisampleFB) + { + // Bind multisample buffer + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mMultisampleFB); - // Create AA render buffer (colour) - // note, this can be shared too because we blit it to the final FBO - // right after the render is finished - mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); + // Create AA render buffer (colour) + // note, this can be shared too because we blit it to the final FBO + // right after the render is finished + mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); - // Attach it, because we won't be attaching below and non-multisample has - // actually been attached to other FBO - mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_EXT, - mMultisampleColourBuffer.zoffset); + // Attach it, because we won't be attaching below and non-multisample has + // actually been attached to other FBO + mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_EXT, + mMultisampleColourBuffer.zoffset); - // depth & stencil will be dealt with below + // depth & stencil will be dealt with below - } + } // Depth buffer is not handled here anymore. - // See GLFrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() + // See GLFrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() - // Do glDrawBuffer calls - GLenum bufs[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - GLsizei n=0; - for(unsigned int x=0; xgetWidth(); - uint32 height = mColour[0].buffer->getHeight(); - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mMultisampleFB); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFB); - glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + // Blit from multisample buffer to final buffer, triggers resolve + uint32 width = mColour[0].buffer->getWidth(); + uint32 height = mColour[0].buffer->getHeight(); + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mMultisampleFB); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFB); + glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); // Unbind glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, oldfb); - } - } + } + } - void GLFrameBufferObject::attachDepthBuffer( DepthBuffer *depthBuffer ) - { - GLDepthBuffer *glDepthBuffer = static_cast(depthBuffer); + void GLFrameBufferObject::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + GLDepthBuffer *glDepthBuffer = static_cast(depthBuffer); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mMultisampleFB ? mMultisampleFB : mFB ); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mMultisampleFB ? mMultisampleFB : mFB ); - if( glDepthBuffer ) - { - GLRenderBuffer *depthBuf = glDepthBuffer->getDepthBuffer(); - GLRenderBuffer *stencilBuf = glDepthBuffer->getStencilBuffer(); + if( glDepthBuffer ) + { + GLRenderBuffer *depthBuf = glDepthBuffer->getDepthBuffer(); + GLRenderBuffer *stencilBuf = glDepthBuffer->getStencilBuffer(); - // Attach depth buffer, if it has one. - if( depthBuf ) - depthBuf->bindToFramebuffer( GL_DEPTH_ATTACHMENT_EXT, 0 ); + // Attach depth buffer, if it has one. + if( depthBuf ) + depthBuf->bindToFramebuffer( GL_DEPTH_ATTACHMENT_EXT, 0 ); - // Attach stencil buffer, if it has one. - if( stencilBuf ) - stencilBuf->bindToFramebuffer( GL_STENCIL_ATTACHMENT_EXT, 0 ); - } - else - { - glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, 0); - glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, 0); - } - } - //----------------------------------------------------------------------------- - void GLFrameBufferObject::detachDepthBuffer() - { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mMultisampleFB ? mMultisampleFB : mFB ); - glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0 ); - glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, 0 ); - } + // Attach stencil buffer, if it has one. + if( stencilBuf ) + stencilBuf->bindToFramebuffer( GL_STENCIL_ATTACHMENT_EXT, 0 ); + } + else + { + glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, 0); + glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, 0); + } + } + //----------------------------------------------------------------------------- + void GLFrameBufferObject::detachDepthBuffer() + { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mMultisampleFB ? mMultisampleFB : mFB ); + glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0 ); + glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, 0 ); + } uint32 GLFrameBufferObject::getWidth() { @@ -323,7 +323,7 @@ namespace Ogre { assert(mColour[0].buffer); return mColour[0].buffer->getFormat(); } - GLsizei GLFrameBufferObject::getFSAA() + GLsizei GLFrameBufferObject::getFSAA() { return mNumSamples; } diff --git a/RenderSystems/GL/src/OgreGLGpuNvparseProgram.cpp b/RenderSystems/GL/src/OgreGLGpuNvparseProgram.cpp index 8aef0e364f4..21fa85a79bb 100644 --- a/RenderSystems/GL/src/OgreGLGpuNvparseProgram.cpp +++ b/RenderSystems/GL/src/OgreGLGpuNvparseProgram.cpp @@ -71,18 +71,18 @@ void GLGpuNvparseProgram::bindProgramParameters(GpuProgramParametersSharedPtr pa { // NB, register combiners uses 2 constants per texture stage (0 and 1) // We have stored these as (stage * 2) + const_index in the physical buffer - // There are no other parameters in a register combiners shader - const FloatConstantList& floatList = - params->getFloatConstantList(); - size_t index = 0; - for (FloatConstantList::const_iterator i = floatList.begin(); - i != floatList.end(); ++i, ++index) - { - GLenum combinerStage = GL_COMBINER0_NV + (unsigned int)(index / 2); - GLenum pname = GL_CONSTANT_COLOR0_NV + (index % 2); - glCombinerStageParameterfvNV(combinerStage, pname, &(*i)); - - } + // There are no other parameters in a register combiners shader + const FloatConstantList& floatList = + params->getFloatConstantList(); + size_t index = 0; + for (FloatConstantList::const_iterator i = floatList.begin(); + i != floatList.end(); ++i, ++index) + { + GLenum combinerStage = GL_COMBINER0_NV + (unsigned int)(index / 2); + GLenum pname = GL_CONSTANT_COLOR0_NV + (index % 2); + glCombinerStageParameterfvNV(combinerStage, pname, &(*i)); + + } } void GLGpuNvparseProgram::unloadImpl(void) diff --git a/RenderSystems/GL/src/OgreGLGpuProgram.cpp b/RenderSystems/GL/src/OgreGLGpuProgram.cpp index a7cc7c50f14..89f630b0844 100644 --- a/RenderSystems/GL/src/OgreGLGpuProgram.cpp +++ b/RenderSystems/GL/src/OgreGLGpuProgram.cpp @@ -35,16 +35,16 @@ namespace Ogre { GLenum getGLShaderType(GpuProgramType programType) { - switch (programType) - { - case GPT_VERTEX_PROGRAM: - default: - return GL_VERTEX_PROGRAM_ARB; - case GPT_GEOMETRY_PROGRAM: - return GL_GEOMETRY_PROGRAM_NV; - case GPT_FRAGMENT_PROGRAM: - return GL_FRAGMENT_PROGRAM_ARB; - } + switch (programType) + { + case GPT_VERTEX_PROGRAM: + default: + return GL_VERTEX_PROGRAM_ARB; + case GPT_GEOMETRY_PROGRAM: + return GL_GEOMETRY_PROGRAM_NV; + case GPT_FRAGMENT_PROGRAM: + return GL_FRAGMENT_PROGRAM_ARB; + } } GLGpuProgram::GLGpuProgram(ResourceManager* creator, const String& name, @@ -67,75 +67,75 @@ GLGpuProgram::~GLGpuProgram() GLuint GLGpuProgram::getAttributeIndex(VertexElementSemantic semantic, uint index) { - return getFixedAttributeIndex(semantic, index); + return getFixedAttributeIndex(semantic, index); } GLuint GLGpuProgram::getFixedAttributeIndex(VertexElementSemantic semantic, uint index) { - // Some drivers (e.g. OS X on nvidia) incorrectly determine the attribute binding automatically - // and end up aliasing existing built-ins. So avoid! Fixed builtins are: - - // a builtin custom attrib name - // ---------------------------------------------- - // 0 gl_Vertex vertex - // 1 n/a blendWeights - // 2 gl_Normal normal - // 3 gl_Color colour - // 4 gl_SecondaryColor secondary_colour - // 5 gl_FogCoord fog_coord - // 7 n/a blendIndices - // 8 gl_MultiTexCoord0 uv0 - // 9 gl_MultiTexCoord1 uv1 - // 10 gl_MultiTexCoord2 uv2 - // 11 gl_MultiTexCoord3 uv3 - // 12 gl_MultiTexCoord4 uv4 - // 13 gl_MultiTexCoord5 uv5 - // 14 gl_MultiTexCoord6 uv6, tangent - // 15 gl_MultiTexCoord7 uv7, binormal - switch(semantic) - { - case VES_POSITION: - return 0; - case VES_BLEND_WEIGHTS: - return 1; - case VES_NORMAL: - return 2; - case VES_DIFFUSE: - return 3; - case VES_SPECULAR: - return 4; - case VES_BLEND_INDICES: - return 7; - case VES_TEXTURE_COORDINATES: - return 8 + index; - case VES_TANGENT: - return 14; - case VES_BINORMAL: - return 15; - default: - assert(false && "Missing attribute!"); - return 0; - }; + // Some drivers (e.g. OS X on nvidia) incorrectly determine the attribute binding automatically + // and end up aliasing existing built-ins. So avoid! Fixed builtins are: + + // a builtin custom attrib name + // ---------------------------------------------- + // 0 gl_Vertex vertex + // 1 n/a blendWeights + // 2 gl_Normal normal + // 3 gl_Color colour + // 4 gl_SecondaryColor secondary_colour + // 5 gl_FogCoord fog_coord + // 7 n/a blendIndices + // 8 gl_MultiTexCoord0 uv0 + // 9 gl_MultiTexCoord1 uv1 + // 10 gl_MultiTexCoord2 uv2 + // 11 gl_MultiTexCoord3 uv3 + // 12 gl_MultiTexCoord4 uv4 + // 13 gl_MultiTexCoord5 uv5 + // 14 gl_MultiTexCoord6 uv6, tangent + // 15 gl_MultiTexCoord7 uv7, binormal + switch(semantic) + { + case VES_POSITION: + return 0; + case VES_BLEND_WEIGHTS: + return 1; + case VES_NORMAL: + return 2; + case VES_DIFFUSE: + return 3; + case VES_SPECULAR: + return 4; + case VES_BLEND_INDICES: + return 7; + case VES_TEXTURE_COORDINATES: + return 8 + index; + case VES_TANGENT: + return 14; + case VES_BINORMAL: + return 15; + default: + assert(false && "Missing attribute!"); + return 0; + }; } bool GLGpuProgram::isAttributeValid(VertexElementSemantic semantic, uint index) { - // default implementation - switch(semantic) - { - case VES_POSITION: - case VES_NORMAL: - case VES_DIFFUSE: - case VES_SPECULAR: - case VES_TEXTURE_COORDINATES: - return false; - case VES_BLEND_WEIGHTS: - case VES_BLEND_INDICES: - case VES_BINORMAL: - case VES_TANGENT: - return true; // with default binding - } + // default implementation + switch(semantic) + { + case VES_POSITION: + case VES_NORMAL: + case VES_DIFFUSE: + case VES_SPECULAR: + case VES_TEXTURE_COORDINATES: + return false; + case VES_BLEND_WEIGHTS: + case VES_BLEND_INDICES: + case VES_BINORMAL: + case VES_TANGENT: + return true; // with default binding + } return false; } @@ -171,7 +171,7 @@ GLArbGpuProgram::~GLArbGpuProgram() void GLArbGpuProgram::setType(GpuProgramType t) { GLGpuProgram::setType(t); - mProgramType = getGLShaderType(t); + mProgramType = getGLShaderType(t); } void GLArbGpuProgram::bindProgram(void) @@ -190,36 +190,36 @@ void GLArbGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params { GLenum type = getGLShaderType(mType); - // only supports float constants - GpuLogicalBufferStructPtr floatStruct = params->getFloatLogicalBufferStruct(); - - for (GpuLogicalIndexUseMap::const_iterator i = floatStruct->map.begin(); - i != floatStruct->map.end(); ++i) - { - if (i->second.variability & mask) - { - GLuint logicalIndex = static_cast(i->first); - const float* pFloat = params->getFloatPointer(i->second.physicalIndex); - // Iterate over the params, set in 4-float chunks (low-level) - for (size_t j = 0; j < i->second.currentSize; j+=4) - { - glProgramLocalParameter4fvARB(type, logicalIndex, pFloat); - pFloat += 4; - ++logicalIndex; - } - } - } + // only supports float constants + GpuLogicalBufferStructPtr floatStruct = params->getFloatLogicalBufferStruct(); + + for (GpuLogicalIndexUseMap::const_iterator i = floatStruct->map.begin(); + i != floatStruct->map.end(); ++i) + { + if (i->second.variability & mask) + { + GLuint logicalIndex = static_cast(i->first); + const float* pFloat = params->getFloatPointer(i->second.physicalIndex); + // Iterate over the params, set in 4-float chunks (low-level) + for (size_t j = 0; j < i->second.currentSize; j+=4) + { + glProgramLocalParameter4fvARB(type, logicalIndex, pFloat); + pFloat += 4; + ++logicalIndex; + } + } + } } void GLArbGpuProgram::bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) { if (params->hasPassIterationNumber()) { - GLenum type = getGLShaderType(mType); + GLenum type = getGLShaderType(mType); - size_t physicalIndex = params->getPassIterationNumberIndex(); - size_t logicalIndex = params->getFloatLogicalIndexForPhysicalIndex(physicalIndex); - const float* pFloat = params->getFloatPointer(physicalIndex); + size_t physicalIndex = params->getPassIterationNumberIndex(); + size_t logicalIndex = params->getFloatLogicalIndexForPhysicalIndex(physicalIndex); + const float* pFloat = params->getFloatPointer(physicalIndex); glProgramLocalParameter4fvARB(type, (GLuint)logicalIndex, pFloat); } @@ -243,8 +243,8 @@ void GLArbGpuProgram::loadFromSource(void) { GLint errPos; glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos); - String errPosStr = StringConverter::toString(errPos); - const char* errStr = (const char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB); + String errPosStr = StringConverter::toString(errPos); + const char* errStr = (const char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB); // XXX New exception code? OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Cannot load GL vertex program " + mName + diff --git a/RenderSystems/GL/src/OgreGLGpuProgramManager.cpp b/RenderSystems/GL/src/OgreGLGpuProgramManager.cpp index 8d51026d534..a17cf8a0a17 100644 --- a/RenderSystems/GL/src/OgreGLGpuProgramManager.cpp +++ b/RenderSystems/GL/src/OgreGLGpuProgramManager.cpp @@ -86,10 +86,10 @@ Resource* GLGpuProgramManager::createImpl(const String& name, ResourceHandle han { gpt = GPT_VERTEX_PROGRAM; } - else if (paramType->second == "geometry_program") - { - gpt = GPT_GEOMETRY_PROGRAM; - } + else if (paramType->second == "geometry_program") + { + gpt = GPT_GEOMETRY_PROGRAM; + } else { gpt = GPT_FRAGMENT_PROGRAM; diff --git a/RenderSystems/GL/src/OgreGLHardwareBufferManager.cpp b/RenderSystems/GL/src/OgreGLHardwareBufferManager.cpp index d909cb6d7c8..36e517fef82 100644 --- a/RenderSystems/GL/src/OgreGLHardwareBufferManager.cpp +++ b/RenderSystems/GL/src/OgreGLHardwareBufferManager.cpp @@ -37,44 +37,44 @@ THE SOFTWARE. namespace Ogre { //----------------------------------------------------------------------- - // Scratch pool management (32 bit structure) - struct GLScratchBufferAlloc - { - /// Size in bytes - uint32 size: 31; - /// Free? (pack with size) - uint32 free: 1; - }; - #define SCRATCH_POOL_SIZE 1 * 1024 * 1024 - #define SCRATCH_ALIGNMENT 32 - //--------------------------------------------------------------------- + // Scratch pool management (32 bit structure) + struct GLScratchBufferAlloc + { + /// Size in bytes + uint32 size: 31; + /// Free? (pack with size) + uint32 free: 1; + }; + #define SCRATCH_POOL_SIZE 1 * 1024 * 1024 + #define SCRATCH_ALIGNMENT 32 + //--------------------------------------------------------------------- GLHardwareBufferManagerBase::GLHardwareBufferManagerBase() - : mScratchBufferPool(NULL), mMapBufferThreshold(OGRE_GL_DEFAULT_MAP_BUFFER_THRESHOLD) + : mScratchBufferPool(NULL), mMapBufferThreshold(OGRE_GL_DEFAULT_MAP_BUFFER_THRESHOLD) { - mStateCacheManager = dynamic_cast(Root::getSingleton().getRenderSystem())->getGLSupportRef()->getStateCacheManager(); + mStateCacheManager = dynamic_cast(Root::getSingleton().getRenderSystem())->getGLSupportRef()->getStateCacheManager(); - // Init scratch pool - // TODO make it a configurable size? - // 32-bit aligned buffer - mScratchBufferPool = static_cast(OGRE_MALLOC_ALIGN(SCRATCH_POOL_SIZE, MEMCATEGORY_GEOMETRY, SCRATCH_ALIGNMENT)); - GLScratchBufferAlloc* ptrAlloc = (GLScratchBufferAlloc*)mScratchBufferPool; - ptrAlloc->size = SCRATCH_POOL_SIZE - sizeof(GLScratchBufferAlloc); - ptrAlloc->free = 1; + // Init scratch pool + // TODO make it a configurable size? + // 32-bit aligned buffer + mScratchBufferPool = static_cast(OGRE_MALLOC_ALIGN(SCRATCH_POOL_SIZE, MEMCATEGORY_GEOMETRY, SCRATCH_ALIGNMENT)); + GLScratchBufferAlloc* ptrAlloc = (GLScratchBufferAlloc*)mScratchBufferPool; + ptrAlloc->size = SCRATCH_POOL_SIZE - sizeof(GLScratchBufferAlloc); + ptrAlloc->free = 1; - // non-Win32 machines are having issues glBufferSubData, looks like buffer corruption - // disable for now until we figure out where the problem lies -# if OGRE_PLATFORM != OGRE_PLATFORM_WIN32 - mMapBufferThreshold = 0; -# endif + // non-Win32 machines are having issues glBufferSubData, looks like buffer corruption + // disable for now until we figure out where the problem lies +# if OGRE_PLATFORM != OGRE_PLATFORM_WIN32 + mMapBufferThreshold = 0; +# endif - // Win32 machines with ATI GPU are having issues glMapBuffer, looks like buffer corruption - // disable for now until we figure out where the problem lies -# if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - if (Root::getSingleton().getRenderSystem()->getCapabilities()->getVendor() == GPU_AMD) - { - mMapBufferThreshold = 0xffffffffUL /* maximum unsigned long value */; - } -# endif + // Win32 machines with ATI GPU are having issues glMapBuffer, looks like buffer corruption + // disable for now until we figure out where the problem lies +# if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 + if (Root::getSingleton().getRenderSystem()->getCapabilities()->getVendor() == GPU_AMD) + { + mMapBufferThreshold = 0xffffffffUL /* maximum unsigned long value */; + } +# endif } //----------------------------------------------------------------------- @@ -83,19 +83,19 @@ namespace Ogre { destroyAllDeclarations(); destroyAllBindings(); - OGRE_FREE_ALIGN(mScratchBufferPool, MEMCATEGORY_GEOMETRY, SCRATCH_ALIGNMENT); + OGRE_FREE_ALIGN(mScratchBufferPool, MEMCATEGORY_GEOMETRY, SCRATCH_ALIGNMENT); } //----------------------------------------------------------------------- HardwareVertexBufferSharedPtr GLHardwareBufferManagerBase::createVertexBuffer( size_t vertexSize, size_t numVerts, HardwareBuffer::Usage usage, bool useShadowBuffer) { - GLHardwareVertexBuffer* buf = - new GLHardwareVertexBuffer(this, vertexSize, numVerts, usage, useShadowBuffer); - { + GLHardwareVertexBuffer* buf = + new GLHardwareVertexBuffer(this, vertexSize, numVerts, usage, useShadowBuffer); + { OGRE_LOCK_MUTEX(mVertexBuffersMutex); - mVertexBuffers.insert(buf); - } - return HardwareVertexBufferSharedPtr(buf); + mVertexBuffers.insert(buf); + } + return HardwareVertexBufferSharedPtr(buf); } //----------------------------------------------------------------------- HardwareIndexBufferSharedPtr @@ -103,37 +103,37 @@ namespace Ogre { HardwareIndexBuffer::IndexType itype, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer) { - GLHardwareIndexBuffer* buf = - new GLHardwareIndexBuffer(this, itype, numIndexes, usage, useShadowBuffer); - { + GLHardwareIndexBuffer* buf = + new GLHardwareIndexBuffer(this, itype, numIndexes, usage, useShadowBuffer); + { OGRE_LOCK_MUTEX(mIndexBuffersMutex); - mIndexBuffers.insert(buf); - } - return HardwareIndexBufferSharedPtr(buf); + mIndexBuffers.insert(buf); + } + return HardwareIndexBufferSharedPtr(buf); } //--------------------------------------------------------------------- RenderToVertexBufferSharedPtr GLHardwareBufferManagerBase::createRenderToVertexBuffer() - { + { return RenderToVertexBufferSharedPtr(new GLRenderToVertexBuffer); } - //--------------------------------------------------------------------- - HardwareUniformBufferSharedPtr - GLHardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + //--------------------------------------------------------------------- + HardwareUniformBufferSharedPtr + GLHardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Uniform buffers not supported in OpenGL RenderSystem.", "GLHardwareBufferManagerBase::createUniformBuffer"); - } + } HardwareCounterBufferSharedPtr GLHardwareBufferManagerBase::createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Counter buffers not supported in OpenGL RenderSystem.", "GLHardwareBufferManagerBase::createCounterBuffer"); - } + } //--------------------------------------------------------------------- GLenum GLHardwareBufferManagerBase::getGLUsage(unsigned int usage) @@ -168,131 +168,131 @@ namespace Ogre { case VET_SHORT4: return GL_SHORT; case VET_COLOUR: - case VET_COLOUR_ABGR: - case VET_COLOUR_ARGB: + case VET_COLOUR_ABGR: + case VET_COLOUR_ARGB: case VET_UBYTE4: return GL_UNSIGNED_BYTE; default: return 0; }; } - //--------------------------------------------------------------------- - //--------------------------------------------------------------------- - void* GLHardwareBufferManagerBase::allocateScratch(uint32 size) - { - // simple forward link search based on alloc sizes - // not that fast but the list should never get that long since not many - // locks at once (hopefully) + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void* GLHardwareBufferManagerBase::allocateScratch(uint32 size) + { + // simple forward link search based on alloc sizes + // not that fast but the list should never get that long since not many + // locks at once (hopefully) OGRE_LOCK_MUTEX(mScratchMutex); - // Alignment - round up the size to 32 bits - // control blocks are 32 bits too so this packs nicely - if (size % 4 != 0) - { - size += 4 - (size % 4); - } + // Alignment - round up the size to 32 bits + // control blocks are 32 bits too so this packs nicely + if (size % 4 != 0) + { + size += 4 - (size % 4); + } - uint32 bufferPos = 0; - while (bufferPos < SCRATCH_POOL_SIZE) - { - GLScratchBufferAlloc* pNext = (GLScratchBufferAlloc*)(mScratchBufferPool + bufferPos); - // Big enough? - if (pNext->free && pNext->size >= size) - { - // split? And enough space for control block - if(pNext->size > size + sizeof(GLScratchBufferAlloc)) - { - uint32 offset = (uint32)sizeof(GLScratchBufferAlloc) + size; + uint32 bufferPos = 0; + while (bufferPos < SCRATCH_POOL_SIZE) + { + GLScratchBufferAlloc* pNext = (GLScratchBufferAlloc*)(mScratchBufferPool + bufferPos); + // Big enough? + if (pNext->free && pNext->size >= size) + { + // split? And enough space for control block + if(pNext->size > size + sizeof(GLScratchBufferAlloc)) + { + uint32 offset = (uint32)sizeof(GLScratchBufferAlloc) + size; - GLScratchBufferAlloc* pSplitAlloc = (GLScratchBufferAlloc*) - (mScratchBufferPool + bufferPos + offset); - pSplitAlloc->free = 1; - // split size is remainder minus new control block - pSplitAlloc->size = pNext->size - size - sizeof(GLScratchBufferAlloc); + GLScratchBufferAlloc* pSplitAlloc = (GLScratchBufferAlloc*) + (mScratchBufferPool + bufferPos + offset); + pSplitAlloc->free = 1; + // split size is remainder minus new control block + pSplitAlloc->size = pNext->size - size - sizeof(GLScratchBufferAlloc); - // New size of current - pNext->size = size; - } - // allocate and return - pNext->free = 0; + // New size of current + pNext->size = size; + } + // allocate and return + pNext->free = 0; - // return pointer just after this control block (++ will do that for us) - return ++pNext; + // return pointer just after this control block (++ will do that for us) + return ++pNext; - } + } - bufferPos += (uint32)sizeof(GLScratchBufferAlloc) + pNext->size; + bufferPos += (uint32)sizeof(GLScratchBufferAlloc) + pNext->size; - } + } - // no available alloc - return 0; + // no available alloc + return 0; - } - //--------------------------------------------------------------------- - void GLHardwareBufferManagerBase::deallocateScratch(void* ptr) - { + } + //--------------------------------------------------------------------- + void GLHardwareBufferManagerBase::deallocateScratch(void* ptr) + { OGRE_LOCK_MUTEX(mScratchMutex); - // Simple linear search dealloc - uint32 bufferPos = 0; - GLScratchBufferAlloc* pLast = 0; - while (bufferPos < SCRATCH_POOL_SIZE) - { - GLScratchBufferAlloc* pCurrent = (GLScratchBufferAlloc*)(mScratchBufferPool + bufferPos); - - // Pointers match? - if ((mScratchBufferPool + bufferPos + sizeof(GLScratchBufferAlloc)) - == ptr) - { - // dealloc - pCurrent->free = 1; - - // merge with previous - if (pLast && pLast->free) - { - // adjust buffer pos - bufferPos -= (pLast->size + (uint32)sizeof(GLScratchBufferAlloc)); - // merge free space - pLast->size += pCurrent->size + sizeof(GLScratchBufferAlloc); - pCurrent = pLast; - } + // Simple linear search dealloc + uint32 bufferPos = 0; + GLScratchBufferAlloc* pLast = 0; + while (bufferPos < SCRATCH_POOL_SIZE) + { + GLScratchBufferAlloc* pCurrent = (GLScratchBufferAlloc*)(mScratchBufferPool + bufferPos); + + // Pointers match? + if ((mScratchBufferPool + bufferPos + sizeof(GLScratchBufferAlloc)) + == ptr) + { + // dealloc + pCurrent->free = 1; + + // merge with previous + if (pLast && pLast->free) + { + // adjust buffer pos + bufferPos -= (pLast->size + (uint32)sizeof(GLScratchBufferAlloc)); + // merge free space + pLast->size += pCurrent->size + sizeof(GLScratchBufferAlloc); + pCurrent = pLast; + } - // merge with next - uint32 offset = bufferPos + pCurrent->size + (uint32)sizeof(GLScratchBufferAlloc); - if (offset < SCRATCH_POOL_SIZE) - { - GLScratchBufferAlloc* pNext = (GLScratchBufferAlloc*)( - mScratchBufferPool + offset); - if (pNext->free) - { - pCurrent->size += pNext->size + sizeof(GLScratchBufferAlloc); - } - } + // merge with next + uint32 offset = bufferPos + pCurrent->size + (uint32)sizeof(GLScratchBufferAlloc); + if (offset < SCRATCH_POOL_SIZE) + { + GLScratchBufferAlloc* pNext = (GLScratchBufferAlloc*)( + mScratchBufferPool + offset); + if (pNext->free) + { + pCurrent->size += pNext->size + sizeof(GLScratchBufferAlloc); + } + } - // done - return; - } + // done + return; + } - bufferPos += (uint32)sizeof(GLScratchBufferAlloc) + pCurrent->size; - pLast = pCurrent; + bufferPos += (uint32)sizeof(GLScratchBufferAlloc) + pCurrent->size; + pLast = pCurrent; - } + } - // Should never get here unless there's a corruption - assert (false && "Memory deallocation error"); + // Should never get here unless there's a corruption + assert (false && "Memory deallocation error"); - } - //--------------------------------------------------------------------- - size_t GLHardwareBufferManagerBase::getGLMapBufferThreshold() const - { - return mMapBufferThreshold; - } - //--------------------------------------------------------------------- - void GLHardwareBufferManagerBase::setGLMapBufferThreshold( const size_t value ) - { - mMapBufferThreshold = value; - } + } + //--------------------------------------------------------------------- + size_t GLHardwareBufferManagerBase::getGLMapBufferThreshold() const + { + return mMapBufferThreshold; + } + //--------------------------------------------------------------------- + void GLHardwareBufferManagerBase::setGLMapBufferThreshold( const size_t value ) + { + mMapBufferThreshold = value; + } } diff --git a/RenderSystems/GL/src/OgreGLHardwareIndexBuffer.cpp b/RenderSystems/GL/src/OgreGLHardwareIndexBuffer.cpp index 84d78ce67ba..2431f1786e0 100644 --- a/RenderSystems/GL/src/OgreGLHardwareIndexBuffer.cpp +++ b/RenderSystems/GL/src/OgreGLHardwareIndexBuffer.cpp @@ -32,7 +32,7 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- GLHardwareIndexBuffer::GLHardwareIndexBuffer(HardwareBufferManagerBase* mgr, IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer) : HardwareIndexBuffer(mgr, idxType, numIndexes, usage, false, useShadowBuffer), mLockedToScratch(false), @@ -47,7 +47,7 @@ namespace Ogre { "GLHardwareIndexBuffer::GLHardwareIndexBuffer"); } - static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId); + static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId); // Initialise buffer and set usage glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, @@ -55,12 +55,12 @@ namespace Ogre { //std::cerr << "creating index buffer " << mBufferId << std::endl; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- GLHardwareIndexBuffer::~GLHardwareIndexBuffer() { static_cast(mMgr)->getStateCacheManager()->deleteGLBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId); } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void* GLHardwareIndexBuffer::lockImpl(size_t offset, size_t length, LockOptions options) { @@ -72,101 +72,101 @@ namespace Ogre { } - void* retPtr = 0; - - GLHardwareBufferManager* glBufManager = static_cast(HardwareBufferManager::getSingletonPtr()); - - // Try to use scratch buffers for smaller buffers - if( length < glBufManager->getGLMapBufferThreshold() ) - { - retPtr = glBufManager->allocateScratch((uint32)length); - if (retPtr) - { - mLockedToScratch = true; - mScratchOffset = offset; - mScratchSize = length; - mScratchPtr = retPtr; - mScratchUploadOnUnlock = (options != HBL_READ_ONLY); - - if (options != HBL_DISCARD && options != HBL_NO_OVERWRITE) - { - // have to read back the data before returning the pointer - readData(offset, length, retPtr); - } - } - } - - if (!retPtr) - { + void* retPtr = 0; + + GLHardwareBufferManager* glBufManager = static_cast(HardwareBufferManager::getSingletonPtr()); + + // Try to use scratch buffers for smaller buffers + if( length < glBufManager->getGLMapBufferThreshold() ) + { + retPtr = glBufManager->allocateScratch((uint32)length); + if (retPtr) + { + mLockedToScratch = true; + mScratchOffset = offset; + mScratchSize = length; + mScratchPtr = retPtr; + mScratchUploadOnUnlock = (options != HBL_READ_ONLY); + + if (options != HBL_DISCARD && options != HBL_NO_OVERWRITE) + { + // have to read back the data before returning the pointer + readData(offset, length, retPtr); + } + } + } + + if (!retPtr) + { GLenum access = 0; static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId); - // Use glMapBuffer - if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE) // TODO: check possibility to use GL_MAP_UNSYNCHRONIZED_BIT for HBL_NO_OVERWRITE locking promise - { - // Discard the buffer - glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, - GLHardwareBufferManager::getGLUsage(mUsage)); - } - if (mUsage & HBU_WRITE_ONLY) - access = GL_WRITE_ONLY_ARB; - else if (options == HBL_READ_ONLY) - access = GL_READ_ONLY_ARB; - else - access = GL_READ_WRITE_ARB; - - void* pBuffer = glMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, access ); - - if(pBuffer == 0) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Index Buffer: Out of memory", - "GLHardwareIndexBuffer::lock"); - } - - // return offsetted - retPtr = static_cast( - static_cast(pBuffer) + offset); - - mLockedToScratch = false; - - } - mIsLocked = true; - return retPtr; + // Use glMapBuffer + if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE) // TODO: check possibility to use GL_MAP_UNSYNCHRONIZED_BIT for HBL_NO_OVERWRITE locking promise + { + // Discard the buffer + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, + GLHardwareBufferManager::getGLUsage(mUsage)); + } + if (mUsage & HBU_WRITE_ONLY) + access = GL_WRITE_ONLY_ARB; + else if (options == HBL_READ_ONLY) + access = GL_READ_ONLY_ARB; + else + access = GL_READ_WRITE_ARB; + + void* pBuffer = glMapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, access ); + + if(pBuffer == 0) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Index Buffer: Out of memory", + "GLHardwareIndexBuffer::lock"); + } + + // return offsetted + retPtr = static_cast( + static_cast(pBuffer) + offset); + + mLockedToScratch = false; + + } + mIsLocked = true; + return retPtr; } - //--------------------------------------------------------------------- - void GLHardwareIndexBuffer::unlockImpl(void) + //--------------------------------------------------------------------- + void GLHardwareIndexBuffer::unlockImpl(void) { - if (mLockedToScratch) - { - if (mScratchUploadOnUnlock) - { - // have to write the data back to vertex buffer - writeData(mScratchOffset, mScratchSize, mScratchPtr, - mScratchOffset == 0 && mScratchSize == getSizeInBytes()); - } - - // deallocate from scratch buffer - static_cast( - HardwareBufferManager::getSingletonPtr())->deallocateScratch(mScratchPtr); - - mLockedToScratch = false; - } - else - { + if (mLockedToScratch) + { + if (mScratchUploadOnUnlock) + { + // have to write the data back to vertex buffer + writeData(mScratchOffset, mScratchSize, mScratchPtr, + mScratchOffset == 0 && mScratchSize == getSizeInBytes()); + } + + // deallocate from scratch buffer + static_cast( + HardwareBufferManager::getSingletonPtr())->deallocateScratch(mScratchPtr); + + mLockedToScratch = false; + } + else + { static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId); - if(!glUnmapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB )) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Buffer data corrupted, please reload", - "GLHardwareIndexBuffer::unlock"); - } - } + if(!glUnmapBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB )) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Buffer data corrupted, please reload", + "GLHardwareIndexBuffer::unlock"); + } + } mIsLocked = false; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void GLHardwareIndexBuffer::readData(size_t offset, size_t length, void* pDest) { @@ -183,7 +183,7 @@ namespace Ogre { glGetBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, pDest); } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void GLHardwareIndexBuffer::writeData(size_t offset, size_t length, const void* pSource, bool discardWholeBuffer) { @@ -215,7 +215,7 @@ namespace Ogre { glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, pSource); } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void GLHardwareIndexBuffer::_updateFromShadow(void) { if (mUseShadowBuffer && mShadowUpdated && !mSuppressHardwareUpdate) diff --git a/RenderSystems/GL/src/OgreGLHardwareOcclusionQuery.cpp b/RenderSystems/GL/src/OgreGLHardwareOcclusionQuery.cpp index e5746adc1cd..564757165f2 100644 --- a/RenderSystems/GL/src/OgreGLHardwareOcclusionQuery.cpp +++ b/RenderSystems/GL/src/OgreGLHardwareOcclusionQuery.cpp @@ -48,22 +48,22 @@ namespace Ogre { */ GLHardwareOcclusionQuery::GLHardwareOcclusionQuery() { - // Check for hardware occlusion support + // Check for hardware occlusion support if(GLEW_VERSION_1_5 || GLEW_ARB_occlusion_query) - { - glGenQueriesARB(1, &mQueryID ); - } - else if (GLEW_NV_occlusion_query) - { - glGenOcclusionQueriesNV(1, &mQueryID); - } - else + { + glGenQueriesARB(1, &mQueryID ); + } + else if (GLEW_NV_occlusion_query) + { + glGenOcclusionQueriesNV(1, &mQueryID); + } + else { OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Cannot allocate a Hardware query. This video card doesn't support it, sorry.", "GLHardwareOcclusionQuery::GLHardwareOcclusionQuery" ); } - + } //------------------------------------------------------------------ /** @@ -72,56 +72,56 @@ GLHardwareOcclusionQuery::GLHardwareOcclusionQuery() GLHardwareOcclusionQuery::~GLHardwareOcclusionQuery() { if(GLEW_VERSION_1_5 || GLEW_ARB_occlusion_query) - { - glDeleteQueriesARB(1, &mQueryID); - } - else if (GLEW_NV_occlusion_query) - { - glDeleteOcclusionQueriesNV(1, &mQueryID); - } + { + glDeleteQueriesARB(1, &mQueryID); + } + else if (GLEW_NV_occlusion_query) + { + glDeleteOcclusionQueriesNV(1, &mQueryID); + } } //------------------------------------------------------------------ void GLHardwareOcclusionQuery::beginOcclusionQuery() { if(GLEW_VERSION_1_5 || GLEW_ARB_occlusion_query) - { - glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryID); - } - else if (GLEW_NV_occlusion_query) - { - glBeginOcclusionQueryNV(mQueryID); - } + { + glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryID); + } + else if (GLEW_NV_occlusion_query) + { + glBeginOcclusionQueryNV(mQueryID); + } } //------------------------------------------------------------------ void GLHardwareOcclusionQuery::endOcclusionQuery() { if(GLEW_VERSION_1_5 || GLEW_ARB_occlusion_query) - { - glEndQueryARB(GL_SAMPLES_PASSED_ARB); - } - else if (GLEW_NV_occlusion_query) - { - glEndOcclusionQueryNV(); - } - + { + glEndQueryARB(GL_SAMPLES_PASSED_ARB); + } + else if (GLEW_NV_occlusion_query) + { + glEndOcclusionQueryNV(); + } + } //------------------------------------------------------------------ bool GLHardwareOcclusionQuery::pullOcclusionQuery( unsigned int* NumOfFragments ) { if(GLEW_VERSION_1_5 || GLEW_ARB_occlusion_query) - { - glGetQueryObjectuivARB(mQueryID, GL_QUERY_RESULT_ARB, (GLuint*)NumOfFragments); - mPixelCount = *NumOfFragments; - return true; - } - else if (GLEW_NV_occlusion_query) - { - glGetOcclusionQueryuivNV(mQueryID, GL_PIXEL_COUNT_NV, (GLuint*)NumOfFragments); - mPixelCount = *NumOfFragments; - return true; - } + { + glGetQueryObjectuivARB(mQueryID, GL_QUERY_RESULT_ARB, (GLuint*)NumOfFragments); + mPixelCount = *NumOfFragments; + return true; + } + else if (GLEW_NV_occlusion_query) + { + glGetOcclusionQueryuivNV(mQueryID, GL_PIXEL_COUNT_NV, (GLuint*)NumOfFragments); + mPixelCount = *NumOfFragments; + return true; + } - return false; + return false; } //------------------------------------------------------------------ bool GLHardwareOcclusionQuery::isStillOutstanding(void) @@ -129,15 +129,15 @@ bool GLHardwareOcclusionQuery::isStillOutstanding(void) GLuint available = GL_FALSE; if(GLEW_VERSION_1_5 || GLEW_ARB_occlusion_query) - { - glGetQueryObjectuivARB(mQueryID, GL_QUERY_RESULT_AVAILABLE_ARB, &available); - } - else if (GLEW_NV_occlusion_query) - { - glGetOcclusionQueryuivNV(mQueryID, GL_PIXEL_COUNT_AVAILABLE_NV, &available); - } + { + glGetQueryObjectuivARB(mQueryID, GL_QUERY_RESULT_AVAILABLE_ARB, &available); + } + else if (GLEW_NV_occlusion_query) + { + glGetOcclusionQueryuivNV(mQueryID, GL_PIXEL_COUNT_AVAILABLE_NV, &available); + } - // GL_TRUE means a wait would occur + // GL_TRUE means a wait would occur return !(available == GL_TRUE); } diff --git a/RenderSystems/GL/src/OgreGLHardwarePixelBuffer.cpp b/RenderSystems/GL/src/OgreGLHardwarePixelBuffer.cpp index 8991a11bac4..11f9c2b9309 100644 --- a/RenderSystems/GL/src/OgreGLHardwarePixelBuffer.cpp +++ b/RenderSystems/GL/src/OgreGLHardwarePixelBuffer.cpp @@ -52,133 +52,133 @@ GLHardwarePixelBuffer::GLHardwarePixelBuffer(uint32 inWidth, uint32 inHeight, ui //----------------------------------------------------------------------------- GLHardwarePixelBuffer::~GLHardwarePixelBuffer() { - // Force free buffer - delete [] (uint8*)mBuffer.data; + // Force free buffer + delete [] (uint8*)mBuffer.data; } //----------------------------------------------------------------------------- void GLHardwarePixelBuffer::allocateBuffer() { - if(mBuffer.data) - // Already allocated - return; - mBuffer.data = new uint8[mSizeInBytes]; - // TODO: use PBO if we're HBU_DYNAMIC + if(mBuffer.data) + // Already allocated + return; + mBuffer.data = new uint8[mSizeInBytes]; + // TODO: use PBO if we're HBU_DYNAMIC } //----------------------------------------------------------------------------- void GLHardwarePixelBuffer::freeBuffer() { - // Free buffer if we're STATIC to save memory - if(mUsage & HBU_STATIC) - { - delete [] (uint8*)mBuffer.data; - mBuffer.data = 0; - } + // Free buffer if we're STATIC to save memory + if(mUsage & HBU_STATIC) + { + delete [] (uint8*)mBuffer.data; + mBuffer.data = 0; + } } //----------------------------------------------------------------------------- PixelBox GLHardwarePixelBuffer::lockImpl(const Image::Box &lockBox, LockOptions options) { - allocateBuffer(); - if(options != HardwareBuffer::HBL_DISCARD) - { - // Download the old contents of the texture - download(mBuffer); - } - mCurrentLockOptions = options; - mLockedBox = lockBox; - return mBuffer.getSubVolume(lockBox); + allocateBuffer(); + if(options != HardwareBuffer::HBL_DISCARD) + { + // Download the old contents of the texture + download(mBuffer); + } + mCurrentLockOptions = options; + mLockedBox = lockBox; + return mBuffer.getSubVolume(lockBox); } //----------------------------------------------------------------------------- void GLHardwarePixelBuffer::unlockImpl(void) { - if (mCurrentLockOptions != HardwareBuffer::HBL_READ_ONLY) - { - // From buffer to card, only upload if was locked for writing - upload(mCurrentLock, mLockedBox); - } - - freeBuffer(); + if (mCurrentLockOptions != HardwareBuffer::HBL_READ_ONLY) + { + // From buffer to card, only upload if was locked for writing + upload(mCurrentLock, mLockedBox); + } + + freeBuffer(); } //----------------------------------------------------------------------------- void GLHardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox) { - if(!mBuffer.contains(dstBox)) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "destination box out of range", - "GLHardwarePixelBuffer::blitFromMemory"); - PixelBox scaled; - - if(src.getWidth() != dstBox.getWidth() || - src.getHeight() != dstBox.getHeight() || - src.getDepth() != dstBox.getDepth()) - { - // Scale to destination size. - // This also does pixel format conversion if needed - allocateBuffer(); - scaled = mBuffer.getSubVolume(dstBox); - Image::scale(src, scaled, Image::FILTER_BILINEAR); - } - else if(GLPixelUtil::getGLOriginFormat(src.format) == 0) - { - // Extents match, but format is not accepted as valid source format for GL - // do conversion in temporary buffer - allocateBuffer(); - scaled = mBuffer.getSubVolume(dstBox); - PixelUtil::bulkPixelConversion(src, scaled); - } - else - { - allocateBuffer(); - // No scaling or conversion needed - scaled = src; - } - - upload(scaled, dstBox); - freeBuffer(); + if(!mBuffer.contains(dstBox)) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "destination box out of range", + "GLHardwarePixelBuffer::blitFromMemory"); + PixelBox scaled; + + if(src.getWidth() != dstBox.getWidth() || + src.getHeight() != dstBox.getHeight() || + src.getDepth() != dstBox.getDepth()) + { + // Scale to destination size. + // This also does pixel format conversion if needed + allocateBuffer(); + scaled = mBuffer.getSubVolume(dstBox); + Image::scale(src, scaled, Image::FILTER_BILINEAR); + } + else if(GLPixelUtil::getGLOriginFormat(src.format) == 0) + { + // Extents match, but format is not accepted as valid source format for GL + // do conversion in temporary buffer + allocateBuffer(); + scaled = mBuffer.getSubVolume(dstBox); + PixelUtil::bulkPixelConversion(src, scaled); + } + else + { + allocateBuffer(); + // No scaling or conversion needed + scaled = src; + } + + upload(scaled, dstBox); + freeBuffer(); } //----------------------------------------------------------------------------- void GLHardwarePixelBuffer::blitToMemory(const Image::Box &srcBox, const PixelBox &dst) { - if(!mBuffer.contains(srcBox)) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "source box out of range", - "GLHardwarePixelBuffer::blitToMemory"); - if(srcBox.left == 0 && srcBox.right == getWidth() && - srcBox.top == 0 && srcBox.bottom == getHeight() && - srcBox.front == 0 && srcBox.back == getDepth() && - dst.getWidth() == getWidth() && - dst.getHeight() == getHeight() && - dst.getDepth() == getDepth() && - GLPixelUtil::getGLOriginFormat(dst.format) != 0) - { - // The direct case: the user wants the entire texture in a format supported by GL - // so we don't need an intermediate buffer - download(dst); - } - else - { - // Use buffer for intermediate copy - allocateBuffer(); - // Download entire buffer - download(mBuffer); - if(srcBox.getWidth() != dst.getWidth() || - srcBox.getHeight() != dst.getHeight() || - srcBox.getDepth() != dst.getDepth()) - { - // We need scaling - Image::scale(mBuffer.getSubVolume(srcBox), dst, Image::FILTER_BILINEAR); - } - else - { - // Just copy the bit that we need - PixelUtil::bulkPixelConversion(mBuffer.getSubVolume(srcBox), dst); - } - freeBuffer(); - } + if(!mBuffer.contains(srcBox)) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "source box out of range", + "GLHardwarePixelBuffer::blitToMemory"); + if(srcBox.left == 0 && srcBox.right == getWidth() && + srcBox.top == 0 && srcBox.bottom == getHeight() && + srcBox.front == 0 && srcBox.back == getDepth() && + dst.getWidth() == getWidth() && + dst.getHeight() == getHeight() && + dst.getDepth() == getDepth() && + GLPixelUtil::getGLOriginFormat(dst.format) != 0) + { + // The direct case: the user wants the entire texture in a format supported by GL + // so we don't need an intermediate buffer + download(dst); + } + else + { + // Use buffer for intermediate copy + allocateBuffer(); + // Download entire buffer + download(mBuffer); + if(srcBox.getWidth() != dst.getWidth() || + srcBox.getHeight() != dst.getHeight() || + srcBox.getDepth() != dst.getDepth()) + { + // We need scaling + Image::scale(mBuffer.getSubVolume(srcBox), dst, Image::FILTER_BILINEAR); + } + else + { + // Just copy the bit that we need + PixelUtil::bulkPixelConversion(mBuffer.getSubVolume(srcBox), dst); + } + freeBuffer(); + } } //----------------------------------------------------------------------------- void GLHardwarePixelBuffer::upload(const PixelBox &data, const Image::Box &dest) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Upload not possible for this pixelbuffer type", + "Upload not possible for this pixelbuffer type", "GLHardwarePixelBuffer::upload"); } //----------------------------------------------------------------------------- @@ -195,70 +195,70 @@ void GLHardwarePixelBuffer::bindToFramebuffer(GLenum attachment, uint32 zoffset) } //********* GLTextureBuffer GLTextureBuffer::GLTextureBuffer(GLSupport& support, const String &baseName, GLenum target, GLuint id, - GLint face, GLint level, Usage usage, bool crappyCard, - bool writeGamma, uint fsaa): - GLHardwarePixelBuffer(0, 0, 0, PF_UNKNOWN, usage), - mTarget(target), mFaceTarget(0), mTextureID(id), mFace(face), mLevel(level), - mSoftwareMipmap(crappyCard), mHwGamma(writeGamma), mSliceTRT(0), mGLSupport(support) + GLint face, GLint level, Usage usage, bool crappyCard, + bool writeGamma, uint fsaa): + GLHardwarePixelBuffer(0, 0, 0, PF_UNKNOWN, usage), + mTarget(target), mFaceTarget(0), mTextureID(id), mFace(face), mLevel(level), + mSoftwareMipmap(crappyCard), mHwGamma(writeGamma), mSliceTRT(0), mGLSupport(support) { - // devise mWidth, mHeight and mDepth and mFormat - GLint value = 0; - - mGLSupport.getStateCacheManager()->bindGLTexture( mTarget, mTextureID ); - - // Get face identifier - mFaceTarget = mTarget; - if(mTarget == GL_TEXTURE_CUBE_MAP) - mFaceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; - - // Get width - glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_WIDTH, &value); - mWidth = value; - - // Get height - if(target == GL_TEXTURE_1D) - value = 1; // Height always 1 for 1D textures - else - glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_HEIGHT, &value); - mHeight = value; - - // Get depth - if(target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY_EXT) - value = 1; // Depth always 1 for non-3D textures - else - glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_DEPTH, &value); - mDepth = value; + // devise mWidth, mHeight and mDepth and mFormat + GLint value = 0; + + mGLSupport.getStateCacheManager()->bindGLTexture( mTarget, mTextureID ); + + // Get face identifier + mFaceTarget = mTarget; + if(mTarget == GL_TEXTURE_CUBE_MAP) + mFaceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; + + // Get width + glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_WIDTH, &value); + mWidth = value; + + // Get height + if(target == GL_TEXTURE_1D) + value = 1; // Height always 1 for 1D textures + else + glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_HEIGHT, &value); + mHeight = value; + + // Get depth + if(target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY_EXT) + value = 1; // Depth always 1 for non-3D textures + else + glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_DEPTH, &value); + mDepth = value; - // Get format - glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_INTERNAL_FORMAT, &value); - mGLInternalFormat = value; - mFormat = GLPixelUtil::getClosestOGREFormat(value); - - // Default - mRowPitch = mWidth; - mSlicePitch = mHeight*mWidth; - mSizeInBytes = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); - - // Log a message - /* - std::stringstream str; - str << "GLHardwarePixelBuffer constructed for texture " << mTextureID - << " face " << mFace << " level " << mLevel << ": " - << "width=" << mWidth << " height="<< mHeight << " depth=" << mDepth - << "format=" << PixelUtil::getFormatName(mFormat) << "(internal 0x" - << std::hex << value << ")"; - LogManager::getSingleton().logMessage( + // Get format + glGetTexLevelParameteriv(mFaceTarget, level, GL_TEXTURE_INTERNAL_FORMAT, &value); + mGLInternalFormat = value; + mFormat = GLPixelUtil::getClosestOGREFormat(value); + + // Default + mRowPitch = mWidth; + mSlicePitch = mHeight*mWidth; + mSizeInBytes = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); + + // Log a message + /* + std::stringstream str; + str << "GLHardwarePixelBuffer constructed for texture " << mTextureID + << " face " << mFace << " level " << mLevel << ": " + << "width=" << mWidth << " height="<< mHeight << " depth=" << mDepth + << "format=" << PixelUtil::getFormatName(mFormat) << "(internal 0x" + << std::hex << value << ")"; + LogManager::getSingleton().logMessage( LML_NORMAL, str.str()); - */ - // Set up pixel box - mBuffer = PixelBox(mWidth, mHeight, mDepth, mFormat); - + */ + // Set up pixel box + mBuffer = PixelBox(mWidth, mHeight, mDepth, mFormat); + if(mWidth==0 || mHeight==0 || mDepth==0) /// We are invalid, do not allocate a buffer return; - // Allocate buffer - //if(mUsage & HBU_STATIC) - // allocateBuffer(); + // Allocate buffer + //if(mUsage & HBU_STATIC) + // allocateBuffer(); // Is this a render target? if(mUsage & TU_RENDERTARGET) { @@ -267,7 +267,7 @@ GLTextureBuffer::GLTextureBuffer(GLSupport& support, const String &baseName, GLe for(uint32 zoffset=0; zoffsetattachRenderTarget(*mSliceTRT[zoffset]); } - } + } } GLTextureBuffer::~GLTextureBuffer() { @@ -287,226 +287,226 @@ GLTextureBuffer::~GLTextureBuffer() { Root::getSingleton().getRenderSystem()->destroyRenderTarget((*it)->getName()); } - } + } } //----------------------------------------------------------------------------- void GLTextureBuffer::upload(const PixelBox &data, const Image::Box &dest) { - mGLSupport.getStateCacheManager()->bindGLTexture( mTarget, mTextureID ); - if(PixelUtil::isCompressed(data.format)) - { - if(data.format != mFormat || !data.isConsecutive()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Compressed images must be consecutive, in the source format", - "GLTextureBuffer::upload"); - GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma); - // Data must be consecutive and at beginning of buffer as PixelStorei not allowed - // for compressed formats - switch(mTarget) { - case GL_TEXTURE_1D: - // some systems (e.g. old Apple) don't like compressed subimage calls - // so prefer non-sub versions - if (dest.left == 0) - { - glCompressedTexImage1DARB(GL_TEXTURE_1D, mLevel, - format, - dest.getWidth(), - 0, - data.getConsecutiveSize(), - data.data); - } - else - { - glCompressedTexSubImage1DARB(GL_TEXTURE_1D, mLevel, - dest.left, - dest.getWidth(), - format, data.getConsecutiveSize(), - data.data); - } - break; - case GL_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP: - // some systems (e.g. old Apple) don't like compressed subimage calls - // so prefer non-sub versions - if (dest.left == 0 && dest.top == 0) - { - glCompressedTexImage2DARB(mFaceTarget, mLevel, - format, - dest.getWidth(), - dest.getHeight(), - 0, - data.getConsecutiveSize(), - data.data); - } - else - { - glCompressedTexSubImage2DARB(mFaceTarget, mLevel, - dest.left, dest.top, - dest.getWidth(), dest.getHeight(), - format, data.getConsecutiveSize(), - data.data); - } - break; - case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY_EXT: - // some systems (e.g. old Apple) don't like compressed subimage calls - // so prefer non-sub versions - if (dest.left == 0 && dest.top == 0 && dest.front == 0) - { - glCompressedTexImage3DARB(mTarget, mLevel, - format, - dest.getWidth(), - dest.getHeight(), - dest.getDepth(), - 0, - data.getConsecutiveSize(), - data.data); - } - else - { - glCompressedTexSubImage3DARB(mTarget, mLevel, - dest.left, dest.top, dest.front, - dest.getWidth(), dest.getHeight(), dest.getDepth(), - format, data.getConsecutiveSize(), - data.data); - } - break; - } - - } - else if(mSoftwareMipmap) - { - GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat); - if(data.getWidth() != data.rowPitch) - glPixelStorei(GL_UNPACK_ROW_LENGTH, data.rowPitch); - if(data.getHeight()*data.getWidth() != data.slicePitch) - glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.slicePitch/data.getWidth())); - if(data.left > 0 || data.top > 0 || data.front > 0) - glPixelStorei(GL_UNPACK_SKIP_PIXELS, data.left + data.rowPitch * data.top + data.slicePitch * data.front); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - switch(mTarget) - { - case GL_TEXTURE_1D: - gluBuild1DMipmaps( - GL_TEXTURE_1D, format, - dest.getWidth(), - GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), - data.data); - break; - case GL_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP: - gluBuild2DMipmaps( - mFaceTarget, - format, dest.getWidth(), dest.getHeight(), - GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), - data.data); - break; - case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY_EXT: - /* Requires GLU 1.3 which is harder to come by than cards doing hardware mipmapping - Most 3D textures don't need mipmaps? - gluBuild3DMipmaps( - GL_TEXTURE_3D, internalFormat, - data.getWidth(), data.getHeight(), data.getDepth(), - GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), - data.data); - */ - glTexImage3D( - mTarget, 0, format, - dest.getWidth(), dest.getHeight(), dest.getDepth(), 0, - GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), - data.data ); - break; - } - } - else - { - if(data.getWidth() != data.rowPitch) - glPixelStorei(GL_UNPACK_ROW_LENGTH, data.rowPitch); - if(data.getWidth() > 0 && data.getHeight()*data.getWidth() != data.slicePitch) - glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.slicePitch/data.getWidth())); - if(data.left > 0 || data.top > 0 || data.front > 0) - glPixelStorei(GL_UNPACK_SKIP_PIXELS, data.left + data.rowPitch * data.top + data.slicePitch * data.front); - if((data.getWidth()*PixelUtil::getNumElemBytes(data.format)) & 3) { - // Standard alignment of 4 is not right - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - } - switch(mTarget) { - case GL_TEXTURE_1D: - glTexSubImage1D(GL_TEXTURE_1D, mLevel, - dest.left, - dest.getWidth(), - GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), - data.data); - break; - case GL_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP: - glTexSubImage2D(mFaceTarget, mLevel, - dest.left, dest.top, - dest.getWidth(), dest.getHeight(), - GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), - data.data); - break; - case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY_EXT: - glTexSubImage3D( - mTarget, mLevel, - dest.left, dest.top, dest.front, - dest.getWidth(), dest.getHeight(), dest.getDepth(), - GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), - data.data); - break; - } - } - // Restore defaults - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - if (GLEW_VERSION_1_2) - glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + mGLSupport.getStateCacheManager()->bindGLTexture( mTarget, mTextureID ); + if(PixelUtil::isCompressed(data.format)) + { + if(data.format != mFormat || !data.isConsecutive()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Compressed images must be consecutive, in the source format", + "GLTextureBuffer::upload"); + GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma); + // Data must be consecutive and at beginning of buffer as PixelStorei not allowed + // for compressed formats + switch(mTarget) { + case GL_TEXTURE_1D: + // some systems (e.g. old Apple) don't like compressed subimage calls + // so prefer non-sub versions + if (dest.left == 0) + { + glCompressedTexImage1DARB(GL_TEXTURE_1D, mLevel, + format, + dest.getWidth(), + 0, + data.getConsecutiveSize(), + data.data); + } + else + { + glCompressedTexSubImage1DARB(GL_TEXTURE_1D, mLevel, + dest.left, + dest.getWidth(), + format, data.getConsecutiveSize(), + data.data); + } + break; + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP: + // some systems (e.g. old Apple) don't like compressed subimage calls + // so prefer non-sub versions + if (dest.left == 0 && dest.top == 0) + { + glCompressedTexImage2DARB(mFaceTarget, mLevel, + format, + dest.getWidth(), + dest.getHeight(), + 0, + data.getConsecutiveSize(), + data.data); + } + else + { + glCompressedTexSubImage2DARB(mFaceTarget, mLevel, + dest.left, dest.top, + dest.getWidth(), dest.getHeight(), + format, data.getConsecutiveSize(), + data.data); + } + break; + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY_EXT: + // some systems (e.g. old Apple) don't like compressed subimage calls + // so prefer non-sub versions + if (dest.left == 0 && dest.top == 0 && dest.front == 0) + { + glCompressedTexImage3DARB(mTarget, mLevel, + format, + dest.getWidth(), + dest.getHeight(), + dest.getDepth(), + 0, + data.getConsecutiveSize(), + data.data); + } + else + { + glCompressedTexSubImage3DARB(mTarget, mLevel, + dest.left, dest.top, dest.front, + dest.getWidth(), dest.getHeight(), dest.getDepth(), + format, data.getConsecutiveSize(), + data.data); + } + break; + } + + } + else if(mSoftwareMipmap) + { + GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat); + if(data.getWidth() != data.rowPitch) + glPixelStorei(GL_UNPACK_ROW_LENGTH, data.rowPitch); + if(data.getHeight()*data.getWidth() != data.slicePitch) + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.slicePitch/data.getWidth())); + if(data.left > 0 || data.top > 0 || data.front > 0) + glPixelStorei(GL_UNPACK_SKIP_PIXELS, data.left + data.rowPitch * data.top + data.slicePitch * data.front); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + switch(mTarget) + { + case GL_TEXTURE_1D: + gluBuild1DMipmaps( + GL_TEXTURE_1D, format, + dest.getWidth(), + GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), + data.data); + break; + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP: + gluBuild2DMipmaps( + mFaceTarget, + format, dest.getWidth(), dest.getHeight(), + GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), + data.data); + break; + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY_EXT: + /* Requires GLU 1.3 which is harder to come by than cards doing hardware mipmapping + Most 3D textures don't need mipmaps? + gluBuild3DMipmaps( + GL_TEXTURE_3D, internalFormat, + data.getWidth(), data.getHeight(), data.getDepth(), + GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), + data.data); + */ + glTexImage3D( + mTarget, 0, format, + dest.getWidth(), dest.getHeight(), dest.getDepth(), 0, + GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), + data.data ); + break; + } + } + else + { + if(data.getWidth() != data.rowPitch) + glPixelStorei(GL_UNPACK_ROW_LENGTH, data.rowPitch); + if(data.getWidth() > 0 && data.getHeight()*data.getWidth() != data.slicePitch) + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.slicePitch/data.getWidth())); + if(data.left > 0 || data.top > 0 || data.front > 0) + glPixelStorei(GL_UNPACK_SKIP_PIXELS, data.left + data.rowPitch * data.top + data.slicePitch * data.front); + if((data.getWidth()*PixelUtil::getNumElemBytes(data.format)) & 3) { + // Standard alignment of 4 is not right + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + } + switch(mTarget) { + case GL_TEXTURE_1D: + glTexSubImage1D(GL_TEXTURE_1D, mLevel, + dest.left, + dest.getWidth(), + GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), + data.data); + break; + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP: + glTexSubImage2D(mFaceTarget, mLevel, + dest.left, dest.top, + dest.getWidth(), dest.getHeight(), + GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), + data.data); + break; + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY_EXT: + glTexSubImage3D( + mTarget, mLevel, + dest.left, dest.top, dest.front, + dest.getWidth(), dest.getHeight(), dest.getDepth(), + GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), + data.data); + break; + } + } + // Restore defaults + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + if (GLEW_VERSION_1_2) + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); } //----------------------------------------------------------------------------- void GLTextureBuffer::download(const PixelBox &data) { - if(data.getWidth() != getWidth() || - data.getHeight() != getHeight() || - data.getDepth() != getDepth()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "only download of entire buffer is supported by GL", - "GLTextureBuffer::download"); - mGLSupport.getStateCacheManager()->bindGLTexture( mTarget, mTextureID ); - if(PixelUtil::isCompressed(data.format)) - { - if(data.format != mFormat || !data.isConsecutive()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Compressed images must be consecutive, in the source format", - "GLTextureBuffer::download"); - // Data must be consecutive and at beginning of buffer as PixelStorei not allowed - // for compressed formate - glGetCompressedTexImageARB(mFaceTarget, mLevel, data.data); - } - else - { - if(data.getWidth() != data.rowPitch) - glPixelStorei(GL_PACK_ROW_LENGTH, data.rowPitch); - if(data.getHeight()*data.getWidth() != data.slicePitch) - glPixelStorei(GL_PACK_IMAGE_HEIGHT, (data.slicePitch/data.getWidth())); - if(data.left > 0 || data.top > 0 || data.front > 0) - glPixelStorei(GL_PACK_SKIP_PIXELS, data.left + data.rowPitch * data.top + data.slicePitch * data.front); - if((data.getWidth()*PixelUtil::getNumElemBytes(data.format)) & 3) { - // Standard alignment of 4 is not right - glPixelStorei(GL_PACK_ALIGNMENT, 1); - } - // We can only get the entire texture - glGetTexImage(mFaceTarget, mLevel, - GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), - data.data); - // Restore defaults - glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0); - glPixelStorei(GL_PACK_SKIP_PIXELS, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 4); - } + if(data.getWidth() != getWidth() || + data.getHeight() != getHeight() || + data.getDepth() != getDepth()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "only download of entire buffer is supported by GL", + "GLTextureBuffer::download"); + mGLSupport.getStateCacheManager()->bindGLTexture( mTarget, mTextureID ); + if(PixelUtil::isCompressed(data.format)) + { + if(data.format != mFormat || !data.isConsecutive()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Compressed images must be consecutive, in the source format", + "GLTextureBuffer::download"); + // Data must be consecutive and at beginning of buffer as PixelStorei not allowed + // for compressed formate + glGetCompressedTexImageARB(mFaceTarget, mLevel, data.data); + } + else + { + if(data.getWidth() != data.rowPitch) + glPixelStorei(GL_PACK_ROW_LENGTH, data.rowPitch); + if(data.getHeight()*data.getWidth() != data.slicePitch) + glPixelStorei(GL_PACK_IMAGE_HEIGHT, (data.slicePitch/data.getWidth())); + if(data.left > 0 || data.top > 0 || data.front > 0) + glPixelStorei(GL_PACK_SKIP_PIXELS, data.left + data.rowPitch * data.top + data.slicePitch * data.front); + if((data.getWidth()*PixelUtil::getNumElemBytes(data.format)) & 3) { + // Standard alignment of 4 is not right + glPixelStorei(GL_PACK_ALIGNMENT, 1); + } + // We can only get the entire texture + glGetTexImage(mFaceTarget, mLevel, + GLPixelUtil::getGLOriginFormat(data.format), GLPixelUtil::getGLOriginDataType(data.format), + data.data); + // Restore defaults + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glPixelStorei(GL_PACK_ALIGNMENT, 4); + } } //----------------------------------------------------------------------------- void GLTextureBuffer::bindToFramebuffer(GLenum attachment, uint32 zoffset) @@ -524,7 +524,7 @@ void GLTextureBuffer::bindToFramebuffer(GLenum attachment, uint32 zoffset) mFaceTarget, mTextureID, mLevel); break; case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY_EXT: + case GL_TEXTURE_2D_ARRAY_EXT: glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, attachment, mFaceTarget, mTextureID, mLevel, zoffset); break; @@ -544,7 +544,7 @@ void GLTextureBuffer::copyFromFramebuffer(uint32 zoffset) glCopyTexSubImage2D(mFaceTarget, mLevel, 0, 0, 0, 0, mWidth, mHeight); break; case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY_EXT: + case GL_TEXTURE_2D_ARRAY_EXT: glCopyTexSubImage3D(mFaceTarget, mLevel, 0, 0, zoffset, 0, 0, mWidth, mHeight); break; } @@ -556,9 +556,9 @@ void GLTextureBuffer::blit(const HardwarePixelBufferSharedPtr &src, const Image: /// Check for FBO support first /// Destination texture must be 1D, 2D, 3D, or Cube /// Source texture must be 1D, 2D or 3D - - // This does not seem to work for RTTs after the first update - // I have no idea why! For the moment, disable + + // This does not seem to work for RTTs after the first update + // I have no idea why! For the moment, disable if(GLEW_EXT_framebuffer_object && (src->getUsage() & TU_RENDERTARGET) == 0 && (srct->mTarget==GL_TEXTURE_1D||srct->mTarget==GL_TEXTURE_2D ||srct->mTarget==GL_TEXTURE_3D)&&mTarget!=GL_TEXTURE_2D_ARRAY_EXT) @@ -591,13 +591,13 @@ void GLTextureBuffer::blitFromTexture(GLTextureBuffer *src, const Image::Box &sr GL_FOG_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT | GL_SCISSOR_BIT | GL_STENCIL_BUFFER_BIT | GL_TEXTURE_BIT | GL_VIEWPORT_BIT); - // Important to disable all other texture units - RenderSystem* rsys = Root::getSingleton().getRenderSystem(); - rsys->_disableTextureUnitsFrom(0); - if (GLEW_VERSION_1_2) - { - mGLSupport.getStateCacheManager()->activateGLTextureUnit(0); - } + // Important to disable all other texture units + RenderSystem* rsys = Root::getSingleton().getRenderSystem(); + rsys->_disableTextureUnitsFrom(0); + if (GLEW_VERSION_1_2) + { + mGLSupport.getStateCacheManager()->activateGLTextureUnit(0); + } /// Disable alpha, depth and scissor testing, disable blending, @@ -713,7 +713,7 @@ void GLTextureBuffer::blitFromTexture(GLTextureBuffer *src, const Image::Box &sr /// Normalise to texture coordinate in 0.0 .. 1.0 w = (w+0.5f) / (float)src->mDepth; - /// Finally we're ready to rumble + /// Finally we're ready to rumble mGLSupport.getStateCacheManager()->bindGLTexture(src->mTarget, src->mTextureID); mGLSupport.getStateCacheManager()->setEnabled(src->mTarget, true); glBegin(GL_QUADS); @@ -746,7 +746,7 @@ void GLTextureBuffer::blitFromTexture(GLTextureBuffer *src, const Image::Box &sr 0, 0, dstBox.getWidth(), dstBox.getHeight()); break; case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY_EXT: + case GL_TEXTURE_2D_ARRAY_EXT: glCopyTexSubImage3D(mFaceTarget, mLevel, dstBox.left, dstBox.top, slice, 0, 0, dstBox.getWidth(), dstBox.getHeight()); @@ -853,7 +853,7 @@ void GLTextureBuffer::blitFromMemory(const PixelBox &src_orig, const Image::Box GLTextureBuffer tex(mGLSupport, BLANKSTRING, target, id, 0, 0, (Usage)(TU_AUTOMIPMAP|HBU_STATIC_WRITE_ONLY), false, false, 0); /// Upload data to 0,0,0 in temporary texture - Image::Box tempTarget(0, 0, 0, src.getWidth(), src.getHeight(), src.getDepth()); + Image::Box tempTarget(0, 0, 0, src.getWidth(), src.getHeight(), src.getDepth()); tex.upload(src, tempTarget); /// Blit @@ -883,16 +883,16 @@ GLRenderBuffer::GLRenderBuffer(GLenum format, uint32 width, uint32 height, GLsiz glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mRenderbufferID); /// Allocate storage for depth buffer - if (numSamples > 0) - { - glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, - numSamples, format, width, height); - } - else - { - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, - width, height); - } + if (numSamples > 0) + { + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, + numSamples, format, width, height); + } + else + { + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, + width, height); + } } //----------------------------------------------------------------------------- GLRenderBuffer::~GLRenderBuffer() diff --git a/RenderSystems/GL/src/OgreGLHardwareVertexBuffer.cpp b/RenderSystems/GL/src/OgreGLHardwareVertexBuffer.cpp index 39dbdd281db..6c13c1ec0b3 100644 --- a/RenderSystems/GL/src/OgreGLHardwareVertexBuffer.cpp +++ b/RenderSystems/GL/src/OgreGLHardwareVertexBuffer.cpp @@ -33,7 +33,7 @@ THE SOFTWARE. namespace Ogre { - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- GLHardwareVertexBuffer::GLHardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage, bool useShadowBuffer) : HardwareVertexBuffer(mgr, vertexSize, numVertices, usage, false, useShadowBuffer), mLockedToScratch(false), @@ -56,12 +56,12 @@ namespace Ogre { //std::cerr << "creating vertex buffer = " << mBufferId << std::endl; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- GLHardwareVertexBuffer::~GLHardwareVertexBuffer() { static_cast(mMgr)->getStateCacheManager()->deleteGLBuffer(GL_ARRAY_BUFFER_ARB, mBufferId); } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void* GLHardwareVertexBuffer::lockImpl(size_t offset, size_t length, LockOptions options) { @@ -73,43 +73,43 @@ namespace Ogre { } - void* retPtr = 0; + void* retPtr = 0; - GLHardwareBufferManager* glBufManager = static_cast(HardwareBufferManager::getSingletonPtr()); + GLHardwareBufferManager* glBufManager = static_cast(HardwareBufferManager::getSingletonPtr()); - // Try to use scratch buffers for smaller buffers - if( length < glBufManager->getGLMapBufferThreshold() ) - { - // if this fails, we fall back on mapping - retPtr = glBufManager->allocateScratch((uint32)length); + // Try to use scratch buffers for smaller buffers + if( length < glBufManager->getGLMapBufferThreshold() ) + { + // if this fails, we fall back on mapping + retPtr = glBufManager->allocateScratch((uint32)length); - if (retPtr) - { - mLockedToScratch = true; - mScratchOffset = offset; - mScratchSize = length; - mScratchPtr = retPtr; - mScratchUploadOnUnlock = (options != HBL_READ_ONLY); + if (retPtr) + { + mLockedToScratch = true; + mScratchOffset = offset; + mScratchSize = length; + mScratchPtr = retPtr; + mScratchUploadOnUnlock = (options != HBL_READ_ONLY); - if (options != HBL_DISCARD && options != HBL_NO_OVERWRITE) - { - // have to read back the data before returning the pointer - readData(offset, length, retPtr); - } - } - } - - if (!retPtr) - { + if (options != HBL_DISCARD && options != HBL_NO_OVERWRITE) + { + // have to read back the data before returning the pointer + readData(offset, length, retPtr); + } + } + } + + if (!retPtr) + { GLenum access = 0; - // Use glMapBuffer + // Use glMapBuffer static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ARRAY_BUFFER_ARB, mBufferId); - // Use glMapBuffer - if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE) // TODO: check possibility to use GL_MAP_UNSYNCHRONIZED_BIT for HBL_NO_OVERWRITE locking promise - { - // Discard the buffer - glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, - GLHardwareBufferManager::getGLUsage(mUsage)); + // Use glMapBuffer + if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE) // TODO: check possibility to use GL_MAP_UNSYNCHRONIZED_BIT for HBL_NO_OVERWRITE locking promise + { + // Discard the buffer + glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, + GLHardwareBufferManager::getGLUsage(mUsage)); GLenum error = glGetError(); if(error != 0) @@ -131,64 +131,64 @@ namespace Ogre { glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, GLHardwareBufferManager::getGLUsage(mUsage)); } - } + } - if (mUsage & HBU_WRITE_ONLY) - access = GL_WRITE_ONLY_ARB; - else if (options == HBL_READ_ONLY) - access = GL_READ_ONLY_ARB; - else - access = GL_READ_WRITE_ARB; + if (mUsage & HBU_WRITE_ONLY) + access = GL_WRITE_ONLY_ARB; + else if (options == HBL_READ_ONLY) + access = GL_READ_ONLY_ARB; + else + access = GL_READ_WRITE_ARB; - void* pBuffer = glMapBufferARB( GL_ARRAY_BUFFER_ARB, access); + void* pBuffer = glMapBufferARB( GL_ARRAY_BUFFER_ARB, access); if(pBuffer == 0) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Vertex Buffer: Out of memory", "GLHardwareVertexBuffer::lock"); - } + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Vertex Buffer: Out of memory", "GLHardwareVertexBuffer::lock"); + } - // return offsetted - retPtr = static_cast( - static_cast(pBuffer) + offset); + // return offsetted + retPtr = static_cast( + static_cast(pBuffer) + offset); - mLockedToScratch = false; - } - mIsLocked = true; - return retPtr; + mLockedToScratch = false; + } + mIsLocked = true; + return retPtr; } - //--------------------------------------------------------------------- - void GLHardwareVertexBuffer::unlockImpl(void) + //--------------------------------------------------------------------- + void GLHardwareVertexBuffer::unlockImpl(void) { - if (mLockedToScratch) - { - if (mScratchUploadOnUnlock) - { - // have to write the data back to vertex buffer - writeData(mScratchOffset, mScratchSize, mScratchPtr, - mScratchOffset == 0 && mScratchSize == getSizeInBytes()); - } + if (mLockedToScratch) + { + if (mScratchUploadOnUnlock) + { + // have to write the data back to vertex buffer + writeData(mScratchOffset, mScratchSize, mScratchPtr, + mScratchOffset == 0 && mScratchSize == getSizeInBytes()); + } - // deallocate from scratch buffer - static_cast( - HardwareBufferManager::getSingletonPtr())->deallocateScratch(mScratchPtr); + // deallocate from scratch buffer + static_cast( + HardwareBufferManager::getSingletonPtr())->deallocateScratch(mScratchPtr); - mLockedToScratch = false; - } - else - { + mLockedToScratch = false; + } + else + { static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ARRAY_BUFFER_ARB, mBufferId); - if(!glUnmapBufferARB( GL_ARRAY_BUFFER_ARB )) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Buffer data corrupted, please reload", - "GLHardwareVertexBuffer::unlock"); - } - } + if(!glUnmapBufferARB( GL_ARRAY_BUFFER_ARB )) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Buffer data corrupted, please reload", + "GLHardwareVertexBuffer::unlock"); + } + } mIsLocked = false; } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void GLHardwareVertexBuffer::readData(size_t offset, size_t length, void* pDest) { @@ -207,7 +207,7 @@ namespace Ogre { glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, pDest); } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void GLHardwareVertexBuffer::writeData(size_t offset, size_t length, const void* pSource, bool discardWholeBuffer) { @@ -239,7 +239,7 @@ namespace Ogre { glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, pSource); } } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void GLHardwareVertexBuffer::_updateFromShadow(void) { if (mUseShadowBuffer && mShadowUpdated && !mSuppressHardwareUpdate) diff --git a/RenderSystems/GL/src/OgreGLPBRenderTexture.cpp b/RenderSystems/GL/src/OgreGLPBRenderTexture.cpp index 943f4356129..c39ad68d29d 100755 --- a/RenderSystems/GL/src/OgreGLPBRenderTexture.cpp +++ b/RenderSystems/GL/src/OgreGLPBRenderTexture.cpp @@ -47,7 +47,7 @@ namespace Ogre { //----------------------------------------------------------------------------- GLPBRenderTexture::GLPBRenderTexture(GLPBRTTManager *manager, const String &name, - const GLSurfaceDesc &target, bool writeGamma, uint fsaa): + const GLSurfaceDesc &target, bool writeGamma, uint fsaa): GLRenderTexture(name, target, writeGamma, fsaa), mManager(manager) { @@ -64,9 +64,9 @@ namespace Ogre { { if( name == GLRenderTexture::CustomAttributeString_TARGET ) { - GLSurfaceDesc &target = *static_cast(pData); - target.buffer = static_cast(mBuffer); - target.zoffset = mZOffset; + GLSurfaceDesc &target = *static_cast(pData); + target.buffer = static_cast(mBuffer); + target.zoffset = mZOffset; } else if (name == GLRenderTexture::CustomAttributeString_GLCONTEXT ) { @@ -77,10 +77,10 @@ namespace Ogre { //----------------------------------------------------------------------------- GLPBRTTManager::GLPBRTTManager(GLSupport *support, RenderTarget *mainwindow): mSupport(support), - mMainWindow(mainwindow), - mMainContext(0) + mMainWindow(mainwindow), + mMainContext(0) { - mMainWindow->getCustomAttribute(GLRenderTexture::CustomAttributeString_GLCONTEXT, &mMainContext); + mMainWindow->getCustomAttribute(GLRenderTexture::CustomAttributeString_GLCONTEXT, &mMainContext); } GLPBRTTManager::~GLPBRTTManager() { @@ -92,7 +92,7 @@ namespace Ogre { } RenderTexture *GLPBRTTManager::createRenderTexture(const String &name, - const GLSurfaceDesc &target, bool writeGamma, uint fsaa) + const GLSurfaceDesc &target, bool writeGamma, uint fsaa) { return new GLPBRenderTexture(this, name, target, writeGamma, fsaa); } @@ -110,9 +110,9 @@ namespace Ogre { void GLPBRTTManager::unbind(RenderTarget *target) { - // Copy on unbind + // Copy on unbind GLSurfaceDesc surface; - surface.buffer = 0; + surface.buffer = 0; target->getCustomAttribute(GLRenderTexture::CustomAttributeString_TARGET, &surface); if(surface.buffer) static_cast(surface.buffer)->copyFromFramebuffer(surface.zoffset); @@ -153,11 +153,11 @@ namespace Ogre { { // Faster to return main context if the RTT is smaller than the window size // and ctype is PCT_BYTE. This must be checked every time because the window might have been resized - if(ctype == PCT_BYTE) - { - if(width <= mMainWindow->getWidth() && height <= mMainWindow->getHeight()) - return mMainContext; - } + if(ctype == PCT_BYTE) + { + if(width <= mMainWindow->getWidth() && height <= mMainWindow->getHeight()) + return mMainContext; + } assert(mPBuffers[ctype].pb); return mPBuffers[ctype].pb->getContext(); } diff --git a/RenderSystems/GL/src/OgreGLPixelFormat.cpp b/RenderSystems/GL/src/OgreGLPixelFormat.cpp index 696b782f2ff..d41a5188d46 100644 --- a/RenderSystems/GL/src/OgreGLPixelFormat.cpp +++ b/RenderSystems/GL/src/OgreGLPixelFormat.cpp @@ -32,29 +32,29 @@ THE SOFTWARE. #include "OgreBitwise.h" namespace Ogre { - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- GLenum GLPixelUtil::getGLOriginFormat(PixelFormat mFormat) { switch(mFormat) { - case PF_A8: - return GL_ALPHA; + case PF_A8: + return GL_ALPHA; case PF_L8: return GL_LUMINANCE; case PF_L16: return GL_LUMINANCE; - case PF_BYTE_LA: - return GL_LUMINANCE_ALPHA; - case PF_R3G3B2: - return GL_RGB; - case PF_A1R5G5B5: - return GL_BGRA; - case PF_R5G6B5: - return GL_RGB; - case PF_B5G6R5: - return GL_BGR; - case PF_A4R4G4B4: - return GL_BGRA; + case PF_BYTE_LA: + return GL_LUMINANCE_ALPHA; + case PF_R3G3B2: + return GL_RGB; + case PF_A1R5G5B5: + return GL_BGRA; + case PF_R5G6B5: + return GL_RGB; + case PF_B5G6R5: + return GL_BGR; + case PF_A4R4G4B4: + return GL_BGRA; #if OGRE_ENDIAN == OGRE_ENDIAN_BIG // Formats are in native endian, so R8G8B8 on little endian is // BGR, on big endian it is RGB. @@ -68,42 +68,42 @@ namespace Ogre { case PF_B8G8R8: return GL_RGB; #endif - case PF_X8R8G8B8: - case PF_A8R8G8B8: - return GL_BGRA; - case PF_X8B8G8R8: + case PF_X8R8G8B8: + case PF_A8R8G8B8: + return GL_BGRA; + case PF_X8B8G8R8: case PF_A8B8G8R8: return GL_RGBA; case PF_B8G8R8A8: return GL_BGRA; - case PF_R8G8B8A8: - return GL_RGBA; + case PF_R8G8B8A8: + return GL_RGBA; case PF_A2R10G10B10: return GL_BGRA; case PF_A2B10G10R10: return GL_RGBA; - case PF_FLOAT16_R: + case PF_FLOAT16_R: return GL_LUMINANCE; - case PF_FLOAT16_GR: - return GL_LUMINANCE_ALPHA; + case PF_FLOAT16_GR: + return GL_LUMINANCE_ALPHA; case PF_FLOAT16_RGB: return GL_RGB; case PF_FLOAT16_RGBA: return GL_RGBA; - case PF_FLOAT32_R: + case PF_FLOAT32_R: return GL_LUMINANCE; - case PF_FLOAT32_GR: - return GL_LUMINANCE_ALPHA; + case PF_FLOAT32_GR: + return GL_LUMINANCE_ALPHA; case PF_FLOAT32_RGB: return GL_RGB; case PF_FLOAT32_RGBA: return GL_RGBA; - case PF_SHORT_RGBA: - return GL_RGBA; + case PF_SHORT_RGBA: + return GL_RGBA; case PF_SHORT_RGB: return GL_RGB; - case PF_SHORT_GR: - return GL_LUMINANCE_ALPHA; + case PF_SHORT_GR: + return GL_LUMINANCE_ALPHA; case PF_DXT1: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; case PF_DXT3: @@ -114,69 +114,69 @@ namespace Ogre { return 0; } } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- GLenum GLPixelUtil::getGLOriginDataType(PixelFormat mFormat) { switch(mFormat) { - case PF_A8: + case PF_A8: case PF_L8: case PF_R8G8B8: case PF_B8G8R8: - case PF_BYTE_LA: + case PF_BYTE_LA: return GL_UNSIGNED_BYTE; - case PF_R3G3B2: - return GL_UNSIGNED_BYTE_3_3_2; - case PF_A1R5G5B5: - return GL_UNSIGNED_SHORT_1_5_5_5_REV; - case PF_R5G6B5: - case PF_B5G6R5: - return GL_UNSIGNED_SHORT_5_6_5; - case PF_A4R4G4B4: - return GL_UNSIGNED_SHORT_4_4_4_4_REV; + case PF_R3G3B2: + return GL_UNSIGNED_BYTE_3_3_2; + case PF_A1R5G5B5: + return GL_UNSIGNED_SHORT_1_5_5_5_REV; + case PF_R5G6B5: + case PF_B5G6R5: + return GL_UNSIGNED_SHORT_5_6_5; + case PF_A4R4G4B4: + return GL_UNSIGNED_SHORT_4_4_4_4_REV; case PF_L16: return GL_UNSIGNED_SHORT; #if OGRE_ENDIAN == OGRE_ENDIAN_BIG - case PF_X8B8G8R8: - case PF_A8B8G8R8: + case PF_X8B8G8R8: + case PF_A8B8G8R8: return GL_UNSIGNED_INT_8_8_8_8_REV; - case PF_X8R8G8B8: + case PF_X8R8G8B8: case PF_A8R8G8B8: - return GL_UNSIGNED_INT_8_8_8_8_REV; + return GL_UNSIGNED_INT_8_8_8_8_REV; case PF_B8G8R8A8: return GL_UNSIGNED_BYTE; - case PF_R8G8B8A8: - return GL_UNSIGNED_BYTE; + case PF_R8G8B8A8: + return GL_UNSIGNED_BYTE; #else - case PF_X8B8G8R8: - case PF_A8B8G8R8: + case PF_X8B8G8R8: + case PF_A8B8G8R8: return GL_UNSIGNED_BYTE; - case PF_X8R8G8B8: + case PF_X8R8G8B8: case PF_A8R8G8B8: - return GL_UNSIGNED_BYTE; + return GL_UNSIGNED_BYTE; case PF_B8G8R8A8: return GL_UNSIGNED_INT_8_8_8_8; - case PF_R8G8B8A8: - return GL_UNSIGNED_INT_8_8_8_8; + case PF_R8G8B8A8: + return GL_UNSIGNED_INT_8_8_8_8; #endif case PF_A2R10G10B10: return GL_UNSIGNED_INT_2_10_10_10_REV; case PF_A2B10G10R10: return GL_UNSIGNED_INT_2_10_10_10_REV; - case PF_FLOAT16_R: - case PF_FLOAT16_GR: + case PF_FLOAT16_R: + case PF_FLOAT16_GR: case PF_FLOAT16_RGB: case PF_FLOAT16_RGBA: return GL_HALF_FLOAT_ARB; - case PF_FLOAT32_R: - case PF_FLOAT32_GR: + case PF_FLOAT32_R: + case PF_FLOAT32_GR: case PF_FLOAT32_RGB: case PF_FLOAT32_RGBA: return GL_FLOAT; - case PF_SHORT_RGBA: + case PF_SHORT_RGBA: case PF_SHORT_RGB: - case PF_SHORT_GR: - return GL_UNSIGNED_SHORT; + case PF_SHORT_GR: + return GL_UNSIGNED_SHORT; default: return 0; } @@ -193,71 +193,71 @@ namespace Ogre { return GL_ALPHA8; case PF_A4L4: return GL_LUMINANCE4_ALPHA4; - case PF_BYTE_LA: - return GL_LUMINANCE8_ALPHA8; - case PF_R3G3B2: - return GL_R3_G3_B2; - case PF_A1R5G5B5: - return GL_RGB5_A1; + case PF_BYTE_LA: + return GL_LUMINANCE8_ALPHA8; + case PF_R3G3B2: + return GL_R3_G3_B2; + case PF_A1R5G5B5: + return GL_RGB5_A1; case PF_R5G6B5: - case PF_B5G6R5: + case PF_B5G6R5: return GL_RGB5; case PF_A4R4G4B4: return GL_RGBA4; case PF_R8G8B8: case PF_B8G8R8: - case PF_X8B8G8R8: - case PF_X8R8G8B8: - if (hwGamma) - return GL_SRGB8; - else - return GL_RGB8; + case PF_X8B8G8R8: + case PF_X8R8G8B8: + if (hwGamma) + return GL_SRGB8; + else + return GL_RGB8; case PF_A8R8G8B8: case PF_B8G8R8A8: - if (hwGamma) - return GL_SRGB8_ALPHA8; - else - return GL_RGBA8; + if (hwGamma) + return GL_SRGB8_ALPHA8; + else + return GL_RGBA8; case PF_A2R10G10B10: case PF_A2B10G10R10: return GL_RGB10_A2; - case PF_FLOAT16_R: - return GL_LUMINANCE16F_ARB; + case PF_FLOAT16_R: + return GL_LUMINANCE16F_ARB; case PF_FLOAT16_RGB: return GL_RGB16F_ARB; - case PF_FLOAT16_GR: - return GL_LUMINANCE_ALPHA16F_ARB; + case PF_FLOAT16_GR: + return GL_LUMINANCE_ALPHA16F_ARB; case PF_FLOAT16_RGBA: return GL_RGBA16F_ARB; - case PF_FLOAT32_R: - return GL_LUMINANCE32F_ARB; - case PF_FLOAT32_GR: - return GL_LUMINANCE_ALPHA32F_ARB; + case PF_FLOAT32_R: + return GL_LUMINANCE32F_ARB; + case PF_FLOAT32_GR: + return GL_LUMINANCE_ALPHA32F_ARB; case PF_FLOAT32_RGB: return GL_RGB32F_ARB; case PF_FLOAT32_RGBA: return GL_RGBA32F_ARB; - case PF_SHORT_RGBA: - return GL_RGBA16; + case PF_SHORT_RGBA: + return GL_RGBA16; case PF_SHORT_RGB: return GL_RGB16; - case PF_SHORT_GR: - return GL_LUMINANCE16_ALPHA16; - case PF_DXT1: - if (hwGamma) - return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; - else - return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + case PF_SHORT_GR: + return GL_LUMINANCE16_ALPHA16; + case PF_DXT1: + if (hwGamma) + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + else + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; case PF_DXT3: - if (hwGamma) - return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; - else - return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + if (hwGamma) + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + else + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; case PF_DXT5: - if (hwGamma) - return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; - else - return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + if (hwGamma) + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + else + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; default: return GL_NONE; } @@ -267,96 +267,96 @@ namespace Ogre { { GLenum format = getGLInternalFormat(mFormat, hwGamma); if(format==GL_NONE) - { - if (hwGamma) - return GL_SRGB8; - else - return GL_RGBA8; - } + { + if (hwGamma) + return GL_SRGB8; + else + return GL_RGBA8; + } else return format; } - - //----------------------------------------------------------------------------- - PixelFormat GLPixelUtil::getClosestOGREFormat(GLenum fmt) - { - switch(fmt) - { - case GL_LUMINANCE8: - return PF_L8; - case GL_LUMINANCE16: - return PF_L16; - case GL_ALPHA8: - return PF_A8; - case GL_LUMINANCE4_ALPHA4: - // Unsupported by GL as input format, use the byte packed format - return PF_BYTE_LA; - case GL_LUMINANCE8_ALPHA8: - return PF_BYTE_LA; - case GL_R3_G3_B2: - return PF_R3G3B2; - case GL_RGB5_A1: - return PF_A1R5G5B5; - case GL_RGB5: - return PF_R5G6B5; - case GL_RGBA4: - return PF_A4R4G4B4; - case GL_RGB8: - case GL_SRGB8: - return PF_X8R8G8B8; - case GL_RGBA8: - case GL_SRGB8_ALPHA8: - return PF_A8R8G8B8; - case GL_RGB10_A2: - return PF_A2R10G10B10; - case GL_RGBA16: - return PF_SHORT_RGBA; + + //----------------------------------------------------------------------------- + PixelFormat GLPixelUtil::getClosestOGREFormat(GLenum fmt) + { + switch(fmt) + { + case GL_LUMINANCE8: + return PF_L8; + case GL_LUMINANCE16: + return PF_L16; + case GL_ALPHA8: + return PF_A8; + case GL_LUMINANCE4_ALPHA4: + // Unsupported by GL as input format, use the byte packed format + return PF_BYTE_LA; + case GL_LUMINANCE8_ALPHA8: + return PF_BYTE_LA; + case GL_R3_G3_B2: + return PF_R3G3B2; + case GL_RGB5_A1: + return PF_A1R5G5B5; + case GL_RGB5: + return PF_R5G6B5; + case GL_RGBA4: + return PF_A4R4G4B4; + case GL_RGB8: + case GL_SRGB8: + return PF_X8R8G8B8; + case GL_RGBA8: + case GL_SRGB8_ALPHA8: + return PF_A8R8G8B8; + case GL_RGB10_A2: + return PF_A2R10G10B10; + case GL_RGBA16: + return PF_SHORT_RGBA; case GL_RGB16: return PF_SHORT_RGB; - case GL_LUMINANCE16_ALPHA16: - return PF_SHORT_GR; - case GL_LUMINANCE_FLOAT16_ATI: - return PF_FLOAT16_R; - case GL_LUMINANCE_ALPHA_FLOAT16_ATI: - return PF_FLOAT16_GR; - case GL_LUMINANCE_ALPHA_FLOAT32_ATI: - return PF_FLOAT32_GR; - case GL_LUMINANCE_FLOAT32_ATI: - return PF_FLOAT32_R; - case GL_RGB_FLOAT16_ATI: // GL_RGB16F_ARB - return PF_FLOAT16_RGB; - case GL_RGBA_FLOAT16_ATI: - return PF_FLOAT16_RGBA; - case GL_RGB_FLOAT32_ATI: - return PF_FLOAT32_RGB; - case GL_RGBA_FLOAT32_ATI: - return PF_FLOAT32_RGBA; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - return PF_DXT1; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - return PF_DXT3; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - return PF_DXT5; - default: - return PF_A8R8G8B8; - }; - } - //----------------------------------------------------------------------------- + case GL_LUMINANCE16_ALPHA16: + return PF_SHORT_GR; + case GL_LUMINANCE_FLOAT16_ATI: + return PF_FLOAT16_R; + case GL_LUMINANCE_ALPHA_FLOAT16_ATI: + return PF_FLOAT16_GR; + case GL_LUMINANCE_ALPHA_FLOAT32_ATI: + return PF_FLOAT32_GR; + case GL_LUMINANCE_FLOAT32_ATI: + return PF_FLOAT32_R; + case GL_RGB_FLOAT16_ATI: // GL_RGB16F_ARB + return PF_FLOAT16_RGB; + case GL_RGBA_FLOAT16_ATI: + return PF_FLOAT16_RGBA; + case GL_RGB_FLOAT32_ATI: + return PF_FLOAT32_RGB; + case GL_RGBA_FLOAT32_ATI: + return PF_FLOAT32_RGBA; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + return PF_DXT1; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + return PF_DXT3; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return PF_DXT5; + default: + return PF_A8R8G8B8; + }; + } + //----------------------------------------------------------------------------- - size_t GLPixelUtil::getMaxMipmaps(uint32 width, uint32 height, uint32 depth, PixelFormat format) - { - size_t count = 0; + size_t GLPixelUtil::getMaxMipmaps(uint32 width, uint32 height, uint32 depth, PixelFormat format) + { + size_t count = 0; if((width > 0) && (height > 0) && (depth > 0)) { do { - if(width>1) width = width/2; - if(height>1) height = height/2; - if(depth>1) depth = depth/2; + if(width>1) width = width/2; + if(height>1) height = height/2; + if(depth>1) depth = depth/2; /* NOT needed, compressed formats will have mipmaps up to 1x1 if(PixelUtil::isValidExtent(width, height, depth, format)) @@ -367,9 +367,9 @@ namespace Ogre { count ++; } while(!(width == 1 && height == 1 && depth == 1)); - } - return count; - } + } + return count; + } //----------------------------------------------------------------------------- uint32 GLPixelUtil::optionalPO2(uint32 value) { @@ -380,5 +380,5 @@ namespace Ogre { return Bitwise::firstPO2From(value); } - + } diff --git a/RenderSystems/GL/src/OgreGLRenderSystem.cpp b/RenderSystems/GL/src/OgreGLRenderSystem.cpp index 2ee105d96d4..49f3df42411 100644 --- a/RenderSystems/GL/src/OgreGLRenderSystem.cpp +++ b/RenderSystems/GL/src/OgreGLRenderSystem.cpp @@ -126,7 +126,7 @@ namespace Ogre { // Get our GLSupport mGLSupport = getGLSupport(); - mGLSupport->setStateCacheManager(mStateCacheManager); + mGLSupport->setStateCacheManager(mStateCacheManager); for( i=0; i units) units = arbUnits; } - rsc->setNumTextureUnits(std::min(16, units)); + rsc->setNumTextureUnits(std::min(16, units)); } else { @@ -373,7 +373,7 @@ namespace Ogre { rsc->setCapability(RSC_GL1_5_NOVBO); } rsc->setCapability(RSC_VBO); - rsc->setCapability(RSC_32BIT_INDEX); + rsc->setCapability(RSC_32BIT_INDEX); } if(GLEW_ARB_vertex_program) @@ -1015,19 +1015,19 @@ namespace Ogre { void GLRenderSystem::setAmbientLight(float r, float g, float b) { - mStateCacheManager->setLightAmbient(r, g, b); + mStateCacheManager->setLightAmbient(r, g, b); } void GLRenderSystem::setShadingType(ShadeOptions so) { - // XXX Don't do this when using shader + // XXX Don't do this when using shader switch(so) { case SO_FLAT: - mStateCacheManager->setShadeModel(GL_FLAT); + mStateCacheManager->setShadeModel(GL_FLAT); break; default: - mStateCacheManager->setShadeModel(GL_SMOOTH); + mStateCacheManager->setShadeModel(GL_SMOOTH); break; } } @@ -1137,7 +1137,7 @@ namespace Ogre { { //Unlike D3D9, OGL doesn't allow sharing the main depth buffer, so keep them separate. //Only Copy does, but Copy means only one depth buffer... - GLContext *windowContext = 0; + GLContext *windowContext = 0; win->getCustomAttribute( GLRenderTexture::CustomAttributeString_GLCONTEXT, &windowContext ); GLDepthBuffer *depthBuffer = new GLDepthBuffer( DepthBuffer::POOL_DEFAULT, this, @@ -1218,7 +1218,7 @@ namespace Ogre { glewContextInit(mGLSupport); #endif - mStateCacheManager->switchContext((intptr_t)mCurrentContext); + mStateCacheManager->switchContext((intptr_t)mCurrentContext); } @@ -1241,7 +1241,7 @@ namespace Ogre { { if (i->second == pWin) { - GLContext *windowContext = 0; + GLContext *windowContext = 0; pWin->getCustomAttribute(GLRenderTexture::CustomAttributeString_GLCONTEXT, &windowContext); //1 Window <-> 1 Context, should be always true @@ -1326,18 +1326,18 @@ namespace Ogre { if (!lt) { // Disable in the scene - mStateCacheManager-> setEnabled(gl_index, false); + mStateCacheManager-> setEnabled(gl_index, false); } else { switch (lt->getType()) { case Light::LT_SPOTLIGHT: - glLightf(gl_index, GL_SPOT_CUTOFF, 0.5f * lt->getSpotlightOuterAngle().valueDegrees()); + glLightf(gl_index, GL_SPOT_CUTOFF, 0.5f * lt->getSpotlightOuterAngle().valueDegrees()); glLightf(gl_index, GL_SPOT_EXPONENT, lt->getSpotlightFalloff()); break; default: - glLightf(gl_index, GL_SPOT_CUTOFF, 180.0); + glLightf(gl_index, GL_SPOT_CUTOFF, 180.0); break; } @@ -1369,7 +1369,7 @@ namespace Ogre { glLightf(gl_index, GL_LINEAR_ATTENUATION, lt->getAttenuationLinear()); glLightf(gl_index, GL_QUADRATIC_ATTENUATION, lt->getAttenuationQuadric()); // Enable in the scene - mStateCacheManager->setEnabled(gl_index, true); + mStateCacheManager->setEnabled(gl_index, true); } } @@ -1471,18 +1471,18 @@ namespace Ogre { } glColorMaterial(GL_FRONT_AND_BACK, gt); - mStateCacheManager->setEnabled(GL_COLOR_MATERIAL, true); + mStateCacheManager->setEnabled(GL_COLOR_MATERIAL, true); } else { - mStateCacheManager->setEnabled(GL_COLOR_MATERIAL, false); + mStateCacheManager->setEnabled(GL_COLOR_MATERIAL, false); } - mStateCacheManager->setMaterialDiffuse(diffuse.r, diffuse.g, diffuse.b, diffuse.a); - mStateCacheManager->setMaterialAmbient(ambient.r, ambient.g, ambient.b, ambient.a); - mStateCacheManager->setMaterialSpecular(specular.r, specular.g, specular.b, specular.a); - mStateCacheManager->setMaterialEmissive(emissive.r, emissive.g, emissive.b, emissive.a); - mStateCacheManager->setMaterialShininess(shininess); + mStateCacheManager->setMaterialDiffuse(diffuse.r, diffuse.g, diffuse.b, diffuse.a); + mStateCacheManager->setMaterialAmbient(ambient.r, ambient.g, ambient.b, ambient.a); + mStateCacheManager->setMaterialSpecular(specular.r, specular.g, specular.b, specular.a); + mStateCacheManager->setMaterialEmissive(emissive.r, emissive.g, emissive.b, emissive.a); + mStateCacheManager->setMaterialShininess(shininess); } //----------------------------------------------------------------------------- void GLRenderSystem::_setPointParameters(Real size, @@ -1514,21 +1514,21 @@ namespace Ogre { val[2] = quadratic * correction; if (mCurrentCapabilities->hasCapability(RSC_VERTEX_PROGRAM)) - mStateCacheManager->setEnabled(GL_VERTEX_PROGRAM_POINT_SIZE, true); + mStateCacheManager->setEnabled(GL_VERTEX_PROGRAM_POINT_SIZE, true); } else { if (maxSize == 0.0f) maxSize = mCurrentCapabilities->getMaxPointSize(); if (mCurrentCapabilities->hasCapability(RSC_VERTEX_PROGRAM)) - mStateCacheManager->setEnabled(GL_VERTEX_PROGRAM_POINT_SIZE, false); + mStateCacheManager->setEnabled(GL_VERTEX_PROGRAM_POINT_SIZE, false); } // no scaling required // GL has no disabled flag for this so just set to constant - mStateCacheManager->setPointSize(size); + mStateCacheManager->setPointSize(size); - mStateCacheManager->setPointParameters(val, minSize, maxSize); + mStateCacheManager->setPointParameters(val, minSize, maxSize); } //--------------------------------------------------------------------- void GLRenderSystem::_setPointSpritesEnabled(bool enabled) @@ -1542,11 +1542,11 @@ namespace Ogre { // Don't offer this as an option since D3D links it to sprite enabled for (ushort i = 0; i < mFixedFunctionTextureUnits; ++i) { - mStateCacheManager->activateGLTextureUnit(i); - glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, + mStateCacheManager->activateGLTextureUnit(i); + glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, enabled ? GL_TRUE : GL_FALSE); } - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } //----------------------------------------------------------------------------- @@ -1555,7 +1555,7 @@ namespace Ogre { GLTexturePtr tex = texPtr.staticCast(); GLenum lastTextureType = mTextureTypes[stage]; - if (!mStateCacheManager->activateGLTextureUnit(stage)) + if (!mStateCacheManager->activateGLTextureUnit(stage)) return; if (enabled) @@ -1586,9 +1586,9 @@ namespace Ogre { } if(!tex.isNull()) - mStateCacheManager->bindGLTexture( mTextureTypes[stage], tex->getGLID() ); + mStateCacheManager->bindGLTexture( mTextureTypes[stage], tex->getGLID() ); else - mStateCacheManager->bindGLTexture( mTextureTypes[stage], static_cast(mTextureManager)->getWarningTextureID() ); + mStateCacheManager->bindGLTexture( mTextureTypes[stage], static_cast(mTextureManager)->getWarningTextureID() ); } else { @@ -1602,36 +1602,36 @@ namespace Ogre { glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } // bind zero texture - mStateCacheManager->bindGLTexture(GL_TEXTURE_2D, 0); - } - - mStateCacheManager->activateGLTextureUnit(0); - } - //----------------------------------------------------------------------------- - void GLRenderSystem::_setVertexTexture( size_t unit, const TexturePtr &tex ) - { - _setTexture(unit, true, tex); - } - //----------------------------------------------------------------------------- - void GLRenderSystem::_setGeometryTexture( size_t unit, const TexturePtr &tex ) - { - _setTexture(unit, true, tex); - } - //----------------------------------------------------------------------------- - void GLRenderSystem::_setComputeTexture( size_t unit, const TexturePtr &tex ) - { - _setTexture(unit, true, tex); - } - //----------------------------------------------------------------------------- - void GLRenderSystem::_setTesselationHullTexture( size_t unit, const TexturePtr &tex ) - { - _setTexture(unit, true, tex); - } - //----------------------------------------------------------------------------- - void GLRenderSystem::_setTesselationDomainTexture( size_t unit, const TexturePtr &tex ) - { - _setTexture(unit, true, tex); - } + mStateCacheManager->bindGLTexture(GL_TEXTURE_2D, 0); + } + + mStateCacheManager->activateGLTextureUnit(0); + } + //----------------------------------------------------------------------------- + void GLRenderSystem::_setVertexTexture( size_t unit, const TexturePtr &tex ) + { + _setTexture(unit, true, tex); + } + //----------------------------------------------------------------------------- + void GLRenderSystem::_setGeometryTexture( size_t unit, const TexturePtr &tex ) + { + _setTexture(unit, true, tex); + } + //----------------------------------------------------------------------------- + void GLRenderSystem::_setComputeTexture( size_t unit, const TexturePtr &tex ) + { + _setTexture(unit, true, tex); + } + //----------------------------------------------------------------------------- + void GLRenderSystem::_setTesselationHullTexture( size_t unit, const TexturePtr &tex ) + { + _setTexture(unit, true, tex); + } + //----------------------------------------------------------------------------- + void GLRenderSystem::_setTesselationDomainTexture( size_t unit, const TexturePtr &tex ) + { + _setTexture(unit, true, tex); + } //----------------------------------------------------------------------------- void GLRenderSystem::_setTextureCoordSet(size_t stage, size_t index) { @@ -1658,26 +1658,26 @@ namespace Ogre { GLfloat eyePlaneR[] = {0.0, 0.0, 1.0, 0.0}; GLfloat eyePlaneQ[] = {0.0, 0.0, 0.0, 1.0}; - if (!mStateCacheManager->activateGLTextureUnit(stage)) + if (!mStateCacheManager->activateGLTextureUnit(stage)) return; switch( m ) { case TEXCALC_NONE: - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_S ); - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_T ); - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_R ); - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_S ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_T ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_R ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); break; case TEXCALC_ENVIRONMENT_MAP: glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_S ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_T ); - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_R ); - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_S ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_T ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_R ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); // Need to use a texture matrix to flip the spheremap mUseAutoTextureMatrix = true; @@ -1694,18 +1694,18 @@ namespace Ogre { glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP ); glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_S ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_T ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_R ); - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_S ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_T ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_R ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); #else glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_S ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_T ); - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_R ); - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_S ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_T ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_R ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); #endif break; case TEXCALC_ENVIRONMENT_MAP_REFLECTION: @@ -1714,10 +1714,10 @@ namespace Ogre { glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP ); glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_S ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_T ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_R ); - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_S ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_T ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_R ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); // We need an extra texture matrix here // This sets the texture matrix to be the inverse of the view matrix @@ -1740,10 +1740,10 @@ namespace Ogre { glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP ); glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_S ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_T ); - mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_R ); - mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_S ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_T ); + mStateCacheManager->enableTextureCoordGen( GL_TEXTURE_GEN_R ); + mStateCacheManager->disableTextureCoordGen( GL_TEXTURE_GEN_Q ); break; case TEXCALC_PROJECTIVE_TEXTURE: glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); @@ -1754,10 +1754,10 @@ namespace Ogre { glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT); glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR); glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ); - mStateCacheManager->enableTextureCoordGen(GL_TEXTURE_GEN_S); - mStateCacheManager->enableTextureCoordGen(GL_TEXTURE_GEN_T); - mStateCacheManager->enableTextureCoordGen(GL_TEXTURE_GEN_R); - mStateCacheManager->enableTextureCoordGen(GL_TEXTURE_GEN_Q); + mStateCacheManager->enableTextureCoordGen(GL_TEXTURE_GEN_S); + mStateCacheManager->enableTextureCoordGen(GL_TEXTURE_GEN_T); + mStateCacheManager->enableTextureCoordGen(GL_TEXTURE_GEN_R); + mStateCacheManager->enableTextureCoordGen(GL_TEXTURE_GEN_Q); mUseAutoTextureMatrix = true; @@ -1782,7 +1782,7 @@ namespace Ogre { default: break; } - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } //----------------------------------------------------------------------------- GLint GLRenderSystem::getTextureAddressingMode( @@ -1805,24 +1805,24 @@ namespace Ogre { //----------------------------------------------------------------------------- void GLRenderSystem::_setTextureAddressingMode(size_t stage, const TextureUnitState::UVWAddressingMode& uvw) { - if (!mStateCacheManager->activateGLTextureUnit(stage)) + if (!mStateCacheManager->activateGLTextureUnit(stage)) return; - mStateCacheManager->setTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_S, + mStateCacheManager->setTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_S, getTextureAddressingMode(uvw.u)); - mStateCacheManager->setTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_T, + mStateCacheManager->setTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_T, getTextureAddressingMode(uvw.v)); - mStateCacheManager->setTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_R, + mStateCacheManager->setTexParameteri( mTextureTypes[stage], GL_TEXTURE_WRAP_R, getTextureAddressingMode(uvw.w)); - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } //----------------------------------------------------------------------------- void GLRenderSystem::_setTextureBorderColour(size_t stage, const ColourValue& colour) { GLfloat border[4] = { colour.r, colour.g, colour.b, colour.a }; - if (mStateCacheManager->activateGLTextureUnit(stage)) + if (mStateCacheManager->activateGLTextureUnit(stage)) { glTexParameterfv( mTextureTypes[stage], GL_TEXTURE_BORDER_COLOR, border); - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } } //----------------------------------------------------------------------------- @@ -1830,7 +1830,7 @@ namespace Ogre { { if (mCurrentCapabilities->hasCapability(RSC_MIPMAP_LOD_BIAS)) { - if (mStateCacheManager->activateGLTextureUnit(stage)) + if (mStateCacheManager->activateGLTextureUnit(stage)) { glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias); mStateCacheManager->activateGLTextureUnit(0); @@ -1849,7 +1849,7 @@ namespace Ogre { GLfloat mat[16]; makeGLMatrix(mat, xform); - if (!mStateCacheManager->activateGLTextureUnit(stage)) + if (!mStateCacheManager->activateGLTextureUnit(stage)) return; glMatrixMode(GL_TEXTURE); @@ -1863,7 +1863,7 @@ namespace Ogre { } glMatrixMode(GL_MODELVIEW); - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } //----------------------------------------------------------------------------- GLint GLRenderSystem::getBlendMode(SceneBlendFactor ogreBlend) const @@ -1901,12 +1901,12 @@ namespace Ogre { GLint destBlend = getBlendMode(destFactor); if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO) { - mStateCacheManager->setEnabled(GL_BLEND, false); + mStateCacheManager->setEnabled(GL_BLEND, false); } else { - mStateCacheManager->setEnabled(GL_BLEND, true); - mStateCacheManager->setBlendFunc(sourceBlend, destBlend); + mStateCacheManager->setEnabled(GL_BLEND, true); + mStateCacheManager->setBlendFunc(sourceBlend, destBlend); } GLint func = GL_FUNC_ADD; @@ -1929,7 +1929,7 @@ namespace Ogre { break; } - mStateCacheManager->setBlendEquation(func); + mStateCacheManager->setBlendEquation(func); } //----------------------------------------------------------------------------- void GLRenderSystem::_setSeparateSceneBlending( @@ -1945,11 +1945,11 @@ namespace Ogre { if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO && sourceFactorAlpha == SBF_ONE && destFactorAlpha == SBF_ZERO) { - mStateCacheManager->setEnabled(GL_BLEND, false); + mStateCacheManager->setEnabled(GL_BLEND, false); } else { - mStateCacheManager->setEnabled(GL_BLEND, true); + mStateCacheManager->setEnabled(GL_BLEND, true); if(GLEW_VERSION_1_4) glBlendFuncSeparate(sourceBlend, destBlend, sourceBlendAlpha, destBlendAlpha); else if(GLEW_EXT_blend_func_separate) @@ -1996,7 +1996,7 @@ namespace Ogre { break; } - mStateCacheManager->setBlendEquation(func, alphaFunc); + mStateCacheManager->setBlendEquation(func, alphaFunc); } //----------------------------------------------------------------------------- void GLRenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage) @@ -2006,17 +2006,17 @@ namespace Ogre { mStateCacheManager->setEnabled(GL_ALPHA_TEST, func == CMPF_ALWAYS_PASS); - if(func != CMPF_ALWAYS_PASS) - { - a2c = alphaToCoverage; - glAlphaFunc(convertCompareFunction(func), value / 255.0f); - } + if(func != CMPF_ALWAYS_PASS) + { + a2c = alphaToCoverage; + glAlphaFunc(convertCompareFunction(func), value / 255.0f); + } - if (a2c != lasta2c && getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE)) - { + if (a2c != lasta2c && getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE)) + { mStateCacheManager->setEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE, a2c); - lasta2c = a2c; - } + lasta2c = a2c; + } } //----------------------------------------------------------------------------- @@ -2047,14 +2047,14 @@ namespace Ogre { // Convert "upper-left" corner to "lower-left" y = target->getHeight() - h - y; } - mStateCacheManager->setViewport(x, y, w, h); + mStateCacheManager->setViewport(x, y, w, h); // Configure the viewport clipping glScissor(x, y, w, h); - mScissorBox[0] = x; - mScissorBox[1] = y; - mScissorBox[2] = w; - mScissorBox[3] = h; + mScissorBox[0] = x; + mScissorBox[1] = y; + mScissorBox[2] = w; + mScissorBox[3] = h; vp->_clearUpdatedFlag(); } @@ -2080,21 +2080,21 @@ namespace Ogre { "Cannot begin frame - no viewport selected.", "GLRenderSystem::_beginFrame"); - // Activate the viewport clipping - mStateCacheManager->setEnabled(GL_SCISSOR_TEST, true); - } - - //----------------------------------------------------------------------------- - void GLRenderSystem::_endFrame(void) - { - // Deactivate the viewport clipping. - mStateCacheManager->setEnabled(GL_SCISSOR_TEST, false); - // unbind GPU programs at end of frame - // this is mostly to avoid holding bound programs that might get deleted - // outside via the resource manager - unbindGpuProgram(GPT_VERTEX_PROGRAM); - unbindGpuProgram(GPT_FRAGMENT_PROGRAM); - } + // Activate the viewport clipping + mStateCacheManager->setEnabled(GL_SCISSOR_TEST, true); + } + + //----------------------------------------------------------------------------- + void GLRenderSystem::_endFrame(void) + { + // Deactivate the viewport clipping. + mStateCacheManager->setEnabled(GL_SCISSOR_TEST, false); + // unbind GPU programs at end of frame + // this is mostly to avoid holding bound programs that might get deleted + // outside via the resource manager + unbindGpuProgram(GPT_VERTEX_PROGRAM); + unbindGpuProgram(GPT_FRAGMENT_PROGRAM); + } //----------------------------------------------------------------------------- void GLRenderSystem::_setCullingMode(CullingMode mode) @@ -2108,40 +2108,40 @@ namespace Ogre { GLenum cullMode; - switch( mode ) - { - case CULL_NONE: - mStateCacheManager->setEnabled( GL_CULL_FACE, false ); - return; - default: - case CULL_CLOCKWISE: - if (mActiveRenderTarget && - ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) || - (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding))) - { - cullMode = GL_FRONT; - } - else - { - cullMode = GL_BACK; - } - break; - case CULL_ANTICLOCKWISE: - if (mActiveRenderTarget && - ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) || - (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding))) - { - cullMode = GL_BACK; - } - else - { - cullMode = GL_FRONT; - } - break; - } - - mStateCacheManager->setEnabled( GL_CULL_FACE, true ); - mStateCacheManager->setCullFace( cullMode ); + switch( mode ) + { + case CULL_NONE: + mStateCacheManager->setEnabled( GL_CULL_FACE, false ); + return; + default: + case CULL_CLOCKWISE: + if (mActiveRenderTarget && + ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) || + (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding))) + { + cullMode = GL_FRONT; + } + else + { + cullMode = GL_BACK; + } + break; + case CULL_ANTICLOCKWISE: + if (mActiveRenderTarget && + ((mActiveRenderTarget->requiresTextureFlipping() && !mInvertVertexWinding) || + (!mActiveRenderTarget->requiresTextureFlipping() && mInvertVertexWinding))) + { + cullMode = GL_BACK; + } + else + { + cullMode = GL_FRONT; + } + break; + } + + mStateCacheManager->setEnabled( GL_CULL_FACE, true ); + mStateCacheManager->setCullFace( cullMode ); } //----------------------------------------------------------------------------- void GLRenderSystem::_setDepthBufferParams(bool depthTest, bool depthWrite, CompareFunction depthFunction) @@ -2155,36 +2155,36 @@ namespace Ogre { { mStateCacheManager->setClearDepth(1.0f); mStateCacheManager->setEnabled(GL_DEPTH_TEST, enabled); - } + } //----------------------------------------------------------------------------- void GLRenderSystem::_setDepthBufferWriteEnabled(bool enabled) { GLboolean flag = enabled ? GL_TRUE : GL_FALSE; - mStateCacheManager->setDepthMask( flag ); + mStateCacheManager->setDepthMask( flag ); // Store for reference in _beginFrame mDepthWrite = enabled; } //----------------------------------------------------------------------------- void GLRenderSystem::_setDepthBufferFunction(CompareFunction func) { - mStateCacheManager->setDepthFunc(convertCompareFunction(func)); - } - //----------------------------------------------------------------------------- - void GLRenderSystem::_setDepthBias(float constantBias, float slopeScaleBias) - { + mStateCacheManager->setDepthFunc(convertCompareFunction(func)); + } + //----------------------------------------------------------------------------- + void GLRenderSystem::_setDepthBias(float constantBias, float slopeScaleBias) + { mStateCacheManager->setEnabled(GL_POLYGON_OFFSET_FILL, constantBias != 0 || slopeScaleBias != 0); mStateCacheManager->setEnabled(GL_POLYGON_OFFSET_POINT, constantBias != 0 || slopeScaleBias != 0); mStateCacheManager->setEnabled(GL_POLYGON_OFFSET_LINE, constantBias != 0 || slopeScaleBias != 0); - if (constantBias != 0 || slopeScaleBias != 0) - { - glPolygonOffset(-slopeScaleBias, -constantBias); - } + if (constantBias != 0 || slopeScaleBias != 0) + { + glPolygonOffset(-slopeScaleBias, -constantBias); + } } //----------------------------------------------------------------------------- void GLRenderSystem::_setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha) { - mStateCacheManager->setColourMask(red, green, blue, alpha); + mStateCacheManager->setColourMask(red, green, blue, alpha); // record this mColourWrite[0] = red; mColourWrite[1] = blue; @@ -2331,18 +2331,18 @@ namespace Ogre { glmode = GL_FILL; break; } - mStateCacheManager->setPolygonMode(glmode); + mStateCacheManager->setPolygonMode(glmode); } //--------------------------------------------------------------------- void GLRenderSystem::setStencilCheckEnabled(bool enabled) { mStateCacheManager->setEnabled(GL_STENCIL_TEST, enabled); - } + } //--------------------------------------------------------------------- void GLRenderSystem::setStencilBufferParams(CompareFunction func, uint32 refValue, uint32 compareMask, uint32 writeMask, StencilOperation stencilFailOp, StencilOperation depthFailOp, StencilOperation passOp, - bool twoSidedOperation, bool readBackAsTexture) + bool twoSidedOperation, bool readBackAsTexture) { bool flip; mStencilWriteMask = writeMask; @@ -2353,33 +2353,33 @@ namespace Ogre { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "2-sided stencils are not supported", "GLRenderSystem::setStencilBufferParams"); - // NB: We should always treat CCW as front face for consistent with default - // culling mode. Therefore, we must take care with two-sided stencil settings. - flip = (mInvertVertexWinding && !mActiveRenderTarget->requiresTextureFlipping()) || - (!mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping()); - if(GLEW_VERSION_2_0) // New GL2 commands - { - // Back - glStencilMaskSeparate(GL_BACK, writeMask); - glStencilFuncSeparate(GL_BACK, convertCompareFunction(func), refValue, compareMask); - glStencilOpSeparate(GL_BACK, - convertStencilOp(stencilFailOp, !flip), - convertStencilOp(depthFailOp, !flip), - convertStencilOp(passOp, !flip)); - // Front - glStencilMaskSeparate(GL_FRONT, writeMask); - glStencilFuncSeparate(GL_FRONT, convertCompareFunction(func), refValue, compareMask); - glStencilOpSeparate(GL_FRONT, - convertStencilOp(stencilFailOp, flip), - convertStencilOp(depthFailOp, flip), - convertStencilOp(passOp, flip)); - } - else // EXT_stencil_two_side - { - mStateCacheManager->setEnabled(GL_STENCIL_TEST_TWO_SIDE_EXT, true); - // Back - glActiveStencilFaceEXT(GL_BACK); - mStateCacheManager->setStencilMask(writeMask); + // NB: We should always treat CCW as front face for consistent with default + // culling mode. Therefore, we must take care with two-sided stencil settings. + flip = (mInvertVertexWinding && !mActiveRenderTarget->requiresTextureFlipping()) || + (!mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping()); + if(GLEW_VERSION_2_0) // New GL2 commands + { + // Back + glStencilMaskSeparate(GL_BACK, writeMask); + glStencilFuncSeparate(GL_BACK, convertCompareFunction(func), refValue, compareMask); + glStencilOpSeparate(GL_BACK, + convertStencilOp(stencilFailOp, !flip), + convertStencilOp(depthFailOp, !flip), + convertStencilOp(passOp, !flip)); + // Front + glStencilMaskSeparate(GL_FRONT, writeMask); + glStencilFuncSeparate(GL_FRONT, convertCompareFunction(func), refValue, compareMask); + glStencilOpSeparate(GL_FRONT, + convertStencilOp(stencilFailOp, flip), + convertStencilOp(depthFailOp, flip), + convertStencilOp(passOp, flip)); + } + else // EXT_stencil_two_side + { + mStateCacheManager->setEnabled(GL_STENCIL_TEST_TWO_SIDE_EXT, true); + // Back + glActiveStencilFaceEXT(GL_BACK); + mStateCacheManager->setStencilMask(writeMask); glStencilFunc(convertCompareFunction(func), refValue, compareMask); glStencilOp( convertStencilOp(stencilFailOp, !flip), @@ -2387,7 +2387,7 @@ namespace Ogre { convertStencilOp(passOp, !flip)); // Front glActiveStencilFaceEXT(GL_FRONT); - mStateCacheManager->setStencilMask(writeMask); + mStateCacheManager->setStencilMask(writeMask); glStencilFunc(convertCompareFunction(func), refValue, compareMask); glStencilOp( convertStencilOp(stencilFailOp, flip), @@ -2401,7 +2401,7 @@ namespace Ogre { mStateCacheManager->setEnabled(GL_STENCIL_TEST_TWO_SIDE_EXT, false); flip = false; - mStateCacheManager->setStencilMask(writeMask); + mStateCacheManager->setStencilMask(writeMask); glStencilFunc(convertCompareFunction(func), refValue, compareMask); glStencilOp( convertStencilOp(stencilFailOp, flip), @@ -2506,14 +2506,14 @@ namespace Ogre { void GLRenderSystem::_setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions fo) { - if (!mStateCacheManager->activateGLTextureUnit(unit)) + if (!mStateCacheManager->activateGLTextureUnit(unit)) return; switch(ftype) { case FT_MIN: mMinFilter = fo; // Combine with existing mip filter - mStateCacheManager->setTexParameteri( + mStateCacheManager->setTexParameteri( mTextureTypes[unit], GL_TEXTURE_MIN_FILTER, getCombinedMinMipFilter()); @@ -2523,14 +2523,14 @@ namespace Ogre { { case FO_ANISOTROPIC: // GL treats linear and aniso the same case FO_LINEAR: - mStateCacheManager->setTexParameteri( + mStateCacheManager->setTexParameteri( mTextureTypes[unit], GL_TEXTURE_MAG_FILTER, GL_LINEAR); break; case FO_POINT: case FO_NONE: - mStateCacheManager->setTexParameteri( + mStateCacheManager->setTexParameteri( mTextureTypes[unit], GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -2540,14 +2540,14 @@ namespace Ogre { case FT_MIP: mMipFilter = fo; // Combine with existing min filter - mStateCacheManager->setTexParameteri( + mStateCacheManager->setTexParameteri( mTextureTypes[unit], GL_TEXTURE_MIN_FILTER, getCombinedMinMipFilter()); break; } - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } //--------------------------------------------------------------------- void GLRenderSystem::_setTextureUnitCompareFunction(size_t unit, CompareFunction function) @@ -2573,7 +2573,7 @@ namespace Ogre { if (!mCurrentCapabilities->hasCapability(RSC_ANISOTROPY)) return; - if (!mStateCacheManager->activateGLTextureUnit(unit)) + if (!mStateCacheManager->activateGLTextureUnit(unit)) return; GLfloat largest_supported_anisotropy = 0; @@ -2584,7 +2584,7 @@ namespace Ogre { if (_getCurrentAnisotropy(unit) != maxAnisotropy) glTexParameterf(mTextureTypes[unit], GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } //----------------------------------------------------------------------------- void GLRenderSystem::_setTextureBlendMode(size_t stage, const LayerBlendModeEx& bm) @@ -2727,7 +2727,7 @@ namespace Ogre { cmd = 0; } - if (!mStateCacheManager->activateGLTextureUnit(stage)) + if (!mStateCacheManager->activateGLTextureUnit(stage)) return; glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); @@ -2746,44 +2746,44 @@ namespace Ogre { glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT); } - float blendValue[4] = {0, 0, 0, static_cast(bm.factor)}; - switch (bm.operation) - { - case LBX_BLEND_DIFFUSE_COLOUR: - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR); - break; - case LBX_BLEND_DIFFUSE_ALPHA: - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR); - break; - case LBX_BLEND_TEXTURE_ALPHA: - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_TEXTURE); - break; - case LBX_BLEND_CURRENT_ALPHA: - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PREVIOUS); - break; - case LBX_BLEND_MANUAL: - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, blendValue); - break; - default: - break; - }; + float blendValue[4] = {0, 0, 0, static_cast(bm.factor)}; + switch (bm.operation) + { + case LBX_BLEND_DIFFUSE_COLOUR: + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR); + break; + case LBX_BLEND_DIFFUSE_ALPHA: + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PRIMARY_COLOR); + break; + case LBX_BLEND_TEXTURE_ALPHA: + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_TEXTURE); + break; + case LBX_BLEND_CURRENT_ALPHA: + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_PREVIOUS); + break; + case LBX_BLEND_MANUAL: + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, blendValue); + break; + default: + break; + }; switch (bm.operation) { case LBX_MODULATE_X2: - glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ? + glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ? GL_RGB_SCALE : GL_ALPHA_SCALE, 2); break; case LBX_MODULATE_X4: - glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ? + glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ? GL_RGB_SCALE : GL_ALPHA_SCALE, 4); break; default: - glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ? + glTexEnvi(GL_TEXTURE_ENV, bm.blendType == LBT_COLOUR ? GL_RGB_SCALE : GL_ALPHA_SCALE, 1); break; } @@ -2806,7 +2806,7 @@ namespace Ogre { if (bm.source2 == LBS_MANUAL) glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cv2); - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } //--------------------------------------------------------------------- void GLRenderSystem::setGLLightPositionDirection(Light* lt, GLenum lightindex) @@ -2951,7 +2951,7 @@ namespace Ogre { if(mCurrentCapabilities->hasCapability(RSC_VBO)) { - mStateCacheManager->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, + mStateCacheManager->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, static_cast( op.indexData->indexBuffer.get())->getGLBufferId()); @@ -3047,13 +3047,13 @@ namespace Ogre { mRenderAttribsBound.clear(); mRenderInstanceAttribsBound.clear(); - } - //--------------------------------------------------------------------- - void GLRenderSystem::setNormaliseNormals(bool normalise) - { + } + //--------------------------------------------------------------------- + void GLRenderSystem::setNormaliseNormals(bool normalise) + { mStateCacheManager->setEnabled(GL_NORMALIZE, normalise); - } - //--------------------------------------------------------------------- + } + //--------------------------------------------------------------------- void GLRenderSystem::bindGpuProgram(GpuProgram* prg) { if (!prg) @@ -3237,13 +3237,13 @@ namespace Ogre { clipPlane[3] = plane.d; glClipPlane(clipPlaneId, clipPlane); - mStateCacheManager->setEnabled(clipPlaneId, true); + mStateCacheManager->setEnabled(clipPlaneId, true); } // disable remaining clip planes for ( ; i < 6/*GL_MAX_CLIP_PLANES*/; ++i) { - mStateCacheManager->setEnabled(static_cast(GL_CLIP_PLANE0 + i), false); + mStateCacheManager->setEnabled(static_cast(GL_CLIP_PLANE0 + i), false); } // restore matrices @@ -3262,7 +3262,7 @@ namespace Ogre { if (enabled) { - mStateCacheManager->setEnabled(GL_SCISSOR_TEST, true); + mStateCacheManager->setEnabled(GL_SCISSOR_TEST, true); // NB GL uses width / height rather than right / bottom x = left; if (flipping) @@ -3272,10 +3272,10 @@ namespace Ogre { w = right - left; h = bottom - top; glScissor(x, y, w, h); - mScissorBox[0] = x; - mScissorBox[1] = y; - mScissorBox[2] = w; - mScissorBox[3] = h; + mScissorBox[0] = x; + mScissorBox[1] = y; + mScissorBox[2] = w; + mScissorBox[3] = h; } else { @@ -3288,10 +3288,10 @@ namespace Ogre { else y = targetHeight - mActiveViewport->getActualTop() - h; glScissor(x, y, w, h); - mScissorBox[0] = x; - mScissorBox[1] = y; - mScissorBox[2] = w; - mScissorBox[3] = h; + mScissorBox[0] = x; + mScissorBox[1] = y; + mScissorBox[2] = w; + mScissorBox[3] = h; } } //--------------------------------------------------------------------- @@ -3308,9 +3308,9 @@ namespace Ogre { // Enable buffer for writing if it isn't if (colourMask) { - mStateCacheManager->setColourMask(true, true, true, true); + mStateCacheManager->setColourMask(true, true, true, true); } - mStateCacheManager->setClearColour(colour.r, colour.g, colour.b, colour.a); + mStateCacheManager->setClearColour(colour.r, colour.g, colour.b, colour.a); } if (buffers & FBT_DEPTH) { @@ -3318,15 +3318,15 @@ namespace Ogre { // Enable buffer for writing if it isn't if (!mDepthWrite) { - mStateCacheManager->setDepthMask( GL_TRUE ); + mStateCacheManager->setDepthMask( GL_TRUE ); } - mStateCacheManager->setClearDepth(depth); + mStateCacheManager->setClearDepth(depth); } if (buffers & FBT_STENCIL) { flags |= GL_STENCIL_BUFFER_BIT; // Enable buffer for writing if it isn't - mStateCacheManager->setStencilMask(0xFFFFFFFF); + mStateCacheManager->setStencilMask(0xFFFFFFFF); glClearStencil(stencil); } @@ -3336,11 +3336,11 @@ namespace Ogre { mStateCacheManager->setEnabled(GL_SCISSOR_TEST, true); // Sets the scissor box as same as viewport - GLint viewport[4]; - mStateCacheManager->getViewport(viewport); + GLint viewport[4]; + mStateCacheManager->getViewport(viewport); bool scissorBoxDifference = - viewport[0] != mScissorBox[0] || viewport[1] != mScissorBox[1] || - viewport[2] != mScissorBox[2] || viewport[3] != mScissorBox[3]; + viewport[0] != mScissorBox[0] || viewport[1] != mScissorBox[1] || + viewport[2] != mScissorBox[2] || viewport[3] != mScissorBox[3]; if (scissorBoxDifference) { glScissor(viewport[0], viewport[1], viewport[2], viewport[3]); @@ -3352,7 +3352,7 @@ namespace Ogre { // Restore scissor box if (scissorBoxDifference) { - glScissor(mScissorBox[0], mScissorBox[1], mScissorBox[2], mScissorBox[3]); + glScissor(mScissorBox[0], mScissorBox[1], mScissorBox[2], mScissorBox[3]); } // Restore scissor test @@ -3361,15 +3361,15 @@ namespace Ogre { // Reset buffer write state if (!mDepthWrite && (buffers & FBT_DEPTH)) { - mStateCacheManager->setDepthMask( GL_FALSE ); + mStateCacheManager->setDepthMask( GL_FALSE ); } if (colourMask && (buffers & FBT_COLOUR)) { - mStateCacheManager->setColourMask(mColourWrite[0], mColourWrite[1], mColourWrite[2], mColourWrite[3]); + mStateCacheManager->setColourMask(mColourWrite[0], mColourWrite[1], mColourWrite[2], mColourWrite[3]); } if (buffers & FBT_STENCIL) { - mStateCacheManager->setStencilMask(mStencilWriteMask); + mStateCacheManager->setStencilMask(mStencilWriteMask); } } // ------------------------------------------------------------------ @@ -3454,25 +3454,25 @@ namespace Ogre { // Set nicer lighting model -- d3d9 has this by default glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); - } - if (GLEW_VERSION_1_4) - { - mStateCacheManager->setEnabled(GL_COLOR_SUM, true); - mStateCacheManager->setEnabled(GL_DITHER, false); - } - - // Check for FSAA - // Enable the extension if it was enabled by the GLSupport - if (mGLSupport->checkExtension("GL_ARB_multisample")) - { - int fsaa_active = false; - glGetIntegerv(GL_SAMPLE_BUFFERS_ARB,(GLint*)&fsaa_active); - if(fsaa_active) - { - mStateCacheManager->setEnabled(GL_MULTISAMPLE_ARB, true); - LogManager::getSingleton().logMessage("Using FSAA from GL_ARB_multisample extension."); - } - } + } + if (GLEW_VERSION_1_4) + { + mStateCacheManager->setEnabled(GL_COLOR_SUM, true); + mStateCacheManager->setEnabled(GL_DITHER, false); + } + + // Check for FSAA + // Enable the extension if it was enabled by the GLSupport + if (mGLSupport->checkExtension("GL_ARB_multisample")) + { + int fsaa_active = false; + glGetIntegerv(GL_SAMPLE_BUFFERS_ARB,(GLint*)&fsaa_active); + if(fsaa_active) + { + mStateCacheManager->setEnabled(GL_MULTISAMPLE_ARB, true); + LogManager::getSingleton().logMessage("Using FSAA from GL_ARB_multisample extension."); + } + } static_cast(mTextureManager)->createWarningTexture(); } @@ -3506,7 +3506,7 @@ namespace Ogre { mCurrentContext = context; mCurrentContext->setCurrent(); - mStateCacheManager->switchContext((intptr_t)mCurrentContext); + mStateCacheManager->switchContext((intptr_t)mCurrentContext); // Check if the context has already done one-time initialisation if(!mCurrentContext->getInitialized()) @@ -3526,9 +3526,9 @@ namespace Ogre { // Must reset depth/colour write mask to according with user desired, otherwise, // clearFrameBuffer would be wrong because the value we are recorded may be // difference with the really state stored in GL context. - mStateCacheManager->setDepthMask(mDepthWrite); - mStateCacheManager->setColourMask(mColourWrite[0], mColourWrite[1], mColourWrite[2], mColourWrite[3]); - mStateCacheManager->setStencilMask(mStencilWriteMask); + mStateCacheManager->setDepthMask(mDepthWrite); + mStateCacheManager->setColourMask(mColourWrite[0], mColourWrite[1], mColourWrite[2], mColourWrite[3]); + mStateCacheManager->setStencilMask(mStencilWriteMask); } //--------------------------------------------------------------------- @@ -3563,13 +3563,13 @@ namespace Ogre { // Bind frame buffer object mRTTManager->bind(target); - if (GLEW_EXT_framebuffer_sRGB) - { - // Enable / disable sRGB states + if (GLEW_EXT_framebuffer_sRGB) + { + // Enable / disable sRGB states mStateCacheManager->setEnabled(GL_FRAMEBUFFER_SRGB_EXT, target->isHardwareGammaEnabled()); - } - } - } + } + } + } //--------------------------------------------------------------------- void GLRenderSystem::_unregisterContext(GLContext *context) { @@ -3586,7 +3586,7 @@ namespace Ogre { mMainContext = 0; } } - mStateCacheManager->unregisterContext((intptr_t)context); + mStateCacheManager->unregisterContext((intptr_t)context); } //--------------------------------------------------------------------- Real GLRenderSystem::getMinimumDepthInputValue(void) diff --git a/RenderSystems/GL/src/OgreGLRenderTexture.cpp b/RenderSystems/GL/src/OgreGLRenderTexture.cpp index 1ea58f63358..368a5811321 100755 --- a/RenderSystems/GL/src/OgreGLRenderTexture.cpp +++ b/RenderSystems/GL/src/OgreGLRenderTexture.cpp @@ -46,7 +46,7 @@ template<> GLRTTManager* Singleton::msSingleton = 0; } MultiRenderTarget* GLRTTManager::createMultiRenderTarget(const String & name) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "MultiRenderTarget can only be used with GL_EXT_framebuffer_object extension", "GLRTTManager::createMultiRenderTarget"); + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "MultiRenderTarget can only be used with GL_EXT_framebuffer_object extension", "GLRTTManager::createMultiRenderTarget"); } PixelFormat GLRTTManager::getSupportedAlternative(PixelFormat format) { @@ -74,15 +74,15 @@ template<> GLRTTManager* Singleton::msSingleton = 0; RenderTexture(target.buffer, target.zoffset) { mName = name; - mHwGamma = writeGamma; - mFSAA = fsaa; + mHwGamma = writeGamma; + mFSAA = fsaa; } GLRenderTexture::~GLRenderTexture() { } //----------------------------------------------------------------------------- GLCopyingRenderTexture::GLCopyingRenderTexture(GLCopyingRTTManager *manager, - const String &name, const GLSurfaceDesc &target, bool writeGamma, uint fsaa): + const String &name, const GLSurfaceDesc &target, bool writeGamma, uint fsaa): GLRenderTexture(name, target, writeGamma, fsaa) { } @@ -90,9 +90,9 @@ template<> GLRTTManager* Singleton::msSingleton = 0; { if( name == GLRenderTexture::CustomAttributeString_TARGET ) { - GLSurfaceDesc &target = *static_cast(pData); - target.buffer = static_cast(mBuffer); - target.zoffset = mZOffset; + GLSurfaceDesc &target = *static_cast(pData); + target.buffer = static_cast(mBuffer); + target.zoffset = mZOffset; } } //----------------------------------------------------------------------------- @@ -104,7 +104,7 @@ template<> GLRTTManager* Singleton::msSingleton = 0; } RenderTexture *GLCopyingRTTManager::createRenderTexture(const String &name, const GLSurfaceDesc &target, - bool writeGamma, uint fsaa) + bool writeGamma, uint fsaa) { return new GLCopyingRenderTexture(this, name, target, writeGamma, fsaa); } @@ -123,12 +123,12 @@ template<> GLRTTManager* Singleton::msSingleton = 0; { // Copy on unbind GLSurfaceDesc surface; - surface.buffer = 0; + surface.buffer = 0; target->getCustomAttribute(GLRenderTexture::CustomAttributeString_TARGET, &surface); if(surface.buffer) static_cast(surface.buffer)->copyFromFramebuffer(surface.zoffset); } - //--------------------------------------------------------------------------------------------- + //--------------------------------------------------------------------------------------------- } diff --git a/RenderSystems/GL/src/OgreGLRenderToVertexBuffer.cpp b/RenderSystems/GL/src/OgreGLRenderToVertexBuffer.cpp index cf85ccc07ab..7988626cffd 100644 --- a/RenderSystems/GL/src/OgreGLRenderToVertexBuffer.cpp +++ b/RenderSystems/GL/src/OgreGLRenderToVertexBuffer.cpp @@ -40,317 +40,317 @@ THE SOFTWARE. namespace Ogre { //----------------------------------------------------------------------------- - static GLint getR2VBPrimitiveType(RenderOperation::OperationType operationType) - { - switch (operationType) - { - case RenderOperation::OT_POINT_LIST: - return GL_POINTS; - case RenderOperation::OT_LINE_LIST: - return GL_LINES; - case RenderOperation::OT_TRIANGLE_LIST: - return GL_TRIANGLES; - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "GL RenderToVertexBuffer" - "can only output point lists, line lists, or triangle lists", - "OgreGLRenderToVertexBuffer::getR2VBPrimitiveType"); - } - } + static GLint getR2VBPrimitiveType(RenderOperation::OperationType operationType) + { + switch (operationType) + { + case RenderOperation::OT_POINT_LIST: + return GL_POINTS; + case RenderOperation::OT_LINE_LIST: + return GL_LINES; + case RenderOperation::OT_TRIANGLE_LIST: + return GL_TRIANGLES; + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "GL RenderToVertexBuffer" + "can only output point lists, line lists, or triangle lists", + "OgreGLRenderToVertexBuffer::getR2VBPrimitiveType"); + } + } //----------------------------------------------------------------------------- - static GLint getVertexCountPerPrimitive(RenderOperation::OperationType operationType) - { - //We can only get points, lines or triangles since they are the only - //legal R2VB output primitive types - switch (operationType) - { - case RenderOperation::OT_POINT_LIST: - return 1; - case RenderOperation::OT_LINE_LIST: - return 2; - default: - case RenderOperation::OT_TRIANGLE_LIST: - return 3; - } - } + static GLint getVertexCountPerPrimitive(RenderOperation::OperationType operationType) + { + //We can only get points, lines or triangles since they are the only + //legal R2VB output primitive types + switch (operationType) + { + case RenderOperation::OT_POINT_LIST: + return 1; + case RenderOperation::OT_LINE_LIST: + return 2; + default: + case RenderOperation::OT_TRIANGLE_LIST: + return 3; + } + } //----------------------------------------------------------------------------- - void checkGLError(bool logError, bool throwException, - const Ogre::String& sectionName = BLANKSTRING) - { - String msg; - bool foundError = false; + void checkGLError(bool logError, bool throwException, + const Ogre::String& sectionName = BLANKSTRING) + { + String msg; + bool foundError = false; - // get all the GL errors - GLenum glErr = glGetError(); - while (glErr != GL_NO_ERROR) + // get all the GL errors + GLenum glErr = glGetError(); + while (glErr != GL_NO_ERROR) { - const char* glerrStr = (const char*)gluErrorString(glErr); - if (glerrStr) - { - msg += String(glerrStr); - } - glErr = glGetError(); - foundError = true; + const char* glerrStr = (const char*)gluErrorString(glErr); + if (glerrStr) + { + msg += String(glerrStr); + } + glErr = glGetError(); + foundError = true; } - if (foundError && (logError || throwException)) - { - String fullErrorMessage = "GL Error : " + msg + " in " + sectionName; - if (logError) - { - LogManager::getSingleton().getDefaultLog()->logMessage(fullErrorMessage, LML_CRITICAL); - } - if (throwException) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - fullErrorMessage, "OgreGLRenderToVertexBuffer"); - } - } - } + if (foundError && (logError || throwException)) + { + String fullErrorMessage = "GL Error : " + msg + " in " + sectionName; + if (logError) + { + LogManager::getSingleton().getDefaultLog()->logMessage(fullErrorMessage, LML_CRITICAL); + } + if (throwException) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + fullErrorMessage, "OgreGLRenderToVertexBuffer"); + } + } + } //----------------------------------------------------------------------------- - GLRenderToVertexBuffer::GLRenderToVertexBuffer() : mFrontBufferIndex(-1) - { - mVertexBuffers[0].setNull(); - mVertexBuffers[1].setNull(); + GLRenderToVertexBuffer::GLRenderToVertexBuffer() : mFrontBufferIndex(-1) + { + mVertexBuffers[0].setNull(); + mVertexBuffers[1].setNull(); - // create query objects - glGenQueries(1, &mPrimitivesDrawnQuery); - } + // create query objects + glGenQueries(1, &mPrimitivesDrawnQuery); + } //----------------------------------------------------------------------------- - GLRenderToVertexBuffer::~GLRenderToVertexBuffer() - { - glDeleteQueries(1, &mPrimitivesDrawnQuery); - } + GLRenderToVertexBuffer::~GLRenderToVertexBuffer() + { + glDeleteQueries(1, &mPrimitivesDrawnQuery); + } //----------------------------------------------------------------------------- - void GLRenderToVertexBuffer::getRenderOperation(RenderOperation& op) - { - op.operationType = mOperationType; - op.useIndexes = false; - op.vertexData = mVertexData; - } + void GLRenderToVertexBuffer::getRenderOperation(RenderOperation& op) + { + op.operationType = mOperationType; + op.useIndexes = false; + op.vertexData = mVertexData; + } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- - void GLRenderToVertexBuffer::update(SceneManager* sceneMgr) - { - checkGLError(true, false, "start of GLRenderToVertexBuffer::update"); + void GLRenderToVertexBuffer::update(SceneManager* sceneMgr) + { + checkGLError(true, false, "start of GLRenderToVertexBuffer::update"); - size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; - if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) - { - //Buffers don't match. Need to reallocate. - mResetRequested = true; - } - - //Single pass only for now - Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); - //Set pass before binding buffers to activate the GPU programs - sceneMgr->_setPass(r2vbPass); - - checkGLError(true, false); + size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; + if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) + { + //Buffers don't match. Need to reallocate. + mResetRequested = true; + } + + //Single pass only for now + Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); + //Set pass before binding buffers to activate the GPU programs + sceneMgr->_setPass(r2vbPass); + + checkGLError(true, false); - bindVerticesOutput(r2vbPass); + bindVerticesOutput(r2vbPass); - RenderOperation renderOp; - size_t targetBufferIndex; - if (mResetRequested || mResetsEveryUpdate) - { - //Use source data to render to first buffer - mSourceRenderable->getRenderOperation(renderOp); - targetBufferIndex = 0; - } - else - { - //Use current front buffer to render to back buffer - this->getRenderOperation(renderOp); - targetBufferIndex = 1 - mFrontBufferIndex; - } + RenderOperation renderOp; + size_t targetBufferIndex; + if (mResetRequested || mResetsEveryUpdate) + { + //Use source data to render to first buffer + mSourceRenderable->getRenderOperation(renderOp); + targetBufferIndex = 0; + } + else + { + //Use current front buffer to render to back buffer + this->getRenderOperation(renderOp); + targetBufferIndex = 1 - mFrontBufferIndex; + } - if (mVertexBuffers[targetBufferIndex].isNull() || - mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) - { - reallocateBuffer(targetBufferIndex); - } + if (mVertexBuffers[targetBufferIndex].isNull() || + mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) + { + reallocateBuffer(targetBufferIndex); + } - GLHardwareVertexBuffer* vertexBuffer = static_cast(mVertexBuffers[targetBufferIndex].getPointer()); - GLuint bufferId = vertexBuffer->getGLBufferId(); + GLHardwareVertexBuffer* vertexBuffer = static_cast(mVertexBuffers[targetBufferIndex].getPointer()); + GLuint bufferId = vertexBuffer->getGLBufferId(); - //Bind the target buffer - glBindBufferOffsetNV(GL_TRANSFORM_FEEDBACK_BUFFER_NV, 0, bufferId, 0); + //Bind the target buffer + glBindBufferOffsetNV(GL_TRANSFORM_FEEDBACK_BUFFER_NV, 0, bufferId, 0); - glBeginTransformFeedbackNV(getR2VBPrimitiveType(mOperationType)); + glBeginTransformFeedbackNV(getR2VBPrimitiveType(mOperationType)); - glEnable(GL_RASTERIZER_DISCARD_NV); // disable rasterization + glEnable(GL_RASTERIZER_DISCARD_NV); // disable rasterization - glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV, mPrimitivesDrawnQuery); + glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV, mPrimitivesDrawnQuery); - RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); - //Draw the object - targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); - targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); - targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); - if (r2vbPass->hasVertexProgram()) - { - targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, - r2vbPass->getVertexProgramParameters(), GPV_ALL); - } - if (r2vbPass->hasGeometryProgram()) - { - targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, - r2vbPass->getGeometryProgramParameters(), GPV_ALL); - } - targetRenderSystem->_render(renderOp); - - //Finish the query - glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV); - glDisable(GL_RASTERIZER_DISCARD_NV); - glEndTransformFeedbackNV(); + RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); + //Draw the object + targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); + targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); + targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); + if (r2vbPass->hasVertexProgram()) + { + targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, + r2vbPass->getVertexProgramParameters(), GPV_ALL); + } + if (r2vbPass->hasGeometryProgram()) + { + targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, + r2vbPass->getGeometryProgramParameters(), GPV_ALL); + } + targetRenderSystem->_render(renderOp); + + //Finish the query + glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV); + glDisable(GL_RASTERIZER_DISCARD_NV); + glEndTransformFeedbackNV(); - //read back query results - GLuint primitivesWritten; - glGetQueryObjectuiv(mPrimitivesDrawnQuery, GL_QUERY_RESULT, &primitivesWritten); - mVertexData->vertexCount = primitivesWritten * getVertexCountPerPrimitive(mOperationType); + //read back query results + GLuint primitivesWritten; + glGetQueryObjectuiv(mPrimitivesDrawnQuery, GL_QUERY_RESULT, &primitivesWritten); + mVertexData->vertexCount = primitivesWritten * getVertexCountPerPrimitive(mOperationType); - checkGLError(true, true, "GLRenderToVertexBuffer::update"); + checkGLError(true, true, "GLRenderToVertexBuffer::update"); - //Switch the vertex binding if necessary - if (targetBufferIndex != mFrontBufferIndex) - { - mVertexData->vertexBufferBinding->unsetAllBindings(); - mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); - mFrontBufferIndex = targetBufferIndex; - } + //Switch the vertex binding if necessary + if (targetBufferIndex != mFrontBufferIndex) + { + mVertexData->vertexBufferBinding->unsetAllBindings(); + mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); + mFrontBufferIndex = targetBufferIndex; + } - glDisable(GL_RASTERIZER_DISCARD_NV); // enable rasterization + glDisable(GL_RASTERIZER_DISCARD_NV); // enable rasterization - //Clear the reset flag - mResetRequested = false; - } + //Clear the reset flag + mResetRequested = false; + } //----------------------------------------------------------------------------- - void GLRenderToVertexBuffer::reallocateBuffer(size_t index) - { - assert(index == 0 || index == 1); - if (!mVertexBuffers[index].isNull()) - { - mVertexBuffers[index].setNull(); - } - - mVertexBuffers[index] = HardwareBufferManager::getSingleton().createVertexBuffer( - mVertexData->vertexDeclaration->getVertexSize(0), mMaxVertexCount, + void GLRenderToVertexBuffer::reallocateBuffer(size_t index) + { + assert(index == 0 || index == 1); + if (!mVertexBuffers[index].isNull()) + { + mVertexBuffers[index].setNull(); + } + + mVertexBuffers[index] = HardwareBufferManager::getSingleton().createVertexBuffer( + mVertexData->vertexDeclaration->getVertexSize(0), mMaxVertexCount, #if OGRE_DEBUG_MODE - //Allow to read the contents of the buffer in debug mode - HardwareBuffer::HBU_DYNAMIC + //Allow to read the contents of the buffer in debug mode + HardwareBuffer::HBU_DYNAMIC #else - HardwareBuffer::HBU_STATIC_WRITE_ONLY + HardwareBuffer::HBU_STATIC_WRITE_ONLY #endif - ); - } + ); + } //----------------------------------------------------------------------------- - String GLRenderToVertexBuffer::getSemanticVaryingName(VertexElementSemantic semantic, unsigned short index) - { - switch (semantic) - { - case VES_POSITION: - return "gl_Position"; - case VES_TEXTURE_COORDINATES: - return String("gl_TexCoord[") + StringConverter::toString(index) + "]"; - case VES_DIFFUSE: - return "gl_FrontColor"; - case VES_SPECULAR: - return "gl_FrontSecondaryColor"; - //TODO : Implement more? - default: - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unsupported vertex element sematic in render to vertex buffer", - "OgreGLRenderToVertexBuffer::getSemanticVaryingName"); - } - } + String GLRenderToVertexBuffer::getSemanticVaryingName(VertexElementSemantic semantic, unsigned short index) + { + switch (semantic) + { + case VES_POSITION: + return "gl_Position"; + case VES_TEXTURE_COORDINATES: + return String("gl_TexCoord[") + StringConverter::toString(index) + "]"; + case VES_DIFFUSE: + return "gl_FrontColor"; + case VES_SPECULAR: + return "gl_FrontSecondaryColor"; + //TODO : Implement more? + default: + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unsupported vertex element sematic in render to vertex buffer", + "OgreGLRenderToVertexBuffer::getSemanticVaryingName"); + } + } //----------------------------------------------------------------------------- - GLint GLRenderToVertexBuffer::getGLSemanticType(VertexElementSemantic semantic) - { - switch (semantic) - { - case VES_POSITION: - return GL_POSITION; - case VES_TEXTURE_COORDINATES: - return GL_TEXTURE_COORD_NV; - case VES_DIFFUSE: - return GL_PRIMARY_COLOR; - case VES_SPECULAR: - return GL_SECONDARY_COLOR_NV; - //TODO : Implement more? - default: - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unsupported vertex element sematic in render to vertex buffer", - "OgreGLRenderToVertexBuffer::getGLSemanticType"); - - } - } + GLint GLRenderToVertexBuffer::getGLSemanticType(VertexElementSemantic semantic) + { + switch (semantic) + { + case VES_POSITION: + return GL_POSITION; + case VES_TEXTURE_COORDINATES: + return GL_TEXTURE_COORD_NV; + case VES_DIFFUSE: + return GL_PRIMARY_COLOR; + case VES_SPECULAR: + return GL_SECONDARY_COLOR_NV; + //TODO : Implement more? + default: + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unsupported vertex element sematic in render to vertex buffer", + "OgreGLRenderToVertexBuffer::getGLSemanticType"); + + } + } //----------------------------------------------------------------------------- - void GLRenderToVertexBuffer::bindVerticesOutput(Pass* pass) - { - VertexDeclaration* declaration = mVertexData->vertexDeclaration; - bool useVaryingAttributes = false; - - //Check if we are FixedFunc/ASM shaders (Static attributes) or GLSL (Varying attributes) - //We assume that there isn't a mix of GLSL and ASM as this is illegal - GpuProgram* sampleProgram = 0; - if (pass->hasVertexProgram()) - { - sampleProgram = pass->getVertexProgram().getPointer(); - } - else if (pass->hasGeometryProgram()) - { - sampleProgram = pass->getGeometryProgram().getPointer(); - } - if ((sampleProgram != 0) && (sampleProgram->getLanguage() == "glsl")) - { - useVaryingAttributes = true; - } + void GLRenderToVertexBuffer::bindVerticesOutput(Pass* pass) + { + VertexDeclaration* declaration = mVertexData->vertexDeclaration; + bool useVaryingAttributes = false; + + //Check if we are FixedFunc/ASM shaders (Static attributes) or GLSL (Varying attributes) + //We assume that there isn't a mix of GLSL and ASM as this is illegal + GpuProgram* sampleProgram = 0; + if (pass->hasVertexProgram()) + { + sampleProgram = pass->getVertexProgram().getPointer(); + } + else if (pass->hasGeometryProgram()) + { + sampleProgram = pass->getGeometryProgram().getPointer(); + } + if ((sampleProgram != 0) && (sampleProgram->getLanguage() == "glsl")) + { + useVaryingAttributes = true; + } - if (useVaryingAttributes) - { - //Have GLSL shaders, using varying attributes - GLSL::GLSLLinkProgram* linkProgram = GLSL::GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); - GLhandleARB linkProgramId = linkProgram->getGLHandle(); - - vector::type locations; - for (unsigned short e=0; e < declaration->getElementCount(); e++) - { - const VertexElement* element =declaration->getElement(e); - String varyingName = getSemanticVaryingName(element->getSemantic(), element->getIndex()); - GLint location = glGetVaryingLocationNV(linkProgramId, varyingName.c_str()); - if (location < 0) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "GLSL link program does not output " + varyingName + - " so it cannot fill the requested vertex buffer", - "OgreGLRenderToVertexBuffer::bindVerticesOutput"); - } - locations.push_back(location); - } - glTransformFeedbackVaryingsNV( - linkProgramId, static_cast(locations.size()), - &locations[0], GL_INTERLEAVED_ATTRIBS_NV); - } - else - { - //Either fixed function or assembly (CG = assembly) shaders - vector::type attribs; - for (unsigned short e=0; e < declaration->getElementCount(); e++) - { - const VertexElement* element = declaration->getElement(e); - //Type - attribs.push_back(getGLSemanticType(element->getSemantic())); - //Number of components - attribs.push_back(VertexElement::getTypeCount(element->getType())); - //Index - attribs.push_back(element->getIndex()); - } - - glTransformFeedbackAttribsNV( - static_cast(declaration->getElementCount()), - &attribs[0], GL_INTERLEAVED_ATTRIBS_NV); - } + if (useVaryingAttributes) + { + //Have GLSL shaders, using varying attributes + GLSL::GLSLLinkProgram* linkProgram = GLSL::GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); + GLhandleARB linkProgramId = linkProgram->getGLHandle(); + + vector::type locations; + for (unsigned short e=0; e < declaration->getElementCount(); e++) + { + const VertexElement* element =declaration->getElement(e); + String varyingName = getSemanticVaryingName(element->getSemantic(), element->getIndex()); + GLint location = glGetVaryingLocationNV(linkProgramId, varyingName.c_str()); + if (location < 0) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "GLSL link program does not output " + varyingName + + " so it cannot fill the requested vertex buffer", + "OgreGLRenderToVertexBuffer::bindVerticesOutput"); + } + locations.push_back(location); + } + glTransformFeedbackVaryingsNV( + linkProgramId, static_cast(locations.size()), + &locations[0], GL_INTERLEAVED_ATTRIBS_NV); + } + else + { + //Either fixed function or assembly (CG = assembly) shaders + vector::type attribs; + for (unsigned short e=0; e < declaration->getElementCount(); e++) + { + const VertexElement* element = declaration->getElement(e); + //Type + attribs.push_back(getGLSemanticType(element->getSemantic())); + //Number of components + attribs.push_back(VertexElement::getTypeCount(element->getType())); + //Index + attribs.push_back(element->getIndex()); + } + + glTransformFeedbackAttribsNV( + static_cast(declaration->getElementCount()), + &attribs[0], GL_INTERLEAVED_ATTRIBS_NV); + } - checkGLError(true, true, "GLRenderToVertexBuffer::bindVerticesOutput"); - } + checkGLError(true, true, "GLRenderToVertexBuffer::bindVerticesOutput"); + } } diff --git a/RenderSystems/GL/src/OgreGLStateCacheManager.cpp b/RenderSystems/GL/src/OgreGLStateCacheManager.cpp index 2e4e8d542b9..49f9eaccf66 100644 --- a/RenderSystems/GL/src/OgreGLStateCacheManager.cpp +++ b/RenderSystems/GL/src/OgreGLStateCacheManager.cpp @@ -123,9 +123,9 @@ namespace Ogre { } bool GLStateCacheManager::activateGLTextureUnit(size_t unit) - { + { return mImp->activateGLTextureUnit(unit); - } + } void GLStateCacheManager::setBlendFunc(GLenum source, GLenum dest) { diff --git a/RenderSystems/GL/src/OgreGLSupport.cpp b/RenderSystems/GL/src/OgreGLSupport.cpp index 66556280e9c..e48dfe89e60 100644 --- a/RenderSystems/GL/src/OgreGLSupport.cpp +++ b/RenderSystems/GL/src/OgreGLSupport.cpp @@ -34,18 +34,18 @@ THE SOFTWARE. namespace Ogre { - void GLSupport::setConfigOption(const String &name, const String &value) - { - ConfigOptionMap::iterator it = mOptions.find(name); + void GLSupport::setConfigOption(const String &name, const String &value) + { + ConfigOptionMap::iterator it = mOptions.find(name); if (it != mOptions.end()) it->second.currentValue = value; - } + } - ConfigOptionMap& GLSupport::getConfigOptions(void) - { - return mOptions; - } + ConfigOptionMap& GLSupport::getConfigOptions(void) + { + return mOptions; + } void GLSupport::initialiseExtensions(void) { @@ -71,7 +71,7 @@ namespace Ogre { LogManager::getSingleton().logMessage("GL_RENDERER = " + tmpStr); // Set extension list - StringStream ext; + StringStream ext; String str; const GLubyte* pcExt = glGetString(GL_EXTENSIONS); @@ -126,7 +126,7 @@ namespace Ogre { bool GLSupport::checkExtension(const String& ext) const { - assert(!extensionList.empty() && "ExtensionList is empty!" ); + assert(!extensionList.empty() && "ExtensionList is empty!" ); if(extensionList.find(ext) == extensionList.end()) return false; diff --git a/RenderSystems/GL/src/OgreGLTexture.cpp b/RenderSystems/GL/src/OgreGLTexture.cpp index fde05c86a4e..4cb230d1318 100644 --- a/RenderSystems/GL/src/OgreGLTexture.cpp +++ b/RenderSystems/GL/src/OgreGLTexture.cpp @@ -48,7 +48,7 @@ THE SOFTWARE. #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 # define WIN32_LEAN_AND_MEAN # if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif # include # include @@ -71,14 +71,14 @@ namespace Ogre { { // have to call this here rather than in Resource destructor // since calling virtual methods in base destructors causes crash - if (isLoaded()) - { - unload(); - } - else - { - freeInternalResources(); - } + if (isLoaded()) + { + unload(); + } + else + { + freeInternalResources(); + } } GLenum GLTexture::getGLTextureTarget(void) const @@ -100,173 +100,173 @@ namespace Ogre { }; } - //* Creation / loading methods ******************************************** - void GLTexture::createInternalResourcesImpl(void) + //* Creation / loading methods ******************************************** + void GLTexture::createInternalResourcesImpl(void) { - if (!GLEW_VERSION_1_2 && mTextureType == TEX_TYPE_3D) - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "3D Textures not supported before OpenGL 1.2", - "GLTexture::createInternalResourcesImpl"); + if (!GLEW_VERSION_1_2 && mTextureType == TEX_TYPE_3D) + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "3D Textures not supported before OpenGL 1.2", + "GLTexture::createInternalResourcesImpl"); - if (!GLEW_VERSION_2_0 && mTextureType == TEX_TYPE_2D_ARRAY) - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "2D texture arrays not supported before OpenGL 2.0", - "GLTexture::createInternalResourcesImpl"); + if (!GLEW_VERSION_2_0 && mTextureType == TEX_TYPE_2D_ARRAY) + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "2D texture arrays not supported before OpenGL 2.0", + "GLTexture::createInternalResourcesImpl"); - // Convert to nearest power-of-two size if required + // Convert to nearest power-of-two size if required mWidth = GLPixelUtil::optionalPO2(mWidth); mHeight = GLPixelUtil::optionalPO2(mHeight); mDepth = GLPixelUtil::optionalPO2(mDepth); - - - // Adjust format if required - mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage); - - // Check requested number of mipmaps - size_t maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat); - mNumMipmaps = mNumRequestedMipmaps; - if(mNumMipmaps>maxMips) - mNumMipmaps = maxMips; - - // Check if we can do HW mipmap generation - mMipmapsHardwareGenerated = - Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP); - - // Generate texture name + + + // Adjust format if required + mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage); + + // Check requested number of mipmaps + size_t maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat); + mNumMipmaps = mNumRequestedMipmaps; + if(mNumMipmaps>maxMips) + mNumMipmaps = maxMips; + + // Check if we can do HW mipmap generation + mMipmapsHardwareGenerated = + Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP); + + // Generate texture name glGenTextures( 1, &mTextureID ); - - // Set texture type - mGLSupport.getStateCacheManager()->bindGLTexture( getGLTextureTarget(), mTextureID ); - // This needs to be set otherwise the texture doesn't get rendered - if (GLEW_VERSION_1_2) - mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), - GL_TEXTURE_MAX_LEVEL, mNumMipmaps); + // Set texture type + mGLSupport.getStateCacheManager()->bindGLTexture( getGLTextureTarget(), mTextureID ); + + // This needs to be set otherwise the texture doesn't get rendered + if (GLEW_VERSION_1_2) + mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), + GL_TEXTURE_MAX_LEVEL, mNumMipmaps); // Set some misc default parameters so NVidia won't complain, these can of course be changed later mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST); mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST); - if (GLEW_VERSION_1_2) - { - mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - - if((mUsage & TU_AUTOMIPMAP) && - mNumRequestedMipmaps && mMipmapsHardwareGenerated) - { - mGLSupport.getStateCacheManager()->setTexParameteri( getGLTextureTarget(), GL_GENERATE_MIPMAP, GL_TRUE ); - } - - // Allocate internal buffer so that glTexSubImageXD can be used - // Internal format - GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma); - uint32 width = mWidth; - uint32 height = mHeight; - uint32 depth = mDepth; - - if(PixelUtil::isCompressed(mFormat)) - { - // Compressed formats - GLsizei size = static_cast(PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat)); - // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not - // accept a 0 pointer like normal glTexImageXD - // Run through this process for every mipmap to pregenerate mipmap piramid - uint8 *tmpdata = new uint8[size]; - memset(tmpdata, 0, size); - - for(uint8 mip=0; mip<=mNumMipmaps; mip++) - { - size = static_cast(PixelUtil::getMemorySize(width, height, depth, mFormat)); - switch(mTextureType) - { - case TEX_TYPE_1D: - glCompressedTexImage1DARB(GL_TEXTURE_1D, mip, format, - width, 0, - size, tmpdata); - break; - case TEX_TYPE_2D: - glCompressedTexImage2DARB(GL_TEXTURE_2D, mip, format, - width, height, 0, - size, tmpdata); - break; - case TEX_TYPE_2D_ARRAY: - case TEX_TYPE_3D: - glCompressedTexImage3DARB(getGLTextureTarget(), mip, format, - width, height, depth, 0, - size, tmpdata); - break; - case TEX_TYPE_CUBE_MAP: - for(int face=0; face<6; face++) { - glCompressedTexImage2DARB(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, - width, height, 0, - size, tmpdata); - } - break; + if (GLEW_VERSION_1_2) + { + mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + if((mUsage & TU_AUTOMIPMAP) && + mNumRequestedMipmaps && mMipmapsHardwareGenerated) + { + mGLSupport.getStateCacheManager()->setTexParameteri( getGLTextureTarget(), GL_GENERATE_MIPMAP, GL_TRUE ); + } + + // Allocate internal buffer so that glTexSubImageXD can be used + // Internal format + GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma); + uint32 width = mWidth; + uint32 height = mHeight; + uint32 depth = mDepth; + + if(PixelUtil::isCompressed(mFormat)) + { + // Compressed formats + GLsizei size = static_cast(PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat)); + // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not + // accept a 0 pointer like normal glTexImageXD + // Run through this process for every mipmap to pregenerate mipmap piramid + uint8 *tmpdata = new uint8[size]; + memset(tmpdata, 0, size); + + for(uint8 mip=0; mip<=mNumMipmaps; mip++) + { + size = static_cast(PixelUtil::getMemorySize(width, height, depth, mFormat)); + switch(mTextureType) + { + case TEX_TYPE_1D: + glCompressedTexImage1DARB(GL_TEXTURE_1D, mip, format, + width, 0, + size, tmpdata); + break; + case TEX_TYPE_2D: + glCompressedTexImage2DARB(GL_TEXTURE_2D, mip, format, + width, height, 0, + size, tmpdata); + break; + case TEX_TYPE_2D_ARRAY: + case TEX_TYPE_3D: + glCompressedTexImage3DARB(getGLTextureTarget(), mip, format, + width, height, depth, 0, + size, tmpdata); + break; + case TEX_TYPE_CUBE_MAP: + for(int face=0; face<6; face++) { + glCompressedTexImage2DARB(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, + width, height, 0, + size, tmpdata); + } + break; case TEX_TYPE_2D_RECT: break; - }; - if(width>1) + }; + if(width>1) width = width/2; - if(height>1) + if(height>1) height = height/2; - if(depth>1 && mTextureType != TEX_TYPE_2D_ARRAY) + if(depth>1 && mTextureType != TEX_TYPE_2D_ARRAY) depth = depth/2; - } - delete [] tmpdata; - } - else - { - // Run through this process to pregenerate mipmap pyramid - for(uint8 mip=0; mip<=mNumMipmaps; mip++) - { - // Normal formats - switch(mTextureType) - { - case TEX_TYPE_1D: - glTexImage1D(GL_TEXTURE_1D, mip, format, - width, 0, - GL_RGBA, GL_UNSIGNED_BYTE, 0); - - break; - case TEX_TYPE_2D: - glTexImage2D(GL_TEXTURE_2D, mip, format, - width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, 0); - break; - case TEX_TYPE_2D_ARRAY: - case TEX_TYPE_3D: - glTexImage3D(getGLTextureTarget(), mip, format, - width, height, depth, 0, - GL_RGBA, GL_UNSIGNED_BYTE, 0); - break; - case TEX_TYPE_CUBE_MAP: - for(int face=0; face<6; face++) { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, - width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, 0); - } - break; + } + delete [] tmpdata; + } + else + { + // Run through this process to pregenerate mipmap pyramid + for(uint8 mip=0; mip<=mNumMipmaps; mip++) + { + // Normal formats + switch(mTextureType) + { + case TEX_TYPE_1D: + glTexImage1D(GL_TEXTURE_1D, mip, format, + width, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + + break; + case TEX_TYPE_2D: + glTexImage2D(GL_TEXTURE_2D, mip, format, + width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + break; + case TEX_TYPE_2D_ARRAY: + case TEX_TYPE_3D: + glTexImage3D(getGLTextureTarget(), mip, format, + width, height, depth, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + break; + case TEX_TYPE_CUBE_MAP: + for(int face=0; face<6; face++) { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, + width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + } + break; case TEX_TYPE_2D_RECT: break; - }; - if(width>1) + }; + if(width>1) width = width/2; - if(height>1) + if(height>1) height = height/2; - if(depth>1 && mTextureType != TEX_TYPE_2D_ARRAY) + if(depth>1 && mTextureType != TEX_TYPE_2D_ARRAY) depth = depth/2; - } - } - _createSurfaceList(); - // Get final internal format - mFormat = getBuffer(0,0)->getFormat(); - } - + } + } + _createSurfaceList(); + // Get final internal format + mFormat = getBuffer(0,0)->getFormat(); + } + void GLTexture::createRenderTexture(void) { // Create the GL texture - // This already does everything necessary + // This already does everything necessary createInternalResources(); } @@ -275,7 +275,7 @@ namespace Ogre { vector::type &images, Resource *r) { - size_t imgIdx = images.size(); + size_t imgIdx = images.size(); images.push_back(Image()); DataStreamPtr dstream = @@ -285,7 +285,7 @@ namespace Ogre { images[imgIdx].load(dstream, ext); } - + void GLTexture::prepareImpl() { if( mUsage & TU_RENDERTARGET ) return; @@ -341,7 +341,7 @@ namespace Ogre { mLoadedImages = loadedImages; } - + void GLTexture::unprepareImpl() { mLoadedImages.setNull(); @@ -380,34 +380,34 @@ namespace Ogre { } } - //************************************************************************* + //************************************************************************* void GLTexture::freeInternalResourcesImpl() { - mSurfaceList.clear(); + mSurfaceList.clear(); glDeleteTextures( 1, &mTextureID ); - mGLSupport.getStateCacheManager()->invalidateStateForTexture( mTextureID ); + mGLSupport.getStateCacheManager()->invalidateStateForTexture( mTextureID ); } - - //--------------------------------------------------------------------------------------------- - void GLTexture::_createSurfaceList() - { - mSurfaceList.clear(); - - // For all faces and mipmaps, store surfaces as HardwarePixelBufferSharedPtr - bool wantGeneratedMips = (mUsage & TU_AUTOMIPMAP)!=0; - - // Do mipmapping in software? (uses GLU) For some cards, this is still needed. Of course, - // only when mipmap generation is desired. - bool doSoftware = wantGeneratedMips && !mMipmapsHardwareGenerated && getNumMipmaps(); - - for(GLint face=0; face(getNumFaces()); face++) - { - for(uint8 mip=0; mip<=getNumMipmaps(); mip++) - { - GLHardwarePixelBuffer *buf = new GLTextureBuffer(mGLSupport, mName, getGLTextureTarget(), mTextureID, face, mip, - static_cast(mUsage), doSoftware && mip==0, mHwGamma, mFSAA); - mSurfaceList.push_back(HardwarePixelBufferSharedPtr(buf)); + + //--------------------------------------------------------------------------------------------- + void GLTexture::_createSurfaceList() + { + mSurfaceList.clear(); + + // For all faces and mipmaps, store surfaces as HardwarePixelBufferSharedPtr + bool wantGeneratedMips = (mUsage & TU_AUTOMIPMAP)!=0; + + // Do mipmapping in software? (uses GLU) For some cards, this is still needed. Of course, + // only when mipmap generation is desired. + bool doSoftware = wantGeneratedMips && !mMipmapsHardwareGenerated && getNumMipmaps(); + + for(GLint face=0; face(getNumFaces()); face++) + { + for(uint8 mip=0; mip<=getNumMipmaps(); mip++) + { + GLHardwarePixelBuffer *buf = new GLTextureBuffer(mGLSupport, mName, getGLTextureTarget(), mTextureID, face, mip, + static_cast(mUsage), doSoftware && mip==0, mHwGamma, mFSAA); + mSurfaceList.push_back(HardwarePixelBufferSharedPtr(buf)); /// Check for error if(buf->getWidth()==0 || buf->getHeight()==0 || buf->getDepth()==0) @@ -420,29 +420,29 @@ namespace Ogre { ". Probably, the GL driver refused to create the texture.", "GLTexture::_createSurfaceList"); } - } - } - } - - //--------------------------------------------------------------------------------------------- - HardwarePixelBufferSharedPtr GLTexture::getBuffer(size_t face, size_t mipmap) - { - if(face >= getNumFaces()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Face index out of range", - "GLTexture::getBuffer"); - if(mipmap > mNumMipmaps) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range", - "GLTexture::getBuffer"); - unsigned long idx = face*(mNumMipmaps+1) + mipmap; - assert(idx < mSurfaceList.size()); - return mSurfaceList[idx]; - } - //--------------------------------------------------------------------------------------------- - void GLTexture::getCustomAttribute(const String& name, void* pData) - { - if (name == "GLID") - *static_cast(pData) = mTextureID; - } - + } + } + } + + //--------------------------------------------------------------------------------------------- + HardwarePixelBufferSharedPtr GLTexture::getBuffer(size_t face, size_t mipmap) + { + if(face >= getNumFaces()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Face index out of range", + "GLTexture::getBuffer"); + if(mipmap > mNumMipmaps) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range", + "GLTexture::getBuffer"); + unsigned long idx = face*(mNumMipmaps+1) + mipmap; + assert(idx < mSurfaceList.size()); + return mSurfaceList[idx]; + } + //--------------------------------------------------------------------------------------------- + void GLTexture::getCustomAttribute(const String& name, void* pData) + { + if (name == "GLID") + *static_cast(pData) = mTextureID; + } + } diff --git a/RenderSystems/GL/src/OgreGLTextureManager.cpp b/RenderSystems/GL/src/OgreGLTextureManager.cpp index 8216f2804e4..46d5207dff2 100644 --- a/RenderSystems/GL/src/OgreGLTextureManager.cpp +++ b/RenderSystems/GL/src/OgreGLTextureManager.cpp @@ -45,8 +45,8 @@ namespace Ogre { { // unregister with group manager ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); - // Delete warning texture - glDeleteTextures(1, &mWarningTextureID); + // Delete warning texture + glDeleteTextures(1, &mWarningTextureID); } //----------------------------------------------------------------------------- Resource* GLTextureManager::createImpl(const String& name, ResourceHandle handle, @@ -56,70 +56,70 @@ namespace Ogre { return new GLTexture(this, name, handle, group, isManual, loader, mGLSupport); } - //----------------------------------------------------------------------------- - void GLTextureManager::createWarningTexture() - { - // Generate warning texture - uint32 width = 8; - uint32 height = 8; - uint32 *data = new uint32[width*height]; // 0xXXRRGGBB - // Yellow/black stripes - for(size_t y=0; ygetCapabilities(); - // Check compressed texture support - // if a compressed format not supported, revert to PF_A8R8G8B8 - if(PixelUtil::isCompressed(format) && + // Check compressed texture support + // if a compressed format not supported, revert to PF_A8R8G8B8 + if(PixelUtil::isCompressed(format) && !caps->hasCapability( RSC_TEXTURE_COMPRESSION_DXT )) - { - return PF_A8R8G8B8; - } - // if floating point textures not supported, revert to PF_A8R8G8B8 - if(PixelUtil::isFloatingPoint(format) && + { + return PF_A8R8G8B8; + } + // if floating point textures not supported, revert to PF_A8R8G8B8 + if(PixelUtil::isFloatingPoint(format) && !caps->hasCapability( RSC_TEXTURE_FLOAT )) - { - return PF_A8R8G8B8; - } + { + return PF_A8R8G8B8; + } // Check if this is a valid rendertarget format - if( usage & TU_RENDERTARGET ) + if( usage & TU_RENDERTARGET ) { /// Get closest supported alternative /// If mFormat is supported it's returned return GLRTTManager::getSingleton().getSupportedAlternative(format); } - // Supported - return format; + // Supported + return format; - - } - //----------------------------------------------------------------------------- + + } + //----------------------------------------------------------------------------- bool GLTextureManager::isHardwareFilteringSupported(TextureType ttype, PixelFormat format, int usage, bool preciseFormatOnly) { diff --git a/RenderSystems/GL/src/SDL/OgreSDLGLSupport.cpp b/RenderSystems/GL/src/SDL/OgreSDLGLSupport.cpp index 9155e520c1c..576dfade9e1 100644 --- a/RenderSystems/GL/src/SDL/OgreSDLGLSupport.cpp +++ b/RenderSystems/GL/src/SDL/OgreSDLGLSupport.cpp @@ -31,8 +31,8 @@ void SDLGLSupport::addConfig(void) ConfigOption optFullScreen; ConfigOption optVideoMode; ConfigOption optFSAA; - ConfigOption optRTTMode; - ConfigOption optEnableFixedPipeline; + ConfigOption optRTTMode; + ConfigOption optEnableFixedPipeline; // FS setting possibilities optFullScreen.name = "Full Screen"; @@ -47,7 +47,7 @@ void SDLGLSupport::addConfig(void) for (size_t i = 0; mVideoModes[i]; i++) { char szBuf[16]; - snprintf(szBuf, 16, "%d x %d", mVideoModes[i]->w, mVideoModes[i]->h); + snprintf(szBuf, 16, "%d x %d", mVideoModes[i]->w, mVideoModes[i]->h); optVideoMode.possibleValues.push_back(szBuf); // Make the first one default if (i == 0) @@ -65,24 +65,24 @@ void SDLGLSupport::addConfig(void) optFSAA.currentValue = "0"; optFSAA.immutable = false; - optRTTMode.name = "RTT Preferred Mode"; - optRTTMode.possibleValues.push_back("FBO"); - optRTTMode.possibleValues.push_back("PBuffer"); - optRTTMode.possibleValues.push_back("Copy"); - optRTTMode.currentValue = "FBO"; - optRTTMode.immutable = false; + optRTTMode.name = "RTT Preferred Mode"; + optRTTMode.possibleValues.push_back("FBO"); + optRTTMode.possibleValues.push_back("PBuffer"); + optRTTMode.possibleValues.push_back("Copy"); + optRTTMode.currentValue = "FBO"; + optRTTMode.immutable = false; - optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; - optEnableFixedPipeline.possibleValues.push_back( "Yes" ); - optEnableFixedPipeline.possibleValues.push_back( "No" ); - optEnableFixedPipeline.currentValue = "Yes"; - optEnableFixedPipeline.immutable = false; + optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; + optEnableFixedPipeline.possibleValues.push_back( "Yes" ); + optEnableFixedPipeline.possibleValues.push_back( "No" ); + optEnableFixedPipeline.currentValue = "Yes"; + optEnableFixedPipeline.immutable = false; mOptions[optFullScreen.name] = optFullScreen; mOptions[optVideoMode.name] = optVideoMode; mOptions[optFSAA.name] = optFSAA; - mOptions[optRTTMode.name] = optRTTMode; - mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; + mOptions[optRTTMode.name] = optRTTMode; + mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; } @@ -93,7 +93,7 @@ String SDLGLSupport::validateConfig(void) RenderWindow* SDLGLSupport::createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle) { - if (autoCreateWindow) + if (autoCreateWindow) { ConfigOptionMap::iterator opt = mOptions.find("Full Screen"); if (opt == mOptions.end()) @@ -108,21 +108,21 @@ RenderWindow* SDLGLSupport::createWindow(bool autoCreateWindow, GLRenderSystem* if (pos == String::npos) OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid Video Mode provided", "SDLGLSupport::createWindow"); - // Parse FSAA config - NameValuePairList winOptions; - winOptions["title"] = windowTitle; + // Parse FSAA config + NameValuePairList winOptions; + winOptions["title"] = windowTitle; int fsaa_x_samples = 0; opt = mOptions.find("FSAA"); if(opt != mOptions.end()) { - winOptions["FSAA"] = opt->second.currentValue; + winOptions["FSAA"] = opt->second.currentValue; } - opt = mOptions.find("Fixed Pipeline Enabled"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow"); - bool enableFixedPipeline = (opt->second.currentValue == "Yes"); - renderSystem->setFixedPipelineEnabled(enableFixedPipeline); + opt = mOptions.find("Fixed Pipeline Enabled"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow"); + bool enableFixedPipeline = (opt->second.currentValue == "Yes"); + renderSystem->setFixedPipelineEnabled(enableFixedPipeline); unsigned int w = StringConverter::parseUnsignedInt(val.substr(0, pos)); unsigned int h = StringConverter::parseUnsignedInt(val.substr(pos + 1)); @@ -133,18 +133,18 @@ RenderWindow* SDLGLSupport::createWindow(bool autoCreateWindow, GLRenderSystem* else { // XXX What is the else? - return NULL; + return NULL; } } RenderWindow* SDLGLSupport::newWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) + bool fullScreen, const NameValuePairList *miscParams) { - SDLWindow* window = new SDLWindow(); - window->create(name, width, height, fullScreen, miscParams); - return window; + SDLWindow* window = new SDLWindow(); + window->create(name, width, height, fullScreen, miscParams); + return window; } void SDLGLSupport::start() diff --git a/RenderSystems/GL/src/SDL/OgreSDLWindow.cpp b/RenderSystems/GL/src/SDL/OgreSDLWindow.cpp index 63ea49dd9c5..5b4c323a655 100644 --- a/RenderSystems/GL/src/SDL/OgreSDLWindow.cpp +++ b/RenderSystems/GL/src/SDL/OgreSDLWindow.cpp @@ -67,48 +67,48 @@ namespace Ogre { } - void SDLWindow::create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) + void SDLWindow::create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams) { - int colourDepth = 32; - String title = name; - if(miscParams) - { - // Parse miscellenous parameters - NameValuePairList::const_iterator opt; - // Bit depth - opt = miscParams->find("colourDepth"); - if(opt != miscParams->end()) //check for FSAA parameter, if not ignore it... - colourDepth = StringConverter::parseUnsignedInt(opt->second); - // Full screen antialiasing - opt = miscParams->find("FSAA"); - if(opt != miscParams->end()) //check for FSAA parameter, if not ignore it... - { - size_t fsaa_x_samples = StringConverter::parseUnsignedInt(opt->second); - if(fsaa_x_samples>1) { - // If FSAA is enabled in the parameters, enable the MULTISAMPLEBUFFERS - // and set the number of samples before the render window is created. - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,fsaa_x_samples); - } - } - // Window title - opt = miscParams->find("title"); - if(opt != miscParams->end()) //check for FSAA parameter, if not ignore it... - title = opt->second; - } - + int colourDepth = 32; + String title = name; + if(miscParams) + { + // Parse miscellenous parameters + NameValuePairList::const_iterator opt; + // Bit depth + opt = miscParams->find("colourDepth"); + if(opt != miscParams->end()) //check for FSAA parameter, if not ignore it... + colourDepth = StringConverter::parseUnsignedInt(opt->second); + // Full screen antialiasing + opt = miscParams->find("FSAA"); + if(opt != miscParams->end()) //check for FSAA parameter, if not ignore it... + { + size_t fsaa_x_samples = StringConverter::parseUnsignedInt(opt->second); + if(fsaa_x_samples>1) { + // If FSAA is enabled in the parameters, enable the MULTISAMPLEBUFFERS + // and set the number of samples before the render window is created. + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,fsaa_x_samples); + } + } + // Window title + opt = miscParams->find("title"); + if(opt != miscParams->end()) //check for FSAA parameter, if not ignore it... + title = opt->second; + } + LogManager::getSingleton().logMessage("SDLWindow::create", LML_TRIVIAL); SDL_Surface* screen; int flags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE; - + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // request good stencil size if 32-bit colour if (colourDepth == 32) { SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8); } - + if (fullScreen) flags |= SDL_FULLSCREEN; @@ -167,7 +167,7 @@ namespace Ogre { { SDL_Surface* screen; int flags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE; - + LogManager::getSingleton().logMessage("Updating window", LML_TRIVIAL); screen = SDL_SetVideoMode(width, height, mScreen->format->BitsPerPixel, flags); if (!screen) @@ -191,14 +191,14 @@ namespace Ogre { } void SDLWindow::setVSyncEnabled(bool vsync) - { + { mVSync = vsync; - } + } - bool SDLWindow::isVSyncEnabled() const - { + bool SDLWindow::isVSyncEnabled() const + { return mVSync; - } + } void SDLWindow::swapBuffers() { @@ -213,50 +213,50 @@ namespace Ogre { // XXX More? } - void SDLWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) - { - if ((dst.left < 0) || (dst.right > mWidth) || - (dst.top < 0) || (dst.bottom > mHeight) || - (dst.front != 0) || (dst.back != 1)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid box.", - "SDLWindow::copyContentsToMemory" ); - } - - if (buffer == FB_AUTO) - { - buffer = mIsFullScreen? FB_FRONT : FB_BACK; - } - - GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format); - GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format); - - if ((format == GL_NONE) || (type == 0)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unsupported format.", - "SDLWindow::copyContentsToMemory" ); - } - - // Switch context if different from current one - RenderSystem* rsys = Root::getSingleton().getRenderSystem(); - rsys->_setViewport(this->getViewport(0)); - + void SDLWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) + { + if ((dst.left < 0) || (dst.right > mWidth) || + (dst.top < 0) || (dst.bottom > mHeight) || + (dst.front != 0) || (dst.back != 1)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid box.", + "SDLWindow::copyContentsToMemory" ); + } + + if (buffer == FB_AUTO) + { + buffer = mIsFullScreen? FB_FRONT : FB_BACK; + } + + GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format); + GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format); + + if ((format == GL_NONE) || (type == 0)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Unsupported format.", + "SDLWindow::copyContentsToMemory" ); + } + + // Switch context if different from current one + RenderSystem* rsys = Root::getSingleton().getRenderSystem(); + rsys->_setViewport(this->getViewport(0)); + if(dst.getWidth() != dst.rowPitch) glPixelStorei(GL_PACK_ROW_LENGTH, dst.rowPitch); - // Must change the packing to ensure no overruns! - glPixelStorei(GL_PACK_ALIGNMENT, 1); - - glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); + // Must change the packing to ensure no overruns! + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); glReadPixels((GLint)0, (GLint)(mHeight - dst.getHeight()), (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(), format, type, dst.getTopLeftFrontPixelPtr()); - - // restore default alignment - glPixelStorei(GL_PACK_ALIGNMENT, 4); + + // restore default alignment + glPixelStorei(GL_PACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ROW_LENGTH, 0); PixelUtil::bulkPixelVerticalFlip(dst); - } + } } diff --git a/RenderSystems/GL/src/StateCacheManager/OgreGLNullStateCacheManagerImp.cpp b/RenderSystems/GL/src/StateCacheManager/OgreGLNullStateCacheManagerImp.cpp index b6bec82ce5a..e4fe9ad7315 100644 --- a/RenderSystems/GL/src/StateCacheManager/OgreGLNullStateCacheManagerImp.cpp +++ b/RenderSystems/GL/src/StateCacheManager/OgreGLNullStateCacheManagerImp.cpp @@ -91,7 +91,7 @@ namespace Ogre { mBlendFuncSource = GL_ONE; mBlendFuncDest = GL_ZERO; - mClearColour.resize(4); + mClearColour.resize(4); mClearColour[0] = mClearColour[1] = mClearColour[2] = mClearColour[3] = 0.0f; mColourMask.resize(4); @@ -193,7 +193,7 @@ namespace Ogre { } bool GLStateCacheManagerImp::activateGLTextureUnit(size_t unit) - { + { // Always return true for the currently bound texture unit if (mActiveTextureUnit == unit) return true; @@ -210,7 +210,7 @@ namespace Ogre { { return false; } - } + } void GLStateCacheManagerImp::setBlendFunc(GLenum source, GLenum dest) { @@ -339,14 +339,14 @@ namespace Ogre { mBlendEquationRGB = eqRGB; mBlendEquationAlpha = eqAlpha; - if(GLEW_VERSION_2_0) { - glBlendEquationSeparate(eqRGB, eqAlpha); - } - else if(GLEW_EXT_blend_equation_separate) { - glBlendEquationSeparateEXT(eqRGB, eqAlpha); - } - } - } + if(GLEW_VERSION_2_0) { + glBlendEquationSeparate(eqRGB, eqAlpha); + } + else if(GLEW_EXT_blend_equation_separate) { + glBlendEquationSeparateEXT(eqRGB, eqAlpha); + } + } + } void GLStateCacheManagerImp::setMaterialDiffuse(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { diff --git a/RenderSystems/GL/src/StateCacheManager/OgreGLNullStateCacheManagerImp.h b/RenderSystems/GL/src/StateCacheManager/OgreGLNullStateCacheManagerImp.h index 195f6ea5b62..b9bb7b8b529 100644 --- a/RenderSystems/GL/src/StateCacheManager/OgreGLNullStateCacheManagerImp.h +++ b/RenderSystems/GL/src/StateCacheManager/OgreGLNullStateCacheManagerImp.h @@ -95,7 +95,7 @@ namespace Ogre /// See GLStateCacheManager.clearCache. void clearCache(); - + /// See GLStateCacheManager.bindGLBuffer. void bindGLBuffer(GLenum target, GLuint buffer, bool force = false); diff --git a/RenderSystems/GL/src/StateCacheManager/OgreGLStateCacheManagerImp.cpp b/RenderSystems/GL/src/StateCacheManager/OgreGLStateCacheManagerImp.cpp index c2e2f8786b5..cdfc3614c96 100644 --- a/RenderSystems/GL/src/StateCacheManager/OgreGLStateCacheManagerImp.cpp +++ b/RenderSystems/GL/src/StateCacheManager/OgreGLStateCacheManagerImp.cpp @@ -169,23 +169,23 @@ namespace Ogre { void GLStateCacheManagerImp::bindGLBuffer(GLenum target, GLuint buffer, GLenum attach, bool force) { - bool update = false; + bool update = false; BindBufferMap::iterator i = mActiveBufferMap.find(target); if (i == mActiveBufferMap.end()) { // Haven't cached this state yet. Insert it into the map mActiveBufferMap.insert(BindBufferMap::value_type(target, buffer)); - update = true; + update = true; } else if((*i).second != buffer || force) // Update the cached value if needed { - (*i).second = buffer; - update = true; + (*i).second = buffer; + update = true; } - // Update GL - if(update) - { + // Update GL + if(update) + { if(target == GL_FRAMEBUFFER) { glBindFramebuffer(target, buffer); @@ -198,7 +198,7 @@ namespace Ogre { { glBindBuffer(target, buffer); } - } + } } @@ -212,17 +212,17 @@ namespace Ogre { if (i != mActiveBufferMap.end() && ((*i).second == buffer || force)) { - if(target == GL_FRAMEBUFFER) + if(target == GL_FRAMEBUFFER) { - glDeleteFramebuffers(1, &buffer); + glDeleteFramebuffers(1, &buffer); } else if(target == GL_RENDERBUFFER) { - glDeleteRenderbuffers(1, &buffer); + glDeleteRenderbuffers(1, &buffer); } else { - glDeleteBuffers(1, &buffer); + glDeleteBuffers(1, &buffer); } // Currently bound buffer is being deleted, update the cached value to 0, @@ -285,30 +285,30 @@ namespace Ogre { } bool GLStateCacheManagerImp::activateGLTextureUnit(size_t unit) - { - if (mActiveTextureUnit != unit) - { - if (unit < dynamic_cast(Root::getSingleton().getRenderSystem())->getCapabilities()->getNumTextureUnits()) - { - glActiveTexture(GL_TEXTURE0 + unit); - mActiveTextureUnit = unit; - return true; - } - else if (!unit) - { - // always ok to use the first unit - return true; - } - else - { - return false; - } - } - else - { - return true; - } - } + { + if (mActiveTextureUnit != unit) + { + if (unit < dynamic_cast(Root::getSingleton().getRenderSystem())->getCapabilities()->getNumTextureUnits()) + { + glActiveTexture(GL_TEXTURE0 + unit); + mActiveTextureUnit = unit; + return true; + } + else if (!unit) + { + // always ok to use the first unit + return true; + } + else + { + return false; + } + } + else + { + return true; + } + } // TODO: Store as high/low bits of a GLuint void GLStateCacheManagerImp::setBlendFunc(GLenum source, GLenum dest) @@ -462,16 +462,16 @@ namespace Ogre { mBlendEquationRGB = eqRGB; mBlendEquationAlpha = eqAlpha; - if(GLEW_VERSION_2_0) + if(GLEW_VERSION_2_0) { - glBlendEquationSeparate(eqRGB, eqAlpha); - } - else if(GLEW_EXT_blend_equation_separate) + glBlendEquationSeparate(eqRGB, eqAlpha); + } + else if(GLEW_EXT_blend_equation_separate) { - glBlendEquationSeparateEXT(eqRGB, eqAlpha); - } - } - } + glBlendEquationSeparateEXT(eqRGB, eqAlpha); + } + } + } void GLStateCacheManagerImp::setMaterialDiffuse(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { diff --git a/RenderSystems/GL/src/StateCacheManager/OgreGLStateCacheManagerImp.h b/RenderSystems/GL/src/StateCacheManager/OgreGLStateCacheManagerImp.h index 1a2e71b7589..2b8bfb454a5 100644 --- a/RenderSystems/GL/src/StateCacheManager/OgreGLStateCacheManagerImp.h +++ b/RenderSystems/GL/src/StateCacheManager/OgreGLStateCacheManagerImp.h @@ -98,7 +98,7 @@ namespace Ogre GLenum mDepthFunc; /// Stores the current stencil mask GLuint mStencilMask; - /// Stores the last bound texture id + /// Stores the last bound texture id GLuint mLastBoundTexID; /// Stores the currently active texture unit size_t mActiveTextureUnit; @@ -134,7 +134,7 @@ namespace Ogre /// See GLStateCacheManager.clearCache. void clearCache(); - + /// See GLStateCacheManager.bindGLBuffer. void bindGLBuffer(GLenum target, GLuint buffer, GLenum attach = 0, bool force = false); diff --git a/RenderSystems/GL/src/StateCacheManager/OgreGLUniformCacheImp.cpp b/RenderSystems/GL/src/StateCacheManager/OgreGLUniformCacheImp.cpp index ada77d96673..2ccf61e69b5 100644 --- a/RenderSystems/GL/src/StateCacheManager/OgreGLUniformCacheImp.cpp +++ b/RenderSystems/GL/src/StateCacheManager/OgreGLUniformCacheImp.cpp @@ -56,7 +56,7 @@ namespace Ogre { { // Haven't cached this state yet or the value has changed mUniformValueMap[location] = hash; - return true; + return true; } return false; diff --git a/RenderSystems/GL/src/StateCacheManager/OgreGLUniformCacheImp.h b/RenderSystems/GL/src/StateCacheManager/OgreGLUniformCacheImp.h index d5b68b18a0a..491ac86feae 100644 --- a/RenderSystems/GL/src/StateCacheManager/OgreGLUniformCacheImp.h +++ b/RenderSystems/GL/src/StateCacheManager/OgreGLUniformCacheImp.h @@ -52,7 +52,7 @@ namespace Ogre /// Clear out the cache void clearCache(); - + /** Update a uniform @return A boolean value indicating whether this uniform needs to be updated in the GL. */ diff --git a/RenderSystems/GL/src/Win32/OgreWin32Context.cpp b/RenderSystems/GL/src/Win32/OgreWin32Context.cpp index 064d24282e5..e306309e0eb 100644 --- a/RenderSystems/GL/src/Win32/OgreWin32Context.cpp +++ b/RenderSystems/GL/src/Win32/OgreWin32Context.cpp @@ -45,63 +45,63 @@ namespace Ogre { Win32Context::~Win32Context() { - // NB have to do this is subclass to ensure any methods called back - // are on this subclass and not half-destructed superclass - GLRenderSystem *rs = static_cast(Root::getSingleton().getRenderSystem()); - rs->_unregisterContext(this); + // NB have to do this is subclass to ensure any methods called back + // are on this subclass and not half-destructed superclass + GLRenderSystem *rs = static_cast(Root::getSingleton().getRenderSystem()); + rs->_unregisterContext(this); } void Win32Context::setCurrent() { wglMakeCurrent(mHDC, mGlrc); } - void Win32Context::endCurrent() - { - wglMakeCurrent(NULL, NULL); - } - - GLContext* Win32Context::clone() const - { - // Create new context based on own HDC - HGLRC newCtx = wglCreateContext(mHDC); - - if (!newCtx) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Error calling wglCreateContext", "Win32Context::clone"); - } - - HGLRC oldrc = wglGetCurrentContext(); - HDC oldhdc = wglGetCurrentDC(); - wglMakeCurrent(NULL, NULL); - // Share lists with old context - if (!wglShareLists(mGlrc, newCtx)) - { - String errorMsg = translateWGLError(); - wglDeleteContext(newCtx); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, String("wglShareLists() failed: ") + errorMsg, "Win32Context::clone"); - } - // restore old context - wglMakeCurrent(oldhdc, oldrc); - - - return new Win32Context(mHDC, newCtx); - } - - void Win32Context::releaseContext() - { - if (mGlrc != NULL) - { - wglDeleteContext(mGlrc); - mGlrc = NULL; - mHDC = NULL; - } - } - - HGLRC Win32Context::getGlrc() const - { - return mGlrc; - } + void Win32Context::endCurrent() + { + wglMakeCurrent(NULL, NULL); + } + + GLContext* Win32Context::clone() const + { + // Create new context based on own HDC + HGLRC newCtx = wglCreateContext(mHDC); + + if (!newCtx) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Error calling wglCreateContext", "Win32Context::clone"); + } + + HGLRC oldrc = wglGetCurrentContext(); + HDC oldhdc = wglGetCurrentDC(); + wglMakeCurrent(NULL, NULL); + // Share lists with old context + if (!wglShareLists(mGlrc, newCtx)) + { + String errorMsg = translateWGLError(); + wglDeleteContext(newCtx); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, String("wglShareLists() failed: ") + errorMsg, "Win32Context::clone"); + } + // restore old context + wglMakeCurrent(oldhdc, oldrc); + + + return new Win32Context(mHDC, newCtx); + } + + void Win32Context::releaseContext() + { + if (mGlrc != NULL) + { + wglDeleteContext(mGlrc); + mGlrc = NULL; + mHDC = NULL; + } + } + + HGLRC Win32Context::getGlrc() const + { + return mGlrc; + } } #if OGRE_THREAD_SUPPORT == 1 @@ -109,19 +109,19 @@ namespace Ogre { // declared in OgreGLPrerequisites.h WGLEWContext * wglewGetContext() { - using namespace Ogre; - static OGRE_THREAD_POINTER_VAR(WGLEWContext, WGLEWContextsPtr); - - WGLEWContext * currentWGLEWContextsPtr = OGRE_THREAD_POINTER_GET(WGLEWContextsPtr); - if (currentWGLEWContextsPtr == NULL) - { - currentWGLEWContextsPtr = new WGLEWContext(); - OGRE_THREAD_POINTER_SET(WGLEWContextsPtr, currentWGLEWContextsPtr); - ZeroMemory(currentWGLEWContextsPtr, sizeof(WGLEWContext)); - wglewInit(); - - } - return currentWGLEWContextsPtr; + using namespace Ogre; + static OGRE_THREAD_POINTER_VAR(WGLEWContext, WGLEWContextsPtr); + + WGLEWContext * currentWGLEWContextsPtr = OGRE_THREAD_POINTER_GET(WGLEWContextsPtr); + if (currentWGLEWContextsPtr == NULL) + { + currentWGLEWContextsPtr = new WGLEWContext(); + OGRE_THREAD_POINTER_SET(WGLEWContextsPtr, currentWGLEWContextsPtr); + ZeroMemory(currentWGLEWContextsPtr, sizeof(WGLEWContext)); + wglewInit(); + + } + return currentWGLEWContextsPtr; } #endif \ No newline at end of file diff --git a/RenderSystems/GL/src/Win32/OgreWin32GLSupport.cpp b/RenderSystems/GL/src/Win32/OgreWin32GLSupport.cpp index 5e205d5e706..3557c160c35 100644 --- a/RenderSystems/GL/src/Win32/OgreWin32GLSupport.cpp +++ b/RenderSystems/GL/src/Win32/OgreWin32GLSupport.cpp @@ -45,220 +45,220 @@ GLenum GLEWAPIENTRY wglewContextInit (Ogre::GLSupport *glSupport); #endif namespace Ogre { - Win32GLSupport::Win32GLSupport() + Win32GLSupport::Win32GLSupport() : mInitialWindow(0) , mHasPixelFormatARB(false) , mHasMultisample(false) - , mHasHardwareGamma(false) + , mHasHardwareGamma(false) { - // immediately test WGL_ARB_pixel_format and FSAA support - // so we can set configuration options appropriately - initialiseWGL(); + // immediately test WGL_ARB_pixel_format and FSAA support + // so we can set configuration options appropriately + initialiseWGL(); } - template void remove_duplicates(C& c) - { - std::sort(c.begin(), c.end()); - typename C::iterator p = std::unique(c.begin(), c.end()); - c.erase(p, c.end()); - } - - void Win32GLSupport::addConfig() - { - //TODO: EnumDisplayDevices http://msdn.microsoft.com/library/en-us/gdi/devcons_2303.asp - /*vector DisplayDevices; - DISPLAY_DEVICE DisplayDevice; - DisplayDevice.cb = sizeof(DISPLAY_DEVICE); - DWORD i=0; - while (EnumDisplayDevices(NULL, i++, &DisplayDevice, 0) { - DisplayDevices.push_back(DisplayDevice.DeviceName); - }*/ - - ConfigOption optFullScreen; - ConfigOption optVideoMode; - ConfigOption optColourDepth; - ConfigOption optDisplayFrequency; - ConfigOption optVSync; - ConfigOption optVSyncInterval; - ConfigOption optFSAA; - ConfigOption optRTTMode; - ConfigOption optSRGB; - ConfigOption optEnableFixedPipeline; - - // FS setting possibilities - optFullScreen.name = "Full Screen"; - optFullScreen.possibleValues.push_back("Yes"); - optFullScreen.possibleValues.push_back("No"); - optFullScreen.currentValue = "Yes"; - optFullScreen.immutable = false; - - // Video mode possibilities - DEVMODE DevMode; - DevMode.dmSize = sizeof(DEVMODE); - optVideoMode.name = "Video Mode"; - optVideoMode.immutable = false; - for (DWORD i = 0; EnumDisplaySettings(NULL, i, &DevMode); ++i) - { - if (DevMode.dmBitsPerPel < 16 || DevMode.dmPelsHeight < 480) - continue; - mDevModes.push_back(DevMode); - StringStream str; - str << DevMode.dmPelsWidth << " x " << DevMode.dmPelsHeight; - optVideoMode.possibleValues.push_back(str.str()); - } - remove_duplicates(optVideoMode.possibleValues); - optVideoMode.currentValue = optVideoMode.possibleValues.front(); - - optColourDepth.name = "Colour Depth"; - optColourDepth.immutable = false; - optColourDepth.currentValue.clear(); - - optDisplayFrequency.name = "Display Frequency"; - optDisplayFrequency.immutable = false; + template void remove_duplicates(C& c) + { + std::sort(c.begin(), c.end()); + typename C::iterator p = std::unique(c.begin(), c.end()); + c.erase(p, c.end()); + } + + void Win32GLSupport::addConfig() + { + //TODO: EnumDisplayDevices http://msdn.microsoft.com/library/en-us/gdi/devcons_2303.asp + /*vector DisplayDevices; + DISPLAY_DEVICE DisplayDevice; + DisplayDevice.cb = sizeof(DISPLAY_DEVICE); + DWORD i=0; + while (EnumDisplayDevices(NULL, i++, &DisplayDevice, 0) { + DisplayDevices.push_back(DisplayDevice.DeviceName); + }*/ + + ConfigOption optFullScreen; + ConfigOption optVideoMode; + ConfigOption optColourDepth; + ConfigOption optDisplayFrequency; + ConfigOption optVSync; + ConfigOption optVSyncInterval; + ConfigOption optFSAA; + ConfigOption optRTTMode; + ConfigOption optSRGB; + ConfigOption optEnableFixedPipeline; + + // FS setting possibilities + optFullScreen.name = "Full Screen"; + optFullScreen.possibleValues.push_back("Yes"); + optFullScreen.possibleValues.push_back("No"); + optFullScreen.currentValue = "Yes"; + optFullScreen.immutable = false; + + // Video mode possibilities + DEVMODE DevMode; + DevMode.dmSize = sizeof(DEVMODE); + optVideoMode.name = "Video Mode"; + optVideoMode.immutable = false; + for (DWORD i = 0; EnumDisplaySettings(NULL, i, &DevMode); ++i) + { + if (DevMode.dmBitsPerPel < 16 || DevMode.dmPelsHeight < 480) + continue; + mDevModes.push_back(DevMode); + StringStream str; + str << DevMode.dmPelsWidth << " x " << DevMode.dmPelsHeight; + optVideoMode.possibleValues.push_back(str.str()); + } + remove_duplicates(optVideoMode.possibleValues); + optVideoMode.currentValue = optVideoMode.possibleValues.front(); + + optColourDepth.name = "Colour Depth"; + optColourDepth.immutable = false; + optColourDepth.currentValue.clear(); + + optDisplayFrequency.name = "Display Frequency"; + optDisplayFrequency.immutable = false; optDisplayFrequency.currentValue.clear(); - optVSync.name = "VSync"; - optVSync.immutable = false; - optVSync.possibleValues.push_back("No"); - optVSync.possibleValues.push_back("Yes"); - optVSync.currentValue = "No"; - - optVSyncInterval.name = "VSync Interval"; - optVSyncInterval.immutable = false; - optVSyncInterval.possibleValues.push_back( "1" ); - optVSyncInterval.possibleValues.push_back( "2" ); - optVSyncInterval.possibleValues.push_back( "3" ); - optVSyncInterval.possibleValues.push_back( "4" ); - optVSyncInterval.currentValue = "1"; - - optFSAA.name = "FSAA"; - optFSAA.immutable = false; - optFSAA.possibleValues.push_back("0"); - for (vector::type::iterator it = mFSAALevels.begin(); it != mFSAALevels.end(); ++it) - { - String val = StringConverter::toString(*it); - optFSAA.possibleValues.push_back(val); - /* not implementing CSAA in GL for now - if (*it >= 8) - optFSAA.possibleValues.push_back(val + " [Quality]"); - */ - - } - optFSAA.currentValue = "0"; - - optRTTMode.name = "RTT Preferred Mode"; - optRTTMode.possibleValues.push_back("FBO"); - optRTTMode.possibleValues.push_back("PBuffer"); - optRTTMode.possibleValues.push_back("Copy"); - optRTTMode.currentValue = "FBO"; - optRTTMode.immutable = false; - - - // SRGB on auto window - optSRGB.name = "sRGB Gamma Conversion"; - optSRGB.possibleValues.push_back("Yes"); - optSRGB.possibleValues.push_back("No"); - optSRGB.currentValue = "No"; - optSRGB.immutable = false; - - optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; - optEnableFixedPipeline.possibleValues.push_back( "Yes" ); - optEnableFixedPipeline.possibleValues.push_back( "No" ); - optEnableFixedPipeline.currentValue = "Yes"; - optEnableFixedPipeline.immutable = false; - - mOptions[optFullScreen.name] = optFullScreen; - mOptions[optVideoMode.name] = optVideoMode; - mOptions[optColourDepth.name] = optColourDepth; - mOptions[optDisplayFrequency.name] = optDisplayFrequency; - mOptions[optVSync.name] = optVSync; - mOptions[optVSyncInterval.name] = optVSyncInterval; - mOptions[optFSAA.name] = optFSAA; - mOptions[optRTTMode.name] = optRTTMode; - mOptions[optSRGB.name] = optSRGB; - mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; - - refreshConfig(); - } - - void Win32GLSupport::refreshConfig() - { - ConfigOptionMap::iterator optVideoMode = mOptions.find("Video Mode"); - ConfigOptionMap::iterator moptColourDepth = mOptions.find("Colour Depth"); - ConfigOptionMap::iterator moptDisplayFrequency = mOptions.find("Display Frequency"); - if(optVideoMode == mOptions.end() || moptColourDepth == mOptions.end() || moptDisplayFrequency == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find mOptions!", "Win32GLSupport::refreshConfig"); - ConfigOption* optColourDepth = &moptColourDepth->second; - ConfigOption* optDisplayFrequency = &moptDisplayFrequency->second; - - const String& val = optVideoMode->second.currentValue; - String::size_type pos = val.find('x'); - if (pos == String::npos) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid Video Mode provided", "Win32GLSupport::refreshConfig"); - DWORD width = StringConverter::parseUnsignedInt(val.substr(0, pos)); - DWORD height = StringConverter::parseUnsignedInt(val.substr(pos+1, String::npos)); - - for(vector::type::const_iterator i = mDevModes.begin(); i != mDevModes.end(); ++i) - { - if (i->dmPelsWidth != width || i->dmPelsHeight != height) - continue; - optColourDepth->possibleValues.push_back(StringConverter::toString((unsigned int)i->dmBitsPerPel)); - optDisplayFrequency->possibleValues.push_back(StringConverter::toString((unsigned int)i->dmDisplayFrequency)); - } - remove_duplicates(optColourDepth->possibleValues); - remove_duplicates(optDisplayFrequency->possibleValues); - optColourDepth->currentValue = optColourDepth->possibleValues.back(); - bool freqValid = std::find(optDisplayFrequency->possibleValues.begin(), - optDisplayFrequency->possibleValues.end(), - optDisplayFrequency->currentValue) != optDisplayFrequency->possibleValues.end(); - - if ( (optDisplayFrequency->currentValue != "N/A") && !freqValid ) - optDisplayFrequency->currentValue = optDisplayFrequency->possibleValues.front(); - } - - void Win32GLSupport::setConfigOption(const String &name, const String &value) - { - ConfigOptionMap::iterator it = mOptions.find(name); - - // Update - if(it != mOptions.end()) - it->second.currentValue = value; - else - { + optVSync.name = "VSync"; + optVSync.immutable = false; + optVSync.possibleValues.push_back("No"); + optVSync.possibleValues.push_back("Yes"); + optVSync.currentValue = "No"; + + optVSyncInterval.name = "VSync Interval"; + optVSyncInterval.immutable = false; + optVSyncInterval.possibleValues.push_back( "1" ); + optVSyncInterval.possibleValues.push_back( "2" ); + optVSyncInterval.possibleValues.push_back( "3" ); + optVSyncInterval.possibleValues.push_back( "4" ); + optVSyncInterval.currentValue = "1"; + + optFSAA.name = "FSAA"; + optFSAA.immutable = false; + optFSAA.possibleValues.push_back("0"); + for (vector::type::iterator it = mFSAALevels.begin(); it != mFSAALevels.end(); ++it) + { + String val = StringConverter::toString(*it); + optFSAA.possibleValues.push_back(val); + /* not implementing CSAA in GL for now + if (*it >= 8) + optFSAA.possibleValues.push_back(val + " [Quality]"); + */ + + } + optFSAA.currentValue = "0"; + + optRTTMode.name = "RTT Preferred Mode"; + optRTTMode.possibleValues.push_back("FBO"); + optRTTMode.possibleValues.push_back("PBuffer"); + optRTTMode.possibleValues.push_back("Copy"); + optRTTMode.currentValue = "FBO"; + optRTTMode.immutable = false; + + + // SRGB on auto window + optSRGB.name = "sRGB Gamma Conversion"; + optSRGB.possibleValues.push_back("Yes"); + optSRGB.possibleValues.push_back("No"); + optSRGB.currentValue = "No"; + optSRGB.immutable = false; + + optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; + optEnableFixedPipeline.possibleValues.push_back( "Yes" ); + optEnableFixedPipeline.possibleValues.push_back( "No" ); + optEnableFixedPipeline.currentValue = "Yes"; + optEnableFixedPipeline.immutable = false; + + mOptions[optFullScreen.name] = optFullScreen; + mOptions[optVideoMode.name] = optVideoMode; + mOptions[optColourDepth.name] = optColourDepth; + mOptions[optDisplayFrequency.name] = optDisplayFrequency; + mOptions[optVSync.name] = optVSync; + mOptions[optVSyncInterval.name] = optVSyncInterval; + mOptions[optFSAA.name] = optFSAA; + mOptions[optRTTMode.name] = optRTTMode; + mOptions[optSRGB.name] = optSRGB; + mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; + + refreshConfig(); + } + + void Win32GLSupport::refreshConfig() + { + ConfigOptionMap::iterator optVideoMode = mOptions.find("Video Mode"); + ConfigOptionMap::iterator moptColourDepth = mOptions.find("Colour Depth"); + ConfigOptionMap::iterator moptDisplayFrequency = mOptions.find("Display Frequency"); + if(optVideoMode == mOptions.end() || moptColourDepth == mOptions.end() || moptDisplayFrequency == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find mOptions!", "Win32GLSupport::refreshConfig"); + ConfigOption* optColourDepth = &moptColourDepth->second; + ConfigOption* optDisplayFrequency = &moptDisplayFrequency->second; + + const String& val = optVideoMode->second.currentValue; + String::size_type pos = val.find('x'); + if (pos == String::npos) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid Video Mode provided", "Win32GLSupport::refreshConfig"); + DWORD width = StringConverter::parseUnsignedInt(val.substr(0, pos)); + DWORD height = StringConverter::parseUnsignedInt(val.substr(pos+1, String::npos)); + + for(vector::type::const_iterator i = mDevModes.begin(); i != mDevModes.end(); ++i) + { + if (i->dmPelsWidth != width || i->dmPelsHeight != height) + continue; + optColourDepth->possibleValues.push_back(StringConverter::toString((unsigned int)i->dmBitsPerPel)); + optDisplayFrequency->possibleValues.push_back(StringConverter::toString((unsigned int)i->dmDisplayFrequency)); + } + remove_duplicates(optColourDepth->possibleValues); + remove_duplicates(optDisplayFrequency->possibleValues); + optColourDepth->currentValue = optColourDepth->possibleValues.back(); + bool freqValid = std::find(optDisplayFrequency->possibleValues.begin(), + optDisplayFrequency->possibleValues.end(), + optDisplayFrequency->currentValue) != optDisplayFrequency->possibleValues.end(); + + if ( (optDisplayFrequency->currentValue != "N/A") && !freqValid ) + optDisplayFrequency->currentValue = optDisplayFrequency->possibleValues.front(); + } + + void Win32GLSupport::setConfigOption(const String &name, const String &value) + { + ConfigOptionMap::iterator it = mOptions.find(name); + + // Update + if(it != mOptions.end()) + it->second.currentValue = value; + else + { StringStream str; str << "Option named '" << name << "' does not exist."; - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, str.str(), "Win32GLSupport::setConfigOption" ); - } - - if( name == "Video Mode" ) - refreshConfig(); - - if( name == "Full Screen" ) - { - it = mOptions.find( "Display Frequency" ); - if( value == "No" ) - { - it->second.currentValue = "N/A"; - it->second.immutable = true; - } - else - { - if (it->second.currentValue.empty() || it->second.currentValue == "N/A") - it->second.currentValue = it->second.possibleValues.front(); - it->second.immutable = false; - } - } - } - - String Win32GLSupport::validateConfig() - { - // TODO, DX9 - return BLANKSTRING; - } - - RenderWindow* Win32GLSupport::createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle) - { - if (autoCreateWindow) + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, str.str(), "Win32GLSupport::setConfigOption" ); + } + + if( name == "Video Mode" ) + refreshConfig(); + + if( name == "Full Screen" ) + { + it = mOptions.find( "Display Frequency" ); + if( value == "No" ) + { + it->second.currentValue = "N/A"; + it->second.immutable = true; + } + else + { + if (it->second.currentValue.empty() || it->second.currentValue == "N/A") + it->second.currentValue = it->second.possibleValues.front(); + it->second.immutable = false; + } + } + } + + String Win32GLSupport::validateConfig() + { + // TODO, DX9 + return BLANKSTRING; + } + + RenderWindow* Win32GLSupport::createWindow(bool autoCreateWindow, GLRenderSystem* renderSystem, const String& windowTitle) + { + if (autoCreateWindow) { ConfigOptionMap::iterator opt = mOptions.find("Full Screen"); if (opt == mOptions.end()) @@ -273,307 +273,307 @@ namespace Ogre { if (pos == String::npos) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid Video Mode provided", "Win32GLSupport::createWindow"); - unsigned int w = StringConverter::parseUnsignedInt(val.substr(0, pos)); + unsigned int w = StringConverter::parseUnsignedInt(val.substr(0, pos)); unsigned int h = StringConverter::parseUnsignedInt(val.substr(pos + 1)); - // Parse optional parameters - NameValuePairList winOptions; - opt = mOptions.find("Colour Depth"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Colour Depth options!", "Win32GLSupport::createWindow"); - unsigned int colourDepth = - StringConverter::parseUnsignedInt(opt->second.currentValue); - winOptions["colourDepth"] = StringConverter::toString(colourDepth); - - opt = mOptions.find("VSync"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync options!", "Win32GLSupport::createWindow"); - bool vsync = (opt->second.currentValue == "Yes"); - winOptions["vsync"] = StringConverter::toString(vsync); - - opt = mOptions.find("VSync Interval"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync Interval options!", "Win32GLSupport::createWindow"); - winOptions["vsyncInterval"] = opt->second.currentValue; - - opt = mOptions.find("Display Frequency"); - if (opt != mOptions.end()) - { - unsigned int displayFrequency = - StringConverter::parseUnsignedInt(opt->second.currentValue); - winOptions["displayFrequency"] = StringConverter::toString(displayFrequency); - } - - opt = mOptions.find("FSAA"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find FSAA options!", "Win32GLSupport::createWindow"); - StringVector aavalues = StringUtil::split(opt->second.currentValue, " ", 1); - unsigned int multisample = StringConverter::parseUnsignedInt(aavalues[0]); - String multisample_hint; - if (aavalues.size() > 1) - multisample_hint = aavalues[1]; - - opt = mOptions.find("Fixed Pipeline Enabled"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow"); - bool enableFixedPipeline = (opt->second.currentValue == "Yes"); - renderSystem->setFixedPipelineEnabled(enableFixedPipeline); - - winOptions["FSAA"] = StringConverter::toString(multisample); - winOptions["FSAAHint"] = multisample_hint; - - opt = mOptions.find("sRGB Gamma Conversion"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find sRGB options!", "Win32GLSupport::createWindow"); - bool hwGamma = (opt->second.currentValue == "Yes"); - winOptions["gamma"] = StringConverter::toString(hwGamma); + // Parse optional parameters + NameValuePairList winOptions; + opt = mOptions.find("Colour Depth"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Colour Depth options!", "Win32GLSupport::createWindow"); + unsigned int colourDepth = + StringConverter::parseUnsignedInt(opt->second.currentValue); + winOptions["colourDepth"] = StringConverter::toString(colourDepth); + + opt = mOptions.find("VSync"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync options!", "Win32GLSupport::createWindow"); + bool vsync = (opt->second.currentValue == "Yes"); + winOptions["vsync"] = StringConverter::toString(vsync); + + opt = mOptions.find("VSync Interval"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync Interval options!", "Win32GLSupport::createWindow"); + winOptions["vsyncInterval"] = opt->second.currentValue; + + opt = mOptions.find("Display Frequency"); + if (opt != mOptions.end()) + { + unsigned int displayFrequency = + StringConverter::parseUnsignedInt(opt->second.currentValue); + winOptions["displayFrequency"] = StringConverter::toString(displayFrequency); + } + + opt = mOptions.find("FSAA"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find FSAA options!", "Win32GLSupport::createWindow"); + StringVector aavalues = StringUtil::split(opt->second.currentValue, " ", 1); + unsigned int multisample = StringConverter::parseUnsignedInt(aavalues[0]); + String multisample_hint; + if (aavalues.size() > 1) + multisample_hint = aavalues[1]; + + opt = mOptions.find("Fixed Pipeline Enabled"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow"); + bool enableFixedPipeline = (opt->second.currentValue == "Yes"); + renderSystem->setFixedPipelineEnabled(enableFixedPipeline); + + winOptions["FSAA"] = StringConverter::toString(multisample); + winOptions["FSAAHint"] = multisample_hint; + + opt = mOptions.find("sRGB Gamma Conversion"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find sRGB options!", "Win32GLSupport::createWindow"); + bool hwGamma = (opt->second.currentValue == "Yes"); + winOptions["gamma"] = StringConverter::toString(hwGamma); return renderSystem->_createRenderWindow(windowTitle, w, h, fullscreen, &winOptions); } else { // XXX What is the else? - return NULL; + return NULL; } - } - - BOOL CALLBACK Win32GLSupport::sCreateMonitorsInfoEnumProc( - HMONITOR hMonitor, // handle to display monitor - HDC hdcMonitor, // handle to monitor DC - LPRECT lprcMonitor, // monitor intersection rectangle - LPARAM dwData // data - ) - { - DisplayMonitorInfoList* pArrMonitorsInfo = (DisplayMonitorInfoList*)dwData; - - // Get monitor info - DisplayMonitorInfo displayMonitorInfo; - - displayMonitorInfo.hMonitor = hMonitor; - - memset(&displayMonitorInfo.monitorInfoEx, 0, sizeof(MONITORINFOEX)); - displayMonitorInfo.monitorInfoEx.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(hMonitor, &displayMonitorInfo.monitorInfoEx); - - pArrMonitorsInfo->push_back(displayMonitorInfo); - - return TRUE; - } - - - RenderWindow* Win32GLSupport::newWindow(const String &name, unsigned int width, - unsigned int height, bool fullScreen, const NameValuePairList *miscParams) - { - Win32Window* window = new Win32Window(*this); - NameValuePairList newParams; - - if (miscParams != NULL) - { - newParams = *miscParams; - miscParams = &newParams; - - NameValuePairList::const_iterator monitorIndexIt = miscParams->find("monitorIndex"); - HMONITOR hMonitor = NULL; - int monitorIndex = -1; - - // If monitor index found, try to assign the monitor handle based on it. - if (monitorIndexIt != miscParams->end()) - { - if (mMonitorInfoList.empty()) - EnumDisplayMonitors(NULL, NULL, sCreateMonitorsInfoEnumProc, (LPARAM)&mMonitorInfoList); - - monitorIndex = StringConverter::parseInt(monitorIndexIt->second); - if (monitorIndex < (int)mMonitorInfoList.size()) - { - hMonitor = mMonitorInfoList[monitorIndex].hMonitor; - } - } - // If we didn't specified the monitor index, or if it didn't find it - if (hMonitor == NULL) - { - POINT windowAnchorPoint; - - NameValuePairList::const_iterator opt; - int left = -1; - int top = -1; - - if ((opt = newParams.find("left")) != newParams.end()) - left = StringConverter::parseInt(opt->second); - - if ((opt = newParams.find("top")) != newParams.end()) - top = StringConverter::parseInt(opt->second); - - // Fill in anchor point. - windowAnchorPoint.x = left; - windowAnchorPoint.y = top; - - - // Get the nearest monitor to this window. - hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY); - } - - newParams["monitorHandle"] = StringConverter::toString((size_t)hMonitor); - } - - window->create(name, width, height, fullScreen, miscParams); - - if(!mInitialWindow) - mInitialWindow = window; - return window; - } - - void Win32GLSupport::start() - { - LogManager::getSingleton().logMessage("*** Starting Win32GL Subsystem ***"); - } - - void Win32GLSupport::stop() - { - LogManager::getSingleton().logMessage("*** Stopping Win32GL Subsystem ***"); - mInitialWindow = 0; // Since there is no removeWindow, although there should be... - } - - void Win32GLSupport::initialiseExtensions() - { - assert(mInitialWindow); - // First, initialise the normal extensions - GLSupport::initialiseExtensions(); - // wglew init + } + + BOOL CALLBACK Win32GLSupport::sCreateMonitorsInfoEnumProc( + HMONITOR hMonitor, // handle to display monitor + HDC hdcMonitor, // handle to monitor DC + LPRECT lprcMonitor, // monitor intersection rectangle + LPARAM dwData // data + ) + { + DisplayMonitorInfoList* pArrMonitorsInfo = (DisplayMonitorInfoList*)dwData; + + // Get monitor info + DisplayMonitorInfo displayMonitorInfo; + + displayMonitorInfo.hMonitor = hMonitor; + + memset(&displayMonitorInfo.monitorInfoEx, 0, sizeof(MONITORINFOEX)); + displayMonitorInfo.monitorInfoEx.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &displayMonitorInfo.monitorInfoEx); + + pArrMonitorsInfo->push_back(displayMonitorInfo); + + return TRUE; + } + + + RenderWindow* Win32GLSupport::newWindow(const String &name, unsigned int width, + unsigned int height, bool fullScreen, const NameValuePairList *miscParams) + { + Win32Window* window = new Win32Window(*this); + NameValuePairList newParams; + + if (miscParams != NULL) + { + newParams = *miscParams; + miscParams = &newParams; + + NameValuePairList::const_iterator monitorIndexIt = miscParams->find("monitorIndex"); + HMONITOR hMonitor = NULL; + int monitorIndex = -1; + + // If monitor index found, try to assign the monitor handle based on it. + if (monitorIndexIt != miscParams->end()) + { + if (mMonitorInfoList.empty()) + EnumDisplayMonitors(NULL, NULL, sCreateMonitorsInfoEnumProc, (LPARAM)&mMonitorInfoList); + + monitorIndex = StringConverter::parseInt(monitorIndexIt->second); + if (monitorIndex < (int)mMonitorInfoList.size()) + { + hMonitor = mMonitorInfoList[monitorIndex].hMonitor; + } + } + // If we didn't specified the monitor index, or if it didn't find it + if (hMonitor == NULL) + { + POINT windowAnchorPoint; + + NameValuePairList::const_iterator opt; + int left = -1; + int top = -1; + + if ((opt = newParams.find("left")) != newParams.end()) + left = StringConverter::parseInt(opt->second); + + if ((opt = newParams.find("top")) != newParams.end()) + top = StringConverter::parseInt(opt->second); + + // Fill in anchor point. + windowAnchorPoint.x = left; + windowAnchorPoint.y = top; + + + // Get the nearest monitor to this window. + hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY); + } + + newParams["monitorHandle"] = StringConverter::toString((size_t)hMonitor); + } + + window->create(name, width, height, fullScreen, miscParams); + + if(!mInitialWindow) + mInitialWindow = window; + return window; + } + + void Win32GLSupport::start() + { + LogManager::getSingleton().logMessage("*** Starting Win32GL Subsystem ***"); + } + + void Win32GLSupport::stop() + { + LogManager::getSingleton().logMessage("*** Stopping Win32GL Subsystem ***"); + mInitialWindow = 0; // Since there is no removeWindow, although there should be... + } + + void Win32GLSupport::initialiseExtensions() + { + assert(mInitialWindow); + // First, initialise the normal extensions + GLSupport::initialiseExtensions(); + // wglew init #if OGRE_THREAD_SUPPORT != 1 - wglewContextInit(this); + wglewContextInit(this); #endif - // Check for W32 specific extensions probe function - PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = - (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); - if(!_wglGetExtensionsStringARB) - return; - const char *wgl_extensions = _wglGetExtensionsStringARB(mInitialWindow->getHDC()); + // Check for W32 specific extensions probe function + PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = + (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); + if(!_wglGetExtensionsStringARB) + return; + const char *wgl_extensions = _wglGetExtensionsStringARB(mInitialWindow->getHDC()); LogManager::getSingleton().stream() - << "Supported WGL extensions: " << wgl_extensions; - // Parse them, and add them to the main list - StringStream ext; + << "Supported WGL extensions: " << wgl_extensions; + // Parse them, and add them to the main list + StringStream ext; String instr; - ext << wgl_extensions; + ext << wgl_extensions; while(ext >> instr) { extensionList.insert(instr); } - } - - - void* Win32GLSupport::getProcAddress(const String& procname) - { - return (void*)wglGetProcAddress( procname.c_str() ); - } - void Win32GLSupport::initialiseWGL() - { - // wglGetProcAddress does not work without an active OpenGL context, - // but we need wglChoosePixelFormatARB's address before we can - // create our main window. Thank you very much, Microsoft! - // - // The solution is to create a dummy OpenGL window first, and then - // test for WGL_ARB_pixel_format support. If it is not supported, - // we make sure to never call the ARB pixel format functions. - // - // If is is supported, we call the pixel format functions at least once - // to initialise them (pointers are stored by glprocs.h). We can also - // take this opportunity to enumerate the valid FSAA modes. - - LPCSTR dummyText = "OgreWglDummy"; + } + + + void* Win32GLSupport::getProcAddress(const String& procname) + { + return (void*)wglGetProcAddress( procname.c_str() ); + } + void Win32GLSupport::initialiseWGL() + { + // wglGetProcAddress does not work without an active OpenGL context, + // but we need wglChoosePixelFormatARB's address before we can + // create our main window. Thank you very much, Microsoft! + // + // The solution is to create a dummy OpenGL window first, and then + // test for WGL_ARB_pixel_format support. If it is not supported, + // we make sure to never call the ARB pixel format functions. + // + // If is is supported, we call the pixel format functions at least once + // to initialise them (pointers are stored by glprocs.h). We can also + // take this opportunity to enumerate the valid FSAA modes. + + LPCSTR dummyText = "OgreWglDummy"; #ifdef OGRE_STATIC_LIB - HINSTANCE hinst = GetModuleHandle( NULL ); + HINSTANCE hinst = GetModuleHandle( NULL ); #else # if OGRE_DEBUG_MODE == 1 - HINSTANCE hinst = GetModuleHandle("RenderSystem_GL_d.dll"); + HINSTANCE hinst = GetModuleHandle("RenderSystem_GL_d.dll"); # else - HINSTANCE hinst = GetModuleHandle("RenderSystem_GL.dll"); + HINSTANCE hinst = GetModuleHandle("RenderSystem_GL.dll"); # endif #endif - - WNDCLASS dummyClass; - memset(&dummyClass, 0, sizeof(WNDCLASS)); - dummyClass.style = CS_OWNDC; - dummyClass.hInstance = hinst; - dummyClass.lpfnWndProc = dummyWndProc; - dummyClass.lpszClassName = dummyText; - RegisterClass(&dummyClass); - - HWND hwnd = CreateWindow(dummyText, dummyText, - WS_POPUP | WS_CLIPCHILDREN, - 0, 0, 32, 32, 0, 0, hinst, 0); - - // if a simple CreateWindow fails, then boy are we in trouble... - if (hwnd == NULL) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "CreateWindow() failed", "Win32GLSupport::initializeWGL"); - - - // no chance of failure and no need to release thanks to CS_OWNDC - HDC hdc = GetDC(hwnd); - - // assign a simple OpenGL pixel format that everyone supports - PIXELFORMATDESCRIPTOR pfd; - memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.cColorBits = 16; - pfd.cDepthBits = 15; - pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - - // if these fail, wglCreateContext will also quietly fail - int format; - if ((format = ChoosePixelFormat(hdc, &pfd)) != 0) - SetPixelFormat(hdc, format, &pfd); - - HGLRC hrc = wglCreateContext(hdc); - if (hrc) - { - HGLRC oldrc = wglGetCurrentContext(); - HDC oldhdc = wglGetCurrentDC(); - // if wglMakeCurrent fails, wglGetProcAddress will return null - wglMakeCurrent(hdc, hrc); - - PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = - (PFNWGLGETEXTENSIONSSTRINGARBPROC) - wglGetProcAddress("wglGetExtensionsStringARB"); - - // check for pixel format and multisampling support - if (_wglGetExtensionsStringARB) - { - std::istringstream wglexts(_wglGetExtensionsStringARB(hdc)); - std::string ext; - while (wglexts >> ext) - { - if (ext == "WGL_ARB_pixel_format") - mHasPixelFormatARB = true; - else if (ext == "WGL_ARB_multisample") - mHasMultisample = true; - else if (ext == "WGL_EXT_framebuffer_sRGB") - mHasHardwareGamma = true; - } - } - - if (mHasPixelFormatARB && mHasMultisample) - { - // enumerate all formats w/ multisampling - static const int iattr[] = { - WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, - WGL_SUPPORT_OPENGL_ARB, GL_TRUE, - WGL_DOUBLE_BUFFER_ARB, GL_TRUE, - WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, - WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, + + WNDCLASS dummyClass; + memset(&dummyClass, 0, sizeof(WNDCLASS)); + dummyClass.style = CS_OWNDC; + dummyClass.hInstance = hinst; + dummyClass.lpfnWndProc = dummyWndProc; + dummyClass.lpszClassName = dummyText; + RegisterClass(&dummyClass); + + HWND hwnd = CreateWindow(dummyText, dummyText, + WS_POPUP | WS_CLIPCHILDREN, + 0, 0, 32, 32, 0, 0, hinst, 0); + + // if a simple CreateWindow fails, then boy are we in trouble... + if (hwnd == NULL) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "CreateWindow() failed", "Win32GLSupport::initializeWGL"); + + + // no chance of failure and no need to release thanks to CS_OWNDC + HDC hdc = GetDC(hwnd); + + // assign a simple OpenGL pixel format that everyone supports + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.cColorBits = 16; + pfd.cDepthBits = 15; + pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + + // if these fail, wglCreateContext will also quietly fail + int format; + if ((format = ChoosePixelFormat(hdc, &pfd)) != 0) + SetPixelFormat(hdc, format, &pfd); + + HGLRC hrc = wglCreateContext(hdc); + if (hrc) + { + HGLRC oldrc = wglGetCurrentContext(); + HDC oldhdc = wglGetCurrentDC(); + // if wglMakeCurrent fails, wglGetProcAddress will return null + wglMakeCurrent(hdc, hrc); + + PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = + (PFNWGLGETEXTENSIONSSTRINGARBPROC) + wglGetProcAddress("wglGetExtensionsStringARB"); + + // check for pixel format and multisampling support + if (_wglGetExtensionsStringARB) + { + std::istringstream wglexts(_wglGetExtensionsStringARB(hdc)); + std::string ext; + while (wglexts >> ext) + { + if (ext == "WGL_ARB_pixel_format") + mHasPixelFormatARB = true; + else if (ext == "WGL_ARB_multisample") + mHasMultisample = true; + else if (ext == "WGL_EXT_framebuffer_sRGB") + mHasHardwareGamma = true; + } + } + + if (mHasPixelFormatARB && mHasMultisample) + { + // enumerate all formats w/ multisampling + static const int iattr[] = { + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, + WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, /* We are no matter about the colour, depth and stencil buffers here - WGL_COLOR_BITS_ARB, 24, - WGL_ALPHA_BITS_ARB, 8, - WGL_DEPTH_BITS_ARB, 24, - WGL_STENCIL_BITS_ARB, 8, + WGL_COLOR_BITS_ARB, 24, + WGL_ALPHA_BITS_ARB, 8, + WGL_DEPTH_BITS_ARB, 24, + WGL_STENCIL_BITS_ARB, 8, */ - WGL_SAMPLES_ARB, 2, - 0 - }; - int formats[256]; - unsigned int count; + WGL_SAMPLES_ARB, 2, + 0 + }; + int formats[256]; + unsigned int count; // cheating here. wglChoosePixelFormatARB procc address needed later on // when a valid GL context does not exist and glew is not initialized yet. WGLEW_GET_FUN(__wglewChoosePixelFormatARB) = @@ -594,120 +594,120 @@ namespace Ogre { } remove_duplicates(mFSAALevels); } - } - - wglMakeCurrent(oldhdc, oldrc); - wglDeleteContext(hrc); - } - - // clean up our dummy window and class - DestroyWindow(hwnd); - UnregisterClass(dummyText, hinst); - } - - LRESULT Win32GLSupport::dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp) - { - return DefWindowProc(hwnd, umsg, wp, lp); - } - - bool Win32GLSupport::selectPixelFormat(HDC hdc, int colourDepth, int multisample, bool hwGamma) - { - PIXELFORMATDESCRIPTOR pfd; - memset(&pfd, 0, sizeof(pfd)); - pfd.nSize = sizeof(pfd); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = (colourDepth > 16)? 24 : colourDepth; - pfd.cAlphaBits = (colourDepth > 16)? 8 : 0; - pfd.cDepthBits = 24; - pfd.cStencilBits = 8; - - int format = 0; - - int useHwGamma = hwGamma? GL_TRUE : GL_FALSE; - - if (multisample && (!mHasMultisample || !mHasPixelFormatARB)) - return false; - - if (hwGamma && !mHasHardwareGamma) - return false; - - if ((multisample || hwGamma) && WGLEW_GET_FUN(__wglewChoosePixelFormatARB)) - { - - // Use WGL to test extended caps (multisample, sRGB) - vector::type attribList; - attribList.push_back(WGL_DRAW_TO_WINDOW_ARB); attribList.push_back(GL_TRUE); - attribList.push_back(WGL_SUPPORT_OPENGL_ARB); attribList.push_back(GL_TRUE); - attribList.push_back(WGL_DOUBLE_BUFFER_ARB); attribList.push_back(GL_TRUE); - attribList.push_back(WGL_SAMPLE_BUFFERS_ARB); attribList.push_back(GL_TRUE); - attribList.push_back(WGL_ACCELERATION_ARB); attribList.push_back(WGL_FULL_ACCELERATION_ARB); - attribList.push_back(WGL_COLOR_BITS_ARB); attribList.push_back(pfd.cColorBits); - attribList.push_back(WGL_ALPHA_BITS_ARB); attribList.push_back(pfd.cAlphaBits); - attribList.push_back(WGL_DEPTH_BITS_ARB); attribList.push_back(24); - attribList.push_back(WGL_STENCIL_BITS_ARB); attribList.push_back(8); - attribList.push_back(WGL_SAMPLES_ARB); attribList.push_back(multisample); - if (useHwGamma && mHasHardwareGamma) - { - attribList.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT); attribList.push_back(GL_TRUE); - } - // terminator - attribList.push_back(0); - - - UINT nformats; - // ChoosePixelFormatARB proc address was obtained when setting up a dummy GL context in initialiseWGL() - // since glew hasn't been initialized yet, we have to cheat and use the previously obtained address - if (!WGLEW_GET_FUN(__wglewChoosePixelFormatARB)(hdc, &(attribList[0]), NULL, 1, &format, &nformats) || nformats <= 0) - return false; - } - else - { - format = ChoosePixelFormat(hdc, &pfd); - } - - - return (format && SetPixelFormat(hdc, format, &pfd)); - } - - bool Win32GLSupport::supportsPBuffers() - { - return WGLEW_GET_FUN(__WGLEW_ARB_pbuffer) != GL_FALSE; - } + } + + wglMakeCurrent(oldhdc, oldrc); + wglDeleteContext(hrc); + } + + // clean up our dummy window and class + DestroyWindow(hwnd); + UnregisterClass(dummyText, hinst); + } + + LRESULT Win32GLSupport::dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp) + { + return DefWindowProc(hwnd, umsg, wp, lp); + } + + bool Win32GLSupport::selectPixelFormat(HDC hdc, int colourDepth, int multisample, bool hwGamma) + { + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = (colourDepth > 16)? 24 : colourDepth; + pfd.cAlphaBits = (colourDepth > 16)? 8 : 0; + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; + + int format = 0; + + int useHwGamma = hwGamma? GL_TRUE : GL_FALSE; + + if (multisample && (!mHasMultisample || !mHasPixelFormatARB)) + return false; + + if (hwGamma && !mHasHardwareGamma) + return false; + + if ((multisample || hwGamma) && WGLEW_GET_FUN(__wglewChoosePixelFormatARB)) + { + + // Use WGL to test extended caps (multisample, sRGB) + vector::type attribList; + attribList.push_back(WGL_DRAW_TO_WINDOW_ARB); attribList.push_back(GL_TRUE); + attribList.push_back(WGL_SUPPORT_OPENGL_ARB); attribList.push_back(GL_TRUE); + attribList.push_back(WGL_DOUBLE_BUFFER_ARB); attribList.push_back(GL_TRUE); + attribList.push_back(WGL_SAMPLE_BUFFERS_ARB); attribList.push_back(GL_TRUE); + attribList.push_back(WGL_ACCELERATION_ARB); attribList.push_back(WGL_FULL_ACCELERATION_ARB); + attribList.push_back(WGL_COLOR_BITS_ARB); attribList.push_back(pfd.cColorBits); + attribList.push_back(WGL_ALPHA_BITS_ARB); attribList.push_back(pfd.cAlphaBits); + attribList.push_back(WGL_DEPTH_BITS_ARB); attribList.push_back(24); + attribList.push_back(WGL_STENCIL_BITS_ARB); attribList.push_back(8); + attribList.push_back(WGL_SAMPLES_ARB); attribList.push_back(multisample); + if (useHwGamma && mHasHardwareGamma) + { + attribList.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT); attribList.push_back(GL_TRUE); + } + // terminator + attribList.push_back(0); + + + UINT nformats; + // ChoosePixelFormatARB proc address was obtained when setting up a dummy GL context in initialiseWGL() + // since glew hasn't been initialized yet, we have to cheat and use the previously obtained address + if (!WGLEW_GET_FUN(__wglewChoosePixelFormatARB)(hdc, &(attribList[0]), NULL, 1, &format, &nformats) || nformats <= 0) + return false; + } + else + { + format = ChoosePixelFormat(hdc, &pfd); + } + + + return (format && SetPixelFormat(hdc, format, &pfd)); + } + + bool Win32GLSupport::supportsPBuffers() + { + return WGLEW_GET_FUN(__WGLEW_ARB_pbuffer) != GL_FALSE; + } GLPBuffer *Win32GLSupport::createPBuffer(PixelComponentType format, size_t width, size_t height) - { - return new Win32PBuffer(format, width, height); - } - - unsigned int Win32GLSupport::getDisplayMonitorCount() const - { - if (mMonitorInfoList.empty()) - EnumDisplayMonitors(NULL, NULL, sCreateMonitorsInfoEnumProc, (LPARAM)&mMonitorInfoList); - - return (unsigned int)mMonitorInfoList.size(); - } - - String translateWGLError() - { - int winError = GetLastError(); - char* errDesc; - int i; - - errDesc = new char[255]; - // Try windows errors first - i = FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - winError, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) errDesc, - 255, - NULL - ); - - return String(errDesc); - } + { + return new Win32PBuffer(format, width, height); + } + + unsigned int Win32GLSupport::getDisplayMonitorCount() const + { + if (mMonitorInfoList.empty()) + EnumDisplayMonitors(NULL, NULL, sCreateMonitorsInfoEnumProc, (LPARAM)&mMonitorInfoList); + + return (unsigned int)mMonitorInfoList.size(); + } + + String translateWGLError() + { + int winError = GetLastError(); + char* errDesc; + int i; + + errDesc = new char[255]; + // Try windows errors first + i = FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + winError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) errDesc, + 255, + NULL + ); + + return String(errDesc); + } } diff --git a/RenderSystems/GL/src/Win32/OgreWin32RenderTexture.cpp b/RenderSystems/GL/src/Win32/OgreWin32RenderTexture.cpp index 5d3a7929e60..8a620b6e113 100644 --- a/RenderSystems/GL/src/Win32/OgreWin32RenderTexture.cpp +++ b/RenderSystems/GL/src/Win32/OgreWin32RenderTexture.cpp @@ -38,51 +38,51 @@ THE SOFTWARE. namespace Ogre { - Win32PBuffer::Win32PBuffer(PixelComponentType format, size_t width, size_t height): - GLPBuffer(format, width, height), + Win32PBuffer::Win32PBuffer(PixelComponentType format, size_t width, size_t height): + GLPBuffer(format, width, height), mContext(0) - { - createPBuffer(); + { + createPBuffer(); // Create context mContext = new Win32Context(mHDC, mGlrc); #if 0 - if(mUseBind) - { - // Bind texture - glBindTextureEXT(GL_TEXTURE_2D, static_cast(mTexture.get())->getGLID()); - wglBindTexImageARB(mPBuffer, WGL_FRONT_LEFT_ARB); - } + if(mUseBind) + { + // Bind texture + glBindTextureEXT(GL_TEXTURE_2D, static_cast(mTexture.get())->getGLID()); + wglBindTexImageARB(mPBuffer, WGL_FRONT_LEFT_ARB); + } #endif - } - Win32PBuffer::~Win32PBuffer() - { + } + Win32PBuffer::~Win32PBuffer() + { #if 0 - if(mUseBind) - { - // Unbind texture - glBindTextureEXT(GL_TEXTURE_2D, - static_cast(mTexture.get())->getGLID()); - glBindTextureEXT(GL_TEXTURE_2D, - static_cast(mTexture.get())->getGLID()); - wglReleaseTexImageARB(mPBuffer, WGL_FRONT_LEFT_ARB); - } + if(mUseBind) + { + // Unbind texture + glBindTextureEXT(GL_TEXTURE_2D, + static_cast(mTexture.get())->getGLID()); + glBindTextureEXT(GL_TEXTURE_2D, + static_cast(mTexture.get())->getGLID()); + wglReleaseTexImageARB(mPBuffer, WGL_FRONT_LEFT_ARB); + } #endif // Unregister and destroy mContext delete mContext; - // Destroy pbuffer - destroyPBuffer(); - } - - void Win32PBuffer::createPBuffer() - { + // Destroy pbuffer + destroyPBuffer(); + } + + void Win32PBuffer::createPBuffer() + { // Process format int bits=0; bool isFloat=false; #if 0 - bool hasAlpha=true; + bool hasAlpha=true; #endif switch(mFormat) { @@ -100,76 +100,76 @@ namespace Ogre { break; default: break; }; - LogManager::getSingleton().logMessage( - " Win32PBuffer::Creating PBuffer of format bits="+ - StringConverter::toString(bits)+ - " float="+StringConverter::toString(isFloat) - ); + LogManager::getSingleton().logMessage( + " Win32PBuffer::Creating PBuffer of format bits="+ + StringConverter::toString(bits)+ + " float="+StringConverter::toString(isFloat) + ); - HDC old_hdc = wglGetCurrentDC(); - HGLRC old_context = wglGetCurrentContext(); + HDC old_hdc = wglGetCurrentDC(); + HGLRC old_context = wglGetCurrentContext(); - // Bind to RGB or RGBA texture - int bttype = 0; + // Bind to RGB or RGBA texture + int bttype = 0; #if 0 - if(mUseBind) - { - // Only provide bind type when actually binding - bttype = PixelUtil::hasAlpha(mInternalFormat)? - WGL_BIND_TO_TEXTURE_RGBA_ARB : WGL_BIND_TO_TEXTURE_RGB_ARB; - } - int texformat = hasAlpha? - WGL_TEXTURE_RGBA_ARB : WGL_TEXTURE_RGB_ARB; + if(mUseBind) + { + // Only provide bind type when actually binding + bttype = PixelUtil::hasAlpha(mInternalFormat)? + WGL_BIND_TO_TEXTURE_RGBA_ARB : WGL_BIND_TO_TEXTURE_RGB_ARB; + } + int texformat = hasAlpha? + WGL_TEXTURE_RGBA_ARB : WGL_TEXTURE_RGB_ARB; #endif - // Make a float buffer? + // Make a float buffer? int pixeltype = isFloat? - WGL_TYPE_RGBA_FLOAT_ARB: WGL_TYPE_RGBA_ARB; - - int attrib[] = { - WGL_RED_BITS_ARB,bits, - WGL_GREEN_BITS_ARB,bits, - WGL_BLUE_BITS_ARB,bits, - WGL_ALPHA_BITS_ARB,bits, - WGL_STENCIL_BITS_ARB,1, - WGL_DEPTH_BITS_ARB,15, - WGL_DRAW_TO_PBUFFER_ARB,true, - WGL_SUPPORT_OPENGL_ARB,true, - WGL_PIXEL_TYPE_ARB,pixeltype, - //WGL_DOUBLE_BUFFER_ARB,true, - //WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB, // Make sure it is accelerated - bttype,true, // must be last, as bttype can be zero - 0 - }; - int pattrib_default[] = { - 0 - }; + WGL_TYPE_RGBA_FLOAT_ARB: WGL_TYPE_RGBA_ARB; + + int attrib[] = { + WGL_RED_BITS_ARB,bits, + WGL_GREEN_BITS_ARB,bits, + WGL_BLUE_BITS_ARB,bits, + WGL_ALPHA_BITS_ARB,bits, + WGL_STENCIL_BITS_ARB,1, + WGL_DEPTH_BITS_ARB,15, + WGL_DRAW_TO_PBUFFER_ARB,true, + WGL_SUPPORT_OPENGL_ARB,true, + WGL_PIXEL_TYPE_ARB,pixeltype, + //WGL_DOUBLE_BUFFER_ARB,true, + //WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB, // Make sure it is accelerated + bttype,true, // must be last, as bttype can be zero + 0 + }; + int pattrib_default[] = { + 0 + }; #if 0 - int pattrib_bind[] = { - WGL_TEXTURE_FORMAT_ARB, texformat, - WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, - WGL_PBUFFER_LARGEST_ARB, true, - 0 - }; + int pattrib_bind[] = { + WGL_TEXTURE_FORMAT_ARB, texformat, + WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, + WGL_PBUFFER_LARGEST_ARB, true, + 0 + }; #endif - int format; - unsigned int count; - - // Choose suitable pixel format - wglChoosePixelFormatARB(old_hdc,attrib,NULL,1,&format,&count); - if(count == 0) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglChoosePixelFormatARB() failed", " Win32PBuffer::createPBuffer"); - - // Analyse pixel format - const int piAttributes[]={ - WGL_RED_BITS_ARB,WGL_GREEN_BITS_ARB,WGL_BLUE_BITS_ARB,WGL_ALPHA_BITS_ARB, - WGL_DEPTH_BITS_ARB,WGL_STENCIL_BITS_ARB - }; - int piValues[sizeof(piAttributes)/sizeof(const int)]; - wglGetPixelFormatAttribivARB(old_hdc,format,0,sizeof(piAttributes)/sizeof(const int),piAttributes,piValues); + int format; + unsigned int count; + + // Choose suitable pixel format + wglChoosePixelFormatARB(old_hdc,attrib,NULL,1,&format,&count); + if(count == 0) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglChoosePixelFormatARB() failed", " Win32PBuffer::createPBuffer"); + + // Analyse pixel format + const int piAttributes[]={ + WGL_RED_BITS_ARB,WGL_GREEN_BITS_ARB,WGL_BLUE_BITS_ARB,WGL_ALPHA_BITS_ARB, + WGL_DEPTH_BITS_ARB,WGL_STENCIL_BITS_ARB + }; + int piValues[sizeof(piAttributes)/sizeof(const int)]; + wglGetPixelFormatAttribivARB(old_hdc,format,0,sizeof(piAttributes)/sizeof(const int),piAttributes,piValues); LogManager::getSingleton().stream() - << " Win32PBuffer::PBuffer -- Chosen pixel format rgba=" + << " Win32PBuffer::PBuffer -- Chosen pixel format rgba=" << piValues[0] << "," << piValues[1] << "," << piValues[2] << "," @@ -177,46 +177,46 @@ namespace Ogre { << " depth=" << piValues[4] << " stencil=" << piValues[5]; - mPBuffer = wglCreatePbufferARB(old_hdc,format,mWidth,mHeight,pattrib_default); - if(!mPBuffer) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglCreatePbufferARB() failed", " Win32PBuffer::createPBuffer"); - - mHDC = wglGetPbufferDCARB(mPBuffer); - if(!mHDC) { - wglDestroyPbufferARB(mPBuffer); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglGetPbufferDCARB() failed", " Win32PBuffer::createPBuffer"); - } - - mGlrc = wglCreateContext(mHDC); - if(!mGlrc) { - wglReleasePbufferDCARB(mPBuffer,mHDC); - wglDestroyPbufferARB(mPBuffer); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglCreateContext() failed", " Win32PBuffer::createPBuffer"); - } - - if(!wglShareLists(old_context,mGlrc)) { - wglDeleteContext(mGlrc); - wglReleasePbufferDCARB(mPBuffer,mHDC); - wglDestroyPbufferARB(mPBuffer); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglShareLists() failed", " Win32PBuffer::createPBuffer"); - } - - // Query real width and height - int iWidth, iHeight; - wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_WIDTH_ARB, &iWidth); - wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_HEIGHT_ARB, &iHeight); - mWidth = iWidth; - mHeight = iHeight; - LogManager::getSingleton().stream() - << "Win32RenderTexture::PBuffer created -- Real dimensions " + mPBuffer = wglCreatePbufferARB(old_hdc,format,mWidth,mHeight,pattrib_default); + if(!mPBuffer) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglCreatePbufferARB() failed", " Win32PBuffer::createPBuffer"); + + mHDC = wglGetPbufferDCARB(mPBuffer); + if(!mHDC) { + wglDestroyPbufferARB(mPBuffer); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglGetPbufferDCARB() failed", " Win32PBuffer::createPBuffer"); + } + + mGlrc = wglCreateContext(mHDC); + if(!mGlrc) { + wglReleasePbufferDCARB(mPBuffer,mHDC); + wglDestroyPbufferARB(mPBuffer); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglCreateContext() failed", " Win32PBuffer::createPBuffer"); + } + + if(!wglShareLists(old_context,mGlrc)) { + wglDeleteContext(mGlrc); + wglReleasePbufferDCARB(mPBuffer,mHDC); + wglDestroyPbufferARB(mPBuffer); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglShareLists() failed", " Win32PBuffer::createPBuffer"); + } + + // Query real width and height + int iWidth, iHeight; + wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_WIDTH_ARB, &iWidth); + wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_HEIGHT_ARB, &iHeight); + mWidth = iWidth; + mHeight = iHeight; + LogManager::getSingleton().stream() + << "Win32RenderTexture::PBuffer created -- Real dimensions " << mWidth << "x" << mHeight; - } - void Win32PBuffer::destroyPBuffer() - { - wglDeleteContext(mGlrc); - wglReleasePbufferDCARB(mPBuffer,mHDC); - wglDestroyPbufferARB(mPBuffer); - } + } + void Win32PBuffer::destroyPBuffer() + { + wglDeleteContext(mGlrc); + wglReleasePbufferDCARB(mPBuffer,mHDC); + wglDestroyPbufferARB(mPBuffer); + } } diff --git a/RenderSystems/GL/src/Win32/OgreWin32Window.cpp b/RenderSystems/GL/src/Win32/OgreWin32Window.cpp index 1491eee1f7d..becdb6f749e 100644 --- a/RenderSystems/GL/src/Win32/OgreWin32Window.cpp +++ b/RenderSystems/GL/src/Win32/OgreWin32Window.cpp @@ -45,890 +45,890 @@ THE SOFTWARE. namespace Ogre { - #define _MAX_CLASS_NAME_ 128 - - Win32Window::Win32Window(Win32GLSupport &glsupport): - mGLSupport(glsupport), - mContext(0) - { - mIsFullScreen = false; - mHWnd = 0; - mGlrc = 0; - mIsExternal = false; - mIsExternalGLControl = false; - mIsExternalGLContext = false; - mSizing = false; - mClosed = false; - mHidden = false; - mVSync = false; - mVSyncInterval = 1; - mDisplayFrequency = 0; - mActive = false; - mDeviceName = NULL; - mWindowedWinStyle = 0; - mFullscreenWinStyle = 0; - } - - Win32Window::~Win32Window() - { - destroy(); - } - - void Win32Window::create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) - { - // destroy current window, if any - if (mHWnd) - destroy(); + #define _MAX_CLASS_NAME_ 128 + + Win32Window::Win32Window(Win32GLSupport &glsupport): + mGLSupport(glsupport), + mContext(0) + { + mIsFullScreen = false; + mHWnd = 0; + mGlrc = 0; + mIsExternal = false; + mIsExternalGLControl = false; + mIsExternalGLContext = false; + mSizing = false; + mClosed = false; + mHidden = false; + mVSync = false; + mVSyncInterval = 1; + mDisplayFrequency = 0; + mActive = false; + mDeviceName = NULL; + mWindowedWinStyle = 0; + mFullscreenWinStyle = 0; + } + + Win32Window::~Win32Window() + { + destroy(); + } + + void Win32Window::create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams) + { + // destroy current window, if any + if (mHWnd) + destroy(); #ifdef OGRE_STATIC_LIB - HINSTANCE hInst = GetModuleHandle( NULL ); + HINSTANCE hInst = GetModuleHandle( NULL ); #else # if OGRE_DEBUG_MODE == 1 - HINSTANCE hInst = GetModuleHandle("RenderSystem_GL_d.dll"); + HINSTANCE hInst = GetModuleHandle("RenderSystem_GL_d.dll"); # else - HINSTANCE hInst = GetModuleHandle("RenderSystem_GL.dll"); + HINSTANCE hInst = GetModuleHandle("RenderSystem_GL.dll"); # endif #endif - mHWnd = 0; - mName = name; - mIsFullScreen = fullScreen; - mClosed = false; - mDisplayFrequency = 0; - mDepthBufferPoolId = DepthBuffer::POOL_DEFAULT; - mColourDepth = mIsFullScreen? 32 : GetDeviceCaps(GetDC(0), BITSPIXEL); - int left = -1; // Defaults to screen center - int top = -1; // Defaults to screen center - HWND parent = 0; - String title = name; - bool hidden = false; - String border; - bool outerSize = false; - bool hwGamma = false; - bool enableDoubleClick = false; - int monitorIndex = -1; - HMONITOR hMonitor = NULL; - - if(miscParams) - { - // Get variable-length params - NameValuePairList::const_iterator opt; - NameValuePairList::const_iterator end = miscParams->end(); - - if ((opt = miscParams->find("title")) != end) - title = opt->second; - - if ((opt = miscParams->find("left")) != end) - left = StringConverter::parseInt(opt->second); - - if ((opt = miscParams->find("top")) != end) - top = StringConverter::parseInt(opt->second); - - if ((opt = miscParams->find("depthBuffer")) != end) - { - mDepthBufferPoolId = StringConverter::parseBool(opt->second) ? - DepthBuffer::POOL_DEFAULT : DepthBuffer::POOL_NO_DEPTH; - } - - if ((opt = miscParams->find("vsync")) != end) - mVSync = StringConverter::parseBool(opt->second); - - if ((opt = miscParams->find("hidden")) != end) - hidden = StringConverter::parseBool(opt->second); - - if ((opt = miscParams->find("vsyncInterval")) != end) - mVSyncInterval = StringConverter::parseUnsignedInt(opt->second); - - if ((opt = miscParams->find("FSAA")) != end) - mFSAA = StringConverter::parseUnsignedInt(opt->second); - - if ((opt = miscParams->find("FSAAHint")) != end) - mFSAAHint = opt->second; - - if ((opt = miscParams->find("gamma")) != end) - hwGamma = StringConverter::parseBool(opt->second); - - if ((opt = miscParams->find("externalWindowHandle")) != end) - { - mHWnd = (HWND)StringConverter::parseSizeT(opt->second); - if (mHWnd) - { - mIsExternal = true; - mIsFullScreen = false; - } - - if ((opt = miscParams->find("externalGLControl")) != end) { - mIsExternalGLControl = StringConverter::parseBool(opt->second); - } - } - if ((opt = miscParams->find("externalGLContext")) != end) - { - mGlrc = (HGLRC)StringConverter::parseUnsignedLong(opt->second); - if( mGlrc ) - mIsExternalGLContext = true; - } - - // window border style - opt = miscParams->find("border"); - if(opt != miscParams->end()) - border = opt->second; - // set outer dimensions? - opt = miscParams->find("outerDimensions"); - if(opt != miscParams->end()) - outerSize = StringConverter::parseBool(opt->second); - - // only available with fullscreen - if ((opt = miscParams->find("displayFrequency")) != end) - mDisplayFrequency = StringConverter::parseUnsignedInt(opt->second); - if ((opt = miscParams->find("colourDepth")) != end) - { - mColourDepth = StringConverter::parseUnsignedInt(opt->second); - if (!mIsFullScreen) - { - // make sure we don't exceed desktop colour depth - if ((int)mColourDepth > GetDeviceCaps(GetDC(0), BITSPIXEL)) - mColourDepth = GetDeviceCaps(GetDC(0), BITSPIXEL); - } - } - - // incompatible with fullscreen - if ((opt = miscParams->find("parentWindowHandle")) != end) - parent = (HWND)StringConverter::parseSizeT(opt->second); - - - // monitor index - if ((opt = miscParams->find("monitorIndex")) != end) - monitorIndex = StringConverter::parseInt(opt->second); - - // monitor handle - if ((opt = miscParams->find("monitorHandle")) != end) - hMonitor = (HMONITOR)StringConverter::parseInt(opt->second); - - // enable double click messages - if ((opt = miscParams->find("enableDoubleClick")) != end) - enableDoubleClick = StringConverter::parseBool(opt->second); - - } - - if (!mIsExternal) - { - DWORD dwStyleEx = 0; - MONITORINFOEX monitorInfoEx; - RECT rc; - - // If we didn't specified the adapter index, or if it didn't find it - if (hMonitor == NULL) - { - POINT windowAnchorPoint; - - // Fill in anchor point. - windowAnchorPoint.x = left; - windowAnchorPoint.y = top; - - - // Get the default primary monitor to this window. - hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY); - } - - // Get the target monitor info - memset(&monitorInfoEx, 0, sizeof(MONITORINFOEX)); - monitorInfoEx.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(hMonitor, &monitorInfoEx); - - size_t devNameLen = strlen(monitorInfoEx.szDevice); - mDeviceName = new char[devNameLen + 1]; - - strcpy(mDeviceName, monitorInfoEx.szDevice); - - // Update window style flags. - mFullscreenWinStyle = (hidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN | WS_POPUP; - mWindowedWinStyle = (hidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN; - - if (parent) - { - mWindowedWinStyle |= WS_CHILD; - } - else - { - if (border == "none") - mWindowedWinStyle |= WS_POPUP; - else if (border == "fixed") - mWindowedWinStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | - WS_SYSMENU | WS_MINIMIZEBOX; - else - mWindowedWinStyle |= WS_OVERLAPPEDWINDOW; - - } - - - // No specified top left -> Center the window in the middle of the monitor - if (left == -1 || top == -1) - { - uint32 screenw = monitorInfoEx.rcWork.right - monitorInfoEx.rcWork.left; - uint32 screenh = monitorInfoEx.rcWork.bottom - monitorInfoEx.rcWork.top; - - uint32 winWidth, winHeight; - adjustWindow(width, height, &winWidth, &winHeight); - - // clamp window dimensions to screen size - uint32 outerw = (winWidth < screenw)? winWidth : screenw; - uint32 outerh = (winHeight < screenh)? winHeight : screenh; - - if (left == -1) - left = monitorInfoEx.rcWork.left + (screenw - outerw) / 2; - else if (monitorIndex != -1) - left += monitorInfoEx.rcWork.left; - - if (top == -1) - top = monitorInfoEx.rcWork.top + (screenh - outerh) / 2; - else if (monitorIndex != -1) - top += monitorInfoEx.rcWork.top; - } - else if (monitorIndex != -1) - { - left += monitorInfoEx.rcWork.left; - top += monitorInfoEx.rcWork.top; - } - - mWidth = width; - mHeight = height; - mTop = top; - mLeft = left; - - if (mIsFullScreen) - { - dwStyleEx |= WS_EX_TOPMOST; - mTop = monitorInfoEx.rcMonitor.top; - mLeft = monitorInfoEx.rcMonitor.left; - } - else - { - int screenw = GetSystemMetrics(SM_CXSCREEN); - int screenh = GetSystemMetrics(SM_CYSCREEN); - - if (!outerSize) - { - // Calculate window dimensions required - // to get the requested client area - SetRect(&rc, 0, 0, mWidth, mHeight); - AdjustWindowRect(&rc, getWindowStyle(fullScreen), false); - mWidth = rc.right - rc.left; - mHeight = rc.bottom - rc.top; - - // Clamp window rect to the default primary display monitor. - if (mLeft < monitorInfoEx.rcWork.left) - mLeft = monitorInfoEx.rcWork.left; - - if (mTop < monitorInfoEx.rcWork.top) - mTop = monitorInfoEx.rcWork.top; - - if ((int)mWidth > monitorInfoEx.rcWork.right - mLeft) - mWidth = monitorInfoEx.rcWork.right - mLeft; - - if ((int)mHeight > monitorInfoEx.rcWork.bottom - mTop) - mHeight = monitorInfoEx.rcWork.bottom - mTop; - } - } + mHWnd = 0; + mName = name; + mIsFullScreen = fullScreen; + mClosed = false; + mDisplayFrequency = 0; + mDepthBufferPoolId = DepthBuffer::POOL_DEFAULT; + mColourDepth = mIsFullScreen? 32 : GetDeviceCaps(GetDC(0), BITSPIXEL); + int left = -1; // Defaults to screen center + int top = -1; // Defaults to screen center + HWND parent = 0; + String title = name; + bool hidden = false; + String border; + bool outerSize = false; + bool hwGamma = false; + bool enableDoubleClick = false; + int monitorIndex = -1; + HMONITOR hMonitor = NULL; + + if(miscParams) + { + // Get variable-length params + NameValuePairList::const_iterator opt; + NameValuePairList::const_iterator end = miscParams->end(); + + if ((opt = miscParams->find("title")) != end) + title = opt->second; + + if ((opt = miscParams->find("left")) != end) + left = StringConverter::parseInt(opt->second); + + if ((opt = miscParams->find("top")) != end) + top = StringConverter::parseInt(opt->second); + + if ((opt = miscParams->find("depthBuffer")) != end) + { + mDepthBufferPoolId = StringConverter::parseBool(opt->second) ? + DepthBuffer::POOL_DEFAULT : DepthBuffer::POOL_NO_DEPTH; + } + + if ((opt = miscParams->find("vsync")) != end) + mVSync = StringConverter::parseBool(opt->second); + + if ((opt = miscParams->find("hidden")) != end) + hidden = StringConverter::parseBool(opt->second); + + if ((opt = miscParams->find("vsyncInterval")) != end) + mVSyncInterval = StringConverter::parseUnsignedInt(opt->second); + + if ((opt = miscParams->find("FSAA")) != end) + mFSAA = StringConverter::parseUnsignedInt(opt->second); + + if ((opt = miscParams->find("FSAAHint")) != end) + mFSAAHint = opt->second; + + if ((opt = miscParams->find("gamma")) != end) + hwGamma = StringConverter::parseBool(opt->second); + + if ((opt = miscParams->find("externalWindowHandle")) != end) + { + mHWnd = (HWND)StringConverter::parseSizeT(opt->second); + if (mHWnd) + { + mIsExternal = true; + mIsFullScreen = false; + } + + if ((opt = miscParams->find("externalGLControl")) != end) { + mIsExternalGLControl = StringConverter::parseBool(opt->second); + } + } + if ((opt = miscParams->find("externalGLContext")) != end) + { + mGlrc = (HGLRC)StringConverter::parseUnsignedLong(opt->second); + if( mGlrc ) + mIsExternalGLContext = true; + } + + // window border style + opt = miscParams->find("border"); + if(opt != miscParams->end()) + border = opt->second; + // set outer dimensions? + opt = miscParams->find("outerDimensions"); + if(opt != miscParams->end()) + outerSize = StringConverter::parseBool(opt->second); + + // only available with fullscreen + if ((opt = miscParams->find("displayFrequency")) != end) + mDisplayFrequency = StringConverter::parseUnsignedInt(opt->second); + if ((opt = miscParams->find("colourDepth")) != end) + { + mColourDepth = StringConverter::parseUnsignedInt(opt->second); + if (!mIsFullScreen) + { + // make sure we don't exceed desktop colour depth + if ((int)mColourDepth > GetDeviceCaps(GetDC(0), BITSPIXEL)) + mColourDepth = GetDeviceCaps(GetDC(0), BITSPIXEL); + } + } + + // incompatible with fullscreen + if ((opt = miscParams->find("parentWindowHandle")) != end) + parent = (HWND)StringConverter::parseSizeT(opt->second); + + + // monitor index + if ((opt = miscParams->find("monitorIndex")) != end) + monitorIndex = StringConverter::parseInt(opt->second); + + // monitor handle + if ((opt = miscParams->find("monitorHandle")) != end) + hMonitor = (HMONITOR)StringConverter::parseInt(opt->second); + + // enable double click messages + if ((opt = miscParams->find("enableDoubleClick")) != end) + enableDoubleClick = StringConverter::parseBool(opt->second); + + } + + if (!mIsExternal) + { + DWORD dwStyleEx = 0; + MONITORINFOEX monitorInfoEx; + RECT rc; + + // If we didn't specified the adapter index, or if it didn't find it + if (hMonitor == NULL) + { + POINT windowAnchorPoint; + + // Fill in anchor point. + windowAnchorPoint.x = left; + windowAnchorPoint.y = top; + + + // Get the default primary monitor to this window. + hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY); + } + + // Get the target monitor info + memset(&monitorInfoEx, 0, sizeof(MONITORINFOEX)); + monitorInfoEx.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &monitorInfoEx); + + size_t devNameLen = strlen(monitorInfoEx.szDevice); + mDeviceName = new char[devNameLen + 1]; + + strcpy(mDeviceName, monitorInfoEx.szDevice); + + // Update window style flags. + mFullscreenWinStyle = (hidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN | WS_POPUP; + mWindowedWinStyle = (hidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN; + + if (parent) + { + mWindowedWinStyle |= WS_CHILD; + } + else + { + if (border == "none") + mWindowedWinStyle |= WS_POPUP; + else if (border == "fixed") + mWindowedWinStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | + WS_SYSMENU | WS_MINIMIZEBOX; + else + mWindowedWinStyle |= WS_OVERLAPPEDWINDOW; + + } + + + // No specified top left -> Center the window in the middle of the monitor + if (left == -1 || top == -1) + { + uint32 screenw = monitorInfoEx.rcWork.right - monitorInfoEx.rcWork.left; + uint32 screenh = monitorInfoEx.rcWork.bottom - monitorInfoEx.rcWork.top; + + uint32 winWidth, winHeight; + adjustWindow(width, height, &winWidth, &winHeight); + + // clamp window dimensions to screen size + uint32 outerw = (winWidth < screenw)? winWidth : screenw; + uint32 outerh = (winHeight < screenh)? winHeight : screenh; + + if (left == -1) + left = monitorInfoEx.rcWork.left + (screenw - outerw) / 2; + else if (monitorIndex != -1) + left += monitorInfoEx.rcWork.left; + + if (top == -1) + top = monitorInfoEx.rcWork.top + (screenh - outerh) / 2; + else if (monitorIndex != -1) + top += monitorInfoEx.rcWork.top; + } + else if (monitorIndex != -1) + { + left += monitorInfoEx.rcWork.left; + top += monitorInfoEx.rcWork.top; + } + + mWidth = width; + mHeight = height; + mTop = top; + mLeft = left; + + if (mIsFullScreen) + { + dwStyleEx |= WS_EX_TOPMOST; + mTop = monitorInfoEx.rcMonitor.top; + mLeft = monitorInfoEx.rcMonitor.left; + } + else + { + int screenw = GetSystemMetrics(SM_CXSCREEN); + int screenh = GetSystemMetrics(SM_CYSCREEN); + + if (!outerSize) + { + // Calculate window dimensions required + // to get the requested client area + SetRect(&rc, 0, 0, mWidth, mHeight); + AdjustWindowRect(&rc, getWindowStyle(fullScreen), false); + mWidth = rc.right - rc.left; + mHeight = rc.bottom - rc.top; + + // Clamp window rect to the default primary display monitor. + if (mLeft < monitorInfoEx.rcWork.left) + mLeft = monitorInfoEx.rcWork.left; + + if (mTop < monitorInfoEx.rcWork.top) + mTop = monitorInfoEx.rcWork.top; + + if ((int)mWidth > monitorInfoEx.rcWork.right - mLeft) + mWidth = monitorInfoEx.rcWork.right - mLeft; + + if ((int)mHeight > monitorInfoEx.rcWork.bottom - mTop) + mHeight = monitorInfoEx.rcWork.bottom - mTop; + } + } - UINT classStyle = CS_OWNDC; - if (enableDoubleClick) - classStyle |= CS_DBLCLKS; - - // register class and create window - WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst, - LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), - (HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "OgreGLWindow" }; - RegisterClass(&wc); - - if (mIsFullScreen) - { - DEVMODE displayDeviceMode; - - memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); - displayDeviceMode.dmSize = sizeof(DEVMODE); - displayDeviceMode.dmBitsPerPel = mColourDepth; - displayDeviceMode.dmPelsWidth = mWidth; - displayDeviceMode.dmPelsHeight = mHeight; - displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - - if (mDisplayFrequency) - { - displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; - displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) - { - LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); - displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; - } - } - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) - LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); - } - - // Pass pointer to self as WM_CREATE parameter - mHWnd = CreateWindowEx(dwStyleEx, "OgreGLWindow", title.c_str(), - getWindowStyle(fullScreen), mLeft, mTop, mWidth, mHeight, parent, 0, hInst, this); - - WindowEventUtilities::_addRenderWindow(this); - - LogManager::getSingleton().stream() - << "Created Win32Window '" - << mName << "' : " << mWidth << "x" << mHeight - << ", " << mColourDepth << "bpp"; - - } - - HDC old_hdc = wglGetCurrentDC(); - HGLRC old_context = wglGetCurrentContext(); - - RECT rc; - // top and left represent outer window position - GetWindowRect(mHWnd, &rc); - mTop = rc.top; - mLeft = rc.left; - // width and height represent drawable area only - GetClientRect(mHWnd, &rc); - mWidth = rc.right; - mHeight = rc.bottom; - - mHDC = GetDC(mHWnd); - - if (!mIsExternalGLControl) - { - int testFsaa = mFSAA; - bool testHwGamma = hwGamma; - bool formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); - if (!formatOk) - { - if (mFSAA > 0) - { - // try without FSAA - testFsaa = 0; - formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); - } - - if (!formatOk && hwGamma) - { - // try without sRGB - testHwGamma = false; - testFsaa = mFSAA; - formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); - } - - if (!formatOk && hwGamma && (mFSAA > 0)) - { - // try without both - testHwGamma = false; - testFsaa = 0; - formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); - } - - if (!formatOk) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "selectPixelFormat failed", "Win32Window::create"); - - } - // record what gamma option we used in the end - // this will control enabling of sRGB state flags when used - mHwGamma = testHwGamma; - mFSAA = testFsaa; - } - if (!mIsExternalGLContext) - { - mGlrc = wglCreateContext(mHDC); - if (!mGlrc) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "wglCreateContext failed: " + translateWGLError(), "Win32Window::create"); - } + UINT classStyle = CS_OWNDC; + if (enableDoubleClick) + classStyle |= CS_DBLCLKS; + + // register class and create window + WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst, + LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), + (HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "OgreGLWindow" }; + RegisterClass(&wc); + + if (mIsFullScreen) + { + DEVMODE displayDeviceMode; + + memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); + displayDeviceMode.dmSize = sizeof(DEVMODE); + displayDeviceMode.dmBitsPerPel = mColourDepth; + displayDeviceMode.dmPelsWidth = mWidth; + displayDeviceMode.dmPelsHeight = mHeight; + displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + + if (mDisplayFrequency) + { + displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; + displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) + { + LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); + displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; + } + } + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) + LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); + } + + // Pass pointer to self as WM_CREATE parameter + mHWnd = CreateWindowEx(dwStyleEx, "OgreGLWindow", title.c_str(), + getWindowStyle(fullScreen), mLeft, mTop, mWidth, mHeight, parent, 0, hInst, this); + + WindowEventUtilities::_addRenderWindow(this); + + LogManager::getSingleton().stream() + << "Created Win32Window '" + << mName << "' : " << mWidth << "x" << mHeight + << ", " << mColourDepth << "bpp"; + + } + + HDC old_hdc = wglGetCurrentDC(); + HGLRC old_context = wglGetCurrentContext(); + + RECT rc; + // top and left represent outer window position + GetWindowRect(mHWnd, &rc); + mTop = rc.top; + mLeft = rc.left; + // width and height represent drawable area only + GetClientRect(mHWnd, &rc); + mWidth = rc.right; + mHeight = rc.bottom; + + mHDC = GetDC(mHWnd); + + if (!mIsExternalGLControl) + { + int testFsaa = mFSAA; + bool testHwGamma = hwGamma; + bool formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); + if (!formatOk) + { + if (mFSAA > 0) + { + // try without FSAA + testFsaa = 0; + formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); + } + + if (!formatOk && hwGamma) + { + // try without sRGB + testHwGamma = false; + testFsaa = mFSAA; + formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); + } + + if (!formatOk && hwGamma && (mFSAA > 0)) + { + // try without both + testHwGamma = false; + testFsaa = 0; + formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); + } + + if (!formatOk) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "selectPixelFormat failed", "Win32Window::create"); + + } + // record what gamma option we used in the end + // this will control enabling of sRGB state flags when used + mHwGamma = testHwGamma; + mFSAA = testFsaa; + } + if (!mIsExternalGLContext) + { + mGlrc = wglCreateContext(mHDC); + if (!mGlrc) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "wglCreateContext failed: " + translateWGLError(), "Win32Window::create"); + } if (old_context && old_context != mGlrc) { // Share lists with old context - if (!wglShareLists(old_context, mGlrc)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglShareLists() failed", " Win32Window::create"); + if (!wglShareLists(old_context, mGlrc)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglShareLists() failed", " Win32Window::create"); } - if (!wglMakeCurrent(mHDC, mGlrc)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent", "Win32Window::create"); + if (!wglMakeCurrent(mHDC, mGlrc)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent", "Win32Window::create"); - // Do not change vsync if the external window has the OpenGL control - if (!mIsExternalGLControl) { - // Don't use wglew as if this is the first window, we won't have initialised yet - PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = - (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); - if (_wglSwapIntervalEXT) - _wglSwapIntervalEXT(mVSync? mVSyncInterval : 0); - } + // Do not change vsync if the external window has the OpenGL control + if (!mIsExternalGLControl) { + // Don't use wglew as if this is the first window, we won't have initialised yet + PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = + (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + if (_wglSwapIntervalEXT) + _wglSwapIntervalEXT(mVSync? mVSyncInterval : 0); + } if (old_context && old_context != mGlrc) { // Restore old context - if (!wglMakeCurrent(old_hdc, old_context)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent() failed", "Win32Window::create"); + if (!wglMakeCurrent(old_hdc, old_context)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent() failed", "Win32Window::create"); } - // Create RenderSystem context - mContext = new Win32Context(mHDC, mGlrc); - - mActive = true; - setHidden(hidden); - } - - void Win32Window::adjustWindow(unsigned int clientWidth, unsigned int clientHeight, - unsigned int* winWidth, unsigned int* winHeight) - { - // NB only call this for non full screen - RECT rc; - SetRect(&rc, 0, 0, clientWidth, clientHeight); - AdjustWindowRect(&rc, getWindowStyle(mIsFullScreen), false); - *winWidth = rc.right - rc.left; - *winHeight = rc.bottom - rc.top; - - // adjust to monitor - HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); - - // Get monitor info - MONITORINFO monitorInfo; - - memset(&monitorInfo, 0, sizeof(MONITORINFO)); - monitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hMonitor, &monitorInfo); - - LONG maxW = monitorInfo.rcWork.right - monitorInfo.rcWork.left; - LONG maxH = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; - - if (*winWidth > (unsigned int)maxW) - *winWidth = maxW; - if (*winHeight > (unsigned int)maxH) - *winHeight = maxH; - - } - - void Win32Window::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) - { - if (mIsFullScreen != fullScreen || width != mWidth || height != mHeight) - { - mIsFullScreen = fullScreen; - - if (mIsFullScreen) - { - - DEVMODE displayDeviceMode; - - memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); - displayDeviceMode.dmSize = sizeof(DEVMODE); - displayDeviceMode.dmBitsPerPel = mColourDepth; - displayDeviceMode.dmPelsWidth = width; - displayDeviceMode.dmPelsHeight = height; - displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - if (mDisplayFrequency) - { - displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; - displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; - - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, - CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) - { - LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); - displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; - } - } - else - { - // try a few - displayDeviceMode.dmDisplayFrequency = 100; - displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, - CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) - { - displayDeviceMode.dmDisplayFrequency = 75; - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, - CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) - { - displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; - } - } - - } - // move window to 0,0 before display switch - SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, mWidth, mHeight, SWP_NOACTIVATE); - - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) - LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); - - // Get the nearest monitor to this window. - HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); - - // Get monitor info - MONITORINFO monitorInfo; - - memset(&monitorInfo, 0, sizeof(MONITORINFO)); - monitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hMonitor, &monitorInfo); - - mTop = monitorInfo.rcMonitor.top; - mLeft = monitorInfo.rcMonitor.left; - - SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); - SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, width, height, - SWP_NOACTIVATE); - mWidth = width; - mHeight = height; - - - } - else - { - // drop out of fullscreen - ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); - - // calculate overall dimensions for requested client area - uint32 winWidth, winHeight; - adjustWindow(width, height, &winWidth, &winHeight); - - // deal with centering when switching down to smaller resolution - - HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); - MONITORINFO monitorInfo; - memset(&monitorInfo, 0, sizeof(MONITORINFO)); - monitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hMonitor, &monitorInfo); - - uint32 screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left; - uint32 screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; + // Create RenderSystem context + mContext = new Win32Context(mHDC, mGlrc); + + mActive = true; + setHidden(hidden); + } + + void Win32Window::adjustWindow(unsigned int clientWidth, unsigned int clientHeight, + unsigned int* winWidth, unsigned int* winHeight) + { + // NB only call this for non full screen + RECT rc; + SetRect(&rc, 0, 0, clientWidth, clientHeight); + AdjustWindowRect(&rc, getWindowStyle(mIsFullScreen), false); + *winWidth = rc.right - rc.left; + *winHeight = rc.bottom - rc.top; + + // adjust to monitor + HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); + + // Get monitor info + MONITORINFO monitorInfo; + + memset(&monitorInfo, 0, sizeof(MONITORINFO)); + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hMonitor, &monitorInfo); + + LONG maxW = monitorInfo.rcWork.right - monitorInfo.rcWork.left; + LONG maxH = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; + + if (*winWidth > (unsigned int)maxW) + *winWidth = maxW; + if (*winHeight > (unsigned int)maxH) + *winHeight = maxH; + + } + + void Win32Window::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) + { + if (mIsFullScreen != fullScreen || width != mWidth || height != mHeight) + { + mIsFullScreen = fullScreen; + + if (mIsFullScreen) + { + + DEVMODE displayDeviceMode; + + memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); + displayDeviceMode.dmSize = sizeof(DEVMODE); + displayDeviceMode.dmBitsPerPel = mColourDepth; + displayDeviceMode.dmPelsWidth = width; + displayDeviceMode.dmPelsHeight = height; + displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + if (mDisplayFrequency) + { + displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; + displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; + + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, + CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) + { + LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); + displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; + } + } + else + { + // try a few + displayDeviceMode.dmDisplayFrequency = 100; + displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, + CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) + { + displayDeviceMode.dmDisplayFrequency = 75; + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, + CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) + { + displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; + } + } + + } + // move window to 0,0 before display switch + SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, mWidth, mHeight, SWP_NOACTIVATE); + + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) + LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); + + // Get the nearest monitor to this window. + HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); + + // Get monitor info + MONITORINFO monitorInfo; + + memset(&monitorInfo, 0, sizeof(MONITORINFO)); + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hMonitor, &monitorInfo); + + mTop = monitorInfo.rcMonitor.top; + mLeft = monitorInfo.rcMonitor.left; + + SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); + SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, width, height, + SWP_NOACTIVATE); + mWidth = width; + mHeight = height; + + + } + else + { + // drop out of fullscreen + ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); + + // calculate overall dimensions for requested client area + uint32 winWidth, winHeight; + adjustWindow(width, height, &winWidth, &winHeight); + + // deal with centering when switching down to smaller resolution + + HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); + MONITORINFO monitorInfo; + memset(&monitorInfo, 0, sizeof(MONITORINFO)); + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hMonitor, &monitorInfo); + + uint32 screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left; + uint32 screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; - uint32 left = screenw > winWidth ? ((screenw - winWidth) / 2) : 0; - uint32 top = screenh > winHeight ? ((screenh - winHeight) / 2) : 0; + uint32 left = screenw > winWidth ? ((screenw - winWidth) / 2) : 0; + uint32 top = screenh > winHeight ? ((screenh - winHeight) / 2) : 0; - SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); - SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight, - SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE); - mWidth = width; - mHeight = height; + SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); + SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight, + SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE); + mWidth = width; + mHeight = height; - windowMovedOrResized(); + windowMovedOrResized(); - } + } - } - } + } + } - void Win32Window::destroy(void) - { - if (!mHWnd) - return; + void Win32Window::destroy(void) + { + if (!mHWnd) + return; - // Unregister and destroy OGRE GLContext - delete mContext; + // Unregister and destroy OGRE GLContext + delete mContext; mContext = 0; - if (!mIsExternalGLContext && mGlrc) - { - wglDeleteContext(mGlrc); - mGlrc = 0; - } - if (!mIsExternal) - { - WindowEventUtilities::_removeRenderWindow(this); - - if (mIsFullScreen) - ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); - DestroyWindow(mHWnd); - } - else - { - // just release the DC - ReleaseDC(mHWnd, mHDC); - } - - mActive = false; - mClosed = true; - mHDC = 0; // no release thanks to CS_OWNDC wndclass style - mHWnd = 0; - - if (mDeviceName != NULL) - { - delete[] mDeviceName; - mDeviceName = NULL; - } - - } - - - bool Win32Window::isActive(void) const - { - if (isFullScreen()) - return isVisible(); - - return mActive && isVisible(); - } - - bool Win32Window::isVisible() const - { - return (mHWnd && !IsIconic(mHWnd)); - } - - bool Win32Window::isClosed() const - { - return mClosed; - } - - void Win32Window::setHidden(bool hidden) - { - mHidden = hidden; - if (!mIsExternal) - { - if (hidden) - ShowWindow(mHWnd, SW_HIDE); - else - ShowWindow(mHWnd, SW_SHOWNORMAL); - } - } - - void Win32Window::setVSyncEnabled(bool vsync) - { - mVSync = vsync; - HDC old_hdc = wglGetCurrentDC(); - HGLRC old_context = wglGetCurrentContext(); - if (!wglMakeCurrent(mHDC, mGlrc)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent", "Win32Window::setVSyncEnabled"); - - // Do not change vsync if the external window has the OpenGL control - if (!mIsExternalGLControl) { - // Don't use wglew as if this is the first window, we won't have initialised yet - PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = - (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); - if (_wglSwapIntervalEXT) - _wglSwapIntervalEXT(mVSync? mVSyncInterval : 0); - } + if (!mIsExternalGLContext && mGlrc) + { + wglDeleteContext(mGlrc); + mGlrc = 0; + } + if (!mIsExternal) + { + WindowEventUtilities::_removeRenderWindow(this); + + if (mIsFullScreen) + ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); + DestroyWindow(mHWnd); + } + else + { + // just release the DC + ReleaseDC(mHWnd, mHDC); + } + + mActive = false; + mClosed = true; + mHDC = 0; // no release thanks to CS_OWNDC wndclass style + mHWnd = 0; + + if (mDeviceName != NULL) + { + delete[] mDeviceName; + mDeviceName = NULL; + } + + } + + + bool Win32Window::isActive(void) const + { + if (isFullScreen()) + return isVisible(); + + return mActive && isVisible(); + } + + bool Win32Window::isVisible() const + { + return (mHWnd && !IsIconic(mHWnd)); + } + + bool Win32Window::isClosed() const + { + return mClosed; + } + + void Win32Window::setHidden(bool hidden) + { + mHidden = hidden; + if (!mIsExternal) + { + if (hidden) + ShowWindow(mHWnd, SW_HIDE); + else + ShowWindow(mHWnd, SW_SHOWNORMAL); + } + } + + void Win32Window::setVSyncEnabled(bool vsync) + { + mVSync = vsync; + HDC old_hdc = wglGetCurrentDC(); + HGLRC old_context = wglGetCurrentContext(); + if (!wglMakeCurrent(mHDC, mGlrc)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent", "Win32Window::setVSyncEnabled"); + + // Do not change vsync if the external window has the OpenGL control + if (!mIsExternalGLControl) { + // Don't use wglew as if this is the first window, we won't have initialised yet + PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = + (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + if (_wglSwapIntervalEXT) + _wglSwapIntervalEXT(mVSync? mVSyncInterval : 0); + } if (old_context && old_context != mGlrc) { // Restore old context - if (!wglMakeCurrent(old_hdc, old_context)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent() failed", "Win32Window::setVSyncEnabled"); - } - } - - void Win32Window::setVSyncInterval(unsigned int interval) - { - mVSyncInterval = interval; - if (mVSync) - setVSyncEnabled(true); - } - - bool Win32Window::isVSyncEnabled() const - { - return mVSync; - } - - unsigned int Win32Window::getVSyncInterval() const - { - return mVSyncInterval; - } - - void Win32Window::reposition(int left, int top) - { - if (mHWnd && !mIsFullScreen) - { - SetWindowPos(mHWnd, 0, left, top, 0, 0, - SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - } - } - - void Win32Window::resize(unsigned int width, unsigned int height) - { - if (!mIsExternal) - { - if (mHWnd && !mIsFullScreen) - { - RECT rc = { 0, 0, width, height }; - AdjustWindowRect(&rc, getWindowStyle(mIsFullScreen), false); - width = rc.right - rc.left; - height = rc.bottom - rc.top; - SetWindowPos(mHWnd, 0, 0, 0, width, height, - SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); - } - } - else - updateWindowRect(); - } - - void Win32Window::windowMovedOrResized() - { - if (!mHWnd || IsIconic(mHWnd)) - return; - - updateWindowRect(); - } - - - void Win32Window::updateWindowRect() - { - RECT rc; - BOOL result; - - // Update top left parameters - result = GetWindowRect(mHWnd, &rc); - if (result == FALSE) - { - mTop = 0; - mLeft = 0; - mWidth = 0; - mHeight = 0; - return; - } - - mTop = rc.top; - mLeft = rc.left; - - // width and height represent drawable area only - result = GetClientRect(mHWnd, &rc); - if (result == FALSE) - { - mTop = 0; - mLeft = 0; - mWidth = 0; - mHeight = 0; - return; - } - unsigned int width = rc.right - rc.left; - unsigned int height = rc.bottom - rc.top; - - // Case window resized. - if (width != mWidth || height != mHeight) - { - mWidth = rc.right - rc.left; - mHeight = rc.bottom - rc.top; - - // Notify viewports of resize - ViewportList::iterator it = mViewportList.begin(); - while( it != mViewportList.end() ) - (*it++).second->_updateDimensions(); - } - } - - - void Win32Window::swapBuffers() - { - if (!mIsExternalGLControl) { - SwapBuffers(mHDC); - } - } - - void Win32Window::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) - { - if ((dst.left < 0) || (dst.right > mWidth) || - (dst.top < 0) || (dst.bottom > mHeight) || - (dst.front != 0) || (dst.back != 1)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid box.", - "Win32Window::copyContentsToMemory" ); - } - - if (buffer == FB_AUTO) - { - buffer = mIsFullScreen? FB_FRONT : FB_BACK; - } - - GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format); - GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format); - - if ((format == GL_NONE) || (type == 0)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unsupported format.", - "Win32Window::copyContentsToMemory" ); - } - - - // Switch context if different from current one - RenderSystem* rsys = Root::getSingleton().getRenderSystem(); - rsys->_setViewport(this->getViewport(0)); + if (!wglMakeCurrent(old_hdc, old_context)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent() failed", "Win32Window::setVSyncEnabled"); + } + } + + void Win32Window::setVSyncInterval(unsigned int interval) + { + mVSyncInterval = interval; + if (mVSync) + setVSyncEnabled(true); + } + + bool Win32Window::isVSyncEnabled() const + { + return mVSync; + } + + unsigned int Win32Window::getVSyncInterval() const + { + return mVSyncInterval; + } + + void Win32Window::reposition(int left, int top) + { + if (mHWnd && !mIsFullScreen) + { + SetWindowPos(mHWnd, 0, left, top, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + + void Win32Window::resize(unsigned int width, unsigned int height) + { + if (!mIsExternal) + { + if (mHWnd && !mIsFullScreen) + { + RECT rc = { 0, 0, width, height }; + AdjustWindowRect(&rc, getWindowStyle(mIsFullScreen), false); + width = rc.right - rc.left; + height = rc.bottom - rc.top; + SetWindowPos(mHWnd, 0, 0, 0, width, height, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + else + updateWindowRect(); + } + + void Win32Window::windowMovedOrResized() + { + if (!mHWnd || IsIconic(mHWnd)) + return; + + updateWindowRect(); + } + + + void Win32Window::updateWindowRect() + { + RECT rc; + BOOL result; + + // Update top left parameters + result = GetWindowRect(mHWnd, &rc); + if (result == FALSE) + { + mTop = 0; + mLeft = 0; + mWidth = 0; + mHeight = 0; + return; + } + + mTop = rc.top; + mLeft = rc.left; + + // width and height represent drawable area only + result = GetClientRect(mHWnd, &rc); + if (result == FALSE) + { + mTop = 0; + mLeft = 0; + mWidth = 0; + mHeight = 0; + return; + } + unsigned int width = rc.right - rc.left; + unsigned int height = rc.bottom - rc.top; + + // Case window resized. + if (width != mWidth || height != mHeight) + { + mWidth = rc.right - rc.left; + mHeight = rc.bottom - rc.top; + + // Notify viewports of resize + ViewportList::iterator it = mViewportList.begin(); + while( it != mViewportList.end() ) + (*it++).second->_updateDimensions(); + } + } + + + void Win32Window::swapBuffers() + { + if (!mIsExternalGLControl) { + SwapBuffers(mHDC); + } + } + + void Win32Window::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) + { + if ((dst.left < 0) || (dst.right > mWidth) || + (dst.top < 0) || (dst.bottom > mHeight) || + (dst.front != 0) || (dst.back != 1)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid box.", + "Win32Window::copyContentsToMemory" ); + } + + if (buffer == FB_AUTO) + { + buffer = mIsFullScreen? FB_FRONT : FB_BACK; + } + + GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format); + GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format); + + if ((format == GL_NONE) || (type == 0)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Unsupported format.", + "Win32Window::copyContentsToMemory" ); + } + + + // Switch context if different from current one + RenderSystem* rsys = Root::getSingleton().getRenderSystem(); + rsys->_setViewport(this->getViewport(0)); if(dst.getWidth() != dst.rowPitch) glPixelStorei(GL_PACK_ROW_LENGTH, dst.rowPitch); - // Must change the packing to ensure no overruns! - glPixelStorei(GL_PACK_ALIGNMENT, 1); + // Must change the packing to ensure no overruns! + glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); + glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); glReadPixels((GLint)0, (GLint)(mHeight - dst.getHeight()), (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(), format, type, dst.getTopLeftFrontPixelPtr()); - // restore default alignment - glPixelStorei(GL_PACK_ALIGNMENT, 4); + // restore default alignment + glPixelStorei(GL_PACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ROW_LENGTH, 0); PixelUtil::bulkPixelVerticalFlip(dst); - } - - void Win32Window::getCustomAttribute( const String& name, void* pData ) - { - if( name == "GLCONTEXT" ) { - *static_cast(pData) = mContext; - return; - } else if( name == "WINDOW" ) - { - HWND *pHwnd = (HWND*)pData; - *pHwnd = getWindowHandle(); - return; - } - else if( name == "GLRC" ) - { - HGLRC *pGlrc = (HGLRC*)pData; - *pGlrc = mContext->getGlrc(); - return; - } - } - - void Win32Window::setActive( bool state ) - { - if (mDeviceName != NULL && state == false) - { - HWND hActiveWindow = GetActiveWindow(); - char classNameSrc[_MAX_CLASS_NAME_ + 1]; - char classNameDst[_MAX_CLASS_NAME_ + 1]; - - GetClassName(mHWnd, classNameSrc, _MAX_CLASS_NAME_); - GetClassName(hActiveWindow, classNameDst, _MAX_CLASS_NAME_); - - if (strcmp(classNameDst, classNameSrc) == 0) - { - state = true; - } - } - - mActive = state; - - if( mIsFullScreen ) - { - if( state == false ) - { //Restore Desktop - ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); - ShowWindow(mHWnd, SW_SHOWMINNOACTIVE); - } - else - { //Restore App - ShowWindow(mHWnd, SW_SHOWNORMAL); - - DEVMODE displayDeviceMode; - - memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); - displayDeviceMode.dmSize = sizeof(DEVMODE); - displayDeviceMode.dmBitsPerPel = mColourDepth; - displayDeviceMode.dmPelsWidth = mWidth; - displayDeviceMode.dmPelsHeight = mHeight; - displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - if (mDisplayFrequency) - { - displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; - displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; - } - ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL); - } - } - } + } + + void Win32Window::getCustomAttribute( const String& name, void* pData ) + { + if( name == "GLCONTEXT" ) { + *static_cast(pData) = mContext; + return; + } else if( name == "WINDOW" ) + { + HWND *pHwnd = (HWND*)pData; + *pHwnd = getWindowHandle(); + return; + } + else if( name == "GLRC" ) + { + HGLRC *pGlrc = (HGLRC*)pData; + *pGlrc = mContext->getGlrc(); + return; + } + } + + void Win32Window::setActive( bool state ) + { + if (mDeviceName != NULL && state == false) + { + HWND hActiveWindow = GetActiveWindow(); + char classNameSrc[_MAX_CLASS_NAME_ + 1]; + char classNameDst[_MAX_CLASS_NAME_ + 1]; + + GetClassName(mHWnd, classNameSrc, _MAX_CLASS_NAME_); + GetClassName(hActiveWindow, classNameDst, _MAX_CLASS_NAME_); + + if (strcmp(classNameDst, classNameSrc) == 0) + { + state = true; + } + } + + mActive = state; + + if( mIsFullScreen ) + { + if( state == false ) + { //Restore Desktop + ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); + ShowWindow(mHWnd, SW_SHOWMINNOACTIVE); + } + else + { //Restore App + ShowWindow(mHWnd, SW_SHOWNORMAL); + + DEVMODE displayDeviceMode; + + memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); + displayDeviceMode.dmSize = sizeof(DEVMODE); + displayDeviceMode.dmBitsPerPel = mColourDepth; + displayDeviceMode.dmPelsWidth = mWidth; + displayDeviceMode.dmPelsHeight = mHeight; + displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + if (mDisplayFrequency) + { + displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; + displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; + } + ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL); + } + } + } } diff --git a/RenderSystems/GL/src/atifs/include/ATI_FS_GLGpuProgram.h b/RenderSystems/GL/src/atifs/include/ATI_FS_GLGpuProgram.h index f64f63fe811..598d87553b3 100644 --- a/RenderSystems/GL/src/atifs/include/ATI_FS_GLGpuProgram.h +++ b/RenderSystems/GL/src/atifs/include/ATI_FS_GLGpuProgram.h @@ -34,37 +34,37 @@ THE SOFTWARE. namespace Ogre { - /** Specialisation of the GL low-level program for ATI Fragment Shader programs. */ - class _OgreGLExport ATI_FS_GLGpuProgram : public GLGpuProgram - { - public: + /** Specialisation of the GL low-level program for ATI Fragment Shader programs. */ + class _OgreGLExport ATI_FS_GLGpuProgram : public GLGpuProgram + { + public: ATI_FS_GLGpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - virtual ~ATI_FS_GLGpuProgram(); + virtual ~ATI_FS_GLGpuProgram(); - /// Execute the binding functions for this program - void bindProgram(void); - /// Execute the unbinding functions for this program - void unbindProgram(void); - /// Execute the param binding functions for this program - void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask); - /** Execute the pass iteration param binding functions for this program. + /// Execute the binding functions for this program + void bindProgram(void); + /// Execute the unbinding functions for this program + void unbindProgram(void); + /// Execute the param binding functions for this program + void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask); + /** Execute the pass iteration param binding functions for this program. Only binds those parameters used for multipass rendering */ void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params); - /// Get the assigned GL program id - GLuint getProgramID(void) const - { return mProgramID; } + /// Get the assigned GL program id + GLuint getProgramID(void) const + { return mProgramID; } - protected: - /// @copydoc Resource::unload - void unloadImpl(void); - void loadFromSource(void); + protected: + /// @copydoc Resource::unload + void unloadImpl(void); + void loadFromSource(void); - }; // class ATI_FS_GLGpuProgram + }; // class ATI_FS_GLGpuProgram diff --git a/RenderSystems/GL/src/atifs/include/Compiler2Pass.h b/RenderSystems/GL/src/atifs/include/Compiler2Pass.h index 39872bbbfa1..ea288a40659 100644 --- a/RenderSystems/GL/src/atifs/include/Compiler2Pass.h +++ b/RenderSystems/GL/src/atifs/include/Compiler2Pass.h @@ -35,7 +35,7 @@ THE SOFTWARE. #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min #endif #include #endif @@ -49,230 +49,230 @@ typedef unsigned int uint; /** Compiler2Pass is a generic compiler/assembler @remarks - provides a tokenizer in pass 1 and relies on the subclass to provide the virtual method for pass 2 + provides a tokenizer in pass 1 and relies on the subclass to provide the virtual method for pass 2 - PASS 1 - tokenize source: this is a simple brute force lexical scanner/analyzer that also parses - the formed token for proper semantics and context in one pass - it uses Look Ahead Left-Right (LALR) ruling based on Backus - Naur From notation for semantic - checking and also performs context checking allowing for language dialects + PASS 1 - tokenize source: this is a simple brute force lexical scanner/analyzer that also parses + the formed token for proper semantics and context in one pass + it uses Look Ahead Left-Right (LALR) ruling based on Backus - Naur From notation for semantic + checking and also performs context checking allowing for language dialects - PASS 2 - generate application specific instructions ie native instructions + PASS 2 - generate application specific instructions ie native instructions @par - this class must be subclassed with the subclass providing implementation for Pass 2. The subclass - is responsible for setting up the token libraries along with defining the language syntax. + this class must be subclassed with the subclass providing implementation for Pass 2. The subclass + is responsible for setting up the token libraries along with defining the language syntax. */ class Compiler2Pass { protected: - // BNF operation types - enum OperationType {otRULE, otAND, otOR, otOPTIONAL, otREPEAT, otEND}; + // BNF operation types + enum OperationType {otRULE, otAND, otOR, otOPTIONAL, otREPEAT, otEND}; - /** structure used to build rule paths + /** structure used to build rule paths - */ - struct TokenRule { - OperationType mOperation; - uint mTokenID; - const char* mSymbol; - uint mErrorID; + */ + struct TokenRule { + OperationType mOperation; + uint mTokenID; + const char* mSymbol; + uint mErrorID; - }; + }; - /** structure used to build Symbol Type library */ - struct SymbolDef { - uint mID; // Token ID which is the index into the Token Type library - uint mPass2Data; // data used by pass 2 to build native instructions + /** structure used to build Symbol Type library */ + struct SymbolDef { + uint mID; // Token ID which is the index into the Token Type library + uint mPass2Data; // data used by pass 2 to build native instructions - uint mContextKey; // context key to fit the Active Context - uint mContextPatternSet; // new pattern to set for Active Context bits - uint mContextPatternClear;// Contexts bits to clear Active Context bits + uint mContextKey; // context key to fit the Active Context + uint mContextPatternSet; // new pattern to set for Active Context bits + uint mContextPatternClear;// Contexts bits to clear Active Context bits - int mDefTextID; // index into text table for default name : set at runtime - uint mRuleID; // index into Rule database for non-terminal took rulepath - // if RuleID is zero the token is terminal + int mDefTextID; // index into text table for default name : set at runtime + uint mRuleID; // index into Rule database for non-terminal took rulepath + // if RuleID is zero the token is terminal - }; + }; - /** structure for Token instructions */ - struct TokenInst { - uint mNTTRuleID; // Non-Terminal Token Rule ID that generated Token - uint mID; // Token ID - int mLine; // line number in source code where Token was found - int mPos; // Character position in source where Token was found + /** structure for Token instructions */ + struct TokenInst { + uint mNTTRuleID; // Non-Terminal Token Rule ID that generated Token + uint mID; // Token ID + int mLine; // line number in source code where Token was found + int mPos; // Character position in source where Token was found - }; + }; - typedef std::vector TokenInstContainer; - //typedef TokenInstContainer::iterator TokenInstIterator; + typedef std::vector TokenInstContainer; + //typedef TokenInstContainer::iterator TokenInstIterator; - /// container for Tokens extracted from source - TokenInstContainer mTokenInstructions; + /// container for Tokens extracted from source + TokenInstContainer mTokenInstructions; - /// pointer to the source to be compiled - const char* mSource; - int mEndOfSource; - - /// pointers to Text and Token Type libraries setup by subclass - SymbolDef* mSymbolTypeLib; + /// pointer to the source to be compiled + const char* mSource; + int mEndOfSource; + + /// pointers to Text and Token Type libraries setup by subclass + SymbolDef* mSymbolTypeLib; - /// pointer to root rule path - has to be set by subclass constructor - TokenRule* mRootRulePath; + /// pointer to root rule path - has to be set by subclass constructor + TokenRule* mRootRulePath; - /// number of entries in Text and Token Type libraries - int mRulePathLibCnt; - int mSymbolTypeLibCnt; + /// number of entries in Text and Token Type libraries + int mRulePathLibCnt; + int mSymbolTypeLibCnt; - /// mVauleID needs to be initialized by the subclass before compiling occurs - /// it defines the token ID used in the symbol type library - uint mValueID; + /// mVauleID needs to be initialized by the subclass before compiling occurs + /// it defines the token ID used in the symbol type library + uint mValueID; - /// storage container for constants defined in source - std::vector mConstants; + /// storage container for constants defined in source + std::vector mConstants; - /// Active Contexts pattern used in pass 1 to determine which tokens are valid for a certain context - uint mActiveContexts; + /// Active Contexts pattern used in pass 1 to determine which tokens are valid for a certain context + uint mActiveContexts; - /** check token semantics between ID1 and ID2 using left/right semantic data in Token Type library - @param ID1 token ID on the left - @param ID2 token ID on the right - @return - true if both will bind to each other - false if either fails the semantic bind test + /** check token semantics between ID1 and ID2 using left/right semantic data in Token Type library + @param ID1 token ID on the left + @param ID2 token ID on the right + @return + true if both will bind to each other + false if either fails the semantic bind test - */ - //bool checkTokenSemantics(uint ID1, uint ID2); + */ + //bool checkTokenSemantics(uint ID1, uint ID2); - /** perform pass 1 of compile process - scans source for symbols that can be tokenized and then - performs general semantic and context verification on each symbol before it is tokenized. - A tokenized instruction list is built to be used by Pass 2. + /** perform pass 1 of compile process + scans source for symbols that can be tokenized and then + performs general semantic and context verification on each symbol before it is tokenized. + A tokenized instruction list is built to be used by Pass 2. - */ - bool doPass1(); + */ + bool doPass1(); - /** pure virtual method that must be set up by subclass to perform Pass 2 of compile process - @remark - Pass 2 is for the subclass to take the token instructions generated in Pass 1 and - build the application specific instructions along with verifying - symantic and context rules that could not be checked in Pass 1 + /** pure virtual method that must be set up by subclass to perform Pass 2 of compile process + @remark + Pass 2 is for the subclass to take the token instructions generated in Pass 1 and + build the application specific instructions along with verifying + symantic and context rules that could not be checked in Pass 1 - */ - virtual bool doPass2() = 0; + */ + virtual bool doPass2() = 0; - void findEOL(); + void findEOL(); - /** get the text symbol for this token - @remark - mainly used for debugging and in test routines - @param sid is the token ID - @return a pointer to the string text - */ - const char* getTypeDefText(const uint sid); + /** get the text symbol for this token + @remark + mainly used for debugging and in test routines + @param sid is the token ID + @return a pointer to the string text + */ + const char* getTypeDefText(const uint sid); - /** check to see if the text at the present position in the source is a numerical constant - @param fvalue is a reference that will receive the float value that is in the source - @param charsize reference to receive number of characters that make of the value in the source - @return - true if characters form a valid float representation - false if a number value could not be extracted - */ - bool isFloatValue(float & fvalue, int & charsize); + /** check to see if the text at the present position in the source is a numerical constant + @param fvalue is a reference that will receive the float value that is in the source + @param charsize reference to receive number of characters that make of the value in the source + @return + true if characters form a valid float representation + false if a number value could not be extracted + */ + bool isFloatValue(float & fvalue, int & charsize); - /** check to see if the text is in the symbol text library - @param symbol points to beginning of text where a symbol token might exist - @param symbolsize reference that will receive the size value of the symbol found - @return - true if a matching token could be found in the token type library - false if could not be tokenized - */ - bool isSymbol(const char* symbol, int & symbolsize); + /** check to see if the text is in the symbol text library + @param symbol points to beginning of text where a symbol token might exist + @param symbolsize reference that will receive the size value of the symbol found + @return + true if a matching token could be found in the token type library + false if could not be tokenized + */ + bool isSymbol(const char* symbol, int & symbolsize); - /// position to the next possible valid sysmbol - bool positionToNextSymbol(); + /// position to the next possible valid sysmbol + bool positionToNextSymbol(); - /** process input source text using rulepath to determine allowed tokens - @remarks - the method is reentrant and recursive - if a non-terminal token is encountered in the current rule path then the method is - called using the new rule path referenced by the non-terminal token - Tokens can have the following operation states which effects the flow path of the rule - RULE: defines a rule path for the non-terminal token - AND: the token is required for the rule to pass - OR: if the previous tokens failed then try these ones - OPTIONAL: the token is optional and does not cause the rule to fail if the token is not found - REPEAT: the token is required but there can be more than one in a sequence - END: end of the rule path - the method returns the succuss of the rule + /** process input source text using rulepath to determine allowed tokens + @remarks + the method is reentrant and recursive + if a non-terminal token is encountered in the current rule path then the method is + called using the new rule path referenced by the non-terminal token + Tokens can have the following operation states which effects the flow path of the rule + RULE: defines a rule path for the non-terminal token + AND: the token is required for the rule to pass + OR: if the previous tokens failed then try these ones + OPTIONAL: the token is optional and does not cause the rule to fail if the token is not found + REPEAT: the token is required but there can be more than one in a sequence + END: end of the rule path - the method returns the succuss of the rule - @param rulepathIDX index into to array of Token Rules that define a rule path to be processed - @return - true if rule passed - all required tokens found - false if one or more tokens required to complete the rule were not found - */ - bool processRulePath( uint rulepathIDX); + @param rulepathIDX index into to array of Token Rules that define a rule path to be processed + @return + true if rule passed - all required tokens found + false if one or more tokens required to complete the rule were not found + */ + bool processRulePath( uint rulepathIDX); - // setup ActiveContexts - should be called by subclass to setup initial language contexts - void setActiveContexts(const uint contexts){ mActiveContexts = contexts; } + // setup ActiveContexts - should be called by subclass to setup initial language contexts + void setActiveContexts(const uint contexts){ mActiveContexts = contexts; } - /// comment specifiers are hard coded - void skipComments(); + /// comment specifiers are hard coded + void skipComments(); - /// find end of line marker and move past it - void skipEOL(); - - /// skip all the white space which includes spaces and tabs - void skipWhiteSpace(); - - - /** check if current position in source has the symbol text equivalent to the TokenID - @param rulepathIDX index into rule path database of token to validate - @param activeRuleID index of non-terminal rule that generated the token - @return - true if token was found - false if token symbol text does not match the source text - if token is non-terminal then processRulePath is called - */ - bool ValidateToken(const uint rulepathIDX, const uint activeRuleID); + /// find end of line marker and move past it + void skipEOL(); + + /// skip all the white space which includes spaces and tabs + void skipWhiteSpace(); + + + /** check if current position in source has the symbol text equivalent to the TokenID + @param rulepathIDX index into rule path database of token to validate + @param activeRuleID index of non-terminal rule that generated the token + @return + true if token was found + false if token symbol text does not match the source text + if token is non-terminal then processRulePath is called + */ + bool ValidateToken(const uint rulepathIDX, const uint activeRuleID); public: - // ** these probably should not be public - int mCurrentLine; - int mCharPos; + // ** these probably should not be public + int mCurrentLine; + int mCharPos; - /// constructor - Compiler2Pass(); + /// constructor + Compiler2Pass(); virtual ~Compiler2Pass() {} - /** compile the source - performs 2 passes - first pass is to tokinize, check semantics and context - second pass is performed by subclass and converts tokens to application specific instructions - @remark - Pass 2 only gets executed if Pass 1 has no errors - @param source a pointer to the source text to be compiled - @return - true if Pass 1 and Pass 2 are successful - false if any errors occur in Pass 1 or Pass 2 - */ - bool compile(const char* source); - - /** Initialize the type library with matching symbol text found in symbol text library - find a default text for all Symbol Types in library - - scan through all the rules and initialize TypeLib with index to text and index to rules for non-terminal tokens - - must be called by subclass after libraries and rule database setup - */ - - void InitSymbolTypeLib(); + /** compile the source - performs 2 passes + first pass is to tokinize, check semantics and context + second pass is performed by subclass and converts tokens to application specific instructions + @remark + Pass 2 only gets executed if Pass 1 has no errors + @param source a pointer to the source text to be compiled + @return + true if Pass 1 and Pass 2 are successful + false if any errors occur in Pass 1 or Pass 2 + */ + bool compile(const char* source); + + /** Initialize the type library with matching symbol text found in symbol text library + find a default text for all Symbol Types in library + + scan through all the rules and initialize TypeLib with index to text and index to rules for non-terminal tokens + + must be called by subclass after libraries and rule database setup + */ + + void InitSymbolTypeLib(); }; diff --git a/RenderSystems/GL/src/atifs/include/ps_1_4.h b/RenderSystems/GL/src/atifs/include/ps_1_4.h index b23e33efb70..27e3eae0a3a 100644 --- a/RenderSystems/GL/src/atifs/include/ps_1_4.h +++ b/RenderSystems/GL/src/atifs/include/ps_1_4.h @@ -28,18 +28,18 @@ THE SOFTWARE. /** - A number of invaluable references were used to put together this ps.1.x compiler for ATI_fragment_shader execution - - References: - 1. MSDN: DirectX 8.1 Reference - 2. Wolfgang F. Engel "Fundamentals of Pixel Shaders - Introduction to Shader Programming Part III" on gamedev.net - 3. Martin Ecker - XEngine - 4. Shawn Kirst - ps14toATIfs - 5. Jason L. Mitchell "Real-Time 3D Graphics With Pixel Shaders" - 6. Jason L. Mitchell "1.4 Pixel Shaders" - 7. Jason L. Mitchell and Evan Hart "Hardware Shading with EXT_vertex_shader and ATI_fragment_shader" - 6. ATI 8500 SDK - 7. GL_ATI_fragment_shader extension reference + A number of invaluable references were used to put together this ps.1.x compiler for ATI_fragment_shader execution + + References: + 1. MSDN: DirectX 8.1 Reference + 2. Wolfgang F. Engel "Fundamentals of Pixel Shaders - Introduction to Shader Programming Part III" on gamedev.net + 3. Martin Ecker - XEngine + 4. Shawn Kirst - ps14toATIfs + 5. Jason L. Mitchell "Real-Time 3D Graphics With Pixel Shaders" + 6. Jason L. Mitchell "1.4 Pixel Shaders" + 7. Jason L. Mitchell and Evan Hart "Hardware Shading with EXT_vertex_shader and ATI_fragment_shader" + 6. ATI 8500 SDK + 7. GL_ATI_fragment_shader extension reference */ //--------------------------------------------------------------------------- @@ -75,288 +75,288 @@ THE SOFTWARE. /** Subclasses Compiler2Pass to provide a ps_1_x compiler that takes DirectX pixel shader assembly - and converts it to a form that can be used by ATI_fragment_shader OpenGL API + and converts it to a form that can be used by ATI_fragment_shader OpenGL API @remarks - all ps_1_1, ps_1_2, ps_1_3, ps_1_4 assembly instructions are recognized but not all are passed - on to ATI_fragment_shader. ATI_fragment_shader does not have an equivalent directive for - texkill or texdepth instructions. + all ps_1_1, ps_1_2, ps_1_3, ps_1_4 assembly instructions are recognized but not all are passed + on to ATI_fragment_shader. ATI_fragment_shader does not have an equivalent directive for + texkill or texdepth instructions. - The user must provide the GL binding interfaces. + The user must provide the GL binding interfaces. - A Test method is provided to verify the basic operation of the compiler which outputs the test - results to a file. + A Test method is provided to verify the basic operation of the compiler which outputs the test + results to a file. */ class PS_1_4 : public Compiler2Pass{ private: - enum RWAflags {rwa_NONE = 0, rwa_READ = 1, rwa_WRITE = 2}; - - enum MachineInstID {mi_COLOROP1, mi_COLOROP2, mi_COLOROP3, mi_ALPHAOP1, mi_ALPHAOP2, - mi_ALPHAOP3, mi_SETCONSTANTS, mi_PASSTEXCOORD, mi_SAMPLEMAP, mi_TEX, - mi_TEXCOORD, mi_TEXREG2RGB, mi_NOP - }; - - struct TokenInstType{ - char* Name; - GLuint ID; - - }; - - struct RegisterUsage { - bool Phase1Write; - bool Phase2Write; - }; - - // Token ID enumeration - enum SymbolID { - // Terminal Tokens section - - // DirectX pixel shader source formats - sid_PS_1_4, sid_PS_1_1, sid_PS_1_2, sid_PS_1_3, - - // PS_BASE - sid_C0, sid_C1, sid_C2, sid_C3, sid_C4, sid_C5, sid_C6, sid_C7, - sid_V0, sid_V1, - sid_ADD, sid_SUB, sid_MUL, sid_MAD, sid_LRP, sid_MOV, sid_CMP, sid_CND, - sid_DP3, sid_DP4, sid_DEF, - sid_R, sid_RA, sid_G, sid_GA, sid_B, sid_BA, sid_A, sid_RGBA, sid_RGB, - sid_RG, sid_RGA, sid_RB, sid_RBA, sid_GB, sid_GBA, - sid_RRRR, sid_GGGG, sid_BBBB, sid_AAAA, - sid_X2, sid_X4, sid_D2, sid_SAT, - sid_BIAS, sid_INVERT, sid_NEGATE, sid_BX2, - sid_COMMA, sid_VALUE, - - //PS_1_4 sid - sid_R0, sid_R1, sid_R2, sid_R3, sid_R4, sid_R5, - sid_T0, sid_T1, sid_T2, sid_T3, sid_T4, sid_T5, - sid_DP2ADD, - sid_X8, sid_D8, sid_D4, - sid_TEXCRD, sid_TEXLD, - sid_STR, sid_STQ, - sid_STRDR, sid_STQDQ, - sid_BEM, - sid_PHASE, - - //PS_1_1 sid - sid_1R0, sid_1R1, sid_1T0, sid_1T1, sid_1T2, sid_1T3, - sid_TEX, sid_TEXCOORD, sid_TEXM3X2PAD, - sid_TEXM3X2TEX, sid_TEXM3X3PAD, sid_TEXM3X3TEX, sid_TEXM3X3SPEC, sid_TEXM3X3VSPEC, - sid_TEXREG2AR, sid_TEXREG2GB, - - //PS_1_2 side - sid_TEXREG2RGB, sid_TEXDP3, sid_TEXDP3TEX, - - // common - sid_SKIP, sid_PLUS, - - // non-terminal tokens section - sid_PROGRAM, sid_PROGRAMTYPE, sid_DECLCONSTS, sid_DEFCONST, - sid_CONSTANT, sid_COLOR, - sid_TEXSWIZZLE, sid_UNARYOP, - sid_NUMVAL, sid_SEPERATOR, sid_ALUOPS, sid_TEXMASK, sid_TEXOP_PS1_1_3, - sid_TEXOP_PS1_4, - sid_ALU_STATEMENT, sid_DSTMODSAT, sid_UNARYOP_ARGS, sid_REG_PS1_4, - sid_TEX_PS1_4, sid_REG_PS1_1_3, sid_TEX_PS1_1_3, sid_DSTINFO, - sid_SRCINFO, sid_BINARYOP_ARGS, sid_TERNARYOP_ARGS, sid_TEMPREG, - sid_DSTMASK, sid_PRESRCMOD, sid_SRCNAME, sid_SRCREP, sid_POSTSRCMOD, - sid_DSTMOD, sid_DSTSAT, sid_BINARYOP, sid_TERNARYOP, - sid_TEXOPS_PHASE1, sid_COISSUE, sid_PHASEMARKER, sid_TEXOPS_PHASE2, - sid_TEXREG_PS1_4, sid_TEXOPS_PS1_4, sid_TEXOPS_PS1_1_3, sid_TEXCISCOP_PS1_1_3, - - - // last token - sid_INVALID = BAD_TOKEN // must be last in enumeration - }; - - /// structure used to keep track of arguments and instruction parameters - struct OpParram { - GLuint Arg; // type of argument - bool Filled; // has it been filled yet - GLuint MaskRep; // Mask/Replicator flags - GLuint Mod; // argument modifier - }; - - typedef std::vector MachineInstContainer; - //typedef MachineInstContainer::iterator MachineInstIterator; - - - // there are 2 phases with 2 subphases each - enum PhaseType {ptPHASE1TEX, ptPHASE1ALU, ptPHASE2TEX, ptPHASE2ALU }; - - struct RegModOffset { - uint MacroOffset; - uint RegisterBase; - uint OpParramsIndex; - }; - - struct MacroRegModify { - TokenInst * Macro; - uint MacroSize; - RegModOffset * RegMods; - uint RegModSize; - - }; - - #define R_BASE static_cast((sid_R0 - GL_REG_0_ATI)) - #define C_BASE static_cast((sid_C0 - GL_CON_0_ATI)) - #define T_BASE static_cast((sid_1T0 - GL_REG_0_ATI)) - - // static library database for tokens and BNF rules - static SymbolDef PS_1_4_SymbolTypeLib[]; - static TokenRule PS_1_x_RulePath[]; - static bool LibInitialized; - - // Static Macro database for ps.1.1 ps.1.2 ps.1.3 instructions - - static TokenInst texreg2ar[]; - static RegModOffset texreg2xx_RegMods[]; - static MacroRegModify texreg2ar_MacroMods; - - static TokenInst texreg2gb[]; - static MacroRegModify texreg2gb_MacroMods; - - static TokenInst texdp3[]; - static RegModOffset texdp3_RegMods[]; - static MacroRegModify texdp3_MacroMods; - - static TokenInst texdp3tex[]; - static RegModOffset texdp3tex_RegMods[]; - static MacroRegModify texdp3tex_MacroMods; - - static TokenInst texm3x2pad[]; - static RegModOffset texm3xxpad_RegMods[]; - static MacroRegModify texm3x2pad_MacroMods; - - static TokenInst texm3x2tex[]; - static RegModOffset texm3xxtex_RegMods[]; - static MacroRegModify texm3x2tex_MacroMods; - - static TokenInst texm3x3pad[]; - static MacroRegModify texm3x3pad_MacroMods; - - static TokenInst texm3x3tex[]; - static MacroRegModify texm3x3tex_MacroMods; - - static TokenInst texm3x3spec[]; - static RegModOffset texm3x3spec_RegMods[]; - static MacroRegModify texm3x3spec_MacroMods; - - static TokenInst texm3x3vspec[]; - static RegModOffset texm3x3vspec_RegMods[]; - static MacroRegModify texm3x3vspec_MacroMods; + enum RWAflags {rwa_NONE = 0, rwa_READ = 1, rwa_WRITE = 2}; + + enum MachineInstID {mi_COLOROP1, mi_COLOROP2, mi_COLOROP3, mi_ALPHAOP1, mi_ALPHAOP2, + mi_ALPHAOP3, mi_SETCONSTANTS, mi_PASSTEXCOORD, mi_SAMPLEMAP, mi_TEX, + mi_TEXCOORD, mi_TEXREG2RGB, mi_NOP + }; + + struct TokenInstType{ + char* Name; + GLuint ID; + + }; + + struct RegisterUsage { + bool Phase1Write; + bool Phase2Write; + }; + + // Token ID enumeration + enum SymbolID { + // Terminal Tokens section + + // DirectX pixel shader source formats + sid_PS_1_4, sid_PS_1_1, sid_PS_1_2, sid_PS_1_3, + + // PS_BASE + sid_C0, sid_C1, sid_C2, sid_C3, sid_C4, sid_C5, sid_C6, sid_C7, + sid_V0, sid_V1, + sid_ADD, sid_SUB, sid_MUL, sid_MAD, sid_LRP, sid_MOV, sid_CMP, sid_CND, + sid_DP3, sid_DP4, sid_DEF, + sid_R, sid_RA, sid_G, sid_GA, sid_B, sid_BA, sid_A, sid_RGBA, sid_RGB, + sid_RG, sid_RGA, sid_RB, sid_RBA, sid_GB, sid_GBA, + sid_RRRR, sid_GGGG, sid_BBBB, sid_AAAA, + sid_X2, sid_X4, sid_D2, sid_SAT, + sid_BIAS, sid_INVERT, sid_NEGATE, sid_BX2, + sid_COMMA, sid_VALUE, + + //PS_1_4 sid + sid_R0, sid_R1, sid_R2, sid_R3, sid_R4, sid_R5, + sid_T0, sid_T1, sid_T2, sid_T3, sid_T4, sid_T5, + sid_DP2ADD, + sid_X8, sid_D8, sid_D4, + sid_TEXCRD, sid_TEXLD, + sid_STR, sid_STQ, + sid_STRDR, sid_STQDQ, + sid_BEM, + sid_PHASE, + + //PS_1_1 sid + sid_1R0, sid_1R1, sid_1T0, sid_1T1, sid_1T2, sid_1T3, + sid_TEX, sid_TEXCOORD, sid_TEXM3X2PAD, + sid_TEXM3X2TEX, sid_TEXM3X3PAD, sid_TEXM3X3TEX, sid_TEXM3X3SPEC, sid_TEXM3X3VSPEC, + sid_TEXREG2AR, sid_TEXREG2GB, + + //PS_1_2 side + sid_TEXREG2RGB, sid_TEXDP3, sid_TEXDP3TEX, + + // common + sid_SKIP, sid_PLUS, + + // non-terminal tokens section + sid_PROGRAM, sid_PROGRAMTYPE, sid_DECLCONSTS, sid_DEFCONST, + sid_CONSTANT, sid_COLOR, + sid_TEXSWIZZLE, sid_UNARYOP, + sid_NUMVAL, sid_SEPERATOR, sid_ALUOPS, sid_TEXMASK, sid_TEXOP_PS1_1_3, + sid_TEXOP_PS1_4, + sid_ALU_STATEMENT, sid_DSTMODSAT, sid_UNARYOP_ARGS, sid_REG_PS1_4, + sid_TEX_PS1_4, sid_REG_PS1_1_3, sid_TEX_PS1_1_3, sid_DSTINFO, + sid_SRCINFO, sid_BINARYOP_ARGS, sid_TERNARYOP_ARGS, sid_TEMPREG, + sid_DSTMASK, sid_PRESRCMOD, sid_SRCNAME, sid_SRCREP, sid_POSTSRCMOD, + sid_DSTMOD, sid_DSTSAT, sid_BINARYOP, sid_TERNARYOP, + sid_TEXOPS_PHASE1, sid_COISSUE, sid_PHASEMARKER, sid_TEXOPS_PHASE2, + sid_TEXREG_PS1_4, sid_TEXOPS_PS1_4, sid_TEXOPS_PS1_1_3, sid_TEXCISCOP_PS1_1_3, + + + // last token + sid_INVALID = BAD_TOKEN // must be last in enumeration + }; + + /// structure used to keep track of arguments and instruction parameters + struct OpParram { + GLuint Arg; // type of argument + bool Filled; // has it been filled yet + GLuint MaskRep; // Mask/Replicator flags + GLuint Mod; // argument modifier + }; + + typedef std::vector MachineInstContainer; + //typedef MachineInstContainer::iterator MachineInstIterator; + + + // there are 2 phases with 2 subphases each + enum PhaseType {ptPHASE1TEX, ptPHASE1ALU, ptPHASE2TEX, ptPHASE2ALU }; + + struct RegModOffset { + uint MacroOffset; + uint RegisterBase; + uint OpParramsIndex; + }; + + struct MacroRegModify { + TokenInst * Macro; + uint MacroSize; + RegModOffset * RegMods; + uint RegModSize; + + }; + + #define R_BASE static_cast((sid_R0 - GL_REG_0_ATI)) + #define C_BASE static_cast((sid_C0 - GL_CON_0_ATI)) + #define T_BASE static_cast((sid_1T0 - GL_REG_0_ATI)) + + // static library database for tokens and BNF rules + static SymbolDef PS_1_4_SymbolTypeLib[]; + static TokenRule PS_1_x_RulePath[]; + static bool LibInitialized; + + // Static Macro database for ps.1.1 ps.1.2 ps.1.3 instructions + + static TokenInst texreg2ar[]; + static RegModOffset texreg2xx_RegMods[]; + static MacroRegModify texreg2ar_MacroMods; + + static TokenInst texreg2gb[]; + static MacroRegModify texreg2gb_MacroMods; + + static TokenInst texdp3[]; + static RegModOffset texdp3_RegMods[]; + static MacroRegModify texdp3_MacroMods; + + static TokenInst texdp3tex[]; + static RegModOffset texdp3tex_RegMods[]; + static MacroRegModify texdp3tex_MacroMods; + + static TokenInst texm3x2pad[]; + static RegModOffset texm3xxpad_RegMods[]; + static MacroRegModify texm3x2pad_MacroMods; + + static TokenInst texm3x2tex[]; + static RegModOffset texm3xxtex_RegMods[]; + static MacroRegModify texm3x2tex_MacroMods; + + static TokenInst texm3x3pad[]; + static MacroRegModify texm3x3pad_MacroMods; + + static TokenInst texm3x3tex[]; + static MacroRegModify texm3x3tex_MacroMods; + + static TokenInst texm3x3spec[]; + static RegModOffset texm3x3spec_RegMods[]; + static MacroRegModify texm3x3spec_MacroMods; + + static TokenInst texm3x3vspec[]; + static RegModOffset texm3x3vspec_RegMods[]; + static MacroRegModify texm3x3vspec_MacroMods; - MachineInstContainer mPhase1TEX_mi; /// machine instructions for phase one texture section - MachineInstContainer mPhase1ALU_mi; /// machine instructions for phase one ALU section - MachineInstContainer mPhase2TEX_mi; /// machine instructions for phase two texture section - MachineInstContainer mPhase2ALU_mi; /// machine instructions for phase two ALU section - - // vars used during pass 2 - MachineInstID mOpType; - uint mOpInst; - bool mDo_Alpha; - PhaseType mInstructionPhase; - int mArgCnt; - int mConstantsPos; + MachineInstContainer mPhase1TEX_mi; /// machine instructions for phase one texture section + MachineInstContainer mPhase1ALU_mi; /// machine instructions for phase one ALU section + MachineInstContainer mPhase2TEX_mi; /// machine instructions for phase two texture section + MachineInstContainer mPhase2ALU_mi; /// machine instructions for phase two ALU section + + // vars used during pass 2 + MachineInstID mOpType; + uint mOpInst; + bool mDo_Alpha; + PhaseType mInstructionPhase; + int mArgCnt; + int mConstantsPos; - #define MAXOPPARRAMS 5 // max number of parrams bound to an instruction - - OpParram mOpParrams[MAXOPPARRAMS]; + #define MAXOPPARRAMS 5 // max number of parrams bound to an instruction + + OpParram mOpParrams[MAXOPPARRAMS]; - /// keeps track of which registers are written to in each phase - /// if a register is read from but has not been written to in phase 2 - /// then if it was written to in phase 1 perform a register pass function - /// at the beginning of phase2 so that the register has something worthwhile in it - /// NB: check ALU and TEX section of phase 1 and phase 2 - /// there are 6 temp registers r0 to r5 to keep track off - /// checks are performed in pass 2 when building machine instructions - RegisterUsage Phase_RegisterUsage[6]; + /// keeps track of which registers are written to in each phase + /// if a register is read from but has not been written to in phase 2 + /// then if it was written to in phase 1 perform a register pass function + /// at the beginning of phase2 so that the register has something worthwhile in it + /// NB: check ALU and TEX section of phase 1 and phase 2 + /// there are 6 temp registers r0 to r5 to keep track off + /// checks are performed in pass 2 when building machine instructions + RegisterUsage Phase_RegisterUsage[6]; - bool mMacroOn; // if true then put all ALU instructions in phase 1 + bool mMacroOn; // if true then put all ALU instructions in phase 1 - uint mTexm3x3padCount; // keep track of how many texm3x3pad instructions are used so know which mask to use + uint mTexm3x3padCount; // keep track of how many texm3x3pad instructions are used so know which mask to use - size_t mLastInstructionPos; // keep track of last phase 2 ALU instruction to check for R0 setting - size_t mSecondLastInstructionPos; + size_t mLastInstructionPos; // keep track of last phase 2 ALU instruction to check for R0 setting + size_t mSecondLastInstructionPos; - // keep track if phase marker found: determines which phase the ALU instructions go into - bool mPhaseMarkerFound; + // keep track if phase marker found: determines which phase the ALU instructions go into + bool mPhaseMarkerFound; #ifdef _DEBUG - FILE* fp; - // full compiler test with output results going to a text file - void testCompile(char* testname, char* teststr, SymbolID* testresult, - uint testresultsize, GLuint* MachinInstResults = NULL, uint MachinInstResultsSize = 0); + FILE* fp; + // full compiler test with output results going to a text file + void testCompile(char* testname, char* teststr, SymbolID* testresult, + uint testresultsize, GLuint* MachinInstResults = NULL, uint MachinInstResultsSize = 0); #endif // _DEBUG - /** attempt to build a machine instruction using current tokens - determines what phase machine insturction should be in and if an Alpha Op is required - calls expandMachineInstruction() to expand the token into machine instructions - */ - bool BuildMachineInst(); - - void clearMachineInstState(); + /** attempt to build a machine instruction using current tokens + determines what phase machine insturction should be in and if an Alpha Op is required + calls expandMachineInstruction() to expand the token into machine instructions + */ + bool BuildMachineInst(); + + void clearMachineInstState(); - bool setOpParram(const SymbolDef* symboldef); + bool setOpParram(const SymbolDef* symboldef); - /** optimizes machine instructions depending on pixel shader context - only applies to ps.1.1 ps.1.2 and ps.1.3 since they use CISC instructions - that must be transformed into RISC instructions - */ - void optimize(); + /** optimizes machine instructions depending on pixel shader context + only applies to ps.1.1 ps.1.2 and ps.1.3 since they use CISC instructions + that must be transformed into RISC instructions + */ + void optimize(); - // the method is expected to be recursive to allow for inline expansion of instructions if required - bool Pass2scan(const TokenInst * Tokens, const size_t size); + // the method is expected to be recursive to allow for inline expansion of instructions if required + bool Pass2scan(const TokenInst * Tokens, const size_t size); - // supply virtual functions for Compiler2Pass - /// Pass 1 is completed so now take tokens generated and build machine instructions - bool doPass2(); + // supply virtual functions for Compiler2Pass + /// Pass 1 is completed so now take tokens generated and build machine instructions + bool doPass2(); - /** Build a machine instruction from token and ready it for expansion - will expand CISC tokens using macro database + /** Build a machine instruction from token and ready it for expansion + will expand CISC tokens using macro database - */ - bool bindMachineInstInPassToFragmentShader(const MachineInstContainer & PassMachineInstructions); + */ + bool bindMachineInstInPassToFragmentShader(const MachineInstContainer & PassMachineInstructions); - /** Expand CISC tokens into PS1_4 token equivalents + /** Expand CISC tokens into PS1_4 token equivalents - */ - bool expandMacro(const MacroRegModify & MacroMod); + */ + bool expandMacro(const MacroRegModify & MacroMod); - /** Expand Machine instruction into operation type and arguments and put into proper machine - instruction container - also expands scaler alpha machine instructions if required + /** Expand Machine instruction into operation type and arguments and put into proper machine + instruction container + also expands scaler alpha machine instructions if required - */ - bool expandMachineInstruction(); + */ + bool expandMachineInstruction(); - // mainly used by tests - too slow for use in binding - size_t getMachineInst(size_t Idx); + // mainly used by tests - too slow for use in binding + size_t getMachineInst(size_t Idx); - size_t getMachineInstCount(); + size_t getMachineInstCount(); - void addMachineInst(PhaseType phase, const uint inst); + void addMachineInst(PhaseType phase, const uint inst); - void clearAllMachineInst(); + void clearAllMachineInst(); - void updateRegisterWriteState(const PhaseType phase); + void updateRegisterWriteState(const PhaseType phase); - bool isRegisterReadValid(const PhaseType phase, const int param); + bool isRegisterReadValid(const PhaseType phase, const int param); public: - /// constructor - PS_1_4(); + /// constructor + PS_1_4(); - /// binds machine instructions generated in Pass 2 to the ATI GL fragment shader - bool bindAllMachineInstToFragmentShader(); + /// binds machine instructions generated in Pass 2 to the ATI GL fragment shader + bool bindAllMachineInstToFragmentShader(); #ifdef _DEBUG - /// perform compiler tests - only available in _DEBUG mode - void test(); - void testbinder(); + /// perform compiler tests - only available in _DEBUG mode + void test(); + void testbinder(); #endif }; diff --git a/RenderSystems/GL/src/atifs/src/ATI_FS_GLGpuProgram.cpp b/RenderSystems/GL/src/atifs/src/ATI_FS_GLGpuProgram.cpp index 145f858a26c..a8d997646e9 100644 --- a/RenderSystems/GL/src/atifs/src/ATI_FS_GLGpuProgram.cpp +++ b/RenderSystems/GL/src/atifs/src/ATI_FS_GLGpuProgram.cpp @@ -42,7 +42,7 @@ ATI_FS_GLGpuProgram::ATI_FS_GLGpuProgram(ResourceManager* creator, const String& group, bool isManual, ManualResourceLoader* loader) : GLGpuProgram(creator, name, handle, group, isManual, loader) { - mProgramType = GL_FRAGMENT_SHADER_ATI; + mProgramType = GL_FRAGMENT_SHADER_ATI; mProgramID = glGenFragmentShadersATI(1); } @@ -55,56 +55,56 @@ ATI_FS_GLGpuProgram::~ATI_FS_GLGpuProgram() void ATI_FS_GLGpuProgram::bindProgram(void) { - glEnable(mProgramType); - glBindFragmentShaderATI(mProgramID); + glEnable(mProgramType); + glBindFragmentShaderATI(mProgramID); } void ATI_FS_GLGpuProgram::unbindProgram(void) { - glDisable(mProgramType); + glDisable(mProgramType); } void ATI_FS_GLGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask) { - // only supports float constants - GpuLogicalBufferStructPtr floatStruct = params->getFloatLogicalBufferStruct(); - - for (GpuLogicalIndexUseMap::const_iterator i = floatStruct->map.begin(); - i != floatStruct->map.end(); ++i) - { - if (i->second.variability & mask) - { - size_t logicalIndex = i->first; - const float* pFloat = params->getFloatPointer(i->second.physicalIndex); - // Iterate over the params, set in 4-float chunks (low-level) - for (size_t j = 0; j < i->second.currentSize; j+=4) - { - glSetFragmentShaderConstantATI(GL_CON_0_ATI + logicalIndex, pFloat); - pFloat += 4; - ++logicalIndex; - } - } - } + // only supports float constants + GpuLogicalBufferStructPtr floatStruct = params->getFloatLogicalBufferStruct(); + + for (GpuLogicalIndexUseMap::const_iterator i = floatStruct->map.begin(); + i != floatStruct->map.end(); ++i) + { + if (i->second.variability & mask) + { + size_t logicalIndex = i->first; + const float* pFloat = params->getFloatPointer(i->second.physicalIndex); + // Iterate over the params, set in 4-float chunks (low-level) + for (size_t j = 0; j < i->second.currentSize; j+=4) + { + glSetFragmentShaderConstantATI(GL_CON_0_ATI + logicalIndex, pFloat); + pFloat += 4; + ++logicalIndex; + } + } + } } void ATI_FS_GLGpuProgram::bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) { - if (params->hasPassIterationNumber()) - { - size_t physicalIndex = params->getPassIterationNumberIndex(); - size_t logicalIndex = params->getFloatLogicalIndexForPhysicalIndex(physicalIndex); - const float* pFloat = params->getFloatPointer(physicalIndex); - glSetFragmentShaderConstantATI( GL_CON_0_ATI + (GLuint)logicalIndex, pFloat); - } + if (params->hasPassIterationNumber()) + { + size_t physicalIndex = params->getPassIterationNumberIndex(); + size_t logicalIndex = params->getFloatLogicalIndexForPhysicalIndex(physicalIndex); + const float* pFloat = params->getFloatPointer(physicalIndex); + glSetFragmentShaderConstantATI( GL_CON_0_ATI + (GLuint)logicalIndex, pFloat); + } } void ATI_FS_GLGpuProgram::unloadImpl(void) { - glDeleteFragmentShaderATI(mProgramID); + glDeleteFragmentShaderATI(mProgramID); } @@ -112,39 +112,39 @@ void ATI_FS_GLGpuProgram::loadFromSource(void) { PS_1_4 PS1_4Assembler; - // attempt to compile the source + // attempt to compile the source #ifdef _DEBUG - PS1_4Assembler.test(); // run compiler tests in debug mode + PS1_4Assembler.test(); // run compiler tests in debug mode #endif bool Error = !PS1_4Assembler.compile(mSource.c_str()); if(!Error) { - glBindFragmentShaderATI(mProgramID); - glBeginFragmentShaderATI(); - // compile was successful so send the machine instructions thru GL to GPU - Error = !PS1_4Assembler.bindAllMachineInstToFragmentShader(); + glBindFragmentShaderATI(mProgramID); + glBeginFragmentShaderATI(); + // compile was successful so send the machine instructions thru GL to GPU + Error = !PS1_4Assembler.bindAllMachineInstToFragmentShader(); glEndFragmentShaderATI(); - // check GL for GPU machine instruction bind erros - if (Error) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Cannot Bind ATI fragment shader :" + mName, mName); - } + // check GL for GPU machine instruction bind erros + if (Error) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Cannot Bind ATI fragment shader :" + mName, mName); + } } else - { - // an error occurred when compiling the ps_1_4 source code - char buff[50]; + { + // an error occurred when compiling the ps_1_4 source code + char buff[50]; sprintf(buff,"error on line %d in pixel shader source\n", PS1_4Assembler.mCurrentLine); - LogManager::getSingleton().logMessage("Warning: atifs compiler reported the following errors:"); - LogManager::getSingleton().logMessage(buff + mName); + LogManager::getSingleton().logMessage("Warning: atifs compiler reported the following errors:"); + LogManager::getSingleton().logMessage(buff + mName); - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Cannot Compile ATI fragment shader : " + mName + "\n\n" + buff , mName);// + + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Cannot Compile ATI fragment shader : " + mName + "\n\n" + buff , mName);// + } diff --git a/RenderSystems/GL/src/atifs/src/Compiler2Pass.cpp b/RenderSystems/GL/src/atifs/src/Compiler2Pass.cpp index b3150cae449..9c5026d0772 100644 --- a/RenderSystems/GL/src/atifs/src/Compiler2Pass.cpp +++ b/RenderSystems/GL/src/atifs/src/Compiler2Pass.cpp @@ -33,12 +33,12 @@ THE SOFTWARE. Compiler2Pass::Compiler2Pass() { - // reserve some memory space in the containers being used - mTokenInstructions.reserve(100); - mConstants.reserve(80); - // default contexts allows all contexts - // subclass should change it to fit the language being compiled - mActiveContexts = 0xffffffff; + // reserve some memory space in the containers being used + mTokenInstructions.reserve(100); + mConstants.reserve(80); + // default contexts allows all contexts + // subclass should change it to fit the language being compiled + mActiveContexts = 0xffffffff; } @@ -46,291 +46,291 @@ Compiler2Pass::Compiler2Pass() void Compiler2Pass::InitSymbolTypeLib() { - uint token_ID; - // find a default text for all Symbol Types in library - - // scan through all the rules and initialize TypeLib with index to text and index to rules for non-terminal tokens - for(int i = 0; i < mRulePathLibCnt; i++) { - token_ID = mRootRulePath[i].mTokenID; - // make sure SymbolTypeLib holds valid token - assert(mSymbolTypeLib[token_ID].mID == token_ID); - switch(mRootRulePath[i].mOperation) { - case otRULE: - // if operation is a rule then update typelib - mSymbolTypeLib[token_ID].mRuleID = i; - - case otAND: - case otOR: - case otOPTIONAL: - // update text index in typelib - if (mRootRulePath[i].mSymbol != NULL) mSymbolTypeLib[token_ID].mDefTextID = i; - break; + uint token_ID; + // find a default text for all Symbol Types in library + + // scan through all the rules and initialize TypeLib with index to text and index to rules for non-terminal tokens + for(int i = 0; i < mRulePathLibCnt; i++) { + token_ID = mRootRulePath[i].mTokenID; + // make sure SymbolTypeLib holds valid token + assert(mSymbolTypeLib[token_ID].mID == token_ID); + switch(mRootRulePath[i].mOperation) { + case otRULE: + // if operation is a rule then update typelib + mSymbolTypeLib[token_ID].mRuleID = i; + + case otAND: + case otOR: + case otOPTIONAL: + // update text index in typelib + if (mRootRulePath[i].mSymbol != NULL) mSymbolTypeLib[token_ID].mDefTextID = i; + break; case otREPEAT: case otEND: break; - } - } + } + } } bool Compiler2Pass::compile(const char* source) { - bool Passed = false; - - mSource = source; - // start compiling if there is a rule base to work with - if(mRootRulePath != NULL) { - Passed = doPass1(); - - if(Passed) { - Passed = doPass2(); - } - } - return Passed; + bool Passed = false; + + mSource = source; + // start compiling if there is a rule base to work with + if(mRootRulePath != NULL) { + Passed = doPass1(); + + if(Passed) { + Passed = doPass2(); + } + } + return Passed; } bool Compiler2Pass::doPass1() { - // scan through Source string and build a token list using TokenInstructions - // this is a simple brute force lexical scanner/analyzer that also parses the formed - // token for proper semantics and context in one pass - - mCurrentLine = 1; - mCharPos = 0; - // reset position in Constants container - mConstants.clear(); - mEndOfSource = strlen(mSource); - - // start with a clean slate - mTokenInstructions.clear(); - // tokenize and check semantics until an error occurs or end of source is reached - // assume RootRulePath has pointer to rules so start at index + 1 for first rule path - // first rule token would be a rule definition so skip over it - bool passed = processRulePath(0); - // if a symbol in source still exists then the end of source was not reached and there was a problem some where - if (positionToNextSymbol()) passed = false; - return passed; + // scan through Source string and build a token list using TokenInstructions + // this is a simple brute force lexical scanner/analyzer that also parses the formed + // token for proper semantics and context in one pass + + mCurrentLine = 1; + mCharPos = 0; + // reset position in Constants container + mConstants.clear(); + mEndOfSource = strlen(mSource); + + // start with a clean slate + mTokenInstructions.clear(); + // tokenize and check semantics until an error occurs or end of source is reached + // assume RootRulePath has pointer to rules so start at index + 1 for first rule path + // first rule token would be a rule definition so skip over it + bool passed = processRulePath(0); + // if a symbol in source still exists then the end of source was not reached and there was a problem some where + if (positionToNextSymbol()) passed = false; + return passed; } bool Compiler2Pass::processRulePath( uint rulepathIDX) { - // rule path determines what tokens and therefore what symbols are acceptable from the source - // it is assumed that the tokens with the longest similar symbols are arranged first so - // if a match is found it is accepted and no further searching is done - - // record position of last token in container - // to be used as the rollback position if a valid token is not found - uint TokenContainerOldSize = mTokenInstructions.size(); - int OldCharPos = mCharPos; - int OldLinePos = mCurrentLine; - uint OldConstantsSize = mConstants.size(); - - // keep track of what non-terminal token activated the rule - uint ActiveNTTRule = mRootRulePath[rulepathIDX].mTokenID; - // start rule path at next position for definition - rulepathIDX++; - - // assume the rule will pass - bool Passed = true; - bool EndFound = false; - - // keep following rulepath until the end is reached - while (EndFound == false) { - switch (mRootRulePath[rulepathIDX].mOperation) { - - case otAND: - // only validate if the previous rule passed - if(Passed) Passed = ValidateToken(rulepathIDX, ActiveNTTRule); - break; - - case otOR: - // only validate if the previous rule failed - if ( Passed == false ) { - // clear previous tokens from entry and try again - mTokenInstructions.resize(TokenContainerOldSize); - Passed = ValidateToken(rulepathIDX, ActiveNTTRule); - } - else { // path passed up to this point therefore finished so pretend end marker found - EndFound = true; - } - break; - - case otOPTIONAL: - // if previous passed then try this rule but it does not effect succes of rule since its optional - if(Passed) ValidateToken(rulepathIDX, ActiveNTTRule); - break; - - case otREPEAT: - // repeat until no tokens of this type found - // at least one must be found - if(Passed) { - int TokensPassed = 0; - // keep calling until failure - while ((Passed = ValidateToken(rulepathIDX, ActiveNTTRule))) { - // increment count for previous passed token - TokensPassed++; - } - // defaults to Passed = fail - // if at least one token found then return passed = true - if (TokensPassed > 0) Passed = true; - } - break; - - case otEND: - // end of rule found so time to return - EndFound = true; - if(Passed == false) { - // the rule did not validate so get rid of tokens decoded - // roll back the token container end position to what it was when rule started - // this will get rid of all tokens that had been pushed on the container while - // trying to validating this rule - mTokenInstructions.resize(TokenContainerOldSize); - mConstants.resize(OldConstantsSize); - mCharPos = OldCharPos; - mCurrentLine = OldLinePos; - } - break; - - default: - // an exception should be raised since the code should never get here - Passed = false; - EndFound = true; - break; - - } - - - // move on to the next rule in the path - rulepathIDX++; - } - - return Passed; + // rule path determines what tokens and therefore what symbols are acceptable from the source + // it is assumed that the tokens with the longest similar symbols are arranged first so + // if a match is found it is accepted and no further searching is done + + // record position of last token in container + // to be used as the rollback position if a valid token is not found + uint TokenContainerOldSize = mTokenInstructions.size(); + int OldCharPos = mCharPos; + int OldLinePos = mCurrentLine; + uint OldConstantsSize = mConstants.size(); + + // keep track of what non-terminal token activated the rule + uint ActiveNTTRule = mRootRulePath[rulepathIDX].mTokenID; + // start rule path at next position for definition + rulepathIDX++; + + // assume the rule will pass + bool Passed = true; + bool EndFound = false; + + // keep following rulepath until the end is reached + while (EndFound == false) { + switch (mRootRulePath[rulepathIDX].mOperation) { + + case otAND: + // only validate if the previous rule passed + if(Passed) Passed = ValidateToken(rulepathIDX, ActiveNTTRule); + break; + + case otOR: + // only validate if the previous rule failed + if ( Passed == false ) { + // clear previous tokens from entry and try again + mTokenInstructions.resize(TokenContainerOldSize); + Passed = ValidateToken(rulepathIDX, ActiveNTTRule); + } + else { // path passed up to this point therefore finished so pretend end marker found + EndFound = true; + } + break; + + case otOPTIONAL: + // if previous passed then try this rule but it does not effect succes of rule since its optional + if(Passed) ValidateToken(rulepathIDX, ActiveNTTRule); + break; + + case otREPEAT: + // repeat until no tokens of this type found + // at least one must be found + if(Passed) { + int TokensPassed = 0; + // keep calling until failure + while ((Passed = ValidateToken(rulepathIDX, ActiveNTTRule))) { + // increment count for previous passed token + TokensPassed++; + } + // defaults to Passed = fail + // if at least one token found then return passed = true + if (TokensPassed > 0) Passed = true; + } + break; + + case otEND: + // end of rule found so time to return + EndFound = true; + if(Passed == false) { + // the rule did not validate so get rid of tokens decoded + // roll back the token container end position to what it was when rule started + // this will get rid of all tokens that had been pushed on the container while + // trying to validating this rule + mTokenInstructions.resize(TokenContainerOldSize); + mConstants.resize(OldConstantsSize); + mCharPos = OldCharPos; + mCurrentLine = OldLinePos; + } + break; + + default: + // an exception should be raised since the code should never get here + Passed = false; + EndFound = true; + break; + + } + + + // move on to the next rule in the path + rulepathIDX++; + } + + return Passed; } bool Compiler2Pass::ValidateToken(const uint rulepathIDX, const uint activeRuleID) { - int tokenlength = 0; - // assume the test is going to fail - bool Passed = false; - uint TokenID = mRootRulePath[rulepathIDX].mTokenID; - // only validate token if context is correct - if (mSymbolTypeLib[TokenID].mContextKey & mActiveContexts) { - - // if terminal token then compare text of symbol with what is in source - if ( mSymbolTypeLib[TokenID].mRuleID == 0){ - - if (positionToNextSymbol()) { - // if Token is supposed to be a number then check if its a numerical constant - if (TokenID == mValueID) { - float constantvalue; - if((Passed = isFloatValue(constantvalue, tokenlength))) { - mConstants.push_back(constantvalue); - } - - } - // compare token symbol text with source text - else Passed = isSymbol(mRootRulePath[rulepathIDX].mSymbol, tokenlength); - - if(Passed) { - TokenInst newtoken; - // push token onto end of container - newtoken.mID = TokenID; - newtoken.mNTTRuleID = activeRuleID; - newtoken.mLine = mCurrentLine; - newtoken.mPos = mCharPos; - - mTokenInstructions.push_back(newtoken); - // update source position - mCharPos += tokenlength; - - // allow token instruction to change the ActiveContexts - // use token contexts pattern to clear ActiveContexts pattern bits - mActiveContexts &= ~mSymbolTypeLib[TokenID].mContextPatternClear; - // use token contexts pattern to set ActiveContexts pattern bits - mActiveContexts |= mSymbolTypeLib[TokenID].mContextPatternSet; - } - } - - } - // else a non terminal token was found - else { - - // execute rule for non-terminal - // get rule_ID for index into rulepath to be called - Passed = processRulePath(mSymbolTypeLib[TokenID].mRuleID); - } - } - - - return Passed; + int tokenlength = 0; + // assume the test is going to fail + bool Passed = false; + uint TokenID = mRootRulePath[rulepathIDX].mTokenID; + // only validate token if context is correct + if (mSymbolTypeLib[TokenID].mContextKey & mActiveContexts) { + + // if terminal token then compare text of symbol with what is in source + if ( mSymbolTypeLib[TokenID].mRuleID == 0){ + + if (positionToNextSymbol()) { + // if Token is supposed to be a number then check if its a numerical constant + if (TokenID == mValueID) { + float constantvalue; + if((Passed = isFloatValue(constantvalue, tokenlength))) { + mConstants.push_back(constantvalue); + } + + } + // compare token symbol text with source text + else Passed = isSymbol(mRootRulePath[rulepathIDX].mSymbol, tokenlength); + + if(Passed) { + TokenInst newtoken; + // push token onto end of container + newtoken.mID = TokenID; + newtoken.mNTTRuleID = activeRuleID; + newtoken.mLine = mCurrentLine; + newtoken.mPos = mCharPos; + + mTokenInstructions.push_back(newtoken); + // update source position + mCharPos += tokenlength; + + // allow token instruction to change the ActiveContexts + // use token contexts pattern to clear ActiveContexts pattern bits + mActiveContexts &= ~mSymbolTypeLib[TokenID].mContextPatternClear; + // use token contexts pattern to set ActiveContexts pattern bits + mActiveContexts |= mSymbolTypeLib[TokenID].mContextPatternSet; + } + } + + } + // else a non terminal token was found + else { + + // execute rule for non-terminal + // get rule_ID for index into rulepath to be called + Passed = processRulePath(mSymbolTypeLib[TokenID].mRuleID); + } + } + + + return Passed; } const char* Compiler2Pass::getTypeDefText(const uint sid) { - return mRootRulePath[mSymbolTypeLib[sid].mDefTextID].mSymbol; + return mRootRulePath[mSymbolTypeLib[sid].mDefTextID].mSymbol; } bool Compiler2Pass::isFloatValue(float& fvalue, int& charsize) { - // check to see if it is a numeric float value - bool valuefound = false; - - const char* startptr = mSource + mCharPos; - char* endptr = NULL; - - fvalue = (float)strtod(startptr, &endptr); - // if a valid float was found then endptr will have the pointer to the first invalid character - if(endptr) { - if(endptr>startptr) { - // a valid value was found so process it - charsize = endptr - startptr; - valuefound = true; - } - } - - return valuefound; + // check to see if it is a numeric float value + bool valuefound = false; + + const char* startptr = mSource + mCharPos; + char* endptr = NULL; + + fvalue = (float)strtod(startptr, &endptr); + // if a valid float was found then endptr will have the pointer to the first invalid character + if(endptr) { + if(endptr>startptr) { + // a valid value was found so process it + charsize = endptr - startptr; + valuefound = true; + } + } + + return valuefound; } bool Compiler2Pass::isSymbol(const char* symbol, int& symbolsize) { - // compare text at source+charpos with the symbol : limit testing to symbolsize - bool symbolfound = false; - symbolsize = strlen(symbol); - if(strncmp(mSource + mCharPos, symbol, symbolsize)==0) { - symbolfound = true; - } - - return symbolfound; + // compare text at source+charpos with the symbol : limit testing to symbolsize + bool symbolfound = false; + symbolsize = strlen(symbol); + if(strncmp(mSource + mCharPos, symbol, symbolsize)==0) { + symbolfound = true; + } + + return symbolfound; } bool Compiler2Pass::positionToNextSymbol() { - bool validsymbolfound = false; - bool endofsource = false; - while(!validsymbolfound && !endofsource) { - skipWhiteSpace(); - skipEOL(); - skipComments(); - // have we reached the end of the string? - if (mCharPos == mEndOfSource) endofsource = true; - else { - // if ASCII > space then assume valid character is found - if (mSource[mCharPos] > ' ') validsymbolfound = true; - } - }// end of while - - return validsymbolfound; + bool validsymbolfound = false; + bool endofsource = false; + while(!validsymbolfound && !endofsource) { + skipWhiteSpace(); + skipEOL(); + skipComments(); + // have we reached the end of the string? + if (mCharPos == mEndOfSource) endofsource = true; + else { + // if ASCII > space then assume valid character is found + if (mSource[mCharPos] > ' ') validsymbolfound = true; + } + }// end of while + + return validsymbolfound; } @@ -338,42 +338,42 @@ bool Compiler2Pass::positionToNextSymbol() void Compiler2Pass::skipComments() { // if current char and next are // then search for EOL - if(mCharPos < mEndOfSource) { - if( ((mSource[mCharPos] == '/') && (mSource[mCharPos + 1] == '/')) || - (mSource[mCharPos] == ';') || - (mSource[mCharPos] == '#') ) findEOL(); - } + if(mCharPos < mEndOfSource) { + if( ((mSource[mCharPos] == '/') && (mSource[mCharPos + 1] == '/')) || + (mSource[mCharPos] == ';') || + (mSource[mCharPos] == '#') ) findEOL(); + } } void Compiler2Pass::findEOL() { - // find eol charter and move to this position - const char* newpos = strchr(&mSource[mCharPos], '\n'); - if(newpos) { - mCharPos += newpos - &mSource[mCharPos]; - } - // couldn't find end of line so skip to the end - else mCharPos = mEndOfSource - 1; + // find eol charter and move to this position + const char* newpos = strchr(&mSource[mCharPos], '\n'); + if(newpos) { + mCharPos += newpos - &mSource[mCharPos]; + } + // couldn't find end of line so skip to the end + else mCharPos = mEndOfSource - 1; } void Compiler2Pass::skipEOL() { - if ((mSource[mCharPos] == '\n') || (mSource[mCharPos] == '\r')) { - mCurrentLine++; - mCharPos++; - if ((mSource[mCharPos] == '\n') || (mSource[mCharPos] == '\r')) { - mCharPos++; - } - } + if ((mSource[mCharPos] == '\n') || (mSource[mCharPos] == '\r')) { + mCurrentLine++; + mCharPos++; + if ((mSource[mCharPos] == '\n') || (mSource[mCharPos] == '\r')) { + mCharPos++; + } + } } void Compiler2Pass::skipWhiteSpace() { - // FIX - this method kinda slow - while((mSource[mCharPos] == ' ') || (mSource[mCharPos] == '\t')) mCharPos++; // find first non white space character + // FIX - this method kinda slow + while((mSource[mCharPos] == ' ') || (mSource[mCharPos] == '\t')) mCharPos++; // find first non white space character } diff --git a/RenderSystems/GL/src/atifs/src/ps_1_4.cpp b/RenderSystems/GL/src/atifs/src/ps_1_4.cpp index 0bad4a8eddc..baaa2d14aa1 100644 --- a/RenderSystems/GL/src/atifs/src/ps_1_4.cpp +++ b/RenderSystems/GL/src/atifs/src/ps_1_4.cpp @@ -44,606 +44,606 @@ bool PS_1_4::LibInitialized = false; #define SYMEND ,0,0,0,0} PS_1_4::SymbolDef PS_1_4::PS_1_4_SymbolTypeLib[] = { - // pixel shader versions supported - { sid_PS_1_4, GL_NONE, ckp_PS_BASE, ckp_PS_1_4, 0, 0, 0 }, - { sid_PS_1_1, GL_NONE, ckp_PS_BASE, ckp_PS_1_1, 0, 0, 0 }, - { sid_PS_1_2, GL_NONE, ckp_PS_BASE, ckp_PS_1_2 + ckp_PS_1_1, 0, 0, 0 }, - { sid_PS_1_3, GL_NONE, ckp_PS_BASE, ckp_PS_1_3 + ckp_PS_1_2 + ckp_PS_1_1, 0, 0, 0 }, - - // PS_BASE - - // constants - SYMSTART sid_C0, GL_CON_0_ATI, ckp_PS_BASE - SYMDEF sid_C1, GL_CON_1_ATI, ckp_PS_BASE - SYMDEF sid_C2, GL_CON_2_ATI, ckp_PS_BASE - SYMDEF sid_C3, GL_CON_3_ATI, ckp_PS_BASE - SYMDEF sid_C4, GL_CON_4_ATI, ckp_PS_BASE - SYMDEF sid_C5, GL_CON_5_ATI, ckp_PS_BASE - SYMDEF sid_C6, GL_CON_6_ATI, ckp_PS_BASE - SYMDEF sid_C7, GL_CON_7_ATI, ckp_PS_BASE - - // colour - SYMDEF sid_V0, GL_PRIMARY_COLOR_ARB, ckp_PS_BASE - SYMDEF sid_V1, GL_SECONDARY_INTERPOLATOR_ATI, ckp_PS_BASE - - // instruction ops - SYMDEF sid_ADD, GL_ADD_ATI, ckp_PS_BASE - SYMDEF sid_SUB, GL_SUB_ATI, ckp_PS_BASE - SYMDEF sid_MUL, GL_MUL_ATI, ckp_PS_BASE - SYMDEF sid_MAD, GL_MAD_ATI, ckp_PS_BASE - SYMDEF sid_LRP, GL_LERP_ATI, ckp_PS_BASE - SYMDEF sid_MOV, GL_MOV_ATI, ckp_PS_BASE - SYMDEF sid_CMP, GL_CND0_ATI, ckp_PS_BASE - SYMDEF sid_CND, GL_CND_ATI, ckp_PS_BASE - SYMDEF sid_DP3, GL_DOT3_ATI, ckp_PS_BASE - SYMDEF sid_DP4, GL_DOT4_ATI, ckp_PS_BASE - - SYMDEF sid_DEF, GL_NONE, ckp_PS_BASE - - // Masks - SYMDEF sid_R, GL_RED_BIT_ATI, ckp_PS_1_4 - SYMDEF sid_RA, GL_RED_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 - SYMDEF sid_G, GL_GREEN_BIT_ATI, ckp_PS_1_4 - SYMDEF sid_GA, GL_GREEN_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 - SYMDEF sid_B, GL_BLUE_BIT_ATI, ckp_PS_1_4 - SYMDEF sid_BA, GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 - SYMDEF sid_A, ALPHA_BIT, ckp_PS_BASE - SYMDEF sid_RGBA, RGB_BITS | ALPHA_BIT, ckp_PS_BASE - SYMDEF sid_RGB, RGB_BITS, ckp_PS_BASE - SYMDEF sid_RG, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI, ckp_PS_1_4 - SYMDEF sid_RGA, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 - SYMDEF sid_RB, GL_RED_BIT_ATI | GL_BLUE_BIT_ATI, ckp_PS_1_4 - SYMDEF sid_RBA, GL_RED_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 - SYMDEF sid_GB, GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI, ckp_PS_1_4 - SYMDEF sid_GBA, GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 - - // Rep - SYMDEF sid_RRRR, GL_RED, ckp_PS_1_4 - SYMDEF sid_GGGG, GL_GREEN, ckp_PS_1_4 - SYMDEF sid_BBBB, GL_BLUE, ckp_PS_BASE - SYMDEF sid_AAAA, GL_ALPHA, ckp_PS_BASE - - - // modifiers - SYMDEF sid_X2, GL_2X_BIT_ATI, ckp_PS_BASE - SYMDEF sid_X4, GL_4X_BIT_ATI, ckp_PS_BASE - SYMDEF sid_D2, GL_HALF_BIT_ATI, ckp_PS_BASE - SYMDEF sid_SAT, GL_SATURATE_BIT_ATI, ckp_PS_BASE - - // argument modifiers - SYMDEF sid_BIAS, GL_BIAS_BIT_ATI, ckp_PS_BASE - SYMDEF sid_INVERT, GL_COMP_BIT_ATI, ckp_PS_BASE - SYMDEF sid_NEGATE, GL_NEGATE_BIT_ATI, ckp_PS_BASE - SYMDEF sid_BX2, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI, ckp_PS_BASE - - // seperator characters - SYMDEF sid_COMMA, GL_NONE, ckp_PS_BASE - SYMDEF sid_VALUE, GL_NONE, ckp_PS_BASE - - // PS_1_4 - // temp R/W registers - SYMDEF sid_R0, GL_REG_0_ATI, ckp_PS_1_4 - SYMDEF sid_R1, GL_REG_1_ATI, ckp_PS_1_4 - SYMDEF sid_R2, GL_REG_2_ATI, ckp_PS_1_4 - SYMDEF sid_R3, GL_REG_3_ATI, ckp_PS_1_4 - SYMDEF sid_R4, GL_REG_4_ATI, ckp_PS_1_4 - SYMDEF sid_R5, GL_REG_5_ATI, ckp_PS_1_4 - - // textures - SYMDEF sid_T0, GL_TEXTURE0_ARB, ckp_PS_1_4 - SYMDEF sid_T1, GL_TEXTURE1_ARB, ckp_PS_1_4 - SYMDEF sid_T2, GL_TEXTURE2_ARB, ckp_PS_1_4 - SYMDEF sid_T3, GL_TEXTURE3_ARB, ckp_PS_1_4 - SYMDEF sid_T4, GL_TEXTURE4_ARB, ckp_PS_1_4 - SYMDEF sid_T5, GL_TEXTURE5_ARB, ckp_PS_1_4 - SYMDEF sid_DP2ADD, GL_DOT2_ADD_ATI, ckp_PS_1_4 - - // modifiers - SYMDEF sid_X8, GL_8X_BIT_ATI, ckp_PS_1_4 - SYMDEF sid_D8, GL_EIGHTH_BIT_ATI, ckp_PS_1_4 - SYMDEF sid_D4, GL_QUARTER_BIT_ATI, ckp_PS_1_4 - - // instructions - SYMDEF sid_TEXCRD, GL_NONE, ckp_PS_1_4 - SYMDEF sid_TEXLD, GL_NONE, ckp_PS_1_4 - - // texture swizzlers - - SYMDEF sid_STR, GL_SWIZZLE_STR_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4 - SYMDEF sid_STQ, GL_SWIZZLE_STQ_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4 - SYMDEF sid_STRDR, GL_SWIZZLE_STR_DR_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4 - SYMDEF sid_STQDQ, GL_SWIZZLE_STQ_DQ_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4 - - SYMDEF sid_BEM, GL_NONE, ckp_PS_1_4 - SYMDEF sid_PHASE, GL_NONE, ckp_PS_1_4 - - // PS_1_1 - // temp R/W registers - // r0, r1 are mapped to r4, r5 - // t0 to t3 are mapped to r0 to r3 - SYMDEF sid_1R0, GL_REG_4_ATI, ckp_PS_1_1 - SYMDEF sid_1R1, GL_REG_5_ATI, ckp_PS_1_1 - SYMDEF sid_1T0, GL_REG_0_ATI, ckp_PS_1_1 - SYMDEF sid_1T1, GL_REG_1_ATI, ckp_PS_1_1 - SYMDEF sid_1T2, GL_REG_2_ATI, ckp_PS_1_1 - SYMDEF sid_1T3, GL_REG_3_ATI, ckp_PS_1_1 - - // instructions common to PS_1_1, PS_1_2, PS_1_3 - SYMDEF sid_TEX, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEXCOORD, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEXM3X2PAD, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEXM3X2TEX, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEXM3X3PAD, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEXM3X3TEX, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEXM3X3SPEC, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEXM3X3VSPEC, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEXREG2AR, GL_NONE, ckp_PS_1_2 - SYMDEF sid_TEXREG2GB, GL_NONE, ckp_PS_1_2 - - // PS_1_2 & PS_1_3 - SYMDEF sid_TEXREG2RGB, GL_NONE, ckp_PS_1_2 - SYMDEF sid_TEXDP3, GL_NONE, ckp_PS_1_2 - SYMDEF sid_TEXDP3TEX, GL_NONE, ckp_PS_1_2 - - - // Common - SYMDEF sid_SKIP, GL_NONE, ckp_PS_BASE - SYMDEF sid_PLUS, GL_NONE, ckp_PS_BASE - - // Non-Terminal Tokens - SYMDEF sid_PROGRAM, GL_NONE, ckp_PS_BASE - SYMDEF sid_PROGRAMTYPE, GL_NONE, ckp_PS_BASE - SYMDEF sid_DECLCONSTS, GL_NONE, ckp_PS_BASE - SYMDEF sid_DEFCONST, GL_NONE, ckp_PS_BASE - SYMDEF sid_CONSTANT, GL_NONE, ckp_PS_BASE - SYMDEF sid_COLOR, GL_NONE, ckp_PS_BASE - SYMDEF sid_TEXSWIZZLE, GL_NONE, ckp_PS_BASE - SYMDEF sid_UNARYOP, GL_NONE, ckp_PS_BASE - SYMDEF sid_NUMVAL, GL_NONE, ckp_PS_BASE - SYMDEF sid_SEPERATOR, GL_NONE, ckp_PS_BASE - SYMDEF sid_ALUOPS, GL_NONE, ckp_PS_BASE - SYMDEF sid_TEXMASK, GL_NONE, ckp_PS_BASE - SYMDEF sid_TEXOP_PS1_1_3, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEXOP_PS1_4, GL_NONE, ckp_PS_1_4 - SYMDEF sid_ALU_STATEMENT, GL_NONE, ckp_PS_BASE - SYMDEF sid_DSTMODSAT, GL_NONE, ckp_PS_BASE - SYMDEF sid_UNARYOP_ARGS, GL_NONE, ckp_PS_BASE - SYMDEF sid_REG_PS1_4, GL_NONE, ckp_PS_1_4 - SYMDEF sid_TEX_PS1_4, GL_NONE, ckp_PS_1_4 - SYMDEF sid_REG_PS1_1_3, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEX_PS1_1_3, GL_NONE, ckp_PS_1_1 - SYMDEF sid_DSTINFO, GL_NONE, ckp_PS_BASE - SYMDEF sid_SRCINFO, GL_NONE, ckp_PS_BASE - SYMDEF sid_BINARYOP_ARGS, GL_NONE, ckp_PS_BASE - SYMDEF sid_TERNARYOP_ARGS, GL_NONE, ckp_PS_BASE - SYMDEF sid_TEMPREG, GL_NONE, ckp_PS_BASE - SYMDEF sid_DSTMASK, GL_NONE, ckp_PS_BASE - SYMDEF sid_PRESRCMOD, GL_NONE, ckp_PS_BASE - SYMDEF sid_SRCNAME, GL_NONE, ckp_PS_BASE - SYMDEF sid_SRCREP, GL_NONE, ckp_PS_BASE - SYMDEF sid_POSTSRCMOD, GL_NONE, ckp_PS_BASE - SYMDEF sid_DSTMOD, GL_NONE, ckp_PS_BASE - SYMDEF sid_DSTSAT, GL_NONE, ckp_PS_BASE - SYMDEF sid_BINARYOP, GL_NONE, ckp_PS_BASE - SYMDEF sid_TERNARYOP, GL_NONE, ckp_PS_BASE - SYMDEF sid_TEXOPS_PHASE1, GL_NONE, ckp_PS_BASE - SYMDEF sid_COISSUE, GL_NONE, ckp_PS_BASE - SYMDEF sid_PHASEMARKER, GL_NONE, ckp_PS_1_4 - SYMDEF sid_TEXOPS_PHASE2, GL_NONE, ckp_PS_1_4 - SYMDEF sid_TEXREG_PS1_4, GL_NONE, ckp_PS_1_4 - SYMDEF sid_TEXOPS_PS1_4, GL_NONE, ckp_PS_1_4 - SYMDEF sid_TEXOPS_PS1_1_3, GL_NONE, ckp_PS_1_1 - SYMDEF sid_TEXCISCOP_PS1_1_3, GL_NONE, ckp_PS_1_1 - SYMEND + // pixel shader versions supported + { sid_PS_1_4, GL_NONE, ckp_PS_BASE, ckp_PS_1_4, 0, 0, 0 }, + { sid_PS_1_1, GL_NONE, ckp_PS_BASE, ckp_PS_1_1, 0, 0, 0 }, + { sid_PS_1_2, GL_NONE, ckp_PS_BASE, ckp_PS_1_2 + ckp_PS_1_1, 0, 0, 0 }, + { sid_PS_1_3, GL_NONE, ckp_PS_BASE, ckp_PS_1_3 + ckp_PS_1_2 + ckp_PS_1_1, 0, 0, 0 }, + + // PS_BASE + + // constants + SYMSTART sid_C0, GL_CON_0_ATI, ckp_PS_BASE + SYMDEF sid_C1, GL_CON_1_ATI, ckp_PS_BASE + SYMDEF sid_C2, GL_CON_2_ATI, ckp_PS_BASE + SYMDEF sid_C3, GL_CON_3_ATI, ckp_PS_BASE + SYMDEF sid_C4, GL_CON_4_ATI, ckp_PS_BASE + SYMDEF sid_C5, GL_CON_5_ATI, ckp_PS_BASE + SYMDEF sid_C6, GL_CON_6_ATI, ckp_PS_BASE + SYMDEF sid_C7, GL_CON_7_ATI, ckp_PS_BASE + + // colour + SYMDEF sid_V0, GL_PRIMARY_COLOR_ARB, ckp_PS_BASE + SYMDEF sid_V1, GL_SECONDARY_INTERPOLATOR_ATI, ckp_PS_BASE + + // instruction ops + SYMDEF sid_ADD, GL_ADD_ATI, ckp_PS_BASE + SYMDEF sid_SUB, GL_SUB_ATI, ckp_PS_BASE + SYMDEF sid_MUL, GL_MUL_ATI, ckp_PS_BASE + SYMDEF sid_MAD, GL_MAD_ATI, ckp_PS_BASE + SYMDEF sid_LRP, GL_LERP_ATI, ckp_PS_BASE + SYMDEF sid_MOV, GL_MOV_ATI, ckp_PS_BASE + SYMDEF sid_CMP, GL_CND0_ATI, ckp_PS_BASE + SYMDEF sid_CND, GL_CND_ATI, ckp_PS_BASE + SYMDEF sid_DP3, GL_DOT3_ATI, ckp_PS_BASE + SYMDEF sid_DP4, GL_DOT4_ATI, ckp_PS_BASE + + SYMDEF sid_DEF, GL_NONE, ckp_PS_BASE + + // Masks + SYMDEF sid_R, GL_RED_BIT_ATI, ckp_PS_1_4 + SYMDEF sid_RA, GL_RED_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 + SYMDEF sid_G, GL_GREEN_BIT_ATI, ckp_PS_1_4 + SYMDEF sid_GA, GL_GREEN_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 + SYMDEF sid_B, GL_BLUE_BIT_ATI, ckp_PS_1_4 + SYMDEF sid_BA, GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 + SYMDEF sid_A, ALPHA_BIT, ckp_PS_BASE + SYMDEF sid_RGBA, RGB_BITS | ALPHA_BIT, ckp_PS_BASE + SYMDEF sid_RGB, RGB_BITS, ckp_PS_BASE + SYMDEF sid_RG, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI, ckp_PS_1_4 + SYMDEF sid_RGA, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 + SYMDEF sid_RB, GL_RED_BIT_ATI | GL_BLUE_BIT_ATI, ckp_PS_1_4 + SYMDEF sid_RBA, GL_RED_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 + SYMDEF sid_GB, GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI, ckp_PS_1_4 + SYMDEF sid_GBA, GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT, ckp_PS_1_4 + + // Rep + SYMDEF sid_RRRR, GL_RED, ckp_PS_1_4 + SYMDEF sid_GGGG, GL_GREEN, ckp_PS_1_4 + SYMDEF sid_BBBB, GL_BLUE, ckp_PS_BASE + SYMDEF sid_AAAA, GL_ALPHA, ckp_PS_BASE + + + // modifiers + SYMDEF sid_X2, GL_2X_BIT_ATI, ckp_PS_BASE + SYMDEF sid_X4, GL_4X_BIT_ATI, ckp_PS_BASE + SYMDEF sid_D2, GL_HALF_BIT_ATI, ckp_PS_BASE + SYMDEF sid_SAT, GL_SATURATE_BIT_ATI, ckp_PS_BASE + + // argument modifiers + SYMDEF sid_BIAS, GL_BIAS_BIT_ATI, ckp_PS_BASE + SYMDEF sid_INVERT, GL_COMP_BIT_ATI, ckp_PS_BASE + SYMDEF sid_NEGATE, GL_NEGATE_BIT_ATI, ckp_PS_BASE + SYMDEF sid_BX2, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI, ckp_PS_BASE + + // seperator characters + SYMDEF sid_COMMA, GL_NONE, ckp_PS_BASE + SYMDEF sid_VALUE, GL_NONE, ckp_PS_BASE + + // PS_1_4 + // temp R/W registers + SYMDEF sid_R0, GL_REG_0_ATI, ckp_PS_1_4 + SYMDEF sid_R1, GL_REG_1_ATI, ckp_PS_1_4 + SYMDEF sid_R2, GL_REG_2_ATI, ckp_PS_1_4 + SYMDEF sid_R3, GL_REG_3_ATI, ckp_PS_1_4 + SYMDEF sid_R4, GL_REG_4_ATI, ckp_PS_1_4 + SYMDEF sid_R5, GL_REG_5_ATI, ckp_PS_1_4 + + // textures + SYMDEF sid_T0, GL_TEXTURE0_ARB, ckp_PS_1_4 + SYMDEF sid_T1, GL_TEXTURE1_ARB, ckp_PS_1_4 + SYMDEF sid_T2, GL_TEXTURE2_ARB, ckp_PS_1_4 + SYMDEF sid_T3, GL_TEXTURE3_ARB, ckp_PS_1_4 + SYMDEF sid_T4, GL_TEXTURE4_ARB, ckp_PS_1_4 + SYMDEF sid_T5, GL_TEXTURE5_ARB, ckp_PS_1_4 + SYMDEF sid_DP2ADD, GL_DOT2_ADD_ATI, ckp_PS_1_4 + + // modifiers + SYMDEF sid_X8, GL_8X_BIT_ATI, ckp_PS_1_4 + SYMDEF sid_D8, GL_EIGHTH_BIT_ATI, ckp_PS_1_4 + SYMDEF sid_D4, GL_QUARTER_BIT_ATI, ckp_PS_1_4 + + // instructions + SYMDEF sid_TEXCRD, GL_NONE, ckp_PS_1_4 + SYMDEF sid_TEXLD, GL_NONE, ckp_PS_1_4 + + // texture swizzlers + + SYMDEF sid_STR, GL_SWIZZLE_STR_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4 + SYMDEF sid_STQ, GL_SWIZZLE_STQ_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4 + SYMDEF sid_STRDR, GL_SWIZZLE_STR_DR_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4 + SYMDEF sid_STQDQ, GL_SWIZZLE_STQ_DQ_ATI - GL_SWIZZLE_STR_ATI, ckp_PS_1_4 + + SYMDEF sid_BEM, GL_NONE, ckp_PS_1_4 + SYMDEF sid_PHASE, GL_NONE, ckp_PS_1_4 + + // PS_1_1 + // temp R/W registers + // r0, r1 are mapped to r4, r5 + // t0 to t3 are mapped to r0 to r3 + SYMDEF sid_1R0, GL_REG_4_ATI, ckp_PS_1_1 + SYMDEF sid_1R1, GL_REG_5_ATI, ckp_PS_1_1 + SYMDEF sid_1T0, GL_REG_0_ATI, ckp_PS_1_1 + SYMDEF sid_1T1, GL_REG_1_ATI, ckp_PS_1_1 + SYMDEF sid_1T2, GL_REG_2_ATI, ckp_PS_1_1 + SYMDEF sid_1T3, GL_REG_3_ATI, ckp_PS_1_1 + + // instructions common to PS_1_1, PS_1_2, PS_1_3 + SYMDEF sid_TEX, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEXCOORD, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEXM3X2PAD, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEXM3X2TEX, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEXM3X3PAD, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEXM3X3TEX, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEXM3X3SPEC, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEXM3X3VSPEC, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEXREG2AR, GL_NONE, ckp_PS_1_2 + SYMDEF sid_TEXREG2GB, GL_NONE, ckp_PS_1_2 + + // PS_1_2 & PS_1_3 + SYMDEF sid_TEXREG2RGB, GL_NONE, ckp_PS_1_2 + SYMDEF sid_TEXDP3, GL_NONE, ckp_PS_1_2 + SYMDEF sid_TEXDP3TEX, GL_NONE, ckp_PS_1_2 + + + // Common + SYMDEF sid_SKIP, GL_NONE, ckp_PS_BASE + SYMDEF sid_PLUS, GL_NONE, ckp_PS_BASE + + // Non-Terminal Tokens + SYMDEF sid_PROGRAM, GL_NONE, ckp_PS_BASE + SYMDEF sid_PROGRAMTYPE, GL_NONE, ckp_PS_BASE + SYMDEF sid_DECLCONSTS, GL_NONE, ckp_PS_BASE + SYMDEF sid_DEFCONST, GL_NONE, ckp_PS_BASE + SYMDEF sid_CONSTANT, GL_NONE, ckp_PS_BASE + SYMDEF sid_COLOR, GL_NONE, ckp_PS_BASE + SYMDEF sid_TEXSWIZZLE, GL_NONE, ckp_PS_BASE + SYMDEF sid_UNARYOP, GL_NONE, ckp_PS_BASE + SYMDEF sid_NUMVAL, GL_NONE, ckp_PS_BASE + SYMDEF sid_SEPERATOR, GL_NONE, ckp_PS_BASE + SYMDEF sid_ALUOPS, GL_NONE, ckp_PS_BASE + SYMDEF sid_TEXMASK, GL_NONE, ckp_PS_BASE + SYMDEF sid_TEXOP_PS1_1_3, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEXOP_PS1_4, GL_NONE, ckp_PS_1_4 + SYMDEF sid_ALU_STATEMENT, GL_NONE, ckp_PS_BASE + SYMDEF sid_DSTMODSAT, GL_NONE, ckp_PS_BASE + SYMDEF sid_UNARYOP_ARGS, GL_NONE, ckp_PS_BASE + SYMDEF sid_REG_PS1_4, GL_NONE, ckp_PS_1_4 + SYMDEF sid_TEX_PS1_4, GL_NONE, ckp_PS_1_4 + SYMDEF sid_REG_PS1_1_3, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEX_PS1_1_3, GL_NONE, ckp_PS_1_1 + SYMDEF sid_DSTINFO, GL_NONE, ckp_PS_BASE + SYMDEF sid_SRCINFO, GL_NONE, ckp_PS_BASE + SYMDEF sid_BINARYOP_ARGS, GL_NONE, ckp_PS_BASE + SYMDEF sid_TERNARYOP_ARGS, GL_NONE, ckp_PS_BASE + SYMDEF sid_TEMPREG, GL_NONE, ckp_PS_BASE + SYMDEF sid_DSTMASK, GL_NONE, ckp_PS_BASE + SYMDEF sid_PRESRCMOD, GL_NONE, ckp_PS_BASE + SYMDEF sid_SRCNAME, GL_NONE, ckp_PS_BASE + SYMDEF sid_SRCREP, GL_NONE, ckp_PS_BASE + SYMDEF sid_POSTSRCMOD, GL_NONE, ckp_PS_BASE + SYMDEF sid_DSTMOD, GL_NONE, ckp_PS_BASE + SYMDEF sid_DSTSAT, GL_NONE, ckp_PS_BASE + SYMDEF sid_BINARYOP, GL_NONE, ckp_PS_BASE + SYMDEF sid_TERNARYOP, GL_NONE, ckp_PS_BASE + SYMDEF sid_TEXOPS_PHASE1, GL_NONE, ckp_PS_BASE + SYMDEF sid_COISSUE, GL_NONE, ckp_PS_BASE + SYMDEF sid_PHASEMARKER, GL_NONE, ckp_PS_1_4 + SYMDEF sid_TEXOPS_PHASE2, GL_NONE, ckp_PS_1_4 + SYMDEF sid_TEXREG_PS1_4, GL_NONE, ckp_PS_1_4 + SYMDEF sid_TEXOPS_PS1_4, GL_NONE, ckp_PS_1_4 + SYMDEF sid_TEXOPS_PS1_1_3, GL_NONE, ckp_PS_1_1 + SYMDEF sid_TEXCISCOP_PS1_1_3, GL_NONE, ckp_PS_1_1 + SYMEND }; // Rule Path Database for ps.1.x code based on extended Backus Naur Form notation -// <> - non-terminal token -#define _rule_ {otRULE, // ::= - rule definition -#define _is_ ,0},{otAND, -#define _and_ ,0},{otAND, // - blank space is an implied "AND" meaning the token is required -#define _or_ ,0},{otOR, // | - or -#define _optional_ ,0},{otOPTIONAL, // [] - optional -#define _repeat_ ,0},{otREPEAT, // {} - repeat until fail -#define _end_ ,0},{otEND,0,0,0}, +// <> - non-terminal token +#define _rule_ {otRULE, // ::= - rule definition +#define _is_ ,0},{otAND, +#define _and_ ,0},{otAND, // - blank space is an implied "AND" meaning the token is required +#define _or_ ,0},{otOR, // | - or +#define _optional_ ,0},{otOPTIONAL, // [] - optional +#define _repeat_ ,0},{otREPEAT, // {} - repeat until fail +#define _end_ ,0},{otEND,0,0,0}, #define _nt_ ,0 // " " - terminal token string PS_1_4::TokenRule PS_1_4::PS_1_x_RulePath[] = { - _rule_ sid_PROGRAM, "Program" + _rule_ sid_PROGRAM, "Program" - _is_ sid_PROGRAMTYPE _nt_ - _optional_ sid_DECLCONSTS _nt_ - _optional_ sid_TEXOPS_PHASE1 _nt_ - _optional_ sid_ALUOPS _nt_ - _optional_ sid_PHASEMARKER _nt_ - _optional_ sid_TEXOPS_PHASE2 _nt_ - _optional_ sid_ALUOPS _nt_ - _end_ + _is_ sid_PROGRAMTYPE _nt_ + _optional_ sid_DECLCONSTS _nt_ + _optional_ sid_TEXOPS_PHASE1 _nt_ + _optional_ sid_ALUOPS _nt_ + _optional_ sid_PHASEMARKER _nt_ + _optional_ sid_TEXOPS_PHASE2 _nt_ + _optional_ sid_ALUOPS _nt_ + _end_ - _rule_ sid_PROGRAMTYPE, "" + _rule_ sid_PROGRAMTYPE, "" - _is_ sid_PS_1_4, "ps.1.4" - _or_ sid_PS_1_1, "ps.1.1" - _or_ sid_PS_1_2, "ps.1.2" - _or_ sid_PS_1_3, "ps.1.3" - _end_ + _is_ sid_PS_1_4, "ps.1.4" + _or_ sid_PS_1_1, "ps.1.1" + _or_ sid_PS_1_2, "ps.1.2" + _or_ sid_PS_1_3, "ps.1.3" + _end_ - _rule_ sid_PHASEMARKER, "" + _rule_ sid_PHASEMARKER, "" - _is_ sid_PHASE, "phase" - _end_ + _is_ sid_PHASE, "phase" + _end_ - _rule_ sid_DECLCONSTS, "" + _rule_ sid_DECLCONSTS, "" - _repeat_ sid_DEFCONST _nt_ - _end_ + _repeat_ sid_DEFCONST _nt_ + _end_ - _rule_ sid_TEXOPS_PHASE1, "" + _rule_ sid_TEXOPS_PHASE1, "" - _is_ sid_TEXOPS_PS1_1_3 _nt_ - _or_ sid_TEXOPS_PS1_4 _nt_ - _end_ + _is_ sid_TEXOPS_PS1_1_3 _nt_ + _or_ sid_TEXOPS_PS1_4 _nt_ + _end_ - _rule_ sid_TEXOPS_PHASE2, "" + _rule_ sid_TEXOPS_PHASE2, "" - _is_ sid_TEXOPS_PS1_4 _nt_ - _end_ + _is_ sid_TEXOPS_PS1_4 _nt_ + _end_ - _rule_ sid_NUMVAL, "" + _rule_ sid_NUMVAL, "" - _is_ sid_VALUE, "Float Value" - _end_ + _is_ sid_VALUE, "Float Value" + _end_ - _rule_ sid_TEXOPS_PS1_1_3, "" + _rule_ sid_TEXOPS_PS1_1_3, "" - _repeat_ sid_TEXOP_PS1_1_3 _nt_ - _end_ + _repeat_ sid_TEXOP_PS1_1_3 _nt_ + _end_ - _rule_ sid_TEXOPS_PS1_4, "" + _rule_ sid_TEXOPS_PS1_4, "" - _repeat_ sid_TEXOP_PS1_4 _nt_ - _end_ + _repeat_ sid_TEXOP_PS1_4 _nt_ + _end_ - _rule_ sid_TEXOP_PS1_1_3, "" + _rule_ sid_TEXOP_PS1_1_3, "" - _is_ sid_TEXCISCOP_PS1_1_3 _nt_ - _and_ sid_TEX_PS1_1_3 _nt_ - _and_ sid_SEPERATOR _nt_ - _and_ sid_TEX_PS1_1_3 _nt_ + _is_ sid_TEXCISCOP_PS1_1_3 _nt_ + _and_ sid_TEX_PS1_1_3 _nt_ + _and_ sid_SEPERATOR _nt_ + _and_ sid_TEX_PS1_1_3 _nt_ - _or_ sid_TEXCOORD, "texcoord" - _and_ sid_TEX_PS1_1_3 _nt_ + _or_ sid_TEXCOORD, "texcoord" + _and_ sid_TEX_PS1_1_3 _nt_ - _or_ sid_TEX, "tex" - _and_ sid_TEX_PS1_1_3 _nt_ + _or_ sid_TEX, "tex" + _and_ sid_TEX_PS1_1_3 _nt_ - _end_ + _end_ - _rule_ sid_TEXOP_PS1_4, "" + _rule_ sid_TEXOP_PS1_4, "" - _is_ sid_TEXCRD, "texcrd" - _and_ sid_REG_PS1_4 _nt_ - _optional_ sid_TEXMASK _nt_ - _and_ sid_SEPERATOR _nt_ - _and_ sid_TEXREG_PS1_4 _nt_ + _is_ sid_TEXCRD, "texcrd" + _and_ sid_REG_PS1_4 _nt_ + _optional_ sid_TEXMASK _nt_ + _and_ sid_SEPERATOR _nt_ + _and_ sid_TEXREG_PS1_4 _nt_ - _or_ sid_TEXLD, "texld" - _and_ sid_REG_PS1_4 _nt_ - _optional_ sid_TEXMASK _nt_ - _and_ sid_SEPERATOR _nt_ - _and_ sid_TEXREG_PS1_4 _nt_ - _end_ + _or_ sid_TEXLD, "texld" + _and_ sid_REG_PS1_4 _nt_ + _optional_ sid_TEXMASK _nt_ + _and_ sid_SEPERATOR _nt_ + _and_ sid_TEXREG_PS1_4 _nt_ + _end_ - _rule_ sid_ALUOPS, "" + _rule_ sid_ALUOPS, "" - _repeat_ sid_ALU_STATEMENT _nt_ - _end_ + _repeat_ sid_ALU_STATEMENT _nt_ + _end_ - _rule_ sid_ALU_STATEMENT, "" + _rule_ sid_ALU_STATEMENT, "" - _is_ sid_COISSUE _nt_ - _and_ sid_UNARYOP _nt_ - _optional_ sid_DSTMODSAT _nt_ - _and_ sid_UNARYOP_ARGS _nt_ + _is_ sid_COISSUE _nt_ + _and_ sid_UNARYOP _nt_ + _optional_ sid_DSTMODSAT _nt_ + _and_ sid_UNARYOP_ARGS _nt_ - _or_ sid_COISSUE _nt_ - _and_ sid_BINARYOP _nt_ - _optional_ sid_DSTMODSAT _nt_ - _and_ sid_BINARYOP_ARGS _nt_ - - _or_ sid_COISSUE _nt_ - _and_ sid_TERNARYOP _nt_ - _optional_ sid_DSTMODSAT _nt_ - _and_ sid_TERNARYOP_ARGS _nt_ - _end_ + _or_ sid_COISSUE _nt_ + _and_ sid_BINARYOP _nt_ + _optional_ sid_DSTMODSAT _nt_ + _and_ sid_BINARYOP_ARGS _nt_ + + _or_ sid_COISSUE _nt_ + _and_ sid_TERNARYOP _nt_ + _optional_ sid_DSTMODSAT _nt_ + _and_ sid_TERNARYOP_ARGS _nt_ + _end_ - _rule_ sid_TEXREG_PS1_4, "" + _rule_ sid_TEXREG_PS1_4, "" - _is_ sid_TEX_PS1_4 _nt_ - _optional_ sid_TEXSWIZZLE _nt_ - _or_ sid_REG_PS1_4 _nt_ - _optional_ sid_TEXSWIZZLE _nt_ - _end_ + _is_ sid_TEX_PS1_4 _nt_ + _optional_ sid_TEXSWIZZLE _nt_ + _or_ sid_REG_PS1_4 _nt_ + _optional_ sid_TEXSWIZZLE _nt_ + _end_ - _rule_ sid_UNARYOP_ARGS, "" + _rule_ sid_UNARYOP_ARGS, "" - _is_ sid_DSTINFO _nt_ - _and_ sid_SRCINFO _nt_ - _end_ + _is_ sid_DSTINFO _nt_ + _and_ sid_SRCINFO _nt_ + _end_ - _rule_ sid_BINARYOP_ARGS, "" - - _is_ sid_DSTINFO _nt_ - _and_ sid_SRCINFO _nt_ - _and_ sid_SRCINFO _nt_ - _end_ + _rule_ sid_BINARYOP_ARGS, "" + + _is_ sid_DSTINFO _nt_ + _and_ sid_SRCINFO _nt_ + _and_ sid_SRCINFO _nt_ + _end_ - _rule_ sid_TERNARYOP_ARGS, "" - - _is_ sid_DSTINFO _nt_ - _and_ sid_SRCINFO _nt_ - _and_ sid_SRCINFO _nt_ - _and_ sid_SRCINFO _nt_ - _end_ + _rule_ sid_TERNARYOP_ARGS, "" + + _is_ sid_DSTINFO _nt_ + _and_ sid_SRCINFO _nt_ + _and_ sid_SRCINFO _nt_ + _and_ sid_SRCINFO _nt_ + _end_ - _rule_ sid_DSTINFO, "" - - _is_ sid_TEMPREG _nt_ - _optional_ sid_DSTMASK _nt_ - _end_ - - _rule_ sid_SRCINFO, "" - - _is_ sid_SEPERATOR _nt_ - _optional_ sid_PRESRCMOD _nt_ - _and_ sid_SRCNAME _nt_ - _optional_ sid_POSTSRCMOD _nt_ - _optional_ sid_SRCREP _nt_ - _end_ - - _rule_ sid_SRCNAME, "" - - _is_ sid_TEMPREG _nt_ - _or_ sid_CONSTANT _nt_ - _or_ sid_COLOR _nt_ - _end_ - - _rule_ sid_DEFCONST, "" - - _is_ sid_DEF, "def" - _and_ sid_CONSTANT _nt_ - _and_ sid_SEPERATOR _nt_ - _and_ sid_NUMVAL _nt_ - _and_ sid_SEPERATOR _nt_ - _and_ sid_NUMVAL _nt_ - _and_ sid_SEPERATOR _nt_ - _and_ sid_NUMVAL _nt_ - _and_ sid_SEPERATOR _nt_ - _and_ sid_NUMVAL _nt_ - _end_ - - _rule_ sid_CONSTANT, "" - - _is_ sid_C0, "c0" - _or_ sid_C1, "c1" - _or_ sid_C2, "c2" - _or_ sid_C3, "c3" - _or_ sid_C4, "c4" - _or_ sid_C5, "c5" - _or_ sid_C6, "c6" - _or_ sid_C7, "c7" - _end_ - - - _rule_ sid_TEXCISCOP_PS1_1_3, "" - - _is_ sid_TEXDP3TEX, "texdp3tex" - _or_ sid_TEXDP3, "texdp3" - _or_ sid_TEXM3X2PAD, "texm3x2pad" - _or_ sid_TEXM3X2TEX, "texm3x2tex" - _or_ sid_TEXM3X3PAD, "texm3x3pad" - _or_ sid_TEXM3X3TEX, "texm3x3tex" - _or_ sid_TEXM3X3SPEC, "texm3x3spec" - _or_ sid_TEXM3X3VSPEC, "texm3x3vspec" - _or_ sid_TEXREG2RGB, "texreg2rgb" - _or_ sid_TEXREG2AR, "texreg2ar" - _or_ sid_TEXREG2GB, "texreg2gb" - _end_ - - - _rule_ sid_TEXSWIZZLE, "" - - _is_ sid_STQDQ, "_dw.xyw" - _or_ sid_STQDQ, "_dw" - _or_ sid_STQDQ, "_da.rga" - _or_ sid_STQDQ, "_da" - _or_ sid_STRDR, "_dz.xyz" - _or_ sid_STRDR, "_dz" - _or_ sid_STRDR, "_db.rgb" - _or_ sid_STRDR, "_db" - _or_ sid_STR, ".xyz" - _or_ sid_STR, ".rgb" - _or_ sid_STQ, ".xyw" - _or_ sid_STQ, ".rga" - _end_ - - _rule_ sid_TEXMASK, "" - - _is_ sid_RGB, ".rgb" - _or_ sid_RGB, ".xyz" - _or_ sid_RG, ".rg" - _or_ sid_RG, ".xy" - _end_ - - _rule_ sid_SEPERATOR, "" - - _is_ sid_COMMA, "," - _end_ - - _rule_ sid_REG_PS1_4, "" - - _is_ sid_R0, "r0" - _or_ sid_R1, "r1" - _or_ sid_R2, "r2" - _or_ sid_R3, "r3" - _or_ sid_R4, "r4" - _or_ sid_R5, "r5" - _end_ - - _rule_ sid_TEX_PS1_4, "" - - _is_ sid_T0, "t0" - _or_ sid_T1, "t1" - _or_ sid_T2, "t2" - _or_ sid_T3, "t3" - _or_ sid_T4, "t4" - _or_ sid_T5, "t5" - _end_ - - _rule_ sid_REG_PS1_1_3, "" - - _is_ sid_1R0, "r0" - _or_ sid_1R1, "r1" - _end_ - - _rule_ sid_TEX_PS1_1_3, "" - - _is_ sid_1T0, "t0" - _or_ sid_1T1, "t1" - _or_ sid_1T2, "t2" - _or_ sid_1T3, "t3" - _end_ - - _rule_ sid_COLOR, "" - - _is_ sid_V0, "v0" - _or_ sid_V1, "v1" - _end_ - - - _rule_ sid_TEMPREG, "" - - _is_ sid_REG_PS1_4 _nt_ - _or_ sid_REG_PS1_1_3 _nt_ - _or_ sid_TEX_PS1_1_3 _nt_ - _end_ - - _rule_ sid_DSTMODSAT, "" - - _optional_ sid_DSTMOD _nt_ - _optional_ sid_DSTSAT _nt_ - _end_ - - _rule_ sid_UNARYOP, "" - - _is_ sid_MOV, "mov" - _end_ - - _rule_ sid_BINARYOP, "" - - _is_ sid_ADD, "add" - _or_ sid_MUL, "mul" - _or_ sid_SUB, "sub" - _or_ sid_DP3, "dp3" - _or_ sid_DP4, "dp4" - _or_ sid_BEM, "bem" - _end_ - - _rule_ sid_TERNARYOP, "" - - _is_ sid_MAD, "mad" - _or_ sid_LRP, "lrp" - _or_ sid_CND, "cnd" - _or_ sid_CMP, "cmp" - _end_ - - _rule_ sid_DSTMASK, "" - - _is_ sid_RGBA, ".rgba" - _or_ sid_RGBA, ".xyzw" - _or_ sid_RGB, ".rgb" - _or_ sid_RGB, ".xyz" - _or_ sid_RGA, ".xyw" - _or_ sid_RGA, ".rga" - _or_ sid_RBA, ".rba" - _or_ sid_RBA, ".xzw" - _or_ sid_GBA, ".gba" - _or_ sid_GBA, ".yzw" - _or_ sid_RG, ".rg" - _or_ sid_RG, ".xy" - _or_ sid_RB, ".xz" - _or_ sid_RB, ".rb" - _or_ sid_RA, ".xw" - _or_ sid_RA, ".ra" - _or_ sid_GB, ".gb" - _or_ sid_GB, ".yz" - _or_ sid_GA, ".yw" - _or_ sid_GA, ".ga" - _or_ sid_BA, ".zw" - _or_ sid_BA, ".ba" - _or_ sid_R, ".r" - _or_ sid_R, ".x" - _or_ sid_G, ".g" - _or_ sid_G, ".y" - _or_ sid_B, ".b" - _or_ sid_B, ".z" - _or_ sid_A, ".a" - _or_ sid_A, ".w" - _end_ - - _rule_ sid_SRCREP, "" - - _is_ sid_RRRR, ".r" - _or_ sid_RRRR, ".x" - _or_ sid_GGGG, ".g" - _or_ sid_GGGG, ".y" - _or_ sid_BBBB, ".b" - _or_ sid_BBBB, ".z" - _or_ sid_AAAA, ".a" - _or_ sid_AAAA, ".w" - _end_ - - _rule_ sid_PRESRCMOD, "" - - _is_ sid_INVERT, "1-" - _or_ sid_INVERT, "1 -" - _or_ sid_NEGATE, "-" - _end_ - - _rule_ sid_POSTSRCMOD, "" - - _is_ sid_BX2, "_bx2" - _or_ sid_X2, "_x2" - _or_ sid_BIAS, "_bias" - _end_ - - _rule_ sid_DSTMOD, "" - - _is_ sid_X2, "_x2" - _or_ sid_X4, "_x4" - _or_ sid_D2, "_d2" - _or_ sid_X8, "_x8" - _or_ sid_D4, "_d4" - _or_ sid_D8, "_d8" - _end_ - - _rule_ sid_DSTSAT, "" - - _is_ sid_SAT, "_sat" - _end_ - - _rule_ sid_COISSUE, "" - - _optional_ sid_PLUS, "+" - _end_ + _rule_ sid_DSTINFO, "" + + _is_ sid_TEMPREG _nt_ + _optional_ sid_DSTMASK _nt_ + _end_ + + _rule_ sid_SRCINFO, "" + + _is_ sid_SEPERATOR _nt_ + _optional_ sid_PRESRCMOD _nt_ + _and_ sid_SRCNAME _nt_ + _optional_ sid_POSTSRCMOD _nt_ + _optional_ sid_SRCREP _nt_ + _end_ + + _rule_ sid_SRCNAME, "" + + _is_ sid_TEMPREG _nt_ + _or_ sid_CONSTANT _nt_ + _or_ sid_COLOR _nt_ + _end_ + + _rule_ sid_DEFCONST, "" + + _is_ sid_DEF, "def" + _and_ sid_CONSTANT _nt_ + _and_ sid_SEPERATOR _nt_ + _and_ sid_NUMVAL _nt_ + _and_ sid_SEPERATOR _nt_ + _and_ sid_NUMVAL _nt_ + _and_ sid_SEPERATOR _nt_ + _and_ sid_NUMVAL _nt_ + _and_ sid_SEPERATOR _nt_ + _and_ sid_NUMVAL _nt_ + _end_ + + _rule_ sid_CONSTANT, "" + + _is_ sid_C0, "c0" + _or_ sid_C1, "c1" + _or_ sid_C2, "c2" + _or_ sid_C3, "c3" + _or_ sid_C4, "c4" + _or_ sid_C5, "c5" + _or_ sid_C6, "c6" + _or_ sid_C7, "c7" + _end_ + + + _rule_ sid_TEXCISCOP_PS1_1_3, "" + + _is_ sid_TEXDP3TEX, "texdp3tex" + _or_ sid_TEXDP3, "texdp3" + _or_ sid_TEXM3X2PAD, "texm3x2pad" + _or_ sid_TEXM3X2TEX, "texm3x2tex" + _or_ sid_TEXM3X3PAD, "texm3x3pad" + _or_ sid_TEXM3X3TEX, "texm3x3tex" + _or_ sid_TEXM3X3SPEC, "texm3x3spec" + _or_ sid_TEXM3X3VSPEC, "texm3x3vspec" + _or_ sid_TEXREG2RGB, "texreg2rgb" + _or_ sid_TEXREG2AR, "texreg2ar" + _or_ sid_TEXREG2GB, "texreg2gb" + _end_ + + + _rule_ sid_TEXSWIZZLE, "" + + _is_ sid_STQDQ, "_dw.xyw" + _or_ sid_STQDQ, "_dw" + _or_ sid_STQDQ, "_da.rga" + _or_ sid_STQDQ, "_da" + _or_ sid_STRDR, "_dz.xyz" + _or_ sid_STRDR, "_dz" + _or_ sid_STRDR, "_db.rgb" + _or_ sid_STRDR, "_db" + _or_ sid_STR, ".xyz" + _or_ sid_STR, ".rgb" + _or_ sid_STQ, ".xyw" + _or_ sid_STQ, ".rga" + _end_ + + _rule_ sid_TEXMASK, "" + + _is_ sid_RGB, ".rgb" + _or_ sid_RGB, ".xyz" + _or_ sid_RG, ".rg" + _or_ sid_RG, ".xy" + _end_ + + _rule_ sid_SEPERATOR, "" + + _is_ sid_COMMA, "," + _end_ + + _rule_ sid_REG_PS1_4, "" + + _is_ sid_R0, "r0" + _or_ sid_R1, "r1" + _or_ sid_R2, "r2" + _or_ sid_R3, "r3" + _or_ sid_R4, "r4" + _or_ sid_R5, "r5" + _end_ + + _rule_ sid_TEX_PS1_4, "" + + _is_ sid_T0, "t0" + _or_ sid_T1, "t1" + _or_ sid_T2, "t2" + _or_ sid_T3, "t3" + _or_ sid_T4, "t4" + _or_ sid_T5, "t5" + _end_ + + _rule_ sid_REG_PS1_1_3, "" + + _is_ sid_1R0, "r0" + _or_ sid_1R1, "r1" + _end_ + + _rule_ sid_TEX_PS1_1_3, "" + + _is_ sid_1T0, "t0" + _or_ sid_1T1, "t1" + _or_ sid_1T2, "t2" + _or_ sid_1T3, "t3" + _end_ + + _rule_ sid_COLOR, "" + + _is_ sid_V0, "v0" + _or_ sid_V1, "v1" + _end_ + + + _rule_ sid_TEMPREG, "" + + _is_ sid_REG_PS1_4 _nt_ + _or_ sid_REG_PS1_1_3 _nt_ + _or_ sid_TEX_PS1_1_3 _nt_ + _end_ + + _rule_ sid_DSTMODSAT, "" + + _optional_ sid_DSTMOD _nt_ + _optional_ sid_DSTSAT _nt_ + _end_ + + _rule_ sid_UNARYOP, "" + + _is_ sid_MOV, "mov" + _end_ + + _rule_ sid_BINARYOP, "" + + _is_ sid_ADD, "add" + _or_ sid_MUL, "mul" + _or_ sid_SUB, "sub" + _or_ sid_DP3, "dp3" + _or_ sid_DP4, "dp4" + _or_ sid_BEM, "bem" + _end_ + + _rule_ sid_TERNARYOP, "" + + _is_ sid_MAD, "mad" + _or_ sid_LRP, "lrp" + _or_ sid_CND, "cnd" + _or_ sid_CMP, "cmp" + _end_ + + _rule_ sid_DSTMASK, "" + + _is_ sid_RGBA, ".rgba" + _or_ sid_RGBA, ".xyzw" + _or_ sid_RGB, ".rgb" + _or_ sid_RGB, ".xyz" + _or_ sid_RGA, ".xyw" + _or_ sid_RGA, ".rga" + _or_ sid_RBA, ".rba" + _or_ sid_RBA, ".xzw" + _or_ sid_GBA, ".gba" + _or_ sid_GBA, ".yzw" + _or_ sid_RG, ".rg" + _or_ sid_RG, ".xy" + _or_ sid_RB, ".xz" + _or_ sid_RB, ".rb" + _or_ sid_RA, ".xw" + _or_ sid_RA, ".ra" + _or_ sid_GB, ".gb" + _or_ sid_GB, ".yz" + _or_ sid_GA, ".yw" + _or_ sid_GA, ".ga" + _or_ sid_BA, ".zw" + _or_ sid_BA, ".ba" + _or_ sid_R, ".r" + _or_ sid_R, ".x" + _or_ sid_G, ".g" + _or_ sid_G, ".y" + _or_ sid_B, ".b" + _or_ sid_B, ".z" + _or_ sid_A, ".a" + _or_ sid_A, ".w" + _end_ + + _rule_ sid_SRCREP, "" + + _is_ sid_RRRR, ".r" + _or_ sid_RRRR, ".x" + _or_ sid_GGGG, ".g" + _or_ sid_GGGG, ".y" + _or_ sid_BBBB, ".b" + _or_ sid_BBBB, ".z" + _or_ sid_AAAA, ".a" + _or_ sid_AAAA, ".w" + _end_ + + _rule_ sid_PRESRCMOD, "" + + _is_ sid_INVERT, "1-" + _or_ sid_INVERT, "1 -" + _or_ sid_NEGATE, "-" + _end_ + + _rule_ sid_POSTSRCMOD, "" + + _is_ sid_BX2, "_bx2" + _or_ sid_X2, "_x2" + _or_ sid_BIAS, "_bias" + _end_ + + _rule_ sid_DSTMOD, "" + + _is_ sid_X2, "_x2" + _or_ sid_X4, "_x4" + _or_ sid_D2, "_d2" + _or_ sid_X8, "_x8" + _or_ sid_D4, "_d4" + _or_ sid_D8, "_d8" + _end_ + + _rule_ sid_DSTSAT, "" + + _is_ sid_SAT, "_sat" + _end_ + + _rule_ sid_COISSUE, "" + + _optional_ sid_PLUS, "+" + _end_ }; @@ -654,263 +654,263 @@ PS_1_4::TokenRule PS_1_4::PS_1_x_RulePath[] = { #define _token_end_ ,0,0} // macro token expansion for ps_1_2 instruction: texreg2ar PS_1_4::TokenInst PS_1_4::texreg2ar[] = { - // mov r(x).r, r(y).a - { sid_UNARYOP, sid_MOV - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_DSTMASK, sid_R - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - _token_ sid_SRCREP, sid_AAAA - - // mov r(x).g, r(y).r - _token_ sid_UNARYOP, sid_MOV - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_DSTMASK, sid_G - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - _token_ sid_SRCREP, sid_RRRR - - // texld r(x), r(x) - _token_ sid_TEXOP_PS1_4, sid_TEXLD - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R1 - _token_end_ + // mov r(x).r, r(y).a + { sid_UNARYOP, sid_MOV + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_DSTMASK, sid_R + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + _token_ sid_SRCREP, sid_AAAA + + // mov r(x).g, r(y).r + _token_ sid_UNARYOP, sid_MOV + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_DSTMASK, sid_G + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + _token_ sid_SRCREP, sid_RRRR + + // texld r(x), r(x) + _token_ sid_TEXOP_PS1_4, sid_TEXLD + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R1 + _token_end_ }; PS_1_4::RegModOffset PS_1_4::texreg2xx_RegMods[] = { - {1, R_BASE, 0}, - {7, R_BASE, 0}, - {13, R_BASE, 0}, - {15, R_BASE, 0}, - {4, R_BASE, 1}, - {10, R_BASE, 1}, + {1, R_BASE, 0}, + {7, R_BASE, 0}, + {13, R_BASE, 0}, + {15, R_BASE, 0}, + {4, R_BASE, 1}, + {10, R_BASE, 1}, }; PS_1_4::MacroRegModify PS_1_4::texreg2ar_MacroMods = { - texreg2ar, ARRAYSIZE(texreg2ar), - texreg2xx_RegMods, ARRAYSIZE(texreg2xx_RegMods) + texreg2ar, ARRAYSIZE(texreg2ar), + texreg2xx_RegMods, ARRAYSIZE(texreg2xx_RegMods) }; // macro token expansion for ps_1_2 instruction: texreg2gb PS_1_4::TokenInst PS_1_4::texreg2gb[] = { - // mov r(x).r, r(y).g - { sid_UNARYOP, sid_MOV - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_DSTMASK, sid_R - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - _token_ sid_SRCREP, sid_GGGG - - // mov r(x).g, r(y).b - _token_ sid_UNARYOP, sid_MOV - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_DSTMASK, sid_G - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - _token_ sid_SRCREP, sid_BBBB - - // texld r(x), r(x) - _token_ sid_TEXOP_PS1_4, sid_TEXLD - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R1 - _token_end_ + // mov r(x).r, r(y).g + { sid_UNARYOP, sid_MOV + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_DSTMASK, sid_R + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + _token_ sid_SRCREP, sid_GGGG + + // mov r(x).g, r(y).b + _token_ sid_UNARYOP, sid_MOV + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_DSTMASK, sid_G + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + _token_ sid_SRCREP, sid_BBBB + + // texld r(x), r(x) + _token_ sid_TEXOP_PS1_4, sid_TEXLD + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R1 + _token_end_ }; PS_1_4::MacroRegModify PS_1_4::texreg2gb_MacroMods = { - texreg2gb, ARRAYSIZE(texreg2gb), - texreg2xx_RegMods, ARRAYSIZE(texreg2xx_RegMods) + texreg2gb, ARRAYSIZE(texreg2gb), + texreg2xx_RegMods, ARRAYSIZE(texreg2xx_RegMods) }; // macro token expansion for ps_1_1 instruction: texdp3 PS_1_4::TokenInst PS_1_4::texdp3[] = { - // texcoord t(x) - { sid_TEXOP_PS1_1_3, sid_TEXCOORD - _token_ sid_TEX_PS1_1_3, sid_1T1 - - // dp3 r(x), r(x), r(y) - _token_ sid_BINARYOP, sid_DP3 - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - _token_end_ + // texcoord t(x) + { sid_TEXOP_PS1_1_3, sid_TEXCOORD + _token_ sid_TEX_PS1_1_3, sid_1T1 + + // dp3 r(x), r(x), r(y) + _token_ sid_BINARYOP, sid_DP3 + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + _token_end_ }; PS_1_4::RegModOffset PS_1_4::texdp3_RegMods[] = { - {1, T_BASE, 0}, - {3, R_BASE, 0}, - {5, R_BASE, 0}, - {7, R_BASE, 1}, + {1, T_BASE, 0}, + {3, R_BASE, 0}, + {5, R_BASE, 0}, + {7, R_BASE, 1}, }; PS_1_4::MacroRegModify PS_1_4::texdp3_MacroMods = { - texdp3, ARRAYSIZE(texdp3), - texdp3_RegMods, ARRAYSIZE(texdp3_RegMods) + texdp3, ARRAYSIZE(texdp3), + texdp3_RegMods, ARRAYSIZE(texdp3_RegMods) }; // macro token expansion for ps_1_1 instruction: texdp3tex PS_1_4::TokenInst PS_1_4::texdp3tex[] = { - // texcoord t(x) - { sid_TEXOP_PS1_1_3, sid_TEXCOORD - _token_ sid_TEX_PS1_1_3, sid_1T1 - - // dp3 r1, r(x), r(y) - _token_ sid_BINARYOP, sid_DP3 - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - - // texld r(x), r(x) - _token_ sid_TEXOP_PS1_4, sid_TEXLD - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R1 - _token_end_ + // texcoord t(x) + { sid_TEXOP_PS1_1_3, sid_TEXCOORD + _token_ sid_TEX_PS1_1_3, sid_1T1 + + // dp3 r1, r(x), r(y) + _token_ sid_BINARYOP, sid_DP3 + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + + // texld r(x), r(x) + _token_ sid_TEXOP_PS1_4, sid_TEXLD + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R1 + _token_end_ }; PS_1_4::RegModOffset PS_1_4::texdp3tex_RegMods[] = { - {1, T_BASE, 0}, - {3, R_BASE, 0}, - {5, R_BASE, 0}, - {7, R_BASE, 1}, - {9, R_BASE, 1}, - {11, R_BASE, 1}, + {1, T_BASE, 0}, + {3, R_BASE, 0}, + {5, R_BASE, 0}, + {7, R_BASE, 1}, + {9, R_BASE, 1}, + {11, R_BASE, 1}, }; PS_1_4::MacroRegModify PS_1_4::texdp3tex_MacroMods = { - texdp3tex, ARRAYSIZE(texdp3tex), - texdp3tex_RegMods, ARRAYSIZE(texdp3tex_RegMods) + texdp3tex, ARRAYSIZE(texdp3tex), + texdp3tex_RegMods, ARRAYSIZE(texdp3tex_RegMods) }; // macro token expansion for ps_1_1 instruction: texm3x2pad PS_1_4::TokenInst PS_1_4::texm3x2pad[] = { - // texcoord t(x) - { sid_TEXOP_PS1_1_3, sid_TEXCOORD - _token_ sid_TEX_PS1_1_3, sid_1T0 - - // dp3 r4.r, r(x), r(y) - _token_ sid_BINARYOP, sid_DP3 - _token_ sid_REG_PS1_4, sid_R4 - _token_ sid_DSTMASK, sid_R - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - _token_end_ + // texcoord t(x) + { sid_TEXOP_PS1_1_3, sid_TEXCOORD + _token_ sid_TEX_PS1_1_3, sid_1T0 + + // dp3 r4.r, r(x), r(y) + _token_ sid_BINARYOP, sid_DP3 + _token_ sid_REG_PS1_4, sid_R4 + _token_ sid_DSTMASK, sid_R + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + _token_end_ }; PS_1_4::RegModOffset PS_1_4::texm3xxpad_RegMods[] = { - {1, T_BASE, 0}, - {6, R_BASE, 0}, - {8, R_BASE, 1}, + {1, T_BASE, 0}, + {6, R_BASE, 0}, + {8, R_BASE, 1}, }; PS_1_4::MacroRegModify PS_1_4::texm3x2pad_MacroMods = { - texm3x2pad, ARRAYSIZE(texm3x2pad), - texm3xxpad_RegMods, ARRAYSIZE(texm3xxpad_RegMods) + texm3x2pad, ARRAYSIZE(texm3x2pad), + texm3xxpad_RegMods, ARRAYSIZE(texm3xxpad_RegMods) }; // macro token expansion for ps_1_1 instruction: texm3x2tex PS_1_4::TokenInst PS_1_4::texm3x2tex[] = { - // texcoord t(x) - { sid_TEXOP_PS1_1_3, sid_TEXCOORD - _token_ sid_TEX_PS1_1_3, sid_1T1 - - // dp3 r4.g, r(x), r(y) - _token_ sid_BINARYOP, sid_DP3 - _token_ sid_REG_PS1_4, sid_R4 - _token_ sid_DSTMASK, sid_G - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - - // texld r(x), r4 - _token_ sid_TEXOP_PS1_4, sid_TEXLD - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R4 - _token_end_ + // texcoord t(x) + { sid_TEXOP_PS1_1_3, sid_TEXCOORD + _token_ sid_TEX_PS1_1_3, sid_1T1 + + // dp3 r4.g, r(x), r(y) + _token_ sid_BINARYOP, sid_DP3 + _token_ sid_REG_PS1_4, sid_R4 + _token_ sid_DSTMASK, sid_G + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + + // texld r(x), r4 + _token_ sid_TEXOP_PS1_4, sid_TEXLD + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R4 + _token_end_ }; PS_1_4::RegModOffset PS_1_4::texm3xxtex_RegMods[] = { - {1, T_BASE, 0}, - {6, R_BASE, 0}, - {8, R_BASE, 1}, - {10, R_BASE, 0} + {1, T_BASE, 0}, + {6, R_BASE, 0}, + {8, R_BASE, 1}, + {10, R_BASE, 0} }; PS_1_4::MacroRegModify PS_1_4::texm3x2tex_MacroMods = { - texm3x2tex, ARRAYSIZE(texm3x2tex), - texm3xxtex_RegMods, ARRAYSIZE(texm3xxtex_RegMods) + texm3x2tex, ARRAYSIZE(texm3x2tex), + texm3xxtex_RegMods, ARRAYSIZE(texm3xxtex_RegMods) }; // macro token expansion for ps_1_1 instruction: texm3x3tex PS_1_4::TokenInst PS_1_4::texm3x3pad[] = { - // texcoord t(x) - { sid_TEXOP_PS1_1_3, sid_TEXCOORD - _token_ sid_TEX_PS1_1_3, sid_1T0 - - // dp3 r4.b, r(x), r(y) - _token_ sid_BINARYOP, sid_DP3 - _token_ sid_REG_PS1_4, sid_R4 - _token_ sid_DSTMASK, sid_B - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - _token_end_ + // texcoord t(x) + { sid_TEXOP_PS1_1_3, sid_TEXCOORD + _token_ sid_TEX_PS1_1_3, sid_1T0 + + // dp3 r4.b, r(x), r(y) + _token_ sid_BINARYOP, sid_DP3 + _token_ sid_REG_PS1_4, sid_R4 + _token_ sid_DSTMASK, sid_B + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + _token_end_ }; PS_1_4::MacroRegModify PS_1_4::texm3x3pad_MacroMods = { - texm3x3pad, ARRAYSIZE(texm3x3pad), - texm3xxpad_RegMods, ARRAYSIZE(texm3xxpad_RegMods) + texm3x3pad, ARRAYSIZE(texm3x3pad), + texm3xxpad_RegMods, ARRAYSIZE(texm3xxpad_RegMods) }; // macro token expansion for ps_1_1 instruction: texm3x3pad PS_1_4::TokenInst PS_1_4::texm3x3tex[] = { - // texcoord t(x) - { sid_TEXOP_PS1_1_3, sid_TEXCOORD - _token_ sid_TEX_PS1_1_3, sid_1T1 - - // dp3 r4.b, r(x), r(y) - _token_ sid_BINARYOP, sid_DP3 - _token_ sid_REG_PS1_4, sid_R4 - _token_ sid_DSTMASK, sid_B - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - - // texld r1, r4 - _token_ sid_TEXOP_PS1_4, sid_TEXLD - _token_ sid_REG_PS1_4, sid_R1 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R4 - _token_end_ + // texcoord t(x) + { sid_TEXOP_PS1_1_3, sid_TEXCOORD + _token_ sid_TEX_PS1_1_3, sid_1T1 + + // dp3 r4.b, r(x), r(y) + _token_ sid_BINARYOP, sid_DP3 + _token_ sid_REG_PS1_4, sid_R4 + _token_ sid_DSTMASK, sid_B + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + + // texld r1, r4 + _token_ sid_TEXOP_PS1_4, sid_TEXLD + _token_ sid_REG_PS1_4, sid_R1 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R4 + _token_end_ }; @@ -919,92 +919,92 @@ PS_1_4::TokenInst PS_1_4::texm3x3tex[] = { PS_1_4::MacroRegModify PS_1_4::texm3x3tex_MacroMods = { - texm3x3tex, ARRAYSIZE(texm3x3tex), - texm3xxtex_RegMods, ARRAYSIZE(texm3xxtex_RegMods) + texm3x3tex, ARRAYSIZE(texm3x3tex), + texm3xxtex_RegMods, ARRAYSIZE(texm3xxtex_RegMods) }; // macro token expansion for ps_1_1 instruction: texm3x3spec PS_1_4::TokenInst PS_1_4::texm3x3spec[] = { - // texcoord t(x) - { sid_TEXOP_PS1_1_3, sid_TEXCOORD - _token_ sid_TEX_PS1_1_3, sid_1T3 - - // dp3 r4.b, r3, r(x) - _token_ sid_BINARYOP, sid_DP3 - _token_ sid_REG_PS1_4, sid_R4 - _token_ sid_DSTMASK, sid_B - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R3 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R0 - - // dp3_x2 r3, r4, c(x) - _token_ sid_BINARYOP, sid_DP3 - _token_ sid_DSTMOD, sid_X2 - _token_ sid_REG_PS1_4, sid_R3 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R4 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_CONSTANT, sid_C0 - - // mul r3, r3, c(x) - _token_ sid_UNARYOP, sid_MUL - _token_ sid_REG_PS1_4, sid_R3 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R3 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_CONSTANT, sid_C0 - - // dp3 r2, r4, r4 - _token_ sid_BINARYOP, sid_DP3 - _token_ sid_REG_PS1_4, sid_R2 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R4 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R4 - - // mad r4.rgb, 1-c(x), r2, r3 - _token_ sid_TERNARYOP, sid_MAD - _token_ sid_REG_PS1_4, sid_R4 - _token_ sid_DSTMASK, sid_RGB - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_PRESRCMOD, sid_INVERT - _token_ sid_CONSTANT, sid_C0 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R2 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R3 - - // + mov r4.a, r2.r - _token_ sid_UNARYOP, sid_MOV - _token_ sid_REG_PS1_4, sid_R4 - _token_ sid_DSTMASK, sid_A - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R2 - _token_ sid_SRCREP, sid_RRRR - - // texld r3, r4.xyz_dz - _token_ sid_TEXOP_PS1_4, sid_TEXLD - _token_ sid_REG_PS1_4, sid_R3 - _token_ sid_SEPERATOR, sid_COMMA - _token_ sid_REG_PS1_4, sid_R4 - _token_ sid_TEXSWIZZLE, sid_STRDR - _token_end_ + // texcoord t(x) + { sid_TEXOP_PS1_1_3, sid_TEXCOORD + _token_ sid_TEX_PS1_1_3, sid_1T3 + + // dp3 r4.b, r3, r(x) + _token_ sid_BINARYOP, sid_DP3 + _token_ sid_REG_PS1_4, sid_R4 + _token_ sid_DSTMASK, sid_B + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R3 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R0 + + // dp3_x2 r3, r4, c(x) + _token_ sid_BINARYOP, sid_DP3 + _token_ sid_DSTMOD, sid_X2 + _token_ sid_REG_PS1_4, sid_R3 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R4 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_CONSTANT, sid_C0 + + // mul r3, r3, c(x) + _token_ sid_UNARYOP, sid_MUL + _token_ sid_REG_PS1_4, sid_R3 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R3 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_CONSTANT, sid_C0 + + // dp3 r2, r4, r4 + _token_ sid_BINARYOP, sid_DP3 + _token_ sid_REG_PS1_4, sid_R2 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R4 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R4 + + // mad r4.rgb, 1-c(x), r2, r3 + _token_ sid_TERNARYOP, sid_MAD + _token_ sid_REG_PS1_4, sid_R4 + _token_ sid_DSTMASK, sid_RGB + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_PRESRCMOD, sid_INVERT + _token_ sid_CONSTANT, sid_C0 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R2 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R3 + + // + mov r4.a, r2.r + _token_ sid_UNARYOP, sid_MOV + _token_ sid_REG_PS1_4, sid_R4 + _token_ sid_DSTMASK, sid_A + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R2 + _token_ sid_SRCREP, sid_RRRR + + // texld r3, r4.xyz_dz + _token_ sid_TEXOP_PS1_4, sid_TEXLD + _token_ sid_REG_PS1_4, sid_R3 + _token_ sid_SEPERATOR, sid_COMMA + _token_ sid_REG_PS1_4, sid_R4 + _token_ sid_TEXSWIZZLE, sid_STRDR + _token_end_ }; PS_1_4::RegModOffset PS_1_4::texm3x3spec_RegMods[] = { - {8, R_BASE, 1}, - {15, R_BASE, 2}, - {21, C_BASE, 2}, - {33, C_BASE, 2}, + {8, R_BASE, 1}, + {15, R_BASE, 2}, + {21, C_BASE, 2}, + {33, C_BASE, 2}, }; PS_1_4::MacroRegModify PS_1_4::texm3x3spec_MacroMods = { - texm3x3spec, ARRAYSIZE(texm3x3spec), - texm3x3spec_RegMods, ARRAYSIZE(texm3x3spec_RegMods) + texm3x3spec, ARRAYSIZE(texm3x3spec), + texm3x3spec_RegMods, ARRAYSIZE(texm3x3spec_RegMods) }; @@ -1012,30 +1012,30 @@ PS_1_4::MacroRegModify PS_1_4::texm3x3spec_MacroMods = { PS_1_4::PS_1_4() { - // allocate enough room for a large pixel shader - mPhase1TEX_mi.reserve(50); - mPhase2TEX_mi.reserve(30); - mPhase1ALU_mi.reserve(100); - mPhase2ALU_mi.reserve(100); - - - mSymbolTypeLib = PS_1_4_SymbolTypeLib; - mSymbolTypeLibCnt = ARRAYSIZE(PS_1_4_SymbolTypeLib); - mRootRulePath = PS_1_x_RulePath; - mRulePathLibCnt = ARRAYSIZE(PS_1_x_RulePath); - // tell compiler what the symbol id is for a numeric value - mValueID = sid_VALUE; - // The type library must have text definitions initialized - // before compiler is invoked - - // only need to initialize the rule database once - if(LibInitialized == false) { - InitSymbolTypeLib(); - LibInitialized = true; - } - - // set initial context to recognize PS base instructions - mActiveContexts = ckp_PS_BASE; + // allocate enough room for a large pixel shader + mPhase1TEX_mi.reserve(50); + mPhase2TEX_mi.reserve(30); + mPhase1ALU_mi.reserve(100); + mPhase2ALU_mi.reserve(100); + + + mSymbolTypeLib = PS_1_4_SymbolTypeLib; + mSymbolTypeLibCnt = ARRAYSIZE(PS_1_4_SymbolTypeLib); + mRootRulePath = PS_1_x_RulePath; + mRulePathLibCnt = ARRAYSIZE(PS_1_x_RulePath); + // tell compiler what the symbol id is for a numeric value + mValueID = sid_VALUE; + // The type library must have text definitions initialized + // before compiler is invoked + + // only need to initialize the rule database once + if(LibInitialized == false) { + InitSymbolTypeLib(); + LibInitialized = true; + } + + // set initial context to recognize PS base instructions + mActiveContexts = ckp_PS_BASE; } @@ -1158,11 +1158,11 @@ bool PS_1_4::bindMachineInstInPassToFragmentShader(const MachineInstContainer & instIDX += 4; break; - default: - instIDX = instCount; - // should generate an error since an unknown instruction was found - // instead for now the bind process is terminated and the fragment program may still function - // but its output may not be what was programmed + default: + instIDX = instCount; + // should generate an error since an unknown instruction was found + // instead for now the bind process is terminated and the fragment program may still function + // but its output may not be what was programmed } // end of switch @@ -1176,79 +1176,79 @@ bool PS_1_4::bindMachineInstInPassToFragmentShader(const MachineInstContainer & size_t PS_1_4::getMachineInst( size_t Idx) { - if (Idx < mPhase1TEX_mi.size()) { - return mPhase1TEX_mi[Idx]; - } - else { - Idx -= mPhase1TEX_mi.size(); - if (Idx < mPhase1ALU_mi.size()) { - return mPhase1ALU_mi[Idx]; - } - else { - Idx -= mPhase1ALU_mi.size(); - if (Idx < mPhase2TEX_mi.size()) { - return mPhase2TEX_mi[Idx]; - } - else { - Idx -= mPhase2TEX_mi.size(); - if (Idx < mPhase2ALU_mi.size()) { - return mPhase2ALU_mi[Idx]; - } - - } - - } - - } - - return 0; + if (Idx < mPhase1TEX_mi.size()) { + return mPhase1TEX_mi[Idx]; + } + else { + Idx -= mPhase1TEX_mi.size(); + if (Idx < mPhase1ALU_mi.size()) { + return mPhase1ALU_mi[Idx]; + } + else { + Idx -= mPhase1ALU_mi.size(); + if (Idx < mPhase2TEX_mi.size()) { + return mPhase2TEX_mi[Idx]; + } + else { + Idx -= mPhase2TEX_mi.size(); + if (Idx < mPhase2ALU_mi.size()) { + return mPhase2ALU_mi[Idx]; + } + + } + + } + + } + + return 0; } void PS_1_4::addMachineInst(const PhaseType phase, const uint inst) { - switch(phase) { + switch(phase) { - case ptPHASE1TEX: - mPhase1TEX_mi.push_back(inst); - break; + case ptPHASE1TEX: + mPhase1TEX_mi.push_back(inst); + break; - case ptPHASE1ALU: - mPhase1ALU_mi.push_back(inst); - break; + case ptPHASE1ALU: + mPhase1ALU_mi.push_back(inst); + break; - case ptPHASE2TEX: - mPhase2TEX_mi.push_back(inst); + case ptPHASE2TEX: + mPhase2TEX_mi.push_back(inst); - break; + break; - case ptPHASE2ALU: - mPhase2ALU_mi.push_back(inst); - break; + case ptPHASE2ALU: + mPhase2ALU_mi.push_back(inst); + break; - } // end switch(phase) + } // end switch(phase) } size_t PS_1_4::getMachineInstCount() { - return (mPhase1TEX_mi.size() + mPhase1ALU_mi.size() + mPhase2TEX_mi.size() + mPhase2ALU_mi.size()); + return (mPhase1TEX_mi.size() + mPhase1ALU_mi.size() + mPhase2TEX_mi.size() + mPhase2ALU_mi.size()); } bool PS_1_4::bindAllMachineInstToFragmentShader() { - bool passed; + bool passed; - // there are 4 machine instruction ques to pass to the ATI fragment shader - passed = bindMachineInstInPassToFragmentShader(mPhase1TEX_mi); - passed &= bindMachineInstInPassToFragmentShader(mPhase1ALU_mi); - passed &= bindMachineInstInPassToFragmentShader(mPhase2TEX_mi); - passed &= bindMachineInstInPassToFragmentShader(mPhase2ALU_mi); - return passed; + // there are 4 machine instruction ques to pass to the ATI fragment shader + passed = bindMachineInstInPassToFragmentShader(mPhase1TEX_mi); + passed &= bindMachineInstInPassToFragmentShader(mPhase1ALU_mi); + passed &= bindMachineInstInPassToFragmentShader(mPhase2TEX_mi); + passed &= bindMachineInstInPassToFragmentShader(mPhase2ALU_mi); + return passed; } @@ -1256,236 +1256,236 @@ bool PS_1_4::bindAllMachineInstToFragmentShader() bool PS_1_4::expandMacro(const MacroRegModify & MacroMod) { - RegModOffset * regmod; + RegModOffset * regmod; - // set source and destination registers in macro expansion - for (uint i = 0; i < MacroMod.RegModSize; i++) { - regmod = &MacroMod.RegMods[i]; - MacroMod.Macro[regmod->MacroOffset].mID = regmod->RegisterBase + mOpParrams[regmod->OpParramsIndex].Arg; + // set source and destination registers in macro expansion + for (uint i = 0; i < MacroMod.RegModSize; i++) { + regmod = &MacroMod.RegMods[i]; + MacroMod.Macro[regmod->MacroOffset].mID = regmod->RegisterBase + mOpParrams[regmod->OpParramsIndex].Arg; - } + } - // turn macro support on so that ps.1.4 ALU instructions get put in phase 1 alu instruction sequence container - mMacroOn = true; - // pass macro tokens on to be turned into machine instructions - // expand macro to ps.1.4 by doing recursive call to doPass2 - bool passed = Pass2scan(MacroMod.Macro, MacroMod.MacroSize); - mMacroOn = false; + // turn macro support on so that ps.1.4 ALU instructions get put in phase 1 alu instruction sequence container + mMacroOn = true; + // pass macro tokens on to be turned into machine instructions + // expand macro to ps.1.4 by doing recursive call to doPass2 + bool passed = Pass2scan(MacroMod.Macro, MacroMod.MacroSize); + mMacroOn = false; - return passed; + return passed; } bool PS_1_4::BuildMachineInst() { - // check the states to see if a machine instruction can be assembled - - // assume all arguments have been set up - bool passed = false; - - - - passed = true; // assume everything will go okay until proven otherwise - - // start with machine NOP instruction - // this is used after the switch to see if an instruction was set up - // determine which MachineInstID is required based on the op instruction - mOpType = mi_NOP; - - switch(mOpInst) { - // ALU operations - case sid_ADD: - case sid_SUB: - case sid_MUL: - case sid_MAD: - case sid_LRP: - case sid_MOV: - case sid_CMP: - case sid_CND: - case sid_DP2ADD: - case sid_DP3: - case sid_DP4: - mOpType = (MachineInstID)(mi_COLOROP1 + mArgCnt - 1); - - // if context is ps.1.x and Macro not on or a phase marker was found then put all ALU ops in phase 2 ALU container - if (((mActiveContexts & ckp_PS_1_1) && !mMacroOn) || mPhaseMarkerFound) mInstructionPhase = ptPHASE2ALU; - else mInstructionPhase = ptPHASE1ALU; - // check for alpha op in destination register which is OpParrams[0] - // if no Mask for destination then make it .rgba - if(mOpParrams[0].MaskRep == 0) mOpParrams[0].MaskRep = - GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT; - if (mOpParrams[0].MaskRep & ALPHA_BIT) { - mDo_Alpha = true; - mOpParrams[0].MaskRep -= ALPHA_BIT; - if(mOpParrams[0].MaskRep == 0) mOpType = mi_NOP; // only do alpha op - } - break; - - case sid_TEXCRD: - mOpType = mi_PASSTEXCOORD; - if (mPhaseMarkerFound) mInstructionPhase = ptPHASE2TEX; - else mInstructionPhase = ptPHASE1TEX; - break; - - case sid_TEXLD: - mOpType = mi_SAMPLEMAP; - if (mPhaseMarkerFound) mInstructionPhase = ptPHASE2TEX; - else mInstructionPhase = ptPHASE1TEX; - break; - - case sid_TEX: // PS_1_1 emulation - mOpType = mi_TEX; - mInstructionPhase = ptPHASE1TEX; - break; - - case sid_TEXCOORD: // PS_1_1 emulation - mOpType = mi_TEXCOORD; - mInstructionPhase = ptPHASE1TEX; - break; - - case sid_TEXREG2AR: - passed = expandMacro(texreg2ar_MacroMods); - break; - - case sid_TEXREG2GB: - passed = expandMacro(texreg2gb_MacroMods); - break; - - case sid_TEXDP3: - passed = expandMacro(texdp3_MacroMods); - break; - - case sid_TEXDP3TEX: - passed = expandMacro(texdp3tex_MacroMods); - break; - - case sid_TEXM3X2PAD: - passed = expandMacro(texm3x2pad_MacroMods); - break; - - case sid_TEXM3X2TEX: - passed = expandMacro(texm3x2tex_MacroMods); - break; - - case sid_TEXM3X3PAD: - // only 2 texm3x3pad instructions allowed - // use count to modify macro to select which mask to use - if(mTexm3x3padCount<2) { - texm3x3pad[4].mID = sid_R + mTexm3x3padCount; - mTexm3x3padCount++; - passed = expandMacro(texm3x3pad_MacroMods); - - } - else passed = false; - - break; - - case sid_TEXM3X3TEX: - passed = expandMacro(texm3x3tex_MacroMods); - break; - - case sid_DEF: - mOpType = mi_SETCONSTANTS; - mInstructionPhase = ptPHASE1TEX; - break; - - case sid_PHASE: // PS_1_4 only - mPhaseMarkerFound = true; - break; - - } // end of switch - - if(passed) passed = expandMachineInstruction(); - - return passed; + // check the states to see if a machine instruction can be assembled + + // assume all arguments have been set up + bool passed = false; + + + + passed = true; // assume everything will go okay until proven otherwise + + // start with machine NOP instruction + // this is used after the switch to see if an instruction was set up + // determine which MachineInstID is required based on the op instruction + mOpType = mi_NOP; + + switch(mOpInst) { + // ALU operations + case sid_ADD: + case sid_SUB: + case sid_MUL: + case sid_MAD: + case sid_LRP: + case sid_MOV: + case sid_CMP: + case sid_CND: + case sid_DP2ADD: + case sid_DP3: + case sid_DP4: + mOpType = (MachineInstID)(mi_COLOROP1 + mArgCnt - 1); + + // if context is ps.1.x and Macro not on or a phase marker was found then put all ALU ops in phase 2 ALU container + if (((mActiveContexts & ckp_PS_1_1) && !mMacroOn) || mPhaseMarkerFound) mInstructionPhase = ptPHASE2ALU; + else mInstructionPhase = ptPHASE1ALU; + // check for alpha op in destination register which is OpParrams[0] + // if no Mask for destination then make it .rgba + if(mOpParrams[0].MaskRep == 0) mOpParrams[0].MaskRep = + GL_RED_BIT_ATI | GL_GREEN_BIT_ATI | GL_BLUE_BIT_ATI | ALPHA_BIT; + if (mOpParrams[0].MaskRep & ALPHA_BIT) { + mDo_Alpha = true; + mOpParrams[0].MaskRep -= ALPHA_BIT; + if(mOpParrams[0].MaskRep == 0) mOpType = mi_NOP; // only do alpha op + } + break; + + case sid_TEXCRD: + mOpType = mi_PASSTEXCOORD; + if (mPhaseMarkerFound) mInstructionPhase = ptPHASE2TEX; + else mInstructionPhase = ptPHASE1TEX; + break; + + case sid_TEXLD: + mOpType = mi_SAMPLEMAP; + if (mPhaseMarkerFound) mInstructionPhase = ptPHASE2TEX; + else mInstructionPhase = ptPHASE1TEX; + break; + + case sid_TEX: // PS_1_1 emulation + mOpType = mi_TEX; + mInstructionPhase = ptPHASE1TEX; + break; + + case sid_TEXCOORD: // PS_1_1 emulation + mOpType = mi_TEXCOORD; + mInstructionPhase = ptPHASE1TEX; + break; + + case sid_TEXREG2AR: + passed = expandMacro(texreg2ar_MacroMods); + break; + + case sid_TEXREG2GB: + passed = expandMacro(texreg2gb_MacroMods); + break; + + case sid_TEXDP3: + passed = expandMacro(texdp3_MacroMods); + break; + + case sid_TEXDP3TEX: + passed = expandMacro(texdp3tex_MacroMods); + break; + + case sid_TEXM3X2PAD: + passed = expandMacro(texm3x2pad_MacroMods); + break; + + case sid_TEXM3X2TEX: + passed = expandMacro(texm3x2tex_MacroMods); + break; + + case sid_TEXM3X3PAD: + // only 2 texm3x3pad instructions allowed + // use count to modify macro to select which mask to use + if(mTexm3x3padCount<2) { + texm3x3pad[4].mID = sid_R + mTexm3x3padCount; + mTexm3x3padCount++; + passed = expandMacro(texm3x3pad_MacroMods); + + } + else passed = false; + + break; + + case sid_TEXM3X3TEX: + passed = expandMacro(texm3x3tex_MacroMods); + break; + + case sid_DEF: + mOpType = mi_SETCONSTANTS; + mInstructionPhase = ptPHASE1TEX; + break; + + case sid_PHASE: // PS_1_4 only + mPhaseMarkerFound = true; + break; + + } // end of switch + + if(passed) passed = expandMachineInstruction(); + + return passed; } bool PS_1_4::expandMachineInstruction() { - // now push instructions onto MachineInstructions container - // assume that an instruction will be expanded - bool passed = true; - - if (mOpType != mi_NOP) { - - // a machine instruction will be built - // this is currently the last one being built so keep track of it - if (mInstructionPhase == ptPHASE2ALU) { - mSecondLastInstructionPos = mLastInstructionPos; - mLastInstructionPos = mPhase2ALU_mi.size(); - } - - - switch (mOpType) { - case mi_COLOROP1: - case mi_COLOROP2: - case mi_COLOROP3: - { - addMachineInst(mInstructionPhase, mOpType); - addMachineInst(mInstructionPhase, mSymbolTypeLib[mOpInst].mPass2Data); - // send all parameters to machine inst container - for(int i=0; i<=mArgCnt; i++) { - addMachineInst(mInstructionPhase, mOpParrams[i].Arg); - addMachineInst(mInstructionPhase, mOpParrams[i].MaskRep); - addMachineInst(mInstructionPhase, mOpParrams[i].Mod); - // check if source register read is valid in this phase - passed &= isRegisterReadValid(mInstructionPhase, i); - } - - // record which registers were written to and in which phase - // mOpParrams[0].Arg is always the destination register r0 -> r5 - updateRegisterWriteState(mInstructionPhase); - - } - break; - - case mi_SETCONSTANTS: - addMachineInst(mInstructionPhase, mOpType); - addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst - addMachineInst(mInstructionPhase, mConstantsPos); // index into constants array - break; - - case mi_PASSTEXCOORD: - case mi_SAMPLEMAP: - // if source is a temp register than place instruction in phase 2 Texture ops - if ((mOpParrams[1].Arg >= GL_REG_0_ATI) && (mOpParrams[1].Arg <= GL_REG_5_ATI)) { - mInstructionPhase = ptPHASE2TEX; - } - - addMachineInst(mInstructionPhase, mOpType); - addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst - addMachineInst(mInstructionPhase, mOpParrams[1].Arg); // coord - addMachineInst(mInstructionPhase, mOpParrams[1].MaskRep + GL_SWIZZLE_STR_ATI); // swizzle - // record which registers were written to and in which phase - // mOpParrams[0].Arg is always the destination register r0 -> r5 - updateRegisterWriteState(mInstructionPhase); - break; - - case mi_TEX: // PS_1_1 emulation - turn CISC into RISC - phase 1 - addMachineInst(mInstructionPhase, mi_SAMPLEMAP); - addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst - // tex tx becomes texld rx, tx with x: 0 - 3 - addMachineInst(mInstructionPhase, mOpParrams[0].Arg - GL_REG_0_ATI + GL_TEXTURE0_ARB); // interp - // default to str which fills rgb of destination register - addMachineInst(mInstructionPhase, GL_SWIZZLE_STR_ATI); // swizzle - // record which registers were written to and in which phase - // mOpParrams[0].Arg is always the destination register r0 -> r5 - updateRegisterWriteState(mInstructionPhase); - break; - - case mi_TEXCOORD: // PS_1_1 emulation - turn CISC into RISC - phase 1 - addMachineInst(mInstructionPhase, mi_PASSTEXCOORD); - addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst - // texcoord tx becomes texcrd rx, tx with x: 0 - 3 - addMachineInst(mInstructionPhase, mOpParrams[0].Arg - GL_REG_0_ATI + GL_TEXTURE0_ARB); // interp - // default to str which fills rgb of destination register - addMachineInst(mInstructionPhase, GL_SWIZZLE_STR_ATI); // swizzle - // record which registers were written to and in which phase - // mOpParrams[0].Arg is always the destination register r0 -> r5 - updateRegisterWriteState(mInstructionPhase); - break; + // now push instructions onto MachineInstructions container + // assume that an instruction will be expanded + bool passed = true; + + if (mOpType != mi_NOP) { + + // a machine instruction will be built + // this is currently the last one being built so keep track of it + if (mInstructionPhase == ptPHASE2ALU) { + mSecondLastInstructionPos = mLastInstructionPos; + mLastInstructionPos = mPhase2ALU_mi.size(); + } + + + switch (mOpType) { + case mi_COLOROP1: + case mi_COLOROP2: + case mi_COLOROP3: + { + addMachineInst(mInstructionPhase, mOpType); + addMachineInst(mInstructionPhase, mSymbolTypeLib[mOpInst].mPass2Data); + // send all parameters to machine inst container + for(int i=0; i<=mArgCnt; i++) { + addMachineInst(mInstructionPhase, mOpParrams[i].Arg); + addMachineInst(mInstructionPhase, mOpParrams[i].MaskRep); + addMachineInst(mInstructionPhase, mOpParrams[i].Mod); + // check if source register read is valid in this phase + passed &= isRegisterReadValid(mInstructionPhase, i); + } + + // record which registers were written to and in which phase + // mOpParrams[0].Arg is always the destination register r0 -> r5 + updateRegisterWriteState(mInstructionPhase); + + } + break; + + case mi_SETCONSTANTS: + addMachineInst(mInstructionPhase, mOpType); + addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst + addMachineInst(mInstructionPhase, mConstantsPos); // index into constants array + break; + + case mi_PASSTEXCOORD: + case mi_SAMPLEMAP: + // if source is a temp register than place instruction in phase 2 Texture ops + if ((mOpParrams[1].Arg >= GL_REG_0_ATI) && (mOpParrams[1].Arg <= GL_REG_5_ATI)) { + mInstructionPhase = ptPHASE2TEX; + } + + addMachineInst(mInstructionPhase, mOpType); + addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst + addMachineInst(mInstructionPhase, mOpParrams[1].Arg); // coord + addMachineInst(mInstructionPhase, mOpParrams[1].MaskRep + GL_SWIZZLE_STR_ATI); // swizzle + // record which registers were written to and in which phase + // mOpParrams[0].Arg is always the destination register r0 -> r5 + updateRegisterWriteState(mInstructionPhase); + break; + + case mi_TEX: // PS_1_1 emulation - turn CISC into RISC - phase 1 + addMachineInst(mInstructionPhase, mi_SAMPLEMAP); + addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst + // tex tx becomes texld rx, tx with x: 0 - 3 + addMachineInst(mInstructionPhase, mOpParrams[0].Arg - GL_REG_0_ATI + GL_TEXTURE0_ARB); // interp + // default to str which fills rgb of destination register + addMachineInst(mInstructionPhase, GL_SWIZZLE_STR_ATI); // swizzle + // record which registers were written to and in which phase + // mOpParrams[0].Arg is always the destination register r0 -> r5 + updateRegisterWriteState(mInstructionPhase); + break; + + case mi_TEXCOORD: // PS_1_1 emulation - turn CISC into RISC - phase 1 + addMachineInst(mInstructionPhase, mi_PASSTEXCOORD); + addMachineInst(mInstructionPhase, mOpParrams[0].Arg); // dst + // texcoord tx becomes texcrd rx, tx with x: 0 - 3 + addMachineInst(mInstructionPhase, mOpParrams[0].Arg - GL_REG_0_ATI + GL_TEXTURE0_ARB); // interp + // default to str which fills rgb of destination register + addMachineInst(mInstructionPhase, GL_SWIZZLE_STR_ATI); // swizzle + // record which registers were written to and in which phase + // mOpParrams[0].Arg is always the destination register r0 -> r5 + updateRegisterWriteState(mInstructionPhase); + break; case mi_ALPHAOP1: case mi_ALPHAOP2: @@ -1495,142 +1495,142 @@ bool PS_1_4::expandMachineInstruction() break; - } // end of switch (mOpType) - } // end of if (mOpType != mi_NOP) - - if(mDo_Alpha) { - // process alpha channel - // - // a scaler machine instruction will be built - // this is currently the last one being built so keep track of it - if (mInstructionPhase == ptPHASE2ALU) { - mSecondLastInstructionPos = mLastInstructionPos; - mLastInstructionPos = mPhase2ALU_mi.size(); - } - - MachineInstID alphaoptype = (MachineInstID)(mi_ALPHAOP1 + mArgCnt - 1); - addMachineInst(mInstructionPhase, alphaoptype); - addMachineInst(mInstructionPhase, mSymbolTypeLib[mOpInst].mPass2Data); - // put all parameters in instruction que - for(int i=0; i<=mArgCnt; i++) { - addMachineInst(mInstructionPhase, mOpParrams[i].Arg); - // destination parameter has no mask since it is the alpha channel - // don't push mask for parrameter 0 (dst) - if(i>0) addMachineInst(mInstructionPhase, mOpParrams[i].MaskRep); - addMachineInst(mInstructionPhase, mOpParrams[i].Mod); - // check if source register read is valid in this phase - passed &= isRegisterReadValid(mInstructionPhase, i); - } - - updateRegisterWriteState(mInstructionPhase); - } - - // instruction passed on to machine instruction so clear the pipe - clearMachineInstState(); - - return passed; + } // end of switch (mOpType) + } // end of if (mOpType != mi_NOP) + + if(mDo_Alpha) { + // process alpha channel + // + // a scaler machine instruction will be built + // this is currently the last one being built so keep track of it + if (mInstructionPhase == ptPHASE2ALU) { + mSecondLastInstructionPos = mLastInstructionPos; + mLastInstructionPos = mPhase2ALU_mi.size(); + } + + MachineInstID alphaoptype = (MachineInstID)(mi_ALPHAOP1 + mArgCnt - 1); + addMachineInst(mInstructionPhase, alphaoptype); + addMachineInst(mInstructionPhase, mSymbolTypeLib[mOpInst].mPass2Data); + // put all parameters in instruction que + for(int i=0; i<=mArgCnt; i++) { + addMachineInst(mInstructionPhase, mOpParrams[i].Arg); + // destination parameter has no mask since it is the alpha channel + // don't push mask for parrameter 0 (dst) + if(i>0) addMachineInst(mInstructionPhase, mOpParrams[i].MaskRep); + addMachineInst(mInstructionPhase, mOpParrams[i].Mod); + // check if source register read is valid in this phase + passed &= isRegisterReadValid(mInstructionPhase, i); + } + + updateRegisterWriteState(mInstructionPhase); + } + + // instruction passed on to machine instruction so clear the pipe + clearMachineInstState(); + + return passed; } void PS_1_4::updateRegisterWriteState(const PhaseType phase) { - int reg_offset = mOpParrams[0].Arg - GL_REG_0_ATI; + int reg_offset = mOpParrams[0].Arg - GL_REG_0_ATI; - switch(phase) { + switch(phase) { - case ptPHASE1TEX: - case ptPHASE1ALU: - Phase_RegisterUsage[reg_offset].Phase1Write = true; - break; + case ptPHASE1TEX: + case ptPHASE1ALU: + Phase_RegisterUsage[reg_offset].Phase1Write = true; + break; - case ptPHASE2TEX: - case ptPHASE2ALU: - Phase_RegisterUsage[reg_offset].Phase2Write = true; - break; + case ptPHASE2TEX: + case ptPHASE2ALU: + Phase_RegisterUsage[reg_offset].Phase2Write = true; + break; - } // end switch(phase) + } // end switch(phase) } bool PS_1_4::isRegisterReadValid(const PhaseType phase, const int param) { - bool passed = true; // assume everything will go alright - // if in phase 2 ALU and argument is a source - if((phase == ptPHASE2ALU) && (param>0)) { - // is source argument a temp register r0 - r5? - if((mOpParrams[param].Arg >= GL_REG_0_ATI) && (mOpParrams[param].Arg <= GL_REG_5_ATI)) { - int reg_offset = mOpParrams[param].Arg - GL_REG_0_ATI; - // if register was not written to in phase 2 but was in phase 1 - if((Phase_RegisterUsage[reg_offset].Phase2Write == false) && Phase_RegisterUsage[reg_offset].Phase1Write) { - // only perform register pass if there are ALU instructions in phase 1 - - if(mPhase1ALU_mi.size() > 0) { - // build machine instructions for passing a register from phase 1 to phase 2 - // NB: only rgb components of register will get passed - - addMachineInst(ptPHASE2TEX, mi_PASSTEXCOORD); - addMachineInst(ptPHASE2TEX, mOpParrams[param].Arg); // dst - addMachineInst(ptPHASE2TEX, mOpParrams[param].Arg); // coord - addMachineInst(ptPHASE2TEX, GL_SWIZZLE_STR_ATI); // swizzle - // mark register as being written to - Phase_RegisterUsage[reg_offset].Phase2Write = true; - } - - } - // register can not be used because it has not been written to previously - else passed = false; - } - - } - - return passed; + bool passed = true; // assume everything will go alright + // if in phase 2 ALU and argument is a source + if((phase == ptPHASE2ALU) && (param>0)) { + // is source argument a temp register r0 - r5? + if((mOpParrams[param].Arg >= GL_REG_0_ATI) && (mOpParrams[param].Arg <= GL_REG_5_ATI)) { + int reg_offset = mOpParrams[param].Arg - GL_REG_0_ATI; + // if register was not written to in phase 2 but was in phase 1 + if((Phase_RegisterUsage[reg_offset].Phase2Write == false) && Phase_RegisterUsage[reg_offset].Phase1Write) { + // only perform register pass if there are ALU instructions in phase 1 + + if(mPhase1ALU_mi.size() > 0) { + // build machine instructions for passing a register from phase 1 to phase 2 + // NB: only rgb components of register will get passed + + addMachineInst(ptPHASE2TEX, mi_PASSTEXCOORD); + addMachineInst(ptPHASE2TEX, mOpParrams[param].Arg); // dst + addMachineInst(ptPHASE2TEX, mOpParrams[param].Arg); // coord + addMachineInst(ptPHASE2TEX, GL_SWIZZLE_STR_ATI); // swizzle + // mark register as being written to + Phase_RegisterUsage[reg_offset].Phase2Write = true; + } + + } + // register can not be used because it has not been written to previously + else passed = false; + } + + } + + return passed; } void PS_1_4::optimize() { - // perform some optimizations on ps.1.1 machine instructions - if (mActiveContexts & ckp_PS_1_1) { - // need to check last few instructions to make sure r0 is set - // ps.1.1 emulation uses r4 for r0 so last couple of instructions will probably require - // changine destination register back to r0 - if (mLastInstructionPos < mPhase2ALU_mi.size()) { - // first argument at mLastInstructionPos + 2 is destination register for all ps.1.1 ALU instructions - mPhase2ALU_mi[mLastInstructionPos + 2] = GL_REG_0_ATI; - // if was an alpha op only then modify second last instruction destination register - if ((mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP1) || - (mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP2) || - (mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP3) - - ) { - - mPhase2ALU_mi[mSecondLastInstructionPos + 2] = GL_REG_0_ATI; - } - - }// end if (mLastInstructionPos < mMachineInstructions.size()) - - }// end if (mActiveContexts & ckp_PS_1_1) + // perform some optimizations on ps.1.1 machine instructions + if (mActiveContexts & ckp_PS_1_1) { + // need to check last few instructions to make sure r0 is set + // ps.1.1 emulation uses r4 for r0 so last couple of instructions will probably require + // changine destination register back to r0 + if (mLastInstructionPos < mPhase2ALU_mi.size()) { + // first argument at mLastInstructionPos + 2 is destination register for all ps.1.1 ALU instructions + mPhase2ALU_mi[mLastInstructionPos + 2] = GL_REG_0_ATI; + // if was an alpha op only then modify second last instruction destination register + if ((mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP1) || + (mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP2) || + (mPhase2ALU_mi[mLastInstructionPos] == mi_ALPHAOP3) + + ) { + + mPhase2ALU_mi[mSecondLastInstructionPos + 2] = GL_REG_0_ATI; + } + + }// end if (mLastInstructionPos < mMachineInstructions.size()) + + }// end if (mActiveContexts & ckp_PS_1_1) } void PS_1_4::clearMachineInstState() { - // set current Machine Instruction State to baseline - mOpType = mi_NOP; - mOpInst = sid_INVALID; - mDo_Alpha = false; - mArgCnt = 0; - - for(int i=0; imID; - } - else passed = false; - break; - - case sid_DSTMASK: - case sid_SRCREP: - case sid_TEXSWIZZLE: - // could be a dst mask or a arg replicator - // if dst mask and alpha included then make up a alpha instruction: maybe best to wait until instruction args completed - mOpParrams[mArgCnt].MaskRep = cursymboldef->mPass2Data; - break; - - case sid_DSTMOD: - case sid_DSTSAT: - case sid_PRESRCMOD: - case sid_POSTSRCMOD: - mOpParrams[mArgCnt].Mod |= cursymboldef->mPass2Data; - break; - - - case sid_NUMVAL: - passed = setOpParram(cursymboldef); - // keep track of how many values are used - // update Constants array position - mConstantsPos++; - break; - - case sid_SEPERATOR: - mArgCnt++; - break; - } // end of switch - - if(!passed) break; - }// end of for: imID; + } + else passed = false; + break; + + case sid_DSTMASK: + case sid_SRCREP: + case sid_TEXSWIZZLE: + // could be a dst mask or a arg replicator + // if dst mask and alpha included then make up a alpha instruction: maybe best to wait until instruction args completed + mOpParrams[mArgCnt].MaskRep = cursymboldef->mPass2Data; + break; + + case sid_DSTMOD: + case sid_DSTSAT: + case sid_PRESRCMOD: + case sid_POSTSRCMOD: + mOpParrams[mArgCnt].Mod |= cursymboldef->mPass2Data; + break; + + + case sid_NUMVAL: + passed = setOpParram(cursymboldef); + // keep track of how many values are used + // update Constants array position + mConstantsPos++; + break; + + case sid_SEPERATOR: + mArgCnt++; + break; + } // end of switch + + if(!passed) break; + }// end of for: iget_ogre_widget(); + // _ogre_widget = window->get_ogre_widget(); // Copy some important information for future reference, for example // for when the context is needed @@ -161,33 +161,33 @@ void GTKGLSupport::stop() void GTKGLSupport::begin_context(RenderTarget *_target) { - // Support nested contexts, in which case.. nothing happens - ++_context_ref; - if (_context_ref == 1) { - if(_target) { - // Begin a specific context - OGREWidget *_ogre_widget = static_cast(_target)->get_ogre_widget(); + // Support nested contexts, in which case.. nothing happens + ++_context_ref; + if (_context_ref == 1) { + if(_target) { + // Begin a specific context + OGREWidget *_ogre_widget = static_cast(_target)->get_ogre_widget(); - _ogre_widget->get_gl_window()->gl_begin(_ogre_widget->get_gl_context()); - } else { - // Begin a generic main context - _main_window->gl_begin(_main_context); - } - } + _ogre_widget->get_gl_window()->gl_begin(_ogre_widget->get_gl_context()); + } else { + // Begin a generic main context + _main_window->gl_begin(_main_context); + } + } } void GTKGLSupport::end_context() { - --_context_ref; - if(_context_ref < 0) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Too many contexts destroyed!", "GTKGLSupport::end_context"); - if (_context_ref == 0) - { - // XX is this enough? (_main_window might not be the current window, - // but we can never be sure the previous rendering window - // even still exists) - _main_window->gl_end(); - } + --_context_ref; + if(_context_ref < 0) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Too many contexts destroyed!", "GTKGLSupport::end_context"); + if (_context_ref == 0) + { + // XX is this enough? (_main_window might not be the current window, + // but we can never be sure the previous rendering window + // even still exists) + _main_window->gl_end(); + } } void GTKGLSupport::initialiseExtensions(void) @@ -209,14 +209,14 @@ bool GTKGLSupport::checkMinGLVersion(const String& v) const bool GTKGLSupport::checkExtension(const String& ext) const { - // query_gl_extension needs an active context, doesn't matter which one - if (_context_ref == 0) - _main_window->gl_begin(_main_context); + // query_gl_extension needs an active context, doesn't matter which one + if (_context_ref == 0) + _main_window->gl_begin(_main_context); - bool result = Gdk::GL::query_gl_extension(ext.c_str()); + bool result = Gdk::GL::query_gl_extension(ext.c_str()); - if (_context_ref == 0) - _main_window->gl_end(); + if (_context_ref == 0) + _main_window->gl_end(); } void* GTKGLSupport::getProcAddress(const String& procname) @@ -225,6 +225,6 @@ void* GTKGLSupport::getProcAddress(const String& procname) } Glib::RefPtr GTKGLSupport::getMainContext() const { - return _main_context; + return _main_context; } diff --git a/RenderSystems/GL/src/gtk/OgreGTKWindow.cpp b/RenderSystems/GL/src/gtk/OgreGTKWindow.cpp index d736754fd2d..bd4acc6d780 100644 --- a/RenderSystems/GL/src/gtk/OgreGTKWindow.cpp +++ b/RenderSystems/GL/src/gtk/OgreGTKWindow.cpp @@ -35,7 +35,7 @@ THE SOFTWARE. using namespace Ogre; OGREWidget::OGREWidget(bool useDepthBuffer) : - Gtk::GL::DrawingArea() + Gtk::GL::DrawingArea() { Glib::RefPtr glconfig; @@ -46,7 +46,7 @@ OGREWidget::OGREWidget(bool useDepthBuffer) : glconfig = Gdk::GL::Config::create(mode); if (glconfig.is_null()) { - LogManager::getSingleton().logMessage("[gtk] GLCONFIG BLOWUP"); + LogManager::getSingleton().logMessage("[gtk] GLCONFIG BLOWUP"); } // Inherit GL context from Ogre main context @@ -60,16 +60,16 @@ OGREWidget::OGREWidget(bool useDepthBuffer) : // - Change aspect ratio GTKWindow::GTKWindow(): - mGtkWindow(0) + mGtkWindow(0) { - //kit = Gtk::Main::instance(); - - // Should this move to GTKGLSupport? - // Gtk::GL::init(0, NULL); - // Already done in GTKGLSupport - - mWidth = 0; - mHeight = 0; + //kit = Gtk::Main::instance(); + + // Should this move to GTKGLSupport? + // Gtk::GL::init(0, NULL); + // Already done in GTKGLSupport + + mWidth = 0; + mHeight = 0; } GTKWindow::~GTKWindow() @@ -95,77 +95,77 @@ void GTKWindow::create(const String& name, unsigned int width, unsigned int heig bool fullScreen, int left, int top, bool depthBuffer, void* miscParam, ...) { - mName = name; - mWidth = width; - mHeight = height; - - if(!miscParam) { - mGtkWindow = new Gtk::Window(); - mGtkWindow->set_title(mName); - - if (fullScreen) - { - mIsFullScreen = true; - mGtkWindow->set_decorated(false); - mGtkWindow->fullscreen(); - } - else - { - mIsFullScreen = false; - mGtkWindow->set_default_size(mWidth, mHeight); - mGtkWindow->move(left, top); - } - } else { - // If miscParam is not 0, a parent widget has been passed in, - // we will handle this later on after the widget has been created. - } - - ogre = Gtk::manage(new OGREWidget(depthBuffer)); - ogre->set_size_request(width, height); - - ogre->signal_delete_event().connect(SigC::slot(*this, >KWindow::on_delete_event)); - ogre->signal_expose_event().connect(SigC::slot(*this, >KWindow::on_expose_event)); - - if(mGtkWindow) { - mGtkWindow->add(*ogre); - mGtkWindow->show_all(); - } - if(miscParam) { - // Attach it! - // Note that the parent widget *must* be visible already at this point, - // or the widget won't get realized in time for the GLinit that follows - // this call. This is usually the case for Glade generated windows, anyway. - reinterpret_cast(miscParam)->add(*ogre); - ogre->show(); - } - //ogre->realize(); + mName = name; + mWidth = width; + mHeight = height; + + if(!miscParam) { + mGtkWindow = new Gtk::Window(); + mGtkWindow->set_title(mName); + + if (fullScreen) + { + mIsFullScreen = true; + mGtkWindow->set_decorated(false); + mGtkWindow->fullscreen(); + } + else + { + mIsFullScreen = false; + mGtkWindow->set_default_size(mWidth, mHeight); + mGtkWindow->move(left, top); + } + } else { + // If miscParam is not 0, a parent widget has been passed in, + // we will handle this later on after the widget has been created. + } + + ogre = Gtk::manage(new OGREWidget(depthBuffer)); + ogre->set_size_request(width, height); + + ogre->signal_delete_event().connect(SigC::slot(*this, >KWindow::on_delete_event)); + ogre->signal_expose_event().connect(SigC::slot(*this, >KWindow::on_expose_event)); + + if(mGtkWindow) { + mGtkWindow->add(*ogre); + mGtkWindow->show_all(); + } + if(miscParam) { + // Attach it! + // Note that the parent widget *must* be visible already at this point, + // or the widget won't get realized in time for the GLinit that follows + // this call. This is usually the case for Glade generated windows, anyway. + reinterpret_cast(miscParam)->add(*ogre); + ogre->show(); + } + //ogre->realize(); } void GTKWindow::destroy() { - Root::getSingleton().getRenderSystem()->detachRenderTarget( this->getName() ); - // We could detach the widget from its parent and destroy it here too, - // but then again, it is managed so we rely on GTK to destroy it. - delete mGtkWindow; - mGtkWindow = 0; + Root::getSingleton().getRenderSystem()->detachRenderTarget( this->getName() ); + // We could detach the widget from its parent and destroy it here too, + // but then again, it is managed so we rely on GTK to destroy it. + delete mGtkWindow; + mGtkWindow = 0; } void GTKWindow::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) { - if((fullScreen) && (!mIsFullScreen)) - { - mIsFullScreen = true; - mGtkWindow->fullscreen(); - ogre->set_size_request(width, height); - } - else if((!fullScreen) && (mIsFullScreen)) - { - mIsFullScreen = false; - mGtkWindow->unfullscreen(); - ogre->set_size_request(width, height); - } + if((fullScreen) && (!mIsFullScreen)) + { + mIsFullScreen = true; + mGtkWindow->fullscreen(); + ogre->set_size_request(width, height); + } + else if((!fullScreen) && (mIsFullScreen)) + { + mIsFullScreen = false; + mGtkWindow->unfullscreen(); + ogre->set_size_request(width, height); + } } bool GTKWindow::isActive() const @@ -180,64 +180,64 @@ bool GTKWindow::isClosed() const void GTKWindow::reposition(int left, int top) { - if(mGtkWindow) - mGtkWindow->move(left, top); + if(mGtkWindow) + mGtkWindow->move(left, top); } void GTKWindow::resize(unsigned int width, unsigned int height) { - if(mGtkWindow) - mGtkWindow->resize(width, height); + if(mGtkWindow) + mGtkWindow->resize(width, height); } void GTKWindow::swapBuffers() { - Glib::RefPtr glwindow = ogre->get_gl_window(); - glwindow->swap_buffers(); + Glib::RefPtr glwindow = ogre->get_gl_window(); + glwindow->swap_buffers(); } void GTKWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) { - if ((dst.left < 0) || (dst.right > mWidth) || - (dst.top < 0) || (dst.bottom > mHeight) || - (dst.front != 0) || (dst.back != 1)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid box.", - "GTKWindow::copyContentsToMemory" ); - } - - if (buffer == FB_AUTO) - { - buffer = mIsFullScreen? FB_FRONT : FB_BACK; - } - - GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format); - GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format); - - if ((format == GL_NONE) || (type == 0)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unsupported format.", - "GTKWindow::copyContentsToMemory" ); - } - - // Switch context if different from current one - RenderSystem* rsys = Root::getSingleton().getRenderSystem(); - rsys->_setViewport(this->getViewport(0)); + if ((dst.left < 0) || (dst.right > mWidth) || + (dst.top < 0) || (dst.bottom > mHeight) || + (dst.front != 0) || (dst.back != 1)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid box.", + "GTKWindow::copyContentsToMemory" ); + } + + if (buffer == FB_AUTO) + { + buffer = mIsFullScreen? FB_FRONT : FB_BACK; + } + + GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format); + GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format); + + if ((format == GL_NONE) || (type == 0)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Unsupported format.", + "GTKWindow::copyContentsToMemory" ); + } + + // Switch context if different from current one + RenderSystem* rsys = Root::getSingleton().getRenderSystem(); + rsys->_setViewport(this->getViewport(0)); if(dst.getWidth() != dst.rowPitch) glPixelStorei(GL_PACK_ROW_LENGTH, dst.rowPitch); - // Must change the packing to ensure no overruns! - glPixelStorei(GL_PACK_ALIGNMENT, 1); + // Must change the packing to ensure no overruns! + glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); + glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); glReadPixels((GLint)0, (GLint)(mHeight - dst.getHeight()), (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(), format, type, dst.getTopLeftFrontPixelPtr()); - // restore default alignment - glPixelStorei(GL_PACK_ALIGNMENT, 4); + // restore default alignment + glPixelStorei(GL_PACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ROW_LENGTH, 0); PixelUtil::bulkPixelVerticalFlip(dst); @@ -245,26 +245,26 @@ void GTKWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) void GTKWindow::getCustomAttribute( const String& name, void* pData ) { - if( name == "GTKMMWINDOW" ) - { - Gtk::Window **win = static_cast(pData); - // Oh, the burdens of multiple inheritance - *win = mGtkWindow; - return; - } - else if( name == "GTKGLMMWIDGET" ) - { - Gtk::GL::DrawingArea **widget = static_cast(pData); - *widget = ogre; - return; - } - else if( name == "isTexture" ) - { - bool *b = reinterpret_cast< bool * >( pData ); - *b = false; - return; - } - RenderWindow::getCustomAttribute(name, pData); + if( name == "GTKMMWINDOW" ) + { + Gtk::Window **win = static_cast(pData); + // Oh, the burdens of multiple inheritance + *win = mGtkWindow; + return; + } + else if( name == "GTKGLMMWIDGET" ) + { + Gtk::GL::DrawingArea **widget = static_cast(pData); + *widget = ogre; + return; + } + else if( name == "isTexture" ) + { + bool *b = reinterpret_cast< bool * >( pData ); + *b = false; + return; + } + RenderWindow::getCustomAttribute(name, pData); } diff --git a/RenderSystems/GL/src/nvparse/_ps1.0_lexer.cpp b/RenderSystems/GL/src/nvparse/_ps1.0_lexer.cpp index 75123cf6284..1a05c072e30 100644 --- a/RenderSystems/GL/src/nvparse/_ps1.0_lexer.cpp +++ b/RenderSystems/GL/src/nvparse/_ps1.0_lexer.cpp @@ -52,15 +52,15 @@ /* yyunput is never used */ #define YY_NO_UNPUT -#else /* ! __cplusplus */ +#else /* ! __cplusplus */ #if __STDC__ #define YY_USE_PROTOS #define YY_USE_CONST -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ #ifdef __TURBOC__ #pragma warn -rch @@ -131,10 +131,10 @@ extern FILE *yyin, *yyout; * int a single C statement (which needs a semi-colon terminator). This * avoids problems with code like: * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); * * Prior to using the do-while the compiler would get upset at the * "else" because it interpreted the "if" statement as being all @@ -144,15 +144,15 @@ extern FILE *yyin, *yyout; /* Return all but the first 'n' matched characters back to the input stream. */ #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) #define unput(c) yyunput( c, yytext_ptr ) @@ -164,61 +164,61 @@ typedef unsigned int yy_size_t; struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ #define YY_BUFFER_EOF_PENDING 2 - }; + }; static YY_BUFFER_STATE yy_current_buffer = 0; @@ -232,15 +232,15 @@ static YY_BUFFER_STATE yy_current_buffer = 0; /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ +static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... @@ -268,18 +268,18 @@ static void yy_flex_free YY_PROTO(( void * )); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } #define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } #define YY_AT_BOL() (yy_current_buffer->yy_at_bol) @@ -298,11 +298,11 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; #define YY_NUM_RULES 36 #define YY_END_OF_BUFFER 37 @@ -567,13 +567,13 @@ using namespace ps10; #define YY_INPUT(buf,result,max_size) \ { \ - int c = *myin++; \ - result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \ + int c = *myin++; \ + result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \ } #define YY_ALWAYS_INTERACTIVE 1 -//#define DBG_MESG(msg, line) errors.set(msg, line) +//#define DBG_MESG(msg, line) errors.set(msg, line) #define DBG_MESG(msg, line) static char buf[80]; @@ -670,21 +670,21 @@ YY_MALLOC_DECL */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - @@ -725,99 +725,99 @@ YY_MALLOC_DECL #endif #define YY_RULE_SETUP \ - YY_USER_ACTION + YY_USER_ACTION YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp = NULL, *yy_bp = NULL; - register int yy_act; + { + register yy_state_type yy_current_state; + register char *yy_cp = NULL, *yy_bp = NULL; + register int yy_act; #line 43 "ps1.0_tokens.l" #line 737 "_ps1.0_lexer.cpp" - if ( yy_init ) - { - yy_init = 0; + if ( yy_init ) + { + yy_init = 0; #ifdef YY_USER_INIT - YY_USER_INIT; + YY_USER_INIT; #endif - if ( ! yy_start ) - yy_start = 1; /* first start state */ + if ( ! yy_start ) + yy_start = 1; /* first start state */ - if ( ! yyin ) - yyin = stdin; + if ( ! yyin ) + yyin = stdin; - if ( ! yyout ) - yyout = stdout; + if ( ! yyout ) + yyout = stdout; - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); - yy_load_buffer_state(); - } + yy_load_buffer_state(); + } - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; - /* Support of yytext. */ - *yy_cp = yy_hold_char; + /* Support of yytext. */ + *yy_cp = yy_hold_char; - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; - yy_current_state = yy_start; + yy_current_state = yy_start; yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 231 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 366 ); + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 231 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 366 ); yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } - YY_DO_BEFORE_ACTION; + YY_DO_BEFORE_ACTION; -do_action: /* This label is used only to access EOF actions. */ +do_action: /* This label is used only to access EOF actions. */ - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; case 1: #line 46 "ps1.0_tokens.l" @@ -825,14 +825,14 @@ case 2: YY_RULE_SETUP #line 46 "ps1.0_tokens.l" { - char ch; - while ((ch = yyinput()) != '\n') - ; - line_number++; - DBG_MESG("dbg: comment, NEWLINE", line_number-1); - return NEWLINE; - } - YY_BREAK + char ch; + while ((ch = yyinput()) != '\n') + ; + line_number++; + DBG_MESG("dbg: comment, NEWLINE", line_number-1); + return NEWLINE; + } + YY_BREAK case 3: #line 56 "ps1.0_tokens.l" case 4: @@ -841,22 +841,22 @@ case 5: YY_RULE_SETUP #line 57 "ps1.0_tokens.l" { - ps10_lval.fval = (float)atof(yytext); - // debug - DBG_MESG("dbg: NUMBER", line_number); - return NUMBER; - } - YY_BREAK + ps10_lval.fval = (float)atof(yytext); + // debug + DBG_MESG("dbg: NUMBER", line_number); + return NUMBER; + } + YY_BREAK case 6: YY_RULE_SETUP #line 67 "ps1.0_tokens.l" { - // debug - DBG_MESG("dbg: DEF", line_number); - BEGIN DEFSTATE; - return DEF; - } - YY_BREAK + // debug + DBG_MESG("dbg: DEF", line_number); + BEGIN DEFSTATE; + return DEF; + } + YY_BREAK case 7: #line 76 "ps1.0_tokens.l" case 8: @@ -867,13 +867,13 @@ case 10: YY_RULE_SETUP #line 78 "ps1.0_tokens.l" { - sprintf(buf, "dbg: REG = %s", yytext); - // debug - DBG_MESG(buf, line_number); - ps10_lval.sval = new string(yytext); - return REG; - } - YY_BREAK + sprintf(buf, "dbg: REG = %s", yytext); + // debug + DBG_MESG(buf, line_number); + ps10_lval.sval = new string(yytext); + return REG; + } + YY_BREAK case 11: #line 87 "ps1.0_tokens.l" case 12: @@ -892,13 +892,13 @@ case 18: YY_RULE_SETUP #line 93 "ps1.0_tokens.l" { - sprintf(buf, "dbg: BLENDOP = %s", yytext); - // debug - DBG_MESG(buf, line_number); - ps10_lval.sval = new string(yytext); - return BLENDOP; - } - YY_BREAK + sprintf(buf, "dbg: BLENDOP = %s", yytext); + // debug + DBG_MESG(buf, line_number); + ps10_lval.sval = new string(yytext); + return BLENDOP; + } + YY_BREAK case 19: #line 102 "ps1.0_tokens.l" case 20: @@ -927,359 +927,359 @@ case 31: YY_RULE_SETUP #line 113 "ps1.0_tokens.l" { - sprintf(buf, "dbg: ADDROP = %s", yytext); - // debug - DBG_MESG(buf, line_number); - ps10_lval.sval = new string(yytext); - return ADDROP; - } - YY_BREAK + sprintf(buf, "dbg: ADDROP = %s", yytext); + // debug + DBG_MESG(buf, line_number); + ps10_lval.sval = new string(yytext); + return ADDROP; + } + YY_BREAK case 32: YY_RULE_SETUP #line 123 "ps1.0_tokens.l" { - line_number++; - BEGIN 0; - // debug - DBG_MESG("dbg: NEWLINE", line_number-1); - return NEWLINE; - } - YY_BREAK + line_number++; + BEGIN 0; + // debug + DBG_MESG("dbg: NEWLINE", line_number-1); + return NEWLINE; + } + YY_BREAK case 33: YY_RULE_SETUP #line 131 "ps1.0_tokens.l" { - } - YY_BREAK + } + YY_BREAK case 34: YY_RULE_SETUP #line 134 "ps1.0_tokens.l" { - return HEADER; - } - YY_BREAK + return HEADER; + } + YY_BREAK case 35: YY_RULE_SETUP #line 138 "ps1.0_tokens.l" { - char buf[40]; - sprintf(buf, "character token == '%c'", *yytext); - DBG_MESG(buf, line_number); - return *yytext; - } - YY_BREAK + char buf[40]; + sprintf(buf, "character token == '%c'", *yytext); + DBG_MESG(buf, line_number); + return *yytext; + } + YY_BREAK case 36: YY_RULE_SETUP #line 145 "ps1.0_tokens.l" ECHO; - YY_BREAK + YY_BREAK #line 974 "_ps1.0_lexer.cpp" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(DEFSTATE): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ #ifdef YY_USES_REJECT - YY_FATAL_ERROR( + YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); #else - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; #endif - } + } - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); - yy_current_buffer->yy_n_chars = yy_n_chars; - } + yy_current_buffer->yy_n_chars = yy_n_chars; + } - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } - else - ret_val = EOB_ACT_CONTINUE_SCAN; + else + ret_val = EOB_ACT_CONTINUE_SCAN; - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - return ret_val; - } + return ret_val; + } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 231 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; - } + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 231 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis - * next_state = yy_try_NUL_trans( current_state ); + * next_state = yy_try_NUL_trans( current_state ); */ #ifdef YY_USE_PROTOS @@ -1288,27 +1288,27 @@ static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) static yy_state_type yy_try_NUL_trans( yy_current_state ) yy_state_type yy_current_state; #endif - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 231 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 230); - - return yy_is_jam ? 0 : yy_current_state; - } + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 231 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 230); + + return yy_is_jam ? 0 : yy_current_state; + } #ifndef YY_NO_UNPUT @@ -1319,41 +1319,41 @@ static void yyunput( c, yy_bp ) int c; register char *yy_bp; #endif - { - register char *yy_cp = yy_c_buf_p; + { + register char *yy_cp = yy_c_buf_p; - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } - *--yy_cp = (char) c; + *--yy_cp = (char) c; - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ #ifdef __cplusplus @@ -1361,72 +1361,72 @@ static int yyinput() #else static int input() #endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; #ifdef __cplusplus - return yyinput(); + return yyinput(); #else - return input(); + return input(); #endif - } + } - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; - return c; - } + return c; + } #ifdef YY_USE_PROTOS @@ -1435,13 +1435,13 @@ void yyrestart( FILE *input_file ) void yyrestart( input_file ) FILE *input_file; #endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } #ifdef YY_USE_PROTOS @@ -1450,28 +1450,28 @@ void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) void yy_switch_to_buffer( new_buffer ) YY_BUFFER_STATE new_buffer; #endif - { - if ( yy_current_buffer == new_buffer ) - return; + { + if ( yy_current_buffer == new_buffer ) + return; - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } - yy_current_buffer = new_buffer; - yy_load_buffer_state(); + yy_current_buffer = new_buffer; + yy_load_buffer_state(); - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } #ifdef YY_USE_PROTOS @@ -1479,12 +1479,12 @@ void yy_load_buffer_state( void ) #else void yy_load_buffer_state() #endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } #ifdef YY_USE_PROTOS @@ -1494,28 +1494,28 @@ YY_BUFFER_STATE yy_create_buffer( file, size ) FILE *file; int size; #endif - { - YY_BUFFER_STATE b; + { + YY_BUFFER_STATE b; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_buf_size = size; + b->yy_buf_size = size; - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_is_our_buffer = 1; + b->yy_is_our_buffer = 1; - yy_init_buffer( b, file ); + yy_init_buffer( b, file ); - return b; - } + return b; + } #ifdef YY_USE_PROTOS @@ -1524,18 +1524,18 @@ void yy_delete_buffer( YY_BUFFER_STATE b ) void yy_delete_buffer( b ) YY_BUFFER_STATE b; #endif - { - if ( ! b ) - return; + { + if ( ! b ) + return; - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); - yy_flex_free( (void *) b ); - } + yy_flex_free( (void *) b ); + } @@ -1548,22 +1548,22 @@ FILE *file; #endif - { - yy_flush_buffer( b ); + { + yy_flush_buffer( b ); - b->yy_input_file = file; - b->yy_fill_buffer = 1; + b->yy_input_file = file; + b->yy_fill_buffer = 1; #if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; + b->yy_is_interactive = 1; #else #if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; + b->yy_is_interactive = 0; #else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; #endif #endif - } + } #ifdef YY_USE_PROTOS @@ -1573,27 +1573,27 @@ void yy_flush_buffer( b ) YY_BUFFER_STATE b; #endif - { - if ( ! b ) - return; + { + if ( ! b ) + return; - b->yy_n_chars = 0; + b->yy_n_chars = 0; - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - b->yy_buf_pos = &b->yy_ch_buf[0]; + b->yy_buf_pos = &b->yy_ch_buf[0]; - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } #ifndef YY_NO_SCAN_BUFFER @@ -1604,33 +1604,33 @@ YY_BUFFER_STATE yy_scan_buffer( base, size ) char *base; yy_size_t size; #endif - { - YY_BUFFER_STATE b; + { + YY_BUFFER_STATE b; - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; - yy_switch_to_buffer( b ); + yy_switch_to_buffer( b ); - return b; - } + return b; + } #endif @@ -1641,13 +1641,13 @@ YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) YY_BUFFER_STATE yy_scan_string( yy_str ) yyconst char *yy_str; #endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; - return yy_scan_bytes( yy_str, len ); - } + return yy_scan_bytes( yy_str, len ); + } #endif @@ -1659,34 +1659,34 @@ YY_BUFFER_STATE yy_scan_bytes( bytes, len ) yyconst char *bytes; int len; #endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; - return b; - } + return b; + } #endif @@ -1697,49 +1697,49 @@ static void yy_push_state( int new_state ) static void yy_push_state( new_state ) int new_state; #endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } - yy_start_stack[yy_start_stack_ptr++] = YY_START; + yy_start_stack[yy_start_stack_ptr++] = YY_START; - BEGIN(new_state); - } + BEGIN(new_state); + } #endif #ifndef YY_NO_POP_STATE static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } #endif #ifndef YY_NO_TOP_STATE static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } #endif #ifndef YY_EXIT_FAILURE @@ -1752,10 +1752,10 @@ static void yy_fatal_error( yyconst char msg[] ) static void yy_fatal_error( msg ) char msg[]; #endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } @@ -1763,16 +1763,16 @@ char msg[]; #undef yyless #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) /* Internal utility routines. */ @@ -1786,11 +1786,11 @@ char *s1; yyconst char *s2; int n; #endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } #endif #ifdef YY_NEED_STRLEN @@ -1800,13 +1800,13 @@ static int yy_flex_strlen( yyconst char *s ) static int yy_flex_strlen( s ) yyconst char *s; #endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; + { + register int n; + for ( n = 0; s[n]; ++n ) + ; - return n; - } + return n; + } #endif @@ -1816,9 +1816,9 @@ static void *yy_flex_alloc( yy_size_t size ) static void *yy_flex_alloc( size ) yy_size_t size; #endif - { - return (void *) malloc( size ); - } + { + return (void *) malloc( size ); + } #ifdef YY_USE_PROTOS static void *yy_flex_realloc( void *ptr, yy_size_t size ) @@ -1827,16 +1827,16 @@ static void *yy_flex_realloc( ptr, size ) void *ptr; yy_size_t size; #endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } #ifdef YY_USE_PROTOS static void yy_flex_free( void *ptr ) @@ -1844,23 +1844,23 @@ static void yy_flex_free( void *ptr ) static void yy_flex_free( ptr ) void *ptr; #endif - { - free( ptr ); - } + { + free( ptr ); + } #if YY_MAIN int main() - { - yylex(); - return 0; - } + { + yylex(); + return 0; + } #endif #line 145 "ps1.0_tokens.l" bool ps10_init(char* inputString) { myin = inputString; - return init_extensions(); + return init_extensions(); } #ifndef ps10_wrap diff --git a/RenderSystems/GL/src/nvparse/_ps1.0_parser.cpp b/RenderSystems/GL/src/nvparse/_ps1.0_parser.cpp index 412713e18fb..da0a86cd043 100644 --- a/RenderSystems/GL/src/nvparse/_ps1.0_parser.cpp +++ b/RenderSystems/GL/src/nvparse/_ps1.0_parser.cpp @@ -115,13 +115,13 @@ THE SOFTWARE. /* - This is a parser for the DX8 PS1.0 pixel shaders. I intend - to use it to set NV_texture_shader* and NV_register_combiners* - state in OpenGL, but the parse tree could be used for any - other purpose. + This is a parser for the DX8 PS1.0 pixel shaders. I intend + to use it to set NV_texture_shader* and NV_register_combiners* + state in OpenGL, but the parse tree could be used for any + other purpose. - Cass Everitt - 7-19-01 + Cass Everitt + 7-19-01 */ @@ -131,7 +131,7 @@ int yylex ( void ); #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0502 // Minimal version is Win XP SP2 @@ -152,7 +152,7 @@ int yylex ( void ); using namespace std; using namespace ps10; -//#define DBG_MESG(msg, line) errors.set(msg, line) +//#define DBG_MESG(msg, line) errors.set(msg, line) #define DBG_MESG(msg, line) @@ -174,14 +174,14 @@ using namespace ps10; #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) #line 43 "ps1.0_grammar.y" typedef union YYSTYPE { - int ival; - float fval; - - string * sval; - constdef * cdef; - vector * consts; - vector * line; - list > * lines; + int ival; + float fval; + + string * sval; + constdef * cdef; + vector * consts; + vector * line; + list > * lines; } YYSTYPE; /* Line 191 of yacc.c. */ #line 153 "_ps1.0_parser.c" @@ -232,7 +232,7 @@ typedef union YYSTYPE { #if (! defined (yyoverflow) \ && (! defined (__cplusplus) \ - || (YYSTYPE_IS_TRIVIAL))) + || (YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc @@ -247,7 +247,7 @@ union yyalloc /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do @@ -257,13 +257,13 @@ union yyalloc # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ while (0) # endif # endif @@ -273,15 +273,15 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ while (0) #endif @@ -310,7 +310,7 @@ union yyalloc #define YYUNDEFTOK 2 #define YYMAXUTOK 264 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ @@ -520,43 +520,43 @@ static const unsigned char yystos[] = # define YYSIZE_T unsigned int #endif -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab +#define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ + YYERROR; \ + } \ while (0) -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYTERROR 1 +#define YYERRCODE 256 /* YYLLOC_DEFAULT -- Compute the default location (before the actions are run). */ @@ -585,27 +585,27 @@ while (0) # define YYFPRINTF fprintf # endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ } while (0) -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ } while (0) -# define YYDSYMPRINTF(Title, Token, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ } while (0) /*------------------------------------------------------------------. @@ -629,10 +629,10 @@ yy_stack_print (bottom, top) YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ } while (0) @@ -659,10 +659,10 @@ yy_reduce_print (yyrule) YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that @@ -678,7 +678,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -887,7 +887,7 @@ yyparse () to reallocate them elsewhere. */ /* The state stack. */ - short yyssa[YYINITDEPTH]; + short yyssa[YYINITDEPTH]; short *yyss = yyssa; register short *yyssp; @@ -916,7 +916,7 @@ yyparse () yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack @@ -947,25 +947,25 @@ yyparse () #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); + &yystacksize); - yyss = yyss1; - yyvs = yyvs1; + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -973,23 +973,23 @@ yyparse () # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; + goto yyoverflowlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@ -999,10 +999,10 @@ yyparse () YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1053,7 +1053,7 @@ yyparse () if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; + goto yyerrlab; yyn = -yyn; goto yyreduce; } @@ -1114,222 +1114,222 @@ yyparse () case 2: #line 73 "ps1.0_grammar.y" { - DBG_MESG("dbg: WholeEnchilada", line_number); - ps10::invoke(yyvsp[-2].consts, yyvsp[-1].lines, yyvsp[0].lines); - ;} + DBG_MESG("dbg: WholeEnchilada", line_number); + ps10::invoke(yyvsp[-2].consts, yyvsp[-1].lines, yyvsp[0].lines); + ;} break; case 3: #line 80 "ps1.0_grammar.y" { - DBG_MESG("dbg: WholeEnchilada", line_number); - ps10::invoke(yyvsp[-2].consts, yyvsp[-1].lines, yyvsp[0].lines); - ;} + DBG_MESG("dbg: WholeEnchilada", line_number); + ps10::invoke(yyvsp[-2].consts, yyvsp[-1].lines, yyvsp[0].lines); + ;} break; case 4: #line 87 "ps1.0_grammar.y" { - DBG_MESG("dbg: WholeEnchilada", line_number); - ps10::invoke( 0, yyvsp[-1].lines, yyvsp[0].lines); - ;} + DBG_MESG("dbg: WholeEnchilada", line_number); + ps10::invoke( 0, yyvsp[-1].lines, yyvsp[0].lines); + ;} break; case 5: #line 94 "ps1.0_grammar.y" { - DBG_MESG("dbg: WholeEnchilada", line_number); - ps10::invoke( 0, yyvsp[-1].lines, yyvsp[0].lines); - ;} + DBG_MESG("dbg: WholeEnchilada", line_number); + ps10::invoke( 0, yyvsp[-1].lines, yyvsp[0].lines); + ;} break; case 6: #line 101 "ps1.0_grammar.y" { - DBG_MESG("dbg: WholeEnchilada", line_number); - ps10::invoke(yyvsp[-1].consts, 0, yyvsp[0].lines); - ;} + DBG_MESG("dbg: WholeEnchilada", line_number); + ps10::invoke(yyvsp[-1].consts, 0, yyvsp[0].lines); + ;} break; case 7: #line 108 "ps1.0_grammar.y" { - DBG_MESG("dbg: WholeEnchilada", line_number); - ps10::invoke(yyvsp[-1].consts, 0, yyvsp[0].lines); - ;} + DBG_MESG("dbg: WholeEnchilada", line_number); + ps10::invoke(yyvsp[-1].consts, 0, yyvsp[0].lines); + ;} break; case 8: #line 115 "ps1.0_grammar.y" { - DBG_MESG("dbg: WholeEnchilada", line_number); - ps10::invoke( 0, 0, yyvsp[0].lines); - ;} + DBG_MESG("dbg: WholeEnchilada", line_number); + ps10::invoke( 0, 0, yyvsp[0].lines); + ;} break; case 9: #line 122 "ps1.0_grammar.y" { - DBG_MESG("dbg: WholeEnchilada", line_number); - ps10::invoke( 0, 0, yyvsp[0].lines); - ;} + DBG_MESG("dbg: WholeEnchilada", line_number); + ps10::invoke( 0, 0, yyvsp[0].lines); + ;} break; case 10: #line 132 "ps1.0_grammar.y" { - yyval.consts = new vector; - yyval.consts->push_back(* yyvsp[0].cdef); - delete yyvsp[0].cdef; - ;} + yyval.consts = new vector; + yyval.consts->push_back(* yyvsp[0].cdef); + delete yyvsp[0].cdef; + ;} break; case 11: #line 140 "ps1.0_grammar.y" { - yyval.consts = yyvsp[-1].consts; - yyval.consts->push_back(* yyvsp[0].cdef); - delete yyvsp[0].cdef; - ;} + yyval.consts = yyvsp[-1].consts; + yyval.consts->push_back(* yyvsp[0].cdef); + delete yyvsp[0].cdef; + ;} break; case 12: #line 152 "ps1.0_grammar.y" { - yyval.cdef = new constdef; - yyval.cdef->reg = * yyvsp[-9].sval; - yyval.cdef->r = yyvsp[-7].fval; - yyval.cdef->g = yyvsp[-5].fval; - yyval.cdef->b = yyvsp[-3].fval; - yyval.cdef->a = yyvsp[-1].fval; - delete yyvsp[-9].sval; - ;} + yyval.cdef = new constdef; + yyval.cdef->reg = * yyvsp[-9].sval; + yyval.cdef->r = yyvsp[-7].fval; + yyval.cdef->g = yyvsp[-5].fval; + yyval.cdef->b = yyvsp[-3].fval; + yyval.cdef->a = yyvsp[-1].fval; + delete yyvsp[-9].sval; + ;} break; case 13: #line 166 "ps1.0_grammar.y" { - yyval.lines = new list >; - yyval.lines->push_back(* yyvsp[0].line); - delete yyvsp[0].line; - ;} + yyval.lines = new list >; + yyval.lines->push_back(* yyvsp[0].line); + delete yyvsp[0].line; + ;} break; case 14: #line 174 "ps1.0_grammar.y" { - yyval.lines = yyvsp[-1].lines; - yyval.lines->push_back(* yyvsp[0].line); - delete yyvsp[0].line; - ;} + yyval.lines = yyvsp[-1].lines; + yyval.lines->push_back(* yyvsp[0].line); + delete yyvsp[0].line; + ;} break; case 15: #line 185 "ps1.0_grammar.y" { - yyval.line = new vector; - yyval.line->push_back(* yyvsp[-2].sval); - yyval.line->push_back(* yyvsp[-1].sval); - delete yyvsp[-2].sval; - delete yyvsp[-1].sval; - ;} + yyval.line = new vector; + yyval.line->push_back(* yyvsp[-2].sval); + yyval.line->push_back(* yyvsp[-1].sval); + delete yyvsp[-2].sval; + delete yyvsp[-1].sval; + ;} break; case 16: #line 195 "ps1.0_grammar.y" { - yyval.line = new vector; - yyval.line->push_back(* yyvsp[-4].sval); - yyval.line->push_back(* yyvsp[-3].sval); - yyval.line->push_back(* yyvsp[-1].sval); - delete yyvsp[-4].sval; - delete yyvsp[-3].sval; - delete yyvsp[-1].sval; - ;} + yyval.line = new vector; + yyval.line->push_back(* yyvsp[-4].sval); + yyval.line->push_back(* yyvsp[-3].sval); + yyval.line->push_back(* yyvsp[-1].sval); + delete yyvsp[-4].sval; + delete yyvsp[-3].sval; + delete yyvsp[-1].sval; + ;} break; case 17: #line 207 "ps1.0_grammar.y" { - yyval.line = new vector; - yyval.line->push_back(* yyvsp[-6].sval); - yyval.line->push_back(* yyvsp[-5].sval); - yyval.line->push_back(* yyvsp[-3].sval); - yyval.line->push_back(* yyvsp[-1].sval); - delete yyvsp[-6].sval; - delete yyvsp[-5].sval; - delete yyvsp[-3].sval; - delete yyvsp[-1].sval; - ;} + yyval.line = new vector; + yyval.line->push_back(* yyvsp[-6].sval); + yyval.line->push_back(* yyvsp[-5].sval); + yyval.line->push_back(* yyvsp[-3].sval); + yyval.line->push_back(* yyvsp[-1].sval); + delete yyvsp[-6].sval; + delete yyvsp[-5].sval; + delete yyvsp[-3].sval; + delete yyvsp[-1].sval; + ;} break; case 18: #line 224 "ps1.0_grammar.y" { - yyval.lines = new list >; - yyval.lines->push_back(* yyvsp[0].line); - delete yyvsp[0].line; - ;} + yyval.lines = new list >; + yyval.lines->push_back(* yyvsp[0].line); + delete yyvsp[0].line; + ;} break; case 19: #line 232 "ps1.0_grammar.y" { - yyval.lines = yyvsp[-1].lines; - yyval.lines->push_back(* yyvsp[0].line); - delete yyvsp[0].line; - ;} + yyval.lines = yyvsp[-1].lines; + yyval.lines->push_back(* yyvsp[0].line); + delete yyvsp[0].line; + ;} break; case 20: #line 244 "ps1.0_grammar.y" { - yyval.line = new vector; + yyval.line = new vector; if ( yyvsp[-5].ival ) yyval.line->push_back("+"); - yyval.line->push_back(* yyvsp[-4].sval); - yyval.line->push_back(* yyvsp[-3].sval); - yyval.line->push_back(* yyvsp[-1].sval); - delete yyvsp[-4].sval; - delete yyvsp[-3].sval; - delete yyvsp[-1].sval; - ;} + yyval.line->push_back(* yyvsp[-4].sval); + yyval.line->push_back(* yyvsp[-3].sval); + yyval.line->push_back(* yyvsp[-1].sval); + delete yyvsp[-4].sval; + delete yyvsp[-3].sval; + delete yyvsp[-1].sval; + ;} break; case 21: #line 258 "ps1.0_grammar.y" { - yyval.line = new vector; + yyval.line = new vector; if ( yyvsp[-7].ival ) yyval.line->push_back("+"); - yyval.line->push_back(* yyvsp[-6].sval); - yyval.line->push_back(* yyvsp[-5].sval); - yyval.line->push_back(* yyvsp[-3].sval); - yyval.line->push_back(* yyvsp[-1].sval); - delete yyvsp[-6].sval; - delete yyvsp[-5].sval; - delete yyvsp[-3].sval; - delete yyvsp[-1].sval; - ;} + yyval.line->push_back(* yyvsp[-6].sval); + yyval.line->push_back(* yyvsp[-5].sval); + yyval.line->push_back(* yyvsp[-3].sval); + yyval.line->push_back(* yyvsp[-1].sval); + delete yyvsp[-6].sval; + delete yyvsp[-5].sval; + delete yyvsp[-3].sval; + delete yyvsp[-1].sval; + ;} break; case 22: #line 274 "ps1.0_grammar.y" { - yyval.line = new vector; + yyval.line = new vector; if ( yyvsp[-9].ival ) yyval.line->push_back("+"); - yyval.line->push_back(* yyvsp[-8].sval); - yyval.line->push_back(* yyvsp[-7].sval); - yyval.line->push_back(* yyvsp[-5].sval); - yyval.line->push_back(* yyvsp[-3].sval); - yyval.line->push_back(* yyvsp[-1].sval); - delete yyvsp[-8].sval; - delete yyvsp[-7].sval; - delete yyvsp[-5].sval; - delete yyvsp[-3].sval; - delete yyvsp[-1].sval; - ;} + yyval.line->push_back(* yyvsp[-8].sval); + yyval.line->push_back(* yyvsp[-7].sval); + yyval.line->push_back(* yyvsp[-5].sval); + yyval.line->push_back(* yyvsp[-3].sval); + yyval.line->push_back(* yyvsp[-1].sval); + delete yyvsp[-8].sval; + delete yyvsp[-7].sval; + delete yyvsp[-5].sval; + delete yyvsp[-3].sval; + delete yyvsp[-1].sval; + ;} break; case 23: @@ -1394,50 +1394,50 @@ yyparse () yyn = yypact[yystate]; if (YYPACT_NINF < yyn && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("syntax error, unexpected ") + 1; - yysize += yystrlen (yytname[yytype]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); - - if (yycount < 5) - { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("syntax error; also virtual memory exhausted"); - } + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } else #endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); + yyerror ("syntax error"); } @@ -1445,21 +1445,21 @@ yyparse () if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + error, discard it. */ /* Return failure if at end of input. */ if (yychar == YYEOF) { - /* Pop the error token. */ + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); YYPOPSTACK; - /* Pop the rest of the stack. */ - while (yyss < yyssp) - { - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - YYPOPSTACK; - } - YYABORT; + } + YYABORT; } YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); @@ -1477,25 +1477,25 @@ yyparse () | yyerrlab1 -- error raised explicitly by an action. | `----------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); yydestruct (yystos[yystate], yyvsp); @@ -1555,6 +1555,6 @@ yyparse () void yyerror(const char* s) { - errors.set("parser: syntax error", line_number); + errors.set("parser: syntax error", line_number); } diff --git a/RenderSystems/GL/src/nvparse/_ps1.0_parser.h b/RenderSystems/GL/src/nvparse/_ps1.0_parser.h index d162ff7c218..ca7c63f17c1 100644 --- a/RenderSystems/GL/src/nvparse/_ps1.0_parser.h +++ b/RenderSystems/GL/src/nvparse/_ps1.0_parser.h @@ -79,14 +79,14 @@ THE SOFTWARE. #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) #line 43 "ps1.0_grammar.y" typedef union YYSTYPE { - int ival; - float fval; - - string * sval; - constdef * cdef; - vector * consts; - vector * line; - list > * lines; + int ival; + float fval; + + string * sval; + constdef * cdef; + vector * consts; + vector * line; + list > * lines; } YYSTYPE; /* Line 1240 of yacc.c. */ #line 65 "_ps1.0_parser.h" diff --git a/RenderSystems/GL/src/nvparse/_rc1.0_lexer.cpp b/RenderSystems/GL/src/nvparse/_rc1.0_lexer.cpp index 62f7fc40913..0fd6c266bb3 100644 --- a/RenderSystems/GL/src/nvparse/_rc1.0_lexer.cpp +++ b/RenderSystems/GL/src/nvparse/_rc1.0_lexer.cpp @@ -52,15 +52,15 @@ /* yyunput is never used */ #define YY_NO_UNPUT -#else /* ! __cplusplus */ +#else /* ! __cplusplus */ #if __STDC__ #define YY_USE_PROTOS #define YY_USE_CONST -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ #ifdef __TURBOC__ #pragma warn -rch @@ -131,10 +131,10 @@ extern FILE *yyin, *yyout; * int a single C statement (which needs a semi-colon terminator). This * avoids problems with code like: * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); * * Prior to using the do-while the compiler would get upset at the * "else" because it interpreted the "if" statement as being all @@ -144,15 +144,15 @@ extern FILE *yyin, *yyout; /* Return all but the first 'n' matched characters back to the input stream. */ #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) #define unput(c) yyunput( c, yytext_ptr ) @@ -164,61 +164,61 @@ typedef unsigned int yy_size_t; struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ #define YY_BUFFER_EOF_PENDING 2 - }; + }; static YY_BUFFER_STATE yy_current_buffer = 0; @@ -232,15 +232,15 @@ static YY_BUFFER_STATE yy_current_buffer = 0; /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ +static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... @@ -268,18 +268,18 @@ static void yy_flex_free YY_PROTO(( void * )); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } #define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } #define YY_AT_BOL() (yy_current_buffer->yy_at_bol) @@ -298,11 +298,11 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; #define YY_NUM_RULES 94 #define YY_END_OF_BUFFER 95 @@ -722,21 +722,21 @@ YY_MALLOC_DECL */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - @@ -777,1108 +777,1108 @@ YY_MALLOC_DECL #endif #define YY_RULE_SETUP \ - YY_USER_ACTION + YY_USER_ACTION YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp = NULL, *yy_bp = NULL; - register int yy_act; + { + register yy_state_type yy_current_state; + register char *yy_cp = NULL, *yy_bp = NULL; + register int yy_act; #line 27 "rc1.0_tokens.l" #line 789 "_rc1.0_lexer.cpp" - if ( yy_init ) - { - yy_init = 0; + if ( yy_init ) + { + yy_init = 0; #ifdef YY_USER_INIT - YY_USER_INIT; + YY_USER_INIT; #endif - if ( ! yy_start ) - yy_start = 1; /* first start state */ + if ( ! yy_start ) + yy_start = 1; /* first start state */ - if ( ! yyin ) - yyin = stdin; + if ( ! yyin ) + yyin = stdin; - if ( ! yyout ) - yyout = stdout; + if ( ! yyout ) + yyout = stdout; - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); - yy_load_buffer_state(); - } + yy_load_buffer_state(); + } - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; - /* Support of yytext. */ - *yy_cp = yy_hold_char; + /* Support of yytext. */ + *yy_cp = yy_hold_char; - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; - yy_current_state = yy_start; + yy_current_state = yy_start; yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 309 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 544 ); + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 309 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 544 ); yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } - YY_DO_BEFORE_ACTION; + YY_DO_BEFORE_ACTION; -do_action: /* This label is used only to access EOF actions. */ +do_action: /* This label is used only to access EOF actions. */ - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; case 1: YY_RULE_SETUP #line 29 "rc1.0_tokens.l" { - A: - switch (yyinput()) { - case '*': goto B; - case 0: errors.set("end-of-file in comment", line_number); break; - case '\n': line_number++; - default: goto A; - } - B: - switch (yyinput()) { - case '*': goto B; - case '/': break; - case 0: errors.set("end-of-file in comment", line_number); break; - case '\n': line_number++; - default: goto A; - } - } - YY_BREAK + A: + switch (yyinput()) { + case '*': goto B; + case 0: errors.set("end-of-file in comment", line_number); break; + case '\n': line_number++; + default: goto A; + } + B: + switch (yyinput()) { + case '*': goto B; + case '/': break; + case 0: errors.set("end-of-file in comment", line_number); break; + case '\n': line_number++; + default: goto A; + } + } + YY_BREAK case 2: YY_RULE_SETUP #line 47 "rc1.0_tokens.l" { - char ch; - while ((ch = yyinput()) != '\n'); - if (ch == '\n') line_number++; - } - YY_BREAK + char ch; + while ((ch = yyinput()) != '\n'); + if (ch == '\n') line_number++; + } + YY_BREAK case 3: YY_RULE_SETUP #line 53 "rc1.0_tokens.l" { - char ch; - while ((ch = yyinput()) != '\n'); - if (ch == '\n') line_number++; - } - YY_BREAK + char ch; + while ((ch = yyinput()) != '\n'); + if (ch == '\n') line_number++; + } + YY_BREAK case 4: YY_RULE_SETUP #line 59 "rc1.0_tokens.l" { /* eat header */ } - YY_BREAK + YY_BREAK case 5: YY_RULE_SETUP #line 61 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_FOG_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_FOG_RGB; + return(regVariable); + } + YY_BREAK case 6: YY_RULE_SETUP #line 65 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_FOG_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_FOG_ALPHA; + return(regVariable); + } + YY_BREAK case 7: YY_RULE_SETUP #line 69 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_FOG_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_FOG_BLUE; + return(regVariable); + } + YY_BREAK case 8: YY_RULE_SETUP #line 73 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_FOG; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_FOG; + return(regVariable); + } + YY_BREAK case 9: YY_RULE_SETUP #line 78 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_PRIMARY_COLOR_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_PRIMARY_COLOR_RGB; + return(regVariable); + } + YY_BREAK case 10: YY_RULE_SETUP #line 82 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_PRIMARY_COLOR_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_PRIMARY_COLOR_ALPHA; + return(regVariable); + } + YY_BREAK case 11: YY_RULE_SETUP #line 86 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_PRIMARY_COLOR_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_PRIMARY_COLOR_BLUE; + return(regVariable); + } + YY_BREAK case 12: YY_RULE_SETUP #line 90 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_PRIMARY_COLOR; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_PRIMARY_COLOR; + return(regVariable); + } + YY_BREAK case 13: YY_RULE_SETUP #line 95 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SECONDARY_COLOR_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SECONDARY_COLOR_RGB; + return(regVariable); + } + YY_BREAK case 14: YY_RULE_SETUP #line 99 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SECONDARY_COLOR_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SECONDARY_COLOR_ALPHA; + return(regVariable); + } + YY_BREAK case 15: YY_RULE_SETUP #line 103 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SECONDARY_COLOR_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SECONDARY_COLOR_BLUE; + return(regVariable); + } + YY_BREAK case 16: YY_RULE_SETUP #line 107 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SECONDARY_COLOR; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SECONDARY_COLOR; + return(regVariable); + } + YY_BREAK case 17: YY_RULE_SETUP #line 112 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SPARE0_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SPARE0_RGB; + return(regVariable); + } + YY_BREAK case 18: YY_RULE_SETUP #line 116 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SPARE0_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SPARE0_ALPHA; + return(regVariable); + } + YY_BREAK case 19: YY_RULE_SETUP #line 120 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SPARE0_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SPARE0_BLUE; + return(regVariable); + } + YY_BREAK case 20: YY_RULE_SETUP #line 124 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SPARE0; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SPARE0; + return(regVariable); + } + YY_BREAK case 21: YY_RULE_SETUP #line 129 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SPARE1_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SPARE1_RGB; + return(regVariable); + } + YY_BREAK case 22: YY_RULE_SETUP #line 133 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SPARE1_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SPARE1_ALPHA; + return(regVariable); + } + YY_BREAK case 23: YY_RULE_SETUP #line 137 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SPARE1_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SPARE1_BLUE; + return(regVariable); + } + YY_BREAK case 24: YY_RULE_SETUP #line 141 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_SPARE1; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_SPARE1; + return(regVariable); + } + YY_BREAK case 25: YY_RULE_SETUP #line 146 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE0_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE0_RGB; + return(regVariable); + } + YY_BREAK case 26: YY_RULE_SETUP #line 150 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE0_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE0_ALPHA; + return(regVariable); + } + YY_BREAK case 27: YY_RULE_SETUP #line 154 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE0_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE0_BLUE; + return(regVariable); + } + YY_BREAK case 28: YY_RULE_SETUP #line 158 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE0; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE0; + return(regVariable); + } + YY_BREAK case 29: YY_RULE_SETUP #line 163 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE1_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE1_RGB; + return(regVariable); + } + YY_BREAK case 30: YY_RULE_SETUP #line 167 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE1_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE1_ALPHA; + return(regVariable); + } + YY_BREAK case 31: YY_RULE_SETUP #line 171 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE1_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE1_BLUE; + return(regVariable); + } + YY_BREAK case 32: YY_RULE_SETUP #line 175 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE1; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE1; + return(regVariable); + } + YY_BREAK case 33: YY_RULE_SETUP #line 180 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE2_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE2_RGB; + return(regVariable); + } + YY_BREAK case 34: YY_RULE_SETUP #line 184 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE2_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE2_ALPHA; + return(regVariable); + } + YY_BREAK case 35: YY_RULE_SETUP #line 188 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE2_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE2_BLUE; + return(regVariable); + } + YY_BREAK case 36: YY_RULE_SETUP #line 192 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE2; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE2; + return(regVariable); + } + YY_BREAK case 37: YY_RULE_SETUP #line 197 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE3_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE3_RGB; + return(regVariable); + } + YY_BREAK case 38: YY_RULE_SETUP #line 201 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE3_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE3_ALPHA; + return(regVariable); + } + YY_BREAK case 39: YY_RULE_SETUP #line 205 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE3_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE3_BLUE; + return(regVariable); + } + YY_BREAK case 40: YY_RULE_SETUP #line 209 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_TEXTURE3; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_TEXTURE3; + return(regVariable); + } + YY_BREAK case 41: YY_RULE_SETUP #line 214 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_CONST_COLOR0_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_CONST_COLOR0_RGB; + return(regVariable); + } + YY_BREAK case 42: YY_RULE_SETUP #line 218 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_CONST_COLOR0_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_CONST_COLOR0_ALPHA; + return(regVariable); + } + YY_BREAK case 43: YY_RULE_SETUP #line 222 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_CONST_COLOR0_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_CONST_COLOR0_BLUE; + return(regVariable); + } + YY_BREAK case 44: YY_RULE_SETUP #line 226 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_CONST_COLOR0; - return(constVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_CONST_COLOR0; + return(constVariable); + } + YY_BREAK case 45: YY_RULE_SETUP #line 231 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_CONST_COLOR1_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_CONST_COLOR1_RGB; + return(regVariable); + } + YY_BREAK case 46: YY_RULE_SETUP #line 235 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_CONST_COLOR1_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_CONST_COLOR1_ALPHA; + return(regVariable); + } + YY_BREAK case 47: YY_RULE_SETUP #line 239 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_CONST_COLOR1_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_CONST_COLOR1_BLUE; + return(regVariable); + } + YY_BREAK case 48: YY_RULE_SETUP #line 243 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_CONST_COLOR1; - return(constVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_CONST_COLOR1; + return(constVariable); + } + YY_BREAK case 49: YY_RULE_SETUP #line 248 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_ZERO_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_ZERO_RGB; + return(regVariable); + } + YY_BREAK case 50: YY_RULE_SETUP #line 252 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_ZERO_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_ZERO_ALPHA; + return(regVariable); + } + YY_BREAK case 51: YY_RULE_SETUP #line 256 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_ZERO_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_ZERO_BLUE; + return(regVariable); + } + YY_BREAK case 52: YY_RULE_SETUP #line 260 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_ZERO; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_ZERO; + return(regVariable); + } + YY_BREAK case 53: YY_RULE_SETUP #line 265 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_ONE_RGB; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_ONE_RGB; + return(regVariable); + } + YY_BREAK case 54: YY_RULE_SETUP #line 269 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_ONE_ALPHA; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_ONE_ALPHA; + return(regVariable); + } + YY_BREAK case 55: YY_RULE_SETUP #line 273 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_ONE_BLUE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_ONE_BLUE; + return(regVariable); + } + YY_BREAK case 56: YY_RULE_SETUP #line 277 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_ONE; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_ONE; + return(regVariable); + } + YY_BREAK case 57: YY_RULE_SETUP #line 282 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_DISCARD; - return(regVariable); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_DISCARD; + return(regVariable); + } + YY_BREAK case 58: YY_RULE_SETUP #line 287 "rc1.0_tokens.l" return(fragment_rgb); - YY_BREAK + YY_BREAK case 59: YY_RULE_SETUP #line 288 "rc1.0_tokens.l" return(fragment_alpha); - YY_BREAK + YY_BREAK case 60: YY_RULE_SETUP #line 290 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_FINAL_PRODUCT; - return(final_product); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_FINAL_PRODUCT; + return(final_product); + } + YY_BREAK case 61: YY_RULE_SETUP #line 295 "rc1.0_tokens.l" { - rc10_lval.registerEnum.word = RCP_COLOR_SUM; - return(color_sum); - } - YY_BREAK + rc10_lval.registerEnum.word = RCP_COLOR_SUM; + return(color_sum); + } + YY_BREAK case 62: YY_RULE_SETUP #line 300 "rc1.0_tokens.l" return(expandString); - YY_BREAK + YY_BREAK case 63: YY_RULE_SETUP #line 301 "rc1.0_tokens.l" return(halfBiasString); - YY_BREAK + YY_BREAK case 64: YY_RULE_SETUP #line 302 "rc1.0_tokens.l" return(unsignedString); - YY_BREAK + YY_BREAK case 65: YY_RULE_SETUP #line 303 "rc1.0_tokens.l" return(unsignedInvertString); - YY_BREAK + YY_BREAK case 66: YY_RULE_SETUP #line 304 "rc1.0_tokens.l" { - rc10_lval.ival = GL_TRUE; - return(muxString); - } - YY_BREAK + rc10_lval.ival = GL_TRUE; + return(muxString); + } + YY_BREAK case 67: YY_RULE_SETUP #line 309 "rc1.0_tokens.l" { - rc10_lval.ival = GL_FALSE; - return(sumString); - } - YY_BREAK + rc10_lval.ival = GL_FALSE; + return(sumString); + } + YY_BREAK case 68: YY_RULE_SETUP #line 314 "rc1.0_tokens.l" { - rc10_lval.ival = RCP_RGB; - return(rgb_portion); - } - YY_BREAK + rc10_lval.ival = RCP_RGB; + return(rgb_portion); + } + YY_BREAK case 69: YY_RULE_SETUP #line 318 "rc1.0_tokens.l" { - rc10_lval.ival = RCP_ALPHA; - return(alpha_portion); - } - YY_BREAK + rc10_lval.ival = RCP_ALPHA; + return(alpha_portion); + } + YY_BREAK case 70: YY_RULE_SETUP #line 323 "rc1.0_tokens.l" { - rc10_lval.ival = true; - return(clamp_color_sum); - } - YY_BREAK + rc10_lval.ival = true; + return(clamp_color_sum); + } + YY_BREAK case 71: YY_RULE_SETUP #line 327 "rc1.0_tokens.l" return(lerp); - YY_BREAK + YY_BREAK case 72: YY_RULE_SETUP #line 330 "rc1.0_tokens.l" { - rc10_lval.biasScaleEnum.word = RCP_BIAS_BY_NEGATIVE_ONE_HALF_SCALE_BY_TWO; - return(bias_by_negative_one_half_scale_by_two); - } - YY_BREAK + rc10_lval.biasScaleEnum.word = RCP_BIAS_BY_NEGATIVE_ONE_HALF_SCALE_BY_TWO; + return(bias_by_negative_one_half_scale_by_two); + } + YY_BREAK case 73: YY_RULE_SETUP #line 334 "rc1.0_tokens.l" { - rc10_lval.biasScaleEnum.word = RCP_BIAS_BY_NEGATIVE_ONE_HALF; - return(bias_by_negative_one_half); - } - YY_BREAK + rc10_lval.biasScaleEnum.word = RCP_BIAS_BY_NEGATIVE_ONE_HALF; + return(bias_by_negative_one_half); + } + YY_BREAK case 74: YY_RULE_SETUP #line 338 "rc1.0_tokens.l" { - rc10_lval.biasScaleEnum.word = RCP_SCALE_BY_ONE_HALF; - return(scale_by_one_half); - } - YY_BREAK + rc10_lval.biasScaleEnum.word = RCP_SCALE_BY_ONE_HALF; + return(scale_by_one_half); + } + YY_BREAK case 75: YY_RULE_SETUP #line 342 "rc1.0_tokens.l" { - rc10_lval.biasScaleEnum.word = RCP_SCALE_BY_TWO; - return(scale_by_two); - } - YY_BREAK + rc10_lval.biasScaleEnum.word = RCP_SCALE_BY_TWO; + return(scale_by_two); + } + YY_BREAK case 76: YY_RULE_SETUP #line 346 "rc1.0_tokens.l" { - rc10_lval.biasScaleEnum.word = RCP_SCALE_BY_FOUR; - return(scale_by_four); - } - YY_BREAK + rc10_lval.biasScaleEnum.word = RCP_SCALE_BY_FOUR; + return(scale_by_four); + } + YY_BREAK case 77: YY_RULE_SETUP #line 351 "rc1.0_tokens.l" { - rc10_lval.fval = (float)atof(yytext); - return(floatValue); - } - YY_BREAK + rc10_lval.fval = (float)atof(yytext); + return(floatValue); + } + YY_BREAK case 78: YY_RULE_SETUP #line 356 "rc1.0_tokens.l" { - rc10_lval.fval = (float)atof(yytext); - return(floatValue); - } - YY_BREAK + rc10_lval.fval = (float)atof(yytext); + return(floatValue); + } + YY_BREAK case 79: YY_RULE_SETUP #line 361 "rc1.0_tokens.l" { - rc10_lval.fval = (float)atof(yytext); - return(floatValue); - } - YY_BREAK + rc10_lval.fval = (float)atof(yytext); + return(floatValue); + } + YY_BREAK case 80: YY_RULE_SETUP #line 366 "rc1.0_tokens.l" return(openBracket); - YY_BREAK + YY_BREAK case 81: YY_RULE_SETUP #line 367 "rc1.0_tokens.l" return(closeBracket); - YY_BREAK + YY_BREAK case 82: YY_RULE_SETUP #line 368 "rc1.0_tokens.l" return(openParen); - YY_BREAK + YY_BREAK case 83: YY_RULE_SETUP #line 369 "rc1.0_tokens.l" return(closeParen); - YY_BREAK + YY_BREAK case 84: YY_RULE_SETUP #line 370 "rc1.0_tokens.l" return(semicolon); - YY_BREAK + YY_BREAK case 85: YY_RULE_SETUP #line 371 "rc1.0_tokens.l" return(comma); - YY_BREAK + YY_BREAK case 86: YY_RULE_SETUP #line 372 "rc1.0_tokens.l" return(dot); - YY_BREAK + YY_BREAK case 87: YY_RULE_SETUP #line 373 "rc1.0_tokens.l" return(times); - YY_BREAK + YY_BREAK case 88: YY_RULE_SETUP #line 374 "rc1.0_tokens.l" return(minus); - YY_BREAK + YY_BREAK case 89: YY_RULE_SETUP #line 375 "rc1.0_tokens.l" return(plus); - YY_BREAK + YY_BREAK case 90: YY_RULE_SETUP #line 376 "rc1.0_tokens.l" return(equals); - YY_BREAK + YY_BREAK case 91: YY_RULE_SETUP #line 378 "rc1.0_tokens.l" { - line_number++; - } - YY_BREAK + line_number++; + } + YY_BREAK case 92: YY_RULE_SETUP #line 382 "rc1.0_tokens.l" {} - YY_BREAK + YY_BREAK case 93: YY_RULE_SETUP #line 384 "rc1.0_tokens.l" { - errors.set("unrecognized token", line_number); - } - YY_BREAK + errors.set("unrecognized token", line_number); + } + YY_BREAK case 94: YY_RULE_SETUP #line 389 "rc1.0_tokens.l" ECHO; - YY_BREAK + YY_BREAK #line 1574 "_rc1.0_lexer.cpp" case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ #ifdef YY_USES_REJECT - YY_FATAL_ERROR( + YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); #else - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; #endif - } + } - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); - yy_current_buffer->yy_n_chars = yy_n_chars; - } + yy_current_buffer->yy_n_chars = yy_n_chars; + } - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } - else - ret_val = EOB_ACT_CONTINUE_SCAN; + else + ret_val = EOB_ACT_CONTINUE_SCAN; - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - return ret_val; - } + return ret_val; + } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 309 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; - } + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 309 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis - * next_state = yy_try_NUL_trans( current_state ); + * next_state = yy_try_NUL_trans( current_state ); */ #ifdef YY_USE_PROTOS @@ -1887,27 +1887,27 @@ static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) static yy_state_type yy_try_NUL_trans( yy_current_state ) yy_state_type yy_current_state; #endif - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 309 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 308); - - return yy_is_jam ? 0 : yy_current_state; - } + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 309 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 308); + + return yy_is_jam ? 0 : yy_current_state; + } #ifndef YY_NO_UNPUT @@ -1918,41 +1918,41 @@ static void yyunput( c, yy_bp ) int c; register char *yy_bp; #endif - { - register char *yy_cp = yy_c_buf_p; + { + register char *yy_cp = yy_c_buf_p; - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } - *--yy_cp = (char) c; + *--yy_cp = (char) c; - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ #ifdef __cplusplus @@ -1960,72 +1960,72 @@ static int yyinput() #else static int input() #endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; #ifdef __cplusplus - return yyinput(); + return yyinput(); #else - return input(); + return input(); #endif - } + } - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; - return c; - } + return c; + } #ifdef YY_USE_PROTOS @@ -2034,13 +2034,13 @@ void yyrestart( FILE *input_file ) void yyrestart( input_file ) FILE *input_file; #endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } #ifdef YY_USE_PROTOS @@ -2049,28 +2049,28 @@ void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) void yy_switch_to_buffer( new_buffer ) YY_BUFFER_STATE new_buffer; #endif - { - if ( yy_current_buffer == new_buffer ) - return; + { + if ( yy_current_buffer == new_buffer ) + return; - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } - yy_current_buffer = new_buffer; - yy_load_buffer_state(); + yy_current_buffer = new_buffer; + yy_load_buffer_state(); - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } #ifdef YY_USE_PROTOS @@ -2078,12 +2078,12 @@ void yy_load_buffer_state( void ) #else void yy_load_buffer_state() #endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } #ifdef YY_USE_PROTOS @@ -2093,28 +2093,28 @@ YY_BUFFER_STATE yy_create_buffer( file, size ) FILE *file; int size; #endif - { - YY_BUFFER_STATE b; + { + YY_BUFFER_STATE b; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_buf_size = size; + b->yy_buf_size = size; - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_is_our_buffer = 1; + b->yy_is_our_buffer = 1; - yy_init_buffer( b, file ); + yy_init_buffer( b, file ); - return b; - } + return b; + } #ifdef YY_USE_PROTOS @@ -2123,18 +2123,18 @@ void yy_delete_buffer( YY_BUFFER_STATE b ) void yy_delete_buffer( b ) YY_BUFFER_STATE b; #endif - { - if ( ! b ) - return; + { + if ( ! b ) + return; - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); - yy_flex_free( (void *) b ); - } + yy_flex_free( (void *) b ); + } @@ -2147,22 +2147,22 @@ FILE *file; #endif - { - yy_flush_buffer( b ); + { + yy_flush_buffer( b ); - b->yy_input_file = file; - b->yy_fill_buffer = 1; + b->yy_input_file = file; + b->yy_fill_buffer = 1; #if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; + b->yy_is_interactive = 1; #else #if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; + b->yy_is_interactive = 0; #else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; #endif #endif - } + } #ifdef YY_USE_PROTOS @@ -2172,27 +2172,27 @@ void yy_flush_buffer( b ) YY_BUFFER_STATE b; #endif - { - if ( ! b ) - return; + { + if ( ! b ) + return; - b->yy_n_chars = 0; + b->yy_n_chars = 0; - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - b->yy_buf_pos = &b->yy_ch_buf[0]; + b->yy_buf_pos = &b->yy_ch_buf[0]; - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } #ifndef YY_NO_SCAN_BUFFER @@ -2203,33 +2203,33 @@ YY_BUFFER_STATE yy_scan_buffer( base, size ) char *base; yy_size_t size; #endif - { - YY_BUFFER_STATE b; + { + YY_BUFFER_STATE b; - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; - yy_switch_to_buffer( b ); + yy_switch_to_buffer( b ); - return b; - } + return b; + } #endif @@ -2240,13 +2240,13 @@ YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) YY_BUFFER_STATE yy_scan_string( yy_str ) yyconst char *yy_str; #endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; - return yy_scan_bytes( yy_str, len ); - } + return yy_scan_bytes( yy_str, len ); + } #endif @@ -2258,34 +2258,34 @@ YY_BUFFER_STATE yy_scan_bytes( bytes, len ) yyconst char *bytes; int len; #endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; - return b; - } + return b; + } #endif @@ -2296,49 +2296,49 @@ static void yy_push_state( int new_state ) static void yy_push_state( new_state ) int new_state; #endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } - yy_start_stack[yy_start_stack_ptr++] = YY_START; + yy_start_stack[yy_start_stack_ptr++] = YY_START; - BEGIN(new_state); - } + BEGIN(new_state); + } #endif #ifndef YY_NO_POP_STATE static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } #endif #ifndef YY_NO_TOP_STATE static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } #endif #ifndef YY_EXIT_FAILURE @@ -2351,10 +2351,10 @@ static void yy_fatal_error( yyconst char msg[] ) static void yy_fatal_error( msg ) char msg[]; #endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } @@ -2362,16 +2362,16 @@ char msg[]; #undef yyless #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) /* Internal utility routines. */ @@ -2385,11 +2385,11 @@ char *s1; yyconst char *s2; int n; #endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } #endif #ifdef YY_NEED_STRLEN @@ -2399,13 +2399,13 @@ static int yy_flex_strlen( yyconst char *s ) static int yy_flex_strlen( s ) yyconst char *s; #endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; + { + register int n; + for ( n = 0; s[n]; ++n ) + ; - return n; - } + return n; + } #endif @@ -2415,9 +2415,9 @@ static void *yy_flex_alloc( yy_size_t size ) static void *yy_flex_alloc( size ) yy_size_t size; #endif - { - return (void *) malloc( size ); - } + { + return (void *) malloc( size ); + } #ifdef YY_USE_PROTOS static void *yy_flex_realloc( void *ptr, yy_size_t size ) @@ -2426,16 +2426,16 @@ static void *yy_flex_realloc( ptr, size ) void *ptr; yy_size_t size; #endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } #ifdef YY_USE_PROTOS static void yy_flex_free( void *ptr ) @@ -2443,16 +2443,16 @@ static void yy_flex_free( void *ptr ) static void yy_flex_free( ptr ) void *ptr; #endif - { - free( ptr ); - } + { + free( ptr ); + } #if YY_MAIN int main() - { - yylex(); - return 0; - } + { + yylex(); + return 0; + } #endif #line 389 "rc1.0_tokens.l" @@ -2462,7 +2462,7 @@ bool rc10_init_more(); bool rc10_init(char* inputString) { myin = inputString; - return rc10_init_more(); + return rc10_init_more(); } #ifndef rc10_wrap diff --git a/RenderSystems/GL/src/nvparse/_rc1.0_parser.cpp b/RenderSystems/GL/src/nvparse/_rc1.0_parser.cpp index 9b8fc3ffd88..8048b6e1b8c 100644 --- a/RenderSystems/GL/src/nvparse/_rc1.0_parser.cpp +++ b/RenderSystems/GL/src/nvparse/_rc1.0_parser.cpp @@ -170,7 +170,7 @@ int yylex ( void ); #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif # include #endif @@ -267,7 +267,7 @@ typedef union YYSTYPE { #if (! defined (yyoverflow) \ && (! defined (__cplusplus) \ - || (YYSTYPE_IS_TRIVIAL))) + || (YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc @@ -282,7 +282,7 @@ union yyalloc /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do @@ -292,13 +292,13 @@ union yyalloc # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ while (0) # endif # endif @@ -308,15 +308,15 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ while (0) #endif @@ -345,7 +345,7 @@ union yyalloc #define YYUNDEFTOK 2 #define YYMAXUTOK 290 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ @@ -705,43 +705,43 @@ static const unsigned char yystos[] = # define YYSIZE_T unsigned int #endif -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab +#define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ + YYERROR; \ + } \ while (0) -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYTERROR 1 +#define YYERRCODE 256 /* YYLLOC_DEFAULT -- Compute the default location (before the actions are run). */ @@ -770,27 +770,27 @@ while (0) # define YYFPRINTF fprintf # endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ } while (0) -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ } while (0) -# define YYDSYMPRINTF(Title, Token, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ } while (0) /*------------------------------------------------------------------. @@ -814,10 +814,10 @@ yy_stack_print (bottom, top) YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ } while (0) @@ -844,10 +844,10 @@ yy_reduce_print (yyrule) YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that @@ -863,7 +863,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -1072,7 +1072,7 @@ yyparse () to reallocate them elsewhere. */ /* The state stack. */ - short yyssa[YYINITDEPTH]; + short yyssa[YYINITDEPTH]; short *yyss = yyssa; register short *yyssp; @@ -1101,7 +1101,7 @@ yyparse () yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack @@ -1132,25 +1132,25 @@ yyparse () #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); + &yystacksize); - yyss = yyss1; - yyvs = yyvs1; + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -1158,23 +1158,23 @@ yyparse () # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; + goto yyoverflowlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@ -1184,10 +1184,10 @@ yyparse () YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1238,7 +1238,7 @@ yyparse () if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; + goto yyerrlab; yyn = -yyn; goto yyreduce; } @@ -1299,822 +1299,822 @@ yyparse () case 2: #line 74 "rc1.0_grammar.y" { - yyvsp[0].combinersStruct.Validate(); - yyvsp[0].combinersStruct.Invoke(); - ;} + yyvsp[0].combinersStruct.Validate(); + yyvsp[0].combinersStruct.Invoke(); + ;} break; case 3: #line 81 "rc1.0_grammar.y" { - CombinersStruct combinersStruct; - combinersStruct.Init(yyvsp[-1].generalCombinersStruct, yyvsp[0].finalCombinerStruct, yyvsp[-2].constColorStruct); - yyval.combinersStruct = combinersStruct; - ;} + CombinersStruct combinersStruct; + combinersStruct.Init(yyvsp[-1].generalCombinersStruct, yyvsp[0].finalCombinerStruct, yyvsp[-2].constColorStruct); + yyval.combinersStruct = combinersStruct; + ;} break; case 4: #line 87 "rc1.0_grammar.y" { - CombinersStruct combinersStruct; - combinersStruct.Init(yyvsp[-1].generalCombinersStruct, yyvsp[0].finalCombinerStruct, yyvsp[-3].constColorStruct, yyvsp[-2].constColorStruct); - yyval.combinersStruct = combinersStruct; - ;} + CombinersStruct combinersStruct; + combinersStruct.Init(yyvsp[-1].generalCombinersStruct, yyvsp[0].finalCombinerStruct, yyvsp[-3].constColorStruct, yyvsp[-2].constColorStruct); + yyval.combinersStruct = combinersStruct; + ;} break; case 5: #line 93 "rc1.0_grammar.y" { - CombinersStruct combinersStruct; - combinersStruct.Init(yyvsp[-1].generalCombinersStruct, yyvsp[0].finalCombinerStruct); - yyval.combinersStruct = combinersStruct; - ;} + CombinersStruct combinersStruct; + combinersStruct.Init(yyvsp[-1].generalCombinersStruct, yyvsp[0].finalCombinerStruct); + yyval.combinersStruct = combinersStruct; + ;} break; case 6: #line 99 "rc1.0_grammar.y" { - GeneralCombinersStruct generalCombinersStruct; - generalCombinersStruct.Init(); - CombinersStruct combinersStruct; - combinersStruct.Init(generalCombinersStruct, yyvsp[0].finalCombinerStruct, yyvsp[-1].constColorStruct); - yyval.combinersStruct = combinersStruct; - ;} + GeneralCombinersStruct generalCombinersStruct; + generalCombinersStruct.Init(); + CombinersStruct combinersStruct; + combinersStruct.Init(generalCombinersStruct, yyvsp[0].finalCombinerStruct, yyvsp[-1].constColorStruct); + yyval.combinersStruct = combinersStruct; + ;} break; case 7: #line 107 "rc1.0_grammar.y" { - GeneralCombinersStruct generalCombinersStruct; - generalCombinersStruct.Init(); - CombinersStruct combinersStruct; - combinersStruct.Init(generalCombinersStruct, yyvsp[0].finalCombinerStruct, yyvsp[-2].constColorStruct, yyvsp[-1].constColorStruct); - yyval.combinersStruct = combinersStruct; - ;} + GeneralCombinersStruct generalCombinersStruct; + generalCombinersStruct.Init(); + CombinersStruct combinersStruct; + combinersStruct.Init(generalCombinersStruct, yyvsp[0].finalCombinerStruct, yyvsp[-2].constColorStruct, yyvsp[-1].constColorStruct); + yyval.combinersStruct = combinersStruct; + ;} break; case 8: #line 115 "rc1.0_grammar.y" { - GeneralCombinersStruct generalCombinersStruct; - generalCombinersStruct.Init(); - CombinersStruct combinersStruct; - combinersStruct.Init(generalCombinersStruct, yyvsp[0].finalCombinerStruct); - yyval.combinersStruct = combinersStruct; - ;} + GeneralCombinersStruct generalCombinersStruct; + generalCombinersStruct.Init(); + CombinersStruct combinersStruct; + combinersStruct.Init(generalCombinersStruct, yyvsp[0].finalCombinerStruct); + yyval.combinersStruct = combinersStruct; + ;} break; case 9: #line 125 "rc1.0_grammar.y" { - ConstColorStruct constColorStruct; - constColorStruct.Init(yyvsp[-11].registerEnum, yyvsp[-8].fval, yyvsp[-6].fval, yyvsp[-4].fval, yyvsp[-2].fval); - yyval.constColorStruct = constColorStruct; - ;} + ConstColorStruct constColorStruct; + constColorStruct.Init(yyvsp[-11].registerEnum, yyvsp[-8].fval, yyvsp[-6].fval, yyvsp[-4].fval, yyvsp[-2].fval); + yyval.constColorStruct = constColorStruct; + ;} break; case 10: #line 134 "rc1.0_grammar.y" { - yyvsp[-1].generalCombinersStruct += yyvsp[0].generalCombinerStruct; - yyval.generalCombinersStruct = yyvsp[-1].generalCombinersStruct; - ;} + yyvsp[-1].generalCombinersStruct += yyvsp[0].generalCombinerStruct; + yyval.generalCombinersStruct = yyvsp[-1].generalCombinersStruct; + ;} break; case 11: #line 139 "rc1.0_grammar.y" { - GeneralCombinersStruct generalCombinersStruct; - generalCombinersStruct.Init(yyvsp[0].generalCombinerStruct); - yyval.generalCombinersStruct = generalCombinersStruct; - ;} + GeneralCombinersStruct generalCombinersStruct; + generalCombinersStruct.Init(yyvsp[0].generalCombinerStruct); + yyval.generalCombinersStruct = generalCombinersStruct; + ;} break; case 12: #line 147 "rc1.0_grammar.y" { - GeneralCombinerStruct generalCombinerStruct; - generalCombinerStruct.Init(yyvsp[-2].generalPortionStruct, yyvsp[-1].generalPortionStruct); - yyval.generalCombinerStruct = generalCombinerStruct; - ;} + GeneralCombinerStruct generalCombinerStruct; + generalCombinerStruct.Init(yyvsp[-2].generalPortionStruct, yyvsp[-1].generalPortionStruct); + yyval.generalCombinerStruct = generalCombinerStruct; + ;} break; case 13: #line 153 "rc1.0_grammar.y" { - GeneralCombinerStruct generalCombinerStruct; - generalCombinerStruct.Init(yyvsp[-2].generalPortionStruct, yyvsp[-1].generalPortionStruct, yyvsp[-3].constColorStruct); - yyval.generalCombinerStruct = generalCombinerStruct; - ;} + GeneralCombinerStruct generalCombinerStruct; + generalCombinerStruct.Init(yyvsp[-2].generalPortionStruct, yyvsp[-1].generalPortionStruct, yyvsp[-3].constColorStruct); + yyval.generalCombinerStruct = generalCombinerStruct; + ;} break; case 14: #line 159 "rc1.0_grammar.y" { - GeneralCombinerStruct generalCombinerStruct; - generalCombinerStruct.Init(yyvsp[-2].generalPortionStruct, yyvsp[-1].generalPortionStruct, yyvsp[-4].constColorStruct, yyvsp[-3].constColorStruct); - yyval.generalCombinerStruct = generalCombinerStruct; - ;} + GeneralCombinerStruct generalCombinerStruct; + generalCombinerStruct.Init(yyvsp[-2].generalPortionStruct, yyvsp[-1].generalPortionStruct, yyvsp[-4].constColorStruct, yyvsp[-3].constColorStruct); + yyval.generalCombinerStruct = generalCombinerStruct; + ;} break; case 15: #line 165 "rc1.0_grammar.y" { - GeneralCombinerStruct generalCombinerStruct; - generalCombinerStruct.Init(yyvsp[-1].generalPortionStruct); - yyval.generalCombinerStruct = generalCombinerStruct; - ;} + GeneralCombinerStruct generalCombinerStruct; + generalCombinerStruct.Init(yyvsp[-1].generalPortionStruct); + yyval.generalCombinerStruct = generalCombinerStruct; + ;} break; case 16: #line 171 "rc1.0_grammar.y" { - GeneralCombinerStruct generalCombinerStruct; - generalCombinerStruct.Init(yyvsp[-1].generalPortionStruct, yyvsp[-2].constColorStruct); - yyval.generalCombinerStruct = generalCombinerStruct; - ;} + GeneralCombinerStruct generalCombinerStruct; + generalCombinerStruct.Init(yyvsp[-1].generalPortionStruct, yyvsp[-2].constColorStruct); + yyval.generalCombinerStruct = generalCombinerStruct; + ;} break; case 17: #line 177 "rc1.0_grammar.y" { - GeneralCombinerStruct generalCombinerStruct; - generalCombinerStruct.Init(yyvsp[-1].generalPortionStruct, yyvsp[-3].constColorStruct, yyvsp[-2].constColorStruct); - yyval.generalCombinerStruct = generalCombinerStruct; - ;} + GeneralCombinerStruct generalCombinerStruct; + generalCombinerStruct.Init(yyvsp[-1].generalPortionStruct, yyvsp[-3].constColorStruct, yyvsp[-2].constColorStruct); + yyval.generalCombinerStruct = generalCombinerStruct; + ;} break; case 18: #line 185 "rc1.0_grammar.y" { - GeneralPortionStruct generalPortionStruct; - generalPortionStruct.Init(yyvsp[-4].ival, yyvsp[-2].generalFunctionStruct, yyvsp[-1].biasScaleEnum); - yyval.generalPortionStruct = generalPortionStruct; - ;} + GeneralPortionStruct generalPortionStruct; + generalPortionStruct.Init(yyvsp[-4].ival, yyvsp[-2].generalFunctionStruct, yyvsp[-1].biasScaleEnum); + yyval.generalPortionStruct = generalPortionStruct; + ;} break; case 19: #line 191 "rc1.0_grammar.y" { - BiasScaleEnum noScale; - noScale.word = RCP_SCALE_BY_ONE; - GeneralPortionStruct generalPortionStruct; - generalPortionStruct.Init(yyvsp[-3].ival, yyvsp[-1].generalFunctionStruct, noScale); - yyval.generalPortionStruct = generalPortionStruct; - ;} + BiasScaleEnum noScale; + noScale.word = RCP_SCALE_BY_ONE; + GeneralPortionStruct generalPortionStruct; + generalPortionStruct.Init(yyvsp[-3].ival, yyvsp[-1].generalFunctionStruct, noScale); + yyval.generalPortionStruct = generalPortionStruct; + ;} break; case 20: #line 201 "rc1.0_grammar.y" { - yyval.ival = yyvsp[0].ival; - ;} + yyval.ival = yyvsp[0].ival; + ;} break; case 21: #line 205 "rc1.0_grammar.y" { - yyval.ival = yyvsp[0].ival; - ;} + yyval.ival = yyvsp[0].ival; + ;} break; case 22: #line 211 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[0].registerEnum, GL_SIGNED_IDENTITY_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[0].registerEnum, GL_SIGNED_IDENTITY_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 23: #line 217 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[0].registerEnum, GL_SIGNED_NEGATE_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[0].registerEnum, GL_SIGNED_NEGATE_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 24: #line 223 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_EXPAND_NORMAL_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_EXPAND_NORMAL_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 25: #line 229 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_EXPAND_NEGATE_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_EXPAND_NEGATE_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 26: #line 235 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_HALF_BIAS_NORMAL_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_HALF_BIAS_NORMAL_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 27: #line 241 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_HALF_BIAS_NEGATE_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_HALF_BIAS_NEGATE_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 28: #line 247 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_IDENTITY_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_IDENTITY_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 29: #line 253 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_INVERT_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_INVERT_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 30: #line 261 "rc1.0_grammar.y" { - GeneralFunctionStruct generalFunction; - generalFunction.Init(yyvsp[-1].opStruct, yyvsp[0].opStruct); - yyval.generalFunctionStruct = generalFunction; - ;} + GeneralFunctionStruct generalFunction; + generalFunction.Init(yyvsp[-1].opStruct, yyvsp[0].opStruct); + yyval.generalFunctionStruct = generalFunction; + ;} break; case 31: #line 267 "rc1.0_grammar.y" { - GeneralFunctionStruct generalFunction; - generalFunction.Init(yyvsp[-1].opStruct, yyvsp[0].opStruct); - yyval.generalFunctionStruct = generalFunction; - ;} + GeneralFunctionStruct generalFunction; + generalFunction.Init(yyvsp[-1].opStruct, yyvsp[0].opStruct); + yyval.generalFunctionStruct = generalFunction; + ;} break; case 32: #line 273 "rc1.0_grammar.y" { - GeneralFunctionStruct generalFunction; - generalFunction.Init(yyvsp[-1].opStruct, yyvsp[0].opStruct); - yyval.generalFunctionStruct = generalFunction; - ;} + GeneralFunctionStruct generalFunction; + generalFunction.Init(yyvsp[-1].opStruct, yyvsp[0].opStruct); + yyval.generalFunctionStruct = generalFunction; + ;} break; case 33: #line 279 "rc1.0_grammar.y" { - GeneralFunctionStruct generalFunction; - generalFunction.Init(yyvsp[0].opStruct); - yyval.generalFunctionStruct = generalFunction; - ;} + GeneralFunctionStruct generalFunction; + generalFunction.Init(yyvsp[0].opStruct); + yyval.generalFunctionStruct = generalFunction; + ;} break; case 34: #line 285 "rc1.0_grammar.y" { - GeneralFunctionStruct generalFunction; - generalFunction.Init(yyvsp[-1].opStruct, yyvsp[0].opStruct); - yyval.generalFunctionStruct = generalFunction; - ;} + GeneralFunctionStruct generalFunction; + generalFunction.Init(yyvsp[-1].opStruct, yyvsp[0].opStruct); + yyval.generalFunctionStruct = generalFunction; + ;} break; case 35: #line 291 "rc1.0_grammar.y" { - GeneralFunctionStruct generalFunction; - generalFunction.Init(yyvsp[-2].opStruct, yyvsp[-1].opStruct, yyvsp[0].opStruct); - yyval.generalFunctionStruct = generalFunction; - ;} + GeneralFunctionStruct generalFunction; + generalFunction.Init(yyvsp[-2].opStruct, yyvsp[-1].opStruct, yyvsp[0].opStruct); + yyval.generalFunctionStruct = generalFunction; + ;} break; case 36: #line 297 "rc1.0_grammar.y" { - GeneralFunctionStruct generalFunction; - generalFunction.Init(yyvsp[-2].opStruct, yyvsp[-1].opStruct, yyvsp[0].opStruct); - yyval.generalFunctionStruct = generalFunction; - ;} + GeneralFunctionStruct generalFunction; + generalFunction.Init(yyvsp[-2].opStruct, yyvsp[-1].opStruct, yyvsp[0].opStruct); + yyval.generalFunctionStruct = generalFunction; + ;} break; case 37: #line 303 "rc1.0_grammar.y" { - GeneralFunctionStruct generalFunction; - generalFunction.Init(yyvsp[0].opStruct); - yyval.generalFunctionStruct = generalFunction; - ;} + GeneralFunctionStruct generalFunction; + generalFunction.Init(yyvsp[0].opStruct); + yyval.generalFunctionStruct = generalFunction; + ;} break; case 38: #line 311 "rc1.0_grammar.y" { - OpStruct dotFunction; - dotFunction.Init(RCP_DOT, yyvsp[-5].registerEnum, yyvsp[-3].mappedRegisterStruct, yyvsp[-1].mappedRegisterStruct); - yyval.opStruct = dotFunction; - ;} + OpStruct dotFunction; + dotFunction.Init(RCP_DOT, yyvsp[-5].registerEnum, yyvsp[-3].mappedRegisterStruct, yyvsp[-1].mappedRegisterStruct); + yyval.opStruct = dotFunction; + ;} break; case 39: #line 319 "rc1.0_grammar.y" { - OpStruct mulFunction; - mulFunction.Init(RCP_MUL, yyvsp[-5].registerEnum, yyvsp[-3].mappedRegisterStruct, yyvsp[-1].mappedRegisterStruct); - yyval.opStruct = mulFunction; - ;} + OpStruct mulFunction; + mulFunction.Init(RCP_MUL, yyvsp[-5].registerEnum, yyvsp[-3].mappedRegisterStruct, yyvsp[-1].mappedRegisterStruct); + yyval.opStruct = mulFunction; + ;} break; case 40: #line 325 "rc1.0_grammar.y" { - RegisterEnum zero; - zero.word = RCP_ZERO; - MappedRegisterStruct one; - one.Init(zero, GL_UNSIGNED_INVERT_NV); - OpStruct mulFunction; - mulFunction.Init(RCP_MUL, yyvsp[-3].registerEnum, yyvsp[-1].mappedRegisterStruct, one); - yyval.opStruct = mulFunction; - ;} + RegisterEnum zero; + zero.word = RCP_ZERO; + MappedRegisterStruct one; + one.Init(zero, GL_UNSIGNED_INVERT_NV); + OpStruct mulFunction; + mulFunction.Init(RCP_MUL, yyvsp[-3].registerEnum, yyvsp[-1].mappedRegisterStruct, one); + yyval.opStruct = mulFunction; + ;} break; case 41: #line 337 "rc1.0_grammar.y" { - OpStruct muxFunction; - muxFunction.Init(RCP_MUX, yyvsp[-5].registerEnum); - yyval.opStruct = muxFunction; - ;} + OpStruct muxFunction; + muxFunction.Init(RCP_MUX, yyvsp[-5].registerEnum); + yyval.opStruct = muxFunction; + ;} break; case 42: #line 345 "rc1.0_grammar.y" { - OpStruct sumFunction; - sumFunction.Init(RCP_SUM, yyvsp[-5].registerEnum); - yyval.opStruct = sumFunction; - ;} + OpStruct sumFunction; + sumFunction.Init(RCP_SUM, yyvsp[-5].registerEnum); + yyval.opStruct = sumFunction; + ;} break; case 43: #line 353 "rc1.0_grammar.y" { - yyval.biasScaleEnum = yyvsp[-3].biasScaleEnum; - ;} + yyval.biasScaleEnum = yyvsp[-3].biasScaleEnum; + ;} break; case 44: #line 357 "rc1.0_grammar.y" { - yyval.biasScaleEnum = yyvsp[-3].biasScaleEnum; - ;} + yyval.biasScaleEnum = yyvsp[-3].biasScaleEnum; + ;} break; case 45: #line 361 "rc1.0_grammar.y" { - yyval.biasScaleEnum = yyvsp[-3].biasScaleEnum; - ;} + yyval.biasScaleEnum = yyvsp[-3].biasScaleEnum; + ;} break; case 46: #line 365 "rc1.0_grammar.y" { - yyval.biasScaleEnum = yyvsp[-3].biasScaleEnum; - ;} + yyval.biasScaleEnum = yyvsp[-3].biasScaleEnum; + ;} break; case 47: #line 369 "rc1.0_grammar.y" { - yyval.biasScaleEnum = yyvsp[-3].biasScaleEnum; - ;} + yyval.biasScaleEnum = yyvsp[-3].biasScaleEnum; + ;} break; case 48: #line 375 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[0].registerEnum, GL_UNSIGNED_IDENTITY_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[0].registerEnum, GL_UNSIGNED_IDENTITY_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 49: #line 381 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_IDENTITY_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_IDENTITY_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 50: #line 387 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_INVERT_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_INVERT_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 51: #line 393 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[0].registerEnum); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[0].registerEnum); + yyval.mappedRegisterStruct = reg; + ;} break; case 52: #line 399 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_IDENTITY_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_IDENTITY_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 53: #line 405 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_INVERT_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_INVERT_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 54: #line 411 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[0].registerEnum); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[0].registerEnum); + yyval.mappedRegisterStruct = reg; + ;} break; case 55: #line 417 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_IDENTITY_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_IDENTITY_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 56: #line 423 "rc1.0_grammar.y" { - MappedRegisterStruct reg; - reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_INVERT_NV); - yyval.mappedRegisterStruct = reg; - ;} + MappedRegisterStruct reg; + reg.Init(yyvsp[-1].registerEnum, GL_UNSIGNED_INVERT_NV); + yyval.mappedRegisterStruct = reg; + ;} break; case 57: #line 431 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, yyvsp[-1].finalAlphaFunctionStruct, false); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, yyvsp[-1].finalAlphaFunctionStruct, false); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 58: #line 437 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, yyvsp[-1].finalAlphaFunctionStruct, true); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, yyvsp[-1].finalAlphaFunctionStruct, true); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 59: #line 443 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, yyvsp[-1].finalAlphaFunctionStruct, false, yyvsp[-2].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, yyvsp[-1].finalAlphaFunctionStruct, false, yyvsp[-2].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 60: #line 449 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, yyvsp[-1].finalAlphaFunctionStruct, true, yyvsp[-2].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, yyvsp[-1].finalAlphaFunctionStruct, true, yyvsp[-2].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 61: #line 455 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, yyvsp[-1].finalAlphaFunctionStruct, true, yyvsp[-3].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, yyvsp[-1].finalAlphaFunctionStruct, true, yyvsp[-3].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 62: #line 462 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - finalCombinerStruct.Init(yyvsp[-1].finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, false); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + finalCombinerStruct.Init(yyvsp[-1].finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, false); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 63: #line 468 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - finalCombinerStruct.Init(yyvsp[-1].finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + finalCombinerStruct.Init(yyvsp[-1].finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 64: #line 474 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - finalCombinerStruct.Init(yyvsp[-1].finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, false, yyvsp[-2].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + finalCombinerStruct.Init(yyvsp[-1].finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, false, yyvsp[-2].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 65: #line 480 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - finalCombinerStruct.Init(yyvsp[-1].finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true, yyvsp[-2].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + finalCombinerStruct.Init(yyvsp[-1].finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true, yyvsp[-2].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 66: #line 486 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - finalCombinerStruct.Init(yyvsp[-1].finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true, yyvsp[-3].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + finalCombinerStruct.Init(yyvsp[-1].finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true, yyvsp[-3].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 67: #line 493 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - FinalAlphaFunctionStruct finalAlphaFunctionStruct; - finalAlphaFunctionStruct.ZeroOut(); - finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, finalAlphaFunctionStruct, false); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + FinalAlphaFunctionStruct finalAlphaFunctionStruct; + finalAlphaFunctionStruct.ZeroOut(); + finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, finalAlphaFunctionStruct, false); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 68: #line 501 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - FinalAlphaFunctionStruct finalAlphaFunctionStruct; - finalAlphaFunctionStruct.ZeroOut(); - finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, finalAlphaFunctionStruct, true); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + FinalAlphaFunctionStruct finalAlphaFunctionStruct; + finalAlphaFunctionStruct.ZeroOut(); + finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, finalAlphaFunctionStruct, true); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 69: #line 509 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - FinalAlphaFunctionStruct finalAlphaFunctionStruct; - finalAlphaFunctionStruct.ZeroOut(); - finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, finalAlphaFunctionStruct, false, yyvsp[-1].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + FinalAlphaFunctionStruct finalAlphaFunctionStruct; + finalAlphaFunctionStruct.ZeroOut(); + finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, finalAlphaFunctionStruct, false, yyvsp[-1].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 70: #line 517 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - FinalAlphaFunctionStruct finalAlphaFunctionStruct; - finalAlphaFunctionStruct.ZeroOut(); - finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, finalAlphaFunctionStruct, true, yyvsp[-1].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + FinalAlphaFunctionStruct finalAlphaFunctionStruct; + finalAlphaFunctionStruct.ZeroOut(); + finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, finalAlphaFunctionStruct, true, yyvsp[-1].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 71: #line 525 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - FinalAlphaFunctionStruct finalAlphaFunctionStruct; - finalAlphaFunctionStruct.ZeroOut(); - finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, finalAlphaFunctionStruct, true, yyvsp[-2].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + FinalAlphaFunctionStruct finalAlphaFunctionStruct; + finalAlphaFunctionStruct.ZeroOut(); + finalCombinerStruct.Init(yyvsp[0].finalRgbFunctionStruct, finalAlphaFunctionStruct, true, yyvsp[-2].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 72: #line 534 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.ZeroOut(); - finalCombinerStruct.Init(finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, false); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.ZeroOut(); + finalCombinerStruct.Init(finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, false); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 73: #line 542 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.ZeroOut(); - finalCombinerStruct.Init(finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.ZeroOut(); + finalCombinerStruct.Init(finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 74: #line 550 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.ZeroOut(); - finalCombinerStruct.Init(finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, false, yyvsp[-1].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.ZeroOut(); + finalCombinerStruct.Init(finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, false, yyvsp[-1].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 75: #line 558 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.ZeroOut(); - finalCombinerStruct.Init(finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true, yyvsp[-1].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.ZeroOut(); + finalCombinerStruct.Init(finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true, yyvsp[-1].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 76: #line 566 "rc1.0_grammar.y" { - FinalCombinerStruct finalCombinerStruct; - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.ZeroOut(); - finalCombinerStruct.Init(finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true, yyvsp[-2].finalProductStruct); - yyval.finalCombinerStruct = finalCombinerStruct; - ;} + FinalCombinerStruct finalCombinerStruct; + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.ZeroOut(); + finalCombinerStruct.Init(finalRgbFunctionStruct, yyvsp[0].finalAlphaFunctionStruct, true, yyvsp[-2].finalProductStruct); + yyval.finalCombinerStruct = finalCombinerStruct; + ;} break; case 77: #line 576 "rc1.0_grammar.y" { - yyval.ival = yyvsp[-3].ival; - ;} + yyval.ival = yyvsp[-3].ival; + ;} break; case 78: #line 582 "rc1.0_grammar.y" { - FinalProductStruct finalProductStruct; - finalProductStruct.Init(yyvsp[-3].mappedRegisterStruct, yyvsp[-1].mappedRegisterStruct); - yyval.finalProductStruct = finalProductStruct; - ;} + FinalProductStruct finalProductStruct; + finalProductStruct.Init(yyvsp[-3].mappedRegisterStruct, yyvsp[-1].mappedRegisterStruct); + yyval.finalProductStruct = finalProductStruct; + ;} break; case 79: #line 590 "rc1.0_grammar.y" { - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.Init(yyvsp[-8].mappedRegisterStruct, yyvsp[-6].mappedRegisterStruct, yyvsp[-4].mappedRegisterStruct, yyvsp[-1].mappedRegisterStruct); - yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; - ;} + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.Init(yyvsp[-8].mappedRegisterStruct, yyvsp[-6].mappedRegisterStruct, yyvsp[-4].mappedRegisterStruct, yyvsp[-1].mappedRegisterStruct); + yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; + ;} break; case 80: #line 596 "rc1.0_grammar.y" { - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.Init(yyvsp[-6].mappedRegisterStruct, yyvsp[-4].mappedRegisterStruct, yyvsp[-2].mappedRegisterStruct, yyvsp[-10].mappedRegisterStruct); - yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; - ;} + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.Init(yyvsp[-6].mappedRegisterStruct, yyvsp[-4].mappedRegisterStruct, yyvsp[-2].mappedRegisterStruct, yyvsp[-10].mappedRegisterStruct); + yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; + ;} break; case 81: #line 602 "rc1.0_grammar.y" { - RegisterEnum zero; - zero.word = RCP_ZERO; - MappedRegisterStruct reg; - reg.Init(zero, GL_UNSIGNED_IDENTITY_NV); - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.Init(yyvsp[-6].mappedRegisterStruct, yyvsp[-4].mappedRegisterStruct, yyvsp[-2].mappedRegisterStruct, reg); - yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; - ;} + RegisterEnum zero; + zero.word = RCP_ZERO; + MappedRegisterStruct reg; + reg.Init(zero, GL_UNSIGNED_IDENTITY_NV); + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.Init(yyvsp[-6].mappedRegisterStruct, yyvsp[-4].mappedRegisterStruct, yyvsp[-2].mappedRegisterStruct, reg); + yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; + ;} break; case 82: #line 612 "rc1.0_grammar.y" { - RegisterEnum zero; - zero.word = RCP_ZERO; - MappedRegisterStruct reg1; - reg1.Init(zero, GL_UNSIGNED_IDENTITY_NV); - MappedRegisterStruct reg2; - reg2.Init(zero, GL_UNSIGNED_IDENTITY_NV); - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.Init(yyvsp[-3].mappedRegisterStruct, yyvsp[-1].mappedRegisterStruct, reg1, reg2); - yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; - ;} + RegisterEnum zero; + zero.word = RCP_ZERO; + MappedRegisterStruct reg1; + reg1.Init(zero, GL_UNSIGNED_IDENTITY_NV); + MappedRegisterStruct reg2; + reg2.Init(zero, GL_UNSIGNED_IDENTITY_NV); + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.Init(yyvsp[-3].mappedRegisterStruct, yyvsp[-1].mappedRegisterStruct, reg1, reg2); + yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; + ;} break; case 83: #line 624 "rc1.0_grammar.y" { - RegisterEnum zero; - zero.word = RCP_ZERO; - MappedRegisterStruct reg1; - reg1.Init(zero, GL_UNSIGNED_IDENTITY_NV); - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.Init(yyvsp[-5].mappedRegisterStruct, yyvsp[-3].mappedRegisterStruct, reg1, yyvsp[-1].mappedRegisterStruct); - yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; - ;} + RegisterEnum zero; + zero.word = RCP_ZERO; + MappedRegisterStruct reg1; + reg1.Init(zero, GL_UNSIGNED_IDENTITY_NV); + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.Init(yyvsp[-5].mappedRegisterStruct, yyvsp[-3].mappedRegisterStruct, reg1, yyvsp[-1].mappedRegisterStruct); + yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; + ;} break; case 84: #line 634 "rc1.0_grammar.y" { - RegisterEnum zero; - zero.word = RCP_ZERO; - MappedRegisterStruct reg1; - reg1.Init(zero, GL_UNSIGNED_IDENTITY_NV); - MappedRegisterStruct reg2; - reg2.Init(zero, GL_UNSIGNED_IDENTITY_NV); - MappedRegisterStruct reg3; - reg3.Init(zero, GL_UNSIGNED_IDENTITY_NV); - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.Init(reg1, reg2, reg3, yyvsp[-1].mappedRegisterStruct); - yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; - ;} + RegisterEnum zero; + zero.word = RCP_ZERO; + MappedRegisterStruct reg1; + reg1.Init(zero, GL_UNSIGNED_IDENTITY_NV); + MappedRegisterStruct reg2; + reg2.Init(zero, GL_UNSIGNED_IDENTITY_NV); + MappedRegisterStruct reg3; + reg3.Init(zero, GL_UNSIGNED_IDENTITY_NV); + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.Init(reg1, reg2, reg3, yyvsp[-1].mappedRegisterStruct); + yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; + ;} break; case 85: #line 648 "rc1.0_grammar.y" { - RegisterEnum zero; - zero.word = RCP_ZERO; - MappedRegisterStruct reg2; - reg2.Init(zero, GL_UNSIGNED_INVERT_NV); - MappedRegisterStruct reg3; - reg3.Init(zero, GL_UNSIGNED_IDENTITY_NV); - FinalRgbFunctionStruct finalRgbFunctionStruct; - finalRgbFunctionStruct.Init(yyvsp[-3].mappedRegisterStruct, reg2, reg3, yyvsp[-1].mappedRegisterStruct); - yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; - ;} + RegisterEnum zero; + zero.word = RCP_ZERO; + MappedRegisterStruct reg2; + reg2.Init(zero, GL_UNSIGNED_INVERT_NV); + MappedRegisterStruct reg3; + reg3.Init(zero, GL_UNSIGNED_IDENTITY_NV); + FinalRgbFunctionStruct finalRgbFunctionStruct; + finalRgbFunctionStruct.Init(yyvsp[-3].mappedRegisterStruct, reg2, reg3, yyvsp[-1].mappedRegisterStruct); + yyval.finalRgbFunctionStruct = finalRgbFunctionStruct; + ;} break; case 86: #line 662 "rc1.0_grammar.y" { - FinalAlphaFunctionStruct finalAlphaFunctionStruct; - finalAlphaFunctionStruct.Init(yyvsp[-1].mappedRegisterStruct); - yyval.finalAlphaFunctionStruct = finalAlphaFunctionStruct; - ;} + FinalAlphaFunctionStruct finalAlphaFunctionStruct; + finalAlphaFunctionStruct.Init(yyvsp[-1].mappedRegisterStruct); + yyval.finalAlphaFunctionStruct = finalAlphaFunctionStruct; + ;} break; case 87: #line 670 "rc1.0_grammar.y" { - yyval.registerEnum = yyvsp[0].registerEnum; - ;} + yyval.registerEnum = yyvsp[0].registerEnum; + ;} break; case 88: #line 674 "rc1.0_grammar.y" { - yyval.registerEnum = yyvsp[0].registerEnum; - ;} + yyval.registerEnum = yyvsp[0].registerEnum; + ;} break; @@ -2159,50 +2159,50 @@ yyparse () yyn = yypact[yystate]; if (YYPACT_NINF < yyn && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("syntax error, unexpected ") + 1; - yysize += yystrlen (yytname[yytype]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); - - if (yycount < 5) - { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("syntax error; also virtual memory exhausted"); - } + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } else #endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); + yyerror ("syntax error"); } @@ -2210,21 +2210,21 @@ yyparse () if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + error, discard it. */ /* Return failure if at end of input. */ if (yychar == YYEOF) { - /* Pop the error token. */ + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); YYPOPSTACK; - /* Pop the rest of the stack. */ - while (yyss < yyssp) - { - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - YYPOPSTACK; - } - YYABORT; + } + YYABORT; } YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); @@ -2242,25 +2242,25 @@ yyparse () | yyerrlab1 -- error raised explicitly by an action. | `----------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); yydestruct (yystos[yystate], yyvsp); diff --git a/RenderSystems/GL/src/nvparse/_ts1.0_lexer.cpp b/RenderSystems/GL/src/nvparse/_ts1.0_lexer.cpp index 0115460e317..2ff9e815215 100644 --- a/RenderSystems/GL/src/nvparse/_ts1.0_lexer.cpp +++ b/RenderSystems/GL/src/nvparse/_ts1.0_lexer.cpp @@ -52,15 +52,15 @@ /* yyunput is never used */ #define YY_NO_UNPUT -#else /* ! __cplusplus */ +#else /* ! __cplusplus */ #if __STDC__ #define YY_USE_PROTOS #define YY_USE_CONST -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ #ifdef __TURBOC__ #pragma warn -rch @@ -131,10 +131,10 @@ extern FILE *yyin, *yyout; * int a single C statement (which needs a semi-colon terminator). This * avoids problems with code like: * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); * * Prior to using the do-while the compiler would get upset at the * "else" because it interpreted the "if" statement as being all @@ -144,15 +144,15 @@ extern FILE *yyin, *yyout; /* Return all but the first 'n' matched characters back to the input stream. */ #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) #define unput(c) yyunput( c, yytext_ptr ) @@ -164,61 +164,61 @@ typedef unsigned int yy_size_t; struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ #define YY_BUFFER_EOF_PENDING 2 - }; + }; static YY_BUFFER_STATE yy_current_buffer = 0; @@ -232,15 +232,15 @@ static YY_BUFFER_STATE yy_current_buffer = 0; /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ +static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... @@ -268,18 +268,18 @@ static void yy_flex_free YY_PROTO(( void * )); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } #define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } #define YY_AT_BOL() (yy_current_buffer->yy_at_bol) @@ -298,11 +298,11 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; #define YY_NUM_RULES 59 #define YY_END_OF_BUFFER 60 @@ -723,7 +723,7 @@ char *yytext; #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif # include #endif @@ -734,8 +734,8 @@ char *yytext; #define YY_INPUT(buf,result,max_size) \ { \ - int c = *myin++; \ - result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \ + int c = *myin++; \ + result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \ } #define YY_ALWAYS_INTERACTIVE 1 @@ -829,21 +829,21 @@ YY_MALLOC_DECL */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - @@ -884,753 +884,753 @@ YY_MALLOC_DECL #endif #define YY_RULE_SETUP \ - YY_USER_ACTION + YY_USER_ACTION YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp = NULL, *yy_bp = NULL; - register int yy_act; + { + register yy_state_type yy_current_state; + register char *yy_cp = NULL, *yy_bp = NULL; + register int yy_act; #line 29 "ts1.0_tokens.l" #line 892 "_ts1.0_lexer.cpp" - if ( yy_init ) - { - yy_init = 0; + if ( yy_init ) + { + yy_init = 0; #ifdef YY_USER_INIT - YY_USER_INIT; + YY_USER_INIT; #endif - if ( ! yy_start ) - yy_start = 1; /* first start state */ + if ( ! yy_start ) + yy_start = 1; /* first start state */ - if ( ! yyin ) - yyin = stdin; + if ( ! yyin ) + yyin = stdin; - if ( ! yyout ) - yyout = stdout; + if ( ! yyout ) + yyout = stdout; - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); - yy_load_buffer_state(); - } + yy_load_buffer_state(); + } - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; - /* Support of yytext. */ - *yy_cp = yy_hold_char; + /* Support of yytext. */ + *yy_cp = yy_hold_char; - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; - yy_current_state = yy_start; + yy_current_state = yy_start; yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 404 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 845 ); + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 404 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 845 ); yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } - YY_DO_BEFORE_ACTION; + YY_DO_BEFORE_ACTION; -do_action: /* This label is used only to access EOF actions. */ +do_action: /* This label is used only to access EOF actions. */ - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; case 1: YY_RULE_SETUP #line 31 "ts1.0_tokens.l" { - A: - switch (yyinput()) { - case '*': goto B; - case 0: errors.set("end-of-file in comment", line_number); break; - case '\n': line_number++; - default: goto A; - } - B: - switch (yyinput()) { - case '*': goto B; - case '/': break; - case 0: errors.set("end-of-file in comment", line_number); break; - case '\n': line_number++; - default: goto A; - } - } - YY_BREAK + A: + switch (yyinput()) { + case '*': goto B; + case 0: errors.set("end-of-file in comment", line_number); break; + case '\n': line_number++; + default: goto A; + } + B: + switch (yyinput()) { + case '*': goto B; + case '/': break; + case 0: errors.set("end-of-file in comment", line_number); break; + case '\n': line_number++; + default: goto A; + } + } + YY_BREAK case 2: YY_RULE_SETUP #line 49 "ts1.0_tokens.l" { - char ch; - while ((ch = yyinput()) != '\n'); - if (ch == '\n') line_number++; - } - YY_BREAK + char ch; + while ((ch = yyinput()) != '\n'); + if (ch == '\n') line_number++; + } + YY_BREAK case 3: YY_RULE_SETUP #line 55 "ts1.0_tokens.l" { - char ch; - while ((ch = yyinput()) != '\n'); - if (ch == '\n') line_number++; - } - YY_BREAK + char ch; + while ((ch = yyinput()) != '\n'); + if (ch == '\n') line_number++; + } + YY_BREAK case 4: YY_RULE_SETUP #line 61 "ts1.0_tokens.l" return(openParen); - YY_BREAK + YY_BREAK case 5: YY_RULE_SETUP #line 62 "ts1.0_tokens.l" return(closeParen); - YY_BREAK + YY_BREAK case 6: YY_RULE_SETUP #line 63 "ts1.0_tokens.l" return(semicolon); - YY_BREAK + YY_BREAK case 7: YY_RULE_SETUP #line 64 "ts1.0_tokens.l" return(comma); - YY_BREAK + YY_BREAK case 8: YY_RULE_SETUP #line 66 "ts1.0_tokens.l" { /* eat header */ } - YY_BREAK + YY_BREAK case 9: YY_RULE_SETUP #line 68 "ts1.0_tokens.l" { - ts10_lval.fval = (float)0; - return(texVariable); - } - YY_BREAK + ts10_lval.fval = (float)0; + return(texVariable); + } + YY_BREAK case 10: YY_RULE_SETUP #line 73 "ts1.0_tokens.l" { - ts10_lval.fval = (float)1; - return(texVariable); - } - YY_BREAK + ts10_lval.fval = (float)1; + return(texVariable); + } + YY_BREAK case 11: YY_RULE_SETUP #line 78 "ts1.0_tokens.l" { - ts10_lval.fval = (float)2; - return(texVariable); - } - YY_BREAK + ts10_lval.fval = (float)2; + return(texVariable); + } + YY_BREAK case 12: YY_RULE_SETUP #line 83 "ts1.0_tokens.l" return(expandString); - YY_BREAK + YY_BREAK case 13: YY_RULE_SETUP #line 85 "ts1.0_tokens.l" { - ts10_lval.fval = (float)GL_GEQUAL; - return (gequal); - } - YY_BREAK + ts10_lval.fval = (float)GL_GEQUAL; + return (gequal); + } + YY_BREAK case 14: YY_RULE_SETUP #line 90 "ts1.0_tokens.l" { - ts10_lval.fval = (float)GL_LESS; - return(less); - } - YY_BREAK + ts10_lval.fval = (float)GL_LESS; + return(less); + } + YY_BREAK case 15: YY_RULE_SETUP #line 95 "ts1.0_tokens.l" return(nop); - YY_BREAK + YY_BREAK case 16: YY_RULE_SETUP #line 96 "ts1.0_tokens.l" return(texture_1d); - YY_BREAK + YY_BREAK case 17: YY_RULE_SETUP #line 97 "ts1.0_tokens.l" return(texture_2d); - YY_BREAK + YY_BREAK case 18: YY_RULE_SETUP #line 98 "ts1.0_tokens.l" return(texture_rectangle); - YY_BREAK + YY_BREAK case 19: YY_RULE_SETUP #line 99 "ts1.0_tokens.l" return(texture_3d); - YY_BREAK + YY_BREAK case 20: YY_RULE_SETUP #line 100 "ts1.0_tokens.l" return(texture_cube_map); - YY_BREAK + YY_BREAK case 21: YY_RULE_SETUP #line 101 "ts1.0_tokens.l" return(cull_fragment); - YY_BREAK + YY_BREAK case 22: YY_RULE_SETUP #line 102 "ts1.0_tokens.l" return(pass_through); - YY_BREAK + YY_BREAK case 23: YY_RULE_SETUP #line 103 "ts1.0_tokens.l" return(offset_2d_scale); - YY_BREAK + YY_BREAK case 24: YY_RULE_SETUP #line 104 "ts1.0_tokens.l" return(offset_2d); - YY_BREAK + YY_BREAK case 25: YY_RULE_SETUP #line 105 "ts1.0_tokens.l" return(offset_rectangle_scale); - YY_BREAK + YY_BREAK case 26: YY_RULE_SETUP #line 106 "ts1.0_tokens.l" return(offset_rectangle); - YY_BREAK + YY_BREAK case 27: YY_RULE_SETUP #line 107 "ts1.0_tokens.l" return(dependent_ar); - YY_BREAK + YY_BREAK case 28: YY_RULE_SETUP #line 108 "ts1.0_tokens.l" return(dependent_gb); - YY_BREAK + YY_BREAK case 29: YY_RULE_SETUP #line 110 "ts1.0_tokens.l" return(dot_product_2d_1of2); - YY_BREAK + YY_BREAK case 30: YY_RULE_SETUP #line 111 "ts1.0_tokens.l" return(dot_product_2d_2of2); - YY_BREAK + YY_BREAK case 31: YY_RULE_SETUP #line 113 "ts1.0_tokens.l" return(dot_product_rectangle_1of2); - YY_BREAK + YY_BREAK case 32: YY_RULE_SETUP #line 114 "ts1.0_tokens.l" return(dot_product_rectangle_2of2); - YY_BREAK + YY_BREAK case 33: YY_RULE_SETUP #line 116 "ts1.0_tokens.l" return(dot_product_depth_replace_1of2); - YY_BREAK + YY_BREAK case 34: YY_RULE_SETUP #line 117 "ts1.0_tokens.l" return(dot_product_depth_replace_2of2); - YY_BREAK + YY_BREAK case 35: YY_RULE_SETUP #line 119 "ts1.0_tokens.l" return(dot_product_3d_1of3); - YY_BREAK + YY_BREAK case 36: YY_RULE_SETUP #line 120 "ts1.0_tokens.l" return(dot_product_3d_2of3); - YY_BREAK + YY_BREAK case 37: YY_RULE_SETUP #line 121 "ts1.0_tokens.l" return(dot_product_3d_3of3); - YY_BREAK + YY_BREAK case 38: YY_RULE_SETUP #line 123 "ts1.0_tokens.l" return(dot_product_cube_map_1of3); - YY_BREAK + YY_BREAK case 39: YY_RULE_SETUP #line 124 "ts1.0_tokens.l" return(dot_product_cube_map_2of3); - YY_BREAK + YY_BREAK case 40: YY_RULE_SETUP #line 125 "ts1.0_tokens.l" return(dot_product_cube_map_3of3); - YY_BREAK + YY_BREAK case 41: YY_RULE_SETUP #line 127 "ts1.0_tokens.l" return(dot_product_reflect_cube_map_eye_from_qs_1of3); - YY_BREAK + YY_BREAK case 42: YY_RULE_SETUP #line 128 "ts1.0_tokens.l" return(dot_product_reflect_cube_map_eye_from_qs_2of3); - YY_BREAK + YY_BREAK case 43: YY_RULE_SETUP #line 129 "ts1.0_tokens.l" return(dot_product_reflect_cube_map_eye_from_qs_3of3); - YY_BREAK + YY_BREAK case 44: YY_RULE_SETUP #line 131 "ts1.0_tokens.l" return(dot_product_reflect_cube_map_const_eye_1of3); - YY_BREAK + YY_BREAK case 45: YY_RULE_SETUP #line 132 "ts1.0_tokens.l" return(dot_product_reflect_cube_map_const_eye_2of3); - YY_BREAK + YY_BREAK case 46: YY_RULE_SETUP #line 133 "ts1.0_tokens.l" return(dot_product_reflect_cube_map_const_eye_3of3); - YY_BREAK + YY_BREAK case 47: YY_RULE_SETUP #line 135 "ts1.0_tokens.l" return(dot_product_cube_map_and_reflect_cube_map_eye_from_qs_1of3); - YY_BREAK + YY_BREAK case 48: YY_RULE_SETUP #line 136 "ts1.0_tokens.l" return(dot_product_cube_map_and_reflect_cube_map_eye_from_qs_2of3); - YY_BREAK + YY_BREAK case 49: YY_RULE_SETUP #line 137 "ts1.0_tokens.l" return(dot_product_cube_map_and_reflect_cube_map_eye_from_qs_3of3); - YY_BREAK + YY_BREAK case 50: YY_RULE_SETUP #line 139 "ts1.0_tokens.l" return(dot_product_cube_map_and_reflect_cube_map_const_eye_1of3); - YY_BREAK + YY_BREAK case 51: YY_RULE_SETUP #line 140 "ts1.0_tokens.l" return(dot_product_cube_map_and_reflect_cube_map_const_eye_2of3); - YY_BREAK + YY_BREAK case 52: YY_RULE_SETUP #line 141 "ts1.0_tokens.l" return(dot_product_cube_map_and_reflect_cube_map_const_eye_3of3); - YY_BREAK + YY_BREAK case 53: YY_RULE_SETUP #line 143 "ts1.0_tokens.l" { - ts10_lval.fval = (float)atof(yytext); - return(floatValue); - } - YY_BREAK + ts10_lval.fval = (float)atof(yytext); + return(floatValue); + } + YY_BREAK case 54: YY_RULE_SETUP #line 148 "ts1.0_tokens.l" { - ts10_lval.fval = (float)atof(yytext); - return(floatValue); - } - YY_BREAK + ts10_lval.fval = (float)atof(yytext); + return(floatValue); + } + YY_BREAK case 55: YY_RULE_SETUP #line 153 "ts1.0_tokens.l" { - ts10_lval.fval = (float)atof(yytext); - return(floatValue); - } - YY_BREAK + ts10_lval.fval = (float)atof(yytext); + return(floatValue); + } + YY_BREAK case 56: YY_RULE_SETUP #line 158 "ts1.0_tokens.l" { - line_number++; - } - YY_BREAK + line_number++; + } + YY_BREAK case 57: YY_RULE_SETUP #line 162 "ts1.0_tokens.l" {} - YY_BREAK + YY_BREAK case 58: YY_RULE_SETUP #line 164 "ts1.0_tokens.l" { - errors.set("unrecognized token", line_number); - } - YY_BREAK + errors.set("unrecognized token", line_number); + } + YY_BREAK case 59: YY_RULE_SETUP #line 169 "ts1.0_tokens.l" ECHO; - YY_BREAK + YY_BREAK #line 1322 "_ts1.0_lexer.cpp" case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ #ifdef YY_USES_REJECT - YY_FATAL_ERROR( + YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); #else - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; #endif - } + } - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); - yy_current_buffer->yy_n_chars = yy_n_chars; - } + yy_current_buffer->yy_n_chars = yy_n_chars; + } - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } - else - ret_val = EOB_ACT_CONTINUE_SCAN; + else + ret_val = EOB_ACT_CONTINUE_SCAN; - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - return ret_val; - } + return ret_val; + } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 404 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; - } + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 404 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis - * next_state = yy_try_NUL_trans( current_state ); + * next_state = yy_try_NUL_trans( current_state ); */ #ifdef YY_USE_PROTOS @@ -1639,27 +1639,27 @@ static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) static yy_state_type yy_try_NUL_trans( yy_current_state ) yy_state_type yy_current_state; #endif - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 404 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 403); - - return yy_is_jam ? 0 : yy_current_state; - } + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 404 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 403); + + return yy_is_jam ? 0 : yy_current_state; + } #ifndef YY_NO_UNPUT @@ -1670,41 +1670,41 @@ static void yyunput( c, yy_bp ) int c; register char *yy_bp; #endif - { - register char *yy_cp = yy_c_buf_p; + { + register char *yy_cp = yy_c_buf_p; - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } - *--yy_cp = (char) c; + *--yy_cp = (char) c; - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ #ifdef __cplusplus @@ -1712,72 +1712,72 @@ static int yyinput() #else static int input() #endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; #ifdef __cplusplus - return yyinput(); + return yyinput(); #else - return input(); + return input(); #endif - } + } - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; - return c; - } + return c; + } #ifdef YY_USE_PROTOS @@ -1786,13 +1786,13 @@ void yyrestart( FILE *input_file ) void yyrestart( input_file ) FILE *input_file; #endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } #ifdef YY_USE_PROTOS @@ -1801,28 +1801,28 @@ void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) void yy_switch_to_buffer( new_buffer ) YY_BUFFER_STATE new_buffer; #endif - { - if ( yy_current_buffer == new_buffer ) - return; + { + if ( yy_current_buffer == new_buffer ) + return; - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } - yy_current_buffer = new_buffer; - yy_load_buffer_state(); + yy_current_buffer = new_buffer; + yy_load_buffer_state(); - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } #ifdef YY_USE_PROTOS @@ -1830,12 +1830,12 @@ void yy_load_buffer_state( void ) #else void yy_load_buffer_state() #endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } #ifdef YY_USE_PROTOS @@ -1845,28 +1845,28 @@ YY_BUFFER_STATE yy_create_buffer( file, size ) FILE *file; int size; #endif - { - YY_BUFFER_STATE b; + { + YY_BUFFER_STATE b; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_buf_size = size; + b->yy_buf_size = size; - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_is_our_buffer = 1; + b->yy_is_our_buffer = 1; - yy_init_buffer( b, file ); + yy_init_buffer( b, file ); - return b; - } + return b; + } #ifdef YY_USE_PROTOS @@ -1875,18 +1875,18 @@ void yy_delete_buffer( YY_BUFFER_STATE b ) void yy_delete_buffer( b ) YY_BUFFER_STATE b; #endif - { - if ( ! b ) - return; + { + if ( ! b ) + return; - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); - yy_flex_free( (void *) b ); - } + yy_flex_free( (void *) b ); + } @@ -1899,22 +1899,22 @@ FILE *file; #endif - { - yy_flush_buffer( b ); + { + yy_flush_buffer( b ); - b->yy_input_file = file; - b->yy_fill_buffer = 1; + b->yy_input_file = file; + b->yy_fill_buffer = 1; #if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; + b->yy_is_interactive = 1; #else #if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; + b->yy_is_interactive = 0; #else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; #endif #endif - } + } #ifdef YY_USE_PROTOS @@ -1924,27 +1924,27 @@ void yy_flush_buffer( b ) YY_BUFFER_STATE b; #endif - { - if ( ! b ) - return; + { + if ( ! b ) + return; - b->yy_n_chars = 0; + b->yy_n_chars = 0; - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - b->yy_buf_pos = &b->yy_ch_buf[0]; + b->yy_buf_pos = &b->yy_ch_buf[0]; - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } #ifndef YY_NO_SCAN_BUFFER @@ -1955,33 +1955,33 @@ YY_BUFFER_STATE yy_scan_buffer( base, size ) char *base; yy_size_t size; #endif - { - YY_BUFFER_STATE b; + { + YY_BUFFER_STATE b; - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; - yy_switch_to_buffer( b ); + yy_switch_to_buffer( b ); - return b; - } + return b; + } #endif @@ -1992,13 +1992,13 @@ YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) YY_BUFFER_STATE yy_scan_string( yy_str ) yyconst char *yy_str; #endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; - return yy_scan_bytes( yy_str, len ); - } + return yy_scan_bytes( yy_str, len ); + } #endif @@ -2010,34 +2010,34 @@ YY_BUFFER_STATE yy_scan_bytes( bytes, len ) yyconst char *bytes; int len; #endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; - return b; - } + return b; + } #endif @@ -2048,49 +2048,49 @@ static void yy_push_state( int new_state ) static void yy_push_state( new_state ) int new_state; #endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } - yy_start_stack[yy_start_stack_ptr++] = YY_START; + yy_start_stack[yy_start_stack_ptr++] = YY_START; - BEGIN(new_state); - } + BEGIN(new_state); + } #endif #ifndef YY_NO_POP_STATE static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } #endif #ifndef YY_NO_TOP_STATE static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } #endif #ifndef YY_EXIT_FAILURE @@ -2103,10 +2103,10 @@ static void yy_fatal_error( yyconst char msg[] ) static void yy_fatal_error( msg ) char msg[]; #endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } @@ -2114,16 +2114,16 @@ char msg[]; #undef yyless #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) /* Internal utility routines. */ @@ -2137,11 +2137,11 @@ char *s1; yyconst char *s2; int n; #endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } #endif #ifdef YY_NEED_STRLEN @@ -2151,13 +2151,13 @@ static int yy_flex_strlen( yyconst char *s ) static int yy_flex_strlen( s ) yyconst char *s; #endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; + { + register int n; + for ( n = 0; s[n]; ++n ) + ; - return n; - } + return n; + } #endif @@ -2167,9 +2167,9 @@ static void *yy_flex_alloc( yy_size_t size ) static void *yy_flex_alloc( size ) yy_size_t size; #endif - { - return (void *) malloc( size ); - } + { + return (void *) malloc( size ); + } #ifdef YY_USE_PROTOS static void *yy_flex_realloc( void *ptr, yy_size_t size ) @@ -2178,16 +2178,16 @@ static void *yy_flex_realloc( ptr, size ) void *ptr; yy_size_t size; #endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } #ifdef YY_USE_PROTOS static void yy_flex_free( void *ptr ) @@ -2195,16 +2195,16 @@ static void yy_flex_free( void *ptr ) static void yy_flex_free( ptr ) void *ptr; #endif - { - free( ptr ); - } + { + free( ptr ); + } #if YY_MAIN int main() - { - yylex(); - return 0; - } + { + yylex(); + return 0; + } #endif #line 169 "ts1.0_tokens.l" @@ -2214,7 +2214,7 @@ bool ts10_init_more(); bool ts10_init(char* inputString) { myin = inputString; - return ts10_init_more(); + return ts10_init_more(); } diff --git a/RenderSystems/GL/src/nvparse/_ts1.0_parser.cpp b/RenderSystems/GL/src/nvparse/_ts1.0_parser.cpp index 06a9cc1edce..192f72d7faf 100644 --- a/RenderSystems/GL/src/nvparse/_ts1.0_parser.cpp +++ b/RenderSystems/GL/src/nvparse/_ts1.0_parser.cpp @@ -198,7 +198,7 @@ int yylex ( void ); #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif # include #endif @@ -281,7 +281,7 @@ typedef union YYSTYPE { #if (! defined (yyoverflow) \ && (! defined (__cplusplus) \ - || (YYSTYPE_IS_TRIVIAL))) + || (YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc @@ -296,7 +296,7 @@ union yyalloc /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do @@ -306,13 +306,13 @@ union yyalloc # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ while (0) # endif # endif @@ -322,15 +322,15 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ while (0) #endif @@ -359,7 +359,7 @@ union yyalloc #define YYUNDEFTOK 2 #define YYMAXUTOK 304 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ @@ -693,43 +693,43 @@ static const unsigned char yystos[] = # define YYSIZE_T unsigned int #endif -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab +#define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ + YYERROR; \ + } \ while (0) -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYTERROR 1 +#define YYERRCODE 256 /* YYLLOC_DEFAULT -- Compute the default location (before the actions are run). */ @@ -758,27 +758,27 @@ while (0) # define YYFPRINTF fprintf # endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ } while (0) -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ } while (0) -# define YYDSYMPRINTF(Title, Token, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ } while (0) /*------------------------------------------------------------------. @@ -802,10 +802,10 @@ yy_stack_print (bottom, top) YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ } while (0) @@ -832,10 +832,10 @@ yy_reduce_print (yyrule) YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that @@ -851,7 +851,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -1060,7 +1060,7 @@ yyparse () to reallocate them elsewhere. */ /* The state stack. */ - short yyssa[YYINITDEPTH]; + short yyssa[YYINITDEPTH]; short *yyss = yyssa; register short *yyssp; @@ -1089,7 +1089,7 @@ yyparse () yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack @@ -1120,25 +1120,25 @@ yyparse () #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); + &yystacksize); - yyss = yyss1; - yyvs = yyvs1; + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -1146,23 +1146,23 @@ yyparse () # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; + goto yyoverflowlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@ -1172,10 +1172,10 @@ yyparse () YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1226,7 +1226,7 @@ yyparse () if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; + goto yyerrlab; yyn = -yyn; goto yyreduce; } @@ -1287,351 +1287,351 @@ yyparse () case 2: #line 74 "ts1.0_grammar.y" { - yyvsp[0].instList->Validate(); - yyvsp[0].instList->Invoke(); - delete yyvsp[0].instList; - ;} + yyvsp[0].instList->Validate(); + yyvsp[0].instList->Invoke(); + delete yyvsp[0].instList; + ;} break; case 3: #line 82 "ts1.0_grammar.y" { - *(yyvsp[-2].instList) += yyvsp[-1].inst; - delete yyvsp[-1].inst; - yyval.instList = yyvsp[-2].instList; - ;} + *(yyvsp[-2].instList) += yyvsp[-1].inst; + delete yyvsp[-1].inst; + yyval.instList = yyvsp[-2].instList; + ;} break; case 4: #line 88 "ts1.0_grammar.y" { - InstListPtr instList = new InstList; - *instList += yyvsp[-1].inst; - delete yyvsp[-1].inst; - yyval.instList = instList; - ;} + InstListPtr instList = new InstList; + *instList += yyvsp[-1].inst; + delete yyvsp[-1].inst; + yyval.instList = instList; + ;} break; case 5: #line 98 "ts1.0_grammar.y" { - yyval.variable = new MappedVariable; - yyval.variable->var = yyvsp[-1].fval; - yyval.variable->expand = true; - ;} + yyval.variable = new MappedVariable; + yyval.variable->var = yyvsp[-1].fval; + yyval.variable->expand = true; + ;} break; case 6: #line 104 "ts1.0_grammar.y" { - yyval.variable = new MappedVariable; - yyval.variable->var = yyvsp[0].fval; - yyval.variable->expand = false; - ;} + yyval.variable = new MappedVariable; + yyval.variable->var = yyvsp[0].fval; + yyval.variable->expand = false; + ;} break; case 7: #line 112 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_NOP); - ;} + yyval.inst = new Inst(TSP_NOP); + ;} break; case 8: #line 116 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_TEXTURE_1D); - ;} + yyval.inst = new Inst(TSP_TEXTURE_1D); + ;} break; case 9: #line 120 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_TEXTURE_2D); - ;} + yyval.inst = new Inst(TSP_TEXTURE_2D); + ;} break; case 10: #line 124 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_TEXTURE_RECTANGLE); - ;} + yyval.inst = new Inst(TSP_TEXTURE_RECTANGLE); + ;} break; case 11: #line 128 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_TEXTURE_3D); - ;} + yyval.inst = new Inst(TSP_TEXTURE_3D); + ;} break; case 12: #line 132 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_TEXTURE_CUBE_MAP); - ;} + yyval.inst = new Inst(TSP_TEXTURE_CUBE_MAP); + ;} break; case 13: #line 136 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_CULL_FRAGMENT, yyvsp[-7].fval, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); - ;} + yyval.inst = new Inst(TSP_CULL_FRAGMENT, yyvsp[-7].fval, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); + ;} break; case 14: #line 140 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_PASS_THROUGH); - ;} + yyval.inst = new Inst(TSP_PASS_THROUGH); + ;} break; case 15: #line 144 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_OFFSET_2D_SCALE, yyvsp[-13].fval, yyvsp[-11].fval, yyvsp[-9].fval, yyvsp[-7].fval, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); - ;} + yyval.inst = new Inst(TSP_OFFSET_2D_SCALE, yyvsp[-13].fval, yyvsp[-11].fval, yyvsp[-9].fval, yyvsp[-7].fval, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); + ;} break; case 16: #line 148 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_OFFSET_2D, yyvsp[-9].fval, yyvsp[-7].fval, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); - ;} + yyval.inst = new Inst(TSP_OFFSET_2D, yyvsp[-9].fval, yyvsp[-7].fval, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); + ;} break; case 17: #line 152 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_OFFSET_RECTANGLE_SCALE, yyvsp[-13].fval, yyvsp[-11].fval, yyvsp[-9].fval, yyvsp[-7].fval, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); - ;} + yyval.inst = new Inst(TSP_OFFSET_RECTANGLE_SCALE, yyvsp[-13].fval, yyvsp[-11].fval, yyvsp[-9].fval, yyvsp[-7].fval, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); + ;} break; case 18: #line 156 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_OFFSET_RECTANGLE, yyvsp[-9].fval, yyvsp[-7].fval, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); - ;} + yyval.inst = new Inst(TSP_OFFSET_RECTANGLE, yyvsp[-9].fval, yyvsp[-7].fval, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); + ;} break; case 19: #line 160 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DEPENDENT_AR, yyvsp[-1].fval); - ;} + yyval.inst = new Inst(TSP_DEPENDENT_AR, yyvsp[-1].fval); + ;} break; case 20: #line 164 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DEPENDENT_GB, yyvsp[-1].fval); - ;} + yyval.inst = new Inst(TSP_DEPENDENT_GB, yyvsp[-1].fval); + ;} break; case 21: #line 168 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_2D_1_OF_2, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_2D_1_OF_2, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 22: #line 173 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_2D_2_OF_2, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_2D_2_OF_2, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 23: #line 178 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_RECTANGLE_1_OF_2, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_RECTANGLE_1_OF_2, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 24: #line 183 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_RECTANGLE_2_OF_2, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_RECTANGLE_2_OF_2, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 25: #line 188 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_DEPTH_REPLACE_1_OF_2, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_DEPTH_REPLACE_1_OF_2, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 26: #line 193 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_DEPTH_REPLACE_2_OF_2, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_DEPTH_REPLACE_2_OF_2, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 27: #line 198 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_3D_1_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_3D_1_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 28: #line 203 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_3D_2_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_3D_2_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 29: #line 208 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_3D_3_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_3D_3_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 30: #line 213 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_1_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_1_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 31: #line 218 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_2_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_2_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 32: #line 223 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_3_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_3_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 33: #line 228 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 34: #line 233 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 35: #line 238 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 36: #line 243 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3, yyvsp[-7].variable, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); - delete yyvsp[-7].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3, yyvsp[-7].variable, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); + delete yyvsp[-7].variable; + ;} break; case 37: #line 248 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 38: #line 253 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 39: #line 258 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 40: #line 263 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 41: #line 268 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 42: #line 273 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3, yyvsp[-7].variable, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); - delete yyvsp[-7].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3, yyvsp[-7].variable, yyvsp[-5].fval, yyvsp[-3].fval, yyvsp[-1].fval); + delete yyvsp[-7].variable; + ;} break; case 43: #line 278 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 44: #line 283 "ts1.0_grammar.y" { - yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3, yyvsp[-1].variable); - delete yyvsp[-1].variable; - ;} + yyval.inst = new Inst(TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3, yyvsp[-1].variable); + delete yyvsp[-1].variable; + ;} break; case 45: #line 290 "ts1.0_grammar.y" { - yyval.fval = yyvsp[0].fval; - ;} + yyval.fval = yyvsp[0].fval; + ;} break; case 46: #line 294 "ts1.0_grammar.y" { - yyval.fval = yyvsp[0].fval; - ;} + yyval.fval = yyvsp[0].fval; + ;} break; @@ -1676,50 +1676,50 @@ yyparse () yyn = yypact[yystate]; if (YYPACT_NINF < yyn && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("syntax error, unexpected ") + 1; - yysize += yystrlen (yytname[yytype]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); - - if (yycount < 5) - { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("syntax error; also virtual memory exhausted"); - } + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } else #endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); + yyerror ("syntax error"); } @@ -1727,21 +1727,21 @@ yyparse () if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + error, discard it. */ /* Return failure if at end of input. */ if (yychar == YYEOF) { - /* Pop the error token. */ + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); YYPOPSTACK; - /* Pop the rest of the stack. */ - while (yyss < yyssp) - { - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - YYPOPSTACK; - } - YYABORT; + } + YYABORT; } YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); @@ -1759,25 +1759,25 @@ yyparse () | yyerrlab1 -- error raised explicitly by an action. | `----------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); yydestruct (yystos[yystate], yyvsp); diff --git a/RenderSystems/GL/src/nvparse/_vs1.0_lexer.cpp b/RenderSystems/GL/src/nvparse/_vs1.0_lexer.cpp index 7e52c918c4c..aab6c779d21 100644 --- a/RenderSystems/GL/src/nvparse/_vs1.0_lexer.cpp +++ b/RenderSystems/GL/src/nvparse/_vs1.0_lexer.cpp @@ -54,15 +54,15 @@ /* yyunput is never used */ #define YY_NO_UNPUT -#else /* ! __cplusplus */ +#else /* ! __cplusplus */ #if __STDC__ #define YY_USE_PROTOS #define YY_USE_CONST -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ #ifdef __TURBOC__ #pragma warn -rch @@ -133,10 +133,10 @@ extern FILE *yyin, *yyout; * int a single C statement (which needs a semi-colon terminator). This * avoids problems with code like: * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); * * Prior to using the do-while the compiler would get upset at the * "else" because it interpreted the "if" statement as being all @@ -146,15 +146,15 @@ extern FILE *yyin, *yyout; /* Return all but the first 'n' matched characters back to the input stream. */ #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) #define unput(c) yyunput( c, yytext_ptr ) @@ -166,61 +166,61 @@ typedef unsigned int yy_size_t; struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ #define YY_BUFFER_EOF_PENDING 2 - }; + }; static YY_BUFFER_STATE yy_current_buffer = 0; @@ -234,15 +234,15 @@ static YY_BUFFER_STATE yy_current_buffer = 0; /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ +static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... @@ -272,18 +272,18 @@ static void yy_flex_free YY_PROTO(( void * )); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } #define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } #define YY_AT_BOL() (yy_current_buffer->yy_at_bol) @@ -304,11 +304,11 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; #define YY_NUM_RULES 72 #define YY_END_OF_BUFFER 73 @@ -795,16 +795,16 @@ unsigned int FindSwizzleValue(char *swizzleText); enum ERROR_VALUES { - ERROR_NONE = 0, - ERROR_MEMORY_ALLOC, - ERROR_FILE_OPEN, - ERROR_UNSUCCESSFUL_ASSEMBLE, - ERROR_TOO_MANY_PARMS, - ERROR_DEST_WRITE, - ERROR_LIST_OPEN, - ERROR_DEST_OPEN, - ERROR_NO_ARGUMENTS, - ERROR_MACRO_OVERRUN + ERROR_NONE = 0, + ERROR_MEMORY_ALLOC, + ERROR_FILE_OPEN, + ERROR_UNSUCCESSFUL_ASSEMBLE, + ERROR_TOO_MANY_PARMS, + ERROR_DEST_WRITE, + ERROR_LIST_OPEN, + ERROR_DEST_OPEN, + ERROR_NO_ARGUMENTS, + ERROR_MACRO_OVERRUN }; @@ -815,14 +815,14 @@ unsigned int gLinesAssembled; #define YY_INPUT(buf,result,max_size) \ { \ - int c = *myin++; \ - result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \ + int c = *myin++; \ + result = (c == 0) ? YY_NULL : (buf[0] = c, 1); \ } #define SAFEDELETEARRAY(x) if ((x) != NULL) \ - delete [] (x) + delete [] (x) #define SAFEFREE(x) if ((x) != NULL) \ - free((x)) + free((x)) #define MAXREPLACESTRING 255 @@ -837,10 +837,10 @@ void MacroAddFunction(char *, unsigned int *, char **); void MacroSubFunction(char *, unsigned int *, char **); MACROFUNCTIONS gMacroFunctions[] = { - { "inc(", MacroIncFunction }, - { "dec(", MacroDecFunction }, - { "add(", MacroAddFunction }, - { "sub(", MacroSubFunction } + { "inc(", MacroIncFunction }, + { "dec(", MacroDecFunction }, + { "add(", MacroAddFunction }, + { "sub(", MacroSubFunction } }; #define NUM_MACRO_FUNCTIONS (sizeof(gMacroFunctions) / sizeof(MACROFUNCTIONS)) @@ -848,19 +848,19 @@ MACROFUNCTIONS gMacroFunctions[] = { #define MAX_INCLUDE_DEPTH 1024 typedef struct INCLUDEINFO { - char *fileName; - unsigned int lineNo; - YY_BUFFER_STATE buffer; - MACROENTRY *lastInvokeMacro; // save off in case nested macros. - MACROENTRY *lastParseMacro; // recursive macros - MACROTEXT *lastMacroLineParse; // save off for recursive lines of macros working on. - bool lastbInsideMacro; // save off for recursive macros - bool lastbInsideDefine; // save off for recursive macros/defines - bool lastbInsideInclude; - bool lastbProcessingIFDEF; // save off #define information -// FILE *fileHandle; - char *prevString; - char *nextString; + char *fileName; + unsigned int lineNo; + YY_BUFFER_STATE buffer; + MACROENTRY *lastInvokeMacro; // save off in case nested macros. + MACROENTRY *lastParseMacro; // recursive macros + MACROTEXT *lastMacroLineParse; // save off for recursive lines of macros working on. + bool lastbInsideMacro; // save off for recursive macros + bool lastbInsideDefine; // save off for recursive macros/defines + bool lastbInsideInclude; + bool lastbProcessingIFDEF; // save off #define information +// FILE *fileHandle; + char *prevString; + char *nextString; } INCLUDEINFO; INCLUDEINFO gIncludeStack[MAX_INCLUDE_DEPTH]; @@ -884,23 +884,23 @@ unsigned int gIfDefStartLine; MACROENTRY *gLastMacro; MACROENTRY *gInvokeMacro; -MACROENTRY *gTempMacro; // until all the parameters are read +MACROENTRY *gTempMacro; // until all the parameters are read MACROENTRY *FindMacro(char *macroName); MACROENTRY *FindNMacro(char *macroName, unsigned int sLen); MACROFUNCTIONPTR gMacroCallFunction; -const char *builtInMacros = "macro m3x2 reg1, reg2, reg3\n" - " dp3 %reg1.x, %reg2, %reg3\n" - " dp3 %reg1.y, %reg2, %inc(%reg3)\n" - "endm"; +const char *builtInMacros = "macro m3x2 reg1, reg2, reg3\n" + " dp3 %reg1.x, %reg2, %reg3\n" + " dp3 %reg1.y, %reg2, %inc(%reg3)\n" + "endm"; // // local prototypes // void CleanUp(); void ReplaceMacroParms(char *srcLine, char *destLine, - MACROENTRY *srcParms, MACROENTRY *invParms); + MACROENTRY *srcParms, MACROENTRY *invParms); MACROTEXT *SaveMacroText(char *srcText, MACROTEXT *lastMacroText); void FreeMacroEntry(MACROENTRY *macEntry); @@ -927,30 +927,30 @@ char gMacroLine[MAXSAVELINE+1]; #endif #endif -bool gbInsideMacro = false; // flag if we are doing a macro replace or not. +bool gbInsideMacro = false; // flag if we are doing a macro replace or not. bool gbTempInsideMacro = false; unsigned int gInvokeState = INITIAL; -MACROENTRY *gParseMacro; // which source macro entry we are using -MACROENTRY *gTempParseMacro; // temporary holder until parameters are received. -MACROTEXT *gMacroLineParse; // which line we are currently parsing inside the macro invocation +MACROENTRY *gParseMacro; // which source macro entry we are using +MACROENTRY *gTempParseMacro; // temporary holder until parameters are received. +MACROTEXT *gMacroLineParse; // which line we are currently parsing inside the macro invocation enum OPCODETYPE { - TYPE_NONE = 0, - TYPE_VERTEX_SHADER = 1, - TYPE_PIXEL_SHADER = 2 + TYPE_NONE = 0, + TYPE_VERTEX_SHADER = 1, + TYPE_PIXEL_SHADER = 2 }; typedef struct OPCODEMAP { - const char *string; // string for opcode - int tokenName; // name of the corresponding token - int numArguments; // number of arguments for opcode - float version; // minimum version supported in. - int opcodeTypeFlags; // whether opcode can be used in vertex shader or pixel shader - bool opcodeModify; // if opcode modifiers can be used - bool textureOpcode; // only outputs to the texture unit + const char *string; // string for opcode + int tokenName; // name of the corresponding token + int numArguments; // number of arguments for opcode + float version; // minimum version supported in. + int opcodeTypeFlags; // whether opcode can be used in vertex shader or pixel shader + bool opcodeModify; // if opcode modifiers can be used + bool textureOpcode; // only outputs to the texture unit } OPCODEMAP; #ifndef TRUE @@ -961,32 +961,32 @@ typedef struct OPCODEMAP #endif OPCODEMAP theOpcodes[] = { - { "add", ADD_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, - { "dp3", DP3_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, - { "dp4", DP4_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "dst", DST_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "exp", EXP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "expp", EXPP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "frc", FRC_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "lit", LIT_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "log", LOG_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "logp", LOGP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "m3x2", M3X2_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "m3x3", M3X3_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "m3x4", M3X4_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "m4x3", M4X3_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "m4x4", M4X4_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "mad", MAD_INSTR, 4, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, - { "max", MAX_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "min", MIN_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "mov", MOV_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, - { "mul", MUL_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, - { "nop", NOP_INSTR, 0, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, - { "rcp", RCP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "rsq", RSQ_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "sge", SGE_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "slt", SLT_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, - { "sub", SUB_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, + { "add", ADD_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, + { "dp3", DP3_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, + { "dp4", DP4_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "dst", DST_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "exp", EXP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "expp", EXPP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "frc", FRC_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "lit", LIT_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "log", LOG_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "logp", LOGP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "m3x2", M3X2_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "m3x3", M3X3_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "m3x4", M3X4_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "m4x3", M4X3_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "m4x4", M4X4_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "mad", MAD_INSTR, 4, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, + { "max", MAX_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "min", MIN_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "mov", MOV_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, + { "mul", MUL_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, + { "nop", NOP_INSTR, 0, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, + { "rcp", RCP_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "rsq", RSQ_INSTR, 2, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "sge", SGE_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "slt", SLT_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER, FALSE, FALSE }, + { "sub", SUB_INSTR, 3, 1.0f, TYPE_VERTEX_SHADER | TYPE_PIXEL_SHADER, TRUE, FALSE }, }; #define NUMOPCODES (sizeof(theOpcodes) / sizeof(OPCODEMAP)) @@ -1081,21 +1081,21 @@ YY_MALLOC_DECL */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - @@ -1136,1652 +1136,1652 @@ YY_MALLOC_DECL #endif #define YY_RULE_SETUP \ - if ( yyleng > 0 ) \ - yy_current_buffer->yy_at_bol = \ - (yytext[yyleng - 1] == '\n'); \ - YY_USER_ACTION + if ( yyleng > 0 ) \ + yy_current_buffer->yy_at_bol = \ + (yytext[yyleng - 1] == '\n'); \ + YY_USER_ACTION YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp = NULL, *yy_bp = NULL; - register int yy_act; + { + register yy_state_type yy_current_state; + register char *yy_cp = NULL, *yy_bp = NULL; + register int yy_act; #line 261 "vs1.0_tokens.l" #line 1147 "_vs1.0_lexer.cpp" - if ( yy_init ) - { - yy_init = 0; + if ( yy_init ) + { + yy_init = 0; #ifdef YY_USER_INIT - YY_USER_INIT; + YY_USER_INIT; #endif - if ( ! yy_start ) - yy_start = 1; /* first start state */ + if ( ! yy_start ) + yy_start = 1; /* first start state */ - if ( ! yyin ) - yyin = stdin; + if ( ! yyin ) + yyin = stdin; - if ( ! yyout ) - yyout = stdout; + if ( ! yyout ) + yyout = stdout; - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); - yy_load_buffer_state(); - } + yy_load_buffer_state(); + } - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; - /* Support of yytext. */ - *yy_cp = yy_hold_char; + /* Support of yytext. */ + *yy_cp = yy_hold_char; - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; - yy_current_state = yy_start; - yy_current_state += YY_AT_BOL(); - yy_state_ptr = yy_state_buf; - *yy_state_ptr++ = yy_current_state; + yy_current_state = yy_start; + yy_current_state += YY_AT_BOL(); + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 329 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - *yy_state_ptr++ = yy_current_state; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 767 ); + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 329 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 767 ); yy_find_action: - yy_current_state = *--yy_state_ptr; - yy_lp = yy_accept[yy_current_state]; + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; find_rule: /* we branch to this label when backing up */ - for ( ; ; ) /* until we find what rule we matched */ - { - if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) - { - yy_act = yy_acclist[yy_lp]; - { - yy_full_match = yy_cp; - break; - } - } - --yy_cp; - yy_current_state = *--yy_state_ptr; - yy_lp = yy_accept[yy_current_state]; - } + for ( ; ; ) /* until we find what rule we matched */ + { + if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[yy_lp]; + { + yy_full_match = yy_cp; + break; + } + } + --yy_cp; + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; + } - YY_DO_BEFORE_ACTION; + YY_DO_BEFORE_ACTION; -do_action: /* This label is used only to access EOF actions. */ +do_action: /* This label is used only to access EOF actions. */ - switch ( yy_act ) - { /* beginning of action switch */ + switch ( yy_act ) + { /* beginning of action switch */ case 1: YY_RULE_SETUP #line 263 "vs1.0_tokens.l" { - gbProcessingDefine = false; - gSaveLine[0] = '\0'; - strncat(gSaveLine, yytext, MAXSAVELINE); -// GenDebugLine(); - if (gbProcessingIFDEF && (gbCompareDefine != gbIFDEF)) - { - BEGIN(IFDEFBODY); - } - else - { - BEGIN(INITIAL); - } - yyless(0); + gbProcessingDefine = false; + gSaveLine[0] = '\0'; + strncat(gSaveLine, yytext, MAXSAVELINE); +// GenDebugLine(); + if (gbProcessingIFDEF && (gbCompareDefine != gbIFDEF)) + { + BEGIN(IFDEFBODY); + } + else + { + BEGIN(INITIAL); + } + yyless(0); } - YY_BREAK + YY_BREAK case 2: YY_RULE_SETUP #line 279 "vs1.0_tokens.l" { - gbProcessingDefine = false; - gSaveLine[0] = '\0'; - strncat(gSaveLine, yytext, MAXSAVELINE); -// GenDebugLine(); - if (gbProcessingIFDEF && (gbCompareDefine != gbIFDEF)) - { - BEGIN(IFDEFBODY); - } - else - { - BEGIN(INITIAL); - } - yyless(0); + gbProcessingDefine = false; + gSaveLine[0] = '\0'; + strncat(gSaveLine, yytext, MAXSAVELINE); +// GenDebugLine(); + if (gbProcessingIFDEF && (gbCompareDefine != gbIFDEF)) + { + BEGIN(IFDEFBODY); + } + else + { + BEGIN(INITIAL); + } + yyless(0); } - YY_BREAK + YY_BREAK case 3: YY_RULE_SETUP #line 295 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - vs10_lval.reg.type = TYPE_ADDRESS_REG; - vs10_lval.reg.index = atoi(&yytext[1]); - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; - return REGISTER; +// fprintf( stderr, "%s", yytext ); + vs10_lval.reg.type = TYPE_ADDRESS_REG; + vs10_lval.reg.index = atoi(&yytext[1]); + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; + return REGISTER; } - YY_BREAK + YY_BREAK case 4: YY_RULE_SETUP #line 304 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - vs10_lval.reg.type = TYPE_VERTEX_ATTRIB_REG; - vs10_lval.reg.index = atoi(&yytext[1]); - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; - return REGISTER; +// fprintf( stderr, "%s", yytext ); + vs10_lval.reg.type = TYPE_VERTEX_ATTRIB_REG; + vs10_lval.reg.index = atoi(&yytext[1]); + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; + return REGISTER; } - YY_BREAK + YY_BREAK case 5: YY_RULE_SETUP #line 313 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - vs10_lval.reg.type = TYPE_TEMPORARY_REG; - vs10_lval.reg.index = atoi(&yytext[1]); - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; - return REGISTER; +// fprintf( stderr, "%s", yytext ); + vs10_lval.reg.type = TYPE_TEMPORARY_REG; + vs10_lval.reg.index = atoi(&yytext[1]); + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; + return REGISTER; } - YY_BREAK + YY_BREAK case 6: YY_RULE_SETUP #line 322 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - vs10_lval.reg.type = TYPE_CONSTANT_MEM_REG; - vs10_lval.reg.index = atoi(&yytext[1]); - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; - return REGISTER; +// fprintf( stderr, "%s", yytext ); + vs10_lval.reg.type = TYPE_CONSTANT_MEM_REG; + vs10_lval.reg.index = atoi(&yytext[1]); + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; + return REGISTER; } - YY_BREAK + YY_BREAK case 7: YY_RULE_SETUP #line 331 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - vs10_lval.reg.type = TYPE_TEXTURE_RESULT_REG; - vs10_lval.reg.index = atoi(&yytext[2]); - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; - return REGISTER; +// fprintf( stderr, "%s", yytext ); + vs10_lval.reg.type = TYPE_TEXTURE_RESULT_REG; + vs10_lval.reg.index = atoi(&yytext[2]); + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; + return REGISTER; } - YY_BREAK + YY_BREAK case 8: YY_RULE_SETUP #line 340 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - vs10_lval.reg.type = TYPE_COLOR_RESULT_REG; - vs10_lval.reg.index = atoi(&yytext[2]); - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; - return REGISTER; +// fprintf( stderr, "%s", yytext ); + vs10_lval.reg.type = TYPE_COLOR_RESULT_REG; + vs10_lval.reg.index = atoi(&yytext[2]); + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; + return REGISTER; } - YY_BREAK + YY_BREAK case 9: YY_RULE_SETUP #line 349 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - vs10_lval.reg.type = TYPE_FOG_RESULT_REG; - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; - return REGISTER; +// fprintf( stderr, "%s", yytext ); + vs10_lval.reg.type = TYPE_FOG_RESULT_REG; + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; + return REGISTER; } - YY_BREAK + YY_BREAK case 10: YY_RULE_SETUP #line 357 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - vs10_lval.reg.type = TYPE_POSITION_RESULT_REG; - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; - return REGISTER; +// fprintf( stderr, "%s", yytext ); + vs10_lval.reg.type = TYPE_POSITION_RESULT_REG; + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; + return REGISTER; } - YY_BREAK + YY_BREAK case 11: YY_RULE_SETUP #line 365 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - vs10_lval.reg.type = TYPE_POINTS_RESULT_REG; - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; - return REGISTER; +// fprintf( stderr, "%s", yytext ); + vs10_lval.reg.type = TYPE_POINTS_RESULT_REG; + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; + return REGISTER; } - YY_BREAK + YY_BREAK case 12: YY_RULE_SETUP #line 373 "vs1.0_tokens.l" { - unsigned int offset; - + unsigned int offset; + offset = strcspn(yytext, " \t\n_"); - yyless(offset); - - OPCODEMAP *opcodeMap = FindOpcode(yytext); - if ( opcodeMap != NULL ) - { -// fprintf( stderr, "%s\t", opcodeMap->string ); - return( opcodeMap->tokenName ); - } - else - { - gTempParseMacro = FindMacro(yytext); - - if (gTempParseMacro != NULL) - { - if (gIncludeStackIndex >= MAX_INCLUDE_DEPTH ) - { - LexError("macros nested too deeply"); - exit( 1 ); - } - - if (gTempParseMacro->firstMacroLines != NULL) - { - - gTempMacro = (MACROENTRY *)malloc(sizeof(MACROENTRY)); - if (gTempMacro == NULL) - { - LexError("Out of memory allocating MACROENTRY structure.\n"); - } - else - { - - gTempMacro->next = NULL; - gTempMacro->prev = NULL; - gTempMacro->macroName = NULL; - gTempMacro->firstMacroParms = NULL; - gTempMacro->lastMacroParms = NULL; - gTempMacro->firstMacroLines = NULL; - gTempMacro->lastMacroLines = NULL; - gTempMacro->numParms = 0; - gTempMacro->nLines = 0; - - gbTempInsideMacro = true; // flag we are currently doing a macro replace. - gInvokeState = YYSTATE; - if (gTempParseMacro->numParms > 0) - { - BEGIN(MACROPARMSTART); - } - else - { - EndMacroParms(); - gbTempInsideMacro = false; // no longer waiting for macro invocation - } - - - } - } - } - else - { -// fprintf( stderr, "Opcode: \"%s\" not found\n", yytext ); - REJECT; - } - } - - //unsigned int offset; - // - //INSTRMAP *opcodeMap; - // - //offset = strcspn(yytext, " \t\n_"); - //yyless(offset); - //opcodeMap = FindInstruction(yytext); - //if (opcodeMap == NULL) - //{ - // REJECT; - //} - // - //yylval.opcodeInfo.opcodeMap = opcodeMap; - // - //return OPCODE; + yyless(offset); + + OPCODEMAP *opcodeMap = FindOpcode(yytext); + if ( opcodeMap != NULL ) + { +// fprintf( stderr, "%s\t", opcodeMap->string ); + return( opcodeMap->tokenName ); + } + else + { + gTempParseMacro = FindMacro(yytext); + + if (gTempParseMacro != NULL) + { + if (gIncludeStackIndex >= MAX_INCLUDE_DEPTH ) + { + LexError("macros nested too deeply"); + exit( 1 ); + } + + if (gTempParseMacro->firstMacroLines != NULL) + { + + gTempMacro = (MACROENTRY *)malloc(sizeof(MACROENTRY)); + if (gTempMacro == NULL) + { + LexError("Out of memory allocating MACROENTRY structure.\n"); + } + else + { + + gTempMacro->next = NULL; + gTempMacro->prev = NULL; + gTempMacro->macroName = NULL; + gTempMacro->firstMacroParms = NULL; + gTempMacro->lastMacroParms = NULL; + gTempMacro->firstMacroLines = NULL; + gTempMacro->lastMacroLines = NULL; + gTempMacro->numParms = 0; + gTempMacro->nLines = 0; + + gbTempInsideMacro = true; // flag we are currently doing a macro replace. + gInvokeState = YYSTATE; + if (gTempParseMacro->numParms > 0) + { + BEGIN(MACROPARMSTART); + } + else + { + EndMacroParms(); + gbTempInsideMacro = false; // no longer waiting for macro invocation + } + + + } + } + } + else + { +// fprintf( stderr, "Opcode: \"%s\" not found\n", yytext ); + REJECT; + } + } + + //unsigned int offset; + // + //INSTRMAP *opcodeMap; + // + //offset = strcspn(yytext, " \t\n_"); + //yyless(offset); + //opcodeMap = FindInstruction(yytext); + //if (opcodeMap == NULL) + //{ + // REJECT; + //} + // + //yylval.opcodeInfo.opcodeMap = opcodeMap; + // + //return OPCODE; } - YY_BREAK + YY_BREAK case 13: YY_RULE_SETUP #line 460 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - char *cmt = new char[yyleng+1]; - strncpy( cmt, yytext, yyleng ); - cmt[0] = '#'; - cmt[yyleng] = '\0'; - vs10_lval.comment = cmt; - return COMMENT; +// fprintf( stderr, "%s", yytext ); + char *cmt = new char[yyleng+1]; + strncpy( cmt, yytext, yyleng ); + cmt[0] = '#'; + cmt[yyleng] = '\0'; + vs10_lval.comment = cmt; + return COMMENT; } - YY_BREAK + YY_BREAK case 14: YY_RULE_SETUP #line 470 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - char *cmt = new char[yyleng+1]; - strncpy( cmt+1, yytext+1, yyleng-1 ); - cmt[0] = '#'; - cmt[1] = ' '; - cmt[yyleng] = '\0'; - vs10_lval.comment = cmt; - return COMMENT; +// fprintf( stderr, "%s", yytext ); + char *cmt = new char[yyleng+1]; + strncpy( cmt+1, yytext+1, yyleng-1 ); + cmt[0] = '#'; + cmt[1] = ' '; + cmt[yyleng] = '\0'; + vs10_lval.comment = cmt; + return COMMENT; } - YY_BREAK + YY_BREAK case 15: YY_RULE_SETUP #line 481 "vs1.0_tokens.l" { - fprintf( stderr, "COISSUE found\n" ); - yyless(yyleng-1); - //return COISSUE; + fprintf( stderr, "COISSUE found\n" ); + yyless(yyleng-1); + //return COISSUE; } - YY_BREAK + YY_BREAK case 16: YY_RULE_SETUP #line 487 "vs1.0_tokens.l" { - fprintf( stderr, "COISSUE found\n" ); - //return COISSUE; + fprintf( stderr, "COISSUE found\n" ); + //return COISSUE; } - YY_BREAK + YY_BREAK case 17: YY_RULE_SETUP #line 492 "vs1.0_tokens.l" { - gCommentStartLine = yylineno; - yyless(0); - BEGIN(EATCOMMENT); + gCommentStartLine = yylineno; + yyless(0); + BEGIN(EATCOMMENT); } - YY_BREAK + YY_BREAK case 18: YY_RULE_SETUP #line 498 "vs1.0_tokens.l" { - BEGIN(INCLUDE); + BEGIN(INCLUDE); } - YY_BREAK + YY_BREAK case 19: YY_RULE_SETUP #line 502 "vs1.0_tokens.l" -{ /* got the include file name */ +{ /* got the include file name */ -// FILE *newyyin; +// FILE *newyyin; char *newyyin; - char incFileName[1024]; - unsigned long sLen; - bool validFileName; - - if ( gIncludeStackIndex >= MAX_INCLUDE_DEPTH ) - { - LexError("Includes nested too deeply, aborting\n"); - exit( 1 ); - } - -// GenDebugLine(); -// GenListString(); - yylineno++; - gLinesAssembled++; - - validFileName = true; - // zap "" and <> - if ((yytext[0] == '"') || (yytext[0] == '<')) - { - char *endQuote; - endQuote = strchr(&yytext[1], yytext[0]); - sLen = (endQuote - yytext)-1; - if (endQuote == NULL) - { - LexError("Unable to open include file %s\n", incFileName); - BEGIN(INITIAL); - validFileName = false; - } - else - { - incFileName[0] ='\0'; - strncat(incFileName, &yytext[1], sLen); - } - } - else - { - strcpy(incFileName, yytext); - } - - if (validFileName) - { - sLen = strlen(incFileName); - if ((incFileName[sLen-1] == '"') || (incFileName[sLen-1] == '>')) - { - incFileName[sLen-1] = '\0'; - } - - - newyyin = ReadTextFile( incFileName ); -// newyyin = fopen( incFileName, "r" ); - - if ( ! newyyin ) - { - LexError("Unable to open include file %s\n", incFileName); - BEGIN(SAVELINE); - } - else - { - gIncludeStack[gIncludeStackIndex].fileName = gCurFileName; - gIncludeStack[gIncludeStackIndex].lineNo = yylineno; -// gIncludeStack[gIncludeStackIndex].fileHandle = yyin; - gIncludeStack[gIncludeStackIndex].prevString = myin; - gIncludeStack[gIncludeStackIndex].nextString = newyyin; - gIncludeStack[gIncludeStackIndex].lastInvokeMacro = gInvokeMacro; - gIncludeStack[gIncludeStackIndex].lastParseMacro = gParseMacro; - gIncludeStack[gIncludeStackIndex].lastMacroLineParse = gMacroLineParse; - gIncludeStack[gIncludeStackIndex].lastbInsideMacro = gbInsideMacro; - gIncludeStack[gIncludeStackIndex].lastbInsideInclude = gbInsideInclude; - gIncludeStack[gIncludeStackIndex].buffer = YY_CURRENT_BUFFER; - gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF; - gIncludeStackIndex++; - - gbProcessingIFDEF = false; - - gCurFileName = strdup(incFileName); -// yyin = newyyin; - myin = newyyin; - -// GenSwitchFileNames(gCurFileName); - - yylineno = 1; - - yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) ); - - gbInsideInclude = true; - - BEGIN(SAVELINE); - } - } + char incFileName[1024]; + unsigned long sLen; + bool validFileName; + + if ( gIncludeStackIndex >= MAX_INCLUDE_DEPTH ) + { + LexError("Includes nested too deeply, aborting\n"); + exit( 1 ); + } + +// GenDebugLine(); +// GenListString(); + yylineno++; + gLinesAssembled++; + + validFileName = true; + // zap "" and <> + if ((yytext[0] == '"') || (yytext[0] == '<')) + { + char *endQuote; + endQuote = strchr(&yytext[1], yytext[0]); + sLen = (endQuote - yytext)-1; + if (endQuote == NULL) + { + LexError("Unable to open include file %s\n", incFileName); + BEGIN(INITIAL); + validFileName = false; + } + else + { + incFileName[0] ='\0'; + strncat(incFileName, &yytext[1], sLen); + } + } + else + { + strcpy(incFileName, yytext); + } + + if (validFileName) + { + sLen = strlen(incFileName); + if ((incFileName[sLen-1] == '"') || (incFileName[sLen-1] == '>')) + { + incFileName[sLen-1] = '\0'; + } + + + newyyin = ReadTextFile( incFileName ); +// newyyin = fopen( incFileName, "r" ); + + if ( ! newyyin ) + { + LexError("Unable to open include file %s\n", incFileName); + BEGIN(SAVELINE); + } + else + { + gIncludeStack[gIncludeStackIndex].fileName = gCurFileName; + gIncludeStack[gIncludeStackIndex].lineNo = yylineno; +// gIncludeStack[gIncludeStackIndex].fileHandle = yyin; + gIncludeStack[gIncludeStackIndex].prevString = myin; + gIncludeStack[gIncludeStackIndex].nextString = newyyin; + gIncludeStack[gIncludeStackIndex].lastInvokeMacro = gInvokeMacro; + gIncludeStack[gIncludeStackIndex].lastParseMacro = gParseMacro; + gIncludeStack[gIncludeStackIndex].lastMacroLineParse = gMacroLineParse; + gIncludeStack[gIncludeStackIndex].lastbInsideMacro = gbInsideMacro; + gIncludeStack[gIncludeStackIndex].lastbInsideInclude = gbInsideInclude; + gIncludeStack[gIncludeStackIndex].buffer = YY_CURRENT_BUFFER; + gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF; + gIncludeStackIndex++; + + gbProcessingIFDEF = false; + + gCurFileName = strdup(incFileName); +// yyin = newyyin; + myin = newyyin; + +// GenSwitchFileNames(gCurFileName); + + yylineno = 1; + + yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) ); + + gbInsideInclude = true; + + BEGIN(SAVELINE); + } + } } - YY_BREAK + YY_BREAK case YY_STATE_EOF(EATCOMMENT): #line 597 "vs1.0_tokens.l" { - LexError("End of file reached before end of comment started on line %d.\n", gCommentStartLine); - BEGIN(INITIAL); + LexError("End of file reached before end of comment started on line %d.\n", gCommentStartLine); + BEGIN(INITIAL); } - YY_BREAK + YY_BREAK case 20: YY_RULE_SETUP #line 602 "vs1.0_tokens.l" { - char *endComment; - unsigned int keepSize; - - strcpy(gSaveLine, yytext); - endComment = strstr(yytext, "*/"); - - char *cmt; - if (endComment != NULL) - { - keepSize = (endComment - yytext+2); - yyless(keepSize); - BEGIN(INITIAL); - - if ( yytext[0] == '/' && yytext[1] == '*' ) - { - cmt = new char[yyleng]; - strncpy( cmt+3, yytext+2, yyleng-2 ); - cmt[0] = '#'; - cmt[1] = ' '; - cmt[2] = ' '; - cmt[yyleng-1] = '\0'; - } - else - { - cmt = new char[yyleng]; - strncpy( cmt+1, yytext, yyleng-2 ); - cmt[0] = '#'; - cmt[yyleng-1] = '\0'; - } - vs10_lval.comment = cmt; - return COMMENT; - } - else - { -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; - - if ( yytext[0] == '/' && yytext[1] == '*' ) - { - cmt = new char[yyleng+2]; - strncpy( cmt+3, yytext+2, yyleng-2 ); - cmt[0] = '#'; - cmt[1] = ' '; - cmt[2] = ' '; - cmt[yyleng+1] = '\0'; - } - else - { - cmt = new char[yyleng+2]; - strncpy( cmt+1, yytext, yyleng ); - cmt[0] = '#'; - cmt[yyleng+1] = '\0'; - } - vs10_lval.comment = cmt; - return COMMENT; - } + char *endComment; + unsigned int keepSize; + + strcpy(gSaveLine, yytext); + endComment = strstr(yytext, "*/"); + + char *cmt; + if (endComment != NULL) + { + keepSize = (endComment - yytext+2); + yyless(keepSize); + BEGIN(INITIAL); + + if ( yytext[0] == '/' && yytext[1] == '*' ) + { + cmt = new char[yyleng]; + strncpy( cmt+3, yytext+2, yyleng-2 ); + cmt[0] = '#'; + cmt[1] = ' '; + cmt[2] = ' '; + cmt[yyleng-1] = '\0'; + } + else + { + cmt = new char[yyleng]; + strncpy( cmt+1, yytext, yyleng-2 ); + cmt[0] = '#'; + cmt[yyleng-1] = '\0'; + } + vs10_lval.comment = cmt; + return COMMENT; + } + else + { +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; + + if ( yytext[0] == '/' && yytext[1] == '*' ) + { + cmt = new char[yyleng+2]; + strncpy( cmt+3, yytext+2, yyleng-2 ); + cmt[0] = '#'; + cmt[1] = ' '; + cmt[2] = ' '; + cmt[yyleng+1] = '\0'; + } + else + { + cmt = new char[yyleng+2]; + strncpy( cmt+1, yytext, yyleng ); + cmt[0] = '#'; + cmt[yyleng+1] = '\0'; + } + vs10_lval.comment = cmt; + return COMMENT; + } } - YY_BREAK + YY_BREAK case YY_STATE_EOF(DEFSTR): #line 663 "vs1.0_tokens.l" { - LexError("#define was incomplete before end of file\n"); - BEGIN(INITIAL); + LexError("#define was incomplete before end of file\n"); + BEGIN(INITIAL); } - YY_BREAK + YY_BREAK case YY_STATE_EOF(DEFINE): #line 668 "vs1.0_tokens.l" { - LexError("#define was incomplete before end of file\n"); - BEGIN(INITIAL); + LexError("#define was incomplete before end of file\n"); + BEGIN(INITIAL); } - YY_BREAK + YY_BREAK case YY_STATE_EOF(DEFSPACE): #line 673 "vs1.0_tokens.l" { - LexError("#define was incomplete before end of file\n"); - BEGIN(INITIAL); + LexError("#define was incomplete before end of file\n"); + BEGIN(INITIAL); } - YY_BREAK + YY_BREAK case YY_STATE_EOF(INCLUDE): #line 678 "vs1.0_tokens.l" { - LexError("#include was incomplete before end of file\n"); - BEGIN(INITIAL); + LexError("#include was incomplete before end of file\n"); + BEGIN(INITIAL); } - YY_BREAK + YY_BREAK case YY_STATE_EOF(MACROBODY): #line 683 "vs1.0_tokens.l" { - LexError("End of file reached before end of #define or endm was found, macro started on line %d.\n", gMacroStartLine); - BEGIN(INITIAL); + LexError("End of file reached before end of #define or endm was found, macro started on line %d.\n", gMacroStartLine); + BEGIN(INITIAL); } - YY_BREAK + YY_BREAK case YY_STATE_EOF(IFDEFBODY): #line 688 "vs1.0_tokens.l" { - LexError("End of file reached before #endif found, macro started on line %d.\n", gIfDefStartLine); - BEGIN(INITIAL); + LexError("End of file reached before #endif found, macro started on line %d.\n", gIfDefStartLine); + BEGIN(INITIAL); } - YY_BREAK + YY_BREAK case 21: YY_RULE_SETUP #line 693 "vs1.0_tokens.l" { - LexError("#define was incomplete before end of line\n"); - BEGIN(SAVELINE); -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; + LexError("#define was incomplete before end of line\n"); + BEGIN(SAVELINE); +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; } - YY_BREAK + YY_BREAK case 22: YY_RULE_SETUP #line 702 "vs1.0_tokens.l" { - LexError("#define was incomplete before end of line\n"); - BEGIN(SAVELINE); -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; + LexError("#define was incomplete before end of line\n"); + BEGIN(SAVELINE); +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; } - YY_BREAK + YY_BREAK case 23: YY_RULE_SETUP #line 711 "vs1.0_tokens.l" { - LexError("#define was incomplete before end of line\n"); - BEGIN(SAVELINE); -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; + LexError("#define was incomplete before end of line\n"); + BEGIN(SAVELINE); +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; } - YY_BREAK + YY_BREAK case 24: YY_RULE_SETUP #line 720 "vs1.0_tokens.l" { - if (gIfDefStackIndex >= MAX_IFDEF_DEPTH) - { - LexError("Out of stack space for #ifdef, aborting.\n"); - exit( 1 ); - } - else - { - gIfDefStack[gIfDefStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF; - gIfDefStack[gIfDefStackIndex].lastbIFDEF = gbIFDEF; - gIfDefStack[gIfDefStackIndex].lastbCompareDefine = gbCompareDefine; - gIfDefStack[gIfDefStackIndex].lastIfDefStartLine = gIfDefStartLine; - gIfDefStackIndex++; - gIfDefStartLine = yylineno; - - gbCompareDefine = true; - BEGIN(IFDEFNAME); - } + if (gIfDefStackIndex >= MAX_IFDEF_DEPTH) + { + LexError("Out of stack space for #ifdef, aborting.\n"); + exit( 1 ); + } + else + { + gIfDefStack[gIfDefStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF; + gIfDefStack[gIfDefStackIndex].lastbIFDEF = gbIFDEF; + gIfDefStack[gIfDefStackIndex].lastbCompareDefine = gbCompareDefine; + gIfDefStack[gIfDefStackIndex].lastIfDefStartLine = gIfDefStartLine; + gIfDefStackIndex++; + gIfDefStartLine = yylineno; + + gbCompareDefine = true; + BEGIN(IFDEFNAME); + } } - YY_BREAK + YY_BREAK case 25: YY_RULE_SETUP #line 740 "vs1.0_tokens.l" { - if (gIfDefStackIndex >= MAX_IFDEF_DEPTH) - { - LexError("Out of stack space for #ifdef, aborting.\n"); - exit( 1 ); - } - else - { - gIfDefStack[gIfDefStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF; - gIfDefStack[gIfDefStackIndex].lastbIFDEF = gbIFDEF; - gIfDefStack[gIfDefStackIndex].lastbCompareDefine = gbCompareDefine; - gIfDefStack[gIfDefStackIndex].lastIfDefStartLine = gIfDefStartLine; - gIfDefStackIndex++; - gIfDefStartLine = yylineno; - - gbCompareDefine = false; - BEGIN(IFDEFNAME); - } + if (gIfDefStackIndex >= MAX_IFDEF_DEPTH) + { + LexError("Out of stack space for #ifdef, aborting.\n"); + exit( 1 ); + } + else + { + gIfDefStack[gIfDefStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF; + gIfDefStack[gIfDefStackIndex].lastbIFDEF = gbIFDEF; + gIfDefStack[gIfDefStackIndex].lastbCompareDefine = gbCompareDefine; + gIfDefStack[gIfDefStackIndex].lastIfDefStartLine = gIfDefStartLine; + gIfDefStackIndex++; + gIfDefStartLine = yylineno; + + gbCompareDefine = false; + BEGIN(IFDEFNAME); + } } - YY_BREAK + YY_BREAK case 26: YY_RULE_SETUP #line 760 "vs1.0_tokens.l" { - if (!gbProcessingIFDEF) - { - LexError("Unexpected #else found at line %d, skipping.\n", yylineno); - } - else - { - gbCompareDefine = !gbCompareDefine; - BEGIN(INITIAL); - } + if (!gbProcessingIFDEF) + { + LexError("Unexpected #else found at line %d, skipping.\n", yylineno); + } + else + { + gbCompareDefine = !gbCompareDefine; + BEGIN(INITIAL); + } } - YY_BREAK + YY_BREAK case 27: YY_RULE_SETUP #line 772 "vs1.0_tokens.l" { - char *defineName; - unsigned int sLen; - - - defineName = FindAlphaNum(yytext, &sLen); - if (defineName == NULL) - { - defineName = strdup(yytext); - defineName[yyleng-1] = '\0'; // kill \n - LexWarning("Mangled name (%s) for #ifdef, assuming not defined.\n", defineName); - free(defineName); - gbIFDEF = false; - } - else - { - if (FindNMacro(defineName, sLen) != NULL) - { - gbIFDEF = true; - } - else - { - gbIFDEF = false; - } - } - - gbProcessingIFDEF = true; - if (gbIFDEF != gbCompareDefine) - { - BEGIN(IFDEFBODY); - } - else - { - BEGIN(SAVELINE); - } - -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; + char *defineName; + unsigned int sLen; + + + defineName = FindAlphaNum(yytext, &sLen); + if (defineName == NULL) + { + defineName = strdup(yytext); + defineName[yyleng-1] = '\0'; // kill \n + LexWarning("Mangled name (%s) for #ifdef, assuming not defined.\n", defineName); + free(defineName); + gbIFDEF = false; + } + else + { + if (FindNMacro(defineName, sLen) != NULL) + { + gbIFDEF = true; + } + else + { + gbIFDEF = false; + } + } + + gbProcessingIFDEF = true; + if (gbIFDEF != gbCompareDefine) + { + BEGIN(IFDEFBODY); + } + else + { + BEGIN(SAVELINE); + } + +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; } - YY_BREAK + YY_BREAK case 28: YY_RULE_SETUP #line 814 "vs1.0_tokens.l" { - if (!gbProcessingIFDEF) - { - LexError("Unexpected #endif found at line %d, skipping.\n", yylineno); - } - else - { - gIfDefStackIndex--; - gbProcessingIFDEF = gIfDefStack[gIfDefStackIndex].lastbProcessingIFDEF; - gbIFDEF = gIfDefStack[gIfDefStackIndex].lastbIFDEF; - gbCompareDefine = gIfDefStack[gIfDefStackIndex].lastbCompareDefine; - gIfDefStartLine = gIfDefStack[gIfDefStackIndex].lastIfDefStartLine; - - } - - if (YYSTATE == IFDEFBODY) - { - strncpy(gSaveLine, yytext, MAXSAVELINE); - } - - BEGIN(ENDMACRO); + if (!gbProcessingIFDEF) + { + LexError("Unexpected #endif found at line %d, skipping.\n", yylineno); + } + else + { + gIfDefStackIndex--; + gbProcessingIFDEF = gIfDefStack[gIfDefStackIndex].lastbProcessingIFDEF; + gbIFDEF = gIfDefStack[gIfDefStackIndex].lastbIFDEF; + gbCompareDefine = gIfDefStack[gIfDefStackIndex].lastbCompareDefine; + gIfDefStartLine = gIfDefStack[gIfDefStackIndex].lastIfDefStartLine; + + } + + if (YYSTATE == IFDEFBODY) + { + strncpy(gSaveLine, yytext, MAXSAVELINE); + } + + BEGIN(ENDMACRO); } - YY_BREAK + YY_BREAK case 29: YY_RULE_SETUP #line 838 "vs1.0_tokens.l" { - LexWarning("Garbage at end of #endif or endm will be ignored.\n"); + LexWarning("Garbage at end of #endif or endm will be ignored.\n"); } - YY_BREAK + YY_BREAK case 30: YY_RULE_SETUP #line 842 "vs1.0_tokens.l" { - BEGIN(SAVELINE); - return '\n'; + BEGIN(SAVELINE); + return '\n'; } - YY_BREAK + YY_BREAK case YY_STATE_EOF(ENDMACRO): #line 847 "vs1.0_tokens.l" { - BEGIN(INITIAL); + BEGIN(INITIAL); } - YY_BREAK + YY_BREAK case 31: YY_RULE_SETUP #line 851 "vs1.0_tokens.l" { - // eat line, because we are not in a TRUE #ifdef, or FALSE #ifndef - strncpy(gSaveLine, yytext, MAXSAVELINE); + // eat line, because we are not in a TRUE #ifdef, or FALSE #ifndef + strncpy(gSaveLine, yytext, MAXSAVELINE); } - YY_BREAK + YY_BREAK case 32: YY_RULE_SETUP #line 856 "vs1.0_tokens.l" { - strcat(gSaveLine, yytext); -// GenDebugLine(); -// GenListString(); - yylineno++; - gLinesAssembled++; + strcat(gSaveLine, yytext); +// GenDebugLine(); +// GenListString(); + yylineno++; + gLinesAssembled++; } - YY_BREAK + YY_BREAK case 33: YY_RULE_SETUP #line 864 "vs1.0_tokens.l" { - gbProcessingDefine = true; - gMacroStartLine = yylineno; - gCountParen = 0; - BEGIN(MACRONAME); + gbProcessingDefine = true; + gMacroStartLine = yylineno; + gCountParen = 0; + BEGIN(MACRONAME); } - YY_BREAK + YY_BREAK case 34: YY_RULE_SETUP #line 871 "vs1.0_tokens.l" { - BEGIN(SAVELINE); -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; + BEGIN(SAVELINE); +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; } - YY_BREAK + YY_BREAK case 35: YY_RULE_SETUP #line 879 "vs1.0_tokens.l" { -// unsigned int majorVersion; -// unsigned int minorVersion; -// int minorOffset; -// +// unsigned int majorVersion; +// unsigned int minorVersion; +// int minorOffset; +// // -// majorVersion = (unsigned int)(atoi(&yytext[3])); -// // skip "ps." + second '.' -// minorOffset = strcspn(&yytext[3], ".")+4; -// minorVersion = (unsigned int)(atoi(&yytext[minorOffset])); -// yylval.ival = D3DVS_VERSION(majorVersion, minorVersion); +// majorVersion = (unsigned int)(atoi(&yytext[3])); +// // skip "ps." + second '.' +// minorOffset = strcspn(&yytext[3], ".")+4; +// minorVersion = (unsigned int)(atoi(&yytext[minorOffset])); +// yylval.ival = D3DVS_VERSION(majorVersion, minorVersion); // -// fprintf( stderr, "%s", yytext ); - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; - return VERTEX_SHADER; +// fprintf( stderr, "%s", yytext ); + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; + return VERTEX_SHADER; } - YY_BREAK + YY_BREAK case 36: YY_RULE_SETUP #line 898 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - vs10_lval.ival = atoi(yytext); - return INTVAL; +// fprintf( stderr, "%s", yytext ); + vs10_lval.ival = atoi(yytext); + return INTVAL; } - YY_BREAK + YY_BREAK case 37: YY_RULE_SETUP #line 905 "vs1.0_tokens.l" { - BEGIN(MODIFIER); + BEGIN(MODIFIER); //fprintf( stderr, "." ); - return yytext[0]; + return yytext[0]; } - YY_BREAK + YY_BREAK case 38: YY_RULE_SETUP #line 911 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - BEGIN(INITIAL); +// fprintf( stderr, "%s", yytext ); + BEGIN(INITIAL); - vs10_lval.mask[0] = tolower(yytext[0]); - vs10_lval.mask[1] = tolower(yytext[1]); - vs10_lval.mask[2] = tolower(yytext[2]); - vs10_lval.mask[3] = tolower(yytext[3]); + vs10_lval.mask[0] = tolower(yytext[0]); + vs10_lval.mask[1] = tolower(yytext[1]); + vs10_lval.mask[2] = tolower(yytext[2]); + vs10_lval.mask[3] = tolower(yytext[3]); - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; - return XYZW_MODIFIER; + return XYZW_MODIFIER; #if 0 - char temp[6]; + char temp[6]; - temp[0] = '\0'; - strncat(temp, yytext, 4); - strlwr(temp); - vs10_lval.lval = FindSwizzleValue(temp); + temp[0] = '\0'; + strncat(temp, yytext, 4); + strlwr(temp); + vs10_lval.lval = FindSwizzleValue(temp); - BEGIN(INITIAL); - return SWIZZLE_MODIFIER; + BEGIN(INITIAL); + return SWIZZLE_MODIFIER; #endif } - YY_BREAK + YY_BREAK case 39: YY_RULE_SETUP #line 939 "vs1.0_tokens.l" { -// fprintf( stderr, "%s", yytext ); - BEGIN(INITIAL); +// fprintf( stderr, "%s", yytext ); + BEGIN(INITIAL); - int validLen = strspn(yytext, "xyzw"); + int validLen = strspn(yytext, "xyzw"); int i; - for ( i = 0; i < validLen; i++ ) - vs10_lval.mask[i] = tolower( yytext[i] ); - while ( i < 4 ) - { - vs10_lval.mask[i] = 0; - i++; - } + for ( i = 0; i < validLen; i++ ) + vs10_lval.mask[i] = tolower( yytext[i] ); + while ( i < 4 ) + { + vs10_lval.mask[i] = 0; + i++; + } - if ( yytext[yyleng-1] == '\n' ) - line_incr = 1; + if ( yytext[yyleng-1] == '\n' ) + line_incr = 1; - return XYZW_MODIFIER; + return XYZW_MODIFIER; #if 0 - //char temp[6]; - char *temp = new char[6]; - unsigned int registerMask; - unsigned int validLen; - - temp[0] = '\0'; - validLen = strspn(yytext, "xyzw"); - strncat(temp, yytext, validLen); - for ( int i = 0; i < validLen; i++ ) - temp[i] = tolower( temp[i] ); - registerMask = MakeRegisterMask(temp); - - if (registerMask != 0) - { - //vs10_lval.sval = temp; - vs10_lval.lval = registerMask; - BEGIN(INITIAL); - return XYZW_MODIFIER; - } - else - { - //vs10_lval.sval = temp; - vs10_lval.lval = FindSwizzleValue(temp); - BEGIN(INITIAL); - return SWIZZLE_MODIFIER; - } + //char temp[6]; + char *temp = new char[6]; + unsigned int registerMask; + unsigned int validLen; + + temp[0] = '\0'; + validLen = strspn(yytext, "xyzw"); + strncat(temp, yytext, validLen); + for ( int i = 0; i < validLen; i++ ) + temp[i] = tolower( temp[i] ); + registerMask = MakeRegisterMask(temp); + + if (registerMask != 0) + { + //vs10_lval.sval = temp; + vs10_lval.lval = registerMask; + BEGIN(INITIAL); + return XYZW_MODIFIER; + } + else + { + //vs10_lval.sval = temp; + vs10_lval.lval = FindSwizzleValue(temp); + BEGIN(INITIAL); + return SWIZZLE_MODIFIER; + } #endif } - YY_BREAK + YY_BREAK case 40: YY_RULE_SETUP #line 988 "vs1.0_tokens.l" { - BEGIN(INITIAL); - yyless(0); + BEGIN(INITIAL); + yyless(0); } - YY_BREAK + YY_BREAK case 41: YY_RULE_SETUP #line 993 "vs1.0_tokens.l" { - /* setup and save off #define/macro name */ - if (FindMacro(yytext) != NULL) - { - LexWarning("Redefinition of #define/macro %s, ignoring.\n", yytext); - if (gbProcessingDefine) - { - BEGIN(EATDEFINE); - } - else - { - BEGIN(EATMACRO); - } - } - else - { - - BEGIN(MACROPARMSTART); - // %%%%% This should be setup to use memory pools - gTempMacro = (MACROENTRY *)malloc(sizeof(MACROENTRY)); - if (gTempMacro == NULL) - { - LexError("Out of memory for macro table.\n"); - if (gbProcessingDefine) - { - BEGIN(EATDEFINE); - } - else - { - BEGIN(EATMACRO); - } - } - else - { - gTempMacro->prev = gLastMacro; - gTempMacro->next = NULL; - - gTempMacro->firstMacroParms = NULL; - gTempMacro->lastMacroParms = NULL; - gTempMacro->firstMacroLines = NULL; - gTempMacro->lastMacroLines = NULL; - gTempMacro->numParms = 0; - gTempMacro->bIsDefine = gbProcessingDefine; - gTempMacro->nLines = 0; - - if (gCurFileName != NULL) - { - gTempMacro->fileName = strdup(gCurFileName); - } - else - { - gTempMacro->fileName = NULL; - } - - gTempMacro->lineNo = yylineno; - - /* %%%%% this should be set up in memory pools. */ - gTempMacro->macroName = (char *)malloc(strlen(yytext)+1); - if (gTempMacro->macroName == NULL) - { - LexError("Out of memory for string table.\n"); - SAFEFREE(gTempMacro); - if (gbProcessingDefine) - { - BEGIN(EATDEFINE); - } - else - { - BEGIN(EATMACRO); - } - } - else - { - strcpy(gTempMacro->macroName, yytext); - } - } - } + /* setup and save off #define/macro name */ + if (FindMacro(yytext) != NULL) + { + LexWarning("Redefinition of #define/macro %s, ignoring.\n", yytext); + if (gbProcessingDefine) + { + BEGIN(EATDEFINE); + } + else + { + BEGIN(EATMACRO); + } + } + else + { + + BEGIN(MACROPARMSTART); + // %%%%% This should be setup to use memory pools + gTempMacro = (MACROENTRY *)malloc(sizeof(MACROENTRY)); + if (gTempMacro == NULL) + { + LexError("Out of memory for macro table.\n"); + if (gbProcessingDefine) + { + BEGIN(EATDEFINE); + } + else + { + BEGIN(EATMACRO); + } + } + else + { + gTempMacro->prev = gLastMacro; + gTempMacro->next = NULL; + + gTempMacro->firstMacroParms = NULL; + gTempMacro->lastMacroParms = NULL; + gTempMacro->firstMacroLines = NULL; + gTempMacro->lastMacroLines = NULL; + gTempMacro->numParms = 0; + gTempMacro->bIsDefine = gbProcessingDefine; + gTempMacro->nLines = 0; + + if (gCurFileName != NULL) + { + gTempMacro->fileName = strdup(gCurFileName); + } + else + { + gTempMacro->fileName = NULL; + } + + gTempMacro->lineNo = yylineno; + + /* %%%%% this should be set up in memory pools. */ + gTempMacro->macroName = (char *)malloc(strlen(yytext)+1); + if (gTempMacro->macroName == NULL) + { + LexError("Out of memory for string table.\n"); + SAFEFREE(gTempMacro); + if (gbProcessingDefine) + { + BEGIN(EATDEFINE); + } + else + { + BEGIN(EATMACRO); + } + } + else + { + strcpy(gTempMacro->macroName, yytext); + } + } + } } - YY_BREAK + YY_BREAK case 42: YY_RULE_SETUP #line 1072 "vs1.0_tokens.l" { - LexError("No macro name specified, skipping macro definition.\n"); - SAFEFREE(gTempMacro->fileName); - SAFEFREE(gTempMacro); - if (gbProcessingDefine) - { - BEGIN(EATDEFINE); - } - else - { - BEGIN(EATMACRO); - } - -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; + LexError("No macro name specified, skipping macro definition.\n"); + SAFEFREE(gTempMacro->fileName); + SAFEFREE(gTempMacro); + if (gbProcessingDefine) + { + BEGIN(EATDEFINE); + } + else + { + BEGIN(EATMACRO); + } + +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; } - YY_BREAK + YY_BREAK case 43: YY_RULE_SETUP #line 1091 "vs1.0_tokens.l" { - gCountParen++; + gCountParen++; } - YY_BREAK + YY_BREAK case 44: YY_RULE_SETUP #line 1095 "vs1.0_tokens.l" {} - YY_BREAK + YY_BREAK case 45: YY_RULE_SETUP #line 1097 "vs1.0_tokens.l" { - if (gbProcessingDefine && (gCountParen == 0)) - { - EndMacroParms(); - } - else - { - BEGIN(MACROPARM); - } - yyless(0); + if (gbProcessingDefine && (gCountParen == 0)) + { + EndMacroParms(); + } + else + { + BEGIN(MACROPARM); + } + yyless(0); } - YY_BREAK + YY_BREAK case 46: YY_RULE_SETUP #line 1109 "vs1.0_tokens.l" { - if ((gCountParen == 0) && gbProcessingDefine) - { - EndMacroParms(); - } + if ((gCountParen == 0) && gbProcessingDefine) + { + EndMacroParms(); + } } - YY_BREAK + YY_BREAK case 47: YY_RULE_SETUP #line 1116 "vs1.0_tokens.l" { - if (gCountParen == 0) - { - EndMacroParms(); - } + if (gCountParen == 0) + { + EndMacroParms(); + } } - YY_BREAK + YY_BREAK case 48: YY_RULE_SETUP #line 1123 "vs1.0_tokens.l" {} - YY_BREAK + YY_BREAK case YY_STATE_EOF(MACROPARM): #line 1125 "vs1.0_tokens.l" { - EndMacroParms(); -// GenDebugLine(); -// GenListString(); - yylineno++; - gLinesAssembled++; - BEGIN(INITIAL); + EndMacroParms(); +// GenDebugLine(); +// GenListString(); + yylineno++; + gLinesAssembled++; + BEGIN(INITIAL); } - YY_BREAK + YY_BREAK case 49: YY_RULE_SETUP #line 1134 "vs1.0_tokens.l" { - if (gbProcessingDefine && (gCountParen > 0)) - { - LexError("Malformed #define, skipping.\n"); - BEGIN(SAVELINE); - } - else - { - EndMacroParms(); -// GenDebugLine(); -// GenListString(); - yylineno++; - gLinesAssembled++; - if (gbProcessingDefine) - { - gbProcessingDefine = false; - BEGIN(SAVELINE); - } - } + if (gbProcessingDefine && (gCountParen > 0)) + { + LexError("Malformed #define, skipping.\n"); + BEGIN(SAVELINE); + } + else + { + EndMacroParms(); +// GenDebugLine(); +// GenListString(); + yylineno++; + gLinesAssembled++; + if (gbProcessingDefine) + { + gbProcessingDefine = false; + BEGIN(SAVELINE); + } + } } - YY_BREAK + YY_BREAK case 50: YY_RULE_SETUP #line 1156 "vs1.0_tokens.l" { - MACROTEXT *tMacro; - char *macroParmEnd; - unsigned int startOffset; - unsigned int leftParenCount; - unsigned int rightParenCount; - - // sheesh, we gotta count the parenthesis.... - macroParmEnd = yytext; - leftParenCount = 0; - rightParenCount = 0; - while (*macroParmEnd) - { - if (*macroParmEnd == ')') - { - rightParenCount++; - } - if (*macroParmEnd == '(') - { - leftParenCount++; - } - - macroParmEnd++; - } - - // if we found the last right parenthesis. - if (rightParenCount == leftParenCount+1) - { - // find if we got the last parenthesis on this line - macroParmEnd = strrchr(yytext, ')'); - yyless((macroParmEnd - yytext)); - BEGIN(MACROPARMEND); - } - - startOffset = strspn(yytext, " \t"); - - tMacro = SaveMacroText(&yytext[startOffset], gTempMacro->lastMacroParms); - if (tMacro == NULL) - { - LexError("Out of memory for string table for macro parameter(s).\n"); - FreeMacroEntry(gTempMacro); - BEGIN(EATMACRO); - } - else - { - // if first one wasn't set then set it - if (gTempMacro->firstMacroParms == NULL) - { - gTempMacro->firstMacroParms = tMacro; - } - - gTempMacro->lastMacroParms = tMacro; - - gTempMacro->numParms++; - } + MACROTEXT *tMacro; + char *macroParmEnd; + unsigned int startOffset; + unsigned int leftParenCount; + unsigned int rightParenCount; + + // sheesh, we gotta count the parenthesis.... + macroParmEnd = yytext; + leftParenCount = 0; + rightParenCount = 0; + while (*macroParmEnd) + { + if (*macroParmEnd == ')') + { + rightParenCount++; + } + if (*macroParmEnd == '(') + { + leftParenCount++; + } + + macroParmEnd++; + } + + // if we found the last right parenthesis. + if (rightParenCount == leftParenCount+1) + { + // find if we got the last parenthesis on this line + macroParmEnd = strrchr(yytext, ')'); + yyless((macroParmEnd - yytext)); + BEGIN(MACROPARMEND); + } + + startOffset = strspn(yytext, " \t"); + + tMacro = SaveMacroText(&yytext[startOffset], gTempMacro->lastMacroParms); + if (tMacro == NULL) + { + LexError("Out of memory for string table for macro parameter(s).\n"); + FreeMacroEntry(gTempMacro); + BEGIN(EATMACRO); + } + else + { + // if first one wasn't set then set it + if (gTempMacro->firstMacroParms == NULL) + { + gTempMacro->firstMacroParms = tMacro; + } + + gTempMacro->lastMacroParms = tMacro; + + gTempMacro->numParms++; + } } - YY_BREAK + YY_BREAK case 51: YY_RULE_SETUP #line 1218 "vs1.0_tokens.l" { - if (!gbProcessingDefine && !gbTempInsideMacro) - { - LexError("Malformed macro, skipping.\n"); - BEGIN(EATMACRO); - } - else - { - gCountParen--; - - // we can get multiple \n's here - while (yytext[yyleng-2] == '\n') - { - yyleng--; - } - yyless(yyleng); - - // if there isn't a \n on this line, macro starts on this line, - // not next, like in a macro definition - if (yytext[yyleng-1] != '\n') - { - EndMacroParms(); - } - else - { - if (yytext[yyleng-1] == '\n') - { - gTempMacro->lineNo++; - } - // count this line - gTempMacro->nLines++; -// GenDebugLine(); -// GenListString(); - EndMacroParms(); - if (!gbInsideMacro) - { - yylineno++; - } - - gLinesAssembled++; - } - - } + if (!gbProcessingDefine && !gbTempInsideMacro) + { + LexError("Malformed macro, skipping.\n"); + BEGIN(EATMACRO); + } + else + { + gCountParen--; + + // we can get multiple \n's here + while (yytext[yyleng-2] == '\n') + { + yyleng--; + } + yyless(yyleng); + + // if there isn't a \n on this line, macro starts on this line, + // not next, like in a macro definition + if (yytext[yyleng-1] != '\n') + { + EndMacroParms(); + } + else + { + if (yytext[yyleng-1] == '\n') + { + gTempMacro->lineNo++; + } + // count this line + gTempMacro->nLines++; +// GenDebugLine(); +// GenListString(); + EndMacroParms(); + if (!gbInsideMacro) + { + yylineno++; + } + + gLinesAssembled++; + } + + } } - YY_BREAK + YY_BREAK case 52: YY_RULE_SETUP #line 1263 "vs1.0_tokens.l" { - if (!gbProcessingDefine && !gbTempInsideMacro) - { - LexError("Malformed macro, skipping.\n"); - BEGIN(EATMACRO); - } - else - { - - // no matter what count this line - gTempMacro->nLines++; - gCountParen--; - EndMacroParms(); - if (!gbInsideMacro) - { - yylineno++; - } - - gLinesAssembled++; - } + if (!gbProcessingDefine && !gbTempInsideMacro) + { + LexError("Malformed macro, skipping.\n"); + BEGIN(EATMACRO); + } + else + { + + // no matter what count this line + gTempMacro->nLines++; + gCountParen--; + EndMacroParms(); + if (!gbInsideMacro) + { + yylineno++; + } + + gLinesAssembled++; + } } - YY_BREAK + YY_BREAK case 53: YY_RULE_SETUP #line 1285 "vs1.0_tokens.l" { - if (!gbProcessingDefine && !gbTempInsideMacro) - { - LexError("Malformed macro, skipping.\n"); - BEGIN(EATMACRO); - } - else - { - gCountParen--; - if (gCountParen == 0) - { - // no matter what count this line - gTempMacro->nLines++; - EndMacroParms(); - if (!gbInsideMacro) - { - yylineno++; - } - - gLinesAssembled++; - } - else - { - REJECT; - } - } + if (!gbProcessingDefine && !gbTempInsideMacro) + { + LexError("Malformed macro, skipping.\n"); + BEGIN(EATMACRO); + } + else + { + gCountParen--; + if (gCountParen == 0) + { + // no matter what count this line + gTempMacro->nLines++; + EndMacroParms(); + if (!gbInsideMacro) + { + yylineno++; + } + + gLinesAssembled++; + } + else + { + REJECT; + } + } } - YY_BREAK + YY_BREAK case 54: YY_RULE_SETUP #line 1313 "vs1.0_tokens.l" { - MACROTEXT *tMacro; - unsigned int copyLen; - char *endLine; - - gSaveLine[0] ='\0'; - endLine = strchr(yytext, '\\'); - copyLen = (endLine - yytext); - if (copyLen > MAXSAVELINE) - { - copyLen = MAXSAVELINE; - } - - strncat(gSaveLine, yytext, copyLen); - strcat(gSaveLine, "\n"); - tMacro = SaveMacroText(gSaveLine, gLastMacro->lastMacroLines); - if (tMacro == NULL) - { - LexError("Out of memory for string table for macro parameter(s).\n"); - BEGIN(EATDEFINE); - } - else - { - gLastMacro->nLines++; - // if first one wasn't set then set it - if (gLastMacro->firstMacroLines == NULL) - { - gLastMacro->firstMacroLines = tMacro; - } - - gLastMacro->lastMacroLines = tMacro; - } - -// GenDebugLine(); -// GenListString(); - yylineno++; - gLinesAssembled++; + MACROTEXT *tMacro; + unsigned int copyLen; + char *endLine; + + gSaveLine[0] ='\0'; + endLine = strchr(yytext, '\\'); + copyLen = (endLine - yytext); + if (copyLen > MAXSAVELINE) + { + copyLen = MAXSAVELINE; + } + + strncat(gSaveLine, yytext, copyLen); + strcat(gSaveLine, "\n"); + tMacro = SaveMacroText(gSaveLine, gLastMacro->lastMacroLines); + if (tMacro == NULL) + { + LexError("Out of memory for string table for macro parameter(s).\n"); + BEGIN(EATDEFINE); + } + else + { + gLastMacro->nLines++; + // if first one wasn't set then set it + if (gLastMacro->firstMacroLines == NULL) + { + gLastMacro->firstMacroLines = tMacro; + } + + gLastMacro->lastMacroLines = tMacro; + } + +// GenDebugLine(); +// GenListString(); + yylineno++; + gLinesAssembled++; } - YY_BREAK + YY_BREAK case 55: YY_RULE_SETUP #line 1352 "vs1.0_tokens.l" { - strncpy(gSaveLine, yytext, MAXSAVELINE); - if (gbProcessingDefine) - { - LexError("Malformed #define, skipping.\n"); - } + strncpy(gSaveLine, yytext, MAXSAVELINE); + if (gbProcessingDefine) + { + LexError("Malformed #define, skipping.\n"); + } - BEGIN(ENDMACRO); + BEGIN(ENDMACRO); } - YY_BREAK + YY_BREAK case 56: YY_RULE_SETUP #line 1363 "vs1.0_tokens.l" { - MACROTEXT *tMacro; - - // check if processing #define and only one line, if not then append \n - if (!gbProcessingDefine || (gLastMacro->nLines >= 1)) - { - gSaveLine[0] = '\0'; - strncat(gSaveLine, yytext, MAXSAVELINE); - strcat(gSaveLine, "\n"); - tMacro = SaveMacroText(gSaveLine, gLastMacro->lastMacroLines); - gLastMacro->nLines++; - } - else if (gLastMacro->numParms > 0) // check if parameters were there - { - // if so, we need the '\n' appended - gMacroLine[0] = '\0'; - strncat(gMacroLine, yytext, MAXSAVELINE); - strcat(gMacroLine, "\n"); - tMacro = SaveMacroText(gMacroLine, gLastMacro->lastMacroLines); - gLastMacro->nLines++; - } - else // straight no newline macro replace - { - tMacro = SaveMacroText(yytext, gLastMacro->lastMacroLines); - } - - if (tMacro == NULL) - { - LexError("Out of memory for string table for macro parameter(s).\n"); - BEGIN(EATMACRO); - } - else - { - // if first one wasn't set then set it - if (gLastMacro->firstMacroLines == NULL) - { - gLastMacro->firstMacroLines = tMacro; - } - - gLastMacro->lastMacroLines = tMacro; - } -} - YY_BREAK -case 57: -YY_RULE_SETUP -#line 1406 "vs1.0_tokens.l" -{ + MACROTEXT *tMacro; - MACROTEXT *tMacro; -// GenDebugLine(); -// GenListString(); - yylineno++; - gLinesAssembled++; - if (gbProcessingDefine) - { - gbProcessingDefine = false; - BEGIN(SAVELINE); - } - else - { - // this means \n by itself inside macro body - if (((yylineno-1) - gLastMacro->lineNo) != gLastMacro->nLines) - { - strcpy(gMacroLine, "\n"); - tMacro = SaveMacroText(gMacroLine, gLastMacro->lastMacroLines); - gLastMacro->nLines++; - - if (tMacro == NULL) - { - LexError("Out of memory for string table for macro parameter(s).\n"); - BEGIN(EATMACRO); - } - else - { - // if first one wasn't set then set it - if (gLastMacro->firstMacroLines == NULL) - { - gLastMacro->firstMacroLines = tMacro; - } - - gLastMacro->lastMacroLines = tMacro; - } - } - } -} - YY_BREAK -case 58: -YY_RULE_SETUP -#line 1446 "vs1.0_tokens.l" -{ - BEGIN(SAVELINE); -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; -} - YY_BREAK -case 59: -YY_RULE_SETUP -#line 1454 "vs1.0_tokens.l" + // check if processing #define and only one line, if not then append \n + if (!gbProcessingDefine || (gLastMacro->nLines >= 1)) + { + gSaveLine[0] = '\0'; + strncat(gSaveLine, yytext, MAXSAVELINE); + strcat(gSaveLine, "\n"); + tMacro = SaveMacroText(gSaveLine, gLastMacro->lastMacroLines); + gLastMacro->nLines++; + } + else if (gLastMacro->numParms > 0) // check if parameters were there + { + // if so, we need the '\n' appended + gMacroLine[0] = '\0'; + strncat(gMacroLine, yytext, MAXSAVELINE); + strcat(gMacroLine, "\n"); + tMacro = SaveMacroText(gMacroLine, gLastMacro->lastMacroLines); + gLastMacro->nLines++; + } + else // straight no newline macro replace + { + tMacro = SaveMacroText(yytext, gLastMacro->lastMacroLines); + } + + if (tMacro == NULL) + { + LexError("Out of memory for string table for macro parameter(s).\n"); + BEGIN(EATMACRO); + } + else + { + // if first one wasn't set then set it + if (gLastMacro->firstMacroLines == NULL) + { + gLastMacro->firstMacroLines = tMacro; + } + + gLastMacro->lastMacroLines = tMacro; + } +} + YY_BREAK +case 57: +YY_RULE_SETUP +#line 1406 "vs1.0_tokens.l" +{ + + MACROTEXT *tMacro; +// GenDebugLine(); +// GenListString(); + yylineno++; + gLinesAssembled++; + if (gbProcessingDefine) + { + gbProcessingDefine = false; + BEGIN(SAVELINE); + } + else + { + // this means \n by itself inside macro body + if (((yylineno-1) - gLastMacro->lineNo) != gLastMacro->nLines) + { + strcpy(gMacroLine, "\n"); + tMacro = SaveMacroText(gMacroLine, gLastMacro->lastMacroLines); + gLastMacro->nLines++; + + if (tMacro == NULL) + { + LexError("Out of memory for string table for macro parameter(s).\n"); + BEGIN(EATMACRO); + } + else + { + // if first one wasn't set then set it + if (gLastMacro->firstMacroLines == NULL) + { + gLastMacro->firstMacroLines = tMacro; + } + + gLastMacro->lastMacroLines = tMacro; + } + } + } +} + YY_BREAK +case 58: +YY_RULE_SETUP +#line 1446 "vs1.0_tokens.l" +{ + BEGIN(SAVELINE); +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; +} + YY_BREAK +case 59: +YY_RULE_SETUP +#line 1454 "vs1.0_tokens.l" { - strncpy(gSaveLine, yytext, MAXSAVELINE); -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; + strncpy(gSaveLine, yytext, MAXSAVELINE); +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; } - YY_BREAK + YY_BREAK case 60: YY_RULE_SETUP #line 1462 "vs1.0_tokens.l" { - strncpy(gSaveLine, yytext, MAXSAVELINE); -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; + strncpy(gSaveLine, yytext, MAXSAVELINE); +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; } - YY_BREAK + YY_BREAK case 61: YY_RULE_SETUP #line 1470 "vs1.0_tokens.l" { - strncpy(gSaveLine, yytext, MAXSAVELINE); -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; - BEGIN(SAVELINE); + strncpy(gSaveLine, yytext, MAXSAVELINE); +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; + BEGIN(SAVELINE); } - YY_BREAK + YY_BREAK case 62: YY_RULE_SETUP #line 1479 "vs1.0_tokens.l" { - gTempParseMacro = FindMacro(yytext); - - if (gTempParseMacro != NULL) - { - if (gIncludeStackIndex >= MAX_INCLUDE_DEPTH ) - { - LexError("macros nested too deeply"); - exit( 1 ); - } - - if (gTempParseMacro->firstMacroLines != NULL) - { - - gTempMacro = (MACROENTRY *)malloc(sizeof(MACROENTRY)); - if (gTempMacro == NULL) - { - LexError("Out of memory allocating MACROENTRY structure.\n"); - } - else - { - - gTempMacro->next = NULL; - gTempMacro->prev = NULL; - gTempMacro->macroName = NULL; - gTempMacro->firstMacroParms = NULL; - gTempMacro->lastMacroParms = NULL; - gTempMacro->firstMacroLines = NULL; - gTempMacro->lastMacroLines = NULL; - gTempMacro->numParms = 0; - gTempMacro->nLines = 0; - - gbTempInsideMacro = true; // flag we are currently doing a macro replace. - gInvokeState = YYSTATE; - if (gTempParseMacro->numParms > 0) - { - BEGIN(MACROPARMSTART); - } - else - { - EndMacroParms(); - gbTempInsideMacro = false; // no longer waiting for macro invocation - } - } - } - } - else - { - BEGIN(INITIAL); - REJECT; - } + gTempParseMacro = FindMacro(yytext); + + if (gTempParseMacro != NULL) + { + if (gIncludeStackIndex >= MAX_INCLUDE_DEPTH ) + { + LexError("macros nested too deeply"); + exit( 1 ); + } + + if (gTempParseMacro->firstMacroLines != NULL) + { + + gTempMacro = (MACROENTRY *)malloc(sizeof(MACROENTRY)); + if (gTempMacro == NULL) + { + LexError("Out of memory allocating MACROENTRY structure.\n"); + } + else + { + + gTempMacro->next = NULL; + gTempMacro->prev = NULL; + gTempMacro->macroName = NULL; + gTempMacro->firstMacroParms = NULL; + gTempMacro->lastMacroParms = NULL; + gTempMacro->firstMacroLines = NULL; + gTempMacro->lastMacroLines = NULL; + gTempMacro->numParms = 0; + gTempMacro->nLines = 0; + + gbTempInsideMacro = true; // flag we are currently doing a macro replace. + gInvokeState = YYSTATE; + if (gTempParseMacro->numParms > 0) + { + BEGIN(MACROPARMSTART); + } + else + { + EndMacroParms(); + gbTempInsideMacro = false; // no longer waiting for macro invocation + } + } + } + } + else + { + BEGIN(INITIAL); + REJECT; + } } - YY_BREAK + YY_BREAK case 63: YY_RULE_SETUP #line 1533 "vs1.0_tokens.l" { // fprintf( stderr, "%c ", yytext[0] ); - return yytext[0]; + return yytext[0]; } - YY_BREAK + YY_BREAK case 64: YY_RULE_SETUP #line 1539 "vs1.0_tokens.l" {} - YY_BREAK + YY_BREAK case 65: YY_RULE_SETUP #line 1541 "vs1.0_tokens.l" { - LexError("Didn't find label string for #define.\n"); - BEGIN(SAVELINE); -// return '\n'; + LexError("Didn't find label string for #define.\n"); + BEGIN(SAVELINE); +// return '\n'; } - YY_BREAK + YY_BREAK case 66: YY_RULE_SETUP #line 1547 "vs1.0_tokens.l" { //fprintf(stderr, "\n"); -// line_incr = 1; - line_incr++; - BEGIN(SAVELINE); - return '\n'; +// line_incr = 1; + line_incr++; + BEGIN(SAVELINE); + return '\n'; } - YY_BREAK + YY_BREAK case 67: YY_RULE_SETUP #line 1555 "vs1.0_tokens.l" { - BEGIN(INITIAL); -// fprintf( stderr, "%s", yytext ); - if (yyleng == 1) - return yytext[0]; - else - LexError("Unrecognized Token: %s\n", yytext); - return UNKNOWN_STRING; + BEGIN(INITIAL); +// fprintf( stderr, "%s", yytext ); + if (yyleng == 1) + return yytext[0]; + else + LexError("Unrecognized Token: %s\n", yytext); + return UNKNOWN_STRING; } - YY_BREAK + YY_BREAK case 68: YY_RULE_SETUP #line 1565 "vs1.0_tokens.l" { -// vs10_lval.ival = yytext[0]; - LexError("Illegal character: %d decimal.\n", yytext[0]); - return(ILLEGAL); +// vs10_lval.ival = yytext[0]; + LexError("Illegal character: %d decimal.\n", yytext[0]); + return(ILLEGAL); } - YY_BREAK + YY_BREAK case 69: YY_RULE_SETUP #line 1571 "vs1.0_tokens.l" { -// vs10_lval.ival = yytext[0]; - LexError("Illegal character: %d decimal.\n", yytext[0]); - return(ILLEGAL); +// vs10_lval.ival = yytext[0]; + LexError("Illegal character: %d decimal.\n", yytext[0]); + return(ILLEGAL); } - YY_BREAK + YY_BREAK case 70: YY_RULE_SETUP #line 1577 "vs1.0_tokens.l" { - return yytext[0]; + return yytext[0]; } - YY_BREAK + YY_BREAK case 71: YY_RULE_SETUP #line 1581 "vs1.0_tokens.l" { - BEGIN(EATSTRING); - yyless(0); + BEGIN(EATSTRING); + yyless(0); } - YY_BREAK + YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(SKIPLINE): case YY_STATE_EOF(EATSTRING): @@ -2795,422 +2795,422 @@ case YY_STATE_EOF(IFDEFNAME): case YY_STATE_EOF(MACROPARMEND): #line 1586 "vs1.0_tokens.l" { - bool wasInMacro; - bool oneLiner; - char *macroText; - - wasInMacro = gbInsideMacro; - oneLiner = false; - - - // if we are inside the macro then do next line until their are no more - if (gbInsideMacro) - { - oneLiner = (gParseMacro->nLines == 0); - - // free the temporary parameter replaced line we were working on. - // get next line in macro text, if any - gMacroLineParse = gMacroLineParse->next; - // more lines to parse? - if (gMacroLineParse != NULL) - { - macroText = gMacroLine; - // if no replacement text, just use source line - if (gParseMacro->firstMacroParms == NULL) - { - macroText = gMacroLineParse->macroText; - } - else - { - // replace the macro parameters - ReplaceMacroParms(gMacroLineParse->macroText, gMacroLine, gParseMacro, gInvokeMacro); - } - -// if (gExpandMacros) -// { -// strcpy(gSaveLine, macroText); -// } - - BEGIN(INITIAL); - // and lex it. - yy_scan_string(macroText); - } - else - { - // no more lines in this macro, so free the working macro - SAFEFREE(gInvokeMacro); - // shut off flag for inside a macro replacement state. - gbInsideMacro = false; - } - } - - if (gbProcessingIFDEF && !wasInMacro) - { - LexError("End of file reached before #endif found, macro started on line %d.\n", gIfDefStartLine); - } - - if (!gbInsideMacro) - { - if ( gIncludeStackIndex == 0 ) - { - if (!gbProcessingBuiltIn) - CleanUp(); - return 0; -// return TOKEN_EOF; - } - else - { - yy_delete_buffer( YY_CURRENT_BUFFER ); - SAFEFREE(gCurFileName); -// SAFEDELETE(myin); -// SAFECLOSE(yyin); - } - - gIncludeStackIndex--; - SAFEDELETEARRAY( gIncludeStack[gIncludeStackIndex].nextString ); - yy_switch_to_buffer(gIncludeStack[gIncludeStackIndex].buffer ); - gCurFileName = gIncludeStack[gIncludeStackIndex].fileName; -// yyin = gIncludeStack[gIncludeStackIndex].fileHandle; - myin = gIncludeStack[gIncludeStackIndex].prevString; - yylineno = gIncludeStack[gIncludeStackIndex].lineNo; - gInvokeMacro = gIncludeStack[gIncludeStackIndex].lastInvokeMacro; - gParseMacro = gIncludeStack[gIncludeStackIndex].lastParseMacro; - gMacroLineParse = gIncludeStack[gIncludeStackIndex].lastMacroLineParse; - gbInsideInclude = gIncludeStack[gIncludeStackIndex].lastbInsideInclude; - gbInsideMacro = gIncludeStack[gIncludeStackIndex].lastbInsideMacro; - gbProcessingIFDEF = gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF; - - if (!gbInsideMacro && !oneLiner) - { -// GenSwitchFileNames(gCurFileName); - BEGIN(SAVELINE); - } - else - { - BEGIN(INITIAL); - } - - // gSaveLine was last line saved, before macro invocation - if (wasInMacro && !gbInsideMacro && !oneLiner) - { -// GenDebugLine(); -// GenListString(); - gLinesAssembled++; - yylineno++; - } - - } + bool wasInMacro; + bool oneLiner; + char *macroText; + + wasInMacro = gbInsideMacro; + oneLiner = false; + + + // if we are inside the macro then do next line until their are no more + if (gbInsideMacro) + { + oneLiner = (gParseMacro->nLines == 0); + + // free the temporary parameter replaced line we were working on. + // get next line in macro text, if any + gMacroLineParse = gMacroLineParse->next; + // more lines to parse? + if (gMacroLineParse != NULL) + { + macroText = gMacroLine; + // if no replacement text, just use source line + if (gParseMacro->firstMacroParms == NULL) + { + macroText = gMacroLineParse->macroText; + } + else + { + // replace the macro parameters + ReplaceMacroParms(gMacroLineParse->macroText, gMacroLine, gParseMacro, gInvokeMacro); + } + +// if (gExpandMacros) +// { +// strcpy(gSaveLine, macroText); +// } + + BEGIN(INITIAL); + // and lex it. + yy_scan_string(macroText); + } + else + { + // no more lines in this macro, so free the working macro + SAFEFREE(gInvokeMacro); + // shut off flag for inside a macro replacement state. + gbInsideMacro = false; + } + } + + if (gbProcessingIFDEF && !wasInMacro) + { + LexError("End of file reached before #endif found, macro started on line %d.\n", gIfDefStartLine); + } + + if (!gbInsideMacro) + { + if ( gIncludeStackIndex == 0 ) + { + if (!gbProcessingBuiltIn) + CleanUp(); + return 0; +// return TOKEN_EOF; + } + else + { + yy_delete_buffer( YY_CURRENT_BUFFER ); + SAFEFREE(gCurFileName); +// SAFEDELETE(myin); +// SAFECLOSE(yyin); + } + + gIncludeStackIndex--; + SAFEDELETEARRAY( gIncludeStack[gIncludeStackIndex].nextString ); + yy_switch_to_buffer(gIncludeStack[gIncludeStackIndex].buffer ); + gCurFileName = gIncludeStack[gIncludeStackIndex].fileName; +// yyin = gIncludeStack[gIncludeStackIndex].fileHandle; + myin = gIncludeStack[gIncludeStackIndex].prevString; + yylineno = gIncludeStack[gIncludeStackIndex].lineNo; + gInvokeMacro = gIncludeStack[gIncludeStackIndex].lastInvokeMacro; + gParseMacro = gIncludeStack[gIncludeStackIndex].lastParseMacro; + gMacroLineParse = gIncludeStack[gIncludeStackIndex].lastMacroLineParse; + gbInsideInclude = gIncludeStack[gIncludeStackIndex].lastbInsideInclude; + gbInsideMacro = gIncludeStack[gIncludeStackIndex].lastbInsideMacro; + gbProcessingIFDEF = gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF; + + if (!gbInsideMacro && !oneLiner) + { +// GenSwitchFileNames(gCurFileName); + BEGIN(SAVELINE); + } + else + { + BEGIN(INITIAL); + } + + // gSaveLine was last line saved, before macro invocation + if (wasInMacro && !gbInsideMacro && !oneLiner) + { +// GenDebugLine(); +// GenListString(); + gLinesAssembled++; + yylineno++; + } + + } } - YY_BREAK + YY_BREAK case 72: YY_RULE_SETUP #line 1695 "vs1.0_tokens.l" ECHO; - YY_BREAK + YY_BREAK #line 2908 "_vs1.0_lexer.cpp" - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ #ifdef YY_USES_REJECT - YY_FATAL_ERROR( + YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); #else - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; #endif - } + } - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); - yy_current_buffer->yy_n_chars = yy_n_chars; - } + yy_current_buffer->yy_n_chars = yy_n_chars; + } - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } - else - ret_val = EOB_ACT_CONTINUE_SCAN; + else + ret_val = EOB_ACT_CONTINUE_SCAN; - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - return ret_val; - } + return ret_val; + } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - yy_current_state += YY_AT_BOL(); - yy_state_ptr = yy_state_buf; - *yy_state_ptr++ = yy_current_state; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 4); - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 329 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - *yy_state_ptr++ = yy_current_state; - } - - return yy_current_state; - } + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + yy_current_state += YY_AT_BOL(); + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 4); + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 329 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + } + + return yy_current_state; + } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis - * next_state = yy_try_NUL_trans( current_state ); + * next_state = yy_try_NUL_trans( current_state ); */ #ifdef YY_USE_PROTOS @@ -3219,23 +3219,23 @@ static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) static yy_state_type yy_try_NUL_trans( yy_current_state ) yy_state_type yy_current_state; #endif - { - register int yy_is_jam; + { + register int yy_is_jam; - register YY_CHAR yy_c = 4; - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 329 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 328); - if ( ! yy_is_jam ) - *yy_state_ptr++ = yy_current_state; + register YY_CHAR yy_c = 4; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 329 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 328); + if ( ! yy_is_jam ) + *yy_state_ptr++ = yy_current_state; - return yy_is_jam ? 0 : yy_current_state; - } + return yy_is_jam ? 0 : yy_current_state; + } #ifndef YY_NO_UNPUT @@ -3246,41 +3246,41 @@ static void yyunput( c, yy_bp ) int c; register char *yy_bp; #endif - { - register char *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } - *--yy_cp = (char) c; + *--yy_cp = (char) c; - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ #ifdef __cplusplus @@ -3288,73 +3288,73 @@ static int yyinput() #else static int input() #endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; #ifdef __cplusplus - return yyinput(); + return yyinput(); #else - return input(); + return input(); #endif - } + } - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; - yy_current_buffer->yy_at_bol = (c == '\n'); + yy_current_buffer->yy_at_bol = (c == '\n'); - return c; - } + return c; + } #ifdef YY_USE_PROTOS @@ -3363,13 +3363,13 @@ void yyrestart( FILE *input_file ) void yyrestart( input_file ) FILE *input_file; #endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } #ifdef YY_USE_PROTOS @@ -3378,28 +3378,28 @@ void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) void yy_switch_to_buffer( new_buffer ) YY_BUFFER_STATE new_buffer; #endif - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } #ifdef YY_USE_PROTOS @@ -3407,12 +3407,12 @@ void yy_load_buffer_state( void ) #else void yy_load_buffer_state() #endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } #ifdef YY_USE_PROTOS @@ -3422,28 +3422,28 @@ YY_BUFFER_STATE yy_create_buffer( file, size ) FILE *file; int size; #endif - { - YY_BUFFER_STATE b; + { + YY_BUFFER_STATE b; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_buf_size = size; + b->yy_buf_size = size; - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_is_our_buffer = 1; + b->yy_is_our_buffer = 1; - yy_init_buffer( b, file ); + yy_init_buffer( b, file ); - return b; - } + return b; + } #ifdef YY_USE_PROTOS @@ -3452,18 +3452,18 @@ void yy_delete_buffer( YY_BUFFER_STATE b ) void yy_delete_buffer( b ) YY_BUFFER_STATE b; #endif - { - if ( ! b ) - return; + { + if ( ! b ) + return; - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); - yy_flex_free( (void *) b ); - } + yy_flex_free( (void *) b ); + } @@ -3476,22 +3476,22 @@ FILE *file; #endif - { - yy_flush_buffer( b ); + { + yy_flush_buffer( b ); - b->yy_input_file = file; - b->yy_fill_buffer = 1; + b->yy_input_file = file; + b->yy_fill_buffer = 1; #if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; + b->yy_is_interactive = 1; #else #if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; + b->yy_is_interactive = 0; #else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; #endif #endif - } + } #ifdef YY_USE_PROTOS @@ -3501,27 +3501,27 @@ void yy_flush_buffer( b ) YY_BUFFER_STATE b; #endif - { - if ( ! b ) - return; + { + if ( ! b ) + return; - b->yy_n_chars = 0; + b->yy_n_chars = 0; - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - b->yy_buf_pos = &b->yy_ch_buf[0]; + b->yy_buf_pos = &b->yy_ch_buf[0]; - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } #ifndef YY_NO_SCAN_BUFFER @@ -3532,33 +3532,33 @@ YY_BUFFER_STATE yy_scan_buffer( base, size ) char *base; yy_size_t size; #endif - { - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; - } + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } #endif @@ -3569,13 +3569,13 @@ YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) YY_BUFFER_STATE yy_scan_string( yy_str ) yyconst char *yy_str; #endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; - return yy_scan_bytes( yy_str, len ); - } + return yy_scan_bytes( yy_str, len ); + } #endif @@ -3587,34 +3587,34 @@ YY_BUFFER_STATE yy_scan_bytes( bytes, len ) yyconst char *bytes; int len; #endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; - - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; - } + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } #endif @@ -3625,49 +3625,49 @@ static void yy_push_state( int new_state ) static void yy_push_state( new_state ) int new_state; #endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } - yy_start_stack[yy_start_stack_ptr++] = YY_START; + yy_start_stack[yy_start_stack_ptr++] = YY_START; - BEGIN(new_state); - } + BEGIN(new_state); + } #endif #ifndef YY_NO_POP_STATE static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } #endif #ifndef YY_NO_TOP_STATE static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } #endif #ifndef YY_EXIT_FAILURE @@ -3680,10 +3680,10 @@ static void yy_fatal_error( yyconst char msg[] ) static void yy_fatal_error( msg ) char msg[]; #endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } @@ -3691,16 +3691,16 @@ char msg[]; #undef yyless #define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) /* Internal utility routines. */ @@ -3714,11 +3714,11 @@ char *s1; yyconst char *s2; int n; #endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } #endif #ifdef YY_NEED_STRLEN @@ -3728,13 +3728,13 @@ static int yy_flex_strlen( yyconst char *s ) static int yy_flex_strlen( s ) yyconst char *s; #endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; + { + register int n; + for ( n = 0; s[n]; ++n ) + ; - return n; - } + return n; + } #endif @@ -3744,9 +3744,9 @@ static void *yy_flex_alloc( yy_size_t size ) static void *yy_flex_alloc( size ) yy_size_t size; #endif - { - return (void *) malloc( size ); - } + { + return (void *) malloc( size ); + } // This function is never referenced under these specific conditions // Removes a warning @@ -3758,16 +3758,16 @@ static void *yy_flex_realloc( ptr, size ) void *ptr; yy_size_t size; #endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } #endif #ifdef YY_USE_PROTOS @@ -3776,1200 +3776,1200 @@ static void yy_flex_free( void *ptr ) static void yy_flex_free( ptr ) void *ptr; #endif - { - free( ptr ); - } + { + free( ptr ); + } #if YY_MAIN int main() - { - yylex(); - return 0; - } + { + yylex(); + return 0; + } #endif #line 1695 "vs1.0_tokens.l" //===================================================================== -// Function: FindNMacro -// Description: Look through macros and see if it had been predefined -// Parameters: findName = name to lookup -// sLen = # characters valid in source (findName) -// Returns: MACROENTRY * = pointer to macro entry if found +// Function: FindNMacro +// Description: Look through macros and see if it had been predefined +// Parameters: findName = name to lookup +// sLen = # characters valid in source (findName) +// Returns: MACROENTRY * = pointer to macro entry if found //===================================================================== MACROENTRY *FindNMacro(char *findName, unsigned int sLen) { - MACROENTRY *curEntry; - - curEntry = gLastMacro; - while (curEntry != NULL) - { - if (strlen(curEntry->macroName) == sLen) - { - if (!strncmp(curEntry->macroName, findName, sLen)) - { - break; - } - } - - curEntry = curEntry->prev; - } - - return curEntry; - + MACROENTRY *curEntry; + + curEntry = gLastMacro; + while (curEntry != NULL) + { + if (strlen(curEntry->macroName) == sLen) + { + if (!strncmp(curEntry->macroName, findName, sLen)) + { + break; + } + } + + curEntry = curEntry->prev; + } + + return curEntry; + } //===================================================================== -// Function: FindMacro -// Description: Look through macros and see if it had been predefined -// Parameters: findName = name to lookup -// Returns: MACROENTRY * = pointer to macro entry if found +// Function: FindMacro +// Description: Look through macros and see if it had been predefined +// Parameters: findName = name to lookup +// Returns: MACROENTRY * = pointer to macro entry if found //===================================================================== MACROENTRY *FindMacro(char *findName) { - MACROENTRY *curEntry; + MACROENTRY *curEntry; - curEntry = gLastMacro; - while (curEntry != NULL) - { - if (!strcmp(curEntry->macroName, findName)) - { - break; - } + curEntry = gLastMacro; + while (curEntry != NULL) + { + if (!strcmp(curEntry->macroName, findName)) + { + break; + } - curEntry = curEntry->prev; - } + curEntry = curEntry->prev; + } - return curEntry; - + return curEntry; + } //===================================================================== -// Function: CleanUp -// Description: Clean up the #define strings -// Parameters: . -// Returns: . +// Function: CleanUp +// Description: Clean up the #define strings +// Parameters: . +// Returns: . //===================================================================== void CleanUp() { - void *tPtr; + void *tPtr; - // free up the macros that were alloced - while (gLastMacro != NULL) - { + // free up the macros that were alloced + while (gLastMacro != NULL) + { - FreeMacroEntry(gLastMacro); + FreeMacroEntry(gLastMacro); - tPtr = gLastMacro; - gLastMacro = gLastMacro->prev; - SAFEFREE(tPtr); - } + tPtr = gLastMacro; + gLastMacro = gLastMacro->prev; + SAFEFREE(tPtr); + } } //===================================================================== -// Function: FreeMacroEntry -// Description: Frees up the macro entry data, (parms, lines of text) -// Parameters: macEntry = pointer to the MACROENTRY structure -// Returns: . +// Function: FreeMacroEntry +// Description: Frees up the macro entry data, (parms, lines of text) +// Parameters: macEntry = pointer to the MACROENTRY structure +// Returns: . //===================================================================== void FreeMacroEntry(MACROENTRY *macEntry) { - MACROTEXT *tText; - MACROTEXT *tNext; - - SAFEFREE(macEntry->macroName); - SAFEFREE(macEntry->fileName); - // free the macro lines that were alloced - tText = macEntry->lastMacroLines; - while (tText != NULL) - { - tNext = tText->prev; - SAFEFREE(tText); - tText = tNext; - } - - // free the text of the macro parms that were alloced - tText = macEntry->lastMacroParms; - while (tText != NULL) - { - tNext = tText->prev; - SAFEFREE(tText); - tText = tNext; - } + MACROTEXT *tText; + MACROTEXT *tNext; + + SAFEFREE(macEntry->macroName); + SAFEFREE(macEntry->fileName); + // free the macro lines that were alloced + tText = macEntry->lastMacroLines; + while (tText != NULL) + { + tNext = tText->prev; + SAFEFREE(tText); + tText = tNext; + } + + // free the text of the macro parms that were alloced + tText = macEntry->lastMacroParms; + while (tText != NULL) + { + tNext = tText->prev; + SAFEFREE(tText); + tText = tNext; + } } //===================================================================== -// Function: CheckMacroFunctions -// Description: Find if this text is a builtin macro function -// Parameters: lookString = non-null terminated string of possible -// and if found set global macro function call -// Returns: . +// Function: CheckMacroFunctions +// Description: Find if this text is a builtin macro function +// Parameters: lookString = non-null terminated string of possible +// and if found set global macro function call +// Returns: . //===================================================================== void CheckMacroFunctions(char *lookString, unsigned int *recognizedLen, char **invString) { - unsigned int i; - unsigned int sLen; - - for (i=0; i< NUM_MACRO_FUNCTIONS; i++) - { - sLen = strlen(gMacroFunctions[i].name); - if (!strncmp(gMacroFunctions[i].name, lookString, sLen)) - { - gMacroCallFunction = gMacroFunctions[i].function; - *recognizedLen = sLen; - *invString = NULL; - return; - } - } + unsigned int i; + unsigned int sLen; + + for (i=0; i< NUM_MACRO_FUNCTIONS; i++) + { + sLen = strlen(gMacroFunctions[i].name); + if (!strncmp(gMacroFunctions[i].name, lookString, sLen)) + { + gMacroCallFunction = gMacroFunctions[i].function; + *recognizedLen = sLen; + *invString = NULL; + return; + } + } } //===================================================================== -// Function: FindAlphaNum -// Description: Find a whole alpha numeric string, ie consists of -// [A-Za-z0-9_] only -// Parameters: srcStr = source string to search through. -// sLen = unsinged int pointer to length of string found -// Returns: pointer to found start of string. -// NULL if none. +// Function: FindAlphaNum +// Description: Find a whole alpha numeric string, ie consists of +// [A-Za-z0-9_] only +// Parameters: srcStr = source string to search through. +// sLen = unsinged int pointer to length of string found +// Returns: pointer to found start of string. +// NULL if none. //===================================================================== char *FindAlphaNum(char *srcStr, unsigned int *sLen) { - char curChar; - char *foundStr; - - while (*srcStr != '\0') - { - curChar = toupper(*srcStr); - if ((curChar >= 'A') && (curChar <= 'Z')) - break; - - if ((curChar >= '0') && (curChar <='9')) - break; - - if (curChar == '_') - break; - - srcStr++; - } - - if (*srcStr == '\0') - { - return NULL; - } - - foundStr = srcStr; - - *sLen = 0; - // now search for end of string of [A-Za-z0-9_] - while (*srcStr != '\0') - { - curChar = toupper(*srcStr); - if ((curChar < 'A') || (curChar > 'Z')) - { - if ((curChar < '0') || (curChar > '9')) - { - if (curChar != '_') - break; - } - } - - (*sLen)++; - srcStr++; - } - - return foundStr; + char curChar; + char *foundStr; + + while (*srcStr != '\0') + { + curChar = toupper(*srcStr); + if ((curChar >= 'A') && (curChar <= 'Z')) + break; + + if ((curChar >= '0') && (curChar <='9')) + break; + + if (curChar == '_') + break; + + srcStr++; + } + + if (*srcStr == '\0') + { + return NULL; + } + + foundStr = srcStr; + + *sLen = 0; + // now search for end of string of [A-Za-z0-9_] + while (*srcStr != '\0') + { + curChar = toupper(*srcStr); + if ((curChar < 'A') || (curChar > 'Z')) + { + if ((curChar < '0') || (curChar > '9')) + { + if (curChar != '_') + break; + } + } + + (*sLen)++; + srcStr++; + } + + return foundStr; } //===================================================================== -// Function: FindDefineParm -// Description: Find if the MACROENTRY->macroText linked list contains -// replaceable parameters. -// Parameters: srcParms = pointer to MACROENTRY structure for source -// parameters -// invParms = MACROENTRY pointer to invocation parameters -// lookString = non-null terminated string of possible -// replaceable string -// recognizedLen = replacement string matched length -// invString = invocation string to replace with -// Returns: pointer to first character found in lookstring +// Function: FindDefineParm +// Description: Find if the MACROENTRY->macroText linked list contains +// replaceable parameters. +// Parameters: srcParms = pointer to MACROENTRY structure for source +// parameters +// invParms = MACROENTRY pointer to invocation parameters +// lookString = non-null terminated string of possible +// replaceable string +// recognizedLen = replacement string matched length +// invString = invocation string to replace with +// Returns: pointer to first character found in lookstring //===================================================================== char *FindDefineParm(MACROENTRY *srcParms, MACROENTRY *invParms, - char *lookString, unsigned int *recognizedLen, char **invString) + char *lookString, unsigned int *recognizedLen, char **invString) { - MACROTEXT *srcText; - MACROTEXT *invText; - char *checkStr; - unsigned int checkLen = 0; - unsigned int sLen; - - checkStr = lookString; - *invString = NULL; - - // first search for first [A-Za-z0-9_] only string - checkStr = FindAlphaNum(lookString, &checkLen); - - while (checkStr != NULL) - { - // check all the #define parameters for match - srcText = srcParms->firstMacroParms; - invText = invParms->firstMacroParms; - while (srcText) - { - sLen = strlen(srcText->macroText); - // lengths should match - if (sLen == checkLen) - { - if (!strncmp(checkStr, srcText->macroText, checkLen)) - { - // it matched so return replacement text - *invString = invText->macroText; - // and length that we recognized - *recognizedLen = checkLen; - return checkStr; - } - } - - srcText = srcText->next; - invText = invText->next; - } - - // not found yet, so go to next string. - checkStr = FindAlphaNum(checkStr+checkLen, &checkLen); - } - - return NULL; + MACROTEXT *srcText; + MACROTEXT *invText; + char *checkStr; + unsigned int checkLen = 0; + unsigned int sLen; + + checkStr = lookString; + *invString = NULL; + + // first search for first [A-Za-z0-9_] only string + checkStr = FindAlphaNum(lookString, &checkLen); + + while (checkStr != NULL) + { + // check all the #define parameters for match + srcText = srcParms->firstMacroParms; + invText = invParms->firstMacroParms; + while (srcText) + { + sLen = strlen(srcText->macroText); + // lengths should match + if (sLen == checkLen) + { + if (!strncmp(checkStr, srcText->macroText, checkLen)) + { + // it matched so return replacement text + *invString = invText->macroText; + // and length that we recognized + *recognizedLen = checkLen; + return checkStr; + } + } + + srcText = srcText->next; + invText = invText->next; + } + + // not found yet, so go to next string. + checkStr = FindAlphaNum(checkStr+checkLen, &checkLen); + } + + return NULL; } //===================================================================== -// Function: FindReplaceParm -// Description: Find if the MACROENTRY->macroText linked list contains -// a replaceable parameters. -// Parameters: srcParms = pointer to MACROENTRY structure for source -// parameters -// invParms = MACROENTRY pointer to invocation parameters -// lookString = non-null terminated string of possible -// replaceable string -// recognizedLen = replacement string matched length -// invString = invocation string to replace with -// Returns: . +// Function: FindReplaceParm +// Description: Find if the MACROENTRY->macroText linked list contains +// a replaceable parameters. +// Parameters: srcParms = pointer to MACROENTRY structure for source +// parameters +// invParms = MACROENTRY pointer to invocation parameters +// lookString = non-null terminated string of possible +// replaceable string +// recognizedLen = replacement string matched length +// invString = invocation string to replace with +// Returns: . //===================================================================== void FindReplaceParm(MACROENTRY *srcParms, MACROENTRY *invParms, - char *lookString, unsigned int *recognizedLen, char **invString) + char *lookString, unsigned int *recognizedLen, char **invString) { - unsigned int sLen; - MACROTEXT *srcText; - MACROTEXT *invText; - - *recognizedLen = 0; - *invString = NULL; - - srcText = srcParms->firstMacroParms; - invText = invParms->firstMacroParms; - - if (srcText != NULL) - { - // go until srcText # strings ends - while (srcText != NULL) - { - sLen = strlen(srcText->macroText); - if (!strncmp(srcText->macroText, lookString, sLen)) - { - // found it so return src, replacement string - *recognizedLen = strlen(srcText->macroText); - *invString = invText->macroText; - // call function macro if it was invoked prior. - if (gMacroCallFunction != NULL) - { - gMacroCallFunction(lookString, recognizedLen, invString); - gMacroCallFunction = NULL; - } - return; - } - - srcText = srcText->next; - invText = invText->next; - } - } - - // ok, it wasn't found, look through builtin macro functions - CheckMacroFunctions(lookString, recognizedLen, invString); + unsigned int sLen; + MACROTEXT *srcText; + MACROTEXT *invText; + + *recognizedLen = 0; + *invString = NULL; + + srcText = srcParms->firstMacroParms; + invText = invParms->firstMacroParms; + + if (srcText != NULL) + { + // go until srcText # strings ends + while (srcText != NULL) + { + sLen = strlen(srcText->macroText); + if (!strncmp(srcText->macroText, lookString, sLen)) + { + // found it so return src, replacement string + *recognizedLen = strlen(srcText->macroText); + *invString = invText->macroText; + // call function macro if it was invoked prior. + if (gMacroCallFunction != NULL) + { + gMacroCallFunction(lookString, recognizedLen, invString); + gMacroCallFunction = NULL; + } + return; + } + + srcText = srcText->next; + invText = invText->next; + } + } + + // ok, it wasn't found, look through builtin macro functions + CheckMacroFunctions(lookString, recognizedLen, invString); } //===================================================================== -// Function: ReplaceMacroParms -// Description: Replace macro parameters when macro was defined, with -// those specified on the macro invocation line -// Parameters: srcLine = source line to replace src macro parms with -// destLine = destination line save to. -// invocation macro parameters. -// parseMacro = currently parsing macro entry -// invParms = invocation macro entry -// Returns: . +// Function: ReplaceMacroParms +// Description: Replace macro parameters when macro was defined, with +// those specified on the macro invocation line +// Parameters: srcLine = source line to replace src macro parms with +// destLine = destination line save to. +// invocation macro parameters. +// parseMacro = currently parsing macro entry +// invParms = invocation macro entry +// Returns: . //===================================================================== void ReplaceMacroParms(char *srcLine, char *destLine, - MACROENTRY *srcParms, MACROENTRY *invParms) + MACROENTRY *srcParms, MACROENTRY *invParms) { - char *findReplace; - char *invString; - unsigned int sLen; - unsigned int dLen; - unsigned int copyLen; - unsigned int subLen; - unsigned int recognizedLen; - - destLine[0]= '\0'; - - sLen = strlen(srcLine); - dLen = 0; - - while (sLen > 0) - { - // strtok might work better except it modifies the string, so - // kind of do my own.... - if (!srcParms->bIsDefine) - { - findReplace = strchr(srcLine, '%'); - if (findReplace != NULL) - { - // bypass % sign in findReplacement - findReplace++; - // figure out length of source before % - copyLen = (findReplace - srcLine)-1; - // check if there is a replacement string - FindReplaceParm(srcParms, invParms, findReplace, &recognizedLen, &invString); - } - else - { - strcat(destLine, srcLine); - return; - } - } - else - { - findReplace = FindDefineParm(srcParms, invParms, srcLine, &recognizedLen, &invString); - if (findReplace != NULL) - { - // figure out length of source before % - copyLen = findReplace - srcLine; - } - else - { - strcat(destLine, srcLine); - return; - } - } - - - if (invString != NULL) - { - // figure out how much we are going to substitute - subLen = strlen(invString); - } - else - { - subLen = 0; - } - - if ((dLen + copyLen + subLen) > MAXSAVELINE) - { - LexError("Macro string overrun.\n"); - CleanUp(); - exit(ERROR_MACRO_OVERRUN); - } - - if (copyLen > 0) - { - strncat(destLine, srcLine, copyLen); - dLen += copyLen; - } - - srcLine += copyLen; - sLen -= copyLen; - // in macro so skip % part of variable - if (!srcParms->bIsDefine) - { - // skip %, also - srcLine++; - sLen--; - } - - if (invString != NULL) - { - strcat(destLine, invString); - dLen += strlen(invString); - } - - srcLine += recognizedLen; - sLen -= recognizedLen; - } + char *findReplace; + char *invString; + unsigned int sLen; + unsigned int dLen; + unsigned int copyLen; + unsigned int subLen; + unsigned int recognizedLen; + + destLine[0]= '\0'; + + sLen = strlen(srcLine); + dLen = 0; + + while (sLen > 0) + { + // strtok might work better except it modifies the string, so + // kind of do my own.... + if (!srcParms->bIsDefine) + { + findReplace = strchr(srcLine, '%'); + if (findReplace != NULL) + { + // bypass % sign in findReplacement + findReplace++; + // figure out length of source before % + copyLen = (findReplace - srcLine)-1; + // check if there is a replacement string + FindReplaceParm(srcParms, invParms, findReplace, &recognizedLen, &invString); + } + else + { + strcat(destLine, srcLine); + return; + } + } + else + { + findReplace = FindDefineParm(srcParms, invParms, srcLine, &recognizedLen, &invString); + if (findReplace != NULL) + { + // figure out length of source before % + copyLen = findReplace - srcLine; + } + else + { + strcat(destLine, srcLine); + return; + } + } + + + if (invString != NULL) + { + // figure out how much we are going to substitute + subLen = strlen(invString); + } + else + { + subLen = 0; + } + + if ((dLen + copyLen + subLen) > MAXSAVELINE) + { + LexError("Macro string overrun.\n"); + CleanUp(); + exit(ERROR_MACRO_OVERRUN); + } + + if (copyLen > 0) + { + strncat(destLine, srcLine, copyLen); + dLen += copyLen; + } + + srcLine += copyLen; + sLen -= copyLen; + // in macro so skip % part of variable + if (!srcParms->bIsDefine) + { + // skip %, also + srcLine++; + sLen--; + } + + if (invString != NULL) + { + strcat(destLine, invString); + dLen += strlen(invString); + } + + srcLine += recognizedLen; + sLen -= recognizedLen; + } } //===================================================================== -// Function: SaveMacroText -// Description: Adds a string to a linked list of MACROTEXT structures -// Parameters: srcText = pointer to source text to save -// lastMacroText = last allocated, or NULL -// Returns: newly allocated MACROTEXT structure, or NULL +// Function: SaveMacroText +// Description: Adds a string to a linked list of MACROTEXT structures +// Parameters: srcText = pointer to source text to save +// lastMacroText = last allocated, or NULL +// Returns: newly allocated MACROTEXT structure, or NULL //===================================================================== MACROTEXT *SaveMacroText(char *srcText, MACROTEXT *lastMacroText) { - MACROTEXT *curMacroText; - - curMacroText = (MACROTEXT *)malloc(sizeof(MACROTEXT)); - if (curMacroText == NULL) - { - return NULL; - } - else - { - // no next entry but set up previous with previously alloced macro parameter - curMacroText->next = NULL; - curMacroText->prev = lastMacroText; - - // if the macroParm pointer is null then we are the first allocated - // so if not set the last one allocate next pointer to newly allocated structure - if (lastMacroText != NULL) - { - lastMacroText->next = curMacroText; - } - - /* %%%%% this should be set up in memory pools. */ - curMacroText->macroText = strdup(srcText); - if (curMacroText->macroText == NULL) - { - SAFEFREE(curMacroText); - return NULL; - } - } - - return curMacroText; + MACROTEXT *curMacroText; + + curMacroText = (MACROTEXT *)malloc(sizeof(MACROTEXT)); + if (curMacroText == NULL) + { + return NULL; + } + else + { + // no next entry but set up previous with previously alloced macro parameter + curMacroText->next = NULL; + curMacroText->prev = lastMacroText; + + // if the macroParm pointer is null then we are the first allocated + // so if not set the last one allocate next pointer to newly allocated structure + if (lastMacroText != NULL) + { + lastMacroText->next = curMacroText; + } + + /* %%%%% this should be set up in memory pools. */ + curMacroText->macroText = strdup(srcText); + if (curMacroText->macroText == NULL) + { + SAFEFREE(curMacroText); + return NULL; + } + } + + return curMacroText; } //===================================================================== -// Function: ParseBuiltInMacroParms -// Description: parse parameters of string and fill in MACROENTRY -// structure. -// Parameters: parsedMacro = pointer to MACROENTRY structure that gets -// filled in with parameter pointers and count -// parmStr = string to parse parameters from -// Returns: false if error +// Function: ParseBuiltInMacroParms +// Description: parse parameters of string and fill in MACROENTRY +// structure. +// Parameters: parsedMacro = pointer to MACROENTRY structure that gets +// filled in with parameter pointers and count +// parmStr = string to parse parameters from +// Returns: false if error //===================================================================== bool ParseBuiltInMacroParms(MACROENTRY *parsedMacro, char *parmStr) { - char *endStr; - char *foundParm; - MACROTEXT *prevMT; - MACROTEXT *curMT; - - parsedMacro->numParms = 0; - parsedMacro->firstMacroParms = NULL; - - foundParm = strdup(parmStr); - if (foundParm == NULL) - { - LexError("Out of memory parsing bultin macro parameters.\n"); - return false; - } - - // assume a ')' is on the end. - endStr = strrchr(foundParm, ')'); - if (endStr == NULL) - { - LexWarning("Ending parenthesis not found for macro %s.\n", parsedMacro->macroName); - endStr = foundParm + strlen(foundParm); - } - - prevMT = NULL; - // strip out and separate parameters - while (foundParm < endStr) - { - // allocate a macro text structure - curMT = (MACROTEXT *)malloc(sizeof(MACROTEXT)); - if (curMT == NULL) - { - free(parmStr); - LexError("Out of memory parsing bultin macro parameters.\n"); - return false; - } - curMT->next = NULL; - curMT->prev = prevMT; - parsedMacro->numParms++; - - if (prevMT != NULL) - { - prevMT->next = curMT; - } - else - { - parsedMacro->firstMacroParms = curMT; - } - - curMT->macroText = foundParm; - // search for next parameters, delimited by comma - foundParm = strchr(foundParm, ','); - if (foundParm == NULL) - { - foundParm = endStr; - *foundParm = '\0'; - } - else - { - // skip comma - *foundParm = '\0'; - foundParm++; - } - prevMT = curMT; - } - - return true; + char *endStr; + char *foundParm; + MACROTEXT *prevMT; + MACROTEXT *curMT; + + parsedMacro->numParms = 0; + parsedMacro->firstMacroParms = NULL; + + foundParm = strdup(parmStr); + if (foundParm == NULL) + { + LexError("Out of memory parsing bultin macro parameters.\n"); + return false; + } + + // assume a ')' is on the end. + endStr = strrchr(foundParm, ')'); + if (endStr == NULL) + { + LexWarning("Ending parenthesis not found for macro %s.\n", parsedMacro->macroName); + endStr = foundParm + strlen(foundParm); + } + + prevMT = NULL; + // strip out and separate parameters + while (foundParm < endStr) + { + // allocate a macro text structure + curMT = (MACROTEXT *)malloc(sizeof(MACROTEXT)); + if (curMT == NULL) + { + free(parmStr); + LexError("Out of memory parsing bultin macro parameters.\n"); + return false; + } + curMT->next = NULL; + curMT->prev = prevMT; + parsedMacro->numParms++; + + if (prevMT != NULL) + { + prevMT->next = curMT; + } + else + { + parsedMacro->firstMacroParms = curMT; + } + + curMT->macroText = foundParm; + // search for next parameters, delimited by comma + foundParm = strchr(foundParm, ','); + if (foundParm == NULL) + { + foundParm = endStr; + *foundParm = '\0'; + } + else + { + // skip comma + *foundParm = '\0'; + foundParm++; + } + prevMT = curMT; + } + + return true; } //===================================================================== -// Function: MacroMathFunction -// Description: Comes here after macro replacement is done to perform -// some mathematic function on parameter (macro replacement -// string (ie, register)) -// Parameters: invMacro = macroentry pointer containing macro information -// recognizedLen = # characters recoginized so far -// invStr = invoked replacement string so far -// mathStr = "-", "+", etc for mathematic function -// Returns: new recognizedLen, invStr, with incremented # +// Function: MacroMathFunction +// Description: Comes here after macro replacement is done to perform +// some mathematic function on parameter (macro replacement +// string (ie, register)) +// Parameters: invMacro = macroentry pointer containing macro information +// recognizedLen = # characters recoginized so far +// invStr = invoked replacement string so far +// mathStr = "-", "+", etc for mathematic function +// Returns: new recognizedLen, invStr, with incremented # //===================================================================== void MacroMathFunction(MACROENTRY *invMacro, unsigned int *recognizedLen, char **invStr, - const char *mathStr) + const char *mathStr) { - char *numStartStr; - unsigned int sLen; - char numberStr[256]; - unsigned int number = 0; - char *operand; - - - // verify enough paramters to complete operation - if (invMacro->numParms != 2) - { - LexError("Two parameters are required for %s macro\n", invMacro->macroName); - return; - } - - // get second macro parm, which is add by amount. - operand = invMacro->firstMacroParms->next->macroText; - - // first find inner most bracket if any - numStartStr = strrchr(*invStr, ']'); - if (numStartStr == NULL) - { - numStartStr = strrchr(*invStr, ')'); - } - - if (numStartStr != NULL) - { - if ((strlen(*invStr)+strlen(operand)+1) > MAXREPLACESTRING) - { - LexError("Out of Temporary string replacement memory inside builtin macro %s\n", - invMacro->macroName); - } - else - { - sLen = (numStartStr - *invStr); - gReplaceText[0] = '\0'; - strncat(gReplaceText, *invStr, sLen); - strcat(gReplaceText, mathStr); - strcat(gReplaceText, operand); - strcat(gReplaceText, numStartStr); - *invStr = gReplaceText; - } - } - else - { - numStartStr = strpbrk(*invStr, "0123456789"); - if (numStartStr != NULL) - { - // put up to number we found - sLen = numStartStr - *invStr; - if (sLen > MAXREPLACESTRING) - goto ErrOut; - - gReplaceText[0] = '\0'; - strncat(gReplaceText, *invStr, sLen); - - switch (mathStr[0]) - { - case '-': - number = atoi(numStartStr)-atoi(operand); - break; - case '+': - number = atoi(numStartStr)+atoi(operand); - break; - } - sprintf(numberStr, "%d", number); - - if ((strlen(gReplaceText) + strlen(numberStr)) > MAXREPLACESTRING) - goto ErrOut; - - strcat(gReplaceText, numberStr); - - while ((*numStartStr != '\0') && (*numStartStr >= '0' && *numStartStr <= '9')) - numStartStr++; - - if ((strlen(gReplaceText) + strlen(numStartStr)) > MAXREPLACESTRING) - goto ErrOut; - - strcat(gReplaceText, numStartStr); - - *invStr = gReplaceText; - } - else - { - if ((strlen(*invStr)+strlen(operand)+1) > MAXREPLACESTRING) - { - LexError("Out of Temporary string replacement memory inside builtin macro %s\n", - invMacro->macroName); - } - else - { - sprintf(gReplaceText, "%s%s%s", *invStr, mathStr, operand); - *invStr = gReplaceText; - } - } - } - - - return; + char *numStartStr; + unsigned int sLen; + char numberStr[256]; + unsigned int number = 0; + char *operand; + + + // verify enough paramters to complete operation + if (invMacro->numParms != 2) + { + LexError("Two parameters are required for %s macro\n", invMacro->macroName); + return; + } + + // get second macro parm, which is add by amount. + operand = invMacro->firstMacroParms->next->macroText; + + // first find inner most bracket if any + numStartStr = strrchr(*invStr, ']'); + if (numStartStr == NULL) + { + numStartStr = strrchr(*invStr, ')'); + } + + if (numStartStr != NULL) + { + if ((strlen(*invStr)+strlen(operand)+1) > MAXREPLACESTRING) + { + LexError("Out of Temporary string replacement memory inside builtin macro %s\n", + invMacro->macroName); + } + else + { + sLen = (numStartStr - *invStr); + gReplaceText[0] = '\0'; + strncat(gReplaceText, *invStr, sLen); + strcat(gReplaceText, mathStr); + strcat(gReplaceText, operand); + strcat(gReplaceText, numStartStr); + *invStr = gReplaceText; + } + } + else + { + numStartStr = strpbrk(*invStr, "0123456789"); + if (numStartStr != NULL) + { + // put up to number we found + sLen = numStartStr - *invStr; + if (sLen > MAXREPLACESTRING) + goto ErrOut; + + gReplaceText[0] = '\0'; + strncat(gReplaceText, *invStr, sLen); + + switch (mathStr[0]) + { + case '-': + number = atoi(numStartStr)-atoi(operand); + break; + case '+': + number = atoi(numStartStr)+atoi(operand); + break; + } + sprintf(numberStr, "%d", number); + + if ((strlen(gReplaceText) + strlen(numberStr)) > MAXREPLACESTRING) + goto ErrOut; + + strcat(gReplaceText, numberStr); + + while ((*numStartStr != '\0') && (*numStartStr >= '0' && *numStartStr <= '9')) + numStartStr++; + + if ((strlen(gReplaceText) + strlen(numStartStr)) > MAXREPLACESTRING) + goto ErrOut; + + strcat(gReplaceText, numStartStr); + + *invStr = gReplaceText; + } + else + { + if ((strlen(*invStr)+strlen(operand)+1) > MAXREPLACESTRING) + { + LexError("Out of Temporary string replacement memory inside builtin macro %s\n", + invMacro->macroName); + } + else + { + sprintf(gReplaceText, "%s%s%s", *invStr, mathStr, operand); + *invStr = gReplaceText; + } + } + } + + + return; ErrOut: - LexError("Out of Temporary string replacement memory inside builtin macro %s\n", - invMacro->macroName); - // skip ')' - (*recognizedLen)++; + LexError("Out of Temporary string replacement memory inside builtin macro %s\n", + invMacro->macroName); + // skip ')' + (*recognizedLen)++; } //===================================================================== -// Function: MacroIncFunction -// Description: Comes here after macro replacement is done to increment -// macro replacement string (ie, register) -// Parameters: lookStr = string after '(', so we can get parameters -// recognizedLen = # characters recoginized so far -// invStr = invoked replacement string so far -// Returns: new recognizedLen, invStr, with incremented # +// Function: MacroIncFunction +// Description: Comes here after macro replacement is done to increment +// macro replacement string (ie, register) +// Parameters: lookStr = string after '(', so we can get parameters +// recognizedLen = # characters recoginized so far +// invStr = invoked replacement string so far +// Returns: new recognizedLen, invStr, with incremented # //===================================================================== void MacroIncFunction(char *lookStr, unsigned int *recognizedLen, char **invStr) { - MACROENTRY tMEntry; - MACROTEXT parm1; - MACROTEXT parm2; - - tMEntry.macroName = (char *)"%inc()"; - tMEntry.numParms = 2; - tMEntry.firstMacroParms = &parm1; - parm1.prev = NULL; - parm1.next = &parm2; - parm1.macroText = *invStr; - parm2.prev = &parm1; - parm2.next = NULL; - parm2.macroText = (char *)"1"; - - MacroMathFunction(&tMEntry, recognizedLen, invStr, "+"); - // skip ')' - (*recognizedLen)++; + MACROENTRY tMEntry; + MACROTEXT parm1; + MACROTEXT parm2; + + tMEntry.macroName = (char *)"%inc()"; + tMEntry.numParms = 2; + tMEntry.firstMacroParms = &parm1; + parm1.prev = NULL; + parm1.next = &parm2; + parm1.macroText = *invStr; + parm2.prev = &parm1; + parm2.next = NULL; + parm2.macroText = (char *)"1"; + + MacroMathFunction(&tMEntry, recognizedLen, invStr, "+"); + // skip ')' + (*recognizedLen)++; } //===================================================================== -// Function: MacroDecFunction -// Description: Comes here after macro replacement is done to decrement -// macro replacement string (ie, register) -// Parameters: lookStr = string after '(', so we can get parameters -// recognizedLen = # characters recoginized so far -// invStr = invoked replacement string so far -// Returns: new recognizedLen, invStr, with decremented # +// Function: MacroDecFunction +// Description: Comes here after macro replacement is done to decrement +// macro replacement string (ie, register) +// Parameters: lookStr = string after '(', so we can get parameters +// recognizedLen = # characters recoginized so far +// invStr = invoked replacement string so far +// Returns: new recognizedLen, invStr, with decremented # //===================================================================== void MacroDecFunction(char *lookStr, unsigned int *recognizedLen, char **invStr) { - MACROENTRY tMEntry; - MACROTEXT parm1; - MACROTEXT parm2; - - tMEntry.macroName = (char *)"%dec()"; - tMEntry.numParms = 2; - tMEntry.firstMacroParms = &parm1; - parm1.prev = NULL; - parm1.next = &parm2; - parm1.macroText = *invStr; - parm2.prev = &parm1; - parm2.next = NULL; - parm2.macroText = (char *)"1"; - - MacroMathFunction(&tMEntry, recognizedLen, invStr, "-"); - // skip ')' - (*recognizedLen)++; + MACROENTRY tMEntry; + MACROTEXT parm1; + MACROTEXT parm2; + + tMEntry.macroName = (char *)"%dec()"; + tMEntry.numParms = 2; + tMEntry.firstMacroParms = &parm1; + parm1.prev = NULL; + parm1.next = &parm2; + parm1.macroText = *invStr; + parm2.prev = &parm1; + parm2.next = NULL; + parm2.macroText = (char *)"1"; + + MacroMathFunction(&tMEntry, recognizedLen, invStr, "-"); + // skip ')' + (*recognizedLen)++; } //===================================================================== -// Function: MacroAddFunction -// Description: Comes here after macro replacement is done to add -// macro replacement string (ie, register) -// Parameters: lookStr = string after '(', so we can get parameters -// recognizedLen = # characters recoginized so far -// invStr = invoked replacement string so far -// Returns: new recognizedLen, invStr, with incremented # +// Function: MacroAddFunction +// Description: Comes here after macro replacement is done to add +// macro replacement string (ie, register) +// Parameters: lookStr = string after '(', so we can get parameters +// recognizedLen = # characters recoginized so far +// invStr = invoked replacement string so far +// Returns: new recognizedLen, invStr, with incremented # //===================================================================== void MacroAddFunction(char *lookStr, unsigned int *recognizedLen, char **invStr) { - MACROENTRY tMEntry; - MACROTEXT *curMT; - MACROTEXT *nextMT; - unsigned int i; - - tMEntry.macroName = (char *)"%add()"; - if (strlen(lookStr) > MAXREPLACESTRING) - { - LexError("Out of Temporary string replacement memory inside builtin macro %add()\n"); - return; - } - if (ParseBuiltInMacroParms(&tMEntry, lookStr)) - { - MacroMathFunction(&tMEntry, recognizedLen, invStr, "+"); - // skip ',' strlen(parm2)+ ')' - (*recognizedLen) += strlen(tMEntry.firstMacroParms->next->macroText)+2; - } - - curMT = tMEntry.firstMacroParms; - // in this case only one string was allocated - free(curMT->macroText); - for (i=0; inext; - free(curMT); - curMT = nextMT; - } + MACROENTRY tMEntry; + MACROTEXT *curMT; + MACROTEXT *nextMT; + unsigned int i; + + tMEntry.macroName = (char *)"%add()"; + if (strlen(lookStr) > MAXREPLACESTRING) + { + LexError("Out of Temporary string replacement memory inside builtin macro %add()\n"); + return; + } + if (ParseBuiltInMacroParms(&tMEntry, lookStr)) + { + MacroMathFunction(&tMEntry, recognizedLen, invStr, "+"); + // skip ',' strlen(parm2)+ ')' + (*recognizedLen) += strlen(tMEntry.firstMacroParms->next->macroText)+2; + } + + curMT = tMEntry.firstMacroParms; + // in this case only one string was allocated + free(curMT->macroText); + for (i=0; inext; + free(curMT); + curMT = nextMT; + } } //===================================================================== -// Function: MacroSubFunction -// Description: Comes here after macro replacement is done to subtract -// macro replacement string (ie, register) -// Parameters: invParms, parameters that macro was invoked with -// recognizedLen = # characters recoginized so far -// invStr = invoked replacement string so far -// Returns: new recognizedLen, invStr, with incremented # +// Function: MacroSubFunction +// Description: Comes here after macro replacement is done to subtract +// macro replacement string (ie, register) +// Parameters: invParms, parameters that macro was invoked with +// recognizedLen = # characters recoginized so far +// invStr = invoked replacement string so far +// Returns: new recognizedLen, invStr, with incremented # //===================================================================== void MacroSubFunction(char *lookStr, unsigned int *recognizedLen, char **invStr) { - MACROENTRY tMEntry; - MACROTEXT *curMT; - MACROTEXT *nextMT; - unsigned int i; - - tMEntry.macroName = (char *)"%sub()"; - if (ParseBuiltInMacroParms(&tMEntry, lookStr)) - { - MacroMathFunction(&tMEntry, recognizedLen, invStr, "-"); - // skip ',' strlen(parm2)+ ')' - (*recognizedLen) += strlen(tMEntry.firstMacroParms->next->macroText)+2; - } - curMT = tMEntry.firstMacroParms; - // in this case only one string was allocated - free(curMT->macroText); - for (i=0; inext; - free(curMT); - curMT = nextMT; - } + MACROENTRY tMEntry; + MACROTEXT *curMT; + MACROTEXT *nextMT; + unsigned int i; + + tMEntry.macroName = (char *)"%sub()"; + if (ParseBuiltInMacroParms(&tMEntry, lookStr)) + { + MacroMathFunction(&tMEntry, recognizedLen, invStr, "-"); + // skip ',' strlen(parm2)+ ')' + (*recognizedLen) += strlen(tMEntry.firstMacroParms->next->macroText)+2; + } + curMT = tMEntry.firstMacroParms; + // in this case only one string was allocated + free(curMT->macroText); + for (i=0; inext; + free(curMT); + curMT = nextMT; + } } //===================================================================== -// Function: EndMacroParms -// Description: Does update and cleanup one end of macro parameters -// is reached -// Parameters: . -// Returns: . +// Function: EndMacroParms +// Description: Does update and cleanup one end of macro parameters +// is reached +// Parameters: . +// Returns: . //===================================================================== void EndMacroParms() { - char *curFileName; - char *macroFileName; - char tempStr[1024]; - char *macroText; - - if (gbTempInsideMacro) - { - if (gTempParseMacro->numParms != gTempMacro->numParms) - { - LexError("Macro invocation number of parameters do not match macro definition, skipping\n"); - BEGIN(INITIAL); - SAFEFREE(gTempMacro); - } - else - { - // we got all the parameters for the MACRO invocation, so start inside - // the macro now, by saving off current state on stack - gIncludeStack[gIncludeStackIndex].lineNo = yylineno; - gIncludeStack[gIncludeStackIndex].fileName = gCurFileName; -// gIncludeStack[gIncludeStackIndex].fileHandle = yyin; + char *curFileName; + char *macroFileName; + char tempStr[1024]; + char *macroText; + + if (gbTempInsideMacro) + { + if (gTempParseMacro->numParms != gTempMacro->numParms) + { + LexError("Macro invocation number of parameters do not match macro definition, skipping\n"); + BEGIN(INITIAL); + SAFEFREE(gTempMacro); + } + else + { + // we got all the parameters for the MACRO invocation, so start inside + // the macro now, by saving off current state on stack + gIncludeStack[gIncludeStackIndex].lineNo = yylineno; + gIncludeStack[gIncludeStackIndex].fileName = gCurFileName; +// gIncludeStack[gIncludeStackIndex].fileHandle = yyin; //fprintf( stderr, "Chris fix this code with myin stuff\n" ); - gIncludeStack[gIncludeStackIndex].prevString = myin; - gIncludeStack[gIncludeStackIndex].nextString = NULL; - gIncludeStack[gIncludeStackIndex].lastInvokeMacro = gInvokeMacro; - gIncludeStack[gIncludeStackIndex].lastParseMacro = gParseMacro; - gIncludeStack[gIncludeStackIndex].lastMacroLineParse = gMacroLineParse; - gIncludeStack[gIncludeStackIndex].lastbInsideMacro = gbInsideMacro; - gIncludeStack[gIncludeStackIndex].lastbInsideInclude = gbInsideInclude; - gIncludeStack[gIncludeStackIndex].buffer = YY_CURRENT_BUFFER; - gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF; - gIncludeStackIndex++; - - gParseMacro = gTempParseMacro; - gInvokeMacro = gTempMacro; - gbInsideMacro = gbTempInsideMacro; - - gbTempInsideMacro = false; - -// yyin = NULL; - myin = NULL; - curFileName = gCurFileName; - if (curFileName == NULL) - curFileName = (char *)""; - - macroFileName = gParseMacro->fileName; - if (macroFileName == NULL) - macroFileName = (char *)""; - - sprintf(tempStr, "%s(%d) : References ->\n%s", curFileName, yylineno, macroFileName); - gCurFileName = strdup(tempStr); - gMacroLineParse = gParseMacro->firstMacroLines; - - macroText = gMacroLine; - // if no replacement text, just use source line - if (gParseMacro->firstMacroParms == NULL) - { - macroText = gMacroLineParse->macroText; - } - else - { - // replace the macro parameters - ReplaceMacroParms(gMacroLineParse->macroText, gMacroLine, gParseMacro, gInvokeMacro); - } - - yylineno = gParseMacro->lineNo; - if (gParseMacro->nLines >= 1) - { - strcpy(gSaveLine, macroText); - } - -// if (gExpandMacros && (gParseMacro->nLines >= 1)) -// { -// // in case there is anything there dump it out -// GenDebugLine(); -// GenListString(); -// if (gInvokeMacro->nLines >= 1) -// GenSwitchFileNames(macroFileName); -// } - - BEGIN(gInvokeState); - yy_scan_string(macroText); - gInvokeState = INITIAL; - } - } - else - { - if (gLastMacro != NULL) - { - gLastMacro->next = gTempMacro; - } - gLastMacro = gTempMacro; - BEGIN(MACROBODY); - } + gIncludeStack[gIncludeStackIndex].prevString = myin; + gIncludeStack[gIncludeStackIndex].nextString = NULL; + gIncludeStack[gIncludeStackIndex].lastInvokeMacro = gInvokeMacro; + gIncludeStack[gIncludeStackIndex].lastParseMacro = gParseMacro; + gIncludeStack[gIncludeStackIndex].lastMacroLineParse = gMacroLineParse; + gIncludeStack[gIncludeStackIndex].lastbInsideMacro = gbInsideMacro; + gIncludeStack[gIncludeStackIndex].lastbInsideInclude = gbInsideInclude; + gIncludeStack[gIncludeStackIndex].buffer = YY_CURRENT_BUFFER; + gIncludeStack[gIncludeStackIndex].lastbProcessingIFDEF = gbProcessingIFDEF; + gIncludeStackIndex++; + + gParseMacro = gTempParseMacro; + gInvokeMacro = gTempMacro; + gbInsideMacro = gbTempInsideMacro; + + gbTempInsideMacro = false; + +// yyin = NULL; + myin = NULL; + curFileName = gCurFileName; + if (curFileName == NULL) + curFileName = (char *)""; + + macroFileName = gParseMacro->fileName; + if (macroFileName == NULL) + macroFileName = (char *)""; + + sprintf(tempStr, "%s(%d) : References ->\n%s", curFileName, yylineno, macroFileName); + gCurFileName = strdup(tempStr); + gMacroLineParse = gParseMacro->firstMacroLines; + + macroText = gMacroLine; + // if no replacement text, just use source line + if (gParseMacro->firstMacroParms == NULL) + { + macroText = gMacroLineParse->macroText; + } + else + { + // replace the macro parameters + ReplaceMacroParms(gMacroLineParse->macroText, gMacroLine, gParseMacro, gInvokeMacro); + } + + yylineno = gParseMacro->lineNo; + if (gParseMacro->nLines >= 1) + { + strcpy(gSaveLine, macroText); + } + +// if (gExpandMacros && (gParseMacro->nLines >= 1)) +// { +// // in case there is anything there dump it out +// GenDebugLine(); +// GenListString(); +// if (gInvokeMacro->nLines >= 1) +// GenSwitchFileNames(macroFileName); +// } + + BEGIN(gInvokeState); + yy_scan_string(macroText); + gInvokeState = INITIAL; + } + } + else + { + if (gLastMacro != NULL) + { + gLastMacro->next = gTempMacro; + } + gLastMacro = gTempMacro; + BEGIN(MACROBODY); + } } //===================================================================== -// Function: FindSwizzleValue -// Description: see if valid swizzle value and return the bits -// Parameters: swizzleTex = pointer to characters to analyze -// Returns: unsigned int = bits for swizzle values, or 0 for error +// Function: FindSwizzleValue +// Description: see if valid swizzle value and return the bits +// Parameters: swizzleTex = pointer to characters to analyze +// Returns: unsigned int = bits for swizzle values, or 0 for error //===================================================================== unsigned int FindSwizzleValue(char *swizzleText) { - unsigned int swizzleBits; - unsigned int sLen; - unsigned int i; - unsigned int lastMask; - - sLen = strlen(swizzleText); - swizzleBits = 0; - lastMask = 0; - - for (i=0; iStack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ while (0) #endif @@ -340,7 +340,7 @@ union yyalloc #define YYUNDEFTOK 2 #define YYMAXUTOK 290 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ @@ -597,43 +597,43 @@ static const unsigned char yystos[] = # define YYSIZE_T unsigned int #endif -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab +#define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ + YYERROR; \ + } \ while (0) -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYTERROR 1 +#define YYERRCODE 256 /* YYLLOC_DEFAULT -- Compute the default location (before the actions are run). */ @@ -662,27 +662,27 @@ while (0) # define YYFPRINTF fprintf # endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ } while (0) -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ } while (0) -# define YYDSYMPRINTF(Title, Token, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ } while (0) /*------------------------------------------------------------------. @@ -706,10 +706,10 @@ yy_stack_print (bottom, top) YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ } while (0) @@ -736,10 +736,10 @@ yy_reduce_print (yyrule) YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that @@ -755,7 +755,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -964,7 +964,7 @@ yyparse () to reallocate them elsewhere. */ /* The state stack. */ - short yyssa[YYINITDEPTH]; + short yyssa[YYINITDEPTH]; short *yyss = yyssa; register short *yyssp; @@ -993,7 +993,7 @@ yyparse () yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ + yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack @@ -1024,25 +1024,25 @@ yyparse () #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); + &yystacksize); - yyss = yyss1; - yyvs = yyvs1; + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -1050,23 +1050,23 @@ yyparse () # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; + goto yyoverflowlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@ -1076,10 +1076,10 @@ yyparse () YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1130,7 +1130,7 @@ yyparse () if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; + goto yyerrlab; yyn = -yyn; goto yyreduce; } @@ -1191,472 +1191,472 @@ yyparse () case 2: #line 97 "vs1.0_grammar.y" { - yyvsp[0].instList->Validate(); - yyvsp[0].instList->Translate(); - delete yyvsp[0].instList; - ;} + yyvsp[0].instList->Validate(); + yyvsp[0].instList->Translate(); + delete yyvsp[0].instList; + ;} break; case 3: #line 105 "vs1.0_grammar.y" { - *(yyvsp[-1].instList) += yyvsp[0].inst; - delete yyvsp[0].inst; - yyval.instList = yyvsp[-1].instList - ;} + *(yyvsp[-1].instList) += yyvsp[0].inst; + delete yyvsp[0].inst; + yyval.instList = yyvsp[-1].instList + ;} break; case 4: #line 111 "vs1.0_grammar.y" { - VS10InstListPtr instList = new VS10InstList; - if ( yyvsp[0].inst != NULL ) - { - *instList += yyvsp[0].inst; - delete yyvsp[0].inst; - } - yyval.instList = instList; - ;} + VS10InstListPtr instList = new VS10InstList; + if ( yyvsp[0].inst != NULL ) + { + *instList += yyvsp[0].inst; + delete yyvsp[0].inst; + } + yyval.instList = instList; + ;} break; case 5: #line 123 "vs1.0_grammar.y" { - yyval.inst = yyvsp[0].inst; - do_linenum_incr(); - ;} + yyval.inst = yyvsp[0].inst; + do_linenum_incr(); + ;} break; case 6: #line 128 "vs1.0_grammar.y" { - yyval.inst = new VS10Inst( get_linenum() ); - do_linenum_incr(); - ;} + yyval.inst = new VS10Inst( get_linenum() ); + do_linenum_incr(); + ;} break; case 12: #line 140 "vs1.0_grammar.y" { - yyval.inst = new VS10Inst( get_linenum(), VS10_NOP ); - ;} + yyval.inst = new VS10Inst( get_linenum(), VS10_NOP ); + ;} break; case 13: #line 144 "vs1.0_grammar.y" { - yyval.inst = new VS10Inst( get_linenum(), VS10_COMMENT, yyvsp[0].comment ); - ;} + yyval.inst = new VS10Inst( get_linenum(), VS10_COMMENT, yyvsp[0].comment ); + ;} break; case 14: #line 148 "vs1.0_grammar.y" { - yyval.inst = new VS10Inst( get_linenum(), VS10_HEADER ); - ;} + yyval.inst = new VS10Inst( get_linenum(), VS10_HEADER ); + ;} break; case 15: #line 154 "vs1.0_grammar.y" { - yyval.inst = new VS10Inst( get_linenum(), yyvsp[-3].ival, yyvsp[-2].reg, yyvsp[0].reg ); - ;} + yyval.inst = new VS10Inst( get_linenum(), yyvsp[-3].ival, yyvsp[-2].reg, yyvsp[0].reg ); + ;} break; case 16: #line 160 "vs1.0_grammar.y" { - VS10Reg reg; - reg = yyvsp[-2].reg; - reg.sign = -1; - reg.type = yyvsp[-2].reg.type; - reg.index = yyvsp[-2].reg.index; - for ( int i = 0; i < 4; i++ ) reg.mask[i] = yyvsp[0].mask[i]; - yyval.reg = reg; - ;} + VS10Reg reg; + reg = yyvsp[-2].reg; + reg.sign = -1; + reg.type = yyvsp[-2].reg.type; + reg.index = yyvsp[-2].reg.index; + for ( int i = 0; i < 4; i++ ) reg.mask[i] = yyvsp[0].mask[i]; + yyval.reg = reg; + ;} break; case 17: #line 170 "vs1.0_grammar.y" { - VS10Reg reg; - reg = yyvsp[-2].reg; - reg.sign = 1; - reg.type = yyvsp[-2].reg.type; - reg.index = yyvsp[-2].reg.index; - for ( int i = 0; i < 4; i++ ) reg.mask[i] = yyvsp[0].mask[i]; - yyval.reg = reg; - ;} + VS10Reg reg; + reg = yyvsp[-2].reg; + reg.sign = 1; + reg.type = yyvsp[-2].reg.type; + reg.index = yyvsp[-2].reg.index; + for ( int i = 0; i < 4; i++ ) reg.mask[i] = yyvsp[0].mask[i]; + yyval.reg = reg; + ;} break; case 18: #line 180 "vs1.0_grammar.y" { - VS10Reg reg; - reg = yyvsp[0].reg; - reg.sign = -1; - reg.type = yyvsp[0].reg.type; - reg.index = yyvsp[0].reg.index; - for ( int i = 0; i < 4; i++ ) reg.mask[i] = 0; - yyval.reg = reg; - ;} + VS10Reg reg; + reg = yyvsp[0].reg; + reg.sign = -1; + reg.type = yyvsp[0].reg.type; + reg.index = yyvsp[0].reg.index; + for ( int i = 0; i < 4; i++ ) reg.mask[i] = 0; + yyval.reg = reg; + ;} break; case 19: #line 190 "vs1.0_grammar.y" { - VS10Reg reg; - reg = yyvsp[0].reg; - reg.sign = 1; - reg.type = yyvsp[0].reg.type; - reg.index = yyvsp[0].reg.index; - for ( int i = 0; i < 4; i++ ) reg.mask[i] = 0; - yyval.reg = reg; - ;} + VS10Reg reg; + reg = yyvsp[0].reg; + reg.sign = 1; + reg.type = yyvsp[0].reg.type; + reg.index = yyvsp[0].reg.index; + for ( int i = 0; i < 4; i++ ) reg.mask[i] = 0; + yyval.reg = reg; + ;} break; case 21: #line 201 "vs1.0_grammar.y" { - ;} + ;} break; case 22: #line 205 "vs1.0_grammar.y" { - VS10Reg reg; - reg.type = TYPE_CONSTANT_MEM_REG; - reg.index = yyvsp[-1].ival; - yyval.reg = reg; - ;} + VS10Reg reg; + reg.type = TYPE_CONSTANT_MEM_REG; + reg.index = yyvsp[-1].ival; + yyval.reg = reg; + ;} break; case 23: #line 212 "vs1.0_grammar.y" { - // Register is valid only if - // type = TYPE_ADDRESS_REG - // index = 0 - // len(mask) = 1 - // mask[0] = 'x' - VS10Reg reg; - yyval.reg.type = TYPE_CONSTANT_A0_REG; - if ( yyvsp[-3].reg.type != TYPE_ADDRESS_REG ) - { - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - } - else if ( yyvsp[-3].reg.index != 0 ) - { - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - } - else - { - int len = 0; - while ( len < 2 ) - { - if ( yyvsp[-1].mask[len] == 0 ) - break; - len++; - } - if ( len != 1 || yyvsp[-1].mask[0] != 'x' ) - { - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - } - - reg.type = TYPE_CONSTANT_A0_REG; - yyval.reg = reg; - } - ;} + // Register is valid only if + // type = TYPE_ADDRESS_REG + // index = 0 + // len(mask) = 1 + // mask[0] = 'x' + VS10Reg reg; + yyval.reg.type = TYPE_CONSTANT_A0_REG; + if ( yyvsp[-3].reg.type != TYPE_ADDRESS_REG ) + { + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + } + else if ( yyvsp[-3].reg.index != 0 ) + { + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + } + else + { + int len = 0; + while ( len < 2 ) + { + if ( yyvsp[-1].mask[len] == 0 ) + break; + len++; + } + if ( len != 1 || yyvsp[-1].mask[0] != 'x' ) + { + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + } + + reg.type = TYPE_CONSTANT_A0_REG; + yyval.reg = reg; + } + ;} break; case 24: #line 247 "vs1.0_grammar.y" { - // Register is valid only if - // type = TYPE_ADDRESS_REG - // index = 0 - // len(mask) = 1 - // mask[0] = 'x' - VS10Reg reg; - yyval.reg.type = TYPE_CONSTANT_A0_OFFSET_REG; - if ( yyvsp[-5].reg.type != TYPE_ADDRESS_REG ) - { - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - } - else if ( yyvsp[-5].reg.index != 0 ) - { - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - } - else - { - int len = 0; - while ( len < 2 ) - { - if ( yyvsp[-3].mask[len] == 0 ) - break; - len++; - } - if ( len != 1 || yyvsp[-3].mask[0] != 'x' ) - { - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - } - - reg.type = TYPE_CONSTANT_A0_OFFSET_REG; - reg.index = yyvsp[-1].ival; - yyval.reg = reg; - } - ;} + // Register is valid only if + // type = TYPE_ADDRESS_REG + // index = 0 + // len(mask) = 1 + // mask[0] = 'x' + VS10Reg reg; + yyval.reg.type = TYPE_CONSTANT_A0_OFFSET_REG; + if ( yyvsp[-5].reg.type != TYPE_ADDRESS_REG ) + { + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + } + else if ( yyvsp[-5].reg.index != 0 ) + { + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + } + else + { + int len = 0; + while ( len < 2 ) + { + if ( yyvsp[-3].mask[len] == 0 ) + break; + len++; + } + if ( len != 1 || yyvsp[-3].mask[0] != 'x' ) + { + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + } + + reg.type = TYPE_CONSTANT_A0_OFFSET_REG; + reg.index = yyvsp[-1].ival; + yyval.reg = reg; + } + ;} break; case 25: #line 283 "vs1.0_grammar.y" { - yyval.reg.type = TYPE_CONSTANT_A0_REG; - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - ;} + yyval.reg.type = TYPE_CONSTANT_A0_REG; + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + ;} break; case 26: #line 288 "vs1.0_grammar.y" { - yyval.reg.type = TYPE_CONSTANT_A0_REG; - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - ;} + yyval.reg.type = TYPE_CONSTANT_A0_REG; + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + ;} break; case 27: #line 293 "vs1.0_grammar.y" { - yyval.reg.type = TYPE_CONSTANT_A0_REG; - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - ;} + yyval.reg.type = TYPE_CONSTANT_A0_REG; + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + ;} break; case 28: #line 298 "vs1.0_grammar.y" { - yyval.reg.type = TYPE_CONSTANT_A0_REG; - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - ;} + yyval.reg.type = TYPE_CONSTANT_A0_REG; + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + ;} break; case 29: #line 303 "vs1.0_grammar.y" { - yyval.reg.type = TYPE_CONSTANT_A0_REG; - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - ;} + yyval.reg.type = TYPE_CONSTANT_A0_REG; + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + ;} break; case 30: #line 308 "vs1.0_grammar.y" { - yyval.reg.type = TYPE_CONSTANT_A0_REG; - LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); - ;} + yyval.reg.type = TYPE_CONSTANT_A0_REG; + LexError( "constant register index must be:\t, a0.x, or a0.x + .\n" ); + ;} break; case 31: #line 315 "vs1.0_grammar.y" { - yyval.inst = new VS10Inst( get_linenum(), yyvsp[-3].ival, yyvsp[-2].reg, yyvsp[0].reg ); - ;} + yyval.inst = new VS10Inst( get_linenum(), yyvsp[-3].ival, yyvsp[-2].reg, yyvsp[0].reg ); + ;} break; case 32: #line 321 "vs1.0_grammar.y" { - yyval.inst = new VS10Inst( get_linenum(), yyvsp[-3].ival, yyvsp[-2].reg, yyvsp[0].reg ); - ;} + yyval.inst = new VS10Inst( get_linenum(), yyvsp[-3].ival, yyvsp[-2].reg, yyvsp[0].reg ); + ;} break; case 33: #line 327 "vs1.0_grammar.y" { - yyval.inst = new VS10Inst( get_linenum(), yyvsp[-5].ival, yyvsp[-4].reg, yyvsp[-2].reg, yyvsp[0].reg ); - ;} + yyval.inst = new VS10Inst( get_linenum(), yyvsp[-5].ival, yyvsp[-4].reg, yyvsp[-2].reg, yyvsp[0].reg ); + ;} break; case 34: #line 334 "vs1.0_grammar.y" { - yyval.inst = new VS10Inst( get_linenum(), yyvsp[-7].ival, yyvsp[-6].reg, yyvsp[-4].reg, yyvsp[-2].reg, yyvsp[0].reg ); - ;} + yyval.inst = new VS10Inst( get_linenum(), yyvsp[-7].ival, yyvsp[-6].reg, yyvsp[-4].reg, yyvsp[-2].reg, yyvsp[0].reg ); + ;} break; case 35: #line 340 "vs1.0_grammar.y" { - yyval.ival = VS10_MOV; - ;} + yyval.ival = VS10_MOV; + ;} break; case 36: #line 344 "vs1.0_grammar.y" { - yyval.ival = VS10_LIT; - ;} + yyval.ival = VS10_LIT; + ;} break; case 37: #line 350 "vs1.0_grammar.y" { - yyval.ival = VS10_RCP; - ;} + yyval.ival = VS10_RCP; + ;} break; case 38: #line 354 "vs1.0_grammar.y" { - yyval.ival = VS10_RSQ; - ;} + yyval.ival = VS10_RSQ; + ;} break; case 39: #line 358 "vs1.0_grammar.y" { - yyval.ival = VS10_EXP; - ;} + yyval.ival = VS10_EXP; + ;} break; case 40: #line 362 "vs1.0_grammar.y" { - yyval.ival = VS10_EXPP; - ;} + yyval.ival = VS10_EXPP; + ;} break; case 41: #line 366 "vs1.0_grammar.y" { - yyval.ival = VS10_LOG; - ;} + yyval.ival = VS10_LOG; + ;} break; case 42: #line 370 "vs1.0_grammar.y" { - yyval.ival = VS10_LOGP; - ;} + yyval.ival = VS10_LOGP; + ;} break; case 43: #line 376 "vs1.0_grammar.y" { - yyval.ival = VS10_FRC; - ;} + yyval.ival = VS10_FRC; + ;} break; case 44: #line 382 "vs1.0_grammar.y" { - yyval.ival = VS10_MUL; - ;} + yyval.ival = VS10_MUL; + ;} break; case 45: #line 386 "vs1.0_grammar.y" { - yyval.ival = VS10_ADD; - ;} + yyval.ival = VS10_ADD; + ;} break; case 46: #line 390 "vs1.0_grammar.y" { - yyval.ival = VS10_DP3; - ;} + yyval.ival = VS10_DP3; + ;} break; case 47: #line 394 "vs1.0_grammar.y" { - yyval.ival = VS10_DP4; - ;} + yyval.ival = VS10_DP4; + ;} break; case 48: #line 398 "vs1.0_grammar.y" { - yyval.ival = VS10_DST; - ;} + yyval.ival = VS10_DST; + ;} break; case 49: #line 402 "vs1.0_grammar.y" { - yyval.ival = VS10_MIN; - ;} + yyval.ival = VS10_MIN; + ;} break; case 50: #line 406 "vs1.0_grammar.y" { - yyval.ival = VS10_MAX; - ;} + yyval.ival = VS10_MAX; + ;} break; case 51: #line 410 "vs1.0_grammar.y" { - yyval.ival = VS10_SLT; - ;} + yyval.ival = VS10_SLT; + ;} break; case 52: #line 414 "vs1.0_grammar.y" { - yyval.ival = VS10_SGE; - ;} + yyval.ival = VS10_SGE; + ;} break; case 53: #line 418 "vs1.0_grammar.y" { - yyval.ival = VS10_M3X2; - ;} + yyval.ival = VS10_M3X2; + ;} break; case 54: #line 422 "vs1.0_grammar.y" { - yyval.ival = VS10_M3X3; - ;} + yyval.ival = VS10_M3X3; + ;} break; case 55: #line 426 "vs1.0_grammar.y" { - yyval.ival = VS10_M3X4; - ;} + yyval.ival = VS10_M3X4; + ;} break; case 56: #line 430 "vs1.0_grammar.y" { - yyval.ival = VS10_M4X3; - ;} + yyval.ival = VS10_M4X3; + ;} break; case 57: #line 434 "vs1.0_grammar.y" { - yyval.ival = VS10_M4X4; - ;} + yyval.ival = VS10_M4X4; + ;} break; case 58: #line 438 "vs1.0_grammar.y" { - yyval.ival = VS10_SUB; - ;} + yyval.ival = VS10_SUB; + ;} break; case 59: #line 444 "vs1.0_grammar.y" { - yyval.ival = VS10_MAD; - ;} + yyval.ival = VS10_MAD; + ;} break; @@ -1701,50 +1701,50 @@ yyparse () yyn = yypact[yystate]; if (YYPACT_NINF < yyn && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("syntax error, unexpected ") + 1; - yysize += yystrlen (yytname[yytype]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); - - if (yycount < 5) - { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("syntax error; also virtual memory exhausted"); - } + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("syntax error, unexpected ") + 1; + yysize += yystrlen (yytname[yytype]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } else #endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); + yyerror ("syntax error"); } @@ -1752,21 +1752,21 @@ yyparse () if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + error, discard it. */ /* Return failure if at end of input. */ if (yychar == YYEOF) { - /* Pop the error token. */ + /* Pop the error token. */ + YYPOPSTACK; + /* Pop the rest of the stack. */ + while (yyss < yyssp) + { + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); YYPOPSTACK; - /* Pop the rest of the stack. */ - while (yyss < yyssp) - { - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - YYPOPSTACK; - } - YYABORT; + } + YYABORT; } YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); @@ -1784,25 +1784,25 @@ yyparse () | yyerrlab1 -- error raised explicitly by an action. | `----------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); yydestruct (yystos[yystate], yyvsp); diff --git a/RenderSystems/GL/src/nvparse/avp1.0_impl.cpp b/RenderSystems/GL/src/nvparse/avp1.0_impl.cpp index 0eff7123f90..03caef44140 100644 --- a/RenderSystems/GL/src/nvparse/avp1.0_impl.cpp +++ b/RenderSystems/GL/src/nvparse/avp1.0_impl.cpp @@ -14,39 +14,39 @@ using namespace std; namespace { - void LoadProgram( GLenum target, GLuint id, char *instring ); - GLint vpid; + void LoadProgram( GLenum target, GLuint id, char *instring ); + GLint vpid; } bool is_avp10(const char * s) { - return ! strncmp(s, "!!ARBvp1.0", 10); + return ! strncmp(s, "!!ARBvp1.0", 10); } bool avp10_init(char * s) { - static bool avpinit = false; - if (avpinit == false ) - { + static bool avpinit = false; + if (avpinit == false ) + { /* - if(! glh_init_extensions("GL_ARB_vertex_program")) - { - errors.set("unable to initialize GL_ARB_vertex_program"); - return false; - } - else - { + if(! glh_init_extensions("GL_ARB_vertex_program")) + { + errors.set("unable to initialize GL_ARB_vertex_program"); + return false; + } + else + { */ - avpinit = true; + avpinit = true; /* - } + } */ - } - - errors.reset(); - line_number = 1; - myin = s; + } + + errors.reset(); + line_number = 1; + myin = s; glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_BINDING_ARB, &vpid); @@ -55,26 +55,26 @@ bool avp10_init(char * s) char str[128]; sprintf( str, "No vertex program id bound for nvparse() invocation. Bound id = %d\n", (int)vpid ); errors.set( str ); - return false; + return false; } - - return true; + + return true; } int avp10_parse() { LoadProgram( GL_VERTEX_PROGRAM_ARB, vpid, myin ); - return 0; + return 0; } namespace { - //.----------------------------------------------------------------------------. - //| Function : LoadProgram | - //| Description: Load a program into GL, and report any errors encountered. | - //.----------------------------------------------------------------------------. - void LoadProgram( GLenum target, GLuint id, char *instring ) - { + //.----------------------------------------------------------------------------. + //| Function : LoadProgram | + //| Description: Load a program into GL, and report any errors encountered. | + //.----------------------------------------------------------------------------. + void LoadProgram( GLenum target, GLuint id, char *instring ) + { GLint errPos; GLenum errCode; int len = strlen(instring); @@ -87,84 +87,84 @@ namespace len, instring); - if ((errCode = glGetError()) != GL_NO_ERROR) - { - glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos); + if ((errCode = glGetError()) != GL_NO_ERROR) + { + glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos); if (errPos == -1) return; - - int nlines = 1; - int nchar = 1; - int i; - for (i = 0; i < errPos; i++) - { - if (instring[i] == '\n') - { - nlines++; - nchar = 1; - } - else - { - nchar++; - } - } - int start = 0; - int end = 0; - int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0; - for (i = errPos; i >= 0; i--) - { - start = i; - if (flag && (start >= errPos-1)) - continue; - if (instring[i] == ';') - { - if (!flag) - { - start = i+1; - if (instring[start] == '\n') - start++; - } - break; - } - } - for (i = errPos; i < len; i++) - { - end = i; - if (instring[i] == ';' && end > start) - { - break; - } - } - if (errPos - start > 30) - { - start = errPos - 30; - } - if (end - errPos > 30) - { - end = errPos + 30; - } - - char substring[96]; - memset( substring, 0, 96 ); - strncpy( substring, &(instring[start]), end-start+1 ); + + int nlines = 1; + int nchar = 1; + int i; + for (i = 0; i < errPos; i++) + { + if (instring[i] == '\n') + { + nlines++; + nchar = 1; + } + else + { + nchar++; + } + } + int start = 0; + int end = 0; + int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0; + for (i = errPos; i >= 0; i--) + { + start = i; + if (flag && (start >= errPos-1)) + continue; + if (instring[i] == ';') + { + if (!flag) + { + start = i+1; + if (instring[start] == '\n') + start++; + } + break; + } + } + for (i = errPos; i < len; i++) + { + end = i; + if (instring[i] == ';' && end > start) + { + break; + } + } + if (errPos - start > 30) + { + start = errPos - 30; + } + if (end - errPos > 30) + { + end = errPos + 30; + } + + char substring[96]; + memset( substring, 0, 96 ); + strncpy( substring, &(instring[start]), end-start+1 ); char str[256]; - sprintf(str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring); - int width = errPos-start; + sprintf(str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring); + int width = errPos-start; - for (i = 0; i < width; i++) - { - strcat(str, " "); - } + for (i = 0; i < width; i++) + { + strcat(str, " "); + } - strcat(str, "|\n"); - for (i = 0; i < width; i++) - { - strcat(str, " "); - } - strcat(str, "^\n"); - - errors.set(str); - } - } + strcat(str, "|\n"); + for (i = 0; i < width; i++) + { + strcat(str, " "); + } + strcat(str, "^\n"); + + errors.set(str); + } + } } diff --git a/RenderSystems/GL/src/nvparse/macro.h b/RenderSystems/GL/src/nvparse/macro.h index 69c2b59c08d..2e0e359f3e8 100644 --- a/RenderSystems/GL/src/nvparse/macro.h +++ b/RenderSystems/GL/src/nvparse/macro.h @@ -4,40 +4,40 @@ #include #endif typedef struct MACROTEXT { - MACROTEXT *next; - MACROTEXT *prev; - char *macroText; + MACROTEXT *next; + MACROTEXT *prev; + char *macroText; } MACROTEXT; typedef struct MACROENTRY { - MACROENTRY *next; - MACROENTRY *prev; - char *macroName; - MACROTEXT *firstMacroParms; - MACROTEXT *lastMacroParms; - MACROTEXT *firstMacroLines; - MACROTEXT *lastMacroLines; - unsigned int numParms; - char *fileName; - unsigned int lineNo; - unsigned int nLines; - bool bIsDefine; + MACROENTRY *next; + MACROENTRY *prev; + char *macroName; + MACROTEXT *firstMacroParms; + MACROTEXT *lastMacroParms; + MACROTEXT *firstMacroLines; + MACROTEXT *lastMacroLines; + unsigned int numParms; + char *fileName; + unsigned int lineNo; + unsigned int nLines; + bool bIsDefine; } MACROENTRY; #define MAX_IFDEF_DEPTH 1024 typedef struct IFDEFINFO { - bool lastbProcessingIFDEF; // save off for if we were processing #ifdef - bool lastbIFDEF; // wether ifdef was true or not - bool lastbCompareDefine; // wether we compare #ifdef or #ifndef - unsigned int lastIfDefStartLine; // where we started for this #ifdef + bool lastbProcessingIFDEF; // save off for if we were processing #ifdef + bool lastbIFDEF; // wether ifdef was true or not + bool lastbCompareDefine; // wether we compare #ifdef or #ifndef + unsigned int lastIfDefStartLine; // where we started for this #ifdef } IFDEFINFO; typedef void (*MACROFUNCTIONPTR)(char *, unsigned int *, char **); typedef struct MACROFUNCTIONS { - const char *name; - MACROFUNCTIONPTR function; + const char *name; + MACROFUNCTIONPTR function; } MACROFUNCTIONS; diff --git a/RenderSystems/GL/src/nvparse/nvparse.cpp b/RenderSystems/GL/src/nvparse/nvparse.cpp index 07cce0903d3..8c3ec3d79db 100644 --- a/RenderSystems/GL/src/nvparse/nvparse.cpp +++ b/RenderSystems/GL/src/nvparse/nvparse.cpp @@ -1,7 +1,7 @@ #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # if !defined(NOMINMAX) && defined(_MSC_VER) -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif # include #else diff --git a/RenderSystems/GL/src/nvparse/nvparse_errors.cpp b/RenderSystems/GL/src/nvparse/nvparse_errors.cpp index 69af5960746..0f71957c5bf 100644 --- a/RenderSystems/GL/src/nvparse/nvparse_errors.cpp +++ b/RenderSystems/GL/src/nvparse/nvparse_errors.cpp @@ -8,40 +8,40 @@ nvparse_errors::nvparse_errors() { - num_errors = 0; - reset(); + num_errors = 0; + reset(); } nvparse_errors::~nvparse_errors() { - reset(); + reset(); } void nvparse_errors::reset() { - for(int i=0; i < num_errors; i++) - free(elist[i]);//FIXME detail_nmap something is writing 0x2 to elist[1] blah! - for(int j=0; j <= NVPARSE_MAX_ERRORS; j++) - elist[j] = 0; - num_errors = 0; + for(int i=0; i < num_errors; i++) + free(elist[i]);//FIXME detail_nmap something is writing 0x2 to elist[1] blah! + for(int j=0; j <= NVPARSE_MAX_ERRORS; j++) + elist[j] = 0; + num_errors = 0; } void nvparse_errors::set(const char * e) { - if(num_errors < NVPARSE_MAX_ERRORS) - elist[num_errors++] = strdup(e); + if(num_errors < NVPARSE_MAX_ERRORS) + elist[num_errors++] = strdup(e); } void nvparse_errors::set(const char * e, int line_number) { - char buff[256]; - sprintf(buff, "error on line %d: %s", line_number, e); - if(num_errors < NVPARSE_MAX_ERRORS) - elist[num_errors++] = strdup(buff); + char buff[256]; + sprintf(buff, "error on line %d: %s", line_number, e); + if(num_errors < NVPARSE_MAX_ERRORS) + elist[num_errors++] = strdup(buff); } char** nvparse_errors::get_errors() { - return elist; + return elist; } diff --git a/RenderSystems/GL/src/nvparse/nvparse_errors.h b/RenderSystems/GL/src/nvparse/nvparse_errors.h index 23ed5999b30..5426dac7936 100644 --- a/RenderSystems/GL/src/nvparse/nvparse_errors.h +++ b/RenderSystems/GL/src/nvparse/nvparse_errors.h @@ -9,17 +9,17 @@ class nvparse_errors { public: - nvparse_errors(); - ~nvparse_errors(); + nvparse_errors(); + ~nvparse_errors(); - void reset(); - void set(const char * e); - void set(const char * e, int line_number); - char** get_errors(); + void reset(); + void set(const char * e); + void set(const char * e, int line_number); + char** get_errors(); inline int get_num_errors() { return num_errors; } private: char* elist [NVPARSE_MAX_ERRORS+1]; - int num_errors; + int num_errors; }; #endif diff --git a/RenderSystems/GL/src/nvparse/ps1.0__test_main.cpp b/RenderSystems/GL/src/nvparse/ps1.0__test_main.cpp index 9f8e32eefd6..7b9a5b18d47 100644 --- a/RenderSystems/GL/src/nvparse/ps1.0__test_main.cpp +++ b/RenderSystems/GL/src/nvparse/ps1.0__test_main.cpp @@ -43,66 +43,66 @@ char * const * const nvparse_print_errors(FILE * errfp) char * read_input_file(string filename) { - char buf[256]; - FILE * fp = fopen(filename.c_str(), "rb"); - if(! fp) - return 0; - string result; - while(fgets(buf, 255, fp) > 0) - { - result += buf; - } - fclose(fp); - char * r = new char[result.size()+1]; - strcpy(r, result.c_str()); - return r; + char buf[256]; + FILE * fp = fopen(filename.c_str(), "rb"); + if(! fp) + return 0; + string result; + while(fgets(buf, 255, fp) > 0) + { + result += buf; + } + fclose(fp); + char * r = new char[result.size()+1]; + strcpy(r, result.c_str()); + return r; } int main(int argc, char **argv) { /* - char test_string[] = - "Ps.1.0 \n\n\n" - "def c0, 0.4, 1, 0, .2 ; diffuse \n" - "def c7, .3, .2, .1, 0 \n \n" - " \n" - "add r0, t0_bias, r1_bx2 \n" - "cnd r0, r0.a, t0, r1 \n" - "dp3 r0, t0, r1 \n" - "lrp r0, t0.a, t0, r1 \n" - "mad r0, t0.a, t0, r1 \n" - "mov r0.a, -r1.a \n" - "mul r0, t0, r1 \n" - "sub r0, t0, r1 \n" - ; + char test_string[] = + "Ps.1.0 \n\n\n" + "def c0, 0.4, 1, 0, .2 ; diffuse \n" + "def c7, .3, .2, .1, 0 \n \n" + " \n" + "add r0, t0_bias, r1_bx2 \n" + "cnd r0, r0.a, t0, r1 \n" + "dp3 r0, t0, r1 \n" + "lrp r0, t0.a, t0, r1 \n" + "mad r0, t0.a, t0, r1 \n" + "mov r0.a, -r1.a \n" + "mul r0, t0, r1 \n" + "sub r0, t0, r1 \n" + ; */ /* - char test_string[] = - "Ps.1.0 \n" - "def c0, 0.4, 1, 0, .2 \n" - "def c7, .3, .2, .1, 0 \n" - "add r0, t0_bias, r1_bx2 \n" - "cnd r0, r0.a, t0, r1 \n" - "dp3 r0, t0, r1 \n" - "lrp r0, t0.a, t0, r1 \n" - "mad r0, t0.a, t0, r1 \n" - "mov r0.a, -r1.a \n" - "mul r0, t0, r1 \n" - "sub r0, t0, r1 \n" - ; + char test_string[] = + "Ps.1.0 \n" + "def c0, 0.4, 1, 0, .2 \n" + "def c7, .3, .2, .1, 0 \n" + "add r0, t0_bias, r1_bx2 \n" + "cnd r0, r0.a, t0, r1 \n" + "dp3 r0, t0, r1 \n" + "lrp r0, t0.a, t0, r1 \n" + "mad r0, t0.a, t0, r1 \n" + "mov r0.a, -r1.a \n" + "mul r0, t0, r1 \n" + "sub r0, t0, r1 \n" + ; */ - char test_string[] = + char test_string[] = "ps.1.1\n" "tex t0\n" "mul r1, t0, c0\n" "mul r0, r1, v0\n" "// End of program\n" - ; + ; - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH|GLUT_RGB); - glutCreateWindow("test window"); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH|GLUT_RGB); + glutCreateWindow("test window"); char * str; if(argc == 2) @@ -114,22 +114,22 @@ int main(int argc, char **argv) str = test_string; } - line_number = 1; + line_number = 1; - ps10_init(str); + ps10_init(str); glNewList(GL_COMPILE_AND_EXECUTE, 1); - ps10_parse(); + ps10_parse(); glEndList(); char * err = (char *) gluErrorString(glGetError()); - errors.set("spacer..."); - nvparse_print_errors(stderr); + errors.set("spacer..."); + nvparse_print_errors(stderr); fprintf(stdout, "\n\nnvparse output: \n\n"); fprintf(stdout, state_to_rc10() ); - return 0; + return 0; } diff --git a/RenderSystems/GL/src/nvparse/ps1.0_program.cpp b/RenderSystems/GL/src/nvparse/ps1.0_program.cpp index f1ae9fa2f32..a6d7da8c084 100644 --- a/RenderSystems/GL/src/nvparse/ps1.0_program.cpp +++ b/RenderSystems/GL/src/nvparse/ps1.0_program.cpp @@ -14,133 +14,133 @@ using namespace std; using namespace ps10; struct ltstr { - bool operator()(const char* s1, const char* s2) const - { - return strcmp(s1, s2) < 0; - } + bool operator()(const char* s1, const char* s2) const + { + return strcmp(s1, s2) < 0; + } }; -#define DBG_MESG(msg, line) errors.set(msg, line) +#define DBG_MESG(msg, line) errors.set(msg, line) //#define DBG_MESG(msg, line) namespace ps10 { - std::map > constToStageAndConstMap; - std::vector constToStageArray; - std::map stageToConstMap; // to keep track of which constants have been used up for this stage. - // r-value of 0 means none, r-value of 1 means c0 used, and r-value of 2 means both used. - //std::map constToStageMap; - std::map stageToTargetMap; - std::set alphaBlueRegisters; // Keeps track of whether the result of a register - // was a dp3, if a register is in this set, it means that if it is used a source for the alpha - // component the blue component should be used, and not the alpha component. - void SetFinalCombinerStage(); + std::map > constToStageAndConstMap; + std::vector constToStageArray; + std::map stageToConstMap; // to keep track of which constants have been used up for this stage. + // r-value of 0 means none, r-value of 1 means c0 used, and r-value of 2 means both used. + //std::map constToStageMap; + std::map stageToTargetMap; + std::set alphaBlueRegisters; // Keeps track of whether the result of a register + // was a dp3, if a register is in this set, it means that if it is used a source for the alpha + // component the blue component should be used, and not the alpha component. + void SetFinalCombinerStage(); } void RemoveFromAlphaBlue(std::string s) { - std::set::iterator iter = - ps10::alphaBlueRegisters.find(s.c_str()); - if (iter != alphaBlueRegisters.end()) - alphaBlueRegisters.erase(iter); + std::set::iterator iter = + ps10::alphaBlueRegisters.find(s.c_str()); + if (iter != alphaBlueRegisters.end()) + alphaBlueRegisters.erase(iter); } /* void AddToMap(string s, int stage) { - const char* cstr = s.c_str(); - if (cstr[0] == 'c') - { - int constNum = atoi(&cstr[1]); - if (constNum < 0 || constNum > 7) - return; - constToStageMap[constNum] = stage; - } + const char* cstr = s.c_str(); + if (cstr[0] == 'c') + { + int constNum = atoi(&cstr[1]); + if (constNum < 0 || constNum > 7) + return; + constToStageMap[constNum] = stage; + } } */ bool AddToMap(string s, int stage, GLenum& constVal) { - const char* cstr = s.c_str(); - if (cstr[0] == 'c') - { - int constNum = atoi(&cstr[1]); - std::map::iterator iter = stageToConstMap.find(stage); - if (iter == stageToConstMap.end()) - { - // no constants used for this stage. - std::pair temp; - temp.first = stage; - temp.second = 0; - constToStageAndConstMap[constNum] = temp; - stageToConstMap[stage] = 0; - constVal = 0; - constToStageArray.push_back(constNum); - constToStageArray.push_back(stage); - constToStageArray.push_back(constVal); - } - else - { - int constUsed = (*iter).second; - if (constUsed >= 1) - return false; - else // const0 has been used, so use const1 for this stage. - { - std::pair temp; - temp.first = stage; - temp.second = 1; - constToStageAndConstMap[constNum] = temp; - stageToConstMap[stage] = 1; - constVal = 1; - constToStageArray.push_back(constNum); - constToStageArray.push_back(stage); - constToStageArray.push_back(constVal); - } - - } - } - constVal += GL_CONSTANT_COLOR0_NV; - return true; + const char* cstr = s.c_str(); + if (cstr[0] == 'c') + { + int constNum = atoi(&cstr[1]); + std::map::iterator iter = stageToConstMap.find(stage); + if (iter == stageToConstMap.end()) + { + // no constants used for this stage. + std::pair temp; + temp.first = stage; + temp.second = 0; + constToStageAndConstMap[constNum] = temp; + stageToConstMap[stage] = 0; + constVal = 0; + constToStageArray.push_back(constNum); + constToStageArray.push_back(stage); + constToStageArray.push_back(constVal); + } + else + { + int constUsed = (*iter).second; + if (constUsed >= 1) + return false; + else // const0 has been used, so use const1 for this stage. + { + std::pair temp; + temp.first = stage; + temp.second = 1; + constToStageAndConstMap[constNum] = temp; + stageToConstMap[stage] = 1; + constVal = 1; + constToStageArray.push_back(constNum); + constToStageArray.push_back(stage); + constToStageArray.push_back(constVal); + } + + } + } + constVal += GL_CONSTANT_COLOR0_NV; + return true; } bool IsLegalTarget(int target) { - if (target == GL_TEXTURE_CUBE_MAP_ARB) - return true; - if (target == GL_TEXTURE_3D) - return true; + if (target == GL_TEXTURE_CUBE_MAP_ARB) + return true; + if (target == GL_TEXTURE_3D) + return true; #if defined(GL_EXT_texture_rectangle) - if (target == GL_TEXTURE_RECTANGLE_EXT) - return true; + if (target == GL_TEXTURE_RECTANGLE_EXT) + return true; #elif defined(GL_NV_texture_rectangle) if (target == GL_TEXTURE_RECTANGLE_NV) return true; #endif - if (target == GL_TEXTURE_2D) - return true; - if (target == GL_TEXTURE_1D) - return true; - return false; + if (target == GL_TEXTURE_2D) + return true; + if (target == GL_TEXTURE_1D) + return true; + return false; } bool ps10_set_map(const std::vector& argv) { - if (argv.size() % 2 != 0) - { - errors.set("Odd number of arguments for texture target map."); - return false; - } - for (unsigned int i=0;i::iterator iter = stageToTargetMap.find(stage); - if (iter != stageToTargetMap.end()) - return (*iter).second; - // If no mapping set, use the current state. This will not work correctly, in general, - // if nvparse was invoked within a display list. - if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB)) - return GL_TEXTURE_CUBE_MAP_ARB; - if(glIsEnabled(GL_TEXTURE_3D)) - return GL_TEXTURE_3D; + struct set_constants + { + void operator() (constdef c) + { + if(c.reg[0] != 'c' && c.reg.size() != 2) + DBG_MESG("def line must use constant registers", 0); + int reg = c.reg[1] - '0'; + GLenum stage = GL_COMBINER0_NV + (reg / 2); + GLenum cclr = GL_CONSTANT_COLOR0_NV + (reg % 2); + + GLfloat cval[4]; + cval[0] = c.r; + cval[1] = c.g; + cval[2] = c.b; + cval[3] = c.a; + glCombinerStageParameterfvNV(stage, cclr, cval); + } + }; + + GLenum get_tex_target(int stage) + { + std::map::iterator iter = stageToTargetMap.find(stage); + if (iter != stageToTargetMap.end()) + return (*iter).second; + // If no mapping set, use the current state. This will not work correctly, in general, + // if nvparse was invoked within a display list. + if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB)) + return GL_TEXTURE_CUBE_MAP_ARB; + if(glIsEnabled(GL_TEXTURE_3D)) + return GL_TEXTURE_3D; #if defined(GL_EXT_texture_rectangle) - if(glIsEnabled(GL_TEXTURE_RECTANGLE_EXT)) - return GL_TEXTURE_RECTANGLE_EXT; + if(glIsEnabled(GL_TEXTURE_RECTANGLE_EXT)) + return GL_TEXTURE_RECTANGLE_EXT; #elif defined(GL_NV_texture_rectangle) if(glIsEnabled(GL_TEXTURE_RECTANGLE_NV)) return GL_TEXTURE_RECTANGLE_NV; #endif - if(glIsEnabled(GL_TEXTURE_2D)) - return GL_TEXTURE_2D; - if(glIsEnabled(GL_TEXTURE_1D)) - return GL_TEXTURE_1D; + if(glIsEnabled(GL_TEXTURE_2D)) + return GL_TEXTURE_2D; + if(glIsEnabled(GL_TEXTURE_1D)) + return GL_TEXTURE_1D; - //otherwise make the op none... - return GL_NONE; - } + //otherwise make the op none... + return GL_NONE; + } - + - struct set_texture_shaders - { - set_texture_shaders(vector * cdef) - { + struct set_texture_shaders + { + set_texture_shaders(vector * cdef) + { GLint activeTex = 0; glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); - for(stage = 0; stage < 4; stage++) - { - glActiveTextureARB(GL_TEXTURE0_ARB + stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE); - } - stage = 0; - c = cdef; + for(stage = 0; stage < 4; stage++) + { + glActiveTextureARB(GL_TEXTURE0_ARB + stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE); + } + stage = 0; + c = cdef; glActiveTextureARB(activeTex); - } + } - void operator() (vector & instr) - { - if(stage > 3) - return; + void operator() (vector & instr) + { + if(stage > 3) + return; GLint activeTex = 0; glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); - glActiveTextureARB(GL_TEXTURE0_ARB + stage); - - string op = instr[0]; - if(op == "tex") - { - if(instr.size() != 2) - fprintf(stderr,"incorrect \"tex\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, get_tex_target(stage)); - } - else if(op == "texbem") - { - if(instr.size() != 3 || stage == 0) - fprintf(stderr,"incorrect \"texbem\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV); - if(reg2stage.count(instr[2]) == 0) - fprintf(stderr,"incorrect \"texbem\" instruction, stage %d...\n", stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); - } - else if(op == "texbeml") - { - if(instr.size() != 3 || stage == 0) - fprintf(stderr,"incorrect \"texbeml\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_SCALE_NV); - if(reg2stage.count(instr[2]) == 0) - fprintf(stderr,"incorrect \"texbeml\" instruction, stage %d...\n", stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); - } - else if(op == "texcoord") - { - if(instr.size() != 2) - fprintf(stderr,"incorrect \"texcoord\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_PASS_THROUGH_NV); - } - else if(op == "texkill") - { - if(instr.size() != 2) - fprintf(stderr,"incorrect \"texkill\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_CULL_FRAGMENT_NV); - } - else if(op == "texm3x2pad") - { - if(instr.size() != 3 || stage == 0) - fprintf(stderr,"incorrect \"texm3x2pad\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - if(instr[2].find("_bx2") != string::npos) - { - instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - } - if(reg2stage.count(instr[2]) == 0) - fprintf(stderr,"incorrect \"texm3x2pad\" instruction, stage %d...\n", stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); - } - else if(op == "texm3x2tex") - { - if(instr.size() != 3 || stage == 0) - fprintf(stderr,"incorrect \"texm3x2tex\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV); - if(instr[2].find("_bx2") != string::npos) - { - instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - } - if(reg2stage.count(instr[2]) == 0) - fprintf(stderr,"incorrect \"texm3x2tex\" instruction, stage %d...\n", stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); - } - else if(op == "texm3x3pad") - { - if(instr.size() != 3 || stage == 0) - fprintf(stderr,"incorrect \"texm3x3pad\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - if(instr[2].find("_bx2") != string::npos) - { - instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - } - if(reg2stage.count(instr[2]) == 0) - fprintf(stderr,"incorrect \"texm3x3pad\" instruction, stage %d...\n", stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); - } - else if(op == "texm3x3tex") - { - if(instr.size() != 3 || stage == 0) - fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV); - - if(instr[2].find("_bx2") != string::npos) - { - instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - } - if(reg2stage.count(instr[2]) == 0) - fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); - } - else if(op == "texm3x3spec") - { - if(instr.size() != 4 || stage == 0) - fprintf(stderr,"incorrect \"texm3x3spec\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - - if(! c) - return; - constdef cd; - for(int i = c->size()-1; i >= 0; i--) - { - cd = (*c)[i]; - if(cd.reg == "c0") - break; - } - - if(cd.reg != "c0" || instr[3] != "c0") - return; - GLfloat eye[4]; - eye[0] = cd.r; - eye[1] = cd.g; - eye[2] = cd.b; - eye[3] = cd.a; - - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV); - glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, eye); - - if(instr[2].find("_bx2") != string::npos) - { - instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - } - if(reg2stage.count(instr[2]) == 0) - fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); - } - else if(op == "texm3x3vspec") - { - if(instr.size() != 3 || stage == 0) - fprintf(stderr,"incorrect \"texm3x3vspec\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV); - - if(instr[2].find("_bx2") != string::npos) - { - instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - } - if(reg2stage.count(instr[2]) == 0) - fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); - } - else if(op == "texreg2ar") - { - if(instr.size() != 3 || stage == 0) - fprintf(stderr,"incorrect \"texreg2ar\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_AR_TEXTURE_2D_NV); - if(reg2stage.count(instr[2]) == 0) - fprintf(stderr,"incorrect \"texreg2ar\" instruction, stage %d...\n", stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); - } - else if(op == "texreg2gb") - { - if(instr.size() != 3 || stage == 0) - fprintf(stderr,"incorrect \"texreg2gb\" instruction, stage %d...\n", stage); - reg2stage[instr[1]] = stage; - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV); - if(reg2stage.count(instr[2]) == 0) - fprintf(stderr,"incorrect \"texreg2gb\" instruction, stage %d...\n", stage); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); - } - stage++; + glActiveTextureARB(GL_TEXTURE0_ARB + stage); + + string op = instr[0]; + if(op == "tex") + { + if(instr.size() != 2) + fprintf(stderr,"incorrect \"tex\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, get_tex_target(stage)); + } + else if(op == "texbem") + { + if(instr.size() != 3 || stage == 0) + fprintf(stderr,"incorrect \"texbem\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV); + if(reg2stage.count(instr[2]) == 0) + fprintf(stderr,"incorrect \"texbem\" instruction, stage %d...\n", stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); + } + else if(op == "texbeml") + { + if(instr.size() != 3 || stage == 0) + fprintf(stderr,"incorrect \"texbeml\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_SCALE_NV); + if(reg2stage.count(instr[2]) == 0) + fprintf(stderr,"incorrect \"texbeml\" instruction, stage %d...\n", stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); + } + else if(op == "texcoord") + { + if(instr.size() != 2) + fprintf(stderr,"incorrect \"texcoord\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_PASS_THROUGH_NV); + } + else if(op == "texkill") + { + if(instr.size() != 2) + fprintf(stderr,"incorrect \"texkill\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_CULL_FRAGMENT_NV); + } + else if(op == "texm3x2pad") + { + if(instr.size() != 3 || stage == 0) + fprintf(stderr,"incorrect \"texm3x2pad\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + if(instr[2].find("_bx2") != string::npos) + { + instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + } + if(reg2stage.count(instr[2]) == 0) + fprintf(stderr,"incorrect \"texm3x2pad\" instruction, stage %d...\n", stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); + } + else if(op == "texm3x2tex") + { + if(instr.size() != 3 || stage == 0) + fprintf(stderr,"incorrect \"texm3x2tex\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV); + if(instr[2].find("_bx2") != string::npos) + { + instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + } + if(reg2stage.count(instr[2]) == 0) + fprintf(stderr,"incorrect \"texm3x2tex\" instruction, stage %d...\n", stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); + } + else if(op == "texm3x3pad") + { + if(instr.size() != 3 || stage == 0) + fprintf(stderr,"incorrect \"texm3x3pad\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + if(instr[2].find("_bx2") != string::npos) + { + instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + } + if(reg2stage.count(instr[2]) == 0) + fprintf(stderr,"incorrect \"texm3x3pad\" instruction, stage %d...\n", stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); + } + else if(op == "texm3x3tex") + { + if(instr.size() != 3 || stage == 0) + fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV); + + if(instr[2].find("_bx2") != string::npos) + { + instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + } + if(reg2stage.count(instr[2]) == 0) + fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); + } + else if(op == "texm3x3spec") + { + if(instr.size() != 4 || stage == 0) + fprintf(stderr,"incorrect \"texm3x3spec\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + + if(! c) + return; + constdef cd; + for(int i = c->size()-1; i >= 0; i--) + { + cd = (*c)[i]; + if(cd.reg == "c0") + break; + } + + if(cd.reg != "c0" || instr[3] != "c0") + return; + GLfloat eye[4]; + eye[0] = cd.r; + eye[1] = cd.g; + eye[2] = cd.b; + eye[3] = cd.a; + + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV); + glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, eye); + + if(instr[2].find("_bx2") != string::npos) + { + instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + } + if(reg2stage.count(instr[2]) == 0) + fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); + } + else if(op == "texm3x3vspec") + { + if(instr.size() != 3 || stage == 0) + fprintf(stderr,"incorrect \"texm3x3vspec\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV); + + if(instr[2].find("_bx2") != string::npos) + { + instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end()); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + } + if(reg2stage.count(instr[2]) == 0) + fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); + } + else if(op == "texreg2ar") + { + if(instr.size() != 3 || stage == 0) + fprintf(stderr,"incorrect \"texreg2ar\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_AR_TEXTURE_2D_NV); + if(reg2stage.count(instr[2]) == 0) + fprintf(stderr,"incorrect \"texreg2ar\" instruction, stage %d...\n", stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); + } + else if(op == "texreg2gb") + { + if(instr.size() != 3 || stage == 0) + fprintf(stderr,"incorrect \"texreg2gb\" instruction, stage %d...\n", stage); + reg2stage[instr[1]] = stage; + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV); + if(reg2stage.count(instr[2]) == 0) + fprintf(stderr,"incorrect \"texreg2gb\" instruction, stage %d...\n", stage); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]); + } + stage++; glActiveTextureARB(activeTex); - } - - map reg2stage; - int stage; - vector * c; - }; - - GLenum reg_enum(string s, int stage) - { - /*if(s == "c0") - return GL_CONSTANT_COLOR0_NV; - else if(s == "c1") - return GL_CONSTANT_COLOR1_NV; - else if(s == "c2") - return GL_CONSTANT_COLOR0_NV; - else if(s == "c3") - return GL_CONSTANT_COLOR1_NV; - else if(s == "c4") - return GL_CONSTANT_COLOR0_NV; - else if(s == "c5") - return GL_CONSTANT_COLOR1_NV; - else if(s == "c6") - return GL_CONSTANT_COLOR0_NV; - else if(s == "c7") - return GL_CONSTANT_COLOR1_NV; - */ - if (s == "c0" || s == "c1" || s == "c2" || s == "c3" || - s == "c4" || s == "c5" || s == "c6" || s == "c7") - { - GLenum result; - if (!AddToMap(s,stage,result)) - errors.set("Illegal constant usage.",line_number); - // This is a pain, since the caller is a void and no check is made for errors. Sigh. - return result; - } - else if(s == "t0") - return GL_TEXTURE0_ARB; - else if(s == "t1") - return GL_TEXTURE1_ARB; - else if(s == "t2") - return GL_TEXTURE2_ARB; - else if(s == "t3") - return GL_TEXTURE3_ARB; - else if(s == "v0") - return GL_PRIMARY_COLOR_NV; - else if(s == "v1") - return GL_SECONDARY_COLOR_NV; - else if(s == "r0") - return GL_SPARE0_NV; - else if(s == "r1") - return GL_SPARE1_NV; - else // ?? - return GL_DISCARD_NV; - } - - struct src - { - src(string s, int stage, string *regname=NULL) - { - init(s, stage, regname); - } - - - void init(string s, int stage, string *regname=NULL) - { - arg = s; - comp = GL_RGB; + } + + map reg2stage; + int stage; + vector * c; + }; + + GLenum reg_enum(string s, int stage) + { + /*if(s == "c0") + return GL_CONSTANT_COLOR0_NV; + else if(s == "c1") + return GL_CONSTANT_COLOR1_NV; + else if(s == "c2") + return GL_CONSTANT_COLOR0_NV; + else if(s == "c3") + return GL_CONSTANT_COLOR1_NV; + else if(s == "c4") + return GL_CONSTANT_COLOR0_NV; + else if(s == "c5") + return GL_CONSTANT_COLOR1_NV; + else if(s == "c6") + return GL_CONSTANT_COLOR0_NV; + else if(s == "c7") + return GL_CONSTANT_COLOR1_NV; + */ + if (s == "c0" || s == "c1" || s == "c2" || s == "c3" || + s == "c4" || s == "c5" || s == "c6" || s == "c7") + { + GLenum result; + if (!AddToMap(s,stage,result)) + errors.set("Illegal constant usage.",line_number); + // This is a pain, since the caller is a void and no check is made for errors. Sigh. + return result; + } + else if(s == "t0") + return GL_TEXTURE0_ARB; + else if(s == "t1") + return GL_TEXTURE1_ARB; + else if(s == "t2") + return GL_TEXTURE2_ARB; + else if(s == "t3") + return GL_TEXTURE3_ARB; + else if(s == "v0") + return GL_PRIMARY_COLOR_NV; + else if(s == "v1") + return GL_SECONDARY_COLOR_NV; + else if(s == "r0") + return GL_SPARE0_NV; + else if(s == "r1") + return GL_SPARE1_NV; + else // ?? + return GL_DISCARD_NV; + } + + struct src + { + src(string s, int stage, string *regname=NULL) + { + init(s, stage, regname); + } + + + void init(string s, int stage, string *regname=NULL) + { + arg = s; + comp = GL_RGB; alphaComp = GL_ALPHA; - map = GL_SIGNED_IDENTITY_NV; + map = GL_SIGNED_IDENTITY_NV; - string::size_type offset; - if( + string::size_type offset; + if( (offset = s.find(".a")) != string::npos || (offset = s.find(".w")) != string::npos ) - { - comp = GL_ALPHA; - s.erase(offset, offset+2); - } + { + comp = GL_ALPHA; + s.erase(offset, offset+2); + } else if ((offset = s.find(".b")) != string::npos || (offset = s.find(".z")) != string::npos) { @@ -488,437 +488,437 @@ namespace s.erase(offset,offset+2); } - bool negate = false; - - if(s[0] == '1') - { - s.erase(0, 1); - while(s[0] == ' ') - s.erase(0,1); - if(s[0] == '-') - s.erase(0,1); - while(s[0] == ' ') - s.erase(0,1); - map = GL_UNSIGNED_INVERT_NV; - } - else if(s[0] == '-') - { - s.erase(0, 1); - while(s[0] == ' ') - s.erase(0,1); - negate = true; - map = GL_UNSIGNED_INVERT_NV; - } - - bool half_bias = false; - bool expand = false; - if(s.find("_bias") != string::npos) - { - s.erase(s.find("_bias"), 5); - half_bias = true; - } - else if(s.find("_bx2") != string::npos) - { - s.erase(s.find("_bx2"), 4); - expand = true; - } - - if(expand) - { - if(negate) - map = GL_EXPAND_NEGATE_NV; - else - map = GL_EXPAND_NORMAL_NV; - } - else if(half_bias) - { - if(negate) - map = GL_HALF_BIAS_NEGATE_NV; - else - map = GL_HALF_BIAS_NORMAL_NV; - } - reg = reg_enum(s,stage); - - if (regname != NULL) - *regname = s; // return the bare register name - - + bool negate = false; + + if(s[0] == '1') + { + s.erase(0, 1); + while(s[0] == ' ') + s.erase(0,1); + if(s[0] == '-') + s.erase(0,1); + while(s[0] == ' ') + s.erase(0,1); + map = GL_UNSIGNED_INVERT_NV; + } + else if(s[0] == '-') + { + s.erase(0, 1); + while(s[0] == ' ') + s.erase(0,1); + negate = true; + map = GL_UNSIGNED_INVERT_NV; + } + + bool half_bias = false; + bool expand = false; + if(s.find("_bias") != string::npos) + { + s.erase(s.find("_bias"), 5); + half_bias = true; + } + else if(s.find("_bx2") != string::npos) + { + s.erase(s.find("_bx2"), 4); + expand = true; + } + + if(expand) + { + if(negate) + map = GL_EXPAND_NEGATE_NV; + else + map = GL_EXPAND_NORMAL_NV; + } + else if(half_bias) + { + if(negate) + map = GL_HALF_BIAS_NEGATE_NV; + else + map = GL_HALF_BIAS_NORMAL_NV; + } + reg = reg_enum(s,stage); + + if (regname != NULL) + *regname = s; // return the bare register name + + //alphaComp = GL_ALPHA; - std::set::iterator iter = - ps10::alphaBlueRegisters.find(s.c_str()); - if (iter != ps10::alphaBlueRegisters.end()) - alphaComp = GL_BLUE; + std::set::iterator iter = + ps10::alphaBlueRegisters.find(s.c_str()); + if (iter != ps10::alphaBlueRegisters.end()) + alphaComp = GL_BLUE; - } + } - string arg; - GLenum reg; - GLenum map; - GLenum comp; - GLenum alphaComp; - }; + string arg; + GLenum reg; + GLenum map; + GLenum comp; + GLenum alphaComp; + }; - struct set_register_combiners - { - set_register_combiners() - { + struct set_register_combiners + { + set_register_combiners() + { // combiner = 0; combiner = -1; - } + } - void operator() (vector & instr) - { - string op; - GLenum scale = GL_NONE; + void operator() (vector & instr) + { + string op; + GLenum scale = GL_NONE; bool paired_instr = false; int instr_base = 0; if (instr[0]=="+") { paired_instr = true; instr_base = 1; } - op = instr[instr_base]; - string::size_type offset; - if((offset = op.find("_x2")) != string::npos) - { - scale = GL_SCALE_BY_TWO_NV; - op.erase(op.begin()+offset, op.begin()+offset+3); - } - else if((offset = op.find("_x4")) != string::npos) - { - scale = GL_SCALE_BY_FOUR_NV; - op.erase(op.begin()+offset, op.begin()+offset+3); - } - else if((offset = op.find("_d2")) != string::npos) - { - scale = GL_SCALE_BY_ONE_HALF_NV; - op.erase(op.begin()+offset, op.begin()+offset+3); - } - - if((offset = op.find("_sat")) != string::npos) - { - op.erase(op.begin()+offset, op.begin()+offset+4); - } - - string dst = instr[1+instr_base]; - int mask = GL_RGBA; - if( + op = instr[instr_base]; + string::size_type offset; + if((offset = op.find("_x2")) != string::npos) + { + scale = GL_SCALE_BY_TWO_NV; + op.erase(op.begin()+offset, op.begin()+offset+3); + } + else if((offset = op.find("_x4")) != string::npos) + { + scale = GL_SCALE_BY_FOUR_NV; + op.erase(op.begin()+offset, op.begin()+offset+3); + } + else if((offset = op.find("_d2")) != string::npos) + { + scale = GL_SCALE_BY_ONE_HALF_NV; + op.erase(op.begin()+offset, op.begin()+offset+3); + } + + if((offset = op.find("_sat")) != string::npos) + { + op.erase(op.begin()+offset, op.begin()+offset+4); + } + + string dst = instr[1+instr_base]; + int mask = GL_RGBA; + if( (offset = dst.find(".rgba")) != string::npos || (offset = dst.find(".xyzw")) != string::npos ) - { - dst.erase(offset, offset + 5); - } - else if( + { + dst.erase(offset, offset + 5); + } + else if( (offset = dst.find(".rgb")) != string::npos || (offset = dst.find(".xyz")) != string::npos ) - { - dst.erase(offset, offset + 4); - mask = GL_RGB; - } - else if( + { + dst.erase(offset, offset + 4); + mask = GL_RGB; + } + else if( (offset = dst.find(".a")) != string::npos || (offset = dst.find(".w")) != string::npos ) - { - dst.erase(offset, offset + 2); - mask = GL_ALPHA; - } + { + dst.erase(offset, offset + 2); + mask = GL_ALPHA; + } if (!paired_instr) combiner++; - GLenum dreg = reg_enum(dst,combiner); - GLenum C = GL_COMBINER0_NV + combiner; - - bool isAlphaBlue = false; // To keep track of whether the dst register's alpha was its blue value. - - if(op == "add" || op == "sub") - { - src a(instr[2+instr_base],combiner); - src b(instr[3+instr_base],combiner); - - if(mask == GL_RGBA || mask == GL_RGB) - { - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp); - if(op == "add") - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); - else - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_EXPAND_NORMAL_NV, GL_RGB); - glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - - if(mask == GL_RGBA || mask == GL_ALPHA) - { - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, b.alphaComp); - if(op == "add") - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); - else - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_EXPAND_NORMAL_NV, GL_ALPHA); - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - } - else if(op == "cnd") - { - src a(instr[3+instr_base],combiner); - src b(instr[4+instr_base],combiner); - - if(instr[2+instr_base] != "r0.a" && instr[2+instr_base] != "r0.w") - {} // bad - if(mask == GL_RGBA || mask == GL_RGB) - { - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); - glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_TRUE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - - if(mask == GL_RGBA || mask == GL_ALPHA) - { - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, b.alphaComp); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_TRUE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - } - else if(op == "dp3") - { - src a(instr[2+instr_base],combiner); - src b(instr[3+instr_base],combiner); - - if(mask == GL_RGBA || mask == GL_RGB) - { - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp); - glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE, - GL_TRUE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - // ooh.. what to do here? - } - - if(mask == GL_RGBA || mask == GL_ALPHA) - { - // todo -- make next ref to dst.a actually ref dst.b since combiners can't write dp3 to the alpha channel - // Done by Ashu: Put this register in the alphaBlueRegister set. - isAlphaBlue = true; - ps10::alphaBlueRegisters.insert(dst.c_str()); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - } - else if(op == "lrp") - { - src a(instr[2+instr_base],combiner); - src b(instr[3+instr_base],combiner); - src c(instr[4+instr_base],combiner); - - if(mask == GL_RGBA || mask == GL_RGB) - { - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, GL_UNSIGNED_IDENTITY_NV, a.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, a.reg, GL_UNSIGNED_INVERT_NV, a.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, c.reg, c.map, c.comp); - glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - - if(mask == GL_RGBA || mask == GL_ALPHA) - { - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, GL_UNSIGNED_IDENTITY_NV, a.alphaComp); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, a.reg, GL_UNSIGNED_INVERT_NV, a.alphaComp); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, c.reg, c.map, c.alphaComp); - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - } - else if(op == "mad") - { - src a(instr[2+instr_base],combiner); - src b(instr[3+instr_base],combiner); - src c(instr[4+instr_base],combiner); - - if(mask == GL_RGBA || mask == GL_RGB) - { - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, c.reg, c.map, c.comp); - glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - - if(mask == GL_RGBA || mask == GL_ALPHA) - { - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, c.reg, c.map, c.alphaComp); - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - } - else if(op == "mov") - { - src a(instr[2+instr_base],combiner); - - if(mask == GL_RGBA || mask == GL_RGB) - { - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); - glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - - if(mask == GL_RGBA || mask == GL_ALPHA) - { - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); - glCombinerOutputNV(C, GL_ALPHA, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - } - else if(op == "mul") - { - src a(instr[2+instr_base],combiner); - src b(instr[3+instr_base],combiner); - - if(mask == GL_RGBA || mask == GL_RGB) - { - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); - glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp); - glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - - if(mask == GL_RGBA || mask == GL_ALPHA) - { - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp); - glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp); - glCombinerOutputNV(C, GL_ALPHA, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - else if (!paired_instr) - { - glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, - GL_FALSE, GL_FALSE, GL_FALSE); - } - } + GLenum dreg = reg_enum(dst,combiner); + GLenum C = GL_COMBINER0_NV + combiner; + + bool isAlphaBlue = false; // To keep track of whether the dst register's alpha was its blue value. + + if(op == "add" || op == "sub") + { + src a(instr[2+instr_base],combiner); + src b(instr[3+instr_base],combiner); + + if(mask == GL_RGBA || mask == GL_RGB) + { + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp); + if(op == "add") + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); + else + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_EXPAND_NORMAL_NV, GL_RGB); + glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + + if(mask == GL_RGBA || mask == GL_ALPHA) + { + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, b.alphaComp); + if(op == "add") + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); + else + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_EXPAND_NORMAL_NV, GL_ALPHA); + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + } + else if(op == "cnd") + { + src a(instr[3+instr_base],combiner); + src b(instr[4+instr_base],combiner); + + if(instr[2+instr_base] != "r0.a" && instr[2+instr_base] != "r0.w") + {} // bad + if(mask == GL_RGBA || mask == GL_RGB) + { + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); + glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_TRUE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + + if(mask == GL_RGBA || mask == GL_ALPHA) + { + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, b.alphaComp); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_TRUE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + } + else if(op == "dp3") + { + src a(instr[2+instr_base],combiner); + src b(instr[3+instr_base],combiner); + + if(mask == GL_RGBA || mask == GL_RGB) + { + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp); + glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE, + GL_TRUE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + // ooh.. what to do here? + } + + if(mask == GL_RGBA || mask == GL_ALPHA) + { + // todo -- make next ref to dst.a actually ref dst.b since combiners can't write dp3 to the alpha channel + // Done by Ashu: Put this register in the alphaBlueRegister set. + isAlphaBlue = true; + ps10::alphaBlueRegisters.insert(dst.c_str()); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + } + else if(op == "lrp") + { + src a(instr[2+instr_base],combiner); + src b(instr[3+instr_base],combiner); + src c(instr[4+instr_base],combiner); + + if(mask == GL_RGBA || mask == GL_RGB) + { + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, GL_UNSIGNED_IDENTITY_NV, a.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, a.reg, GL_UNSIGNED_INVERT_NV, a.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, c.reg, c.map, c.comp); + glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + + if(mask == GL_RGBA || mask == GL_ALPHA) + { + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, GL_UNSIGNED_IDENTITY_NV, a.alphaComp); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, a.reg, GL_UNSIGNED_INVERT_NV, a.alphaComp); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, c.reg, c.map, c.alphaComp); + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + } + else if(op == "mad") + { + src a(instr[2+instr_base],combiner); + src b(instr[3+instr_base],combiner); + src c(instr[4+instr_base],combiner); + + if(mask == GL_RGBA || mask == GL_RGB) + { + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, c.reg, c.map, c.comp); + glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + + if(mask == GL_RGBA || mask == GL_ALPHA) + { + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, c.reg, c.map, c.alphaComp); + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + } + else if(op == "mov") + { + src a(instr[2+instr_base],combiner); + + if(mask == GL_RGBA || mask == GL_RGB) + { + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB); + glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + + if(mask == GL_RGBA || mask == GL_ALPHA) + { + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA); + glCombinerOutputNV(C, GL_ALPHA, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + } + else if(op == "mul") + { + src a(instr[2+instr_base],combiner); + src b(instr[3+instr_base],combiner); + + if(mask == GL_RGBA || mask == GL_RGB) + { + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp); + glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp); + glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + + if(mask == GL_RGBA || mask == GL_ALPHA) + { + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp); + glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp); + glCombinerOutputNV(C, GL_ALPHA, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + else if (!paired_instr) + { + glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, + GL_FALSE, GL_FALSE, GL_FALSE); + } + } // combiner++; - if (!isAlphaBlue) - RemoveFromAlphaBlue(dst); - } + if (!isAlphaBlue) + RemoveFromAlphaBlue(dst); + } - int combiner; - }; + int combiner; + }; } void ps10::SetFinalCombinerStage() { - glFinalCombinerInputNV(GL_VARIABLE_A_NV,GL_FOG,GL_UNSIGNED_IDENTITY_NV,GL_ALPHA); - glFinalCombinerInputNV(GL_VARIABLE_B_NV,GL_SPARE0_NV, - GL_UNSIGNED_IDENTITY_NV,GL_RGB); - glFinalCombinerInputNV(GL_VARIABLE_C_NV,GL_FOG,GL_UNSIGNED_IDENTITY_NV,GL_RGB); - glFinalCombinerInputNV(GL_VARIABLE_D_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB); - glFinalCombinerInputNV(GL_VARIABLE_E_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB); - glFinalCombinerInputNV(GL_VARIABLE_F_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB); - std::set::iterator iter = ps10::alphaBlueRegisters.find("r0"); - GLenum alphaComp = GL_ALPHA; - if (iter != ps10::alphaBlueRegisters.end()) - alphaComp = GL_BLUE; - glFinalCombinerInputNV(GL_VARIABLE_G_NV,GL_SPARE0_NV,GL_UNSIGNED_IDENTITY_NV,alphaComp); - // We can now clear alphaBlueRegisters for the next go around - alphaBlueRegisters.clear(); + glFinalCombinerInputNV(GL_VARIABLE_A_NV,GL_FOG,GL_UNSIGNED_IDENTITY_NV,GL_ALPHA); + glFinalCombinerInputNV(GL_VARIABLE_B_NV,GL_SPARE0_NV, + GL_UNSIGNED_IDENTITY_NV,GL_RGB); + glFinalCombinerInputNV(GL_VARIABLE_C_NV,GL_FOG,GL_UNSIGNED_IDENTITY_NV,GL_RGB); + glFinalCombinerInputNV(GL_VARIABLE_D_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB); + glFinalCombinerInputNV(GL_VARIABLE_E_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB); + glFinalCombinerInputNV(GL_VARIABLE_F_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB); + std::set::iterator iter = ps10::alphaBlueRegisters.find("r0"); + GLenum alphaComp = GL_ALPHA; + if (iter != ps10::alphaBlueRegisters.end()) + alphaComp = GL_BLUE; + glFinalCombinerInputNV(GL_VARIABLE_G_NV,GL_SPARE0_NV,GL_UNSIGNED_IDENTITY_NV,alphaComp); + // We can now clear alphaBlueRegisters for the next go around + alphaBlueRegisters.clear(); } void ps10::invoke(vector * c, - list > * a, - list > * b) + list > * a, + list > * b) { - const_to_combiner_reg_mapping_count = 0; // Hansong + const_to_combiner_reg_mapping_count = 0; // Hansong GLint activeTex = 0; glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); - glEnable(GL_PER_STAGE_CONSTANTS_NV); // should we require apps to do this? - if(c) - for_each(c->begin(), c->end(), set_constants()); - if(a) - for_each(a->begin(), a->end(), set_texture_shaders(c)); - glActiveTextureARB( GL_TEXTURE0_ARB ); + glEnable(GL_PER_STAGE_CONSTANTS_NV); // should we require apps to do this? + if(c) + for_each(c->begin(), c->end(), set_constants()); + if(a) + for_each(a->begin(), a->end(), set_texture_shaders(c)); + glActiveTextureARB( GL_TEXTURE0_ARB ); int numCombiners = 0; list >::iterator it = b->begin(); for(; it!=b->end(); ++it) { @@ -926,11 +926,11 @@ void ps10::invoke(vector * c, numCombiners++; } glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, numCombiners); - if(b) - for_each(b->begin(), b->end(), set_register_combiners()); - SetFinalCombinerStage(); - // We can clear the stageToTarget map now. - stageToTargetMap.clear(); + if(b) + for_each(b->begin(), b->end(), set_register_combiners()); + SetFinalCombinerStage(); + // We can clear the stageToTarget map now. + stageToTargetMap.clear(); glActiveTextureARB(activeTex); } @@ -938,84 +938,84 @@ void ps10::invoke(vector * c, // -- easy to break... bool is_ps10(const char * s) { - if(strstr(s, "ps.1.0")) - return true; - if(strstr(s, "Ps.1.0")) - return true; - if(strstr(s, "ps.1.1")) - return true; - if(strstr(s, "Ps.1.1")) - return true; - return false; + if(strstr(s, "ps.1.0")) + return true; + if(strstr(s, "Ps.1.0")) + return true; + if(strstr(s, "ps.1.1")) + return true; + if(strstr(s, "Ps.1.1")) + return true; + return false; } bool ps10::init_extensions() { - // register combiners - static bool rcinit = false; - if(rcinit == false) - { + // register combiners + static bool rcinit = false; + if(rcinit == false) + { /* - if(! glh_init_extensions("GL_NV_register_combiners")) - { - errors.set("unable to initialize GL_NV_register_combiners\n"); - return false; - } - else - { + if(! glh_init_extensions("GL_NV_register_combiners")) + { + errors.set("unable to initialize GL_NV_register_combiners\n"); + return false; + } + else + { */ - rcinit = true; + rcinit = true; /* - } + } */ - } + } - // register combiners 2 - static bool rc2init = false; - if(rc2init == false) - { + // register combiners 2 + static bool rc2init = false; + if(rc2init == false) + { /* - if( ! glh_init_extensions("GL_NV_register_combiners2")) - { - errors.set("unable to initialize GL_NV_register_combiners2\n"); - return false; - } - else - { + if( ! glh_init_extensions("GL_NV_register_combiners2")) + { + errors.set("unable to initialize GL_NV_register_combiners2\n"); + return false; + } + else + { */ - rc2init = true; + rc2init = true; /* - } + } */ - } - - static bool tsinit = 0; - if (tsinit == false ) - { + } + + static bool tsinit = 0; + if (tsinit == false ) + { /* - if(! glh_init_extensions( "GL_NV_texture_shader " "GL_ARB_multitexture " )) - { - errors.set("unable to initialize GL_NV_texture_shader\n"); - return false; - } - else - { + if(! glh_init_extensions( "GL_NV_texture_shader " "GL_ARB_multitexture " )) + { + errors.set("unable to initialize GL_NV_texture_shader\n"); + return false; + } + else + { */ - tsinit = true; + tsinit = true; /* - } + } */ - } - constToStageAndConstMap.clear(); - constToStageArray.clear(); - stageToConstMap.clear(); - line_number = 1; - return true; + } + constToStageAndConstMap.clear(); + constToStageArray.clear(); + stageToConstMap.clear(); + line_number = 1; + return true; } const int* ps10_get_info(int* pcount) { - if (pcount) - *pcount = constToStageArray.size(); - return &(constToStageArray[0]); + if (pcount) + *pcount = constToStageArray.size(); + return &(constToStageArray[0]); } diff --git a/RenderSystems/GL/src/nvparse/ps1.0_program.h b/RenderSystems/GL/src/nvparse/ps1.0_program.h index 97365495661..6214b9c4401 100644 --- a/RenderSystems/GL/src/nvparse/ps1.0_program.h +++ b/RenderSystems/GL/src/nvparse/ps1.0_program.h @@ -12,19 +12,19 @@ namespace ps10 { - struct constdef - { - std::string reg; - float r,g,b,a; - }; + struct constdef + { + std::string reg; + float r,g,b,a; + }; - extern std::map > constToStageAndConstMap; - extern std::map stageToTargetMap; - void invoke(std::vector * c, - std::list > * a, - std::list > * b); - - bool init_extensions(); + extern std::map > constToStageAndConstMap; + extern std::map stageToTargetMap; + void invoke(std::vector * c, + std::list > * a, + std::list > * b); + + bool init_extensions(); } #endif diff --git a/RenderSystems/GL/src/nvparse/rc1.0_combiners.cpp b/RenderSystems/GL/src/nvparse/rc1.0_combiners.cpp index e9afe5b080a..5d1c37d3e58 100644 --- a/RenderSystems/GL/src/nvparse/rc1.0_combiners.cpp +++ b/RenderSystems/GL/src/nvparse/rc1.0_combiners.cpp @@ -5,64 +5,64 @@ void CombinersStruct::Validate() { - if (2 == numConsts && - cc[0].reg.bits.name == cc[1].reg.bits.name) - errors.set("global constant set twice"); + if (2 == numConsts && + cc[0].reg.bits.name == cc[1].reg.bits.name) + errors.set("global constant set twice"); - generals.Validate(numConsts, &cc[0]); + generals.Validate(numConsts, &cc[0]); - final.Validate(); + final.Validate(); } void CombinersStruct::Invoke() { - for (int i = 0; i < numConsts; i++) - glCombinerParameterfvNV(cc[i].reg.bits.name, &(cc[i].v[0])); + for (int i = 0; i < numConsts; i++) + glCombinerParameterfvNV(cc[i].reg.bits.name, &(cc[i].v[0])); - generals.Invoke(); + generals.Invoke(); - final.Invoke(); + final.Invoke(); } bool is_rc10(const char * s) { - return ! strncmp(s, "!!RC1.0", 7); + return ! strncmp(s, "!!RC1.0", 7); } bool rc10_init_more() { - bool rcinit = false; - if(rcinit == false) - { + bool rcinit = false; + if(rcinit == false) + { /* - if(! glh_init_extensions("GL_NV_register_combiners")) - { - errors.set("unable to initialize GL_NV_register_combiners\n"); - return false; - } - else - { + if(! glh_init_extensions("GL_NV_register_combiners")) + { + errors.set("unable to initialize GL_NV_register_combiners\n"); + return false; + } + else + { */ - rcinit = true; + rcinit = true; /* - } + } */ - } + } - bool rc2init = false; - if(rc2init == false) - { - //glh_init_extensions("GL_NV_register_combiners2"); - // Don't fail if this doesn't initialize. - // We will run even if it doesn't exist. - rc2init = true; - } - - errors.reset(); - line_number = 1; + bool rc2init = false; + if(rc2init == false) + { + //glh_init_extensions("GL_NV_register_combiners2"); + // Don't fail if this doesn't initialize. + // We will run even if it doesn't exist. + rc2init = true; + } + + errors.reset(); + line_number = 1; - return true; + return true; } /* else if(!strncmp(instring, "!!RC1.0", 7)) diff --git a/RenderSystems/GL/src/nvparse/rc1.0_combiners.h b/RenderSystems/GL/src/nvparse/rc1.0_combiners.h index 907dba78aa8..85c1c560c5c 100644 --- a/RenderSystems/GL/src/nvparse/rc1.0_combiners.h +++ b/RenderSystems/GL/src/nvparse/rc1.0_combiners.h @@ -6,19 +6,19 @@ class CombinersStruct { public: - void Init(GeneralCombinersStruct _gcs, FinalCombinerStruct _fc, ConstColorStruct _cc0, ConstColorStruct _cc1) - { generals = _gcs; final = _fc; cc[0] = _cc0; cc[1] = _cc1; numConsts = 2;} - void Init(GeneralCombinersStruct _gcs, FinalCombinerStruct _fc, ConstColorStruct _cc0) - { generals = _gcs; final = _fc; cc[0] = _cc0; numConsts = 1;} - void Init(GeneralCombinersStruct _gcs, FinalCombinerStruct _fc) - { generals = _gcs; final = _fc; numConsts = 0;} - void Validate(); - void Invoke(); + void Init(GeneralCombinersStruct _gcs, FinalCombinerStruct _fc, ConstColorStruct _cc0, ConstColorStruct _cc1) + { generals = _gcs; final = _fc; cc[0] = _cc0; cc[1] = _cc1; numConsts = 2;} + void Init(GeneralCombinersStruct _gcs, FinalCombinerStruct _fc, ConstColorStruct _cc0) + { generals = _gcs; final = _fc; cc[0] = _cc0; numConsts = 1;} + void Init(GeneralCombinersStruct _gcs, FinalCombinerStruct _fc) + { generals = _gcs; final = _fc; numConsts = 0;} + void Validate(); + void Invoke(); private: - GeneralCombinersStruct generals; - FinalCombinerStruct final; - ConstColorStruct cc[2]; - int numConsts; + GeneralCombinersStruct generals; + FinalCombinerStruct final; + ConstColorStruct cc[2]; + int numConsts; }; #endif diff --git a/RenderSystems/GL/src/nvparse/rc1.0_final.cpp b/RenderSystems/GL/src/nvparse/rc1.0_final.cpp index 1b0369a2e7f..c6c2ff2bcfc 100644 --- a/RenderSystems/GL/src/nvparse/rc1.0_final.cpp +++ b/RenderSystems/GL/src/nvparse/rc1.0_final.cpp @@ -4,154 +4,154 @@ void FinalRgbFunctionStruct::ZeroOut() { - RegisterEnum zero; - zero.word = RCP_ZERO; - a.Init(zero, GL_UNSIGNED_IDENTITY_NV); - b.Init(zero, GL_UNSIGNED_IDENTITY_NV); - c.Init(zero, GL_UNSIGNED_IDENTITY_NV); - d.Init(zero, GL_UNSIGNED_IDENTITY_NV); + RegisterEnum zero; + zero.word = RCP_ZERO; + a.Init(zero, GL_UNSIGNED_IDENTITY_NV); + b.Init(zero, GL_UNSIGNED_IDENTITY_NV); + c.Init(zero, GL_UNSIGNED_IDENTITY_NV); + d.Init(zero, GL_UNSIGNED_IDENTITY_NV); } void FinalAlphaFunctionStruct::ZeroOut() { - RegisterEnum zero; - zero.word = RCP_ZERO; - g.Init(zero, GL_UNSIGNED_IDENTITY_NV); + RegisterEnum zero; + zero.word = RCP_ZERO; + g.Init(zero, GL_UNSIGNED_IDENTITY_NV); } void FinalProductStruct::ZeroOut() { - RegisterEnum zero; - zero.word = RCP_ZERO; - e.Init(zero, GL_UNSIGNED_IDENTITY_NV); - f.Init(zero, GL_UNSIGNED_IDENTITY_NV); + RegisterEnum zero; + zero.word = RCP_ZERO; + e.Init(zero, GL_UNSIGNED_IDENTITY_NV); + f.Init(zero, GL_UNSIGNED_IDENTITY_NV); } void FinalCombinerStruct::Validate() { - if (hasProduct && - (GL_E_TIMES_F_NV == product.e.reg.bits.name || - GL_SPARE0_PLUS_SECONDARY_COLOR_NV == product.e.reg.bits.name || - GL_DISCARD_NV == product.e.reg.bits.name || - GL_E_TIMES_F_NV == product.f.reg.bits.name || - GL_SPARE0_PLUS_SECONDARY_COLOR_NV == product.f.reg.bits.name || - GL_DISCARD_NV == product.f.reg.bits.name)) - errors.set("invalid input register for final_product"); - - if (hasProduct && - (RCP_BLUE == product.e.reg.bits.channel || - RCP_BLUE == product.f.reg.bits.channel)) - errors.set("blue register used in final_product"); - - if (GL_E_TIMES_F_NV == alpha.g.reg.bits.name || - GL_SPARE0_PLUS_SECONDARY_COLOR_NV == alpha.g.reg.bits.name || - GL_DISCARD_NV == alpha.g.reg.bits.name) - errors.set("invalid input register for final alpha"); - - if (RCP_RGB == alpha.g.reg.bits.channel) - errors.set("rgb register used in final alpha"); - - if (GL_SPARE0_PLUS_SECONDARY_COLOR_NV == rgb.a.reg.bits.name && - GL_SPARE0_PLUS_SECONDARY_COLOR_NV != rgb.b.reg.bits.name && - GL_ZERO == rgb.c.reg.bits.name && GL_UNSIGNED_IDENTITY_NV == rgb.c.map) - { - MappedRegisterStruct temp; - temp = rgb.a; - rgb.a = rgb.b; - rgb.b = temp; - } - - if (GL_SPARE0_PLUS_SECONDARY_COLOR_NV == rgb.a.reg.bits.name && - GL_ZERO == rgb.b.reg.bits.name && GL_UNSIGNED_INVERT_NV == rgb.b.map && - GL_ZERO == rgb.c.reg.bits.name && GL_UNSIGNED_IDENTITY_NV == rgb.c.map && - GL_SPARE0_PLUS_SECONDARY_COLOR_NV != rgb.d.reg.bits.name) - { - MappedRegisterStruct temp; - temp = rgb.a; - rgb.a = rgb.d; - rgb.d = temp; - } - - if (GL_SPARE0_PLUS_SECONDARY_COLOR_NV == rgb.a.reg.bits.name || - GL_DISCARD_NV == rgb.a.reg.bits.name || - GL_DISCARD_NV == rgb.b.reg.bits.name || - GL_DISCARD_NV == rgb.c.reg.bits.name || - GL_DISCARD_NV == rgb.d.reg.bits.name) - errors.set("invalid input register for final rgb"); - - if (RCP_BLUE == rgb.a.reg.bits.channel || - RCP_BLUE == rgb.b.reg.bits.channel || - RCP_BLUE == rgb.c.reg.bits.channel || - RCP_BLUE == rgb.d.reg.bits.channel) - errors.set("blue register used in final rgb"); - - if ((GL_E_TIMES_F_NV == rgb.a.reg.bits.name || - GL_E_TIMES_F_NV == rgb.b.reg.bits.name || - GL_E_TIMES_F_NV == rgb.c.reg.bits.name || - GL_E_TIMES_F_NV == rgb.d.reg.bits.name) && !hasProduct) - errors.set("final_product used but not set"); - - if (RCP_NONE == rgb.a.reg.bits.channel) - rgb.a.reg.bits.channel = RCP_RGB; - if (RCP_NONE == rgb.b.reg.bits.channel) - rgb.b.reg.bits.channel = RCP_RGB; - if (RCP_NONE == rgb.c.reg.bits.channel) - rgb.c.reg.bits.channel = RCP_RGB; - if (RCP_NONE == rgb.d.reg.bits.channel) - rgb.d.reg.bits.channel = RCP_RGB; - if (RCP_NONE == product.e.reg.bits.channel) - product.e.reg.bits.channel = RCP_RGB; - if (RCP_NONE == product.f.reg.bits.channel) - product.f.reg.bits.channel = RCP_RGB; - if (RCP_NONE == alpha.g.reg.bits.channel) - alpha.g.reg.bits.channel = RCP_ALPHA; + if (hasProduct && + (GL_E_TIMES_F_NV == product.e.reg.bits.name || + GL_SPARE0_PLUS_SECONDARY_COLOR_NV == product.e.reg.bits.name || + GL_DISCARD_NV == product.e.reg.bits.name || + GL_E_TIMES_F_NV == product.f.reg.bits.name || + GL_SPARE0_PLUS_SECONDARY_COLOR_NV == product.f.reg.bits.name || + GL_DISCARD_NV == product.f.reg.bits.name)) + errors.set("invalid input register for final_product"); + + if (hasProduct && + (RCP_BLUE == product.e.reg.bits.channel || + RCP_BLUE == product.f.reg.bits.channel)) + errors.set("blue register used in final_product"); + + if (GL_E_TIMES_F_NV == alpha.g.reg.bits.name || + GL_SPARE0_PLUS_SECONDARY_COLOR_NV == alpha.g.reg.bits.name || + GL_DISCARD_NV == alpha.g.reg.bits.name) + errors.set("invalid input register for final alpha"); + + if (RCP_RGB == alpha.g.reg.bits.channel) + errors.set("rgb register used in final alpha"); + + if (GL_SPARE0_PLUS_SECONDARY_COLOR_NV == rgb.a.reg.bits.name && + GL_SPARE0_PLUS_SECONDARY_COLOR_NV != rgb.b.reg.bits.name && + GL_ZERO == rgb.c.reg.bits.name && GL_UNSIGNED_IDENTITY_NV == rgb.c.map) + { + MappedRegisterStruct temp; + temp = rgb.a; + rgb.a = rgb.b; + rgb.b = temp; + } + + if (GL_SPARE0_PLUS_SECONDARY_COLOR_NV == rgb.a.reg.bits.name && + GL_ZERO == rgb.b.reg.bits.name && GL_UNSIGNED_INVERT_NV == rgb.b.map && + GL_ZERO == rgb.c.reg.bits.name && GL_UNSIGNED_IDENTITY_NV == rgb.c.map && + GL_SPARE0_PLUS_SECONDARY_COLOR_NV != rgb.d.reg.bits.name) + { + MappedRegisterStruct temp; + temp = rgb.a; + rgb.a = rgb.d; + rgb.d = temp; + } + + if (GL_SPARE0_PLUS_SECONDARY_COLOR_NV == rgb.a.reg.bits.name || + GL_DISCARD_NV == rgb.a.reg.bits.name || + GL_DISCARD_NV == rgb.b.reg.bits.name || + GL_DISCARD_NV == rgb.c.reg.bits.name || + GL_DISCARD_NV == rgb.d.reg.bits.name) + errors.set("invalid input register for final rgb"); + + if (RCP_BLUE == rgb.a.reg.bits.channel || + RCP_BLUE == rgb.b.reg.bits.channel || + RCP_BLUE == rgb.c.reg.bits.channel || + RCP_BLUE == rgb.d.reg.bits.channel) + errors.set("blue register used in final rgb"); + + if ((GL_E_TIMES_F_NV == rgb.a.reg.bits.name || + GL_E_TIMES_F_NV == rgb.b.reg.bits.name || + GL_E_TIMES_F_NV == rgb.c.reg.bits.name || + GL_E_TIMES_F_NV == rgb.d.reg.bits.name) && !hasProduct) + errors.set("final_product used but not set"); + + if (RCP_NONE == rgb.a.reg.bits.channel) + rgb.a.reg.bits.channel = RCP_RGB; + if (RCP_NONE == rgb.b.reg.bits.channel) + rgb.b.reg.bits.channel = RCP_RGB; + if (RCP_NONE == rgb.c.reg.bits.channel) + rgb.c.reg.bits.channel = RCP_RGB; + if (RCP_NONE == rgb.d.reg.bits.channel) + rgb.d.reg.bits.channel = RCP_RGB; + if (RCP_NONE == product.e.reg.bits.channel) + product.e.reg.bits.channel = RCP_RGB; + if (RCP_NONE == product.f.reg.bits.channel) + product.f.reg.bits.channel = RCP_RGB; + if (RCP_NONE == alpha.g.reg.bits.channel) + alpha.g.reg.bits.channel = RCP_ALPHA; } void FinalCombinerStruct::Invoke() { - if(clamp) - glCombinerParameteriNV(GL_COLOR_SUM_CLAMP_NV, GL_TRUE); - else - glCombinerParameteriNV(GL_COLOR_SUM_CLAMP_NV, GL_FALSE); - - glFinalCombinerInputNV( - GL_VARIABLE_A_NV, - rgb.a.reg.bits.name, - rgb.a.map, - MAP_CHANNEL(rgb.a.reg.bits.channel)); - - glFinalCombinerInputNV( - GL_VARIABLE_B_NV, - rgb.b.reg.bits.name, - rgb.b.map, - MAP_CHANNEL(rgb.b.reg.bits.channel)); - - glFinalCombinerInputNV( - GL_VARIABLE_C_NV, - rgb.c.reg.bits.name, - rgb.c.map, - MAP_CHANNEL(rgb.c.reg.bits.channel)); - - glFinalCombinerInputNV( - GL_VARIABLE_D_NV, - rgb.d.reg.bits.name, - rgb.d.map, - MAP_CHANNEL(rgb.d.reg.bits.channel)); - - glFinalCombinerInputNV( - GL_VARIABLE_E_NV, - product.e.reg.bits.name, - product.e.map, - MAP_CHANNEL(product.e.reg.bits.channel)); - - glFinalCombinerInputNV( - GL_VARIABLE_F_NV, - product.f.reg.bits.name, - product.f.map, - MAP_CHANNEL(product.f.reg.bits.channel)); - - glFinalCombinerInputNV( - GL_VARIABLE_G_NV, - alpha.g.reg.bits.name, - alpha.g.map, - MAP_CHANNEL(alpha.g.reg.bits.channel)); + if(clamp) + glCombinerParameteriNV(GL_COLOR_SUM_CLAMP_NV, GL_TRUE); + else + glCombinerParameteriNV(GL_COLOR_SUM_CLAMP_NV, GL_FALSE); + + glFinalCombinerInputNV( + GL_VARIABLE_A_NV, + rgb.a.reg.bits.name, + rgb.a.map, + MAP_CHANNEL(rgb.a.reg.bits.channel)); + + glFinalCombinerInputNV( + GL_VARIABLE_B_NV, + rgb.b.reg.bits.name, + rgb.b.map, + MAP_CHANNEL(rgb.b.reg.bits.channel)); + + glFinalCombinerInputNV( + GL_VARIABLE_C_NV, + rgb.c.reg.bits.name, + rgb.c.map, + MAP_CHANNEL(rgb.c.reg.bits.channel)); + + glFinalCombinerInputNV( + GL_VARIABLE_D_NV, + rgb.d.reg.bits.name, + rgb.d.map, + MAP_CHANNEL(rgb.d.reg.bits.channel)); + + glFinalCombinerInputNV( + GL_VARIABLE_E_NV, + product.e.reg.bits.name, + product.e.map, + MAP_CHANNEL(product.e.reg.bits.channel)); + + glFinalCombinerInputNV( + GL_VARIABLE_F_NV, + product.f.reg.bits.name, + product.f.map, + MAP_CHANNEL(product.f.reg.bits.channel)); + + glFinalCombinerInputNV( + GL_VARIABLE_G_NV, + alpha.g.reg.bits.name, + alpha.g.map, + MAP_CHANNEL(alpha.g.reg.bits.channel)); } diff --git a/RenderSystems/GL/src/nvparse/rc1.0_final.h b/RenderSystems/GL/src/nvparse/rc1.0_final.h index f0d98443125..9d919cf0a9f 100644 --- a/RenderSystems/GL/src/nvparse/rc1.0_final.h +++ b/RenderSystems/GL/src/nvparse/rc1.0_final.h @@ -5,44 +5,44 @@ class FinalAlphaFunctionStruct { public: - void Init(MappedRegisterStruct _g) { g = _g; } - void ZeroOut(); - MappedRegisterStruct g; + void Init(MappedRegisterStruct _g) { g = _g; } + void ZeroOut(); + MappedRegisterStruct g; }; class FinalRgbFunctionStruct { public: - void Init(MappedRegisterStruct _a, MappedRegisterStruct _b, MappedRegisterStruct _c, MappedRegisterStruct _d) - { a = _a; b = _b; c = _c; d = _d; } - void ZeroOut(); - MappedRegisterStruct a; - MappedRegisterStruct b; - MappedRegisterStruct c; - MappedRegisterStruct d; + void Init(MappedRegisterStruct _a, MappedRegisterStruct _b, MappedRegisterStruct _c, MappedRegisterStruct _d) + { a = _a; b = _b; c = _c; d = _d; } + void ZeroOut(); + MappedRegisterStruct a; + MappedRegisterStruct b; + MappedRegisterStruct c; + MappedRegisterStruct d; }; class FinalProductStruct { public: - void Init(MappedRegisterStruct _e, MappedRegisterStruct _f) { e = _e; f = _f; } - void ZeroOut(); - MappedRegisterStruct e; - MappedRegisterStruct f; + void Init(MappedRegisterStruct _e, MappedRegisterStruct _f) { e = _e; f = _f; } + void ZeroOut(); + MappedRegisterStruct e; + MappedRegisterStruct f; }; class FinalCombinerStruct { public: - void Init(FinalRgbFunctionStruct _rgb, FinalAlphaFunctionStruct _alpha, int _clamp, FinalProductStruct _product) - { rgb = _rgb; alpha = _alpha; clamp = _clamp; product = _product; hasProduct = true;} - void Init(FinalRgbFunctionStruct _rgb, FinalAlphaFunctionStruct _alpha, int _clamp) - { rgb = _rgb; alpha = _alpha; clamp = _clamp; hasProduct = false; product.ZeroOut();} + void Init(FinalRgbFunctionStruct _rgb, FinalAlphaFunctionStruct _alpha, int _clamp, FinalProductStruct _product) + { rgb = _rgb; alpha = _alpha; clamp = _clamp; product = _product; hasProduct = true;} + void Init(FinalRgbFunctionStruct _rgb, FinalAlphaFunctionStruct _alpha, int _clamp) + { rgb = _rgb; alpha = _alpha; clamp = _clamp; hasProduct = false; product.ZeroOut();} - int hasProduct; - FinalProductStruct product; - int clamp; - FinalRgbFunctionStruct rgb; - FinalAlphaFunctionStruct alpha; - void Validate(); - void Invoke(); + int hasProduct; + FinalProductStruct product; + int clamp; + FinalRgbFunctionStruct rgb; + FinalAlphaFunctionStruct alpha; + void Validate(); + void Invoke(); }; #endif diff --git a/RenderSystems/GL/src/nvparse/rc1.0_general.cpp b/RenderSystems/GL/src/nvparse/rc1.0_general.cpp index 9d7124847a9..2e1a7a73963 100644 --- a/RenderSystems/GL/src/nvparse/rc1.0_general.cpp +++ b/RenderSystems/GL/src/nvparse/rc1.0_general.cpp @@ -5,296 +5,296 @@ void GeneralCombinersStruct::Validate(int numConsts, ConstColorStruct *pcc) { - GLint maxGCs; - glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &maxGCs); - if (num > maxGCs) { - char buffer[256]; - sprintf(buffer, "%d general combiners specified, only %d supported", num, (int)maxGCs); - errors.set(buffer); - num = maxGCs; - } - - if (0 == num) { - // Setup a "fake" general combiner 0 - general[0].ZeroOut(); - num = 1; - } - - localConsts = 0; - int i; - for (i = 0; i < num; i++) - localConsts += general[i].numConsts; - - if (localConsts > 0) + GLint maxGCs; + glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &maxGCs); + if (num > maxGCs) { + char buffer[256]; + sprintf(buffer, "%d general combiners specified, only %d supported", num, (int)maxGCs); + errors.set(buffer); + num = maxGCs; + } + + if (0 == num) { + // Setup a "fake" general combiner 0 + general[0].ZeroOut(); + num = 1; + } + + localConsts = 0; + int i; + for (i = 0; i < num; i++) + localConsts += general[i].numConsts; + + if (localConsts > 0) { - if (NULL == glCombinerStageParameterfvNV) - errors.set("local constant(s) specified, but not supported -- ignored"); - else - for (i = 0; i < num; i++) - general[i].SetUnusedLocalConsts(numConsts, pcc); + if (NULL == glCombinerStageParameterfvNV) + errors.set("local constant(s) specified, but not supported -- ignored"); + else + for (i = 0; i < num; i++) + general[i].SetUnusedLocalConsts(numConsts, pcc); } - for (i = 0; i < num; i++) - general[i].Validate(i); + for (i = 0; i < num; i++) + general[i].Validate(i); - for (; i < maxGCs; i++) - general[i].ZeroOut(); + for (; i < maxGCs; i++) + general[i].ZeroOut(); } void GeneralCombinersStruct::Invoke() { - glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, num); - int i; - for (i = 0; i < num; i++) - general[i].Invoke(i); - - if (NULL != glCombinerStageParameterfvNV) { - if (localConsts > 0) - glEnable(GL_PER_STAGE_CONSTANTS_NV); - else - glDisable(GL_PER_STAGE_CONSTANTS_NV); - } - + glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, num); + int i; + for (i = 0; i < num; i++) + general[i].Invoke(i); + + if (NULL != glCombinerStageParameterfvNV) { + if (localConsts > 0) + glEnable(GL_PER_STAGE_CONSTANTS_NV); + else + glDisable(GL_PER_STAGE_CONSTANTS_NV); + } + } void GeneralCombinerStruct::ZeroOut() { - numPortions = 2; - numConsts = 0; + numPortions = 2; + numConsts = 0; - portion[0].ZeroOut(); - portion[0].designator = RCP_RGB; - portion[1].ZeroOut(); - portion[1].designator = RCP_ALPHA; + portion[0].ZeroOut(); + portion[0].designator = RCP_RGB; + portion[1].ZeroOut(); + portion[1].designator = RCP_ALPHA; } void GeneralCombinerStruct::SetUnusedLocalConsts(int numGlobalConsts, ConstColorStruct *globalCCs) { int i; - for (i = 0; i < numGlobalConsts; i++) { - bool constUsed = false; - int j; - for (j = 0; j < numConsts; j++) - constUsed |= (cc[j].reg.bits.name == globalCCs[i].reg.bits.name); - if (!constUsed) - cc[numConsts++] = globalCCs[i]; - } + for (i = 0; i < numGlobalConsts; i++) { + bool constUsed = false; + int j; + for (j = 0; j < numConsts; j++) + constUsed |= (cc[j].reg.bits.name == globalCCs[i].reg.bits.name); + if (!constUsed) + cc[numConsts++] = globalCCs[i]; + } } void GeneralCombinerStruct::Validate(int stage) { - if (2 == numConsts && - cc[0].reg.bits.name == cc[1].reg.bits.name) - errors.set("local constant set twice"); - - switch (numPortions) - { - case 0: - portion[0].designator = RCP_RGB; - // Fallthru - case 1: - portion[1].designator = ((RCP_RGB == portion[0].designator) ? RCP_ALPHA : RCP_RGB); - // Fallthru - case 2: - if (portion[0].designator == portion[1].designator) - errors.set("portion declared twice"); - break; - } - int i; - for (i = 0; i < numPortions; i++) - portion[i].Validate(stage); - - for (; i < 2; i++) - portion[i].ZeroOut(); + if (2 == numConsts && + cc[0].reg.bits.name == cc[1].reg.bits.name) + errors.set("local constant set twice"); + + switch (numPortions) + { + case 0: + portion[0].designator = RCP_RGB; + // Fallthru + case 1: + portion[1].designator = ((RCP_RGB == portion[0].designator) ? RCP_ALPHA : RCP_RGB); + // Fallthru + case 2: + if (portion[0].designator == portion[1].designator) + errors.set("portion declared twice"); + break; + } + int i; + for (i = 0; i < numPortions; i++) + portion[i].Validate(stage); + + for (; i < 2; i++) + portion[i].ZeroOut(); } void GeneralCombinerStruct::Invoke(int stage) { - int i; + int i; - if (NULL != glCombinerStageParameterfvNV) - for (i = 0; i < numConsts; i++) - glCombinerStageParameterfvNV(GL_COMBINER0_NV + stage, cc[i].reg.bits.name, &(cc[i].v[0])); + if (NULL != glCombinerStageParameterfvNV) + for (i = 0; i < numConsts; i++) + glCombinerStageParameterfvNV(GL_COMBINER0_NV + stage, cc[i].reg.bits.name, &(cc[i].v[0])); - for (i = 0; i < 2; i++) - portion[i].Invoke(stage); + for (i = 0; i < 2; i++) + portion[i].Invoke(stage); } void GeneralPortionStruct::Validate(int stage) { - gf.Validate(stage, designator); + gf.Validate(stage, designator); } void GeneralPortionStruct::Invoke(int stage) { - gf.Invoke(stage, designator, bs); + gf.Invoke(stage, designator, bs); } void GeneralPortionStruct::ZeroOut() { - gf.ZeroOut(); - bs.word = RCP_SCALE_BY_ONE; + gf.ZeroOut(); + bs.word = RCP_SCALE_BY_ONE; } void GeneralFunctionStruct::ZeroOut() { - // Create mapped registers for zero and discard - MappedRegisterStruct unsignedZero; - RegisterEnum zero; - zero.word = RCP_ZERO; - unsignedZero.Init(zero); + // Create mapped registers for zero and discard + MappedRegisterStruct unsignedZero; + RegisterEnum zero; + zero.word = RCP_ZERO; + unsignedZero.Init(zero); - MappedRegisterStruct unsignedDiscard; - RegisterEnum discard; - discard.word = RCP_DISCARD; - unsignedDiscard.Init(discard); + MappedRegisterStruct unsignedDiscard; + RegisterEnum discard; + discard.word = RCP_DISCARD; + unsignedDiscard.Init(discard); - numOps = 3; + numOps = 3; - op[0].op = RCP_MUL; - op[0].reg[0] = unsignedDiscard; - op[0].reg[1] = unsignedZero; - op[0].reg[2] = unsignedZero; + op[0].op = RCP_MUL; + op[0].reg[0] = unsignedDiscard; + op[0].reg[1] = unsignedZero; + op[0].reg[2] = unsignedZero; - op[1].op = RCP_MUL; - op[1].reg[0] = unsignedDiscard; - op[1].reg[1] = unsignedZero; - op[1].reg[2] = unsignedZero; + op[1].op = RCP_MUL; + op[1].reg[0] = unsignedDiscard; + op[1].reg[1] = unsignedZero; + op[1].reg[2] = unsignedZero; - op[2].op = RCP_SUM; - op[2].reg[0] = unsignedDiscard; + op[2].op = RCP_SUM; + op[2].reg[0] = unsignedDiscard; } void GeneralFunctionStruct::Validate(int stage, int portion) { int i; - for (i = 0; i < numOps; i++) - op[i].Validate(stage, portion); - // Check if multiple ops are writing to same register (and it's not DISCARD) - if (numOps > 1 && - op[0].reg[0].reg.bits.name == op[1].reg[0].reg.bits.name && - GL_DISCARD_NV != op[0].reg[0].reg.bits.name) - errors.set("writing to same register twice"); - if (numOps > 2 && - (op[0].reg[0].reg.bits.name == op[2].reg[0].reg.bits.name || - op[1].reg[0].reg.bits.name == op[2].reg[0].reg.bits.name) && - GL_DISCARD_NV != op[2].reg[0].reg.bits.name) - errors.set("writing to same register twice"); - - // Set unused outputs to discard, unused inputs to zero/unsigned_identity - if (numOps < 2) { - // Set C input to zero - op[1].reg[1].reg.bits.name = GL_ZERO; - op[1].reg[1].map = GL_UNSIGNED_IDENTITY_NV; - op[1].reg[1].reg.bits.channel = portion; - - // Set D input to zero - op[1].reg[2].reg.bits.name = GL_ZERO; - op[1].reg[2].map = GL_UNSIGNED_IDENTITY_NV; - op[1].reg[2].reg.bits.channel = portion; - - // Discard CD output - op[1].op = false; - op[1].reg[0].reg.bits.name = GL_DISCARD_NV; - } - - if (numOps < 3) { - // Discard muxSum output - op[2].reg[0].reg.bits.name = GL_DISCARD_NV; - op[2].op = RCP_SUM; - } + for (i = 0; i < numOps; i++) + op[i].Validate(stage, portion); + // Check if multiple ops are writing to same register (and it's not DISCARD) + if (numOps > 1 && + op[0].reg[0].reg.bits.name == op[1].reg[0].reg.bits.name && + GL_DISCARD_NV != op[0].reg[0].reg.bits.name) + errors.set("writing to same register twice"); + if (numOps > 2 && + (op[0].reg[0].reg.bits.name == op[2].reg[0].reg.bits.name || + op[1].reg[0].reg.bits.name == op[2].reg[0].reg.bits.name) && + GL_DISCARD_NV != op[2].reg[0].reg.bits.name) + errors.set("writing to same register twice"); + + // Set unused outputs to discard, unused inputs to zero/unsigned_identity + if (numOps < 2) { + // Set C input to zero + op[1].reg[1].reg.bits.name = GL_ZERO; + op[1].reg[1].map = GL_UNSIGNED_IDENTITY_NV; + op[1].reg[1].reg.bits.channel = portion; + + // Set D input to zero + op[1].reg[2].reg.bits.name = GL_ZERO; + op[1].reg[2].map = GL_UNSIGNED_IDENTITY_NV; + op[1].reg[2].reg.bits.channel = portion; + + // Discard CD output + op[1].op = false; + op[1].reg[0].reg.bits.name = GL_DISCARD_NV; + } + + if (numOps < 3) { + // Discard muxSum output + op[2].reg[0].reg.bits.name = GL_DISCARD_NV; + op[2].op = RCP_SUM; + } } void GeneralFunctionStruct::Invoke(int stage, int portion, BiasScaleEnum bs) { - GLenum portionEnum = (RCP_RGB == portion) ? GL_RGB : GL_ALPHA; - - glCombinerInputNV(GL_COMBINER0_NV + stage, - portionEnum, - GL_VARIABLE_A_NV, - op[0].reg[1].reg.bits.name, - op[0].reg[1].map, - MAP_CHANNEL(op[0].reg[1].reg.bits.channel)); - - glCombinerInputNV(GL_COMBINER0_NV + stage, - portionEnum, - GL_VARIABLE_B_NV, - op[0].reg[2].reg.bits.name, - op[0].reg[2].map, - MAP_CHANNEL(op[0].reg[2].reg.bits.channel)); - - glCombinerInputNV(GL_COMBINER0_NV + stage, - portionEnum, - GL_VARIABLE_C_NV, - op[1].reg[1].reg.bits.name, - op[1].reg[1].map, - MAP_CHANNEL(op[1].reg[1].reg.bits.channel)); - - glCombinerInputNV(GL_COMBINER0_NV + stage, - portionEnum, - GL_VARIABLE_D_NV, - op[1].reg[2].reg.bits.name, - op[1].reg[2].map, - MAP_CHANNEL(op[1].reg[2].reg.bits.channel)); - - glCombinerOutputNV(GL_COMBINER0_NV + stage, - portionEnum, - op[0].reg[0].reg.bits.name, - op[1].reg[0].reg.bits.name, - op[2].reg[0].reg.bits.name, - bs.bits.scale, - bs.bits.bias, - op[0].op, - op[1].op, - (op[2].op == RCP_MUX) ? true : false); + GLenum portionEnum = (RCP_RGB == portion) ? GL_RGB : GL_ALPHA; + + glCombinerInputNV(GL_COMBINER0_NV + stage, + portionEnum, + GL_VARIABLE_A_NV, + op[0].reg[1].reg.bits.name, + op[0].reg[1].map, + MAP_CHANNEL(op[0].reg[1].reg.bits.channel)); + + glCombinerInputNV(GL_COMBINER0_NV + stage, + portionEnum, + GL_VARIABLE_B_NV, + op[0].reg[2].reg.bits.name, + op[0].reg[2].map, + MAP_CHANNEL(op[0].reg[2].reg.bits.channel)); + + glCombinerInputNV(GL_COMBINER0_NV + stage, + portionEnum, + GL_VARIABLE_C_NV, + op[1].reg[1].reg.bits.name, + op[1].reg[1].map, + MAP_CHANNEL(op[1].reg[1].reg.bits.channel)); + + glCombinerInputNV(GL_COMBINER0_NV + stage, + portionEnum, + GL_VARIABLE_D_NV, + op[1].reg[2].reg.bits.name, + op[1].reg[2].map, + MAP_CHANNEL(op[1].reg[2].reg.bits.channel)); + + glCombinerOutputNV(GL_COMBINER0_NV + stage, + portionEnum, + op[0].reg[0].reg.bits.name, + op[1].reg[0].reg.bits.name, + op[2].reg[0].reg.bits.name, + bs.bits.scale, + bs.bits.bias, + op[0].op, + op[1].op, + (op[2].op == RCP_MUX) ? true : false); } // This helper function assigns a channel to an undesignated input register static void ConvertRegister(RegisterEnum& reg, int portion) { - if (RCP_NONE == reg.bits.channel) { - reg.bits.channel = portion; - if (GL_FOG == reg.bits.name && RCP_ALPHA == portion) - // Special case where fog alpha is final only, but RGB is not - reg.bits.finalOnly = true; - } + if (RCP_NONE == reg.bits.channel) { + reg.bits.channel = portion; + if (GL_FOG == reg.bits.name && RCP_ALPHA == portion) + // Special case where fog alpha is final only, but RGB is not + reg.bits.finalOnly = true; + } } void OpStruct::Validate(int stage, int portion) { - int args = 1; - - if (RCP_DOT == op || RCP_MUL == op) - args = 3; - else - args = 1; - - if (reg[0].reg.bits.readOnly) - errors.set("writing to a read-only register"); - - if (RCP_ALPHA == portion && - RCP_DOT == op) - errors.set("dot used in alpha portion"); - int i; - for (i = 0; i < args; i++) { - ConvertRegister(reg[i].reg, portion); - if (reg[i].reg.bits.finalOnly) - errors.set("final register used in general combiner"); - if (RCP_RGB == portion && - RCP_BLUE == reg[i].reg.bits.channel) - errors.set("blue register used in rgb portion"); - if (RCP_ALPHA == portion && - RCP_RGB == reg[i].reg.bits.channel) - errors.set("rgb register used in alpha portion"); - if (i > 0 && - GL_DISCARD_NV == reg[i].reg.bits.name) - errors.set("reading from discard"); - } + int args = 1; + + if (RCP_DOT == op || RCP_MUL == op) + args = 3; + else + args = 1; + + if (reg[0].reg.bits.readOnly) + errors.set("writing to a read-only register"); + + if (RCP_ALPHA == portion && + RCP_DOT == op) + errors.set("dot used in alpha portion"); + int i; + for (i = 0; i < args; i++) { + ConvertRegister(reg[i].reg, portion); + if (reg[i].reg.bits.finalOnly) + errors.set("final register used in general combiner"); + if (RCP_RGB == portion && + RCP_BLUE == reg[i].reg.bits.channel) + errors.set("blue register used in rgb portion"); + if (RCP_ALPHA == portion && + RCP_RGB == reg[i].reg.bits.channel) + errors.set("rgb register used in alpha portion"); + if (i > 0 && + GL_DISCARD_NV == reg[i].reg.bits.name) + errors.set("reading from discard"); + } } diff --git a/RenderSystems/GL/src/nvparse/rc1.0_general.h b/RenderSystems/GL/src/nvparse/rc1.0_general.h index 3fd560ac259..5431bce3b62 100644 --- a/RenderSystems/GL/src/nvparse/rc1.0_general.h +++ b/RenderSystems/GL/src/nvparse/rc1.0_general.h @@ -6,101 +6,101 @@ #include "nvparse_externs.h" enum { - RCP_MUL = 0, - RCP_DOT, - RCP_MUX, - RCP_SUM + RCP_MUL = 0, + RCP_DOT, + RCP_MUX, + RCP_SUM }; class ConstColorStruct { public: - void Init(RegisterEnum _reg, float _v0, float _v1, float _v2, float _v3) - { reg = _reg; v[0] = _v0; v[1] = _v1; v[2] = _v2; v[3] = _v3; } - RegisterEnum reg; - float v[4]; + void Init(RegisterEnum _reg, float _v0, float _v1, float _v2, float _v3) + { reg = _reg; v[0] = _v0; v[1] = _v1; v[2] = _v2; v[3] = _v3; } + RegisterEnum reg; + float v[4]; }; class OpStruct { public: - void Init(int _op, RegisterEnum _reg0, MappedRegisterStruct _reg1, MappedRegisterStruct _reg2) - { op = _op; reg[0].reg = _reg0; reg[1] = _reg1; reg[2] = _reg2; } - void Init(int _op, RegisterEnum _reg0) - { op = _op; reg[0].reg = _reg0; } - int op; - MappedRegisterStruct reg[3]; - void Validate(int stage, int portion); + void Init(int _op, RegisterEnum _reg0, MappedRegisterStruct _reg1, MappedRegisterStruct _reg2) + { op = _op; reg[0].reg = _reg0; reg[1] = _reg1; reg[2] = _reg2; } + void Init(int _op, RegisterEnum _reg0) + { op = _op; reg[0].reg = _reg0; } + int op; + MappedRegisterStruct reg[3]; + void Validate(int stage, int portion); }; class GeneralFunctionStruct { public: - void Init(OpStruct _op0, OpStruct _op1, OpStruct _op2) { op[0] = _op0; op[1] = _op1; op[2] = _op2; numOps = 3; } - void Init(OpStruct _op0, OpStruct _op1) { op[0] = _op0; op[1] = _op1; numOps = 2; } - void Init(OpStruct _op0) { op[0] = _op0; numOps = 1; } - void Validate(int stage, int portion); - void Invoke(int stage, int portion, BiasScaleEnum bs); - void ZeroOut(); - int numOps; - OpStruct op[3]; + void Init(OpStruct _op0, OpStruct _op1, OpStruct _op2) { op[0] = _op0; op[1] = _op1; op[2] = _op2; numOps = 3; } + void Init(OpStruct _op0, OpStruct _op1) { op[0] = _op0; op[1] = _op1; numOps = 2; } + void Init(OpStruct _op0) { op[0] = _op0; numOps = 1; } + void Validate(int stage, int portion); + void Invoke(int stage, int portion, BiasScaleEnum bs); + void ZeroOut(); + int numOps; + OpStruct op[3]; }; class GeneralPortionStruct { public: - void Init(int _designator, GeneralFunctionStruct _gf, BiasScaleEnum _bs) - { designator = _designator; gf = _gf; bs = _bs; } + void Init(int _designator, GeneralFunctionStruct _gf, BiasScaleEnum _bs) + { designator = _designator; gf = _gf; bs = _bs; } - void Validate(int stage); - void Invoke(int stage); - void ZeroOut(); - int designator; - GeneralFunctionStruct gf; - BiasScaleEnum bs; + void Validate(int stage); + void Invoke(int stage); + void ZeroOut(); + int designator; + GeneralFunctionStruct gf; + BiasScaleEnum bs; }; class GeneralCombinerStruct { public: - void Init(GeneralPortionStruct _portion0, GeneralPortionStruct _portion1, ConstColorStruct _cc0, ConstColorStruct _cc1) - { portion[0] = _portion0; portion[1] = _portion1; numPortions = 2; cc[0] = _cc0; cc[1] = _cc1; numConsts = 2; } - void Init(GeneralPortionStruct _portion0, GeneralPortionStruct _portion1, ConstColorStruct _cc0) - { portion[0] = _portion0; portion[1] = _portion1; numPortions = 2; cc[0] = _cc0; numConsts = 1; } - void Init(GeneralPortionStruct _portion0, GeneralPortionStruct _portion1) - { portion[0] = _portion0; portion[1] = _portion1; numPortions = 2; numConsts = 0; } + void Init(GeneralPortionStruct _portion0, GeneralPortionStruct _portion1, ConstColorStruct _cc0, ConstColorStruct _cc1) + { portion[0] = _portion0; portion[1] = _portion1; numPortions = 2; cc[0] = _cc0; cc[1] = _cc1; numConsts = 2; } + void Init(GeneralPortionStruct _portion0, GeneralPortionStruct _portion1, ConstColorStruct _cc0) + { portion[0] = _portion0; portion[1] = _portion1; numPortions = 2; cc[0] = _cc0; numConsts = 1; } + void Init(GeneralPortionStruct _portion0, GeneralPortionStruct _portion1) + { portion[0] = _portion0; portion[1] = _portion1; numPortions = 2; numConsts = 0; } - void Init(GeneralPortionStruct _portion0, ConstColorStruct _cc0, ConstColorStruct _cc1) - { portion[0] = _portion0; numPortions = 1; cc[0] = _cc0; cc[1] = _cc1; numConsts = 2; } - void Init(GeneralPortionStruct _portion0, ConstColorStruct _cc0) - { portion[0] = _portion0; numPortions = 1; cc[0] = _cc0; numConsts = 1; } - void Init(GeneralPortionStruct _portion0) - { portion[0] = _portion0; numPortions = 1; numConsts = 0; } + void Init(GeneralPortionStruct _portion0, ConstColorStruct _cc0, ConstColorStruct _cc1) + { portion[0] = _portion0; numPortions = 1; cc[0] = _cc0; cc[1] = _cc1; numConsts = 2; } + void Init(GeneralPortionStruct _portion0, ConstColorStruct _cc0) + { portion[0] = _portion0; numPortions = 1; cc[0] = _cc0; numConsts = 1; } + void Init(GeneralPortionStruct _portion0) + { portion[0] = _portion0; numPortions = 1; numConsts = 0; } - void Validate(int stage); - void SetUnusedLocalConsts(int numGlobalConsts, ConstColorStruct *globalCCs); - void Invoke(int stage); - void ZeroOut(); - GeneralPortionStruct portion[2]; - int numPortions; - ConstColorStruct cc[2]; - int numConsts; + void Validate(int stage); + void SetUnusedLocalConsts(int numGlobalConsts, ConstColorStruct *globalCCs); + void Invoke(int stage); + void ZeroOut(); + GeneralPortionStruct portion[2]; + int numPortions; + ConstColorStruct cc[2]; + int numConsts; }; class GeneralCombinersStruct { public: - void Init() {num = 0;} - void Init(GeneralCombinerStruct _gc) { num = 1; general[0] = _gc; } - GeneralCombinersStruct& operator+=(GeneralCombinerStruct& _gc) - { - if (num < RCP_NUM_GENERAL_COMBINERS) - general[num++] = _gc; - else - errors.set("Too many general combiners."); - return *this; - } - void Validate(int numConsts, ConstColorStruct *cc); - void Invoke(); - GeneralCombinerStruct general[RCP_NUM_GENERAL_COMBINERS]; - int num; + void Init() {num = 0;} + void Init(GeneralCombinerStruct _gc) { num = 1; general[0] = _gc; } + GeneralCombinersStruct& operator+=(GeneralCombinerStruct& _gc) + { + if (num < RCP_NUM_GENERAL_COMBINERS) + general[num++] = _gc; + else + errors.set("Too many general combiners."); + return *this; + } + void Validate(int numConsts, ConstColorStruct *cc); + void Invoke(); + GeneralCombinerStruct general[RCP_NUM_GENERAL_COMBINERS]; + int num; private: - int localConsts; + int localConsts; }; diff --git a/RenderSystems/GL/src/nvparse/rc1.0_register.h b/RenderSystems/GL/src/nvparse/rc1.0_register.h index 4604df10517..3969a1595c8 100644 --- a/RenderSystems/GL/src/nvparse/rc1.0_register.h +++ b/RenderSystems/GL/src/nvparse/rc1.0_register.h @@ -7,10 +7,10 @@ #define RCP_NUM_GENERAL_COMBINERS 8 -#define RCP_RGB 0 -#define RCP_ALPHA 1 -#define RCP_BLUE 2 -#define RCP_NONE 3 +#define RCP_RGB 0 +#define RCP_ALPHA 1 +#define RCP_BLUE 2 +#define RCP_NONE 3 typedef union _RegisterEnum { struct { @@ -36,63 +36,63 @@ typedef union _RegisterEnum { // unless you're absolutely sure of what you're doing! // This constant allocation makes validation *much* cleaner. #define RCP_SET_REGISTER_ENUM(name, channel, readonly, finalonly) \ - ((finalonly << 19) | (readonly << 18) | (channel << 16) | name) - -#define RCP_FOG_RGB RCP_SET_REGISTER_ENUM(GL_FOG, RCP_RGB, 1, 0) -#define RCP_FOG_ALPHA RCP_SET_REGISTER_ENUM(GL_FOG, RCP_ALPHA, 1, 1) -#define RCP_FOG_BLUE RCP_SET_REGISTER_ENUM(GL_FOG, RCP_BLUE, 1, 0) -#define RCP_FOG RCP_SET_REGISTER_ENUM(GL_FOG, RCP_NONE, 1, 0) -#define RCP_PRIMARY_COLOR_RGB RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_RGB, 0, 0) -#define RCP_PRIMARY_COLOR_ALPHA RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_ALPHA, 0, 0) -#define RCP_PRIMARY_COLOR_BLUE RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_BLUE, 0, 0) -#define RCP_PRIMARY_COLOR RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_NONE, 0, 0) -#define RCP_SECONDARY_COLOR_RGB RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_RGB, 0, 0) -#define RCP_SECONDARY_COLOR_ALPHA RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_ALPHA, 0, 0) -#define RCP_SECONDARY_COLOR_BLUE RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_BLUE, 0, 0) -#define RCP_SECONDARY_COLOR RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_NONE, 0, 0) -#define RCP_SPARE0_RGB RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_RGB, 0, 0) -#define RCP_SPARE0_ALPHA RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_ALPHA, 0, 0) -#define RCP_SPARE0_BLUE RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_BLUE, 0, 0) -#define RCP_SPARE0 RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_NONE, 0, 0) -#define RCP_SPARE1_RGB RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_RGB, 0, 0) -#define RCP_SPARE1_ALPHA RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_ALPHA, 0, 0) -#define RCP_SPARE1_BLUE RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_BLUE, 0, 0) -#define RCP_SPARE1 RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_NONE, 0, 0) -#define RCP_TEXTURE0_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_RGB, 0, 0) -#define RCP_TEXTURE0_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_ALPHA, 0, 0) -#define RCP_TEXTURE0_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_BLUE, 0, 0) -#define RCP_TEXTURE0 RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_NONE, 0, 0) -#define RCP_TEXTURE1_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_RGB, 0, 0) -#define RCP_TEXTURE1_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_ALPHA, 0, 0) -#define RCP_TEXTURE1_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_BLUE, 0, 0) -#define RCP_TEXTURE1 RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_NONE, 0, 0) -#define RCP_TEXTURE2_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_RGB, 0, 0) -#define RCP_TEXTURE2_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_ALPHA, 0, 0) -#define RCP_TEXTURE2_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_BLUE, 0, 0) -#define RCP_TEXTURE2 RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_NONE, 0, 0) -#define RCP_TEXTURE3_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_RGB, 0, 0) -#define RCP_TEXTURE3_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_ALPHA, 0, 0) -#define RCP_TEXTURE3_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_BLUE, 0, 0) -#define RCP_TEXTURE3 RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_NONE, 0, 0) -#define RCP_CONST_COLOR0_RGB RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_RGB, 1, 0) -#define RCP_CONST_COLOR0_ALPHA RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_ALPHA, 1, 0) -#define RCP_CONST_COLOR0_BLUE RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_BLUE, 1, 0) -#define RCP_CONST_COLOR0 RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_NONE, 1, 0) -#define RCP_CONST_COLOR1_RGB RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_RGB, 1, 0) -#define RCP_CONST_COLOR1_ALPHA RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_ALPHA, 1, 0) -#define RCP_CONST_COLOR1_BLUE RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_BLUE, 1, 0) -#define RCP_CONST_COLOR1 RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_NONE, 1, 0) -#define RCP_ZERO_RGB RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_RGB, 1, 0) -#define RCP_ZERO_ALPHA RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_ALPHA, 1, 0) -#define RCP_ZERO_BLUE RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_BLUE, 1, 0) -#define RCP_ZERO RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_NONE, 1, 0) -#define RCP_ONE_RGB RCP_SET_REGISTER_ENUM(GL_ONE, RCP_RGB, 1, 0) -#define RCP_ONE_ALPHA RCP_SET_REGISTER_ENUM(GL_ONE, RCP_ALPHA, 1, 0) -#define RCP_ONE_BLUE RCP_SET_REGISTER_ENUM(GL_ONE, RCP_BLUE, 1, 0) -#define RCP_ONE RCP_SET_REGISTER_ENUM(GL_ONE, RCP_NONE, 1, 0) -#define RCP_DISCARD RCP_SET_REGISTER_ENUM(GL_DISCARD_NV, RCP_NONE, 0, 0) -#define RCP_FINAL_PRODUCT RCP_SET_REGISTER_ENUM(GL_E_TIMES_F_NV, RCP_NONE, 1, 1) -#define RCP_COLOR_SUM RCP_SET_REGISTER_ENUM(GL_SPARE0_PLUS_SECONDARY_COLOR_NV, RCP_NONE, 1, 1) + ((finalonly << 19) | (readonly << 18) | (channel << 16) | name) + +#define RCP_FOG_RGB RCP_SET_REGISTER_ENUM(GL_FOG, RCP_RGB, 1, 0) +#define RCP_FOG_ALPHA RCP_SET_REGISTER_ENUM(GL_FOG, RCP_ALPHA, 1, 1) +#define RCP_FOG_BLUE RCP_SET_REGISTER_ENUM(GL_FOG, RCP_BLUE, 1, 0) +#define RCP_FOG RCP_SET_REGISTER_ENUM(GL_FOG, RCP_NONE, 1, 0) +#define RCP_PRIMARY_COLOR_RGB RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_RGB, 0, 0) +#define RCP_PRIMARY_COLOR_ALPHA RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_ALPHA, 0, 0) +#define RCP_PRIMARY_COLOR_BLUE RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_BLUE, 0, 0) +#define RCP_PRIMARY_COLOR RCP_SET_REGISTER_ENUM(GL_PRIMARY_COLOR_NV, RCP_NONE, 0, 0) +#define RCP_SECONDARY_COLOR_RGB RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_RGB, 0, 0) +#define RCP_SECONDARY_COLOR_ALPHA RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_ALPHA, 0, 0) +#define RCP_SECONDARY_COLOR_BLUE RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_BLUE, 0, 0) +#define RCP_SECONDARY_COLOR RCP_SET_REGISTER_ENUM(GL_SECONDARY_COLOR_NV, RCP_NONE, 0, 0) +#define RCP_SPARE0_RGB RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_RGB, 0, 0) +#define RCP_SPARE0_ALPHA RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_ALPHA, 0, 0) +#define RCP_SPARE0_BLUE RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_BLUE, 0, 0) +#define RCP_SPARE0 RCP_SET_REGISTER_ENUM(GL_SPARE0_NV, RCP_NONE, 0, 0) +#define RCP_SPARE1_RGB RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_RGB, 0, 0) +#define RCP_SPARE1_ALPHA RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_ALPHA, 0, 0) +#define RCP_SPARE1_BLUE RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_BLUE, 0, 0) +#define RCP_SPARE1 RCP_SET_REGISTER_ENUM(GL_SPARE1_NV, RCP_NONE, 0, 0) +#define RCP_TEXTURE0_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_RGB, 0, 0) +#define RCP_TEXTURE0_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_ALPHA, 0, 0) +#define RCP_TEXTURE0_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_BLUE, 0, 0) +#define RCP_TEXTURE0 RCP_SET_REGISTER_ENUM(GL_TEXTURE0_ARB, RCP_NONE, 0, 0) +#define RCP_TEXTURE1_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_RGB, 0, 0) +#define RCP_TEXTURE1_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_ALPHA, 0, 0) +#define RCP_TEXTURE1_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_BLUE, 0, 0) +#define RCP_TEXTURE1 RCP_SET_REGISTER_ENUM(GL_TEXTURE1_ARB, RCP_NONE, 0, 0) +#define RCP_TEXTURE2_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_RGB, 0, 0) +#define RCP_TEXTURE2_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_ALPHA, 0, 0) +#define RCP_TEXTURE2_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_BLUE, 0, 0) +#define RCP_TEXTURE2 RCP_SET_REGISTER_ENUM(GL_TEXTURE2_ARB, RCP_NONE, 0, 0) +#define RCP_TEXTURE3_RGB RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_RGB, 0, 0) +#define RCP_TEXTURE3_ALPHA RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_ALPHA, 0, 0) +#define RCP_TEXTURE3_BLUE RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_BLUE, 0, 0) +#define RCP_TEXTURE3 RCP_SET_REGISTER_ENUM(GL_TEXTURE3_ARB, RCP_NONE, 0, 0) +#define RCP_CONST_COLOR0_RGB RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_RGB, 1, 0) +#define RCP_CONST_COLOR0_ALPHA RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_ALPHA, 1, 0) +#define RCP_CONST_COLOR0_BLUE RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_BLUE, 1, 0) +#define RCP_CONST_COLOR0 RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR0_NV, RCP_NONE, 1, 0) +#define RCP_CONST_COLOR1_RGB RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_RGB, 1, 0) +#define RCP_CONST_COLOR1_ALPHA RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_ALPHA, 1, 0) +#define RCP_CONST_COLOR1_BLUE RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_BLUE, 1, 0) +#define RCP_CONST_COLOR1 RCP_SET_REGISTER_ENUM(GL_CONSTANT_COLOR1_NV, RCP_NONE, 1, 0) +#define RCP_ZERO_RGB RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_RGB, 1, 0) +#define RCP_ZERO_ALPHA RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_ALPHA, 1, 0) +#define RCP_ZERO_BLUE RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_BLUE, 1, 0) +#define RCP_ZERO RCP_SET_REGISTER_ENUM(GL_ZERO, RCP_NONE, 1, 0) +#define RCP_ONE_RGB RCP_SET_REGISTER_ENUM(GL_ONE, RCP_RGB, 1, 0) +#define RCP_ONE_ALPHA RCP_SET_REGISTER_ENUM(GL_ONE, RCP_ALPHA, 1, 0) +#define RCP_ONE_BLUE RCP_SET_REGISTER_ENUM(GL_ONE, RCP_BLUE, 1, 0) +#define RCP_ONE RCP_SET_REGISTER_ENUM(GL_ONE, RCP_NONE, 1, 0) +#define RCP_DISCARD RCP_SET_REGISTER_ENUM(GL_DISCARD_NV, RCP_NONE, 0, 0) +#define RCP_FINAL_PRODUCT RCP_SET_REGISTER_ENUM(GL_E_TIMES_F_NV, RCP_NONE, 1, 1) +#define RCP_COLOR_SUM RCP_SET_REGISTER_ENUM(GL_SPARE0_PLUS_SECONDARY_COLOR_NV, RCP_NONE, 1, 1) #define MAP_CHANNEL(channel) ((RCP_RGB == (channel)) ? GL_RGB : (RCP_ALPHA == (channel) ? GL_ALPHA : GL_BLUE)) @@ -114,51 +114,51 @@ typedef union _BiasScaleEnum { // This constant allocation makes validation *much* cleaner. #define RCP_SET_BIAS_SCALE_ENUM(bias, scale) ((scale << 16) | bias) -#define RCP_BIAS_BY_NEGATIVE_ONE_HALF_SCALE_BY_TWO RCP_SET_BIAS_SCALE_ENUM(GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_SCALE_BY_TWO_NV) -#define RCP_BIAS_BY_NEGATIVE_ONE_HALF RCP_SET_BIAS_SCALE_ENUM(GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_NONE) -#define RCP_SCALE_BY_ONE_HALF RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_ONE_HALF_NV) -#define RCP_SCALE_BY_ONE RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_NONE) -#define RCP_SCALE_BY_TWO RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_TWO_NV) -#define RCP_SCALE_BY_FOUR RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_FOUR_NV) +#define RCP_BIAS_BY_NEGATIVE_ONE_HALF_SCALE_BY_TWO RCP_SET_BIAS_SCALE_ENUM(GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_SCALE_BY_TWO_NV) +#define RCP_BIAS_BY_NEGATIVE_ONE_HALF RCP_SET_BIAS_SCALE_ENUM(GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_NONE) +#define RCP_SCALE_BY_ONE_HALF RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_ONE_HALF_NV) +#define RCP_SCALE_BY_ONE RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_NONE) +#define RCP_SCALE_BY_TWO RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_TWO_NV) +#define RCP_SCALE_BY_FOUR RCP_SET_BIAS_SCALE_ENUM(GL_NONE, GL_SCALE_BY_FOUR_NV) class MappedRegisterStruct { public: - void Init(RegisterEnum _reg, int _map = GL_UNSIGNED_IDENTITY_NV) - { - if (RCP_ONE == _reg.word) { - _reg.word = RCP_ZERO; - switch (_map) { - case GL_UNSIGNED_IDENTITY_NV: - _map = GL_UNSIGNED_INVERT_NV; - break; - case GL_UNSIGNED_INVERT_NV: - _map = GL_UNSIGNED_IDENTITY_NV; - break; - case GL_EXPAND_NORMAL_NV: - _map = GL_UNSIGNED_INVERT_NV; - break; - case GL_EXPAND_NEGATE_NV: - _map = GL_EXPAND_NORMAL_NV; - break; - case GL_HALF_BIAS_NORMAL_NV: - _map = GL_HALF_BIAS_NEGATE_NV; - break; - case GL_HALF_BIAS_NEGATE_NV: - _map = GL_HALF_BIAS_NORMAL_NV; - break; - case GL_SIGNED_IDENTITY_NV: - _map = GL_UNSIGNED_INVERT_NV; - break; - case GL_SIGNED_NEGATE_NV: - _map = GL_EXPAND_NORMAL_NV; - break; - } - } - map = _map; - reg = _reg; - } - int map; - RegisterEnum reg; + void Init(RegisterEnum _reg, int _map = GL_UNSIGNED_IDENTITY_NV) + { + if (RCP_ONE == _reg.word) { + _reg.word = RCP_ZERO; + switch (_map) { + case GL_UNSIGNED_IDENTITY_NV: + _map = GL_UNSIGNED_INVERT_NV; + break; + case GL_UNSIGNED_INVERT_NV: + _map = GL_UNSIGNED_IDENTITY_NV; + break; + case GL_EXPAND_NORMAL_NV: + _map = GL_UNSIGNED_INVERT_NV; + break; + case GL_EXPAND_NEGATE_NV: + _map = GL_EXPAND_NORMAL_NV; + break; + case GL_HALF_BIAS_NORMAL_NV: + _map = GL_HALF_BIAS_NEGATE_NV; + break; + case GL_HALF_BIAS_NEGATE_NV: + _map = GL_HALF_BIAS_NORMAL_NV; + break; + case GL_SIGNED_IDENTITY_NV: + _map = GL_UNSIGNED_INVERT_NV; + break; + case GL_SIGNED_NEGATE_NV: + _map = GL_EXPAND_NORMAL_NV; + break; + } + } + map = _map; + reg = _reg; + } + int map; + RegisterEnum reg; }; #ifdef TEST_BIT_FIELDS @@ -190,8 +190,8 @@ class RegisterEnumTest { error = true; if (error) { - fprintf(stderr, "ERROR: Bit Fields were not compiled correctly in " __FILE__ "!\n"); - exit(1); + fprintf(stderr, "ERROR: Bit Fields were not compiled correctly in " __FILE__ "!\n"); + exit(1); } } }; diff --git a/RenderSystems/GL/src/nvparse/ts1.0_inst.cpp b/RenderSystems/GL/src/nvparse/ts1.0_inst.cpp index c9d4ae72fa9..a43d69e1d3b 100644 --- a/RenderSystems/GL/src/nvparse/ts1.0_inst.cpp +++ b/RenderSystems/GL/src/nvparse/ts1.0_inst.cpp @@ -2,292 +2,292 @@ Inst::Inst(int inst, float arg0, float arg1, float arg2, float arg3, float arg4, float arg5, float arg6) { - opcode.word = inst; - expand = 0; - args[0] = arg0; - args[1] = arg1; - args[2] = arg2; - args[3] = arg3; - args[4] = arg4; - args[5] = arg5; - args[6] = arg6; + opcode.word = inst; + expand = 0; + args[0] = arg0; + args[1] = arg1; + args[2] = arg2; + args[3] = arg3; + args[4] = arg4; + args[5] = arg5; + args[6] = arg6; } Inst::Inst(int inst, MappedVariablePtr arg0, float arg1, float arg2, float arg3, float arg4, float arg5, float arg6) { - opcode.word = inst; - expand = arg0->expand; - args[0] = arg0->var; - args[1] = arg1; - args[2] = arg2; - args[3] = arg3; - args[4] = arg4; - args[5] = arg5; - args[6] = arg6; + opcode.word = inst; + expand = arg0->expand; + args[0] = arg0->var; + args[1] = arg1; + args[2] = arg2; + args[3] = arg3; + args[4] = arg4; + args[5] = arg5; + args[6] = arg6; } void Inst::Invoke() { - switch(opcode.word) { - case TSP_NOP: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE); - break; - case TSP_TEXTURE_1D: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_1D); - break; - case TSP_TEXTURE_2D: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); - break; + switch(opcode.word) { + case TSP_NOP: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE); + break; + case TSP_TEXTURE_1D: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_1D); + break; + case TSP_TEXTURE_2D: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D); + break; #if defined(GL_EXT_texture_rectangle) - case TSP_TEXTURE_RECTANGLE: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_RECTANGLE_EXT); - break; + case TSP_TEXTURE_RECTANGLE: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_RECTANGLE_EXT); + break; #elif defined(GL_NV_texture_rectangle) case TSP_TEXTURE_RECTANGLE: glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_RECTANGLE_NV); break; #else - case TSP_TEXTURE_RECTANGLE: + case TSP_TEXTURE_RECTANGLE: break; #endif - case TSP_TEXTURE_3D: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D); - break; - case TSP_TEXTURE_CUBE_MAP: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB); - break; - case TSP_CULL_FRAGMENT: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_CULL_FRAGMENT_NV); - glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CULL_MODES_NV, &args[0]); - break; - case TSP_PASS_THROUGH: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_PASS_THROUGH_NV); - break; - case TSP_OFFSET_2D_SCALE: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_SCALE_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]); - glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV, args[5]); - glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV, args[6]); - break; - case TSP_OFFSET_2D: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]); - break; - case TSP_OFFSET_RECTANGLE_SCALE: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]); - glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV, args[5]); - glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV, args[6]); - break; - case TSP_OFFSET_RECTANGLE: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_RECTANGLE_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]); - break; - case TSP_DEPENDENT_AR: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_AR_TEXTURE_2D_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DEPENDENT_GB: - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_2D_1_OF_2: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_2D_2_OF_2: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_RECTANGLE_1_OF_2: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_RECTANGLE_2_OF_2: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_DEPTH_REPLACE_1_OF_2: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_DEPTH_REPLACE_2_OF_2: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DEPTH_REPLACE_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_3D_1_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_3D_2_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_3D_3_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_CUBE_MAP_1_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_CUBE_MAP_2_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_CUBE_MAP_3_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, &args[1]); - break; - case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - break; - case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3: - if (expand) - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); - else - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV); - glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); - glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, &args[1]); - break; - } + case TSP_TEXTURE_3D: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D); + break; + case TSP_TEXTURE_CUBE_MAP: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB); + break; + case TSP_CULL_FRAGMENT: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_CULL_FRAGMENT_NV); + glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CULL_MODES_NV, &args[0]); + break; + case TSP_PASS_THROUGH: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_PASS_THROUGH_NV); + break; + case TSP_OFFSET_2D_SCALE: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_SCALE_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]); + glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV, args[5]); + glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV, args[6]); + break; + case TSP_OFFSET_2D: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]); + break; + case TSP_OFFSET_RECTANGLE_SCALE: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]); + glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV, args[5]); + glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV, args[6]); + break; + case TSP_OFFSET_RECTANGLE: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_RECTANGLE_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &args[1]); + break; + case TSP_DEPENDENT_AR: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_AR_TEXTURE_2D_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DEPENDENT_GB: + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_2D_1_OF_2: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_2D_2_OF_2: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_RECTANGLE_1_OF_2: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_RECTANGLE_2_OF_2: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_DEPTH_REPLACE_1_OF_2: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_DEPTH_REPLACE_2_OF_2: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DEPTH_REPLACE_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_3D_1_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_3D_2_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_3D_3_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_CUBE_MAP_1_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_CUBE_MAP_2_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_CUBE_MAP_3_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, &args[1]); + break; + case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + break; + case TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3: + if (expand) + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV); + else + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_UNSIGNED_IDENTITY_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV); + glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + (int)args[0]); + glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, &args[1]); + break; + } } diff --git a/RenderSystems/GL/src/nvparse/ts1.0_inst.h b/RenderSystems/GL/src/nvparse/ts1.0_inst.h index 88b6d10c7a7..f44b2792e44 100644 --- a/RenderSystems/GL/src/nvparse/ts1.0_inst.h +++ b/RenderSystems/GL/src/nvparse/ts1.0_inst.h @@ -30,70 +30,70 @@ typedef union _InstructionEnum { // unless you're absolutely sure of what you're doing! // This constant allocation makes validation *much* cleaner. #define TSP_SET_INSTRUCTION_ENUM(inst, st, dep, noout) \ - ((noout << 15) | (dep << 14) | (st << 10) | inst) - -#define TSP_NOP TSP_SET_INSTRUCTION_ENUM(0, 0, 0, 1) -#define TSP_TEXTURE_1D TSP_SET_INSTRUCTION_ENUM(1, 0, 0, 0) -#define TSP_TEXTURE_2D TSP_SET_INSTRUCTION_ENUM(2, 0, 0, 0) -#define TSP_TEXTURE_RECTANGLE TSP_SET_INSTRUCTION_ENUM(3, 0, 0, 0) -#define TSP_TEXTURE_3D TSP_SET_INSTRUCTION_ENUM(4, 0, 0, 0) -#define TSP_TEXTURE_CUBE_MAP TSP_SET_INSTRUCTION_ENUM(5, 0, 0, 0) -#define TSP_CULL_FRAGMENT TSP_SET_INSTRUCTION_ENUM(6, 0, 0, 1) -#define TSP_PASS_THROUGH TSP_SET_INSTRUCTION_ENUM(7, 0, 0, 0) -#define TSP_DEPENDENT_AR TSP_SET_INSTRUCTION_ENUM(8, 0, 1, 0) -#define TSP_DEPENDENT_GB TSP_SET_INSTRUCTION_ENUM(9, 0, 1, 0) -#define TSP_OFFSET_2D TSP_SET_INSTRUCTION_ENUM(10, 0, 1, 0) -#define TSP_OFFSET_2D_SCALE TSP_SET_INSTRUCTION_ENUM(11, 0, 1, 0) -#define TSP_OFFSET_RECTANGLE TSP_SET_INSTRUCTION_ENUM(12, 0, 1, 0) -#define TSP_OFFSET_RECTANGLE_SCALE TSP_SET_INSTRUCTION_ENUM(13, 0, 1, 0) - -#define TSP_DOT_PRODUCT_2D_1_OF_2 TSP_SET_INSTRUCTION_ENUM(14, 0, 1, 1) -#define TSP_DOT_PRODUCT_2D_2_OF_2 TSP_SET_INSTRUCTION_ENUM(14, 1, 1, 0) - -#define TSP_DOT_PRODUCT_RECTANGLE_1_OF_2 TSP_SET_INSTRUCTION_ENUM(15, 0, 1, 1) -#define TSP_DOT_PRODUCT_RECTANGLE_2_OF_2 TSP_SET_INSTRUCTION_ENUM(15, 1, 1, 0) - -#define TSP_DOT_PRODUCT_DEPTH_REPLACE_1_OF_2 TSP_SET_INSTRUCTION_ENUM(16, 0, 1, 1) -#define TSP_DOT_PRODUCT_DEPTH_REPLACE_2_OF_2 TSP_SET_INSTRUCTION_ENUM(16, 1, 1, 0) - -#define TSP_DOT_PRODUCT_3D_1_OF_3 TSP_SET_INSTRUCTION_ENUM(17, 0, 1, 1) -#define TSP_DOT_PRODUCT_3D_2_OF_3 TSP_SET_INSTRUCTION_ENUM(17, 1, 1, 1) -#define TSP_DOT_PRODUCT_3D_3_OF_3 TSP_SET_INSTRUCTION_ENUM(17, 2, 1, 0) - -#define TSP_DOT_PRODUCT_CUBE_MAP_1_OF_3 TSP_SET_INSTRUCTION_ENUM(18, 0, 1, 1) -#define TSP_DOT_PRODUCT_CUBE_MAP_2_OF_3 TSP_SET_INSTRUCTION_ENUM(18, 1, 1, 1) -#define TSP_DOT_PRODUCT_CUBE_MAP_3_OF_3 TSP_SET_INSTRUCTION_ENUM(18, 2, 1, 0) - -#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3 TSP_SET_INSTRUCTION_ENUM(19, 0, 1, 1) -#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3 TSP_SET_INSTRUCTION_ENUM(19, 1, 1, 1) -#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3 TSP_SET_INSTRUCTION_ENUM(19, 2, 1, 0) - -#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3 TSP_SET_INSTRUCTION_ENUM(20, 0, 1, 1) -#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3 TSP_SET_INSTRUCTION_ENUM(20, 1, 1, 1) -#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3 TSP_SET_INSTRUCTION_ENUM(20, 2, 1, 0) - -#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3 TSP_SET_INSTRUCTION_ENUM(21, 0, 1, 1) -#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3 TSP_SET_INSTRUCTION_ENUM(21, 1, 1, 0) -#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3 TSP_SET_INSTRUCTION_ENUM(21, 2, 1, 0) - -#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3 TSP_SET_INSTRUCTION_ENUM(22, 0, 1, 1) -#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3 TSP_SET_INSTRUCTION_ENUM(22, 1, 1, 0) -#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3 TSP_SET_INSTRUCTION_ENUM(22, 2, 1, 0) + ((noout << 15) | (dep << 14) | (st << 10) | inst) + +#define TSP_NOP TSP_SET_INSTRUCTION_ENUM(0, 0, 0, 1) +#define TSP_TEXTURE_1D TSP_SET_INSTRUCTION_ENUM(1, 0, 0, 0) +#define TSP_TEXTURE_2D TSP_SET_INSTRUCTION_ENUM(2, 0, 0, 0) +#define TSP_TEXTURE_RECTANGLE TSP_SET_INSTRUCTION_ENUM(3, 0, 0, 0) +#define TSP_TEXTURE_3D TSP_SET_INSTRUCTION_ENUM(4, 0, 0, 0) +#define TSP_TEXTURE_CUBE_MAP TSP_SET_INSTRUCTION_ENUM(5, 0, 0, 0) +#define TSP_CULL_FRAGMENT TSP_SET_INSTRUCTION_ENUM(6, 0, 0, 1) +#define TSP_PASS_THROUGH TSP_SET_INSTRUCTION_ENUM(7, 0, 0, 0) +#define TSP_DEPENDENT_AR TSP_SET_INSTRUCTION_ENUM(8, 0, 1, 0) +#define TSP_DEPENDENT_GB TSP_SET_INSTRUCTION_ENUM(9, 0, 1, 0) +#define TSP_OFFSET_2D TSP_SET_INSTRUCTION_ENUM(10, 0, 1, 0) +#define TSP_OFFSET_2D_SCALE TSP_SET_INSTRUCTION_ENUM(11, 0, 1, 0) +#define TSP_OFFSET_RECTANGLE TSP_SET_INSTRUCTION_ENUM(12, 0, 1, 0) +#define TSP_OFFSET_RECTANGLE_SCALE TSP_SET_INSTRUCTION_ENUM(13, 0, 1, 0) + +#define TSP_DOT_PRODUCT_2D_1_OF_2 TSP_SET_INSTRUCTION_ENUM(14, 0, 1, 1) +#define TSP_DOT_PRODUCT_2D_2_OF_2 TSP_SET_INSTRUCTION_ENUM(14, 1, 1, 0) + +#define TSP_DOT_PRODUCT_RECTANGLE_1_OF_2 TSP_SET_INSTRUCTION_ENUM(15, 0, 1, 1) +#define TSP_DOT_PRODUCT_RECTANGLE_2_OF_2 TSP_SET_INSTRUCTION_ENUM(15, 1, 1, 0) + +#define TSP_DOT_PRODUCT_DEPTH_REPLACE_1_OF_2 TSP_SET_INSTRUCTION_ENUM(16, 0, 1, 1) +#define TSP_DOT_PRODUCT_DEPTH_REPLACE_2_OF_2 TSP_SET_INSTRUCTION_ENUM(16, 1, 1, 0) + +#define TSP_DOT_PRODUCT_3D_1_OF_3 TSP_SET_INSTRUCTION_ENUM(17, 0, 1, 1) +#define TSP_DOT_PRODUCT_3D_2_OF_3 TSP_SET_INSTRUCTION_ENUM(17, 1, 1, 1) +#define TSP_DOT_PRODUCT_3D_3_OF_3 TSP_SET_INSTRUCTION_ENUM(17, 2, 1, 0) + +#define TSP_DOT_PRODUCT_CUBE_MAP_1_OF_3 TSP_SET_INSTRUCTION_ENUM(18, 0, 1, 1) +#define TSP_DOT_PRODUCT_CUBE_MAP_2_OF_3 TSP_SET_INSTRUCTION_ENUM(18, 1, 1, 1) +#define TSP_DOT_PRODUCT_CUBE_MAP_3_OF_3 TSP_SET_INSTRUCTION_ENUM(18, 2, 1, 0) + +#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3 TSP_SET_INSTRUCTION_ENUM(19, 0, 1, 1) +#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3 TSP_SET_INSTRUCTION_ENUM(19, 1, 1, 1) +#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3 TSP_SET_INSTRUCTION_ENUM(19, 2, 1, 0) + +#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3 TSP_SET_INSTRUCTION_ENUM(20, 0, 1, 1) +#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3 TSP_SET_INSTRUCTION_ENUM(20, 1, 1, 1) +#define TSP_DOT_PRODUCT_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3 TSP_SET_INSTRUCTION_ENUM(20, 2, 1, 0) + +#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_1_OF_3 TSP_SET_INSTRUCTION_ENUM(21, 0, 1, 1) +#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_2_OF_3 TSP_SET_INSTRUCTION_ENUM(21, 1, 1, 0) +#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_EYE_FROM_QS_3_OF_3 TSP_SET_INSTRUCTION_ENUM(21, 2, 1, 0) + +#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_1_OF_3 TSP_SET_INSTRUCTION_ENUM(22, 0, 1, 1) +#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_2_OF_3 TSP_SET_INSTRUCTION_ENUM(22, 1, 1, 0) +#define TSP_DOT_PRODUCT_CUBE_MAP_AND_REFLECT_CUBE_MAP_CONST_EYE_3_OF_3 TSP_SET_INSTRUCTION_ENUM(22, 2, 1, 0) typedef struct _MappedVariable { - float var; - int expand; + float var; + int expand; } MappedVariable, *MappedVariablePtr; typedef class Inst { public: - Inst(int inst, float arg0 = 0., float arg1 = 0., float arg2 = 0., float arg3 = 0., float arg4 = 0., float arg5 = 0., float arg6 = 0.); - Inst(int inst, MappedVariablePtr arg0, float arg1 = 0., float arg2 = 0., float arg3 = 0., float arg4 = 0., float arg5 = 0., float arg6 = 0.); - void Invoke(); - InstructionEnum opcode; - float args[TSP_MAX_ARGS]; + Inst(int inst, float arg0 = 0., float arg1 = 0., float arg2 = 0., float arg3 = 0., float arg4 = 0., float arg5 = 0., float arg6 = 0.); + Inst(int inst, MappedVariablePtr arg0, float arg1 = 0., float arg2 = 0., float arg3 = 0., float arg4 = 0., float arg5 = 0., float arg6 = 0.); + void Invoke(); + InstructionEnum opcode; + float args[TSP_MAX_ARGS]; private: - int expand; + int expand; } Inst, *InstPtr; #ifdef TEST_BIT_FIELDS @@ -127,8 +127,8 @@ class InstructionEnumTest { error = true; if (error) { - fprintf(stderr, "ERROR: Bit Fields were not compiled correctly in " __FILE__ "!\n"); - exit(1); + fprintf(stderr, "ERROR: Bit Fields were not compiled correctly in " __FILE__ "!\n"); + exit(1); } } }; diff --git a/RenderSystems/GL/src/nvparse/ts1.0_inst_list.cpp b/RenderSystems/GL/src/nvparse/ts1.0_inst_list.cpp index bd7d5a014f3..41a50c2fd6a 100644 --- a/RenderSystems/GL/src/nvparse/ts1.0_inst_list.cpp +++ b/RenderSystems/GL/src/nvparse/ts1.0_inst_list.cpp @@ -12,30 +12,30 @@ const int instListInc = 4; InstList::InstList() { - size = 0; - max = instListInc; - list = (InstPtr)malloc(sizeof(Inst) * max); + size = 0; + max = instListInc; + list = (InstPtr)malloc(sizeof(Inst) * max); } InstList::~InstList() { - free(list); + free(list); } int InstList::Size() { - return size; + return size; } InstList& InstList::operator+=(InstPtr t) { - if (size == max) { - /* Extend list size by instListInc amount */ - max += instListInc; - list = (InstPtr)realloc(list, sizeof(Inst) * max); - } - list[size++] = *t; - return *this; + if (size == max) { + /* Extend list size by instListInc amount */ + max += instListInc; + list = (InstPtr)realloc(list, sizeof(Inst) * max); + } + list[size++] = *t; + return *this; } void InstList::Invoke() @@ -44,70 +44,70 @@ void InstList::Invoke() GLint activeTex = 0; glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); - for (i = 0; i < size; i++) { - // set active texture - glActiveTextureARB(GL_TEXTURE0_ARB + i); - list[i].Invoke(); - } + for (i = 0; i < size; i++) { + // set active texture + glActiveTextureARB(GL_TEXTURE0_ARB + i); + list[i].Invoke(); + } - glActiveTextureARB(activeTex); + glActiveTextureARB(activeTex); } void InstList::Validate() { - if (size > TSP_NUM_TEXTURE_UNITS) - errors.set("too many instructions"); - int i; - for (i = 0; i < size; i++) { - int stage = list[i].opcode.bits.stage; - if (stage > i) - errors.set("prior stage missing"); - if (list[i].opcode.bits.instruction != list[i - stage].opcode.bits.instruction) - errors.set("stage mismatch"); - if (list[i].opcode.bits.dependent) { - int previousTexture = (int)list[i].args[0]; - if (previousTexture >= i - stage) - errors.set("invalid texture reference"); - if (list[previousTexture].opcode.bits.noOutput) - errors.set("no output on referenced texture"); - } - } - - // Assign remaining undesignated texture units to nop - for (; i < TSP_NUM_TEXTURE_UNITS; i++) { - InstPtr nopInst = new Inst(TSP_NOP); - *this += nopInst; - delete nopInst; - } + if (size > TSP_NUM_TEXTURE_UNITS) + errors.set("too many instructions"); + int i; + for (i = 0; i < size; i++) { + int stage = list[i].opcode.bits.stage; + if (stage > i) + errors.set("prior stage missing"); + if (list[i].opcode.bits.instruction != list[i - stage].opcode.bits.instruction) + errors.set("stage mismatch"); + if (list[i].opcode.bits.dependent) { + int previousTexture = (int)list[i].args[0]; + if (previousTexture >= i - stage) + errors.set("invalid texture reference"); + if (list[previousTexture].opcode.bits.noOutput) + errors.set("no output on referenced texture"); + } + } + + // Assign remaining undesignated texture units to nop + for (; i < TSP_NUM_TEXTURE_UNITS; i++) { + InstPtr nopInst = new Inst(TSP_NOP); + *this += nopInst; + delete nopInst; + } } bool is_ts10(const char * s) { - return ! strncmp(s, "!!TS1.0", 7); + return ! strncmp(s, "!!TS1.0", 7); } bool ts10_init_more() { - static bool tsinit = false; - if (tsinit == false ) - { + static bool tsinit = false; + if (tsinit == false ) + { /* - if(! glh_init_extensions( "GL_NV_texture_shader " "GL_ARB_multitexture " )) - { - errors.set("unable to initialize GL_NV_texture_shader\n"); - return false; - } - else - { + if(! glh_init_extensions( "GL_NV_texture_shader " "GL_ARB_multitexture " )) + { + errors.set("unable to initialize GL_NV_texture_shader\n"); + return false; + } + else + { */ - tsinit = true; + tsinit = true; /* - } + } */ - } - errors.reset(); - line_number = 1; - return true; + } + errors.reset(); + line_number = 1; + return true; } /* diff --git a/RenderSystems/GL/src/nvparse/ts1.0_inst_list.h b/RenderSystems/GL/src/nvparse/ts1.0_inst_list.h index 00b9fd1229a..e94cb8c191b 100644 --- a/RenderSystems/GL/src/nvparse/ts1.0_inst_list.h +++ b/RenderSystems/GL/src/nvparse/ts1.0_inst_list.h @@ -5,12 +5,12 @@ typedef class InstList { public: - InstList(); - ~InstList(); - int Size(); - InstList& operator+=(InstPtr t); - void Validate(); - void Invoke(); + InstList(); + ~InstList(); + int Size(); + InstList& operator+=(InstPtr t); + void Validate(); + void Invoke(); private: InstPtr list; int size; diff --git a/RenderSystems/GL/src/nvparse/vcp1.0_impl.cpp b/RenderSystems/GL/src/nvparse/vcp1.0_impl.cpp index 4e9d67fc0f3..8131acde138 100644 --- a/RenderSystems/GL/src/nvparse/vcp1.0_impl.cpp +++ b/RenderSystems/GL/src/nvparse/vcp1.0_impl.cpp @@ -12,238 +12,238 @@ using namespace std; namespace { - void ParseVertexProgramConstants( GLenum target, char *instring); - GLuint LookupTrackMatrix(char *matrixName); - GLuint LookupTrackMatrixTransform(char *matrixTransformName); + void ParseVertexProgramConstants( GLenum target, char *instring); + GLuint LookupTrackMatrix(char *matrixName); + GLuint LookupTrackMatrixTransform(char *matrixTransformName); } bool is_vcp10(const char * s) { - return ! strncmp(s, "!!VCP1.0", 8); + return ! strncmp(s, "!!VCP1.0", 8); } bool vcp10_init(char * s) { - static int vpinit = 0; - - if (vpinit == 0 ) - { + static int vpinit = 0; + + if (vpinit == 0 ) + { /* - if(! glh_init_extensions("GL_NV_vertex_program")) - { - errors.set("unable to initialize GL_NV_vertex_program"); - return false; - } - else - { + if(! glh_init_extensions("GL_NV_vertex_program")) + { + errors.set("unable to initialize GL_NV_vertex_program"); + return false; + } + else + { */ - vpinit = 1; + vpinit = 1; /* - } + } */ - } - - errors.reset(); - line_number = 1; - - myin = s; - - return true; + } + + errors.reset(); + line_number = 1; + + myin = s; + + return true; } int vcp10_parse() { - // parse the constant declarations, setting their values in the GL. - ParseVertexProgramConstants( GL_VERTEX_PROGRAM_NV, myin); - return 0; + // parse the constant declarations, setting their values in the GL. + ParseVertexProgramConstants( GL_VERTEX_PROGRAM_NV, myin); + return 0; } namespace { - - //.----------------------------------------------------------------------------. - //| Function : ParseVertexProgramConstants | - //| Description: Parse and set VP1.0 constant memory based on const | - //| directives. | - //| | - //| Format : c[XX] = (x, y, z, w); # where XXX is an integer 0-95. | - //| : c[XX] = TRACK(matrix, transform); # track a matrix | - //.----------------------------------------------------------------------------. - void ParseVertexProgramConstants(GLenum target, char *instring) - { - // don't overwrite the original string. - char *tmpstring = new char[strlen(instring)+1]; - strcpy(tmpstring, instring); - - char lineSeparator[] = "\n"; - //char wordSeparator[] = " \t"; - char error[256]; - char dummy[256]; - char *token; - - //iterate over the lines in the string - token = strtok(tmpstring, lineSeparator); - - // we assume the first line is the "!!VCP1.0 line". - if (token != NULL) - { - token = strtok(NULL, lineSeparator); - } - - int iLineCount = 1; // skip first line - - while (token != NULL) - { - iLineCount++; - - // if the first non-whitespace character is a #, this is a comment. Skip. - if (!sscanf(token, " #%s", dummy)) - { // not a comment. Is it a constant? - - // strip whitespace from the beginning of the string - int i; - for (i = 0; i < (int)strlen(token) && isspace(token[i]); i++); - token += i; - - if (strlen(token) > 0 && // this is not a blank line and - !strnicmp(token, "c[", 2)) // the first word is of the form "c[xx]", so its a constant. - { - int iConstID; - int iNumValuesAssigned; - char c[6]; - - iNumValuesAssigned = sscanf(token, " %c [ %d ] = %s ", &c[0], &iConstID, dummy); - - if (3 != iNumValuesAssigned || toupper(c[0]) != 'C') - { // error in constant directive. - sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token); - errors.set(error); - } - else if (!strnicmp(dummy, "track", 5)) - { // this is a TrackMatrix directive - char matrixName[256], matrixTransformName[256]; - - // the series of %c's are to make sure "track(" doesn't get glommed onto the matrixName - iNumValuesAssigned = sscanf(token, - " %c [ %d ] = %c%c%c%c%c ( %s %s ) ;", - &c[0], &iConstID, &c[1], &c[2], &c[3], &c[4], &c[5], - matrixName, matrixTransformName); - - if (iNumValuesAssigned < 8) - { - sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token); - errors.set(error); - } - else - { - char *buffer; - if (9 == iNumValuesAssigned) - { - // just need to remove any junk from the matrix names and IDs. - buffer = strstr(matrixName, ","); - if (buffer) - *buffer = 0; - - buffer = strstr(matrixTransformName, ")"); - if (buffer) - *buffer = 0; - } - else // 8 == iNumValuesAssigned - { - // have to split the two names, since they both were put into the matrixName - buffer = strstr(matrixName, ","); - if (buffer) - { - strcpy(matrixTransformName, buffer + 1); - *buffer = 0; - // get rid of paren at end of transform name, if it is there - buffer = strstr(matrixTransformName, ")"); - if (buffer) - *buffer = 0; - - } - else - { - sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token); - errors.set(error); - } - } - - // constant ID must be modulo 4. - if (0 != (iConstID % 4)) - { - sprintf(error, - "error at line %d \n\"%s\"\n\tglTrackMatrixNV address must be modulo 4\n", - iLineCount, token); - errors.set(error); - } - else if (iConstID < 0 || iConstID > 95) - { - sprintf(error, - "error at line %d \n\"%s\"\n\tConstant address out of range\n", - iLineCount, token); - errors.set(error); - } - else - { - // get the enum values for the specified matrices - GLuint iMatrixID = LookupTrackMatrix(matrixName); - GLuint iTransformID = LookupTrackMatrixTransform(matrixTransformName); - - if (0 == iMatrixID) - { - sprintf(error, - "error at line %d \n\"%s\"\n\tInvalid Matrix parameter in glTrackMatrixNV.\n", - iLineCount, token); - errors.set(error); - } - else if (0 == iTransformID) - { - sprintf(error, - "error at line %d \n\"%s\"\n\tInvalid Transform parameter in glTrackMatrixNV\n", - iLineCount, token); - errors.set(error); - } - else - { - // untrack any currently tracked matrix - glTrackMatrixNV(target, iConstID, GL_NONE, GL_IDENTITY_NV); - - // tell GL the matrix to track - glTrackMatrixNV(target, iConstID, iMatrixID, iTransformID); - } - } - } - } - else // this is a constant directive - { - float xyzw[4] = {0, 0, 0, 0}; - iNumValuesAssigned = sscanf(token, - " %c [ %d ] = ( %f , %f , %f , %f ) ; ", - &c[0], &iConstID, xyzw, xyzw + 1, xyzw + 2, xyzw + 3); - - if (6 != iNumValuesAssigned) - { // error in constant directive. - sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token); - errors.set(error); - } - else if (iConstID < 0 || iConstID > 95) - { - sprintf(error, - "error at line %d \n\"%s\"\n\tConstant address out of range\n", - iLineCount, token); - errors.set(error); - } - else - { - // Always set the closest matrix location to tracking NONE to avoid errors! - glTrackMatrixNV(target, iConstID - (iConstID % 4), GL_NONE, GL_IDENTITY_NV); - - // tell GL the constant values - glProgramParameter4fvNV(target, iConstID, xyzw); - } - } + + //.----------------------------------------------------------------------------. + //| Function : ParseVertexProgramConstants | + //| Description: Parse and set VP1.0 constant memory based on const | + //| directives. | + //| | + //| Format : c[XX] = (x, y, z, w); # where XXX is an integer 0-95. | + //| : c[XX] = TRACK(matrix, transform); # track a matrix | + //.----------------------------------------------------------------------------. + void ParseVertexProgramConstants(GLenum target, char *instring) + { + // don't overwrite the original string. + char *tmpstring = new char[strlen(instring)+1]; + strcpy(tmpstring, instring); + + char lineSeparator[] = "\n"; + //char wordSeparator[] = " \t"; + char error[256]; + char dummy[256]; + char *token; + + //iterate over the lines in the string + token = strtok(tmpstring, lineSeparator); + + // we assume the first line is the "!!VCP1.0 line". + if (token != NULL) + { + token = strtok(NULL, lineSeparator); + } + + int iLineCount = 1; // skip first line + + while (token != NULL) + { + iLineCount++; + + // if the first non-whitespace character is a #, this is a comment. Skip. + if (!sscanf(token, " #%s", dummy)) + { // not a comment. Is it a constant? + + // strip whitespace from the beginning of the string + int i; + for (i = 0; i < (int)strlen(token) && isspace(token[i]); i++); + token += i; + + if (strlen(token) > 0 && // this is not a blank line and + !strnicmp(token, "c[", 2)) // the first word is of the form "c[xx]", so its a constant. + { + int iConstID; + int iNumValuesAssigned; + char c[6]; + + iNumValuesAssigned = sscanf(token, " %c [ %d ] = %s ", &c[0], &iConstID, dummy); + + if (3 != iNumValuesAssigned || toupper(c[0]) != 'C') + { // error in constant directive. + sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token); + errors.set(error); + } + else if (!strnicmp(dummy, "track", 5)) + { // this is a TrackMatrix directive + char matrixName[256], matrixTransformName[256]; + + // the series of %c's are to make sure "track(" doesn't get glommed onto the matrixName + iNumValuesAssigned = sscanf(token, + " %c [ %d ] = %c%c%c%c%c ( %s %s ) ;", + &c[0], &iConstID, &c[1], &c[2], &c[3], &c[4], &c[5], + matrixName, matrixTransformName); + + if (iNumValuesAssigned < 8) + { + sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token); + errors.set(error); + } + else + { + char *buffer; + if (9 == iNumValuesAssigned) + { + // just need to remove any junk from the matrix names and IDs. + buffer = strstr(matrixName, ","); + if (buffer) + *buffer = 0; + + buffer = strstr(matrixTransformName, ")"); + if (buffer) + *buffer = 0; + } + else // 8 == iNumValuesAssigned + { + // have to split the two names, since they both were put into the matrixName + buffer = strstr(matrixName, ","); + if (buffer) + { + strcpy(matrixTransformName, buffer + 1); + *buffer = 0; + // get rid of paren at end of transform name, if it is there + buffer = strstr(matrixTransformName, ")"); + if (buffer) + *buffer = 0; + + } + else + { + sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token); + errors.set(error); + } + } + + // constant ID must be modulo 4. + if (0 != (iConstID % 4)) + { + sprintf(error, + "error at line %d \n\"%s\"\n\tglTrackMatrixNV address must be modulo 4\n", + iLineCount, token); + errors.set(error); + } + else if (iConstID < 0 || iConstID > 95) + { + sprintf(error, + "error at line %d \n\"%s\"\n\tConstant address out of range\n", + iLineCount, token); + errors.set(error); + } + else + { + // get the enum values for the specified matrices + GLuint iMatrixID = LookupTrackMatrix(matrixName); + GLuint iTransformID = LookupTrackMatrixTransform(matrixTransformName); + + if (0 == iMatrixID) + { + sprintf(error, + "error at line %d \n\"%s\"\n\tInvalid Matrix parameter in glTrackMatrixNV.\n", + iLineCount, token); + errors.set(error); + } + else if (0 == iTransformID) + { + sprintf(error, + "error at line %d \n\"%s\"\n\tInvalid Transform parameter in glTrackMatrixNV\n", + iLineCount, token); + errors.set(error); + } + else + { + // untrack any currently tracked matrix + glTrackMatrixNV(target, iConstID, GL_NONE, GL_IDENTITY_NV); + + // tell GL the matrix to track + glTrackMatrixNV(target, iConstID, iMatrixID, iTransformID); + } + } + } + } + else // this is a constant directive + { + float xyzw[4] = {0, 0, 0, 0}; + iNumValuesAssigned = sscanf(token, + " %c [ %d ] = ( %f , %f , %f , %f ) ; ", + &c[0], &iConstID, xyzw, xyzw + 1, xyzw + 2, xyzw + 3); + + if (6 != iNumValuesAssigned) + { // error in constant directive. + sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token); + errors.set(error); + } + else if (iConstID < 0 || iConstID > 95) + { + sprintf(error, + "error at line %d \n\"%s\"\n\tConstant address out of range\n", + iLineCount, token); + errors.set(error); + } + else + { + // Always set the closest matrix location to tracking NONE to avoid errors! + glTrackMatrixNV(target, iConstID - (iConstID % 4), GL_NONE, GL_IDENTITY_NV); + + // tell GL the constant values + glProgramParameter4fvNV(target, iConstID, xyzw); + } + } } } diff --git a/RenderSystems/GL/src/nvparse/vp1.0_impl.cpp b/RenderSystems/GL/src/nvparse/vp1.0_impl.cpp index ff5a794b47d..cea8a3fcea9 100644 --- a/RenderSystems/GL/src/nvparse/vp1.0_impl.cpp +++ b/RenderSystems/GL/src/nvparse/vp1.0_impl.cpp @@ -5,9 +5,9 @@ #include #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE -# include +# include #else -# include +# include #endif using namespace std; @@ -15,39 +15,39 @@ using namespace std; namespace { - void LoadProgram( GLenum target, GLuint id, char *instring ); - GLint vpid; + void LoadProgram( GLenum target, GLuint id, char *instring ); + GLint vpid; } bool is_vp10(const char * s) { - return ! strncmp(s, "!!VP1.0", 7); + return ! strncmp(s, "!!VP1.0", 7); } bool vp10_init(char * s) { - static bool vpinit = false; - if (vpinit == false ) - { + static bool vpinit = false; + if (vpinit == false ) + { /* - if(! glh_init_extensions("GL_NV_vertex_program")) - { - errors.set("unable to initialize GL_NV_vertex_program"); - return false; - } - else - { + if(! glh_init_extensions("GL_NV_vertex_program")) + { + errors.set("unable to initialize GL_NV_vertex_program"); + return false; + } + else + { */ - vpinit = true; + vpinit = true; /* - } + } */ - } - - errors.reset(); - line_number = 1; - myin = s; + } + + errors.reset(); + line_number = 1; + myin = s; glGetIntegerv( GL_VERTEX_PROGRAM_BINDING_NV, &vpid ); @@ -56,109 +56,109 @@ bool vp10_init(char * s) char str[128]; sprintf( str, "No vertex program id bound for nvparse() invocation. Bound id = %d\n", (int)vpid ); errors.set( str ); - return false; + return false; } - - return true; + + return true; } int vp10_parse() { LoadProgram( GL_VERTEX_PROGRAM_NV, vpid, myin ); - return 0; + return 0; } namespace { - //.----------------------------------------------------------------------------. - //| Function : LoadProgram | - //| Description: Load a program into GL, and report any errors encountered. | - //.----------------------------------------------------------------------------. - void LoadProgram( GLenum target, GLuint id, char *instring ) - { - GLint errPos; - GLenum errCode; - - int len = strlen(instring); - glLoadProgramNV( target, id, len, (const GLubyte *) instring ); - if ( (errCode = glGetError()) != GL_NO_ERROR ) - { - glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos ); + //.----------------------------------------------------------------------------. + //| Function : LoadProgram | + //| Description: Load a program into GL, and report any errors encountered. | + //.----------------------------------------------------------------------------. + void LoadProgram( GLenum target, GLuint id, char *instring ) + { + GLint errPos; + GLenum errCode; + + int len = strlen(instring); + glLoadProgramNV( target, id, len, (const GLubyte *) instring ); + if ( (errCode = glGetError()) != GL_NO_ERROR ) + { + glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos ); if (errPos == -1) return; - - int nlines = 1; - int nchar = 1; - int i; - for ( i = 0; i < errPos; i++ ) - { - if ( instring[i] == '\n' ) - { - nlines++; - nchar = 1; - } - else - { - nchar++; - } - } - int start = 0; - int end = 0; - int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0; - for ( i = errPos; i >= 0; i-- ) - { - start = i; - if ( flag && (start >= errPos-1) ) - continue; - if ( instring[i] == ';' ) - { - if ( !flag ) - { - start = i+1; - if ( instring[start] == '\n' ) - start++; - } - break; - } - } - for ( i = errPos; i < len; i++ ) - { - end = i; - if ( instring[i] == ';' && end > start) - { - break; - } - } - if ( errPos - start > 30 ) - { - start = errPos - 30; - } - if ( end - errPos > 30 ) - { - end = errPos + 30; - } - - char substring[96]; - memset( substring, 0, 96 ); - strncpy( substring, &(instring[start]), end-start+1 ); - char str[256]; - //sprintf( str, "error at line %d character %d\n \"%s\"\n", nlines, nchar, substring ); - sprintf( str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring ); - int width = errPos-start; - for ( i = 0; i < width; i++ ) - { - strcat( str, " " ); - } - strcat( str, "|\n" ); - for ( i = 0; i < width; i++ ) - { - strcat( str, " " ); - } - strcat( str, "^\n" ); - - errors.set( str ); - } - } + + int nlines = 1; + int nchar = 1; + int i; + for ( i = 0; i < errPos; i++ ) + { + if ( instring[i] == '\n' ) + { + nlines++; + nchar = 1; + } + else + { + nchar++; + } + } + int start = 0; + int end = 0; + int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0; + for ( i = errPos; i >= 0; i-- ) + { + start = i; + if ( flag && (start >= errPos-1) ) + continue; + if ( instring[i] == ';' ) + { + if ( !flag ) + { + start = i+1; + if ( instring[start] == '\n' ) + start++; + } + break; + } + } + for ( i = errPos; i < len; i++ ) + { + end = i; + if ( instring[i] == ';' && end > start) + { + break; + } + } + if ( errPos - start > 30 ) + { + start = errPos - 30; + } + if ( end - errPos > 30 ) + { + end = errPos + 30; + } + + char substring[96]; + memset( substring, 0, 96 ); + strncpy( substring, &(instring[start]), end-start+1 ); + char str[256]; + //sprintf( str, "error at line %d character %d\n \"%s\"\n", nlines, nchar, substring ); + sprintf( str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring ); + int width = errPos-start; + for ( i = 0; i < width; i++ ) + { + strcat( str, " " ); + } + strcat( str, "|\n" ); + for ( i = 0; i < width; i++ ) + { + strcat( str, " " ); + } + strcat( str, "^\n" ); + + errors.set( str ); + } + } } /* else if(!strncmp(instring, "!!VP1.0", 7)) { diff --git a/RenderSystems/GL/src/nvparse/vs1.0_inst.cpp b/RenderSystems/GL/src/nvparse/vs1.0_inst.cpp index 97244258150..e33bb8e82eb 100644 --- a/RenderSystems/GL/src/nvparse/vs1.0_inst.cpp +++ b/RenderSystems/GL/src/nvparse/vs1.0_inst.cpp @@ -16,7 +16,7 @@ VS10Reg::VS10Reg() { type = 0; index = 0; - sign = 0; + sign = 0; mask = 0; } @@ -24,7 +24,7 @@ VS10Reg::VS10Reg(const VS10Reg &r) { type = r.type; index = r.index; - sign = r.sign; + sign = r.sign; mask = r.mask; } @@ -34,7 +34,7 @@ VS10Reg& VS10Reg::operator=(const VS10Reg &r) { type = r.type; index = r.index; - sign = r.sign; + sign = r.sign; mask = r.mask; } return *this; @@ -97,7 +97,7 @@ int VS10Reg::ValidateIndex() errors.set( "VS10Reg::ValidateIndex() Internal Error: unknown register type\n" ); return 1; } - return 1; + return 1; } void VS10Reg::Translate() @@ -253,8 +253,8 @@ VS10Inst::VS10Inst(int currline, int inst, char *cmt) VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0) { line = currline; - instid = inst; - dst = dreg; + instid = inst; + dst = dreg; src[0] = src0; src[1].Init(); src[2].Init(); @@ -264,8 +264,8 @@ VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0) VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1) { line = currline; - instid = inst; - dst = dreg; + instid = inst; + dst = dreg; src[0] = src0; src[1] = src1; src[2].Init(); @@ -275,8 +275,8 @@ VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg s VS10Inst::VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1, VS10Reg src2) { line = currline; - instid = inst; - dst = dreg; + instid = inst; + dst = dreg; src[0] = src0; src[1] = src1; src[2] = src2; diff --git a/RenderSystems/GL/src/nvparse/vs1.0_inst.h b/RenderSystems/GL/src/nvparse/vs1.0_inst.h index b3be02a5931..bd20af64709 100644 --- a/RenderSystems/GL/src/nvparse/vs1.0_inst.h +++ b/RenderSystems/GL/src/nvparse/vs1.0_inst.h @@ -46,12 +46,12 @@ class VS10Reg { public: // VS10Reg(); // VS10Reg(const VS10Reg &r); -// VS10Reg& operator=(const VS10Reg &r); - void Init(); +// VS10Reg& operator=(const VS10Reg &r); + void Init(); void Translate(); int type; int index; - int sign; + int sign; char mask[4]; int ValidateIndex(); @@ -59,19 +59,19 @@ class VS10Reg { typedef class VS10Inst { public: - ~VS10Inst(); - VS10Inst(); - VS10Inst(int currline); - VS10Inst(const VS10Inst &inst); + ~VS10Inst(); + VS10Inst(); + VS10Inst(int currline); + VS10Inst(const VS10Inst &inst); VS10Inst& operator=(const VS10Inst &inst); - VS10Inst(int currline, int inst); - VS10Inst(int currline, int inst, char *cmt); - VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0); - VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1); - VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1, VS10Reg src2); + VS10Inst(int currline, int inst); + VS10Inst(int currline, int inst, char *cmt); + VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0); + VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1); + VS10Inst(int currline, int inst, VS10Reg dreg, VS10Reg src0, VS10Reg src1, VS10Reg src2); void Validate( int &vsflag ); - int Translate(); - VS10Reg dst; + int Translate(); + VS10Reg dst; VS10Reg src[3]; private: int line; diff --git a/RenderSystems/GL/src/nvparse/vs1.0_inst_list.cpp b/RenderSystems/GL/src/nvparse/vs1.0_inst_list.cpp index 21e92113fc9..2ed104a8fb4 100644 --- a/RenderSystems/GL/src/nvparse/vs1.0_inst_list.cpp +++ b/RenderSystems/GL/src/nvparse/vs1.0_inst_list.cpp @@ -8,9 +8,9 @@ #include #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE -# include +# include #else -# include +# include #endif using namespace std; @@ -22,8 +22,8 @@ extern string vs10_transstring; VS10InstList::VS10InstList() { - size = 0; - max = INSTRUCTION_LIST_INC; + size = 0; + max = INSTRUCTION_LIST_INC; list = new VS10Inst[max]; } @@ -34,23 +34,23 @@ VS10InstList::~VS10InstList() int VS10InstList::Size() { - return size; + return size; } VS10InstList& VS10InstList::operator+=(VS10InstPtr t) { - if (size == max) { - // Extend list size by increment amount. + if (size == max) { + // Extend list size by increment amount. VS10InstPtr newlist; - max += INSTRUCTION_LIST_INC; + max += INSTRUCTION_LIST_INC; newlist = new VS10Inst[max]; for ( int i = 0; i < size; i++ ) newlist[i] = list[i]; delete [] list; list = newlist; - } - list[size++] = *t; - return *this; + } + list[size++] = *t; + return *this; } void VS10InstList::Translate() @@ -58,10 +58,10 @@ void VS10InstList::Translate() int ntranslated = 0; vs10_transstring.append( "!!VP1.0\n" ); - for (int i = 0; i < size; i++) + for (int i = 0; i < size; i++) { - ntranslated += list[i].Translate(); - } + ntranslated += list[i].Translate(); + } vs10_transstring.append( "END\n" ); if ( ntranslated > 128 ) @@ -86,8 +86,8 @@ void VS10InstList::Validate() namespace { - void LoadProgram( GLenum target, GLuint id, char *instring ); - GLint vpid; + void LoadProgram( GLenum target, GLuint id, char *instring ); + GLint vpid; } @@ -119,136 +119,136 @@ bool is_vs10(const char *s) bool vs10_init_more() { - static bool vpinit = false; - if (vpinit == false ) - { + static bool vpinit = false; + if (vpinit == false ) + { /* - if(! glh_init_extensions("GL_NV_vertex_program")) - { - errors.set("unable to initialize GL_NV_vertex_program"); - return false; - } - else - { + if(! glh_init_extensions("GL_NV_vertex_program")) + { + errors.set("unable to initialize GL_NV_vertex_program"); + return false; + } + else + { */ - vpinit = true; + vpinit = true; /* - } + } */ - } - - glGetIntegerv( GL_VERTEX_PROGRAM_BINDING_NV, &vpid ); - - if ( vpid == 0 ) - { - char str[128]; - sprintf( str, "No vertex program id bound for nvparse() invocation. Bound id = %d\n", (int)vpid ); - errors.set( str ); - return false; - } + } + + glGetIntegerv( GL_VERTEX_PROGRAM_BINDING_NV, &vpid ); + + if ( vpid == 0 ) + { + char str[128]; + sprintf( str, "No vertex program id bound for nvparse() invocation. Bound id = %d\n", (int)vpid ); + errors.set( str ); + return false; + } errors.reset(); line_number = 1; vs10_transstring = ""; - return true; + return true; } void vs10_load_program() { // Only load the program if no errors occurred. if ( errors.get_num_errors() == 0 ) - LoadProgram( GL_VERTEX_PROGRAM_NV, vpid, (char *) vs10_transstring.c_str() ); + LoadProgram( GL_VERTEX_PROGRAM_NV, vpid, (char *) vs10_transstring.c_str() ); } namespace { - //.----------------------------------------------------------------------------. - //| Function : LoadProgram | - //| Description: Load a program into GL, and report any errors encountered. | - //.----------------------------------------------------------------------------. - void LoadProgram( GLenum target, GLuint id, char *instring ) - { - GLint errPos; - GLenum errCode; - - int len = strlen(instring); - glLoadProgramNV( target, id, len, (const GLubyte *) instring ); - if ( (errCode = glGetError()) != GL_NO_ERROR ) - { - glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos ); - - int nlines = 1; - int nchar = 1; - int i; - for ( i = 0; i < errPos; i++ ) - { - if ( instring[i] == '\n' ) - { - nlines++; - nchar = 1; - } - else - { - nchar++; - } - } - int start = 0; - int end = 0; - int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0; - for ( i = errPos; i >= 0; i-- ) - { - start = i; - if ( flag && (start >= errPos-1) ) - continue; - if ( instring[i] == ';' ) - { - if ( !flag ) - { - start = i+1; - if ( instring[start] == '\n' ) - start++; - } - break; - } - } - for ( i = errPos; i < len; i++ ) - { - end = i; - if ( instring[i] == ';' && end > start) - { - break; - } - } - if ( errPos - start > 30 ) - { - start = errPos - 30; - } - if ( end - errPos > 30 ) - { - end = errPos + 30; - } - - char substring[96]; - memset( substring, 0, 96 ); - strncpy( substring, &(instring[start]), end-start+1 ); - char str[256]; - //sprintf( str, "error at line %d character %d\n \"%s\"\n", nlines, nchar, substring ); - sprintf( str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring ); - int width = errPos-start; - for ( i = 0; i < width; i++ ) - { - strcat( str, " " ); - } - strcat( str, "|\n" ); - for ( i = 0; i < width; i++ ) - { - strcat( str, " " ); - } - strcat( str, "^\n" ); - - errors.set( str ); - } - } + //.----------------------------------------------------------------------------. + //| Function : LoadProgram | + //| Description: Load a program into GL, and report any errors encountered. | + //.----------------------------------------------------------------------------. + void LoadProgram( GLenum target, GLuint id, char *instring ) + { + GLint errPos; + GLenum errCode; + + int len = strlen(instring); + glLoadProgramNV( target, id, len, (const GLubyte *) instring ); + if ( (errCode = glGetError()) != GL_NO_ERROR ) + { + glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos ); + + int nlines = 1; + int nchar = 1; + int i; + for ( i = 0; i < errPos; i++ ) + { + if ( instring[i] == '\n' ) + { + nlines++; + nchar = 1; + } + else + { + nchar++; + } + } + int start = 0; + int end = 0; + int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0; + for ( i = errPos; i >= 0; i-- ) + { + start = i; + if ( flag && (start >= errPos-1) ) + continue; + if ( instring[i] == ';' ) + { + if ( !flag ) + { + start = i+1; + if ( instring[start] == '\n' ) + start++; + } + break; + } + } + for ( i = errPos; i < len; i++ ) + { + end = i; + if ( instring[i] == ';' && end > start) + { + break; + } + } + if ( errPos - start > 30 ) + { + start = errPos - 30; + } + if ( end - errPos > 30 ) + { + end = errPos + 30; + } + + char substring[96]; + memset( substring, 0, 96 ); + strncpy( substring, &(instring[start]), end-start+1 ); + char str[256]; + //sprintf( str, "error at line %d character %d\n \"%s\"\n", nlines, nchar, substring ); + sprintf( str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring ); + int width = errPos-start; + for ( i = 0; i < width; i++ ) + { + strcat( str, " " ); + } + strcat( str, "|\n" ); + for ( i = 0; i < width; i++ ) + { + strcat( str, " " ); + } + strcat( str, "^\n" ); + + errors.set( str ); + } + } } /* diff --git a/RenderSystems/GL/src/nvparse/vs1.0_inst_list.h b/RenderSystems/GL/src/nvparse/vs1.0_inst_list.h index 03a0f44f722..f7fc5ba4552 100644 --- a/RenderSystems/GL/src/nvparse/vs1.0_inst_list.h +++ b/RenderSystems/GL/src/nvparse/vs1.0_inst_list.h @@ -1,21 +1,21 @@ #ifndef _VS10_H #define _VS10_H -#define WRITEMASK_X 0x01 -#define WRITEMASK_Y 0x02 -#define WRITEMASK_Z 0x04 -#define WRITEMASK_W 0x08 +#define WRITEMASK_X 0x01 +#define WRITEMASK_Y 0x02 +#define WRITEMASK_Z 0x04 +#define WRITEMASK_W 0x08 #include "vs1.0_inst.h" typedef class VS10InstList { public: - VS10InstList(); - ~VS10InstList(); - int Size(); - VS10InstList& operator+=(VS10InstPtr t); - void Validate(); - void Translate(); + VS10InstList(); + ~VS10InstList(); + int Size(); + VS10InstList& operator+=(VS10InstPtr t); + void Validate(); + void Translate(); private: VS10InstPtr list; int size; diff --git a/RenderSystems/GL/src/nvparse/vsp1.0_impl.cpp b/RenderSystems/GL/src/nvparse/vsp1.0_impl.cpp index 3412c0c2277..ff03304fc21 100644 --- a/RenderSystems/GL/src/nvparse/vsp1.0_impl.cpp +++ b/RenderSystems/GL/src/nvparse/vsp1.0_impl.cpp @@ -5,9 +5,9 @@ #include #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE -# include +# include #else -# include +# include #endif @@ -16,137 +16,137 @@ using namespace std; namespace { - void LoadProgram( GLenum target, GLuint id, char *instring ); + void LoadProgram( GLenum target, GLuint id, char *instring ); } bool is_vsp10(const char * s) { - return ! strncmp(s, "!!VSP1.0", 8); + return ! strncmp(s, "!!VSP1.0", 8); } bool vsp10_init(char * s) { - static bool vpinit = false; - if (vpinit == false ) - { + static bool vpinit = false; + if (vpinit == false ) + { /* - if(! glh_init_extensions("GL_NV_vertex_program")) - { - errors.set("unable to initialize GL_NV_vertex_program"); - return false; - } - else - { + if(! glh_init_extensions("GL_NV_vertex_program")) + { + errors.set("unable to initialize GL_NV_vertex_program"); + return false; + } + else + { */ - vpinit = true; + vpinit = true; /* - } + } */ - } - - errors.reset(); - line_number = 1; - myin = s; - - return true; + } + + errors.reset(); + line_number = 1; + myin = s; + + return true; } int vsp10_parse(int vpsid) { LoadProgram( GL_VERTEX_STATE_PROGRAM_NV, vpsid, myin ); - return 0; + return 0; } namespace { - //.----------------------------------------------------------------------------. - //| Function : LoadProgram | - //| Description: Load a program into GL, and report any errors encountered. | - //.----------------------------------------------------------------------------. - void LoadProgram( GLenum target, GLuint id, char *instring ) - { - GLint errPos; - GLenum errCode; + //.----------------------------------------------------------------------------. + //| Function : LoadProgram | + //| Description: Load a program into GL, and report any errors encountered. | + //.----------------------------------------------------------------------------. + void LoadProgram( GLenum target, GLuint id, char *instring ) + { + GLint errPos; + GLenum errCode; - int len = strlen(instring); - glLoadProgramNV( target, id, len, (const GLubyte *) instring ); - if ( (errCode = glGetError()) != GL_NO_ERROR ) - { - glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos ); - - int nlines = 1; - int nchar = 1; - int i; - for ( i = 0; i < errPos; i++ ) - { - if ( instring[i] == '\n' ) - { - nlines++; - nchar = 1; - } - else - { - nchar++; - } - } - int start = 0; - int end = 0; - int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0; - for ( i = errPos; i >= 0; i-- ) - { - start = i; - if ( flag && (start >= errPos-1) ) - continue; - if ( instring[i] == ';' ) - { - if ( !flag ) - { - start = i+1; - if ( instring[start] == '\n' ) - start++; - } - break; - } - } - for ( i = errPos; i < len; i++ ) - { - end = i; - if ( instring[i] == ';' && end > start) - { - break; - } - } - if ( errPos - start > 30 ) - { - start = errPos - 30; - } - if ( end - errPos > 30 ) - { - end = errPos + 30; - } - - char substring[96]; - memset( substring, 0, 96 ); - strncpy( substring, &(instring[start]), end-start+1 ); - char str[256]; - //sprintf( str, "error at line %d character %d\n \"%s\"\n", nlines, nchar, substring ); - sprintf( str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring ); - int width = errPos-start; - for ( i = 0; i < width; i++ ) - { - strcat( str, " " ); - } - strcat( str, "|\n" ); - for ( i = 0; i < width; i++ ) - { - strcat( str, " " ); - } - strcat( str, "^\n" ); - - errors.set( str ); - } - } + int len = strlen(instring); + glLoadProgramNV( target, id, len, (const GLubyte *) instring ); + if ( (errCode = glGetError()) != GL_NO_ERROR ) + { + glGetIntegerv( GL_PROGRAM_ERROR_POSITION_NV, &errPos ); + + int nlines = 1; + int nchar = 1; + int i; + for ( i = 0; i < errPos; i++ ) + { + if ( instring[i] == '\n' ) + { + nlines++; + nchar = 1; + } + else + { + nchar++; + } + } + int start = 0; + int end = 0; + int flag = ((instring[errPos]==';') | (instring[errPos-1]==';')) ? 1 : 0; + for ( i = errPos; i >= 0; i-- ) + { + start = i; + if ( flag && (start >= errPos-1) ) + continue; + if ( instring[i] == ';' ) + { + if ( !flag ) + { + start = i+1; + if ( instring[start] == '\n' ) + start++; + } + break; + } + } + for ( i = errPos; i < len; i++ ) + { + end = i; + if ( instring[i] == ';' && end > start) + { + break; + } + } + if ( errPos - start > 30 ) + { + start = errPos - 30; + } + if ( end - errPos > 30 ) + { + end = errPos + 30; + } + + char substring[96]; + memset( substring, 0, 96 ); + strncpy( substring, &(instring[start]), end-start+1 ); + char str[256]; + //sprintf( str, "error at line %d character %d\n \"%s\"\n", nlines, nchar, substring ); + sprintf( str, "error at line %d character %d\n\"%s\"\n", nlines, nchar, substring ); + int width = errPos-start; + for ( i = 0; i < width; i++ ) + { + strcat( str, " " ); + } + strcat( str, "|\n" ); + for ( i = 0; i < width; i++ ) + { + strcat( str, " " ); + } + strcat( str, "^\n" ); + + errors.set( str ); + } + } } /* else if(!strncmp(instring, "!!VSP1.0", 8)) @@ -168,16 +168,16 @@ vpinit = 1; errors.reset(); line_number = 1; - va_list ap; - va_start(ap, input_string); - int vpsid = va_arg(ap,int); - va_end(ap); - - if ( glGetError() != GL_NO_ERROR ) - { - errors.set( "Previous GL_ERROR prior to vertex state program parsing." ); - } - + va_list ap; + va_start(ap, input_string); + int vpsid = va_arg(ap,int); + va_end(ap); + + if ( glGetError() != GL_NO_ERROR ) + { + errors.set( "Previous GL_ERROR prior to vertex state program parsing." ); + } + LoadProgram( GL_VERTEX_STATE_PROGRAM_NV, vpsid, instring ); - } - */ + } + */ diff --git a/RenderSystems/GL3Plus/include/GL/gl3w.h b/RenderSystems/GL3Plus/include/GL/gl3w.h index ee563f8d401..b278d9f61c0 100644 --- a/RenderSystems/GL3Plus/include/GL/gl3w.h +++ b/RenderSystems/GL3Plus/include/GL/gl3w.h @@ -622,610 +622,610 @@ extern PFNGLTEXSTORAGE3DMULTISAMPLEPROC gl3wTexStorage3DMultisample; extern PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC gl3wTextureStorage2DMultisampleEXT; extern PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC gl3wTextureStorage3DMultisampleEXT; -#define glCullFace gl3wCullFace -#define glFrontFace gl3wFrontFace -#define glHint gl3wHint -#define glLineWidth gl3wLineWidth -#define glPointSize gl3wPointSize -#define glPolygonMode gl3wPolygonMode -#define glScissor gl3wScissor -#define glTexParameterf gl3wTexParameterf -#define glTexParameterfv gl3wTexParameterfv -#define glTexParameteri gl3wTexParameteri -#define glTexParameteriv gl3wTexParameteriv -#define glTexImage1D gl3wTexImage1D -#define glTexImage2D gl3wTexImage2D -#define glDrawBuffer gl3wDrawBuffer -#define glClear gl3wClear -#define glClearColor gl3wClearColor -#define glClearStencil gl3wClearStencil -#define glClearDepth gl3wClearDepth -#define glStencilMask gl3wStencilMask -#define glColorMask gl3wColorMask -#define glDepthMask gl3wDepthMask -#define glDisable gl3wDisable -#define glEnable gl3wEnable -#define glFinish gl3wFinish -#define glFlush gl3wFlush -#define glBlendFunc gl3wBlendFunc -#define glLogicOp gl3wLogicOp -#define glStencilFunc gl3wStencilFunc -#define glStencilOp gl3wStencilOp -#define glDepthFunc gl3wDepthFunc -#define glPixelStoref gl3wPixelStoref -#define glPixelStorei gl3wPixelStorei -#define glReadBuffer gl3wReadBuffer -#define glReadPixels gl3wReadPixels -#define glGetBooleanv gl3wGetBooleanv -#define glGetDoublev gl3wGetDoublev -#define glGetError gl3wGetError -#define glGetFloatv gl3wGetFloatv -#define glGetIntegerv gl3wGetIntegerv -#define glGetString gl3wGetString -#define glGetTexImage gl3wGetTexImage -#define glGetTexParameterfv gl3wGetTexParameterfv -#define glGetTexParameteriv gl3wGetTexParameteriv -#define glGetTexLevelParameterfv gl3wGetTexLevelParameterfv -#define glGetTexLevelParameteriv gl3wGetTexLevelParameteriv -#define glIsEnabled gl3wIsEnabled -#define glDepthRange gl3wDepthRange -#define glViewport gl3wViewport -#define glDrawArrays gl3wDrawArrays -#define glDrawElements gl3wDrawElements -#define glGetPointerv gl3wGetPointerv -#define glPolygonOffset gl3wPolygonOffset -#define glCopyTexImage1D gl3wCopyTexImage1D -#define glCopyTexImage2D gl3wCopyTexImage2D -#define glCopyTexSubImage1D gl3wCopyTexSubImage1D -#define glCopyTexSubImage2D gl3wCopyTexSubImage2D -#define glTexSubImage1D gl3wTexSubImage1D -#define glTexSubImage2D gl3wTexSubImage2D -#define glBindTexture gl3wBindTexture -#define glDeleteTextures gl3wDeleteTextures -#define glGenTextures gl3wGenTextures -#define glIsTexture gl3wIsTexture -#define glBlendColor gl3wBlendColor -#define glBlendEquation gl3wBlendEquation -#define glDrawRangeElements gl3wDrawRangeElements -#define glTexImage3D gl3wTexImage3D -#define glTexSubImage3D gl3wTexSubImage3D -#define glCopyTexSubImage3D gl3wCopyTexSubImage3D -#define glActiveTexture gl3wActiveTexture -#define glSampleCoverage gl3wSampleCoverage -#define glCompressedTexImage3D gl3wCompressedTexImage3D -#define glCompressedTexImage2D gl3wCompressedTexImage2D -#define glCompressedTexImage1D gl3wCompressedTexImage1D -#define glCompressedTexSubImage3D gl3wCompressedTexSubImage3D -#define glCompressedTexSubImage2D gl3wCompressedTexSubImage2D -#define glCompressedTexSubImage1D gl3wCompressedTexSubImage1D -#define glGetCompressedTexImage gl3wGetCompressedTexImage -#define glBlendFuncSeparate gl3wBlendFuncSeparate -#define glMultiDrawArrays gl3wMultiDrawArrays -#define glMultiDrawElements gl3wMultiDrawElements -#define glPointParameterf gl3wPointParameterf -#define glPointParameterfv gl3wPointParameterfv -#define glPointParameteri gl3wPointParameteri -#define glPointParameteriv gl3wPointParameteriv -#define glGenQueries gl3wGenQueries -#define glDeleteQueries gl3wDeleteQueries -#define glIsQuery gl3wIsQuery -#define glBeginQuery gl3wBeginQuery -#define glEndQuery gl3wEndQuery -#define glGetQueryiv gl3wGetQueryiv -#define glGetQueryObjectiv gl3wGetQueryObjectiv -#define glGetQueryObjectuiv gl3wGetQueryObjectuiv -#define glBindBuffer gl3wBindBuffer -#define glDeleteBuffers gl3wDeleteBuffers -#define glGenBuffers gl3wGenBuffers -#define glIsBuffer gl3wIsBuffer -#define glBufferData gl3wBufferData -#define glBufferSubData gl3wBufferSubData -#define glGetBufferSubData gl3wGetBufferSubData -#define glMapBuffer gl3wMapBuffer -#define glUnmapBuffer gl3wUnmapBuffer -#define glGetBufferParameteriv gl3wGetBufferParameteriv -#define glGetBufferPointerv gl3wGetBufferPointerv -#define glBlendEquationSeparate gl3wBlendEquationSeparate -#define glDrawBuffers gl3wDrawBuffers -#define glStencilOpSeparate gl3wStencilOpSeparate -#define glStencilFuncSeparate gl3wStencilFuncSeparate -#define glStencilMaskSeparate gl3wStencilMaskSeparate -#define glAttachShader gl3wAttachShader -#define glBindAttribLocation gl3wBindAttribLocation -#define glCompileShader gl3wCompileShader -#define glCreateProgram gl3wCreateProgram -#define glCreateShader gl3wCreateShader -#define glDeleteProgram gl3wDeleteProgram -#define glDeleteShader gl3wDeleteShader -#define glDetachShader gl3wDetachShader -#define glDisableVertexAttribArray gl3wDisableVertexAttribArray -#define glEnableVertexAttribArray gl3wEnableVertexAttribArray -#define glGetActiveAttrib gl3wGetActiveAttrib -#define glGetActiveUniform gl3wGetActiveUniform -#define glGetAttachedShaders gl3wGetAttachedShaders -#define glGetAttribLocation gl3wGetAttribLocation -#define glGetProgramiv gl3wGetProgramiv -#define glGetProgramInfoLog gl3wGetProgramInfoLog -#define glGetShaderiv gl3wGetShaderiv -#define glGetShaderInfoLog gl3wGetShaderInfoLog -#define glGetShaderSource gl3wGetShaderSource -#define glGetUniformLocation gl3wGetUniformLocation -#define glGetUniformfv gl3wGetUniformfv -#define glGetUniformiv gl3wGetUniformiv -#define glGetVertexAttribdv gl3wGetVertexAttribdv -#define glGetVertexAttribfv gl3wGetVertexAttribfv -#define glGetVertexAttribiv gl3wGetVertexAttribiv -#define glGetVertexAttribPointerv gl3wGetVertexAttribPointerv -#define glIsProgram gl3wIsProgram -#define glIsShader gl3wIsShader -#define glLinkProgram gl3wLinkProgram -#define glShaderSource gl3wShaderSource -#define glUseProgram gl3wUseProgram -#define glUniform1f gl3wUniform1f -#define glUniform2f gl3wUniform2f -#define glUniform3f gl3wUniform3f -#define glUniform4f gl3wUniform4f -#define glUniform1i gl3wUniform1i -#define glUniform2i gl3wUniform2i -#define glUniform3i gl3wUniform3i -#define glUniform4i gl3wUniform4i -#define glUniform1fv gl3wUniform1fv -#define glUniform2fv gl3wUniform2fv -#define glUniform3fv gl3wUniform3fv -#define glUniform4fv gl3wUniform4fv -#define glUniform1iv gl3wUniform1iv -#define glUniform2iv gl3wUniform2iv -#define glUniform3iv gl3wUniform3iv -#define glUniform4iv gl3wUniform4iv -#define glUniformMatrix2fv gl3wUniformMatrix2fv -#define glUniformMatrix3fv gl3wUniformMatrix3fv -#define glUniformMatrix4fv gl3wUniformMatrix4fv -#define glValidateProgram gl3wValidateProgram -#define glVertexAttrib1d gl3wVertexAttrib1d -#define glVertexAttrib1dv gl3wVertexAttrib1dv -#define glVertexAttrib1f gl3wVertexAttrib1f -#define glVertexAttrib1fv gl3wVertexAttrib1fv -#define glVertexAttrib1s gl3wVertexAttrib1s -#define glVertexAttrib1sv gl3wVertexAttrib1sv -#define glVertexAttrib2d gl3wVertexAttrib2d -#define glVertexAttrib2dv gl3wVertexAttrib2dv -#define glVertexAttrib2f gl3wVertexAttrib2f -#define glVertexAttrib2fv gl3wVertexAttrib2fv -#define glVertexAttrib2s gl3wVertexAttrib2s -#define glVertexAttrib2sv gl3wVertexAttrib2sv -#define glVertexAttrib3d gl3wVertexAttrib3d -#define glVertexAttrib3dv gl3wVertexAttrib3dv -#define glVertexAttrib3f gl3wVertexAttrib3f -#define glVertexAttrib3fv gl3wVertexAttrib3fv -#define glVertexAttrib3s gl3wVertexAttrib3s -#define glVertexAttrib3sv gl3wVertexAttrib3sv -#define glVertexAttrib4Nbv gl3wVertexAttrib4Nbv -#define glVertexAttrib4Niv gl3wVertexAttrib4Niv -#define glVertexAttrib4Nsv gl3wVertexAttrib4Nsv -#define glVertexAttrib4Nub gl3wVertexAttrib4Nub -#define glVertexAttrib4Nubv gl3wVertexAttrib4Nubv -#define glVertexAttrib4Nuiv gl3wVertexAttrib4Nuiv -#define glVertexAttrib4Nusv gl3wVertexAttrib4Nusv -#define glVertexAttrib4bv gl3wVertexAttrib4bv -#define glVertexAttrib4d gl3wVertexAttrib4d -#define glVertexAttrib4dv gl3wVertexAttrib4dv -#define glVertexAttrib4f gl3wVertexAttrib4f -#define glVertexAttrib4fv gl3wVertexAttrib4fv -#define glVertexAttrib4iv gl3wVertexAttrib4iv -#define glVertexAttrib4s gl3wVertexAttrib4s -#define glVertexAttrib4sv gl3wVertexAttrib4sv -#define glVertexAttrib4ubv gl3wVertexAttrib4ubv -#define glVertexAttrib4uiv gl3wVertexAttrib4uiv -#define glVertexAttrib4usv gl3wVertexAttrib4usv -#define glVertexAttribPointer gl3wVertexAttribPointer -#define glUniformMatrix2x3fv gl3wUniformMatrix2x3fv -#define glUniformMatrix3x2fv gl3wUniformMatrix3x2fv -#define glUniformMatrix2x4fv gl3wUniformMatrix2x4fv -#define glUniformMatrix4x2fv gl3wUniformMatrix4x2fv -#define glUniformMatrix3x4fv gl3wUniformMatrix3x4fv -#define glUniformMatrix4x3fv gl3wUniformMatrix4x3fv -#define glColorMaski gl3wColorMaski -#define glGetBooleani_v gl3wGetBooleani_v -#define glGetIntegeri_v gl3wGetIntegeri_v -#define glEnablei gl3wEnablei -#define glDisablei gl3wDisablei -#define glIsEnabledi gl3wIsEnabledi -#define glBeginTransformFeedback gl3wBeginTransformFeedback -#define glEndTransformFeedback gl3wEndTransformFeedback -#define glBindBufferRange gl3wBindBufferRange -#define glBindBufferBase gl3wBindBufferBase -#define glTransformFeedbackVaryings gl3wTransformFeedbackVaryings -#define glGetTransformFeedbackVarying gl3wGetTransformFeedbackVarying -#define glClampColor gl3wClampColor -#define glBeginConditionalRender gl3wBeginConditionalRender -#define glEndConditionalRender gl3wEndConditionalRender -#define glVertexAttribIPointer gl3wVertexAttribIPointer -#define glGetVertexAttribIiv gl3wGetVertexAttribIiv -#define glGetVertexAttribIuiv gl3wGetVertexAttribIuiv -#define glVertexAttribI1i gl3wVertexAttribI1i -#define glVertexAttribI2i gl3wVertexAttribI2i -#define glVertexAttribI3i gl3wVertexAttribI3i -#define glVertexAttribI4i gl3wVertexAttribI4i -#define glVertexAttribI1ui gl3wVertexAttribI1ui -#define glVertexAttribI2ui gl3wVertexAttribI2ui -#define glVertexAttribI3ui gl3wVertexAttribI3ui -#define glVertexAttribI4ui gl3wVertexAttribI4ui -#define glVertexAttribI1iv gl3wVertexAttribI1iv -#define glVertexAttribI2iv gl3wVertexAttribI2iv -#define glVertexAttribI3iv gl3wVertexAttribI3iv -#define glVertexAttribI4iv gl3wVertexAttribI4iv -#define glVertexAttribI1uiv gl3wVertexAttribI1uiv -#define glVertexAttribI2uiv gl3wVertexAttribI2uiv -#define glVertexAttribI3uiv gl3wVertexAttribI3uiv -#define glVertexAttribI4uiv gl3wVertexAttribI4uiv -#define glVertexAttribI4bv gl3wVertexAttribI4bv -#define glVertexAttribI4sv gl3wVertexAttribI4sv -#define glVertexAttribI4ubv gl3wVertexAttribI4ubv -#define glVertexAttribI4usv gl3wVertexAttribI4usv -#define glGetUniformuiv gl3wGetUniformuiv -#define glBindFragDataLocation gl3wBindFragDataLocation -#define glGetFragDataLocation gl3wGetFragDataLocation -#define glUniform1ui gl3wUniform1ui -#define glUniform2ui gl3wUniform2ui -#define glUniform3ui gl3wUniform3ui -#define glUniform4ui gl3wUniform4ui -#define glUniform1uiv gl3wUniform1uiv -#define glUniform2uiv gl3wUniform2uiv -#define glUniform3uiv gl3wUniform3uiv -#define glUniform4uiv gl3wUniform4uiv -#define glTexParameterIiv gl3wTexParameterIiv -#define glTexParameterIuiv gl3wTexParameterIuiv -#define glGetTexParameterIiv gl3wGetTexParameterIiv -#define glGetTexParameterIuiv gl3wGetTexParameterIuiv -#define glClearBufferiv gl3wClearBufferiv -#define glClearBufferuiv gl3wClearBufferuiv -#define glClearBufferfv gl3wClearBufferfv -#define glClearBufferfi gl3wClearBufferfi -#define glGetStringi gl3wGetStringi -#define glDrawArraysInstanced gl3wDrawArraysInstanced -#define glDrawElementsInstanced gl3wDrawElementsInstanced -#define glTexBuffer gl3wTexBuffer -#define glPrimitiveRestartIndex gl3wPrimitiveRestartIndex -#define glGetInteger64i_v gl3wGetInteger64i_v -#define glGetBufferParameteri64v gl3wGetBufferParameteri64v -#define glFramebufferTexture gl3wFramebufferTexture -#define glVertexAttribDivisor gl3wVertexAttribDivisor -#define glMinSampleShading gl3wMinSampleShading -#define glBlendEquationi gl3wBlendEquationi -#define glBlendEquationSeparatei gl3wBlendEquationSeparatei -#define glBlendFunci gl3wBlendFunci -#define glBlendFuncSeparatei gl3wBlendFuncSeparatei -#define glIsRenderbuffer gl3wIsRenderbuffer -#define glBindRenderbuffer gl3wBindRenderbuffer -#define glDeleteRenderbuffers gl3wDeleteRenderbuffers -#define glGenRenderbuffers gl3wGenRenderbuffers -#define glRenderbufferStorage gl3wRenderbufferStorage -#define glGetRenderbufferParameteriv gl3wGetRenderbufferParameteriv -#define glIsFramebuffer gl3wIsFramebuffer -#define glBindFramebuffer gl3wBindFramebuffer -#define glDeleteFramebuffers gl3wDeleteFramebuffers -#define glGenFramebuffers gl3wGenFramebuffers -#define glCheckFramebufferStatus gl3wCheckFramebufferStatus -#define glFramebufferTexture1D gl3wFramebufferTexture1D -#define glFramebufferTexture2D gl3wFramebufferTexture2D -#define glFramebufferTexture3D gl3wFramebufferTexture3D -#define glFramebufferRenderbuffer gl3wFramebufferRenderbuffer -#define glGetFramebufferAttachmentParameteriv gl3wGetFramebufferAttachmentParameteriv -#define glGenerateMipmap gl3wGenerateMipmap -#define glBlitFramebuffer gl3wBlitFramebuffer -#define glRenderbufferStorageMultisample gl3wRenderbufferStorageMultisample -#define glFramebufferTextureLayer gl3wFramebufferTextureLayer -#define glMapBufferRange gl3wMapBufferRange -#define glFlushMappedBufferRange gl3wFlushMappedBufferRange -#define glBindVertexArray gl3wBindVertexArray -#define glDeleteVertexArrays gl3wDeleteVertexArrays -#define glGenVertexArrays gl3wGenVertexArrays -#define glIsVertexArray gl3wIsVertexArray -#define glGetUniformIndices gl3wGetUniformIndices -#define glGetActiveUniformsiv gl3wGetActiveUniformsiv -#define glGetActiveUniformName gl3wGetActiveUniformName -#define glGetUniformBlockIndex gl3wGetUniformBlockIndex -#define glGetActiveUniformBlockiv gl3wGetActiveUniformBlockiv -#define glGetActiveUniformBlockName gl3wGetActiveUniformBlockName -#define glUniformBlockBinding gl3wUniformBlockBinding -#define glCopyBufferSubData gl3wCopyBufferSubData -#define glDrawElementsBaseVertex gl3wDrawElementsBaseVertex -#define glDrawRangeElementsBaseVertex gl3wDrawRangeElementsBaseVertex -#define glDrawElementsInstancedBaseVertex gl3wDrawElementsInstancedBaseVertex -#define glMultiDrawElementsBaseVertex gl3wMultiDrawElementsBaseVertex -#define glProvokingVertex gl3wProvokingVertex -#define glFenceSync gl3wFenceSync -#define glIsSync gl3wIsSync -#define glDeleteSync gl3wDeleteSync -#define glClientWaitSync gl3wClientWaitSync -#define glWaitSync gl3wWaitSync -#define glGetInteger64v gl3wGetInteger64v -#define glGetSynciv gl3wGetSynciv -#define glTexImage2DMultisample gl3wTexImage2DMultisample -#define glTexImage3DMultisample gl3wTexImage3DMultisample -#define glGetMultisamplefv gl3wGetMultisamplefv -#define glSampleMaski gl3wSampleMaski -#define glBlendEquationiARB gl3wBlendEquationiARB -#define glBlendEquationSeparateiARB gl3wBlendEquationSeparateiARB -#define glBlendFunciARB gl3wBlendFunciARB -#define glBlendFuncSeparateiARB gl3wBlendFuncSeparateiARB -#define glMinSampleShadingARB gl3wMinSampleShadingARB -#define glNamedStringARB gl3wNamedStringARB -#define glDeleteNamedStringARB gl3wDeleteNamedStringARB -#define glCompileShaderIncludeARB gl3wCompileShaderIncludeARB -#define glIsNamedStringARB gl3wIsNamedStringARB -#define glGetNamedStringARB gl3wGetNamedStringARB -#define glGetNamedStringivARB gl3wGetNamedStringivARB -#define glBindFragDataLocationIndexed gl3wBindFragDataLocationIndexed -#define glGetFragDataIndex gl3wGetFragDataIndex -#define glGenSamplers gl3wGenSamplers -#define glDeleteSamplers gl3wDeleteSamplers -#define glIsSampler gl3wIsSampler -#define glBindSampler gl3wBindSampler -#define glSamplerParameteri gl3wSamplerParameteri -#define glSamplerParameteriv gl3wSamplerParameteriv -#define glSamplerParameterf gl3wSamplerParameterf -#define glSamplerParameterfv gl3wSamplerParameterfv -#define glSamplerParameterIiv gl3wSamplerParameterIiv -#define glSamplerParameterIuiv gl3wSamplerParameterIuiv -#define glGetSamplerParameteriv gl3wGetSamplerParameteriv -#define glGetSamplerParameterIiv gl3wGetSamplerParameterIiv -#define glGetSamplerParameterfv gl3wGetSamplerParameterfv -#define glGetSamplerParameterIuiv gl3wGetSamplerParameterIuiv -#define glQueryCounter gl3wQueryCounter -#define glGetQueryObjecti64v gl3wGetQueryObjecti64v -#define glGetQueryObjectui64v gl3wGetQueryObjectui64v -#define glVertexP2ui gl3wVertexP2ui -#define glVertexP2uiv gl3wVertexP2uiv -#define glVertexP3ui gl3wVertexP3ui -#define glVertexP3uiv gl3wVertexP3uiv -#define glVertexP4ui gl3wVertexP4ui -#define glVertexP4uiv gl3wVertexP4uiv -#define glTexCoordP1ui gl3wTexCoordP1ui -#define glTexCoordP1uiv gl3wTexCoordP1uiv -#define glTexCoordP2ui gl3wTexCoordP2ui -#define glTexCoordP2uiv gl3wTexCoordP2uiv -#define glTexCoordP3ui gl3wTexCoordP3ui -#define glTexCoordP3uiv gl3wTexCoordP3uiv -#define glTexCoordP4ui gl3wTexCoordP4ui -#define glTexCoordP4uiv gl3wTexCoordP4uiv -#define glMultiTexCoordP1ui gl3wMultiTexCoordP1ui -#define glMultiTexCoordP1uiv gl3wMultiTexCoordP1uiv -#define glMultiTexCoordP2ui gl3wMultiTexCoordP2ui -#define glMultiTexCoordP2uiv gl3wMultiTexCoordP2uiv -#define glMultiTexCoordP3ui gl3wMultiTexCoordP3ui -#define glMultiTexCoordP3uiv gl3wMultiTexCoordP3uiv -#define glMultiTexCoordP4ui gl3wMultiTexCoordP4ui -#define glMultiTexCoordP4uiv gl3wMultiTexCoordP4uiv -#define glNormalP3ui gl3wNormalP3ui -#define glNormalP3uiv gl3wNormalP3uiv -#define glColorP3ui gl3wColorP3ui -#define glColorP3uiv gl3wColorP3uiv -#define glColorP4ui gl3wColorP4ui -#define glColorP4uiv gl3wColorP4uiv -#define glSecondaryColorP3ui gl3wSecondaryColorP3ui -#define glSecondaryColorP3uiv gl3wSecondaryColorP3uiv -#define glVertexAttribP1ui gl3wVertexAttribP1ui -#define glVertexAttribP1uiv gl3wVertexAttribP1uiv -#define glVertexAttribP2ui gl3wVertexAttribP2ui -#define glVertexAttribP2uiv gl3wVertexAttribP2uiv -#define glVertexAttribP3ui gl3wVertexAttribP3ui -#define glVertexAttribP3uiv gl3wVertexAttribP3uiv -#define glVertexAttribP4ui gl3wVertexAttribP4ui -#define glVertexAttribP4uiv gl3wVertexAttribP4uiv -#define glDrawArraysIndirect gl3wDrawArraysIndirect -#define glDrawElementsIndirect gl3wDrawElementsIndirect -#define glUniform1d gl3wUniform1d -#define glUniform2d gl3wUniform2d -#define glUniform3d gl3wUniform3d -#define glUniform4d gl3wUniform4d -#define glUniform1dv gl3wUniform1dv -#define glUniform2dv gl3wUniform2dv -#define glUniform3dv gl3wUniform3dv -#define glUniform4dv gl3wUniform4dv -#define glUniformMatrix2dv gl3wUniformMatrix2dv -#define glUniformMatrix3dv gl3wUniformMatrix3dv -#define glUniformMatrix4dv gl3wUniformMatrix4dv -#define glUniformMatrix2x3dv gl3wUniformMatrix2x3dv -#define glUniformMatrix2x4dv gl3wUniformMatrix2x4dv -#define glUniformMatrix3x2dv gl3wUniformMatrix3x2dv -#define glUniformMatrix3x4dv gl3wUniformMatrix3x4dv -#define glUniformMatrix4x2dv gl3wUniformMatrix4x2dv -#define glUniformMatrix4x3dv gl3wUniformMatrix4x3dv -#define glGetUniformdv gl3wGetUniformdv -#define glGetSubroutineUniformLocation gl3wGetSubroutineUniformLocation -#define glGetSubroutineIndex gl3wGetSubroutineIndex -#define glGetActiveSubroutineUniformiv gl3wGetActiveSubroutineUniformiv -#define glGetActiveSubroutineUniformName gl3wGetActiveSubroutineUniformName -#define glGetActiveSubroutineName gl3wGetActiveSubroutineName -#define glUniformSubroutinesuiv gl3wUniformSubroutinesuiv -#define glGetUniformSubroutineuiv gl3wGetUniformSubroutineuiv -#define glGetProgramStageiv gl3wGetProgramStageiv -#define glPatchParameteri gl3wPatchParameteri -#define glPatchParameterfv gl3wPatchParameterfv -#define glBindTransformFeedback gl3wBindTransformFeedback -#define glDeleteTransformFeedbacks gl3wDeleteTransformFeedbacks -#define glGenTransformFeedbacks gl3wGenTransformFeedbacks -#define glIsTransformFeedback gl3wIsTransformFeedback -#define glPauseTransformFeedback gl3wPauseTransformFeedback -#define glResumeTransformFeedback gl3wResumeTransformFeedback -#define glDrawTransformFeedback gl3wDrawTransformFeedback -#define glDrawTransformFeedbackStream gl3wDrawTransformFeedbackStream -#define glBeginQueryIndexed gl3wBeginQueryIndexed -#define glEndQueryIndexed gl3wEndQueryIndexed -#define glGetQueryIndexediv gl3wGetQueryIndexediv -#define glReleaseShaderCompiler gl3wReleaseShaderCompiler -#define glShaderBinary gl3wShaderBinary -#define glGetShaderPrecisionFormat gl3wGetShaderPrecisionFormat -#define glDepthRangef gl3wDepthRangef -#define glClearDepthf gl3wClearDepthf -#define glGetProgramBinary gl3wGetProgramBinary -#define glProgramBinary gl3wProgramBinary -#define glProgramParameteri gl3wProgramParameteri -#define glUseProgramStages gl3wUseProgramStages -#define glActiveShaderProgram gl3wActiveShaderProgram -#define glCreateShaderProgramv gl3wCreateShaderProgramv -#define glBindProgramPipeline gl3wBindProgramPipeline -#define glDeleteProgramPipelines gl3wDeleteProgramPipelines -#define glGenProgramPipelines gl3wGenProgramPipelines -#define glIsProgramPipeline gl3wIsProgramPipeline -#define glGetProgramPipelineiv gl3wGetProgramPipelineiv -#define glProgramUniform1i gl3wProgramUniform1i -#define glProgramUniform1iv gl3wProgramUniform1iv -#define glProgramUniform1f gl3wProgramUniform1f -#define glProgramUniform1fv gl3wProgramUniform1fv -#define glProgramUniform1d gl3wProgramUniform1d -#define glProgramUniform1dv gl3wProgramUniform1dv -#define glProgramUniform1ui gl3wProgramUniform1ui -#define glProgramUniform1uiv gl3wProgramUniform1uiv -#define glProgramUniform2i gl3wProgramUniform2i -#define glProgramUniform2iv gl3wProgramUniform2iv -#define glProgramUniform2f gl3wProgramUniform2f -#define glProgramUniform2fv gl3wProgramUniform2fv -#define glProgramUniform2d gl3wProgramUniform2d -#define glProgramUniform2dv gl3wProgramUniform2dv -#define glProgramUniform2ui gl3wProgramUniform2ui -#define glProgramUniform2uiv gl3wProgramUniform2uiv -#define glProgramUniform3i gl3wProgramUniform3i -#define glProgramUniform3iv gl3wProgramUniform3iv -#define glProgramUniform3f gl3wProgramUniform3f -#define glProgramUniform3fv gl3wProgramUniform3fv -#define glProgramUniform3d gl3wProgramUniform3d -#define glProgramUniform3dv gl3wProgramUniform3dv -#define glProgramUniform3ui gl3wProgramUniform3ui -#define glProgramUniform3uiv gl3wProgramUniform3uiv -#define glProgramUniform4i gl3wProgramUniform4i -#define glProgramUniform4iv gl3wProgramUniform4iv -#define glProgramUniform4f gl3wProgramUniform4f -#define glProgramUniform4fv gl3wProgramUniform4fv -#define glProgramUniform4d gl3wProgramUniform4d -#define glProgramUniform4dv gl3wProgramUniform4dv -#define glProgramUniform4ui gl3wProgramUniform4ui -#define glProgramUniform4uiv gl3wProgramUniform4uiv -#define glProgramUniformMatrix2fv gl3wProgramUniformMatrix2fv -#define glProgramUniformMatrix3fv gl3wProgramUniformMatrix3fv -#define glProgramUniformMatrix4fv gl3wProgramUniformMatrix4fv -#define glProgramUniformMatrix2dv gl3wProgramUniformMatrix2dv -#define glProgramUniformMatrix3dv gl3wProgramUniformMatrix3dv -#define glProgramUniformMatrix4dv gl3wProgramUniformMatrix4dv -#define glProgramUniformMatrix2x3fv gl3wProgramUniformMatrix2x3fv -#define glProgramUniformMatrix3x2fv gl3wProgramUniformMatrix3x2fv -#define glProgramUniformMatrix2x4fv gl3wProgramUniformMatrix2x4fv -#define glProgramUniformMatrix4x2fv gl3wProgramUniformMatrix4x2fv -#define glProgramUniformMatrix3x4fv gl3wProgramUniformMatrix3x4fv -#define glProgramUniformMatrix4x3fv gl3wProgramUniformMatrix4x3fv -#define glProgramUniformMatrix2x3dv gl3wProgramUniformMatrix2x3dv -#define glProgramUniformMatrix3x2dv gl3wProgramUniformMatrix3x2dv -#define glProgramUniformMatrix2x4dv gl3wProgramUniformMatrix2x4dv -#define glProgramUniformMatrix4x2dv gl3wProgramUniformMatrix4x2dv -#define glProgramUniformMatrix3x4dv gl3wProgramUniformMatrix3x4dv -#define glProgramUniformMatrix4x3dv gl3wProgramUniformMatrix4x3dv -#define glValidateProgramPipeline gl3wValidateProgramPipeline -#define glGetProgramPipelineInfoLog gl3wGetProgramPipelineInfoLog -#define glVertexAttribL1d gl3wVertexAttribL1d -#define glVertexAttribL2d gl3wVertexAttribL2d -#define glVertexAttribL3d gl3wVertexAttribL3d -#define glVertexAttribL4d gl3wVertexAttribL4d -#define glVertexAttribL1dv gl3wVertexAttribL1dv -#define glVertexAttribL2dv gl3wVertexAttribL2dv -#define glVertexAttribL3dv gl3wVertexAttribL3dv -#define glVertexAttribL4dv gl3wVertexAttribL4dv -#define glVertexAttribLPointer gl3wVertexAttribLPointer -#define glGetVertexAttribLdv gl3wGetVertexAttribLdv -#define glViewportArrayv gl3wViewportArrayv -#define glViewportIndexedf gl3wViewportIndexedf -#define glViewportIndexedfv gl3wViewportIndexedfv -#define glScissorArrayv gl3wScissorArrayv -#define glScissorIndexed gl3wScissorIndexed -#define glScissorIndexedv gl3wScissorIndexedv -#define glDepthRangeArrayv gl3wDepthRangeArrayv -#define glDepthRangeIndexed gl3wDepthRangeIndexed -#define glGetFloati_v gl3wGetFloati_v -#define glGetDoublei_v gl3wGetDoublei_v -#define glCreateSyncFromCLeventARB gl3wCreateSyncFromCLeventARB -#define glDebugMessageControlARB gl3wDebugMessageControlARB -#define glDebugMessageInsertARB gl3wDebugMessageInsertARB -#define glDebugMessageCallbackARB gl3wDebugMessageCallbackARB -#define glGetDebugMessageLogARB gl3wGetDebugMessageLogARB -#define glGetGraphicsResetStatusARB gl3wGetGraphicsResetStatusARB -#define glGetnTexImageARB gl3wGetnTexImageARB -#define glReadnPixelsARB gl3wReadnPixelsARB -#define glGetnCompressedTexImageARB gl3wGetnCompressedTexImageARB -#define glGetnUniformfvARB gl3wGetnUniformfvARB -#define glGetnUniformivARB gl3wGetnUniformivARB -#define glGetnUniformuivARB gl3wGetnUniformuivARB -#define glGetnUniformdvARB gl3wGetnUniformdvARB -#define glDrawArraysInstancedBaseInstance gl3wDrawArraysInstancedBaseInstance -#define glDrawElementsInstancedBaseInstance gl3wDrawElementsInstancedBaseInstance -#define glDrawElementsInstancedBaseVertexBaseInstance gl3wDrawElementsInstancedBaseVertexBaseInstance -#define glDrawTransformFeedbackInstanced gl3wDrawTransformFeedbackInstanced -#define glDrawTransformFeedbackStreamInstanced gl3wDrawTransformFeedbackStreamInstanced -#define glGetInternalformativ gl3wGetInternalformativ -#define glGetActiveAtomicCounterBufferiv gl3wGetActiveAtomicCounterBufferiv -#define glBindImageTexture gl3wBindImageTexture -#define glMemoryBarrier gl3wMemoryBarrier -#define glTexStorage1D gl3wTexStorage1D -#define glTexStorage2D gl3wTexStorage2D -#define glTexStorage3D gl3wTexStorage3D -#define glTextureStorage1DEXT gl3wTextureStorage1DEXT -#define glTextureStorage2DEXT gl3wTextureStorage2DEXT -#define glTextureStorage3DEXT gl3wTextureStorage3DEXT -#define glDebugMessageControl gl3wDebugMessageControl -#define glDebugMessageInsert gl3wDebugMessageInsert -#define glDebugMessageCallback gl3wDebugMessageCallback -#define glGetDebugMessageLog gl3wGetDebugMessageLog -#define glPushDebugGroup gl3wPushDebugGroup -#define glPopDebugGroup gl3wPopDebugGroup -#define glObjectLabel gl3wObjectLabel -#define glGetObjectLabel gl3wGetObjectLabel -#define glObjectPtrLabel gl3wObjectPtrLabel -#define glGetObjectPtrLabel gl3wGetObjectPtrLabel -#define glClearBufferData gl3wClearBufferData -#define glClearBufferSubData gl3wClearBufferSubData -#define glClearNamedBufferDataEXT gl3wClearNamedBufferDataEXT -#define glClearNamedBufferSubDataEXT gl3wClearNamedBufferSubDataEXT -#define glDispatchCompute gl3wDispatchCompute -#define glDispatchComputeIndirect gl3wDispatchComputeIndirect -#define glCopyImageSubData gl3wCopyImageSubData -#define glTextureView gl3wTextureView -#define glBindVertexBuffer gl3wBindVertexBuffer -#define glVertexAttribFormat gl3wVertexAttribFormat -#define glVertexAttribIFormat gl3wVertexAttribIFormat -#define glVertexAttribLFormat gl3wVertexAttribLFormat -#define glVertexAttribBinding gl3wVertexAttribBinding -#define glVertexBindingDivisor gl3wVertexBindingDivisor -#define glVertexArrayBindVertexBufferEXT gl3wVertexArrayBindVertexBufferEXT -#define glVertexArrayVertexAttribFormatEXT gl3wVertexArrayVertexAttribFormatEXT -#define glVertexArrayVertexAttribIFormatEXT gl3wVertexArrayVertexAttribIFormatEXT -#define glVertexArrayVertexAttribLFormatEXT gl3wVertexArrayVertexAttribLFormatEXT -#define glVertexArrayVertexAttribBindingEXT gl3wVertexArrayVertexAttribBindingEXT -#define glVertexArrayVertexBindingDivisorEXT gl3wVertexArrayVertexBindingDivisorEXT -#define glFramebufferParameteri gl3wFramebufferParameteri -#define glGetFramebufferParameteriv gl3wGetFramebufferParameteriv -#define glNamedFramebufferParameteriEXT gl3wNamedFramebufferParameteriEXT -#define glGetNamedFramebufferParameterivEXT gl3wGetNamedFramebufferParameterivEXT -#define glGetInternalformati64v gl3wGetInternalformati64v -#define glInvalidateTexSubImage gl3wInvalidateTexSubImage -#define glInvalidateTexImage gl3wInvalidateTexImage -#define glInvalidateBufferSubData gl3wInvalidateBufferSubData -#define glInvalidateBufferData gl3wInvalidateBufferData -#define glInvalidateFramebuffer gl3wInvalidateFramebuffer -#define glInvalidateSubFramebuffer gl3wInvalidateSubFramebuffer -#define glMultiDrawArraysIndirect gl3wMultiDrawArraysIndirect -#define glMultiDrawElementsIndirect gl3wMultiDrawElementsIndirect -#define glGetProgramInterfaceiv gl3wGetProgramInterfaceiv -#define glGetProgramResourceIndex gl3wGetProgramResourceIndex -#define glGetProgramResourceName gl3wGetProgramResourceName -#define glGetProgramResourceiv gl3wGetProgramResourceiv -#define glGetProgramResourceLocation gl3wGetProgramResourceLocation -#define glGetProgramResourceLocationIndex gl3wGetProgramResourceLocationIndex -#define glShaderStorageBlockBinding gl3wShaderStorageBlockBinding -#define glTexBufferRange gl3wTexBufferRange -#define glTextureBufferRangeEXT gl3wTextureBufferRangeEXT -#define glTexStorage2DMultisample gl3wTexStorage2DMultisample -#define glTexStorage3DMultisample gl3wTexStorage3DMultisample -#define glTextureStorage2DMultisampleEXT gl3wTextureStorage2DMultisampleEXT -#define glTextureStorage3DMultisampleEXT gl3wTextureStorage3DMultisampleEXT +#define glCullFace gl3wCullFace +#define glFrontFace gl3wFrontFace +#define glHint gl3wHint +#define glLineWidth gl3wLineWidth +#define glPointSize gl3wPointSize +#define glPolygonMode gl3wPolygonMode +#define glScissor gl3wScissor +#define glTexParameterf gl3wTexParameterf +#define glTexParameterfv gl3wTexParameterfv +#define glTexParameteri gl3wTexParameteri +#define glTexParameteriv gl3wTexParameteriv +#define glTexImage1D gl3wTexImage1D +#define glTexImage2D gl3wTexImage2D +#define glDrawBuffer gl3wDrawBuffer +#define glClear gl3wClear +#define glClearColor gl3wClearColor +#define glClearStencil gl3wClearStencil +#define glClearDepth gl3wClearDepth +#define glStencilMask gl3wStencilMask +#define glColorMask gl3wColorMask +#define glDepthMask gl3wDepthMask +#define glDisable gl3wDisable +#define glEnable gl3wEnable +#define glFinish gl3wFinish +#define glFlush gl3wFlush +#define glBlendFunc gl3wBlendFunc +#define glLogicOp gl3wLogicOp +#define glStencilFunc gl3wStencilFunc +#define glStencilOp gl3wStencilOp +#define glDepthFunc gl3wDepthFunc +#define glPixelStoref gl3wPixelStoref +#define glPixelStorei gl3wPixelStorei +#define glReadBuffer gl3wReadBuffer +#define glReadPixels gl3wReadPixels +#define glGetBooleanv gl3wGetBooleanv +#define glGetDoublev gl3wGetDoublev +#define glGetError gl3wGetError +#define glGetFloatv gl3wGetFloatv +#define glGetIntegerv gl3wGetIntegerv +#define glGetString gl3wGetString +#define glGetTexImage gl3wGetTexImage +#define glGetTexParameterfv gl3wGetTexParameterfv +#define glGetTexParameteriv gl3wGetTexParameteriv +#define glGetTexLevelParameterfv gl3wGetTexLevelParameterfv +#define glGetTexLevelParameteriv gl3wGetTexLevelParameteriv +#define glIsEnabled gl3wIsEnabled +#define glDepthRange gl3wDepthRange +#define glViewport gl3wViewport +#define glDrawArrays gl3wDrawArrays +#define glDrawElements gl3wDrawElements +#define glGetPointerv gl3wGetPointerv +#define glPolygonOffset gl3wPolygonOffset +#define glCopyTexImage1D gl3wCopyTexImage1D +#define glCopyTexImage2D gl3wCopyTexImage2D +#define glCopyTexSubImage1D gl3wCopyTexSubImage1D +#define glCopyTexSubImage2D gl3wCopyTexSubImage2D +#define glTexSubImage1D gl3wTexSubImage1D +#define glTexSubImage2D gl3wTexSubImage2D +#define glBindTexture gl3wBindTexture +#define glDeleteTextures gl3wDeleteTextures +#define glGenTextures gl3wGenTextures +#define glIsTexture gl3wIsTexture +#define glBlendColor gl3wBlendColor +#define glBlendEquation gl3wBlendEquation +#define glDrawRangeElements gl3wDrawRangeElements +#define glTexImage3D gl3wTexImage3D +#define glTexSubImage3D gl3wTexSubImage3D +#define glCopyTexSubImage3D gl3wCopyTexSubImage3D +#define glActiveTexture gl3wActiveTexture +#define glSampleCoverage gl3wSampleCoverage +#define glCompressedTexImage3D gl3wCompressedTexImage3D +#define glCompressedTexImage2D gl3wCompressedTexImage2D +#define glCompressedTexImage1D gl3wCompressedTexImage1D +#define glCompressedTexSubImage3D gl3wCompressedTexSubImage3D +#define glCompressedTexSubImage2D gl3wCompressedTexSubImage2D +#define glCompressedTexSubImage1D gl3wCompressedTexSubImage1D +#define glGetCompressedTexImage gl3wGetCompressedTexImage +#define glBlendFuncSeparate gl3wBlendFuncSeparate +#define glMultiDrawArrays gl3wMultiDrawArrays +#define glMultiDrawElements gl3wMultiDrawElements +#define glPointParameterf gl3wPointParameterf +#define glPointParameterfv gl3wPointParameterfv +#define glPointParameteri gl3wPointParameteri +#define glPointParameteriv gl3wPointParameteriv +#define glGenQueries gl3wGenQueries +#define glDeleteQueries gl3wDeleteQueries +#define glIsQuery gl3wIsQuery +#define glBeginQuery gl3wBeginQuery +#define glEndQuery gl3wEndQuery +#define glGetQueryiv gl3wGetQueryiv +#define glGetQueryObjectiv gl3wGetQueryObjectiv +#define glGetQueryObjectuiv gl3wGetQueryObjectuiv +#define glBindBuffer gl3wBindBuffer +#define glDeleteBuffers gl3wDeleteBuffers +#define glGenBuffers gl3wGenBuffers +#define glIsBuffer gl3wIsBuffer +#define glBufferData gl3wBufferData +#define glBufferSubData gl3wBufferSubData +#define glGetBufferSubData gl3wGetBufferSubData +#define glMapBuffer gl3wMapBuffer +#define glUnmapBuffer gl3wUnmapBuffer +#define glGetBufferParameteriv gl3wGetBufferParameteriv +#define glGetBufferPointerv gl3wGetBufferPointerv +#define glBlendEquationSeparate gl3wBlendEquationSeparate +#define glDrawBuffers gl3wDrawBuffers +#define glStencilOpSeparate gl3wStencilOpSeparate +#define glStencilFuncSeparate gl3wStencilFuncSeparate +#define glStencilMaskSeparate gl3wStencilMaskSeparate +#define glAttachShader gl3wAttachShader +#define glBindAttribLocation gl3wBindAttribLocation +#define glCompileShader gl3wCompileShader +#define glCreateProgram gl3wCreateProgram +#define glCreateShader gl3wCreateShader +#define glDeleteProgram gl3wDeleteProgram +#define glDeleteShader gl3wDeleteShader +#define glDetachShader gl3wDetachShader +#define glDisableVertexAttribArray gl3wDisableVertexAttribArray +#define glEnableVertexAttribArray gl3wEnableVertexAttribArray +#define glGetActiveAttrib gl3wGetActiveAttrib +#define glGetActiveUniform gl3wGetActiveUniform +#define glGetAttachedShaders gl3wGetAttachedShaders +#define glGetAttribLocation gl3wGetAttribLocation +#define glGetProgramiv gl3wGetProgramiv +#define glGetProgramInfoLog gl3wGetProgramInfoLog +#define glGetShaderiv gl3wGetShaderiv +#define glGetShaderInfoLog gl3wGetShaderInfoLog +#define glGetShaderSource gl3wGetShaderSource +#define glGetUniformLocation gl3wGetUniformLocation +#define glGetUniformfv gl3wGetUniformfv +#define glGetUniformiv gl3wGetUniformiv +#define glGetVertexAttribdv gl3wGetVertexAttribdv +#define glGetVertexAttribfv gl3wGetVertexAttribfv +#define glGetVertexAttribiv gl3wGetVertexAttribiv +#define glGetVertexAttribPointerv gl3wGetVertexAttribPointerv +#define glIsProgram gl3wIsProgram +#define glIsShader gl3wIsShader +#define glLinkProgram gl3wLinkProgram +#define glShaderSource gl3wShaderSource +#define glUseProgram gl3wUseProgram +#define glUniform1f gl3wUniform1f +#define glUniform2f gl3wUniform2f +#define glUniform3f gl3wUniform3f +#define glUniform4f gl3wUniform4f +#define glUniform1i gl3wUniform1i +#define glUniform2i gl3wUniform2i +#define glUniform3i gl3wUniform3i +#define glUniform4i gl3wUniform4i +#define glUniform1fv gl3wUniform1fv +#define glUniform2fv gl3wUniform2fv +#define glUniform3fv gl3wUniform3fv +#define glUniform4fv gl3wUniform4fv +#define glUniform1iv gl3wUniform1iv +#define glUniform2iv gl3wUniform2iv +#define glUniform3iv gl3wUniform3iv +#define glUniform4iv gl3wUniform4iv +#define glUniformMatrix2fv gl3wUniformMatrix2fv +#define glUniformMatrix3fv gl3wUniformMatrix3fv +#define glUniformMatrix4fv gl3wUniformMatrix4fv +#define glValidateProgram gl3wValidateProgram +#define glVertexAttrib1d gl3wVertexAttrib1d +#define glVertexAttrib1dv gl3wVertexAttrib1dv +#define glVertexAttrib1f gl3wVertexAttrib1f +#define glVertexAttrib1fv gl3wVertexAttrib1fv +#define glVertexAttrib1s gl3wVertexAttrib1s +#define glVertexAttrib1sv gl3wVertexAttrib1sv +#define glVertexAttrib2d gl3wVertexAttrib2d +#define glVertexAttrib2dv gl3wVertexAttrib2dv +#define glVertexAttrib2f gl3wVertexAttrib2f +#define glVertexAttrib2fv gl3wVertexAttrib2fv +#define glVertexAttrib2s gl3wVertexAttrib2s +#define glVertexAttrib2sv gl3wVertexAttrib2sv +#define glVertexAttrib3d gl3wVertexAttrib3d +#define glVertexAttrib3dv gl3wVertexAttrib3dv +#define glVertexAttrib3f gl3wVertexAttrib3f +#define glVertexAttrib3fv gl3wVertexAttrib3fv +#define glVertexAttrib3s gl3wVertexAttrib3s +#define glVertexAttrib3sv gl3wVertexAttrib3sv +#define glVertexAttrib4Nbv gl3wVertexAttrib4Nbv +#define glVertexAttrib4Niv gl3wVertexAttrib4Niv +#define glVertexAttrib4Nsv gl3wVertexAttrib4Nsv +#define glVertexAttrib4Nub gl3wVertexAttrib4Nub +#define glVertexAttrib4Nubv gl3wVertexAttrib4Nubv +#define glVertexAttrib4Nuiv gl3wVertexAttrib4Nuiv +#define glVertexAttrib4Nusv gl3wVertexAttrib4Nusv +#define glVertexAttrib4bv gl3wVertexAttrib4bv +#define glVertexAttrib4d gl3wVertexAttrib4d +#define glVertexAttrib4dv gl3wVertexAttrib4dv +#define glVertexAttrib4f gl3wVertexAttrib4f +#define glVertexAttrib4fv gl3wVertexAttrib4fv +#define glVertexAttrib4iv gl3wVertexAttrib4iv +#define glVertexAttrib4s gl3wVertexAttrib4s +#define glVertexAttrib4sv gl3wVertexAttrib4sv +#define glVertexAttrib4ubv gl3wVertexAttrib4ubv +#define glVertexAttrib4uiv gl3wVertexAttrib4uiv +#define glVertexAttrib4usv gl3wVertexAttrib4usv +#define glVertexAttribPointer gl3wVertexAttribPointer +#define glUniformMatrix2x3fv gl3wUniformMatrix2x3fv +#define glUniformMatrix3x2fv gl3wUniformMatrix3x2fv +#define glUniformMatrix2x4fv gl3wUniformMatrix2x4fv +#define glUniformMatrix4x2fv gl3wUniformMatrix4x2fv +#define glUniformMatrix3x4fv gl3wUniformMatrix3x4fv +#define glUniformMatrix4x3fv gl3wUniformMatrix4x3fv +#define glColorMaski gl3wColorMaski +#define glGetBooleani_v gl3wGetBooleani_v +#define glGetIntegeri_v gl3wGetIntegeri_v +#define glEnablei gl3wEnablei +#define glDisablei gl3wDisablei +#define glIsEnabledi gl3wIsEnabledi +#define glBeginTransformFeedback gl3wBeginTransformFeedback +#define glEndTransformFeedback gl3wEndTransformFeedback +#define glBindBufferRange gl3wBindBufferRange +#define glBindBufferBase gl3wBindBufferBase +#define glTransformFeedbackVaryings gl3wTransformFeedbackVaryings +#define glGetTransformFeedbackVarying gl3wGetTransformFeedbackVarying +#define glClampColor gl3wClampColor +#define glBeginConditionalRender gl3wBeginConditionalRender +#define glEndConditionalRender gl3wEndConditionalRender +#define glVertexAttribIPointer gl3wVertexAttribIPointer +#define glGetVertexAttribIiv gl3wGetVertexAttribIiv +#define glGetVertexAttribIuiv gl3wGetVertexAttribIuiv +#define glVertexAttribI1i gl3wVertexAttribI1i +#define glVertexAttribI2i gl3wVertexAttribI2i +#define glVertexAttribI3i gl3wVertexAttribI3i +#define glVertexAttribI4i gl3wVertexAttribI4i +#define glVertexAttribI1ui gl3wVertexAttribI1ui +#define glVertexAttribI2ui gl3wVertexAttribI2ui +#define glVertexAttribI3ui gl3wVertexAttribI3ui +#define glVertexAttribI4ui gl3wVertexAttribI4ui +#define glVertexAttribI1iv gl3wVertexAttribI1iv +#define glVertexAttribI2iv gl3wVertexAttribI2iv +#define glVertexAttribI3iv gl3wVertexAttribI3iv +#define glVertexAttribI4iv gl3wVertexAttribI4iv +#define glVertexAttribI1uiv gl3wVertexAttribI1uiv +#define glVertexAttribI2uiv gl3wVertexAttribI2uiv +#define glVertexAttribI3uiv gl3wVertexAttribI3uiv +#define glVertexAttribI4uiv gl3wVertexAttribI4uiv +#define glVertexAttribI4bv gl3wVertexAttribI4bv +#define glVertexAttribI4sv gl3wVertexAttribI4sv +#define glVertexAttribI4ubv gl3wVertexAttribI4ubv +#define glVertexAttribI4usv gl3wVertexAttribI4usv +#define glGetUniformuiv gl3wGetUniformuiv +#define glBindFragDataLocation gl3wBindFragDataLocation +#define glGetFragDataLocation gl3wGetFragDataLocation +#define glUniform1ui gl3wUniform1ui +#define glUniform2ui gl3wUniform2ui +#define glUniform3ui gl3wUniform3ui +#define glUniform4ui gl3wUniform4ui +#define glUniform1uiv gl3wUniform1uiv +#define glUniform2uiv gl3wUniform2uiv +#define glUniform3uiv gl3wUniform3uiv +#define glUniform4uiv gl3wUniform4uiv +#define glTexParameterIiv gl3wTexParameterIiv +#define glTexParameterIuiv gl3wTexParameterIuiv +#define glGetTexParameterIiv gl3wGetTexParameterIiv +#define glGetTexParameterIuiv gl3wGetTexParameterIuiv +#define glClearBufferiv gl3wClearBufferiv +#define glClearBufferuiv gl3wClearBufferuiv +#define glClearBufferfv gl3wClearBufferfv +#define glClearBufferfi gl3wClearBufferfi +#define glGetStringi gl3wGetStringi +#define glDrawArraysInstanced gl3wDrawArraysInstanced +#define glDrawElementsInstanced gl3wDrawElementsInstanced +#define glTexBuffer gl3wTexBuffer +#define glPrimitiveRestartIndex gl3wPrimitiveRestartIndex +#define glGetInteger64i_v gl3wGetInteger64i_v +#define glGetBufferParameteri64v gl3wGetBufferParameteri64v +#define glFramebufferTexture gl3wFramebufferTexture +#define glVertexAttribDivisor gl3wVertexAttribDivisor +#define glMinSampleShading gl3wMinSampleShading +#define glBlendEquationi gl3wBlendEquationi +#define glBlendEquationSeparatei gl3wBlendEquationSeparatei +#define glBlendFunci gl3wBlendFunci +#define glBlendFuncSeparatei gl3wBlendFuncSeparatei +#define glIsRenderbuffer gl3wIsRenderbuffer +#define glBindRenderbuffer gl3wBindRenderbuffer +#define glDeleteRenderbuffers gl3wDeleteRenderbuffers +#define glGenRenderbuffers gl3wGenRenderbuffers +#define glRenderbufferStorage gl3wRenderbufferStorage +#define glGetRenderbufferParameteriv gl3wGetRenderbufferParameteriv +#define glIsFramebuffer gl3wIsFramebuffer +#define glBindFramebuffer gl3wBindFramebuffer +#define glDeleteFramebuffers gl3wDeleteFramebuffers +#define glGenFramebuffers gl3wGenFramebuffers +#define glCheckFramebufferStatus gl3wCheckFramebufferStatus +#define glFramebufferTexture1D gl3wFramebufferTexture1D +#define glFramebufferTexture2D gl3wFramebufferTexture2D +#define glFramebufferTexture3D gl3wFramebufferTexture3D +#define glFramebufferRenderbuffer gl3wFramebufferRenderbuffer +#define glGetFramebufferAttachmentParameteriv gl3wGetFramebufferAttachmentParameteriv +#define glGenerateMipmap gl3wGenerateMipmap +#define glBlitFramebuffer gl3wBlitFramebuffer +#define glRenderbufferStorageMultisample gl3wRenderbufferStorageMultisample +#define glFramebufferTextureLayer gl3wFramebufferTextureLayer +#define glMapBufferRange gl3wMapBufferRange +#define glFlushMappedBufferRange gl3wFlushMappedBufferRange +#define glBindVertexArray gl3wBindVertexArray +#define glDeleteVertexArrays gl3wDeleteVertexArrays +#define glGenVertexArrays gl3wGenVertexArrays +#define glIsVertexArray gl3wIsVertexArray +#define glGetUniformIndices gl3wGetUniformIndices +#define glGetActiveUniformsiv gl3wGetActiveUniformsiv +#define glGetActiveUniformName gl3wGetActiveUniformName +#define glGetUniformBlockIndex gl3wGetUniformBlockIndex +#define glGetActiveUniformBlockiv gl3wGetActiveUniformBlockiv +#define glGetActiveUniformBlockName gl3wGetActiveUniformBlockName +#define glUniformBlockBinding gl3wUniformBlockBinding +#define glCopyBufferSubData gl3wCopyBufferSubData +#define glDrawElementsBaseVertex gl3wDrawElementsBaseVertex +#define glDrawRangeElementsBaseVertex gl3wDrawRangeElementsBaseVertex +#define glDrawElementsInstancedBaseVertex gl3wDrawElementsInstancedBaseVertex +#define glMultiDrawElementsBaseVertex gl3wMultiDrawElementsBaseVertex +#define glProvokingVertex gl3wProvokingVertex +#define glFenceSync gl3wFenceSync +#define glIsSync gl3wIsSync +#define glDeleteSync gl3wDeleteSync +#define glClientWaitSync gl3wClientWaitSync +#define glWaitSync gl3wWaitSync +#define glGetInteger64v gl3wGetInteger64v +#define glGetSynciv gl3wGetSynciv +#define glTexImage2DMultisample gl3wTexImage2DMultisample +#define glTexImage3DMultisample gl3wTexImage3DMultisample +#define glGetMultisamplefv gl3wGetMultisamplefv +#define glSampleMaski gl3wSampleMaski +#define glBlendEquationiARB gl3wBlendEquationiARB +#define glBlendEquationSeparateiARB gl3wBlendEquationSeparateiARB +#define glBlendFunciARB gl3wBlendFunciARB +#define glBlendFuncSeparateiARB gl3wBlendFuncSeparateiARB +#define glMinSampleShadingARB gl3wMinSampleShadingARB +#define glNamedStringARB gl3wNamedStringARB +#define glDeleteNamedStringARB gl3wDeleteNamedStringARB +#define glCompileShaderIncludeARB gl3wCompileShaderIncludeARB +#define glIsNamedStringARB gl3wIsNamedStringARB +#define glGetNamedStringARB gl3wGetNamedStringARB +#define glGetNamedStringivARB gl3wGetNamedStringivARB +#define glBindFragDataLocationIndexed gl3wBindFragDataLocationIndexed +#define glGetFragDataIndex gl3wGetFragDataIndex +#define glGenSamplers gl3wGenSamplers +#define glDeleteSamplers gl3wDeleteSamplers +#define glIsSampler gl3wIsSampler +#define glBindSampler gl3wBindSampler +#define glSamplerParameteri gl3wSamplerParameteri +#define glSamplerParameteriv gl3wSamplerParameteriv +#define glSamplerParameterf gl3wSamplerParameterf +#define glSamplerParameterfv gl3wSamplerParameterfv +#define glSamplerParameterIiv gl3wSamplerParameterIiv +#define glSamplerParameterIuiv gl3wSamplerParameterIuiv +#define glGetSamplerParameteriv gl3wGetSamplerParameteriv +#define glGetSamplerParameterIiv gl3wGetSamplerParameterIiv +#define glGetSamplerParameterfv gl3wGetSamplerParameterfv +#define glGetSamplerParameterIuiv gl3wGetSamplerParameterIuiv +#define glQueryCounter gl3wQueryCounter +#define glGetQueryObjecti64v gl3wGetQueryObjecti64v +#define glGetQueryObjectui64v gl3wGetQueryObjectui64v +#define glVertexP2ui gl3wVertexP2ui +#define glVertexP2uiv gl3wVertexP2uiv +#define glVertexP3ui gl3wVertexP3ui +#define glVertexP3uiv gl3wVertexP3uiv +#define glVertexP4ui gl3wVertexP4ui +#define glVertexP4uiv gl3wVertexP4uiv +#define glTexCoordP1ui gl3wTexCoordP1ui +#define glTexCoordP1uiv gl3wTexCoordP1uiv +#define glTexCoordP2ui gl3wTexCoordP2ui +#define glTexCoordP2uiv gl3wTexCoordP2uiv +#define glTexCoordP3ui gl3wTexCoordP3ui +#define glTexCoordP3uiv gl3wTexCoordP3uiv +#define glTexCoordP4ui gl3wTexCoordP4ui +#define glTexCoordP4uiv gl3wTexCoordP4uiv +#define glMultiTexCoordP1ui gl3wMultiTexCoordP1ui +#define glMultiTexCoordP1uiv gl3wMultiTexCoordP1uiv +#define glMultiTexCoordP2ui gl3wMultiTexCoordP2ui +#define glMultiTexCoordP2uiv gl3wMultiTexCoordP2uiv +#define glMultiTexCoordP3ui gl3wMultiTexCoordP3ui +#define glMultiTexCoordP3uiv gl3wMultiTexCoordP3uiv +#define glMultiTexCoordP4ui gl3wMultiTexCoordP4ui +#define glMultiTexCoordP4uiv gl3wMultiTexCoordP4uiv +#define glNormalP3ui gl3wNormalP3ui +#define glNormalP3uiv gl3wNormalP3uiv +#define glColorP3ui gl3wColorP3ui +#define glColorP3uiv gl3wColorP3uiv +#define glColorP4ui gl3wColorP4ui +#define glColorP4uiv gl3wColorP4uiv +#define glSecondaryColorP3ui gl3wSecondaryColorP3ui +#define glSecondaryColorP3uiv gl3wSecondaryColorP3uiv +#define glVertexAttribP1ui gl3wVertexAttribP1ui +#define glVertexAttribP1uiv gl3wVertexAttribP1uiv +#define glVertexAttribP2ui gl3wVertexAttribP2ui +#define glVertexAttribP2uiv gl3wVertexAttribP2uiv +#define glVertexAttribP3ui gl3wVertexAttribP3ui +#define glVertexAttribP3uiv gl3wVertexAttribP3uiv +#define glVertexAttribP4ui gl3wVertexAttribP4ui +#define glVertexAttribP4uiv gl3wVertexAttribP4uiv +#define glDrawArraysIndirect gl3wDrawArraysIndirect +#define glDrawElementsIndirect gl3wDrawElementsIndirect +#define glUniform1d gl3wUniform1d +#define glUniform2d gl3wUniform2d +#define glUniform3d gl3wUniform3d +#define glUniform4d gl3wUniform4d +#define glUniform1dv gl3wUniform1dv +#define glUniform2dv gl3wUniform2dv +#define glUniform3dv gl3wUniform3dv +#define glUniform4dv gl3wUniform4dv +#define glUniformMatrix2dv gl3wUniformMatrix2dv +#define glUniformMatrix3dv gl3wUniformMatrix3dv +#define glUniformMatrix4dv gl3wUniformMatrix4dv +#define glUniformMatrix2x3dv gl3wUniformMatrix2x3dv +#define glUniformMatrix2x4dv gl3wUniformMatrix2x4dv +#define glUniformMatrix3x2dv gl3wUniformMatrix3x2dv +#define glUniformMatrix3x4dv gl3wUniformMatrix3x4dv +#define glUniformMatrix4x2dv gl3wUniformMatrix4x2dv +#define glUniformMatrix4x3dv gl3wUniformMatrix4x3dv +#define glGetUniformdv gl3wGetUniformdv +#define glGetSubroutineUniformLocation gl3wGetSubroutineUniformLocation +#define glGetSubroutineIndex gl3wGetSubroutineIndex +#define glGetActiveSubroutineUniformiv gl3wGetActiveSubroutineUniformiv +#define glGetActiveSubroutineUniformName gl3wGetActiveSubroutineUniformName +#define glGetActiveSubroutineName gl3wGetActiveSubroutineName +#define glUniformSubroutinesuiv gl3wUniformSubroutinesuiv +#define glGetUniformSubroutineuiv gl3wGetUniformSubroutineuiv +#define glGetProgramStageiv gl3wGetProgramStageiv +#define glPatchParameteri gl3wPatchParameteri +#define glPatchParameterfv gl3wPatchParameterfv +#define glBindTransformFeedback gl3wBindTransformFeedback +#define glDeleteTransformFeedbacks gl3wDeleteTransformFeedbacks +#define glGenTransformFeedbacks gl3wGenTransformFeedbacks +#define glIsTransformFeedback gl3wIsTransformFeedback +#define glPauseTransformFeedback gl3wPauseTransformFeedback +#define glResumeTransformFeedback gl3wResumeTransformFeedback +#define glDrawTransformFeedback gl3wDrawTransformFeedback +#define glDrawTransformFeedbackStream gl3wDrawTransformFeedbackStream +#define glBeginQueryIndexed gl3wBeginQueryIndexed +#define glEndQueryIndexed gl3wEndQueryIndexed +#define glGetQueryIndexediv gl3wGetQueryIndexediv +#define glReleaseShaderCompiler gl3wReleaseShaderCompiler +#define glShaderBinary gl3wShaderBinary +#define glGetShaderPrecisionFormat gl3wGetShaderPrecisionFormat +#define glDepthRangef gl3wDepthRangef +#define glClearDepthf gl3wClearDepthf +#define glGetProgramBinary gl3wGetProgramBinary +#define glProgramBinary gl3wProgramBinary +#define glProgramParameteri gl3wProgramParameteri +#define glUseProgramStages gl3wUseProgramStages +#define glActiveShaderProgram gl3wActiveShaderProgram +#define glCreateShaderProgramv gl3wCreateShaderProgramv +#define glBindProgramPipeline gl3wBindProgramPipeline +#define glDeleteProgramPipelines gl3wDeleteProgramPipelines +#define glGenProgramPipelines gl3wGenProgramPipelines +#define glIsProgramPipeline gl3wIsProgramPipeline +#define glGetProgramPipelineiv gl3wGetProgramPipelineiv +#define glProgramUniform1i gl3wProgramUniform1i +#define glProgramUniform1iv gl3wProgramUniform1iv +#define glProgramUniform1f gl3wProgramUniform1f +#define glProgramUniform1fv gl3wProgramUniform1fv +#define glProgramUniform1d gl3wProgramUniform1d +#define glProgramUniform1dv gl3wProgramUniform1dv +#define glProgramUniform1ui gl3wProgramUniform1ui +#define glProgramUniform1uiv gl3wProgramUniform1uiv +#define glProgramUniform2i gl3wProgramUniform2i +#define glProgramUniform2iv gl3wProgramUniform2iv +#define glProgramUniform2f gl3wProgramUniform2f +#define glProgramUniform2fv gl3wProgramUniform2fv +#define glProgramUniform2d gl3wProgramUniform2d +#define glProgramUniform2dv gl3wProgramUniform2dv +#define glProgramUniform2ui gl3wProgramUniform2ui +#define glProgramUniform2uiv gl3wProgramUniform2uiv +#define glProgramUniform3i gl3wProgramUniform3i +#define glProgramUniform3iv gl3wProgramUniform3iv +#define glProgramUniform3f gl3wProgramUniform3f +#define glProgramUniform3fv gl3wProgramUniform3fv +#define glProgramUniform3d gl3wProgramUniform3d +#define glProgramUniform3dv gl3wProgramUniform3dv +#define glProgramUniform3ui gl3wProgramUniform3ui +#define glProgramUniform3uiv gl3wProgramUniform3uiv +#define glProgramUniform4i gl3wProgramUniform4i +#define glProgramUniform4iv gl3wProgramUniform4iv +#define glProgramUniform4f gl3wProgramUniform4f +#define glProgramUniform4fv gl3wProgramUniform4fv +#define glProgramUniform4d gl3wProgramUniform4d +#define glProgramUniform4dv gl3wProgramUniform4dv +#define glProgramUniform4ui gl3wProgramUniform4ui +#define glProgramUniform4uiv gl3wProgramUniform4uiv +#define glProgramUniformMatrix2fv gl3wProgramUniformMatrix2fv +#define glProgramUniformMatrix3fv gl3wProgramUniformMatrix3fv +#define glProgramUniformMatrix4fv gl3wProgramUniformMatrix4fv +#define glProgramUniformMatrix2dv gl3wProgramUniformMatrix2dv +#define glProgramUniformMatrix3dv gl3wProgramUniformMatrix3dv +#define glProgramUniformMatrix4dv gl3wProgramUniformMatrix4dv +#define glProgramUniformMatrix2x3fv gl3wProgramUniformMatrix2x3fv +#define glProgramUniformMatrix3x2fv gl3wProgramUniformMatrix3x2fv +#define glProgramUniformMatrix2x4fv gl3wProgramUniformMatrix2x4fv +#define glProgramUniformMatrix4x2fv gl3wProgramUniformMatrix4x2fv +#define glProgramUniformMatrix3x4fv gl3wProgramUniformMatrix3x4fv +#define glProgramUniformMatrix4x3fv gl3wProgramUniformMatrix4x3fv +#define glProgramUniformMatrix2x3dv gl3wProgramUniformMatrix2x3dv +#define glProgramUniformMatrix3x2dv gl3wProgramUniformMatrix3x2dv +#define glProgramUniformMatrix2x4dv gl3wProgramUniformMatrix2x4dv +#define glProgramUniformMatrix4x2dv gl3wProgramUniformMatrix4x2dv +#define glProgramUniformMatrix3x4dv gl3wProgramUniformMatrix3x4dv +#define glProgramUniformMatrix4x3dv gl3wProgramUniformMatrix4x3dv +#define glValidateProgramPipeline gl3wValidateProgramPipeline +#define glGetProgramPipelineInfoLog gl3wGetProgramPipelineInfoLog +#define glVertexAttribL1d gl3wVertexAttribL1d +#define glVertexAttribL2d gl3wVertexAttribL2d +#define glVertexAttribL3d gl3wVertexAttribL3d +#define glVertexAttribL4d gl3wVertexAttribL4d +#define glVertexAttribL1dv gl3wVertexAttribL1dv +#define glVertexAttribL2dv gl3wVertexAttribL2dv +#define glVertexAttribL3dv gl3wVertexAttribL3dv +#define glVertexAttribL4dv gl3wVertexAttribL4dv +#define glVertexAttribLPointer gl3wVertexAttribLPointer +#define glGetVertexAttribLdv gl3wGetVertexAttribLdv +#define glViewportArrayv gl3wViewportArrayv +#define glViewportIndexedf gl3wViewportIndexedf +#define glViewportIndexedfv gl3wViewportIndexedfv +#define glScissorArrayv gl3wScissorArrayv +#define glScissorIndexed gl3wScissorIndexed +#define glScissorIndexedv gl3wScissorIndexedv +#define glDepthRangeArrayv gl3wDepthRangeArrayv +#define glDepthRangeIndexed gl3wDepthRangeIndexed +#define glGetFloati_v gl3wGetFloati_v +#define glGetDoublei_v gl3wGetDoublei_v +#define glCreateSyncFromCLeventARB gl3wCreateSyncFromCLeventARB +#define glDebugMessageControlARB gl3wDebugMessageControlARB +#define glDebugMessageInsertARB gl3wDebugMessageInsertARB +#define glDebugMessageCallbackARB gl3wDebugMessageCallbackARB +#define glGetDebugMessageLogARB gl3wGetDebugMessageLogARB +#define glGetGraphicsResetStatusARB gl3wGetGraphicsResetStatusARB +#define glGetnTexImageARB gl3wGetnTexImageARB +#define glReadnPixelsARB gl3wReadnPixelsARB +#define glGetnCompressedTexImageARB gl3wGetnCompressedTexImageARB +#define glGetnUniformfvARB gl3wGetnUniformfvARB +#define glGetnUniformivARB gl3wGetnUniformivARB +#define glGetnUniformuivARB gl3wGetnUniformuivARB +#define glGetnUniformdvARB gl3wGetnUniformdvARB +#define glDrawArraysInstancedBaseInstance gl3wDrawArraysInstancedBaseInstance +#define glDrawElementsInstancedBaseInstance gl3wDrawElementsInstancedBaseInstance +#define glDrawElementsInstancedBaseVertexBaseInstance gl3wDrawElementsInstancedBaseVertexBaseInstance +#define glDrawTransformFeedbackInstanced gl3wDrawTransformFeedbackInstanced +#define glDrawTransformFeedbackStreamInstanced gl3wDrawTransformFeedbackStreamInstanced +#define glGetInternalformativ gl3wGetInternalformativ +#define glGetActiveAtomicCounterBufferiv gl3wGetActiveAtomicCounterBufferiv +#define glBindImageTexture gl3wBindImageTexture +#define glMemoryBarrier gl3wMemoryBarrier +#define glTexStorage1D gl3wTexStorage1D +#define glTexStorage2D gl3wTexStorage2D +#define glTexStorage3D gl3wTexStorage3D +#define glTextureStorage1DEXT gl3wTextureStorage1DEXT +#define glTextureStorage2DEXT gl3wTextureStorage2DEXT +#define glTextureStorage3DEXT gl3wTextureStorage3DEXT +#define glDebugMessageControl gl3wDebugMessageControl +#define glDebugMessageInsert gl3wDebugMessageInsert +#define glDebugMessageCallback gl3wDebugMessageCallback +#define glGetDebugMessageLog gl3wGetDebugMessageLog +#define glPushDebugGroup gl3wPushDebugGroup +#define glPopDebugGroup gl3wPopDebugGroup +#define glObjectLabel gl3wObjectLabel +#define glGetObjectLabel gl3wGetObjectLabel +#define glObjectPtrLabel gl3wObjectPtrLabel +#define glGetObjectPtrLabel gl3wGetObjectPtrLabel +#define glClearBufferData gl3wClearBufferData +#define glClearBufferSubData gl3wClearBufferSubData +#define glClearNamedBufferDataEXT gl3wClearNamedBufferDataEXT +#define glClearNamedBufferSubDataEXT gl3wClearNamedBufferSubDataEXT +#define glDispatchCompute gl3wDispatchCompute +#define glDispatchComputeIndirect gl3wDispatchComputeIndirect +#define glCopyImageSubData gl3wCopyImageSubData +#define glTextureView gl3wTextureView +#define glBindVertexBuffer gl3wBindVertexBuffer +#define glVertexAttribFormat gl3wVertexAttribFormat +#define glVertexAttribIFormat gl3wVertexAttribIFormat +#define glVertexAttribLFormat gl3wVertexAttribLFormat +#define glVertexAttribBinding gl3wVertexAttribBinding +#define glVertexBindingDivisor gl3wVertexBindingDivisor +#define glVertexArrayBindVertexBufferEXT gl3wVertexArrayBindVertexBufferEXT +#define glVertexArrayVertexAttribFormatEXT gl3wVertexArrayVertexAttribFormatEXT +#define glVertexArrayVertexAttribIFormatEXT gl3wVertexArrayVertexAttribIFormatEXT +#define glVertexArrayVertexAttribLFormatEXT gl3wVertexArrayVertexAttribLFormatEXT +#define glVertexArrayVertexAttribBindingEXT gl3wVertexArrayVertexAttribBindingEXT +#define glVertexArrayVertexBindingDivisorEXT gl3wVertexArrayVertexBindingDivisorEXT +#define glFramebufferParameteri gl3wFramebufferParameteri +#define glGetFramebufferParameteriv gl3wGetFramebufferParameteriv +#define glNamedFramebufferParameteriEXT gl3wNamedFramebufferParameteriEXT +#define glGetNamedFramebufferParameterivEXT gl3wGetNamedFramebufferParameterivEXT +#define glGetInternalformati64v gl3wGetInternalformati64v +#define glInvalidateTexSubImage gl3wInvalidateTexSubImage +#define glInvalidateTexImage gl3wInvalidateTexImage +#define glInvalidateBufferSubData gl3wInvalidateBufferSubData +#define glInvalidateBufferData gl3wInvalidateBufferData +#define glInvalidateFramebuffer gl3wInvalidateFramebuffer +#define glInvalidateSubFramebuffer gl3wInvalidateSubFramebuffer +#define glMultiDrawArraysIndirect gl3wMultiDrawArraysIndirect +#define glMultiDrawElementsIndirect gl3wMultiDrawElementsIndirect +#define glGetProgramInterfaceiv gl3wGetProgramInterfaceiv +#define glGetProgramResourceIndex gl3wGetProgramResourceIndex +#define glGetProgramResourceName gl3wGetProgramResourceName +#define glGetProgramResourceiv gl3wGetProgramResourceiv +#define glGetProgramResourceLocation gl3wGetProgramResourceLocation +#define glGetProgramResourceLocationIndex gl3wGetProgramResourceLocationIndex +#define glShaderStorageBlockBinding gl3wShaderStorageBlockBinding +#define glTexBufferRange gl3wTexBufferRange +#define glTextureBufferRangeEXT gl3wTextureBufferRangeEXT +#define glTexStorage2DMultisample gl3wTexStorage2DMultisample +#define glTexStorage3DMultisample gl3wTexStorage3DMultisample +#define glTextureStorage2DMultisampleEXT gl3wTextureStorage2DMultisampleEXT +#define glTextureStorage3DMultisampleEXT gl3wTextureStorage3DMultisampleEXT #ifdef __cplusplus } diff --git a/RenderSystems/GL3Plus/include/GL/glext.h b/RenderSystems/GL3Plus/include/GL/glext.h index 207a0e55f21..0b913867e66 100644 --- a/RenderSystems/GL3Plus/include/GL/glext.h +++ b/RenderSystems/GL3Plus/include/GL/glext.h @@ -4132,9 +4132,9 @@ extern "C" { #endif #ifndef GL_AMD_compressed_ATC_texture -#define ATC_RGB_AMD 0x8C92 -#define ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 -#define ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#define ATC_RGB_AMD 0x8C92 +#define ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE #endif #ifndef GL_IBM_cull_vertex diff --git a/RenderSystems/GL3Plus/include/GL/glxext.h b/RenderSystems/GL3Plus/include/GL/glxext.h index 9f0ec4afbea..65b1e6e5d24 100644 --- a/RenderSystems/GL3Plus/include/GL/glxext.h +++ b/RenderSystems/GL3Plus/include/GL/glxext.h @@ -468,16 +468,16 @@ typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; typedef XID GLXPbufferSGIX; typedef struct { int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came for SendEvent request */ - Display *display; /* display the event was read from */ - GLXDrawable drawable; /* i.d. of Drawable */ - int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ - int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ - unsigned int mask; /* mask indicating which buffers are affected*/ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* i.d. of Drawable */ + int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ + int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ + unsigned int mask; /* mask indicating which buffers are affected*/ int x, y; int width, height; - int count; /* if nonzero, at least this many more */ + int count; /* if nonzero, at least this many more */ } GLXBufferClobberEventSGIX; #endif diff --git a/RenderSystems/GL3Plus/include/GL/glxtokens-backup.h b/RenderSystems/GL3Plus/include/GL/glxtokens-backup.h index e30c579b3e8..d151f7351ca 100644 --- a/RenderSystems/GL3Plus/include/GL/glxtokens-backup.h +++ b/RenderSystems/GL3Plus/include/GL/glxtokens-backup.h @@ -48,54 +48,54 @@ extern "C" { /* ** Visual Config Attributes (glXGetConfig, glXGetFBConfigAttrib) */ -#define GLX_USE_GL 1 /* support GLX rendering */ -#define GLX_BUFFER_SIZE 2 /* depth of the color buffer */ -#define GLX_LEVEL 3 /* level in plane stacking */ -#define GLX_RGBA 4 /* true if RGBA mode */ -#define GLX_DOUBLEBUFFER 5 /* double buffering supported */ -#define GLX_STEREO 6 /* stereo buffering supported */ -#define GLX_AUX_BUFFERS 7 /* number of aux buffers */ -#define GLX_RED_SIZE 8 /* number of red component bits */ -#define GLX_GREEN_SIZE 9 /* number of green component bits */ -#define GLX_BLUE_SIZE 10 /* number of blue component bits */ -#define GLX_ALPHA_SIZE 11 /* number of alpha component bits */ -#define GLX_DEPTH_SIZE 12 /* number of depth bits */ -#define GLX_STENCIL_SIZE 13 /* number of stencil bits */ -#define GLX_ACCUM_RED_SIZE 14 /* number of red accum bits */ -#define GLX_ACCUM_GREEN_SIZE 15 /* number of green accum bits */ -#define GLX_ACCUM_BLUE_SIZE 16 /* number of blue accum bits */ -#define GLX_ACCUM_ALPHA_SIZE 17 /* number of alpha accum bits */ +#define GLX_USE_GL 1 /* support GLX rendering */ +#define GLX_BUFFER_SIZE 2 /* depth of the color buffer */ +#define GLX_LEVEL 3 /* level in plane stacking */ +#define GLX_RGBA 4 /* true if RGBA mode */ +#define GLX_DOUBLEBUFFER 5 /* double buffering supported */ +#define GLX_STEREO 6 /* stereo buffering supported */ +#define GLX_AUX_BUFFERS 7 /* number of aux buffers */ +#define GLX_RED_SIZE 8 /* number of red component bits */ +#define GLX_GREEN_SIZE 9 /* number of green component bits */ +#define GLX_BLUE_SIZE 10 /* number of blue component bits */ +#define GLX_ALPHA_SIZE 11 /* number of alpha component bits */ +#define GLX_DEPTH_SIZE 12 /* number of depth bits */ +#define GLX_STENCIL_SIZE 13 /* number of stencil bits */ +#define GLX_ACCUM_RED_SIZE 14 /* number of red accum bits */ +#define GLX_ACCUM_GREEN_SIZE 15 /* number of green accum bits */ +#define GLX_ACCUM_BLUE_SIZE 16 /* number of blue accum bits */ +#define GLX_ACCUM_ALPHA_SIZE 17 /* number of alpha accum bits */ /* ** FBConfig-specific attributes */ -#define GLX_X_VISUAL_TYPE 0x22 -#define GLX_CONFIG_CAVEAT 0x20 /* Like visual_info VISUAL_CAVEAT_EXT */ -#define GLX_TRANSPARENT_TYPE 0x23 -#define GLX_TRANSPARENT_INDEX_VALUE 0x24 -#define GLX_TRANSPARENT_RED_VALUE 0x25 -#define GLX_TRANSPARENT_GREEN_VALUE 0x26 -#define GLX_TRANSPARENT_BLUE_VALUE 0x27 -#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 -#define GLX_DRAWABLE_TYPE 0x8010 -#define GLX_RENDER_TYPE 0x8011 -#define GLX_X_RENDERABLE 0x8012 -#define GLX_FBCONFIG_ID 0x8013 -#define GLX_MAX_PBUFFER_WIDTH 0x8016 -#define GLX_MAX_PBUFFER_HEIGHT 0x8017 -#define GLX_MAX_PBUFFER_PIXELS 0x8018 -#define GLX_VISUAL_ID 0x800B +#define GLX_X_VISUAL_TYPE 0x22 +#define GLX_CONFIG_CAVEAT 0x20 /* Like visual_info VISUAL_CAVEAT_EXT */ +#define GLX_TRANSPARENT_TYPE 0x23 +#define GLX_TRANSPARENT_INDEX_VALUE 0x24 +#define GLX_TRANSPARENT_RED_VALUE 0x25 +#define GLX_TRANSPARENT_GREEN_VALUE 0x26 +#define GLX_TRANSPARENT_BLUE_VALUE 0x27 +#define GLX_TRANSPARENT_ALPHA_VALUE 0x28 +#define GLX_DRAWABLE_TYPE 0x8010 +#define GLX_RENDER_TYPE 0x8011 +#define GLX_X_RENDERABLE 0x8012 +#define GLX_FBCONFIG_ID 0x8013 +#define GLX_MAX_PBUFFER_WIDTH 0x8016 +#define GLX_MAX_PBUFFER_HEIGHT 0x8017 +#define GLX_MAX_PBUFFER_PIXELS 0x8018 +#define GLX_VISUAL_ID 0x800B /* ** Error return values from glXGetConfig. Success is indicated by ** a value of 0. */ -#define GLX_BAD_SCREEN 1 /* screen # is bad */ -#define GLX_BAD_ATTRIBUTE 2 /* attribute to get is bad */ -#define GLX_NO_EXTENSION 3 /* no glx extension on server */ -#define GLX_BAD_VISUAL 4 /* visual # not known by GLX */ -#define GLX_BAD_CONTEXT 5 /* returned only by import_context EXT? */ -#define GLX_BAD_VALUE 6 /* returned only by glXSwapIntervalSGI? */ -#define GLX_BAD_ENUM 7 /* unused? */ +#define GLX_BAD_SCREEN 1 /* screen # is bad */ +#define GLX_BAD_ATTRIBUTE 2 /* attribute to get is bad */ +#define GLX_NO_EXTENSION 3 /* no glx extension on server */ +#define GLX_BAD_VISUAL 4 /* visual # not known by GLX */ +#define GLX_BAD_CONTEXT 5 /* returned only by import_context EXT? */ +#define GLX_BAD_VALUE 6 /* returned only by glXSwapIntervalSGI? */ +#define GLX_BAD_ENUM 7 /* unused? */ /* FBConfig attribute values */ @@ -103,120 +103,120 @@ extern "C" { ** Generic "don't care" value for glX ChooseFBConfig attributes (except ** GLX_LEVEL) */ -#define GLX_DONT_CARE 0xFFFFFFFF +#define GLX_DONT_CARE 0xFFFFFFFF /* GLX_RENDER_TYPE bits */ -#define GLX_RGBA_BIT 0x00000001 -#define GLX_COLOR_INDEX_BIT 0x00000002 +#define GLX_RGBA_BIT 0x00000001 +#define GLX_COLOR_INDEX_BIT 0x00000002 /* GLX_DRAWABLE_TYPE bits */ -#define GLX_WINDOW_BIT 0x00000001 -#define GLX_PIXMAP_BIT 0x00000002 -#define GLX_PBUFFER_BIT 0x00000004 +#define GLX_WINDOW_BIT 0x00000001 +#define GLX_PIXMAP_BIT 0x00000002 +#define GLX_PBUFFER_BIT 0x00000004 /* GLX_CONFIG_CAVEAT attribute values */ -#define GLX_NONE 0x8000 -#define GLX_SLOW_CONFIG 0x8001 -#define GLX_NON_CONFORMANT_CONFIG 0x800D +#define GLX_NONE 0x8000 +#define GLX_SLOW_CONFIG 0x8001 +#define GLX_NON_CONFORMANT_CONFIG 0x800D /* GLX_X_VISUAL_TYPE attribute values */ -#define GLX_TRUE_COLOR 0x8002 -#define GLX_DIRECT_COLOR 0x8003 -#define GLX_PSEUDO_COLOR 0x8004 -#define GLX_STATIC_COLOR 0x8005 -#define GLX_GRAY_SCALE 0x8006 -#define GLX_STATIC_GRAY 0x8007 +#define GLX_TRUE_COLOR 0x8002 +#define GLX_DIRECT_COLOR 0x8003 +#define GLX_PSEUDO_COLOR 0x8004 +#define GLX_STATIC_COLOR 0x8005 +#define GLX_GRAY_SCALE 0x8006 +#define GLX_STATIC_GRAY 0x8007 /* GLX_TRANSPARENT_TYPE attribute values */ -/* #define GLX_NONE 0x8000 */ -#define GLX_TRANSPARENT_RGB 0x8008 -#define GLX_TRANSPARENT_INDEX 0x8009 +/* #define GLX_NONE 0x8000 */ +#define GLX_TRANSPARENT_RGB 0x8008 +#define GLX_TRANSPARENT_INDEX 0x8009 /* glXCreateGLXPbuffer attributes */ -#define GLX_PRESERVED_CONTENTS 0x801B -#define GLX_LARGEST_PBUFFER 0x801C -#define GLX_PBUFFER_HEIGHT 0x8040 /* New for GLX 1.3 */ -#define GLX_PBUFFER_WIDTH 0x8041 /* New for GLX 1.3 */ +#define GLX_PRESERVED_CONTENTS 0x801B +#define GLX_LARGEST_PBUFFER 0x801C +#define GLX_PBUFFER_HEIGHT 0x8040 /* New for GLX 1.3 */ +#define GLX_PBUFFER_WIDTH 0x8041 /* New for GLX 1.3 */ /* glXQueryGLXPBuffer attributes */ -#define GLX_WIDTH 0x801D -#define GLX_HEIGHT 0x801E -#define GLX_EVENT_MASK 0x801F +#define GLX_WIDTH 0x801D +#define GLX_HEIGHT 0x801E +#define GLX_EVENT_MASK 0x801F /* glXCreateNewContext render_type attribute values */ -#define GLX_RGBA_TYPE 0x8014 -#define GLX_COLOR_INDEX_TYPE 0x8015 +#define GLX_RGBA_TYPE 0x8014 +#define GLX_COLOR_INDEX_TYPE 0x8015 /* glXQueryContext attributes */ -/* #define GLX_FBCONFIG_ID 0x8013 */ -/* #define GLX_RENDER_TYPE 0x8011 */ -#define GLX_SCREEN 0x800C +/* #define GLX_FBCONFIG_ID 0x8013 */ +/* #define GLX_RENDER_TYPE 0x8011 */ +#define GLX_SCREEN 0x800C /* glXSelectEvent event mask bits */ -#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 +#define GLX_PBUFFER_CLOBBER_MASK 0x08000000 /* GLXPbufferClobberEvent event_type values */ -#define GLX_DAMAGED 0x8020 -#define GLX_SAVED 0x8021 +#define GLX_DAMAGED 0x8020 +#define GLX_SAVED 0x8021 /* GLXPbufferClobberEvent draw_type values */ -#define GLX_WINDOW 0x8022 -#define GLX_PBUFFER 0x8023 +#define GLX_WINDOW 0x8022 +#define GLX_PBUFFER 0x8023 /* GLXPbufferClobberEvent buffer_mask bits */ -#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 -#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 -#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 -#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 -#define GLX_AUX_BUFFERS_BIT 0x00000010 -#define GLX_DEPTH_BUFFER_BIT 0x00000020 -#define GLX_STENCIL_BUFFER_BIT 0x00000040 -#define GLX_ACCUM_BUFFER_BIT 0x00000080 +#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 +#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 +#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 +#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 +#define GLX_AUX_BUFFERS_BIT 0x00000010 +#define GLX_DEPTH_BUFFER_BIT 0x00000020 +#define GLX_STENCIL_BUFFER_BIT 0x00000040 +#define GLX_ACCUM_BUFFER_BIT 0x00000080 /* ** Extension return values from glXGetConfig. These are also ** accepted as parameter values for glXChooseVisual. */ -#define GLX_X_VISUAL_TYPE_EXT 0x22 /* visual_info extension type */ -#define GLX_TRANSPARENT_TYPE_EXT 0x23 /* visual_info extension */ -#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 /* visual_info extension */ -#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 /* visual_info extension */ -#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 /* visual_info extension */ -#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 /* visual_info extension */ -#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 /* visual_info extension */ +#define GLX_X_VISUAL_TYPE_EXT 0x22 /* visual_info extension type */ +#define GLX_TRANSPARENT_TYPE_EXT 0x23 /* visual_info extension */ +#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24 /* visual_info extension */ +#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25 /* visual_info extension */ +#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26 /* visual_info extension */ +#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27 /* visual_info extension */ +#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28 /* visual_info extension */ /* Property values for visual_type */ -#define GLX_TRUE_COLOR_EXT 0x8002 -#define GLX_DIRECT_COLOR_EXT 0x8003 -#define GLX_PSEUDO_COLOR_EXT 0x8004 -#define GLX_STATIC_COLOR_EXT 0x8005 -#define GLX_GRAY_SCALE_EXT 0x8006 -#define GLX_STATIC_GRAY_EXT 0x8007 +#define GLX_TRUE_COLOR_EXT 0x8002 +#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_PSEUDO_COLOR_EXT 0x8004 +#define GLX_STATIC_COLOR_EXT 0x8005 +#define GLX_GRAY_SCALE_EXT 0x8006 +#define GLX_STATIC_GRAY_EXT 0x8007 /* Property values for transparent pixel */ -#define GLX_NONE_EXT 0x8000 -#define GLX_TRANSPARENT_RGB_EXT 0x8008 -#define GLX_TRANSPARENT_INDEX_EXT 0x8009 +#define GLX_NONE_EXT 0x8000 +#define GLX_TRANSPARENT_RGB_EXT 0x8008 +#define GLX_TRANSPARENT_INDEX_EXT 0x8009 /* Property values for visual_rating */ -#define GLX_VISUAL_CAVEAT_EXT 0x20 /* visual_rating extension type */ -#define GLX_SLOW_VISUAL_EXT 0x8001 -#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +#define GLX_VISUAL_CAVEAT_EXT 0x20 /* visual_rating extension type */ +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D /* ** Names for attributes to glXGetClientString. */ -#define GLX_VENDOR 0x1 -#define GLX_VERSION 0x2 -#define GLX_EXTENSIONS 0x3 +#define GLX_VENDOR 0x1 +#define GLX_VERSION 0x2 +#define GLX_EXTENSIONS 0x3 /* ** Names for attributes to glXQueryContextInfoEXT. */ -#define GLX_SHARE_CONTEXT_EXT 0x800A /* id of share context */ -#define GLX_VISUAL_ID_EXT 0x800B /* id of context's visual */ -#define GLX_SCREEN_EXT 0x800C /* screen number */ +#define GLX_SHARE_CONTEXT_EXT 0x800A /* id of share context */ +#define GLX_VISUAL_ID_EXT 0x800B /* id of context's visual */ +#define GLX_SCREEN_EXT 0x800C /* screen number */ /* * GLX 1.4 and later: diff --git a/RenderSystems/GL3Plus/include/OgreGL3PlusContext.h b/RenderSystems/GL3Plus/include/OgreGL3PlusContext.h index 3050d709e21..eee8eeb4f1a 100644 --- a/RenderSystems/GL3Plus/include/OgreGL3PlusContext.h +++ b/RenderSystems/GL3Plus/include/OgreGL3PlusContext.h @@ -64,10 +64,10 @@ namespace Ogre { */ virtual GL3PlusContext* clone() const = 0; - /** - * Release the render context. - */ - virtual void releaseContext() {} + /** + * Release the render context. + */ + virtual void releaseContext() {} protected: bool initialized; diff --git a/RenderSystems/GL3Plus/include/OgreGL3PlusDepthBuffer.h b/RenderSystems/GL3Plus/include/OgreGL3PlusDepthBuffer.h index 9f06d672e38..f05c5298e01 100644 --- a/RenderSystems/GL3Plus/include/OgreGL3PlusDepthBuffer.h +++ b/RenderSystems/GL3Plus/include/OgreGL3PlusDepthBuffer.h @@ -37,39 +37,39 @@ namespace Ogre class GL3PlusContext; class GL3PlusRenderBuffer; class GL3PlusRenderSystem; - /** - @copydoc DepthBuffer + /** + @copydoc DepthBuffer - OpenGL supports 3 different methods: FBO, pbuffer & Copy. - Each one has it's own limitations. Non-FBO methods are solved using "dummy" DepthBuffers. - That is, a DepthBuffer pointer is attached to the RenderTarget (for the sake of consistency) - but it doesn't actually contain a Depth surface/renderbuffer (mDepthBuffer & mStencilBuffer are - null pointers all the time) Those dummy DepthBuffers are identified thanks to their GL context. - Note that FBOs don't allow sharing with the main window's depth buffer. Therefore even - when FBO is enabled, a dummy DepthBuffer is still used to manage the windows. - */ - class _OgreGL3PlusExport GL3PlusDepthBuffer : public DepthBuffer - { - public: - GL3PlusDepthBuffer( uint16 poolId, GL3PlusRenderSystem *renderSystem, GL3PlusContext *creatorContext, - GL3PlusRenderBuffer *depth, GL3PlusRenderBuffer *stencil, - uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, - bool manual ); - ~GL3PlusDepthBuffer(); + OpenGL supports 3 different methods: FBO, pbuffer & Copy. + Each one has it's own limitations. Non-FBO methods are solved using "dummy" DepthBuffers. + That is, a DepthBuffer pointer is attached to the RenderTarget (for the sake of consistency) + but it doesn't actually contain a Depth surface/renderbuffer (mDepthBuffer & mStencilBuffer are + null pointers all the time) Those dummy DepthBuffers are identified thanks to their GL context. + Note that FBOs don't allow sharing with the main window's depth buffer. Therefore even + when FBO is enabled, a dummy DepthBuffer is still used to manage the windows. + */ + class _OgreGL3PlusExport GL3PlusDepthBuffer : public DepthBuffer + { + public: + GL3PlusDepthBuffer( uint16 poolId, GL3PlusRenderSystem *renderSystem, GL3PlusContext *creatorContext, + GL3PlusRenderBuffer *depth, GL3PlusRenderBuffer *stencil, + uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, + bool manual ); + ~GL3PlusDepthBuffer(); - /// @copydoc DepthBuffer::isCompatible - virtual bool isCompatible( RenderTarget *renderTarget ) const; + /// @copydoc DepthBuffer::isCompatible + virtual bool isCompatible( RenderTarget *renderTarget ) const; - GL3PlusContext* getGLContext() const { return mCreatorContext; } - GL3PlusRenderBuffer* getDepthBuffer() const { return mDepthBuffer; } - GL3PlusRenderBuffer* getStencilBuffer() const { return mStencilBuffer; } + GL3PlusContext* getGLContext() const { return mCreatorContext; } + GL3PlusRenderBuffer* getDepthBuffer() const { return mDepthBuffer; } + GL3PlusRenderBuffer* getStencilBuffer() const { return mStencilBuffer; } - protected: - uint32 mMultiSampleQuality; - GL3PlusContext *mCreatorContext; - GL3PlusRenderBuffer *mDepthBuffer; - GL3PlusRenderBuffer *mStencilBuffer; - GL3PlusRenderSystem *mRenderSystem; - }; + protected: + uint32 mMultiSampleQuality; + GL3PlusContext *mCreatorContext; + GL3PlusRenderBuffer *mDepthBuffer; + GL3PlusRenderBuffer *mStencilBuffer; + GL3PlusRenderSystem *mRenderSystem; + }; } #endif diff --git a/RenderSystems/GL3Plus/include/OgreGL3PlusFBOMultiRenderTarget.h b/RenderSystems/GL3Plus/include/OgreGL3PlusFBOMultiRenderTarget.h index 49025f0d50b..b0720e84d39 100644 --- a/RenderSystems/GL3Plus/include/OgreGL3PlusFBOMultiRenderTarget.h +++ b/RenderSystems/GL3Plus/include/OgreGL3PlusFBOMultiRenderTarget.h @@ -35,27 +35,27 @@ namespace Ogre { class GL3PlusFBOManager; - /** MultiRenderTarget for OpenGL - */ - class _OgreGL3PlusExport GL3PlusFBOMultiRenderTarget : public MultiRenderTarget - { - public: - GL3PlusFBOMultiRenderTarget(GL3PlusFBOManager *manager, const String &name); - ~GL3PlusFBOMultiRenderTarget(); - - virtual void getCustomAttribute( const String& name, void *pData ); - - bool requiresTextureFlipping() const { return true; } - - /// Override so we can attach the depth buffer to the FBO - virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); - virtual void detachDepthBuffer(); - virtual void _detachDepthBuffer(); - private: - virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); - virtual void unbindSurfaceImpl(size_t attachment); - GL3PlusFrameBufferObject fbo; - }; + /** MultiRenderTarget for OpenGL + */ + class _OgreGL3PlusExport GL3PlusFBOMultiRenderTarget : public MultiRenderTarget + { + public: + GL3PlusFBOMultiRenderTarget(GL3PlusFBOManager *manager, const String &name); + ~GL3PlusFBOMultiRenderTarget(); + + virtual void getCustomAttribute( const String& name, void *pData ); + + bool requiresTextureFlipping() const { return true; } + + /// Override so we can attach the depth buffer to the FBO + virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); + virtual void detachDepthBuffer(); + virtual void _detachDepthBuffer(); + private: + virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); + virtual void unbindSurfaceImpl(size_t attachment); + GL3PlusFrameBufferObject fbo; + }; } diff --git a/RenderSystems/GL3Plus/include/OgreGL3PlusFBORenderTexture.h b/RenderSystems/GL3Plus/include/OgreGL3PlusFBORenderTexture.h index 2692ca7e3c1..76e2fa0c051 100644 --- a/RenderSystems/GL3Plus/include/OgreGL3PlusFBORenderTexture.h +++ b/RenderSystems/GL3Plus/include/OgreGL3PlusFBORenderTexture.h @@ -46,7 +46,7 @@ namespace Ogre { virtual void getCustomAttribute(const String& name, void* pData); /// Override needed to deal with multisample buffers - virtual void swapBuffers(); + virtual void swapBuffers(); /// Override so we can attach the depth buffer to the FBO virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); diff --git a/RenderSystems/GL3Plus/include/OgreGL3PlusFrameBufferObject.h b/RenderSystems/GL3Plus/include/OgreGL3PlusFrameBufferObject.h index e3b31ddbc6d..d7a2d8dfaa7 100644 --- a/RenderSystems/GL3Plus/include/OgreGL3PlusFrameBufferObject.h +++ b/RenderSystems/GL3Plus/include/OgreGL3PlusFrameBufferObject.h @@ -56,44 +56,44 @@ namespace Ogre { */ void bind(); - /** Swap buffers - only useful when using multisample buffers. - */ - void swapBuffers(); + /** Swap buffers - only useful when using multisample buffers. + */ + void swapBuffers(); /** This function acts very similar to @see GL3PlusFBORenderTexture::attachDepthBuffer - The difference between D3D & OGL is that D3D setups the DepthBuffer before rendering, - while OGL setups the DepthBuffer per FBO. So the DepthBuffer (RenderBuffer) needs to - be attached for OGL. - */ - void attachDepthBuffer( DepthBuffer *depthBuffer ); - void detachDepthBuffer(); + The difference between D3D & OGL is that D3D setups the DepthBuffer before rendering, + while OGL setups the DepthBuffer per FBO. So the DepthBuffer (RenderBuffer) needs to + be attached for OGL. + */ + void attachDepthBuffer( DepthBuffer *depthBuffer ); + void detachDepthBuffer(); - /// Get the GL id for the FBO - GLuint getGLFBOID() const { return mFB; } - /// Get the GL id for the multisample FBO - GLuint getGLMultisampleFBOID() const { return mMultisampleFB; } + /// Get the GL id for the FBO + GLuint getGLFBOID() const { return mFB; } + /// Get the GL id for the multisample FBO + GLuint getGLMultisampleFBOID() const { return mMultisampleFB; } /// Accessors uint32 getWidth(); uint32 getHeight(); PixelFormat getFormat(); - GLsizei getFSAA(); + GLsizei getFSAA(); GL3PlusFBOManager *getManager() { return mManager; } - const GL3PlusSurfaceDesc &getSurface(size_t attachment) { return mColour[attachment]; } + const GL3PlusSurfaceDesc &getSurface(size_t attachment) { return mColour[attachment]; } private: GL3PlusFBOManager *mManager; - GLsizei mNumSamples; + GLsizei mNumSamples; GLuint mFB; - GLuint mMultisampleFB; - GL3PlusSurfaceDesc mMultisampleColourBuffer; + GLuint mMultisampleFB; + GL3PlusSurfaceDesc mMultisampleColourBuffer; GL3PlusSurfaceDesc mDepth; GL3PlusSurfaceDesc mStencil; // Arbitrary number of texture surfaces GL3PlusSurfaceDesc mColour[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - /** Initialise object (find suitable depth and stencil format). + /** Initialise object (find suitable depth and stencil format). Must be called every time the bindings change. It fails with an exception (ERR_INVALIDPARAMS) if: - Attachment point 0 has no binding diff --git a/RenderSystems/GL3Plus/include/OgreGL3PlusHardwareOcclusionQuery.h b/RenderSystems/GL3Plus/include/OgreGL3PlusHardwareOcclusionQuery.h index c8491e6415e..47e31d3aa21 100644 --- a/RenderSystems/GL3Plus/include/OgreGL3PlusHardwareOcclusionQuery.h +++ b/RenderSystems/GL3Plus/include/OgreGL3PlusHardwareOcclusionQuery.h @@ -68,26 +68,26 @@ class _OgreGL3PlusExport GL3PlusHardwareOcclusionQuery : public HardwareOcclusio // Public methods //-- public: - /** - * Default object constructor - * - */ - GL3PlusHardwareOcclusionQuery(); - /** - * Object destructor - */ - ~GL3PlusHardwareOcclusionQuery(); - - //------------------------------------------------------------------ - // Occlusion query functions (see base class documentation for this) - //-- - void beginOcclusionQuery(); - void endOcclusionQuery(); - bool pullOcclusionQuery(unsigned int* NumOfFragments); - bool isStillOutstanding(void); + /** + * Default object constructor + * + */ + GL3PlusHardwareOcclusionQuery(); + /** + * Object destructor + */ + ~GL3PlusHardwareOcclusionQuery(); + + //------------------------------------------------------------------ + // Occlusion query functions (see base class documentation for this) + //-- + void beginOcclusionQuery(); + void endOcclusionQuery(); + bool pullOcclusionQuery(unsigned int* NumOfFragments); + bool isStillOutstanding(void); private: - GLuint mQueryID; + GLuint mQueryID; }; } diff --git a/RenderSystems/GL3Plus/include/OgreGL3PlusPlugin.h b/RenderSystems/GL3Plus/include/OgreGL3PlusPlugin.h index bd27fb8fc10..d8aababad45 100644 --- a/RenderSystems/GL3Plus/include/OgreGL3PlusPlugin.h +++ b/RenderSystems/GL3Plus/include/OgreGL3PlusPlugin.h @@ -34,30 +34,30 @@ THE SOFTWARE. namespace Ogre { - /** Plugin instance for GL3Plus Manager */ - class GL3PlusPlugin : public Plugin - { - public: - GL3PlusPlugin(); + /** Plugin instance for GL3Plus Manager */ + class GL3PlusPlugin : public Plugin + { + public: + GL3PlusPlugin(); - /// @copydoc Plugin::getName - const String& getName() const; + /// @copydoc Plugin::getName + const String& getName() const; - /// @copydoc Plugin::install - void install(); + /// @copydoc Plugin::install + void install(); - /// @copydoc Plugin::initialise - void initialise(); + /// @copydoc Plugin::initialise + void initialise(); - /// @copydoc Plugin::shutdown - void shutdown(); + /// @copydoc Plugin::shutdown + void shutdown(); - /// @copydoc Plugin::uninstall - void uninstall(); - protected: - GL3PlusRenderSystem* mRenderSystem; - }; + /// @copydoc Plugin::uninstall + void uninstall(); + protected: + GL3PlusRenderSystem* mRenderSystem; + }; } #endif diff --git a/RenderSystems/GL3Plus/include/OgreGL3PlusPrerequisites.h b/RenderSystems/GL3Plus/include/OgreGL3PlusPrerequisites.h index 629f96b49e6..afe7f9bc094 100644 --- a/RenderSystems/GL3Plus/include/OgreGL3PlusPrerequisites.h +++ b/RenderSystems/GL3Plus/include/OgreGL3PlusPrerequisites.h @@ -55,7 +55,7 @@ namespace Ogre { #if !defined( __MINGW32__ ) # define WIN32_LEAN_AND_MEAN # ifndef NOMINMAX -# define NOMINMAX // required to stop windows.h messing up std::min +# define NOMINMAX // required to stop windows.h messing up std::min # endif #endif # define WGL_WGLEXT_PROTOTYPES @@ -85,15 +85,15 @@ namespace Ogre { #endif #if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) && !defined(__MINGW32__) && !defined(OGRE_STATIC_LIB) -# ifdef RenderSystem_GL3Plus_EXPORTS -# define _OgreGL3PlusExport __declspec(dllexport) -# else +# ifdef RenderSystem_GL3Plus_EXPORTS +# define _OgreGL3PlusExport __declspec(dllexport) +# else # if defined( __MINGW32__ ) # define _OgreGL3PlusExport # else -# define _OgreGL3PlusExport __declspec(dllimport) +# define _OgreGL3PlusExport __declspec(dllimport) # endif -# endif +# endif #elif defined ( OGRE_GCC_VISIBILITY ) # define _OgreGL3PlusExport __attribute__ ((visibility("default"))) #else diff --git a/RenderSystems/GL3Plus/include/OgreGL3PlusRenderSystem.h b/RenderSystems/GL3Plus/include/OgreGL3PlusRenderSystem.h index f23bcc34ade..0c1585d2c4d 100644 --- a/RenderSystems/GL3Plus/include/OgreGL3PlusRenderSystem.h +++ b/RenderSystems/GL3Plus/include/OgreGL3PlusRenderSystem.h @@ -290,23 +290,23 @@ namespace Ogre { RenderSystem */ void _setPointSpritesEnabled(bool enabled); - /** See + /** See RenderSystem */ void _setVertexTexture(size_t unit, const TexturePtr &tex); - /** See + /** See RenderSystem */ void _setGeometryTexture(size_t unit, const TexturePtr &tex); - /** See + /** See RenderSystem */ void _setComputeTexture(size_t unit, const TexturePtr &tex); - /** See + /** See RenderSystem */ void _setTesselationHullTexture(size_t unit, const TexturePtr &tex); - /** See + /** See RenderSystem */ void _setTesselationDomainTexture(size_t unit, const TexturePtr &tex); @@ -437,7 +437,7 @@ namespace Ogre { StencilOperation depthFailOp = SOP_KEEP, StencilOperation passOp = SOP_KEEP, bool twoSidedOperation = false, - bool readBackAsTexture = false); + bool readBackAsTexture = false); /** See RenderSystem */ diff --git a/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXContext.h b/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXContext.h index 365abee2f2a..859be22c12c 100644 --- a/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXContext.h +++ b/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXContext.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- This source file is part of OGRE - (Object-oriented Graphics Rendering Engine) + (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2014 Torus Knot Software Ltd @@ -33,30 +33,30 @@ THE SOFTWARE. namespace Ogre { - class _OgrePrivate GLXContext: public GL3PlusContext - { - public: - GLXContext(GLXGLSupport* glsupport, ::GLXFBConfig fbconfig, ::GLXDrawable drawable, ::GLXContext context = 0); - - virtual ~GLXContext(); - - /// @copydoc GL3PlusContext::setCurrent - virtual void setCurrent(); - - /// @copydoc GL3PlusContext::endCurrent - virtual void endCurrent(); - - /// @copydoc GL3PlusContext::clone - GL3PlusContext* clone() const; - - ::GLXDrawable mDrawable; - ::GLXContext mContext; - - private: - ::GLXFBConfig mFBConfig; - GLXGLSupport* mGLSupport; - bool mExternalContext; - }; + class _OgrePrivate GLXContext: public GL3PlusContext + { + public: + GLXContext(GLXGLSupport* glsupport, ::GLXFBConfig fbconfig, ::GLXDrawable drawable, ::GLXContext context = 0); + + virtual ~GLXContext(); + + /// @copydoc GL3PlusContext::setCurrent + virtual void setCurrent(); + + /// @copydoc GL3PlusContext::endCurrent + virtual void endCurrent(); + + /// @copydoc GL3PlusContext::clone + GL3PlusContext* clone() const; + + ::GLXDrawable mDrawable; + ::GLXContext mContext; + + private: + ::GLXFBConfig mFBConfig; + GLXGLSupport* mGLSupport; + bool mExternalContext; + }; } #endif diff --git a/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXUtils.h b/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXUtils.h index 5d8dca076cb..11093dca8dd 100644 --- a/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXUtils.h +++ b/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXUtils.h @@ -35,61 +35,61 @@ THE SOFTWARE. namespace Ogre { - class _OgrePrivate GLXUtils - { - public: - // Portable replacements for some GLX 1.3 function pointers + class _OgrePrivate GLXUtils + { + public: + // Portable replacements for some GLX 1.3 function pointers - static PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig; - static PFNGLXCREATENEWCONTEXTPROC createNewContext; - static PFNGLXGETFBCONFIGATTRIBPROC getFBConfigAttrib; - static PFNGLXGETVISUALFROMFBCONFIGPROC getVisualFromFBConfig; + static PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig; + static PFNGLXCREATENEWCONTEXTPROC createNewContext; + static PFNGLXGETFBCONFIGATTRIBPROC getFBConfigAttrib; + static PFNGLXGETVISUALFROMFBCONFIGPROC getVisualFromFBConfig; - /** - * Get the GLXFBConfig used to create a ::GLXContext - * - * @param display X Display - * @param drawable GLXContext - * @returns GLXFBConfig used to create the context - */ - static GLXFBConfig getFBConfigFromContext (Display *display, ::GLXContext context); + /** + * Get the GLXFBConfig used to create a ::GLXContext + * + * @param display X Display + * @param drawable GLXContext + * @returns GLXFBConfig used to create the context + */ + static GLXFBConfig getFBConfigFromContext (Display *display, ::GLXContext context); - /** - * Get the GLXFBConfig used to create a GLXDrawable. - * Caveat: GLX version 1.3 is needed when the drawable is a GLXPixmap - * - * @param display X Display - * @param drawable GLXDrawable - * @param width Receiver for the drawable width - * @param height Receiver for the drawable height - * @returns GLXFBConfig used to create the drawable - */ - static GLXFBConfig getFBConfigFromDrawable (Display *display, GLXDrawable drawable, - unsigned int *width, unsigned int *height); + /** + * Get the GLXFBConfig used to create a GLXDrawable. + * Caveat: GLX version 1.3 is needed when the drawable is a GLXPixmap + * + * @param display X Display + * @param drawable GLXDrawable + * @param width Receiver for the drawable width + * @param height Receiver for the drawable height + * @returns GLXFBConfig used to create the drawable + */ + static GLXFBConfig getFBConfigFromDrawable (Display *display, GLXDrawable drawable, + unsigned int *width, unsigned int *height); - /** - * Select an FBConfig given a list of required and a list of desired properties - * - * @param display X Display - * @param minAttribs FBConfig attributes that must be provided with minimum values - * @param maxAttribs FBConfig attributes that are preferred with maximum values - * @returns GLXFBConfig with attributes or 0 when unsupported. - */ - static GLXFBConfig selectFBConfig(Display *display, const int *minAttribs, const int *maxAttribs); + /** + * Select an FBConfig given a list of required and a list of desired properties + * + * @param display X Display + * @param minAttribs FBConfig attributes that must be provided with minimum values + * @param maxAttribs FBConfig attributes that are preferred with maximum values + * @returns GLXFBConfig with attributes or 0 when unsupported. + */ + static GLXFBConfig selectFBConfig(Display *display, const int *minAttribs, const int *maxAttribs); - /** - * Loads an icon from an Ogre resource into the X Server. This currently only - * works for 24 and 32 bit displays. The image must be findable by the Ogre - * resource system, and of format PF_A8R8G8B8. - * - * @param display X display - * @param name Name of image to load - * @param pix Receiver for the output pixmap - * @param mask Receiver for the output mask (alpha bitmap) - * @returns true on success - */ - static bool loadIcon(Display *display, const std::string &name, Pixmap *pix, Pixmap *mask); - }; + /** + * Loads an icon from an Ogre resource into the X Server. This currently only + * works for 24 and 32 bit displays. The image must be findable by the Ogre + * resource system, and of format PF_A8R8G8B8. + * + * @param display X display + * @param name Name of image to load + * @param pix Receiver for the output pixmap + * @param mask Receiver for the output mask (alpha bitmap) + * @returns true on success + */ + static bool loadIcon(Display *display, const std::string &name, Pixmap *pix, Pixmap *mask); + }; } diff --git a/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXWindow.h b/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXWindow.h index 5a93580cef0..fa23e3c3613 100644 --- a/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXWindow.h +++ b/RenderSystems/GL3Plus/include/windowing/GLX/OgreGLXWindow.h @@ -36,91 +36,91 @@ THE SOFTWARE. namespace Ogre { - class _OgrePrivate GLXWindow : public RenderWindow - { - public: - GLXWindow(GLXGLSupport* glsupport); - ~GLXWindow(); - - void create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams); - - /** @copydoc see RenderWindow::setFullscreen */ - void setFullscreen (bool fullscreen, uint width, uint height); - - /** @copydoc see RenderWindow::destroy */ - void destroy(void); - - /** @copydoc see RenderWindow::isClosed */ - bool isClosed(void) const; - - /** @copydoc see RenderWindow::isVisible */ - bool isVisible(void) const; - - /** @copydoc see RenderWindow::setVisible */ - void setVisible(bool visible); - - /** @copydoc see RenderWindow::isHidden */ - bool isHidden(void) const { return mHidden; } - - /** @copydoc see RenderWindow::setHidden */ - void setHidden(bool hidden); - - /** @copydoc see RenderWindow::setVSyncEnabled */ - void setVSyncEnabled(bool vsync); - - /** @copydoc see RenderWindow::isVSyncEnabled */ - bool isVSyncEnabled() const; - - /** @copydoc see RenderWindow::setVSyncInterval */ - void setVSyncInterval(unsigned int interval); - - /** @copydoc see RenderWindow::getVSyncInterval */ - unsigned int getVSyncInterval() const; - - /** @copydoc see RenderWindow::reposition */ - void reposition(int left, int top); - - /** @copydoc see RenderWindow::resize */ - void resize(unsigned int width, unsigned int height); - - /** @copydoc see RenderWindow::windowMovedOrResized */ - void windowMovedOrResized(); - - /** @copydoc see RenderWindow::swapBuffers */ - void swapBuffers(); - - /** @copydoc see RenderTarget::copyContentsToMemory */ - void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); - - /** - @remarks - * Get custom attribute; the following attributes are valid: - * WINDOW The X Window target for rendering. - * GLCONTEXT The Ogre GL3PlusContext used for rendering. - * DISPLAY The X Display connection behind that context. - * DISPLAYNAME The X Server name for the connected display. - * ATOM The X Atom used in client delete events. - */ - void getCustomAttribute(const String& name, void* pData); - - bool requiresTextureFlipping() const { return false; } - - private: - bool mClosed; - bool mVisible; - bool mHidden; - bool mIsTopLevel; - bool mIsExternal; - bool mIsExternalGLControl; - bool mVSync; - int mVSyncInterval; - - GLXGLSupport* mGLSupport; - ::Window mWindow; - GLXContext* mContext; - void switchFullScreen(bool fullscreen); - }; + class _OgrePrivate GLXWindow : public RenderWindow + { + public: + GLXWindow(GLXGLSupport* glsupport); + ~GLXWindow(); + + void create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams); + + /** @copydoc see RenderWindow::setFullscreen */ + void setFullscreen (bool fullscreen, uint width, uint height); + + /** @copydoc see RenderWindow::destroy */ + void destroy(void); + + /** @copydoc see RenderWindow::isClosed */ + bool isClosed(void) const; + + /** @copydoc see RenderWindow::isVisible */ + bool isVisible(void) const; + + /** @copydoc see RenderWindow::setVisible */ + void setVisible(bool visible); + + /** @copydoc see RenderWindow::isHidden */ + bool isHidden(void) const { return mHidden; } + + /** @copydoc see RenderWindow::setHidden */ + void setHidden(bool hidden); + + /** @copydoc see RenderWindow::setVSyncEnabled */ + void setVSyncEnabled(bool vsync); + + /** @copydoc see RenderWindow::isVSyncEnabled */ + bool isVSyncEnabled() const; + + /** @copydoc see RenderWindow::setVSyncInterval */ + void setVSyncInterval(unsigned int interval); + + /** @copydoc see RenderWindow::getVSyncInterval */ + unsigned int getVSyncInterval() const; + + /** @copydoc see RenderWindow::reposition */ + void reposition(int left, int top); + + /** @copydoc see RenderWindow::resize */ + void resize(unsigned int width, unsigned int height); + + /** @copydoc see RenderWindow::windowMovedOrResized */ + void windowMovedOrResized(); + + /** @copydoc see RenderWindow::swapBuffers */ + void swapBuffers(); + + /** @copydoc see RenderTarget::copyContentsToMemory */ + void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); + + /** + @remarks + * Get custom attribute; the following attributes are valid: + * WINDOW The X Window target for rendering. + * GLCONTEXT The Ogre GL3PlusContext used for rendering. + * DISPLAY The X Display connection behind that context. + * DISPLAYNAME The X Server name for the connected display. + * ATOM The X Atom used in client delete events. + */ + void getCustomAttribute(const String& name, void* pData); + + bool requiresTextureFlipping() const { return false; } + + private: + bool mClosed; + bool mVisible; + bool mHidden; + bool mIsTopLevel; + bool mIsExternal; + bool mIsExternalGLControl; + bool mVSync; + int mVSyncInterval; + + GLXGLSupport* mGLSupport; + ::Window mWindow; + GLXContext* mContext; + void switchFullScreen(bool fullscreen); + }; } #endif diff --git a/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaContext.h b/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaContext.h index 0675460c627..cc3fea1d10a 100644 --- a/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaContext.h +++ b/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaContext.h @@ -42,30 +42,30 @@ namespace Ogre { /** See GL3PlusContext */ virtual void setCurrent(); - /** + /** * This is called before another context is made current. By default, * nothing is done here. */ virtual void endCurrent(); - /** Create a new context based on the same window/pbuffer as this - context - mostly useful for additional threads. - @note The caller is responsible for deleting the returned context. - */ - virtual GL3PlusContext* clone() const; + /** Create a new context based on the same window/pbuffer as this + context - mostly useful for additional threads. + @note The caller is responsible for deleting the returned context. + */ + virtual GL3PlusContext* clone() const; - /** Grab the NSOpenGLContext if it exists */ - NSOpenGLContext* getContext(); - - /** Grab the NSOpenGLPixelFormat if it exists */ - NSOpenGLPixelFormat* getPixelFormat(); - + /** Grab the NSOpenGLContext if it exists */ + NSOpenGLContext* getContext(); + + /** Grab the NSOpenGLPixelFormat if it exists */ + NSOpenGLPixelFormat* getPixelFormat(); + /* The pixel dimensions of the backbuffer */ GLint mBackingWidth; GLint mBackingHeight; - private: - NSOpenGLContext* mNSGLContext; - NSOpenGLPixelFormat *mNSGLPixelFormat; + private: + NSOpenGLContext* mNSGLContext; + NSOpenGLPixelFormat *mNSGLPixelFormat; }; } diff --git a/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaView.h b/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaView.h index 0993be12aa7..8cc67d8d4af 100644 --- a/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaView.h +++ b/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaView.h @@ -34,7 +34,7 @@ THE SOFTWARE. @interface OgreGL3PlusView : NSView { - Ogre::RenderWindow *window; + Ogre::RenderWindow *window; } - (id)initWithFrame:(NSRect)f; diff --git a/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaWindow.h b/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaWindow.h index 5e04b98665f..c658d99e8a4 100644 --- a/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaWindow.h +++ b/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaWindow.h @@ -53,13 +53,13 @@ namespace Ogre { CVDisplayLinkRef mDisplayLink; NSPoint mWindowOrigin; CocoaWindowDelegate *mWindowDelegate; - CocoaContext* mContext; + CocoaContext* mContext; bool mActive; bool mClosed; bool mHidden; bool mVSync; - bool mHasResized; + bool mHasResized; bool mIsExternal; String mWindowTitle; bool mUseNSView; @@ -69,14 +69,14 @@ namespace Ogre { public: CocoaWindow(); ~CocoaWindow(); - - NSView* ogreView() const { return mView; }; - NSWindow* ogreWindow() const { return mWindow; }; - NSOpenGLContext* nsopenGLContext() const { return mGLContext; }; - void createWithView(OgreGL3PlusView *view); - - void create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams); + + NSView* ogreView() const { return mView; }; + NSWindow* ogreWindow() const { return mWindow; }; + NSOpenGLContext* nsopenGLContext() const { return mGLContext; }; + void createWithView(OgreGL3PlusView *view); + + void create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams); /** Overridden - see RenderWindow */ void destroy(void); /** Overridden - see RenderWindow */ @@ -106,14 +106,14 @@ namespace Ogre { /** Overridden - see RenderWindow */ virtual unsigned int getHeight(void) const; /** Overridden - see RenderWindow */ - void windowMovedOrResized(void); - void windowResized(void); - void windowHasResized(void); - void createNewWindow(unsigned int width, unsigned int height, String title); + void windowMovedOrResized(void); + void windowResized(void); + void windowHasResized(void); + void createNewWindow(unsigned int width, unsigned int height, String title); void createWindowFromExternal(NSView *viewRef); - bool requiresTextureFlipping() const { return false; } - void getCustomAttribute( const String& name, void* pData ); + bool requiresTextureFlipping() const { return false; } + void getCustomAttribute( const String& name, void* pData ); }; } diff --git a/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaWindowDelegate.h b/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaWindowDelegate.h index 549a3b14bd2..595e9729e17 100644 --- a/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaWindowDelegate.h +++ b/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXCocoaWindowDelegate.h @@ -36,7 +36,7 @@ using namespace Ogre; { @private RenderWindow *ogreWindow; - NSWindow *window; + NSWindow *window; } -(id)initWithNSWindow:(NSWindow*)nswin ogreWindow:(RenderWindow*)ogrewin; diff --git a/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXGL3PlusSupport.h b/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXGL3PlusSupport.h index 9287ed6ff8e..0a3f57c121b 100644 --- a/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXGL3PlusSupport.h +++ b/RenderSystems/GL3Plus/include/windowing/OSX/OgreOSXGL3PlusSupport.h @@ -38,51 +38,51 @@ namespace Ogre class OSXGL3PlusSupport : public GL3PlusSupport { public: - OSXGL3PlusSupport(); - ~OSXGL3PlusSupport(); - - /** - * Add any special config values to the system. - * Must have a "Full Screen" value that is a bool and a "Video Mode" value - * that is a string in the form of wxh - */ - void addConfig( void ); - - /** - * Make sure all the extra options are valid - */ - String validateConfig( void ); - - /// @copydoc GL3PlusSupport::createWindow - RenderWindow* createWindow( bool autoCreateWindow, GL3PlusRenderSystem* renderSystem, const String& windowTitle ); - - /// @copydoc RenderSystem::createRenderWindow - virtual RenderWindow* newWindow( const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0 ); - - /** - * Start anything special - */ - void start(); - - /** - * Stop anything special - */ - void stop(); - - /** - * Get the address of a function - */ - void* getProcAddress( const char *name ); - void* getProcAddress( const String& procname ); - - virtual bool supportsPBuffers(); - - // Core Foundation Array callback function for sorting, must be static for the function ptr - static CFComparisonResult _compareModes (const void *val1, const void *val2, void *context); - // Core Fondation Dictionary helper functions, also static for ease of use in above static - static Boolean _getDictionaryBoolean(CFDictionaryRef dict, const void* key); - static long _getDictionaryLong(CFDictionaryRef dict, const void* key); + OSXGL3PlusSupport(); + ~OSXGL3PlusSupport(); + + /** + * Add any special config values to the system. + * Must have a "Full Screen" value that is a bool and a "Video Mode" value + * that is a string in the form of wxh + */ + void addConfig( void ); + + /** + * Make sure all the extra options are valid + */ + String validateConfig( void ); + + /// @copydoc GL3PlusSupport::createWindow + RenderWindow* createWindow( bool autoCreateWindow, GL3PlusRenderSystem* renderSystem, const String& windowTitle ); + + /// @copydoc RenderSystem::createRenderWindow + virtual RenderWindow* newWindow( const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0 ); + + /** + * Start anything special + */ + void start(); + + /** + * Stop anything special + */ + void stop(); + + /** + * Get the address of a function + */ + void* getProcAddress( const char *name ); + void* getProcAddress( const String& procname ); + + virtual bool supportsPBuffers(); + + // Core Foundation Array callback function for sorting, must be static for the function ptr + static CFComparisonResult _compareModes (const void *val1, const void *val2, void *context); + // Core Fondation Dictionary helper functions, also static for ease of use in above static + static Boolean _getDictionaryBoolean(CFDictionaryRef dict, const void* key); + static long _getDictionaryLong(CFDictionaryRef dict, const void* key); }; // class OSXGL3PlusSupport diff --git a/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLGLSupport.h b/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLGLSupport.h index c94a22d3178..b3cd6c90f90 100644 --- a/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLGLSupport.h +++ b/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLGLSupport.h @@ -26,9 +26,9 @@ class _OgrePrivate SDLGLSupport : public GL3PlusSupport virtual RenderWindow* createWindow(bool autoCreateWindow, GL3PlusRenderSystem* renderSystem, const String& windowTitle); - /// @copydoc RenderSystem::createRenderWindow - virtual RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0); + /// @copydoc RenderSystem::createRenderWindow + virtual RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0); /** * Start anything special diff --git a/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLPrerequisites.h b/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLPrerequisites.h index 8f5f8ee47b5..70efb2b19e7 100644 --- a/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLPrerequisites.h +++ b/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLPrerequisites.h @@ -31,9 +31,9 @@ THE SOFTWARE. #include "OgrePlatform.h" #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE -# include +# include #else -# include +# include #endif #include diff --git a/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLWindow.h b/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLWindow.h index 83621275413..1325d631141 100644 --- a/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLWindow.h +++ b/RenderSystems/GL3Plus/include/windowing/SDL/OgreSDLWindow.h @@ -51,8 +51,8 @@ namespace Ogre { SDLWindow(); ~SDLWindow(); - void create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams); + void create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams); /** Overridden - see RenderWindow */ void destroy(void); /** Overridden - see RenderWindow */ diff --git a/RenderSystems/GL3Plus/include/windowing/gtk/OgreGTKWindow.h b/RenderSystems/GL3Plus/include/windowing/gtk/OgreGTKWindow.h index 30ca84bfd11..2bd14465f38 100644 --- a/RenderSystems/GL3Plus/include/windowing/gtk/OgreGTKWindow.h +++ b/RenderSystems/GL3Plus/include/windowing/gtk/OgreGTKWindow.h @@ -66,7 +66,7 @@ class GTKWindow : public RenderWindow, public SigC::Object bool fullScreen, int left, int top, bool depthBuffer, void* miscParam, ...); - void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); + void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); void destroy(void); bool isActive(void) const; bool isClosed(void) const; @@ -77,12 +77,12 @@ class GTKWindow : public RenderWindow, public SigC::Object bool requiresTextureFlipping() const { return false; } - /** - * Get a custom, GTK specific attribute. The specific attributes - * are: - * GTKMMWINDOW The Gtk::Window instance (Rendering window) - * GTKGLMMWIDGET The Gtk::GL::DrawingArea instance (Ogre widget) - */ + /** + * Get a custom, GTK specific attribute. The specific attributes + * are: + * GTKMMWINDOW The Gtk::Window instance (Rendering window) + * GTKGLMMWIDGET The Gtk::GL::DrawingArea instance (Ogre widget) + */ void getCustomAttribute( const String& name, void* pData ); protected: // Signal handlers diff --git a/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Context.h b/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Context.h index 75169abee95..7871b5f7b0d 100644 --- a/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Context.h +++ b/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Context.h @@ -42,14 +42,14 @@ namespace Ogre { /** See GL3PlusContext */ virtual void setCurrent(); - /** See GL3PlusContext */ - virtual void endCurrent(); - /// @copydoc GL3PlusContext::clone - GL3PlusContext* clone() const; + /** See GL3PlusContext */ + virtual void endCurrent(); + /// @copydoc GL3PlusContext::clone + GL3PlusContext* clone() const; - virtual void releaseContext(); + virtual void releaseContext(); - protected: + protected: HDC mHDC; HGLRC mGlrc; }; diff --git a/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32GLSupport.h b/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32GLSupport.h index 75f08be16a6..5870429f4b5 100644 --- a/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32GLSupport.h +++ b/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32GLSupport.h @@ -35,81 +35,81 @@ namespace Ogre { - class _OgreGL3PlusExport Win32GLSupport : public GL3PlusSupport - { - public: + class _OgreGL3PlusExport Win32GLSupport : public GL3PlusSupport + { + public: Win32GLSupport(); - /** - * Add any special config values to the system. - * Must have a "Full Screen" value that is a bool and a "Video Mode" value - * that is a string in the form of wxhxb - */ - void addConfig(); - - void setConfigOption(const String &name, const String &value); - - /** - * Make sure all the extra options are valid - */ - String validateConfig(); - - virtual RenderWindow* createWindow(bool autoCreateWindow, GL3PlusRenderSystem* renderSystem, const String& windowTitle = "OGRE Render Window"); - - /// @copydoc RenderSystem::_createRenderWindow - virtual RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams = 0); - - - /** - * Start anything special - */ - void start(); - /** - * Stop anything special - */ - void stop(); - - /** - * Get the address of a function - */ - void* getProcAddress(const String& procname); - - /** - * Initialise extensions - */ - virtual void initialiseExtensions(); - - - bool selectPixelFormat(HDC hdc, int colourDepth, int multisample, bool hwGamma); - - virtual unsigned int getDisplayMonitorCount() const; - private: - // Allowed video modes - vector::type mDevModes; - Win32Window *mInitialWindow; - vector::type mFSAALevels; - bool mHasPixelFormatARB; + /** + * Add any special config values to the system. + * Must have a "Full Screen" value that is a bool and a "Video Mode" value + * that is a string in the form of wxhxb + */ + void addConfig(); + + void setConfigOption(const String &name, const String &value); + + /** + * Make sure all the extra options are valid + */ + String validateConfig(); + + virtual RenderWindow* createWindow(bool autoCreateWindow, GL3PlusRenderSystem* renderSystem, const String& windowTitle = "OGRE Render Window"); + + /// @copydoc RenderSystem::_createRenderWindow + virtual RenderWindow* newWindow(const String &name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams = 0); + + + /** + * Start anything special + */ + void start(); + /** + * Stop anything special + */ + void stop(); + + /** + * Get the address of a function + */ + void* getProcAddress(const String& procname); + + /** + * Initialise extensions + */ + virtual void initialiseExtensions(); + + + bool selectPixelFormat(HDC hdc, int colourDepth, int multisample, bool hwGamma); + + virtual unsigned int getDisplayMonitorCount() const; + private: + // Allowed video modes + vector::type mDevModes; + Win32Window *mInitialWindow; + vector::type mFSAALevels; + bool mHasPixelFormatARB; bool mHasMultisample; - bool mHasHardwareGamma; - PFNWGLCHOOSEPIXELFORMATARBPROC mWglChoosePixelFormat; - - struct DisplayMonitorInfo - { - HMONITOR hMonitor; - MONITORINFOEX monitorInfoEx; - }; - - typedef vector::type DisplayMonitorInfoList; - typedef DisplayMonitorInfoList::iterator DisplayMonitorInfoIterator; - - DisplayMonitorInfoList mMonitorInfoList; - - void refreshConfig(); - void initialiseWGL(); - static LRESULT CALLBACK dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp); - static BOOL CALLBACK sCreateMonitorsInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, - LPRECT lprcMonitor, LPARAM dwData); - }; + bool mHasHardwareGamma; + PFNWGLCHOOSEPIXELFORMATARBPROC mWglChoosePixelFormat; + + struct DisplayMonitorInfo + { + HMONITOR hMonitor; + MONITORINFOEX monitorInfoEx; + }; + + typedef vector::type DisplayMonitorInfoList; + typedef DisplayMonitorInfoList::iterator DisplayMonitorInfoIterator; + + DisplayMonitorInfoList mMonitorInfoList; + + void refreshConfig(); + void initialiseWGL(); + static LRESULT CALLBACK dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp); + static BOOL CALLBACK sCreateMonitorsInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, + LPRECT lprcMonitor, LPARAM dwData); + }; } diff --git a/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Prerequisites.h b/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Prerequisites.h index 1ab48b9de9a..c131553017e 100644 --- a/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Prerequisites.h +++ b/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Prerequisites.h @@ -40,8 +40,8 @@ namespace Ogre { class Win32Context; - // Useful error method implemented in Win32GLSupport - String translateWGLError(); + // Useful error method implemented in Win32GLSupport + String translateWGLError(); } diff --git a/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Window.h b/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Window.h index 80c203c1241..6eb29462078 100644 --- a/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Window.h +++ b/RenderSystems/GL3Plus/include/windowing/win32/OgreWin32Window.h @@ -39,69 +39,69 @@ namespace Ogre { Win32Window(Win32GLSupport &glsupport); ~Win32Window(); - void create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams); - void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); + void create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams); + void setFullscreen(bool fullScreen, unsigned int width, unsigned int height); void destroy(void); - bool isActive(void) const; + bool isActive(void) const; bool isVisible() const; - bool isHidden() const { return mHidden; } - void setHidden(bool hidden); - void setVSyncEnabled(bool vsync); - bool isVSyncEnabled() const; - void setVSyncInterval(unsigned int interval); - unsigned int getVSyncInterval() const; + bool isHidden() const { return mHidden; } + void setHidden(bool hidden); + void setVSyncEnabled(bool vsync); + bool isVSyncEnabled() const; + void setVSyncInterval(unsigned int interval); + unsigned int getVSyncInterval() const; bool isClosed(void) const; void reposition(int left, int top); void resize(unsigned int width, unsigned int height); void swapBuffers(); - /** Overridden - see RenderTarget. */ - virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); + /** Overridden - see RenderTarget. */ + virtual void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); - bool requiresTextureFlipping() const { return false; } + bool requiresTextureFlipping() const { return false; } - HWND getWindowHandle() const { return mHWnd; } - HDC getHDC() const { return mHDC; } - - // Method for dealing with resize / move & 3d library - virtual void windowMovedOrResized(void); + HWND getWindowHandle() const { return mHWnd; } + HDC getHDC() const { return mHDC; } + + // Method for dealing with resize / move & 3d library + virtual void windowMovedOrResized(void); - void getCustomAttribute( const String& name, void* pData ); + void getCustomAttribute( const String& name, void* pData ); /** Used to set the active state of the render target. */ virtual void setActive( bool state ); - void adjustWindow(unsigned int clientWidth, unsigned int clientHeight, - unsigned int* winWidth, unsigned int* winHeight); + void adjustWindow(unsigned int clientWidth, unsigned int clientHeight, + unsigned int* winWidth, unsigned int* winHeight); - protected: - - /** Update the window rect. */ - void updateWindowRect(); + protected: + + /** Update the window rect. */ + void updateWindowRect(); - /** Return the target window style depending on the fullscreen parameter. */ - DWORD getWindowStyle(bool fullScreen) const { if (fullScreen) return mFullscreenWinStyle; return mWindowedWinStyle; } + /** Return the target window style depending on the fullscreen parameter. */ + DWORD getWindowStyle(bool fullScreen) const { if (fullScreen) return mFullscreenWinStyle; return mWindowedWinStyle; } - protected: - Win32GLSupport &mGLSupport; - HWND mHWnd; // Win32 Window handle - HDC mHDC; - HGLRC mGlrc; + protected: + Win32GLSupport &mGLSupport; + HWND mHWnd; // Win32 Window handle + HDC mHDC; + HGLRC mGlrc; bool mIsExternal; - char* mDeviceName; - bool mIsExternalGLControl; - bool mIsExternalGLContext; + char* mDeviceName; + bool mIsExternalGLControl; + bool mIsExternalGLContext; bool mSizing; - bool mClosed; - bool mHidden; - bool mVSync; - unsigned int mVSyncInterval; + bool mClosed; + bool mHidden; + bool mVSync; + unsigned int mVSyncInterval; int mDisplayFrequency; // fullscreen only, to restore display Win32Context *mContext; - DWORD mWindowedWinStyle; // Windowed mode window style flags. - DWORD mFullscreenWinStyle; // Fullscreen mode window style flags. + DWORD mWindowedWinStyle; // Windowed mode window style flags. + DWORD mFullscreenWinStyle; // Fullscreen mode window style flags. }; } diff --git a/RenderSystems/GL3Plus/src/OgreGL3PlusDepthBuffer.cpp b/RenderSystems/GL3Plus/src/OgreGL3PlusDepthBuffer.cpp index fa3a40c426a..4510fe9d156 100644 --- a/RenderSystems/GL3Plus/src/OgreGL3PlusDepthBuffer.cpp +++ b/RenderSystems/GL3Plus/src/OgreGL3PlusDepthBuffer.cpp @@ -102,7 +102,7 @@ namespace Ogre if( !fbo ) { - GL3PlusContext *windowContext = 0; + GL3PlusContext *windowContext = 0; renderTarget->getCustomAttribute( GL3PlusRenderTexture::CustomAttributeString_GLCONTEXT, &windowContext ); //Non-FBO targets and FBO depth surfaces don't play along, only dummies which match the same diff --git a/RenderSystems/GL3Plus/src/OgreGL3PlusFrameBufferObject.cpp b/RenderSystems/GL3Plus/src/OgreGL3PlusFrameBufferObject.cpp index dbf0a79c6a6..f87a945b75c 100644 --- a/RenderSystems/GL3Plus/src/OgreGL3PlusFrameBufferObject.cpp +++ b/RenderSystems/GL3Plus/src/OgreGL3PlusFrameBufferObject.cpp @@ -49,15 +49,15 @@ namespace Ogre { OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0)); mNumSamples = std::min(mNumSamples, (GLsizei)maxSamples); - // Will we need a second FBO to do multisampling? - if (mNumSamples) - { - OGRE_CHECK_GL_ERROR(glGenFramebuffers(1, &mMultisampleFB)); - } - else - { - mMultisampleFB = 0; - } + // Will we need a second FBO to do multisampling? + if (mNumSamples) + { + OGRE_CHECK_GL_ERROR(glGenFramebuffers(1, &mMultisampleFB)); + } + else + { + mMultisampleFB = 0; + } // Initialise state mDepth.buffer=0; @@ -72,38 +72,38 @@ namespace Ogre { { mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); - mManager->releaseRenderBuffer(mMultisampleColourBuffer); + mManager->releaseRenderBuffer(mMultisampleColourBuffer); // Delete framebuffer object OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &mFB)); - if (mMultisampleFB) - OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &mMultisampleFB)); + if (mMultisampleFB) + OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &mMultisampleFB)); } void GL3PlusFrameBufferObject::bindSurface(size_t attachment, const GL3PlusSurfaceDesc &target) { assert(attachment < OGRE_MAX_MULTIPLE_RENDER_TARGETS); mColour[attachment] = target; - // Re-initialise - if(mColour[0].buffer) - initialise(); + // Re-initialise + if(mColour[0].buffer) + initialise(); } void GL3PlusFrameBufferObject::unbindSurface(size_t attachment) { assert(attachment < OGRE_MAX_MULTIPLE_RENDER_TARGETS); mColour[attachment].buffer = 0; - // Re-initialise if buffer 0 still bound - if(mColour[0].buffer) - initialise(); + // Re-initialise if buffer 0 still bound + if(mColour[0].buffer) + initialise(); } void GL3PlusFrameBufferObject::initialise() { - // Release depth and stencil, if they were bound + // Release depth and stencil, if they were bound mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); - mManager->releaseRenderBuffer(mMultisampleColourBuffer); + mManager->releaseRenderBuffer(mMultisampleColourBuffer); // First buffer must be bound if(!mColour[0].buffer) { @@ -112,10 +112,10 @@ namespace Ogre { "GL3PlusFrameBufferObject::initialise"); } - // If we're doing multisampling, then we need another FBO which contains a - // renderbuffer which is set up to multisample, and we'll blit it to the final - // FBO afterwards to perform the multisample resolve. In that case, the - // mMultisampleFB is bound during rendering and is the one with a depth/stencil + // If we're doing multisampling, then we need another FBO which contains a + // renderbuffer which is set up to multisample, and we'll blit it to the final + // FBO afterwards to perform the multisample resolve. In that case, the + // mMultisampleFB is bound during rendering and is the one with a depth/stencil // Store basic stats uint32 width = mColour[0].buffer->getWidth(); @@ -123,8 +123,8 @@ namespace Ogre { GLuint format = mColour[0].buffer->getGLFormat(); ushort maxSupportedMRTs = Root::getSingleton().getRenderSystem()->getCapabilities()->getNumMultiRenderTargets(); - // Bind simple buffer to add colour attachments - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mFB)); + // Bind simple buffer to add colour attachments + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mFB)); // Bind all attachment points to frame buffer for(unsigned int x = 0; x < maxSupportedMRTs; ++x) @@ -159,63 +159,63 @@ namespace Ogre { } } - // Now deal with depth / stencil - if (mMultisampleFB) - { - // Bind multisample buffer - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB)); + // Now deal with depth / stencil + if (mMultisampleFB) + { + // Bind multisample buffer + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB)); - // Create AA render buffer (colour) - // note, this can be shared too because we blit it to the final FBO - // right after the render is finished - mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); + // Create AA render buffer (colour) + // note, this can be shared too because we blit it to the final FBO + // right after the render is finished + mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); - // Attach it, because we won't be attaching below and non-multisample has - // actually been attached to other FBO - mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0, - mMultisampleColourBuffer.zoffset); + // Attach it, because we won't be attaching below and non-multisample has + // actually been attached to other FBO + mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0, + mMultisampleColourBuffer.zoffset); - // depth & stencil will be dealt with below - } + // depth & stencil will be dealt with below + } // Depth buffer is not handled here anymore. - // See GL3PlusFrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() + // See GL3PlusFrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() - // Do glDrawBuffer calls + // Do glDrawBuffer calls GLenum bufs[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - GLsizei n=0; - for(unsigned int x=0; xgetWidth(); - uint32 height = mColour[0].buffer->getHeight(); - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mMultisampleFB)); - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFB)); - OGRE_CHECK_GL_ERROR(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST)); - // Unbind - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, oldfb)); - } - } - - void GL3PlusFrameBufferObject::attachDepthBuffer( DepthBuffer *depthBuffer ) - { - GL3PlusDepthBuffer *glDepthBuffer = static_cast(depthBuffer); - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB ? mMultisampleFB : mFB )); - - if( glDepthBuffer ) - { - GL3PlusRenderBuffer *depthBuf = glDepthBuffer->getDepthBuffer(); - GL3PlusRenderBuffer *stencilBuf = glDepthBuffer->getStencilBuffer(); + // Blit from multisample buffer to final buffer, triggers resolve + uint32 width = mColour[0].buffer->getWidth(); + uint32 height = mColour[0].buffer->getHeight(); + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mMultisampleFB)); + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFB)); + OGRE_CHECK_GL_ERROR(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST)); + // Unbind + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, oldfb)); + } + } + + void GL3PlusFrameBufferObject::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + GL3PlusDepthBuffer *glDepthBuffer = static_cast(depthBuffer); + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB ? mMultisampleFB : mFB )); + + if( glDepthBuffer ) + { + GL3PlusRenderBuffer *depthBuf = glDepthBuffer->getDepthBuffer(); + GL3PlusRenderBuffer *stencilBuf = glDepthBuffer->getStencilBuffer(); // Attach depth buffer, if it has one. if( depthBuf ) depthBuf->bindToFramebuffer( GL_DEPTH_ATTACHMENT, 0 ); // Attach stencil buffer, if it has one. if( stencilBuf ) - stencilBuf->bindToFramebuffer( GL_STENCIL_ATTACHMENT, 0 ); - } - else - { - OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + stencilBuf->bindToFramebuffer( GL_STENCIL_ATTACHMENT, 0 ); + } + else + { + OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0)); - OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0)); - } - } - - void GL3PlusFrameBufferObject::detachDepthBuffer() - { - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB ? mMultisampleFB : mFB )); - OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0 )); - OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + } + } + + void GL3PlusFrameBufferObject::detachDepthBuffer() + { + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB ? mMultisampleFB : mFB )); + OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0 )); + OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0 )); - } + } uint32 GL3PlusFrameBufferObject::getWidth() { @@ -315,7 +315,7 @@ namespace Ogre { assert(mColour[0].buffer); return mColour[0].buffer->getFormat(); } - GLsizei GL3PlusFrameBufferObject::getFSAA() + GLsizei GL3PlusFrameBufferObject::getFSAA() { return mNumSamples; } diff --git a/RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp b/RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp index 29e4f350d69..99cff867070 100644 --- a/RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp +++ b/RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp @@ -977,30 +977,30 @@ namespace Ogre { activateGLTextureUnit(0); } - void GL3PlusRenderSystem::_setVertexTexture( size_t unit, const TexturePtr &tex ) - { - _setTexture(unit, true, tex); - } - - void GL3PlusRenderSystem::_setGeometryTexture( size_t unit, const TexturePtr &tex ) - { - _setTexture(unit, true, tex); - } - - void GL3PlusRenderSystem::_setComputeTexture( size_t unit, const TexturePtr &tex ) - { - _setTexture(unit, true, tex); - } - - void GL3PlusRenderSystem::_setTesselationHullTexture( size_t unit, const TexturePtr &tex ) - { - _setTexture(unit, true, tex); - } - - void GL3PlusRenderSystem::_setTesselationDomainTexture( size_t unit, const TexturePtr &tex ) - { - _setTexture(unit, true, tex); - } + void GL3PlusRenderSystem::_setVertexTexture( size_t unit, const TexturePtr &tex ) + { + _setTexture(unit, true, tex); + } + + void GL3PlusRenderSystem::_setGeometryTexture( size_t unit, const TexturePtr &tex ) + { + _setTexture(unit, true, tex); + } + + void GL3PlusRenderSystem::_setComputeTexture( size_t unit, const TexturePtr &tex ) + { + _setTexture(unit, true, tex); + } + + void GL3PlusRenderSystem::_setTesselationHullTexture( size_t unit, const TexturePtr &tex ) + { + _setTexture(unit, true, tex); + } + + void GL3PlusRenderSystem::_setTesselationDomainTexture( size_t unit, const TexturePtr &tex ) + { + _setTexture(unit, true, tex); + } void GL3PlusRenderSystem::_setTextureCoordSet(size_t stage, size_t index) { @@ -1579,7 +1579,7 @@ namespace Ogre { StencilOperation depthFailOp, StencilOperation passOp, bool twoSidedOperation, - bool readBackAsTexture) + bool readBackAsTexture) { bool flip; mStencilWriteMask = writeMask; diff --git a/RenderSystems/GL3Plus/src/gl3w.cpp b/RenderSystems/GL3Plus/src/gl3w.cpp index 11f59cda21c..984e2a1bb91 100644 --- a/RenderSystems/GL3Plus/src/gl3w.cpp +++ b/RenderSystems/GL3Plus/src/gl3w.cpp @@ -8,22 +8,22 @@ static HMODULE libgl; static void open_libgl(void) { - libgl = LoadLibraryA("opengl32.dll"); + libgl = LoadLibraryA("opengl32.dll"); } static void close_libgl(void) { - FreeLibrary(libgl); + FreeLibrary(libgl); } static void *get_proc(const char *proc) { - void *res; + void *res; - res = wglGetProcAddress(proc); - if (!res) - res = GetProcAddress(libgl, proc); - return res; + res = wglGetProcAddress(proc); + if (!res) + res = GetProcAddress(libgl, proc); + return res; } #elif defined(__APPLE__) || defined(__APPLE_CC__) #include @@ -33,29 +33,29 @@ CFURLRef bundleURL; static void open_libgl(void) { - bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, - CFSTR("/System/Library/Frameworks/OpenGL.framework"), - kCFURLPOSIXPathStyle, true); + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, + CFSTR("/System/Library/Frameworks/OpenGL.framework"), + kCFURLPOSIXPathStyle, true); - bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); - assert(bundle != NULL); + bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); + assert(bundle != NULL); } static void close_libgl(void) { - CFRelease(bundle); - CFRelease(bundleURL); + CFRelease(bundle); + CFRelease(bundleURL); } static void *get_proc(const char *proc) { - void *res; + void *res; - CFStringRef procname = CFStringCreateWithCString(kCFAllocatorDefault, proc, - kCFStringEncodingASCII); - res = CFBundleGetFunctionPointerForName(bundle, procname); - CFRelease(procname); - return res; + CFStringRef procname = CFStringCreateWithCString(kCFAllocatorDefault, proc, + kCFStringEncodingASCII); + res = CFBundleGetFunctionPointerForName(bundle, procname); + CFRelease(procname); + return res; } #else #include @@ -65,64 +65,64 @@ static void *libgl; static void open_libgl(void) { - libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); + libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); } static void close_libgl(void) { - dlclose(libgl); + dlclose(libgl); } static void *get_proc(const char *proc) { - void *res; + void *res; - res = (void*)glXGetProcAddress((const GLubyte *) proc); - if (!res) - res = dlsym(libgl, proc); - return res; + res = (void*)glXGetProcAddress((const GLubyte *) proc); + if (!res) + res = dlsym(libgl, proc); + return res; } #endif static struct { - int major, minor; + int major, minor; } version; static int parse_version(void) { - if (!glGetIntegerv) - return -1; + if (!glGetIntegerv) + return -1; - glGetIntegerv(GL_MAJOR_VERSION, &version.major); - glGetIntegerv(GL_MINOR_VERSION, &version.minor); + glGetIntegerv(GL_MAJOR_VERSION, &version.major); + glGetIntegerv(GL_MINOR_VERSION, &version.minor); - if (version.major < 3) - return -1; - return 0; + if (version.major < 3) + return -1; + return 0; } static void load_procs(void); int gl3wInit(void) { - open_libgl(); - load_procs(); - close_libgl(); - return parse_version(); + open_libgl(); + load_procs(); + close_libgl(); + return parse_version(); } int gl3wIsSupported(int major, int minor) { - if (major < 3) - return 0; - if (version.major == major) - return version.minor >= minor; - return version.major >= major; + if (major < 3) + return 0; + if (version.major == major) + return version.minor >= minor; + return version.major >= major; } void *gl3wGetProcAddress(const char *proc) { - return get_proc(proc); + return get_proc(proc); } PFNGLCULLFACEPROC gl3wCullFace; @@ -732,608 +732,608 @@ PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC gl3wTextureStorage3DMultisampleEXT; static void load_procs(void) { - gl3wCullFace = (PFNGLCULLFACEPROC) get_proc("glCullFace"); - gl3wFrontFace = (PFNGLFRONTFACEPROC) get_proc("glFrontFace"); - gl3wHint = (PFNGLHINTPROC) get_proc("glHint"); - gl3wLineWidth = (PFNGLLINEWIDTHPROC) get_proc("glLineWidth"); - gl3wPointSize = (PFNGLPOINTSIZEPROC) get_proc("glPointSize"); - gl3wPolygonMode = (PFNGLPOLYGONMODEPROC) get_proc("glPolygonMode"); - gl3wScissor = (PFNGLSCISSORPROC) get_proc("glScissor"); - gl3wTexParameterf = (PFNGLTEXPARAMETERFPROC) get_proc("glTexParameterf"); - gl3wTexParameterfv = (PFNGLTEXPARAMETERFVPROC) get_proc("glTexParameterfv"); - gl3wTexParameteri = (PFNGLTEXPARAMETERIPROC) get_proc("glTexParameteri"); - gl3wTexParameteriv = (PFNGLTEXPARAMETERIVPROC) get_proc("glTexParameteriv"); - gl3wTexImage1D = (PFNGLTEXIMAGE1DPROC) get_proc("glTexImage1D"); - gl3wTexImage2D = (PFNGLTEXIMAGE2DPROC) get_proc("glTexImage2D"); - gl3wDrawBuffer = (PFNGLDRAWBUFFERPROC) get_proc("glDrawBuffer"); - gl3wClear = (PFNGLCLEARPROC) get_proc("glClear"); - gl3wClearColor = (PFNGLCLEARCOLORPROC) get_proc("glClearColor"); - gl3wClearStencil = (PFNGLCLEARSTENCILPROC) get_proc("glClearStencil"); - gl3wClearDepth = (PFNGLCLEARDEPTHPROC) get_proc("glClearDepth"); - gl3wStencilMask = (PFNGLSTENCILMASKPROC) get_proc("glStencilMask"); - gl3wColorMask = (PFNGLCOLORMASKPROC) get_proc("glColorMask"); - gl3wDepthMask = (PFNGLDEPTHMASKPROC) get_proc("glDepthMask"); - gl3wDisable = (PFNGLDISABLEPROC) get_proc("glDisable"); - gl3wEnable = (PFNGLENABLEPROC) get_proc("glEnable"); - gl3wFinish = (PFNGLFINISHPROC) get_proc("glFinish"); - gl3wFlush = (PFNGLFLUSHPROC) get_proc("glFlush"); - gl3wBlendFunc = (PFNGLBLENDFUNCPROC) get_proc("glBlendFunc"); - gl3wLogicOp = (PFNGLLOGICOPPROC) get_proc("glLogicOp"); - gl3wStencilFunc = (PFNGLSTENCILFUNCPROC) get_proc("glStencilFunc"); - gl3wStencilOp = (PFNGLSTENCILOPPROC) get_proc("glStencilOp"); - gl3wDepthFunc = (PFNGLDEPTHFUNCPROC) get_proc("glDepthFunc"); - gl3wPixelStoref = (PFNGLPIXELSTOREFPROC) get_proc("glPixelStoref"); - gl3wPixelStorei = (PFNGLPIXELSTOREIPROC) get_proc("glPixelStorei"); - gl3wReadBuffer = (PFNGLREADBUFFERPROC) get_proc("glReadBuffer"); - gl3wReadPixels = (PFNGLREADPIXELSPROC) get_proc("glReadPixels"); - gl3wGetBooleanv = (PFNGLGETBOOLEANVPROC) get_proc("glGetBooleanv"); - gl3wGetDoublev = (PFNGLGETDOUBLEVPROC) get_proc("glGetDoublev"); - gl3wGetError = (PFNGLGETERRORPROC) get_proc("glGetError"); - gl3wGetFloatv = (PFNGLGETFLOATVPROC) get_proc("glGetFloatv"); - gl3wGetIntegerv = (PFNGLGETINTEGERVPROC) get_proc("glGetIntegerv"); - gl3wGetString = (PFNGLGETSTRINGPROC) get_proc("glGetString"); - gl3wGetTexImage = (PFNGLGETTEXIMAGEPROC) get_proc("glGetTexImage"); - gl3wGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) get_proc("glGetTexParameterfv"); - gl3wGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) get_proc("glGetTexParameteriv"); - gl3wGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) get_proc("glGetTexLevelParameterfv"); - gl3wGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) get_proc("glGetTexLevelParameteriv"); - gl3wIsEnabled = (PFNGLISENABLEDPROC) get_proc("glIsEnabled"); - gl3wDepthRange = (PFNGLDEPTHRANGEPROC) get_proc("glDepthRange"); - gl3wViewport = (PFNGLVIEWPORTPROC) get_proc("glViewport"); - gl3wDrawArrays = (PFNGLDRAWARRAYSPROC) get_proc("glDrawArrays"); - gl3wDrawElements = (PFNGLDRAWELEMENTSPROC) get_proc("glDrawElements"); - gl3wGetPointerv = (PFNGLGETPOINTERVPROC) get_proc("glGetPointerv"); - gl3wPolygonOffset = (PFNGLPOLYGONOFFSETPROC) get_proc("glPolygonOffset"); - gl3wCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) get_proc("glCopyTexImage1D"); - gl3wCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) get_proc("glCopyTexImage2D"); - gl3wCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) get_proc("glCopyTexSubImage1D"); - gl3wCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) get_proc("glCopyTexSubImage2D"); - gl3wTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) get_proc("glTexSubImage1D"); - gl3wTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) get_proc("glTexSubImage2D"); - gl3wBindTexture = (PFNGLBINDTEXTUREPROC) get_proc("glBindTexture"); - gl3wDeleteTextures = (PFNGLDELETETEXTURESPROC) get_proc("glDeleteTextures"); - gl3wGenTextures = (PFNGLGENTEXTURESPROC) get_proc("glGenTextures"); - gl3wIsTexture = (PFNGLISTEXTUREPROC) get_proc("glIsTexture"); - gl3wBlendColor = (PFNGLBLENDCOLORPROC) get_proc("glBlendColor"); - gl3wBlendEquation = (PFNGLBLENDEQUATIONPROC) get_proc("glBlendEquation"); - gl3wDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) get_proc("glDrawRangeElements"); - gl3wTexImage3D = (PFNGLTEXIMAGE3DPROC) get_proc("glTexImage3D"); - gl3wTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) get_proc("glTexSubImage3D"); - gl3wCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) get_proc("glCopyTexSubImage3D"); - gl3wActiveTexture = (PFNGLACTIVETEXTUREPROC) get_proc("glActiveTexture"); - gl3wSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) get_proc("glSampleCoverage"); - gl3wCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) get_proc("glCompressedTexImage3D"); - gl3wCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) get_proc("glCompressedTexImage2D"); - gl3wCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) get_proc("glCompressedTexImage1D"); - gl3wCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) get_proc("glCompressedTexSubImage3D"); - gl3wCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) get_proc("glCompressedTexSubImage2D"); - gl3wCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) get_proc("glCompressedTexSubImage1D"); - gl3wGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) get_proc("glGetCompressedTexImage"); - gl3wBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) get_proc("glBlendFuncSeparate"); - gl3wMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) get_proc("glMultiDrawArrays"); - gl3wMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) get_proc("glMultiDrawElements"); - gl3wPointParameterf = (PFNGLPOINTPARAMETERFPROC) get_proc("glPointParameterf"); - gl3wPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) get_proc("glPointParameterfv"); - gl3wPointParameteri = (PFNGLPOINTPARAMETERIPROC) get_proc("glPointParameteri"); - gl3wPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) get_proc("glPointParameteriv"); - gl3wGenQueries = (PFNGLGENQUERIESPROC) get_proc("glGenQueries"); - gl3wDeleteQueries = (PFNGLDELETEQUERIESPROC) get_proc("glDeleteQueries"); - gl3wIsQuery = (PFNGLISQUERYPROC) get_proc("glIsQuery"); - gl3wBeginQuery = (PFNGLBEGINQUERYPROC) get_proc("glBeginQuery"); - gl3wEndQuery = (PFNGLENDQUERYPROC) get_proc("glEndQuery"); - gl3wGetQueryiv = (PFNGLGETQUERYIVPROC) get_proc("glGetQueryiv"); - gl3wGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) get_proc("glGetQueryObjectiv"); - gl3wGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) get_proc("glGetQueryObjectuiv"); - gl3wBindBuffer = (PFNGLBINDBUFFERPROC) get_proc("glBindBuffer"); - gl3wDeleteBuffers = (PFNGLDELETEBUFFERSPROC) get_proc("glDeleteBuffers"); - gl3wGenBuffers = (PFNGLGENBUFFERSPROC) get_proc("glGenBuffers"); - gl3wIsBuffer = (PFNGLISBUFFERPROC) get_proc("glIsBuffer"); - gl3wBufferData = (PFNGLBUFFERDATAPROC) get_proc("glBufferData"); - gl3wBufferSubData = (PFNGLBUFFERSUBDATAPROC) get_proc("glBufferSubData"); - gl3wGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) get_proc("glGetBufferSubData"); - gl3wMapBuffer = (PFNGLMAPBUFFERPROC) get_proc("glMapBuffer"); - gl3wUnmapBuffer = (PFNGLUNMAPBUFFERPROC) get_proc("glUnmapBuffer"); - gl3wGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) get_proc("glGetBufferParameteriv"); - gl3wGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) get_proc("glGetBufferPointerv"); - gl3wBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) get_proc("glBlendEquationSeparate"); - gl3wDrawBuffers = (PFNGLDRAWBUFFERSPROC) get_proc("glDrawBuffers"); - gl3wStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) get_proc("glStencilOpSeparate"); - gl3wStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) get_proc("glStencilFuncSeparate"); - gl3wStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) get_proc("glStencilMaskSeparate"); - gl3wAttachShader = (PFNGLATTACHSHADERPROC) get_proc("glAttachShader"); - gl3wBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) get_proc("glBindAttribLocation"); - gl3wCompileShader = (PFNGLCOMPILESHADERPROC) get_proc("glCompileShader"); - gl3wCreateProgram = (PFNGLCREATEPROGRAMPROC) get_proc("glCreateProgram"); - gl3wCreateShader = (PFNGLCREATESHADERPROC) get_proc("glCreateShader"); - gl3wDeleteProgram = (PFNGLDELETEPROGRAMPROC) get_proc("glDeleteProgram"); - gl3wDeleteShader = (PFNGLDELETESHADERPROC) get_proc("glDeleteShader"); - gl3wDetachShader = (PFNGLDETACHSHADERPROC) get_proc("glDetachShader"); - gl3wDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) get_proc("glDisableVertexAttribArray"); - gl3wEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) get_proc("glEnableVertexAttribArray"); - gl3wGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) get_proc("glGetActiveAttrib"); - gl3wGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) get_proc("glGetActiveUniform"); - gl3wGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) get_proc("glGetAttachedShaders"); - gl3wGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) get_proc("glGetAttribLocation"); - gl3wGetProgramiv = (PFNGLGETPROGRAMIVPROC) get_proc("glGetProgramiv"); - gl3wGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) get_proc("glGetProgramInfoLog"); - gl3wGetShaderiv = (PFNGLGETSHADERIVPROC) get_proc("glGetShaderiv"); - gl3wGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) get_proc("glGetShaderInfoLog"); - gl3wGetShaderSource = (PFNGLGETSHADERSOURCEPROC) get_proc("glGetShaderSource"); - gl3wGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) get_proc("glGetUniformLocation"); - gl3wGetUniformfv = (PFNGLGETUNIFORMFVPROC) get_proc("glGetUniformfv"); - gl3wGetUniformiv = (PFNGLGETUNIFORMIVPROC) get_proc("glGetUniformiv"); - gl3wGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) get_proc("glGetVertexAttribdv"); - gl3wGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) get_proc("glGetVertexAttribfv"); - gl3wGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) get_proc("glGetVertexAttribiv"); - gl3wGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) get_proc("glGetVertexAttribPointerv"); - gl3wIsProgram = (PFNGLISPROGRAMPROC) get_proc("glIsProgram"); - gl3wIsShader = (PFNGLISSHADERPROC) get_proc("glIsShader"); - gl3wLinkProgram = (PFNGLLINKPROGRAMPROC) get_proc("glLinkProgram"); - gl3wShaderSource = (PFNGLSHADERSOURCEPROC) get_proc("glShaderSource"); - gl3wUseProgram = (PFNGLUSEPROGRAMPROC) get_proc("glUseProgram"); - gl3wUniform1f = (PFNGLUNIFORM1FPROC) get_proc("glUniform1f"); - gl3wUniform2f = (PFNGLUNIFORM2FPROC) get_proc("glUniform2f"); - gl3wUniform3f = (PFNGLUNIFORM3FPROC) get_proc("glUniform3f"); - gl3wUniform4f = (PFNGLUNIFORM4FPROC) get_proc("glUniform4f"); - gl3wUniform1i = (PFNGLUNIFORM1IPROC) get_proc("glUniform1i"); - gl3wUniform2i = (PFNGLUNIFORM2IPROC) get_proc("glUniform2i"); - gl3wUniform3i = (PFNGLUNIFORM3IPROC) get_proc("glUniform3i"); - gl3wUniform4i = (PFNGLUNIFORM4IPROC) get_proc("glUniform4i"); - gl3wUniform1fv = (PFNGLUNIFORM1FVPROC) get_proc("glUniform1fv"); - gl3wUniform2fv = (PFNGLUNIFORM2FVPROC) get_proc("glUniform2fv"); - gl3wUniform3fv = (PFNGLUNIFORM3FVPROC) get_proc("glUniform3fv"); - gl3wUniform4fv = (PFNGLUNIFORM4FVPROC) get_proc("glUniform4fv"); - gl3wUniform1iv = (PFNGLUNIFORM1IVPROC) get_proc("glUniform1iv"); - gl3wUniform2iv = (PFNGLUNIFORM2IVPROC) get_proc("glUniform2iv"); - gl3wUniform3iv = (PFNGLUNIFORM3IVPROC) get_proc("glUniform3iv"); - gl3wUniform4iv = (PFNGLUNIFORM4IVPROC) get_proc("glUniform4iv"); - gl3wUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) get_proc("glUniformMatrix2fv"); - gl3wUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) get_proc("glUniformMatrix3fv"); - gl3wUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) get_proc("glUniformMatrix4fv"); - gl3wValidateProgram = (PFNGLVALIDATEPROGRAMPROC) get_proc("glValidateProgram"); - gl3wVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) get_proc("glVertexAttrib1d"); - gl3wVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) get_proc("glVertexAttrib1dv"); - gl3wVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) get_proc("glVertexAttrib1f"); - gl3wVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) get_proc("glVertexAttrib1fv"); - gl3wVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) get_proc("glVertexAttrib1s"); - gl3wVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) get_proc("glVertexAttrib1sv"); - gl3wVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) get_proc("glVertexAttrib2d"); - gl3wVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) get_proc("glVertexAttrib2dv"); - gl3wVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) get_proc("glVertexAttrib2f"); - gl3wVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) get_proc("glVertexAttrib2fv"); - gl3wVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) get_proc("glVertexAttrib2s"); - gl3wVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) get_proc("glVertexAttrib2sv"); - gl3wVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) get_proc("glVertexAttrib3d"); - gl3wVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) get_proc("glVertexAttrib3dv"); - gl3wVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) get_proc("glVertexAttrib3f"); - gl3wVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) get_proc("glVertexAttrib3fv"); - gl3wVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) get_proc("glVertexAttrib3s"); - gl3wVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) get_proc("glVertexAttrib3sv"); - gl3wVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) get_proc("glVertexAttrib4Nbv"); - gl3wVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) get_proc("glVertexAttrib4Niv"); - gl3wVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) get_proc("glVertexAttrib4Nsv"); - gl3wVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) get_proc("glVertexAttrib4Nub"); - gl3wVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) get_proc("glVertexAttrib4Nubv"); - gl3wVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) get_proc("glVertexAttrib4Nuiv"); - gl3wVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) get_proc("glVertexAttrib4Nusv"); - gl3wVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) get_proc("glVertexAttrib4bv"); - gl3wVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) get_proc("glVertexAttrib4d"); - gl3wVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) get_proc("glVertexAttrib4dv"); - gl3wVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) get_proc("glVertexAttrib4f"); - gl3wVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) get_proc("glVertexAttrib4fv"); - gl3wVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) get_proc("glVertexAttrib4iv"); - gl3wVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) get_proc("glVertexAttrib4s"); - gl3wVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) get_proc("glVertexAttrib4sv"); - gl3wVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) get_proc("glVertexAttrib4ubv"); - gl3wVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) get_proc("glVertexAttrib4uiv"); - gl3wVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) get_proc("glVertexAttrib4usv"); - gl3wVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) get_proc("glVertexAttribPointer"); - gl3wUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) get_proc("glUniformMatrix2x3fv"); - gl3wUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) get_proc("glUniformMatrix3x2fv"); - gl3wUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) get_proc("glUniformMatrix2x4fv"); - gl3wUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) get_proc("glUniformMatrix4x2fv"); - gl3wUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) get_proc("glUniformMatrix3x4fv"); - gl3wUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) get_proc("glUniformMatrix4x3fv"); - gl3wColorMaski = (PFNGLCOLORMASKIPROC) get_proc("glColorMaski"); - gl3wGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) get_proc("glGetBooleani_v"); - gl3wGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) get_proc("glGetIntegeri_v"); - gl3wEnablei = (PFNGLENABLEIPROC) get_proc("glEnablei"); - gl3wDisablei = (PFNGLDISABLEIPROC) get_proc("glDisablei"); - gl3wIsEnabledi = (PFNGLISENABLEDIPROC) get_proc("glIsEnabledi"); - gl3wBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) get_proc("glBeginTransformFeedback"); - gl3wEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) get_proc("glEndTransformFeedback"); - gl3wBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) get_proc("glBindBufferRange"); - gl3wBindBufferBase = (PFNGLBINDBUFFERBASEPROC) get_proc("glBindBufferBase"); - gl3wTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) get_proc("glTransformFeedbackVaryings"); - gl3wGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) get_proc("glGetTransformFeedbackVarying"); - gl3wClampColor = (PFNGLCLAMPCOLORPROC) get_proc("glClampColor"); - gl3wBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) get_proc("glBeginConditionalRender"); - gl3wEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) get_proc("glEndConditionalRender"); - gl3wVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) get_proc("glVertexAttribIPointer"); - gl3wGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) get_proc("glGetVertexAttribIiv"); - gl3wGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) get_proc("glGetVertexAttribIuiv"); - gl3wVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) get_proc("glVertexAttribI1i"); - gl3wVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) get_proc("glVertexAttribI2i"); - gl3wVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) get_proc("glVertexAttribI3i"); - gl3wVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) get_proc("glVertexAttribI4i"); - gl3wVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) get_proc("glVertexAttribI1ui"); - gl3wVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) get_proc("glVertexAttribI2ui"); - gl3wVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) get_proc("glVertexAttribI3ui"); - gl3wVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) get_proc("glVertexAttribI4ui"); - gl3wVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) get_proc("glVertexAttribI1iv"); - gl3wVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) get_proc("glVertexAttribI2iv"); - gl3wVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) get_proc("glVertexAttribI3iv"); - gl3wVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) get_proc("glVertexAttribI4iv"); - gl3wVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) get_proc("glVertexAttribI1uiv"); - gl3wVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) get_proc("glVertexAttribI2uiv"); - gl3wVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) get_proc("glVertexAttribI3uiv"); - gl3wVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) get_proc("glVertexAttribI4uiv"); - gl3wVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) get_proc("glVertexAttribI4bv"); - gl3wVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) get_proc("glVertexAttribI4sv"); - gl3wVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) get_proc("glVertexAttribI4ubv"); - gl3wVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) get_proc("glVertexAttribI4usv"); - gl3wGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) get_proc("glGetUniformuiv"); - gl3wBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) get_proc("glBindFragDataLocation"); - gl3wGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) get_proc("glGetFragDataLocation"); - gl3wUniform1ui = (PFNGLUNIFORM1UIPROC) get_proc("glUniform1ui"); - gl3wUniform2ui = (PFNGLUNIFORM2UIPROC) get_proc("glUniform2ui"); - gl3wUniform3ui = (PFNGLUNIFORM3UIPROC) get_proc("glUniform3ui"); - gl3wUniform4ui = (PFNGLUNIFORM4UIPROC) get_proc("glUniform4ui"); - gl3wUniform1uiv = (PFNGLUNIFORM1UIVPROC) get_proc("glUniform1uiv"); - gl3wUniform2uiv = (PFNGLUNIFORM2UIVPROC) get_proc("glUniform2uiv"); - gl3wUniform3uiv = (PFNGLUNIFORM3UIVPROC) get_proc("glUniform3uiv"); - gl3wUniform4uiv = (PFNGLUNIFORM4UIVPROC) get_proc("glUniform4uiv"); - gl3wTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) get_proc("glTexParameterIiv"); - gl3wTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) get_proc("glTexParameterIuiv"); - gl3wGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) get_proc("glGetTexParameterIiv"); - gl3wGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) get_proc("glGetTexParameterIuiv"); - gl3wClearBufferiv = (PFNGLCLEARBUFFERIVPROC) get_proc("glClearBufferiv"); - gl3wClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) get_proc("glClearBufferuiv"); - gl3wClearBufferfv = (PFNGLCLEARBUFFERFVPROC) get_proc("glClearBufferfv"); - gl3wClearBufferfi = (PFNGLCLEARBUFFERFIPROC) get_proc("glClearBufferfi"); - gl3wGetStringi = (PFNGLGETSTRINGIPROC) get_proc("glGetStringi"); - gl3wDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) get_proc("glDrawArraysInstanced"); - gl3wDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) get_proc("glDrawElementsInstanced"); - gl3wTexBuffer = (PFNGLTEXBUFFERPROC) get_proc("glTexBuffer"); - gl3wPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) get_proc("glPrimitiveRestartIndex"); - gl3wGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) get_proc("glGetInteger64i_v"); - gl3wGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) get_proc("glGetBufferParameteri64v"); - gl3wFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) get_proc("glFramebufferTexture"); - gl3wVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) get_proc("glVertexAttribDivisor"); - gl3wMinSampleShading = (PFNGLMINSAMPLESHADINGPROC) get_proc("glMinSampleShading"); - gl3wBlendEquationi = (PFNGLBLENDEQUATIONIPROC) get_proc("glBlendEquationi"); - gl3wBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC) get_proc("glBlendEquationSeparatei"); - gl3wBlendFunci = (PFNGLBLENDFUNCIPROC) get_proc("glBlendFunci"); - gl3wBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC) get_proc("glBlendFuncSeparatei"); - gl3wIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) get_proc("glIsRenderbuffer"); - gl3wBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) get_proc("glBindRenderbuffer"); - gl3wDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) get_proc("glDeleteRenderbuffers"); - gl3wGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) get_proc("glGenRenderbuffers"); - gl3wRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) get_proc("glRenderbufferStorage"); - gl3wGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) get_proc("glGetRenderbufferParameteriv"); - gl3wIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) get_proc("glIsFramebuffer"); - gl3wBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) get_proc("glBindFramebuffer"); - gl3wDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) get_proc("glDeleteFramebuffers"); - gl3wGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) get_proc("glGenFramebuffers"); - gl3wCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) get_proc("glCheckFramebufferStatus"); - gl3wFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) get_proc("glFramebufferTexture1D"); - gl3wFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) get_proc("glFramebufferTexture2D"); - gl3wFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) get_proc("glFramebufferTexture3D"); - gl3wFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) get_proc("glFramebufferRenderbuffer"); - gl3wGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) get_proc("glGetFramebufferAttachmentParameteriv"); - gl3wGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) get_proc("glGenerateMipmap"); - gl3wBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) get_proc("glBlitFramebuffer"); - gl3wRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) get_proc("glRenderbufferStorageMultisample"); - gl3wFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) get_proc("glFramebufferTextureLayer"); - gl3wMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) get_proc("glMapBufferRange"); - gl3wFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) get_proc("glFlushMappedBufferRange"); - gl3wBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) get_proc("glBindVertexArray"); - gl3wDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) get_proc("glDeleteVertexArrays"); - gl3wGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) get_proc("glGenVertexArrays"); - gl3wIsVertexArray = (PFNGLISVERTEXARRAYPROC) get_proc("glIsVertexArray"); - gl3wGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) get_proc("glGetUniformIndices"); - gl3wGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) get_proc("glGetActiveUniformsiv"); - gl3wGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) get_proc("glGetActiveUniformName"); - gl3wGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) get_proc("glGetUniformBlockIndex"); - gl3wGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) get_proc("glGetActiveUniformBlockiv"); - gl3wGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) get_proc("glGetActiveUniformBlockName"); - gl3wUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) get_proc("glUniformBlockBinding"); - gl3wCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) get_proc("glCopyBufferSubData"); - gl3wDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) get_proc("glDrawElementsBaseVertex"); - gl3wDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) get_proc("glDrawRangeElementsBaseVertex"); - gl3wDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) get_proc("glDrawElementsInstancedBaseVertex"); - gl3wMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) get_proc("glMultiDrawElementsBaseVertex"); - gl3wProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) get_proc("glProvokingVertex"); - gl3wFenceSync = (PFNGLFENCESYNCPROC) get_proc("glFenceSync"); - gl3wIsSync = (PFNGLISSYNCPROC) get_proc("glIsSync"); - gl3wDeleteSync = (PFNGLDELETESYNCPROC) get_proc("glDeleteSync"); - gl3wClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) get_proc("glClientWaitSync"); - gl3wWaitSync = (PFNGLWAITSYNCPROC) get_proc("glWaitSync"); - gl3wGetInteger64v = (PFNGLGETINTEGER64VPROC) get_proc("glGetInteger64v"); - gl3wGetSynciv = (PFNGLGETSYNCIVPROC) get_proc("glGetSynciv"); - gl3wTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) get_proc("glTexImage2DMultisample"); - gl3wTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) get_proc("glTexImage3DMultisample"); - gl3wGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) get_proc("glGetMultisamplefv"); - gl3wSampleMaski = (PFNGLSAMPLEMASKIPROC) get_proc("glSampleMaski"); - gl3wBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC) get_proc("glBlendEquationiARB"); - gl3wBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC) get_proc("glBlendEquationSeparateiARB"); - gl3wBlendFunciARB = (PFNGLBLENDFUNCIARBPROC) get_proc("glBlendFunciARB"); - gl3wBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC) get_proc("glBlendFuncSeparateiARB"); - gl3wMinSampleShadingARB = (PFNGLMINSAMPLESHADINGARBPROC) get_proc("glMinSampleShadingARB"); - gl3wNamedStringARB = (PFNGLNAMEDSTRINGARBPROC) get_proc("glNamedStringARB"); - gl3wDeleteNamedStringARB = (PFNGLDELETENAMEDSTRINGARBPROC) get_proc("glDeleteNamedStringARB"); - gl3wCompileShaderIncludeARB = (PFNGLCOMPILESHADERINCLUDEARBPROC) get_proc("glCompileShaderIncludeARB"); - gl3wIsNamedStringARB = (PFNGLISNAMEDSTRINGARBPROC) get_proc("glIsNamedStringARB"); - gl3wGetNamedStringARB = (PFNGLGETNAMEDSTRINGARBPROC) get_proc("glGetNamedStringARB"); - gl3wGetNamedStringivARB = (PFNGLGETNAMEDSTRINGIVARBPROC) get_proc("glGetNamedStringivARB"); - gl3wBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) get_proc("glBindFragDataLocationIndexed"); - gl3wGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) get_proc("glGetFragDataIndex"); - gl3wGenSamplers = (PFNGLGENSAMPLERSPROC) get_proc("glGenSamplers"); - gl3wDeleteSamplers = (PFNGLDELETESAMPLERSPROC) get_proc("glDeleteSamplers"); - gl3wIsSampler = (PFNGLISSAMPLERPROC) get_proc("glIsSampler"); - gl3wBindSampler = (PFNGLBINDSAMPLERPROC) get_proc("glBindSampler"); - gl3wSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) get_proc("glSamplerParameteri"); - gl3wSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) get_proc("glSamplerParameteriv"); - gl3wSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) get_proc("glSamplerParameterf"); - gl3wSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) get_proc("glSamplerParameterfv"); - gl3wSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) get_proc("glSamplerParameterIiv"); - gl3wSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) get_proc("glSamplerParameterIuiv"); - gl3wGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) get_proc("glGetSamplerParameteriv"); - gl3wGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) get_proc("glGetSamplerParameterIiv"); - gl3wGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) get_proc("glGetSamplerParameterfv"); - gl3wGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) get_proc("glGetSamplerParameterIuiv"); - gl3wQueryCounter = (PFNGLQUERYCOUNTERPROC) get_proc("glQueryCounter"); - gl3wGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) get_proc("glGetQueryObjecti64v"); - gl3wGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) get_proc("glGetQueryObjectui64v"); - gl3wVertexP2ui = (PFNGLVERTEXP2UIPROC) get_proc("glVertexP2ui"); - gl3wVertexP2uiv = (PFNGLVERTEXP2UIVPROC) get_proc("glVertexP2uiv"); - gl3wVertexP3ui = (PFNGLVERTEXP3UIPROC) get_proc("glVertexP3ui"); - gl3wVertexP3uiv = (PFNGLVERTEXP3UIVPROC) get_proc("glVertexP3uiv"); - gl3wVertexP4ui = (PFNGLVERTEXP4UIPROC) get_proc("glVertexP4ui"); - gl3wVertexP4uiv = (PFNGLVERTEXP4UIVPROC) get_proc("glVertexP4uiv"); - gl3wTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC) get_proc("glTexCoordP1ui"); - gl3wTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC) get_proc("glTexCoordP1uiv"); - gl3wTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC) get_proc("glTexCoordP2ui"); - gl3wTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC) get_proc("glTexCoordP2uiv"); - gl3wTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC) get_proc("glTexCoordP3ui"); - gl3wTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC) get_proc("glTexCoordP3uiv"); - gl3wTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC) get_proc("glTexCoordP4ui"); - gl3wTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC) get_proc("glTexCoordP4uiv"); - gl3wMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC) get_proc("glMultiTexCoordP1ui"); - gl3wMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC) get_proc("glMultiTexCoordP1uiv"); - gl3wMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC) get_proc("glMultiTexCoordP2ui"); - gl3wMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC) get_proc("glMultiTexCoordP2uiv"); - gl3wMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC) get_proc("glMultiTexCoordP3ui"); - gl3wMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC) get_proc("glMultiTexCoordP3uiv"); - gl3wMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC) get_proc("glMultiTexCoordP4ui"); - gl3wMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC) get_proc("glMultiTexCoordP4uiv"); - gl3wNormalP3ui = (PFNGLNORMALP3UIPROC) get_proc("glNormalP3ui"); - gl3wNormalP3uiv = (PFNGLNORMALP3UIVPROC) get_proc("glNormalP3uiv"); - gl3wColorP3ui = (PFNGLCOLORP3UIPROC) get_proc("glColorP3ui"); - gl3wColorP3uiv = (PFNGLCOLORP3UIVPROC) get_proc("glColorP3uiv"); - gl3wColorP4ui = (PFNGLCOLORP4UIPROC) get_proc("glColorP4ui"); - gl3wColorP4uiv = (PFNGLCOLORP4UIVPROC) get_proc("glColorP4uiv"); - gl3wSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC) get_proc("glSecondaryColorP3ui"); - gl3wSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC) get_proc("glSecondaryColorP3uiv"); - gl3wVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) get_proc("glVertexAttribP1ui"); - gl3wVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) get_proc("glVertexAttribP1uiv"); - gl3wVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) get_proc("glVertexAttribP2ui"); - gl3wVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) get_proc("glVertexAttribP2uiv"); - gl3wVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) get_proc("glVertexAttribP3ui"); - gl3wVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) get_proc("glVertexAttribP3uiv"); - gl3wVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) get_proc("glVertexAttribP4ui"); - gl3wVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) get_proc("glVertexAttribP4uiv"); - gl3wDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) get_proc("glDrawArraysIndirect"); - gl3wDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) get_proc("glDrawElementsIndirect"); - gl3wUniform1d = (PFNGLUNIFORM1DPROC) get_proc("glUniform1d"); - gl3wUniform2d = (PFNGLUNIFORM2DPROC) get_proc("glUniform2d"); - gl3wUniform3d = (PFNGLUNIFORM3DPROC) get_proc("glUniform3d"); - gl3wUniform4d = (PFNGLUNIFORM4DPROC) get_proc("glUniform4d"); - gl3wUniform1dv = (PFNGLUNIFORM1DVPROC) get_proc("glUniform1dv"); - gl3wUniform2dv = (PFNGLUNIFORM2DVPROC) get_proc("glUniform2dv"); - gl3wUniform3dv = (PFNGLUNIFORM3DVPROC) get_proc("glUniform3dv"); - gl3wUniform4dv = (PFNGLUNIFORM4DVPROC) get_proc("glUniform4dv"); - gl3wUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC) get_proc("glUniformMatrix2dv"); - gl3wUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC) get_proc("glUniformMatrix3dv"); - gl3wUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC) get_proc("glUniformMatrix4dv"); - gl3wUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC) get_proc("glUniformMatrix2x3dv"); - gl3wUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC) get_proc("glUniformMatrix2x4dv"); - gl3wUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC) get_proc("glUniformMatrix3x2dv"); - gl3wUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC) get_proc("glUniformMatrix3x4dv"); - gl3wUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC) get_proc("glUniformMatrix4x2dv"); - gl3wUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC) get_proc("glUniformMatrix4x3dv"); - gl3wGetUniformdv = (PFNGLGETUNIFORMDVPROC) get_proc("glGetUniformdv"); - gl3wGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) get_proc("glGetSubroutineUniformLocation"); - gl3wGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC) get_proc("glGetSubroutineIndex"); - gl3wGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) get_proc("glGetActiveSubroutineUniformiv"); - gl3wGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) get_proc("glGetActiveSubroutineUniformName"); - gl3wGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC) get_proc("glGetActiveSubroutineName"); - gl3wUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC) get_proc("glUniformSubroutinesuiv"); - gl3wGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC) get_proc("glGetUniformSubroutineuiv"); - gl3wGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC) get_proc("glGetProgramStageiv"); - gl3wPatchParameteri = (PFNGLPATCHPARAMETERIPROC) get_proc("glPatchParameteri"); - gl3wPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC) get_proc("glPatchParameterfv"); - gl3wBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) get_proc("glBindTransformFeedback"); - gl3wDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) get_proc("glDeleteTransformFeedbacks"); - gl3wGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) get_proc("glGenTransformFeedbacks"); - gl3wIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) get_proc("glIsTransformFeedback"); - gl3wPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) get_proc("glPauseTransformFeedback"); - gl3wResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) get_proc("glResumeTransformFeedback"); - gl3wDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC) get_proc("glDrawTransformFeedback"); - gl3wDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) get_proc("glDrawTransformFeedbackStream"); - gl3wBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC) get_proc("glBeginQueryIndexed"); - gl3wEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC) get_proc("glEndQueryIndexed"); - gl3wGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC) get_proc("glGetQueryIndexediv"); - gl3wReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) get_proc("glReleaseShaderCompiler"); - gl3wShaderBinary = (PFNGLSHADERBINARYPROC) get_proc("glShaderBinary"); - gl3wGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) get_proc("glGetShaderPrecisionFormat"); - gl3wDepthRangef = (PFNGLDEPTHRANGEFPROC) get_proc("glDepthRangef"); - gl3wClearDepthf = (PFNGLCLEARDEPTHFPROC) get_proc("glClearDepthf"); - gl3wGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) get_proc("glGetProgramBinary"); - gl3wProgramBinary = (PFNGLPROGRAMBINARYPROC) get_proc("glProgramBinary"); - gl3wProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) get_proc("glProgramParameteri"); - gl3wUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) get_proc("glUseProgramStages"); - gl3wActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) get_proc("glActiveShaderProgram"); - gl3wCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) get_proc("glCreateShaderProgramv"); - gl3wBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) get_proc("glBindProgramPipeline"); - gl3wDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) get_proc("glDeleteProgramPipelines"); - gl3wGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) get_proc("glGenProgramPipelines"); - gl3wIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) get_proc("glIsProgramPipeline"); - gl3wGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) get_proc("glGetProgramPipelineiv"); - gl3wProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) get_proc("glProgramUniform1i"); - gl3wProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) get_proc("glProgramUniform1iv"); - gl3wProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) get_proc("glProgramUniform1f"); - gl3wProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) get_proc("glProgramUniform1fv"); - gl3wProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC) get_proc("glProgramUniform1d"); - gl3wProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC) get_proc("glProgramUniform1dv"); - gl3wProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) get_proc("glProgramUniform1ui"); - gl3wProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) get_proc("glProgramUniform1uiv"); - gl3wProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) get_proc("glProgramUniform2i"); - gl3wProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) get_proc("glProgramUniform2iv"); - gl3wProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) get_proc("glProgramUniform2f"); - gl3wProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) get_proc("glProgramUniform2fv"); - gl3wProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC) get_proc("glProgramUniform2d"); - gl3wProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC) get_proc("glProgramUniform2dv"); - gl3wProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) get_proc("glProgramUniform2ui"); - gl3wProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) get_proc("glProgramUniform2uiv"); - gl3wProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) get_proc("glProgramUniform3i"); - gl3wProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) get_proc("glProgramUniform3iv"); - gl3wProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) get_proc("glProgramUniform3f"); - gl3wProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) get_proc("glProgramUniform3fv"); - gl3wProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC) get_proc("glProgramUniform3d"); - gl3wProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC) get_proc("glProgramUniform3dv"); - gl3wProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) get_proc("glProgramUniform3ui"); - gl3wProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) get_proc("glProgramUniform3uiv"); - gl3wProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) get_proc("glProgramUniform4i"); - gl3wProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) get_proc("glProgramUniform4iv"); - gl3wProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) get_proc("glProgramUniform4f"); - gl3wProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) get_proc("glProgramUniform4fv"); - gl3wProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC) get_proc("glProgramUniform4d"); - gl3wProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC) get_proc("glProgramUniform4dv"); - gl3wProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) get_proc("glProgramUniform4ui"); - gl3wProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) get_proc("glProgramUniform4uiv"); - gl3wProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) get_proc("glProgramUniformMatrix2fv"); - gl3wProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) get_proc("glProgramUniformMatrix3fv"); - gl3wProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) get_proc("glProgramUniformMatrix4fv"); - gl3wProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC) get_proc("glProgramUniformMatrix2dv"); - gl3wProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC) get_proc("glProgramUniformMatrix3dv"); - gl3wProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC) get_proc("glProgramUniformMatrix4dv"); - gl3wProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) get_proc("glProgramUniformMatrix2x3fv"); - gl3wProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) get_proc("glProgramUniformMatrix3x2fv"); - gl3wProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) get_proc("glProgramUniformMatrix2x4fv"); - gl3wProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) get_proc("glProgramUniformMatrix4x2fv"); - gl3wProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) get_proc("glProgramUniformMatrix3x4fv"); - gl3wProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) get_proc("glProgramUniformMatrix4x3fv"); - gl3wProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) get_proc("glProgramUniformMatrix2x3dv"); - gl3wProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) get_proc("glProgramUniformMatrix3x2dv"); - gl3wProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) get_proc("glProgramUniformMatrix2x4dv"); - gl3wProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) get_proc("glProgramUniformMatrix4x2dv"); - gl3wProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) get_proc("glProgramUniformMatrix3x4dv"); - gl3wProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) get_proc("glProgramUniformMatrix4x3dv"); - gl3wValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) get_proc("glValidateProgramPipeline"); - gl3wGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) get_proc("glGetProgramPipelineInfoLog"); - gl3wVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC) get_proc("glVertexAttribL1d"); - gl3wVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC) get_proc("glVertexAttribL2d"); - gl3wVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC) get_proc("glVertexAttribL3d"); - gl3wVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC) get_proc("glVertexAttribL4d"); - gl3wVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC) get_proc("glVertexAttribL1dv"); - gl3wVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC) get_proc("glVertexAttribL2dv"); - gl3wVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC) get_proc("glVertexAttribL3dv"); - gl3wVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC) get_proc("glVertexAttribL4dv"); - gl3wVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC) get_proc("glVertexAttribLPointer"); - gl3wGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC) get_proc("glGetVertexAttribLdv"); - gl3wViewportArrayv = (PFNGLVIEWPORTARRAYVPROC) get_proc("glViewportArrayv"); - gl3wViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC) get_proc("glViewportIndexedf"); - gl3wViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC) get_proc("glViewportIndexedfv"); - gl3wScissorArrayv = (PFNGLSCISSORARRAYVPROC) get_proc("glScissorArrayv"); - gl3wScissorIndexed = (PFNGLSCISSORINDEXEDPROC) get_proc("glScissorIndexed"); - gl3wScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC) get_proc("glScissorIndexedv"); - gl3wDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC) get_proc("glDepthRangeArrayv"); - gl3wDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC) get_proc("glDepthRangeIndexed"); - gl3wGetFloati_v = (PFNGLGETFLOATI_VPROC) get_proc("glGetFloati_v"); - gl3wGetDoublei_v = (PFNGLGETDOUBLEI_VPROC) get_proc("glGetDoublei_v"); - gl3wCreateSyncFromCLeventARB = (PFNGLCREATESYNCFROMCLEVENTARBPROC) get_proc("glCreateSyncFromCLeventARB"); - gl3wDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) get_proc("glDebugMessageControlARB"); - gl3wDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) get_proc("glDebugMessageInsertARB"); - gl3wDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) get_proc("glDebugMessageCallbackARB"); - gl3wGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) get_proc("glGetDebugMessageLogARB"); - gl3wGetGraphicsResetStatusARB = (PFNGLGETGRAPHICSRESETSTATUSARBPROC) get_proc("glGetGraphicsResetStatusARB"); - gl3wGetnTexImageARB = (PFNGLGETNTEXIMAGEARBPROC) get_proc("glGetnTexImageARB"); - gl3wReadnPixelsARB = (PFNGLREADNPIXELSARBPROC) get_proc("glReadnPixelsARB"); - gl3wGetnCompressedTexImageARB = (PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) get_proc("glGetnCompressedTexImageARB"); - gl3wGetnUniformfvARB = (PFNGLGETNUNIFORMFVARBPROC) get_proc("glGetnUniformfvARB"); - gl3wGetnUniformivARB = (PFNGLGETNUNIFORMIVARBPROC) get_proc("glGetnUniformivARB"); - gl3wGetnUniformuivARB = (PFNGLGETNUNIFORMUIVARBPROC) get_proc("glGetnUniformuivARB"); - gl3wGetnUniformdvARB = (PFNGLGETNUNIFORMDVARBPROC) get_proc("glGetnUniformdvARB"); - gl3wDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) get_proc("glDrawArraysInstancedBaseInstance"); - gl3wDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) get_proc("glDrawElementsInstancedBaseInstance"); - gl3wDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) get_proc("glDrawElementsInstancedBaseVertexBaseInstance"); - gl3wDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) get_proc("glDrawTransformFeedbackInstanced"); - gl3wDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) get_proc("glDrawTransformFeedbackStreamInstanced"); - gl3wGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) get_proc("glGetInternalformativ"); - gl3wGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) get_proc("glGetActiveAtomicCounterBufferiv"); - gl3wBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) get_proc("glBindImageTexture"); - gl3wMemoryBarrier = (PFNGLMEMORYBARRIERPROC) get_proc("glMemoryBarrier"); - gl3wTexStorage1D = (PFNGLTEXSTORAGE1DPROC) get_proc("glTexStorage1D"); - gl3wTexStorage2D = (PFNGLTEXSTORAGE2DPROC) get_proc("glTexStorage2D"); - gl3wTexStorage3D = (PFNGLTEXSTORAGE3DPROC) get_proc("glTexStorage3D"); - gl3wTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC) get_proc("glTextureStorage1DEXT"); - gl3wTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC) get_proc("glTextureStorage2DEXT"); - gl3wTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC) get_proc("glTextureStorage3DEXT"); - gl3wDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) get_proc("glDebugMessageControl"); - gl3wDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) get_proc("glDebugMessageInsert"); - gl3wDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) get_proc("glDebugMessageCallback"); - gl3wGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) get_proc("glGetDebugMessageLog"); - gl3wPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) get_proc("glPushDebugGroup"); - gl3wPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) get_proc("glPopDebugGroup"); - gl3wObjectLabel = (PFNGLOBJECTLABELPROC) get_proc("glObjectLabel"); - gl3wGetObjectLabel = (PFNGLGETOBJECTLABELPROC) get_proc("glGetObjectLabel"); - gl3wObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) get_proc("glObjectPtrLabel"); - gl3wGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) get_proc("glGetObjectPtrLabel"); - gl3wClearBufferData = (PFNGLCLEARBUFFERDATAPROC) get_proc("glClearBufferData"); - gl3wClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC) get_proc("glClearBufferSubData"); - gl3wClearNamedBufferDataEXT = (PFNGLCLEARNAMEDBUFFERDATAEXTPROC) get_proc("glClearNamedBufferDataEXT"); - gl3wClearNamedBufferSubDataEXT = (PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) get_proc("glClearNamedBufferSubDataEXT"); - gl3wDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) get_proc("glDispatchCompute"); - gl3wDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) get_proc("glDispatchComputeIndirect"); - gl3wCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC) get_proc("glCopyImageSubData"); - gl3wTextureView = (PFNGLTEXTUREVIEWPROC) get_proc("glTextureView"); - gl3wBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) get_proc("glBindVertexBuffer"); - gl3wVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) get_proc("glVertexAttribFormat"); - gl3wVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) get_proc("glVertexAttribIFormat"); - gl3wVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC) get_proc("glVertexAttribLFormat"); - gl3wVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) get_proc("glVertexAttribBinding"); - gl3wVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) get_proc("glVertexBindingDivisor"); - gl3wVertexArrayBindVertexBufferEXT = (PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) get_proc("glVertexArrayBindVertexBufferEXT"); - gl3wVertexArrayVertexAttribFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) get_proc("glVertexArrayVertexAttribFormatEXT"); - gl3wVertexArrayVertexAttribIFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) get_proc("glVertexArrayVertexAttribIFormatEXT"); - gl3wVertexArrayVertexAttribLFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) get_proc("glVertexArrayVertexAttribLFormatEXT"); - gl3wVertexArrayVertexAttribBindingEXT = (PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) get_proc("glVertexArrayVertexAttribBindingEXT"); - gl3wVertexArrayVertexBindingDivisorEXT = (PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) get_proc("glVertexArrayVertexBindingDivisorEXT"); - gl3wFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) get_proc("glFramebufferParameteri"); - gl3wGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) get_proc("glGetFramebufferParameteriv"); - gl3wNamedFramebufferParameteriEXT = (PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) get_proc("glNamedFramebufferParameteriEXT"); - gl3wGetNamedFramebufferParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) get_proc("glGetNamedFramebufferParameterivEXT"); - gl3wGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC) get_proc("glGetInternalformati64v"); - gl3wInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC) get_proc("glInvalidateTexSubImage"); - gl3wInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC) get_proc("glInvalidateTexImage"); - gl3wInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC) get_proc("glInvalidateBufferSubData"); - gl3wInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC) get_proc("glInvalidateBufferData"); - gl3wInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) get_proc("glInvalidateFramebuffer"); - gl3wInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) get_proc("glInvalidateSubFramebuffer"); - gl3wMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC) get_proc("glMultiDrawArraysIndirect"); - gl3wMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC) get_proc("glMultiDrawElementsIndirect"); - gl3wGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) get_proc("glGetProgramInterfaceiv"); - gl3wGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) get_proc("glGetProgramResourceIndex"); - gl3wGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) get_proc("glGetProgramResourceName"); - gl3wGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) get_proc("glGetProgramResourceiv"); - gl3wGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) get_proc("glGetProgramResourceLocation"); - gl3wGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) get_proc("glGetProgramResourceLocationIndex"); - gl3wShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) get_proc("glShaderStorageBlockBinding"); - gl3wTexBufferRange = (PFNGLTEXBUFFERRANGEPROC) get_proc("glTexBufferRange"); - gl3wTextureBufferRangeEXT = (PFNGLTEXTUREBUFFERRANGEEXTPROC) get_proc("glTextureBufferRangeEXT"); - gl3wTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) get_proc("glTexStorage2DMultisample"); - gl3wTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) get_proc("glTexStorage3DMultisample"); - gl3wTextureStorage2DMultisampleEXT = (PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) get_proc("glTextureStorage2DMultisampleEXT"); - gl3wTextureStorage3DMultisampleEXT = (PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) get_proc("glTextureStorage3DMultisampleEXT"); + gl3wCullFace = (PFNGLCULLFACEPROC) get_proc("glCullFace"); + gl3wFrontFace = (PFNGLFRONTFACEPROC) get_proc("glFrontFace"); + gl3wHint = (PFNGLHINTPROC) get_proc("glHint"); + gl3wLineWidth = (PFNGLLINEWIDTHPROC) get_proc("glLineWidth"); + gl3wPointSize = (PFNGLPOINTSIZEPROC) get_proc("glPointSize"); + gl3wPolygonMode = (PFNGLPOLYGONMODEPROC) get_proc("glPolygonMode"); + gl3wScissor = (PFNGLSCISSORPROC) get_proc("glScissor"); + gl3wTexParameterf = (PFNGLTEXPARAMETERFPROC) get_proc("glTexParameterf"); + gl3wTexParameterfv = (PFNGLTEXPARAMETERFVPROC) get_proc("glTexParameterfv"); + gl3wTexParameteri = (PFNGLTEXPARAMETERIPROC) get_proc("glTexParameteri"); + gl3wTexParameteriv = (PFNGLTEXPARAMETERIVPROC) get_proc("glTexParameteriv"); + gl3wTexImage1D = (PFNGLTEXIMAGE1DPROC) get_proc("glTexImage1D"); + gl3wTexImage2D = (PFNGLTEXIMAGE2DPROC) get_proc("glTexImage2D"); + gl3wDrawBuffer = (PFNGLDRAWBUFFERPROC) get_proc("glDrawBuffer"); + gl3wClear = (PFNGLCLEARPROC) get_proc("glClear"); + gl3wClearColor = (PFNGLCLEARCOLORPROC) get_proc("glClearColor"); + gl3wClearStencil = (PFNGLCLEARSTENCILPROC) get_proc("glClearStencil"); + gl3wClearDepth = (PFNGLCLEARDEPTHPROC) get_proc("glClearDepth"); + gl3wStencilMask = (PFNGLSTENCILMASKPROC) get_proc("glStencilMask"); + gl3wColorMask = (PFNGLCOLORMASKPROC) get_proc("glColorMask"); + gl3wDepthMask = (PFNGLDEPTHMASKPROC) get_proc("glDepthMask"); + gl3wDisable = (PFNGLDISABLEPROC) get_proc("glDisable"); + gl3wEnable = (PFNGLENABLEPROC) get_proc("glEnable"); + gl3wFinish = (PFNGLFINISHPROC) get_proc("glFinish"); + gl3wFlush = (PFNGLFLUSHPROC) get_proc("glFlush"); + gl3wBlendFunc = (PFNGLBLENDFUNCPROC) get_proc("glBlendFunc"); + gl3wLogicOp = (PFNGLLOGICOPPROC) get_proc("glLogicOp"); + gl3wStencilFunc = (PFNGLSTENCILFUNCPROC) get_proc("glStencilFunc"); + gl3wStencilOp = (PFNGLSTENCILOPPROC) get_proc("glStencilOp"); + gl3wDepthFunc = (PFNGLDEPTHFUNCPROC) get_proc("glDepthFunc"); + gl3wPixelStoref = (PFNGLPIXELSTOREFPROC) get_proc("glPixelStoref"); + gl3wPixelStorei = (PFNGLPIXELSTOREIPROC) get_proc("glPixelStorei"); + gl3wReadBuffer = (PFNGLREADBUFFERPROC) get_proc("glReadBuffer"); + gl3wReadPixels = (PFNGLREADPIXELSPROC) get_proc("glReadPixels"); + gl3wGetBooleanv = (PFNGLGETBOOLEANVPROC) get_proc("glGetBooleanv"); + gl3wGetDoublev = (PFNGLGETDOUBLEVPROC) get_proc("glGetDoublev"); + gl3wGetError = (PFNGLGETERRORPROC) get_proc("glGetError"); + gl3wGetFloatv = (PFNGLGETFLOATVPROC) get_proc("glGetFloatv"); + gl3wGetIntegerv = (PFNGLGETINTEGERVPROC) get_proc("glGetIntegerv"); + gl3wGetString = (PFNGLGETSTRINGPROC) get_proc("glGetString"); + gl3wGetTexImage = (PFNGLGETTEXIMAGEPROC) get_proc("glGetTexImage"); + gl3wGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) get_proc("glGetTexParameterfv"); + gl3wGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) get_proc("glGetTexParameteriv"); + gl3wGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) get_proc("glGetTexLevelParameterfv"); + gl3wGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) get_proc("glGetTexLevelParameteriv"); + gl3wIsEnabled = (PFNGLISENABLEDPROC) get_proc("glIsEnabled"); + gl3wDepthRange = (PFNGLDEPTHRANGEPROC) get_proc("glDepthRange"); + gl3wViewport = (PFNGLVIEWPORTPROC) get_proc("glViewport"); + gl3wDrawArrays = (PFNGLDRAWARRAYSPROC) get_proc("glDrawArrays"); + gl3wDrawElements = (PFNGLDRAWELEMENTSPROC) get_proc("glDrawElements"); + gl3wGetPointerv = (PFNGLGETPOINTERVPROC) get_proc("glGetPointerv"); + gl3wPolygonOffset = (PFNGLPOLYGONOFFSETPROC) get_proc("glPolygonOffset"); + gl3wCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) get_proc("glCopyTexImage1D"); + gl3wCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) get_proc("glCopyTexImage2D"); + gl3wCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) get_proc("glCopyTexSubImage1D"); + gl3wCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) get_proc("glCopyTexSubImage2D"); + gl3wTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) get_proc("glTexSubImage1D"); + gl3wTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) get_proc("glTexSubImage2D"); + gl3wBindTexture = (PFNGLBINDTEXTUREPROC) get_proc("glBindTexture"); + gl3wDeleteTextures = (PFNGLDELETETEXTURESPROC) get_proc("glDeleteTextures"); + gl3wGenTextures = (PFNGLGENTEXTURESPROC) get_proc("glGenTextures"); + gl3wIsTexture = (PFNGLISTEXTUREPROC) get_proc("glIsTexture"); + gl3wBlendColor = (PFNGLBLENDCOLORPROC) get_proc("glBlendColor"); + gl3wBlendEquation = (PFNGLBLENDEQUATIONPROC) get_proc("glBlendEquation"); + gl3wDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) get_proc("glDrawRangeElements"); + gl3wTexImage3D = (PFNGLTEXIMAGE3DPROC) get_proc("glTexImage3D"); + gl3wTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) get_proc("glTexSubImage3D"); + gl3wCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) get_proc("glCopyTexSubImage3D"); + gl3wActiveTexture = (PFNGLACTIVETEXTUREPROC) get_proc("glActiveTexture"); + gl3wSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) get_proc("glSampleCoverage"); + gl3wCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) get_proc("glCompressedTexImage3D"); + gl3wCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) get_proc("glCompressedTexImage2D"); + gl3wCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) get_proc("glCompressedTexImage1D"); + gl3wCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) get_proc("glCompressedTexSubImage3D"); + gl3wCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) get_proc("glCompressedTexSubImage2D"); + gl3wCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) get_proc("glCompressedTexSubImage1D"); + gl3wGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) get_proc("glGetCompressedTexImage"); + gl3wBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) get_proc("glBlendFuncSeparate"); + gl3wMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) get_proc("glMultiDrawArrays"); + gl3wMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) get_proc("glMultiDrawElements"); + gl3wPointParameterf = (PFNGLPOINTPARAMETERFPROC) get_proc("glPointParameterf"); + gl3wPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) get_proc("glPointParameterfv"); + gl3wPointParameteri = (PFNGLPOINTPARAMETERIPROC) get_proc("glPointParameteri"); + gl3wPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) get_proc("glPointParameteriv"); + gl3wGenQueries = (PFNGLGENQUERIESPROC) get_proc("glGenQueries"); + gl3wDeleteQueries = (PFNGLDELETEQUERIESPROC) get_proc("glDeleteQueries"); + gl3wIsQuery = (PFNGLISQUERYPROC) get_proc("glIsQuery"); + gl3wBeginQuery = (PFNGLBEGINQUERYPROC) get_proc("glBeginQuery"); + gl3wEndQuery = (PFNGLENDQUERYPROC) get_proc("glEndQuery"); + gl3wGetQueryiv = (PFNGLGETQUERYIVPROC) get_proc("glGetQueryiv"); + gl3wGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) get_proc("glGetQueryObjectiv"); + gl3wGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) get_proc("glGetQueryObjectuiv"); + gl3wBindBuffer = (PFNGLBINDBUFFERPROC) get_proc("glBindBuffer"); + gl3wDeleteBuffers = (PFNGLDELETEBUFFERSPROC) get_proc("glDeleteBuffers"); + gl3wGenBuffers = (PFNGLGENBUFFERSPROC) get_proc("glGenBuffers"); + gl3wIsBuffer = (PFNGLISBUFFERPROC) get_proc("glIsBuffer"); + gl3wBufferData = (PFNGLBUFFERDATAPROC) get_proc("glBufferData"); + gl3wBufferSubData = (PFNGLBUFFERSUBDATAPROC) get_proc("glBufferSubData"); + gl3wGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) get_proc("glGetBufferSubData"); + gl3wMapBuffer = (PFNGLMAPBUFFERPROC) get_proc("glMapBuffer"); + gl3wUnmapBuffer = (PFNGLUNMAPBUFFERPROC) get_proc("glUnmapBuffer"); + gl3wGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) get_proc("glGetBufferParameteriv"); + gl3wGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) get_proc("glGetBufferPointerv"); + gl3wBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) get_proc("glBlendEquationSeparate"); + gl3wDrawBuffers = (PFNGLDRAWBUFFERSPROC) get_proc("glDrawBuffers"); + gl3wStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) get_proc("glStencilOpSeparate"); + gl3wStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) get_proc("glStencilFuncSeparate"); + gl3wStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) get_proc("glStencilMaskSeparate"); + gl3wAttachShader = (PFNGLATTACHSHADERPROC) get_proc("glAttachShader"); + gl3wBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) get_proc("glBindAttribLocation"); + gl3wCompileShader = (PFNGLCOMPILESHADERPROC) get_proc("glCompileShader"); + gl3wCreateProgram = (PFNGLCREATEPROGRAMPROC) get_proc("glCreateProgram"); + gl3wCreateShader = (PFNGLCREATESHADERPROC) get_proc("glCreateShader"); + gl3wDeleteProgram = (PFNGLDELETEPROGRAMPROC) get_proc("glDeleteProgram"); + gl3wDeleteShader = (PFNGLDELETESHADERPROC) get_proc("glDeleteShader"); + gl3wDetachShader = (PFNGLDETACHSHADERPROC) get_proc("glDetachShader"); + gl3wDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) get_proc("glDisableVertexAttribArray"); + gl3wEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) get_proc("glEnableVertexAttribArray"); + gl3wGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) get_proc("glGetActiveAttrib"); + gl3wGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) get_proc("glGetActiveUniform"); + gl3wGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) get_proc("glGetAttachedShaders"); + gl3wGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) get_proc("glGetAttribLocation"); + gl3wGetProgramiv = (PFNGLGETPROGRAMIVPROC) get_proc("glGetProgramiv"); + gl3wGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) get_proc("glGetProgramInfoLog"); + gl3wGetShaderiv = (PFNGLGETSHADERIVPROC) get_proc("glGetShaderiv"); + gl3wGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) get_proc("glGetShaderInfoLog"); + gl3wGetShaderSource = (PFNGLGETSHADERSOURCEPROC) get_proc("glGetShaderSource"); + gl3wGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) get_proc("glGetUniformLocation"); + gl3wGetUniformfv = (PFNGLGETUNIFORMFVPROC) get_proc("glGetUniformfv"); + gl3wGetUniformiv = (PFNGLGETUNIFORMIVPROC) get_proc("glGetUniformiv"); + gl3wGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) get_proc("glGetVertexAttribdv"); + gl3wGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) get_proc("glGetVertexAttribfv"); + gl3wGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) get_proc("glGetVertexAttribiv"); + gl3wGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) get_proc("glGetVertexAttribPointerv"); + gl3wIsProgram = (PFNGLISPROGRAMPROC) get_proc("glIsProgram"); + gl3wIsShader = (PFNGLISSHADERPROC) get_proc("glIsShader"); + gl3wLinkProgram = (PFNGLLINKPROGRAMPROC) get_proc("glLinkProgram"); + gl3wShaderSource = (PFNGLSHADERSOURCEPROC) get_proc("glShaderSource"); + gl3wUseProgram = (PFNGLUSEPROGRAMPROC) get_proc("glUseProgram"); + gl3wUniform1f = (PFNGLUNIFORM1FPROC) get_proc("glUniform1f"); + gl3wUniform2f = (PFNGLUNIFORM2FPROC) get_proc("glUniform2f"); + gl3wUniform3f = (PFNGLUNIFORM3FPROC) get_proc("glUniform3f"); + gl3wUniform4f = (PFNGLUNIFORM4FPROC) get_proc("glUniform4f"); + gl3wUniform1i = (PFNGLUNIFORM1IPROC) get_proc("glUniform1i"); + gl3wUniform2i = (PFNGLUNIFORM2IPROC) get_proc("glUniform2i"); + gl3wUniform3i = (PFNGLUNIFORM3IPROC) get_proc("glUniform3i"); + gl3wUniform4i = (PFNGLUNIFORM4IPROC) get_proc("glUniform4i"); + gl3wUniform1fv = (PFNGLUNIFORM1FVPROC) get_proc("glUniform1fv"); + gl3wUniform2fv = (PFNGLUNIFORM2FVPROC) get_proc("glUniform2fv"); + gl3wUniform3fv = (PFNGLUNIFORM3FVPROC) get_proc("glUniform3fv"); + gl3wUniform4fv = (PFNGLUNIFORM4FVPROC) get_proc("glUniform4fv"); + gl3wUniform1iv = (PFNGLUNIFORM1IVPROC) get_proc("glUniform1iv"); + gl3wUniform2iv = (PFNGLUNIFORM2IVPROC) get_proc("glUniform2iv"); + gl3wUniform3iv = (PFNGLUNIFORM3IVPROC) get_proc("glUniform3iv"); + gl3wUniform4iv = (PFNGLUNIFORM4IVPROC) get_proc("glUniform4iv"); + gl3wUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) get_proc("glUniformMatrix2fv"); + gl3wUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) get_proc("glUniformMatrix3fv"); + gl3wUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) get_proc("glUniformMatrix4fv"); + gl3wValidateProgram = (PFNGLVALIDATEPROGRAMPROC) get_proc("glValidateProgram"); + gl3wVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) get_proc("glVertexAttrib1d"); + gl3wVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) get_proc("glVertexAttrib1dv"); + gl3wVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) get_proc("glVertexAttrib1f"); + gl3wVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) get_proc("glVertexAttrib1fv"); + gl3wVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) get_proc("glVertexAttrib1s"); + gl3wVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) get_proc("glVertexAttrib1sv"); + gl3wVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) get_proc("glVertexAttrib2d"); + gl3wVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) get_proc("glVertexAttrib2dv"); + gl3wVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) get_proc("glVertexAttrib2f"); + gl3wVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) get_proc("glVertexAttrib2fv"); + gl3wVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) get_proc("glVertexAttrib2s"); + gl3wVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) get_proc("glVertexAttrib2sv"); + gl3wVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) get_proc("glVertexAttrib3d"); + gl3wVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) get_proc("glVertexAttrib3dv"); + gl3wVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) get_proc("glVertexAttrib3f"); + gl3wVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) get_proc("glVertexAttrib3fv"); + gl3wVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) get_proc("glVertexAttrib3s"); + gl3wVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) get_proc("glVertexAttrib3sv"); + gl3wVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) get_proc("glVertexAttrib4Nbv"); + gl3wVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) get_proc("glVertexAttrib4Niv"); + gl3wVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) get_proc("glVertexAttrib4Nsv"); + gl3wVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) get_proc("glVertexAttrib4Nub"); + gl3wVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) get_proc("glVertexAttrib4Nubv"); + gl3wVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) get_proc("glVertexAttrib4Nuiv"); + gl3wVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) get_proc("glVertexAttrib4Nusv"); + gl3wVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) get_proc("glVertexAttrib4bv"); + gl3wVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) get_proc("glVertexAttrib4d"); + gl3wVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) get_proc("glVertexAttrib4dv"); + gl3wVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) get_proc("glVertexAttrib4f"); + gl3wVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) get_proc("glVertexAttrib4fv"); + gl3wVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) get_proc("glVertexAttrib4iv"); + gl3wVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) get_proc("glVertexAttrib4s"); + gl3wVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) get_proc("glVertexAttrib4sv"); + gl3wVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) get_proc("glVertexAttrib4ubv"); + gl3wVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) get_proc("glVertexAttrib4uiv"); + gl3wVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) get_proc("glVertexAttrib4usv"); + gl3wVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) get_proc("glVertexAttribPointer"); + gl3wUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) get_proc("glUniformMatrix2x3fv"); + gl3wUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) get_proc("glUniformMatrix3x2fv"); + gl3wUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) get_proc("glUniformMatrix2x4fv"); + gl3wUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) get_proc("glUniformMatrix4x2fv"); + gl3wUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) get_proc("glUniformMatrix3x4fv"); + gl3wUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) get_proc("glUniformMatrix4x3fv"); + gl3wColorMaski = (PFNGLCOLORMASKIPROC) get_proc("glColorMaski"); + gl3wGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) get_proc("glGetBooleani_v"); + gl3wGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) get_proc("glGetIntegeri_v"); + gl3wEnablei = (PFNGLENABLEIPROC) get_proc("glEnablei"); + gl3wDisablei = (PFNGLDISABLEIPROC) get_proc("glDisablei"); + gl3wIsEnabledi = (PFNGLISENABLEDIPROC) get_proc("glIsEnabledi"); + gl3wBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) get_proc("glBeginTransformFeedback"); + gl3wEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) get_proc("glEndTransformFeedback"); + gl3wBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) get_proc("glBindBufferRange"); + gl3wBindBufferBase = (PFNGLBINDBUFFERBASEPROC) get_proc("glBindBufferBase"); + gl3wTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) get_proc("glTransformFeedbackVaryings"); + gl3wGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) get_proc("glGetTransformFeedbackVarying"); + gl3wClampColor = (PFNGLCLAMPCOLORPROC) get_proc("glClampColor"); + gl3wBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) get_proc("glBeginConditionalRender"); + gl3wEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) get_proc("glEndConditionalRender"); + gl3wVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) get_proc("glVertexAttribIPointer"); + gl3wGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) get_proc("glGetVertexAttribIiv"); + gl3wGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) get_proc("glGetVertexAttribIuiv"); + gl3wVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) get_proc("glVertexAttribI1i"); + gl3wVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) get_proc("glVertexAttribI2i"); + gl3wVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) get_proc("glVertexAttribI3i"); + gl3wVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) get_proc("glVertexAttribI4i"); + gl3wVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) get_proc("glVertexAttribI1ui"); + gl3wVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) get_proc("glVertexAttribI2ui"); + gl3wVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) get_proc("glVertexAttribI3ui"); + gl3wVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) get_proc("glVertexAttribI4ui"); + gl3wVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) get_proc("glVertexAttribI1iv"); + gl3wVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) get_proc("glVertexAttribI2iv"); + gl3wVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) get_proc("glVertexAttribI3iv"); + gl3wVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) get_proc("glVertexAttribI4iv"); + gl3wVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) get_proc("glVertexAttribI1uiv"); + gl3wVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) get_proc("glVertexAttribI2uiv"); + gl3wVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) get_proc("glVertexAttribI3uiv"); + gl3wVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) get_proc("glVertexAttribI4uiv"); + gl3wVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) get_proc("glVertexAttribI4bv"); + gl3wVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) get_proc("glVertexAttribI4sv"); + gl3wVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) get_proc("glVertexAttribI4ubv"); + gl3wVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) get_proc("glVertexAttribI4usv"); + gl3wGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) get_proc("glGetUniformuiv"); + gl3wBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) get_proc("glBindFragDataLocation"); + gl3wGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) get_proc("glGetFragDataLocation"); + gl3wUniform1ui = (PFNGLUNIFORM1UIPROC) get_proc("glUniform1ui"); + gl3wUniform2ui = (PFNGLUNIFORM2UIPROC) get_proc("glUniform2ui"); + gl3wUniform3ui = (PFNGLUNIFORM3UIPROC) get_proc("glUniform3ui"); + gl3wUniform4ui = (PFNGLUNIFORM4UIPROC) get_proc("glUniform4ui"); + gl3wUniform1uiv = (PFNGLUNIFORM1UIVPROC) get_proc("glUniform1uiv"); + gl3wUniform2uiv = (PFNGLUNIFORM2UIVPROC) get_proc("glUniform2uiv"); + gl3wUniform3uiv = (PFNGLUNIFORM3UIVPROC) get_proc("glUniform3uiv"); + gl3wUniform4uiv = (PFNGLUNIFORM4UIVPROC) get_proc("glUniform4uiv"); + gl3wTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) get_proc("glTexParameterIiv"); + gl3wTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) get_proc("glTexParameterIuiv"); + gl3wGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) get_proc("glGetTexParameterIiv"); + gl3wGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) get_proc("glGetTexParameterIuiv"); + gl3wClearBufferiv = (PFNGLCLEARBUFFERIVPROC) get_proc("glClearBufferiv"); + gl3wClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) get_proc("glClearBufferuiv"); + gl3wClearBufferfv = (PFNGLCLEARBUFFERFVPROC) get_proc("glClearBufferfv"); + gl3wClearBufferfi = (PFNGLCLEARBUFFERFIPROC) get_proc("glClearBufferfi"); + gl3wGetStringi = (PFNGLGETSTRINGIPROC) get_proc("glGetStringi"); + gl3wDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) get_proc("glDrawArraysInstanced"); + gl3wDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) get_proc("glDrawElementsInstanced"); + gl3wTexBuffer = (PFNGLTEXBUFFERPROC) get_proc("glTexBuffer"); + gl3wPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) get_proc("glPrimitiveRestartIndex"); + gl3wGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) get_proc("glGetInteger64i_v"); + gl3wGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) get_proc("glGetBufferParameteri64v"); + gl3wFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) get_proc("glFramebufferTexture"); + gl3wVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) get_proc("glVertexAttribDivisor"); + gl3wMinSampleShading = (PFNGLMINSAMPLESHADINGPROC) get_proc("glMinSampleShading"); + gl3wBlendEquationi = (PFNGLBLENDEQUATIONIPROC) get_proc("glBlendEquationi"); + gl3wBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC) get_proc("glBlendEquationSeparatei"); + gl3wBlendFunci = (PFNGLBLENDFUNCIPROC) get_proc("glBlendFunci"); + gl3wBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC) get_proc("glBlendFuncSeparatei"); + gl3wIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) get_proc("glIsRenderbuffer"); + gl3wBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) get_proc("glBindRenderbuffer"); + gl3wDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) get_proc("glDeleteRenderbuffers"); + gl3wGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) get_proc("glGenRenderbuffers"); + gl3wRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) get_proc("glRenderbufferStorage"); + gl3wGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) get_proc("glGetRenderbufferParameteriv"); + gl3wIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) get_proc("glIsFramebuffer"); + gl3wBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) get_proc("glBindFramebuffer"); + gl3wDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) get_proc("glDeleteFramebuffers"); + gl3wGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) get_proc("glGenFramebuffers"); + gl3wCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) get_proc("glCheckFramebufferStatus"); + gl3wFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) get_proc("glFramebufferTexture1D"); + gl3wFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) get_proc("glFramebufferTexture2D"); + gl3wFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) get_proc("glFramebufferTexture3D"); + gl3wFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) get_proc("glFramebufferRenderbuffer"); + gl3wGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) get_proc("glGetFramebufferAttachmentParameteriv"); + gl3wGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) get_proc("glGenerateMipmap"); + gl3wBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) get_proc("glBlitFramebuffer"); + gl3wRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) get_proc("glRenderbufferStorageMultisample"); + gl3wFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) get_proc("glFramebufferTextureLayer"); + gl3wMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) get_proc("glMapBufferRange"); + gl3wFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) get_proc("glFlushMappedBufferRange"); + gl3wBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) get_proc("glBindVertexArray"); + gl3wDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) get_proc("glDeleteVertexArrays"); + gl3wGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) get_proc("glGenVertexArrays"); + gl3wIsVertexArray = (PFNGLISVERTEXARRAYPROC) get_proc("glIsVertexArray"); + gl3wGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) get_proc("glGetUniformIndices"); + gl3wGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) get_proc("glGetActiveUniformsiv"); + gl3wGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) get_proc("glGetActiveUniformName"); + gl3wGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) get_proc("glGetUniformBlockIndex"); + gl3wGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) get_proc("glGetActiveUniformBlockiv"); + gl3wGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) get_proc("glGetActiveUniformBlockName"); + gl3wUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) get_proc("glUniformBlockBinding"); + gl3wCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) get_proc("glCopyBufferSubData"); + gl3wDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) get_proc("glDrawElementsBaseVertex"); + gl3wDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) get_proc("glDrawRangeElementsBaseVertex"); + gl3wDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) get_proc("glDrawElementsInstancedBaseVertex"); + gl3wMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) get_proc("glMultiDrawElementsBaseVertex"); + gl3wProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) get_proc("glProvokingVertex"); + gl3wFenceSync = (PFNGLFENCESYNCPROC) get_proc("glFenceSync"); + gl3wIsSync = (PFNGLISSYNCPROC) get_proc("glIsSync"); + gl3wDeleteSync = (PFNGLDELETESYNCPROC) get_proc("glDeleteSync"); + gl3wClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) get_proc("glClientWaitSync"); + gl3wWaitSync = (PFNGLWAITSYNCPROC) get_proc("glWaitSync"); + gl3wGetInteger64v = (PFNGLGETINTEGER64VPROC) get_proc("glGetInteger64v"); + gl3wGetSynciv = (PFNGLGETSYNCIVPROC) get_proc("glGetSynciv"); + gl3wTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) get_proc("glTexImage2DMultisample"); + gl3wTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) get_proc("glTexImage3DMultisample"); + gl3wGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) get_proc("glGetMultisamplefv"); + gl3wSampleMaski = (PFNGLSAMPLEMASKIPROC) get_proc("glSampleMaski"); + gl3wBlendEquationiARB = (PFNGLBLENDEQUATIONIARBPROC) get_proc("glBlendEquationiARB"); + gl3wBlendEquationSeparateiARB = (PFNGLBLENDEQUATIONSEPARATEIARBPROC) get_proc("glBlendEquationSeparateiARB"); + gl3wBlendFunciARB = (PFNGLBLENDFUNCIARBPROC) get_proc("glBlendFunciARB"); + gl3wBlendFuncSeparateiARB = (PFNGLBLENDFUNCSEPARATEIARBPROC) get_proc("glBlendFuncSeparateiARB"); + gl3wMinSampleShadingARB = (PFNGLMINSAMPLESHADINGARBPROC) get_proc("glMinSampleShadingARB"); + gl3wNamedStringARB = (PFNGLNAMEDSTRINGARBPROC) get_proc("glNamedStringARB"); + gl3wDeleteNamedStringARB = (PFNGLDELETENAMEDSTRINGARBPROC) get_proc("glDeleteNamedStringARB"); + gl3wCompileShaderIncludeARB = (PFNGLCOMPILESHADERINCLUDEARBPROC) get_proc("glCompileShaderIncludeARB"); + gl3wIsNamedStringARB = (PFNGLISNAMEDSTRINGARBPROC) get_proc("glIsNamedStringARB"); + gl3wGetNamedStringARB = (PFNGLGETNAMEDSTRINGARBPROC) get_proc("glGetNamedStringARB"); + gl3wGetNamedStringivARB = (PFNGLGETNAMEDSTRINGIVARBPROC) get_proc("glGetNamedStringivARB"); + gl3wBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) get_proc("glBindFragDataLocationIndexed"); + gl3wGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) get_proc("glGetFragDataIndex"); + gl3wGenSamplers = (PFNGLGENSAMPLERSPROC) get_proc("glGenSamplers"); + gl3wDeleteSamplers = (PFNGLDELETESAMPLERSPROC) get_proc("glDeleteSamplers"); + gl3wIsSampler = (PFNGLISSAMPLERPROC) get_proc("glIsSampler"); + gl3wBindSampler = (PFNGLBINDSAMPLERPROC) get_proc("glBindSampler"); + gl3wSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) get_proc("glSamplerParameteri"); + gl3wSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) get_proc("glSamplerParameteriv"); + gl3wSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) get_proc("glSamplerParameterf"); + gl3wSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) get_proc("glSamplerParameterfv"); + gl3wSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) get_proc("glSamplerParameterIiv"); + gl3wSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) get_proc("glSamplerParameterIuiv"); + gl3wGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) get_proc("glGetSamplerParameteriv"); + gl3wGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) get_proc("glGetSamplerParameterIiv"); + gl3wGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) get_proc("glGetSamplerParameterfv"); + gl3wGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) get_proc("glGetSamplerParameterIuiv"); + gl3wQueryCounter = (PFNGLQUERYCOUNTERPROC) get_proc("glQueryCounter"); + gl3wGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) get_proc("glGetQueryObjecti64v"); + gl3wGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) get_proc("glGetQueryObjectui64v"); + gl3wVertexP2ui = (PFNGLVERTEXP2UIPROC) get_proc("glVertexP2ui"); + gl3wVertexP2uiv = (PFNGLVERTEXP2UIVPROC) get_proc("glVertexP2uiv"); + gl3wVertexP3ui = (PFNGLVERTEXP3UIPROC) get_proc("glVertexP3ui"); + gl3wVertexP3uiv = (PFNGLVERTEXP3UIVPROC) get_proc("glVertexP3uiv"); + gl3wVertexP4ui = (PFNGLVERTEXP4UIPROC) get_proc("glVertexP4ui"); + gl3wVertexP4uiv = (PFNGLVERTEXP4UIVPROC) get_proc("glVertexP4uiv"); + gl3wTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC) get_proc("glTexCoordP1ui"); + gl3wTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC) get_proc("glTexCoordP1uiv"); + gl3wTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC) get_proc("glTexCoordP2ui"); + gl3wTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC) get_proc("glTexCoordP2uiv"); + gl3wTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC) get_proc("glTexCoordP3ui"); + gl3wTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC) get_proc("glTexCoordP3uiv"); + gl3wTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC) get_proc("glTexCoordP4ui"); + gl3wTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC) get_proc("glTexCoordP4uiv"); + gl3wMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC) get_proc("glMultiTexCoordP1ui"); + gl3wMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC) get_proc("glMultiTexCoordP1uiv"); + gl3wMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC) get_proc("glMultiTexCoordP2ui"); + gl3wMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC) get_proc("glMultiTexCoordP2uiv"); + gl3wMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC) get_proc("glMultiTexCoordP3ui"); + gl3wMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC) get_proc("glMultiTexCoordP3uiv"); + gl3wMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC) get_proc("glMultiTexCoordP4ui"); + gl3wMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC) get_proc("glMultiTexCoordP4uiv"); + gl3wNormalP3ui = (PFNGLNORMALP3UIPROC) get_proc("glNormalP3ui"); + gl3wNormalP3uiv = (PFNGLNORMALP3UIVPROC) get_proc("glNormalP3uiv"); + gl3wColorP3ui = (PFNGLCOLORP3UIPROC) get_proc("glColorP3ui"); + gl3wColorP3uiv = (PFNGLCOLORP3UIVPROC) get_proc("glColorP3uiv"); + gl3wColorP4ui = (PFNGLCOLORP4UIPROC) get_proc("glColorP4ui"); + gl3wColorP4uiv = (PFNGLCOLORP4UIVPROC) get_proc("glColorP4uiv"); + gl3wSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC) get_proc("glSecondaryColorP3ui"); + gl3wSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC) get_proc("glSecondaryColorP3uiv"); + gl3wVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) get_proc("glVertexAttribP1ui"); + gl3wVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) get_proc("glVertexAttribP1uiv"); + gl3wVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) get_proc("glVertexAttribP2ui"); + gl3wVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) get_proc("glVertexAttribP2uiv"); + gl3wVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) get_proc("glVertexAttribP3ui"); + gl3wVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) get_proc("glVertexAttribP3uiv"); + gl3wVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) get_proc("glVertexAttribP4ui"); + gl3wVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) get_proc("glVertexAttribP4uiv"); + gl3wDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) get_proc("glDrawArraysIndirect"); + gl3wDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) get_proc("glDrawElementsIndirect"); + gl3wUniform1d = (PFNGLUNIFORM1DPROC) get_proc("glUniform1d"); + gl3wUniform2d = (PFNGLUNIFORM2DPROC) get_proc("glUniform2d"); + gl3wUniform3d = (PFNGLUNIFORM3DPROC) get_proc("glUniform3d"); + gl3wUniform4d = (PFNGLUNIFORM4DPROC) get_proc("glUniform4d"); + gl3wUniform1dv = (PFNGLUNIFORM1DVPROC) get_proc("glUniform1dv"); + gl3wUniform2dv = (PFNGLUNIFORM2DVPROC) get_proc("glUniform2dv"); + gl3wUniform3dv = (PFNGLUNIFORM3DVPROC) get_proc("glUniform3dv"); + gl3wUniform4dv = (PFNGLUNIFORM4DVPROC) get_proc("glUniform4dv"); + gl3wUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC) get_proc("glUniformMatrix2dv"); + gl3wUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC) get_proc("glUniformMatrix3dv"); + gl3wUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC) get_proc("glUniformMatrix4dv"); + gl3wUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC) get_proc("glUniformMatrix2x3dv"); + gl3wUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC) get_proc("glUniformMatrix2x4dv"); + gl3wUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC) get_proc("glUniformMatrix3x2dv"); + gl3wUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC) get_proc("glUniformMatrix3x4dv"); + gl3wUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC) get_proc("glUniformMatrix4x2dv"); + gl3wUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC) get_proc("glUniformMatrix4x3dv"); + gl3wGetUniformdv = (PFNGLGETUNIFORMDVPROC) get_proc("glGetUniformdv"); + gl3wGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) get_proc("glGetSubroutineUniformLocation"); + gl3wGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC) get_proc("glGetSubroutineIndex"); + gl3wGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) get_proc("glGetActiveSubroutineUniformiv"); + gl3wGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) get_proc("glGetActiveSubroutineUniformName"); + gl3wGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC) get_proc("glGetActiveSubroutineName"); + gl3wUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC) get_proc("glUniformSubroutinesuiv"); + gl3wGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC) get_proc("glGetUniformSubroutineuiv"); + gl3wGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC) get_proc("glGetProgramStageiv"); + gl3wPatchParameteri = (PFNGLPATCHPARAMETERIPROC) get_proc("glPatchParameteri"); + gl3wPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC) get_proc("glPatchParameterfv"); + gl3wBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) get_proc("glBindTransformFeedback"); + gl3wDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) get_proc("glDeleteTransformFeedbacks"); + gl3wGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) get_proc("glGenTransformFeedbacks"); + gl3wIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) get_proc("glIsTransformFeedback"); + gl3wPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) get_proc("glPauseTransformFeedback"); + gl3wResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) get_proc("glResumeTransformFeedback"); + gl3wDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC) get_proc("glDrawTransformFeedback"); + gl3wDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) get_proc("glDrawTransformFeedbackStream"); + gl3wBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC) get_proc("glBeginQueryIndexed"); + gl3wEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC) get_proc("glEndQueryIndexed"); + gl3wGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC) get_proc("glGetQueryIndexediv"); + gl3wReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) get_proc("glReleaseShaderCompiler"); + gl3wShaderBinary = (PFNGLSHADERBINARYPROC) get_proc("glShaderBinary"); + gl3wGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) get_proc("glGetShaderPrecisionFormat"); + gl3wDepthRangef = (PFNGLDEPTHRANGEFPROC) get_proc("glDepthRangef"); + gl3wClearDepthf = (PFNGLCLEARDEPTHFPROC) get_proc("glClearDepthf"); + gl3wGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) get_proc("glGetProgramBinary"); + gl3wProgramBinary = (PFNGLPROGRAMBINARYPROC) get_proc("glProgramBinary"); + gl3wProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) get_proc("glProgramParameteri"); + gl3wUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) get_proc("glUseProgramStages"); + gl3wActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) get_proc("glActiveShaderProgram"); + gl3wCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) get_proc("glCreateShaderProgramv"); + gl3wBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) get_proc("glBindProgramPipeline"); + gl3wDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) get_proc("glDeleteProgramPipelines"); + gl3wGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) get_proc("glGenProgramPipelines"); + gl3wIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) get_proc("glIsProgramPipeline"); + gl3wGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) get_proc("glGetProgramPipelineiv"); + gl3wProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) get_proc("glProgramUniform1i"); + gl3wProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) get_proc("glProgramUniform1iv"); + gl3wProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) get_proc("glProgramUniform1f"); + gl3wProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) get_proc("glProgramUniform1fv"); + gl3wProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC) get_proc("glProgramUniform1d"); + gl3wProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC) get_proc("glProgramUniform1dv"); + gl3wProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) get_proc("glProgramUniform1ui"); + gl3wProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) get_proc("glProgramUniform1uiv"); + gl3wProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) get_proc("glProgramUniform2i"); + gl3wProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) get_proc("glProgramUniform2iv"); + gl3wProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) get_proc("glProgramUniform2f"); + gl3wProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) get_proc("glProgramUniform2fv"); + gl3wProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC) get_proc("glProgramUniform2d"); + gl3wProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC) get_proc("glProgramUniform2dv"); + gl3wProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) get_proc("glProgramUniform2ui"); + gl3wProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) get_proc("glProgramUniform2uiv"); + gl3wProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) get_proc("glProgramUniform3i"); + gl3wProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) get_proc("glProgramUniform3iv"); + gl3wProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) get_proc("glProgramUniform3f"); + gl3wProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) get_proc("glProgramUniform3fv"); + gl3wProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC) get_proc("glProgramUniform3d"); + gl3wProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC) get_proc("glProgramUniform3dv"); + gl3wProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) get_proc("glProgramUniform3ui"); + gl3wProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) get_proc("glProgramUniform3uiv"); + gl3wProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) get_proc("glProgramUniform4i"); + gl3wProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) get_proc("glProgramUniform4iv"); + gl3wProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) get_proc("glProgramUniform4f"); + gl3wProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) get_proc("glProgramUniform4fv"); + gl3wProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC) get_proc("glProgramUniform4d"); + gl3wProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC) get_proc("glProgramUniform4dv"); + gl3wProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) get_proc("glProgramUniform4ui"); + gl3wProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) get_proc("glProgramUniform4uiv"); + gl3wProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) get_proc("glProgramUniformMatrix2fv"); + gl3wProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) get_proc("glProgramUniformMatrix3fv"); + gl3wProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) get_proc("glProgramUniformMatrix4fv"); + gl3wProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC) get_proc("glProgramUniformMatrix2dv"); + gl3wProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC) get_proc("glProgramUniformMatrix3dv"); + gl3wProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC) get_proc("glProgramUniformMatrix4dv"); + gl3wProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) get_proc("glProgramUniformMatrix2x3fv"); + gl3wProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) get_proc("glProgramUniformMatrix3x2fv"); + gl3wProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) get_proc("glProgramUniformMatrix2x4fv"); + gl3wProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) get_proc("glProgramUniformMatrix4x2fv"); + gl3wProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) get_proc("glProgramUniformMatrix3x4fv"); + gl3wProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) get_proc("glProgramUniformMatrix4x3fv"); + gl3wProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) get_proc("glProgramUniformMatrix2x3dv"); + gl3wProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) get_proc("glProgramUniformMatrix3x2dv"); + gl3wProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) get_proc("glProgramUniformMatrix2x4dv"); + gl3wProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) get_proc("glProgramUniformMatrix4x2dv"); + gl3wProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) get_proc("glProgramUniformMatrix3x4dv"); + gl3wProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) get_proc("glProgramUniformMatrix4x3dv"); + gl3wValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) get_proc("glValidateProgramPipeline"); + gl3wGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) get_proc("glGetProgramPipelineInfoLog"); + gl3wVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC) get_proc("glVertexAttribL1d"); + gl3wVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC) get_proc("glVertexAttribL2d"); + gl3wVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC) get_proc("glVertexAttribL3d"); + gl3wVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC) get_proc("glVertexAttribL4d"); + gl3wVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC) get_proc("glVertexAttribL1dv"); + gl3wVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC) get_proc("glVertexAttribL2dv"); + gl3wVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC) get_proc("glVertexAttribL3dv"); + gl3wVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC) get_proc("glVertexAttribL4dv"); + gl3wVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC) get_proc("glVertexAttribLPointer"); + gl3wGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC) get_proc("glGetVertexAttribLdv"); + gl3wViewportArrayv = (PFNGLVIEWPORTARRAYVPROC) get_proc("glViewportArrayv"); + gl3wViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC) get_proc("glViewportIndexedf"); + gl3wViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC) get_proc("glViewportIndexedfv"); + gl3wScissorArrayv = (PFNGLSCISSORARRAYVPROC) get_proc("glScissorArrayv"); + gl3wScissorIndexed = (PFNGLSCISSORINDEXEDPROC) get_proc("glScissorIndexed"); + gl3wScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC) get_proc("glScissorIndexedv"); + gl3wDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC) get_proc("glDepthRangeArrayv"); + gl3wDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC) get_proc("glDepthRangeIndexed"); + gl3wGetFloati_v = (PFNGLGETFLOATI_VPROC) get_proc("glGetFloati_v"); + gl3wGetDoublei_v = (PFNGLGETDOUBLEI_VPROC) get_proc("glGetDoublei_v"); + gl3wCreateSyncFromCLeventARB = (PFNGLCREATESYNCFROMCLEVENTARBPROC) get_proc("glCreateSyncFromCLeventARB"); + gl3wDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) get_proc("glDebugMessageControlARB"); + gl3wDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) get_proc("glDebugMessageInsertARB"); + gl3wDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) get_proc("glDebugMessageCallbackARB"); + gl3wGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) get_proc("glGetDebugMessageLogARB"); + gl3wGetGraphicsResetStatusARB = (PFNGLGETGRAPHICSRESETSTATUSARBPROC) get_proc("glGetGraphicsResetStatusARB"); + gl3wGetnTexImageARB = (PFNGLGETNTEXIMAGEARBPROC) get_proc("glGetnTexImageARB"); + gl3wReadnPixelsARB = (PFNGLREADNPIXELSARBPROC) get_proc("glReadnPixelsARB"); + gl3wGetnCompressedTexImageARB = (PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) get_proc("glGetnCompressedTexImageARB"); + gl3wGetnUniformfvARB = (PFNGLGETNUNIFORMFVARBPROC) get_proc("glGetnUniformfvARB"); + gl3wGetnUniformivARB = (PFNGLGETNUNIFORMIVARBPROC) get_proc("glGetnUniformivARB"); + gl3wGetnUniformuivARB = (PFNGLGETNUNIFORMUIVARBPROC) get_proc("glGetnUniformuivARB"); + gl3wGetnUniformdvARB = (PFNGLGETNUNIFORMDVARBPROC) get_proc("glGetnUniformdvARB"); + gl3wDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) get_proc("glDrawArraysInstancedBaseInstance"); + gl3wDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) get_proc("glDrawElementsInstancedBaseInstance"); + gl3wDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) get_proc("glDrawElementsInstancedBaseVertexBaseInstance"); + gl3wDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) get_proc("glDrawTransformFeedbackInstanced"); + gl3wDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) get_proc("glDrawTransformFeedbackStreamInstanced"); + gl3wGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) get_proc("glGetInternalformativ"); + gl3wGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) get_proc("glGetActiveAtomicCounterBufferiv"); + gl3wBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) get_proc("glBindImageTexture"); + gl3wMemoryBarrier = (PFNGLMEMORYBARRIERPROC) get_proc("glMemoryBarrier"); + gl3wTexStorage1D = (PFNGLTEXSTORAGE1DPROC) get_proc("glTexStorage1D"); + gl3wTexStorage2D = (PFNGLTEXSTORAGE2DPROC) get_proc("glTexStorage2D"); + gl3wTexStorage3D = (PFNGLTEXSTORAGE3DPROC) get_proc("glTexStorage3D"); + gl3wTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC) get_proc("glTextureStorage1DEXT"); + gl3wTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC) get_proc("glTextureStorage2DEXT"); + gl3wTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC) get_proc("glTextureStorage3DEXT"); + gl3wDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) get_proc("glDebugMessageControl"); + gl3wDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) get_proc("glDebugMessageInsert"); + gl3wDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) get_proc("glDebugMessageCallback"); + gl3wGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) get_proc("glGetDebugMessageLog"); + gl3wPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) get_proc("glPushDebugGroup"); + gl3wPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) get_proc("glPopDebugGroup"); + gl3wObjectLabel = (PFNGLOBJECTLABELPROC) get_proc("glObjectLabel"); + gl3wGetObjectLabel = (PFNGLGETOBJECTLABELPROC) get_proc("glGetObjectLabel"); + gl3wObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) get_proc("glObjectPtrLabel"); + gl3wGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) get_proc("glGetObjectPtrLabel"); + gl3wClearBufferData = (PFNGLCLEARBUFFERDATAPROC) get_proc("glClearBufferData"); + gl3wClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC) get_proc("glClearBufferSubData"); + gl3wClearNamedBufferDataEXT = (PFNGLCLEARNAMEDBUFFERDATAEXTPROC) get_proc("glClearNamedBufferDataEXT"); + gl3wClearNamedBufferSubDataEXT = (PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) get_proc("glClearNamedBufferSubDataEXT"); + gl3wDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) get_proc("glDispatchCompute"); + gl3wDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) get_proc("glDispatchComputeIndirect"); + gl3wCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC) get_proc("glCopyImageSubData"); + gl3wTextureView = (PFNGLTEXTUREVIEWPROC) get_proc("glTextureView"); + gl3wBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) get_proc("glBindVertexBuffer"); + gl3wVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) get_proc("glVertexAttribFormat"); + gl3wVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) get_proc("glVertexAttribIFormat"); + gl3wVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC) get_proc("glVertexAttribLFormat"); + gl3wVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) get_proc("glVertexAttribBinding"); + gl3wVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) get_proc("glVertexBindingDivisor"); + gl3wVertexArrayBindVertexBufferEXT = (PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) get_proc("glVertexArrayBindVertexBufferEXT"); + gl3wVertexArrayVertexAttribFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) get_proc("glVertexArrayVertexAttribFormatEXT"); + gl3wVertexArrayVertexAttribIFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) get_proc("glVertexArrayVertexAttribIFormatEXT"); + gl3wVertexArrayVertexAttribLFormatEXT = (PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) get_proc("glVertexArrayVertexAttribLFormatEXT"); + gl3wVertexArrayVertexAttribBindingEXT = (PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) get_proc("glVertexArrayVertexAttribBindingEXT"); + gl3wVertexArrayVertexBindingDivisorEXT = (PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) get_proc("glVertexArrayVertexBindingDivisorEXT"); + gl3wFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) get_proc("glFramebufferParameteri"); + gl3wGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) get_proc("glGetFramebufferParameteriv"); + gl3wNamedFramebufferParameteriEXT = (PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) get_proc("glNamedFramebufferParameteriEXT"); + gl3wGetNamedFramebufferParameterivEXT = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) get_proc("glGetNamedFramebufferParameterivEXT"); + gl3wGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC) get_proc("glGetInternalformati64v"); + gl3wInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC) get_proc("glInvalidateTexSubImage"); + gl3wInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC) get_proc("glInvalidateTexImage"); + gl3wInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC) get_proc("glInvalidateBufferSubData"); + gl3wInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC) get_proc("glInvalidateBufferData"); + gl3wInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) get_proc("glInvalidateFramebuffer"); + gl3wInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) get_proc("glInvalidateSubFramebuffer"); + gl3wMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC) get_proc("glMultiDrawArraysIndirect"); + gl3wMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC) get_proc("glMultiDrawElementsIndirect"); + gl3wGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) get_proc("glGetProgramInterfaceiv"); + gl3wGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) get_proc("glGetProgramResourceIndex"); + gl3wGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) get_proc("glGetProgramResourceName"); + gl3wGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) get_proc("glGetProgramResourceiv"); + gl3wGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) get_proc("glGetProgramResourceLocation"); + gl3wGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) get_proc("glGetProgramResourceLocationIndex"); + gl3wShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) get_proc("glShaderStorageBlockBinding"); + gl3wTexBufferRange = (PFNGLTEXBUFFERRANGEPROC) get_proc("glTexBufferRange"); + gl3wTextureBufferRangeEXT = (PFNGLTEXTUREBUFFERRANGEEXTPROC) get_proc("glTextureBufferRangeEXT"); + gl3wTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) get_proc("glTexStorage2DMultisample"); + gl3wTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) get_proc("glTexStorage3DMultisample"); + gl3wTextureStorage2DMultisampleEXT = (PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) get_proc("glTextureStorage2DMultisampleEXT"); + gl3wTextureStorage3DMultisampleEXT = (PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) get_proc("glTextureStorage3DMultisampleEXT"); } diff --git a/RenderSystems/GL3Plus/src/windowing/SDL/OgreSDLGLSupport.cpp b/RenderSystems/GL3Plus/src/windowing/SDL/OgreSDLGLSupport.cpp index ae6f54f03b7..9c8597275df 100644 --- a/RenderSystems/GL3Plus/src/windowing/SDL/OgreSDLGLSupport.cpp +++ b/RenderSystems/GL3Plus/src/windowing/SDL/OgreSDLGLSupport.cpp @@ -31,8 +31,8 @@ void SDLGLSupport::addConfig(void) ConfigOption optFullScreen; ConfigOption optVideoMode; ConfigOption optFSAA; - ConfigOption optRTTMode; - ConfigOption optEnableFixedPipeline; + ConfigOption optRTTMode; + ConfigOption optEnableFixedPipeline; // FS setting possibilities optFullScreen.name = "Full Screen"; @@ -47,7 +47,7 @@ void SDLGLSupport::addConfig(void) for (size_t i = 0; mVideoModes[i]; i++) { char szBuf[16]; - snprintf(szBuf, 16, "%d x %d", mVideoModes[i]->w, mVideoModes[i]->h); + snprintf(szBuf, 16, "%d x %d", mVideoModes[i]->w, mVideoModes[i]->h); optVideoMode.possibleValues.push_back(szBuf); // Make the first one default if (i == 0) @@ -65,24 +65,24 @@ void SDLGLSupport::addConfig(void) optFSAA.currentValue = "0"; optFSAA.immutable = false; - optRTTMode.name = "RTT Preferred Mode"; - optRTTMode.possibleValues.push_back("FBO"); - optRTTMode.possibleValues.push_back("PBuffer"); - optRTTMode.possibleValues.push_back("Copy"); - optRTTMode.currentValue = "FBO"; - optRTTMode.immutable = false; + optRTTMode.name = "RTT Preferred Mode"; + optRTTMode.possibleValues.push_back("FBO"); + optRTTMode.possibleValues.push_back("PBuffer"); + optRTTMode.possibleValues.push_back("Copy"); + optRTTMode.currentValue = "FBO"; + optRTTMode.immutable = false; - optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; - optEnableFixedPipeline.possibleValues.push_back( "Yes" ); - optEnableFixedPipeline.possibleValues.push_back( "No" ); - optEnableFixedPipeline.currentValue = "Yes"; - optEnableFixedPipeline.immutable = false; + optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; + optEnableFixedPipeline.possibleValues.push_back( "Yes" ); + optEnableFixedPipeline.possibleValues.push_back( "No" ); + optEnableFixedPipeline.currentValue = "Yes"; + optEnableFixedPipeline.immutable = false; mOptions[optFullScreen.name] = optFullScreen; mOptions[optVideoMode.name] = optVideoMode; mOptions[optFSAA.name] = optFSAA; - mOptions[optRTTMode.name] = optRTTMode; - mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; + mOptions[optRTTMode.name] = optRTTMode; + mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; } @@ -93,7 +93,7 @@ String SDLGLSupport::validateConfig(void) RenderWindow* SDLGLSupport::createWindow(bool autoCreateWindow, GL3PlusRenderSystem* renderSystem, const String& windowTitle) { - if (autoCreateWindow) + if (autoCreateWindow) { ConfigOptionMap::iterator opt = mOptions.find("Full Screen"); if (opt == mOptions.end()) @@ -108,21 +108,21 @@ RenderWindow* SDLGLSupport::createWindow(bool autoCreateWindow, GL3PlusRenderSys if (pos == String::npos) OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Invalid Video Mode provided", "SDLGLSupport::createWindow"); - // Parse FSAA config - NameValuePairList winOptions; - winOptions["title"] = windowTitle; + // Parse FSAA config + NameValuePairList winOptions; + winOptions["title"] = windowTitle; int fsaa_x_samples = 0; opt = mOptions.find("FSAA"); if(opt != mOptions.end()) { - winOptions["FSAA"] = opt->second.currentValue; + winOptions["FSAA"] = opt->second.currentValue; } - opt = mOptions.find("Fixed Pipeline Enabled"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow"); - bool enableFixedPipeline = (opt->second.currentValue == "Yes"); - renderSystem->setFixedPipelineEnabled(enableFixedPipeline); + opt = mOptions.find("Fixed Pipeline Enabled"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow"); + bool enableFixedPipeline = (opt->second.currentValue == "Yes"); + renderSystem->setFixedPipelineEnabled(enableFixedPipeline); unsigned int w = StringConverter::parseUnsignedInt(val.substr(0, pos)); unsigned int h = StringConverter::parseUnsignedInt(val.substr(pos + 1)); @@ -133,18 +133,18 @@ RenderWindow* SDLGLSupport::createWindow(bool autoCreateWindow, GL3PlusRenderSys else { // XXX What is the else? - return NULL; + return NULL; } } RenderWindow* SDLGLSupport::newWindow(const String &name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) + bool fullScreen, const NameValuePairList *miscParams) { - SDLWindow* window = new SDLWindow(); - window->create(name, width, height, fullScreen, miscParams); - return window; + SDLWindow* window = new SDLWindow(); + window->create(name, width, height, fullScreen, miscParams); + return window; } void SDLGLSupport::start() diff --git a/RenderSystems/GL3Plus/src/windowing/gtk/OgreGTKGLSupport.cpp b/RenderSystems/GL3Plus/src/windowing/gtk/OgreGTKGLSupport.cpp index 14e1d311d47..beeb1425ac2 100644 --- a/RenderSystems/GL3Plus/src/windowing/gtk/OgreGTKGLSupport.cpp +++ b/RenderSystems/GL3Plus/src/windowing/gtk/OgreGTKGLSupport.cpp @@ -91,7 +91,7 @@ String GTKGLSupport::validateConfig() RenderWindow* GTKGLSupport::createWindow(bool autoCreateWindow, GL3PlusRenderSystem* renderSystem, - const String& windowTitle) + const String& windowTitle) { if (autoCreateWindow) { @@ -130,7 +130,7 @@ RenderWindow* GTKGLSupport::newWindow(const String& name, unsigned int width, depthBuffer, parentWindowHandle); //if(!_ogre_widget) - // _ogre_widget = window->get_ogre_widget(); + // _ogre_widget = window->get_ogre_widget(); // Copy some important information for future reference, for example // for when the context is needed @@ -161,33 +161,33 @@ void GTKGLSupport::stop() void GTKGLSupport::begin_context(RenderTarget *_target) { - // Support nested contexts, in which case.. nothing happens - ++_context_ref; - if (_context_ref == 1) { - if(_target) { - // Begin a specific context - OGREWidget *_ogre_widget = static_cast(_target)->get_ogre_widget(); + // Support nested contexts, in which case.. nothing happens + ++_context_ref; + if (_context_ref == 1) { + if(_target) { + // Begin a specific context + OGREWidget *_ogre_widget = static_cast(_target)->get_ogre_widget(); - _ogre_widget->get_gl_window()->gl_begin(_ogre_widget->get_gl_context()); - } else { - // Begin a generic main context - _main_window->gl_begin(_main_context); - } - } + _ogre_widget->get_gl_window()->gl_begin(_ogre_widget->get_gl_context()); + } else { + // Begin a generic main context + _main_window->gl_begin(_main_context); + } + } } void GTKGLSupport::end_context() { - --_context_ref; - if(_context_ref < 0) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Too many contexts destroyed!", "GTKGLSupport::end_context"); - if (_context_ref == 0) - { - // XX is this enough? (_main_window might not be the current window, - // but we can never be sure the previous rendering window - // even still exists) - _main_window->gl_end(); - } + --_context_ref; + if(_context_ref < 0) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Too many contexts destroyed!", "GTKGLSupport::end_context"); + if (_context_ref == 0) + { + // XX is this enough? (_main_window might not be the current window, + // but we can never be sure the previous rendering window + // even still exists) + _main_window->gl_end(); + } } void GTKGLSupport::initialiseExtensions(void) @@ -209,14 +209,14 @@ bool GTKGLSupport::checkMinGLVersion(const String& v) const bool GTKGLSupport::checkExtension(const String& ext) const { - // query_gl_extension needs an active context, doesn't matter which one - if (_context_ref == 0) - _main_window->gl_begin(_main_context); + // query_gl_extension needs an active context, doesn't matter which one + if (_context_ref == 0) + _main_window->gl_begin(_main_context); - bool result = Gdk::GL::query_gl_extension(ext.c_str()); + bool result = Gdk::GL::query_gl_extension(ext.c_str()); - if (_context_ref == 0) - _main_window->gl_end(); + if (_context_ref == 0) + _main_window->gl_end(); } void* GTKGLSupport::getProcAddress(const String& procname) @@ -225,6 +225,6 @@ void* GTKGLSupport::getProcAddress(const String& procname) } Glib::RefPtr GTKGLSupport::getMainContext() const { - return _main_context; + return _main_context; } diff --git a/RenderSystems/GL3Plus/src/windowing/gtk/OgreGTKWindow.cpp b/RenderSystems/GL3Plus/src/windowing/gtk/OgreGTKWindow.cpp index 65b6629d362..bc8b9dd7827 100644 --- a/RenderSystems/GL3Plus/src/windowing/gtk/OgreGTKWindow.cpp +++ b/RenderSystems/GL3Plus/src/windowing/gtk/OgreGTKWindow.cpp @@ -35,7 +35,7 @@ THE SOFTWARE. using namespace Ogre; OGREWidget::OGREWidget(bool useDepthBuffer) : - Gtk::GL::DrawingArea() + Gtk::GL::DrawingArea() { Glib::RefPtr glconfig; @@ -46,7 +46,7 @@ OGREWidget::OGREWidget(bool useDepthBuffer) : glconfig = Gdk::GL::Config::create(mode); if (glconfig.is_null()) { - LogManager::getSingleton().logMessage("[gtk] GLCONFIG BLOWUP"); + LogManager::getSingleton().logMessage("[gtk] GLCONFIG BLOWUP"); } // Inherit GL context from Ogre main context @@ -60,16 +60,16 @@ OGREWidget::OGREWidget(bool useDepthBuffer) : // - Change aspect ratio GTKWindow::GTKWindow(): - mGtkWindow(0) + mGtkWindow(0) { - //kit = Gtk::Main::instance(); - - // Should this move to GTKGLSupport? - // Gtk::GL::init(0, NULL); - // Already done in GTKGLSupport - - mWidth = 0; - mHeight = 0; + //kit = Gtk::Main::instance(); + + // Should this move to GTKGLSupport? + // Gtk::GL::init(0, NULL); + // Already done in GTKGLSupport + + mWidth = 0; + mHeight = 0; } GTKWindow::~GTKWindow() @@ -95,77 +95,77 @@ void GTKWindow::create(const String& name, unsigned int width, unsigned int heig bool fullScreen, int left, int top, bool depthBuffer, void* miscParam, ...) { - mName = name; - mWidth = width; - mHeight = height; - - if(!miscParam) { - mGtkWindow = new Gtk::Window(); - mGtkWindow->set_title(mName); - - if (fullScreen) - { - mIsFullScreen = true; - mGtkWindow->set_decorated(false); - mGtkWindow->fullscreen(); - } - else - { - mIsFullScreen = false; - mGtkWindow->set_default_size(mWidth, mHeight); - mGtkWindow->move(left, top); - } - } else { - // If miscParam is not 0, a parent widget has been passed in, - // we will handle this later on after the widget has been created. - } - - ogre = Gtk::manage(new OGREWidget(depthBuffer)); - ogre->set_size_request(width, height); - - ogre->signal_delete_event().connect(SigC::slot(*this, >KWindow::on_delete_event)); - ogre->signal_expose_event().connect(SigC::slot(*this, >KWindow::on_expose_event)); - - if(mGtkWindow) { - mGtkWindow->add(*ogre); - mGtkWindow->show_all(); - } - if(miscParam) { - // Attach it! - // Note that the parent widget *must* be visible already at this point, - // or the widget won't get realized in time for the GLinit that follows - // this call. This is usually the case for Glade generated windows, anyway. - reinterpret_cast(miscParam)->add(*ogre); - ogre->show(); - } - //ogre->realize(); + mName = name; + mWidth = width; + mHeight = height; + + if(!miscParam) { + mGtkWindow = new Gtk::Window(); + mGtkWindow->set_title(mName); + + if (fullScreen) + { + mIsFullScreen = true; + mGtkWindow->set_decorated(false); + mGtkWindow->fullscreen(); + } + else + { + mIsFullScreen = false; + mGtkWindow->set_default_size(mWidth, mHeight); + mGtkWindow->move(left, top); + } + } else { + // If miscParam is not 0, a parent widget has been passed in, + // we will handle this later on after the widget has been created. + } + + ogre = Gtk::manage(new OGREWidget(depthBuffer)); + ogre->set_size_request(width, height); + + ogre->signal_delete_event().connect(SigC::slot(*this, >KWindow::on_delete_event)); + ogre->signal_expose_event().connect(SigC::slot(*this, >KWindow::on_expose_event)); + + if(mGtkWindow) { + mGtkWindow->add(*ogre); + mGtkWindow->show_all(); + } + if(miscParam) { + // Attach it! + // Note that the parent widget *must* be visible already at this point, + // or the widget won't get realized in time for the GLinit that follows + // this call. This is usually the case for Glade generated windows, anyway. + reinterpret_cast(miscParam)->add(*ogre); + ogre->show(); + } + //ogre->realize(); } void GTKWindow::destroy() { - Root::getSingleton().getRenderSystem()->detachRenderTarget( this->getName() ); - // We could detach the widget from its parent and destroy it here too, - // but then again, it is managed so we rely on GTK to destroy it. - delete mGtkWindow; - mGtkWindow = 0; + Root::getSingleton().getRenderSystem()->detachRenderTarget( this->getName() ); + // We could detach the widget from its parent and destroy it here too, + // but then again, it is managed so we rely on GTK to destroy it. + delete mGtkWindow; + mGtkWindow = 0; } void GTKWindow::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) { - if((fullScreen) && (!mIsFullScreen)) - { - mIsFullScreen = true; - mGtkWindow->fullscreen(); - ogre->set_size_request(width, height); - } - else if((!fullScreen) && (mIsFullScreen)) - { - mIsFullScreen = false; - mGtkWindow->unfullscreen(); - ogre->set_size_request(width, height); - } + if((fullScreen) && (!mIsFullScreen)) + { + mIsFullScreen = true; + mGtkWindow->fullscreen(); + ogre->set_size_request(width, height); + } + else if((!fullScreen) && (mIsFullScreen)) + { + mIsFullScreen = false; + mGtkWindow->unfullscreen(); + ogre->set_size_request(width, height); + } } bool GTKWindow::isActive() const @@ -180,47 +180,47 @@ bool GTKWindow::isClosed() const void GTKWindow::reposition(int left, int top) { - if(mGtkWindow) - mGtkWindow->move(left, top); + if(mGtkWindow) + mGtkWindow->move(left, top); } void GTKWindow::resize(unsigned int width, unsigned int height) { - if(mGtkWindow) - mGtkWindow->resize(width, height); + if(mGtkWindow) + mGtkWindow->resize(width, height); } void GTKWindow::swapBuffers() { - Glib::RefPtr glwindow = ogre->get_gl_window(); - glwindow->swap_buffers(); + Glib::RefPtr glwindow = ogre->get_gl_window(); + glwindow->swap_buffers(); } void GTKWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) { - if ((dst.left < 0) || (dst.right > mWidth) || - (dst.top < 0) || (dst.bottom > mHeight) || - (dst.front != 0) || (dst.back != 1)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid box.", - "GTKWindow::copyContentsToMemory" ); - } - - if (buffer == FB_AUTO) - { - buffer = mIsFullScreen? FB_FRONT : FB_BACK; - } - - GLenum format = Ogre::GL3PlusPixelUtil::getGLOriginFormat(dst.format); - GLenum type = Ogre::GL3PlusPixelUtil::getGLOriginDataType(dst.format); - - if ((format == GL_NONE) || (type == 0)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unsupported format.", - "GTKWindow::copyContentsToMemory" ); - } + if ((dst.left < 0) || (dst.right > mWidth) || + (dst.top < 0) || (dst.bottom > mHeight) || + (dst.front != 0) || (dst.back != 1)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid box.", + "GTKWindow::copyContentsToMemory" ); + } + + if (buffer == FB_AUTO) + { + buffer = mIsFullScreen? FB_FRONT : FB_BACK; + } + + GLenum format = Ogre::GL3PlusPixelUtil::getGLOriginFormat(dst.format); + GLenum type = Ogre::GL3PlusPixelUtil::getGLOriginDataType(dst.format); + + if ((format == GL_NONE) || (type == 0)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Unsupported format.", + "GTKWindow::copyContentsToMemory" ); + } if(dst.getWidth() != dst.rowPitch) { @@ -232,7 +232,7 @@ void GTKWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) glPixelStorei(GL_PACK_ALIGNMENT, 1); } - glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); + glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); glReadPixels((GLint)0, (GLint)(mHeight - dst.getHeight()), (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(), format, type, dst.getTopLeftFrontPixelPtr()); @@ -245,26 +245,26 @@ void GTKWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) void GTKWindow::getCustomAttribute( const String& name, void* pData ) { - if( name == "GTKMMWINDOW" ) - { - Gtk::Window **win = static_cast(pData); - // Oh, the burdens of multiple inheritance - *win = mGtkWindow; - return; - } - else if( name == "GTKGLMMWIDGET" ) - { - Gtk::GL::DrawingArea **widget = static_cast(pData); - *widget = ogre; - return; - } - else if( name == "isTexture" ) - { - bool *b = reinterpret_cast< bool * >( pData ); - *b = false; - return; - } - RenderWindow::getCustomAttribute(name, pData); + if( name == "GTKMMWINDOW" ) + { + Gtk::Window **win = static_cast(pData); + // Oh, the burdens of multiple inheritance + *win = mGtkWindow; + return; + } + else if( name == "GTKGLMMWIDGET" ) + { + Gtk::GL::DrawingArea **widget = static_cast(pData); + *widget = ogre; + return; + } + else if( name == "isTexture" ) + { + bool *b = reinterpret_cast< bool * >( pData ); + *b = false; + return; + } + RenderWindow::getCustomAttribute(name, pData); } diff --git a/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32Context.cpp b/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32Context.cpp index 68fce04e6b4..efd299d8367 100644 --- a/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32Context.cpp +++ b/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32Context.cpp @@ -44,56 +44,56 @@ namespace Ogre { Win32Context::~Win32Context() { - // NB have to do this is subclass to ensure any methods called back - // are on this subclass and not half-destructed superclass - GL3PlusRenderSystem *rs = static_cast(Root::getSingleton().getRenderSystem()); - rs->_unregisterContext(this); + // NB have to do this is subclass to ensure any methods called back + // are on this subclass and not half-destructed superclass + GL3PlusRenderSystem *rs = static_cast(Root::getSingleton().getRenderSystem()); + rs->_unregisterContext(this); } void Win32Context::setCurrent() { wglMakeCurrent(mHDC, mGlrc); } - void Win32Context::endCurrent() - { - wglMakeCurrent(NULL, NULL); - } + void Win32Context::endCurrent() + { + wglMakeCurrent(NULL, NULL); + } - GL3PlusContext* Win32Context::clone() const - { - // Create new context based on own HDC - HGLRC newCtx = wglCreateContext(mHDC); - - if (!newCtx) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Error calling wglCreateContext", "Win32Context::clone"); - } + GL3PlusContext* Win32Context::clone() const + { + // Create new context based on own HDC + HGLRC newCtx = wglCreateContext(mHDC); + + if (!newCtx) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Error calling wglCreateContext", "Win32Context::clone"); + } - HGLRC oldrc = wglGetCurrentContext(); - HDC oldhdc = wglGetCurrentDC(); - wglMakeCurrent(NULL, NULL); - // Share lists with old context - if (!wglShareLists(mGlrc, newCtx)) - { - String errorMsg = translateWGLError(); - wglDeleteContext(newCtx); - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, String("wglShareLists() failed: ") + errorMsg, "Win32Context::clone"); - } - // restore old context - wglMakeCurrent(oldhdc, oldrc); - + HGLRC oldrc = wglGetCurrentContext(); + HDC oldhdc = wglGetCurrentDC(); + wglMakeCurrent(NULL, NULL); + // Share lists with old context + if (!wglShareLists(mGlrc, newCtx)) + { + String errorMsg = translateWGLError(); + wglDeleteContext(newCtx); + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, String("wglShareLists() failed: ") + errorMsg, "Win32Context::clone"); + } + // restore old context + wglMakeCurrent(oldhdc, oldrc); + - return new Win32Context(mHDC, newCtx); - } + return new Win32Context(mHDC, newCtx); + } - void Win32Context::releaseContext() - { - if (mGlrc != NULL) - { - wglDeleteContext(mGlrc); - mGlrc = NULL; - mHDC = NULL; - } - } + void Win32Context::releaseContext() + { + if (mGlrc != NULL) + { + wglDeleteContext(mGlrc); + mGlrc = NULL; + mHDC = NULL; + } + } } diff --git a/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32GLSupport.cpp b/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32GLSupport.cpp index 394b89493f8..ff94462e608 100644 --- a/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32GLSupport.cpp +++ b/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32GLSupport.cpp @@ -40,221 +40,221 @@ using namespace Ogre; namespace Ogre { - Win32GLSupport::Win32GLSupport() + Win32GLSupport::Win32GLSupport() : mInitialWindow(0) , mHasPixelFormatARB(false) , mHasMultisample(false) - , mHasHardwareGamma(false) - , mWglChoosePixelFormat(0) + , mHasHardwareGamma(false) + , mWglChoosePixelFormat(0) { - // immediately test WGL_ARB_pixel_format and FSAA support - // so we can set configuration options appropriately - initialiseWGL(); + // immediately test WGL_ARB_pixel_format and FSAA support + // so we can set configuration options appropriately + initialiseWGL(); } - template void remove_duplicates(C& c) - { - std::sort(c.begin(), c.end()); - typename C::iterator p = std::unique(c.begin(), c.end()); - c.erase(p, c.end()); - } - - void Win32GLSupport::addConfig() - { - //TODO: EnumDisplayDevices http://msdn.microsoft.com/library/en-us/gdi/devcons_2303.asp - /*vector DisplayDevices; - DISPLAY_DEVICE DisplayDevice; - DisplayDevice.cb = sizeof(DISPLAY_DEVICE); - DWORD i=0; - while (EnumDisplayDevices(NULL, i++, &DisplayDevice, 0) { - DisplayDevices.push_back(DisplayDevice.DeviceName); - }*/ - - ConfigOption optFullScreen; - ConfigOption optVideoMode; - ConfigOption optColourDepth; - ConfigOption optDisplayFrequency; - ConfigOption optVSync; - ConfigOption optVSyncInterval; - ConfigOption optFSAA; - ConfigOption optRTTMode; - ConfigOption optSRGB; - ConfigOption optEnableFixedPipeline; - - // FS setting possibilities - optFullScreen.name = "Full Screen"; - optFullScreen.possibleValues.push_back("Yes"); - optFullScreen.possibleValues.push_back("No"); - optFullScreen.currentValue = "Yes"; - optFullScreen.immutable = false; - - // Video mode possibilities - DEVMODE DevMode; - DevMode.dmSize = sizeof(DEVMODE); - optVideoMode.name = "Video Mode"; - optVideoMode.immutable = false; - for (DWORD i = 0; EnumDisplaySettings(NULL, i, &DevMode); ++i) - { - if (DevMode.dmBitsPerPel < 16 || DevMode.dmPelsHeight < 480) - continue; - mDevModes.push_back(DevMode); - StringStream str; - str << DevMode.dmPelsWidth << " x " << DevMode.dmPelsHeight; - optVideoMode.possibleValues.push_back(str.str()); - } - remove_duplicates(optVideoMode.possibleValues); - optVideoMode.currentValue = optVideoMode.possibleValues.front(); - - optColourDepth.name = "Colour Depth"; - optColourDepth.immutable = false; - optColourDepth.currentValue.clear(); - - optDisplayFrequency.name = "Display Frequency"; - optDisplayFrequency.immutable = false; + template void remove_duplicates(C& c) + { + std::sort(c.begin(), c.end()); + typename C::iterator p = std::unique(c.begin(), c.end()); + c.erase(p, c.end()); + } + + void Win32GLSupport::addConfig() + { + //TODO: EnumDisplayDevices http://msdn.microsoft.com/library/en-us/gdi/devcons_2303.asp + /*vector DisplayDevices; + DISPLAY_DEVICE DisplayDevice; + DisplayDevice.cb = sizeof(DISPLAY_DEVICE); + DWORD i=0; + while (EnumDisplayDevices(NULL, i++, &DisplayDevice, 0) { + DisplayDevices.push_back(DisplayDevice.DeviceName); + }*/ + + ConfigOption optFullScreen; + ConfigOption optVideoMode; + ConfigOption optColourDepth; + ConfigOption optDisplayFrequency; + ConfigOption optVSync; + ConfigOption optVSyncInterval; + ConfigOption optFSAA; + ConfigOption optRTTMode; + ConfigOption optSRGB; + ConfigOption optEnableFixedPipeline; + + // FS setting possibilities + optFullScreen.name = "Full Screen"; + optFullScreen.possibleValues.push_back("Yes"); + optFullScreen.possibleValues.push_back("No"); + optFullScreen.currentValue = "Yes"; + optFullScreen.immutable = false; + + // Video mode possibilities + DEVMODE DevMode; + DevMode.dmSize = sizeof(DEVMODE); + optVideoMode.name = "Video Mode"; + optVideoMode.immutable = false; + for (DWORD i = 0; EnumDisplaySettings(NULL, i, &DevMode); ++i) + { + if (DevMode.dmBitsPerPel < 16 || DevMode.dmPelsHeight < 480) + continue; + mDevModes.push_back(DevMode); + StringStream str; + str << DevMode.dmPelsWidth << " x " << DevMode.dmPelsHeight; + optVideoMode.possibleValues.push_back(str.str()); + } + remove_duplicates(optVideoMode.possibleValues); + optVideoMode.currentValue = optVideoMode.possibleValues.front(); + + optColourDepth.name = "Colour Depth"; + optColourDepth.immutable = false; + optColourDepth.currentValue.clear(); + + optDisplayFrequency.name = "Display Frequency"; + optDisplayFrequency.immutable = false; optDisplayFrequency.currentValue.clear(); - optVSync.name = "VSync"; - optVSync.immutable = false; - optVSync.possibleValues.push_back("No"); - optVSync.possibleValues.push_back("Yes"); - optVSync.currentValue = "No"; - - optVSyncInterval.name = "VSync Interval"; - optVSyncInterval.immutable = false; - optVSyncInterval.possibleValues.push_back( "1" ); - optVSyncInterval.possibleValues.push_back( "2" ); - optVSyncInterval.possibleValues.push_back( "3" ); - optVSyncInterval.possibleValues.push_back( "4" ); - optVSyncInterval.currentValue = "1"; - - optFSAA.name = "FSAA"; - optFSAA.immutable = false; - optFSAA.possibleValues.push_back("0"); - for (vector::type::iterator it = mFSAALevels.begin(); it != mFSAALevels.end(); ++it) - { - String val = StringConverter::toString(*it); - optFSAA.possibleValues.push_back(val); - /* not implementing CSAA in GL for now - if (*it >= 8) - optFSAA.possibleValues.push_back(val + " [Quality]"); - */ - - } - optFSAA.currentValue = "0"; - - optRTTMode.name = "RTT Preferred Mode"; - optRTTMode.possibleValues.push_back("FBO"); - optRTTMode.possibleValues.push_back("PBuffer"); - optRTTMode.possibleValues.push_back("Copy"); - optRTTMode.currentValue = "FBO"; - optRTTMode.immutable = false; - - - // SRGB on auto window - optSRGB.name = "sRGB Gamma Conversion"; - optSRGB.possibleValues.push_back("Yes"); - optSRGB.possibleValues.push_back("No"); - optSRGB.currentValue = "No"; - optSRGB.immutable = false; - - optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; - optEnableFixedPipeline.possibleValues.push_back( "Yes" ); - optEnableFixedPipeline.possibleValues.push_back( "No" ); - optEnableFixedPipeline.currentValue = "Yes"; - optEnableFixedPipeline.immutable = false; - - mOptions[optFullScreen.name] = optFullScreen; - mOptions[optVideoMode.name] = optVideoMode; - mOptions[optColourDepth.name] = optColourDepth; - mOptions[optDisplayFrequency.name] = optDisplayFrequency; - mOptions[optVSync.name] = optVSync; - mOptions[optVSyncInterval.name] = optVSyncInterval; - mOptions[optFSAA.name] = optFSAA; - mOptions[optRTTMode.name] = optRTTMode; - mOptions[optSRGB.name] = optSRGB; - mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; - - refreshConfig(); - } - - void Win32GLSupport::refreshConfig() - { - ConfigOptionMap::iterator optVideoMode = mOptions.find("Video Mode"); - ConfigOptionMap::iterator moptColourDepth = mOptions.find("Colour Depth"); - ConfigOptionMap::iterator moptDisplayFrequency = mOptions.find("Display Frequency"); - if(optVideoMode == mOptions.end() || moptColourDepth == mOptions.end() || moptDisplayFrequency == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find mOptions!", "Win32GLSupport::refreshConfig"); - ConfigOption* optColourDepth = &moptColourDepth->second; - ConfigOption* optDisplayFrequency = &moptDisplayFrequency->second; - - const String& val = optVideoMode->second.currentValue; - String::size_type pos = val.find('x'); - if (pos == String::npos) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid Video Mode provided", "Win32GLSupport::refreshConfig"); - DWORD width = StringConverter::parseUnsignedInt(val.substr(0, pos)); - DWORD height = StringConverter::parseUnsignedInt(val.substr(pos+1, String::npos)); - - for(vector::type::const_iterator i = mDevModes.begin(); i != mDevModes.end(); ++i) - { - if (i->dmPelsWidth != width || i->dmPelsHeight != height) - continue; - optColourDepth->possibleValues.push_back(StringConverter::toString((unsigned int)i->dmBitsPerPel)); - optDisplayFrequency->possibleValues.push_back(StringConverter::toString((unsigned int)i->dmDisplayFrequency)); - } - remove_duplicates(optColourDepth->possibleValues); - remove_duplicates(optDisplayFrequency->possibleValues); - optColourDepth->currentValue = optColourDepth->possibleValues.back(); - bool freqValid = std::find(optDisplayFrequency->possibleValues.begin(), - optDisplayFrequency->possibleValues.end(), - optDisplayFrequency->currentValue) != optDisplayFrequency->possibleValues.end(); - - if ( (optDisplayFrequency->currentValue != "N/A") && !freqValid ) - optDisplayFrequency->currentValue = optDisplayFrequency->possibleValues.front(); - } - - void Win32GLSupport::setConfigOption(const String &name, const String &value) - { - ConfigOptionMap::iterator it = mOptions.find(name); - - // Update - if(it != mOptions.end()) - it->second.currentValue = value; - else - { + optVSync.name = "VSync"; + optVSync.immutable = false; + optVSync.possibleValues.push_back("No"); + optVSync.possibleValues.push_back("Yes"); + optVSync.currentValue = "No"; + + optVSyncInterval.name = "VSync Interval"; + optVSyncInterval.immutable = false; + optVSyncInterval.possibleValues.push_back( "1" ); + optVSyncInterval.possibleValues.push_back( "2" ); + optVSyncInterval.possibleValues.push_back( "3" ); + optVSyncInterval.possibleValues.push_back( "4" ); + optVSyncInterval.currentValue = "1"; + + optFSAA.name = "FSAA"; + optFSAA.immutable = false; + optFSAA.possibleValues.push_back("0"); + for (vector::type::iterator it = mFSAALevels.begin(); it != mFSAALevels.end(); ++it) + { + String val = StringConverter::toString(*it); + optFSAA.possibleValues.push_back(val); + /* not implementing CSAA in GL for now + if (*it >= 8) + optFSAA.possibleValues.push_back(val + " [Quality]"); + */ + + } + optFSAA.currentValue = "0"; + + optRTTMode.name = "RTT Preferred Mode"; + optRTTMode.possibleValues.push_back("FBO"); + optRTTMode.possibleValues.push_back("PBuffer"); + optRTTMode.possibleValues.push_back("Copy"); + optRTTMode.currentValue = "FBO"; + optRTTMode.immutable = false; + + + // SRGB on auto window + optSRGB.name = "sRGB Gamma Conversion"; + optSRGB.possibleValues.push_back("Yes"); + optSRGB.possibleValues.push_back("No"); + optSRGB.currentValue = "No"; + optSRGB.immutable = false; + + optEnableFixedPipeline.name = "Fixed Pipeline Enabled"; + optEnableFixedPipeline.possibleValues.push_back( "Yes" ); + optEnableFixedPipeline.possibleValues.push_back( "No" ); + optEnableFixedPipeline.currentValue = "Yes"; + optEnableFixedPipeline.immutable = false; + + mOptions[optFullScreen.name] = optFullScreen; + mOptions[optVideoMode.name] = optVideoMode; + mOptions[optColourDepth.name] = optColourDepth; + mOptions[optDisplayFrequency.name] = optDisplayFrequency; + mOptions[optVSync.name] = optVSync; + mOptions[optVSyncInterval.name] = optVSyncInterval; + mOptions[optFSAA.name] = optFSAA; + mOptions[optRTTMode.name] = optRTTMode; + mOptions[optSRGB.name] = optSRGB; + mOptions[optEnableFixedPipeline.name] = optEnableFixedPipeline; + + refreshConfig(); + } + + void Win32GLSupport::refreshConfig() + { + ConfigOptionMap::iterator optVideoMode = mOptions.find("Video Mode"); + ConfigOptionMap::iterator moptColourDepth = mOptions.find("Colour Depth"); + ConfigOptionMap::iterator moptDisplayFrequency = mOptions.find("Display Frequency"); + if(optVideoMode == mOptions.end() || moptColourDepth == mOptions.end() || moptDisplayFrequency == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find mOptions!", "Win32GLSupport::refreshConfig"); + ConfigOption* optColourDepth = &moptColourDepth->second; + ConfigOption* optDisplayFrequency = &moptDisplayFrequency->second; + + const String& val = optVideoMode->second.currentValue; + String::size_type pos = val.find('x'); + if (pos == String::npos) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid Video Mode provided", "Win32GLSupport::refreshConfig"); + DWORD width = StringConverter::parseUnsignedInt(val.substr(0, pos)); + DWORD height = StringConverter::parseUnsignedInt(val.substr(pos+1, String::npos)); + + for(vector::type::const_iterator i = mDevModes.begin(); i != mDevModes.end(); ++i) + { + if (i->dmPelsWidth != width || i->dmPelsHeight != height) + continue; + optColourDepth->possibleValues.push_back(StringConverter::toString((unsigned int)i->dmBitsPerPel)); + optDisplayFrequency->possibleValues.push_back(StringConverter::toString((unsigned int)i->dmDisplayFrequency)); + } + remove_duplicates(optColourDepth->possibleValues); + remove_duplicates(optDisplayFrequency->possibleValues); + optColourDepth->currentValue = optColourDepth->possibleValues.back(); + bool freqValid = std::find(optDisplayFrequency->possibleValues.begin(), + optDisplayFrequency->possibleValues.end(), + optDisplayFrequency->currentValue) != optDisplayFrequency->possibleValues.end(); + + if ( (optDisplayFrequency->currentValue != "N/A") && !freqValid ) + optDisplayFrequency->currentValue = optDisplayFrequency->possibleValues.front(); + } + + void Win32GLSupport::setConfigOption(const String &name, const String &value) + { + ConfigOptionMap::iterator it = mOptions.find(name); + + // Update + if(it != mOptions.end()) + it->second.currentValue = value; + else + { StringStream str; str << "Option named '" << name << "' does not exist."; - OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, str.str(), "Win32GLSupport::setConfigOption" ); - } - - if( name == "Video Mode" ) - refreshConfig(); - - if( name == "Full Screen" ) - { - it = mOptions.find( "Display Frequency" ); - if( value == "No" ) - { - it->second.currentValue = "N/A"; - it->second.immutable = true; - } - else - { - if (it->second.currentValue.empty() || it->second.currentValue == "N/A") - it->second.currentValue = it->second.possibleValues.front(); - it->second.immutable = false; - } - } - } - - String Win32GLSupport::validateConfig() - { - // TODO, DX9 - return BLANKSTRING; - } - - RenderWindow* Win32GLSupport::createWindow(bool autoCreateWindow, GL3PlusRenderSystem* renderSystem, const String& windowTitle) - { - if (autoCreateWindow) + OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, str.str(), "Win32GLSupport::setConfigOption" ); + } + + if( name == "Video Mode" ) + refreshConfig(); + + if( name == "Full Screen" ) + { + it = mOptions.find( "Display Frequency" ); + if( value == "No" ) + { + it->second.currentValue = "N/A"; + it->second.immutable = true; + } + else + { + if (it->second.currentValue.empty() || it->second.currentValue == "N/A") + it->second.currentValue = it->second.possibleValues.front(); + it->second.immutable = false; + } + } + } + + String Win32GLSupport::validateConfig() + { + // TODO, DX9 + return BLANKSTRING; + } + + RenderWindow* Win32GLSupport::createWindow(bool autoCreateWindow, GL3PlusRenderSystem* renderSystem, const String& windowTitle) + { + if (autoCreateWindow) { ConfigOptionMap::iterator opt = mOptions.find("Full Screen"); if (opt == mOptions.end()) @@ -269,308 +269,308 @@ namespace Ogre { if (pos == String::npos) OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid Video Mode provided", "Win32GLSupport::createWindow"); - unsigned int w = StringConverter::parseUnsignedInt(val.substr(0, pos)); + unsigned int w = StringConverter::parseUnsignedInt(val.substr(0, pos)); unsigned int h = StringConverter::parseUnsignedInt(val.substr(pos + 1)); - // Parse optional parameters - NameValuePairList winOptions; - opt = mOptions.find("Colour Depth"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Colour Depth options!", "Win32GLSupport::createWindow"); - unsigned int colourDepth = - StringConverter::parseUnsignedInt(opt->second.currentValue); - winOptions["colourDepth"] = StringConverter::toString(colourDepth); - - opt = mOptions.find("VSync"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync options!", "Win32GLSupport::createWindow"); - bool vsync = (opt->second.currentValue == "Yes"); - winOptions["vsync"] = StringConverter::toString(vsync); - - opt = mOptions.find("VSync Interval"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync Interval options!", "Win32GLSupport::createWindow"); - winOptions["vsyncInterval"] = opt->second.currentValue; - - opt = mOptions.find("Display Frequency"); - if (opt != mOptions.end()) - { - unsigned int displayFrequency = - StringConverter::parseUnsignedInt(opt->second.currentValue); - winOptions["displayFrequency"] = StringConverter::toString(displayFrequency); - } - - opt = mOptions.find("FSAA"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find FSAA options!", "Win32GLSupport::createWindow"); - StringVector aavalues = StringUtil::split(opt->second.currentValue, " ", 1); - unsigned int multisample = StringConverter::parseUnsignedInt(aavalues[0]); - String multisample_hint; - if (aavalues.size() > 1) - multisample_hint = aavalues[1]; - - opt = mOptions.find("Fixed Pipeline Enabled"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow"); - bool enableFixedPipeline = (opt->second.currentValue == "Yes"); - renderSystem->setFixedPipelineEnabled(enableFixedPipeline); - - winOptions["FSAA"] = StringConverter::toString(multisample); - winOptions["FSAAHint"] = multisample_hint; - - opt = mOptions.find("sRGB Gamma Conversion"); - if (opt == mOptions.end()) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find sRGB options!", "Win32GLSupport::createWindow"); - bool hwGamma = (opt->second.currentValue == "Yes"); - winOptions["gamma"] = StringConverter::toString(hwGamma); + // Parse optional parameters + NameValuePairList winOptions; + opt = mOptions.find("Colour Depth"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Colour Depth options!", "Win32GLSupport::createWindow"); + unsigned int colourDepth = + StringConverter::parseUnsignedInt(opt->second.currentValue); + winOptions["colourDepth"] = StringConverter::toString(colourDepth); + + opt = mOptions.find("VSync"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync options!", "Win32GLSupport::createWindow"); + bool vsync = (opt->second.currentValue == "Yes"); + winOptions["vsync"] = StringConverter::toString(vsync); + + opt = mOptions.find("VSync Interval"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find VSync Interval options!", "Win32GLSupport::createWindow"); + winOptions["vsyncInterval"] = opt->second.currentValue; + + opt = mOptions.find("Display Frequency"); + if (opt != mOptions.end()) + { + unsigned int displayFrequency = + StringConverter::parseUnsignedInt(opt->second.currentValue); + winOptions["displayFrequency"] = StringConverter::toString(displayFrequency); + } + + opt = mOptions.find("FSAA"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find FSAA options!", "Win32GLSupport::createWindow"); + StringVector aavalues = StringUtil::split(opt->second.currentValue, " ", 1); + unsigned int multisample = StringConverter::parseUnsignedInt(aavalues[0]); + String multisample_hint; + if (aavalues.size() > 1) + multisample_hint = aavalues[1]; + + opt = mOptions.find("Fixed Pipeline Enabled"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find Fixed Pipeline enabled options!", "Win32GLSupport::createWindow"); + bool enableFixedPipeline = (opt->second.currentValue == "Yes"); + renderSystem->setFixedPipelineEnabled(enableFixedPipeline); + + winOptions["FSAA"] = StringConverter::toString(multisample); + winOptions["FSAAHint"] = multisample_hint; + + opt = mOptions.find("sRGB Gamma Conversion"); + if (opt == mOptions.end()) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Can't find sRGB options!", "Win32GLSupport::createWindow"); + bool hwGamma = (opt->second.currentValue == "Yes"); + winOptions["gamma"] = StringConverter::toString(hwGamma); return renderSystem->_createRenderWindow(windowTitle, w, h, fullscreen, &winOptions); } else { // XXX What is the else? - return NULL; + return NULL; + } + } + + BOOL CALLBACK Win32GLSupport::sCreateMonitorsInfoEnumProc( + HMONITOR hMonitor, // handle to display monitor + HDC hdcMonitor, // handle to monitor DC + LPRECT lprcMonitor, // monitor intersection rectangle + LPARAM dwData // data + ) + { + DisplayMonitorInfoList* pArrMonitorsInfo = (DisplayMonitorInfoList*)dwData; + + // Get monitor info + DisplayMonitorInfo displayMonitorInfo; + + displayMonitorInfo.hMonitor = hMonitor; + + memset(&displayMonitorInfo.monitorInfoEx, 0, sizeof(MONITORINFOEX)); + displayMonitorInfo.monitorInfoEx.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &displayMonitorInfo.monitorInfoEx); + + pArrMonitorsInfo->push_back(displayMonitorInfo); + + return TRUE; + } + + + RenderWindow* Win32GLSupport::newWindow(const String &name, unsigned int width, + unsigned int height, bool fullScreen, const NameValuePairList *miscParams) + { + Win32Window* window = OGRE_NEW Win32Window(*this); + NameValuePairList newParams; + + if (miscParams != NULL) + { + newParams = *miscParams; + miscParams = &newParams; + + NameValuePairList::const_iterator monitorIndexIt = miscParams->find("monitorIndex"); + HMONITOR hMonitor = NULL; + int monitorIndex = -1; + + // If monitor index found, try to assign the monitor handle based on it. + if (monitorIndexIt != miscParams->end()) + { + if (mMonitorInfoList.empty()) + EnumDisplayMonitors(NULL, NULL, sCreateMonitorsInfoEnumProc, (LPARAM)&mMonitorInfoList); + + monitorIndex = StringConverter::parseInt(monitorIndexIt->second); + if (monitorIndex < (int)mMonitorInfoList.size()) + { + hMonitor = mMonitorInfoList[monitorIndex].hMonitor; + } + } + // If we didn't specified the monitor index, or if it didn't find it + if (hMonitor == NULL) + { + POINT windowAnchorPoint; + + NameValuePairList::const_iterator opt; + int left = -1; + int top = -1; + + if ((opt = newParams.find("left")) != newParams.end()) + left = StringConverter::parseInt(opt->second); + + if ((opt = newParams.find("top")) != newParams.end()) + top = StringConverter::parseInt(opt->second); + + // Fill in anchor point. + windowAnchorPoint.x = left; + windowAnchorPoint.y = top; + + + // Get the nearest monitor to this window. + hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY); + } + + newParams["monitorHandle"] = StringConverter::toString((size_t)hMonitor); } - } - - BOOL CALLBACK Win32GLSupport::sCreateMonitorsInfoEnumProc( - HMONITOR hMonitor, // handle to display monitor - HDC hdcMonitor, // handle to monitor DC - LPRECT lprcMonitor, // monitor intersection rectangle - LPARAM dwData // data - ) - { - DisplayMonitorInfoList* pArrMonitorsInfo = (DisplayMonitorInfoList*)dwData; - - // Get monitor info - DisplayMonitorInfo displayMonitorInfo; - - displayMonitorInfo.hMonitor = hMonitor; - - memset(&displayMonitorInfo.monitorInfoEx, 0, sizeof(MONITORINFOEX)); - displayMonitorInfo.monitorInfoEx.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(hMonitor, &displayMonitorInfo.monitorInfoEx); - - pArrMonitorsInfo->push_back(displayMonitorInfo); - - return TRUE; - } - - - RenderWindow* Win32GLSupport::newWindow(const String &name, unsigned int width, - unsigned int height, bool fullScreen, const NameValuePairList *miscParams) - { - Win32Window* window = OGRE_NEW Win32Window(*this); - NameValuePairList newParams; - - if (miscParams != NULL) - { - newParams = *miscParams; - miscParams = &newParams; - - NameValuePairList::const_iterator monitorIndexIt = miscParams->find("monitorIndex"); - HMONITOR hMonitor = NULL; - int monitorIndex = -1; - - // If monitor index found, try to assign the monitor handle based on it. - if (monitorIndexIt != miscParams->end()) - { - if (mMonitorInfoList.empty()) - EnumDisplayMonitors(NULL, NULL, sCreateMonitorsInfoEnumProc, (LPARAM)&mMonitorInfoList); - - monitorIndex = StringConverter::parseInt(monitorIndexIt->second); - if (monitorIndex < (int)mMonitorInfoList.size()) - { - hMonitor = mMonitorInfoList[monitorIndex].hMonitor; - } - } - // If we didn't specified the monitor index, or if it didn't find it - if (hMonitor == NULL) - { - POINT windowAnchorPoint; - - NameValuePairList::const_iterator opt; - int left = -1; - int top = -1; - - if ((opt = newParams.find("left")) != newParams.end()) - left = StringConverter::parseInt(opt->second); - - if ((opt = newParams.find("top")) != newParams.end()) - top = StringConverter::parseInt(opt->second); - - // Fill in anchor point. - windowAnchorPoint.x = left; - windowAnchorPoint.y = top; - - - // Get the nearest monitor to this window. - hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY); - } - - newParams["monitorHandle"] = StringConverter::toString((size_t)hMonitor); - } - - window->create(name, width, height, fullScreen, miscParams); - - if(!mInitialWindow) - mInitialWindow = window; - return window; - } - - void Win32GLSupport::start() - { - LogManager::getSingleton().logMessage("*** Starting Win32GL Subsystem ***"); - } - - void Win32GLSupport::stop() - { - LogManager::getSingleton().logMessage("*** Stopping Win32GL Subsystem ***"); - mInitialWindow = 0; // Since there is no removeWindow, although there should be... - } - - void Win32GLSupport::initialiseExtensions() - { - assert(mInitialWindow); - // First, initialise the normal extensions - GL3PlusSupport::initialiseExtensions(); - - // Check for W32 specific extensions probe function - PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = - (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); - if(!_wglGetExtensionsStringARB) - return; - const char *wgl_extensions = _wglGetExtensionsStringARB(mInitialWindow->getHDC()); + + window->create(name, width, height, fullScreen, miscParams); + + if(!mInitialWindow) + mInitialWindow = window; + return window; + } + + void Win32GLSupport::start() + { + LogManager::getSingleton().logMessage("*** Starting Win32GL Subsystem ***"); + } + + void Win32GLSupport::stop() + { + LogManager::getSingleton().logMessage("*** Stopping Win32GL Subsystem ***"); + mInitialWindow = 0; // Since there is no removeWindow, although there should be... + } + + void Win32GLSupport::initialiseExtensions() + { + assert(mInitialWindow); + // First, initialise the normal extensions + GL3PlusSupport::initialiseExtensions(); + + // Check for W32 specific extensions probe function + PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = + (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); + if(!_wglGetExtensionsStringARB) + return; + const char *wgl_extensions = _wglGetExtensionsStringARB(mInitialWindow->getHDC()); LogManager::getSingleton().stream() - << "Supported WGL extensions: " << wgl_extensions; - // Parse them, and add them to the main list - StringStream ext; + << "Supported WGL extensions: " << wgl_extensions; + // Parse them, and add them to the main list + StringStream ext; String instr; - ext << wgl_extensions; + ext << wgl_extensions; while(ext >> instr) { extensionList.insert(instr); } - } - - - void* Win32GLSupport::getProcAddress(const String& procname) - { - return (void*)wglGetProcAddress( procname.c_str() ); - } - void Win32GLSupport::initialiseWGL() - { - // wglGetProcAddress does not work without an active OpenGL context, - // but we need wglChoosePixelFormatARB's address before we can - // create our main window. Thank you very much, Microsoft! - // - // The solution is to create a dummy OpenGL window first, and then - // test for WGL_ARB_pixel_format support. If it is not supported, - // we make sure to never call the ARB pixel format functions. - // - // If is is supported, we call the pixel format functions at least once - // to initialise them (pointers are stored by glprocs.h). We can also - // take this opportunity to enumerate the valid FSAA modes. - - LPCSTR dummyText = "OgreWglDummy"; + } + + + void* Win32GLSupport::getProcAddress(const String& procname) + { + return (void*)wglGetProcAddress( procname.c_str() ); + } + void Win32GLSupport::initialiseWGL() + { + // wglGetProcAddress does not work without an active OpenGL context, + // but we need wglChoosePixelFormatARB's address before we can + // create our main window. Thank you very much, Microsoft! + // + // The solution is to create a dummy OpenGL window first, and then + // test for WGL_ARB_pixel_format support. If it is not supported, + // we make sure to never call the ARB pixel format functions. + // + // If is is supported, we call the pixel format functions at least once + // to initialise them (pointers are stored by glprocs.h). We can also + // take this opportunity to enumerate the valid FSAA modes. + + LPCSTR dummyText = "OgreWglDummy"; #ifdef OGRE_STATIC_LIB - HINSTANCE hinst = GetModuleHandle( NULL ); + HINSTANCE hinst = GetModuleHandle( NULL ); #else # if OGRE_DEBUG_MODE == 1 - HINSTANCE hinst = GetModuleHandle("RenderSystem_GL_d.dll"); + HINSTANCE hinst = GetModuleHandle("RenderSystem_GL_d.dll"); # else - HINSTANCE hinst = GetModuleHandle("RenderSystem_GL.dll"); + HINSTANCE hinst = GetModuleHandle("RenderSystem_GL.dll"); # endif #endif - - WNDCLASS dummyClass; - memset(&dummyClass, 0, sizeof(WNDCLASS)); - dummyClass.style = CS_OWNDC; - dummyClass.hInstance = hinst; - dummyClass.lpfnWndProc = dummyWndProc; - dummyClass.lpszClassName = dummyText; - RegisterClass(&dummyClass); - - HWND hwnd = CreateWindow(dummyText, dummyText, - WS_POPUP | WS_CLIPCHILDREN, - 0, 0, 32, 32, 0, 0, hinst, 0); - - // if a simple CreateWindow fails, then boy are we in trouble... - if (hwnd == NULL) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "CreateWindow() failed", "Win32GLSupport::initializeWGL"); - - - // no chance of failure and no need to release thanks to CS_OWNDC - HDC hdc = GetDC(hwnd); - - // assign a simple OpenGL pixel format that everyone supports - PIXELFORMATDESCRIPTOR pfd; - memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.cColorBits = 16; - pfd.cDepthBits = 15; - pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - - // if these fail, wglCreateContext will also quietly fail - int format; - if ((format = ChoosePixelFormat(hdc, &pfd)) != 0) - SetPixelFormat(hdc, format, &pfd); - - HGLRC hrc = wglCreateContext(hdc); - if (hrc) - { - HGLRC oldrc = wglGetCurrentContext(); - HDC oldhdc = wglGetCurrentDC(); - // if wglMakeCurrent fails, wglGetProcAddress will return null - wglMakeCurrent(hdc, hrc); - - PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = - (PFNWGLGETEXTENSIONSSTRINGARBPROC) - wglGetProcAddress("wglGetExtensionsStringARB"); - - // check for pixel format and multisampling support - if (_wglGetExtensionsStringARB) - { - std::istringstream wglexts(_wglGetExtensionsStringARB(hdc)); - std::string ext; - while (wglexts >> ext) - { - if (ext == "WGL_ARB_pixel_format") - mHasPixelFormatARB = true; - else if (ext == "WGL_ARB_multisample") - mHasMultisample = true; - else if (ext == "WGL_EXT_framebuffer_sRGB") - mHasHardwareGamma = true; - } - } - - if (mHasPixelFormatARB && mHasMultisample) - { - // enumerate all formats w/ multisampling - static const int iattr[] = { - WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, - WGL_SUPPORT_OPENGL_ARB, GL_TRUE, - WGL_DOUBLE_BUFFER_ARB, GL_TRUE, - WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, - WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, + + WNDCLASS dummyClass; + memset(&dummyClass, 0, sizeof(WNDCLASS)); + dummyClass.style = CS_OWNDC; + dummyClass.hInstance = hinst; + dummyClass.lpfnWndProc = dummyWndProc; + dummyClass.lpszClassName = dummyText; + RegisterClass(&dummyClass); + + HWND hwnd = CreateWindow(dummyText, dummyText, + WS_POPUP | WS_CLIPCHILDREN, + 0, 0, 32, 32, 0, 0, hinst, 0); + + // if a simple CreateWindow fails, then boy are we in trouble... + if (hwnd == NULL) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "CreateWindow() failed", "Win32GLSupport::initializeWGL"); + + + // no chance of failure and no need to release thanks to CS_OWNDC + HDC hdc = GetDC(hwnd); + + // assign a simple OpenGL pixel format that everyone supports + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.cColorBits = 16; + pfd.cDepthBits = 15; + pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + + // if these fail, wglCreateContext will also quietly fail + int format; + if ((format = ChoosePixelFormat(hdc, &pfd)) != 0) + SetPixelFormat(hdc, format, &pfd); + + HGLRC hrc = wglCreateContext(hdc); + if (hrc) + { + HGLRC oldrc = wglGetCurrentContext(); + HDC oldhdc = wglGetCurrentDC(); + // if wglMakeCurrent fails, wglGetProcAddress will return null + wglMakeCurrent(hdc, hrc); + + PFNWGLGETEXTENSIONSSTRINGARBPROC _wglGetExtensionsStringARB = + (PFNWGLGETEXTENSIONSSTRINGARBPROC) + wglGetProcAddress("wglGetExtensionsStringARB"); + + // check for pixel format and multisampling support + if (_wglGetExtensionsStringARB) + { + std::istringstream wglexts(_wglGetExtensionsStringARB(hdc)); + std::string ext; + while (wglexts >> ext) + { + if (ext == "WGL_ARB_pixel_format") + mHasPixelFormatARB = true; + else if (ext == "WGL_ARB_multisample") + mHasMultisample = true; + else if (ext == "WGL_EXT_framebuffer_sRGB") + mHasHardwareGamma = true; + } + } + + if (mHasPixelFormatARB && mHasMultisample) + { + // enumerate all formats w/ multisampling + static const int iattr[] = { + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, + WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, /* We are no matter about the colour, depth and stencil buffers here - WGL_COLOR_BITS_ARB, 24, - WGL_ALPHA_BITS_ARB, 8, - WGL_DEPTH_BITS_ARB, 24, - WGL_STENCIL_BITS_ARB, 8, + WGL_COLOR_BITS_ARB, 24, + WGL_ALPHA_BITS_ARB, 8, + WGL_DEPTH_BITS_ARB, 24, + WGL_STENCIL_BITS_ARB, 8, */ - WGL_SAMPLES_ARB, 2, - 0 - }; - int formats[256]; - unsigned int count; + WGL_SAMPLES_ARB, 2, + 0 + }; + int formats[256]; + unsigned int count; // cheating here. wglChoosePixelFormatARB procc address needed later on // when a valid GL context does not exist and glew is not initialized yet. - PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribiv = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB"); + PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribiv = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB"); - mWglChoosePixelFormat = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); + mWglChoosePixelFormat = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); if (mWglChoosePixelFormat(hdc, iattr, 0, 256, formats, &count)) @@ -586,111 +586,111 @@ namespace Ogre { } remove_duplicates(mFSAALevels); } - } - - wglMakeCurrent(oldhdc, oldrc); - wglDeleteContext(hrc); - } - - // clean up our dummy window and class - DestroyWindow(hwnd); - UnregisterClass(dummyText, hinst); - } - - LRESULT Win32GLSupport::dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp) - { - return DefWindowProc(hwnd, umsg, wp, lp); - } - - bool Win32GLSupport::selectPixelFormat(HDC hdc, int colourDepth, int multisample, bool hwGamma) - { - PIXELFORMATDESCRIPTOR pfd; - memset(&pfd, 0, sizeof(pfd)); - pfd.nSize = sizeof(pfd); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = (colourDepth > 16)? 24 : colourDepth; - pfd.cAlphaBits = (colourDepth > 16)? 8 : 0; - pfd.cDepthBits = 24; - pfd.cStencilBits = 8; - - int format = 0; - - int useHwGamma = hwGamma? GL_TRUE : GL_FALSE; - - if (multisample && (!mHasMultisample || !mHasPixelFormatARB)) - return false; - - if (hwGamma && !mHasHardwareGamma) - return false; - - if ((multisample || hwGamma) && mWglChoosePixelFormat) - { - - // Use WGL to test extended caps (multisample, sRGB) - vector::type attribList; - attribList.push_back(WGL_DRAW_TO_WINDOW_ARB); attribList.push_back(GL_TRUE); - attribList.push_back(WGL_SUPPORT_OPENGL_ARB); attribList.push_back(GL_TRUE); - attribList.push_back(WGL_DOUBLE_BUFFER_ARB); attribList.push_back(GL_TRUE); - attribList.push_back(WGL_SAMPLE_BUFFERS_ARB); attribList.push_back(GL_TRUE); - attribList.push_back(WGL_ACCELERATION_ARB); attribList.push_back(WGL_FULL_ACCELERATION_ARB); - attribList.push_back(WGL_COLOR_BITS_ARB); attribList.push_back(pfd.cColorBits); - attribList.push_back(WGL_ALPHA_BITS_ARB); attribList.push_back(pfd.cAlphaBits); - attribList.push_back(WGL_DEPTH_BITS_ARB); attribList.push_back(24); - attribList.push_back(WGL_STENCIL_BITS_ARB); attribList.push_back(8); - attribList.push_back(WGL_SAMPLES_ARB); attribList.push_back(multisample); - if (useHwGamma && mHasHardwareGamma) - { - attribList.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT); attribList.push_back(GL_TRUE); - } - // terminator - attribList.push_back(0); - - - UINT nformats; - // ChoosePixelFormatARB proc address was obtained when setting up a dummy GL context in initialiseWGL() - // since glew hasn't been initialized yet, we have to cheat and use the previously obtained address - if (!mWglChoosePixelFormat(hdc, &(attribList[0]), NULL, 1, &format, &nformats) || nformats <= 0) - return false; - } - else - { - format = ChoosePixelFormat(hdc, &pfd); - } - - - return (format && SetPixelFormat(hdc, format, &pfd)); - } - - unsigned int Win32GLSupport::getDisplayMonitorCount() const - { - if (mMonitorInfoList.empty()) - EnumDisplayMonitors(NULL, NULL, sCreateMonitorsInfoEnumProc, (LPARAM)&mMonitorInfoList); - - return (unsigned int)mMonitorInfoList.size(); - } - - String translateWGLError() - { - int winError = GetLastError(); - char* errDesc; - int i; - - errDesc = new char[255]; - // Try windows errors first - i = FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - winError, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) errDesc, - 255, - NULL - ); - - return String(errDesc); - } + } + + wglMakeCurrent(oldhdc, oldrc); + wglDeleteContext(hrc); + } + + // clean up our dummy window and class + DestroyWindow(hwnd); + UnregisterClass(dummyText, hinst); + } + + LRESULT Win32GLSupport::dummyWndProc(HWND hwnd, UINT umsg, WPARAM wp, LPARAM lp) + { + return DefWindowProc(hwnd, umsg, wp, lp); + } + + bool Win32GLSupport::selectPixelFormat(HDC hdc, int colourDepth, int multisample, bool hwGamma) + { + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = (colourDepth > 16)? 24 : colourDepth; + pfd.cAlphaBits = (colourDepth > 16)? 8 : 0; + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; + + int format = 0; + + int useHwGamma = hwGamma? GL_TRUE : GL_FALSE; + + if (multisample && (!mHasMultisample || !mHasPixelFormatARB)) + return false; + + if (hwGamma && !mHasHardwareGamma) + return false; + + if ((multisample || hwGamma) && mWglChoosePixelFormat) + { + + // Use WGL to test extended caps (multisample, sRGB) + vector::type attribList; + attribList.push_back(WGL_DRAW_TO_WINDOW_ARB); attribList.push_back(GL_TRUE); + attribList.push_back(WGL_SUPPORT_OPENGL_ARB); attribList.push_back(GL_TRUE); + attribList.push_back(WGL_DOUBLE_BUFFER_ARB); attribList.push_back(GL_TRUE); + attribList.push_back(WGL_SAMPLE_BUFFERS_ARB); attribList.push_back(GL_TRUE); + attribList.push_back(WGL_ACCELERATION_ARB); attribList.push_back(WGL_FULL_ACCELERATION_ARB); + attribList.push_back(WGL_COLOR_BITS_ARB); attribList.push_back(pfd.cColorBits); + attribList.push_back(WGL_ALPHA_BITS_ARB); attribList.push_back(pfd.cAlphaBits); + attribList.push_back(WGL_DEPTH_BITS_ARB); attribList.push_back(24); + attribList.push_back(WGL_STENCIL_BITS_ARB); attribList.push_back(8); + attribList.push_back(WGL_SAMPLES_ARB); attribList.push_back(multisample); + if (useHwGamma && mHasHardwareGamma) + { + attribList.push_back(WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT); attribList.push_back(GL_TRUE); + } + // terminator + attribList.push_back(0); + + + UINT nformats; + // ChoosePixelFormatARB proc address was obtained when setting up a dummy GL context in initialiseWGL() + // since glew hasn't been initialized yet, we have to cheat and use the previously obtained address + if (!mWglChoosePixelFormat(hdc, &(attribList[0]), NULL, 1, &format, &nformats) || nformats <= 0) + return false; + } + else + { + format = ChoosePixelFormat(hdc, &pfd); + } + + + return (format && SetPixelFormat(hdc, format, &pfd)); + } + + unsigned int Win32GLSupport::getDisplayMonitorCount() const + { + if (mMonitorInfoList.empty()) + EnumDisplayMonitors(NULL, NULL, sCreateMonitorsInfoEnumProc, (LPARAM)&mMonitorInfoList); + + return (unsigned int)mMonitorInfoList.size(); + } + + String translateWGLError() + { + int winError = GetLastError(); + char* errDesc; + int i; + + errDesc = new char[255]; + // Try windows errors first + i = FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + winError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) errDesc, + 255, + NULL + ); + + return String(errDesc); + } } diff --git a/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32Window.cpp b/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32Window.cpp index 5adf532f505..5478f8b9e0a 100644 --- a/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32Window.cpp +++ b/RenderSystems/GL3Plus/src/windowing/win32/OgreWin32Window.cpp @@ -45,880 +45,880 @@ THE SOFTWARE. namespace Ogre { - #define _MAX_CLASS_NAME_ 128 - - Win32Window::Win32Window(Win32GLSupport &glsupport): - mGLSupport(glsupport), - mContext(0) - { - mIsFullScreen = false; - mHWnd = 0; - mGlrc = 0; - mIsExternal = false; - mIsExternalGLControl = false; - mIsExternalGLContext = false; - mSizing = false; - mClosed = false; - mHidden = false; - mVSync = false; - mVSyncInterval = 1; - mDisplayFrequency = 0; - mActive = false; - mDeviceName = NULL; - mWindowedWinStyle = 0; - mFullscreenWinStyle = 0; - } - - Win32Window::~Win32Window() - { - destroy(); - } - - void Win32Window::create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams) - { - // destroy current window, if any - if (mHWnd) - destroy(); + #define _MAX_CLASS_NAME_ 128 + + Win32Window::Win32Window(Win32GLSupport &glsupport): + mGLSupport(glsupport), + mContext(0) + { + mIsFullScreen = false; + mHWnd = 0; + mGlrc = 0; + mIsExternal = false; + mIsExternalGLControl = false; + mIsExternalGLContext = false; + mSizing = false; + mClosed = false; + mHidden = false; + mVSync = false; + mVSyncInterval = 1; + mDisplayFrequency = 0; + mActive = false; + mDeviceName = NULL; + mWindowedWinStyle = 0; + mFullscreenWinStyle = 0; + } + + Win32Window::~Win32Window() + { + destroy(); + } + + void Win32Window::create(const String& name, unsigned int width, unsigned int height, + bool fullScreen, const NameValuePairList *miscParams) + { + // destroy current window, if any + if (mHWnd) + destroy(); #ifdef OGRE_STATIC_LIB - HINSTANCE hInst = GetModuleHandle( NULL ); + HINSTANCE hInst = GetModuleHandle( NULL ); #else # if OGRE_DEBUG_MODE == 1 - HINSTANCE hInst = GetModuleHandle("RenderSystem_GL_d.dll"); + HINSTANCE hInst = GetModuleHandle("RenderSystem_GL_d.dll"); # else - HINSTANCE hInst = GetModuleHandle("RenderSystem_GL.dll"); + HINSTANCE hInst = GetModuleHandle("RenderSystem_GL.dll"); # endif #endif - mHWnd = 0; - mName = name; - mIsFullScreen = fullScreen; - mClosed = false; - mDisplayFrequency = 0; - mDepthBufferPoolId = DepthBuffer::POOL_DEFAULT; - mColourDepth = mIsFullScreen? 32 : GetDeviceCaps(GetDC(0), BITSPIXEL); - int left = -1; // Defaults to screen center - int top = -1; // Defaults to screen center - HWND parent = 0; - String title = name; - bool hidden = false; - String border; - bool outerSize = false; - bool hwGamma = false; - bool enableDoubleClick = false; - int monitorIndex = -1; - HMONITOR hMonitor = NULL; - - if(miscParams) - { - // Get variable-length params - NameValuePairList::const_iterator opt; - NameValuePairList::const_iterator end = miscParams->end(); - - if ((opt = miscParams->find("title")) != end) - title = opt->second; - - if ((opt = miscParams->find("left")) != end) - left = StringConverter::parseInt(opt->second); - - if ((opt = miscParams->find("top")) != end) - top = StringConverter::parseInt(opt->second); - - if ((opt = miscParams->find("depthBuffer")) != end) - { - mDepthBufferPoolId = StringConverter::parseBool(opt->second) ? - DepthBuffer::POOL_DEFAULT : DepthBuffer::POOL_NO_DEPTH; - } - - if ((opt = miscParams->find("vsync")) != end) - mVSync = StringConverter::parseBool(opt->second); - - if ((opt = miscParams->find("hidden")) != end) - hidden = StringConverter::parseBool(opt->second); - - if ((opt = miscParams->find("vsyncInterval")) != end) - mVSyncInterval = StringConverter::parseUnsignedInt(opt->second); - - if ((opt = miscParams->find("FSAA")) != end) - mFSAA = StringConverter::parseUnsignedInt(opt->second); - - if ((opt = miscParams->find("FSAAHint")) != end) - mFSAAHint = opt->second; - - if ((opt = miscParams->find("gamma")) != end) - hwGamma = StringConverter::parseBool(opt->second); - - if ((opt = miscParams->find("externalWindowHandle")) != end) - { - mHWnd = (HWND)StringConverter::parseSizeT(opt->second); - if (mHWnd) - { - mIsExternal = true; - mIsFullScreen = false; - } - - if ((opt = miscParams->find("externalGLControl")) != end) { - mIsExternalGLControl = StringConverter::parseBool(opt->second); - } - } - if ((opt = miscParams->find("externalGLContext")) != end) - { - mGlrc = (HGLRC)StringConverter::parseUnsignedLong(opt->second); - if( mGlrc ) - mIsExternalGLContext = true; - } - - // window border style - opt = miscParams->find("border"); - if(opt != miscParams->end()) - border = opt->second; - // set outer dimensions? - opt = miscParams->find("outerDimensions"); - if(opt != miscParams->end()) - outerSize = StringConverter::parseBool(opt->second); - - // only available with fullscreen - if ((opt = miscParams->find("displayFrequency")) != end) - mDisplayFrequency = StringConverter::parseUnsignedInt(opt->second); - if ((opt = miscParams->find("colourDepth")) != end) - { - mColourDepth = StringConverter::parseUnsignedInt(opt->second); - if (!mIsFullScreen) - { - // make sure we don't exceed desktop colour depth - if ((int)mColourDepth > GetDeviceCaps(GetDC(0), BITSPIXEL)) - mColourDepth = GetDeviceCaps(GetDC(0), BITSPIXEL); - } - } - - // incompatible with fullscreen - if ((opt = miscParams->find("parentWindowHandle")) != end) - parent = (HWND)StringConverter::parseSizeT(opt->second); - - - // monitor index - if ((opt = miscParams->find("monitorIndex")) != end) - monitorIndex = StringConverter::parseInt(opt->second); - - // monitor handle - if ((opt = miscParams->find("monitorHandle")) != end) - hMonitor = (HMONITOR)StringConverter::parseInt(opt->second); - - // enable double click messages - if ((opt = miscParams->find("enableDoubleClick")) != end) - enableDoubleClick = StringConverter::parseBool(opt->second); - - } - - if (!mIsExternal) - { - DWORD dwStyleEx = 0; - MONITORINFOEX monitorInfoEx; - RECT rc; - - // If we didn't specified the adapter index, or if it didn't find it - if (hMonitor == NULL) - { - POINT windowAnchorPoint; - - // Fill in anchor point. - windowAnchorPoint.x = left; - windowAnchorPoint.y = top; - - - // Get the nearest monitor to this window. - hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY); - } - - // Get the target monitor info - memset(&monitorInfoEx, 0, sizeof(MONITORINFOEX)); - monitorInfoEx.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(hMonitor, &monitorInfoEx); - - size_t devNameLen = strlen(monitorInfoEx.szDevice); - mDeviceName = new char[devNameLen + 1]; - - strcpy(mDeviceName, monitorInfoEx.szDevice); - - // Update window style flags. - mFullscreenWinStyle = (hidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN | WS_POPUP; - mWindowedWinStyle = (hidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN; - - if (parent) - { - mWindowedWinStyle |= WS_CHILD; - } - else - { - if (border == "none") - mWindowedWinStyle |= WS_POPUP; - else if (border == "fixed") - mWindowedWinStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | - WS_SYSMENU | WS_MINIMIZEBOX; - else - mWindowedWinStyle |= WS_OVERLAPPEDWINDOW; - - } - - - // No specified top left -> Center the window in the middle of the monitor - if (left == -1 || top == -1) - { - int screenw = monitorInfoEx.rcWork.right - monitorInfoEx.rcWork.left; - int screenh = monitorInfoEx.rcWork.bottom - monitorInfoEx.rcWork.top; - - unsigned int winWidth, winHeight; - adjustWindow(width, height, &winWidth, &winHeight); - - // clamp window dimensions to screen size - int outerw = (winWidth < screenw)? winWidth : screenw; - int outerh = (winHeight < screenh)? winHeight : screenh; - - if (left == -1) - left = monitorInfoEx.rcWork.left + (screenw - outerw) / 2; - else if (monitorIndex != -1) - left += monitorInfoEx.rcWork.left; - - if (top == -1) - top = monitorInfoEx.rcWork.top + (screenh - outerh) / 2; - else if (monitorIndex != -1) - top += monitorInfoEx.rcWork.top; - } - else if (monitorIndex != -1) - { - left += monitorInfoEx.rcWork.left; - top += monitorInfoEx.rcWork.top; - } - - mWidth = width; - mHeight = height; - mTop = top; - mLeft = left; - - if (mIsFullScreen) - { - dwStyleEx |= WS_EX_TOPMOST; - mTop = monitorInfoEx.rcMonitor.top; - mLeft = monitorInfoEx.rcMonitor.left; - } - else - { - int screenw = GetSystemMetrics(SM_CXSCREEN); - int screenh = GetSystemMetrics(SM_CYSCREEN); - - if (!outerSize) - { - // Calculate window dimensions required - // to get the requested client area - SetRect(&rc, 0, 0, mWidth, mHeight); - AdjustWindowRect(&rc, getWindowStyle(fullScreen), false); - mWidth = rc.right - rc.left; - mHeight = rc.bottom - rc.top; - - // Clamp window rect to the nearest display monitor. - if (mLeft < monitorInfoEx.rcWork.left) - mLeft = monitorInfoEx.rcWork.left; - - if (mTop < monitorInfoEx.rcWork.top) - mTop = monitorInfoEx.rcWork.top; - - if ((int)mWidth > monitorInfoEx.rcWork.right - mLeft) - mWidth = monitorInfoEx.rcWork.right - mLeft; - - if ((int)mHeight > monitorInfoEx.rcWork.bottom - mTop) - mHeight = monitorInfoEx.rcWork.bottom - mTop; - } - } + mHWnd = 0; + mName = name; + mIsFullScreen = fullScreen; + mClosed = false; + mDisplayFrequency = 0; + mDepthBufferPoolId = DepthBuffer::POOL_DEFAULT; + mColourDepth = mIsFullScreen? 32 : GetDeviceCaps(GetDC(0), BITSPIXEL); + int left = -1; // Defaults to screen center + int top = -1; // Defaults to screen center + HWND parent = 0; + String title = name; + bool hidden = false; + String border; + bool outerSize = false; + bool hwGamma = false; + bool enableDoubleClick = false; + int monitorIndex = -1; + HMONITOR hMonitor = NULL; + + if(miscParams) + { + // Get variable-length params + NameValuePairList::const_iterator opt; + NameValuePairList::const_iterator end = miscParams->end(); + + if ((opt = miscParams->find("title")) != end) + title = opt->second; + + if ((opt = miscParams->find("left")) != end) + left = StringConverter::parseInt(opt->second); + + if ((opt = miscParams->find("top")) != end) + top = StringConverter::parseInt(opt->second); + + if ((opt = miscParams->find("depthBuffer")) != end) + { + mDepthBufferPoolId = StringConverter::parseBool(opt->second) ? + DepthBuffer::POOL_DEFAULT : DepthBuffer::POOL_NO_DEPTH; + } + + if ((opt = miscParams->find("vsync")) != end) + mVSync = StringConverter::parseBool(opt->second); + + if ((opt = miscParams->find("hidden")) != end) + hidden = StringConverter::parseBool(opt->second); + + if ((opt = miscParams->find("vsyncInterval")) != end) + mVSyncInterval = StringConverter::parseUnsignedInt(opt->second); + + if ((opt = miscParams->find("FSAA")) != end) + mFSAA = StringConverter::parseUnsignedInt(opt->second); + + if ((opt = miscParams->find("FSAAHint")) != end) + mFSAAHint = opt->second; + + if ((opt = miscParams->find("gamma")) != end) + hwGamma = StringConverter::parseBool(opt->second); + + if ((opt = miscParams->find("externalWindowHandle")) != end) + { + mHWnd = (HWND)StringConverter::parseSizeT(opt->second); + if (mHWnd) + { + mIsExternal = true; + mIsFullScreen = false; + } + + if ((opt = miscParams->find("externalGLControl")) != end) { + mIsExternalGLControl = StringConverter::parseBool(opt->second); + } + } + if ((opt = miscParams->find("externalGLContext")) != end) + { + mGlrc = (HGLRC)StringConverter::parseUnsignedLong(opt->second); + if( mGlrc ) + mIsExternalGLContext = true; + } + + // window border style + opt = miscParams->find("border"); + if(opt != miscParams->end()) + border = opt->second; + // set outer dimensions? + opt = miscParams->find("outerDimensions"); + if(opt != miscParams->end()) + outerSize = StringConverter::parseBool(opt->second); + + // only available with fullscreen + if ((opt = miscParams->find("displayFrequency")) != end) + mDisplayFrequency = StringConverter::parseUnsignedInt(opt->second); + if ((opt = miscParams->find("colourDepth")) != end) + { + mColourDepth = StringConverter::parseUnsignedInt(opt->second); + if (!mIsFullScreen) + { + // make sure we don't exceed desktop colour depth + if ((int)mColourDepth > GetDeviceCaps(GetDC(0), BITSPIXEL)) + mColourDepth = GetDeviceCaps(GetDC(0), BITSPIXEL); + } + } + + // incompatible with fullscreen + if ((opt = miscParams->find("parentWindowHandle")) != end) + parent = (HWND)StringConverter::parseSizeT(opt->second); + + + // monitor index + if ((opt = miscParams->find("monitorIndex")) != end) + monitorIndex = StringConverter::parseInt(opt->second); + + // monitor handle + if ((opt = miscParams->find("monitorHandle")) != end) + hMonitor = (HMONITOR)StringConverter::parseInt(opt->second); + + // enable double click messages + if ((opt = miscParams->find("enableDoubleClick")) != end) + enableDoubleClick = StringConverter::parseBool(opt->second); + + } + + if (!mIsExternal) + { + DWORD dwStyleEx = 0; + MONITORINFOEX monitorInfoEx; + RECT rc; + + // If we didn't specified the adapter index, or if it didn't find it + if (hMonitor == NULL) + { + POINT windowAnchorPoint; + + // Fill in anchor point. + windowAnchorPoint.x = left; + windowAnchorPoint.y = top; + + + // Get the nearest monitor to this window. + hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTOPRIMARY); + } + + // Get the target monitor info + memset(&monitorInfoEx, 0, sizeof(MONITORINFOEX)); + monitorInfoEx.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &monitorInfoEx); + + size_t devNameLen = strlen(monitorInfoEx.szDevice); + mDeviceName = new char[devNameLen + 1]; + + strcpy(mDeviceName, monitorInfoEx.szDevice); + + // Update window style flags. + mFullscreenWinStyle = (hidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN | WS_POPUP; + mWindowedWinStyle = (hidden ? 0 : WS_VISIBLE) | WS_CLIPCHILDREN; + + if (parent) + { + mWindowedWinStyle |= WS_CHILD; + } + else + { + if (border == "none") + mWindowedWinStyle |= WS_POPUP; + else if (border == "fixed") + mWindowedWinStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | + WS_SYSMENU | WS_MINIMIZEBOX; + else + mWindowedWinStyle |= WS_OVERLAPPEDWINDOW; + + } + + + // No specified top left -> Center the window in the middle of the monitor + if (left == -1 || top == -1) + { + int screenw = monitorInfoEx.rcWork.right - monitorInfoEx.rcWork.left; + int screenh = monitorInfoEx.rcWork.bottom - monitorInfoEx.rcWork.top; + + unsigned int winWidth, winHeight; + adjustWindow(width, height, &winWidth, &winHeight); + + // clamp window dimensions to screen size + int outerw = (winWidth < screenw)? winWidth : screenw; + int outerh = (winHeight < screenh)? winHeight : screenh; + + if (left == -1) + left = monitorInfoEx.rcWork.left + (screenw - outerw) / 2; + else if (monitorIndex != -1) + left += monitorInfoEx.rcWork.left; + + if (top == -1) + top = monitorInfoEx.rcWork.top + (screenh - outerh) / 2; + else if (monitorIndex != -1) + top += monitorInfoEx.rcWork.top; + } + else if (monitorIndex != -1) + { + left += monitorInfoEx.rcWork.left; + top += monitorInfoEx.rcWork.top; + } + + mWidth = width; + mHeight = height; + mTop = top; + mLeft = left; + + if (mIsFullScreen) + { + dwStyleEx |= WS_EX_TOPMOST; + mTop = monitorInfoEx.rcMonitor.top; + mLeft = monitorInfoEx.rcMonitor.left; + } + else + { + int screenw = GetSystemMetrics(SM_CXSCREEN); + int screenh = GetSystemMetrics(SM_CYSCREEN); + + if (!outerSize) + { + // Calculate window dimensions required + // to get the requested client area + SetRect(&rc, 0, 0, mWidth, mHeight); + AdjustWindowRect(&rc, getWindowStyle(fullScreen), false); + mWidth = rc.right - rc.left; + mHeight = rc.bottom - rc.top; + + // Clamp window rect to the nearest display monitor. + if (mLeft < monitorInfoEx.rcWork.left) + mLeft = monitorInfoEx.rcWork.left; + + if (mTop < monitorInfoEx.rcWork.top) + mTop = monitorInfoEx.rcWork.top; + + if ((int)mWidth > monitorInfoEx.rcWork.right - mLeft) + mWidth = monitorInfoEx.rcWork.right - mLeft; + + if ((int)mHeight > monitorInfoEx.rcWork.bottom - mTop) + mHeight = monitorInfoEx.rcWork.bottom - mTop; + } + } - UINT classStyle = CS_OWNDC; - if (enableDoubleClick) - classStyle |= CS_DBLCLKS; - - // register class and create window - WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst, - LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), - (HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "OgreGLWindow" }; - RegisterClass(&wc); - - if (mIsFullScreen) - { - DEVMODE displayDeviceMode; - - memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); - displayDeviceMode.dmSize = sizeof(DEVMODE); - displayDeviceMode.dmBitsPerPel = mColourDepth; - displayDeviceMode.dmPelsWidth = mWidth; - displayDeviceMode.dmPelsHeight = mHeight; - displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - - if (mDisplayFrequency) - { - displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; - displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) - { - LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); - displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; - } - } - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) - LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); - } - - // Pass pointer to self as WM_CREATE parameter - mHWnd = CreateWindowEx(dwStyleEx, "OgreGLWindow", title.c_str(), - getWindowStyle(fullScreen), mLeft, mTop, mWidth, mHeight, parent, 0, hInst, this); - - WindowEventUtilities::_addRenderWindow(this); - - LogManager::getSingleton().stream() - << "Created Win32Window '" - << mName << "' : " << mWidth << "x" << mHeight - << ", " << mColourDepth << "bpp"; - - } - - HDC old_hdc = wglGetCurrentDC(); - HGLRC old_context = wglGetCurrentContext(); - - RECT rc; - // top and left represent outer window position - GetWindowRect(mHWnd, &rc); - mTop = rc.top; - mLeft = rc.left; - // width and height represent drawable area only - GetClientRect(mHWnd, &rc); - mWidth = rc.right; - mHeight = rc.bottom; - - mHDC = GetDC(mHWnd); - - if (!mIsExternalGLControl) - { - int testFsaa = mFSAA; - bool testHwGamma = hwGamma; - bool formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); - if (!formatOk) - { - if (mFSAA > 0) - { - // try without FSAA - testFsaa = 0; - formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); - } - - if (!formatOk && hwGamma) - { - // try without sRGB - testHwGamma = false; - testFsaa = mFSAA; - formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); - } - - if (!formatOk && hwGamma && (mFSAA > 0)) - { - // try without both - testHwGamma = false; - testFsaa = 0; - formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); - } - - if (!formatOk) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "selectPixelFormat failed", "Win32Window::create"); - - } - // record what gamma option we used in the end - // this will control enabling of sRGB state flags when used - mHwGamma = testHwGamma; - mFSAA = testFsaa; - } - if (!mIsExternalGLContext) - { - mGlrc = wglCreateContext(mHDC); - if (!mGlrc) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "wglCreateContext failed: " + translateWGLError(), "Win32Window::create"); - } + UINT classStyle = CS_OWNDC; + if (enableDoubleClick) + classStyle |= CS_DBLCLKS; + + // register class and create window + WNDCLASS wc = { classStyle, WindowEventUtilities::_WndProc, 0, 0, hInst, + LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), + (HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "OgreGLWindow" }; + RegisterClass(&wc); + + if (mIsFullScreen) + { + DEVMODE displayDeviceMode; + + memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); + displayDeviceMode.dmSize = sizeof(DEVMODE); + displayDeviceMode.dmBitsPerPel = mColourDepth; + displayDeviceMode.dmPelsWidth = mWidth; + displayDeviceMode.dmPelsHeight = mHeight; + displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + + if (mDisplayFrequency) + { + displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; + displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) + { + LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); + displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; + } + } + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) + LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); + } + + // Pass pointer to self as WM_CREATE parameter + mHWnd = CreateWindowEx(dwStyleEx, "OgreGLWindow", title.c_str(), + getWindowStyle(fullScreen), mLeft, mTop, mWidth, mHeight, parent, 0, hInst, this); + + WindowEventUtilities::_addRenderWindow(this); + + LogManager::getSingleton().stream() + << "Created Win32Window '" + << mName << "' : " << mWidth << "x" << mHeight + << ", " << mColourDepth << "bpp"; + + } + + HDC old_hdc = wglGetCurrentDC(); + HGLRC old_context = wglGetCurrentContext(); + + RECT rc; + // top and left represent outer window position + GetWindowRect(mHWnd, &rc); + mTop = rc.top; + mLeft = rc.left; + // width and height represent drawable area only + GetClientRect(mHWnd, &rc); + mWidth = rc.right; + mHeight = rc.bottom; + + mHDC = GetDC(mHWnd); + + if (!mIsExternalGLControl) + { + int testFsaa = mFSAA; + bool testHwGamma = hwGamma; + bool formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); + if (!formatOk) + { + if (mFSAA > 0) + { + // try without FSAA + testFsaa = 0; + formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); + } + + if (!formatOk && hwGamma) + { + // try without sRGB + testHwGamma = false; + testFsaa = mFSAA; + formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); + } + + if (!formatOk && hwGamma && (mFSAA > 0)) + { + // try without both + testHwGamma = false; + testFsaa = 0; + formatOk = mGLSupport.selectPixelFormat(mHDC, mColourDepth, testFsaa, testHwGamma); + } + + if (!formatOk) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "selectPixelFormat failed", "Win32Window::create"); + + } + // record what gamma option we used in the end + // this will control enabling of sRGB state flags when used + mHwGamma = testHwGamma; + mFSAA = testFsaa; + } + if (!mIsExternalGLContext) + { + mGlrc = wglCreateContext(mHDC); + if (!mGlrc) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "wglCreateContext failed: " + translateWGLError(), "Win32Window::create"); + } if (old_context && old_context != mGlrc) { // Share lists with old context - if (!wglShareLists(old_context, mGlrc)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglShareLists() failed", " Win32Window::create"); + if (!wglShareLists(old_context, mGlrc)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglShareLists() failed", " Win32Window::create"); } - if (!wglMakeCurrent(mHDC, mGlrc)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent", "Win32Window::create"); + if (!wglMakeCurrent(mHDC, mGlrc)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent", "Win32Window::create"); - // Do not change vsync if the external window has the OpenGL control - if (!mIsExternalGLControl) { - // Don't use wglew as if this is the first window, we won't have initialised yet - PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = - (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); - if (_wglSwapIntervalEXT) - _wglSwapIntervalEXT(mVSync? mVSyncInterval : 0); - } + // Do not change vsync if the external window has the OpenGL control + if (!mIsExternalGLControl) { + // Don't use wglew as if this is the first window, we won't have initialised yet + PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = + (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + if (_wglSwapIntervalEXT) + _wglSwapIntervalEXT(mVSync? mVSyncInterval : 0); + } if (old_context && old_context != mGlrc) { // Restore old context - if (!wglMakeCurrent(old_hdc, old_context)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent() failed", "Win32Window::create"); + if (!wglMakeCurrent(old_hdc, old_context)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent() failed", "Win32Window::create"); } - // Create RenderSystem context - mContext = new Win32Context(mHDC, mGlrc); - - mActive = true; - setHidden(hidden); - } - - void Win32Window::adjustWindow(unsigned int clientWidth, unsigned int clientHeight, - unsigned int* winWidth, unsigned int* winHeight) - { - // NB only call this for non full screen - RECT rc; - SetRect(&rc, 0, 0, clientWidth, clientHeight); - AdjustWindowRect(&rc, getWindowStyle(mIsFullScreen), false); - *winWidth = rc.right - rc.left; - *winHeight = rc.bottom - rc.top; - - // adjust to monitor - HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); - - // Get monitor info - MONITORINFO monitorInfo; - - memset(&monitorInfo, 0, sizeof(MONITORINFO)); - monitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hMonitor, &monitorInfo); - - LONG maxW = monitorInfo.rcWork.right - monitorInfo.rcWork.left; - LONG maxH = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; - - if (*winWidth > (unsigned int)maxW) - *winWidth = maxW; - if (*winHeight > (unsigned int)maxH) - *winHeight = maxH; - - } - - void Win32Window::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) - { - if (mIsFullScreen != fullScreen || width != mWidth || height != mHeight) - { - mIsFullScreen = fullScreen; - - if (mIsFullScreen) - { - - DEVMODE displayDeviceMode; - - memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); - displayDeviceMode.dmSize = sizeof(DEVMODE); - displayDeviceMode.dmBitsPerPel = mColourDepth; - displayDeviceMode.dmPelsWidth = width; - displayDeviceMode.dmPelsHeight = height; - displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - if (mDisplayFrequency) - { - displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; - displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; - - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, - CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) - { - LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); - displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; - } - } - else - { - // try a few - displayDeviceMode.dmDisplayFrequency = 100; - displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, - CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) - { - displayDeviceMode.dmDisplayFrequency = 75; - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, - CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) - { - displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; - } - } - - } - // move window to 0,0 before display switch - SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, mWidth, mHeight, SWP_NOACTIVATE); - - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) - LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); - - // Get the nearest monitor to this window. - HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); - - // Get monitor info - MONITORINFO monitorInfo; - - memset(&monitorInfo, 0, sizeof(MONITORINFO)); - monitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hMonitor, &monitorInfo); - - mTop = monitorInfo.rcMonitor.top; - mLeft = monitorInfo.rcMonitor.left; - - SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); - SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, width, height, - SWP_NOACTIVATE); - mWidth = width; - mHeight = height; - - - } - else - { - // drop out of fullscreen - ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); - - // calculate overall dimensions for requested client area - unsigned int winWidth, winHeight; - adjustWindow(width, height, &winWidth, &winHeight); - - // deal with centering when switching down to smaller resolution - - HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); - MONITORINFO monitorInfo; - memset(&monitorInfo, 0, sizeof(MONITORINFO)); - monitorInfo.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hMonitor, &monitorInfo); - - LONG screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left; - LONG screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; - - - int left = screenw > winWidth ? ((screenw - winWidth) / 2) : 0; - int top = screenh > winHeight ? ((screenh - winHeight) / 2) : 0; - - SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); - SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight, - SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE); - mWidth = width; - mHeight = height; - - windowMovedOrResized(); - - } - - } - } - - void Win32Window::destroy(void) - { - if (!mHWnd) - return; - - // Unregister and destroy OGRE GL3PlusContext - delete mContext; + // Create RenderSystem context + mContext = new Win32Context(mHDC, mGlrc); + + mActive = true; + setHidden(hidden); + } + + void Win32Window::adjustWindow(unsigned int clientWidth, unsigned int clientHeight, + unsigned int* winWidth, unsigned int* winHeight) + { + // NB only call this for non full screen + RECT rc; + SetRect(&rc, 0, 0, clientWidth, clientHeight); + AdjustWindowRect(&rc, getWindowStyle(mIsFullScreen), false); + *winWidth = rc.right - rc.left; + *winHeight = rc.bottom - rc.top; + + // adjust to monitor + HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); + + // Get monitor info + MONITORINFO monitorInfo; + + memset(&monitorInfo, 0, sizeof(MONITORINFO)); + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hMonitor, &monitorInfo); + + LONG maxW = monitorInfo.rcWork.right - monitorInfo.rcWork.left; + LONG maxH = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; + + if (*winWidth > (unsigned int)maxW) + *winWidth = maxW; + if (*winHeight > (unsigned int)maxH) + *winHeight = maxH; + + } + + void Win32Window::setFullscreen(bool fullScreen, unsigned int width, unsigned int height) + { + if (mIsFullScreen != fullScreen || width != mWidth || height != mHeight) + { + mIsFullScreen = fullScreen; + + if (mIsFullScreen) + { + + DEVMODE displayDeviceMode; + + memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); + displayDeviceMode.dmSize = sizeof(DEVMODE); + displayDeviceMode.dmBitsPerPel = mColourDepth; + displayDeviceMode.dmPelsWidth = width; + displayDeviceMode.dmPelsHeight = height; + displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + if (mDisplayFrequency) + { + displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; + displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; + + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, + CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) + { + LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); + displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; + } + } + else + { + // try a few + displayDeviceMode.dmDisplayFrequency = 100; + displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, + CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) + { + displayDeviceMode.dmDisplayFrequency = 75; + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, + CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) + { + displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; + } + } + + } + // move window to 0,0 before display switch + SetWindowPos(mHWnd, HWND_TOPMOST, 0, 0, mWidth, mHeight, SWP_NOACTIVATE); + + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) + LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); + + // Get the nearest monitor to this window. + HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); + + // Get monitor info + MONITORINFO monitorInfo; + + memset(&monitorInfo, 0, sizeof(MONITORINFO)); + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hMonitor, &monitorInfo); + + mTop = monitorInfo.rcMonitor.top; + mLeft = monitorInfo.rcMonitor.left; + + SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); + SetWindowPos(mHWnd, HWND_TOPMOST, mLeft, mTop, width, height, + SWP_NOACTIVATE); + mWidth = width; + mHeight = height; + + + } + else + { + // drop out of fullscreen + ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); + + // calculate overall dimensions for requested client area + unsigned int winWidth, winHeight; + adjustWindow(width, height, &winWidth, &winHeight); + + // deal with centering when switching down to smaller resolution + + HMONITOR hMonitor = MonitorFromWindow(mHWnd, MONITOR_DEFAULTTONEAREST); + MONITORINFO monitorInfo; + memset(&monitorInfo, 0, sizeof(MONITORINFO)); + monitorInfo.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hMonitor, &monitorInfo); + + LONG screenw = monitorInfo.rcWork.right - monitorInfo.rcWork.left; + LONG screenh = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top; + + + int left = screenw > winWidth ? ((screenw - winWidth) / 2) : 0; + int top = screenh > winHeight ? ((screenh - winHeight) / 2) : 0; + + SetWindowLong(mHWnd, GWL_STYLE, getWindowStyle(mIsFullScreen)); + SetWindowPos(mHWnd, HWND_NOTOPMOST, left, top, winWidth, winHeight, + SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOACTIVATE); + mWidth = width; + mHeight = height; + + windowMovedOrResized(); + + } + + } + } + + void Win32Window::destroy(void) + { + if (!mHWnd) + return; + + // Unregister and destroy OGRE GL3PlusContext + delete mContext; mContext = 0; - if (!mIsExternalGLContext && mGlrc) - { - wglDeleteContext(mGlrc); - mGlrc = 0; - } - if (!mIsExternal) - { - WindowEventUtilities::_removeRenderWindow(this); - - if (mIsFullScreen) - ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); - DestroyWindow(mHWnd); - } - else - { - // just release the DC - ReleaseDC(mHWnd, mHDC); - } - - mActive = false; - mClosed = true; - mHDC = 0; // no release thanks to CS_OWNDC wndclass style - mHWnd = 0; - - if (mDeviceName != NULL) - { - delete[] mDeviceName; - mDeviceName = NULL; - } - - } - - - bool Win32Window::isActive(void) const - { - if (isFullScreen()) - return isVisible(); - - return mActive && isVisible(); - } - - bool Win32Window::isVisible() const - { - return (mHWnd && !IsIconic(mHWnd)); - } - - bool Win32Window::isClosed() const - { - return mClosed; - } - - void Win32Window::setHidden(bool hidden) - { - mHidden = hidden; - if (!mIsExternal) - { - if (hidden) - ShowWindow(mHWnd, SW_HIDE); - else - ShowWindow(mHWnd, SW_SHOWNORMAL); - } - } - - void Win32Window::setVSyncEnabled(bool vsync) - { - mVSync = vsync; - HDC old_hdc = wglGetCurrentDC(); - HGLRC old_context = wglGetCurrentContext(); - if (!wglMakeCurrent(mHDC, mGlrc)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent", "Win32Window::setVSyncEnabled"); - - // Do not change vsync if the external window has the OpenGL control - if (!mIsExternalGLControl) { - // Don't use wglew as if this is the first window, we won't have initialised yet - PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = - (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); - if (_wglSwapIntervalEXT) - _wglSwapIntervalEXT(mVSync? mVSyncInterval : 0); - } + if (!mIsExternalGLContext && mGlrc) + { + wglDeleteContext(mGlrc); + mGlrc = 0; + } + if (!mIsExternal) + { + WindowEventUtilities::_removeRenderWindow(this); + + if (mIsFullScreen) + ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); + DestroyWindow(mHWnd); + } + else + { + // just release the DC + ReleaseDC(mHWnd, mHDC); + } + + mActive = false; + mClosed = true; + mHDC = 0; // no release thanks to CS_OWNDC wndclass style + mHWnd = 0; + + if (mDeviceName != NULL) + { + delete[] mDeviceName; + mDeviceName = NULL; + } + + } + + + bool Win32Window::isActive(void) const + { + if (isFullScreen()) + return isVisible(); + + return mActive && isVisible(); + } + + bool Win32Window::isVisible() const + { + return (mHWnd && !IsIconic(mHWnd)); + } + + bool Win32Window::isClosed() const + { + return mClosed; + } + + void Win32Window::setHidden(bool hidden) + { + mHidden = hidden; + if (!mIsExternal) + { + if (hidden) + ShowWindow(mHWnd, SW_HIDE); + else + ShowWindow(mHWnd, SW_SHOWNORMAL); + } + } + + void Win32Window::setVSyncEnabled(bool vsync) + { + mVSync = vsync; + HDC old_hdc = wglGetCurrentDC(); + HGLRC old_context = wglGetCurrentContext(); + if (!wglMakeCurrent(mHDC, mGlrc)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent", "Win32Window::setVSyncEnabled"); + + // Do not change vsync if the external window has the OpenGL control + if (!mIsExternalGLControl) { + // Don't use wglew as if this is the first window, we won't have initialised yet + PFNWGLSWAPINTERVALEXTPROC _wglSwapIntervalEXT = + (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + if (_wglSwapIntervalEXT) + _wglSwapIntervalEXT(mVSync? mVSyncInterval : 0); + } if (old_context && old_context != mGlrc) { // Restore old context - if (!wglMakeCurrent(old_hdc, old_context)) - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent() failed", "Win32Window::setVSyncEnabled"); - } - } - - void Win32Window::setVSyncInterval(unsigned int interval) - { - mVSyncInterval = interval; - if (mVSync) - setVSyncEnabled(true); - } - - bool Win32Window::isVSyncEnabled() const - { - return mVSync; - } - - unsigned int Win32Window::getVSyncInterval() const - { - return mVSyncInterval; - } - - void Win32Window::reposition(int left, int top) - { - if (mHWnd && !mIsFullScreen) - { - SetWindowPos(mHWnd, 0, left, top, 0, 0, - SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); - } - } - - void Win32Window::resize(unsigned int width, unsigned int height) - { - if (mHWnd && !mIsFullScreen) - { - RECT rc = { 0, 0, width, height }; - AdjustWindowRect(&rc, getWindowStyle(mIsFullScreen), false); - width = rc.right - rc.left; - height = rc.bottom - rc.top; - SetWindowPos(mHWnd, 0, 0, 0, width, height, - SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); - } - } - - void Win32Window::windowMovedOrResized() - { - if (!mHWnd || IsIconic(mHWnd)) - return; - - updateWindowRect(); - } - - - void Win32Window::updateWindowRect() - { - RECT rc; - BOOL result; - - // Update top left parameters - result = GetWindowRect(mHWnd, &rc); - if (result == FALSE) - { - mTop = 0; - mLeft = 0; - mWidth = 0; - mHeight = 0; - return; - } - - mTop = rc.top; - mLeft = rc.left; - - // width and height represent drawable area only - result = GetClientRect(mHWnd, &rc); - if (result == FALSE) - { - mTop = 0; - mLeft = 0; - mWidth = 0; - mHeight = 0; - return; - } - unsigned int width = rc.right - rc.left; - unsigned int height = rc.bottom - rc.top; - - // Case window resized. - if (width != mWidth || height != mHeight) - { - mWidth = rc.right - rc.left; - mHeight = rc.bottom - rc.top; - - // Notify viewports of resize - ViewportList::iterator it = mViewportList.begin(); - while( it != mViewportList.end() ) - (*it++).second->_updateDimensions(); - } - } - - - void Win32Window::swapBuffers() - { - if (!mIsExternalGLControl) { - SwapBuffers(mHDC); - } - } - - void Win32Window::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) - { - if ((dst.left < 0) || (dst.right > mWidth) || - (dst.top < 0) || (dst.bottom > mHeight) || - (dst.front != 0) || (dst.back != 1)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid box.", - "Win32Window::copyContentsToMemory" ); - } - - if (buffer == FB_AUTO) - { - buffer = mIsFullScreen? FB_FRONT : FB_BACK; - } - - GLenum format = Ogre::GL3PlusPixelUtil::getGLOriginFormat(dst.format); - GLenum type = Ogre::GL3PlusPixelUtil::getGLOriginDataType(dst.format); - - if ((format == GL_NONE) || (type == 0)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unsupported format.", - "Win32Window::copyContentsToMemory" ); - } - - - // Switch context if different from current one - RenderSystem* rsys = Root::getSingleton().getRenderSystem(); - rsys->_setViewport(this->getViewport(0)); + if (!wglMakeCurrent(old_hdc, old_context)) + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "wglMakeCurrent() failed", "Win32Window::setVSyncEnabled"); + } + } + + void Win32Window::setVSyncInterval(unsigned int interval) + { + mVSyncInterval = interval; + if (mVSync) + setVSyncEnabled(true); + } + + bool Win32Window::isVSyncEnabled() const + { + return mVSync; + } + + unsigned int Win32Window::getVSyncInterval() const + { + return mVSyncInterval; + } + + void Win32Window::reposition(int left, int top) + { + if (mHWnd && !mIsFullScreen) + { + SetWindowPos(mHWnd, 0, left, top, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + + void Win32Window::resize(unsigned int width, unsigned int height) + { + if (mHWnd && !mIsFullScreen) + { + RECT rc = { 0, 0, width, height }; + AdjustWindowRect(&rc, getWindowStyle(mIsFullScreen), false); + width = rc.right - rc.left; + height = rc.bottom - rc.top; + SetWindowPos(mHWnd, 0, 0, 0, width, height, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + + void Win32Window::windowMovedOrResized() + { + if (!mHWnd || IsIconic(mHWnd)) + return; + + updateWindowRect(); + } + + + void Win32Window::updateWindowRect() + { + RECT rc; + BOOL result; + + // Update top left parameters + result = GetWindowRect(mHWnd, &rc); + if (result == FALSE) + { + mTop = 0; + mLeft = 0; + mWidth = 0; + mHeight = 0; + return; + } + + mTop = rc.top; + mLeft = rc.left; + + // width and height represent drawable area only + result = GetClientRect(mHWnd, &rc); + if (result == FALSE) + { + mTop = 0; + mLeft = 0; + mWidth = 0; + mHeight = 0; + return; + } + unsigned int width = rc.right - rc.left; + unsigned int height = rc.bottom - rc.top; + + // Case window resized. + if (width != mWidth || height != mHeight) + { + mWidth = rc.right - rc.left; + mHeight = rc.bottom - rc.top; + + // Notify viewports of resize + ViewportList::iterator it = mViewportList.begin(); + while( it != mViewportList.end() ) + (*it++).second->_updateDimensions(); + } + } + + + void Win32Window::swapBuffers() + { + if (!mIsExternalGLControl) { + SwapBuffers(mHDC); + } + } + + void Win32Window::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) + { + if ((dst.left < 0) || (dst.right > mWidth) || + (dst.top < 0) || (dst.bottom > mHeight) || + (dst.front != 0) || (dst.back != 1)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid box.", + "Win32Window::copyContentsToMemory" ); + } + + if (buffer == FB_AUTO) + { + buffer = mIsFullScreen? FB_FRONT : FB_BACK; + } + + GLenum format = Ogre::GL3PlusPixelUtil::getGLOriginFormat(dst.format); + GLenum type = Ogre::GL3PlusPixelUtil::getGLOriginDataType(dst.format); + + if ((format == GL_NONE) || (type == 0)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Unsupported format.", + "Win32Window::copyContentsToMemory" ); + } + + + // Switch context if different from current one + RenderSystem* rsys = Root::getSingleton().getRenderSystem(); + rsys->_setViewport(this->getViewport(0)); if(dst.getWidth() != dst.rowPitch) glPixelStorei(GL_PACK_ROW_LENGTH, dst.rowPitch); - // Must change the packing to ensure no overruns! - glPixelStorei(GL_PACK_ALIGNMENT, 1); + // Must change the packing to ensure no overruns! + glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); + glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); glReadPixels((GLint)0, (GLint)(mHeight - dst.getHeight()), (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(), format, type, dst.getTopLeftFrontPixelPtr()); - // restore default alignment - glPixelStorei(GL_PACK_ALIGNMENT, 4); + // restore default alignment + glPixelStorei(GL_PACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ROW_LENGTH, 0); PixelUtil::bulkPixelVerticalFlip(dst); - } - - void Win32Window::getCustomAttribute( const String& name, void* pData ) - { - if( name == "GLCONTEXT" ) { - *static_cast(pData) = mContext; - return; - } else if( name == "WINDOW" ) - { - HWND *pHwnd = (HWND*)pData; - *pHwnd = getWindowHandle(); - return; - } - } - - void Win32Window::setActive( bool state ) - { - if (mDeviceName != NULL && state == false) - { - HWND hActiveWindow = GetActiveWindow(); - char classNameSrc[_MAX_CLASS_NAME_ + 1]; - char classNameDst[_MAX_CLASS_NAME_ + 1]; - - GetClassName(mHWnd, classNameSrc, _MAX_CLASS_NAME_); - GetClassName(hActiveWindow, classNameDst, _MAX_CLASS_NAME_); - - if (strcmp(classNameDst, classNameSrc) == 0) - { - state = true; - } - } - - mActive = state; - - if( mIsFullScreen ) - { - if( state == false ) - { //Restore Desktop - ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); - ShowWindow(mHWnd, SW_SHOWMINNOACTIVE); - } - else - { //Restore App - ShowWindow(mHWnd, SW_SHOWNORMAL); - - DEVMODE displayDeviceMode; - - memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); - displayDeviceMode.dmSize = sizeof(DEVMODE); - displayDeviceMode.dmBitsPerPel = mColourDepth; - displayDeviceMode.dmPelsWidth = mWidth; - displayDeviceMode.dmPelsHeight = mHeight; - displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - if (mDisplayFrequency) - { - displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; - displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; - } - ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL); - } - } - } + } + + void Win32Window::getCustomAttribute( const String& name, void* pData ) + { + if( name == "GLCONTEXT" ) { + *static_cast(pData) = mContext; + return; + } else if( name == "WINDOW" ) + { + HWND *pHwnd = (HWND*)pData; + *pHwnd = getWindowHandle(); + return; + } + } + + void Win32Window::setActive( bool state ) + { + if (mDeviceName != NULL && state == false) + { + HWND hActiveWindow = GetActiveWindow(); + char classNameSrc[_MAX_CLASS_NAME_ + 1]; + char classNameDst[_MAX_CLASS_NAME_ + 1]; + + GetClassName(mHWnd, classNameSrc, _MAX_CLASS_NAME_); + GetClassName(hActiveWindow, classNameDst, _MAX_CLASS_NAME_); + + if (strcmp(classNameDst, classNameSrc) == 0) + { + state = true; + } + } + + mActive = state; + + if( mIsFullScreen ) + { + if( state == false ) + { //Restore Desktop + ChangeDisplaySettingsEx(mDeviceName, NULL, NULL, 0, NULL); + ShowWindow(mHWnd, SW_SHOWMINNOACTIVE); + } + else + { //Restore App + ShowWindow(mHWnd, SW_SHOWNORMAL); + + DEVMODE displayDeviceMode; + + memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); + displayDeviceMode.dmSize = sizeof(DEVMODE); + displayDeviceMode.dmBitsPerPel = mColourDepth; + displayDeviceMode.dmPelsWidth = mWidth; + displayDeviceMode.dmPelsHeight = mHeight; + displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + if (mDisplayFrequency) + { + displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; + displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; + } + ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL); + } + } + } } diff --git a/RenderSystems/GLES/include/EAGL/OgreEAGLSupport.h b/RenderSystems/GLES/include/EAGL/OgreEAGLSupport.h index 9700c4e1942..883a62e6dd0 100644 --- a/RenderSystems/GLES/include/EAGL/OgreEAGLSupport.h +++ b/RenderSystems/GLES/include/EAGL/OgreEAGLSupport.h @@ -43,12 +43,12 @@ namespace Ogre { class EAGLWindow; class EAGLESContext; - template void removeDuplicates(C& c) - { - std::sort(c.begin(), c.end()); - typename C::iterator p = std::unique(c.begin(), c.end()); - c.erase(p, c.end()); - } + template void removeDuplicates(C& c) + { + std::sort(c.begin(), c.end()); + typename C::iterator p = std::unique(c.begin(), c.end()); + c.erase(p, c.end()); + } class _OgrePrivate EAGLSupport : public GLESSupport { @@ -62,7 +62,7 @@ namespace Ogre { void addConfig(void); String validateConfig(void); virtual String getDisplayName(void); - CFDictionaryRef chooseGLConfig(const GLint *attribList, GLint *nElements); + CFDictionaryRef chooseGLConfig(const GLint *attribList, GLint *nElements); GLint getGLConfigAttrib(CFDictionaryRef fbConfig, GLint attribute, GLint *value); void * getProcAddress(const Ogre::String& name); RenderWindow * createWindow(bool autoCreateWindow, @@ -84,8 +84,8 @@ namespace Ogre { CFDictionaryRef getGLConfigFromContext(EAGLESContext context); CFDictionaryRef getGLConfigFromDrawable(CAEAGLLayer *drawable, unsigned int *w, unsigned int *h); #endif - CFDictionaryRef selectGLConfig(const int* minAttribs, const int *maxAttribs); - }; + CFDictionaryRef selectGLConfig(const int* minAttribs, const int *maxAttribs); + }; } #endif diff --git a/RenderSystems/GLES/include/EAGL/OgreEAGLWindow.h b/RenderSystems/GLES/include/EAGL/OgreEAGLWindow.h index 8be415712e3..0da29dc6e90 100644 --- a/RenderSystems/GLES/include/EAGL/OgreEAGLWindow.h +++ b/RenderSystems/GLES/include/EAGL/OgreEAGLWindow.h @@ -68,28 +68,28 @@ namespace Ogre { EAGLSupport* mGLSupport; EAGLESContext* mContext; #ifdef __OBJC__ - NativeWindowType mWindow; + NativeWindowType mWindow; EAGLView *mView; EAGLViewController *mViewController; #endif void switchFullScreen(bool fullscreen) { } - void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); - void initNativeCreatedWindow(const NameValuePairList *miscParams); - void createNativeWindow(int &left, int &top, uint &width, uint &height, String &title); - void reposition(int left, int top); - void resize(unsigned int width, unsigned int height); - void windowMovedOrResized(); + void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); + void initNativeCreatedWindow(const NameValuePairList *miscParams); + void createNativeWindow(int &left, int &top, uint &width, uint &height, String &title); + void reposition(int left, int top); + void resize(unsigned int width, unsigned int height); + void windowMovedOrResized(); virtual void _beginUpdate(); - public: + public: EAGLWindow(EAGLSupport* glsupport); virtual ~EAGLWindow(); void create(const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams); - virtual void setFullscreen(bool fullscreen, uint width, uint height); + virtual void setFullscreen(bool fullscreen, uint width, uint height); void destroy(void); bool isClosed(void) const { return mClosed; } bool isVisible(void) const { return mVisible; } diff --git a/RenderSystems/GLES/include/EGL/Android/OgreAndroidEGLSupport.h b/RenderSystems/GLES/include/EGL/Android/OgreAndroidEGLSupport.h index 2192e62bf1e..0f04584dc3e 100644 --- a/RenderSystems/GLES/include/EGL/Android/OgreAndroidEGLSupport.h +++ b/RenderSystems/GLES/include/EGL/Android/OgreAndroidEGLSupport.h @@ -47,7 +47,7 @@ namespace Ogre { virtual GLESPBuffer* createPBuffer(PixelComponentType format, size_t width, size_t height); - }; + }; } #endif diff --git a/RenderSystems/GLES/include/EGL/Android/OgreAndroidEGLWindow.h b/RenderSystems/GLES/include/EGL/Android/OgreAndroidEGLWindow.h index 75d7f5fe8f5..0fd8f6f7a8c 100644 --- a/RenderSystems/GLES/include/EGL/Android/OgreAndroidEGLWindow.h +++ b/RenderSystems/GLES/include/EGL/Android/OgreAndroidEGLWindow.h @@ -36,30 +36,30 @@ THE SOFTWARE. namespace Ogre { class _OgrePrivate AndroidEGLWindow : public EGLWindow { - private: - uint mMaxBufferSize; - uint mMaxDepthSize; - uint mMaxStencilSize; - - protected: - virtual EGLContext * createEGLContext() const; - virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); - virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); - virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); - virtual void reposition(int left, int top); - virtual void resize(unsigned int width, unsigned int height); - virtual void windowMovedOrResized(); - virtual void switchFullScreen(bool fullscreen); + private: + uint mMaxBufferSize; + uint mMaxDepthSize; + uint mMaxStencilSize; - public: - AndroidEGLWindow(AndroidEGLSupport* glsupport); - virtual ~AndroidEGLWindow(); + protected: + virtual EGLContext * createEGLContext() const; + virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); + virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); + virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); + virtual void reposition(int left, int top); + virtual void resize(unsigned int width, unsigned int height); + virtual void windowMovedOrResized(); + virtual void switchFullScreen(bool fullscreen); + + public: + AndroidEGLWindow(AndroidEGLSupport* glsupport); + virtual ~AndroidEGLWindow(); void create(const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams); void _destroyInternalResources(); void _createInternalResources(NativeWindowType window, AConfiguration* config); - }; + }; } #endif diff --git a/RenderSystems/GLES/include/EGL/Android/OgreAndroidResource.h b/RenderSystems/GLES/include/EGL/Android/OgreAndroidResource.h index 929af0eb8a2..7c5d77891b2 100755 --- a/RenderSystems/GLES/include/EGL/Android/OgreAndroidResource.h +++ b/RenderSystems/GLES/include/EGL/Android/OgreAndroidResource.h @@ -34,25 +34,25 @@ namespace Ogre { class AndroidEGLContext; - /** Represents a Android rendering resource. - Provide unified interface to - handle various device states. - */ - class _OgrePrivate AndroidResource - { - - // Interface. - public: - - // Called immediately after the Android context has entered a lost state. - virtual void notifyOnContextLost() {} - - // Called immediately after the Android context has been reset. - virtual void notifyOnContextReset() {} - - public: - AndroidResource(); - virtual ~AndroidResource(); - }; + /** Represents a Android rendering resource. + Provide unified interface to + handle various device states. + */ + class _OgrePrivate AndroidResource + { + + // Interface. + public: + + // Called immediately after the Android context has entered a lost state. + virtual void notifyOnContextLost() {} + + // Called immediately after the Android context has been reset. + virtual void notifyOnContextReset() {} + + public: + AndroidResource(); + virtual ~AndroidResource(); + }; } #endif diff --git a/RenderSystems/GLES/include/EGL/Android/OgreAndroidResourceManager.h b/RenderSystems/GLES/include/EGL/Android/OgreAndroidResourceManager.h index 8dd3215c303..f4ac66f3feb 100755 --- a/RenderSystems/GLES/include/EGL/Android/OgreAndroidResourceManager.h +++ b/RenderSystems/GLES/include/EGL/Android/OgreAndroidResourceManager.h @@ -31,45 +31,45 @@ THE SOFTWARE. #include "OgreGLESPrerequisites.h" namespace Ogre { - class AndroidEGLContext; + class AndroidEGLContext; class AndroidResource; - class _OgrePrivate AndroidResourceManager : public ResourceAlloc - { - // Interface. - public: + class _OgrePrivate AndroidResourceManager : public ResourceAlloc + { + // Interface. + public: - // Called immediately after the Android context has entered a lost state. + // Called immediately after the Android context has entered a lost state. void notifyOnContextLost(); - // Called immediately after the Android context has been reset. + // Called immediately after the Android context has been reset. void notifyOnContextReset(); - - AndroidResourceManager(); - ~AndroidResourceManager(); + + AndroidResourceManager(); + ~AndroidResourceManager(); - // Friends. - protected: - friend class AndroidResource; - - // Types. - protected: - typedef vector::type ResourceContainer; - typedef ResourceContainer::iterator ResourceContainerIterator; + // Friends. + protected: + friend class AndroidResource; + + // Types. + protected: + typedef vector::type ResourceContainer; + typedef ResourceContainer::iterator ResourceContainerIterator; - // Protected methods. - protected: - - // Called when new resource created. - void _notifyResourceCreated (AndroidResource* pResource); + // Protected methods. + protected: + + // Called when new resource created. + void _notifyResourceCreated (AndroidResource* pResource); - // Called when resource is about to be destroyed. - void _notifyResourceDestroyed (AndroidResource* pResource); - - // Attributes. - protected: - ResourceContainer mResources; - }; + // Called when resource is about to be destroyed. + void _notifyResourceDestroyed (AndroidResource* pResource); + + // Attributes. + protected: + ResourceContainer mResources; + }; } #endif diff --git a/RenderSystems/GLES/include/EGL/OgreEGLContext.h b/RenderSystems/GLES/include/EGL/OgreEGLContext.h index 1d2c7f5ec4c..85a9b426e28 100644 --- a/RenderSystems/GLES/include/EGL/OgreEGLContext.h +++ b/RenderSystems/GLES/include/EGL/OgreEGLContext.h @@ -56,7 +56,7 @@ namespace Ogre { virtual void endCurrent(); virtual GLESContext* clone() const = 0; - EGLSurface getDrawable() const; + EGLSurface getDrawable() const; }; } diff --git a/RenderSystems/GLES/include/EGL/OgreEGLRenderTexture.h b/RenderSystems/GLES/include/EGL/OgreEGLRenderTexture.h index 2cc97197dac..1cd35bf1597 100644 --- a/RenderSystems/GLES/include/EGL/OgreEGLRenderTexture.h +++ b/RenderSystems/GLES/include/EGL/OgreEGLRenderTexture.h @@ -44,11 +44,11 @@ namespace Ogre { protected: EGLSupport* mGLSupport; - ::EGLDisplay mGlDisplay; - ::EGLSurface mEglDrawable; + ::EGLDisplay mGlDisplay; + ::EGLSurface mEglDrawable; public: EGLPBuffer(EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height); - void initEGLPBuffer(); + void initEGLPBuffer(); virtual ~EGLPBuffer(); }; diff --git a/RenderSystems/GLES/include/EGL/OgreEGLSupport.h b/RenderSystems/GLES/include/EGL/OgreEGLSupport.h index 96d96be697d..0f95b5c27e6 100644 --- a/RenderSystems/GLES/include/EGL/OgreEGLSupport.h +++ b/RenderSystems/GLES/include/EGL/OgreEGLSupport.h @@ -37,12 +37,12 @@ THE SOFTWARE. #include "OgreEGLWindow.h" namespace Ogre { - template void removeDuplicates(C& c) - { - std::sort(c.begin(), c.end()); - typename C::iterator p = std::unique(c.begin(), c.end()); - c.erase(p, c.end()); - } + template void removeDuplicates(C& c) + { + std::sort(c.begin(), c.end()); + typename C::iterator p = std::unique(c.begin(), c.end()); + c.erase(p, c.end()); + } class _OgrePrivate EGLSupport : public GLESSupport { @@ -50,9 +50,9 @@ namespace Ogre { void refreshConfig(void); EGLDisplay mGLDisplay; - NativeDisplayType mNativeDisplay; + NativeDisplayType mNativeDisplay; - bool mIsExternalDisplay; + bool mIsExternalDisplay; bool mRandr; typedef std::pair ScreenSize; typedef short Rate; @@ -63,7 +63,7 @@ namespace Ogre { VideoMode mCurrentMode; StringVector mSampleLevels; - //virtual EGLWindow* createEGLWindow( EGLSupport * support) = 0; + //virtual EGLWindow* createEGLWindow( EGLSupport * support) = 0; public: EGLSupport(); virtual ~EGLSupport(); @@ -74,9 +74,9 @@ namespace Ogre { String validateConfig(void); void setConfigOption(const String &name, const String &value); virtual String getDisplayName (void); - EGLDisplay getGLDisplay(void); - void setGLDisplay(EGLDisplay val); - EGLConfig* chooseGLConfig(const EGLint *attribList, EGLint *nElements); + EGLDisplay getGLDisplay(void); + void setGLDisplay(EGLDisplay val); + EGLConfig* chooseGLConfig(const EGLint *attribList, EGLint *nElements); EGLBoolean getGLConfigAttrib(EGLConfig fbConfig, EGLint attribute, EGLint *value); void* getProcAddress(const Ogre::String& name); ::EGLContext createNewContext(EGLDisplay eglDisplay, ::EGLConfig glconfig, ::EGLContext shareList) const; @@ -93,13 +93,13 @@ namespace Ogre { ::EGLConfig getGLConfigFromContext(::EGLContext context); ::EGLConfig getGLConfigFromDrawable(::EGLSurface drawable, unsigned int *w, unsigned int *h); - ::EGLConfig selectGLConfig (const EGLint* minAttribs, const EGLint *maxAttribs); + ::EGLConfig selectGLConfig (const EGLint* minAttribs, const EGLint *maxAttribs); void switchMode(void); - virtual void switchMode(uint& width, uint& height, short& frequency) = 0; + virtual void switchMode(uint& width, uint& height, short& frequency) = 0; virtual GLESPBuffer* createPBuffer(PixelComponentType format, size_t width, size_t height) = 0; -// NativeDisplayType getNativeDisplay(); - }; +// NativeDisplayType getNativeDisplay(); + }; } #endif diff --git a/RenderSystems/GLES/include/EGL/OgreEGLWindow.h b/RenderSystems/GLES/include/EGL/OgreEGLWindow.h index ed369a5c744..d1cbadcfa1a 100644 --- a/RenderSystems/GLES/include/EGL/OgreEGLWindow.h +++ b/RenderSystems/GLES/include/EGL/OgreEGLWindow.h @@ -37,7 +37,7 @@ THE SOFTWARE. namespace Ogre { class _OgrePrivate EGLWindow : public RenderWindow { - private: + private: protected: bool mClosed; bool mVisible; @@ -47,34 +47,34 @@ namespace Ogre { EGLSupport* mGLSupport; EGLContext* mContext; - NativeWindowType mWindow; - NativeDisplayType mNativeDisplay; - ::EGLDisplay mEglDisplay; + NativeWindowType mWindow; + NativeDisplayType mNativeDisplay; + ::EGLDisplay mEglDisplay; - ::EGLConfig mEglConfig; - ::EGLSurface mEglSurface; + ::EGLConfig mEglConfig; + ::EGLSurface mEglSurface; ::EGLSurface createSurfaceFromWindow(::EGLDisplay display, NativeWindowType win); - virtual void switchFullScreen(bool fullscreen) = 0; - virtual EGLContext * createEGLContext() const = 0; - virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height) = 0; - virtual void initNativeCreatedWindow(const NameValuePairList *miscParams) = 0; - virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) = 0; - virtual void reposition(int left, int top) = 0; - virtual void resize(unsigned int width, unsigned int height) = 0; - virtual void windowMovedOrResized() = 0; + virtual void switchFullScreen(bool fullscreen) = 0; + virtual EGLContext * createEGLContext() const = 0; + virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height) = 0; + virtual void initNativeCreatedWindow(const NameValuePairList *miscParams) = 0; + virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) = 0; + virtual void reposition(int left, int top) = 0; + virtual void resize(unsigned int width, unsigned int height) = 0; + virtual void windowMovedOrResized() = 0; - public: + public: EGLWindow(EGLSupport* glsupport); virtual ~EGLWindow(); -// Moved create to native source because it has native calls in it. +// Moved create to native source because it has native calls in it. // void create(const String& name, unsigned int width, unsigned int height, // bool fullScreen, const NameValuePairList *miscParams); - virtual void setFullscreen (bool fullscreen, uint width, uint height); + virtual void setFullscreen (bool fullscreen, uint width, uint height); void destroy(void); bool isClosed(void) const; bool isVisible(void) const; diff --git a/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLRenderTexture.h b/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLRenderTexture.h index 69f3fedc11b..b0b3b63821a 100644 --- a/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLRenderTexture.h +++ b/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLRenderTexture.h @@ -42,9 +42,9 @@ namespace Ogre class _OgrePrivate Win32EGLPBuffer : public EGLPBuffer { - protected: + protected: - public: + public: Win32EGLPBuffer(Win32EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height); virtual ~Win32EGLPBuffer(); }; diff --git a/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLSupport.h b/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLSupport.h index 9899fcf3580..c82ef997d5a 100644 --- a/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLSupport.h +++ b/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLSupport.h @@ -36,32 +36,32 @@ THE SOFTWARE. namespace Ogre { class _OgrePrivate Win32EGLSupport : public EGLSupport { - protected: + protected: - //Removed createEGLWindow because it was easier to just call - //new Win32EGLWindow in the code to get the native version - //virtual EGLWindow* createEGLWindow( EGLSupport * support); + //Removed createEGLWindow because it was easier to just call + //new Win32EGLWindow in the code to get the native version + //virtual EGLWindow* createEGLWindow( EGLSupport * support); public: Win32EGLSupport(); virtual ~Win32EGLSupport(); - virtual GLESPBuffer* createPBuffer(PixelComponentType format, - size_t width, size_t height); - virtual void switchMode(uint& width, uint& height, short& frequency); + virtual GLESPBuffer* createPBuffer(PixelComponentType format, + size_t width, size_t height); + virtual void switchMode(uint& width, uint& height, short& frequency); RenderWindow* newWindow(const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams = 0); - //Moved getNativeDisplay to native class - NativeDisplayType getNativeDisplay(); + //Moved getNativeDisplay to native class + NativeDisplayType getNativeDisplay(); - //This sets up the native variables then calls EGLSupport::getGLDisplay - EGLDisplay getGLDisplay(); + //This sets up the native variables then calls EGLSupport::getGLDisplay + EGLDisplay getGLDisplay(); - }; + }; } #endif diff --git a/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLWindow.h b/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLWindow.h index 2e1e6334e64..13fc8b90083 100644 --- a/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLWindow.h +++ b/RenderSystems/GLES/include/EGL/WIN32/OgreWin32EGLWindow.h @@ -36,19 +36,19 @@ THE SOFTWARE. namespace Ogre { class _OgrePrivate Win32EGLWindow : public EGLWindow { - protected: - virtual EGLContext * createEGLContext() const; - virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); - virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); - virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); - virtual void reposition(int left, int top); - virtual void resize(unsigned int width, unsigned int height); - virtual void windowMovedOrResized(); - virtual void switchFullScreen(bool fullscreen); + protected: + virtual EGLContext * createEGLContext() const; + virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); + virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); + virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); + virtual void reposition(int left, int top); + virtual void resize(unsigned int width, unsigned int height); + virtual void windowMovedOrResized(); + virtual void switchFullScreen(bool fullscreen); public: - Win32EGLWindow(Win32EGLSupport* glsupport); - virtual ~Win32EGLWindow(); + Win32EGLWindow(Win32EGLSupport* glsupport); + virtual ~Win32EGLWindow(); void create(const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams); diff --git a/RenderSystems/GLES/include/EGL/X11/OgreX11EGLRenderTexture.h b/RenderSystems/GLES/include/EGL/X11/OgreX11EGLRenderTexture.h index f1e19445ba8..3645c10c079 100644 --- a/RenderSystems/GLES/include/EGL/X11/OgreX11EGLRenderTexture.h +++ b/RenderSystems/GLES/include/EGL/X11/OgreX11EGLRenderTexture.h @@ -42,7 +42,7 @@ namespace Ogre class _OgrePrivate X11EGLPBuffer : public EGLPBuffer { - protected: + protected: public: X11EGLPBuffer(X11EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height); diff --git a/RenderSystems/GLES/include/EGL/X11/OgreX11EGLSupport.h b/RenderSystems/GLES/include/EGL/X11/OgreX11EGLSupport.h index ac44c3a53e9..d1bcd3bbd58 100644 --- a/RenderSystems/GLES/include/EGL/X11/OgreX11EGLSupport.h +++ b/RenderSystems/GLES/include/EGL/X11/OgreX11EGLSupport.h @@ -34,143 +34,143 @@ THE SOFTWARE. #include "OgreEGLSupport.h" #if (OGRE_PLATFORM == OGRE_PLATFORM_LINUX) - #include - #include - #include - #include - #include - #include - #include + #include + #include + #include + #include + #include + #include + #include #else - #define StructureNotifyMask 0 - #define VisibilityChangeMask 0 - #define FocusChangeMask 0 - #define CWBackPixel 0 - #define CWBorderPixel 0 - #define CWColormap 0 - #define CWEventMask 0 - #define NotUseful 0 - #define CWSaveUnder 0 - #define CWBackingStore 0 - #define CWOverrideRedirect 0 - #define InputOutput 0 - #define NormalState 0 - #define StateHint 0 - #define InputHint 0 - #define USPosition 0 - #define ClientMessage 0 - #define SubstructureRedirectMask 0 - #define SubstructureNotifyMask 0 - #define CurrentTime 0 - #define VisualIDMask 0 - #define AllocNone 0 - - enum X11Bool - { - False - , - True - }; - class NotPointerAtom{}; - typedef NotPointerAtom * Atom; - - class Display{}; - class XErrorEvent{}; - class XRRScreenConfiguration{}; - class Rotation{}; - class Visual{}; - #define Window NativeWindowType - - struct XVisualInfo{int visualid, visual, depth;}; - struct XRRScreenSize{int width, height;}; - struct XWMHints{int initial_state, input, flags;}; - struct XSizeHints{int flags;}; - struct XWindowAttributes{NativeWindowType root; int x, y, width, height;}; - struct XSetWindowAttributes{int background_pixel, border_pixel, colormap, event_mask, backing_store, save_under, override_redirect;}; - struct XTextProperty{int * value;}; - struct StrangeData{StrangeData(){}StrangeData(Atom atom){}StrangeData(int num){}}; - struct XClientMessageEventData{StrangeData l[3];}; - struct XClientMessageEvent{int type, serial, send_event, format; XClientMessageEventData data ; NativeWindowType window; Atom message_type;}; - struct XEvent{}; - - - void XStringListToTextProperty(char ** prop, int num, XTextProperty * textProp); - Window DefaultRootWindow(Display* nativeDisplayType); - bool XQueryExtension(Display* nativeDisplayType, char * name, int * dummy0, int * dummy2, int * dummy3); - XRRScreenConfiguration * XRRGetScreenInfo(Display* nativeDisplayType, Window window ); - int XRRConfigCurrentConfiguration(XRRScreenConfiguration * config, Rotation * rotation); - XRRScreenSize * XRRConfigSizes(XRRScreenConfiguration * config, int * nSizes); - int XRRConfigCurrentRate(XRRScreenConfiguration * config); - short * XRRConfigRates(XRRScreenConfiguration * config, int sizeID, int * nRates); - void XRRFreeScreenConfigInfo(XRRScreenConfiguration * config); - int DefaultScreen(NativeDisplayType nativeDisplayType); - int DisplayWidth(Display* nativeDisplayType, int screen); - int DisplayHeight(Display* nativeDisplayType, int screen); - Display* XOpenDisplay(int num); - void XCloseDisplay(Display* nativeDisplayType); - Atom XInternAtom(Display* nativeDisplayType, char * name, X11Bool isTrue);; - char * DisplayString(NativeDisplayType nativeDisplayType); - const char * XDisplayName(char * name); - Visual * DefaultVisual(Display* nativeDisplayType, int screen); - int XVisualIDFromVisual(Visual *v); - void XRRSetScreenConfigAndRate(Display* nativeDisplayType, XRRScreenConfiguration * config, Window window, int size, Rotation rotation, int mode, int currentTime ); - XVisualInfo * XGetVisualInfo(Display* nativeDisplayType, int mask, XVisualInfo * info, int * n); - typedef int (*XErrorHandler)(Display *, XErrorEvent*); - XErrorHandler XSetErrorHandler(XErrorHandler xErrorHandler); - void XDestroyWindow(Display* nativeDisplayType, Window nativeWindowType); - bool XGetWindowAttributes(Display* nativeDisplayType, Window nativeWindowType, XWindowAttributes * xWindowAttributes); - int XCreateColormap(Display* nativeDisplayType, Window nativeWindowType, int visual, int allocNone); - Window XCreateWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top, int width, int height, int dummy1, int depth, int inputOutput, int visual, int mask, XSetWindowAttributes * xSetWindowAttributes); - void XFree(void *data); - XWMHints * XAllocWMHints(); - XSizeHints * XAllocSizeHints(); - void XSetWMProperties(Display* nativeDisplayType, Window nativeWindowType,XTextProperty * titleprop, char * dummy1, char * dummy2, int num, XSizeHints *sizeHints, XWMHints *wmHints, char * dummy3); - void XSetWMProtocols(Display* nativeDisplayType, Window nativeWindowType, Atom * atom, int num); - void XMapWindow(Display* nativeDisplayType, Window nativeWindowType); - void XFlush(Display* nativeDisplayType); - void XMoveWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top); - void XResizeWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top); - void XQueryTree(Display* nativeDisplayType, Window nativeWindowType, Window * root, Window *parent, Window **children, unsigned int * nChildren); - void XSendEvent(Display* nativeDisplayType, Window nativeWindowType, int dummy1, int mask, XEvent* xevent); + #define StructureNotifyMask 0 + #define VisibilityChangeMask 0 + #define FocusChangeMask 0 + #define CWBackPixel 0 + #define CWBorderPixel 0 + #define CWColormap 0 + #define CWEventMask 0 + #define NotUseful 0 + #define CWSaveUnder 0 + #define CWBackingStore 0 + #define CWOverrideRedirect 0 + #define InputOutput 0 + #define NormalState 0 + #define StateHint 0 + #define InputHint 0 + #define USPosition 0 + #define ClientMessage 0 + #define SubstructureRedirectMask 0 + #define SubstructureNotifyMask 0 + #define CurrentTime 0 + #define VisualIDMask 0 + #define AllocNone 0 + + enum X11Bool + { + False + , + True + }; + class NotPointerAtom{}; + typedef NotPointerAtom * Atom; + + class Display{}; + class XErrorEvent{}; + class XRRScreenConfiguration{}; + class Rotation{}; + class Visual{}; + #define Window NativeWindowType + + struct XVisualInfo{int visualid, visual, depth;}; + struct XRRScreenSize{int width, height;}; + struct XWMHints{int initial_state, input, flags;}; + struct XSizeHints{int flags;}; + struct XWindowAttributes{NativeWindowType root; int x, y, width, height;}; + struct XSetWindowAttributes{int background_pixel, border_pixel, colormap, event_mask, backing_store, save_under, override_redirect;}; + struct XTextProperty{int * value;}; + struct StrangeData{StrangeData(){}StrangeData(Atom atom){}StrangeData(int num){}}; + struct XClientMessageEventData{StrangeData l[3];}; + struct XClientMessageEvent{int type, serial, send_event, format; XClientMessageEventData data ; NativeWindowType window; Atom message_type;}; + struct XEvent{}; + + + void XStringListToTextProperty(char ** prop, int num, XTextProperty * textProp); + Window DefaultRootWindow(Display* nativeDisplayType); + bool XQueryExtension(Display* nativeDisplayType, char * name, int * dummy0, int * dummy2, int * dummy3); + XRRScreenConfiguration * XRRGetScreenInfo(Display* nativeDisplayType, Window window ); + int XRRConfigCurrentConfiguration(XRRScreenConfiguration * config, Rotation * rotation); + XRRScreenSize * XRRConfigSizes(XRRScreenConfiguration * config, int * nSizes); + int XRRConfigCurrentRate(XRRScreenConfiguration * config); + short * XRRConfigRates(XRRScreenConfiguration * config, int sizeID, int * nRates); + void XRRFreeScreenConfigInfo(XRRScreenConfiguration * config); + int DefaultScreen(NativeDisplayType nativeDisplayType); + int DisplayWidth(Display* nativeDisplayType, int screen); + int DisplayHeight(Display* nativeDisplayType, int screen); + Display* XOpenDisplay(int num); + void XCloseDisplay(Display* nativeDisplayType); + Atom XInternAtom(Display* nativeDisplayType, char * name, X11Bool isTrue);; + char * DisplayString(NativeDisplayType nativeDisplayType); + const char * XDisplayName(char * name); + Visual * DefaultVisual(Display* nativeDisplayType, int screen); + int XVisualIDFromVisual(Visual *v); + void XRRSetScreenConfigAndRate(Display* nativeDisplayType, XRRScreenConfiguration * config, Window window, int size, Rotation rotation, int mode, int currentTime ); + XVisualInfo * XGetVisualInfo(Display* nativeDisplayType, int mask, XVisualInfo * info, int * n); + typedef int (*XErrorHandler)(Display *, XErrorEvent*); + XErrorHandler XSetErrorHandler(XErrorHandler xErrorHandler); + void XDestroyWindow(Display* nativeDisplayType, Window nativeWindowType); + bool XGetWindowAttributes(Display* nativeDisplayType, Window nativeWindowType, XWindowAttributes * xWindowAttributes); + int XCreateColormap(Display* nativeDisplayType, Window nativeWindowType, int visual, int allocNone); + Window XCreateWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top, int width, int height, int dummy1, int depth, int inputOutput, int visual, int mask, XSetWindowAttributes * xSetWindowAttributes); + void XFree(void *data); + XWMHints * XAllocWMHints(); + XSizeHints * XAllocSizeHints(); + void XSetWMProperties(Display* nativeDisplayType, Window nativeWindowType,XTextProperty * titleprop, char * dummy1, char * dummy2, int num, XSizeHints *sizeHints, XWMHints *wmHints, char * dummy3); + void XSetWMProtocols(Display* nativeDisplayType, Window nativeWindowType, Atom * atom, int num); + void XMapWindow(Display* nativeDisplayType, Window nativeWindowType); + void XFlush(Display* nativeDisplayType); + void XMoveWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top); + void XResizeWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top); + void XQueryTree(Display* nativeDisplayType, Window nativeWindowType, Window * root, Window *parent, Window **children, unsigned int * nChildren); + void XSendEvent(Display* nativeDisplayType, Window nativeWindowType, int dummy1, int mask, XEvent* xevent); #endif namespace Ogre { class _OgrePrivate X11EGLSupport : public EGLSupport { - protected: + protected: - //removed createEGLWindow because it was easier to just use - // new X11EGLWindow in the code to get the native version. - //virtual EGLWindow* createEGLWindow( EGLSupport * support); + //removed createEGLWindow because it was easier to just use + // new X11EGLWindow in the code to get the native version. + //virtual EGLWindow* createEGLWindow( EGLSupport * support); public: X11EGLSupport(); virtual ~X11EGLSupport(); - virtual GLESPBuffer* createPBuffer(PixelComponentType format, - size_t width, size_t height); + virtual GLESPBuffer* createPBuffer(PixelComponentType format, + size_t width, size_t height); - virtual void switchMode(uint& width, uint& height, short& frequency); - String getDisplayName(void); + virtual void switchMode(uint& width, uint& height, short& frequency); + String getDisplayName(void); - NativeDisplayType getNativeDisplay(void); - XVisualInfo *getVisualFromFBConfig(::EGLConfig glConfig); - Atom mAtomDeleteWindow; - Atom mAtomFullScreen; - Atom mAtomState; + NativeDisplayType getNativeDisplay(void); + XVisualInfo *getVisualFromFBConfig(::EGLConfig glConfig); + Atom mAtomDeleteWindow; + Atom mAtomFullScreen; + Atom mAtomState; - // This just sets the native variables needed by EGLSupport::getGLDisplay - //Then it calls EGLSupport::getDLDisplay to do the rest of the work. - EGLDisplay getGLDisplay(); + // This just sets the native variables needed by EGLSupport::getGLDisplay + //Then it calls EGLSupport::getDLDisplay to do the rest of the work. + EGLDisplay getGLDisplay(); - //Moved this here from EGLSupport because maybe it should be more native. - RenderWindow* newWindow(const String& name, - unsigned int width, unsigned int height, - bool fullScreen, - const NameValuePairList *miscParams = 0); + //Moved this here from EGLSupport because maybe it should be more native. + RenderWindow* newWindow(const String& name, + unsigned int width, unsigned int height, + bool fullScreen, + const NameValuePairList *miscParams = 0); - }; + }; } #endif diff --git a/RenderSystems/GLES/include/EGL/X11/OgreX11EGLWindow.h b/RenderSystems/GLES/include/EGL/X11/OgreX11EGLWindow.h index 8c99e761617..8386a61063c 100644 --- a/RenderSystems/GLES/include/EGL/X11/OgreX11EGLWindow.h +++ b/RenderSystems/GLES/include/EGL/X11/OgreX11EGLWindow.h @@ -36,42 +36,42 @@ THE SOFTWARE. namespace Ogre { class _OgrePrivate X11EGLWindow : public EGLWindow { - protected: - X11EGLSupport* mGLSupport; + protected: + X11EGLSupport* mGLSupport; - //Changed these variables back to Window type because - //it seems they are not used outside this class. - Window mParentWindow; - Window mExternalWindow; - virtual EGLContext * createEGLContext() const; - virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); - virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); - virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); - virtual void reposition(int left, int top); - virtual void resize(unsigned int width, unsigned int height); - virtual void windowMovedOrResized(); - virtual void switchFullScreen(bool fullscreen); + //Changed these variables back to Window type because + //it seems they are not used outside this class. + Window mParentWindow; + Window mExternalWindow; + virtual EGLContext * createEGLContext() const; + virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); + virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); + virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); + virtual void reposition(int left, int top); + virtual void resize(unsigned int width, unsigned int height); + virtual void windowMovedOrResized(); + virtual void switchFullScreen(bool fullscreen); - public: + public: X11EGLWindow(X11EGLSupport* glsupport); virtual ~X11EGLWindow(); - /** - @remarks - * Get custom attribute; the following attributes are valid: - * XDISPLAY The X Display connection behind that context. - * XWINDOW The X NativeWindowType connection behind that context. - * ATOM The X Atom used in client delete events. - */ - virtual void getCustomAttribute(const String& name, void* pData); + /** + @remarks + * Get custom attribute; the following attributes are valid: + * XDISPLAY The X Display connection behind that context. + * XWINDOW The X NativeWindowType connection behind that context. + * ATOM The X Atom used in client delete events. + */ + virtual void getCustomAttribute(const String& name, void* pData); - virtual void setFullscreen (bool fullscreen, uint width, uint height); + virtual void setFullscreen (bool fullscreen, uint width, uint height); - //Moved this from EGLWindow because it has some native calls. + //Moved this from EGLWindow because it has some native calls. void create(const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams); - }; + }; } #endif diff --git a/RenderSystems/GLES/include/OgreGLESDefaultHardwareBufferManager.h b/RenderSystems/GLES/include/OgreGLESDefaultHardwareBufferManager.h index 164d686324a..c50144e6cfd 100644 --- a/RenderSystems/GLES/include/OgreGLESDefaultHardwareBufferManager.h +++ b/RenderSystems/GLES/include/OgreGLESDefaultHardwareBufferManager.h @@ -112,7 +112,7 @@ namespace Ogre { createIndexBuffer(HardwareIndexBuffer::IndexType itype, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer = false); /// Create a render to vertex buffer - RenderToVertexBufferSharedPtr createRenderToVertexBuffer(void); + RenderToVertexBufferSharedPtr createRenderToVertexBuffer(void); HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name = "") { @@ -120,7 +120,7 @@ namespace Ogre { "GLES does not support uniform buffer objects", "GLESDefaultHardwareBufferManagerBase::createUniformBuffer"); } - HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, + HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, bool useShadowBuffer = false, const String& name = "") { @@ -130,19 +130,19 @@ namespace Ogre { } }; - /// GLESDefaultHardwareBufferManagerBase as a Singleton - class _OgreGLESExport GLESDefaultHardwareBufferManager : public HardwareBufferManager - { - public: - GLESDefaultHardwareBufferManager() - : HardwareBufferManager(OGRE_NEW GLESDefaultHardwareBufferManagerBase()) - { - - } - ~GLESDefaultHardwareBufferManager() - { - OGRE_DELETE mImpl; - } + /// GLESDefaultHardwareBufferManagerBase as a Singleton + class _OgreGLESExport GLESDefaultHardwareBufferManager : public HardwareBufferManager + { + public: + GLESDefaultHardwareBufferManager() + : HardwareBufferManager(OGRE_NEW GLESDefaultHardwareBufferManagerBase()) + { + + } + ~GLESDefaultHardwareBufferManager() + { + OGRE_DELETE mImpl; + } HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name = "") { @@ -150,7 +150,7 @@ namespace Ogre { "GLES does not support render to vertex buffer objects", "GLESDefaultHardwareBufferManager::createUniformBuffer"); } - }; + }; } #endif diff --git a/RenderSystems/GLES/include/OgreGLESDepthBuffer.h b/RenderSystems/GLES/include/OgreGLESDepthBuffer.h index 6cab062e6fd..fe3220e57c8 100644 --- a/RenderSystems/GLES/include/OgreGLESDepthBuffer.h +++ b/RenderSystems/GLES/include/OgreGLESDepthBuffer.h @@ -35,39 +35,39 @@ THE SOFTWARE. namespace Ogre { - /** - @copydoc DepthBuffer + /** + @copydoc DepthBuffer - OpenGL supports 2 different methods: FBO & Copy. - Each one has it's own limitations. Non-FBO methods are solved using "dummy" DepthBuffers. - That is, a DepthBuffer pointer is attached to the RenderTarget (for the sake of consistency) - but it doesn't actually contain a Depth surface/renderbuffer (mDepthBuffer & mStencilBuffer are - null pointers all the time) Those dummy DepthBuffers are identified thanks to their GL context. - Note that FBOs don't allow sharing with the main window's depth buffer. Therefore even - when FBO is enabled, a dummy DepthBuffer is still used to manage the windows. - */ - class GLESDepthBuffer : public DepthBuffer - { - public: - GLESDepthBuffer( uint16 poolId, GLESRenderSystem *renderSystem, GLESContext *creatorContext, - GLESRenderBuffer *depth, GLESRenderBuffer *stencil, - uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, - bool isManual ); - ~GLESDepthBuffer(); + OpenGL supports 2 different methods: FBO & Copy. + Each one has it's own limitations. Non-FBO methods are solved using "dummy" DepthBuffers. + That is, a DepthBuffer pointer is attached to the RenderTarget (for the sake of consistency) + but it doesn't actually contain a Depth surface/renderbuffer (mDepthBuffer & mStencilBuffer are + null pointers all the time) Those dummy DepthBuffers are identified thanks to their GL context. + Note that FBOs don't allow sharing with the main window's depth buffer. Therefore even + when FBO is enabled, a dummy DepthBuffer is still used to manage the windows. + */ + class GLESDepthBuffer : public DepthBuffer + { + public: + GLESDepthBuffer( uint16 poolId, GLESRenderSystem *renderSystem, GLESContext *creatorContext, + GLESRenderBuffer *depth, GLESRenderBuffer *stencil, + uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, + bool isManual ); + ~GLESDepthBuffer(); - /// @copydoc DepthBuffer::isCompatible - virtual bool isCompatible( RenderTarget *renderTarget ) const; + /// @copydoc DepthBuffer::isCompatible + virtual bool isCompatible( RenderTarget *renderTarget ) const; - GLESContext* getGLContext() const { return mCreatorContext; } - GLESRenderBuffer* getDepthBuffer() const { return mDepthBuffer; } - GLESRenderBuffer* getStencilBuffer() const { return mStencilBuffer; } + GLESContext* getGLContext() const { return mCreatorContext; } + GLESRenderBuffer* getDepthBuffer() const { return mDepthBuffer; } + GLESRenderBuffer* getStencilBuffer() const { return mStencilBuffer; } - protected: - uint32 mMultiSampleQuality; - GLESContext *mCreatorContext; - GLESRenderBuffer *mDepthBuffer; - GLESRenderBuffer *mStencilBuffer; - GLESRenderSystem *mRenderSystem; - }; + protected: + uint32 mMultiSampleQuality; + GLESContext *mCreatorContext; + GLESRenderBuffer *mDepthBuffer; + GLESRenderBuffer *mStencilBuffer; + GLESRenderSystem *mRenderSystem; + }; } #endif diff --git a/RenderSystems/GLES/include/OgreGLESFBOMultiRenderTarget.h b/RenderSystems/GLES/include/OgreGLESFBOMultiRenderTarget.h index 8377910eead..772e5084814 100644 --- a/RenderSystems/GLES/include/OgreGLESFBOMultiRenderTarget.h +++ b/RenderSystems/GLES/include/OgreGLESFBOMultiRenderTarget.h @@ -35,27 +35,27 @@ namespace Ogre { class GLESFBOManager; - /** MultiRenderTarget for GL ES. Requires the FBO extension. - */ - class _OgreGLESExport GLESFBOMultiRenderTarget : public MultiRenderTarget - { - public: - GLESFBOMultiRenderTarget(GLESFBOManager *manager, const String &name); - ~GLESFBOMultiRenderTarget(); - - virtual void getCustomAttribute( const String& name, void *pData ); - - bool requiresTextureFlipping() const { return true; } - - /// Override so we can attach the depth buffer to the FBO - virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); - virtual void detachDepthBuffer(); - virtual void _detachDepthBuffer(); - private: - virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); - virtual void unbindSurfaceImpl(size_t attachment); - GLESFrameBufferObject fbo; - }; + /** MultiRenderTarget for GL ES. Requires the FBO extension. + */ + class _OgreGLESExport GLESFBOMultiRenderTarget : public MultiRenderTarget + { + public: + GLESFBOMultiRenderTarget(GLESFBOManager *manager, const String &name); + ~GLESFBOMultiRenderTarget(); + + virtual void getCustomAttribute( const String& name, void *pData ); + + bool requiresTextureFlipping() const { return true; } + + /// Override so we can attach the depth buffer to the FBO + virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); + virtual void detachDepthBuffer(); + virtual void _detachDepthBuffer(); + private: + virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); + virtual void unbindSurfaceImpl(size_t attachment); + GLESFrameBufferObject fbo; + }; } diff --git a/RenderSystems/GLES/include/OgreGLESFBORenderTexture.h b/RenderSystems/GLES/include/OgreGLESFBORenderTexture.h index cc73fc7f58b..f5bbf7bf964 100644 --- a/RenderSystems/GLES/include/OgreGLESFBORenderTexture.h +++ b/RenderSystems/GLES/include/OgreGLESFBORenderTexture.h @@ -46,13 +46,13 @@ namespace Ogre { virtual void getCustomAttribute(const String& name, void* pData); - /// Override needed to deal with multisample buffers - virtual void swapBuffers(); + /// Override needed to deal with multisample buffers + virtual void swapBuffers(); - /// Override so we can attach the depth buffer to the FBO - virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); - virtual void detachDepthBuffer(); - virtual void _detachDepthBuffer(); + /// Override so we can attach the depth buffer to the FBO + virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); + virtual void detachDepthBuffer(); + virtual void _detachDepthBuffer(); protected: GLESFrameBufferObject mFB; @@ -71,7 +71,7 @@ namespace Ogre { { public: GLESFBOManager(); - ~GLESFBOManager(); + ~GLESFBOManager(); /** Bind a certain render target if it is a FBO. If it is not a FBO, bind the main frame buffer. @@ -89,11 +89,11 @@ namespace Ogre { /** Create a texture rendertarget object */ virtual GLESFBORenderTexture *createRenderTexture(const String &name, - const GLESSurfaceDesc &target, bool writeGamma, uint fsaa); + const GLESSurfaceDesc &target, bool writeGamma, uint fsaa); - /** Create a multi render target - */ - virtual MultiRenderTarget* createMultiRenderTarget(const String & name); + /** Create a multi render target + */ + virtual MultiRenderTarget* createMultiRenderTarget(const String & name); /** Request a render buffer. If format is GL_NONE, return a zero buffer. */ @@ -150,7 +150,7 @@ namespace Ogre { GLenum format; size_t width; size_t height; - uint samples; + uint samples; // Overloaded comparison operator for usage in map bool operator < (const RBFormat &other) const { @@ -168,11 +168,11 @@ namespace Ogre { { if(height < other.height) return true; - else if (height == other.height) - { - if (samples < other.samples) - return true; - } + else if (height == other.height) + { + if (samples < other.samples) + return true; + } } } return false; diff --git a/RenderSystems/GLES/include/OgreGLESFrameBufferObject.h b/RenderSystems/GLES/include/OgreGLESFrameBufferObject.h index d118dc9af69..3c23b636943 100644 --- a/RenderSystems/GLES/include/OgreGLESFrameBufferObject.h +++ b/RenderSystems/GLES/include/OgreGLESFrameBufferObject.h @@ -56,26 +56,26 @@ namespace Ogre { */ void bind(); - /** Swap buffers - only useful when using multisample buffers. - */ - void swapBuffers(); + /** Swap buffers - only useful when using multisample buffers. + */ + void swapBuffers(); /** This function acts very similar to @see GLESFBORenderTexture::attachDepthBuffer - The difference between D3D & OGL is that D3D setups the DepthBuffer before rendering, - while OGL setups the DepthBuffer per FBO. So the DepthBuffer (RenderBuffer) needs to - be attached for OGL. - */ - void attachDepthBuffer( DepthBuffer *depthBuffer ); - void detachDepthBuffer(); + The difference between D3D & OGL is that D3D setups the DepthBuffer before rendering, + while OGL setups the DepthBuffer per FBO. So the DepthBuffer (RenderBuffer) needs to + be attached for OGL. + */ + void attachDepthBuffer( DepthBuffer *depthBuffer ); + void detachDepthBuffer(); /// Accessors uint32 getWidth(); uint32 getHeight(); PixelFormat getFormat(); - GLsizei getFSAA(); + GLsizei getFSAA(); GLESFBOManager *getManager() { return mManager; } - const GLESSurfaceDesc &getSurface(size_t attachment) { return mColour[attachment]; } + const GLESSurfaceDesc &getSurface(size_t attachment) { return mColour[attachment]; } #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID /** See AndroidResource. */ @@ -87,17 +87,17 @@ namespace Ogre { private: GLESFBOManager *mManager; - GLsizei mNumSamples; + GLsizei mNumSamples; GLuint mFB; - GLuint mMultisampleFB; - GLESSurfaceDesc mMultisampleColourBuffer; + GLuint mMultisampleFB; + GLESSurfaceDesc mMultisampleColourBuffer; GLESSurfaceDesc mDepth; GLESSurfaceDesc mStencil; // Arbitrary number of texture surfaces GLESSurfaceDesc mColour[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - /** Initialise object (find suitable depth and stencil format). + /** Initialise object (find suitable depth and stencil format). Must be called every time the bindings change. It fails with an exception (ERR_INVALIDPARAMS) if: - Attachment point 0 has no binding diff --git a/RenderSystems/GLES/include/OgreGLESHardwareBufferManager.h b/RenderSystems/GLES/include/OgreGLESHardwareBufferManager.h index af831cf98a8..acc42696bbd 100644 --- a/RenderSystems/GLES/include/OgreGLESHardwareBufferManager.h +++ b/RenderSystems/GLES/include/OgreGLESHardwareBufferManager.h @@ -56,8 +56,8 @@ namespace Ogre { HardwareIndexBufferSharedPtr createIndexBuffer( HardwareIndexBuffer::IndexType itype, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// Create a render to vertex buffer - RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); + /// Create a render to vertex buffer + RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); /// Utility function to get the correct GL usage based on HBU's static GLenum getGLUsage(unsigned int usage); @@ -77,7 +77,7 @@ namespace Ogre { /// @see allocateScratch void deallocateScratch(void* ptr); - /** Threshold after which glMapBuffer is used and not glBufferSubData + /** Threshold after which glMapBuffer is used and not glBufferSubData */ size_t getGLMapBufferThreshold() const; void setGLMapBufferThreshold( const size_t value ); @@ -88,59 +88,59 @@ namespace Ogre { bool useShadowBuffer = false, const String& name = ""); }; - /// GLESHardwareBufferManagerBase as a Singleton - class _OgreGLESExport GLESHardwareBufferManager : public HardwareBufferManager - { - public: - GLESHardwareBufferManager() - : HardwareBufferManager(OGRE_NEW GLESHardwareBufferManagerBase()) - { - - } - ~GLESHardwareBufferManager() - { - OGRE_DELETE mImpl; - } - - - - /// Utility function to get the correct GL usage based on HBU's - static GLenum getGLUsage(unsigned int usage) - { return GLESHardwareBufferManagerBase::getGLUsage(usage); } - - /// Utility function to get the correct GL type based on VET's - static GLenum getGLType(unsigned int type) - { return GLESHardwareBufferManagerBase::getGLType(type); } - - /** Allocator method to allow us to use a pool of memory as a scratch - area for hardware buffers. This is because glMapBuffer is incredibly - inefficient, seemingly no matter what options we give it. So for the - period of lock/unlock, we will instead allocate a section of a local - memory pool, and use glBufferSubDataARB / glGetBufferSubDataARB - instead. - */ - void* allocateScratch(uint32 size) - { - return static_cast(mImpl)->allocateScratch(size); - } - - /// @see allocateScratch - void deallocateScratch(void* ptr) - { - static_cast(mImpl)->deallocateScratch(ptr); - } + /// GLESHardwareBufferManagerBase as a Singleton + class _OgreGLESExport GLESHardwareBufferManager : public HardwareBufferManager + { + public: + GLESHardwareBufferManager() + : HardwareBufferManager(OGRE_NEW GLESHardwareBufferManagerBase()) + { + + } + ~GLESHardwareBufferManager() + { + OGRE_DELETE mImpl; + } + + + + /// Utility function to get the correct GL usage based on HBU's + static GLenum getGLUsage(unsigned int usage) + { return GLESHardwareBufferManagerBase::getGLUsage(usage); } + + /// Utility function to get the correct GL type based on VET's + static GLenum getGLType(unsigned int type) + { return GLESHardwareBufferManagerBase::getGLType(type); } + + /** Allocator method to allow us to use a pool of memory as a scratch + area for hardware buffers. This is because glMapBuffer is incredibly + inefficient, seemingly no matter what options we give it. So for the + period of lock/unlock, we will instead allocate a section of a local + memory pool, and use glBufferSubDataARB / glGetBufferSubDataARB + instead. + */ + void* allocateScratch(uint32 size) + { + return static_cast(mImpl)->allocateScratch(size); + } + + /// @see allocateScratch + void deallocateScratch(void* ptr) + { + static_cast(mImpl)->deallocateScratch(ptr); + } /** Threshold after which glMapBuffer is used and not glBufferSubData - */ - size_t getGLMapBufferThreshold() const - { - return static_cast(mImpl)->getGLMapBufferThreshold(); - } - void setGLMapBufferThreshold( const size_t value ) - { - static_cast(mImpl)->setGLMapBufferThreshold(value); - } - - }; + */ + size_t getGLMapBufferThreshold() const + { + return static_cast(mImpl)->getGLMapBufferThreshold(); + } + void setGLMapBufferThreshold( const size_t value ) + { + static_cast(mImpl)->setGLMapBufferThreshold(value); + } + + }; } diff --git a/RenderSystems/GLES/include/OgreGLESPrerequisites.h b/RenderSystems/GLES/include/OgreGLESPrerequisites.h index dc745ee4ce5..26832200511 100644 --- a/RenderSystems/GLES/include/OgreGLESPrerequisites.h +++ b/RenderSystems/GLES/include/OgreGLESPrerequisites.h @@ -34,14 +34,14 @@ THE SOFTWARE. #include "OgreMath.h" #if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) -# if !defined( __MINGW32__ ) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN 1 -# endif -# ifndef NOMINMAX -# define NOMINMAX // required to stop windows.h messing up std::min -# endif -# endif +# if !defined( __MINGW32__ ) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN 1 +# endif +# ifndef NOMINMAX +# define NOMINMAX // required to stop windows.h messing up std::min +# endif +# endif #endif #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) @@ -50,16 +50,16 @@ THE SOFTWARE. # ifdef __OBJC__ # include # endif -# ifndef GL_GLEXT_PROTOTYPES -# define GL_GLEXT_PROTOTYPES -# endif +# ifndef GL_GLEXT_PROTOTYPES +# define GL_GLEXT_PROTOTYPES +# endif #elif (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) -# ifndef GL_GLEXT_PROTOTYPES -# define GL_GLEXT_PROTOTYPES -# endif -# include -# include -# include +# ifndef GL_GLEXT_PROTOTYPES +# define GL_GLEXT_PROTOTYPES +# endif +# include +# include +# include # include #else # include @@ -69,25 +69,25 @@ THE SOFTWARE. // If we are going to use the PVRTC_CODEC make sure we // setup the needed constants #if OGRE_NO_PVRTC_CODEC == 0 -# ifndef GL_IMG_texture_compression_pvrtc -# define GL_IMG_texture_compression_pvrtc 1 -# define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 -# define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 -# define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 -# define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 -# endif +# ifndef GL_IMG_texture_compression_pvrtc +# define GL_IMG_texture_compression_pvrtc 1 +# define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +# define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +# define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +# define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +# endif #endif /* GL_EXT_texture_compression_dxt1 */ #ifndef GL_EXT_texture_compression_dxt1 -# define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -# define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +# define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +# define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #endif // Function pointers for FBO extension methods // Declare them here since we don't have GLEW to do it for us -# ifndef GL_GLEXT_PROTOTYPES +# ifndef GL_GLEXT_PROTOTYPES extern PFNGLISRENDERBUFFEROESPROC glIsRenderbufferOES; extern PFNGLBINDRENDERBUFFEROESPROC glBindRenderbufferOES; extern PFNGLDELETERENDERBUFFERSOESPROC glDeleteRenderbuffersOES; @@ -108,7 +108,7 @@ extern PFNGLBLENDFUNCSEPARATEOESPROC glBlendFuncSeparateOES; extern PFNGLBLENDEQUATIONSEPARATEOESPROC glBlendEquationSeparateOES; extern PFNGLMAPBUFFEROESPROC glMapBufferOES; extern PFNGLUNMAPBUFFEROESPROC glUnmapBufferOES; -# endif +# endif #endif diff --git a/RenderSystems/GLES/include/OgreGLESRenderSystem.h b/RenderSystems/GLES/include/OgreGLESRenderSystem.h index 167e1feb667..a586f7e2eea 100644 --- a/RenderSystems/GLES/include/OgreGLESRenderSystem.h +++ b/RenderSystems/GLES/include/OgreGLESRenderSystem.h @@ -127,8 +127,8 @@ namespace Ogre { bool activateGLTextureUnit(size_t unit); bool activateGLClientTextureUnit(size_t unit); - // Mipmap count of the actual bounded texture - size_t mCurTexMipCount; + // Mipmap count of the actual bounded texture + size_t mCurTexMipCount; public: // Default constructor / destructor GLESRenderSystem(); @@ -382,17 +382,17 @@ namespace Ogre { StencilOperation stencilFailOp = SOP_KEEP, StencilOperation depthFailOp = SOP_KEEP, StencilOperation passOp = SOP_KEEP, - bool twoSidedOperation = false, - bool readBackAsTexture = false); + bool twoSidedOperation = false, + bool readBackAsTexture = false); /** See RenderSystem */ void _setTextureUnitCompareFunction(size_t unit, CompareFunction function); - /** See + /** See RenderSystem */ - virtual void _setTextureUnitFiltering(size_t unit, FilterOptions minFilter, - FilterOptions magFilter, FilterOptions mipFilter); + virtual void _setTextureUnitFiltering(size_t unit, FilterOptions minFilter, + FilterOptions magFilter, FilterOptions mipFilter); /** See RenderSystem */ @@ -477,14 +477,14 @@ namespace Ogre { void bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params, uint16 mask); void bindGpuProgramPassIterationParameters(GpuProgramType gptype); - /// @copydoc RenderSystem::_setSceneBlending - void _setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op ); - /// @copydoc RenderSystem::_setSeparateSceneBlending - void _setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ); - /// @copydoc RenderSystem::_setAlphaRejectSettings - void _setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ); - /// @copydoc RenderSystem::getDisplayMonitorCount - unsigned int getDisplayMonitorCount() const; + /// @copydoc RenderSystem::_setSceneBlending + void _setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op ); + /// @copydoc RenderSystem::_setSeparateSceneBlending + void _setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ); + /// @copydoc RenderSystem::_setAlphaRejectSettings + void _setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ); + /// @copydoc RenderSystem::getDisplayMonitorCount + unsigned int getDisplayMonitorCount() const; /// Internal method for anisotropy validation GLfloat _getCurrentAnisotropy(size_t unit); diff --git a/RenderSystems/GLES/include/OgreGLESStateCacheManager.h b/RenderSystems/GLES/include/OgreGLESStateCacheManager.h index c34844d7a2f..620abe285cb 100644 --- a/RenderSystems/GLES/include/OgreGLESStateCacheManager.h +++ b/RenderSystems/GLES/include/OgreGLESStateCacheManager.h @@ -68,21 +68,21 @@ namespace Ogre */ void clearCache(); - /** Bind an OpenGL buffer of any type. + /** Bind an OpenGL buffer of any type. @param target The buffer target. @param buffer The buffer ID. @param force Optional parameter to force an update. */ void bindGLBuffer(GLenum target, GLuint buffer, GLenum attach = 0, bool force = false); - /** Delete an OpenGL buffer of any type. + /** Delete an OpenGL buffer of any type. @param target The buffer target. @param buffer The buffer ID. @param force Optional parameter to force an update. */ void deleteGLBuffer(GLenum target, GLuint buffer, GLenum attach = 0, bool force = false); - /** Bind an OpenGL texture of any type. + /** Bind an OpenGL texture of any type. @param target The texture target. @param texture The texture ID. */ @@ -137,7 +137,7 @@ namespace Ogre */ void setDepthFunc(GLenum func); - /** Gets the clear depth in the range from [0..1]. + /** Gets the clear depth in the range from [0..1]. @return The current clearing depth. */ GLclampf getClearDepth(void) const; diff --git a/RenderSystems/GLES/src/EGL/Android/OgreAndroidEGLSupport.cpp b/RenderSystems/GLES/src/EGL/Android/OgreAndroidEGLSupport.cpp index 7c8518e45e7..638537e0307 100644 --- a/RenderSystems/GLES/src/EGL/Android/OgreAndroidEGLSupport.cpp +++ b/RenderSystems/GLES/src/EGL/Android/OgreAndroidEGLSupport.cpp @@ -47,10 +47,10 @@ namespace Ogre { mGLDisplay = getGLDisplay(); mCurrentMode.first.first = 1280; - mCurrentMode.first.second = 800; - mCurrentMode.second = 0; - mOriginalMode = mCurrentMode; - mVideoModes.push_back(mCurrentMode); + mCurrentMode.first.second = 800; + mCurrentMode.second = 0; + mOriginalMode = mCurrentMode; + mVideoModes.push_back(mCurrentMode); ConfigOption optOrientation; optOrientation.name = "Orientation"; @@ -65,24 +65,24 @@ namespace Ogre { AndroidEGLSupport::~AndroidEGLSupport() { - } + } void AndroidEGLSupport::switchMode( uint& width, uint& height, short& frequency ) - { - if (!mRandr) - return; + { + if (!mRandr) + return; } RenderWindow* AndroidEGLSupport::newWindow( const String &name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams) - { - AndroidEGLWindow* window = new AndroidEGLWindow(this); - window->create(name, width, height, fullScreen, miscParams); + { + AndroidEGLWindow* window = new AndroidEGLWindow(this); + window->create(name, width, height, fullScreen, miscParams); - return window; - } + return window; + } GLESPBuffer* AndroidEGLSupport::createPBuffer( PixelComponentType format, size_t width, size_t height ) - { - return new EGLPBuffer(this, format, width, height); - } + { + return new EGLPBuffer(this, format, width, height); + } } diff --git a/RenderSystems/GLES/src/EGL/Android/OgreAndroidEGLWindow.cpp b/RenderSystems/GLES/src/EGL/Android/OgreAndroidEGLWindow.cpp index 569d3fbdb73..d01622fa582 100644 --- a/RenderSystems/GLES/src/EGL/Android/OgreAndroidEGLWindow.cpp +++ b/RenderSystems/GLES/src/EGL/Android/OgreAndroidEGLWindow.cpp @@ -46,52 +46,52 @@ THE SOFTWARE. #include namespace Ogre { - AndroidEGLWindow::AndroidEGLWindow(AndroidEGLSupport *glsupport) - : EGLWindow(glsupport), - mMaxBufferSize(32), - mMaxDepthSize(24), - mMaxStencilSize(8) - { - } + AndroidEGLWindow::AndroidEGLWindow(AndroidEGLSupport *glsupport) + : EGLWindow(glsupport), + mMaxBufferSize(32), + mMaxDepthSize(24), + mMaxStencilSize(8) + { + } - AndroidEGLWindow::~AndroidEGLWindow() - { - } + AndroidEGLWindow::~AndroidEGLWindow() + { + } - EGLContext* AndroidEGLWindow::createEGLContext() const - { - return new AndroidEGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); - } + EGLContext* AndroidEGLWindow::createEGLContext() const + { + return new AndroidEGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); + } - void AndroidEGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) - { - // We don't have a native window.... but I think all android windows are origined - left = top = 0; - } + void AndroidEGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) + { + // We don't have a native window.... but I think all android windows are origined + left = top = 0; + } - void AndroidEGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) - { - } + void AndroidEGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) + { + } - void AndroidEGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) - { - } + void AndroidEGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) + { + } - void AndroidEGLWindow::reposition( int left, int top ) - { - } + void AndroidEGLWindow::reposition( int left, int top ) + { + } - void AndroidEGLWindow::resize(uint width, uint height) - { - } + void AndroidEGLWindow::resize(uint width, uint height) + { + } - void AndroidEGLWindow::windowMovedOrResized() - { + void AndroidEGLWindow::windowMovedOrResized() + { if(mActive) { eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, (EGLint*)&mWidth); - EGL_CHECK_ERROR - + EGL_CHECK_ERROR + eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, (EGLint*)&mHeight); EGL_CHECK_ERROR @@ -100,8 +100,8 @@ namespace Ogre { while( it != mViewportList.end() ) (*it++).second->_updateDimensions(); } - } - + } + void AndroidEGLWindow::switchFullScreen(bool fullscreen) { @@ -110,7 +110,7 @@ namespace Ogre { void AndroidEGLWindow::create(const String& name, uint width, uint height, bool fullScreen, const NameValuePairList *miscParams) { - mName = name; + mName = name; mWidth = width; mHeight = height; mLeft = 0; @@ -156,18 +156,18 @@ namespace Ogre { mIsExternalGLControl = true; ctxHandle = Ogre::StringConverter::parseInt(opt->second); } - - if((opt = miscParams->find("maxColourBufferSize")) != end) + + if((opt = miscParams->find("maxColourBufferSize")) != end) { mMaxBufferSize = Ogre::StringConverter::parseInt(opt->second); } - - if((opt = miscParams->find("maxDepthBufferSize")) != end) + + if((opt = miscParams->find("maxDepthBufferSize")) != end) { mMaxDepthSize = Ogre::StringConverter::parseInt(opt->second); } - - if((opt = miscParams->find("maxStencilBufferSize")) != end) + + if((opt = miscParams->find("maxStencilBufferSize")) != end) { mMaxStencilSize = Ogre::StringConverter::parseInt(opt->second); } @@ -204,10 +204,10 @@ namespace Ogre { mContext = createEGLContext(); - mActive = true; - mVisible = true; - mClosed = false; - } + mActive = true; + mVisible = true; + mClosed = false; + } void AndroidEGLWindow::_destroyInternalResources() { @@ -224,7 +224,7 @@ namespace Ogre { mEglSurface = 0; mActive = false; - mVisible = false; + mVisible = false; mClosed = true; } @@ -241,7 +241,7 @@ namespace Ogre { int maxAttribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, - EGL_BUFFER_SIZE, mMaxBufferSize, + EGL_BUFFER_SIZE, mMaxBufferSize, EGL_DEPTH_SIZE, mMaxDepthSize, EGL_STENCIL_SIZE, mMaxStencilSize, EGL_NONE diff --git a/RenderSystems/GLES/src/EGL/Android/OgreAndroidResource.cpp b/RenderSystems/GLES/src/EGL/Android/OgreAndroidResource.cpp index 14c73c974c8..0cd469530b4 100644 --- a/RenderSystems/GLES/src/EGL/Android/OgreAndroidResource.cpp +++ b/RenderSystems/GLES/src/EGL/Android/OgreAndroidResource.cpp @@ -31,13 +31,13 @@ THE SOFTWARE. namespace Ogre { - AndroidResource::AndroidResource() - { - GLESRenderSystem::getResourceManager()->_notifyResourceCreated(static_cast(this)); - } + AndroidResource::AndroidResource() + { + GLESRenderSystem::getResourceManager()->_notifyResourceCreated(static_cast(this)); + } - AndroidResource::~AndroidResource() - { - GLESRenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast(this)); - } + AndroidResource::~AndroidResource() + { + GLESRenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast(this)); + } } diff --git a/RenderSystems/GLES/src/EGL/Android/OgreAndroidResourceManager.cpp b/RenderSystems/GLES/src/EGL/Android/OgreAndroidResourceManager.cpp index 0e30fa94c3a..765ea86b092 100644 --- a/RenderSystems/GLES/src/EGL/Android/OgreAndroidResourceManager.cpp +++ b/RenderSystems/GLES/src/EGL/Android/OgreAndroidResourceManager.cpp @@ -30,45 +30,45 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - AndroidResourceManager::AndroidResourceManager() - { - } - //----------------------------------------------------------------------- - AndroidResourceManager::~AndroidResourceManager() - { - - } //----------------------------------------------------------------------- - void AndroidResourceManager::notifyOnContextLost() - { - ResourceContainerIterator it = mResources.begin(); - while (it != mResources.end()) - { - (*it)->notifyOnContextLost(); - ++it; - } - } + AndroidResourceManager::AndroidResourceManager() + { + } //----------------------------------------------------------------------- - void AndroidResourceManager::notifyOnContextReset() - { - ResourceContainerIterator it = mResources.begin(); - while (it != mResources.end()) - { - (*it)->notifyOnContextReset(); - ++it; - } - } - //----------------------------------------------------------------------- - void AndroidResourceManager::_notifyResourceCreated(AndroidResource* pResource) - { - mResources.push_back(pResource); - } - //----------------------------------------------------------------------- - void AndroidResourceManager::_notifyResourceDestroyed(AndroidResource* pResource) - { + AndroidResourceManager::~AndroidResourceManager() + { + + } + //----------------------------------------------------------------------- + void AndroidResourceManager::notifyOnContextLost() + { + ResourceContainerIterator it = mResources.begin(); + while (it != mResources.end()) + { + (*it)->notifyOnContextLost(); + ++it; + } + } + //----------------------------------------------------------------------- + void AndroidResourceManager::notifyOnContextReset() + { + ResourceContainerIterator it = mResources.begin(); + while (it != mResources.end()) + { + (*it)->notifyOnContextReset(); + ++it; + } + } + //----------------------------------------------------------------------- + void AndroidResourceManager::_notifyResourceCreated(AndroidResource* pResource) + { + mResources.push_back(pResource); + } + //----------------------------------------------------------------------- + void AndroidResourceManager::_notifyResourceDestroyed(AndroidResource* pResource) + { ResourceContainerIterator it = std::find( mResources.begin(), mResources.end(), pResource ); if(it != mResources.end()) mResources.erase(it); - } + } } diff --git a/RenderSystems/GLES/src/EGL/OgreEGLContext.cpp b/RenderSystems/GLES/src/EGL/OgreEGLContext.cpp index 356c6549ae9..987c23d8a10 100644 --- a/RenderSystems/GLES/src/EGL/OgreEGLContext.cpp +++ b/RenderSystems/GLES/src/EGL/OgreEGLContext.cpp @@ -35,14 +35,14 @@ THE SOFTWARE. namespace Ogre { EGLContext::EGLContext(EGLDisplay eglDisplay, - const EGLSupport* glsupport, + const EGLSupport* glsupport, ::EGLConfig glconfig, ::EGLSurface drawable) : mGLSupport(glsupport), mDrawable(drawable), mContext(0) { - assert(drawable); + assert(drawable); GLESRenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); EGLContext* mainContext = @@ -106,11 +106,11 @@ namespace Ogre { void EGLContext::endCurrent() { - eglMakeCurrent(mEglDisplay, 0, 0, 0); + eglMakeCurrent(mEglDisplay, 0, 0, 0); } - EGLSurface EGLContext::getDrawable() const - { - return mDrawable; - } + EGLSurface EGLContext::getDrawable() const + { + return mDrawable; + } } diff --git a/RenderSystems/GLES/src/EGL/OgreEGLRenderTexture.cpp b/RenderSystems/GLES/src/EGL/OgreEGLRenderTexture.cpp index 6881f9b7bf6..4211cffe9d0 100644 --- a/RenderSystems/GLES/src/EGL/OgreEGLRenderTexture.cpp +++ b/RenderSystems/GLES/src/EGL/OgreEGLRenderTexture.cpp @@ -52,14 +52,14 @@ namespace Ogre { } - //Changed the constructor to a member function so that the - //native constructor would be called first. This member - //function is then called from the native constructor. + //Changed the constructor to a member function so that the + //native constructor would be called first. This member + //function is then called from the native constructor. void EGLPBuffer::initEGLPBuffer() { -// These are now initialized in the native constructors. -// mGLSupport = glsupport; +// These are now initialized in the native constructors. +// mGLSupport = glsupport; // mGlDisplay = mGLSupport->getGLDisplay(); mEglDrawable = 0; ::EGLConfig glConfig = 0; @@ -109,17 +109,17 @@ namespace Ogre { }; EGLint pBufferAttribs[] = { - // First we specify the width of the surface... + // First we specify the width of the surface... EGL_WIDTH, mWidth, - // ...then the height of the surface... + // ...then the height of the surface... EGL_HEIGHT, mHeight, - /* ... then we specify the target for the texture - that will be created when the pbuffer is created...*/ - EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, - /*..then the format of the texture that will be created - when the pBuffer is bound to a texture...*/ + /* ... then we specify the target for the texture + that will be created when the pbuffer is created...*/ + EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, + /*..then the format of the texture that will be created + when the pBuffer is bound to a texture...*/ EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB, - // The final thing is EGL_NONE which signifies the end. + // The final thing is EGL_NONE which signifies the end. EGL_NONE }; @@ -155,7 +155,7 @@ namespace Ogre { EGLPBuffer::~EGLPBuffer() { - eglDestroySurface(mGlDisplay, mEglDrawable); + eglDestroySurface(mGlDisplay, mEglDrawable); LogManager::getSingleton().logMessage(LML_NORMAL, "EGLPBuffer::PBuffer destroyed"); } diff --git a/RenderSystems/GLES/src/EGL/OgreEGLSupport.cpp b/RenderSystems/GLES/src/EGL/OgreEGLSupport.cpp index 2e898d9a557..dae713e0157 100644 --- a/RenderSystems/GLES/src/EGL/OgreEGLSupport.cpp +++ b/RenderSystems/GLES/src/EGL/OgreEGLSupport.cpp @@ -46,16 +46,16 @@ namespace Ogre { EGLSupport::EGLSupport() : mGLDisplay(0), //mNativeDisplay(0), - mRandr(false) + mRandr(false) { // mGLDisplay = getGLDisplay(); -// mNativeDisplay = getNativeDisplay(); +// mNativeDisplay = getNativeDisplay(); } EGLSupport::~EGLSupport() { - } + } void EGLSupport::addConfig(void) { @@ -180,18 +180,18 @@ namespace Ogre { return BLANKSTRING; } - //Moved to native. -// NativeDisplayType EGLSupport::getNativeDisplay() -// { -// return EGL_DEFAULT_DISPLAY; // TODO -// } + //Moved to native. +// NativeDisplayType EGLSupport::getNativeDisplay() +// { +// return EGL_DEFAULT_DISPLAY; // TODO +// } EGLDisplay EGLSupport::getGLDisplay(void) { EGLint major, minor; - mGLDisplay = eglGetDisplay(mNativeDisplay); + mGLDisplay = eglGetDisplay(mNativeDisplay); if(mGLDisplay == EGL_NO_DISPLAY) { @@ -206,14 +206,14 @@ namespace Ogre { "Couldn`t initialize EGLDisplay ", "EGLSupport::getGLDisplay"); } - return mGLDisplay; + return mGLDisplay; } String EGLSupport::getDisplayName(void) { - return "todo"; - } + return "todo"; + } EGLConfig* EGLSupport::chooseGLConfig(const EGLint *attribList, EGLint *nElements) { @@ -228,7 +228,7 @@ namespace Ogre { *nElements = 0; return 0; - } + } configs = (EGLConfig*) malloc(*nElements * sizeof(EGLConfig)); if (eglChooseConfig(mGLDisplay, attribList, configs, *nElements, nElements) == EGL_FALSE) @@ -239,7 +239,7 @@ namespace Ogre { *nElements = 0; free(configs); - return 0; + return 0; } return configs; @@ -467,20 +467,20 @@ namespace Ogre { // } ::EGLContext EGLSupport::createNewContext(EGLDisplay eglDisplay, - ::EGLConfig glconfig, + ::EGLConfig glconfig, ::EGLContext shareList) const { - ::EGLContext context = ((::EGLContext) 0); - if (eglDisplay == ((EGLDisplay) 0)) - { - context = eglCreateContext(mGLDisplay, glconfig, shareList, 0); - } - else - { - context = eglCreateContext(eglDisplay, glconfig, 0, 0); - } - - if (context == ((::EGLContext) 0)) + ::EGLContext context = ((::EGLContext) 0); + if (eglDisplay == ((EGLDisplay) 0)) + { + context = eglCreateContext(mGLDisplay, glconfig, shareList, 0); + } + else + { + context = eglCreateContext(eglDisplay, glconfig, 0, 0); + } + + if (context == ((::EGLContext) 0)) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Fail to create New context", @@ -499,8 +499,8 @@ namespace Ogre { { } - void EGLSupport::setGLDisplay( EGLDisplay val ) - { - mGLDisplay = val; - } + void EGLSupport::setGLDisplay( EGLDisplay val ) + { + mGLDisplay = val; + } } diff --git a/RenderSystems/GLES/src/EGL/OgreEGLWindow.cpp b/RenderSystems/GLES/src/EGL/OgreEGLWindow.cpp index d0e053591b9..68ca7a6f3f5 100644 --- a/RenderSystems/GLES/src/EGL/OgreEGLWindow.cpp +++ b/RenderSystems/GLES/src/EGL/OgreEGLWindow.cpp @@ -48,18 +48,18 @@ namespace Ogre { EGLWindow::EGLWindow(EGLSupport *glsupport) : mGLSupport(glsupport), mContext(0), - mEglConfig(0), - mEglSurface(0), - mWindow(0), - mNativeDisplay(0), - mEglDisplay(EGL_NO_DISPLAY) + mEglConfig(0), + mEglSurface(0), + mWindow(0), + mNativeDisplay(0), + mEglDisplay(EGL_NO_DISPLAY) { mIsTopLevel = false; mIsFullScreen = false; mClosed = false; mActive = true;//todo mIsExternalGLControl = false; - mVisible = false; + mVisible = false; } EGLWindow::~EGLWindow() @@ -74,7 +74,7 @@ namespace Ogre { mContext = 0; } -// Moved EGLWindow::create to native source because it has native calls in it +// Moved EGLWindow::create to native source because it has native calls in it /* void EGLWindow::create(const String& name, uint width, uint height, bool fullScreen, const NameValuePairList *miscParams) { @@ -84,10 +84,10 @@ namespace Ogre { short frequency = 0; bool vsync = false; ::EGLContext eglContext = 0; - int left = 0; - int top = 0; + int left = 0; + int top = 0; - getLeftAndTopFromNativeWindow(left, top, width, height); + getLeftAndTopFromNativeWindow(left, top, width, height); mIsFullScreen = fullScreen; @@ -151,9 +151,9 @@ namespace Ogre { { mIsExternalGLControl = StringConverter::parseBool(opt->second); } - } + } - initNativeCreatedWindow(miscParams); + initNativeCreatedWindow(miscParams); if (mEglSurface) { @@ -207,12 +207,12 @@ namespace Ogre { mGLSupport->switchMode (width, height, frequency); } - if (!mIsExternal) + if (!mIsExternal) { - createNativeWindow(left, top, width, height, title); - } + createNativeWindow(left, top, width, height, title); + } - mContext = createEGLContext(); + mContext = createEGLContext(); ::EGLSurface oldDrawableDraw = eglGetCurrentSurface(EGL_DRAW); ::EGLSurface oldDrawableRead = eglGetCurrentSurface(EGL_READ); @@ -229,10 +229,10 @@ namespace Ogre { mLeft = left; mTop = top; mActive = true; - mVisible = true; + mVisible = true; mClosed = false; - }*/ + }*/ void EGLWindow::destroy(void) { @@ -269,7 +269,7 @@ namespace Ogre { { return; } - if (fullscreen) + if (fullscreen) { mGLSupport->switchMode(width, height, frequency); } @@ -317,7 +317,7 @@ namespace Ogre { glFlush(); if (eglSwapBuffers(mEglDisplay, mEglSurface) == EGL_FALSE) { - EGL_CHECK_ERROR + EGL_CHECK_ERROR OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Fail to SwapBuffers", __FUNCTION__); @@ -341,58 +341,58 @@ namespace Ogre { *static_cast(pData) = mContext; return; } - else if (name == "WINDOW") - { - *static_cast(pData) = mWindow; - return; - } - } + else if (name == "WINDOW") + { + *static_cast(pData) = mWindow; + return; + } + } void EGLWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) { - if ((dst.left < 0) || (dst.right > mWidth) || - (dst.top < 0) || (dst.bottom > mHeight) || - (dst.front != 0) || (dst.back != 1)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid box.", - "Win32Window::copyContentsToMemory" ); - } - - if (buffer == FB_AUTO) - { - buffer = mIsFullScreen? FB_FRONT : FB_BACK; - } - - GLenum format = GLESPixelUtil::getGLOriginFormat(dst.format); - GLenum type = GLESPixelUtil::getGLOriginDataType(dst.format); - - if ((format == 0) || (type == 0)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unsupported format.", - "GtkEGLWindow::copyContentsToMemory" ); - } - - - // Switch context if different from current one - RenderSystem* rsys = Root::getSingleton().getRenderSystem(); - rsys->_setViewport(this->getViewport(0)); + if ((dst.left < 0) || (dst.right > mWidth) || + (dst.top < 0) || (dst.bottom > mHeight) || + (dst.front != 0) || (dst.back != 1)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid box.", + "Win32Window::copyContentsToMemory" ); + } + + if (buffer == FB_AUTO) + { + buffer = mIsFullScreen? FB_FRONT : FB_BACK; + } + + GLenum format = GLESPixelUtil::getGLOriginFormat(dst.format); + GLenum type = GLESPixelUtil::getGLOriginDataType(dst.format); + + if ((format == 0) || (type == 0)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Unsupported format.", + "GtkEGLWindow::copyContentsToMemory" ); + } + + + // Switch context if different from current one + RenderSystem* rsys = Root::getSingleton().getRenderSystem(); + rsys->_setViewport(this->getViewport(0)); #if OGRE_NO_GLES3_SUPPORT == 0 if(dst.getWidth() != dst.rowPitch) glPixelStorei(GL_PACK_ROW_LENGTH, dst.rowPitch); #endif - // Must change the packing to ensure no overruns! - glPixelStorei(GL_PACK_ALIGNMENT, 1); + // Must change the packing to ensure no overruns! + glPixelStorei(GL_PACK_ALIGNMENT, 1); - //glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); + //glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); glReadPixels((GLint)0, (GLint)(mHeight - dst.getHeight()), (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(), format, type, dst.getTopLeftFrontPixelPtr()); - // restore default alignment - glPixelStorei(GL_PACK_ALIGNMENT, 4); + // restore default alignment + glPixelStorei(GL_PACK_ALIGNMENT, 4); #if OGRE_NO_GLES3_SUPPORT == 0 glPixelStorei(GL_PACK_ROW_LENGTH, 0); #endif @@ -415,9 +415,9 @@ namespace Ogre { return surface; } - bool EGLWindow::requiresTextureFlipping() const - { - return false; - } + bool EGLWindow::requiresTextureFlipping() const + { + return false; + } } diff --git a/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLContext.cpp b/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLContext.cpp index 09d8e2f3797..adeb822285b 100644 --- a/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLContext.cpp +++ b/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLContext.cpp @@ -35,7 +35,7 @@ THE SOFTWARE. namespace Ogre { Win32EGLContext::Win32EGLContext(EGLDisplay eglDisplay, - const EGLSupport* glsupport, + const EGLSupport* glsupport, ::EGLConfig glconfig, ::EGLSurface drawable) : EGLContext(eglDisplay, glsupport, glconfig, drawable) diff --git a/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLRenderTexture.cpp b/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLRenderTexture.cpp index 4df8fd6108f..ff9a24cb129 100644 --- a/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLRenderTexture.cpp +++ b/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLRenderTexture.cpp @@ -46,18 +46,18 @@ THE SOFTWARE. namespace Ogre { - Win32EGLPBuffer::Win32EGLPBuffer( Win32EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height ) - : EGLPBuffer(glsupport, format, width, height) - { - mGLSupport = glsupport; - mGlDisplay = glsupport->getGLDisplay(); - initEGLPBuffer(); + Win32EGLPBuffer::Win32EGLPBuffer( Win32EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height ) + : EGLPBuffer(glsupport, format, width, height) + { + mGLSupport = glsupport; + mGlDisplay = glsupport->getGLDisplay(); + initEGLPBuffer(); - } + } - Win32EGLPBuffer::~Win32EGLPBuffer() - { + Win32EGLPBuffer::~Win32EGLPBuffer() + { - } + } } diff --git a/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLSupport.cpp b/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLSupport.cpp index ba81fdc2075..31621aa00a6 100644 --- a/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLSupport.cpp +++ b/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLSupport.cpp @@ -45,111 +45,111 @@ THE SOFTWARE. namespace Ogre { - Win32EGLSupport::Win32EGLSupport() - { - //RECT windowRect; - //GetClientRect(mNativeDisplay, &windowRect); - mNativeDisplay = getNativeDisplay(); - mGLDisplay = getGLDisplay(); - - // Video mode possibilities - DEVMODE DevMode; - DevMode.dmSize = sizeof(DEVMODE); - for (DWORD i = 0; EnumDisplaySettings(NULL, i, &DevMode); ++i) - { - if (DevMode.dmBitsPerPel < 16) - continue; - - mCurrentMode.first.first = DevMode.dmPelsWidth; - mCurrentMode.first.second = DevMode.dmPelsHeight; - mCurrentMode.second = 0; - mOriginalMode = mCurrentMode; - mVideoModes.push_back(mCurrentMode); - } - - EGLConfig *glConfigs; - int config, nConfigs = 0; - - glConfigs = chooseGLConfig(NULL, &nConfigs); - - for (config = 0; config < nConfigs; config++) - { - int caveat, samples; - - getGLConfigAttrib(glConfigs[config], EGL_CONFIG_CAVEAT, &caveat); - - if (caveat != EGL_SLOW_CONFIG) - { - getGLConfigAttrib(glConfigs[config], EGL_SAMPLES, &samples); - mSampleLevels.push_back(StringConverter::toString(samples)); - } - } - - free(glConfigs); - - removeDuplicates(mSampleLevels); - - - } - - Win32EGLSupport::~Win32EGLSupport() - { - - } - - //Removed createEGLWindow because it was easier to call new Win32EGLWindow - //directly to get the native version. -// EGLWindow* Win32EGLSupport::createEGLWindow( EGLSupport * support ) -// { -// return new Win32EGLWindow(support); -// } - - GLESPBuffer* Win32EGLSupport::createPBuffer( PixelComponentType format, size_t width, size_t height ) - { - return new Win32EGLPBuffer(this, format, width, height); - } - - void Win32EGLSupport::switchMode( uint& width, uint& height, short& frequency ) - { - if (!mRandr) - return; - - int size = 0; - int newSize = -1; - - VideoModes::iterator mode; - VideoModes::iterator end = mVideoModes.end(); - VideoMode *newMode = 0; - - for(mode = mVideoModes.begin(); mode != end; size++) - { - if (mode->first.first >= static_cast(width) && - mode->first.second >= static_cast(height)) - { - if (!newMode || - mode->first.first < newMode->first.first || - mode->first.second < newMode->first.second) - { - newSize = size; - newMode = &(*mode); - } - } - - VideoMode* lastMode = &(*mode); - - while (++mode != end && mode->first == lastMode->first) - { - if (lastMode == newMode && mode->second == frequency) - { - newMode = &(*mode); - } - } - } - - //todo - } - - //Moved to native from EGLSupport + Win32EGLSupport::Win32EGLSupport() + { + //RECT windowRect; + //GetClientRect(mNativeDisplay, &windowRect); + mNativeDisplay = getNativeDisplay(); + mGLDisplay = getGLDisplay(); + + // Video mode possibilities + DEVMODE DevMode; + DevMode.dmSize = sizeof(DEVMODE); + for (DWORD i = 0; EnumDisplaySettings(NULL, i, &DevMode); ++i) + { + if (DevMode.dmBitsPerPel < 16) + continue; + + mCurrentMode.first.first = DevMode.dmPelsWidth; + mCurrentMode.first.second = DevMode.dmPelsHeight; + mCurrentMode.second = 0; + mOriginalMode = mCurrentMode; + mVideoModes.push_back(mCurrentMode); + } + + EGLConfig *glConfigs; + int config, nConfigs = 0; + + glConfigs = chooseGLConfig(NULL, &nConfigs); + + for (config = 0; config < nConfigs; config++) + { + int caveat, samples; + + getGLConfigAttrib(glConfigs[config], EGL_CONFIG_CAVEAT, &caveat); + + if (caveat != EGL_SLOW_CONFIG) + { + getGLConfigAttrib(glConfigs[config], EGL_SAMPLES, &samples); + mSampleLevels.push_back(StringConverter::toString(samples)); + } + } + + free(glConfigs); + + removeDuplicates(mSampleLevels); + + + } + + Win32EGLSupport::~Win32EGLSupport() + { + + } + + //Removed createEGLWindow because it was easier to call new Win32EGLWindow + //directly to get the native version. +// EGLWindow* Win32EGLSupport::createEGLWindow( EGLSupport * support ) +// { +// return new Win32EGLWindow(support); +// } + + GLESPBuffer* Win32EGLSupport::createPBuffer( PixelComponentType format, size_t width, size_t height ) + { + return new Win32EGLPBuffer(this, format, width, height); + } + + void Win32EGLSupport::switchMode( uint& width, uint& height, short& frequency ) + { + if (!mRandr) + return; + + int size = 0; + int newSize = -1; + + VideoModes::iterator mode; + VideoModes::iterator end = mVideoModes.end(); + VideoMode *newMode = 0; + + for(mode = mVideoModes.begin(); mode != end; size++) + { + if (mode->first.first >= static_cast(width) && + mode->first.second >= static_cast(height)) + { + if (!newMode || + mode->first.first < newMode->first.first || + mode->first.second < newMode->first.second) + { + newSize = size; + newMode = &(*mode); + } + } + + VideoMode* lastMode = &(*mode); + + while (++mode != end && mode->first == lastMode->first) + { + if (lastMode == newMode && mode->second == frequency) + { + newMode = &(*mode); + } + } + } + + //todo + } + + //Moved to native from EGLSupport RenderWindow* Win32EGLSupport::newWindow(const String &name, unsigned int width, unsigned int height, bool fullScreen, @@ -157,29 +157,29 @@ namespace Ogre { { // EGLWindow* window = createEGLWindow(this); - Win32EGLWindow* window = new Win32EGLWindow(this); + Win32EGLWindow* window = new Win32EGLWindow(this); window->create(name, width, height, fullScreen, miscParams); return window; } - //Moved to native from EGLSupport - NativeDisplayType Win32EGLSupport::getNativeDisplay() - { - return EGL_DEFAULT_DISPLAY; // TODO - } - - //Win32EGLSupport::getGLDisplay sets up the native variable - //then calls EGLSupport::getGLDisplay - EGLDisplay Win32EGLSupport::getGLDisplay() - { - if (!mGLDisplay) - { - mNativeDisplay = getNativeDisplay(); - return EGLSupport::getGLDisplay(); - } - return mGLDisplay; - } + //Moved to native from EGLSupport + NativeDisplayType Win32EGLSupport::getNativeDisplay() + { + return EGL_DEFAULT_DISPLAY; // TODO + } + + //Win32EGLSupport::getGLDisplay sets up the native variable + //then calls EGLSupport::getGLDisplay + EGLDisplay Win32EGLSupport::getGLDisplay() + { + if (!mGLDisplay) + { + mNativeDisplay = getNativeDisplay(); + return EGLSupport::getGLDisplay(); + } + return mGLDisplay; + } } diff --git a/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLWindow.cpp b/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLWindow.cpp index e5b9adbe320..25d3578e825 100644 --- a/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLWindow.cpp +++ b/RenderSystems/GLES/src/EGL/WIN32/OgreWin32EGLWindow.cpp @@ -46,258 +46,258 @@ THE SOFTWARE. namespace Ogre { Win32EGLWindow::Win32EGLWindow(Win32EGLSupport *glsupport) - : EGLWindow(glsupport) + : EGLWindow(glsupport) { - mGLSupport = glsupport; - mNativeDisplay = glsupport->getNativeDisplay(); + mGLSupport = glsupport; + mNativeDisplay = glsupport->getNativeDisplay(); } Win32EGLWindow::~Win32EGLWindow() { } - EGLContext * Win32EGLWindow::createEGLContext() const - { - return new Win32EGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); - } + EGLContext * Win32EGLWindow::createEGLContext() const + { + return new Win32EGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); + } - void Win32EGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) - { + void Win32EGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) + { - } + } - void Win32EGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) - { + void Win32EGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) + { - } + } - void Win32EGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) - { - // destroy current window, if any - if (mWindow) - destroy(); + void Win32EGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) + { + // destroy current window, if any + if (mWindow) + destroy(); #ifdef OGRE_STATIC_LIB - HINSTANCE hInst = GetModuleHandle( NULL ); + HINSTANCE hInst = GetModuleHandle( NULL ); #else # if OGRE_DEBUG_MODE == 1 - HINSTANCE hInst = GetModuleHandle("RenderSystem_GLES_d.dll"); + HINSTANCE hInst = GetModuleHandle("RenderSystem_GLES_d.dll"); # else - HINSTANCE hInst = GetModuleHandle("RenderSystem_GLES.dll"); + HINSTANCE hInst = GetModuleHandle("RenderSystem_GLES.dll"); # endif #endif - mWindow = 0; - mClosed = false; - mColourDepth = mIsFullScreen? 32 : GetDeviceCaps(GetDC(0), BITSPIXEL); - HWND parent = 0; - bool vsync = false; - String border; - bool outerSize = false; - bool hwGamma = false; - int monitorIndex = -1; - HMONITOR hMonitor = NULL; - - - if (!mIsExternal) - { - DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN; - DWORD dwStyleEx = 0; - MONITORINFOEX monitorInfoEx; - RECT rc; - - // If we didn't specified the adapter index, or if it didn't find it - if (hMonitor == NULL) - { - POINT windowAnchorPoint; - - // Fill in anchor point. - windowAnchorPoint.x = left; - windowAnchorPoint.y = top; - - - // Get the nearest monitor to this window. - hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTONEAREST); - } - - // Get the target monitor info - memset(&monitorInfoEx, 0, sizeof(MONITORINFOEX)); - monitorInfoEx.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(hMonitor, &monitorInfoEx); - - //size_t devNameLen = strlen(monitorInfoEx.szDevice); - //mDeviceName = new char[devNameLen + 1]; - - //strcpy(mDeviceName, monitorInfoEx.szDevice); - - - // No specified top left -> Center the window in the middle of the monitor - if (left == -1 || top == -1) - { - int screenw = monitorInfoEx.rcMonitor.right - monitorInfoEx.rcMonitor.left; - int screenh = monitorInfoEx.rcMonitor.bottom - monitorInfoEx.rcMonitor.top; - - SetRect(&rc, 0, 0, width, height); - AdjustWindowRect(&rc, dwStyle, false); - - // clamp window dimensions to screen size - int outerw = (rc.right-rc.left < screenw)? rc.right-rc.left : screenw; - int outerh = (rc.bottom-rc.top < screenh)? rc.bottom-rc.top : screenh; - - if (left == -1) - left = monitorInfoEx.rcMonitor.left + (screenw - outerw) / 2; - else if (monitorIndex != -1) - left += monitorInfoEx.rcMonitor.left; - - if (top == -1) - top = monitorInfoEx.rcMonitor.top + (screenh - outerh) / 2; - else if (monitorIndex != -1) - top += monitorInfoEx.rcMonitor.top; - } - else if (monitorIndex != -1) - { - left += monitorInfoEx.rcMonitor.left; - top += monitorInfoEx.rcMonitor.top; - } - - mWidth = width; - mHeight = height; - mTop = top; - mLeft = left; - - if (mIsFullScreen) - { - dwStyle |= WS_POPUP; - dwStyleEx |= WS_EX_TOPMOST; - mTop = monitorInfoEx.rcMonitor.top; - mLeft = monitorInfoEx.rcMonitor.left; - } - else - { - if (parent) - { - dwStyle |= WS_CHILD; - } - else - { - if (border == "none") - dwStyle |= WS_POPUP; - else if (border == "fixed") - dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | - WS_SYSMENU | WS_MINIMIZEBOX; - else - dwStyle |= WS_OVERLAPPEDWINDOW; - } - - int screenw = GetSystemMetrics(SM_CXSCREEN); - int screenh = GetSystemMetrics(SM_CYSCREEN); - - if (!outerSize) - { - // Calculate window dimensions required - // to get the requested client area - SetRect(&rc, 0, 0, mWidth, mHeight); - AdjustWindowRect(&rc, dwStyle, false); - mWidth = rc.right - rc.left; - mHeight = rc.bottom - rc.top; - - // Clamp window rect to the nearest display monitor. - if (mLeft < monitorInfoEx.rcMonitor.left) - mLeft = monitorInfoEx.rcMonitor.left; - - if (mTop < monitorInfoEx.rcMonitor.top) - mTop = monitorInfoEx.rcMonitor.top; - - if ((int)mWidth > monitorInfoEx.rcMonitor.right - mLeft) - mWidth = monitorInfoEx.rcMonitor.right - mLeft; - - if ((int)mHeight > monitorInfoEx.rcMonitor.bottom - mTop) - mHeight = monitorInfoEx.rcMonitor.bottom - mTop; - } - } - - // register class and create window - WNDCLASS wc = { CS_OWNDC, WindowEventUtilities::_WndProc, 0, 0, hInst, - LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), - (HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "OgreGLWindow" }; - RegisterClass(&wc); - - if (mIsFullScreen) - { - DEVMODE displayDeviceMode; - - memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); - displayDeviceMode.dmSize = sizeof(DEVMODE); - displayDeviceMode.dmBitsPerPel = mColourDepth; - displayDeviceMode.dmPelsWidth = mWidth; - displayDeviceMode.dmPelsHeight = mHeight; - displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + mWindow = 0; + mClosed = false; + mColourDepth = mIsFullScreen? 32 : GetDeviceCaps(GetDC(0), BITSPIXEL); + HWND parent = 0; + bool vsync = false; + String border; + bool outerSize = false; + bool hwGamma = false; + int monitorIndex = -1; + HMONITOR hMonitor = NULL; + + + if (!mIsExternal) + { + DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN; + DWORD dwStyleEx = 0; + MONITORINFOEX monitorInfoEx; + RECT rc; + + // If we didn't specified the adapter index, or if it didn't find it + if (hMonitor == NULL) + { + POINT windowAnchorPoint; + + // Fill in anchor point. + windowAnchorPoint.x = left; + windowAnchorPoint.y = top; + + + // Get the nearest monitor to this window. + hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTONEAREST); + } + + // Get the target monitor info + memset(&monitorInfoEx, 0, sizeof(MONITORINFOEX)); + monitorInfoEx.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &monitorInfoEx); + + //size_t devNameLen = strlen(monitorInfoEx.szDevice); + //mDeviceName = new char[devNameLen + 1]; + + //strcpy(mDeviceName, monitorInfoEx.szDevice); + + + // No specified top left -> Center the window in the middle of the monitor + if (left == -1 || top == -1) + { + int screenw = monitorInfoEx.rcMonitor.right - monitorInfoEx.rcMonitor.left; + int screenh = monitorInfoEx.rcMonitor.bottom - monitorInfoEx.rcMonitor.top; + + SetRect(&rc, 0, 0, width, height); + AdjustWindowRect(&rc, dwStyle, false); + + // clamp window dimensions to screen size + int outerw = (rc.right-rc.left < screenw)? rc.right-rc.left : screenw; + int outerh = (rc.bottom-rc.top < screenh)? rc.bottom-rc.top : screenh; + + if (left == -1) + left = monitorInfoEx.rcMonitor.left + (screenw - outerw) / 2; + else if (monitorIndex != -1) + left += monitorInfoEx.rcMonitor.left; + + if (top == -1) + top = monitorInfoEx.rcMonitor.top + (screenh - outerh) / 2; + else if (monitorIndex != -1) + top += monitorInfoEx.rcMonitor.top; + } + else if (monitorIndex != -1) + { + left += monitorInfoEx.rcMonitor.left; + top += monitorInfoEx.rcMonitor.top; + } + + mWidth = width; + mHeight = height; + mTop = top; + mLeft = left; + + if (mIsFullScreen) + { + dwStyle |= WS_POPUP; + dwStyleEx |= WS_EX_TOPMOST; + mTop = monitorInfoEx.rcMonitor.top; + mLeft = monitorInfoEx.rcMonitor.left; + } + else + { + if (parent) + { + dwStyle |= WS_CHILD; + } + else + { + if (border == "none") + dwStyle |= WS_POPUP; + else if (border == "fixed") + dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | + WS_SYSMENU | WS_MINIMIZEBOX; + else + dwStyle |= WS_OVERLAPPEDWINDOW; + } + + int screenw = GetSystemMetrics(SM_CXSCREEN); + int screenh = GetSystemMetrics(SM_CYSCREEN); + + if (!outerSize) + { + // Calculate window dimensions required + // to get the requested client area + SetRect(&rc, 0, 0, mWidth, mHeight); + AdjustWindowRect(&rc, dwStyle, false); + mWidth = rc.right - rc.left; + mHeight = rc.bottom - rc.top; + + // Clamp window rect to the nearest display monitor. + if (mLeft < monitorInfoEx.rcMonitor.left) + mLeft = monitorInfoEx.rcMonitor.left; + + if (mTop < monitorInfoEx.rcMonitor.top) + mTop = monitorInfoEx.rcMonitor.top; + + if ((int)mWidth > monitorInfoEx.rcMonitor.right - mLeft) + mWidth = monitorInfoEx.rcMonitor.right - mLeft; + + if ((int)mHeight > monitorInfoEx.rcMonitor.bottom - mTop) + mHeight = monitorInfoEx.rcMonitor.bottom - mTop; + } + } + + // register class and create window + WNDCLASS wc = { CS_OWNDC, WindowEventUtilities::_WndProc, 0, 0, hInst, + LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), + (HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "OgreGLWindow" }; + RegisterClass(&wc); + + if (mIsFullScreen) + { + DEVMODE displayDeviceMode; + + memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); + displayDeviceMode.dmSize = sizeof(DEVMODE); + displayDeviceMode.dmBitsPerPel = mColourDepth; + displayDeviceMode.dmPelsWidth = mWidth; + displayDeviceMode.dmPelsHeight = mHeight; + displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; /* - if (mDisplayFrequency) - { - displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; - displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) - { - LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); - displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; - } - } - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) - LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); + if (mDisplayFrequency) + { + displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; + displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) + { + LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); + displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; + } + } + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) + LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); */ - } - // Pass pointer to self as WM_CREATE parameter - mWindow = CreateWindowEx(dwStyleEx, "OgreGLWindow", title.c_str(), - dwStyle, mLeft, mTop, mWidth, mHeight, parent, 0, hInst, this); + } + // Pass pointer to self as WM_CREATE parameter + mWindow = CreateWindowEx(dwStyleEx, "OgreGLWindow", title.c_str(), + dwStyle, mLeft, mTop, mWidth, mHeight, parent, 0, hInst, this); - WindowEventUtilities::_addRenderWindow(this); + WindowEventUtilities::_addRenderWindow(this); - LogManager::getSingleton().stream() - << "Created Win32Window '" - << mName << "' : " << mWidth << "x" << mHeight - << ", " << mColourDepth << "bpp"; + LogManager::getSingleton().stream() + << "Created Win32Window '" + << mName << "' : " << mWidth << "x" << mHeight + << ", " << mColourDepth << "bpp"; - } + } - RECT rc; - // top and left represent outer window position - GetWindowRect(mWindow, &rc); - mTop = rc.top; - mLeft = rc.left; - // width and height represent drawable area only - GetClientRect(mWindow, &rc); - mWidth = rc.right; - mHeight = rc.bottom; + RECT rc; + // top and left represent outer window position + GetWindowRect(mWindow, &rc); + mTop = rc.top; + mLeft = rc.left; + // width and height represent drawable area only + GetClientRect(mWindow, &rc); + mWidth = rc.right; + mHeight = rc.bottom; - mNativeDisplay = GetDC(mWindow); - mEglDisplay = eglGetDisplay(mNativeDisplay); - mGLSupport->setGLDisplay(mEglDisplay); - mEglSurface = createSurfaceFromWindow(mEglDisplay, mWindow); + mNativeDisplay = GetDC(mWindow); + mEglDisplay = eglGetDisplay(mNativeDisplay); + mGLSupport->setGLDisplay(mEglDisplay); + mEglSurface = createSurfaceFromWindow(mEglDisplay, mWindow); - } + } - void Win32EGLWindow::reposition( int left, int top ) - { + void Win32EGLWindow::reposition( int left, int top ) + { - } + } - void Win32EGLWindow::resize( unsigned int width, unsigned int height ) - { + void Win32EGLWindow::resize( unsigned int width, unsigned int height ) + { - } + } - void Win32EGLWindow::windowMovedOrResized() - { + void Win32EGLWindow::windowMovedOrResized() + { - } + } - void Win32EGLWindow::switchFullScreen( bool fullscreen ) - { + void Win32EGLWindow::switchFullScreen( bool fullscreen ) + { - } + } void Win32EGLWindow::create(const String& name, uint width, uint height, bool fullScreen, const NameValuePairList *miscParams) @@ -308,10 +308,10 @@ namespace Ogre { short frequency = 0; bool vsync = false; ::EGLContext eglContext = 0; - int left = 0; - int top = 0; + int left = 0; + int top = 0; - getLeftAndTopFromNativeWindow(left, top, width, height); + getLeftAndTopFromNativeWindow(left, top, width, height); mIsFullScreen = fullScreen; @@ -375,9 +375,9 @@ namespace Ogre { { mIsExternalGLControl = StringConverter::parseBool(opt->second); } - } + } - initNativeCreatedWindow(miscParams); + initNativeCreatedWindow(miscParams); if (mEglSurface) { @@ -431,12 +431,12 @@ namespace Ogre { mGLSupport->switchMode (width, height, frequency); } - if (!mIsExternal) + if (!mIsExternal) { - createNativeWindow(left, top, width, height, title); - } + createNativeWindow(left, top, width, height, title); + } - mContext = createEGLContext(); + mContext = createEGLContext(); ::EGLSurface oldDrawableDraw = eglGetCurrentSurface(EGL_DRAW); ::EGLSurface oldDrawableRead = eglGetCurrentSurface(EGL_READ); @@ -453,9 +453,9 @@ namespace Ogre { mLeft = left; mTop = top; mActive = true; - mVisible = true; + mVisible = true; mClosed = false; - } + } } diff --git a/RenderSystems/GLES/src/EGL/X11/OgreX11EGLContext.cpp b/RenderSystems/GLES/src/EGL/X11/OgreX11EGLContext.cpp index 69c8f334967..7afc92d78e5 100644 --- a/RenderSystems/GLES/src/EGL/X11/OgreX11EGLContext.cpp +++ b/RenderSystems/GLES/src/EGL/X11/OgreX11EGLContext.cpp @@ -36,7 +36,7 @@ THE SOFTWARE. namespace Ogre { X11EGLContext::X11EGLContext(EGLDisplay eglDisplay, - const EGLSupport* glsupport, + const EGLSupport* glsupport, ::EGLConfig glconfig, ::EGLSurface drawable) : EGLContext(eglDisplay, glsupport, glconfig, drawable) diff --git a/RenderSystems/GLES/src/EGL/X11/OgreX11EGLRenderTexture.cpp b/RenderSystems/GLES/src/EGL/X11/OgreX11EGLRenderTexture.cpp index c0eb4cf3843..04db08a1115 100644 --- a/RenderSystems/GLES/src/EGL/X11/OgreX11EGLRenderTexture.cpp +++ b/RenderSystems/GLES/src/EGL/X11/OgreX11EGLRenderTexture.cpp @@ -46,17 +46,17 @@ THE SOFTWARE. namespace Ogre { - X11EGLPBuffer::X11EGLPBuffer( X11EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height ) - : EGLPBuffer(glsupport, format, width, height) - { - mGlDisplay = glsupport->getGLDisplay(); - mGLSupport = glsupport; - initEGLPBuffer(); - } - - X11EGLPBuffer::~X11EGLPBuffer() - { - - } + X11EGLPBuffer::X11EGLPBuffer( X11EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height ) + : EGLPBuffer(glsupport, format, width, height) + { + mGlDisplay = glsupport->getGLDisplay(); + mGLSupport = glsupport; + initEGLPBuffer(); + } + + X11EGLPBuffer::~X11EGLPBuffer() + { + + } } diff --git a/RenderSystems/GLES/src/EGL/X11/OgreX11EGLSupport.cpp b/RenderSystems/GLES/src/EGL/X11/OgreX11EGLSupport.cpp index 21e87860346..2fe2c5a0cd7 100644 --- a/RenderSystems/GLES/src/EGL/X11/OgreX11EGLSupport.cpp +++ b/RenderSystems/GLES/src/EGL/X11/OgreX11EGLSupport.cpp @@ -42,54 +42,54 @@ THE SOFTWARE. #if (OGRE_PLATFORM != OGRE_PLATFORM_LINUX) - void XStringListToTextProperty(char ** prop, int num, XTextProperty * textProp){}; - Window DefaultRootWindow(Display* nativeDisplayType){return Window();}; - bool XQueryExtension(Display* nativeDisplayType, char * name, int * dummy0, int * dummy2, int * dummy3){return 0;} - XRRScreenConfiguration * XRRGetScreenInfo(Display* nativeDisplayType, Window window ){return 0;}; - int XRRConfigCurrentConfiguration(XRRScreenConfiguration * config, Rotation * rotation){return 0;}; - XRRScreenSize * XRRConfigSizes(XRRScreenConfiguration * config, int * nSizes){return 0;}; - int XRRConfigCurrentRate(XRRScreenConfiguration * config){return 0;}; - short * XRRConfigRates(XRRScreenConfiguration * config, int sizeID, int * nRates){return 0;}; - void XRRFreeScreenConfigInfo(XRRScreenConfiguration * config){} - int DefaultScreen(NativeDisplayType nativeDisplayType){return 0;}; - int DisplayWidth(Display* nativeDisplayType, int screen){return 0;}; - int DisplayHeight(Display* nativeDisplayType, int screen){return 0;}; - Display* XOpenDisplay(int num){return NULL;}; - void XCloseDisplay(Display* nativeDisplayType){}; - Atom XInternAtom(Display* nativeDisplayType, char * name, X11Bool isTrue) {return Atom();}; - char * DisplayString(NativeDisplayType nativeDisplayType){return 0;}; - const char * XDisplayName(char * name){return 0;}; - Visual * DefaultVisual(Display* nativeDisplayType, int screen){return 0;}; - int XVisualIDFromVisual(Visual *v){return 0;}; - void XRRSetScreenConfigAndRate(Display* nativeDisplayType, XRRScreenConfiguration * config, Window window, int size, Rotation rotation, int mode, int currentTime ){}; - XVisualInfo * XGetVisualInfo(Display* nativeDisplayType, int mask, XVisualInfo * info, int * n){return 0;}; - typedef int (*XErrorHandler)(Display *, XErrorEvent*); - XErrorHandler XSetErrorHandler(XErrorHandler xErrorHandler){return 0;}; - void XDestroyWindow(Display* nativeDisplayType, Window nativeWindowType){}; - bool XGetWindowAttributes(Display* nativeDisplayType, Window nativeWindowType, XWindowAttributes * xWindowAttributes){return 0;}; - int XCreateColormap(Display* nativeDisplayType, Window nativeWindowType, int visual, int allocNone){return 0;}; - Window XCreateWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top, int width, int height, int dummy1, int depth, int inputOutput, int visual, int mask, XSetWindowAttributes * xSetWindowAttributes){return Window();}; - void XFree(void *data){}; - XWMHints * XAllocWMHints(){return 0;}; - XSizeHints * XAllocSizeHints(){return 0;}; - void XSetWMProperties(Display* nativeDisplayType, Window nativeWindowType,XTextProperty * titleprop, char * dummy1, char * dummy2, int num, XSizeHints *sizeHints, XWMHints *wmHints, char * dummy3){}; - void XSetWMProtocols(Display* nativeDisplayType, Window nativeWindowType, Atom * atom, int num){}; - void XMapWindow(Display* nativeDisplayType, Window nativeWindowType){}; - void XFlush(Display* nativeDisplayType){}; - void XMoveWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top){}; - void XResizeWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top){}; - void XQueryTree(Display* nativeDisplayType, Window nativeWindowType, Window * root, Window *parent, Window **children, unsigned int * nChildren){}; - void XSendEvent(Display* nativeDisplayType, Window nativeWindowType, int dummy1, int mask, XEvent* xevent){}; + void XStringListToTextProperty(char ** prop, int num, XTextProperty * textProp){}; + Window DefaultRootWindow(Display* nativeDisplayType){return Window();}; + bool XQueryExtension(Display* nativeDisplayType, char * name, int * dummy0, int * dummy2, int * dummy3){return 0;} + XRRScreenConfiguration * XRRGetScreenInfo(Display* nativeDisplayType, Window window ){return 0;}; + int XRRConfigCurrentConfiguration(XRRScreenConfiguration * config, Rotation * rotation){return 0;}; + XRRScreenSize * XRRConfigSizes(XRRScreenConfiguration * config, int * nSizes){return 0;}; + int XRRConfigCurrentRate(XRRScreenConfiguration * config){return 0;}; + short * XRRConfigRates(XRRScreenConfiguration * config, int sizeID, int * nRates){return 0;}; + void XRRFreeScreenConfigInfo(XRRScreenConfiguration * config){} + int DefaultScreen(NativeDisplayType nativeDisplayType){return 0;}; + int DisplayWidth(Display* nativeDisplayType, int screen){return 0;}; + int DisplayHeight(Display* nativeDisplayType, int screen){return 0;}; + Display* XOpenDisplay(int num){return NULL;}; + void XCloseDisplay(Display* nativeDisplayType){}; + Atom XInternAtom(Display* nativeDisplayType, char * name, X11Bool isTrue) {return Atom();}; + char * DisplayString(NativeDisplayType nativeDisplayType){return 0;}; + const char * XDisplayName(char * name){return 0;}; + Visual * DefaultVisual(Display* nativeDisplayType, int screen){return 0;}; + int XVisualIDFromVisual(Visual *v){return 0;}; + void XRRSetScreenConfigAndRate(Display* nativeDisplayType, XRRScreenConfiguration * config, Window window, int size, Rotation rotation, int mode, int currentTime ){}; + XVisualInfo * XGetVisualInfo(Display* nativeDisplayType, int mask, XVisualInfo * info, int * n){return 0;}; + typedef int (*XErrorHandler)(Display *, XErrorEvent*); + XErrorHandler XSetErrorHandler(XErrorHandler xErrorHandler){return 0;}; + void XDestroyWindow(Display* nativeDisplayType, Window nativeWindowType){}; + bool XGetWindowAttributes(Display* nativeDisplayType, Window nativeWindowType, XWindowAttributes * xWindowAttributes){return 0;}; + int XCreateColormap(Display* nativeDisplayType, Window nativeWindowType, int visual, int allocNone){return 0;}; + Window XCreateWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top, int width, int height, int dummy1, int depth, int inputOutput, int visual, int mask, XSetWindowAttributes * xSetWindowAttributes){return Window();}; + void XFree(void *data){}; + XWMHints * XAllocWMHints(){return 0;}; + XSizeHints * XAllocSizeHints(){return 0;}; + void XSetWMProperties(Display* nativeDisplayType, Window nativeWindowType,XTextProperty * titleprop, char * dummy1, char * dummy2, int num, XSizeHints *sizeHints, XWMHints *wmHints, char * dummy3){}; + void XSetWMProtocols(Display* nativeDisplayType, Window nativeWindowType, Atom * atom, int num){}; + void XMapWindow(Display* nativeDisplayType, Window nativeWindowType){}; + void XFlush(Display* nativeDisplayType){}; + void XMoveWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top){}; + void XResizeWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top){}; + void XQueryTree(Display* nativeDisplayType, Window nativeWindowType, Window * root, Window *parent, Window **children, unsigned int * nChildren){}; + void XSendEvent(Display* nativeDisplayType, Window nativeWindowType, int dummy1, int mask, XEvent* xevent){}; #endif namespace Ogre { X11EGLSupport::X11EGLSupport() { - mNativeDisplay = getNativeDisplay(); + mNativeDisplay = getNativeDisplay(); mGLDisplay = getGLDisplay(); - int dummy; + int dummy; if (XQueryExtension((Display*)mNativeDisplay, "RANDR", &dummy, &dummy, &dummy)) { @@ -140,7 +140,7 @@ namespace Ogre { mVideoModes.push_back(mCurrentMode); } - EGLConfig *glConfigs; + EGLConfig *glConfigs; int config, nConfigs = 0; glConfigs = chooseGLConfig(NULL, &nConfigs); @@ -164,17 +164,17 @@ namespace Ogre { } - //Removed this because it was easier to call new X11EGLWindow directly - //to get the native version -// EGLWindow* X11EGLSupport::createEGLWindow( EGLSupport * support ) -// { -// return new X11EGLWindow((X11EGLSupport*)support); -// } + //Removed this because it was easier to call new X11EGLWindow directly + //to get the native version +// EGLWindow* X11EGLSupport::createEGLWindow( EGLSupport * support ) +// { +// return new X11EGLWindow((X11EGLSupport*)support); +// } - GLESPBuffer* X11EGLSupport::createPBuffer( PixelComponentType format, size_t width, size_t height ) - { - return new X11EGLPBuffer(this, format, width, height); - } + GLESPBuffer* X11EGLSupport::createPBuffer( PixelComponentType format, size_t width, size_t height ) + { + return new X11EGLPBuffer(this, format, width, height); + } X11EGLSupport::~X11EGLSupport() { @@ -187,16 +187,16 @@ namespace Ogre { { eglTerminate(mGLDisplay); } - } + } - NativeDisplayType X11EGLSupport::getNativeDisplay() - { + NativeDisplayType X11EGLSupport::getNativeDisplay() + { if (!mNativeDisplay) { - mNativeDisplay = (NativeDisplayType)XOpenDisplay(0); + mNativeDisplay = (NativeDisplayType)XOpenDisplay(0); if (!mNativeDisplay) { @@ -215,8 +215,8 @@ namespace Ogre { String X11EGLSupport::getDisplayName(void) { - return String((const char*)XDisplayName(DisplayString(mNativeDisplay))); - } + return String((const char*)XDisplayName(DisplayString(mNativeDisplay))); + } void X11EGLSupport::switchMode(uint& width, uint& height, short& frequency) @@ -272,7 +272,7 @@ namespace Ogre { LogManager::getSingleton().logMessage("Entered video mode " + StringConverter::toString(mCurrentMode.first.first) + "x" + StringConverter::toString(mCurrentMode.first.second) + " @ " + StringConverter::toString(mCurrentMode.second) + "MHz"); } } - } + } @@ -322,23 +322,23 @@ namespace Ogre { const NameValuePairList *miscParams) { // EGLWindow* window = createEGLWindow(this); - EGLWindow* window = new X11EGLWindow(this); + EGLWindow* window = new X11EGLWindow(this); window->create(name, width, height, fullScreen, miscParams); return window; } - //X11EGLSupport::getGLDisplay sets up the native variable - //then calls EGLSupport::getGLDisplay + //X11EGLSupport::getGLDisplay sets up the native variable + //then calls EGLSupport::getGLDisplay EGLDisplay X11EGLSupport::getGLDisplay() { - if (!mGLDisplay) - { - if(!mNativeDisplay) - mNativeDisplay = getNativeDisplay(); - return EGLSupport::getGLDisplay(); - } - return mGLDisplay; + if (!mGLDisplay) + { + if(!mNativeDisplay) + mNativeDisplay = getNativeDisplay(); + return EGLSupport::getGLDisplay(); + } + return mGLDisplay; } diff --git a/RenderSystems/GLES/src/EGL/X11/OgreX11EGLWindow.cpp b/RenderSystems/GLES/src/EGL/X11/OgreX11EGLWindow.cpp index 2a4a52cda6d..97e05f4cccc 100644 --- a/RenderSystems/GLES/src/EGL/X11/OgreX11EGLWindow.cpp +++ b/RenderSystems/GLES/src/EGL/X11/OgreX11EGLWindow.cpp @@ -52,384 +52,384 @@ extern "C" } - int (*oldXErrorHandler)(Display *, XErrorEvent*); + int (*oldXErrorHandler)(Display *, XErrorEvent*); } namespace Ogre { - X11EGLWindow::X11EGLWindow(X11EGLSupport *glsupport) - : EGLWindow(glsupport) - //, mParentWindow(glsupport) todo - { - mGLSupport = glsupport; - mNativeDisplay = glsupport->getNativeDisplay(); - } - - X11EGLWindow::~X11EGLWindow() - { - - mNativeDisplay = mGLSupport->getNativeDisplay(); - // Ignore fatal XErrorEvents from stale handles. - oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); - - if (mWindow) - { - XDestroyWindow((Display*)mNativeDisplay, (Window)mWindow); - } - - XSetErrorHandler(oldXErrorHandler); - mWindow = 0; - - } - - void X11EGLWindow::getCustomAttribute( const String& name, void* pData ) - { - EGLWindow::getCustomAttribute(name, pData); - if (name == "ATOM") - { - *static_cast< ::Atom* >(pData) = mGLSupport->mAtomDeleteWindow; - return; - } - else if (name == "XDISPLAY") - { - *static_cast(pData) = mGLSupport->getNativeDisplay(); - return; - } - else if (name == "XWINDOW") - { - *static_cast(pData) = mWindow; - return; - } - - } - - EGLContext * X11EGLWindow::createEGLContext() const - { - return new X11EGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); - } - - void X11EGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) - { - NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); - left = DisplayWidth((Display*)mNativeDisplay, DefaultScreen(mNativeDisplay))/2 - width/2; - top = DisplayHeight((Display*)mNativeDisplay, DefaultScreen(mNativeDisplay))/2 - height/2; - } - - void X11EGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) - { - if (miscParams) - { - NameValuePairList::const_iterator opt; - NameValuePairList::const_iterator end = miscParams->end(); - - mExternalWindow = 0; - mNativeDisplay = mGLSupport->getNativeDisplay(); - mParentWindow = DefaultRootWindow((Display*)mNativeDisplay); - - if ((opt = miscParams->find("parentWindowHandle")) != end) - { - //vector::type tokens = StringUtil::split(opt->second, " :"); - StringVector tokens = StringUtil::split(opt->second, " :"); - - if (tokens.size() == 3) - { - // deprecated display:screen:xid format - mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); - } - else - { - // xid format - mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[0]); - } - } - else if ((opt = miscParams->find("externalWindowHandle")) != end) - { - //vector::type tokens = StringUtil::split(opt->second, " :"); - StringVector tokens = StringUtil::split(opt->second, " :"); - - LogManager::getSingleton().logMessage( - "EGLWindow::create: The externalWindowHandle parameter is deprecated.\n" - "Use the parentWindowHandle or currentGLContext parameter instead."); - if (tokens.size() == 3) - { - // Old display:screen:xid format - // The old EGL code always created a "parent" window in this case: - mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); - } - else if (tokens.size() == 4) - { - // Old display:screen:xid:visualinfo format - mExternalWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); - } - else - { - // xid format - mExternalWindow = (Window)StringConverter::parseUnsignedLong(tokens[0]); - } - } - - } - - // Ignore fatal XErrorEvents during parameter validation: - oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); - - // Validate parentWindowHandle - if (mParentWindow != DefaultRootWindow((Display*)mNativeDisplay)) - { - XWindowAttributes windowAttrib; - - if (!XGetWindowAttributes((Display*)mNativeDisplay, mParentWindow, &windowAttrib) || - windowAttrib.root != DefaultRootWindow((Display*)mNativeDisplay)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Invalid parentWindowHandle (wrong server or screen)", - "EGLWindow::create"); - } - } - - // Validate externalWindowHandle - if (mExternalWindow != 0) - { - XWindowAttributes windowAttrib; - - if (!XGetWindowAttributes((Display*)mNativeDisplay, mExternalWindow, &windowAttrib) || - windowAttrib.root != DefaultRootWindow((Display*)mNativeDisplay)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Invalid externalWindowHandle (wrong server or screen)", - "EGLWindow::create"); - } - - mEglConfig = 0; - mEglSurface = createSurfaceFromWindow(mEglDisplay, (NativeWindowType)mExternalWindow); - } - - XSetErrorHandler(oldXErrorHandler); - - mIsTopLevel = (!mIsExternal && mParentWindow == DefaultRootWindow((Display*)mNativeDisplay)); - - } - - void X11EGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) - { - mEglDisplay = mGLSupport->getGLDisplay();//todo - XSetWindowAttributes attr; - ulong mask; - XVisualInfo *visualInfo = mGLSupport->getVisualFromFBConfig(mEglConfig); - - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap((Display*)mNativeDisplay, - DefaultRootWindow((Display*)mNativeDisplay), - visualInfo->visual, - AllocNone); - attr.event_mask = StructureNotifyMask | VisibilityChangeMask | FocusChangeMask; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - - if(mIsFullScreen && mGLSupport->mAtomFullScreen == None) - { - LogManager::getSingleton().logMessage("EGLWindow::switchFullScreen: Your WM has no fullscreen support"); - - // A second best approach for outdated window managers - attr.backing_store = NotUseful; - attr.save_under = False; - attr.override_redirect = True; - mask |= CWSaveUnder | CWBackingStore | CWOverrideRedirect; - left = top = 0; - } - - // Create window on server - mWindow = (NativeWindowType)XCreateWindow((Display*)mNativeDisplay, - mParentWindow, - left, top, width, height, - 0, visualInfo->depth, - InputOutput, - visualInfo->visual, mask, &attr); - XFree(visualInfo); - - if(!mWindow) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create an X NativeWindowType", - "EGLWindow::create"); - } - - if (mIsTopLevel) - { - XWMHints *wmHints; - XSizeHints *sizeHints; - - // Is this really necessary ? Which broken WM might need it? - if ((wmHints = XAllocWMHints()) != NULL) - { - wmHints->initial_state = NormalState; - wmHints->input = True; - wmHints->flags = StateHint | InputHint; - } - - // Is this really necessary ? Which broken WM might need it? - if ((sizeHints = XAllocSizeHints()) != NULL) - { - sizeHints->flags = USPosition; - } - - XTextProperty titleprop; - char *lst = (char*)title.c_str(); - XStringListToTextProperty((char **)&lst, 1, &titleprop); - XSetWMProperties((Display*)mNativeDisplay, (Window)mWindow, &titleprop, - NULL, NULL, 0, sizeHints, wmHints, NULL); - - XFree(titleprop.value); - XFree(wmHints); - XFree(sizeHints); - - XSetWMProtocols((Display*)mNativeDisplay, (Window)mWindow, &mGLSupport->mAtomDeleteWindow, 1); - - XWindowAttributes windowAttrib; - - XGetWindowAttributes((Display*)mNativeDisplay, (Window)mWindow, &windowAttrib); - - left = windowAttrib.x; - top = windowAttrib.y; - width = windowAttrib.width; - height = windowAttrib.height; - } - - mEglSurface = createSurfaceFromWindow(mGLSupport->getGLDisplay(), mWindow); - - XMapWindow((Display*)mNativeDisplay, (Window)mWindow); - - if (mIsFullScreen) - { - switchFullScreen(true); - } - - XFlush((Display*)mNativeDisplay); - - WindowEventUtilities::_addRenderWindow(this); - } - - void X11EGLWindow::setFullscreen( bool fullscreen, uint width, uint height ) - { - if (mIsFullScreen != fullscreen && &mGLSupport->mAtomFullScreen == None) - { - // Without WM support it is best to give up. - LogManager::getSingleton().logMessage("EGLWindow::switchFullScreen: Your WM has no fullscreen support"); - return; - } - EGLWindow::setFullscreen(fullscreen, width, height); - } - - void X11EGLWindow::reposition( int left, int top ) - { - if (mClosed || ! mIsTopLevel) - { - return; - } - - XMoveWindow((Display*)mGLSupport->getNativeDisplay(), (Window)mWindow, left, top); - } - - void X11EGLWindow::resize(uint width, uint height) - { - if (mClosed) - { - return; - } - - if (mWidth == width && mHeight == height) - { - return; - } - - if (width != 0 && height != 0) - { - if (mIsTopLevel) - { - XResizeWindow((Display*)mGLSupport->getNativeDisplay(), (Window)mWindow, width, height); - } - else - { - mWidth = width; - mHeight = height; - - for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) - { - (*it).second->_updateDimensions(); - } - } - } - } - - void X11EGLWindow::windowMovedOrResized() - { - if (mClosed || !mWindow) - { - return; - } - - NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); - XWindowAttributes windowAttrib; - - if (mIsTopLevel && !mIsFullScreen) - { - Window parent, root, *children; - uint nChildren; - - XQueryTree((Display*)mNativeDisplay, (Window)mWindow, &root, &parent, &children, &nChildren); - - if (children) - { - XFree(children); - } - - XGetWindowAttributes((Display*)mNativeDisplay, parent, &windowAttrib); - mLeft = windowAttrib.x; - mTop = windowAttrib.y; - } - - XGetWindowAttributes((Display*)mNativeDisplay, (Window)mWindow, &windowAttrib); - - if (mWidth == windowAttrib.width && mHeight == windowAttrib.height) - { - return; - } - - mWidth = windowAttrib.width; - mHeight = windowAttrib.height; - - for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) - { - (*it).second->_updateDimensions(); - } - } - void X11EGLWindow::switchFullScreen(bool fullscreen) - { - if (&mGLSupport->mAtomFullScreen != None) - { - NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); - XClientMessageEvent xMessage; - - xMessage.type = ClientMessage; - xMessage.serial = 0; - xMessage.send_event = True; - xMessage.window = (Window)mWindow; - xMessage.message_type = mGLSupport->mAtomState; - xMessage.format = 32; - xMessage.data.l[0] = (fullscreen ? 1 : 0); - xMessage.data.l[1] = mGLSupport->mAtomFullScreen; - xMessage.data.l[2] = 0; - - XSendEvent((Display*)mNativeDisplay, DefaultRootWindow((Display*)mNativeDisplay), False, - SubstructureRedirectMask | SubstructureNotifyMask, - (XEvent*)&xMessage); - - mIsFullScreen = fullscreen; - } - } - - - //Moved EGLWindow::create to native source because it has native calls in it + X11EGLWindow::X11EGLWindow(X11EGLSupport *glsupport) + : EGLWindow(glsupport) + //, mParentWindow(glsupport) todo + { + mGLSupport = glsupport; + mNativeDisplay = glsupport->getNativeDisplay(); + } + + X11EGLWindow::~X11EGLWindow() + { + + mNativeDisplay = mGLSupport->getNativeDisplay(); + // Ignore fatal XErrorEvents from stale handles. + oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); + + if (mWindow) + { + XDestroyWindow((Display*)mNativeDisplay, (Window)mWindow); + } + + XSetErrorHandler(oldXErrorHandler); + mWindow = 0; + + } + + void X11EGLWindow::getCustomAttribute( const String& name, void* pData ) + { + EGLWindow::getCustomAttribute(name, pData); + if (name == "ATOM") + { + *static_cast< ::Atom* >(pData) = mGLSupport->mAtomDeleteWindow; + return; + } + else if (name == "XDISPLAY") + { + *static_cast(pData) = mGLSupport->getNativeDisplay(); + return; + } + else if (name == "XWINDOW") + { + *static_cast(pData) = mWindow; + return; + } + + } + + EGLContext * X11EGLWindow::createEGLContext() const + { + return new X11EGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); + } + + void X11EGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) + { + NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); + left = DisplayWidth((Display*)mNativeDisplay, DefaultScreen(mNativeDisplay))/2 - width/2; + top = DisplayHeight((Display*)mNativeDisplay, DefaultScreen(mNativeDisplay))/2 - height/2; + } + + void X11EGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) + { + if (miscParams) + { + NameValuePairList::const_iterator opt; + NameValuePairList::const_iterator end = miscParams->end(); + + mExternalWindow = 0; + mNativeDisplay = mGLSupport->getNativeDisplay(); + mParentWindow = DefaultRootWindow((Display*)mNativeDisplay); + + if ((opt = miscParams->find("parentWindowHandle")) != end) + { + //vector::type tokens = StringUtil::split(opt->second, " :"); + StringVector tokens = StringUtil::split(opt->second, " :"); + + if (tokens.size() == 3) + { + // deprecated display:screen:xid format + mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); + } + else + { + // xid format + mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[0]); + } + } + else if ((opt = miscParams->find("externalWindowHandle")) != end) + { + //vector::type tokens = StringUtil::split(opt->second, " :"); + StringVector tokens = StringUtil::split(opt->second, " :"); + + LogManager::getSingleton().logMessage( + "EGLWindow::create: The externalWindowHandle parameter is deprecated.\n" + "Use the parentWindowHandle or currentGLContext parameter instead."); + if (tokens.size() == 3) + { + // Old display:screen:xid format + // The old EGL code always created a "parent" window in this case: + mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); + } + else if (tokens.size() == 4) + { + // Old display:screen:xid:visualinfo format + mExternalWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); + } + else + { + // xid format + mExternalWindow = (Window)StringConverter::parseUnsignedLong(tokens[0]); + } + } + + } + + // Ignore fatal XErrorEvents during parameter validation: + oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); + + // Validate parentWindowHandle + if (mParentWindow != DefaultRootWindow((Display*)mNativeDisplay)) + { + XWindowAttributes windowAttrib; + + if (!XGetWindowAttributes((Display*)mNativeDisplay, mParentWindow, &windowAttrib) || + windowAttrib.root != DefaultRootWindow((Display*)mNativeDisplay)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Invalid parentWindowHandle (wrong server or screen)", + "EGLWindow::create"); + } + } + + // Validate externalWindowHandle + if (mExternalWindow != 0) + { + XWindowAttributes windowAttrib; + + if (!XGetWindowAttributes((Display*)mNativeDisplay, mExternalWindow, &windowAttrib) || + windowAttrib.root != DefaultRootWindow((Display*)mNativeDisplay)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Invalid externalWindowHandle (wrong server or screen)", + "EGLWindow::create"); + } + + mEglConfig = 0; + mEglSurface = createSurfaceFromWindow(mEglDisplay, (NativeWindowType)mExternalWindow); + } + + XSetErrorHandler(oldXErrorHandler); + + mIsTopLevel = (!mIsExternal && mParentWindow == DefaultRootWindow((Display*)mNativeDisplay)); + + } + + void X11EGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) + { + mEglDisplay = mGLSupport->getGLDisplay();//todo + XSetWindowAttributes attr; + ulong mask; + XVisualInfo *visualInfo = mGLSupport->getVisualFromFBConfig(mEglConfig); + + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap((Display*)mNativeDisplay, + DefaultRootWindow((Display*)mNativeDisplay), + visualInfo->visual, + AllocNone); + attr.event_mask = StructureNotifyMask | VisibilityChangeMask | FocusChangeMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + if(mIsFullScreen && mGLSupport->mAtomFullScreen == None) + { + LogManager::getSingleton().logMessage("EGLWindow::switchFullScreen: Your WM has no fullscreen support"); + + // A second best approach for outdated window managers + attr.backing_store = NotUseful; + attr.save_under = False; + attr.override_redirect = True; + mask |= CWSaveUnder | CWBackingStore | CWOverrideRedirect; + left = top = 0; + } + + // Create window on server + mWindow = (NativeWindowType)XCreateWindow((Display*)mNativeDisplay, + mParentWindow, + left, top, width, height, + 0, visualInfo->depth, + InputOutput, + visualInfo->visual, mask, &attr); + XFree(visualInfo); + + if(!mWindow) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create an X NativeWindowType", + "EGLWindow::create"); + } + + if (mIsTopLevel) + { + XWMHints *wmHints; + XSizeHints *sizeHints; + + // Is this really necessary ? Which broken WM might need it? + if ((wmHints = XAllocWMHints()) != NULL) + { + wmHints->initial_state = NormalState; + wmHints->input = True; + wmHints->flags = StateHint | InputHint; + } + + // Is this really necessary ? Which broken WM might need it? + if ((sizeHints = XAllocSizeHints()) != NULL) + { + sizeHints->flags = USPosition; + } + + XTextProperty titleprop; + char *lst = (char*)title.c_str(); + XStringListToTextProperty((char **)&lst, 1, &titleprop); + XSetWMProperties((Display*)mNativeDisplay, (Window)mWindow, &titleprop, + NULL, NULL, 0, sizeHints, wmHints, NULL); + + XFree(titleprop.value); + XFree(wmHints); + XFree(sizeHints); + + XSetWMProtocols((Display*)mNativeDisplay, (Window)mWindow, &mGLSupport->mAtomDeleteWindow, 1); + + XWindowAttributes windowAttrib; + + XGetWindowAttributes((Display*)mNativeDisplay, (Window)mWindow, &windowAttrib); + + left = windowAttrib.x; + top = windowAttrib.y; + width = windowAttrib.width; + height = windowAttrib.height; + } + + mEglSurface = createSurfaceFromWindow(mGLSupport->getGLDisplay(), mWindow); + + XMapWindow((Display*)mNativeDisplay, (Window)mWindow); + + if (mIsFullScreen) + { + switchFullScreen(true); + } + + XFlush((Display*)mNativeDisplay); + + WindowEventUtilities::_addRenderWindow(this); + } + + void X11EGLWindow::setFullscreen( bool fullscreen, uint width, uint height ) + { + if (mIsFullScreen != fullscreen && &mGLSupport->mAtomFullScreen == None) + { + // Without WM support it is best to give up. + LogManager::getSingleton().logMessage("EGLWindow::switchFullScreen: Your WM has no fullscreen support"); + return; + } + EGLWindow::setFullscreen(fullscreen, width, height); + } + + void X11EGLWindow::reposition( int left, int top ) + { + if (mClosed || ! mIsTopLevel) + { + return; + } + + XMoveWindow((Display*)mGLSupport->getNativeDisplay(), (Window)mWindow, left, top); + } + + void X11EGLWindow::resize(uint width, uint height) + { + if (mClosed) + { + return; + } + + if (mWidth == width && mHeight == height) + { + return; + } + + if (width != 0 && height != 0) + { + if (mIsTopLevel) + { + XResizeWindow((Display*)mGLSupport->getNativeDisplay(), (Window)mWindow, width, height); + } + else + { + mWidth = width; + mHeight = height; + + for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) + { + (*it).second->_updateDimensions(); + } + } + } + } + + void X11EGLWindow::windowMovedOrResized() + { + if (mClosed || !mWindow) + { + return; + } + + NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); + XWindowAttributes windowAttrib; + + if (mIsTopLevel && !mIsFullScreen) + { + Window parent, root, *children; + uint nChildren; + + XQueryTree((Display*)mNativeDisplay, (Window)mWindow, &root, &parent, &children, &nChildren); + + if (children) + { + XFree(children); + } + + XGetWindowAttributes((Display*)mNativeDisplay, parent, &windowAttrib); + mLeft = windowAttrib.x; + mTop = windowAttrib.y; + } + + XGetWindowAttributes((Display*)mNativeDisplay, (Window)mWindow, &windowAttrib); + + if (mWidth == windowAttrib.width && mHeight == windowAttrib.height) + { + return; + } + + mWidth = windowAttrib.width; + mHeight = windowAttrib.height; + + for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) + { + (*it).second->_updateDimensions(); + } + } + void X11EGLWindow::switchFullScreen(bool fullscreen) + { + if (&mGLSupport->mAtomFullScreen != None) + { + NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); + XClientMessageEvent xMessage; + + xMessage.type = ClientMessage; + xMessage.serial = 0; + xMessage.send_event = True; + xMessage.window = (Window)mWindow; + xMessage.message_type = mGLSupport->mAtomState; + xMessage.format = 32; + xMessage.data.l[0] = (fullscreen ? 1 : 0); + xMessage.data.l[1] = mGLSupport->mAtomFullScreen; + xMessage.data.l[2] = 0; + + XSendEvent((Display*)mNativeDisplay, DefaultRootWindow((Display*)mNativeDisplay), False, + SubstructureRedirectMask | SubstructureNotifyMask, + (XEvent*)&xMessage); + + mIsFullScreen = fullscreen; + } + } + + + //Moved EGLWindow::create to native source because it has native calls in it void X11EGLWindow::create(const String& name, uint width, uint height, bool fullScreen, const NameValuePairList *miscParams) { @@ -439,10 +439,10 @@ namespace Ogre { short frequency = 0; bool vsync = false; ::EGLContext eglContext = 0; - int left = 0; - int top = 0; + int left = 0; + int top = 0; - getLeftAndTopFromNativeWindow(left, top, width, height); + getLeftAndTopFromNativeWindow(left, top, width, height); mIsFullScreen = fullScreen; @@ -506,9 +506,9 @@ namespace Ogre { { mIsExternalGLControl = StringConverter::parseBool(opt->second); } - } + } - initNativeCreatedWindow(miscParams); + initNativeCreatedWindow(miscParams); if (mEglSurface) { @@ -562,12 +562,12 @@ namespace Ogre { mGLSupport->switchMode (width, height, frequency); } - if (!mIsExternal) + if (!mIsExternal) { - createNativeWindow(left, top, width, height, title); - } + createNativeWindow(left, top, width, height, title); + } - mContext = createEGLContext(); + mContext = createEGLContext(); ::EGLSurface oldDrawableDraw = eglGetCurrentSurface(EGL_DRAW); ::EGLSurface oldDrawableRead = eglGetCurrentSurface(EGL_READ); @@ -584,10 +584,10 @@ namespace Ogre { mLeft = left; mTop = top; mActive = true; - mVisible = true; + mVisible = true; mClosed = false; - } + } diff --git a/RenderSystems/GLES/src/OgreGLESDefaultHardwareBufferManager.cpp b/RenderSystems/GLES/src/OgreGLESDefaultHardwareBufferManager.cpp index 3d1fb1baad2..ca314dfbc6e 100644 --- a/RenderSystems/GLES/src/OgreGLESDefaultHardwareBufferManager.cpp +++ b/RenderSystems/GLES/src/OgreGLESDefaultHardwareBufferManager.cpp @@ -99,12 +99,12 @@ namespace Ogre { : HardwareIndexBuffer(0, idxType, numIndexes, usage, true, false) // always software, never shadowed { - if (idxType == HardwareIndexBuffer::IT_32BIT) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "32 bit hardware buffers are not allowed in OpenGL ES.", - "GLESDefaultHardwareIndexBuffer"); - } + if (idxType == HardwareIndexBuffer::IT_32BIT) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "32 bit hardware buffers are not allowed in OpenGL ES.", + "GLESDefaultHardwareIndexBuffer"); + } mData = new unsigned char[mSizeInBytes]; } @@ -176,10 +176,10 @@ namespace Ogre { OGRE_NEW GLESDefaultHardwareIndexBuffer(itype, numIndexes, usage)); } - Ogre::RenderToVertexBufferSharedPtr GLESDefaultHardwareBufferManagerBase::createRenderToVertexBuffer( void ) - { + Ogre::RenderToVertexBufferSharedPtr GLESDefaultHardwareBufferManagerBase::createRenderToVertexBuffer( void ) + { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Cannot create RenderToVertexBuffer in GLESDefaultHardwareBufferManagerBase", "GLESDefaultHardwareBufferManagerBase::createRenderToVertexBuffer"); - } + } } diff --git a/RenderSystems/GLES/src/OgreGLESDepthBuffer.cpp b/RenderSystems/GLES/src/OgreGLESDepthBuffer.cpp index 34bc26ae844..90b37555aa1 100644 --- a/RenderSystems/GLES/src/OgreGLESDepthBuffer.cpp +++ b/RenderSystems/GLES/src/OgreGLESDepthBuffer.cpp @@ -32,102 +32,102 @@ THE SOFTWARE. namespace Ogre { - GLESDepthBuffer::GLESDepthBuffer( uint16 poolId, GLESRenderSystem *renderSystem, GLESContext *creatorContext, - GLESRenderBuffer *depth, GLESRenderBuffer *stencil, - uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, - bool isManual ) : - DepthBuffer( poolId, 0, width, height, fsaa, "", isManual ), - mMultiSampleQuality( multiSampleQuality ), - mCreatorContext( creatorContext ), - mDepthBuffer( depth ), - mStencilBuffer( stencil ), - mRenderSystem( renderSystem ) - { - if( mDepthBuffer ) - { - switch( mDepthBuffer->getGLFormat() ) - { + GLESDepthBuffer::GLESDepthBuffer( uint16 poolId, GLESRenderSystem *renderSystem, GLESContext *creatorContext, + GLESRenderBuffer *depth, GLESRenderBuffer *stencil, + uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, + bool isManual ) : + DepthBuffer( poolId, 0, width, height, fsaa, "", isManual ), + mMultiSampleQuality( multiSampleQuality ), + mCreatorContext( creatorContext ), + mDepthBuffer( depth ), + mStencilBuffer( stencil ), + mRenderSystem( renderSystem ) + { + if( mDepthBuffer ) + { + switch( mDepthBuffer->getGLFormat() ) + { #if GL_OES_framebuffer_object - case GL_DEPTH_COMPONENT16_OES: - mBitDepth = 16; - break; + case GL_DEPTH_COMPONENT16_OES: + mBitDepth = 16; + break; #endif #if GL_OES_packed_depth_stencil case GL_DEPTH24_STENCIL8_OES: // Packed depth / stencil #endif #if GL_OES_depth24 - case GL_DEPTH_COMPONENT24_OES: - mBitDepth = 32; - break; + case GL_DEPTH_COMPONENT24_OES: + mBitDepth = 32; + break; #endif - } - } - } - - GLESDepthBuffer::~GLESDepthBuffer() - { - if( mStencilBuffer && mStencilBuffer != mDepthBuffer ) - { - delete mStencilBuffer; - mStencilBuffer = 0; - } - - if( mDepthBuffer ) - { - delete mDepthBuffer; - mDepthBuffer = 0; - } - } - //--------------------------------------------------------------------- - bool GLESDepthBuffer::isCompatible( RenderTarget *renderTarget ) const - { - bool retVal = false; - - //Check standard stuff first. - if( mRenderSystem->getCapabilities()->hasCapability( RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL ) ) - { - if( !DepthBuffer::isCompatible( renderTarget ) ) - return false; - } - else - { - if( this->getWidth() != renderTarget->getWidth() || - this->getHeight() != renderTarget->getHeight() || - this->getFsaa() != renderTarget->getFSAA() ) - return false; - } - - //Now check this is the appropriate format - GLESFrameBufferObject *fbo = 0; + } + } + } + + GLESDepthBuffer::~GLESDepthBuffer() + { + if( mStencilBuffer && mStencilBuffer != mDepthBuffer ) + { + delete mStencilBuffer; + mStencilBuffer = 0; + } + + if( mDepthBuffer ) + { + delete mDepthBuffer; + mDepthBuffer = 0; + } + } + //--------------------------------------------------------------------- + bool GLESDepthBuffer::isCompatible( RenderTarget *renderTarget ) const + { + bool retVal = false; + + //Check standard stuff first. + if( mRenderSystem->getCapabilities()->hasCapability( RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL ) ) + { + if( !DepthBuffer::isCompatible( renderTarget ) ) + return false; + } + else + { + if( this->getWidth() != renderTarget->getWidth() || + this->getHeight() != renderTarget->getHeight() || + this->getFsaa() != renderTarget->getFSAA() ) + return false; + } + + //Now check this is the appropriate format + GLESFrameBufferObject *fbo = 0; renderTarget->getCustomAttribute("FBO", &fbo); - if( !fbo ) - { - GLESContext *windowContext = 0; - renderTarget->getCustomAttribute( "GLCONTEXT", &windowContext ); - - //Non-FBO targets and FBO depth surfaces don't play along, only dummies which match the same - //context - if( !mDepthBuffer && !mStencilBuffer && mCreatorContext == windowContext ) - retVal = true; - } - else - { - //Check this isn't a dummy non-FBO depth buffer with an FBO target, don't mix them. - //If you don't want depth buffer, use a Null Depth Buffer, not a dummy one. - if( mDepthBuffer || mStencilBuffer ) - { - GLenum internalFormat = fbo->getFormat(); - GLenum depthFormat, stencilFormat; - mRenderSystem->_getDepthStencilFormatFor( internalFormat, &depthFormat, &stencilFormat ); - - bool bSameDepth = false; - - if( mDepthBuffer ) - bSameDepth |= mDepthBuffer->getGLFormat() == depthFormat; - - bool bSameStencil = false; + if( !fbo ) + { + GLESContext *windowContext = 0; + renderTarget->getCustomAttribute( "GLCONTEXT", &windowContext ); + + //Non-FBO targets and FBO depth surfaces don't play along, only dummies which match the same + //context + if( !mDepthBuffer && !mStencilBuffer && mCreatorContext == windowContext ) + retVal = true; + } + else + { + //Check this isn't a dummy non-FBO depth buffer with an FBO target, don't mix them. + //If you don't want depth buffer, use a Null Depth Buffer, not a dummy one. + if( mDepthBuffer || mStencilBuffer ) + { + GLenum internalFormat = fbo->getFormat(); + GLenum depthFormat, stencilFormat; + mRenderSystem->_getDepthStencilFormatFor( internalFormat, &depthFormat, &stencilFormat ); + + bool bSameDepth = false; + + if( mDepthBuffer ) + bSameDepth |= mDepthBuffer->getGLFormat() == depthFormat; + + bool bSameStencil = false; if( !mStencilBuffer || mStencilBuffer == mDepthBuffer ) bSameStencil = stencilFormat == GL_NONE; @@ -137,10 +137,10 @@ namespace Ogre bSameStencil = stencilFormat == mStencilBuffer->getGLFormat(); } - retVal = bSameDepth && bSameStencil; - } - } + retVal = bSameDepth && bSameStencil; + } + } - return retVal; - } + return retVal; + } } diff --git a/RenderSystems/GLES/src/OgreGLESFBOMultiRenderTarget.cpp b/RenderSystems/GLES/src/OgreGLESFBOMultiRenderTarget.cpp index 2c01632ed4d..b5efe42d2c8 100644 --- a/RenderSystems/GLES/src/OgreGLESFBOMultiRenderTarget.cpp +++ b/RenderSystems/GLES/src/OgreGLESFBOMultiRenderTarget.cpp @@ -31,68 +31,68 @@ THE SOFTWARE. namespace Ogre { - GLESFBOMultiRenderTarget::GLESFBOMultiRenderTarget(GLESFBOManager *manager, const String &name): - MultiRenderTarget(name), - fbo(manager, 0 /* TODO: multisampling on MRTs? */) - { - } - GLESFBOMultiRenderTarget::~GLESFBOMultiRenderTarget() - { - } + GLESFBOMultiRenderTarget::GLESFBOMultiRenderTarget(GLESFBOManager *manager, const String &name): + MultiRenderTarget(name), + fbo(manager, 0 /* TODO: multisampling on MRTs? */) + { + } + GLESFBOMultiRenderTarget::~GLESFBOMultiRenderTarget() + { + } - void GLESFBOMultiRenderTarget::bindSurfaceImpl(size_t attachment, RenderTexture *target) - { - /// Check if the render target is in the rendertarget->FBO map + void GLESFBOMultiRenderTarget::bindSurfaceImpl(size_t attachment, RenderTexture *target) + { + /// Check if the render target is in the rendertarget->FBO map GLESFrameBufferObject *fbobj = 0; target->getCustomAttribute("FBO", &fbobj); - assert(fbobj); - fbo.bindSurface(attachment, fbobj->getSurface(0)); + assert(fbobj); + fbo.bindSurface(attachment, fbobj->getSurface(0)); GL_CHECK_ERROR; - // Initialise? + // Initialise? - // Set width and height - mWidth = fbo.getWidth(); - mHeight = fbo.getHeight(); - } + // Set width and height + mWidth = fbo.getWidth(); + mHeight = fbo.getHeight(); + } - void GLESFBOMultiRenderTarget::unbindSurfaceImpl(size_t attachment) - { - fbo.unbindSurface(attachment); + void GLESFBOMultiRenderTarget::unbindSurfaceImpl(size_t attachment) + { + fbo.unbindSurface(attachment); GL_CHECK_ERROR; - // Set width and height - mWidth = fbo.getWidth(); - mHeight = fbo.getHeight(); - } + // Set width and height + mWidth = fbo.getWidth(); + mHeight = fbo.getHeight(); + } - void GLESFBOMultiRenderTarget::getCustomAttribute( const String& name, void *pData ) - { - if(name=="FBO") + void GLESFBOMultiRenderTarget::getCustomAttribute( const String& name, void *pData ) + { + if(name=="FBO") { *static_cast(pData) = &fbo; } - } + } - //----------------------------------------------------------------------------- - bool GLESFBOMultiRenderTarget::attachDepthBuffer( DepthBuffer *depthBuffer ) - { - bool result; - if( (result = MultiRenderTarget::attachDepthBuffer( depthBuffer )) ) - fbo.attachDepthBuffer( depthBuffer ); + //----------------------------------------------------------------------------- + bool GLESFBOMultiRenderTarget::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + bool result; + if( (result = MultiRenderTarget::attachDepthBuffer( depthBuffer )) ) + fbo.attachDepthBuffer( depthBuffer ); - return result; - } - //----------------------------------------------------------------------------- - void GLESFBOMultiRenderTarget::detachDepthBuffer() - { - fbo.detachDepthBuffer(); - MultiRenderTarget::detachDepthBuffer(); - } - //----------------------------------------------------------------------------- - void GLESFBOMultiRenderTarget::_detachDepthBuffer() - { - fbo.detachDepthBuffer(); - MultiRenderTarget::_detachDepthBuffer(); - } + return result; + } + //----------------------------------------------------------------------------- + void GLESFBOMultiRenderTarget::detachDepthBuffer() + { + fbo.detachDepthBuffer(); + MultiRenderTarget::detachDepthBuffer(); + } + //----------------------------------------------------------------------------- + void GLESFBOMultiRenderTarget::_detachDepthBuffer() + { + fbo.detachDepthBuffer(); + MultiRenderTarget::_detachDepthBuffer(); + } } diff --git a/RenderSystems/GLES/src/OgreGLESFBORenderTexture.cpp b/RenderSystems/GLES/src/OgreGLESFBORenderTexture.cpp index 5d3c7c491ba..fe11c1f2c80 100644 --- a/RenderSystems/GLES/src/OgreGLESFBORenderTexture.cpp +++ b/RenderSystems/GLES/src/OgreGLESFBORenderTexture.cpp @@ -58,10 +58,10 @@ namespace Ogre { } } - void GLESFBORenderTexture::swapBuffers() - { - mFB.swapBuffers(); - } + void GLESFBORenderTexture::swapBuffers() + { + mFB.swapBuffers(); + } #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID void GLESFBORenderTexture::notifyOnContextLost() @@ -82,26 +82,26 @@ namespace Ogre { #endif //----------------------------------------------------------------------------- - bool GLESFBORenderTexture::attachDepthBuffer( DepthBuffer *depthBuffer ) - { - bool result; - if( (result = GLESRenderTexture::attachDepthBuffer( depthBuffer )) ) - mFB.attachDepthBuffer( depthBuffer ); - - return result; - } - //----------------------------------------------------------------------------- - void GLESFBORenderTexture::detachDepthBuffer() - { - mFB.detachDepthBuffer(); - GLESRenderTexture::detachDepthBuffer(); - } - //----------------------------------------------------------------------------- - void GLESFBORenderTexture::_detachDepthBuffer() - { - mFB.detachDepthBuffer(); - GLESRenderTexture::_detachDepthBuffer(); - } + bool GLESFBORenderTexture::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + bool result; + if( (result = GLESRenderTexture::attachDepthBuffer( depthBuffer )) ) + mFB.attachDepthBuffer( depthBuffer ); + + return result; + } + //----------------------------------------------------------------------------- + void GLESFBORenderTexture::detachDepthBuffer() + { + mFB.detachDepthBuffer(); + GLESRenderTexture::detachDepthBuffer(); + } + //----------------------------------------------------------------------------- + void GLESFBORenderTexture::_detachDepthBuffer() + { + mFB.detachDepthBuffer(); + GLESRenderTexture::_detachDepthBuffer(); + } /// Size of probe texture #define PROBE_SIZE 16 @@ -131,8 +131,8 @@ namespace Ogre { }; #define DEPTHFORMAT_COUNT (sizeof(depthFormats)/sizeof(GLenum)) - GLESFBOManager::GLESFBOManager() - : mTempFBO(0) + GLESFBOManager::GLESFBOManager() + : mTempFBO(0) { detectFBOFormats(); @@ -140,16 +140,16 @@ namespace Ogre { GL_CHECK_ERROR; } - GLESFBOManager::~GLESFBOManager() - { - if(!mRenderBufferMap.empty()) - { - LogManager::getSingleton().logMessage("GL ES: Warning! GLESFBOManager destructor called, but not all renderbuffers were released."); - } + GLESFBOManager::~GLESFBOManager() + { + if(!mRenderBufferMap.empty()) + { + LogManager::getSingleton().logMessage("GL ES: Warning! GLESFBOManager destructor called, but not all renderbuffers were released."); + } glDeleteFramebuffersOES(1, &mTempFBO); GL_CHECK_ERROR; - } + } void GLESFBOManager::_reload() { @@ -271,8 +271,8 @@ namespace Ogre { { mProps[x].valid = false; - // Fetch GL format token - GLenum fmt = GLESPixelUtil::getGLInternalFormat((PixelFormat)x); + // Fetch GL format token + GLenum fmt = GLESPixelUtil::getGLInternalFormat((PixelFormat)x); #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID if(fmt == GL_NONE) continue; @@ -281,42 +281,42 @@ namespace Ogre { continue; #endif - // No test for compressed formats - if(PixelUtil::isCompressed((PixelFormat)x)) - continue; + // No test for compressed formats + if(PixelUtil::isCompressed((PixelFormat)x)) + continue; // Create and attach framebuffer glGenFramebuffersOES(1, &fb); glBindFramebufferOES(GL_FRAMEBUFFER_OES, fb); if (fmt!=GL_NONE) { - // Create and attach texture - glGenTextures(1, &tid); - glBindTexture(target, tid); - + // Create and attach texture + glGenTextures(1, &tid); + glBindTexture(target, tid); + // Set some default parameters glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, fmt, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, + glTexImage2D(target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, fmt, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, target, tid, 0); } // Check status GLuint status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); - // Ignore status in case of fmt==GL_NONE, because no implementation will accept - // a buffer without *any* attachment. Buffers with only stencil and depth attachment - // might still be supported, so we must continue probing. + // Ignore status in case of fmt==GL_NONE, because no implementation will accept + // a buffer without *any* attachment. Buffers with only stencil and depth attachment + // might still be supported, so we must continue probing. if(fmt == GL_NONE || status == GL_FRAMEBUFFER_COMPLETE_OES) { mProps[x].valid = true; - StringStream str; - str << "FBO " << PixelUtil::getFormatName((PixelFormat)x) - << " depth/stencil support: "; + StringStream str; + str << "FBO " << PixelUtil::getFormatName((PixelFormat)x) + << " depth/stencil support: "; // For each depth/stencil formats for (size_t depth = 0; depth < DEPTHFORMAT_COUNT; ++depth) @@ -329,8 +329,8 @@ namespace Ogre { { //StringStream l; //l << "Trying " << PixelUtil::getFormatName((PixelFormat)x) - // << " D" << depthBits[depth] - // << "S" << stencilBits[stencil]; + // << " D" << depthBits[depth] + // << "S" << stencilBits[stencil]; //LogManager::getSingleton().logMessage(l.str()); if (_tryFormat(depthFormats[depth], stencilFormats[stencil])) @@ -364,12 +364,12 @@ namespace Ogre { // Delete texture and framebuffer glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); glDeleteFramebuffersOES(1, &fb); - + if (fmt!=GL_NONE) glDeleteTextures(1, &tid); } - String fmtstring; + String fmtstring; for(size_t x=0; xbestscore) @@ -415,15 +415,15 @@ namespace Ogre { } GLESFBORenderTexture *GLESFBOManager::createRenderTexture(const String &name, - const GLESSurfaceDesc &target, bool writeGamma, uint fsaa) + const GLESSurfaceDesc &target, bool writeGamma, uint fsaa) { GLESFBORenderTexture *retval = OGRE_NEW GLESFBORenderTexture(this, name, target, writeGamma, fsaa); return retval; } - MultiRenderTarget *GLESFBOManager::createMultiRenderTarget(const String & name) - { - return OGRE_NEW GLESFBOMultiRenderTarget(this, name); - } + MultiRenderTarget *GLESFBOManager::createMultiRenderTarget(const String & name) + { + return OGRE_NEW GLESFBOMultiRenderTarget(this, name); + } void GLESFBOManager::bind(RenderTarget *target) { @@ -455,7 +455,7 @@ namespace Ogre { { retval.buffer = it->second.buffer; retval.zoffset = 0; - retval.numSamples = fsaa; + retval.numSamples = fsaa; // Increase refcount ++it->second.refcount; } @@ -466,7 +466,7 @@ namespace Ogre { mRenderBufferMap[key] = RBRef(rb); retval.buffer = rb; retval.zoffset = 0; - retval.numSamples = fsaa; + retval.numSamples = fsaa; } } // std::cerr << "Requested renderbuffer with format " << std::hex << format << std::dec << " of " << width << "x" << height << " :" << retval.buffer << std::endl; @@ -495,17 +495,17 @@ namespace Ogre { RBFormat key(surface.buffer->getGLFormat(), surface.buffer->getWidth(), surface.buffer->getHeight(), surface.numSamples); RenderBufferMap::iterator it = mRenderBufferMap.find(key); if(it != mRenderBufferMap.end()) - { - // Decrease refcount - --it->second.refcount; - if(it->second.refcount==0) - { - // If refcount reaches zero, delete buffer and remove from map - OGRE_DELETE it->second.buffer; - mRenderBufferMap.erase(it); - //std::cerr << "Destroyed renderbuffer of format " << std::hex << key.format << std::dec - // << " of " << key.width << "x" << key.height << std::endl; - } - } + { + // Decrease refcount + --it->second.refcount; + if(it->second.refcount==0) + { + // If refcount reaches zero, delete buffer and remove from map + OGRE_DELETE it->second.buffer; + mRenderBufferMap.erase(it); + //std::cerr << "Destroyed renderbuffer of format " << std::hex << key.format << std::dec + // << " of " << key.width << "x" << key.height << std::endl; + } + } } } diff --git a/RenderSystems/GLES/src/OgreGLESFrameBufferObject.cpp b/RenderSystems/GLES/src/OgreGLESFrameBufferObject.cpp index 5e73d004b70..addc88baba0 100644 --- a/RenderSystems/GLES/src/OgreGLESFrameBufferObject.cpp +++ b/RenderSystems/GLES/src/OgreGLESFrameBufferObject.cpp @@ -42,30 +42,30 @@ namespace Ogre { glGenFramebuffersOES(1, &mFB); GL_CHECK_ERROR; - // Check multisampling + // Check multisampling #if GL_APPLE_framebuffer_multisample - // Check samples supported - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFB); + // Check samples supported + glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFB); GL_CHECK_ERROR; - GLint maxSamples; - glGetIntegerv(GL_MAX_SAMPLES_APPLE, &maxSamples); + GLint maxSamples; + glGetIntegerv(GL_MAX_SAMPLES_APPLE, &maxSamples); GL_CHECK_ERROR; - glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); GL_CHECK_ERROR; - mNumSamples = std::min(mNumSamples, (GLsizei)maxSamples); + mNumSamples = std::min(mNumSamples, (GLsizei)maxSamples); #else - mNumSamples = 0; + mNumSamples = 0; #endif - // will we need a second FBO to do multisampling? - if (mNumSamples) - { - glGenFramebuffersOES(1, &mMultisampleFB); + // will we need a second FBO to do multisampling? + if (mNumSamples) + { + glGenFramebuffersOES(1, &mMultisampleFB); GL_CHECK_ERROR; - } - else - { - mMultisampleFB = 0; - } + } + else + { + mMultisampleFB = 0; + } /// Initialise state mDepth.buffer=0; @@ -80,13 +80,13 @@ namespace Ogre { { mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); - mManager->releaseRenderBuffer(mMultisampleColourBuffer); + mManager->releaseRenderBuffer(mMultisampleColourBuffer); /// Delete framebuffer object glDeleteFramebuffersOES(1, &mFB); GL_CHECK_ERROR; - if (mMultisampleFB) - glDeleteFramebuffersOES(1, &mMultisampleFB); + if (mMultisampleFB) + glDeleteFramebuffersOES(1, &mMultisampleFB); GL_CHECK_ERROR; } @@ -96,13 +96,13 @@ namespace Ogre { { mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); - mManager->releaseRenderBuffer(mMultisampleColourBuffer); + mManager->releaseRenderBuffer(mMultisampleColourBuffer); glDeleteFramebuffersOES(1, &mFB); GL_CHECK_ERROR; - if (mMultisampleFB) - glDeleteFramebuffersOES(1, &mMultisampleFB); + if (mMultisampleFB) + glDeleteFramebuffersOES(1, &mMultisampleFB); GL_CHECK_ERROR; } @@ -126,26 +126,26 @@ namespace Ogre { { assert(attachment < OGRE_MAX_MULTIPLE_RENDER_TARGETS); mColour[attachment] = target; - // Re-initialise - if(mColour[0].buffer) - initialise(); + // Re-initialise + if(mColour[0].buffer) + initialise(); } void GLESFrameBufferObject::unbindSurface(size_t attachment) { assert(attachment < OGRE_MAX_MULTIPLE_RENDER_TARGETS); mColour[attachment].buffer = 0; - // Re-initialise if buffer 0 still bound - if(mColour[0].buffer) - initialise(); + // Re-initialise if buffer 0 still bound + if(mColour[0].buffer) + initialise(); } void GLESFrameBufferObject::initialise() { - // Release depth and stencil, if they were bound + // Release depth and stencil, if they were bound mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); - mManager->releaseRenderBuffer(mMultisampleColourBuffer); + mManager->releaseRenderBuffer(mMultisampleColourBuffer); /// First buffer must be bound if(!mColour[0].buffer) { @@ -154,18 +154,18 @@ namespace Ogre { "GLESFrameBufferObject::initialise"); } - // If we're doing multisampling, then we need another FBO which contains a - // renderbuffer which is set up to multisample, and we'll blit it to the final - // FBO afterwards to perform the multisample resolve. In that case, the - // mMultisampleFB is bound during rendering and is the one with a depth/stencil + // If we're doing multisampling, then we need another FBO which contains a + // renderbuffer which is set up to multisample, and we'll blit it to the final + // FBO afterwards to perform the multisample resolve. In that case, the + // mMultisampleFB is bound during rendering and is the one with a depth/stencil /// Store basic stats size_t width = mColour[0].buffer->getWidth(); size_t height = mColour[0].buffer->getHeight(); GLuint format = mColour[0].buffer->getGLFormat(); - // Bind simple buffer to add colour attachments - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFB); + // Bind simple buffer to add colour attachments + glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFB); GL_CHECK_ERROR; /// Bind all attachment points to frame buffer @@ -189,7 +189,7 @@ namespace Ogre { ss << "Attachment " << x << " has incompatible format."; OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "GLESFrameBufferObject::initialise"); } - mColour[x].buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_OES+x, mColour[x].zoffset); + mColour[x].buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_OES+x, mColour[x].zoffset); } else { @@ -200,43 +200,43 @@ namespace Ogre { } } - // Now deal with depth / stencil - if (mMultisampleFB) - { - // Bind multisample buffer - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mMultisampleFB); + // Now deal with depth / stencil + if (mMultisampleFB) + { + // Bind multisample buffer + glBindFramebufferOES(GL_FRAMEBUFFER_OES, mMultisampleFB); GL_CHECK_ERROR; - // Create AA render buffer (colour) - // note, this can be shared too because we blit it to the final FBO - // right after the render is finished - mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); + // Create AA render buffer (colour) + // note, this can be shared too because we blit it to the final FBO + // right after the render is finished + mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); - // Attach it, because we won't be attaching below and non-multisample has - // actually been attached to other FBO - mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_OES, - mMultisampleColourBuffer.zoffset); + // Attach it, because we won't be attaching below and non-multisample has + // actually been attached to other FBO + mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0_OES, + mMultisampleColourBuffer.zoffset); - // depth & stencil will be dealt with below - } + // depth & stencil will be dealt with below + } /// Depth buffer is not handled here anymore. - /// See GLESFrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() + /// See GLESFrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() - /// Do glDrawBuffer calls - GLenum bufs[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - for(size_t x=0; x(depthBuffer); + void GLESFrameBufferObject::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + GLESDepthBuffer *glDepthBuffer = static_cast(depthBuffer); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mMultisampleFB ? mMultisampleFB : mFB ); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, mMultisampleFB ? mMultisampleFB : mFB ); - if( glDepthBuffer ) - { - GLESRenderBuffer *depthBuf = glDepthBuffer->getDepthBuffer(); - GLESRenderBuffer *stencilBuf = glDepthBuffer->getStencilBuffer(); + if( glDepthBuffer ) + { + GLESRenderBuffer *depthBuf = glDepthBuffer->getDepthBuffer(); + GLESRenderBuffer *stencilBuf = glDepthBuffer->getStencilBuffer(); - //Attach depth buffer, if it has one. - if( depthBuf ) - depthBuf->bindToFramebuffer( GL_DEPTH_ATTACHMENT_OES, 0 ); + //Attach depth buffer, if it has one. + if( depthBuf ) + depthBuf->bindToFramebuffer( GL_DEPTH_ATTACHMENT_OES, 0 ); - //Attach stencil buffer, if it has one. - if( stencilBuf ) - stencilBuf->bindToFramebuffer( GL_STENCIL_ATTACHMENT_OES, 0 ); - } - else - { - glFramebufferRenderbufferOES( GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, - GL_RENDERBUFFER_OES, 0); - glFramebufferRenderbufferOES( GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, - GL_RENDERBUFFER_OES, 0); - } - } - //----------------------------------------------------------------------------- - void GLESFrameBufferObject::detachDepthBuffer() - { - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mMultisampleFB ? mMultisampleFB : mFB ); - glFramebufferRenderbufferOES( GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, 0 ); - glFramebufferRenderbufferOES( GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, - GL_RENDERBUFFER_OES, 0 ); - } + //Attach stencil buffer, if it has one. + if( stencilBuf ) + stencilBuf->bindToFramebuffer( GL_STENCIL_ATTACHMENT_OES, 0 ); + } + else + { + glFramebufferRenderbufferOES( GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, + GL_RENDERBUFFER_OES, 0); + glFramebufferRenderbufferOES( GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, + GL_RENDERBUFFER_OES, 0); + } + } + //----------------------------------------------------------------------------- + void GLESFrameBufferObject::detachDepthBuffer() + { + glBindFramebufferOES(GL_FRAMEBUFFER_OES, mMultisampleFB ? mMultisampleFB : mFB ); + glFramebufferRenderbufferOES( GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, 0 ); + glFramebufferRenderbufferOES( GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, + GL_RENDERBUFFER_OES, 0 ); + } uint32 GLESFrameBufferObject::getWidth() { @@ -345,7 +345,7 @@ namespace Ogre { assert(mColour[0].buffer); return mColour[0].buffer->getFormat(); } - GLsizei GLESFrameBufferObject::getFSAA() + GLsizei GLESFrameBufferObject::getFSAA() { return mNumSamples; } diff --git a/RenderSystems/GLES/src/OgreGLESGpuProgramManager.cpp b/RenderSystems/GLES/src/OgreGLESGpuProgramManager.cpp index c1365faad13..e5e8abb69f0 100644 --- a/RenderSystems/GLES/src/OgreGLESGpuProgramManager.cpp +++ b/RenderSystems/GLES/src/OgreGLESGpuProgramManager.cpp @@ -101,20 +101,20 @@ namespace Ogre { const String& syntaxCode) { // TODO not implemented - class DummyGpuProgram : public GpuProgram - { - public: - DummyGpuProgram(ResourceManager* creator, const String& inName, ResourceHandle inHandle, - const String& inGroup, bool inIsManual, ManualResourceLoader* inLoader) - : GpuProgram(creator, inName, inHandle, inGroup, inIsManual, inLoader ) - {}; - /** @copydoc Resource::unloadImpl */ - void unloadImpl(void){}; - /** Overridden from GpuProgram */ - void loadFromSource(void){}; - - }; - return OGRE_NEW DummyGpuProgram(this, name, handle, group, - isManual, loader); + class DummyGpuProgram : public GpuProgram + { + public: + DummyGpuProgram(ResourceManager* creator, const String& inName, ResourceHandle inHandle, + const String& inGroup, bool inIsManual, ManualResourceLoader* inLoader) + : GpuProgram(creator, inName, inHandle, inGroup, inIsManual, inLoader ) + {}; + /** @copydoc Resource::unloadImpl */ + void unloadImpl(void){}; + /** Overridden from GpuProgram */ + void loadFromSource(void){}; + + }; + return OGRE_NEW DummyGpuProgram(this, name, handle, group, + isManual, loader); } } diff --git a/RenderSystems/GLES/src/OgreGLESHardwareBufferManager.cpp b/RenderSystems/GLES/src/OgreGLESHardwareBufferManager.cpp index 6fc2f2444cb..7cb9c1722c3 100644 --- a/RenderSystems/GLES/src/OgreGLESHardwareBufferManager.cpp +++ b/RenderSystems/GLES/src/OgreGLESHardwareBufferManager.cpp @@ -58,10 +58,10 @@ namespace Ogre { ptrAlloc->free = 1; // non-Win32 machines are having issues glBufferSubData, looks like buffer corruption - // disable for now until we figure out where the problem lies -# if OGRE_PLATFORM != OGRE_PLATFORM_WIN32 - mMapBufferThreshold = 0; -# endif + // disable for now until we figure out where the problem lies +# if OGRE_PLATFORM != OGRE_PLATFORM_WIN32 + mMapBufferThreshold = 0; +# endif } GLESHardwareBufferManagerBase::~GLESHardwareBufferManagerBase() @@ -103,11 +103,11 @@ namespace Ogre { return HardwareIndexBufferSharedPtr(buf); } - RenderToVertexBufferSharedPtr GLESHardwareBufferManagerBase::createRenderToVertexBuffer() - { - // not supported - return RenderToVertexBufferSharedPtr(); - } + RenderToVertexBufferSharedPtr GLESHardwareBufferManagerBase::createRenderToVertexBuffer() + { + // not supported + return RenderToVertexBufferSharedPtr(); + } GLenum GLESHardwareBufferManagerBase::getGLUsage(unsigned int usage) @@ -249,16 +249,16 @@ namespace Ogre { // Should never get here unless there's a corruption assert(false && "Memory deallocation error"); } - //--------------------------------------------------------------------- - size_t GLESHardwareBufferManagerBase::getGLMapBufferThreshold() const - { - return mMapBufferThreshold; - } - //--------------------------------------------------------------------- - void GLESHardwareBufferManagerBase::setGLMapBufferThreshold( const size_t value ) - { - mMapBufferThreshold = value; - } + //--------------------------------------------------------------------- + size_t GLESHardwareBufferManagerBase::getGLMapBufferThreshold() const + { + return mMapBufferThreshold; + } + //--------------------------------------------------------------------- + void GLESHardwareBufferManagerBase::setGLMapBufferThreshold( const size_t value ) + { + mMapBufferThreshold = value; + } //--------------------------------------------------------------------- HardwareUniformBufferSharedPtr GLESHardwareBufferManagerBase:: createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, diff --git a/RenderSystems/GLES/src/OgreGLESHardwareIndexBuffer.cpp b/RenderSystems/GLES/src/OgreGLESHardwareIndexBuffer.cpp index 64e263ca27e..9c6f0028354 100644 --- a/RenderSystems/GLES/src/OgreGLESHardwareIndexBuffer.cpp +++ b/RenderSystems/GLES/src/OgreGLESHardwareIndexBuffer.cpp @@ -34,20 +34,20 @@ THE SOFTWARE. namespace Ogre { GLESHardwareIndexBuffer::GLESHardwareIndexBuffer(HardwareBufferManagerBase* mgr, - IndexType idxType, + IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer) : HardwareIndexBuffer(mgr, idxType, numIndexes, usage, false, true) { - if (idxType == HardwareIndexBuffer::IT_32BIT) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "32 bit hardware buffers are not allowed in OpenGL ES.", - "GLESHardwareIndexBuffer"); - } + if (idxType == HardwareIndexBuffer::IT_32BIT) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "32 bit hardware buffers are not allowed in OpenGL ES.", + "GLESHardwareIndexBuffer"); + } - if (!useShadowBuffer) + if (!useShadowBuffer) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Only support with shadowBuffer", @@ -112,7 +112,7 @@ namespace Ogre { mScratchOffset == 0 && mScratchSize == getSizeInBytes()); } - // deallocate from scratch buffer + // deallocate from scratch buffer static_cast( HardwareBufferManager::getSingletonPtr())->deallocateScratch(mScratchPtr); @@ -121,14 +121,14 @@ namespace Ogre { else { #if defined(GL_GLEXT_PROTOTYPES) - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mBufferId ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mBufferId ); - if(!glUnmapBufferOES( GL_ELEMENT_ARRAY_BUFFER )) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + if(!glUnmapBufferOES( GL_ELEMENT_ARRAY_BUFFER )) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer data corrupted, please reload", "GLESHardwareIndexBuffer::unlock"); - } + } #else OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Lock to scratch is only supported", @@ -150,7 +150,7 @@ namespace Ogre { } void* retPtr = 0; - GLESHardwareBufferManager* glBufManager = static_cast(HardwareBufferManager::getSingletonPtr()); + GLESHardwareBufferManager* glBufManager = static_cast(HardwareBufferManager::getSingletonPtr()); if(length < glBufManager->getGLMapBufferThreshold()) { @@ -178,34 +178,34 @@ namespace Ogre { #if defined(GL_GLEXT_PROTOTYPES) if (!retPtr) - { + { GLenum access = 0; - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mBufferId ); - // Use glMapBuffer - if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE) - { - // Discard the buffer - glBufferData(GL_ELEMENT_ARRAY_BUFFER, mSizeInBytes, NULL, + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mBufferId ); + // Use glMapBuffer + if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE) + { + // Discard the buffer + glBufferData(GL_ELEMENT_ARRAY_BUFFER, mSizeInBytes, NULL, GLESHardwareBufferManager::getGLUsage(mUsage)); - } - if (mUsage & HBU_WRITE_ONLY) - access = GL_WRITE_ONLY_OES; + } + if (mUsage & HBU_WRITE_ONLY) + access = GL_WRITE_ONLY_OES; - void* pBuffer = glMapBufferOES( GL_ELEMENT_ARRAY_BUFFER, access ); + void* pBuffer = glMapBufferOES( GL_ELEMENT_ARRAY_BUFFER, access ); - if(pBuffer == 0) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + if(pBuffer == 0) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Index Buffer: Out of memory", "GLESHardwareIndexBuffer::lock"); - } + } - // return offsetted - retPtr = static_cast(static_cast(pBuffer) + offset); + // return offsetted + retPtr = static_cast(static_cast(pBuffer) + offset); - mLockedToScratch = false; - } - mIsLocked = true; + mLockedToScratch = false; + } + mIsLocked = true; #endif return retPtr; diff --git a/RenderSystems/GLES/src/OgreGLESHardwarePixelBuffer.cpp b/RenderSystems/GLES/src/OgreGLESHardwarePixelBuffer.cpp index d3f69dd9bd7..bd249b2fa6e 100644 --- a/RenderSystems/GLES/src/OgreGLESHardwarePixelBuffer.cpp +++ b/RenderSystems/GLES/src/OgreGLESHardwarePixelBuffer.cpp @@ -469,12 +469,12 @@ namespace Ogre { // @author W.J. van der Laan void GLESTextureBuffer::blitFromTexture(GLESTextureBuffer *src, const Image::Box &srcBox, const Image::Box &dstBox) { - if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_FBO) == false) - { - // the following code depends on FBO support, it crashes if FBO is not supported. - // TODO - write PBUFFER version of this function or a version that doesn't require FBO - return; // for now - do nothing. - } + if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_FBO) == false) + { + // the following code depends on FBO support, it crashes if FBO is not supported. + // TODO - write PBUFFER version of this function or a version that doesn't require FBO + return; // for now - do nothing. + } // std::cerr << "GLESTextureBuffer::blitFromTexture " << // src->mTextureID << ":" << srcBox.left << "," << srcBox.top << "," << srcBox.right << "," << srcBox.bottom << " " << diff --git a/RenderSystems/GLES/src/OgreGLESHardwareVertexBuffer.cpp b/RenderSystems/GLES/src/OgreGLESHardwareVertexBuffer.cpp index 9a0e8d1dce3..af605788f1a 100644 --- a/RenderSystems/GLES/src/OgreGLESHardwareVertexBuffer.cpp +++ b/RenderSystems/GLES/src/OgreGLESHardwareVertexBuffer.cpp @@ -34,7 +34,7 @@ THE SOFTWARE. namespace Ogre { GLESHardwareVertexBuffer::GLESHardwareVertexBuffer(HardwareBufferManagerBase* mgr, - size_t vertexSize, + size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage, bool useShadowBuffer) @@ -107,12 +107,12 @@ namespace Ogre { void* retPtr = 0; - GLESHardwareBufferManager* glBufManager = static_cast(HardwareBufferManager::getSingletonPtr()); + GLESHardwareBufferManager* glBufManager = static_cast(HardwareBufferManager::getSingletonPtr()); - // Try to use scratch buffers for smaller buffers + // Try to use scratch buffers for smaller buffers if (length < glBufManager->getGLMapBufferThreshold()) { - // if this fails, we fall back on mapping + // if this fails, we fall back on mapping retPtr = glBufManager->allocateScratch((uint32)length); if (retPtr) @@ -125,7 +125,7 @@ namespace Ogre { if (options != HBL_DISCARD && options != HBL_NO_OVERWRITE) { - // have to read back the data before returning the pointer + // have to read back the data before returning the pointer readData(offset, length, retPtr); } } @@ -139,37 +139,37 @@ namespace Ogre { #if defined(GL_GLEXT_PROTOTYPES) if (!retPtr) - { + { GLenum access = 0; - // Use glMapBuffer - glBindBuffer( GL_ARRAY_BUFFER, mBufferId ); - // Use glMapBuffer - if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE) - { - // Discard the buffer - glBufferData(GL_ARRAY_BUFFER, mSizeInBytes, NULL, + // Use glMapBuffer + glBindBuffer( GL_ARRAY_BUFFER, mBufferId ); + // Use glMapBuffer + if(options == HBL_DISCARD || options == HBL_NO_OVERWRITE) + { + // Discard the buffer + glBufferData(GL_ARRAY_BUFFER, mSizeInBytes, NULL, GLESHardwareBufferManager::getGLUsage(mUsage)); - } - if (mUsage & HBU_WRITE_ONLY) - access = GL_WRITE_ONLY_OES; + } + if (mUsage & HBU_WRITE_ONLY) + access = GL_WRITE_ONLY_OES; - void* pBuffer = glMapBufferOES( GL_ARRAY_BUFFER, access); + void* pBuffer = glMapBufferOES( GL_ARRAY_BUFFER, access); - if(pBuffer == 0) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + if(pBuffer == 0) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Vertex Buffer: Out of memory", "GLESHardwareVertexBuffer::lock"); - } + } - // return offsetted - retPtr = static_cast( - static_cast(pBuffer) + offset); + // return offsetted + retPtr = static_cast( + static_cast(pBuffer) + offset); - mLockedToScratch = false; - } + mLockedToScratch = false; + } #endif - mIsLocked = true; + mIsLocked = true; return retPtr; } @@ -192,14 +192,14 @@ namespace Ogre { else { #if defined(GL_GLEXT_PROTOTYPES) - glBindBuffer(GL_ARRAY_BUFFER, mBufferId); + glBindBuffer(GL_ARRAY_BUFFER, mBufferId); - if(!glUnmapBufferOES( GL_ARRAY_BUFFER )) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + if(!glUnmapBufferOES( GL_ARRAY_BUFFER )) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer data corrupted, please reload", "GLESHardwareVertexBuffer::unlock"); - } + } #else OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Only locking to scratch is supported", diff --git a/RenderSystems/GLES/src/OgreGLESPixelFormat.cpp b/RenderSystems/GLES/src/OgreGLESPixelFormat.cpp index 81e354d0899..9d9ccc5a3d3 100644 --- a/RenderSystems/GLES/src/OgreGLESPixelFormat.cpp +++ b/RenderSystems/GLES/src/OgreGLESPixelFormat.cpp @@ -35,9 +35,9 @@ THE SOFTWARE. /* GL_AMD_compressed_ATC_texture */ #if OGRE_NO_ETC_CODEC == 0 -# define ATC_RGB_AMD 0x8C92 -# define ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 -# define ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +# define ATC_RGB_AMD 0x8C92 +# define ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +# define ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE #endif @@ -79,18 +79,18 @@ namespace Ogre { return GL_RGB; #if OGRE_NO_ETC_CODEC == 0 -# ifdef GL_OES_compressed_ETC1_RGB8_texture +# ifdef GL_OES_compressed_ETC1_RGB8_texture case PF_ETC1_RGB8: return GL_ETC1_RGB8_OES; -# endif -# ifdef GL_AMD_compressed_ATC_texture - case PF_ATC_RGB: - return ATC_RGB_AMD; - case PF_ATC_RGBA_EXPLICIT_ALPHA: - return ATC_RGBA_EXPLICIT_ALPHA_AMD; - case PF_ATC_RGBA_INTERPOLATED_ALPHA: - return ATC_RGBA_INTERPOLATED_ALPHA_AMD; -# endif +# endif +# ifdef GL_AMD_compressed_ATC_texture + case PF_ATC_RGB: + return ATC_RGB_AMD; + case PF_ATC_RGBA_EXPLICIT_ALPHA: + return ATC_RGBA_EXPLICIT_ALPHA_AMD; + case PF_ATC_RGBA_INTERPOLATED_ALPHA: + return ATC_RGBA_INTERPOLATED_ALPHA_AMD; +# endif #endif #if GL_EXT_texture_compression_dxt1 @@ -119,15 +119,15 @@ namespace Ogre { case PF_A8B8G8R8: return GL_RGBA; #else - case PF_X8R8G8B8: - case PF_A8R8G8B8: + case PF_X8R8G8B8: + case PF_A8R8G8B8: case PF_A8B8G8R8: case PF_B8G8R8A8: case PF_A2R10G10B10: return GL_BGRA; case PF_A4R4G4B4: case PF_X8B8G8R8: - case PF_R8G8B8A8: + case PF_R8G8B8A8: case PF_A2B10G10R10: return GL_RGBA; #endif @@ -151,7 +151,7 @@ namespace Ogre { case PF_B5G6R5: return GL_UNSIGNED_SHORT_5_6_5; case PF_A4R4G4B4: - return GL_UNSIGNED_SHORT_4_4_4_4; + return GL_UNSIGNED_SHORT_4_4_4_4; case PF_A1R5G5B5: return GL_UNSIGNED_SHORT_5_5_5_1; @@ -204,18 +204,18 @@ namespace Ogre { #endif #if OGRE_NO_ETC_CODEC == 0 -# ifdef GL_OES_compressed_ETC1_RGB8_texture +# ifdef GL_OES_compressed_ETC1_RGB8_texture case PF_ETC1_RGB8: return GL_ETC1_RGB8_OES; -# endif -# ifdef GL_AMD_compressed_ATC_texture - case PF_ATC_RGB: - return ATC_RGB_AMD; - case PF_ATC_RGBA_EXPLICIT_ALPHA: - return ATC_RGBA_EXPLICIT_ALPHA_AMD; - case PF_ATC_RGBA_INTERPOLATED_ALPHA: - return ATC_RGBA_INTERPOLATED_ALPHA_AMD; -# endif +# endif +# ifdef GL_AMD_compressed_ATC_texture + case PF_ATC_RGB: + return ATC_RGB_AMD; + case PF_ATC_RGBA_EXPLICIT_ALPHA: + return ATC_RGBA_EXPLICIT_ALPHA_AMD; + case PF_ATC_RGBA_INTERPOLATED_ALPHA: + return ATC_RGBA_INTERPOLATED_ALPHA_AMD; +# endif #endif #if GL_EXT_texture_compression_dxt1 @@ -236,8 +236,8 @@ namespace Ogre { case PF_R8G8B8: case PF_B8G8R8: return GL_RGB; - case PF_X8B8G8R8: - case PF_X8R8G8B8: + case PF_X8B8G8R8: + case PF_X8R8G8B8: case PF_A8R8G8B8: case PF_A8B8G8R8: case PF_B8G8R8A8: @@ -285,18 +285,18 @@ namespace Ogre { #endif #if OGRE_NO_ETC_CODEC == 0 -# ifdef GL_OES_compressed_ETC1_RGB8_texture +# ifdef GL_OES_compressed_ETC1_RGB8_texture case GL_ETC1_RGB8_OES: return PF_ETC1_RGB8; -# endif -# ifdef GL_AMD_compressed_ATC_texture - case ATC_RGB_AMD: - return PF_ATC_RGB; - case ATC_RGBA_EXPLICIT_ALPHA_AMD: - return PF_ATC_RGBA_EXPLICIT_ALPHA; - case ATC_RGBA_INTERPOLATED_ALPHA_AMD: - return PF_ATC_RGBA_INTERPOLATED_ALPHA; -# endif +# endif +# ifdef GL_AMD_compressed_ATC_texture + case ATC_RGB_AMD: + return PF_ATC_RGB; + case ATC_RGBA_EXPLICIT_ALPHA_AMD: + return PF_ATC_RGBA_EXPLICIT_ALPHA; + case ATC_RGBA_INTERPOLATED_ALPHA_AMD: + return PF_ATC_RGBA_INTERPOLATED_ALPHA; +# endif #endif #if GL_EXT_texture_compression_dxt1 @@ -353,13 +353,13 @@ namespace Ogre { size_t GLESPixelUtil::getMaxMipmaps(size_t width, size_t height, size_t depth, PixelFormat format) { - size_t count = 0; + size_t count = 0; if((width > 0) && (height > 0) && (depth > 0)) { do { - if(width>1) width = width/2; - if(height>1) height = height/2; - if(depth>1) depth = depth/2; + if(width>1) width = width/2; + if(height>1) height = height/2; + if(depth>1) depth = depth/2; /* NOT needed, compressed formats will have mipmaps up to 1x1 if(PixelUtil::isValidExtent(width, height, depth, format)) @@ -370,8 +370,8 @@ namespace Ogre { count ++; } while(!(width == 1 && height == 1 && depth == 1)); - } - return count; + } + return count; } size_t GLESPixelUtil::optionalPO2(size_t value) @@ -398,9 +398,9 @@ namespace Ogre { // Convert PF_A4R4G4B4 -> PF_B4G4R4A4 // Reverse pixel order uint16 *srcptr = static_cast(src.data) - + (src.left + src.top * src.rowPitch + src.front * src.slicePitch); + + (src.left + src.top * src.rowPitch + src.front * src.slicePitch); uint16 *dstptr = static_cast(dst.data) - + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch); + + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch); const size_t srcSliceSkip = src.getSliceSkip(); const size_t dstSliceSkip = dst.getSliceSkip(); const size_t k = src.right - src.left; diff --git a/RenderSystems/GLES/src/OgreGLESRenderSystem.cpp b/RenderSystems/GLES/src/OgreGLESRenderSystem.cpp index 94fbe80377a..b0e07be2f31 100644 --- a/RenderSystems/GLES/src/OgreGLESRenderSystem.cpp +++ b/RenderSystems/GLES/src/OgreGLESRenderSystem.cpp @@ -45,14 +45,14 @@ THE SOFTWARE. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS # include "OgreEAGLWindow.h" #elif OGRE_PLATFORM == OGRE_PLATFORM_ANDROID -# include "OgreAndroidEGLWindow.h" -# include "OgreAndroidEGLContext.h" +# include "OgreAndroidEGLWindow.h" +# include "OgreAndroidEGLContext.h" # include "OgreAndroidResourceManager.h" Ogre::AndroidResourceManager* Ogre::GLESRenderSystem::mResourceManager = NULL; #else # include "OgreEGLWindow.h" -# ifndef GL_GLEXT_PROTOTYPES +# ifndef GL_GLEXT_PROTOTYPES // Function pointers for FBO extension PFNGLISRENDERBUFFEROESPROC glIsRenderbufferOES; PFNGLBINDRENDERBUFFEROESPROC glBindRenderbufferOES; @@ -69,12 +69,12 @@ Ogre::AndroidResourceManager* Ogre::GLESRenderSystem::mResourceManager = NULL; PFNGLFRAMEBUFFERTEXTURE2DOESPROC glFramebufferTexture2DOES; PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC glGetFramebufferAttachmentParameterivOES; PFNGLGENERATEMIPMAPOESPROC glGenerateMipmapOES; - PFNGLBLENDEQUATIONOESPROC glBlendEquationOES; - PFNGLBLENDFUNCSEPARATEOESPROC glBlendFuncSeparateOES; - PFNGLBLENDEQUATIONSEPARATEOESPROC glBlendEquationSeparateOES; + PFNGLBLENDEQUATIONOESPROC glBlendEquationOES; + PFNGLBLENDFUNCSEPARATEOESPROC glBlendFuncSeparateOES; + PFNGLBLENDEQUATIONSEPARATEOESPROC glBlendEquationSeparateOES; PFNGLMAPBUFFEROESPROC glMapBufferOES; PFNGLUNMAPBUFFEROESPROC glUnmapBufferOES; -# endif +# endif #endif @@ -90,7 +90,7 @@ namespace Ogre { : mGpuProgramManager(0), mHardwareBufferManager(0), mRTTManager(0), - mCurTexMipCount(0) + mCurTexMipCount(0) { // Get function pointers on platforms that doesn't have prototypes #ifndef GL_GLEXT_PROTOTYPES @@ -109,14 +109,14 @@ namespace Ogre { ::glFramebufferTexture2DOES = (PFNGLFRAMEBUFFERTEXTURE2DOESPROC)eglGetProcAddress("glFramebufferTexture2DOES"); ::glGetFramebufferAttachmentParameterivOES = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC)eglGetProcAddress("glGetFramebufferAttachmentParameterivOES"); ::glGenerateMipmapOES = (PFNGLGENERATEMIPMAPOESPROC)eglGetProcAddress("glGenerateMipmapOES"); - ::glBlendEquationOES = (PFNGLBLENDEQUATIONOESPROC)eglGetProcAddress("glBlendEquationOES"); - ::glBlendFuncSeparateOES = (PFNGLBLENDFUNCSEPARATEOESPROC)eglGetProcAddress("glBlendFuncSeparateOES"); - ::glBlendEquationSeparateOES = (PFNGLBLENDEQUATIONSEPARATEOESPROC)eglGetProcAddress("glBlendEquationSeparateOES"); + ::glBlendEquationOES = (PFNGLBLENDEQUATIONOESPROC)eglGetProcAddress("glBlendEquationOES"); + ::glBlendFuncSeparateOES = (PFNGLBLENDFUNCSEPARATEOESPROC)eglGetProcAddress("glBlendFuncSeparateOES"); + ::glBlendEquationSeparateOES = (PFNGLBLENDEQUATIONSEPARATEOESPROC)eglGetProcAddress("glBlendEquationSeparateOES"); ::glMapBufferOES = (PFNGLMAPBUFFEROESPROC)eglGetProcAddress("glMapBufferOES"); ::glUnmapBufferOES = (PFNGLUNMAPBUFFEROESPROC)eglGetProcAddress("glUnmapBufferOES"); #endif GL_CHECK_ERROR; - LogManager::getSingleton().logMessage(getName() + " created."); + LogManager::getSingleton().logMessage(getName() + " created."); #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID mResourceManager = OGRE_NEW AndroidResourceManager(); @@ -154,7 +154,7 @@ namespace Ogre { { shutdown(); - // Destroy render windows + // Destroy render windows RenderTargetMap::iterator i; for (i = mRenderTargets.begin(); i != mRenderTargets.end(); ++i) { @@ -167,10 +167,10 @@ namespace Ogre { #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID if (mResourceManager != NULL) - { - OGRE_DELETE mResourceManager; - mResourceManager = NULL; - } + { + OGRE_DELETE mResourceManager; + mResourceManager = NULL; + } #endif } @@ -192,17 +192,17 @@ namespace Ogre { String GLESRenderSystem::validateConfigOptions(void) { - // XXX Return an error string if something is invalid + // XXX Return an error string if something is invalid return mGLSupport->validateConfig(); } RenderWindow* GLESRenderSystem::_initialise(bool autoCreateWindow, const String& windowTitle) { - mGLSupport->start(); + mGLSupport->start(); // Create the texture manager - mTextureManager = OGRE_NEW GLESTextureManager(*mGLSupport); + mTextureManager = OGRE_NEW GLESTextureManager(*mGLSupport); RenderWindow *autoWindow = mGLSupport->createWindow(autoCreateWindow, this, windowTitle); @@ -218,7 +218,7 @@ namespace Ogre { rsc->setDriverVersion(mDriverVersion); const char* deviceName = (const char*)glGetString(GL_RENDERER); - const char* vendorName = (const char*)glGetString(GL_VENDOR); + const char* vendorName = (const char*)glGetString(GL_VENDOR); if (deviceName) { rsc->setDeviceName(deviceName); @@ -226,15 +226,15 @@ namespace Ogre { rsc->setRenderSystemName(getName()); - // Determine vendor - if (strstr(vendorName, "Imagination Technologies")) - rsc->setVendor(GPU_IMAGINATION_TECHNOLOGIES); - else if (strstr(vendorName, "Apple Computer, Inc.")) - rsc->setVendor(GPU_APPLE); // iOS Simulator - else if (strstr(vendorName, "NVIDIA")) - rsc->setVendor(GPU_NVIDIA); - else if (strstr(vendorName, "Nokia")) - rsc->setVendor(GPU_NOKIA); + // Determine vendor + if (strstr(vendorName, "Imagination Technologies")) + rsc->setVendor(GPU_IMAGINATION_TECHNOLOGIES); + else if (strstr(vendorName, "Apple Computer, Inc.")) + rsc->setVendor(GPU_APPLE); // iOS Simulator + else if (strstr(vendorName, "NVIDIA")) + rsc->setVendor(GPU_NVIDIA); + else if (strstr(vendorName, "Nokia")) + rsc->setVendor(GPU_NOKIA); else rsc->setVendor(GPU_UNKNOWN); @@ -276,19 +276,19 @@ namespace Ogre { mGLSupport->checkExtension("GL_OES_compressed_paletted_texture")) { rsc->setCapability(RSC_TEXTURE_COMPRESSION); - + if(mGLSupport->checkExtension("GL_IMG_texture_compression_pvrtc") || mGLSupport->checkExtension("GL_IMG_texture_compression_pvrtc2")) rsc->setCapability(RSC_TEXTURE_COMPRESSION_PVRTC); - + if(mGLSupport->checkExtension("GL_EXT_texture_compression_dxt1") && mGLSupport->checkExtension("GL_EXT_texture_compression_s3tc")) rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT); if(mGLSupport->checkExtension("GL_OES_compressed_ETC1_RGB8_texture")) rsc->setCapability(RSC_TEXTURE_COMPRESSION_ETC1); - - if(mGLSupport->checkExtension("GL_AMD_compressed_ATC_texture")) + + if(mGLSupport->checkExtension("GL_AMD_compressed_ATC_texture")) rsc->setCapability(RSC_TEXTURE_COMPRESSION_ATC); } @@ -320,7 +320,7 @@ namespace Ogre { // if (mGLSupport->checkExtension("GL_IMG_user_clip_plane")) rsc->setCapability(RSC_USER_CLIP_PLANES); - rsc->setCapability(RSC_TEXTURE_1D); + rsc->setCapability(RSC_TEXTURE_1D); if (mGLSupport->checkExtension("GL_OES_texture3D")) rsc->setCapability(RSC_TEXTURE_3D); @@ -388,39 +388,39 @@ namespace Ogre { } // Check for framebuffer object extension - if(caps->hasCapability(RSC_FBO)) - { - if(caps->hasCapability(RSC_HWRENDER_TO_TEXTURE)) - { - // Create FBO manager - LogManager::getSingleton().logMessage("GL ES: Using GL_OES_framebuffer_object for rendering to textures (best)"); - mRTTManager = new GLESFBOManager(); - caps->setCapability(RSC_RTT_SEPARATE_DEPTHBUFFER); - } - } - else - { - // Check GLSupport for PBuffer support - if(caps->hasCapability(RSC_PBUFFER)) - { - if(caps->hasCapability(RSC_HWRENDER_TO_TEXTURE)) - { - // Use PBuffers - mRTTManager = new GLESPBRTTManager(mGLSupport, primary); - LogManager::getSingleton().logMessage("GL ES: Using PBuffers for rendering to textures"); - } - } + if(caps->hasCapability(RSC_FBO)) + { + if(caps->hasCapability(RSC_HWRENDER_TO_TEXTURE)) + { + // Create FBO manager + LogManager::getSingleton().logMessage("GL ES: Using GL_OES_framebuffer_object for rendering to textures (best)"); + mRTTManager = new GLESFBOManager(); + caps->setCapability(RSC_RTT_SEPARATE_DEPTHBUFFER); + } + } + else + { + // Check GLSupport for PBuffer support + if(caps->hasCapability(RSC_PBUFFER)) + { + if(caps->hasCapability(RSC_HWRENDER_TO_TEXTURE)) + { + // Use PBuffers + mRTTManager = new GLESPBRTTManager(mGLSupport, primary); + LogManager::getSingleton().logMessage("GL ES: Using PBuffers for rendering to textures"); + } + } - // Downgrade number of simultaneous targets - caps->setNumMultiRenderTargets(1); - } + // Downgrade number of simultaneous targets + caps->setNumMultiRenderTargets(1); + } - Log* defaultLog = LogManager::getSingleton().getDefaultLog(); - if (defaultLog) - { - caps->log(defaultLog); - } + Log* defaultLog = LogManager::getSingleton().getDefaultLog(); + if (defaultLog) + { + caps->log(defaultLog); + } GL_CHECK_ERROR; mGLInitialised = true; @@ -499,7 +499,7 @@ namespace Ogre { "GLESRenderSystem::_createRenderWindow"); } - // Log a message + // Log a message StringStream ss; ss << "GLESRenderSystem::_createRenderWindow \"" << name << "\", " << width << "x" << height << " "; @@ -520,7 +520,7 @@ namespace Ogre { LogManager::getSingleton().logMessage(ss.str()); } - // Create the window + // Create the window RenderWindow* win = mGLSupport->newWindow(name, width, height, fullScreen, miscParams); attachRenderTarget((Ogre::RenderTarget&) *win); @@ -538,11 +538,11 @@ namespace Ogre { mDriverVersion.release = StringConverter::parseInt(tokens[2]); } mDriverVersion.build = 0; - // Initialise GL after the first window has been created - // TODO: fire this from emulation options, and don't duplicate Real and Current capabilities + // Initialise GL after the first window has been created + // TODO: fire this from emulation options, and don't duplicate Real and Current capabilities mRealCapabilities = createRenderSystemCapabilities(); - // use real capabilities if custom capabilities are not available + // use real capabilities if custom capabilities are not available if (!mUseCustomCapabilities) mCurrentCapabilities = mRealCapabilities; @@ -550,76 +550,76 @@ namespace Ogre { initialiseFromRenderSystemCapabilities(mCurrentCapabilities, (RenderTarget *) win); - // Initialise the main context + // Initialise the main context _oneTimeContextInitialization(); if (mCurrentContext) mCurrentContext->setInitialized(); } if( win->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH ) - { - //Unlike D3D9, OGL doesn't allow sharing the main depth buffer, so keep them separate. - //Only Copy does, but Copy means only one depth buffer... - GLESDepthBuffer *depthBuffer = OGRE_NEW GLESDepthBuffer( DepthBuffer::POOL_DEFAULT, this, - mCurrentContext, 0, 0, - win->getWidth(), win->getHeight(), - win->getFSAA(), 0, true ); + { + //Unlike D3D9, OGL doesn't allow sharing the main depth buffer, so keep them separate. + //Only Copy does, but Copy means only one depth buffer... + GLESDepthBuffer *depthBuffer = OGRE_NEW GLESDepthBuffer( DepthBuffer::POOL_DEFAULT, this, + mCurrentContext, 0, 0, + win->getWidth(), win->getHeight(), + win->getFSAA(), 0, true ); - mDepthBufferPool[depthBuffer->getPoolId()].push_back( depthBuffer ); + mDepthBufferPool[depthBuffer->getPoolId()].push_back( depthBuffer ); - win->attachDepthBuffer( depthBuffer ); - } + win->attachDepthBuffer( depthBuffer ); + } return win; } - //--------------------------------------------------------------------- - DepthBuffer* GLESRenderSystem::_createDepthBufferFor( RenderTarget *renderTarget ) - { - GLESDepthBuffer *retVal = 0; + //--------------------------------------------------------------------- + DepthBuffer* GLESRenderSystem::_createDepthBufferFor( RenderTarget *renderTarget ) + { + GLESDepthBuffer *retVal = 0; - // Only FBO & pbuffer support different depth buffers, so everything - // else creates dummy (empty) containers - // retVal = mRTTManager->_createDepthBufferFor( renderTarget ); - GLESFrameBufferObject *fbo = 0; + // Only FBO & pbuffer support different depth buffers, so everything + // else creates dummy (empty) containers + // retVal = mRTTManager->_createDepthBufferFor( renderTarget ); + GLESFrameBufferObject *fbo = 0; renderTarget->getCustomAttribute("FBO", &fbo); - if( fbo ) - { - // Presence of an FBO means the manager is an FBO Manager, that's why it's safe to downcast - // Find best depth & stencil format suited for the RT's format - GLuint depthFormat, stencilFormat; - static_cast(mRTTManager)->getBestDepthStencil( fbo->getFormat(), - &depthFormat, &stencilFormat ); + if( fbo ) + { + // Presence of an FBO means the manager is an FBO Manager, that's why it's safe to downcast + // Find best depth & stencil format suited for the RT's format + GLuint depthFormat, stencilFormat; + static_cast(mRTTManager)->getBestDepthStencil( fbo->getFormat(), + &depthFormat, &stencilFormat ); - GLESRenderBuffer *depthBuffer = OGRE_NEW GLESRenderBuffer( depthFormat, fbo->getWidth(), - fbo->getHeight(), fbo->getFSAA() ); + GLESRenderBuffer *depthBuffer = OGRE_NEW GLESRenderBuffer( depthFormat, fbo->getWidth(), + fbo->getHeight(), fbo->getFSAA() ); - GLESRenderBuffer *stencilBuffer = depthBuffer; - if( + GLESRenderBuffer *stencilBuffer = depthBuffer; + if( // not supported on AMD emulation for now... #ifdef GL_DEPTH24_STENCIL8_OES depthFormat != GL_DEPTH24_STENCIL8_OES && #endif stencilFormat ) - { - stencilBuffer = OGRE_NEW GLESRenderBuffer( stencilFormat, fbo->getWidth(), - fbo->getHeight(), fbo->getFSAA() ); - } - - //No "custom-quality" multisample for now in GL - retVal = OGRE_NEW GLESDepthBuffer( 0, this, mCurrentContext, depthBuffer, stencilBuffer, - fbo->getWidth(), fbo->getHeight(), fbo->getFSAA(), 0, false ); - } - - return retVal; - } - //--------------------------------------------------------------------- - void GLESRenderSystem::_getDepthStencilFormatFor( GLenum internalColourFormat, GLenum *depthFormat, - GLenum *stencilFormat ) - { - mRTTManager->getBestDepthStencil( internalColourFormat, depthFormat, stencilFormat ); - } + { + stencilBuffer = OGRE_NEW GLESRenderBuffer( stencilFormat, fbo->getWidth(), + fbo->getHeight(), fbo->getFSAA() ); + } + + //No "custom-quality" multisample for now in GL + retVal = OGRE_NEW GLESDepthBuffer( 0, this, mCurrentContext, depthBuffer, stencilBuffer, + fbo->getWidth(), fbo->getHeight(), fbo->getFSAA(), 0, false ); + } + + return retVal; + } + //--------------------------------------------------------------------- + void GLESRenderSystem::_getDepthStencilFormatFor( GLenum internalColourFormat, GLenum *depthFormat, + GLenum *stencilFormat ) + { + mRTTManager->getBestDepthStencil( internalColourFormat, depthFormat, stencilFormat ); + } MultiRenderTarget* GLESRenderSystem::createMultiRenderTarget(const String & name) { @@ -630,7 +630,7 @@ namespace Ogre { void GLESRenderSystem::destroyRenderWindow(RenderWindow* pWin) { - // Find it to remove from list + // Find it to remove from list RenderTargetMap::iterator i = mRenderTargets.begin(); while (i != mRenderTargets.end()) @@ -780,7 +780,7 @@ namespace Ogre { makeGLMatrix(mat, m); if (mActiveRenderTarget->requiresTextureFlipping()) { - // Invert transformed y + // Invert transformed y mat[1] = -mat[1]; mat[5] = -mat[5]; mat[9] = -mat[9]; @@ -939,8 +939,8 @@ namespace Ogre { void GLESRenderSystem::_setPointSpritesEnabled(bool enabled) { - if (!getCapabilities()->hasCapability(RSC_POINT_SPRITES)) - return; + if (!getCapabilities()->hasCapability(RSC_POINT_SPRITES)) + return; GL_CHECK_ERROR; if (enabled) @@ -954,28 +954,28 @@ namespace Ogre { GL_CHECK_ERROR; } - // Set sprite texture coord generation - // Don't offer this as an option since D3D links it to sprite enabled - for (ushort i = 0; i < mFixedFunctionTextureUnits; ++i) - { - mStateCacheManager->activateGLTextureUnit(i); - glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, + // Set sprite texture coord generation + // Don't offer this as an option since D3D links it to sprite enabled + for (ushort i = 0; i < mFixedFunctionTextureUnits; ++i) + { + mStateCacheManager->activateGLTextureUnit(i); + glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, enabled ? GL_TRUE : GL_FALSE); - } - mStateCacheManager->activateGLTextureUnit(0); + } + mStateCacheManager->activateGLTextureUnit(0); } void GLESRenderSystem::_setTexture(size_t stage, bool enabled, const TexturePtr &texPtr) { - GLESTexturePtr tex = texPtr.staticCast(); + GLESTexturePtr tex = texPtr.staticCast(); if (!mStateCacheManager->activateGLTextureUnit(stage)) - return; + return; if (enabled) { #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - mCurTexMipCount = 0; + mCurTexMipCount = 0; #endif if (!tex.isNull()) { @@ -984,7 +984,7 @@ namespace Ogre { glEnable(tex->getGLESTextureTarget()); mStateCacheManager->bindGLTexture(tex->getGLESTextureTarget(), tex->getGLID()); #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - mCurTexMipCount = tex->getNumMipmaps(); + mCurTexMipCount = tex->getNumMipmaps(); #endif } else @@ -1118,7 +1118,7 @@ namespace Ogre { default: break; } - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } void GLESRenderSystem::_setTextureBlendMode(size_t stage, const LayerBlendModeEx& bm) @@ -1258,8 +1258,8 @@ namespace Ogre { cmd = 0; } - if (!mStateCacheManager->activateGLTextureUnit(stage)) - return; + if (!mStateCacheManager->activateGLTextureUnit(stage)) + return; glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); GL_CHECK_ERROR; @@ -1370,7 +1370,7 @@ namespace Ogre { if (bm.source2 == LBS_MANUAL) glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, cv2); - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } GLint GLESRenderSystem::getTextureAddressingMode(TextureUnitState::TextureAddressingMode tam) const @@ -1392,13 +1392,13 @@ namespace Ogre { void GLESRenderSystem::_setTextureAddressingMode(size_t stage, const TextureUnitState::UVWAddressingMode& uvw) { - if (!mStateCacheManager->activateGLTextureUnit(stage)) - return; + if (!mStateCacheManager->activateGLTextureUnit(stage)) + return; mStateCacheManager->setTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getTextureAddressingMode(uvw.u)); mStateCacheManager->setTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getTextureAddressingMode(uvw.v)); - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } void GLESRenderSystem::_setTextureBorderColour(size_t stage, const ColourValue& colour) @@ -1410,7 +1410,7 @@ namespace Ogre { { if (mCurrentCapabilities->hasCapability(RSC_MIPMAP_LOD_BIAS)) { -#if GL_EXT_texture_lod_bias // This extension only seems to be supported on iOS OS, block it out to fix Linux build +#if GL_EXT_texture_lod_bias // This extension only seems to be supported on iOS OS, block it out to fix Linux build if (mStateCacheManager->activateGLTextureUnit(unit)) { glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias); @@ -1428,8 +1428,8 @@ namespace Ogre { return; } - if (!mStateCacheManager->activateGLTextureUnit(stage)) - return; + if (!mStateCacheManager->activateGLTextureUnit(stage)) + return; GLfloat mat[16]; makeGLMatrix(mat, xform); @@ -1449,7 +1449,7 @@ namespace Ogre { glMatrixMode(GL_MODELVIEW); GL_CHECK_ERROR; - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } GLint GLESRenderSystem::getBlendMode(SceneBlendFactor ogreBlend) const @@ -1482,60 +1482,60 @@ namespace Ogre { return GL_ONE; } - void GLESRenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op) - { + void GLESRenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op) + { GL_CHECK_ERROR; - GLenum sourceBlend = getBlendMode(sourceFactor); - GLenum destBlend = getBlendMode(destFactor); - if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO) - { - mStateCacheManager->setDisabled(GL_BLEND); - } - else - { - // SBF_SOURCE_COLOUR - not allowed for source - http://www.khronos.org/opengles/sdk/1.1/docs/man/ - if(sourceFactor == SBF_SOURCE_COLOUR) - { - sourceBlend = getBlendMode(SBF_SOURCE_ALPHA); - } + GLenum sourceBlend = getBlendMode(sourceFactor); + GLenum destBlend = getBlendMode(destFactor); + if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO) + { + mStateCacheManager->setDisabled(GL_BLEND); + } + else + { + // SBF_SOURCE_COLOUR - not allowed for source - http://www.khronos.org/opengles/sdk/1.1/docs/man/ + if(sourceFactor == SBF_SOURCE_COLOUR) + { + sourceBlend = getBlendMode(SBF_SOURCE_ALPHA); + } mStateCacheManager->setEnabled(GL_BLEND); mStateCacheManager->setBlendFunc(sourceBlend, destBlend); - } + } #if GL_OES_blend_subtract GLint func = GL_FUNC_ADD_OES; - switch(op) - { - case SBO_ADD: - func = GL_FUNC_ADD_OES; - break; - case SBO_SUBTRACT: - func = GL_FUNC_SUBTRACT_OES; - break; - case SBO_REVERSE_SUBTRACT: - func = GL_FUNC_REVERSE_SUBTRACT_OES; - break; - case SBO_MIN: + switch(op) + { + case SBO_ADD: + func = GL_FUNC_ADD_OES; + break; + case SBO_SUBTRACT: + func = GL_FUNC_SUBTRACT_OES; + break; + case SBO_REVERSE_SUBTRACT: + func = GL_FUNC_REVERSE_SUBTRACT_OES; + break; + case SBO_MIN: #if GL_EXT_blend_minmax func = GL_MIN_EXT; #endif break; - case SBO_MAX: + case SBO_MAX: #if GL_EXT_blend_minmax func = GL_MAX_EXT; #endif - break; - } + break; + } mStateCacheManager->setBlendEquation(func); #endif - } + } - void GLESRenderSystem::_setSeparateSceneBlending( + void GLESRenderSystem::_setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ) - { + { // Kinda hacky way to prevent this from compiling if the extensions aren't available #if defined(GL_OES_blend_func_separate) && defined(GL_OES_blend_equation_separate) && defined(GL_EXT_blend_minmax) if (mGLSupport->checkExtension("GL_OES_blend_equation_separate") && @@ -1603,45 +1603,45 @@ namespace Ogre { GL_CHECK_ERROR; } #endif - } + } void GLESRenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage) { - bool a2c = false; - static bool lasta2c = false; - if (func == CMPF_ALWAYS_PASS) - { + bool a2c = false; + static bool lasta2c = false; + if (func == CMPF_ALWAYS_PASS) + { mStateCacheManager->setDisabled(GL_ALPHA_TEST); - } - else - { + } + else + { mStateCacheManager->setEnabled(GL_ALPHA_TEST); - a2c = alphaToCoverage; + a2c = alphaToCoverage; - glAlphaFunc(convertCompareFunction(func), value / 255.0f); - GL_CHECK_ERROR; - } - if (a2c != lasta2c && getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE)) - { - if (a2c) + glAlphaFunc(convertCompareFunction(func), value / 255.0f); + GL_CHECK_ERROR; + } + if (a2c != lasta2c && getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE)) + { + if (a2c) mStateCacheManager->setEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE); - else + else mStateCacheManager->setDisabled(GL_SAMPLE_ALPHA_TO_COVERAGE); - lasta2c = a2c; - } - } + lasta2c = a2c; + } + } void GLESRenderSystem::_setViewport(Viewport *vp) { - // Check if viewport is different - if (!vp) - { - mActiveViewport = NULL; - _setRenderTarget(NULL); - } - else if (vp != mActiveViewport || vp->_isUpdated()) + // Check if viewport is different + if (!vp) + { + mActiveViewport = NULL; + _setRenderTarget(NULL); + } + else if (vp != mActiveViewport || vp->_isUpdated()) { RenderTarget* target; @@ -1651,7 +1651,7 @@ namespace Ogre { GLsizei x, y, w, h; - // Calculate the "lower-left" corner of the viewport + // Calculate the "lower-left" corner of the viewport w = vp->getActualWidth(); h = vp->getActualHeight(); x = vp->getActualLeft(); @@ -1674,20 +1674,20 @@ namespace Ogre { if (pos != String::npos) { - // Convert x,y since glViewport is expecting the x,y to be lower-left of the portrait orientation - if (val.find("Left") != String::npos) - { - GLsizei temp = x; - x = y; - y = target->getWidth() - w - temp; - } - else - { - GLsizei temp = x; - x = target->getHeight() - h - y; - y = temp; - } - + // Convert x,y since glViewport is expecting the x,y to be lower-left of the portrait orientation + if (val.find("Left") != String::npos) + { + GLsizei temp = x; + x = y; + y = target->getWidth() - w - temp; + } + else + { + GLsizei temp = x; + x = target->getHeight() - h - y; + y = temp; + } + GLsizei temp = h; h = w; w = temp; @@ -1697,7 +1697,7 @@ namespace Ogre { glViewport(x, y, w, h); GL_CHECK_ERROR; - // Configure the viewport clipping + // Configure the viewport clipping glScissor(x, y, w, h); GL_CHECK_ERROR; @@ -1861,7 +1861,7 @@ namespace Ogre { Matrix4& dest, bool forGpuProgram) { - // no any conversion request for OpenGL + // no any conversion request for OpenGL dest = matrix; } @@ -1872,13 +1872,13 @@ namespace Ogre { Radian thetaY(fovy / 2.0f); Real tanThetaY = Math::Tan(thetaY); - // Calc matrix elements + // Calc matrix elements Real w = (1.0f / tanThetaY) / aspect; Real h = 1.0f / tanThetaY; Real q, qn; if (farPlane == 0) { - // Infinite far plane + // Infinite far plane q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1; qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2); } @@ -1888,12 +1888,12 @@ namespace Ogre { qn = -2 * (farPlane * nearPlane) / (farPlane - nearPlane); } - // NB This creates Z in range [-1,1] - // - // [ w 0 0 0 ] - // [ 0 h 0 0 ] - // [ 0 0 q qn ] - // [ 0 0 -1 0 ] + // NB This creates Z in range [-1,1] + // + // [ w 0 0 0 ] + // [ 0 h 0 0 ] + // [ 0 0 q qn ] + // [ 0 0 -1 0 ] dest = Matrix4::ZERO; dest[0][0] = w; @@ -1913,7 +1913,7 @@ namespace Ogre { Real q, qn; if (farPlane == 0) { - // Infinite far plane + // Infinite far plane q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1; qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2); } @@ -1967,12 +1967,12 @@ namespace Ogre { const Plane& plane, bool forGpuProgram) { - // Thanks to Eric Lenyel for posting this calculation at www.terathon.com + // Thanks to Eric Lenyel for posting this calculation at www.terathon.com - // Calculate the clip-space corner point opposite the clipping plane - // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and - // transform it into camera space by multiplying it - // by the inverse of the projection matrix + // Calculate the clip-space corner point opposite the clipping plane + // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and + // transform it into camera space by multiplying it + // by the inverse of the projection matrix Vector4 q; q.x = (Math::Sign(plane.normal.x) + matrix[0][2]) / matrix[0][0]; @@ -2026,7 +2026,7 @@ namespace Ogre { StencilOperation depthFailOp, StencilOperation passOp, bool twoSidedOperation, - bool readBackAsTexture) + bool readBackAsTexture) { mStateCacheManager->setStencilMask(writeMask); glStencilFunc(convertCompareFunction(func), refValue, compareMask); @@ -2078,24 +2078,24 @@ namespace Ogre { return 0; } - void GLESRenderSystem::_setTextureUnitFiltering(size_t unit, FilterOptions minFilter, - FilterOptions magFilter, FilterOptions mipFilter) - { - mMipFilter = mipFilter; + void GLESRenderSystem::_setTextureUnitFiltering(size_t unit, FilterOptions minFilter, + FilterOptions magFilter, FilterOptions mipFilter) + { + mMipFilter = mipFilter; #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - if(mCurTexMipCount == 0 && mMipFilter != FO_NONE) - { - mMipFilter = FO_NONE; - } + if(mCurTexMipCount == 0 && mMipFilter != FO_NONE) + { + mMipFilter = FO_NONE; + } #endif - _setTextureUnitFiltering(unit, FT_MAG, magFilter); - _setTextureUnitFiltering(unit, FT_MIN, minFilter); - } - + _setTextureUnitFiltering(unit, FT_MAG, magFilter); + _setTextureUnitFiltering(unit, FT_MIN, minFilter); + } + void GLESRenderSystem::_setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions fo) { - if (!mStateCacheManager->activateGLTextureUnit(unit)) - return; + if (!mStateCacheManager->activateGLTextureUnit(unit)) + return; switch (ftype) { @@ -2130,34 +2130,34 @@ namespace Ogre { break; } - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } GLfloat GLESRenderSystem::_getCurrentAnisotropy(size_t unit) - { - GLfloat curAniso = 0; - glGetTexParameterfv(GL_TEXTURE_2D, + { + GLfloat curAniso = 0; + glGetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &curAniso); - return curAniso ? curAniso : 1; - } + return curAniso ? curAniso : 1; + } void GLESRenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) { - if (!mCurrentCapabilities->hasCapability(RSC_ANISOTROPY)) - return; + if (!mCurrentCapabilities->hasCapability(RSC_ANISOTROPY)) + return; - if (!mStateCacheManager->activateGLTextureUnit(unit)) - return; + if (!mStateCacheManager->activateGLTextureUnit(unit)) + return; - GLfloat largest_supported_anisotropy = 0; - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy); - if (maxAnisotropy > largest_supported_anisotropy) - maxAnisotropy = largest_supported_anisotropy ? - static_cast(largest_supported_anisotropy) : 1; - if (_getCurrentAnisotropy(unit) != maxAnisotropy) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); + GLfloat largest_supported_anisotropy = 0; + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest_supported_anisotropy); + if (maxAnisotropy > largest_supported_anisotropy) + maxAnisotropy = largest_supported_anisotropy ? + static_cast(largest_supported_anisotropy) : 1; + if (_getCurrentAnisotropy(unit) != maxAnisotropy) + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } void GLESRenderSystem::setVertexDeclaration(VertexDeclaration* decl) @@ -2175,7 +2175,7 @@ namespace Ogre { RenderSystem::_render(op); void* pBufferData = 0; - bool multitexturing = (getCapabilities()->getNumTextureUnits() > 1); + bool multitexturing = (getCapabilities()->getNumTextureUnits() > 1); const VertexDeclaration::VertexElementList& decl = op.vertexData->vertexDeclaration->getElements(); @@ -2271,7 +2271,7 @@ namespace Ogre { } } - if (multitexturing) + if (multitexturing) glClientActiveTexture(GL_TEXTURE0); GL_CHECK_ERROR; @@ -2354,8 +2354,8 @@ namespace Ogre { glDisableClientState(GL_VERTEX_ARRAY); GL_CHECK_ERROR; - // Only valid up to GL_MAX_TEXTURE_UNITS, which is recorded in mFixedFunctionTextureUnits - if (multitexturing) + // Only valid up to GL_MAX_TEXTURE_UNITS, which is recorded in mFixedFunctionTextureUnits + if (multitexturing) { for (int i = 0; i < mFixedFunctionTextureUnits; i++) { @@ -2430,7 +2430,7 @@ namespace Ogre { if (buffers & FBT_COLOUR) { flags |= GL_COLOR_BUFFER_BIT; - // Enable buffer for writing if it isn't + // Enable buffer for writing if it isn't if (colourMask) { mStateCacheManager->setColourMask(true, true, true, true); @@ -2440,7 +2440,7 @@ namespace Ogre { if (buffers & FBT_DEPTH) { flags |= GL_DEPTH_BUFFER_BIT; - // Enable buffer for writing if it isn't + // Enable buffer for writing if it isn't if (!mStateCacheManager->getDepthMask()) { mStateCacheManager->setDepthMask(GL_TRUE); @@ -2450,17 +2450,17 @@ namespace Ogre { if (buffers & FBT_STENCIL) { flags |= GL_STENCIL_BUFFER_BIT; - // Enable buffer for writing if it isn't + // Enable buffer for writing if it isn't mStateCacheManager->setStencilMask(0xFFFFFFFF); glClearStencil(stencil); GL_CHECK_ERROR; } - // Should be enable scissor test due the clear region is - // relied on scissor box bounds. + // Should be enable scissor test due the clear region is + // relied on scissor box bounds. mStateCacheManager->setEnabled(GL_SCISSOR_TEST); - // Sets the scissor box as same as viewport + // Sets the scissor box as same as viewport GLint viewport[4], scissor[4]; glGetIntegerv(GL_VIEWPORT, viewport); GL_CHECK_ERROR; @@ -2477,7 +2477,7 @@ namespace Ogre { mStateCacheManager->setDiscardBuffers(buffers); - // Clear buffers + // Clear buffers glClear(flags); GL_CHECK_ERROR; @@ -2516,25 +2516,25 @@ namespace Ogre { Real GLESRenderSystem::getHorizontalTexelOffset(void) { - // No offset in GL + // No offset in GL return 0.0; } Real GLESRenderSystem::getVerticalTexelOffset(void) { - // No offset in GL + // No offset in GL return 0.0; } Real GLESRenderSystem::getMinimumDepthInputValue(void) { - // Range [-1.0f, 1.0f] + // Range [-1.0f, 1.0f] return -1.0f; } Real GLESRenderSystem::getMaximumDepthInputValue(void) { - // Range [-1.0f, 1.0f] + // Range [-1.0f, 1.0f] return 1.0f; } @@ -2624,15 +2624,15 @@ namespace Ogre { void GLESRenderSystem::_switchContext(GLESContext *context) { // Disable lights - for (unsigned short i = 0; i < mCurrentLights; ++i) - { - setGLLight(i, NULL); - mLights[i] = NULL; - } - mCurrentLights = 0; + for (unsigned short i = 0; i < mCurrentLights; ++i) + { + setGLLight(i, NULL); + mLights[i] = NULL; + } + mCurrentLights = 0; - // Disable textures - _disableTextureUnitsFrom(0); + // Disable textures + _disableTextureUnitsFrom(0); // It's ready for switching if(mCurrentContext) @@ -2660,16 +2660,16 @@ namespace Ogre { { if (mCurrentContext == context) { - // Change the context to something else so that a valid context - // remains active. When this is the main context being unregistered, - // we set the main context to 0. + // Change the context to something else so that a valid context + // remains active. When this is the main context being unregistered, + // we set the main context to 0. if (mCurrentContext != mMainContext) { _switchContext(mMainContext); } else { - /// No contexts remain + /// No contexts remain mCurrentContext->endCurrent(); mCurrentContext = 0; mMainContext = 0; @@ -2697,16 +2697,16 @@ namespace Ogre { void GLESRenderSystem::initialiseContext(RenderWindow* primary) { - // Set main and current context + // Set main and current context mMainContext = 0; primary->getCustomAttribute("GLCONTEXT", &mMainContext); mCurrentContext = mMainContext; - // Set primary context as active + // Set primary context as active if (mCurrentContext) mCurrentContext->setCurrent(); - // Setup GLSupport + // Setup GLSupport mGLSupport->initialiseExtensions(); LogManager::getSingleton().logMessage("**************************************"); @@ -2721,30 +2721,30 @@ namespace Ogre { mRTTManager->unbind(mActiveRenderTarget); mActiveRenderTarget = target; - if (target) - { - // Switch context if different from current one - GLESContext *newContext = 0; - target->getCustomAttribute("GLCONTEXT", &newContext); - if (newContext && mCurrentContext != newContext) - { - _switchContext(newContext); - } - - // Check the FBO's depth buffer status - GLESDepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); - - if( target->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH && - (!depthBuffer || depthBuffer->getGLContext() != mCurrentContext ) ) - { - // Depth is automatically managed and there is no depth buffer attached to this RT - // or the Current context doesn't match the one this Depth buffer was created with - setDepthBufferFor( target ); - } - - // Bind frame buffer object - mRTTManager->bind(target); - } + if (target) + { + // Switch context if different from current one + GLESContext *newContext = 0; + target->getCustomAttribute("GLCONTEXT", &newContext); + if (newContext && mCurrentContext != newContext) + { + _switchContext(newContext); + } + + // Check the FBO's depth buffer status + GLESDepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); + + if( target->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH && + (!depthBuffer || depthBuffer->getGLContext() != mCurrentContext ) ) + { + // Depth is automatically managed and there is no depth buffer attached to this RT + // or the Current context doesn't match the one this Depth buffer was created with + setDepthBufferFor( target ); + } + + // Bind frame buffer object + mRTTManager->bind(target); + } } void GLESRenderSystem::makeGLMatrix(GLfloat gl_matrix[16], const Matrix4& m) @@ -2786,28 +2786,28 @@ namespace Ogre { return GL_ALWAYS; } - GLint GLESRenderSystem::convertStencilOp(StencilOperation op, bool invert) const - { - switch(op) - { - case SOP_KEEP: - return GL_KEEP; - case SOP_ZERO: - return GL_ZERO; - case SOP_REPLACE: - return GL_REPLACE; - case SOP_INCREMENT_WRAP: + GLint GLESRenderSystem::convertStencilOp(StencilOperation op, bool invert) const + { + switch(op) + { + case SOP_KEEP: + return GL_KEEP; + case SOP_ZERO: + return GL_ZERO; + case SOP_REPLACE: + return GL_REPLACE; + case SOP_INCREMENT_WRAP: case SOP_INCREMENT: - return invert ? GL_DECR : GL_INCR; - case SOP_DECREMENT_WRAP: - case SOP_DECREMENT: - return invert ? GL_INCR : GL_DECR; - case SOP_INVERT: - return GL_INVERT; - }; - // to keep compiler happy - return SOP_KEEP; - } + return invert ? GL_DECR : GL_INCR; + case SOP_DECREMENT_WRAP: + case SOP_DECREMENT: + return invert ? GL_INCR : GL_DECR; + case SOP_INVERT: + return GL_INVERT; + }; + // to keep compiler happy + return SOP_KEEP; + } void GLESRenderSystem::setLights() { @@ -2829,23 +2829,23 @@ namespace Ogre { vec = lt->getAs4DVector(); #if OGRE_DOUBLE_PRECISION - // Must convert to float* - float tmp[4] = {static_cast(vec.x), static_cast(vec.y), static_cast(vec.z), static_cast(vec.w)}; - glLightfv(lightindex, GL_POSITION, tmp); + // Must convert to float* + float tmp[4] = {static_cast(vec.x), static_cast(vec.y), static_cast(vec.z), static_cast(vec.w)}; + glLightfv(lightindex, GL_POSITION, tmp); #else - glLightfv(lightindex, GL_POSITION, vec.ptr()); + glLightfv(lightindex, GL_POSITION, vec.ptr()); #endif - // Set spotlight direction - if (lt->getType() == Light::LT_SPOTLIGHT) - { - vec = lt->getDerivedDirection(); - vec.w = 0.0; + // Set spotlight direction + if (lt->getType() == Light::LT_SPOTLIGHT) + { + vec = lt->getDerivedDirection(); + vec.w = 0.0; #if OGRE_DOUBLE_PRECISION - // Must convert to float* + // Must convert to float* float tmp2[4] = {static_cast(vec.x), static_cast(vec.y), static_cast(vec.z), static_cast(vec.w)}; - glLightfv(lightindex, GL_SPOT_DIRECTION, tmp2); + glLightfv(lightindex, GL_SPOT_DIRECTION, tmp2); #else - glLightfv(lightindex, GL_SPOT_DIRECTION, vec.ptr()); + glLightfv(lightindex, GL_SPOT_DIRECTION, vec.ptr()); #endif } } @@ -2936,12 +2936,12 @@ namespace Ogre { // Not implemented } - unsigned int GLESRenderSystem::getDisplayMonitorCount() const - { - return 1; - } + unsigned int GLESRenderSystem::getDisplayMonitorCount() const + { + return 1; + } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID void GLESRenderSystem::resetRenderer(RenderWindow* win) { @@ -2967,7 +2967,7 @@ namespace Ogre { GLESRenderSystem::mResourceManager->notifyOnContextReset(); - mStateCacheManager->clearCache(); + mStateCacheManager->clearCache(); _setViewport(NULL); _setRenderTarget(win); } diff --git a/RenderSystems/GLES/src/OgreGLESStateCacheManager.cpp b/RenderSystems/GLES/src/OgreGLESStateCacheManager.cpp index fa913215858..8563fef6561 100644 --- a/RenderSystems/GLES/src/OgreGLESStateCacheManager.cpp +++ b/RenderSystems/GLES/src/OgreGLESStateCacheManager.cpp @@ -81,9 +81,9 @@ namespace Ogre { } bool GLESStateCacheManager::activateGLTextureUnit(unsigned char unit) - { + { return mImp->activateGLTextureUnit(unit); - } + } void GLESStateCacheManager::setBlendFunc(GLenum source, GLenum dest) { diff --git a/RenderSystems/GLES/src/OgreGLESSupport.cpp b/RenderSystems/GLES/src/OgreGLESSupport.cpp index ea8b0790535..b753368a27c 100644 --- a/RenderSystems/GLES/src/OgreGLESSupport.cpp +++ b/RenderSystems/GLES/src/OgreGLESSupport.cpp @@ -89,45 +89,45 @@ namespace Ogre { while (ext >> str) { - LogManager::getSingleton().logMessage("EXT:" + str); + LogManager::getSingleton().logMessage("EXT:" + str); extensionList.insert(str); } - // Get function pointers on platforms that doesn't have prototypes + // Get function pointers on platforms that doesn't have prototypes #ifndef GL_GLEXT_PROTOTYPES - // define the GL types if they are not defined -# ifndef PFNGLISRENDERBUFFEROES - - // GL_OES_Framebuffer_object - - typedef GLboolean (GL_APIENTRY *PFNGLISRENDERBUFFEROES)(GLuint renderbuffer); - typedef void (GL_APIENTRY *PFNGLBINDRENDERBUFFEROES)(GLenum target, GLuint renderbuffer); - typedef void (GL_APIENTRY *PFNGLDELETERENDERBUFFERSOES)(GLsizei n, const GLuint *renderbuffers); - typedef void (GL_APIENTRY *PFNGLGENRENDERBUFFERSOES)(GLsizei n, GLuint *renderbuffers); - typedef void (GL_APIENTRY *PFNGLRENDERBUFFERSTORAGEOES)(GLenum target, GLenum internalformat,GLsizei width, GLsizei height); - typedef void (GL_APIENTRY *PFNGLGETRENDERBUFFERPARAMETERIVOES)(GLenum target, GLenum pname, GLint* params); - typedef GLboolean (GL_APIENTRY *PFNGLISFRAMEBUFFEROES)(GLuint framebuffer); - typedef void (GL_APIENTRY *PFNGLBINDFRAMEBUFFEROES)(GLenum target, GLuint framebuffer); - typedef void (GL_APIENTRY *PFNGLDELETEFRAMEBUFFERSOES)(GLsizei n, const GLuint *framebuffers); - typedef void (GL_APIENTRY *PFNGLGENFRAMEBUFFERSOES)(GLsizei n, GLuint *framebuffers); - typedef GLenum (GL_APIENTRY *PFNGLCHECKFRAMEBUFFERSTATUSOES)(GLenum target); - typedef void (GL_APIENTRY *PFNGLFRAMEBUFFERTEXTURE2DOES)(GLenum target, GLenum attachment,GLenum textarget, GLuint texture,GLint level); - typedef void (GL_APIENTRY *PFNGLFRAMEBUFFERRENDERBUFFEROES)(GLenum target, GLenum attachment,GLenum renderbuffertarget, GLuint renderbuffer); - typedef void (GL_APIENTRY *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOES)(GLenum target, GLenum attachment,GLenum pname, GLint *params); - typedef void (GL_APIENTRY *PFNGLGENERATEMIPMAPOES)(GLenum target); - - typedef void (GL_APIENTRY *PFNGLBLENDEQUATIONOES)(GLenum mode); - typedef void (GL_APIENTRY *PFNGLBLENDFUNCSEPARATEOES)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); - typedef void (GL_APIENTRY *PFNGLBLENDEQUATIONSEPARATEOES)(GLenum modeRGB, GLenum modeAlpha); + // define the GL types if they are not defined +# ifndef PFNGLISRENDERBUFFEROES + + // GL_OES_Framebuffer_object + + typedef GLboolean (GL_APIENTRY *PFNGLISRENDERBUFFEROES)(GLuint renderbuffer); + typedef void (GL_APIENTRY *PFNGLBINDRENDERBUFFEROES)(GLenum target, GLuint renderbuffer); + typedef void (GL_APIENTRY *PFNGLDELETERENDERBUFFERSOES)(GLsizei n, const GLuint *renderbuffers); + typedef void (GL_APIENTRY *PFNGLGENRENDERBUFFERSOES)(GLsizei n, GLuint *renderbuffers); + typedef void (GL_APIENTRY *PFNGLRENDERBUFFERSTORAGEOES)(GLenum target, GLenum internalformat,GLsizei width, GLsizei height); + typedef void (GL_APIENTRY *PFNGLGETRENDERBUFFERPARAMETERIVOES)(GLenum target, GLenum pname, GLint* params); + typedef GLboolean (GL_APIENTRY *PFNGLISFRAMEBUFFEROES)(GLuint framebuffer); + typedef void (GL_APIENTRY *PFNGLBINDFRAMEBUFFEROES)(GLenum target, GLuint framebuffer); + typedef void (GL_APIENTRY *PFNGLDELETEFRAMEBUFFERSOES)(GLsizei n, const GLuint *framebuffers); + typedef void (GL_APIENTRY *PFNGLGENFRAMEBUFFERSOES)(GLsizei n, GLuint *framebuffers); + typedef GLenum (GL_APIENTRY *PFNGLCHECKFRAMEBUFFERSTATUSOES)(GLenum target); + typedef void (GL_APIENTRY *PFNGLFRAMEBUFFERTEXTURE2DOES)(GLenum target, GLenum attachment,GLenum textarget, GLuint texture,GLint level); + typedef void (GL_APIENTRY *PFNGLFRAMEBUFFERRENDERBUFFEROES)(GLenum target, GLenum attachment,GLenum renderbuffertarget, GLuint renderbuffer); + typedef void (GL_APIENTRY *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOES)(GLenum target, GLenum attachment,GLenum pname, GLint *params); + typedef void (GL_APIENTRY *PFNGLGENERATEMIPMAPOES)(GLenum target); + + typedef void (GL_APIENTRY *PFNGLBLENDEQUATIONOES)(GLenum mode); + typedef void (GL_APIENTRY *PFNGLBLENDFUNCSEPARATEOES)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + typedef void (GL_APIENTRY *PFNGLBLENDEQUATIONSEPARATEOES)(GLenum modeRGB, GLenum modeAlpha); typedef void* (GL_APIENTRY *PFNGLMAPBUFFEROES)(GLenum target, GLenum access); typedef GLboolean (GL_APIENTRY *PFNGLUNMAPBUFFEROES)(GLenum target); - // GL_OES_point_size_array - typedef void (GL_APIENTRY *PFNGLPOINTSIZEPOINTEROES)(GLenum type, GLsizei stride, const void *ptr ); -# endif + // GL_OES_point_size_array + typedef void (GL_APIENTRY *PFNGLPOINTSIZEPOINTEROES)(GLenum type, GLsizei stride, const void *ptr ); +# endif glIsRenderbufferOES = (PFNGLISRENDERBUFFEROES)getProcAddress("glIsRenderbufferOES"); glBindRenderbufferOES = (PFNGLBINDRENDERBUFFEROES)getProcAddress("glBindRenderbufferOES"); @@ -145,9 +145,9 @@ namespace Ogre { glGetFramebufferAttachmentParameterivOES = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOES)getProcAddress("glGetFramebufferAttachmentParameterivOES"); glGenerateMipmapOES = (PFNGLGENERATEMIPMAPOES)getProcAddress("glGenerateMipmapOES"); - glBlendEquationOES = (PFNGLBLENDEQUATIONOES)getProcAddress("glBlendEquationOES"); - glBlendFuncSeparateOES = (PFNGLBLENDFUNCSEPARATEOES)getProcAddress("glBlendFuncSeparateOES"); - glBlendEquationSeparateOES = (PFNGLBLENDEQUATIONSEPARATEOES)getProcAddress("glBlendEquationSeparateOES"); + glBlendEquationOES = (PFNGLBLENDEQUATIONOES)getProcAddress("glBlendEquationOES"); + glBlendFuncSeparateOES = (PFNGLBLENDFUNCSEPARATEOES)getProcAddress("glBlendFuncSeparateOES"); + glBlendEquationSeparateOES = (PFNGLBLENDEQUATIONSEPARATEOES)getProcAddress("glBlendEquationSeparateOES"); glMapBufferOES = (PFNGLMAPBUFFEROES)getProcAddress("glMapBufferOES"); glUnmapBufferOES = (PFNGLUNMAPBUFFEROES)getProcAddress("glUnmapBufferOES"); diff --git a/RenderSystems/GLES/src/OgreGLESTexture.cpp b/RenderSystems/GLES/src/OgreGLESTexture.cpp index 49d7d0c94dd..b6c91d3f660 100644 --- a/RenderSystems/GLES/src/OgreGLESTexture.cpp +++ b/RenderSystems/GLES/src/OgreGLESTexture.cpp @@ -105,10 +105,10 @@ namespace Ogre { mHeight = GLESPixelUtil::optionalPO2(mHeight); mDepth = GLESPixelUtil::optionalPO2(mDepth); - // Adjust format if required + // Adjust format if required mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage); - // Check requested number of mipmaps + // Check requested number of mipmaps size_t maxMips = GLESPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat); if(PixelUtil::isCompressed(mFormat) && (mNumMipmaps == 0)) @@ -118,11 +118,11 @@ namespace Ogre { if (mNumMipmaps > maxMips) mNumMipmaps = maxMips; - // Generate texture name + // Generate texture name glGenTextures(1, &mTextureID); GL_CHECK_ERROR; - // Set texture type + // Set texture type mGLSupport.getStateCacheManager()->bindGLTexture(getGLESTextureTarget(), mTextureID); // Set some misc default parameters, these can of course be changed later @@ -138,7 +138,7 @@ namespace Ogre { mGLSupport.getStateCacheManager()->setTexParameteri(getGLESTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - // If we can do automip generation and the user desires this, do so + // If we can do automip generation and the user desires this, do so mMipmapsHardwareGenerated = Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP) && !PixelUtil::isCompressed(mFormat); @@ -182,9 +182,9 @@ namespace Ogre { size = PixelUtil::getMemorySize(width, height, depth, mFormat); switch(mTextureType) - { - case TEX_TYPE_1D: - case TEX_TYPE_2D: + { + case TEX_TYPE_1D: + case TEX_TYPE_2D: glCompressedTexImage2D(GL_TEXTURE_2D, mip, internalformat, @@ -196,13 +196,13 @@ namespace Ogre { break; #ifdef GL_OES_texture_cube_map case TEX_TYPE_CUBE_MAP: - for(int face = 0; face < 6; face++) { - glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES + face, mip, internalformat, + for(int face = 0; face < 6; face++) { + glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES + face, mip, internalformat, width, height, 0, size, tmpdata); GL_CHECK_ERROR; - } - break; + } + break; #endif default: break; @@ -235,9 +235,9 @@ namespace Ogre { for(size_t mip = 0; mip <= mNumMipmaps; mip++) { switch(mTextureType) - { - case TEX_TYPE_1D: - case TEX_TYPE_2D: + { + case TEX_TYPE_1D: + case TEX_TYPE_2D: glTexImage2D(GL_TEXTURE_2D, mip, internalformat, @@ -248,13 +248,13 @@ namespace Ogre { GL_CHECK_ERROR; break; #ifdef GL_OES_texture_cube_map - case TEX_TYPE_CUBE_MAP: - for(int face = 0; face < 6; face++) { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES + face, mip, internalformat, + case TEX_TYPE_CUBE_MAP: + for(int face = 0; face < 6; face++) { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES + face, mip, internalformat, width, height, 0, format, datatype, 0); - } - break; + } + break; #endif default: break; @@ -275,7 +275,7 @@ namespace Ogre { // Creation / loading methods void GLESTexture::createInternalResourcesImpl(void) { - _createGLTexResource(); + _createGLTexResource(); _createSurfaceList(); @@ -323,11 +323,11 @@ namespace Ogre { } #endif - // If PVRTC and 0 custom mipmap disable auto mip generation and disable software mipmap creation + // If PVRTC and 0 custom mipmap disable auto mip generation and disable software mipmap creation PixelFormat imageFormat = (*loadedImages)[0].getFormat(); - if (imageFormat == PF_PVRTC_RGB2 || imageFormat == PF_PVRTC_RGBA2 || + if (imageFormat == PF_PVRTC_RGB2 || imageFormat == PF_PVRTC_RGBA2 || imageFormat == PF_PVRTC_RGB4 || imageFormat == PF_PVRTC_RGBA4) - { + { size_t imageMips = (*loadedImages)[0].getNumMipmaps(); if (imageMips == 0) { @@ -335,7 +335,7 @@ namespace Ogre { // Disable flag for auto mip generation mUsage &= ~TU_AUTOMIPMAP; } - } + } } #ifdef GL_OES_texture_cube_map else if (mTextureType == TEX_TYPE_CUBE_MAP) @@ -466,8 +466,8 @@ namespace Ogre { for (size_t face = 0; face < getNumFaces(); face++) { - size_t width = mWidth; - size_t height = mHeight; + size_t width = mWidth; + size_t height = mHeight; for (size_t mip = 0; mip <= getNumMipmaps(); mip++) { GLESHardwarePixelBuffer *buf = OGRE_NEW GLESTextureBuffer(mName, diff --git a/RenderSystems/GLES/src/OgreGLESTextureManager.cpp b/RenderSystems/GLES/src/OgreGLESTextureManager.cpp index fab700cb9c3..8daee881710 100644 --- a/RenderSystems/GLES/src/OgreGLESTextureManager.cpp +++ b/RenderSystems/GLES/src/OgreGLESTextureManager.cpp @@ -76,7 +76,7 @@ namespace Ogre { } } - GL_CHECK_ERROR; + GL_CHECK_ERROR; // Create GL resource glGenTextures(1, &mWarningTextureID); GL_CHECK_ERROR; @@ -98,9 +98,9 @@ namespace Ogre { // if a compressed format not supported, revert to PF_A8R8G8B8 if (PixelUtil::isCompressed(format) && !caps->hasCapability(RSC_TEXTURE_COMPRESSION_DXT) && - !caps->hasCapability(RSC_TEXTURE_COMPRESSION_PVRTC) && - !caps->hasCapability(RSC_TEXTURE_COMPRESSION_ATC) && - !caps->hasCapability(RSC_TEXTURE_COMPRESSION_ETC1)) + !caps->hasCapability(RSC_TEXTURE_COMPRESSION_PVRTC) && + !caps->hasCapability(RSC_TEXTURE_COMPRESSION_ATC) && + !caps->hasCapability(RSC_TEXTURE_COMPRESSION_ETC1)) { return PF_A8R8G8B8; } diff --git a/RenderSystems/GLES/src/StateCacheManager/OgreGLESNullStateCacheManagerImp.cpp b/RenderSystems/GLES/src/StateCacheManager/OgreGLESNullStateCacheManagerImp.cpp index 8a41fa0f524..8612a40c0b7 100644 --- a/RenderSystems/GLES/src/StateCacheManager/OgreGLESNullStateCacheManagerImp.cpp +++ b/RenderSystems/GLES/src/StateCacheManager/OgreGLESNullStateCacheManagerImp.cpp @@ -155,7 +155,7 @@ namespace Ogre { } bool GLESStateCacheManagerImp::activateGLTextureUnit(unsigned char unit) - { + { // Always return true for the currently bound texture unit if (mActiveTextureUnit == unit) return true; @@ -173,7 +173,7 @@ namespace Ogre { { return false; } - } + } void GLESStateCacheManagerImp::setBlendFunc(GLenum source, GLenum dest) { diff --git a/RenderSystems/GLES/src/StateCacheManager/OgreGLESNullStateCacheManagerImp.h b/RenderSystems/GLES/src/StateCacheManager/OgreGLESNullStateCacheManagerImp.h index b2afa8e0b5f..abfdab9e49d 100644 --- a/RenderSystems/GLES/src/StateCacheManager/OgreGLESNullStateCacheManagerImp.h +++ b/RenderSystems/GLES/src/StateCacheManager/OgreGLESNullStateCacheManagerImp.h @@ -73,7 +73,7 @@ namespace Ogre /// See GLESStateCacheManager.clearCache. void clearCache(); - + /// See GLESStateCacheManager.bindGLBuffer. void bindGLBuffer(GLenum target, GLuint buffer, GLenum attach = 0, bool force = false); diff --git a/RenderSystems/GLES/src/StateCacheManager/OgreGLESStateCacheManagerImp.cpp b/RenderSystems/GLES/src/StateCacheManager/OgreGLESStateCacheManagerImp.cpp index c93bf8bafeb..b59e8f5ff42 100644 --- a/RenderSystems/GLES/src/StateCacheManager/OgreGLESStateCacheManagerImp.cpp +++ b/RenderSystems/GLES/src/StateCacheManager/OgreGLESStateCacheManagerImp.cpp @@ -261,7 +261,7 @@ namespace Ogre { } bool GLESStateCacheManagerImp::activateGLTextureUnit(unsigned char unit) - { + { // Always return true for the currently bound texture unit if (mActiveTextureUnit == unit) return true; @@ -279,7 +279,7 @@ namespace Ogre { { return false; } - } + } #pragma mark Blending settings // TODO: Store as high/low bits of a GLuint diff --git a/RenderSystems/GLES/src/StateCacheManager/OgreGLESStateCacheManagerImp.h b/RenderSystems/GLES/src/StateCacheManager/OgreGLESStateCacheManagerImp.h index e9fa7f0cb4b..7eefb468ea2 100644 --- a/RenderSystems/GLES/src/StateCacheManager/OgreGLESStateCacheManagerImp.h +++ b/RenderSystems/GLES/src/StateCacheManager/OgreGLESStateCacheManagerImp.h @@ -106,7 +106,7 @@ namespace Ogre /// See GLESStateCacheManager.clearCache. void clearCache(); - + /// See GLESStateCacheManager.bindGLBuffer. void bindGLBuffer(GLenum target, GLuint buffer, GLenum attach = 0, bool force = false); diff --git a/RenderSystems/GLES2/include/EAGL/OgreEAGL2Support.h b/RenderSystems/GLES2/include/EAGL/OgreEAGL2Support.h index bd3add858ea..8f4430de214 100644 --- a/RenderSystems/GLES2/include/EAGL/OgreEAGL2Support.h +++ b/RenderSystems/GLES2/include/EAGL/OgreEAGL2Support.h @@ -43,12 +43,12 @@ namespace Ogre { class EAGL2Window; class EAGLES2Context; - template void removeDuplicates(C& c) - { - std::sort(c.begin(), c.end()); - typename C::iterator p = std::unique(c.begin(), c.end()); - c.erase(p, c.end()); - } + template void removeDuplicates(C& c) + { + std::sort(c.begin(), c.end()); + typename C::iterator p = std::unique(c.begin(), c.end()); + c.erase(p, c.end()); + } class _OgrePrivate EAGL2Support : public GLES2Support { @@ -61,7 +61,7 @@ namespace Ogre { void addConfig(void); String validateConfig(void); virtual String getDisplayName(void); - CFDictionaryRef chooseGLConfig(const GLint *attribList, GLint *nElements); + CFDictionaryRef chooseGLConfig(const GLint *attribList, GLint *nElements); GLint getGLConfigAttrib(CFDictionaryRef fbConfig, GLint attribute, GLint *value); float getCurrentOSVersion(void) { return mCurrentOSVersion; } void * getProcAddress(const Ogre::String& name); @@ -82,10 +82,10 @@ namespace Ogre { CFDictionaryRef getGLConfigFromContext(EAGLES2Context context); CFDictionaryRef getGLConfigFromDrawable(CAEAGLLayer *drawable, unsigned int *w, unsigned int *h); #endif - CFDictionaryRef selectGLConfig(const int* minAttribs, const int *maxAttribs); + CFDictionaryRef selectGLConfig(const int* minAttribs, const int *maxAttribs); protected: float mCurrentOSVersion; - }; + }; } #endif diff --git a/RenderSystems/GLES2/include/EAGL/OgreEAGL2Window.h b/RenderSystems/GLES2/include/EAGL/OgreEAGL2Window.h index 53bb6ffb74e..5d7ae17404f 100644 --- a/RenderSystems/GLES2/include/EAGL/OgreEAGL2Window.h +++ b/RenderSystems/GLES2/include/EAGL/OgreEAGL2Window.h @@ -66,28 +66,28 @@ namespace Ogre { EAGL2Support* mGLSupport; EAGLES2Context* mContext; #ifdef __OBJC__ - NativeWindowType mWindow; + NativeWindowType mWindow; EAGL2View *mView; EAGL2ViewController *mViewController; #endif void switchFullScreen(bool fullscreen) { } - void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); - void initNativeCreatedWindow(const NameValuePairList *miscParams); - void createNativeWindow(int &left, int &top, uint &width, uint &height, String &title); - void reposition(int left, int top); - void resize(unsigned int width, unsigned int height); - void windowMovedOrResized(); + void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); + void initNativeCreatedWindow(const NameValuePairList *miscParams); + void createNativeWindow(int &left, int &top, uint &width, uint &height, String &title); + void reposition(int left, int top); + void resize(unsigned int width, unsigned int height); + void windowMovedOrResized(); virtual void _beginUpdate(); - public: + public: EAGL2Window(EAGL2Support* glsupport); virtual ~EAGL2Window(); void create(const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams); - virtual void setFullscreen(bool fullscreen, uint width, uint height); + virtual void setFullscreen(bool fullscreen, uint width, uint height); void destroy(void); bool isClosed(void) const { return mClosed; } bool isVisible(void) const { return mVisible; } diff --git a/RenderSystems/GLES2/include/EGL/Android/OgreAndroidEGLSupport.h b/RenderSystems/GLES2/include/EGL/Android/OgreAndroidEGLSupport.h index 170075fd60c..a801afbcbe6 100644 --- a/RenderSystems/GLES2/include/EGL/Android/OgreAndroidEGLSupport.h +++ b/RenderSystems/GLES2/include/EGL/Android/OgreAndroidEGLSupport.h @@ -44,7 +44,7 @@ namespace Ogre { unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams = 0); - }; + }; } #endif diff --git a/RenderSystems/GLES2/include/EGL/Android/OgreAndroidEGLWindow.h b/RenderSystems/GLES2/include/EGL/Android/OgreAndroidEGLWindow.h index 121831c1d63..ece847fcbb2 100644 --- a/RenderSystems/GLES2/include/EGL/Android/OgreAndroidEGLWindow.h +++ b/RenderSystems/GLES2/include/EGL/Android/OgreAndroidEGLWindow.h @@ -44,33 +44,33 @@ THE SOFTWARE. namespace Ogre { class _OgrePrivate AndroidEGLWindow : public EGLWindow { - private: - uint mMaxBufferSize; - uint mMinBufferSize; - uint mMaxDepthSize; - uint mMaxStencilSize; - uint mMSAA; - uint mCSAA; - - protected: - virtual EGLContext * createEGLContext() const; - virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); - virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); - virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); - virtual void reposition(int left, int top); - virtual void resize(unsigned int width, unsigned int height); - virtual void windowMovedOrResized(); - virtual void switchFullScreen(bool fullscreen); + private: + uint mMaxBufferSize; + uint mMinBufferSize; + uint mMaxDepthSize; + uint mMaxStencilSize; + uint mMSAA; + uint mCSAA; + + protected: + virtual EGLContext * createEGLContext() const; + virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); + virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); + virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); + virtual void reposition(int left, int top); + virtual void resize(unsigned int width, unsigned int height); + virtual void windowMovedOrResized(); + virtual void switchFullScreen(bool fullscreen); public: - AndroidEGLWindow(AndroidEGLSupport* glsupport); - virtual ~AndroidEGLWindow(); + AndroidEGLWindow(AndroidEGLSupport* glsupport); + virtual ~AndroidEGLWindow(); void create(const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams); void _destroyInternalResources(); void _createInternalResources(NativeWindowType window, AConfiguration* config); - }; + }; } #endif diff --git a/RenderSystems/GLES2/include/EGL/Android/OgreAndroidResource.h b/RenderSystems/GLES2/include/EGL/Android/OgreAndroidResource.h index 41209f7937b..1dadc797767 100644 --- a/RenderSystems/GLES2/include/EGL/Android/OgreAndroidResource.h +++ b/RenderSystems/GLES2/include/EGL/Android/OgreAndroidResource.h @@ -34,25 +34,25 @@ namespace Ogre { class AndroidEGLContext; - /** Represents a Android rendering resource. - Provide unified interface to - handle various device states. - */ - class _OgrePrivate AndroidResource - { - - // Interface. - public: - - // Called immediately after the Android context has entered a lost state. - virtual void notifyOnContextLost() {} - - // Called immediately after the Android context has been reset. - virtual void notifyOnContextReset() {} - - public: - AndroidResource(); - virtual ~AndroidResource(); - }; + /** Represents a Android rendering resource. + Provide unified interface to + handle various device states. + */ + class _OgrePrivate AndroidResource + { + + // Interface. + public: + + // Called immediately after the Android context has entered a lost state. + virtual void notifyOnContextLost() {} + + // Called immediately after the Android context has been reset. + virtual void notifyOnContextReset() {} + + public: + AndroidResource(); + virtual ~AndroidResource(); + }; } #endif diff --git a/RenderSystems/GLES2/include/EGL/Android/OgreAndroidResourceManager.h b/RenderSystems/GLES2/include/EGL/Android/OgreAndroidResourceManager.h index 3d814c52d2b..4d1e26553ae 100644 --- a/RenderSystems/GLES2/include/EGL/Android/OgreAndroidResourceManager.h +++ b/RenderSystems/GLES2/include/EGL/Android/OgreAndroidResourceManager.h @@ -31,45 +31,45 @@ THE SOFTWARE. #include "OgreGLES2Prerequisites.h" namespace Ogre { - class AndroidEGLContext; + class AndroidEGLContext; class AndroidResource; - class _OgrePrivate AndroidResourceManager : public ResourceAlloc - { - // Interface. - public: + class _OgrePrivate AndroidResourceManager : public ResourceAlloc + { + // Interface. + public: - // Called immediately after the Android context has entered a lost state. + // Called immediately after the Android context has entered a lost state. void notifyOnContextLost(); - // Called immediately after the Android context has been reset. + // Called immediately after the Android context has been reset. void notifyOnContextReset(); - - AndroidResourceManager(); - ~AndroidResourceManager(); + + AndroidResourceManager(); + ~AndroidResourceManager(); - // Friends. - protected: - friend class AndroidResource; - - // Types. - protected: - typedef vector::type ResourceContainer; - typedef ResourceContainer::iterator ResourceContainerIterator; + // Friends. + protected: + friend class AndroidResource; + + // Types. + protected: + typedef vector::type ResourceContainer; + typedef ResourceContainer::iterator ResourceContainerIterator; - // Protected methods. - protected: - - // Called when new resource created. - void _notifyResourceCreated (AndroidResource* pResource); + // Protected methods. + protected: + + // Called when new resource created. + void _notifyResourceCreated (AndroidResource* pResource); - // Called when resource is about to be destroyed. - void _notifyResourceDestroyed (AndroidResource* pResource); - - // Attributes. - protected: - ResourceContainer mResources; - }; + // Called when resource is about to be destroyed. + void _notifyResourceDestroyed (AndroidResource* pResource); + + // Attributes. + protected: + ResourceContainer mResources; + }; } #endif diff --git a/RenderSystems/GLES2/include/EGL/OgreEGLContext.h b/RenderSystems/GLES2/include/EGL/OgreEGLContext.h index 0520235be8b..15225014d51 100644 --- a/RenderSystems/GLES2/include/EGL/OgreEGLContext.h +++ b/RenderSystems/GLES2/include/EGL/OgreEGLContext.h @@ -57,7 +57,7 @@ namespace Ogre { virtual void endCurrent(); virtual GLES2Context* clone() const = 0; - EGLSurface getDrawable() const; + EGLSurface getDrawable() const; }; } diff --git a/RenderSystems/GLES2/include/EGL/OgreEGLRenderTexture.h b/RenderSystems/GLES2/include/EGL/OgreEGLRenderTexture.h index 77d3689ea94..fe15cf6e9a0 100644 --- a/RenderSystems/GLES2/include/EGL/OgreEGLRenderTexture.h +++ b/RenderSystems/GLES2/include/EGL/OgreEGLRenderTexture.h @@ -45,11 +45,11 @@ namespace Ogre { protected: EGLSupport* mGLSupport; - ::EGLDisplay mGlDisplay; - ::EGLSurface mEglDrawable; + ::EGLDisplay mGlDisplay; + ::EGLSurface mEglDrawable; public: EGLPBuffer(EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height); - void initEGLPBuffer(); + void initEGLPBuffer(); virtual ~EGLPBuffer(); }; diff --git a/RenderSystems/GLES2/include/EGL/OgreEGLSupport.h b/RenderSystems/GLES2/include/EGL/OgreEGLSupport.h index 6e0e813cd6c..af1a3a30f0b 100644 --- a/RenderSystems/GLES2/include/EGL/OgreEGLSupport.h +++ b/RenderSystems/GLES2/include/EGL/OgreEGLSupport.h @@ -37,12 +37,12 @@ THE SOFTWARE. #include "OgreEGLWindow.h" namespace Ogre { - template void removeDuplicates(C& c) - { - std::sort(c.begin(), c.end()); - typename C::iterator p = std::unique(c.begin(), c.end()); - c.erase(p, c.end()); - } + template void removeDuplicates(C& c) + { + std::sort(c.begin(), c.end()); + typename C::iterator p = std::unique(c.begin(), c.end()); + c.erase(p, c.end()); + } class _OgrePrivate EGLSupport : public GLES2Support { @@ -50,9 +50,9 @@ namespace Ogre { void refreshConfig(void); EGLDisplay mGLDisplay; - NativeDisplayType mNativeDisplay; + NativeDisplayType mNativeDisplay; - bool mIsExternalDisplay; + bool mIsExternalDisplay; bool mRandr; typedef std::pair ScreenSize; typedef short Rate; @@ -63,7 +63,7 @@ namespace Ogre { VideoMode mCurrentMode; StringVector mSampleLevels; - //virtual EGLWindow* createEGLWindow( EGLSupport * support) = 0; + //virtual EGLWindow* createEGLWindow( EGLSupport * support) = 0; public: EGLSupport(); virtual ~EGLSupport(); @@ -74,10 +74,10 @@ namespace Ogre { String validateConfig(void); void setConfigOption(const String &name, const String &value); virtual String getDisplayName (void); - EGLDisplay getGLDisplay(void); - void setGLDisplay(EGLDisplay val); - EGLConfig* chooseGLConfig(const EGLint *attribList, EGLint *nElements); - EGLConfig* getConfigs(EGLint *nElements); + EGLDisplay getGLDisplay(void); + void setGLDisplay(EGLDisplay val); + EGLConfig* chooseGLConfig(const EGLint *attribList, EGLint *nElements); + EGLConfig* getConfigs(EGLint *nElements); EGLBoolean getGLConfigAttrib(EGLConfig fbConfig, EGLint attribute, EGLint *value); void* getProcAddress(const Ogre::String& name); ::EGLContext createNewContext(EGLDisplay eglDisplay, ::EGLConfig glconfig, ::EGLContext shareList) const; @@ -94,13 +94,13 @@ namespace Ogre { ::EGLConfig getGLConfigFromContext(::EGLContext context); ::EGLConfig getGLConfigFromDrawable(::EGLSurface drawable, unsigned int *w, unsigned int *h); - ::EGLConfig selectGLConfig (const EGLint* minAttribs, const EGLint *maxAttribs); + ::EGLConfig selectGLConfig (const EGLint* minAttribs, const EGLint *maxAttribs); void switchMode(void); - virtual void switchMode(uint& width, uint& height, short& frequency) = 0; + virtual void switchMode(uint& width, uint& height, short& frequency) = 0; // virtual GLES2PBuffer* createPBuffer(PixelComponentType format, // size_t width, size_t height) = 0; -// NativeDisplayType getNativeDisplay(); - }; +// NativeDisplayType getNativeDisplay(); + }; } #endif diff --git a/RenderSystems/GLES2/include/EGL/OgreEGLWindow.h b/RenderSystems/GLES2/include/EGL/OgreEGLWindow.h index ed369a5c744..d1cbadcfa1a 100644 --- a/RenderSystems/GLES2/include/EGL/OgreEGLWindow.h +++ b/RenderSystems/GLES2/include/EGL/OgreEGLWindow.h @@ -37,7 +37,7 @@ THE SOFTWARE. namespace Ogre { class _OgrePrivate EGLWindow : public RenderWindow { - private: + private: protected: bool mClosed; bool mVisible; @@ -47,34 +47,34 @@ namespace Ogre { EGLSupport* mGLSupport; EGLContext* mContext; - NativeWindowType mWindow; - NativeDisplayType mNativeDisplay; - ::EGLDisplay mEglDisplay; + NativeWindowType mWindow; + NativeDisplayType mNativeDisplay; + ::EGLDisplay mEglDisplay; - ::EGLConfig mEglConfig; - ::EGLSurface mEglSurface; + ::EGLConfig mEglConfig; + ::EGLSurface mEglSurface; ::EGLSurface createSurfaceFromWindow(::EGLDisplay display, NativeWindowType win); - virtual void switchFullScreen(bool fullscreen) = 0; - virtual EGLContext * createEGLContext() const = 0; - virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height) = 0; - virtual void initNativeCreatedWindow(const NameValuePairList *miscParams) = 0; - virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) = 0; - virtual void reposition(int left, int top) = 0; - virtual void resize(unsigned int width, unsigned int height) = 0; - virtual void windowMovedOrResized() = 0; + virtual void switchFullScreen(bool fullscreen) = 0; + virtual EGLContext * createEGLContext() const = 0; + virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height) = 0; + virtual void initNativeCreatedWindow(const NameValuePairList *miscParams) = 0; + virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) = 0; + virtual void reposition(int left, int top) = 0; + virtual void resize(unsigned int width, unsigned int height) = 0; + virtual void windowMovedOrResized() = 0; - public: + public: EGLWindow(EGLSupport* glsupport); virtual ~EGLWindow(); -// Moved create to native source because it has native calls in it. +// Moved create to native source because it has native calls in it. // void create(const String& name, unsigned int width, unsigned int height, // bool fullScreen, const NameValuePairList *miscParams); - virtual void setFullscreen (bool fullscreen, uint width, uint height); + virtual void setFullscreen (bool fullscreen, uint width, uint height); void destroy(void); bool isClosed(void) const; bool isVisible(void) const; diff --git a/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLRenderTexture.h b/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLRenderTexture.h index c13d4c31acc..69ac3c566e8 100644 --- a/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLRenderTexture.h +++ b/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLRenderTexture.h @@ -42,9 +42,9 @@ namespace Ogre class _OgrePrivate Win32EGLPBuffer : public EGLPBuffer { - protected: + protected: - public: + public: Win32EGLPBuffer(Win32EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height); virtual ~Win32EGLPBuffer(); }; diff --git a/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLSupport.h b/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLSupport.h index 6a1f3f49f51..1e76dad2419 100644 --- a/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLSupport.h +++ b/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLSupport.h @@ -36,32 +36,32 @@ THE SOFTWARE. namespace Ogre { class _OgrePrivate Win32EGLSupport : public EGLSupport { - protected: + protected: - //Removed createEGLWindow because it was easier to just call - //new Win32EGLWindow in the code to get the native version - //virtual EGLWindow* createEGLWindow( EGLSupport * support); + //Removed createEGLWindow because it was easier to just call + //new Win32EGLWindow in the code to get the native version + //virtual EGLWindow* createEGLWindow( EGLSupport * support); public: Win32EGLSupport(); virtual ~Win32EGLSupport(); - //virtual GLESPBuffer* createPBuffer(PixelComponentType format, - // size_t width, size_t height); - virtual void switchMode(uint& width, uint& height, short& frequency); + //virtual GLESPBuffer* createPBuffer(PixelComponentType format, + // size_t width, size_t height); + virtual void switchMode(uint& width, uint& height, short& frequency); RenderWindow* newWindow(const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams = 0); - //Moved getNativeDisplay to native class - NativeDisplayType getNativeDisplay(); + //Moved getNativeDisplay to native class + NativeDisplayType getNativeDisplay(); - //This sets up the native variables then calls EGLSupport::getGLDisplay - EGLDisplay getGLDisplay(); + //This sets up the native variables then calls EGLSupport::getGLDisplay + EGLDisplay getGLDisplay(); - }; + }; } #endif diff --git a/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLWindow.h b/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLWindow.h index 2e1e6334e64..13fc8b90083 100644 --- a/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLWindow.h +++ b/RenderSystems/GLES2/include/EGL/WIN32/OgreWin32EGLWindow.h @@ -36,19 +36,19 @@ THE SOFTWARE. namespace Ogre { class _OgrePrivate Win32EGLWindow : public EGLWindow { - protected: - virtual EGLContext * createEGLContext() const; - virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); - virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); - virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); - virtual void reposition(int left, int top); - virtual void resize(unsigned int width, unsigned int height); - virtual void windowMovedOrResized(); - virtual void switchFullScreen(bool fullscreen); + protected: + virtual EGLContext * createEGLContext() const; + virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); + virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); + virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); + virtual void reposition(int left, int top); + virtual void resize(unsigned int width, unsigned int height); + virtual void windowMovedOrResized(); + virtual void switchFullScreen(bool fullscreen); public: - Win32EGLWindow(Win32EGLSupport* glsupport); - virtual ~Win32EGLWindow(); + Win32EGLWindow(Win32EGLSupport* glsupport); + virtual ~Win32EGLWindow(); void create(const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams); diff --git a/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLRenderTexture.h b/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLRenderTexture.h index 0c57a2c548e..d5c11f74a9f 100644 --- a/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLRenderTexture.h +++ b/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLRenderTexture.h @@ -43,7 +43,7 @@ namespace Ogre class _OgrePrivate X11EGLPBuffer : public EGLPBuffer { - protected: + protected: public: X11EGLPBuffer(X11EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height); diff --git a/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLSupport.h b/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLSupport.h index 33edd91329d..d8e76b825f2 100644 --- a/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLSupport.h +++ b/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLSupport.h @@ -37,141 +37,141 @@ THE SOFTWARE. #ifndef Status #define Status int #endif - #include - #include -// #include - #include - #include + #include + #include +// #include + #include + #include #else - #define StructureNotifyMask 0 - #define VisibilityChangeMask 0 - #define FocusChangeMask 0 - #define CWBackPixel 0 - #define CWBorderPixel 0 - #define CWColormap 0 - #define CWEventMask 0 - #define NotUseful 0 - #define CWSaveUnder 0 - #define CWBackingStore 0 - #define CWOverrideRedirect 0 - #define InputOutput 0 - #define NormalState 0 - #define StateHint 0 - #define InputHint 0 - #define USPosition 0 - #define ClientMessage 0 - #define SubstructureRedirectMask 0 - #define SubstructureNotifyMask 0 - #define CurrentTime 0 - #define VisualIDMask 0 - #define AllocNone 0 - - enum X11Bool - { - False - , - True - }; - class NotPointerAtom{}; - typedef NotPointerAtom * Atom; - - class Display{}; - class XErrorEvent{}; - class XRRScreenConfiguration{}; - class Rotation{}; - class Visual{}; - #define Window NativeWindowType - - struct XVisualInfo{int visualid, visual, depth;}; - struct XRRScreenSize{int width, height;}; - struct XWMHints{int initial_state, input, flags;}; - struct XSizeHints{int flags;}; - struct XWindowAttributes{NativeWindowType root; int x, y, width, height;}; - struct XSetWindowAttributes{int background_pixel, border_pixel, colormap, event_mask, backing_store, save_under, override_redirect;}; - struct XTextProperty{int * value;}; - struct StrangeData{StrangeData(){}StrangeData(Atom atom){}StrangeData(int num){}}; - struct XClientMessageEventData{StrangeData l[3];}; - struct XClientMessageEvent{int type, serial, send_event, format; XClientMessageEventData data ; NativeWindowType window; Atom message_type;}; - struct XEvent{}; - - - void XStringListToTextProperty(char ** prop, int num, XTextProperty * textProp); - Window DefaultRootWindow(Display* nativeDisplayType); - bool XQueryExtension(Display* nativeDisplayType, char * name, int * dummy0, int * dummy2, int * dummy3); - XRRScreenConfiguration * XRRGetScreenInfo(Display* nativeDisplayType, Window window ); - int XRRConfigCurrentConfiguration(XRRScreenConfiguration * config, Rotation * rotation); - XRRScreenSize * XRRConfigSizes(XRRScreenConfiguration * config, int * nSizes); - int XRRConfigCurrentRate(XRRScreenConfiguration * config); - short * XRRConfigRates(XRRScreenConfiguration * config, int sizeID, int * nRates); - void XRRFreeScreenConfigInfo(XRRScreenConfiguration * config); - int DefaultScreen(NativeDisplayType nativeDisplayType); - int DisplayWidth(Display* nativeDisplayType, int screen); - int DisplayHeight(Display* nativeDisplayType, int screen); - Display* XOpenDisplay(int num); - void XCloseDisplay(Display* nativeDisplayType); - Atom XInternAtom(Display* nativeDisplayType, char * name, X11Bool isTrue);; - char * DisplayString(NativeDisplayType nativeDisplayType); - const char * XDisplayName(char * name); - Visual * DefaultVisual(Display* nativeDisplayType, int screen); - int XVisualIDFromVisual(Visual *v); - void XRRSetScreenConfigAndRate(Display* nativeDisplayType, XRRScreenConfiguration * config, Window window, int size, Rotation rotation, int mode, int currentTime ); - XVisualInfo * XGetVisualInfo(Display* nativeDisplayType, int mask, XVisualInfo * info, int * n); - typedef int (*XErrorHandler)(Display *, XErrorEvent*); - XErrorHandler XSetErrorHandler(XErrorHandler xErrorHandler); - void XDestroyWindow(Display* nativeDisplayType, Window nativeWindowType); - bool XGetWindowAttributes(Display* nativeDisplayType, Window nativeWindowType, XWindowAttributes * xWindowAttributes); - int XCreateColormap(Display* nativeDisplayType, Window nativeWindowType, int visual, int allocNone); - Window XCreateWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top, int width, int height, int dummy1, int depth, int inputOutput, int visual, int mask, XSetWindowAttributes * xSetWindowAttributes); - void XFree(void *data); - XWMHints * XAllocWMHints(); - XSizeHints * XAllocSizeHints(); - void XSetWMProperties(Display* nativeDisplayType, Window nativeWindowType,XTextProperty * titleprop, char * dummy1, char * dummy2, int num, XSizeHints *sizeHints, XWMHints *wmHints, char * dummy3); - void XSetWMProtocols(Display* nativeDisplayType, Window nativeWindowType, Atom * atom, int num); - void XMapWindow(Display* nativeDisplayType, Window nativeWindowType); - void XFlush(Display* nativeDisplayType); - void XMoveWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top); - void XResizeWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top); - void XQueryTree(Display* nativeDisplayType, Window nativeWindowType, Window * root, Window *parent, Window **children, unsigned int * nChildren); - void XSendEvent(Display* nativeDisplayType, Window nativeWindowType, int dummy1, int mask, XEvent* xevent); + #define StructureNotifyMask 0 + #define VisibilityChangeMask 0 + #define FocusChangeMask 0 + #define CWBackPixel 0 + #define CWBorderPixel 0 + #define CWColormap 0 + #define CWEventMask 0 + #define NotUseful 0 + #define CWSaveUnder 0 + #define CWBackingStore 0 + #define CWOverrideRedirect 0 + #define InputOutput 0 + #define NormalState 0 + #define StateHint 0 + #define InputHint 0 + #define USPosition 0 + #define ClientMessage 0 + #define SubstructureRedirectMask 0 + #define SubstructureNotifyMask 0 + #define CurrentTime 0 + #define VisualIDMask 0 + #define AllocNone 0 + + enum X11Bool + { + False + , + True + }; + class NotPointerAtom{}; + typedef NotPointerAtom * Atom; + + class Display{}; + class XErrorEvent{}; + class XRRScreenConfiguration{}; + class Rotation{}; + class Visual{}; + #define Window NativeWindowType + + struct XVisualInfo{int visualid, visual, depth;}; + struct XRRScreenSize{int width, height;}; + struct XWMHints{int initial_state, input, flags;}; + struct XSizeHints{int flags;}; + struct XWindowAttributes{NativeWindowType root; int x, y, width, height;}; + struct XSetWindowAttributes{int background_pixel, border_pixel, colormap, event_mask, backing_store, save_under, override_redirect;}; + struct XTextProperty{int * value;}; + struct StrangeData{StrangeData(){}StrangeData(Atom atom){}StrangeData(int num){}}; + struct XClientMessageEventData{StrangeData l[3];}; + struct XClientMessageEvent{int type, serial, send_event, format; XClientMessageEventData data ; NativeWindowType window; Atom message_type;}; + struct XEvent{}; + + + void XStringListToTextProperty(char ** prop, int num, XTextProperty * textProp); + Window DefaultRootWindow(Display* nativeDisplayType); + bool XQueryExtension(Display* nativeDisplayType, char * name, int * dummy0, int * dummy2, int * dummy3); + XRRScreenConfiguration * XRRGetScreenInfo(Display* nativeDisplayType, Window window ); + int XRRConfigCurrentConfiguration(XRRScreenConfiguration * config, Rotation * rotation); + XRRScreenSize * XRRConfigSizes(XRRScreenConfiguration * config, int * nSizes); + int XRRConfigCurrentRate(XRRScreenConfiguration * config); + short * XRRConfigRates(XRRScreenConfiguration * config, int sizeID, int * nRates); + void XRRFreeScreenConfigInfo(XRRScreenConfiguration * config); + int DefaultScreen(NativeDisplayType nativeDisplayType); + int DisplayWidth(Display* nativeDisplayType, int screen); + int DisplayHeight(Display* nativeDisplayType, int screen); + Display* XOpenDisplay(int num); + void XCloseDisplay(Display* nativeDisplayType); + Atom XInternAtom(Display* nativeDisplayType, char * name, X11Bool isTrue);; + char * DisplayString(NativeDisplayType nativeDisplayType); + const char * XDisplayName(char * name); + Visual * DefaultVisual(Display* nativeDisplayType, int screen); + int XVisualIDFromVisual(Visual *v); + void XRRSetScreenConfigAndRate(Display* nativeDisplayType, XRRScreenConfiguration * config, Window window, int size, Rotation rotation, int mode, int currentTime ); + XVisualInfo * XGetVisualInfo(Display* nativeDisplayType, int mask, XVisualInfo * info, int * n); + typedef int (*XErrorHandler)(Display *, XErrorEvent*); + XErrorHandler XSetErrorHandler(XErrorHandler xErrorHandler); + void XDestroyWindow(Display* nativeDisplayType, Window nativeWindowType); + bool XGetWindowAttributes(Display* nativeDisplayType, Window nativeWindowType, XWindowAttributes * xWindowAttributes); + int XCreateColormap(Display* nativeDisplayType, Window nativeWindowType, int visual, int allocNone); + Window XCreateWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top, int width, int height, int dummy1, int depth, int inputOutput, int visual, int mask, XSetWindowAttributes * xSetWindowAttributes); + void XFree(void *data); + XWMHints * XAllocWMHints(); + XSizeHints * XAllocSizeHints(); + void XSetWMProperties(Display* nativeDisplayType, Window nativeWindowType,XTextProperty * titleprop, char * dummy1, char * dummy2, int num, XSizeHints *sizeHints, XWMHints *wmHints, char * dummy3); + void XSetWMProtocols(Display* nativeDisplayType, Window nativeWindowType, Atom * atom, int num); + void XMapWindow(Display* nativeDisplayType, Window nativeWindowType); + void XFlush(Display* nativeDisplayType); + void XMoveWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top); + void XResizeWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top); + void XQueryTree(Display* nativeDisplayType, Window nativeWindowType, Window * root, Window *parent, Window **children, unsigned int * nChildren); + void XSendEvent(Display* nativeDisplayType, Window nativeWindowType, int dummy1, int mask, XEvent* xevent); #endif namespace Ogre { class _OgrePrivate X11EGLSupport : public EGLSupport { - protected: + protected: - //removed createEGLWindow because it was easier to just use - // new X11EGLWindow in the code to get the native version. - //virtual EGLWindow* createEGLWindow( EGLSupport * support); + //removed createEGLWindow because it was easier to just use + // new X11EGLWindow in the code to get the native version. + //virtual EGLWindow* createEGLWindow( EGLSupport * support); public: X11EGLSupport(); virtual ~X11EGLSupport(); -// virtual GLES2PBuffer* createPBuffer(PixelComponentType format, -// size_t width, size_t height); +// virtual GLES2PBuffer* createPBuffer(PixelComponentType format, +// size_t width, size_t height); - virtual void switchMode(uint& width, uint& height, short& frequency); - String getDisplayName(void); + virtual void switchMode(uint& width, uint& height, short& frequency); + String getDisplayName(void); - NativeDisplayType getNativeDisplay(void); - XVisualInfo *getVisualFromFBConfig(::EGLConfig glConfig); - Atom mAtomDeleteWindow; - Atom mAtomFullScreen; - Atom mAtomState; + NativeDisplayType getNativeDisplay(void); + XVisualInfo *getVisualFromFBConfig(::EGLConfig glConfig); + Atom mAtomDeleteWindow; + Atom mAtomFullScreen; + Atom mAtomState; - // This just sets the native variables needed by EGLSupport::getGLDisplay - //Then it calls EGLSupport::getDLDisplay to do the rest of the work. - EGLDisplay getGLDisplay(); + // This just sets the native variables needed by EGLSupport::getGLDisplay + //Then it calls EGLSupport::getDLDisplay to do the rest of the work. + EGLDisplay getGLDisplay(); - //Moved this here from EGLSupport because maybe it should be more native. - RenderWindow* newWindow(const String& name, - unsigned int width, unsigned int height, - bool fullScreen, - const NameValuePairList *miscParams = 0); + //Moved this here from EGLSupport because maybe it should be more native. + RenderWindow* newWindow(const String& name, + unsigned int width, unsigned int height, + bool fullScreen, + const NameValuePairList *miscParams = 0); - }; + }; } #endif diff --git a/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLWindow.h b/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLWindow.h index 8c99e761617..8386a61063c 100644 --- a/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLWindow.h +++ b/RenderSystems/GLES2/include/EGL/X11/OgreX11EGLWindow.h @@ -36,42 +36,42 @@ THE SOFTWARE. namespace Ogre { class _OgrePrivate X11EGLWindow : public EGLWindow { - protected: - X11EGLSupport* mGLSupport; + protected: + X11EGLSupport* mGLSupport; - //Changed these variables back to Window type because - //it seems they are not used outside this class. - Window mParentWindow; - Window mExternalWindow; - virtual EGLContext * createEGLContext() const; - virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); - virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); - virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); - virtual void reposition(int left, int top); - virtual void resize(unsigned int width, unsigned int height); - virtual void windowMovedOrResized(); - virtual void switchFullScreen(bool fullscreen); + //Changed these variables back to Window type because + //it seems they are not used outside this class. + Window mParentWindow; + Window mExternalWindow; + virtual EGLContext * createEGLContext() const; + virtual void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); + virtual void initNativeCreatedWindow(const NameValuePairList *miscParams); + virtual void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); + virtual void reposition(int left, int top); + virtual void resize(unsigned int width, unsigned int height); + virtual void windowMovedOrResized(); + virtual void switchFullScreen(bool fullscreen); - public: + public: X11EGLWindow(X11EGLSupport* glsupport); virtual ~X11EGLWindow(); - /** - @remarks - * Get custom attribute; the following attributes are valid: - * XDISPLAY The X Display connection behind that context. - * XWINDOW The X NativeWindowType connection behind that context. - * ATOM The X Atom used in client delete events. - */ - virtual void getCustomAttribute(const String& name, void* pData); + /** + @remarks + * Get custom attribute; the following attributes are valid: + * XDISPLAY The X Display connection behind that context. + * XWINDOW The X NativeWindowType connection behind that context. + * ATOM The X Atom used in client delete events. + */ + virtual void getCustomAttribute(const String& name, void* pData); - virtual void setFullscreen (bool fullscreen, uint width, uint height); + virtual void setFullscreen (bool fullscreen, uint width, uint height); - //Moved this from EGLWindow because it has some native calls. + //Moved this from EGLWindow because it has some native calls. void create(const String& name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams); - }; + }; } #endif diff --git a/RenderSystems/GLES2/include/GLES2/gl2ext.h b/RenderSystems/GLES2/include/GLES2/gl2ext.h index 01f8236af69..93014ae4463 100644 --- a/RenderSystems/GLES2/include/GLES2/gl2ext.h +++ b/RenderSystems/GLES2/include/GLES2/gl2ext.h @@ -596,9 +596,9 @@ typedef void (GL_APIENTRYP GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,G /* GL_AMD_compressed_ATC_texture */ #ifndef GL_AMD_compressed_ATC_texture -#define ATC_RGB_AMD 0x8C92 -#define ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 -#define ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#define ATC_RGB_AMD 0x8C92 +#define ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE #endif /* GL_EXT_texture_filter_anisotropic */ diff --git a/RenderSystems/GLES2/include/GLES2/gles2w.h b/RenderSystems/GLES2/include/GLES2/gles2w.h index fdf4eccbc9a..573f8336566 100644 --- a/RenderSystems/GLES2/include/GLES2/gles2w.h +++ b/RenderSystems/GLES2/include/GLES2/gles2w.h @@ -638,309 +638,309 @@ extern PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC gleswExtGetProgramBinarySourceQCOM extern PFNGLSTARTTILINGQCOMPROC gleswStartTilingQCOM; extern PFNGLENDTILINGQCOMPROC gleswEndTilingQCOM; -#define glActiveTexture gleswActiveTexture -#define glAttachShader gleswAttachShader -#define glBindAttribLocation gleswBindAttribLocation -#define glBindBuffer gleswBindBuffer -#define glBindFramebuffer gleswBindFramebuffer -#define glBindRenderbuffer gleswBindRenderbuffer -#define glBindTexture gleswBindTexture -#define glBlendColor gleswBlendColor -#define glBlendEquation gleswBlendEquation -#define glBlendEquationSeparate gleswBlendEquationSeparate -#define glBlendFunc gleswBlendFunc -#define glBlendFuncSeparate gleswBlendFuncSeparate -#define glBufferData gleswBufferData -#define glBufferSubData gleswBufferSubData -#define glCheckFramebufferStatus gleswCheckFramebufferStatus -#define glClear gleswClear -#define glClearColor gleswClearColor -#define glClearDepthf gleswClearDepthf -#define glClearStencil gleswClearStencil -#define glColorMask gleswColorMask -#define glCompileShader gleswCompileShader -#define glCompressedTexImage2D gleswCompressedTexImage2D -#define glCompressedTexSubImage2D gleswCompressedTexSubImage2D -#define glCopyTexImage2D gleswCopyTexImage2D -#define glCopyTexSubImage2D gleswCopyTexSubImage2D -#define glCreateProgram gleswCreateProgram -#define glCreateShader gleswCreateShader -#define glCullFace gleswCullFace -#define glDeleteBuffers gleswDeleteBuffers -#define glDeleteFramebuffers gleswDeleteFramebuffers -#define glDeleteProgram gleswDeleteProgram -#define glDeleteRenderbuffers gleswDeleteRenderbuffers -#define glDeleteShader gleswDeleteShader -#define glDeleteTextures gleswDeleteTextures -#define glDepthFunc gleswDepthFunc -#define glDepthMask gleswDepthMask -#define glDepthRangef gleswDepthRangef -#define glDetachShader gleswDetachShader -#define glDisable gleswDisable -#define glDisableVertexAttribArray gleswDisableVertexAttribArray -#define glDrawArrays gleswDrawArrays -#define glDrawElements gleswDrawElements -#define glEnable gleswEnable -#define glEnableVertexAttribArray gleswEnableVertexAttribArray -#define glFinish gleswFinish -#define glFlush gleswFlush -#define glFramebufferRenderbuffer gleswFramebufferRenderbuffer -#define glFramebufferTexture2D gleswFramebufferTexture2D -#define glFrontFace gleswFrontFace -#define glGenBuffers gleswGenBuffers -#define glGenerateMipmap gleswGenerateMipmap -#define glGenFramebuffers gleswGenFramebuffers -#define glGenRenderbuffers gleswGenRenderbuffers -#define glGenTextures gleswGenTextures -#define glGetActiveAttrib gleswGetActiveAttrib -#define glGetActiveUniform gleswGetActiveUniform -#define glGetAttachedShaders gleswGetAttachedShaders -#define glGetAttribLocation gleswGetAttribLocation -#define glGetBooleanv gleswGetBooleanv -#define glGetBufferParameteriv gleswGetBufferParameteriv -#define glGetError gleswGetError -#define glGetFloatv gleswGetFloatv -#define glGetFramebufferAttachmentParameteriv gleswGetFramebufferAttachmentParameteriv -#define glGetIntegerv gleswGetIntegerv -#define glGetProgramiv gleswGetProgramiv -#define glGetProgramInfoLog gleswGetProgramInfoLog -#define glGetRenderbufferParameteriv gleswGetRenderbufferParameteriv -#define glGetShaderiv gleswGetShaderiv -#define glGetShaderInfoLog gleswGetShaderInfoLog -#define glGetShaderPrecisionFormat gleswGetShaderPrecisionFormat -#define glGetShaderSource gleswGetShaderSource -#define glGetString gleswGetString -#define glGetTexParameterfv gleswGetTexParameterfv -#define glGetTexParameteriv gleswGetTexParameteriv -#define glGetUniformfv gleswGetUniformfv -#define glGetUniformiv gleswGetUniformiv -#define glGetUniformLocation gleswGetUniformLocation -#define glGetVertexAttribfv gleswGetVertexAttribfv -#define glGetVertexAttribiv gleswGetVertexAttribiv -#define glGetVertexAttribPointerv gleswGetVertexAttribPointerv -#define glHint gleswHint -#define glIsBuffer gleswIsBuffer -#define glIsEnabled gleswIsEnabled -#define glIsFramebuffer gleswIsFramebuffer -#define glIsProgram gleswIsProgram -#define glIsRenderbuffer gleswIsRenderbuffer -#define glIsShader gleswIsShader -#define glIsTexture gleswIsTexture -#define glLineWidth gleswLineWidth -#define glLinkProgram gleswLinkProgram -#define glPixelStorei gleswPixelStorei -#define glPolygonOffset gleswPolygonOffset -#define glReadPixels gleswReadPixels -#define glReleaseShaderCompiler gleswReleaseShaderCompiler -#define glRenderbufferStorage gleswRenderbufferStorage -#define glSampleCoverage gleswSampleCoverage -#define glScissor gleswScissor -#define glShaderBinary gleswShaderBinary -#define glShaderSource gleswShaderSource -#define glStencilFunc gleswStencilFunc -#define glStencilFuncSeparate gleswStencilFuncSeparate -#define glStencilMask gleswStencilMask -#define glStencilMaskSeparate gleswStencilMaskSeparate -#define glStencilOp gleswStencilOp -#define glStencilOpSeparate gleswStencilOpSeparate -#define glTexImage2D gleswTexImage2D -#define glTexParameterf gleswTexParameterf -#define glTexParameterfv gleswTexParameterfv -#define glTexParameteri gleswTexParameteri -#define glTexParameteriv gleswTexParameteriv -#define glTexSubImage2D gleswTexSubImage2D -#define glUniform1f gleswUniform1f -#define glUniform1fv gleswUniform1fv -#define glUniform1i gleswUniform1i -#define glUniform1iv gleswUniform1iv -#define glUniform2f gleswUniform2f -#define glUniform2fv gleswUniform2fv -#define glUniform2i gleswUniform2i -#define glUniform2iv gleswUniform2iv -#define glUniform3f gleswUniform3f -#define glUniform3fv gleswUniform3fv -#define glUniform3i gleswUniform3i -#define glUniform3iv gleswUniform3iv -#define glUniform4f gleswUniform4f -#define glUniform4fv gleswUniform4fv -#define glUniform4i gleswUniform4i -#define glUniform4iv gleswUniform4iv -#define glUniformMatrix2fv gleswUniformMatrix2fv -#define glUniformMatrix3fv gleswUniformMatrix3fv -#define glUniformMatrix4fv gleswUniformMatrix4fv -#define glUseProgram gleswUseProgram -#define glValidateProgram gleswValidateProgram -#define glVertexAttrib1f gleswVertexAttrib1f -#define glVertexAttrib1fv gleswVertexAttrib1fv -#define glVertexAttrib2f gleswVertexAttrib2f -#define glVertexAttrib2fv gleswVertexAttrib2fv -#define glVertexAttrib3f gleswVertexAttrib3f -#define glVertexAttrib3fv gleswVertexAttrib3fv -#define glVertexAttrib4f gleswVertexAttrib4f -#define glVertexAttrib4fv gleswVertexAttrib4fv -#define glVertexAttribPointer gleswVertexAttribPointer -#define glViewport gleswViewport -#define glEGLImageTargetTexture2DOES gleswEGLImageTargetTexture2DOES -#define glEGLImageTargetRenderbufferStorageOES gleswEGLImageTargetRenderbufferStorageOES -#define glGetProgramBinaryOES gleswGetProgramBinaryOES -#define glProgramBinaryOES gleswProgramBinaryOES -#define glMapBufferOES gleswMapBufferOES -#define glUnmapBufferOES gleswUnmapBufferOES -#define glGetBufferPointervOES gleswGetBufferPointervOES -#define glTexImage3DOES gleswTexImage3DOES -#define glTexSubImage3DOES gleswTexSubImage3DOES -#define glCopyTexSubImage3DOES gleswCopyTexSubImage3DOES -#define glCompressedTexImage3DOES gleswCompressedTexImage3DOES -#define glCompressedTexSubImage3DOES gleswCompressedTexSubImage3DOES -#define glFramebufferTexture3DOES gleswFramebufferTexture3DOES -#define glBindVertexArrayOES gleswBindVertexArrayOES -#define glDeleteVertexArraysOES gleswDeleteVertexArraysOES -#define glGenVertexArraysOES gleswGenVertexArraysOES -#define glIsVertexArrayOES gleswIsVertexArrayOES -#define glDebugMessageControlKHR gleswDebugMessageControlKHR -#define glDebugMessageInsertKHR gleswDebugMessageInsertKHR -#define glDebugMessageCallbackKHR gleswDebugMessageCallbackKHR -#define glGetDebugMessageLogKHR gleswGetDebugMessageLogKHR -#define glPushDebugGroupKHR gleswPushDebugGroupKHR -#define glPopDebugGroupKHR gleswPopDebugGroupKHR -#define glObjectLabelKHR gleswObjectLabelKHR -#define glGetObjectLabelKHR gleswGetObjectLabelKHR -#define glObjectPtrLabelKHR gleswObjectPtrLabelKHR -#define glGetObjectPtrLabelKHR gleswGetObjectPtrLabelKHR -#define glGetPointervKHR gleswGetPointervKHR -#define glGetPerfMonitorGroupsAMD gleswGetPerfMonitorGroupsAMD -#define glGetPerfMonitorCountersAMD gleswGetPerfMonitorCountersAMD -#define glGetPerfMonitorGroupStringAMD gleswGetPerfMonitorGroupStringAMD -#define glGetPerfMonitorCounterStringAMD gleswGetPerfMonitorCounterStringAMD -#define glGetPerfMonitorCounterInfoAMD gleswGetPerfMonitorCounterInfoAMD -#define glGenPerfMonitorsAMD gleswGenPerfMonitorsAMD -#define glDeletePerfMonitorsAMD gleswDeletePerfMonitorsAMD -#define glSelectPerfMonitorCountersAMD gleswSelectPerfMonitorCountersAMD -#define glBeginPerfMonitorAMD gleswBeginPerfMonitorAMD -#define glEndPerfMonitorAMD gleswEndPerfMonitorAMD -#define glGetPerfMonitorCounterDataAMD gleswGetPerfMonitorCounterDataAMD -#define glBlitFramebufferANGLE gleswBlitFramebufferANGLE -#define glRenderbufferStorageMultisampleANGLE gleswRenderbufferStorageMultisampleANGLE -#define glDrawArraysInstancedANGLE gleswDrawArraysInstancedANGLE -#define glDrawElementsInstancedANGLE gleswDrawElementsInstancedANGLE -#define glVertexAttribDivisorANGLE gleswVertexAttribDivisorANGLE -#define glGetTranslatedShaderSourceANGLE gleswGetTranslatedShaderSourceANGLE -#define glDrawArraysInstancedEXT gleswDrawArraysInstancedEXT -#define glDrawElementsInstancedEXT gleswDrawElementsInstancedEXT -#define glVertexAttribDivisorEXT gleswVertexAttribDivisorEXT -#define glCopyTextureLevelsAPPLE gleswCopyTextureLevelsAPPLE -#define glRenderbufferStorageMultisampleAPPLE gleswRenderbufferStorageMultisampleAPPLE -#define glResolveMultisampleFramebufferAPPLE gleswResolveMultisampleFramebufferAPPLE -#define glFenceSyncAPPLE gleswFenceSyncAPPLE -#define glIsSyncAPPLE gleswIsSyncAPPLE -#define glDeleteSyncAPPLE gleswDeleteSyncAPPLE -#define glClientWaitSyncAPPLE gleswClientWaitSyncAPPLE -#define glWaitSyncAPPLE gleswWaitSyncAPPLE -#define glGetInteger64vAPPLE gleswGetInteger64vAPPLE -#define glGetSyncivAPPLE gleswGetSyncivAPPLE -#define glLabelObjectEXT gleswLabelObjectEXT -#define glGetObjectLabelEXT gleswGetObjectLabelEXT -#define glInsertEventMarkerEXT gleswInsertEventMarkerEXT -#define glPushGroupMarkerEXT gleswPushGroupMarkerEXT -#define glPopGroupMarkerEXT gleswPopGroupMarkerEXT -#define glDiscardFramebufferEXT gleswDiscardFramebufferEXT -#define glGenQueriesEXT gleswGenQueriesEXT -#define glDeleteQueriesEXT gleswDeleteQueriesEXT -#define glIsQueryEXT gleswIsQueryEXT -#define glBeginQueryEXT gleswBeginQueryEXT -#define glEndQueryEXT gleswEndQueryEXT -#define glQueryCounterEXT gleswQueryCounterEXT -#define glGetQueryivEXT gleswGetQueryivEXT -#define glGetQueryObjectivEXT gleswGetQueryObjectivEXT -#define glGetQueryObjectuivEXT gleswGetQueryObjectuivEXT -#define glGetQueryObjecti64vEXT gleswGetQueryObjecti64vEXT -#define glGetQueryObjectui64vEXT gleswGetQueryObjectui64vEXT -#define glMapBufferRangeEXT gleswMapBufferRangeEXT -#define glFlushMappedBufferRangeEXT gleswFlushMappedBufferRangeEXT -#define glRenderbufferStorageMultisampleEXT gleswRenderbufferStorageMultisampleEXT -#define glFramebufferTexture2DMultisampleEXT gleswFramebufferTexture2DMultisampleEXT -#define glReadBufferIndexedEXT gleswReadBufferIndexedEXT -#define glDrawBuffersIndexedEXT gleswDrawBuffersIndexedEXT -#define glGetIntegeri_vEXT gleswGetIntegeri_vEXT -#define glMultiDrawArraysEXT gleswMultiDrawArraysEXT -#define glMultiDrawElementsEXT gleswMultiDrawElementsEXT -#define glGetGraphicsResetStatusEXT gleswGetGraphicsResetStatusEXT -#define glReadnPixelsEXT gleswReadnPixelsEXT -#define glGetnUniformfvEXT gleswGetnUniformfvEXT -#define glGetnUniformivEXT gleswGetnUniformivEXT -#define glUseProgramStagesEXT gleswUseProgramStagesEXT -#define glActiveShaderProgramEXT gleswActiveShaderProgramEXT -#define glCreateShaderProgramvEXT gleswCreateShaderProgramvEXT -#define glBindProgramPipelineEXT gleswBindProgramPipelineEXT -#define glDeleteProgramPipelinesEXT gleswDeleteProgramPipelinesEXT -#define glGenProgramPipelinesEXT gleswGenProgramPipelinesEXT -#define glIsProgramPipelineEXT gleswIsProgramPipelineEXT -#define glProgramParameteriEXT gleswProgramParameteriEXT -#define glGetProgramPipelineivEXT gleswGetProgramPipelineivEXT -#define glProgramUniform1iEXT gleswProgramUniform1iEXT -#define glProgramUniform2iEXT gleswProgramUniform2iEXT -#define glProgramUniform3iEXT gleswProgramUniform3iEXT -#define glProgramUniform4iEXT gleswProgramUniform4iEXT -#define glProgramUniform1fEXT gleswProgramUniform1fEXT -#define glProgramUniform2fEXT gleswProgramUniform2fEXT -#define glProgramUniform3fEXT gleswProgramUniform3fEXT -#define glProgramUniform4fEXT gleswProgramUniform4fEXT -#define glProgramUniform1ivEXT gleswProgramUniform1ivEXT -#define glProgramUniform2ivEXT gleswProgramUniform2ivEXT -#define glProgramUniform3ivEXT gleswProgramUniform3ivEXT -#define glProgramUniform4ivEXT gleswProgramUniform4ivEXT -#define glProgramUniform1fvEXT gleswProgramUniform1fvEXT -#define glProgramUniform2fvEXT gleswProgramUniform2fvEXT -#define glProgramUniform3fvEXT gleswProgramUniform3fvEXT -#define glProgramUniform4fvEXT gleswProgramUniform4fvEXT -#define glProgramUniformMatrix2fvEXT gleswProgramUniformMatrix2fvEXT -#define glProgramUniformMatrix3fvEXT gleswProgramUniformMatrix3fvEXT -#define glProgramUniformMatrix4fvEXT gleswProgramUniformMatrix4fvEXT -#define glValidateProgramPipelineEXT gleswValidateProgramPipelineEXT -#define glGetProgramPipelineInfoLogEXT gleswGetProgramPipelineInfoLogEXT -#define glTexStorage1DEXT gleswTexStorage1DEXT -#define glTexStorage2DEXT gleswTexStorage2DEXT -#define glTexStorage3DEXT gleswTexStorage3DEXT -#define glTextureStorage1DEXT gleswTextureStorage1DEXT -#define glTextureStorage2DEXT gleswTextureStorage2DEXT -#define glTextureStorage3DEXT gleswTextureStorage3DEXT -#define glRenderbufferStorageMultisampleIMG gleswRenderbufferStorageMultisampleIMG -#define glFramebufferTexture2DMultisampleIMG gleswFramebufferTexture2DMultisampleIMG -#define glCoverageMaskNV gleswCoverageMaskNV -#define glCoverageOperationNV gleswCoverageOperationNV -#define glDrawBuffersNV gleswDrawBuffersNV -#define glDrawArraysInstancedNV gleswDrawArraysInstancedNV -#define glDrawElementsInstancedNV gleswDrawElementsInstancedNV -#define glDeleteFencesNV gleswDeleteFencesNV -#define glGenFencesNV gleswGenFencesNV -#define glIsFenceNV gleswIsFenceNV -#define glTestFenceNV gleswTestFenceNV -#define glGetFenceivNV gleswGetFenceivNV -#define glFinishFenceNV gleswFinishFenceNV -#define glSetFenceNV gleswSetFenceNV -#define glBlitFramebufferNV gleswBlitFramebufferNV -#define glRenderbufferStorageMultisampleNV gleswRenderbufferStorageMultisampleNV -#define glVertexAttribDivisorNV gleswVertexAttribDivisorNV -#define glReadBufferNV gleswReadBufferNV -#define glAlphaFuncQCOM gleswAlphaFuncQCOM -#define glGetDriverControlsQCOM gleswGetDriverControlsQCOM -#define glGetDriverControlStringQCOM gleswGetDriverControlStringQCOM -#define glEnableDriverControlQCOM gleswEnableDriverControlQCOM -#define glDisableDriverControlQCOM gleswDisableDriverControlQCOM -#define glExtGetTexturesQCOM gleswExtGetTexturesQCOM -#define glExtGetBuffersQCOM gleswExtGetBuffersQCOM -#define glExtGetRenderbuffersQCOM gleswExtGetRenderbuffersQCOM -#define glExtGetFramebuffersQCOM gleswExtGetFramebuffersQCOM -#define glExtGetTexLevelParameterivQCOM gleswExtGetTexLevelParameterivQCOM -#define glExtTexObjectStateOverrideiQCOM gleswExtTexObjectStateOverrideiQCOM -#define glExtGetTexSubImageQCOM gleswExtGetTexSubImageQCOM -#define glExtGetBufferPointervQCOM gleswExtGetBufferPointervQCOM -#define glExtGetShadersQCOM gleswExtGetShadersQCOM -#define glExtGetProgramsQCOM gleswExtGetProgramsQCOM -#define glExtIsProgramBinaryQCOM gleswExtIsProgramBinaryQCOM -#define glExtGetProgramBinarySourceQCOM gleswExtGetProgramBinarySourceQCOM -#define glStartTilingQCOM gleswStartTilingQCOM -#define glEndTilingQCOM gleswEndTilingQCOM +#define glActiveTexture gleswActiveTexture +#define glAttachShader gleswAttachShader +#define glBindAttribLocation gleswBindAttribLocation +#define glBindBuffer gleswBindBuffer +#define glBindFramebuffer gleswBindFramebuffer +#define glBindRenderbuffer gleswBindRenderbuffer +#define glBindTexture gleswBindTexture +#define glBlendColor gleswBlendColor +#define glBlendEquation gleswBlendEquation +#define glBlendEquationSeparate gleswBlendEquationSeparate +#define glBlendFunc gleswBlendFunc +#define glBlendFuncSeparate gleswBlendFuncSeparate +#define glBufferData gleswBufferData +#define glBufferSubData gleswBufferSubData +#define glCheckFramebufferStatus gleswCheckFramebufferStatus +#define glClear gleswClear +#define glClearColor gleswClearColor +#define glClearDepthf gleswClearDepthf +#define glClearStencil gleswClearStencil +#define glColorMask gleswColorMask +#define glCompileShader gleswCompileShader +#define glCompressedTexImage2D gleswCompressedTexImage2D +#define glCompressedTexSubImage2D gleswCompressedTexSubImage2D +#define glCopyTexImage2D gleswCopyTexImage2D +#define glCopyTexSubImage2D gleswCopyTexSubImage2D +#define glCreateProgram gleswCreateProgram +#define glCreateShader gleswCreateShader +#define glCullFace gleswCullFace +#define glDeleteBuffers gleswDeleteBuffers +#define glDeleteFramebuffers gleswDeleteFramebuffers +#define glDeleteProgram gleswDeleteProgram +#define glDeleteRenderbuffers gleswDeleteRenderbuffers +#define glDeleteShader gleswDeleteShader +#define glDeleteTextures gleswDeleteTextures +#define glDepthFunc gleswDepthFunc +#define glDepthMask gleswDepthMask +#define glDepthRangef gleswDepthRangef +#define glDetachShader gleswDetachShader +#define glDisable gleswDisable +#define glDisableVertexAttribArray gleswDisableVertexAttribArray +#define glDrawArrays gleswDrawArrays +#define glDrawElements gleswDrawElements +#define glEnable gleswEnable +#define glEnableVertexAttribArray gleswEnableVertexAttribArray +#define glFinish gleswFinish +#define glFlush gleswFlush +#define glFramebufferRenderbuffer gleswFramebufferRenderbuffer +#define glFramebufferTexture2D gleswFramebufferTexture2D +#define glFrontFace gleswFrontFace +#define glGenBuffers gleswGenBuffers +#define glGenerateMipmap gleswGenerateMipmap +#define glGenFramebuffers gleswGenFramebuffers +#define glGenRenderbuffers gleswGenRenderbuffers +#define glGenTextures gleswGenTextures +#define glGetActiveAttrib gleswGetActiveAttrib +#define glGetActiveUniform gleswGetActiveUniform +#define glGetAttachedShaders gleswGetAttachedShaders +#define glGetAttribLocation gleswGetAttribLocation +#define glGetBooleanv gleswGetBooleanv +#define glGetBufferParameteriv gleswGetBufferParameteriv +#define glGetError gleswGetError +#define glGetFloatv gleswGetFloatv +#define glGetFramebufferAttachmentParameteriv gleswGetFramebufferAttachmentParameteriv +#define glGetIntegerv gleswGetIntegerv +#define glGetProgramiv gleswGetProgramiv +#define glGetProgramInfoLog gleswGetProgramInfoLog +#define glGetRenderbufferParameteriv gleswGetRenderbufferParameteriv +#define glGetShaderiv gleswGetShaderiv +#define glGetShaderInfoLog gleswGetShaderInfoLog +#define glGetShaderPrecisionFormat gleswGetShaderPrecisionFormat +#define glGetShaderSource gleswGetShaderSource +#define glGetString gleswGetString +#define glGetTexParameterfv gleswGetTexParameterfv +#define glGetTexParameteriv gleswGetTexParameteriv +#define glGetUniformfv gleswGetUniformfv +#define glGetUniformiv gleswGetUniformiv +#define glGetUniformLocation gleswGetUniformLocation +#define glGetVertexAttribfv gleswGetVertexAttribfv +#define glGetVertexAttribiv gleswGetVertexAttribiv +#define glGetVertexAttribPointerv gleswGetVertexAttribPointerv +#define glHint gleswHint +#define glIsBuffer gleswIsBuffer +#define glIsEnabled gleswIsEnabled +#define glIsFramebuffer gleswIsFramebuffer +#define glIsProgram gleswIsProgram +#define glIsRenderbuffer gleswIsRenderbuffer +#define glIsShader gleswIsShader +#define glIsTexture gleswIsTexture +#define glLineWidth gleswLineWidth +#define glLinkProgram gleswLinkProgram +#define glPixelStorei gleswPixelStorei +#define glPolygonOffset gleswPolygonOffset +#define glReadPixels gleswReadPixels +#define glReleaseShaderCompiler gleswReleaseShaderCompiler +#define glRenderbufferStorage gleswRenderbufferStorage +#define glSampleCoverage gleswSampleCoverage +#define glScissor gleswScissor +#define glShaderBinary gleswShaderBinary +#define glShaderSource gleswShaderSource +#define glStencilFunc gleswStencilFunc +#define glStencilFuncSeparate gleswStencilFuncSeparate +#define glStencilMask gleswStencilMask +#define glStencilMaskSeparate gleswStencilMaskSeparate +#define glStencilOp gleswStencilOp +#define glStencilOpSeparate gleswStencilOpSeparate +#define glTexImage2D gleswTexImage2D +#define glTexParameterf gleswTexParameterf +#define glTexParameterfv gleswTexParameterfv +#define glTexParameteri gleswTexParameteri +#define glTexParameteriv gleswTexParameteriv +#define glTexSubImage2D gleswTexSubImage2D +#define glUniform1f gleswUniform1f +#define glUniform1fv gleswUniform1fv +#define glUniform1i gleswUniform1i +#define glUniform1iv gleswUniform1iv +#define glUniform2f gleswUniform2f +#define glUniform2fv gleswUniform2fv +#define glUniform2i gleswUniform2i +#define glUniform2iv gleswUniform2iv +#define glUniform3f gleswUniform3f +#define glUniform3fv gleswUniform3fv +#define glUniform3i gleswUniform3i +#define glUniform3iv gleswUniform3iv +#define glUniform4f gleswUniform4f +#define glUniform4fv gleswUniform4fv +#define glUniform4i gleswUniform4i +#define glUniform4iv gleswUniform4iv +#define glUniformMatrix2fv gleswUniformMatrix2fv +#define glUniformMatrix3fv gleswUniformMatrix3fv +#define glUniformMatrix4fv gleswUniformMatrix4fv +#define glUseProgram gleswUseProgram +#define glValidateProgram gleswValidateProgram +#define glVertexAttrib1f gleswVertexAttrib1f +#define glVertexAttrib1fv gleswVertexAttrib1fv +#define glVertexAttrib2f gleswVertexAttrib2f +#define glVertexAttrib2fv gleswVertexAttrib2fv +#define glVertexAttrib3f gleswVertexAttrib3f +#define glVertexAttrib3fv gleswVertexAttrib3fv +#define glVertexAttrib4f gleswVertexAttrib4f +#define glVertexAttrib4fv gleswVertexAttrib4fv +#define glVertexAttribPointer gleswVertexAttribPointer +#define glViewport gleswViewport +#define glEGLImageTargetTexture2DOES gleswEGLImageTargetTexture2DOES +#define glEGLImageTargetRenderbufferStorageOES gleswEGLImageTargetRenderbufferStorageOES +#define glGetProgramBinaryOES gleswGetProgramBinaryOES +#define glProgramBinaryOES gleswProgramBinaryOES +#define glMapBufferOES gleswMapBufferOES +#define glUnmapBufferOES gleswUnmapBufferOES +#define glGetBufferPointervOES gleswGetBufferPointervOES +#define glTexImage3DOES gleswTexImage3DOES +#define glTexSubImage3DOES gleswTexSubImage3DOES +#define glCopyTexSubImage3DOES gleswCopyTexSubImage3DOES +#define glCompressedTexImage3DOES gleswCompressedTexImage3DOES +#define glCompressedTexSubImage3DOES gleswCompressedTexSubImage3DOES +#define glFramebufferTexture3DOES gleswFramebufferTexture3DOES +#define glBindVertexArrayOES gleswBindVertexArrayOES +#define glDeleteVertexArraysOES gleswDeleteVertexArraysOES +#define glGenVertexArraysOES gleswGenVertexArraysOES +#define glIsVertexArrayOES gleswIsVertexArrayOES +#define glDebugMessageControlKHR gleswDebugMessageControlKHR +#define glDebugMessageInsertKHR gleswDebugMessageInsertKHR +#define glDebugMessageCallbackKHR gleswDebugMessageCallbackKHR +#define glGetDebugMessageLogKHR gleswGetDebugMessageLogKHR +#define glPushDebugGroupKHR gleswPushDebugGroupKHR +#define glPopDebugGroupKHR gleswPopDebugGroupKHR +#define glObjectLabelKHR gleswObjectLabelKHR +#define glGetObjectLabelKHR gleswGetObjectLabelKHR +#define glObjectPtrLabelKHR gleswObjectPtrLabelKHR +#define glGetObjectPtrLabelKHR gleswGetObjectPtrLabelKHR +#define glGetPointervKHR gleswGetPointervKHR +#define glGetPerfMonitorGroupsAMD gleswGetPerfMonitorGroupsAMD +#define glGetPerfMonitorCountersAMD gleswGetPerfMonitorCountersAMD +#define glGetPerfMonitorGroupStringAMD gleswGetPerfMonitorGroupStringAMD +#define glGetPerfMonitorCounterStringAMD gleswGetPerfMonitorCounterStringAMD +#define glGetPerfMonitorCounterInfoAMD gleswGetPerfMonitorCounterInfoAMD +#define glGenPerfMonitorsAMD gleswGenPerfMonitorsAMD +#define glDeletePerfMonitorsAMD gleswDeletePerfMonitorsAMD +#define glSelectPerfMonitorCountersAMD gleswSelectPerfMonitorCountersAMD +#define glBeginPerfMonitorAMD gleswBeginPerfMonitorAMD +#define glEndPerfMonitorAMD gleswEndPerfMonitorAMD +#define glGetPerfMonitorCounterDataAMD gleswGetPerfMonitorCounterDataAMD +#define glBlitFramebufferANGLE gleswBlitFramebufferANGLE +#define glRenderbufferStorageMultisampleANGLE gleswRenderbufferStorageMultisampleANGLE +#define glDrawArraysInstancedANGLE gleswDrawArraysInstancedANGLE +#define glDrawElementsInstancedANGLE gleswDrawElementsInstancedANGLE +#define glVertexAttribDivisorANGLE gleswVertexAttribDivisorANGLE +#define glGetTranslatedShaderSourceANGLE gleswGetTranslatedShaderSourceANGLE +#define glDrawArraysInstancedEXT gleswDrawArraysInstancedEXT +#define glDrawElementsInstancedEXT gleswDrawElementsInstancedEXT +#define glVertexAttribDivisorEXT gleswVertexAttribDivisorEXT +#define glCopyTextureLevelsAPPLE gleswCopyTextureLevelsAPPLE +#define glRenderbufferStorageMultisampleAPPLE gleswRenderbufferStorageMultisampleAPPLE +#define glResolveMultisampleFramebufferAPPLE gleswResolveMultisampleFramebufferAPPLE +#define glFenceSyncAPPLE gleswFenceSyncAPPLE +#define glIsSyncAPPLE gleswIsSyncAPPLE +#define glDeleteSyncAPPLE gleswDeleteSyncAPPLE +#define glClientWaitSyncAPPLE gleswClientWaitSyncAPPLE +#define glWaitSyncAPPLE gleswWaitSyncAPPLE +#define glGetInteger64vAPPLE gleswGetInteger64vAPPLE +#define glGetSyncivAPPLE gleswGetSyncivAPPLE +#define glLabelObjectEXT gleswLabelObjectEXT +#define glGetObjectLabelEXT gleswGetObjectLabelEXT +#define glInsertEventMarkerEXT gleswInsertEventMarkerEXT +#define glPushGroupMarkerEXT gleswPushGroupMarkerEXT +#define glPopGroupMarkerEXT gleswPopGroupMarkerEXT +#define glDiscardFramebufferEXT gleswDiscardFramebufferEXT +#define glGenQueriesEXT gleswGenQueriesEXT +#define glDeleteQueriesEXT gleswDeleteQueriesEXT +#define glIsQueryEXT gleswIsQueryEXT +#define glBeginQueryEXT gleswBeginQueryEXT +#define glEndQueryEXT gleswEndQueryEXT +#define glQueryCounterEXT gleswQueryCounterEXT +#define glGetQueryivEXT gleswGetQueryivEXT +#define glGetQueryObjectivEXT gleswGetQueryObjectivEXT +#define glGetQueryObjectuivEXT gleswGetQueryObjectuivEXT +#define glGetQueryObjecti64vEXT gleswGetQueryObjecti64vEXT +#define glGetQueryObjectui64vEXT gleswGetQueryObjectui64vEXT +#define glMapBufferRangeEXT gleswMapBufferRangeEXT +#define glFlushMappedBufferRangeEXT gleswFlushMappedBufferRangeEXT +#define glRenderbufferStorageMultisampleEXT gleswRenderbufferStorageMultisampleEXT +#define glFramebufferTexture2DMultisampleEXT gleswFramebufferTexture2DMultisampleEXT +#define glReadBufferIndexedEXT gleswReadBufferIndexedEXT +#define glDrawBuffersIndexedEXT gleswDrawBuffersIndexedEXT +#define glGetIntegeri_vEXT gleswGetIntegeri_vEXT +#define glMultiDrawArraysEXT gleswMultiDrawArraysEXT +#define glMultiDrawElementsEXT gleswMultiDrawElementsEXT +#define glGetGraphicsResetStatusEXT gleswGetGraphicsResetStatusEXT +#define glReadnPixelsEXT gleswReadnPixelsEXT +#define glGetnUniformfvEXT gleswGetnUniformfvEXT +#define glGetnUniformivEXT gleswGetnUniformivEXT +#define glUseProgramStagesEXT gleswUseProgramStagesEXT +#define glActiveShaderProgramEXT gleswActiveShaderProgramEXT +#define glCreateShaderProgramvEXT gleswCreateShaderProgramvEXT +#define glBindProgramPipelineEXT gleswBindProgramPipelineEXT +#define glDeleteProgramPipelinesEXT gleswDeleteProgramPipelinesEXT +#define glGenProgramPipelinesEXT gleswGenProgramPipelinesEXT +#define glIsProgramPipelineEXT gleswIsProgramPipelineEXT +#define glProgramParameteriEXT gleswProgramParameteriEXT +#define glGetProgramPipelineivEXT gleswGetProgramPipelineivEXT +#define glProgramUniform1iEXT gleswProgramUniform1iEXT +#define glProgramUniform2iEXT gleswProgramUniform2iEXT +#define glProgramUniform3iEXT gleswProgramUniform3iEXT +#define glProgramUniform4iEXT gleswProgramUniform4iEXT +#define glProgramUniform1fEXT gleswProgramUniform1fEXT +#define glProgramUniform2fEXT gleswProgramUniform2fEXT +#define glProgramUniform3fEXT gleswProgramUniform3fEXT +#define glProgramUniform4fEXT gleswProgramUniform4fEXT +#define glProgramUniform1ivEXT gleswProgramUniform1ivEXT +#define glProgramUniform2ivEXT gleswProgramUniform2ivEXT +#define glProgramUniform3ivEXT gleswProgramUniform3ivEXT +#define glProgramUniform4ivEXT gleswProgramUniform4ivEXT +#define glProgramUniform1fvEXT gleswProgramUniform1fvEXT +#define glProgramUniform2fvEXT gleswProgramUniform2fvEXT +#define glProgramUniform3fvEXT gleswProgramUniform3fvEXT +#define glProgramUniform4fvEXT gleswProgramUniform4fvEXT +#define glProgramUniformMatrix2fvEXT gleswProgramUniformMatrix2fvEXT +#define glProgramUniformMatrix3fvEXT gleswProgramUniformMatrix3fvEXT +#define glProgramUniformMatrix4fvEXT gleswProgramUniformMatrix4fvEXT +#define glValidateProgramPipelineEXT gleswValidateProgramPipelineEXT +#define glGetProgramPipelineInfoLogEXT gleswGetProgramPipelineInfoLogEXT +#define glTexStorage1DEXT gleswTexStorage1DEXT +#define glTexStorage2DEXT gleswTexStorage2DEXT +#define glTexStorage3DEXT gleswTexStorage3DEXT +#define glTextureStorage1DEXT gleswTextureStorage1DEXT +#define glTextureStorage2DEXT gleswTextureStorage2DEXT +#define glTextureStorage3DEXT gleswTextureStorage3DEXT +#define glRenderbufferStorageMultisampleIMG gleswRenderbufferStorageMultisampleIMG +#define glFramebufferTexture2DMultisampleIMG gleswFramebufferTexture2DMultisampleIMG +#define glCoverageMaskNV gleswCoverageMaskNV +#define glCoverageOperationNV gleswCoverageOperationNV +#define glDrawBuffersNV gleswDrawBuffersNV +#define glDrawArraysInstancedNV gleswDrawArraysInstancedNV +#define glDrawElementsInstancedNV gleswDrawElementsInstancedNV +#define glDeleteFencesNV gleswDeleteFencesNV +#define glGenFencesNV gleswGenFencesNV +#define glIsFenceNV gleswIsFenceNV +#define glTestFenceNV gleswTestFenceNV +#define glGetFenceivNV gleswGetFenceivNV +#define glFinishFenceNV gleswFinishFenceNV +#define glSetFenceNV gleswSetFenceNV +#define glBlitFramebufferNV gleswBlitFramebufferNV +#define glRenderbufferStorageMultisampleNV gleswRenderbufferStorageMultisampleNV +#define glVertexAttribDivisorNV gleswVertexAttribDivisorNV +#define glReadBufferNV gleswReadBufferNV +#define glAlphaFuncQCOM gleswAlphaFuncQCOM +#define glGetDriverControlsQCOM gleswGetDriverControlsQCOM +#define glGetDriverControlStringQCOM gleswGetDriverControlStringQCOM +#define glEnableDriverControlQCOM gleswEnableDriverControlQCOM +#define glDisableDriverControlQCOM gleswDisableDriverControlQCOM +#define glExtGetTexturesQCOM gleswExtGetTexturesQCOM +#define glExtGetBuffersQCOM gleswExtGetBuffersQCOM +#define glExtGetRenderbuffersQCOM gleswExtGetRenderbuffersQCOM +#define glExtGetFramebuffersQCOM gleswExtGetFramebuffersQCOM +#define glExtGetTexLevelParameterivQCOM gleswExtGetTexLevelParameterivQCOM +#define glExtTexObjectStateOverrideiQCOM gleswExtTexObjectStateOverrideiQCOM +#define glExtGetTexSubImageQCOM gleswExtGetTexSubImageQCOM +#define glExtGetBufferPointervQCOM gleswExtGetBufferPointervQCOM +#define glExtGetShadersQCOM gleswExtGetShadersQCOM +#define glExtGetProgramsQCOM gleswExtGetProgramsQCOM +#define glExtIsProgramBinaryQCOM gleswExtIsProgramBinaryQCOM +#define glExtGetProgramBinarySourceQCOM gleswExtGetProgramBinarySourceQCOM +#define glStartTilingQCOM gleswStartTilingQCOM +#define glEndTilingQCOM gleswEndTilingQCOM #ifdef __cplusplus } diff --git a/RenderSystems/GLES2/include/GLES3/gles3w.h b/RenderSystems/GLES2/include/GLES3/gles3w.h index 40167f843e1..3fe0f56ec92 100644 --- a/RenderSystems/GLES2/include/GLES3/gles3w.h +++ b/RenderSystems/GLES2/include/GLES3/gles3w.h @@ -603,293 +603,293 @@ extern PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC gleswProgramUniformMatrix4x3fvEXT; extern PFNGLVALIDATEPROGRAMPIPELINEEXTPROC gleswValidateProgramPipelineEXT; extern PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC gleswGetProgramPipelineInfoLogEXT; -#define glActiveTexture gleswActiveTexture -#define glAttachShader gleswAttachShader -#define glBindAttribLocation gleswBindAttribLocation -#define glBindBuffer gleswBindBuffer -#define glBindFramebuffer gleswBindFramebuffer -#define glBindRenderbuffer gleswBindRenderbuffer -#define glBindTexture gleswBindTexture -#define glBlendColor gleswBlendColor -#define glBlendEquation gleswBlendEquation -#define glBlendEquationSeparate gleswBlendEquationSeparate -#define glBlendFunc gleswBlendFunc -#define glBlendFuncSeparate gleswBlendFuncSeparate -#define glBufferData gleswBufferData -#define glBufferSubData gleswBufferSubData -#define glCheckFramebufferStatus gleswCheckFramebufferStatus -#define glClear gleswClear -#define glClearColor gleswClearColor -#define glClearDepthf gleswClearDepthf -#define glClearStencil gleswClearStencil -#define glColorMask gleswColorMask -#define glCompileShader gleswCompileShader -#define glCompressedTexImage2D gleswCompressedTexImage2D -#define glCompressedTexSubImage2D gleswCompressedTexSubImage2D -#define glCopyTexImage2D gleswCopyTexImage2D -#define glCopyTexSubImage2D gleswCopyTexSubImage2D -#define glCreateProgram gleswCreateProgram -#define glCreateShader gleswCreateShader -#define glCullFace gleswCullFace -#define glDeleteBuffers gleswDeleteBuffers -#define glDeleteFramebuffers gleswDeleteFramebuffers -#define glDeleteProgram gleswDeleteProgram -#define glDeleteRenderbuffers gleswDeleteRenderbuffers -#define glDeleteShader gleswDeleteShader -#define glDeleteTextures gleswDeleteTextures -#define glDepthFunc gleswDepthFunc -#define glDepthMask gleswDepthMask -#define glDepthRangef gleswDepthRangef -#define glDetachShader gleswDetachShader -#define glDisable gleswDisable -#define glDisableVertexAttribArray gleswDisableVertexAttribArray -#define glDrawArrays gleswDrawArrays -#define glDrawElements gleswDrawElements -#define glEnable gleswEnable -#define glEnableVertexAttribArray gleswEnableVertexAttribArray -#define glFinish gleswFinish -#define glFlush gleswFlush -#define glFramebufferRenderbuffer gleswFramebufferRenderbuffer -#define glFramebufferTexture2D gleswFramebufferTexture2D -#define glFrontFace gleswFrontFace -#define glGenBuffers gleswGenBuffers -#define glGenerateMipmap gleswGenerateMipmap -#define glGenFramebuffers gleswGenFramebuffers -#define glGenRenderbuffers gleswGenRenderbuffers -#define glGenTextures gleswGenTextures -#define glGetActiveAttrib gleswGetActiveAttrib -#define glGetActiveUniform gleswGetActiveUniform -#define glGetAttachedShaders gleswGetAttachedShaders -#define glGetAttribLocation gleswGetAttribLocation -#define glGetBooleanv gleswGetBooleanv -#define glGetBufferParameteriv gleswGetBufferParameteriv -#define glGetError gleswGetError -#define glGetFloatv gleswGetFloatv -#define glGetFramebufferAttachmentParameteriv gleswGetFramebufferAttachmentParameteriv -#define glGetIntegerv gleswGetIntegerv -#define glGetProgramiv gleswGetProgramiv -#define glGetProgramInfoLog gleswGetProgramInfoLog -#define glGetRenderbufferParameteriv gleswGetRenderbufferParameteriv -#define glGetShaderiv gleswGetShaderiv -#define glGetShaderInfoLog gleswGetShaderInfoLog -#define glGetShaderPrecisionFormat gleswGetShaderPrecisionFormat -#define glGetShaderSource gleswGetShaderSource -#define glGetString gleswGetString -#define glGetTexParameterfv gleswGetTexParameterfv -#define glGetTexParameteriv gleswGetTexParameteriv -#define glGetUniformfv gleswGetUniformfv -#define glGetUniformiv gleswGetUniformiv -#define glGetUniformLocation gleswGetUniformLocation -#define glGetVertexAttribfv gleswGetVertexAttribfv -#define glGetVertexAttribiv gleswGetVertexAttribiv -#define glGetVertexAttribPointerv gleswGetVertexAttribPointerv -#define glHint gleswHint -#define glIsBuffer gleswIsBuffer -#define glIsEnabled gleswIsEnabled -#define glIsFramebuffer gleswIsFramebuffer -#define glIsProgram gleswIsProgram -#define glIsRenderbuffer gleswIsRenderbuffer -#define glIsShader gleswIsShader -#define glIsTexture gleswIsTexture -#define glLineWidth gleswLineWidth -#define glLinkProgram gleswLinkProgram -#define glPixelStorei gleswPixelStorei -#define glPolygonOffset gleswPolygonOffset -#define glReadPixels gleswReadPixels -#define glReleaseShaderCompiler gleswReleaseShaderCompiler -#define glRenderbufferStorage gleswRenderbufferStorage -#define glSampleCoverage gleswSampleCoverage -#define glScissor gleswScissor -#define glShaderBinary gleswShaderBinary -#define glShaderSource gleswShaderSource -#define glStencilFunc gleswStencilFunc -#define glStencilFuncSeparate gleswStencilFuncSeparate -#define glStencilMask gleswStencilMask -#define glStencilMaskSeparate gleswStencilMaskSeparate -#define glStencilOp gleswStencilOp -#define glStencilOpSeparate gleswStencilOpSeparate -#define glTexImage2D gleswTexImage2D -#define glTexParameterf gleswTexParameterf -#define glTexParameterfv gleswTexParameterfv -#define glTexParameteri gleswTexParameteri -#define glTexParameteriv gleswTexParameteriv -#define glTexSubImage2D gleswTexSubImage2D -#define glUniform1f gleswUniform1f -#define glUniform1fv gleswUniform1fv -#define glUniform1i gleswUniform1i -#define glUniform1iv gleswUniform1iv -#define glUniform2f gleswUniform2f -#define glUniform2fv gleswUniform2fv -#define glUniform2i gleswUniform2i -#define glUniform2iv gleswUniform2iv -#define glUniform3f gleswUniform3f -#define glUniform3fv gleswUniform3fv -#define glUniform3i gleswUniform3i -#define glUniform3iv gleswUniform3iv -#define glUniform4f gleswUniform4f -#define glUniform4fv gleswUniform4fv -#define glUniform4i gleswUniform4i -#define glUniform4iv gleswUniform4iv -#define glUniformMatrix2fv gleswUniformMatrix2fv -#define glUniformMatrix3fv gleswUniformMatrix3fv -#define glUniformMatrix4fv gleswUniformMatrix4fv -#define glUseProgram gleswUseProgram -#define glValidateProgram gleswValidateProgram -#define glVertexAttrib1f gleswVertexAttrib1f -#define glVertexAttrib1fv gleswVertexAttrib1fv -#define glVertexAttrib2f gleswVertexAttrib2f -#define glVertexAttrib2fv gleswVertexAttrib2fv -#define glVertexAttrib3f gleswVertexAttrib3f -#define glVertexAttrib3fv gleswVertexAttrib3fv -#define glVertexAttrib4f gleswVertexAttrib4f -#define glVertexAttrib4fv gleswVertexAttrib4fv -#define glVertexAttribPointer gleswVertexAttribPointer -#define glViewport gleswViewport -#define glReadBuffer gleswReadBuffer -#define glDrawRangeElements gleswDrawRangeElements -#define glTexImage3D gleswTexImage3D -#define glTexSubImage3D gleswTexSubImage3D -#define glCopyTexSubImage3D gleswCopyTexSubImage3D -#define glCompressedTexImage3D gleswCompressedTexImage3D -#define glCompressedTexSubImage3D gleswCompressedTexSubImage3D -#define glGenQueries gleswGenQueries -#define glDeleteQueries gleswDeleteQueries -#define glIsQuery gleswIsQuery -#define glBeginQuery gleswBeginQuery -#define glEndQuery gleswEndQuery -#define glGetQueryiv gleswGetQueryiv -#define glGetQueryObjectuiv gleswGetQueryObjectuiv -#define glUnmapBuffer gleswUnmapBuffer -#define glGetBufferPointerv gleswGetBufferPointerv -#define glDrawBuffers gleswDrawBuffers -#define glUniformMatrix2x3fv gleswUniformMatrix2x3fv -#define glUniformMatrix3x2fv gleswUniformMatrix3x2fv -#define glUniformMatrix2x4fv gleswUniformMatrix2x4fv -#define glUniformMatrix4x2fv gleswUniformMatrix4x2fv -#define glUniformMatrix3x4fv gleswUniformMatrix3x4fv -#define glUniformMatrix4x3fv gleswUniformMatrix4x3fv -#define glBlitFramebuffer gleswBlitFramebuffer -#define glRenderbufferStorageMultisample gleswRenderbufferStorageMultisample -#define glFramebufferTextureLayer gleswFramebufferTextureLayer -#define glMapBufferRange gleswMapBufferRange -#define glFlushMappedBufferRange gleswFlushMappedBufferRange -#define glBindVertexArray gleswBindVertexArray -#define glDeleteVertexArrays gleswDeleteVertexArrays -#define glGenVertexArrays gleswGenVertexArrays -#define glIsVertexArray gleswIsVertexArray -#define glGetIntegeri_v gleswGetIntegeri_v -#define glBeginTransformFeedback gleswBeginTransformFeedback -#define glEndTransformFeedback gleswEndTransformFeedback -#define glBindBufferRange gleswBindBufferRange -#define glBindBufferBase gleswBindBufferBase -#define glTransformFeedbackVaryings gleswTransformFeedbackVaryings -#define glGetTransformFeedbackVarying gleswGetTransformFeedbackVarying -#define glVertexAttribIPointer gleswVertexAttribIPointer -#define glGetVertexAttribIiv gleswGetVertexAttribIiv -#define glGetVertexAttribIuiv gleswGetVertexAttribIuiv -#define glVertexAttribI4i gleswVertexAttribI4i -#define glVertexAttribI4ui gleswVertexAttribI4ui -#define glVertexAttribI4iv gleswVertexAttribI4iv -#define glVertexAttribI4uiv gleswVertexAttribI4uiv -#define glGetUniformuiv gleswGetUniformuiv -#define glGetFragDataLocation gleswGetFragDataLocation -#define glUniform1ui gleswUniform1ui -#define glUniform2ui gleswUniform2ui -#define glUniform3ui gleswUniform3ui -#define glUniform4ui gleswUniform4ui -#define glUniform1uiv gleswUniform1uiv -#define glUniform2uiv gleswUniform2uiv -#define glUniform3uiv gleswUniform3uiv -#define glUniform4uiv gleswUniform4uiv -#define glClearBufferiv gleswClearBufferiv -#define glClearBufferuiv gleswClearBufferuiv -#define glClearBufferfv gleswClearBufferfv -#define glClearBufferfi gleswClearBufferfi -#define glGetStringi gleswGetStringi -#define glCopyBufferSubData gleswCopyBufferSubData -#define glGetUniformIndices gleswGetUniformIndices -#define glGetActiveUniformsiv gleswGetActiveUniformsiv -#define glGetUniformBlockIndex gleswGetUniformBlockIndex -#define glGetActiveUniformBlockiv gleswGetActiveUniformBlockiv -#define glGetActiveUniformBlockName gleswGetActiveUniformBlockName -#define glUniformBlockBinding gleswUniformBlockBinding -#define glDrawArraysInstanced gleswDrawArraysInstanced -#define glDrawElementsInstanced gleswDrawElementsInstanced -#define glFenceSync gleswFenceSync -#define glIsSync gleswIsSync -#define glDeleteSync gleswDeleteSync -#define glClientWaitSync gleswClientWaitSync -#define glWaitSync gleswWaitSync -#define glGetInteger64v gleswGetInteger64v -#define glGetSynciv gleswGetSynciv -#define glGetInteger64i_v gleswGetInteger64i_v -#define glGetBufferParameteri64v gleswGetBufferParameteri64v -#define glGenSamplers gleswGenSamplers -#define glDeleteSamplers gleswDeleteSamplers -#define glIsSampler gleswIsSampler -#define glBindSampler gleswBindSampler -#define glSamplerParameteri gleswSamplerParameteri -#define glSamplerParameteriv gleswSamplerParameteriv -#define glSamplerParameterf gleswSamplerParameterf -#define glSamplerParameterfv gleswSamplerParameterfv -#define glGetSamplerParameteriv gleswGetSamplerParameteriv -#define glGetSamplerParameterfv gleswGetSamplerParameterfv -#define glVertexAttribDivisor gleswVertexAttribDivisor -#define glBindTransformFeedback gleswBindTransformFeedback -#define glDeleteTransformFeedbacks gleswDeleteTransformFeedbacks -#define glGenTransformFeedbacks gleswGenTransformFeedbacks -#define glIsTransformFeedback gleswIsTransformFeedback -#define glPauseTransformFeedback gleswPauseTransformFeedback -#define glResumeTransformFeedback gleswResumeTransformFeedback -#define glGetProgramBinary gleswGetProgramBinary -#define glProgramBinary gleswProgramBinary -#define glProgramParameteri gleswProgramParameteri -#define glInvalidateFramebuffer gleswInvalidateFramebuffer -#define glInvalidateSubFramebuffer gleswInvalidateSubFramebuffer -#define glTexStorage2D gleswTexStorage2D -#define glTexStorage3D gleswTexStorage3D -#define glGetInternalformativ gleswGetInternalformativ -#define glLabelObjectEXT gleswLabelObjectEXT -#define glGetObjectLabelEXT gleswGetObjectLabelEXT -#define glInsertEventMarkerEXT gleswInsertEventMarkerEXT -#define glPushGroupMarkerEXT gleswPushGroupMarkerEXT -#define glPopGroupMarkerEXT gleswPopGroupMarkerEXT -#define glUseProgramStagesEXT gleswUseProgramStagesEXT -#define glActiveShaderProgramEXT gleswActiveShaderProgramEXT -#define glCreateShaderProgramvEXT gleswCreateShaderProgramvEXT -#define glBindProgramPipelineEXT gleswBindProgramPipelineEXT -#define glDeleteProgramPipelinesEXT gleswDeleteProgramPipelinesEXT -#define glGenProgramPipelinesEXT gleswGenProgramPipelinesEXT -#define glIsProgramPipelineEXT gleswIsProgramPipelineEXT -#define glProgramParameteriEXT gleswProgramParameteriEXT -#define glGetProgramPipelineivEXT gleswGetProgramPipelineivEXT -#define glProgramUniform1iEXT gleswProgramUniform1iEXT -#define glProgramUniform2iEXT gleswProgramUniform2iEXT -#define glProgramUniform3iEXT gleswProgramUniform3iEXT -#define glProgramUniform4iEXT gleswProgramUniform4iEXT -#define glProgramUniform1fEXT gleswProgramUniform1fEXT -#define glProgramUniform2fEXT gleswProgramUniform2fEXT -#define glProgramUniform3fEXT gleswProgramUniform3fEXT -#define glProgramUniform4fEXT gleswProgramUniform4fEXT -#define glProgramUniform1ivEXT gleswProgramUniform1ivEXT -#define glProgramUniform2ivEXT gleswProgramUniform2ivEXT -#define glProgramUniform3ivEXT gleswProgramUniform3ivEXT -#define glProgramUniform4ivEXT gleswProgramUniform4ivEXT -#define glProgramUniform1fvEXT gleswProgramUniform1fvEXT -#define glProgramUniform2fvEXT gleswProgramUniform2fvEXT -#define glProgramUniform3fvEXT gleswProgramUniform3fvEXT -#define glProgramUniform4fvEXT gleswProgramUniform4fvEXT -#define glProgramUniformMatrix2fvEXT gleswProgramUniformMatrix2fvEXT -#define glProgramUniformMatrix3fvEXT gleswProgramUniformMatrix3fvEXT -#define glProgramUniformMatrix4fvEXT gleswProgramUniformMatrix4fvEXT -#define glProgramUniformMatrix2x3fvEXT gleswProgramUniformMatrix2x3fvEXT -#define glProgramUniformMatrix3x2fvEXT gleswProgramUniformMatrix3x2fvEXT -#define glProgramUniformMatrix2x4fvEXT gleswProgramUniformMatrix2x4fvEXT -#define glProgramUniformMatrix4x2fvEXT gleswProgramUniformMatrix4x2fvEXT -#define glProgramUniformMatrix3x4fvEXT gleswProgramUniformMatrix3x4fvEXT -#define glProgramUniformMatrix4x3fvEXT gleswProgramUniformMatrix4x3fvEXT -#define glValidateProgramPipelineEXT gleswValidateProgramPipelineEXT -#define glGetProgramPipelineInfoLogEXT gleswGetProgramPipelineInfoLogEXT +#define glActiveTexture gleswActiveTexture +#define glAttachShader gleswAttachShader +#define glBindAttribLocation gleswBindAttribLocation +#define glBindBuffer gleswBindBuffer +#define glBindFramebuffer gleswBindFramebuffer +#define glBindRenderbuffer gleswBindRenderbuffer +#define glBindTexture gleswBindTexture +#define glBlendColor gleswBlendColor +#define glBlendEquation gleswBlendEquation +#define glBlendEquationSeparate gleswBlendEquationSeparate +#define glBlendFunc gleswBlendFunc +#define glBlendFuncSeparate gleswBlendFuncSeparate +#define glBufferData gleswBufferData +#define glBufferSubData gleswBufferSubData +#define glCheckFramebufferStatus gleswCheckFramebufferStatus +#define glClear gleswClear +#define glClearColor gleswClearColor +#define glClearDepthf gleswClearDepthf +#define glClearStencil gleswClearStencil +#define glColorMask gleswColorMask +#define glCompileShader gleswCompileShader +#define glCompressedTexImage2D gleswCompressedTexImage2D +#define glCompressedTexSubImage2D gleswCompressedTexSubImage2D +#define glCopyTexImage2D gleswCopyTexImage2D +#define glCopyTexSubImage2D gleswCopyTexSubImage2D +#define glCreateProgram gleswCreateProgram +#define glCreateShader gleswCreateShader +#define glCullFace gleswCullFace +#define glDeleteBuffers gleswDeleteBuffers +#define glDeleteFramebuffers gleswDeleteFramebuffers +#define glDeleteProgram gleswDeleteProgram +#define glDeleteRenderbuffers gleswDeleteRenderbuffers +#define glDeleteShader gleswDeleteShader +#define glDeleteTextures gleswDeleteTextures +#define glDepthFunc gleswDepthFunc +#define glDepthMask gleswDepthMask +#define glDepthRangef gleswDepthRangef +#define glDetachShader gleswDetachShader +#define glDisable gleswDisable +#define glDisableVertexAttribArray gleswDisableVertexAttribArray +#define glDrawArrays gleswDrawArrays +#define glDrawElements gleswDrawElements +#define glEnable gleswEnable +#define glEnableVertexAttribArray gleswEnableVertexAttribArray +#define glFinish gleswFinish +#define glFlush gleswFlush +#define glFramebufferRenderbuffer gleswFramebufferRenderbuffer +#define glFramebufferTexture2D gleswFramebufferTexture2D +#define glFrontFace gleswFrontFace +#define glGenBuffers gleswGenBuffers +#define glGenerateMipmap gleswGenerateMipmap +#define glGenFramebuffers gleswGenFramebuffers +#define glGenRenderbuffers gleswGenRenderbuffers +#define glGenTextures gleswGenTextures +#define glGetActiveAttrib gleswGetActiveAttrib +#define glGetActiveUniform gleswGetActiveUniform +#define glGetAttachedShaders gleswGetAttachedShaders +#define glGetAttribLocation gleswGetAttribLocation +#define glGetBooleanv gleswGetBooleanv +#define glGetBufferParameteriv gleswGetBufferParameteriv +#define glGetError gleswGetError +#define glGetFloatv gleswGetFloatv +#define glGetFramebufferAttachmentParameteriv gleswGetFramebufferAttachmentParameteriv +#define glGetIntegerv gleswGetIntegerv +#define glGetProgramiv gleswGetProgramiv +#define glGetProgramInfoLog gleswGetProgramInfoLog +#define glGetRenderbufferParameteriv gleswGetRenderbufferParameteriv +#define glGetShaderiv gleswGetShaderiv +#define glGetShaderInfoLog gleswGetShaderInfoLog +#define glGetShaderPrecisionFormat gleswGetShaderPrecisionFormat +#define glGetShaderSource gleswGetShaderSource +#define glGetString gleswGetString +#define glGetTexParameterfv gleswGetTexParameterfv +#define glGetTexParameteriv gleswGetTexParameteriv +#define glGetUniformfv gleswGetUniformfv +#define glGetUniformiv gleswGetUniformiv +#define glGetUniformLocation gleswGetUniformLocation +#define glGetVertexAttribfv gleswGetVertexAttribfv +#define glGetVertexAttribiv gleswGetVertexAttribiv +#define glGetVertexAttribPointerv gleswGetVertexAttribPointerv +#define glHint gleswHint +#define glIsBuffer gleswIsBuffer +#define glIsEnabled gleswIsEnabled +#define glIsFramebuffer gleswIsFramebuffer +#define glIsProgram gleswIsProgram +#define glIsRenderbuffer gleswIsRenderbuffer +#define glIsShader gleswIsShader +#define glIsTexture gleswIsTexture +#define glLineWidth gleswLineWidth +#define glLinkProgram gleswLinkProgram +#define glPixelStorei gleswPixelStorei +#define glPolygonOffset gleswPolygonOffset +#define glReadPixels gleswReadPixels +#define glReleaseShaderCompiler gleswReleaseShaderCompiler +#define glRenderbufferStorage gleswRenderbufferStorage +#define glSampleCoverage gleswSampleCoverage +#define glScissor gleswScissor +#define glShaderBinary gleswShaderBinary +#define glShaderSource gleswShaderSource +#define glStencilFunc gleswStencilFunc +#define glStencilFuncSeparate gleswStencilFuncSeparate +#define glStencilMask gleswStencilMask +#define glStencilMaskSeparate gleswStencilMaskSeparate +#define glStencilOp gleswStencilOp +#define glStencilOpSeparate gleswStencilOpSeparate +#define glTexImage2D gleswTexImage2D +#define glTexParameterf gleswTexParameterf +#define glTexParameterfv gleswTexParameterfv +#define glTexParameteri gleswTexParameteri +#define glTexParameteriv gleswTexParameteriv +#define glTexSubImage2D gleswTexSubImage2D +#define glUniform1f gleswUniform1f +#define glUniform1fv gleswUniform1fv +#define glUniform1i gleswUniform1i +#define glUniform1iv gleswUniform1iv +#define glUniform2f gleswUniform2f +#define glUniform2fv gleswUniform2fv +#define glUniform2i gleswUniform2i +#define glUniform2iv gleswUniform2iv +#define glUniform3f gleswUniform3f +#define glUniform3fv gleswUniform3fv +#define glUniform3i gleswUniform3i +#define glUniform3iv gleswUniform3iv +#define glUniform4f gleswUniform4f +#define glUniform4fv gleswUniform4fv +#define glUniform4i gleswUniform4i +#define glUniform4iv gleswUniform4iv +#define glUniformMatrix2fv gleswUniformMatrix2fv +#define glUniformMatrix3fv gleswUniformMatrix3fv +#define glUniformMatrix4fv gleswUniformMatrix4fv +#define glUseProgram gleswUseProgram +#define glValidateProgram gleswValidateProgram +#define glVertexAttrib1f gleswVertexAttrib1f +#define glVertexAttrib1fv gleswVertexAttrib1fv +#define glVertexAttrib2f gleswVertexAttrib2f +#define glVertexAttrib2fv gleswVertexAttrib2fv +#define glVertexAttrib3f gleswVertexAttrib3f +#define glVertexAttrib3fv gleswVertexAttrib3fv +#define glVertexAttrib4f gleswVertexAttrib4f +#define glVertexAttrib4fv gleswVertexAttrib4fv +#define glVertexAttribPointer gleswVertexAttribPointer +#define glViewport gleswViewport +#define glReadBuffer gleswReadBuffer +#define glDrawRangeElements gleswDrawRangeElements +#define glTexImage3D gleswTexImage3D +#define glTexSubImage3D gleswTexSubImage3D +#define glCopyTexSubImage3D gleswCopyTexSubImage3D +#define glCompressedTexImage3D gleswCompressedTexImage3D +#define glCompressedTexSubImage3D gleswCompressedTexSubImage3D +#define glGenQueries gleswGenQueries +#define glDeleteQueries gleswDeleteQueries +#define glIsQuery gleswIsQuery +#define glBeginQuery gleswBeginQuery +#define glEndQuery gleswEndQuery +#define glGetQueryiv gleswGetQueryiv +#define glGetQueryObjectuiv gleswGetQueryObjectuiv +#define glUnmapBuffer gleswUnmapBuffer +#define glGetBufferPointerv gleswGetBufferPointerv +#define glDrawBuffers gleswDrawBuffers +#define glUniformMatrix2x3fv gleswUniformMatrix2x3fv +#define glUniformMatrix3x2fv gleswUniformMatrix3x2fv +#define glUniformMatrix2x4fv gleswUniformMatrix2x4fv +#define glUniformMatrix4x2fv gleswUniformMatrix4x2fv +#define glUniformMatrix3x4fv gleswUniformMatrix3x4fv +#define glUniformMatrix4x3fv gleswUniformMatrix4x3fv +#define glBlitFramebuffer gleswBlitFramebuffer +#define glRenderbufferStorageMultisample gleswRenderbufferStorageMultisample +#define glFramebufferTextureLayer gleswFramebufferTextureLayer +#define glMapBufferRange gleswMapBufferRange +#define glFlushMappedBufferRange gleswFlushMappedBufferRange +#define glBindVertexArray gleswBindVertexArray +#define glDeleteVertexArrays gleswDeleteVertexArrays +#define glGenVertexArrays gleswGenVertexArrays +#define glIsVertexArray gleswIsVertexArray +#define glGetIntegeri_v gleswGetIntegeri_v +#define glBeginTransformFeedback gleswBeginTransformFeedback +#define glEndTransformFeedback gleswEndTransformFeedback +#define glBindBufferRange gleswBindBufferRange +#define glBindBufferBase gleswBindBufferBase +#define glTransformFeedbackVaryings gleswTransformFeedbackVaryings +#define glGetTransformFeedbackVarying gleswGetTransformFeedbackVarying +#define glVertexAttribIPointer gleswVertexAttribIPointer +#define glGetVertexAttribIiv gleswGetVertexAttribIiv +#define glGetVertexAttribIuiv gleswGetVertexAttribIuiv +#define glVertexAttribI4i gleswVertexAttribI4i +#define glVertexAttribI4ui gleswVertexAttribI4ui +#define glVertexAttribI4iv gleswVertexAttribI4iv +#define glVertexAttribI4uiv gleswVertexAttribI4uiv +#define glGetUniformuiv gleswGetUniformuiv +#define glGetFragDataLocation gleswGetFragDataLocation +#define glUniform1ui gleswUniform1ui +#define glUniform2ui gleswUniform2ui +#define glUniform3ui gleswUniform3ui +#define glUniform4ui gleswUniform4ui +#define glUniform1uiv gleswUniform1uiv +#define glUniform2uiv gleswUniform2uiv +#define glUniform3uiv gleswUniform3uiv +#define glUniform4uiv gleswUniform4uiv +#define glClearBufferiv gleswClearBufferiv +#define glClearBufferuiv gleswClearBufferuiv +#define glClearBufferfv gleswClearBufferfv +#define glClearBufferfi gleswClearBufferfi +#define glGetStringi gleswGetStringi +#define glCopyBufferSubData gleswCopyBufferSubData +#define glGetUniformIndices gleswGetUniformIndices +#define glGetActiveUniformsiv gleswGetActiveUniformsiv +#define glGetUniformBlockIndex gleswGetUniformBlockIndex +#define glGetActiveUniformBlockiv gleswGetActiveUniformBlockiv +#define glGetActiveUniformBlockName gleswGetActiveUniformBlockName +#define glUniformBlockBinding gleswUniformBlockBinding +#define glDrawArraysInstanced gleswDrawArraysInstanced +#define glDrawElementsInstanced gleswDrawElementsInstanced +#define glFenceSync gleswFenceSync +#define glIsSync gleswIsSync +#define glDeleteSync gleswDeleteSync +#define glClientWaitSync gleswClientWaitSync +#define glWaitSync gleswWaitSync +#define glGetInteger64v gleswGetInteger64v +#define glGetSynciv gleswGetSynciv +#define glGetInteger64i_v gleswGetInteger64i_v +#define glGetBufferParameteri64v gleswGetBufferParameteri64v +#define glGenSamplers gleswGenSamplers +#define glDeleteSamplers gleswDeleteSamplers +#define glIsSampler gleswIsSampler +#define glBindSampler gleswBindSampler +#define glSamplerParameteri gleswSamplerParameteri +#define glSamplerParameteriv gleswSamplerParameteriv +#define glSamplerParameterf gleswSamplerParameterf +#define glSamplerParameterfv gleswSamplerParameterfv +#define glGetSamplerParameteriv gleswGetSamplerParameteriv +#define glGetSamplerParameterfv gleswGetSamplerParameterfv +#define glVertexAttribDivisor gleswVertexAttribDivisor +#define glBindTransformFeedback gleswBindTransformFeedback +#define glDeleteTransformFeedbacks gleswDeleteTransformFeedbacks +#define glGenTransformFeedbacks gleswGenTransformFeedbacks +#define glIsTransformFeedback gleswIsTransformFeedback +#define glPauseTransformFeedback gleswPauseTransformFeedback +#define glResumeTransformFeedback gleswResumeTransformFeedback +#define glGetProgramBinary gleswGetProgramBinary +#define glProgramBinary gleswProgramBinary +#define glProgramParameteri gleswProgramParameteri +#define glInvalidateFramebuffer gleswInvalidateFramebuffer +#define glInvalidateSubFramebuffer gleswInvalidateSubFramebuffer +#define glTexStorage2D gleswTexStorage2D +#define glTexStorage3D gleswTexStorage3D +#define glGetInternalformativ gleswGetInternalformativ +#define glLabelObjectEXT gleswLabelObjectEXT +#define glGetObjectLabelEXT gleswGetObjectLabelEXT +#define glInsertEventMarkerEXT gleswInsertEventMarkerEXT +#define glPushGroupMarkerEXT gleswPushGroupMarkerEXT +#define glPopGroupMarkerEXT gleswPopGroupMarkerEXT +#define glUseProgramStagesEXT gleswUseProgramStagesEXT +#define glActiveShaderProgramEXT gleswActiveShaderProgramEXT +#define glCreateShaderProgramvEXT gleswCreateShaderProgramvEXT +#define glBindProgramPipelineEXT gleswBindProgramPipelineEXT +#define glDeleteProgramPipelinesEXT gleswDeleteProgramPipelinesEXT +#define glGenProgramPipelinesEXT gleswGenProgramPipelinesEXT +#define glIsProgramPipelineEXT gleswIsProgramPipelineEXT +#define glProgramParameteriEXT gleswProgramParameteriEXT +#define glGetProgramPipelineivEXT gleswGetProgramPipelineivEXT +#define glProgramUniform1iEXT gleswProgramUniform1iEXT +#define glProgramUniform2iEXT gleswProgramUniform2iEXT +#define glProgramUniform3iEXT gleswProgramUniform3iEXT +#define glProgramUniform4iEXT gleswProgramUniform4iEXT +#define glProgramUniform1fEXT gleswProgramUniform1fEXT +#define glProgramUniform2fEXT gleswProgramUniform2fEXT +#define glProgramUniform3fEXT gleswProgramUniform3fEXT +#define glProgramUniform4fEXT gleswProgramUniform4fEXT +#define glProgramUniform1ivEXT gleswProgramUniform1ivEXT +#define glProgramUniform2ivEXT gleswProgramUniform2ivEXT +#define glProgramUniform3ivEXT gleswProgramUniform3ivEXT +#define glProgramUniform4ivEXT gleswProgramUniform4ivEXT +#define glProgramUniform1fvEXT gleswProgramUniform1fvEXT +#define glProgramUniform2fvEXT gleswProgramUniform2fvEXT +#define glProgramUniform3fvEXT gleswProgramUniform3fvEXT +#define glProgramUniform4fvEXT gleswProgramUniform4fvEXT +#define glProgramUniformMatrix2fvEXT gleswProgramUniformMatrix2fvEXT +#define glProgramUniformMatrix3fvEXT gleswProgramUniformMatrix3fvEXT +#define glProgramUniformMatrix4fvEXT gleswProgramUniformMatrix4fvEXT +#define glProgramUniformMatrix2x3fvEXT gleswProgramUniformMatrix2x3fvEXT +#define glProgramUniformMatrix3x2fvEXT gleswProgramUniformMatrix3x2fvEXT +#define glProgramUniformMatrix2x4fvEXT gleswProgramUniformMatrix2x4fvEXT +#define glProgramUniformMatrix4x2fvEXT gleswProgramUniformMatrix4x2fvEXT +#define glProgramUniformMatrix3x4fvEXT gleswProgramUniformMatrix3x4fvEXT +#define glProgramUniformMatrix4x3fvEXT gleswProgramUniformMatrix4x3fvEXT +#define glValidateProgramPipelineEXT gleswValidateProgramPipelineEXT +#define glGetProgramPipelineInfoLogEXT gleswGetProgramPipelineInfoLogEXT #ifdef __cplusplus } diff --git a/RenderSystems/GLES2/include/NaCl/OgreNaClGLContext.h b/RenderSystems/GLES2/include/NaCl/OgreNaClGLContext.h index 2f7642d5049..205b8f89f56 100644 --- a/RenderSystems/GLES2/include/NaCl/OgreNaClGLContext.h +++ b/RenderSystems/GLES2/include/NaCl/OgreNaClGLContext.h @@ -38,8 +38,8 @@ namespace Ogre { class _OgrePrivate NaClGLContext : public GLES2Context, public pp::Graphics3DClient { - private: - const NaClGLSupport *mGLSupport; + private: + const NaClGLSupport *mGLSupport; const NaClWindow * mWindow; pp::Instance* mInstance; pp::CompletionCallback* mSwapCallback; @@ -50,7 +50,7 @@ namespace Ogre { NaClGLContext(const NaClWindow * window, const NaClGLSupport *glsupport, pp::Instance* instance, pp::CompletionCallback* swapCallback); virtual ~NaClGLContext(); - virtual void setCurrent(); + virtual void setCurrent(); virtual void endCurrent(); GLES2Context* clone() const; diff --git a/RenderSystems/GLES2/include/NaCl/OgreNaClGLSupport.h b/RenderSystems/GLES2/include/NaCl/OgreNaClGLSupport.h index 77c8e31eaa1..8d537431d6e 100644 --- a/RenderSystems/GLES2/include/NaCl/OgreNaClGLSupport.h +++ b/RenderSystems/GLES2/include/NaCl/OgreNaClGLSupport.h @@ -32,34 +32,34 @@ THE SOFTWARE. #include "OgreGLES2Support.h" namespace Ogre { - class GLES2PBuffer; - + class GLES2PBuffer; + class _OgrePrivate NaClGLSupport : public GLES2Support { public: NaClGLSupport(); virtual ~NaClGLSupport(); - void switchMode(uint& width, uint& height, short& frequency); - String getDisplayName(void); + void switchMode(uint& width, uint& height, short& frequency); + String getDisplayName(void); - RenderWindow* createWindow(bool autoCreateWindow, + RenderWindow* createWindow(bool autoCreateWindow, GLES2RenderSystem *renderSystem, const String& windowTitle); - - RenderWindow* newWindow(const String& name, - unsigned int width, unsigned int height, - bool fullScreen, - const NameValuePairList *miscParams = 0); - - void start(void); + + RenderWindow* newWindow(const String& name, + unsigned int width, unsigned int height, + bool fullScreen, + const NameValuePairList *miscParams = 0); + + void start(void); void stop(void); void addConfig(void); - void refreshConfig(void); + void refreshConfig(void); String validateConfig(void); void setConfigOption(const String &name, const String &value); void* getProcAddress(const Ogre::String& name); - }; + }; } #endif diff --git a/RenderSystems/GLES2/include/NaCl/OgreNaClWindow.h b/RenderSystems/GLES2/include/NaCl/OgreNaClWindow.h index d79c2df7362..3d2ff6de497 100644 --- a/RenderSystems/GLES2/include/NaCl/OgreNaClWindow.h +++ b/RenderSystems/GLES2/include/NaCl/OgreNaClWindow.h @@ -32,50 +32,50 @@ THE SOFTWARE. #include "OgreNaClGLSupport.h" namespace Ogre { - class NaClGLContext; - - + class NaClGLContext; + + class _OgrePrivate NaClWindow : public RenderWindow { - protected: - NaClGLSupport* mGLSupport; - NaClGLContext* mContext; + protected: + NaClGLSupport* mGLSupport; + NaClGLContext* mContext; pp::Instance* mInstance; pp::CompletionCallback* mSwapCallback; - bool mClosed; + bool mClosed; - void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); - void initNativeCreatedWindow(const NameValuePairList *miscParams); - void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); - void reposition(int left, int top); - void resize(unsigned int width, unsigned int height); - void windowMovedOrResized(); - void switchFullScreen(bool fullscreen); + void getLeftAndTopFromNativeWindow(int & left, int & top, uint width, uint height); + void initNativeCreatedWindow(const NameValuePairList *miscParams); + void createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ); + void reposition(int left, int top); + void resize(unsigned int width, unsigned int height); + void windowMovedOrResized(); + void switchFullScreen(bool fullscreen); - public: + public: NaClWindow(NaClGLSupport* glsupport); virtual ~NaClWindow(); - /** - @remarks - * Get custom attribute; the following attributes are valid: - * HANDLE The integer id of the android window - * GLCONTEXT The Ogre GLContext used for rendering. - */ - void getCustomAttribute(const String& name, void* pData); - - void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); - bool requiresTextureFlipping() const; - void destroy(void); - bool isClosed(void) const; + /** + @remarks + * Get custom attribute; the following attributes are valid: + * HANDLE The integer id of the android window + * GLCONTEXT The Ogre GLContext used for rendering. + */ + void getCustomAttribute(const String& name, void* pData); + + void copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer); + bool requiresTextureFlipping() const; + void destroy(void); + bool isClosed(void) const; void swapBuffers(); - //Moved this from EGLWindow because it has some native calls. + //Moved this from EGLWindow because it has some native calls. void create(const String& name, unsigned int width, unsigned int height, - bool fullScreen, const NameValuePairList *miscParams); - }; + bool fullScreen, const NameValuePairList *miscParams); + }; } #endif diff --git a/RenderSystems/GLES2/include/OgreGLES2Context.h b/RenderSystems/GLES2/include/OgreGLES2Context.h index 97cae5d82f1..a3c73d58645 100644 --- a/RenderSystems/GLES2/include/OgreGLES2Context.h +++ b/RenderSystems/GLES2/include/OgreGLES2Context.h @@ -64,10 +64,10 @@ namespace Ogre { */ virtual GLES2Context* clone() const = 0; - /** - * Release the render context. - */ - virtual void releaseContext() {} + /** + * Release the render context. + */ + virtual void releaseContext() {} protected: bool initialized; diff --git a/RenderSystems/GLES2/include/OgreGLES2DefaultHardwareBufferManager.h b/RenderSystems/GLES2/include/OgreGLES2DefaultHardwareBufferManager.h index 95465914828..ba9d8d234a5 100644 --- a/RenderSystems/GLES2/include/OgreGLES2DefaultHardwareBufferManager.h +++ b/RenderSystems/GLES2/include/OgreGLES2DefaultHardwareBufferManager.h @@ -145,7 +145,7 @@ namespace Ogre { HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name = ""); - HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, + HardwareCounterBufferSharedPtr createCounterBuffer(size_t sizeBytes, HardwareBuffer::Usage usage = HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, bool useShadowBuffer = false, const String& name = "") { @@ -155,19 +155,19 @@ namespace Ogre { } }; - /// GLES2DefaultHardwareBufferManagerBase as a Singleton - class _OgreGLES2Export GLES2DefaultHardwareBufferManager : public HardwareBufferManager - { - public: - GLES2DefaultHardwareBufferManager() - : HardwareBufferManager(OGRE_NEW GLES2DefaultHardwareBufferManagerBase()) - { - - } - ~GLES2DefaultHardwareBufferManager() - { - OGRE_DELETE mImpl; - } + /// GLES2DefaultHardwareBufferManagerBase as a Singleton + class _OgreGLES2Export GLES2DefaultHardwareBufferManager : public HardwareBufferManager + { + public: + GLES2DefaultHardwareBufferManager() + : HardwareBufferManager(OGRE_NEW GLES2DefaultHardwareBufferManagerBase()) + { + + } + ~GLES2DefaultHardwareBufferManager() + { + OGRE_DELETE mImpl; + } HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage,bool useShadowBuffer, const String& name = "") { diff --git a/RenderSystems/GLES2/include/OgreGLES2DepthBuffer.h b/RenderSystems/GLES2/include/OgreGLES2DepthBuffer.h index bf6ef321ce8..1c5c5ec537e 100644 --- a/RenderSystems/GLES2/include/OgreGLES2DepthBuffer.h +++ b/RenderSystems/GLES2/include/OgreGLES2DepthBuffer.h @@ -37,39 +37,39 @@ namespace Ogre class GLES2Context; class GLES2RenderBuffer; class GLES2RenderSystem; - /** - @copydoc DepthBuffer + /** + @copydoc DepthBuffer - OpenGL supports 2 different methods: FBO & Copy. - Each one has it's own limitations. Non-FBO methods are solved using "dummy" DepthBuffers. - That is, a DepthBuffer pointer is attached to the RenderTarget (for the sake of consistency) - but it doesn't actually contain a Depth surface/renderbuffer (mDepthBuffer & mStencilBuffer are - null pointers all the time) Those dummy DepthBuffers are identified thanks to their GL context. - Note that FBOs don't allow sharing with the main window's depth buffer. Therefore even - when FBO is enabled, a dummy DepthBuffer is still used to manage the windows. - */ - class _OgreGLES2Export GLES2DepthBuffer : public DepthBuffer - { - public: - GLES2DepthBuffer( uint16 poolId, GLES2RenderSystem *renderSystem, GLES2Context *creatorContext, - GLES2RenderBuffer *depth, GLES2RenderBuffer *stencil, - uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, - bool isManual ); - ~GLES2DepthBuffer(); + OpenGL supports 2 different methods: FBO & Copy. + Each one has it's own limitations. Non-FBO methods are solved using "dummy" DepthBuffers. + That is, a DepthBuffer pointer is attached to the RenderTarget (for the sake of consistency) + but it doesn't actually contain a Depth surface/renderbuffer (mDepthBuffer & mStencilBuffer are + null pointers all the time) Those dummy DepthBuffers are identified thanks to their GL context. + Note that FBOs don't allow sharing with the main window's depth buffer. Therefore even + when FBO is enabled, a dummy DepthBuffer is still used to manage the windows. + */ + class _OgreGLES2Export GLES2DepthBuffer : public DepthBuffer + { + public: + GLES2DepthBuffer( uint16 poolId, GLES2RenderSystem *renderSystem, GLES2Context *creatorContext, + GLES2RenderBuffer *depth, GLES2RenderBuffer *stencil, + uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, + bool isManual ); + ~GLES2DepthBuffer(); - /// @copydoc DepthBuffer::isCompatible - virtual bool isCompatible( RenderTarget *renderTarget ) const; + /// @copydoc DepthBuffer::isCompatible + virtual bool isCompatible( RenderTarget *renderTarget ) const; - GLES2Context* getGLContext() const { return mCreatorContext; } - GLES2RenderBuffer* getDepthBuffer() const { return mDepthBuffer; } - GLES2RenderBuffer* getStencilBuffer() const { return mStencilBuffer; } + GLES2Context* getGLContext() const { return mCreatorContext; } + GLES2RenderBuffer* getDepthBuffer() const { return mDepthBuffer; } + GLES2RenderBuffer* getStencilBuffer() const { return mStencilBuffer; } - protected: - uint32 mMultiSampleQuality; - GLES2Context *mCreatorContext; - GLES2RenderBuffer *mDepthBuffer; - GLES2RenderBuffer *mStencilBuffer; - GLES2RenderSystem *mRenderSystem; - }; + protected: + uint32 mMultiSampleQuality; + GLES2Context *mCreatorContext; + GLES2RenderBuffer *mDepthBuffer; + GLES2RenderBuffer *mStencilBuffer; + GLES2RenderSystem *mRenderSystem; + }; } #endif diff --git a/RenderSystems/GLES2/include/OgreGLES2FBOMultiRenderTarget.h b/RenderSystems/GLES2/include/OgreGLES2FBOMultiRenderTarget.h index 0108ad7a32a..8bc800d48cf 100644 --- a/RenderSystems/GLES2/include/OgreGLES2FBOMultiRenderTarget.h +++ b/RenderSystems/GLES2/include/OgreGLES2FBOMultiRenderTarget.h @@ -35,27 +35,27 @@ namespace Ogre { class GLES2FBOManager; - /** MultiRenderTarget for GL ES 2.x. - */ - class _OgreGLES2Export GLES2FBOMultiRenderTarget : public MultiRenderTarget - { - public: - GLES2FBOMultiRenderTarget(GLES2FBOManager *manager, const String &name); - ~GLES2FBOMultiRenderTarget(); - - virtual void getCustomAttribute( const String& name, void *pData ); - - bool requiresTextureFlipping() const { return true; } - - /// Override so we can attach the depth buffer to the FBO - virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); - virtual void detachDepthBuffer(); - virtual void _detachDepthBuffer(); - private: - virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); - virtual void unbindSurfaceImpl(size_t attachment); - GLES2FrameBufferObject fbo; - }; + /** MultiRenderTarget for GL ES 2.x. + */ + class _OgreGLES2Export GLES2FBOMultiRenderTarget : public MultiRenderTarget + { + public: + GLES2FBOMultiRenderTarget(GLES2FBOManager *manager, const String &name); + ~GLES2FBOMultiRenderTarget(); + + virtual void getCustomAttribute( const String& name, void *pData ); + + bool requiresTextureFlipping() const { return true; } + + /// Override so we can attach the depth buffer to the FBO + virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); + virtual void detachDepthBuffer(); + virtual void _detachDepthBuffer(); + private: + virtual void bindSurfaceImpl(size_t attachment, RenderTexture *target); + virtual void unbindSurfaceImpl(size_t attachment); + GLES2FrameBufferObject fbo; + }; } diff --git a/RenderSystems/GLES2/include/OgreGLES2FBORenderTexture.h b/RenderSystems/GLES2/include/OgreGLES2FBORenderTexture.h index 5ab4ed20a1b..21f711a8978 100644 --- a/RenderSystems/GLES2/include/OgreGLES2FBORenderTexture.h +++ b/RenderSystems/GLES2/include/OgreGLES2FBORenderTexture.h @@ -46,13 +46,13 @@ namespace Ogre { virtual void getCustomAttribute(const String& name, void* pData); - /// Override needed to deal with multisample buffers - virtual void swapBuffers(); + /// Override needed to deal with multisample buffers + virtual void swapBuffers(); - /// Override so we can attach the depth buffer to the FBO - virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); - virtual void detachDepthBuffer(); - virtual void _detachDepthBuffer(); + /// Override so we can attach the depth buffer to the FBO + virtual bool attachDepthBuffer( DepthBuffer *depthBuffer ); + virtual void detachDepthBuffer(); + virtual void _detachDepthBuffer(); protected: GLES2FrameBufferObject mFB; @@ -71,7 +71,7 @@ namespace Ogre { { public: GLES2FBOManager(); - ~GLES2FBOManager(); + ~GLES2FBOManager(); /** Bind a certain render target if it is a FBO. If it is not a FBO, bind the main frame buffer. @@ -89,11 +89,11 @@ namespace Ogre { /** Create a texture rendertarget object */ virtual GLES2FBORenderTexture *createRenderTexture(const String &name, - const GLES2SurfaceDesc &target, bool writeGamma, uint fsaa); + const GLES2SurfaceDesc &target, bool writeGamma, uint fsaa); - /** Create a multi render target - */ - virtual MultiRenderTarget* createMultiRenderTarget(const String & name); + /** Create a multi render target + */ + virtual MultiRenderTarget* createMultiRenderTarget(const String & name); /** Request a render buffer. If format is GL_NONE, return a zero buffer. */ @@ -150,7 +150,7 @@ namespace Ogre { GLenum format; size_t width; size_t height; - uint samples; + uint samples; // Overloaded comparison operator for usage in map bool operator < (const RBFormat &other) const { @@ -168,11 +168,11 @@ namespace Ogre { { if(height < other.height) return true; - else if (height == other.height) - { - if (samples < other.samples) - return true; - } + else if (height == other.height) + { + if (samples < other.samples) + return true; + } } } return false; diff --git a/RenderSystems/GLES2/include/OgreGLES2FrameBufferObject.h b/RenderSystems/GLES2/include/OgreGLES2FrameBufferObject.h index 3ed2b839f36..1d02346c60b 100644 --- a/RenderSystems/GLES2/include/OgreGLES2FrameBufferObject.h +++ b/RenderSystems/GLES2/include/OgreGLES2FrameBufferObject.h @@ -57,26 +57,26 @@ namespace Ogre { */ void bind(); - /** Swap buffers - only useful when using multisample buffers. - */ - void swapBuffers(); + /** Swap buffers - only useful when using multisample buffers. + */ + void swapBuffers(); /** This function acts very similar to @see GLES2FBORenderTexture::attachDepthBuffer - The difference between D3D & OGL is that D3D setups the DepthBuffer before rendering, - while OGL setups the DepthBuffer per FBO. So the DepthBuffer (RenderBuffer) needs to - be attached for OGL. - */ - void attachDepthBuffer( DepthBuffer *depthBuffer ); - void detachDepthBuffer(); + The difference between D3D & OGL is that D3D setups the DepthBuffer before rendering, + while OGL setups the DepthBuffer per FBO. So the DepthBuffer (RenderBuffer) needs to + be attached for OGL. + */ + void attachDepthBuffer( DepthBuffer *depthBuffer ); + void detachDepthBuffer(); /// Accessors uint32 getWidth(); uint32 getHeight(); PixelFormat getFormat(); - GLsizei getFSAA(); + GLsizei getFSAA(); GLES2FBOManager *getManager() { return mManager; } - const GLES2SurfaceDesc &getSurface(size_t attachment) { return mColour[attachment]; } + const GLES2SurfaceDesc &getSurface(size_t attachment) { return mColour[attachment]; } #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID /** See AndroidResource. */ @@ -88,17 +88,17 @@ namespace Ogre { private: GLES2FBOManager *mManager; - GLsizei mNumSamples; + GLsizei mNumSamples; GLuint mFB; - GLuint mMultisampleFB; - GLES2SurfaceDesc mMultisampleColourBuffer; + GLuint mMultisampleFB; + GLES2SurfaceDesc mMultisampleColourBuffer; GLES2SurfaceDesc mDepth; GLES2SurfaceDesc mStencil; // Arbitrary number of texture surfaces GLES2SurfaceDesc mColour[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - /** Initialise object (find suitable depth and stencil format). + /** Initialise object (find suitable depth and stencil format). Must be called every time the bindings change. It fails with an exception (ERR_INVALIDPARAMS) if: - Attachment point 0 has no binding diff --git a/RenderSystems/GLES2/include/OgreGLES2GpuProgram.h b/RenderSystems/GLES2/include/OgreGLES2GpuProgram.h index fe3faf3d275..093d39a7e81 100644 --- a/RenderSystems/GLES2/include/OgreGLES2GpuProgram.h +++ b/RenderSystems/GLES2/include/OgreGLES2GpuProgram.h @@ -49,11 +49,11 @@ namespace Ogre { virtual void unbindProgram(void) {} /// Execute the param binding functions for this program - virtual void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask) {} - /// Bind just the pass iteration parameters - virtual void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) {} - /// Execute the shared param binding functions for this program - virtual void bindProgramSharedParameters(GpuProgramParametersSharedPtr params, uint16 mask) {} + virtual void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask) {} + /// Bind just the pass iteration parameters + virtual void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) {} + /// Execute the shared param binding functions for this program + virtual void bindProgramSharedParameters(GpuProgramParametersSharedPtr params, uint16 mask) {} /// @copydoc Resource::calculateSize virtual size_t calculateSize(void) const; @@ -63,8 +63,8 @@ namespace Ogre { { return mProgramID; } protected: - /** Overridden from GpuProgram, do nothing */ - void loadFromSource(void) {} + /** Overridden from GpuProgram, do nothing */ + void loadFromSource(void) {} /// @copydoc Resource::unloadImpl void unloadImpl(void) {} diff --git a/RenderSystems/GLES2/include/OgreGLES2HardwareBufferManager.h b/RenderSystems/GLES2/include/OgreGLES2HardwareBufferManager.h index cc54bfa2693..ce7566030e6 100644 --- a/RenderSystems/GLES2/include/OgreGLES2HardwareBufferManager.h +++ b/RenderSystems/GLES2/include/OgreGLES2HardwareBufferManager.h @@ -33,13 +33,13 @@ THE SOFTWARE. #include "OgreHardwareBufferManager.h" namespace Ogre { - class GLES2StateCacheManager; + class GLES2StateCacheManager; /** Implementation of HardwareBufferManager for OpenGL ES. */ class _OgreGLES2Export GLES2HardwareBufferManagerBase : public HardwareBufferManagerBase { protected: - GLES2StateCacheManager* mStateCacheManager; + GLES2StateCacheManager* mStateCacheManager; /// Internal method for creates a new vertex declaration, may be overridden by certain rendering APIs VertexDeclaration* createVertexDeclarationImpl(void); /// Internal method for destroys a vertex declaration, may be overridden by certain rendering APIs @@ -55,8 +55,8 @@ namespace Ogre { HardwareIndexBufferSharedPtr createIndexBuffer( HardwareIndexBuffer::IndexType itype, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer = false); - /// Create a render to vertex buffer - RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); + /// Create a render to vertex buffer + RenderToVertexBufferSharedPtr createRenderToVertexBuffer(); HardwareUniformBufferSharedPtr createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name = ""); /// Create a uniform buffer @@ -72,31 +72,31 @@ namespace Ogre { /// Utility function to get the correct GL type based on VET's static GLenum getGLType(unsigned int type); - GLES2StateCacheManager * getStateCacheManager() { return mStateCacheManager; } + GLES2StateCacheManager * getStateCacheManager() { return mStateCacheManager; } }; - /// GLES2HardwareBufferManagerBase as a Singleton - class _OgreGLES2Export GLES2HardwareBufferManager : public HardwareBufferManager - { - public: - GLES2HardwareBufferManager() - : HardwareBufferManager(OGRE_NEW GLES2HardwareBufferManagerBase()) - { - - } - ~GLES2HardwareBufferManager() - { - OGRE_DELETE mImpl; - } - - /// Utility function to get the correct GL usage based on HBU's - static GLenum getGLUsage(unsigned int usage) + /// GLES2HardwareBufferManagerBase as a Singleton + class _OgreGLES2Export GLES2HardwareBufferManager : public HardwareBufferManager + { + public: + GLES2HardwareBufferManager() + : HardwareBufferManager(OGRE_NEW GLES2HardwareBufferManagerBase()) + { + + } + ~GLES2HardwareBufferManager() + { + OGRE_DELETE mImpl; + } + + /// Utility function to get the correct GL usage based on HBU's + static GLenum getGLUsage(unsigned int usage) { return GLES2HardwareBufferManagerBase::getGLUsage(usage); } - /// Utility function to get the correct GL type based on VET's - static GLenum getGLType(unsigned int type) + /// Utility function to get the correct GL type based on VET's + static GLenum getGLType(unsigned int type) { return GLES2HardwareBufferManagerBase::getGLType(type); } - }; + }; } diff --git a/RenderSystems/GLES2/include/OgreGLES2HardwareOcclusionQuery.h b/RenderSystems/GLES2/include/OgreGLES2HardwareOcclusionQuery.h index 91608bb00e5..f21762e49a7 100644 --- a/RenderSystems/GLES2/include/OgreGLES2HardwareOcclusionQuery.h +++ b/RenderSystems/GLES2/include/OgreGLES2HardwareOcclusionQuery.h @@ -48,23 +48,23 @@ class _OgreGLES2Export GLES2HardwareOcclusionQuery : public HardwareOcclusionQue // Public methods //-- public: - /** - * Default object constructor - * - */ - GLES2HardwareOcclusionQuery(); - /** - * Object destructor - */ - ~GLES2HardwareOcclusionQuery(); - - //------------------------------------------------------------------ - // Occlusion query functions (see base class documentation for this) - //-- - void beginOcclusionQuery(); - void endOcclusionQuery(); - bool pullOcclusionQuery( unsigned int* NumOfFragments); - bool isStillOutstanding(void); + /** + * Default object constructor + * + */ + GLES2HardwareOcclusionQuery(); + /** + * Object destructor + */ + ~GLES2HardwareOcclusionQuery(); + + //------------------------------------------------------------------ + // Occlusion query functions (see base class documentation for this) + //-- + void beginOcclusionQuery(); + void endOcclusionQuery(); + bool pullOcclusionQuery( unsigned int* NumOfFragments); + bool isStillOutstanding(void); //---------------------------------------------------------------------- diff --git a/RenderSystems/GLES2/include/OgreGLES2Prerequisites.h b/RenderSystems/GLES2/include/OgreGLES2Prerequisites.h index 44ad7bcf6d2..34eb365671d 100644 --- a/RenderSystems/GLES2/include/OgreGLES2Prerequisites.h +++ b/RenderSystems/GLES2/include/OgreGLES2Prerequisites.h @@ -55,28 +55,28 @@ THE SOFTWARE. # endif # endif #elif (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) || (OGRE_PLATFORM == OGRE_PLATFORM_NACL) -# ifndef GL_GLEXT_PROTOTYPES -# define GL_GLEXT_PROTOTYPES -# endif +# ifndef GL_GLEXT_PROTOTYPES +# define GL_GLEXT_PROTOTYPES +# endif # if OGRE_NO_GLES3_SUPPORT == 0 # include -# include +# include # else # include -# include +# include # include # endif -# if (OGRE_PLATFORM == OGRE_PLATFORM_NACL) -# include "ppapi/cpp/completion_callback.h" +# if (OGRE_PLATFORM == OGRE_PLATFORM_NACL) +# include "ppapi/cpp/completion_callback.h" # include "ppapi/cpp/instance.h" # include "ppapi/c/ppp_graphics_3d.h" # include "ppapi/cpp/graphics_3d.h" # include "ppapi/cpp/graphics_3d_client.h" -# include "ppapi/gles2/gl2ext_ppapi.h" +# include "ppapi/gles2/gl2ext_ppapi.h" # undef GL_OES_get_program_binary # undef GL_OES_mapbuffer # undef GL_OES_vertex_array_object -# endif +# endif #else # if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) # if !defined( __MINGW32__ ) @@ -89,7 +89,7 @@ THE SOFTWARE. # endif # endif # endif -# undef GL_GLEXT_PROTOTYPES +# undef GL_GLEXT_PROTOTYPES # if OGRE_NO_GLES3_SUPPORT == 0 # include # include diff --git a/RenderSystems/GLES2/include/OgreGLES2RenderSystem.h b/RenderSystems/GLES2/include/OgreGLES2RenderSystem.h index c883d8ee013..4a6a49ce58a 100644 --- a/RenderSystems/GLES2/include/OgreGLES2RenderSystem.h +++ b/RenderSystems/GLES2/include/OgreGLES2RenderSystem.h @@ -82,9 +82,9 @@ namespace Ogre { /// GL support class, used for creating windows etc. GLES2Support *mGLSupport; - /// State cache manager which responsible to reduce redundant state changes + /// State cache manager which responsible to reduce redundant state changes GLES2StateCacheManager* mStateCacheManager; - + /* The main GL context - main thread only */ GLES2Context *mMainContext; @@ -130,8 +130,8 @@ namespace Ogre { vector::type &instanceAttribsBound, bool updateVAO); - // Mipmap count of the actual bounded texture - size_t mCurTexMipCount; + // Mipmap count of the actual bounded texture + size_t mCurTexMipCount; GLint mViewport[4]; GLint mScissor[4]; @@ -390,21 +390,21 @@ namespace Ogre { StencilOperation stencilFailOp = SOP_KEEP, StencilOperation depthFailOp = SOP_KEEP, StencilOperation passOp = SOP_KEEP, - bool twoSidedOperation = false, - bool readBackAsTexture = false); - /** See + bool twoSidedOperation = false, + bool readBackAsTexture = false); + /** See RenderSystem */ - void _setTextureUnitCompareFunction(size_t unit, CompareFunction function); - /** See + void _setTextureUnitCompareFunction(size_t unit, CompareFunction function); + /** See RenderSystem */ - void _setTextureUnitCompareEnabled(size_t unit, bool compare); - /** See + void _setTextureUnitCompareEnabled(size_t unit, bool compare); + /** See RenderSystem */ - virtual void _setTextureUnitFiltering(size_t unit, FilterOptions minFilter, - FilterOptions magFilter, FilterOptions mipFilter); + virtual void _setTextureUnitFiltering(size_t unit, FilterOptions minFilter, + FilterOptions magFilter, FilterOptions mipFilter); /** See RenderSystem */ @@ -416,7 +416,7 @@ namespace Ogre { /** See RenderSystem */ - virtual bool hasAnisotropicMipMapFilter() const { return false; } + virtual bool hasAnisotropicMipMapFilter() const { return false; } /** See RenderSystem */ @@ -489,14 +489,14 @@ namespace Ogre { void bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params, uint16 mask); void bindGpuProgramPassIterationParameters(GpuProgramType gptype); - /// @copydoc RenderSystem::_setSceneBlending - void _setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op ); - /// @copydoc RenderSystem::_setSeparateSceneBlending - void _setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ); - /// @copydoc RenderSystem::_setAlphaRejectSettings - void _setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ); - /// @copydoc RenderSystem::getDisplayMonitorCount - unsigned int getDisplayMonitorCount() const; + /// @copydoc RenderSystem::_setSceneBlending + void _setSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op ); + /// @copydoc RenderSystem::_setSeparateSceneBlending + void _setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ); + /// @copydoc RenderSystem::_setAlphaRejectSettings + void _setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage ); + /// @copydoc RenderSystem::getDisplayMonitorCount + unsigned int getDisplayMonitorCount() const; /// Internal method for anisotropy validation GLfloat _getCurrentAnisotropy(size_t unit); diff --git a/RenderSystems/GLES2/include/OgreGLES2RenderToVertexBuffer.h b/RenderSystems/GLES2/include/OgreGLES2RenderToVertexBuffer.h index 98ebb1253a0..1d5a7e51ef8 100644 --- a/RenderSystems/GLES2/include/OgreGLES2RenderToVertexBuffer.h +++ b/RenderSystems/GLES2/include/OgreGLES2RenderToVertexBuffer.h @@ -43,12 +43,12 @@ namespace Ogre { that run on previous results of those shaders, creating stateful shaders. */ - class _OgreGLES2Export GLES2RenderToVertexBuffer : public RenderToVertexBuffer + class _OgreGLES2Export GLES2RenderToVertexBuffer : public RenderToVertexBuffer { public: - /** C'tor */ - GLES2RenderToVertexBuffer(); - /** D'tor */ + /** C'tor */ + GLES2RenderToVertexBuffer(); + /** D'tor */ virtual ~GLES2RenderToVertexBuffer(); /** @@ -60,13 +60,13 @@ namespace Ogre { Update the contents of this vertex buffer by rendering */ virtual void update(SceneManager* sceneMgr); - protected: - void reallocateBuffer(size_t index); - void bindVerticesOutput(Pass* pass); - String getSemanticVaryingName(VertexElementSemantic semantic, unsigned short index); - HardwareVertexBufferSharedPtr mVertexBuffers[2]; - size_t mFrontBufferIndex; - GLuint mPrimitivesDrawnQuery; + protected: + void reallocateBuffer(size_t index); + void bindVerticesOutput(Pass* pass); + String getSemanticVaryingName(VertexElementSemantic semantic, unsigned short index); + HardwareVertexBufferSharedPtr mVertexBuffers[2]; + size_t mFrontBufferIndex; + GLuint mPrimitivesDrawnQuery; bool mFeedbackActive; }; } diff --git a/RenderSystems/GLES2/include/OgreGLES2StateCacheManager.h b/RenderSystems/GLES2/include/OgreGLES2StateCacheManager.h index 7286f5057ba..93a288e8255 100644 --- a/RenderSystems/GLES2/include/OgreGLES2StateCacheManager.h +++ b/RenderSystems/GLES2/include/OgreGLES2StateCacheManager.h @@ -35,7 +35,7 @@ typedef Ogre::GeneralAllocatedObject StateCacheAlloc; namespace Ogre { - class GLES2StateCacheManagerImp; + class GLES2StateCacheManagerImp; /** An in memory cache of the OpenGL ES state. @remarks @@ -53,13 +53,13 @@ namespace Ogre class _OgreGLES2Export GLES2StateCacheManager : public StateCacheAlloc { private: - GLES2StateCacheManagerImp* mImp; + GLES2StateCacheManagerImp* mImp; public: GLES2StateCacheManager(void); ~GLES2StateCacheManager(void); - /** Initialize our cache variables and sets the + /** Initialize our cache variables and sets the GL states on the current context. */ void initializeCache(); @@ -67,22 +67,22 @@ namespace Ogre /** Clears all cached values */ void clearCache(); - - /** Bind an OpenGL buffer of any type. + + /** Bind an OpenGL buffer of any type. @param target The buffer target. @param buffer The buffer ID. @param force Optional parameter to force an update. */ void bindGLBuffer(GLenum target, GLuint buffer, bool force = false); - /** Delete an OpenGL buffer of any type. + /** Delete an OpenGL buffer of any type. @param target The buffer target. @param buffer The buffer ID. @param force Optional parameter to force an update. */ void deleteGLBuffer(GLenum target, GLuint buffer, bool force = false); - /** Bind an OpenGL texture of any type. + /** Bind an OpenGL texture of any type. @param target The texture target. @param texture The texture ID. */ @@ -156,7 +156,7 @@ namespace Ogre */ void setDepthFunc(GLenum func); - /** Gets the clear depth in the range from [0..1]. + /** Gets the clear depth in the range from [0..1]. @return The current clearing depth. */ GLclampf getClearDepth(void) const; diff --git a/RenderSystems/GLES2/include/OgreGLES2Support.h b/RenderSystems/GLES2/include/OgreGLES2Support.h index 1792cb69779..06f4ba76cca 100644 --- a/RenderSystems/GLES2/include/OgreGLES2Support.h +++ b/RenderSystems/GLES2/include/OgreGLES2Support.h @@ -137,7 +137,7 @@ namespace Ogre return 1; } - /** + /** * Get the state cache manager */ GLES2StateCacheManager* getStateCacheManager() const @@ -152,7 +152,7 @@ namespace Ogre { mStateCacheMgr = stateCacheMgr; } - + /** * Start anything special */ @@ -174,9 +174,9 @@ namespace Ogre // This contains the complete list of supported extensions set::type extensionList; - - // State cache management - GLES2StateCacheManager* mStateCacheMgr; + + // State cache management + GLES2StateCacheManager* mStateCacheMgr; }; } diff --git a/RenderSystems/GLES2/include/OgreGLES2UniformCache.h b/RenderSystems/GLES2/include/OgreGLES2UniformCache.h index 0e0f402dc4b..bc3094da7eb 100644 --- a/RenderSystems/GLES2/include/OgreGLES2UniformCache.h +++ b/RenderSystems/GLES2/include/OgreGLES2UniformCache.h @@ -35,13 +35,13 @@ typedef Ogre::GeneralAllocatedObject UniformCacheAlloc; namespace Ogre { - class GLES2UniformCacheImp; + class GLES2UniformCacheImp; /** An in memory cache of the OpenGL ES 2 uniforms. */ class _OgreGLES2Export GLES2UniformCache : public UniformCacheAlloc { private: - GLES2UniformCacheImp* mImp; + GLES2UniformCacheImp* mImp; public: GLES2UniformCache(void); @@ -50,7 +50,7 @@ namespace Ogre /** Clears all cached values */ void clearCache(); - + /** Update a uniform @return A boolean value indicating whether this uniform needs to be updated in the GL. */ diff --git a/RenderSystems/GLES2/include/OgreGLES2VertexDeclaration.h b/RenderSystems/GLES2/include/OgreGLES2VertexDeclaration.h index e23bc866260..90d75b0b4de 100644 --- a/RenderSystems/GLES2/include/OgreGLES2VertexDeclaration.h +++ b/RenderSystems/GLES2/include/OgreGLES2VertexDeclaration.h @@ -33,21 +33,21 @@ THE SOFTWARE. namespace Ogre { - /** Specialisation of VertexDeclaration for OpenGL ES 2 Vertex Array Object usage */ - class GLES2VertexDeclaration : public VertexDeclaration - { - protected: + /** Specialisation of VertexDeclaration for OpenGL ES 2 Vertex Array Object usage */ + class GLES2VertexDeclaration : public VertexDeclaration + { + protected: /// OpenGL id for the vertex array object GLuint mVAO; bool mIsInitialised; - public: - GLES2VertexDeclaration(); - ~GLES2VertexDeclaration(); + public: + GLES2VertexDeclaration(); + ~GLES2VertexDeclaration(); void bind(void); bool isInitialised(void) { return mIsInitialised; } void setInitialised(bool flag) { mIsInitialised = flag; } - }; + }; } diff --git a/RenderSystems/GLES2/src/EGL/Android/OgreAndroidEGLSupport.cpp b/RenderSystems/GLES2/src/EGL/Android/OgreAndroidEGLSupport.cpp index 880792285e9..d6fb22f2a63 100644 --- a/RenderSystems/GLES2/src/EGL/Android/OgreAndroidEGLSupport.cpp +++ b/RenderSystems/GLES2/src/EGL/Android/OgreAndroidEGLSupport.cpp @@ -46,10 +46,10 @@ namespace Ogre { mGLDisplay = getGLDisplay(); mCurrentMode.first.first = 1280; - mCurrentMode.first.second = 800; - mCurrentMode.second = 0; - mOriginalMode = mCurrentMode; - mVideoModes.push_back(mCurrentMode); + mCurrentMode.first.second = 800; + mCurrentMode.second = 0; + mOriginalMode = mCurrentMode; + mVideoModes.push_back(mCurrentMode); ConfigOption optOrientation; optOrientation.name = "Orientation"; @@ -64,19 +64,19 @@ namespace Ogre { AndroidEGLSupport::~AndroidEGLSupport() { - } + } void AndroidEGLSupport::switchMode( uint& width, uint& height, short& frequency ) - { - if (!mRandr) - return; + { + if (!mRandr) + return; } RenderWindow* AndroidEGLSupport::newWindow( const String &name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams) - { - AndroidEGLWindow* window = new AndroidEGLWindow(this); - window->create(name, width, height, fullScreen, miscParams); + { + AndroidEGLWindow* window = new AndroidEGLWindow(this); + window->create(name, width, height, fullScreen, miscParams); - return window; - } + return window; + } } diff --git a/RenderSystems/GLES2/src/EGL/Android/OgreAndroidEGLWindow.cpp b/RenderSystems/GLES2/src/EGL/Android/OgreAndroidEGLWindow.cpp index 2cc1faae5d6..1aeb1d5780a 100644 --- a/RenderSystems/GLES2/src/EGL/Android/OgreAndroidEGLWindow.cpp +++ b/RenderSystems/GLES2/src/EGL/Android/OgreAndroidEGLWindow.cpp @@ -46,50 +46,50 @@ THE SOFTWARE. #include namespace Ogre { - AndroidEGLWindow::AndroidEGLWindow(AndroidEGLSupport *glsupport) - : EGLWindow(glsupport), - mMaxBufferSize(32), - mMinBufferSize(16), - mMaxDepthSize(16), - mMaxStencilSize(0), - mMSAA(0), - mCSAA(0) - { - } + AndroidEGLWindow::AndroidEGLWindow(AndroidEGLSupport *glsupport) + : EGLWindow(glsupport), + mMaxBufferSize(32), + mMinBufferSize(16), + mMaxDepthSize(16), + mMaxStencilSize(0), + mMSAA(0), + mCSAA(0) + { + } - AndroidEGLWindow::~AndroidEGLWindow() - { - } + AndroidEGLWindow::~AndroidEGLWindow() + { + } - EGLContext* AndroidEGLWindow::createEGLContext() const - { - return new AndroidEGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); - } + EGLContext* AndroidEGLWindow::createEGLContext() const + { + return new AndroidEGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); + } - void AndroidEGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) - { - // We don't have a native window.... but I think all android windows are origined - left = top = 0; - } + void AndroidEGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) + { + // We don't have a native window.... but I think all android windows are origined + left = top = 0; + } - void AndroidEGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) - { - } + void AndroidEGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) + { + } - void AndroidEGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) - { - } + void AndroidEGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) + { + } - void AndroidEGLWindow::reposition( int left, int top ) - { - } + void AndroidEGLWindow::reposition( int left, int top ) + { + } - void AndroidEGLWindow::resize(uint width, uint height) - { - } + void AndroidEGLWindow::resize(uint width, uint height) + { + } - void AndroidEGLWindow::windowMovedOrResized() - { + void AndroidEGLWindow::windowMovedOrResized() + { if(mActive) { eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, (EGLint*)&mWidth); @@ -100,8 +100,8 @@ namespace Ogre { while( it != mViewportList.end() ) (*it++).second->_updateDimensions(); } - } - + } + void AndroidEGLWindow::switchFullScreen(bool fullscreen) { @@ -110,7 +110,7 @@ namespace Ogre { void AndroidEGLWindow::create(const String& name, uint width, uint height, bool fullScreen, const NameValuePairList *miscParams) { - mName = name; + mName = name; mWidth = width; mHeight = height; mLeft = 0; @@ -156,34 +156,34 @@ namespace Ogre { mIsExternalGLControl = true; ctxHandle = Ogre::StringConverter::parseInt(opt->second); } - - if((opt = miscParams->find("maxColourBufferSize")) != end) + + if((opt = miscParams->find("maxColourBufferSize")) != end) { mMaxBufferSize = Ogre::StringConverter::parseInt(opt->second); } - - if((opt = miscParams->find("maxDepthBufferSize")) != end) + + if((opt = miscParams->find("maxDepthBufferSize")) != end) { mMaxDepthSize = Ogre::StringConverter::parseInt(opt->second); } - - if((opt = miscParams->find("maxStencilBufferSize")) != end) + + if((opt = miscParams->find("maxStencilBufferSize")) != end) { mMaxStencilSize = Ogre::StringConverter::parseInt(opt->second); } - if((opt = miscParams->find("minColourBufferSize")) != end) + if((opt = miscParams->find("minColourBufferSize")) != end) { mMinBufferSize = Ogre::StringConverter::parseInt(opt->second); if (mMinBufferSize > mMaxBufferSize) mMinBufferSize = mMaxBufferSize; } - if((opt = miscParams->find("MSAA")) != end) + if((opt = miscParams->find("MSAA")) != end) { mMSAA = Ogre::StringConverter::parseInt(opt->second); } - - if((opt = miscParams->find("CSAA")) != end) + + if((opt = miscParams->find("CSAA")) != end) { mCSAA = Ogre::StringConverter::parseInt(opt->second); } @@ -213,21 +213,21 @@ namespace Ogre { if (!mEglConfig) { - _createInternalResources(mWindow, config); + _createInternalResources(mWindow, config); mHwGamma = false; } mContext = createEGLContext(); mContext->setCurrent(); - + eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, (EGLint*)&mWidth); eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, (EGLint*)&mHeight); EGL_CHECK_ERROR - mActive = true; - mVisible = true; - mClosed = false; - } + mActive = true; + mVisible = true; + mClosed = false; + } void AndroidEGLWindow::_destroyInternalResources() { @@ -244,7 +244,7 @@ namespace Ogre { mEglSurface = 0; mActive = false; - mVisible = false; + mVisible = false; mClosed = true; } @@ -261,72 +261,72 @@ namespace Ogre { int maxAttribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_BUFFER_SIZE, mMaxBufferSize, + EGL_BUFFER_SIZE, mMaxBufferSize, EGL_DEPTH_SIZE, mMaxDepthSize, EGL_STENCIL_SIZE, mMaxStencilSize, EGL_NONE }; - bool bAASuccess = false; - if (mCSAA) - { - try - { - int CSAAminAttribs[] = { - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_BUFFER_SIZE, mMinBufferSize, - EGL_DEPTH_SIZE, 16, - EGL_COVERAGE_BUFFERS_NV, 1, - EGL_COVERAGE_SAMPLES_NV, mCSAA, - EGL_NONE - }; - int CSAAmaxAttribs[] = { - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_BUFFER_SIZE, mMaxBufferSize, - EGL_DEPTH_SIZE, mMaxDepthSize, - EGL_STENCIL_SIZE, mMaxStencilSize, - EGL_COVERAGE_BUFFERS_NV, 1, - EGL_COVERAGE_SAMPLES_NV, mCSAA, - EGL_NONE - }; - mEglConfig = mGLSupport->selectGLConfig(CSAAminAttribs, CSAAmaxAttribs); - bAASuccess = true; - } - catch (Exception& e) - { - LogManager::getSingleton().logMessage("AndroidEGLWindow::_createInternalResources: setting CSAA failed"); - } - } + bool bAASuccess = false; + if (mCSAA) + { + try + { + int CSAAminAttribs[] = { + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_BUFFER_SIZE, mMinBufferSize, + EGL_DEPTH_SIZE, 16, + EGL_COVERAGE_BUFFERS_NV, 1, + EGL_COVERAGE_SAMPLES_NV, mCSAA, + EGL_NONE + }; + int CSAAmaxAttribs[] = { + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_BUFFER_SIZE, mMaxBufferSize, + EGL_DEPTH_SIZE, mMaxDepthSize, + EGL_STENCIL_SIZE, mMaxStencilSize, + EGL_COVERAGE_BUFFERS_NV, 1, + EGL_COVERAGE_SAMPLES_NV, mCSAA, + EGL_NONE + }; + mEglConfig = mGLSupport->selectGLConfig(CSAAminAttribs, CSAAmaxAttribs); + bAASuccess = true; + } + catch (Exception& e) + { + LogManager::getSingleton().logMessage("AndroidEGLWindow::_createInternalResources: setting CSAA failed"); + } + } - if (mMSAA && !bAASuccess) - { - try - { - int MSAAminAttribs[] = { - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_BUFFER_SIZE, mMinBufferSize, - EGL_DEPTH_SIZE, 16, - EGL_SAMPLE_BUFFERS, 1, - EGL_SAMPLES, mMSAA, - EGL_NONE - }; - int MSAAmaxAttribs[] = { - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_BUFFER_SIZE, mMaxBufferSize, - EGL_DEPTH_SIZE, mMaxDepthSize, - EGL_STENCIL_SIZE, mMaxStencilSize, - EGL_SAMPLE_BUFFERS, 1, - EGL_SAMPLES, mMSAA, - EGL_NONE - }; - mEglConfig = mGLSupport->selectGLConfig(MSAAminAttribs, MSAAmaxAttribs); - bAASuccess = true; - } - catch (Exception& e) - { - LogManager::getSingleton().logMessage("AndroidEGLWindow::_createInternalResources: setting MSAA failed"); - } - } + if (mMSAA && !bAASuccess) + { + try + { + int MSAAminAttribs[] = { + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_BUFFER_SIZE, mMinBufferSize, + EGL_DEPTH_SIZE, 16, + EGL_SAMPLE_BUFFERS, 1, + EGL_SAMPLES, mMSAA, + EGL_NONE + }; + int MSAAmaxAttribs[] = { + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_BUFFER_SIZE, mMaxBufferSize, + EGL_DEPTH_SIZE, mMaxDepthSize, + EGL_STENCIL_SIZE, mMaxStencilSize, + EGL_SAMPLE_BUFFERS, 1, + EGL_SAMPLES, mMSAA, + EGL_NONE + }; + mEglConfig = mGLSupport->selectGLConfig(MSAAminAttribs, MSAAmaxAttribs); + bAASuccess = true; + } + catch (Exception& e) + { + LogManager::getSingleton().logMessage("AndroidEGLWindow::_createInternalResources: setting MSAA failed"); + } + } mEglDisplay = mGLSupport->getGLDisplay(); if (!bAASuccess) mEglConfig = mGLSupport->selectGLConfig(minAttribs, maxAttribs); diff --git a/RenderSystems/GLES2/src/EGL/Android/OgreAndroidResource.cpp b/RenderSystems/GLES2/src/EGL/Android/OgreAndroidResource.cpp index e8d34fde963..bb3fc8da2e5 100644 --- a/RenderSystems/GLES2/src/EGL/Android/OgreAndroidResource.cpp +++ b/RenderSystems/GLES2/src/EGL/Android/OgreAndroidResource.cpp @@ -31,13 +31,13 @@ THE SOFTWARE. namespace Ogre { - AndroidResource::AndroidResource() - { - GLES2RenderSystem::getResourceManager()->_notifyResourceCreated(static_cast(this)); - } + AndroidResource::AndroidResource() + { + GLES2RenderSystem::getResourceManager()->_notifyResourceCreated(static_cast(this)); + } - AndroidResource::~AndroidResource() - { - GLES2RenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast(this)); - } + AndroidResource::~AndroidResource() + { + GLES2RenderSystem::getResourceManager()->_notifyResourceDestroyed(static_cast(this)); + } } diff --git a/RenderSystems/GLES2/src/EGL/Android/OgreAndroidResourceManager.cpp b/RenderSystems/GLES2/src/EGL/Android/OgreAndroidResourceManager.cpp index 0e30fa94c3a..765ea86b092 100644 --- a/RenderSystems/GLES2/src/EGL/Android/OgreAndroidResourceManager.cpp +++ b/RenderSystems/GLES2/src/EGL/Android/OgreAndroidResourceManager.cpp @@ -30,45 +30,45 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - AndroidResourceManager::AndroidResourceManager() - { - } - //----------------------------------------------------------------------- - AndroidResourceManager::~AndroidResourceManager() - { - - } //----------------------------------------------------------------------- - void AndroidResourceManager::notifyOnContextLost() - { - ResourceContainerIterator it = mResources.begin(); - while (it != mResources.end()) - { - (*it)->notifyOnContextLost(); - ++it; - } - } + AndroidResourceManager::AndroidResourceManager() + { + } //----------------------------------------------------------------------- - void AndroidResourceManager::notifyOnContextReset() - { - ResourceContainerIterator it = mResources.begin(); - while (it != mResources.end()) - { - (*it)->notifyOnContextReset(); - ++it; - } - } - //----------------------------------------------------------------------- - void AndroidResourceManager::_notifyResourceCreated(AndroidResource* pResource) - { - mResources.push_back(pResource); - } - //----------------------------------------------------------------------- - void AndroidResourceManager::_notifyResourceDestroyed(AndroidResource* pResource) - { + AndroidResourceManager::~AndroidResourceManager() + { + + } + //----------------------------------------------------------------------- + void AndroidResourceManager::notifyOnContextLost() + { + ResourceContainerIterator it = mResources.begin(); + while (it != mResources.end()) + { + (*it)->notifyOnContextLost(); + ++it; + } + } + //----------------------------------------------------------------------- + void AndroidResourceManager::notifyOnContextReset() + { + ResourceContainerIterator it = mResources.begin(); + while (it != mResources.end()) + { + (*it)->notifyOnContextReset(); + ++it; + } + } + //----------------------------------------------------------------------- + void AndroidResourceManager::_notifyResourceCreated(AndroidResource* pResource) + { + mResources.push_back(pResource); + } + //----------------------------------------------------------------------- + void AndroidResourceManager::_notifyResourceDestroyed(AndroidResource* pResource) + { ResourceContainerIterator it = std::find( mResources.begin(), mResources.end(), pResource ); if(it != mResources.end()) mResources.erase(it); - } + } } diff --git a/RenderSystems/GLES2/src/EGL/OgreEGLContext.cpp b/RenderSystems/GLES2/src/EGL/OgreEGLContext.cpp index 4702283463e..f02673de4a0 100644 --- a/RenderSystems/GLES2/src/EGL/OgreEGLContext.cpp +++ b/RenderSystems/GLES2/src/EGL/OgreEGLContext.cpp @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { EGLContext::EGLContext(EGLDisplay eglDisplay, - const EGLSupport* glsupport, + const EGLSupport* glsupport, ::EGLConfig glconfig, ::EGLSurface drawable) : mGLSupport(glsupport), mContext(0) { - assert(drawable); + assert(drawable); GLES2RenderSystem* renderSystem = static_cast(Root::getSingleton().getRenderSystem()); EGLContext* mainContext = static_cast(renderSystem->_getMainContext()); ::EGLContext shareContext = (::EGLContext) 0; @@ -110,12 +110,12 @@ namespace Ogre { void EGLContext::endCurrent() { - eglMakeCurrent(mEglDisplay, 0, 0, 0); + eglMakeCurrent(mEglDisplay, 0, 0, 0); EGL_CHECK_ERROR } - EGLSurface EGLContext::getDrawable() const - { - return mDrawable; - } + EGLSurface EGLContext::getDrawable() const + { + return mDrawable; + } } diff --git a/RenderSystems/GLES2/src/EGL/OgreEGLRenderTexture.cpp b/RenderSystems/GLES2/src/EGL/OgreEGLRenderTexture.cpp index 249e6d0f8ae..8709ce0967c 100644 --- a/RenderSystems/GLES2/src/EGL/OgreEGLRenderTexture.cpp +++ b/RenderSystems/GLES2/src/EGL/OgreEGLRenderTexture.cpp @@ -47,21 +47,21 @@ THE SOFTWARE. #include namespace Ogre { - EGLPBuffer::EGLPBuffer(EGLSupport* glsupport, PixelComponentType format, + EGLPBuffer::EGLPBuffer(EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height) : GLESPBuffer(format, width, height) { } - //Changed the constructor to a member function so that the - //native constructor would be called first. This member - //function is then called from the native constructor. + //Changed the constructor to a member function so that the + //native constructor would be called first. This member + //function is then called from the native constructor. void EGLPBuffer::initEGLPBuffer() { -// These are now initialized in the native constructors. -// mGLSupport = glsupport; +// These are now initialized in the native constructors. +// mGLSupport = glsupport; // mGlDisplay = mGLSupport->getGLDisplay(); mEglDrawable = 0; ::EGLConfig glConfig = 0; @@ -111,17 +111,17 @@ namespace Ogre { }; int pBufferAttribs[] = { - // First we specify the width of the surface... + // First we specify the width of the surface... EGL_WIDTH, mWidth, - // ...then the height of the surface... + // ...then the height of the surface... EGL_HEIGHT, mHeight, - /* ... then we specify the target for the texture - that will be created when the pbuffer is created...*/ - EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, - /*..then the format of the texture that will be created - when the pBuffer is bound to a texture...*/ + /* ... then we specify the target for the texture + that will be created when the pbuffer is created...*/ + EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, + /*..then the format of the texture that will be created + when the pBuffer is bound to a texture...*/ EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB, - // The final thing is EGL_NONE which signifies the end. + // The final thing is EGL_NONE which signifies the end. EGL_NONE }; @@ -157,7 +157,7 @@ namespace Ogre { EGLPBuffer::~EGLPBuffer() { - eglDestroySurface(mGlDisplay, mEglDrawable); + eglDestroySurface(mGlDisplay, mEglDrawable); LogManager::getSingleton().logMessage(LML_NORMAL, "EGLPBuffer::PBuffer destroyed"); } diff --git a/RenderSystems/GLES2/src/EGL/OgreEGLSupport.cpp b/RenderSystems/GLES2/src/EGL/OgreEGLSupport.cpp index aa1e97c14a0..ac7daec0010 100755 --- a/RenderSystems/GLES2/src/EGL/OgreEGLSupport.cpp +++ b/RenderSystems/GLES2/src/EGL/OgreEGLSupport.cpp @@ -46,7 +46,7 @@ namespace Ogre { EGLSupport::EGLSupport() : mGLDisplay(0), mNativeDisplay(0), - mRandr(false) + mRandr(false) { } @@ -204,7 +204,7 @@ namespace Ogre { String EGLSupport::getDisplayName(void) { - return "todo"; + return "todo"; } EGLConfig* EGLSupport::chooseGLConfig(const GLint *attribList, GLint *nElements) @@ -386,8 +386,8 @@ namespace Ogre { if (!nConfigs) { - glConfigs = getConfigs(&nConfigs); - } + glConfigs = getConfigs(&nConfigs); + } if (!nConfigs) { @@ -481,7 +481,7 @@ namespace Ogre { } ::EGLContext EGLSupport::createNewContext(EGLDisplay eglDisplay, - ::EGLConfig glconfig, + ::EGLConfig glconfig, ::EGLContext shareList) const { EGLint contextAttrs[] = { @@ -521,8 +521,8 @@ namespace Ogre { void EGLSupport::stop() { - eglTerminate(mGLDisplay); - EGL_CHECK_ERROR + eglTerminate(mGLDisplay); + EGL_CHECK_ERROR } void EGLSupport::setGLDisplay( EGLDisplay val ) diff --git a/RenderSystems/GLES2/src/EGL/OgreEGLWindow.cpp b/RenderSystems/GLES2/src/EGL/OgreEGLWindow.cpp index fa86d340728..cd0a31c2595 100644 --- a/RenderSystems/GLES2/src/EGL/OgreEGLWindow.cpp +++ b/RenderSystems/GLES2/src/EGL/OgreEGLWindow.cpp @@ -47,18 +47,18 @@ namespace Ogre { EGLWindow::EGLWindow(EGLSupport *glsupport) : mGLSupport(glsupport), mContext(0), - mEglConfig(0), - mEglSurface(0), - mWindow(0), - mNativeDisplay(0), - mEglDisplay(EGL_NO_DISPLAY) + mEglConfig(0), + mEglSurface(0), + mWindow(0), + mNativeDisplay(0), + mEglDisplay(EGL_NO_DISPLAY) { mIsTopLevel = false; mIsFullScreen = false; mClosed = false; mActive = true;//todo mIsExternalGLControl = false; - mVisible = false; + mVisible = false; } EGLWindow::~EGLWindow() @@ -108,7 +108,7 @@ namespace Ogre { { return; } - if (fullscreen) + if (fullscreen) { mGLSupport->switchMode(width, height, frequency); } @@ -155,7 +155,7 @@ namespace Ogre { if (eglSwapBuffers(mEglDisplay, mEglSurface) == EGL_FALSE) { - EGL_CHECK_ERROR + EGL_CHECK_ERROR OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Fail to SwapBuffers", __FUNCTION__); @@ -179,60 +179,60 @@ namespace Ogre { *static_cast(pData) = mContext; return; } - else if (name == "WINDOW") - { - *static_cast(pData) = mWindow; - return; - } - } + else if (name == "WINDOW") + { + *static_cast(pData) = mWindow; + return; + } + } void EGLWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) { - if ((dst.left < 0) || (dst.right > mWidth) || - (dst.top < 0) || (dst.bottom > mHeight) || - (dst.front != 0) || (dst.back != 1)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Invalid box.", - "EGLWindow::copyContentsToMemory" ); - } - - if (buffer == FB_AUTO) - { - buffer = mIsFullScreen? FB_FRONT : FB_BACK; - } - - GLenum format = GLES2PixelUtil::getGLOriginFormat(dst.format); - GLenum type = GLES2PixelUtil::getGLOriginDataType(dst.format); - - if ((format == 0) || (type == 0)) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unsupported format.", - "EGLWindow::copyContentsToMemory" ); - } - - - // Switch context if different from current one - RenderSystem* rsys = Root::getSingleton().getRenderSystem(); - rsys->_setViewport(this->getViewport(0)); + if ((dst.left < 0) || (dst.right > mWidth) || + (dst.top < 0) || (dst.bottom > mHeight) || + (dst.front != 0) || (dst.back != 1)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Invalid box.", + "EGLWindow::copyContentsToMemory" ); + } + + if (buffer == FB_AUTO) + { + buffer = mIsFullScreen? FB_FRONT : FB_BACK; + } + + GLenum format = GLES2PixelUtil::getGLOriginFormat(dst.format); + GLenum type = GLES2PixelUtil::getGLOriginDataType(dst.format); + + if ((format == 0) || (type == 0)) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Unsupported format.", + "EGLWindow::copyContentsToMemory" ); + } + + + // Switch context if different from current one + RenderSystem* rsys = Root::getSingleton().getRenderSystem(); + rsys->_setViewport(this->getViewport(0)); #if OGRE_NO_GLES3_SUPPORT == 0 if(dst.getWidth() != dst.rowPitch) glPixelStorei(GL_PACK_ROW_LENGTH, dst.rowPitch); #endif - // Must change the packing to ensure no overruns! - glPixelStorei(GL_PACK_ALIGNMENT, 1); + // Must change the packing to ensure no overruns! + glPixelStorei(GL_PACK_ALIGNMENT, 1); #if OGRE_NO_GLES3_SUPPORT == 0 - glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); + glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK); #endif glReadPixels((GLint)0, (GLint)(mHeight - dst.getHeight()), (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(), format, type, dst.getTopLeftFrontPixelPtr()); - // restore default alignment - glPixelStorei(GL_PACK_ALIGNMENT, 4); + // restore default alignment + glPixelStorei(GL_PACK_ALIGNMENT, 4); #if OGRE_NO_GLES3_SUPPORT == 0 glPixelStorei(GL_PACK_ROW_LENGTH, 0); #endif @@ -258,9 +258,9 @@ namespace Ogre { return surface; } - bool EGLWindow::requiresTextureFlipping() const - { - return false; - } + bool EGLWindow::requiresTextureFlipping() const + { + return false; + } } diff --git a/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLContext.cpp b/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLContext.cpp index 690d9a5ca75..c1f16983522 100644 --- a/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLContext.cpp +++ b/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLContext.cpp @@ -35,7 +35,7 @@ THE SOFTWARE. namespace Ogre { Win32EGLContext::Win32EGLContext(EGLDisplay eglDisplay, - const EGLSupport* glsupport, + const EGLSupport* glsupport, ::EGLConfig glconfig, ::EGLSurface drawable) : EGLContext(eglDisplay, glsupport, glconfig, drawable) diff --git a/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLRenderTexture.cpp b/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLRenderTexture.cpp index 10643b9124a..36fd320b7be 100644 --- a/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLRenderTexture.cpp +++ b/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLRenderTexture.cpp @@ -47,19 +47,19 @@ THE SOFTWARE. namespace Ogre { - Win32EGLPBuffer::Win32EGLPBuffer( Win32EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height ) - : EGLPBuffer(glsupport, format, width, height) - { - mGLSupport = glsupport; - mGlDisplay = glsupport->getGLDisplay(); - initEGLPBuffer(); + Win32EGLPBuffer::Win32EGLPBuffer( Win32EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height ) + : EGLPBuffer(glsupport, format, width, height) + { + mGLSupport = glsupport; + mGlDisplay = glsupport->getGLDisplay(); + initEGLPBuffer(); - } + } - Win32EGLPBuffer::~Win32EGLPBuffer() - { + Win32EGLPBuffer::~Win32EGLPBuffer() + { - } + } } */ \ No newline at end of file diff --git a/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLSupport.cpp b/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLSupport.cpp index 0b1938d2af1..02cc16c76b4 100644 --- a/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLSupport.cpp +++ b/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLSupport.cpp @@ -45,119 +45,119 @@ THE SOFTWARE. namespace Ogre { - Win32EGLSupport::Win32EGLSupport() - { - //RECT windowRect; - //GetClientRect(mNativeDisplay, &windowRect); - mNativeDisplay = getNativeDisplay(); - mGLDisplay = getGLDisplay(); - - // Video mode possibilities - DEVMODE DevMode; - DevMode.dmSize = sizeof(DEVMODE); - for (DWORD i = 0; EnumDisplaySettings(NULL, i, &DevMode); ++i) - { - if (DevMode.dmBitsPerPel < 16) - continue; - - mCurrentMode.first.first = DevMode.dmPelsWidth; - mCurrentMode.first.second = DevMode.dmPelsHeight; - mCurrentMode.second = 0; - mOriginalMode = mCurrentMode; - mVideoModes.push_back(mCurrentMode); - } - - EGLConfig *glConfigs; - int config, nConfigs = 0; - - EGLint const attrib_list[] = { - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_BUFFER_SIZE, 32, - EGL_DEPTH_SIZE, 24, - EGL_STENCIL_SIZE, 8, - EGL_NONE - }; - - glConfigs = chooseGLConfig(attrib_list, &nConfigs); - - for (config = 0; config < nConfigs; config++) - { - int caveat, samples; - - getGLConfigAttrib(glConfigs[config], EGL_CONFIG_CAVEAT, &caveat); - - if (caveat != EGL_SLOW_CONFIG) - { - getGLConfigAttrib(glConfigs[config], EGL_SAMPLES, &samples); - mSampleLevels.push_back(StringConverter::toString(samples)); - } - } - - free(glConfigs); - - removeDuplicates(mSampleLevels); - - - } - - Win32EGLSupport::~Win32EGLSupport() - { - - } - - //Removed createEGLWindow because it was easier to call new Win32EGLWindow - //directly to get the native version. -// EGLWindow* Win32EGLSupport::createEGLWindow( EGLSupport * support ) -// { -// return new Win32EGLWindow(support); -// } - - /*GLESPBuffer* Win32EGLSupport::createPBuffer( PixelComponentType format, size_t width, size_t height ) - { - return new Win32EGLPBuffer(this, format, width, height); - }*/ - - void Win32EGLSupport::switchMode( uint& width, uint& height, short& frequency ) - { - if (!mRandr) - return; - - int size = 0; - int newSize = -1; - - VideoModes::iterator mode; - VideoModes::iterator end = mVideoModes.end(); - VideoMode *newMode = 0; - - for(mode = mVideoModes.begin(); mode != end; size++) - { - if (mode->first.first >= static_cast(width) && - mode->first.second >= static_cast(height)) - { - if (!newMode || - mode->first.first < newMode->first.first || - mode->first.second < newMode->first.second) - { - newSize = size; - newMode = &(*mode); - } - } - - VideoMode* lastMode = &(*mode); - - while (++mode != end && mode->first == lastMode->first) - { - if (lastMode == newMode && mode->second == frequency) - { - newMode = &(*mode); - } - } - } - - //todo - } - - //Moved to native from EGLSupport + Win32EGLSupport::Win32EGLSupport() + { + //RECT windowRect; + //GetClientRect(mNativeDisplay, &windowRect); + mNativeDisplay = getNativeDisplay(); + mGLDisplay = getGLDisplay(); + + // Video mode possibilities + DEVMODE DevMode; + DevMode.dmSize = sizeof(DEVMODE); + for (DWORD i = 0; EnumDisplaySettings(NULL, i, &DevMode); ++i) + { + if (DevMode.dmBitsPerPel < 16) + continue; + + mCurrentMode.first.first = DevMode.dmPelsWidth; + mCurrentMode.first.second = DevMode.dmPelsHeight; + mCurrentMode.second = 0; + mOriginalMode = mCurrentMode; + mVideoModes.push_back(mCurrentMode); + } + + EGLConfig *glConfigs; + int config, nConfigs = 0; + + EGLint const attrib_list[] = { + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_BUFFER_SIZE, 32, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + EGL_NONE + }; + + glConfigs = chooseGLConfig(attrib_list, &nConfigs); + + for (config = 0; config < nConfigs; config++) + { + int caveat, samples; + + getGLConfigAttrib(glConfigs[config], EGL_CONFIG_CAVEAT, &caveat); + + if (caveat != EGL_SLOW_CONFIG) + { + getGLConfigAttrib(glConfigs[config], EGL_SAMPLES, &samples); + mSampleLevels.push_back(StringConverter::toString(samples)); + } + } + + free(glConfigs); + + removeDuplicates(mSampleLevels); + + + } + + Win32EGLSupport::~Win32EGLSupport() + { + + } + + //Removed createEGLWindow because it was easier to call new Win32EGLWindow + //directly to get the native version. +// EGLWindow* Win32EGLSupport::createEGLWindow( EGLSupport * support ) +// { +// return new Win32EGLWindow(support); +// } + + /*GLESPBuffer* Win32EGLSupport::createPBuffer( PixelComponentType format, size_t width, size_t height ) + { + return new Win32EGLPBuffer(this, format, width, height); + }*/ + + void Win32EGLSupport::switchMode( uint& width, uint& height, short& frequency ) + { + if (!mRandr) + return; + + int size = 0; + int newSize = -1; + + VideoModes::iterator mode; + VideoModes::iterator end = mVideoModes.end(); + VideoMode *newMode = 0; + + for(mode = mVideoModes.begin(); mode != end; size++) + { + if (mode->first.first >= static_cast(width) && + mode->first.second >= static_cast(height)) + { + if (!newMode || + mode->first.first < newMode->first.first || + mode->first.second < newMode->first.second) + { + newSize = size; + newMode = &(*mode); + } + } + + VideoMode* lastMode = &(*mode); + + while (++mode != end && mode->first == lastMode->first) + { + if (lastMode == newMode && mode->second == frequency) + { + newMode = &(*mode); + } + } + } + + //todo + } + + //Moved to native from EGLSupport RenderWindow* Win32EGLSupport::newWindow(const String &name, unsigned int width, unsigned int height, bool fullScreen, @@ -165,29 +165,29 @@ namespace Ogre { { // EGLWindow* window = createEGLWindow(this); - Win32EGLWindow* window = new Win32EGLWindow(this); + Win32EGLWindow* window = new Win32EGLWindow(this); window->create(name, width, height, fullScreen, miscParams); return window; } - //Moved to native from EGLSupport - NativeDisplayType Win32EGLSupport::getNativeDisplay() - { - return EGL_DEFAULT_DISPLAY; // TODO - } - - //Win32EGLSupport::getGLDisplay sets up the native variable - //then calls EGLSupport::getGLDisplay - EGLDisplay Win32EGLSupport::getGLDisplay() - { - if (!mGLDisplay) - { - mNativeDisplay = getNativeDisplay(); - return EGLSupport::getGLDisplay(); - } - return mGLDisplay; - } + //Moved to native from EGLSupport + NativeDisplayType Win32EGLSupport::getNativeDisplay() + { + return EGL_DEFAULT_DISPLAY; // TODO + } + + //Win32EGLSupport::getGLDisplay sets up the native variable + //then calls EGLSupport::getGLDisplay + EGLDisplay Win32EGLSupport::getGLDisplay() + { + if (!mGLDisplay) + { + mNativeDisplay = getNativeDisplay(); + return EGLSupport::getGLDisplay(); + } + return mGLDisplay; + } } diff --git a/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLWindow.cpp b/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLWindow.cpp index 509a5bd18a1..bbd57be93da 100644 --- a/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLWindow.cpp +++ b/RenderSystems/GLES2/src/EGL/WIN32/OgreWin32EGLWindow.cpp @@ -46,269 +46,269 @@ THE SOFTWARE. namespace Ogre { Win32EGLWindow::Win32EGLWindow(Win32EGLSupport *glsupport) - : EGLWindow(glsupport) + : EGLWindow(glsupport) { - mGLSupport = glsupport; - mNativeDisplay = glsupport->getNativeDisplay(); + mGLSupport = glsupport; + mNativeDisplay = glsupport->getNativeDisplay(); } Win32EGLWindow::~Win32EGLWindow() { } - EGLContext * Win32EGLWindow::createEGLContext() const - { - return new Win32EGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); - } + EGLContext * Win32EGLWindow::createEGLContext() const + { + return new Win32EGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); + } - void Win32EGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) - { + void Win32EGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) + { - } + } - void Win32EGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) - { + void Win32EGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) + { - } + } - void Win32EGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) - { - // destroy current window, if any - if (mWindow) - destroy(); + void Win32EGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) + { + // destroy current window, if any + if (mWindow) + destroy(); #ifdef OGRE_STATIC_LIB - HINSTANCE hInst = GetModuleHandle( NULL ); + HINSTANCE hInst = GetModuleHandle( NULL ); #else # if OGRE_DEBUG_MODE == 1 - HINSTANCE hInst = GetModuleHandle("RenderSystem_GLES2_d.dll"); + HINSTANCE hInst = GetModuleHandle("RenderSystem_GLES2_d.dll"); # else - HINSTANCE hInst = GetModuleHandle("RenderSystem_GLES2.dll"); + HINSTANCE hInst = GetModuleHandle("RenderSystem_GLES2.dll"); # endif #endif - mWindow = 0; - mClosed = false; - mColourDepth = mIsFullScreen? 32 : GetDeviceCaps(GetDC(0), BITSPIXEL); - HWND parent = 0; - bool vsync = false; - String border; - bool outerSize = false; - bool hwGamma = false; - int monitorIndex = -1; - HMONITOR hMonitor = NULL; - - - if (!mIsExternal) - { - DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN; - DWORD dwStyleEx = 0; - MONITORINFOEX monitorInfoEx; - RECT rc; - - // If we didn't specified the adapter index, or if it didn't find it - if (hMonitor == NULL) - { - POINT windowAnchorPoint; - - // Fill in anchor point. - windowAnchorPoint.x = left; - windowAnchorPoint.y = top; - - - // Get the nearest monitor to this window. - hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTONEAREST); - } - - // Get the target monitor info - memset(&monitorInfoEx, 0, sizeof(MONITORINFOEX)); - monitorInfoEx.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(hMonitor, &monitorInfoEx); - - //size_t devNameLen = strlen(monitorInfoEx.szDevice); - //mDeviceName = new char[devNameLen + 1]; - - //strcpy(mDeviceName, monitorInfoEx.szDevice); - - - // No specified top left -> Center the window in the middle of the monitor - if (left == -1 || top == -1) - { - int screenw = monitorInfoEx.rcMonitor.right - monitorInfoEx.rcMonitor.left; - int screenh = monitorInfoEx.rcMonitor.bottom - monitorInfoEx.rcMonitor.top; - - SetRect(&rc, 0, 0, width, height); - AdjustWindowRect(&rc, dwStyle, false); - - // clamp window dimensions to screen size - int outerw = (rc.right-rc.left < screenw)? rc.right-rc.left : screenw; - int outerh = (rc.bottom-rc.top < screenh)? rc.bottom-rc.top : screenh; - - if (left == -1) - left = monitorInfoEx.rcMonitor.left + (screenw - outerw) / 2; - else if (monitorIndex != -1) - left += monitorInfoEx.rcMonitor.left; - - if (top == -1) - top = monitorInfoEx.rcMonitor.top + (screenh - outerh) / 2; - else if (monitorIndex != -1) - top += monitorInfoEx.rcMonitor.top; - } - else if (monitorIndex != -1) - { - left += monitorInfoEx.rcMonitor.left; - top += monitorInfoEx.rcMonitor.top; - } - - mWidth = width; - mHeight = height; - mTop = top; - mLeft = left; - - if (mIsFullScreen) - { - dwStyle |= WS_POPUP; - dwStyleEx |= WS_EX_TOPMOST; - mTop = monitorInfoEx.rcMonitor.top; - mLeft = monitorInfoEx.rcMonitor.left; - } - else - { - if (parent) - { - dwStyle |= WS_CHILD; - } - else - { - if (border == "none") - dwStyle |= WS_POPUP; - else if (border == "fixed") - dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | - WS_SYSMENU | WS_MINIMIZEBOX; - else - dwStyle |= WS_OVERLAPPEDWINDOW; - } - - int screenw = GetSystemMetrics(SM_CXSCREEN); - int screenh = GetSystemMetrics(SM_CYSCREEN); - - if (!outerSize) - { - // Calculate window dimensions required - // to get the requested client area - SetRect(&rc, 0, 0, mWidth, mHeight); - AdjustWindowRect(&rc, dwStyle, false); - mWidth = rc.right - rc.left; - mHeight = rc.bottom - rc.top; - - // Clamp window rect to the nearest display monitor. - if (mLeft < monitorInfoEx.rcMonitor.left) - mLeft = monitorInfoEx.rcMonitor.left; - - if (mTop < monitorInfoEx.rcMonitor.top) - mTop = monitorInfoEx.rcMonitor.top; - - if ((int)mWidth > monitorInfoEx.rcMonitor.right - mLeft) - mWidth = monitorInfoEx.rcMonitor.right - mLeft; - - if ((int)mHeight > monitorInfoEx.rcMonitor.bottom - mTop) - mHeight = monitorInfoEx.rcMonitor.bottom - mTop; - } - } - - // register class and create window - WNDCLASS wc = { CS_OWNDC, WindowEventUtilities::_WndProc, 0, 0, hInst, - LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), - (HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "OgreGLES2Window" }; - RegisterClass(&wc); - - if (mIsFullScreen) - { - DEVMODE displayDeviceMode; - - memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); - displayDeviceMode.dmSize = sizeof(DEVMODE); - displayDeviceMode.dmBitsPerPel = mColourDepth; - displayDeviceMode.dmPelsWidth = mWidth; - displayDeviceMode.dmPelsHeight = mHeight; - displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + mWindow = 0; + mClosed = false; + mColourDepth = mIsFullScreen? 32 : GetDeviceCaps(GetDC(0), BITSPIXEL); + HWND parent = 0; + bool vsync = false; + String border; + bool outerSize = false; + bool hwGamma = false; + int monitorIndex = -1; + HMONITOR hMonitor = NULL; + + + if (!mIsExternal) + { + DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN; + DWORD dwStyleEx = 0; + MONITORINFOEX monitorInfoEx; + RECT rc; + + // If we didn't specified the adapter index, or if it didn't find it + if (hMonitor == NULL) + { + POINT windowAnchorPoint; + + // Fill in anchor point. + windowAnchorPoint.x = left; + windowAnchorPoint.y = top; + + + // Get the nearest monitor to this window. + hMonitor = MonitorFromPoint(windowAnchorPoint, MONITOR_DEFAULTTONEAREST); + } + + // Get the target monitor info + memset(&monitorInfoEx, 0, sizeof(MONITORINFOEX)); + monitorInfoEx.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &monitorInfoEx); + + //size_t devNameLen = strlen(monitorInfoEx.szDevice); + //mDeviceName = new char[devNameLen + 1]; + + //strcpy(mDeviceName, monitorInfoEx.szDevice); + + + // No specified top left -> Center the window in the middle of the monitor + if (left == -1 || top == -1) + { + int screenw = monitorInfoEx.rcMonitor.right - monitorInfoEx.rcMonitor.left; + int screenh = monitorInfoEx.rcMonitor.bottom - monitorInfoEx.rcMonitor.top; + + SetRect(&rc, 0, 0, width, height); + AdjustWindowRect(&rc, dwStyle, false); + + // clamp window dimensions to screen size + int outerw = (rc.right-rc.left < screenw)? rc.right-rc.left : screenw; + int outerh = (rc.bottom-rc.top < screenh)? rc.bottom-rc.top : screenh; + + if (left == -1) + left = monitorInfoEx.rcMonitor.left + (screenw - outerw) / 2; + else if (monitorIndex != -1) + left += monitorInfoEx.rcMonitor.left; + + if (top == -1) + top = monitorInfoEx.rcMonitor.top + (screenh - outerh) / 2; + else if (monitorIndex != -1) + top += monitorInfoEx.rcMonitor.top; + } + else if (monitorIndex != -1) + { + left += monitorInfoEx.rcMonitor.left; + top += monitorInfoEx.rcMonitor.top; + } + + mWidth = width; + mHeight = height; + mTop = top; + mLeft = left; + + if (mIsFullScreen) + { + dwStyle |= WS_POPUP; + dwStyleEx |= WS_EX_TOPMOST; + mTop = monitorInfoEx.rcMonitor.top; + mLeft = monitorInfoEx.rcMonitor.left; + } + else + { + if (parent) + { + dwStyle |= WS_CHILD; + } + else + { + if (border == "none") + dwStyle |= WS_POPUP; + else if (border == "fixed") + dwStyle |= WS_OVERLAPPED | WS_BORDER | WS_CAPTION | + WS_SYSMENU | WS_MINIMIZEBOX; + else + dwStyle |= WS_OVERLAPPEDWINDOW; + } + + int screenw = GetSystemMetrics(SM_CXSCREEN); + int screenh = GetSystemMetrics(SM_CYSCREEN); + + if (!outerSize) + { + // Calculate window dimensions required + // to get the requested client area + SetRect(&rc, 0, 0, mWidth, mHeight); + AdjustWindowRect(&rc, dwStyle, false); + mWidth = rc.right - rc.left; + mHeight = rc.bottom - rc.top; + + // Clamp window rect to the nearest display monitor. + if (mLeft < monitorInfoEx.rcMonitor.left) + mLeft = monitorInfoEx.rcMonitor.left; + + if (mTop < monitorInfoEx.rcMonitor.top) + mTop = monitorInfoEx.rcMonitor.top; + + if ((int)mWidth > monitorInfoEx.rcMonitor.right - mLeft) + mWidth = monitorInfoEx.rcMonitor.right - mLeft; + + if ((int)mHeight > monitorInfoEx.rcMonitor.bottom - mTop) + mHeight = monitorInfoEx.rcMonitor.bottom - mTop; + } + } + + // register class and create window + WNDCLASS wc = { CS_OWNDC, WindowEventUtilities::_WndProc, 0, 0, hInst, + LoadIcon(NULL, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), + (HBRUSH)GetStockObject(BLACK_BRUSH), NULL, "OgreGLES2Window" }; + RegisterClass(&wc); + + if (mIsFullScreen) + { + DEVMODE displayDeviceMode; + + memset(&displayDeviceMode, 0, sizeof(displayDeviceMode)); + displayDeviceMode.dmSize = sizeof(DEVMODE); + displayDeviceMode.dmBitsPerPel = mColourDepth; + displayDeviceMode.dmPelsWidth = mWidth; + displayDeviceMode.dmPelsHeight = mHeight; + displayDeviceMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; /* - if (mDisplayFrequency) - { - displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; - displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) - { - LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); - displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; - } - } - if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) - LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); + if (mDisplayFrequency) + { + displayDeviceMode.dmDisplayFrequency = mDisplayFrequency; + displayDeviceMode.dmFields |= DM_DISPLAYFREQUENCY; + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN | CDS_TEST, NULL) != DISP_CHANGE_SUCCESSFUL) + { + LogManager::getSingleton().logMessage(LML_NORMAL, "ChangeDisplaySettings with user display frequency failed"); + displayDeviceMode.dmFields ^= DM_DISPLAYFREQUENCY; + } + } + if (ChangeDisplaySettingsEx(mDeviceName, &displayDeviceMode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) + LogManager::getSingleton().logMessage(LML_CRITICAL, "ChangeDisplaySettings failed"); */ - } - // Pass pointer to self as WM_CREATE parameter - mWindow = CreateWindowEx(dwStyleEx, "OgreGLES2Window", title.c_str(), - dwStyle, mLeft, mTop, mWidth, mHeight, parent, 0, hInst, this); - - WindowEventUtilities::_addRenderWindow(this); - - LogManager::getSingleton().stream() - << "Created Win32Window '" - << mName << "' : " << mWidth << "x" << mHeight - << ", " << mColourDepth << "bpp"; - - } - - RECT rc; - // top and left represent outer window position - GetWindowRect(mWindow, &rc); - mTop = rc.top; - mLeft = rc.left; - // width and height represent drawable area only - GetClientRect(mWindow, &rc); - mWidth = rc.right; - mHeight = rc.bottom; - - mNativeDisplay = GetDC(mWindow); - mEglDisplay = eglGetDisplay(mNativeDisplay); - - // fallback for some emulations - if (mEglDisplay == EGL_NO_DISPLAY) - { - mEglDisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY ); - } - - eglInitialize(mEglDisplay, NULL, NULL); + } + // Pass pointer to self as WM_CREATE parameter + mWindow = CreateWindowEx(dwStyleEx, "OgreGLES2Window", title.c_str(), + dwStyle, mLeft, mTop, mWidth, mHeight, parent, 0, hInst, this); + + WindowEventUtilities::_addRenderWindow(this); + + LogManager::getSingleton().stream() + << "Created Win32Window '" + << mName << "' : " << mWidth << "x" << mHeight + << ", " << mColourDepth << "bpp"; + + } + + RECT rc; + // top and left represent outer window position + GetWindowRect(mWindow, &rc); + mTop = rc.top; + mLeft = rc.left; + // width and height represent drawable area only + GetClientRect(mWindow, &rc); + mWidth = rc.right; + mHeight = rc.bottom; + + mNativeDisplay = GetDC(mWindow); + mEglDisplay = eglGetDisplay(mNativeDisplay); + + // fallback for some emulations + if (mEglDisplay == EGL_NO_DISPLAY) + { + mEglDisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY ); + } + + eglInitialize(mEglDisplay, NULL, NULL); eglBindAPI(EGL_OPENGL_ES_API); - mGLSupport->setGLDisplay(mEglDisplay); - mEglSurface = createSurfaceFromWindow(mEglDisplay, mWindow); + mGLSupport->setGLDisplay(mEglDisplay); + mEglSurface = createSurfaceFromWindow(mEglDisplay, mWindow); - } + } - void Win32EGLWindow::reposition( int left, int top ) - { + void Win32EGLWindow::reposition( int left, int top ) + { - } + } - void Win32EGLWindow::resize( unsigned int width, unsigned int height ) - { + void Win32EGLWindow::resize( unsigned int width, unsigned int height ) + { - } + } - void Win32EGLWindow::windowMovedOrResized() - { + void Win32EGLWindow::windowMovedOrResized() + { - } + } - void Win32EGLWindow::switchFullScreen( bool fullscreen ) - { + void Win32EGLWindow::switchFullScreen( bool fullscreen ) + { - } + } void Win32EGLWindow::create(const String& name, uint width, uint height, bool fullScreen, const NameValuePairList *miscParams) @@ -319,10 +319,10 @@ namespace Ogre { short frequency = 0; bool vsync = false; ::EGLContext eglContext = 0; - int left = 0; - int top = 0; + int left = 0; + int top = 0; - getLeftAndTopFromNativeWindow(left, top, width, height); + getLeftAndTopFromNativeWindow(left, top, width, height); mIsFullScreen = fullScreen; @@ -386,9 +386,9 @@ namespace Ogre { { mIsExternalGLControl = StringConverter::parseBool(opt->second); } - } + } - initNativeCreatedWindow(miscParams); + initNativeCreatedWindow(miscParams); if (mEglSurface) { @@ -418,9 +418,9 @@ namespace Ogre { EGL_LEVEL, 0, EGL_DEPTH_SIZE, 16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_NATIVE_RENDERABLE, EGL_FALSE, - EGL_DEPTH_SIZE, EGL_DONT_CARE, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NATIVE_RENDERABLE, EGL_FALSE, + EGL_DEPTH_SIZE, EGL_DONT_CARE, EGL_NONE }; @@ -445,13 +445,13 @@ namespace Ogre { mGLSupport->switchMode (width, height, frequency); } - if (!mIsExternal) + if (!mIsExternal) { - createNativeWindow(left, top, width, height, title); - } + createNativeWindow(left, top, width, height, title); + } - mContext = createEGLContext(); - mContext->setCurrent(); + mContext = createEGLContext(); + mContext->setCurrent(); ::EGLSurface oldDrawableDraw = eglGetCurrentSurface(EGL_DRAW); ::EGLSurface oldDrawableRead = eglGetCurrentSurface(EGL_READ); ::EGLContext oldContext = eglGetCurrentContext(); @@ -467,9 +467,9 @@ namespace Ogre { mLeft = left; mTop = top; mActive = true; - mVisible = true; + mVisible = true; mClosed = false; - } + } } diff --git a/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLContext.cpp b/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLContext.cpp index e6428119516..65cd40bbc35 100644 --- a/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLContext.cpp +++ b/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLContext.cpp @@ -36,7 +36,7 @@ THE SOFTWARE. namespace Ogre { X11EGLContext::X11EGLContext(EGLDisplay eglDisplay, - const EGLSupport* glsupport, + const EGLSupport* glsupport, ::EGLConfig glconfig, ::EGLSurface drawable) : EGLContext(eglDisplay, glsupport, glconfig, drawable) diff --git a/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLRenderTexture.cpp b/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLRenderTexture.cpp index a851921effc..1805aedac3a 100644 --- a/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLRenderTexture.cpp +++ b/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLRenderTexture.cpp @@ -47,18 +47,18 @@ THE SOFTWARE. namespace Ogre { - X11EGLPBuffer::X11EGLPBuffer( X11EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height ) - : EGLPBuffer(glsupport, format, width, height) - { - mGlDisplay = glsupport->getGLDisplay(); - mGLSupport = glsupport; - initEGLPBuffer(); - } + X11EGLPBuffer::X11EGLPBuffer( X11EGLSupport* glsupport, PixelComponentType format, size_t width, size_t height ) + : EGLPBuffer(glsupport, format, width, height) + { + mGlDisplay = glsupport->getGLDisplay(); + mGLSupport = glsupport; + initEGLPBuffer(); + } - X11EGLPBuffer::~X11EGLPBuffer() - { + X11EGLPBuffer::~X11EGLPBuffer() + { - } + } } #endif diff --git a/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLSupport.cpp b/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLSupport.cpp index 19f7459108f..b290fb173ed 100644 --- a/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLSupport.cpp +++ b/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLSupport.cpp @@ -42,44 +42,44 @@ THE SOFTWARE. #if (OGRE_PLATFORM != OGRE_PLATFORM_LINUX) - void XStringListToTextProperty(char ** prop, int num, XTextProperty * textProp){}; - Window DefaultRootWindow(Display* nativeDisplayType){return Window();}; - bool XQueryExtension(Display* nativeDisplayType, char * name, int * dummy0, int * dummy2, int * dummy3){return 0;} - XRRScreenConfiguration * XRRGetScreenInfo(Display* nativeDisplayType, Window window ){return 0;}; - int XRRConfigCurrentConfiguration(XRRScreenConfiguration * config, Rotation * rotation){return 0;}; - XRRScreenSize * XRRConfigSizes(XRRScreenConfiguration * config, int * nSizes){return 0;}; - int XRRConfigCurrentRate(XRRScreenConfiguration * config){return 0;}; - short * XRRConfigRates(XRRScreenConfiguration * config, int sizeID, int * nRates){return 0;}; - void XRRFreeScreenConfigInfo(XRRScreenConfiguration * config){} - int DefaultScreen(NativeDisplayType nativeDisplayType){return 0;}; - int DisplayWidth(Display* nativeDisplayType, int screen){return 0;}; - int DisplayHeight(Display* nativeDisplayType, int screen){return 0;}; - Display* XOpenDisplay(int num){return NULL;}; - void XCloseDisplay(Display* nativeDisplayType){}; - Atom XInternAtom(Display* nativeDisplayType, char * name, X11Bool isTrue) {return Atom();}; - char * DisplayString(NativeDisplayType nativeDisplayType){return 0;}; - const char * XDisplayName(char * name){return 0;}; - Visual * DefaultVisual(Display* nativeDisplayType, int screen){return 0;}; - int XVisualIDFromVisual(Visual *v){return 0;}; - void XRRSetScreenConfigAndRate(Display* nativeDisplayType, XRRScreenConfiguration * config, Window window, int size, Rotation rotation, int mode, int currentTime ){}; - XVisualInfo * XGetVisualInfo(Display* nativeDisplayType, int mask, XVisualInfo * info, int * n){return 0;}; - typedef int (*XErrorHandler)(Display *, XErrorEvent*); - XErrorHandler XSetErrorHandler(XErrorHandler xErrorHandler){return 0;}; - void XDestroyWindow(Display* nativeDisplayType, Window nativeWindowType){}; - bool XGetWindowAttributes(Display* nativeDisplayType, Window nativeWindowType, XWindowAttributes * xWindowAttributes){return 0;}; - int XCreateColormap(Display* nativeDisplayType, Window nativeWindowType, int visual, int allocNone){return 0;}; - Window XCreateWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top, int width, int height, int dummy1, int depth, int inputOutput, int visual, int mask, XSetWindowAttributes * xSetWindowAttributes){return Window();}; - void XFree(void *data){}; - XWMHints * XAllocWMHints(){return 0;}; - XSizeHints * XAllocSizeHints(){return 0;}; - void XSetWMProperties(Display* nativeDisplayType, Window nativeWindowType,XTextProperty * titleprop, char * dummy1, char * dummy2, int num, XSizeHints *sizeHints, XWMHints *wmHints, char * dummy3){}; - void XSetWMProtocols(Display* nativeDisplayType, Window nativeWindowType, Atom * atom, int num){}; - void XMapWindow(Display* nativeDisplayType, Window nativeWindowType){}; - void XFlush(Display* nativeDisplayType){}; - void XMoveWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top){}; - void XResizeWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top){}; - void XQueryTree(Display* nativeDisplayType, Window nativeWindowType, Window * root, Window *parent, Window **children, unsigned int * nChildren){}; - void XSendEvent(Display* nativeDisplayType, Window nativeWindowType, int dummy1, int mask, XEvent* xevent){}; + void XStringListToTextProperty(char ** prop, int num, XTextProperty * textProp){}; + Window DefaultRootWindow(Display* nativeDisplayType){return Window();}; + bool XQueryExtension(Display* nativeDisplayType, char * name, int * dummy0, int * dummy2, int * dummy3){return 0;} + XRRScreenConfiguration * XRRGetScreenInfo(Display* nativeDisplayType, Window window ){return 0;}; + int XRRConfigCurrentConfiguration(XRRScreenConfiguration * config, Rotation * rotation){return 0;}; + XRRScreenSize * XRRConfigSizes(XRRScreenConfiguration * config, int * nSizes){return 0;}; + int XRRConfigCurrentRate(XRRScreenConfiguration * config){return 0;}; + short * XRRConfigRates(XRRScreenConfiguration * config, int sizeID, int * nRates){return 0;}; + void XRRFreeScreenConfigInfo(XRRScreenConfiguration * config){} + int DefaultScreen(NativeDisplayType nativeDisplayType){return 0;}; + int DisplayWidth(Display* nativeDisplayType, int screen){return 0;}; + int DisplayHeight(Display* nativeDisplayType, int screen){return 0;}; + Display* XOpenDisplay(int num){return NULL;}; + void XCloseDisplay(Display* nativeDisplayType){}; + Atom XInternAtom(Display* nativeDisplayType, char * name, X11Bool isTrue) {return Atom();}; + char * DisplayString(NativeDisplayType nativeDisplayType){return 0;}; + const char * XDisplayName(char * name){return 0;}; + Visual * DefaultVisual(Display* nativeDisplayType, int screen){return 0;}; + int XVisualIDFromVisual(Visual *v){return 0;}; + void XRRSetScreenConfigAndRate(Display* nativeDisplayType, XRRScreenConfiguration * config, Window window, int size, Rotation rotation, int mode, int currentTime ){}; + XVisualInfo * XGetVisualInfo(Display* nativeDisplayType, int mask, XVisualInfo * info, int * n){return 0;}; + typedef int (*XErrorHandler)(Display *, XErrorEvent*); + XErrorHandler XSetErrorHandler(XErrorHandler xErrorHandler){return 0;}; + void XDestroyWindow(Display* nativeDisplayType, Window nativeWindowType){}; + bool XGetWindowAttributes(Display* nativeDisplayType, Window nativeWindowType, XWindowAttributes * xWindowAttributes){return 0;}; + int XCreateColormap(Display* nativeDisplayType, Window nativeWindowType, int visual, int allocNone){return 0;}; + Window XCreateWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top, int width, int height, int dummy1, int depth, int inputOutput, int visual, int mask, XSetWindowAttributes * xSetWindowAttributes){return Window();}; + void XFree(void *data){}; + XWMHints * XAllocWMHints(){return 0;}; + XSizeHints * XAllocSizeHints(){return 0;}; + void XSetWMProperties(Display* nativeDisplayType, Window nativeWindowType,XTextProperty * titleprop, char * dummy1, char * dummy2, int num, XSizeHints *sizeHints, XWMHints *wmHints, char * dummy3){}; + void XSetWMProtocols(Display* nativeDisplayType, Window nativeWindowType, Atom * atom, int num){}; + void XMapWindow(Display* nativeDisplayType, Window nativeWindowType){}; + void XFlush(Display* nativeDisplayType){}; + void XMoveWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top){}; + void XResizeWindow(Display* nativeDisplayType, Window nativeWindowType, int left, int top){}; + void XQueryTree(Display* nativeDisplayType, Window nativeWindowType, Window * root, Window *parent, Window **children, unsigned int * nChildren){}; + void XSendEvent(Display* nativeDisplayType, Window nativeWindowType, int dummy1, int mask, XEvent* xevent){}; #endif namespace Ogre { @@ -94,7 +94,7 @@ namespace Ogre { int dummy = 0; - // TODO: Probe video modes + // TODO: Probe video modes mCurrentMode.first.first = DisplayWidth(mNativeDisplay, DefaultScreen(mNativeDisplay)); mCurrentMode.first.second = DisplayHeight(mNativeDisplay, DefaultScreen(mNativeDisplay)); mCurrentMode.second = 0; @@ -143,7 +143,7 @@ namespace Ogre { { if (!mNativeDisplay) { - mNativeDisplay = (NativeDisplayType)XOpenDisplay(NULL); + mNativeDisplay = (NativeDisplayType)XOpenDisplay(NULL); if (!mNativeDisplay) { @@ -162,7 +162,7 @@ namespace Ogre { String X11EGLSupport::getDisplayName(void) { - return String((const char*)XDisplayName(DisplayString(mNativeDisplay))); + return String((const char*)XDisplayName(DisplayString(mNativeDisplay))); } @@ -265,8 +265,8 @@ namespace Ogre { return window; } - //X11EGLSupport::getGLDisplay sets up the native variable - //then calls EGLSupport::getGLDisplay + //X11EGLSupport::getGLDisplay sets up the native variable + //then calls EGLSupport::getGLDisplay EGLDisplay X11EGLSupport::getGLDisplay() { if (!mGLDisplay) diff --git a/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLWindow.cpp b/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLWindow.cpp index 5393ba73c7d..c7650cbe598 100644 --- a/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLWindow.cpp +++ b/RenderSystems/GLES2/src/EGL/X11/OgreX11EGLWindow.cpp @@ -52,384 +52,384 @@ extern "C" } - int (*oldXErrorHandler)(Display *, XErrorEvent*); + int (*oldXErrorHandler)(Display *, XErrorEvent*); } namespace Ogre { - X11EGLWindow::X11EGLWindow(X11EGLSupport *glsupport) - : EGLWindow(glsupport) - //, mParentWindow(glsupport) todo - { - mGLSupport = glsupport; - mNativeDisplay = glsupport->getNativeDisplay(); - } - - X11EGLWindow::~X11EGLWindow() - { - - mNativeDisplay = mGLSupport->getNativeDisplay(); - // Ignore fatal XErrorEvents from stale handles. - oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); - - if (mWindow) - { - XDestroyWindow((Display*)mNativeDisplay, (Window)mWindow); - } - - XSetErrorHandler(oldXErrorHandler); - mWindow = 0; - - } - - void X11EGLWindow::getCustomAttribute( const String& name, void* pData ) - { - EGLWindow::getCustomAttribute(name, pData); - if (name == "ATOM") - { - *static_cast< ::Atom* >(pData) = mGLSupport->mAtomDeleteWindow; - return; - } - else if (name == "XDISPLAY") - { - *static_cast(pData) = mGLSupport->getNativeDisplay(); - return; - } - else if (name == "XWINDOW") - { - *static_cast(pData) = mWindow; - return; - } - - } - - EGLContext * X11EGLWindow::createEGLContext() const - { - return new X11EGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); - } - - void X11EGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) - { - NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); - left = DisplayWidth((Display*)mNativeDisplay, DefaultScreen(mNativeDisplay))/2 - width/2; - top = DisplayHeight((Display*)mNativeDisplay, DefaultScreen(mNativeDisplay))/2 - height/2; - } - - void X11EGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) - { - if (miscParams) - { - NameValuePairList::const_iterator opt; - NameValuePairList::const_iterator end = miscParams->end(); - - mExternalWindow = 0; - mNativeDisplay = mGLSupport->getNativeDisplay(); - mParentWindow = DefaultRootWindow((Display*)mNativeDisplay); - - if ((opt = miscParams->find("parentWindowHandle")) != end) - { - //vector::type tokens = StringUtil::split(opt->second, " :"); - StringVector tokens = StringUtil::split(opt->second, " :"); - - if (tokens.size() == 3) - { - // deprecated display:screen:xid format - mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); - } - else - { - // xid format - mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[0]); - } - } - else if ((opt = miscParams->find("externalWindowHandle")) != end) - { - //vector::type tokens = StringUtil::split(opt->second, " :"); - StringVector tokens = StringUtil::split(opt->second, " :"); - - LogManager::getSingleton().logMessage( - "EGLWindow::create: The externalWindowHandle parameter is deprecated.\n" - "Use the parentWindowHandle or currentGLContext parameter instead."); - if (tokens.size() == 3) - { - // Old display:screen:xid format - // The old EGL code always created a "parent" window in this case: - mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); - } - else if (tokens.size() == 4) - { - // Old display:screen:xid:visualinfo format - mExternalWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); - } - else - { - // xid format - mExternalWindow = (Window)StringConverter::parseUnsignedLong(tokens[0]); - } - } - - } - - // Ignore fatal XErrorEvents during parameter validation: - oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); - - // Validate parentWindowHandle - if (mParentWindow != DefaultRootWindow((Display*)mNativeDisplay)) - { - XWindowAttributes windowAttrib; - - if (!XGetWindowAttributes((Display*)mNativeDisplay, mParentWindow, &windowAttrib) || - windowAttrib.root != DefaultRootWindow((Display*)mNativeDisplay)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Invalid parentWindowHandle (wrong server or screen)", - "EGLWindow::create"); - } - } - - // Validate externalWindowHandle - if (mExternalWindow != 0) - { - XWindowAttributes windowAttrib; - - if (!XGetWindowAttributes((Display*)mNativeDisplay, mExternalWindow, &windowAttrib) || - windowAttrib.root != DefaultRootWindow((Display*)mNativeDisplay)) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Invalid externalWindowHandle (wrong server or screen)", - "EGLWindow::create"); - } - - mEglConfig = 0; - mEglSurface = createSurfaceFromWindow(mEglDisplay, (NativeWindowType)mExternalWindow); - } - - XSetErrorHandler(oldXErrorHandler); - - mIsTopLevel = (!mIsExternal && mParentWindow == DefaultRootWindow((Display*)mNativeDisplay)); - - } - - void X11EGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) - { - mEglDisplay = mGLSupport->getGLDisplay();//todo - XSetWindowAttributes attr; - ulong mask; - XVisualInfo *visualInfo = mGLSupport->getVisualFromFBConfig(mEglConfig); - - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap((Display*)mNativeDisplay, - DefaultRootWindow((Display*)mNativeDisplay), - visualInfo->visual, - AllocNone); - attr.event_mask = StructureNotifyMask | VisibilityChangeMask | FocusChangeMask; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - - if(mIsFullScreen && mGLSupport->mAtomFullScreen == None) - { - LogManager::getSingleton().logMessage("X11EGLWindow::switchFullScreen: Your WM has no fullscreen support"); - - // A second best approach for outdated window managers - attr.backing_store = NotUseful; - attr.save_under = False; - attr.override_redirect = True; - mask |= CWSaveUnder | CWBackingStore | CWOverrideRedirect; - left = top = 0; - } - - // Create window on server - mWindow = (NativeWindowType)XCreateWindow((Display*)mNativeDisplay, - mParentWindow, - left, top, width, height, - 0, visualInfo->depth, - InputOutput, - visualInfo->visual, mask, &attr); - XFree(visualInfo); - - if(!mWindow) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unable to create an X NativeWindowType", - "EGLWindow::create"); - } - - if (mIsTopLevel) - { - XWMHints *wmHints; - XSizeHints *sizeHints; - - // Is this really necessary ? Which broken WM might need it? - if ((wmHints = XAllocWMHints()) != NULL) - { - wmHints->initial_state = NormalState; - wmHints->input = True; - wmHints->flags = StateHint | InputHint; - } - - // Is this really necessary ? Which broken WM might need it? - if ((sizeHints = XAllocSizeHints()) != NULL) - { - sizeHints->flags = USPosition; - } - - XTextProperty titleprop; - char *lst = (char*)title.c_str(); - XStringListToTextProperty((char **)&lst, 1, &titleprop); - XSetWMProperties((Display*)mNativeDisplay, (Window)mWindow, &titleprop, - NULL, NULL, 0, sizeHints, wmHints, NULL); - - XFree(titleprop.value); - XFree(wmHints); - XFree(sizeHints); - - XSetWMProtocols((Display*)mNativeDisplay, (Window)mWindow, &mGLSupport->mAtomDeleteWindow, 1); - - XWindowAttributes windowAttrib; - - XGetWindowAttributes((Display*)mNativeDisplay, (Window)mWindow, &windowAttrib); - - left = windowAttrib.x; - top = windowAttrib.y; - width = windowAttrib.width; - height = windowAttrib.height; - } - - mEglSurface = createSurfaceFromWindow(mGLSupport->getGLDisplay(), mWindow); - - XMapWindow((Display*)mNativeDisplay, (Window)mWindow); - - if (mIsFullScreen) - { - switchFullScreen(true); - } - - XFlush((Display*)mNativeDisplay); - - WindowEventUtilities::_addRenderWindow(this); - } - - void X11EGLWindow::setFullscreen( bool fullscreen, uint width, uint height ) - { - if (mIsFullScreen != fullscreen && &mGLSupport->mAtomFullScreen == None) - { - // Without WM support it is best to give up. - LogManager::getSingleton().logMessage("EGLWindow::switchFullScreen: Your WM has no fullscreen support"); - return; - } - EGLWindow::setFullscreen(fullscreen, width, height); - } - - void X11EGLWindow::reposition( int left, int top ) - { - if (mClosed || ! mIsTopLevel) - { - return; - } - - XMoveWindow((Display*)mGLSupport->getNativeDisplay(), (Window)mWindow, left, top); - } - - void X11EGLWindow::resize(uint width, uint height) - { - if (mClosed) - { - return; - } - - if (mWidth == width && mHeight == height) - { - return; - } - - if (width != 0 && height != 0) - { - if (mIsTopLevel) - { - XResizeWindow((Display*)mGLSupport->getNativeDisplay(), (Window)mWindow, width, height); - } - else - { - mWidth = width; - mHeight = height; - - for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) - { - (*it).second->_updateDimensions(); - } - } - } - } - - void X11EGLWindow::windowMovedOrResized() - { - if (mClosed || !mWindow) - { - return; - } - - NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); - XWindowAttributes windowAttrib; - - if (mIsTopLevel && !mIsFullScreen) - { - Window parent, root, *children; - uint nChildren; - - XQueryTree((Display*)mNativeDisplay, (Window)mWindow, &root, &parent, &children, &nChildren); - - if (children) - { - XFree(children); - } - - XGetWindowAttributes((Display*)mNativeDisplay, parent, &windowAttrib); - mLeft = windowAttrib.x; - mTop = windowAttrib.y; - } - - XGetWindowAttributes((Display*)mNativeDisplay, (Window)mWindow, &windowAttrib); - - if (mWidth == windowAttrib.width && mHeight == windowAttrib.height) - { - return; - } - - mWidth = windowAttrib.width; - mHeight = windowAttrib.height; - - for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) - { - (*it).second->_updateDimensions(); - } - } - void X11EGLWindow::switchFullScreen(bool fullscreen) - { - if (&mGLSupport->mAtomFullScreen != None) - { - NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); - XClientMessageEvent xMessage; - - xMessage.type = ClientMessage; - xMessage.serial = 0; - xMessage.send_event = True; - xMessage.window = (Window)mWindow; - xMessage.message_type = mGLSupport->mAtomState; - xMessage.format = 32; - xMessage.data.l[0] = (fullscreen ? 1 : 0); - xMessage.data.l[1] = mGLSupport->mAtomFullScreen; - xMessage.data.l[2] = 0; - - XSendEvent((Display*)mNativeDisplay, DefaultRootWindow((Display*)mNativeDisplay), False, - SubstructureRedirectMask | SubstructureNotifyMask, - (XEvent*)&xMessage); - - mIsFullScreen = fullscreen; - } - } - - - //Moved EGLWindow::create to native source because it has native calls in it + X11EGLWindow::X11EGLWindow(X11EGLSupport *glsupport) + : EGLWindow(glsupport) + //, mParentWindow(glsupport) todo + { + mGLSupport = glsupport; + mNativeDisplay = glsupport->getNativeDisplay(); + } + + X11EGLWindow::~X11EGLWindow() + { + + mNativeDisplay = mGLSupport->getNativeDisplay(); + // Ignore fatal XErrorEvents from stale handles. + oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); + + if (mWindow) + { + XDestroyWindow((Display*)mNativeDisplay, (Window)mWindow); + } + + XSetErrorHandler(oldXErrorHandler); + mWindow = 0; + + } + + void X11EGLWindow::getCustomAttribute( const String& name, void* pData ) + { + EGLWindow::getCustomAttribute(name, pData); + if (name == "ATOM") + { + *static_cast< ::Atom* >(pData) = mGLSupport->mAtomDeleteWindow; + return; + } + else if (name == "XDISPLAY") + { + *static_cast(pData) = mGLSupport->getNativeDisplay(); + return; + } + else if (name == "XWINDOW") + { + *static_cast(pData) = mWindow; + return; + } + + } + + EGLContext * X11EGLWindow::createEGLContext() const + { + return new X11EGLContext(mEglDisplay, mGLSupport, mEglConfig, mEglSurface); + } + + void X11EGLWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) + { + NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); + left = DisplayWidth((Display*)mNativeDisplay, DefaultScreen(mNativeDisplay))/2 - width/2; + top = DisplayHeight((Display*)mNativeDisplay, DefaultScreen(mNativeDisplay))/2 - height/2; + } + + void X11EGLWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) + { + if (miscParams) + { + NameValuePairList::const_iterator opt; + NameValuePairList::const_iterator end = miscParams->end(); + + mExternalWindow = 0; + mNativeDisplay = mGLSupport->getNativeDisplay(); + mParentWindow = DefaultRootWindow((Display*)mNativeDisplay); + + if ((opt = miscParams->find("parentWindowHandle")) != end) + { + //vector::type tokens = StringUtil::split(opt->second, " :"); + StringVector tokens = StringUtil::split(opt->second, " :"); + + if (tokens.size() == 3) + { + // deprecated display:screen:xid format + mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); + } + else + { + // xid format + mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[0]); + } + } + else if ((opt = miscParams->find("externalWindowHandle")) != end) + { + //vector::type tokens = StringUtil::split(opt->second, " :"); + StringVector tokens = StringUtil::split(opt->second, " :"); + + LogManager::getSingleton().logMessage( + "EGLWindow::create: The externalWindowHandle parameter is deprecated.\n" + "Use the parentWindowHandle or currentGLContext parameter instead."); + if (tokens.size() == 3) + { + // Old display:screen:xid format + // The old EGL code always created a "parent" window in this case: + mParentWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); + } + else if (tokens.size() == 4) + { + // Old display:screen:xid:visualinfo format + mExternalWindow = (Window)StringConverter::parseUnsignedLong(tokens[2]); + } + else + { + // xid format + mExternalWindow = (Window)StringConverter::parseUnsignedLong(tokens[0]); + } + } + + } + + // Ignore fatal XErrorEvents during parameter validation: + oldXErrorHandler = XSetErrorHandler(safeXErrorHandler); + + // Validate parentWindowHandle + if (mParentWindow != DefaultRootWindow((Display*)mNativeDisplay)) + { + XWindowAttributes windowAttrib; + + if (!XGetWindowAttributes((Display*)mNativeDisplay, mParentWindow, &windowAttrib) || + windowAttrib.root != DefaultRootWindow((Display*)mNativeDisplay)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Invalid parentWindowHandle (wrong server or screen)", + "EGLWindow::create"); + } + } + + // Validate externalWindowHandle + if (mExternalWindow != 0) + { + XWindowAttributes windowAttrib; + + if (!XGetWindowAttributes((Display*)mNativeDisplay, mExternalWindow, &windowAttrib) || + windowAttrib.root != DefaultRootWindow((Display*)mNativeDisplay)) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Invalid externalWindowHandle (wrong server or screen)", + "EGLWindow::create"); + } + + mEglConfig = 0; + mEglSurface = createSurfaceFromWindow(mEglDisplay, (NativeWindowType)mExternalWindow); + } + + XSetErrorHandler(oldXErrorHandler); + + mIsTopLevel = (!mIsExternal && mParentWindow == DefaultRootWindow((Display*)mNativeDisplay)); + + } + + void X11EGLWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) + { + mEglDisplay = mGLSupport->getGLDisplay();//todo + XSetWindowAttributes attr; + ulong mask; + XVisualInfo *visualInfo = mGLSupport->getVisualFromFBConfig(mEglConfig); + + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap((Display*)mNativeDisplay, + DefaultRootWindow((Display*)mNativeDisplay), + visualInfo->visual, + AllocNone); + attr.event_mask = StructureNotifyMask | VisibilityChangeMask | FocusChangeMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + if(mIsFullScreen && mGLSupport->mAtomFullScreen == None) + { + LogManager::getSingleton().logMessage("X11EGLWindow::switchFullScreen: Your WM has no fullscreen support"); + + // A second best approach for outdated window managers + attr.backing_store = NotUseful; + attr.save_under = False; + attr.override_redirect = True; + mask |= CWSaveUnder | CWBackingStore | CWOverrideRedirect; + left = top = 0; + } + + // Create window on server + mWindow = (NativeWindowType)XCreateWindow((Display*)mNativeDisplay, + mParentWindow, + left, top, width, height, + 0, visualInfo->depth, + InputOutput, + visualInfo->visual, mask, &attr); + XFree(visualInfo); + + if(!mWindow) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unable to create an X NativeWindowType", + "EGLWindow::create"); + } + + if (mIsTopLevel) + { + XWMHints *wmHints; + XSizeHints *sizeHints; + + // Is this really necessary ? Which broken WM might need it? + if ((wmHints = XAllocWMHints()) != NULL) + { + wmHints->initial_state = NormalState; + wmHints->input = True; + wmHints->flags = StateHint | InputHint; + } + + // Is this really necessary ? Which broken WM might need it? + if ((sizeHints = XAllocSizeHints()) != NULL) + { + sizeHints->flags = USPosition; + } + + XTextProperty titleprop; + char *lst = (char*)title.c_str(); + XStringListToTextProperty((char **)&lst, 1, &titleprop); + XSetWMProperties((Display*)mNativeDisplay, (Window)mWindow, &titleprop, + NULL, NULL, 0, sizeHints, wmHints, NULL); + + XFree(titleprop.value); + XFree(wmHints); + XFree(sizeHints); + + XSetWMProtocols((Display*)mNativeDisplay, (Window)mWindow, &mGLSupport->mAtomDeleteWindow, 1); + + XWindowAttributes windowAttrib; + + XGetWindowAttributes((Display*)mNativeDisplay, (Window)mWindow, &windowAttrib); + + left = windowAttrib.x; + top = windowAttrib.y; + width = windowAttrib.width; + height = windowAttrib.height; + } + + mEglSurface = createSurfaceFromWindow(mGLSupport->getGLDisplay(), mWindow); + + XMapWindow((Display*)mNativeDisplay, (Window)mWindow); + + if (mIsFullScreen) + { + switchFullScreen(true); + } + + XFlush((Display*)mNativeDisplay); + + WindowEventUtilities::_addRenderWindow(this); + } + + void X11EGLWindow::setFullscreen( bool fullscreen, uint width, uint height ) + { + if (mIsFullScreen != fullscreen && &mGLSupport->mAtomFullScreen == None) + { + // Without WM support it is best to give up. + LogManager::getSingleton().logMessage("EGLWindow::switchFullScreen: Your WM has no fullscreen support"); + return; + } + EGLWindow::setFullscreen(fullscreen, width, height); + } + + void X11EGLWindow::reposition( int left, int top ) + { + if (mClosed || ! mIsTopLevel) + { + return; + } + + XMoveWindow((Display*)mGLSupport->getNativeDisplay(), (Window)mWindow, left, top); + } + + void X11EGLWindow::resize(uint width, uint height) + { + if (mClosed) + { + return; + } + + if (mWidth == width && mHeight == height) + { + return; + } + + if (width != 0 && height != 0) + { + if (mIsTopLevel) + { + XResizeWindow((Display*)mGLSupport->getNativeDisplay(), (Window)mWindow, width, height); + } + else + { + mWidth = width; + mHeight = height; + + for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) + { + (*it).second->_updateDimensions(); + } + } + } + } + + void X11EGLWindow::windowMovedOrResized() + { + if (mClosed || !mWindow) + { + return; + } + + NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); + XWindowAttributes windowAttrib; + + if (mIsTopLevel && !mIsFullScreen) + { + Window parent, root, *children; + uint nChildren; + + XQueryTree((Display*)mNativeDisplay, (Window)mWindow, &root, &parent, &children, &nChildren); + + if (children) + { + XFree(children); + } + + XGetWindowAttributes((Display*)mNativeDisplay, parent, &windowAttrib); + mLeft = windowAttrib.x; + mTop = windowAttrib.y; + } + + XGetWindowAttributes((Display*)mNativeDisplay, (Window)mWindow, &windowAttrib); + + if (mWidth == windowAttrib.width && mHeight == windowAttrib.height) + { + return; + } + + mWidth = windowAttrib.width; + mHeight = windowAttrib.height; + + for (ViewportList::iterator it = mViewportList.begin(); it != mViewportList.end(); ++it) + { + (*it).second->_updateDimensions(); + } + } + void X11EGLWindow::switchFullScreen(bool fullscreen) + { + if (&mGLSupport->mAtomFullScreen != None) + { + NativeDisplayType mNativeDisplay = mGLSupport->getNativeDisplay(); + XClientMessageEvent xMessage; + + xMessage.type = ClientMessage; + xMessage.serial = 0; + xMessage.send_event = True; + xMessage.window = (Window)mWindow; + xMessage.message_type = mGLSupport->mAtomState; + xMessage.format = 32; + xMessage.data.l[0] = (fullscreen ? 1 : 0); + xMessage.data.l[1] = mGLSupport->mAtomFullScreen; + xMessage.data.l[2] = 0; + + XSendEvent((Display*)mNativeDisplay, DefaultRootWindow((Display*)mNativeDisplay), False, + SubstructureRedirectMask | SubstructureNotifyMask, + (XEvent*)&xMessage); + + mIsFullScreen = fullscreen; + } + } + + + //Moved EGLWindow::create to native source because it has native calls in it void X11EGLWindow::create(const String& name, uint width, uint height, bool fullScreen, const NameValuePairList *miscParams) { @@ -439,7 +439,7 @@ namespace Ogre { short frequency = 0; bool vsync = false; ::EGLContext eglContext = 0; - int left = 0; + int left = 0; int top = 0; getLeftAndTopFromNativeWindow(left, top, width, height); @@ -509,9 +509,9 @@ namespace Ogre { { mIsExternalGLControl = StringConverter::parseBool(opt->second); } - } + } - initNativeCreatedWindow(miscParams); + initNativeCreatedWindow(miscParams); if (mEglSurface) { @@ -574,12 +574,12 @@ namespace Ogre { mGLSupport->switchMode (width, height, frequency); } - if (!mIsExternal) + if (!mIsExternal) { - createNativeWindow(left, top, width, height, title); - } + createNativeWindow(left, top, width, height, title); + } - mContext = createEGLContext(); + mContext = createEGLContext(); ::EGLSurface oldDrawableDraw = eglGetCurrentSurface(EGL_DRAW); EGL_CHECK_ERROR @@ -599,10 +599,10 @@ namespace Ogre { mLeft = left; mTop = top; mActive = true; - mVisible = true; + mVisible = true; mClosed = false; - } + } } diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESCgProgram.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESCgProgram.h index ce10ddb6abf..10c92866081 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESCgProgram.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESCgProgram.h @@ -57,7 +57,7 @@ namespace Ogre { GLSLESCgProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - ~GLSLESCgProgram(); + ~GLSLESCgProgram(); /// Overridden from GLSLESProgram diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESCgProgramFactory.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESCgProgramFactory.h index f875ef31f9d..753a06e29c2 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESCgProgramFactory.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESCgProgramFactory.h @@ -39,12 +39,12 @@ namespace Ogre class _OgreGLES2Export GLSLESCgProgramFactory : public HighLevelGpuProgramFactory { protected: - static String sLanguageName; + static String sLanguageName; public: GLSLESCgProgramFactory(); virtual ~GLSLESCgProgramFactory(); - const String& getLanguage(void) const; + const String& getLanguage(void) const; HighLevelGpuProgram* create(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); void destroy(HighLevelGpuProgram* prog); }; diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESExtSupport.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESExtSupport.h index 25977418774..4528df586ac 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESExtSupport.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESExtSupport.h @@ -39,19 +39,19 @@ THE SOFTWARE. namespace Ogre { - // forward declarations - class GLSLESProgram; - class GLSLESGpuProgram; - class GLSLESLinkProgram; - class GLSLESLinkProgramManager; - class GLSLESProgramPipelineManager; - class GLSLESProgramFactory; - - /** If there is a message in GL info log then post it in the Ogre Log - @param msg The info log message string is appended to this string - @param obj The GL object that is used to retrieve the info log - */ - String logObjectInfo(const String& msg, const GLuint obj); + // forward declarations + class GLSLESProgram; + class GLSLESGpuProgram; + class GLSLESLinkProgram; + class GLSLESLinkProgramManager; + class GLSLESProgramPipelineManager; + class GLSLESProgramFactory; + + /** If there is a message in GL info log then post it in the Ogre Log + @param msg The info log message string is appended to this string + @param obj The GL object that is used to retrieve the info log + */ + String logObjectInfo(const String& msg, const GLuint obj); } // namespace Ogre diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESGpuProgram.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESGpuProgram.h index 14f321ed6ff..bba5558f9b7 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESGpuProgram.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESGpuProgram.h @@ -36,47 +36,47 @@ THE SOFTWARE. namespace Ogre { /** GLSL ES low level compiled shader object - this class is used to get at the linked program object - and provide an interface for GLES2RenderSystem calls. GLSL ES does not provide access to the - low level code of the shader so this class is really just a dummy place holder. - GLSL ES uses a program object to represent the active vertex and fragment programs used - but Ogre materials maintain separate instances of the active vertex and fragment programs - which creates a small problem for GLSL integration. The GLSLESGpuProgram class provides the - interface between the GLSLESLinkProgramManager, GLSLESProgramPipelineManager , GLES2RenderSystem, + and provide an interface for GLES2RenderSystem calls. GLSL ES does not provide access to the + low level code of the shader so this class is really just a dummy place holder. + GLSL ES uses a program object to represent the active vertex and fragment programs used + but Ogre materials maintain separate instances of the active vertex and fragment programs + which creates a small problem for GLSL integration. The GLSLESGpuProgram class provides the + interface between the GLSLESLinkProgramManager, GLSLESProgramPipelineManager , GLES2RenderSystem, and the active GLSLESProgram instances. - */ + */ class _OgreGLES2Export GLSLESGpuProgram : public GLES2GpuProgram { private: - /// GL Handle for the shader object - GLSLESProgram* mGLSLProgram; + /// GL Handle for the shader object + GLSLESProgram* mGLSLProgram; - /// Keep track of the number of vertex shaders created - static GLuint mVertexShaderCount; - /// Keep track of the number of fragment shaders created - static GLuint mFragmentShaderCount; + /// Keep track of the number of vertex shaders created + static GLuint mVertexShaderCount; + /// Keep track of the number of fragment shaders created + static GLuint mFragmentShaderCount; /** Flag indicating that the program object has been successfully linked. Only used when programs are linked separately with GL_EXT_separate_shader_objects. */ - GLint mLinked; + GLint mLinked; - public: + public: GLSLESGpuProgram(GLSLESProgram* parent); - ~GLSLESGpuProgram(); - - /// Execute the binding functions for this program - void bindProgram(void); - /// Execute the unbinding functions for this program - void unbindProgram(void); - /// Execute the param binding functions for this program - void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask); - /// Execute the shared param binding functions for this program - void bindProgramSharedParameters(GpuProgramParametersSharedPtr params, uint16 mask); - /// Execute the pass iteration param binding functions for this program - void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params); - - /// Get the GLSLESProgram for the shader object - GLSLESProgram* getGLSLProgram(void) const { return mGLSLProgram; } + ~GLSLESGpuProgram(); + + /// Execute the binding functions for this program + void bindProgram(void); + /// Execute the unbinding functions for this program + void unbindProgram(void); + /// Execute the param binding functions for this program + void bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask); + /// Execute the shared param binding functions for this program + void bindProgramSharedParameters(GpuProgramParametersSharedPtr params, uint16 mask); + /// Execute the pass iteration param binding functions for this program + void bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params); + + /// Get the GLSLESProgram for the shader object + GLSLESProgram* getGLSLProgram(void) const { return mGLSLProgram; } /** Return the programs link status Only used when programs are linked separately with GL_EXT_separate_shader_objects. @@ -91,10 +91,10 @@ namespace Ogre { protected: /// Overridden from GpuProgram void loadFromSource(void); - /// @copydoc Resource::unloadImpl - void unloadImpl(void); - /// @copydoc Resource::loadImpl - void loadImpl(void); + /// @copydoc Resource::unloadImpl + void unloadImpl(void); + /// @copydoc Resource::loadImpl + void loadImpl(void); }; } diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESLinkProgram.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESLinkProgram.h index 10afea9764d..95b29fbe856 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESLinkProgram.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESLinkProgram.h @@ -38,21 +38,21 @@ namespace Ogre { class GLSLESGpuProgram; - /** C++ encapsulation of GLSL ES Program Object + /** C++ encapsulation of GLSL ES Program Object - */ + */ - class _OgreGLES2Export GLSLESLinkProgram : public GLSLESProgramCommon MANAGED_RESOURCE - { - protected: + class _OgreGLES2Export GLSLESLinkProgram : public GLSLESProgramCommon MANAGED_RESOURCE + { + protected: virtual void extractLayoutQualifiers(void) {} - /// Compiles and links the vertex and fragment programs - virtual void compileAndLink(void); + /// Compiles and links the vertex and fragment programs + virtual void compileAndLink(void); /// Put a program in use virtual void _useProgram(void); - void buildGLUniformReferences(void); + void buildGLUniformReferences(void); #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID /** See AndroidResource. */ @@ -62,28 +62,28 @@ namespace Ogre { virtual void notifyOnContextReset(); #endif - public: - /// Constructor should only be used by GLSLESLinkProgramManager - GLSLESLinkProgram(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram); - virtual ~GLSLESLinkProgram(void); - - /** Makes a program object active by making sure it is linked and then putting it in use. - */ - void activate(void); - - /** Updates program object uniforms using data from GpuProgramParameters. - normally called by GLSLESGpuProgram::bindParameters() just before rendering occurs. - */ - virtual void updateUniforms(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType); - /** Updates program object uniform blocks using data from GpuProgramParameters. + public: + /// Constructor should only be used by GLSLESLinkProgramManager + GLSLESLinkProgram(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram); + virtual ~GLSLESLinkProgram(void); + + /** Makes a program object active by making sure it is linked and then putting it in use. + */ + void activate(void); + + /** Updates program object uniforms using data from GpuProgramParameters. + normally called by GLSLESGpuProgram::bindParameters() just before rendering occurs. + */ + virtual void updateUniforms(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType); + /** Updates program object uniform blocks using data from GpuProgramParameters. normally called by GLSLGpuProgram::bindParameters() just before rendering occurs. */ - virtual void updateUniformBlocks(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType); - /** Updates program object uniforms using data from pass iteration GpuProgramParameters. - normally called by GLSLESGpuProgram::bindMultiPassParameters() just before multi pass rendering occurs. - */ - virtual void updatePassIterationUniforms(GpuProgramParametersSharedPtr params); - }; + virtual void updateUniformBlocks(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType); + /** Updates program object uniforms using data from pass iteration GpuProgramParameters. + normally called by GLSLESGpuProgram::bindMultiPassParameters() just before multi pass rendering occurs. + */ + virtual void updatePassIterationUniforms(GpuProgramParametersSharedPtr params); + }; } diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESLinkProgramManager.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESLinkProgramManager.h index 8419509c013..e3d790ee909 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESLinkProgramManager.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESLinkProgramManager.h @@ -38,61 +38,61 @@ THE SOFTWARE. namespace Ogre { - /** Ogre assumes that there are separate vertex and fragment programs to deal with but - GLSL ES has one program object that represents the active vertex and fragment shader objects - during a rendering state. GLSL Vertex and fragment - shader objects are compiled separately and then attached to a program object and then the - program object is linked. Since Ogre can only handle one vertex program and one fragment - program being active in a pass, the GLSL ES Link Program Manager does the same. The GLSL ES Link - program manager acts as a state machine and activates a program object based on the active - vertex and fragment program. Previously created program objects are stored along with a unique - key in a hash_map for quick retrieval the next time the program object is required. - */ - - class _OgreGLES2Export GLSLESLinkProgramManager : public GLSLESProgramManagerCommon, public Singleton - { - - private: - - typedef map::type LinkProgramMap; - typedef LinkProgramMap::iterator LinkProgramIterator; - - /// Container holding previously created program objects - LinkProgramMap mLinkPrograms; - - /// Active objects defining the active rendering gpu state - GLSLESLinkProgram* mActiveLinkProgram; - - typedef map::type StringToEnumMap; - StringToEnumMap mTypeEnumMap; - - public: - - GLSLESLinkProgramManager(void); - - ~GLSLESLinkProgramManager(void); - - /** - Get the program object that links the two active shader objects together - if a program object was not already created and linked a new one is created and linked - */ - GLSLESLinkProgram* getActiveLinkProgram(void); - - /** Set the active fragment shader for the next rendering state. - The active program object will be cleared. - Normally called from the GLSLESGpuProgram::bindProgram and unbindProgram methods - */ - void setActiveFragmentShader(GLSLESGpuProgram* fragmentGpuProgram); - /** Set the active vertex shader for the next rendering state. - The active program object will be cleared. - Normally called from the GLSLESGpuProgram::bindProgram and unbindProgram methods - */ - void setActiveVertexShader(GLSLESGpuProgram* vertexGpuProgram); - - static GLSLESLinkProgramManager& getSingleton(void); + /** Ogre assumes that there are separate vertex and fragment programs to deal with but + GLSL ES has one program object that represents the active vertex and fragment shader objects + during a rendering state. GLSL Vertex and fragment + shader objects are compiled separately and then attached to a program object and then the + program object is linked. Since Ogre can only handle one vertex program and one fragment + program being active in a pass, the GLSL ES Link Program Manager does the same. The GLSL ES Link + program manager acts as a state machine and activates a program object based on the active + vertex and fragment program. Previously created program objects are stored along with a unique + key in a hash_map for quick retrieval the next time the program object is required. + */ + + class _OgreGLES2Export GLSLESLinkProgramManager : public GLSLESProgramManagerCommon, public Singleton + { + + private: + + typedef map::type LinkProgramMap; + typedef LinkProgramMap::iterator LinkProgramIterator; + + /// Container holding previously created program objects + LinkProgramMap mLinkPrograms; + + /// Active objects defining the active rendering gpu state + GLSLESLinkProgram* mActiveLinkProgram; + + typedef map::type StringToEnumMap; + StringToEnumMap mTypeEnumMap; + + public: + + GLSLESLinkProgramManager(void); + + ~GLSLESLinkProgramManager(void); + + /** + Get the program object that links the two active shader objects together + if a program object was not already created and linked a new one is created and linked + */ + GLSLESLinkProgram* getActiveLinkProgram(void); + + /** Set the active fragment shader for the next rendering state. + The active program object will be cleared. + Normally called from the GLSLESGpuProgram::bindProgram and unbindProgram methods + */ + void setActiveFragmentShader(GLSLESGpuProgram* fragmentGpuProgram); + /** Set the active vertex shader for the next rendering state. + The active program object will be cleared. + Normally called from the GLSLESGpuProgram::bindProgram and unbindProgram methods + */ + void setActiveVertexShader(GLSLESGpuProgram* vertexGpuProgram); + + static GLSLESLinkProgramManager& getSingleton(void); static GLSLESLinkProgramManager* getSingletonPtr(void); - }; + }; } diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESPreprocessor.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESPreprocessor.h index 285bf64c509..61c37a0c80d 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESPreprocessor.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESPreprocessor.h @@ -196,7 +196,7 @@ class CPreprocessor ~Macro () //{ OGRE_DELETE [] Args; OGRE_DELETE Next; } - { delete [] Args; delete Next; } + { delete [] Args; delete Next; } /// Expand the macro value (will not work for functions) Token Expand (int iNumArgs, Token *iArgs, Macro *iMacros); diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgram.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgram.h index 97747516fc6..37e62f82938 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgram.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgram.h @@ -36,16 +36,16 @@ namespace Ogre { /** Specialisation of HighLevelGpuProgram to provide support for OpenGL Shader Language (GLSL ES) for OpenGL ES 2.0. @remarks - GLSL ES has no target assembler or entry point specification like DirectX 9 HLSL. - Vertex and Fragment shaders only have one entry point called "main". - When a shader is compiled, microcode is generated but can not be accessed by - the application. - GLSL ES also does not provide assembler low level output after compiling. The GL ES Render - system assumes that the Gpu program is a GL Gpu program so GLSLESProgram will create a - GLSLESGpuProgram that is subclassed from GLES2GpuProgram for the low level implementation. - The GLES2Program class will create a shader object and compile the source but will - not create a program object. It's up to GLES2GpuProgram class to request a program object - to link the shader object to. + GLSL ES has no target assembler or entry point specification like DirectX 9 HLSL. + Vertex and Fragment shaders only have one entry point called "main". + When a shader is compiled, microcode is generated but can not be accessed by + the application. + GLSL ES also does not provide assembler low level output after compiling. The GL ES Render + system assumes that the Gpu program is a GL Gpu program so GLSLESProgram will create a + GLSLESGpuProgram that is subclassed from GLES2GpuProgram for the low level implementation. + The GLES2Program class will create a shader object and compile the source but will + not create a program object. It's up to GLES2GpuProgram class to request a program object + to link the shader object to. */ class _OgreGLES2Export GLSLESProgram : public HighLevelGpuProgram MANAGED_RESOURCE { @@ -56,50 +56,50 @@ namespace Ogre { { public: String doGet(const void* target) const; - void doSet(void* target, const String& val); + void doSet(void* target, const String& val); }; #endif - /// Command object for setting macro defines - class CmdPreprocessorDefines : public ParamCommand - { - public: - String doGet(const void* target) const; - void doSet(void* target, const String& val); - }; + /// Command object for setting macro defines + class CmdPreprocessorDefines : public ParamCommand + { + public: + String doGet(const void* target) const; + void doSet(void* target, const String& val); + }; GLSLESProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - ~GLSLESProgram(); + ~GLSLESProgram(); /// GL Shader Handle - GLuint getGLShaderHandle() const { return mGLShaderHandle; } - void attachToProgramObject( const GLuint programObject ); - void detachFromProgramObject( const GLuint programObject ); - GLuint getGLProgramHandle() const { return mGLProgramHandle; } + GLuint getGLShaderHandle() const { return mGLShaderHandle; } + void attachToProgramObject( const GLuint programObject ); + void detachFromProgramObject( const GLuint programObject ); + GLuint getGLProgramHandle() const { return mGLProgramHandle; } - /// Overridden - bool getPassTransformStates(void) const; - bool getPassSurfaceAndLightStates(void) const; - bool getPassFogStates(void) const; + /// Overridden + bool getPassTransformStates(void) const; + bool getPassSurfaceAndLightStates(void) const; + bool getPassFogStates(void) const; - /// Sets the preprocessor defines use to compile the program. - void setPreprocessorDefines(const String& defines) { mPreprocessorDefines = defines; } - /// Sets the preprocessor defines use to compile the program. - const String& getPreprocessorDefines(void) const { return mPreprocessorDefines; } + /// Sets the preprocessor defines use to compile the program. + void setPreprocessorDefines(const String& defines) { mPreprocessorDefines = defines; } + /// Sets the preprocessor defines use to compile the program. + const String& getPreprocessorDefines(void) const { return mPreprocessorDefines; } #if !OGRE_NO_GLES2_GLSL_OPTIMISER /// Sets if the GLSL optimiser is enabled. - void setOptimiserEnabled(bool enabled); - /// Gets if the GLSL optimiser is enabled. - bool getOptimiserEnabled(void) const { return mOptimiserEnabled; } + void setOptimiserEnabled(bool enabled); + /// Gets if the GLSL optimiser is enabled. + bool getOptimiserEnabled(void) const { return mOptimiserEnabled; } /// Sets if the GLSL source has been optimised successfully void setIsOptimised(bool flag) { mIsOptimised = flag; } /// Gets if the GLSL source has been optimised successfully bool getIsOptimised(void) { return mIsOptimised; } - /// Sets the optimised GLSL source + /// Sets the optimised GLSL source void setOptimisedSource(const String& src) { mOptimisedSource = src; } /// Gets he optimised GLSL source String getOptimisedSource(void) { return mOptimisedSource; } @@ -107,61 +107,61 @@ namespace Ogre { /// Overridden from GpuProgram const String& getLanguage(void) const; - /// Overridden from GpuProgram - GpuProgramParametersSharedPtr createParameters(void); + /// Overridden from GpuProgram + GpuProgramParametersSharedPtr createParameters(void); - /// compile source into shader object - bool compile( const bool checkErrors = false); + /// compile source into shader object + bool compile( const bool checkErrors = false); - protected: - static CmdPreprocessorDefines msCmdPreprocessorDefines; + protected: + static CmdPreprocessorDefines msCmdPreprocessorDefines; #if !OGRE_NO_GLES2_GLSL_OPTIMISER - static CmdOptimisation msCmdOptimisation; + static CmdOptimisation msCmdOptimisation; #endif /** Internal load implementation, must be implemented by subclasses. */ void loadFromSource(void); /** Internal method for creating a dummy low-level program for this - high-level program. GLSL ES does not give access to the low level implementation of the - shader so this method creates an object sub-classed from GLES2GpuProgram just to be - compatible with GLES2RenderSystem. - */ - void createLowLevelImpl(void); + high-level program. GLSL ES does not give access to the low level implementation of the + shader so this method creates an object sub-classed from GLES2GpuProgram just to be + compatible with GLES2RenderSystem. + */ + void createLowLevelImpl(void); /// Internal unload implementation, must be implemented by subclasses void unloadHighLevelImpl(void); - /// Overridden from HighLevelGpuProgram - void unloadImpl(void); + /// Overridden from HighLevelGpuProgram + void unloadImpl(void); /// Populate the passed parameters with name->index map void populateParameterNames(GpuProgramParametersSharedPtr params); /// Populate the passed parameters with name->index map, must be overridden void buildConstantDefinitions() const; - /** check the compile result for an error with default precision - and recompile if needed. - some glsl compilers return an error default precision is set to types other then - int or float, this function test a failed compile result for the error, - delete the needed lines from the source if needed then try to re-compile. - */ - void checkAndFixInvalidDefaultPrecisionError( String &message ); + /** check the compile result for an error with default precision - and recompile if needed. + some glsl compilers return an error default precision is set to types other then + int or float, this function test a failed compile result for the error, + delete the needed lines from the source if needed then try to re-compile. + */ + void checkAndFixInvalidDefaultPrecisionError( String &message ); #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID /** See AndroidResource. */ virtual void notifyOnContextLost(); #endif - private: - /// GL handle for shader object - GLuint mGLShaderHandle; + private: + /// GL handle for shader object + GLuint mGLShaderHandle; GLuint mGLProgramHandle; - /// Flag indicating if shader object successfully compiled - GLint mCompiled; - /// Preprocessor options - String mPreprocessorDefines; + /// Flag indicating if shader object successfully compiled + GLint mCompiled; + /// Preprocessor options + String mPreprocessorDefines; #if !OGRE_NO_GLES2_GLSL_OPTIMISER /// Flag indicating if shader has been successfully optimised bool mIsOptimised; bool mOptimiserEnabled; - /// The optmised source of the program (may be blank until the shader is optmisied) + /// The optmised source of the program (may be blank until the shader is optmisied) String mOptimisedSource; #endif }; diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramCommon.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramCommon.h index d789040473d..2413889453a 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramCommon.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramCommon.h @@ -38,67 +38,67 @@ namespace Ogre { class GLSLESGpuProgram; - /// Structure used to keep track of named uniforms in the linked program object - struct GLUniformReference - { - /// GL location handle - GLint mLocation; - /// Which type of program params will this value come from? - GpuProgramType mSourceProgType; - /// The constant definition it relates to - const GpuConstantDefinition* mConstantDef; - }; - - typedef vector::type GLUniformReferenceList; - typedef GLUniformReferenceList::iterator GLUniformReferenceIterator; + /// Structure used to keep track of named uniforms in the linked program object + struct GLUniformReference + { + /// GL location handle + GLint mLocation; + /// Which type of program params will this value come from? + GpuProgramType mSourceProgType; + /// The constant definition it relates to + const GpuConstantDefinition* mConstantDef; + }; + + typedef vector::type GLUniformReferenceList; + typedef GLUniformReferenceList::iterator GLUniformReferenceIterator; typedef vector::type GLUniformBufferList; typedef GLUniformBufferList::iterator GLUniformBufferIterator; - /** C++ encapsulation of GLSL ES Program Object + /** C++ encapsulation of GLSL ES Program Object */ - class _OgreGLES2Export GLSLESProgramCommon - { - protected: - /// Container of uniform references that are active in the program object - GLUniformReferenceList mGLUniformReferences; - /// Container of uniform buffer references that are active in the program object - GLUniformBufferList mGLUniformBufferReferences; - - /// Linked vertex program - GLSLESGpuProgram* mVertexProgram; - /// Linked fragment program - GLSLESGpuProgram* mFragmentProgram; + class _OgreGLES2Export GLSLESProgramCommon + { + protected: + /// Container of uniform references that are active in the program object + GLUniformReferenceList mGLUniformReferences; + /// Container of uniform buffer references that are active in the program object + GLUniformBufferList mGLUniformBufferReferences; + + /// Linked vertex program + GLSLESGpuProgram* mVertexProgram; + /// Linked fragment program + GLSLESGpuProgram* mFragmentProgram; GLES2UniformCache *mUniformCache; - /// Flag to indicate that uniform references have already been built - bool mUniformRefsBuilt; - /// GL handle for the program object - GLuint mGLProgramHandle; - /// Flag indicating that the program or pipeline object has been successfully linked - GLint mLinked; - /// Flag indicating that the program or pipeline object has tried to link and failed - bool mTriedToLinkAndFailed; - /// Flag indicating skeletal animation is being performed - bool mSkeletalAnimation; - - /// Build uniform references from active named uniforms - void buildGLUniformReferences(void); - typedef set::type AttributeSet; - - /// An array to hold the attributes indexes - GLint mCustomAttributesIndexes[VES_COUNT][OGRE_MAX_TEXTURE_COORD_SETS]; + /// Flag to indicate that uniform references have already been built + bool mUniformRefsBuilt; + /// GL handle for the program object + GLuint mGLProgramHandle; + /// Flag indicating that the program or pipeline object has been successfully linked + GLint mLinked; + /// Flag indicating that the program or pipeline object has tried to link and failed + bool mTriedToLinkAndFailed; + /// Flag indicating skeletal animation is being performed + bool mSkeletalAnimation; + + /// Build uniform references from active named uniforms + void buildGLUniformReferences(void); + typedef set::type AttributeSet; + + /// An array to hold the attributes indexes + GLint mCustomAttributesIndexes[VES_COUNT][OGRE_MAX_TEXTURE_COORD_SETS]; /// A value to define the case we didn't look for the attributes since the contractor #define NULL_CUSTOM_ATTRIBUTES_INDEX -2 /// A value to define the attribute has not been found (this is also the result when glGetAttribLocation fails) #define NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX -1 - Ogre::String getCombinedName(void); - /// Get the the binary data of a program from the microcode cache - void getMicrocodeFromCache(void); - /// Compiles and links the vertex and fragment programs - virtual void compileAndLink(void) = 0; + Ogre::String getCombinedName(void); + /// Get the the binary data of a program from the microcode cache + void getMicrocodeFromCache(void); + /// Compiles and links the vertex and fragment programs + virtual void compileAndLink(void) = 0; /// Put a program in use virtual void _useProgram(void) = 0; @@ -108,29 +108,29 @@ namespace Ogre { VertexElementSemantic getAttributeSemanticEnum(String type); const char * getAttributeSemanticString(VertexElementSemantic semantic); - public: - /// Constructor should only be used by GLSLESLinkProgramManager and GLSLESProgramPipelineManager - GLSLESProgramCommon(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram); - virtual ~GLSLESProgramCommon(void); + public: + /// Constructor should only be used by GLSLESLinkProgramManager and GLSLESProgramPipelineManager + GLSLESProgramCommon(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram); + virtual ~GLSLESProgramCommon(void); - /** Makes a program object active by making sure it is linked and then putting it in use. + /** Makes a program object active by making sure it is linked and then putting it in use. */ - virtual void activate(void) = 0; + virtual void activate(void) = 0; - /** Updates program object uniforms using data from GpuProgramParameters. + /** Updates program object uniforms using data from GpuProgramParameters. normally called by GLSLESGpuProgram::bindParameters() just before rendering occurs. */ - virtual void updateUniforms(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType) = 0; - /** Updates program object uniform blocks using data from GpuProgramParameters. + virtual void updateUniforms(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType) = 0; + /** Updates program object uniform blocks using data from GpuProgramParameters. normally called by GLSLGpuProgram::bindParameters() just before rendering occurs. */ - virtual void updateUniformBlocks(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType) = 0; - /** Updates program object uniforms using data from pass iteration GpuProgramParameters. + virtual void updateUniformBlocks(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType) = 0; + /** Updates program object uniforms using data from pass iteration GpuProgramParameters. normally called by GLSLESGpuProgram::bindMultiPassParameters() just before multi pass rendering occurs. */ - virtual void updatePassIterationUniforms(GpuProgramParametersSharedPtr params) = 0; - /// Get the GL Handle for the program object - GLuint getGLProgramHandle(void) const { return mGLProgramHandle; } + virtual void updatePassIterationUniforms(GpuProgramParametersSharedPtr params) = 0; + /// Get the GL Handle for the program object + GLuint getGLProgramHandle(void) const { return mGLProgramHandle; } /** Sets whether the linked program includes the required instructions to perform skeletal animation. @remarks @@ -147,15 +147,15 @@ namespace Ogre { */ bool isSkeletalAnimationIncluded(void) const { return mSkeletalAnimation; } - /// Get the index of a non-standard attribute bound in the linked code - virtual GLint getAttributeIndex(VertexElementSemantic semantic, uint index); - /// Is a non-standard attribute bound in the linked code? - bool isAttributeValid(VertexElementSemantic semantic, uint index); + /// Get the index of a non-standard attribute bound in the linked code + virtual GLint getAttributeIndex(VertexElementSemantic semantic, uint index); + /// Is a non-standard attribute bound in the linked code? + bool isAttributeValid(VertexElementSemantic semantic, uint index); - GLSLESGpuProgram* getVertexProgram(void) const { return mVertexProgram; } - GLSLESGpuProgram* getFragmentProgram(void) const { return mFragmentProgram; } + GLSLESGpuProgram* getVertexProgram(void) const { return mVertexProgram; } + GLSLESGpuProgram* getFragmentProgram(void) const { return mFragmentProgram; } GLES2UniformCache * getUniformCache(void) { return mUniformCache; } - }; + }; } #endif // __GLSLESProgramCommon_H__ diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramFactory.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramFactory.h index 8beeef9e6fc..2cacabbe14c 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramFactory.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramFactory.h @@ -39,21 +39,21 @@ namespace Ogre class _OgreGLES2Export GLSLESProgramFactory : public HighLevelGpuProgramFactory { protected: - static String sLanguageName; + static String sLanguageName; public: GLSLESProgramFactory(void); ~GLSLESProgramFactory(void); - /// Get the name of the language this factory creates programs for - const String& getLanguage(void) const; - /// Create an instance of GLSLESProgram + /// Get the name of the language this factory creates programs for + const String& getLanguage(void) const; + /// Create an instance of GLSLESProgram HighLevelGpuProgram* create(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader); - void destroy(HighLevelGpuProgram* prog); + void destroy(HighLevelGpuProgram* prog); - private: - static GLSLESLinkProgramManager* mLinkProgramManager; - static GLSLESProgramPipelineManager* mProgramPipelineManager; + private: + static GLSLESLinkProgramManager* mLinkProgramManager; + static GLSLESProgramPipelineManager* mProgramPipelineManager; }; } diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramManagerCommon.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramManagerCommon.h index b5e272644bf..f499a19b2ac 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramManagerCommon.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramManagerCommon.h @@ -40,44 +40,44 @@ THE SOFTWARE. namespace Ogre { - /** Ogre assumes that there are separate vertex and fragment programs to deal with but - GLSL ES has one program object that represents the active vertex and fragment shader objects - during a rendering state. GLSL Vertex and fragment - shader objects are compiled separately and then attached to a program object and then the - program object is linked. Since Ogre can only handle one vertex program and one fragment - program being active in a pass, the GLSL ES Link Program Manager does the same. The GLSL ES Link - program manager acts as a state machine and activates a program object based on the active - vertex and fragment program. Previously created program objects are stored along with a unique - key in a hash_map for quick retrieval the next time the program object is required. - */ - - class _OgreGLES2Export GLSLESProgramManagerCommon - { - protected: - /// Active objects defining the active rendering gpu state - GLSLESGpuProgram* mActiveVertexGpuProgram; - GLSLESGpuProgram* mActiveFragmentGpuProgram; - - typedef map::type StringToEnumMap; - StringToEnumMap mTypeEnumMap; + /** Ogre assumes that there are separate vertex and fragment programs to deal with but + GLSL ES has one program object that represents the active vertex and fragment shader objects + during a rendering state. GLSL Vertex and fragment + shader objects are compiled separately and then attached to a program object and then the + program object is linked. Since Ogre can only handle one vertex program and one fragment + program being active in a pass, the GLSL ES Link Program Manager does the same. The GLSL ES Link + program manager acts as a state machine and activates a program object based on the active + vertex and fragment program. Previously created program objects are stored along with a unique + key in a hash_map for quick retrieval the next time the program object is required. + */ + + class _OgreGLES2Export GLSLESProgramManagerCommon + { + protected: + /// Active objects defining the active rendering gpu state + GLSLESGpuProgram* mActiveVertexGpuProgram; + GLSLESGpuProgram* mActiveFragmentGpuProgram; + + typedef map::type StringToEnumMap; + StringToEnumMap mTypeEnumMap; #if !OGRE_NO_GLES2_GLSL_OPTIMISER struct glslopt_ctx *mGLSLOptimiserContext; #endif - /// Use type to complete other information - void completeDefInfo(GLenum gltype, GpuConstantDefinition& defToUpdate); - /// Find where the data for a specific uniform should come from, populate - bool completeParamSource(const String& paramName, - const GpuConstantDefinitionMap* vertexConstantDefs, - const GpuConstantDefinitionMap* fragmentConstantDefs, - GLUniformReference& refToUpdate); + /// Use type to complete other information + void completeDefInfo(GLenum gltype, GpuConstantDefinition& defToUpdate); + /// Find where the data for a specific uniform should come from, populate + bool completeParamSource(const String& paramName, + const GpuConstantDefinitionMap* vertexConstantDefs, + const GpuConstantDefinitionMap* fragmentConstantDefs, + GLUniformReference& refToUpdate); void parseIndividualConstant(const String& src, GpuNamedConstants& defs, String::size_type currPos, const String& filename, GpuSharedParametersPtr sharedParams); - public: + public: - GLSLESProgramManagerCommon(void); - ~GLSLESProgramManagerCommon(void); + GLSLESProgramManagerCommon(void); + ~GLSLESProgramManagerCommon(void); #if !OGRE_NO_GLES2_GLSL_OPTIMISER /** @@ -86,30 +86,30 @@ namespace Ogre { void optimiseShaderSource(GLSLESGpuProgram* gpuProgram); #endif - /** Populate a list of uniforms based on a program object. - @param programObject Handle to the program object to query - @param vertexConstantDefs Definition of the constants extracted from the - vertex program, used to match up physical buffer indexes with program - uniforms. May be null if there is no vertex program. - @param fragmentConstantDefs Definition of the constants extracted from the - fragment program, used to match up physical buffer indexes with program - uniforms. May be null if there is no fragment program. - @param list The list to populate (will not be cleared before adding, clear - it yourself before calling this if that's what you want). - */ - void extractUniforms(GLuint programObject, - const GpuConstantDefinitionMap* vertexConstantDefs, - const GpuConstantDefinitionMap* fragmentConstantDefs, - GLUniformReferenceList& list, GLUniformBufferList& sharedList); - /** Populate a list of uniforms based on GLSL ES source. - @param src Reference to the source code - @param constantDefs The defs to populate (will not be cleared before adding, clear - it yourself before calling this if that's what you want). - @param filename The file name this came from, for logging errors. - */ - void extractConstantDefs(const String& src, GpuNamedConstants& constantDefs, - const String& filename); - }; + /** Populate a list of uniforms based on a program object. + @param programObject Handle to the program object to query + @param vertexConstantDefs Definition of the constants extracted from the + vertex program, used to match up physical buffer indexes with program + uniforms. May be null if there is no vertex program. + @param fragmentConstantDefs Definition of the constants extracted from the + fragment program, used to match up physical buffer indexes with program + uniforms. May be null if there is no fragment program. + @param list The list to populate (will not be cleared before adding, clear + it yourself before calling this if that's what you want). + */ + void extractUniforms(GLuint programObject, + const GpuConstantDefinitionMap* vertexConstantDefs, + const GpuConstantDefinitionMap* fragmentConstantDefs, + GLUniformReferenceList& list, GLUniformBufferList& sharedList); + /** Populate a list of uniforms based on GLSL ES source. + @param src Reference to the source code + @param constantDefs The defs to populate (will not be cleared before adding, clear + it yourself before calling this if that's what you want). + @param filename The file name this came from, for logging errors. + */ + void extractConstantDefs(const String& src, GpuNamedConstants& constantDefs, + const String& filename); + }; } diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramPipeline.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramPipeline.h index 3c19cfc9d44..125355043af 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramPipeline.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramPipeline.h @@ -56,50 +56,50 @@ namespace Ogre class _OgreGLES2Export GLSLESProgramPipeline : public GLSLESProgramCommon { public: - /// Constructor should only be used by GLSLESProgramPipelineManager - GLSLESProgramPipeline(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram); - virtual ~GLSLESProgramPipeline(); + /// Constructor should only be used by GLSLESProgramPipelineManager + GLSLESProgramPipeline(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram); + virtual ~GLSLESProgramPipeline(); /// GL Program Pipeline Handle - GLuint getGLProgramPipelineHandle() const { return mGLProgramPipelineHandle; } + GLuint getGLProgramPipelineHandle() const { return mGLProgramPipelineHandle; } /** Updates program pipeline object uniforms using data from GpuProgramParameters. normally called by GLSLESGpuProgram::bindParameters() just before rendering occurs. */ - virtual void updateUniforms(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType); - /** Updates program object uniform blocks using data from GpuProgramParameters. + virtual void updateUniforms(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType); + /** Updates program object uniform blocks using data from GpuProgramParameters. normally called by GLSLGpuProgram::bindParameters() just before rendering occurs. */ - virtual void updateUniformBlocks(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType); - /** Updates program pipeline object uniforms using data from pass iteration GpuProgramParameters. + virtual void updateUniformBlocks(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType); + /** Updates program pipeline object uniforms using data from pass iteration GpuProgramParameters. normally called by GLSLESGpuProgram::bindMultiPassParameters() just before multi pass rendering occurs. */ - virtual void updatePassIterationUniforms(GpuProgramParametersSharedPtr params); + virtual void updatePassIterationUniforms(GpuProgramParametersSharedPtr params); /** Makes a program pipeline object active by making sure it is linked and then putting it in use. */ - void activate(void); + void activate(void); /// Get the index of a non-standard attribute bound in the linked code - virtual GLint getAttributeIndex(VertexElementSemantic semantic, uint index); + virtual GLint getAttributeIndex(VertexElementSemantic semantic, uint index); - protected: + protected: enum { VERTEX_PROGRAM_LINKED = 1, FRAGMENT_PROGRAM_LINKED = 2, ALL_PROGRAMS_LINKED = 3 }; - /// GL handle for pipeline object + /// GL handle for pipeline object GLuint mGLProgramPipelineHandle; - /// Compiles and links the separate vertex and fragment programs + /// Compiles and links the separate vertex and fragment programs virtual void compileAndLink(void); /// Put a program pipeline in use virtual void _useProgram(void); /// Finds layout qualifiers in the shader source and sets attribute indices appropriately virtual void extractLayoutQualifiers(void); /// Build uniform references from active named uniforms - virtual void buildGLUniformReferences(void); + virtual void buildGLUniformReferences(void); }; } diff --git a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramPipelineManager.h b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramPipelineManager.h index 6bd189d88f6..b046f9946b1 100644 --- a/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramPipelineManager.h +++ b/RenderSystems/GLES2/src/GLSLES/include/OgreGLSLESProgramPipelineManager.h @@ -35,7 +35,7 @@ namespace Ogre { - /** Ogre assumes that there are separate vertex and fragment programs to deal with but + /** Ogre assumes that there are separate vertex and fragment programs to deal with but GLSL ES has one program pipeline object that represents the active vertex and fragment program objects during a rendering state. GLSL vertex and fragment program objects are compiled separately and then attached to a program object and then the program pipeline object is linked. @@ -47,36 +47,36 @@ namespace Ogre */ class _OgreGLES2Export GLSLESProgramPipelineManager : public GLSLESProgramManagerCommon, public Singleton { - private: + private: - typedef map::type ProgramPipelineMap; - typedef ProgramPipelineMap::iterator ProgramPipelineIterator; + typedef map::type ProgramPipelineMap; + typedef ProgramPipelineMap::iterator ProgramPipelineIterator; - /// Container holding previously created program pipeline objects - ProgramPipelineMap mProgramPipelines; + /// Container holding previously created program pipeline objects + ProgramPipelineMap mProgramPipelines; - /// Active objects defining the active rendering gpu state - GLSLESProgramPipeline* mActiveProgramPipeline; + /// Active objects defining the active rendering gpu state + GLSLESProgramPipeline* mActiveProgramPipeline; - public: + public: - GLSLESProgramPipelineManager(void); - ~GLSLESProgramPipelineManager(void); + GLSLESProgramPipelineManager(void); + ~GLSLESProgramPipelineManager(void); - /** + /** Get the program object that links the two active program objects together. If a program pipeline object was not already created and linked a new one is created and linked. */ - GLSLESProgramPipeline* getActiveProgramPipeline(void); + GLSLESProgramPipeline* getActiveProgramPipeline(void); - /** Set the active vertex and fragment link programs for the next rendering state. + /** Set the active vertex and fragment link programs for the next rendering state. The active program pipeline object will be cleared. Normally called from the GLSLESGpuProgram::bindProgram and unbindProgram methods */ void setActiveVertexLinkProgram(GLSLESGpuProgram* vertexGpuProgram); void setActiveFragmentLinkProgram(GLSLESGpuProgram* fragmentGpuProgram); - static GLSLESProgramPipelineManager& getSingleton(void); + static GLSLESProgramPipelineManager& getSingleton(void); static GLSLESProgramPipelineManager* getSingletonPtr(void); }; } diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESCgProgram.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESCgProgram.cpp index 5b65584df50..e1b86da5672 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESCgProgram.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESCgProgram.cpp @@ -87,7 +87,7 @@ namespace Ogre { "blendIndices" }; //----------------------------------------------------------------------- - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- GLSLESCgProgram::GLSLESCgProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESExtSupport.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESExtSupport.cpp index cabdd7fae65..878940c8560 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESExtSupport.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESExtSupport.cpp @@ -35,13 +35,13 @@ THE SOFTWARE. namespace Ogre { //----------------------------------------------------------------------------- - String logObjectInfo(const String& msg, const GLuint obj) - { - String logMessage = msg; + String logObjectInfo(const String& msg, const GLuint obj) + { + String logMessage = msg; - if (obj > 0) - { - GLint infologLength = 0; + if (obj > 0) + { + GLint infologLength = 0; if(glIsShader(obj)) { @@ -62,12 +62,12 @@ namespace Ogre } #endif - if (infologLength > 1) - { - GLint charsWritten = 0; + if (infologLength > 1) + { + GLint charsWritten = 0; - char * infoLog = new char [infologLength]; - infoLog[0] = 0; + char * infoLog = new char [infologLength]; + infoLog[0] = 0; if(glIsShader(obj)) { @@ -88,27 +88,27 @@ namespace Ogre } #endif - if (strlen(infoLog) > 0) - { - logMessage += "\n" + String(infoLog); - } - - delete [] infoLog; - - if (logMessage.size() > 0) - { - // remove ends of line in the end - so there will be no empty lines in the log. - while( logMessage[logMessage.size() - 1] == '\n' ) - { - logMessage.erase(logMessage.size() - 1, 1); - } - LogManager::getSingleton().logMessage(logMessage); - } - } - } - - return logMessage; - } + if (strlen(infoLog) > 0) + { + logMessage += "\n" + String(infoLog); + } + + delete [] infoLog; + + if (logMessage.size() > 0) + { + // remove ends of line in the end - so there will be no empty lines in the log. + while( logMessage[logMessage.size() - 1] == '\n' ) + { + logMessage.erase(logMessage.size() - 1, 1); + } + LogManager::getSingleton().logMessage(logMessage); + } + } + } + + return logMessage; + } } // namespace Ogre diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESGpuProgram.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESGpuProgram.cpp index 9329ab9b8af..7203b5a5ab4 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESGpuProgram.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESGpuProgram.cpp @@ -34,10 +34,10 @@ THE SOFTWARE. namespace Ogre { - GLuint GLSLESGpuProgram::mVertexShaderCount = 0; - GLuint GLSLESGpuProgram::mFragmentShaderCount = 0; + GLuint GLSLESGpuProgram::mVertexShaderCount = 0; + GLuint GLSLESGpuProgram::mFragmentShaderCount = 0; //----------------------------------------------------------------------------- - GLSLESGpuProgram::GLSLESGpuProgram(GLSLESProgram* parent) : + GLSLESGpuProgram::GLSLESGpuProgram(GLSLESProgram* parent) : GLES2GpuProgram(parent->getCreator(), parent->getName(), parent->getHandle(), parent->getGroup(), false, 0), mGLSLProgram(parent) { @@ -46,19 +46,19 @@ namespace Ogre { mLinked = 0; - if (parent->getType() == GPT_VERTEX_PROGRAM) - { - mProgramID = ++mVertexShaderCount; - } - else if (parent->getType() == GPT_FRAGMENT_PROGRAM) - { - mProgramID = ++mFragmentShaderCount; - } + if (parent->getType() == GPT_VERTEX_PROGRAM) + { + mProgramID = ++mVertexShaderCount; + } + else if (parent->getType() == GPT_FRAGMENT_PROGRAM) + { + mProgramID = ++mFragmentShaderCount; + } // Transfer skeletal animation status from parent mSkeletalAnimation = mGLSLProgram->isSkeletalAnimationIncluded(); - // There is nothing to load - mLoadFromFile = false; + // There is nothing to load + mLoadFromFile = false; } //----------------------------------------------------------------------- GLSLESGpuProgram::~GLSLESGpuProgram() @@ -67,27 +67,27 @@ namespace Ogre { // since calling virtual methods in base destructors causes crash unload(); } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void GLSLESGpuProgram::loadImpl(void) { - // nothing to load + // nothing to load } - //----------------------------------------------------------------------------- - void GLSLESGpuProgram::unloadImpl(void) - { - // nothing to unload - } + //----------------------------------------------------------------------------- + void GLSLESGpuProgram::unloadImpl(void) + { + // nothing to unload + } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- void GLSLESGpuProgram::loadFromSource(void) { - // nothing to load - } + // nothing to load + } - //----------------------------------------------------------------------------- - void GLSLESGpuProgram::bindProgram(void) - { + //----------------------------------------------------------------------------- + void GLSLESGpuProgram::bindProgram(void) + { if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { // Tell the Program Pipeline Manager what pipeline is to become active @@ -120,11 +120,11 @@ namespace Ogre { break; } } - } + } - //----------------------------------------------------------------------------- - void GLSLESGpuProgram::unbindProgram(void) - { + //----------------------------------------------------------------------------- + void GLSLESGpuProgram::unbindProgram(void) + { if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { // Tell the Program Pipeline Manager what pipeline is to become inactive @@ -149,14 +149,14 @@ namespace Ogre { GLSLESLinkProgramManager::getSingleton().setActiveFragmentShader( NULL ); } } - } - - //----------------------------------------------------------------------------- - void GLSLESGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask) - { - // Link can throw exceptions, ignore them at this point - try - { + } + + //----------------------------------------------------------------------------- + void GLSLESGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask) + { + // Link can throw exceptions, ignore them at this point + try + { if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { // Activate the program pipeline object @@ -171,16 +171,16 @@ namespace Ogre { // Pass on parameters from params to program object uniforms linkProgram->updateUniforms(params, mask, mType); } - } - catch (Exception& e) {} - } + } + catch (Exception& e) {} + } //----------------------------------------------------------------------------- - void GLSLESGpuProgram::bindProgramSharedParameters(GpuProgramParametersSharedPtr params, uint16 mask) - { - // Link can throw exceptions, ignore them at this point - try - { + void GLSLESGpuProgram::bindProgramSharedParameters(GpuProgramParametersSharedPtr params, uint16 mask) + { + // Link can throw exceptions, ignore them at this point + try + { if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { // Activate the program pipeline object @@ -195,13 +195,13 @@ namespace Ogre { // Pass on parameters from params to program object uniforms linkProgram->updateUniformBlocks(params, mask, mType); } - } - catch (Exception& e) {} - } + } + catch (Exception& e) {} + } - //----------------------------------------------------------------------------- - void GLSLESGpuProgram::bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) - { + //----------------------------------------------------------------------------- + void GLSLESGpuProgram::bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) + { if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { // Activate the program pipeline object @@ -216,5 +216,5 @@ namespace Ogre { // Pass on parameters from params to program object uniforms linkProgram->updatePassIterationUniforms( params ); } - } + } } diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESLinkProgram.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESLinkProgram.cpp index e7b7a6f6166..dcff96a1b8d 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESLinkProgram.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESLinkProgram.cpp @@ -40,36 +40,36 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - GLSLESLinkProgram::GLSLESLinkProgram(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram) + //----------------------------------------------------------------------- + GLSLESLinkProgram::GLSLESLinkProgram(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram) : GLSLESProgramCommon(vertexProgram, fragmentProgram) - { + { if ((!mVertexProgram || !mFragmentProgram)) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Attempted to create a shader program without both a vertex and fragment program.", "GLSLESLinkProgram::GLSLESLinkProgram"); } - } + } - //----------------------------------------------------------------------- - GLSLESLinkProgram::~GLSLESLinkProgram(void) - { - OGRE_CHECK_GL_ERROR(glDeleteProgram(mGLProgramHandle)); - } + //----------------------------------------------------------------------- + GLSLESLinkProgram::~GLSLESLinkProgram(void) + { + OGRE_CHECK_GL_ERROR(glDeleteProgram(mGLProgramHandle)); + } void GLSLESLinkProgram::_useProgram(void) { - if (mLinked) - { + if (mLinked) + { OGRE_CHECK_GL_ERROR(glUseProgram( mGLProgramHandle )); - } + } } #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID void GLSLESLinkProgram::notifyOnContextLost() { - OGRE_CHECK_GL_ERROR(glDeleteProgram(mGLProgramHandle)); - mGLProgramHandle = 0; + OGRE_CHECK_GL_ERROR(glDeleteProgram(mGLProgramHandle)); + mGLProgramHandle = 0; mLinked = false; mTriedToLinkAndFailed = false; mUniformRefsBuilt = false; @@ -81,22 +81,22 @@ namespace Ogre { activate(); } #endif - //----------------------------------------------------------------------- - void GLSLESLinkProgram::activate(void) - { - if (!mLinked && !mTriedToLinkAndFailed) - { - glGetError(); // Clean up the error. Otherwise will flood log. - - OGRE_CHECK_GL_ERROR(mGLProgramHandle = glCreateProgram()); - - if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() && - GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) ) - { - getMicrocodeFromCache(); - } - else - { + //----------------------------------------------------------------------- + void GLSLESLinkProgram::activate(void) + { + if (!mLinked && !mTriedToLinkAndFailed) + { + glGetError(); // Clean up the error. Otherwise will flood log. + + OGRE_CHECK_GL_ERROR(mGLProgramHandle = glCreateProgram()); + + if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() && + GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) ) + { + getMicrocodeFromCache(); + } + else + { #if !OGRE_NO_GLES2_GLSL_OPTIMISER // Check CmdParams for each shader type to see if we should optimize if(mVertexProgram) @@ -117,34 +117,34 @@ namespace Ogre { } } #endif - compileAndLink(); + compileAndLink(); #if !OGRE_NO_GLES2_GLSL_OPTIMISER - // Try it again when we used the optimised versions - if(mTriedToLinkAndFailed && - mVertexProgram->getGLSLProgram()->getOptimiserEnabled() && - mFragmentProgram->getGLSLProgram()->getOptimiserEnabled()) - { - LogManager::getSingleton().stream() << "Try not optimised shader."; - mTriedToLinkAndFailed = false; - mVertexProgram->getGLSLProgram()->setOptimiserEnabled(false); - mFragmentProgram->getGLSLProgram()->setOptimiserEnabled(false); - compileAndLink(); - } + // Try it again when we used the optimised versions + if(mTriedToLinkAndFailed && + mVertexProgram->getGLSLProgram()->getOptimiserEnabled() && + mFragmentProgram->getGLSLProgram()->getOptimiserEnabled()) + { + LogManager::getSingleton().stream() << "Try not optimised shader."; + mTriedToLinkAndFailed = false; + mVertexProgram->getGLSLProgram()->setOptimiserEnabled(false); + mFragmentProgram->getGLSLProgram()->setOptimiserEnabled(false); + compileAndLink(); + } #endif - } + } extractLayoutQualifiers(); - buildGLUniformReferences(); - } + buildGLUniformReferences(); + } _useProgram(); - } + } - //----------------------------------------------------------------------- - void GLSLESLinkProgram::compileAndLink() - { - // Compile and attach Vertex Program + //----------------------------------------------------------------------- + void GLSLESLinkProgram::compileAndLink() + { + // Compile and attach Vertex Program try { mVertexProgram->getGLSLProgram()->compile(true); @@ -159,7 +159,7 @@ namespace Ogre { mVertexProgram->getGLSLProgram()->attachToProgramObject(mGLProgramHandle); setSkeletalAnimationIncluded(mVertexProgram->isSkeletalAnimationIncluded()); - // Compile and attach Fragment Program + // Compile and attach Fragment Program try { mFragmentProgram->getGLSLProgram()->compile(true); @@ -190,24 +190,24 @@ namespace Ogre { } else if(glIsProgram(mGLProgramHandle)) #else - if(glIsProgram(mGLProgramHandle)) + if(glIsProgram(mGLProgramHandle)) #endif { glValidateProgram(mGLProgramHandle); } - logObjectInfo( getCombinedName() + String(" GLSL validation result : "), mGLProgramHandle ); + logObjectInfo( getCombinedName() + String(" GLSL validation result : "), mGLProgramHandle ); - if(mLinked) - { - if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() ) - { - // Add to the microcode to the cache - String name; - name = getCombinedName(); + if(mLinked) + { + if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() ) + { + // Add to the microcode to the cache + String name; + name = getCombinedName(); - // Get buffer size - GLint binaryLength = 0; + // Get buffer size + GLint binaryLength = 0; if(getGLES2SupportRef()->checkExtension("GL_OES_get_program_binary") || gleswIsSupported(3, 0)) OGRE_CHECK_GL_ERROR(glGetProgramiv(mGLProgramHandle, GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength)); @@ -215,59 +215,59 @@ namespace Ogre { GpuProgramManager::Microcode newMicrocode = GpuProgramManager::getSingleton().createMicrocode(static_cast(binaryLength + sizeof(GLenum))); - // Get binary + // Get binary if(getGLES2SupportRef()->checkExtension("GL_OES_get_program_binary") || gleswIsSupported(3, 0)) OGRE_CHECK_GL_ERROR(glGetProgramBinaryOES(mGLProgramHandle, binaryLength, NULL, (GLenum *)newMicrocode->getPtr(), newMicrocode->getPtr() + sizeof(GLenum))); - // Add to the microcode to the cache - GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode); - } - } - } - - //----------------------------------------------------------------------- - void GLSLESLinkProgram::buildGLUniformReferences(void) - { - if (!mUniformRefsBuilt) - { - const GpuConstantDefinitionMap* vertParams = 0; - const GpuConstantDefinitionMap* fragParams = 0; - if (mVertexProgram) - { - vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map); - } - if (mFragmentProgram) - { - fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map); - } - - GLSLESLinkProgramManager::getSingleton().extractUniforms( - mGLProgramHandle, vertParams, fragParams, mGLUniformReferences, mGLUniformBufferReferences); - - mUniformRefsBuilt = true; - } - } - - //----------------------------------------------------------------------- - void GLSLESLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params, - uint16 mask, GpuProgramType fromProgType) - { - // Iterate through uniform reference list and update uniform values - GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); - GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); - - for (;currentUniform != endUniform; ++currentUniform) - { - // Only pull values from buffer it's supposed to be in (vertex or fragment) - // This method will be called twice, once for vertex program params, - // and once for fragment program params. - if (fromProgType == currentUniform->mSourceProgType) - { - const GpuConstantDefinition* def = currentUniform->mConstantDef; - if (def->variability & mask) - { - GLsizei glArraySize = (GLsizei)def->arraySize; + // Add to the microcode to the cache + GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode); + } + } + } + + //----------------------------------------------------------------------- + void GLSLESLinkProgram::buildGLUniformReferences(void) + { + if (!mUniformRefsBuilt) + { + const GpuConstantDefinitionMap* vertParams = 0; + const GpuConstantDefinitionMap* fragParams = 0; + if (mVertexProgram) + { + vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map); + } + if (mFragmentProgram) + { + fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map); + } + + GLSLESLinkProgramManager::getSingleton().extractUniforms( + mGLProgramHandle, vertParams, fragParams, mGLUniformReferences, mGLUniformBufferReferences); + + mUniformRefsBuilt = true; + } + } + + //----------------------------------------------------------------------- + void GLSLESLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params, + uint16 mask, GpuProgramType fromProgType) + { + // Iterate through uniform reference list and update uniform values + GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); + GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); + + for (;currentUniform != endUniform; ++currentUniform) + { + // Only pull values from buffer it's supposed to be in (vertex or fragment) + // This method will be called twice, once for vertex program params, + // and once for fragment program params. + if (fromProgType == currentUniform->mSourceProgType) + { + const GpuConstantDefinition* def = currentUniform->mConstantDef; + if (def->variability & mask) + { + GLsizei glArraySize = (GLsizei)def->arraySize; bool shouldUpdate = true; switch (def->constType) @@ -296,37 +296,37 @@ namespace Ogre { if(!shouldUpdate) continue; - // Get the index in the parameter real list - switch (def->constType) - { - case GCT_FLOAT1: - OGRE_CHECK_GL_ERROR(glUniform1fv(currentUniform->mLocation, glArraySize, + // Get the index in the parameter real list + switch (def->constType) + { + case GCT_FLOAT1: + OGRE_CHECK_GL_ERROR(glUniform1fv(currentUniform->mLocation, glArraySize, params->getFloatPointer(def->physicalIndex))); - break; - case GCT_FLOAT2: - OGRE_CHECK_GL_ERROR(glUniform2fv(currentUniform->mLocation, glArraySize, + break; + case GCT_FLOAT2: + OGRE_CHECK_GL_ERROR(glUniform2fv(currentUniform->mLocation, glArraySize, params->getFloatPointer(def->physicalIndex))); - break; - case GCT_FLOAT3: - OGRE_CHECK_GL_ERROR(glUniform3fv(currentUniform->mLocation, glArraySize, + break; + case GCT_FLOAT3: + OGRE_CHECK_GL_ERROR(glUniform3fv(currentUniform->mLocation, glArraySize, params->getFloatPointer(def->physicalIndex))); - break; - case GCT_FLOAT4: - OGRE_CHECK_GL_ERROR(glUniform4fv(currentUniform->mLocation, glArraySize, + break; + case GCT_FLOAT4: + OGRE_CHECK_GL_ERROR(glUniform4fv(currentUniform->mLocation, glArraySize, params->getFloatPointer(def->physicalIndex))); - break; - case GCT_MATRIX_2X2: - OGRE_CHECK_GL_ERROR(glUniformMatrix2fv(currentUniform->mLocation, glArraySize, + break; + case GCT_MATRIX_2X2: + OGRE_CHECK_GL_ERROR(glUniformMatrix2fv(currentUniform->mLocation, glArraySize, GL_FALSE, params->getFloatPointer(def->physicalIndex))); - break; - case GCT_MATRIX_3X3: - OGRE_CHECK_GL_ERROR(glUniformMatrix3fv(currentUniform->mLocation, glArraySize, + break; + case GCT_MATRIX_3X3: + OGRE_CHECK_GL_ERROR(glUniformMatrix3fv(currentUniform->mLocation, glArraySize, GL_FALSE, params->getFloatPointer(def->physicalIndex))); - break; - case GCT_MATRIX_4X4: - OGRE_CHECK_GL_ERROR(glUniformMatrix4fv(currentUniform->mLocation, glArraySize, + break; + case GCT_MATRIX_4X4: + OGRE_CHECK_GL_ERROR(glUniformMatrix4fv(currentUniform->mLocation, glArraySize, GL_FALSE, params->getFloatPointer(def->physicalIndex))); - break; + break; #if OGRE_NO_GLES3_SUPPORT == 0 case GCT_MATRIX_2X3: OGRE_CHECK_GL_ERROR(glUniformMatrix2x3fv(currentUniform->mLocation, glArraySize, @@ -353,40 +353,40 @@ namespace Ogre { GL_FALSE, params->getFloatPointer(def->physicalIndex))); break; #else - case GCT_MATRIX_2X3: - case GCT_MATRIX_2X4: - case GCT_MATRIX_3X2: - case GCT_MATRIX_3X4: - case GCT_MATRIX_4X2: - case GCT_MATRIX_4X3: - break; + case GCT_MATRIX_2X3: + case GCT_MATRIX_2X4: + case GCT_MATRIX_3X2: + case GCT_MATRIX_3X4: + case GCT_MATRIX_4X2: + case GCT_MATRIX_4X3: + break; #endif - case GCT_INT1: - OGRE_CHECK_GL_ERROR(glUniform1iv(currentUniform->mLocation, glArraySize, + case GCT_INT1: + OGRE_CHECK_GL_ERROR(glUniform1iv(currentUniform->mLocation, glArraySize, (GLint*)params->getIntPointer(def->physicalIndex))); - break; - case GCT_INT2: - OGRE_CHECK_GL_ERROR(glUniform2iv(currentUniform->mLocation, glArraySize, + break; + case GCT_INT2: + OGRE_CHECK_GL_ERROR(glUniform2iv(currentUniform->mLocation, glArraySize, (GLint*)params->getIntPointer(def->physicalIndex))); - break; - case GCT_INT3: - OGRE_CHECK_GL_ERROR(glUniform3iv(currentUniform->mLocation, glArraySize, + break; + case GCT_INT3: + OGRE_CHECK_GL_ERROR(glUniform3iv(currentUniform->mLocation, glArraySize, (GLint*)params->getIntPointer(def->physicalIndex))); - break; - case GCT_INT4: - OGRE_CHECK_GL_ERROR(glUniform4iv(currentUniform->mLocation, glArraySize, + break; + case GCT_INT4: + OGRE_CHECK_GL_ERROR(glUniform4iv(currentUniform->mLocation, glArraySize, (GLint*)params->getIntPointer(def->physicalIndex))); - break; - case GCT_SAMPLER1D: - case GCT_SAMPLER1DSHADOW: - case GCT_SAMPLER2D: - case GCT_SAMPLER2DSHADOW: - case GCT_SAMPLER3D: - case GCT_SAMPLERCUBE: - // Samplers handled like 1-element ints - OGRE_CHECK_GL_ERROR(glUniform1iv(currentUniform->mLocation, 1, + break; + case GCT_SAMPLER1D: + case GCT_SAMPLER1DSHADOW: + case GCT_SAMPLER2D: + case GCT_SAMPLER2DSHADOW: + case GCT_SAMPLER3D: + case GCT_SAMPLERCUBE: + // Samplers handled like 1-element ints + OGRE_CHECK_GL_ERROR(glUniform1iv(currentUniform->mLocation, 1, (GLint*)params->getIntPointer(def->physicalIndex))); - break; + break; case GCT_SAMPLER2DARRAY: case GCT_UNKNOWN: case GCT_SUBROUTINE: @@ -407,25 +407,25 @@ namespace Ogre { default: break; - } // End switch - } // Variability & mask - } // fromProgType == currentUniform->mSourceProgType + } // End switch + } // Variability & mask + } // fromProgType == currentUniform->mSourceProgType - } // End for - } - //----------------------------------------------------------------------- - void GLSLESLinkProgram::updateUniformBlocks(GpuProgramParametersSharedPtr params, + } // End for + } + //----------------------------------------------------------------------- + void GLSLESLinkProgram::updateUniformBlocks(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType) - { + { #if OGRE_NO_GLES3_SUPPORT == 0 // Iterate through the list of uniform buffers and update them as needed - GLUniformBufferIterator currentBuffer = mGLUniformBufferReferences.begin(); - GLUniformBufferIterator endBuffer = mGLUniformBufferReferences.end(); + GLUniformBufferIterator currentBuffer = mGLUniformBufferReferences.begin(); + GLUniformBufferIterator endBuffer = mGLUniformBufferReferences.end(); const GpuProgramParameters::GpuSharedParamUsageList& sharedParams = params->getSharedParameters(); - GpuProgramParameters::GpuSharedParamUsageList::const_iterator it, end = sharedParams.end(); - for (it = sharedParams.begin(); it != end; ++it) + GpuProgramParameters::GpuSharedParamUsageList::const_iterator it, end = sharedParams.end(); + for (it = sharedParams.begin(); it != end; ++it) { for (;currentBuffer != endBuffer; ++currentBuffer) { @@ -441,32 +441,32 @@ namespace Ogre { } } #endif - } - //----------------------------------------------------------------------- - void GLSLESLinkProgram::updatePassIterationUniforms(GpuProgramParametersSharedPtr params) - { - if (params->hasPassIterationNumber()) - { - size_t index = params->getPassIterationNumberIndex(); - - GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); - GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); - - // Need to find the uniform that matches the multi pass entry - for (;currentUniform != endUniform; ++currentUniform) - { - // Get the index in the parameter real list - if (index == currentUniform->mConstantDef->physicalIndex) - { + } + //----------------------------------------------------------------------- + void GLSLESLinkProgram::updatePassIterationUniforms(GpuProgramParametersSharedPtr params) + { + if (params->hasPassIterationNumber()) + { + size_t index = params->getPassIterationNumberIndex(); + + GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); + GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); + + // Need to find the uniform that matches the multi pass entry + for (;currentUniform != endUniform; ++currentUniform) + { + // Get the index in the parameter real list + if (index == currentUniform->mConstantDef->physicalIndex) + { mUniformCache->updateUniform(currentUniform->mLocation, params->getFloatPointer(index), static_cast(currentUniform->mConstantDef->elementSize * currentUniform->mConstantDef->arraySize * sizeof(float))); - // There will only be one multipass entry - return; - } - } - } + // There will only be one multipass entry + return; + } + } + } } } // namespace Ogre diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESLinkProgramManager.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESLinkProgramManager.cpp index 7a476e2dc0b..3b0f57f24d5 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESLinkProgramManager.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESLinkProgramManager.cpp @@ -33,99 +33,99 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - template<> GLSLESLinkProgramManager* Singleton::msSingleton = 0; + //----------------------------------------------------------------------- + template<> GLSLESLinkProgramManager* Singleton::msSingleton = 0; - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- GLSLESLinkProgramManager* GLSLESLinkProgramManager::getSingletonPtr(void) { return msSingleton; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- GLSLESLinkProgramManager& GLSLESLinkProgramManager::getSingleton(void) { assert( msSingleton ); return ( *msSingleton ); } - //----------------------------------------------------------------------- - GLSLESLinkProgramManager::GLSLESLinkProgramManager(void) : + //----------------------------------------------------------------------- + GLSLESLinkProgramManager::GLSLESLinkProgramManager(void) : GLSLESProgramManagerCommon(), mActiveLinkProgram(NULL) { } - //----------------------------------------------------------------------- - GLSLESLinkProgramManager::~GLSLESLinkProgramManager(void) - { - // iterate through map container and delete link programs - for (LinkProgramIterator currentProgram = mLinkPrograms.begin(); - currentProgram != mLinkPrograms.end(); ++currentProgram) - { - OGRE_DELETE currentProgram->second; - } - } - - //----------------------------------------------------------------------- - GLSLESLinkProgram* GLSLESLinkProgramManager::getActiveLinkProgram(void) - { - // If there is an active link program then return it - if (mActiveLinkProgram) - return mActiveLinkProgram; - - // No active link program so find one or make a new one - // Is there an active key? - uint64 activeKey = 0; - - if (mActiveVertexGpuProgram) - { - activeKey = static_cast(mActiveVertexGpuProgram->getProgramID()) << 32; - } - if (mActiveFragmentGpuProgram) - { - activeKey += static_cast(mActiveFragmentGpuProgram->getProgramID()); - } - - // Only return a link program object if a vertex or fragment program exist - if (activeKey > 0) - { - // Find the key in the hash map - LinkProgramIterator programFound = mLinkPrograms.find(activeKey); - // Program object not found for key so need to create it - if (programFound == mLinkPrograms.end()) - { - mActiveLinkProgram = new GLSLESLinkProgram(mActiveVertexGpuProgram,mActiveFragmentGpuProgram); - mLinkPrograms[activeKey] = mActiveLinkProgram; - } - else - { - // Found a link program in map container so make it active - mActiveLinkProgram = programFound->second; - } - - } - // Make the program object active - if (mActiveLinkProgram) mActiveLinkProgram->activate(); - - return mActiveLinkProgram; - } - - //----------------------------------------------------------------------- - void GLSLESLinkProgramManager::setActiveFragmentShader(GLSLESGpuProgram* fragmentGpuProgram) - { - if (fragmentGpuProgram != mActiveFragmentGpuProgram) - { - mActiveFragmentGpuProgram = fragmentGpuProgram; - // ActiveLinkProgram is no longer valid - mActiveLinkProgram = NULL; - } - } - - //----------------------------------------------------------------------- - void GLSLESLinkProgramManager::setActiveVertexShader(GLSLESGpuProgram* vertexGpuProgram) - { - if (vertexGpuProgram != mActiveVertexGpuProgram) - { - mActiveVertexGpuProgram = vertexGpuProgram; - // ActiveLinkProgram is no longer valid - mActiveLinkProgram = NULL; - } - } + //----------------------------------------------------------------------- + GLSLESLinkProgramManager::~GLSLESLinkProgramManager(void) + { + // iterate through map container and delete link programs + for (LinkProgramIterator currentProgram = mLinkPrograms.begin(); + currentProgram != mLinkPrograms.end(); ++currentProgram) + { + OGRE_DELETE currentProgram->second; + } + } + + //----------------------------------------------------------------------- + GLSLESLinkProgram* GLSLESLinkProgramManager::getActiveLinkProgram(void) + { + // If there is an active link program then return it + if (mActiveLinkProgram) + return mActiveLinkProgram; + + // No active link program so find one or make a new one + // Is there an active key? + uint64 activeKey = 0; + + if (mActiveVertexGpuProgram) + { + activeKey = static_cast(mActiveVertexGpuProgram->getProgramID()) << 32; + } + if (mActiveFragmentGpuProgram) + { + activeKey += static_cast(mActiveFragmentGpuProgram->getProgramID()); + } + + // Only return a link program object if a vertex or fragment program exist + if (activeKey > 0) + { + // Find the key in the hash map + LinkProgramIterator programFound = mLinkPrograms.find(activeKey); + // Program object not found for key so need to create it + if (programFound == mLinkPrograms.end()) + { + mActiveLinkProgram = new GLSLESLinkProgram(mActiveVertexGpuProgram,mActiveFragmentGpuProgram); + mLinkPrograms[activeKey] = mActiveLinkProgram; + } + else + { + // Found a link program in map container so make it active + mActiveLinkProgram = programFound->second; + } + + } + // Make the program object active + if (mActiveLinkProgram) mActiveLinkProgram->activate(); + + return mActiveLinkProgram; + } + + //----------------------------------------------------------------------- + void GLSLESLinkProgramManager::setActiveFragmentShader(GLSLESGpuProgram* fragmentGpuProgram) + { + if (fragmentGpuProgram != mActiveFragmentGpuProgram) + { + mActiveFragmentGpuProgram = fragmentGpuProgram; + // ActiveLinkProgram is no longer valid + mActiveLinkProgram = NULL; + } + } + + //----------------------------------------------------------------------- + void GLSLESLinkProgramManager::setActiveVertexShader(GLSLESGpuProgram* vertexGpuProgram) + { + if (vertexGpuProgram != mActiveVertexGpuProgram) + { + mActiveVertexGpuProgram = vertexGpuProgram; + // ActiveLinkProgram is no longer valid + mActiveLinkProgram = NULL; + } + } } diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESPreprocessor.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESPreprocessor.cpp index 2e4a2a98ae5..cbc073fc67e 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESPreprocessor.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESPreprocessor.cpp @@ -35,7 +35,7 @@ namespace Ogre { #define MAX_MACRO_ARGS 16 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 && !defined( __MINGW32__ ) - #define snprintf _snprintf + #define snprintf _snprintf #endif //---------------------------------------------------------------------------// diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgram.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgram.cpp index bd661da9ff6..2a076c91a1d 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgram.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgram.cpp @@ -45,17 +45,17 @@ namespace Ogre { RenderOperation::OperationType parseOperationType(const String& val); //----------------------------------------------------------------------- - GLSLESProgram::CmdPreprocessorDefines GLSLESProgram::msCmdPreprocessorDefines; + GLSLESProgram::CmdPreprocessorDefines GLSLESProgram::msCmdPreprocessorDefines; #if !OGRE_NO_GLES2_GLSL_OPTIMISER GLSLESProgram::CmdOptimisation GLSLESProgram::msCmdOptimisation; #endif //----------------------------------------------------------------------- - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- GLSLESProgram::GLSLESProgram(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader) : HighLevelGpuProgram(creator, name, handle, group, isManual, loader) - , mGLShaderHandle(0) + , mGLShaderHandle(0) , mGLProgramHandle(0) , mCompiled(0) #if !OGRE_NO_GLES2_GLSL_OPTIMISER @@ -68,11 +68,11 @@ namespace Ogre { setupBaseParamDictionary(); ParamDictionary* dict = getParamDictionary(); - dict->addParameter(ParameterDef("preprocessor_defines", + dict->addParameter(ParameterDef("preprocessor_defines", "Preprocessor defines use to compile the program.", PT_STRING),&msCmdPreprocessorDefines); #if !OGRE_NO_GLES2_GLSL_OPTIMISER - dict->addParameter(ParameterDef("use_optimiser", + dict->addParameter(ParameterDef("use_optimiser", "Should the GLSL optimiser be used. Default is false.", PT_BOOL),&msCmdOptimisation); #endif @@ -102,96 +102,96 @@ namespace Ogre { } #endif //----------------------------------------------------------------------- - void GLSLESProgram::loadFromSource(void) - { - // Preprocess the GLSL ES shader in order to get a clean source - CPreprocessor cpp; - - // Pass all user-defined macros to preprocessor - if (!mPreprocessorDefines.empty ()) - { - String::size_type pos = 0; - while (pos != String::npos) - { - // Find delims - String::size_type endPos = mPreprocessorDefines.find_first_of(";,=", pos); - if (endPos != String::npos) - { - String::size_type macro_name_start = pos; - size_t macro_name_len = endPos - pos; - pos = endPos; - - // Check definition part - if (mPreprocessorDefines[pos] == '=') - { - // Set up a definition, skip delim - ++pos; - String::size_type macro_val_start = pos; - size_t macro_val_len; - - endPos = mPreprocessorDefines.find_first_of(";,", pos); - if (endPos == String::npos) - { - macro_val_len = mPreprocessorDefines.size () - pos; - pos = endPos; - } - else - { - macro_val_len = endPos - pos; - pos = endPos+1; - } - cpp.Define ( - mPreprocessorDefines.c_str () + macro_name_start, macro_name_len, - mPreprocessorDefines.c_str () + macro_val_start, macro_val_len); - } - else - { - // No definition part, define as "1" - ++pos; - cpp.Define ( - mPreprocessorDefines.c_str () + macro_name_start, macro_name_len, 1); - } - } - else - pos = endPos; - } - } - - size_t out_size = 0; - const char *src = mSource.c_str (); - size_t src_len = mSource.size (); - char *out = cpp.Parse (src, src_len, out_size); - if (!out || !out_size) - // Failed to preprocess, break out - OGRE_EXCEPT (Exception::ERR_RENDERINGAPI_ERROR, - "Failed to preprocess shader " + mName, - __FUNCTION__); - - mSource = String (out, out_size); - if (out < src || out > src + src_len) - free (out); + void GLSLESProgram::loadFromSource(void) + { + // Preprocess the GLSL ES shader in order to get a clean source + CPreprocessor cpp; + + // Pass all user-defined macros to preprocessor + if (!mPreprocessorDefines.empty ()) + { + String::size_type pos = 0; + while (pos != String::npos) + { + // Find delims + String::size_type endPos = mPreprocessorDefines.find_first_of(";,=", pos); + if (endPos != String::npos) + { + String::size_type macro_name_start = pos; + size_t macro_name_len = endPos - pos; + pos = endPos; + + // Check definition part + if (mPreprocessorDefines[pos] == '=') + { + // Set up a definition, skip delim + ++pos; + String::size_type macro_val_start = pos; + size_t macro_val_len; + + endPos = mPreprocessorDefines.find_first_of(";,", pos); + if (endPos == String::npos) + { + macro_val_len = mPreprocessorDefines.size () - pos; + pos = endPos; + } + else + { + macro_val_len = endPos - pos; + pos = endPos+1; + } + cpp.Define ( + mPreprocessorDefines.c_str () + macro_name_start, macro_name_len, + mPreprocessorDefines.c_str () + macro_val_start, macro_val_len); + } + else + { + // No definition part, define as "1" + ++pos; + cpp.Define ( + mPreprocessorDefines.c_str () + macro_name_start, macro_name_len, 1); + } + } + else + pos = endPos; + } + } + + size_t out_size = 0; + const char *src = mSource.c_str (); + size_t src_len = mSource.size (); + char *out = cpp.Parse (src, src_len, out_size); + if (!out || !out_size) + // Failed to preprocess, break out + OGRE_EXCEPT (Exception::ERR_RENDERINGAPI_ERROR, + "Failed to preprocess shader " + mName, + __FUNCTION__); + + mSource = String (out, out_size); + if (out < src || out > src + src_len) + free (out); } - bool GLSLESProgram::compile(const bool checkErrors) - { - if (mCompiled == 1) - { - return true; - } - // Only create a shader object if glsl es is supported - if (isSupported()) - { - // Create shader object - GLenum shaderType = 0x0000; - if (mType == GPT_VERTEX_PROGRAM) - { - shaderType = GL_VERTEX_SHADER; - } + bool GLSLESProgram::compile(const bool checkErrors) + { + if (mCompiled == 1) + { + return true; + } + // Only create a shader object if glsl es is supported + if (isSupported()) + { + // Create shader object + GLenum shaderType = 0x0000; + if (mType == GPT_VERTEX_PROGRAM) + { + shaderType = GL_VERTEX_SHADER; + } else if (mType == GPT_FRAGMENT_PROGRAM) { - shaderType = GL_FRAGMENT_SHADER; - } - OGRE_CHECK_GL_ERROR(mGLShaderHandle = glCreateShader(shaderType)); + shaderType = GL_FRAGMENT_SHADER; + } + OGRE_CHECK_GL_ERROR(mGLShaderHandle = glCreateShader(shaderType)); #if OGRE_PLATFORM != OGRE_PLATFORM_NACL if(getGLES2SupportRef()->checkExtension("GL_EXT_debug_label")) @@ -212,11 +212,11 @@ namespace Ogre { } #endif } - } + } - // Add preprocessor extras and main source - if (!mSource.empty()) - { + // Add preprocessor extras and main source + if (!mSource.empty()) + { // Fix up the source in case someone forgot to redeclare gl_Position if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS) && mType == GPT_VERTEX_PROGRAM) @@ -238,49 +238,49 @@ namespace Ogre { } #if !OGRE_NO_GLES2_GLSL_OPTIMISER - const char *source = (getOptimiserEnabled() && getIsOptimised()) ? mOptimisedSource.c_str() : mSource.c_str(); + const char *source = (getOptimiserEnabled() && getIsOptimised()) ? mOptimisedSource.c_str() : mSource.c_str(); #else - const char *source = mSource.c_str(); + const char *source = mSource.c_str(); #endif - OGRE_CHECK_GL_ERROR(glShaderSource(mGLShaderHandle, 1, &source, NULL)); - } + OGRE_CHECK_GL_ERROR(glShaderSource(mGLShaderHandle, 1, &source, NULL)); + } if (checkErrors) logObjectInfo("GLSL ES compiling: " + mName, mGLShaderHandle); - OGRE_CHECK_GL_ERROR(glCompileShader(mGLShaderHandle)); + OGRE_CHECK_GL_ERROR(glCompileShader(mGLShaderHandle)); - // Check for compile errors - OGRE_CHECK_GL_ERROR(glGetShaderiv(mGLShaderHandle, GL_COMPILE_STATUS, &mCompiled)); + // Check for compile errors + OGRE_CHECK_GL_ERROR(glGetShaderiv(mGLShaderHandle, GL_COMPILE_STATUS, &mCompiled)); if(!mCompiled && checkErrors) - { + { String message = logObjectInfo("GLSL ES compile log: " + mName, mGLShaderHandle); - checkAndFixInvalidDefaultPrecisionError(message); - } + checkAndFixInvalidDefaultPrecisionError(message); + } - // Log a message that the shader compiled successfully. + // Log a message that the shader compiled successfully. if (mCompiled && checkErrors) logObjectInfo("GLSL ES compiled: " + mName, mGLShaderHandle); if(!mCompiled) - { + { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, ((mType == GPT_VERTEX_PROGRAM) ? "Vertex Program " : "Fragment Program ") + mName + " failed to compile. See compile log above for details.", "GLSLESProgram::compile"); - } + } - return (mCompiled == 1); - } + return (mCompiled == 1); + } -#if !OGRE_NO_GLES2_GLSL_OPTIMISER - //----------------------------------------------------------------------- +#if !OGRE_NO_GLES2_GLSL_OPTIMISER + //----------------------------------------------------------------------- void GLSLESProgram::setOptimiserEnabled(bool enabled) - { - if(mOptimiserEnabled != enabled && mOptimiserEnabled && mCompiled == 1) - { - OGRE_CHECK_GL_ERROR(glDeleteShader(mGLShaderHandle)); + { + if(mOptimiserEnabled != enabled && mOptimiserEnabled && mCompiled == 1) + { + OGRE_CHECK_GL_ERROR(glDeleteShader(mGLShaderHandle)); if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { @@ -290,33 +290,33 @@ namespace Ogre { mGLShaderHandle = 0; mGLProgramHandle = 0; mCompiled = 0; - } - mOptimiserEnabled = enabled; - } + } + mOptimiserEnabled = enabled; + } #endif - //----------------------------------------------------------------------- - void GLSLESProgram::createLowLevelImpl(void) - { - mAssemblerProgram = GpuProgramPtr(OGRE_NEW GLSLESGpuProgram( this )); - } - //--------------------------------------------------------------------------- - void GLSLESProgram::unloadImpl() - { - // We didn't create mAssemblerProgram through a manager, so override this - // implementation so that we don't try to remove it from one. Since getCreator() - // is used, it might target a different matching handle! - mAssemblerProgram.setNull(); - - unloadHighLevel(); - } - //----------------------------------------------------------------------- - void GLSLESProgram::unloadHighLevelImpl(void) - { - if (isSupported()) - { + //----------------------------------------------------------------------- + void GLSLESProgram::createLowLevelImpl(void) + { + mAssemblerProgram = GpuProgramPtr(OGRE_NEW GLSLESGpuProgram( this )); + } + //--------------------------------------------------------------------------- + void GLSLESProgram::unloadImpl() + { + // We didn't create mAssemblerProgram through a manager, so override this + // implementation so that we don't try to remove it from one. Since getCreator() + // is used, it might target a different matching handle! + mAssemblerProgram.setNull(); + + unloadHighLevel(); + } + //----------------------------------------------------------------------- + void GLSLESProgram::unloadHighLevelImpl(void) + { + if (isSupported()) + { // LogManager::getSingleton().logMessage("Deleting shader " + StringConverter::toString(mGLShaderHandle) + // " and program " + StringConverter::toString(mGLProgramHandle)); - OGRE_CHECK_GL_ERROR(glDeleteShader(mGLShaderHandle)); + OGRE_CHECK_GL_ERROR(glDeleteShader(mGLShaderHandle)); if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { @@ -326,24 +326,24 @@ namespace Ogre { mGLShaderHandle = 0; mGLProgramHandle = 0; mCompiled = 0; - } - } - - //----------------------------------------------------------------------- - void GLSLESProgram::populateParameterNames(GpuProgramParametersSharedPtr params) - { - getConstantDefinitions(); - params->_setNamedConstants(mConstantDefs); - // Don't set logical / physical maps here, as we can't access parameters by logical index in GLHL. - } - //----------------------------------------------------------------------- - void GLSLESProgram::buildConstantDefinitions() const - { - // We need an accurate list of all the uniforms in the shader, but we - // can't get at them until we link all the shaders into a program object. - - // Therefore instead, parse the source code manually and extract the uniforms - createParameterMappingStructures(true); + } + } + + //----------------------------------------------------------------------- + void GLSLESProgram::populateParameterNames(GpuProgramParametersSharedPtr params) + { + getConstantDefinitions(); + params->_setNamedConstants(mConstantDefs); + // Don't set logical / physical maps here, as we can't access parameters by logical index in GLHL. + } + //----------------------------------------------------------------------- + void GLSLESProgram::buildConstantDefinitions() const + { + // We need an accurate list of all the uniforms in the shader, but we + // can't get at them until we link all the shaders into a program object. + + // Therefore instead, parse the source code manually and extract the uniforms + createParameterMappingStructures(true); if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLESProgramPipelineManager::getSingleton().extractConstantDefs(mSource, *mConstantDefs.get(), mName); @@ -352,61 +352,61 @@ namespace Ogre { { GLSLESLinkProgramManager::getSingleton().extractConstantDefs(mSource, *mConstantDefs.get(), mName); } - } - - //--------------------------------------------------------------------- - inline bool GLSLESProgram::getPassSurfaceAndLightStates(void) const - { - // Scenemanager should pass on light & material state to the rendersystem - return true; - } - //--------------------------------------------------------------------- - inline bool GLSLESProgram::getPassTransformStates(void) const - { - // Scenemanager should pass on transform state to the rendersystem - return true; - } - //--------------------------------------------------------------------- - inline bool GLSLESProgram::getPassFogStates(void) const - { - // Scenemanager should pass on fog state to the rendersystem - return true; - } - //----------------------------------------------------------------------- + } + + //--------------------------------------------------------------------- + inline bool GLSLESProgram::getPassSurfaceAndLightStates(void) const + { + // Scenemanager should pass on light & material state to the rendersystem + return true; + } + //--------------------------------------------------------------------- + inline bool GLSLESProgram::getPassTransformStates(void) const + { + // Scenemanager should pass on transform state to the rendersystem + return true; + } + //--------------------------------------------------------------------- + inline bool GLSLESProgram::getPassFogStates(void) const + { + // Scenemanager should pass on fog state to the rendersystem + return true; + } + //----------------------------------------------------------------------- #if !OGRE_NO_GLES2_GLSL_OPTIMISER - String GLSLESProgram::CmdOptimisation::doGet(const void *target) const - { + String GLSLESProgram::CmdOptimisation::doGet(const void *target) const + { return StringConverter::toString(static_cast(target)->getOptimiserEnabled()); - } - void GLSLESProgram::CmdOptimisation::doSet(void *target, const String& val) - { + } + void GLSLESProgram::CmdOptimisation::doSet(void *target, const String& val) + { static_cast(target)->setOptimiserEnabled(StringConverter::parseBool(val)); - } + } #endif - //----------------------------------------------------------------------- - String GLSLESProgram::CmdPreprocessorDefines::doGet(const void *target) const - { - return static_cast(target)->getPreprocessorDefines(); - } - void GLSLESProgram::CmdPreprocessorDefines::doSet(void *target, const String& val) - { - static_cast(target)->setPreprocessorDefines(val); - } - - //----------------------------------------------------------------------- - void GLSLESProgram::attachToProgramObject( const GLuint programObject ) - { + //----------------------------------------------------------------------- + String GLSLESProgram::CmdPreprocessorDefines::doGet(const void *target) const + { + return static_cast(target)->getPreprocessorDefines(); + } + void GLSLESProgram::CmdPreprocessorDefines::doSet(void *target, const String& val) + { + static_cast(target)->setPreprocessorDefines(val); + } + + //----------------------------------------------------------------------- + void GLSLESProgram::attachToProgramObject( const GLuint programObject ) + { // LogManager::getSingleton().logMessage("Attaching shader " + StringConverter::toString(mGLShaderHandle) + // " to program " + StringConverter::toString(programObject)); OGRE_CHECK_GL_ERROR(glAttachShader(programObject, mGLShaderHandle)); } - //----------------------------------------------------------------------- - void GLSLESProgram::detachFromProgramObject( const GLuint programObject ) - { + //----------------------------------------------------------------------- + void GLSLESProgram::detachFromProgramObject( const GLuint programObject ) + { // LogManager::getSingleton().logMessage("Detaching shader " + StringConverter::toString(mGLShaderHandle) + // " to program " + StringConverter::toString(programObject)); OGRE_CHECK_GL_ERROR(glDetachShader(programObject, mGLShaderHandle)); - } + } //----------------------------------------------------------------------- const String& GLSLESProgram::getLanguage(void) const @@ -415,55 +415,55 @@ namespace Ogre { return language; } - //----------------------------------------------------------------------- - Ogre::GpuProgramParametersSharedPtr GLSLESProgram::createParameters( void ) - { - GpuProgramParametersSharedPtr params = HighLevelGpuProgram::createParameters(); - params->setTransposeMatrices(true); - return params; - } - //----------------------------------------------------------------------- - void GLSLESProgram::checkAndFixInvalidDefaultPrecisionError( String &message ) - { - String precisionQualifierErrorString = ": 'Default Precision Qualifier' : invalid type Type for default precision qualifier can be only float or int"; - vector< String >::type linesOfSource = StringUtil::split(mSource, "\n"); - if( message.find(precisionQualifierErrorString) != String::npos ) - { - LogManager::getSingleton().logMessage("Fixing invalid type Type for default precision qualifier by deleting bad lines the re-compiling"); - - // remove relevant lines from source - vector< String >::type errors = StringUtil::split(message, "\n"); - - // going from the end so when we delete a line the numbers of the lines before will not change - for(int i = static_cast(errors.size()) - 1 ; i != -1 ; i--) - { - String & curError = errors[i]; - size_t foundPos = curError.find(precisionQualifierErrorString); - if(foundPos != String::npos) - { - String lineNumber = curError.substr(0, foundPos); - size_t posOfStartOfNumber = lineNumber.find_last_of(':'); - if (posOfStartOfNumber != String::npos) - { - lineNumber = lineNumber.substr(posOfStartOfNumber + 1, lineNumber.size() - (posOfStartOfNumber + 1)); - if (StringConverter::isNumber(lineNumber)) - { - int iLineNumber = StringConverter::parseInt(lineNumber); - linesOfSource.erase(linesOfSource.begin() + iLineNumber - 1); - } - } - } - } - // rebuild source - StringStream newSource; - for(size_t i = 0; i < linesOfSource.size() ; i++) - { - newSource << linesOfSource[i] << "\n"; - } - mSource = newSource.str(); - - const char *source = mSource.c_str(); - OGRE_CHECK_GL_ERROR(glShaderSource(mGLShaderHandle, 1, &source, NULL)); + //----------------------------------------------------------------------- + Ogre::GpuProgramParametersSharedPtr GLSLESProgram::createParameters( void ) + { + GpuProgramParametersSharedPtr params = HighLevelGpuProgram::createParameters(); + params->setTransposeMatrices(true); + return params; + } + //----------------------------------------------------------------------- + void GLSLESProgram::checkAndFixInvalidDefaultPrecisionError( String &message ) + { + String precisionQualifierErrorString = ": 'Default Precision Qualifier' : invalid type Type for default precision qualifier can be only float or int"; + vector< String >::type linesOfSource = StringUtil::split(mSource, "\n"); + if( message.find(precisionQualifierErrorString) != String::npos ) + { + LogManager::getSingleton().logMessage("Fixing invalid type Type for default precision qualifier by deleting bad lines the re-compiling"); + + // remove relevant lines from source + vector< String >::type errors = StringUtil::split(message, "\n"); + + // going from the end so when we delete a line the numbers of the lines before will not change + for(int i = static_cast(errors.size()) - 1 ; i != -1 ; i--) + { + String & curError = errors[i]; + size_t foundPos = curError.find(precisionQualifierErrorString); + if(foundPos != String::npos) + { + String lineNumber = curError.substr(0, foundPos); + size_t posOfStartOfNumber = lineNumber.find_last_of(':'); + if (posOfStartOfNumber != String::npos) + { + lineNumber = lineNumber.substr(posOfStartOfNumber + 1, lineNumber.size() - (posOfStartOfNumber + 1)); + if (StringConverter::isNumber(lineNumber)) + { + int iLineNumber = StringConverter::parseInt(lineNumber); + linesOfSource.erase(linesOfSource.begin() + iLineNumber - 1); + } + } + } + } + // rebuild source + StringStream newSource; + for(size_t i = 0; i < linesOfSource.size() ; i++) + { + newSource << linesOfSource[i] << "\n"; + } + mSource = newSource.str(); + + const char *source = mSource.c_str(); + OGRE_CHECK_GL_ERROR(glShaderSource(mGLShaderHandle, 1, &source, NULL)); if (compile()) { @@ -473,61 +473,61 @@ namespace Ogre { { LogManager::getSingleton().logMessage("The removing of the lines didn't help."); } - } - } - //----------------------------------------------------------------------- - RenderOperation::OperationType parseOperationType(const String& val) - { - if (val == "point_list") - { - return RenderOperation::OT_POINT_LIST; - } - else if (val == "line_list") - { - return RenderOperation::OT_LINE_LIST; - } - else if (val == "line_strip") - { - return RenderOperation::OT_LINE_STRIP; - } - else if (val == "triangle_strip") - { - return RenderOperation::OT_TRIANGLE_STRIP; - } - else if (val == "triangle_fan") - { - return RenderOperation::OT_TRIANGLE_FAN; - } - else - { - //Triangle list is the default fallback. Keep it this way? - return RenderOperation::OT_TRIANGLE_LIST; - } - } - //----------------------------------------------------------------------- - String operationTypeToString(RenderOperation::OperationType val) - { - switch (val) - { - case RenderOperation::OT_POINT_LIST: - return "point_list"; - break; - case RenderOperation::OT_LINE_LIST: - return "line_list"; - break; - case RenderOperation::OT_LINE_STRIP: - return "line_strip"; - break; - case RenderOperation::OT_TRIANGLE_STRIP: - return "triangle_strip"; - break; - case RenderOperation::OT_TRIANGLE_FAN: - return "triangle_fan"; - break; - case RenderOperation::OT_TRIANGLE_LIST: - default: - return "triangle_list"; - break; - } - } + } + } + //----------------------------------------------------------------------- + RenderOperation::OperationType parseOperationType(const String& val) + { + if (val == "point_list") + { + return RenderOperation::OT_POINT_LIST; + } + else if (val == "line_list") + { + return RenderOperation::OT_LINE_LIST; + } + else if (val == "line_strip") + { + return RenderOperation::OT_LINE_STRIP; + } + else if (val == "triangle_strip") + { + return RenderOperation::OT_TRIANGLE_STRIP; + } + else if (val == "triangle_fan") + { + return RenderOperation::OT_TRIANGLE_FAN; + } + else + { + //Triangle list is the default fallback. Keep it this way? + return RenderOperation::OT_TRIANGLE_LIST; + } + } + //----------------------------------------------------------------------- + String operationTypeToString(RenderOperation::OperationType val) + { + switch (val) + { + case RenderOperation::OT_POINT_LIST: + return "point_list"; + break; + case RenderOperation::OT_LINE_LIST: + return "line_list"; + break; + case RenderOperation::OT_LINE_STRIP: + return "line_strip"; + break; + case RenderOperation::OT_TRIANGLE_STRIP: + return "triangle_strip"; + break; + case RenderOperation::OT_TRIANGLE_FAN: + return "triangle_fan"; + break; + case RenderOperation::OT_TRIANGLE_LIST: + default: + return "triangle_list"; + break; + } + } } diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramCommon.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramCommon.cpp index a2a915d805a..1330a609986 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramCommon.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramCommon.cpp @@ -35,17 +35,17 @@ namespace Ogre { - //----------------------------------------------------------------------- - GLSLESProgramCommon::GLSLESProgramCommon(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram) + //----------------------------------------------------------------------- + GLSLESProgramCommon::GLSLESProgramCommon(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram) : mVertexProgram(vertexProgram) , mFragmentProgram(fragmentProgram) , mUniformRefsBuilt(false) , mLinked(false) , mTriedToLinkAndFailed(false) - { - // init mCustomAttributesIndexes - for(size_t i = 0 ; i < VES_COUNT; i++) - for(size_t j = 0 ; j < OGRE_MAX_TEXTURE_COORD_SETS; j++) + { + // init mCustomAttributesIndexes + for(size_t i = 0 ; i < VES_COUNT; i++) + for(size_t j = 0 ; j < OGRE_MAX_TEXTURE_COORD_SETS; j++) { mCustomAttributesIndexes[i][j] = NULL_CUSTOM_ATTRIBUTES_INDEX; } @@ -70,38 +70,38 @@ namespace Ogre { } // Initialise uniform cache - mUniformCache = new GLES2UniformCache(); - } + mUniformCache = new GLES2UniformCache(); + } - //----------------------------------------------------------------------- - GLSLESProgramCommon::~GLSLESProgramCommon(void) - { - OGRE_CHECK_GL_ERROR(glDeleteProgram(mGLProgramHandle)); + //----------------------------------------------------------------------- + GLSLESProgramCommon::~GLSLESProgramCommon(void) + { + OGRE_CHECK_GL_ERROR(glDeleteProgram(mGLProgramHandle)); delete mUniformCache; mUniformCache = 0; - } + } - //----------------------------------------------------------------------- - Ogre::String GLSLESProgramCommon::getCombinedName() - { - String name; - if (mVertexProgram) - { - name += "Vertex Program:" ; - name += mVertexProgram->getName(); - } - if (mFragmentProgram) - { - name += " Fragment Program:" ; - name += mFragmentProgram->getName(); - } + //----------------------------------------------------------------------- + Ogre::String GLSLESProgramCommon::getCombinedName() + { + String name; + if (mVertexProgram) + { + name += "Vertex Program:" ; + name += mVertexProgram->getName(); + } + if (mFragmentProgram) + { + name += " Fragment Program:" ; + name += mFragmentProgram->getName(); + } name += "\n"; - return name; - } + return name; + } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- VertexElementSemantic GLSLESProgramCommon::getAttributeSemanticEnum(String type) { VertexElementSemantic semantic = mSemanticTypeMap[type]; @@ -116,9 +116,9 @@ namespace Ogre { } } - //----------------------------------------------------------------------- - const char * GLSLESProgramCommon::getAttributeSemanticString(VertexElementSemantic semantic) - { + //----------------------------------------------------------------------- + const char * GLSLESProgramCommon::getAttributeSemanticString(VertexElementSemantic semantic) + { for (SemanticToStringMap::iterator i = mSemanticTypeMap.begin(); i != mSemanticTypeMap.end(); ++i) { if((*i).second == semantic) @@ -127,59 +127,59 @@ namespace Ogre { assert(false && "Missing attribute!"); return 0; - } + } - //----------------------------------------------------------------------- - GLint GLSLESProgramCommon::getAttributeIndex(VertexElementSemantic semantic, uint index) - { - GLint res = mCustomAttributesIndexes[semantic-1][index]; - if (res == NULL_CUSTOM_ATTRIBUTES_INDEX) - { - const char * attString = getAttributeSemanticString(semantic); - GLint attrib; + //----------------------------------------------------------------------- + GLint GLSLESProgramCommon::getAttributeIndex(VertexElementSemantic semantic, uint index) + { + GLint res = mCustomAttributesIndexes[semantic-1][index]; + if (res == NULL_CUSTOM_ATTRIBUTES_INDEX) + { + const char * attString = getAttributeSemanticString(semantic); + GLint attrib; OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(mGLProgramHandle, attString)); - // sadly position is a special case - if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX && semantic == VES_POSITION) - { - OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(mGLProgramHandle, "position")); - } - - // for uv and other case the index is a part of the name - if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX) - { - String attStringWithSemantic = String(attString) + StringConverter::toString(index); - OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(mGLProgramHandle, attStringWithSemantic.c_str())); - } - - // update mCustomAttributesIndexes with the index we found (or didn't find) - mCustomAttributesIndexes[semantic-1][index] = attrib; - res = attrib; - } - return res; - } - //----------------------------------------------------------------------- - bool GLSLESProgramCommon::isAttributeValid(VertexElementSemantic semantic, uint index) - { - return getAttributeIndex(semantic, index) != NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX; - } + // sadly position is a special case + if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX && semantic == VES_POSITION) + { + OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(mGLProgramHandle, "position")); + } + + // for uv and other case the index is a part of the name + if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX) + { + String attStringWithSemantic = String(attString) + StringConverter::toString(index); + OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(mGLProgramHandle, attStringWithSemantic.c_str())); + } + + // update mCustomAttributesIndexes with the index we found (or didn't find) + mCustomAttributesIndexes[semantic-1][index] = attrib; + res = attrib; + } + return res; + } + //----------------------------------------------------------------------- + bool GLSLESProgramCommon::isAttributeValid(VertexElementSemantic semantic, uint index) + { + return getAttributeIndex(semantic, index) != NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX; + } //----------------------------------------------------------------------- - void GLSLESProgramCommon::getMicrocodeFromCache(void) - { - GpuProgramManager::Microcode cacheMicrocode = + void GLSLESProgramCommon::getMicrocodeFromCache(void) + { + GpuProgramManager::Microcode cacheMicrocode = GpuProgramManager::getSingleton().getMicrocodeFromCache(getCombinedName()); - // add to the microcode to the cache - String name; - name = getCombinedName(); + // add to the microcode to the cache + String name; + name = getCombinedName(); - // turns out we need this param when loading - GLenum binaryFormat = 0; + // turns out we need this param when loading + GLenum binaryFormat = 0; - cacheMicrocode->seek(0); + cacheMicrocode->seek(0); - // get size of binary - cacheMicrocode->read(&binaryFormat, sizeof(GLenum)); + // get size of binary + cacheMicrocode->read(&binaryFormat, sizeof(GLenum)); if(getGLES2SupportRef()->checkExtension("GL_OES_get_program_binary") || gleswIsSupported(3, 0)) { @@ -192,17 +192,17 @@ namespace Ogre { binaryLength)); } - GLint success = 0; - OGRE_CHECK_GL_ERROR(glGetProgramiv(mGLProgramHandle, GL_LINK_STATUS, &success)); - if (!success) - { - // - // Something must have changed since the program binaries - // were cached away. Fallback to source shader loading path, - // and then retrieve and cache new program binaries once again. - // - compileAndLink(); - } - } + GLint success = 0; + OGRE_CHECK_GL_ERROR(glGetProgramiv(mGLProgramHandle, GL_LINK_STATUS, &success)); + if (!success) + { + // + // Something must have changed since the program binaries + // were cached away. Fallback to source shader loading path, + // and then retrieve and cache new program binaries once again. + // + compileAndLink(); + } + } } // namespace Ogre diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramFactory.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramFactory.cpp index ba97ab4ef1e..d3e4264f4b7 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramFactory.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramFactory.cpp @@ -38,11 +38,11 @@ namespace Ogre { //----------------------------------------------------------------------- String GLSLESProgramFactory::sLanguageName = "glsles"; //----------------------------------------------------------------------- - GLSLESProgramFactory::GLSLESProgramFactory(void) + GLSLESProgramFactory::GLSLESProgramFactory(void) { if (mLinkProgramManager == NULL) { - mLinkProgramManager = new GLSLESLinkProgramManager(); + mLinkProgramManager = new GLSLESLinkProgramManager(); } if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) @@ -56,9 +56,9 @@ namespace Ogre { //----------------------------------------------------------------------- GLSLESProgramFactory::~GLSLESProgramFactory(void) { - if (mLinkProgramManager) + if (mLinkProgramManager) { - delete mLinkProgramManager; + delete mLinkProgramManager; mLinkProgramManager = NULL; } @@ -84,7 +84,7 @@ namespace Ogre { return OGRE_NEW GLSLESProgram(creator, name, handle, group, isManual, loader); } //----------------------------------------------------------------------- - void GLSLESProgramFactory::destroy(HighLevelGpuProgram* prog) + void GLSLESProgramFactory::destroy(HighLevelGpuProgram* prog) { OGRE_DELETE prog; } diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramManagerCommon.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramManagerCommon.cpp index ef6cd7a9354..72bebcca2f5 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramManagerCommon.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramManagerCommon.cpp @@ -37,52 +37,52 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - GLSLESProgramManagerCommon::GLSLESProgramManagerCommon(void) : mActiveVertexGpuProgram(NULL), - mActiveFragmentGpuProgram(NULL) - { - // Fill in the relationship between type names and enums - mTypeEnumMap.insert(StringToEnumMap::value_type("float", GL_FLOAT)); - mTypeEnumMap.insert(StringToEnumMap::value_type("vec2", GL_FLOAT_VEC2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("vec3", GL_FLOAT_VEC3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("vec4", GL_FLOAT_VEC4)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2D", GL_SAMPLER_2D)); - mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCube", GL_SAMPLER_CUBE)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DShadow", GL_SAMPLER_2D_SHADOW_EXT)); - mTypeEnumMap.insert(StringToEnumMap::value_type("int", GL_INT)); - mTypeEnumMap.insert(StringToEnumMap::value_type("ivec2", GL_INT_VEC2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("ivec3", GL_INT_VEC3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("ivec4", GL_INT_VEC4)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat2", GL_FLOAT_MAT2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat3", GL_FLOAT_MAT3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat4", GL_FLOAT_MAT4)); + //----------------------------------------------------------------------- + GLSLESProgramManagerCommon::GLSLESProgramManagerCommon(void) : mActiveVertexGpuProgram(NULL), + mActiveFragmentGpuProgram(NULL) + { + // Fill in the relationship between type names and enums + mTypeEnumMap.insert(StringToEnumMap::value_type("float", GL_FLOAT)); + mTypeEnumMap.insert(StringToEnumMap::value_type("vec2", GL_FLOAT_VEC2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("vec3", GL_FLOAT_VEC3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("vec4", GL_FLOAT_VEC4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2D", GL_SAMPLER_2D)); + mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCube", GL_SAMPLER_CUBE)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DShadow", GL_SAMPLER_2D_SHADOW_EXT)); + mTypeEnumMap.insert(StringToEnumMap::value_type("int", GL_INT)); + mTypeEnumMap.insert(StringToEnumMap::value_type("ivec2", GL_INT_VEC2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("ivec3", GL_INT_VEC3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("ivec4", GL_INT_VEC4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat2", GL_FLOAT_MAT2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat3", GL_FLOAT_MAT3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat4", GL_FLOAT_MAT4)); #if OGRE_NO_GLES3_SUPPORT == 0 - mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x3", GL_FLOAT_MAT2x3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x2", GL_FLOAT_MAT3x2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x4", GL_FLOAT_MAT3x4)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x3", GL_FLOAT_MAT4x3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x4", GL_FLOAT_MAT2x4)); - mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x2", GL_FLOAT_MAT4x2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("bvec2", GL_BOOL_VEC2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("bvec3", GL_BOOL_VEC3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("bvec4", GL_BOOL_VEC4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x3", GL_FLOAT_MAT2x3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x2", GL_FLOAT_MAT3x2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat3x4", GL_FLOAT_MAT3x4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x3", GL_FLOAT_MAT4x3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat2x4", GL_FLOAT_MAT2x4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("mat4x2", GL_FLOAT_MAT4x2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("bvec2", GL_BOOL_VEC2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("bvec3", GL_BOOL_VEC3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("bvec4", GL_BOOL_VEC4)); mTypeEnumMap.insert(StringToEnumMap::value_type("uint", GL_UNSIGNED_INT)); - mTypeEnumMap.insert(StringToEnumMap::value_type("uvec2", GL_UNSIGNED_INT_VEC2)); - mTypeEnumMap.insert(StringToEnumMap::value_type("uvec3", GL_UNSIGNED_INT_VEC3)); - mTypeEnumMap.insert(StringToEnumMap::value_type("uvec4", GL_UNSIGNED_INT_VEC4)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler3D", GL_SAMPLER_3D)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DShadow", GL_SAMPLER_2D_SHADOW)); - mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCubeShadow", GL_SAMPLER_CUBE_SHADOW)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DArray", GL_SAMPLER_2D_ARRAY)); - mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DArrayShadow", GL_SAMPLER_2D_ARRAY_SHADOW)); - mTypeEnumMap.insert(StringToEnumMap::value_type("isampler2D", GL_INT_SAMPLER_2D)); - mTypeEnumMap.insert(StringToEnumMap::value_type("isampler3D", GL_INT_SAMPLER_3D)); - mTypeEnumMap.insert(StringToEnumMap::value_type("isamplerCube", GL_INT_SAMPLER_CUBE)); - mTypeEnumMap.insert(StringToEnumMap::value_type("isampler2DArray", GL_INT_SAMPLER_2D_ARRAY)); - mTypeEnumMap.insert(StringToEnumMap::value_type("usampler2D", GL_UNSIGNED_INT_SAMPLER_2D)); - mTypeEnumMap.insert(StringToEnumMap::value_type("usampler3D", GL_UNSIGNED_INT_SAMPLER_3D)); - mTypeEnumMap.insert(StringToEnumMap::value_type("usamplerCube", GL_UNSIGNED_INT_SAMPLER_CUBE)); - mTypeEnumMap.insert(StringToEnumMap::value_type("usampler2DArray", GL_UNSIGNED_INT_SAMPLER_2D_ARRAY)); + mTypeEnumMap.insert(StringToEnumMap::value_type("uvec2", GL_UNSIGNED_INT_VEC2)); + mTypeEnumMap.insert(StringToEnumMap::value_type("uvec3", GL_UNSIGNED_INT_VEC3)); + mTypeEnumMap.insert(StringToEnumMap::value_type("uvec4", GL_UNSIGNED_INT_VEC4)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler3D", GL_SAMPLER_3D)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DShadow", GL_SAMPLER_2D_SHADOW)); + mTypeEnumMap.insert(StringToEnumMap::value_type("samplerCubeShadow", GL_SAMPLER_CUBE_SHADOW)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DArray", GL_SAMPLER_2D_ARRAY)); + mTypeEnumMap.insert(StringToEnumMap::value_type("sampler2DArrayShadow", GL_SAMPLER_2D_ARRAY_SHADOW)); + mTypeEnumMap.insert(StringToEnumMap::value_type("isampler2D", GL_INT_SAMPLER_2D)); + mTypeEnumMap.insert(StringToEnumMap::value_type("isampler3D", GL_INT_SAMPLER_3D)); + mTypeEnumMap.insert(StringToEnumMap::value_type("isamplerCube", GL_INT_SAMPLER_CUBE)); + mTypeEnumMap.insert(StringToEnumMap::value_type("isampler2DArray", GL_INT_SAMPLER_2D_ARRAY)); + mTypeEnumMap.insert(StringToEnumMap::value_type("usampler2D", GL_UNSIGNED_INT_SAMPLER_2D)); + mTypeEnumMap.insert(StringToEnumMap::value_type("usampler3D", GL_UNSIGNED_INT_SAMPLER_3D)); + mTypeEnumMap.insert(StringToEnumMap::value_type("usamplerCube", GL_UNSIGNED_INT_SAMPLER_CUBE)); + mTypeEnumMap.insert(StringToEnumMap::value_type("usampler2DArray", GL_UNSIGNED_INT_SAMPLER_2D_ARRAY)); #endif #if !OGRE_NO_GLES2_GLSL_OPTIMISER @@ -92,11 +92,11 @@ namespace Ogre { mGLSLOptimiserContext = glslopt_initialize(kGlslTargetOpenGLES20); #endif #endif - } + } - //----------------------------------------------------------------------- - GLSLESProgramManagerCommon::~GLSLESProgramManagerCommon(void) - { + //----------------------------------------------------------------------- + GLSLESProgramManagerCommon::~GLSLESProgramManagerCommon(void) + { #if !OGRE_NO_GLES2_GLSL_OPTIMISER if(mGLSLOptimiserContext) { @@ -104,28 +104,28 @@ namespace Ogre { mGLSLOptimiserContext = NULL; } #endif - } - //--------------------------------------------------------------------- - void GLSLESProgramManagerCommon::completeDefInfo(GLenum gltype, - GpuConstantDefinition& defToUpdate) - { - // Decode uniform size and type - // Note GLSL ES never packs rows into float4's(from an API perspective anyway) - // therefore all values are tight in the buffer - switch (gltype) - { - case GL_FLOAT: - defToUpdate.constType = GCT_FLOAT1; - break; - case GL_FLOAT_VEC2: - defToUpdate.constType = GCT_FLOAT2; - break; - case GL_FLOAT_VEC3: - defToUpdate.constType = GCT_FLOAT3; - break; - case GL_FLOAT_VEC4: - defToUpdate.constType = GCT_FLOAT4; - break; + } + //--------------------------------------------------------------------- + void GLSLESProgramManagerCommon::completeDefInfo(GLenum gltype, + GpuConstantDefinition& defToUpdate) + { + // Decode uniform size and type + // Note GLSL ES never packs rows into float4's(from an API perspective anyway) + // therefore all values are tight in the buffer + switch (gltype) + { + case GL_FLOAT: + defToUpdate.constType = GCT_FLOAT1; + break; + case GL_FLOAT_VEC2: + defToUpdate.constType = GCT_FLOAT2; + break; + case GL_FLOAT_VEC3: + defToUpdate.constType = GCT_FLOAT3; + break; + case GL_FLOAT_VEC4: + defToUpdate.constType = GCT_FLOAT4; + break; #if OGRE_NO_GLES3_SUPPORT == 0 case GL_SAMPLER_3D: case GL_INT_SAMPLER_3D: @@ -138,41 +138,41 @@ namespace Ogre { case GL_INT_SAMPLER_2D_ARRAY: case GL_SAMPLER_2D_ARRAY: #endif - case GL_SAMPLER_2D: - defToUpdate.constType = GCT_SAMPLER2D; - break; + case GL_SAMPLER_2D: + defToUpdate.constType = GCT_SAMPLER2D; + break; #if OGRE_NO_GLES3_SUPPORT == 0 case GL_SAMPLER_CUBE_SHADOW: case GL_INT_SAMPLER_CUBE: case GL_UNSIGNED_INT_SAMPLER_CUBE: #endif - case GL_SAMPLER_CUBE: - defToUpdate.constType = GCT_SAMPLERCUBE; - break; + case GL_SAMPLER_CUBE: + defToUpdate.constType = GCT_SAMPLERCUBE; + break; case GL_SAMPLER_2D_SHADOW_EXT: defToUpdate.constType = GCT_SAMPLER2DSHADOW; break; case GL_INT: - defToUpdate.constType = GCT_INT1; - break; - case GL_INT_VEC2: - defToUpdate.constType = GCT_INT2; - break; - case GL_INT_VEC3: - defToUpdate.constType = GCT_INT3; - break; - case GL_INT_VEC4: - defToUpdate.constType = GCT_INT4; - break; - case GL_FLOAT_MAT2: - defToUpdate.constType = GCT_MATRIX_2X2; - break; - case GL_FLOAT_MAT3: - defToUpdate.constType = GCT_MATRIX_3X3; - break; - case GL_FLOAT_MAT4: - defToUpdate.constType = GCT_MATRIX_4X4; - break; + defToUpdate.constType = GCT_INT1; + break; + case GL_INT_VEC2: + defToUpdate.constType = GCT_INT2; + break; + case GL_INT_VEC3: + defToUpdate.constType = GCT_INT3; + break; + case GL_INT_VEC4: + defToUpdate.constType = GCT_INT4; + break; + case GL_FLOAT_MAT2: + defToUpdate.constType = GCT_MATRIX_2X2; + break; + case GL_FLOAT_MAT3: + defToUpdate.constType = GCT_MATRIX_3X3; + break; + case GL_FLOAT_MAT4: + defToUpdate.constType = GCT_MATRIX_4X4; + break; #if OGRE_NO_GLES3_SUPPORT == 0 case GL_FLOAT_MAT2x3: defToUpdate.constType = GCT_MATRIX_2X3; @@ -193,47 +193,47 @@ namespace Ogre { defToUpdate.constType = GCT_MATRIX_4X3; break; #endif - default: - defToUpdate.constType = GCT_UNKNOWN; - break; - } - - // GL doesn't pad - defToUpdate.elementSize = GpuConstantDefinition::getElementSize(defToUpdate.constType, false); - } - - //--------------------------------------------------------------------- - bool GLSLESProgramManagerCommon::completeParamSource( - const String& paramName, - const GpuConstantDefinitionMap* vertexConstantDefs, - const GpuConstantDefinitionMap* fragmentConstantDefs, - GLUniformReference& refToUpdate) - { - if (vertexConstantDefs) - { - GpuConstantDefinitionMap::const_iterator parami = - vertexConstantDefs->find(paramName); - if (parami != vertexConstantDefs->end()) - { - refToUpdate.mSourceProgType = GPT_VERTEX_PROGRAM; - refToUpdate.mConstantDef = &(parami->second); - return true; - } - } - - if (fragmentConstantDefs) - { - GpuConstantDefinitionMap::const_iterator parami = - fragmentConstantDefs->find(paramName); - if (parami != fragmentConstantDefs->end()) - { - refToUpdate.mSourceProgType = GPT_FRAGMENT_PROGRAM; - refToUpdate.mConstantDef = &(parami->second); - return true; - } - } - return false; - } + default: + defToUpdate.constType = GCT_UNKNOWN; + break; + } + + // GL doesn't pad + defToUpdate.elementSize = GpuConstantDefinition::getElementSize(defToUpdate.constType, false); + } + + //--------------------------------------------------------------------- + bool GLSLESProgramManagerCommon::completeParamSource( + const String& paramName, + const GpuConstantDefinitionMap* vertexConstantDefs, + const GpuConstantDefinitionMap* fragmentConstantDefs, + GLUniformReference& refToUpdate) + { + if (vertexConstantDefs) + { + GpuConstantDefinitionMap::const_iterator parami = + vertexConstantDefs->find(paramName); + if (parami != vertexConstantDefs->end()) + { + refToUpdate.mSourceProgType = GPT_VERTEX_PROGRAM; + refToUpdate.mConstantDef = &(parami->second); + return true; + } + } + + if (fragmentConstantDefs) + { + GpuConstantDefinitionMap::const_iterator parami = + fragmentConstantDefs->find(paramName); + if (parami != fragmentConstantDefs->end()) + { + refToUpdate.mSourceProgType = GPT_FRAGMENT_PROGRAM; + refToUpdate.mConstantDef = &(parami->second); + return true; + } + } + return false; + } #if !OGRE_NO_GLES2_GLSL_OPTIMISER void GLSLESProgramManagerCommon::optimiseShaderSource(GLSLESGpuProgram* gpuProgram) @@ -280,79 +280,79 @@ namespace Ogre { } #endif - //--------------------------------------------------------------------- - void GLSLESProgramManagerCommon::extractUniforms(GLuint programObject, - const GpuConstantDefinitionMap* vertexConstantDefs, - const GpuConstantDefinitionMap* fragmentConstantDefs, - GLUniformReferenceList& list, GLUniformBufferList& sharedList) - { - // Scan through the active uniforms and add them to the reference list - GLint uniformCount = 0; + //--------------------------------------------------------------------- + void GLSLESProgramManagerCommon::extractUniforms(GLuint programObject, + const GpuConstantDefinitionMap* vertexConstantDefs, + const GpuConstantDefinitionMap* fragmentConstantDefs, + GLUniformReferenceList& list, GLUniformBufferList& sharedList) + { + // Scan through the active uniforms and add them to the reference list + GLint uniformCount = 0; GLint maxLength = 0; - char* uniformName = NULL; - #define uniformLength 200 + char* uniformName = NULL; + #define uniformLength 200 - OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength)); + OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength)); // If the max length of active uniforms is 0, then there are 0 active. // There won't be any to extract so we can return. if(maxLength == 0) return; - uniformName = new char[maxLength + 1]; - GLUniformReference newGLUniformReference; - - // Get the number of active uniforms - OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORMS, &uniformCount)); - - // Loop over each of the active uniforms, and add them to the reference container - // only do this for user defined uniforms, ignore built in gl state uniforms - for (GLuint index = 0; index < (GLuint)uniformCount; index++) - { - GLint arraySize = 0; - GLenum glType = GL_NONE; - OGRE_CHECK_GL_ERROR(glGetActiveUniform(programObject, index, maxLength, NULL, - &arraySize, &glType, uniformName)); - - // Don't add built in uniforms - newGLUniformReference.mLocation = glGetUniformLocation(programObject, uniformName); - if (newGLUniformReference.mLocation >= 0) - { - // User defined uniform found, add it to the reference list - String paramName = String( uniformName ); - - // If the uniform name has a "[" in it then its an array element uniform. - String::size_type arrayStart = paramName.find("["); - if (arrayStart != String::npos) - { - // If not the first array element then skip it and continue to the next uniform - if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0) continue; - paramName = paramName.substr(0, arrayStart); - } - - // Find out which params object this comes from - bool foundSource = completeParamSource(paramName, - vertexConstantDefs, fragmentConstantDefs, newGLUniformReference); - - // Only add this parameter if we found the source - if (foundSource) - { - assert(size_t (arraySize) == newGLUniformReference.mConstantDef->arraySize - && "GL doesn't agree with our array size!"); - list.push_back(newGLUniformReference); - } - - // Don't bother adding individual array params, they will be - // picked up in the 'parent' parameter can copied all at once - // anyway, individual indexes are only needed for lookup from - // user params - } // end if - } // end for - - if( uniformName != NULL ) - { - delete[] uniformName; - } + uniformName = new char[maxLength + 1]; + GLUniformReference newGLUniformReference; + + // Get the number of active uniforms + OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORMS, &uniformCount)); + + // Loop over each of the active uniforms, and add them to the reference container + // only do this for user defined uniforms, ignore built in gl state uniforms + for (GLuint index = 0; index < (GLuint)uniformCount; index++) + { + GLint arraySize = 0; + GLenum glType = GL_NONE; + OGRE_CHECK_GL_ERROR(glGetActiveUniform(programObject, index, maxLength, NULL, + &arraySize, &glType, uniformName)); + + // Don't add built in uniforms + newGLUniformReference.mLocation = glGetUniformLocation(programObject, uniformName); + if (newGLUniformReference.mLocation >= 0) + { + // User defined uniform found, add it to the reference list + String paramName = String( uniformName ); + + // If the uniform name has a "[" in it then its an array element uniform. + String::size_type arrayStart = paramName.find("["); + if (arrayStart != String::npos) + { + // If not the first array element then skip it and continue to the next uniform + if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0) continue; + paramName = paramName.substr(0, arrayStart); + } + + // Find out which params object this comes from + bool foundSource = completeParamSource(paramName, + vertexConstantDefs, fragmentConstantDefs, newGLUniformReference); + + // Only add this parameter if we found the source + if (foundSource) + { + assert(size_t (arraySize) == newGLUniformReference.mConstantDef->arraySize + && "GL doesn't agree with our array size!"); + list.push_back(newGLUniformReference); + } + + // Don't bother adding individual array params, they will be + // picked up in the 'parent' parameter can copied all at once + // anyway, individual indexes are only needed for lookup from + // user params + } // end if + } // end for + + if( uniformName != NULL ) + { + delete[] uniformName; + } #if OGRE_NO_GLES3_SUPPORT == 0 // Now deal with uniform blocks @@ -378,49 +378,49 @@ namespace Ogre { } #endif } - //--------------------------------------------------------------------- - void GLSLESProgramManagerCommon::extractConstantDefs(const String& src, - GpuNamedConstants& defs, const String& filename) - { - // Parse the output string and collect all uniforms - // NOTE this relies on the source already having been preprocessed - // which is done in GLSLESProgram::loadFromSource - String line; - String::size_type currPos = src.find("uniform"); - while (currPos != String::npos) - { - GpuConstantDefinition def; - String paramName; - - // Now check for using the word 'uniform' in a larger string & ignore - bool inLargerString = false; - if (currPos != 0) - { - char prev = src.at(currPos - 1); - if (prev != ' ' && prev != '\t' && prev != '\r' && prev != '\n' - && prev != ';') - inLargerString = true; - } - if (!inLargerString && currPos + 7 < src.size()) - { - char next = src.at(currPos + 7); - if (next != ' ' && next != '\t' && next != '\r' && next != '\n') - inLargerString = true; - } - - // skip 'uniform' - currPos += 7; - - if (!inLargerString) - { + //--------------------------------------------------------------------- + void GLSLESProgramManagerCommon::extractConstantDefs(const String& src, + GpuNamedConstants& defs, const String& filename) + { + // Parse the output string and collect all uniforms + // NOTE this relies on the source already having been preprocessed + // which is done in GLSLESProgram::loadFromSource + String line; + String::size_type currPos = src.find("uniform"); + while (currPos != String::npos) + { + GpuConstantDefinition def; + String paramName; + + // Now check for using the word 'uniform' in a larger string & ignore + bool inLargerString = false; + if (currPos != 0) + { + char prev = src.at(currPos - 1); + if (prev != ' ' && prev != '\t' && prev != '\r' && prev != '\n' + && prev != ';') + inLargerString = true; + } + if (!inLargerString && currPos + 7 < src.size()) + { + char next = src.at(currPos + 7); + if (next != ' ' && next != '\t' && next != '\r' && next != '\n') + inLargerString = true; + } + + // skip 'uniform' + currPos += 7; + + if (!inLargerString) + { String::size_type endPos; String typeString; GpuSharedParametersPtr blockSharedParams; // Check for a type. If there is one, then the semicolon is missing // otherwise treat as if it is a uniform block - String::size_type lineEndPos = src.find_first_of("\n\r", currPos); - line = src.substr(currPos, lineEndPos - currPos); + String::size_type lineEndPos = src.find_first_of("\n\r", currPos); + line = src.substr(currPos, lineEndPos - currPos); StringVector parts = StringUtil::split(line, " \t"); // Skip over precision keywords @@ -475,15 +475,15 @@ namespace Ogre { parseIndividualConstant(src, defs, currPos, filename, blockSharedParams); } line = src.substr(currPos, endPos - currPos); - } // not commented or a larger symbol + } // not commented or a larger symbol - // Find next one - currPos = src.find("uniform", currPos); - } - - } + // Find next one + currPos = src.find("uniform", currPos); + } + + } //--------------------------------------------------------------------- - void GLSLESProgramManagerCommon::parseIndividualConstant(const String& src, GpuNamedConstants& defs, + void GLSLESProgramManagerCommon::parseIndividualConstant(const String& src, GpuNamedConstants& defs, String::size_type currPos, const String& filename, GpuSharedParametersPtr sharedParams) { diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramPipeline.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramPipeline.cpp index ab7781da3fb..da148c31659 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramPipeline.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramPipeline.cpp @@ -53,14 +53,14 @@ namespace Ogre } void GLSLESProgramPipeline::compileAndLink() - { + { #if OGRE_PLATFORM != OGRE_PLATFORM_NACL GLint linkStatus = 0; OGRE_CHECK_GL_ERROR(glGenProgramPipelinesEXT(1, &mGLProgramPipelineHandle)); OGRE_CHECK_GL_ERROR(glBindProgramPipelineEXT(mGLProgramPipelineHandle)); - // Compile and attach Vertex Program + // Compile and attach Vertex Program if(mVertexProgram && !mVertexProgram->isLinked()) { try @@ -69,7 +69,7 @@ namespace Ogre } catch (Exception& e) { - LogManager::getSingleton().stream() << e.getDescription(); + LogManager::getSingleton().stream() << e.getDescription(); mTriedToLinkAndFailed = true; return; } @@ -92,7 +92,7 @@ namespace Ogre setSkeletalAnimationIncluded(mVertexProgram->isSkeletalAnimationIncluded()); } - // Compile and attach Fragment Program + // Compile and attach Fragment Program if(mFragmentProgram && !mFragmentProgram->isLinked()) { try @@ -101,7 +101,7 @@ namespace Ogre } catch (Exception& e) { - LogManager::getSingleton().stream() << e.getDescription(); + LogManager::getSingleton().stream() << e.getDescription(); mTriedToLinkAndFailed = true; return; } @@ -123,8 +123,8 @@ namespace Ogre logObjectInfo( getCombinedName() + String("GLSL fragment program result : "), programHandle ); } - if(mLinked) - { + if(mLinked) + { if(mVertexProgram && mVertexProgram->isLinked()) { OGRE_CHECK_GL_ERROR(glUseProgramStagesEXT(mGLProgramPipelineHandle, GL_VERTEX_SHADER_BIT_EXT, mVertexProgram->getGLSLProgram()->getGLProgramHandle())); @@ -142,58 +142,58 @@ namespace Ogre glLabelObjectEXT(GL_PROGRAM_PIPELINE_OBJECT_EXT, mGLProgramPipelineHandle, 0, (mVertexProgram->getName() + "/" + mFragmentProgram->getName()).c_str()); #endif - } + } #endif - } + } void GLSLESProgramPipeline::_useProgram(void) { - if (mLinked) - { + if (mLinked) + { #if OGRE_PLATFORM != OGRE_PLATFORM_NACL OGRE_CHECK_GL_ERROR(glBindProgramPipelineEXT(mGLProgramPipelineHandle)); #endif - } + } } - //----------------------------------------------------------------------- - GLint GLSLESProgramPipeline::getAttributeIndex(VertexElementSemantic semantic, uint index) - { - GLint res = mCustomAttributesIndexes[semantic-1][index]; - if (res == NULL_CUSTOM_ATTRIBUTES_INDEX) - { + //----------------------------------------------------------------------- + GLint GLSLESProgramPipeline::getAttributeIndex(VertexElementSemantic semantic, uint index) + { + GLint res = mCustomAttributesIndexes[semantic-1][index]; + if (res == NULL_CUSTOM_ATTRIBUTES_INDEX) + { GLuint handle = mVertexProgram->getGLSLProgram()->getGLProgramHandle(); - const char * attString = getAttributeSemanticString(semantic); - GLint attrib; + const char * attString = getAttributeSemanticString(semantic); + GLint attrib; OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(handle, attString)); - // Sadly position is a special case - if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX && semantic == VES_POSITION) - { - OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(handle, "position")); - } + // Sadly position is a special case + if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX && semantic == VES_POSITION) + { + OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(handle, "position")); + } - // For uv and other case the index is a part of the name - if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX) - { - String attStringWithSemantic = String(attString) + StringConverter::toString(index); - OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(handle, attStringWithSemantic.c_str())); - } + // For uv and other case the index is a part of the name + if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX) + { + String attStringWithSemantic = String(attString) + StringConverter::toString(index); + OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(handle, attStringWithSemantic.c_str())); + } - // Update mCustomAttributesIndexes with the index we found (or didn't find) - mCustomAttributesIndexes[semantic-1][index] = attrib; - res = attrib; - } + // Update mCustomAttributesIndexes with the index we found (or didn't find) + mCustomAttributesIndexes[semantic-1][index] = attrib; + res = attrib; + } - return res; - } + return res; + } //----------------------------------------------------------------------- - void GLSLESProgramPipeline::activate(void) - { - if (!mLinked && !mTriedToLinkAndFailed) - { - glGetError(); // Clean up the error. Otherwise will flood log. + void GLSLESProgramPipeline::activate(void) + { + if (!mLinked && !mTriedToLinkAndFailed) + { + glGetError(); // Clean up the error. Otherwise will flood log. #if !OGRE_NO_GLES2_GLSL_OPTIMISER // Check CmdParams for each shader type to see if we should optimise @@ -219,43 +219,43 @@ namespace Ogre extractLayoutQualifiers(); - buildGLUniformReferences(); - } + buildGLUniformReferences(); + } _useProgram(); - } + } //----------------------------------------------------------------------- - void GLSLESProgramPipeline::buildGLUniformReferences(void) - { - if (!mUniformRefsBuilt) - { - const GpuConstantDefinitionMap* vertParams = 0; - const GpuConstantDefinitionMap* fragParams = 0; - if (mVertexProgram) - { - vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map); + void GLSLESProgramPipeline::buildGLUniformReferences(void) + { + if (!mUniformRefsBuilt) + { + const GpuConstantDefinitionMap* vertParams = 0; + const GpuConstantDefinitionMap* fragParams = 0; + if (mVertexProgram) + { + vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map); GLSLESProgramPipelineManager::getSingleton().extractUniforms(mVertexProgram->getGLSLProgram()->getGLProgramHandle(), - vertParams, NULL, mGLUniformReferences, mGLUniformBufferReferences); - } - if (mFragmentProgram) - { - fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map); + vertParams, NULL, mGLUniformReferences, mGLUniformBufferReferences); + } + if (mFragmentProgram) + { + fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map); GLSLESProgramPipelineManager::getSingleton().extractUniforms(mFragmentProgram->getGLSLProgram()->getGLProgramHandle(), NULL, fragParams, mGLUniformReferences, mGLUniformBufferReferences); - } + } - mUniformRefsBuilt = true; - } - } + mUniformRefsBuilt = true; + } + } - //----------------------------------------------------------------------- - void GLSLESProgramPipeline::updateUniforms(GpuProgramParametersSharedPtr params, + //----------------------------------------------------------------------- + void GLSLESProgramPipeline::updateUniforms(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType) - { - // Iterate through uniform reference list and update uniform values - GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); - GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); + { + // Iterate through uniform reference list and update uniform values + GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); + GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); #if OGRE_PLATFORM != OGRE_PLATFORM_NACL GLuint progID = 0; if(fromProgType == GPT_VERTEX_PROGRAM) @@ -267,17 +267,17 @@ namespace Ogre progID = mFragmentProgram->getGLSLProgram()->getGLProgramHandle(); } - for (;currentUniform != endUniform; ++currentUniform) - { - // Only pull values from buffer it's supposed to be in (vertex or fragment) - // This method will be called twice, once for vertex program params, - // and once for fragment program params. - if (fromProgType == currentUniform->mSourceProgType) - { - const GpuConstantDefinition* def = currentUniform->mConstantDef; - if (def->variability & mask) - { - GLsizei glArraySize = (GLsizei)def->arraySize; + for (;currentUniform != endUniform; ++currentUniform) + { + // Only pull values from buffer it's supposed to be in (vertex or fragment) + // This method will be called twice, once for vertex program params, + // and once for fragment program params. + if (fromProgType == currentUniform->mSourceProgType) + { + const GpuConstantDefinition* def = currentUniform->mConstantDef; + if (def->variability & mask) + { + GLsizei glArraySize = (GLsizei)def->arraySize; bool shouldUpdate = true; switch (def->constType) { @@ -308,9 +308,9 @@ namespace Ogre if(!shouldUpdate) continue; - // Get the index in the parameter real list - switch (def->constType) - { + // Get the index in the parameter real list + switch (def->constType) + { case GCT_FLOAT1: OGRE_CHECK_GL_ERROR(glProgramUniform1fvEXT(progID, currentUniform->mLocation, glArraySize, params->getFloatPointer(def->physicalIndex))); @@ -421,26 +421,26 @@ namespace Ogre default: break; - } // End switch - } // Variability & mask - } // fromProgType == currentUniform->mSourceProgType + } // End switch + } // Variability & mask + } // fromProgType == currentUniform->mSourceProgType - } // End for + } // End for #endif - } + } //----------------------------------------------------------------------- - void GLSLESProgramPipeline::updateUniformBlocks(GpuProgramParametersSharedPtr params, + void GLSLESProgramPipeline::updateUniformBlocks(GpuProgramParametersSharedPtr params, uint16 mask, GpuProgramType fromProgType) - { + { #if OGRE_NO_GLES3_SUPPORT == 0 // Iterate through the list of uniform buffers and update them as needed - GLUniformBufferIterator currentBuffer = mGLUniformBufferReferences.begin(); - GLUniformBufferIterator endBuffer = mGLUniformBufferReferences.end(); + GLUniformBufferIterator currentBuffer = mGLUniformBufferReferences.begin(); + GLUniformBufferIterator endBuffer = mGLUniformBufferReferences.end(); const GpuProgramParameters::GpuSharedParamUsageList& sharedParams = params->getSharedParameters(); - GpuProgramParameters::GpuSharedParamUsageList::const_iterator it, end = sharedParams.end(); - for (it = sharedParams.begin(); it != end; ++it) + GpuProgramParameters::GpuSharedParamUsageList::const_iterator it, end = sharedParams.end(); + for (it = sharedParams.begin(); it != end; ++it) { for (;currentBuffer != endBuffer; ++currentBuffer) { @@ -456,23 +456,23 @@ namespace Ogre } } #endif - } - //----------------------------------------------------------------------- - void GLSLESProgramPipeline::updatePassIterationUniforms(GpuProgramParametersSharedPtr params) - { - if (params->hasPassIterationNumber()) - { - size_t index = params->getPassIterationNumberIndex(); + } + //----------------------------------------------------------------------- + void GLSLESProgramPipeline::updatePassIterationUniforms(GpuProgramParametersSharedPtr params) + { + if (params->hasPassIterationNumber()) + { + size_t index = params->getPassIterationNumberIndex(); - GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); - GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); + GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); + GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); - // Need to find the uniform that matches the multi pass entry - for (;currentUniform != endUniform; ++currentUniform) - { - // Get the index in the parameter real list - if (index == currentUniform->mConstantDef->physicalIndex) - { + // Need to find the uniform that matches the multi pass entry + for (;currentUniform != endUniform; ++currentUniform) + { + // Get the index in the parameter real list + if (index == currentUniform->mConstantDef->physicalIndex) + { #if OGRE_PLATFORM != OGRE_PLATFORM_NACL GLuint progID = 0; @@ -501,11 +501,11 @@ namespace Ogre OGRE_CHECK_GL_ERROR(glProgramUniform1fvEXT(progID, currentUniform->mLocation, 1, params->getFloatPointer(index))); } #endif - // There will only be one multipass entry - return; - } - } - } + // There will only be one multipass entry + return; + } + } + } } //----------------------------------------------------------------------- void GLSLESProgramPipeline::extractLayoutQualifiers(void) @@ -523,13 +523,13 @@ namespace Ogre GLint index = 0; String::size_type endPos = shaderSource.find(";", currPos); - if (endPos == String::npos) - { - // Problem, missing semicolon, abort - break; - } + if (endPos == String::npos) + { + // Problem, missing semicolon, abort + break; + } - String line = shaderSource.substr(currPos, endPos - currPos); + String line = shaderSource.substr(currPos, endPos - currPos); // Skip over 'layout' currPos += 6; @@ -547,7 +547,7 @@ namespace Ogre // Erase up to it then split the remainder by spaces. line.erase (0, parenPos + 1); StringUtil::trim(line); - StringVector parts = StringUtil::split(line, " "); + StringVector parts = StringUtil::split(line, " "); if(parts.size() < 3) { diff --git a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramPipelineManager.cpp b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramPipelineManager.cpp index 58474521aa3..5b615c80623 100644 --- a/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramPipelineManager.cpp +++ b/RenderSystems/GLES2/src/GLSLES/src/OgreGLSLESProgramPipelineManager.cpp @@ -33,15 +33,15 @@ namespace Ogre { //----------------------------------------------------------------------- - template<> GLSLESProgramPipelineManager* Singleton::msSingleton = 0; + template<> GLSLESProgramPipelineManager* Singleton::msSingleton = 0; - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- GLSLESProgramPipelineManager* GLSLESProgramPipelineManager::getSingletonPtr(void) { return msSingleton; } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- GLSLESProgramPipelineManager& GLSLESProgramPipelineManager::getSingleton(void) { assert( msSingleton ); return ( *msSingleton ); @@ -52,79 +52,79 @@ namespace Ogre GLSLESProgramPipelineManager::~GLSLESProgramPipelineManager(void) { - // Iterate through map container and delete program pipelines - for (ProgramPipelineIterator currentProgram = mProgramPipelines.begin(); + // Iterate through map container and delete program pipelines + for (ProgramPipelineIterator currentProgram = mProgramPipelines.begin(); currentProgram != mProgramPipelines.end(); ++currentProgram) - { - delete currentProgram->second; - } + { + delete currentProgram->second; + } } //----------------------------------------------------------------------- - void GLSLESProgramPipelineManager::setActiveFragmentLinkProgram(GLSLESGpuProgram* fragmentGpuProgram) - { - if (fragmentGpuProgram != mActiveFragmentGpuProgram) - { - mActiveFragmentGpuProgram = fragmentGpuProgram; - // ActiveProgramPipeline is no longer valid - mActiveProgramPipeline = NULL; - } - } + void GLSLESProgramPipelineManager::setActiveFragmentLinkProgram(GLSLESGpuProgram* fragmentGpuProgram) + { + if (fragmentGpuProgram != mActiveFragmentGpuProgram) + { + mActiveFragmentGpuProgram = fragmentGpuProgram; + // ActiveProgramPipeline is no longer valid + mActiveProgramPipeline = NULL; + } + } - //----------------------------------------------------------------------- - void GLSLESProgramPipelineManager::setActiveVertexLinkProgram(GLSLESGpuProgram* vertexGpuProgram) - { - if (vertexGpuProgram != mActiveVertexGpuProgram) - { - mActiveVertexGpuProgram = vertexGpuProgram; - // ActiveProgramPipeline is no longer valid - mActiveProgramPipeline = NULL; - } - } + //----------------------------------------------------------------------- + void GLSLESProgramPipelineManager::setActiveVertexLinkProgram(GLSLESGpuProgram* vertexGpuProgram) + { + if (vertexGpuProgram != mActiveVertexGpuProgram) + { + mActiveVertexGpuProgram = vertexGpuProgram; + // ActiveProgramPipeline is no longer valid + mActiveProgramPipeline = NULL; + } + } //----------------------------------------------------------------------- - GLSLESProgramPipeline* GLSLESProgramPipelineManager::getActiveProgramPipeline(void) - { - // If there is an active link program then return it - if (mActiveProgramPipeline) - return mActiveProgramPipeline; + GLSLESProgramPipeline* GLSLESProgramPipelineManager::getActiveProgramPipeline(void) + { + // If there is an active link program then return it + if (mActiveProgramPipeline) + return mActiveProgramPipeline; - // No active link program so find one or make a new one - // Is there an active key? - uint64 activeKey = 0; + // No active link program so find one or make a new one + // Is there an active key? + uint64 activeKey = 0; - if (mActiveVertexGpuProgram) - { - activeKey = static_cast(mActiveVertexGpuProgram->getProgramID()) << 32; - } - if (mActiveFragmentGpuProgram) - { - activeKey += static_cast(mActiveFragmentGpuProgram->getProgramID()); - } + if (mActiveVertexGpuProgram) + { + activeKey = static_cast(mActiveVertexGpuProgram->getProgramID()) << 32; + } + if (mActiveFragmentGpuProgram) + { + activeKey += static_cast(mActiveFragmentGpuProgram->getProgramID()); + } - // Only return a program pipeline object if a vertex or fragment stage exist - if (activeKey > 0) - { - // Find the key in the hash map - ProgramPipelineIterator programFound = mProgramPipelines.find(activeKey); - // Program object not found for key so need to create it - if (programFound == mProgramPipelines.end()) - { - mActiveProgramPipeline = new GLSLESProgramPipeline(mActiveVertexGpuProgram, mActiveFragmentGpuProgram); - mProgramPipelines[activeKey] = mActiveProgramPipeline; - } - else - { - // Found a link program in map container so make it active - mActiveProgramPipeline = programFound->second; - } + // Only return a program pipeline object if a vertex or fragment stage exist + if (activeKey > 0) + { + // Find the key in the hash map + ProgramPipelineIterator programFound = mProgramPipelines.find(activeKey); + // Program object not found for key so need to create it + if (programFound == mProgramPipelines.end()) + { + mActiveProgramPipeline = new GLSLESProgramPipeline(mActiveVertexGpuProgram, mActiveFragmentGpuProgram); + mProgramPipelines[activeKey] = mActiveProgramPipeline; + } + else + { + // Found a link program in map container so make it active + mActiveProgramPipeline = programFound->second; + } - } - // Make the program object active - if (mActiveProgramPipeline) + } + // Make the program object active + if (mActiveProgramPipeline) mActiveProgramPipeline->activate(); - return mActiveProgramPipeline; - } + return mActiveProgramPipeline; + } } diff --git a/RenderSystems/GLES2/src/NaCl/OgreNaClGLContext.cpp b/RenderSystems/GLES2/src/NaCl/OgreNaClGLContext.cpp index 37f3b7e3321..8cfbda5f467 100644 --- a/RenderSystems/GLES2/src/NaCl/OgreNaClGLContext.cpp +++ b/RenderSystems/GLES2/src/NaCl/OgreNaClGLContext.cpp @@ -44,7 +44,7 @@ THE SOFTWARE. namespace Ogre { NaClGLContext::NaClGLContext(const NaClWindow * window, const NaClGLSupport *glsupport, pp::Instance* instance, pp::CompletionCallback* swapCallback) - : pp::Graphics3DClient(instance) + : pp::Graphics3DClient(instance) , mWindow(window) , mGLSupport(glsupport) , mInstance(instance) @@ -58,8 +58,8 @@ namespace Ogre { { glSetCurrentContextPPAPI(0); } - - void NaClGLContext::setCurrent() + + void NaClGLContext::setCurrent() { if (mInstance == NULL) { glSetCurrentContextPPAPI(0); diff --git a/RenderSystems/GLES2/src/NaCl/OgreNaClGLSupport.cpp b/RenderSystems/GLES2/src/NaCl/OgreNaClGLSupport.cpp index 3836b71fe00..2248cf3bf5a 100644 --- a/RenderSystems/GLES2/src/NaCl/OgreNaClGLSupport.cpp +++ b/RenderSystems/GLES2/src/NaCl/OgreNaClGLSupport.cpp @@ -63,26 +63,26 @@ namespace Ogre { NaClGLSupport::~NaClGLSupport() { - } + } String NaClGLSupport::getDisplayName(void) { - return "NaCl GLES2 Support"; - } + return "NaCl GLES2 Support"; + } void NaClGLSupport::switchMode(uint& width, uint& height, short& frequency) { - } - - RenderWindow* NaClGLSupport::createWindow(bool autoCreateWindow, - GLES2RenderSystem *renderSystem, - const String& windowTitle) - { - LogManager::getSingleton().logMessage("\tGLSupport createWindow called"); - - RenderWindow *window = 0; + } + + RenderWindow* NaClGLSupport::createWindow(bool autoCreateWindow, + GLES2RenderSystem *renderSystem, + const String& windowTitle) + { + LogManager::getSingleton().logMessage("\tGLSupport createWindow called"); + + RenderWindow *window = 0; if (autoCreateWindow) { @@ -91,7 +91,7 @@ namespace Ogre { NameValuePairList miscParams; bool fullscreen = true; - unsigned int w = 1, h = 1; + unsigned int w = 1, h = 1; if ((opt = mOptions.find("Display Frequency")) != end) { @@ -102,58 +102,58 @@ namespace Ogre { } return window; - } + } RenderWindow* NaClGLSupport::newWindow(const String &name, unsigned int width, unsigned int height, bool fullScreen, const NameValuePairList *miscParams) { - LogManager::getSingleton().logMessage("\tGLSupport newWindow called"); - - NaClWindow* window = new NaClWindow(this); + LogManager::getSingleton().logMessage("\tGLSupport newWindow called"); + + NaClWindow* window = new NaClWindow(this); window->create(name, width, height, fullScreen, miscParams); String targetName = window->getName(); return window; } - - void NaClGLSupport::start(void) - { - LogManager::getSingleton().logMessage("\tGLSupport start called"); - } - void NaClGLSupport::stop(void) - { - LogManager::getSingleton().logMessage("\tGLSupport stop called"); - } + void NaClGLSupport::start(void) + { + LogManager::getSingleton().logMessage("\tGLSupport start called"); + } + + void NaClGLSupport::stop(void) + { + LogManager::getSingleton().logMessage("\tGLSupport stop called"); + } + + void NaClGLSupport::addConfig(void) + { + LogManager::getSingleton().logMessage("\tGLSupport addConfig called"); + + // Currently no config options supported + refreshConfig(); + } - void NaClGLSupport::addConfig(void) - { - LogManager::getSingleton().logMessage("\tGLSupport addConfig called"); - - // Currently no config options supported - refreshConfig(); - } - - void NaClGLSupport::refreshConfig(void) - { - } + void NaClGLSupport::refreshConfig(void) + { + } - String NaClGLSupport::validateConfig(void) - { - return BLANKSTRING; - } + String NaClGLSupport::validateConfig(void) + { + return BLANKSTRING; + } - void NaClGLSupport::setConfigOption(const String &name, const String &value) - { - GLES2Support::setConfigOption(name, value); - } + void NaClGLSupport::setConfigOption(const String &name, const String &value) + { + GLES2Support::setConfigOption(name, value); + } - void* NaClGLSupport::getProcAddress(const Ogre::String& name) - { + void* NaClGLSupport::getProcAddress(const Ogre::String& name) + { //return (void*)pglGetProcAddress((const char*) name.c_str()); - doesn't link return 0; - } - + } + } diff --git a/RenderSystems/GLES2/src/NaCl/OgreNaClWindow.cpp b/RenderSystems/GLES2/src/NaCl/OgreNaClWindow.cpp index a079814cb02..e030929770b 100644 --- a/RenderSystems/GLES2/src/NaCl/OgreNaClWindow.cpp +++ b/RenderSystems/GLES2/src/NaCl/OgreNaClWindow.cpp @@ -44,53 +44,53 @@ THE SOFTWARE. #include namespace Ogre { - NaClWindow::NaClWindow(NaClGLSupport *glsupport) - : mGLSupport(glsupport), mClosed(false), mContext(0), mInstance(0), mSwapCallback(0) - { - } - - NaClWindow::~NaClWindow() - { - if(mContext) - delete mContext; - } - - void NaClWindow::getCustomAttribute( const String& name, void* pData ) - { - if(name == "pp::Instance") - { - *static_cast(pData) = mInstance; + NaClWindow::NaClWindow(NaClGLSupport *glsupport) + : mGLSupport(glsupport), mClosed(false), mContext(0), mInstance(0), mSwapCallback(0) + { + } + + NaClWindow::~NaClWindow() + { + if(mContext) + delete mContext; + } + + void NaClWindow::getCustomAttribute( const String& name, void* pData ) + { + if(name == "pp::Instance") + { + *static_cast(pData) = mInstance; return; - } + } else if(name == "GLCONTEXT") { *static_cast(pData) = mContext; return; } - } + } - void NaClWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) - { + void NaClWindow::getLeftAndTopFromNativeWindow( int & left, int & top, uint width, uint height ) + { // todo - } + } - void NaClWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) - { - LogManager::getSingleton().logMessage("\tinitNativeCreatedWindow called"); + void NaClWindow::initNativeCreatedWindow(const NameValuePairList *miscParams) + { + LogManager::getSingleton().logMessage("\tinitNativeCreatedWindow called"); - if (miscParams) - { - NameValuePairList::const_iterator opt; - NameValuePairList::const_iterator end = miscParams->end(); + if (miscParams) + { + NameValuePairList::const_iterator opt; + NameValuePairList::const_iterator end = miscParams->end(); mInstance = NULL; - opt = miscParams->find("pp::Instance"); - if(opt != end) - { + opt = miscParams->find("pp::Instance"); + if(opt != end) + { LogManager::getSingleton().logMessage("\tgetting pp::Instance - if stopped here - it means the parameter is null!"); - mInstance = (pp::Instance*)(Ogre::StringConverter::parseUnsignedLong(opt->second)); + mInstance = (pp::Instance*)(Ogre::StringConverter::parseUnsignedLong(opt->second)); LogManager::getSingleton().logMessage("\tgot the pp::Instance."); - } + } opt = miscParams->find("SwapCallback"); if(opt != end) { @@ -98,83 +98,83 @@ namespace Ogre { mSwapCallback = (pp::CompletionCallback*)(Ogre::StringConverter::parseUnsignedLong(opt->second)); LogManager::getSingleton().logMessage("\tgot the SwapCallback."); } - - if(mInstance != NULL) - { - mContext = new NaClGLContext(this, mGLSupport, mInstance, mSwapCallback); - } - else - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "pp::Instance parameter required for NaCl windows.", - "NaClWindow::initNativeCreatedWindow" ); - } - } + + if(mInstance != NULL) + { + mContext = new NaClGLContext(this, mGLSupport, mInstance, mSwapCallback); + } + else + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "pp::Instance parameter required for NaCl windows.", + "NaClWindow::initNativeCreatedWindow" ); + } + } LogManager::getSingleton().logMessage("\tinitNativeCreatedWindow ended"); - } + } - void NaClWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) - { - LogManager::getSingleton().logMessage("\tcreateNativeWindow called"); - } + void NaClWindow::createNativeWindow( int &left, int &top, uint &width, uint &height, String &title ) + { + LogManager::getSingleton().logMessage("\tcreateNativeWindow called"); + } - void NaClWindow::reposition( int left, int top ) - { - LogManager::getSingleton().logMessage("\treposition called"); - } + void NaClWindow::reposition( int left, int top ) + { + LogManager::getSingleton().logMessage("\treposition called"); + } - void NaClWindow::resize(uint width, uint height) - { - LogManager::getSingleton().logMessage("\tresize called"); + void NaClWindow::resize(uint width, uint height) + { + LogManager::getSingleton().logMessage("\tresize called"); mWidth = width; mHeight = height; mContext->resize(); - } - - void NaClWindow::windowMovedOrResized() - { - LogManager::getSingleton().logMessage("\twindowMovedOrResized called"); - } - - void NaClWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) - { - - } - - bool NaClWindow::requiresTextureFlipping() const - { - return false; - } - - void NaClWindow::destroy(void) - { - LogManager::getSingleton().logMessage("\tdestroy called"); - } - - bool NaClWindow::isClosed(void) const - { - return mClosed; - } + } + + void NaClWindow::windowMovedOrResized() + { + LogManager::getSingleton().logMessage("\twindowMovedOrResized called"); + } + + void NaClWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer) + { + + } + + bool NaClWindow::requiresTextureFlipping() const + { + return false; + } + + void NaClWindow::destroy(void) + { + LogManager::getSingleton().logMessage("\tdestroy called"); + } + + bool NaClWindow::isClosed(void) const + { + return mClosed; + } void NaClWindow::create(const String& name, uint width, uint height, bool fullScreen, const NameValuePairList *miscParams) { LogManager::getSingleton().logMessage("\tcreate called"); - - initNativeCreatedWindow(miscParams); - - mName = name; + + initNativeCreatedWindow(miscParams); + + mName = name; mWidth = width; mHeight = height; mLeft = 0; mTop = 0; mActive = true; - //mVisible = true; + //mVisible = true; mClosed = false; - } + } void NaClWindow::swapBuffers() { diff --git a/RenderSystems/GLES2/src/OgreGLES2DefaultHardwareBufferManager.cpp b/RenderSystems/GLES2/src/OgreGLES2DefaultHardwareBufferManager.cpp index 655c79b4eaf..e61c127c22e 100644 --- a/RenderSystems/GLES2/src/OgreGLES2DefaultHardwareBufferManager.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2DefaultHardwareBufferManager.cpp @@ -103,13 +103,13 @@ namespace Ogre { // always software, never shadowed { #if OGRE_NO_GLES3_SUPPORT == 1 - if (!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_32BIT_INDEX) && + if (!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_32BIT_INDEX) && idxType == HardwareIndexBuffer::IT_32BIT) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "32 bit hardware buffers are not allowed in OpenGL ES.", - "GLES2DefaultHardwareIndexBuffer"); - } + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "32 bit hardware buffers are not allowed in OpenGL ES.", + "GLES2DefaultHardwareIndexBuffer"); + } #endif mData = new unsigned char[mSizeInBytes]; } @@ -249,7 +249,7 @@ namespace Ogre { HardwareUniformBufferSharedPtr GLES2DefaultHardwareBufferManagerBase::createUniformBuffer(size_t sizeBytes, HardwareBuffer::Usage usage, bool useShadowBuffer, const String& name) - { + { if(!gleswIsSupported(3, 0)) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, @@ -258,10 +258,10 @@ namespace Ogre { } return HardwareUniformBufferSharedPtr(new GLES2DefaultHardwareUniformBuffer(this, sizeBytes, usage, useShadowBuffer, name)); - } + } - Ogre::RenderToVertexBufferSharedPtr GLES2DefaultHardwareBufferManagerBase::createRenderToVertexBuffer( void ) - { + Ogre::RenderToVertexBufferSharedPtr GLES2DefaultHardwareBufferManagerBase::createRenderToVertexBuffer( void ) + { if(!gleswIsSupported(3, 0)) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, @@ -269,5 +269,5 @@ namespace Ogre { "GLES2DefaultHardwareBufferManagerBase::createRenderToVertexBuffer"); } // return HardwareUniformBufferSharedPtr(new GLES2DefaultHardwareRenderToVertexBuffer(this, sizeBytes, usage, useShadowBuffer, name)); - } + } } diff --git a/RenderSystems/GLES2/src/OgreGLES2DepthBuffer.cpp b/RenderSystems/GLES2/src/OgreGLES2DepthBuffer.cpp index a52682660dd..ce89eed51a0 100644 --- a/RenderSystems/GLES2/src/OgreGLES2DepthBuffer.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2DepthBuffer.cpp @@ -32,96 +32,96 @@ THE SOFTWARE. namespace Ogre { - GLES2DepthBuffer::GLES2DepthBuffer( uint16 poolId, GLES2RenderSystem *renderSystem, GLES2Context *creatorContext, - GLES2RenderBuffer *depth, GLES2RenderBuffer *stencil, - uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, - bool manual ) : - DepthBuffer( poolId, 0, width, height, fsaa, "", manual ), - mMultiSampleQuality( multiSampleQuality ), - mCreatorContext( creatorContext ), - mDepthBuffer( depth ), - mStencilBuffer( stencil ), - mRenderSystem( renderSystem ) - { - if( mDepthBuffer ) - { - switch( mDepthBuffer->getGLFormat() ) - { - case GL_DEPTH_COMPONENT16: - mBitDepth = 16; - break; - case GL_DEPTH_COMPONENT24_OES: + GLES2DepthBuffer::GLES2DepthBuffer( uint16 poolId, GLES2RenderSystem *renderSystem, GLES2Context *creatorContext, + GLES2RenderBuffer *depth, GLES2RenderBuffer *stencil, + uint32 width, uint32 height, uint32 fsaa, uint32 multiSampleQuality, + bool manual ) : + DepthBuffer( poolId, 0, width, height, fsaa, "", manual ), + mMultiSampleQuality( multiSampleQuality ), + mCreatorContext( creatorContext ), + mDepthBuffer( depth ), + mStencilBuffer( stencil ), + mRenderSystem( renderSystem ) + { + if( mDepthBuffer ) + { + switch( mDepthBuffer->getGLFormat() ) + { + case GL_DEPTH_COMPONENT16: + mBitDepth = 16; + break; + case GL_DEPTH_COMPONENT24_OES: case GL_DEPTH_COMPONENT32_OES: case GL_DEPTH24_STENCIL8_OES: // Packed depth / stencil - mBitDepth = 32; - break; - } - } - } - - GLES2DepthBuffer::~GLES2DepthBuffer() - { - if( mStencilBuffer && mStencilBuffer != mDepthBuffer ) - { - delete mStencilBuffer; - mStencilBuffer = 0; - } - - if( mDepthBuffer ) - { - delete mDepthBuffer; - mDepthBuffer = 0; - } - } - //--------------------------------------------------------------------- - bool GLES2DepthBuffer::isCompatible( RenderTarget *renderTarget ) const - { - bool retVal = false; - - //Check standard stuff first. - if( mRenderSystem->getCapabilities()->hasCapability( RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL ) ) - { - if( !DepthBuffer::isCompatible( renderTarget ) ) - return false; - } - else - { - if( this->getWidth() != renderTarget->getWidth() || - this->getHeight() != renderTarget->getHeight() || - this->getFsaa() != renderTarget->getFSAA() ) - return false; - } - - //Now check this is the appropriate format - GLES2FrameBufferObject *fbo = 0; + mBitDepth = 32; + break; + } + } + } + + GLES2DepthBuffer::~GLES2DepthBuffer() + { + if( mStencilBuffer && mStencilBuffer != mDepthBuffer ) + { + delete mStencilBuffer; + mStencilBuffer = 0; + } + + if( mDepthBuffer ) + { + delete mDepthBuffer; + mDepthBuffer = 0; + } + } + //--------------------------------------------------------------------- + bool GLES2DepthBuffer::isCompatible( RenderTarget *renderTarget ) const + { + bool retVal = false; + + //Check standard stuff first. + if( mRenderSystem->getCapabilities()->hasCapability( RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL ) ) + { + if( !DepthBuffer::isCompatible( renderTarget ) ) + return false; + } + else + { + if( this->getWidth() != renderTarget->getWidth() || + this->getHeight() != renderTarget->getHeight() || + this->getFsaa() != renderTarget->getFSAA() ) + return false; + } + + //Now check this is the appropriate format + GLES2FrameBufferObject *fbo = 0; renderTarget->getCustomAttribute("FBO", &fbo); - if( !fbo ) - { - GLES2Context *windowContext = 0; - renderTarget->getCustomAttribute( "GLCONTEXT", &windowContext ); - - //Non-FBO targets and FBO depth surfaces don't play along, only dummies which match the same - //context - if( !mDepthBuffer && !mStencilBuffer && mCreatorContext == windowContext ) - retVal = true; - } - else - { - //Check this isn't a dummy non-FBO depth buffer with an FBO target, don't mix them. - //If you don't want depth buffer, use a Null Depth Buffer, not a dummy one. - if( mDepthBuffer || mStencilBuffer ) - { - GLenum internalFormat = fbo->getFormat(); - GLenum depthFormat, stencilFormat; - mRenderSystem->_getDepthStencilFormatFor( internalFormat, &depthFormat, &stencilFormat ); - - bool bSameDepth = false; - - if( mDepthBuffer ) - bSameDepth |= mDepthBuffer->getGLFormat() == depthFormat; - - bool bSameStencil = false; + if( !fbo ) + { + GLES2Context *windowContext = 0; + renderTarget->getCustomAttribute( "GLCONTEXT", &windowContext ); + + //Non-FBO targets and FBO depth surfaces don't play along, only dummies which match the same + //context + if( !mDepthBuffer && !mStencilBuffer && mCreatorContext == windowContext ) + retVal = true; + } + else + { + //Check this isn't a dummy non-FBO depth buffer with an FBO target, don't mix them. + //If you don't want depth buffer, use a Null Depth Buffer, not a dummy one. + if( mDepthBuffer || mStencilBuffer ) + { + GLenum internalFormat = fbo->getFormat(); + GLenum depthFormat, stencilFormat; + mRenderSystem->_getDepthStencilFormatFor( internalFormat, &depthFormat, &stencilFormat ); + + bool bSameDepth = false; + + if( mDepthBuffer ) + bSameDepth |= mDepthBuffer->getGLFormat() == depthFormat; + + bool bSameStencil = false; if( !mStencilBuffer || mStencilBuffer == mDepthBuffer ) bSameStencil = stencilFormat == GL_NONE; @@ -131,10 +131,10 @@ namespace Ogre bSameStencil = stencilFormat == mStencilBuffer->getGLFormat(); } - retVal = bSameDepth && bSameStencil; - } - } + retVal = bSameDepth && bSameStencil; + } + } - return retVal; - } + return retVal; + } } diff --git a/RenderSystems/GLES2/src/OgreGLES2FBOMultiRenderTarget.cpp b/RenderSystems/GLES2/src/OgreGLES2FBOMultiRenderTarget.cpp index 6923b78caba..babf0c40c27 100644 --- a/RenderSystems/GLES2/src/OgreGLES2FBOMultiRenderTarget.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2FBOMultiRenderTarget.cpp @@ -31,63 +31,63 @@ THE SOFTWARE. namespace Ogre { - GLES2FBOMultiRenderTarget::GLES2FBOMultiRenderTarget(GLES2FBOManager *manager, const String &name): - MultiRenderTarget(name), - fbo(manager, 0 /* TODO: multisampling on MRTs? */) - { - } - GLES2FBOMultiRenderTarget::~GLES2FBOMultiRenderTarget() - { - } + GLES2FBOMultiRenderTarget::GLES2FBOMultiRenderTarget(GLES2FBOManager *manager, const String &name): + MultiRenderTarget(name), + fbo(manager, 0 /* TODO: multisampling on MRTs? */) + { + } + GLES2FBOMultiRenderTarget::~GLES2FBOMultiRenderTarget() + { + } - void GLES2FBOMultiRenderTarget::bindSurfaceImpl(size_t attachment, RenderTexture *target) - { - /// Check if the render target is in the rendertarget->FBO map + void GLES2FBOMultiRenderTarget::bindSurfaceImpl(size_t attachment, RenderTexture *target) + { + /// Check if the render target is in the rendertarget->FBO map GLES2FrameBufferObject *fbobj = 0; target->getCustomAttribute("FBO", &fbobj); - assert(fbobj); - fbo.bindSurface(attachment, fbobj->getSurface(0)); + assert(fbobj); + fbo.bindSurface(attachment, fbobj->getSurface(0)); - // Set width and height - mWidth = fbo.getWidth(); - mHeight = fbo.getHeight(); - } + // Set width and height + mWidth = fbo.getWidth(); + mHeight = fbo.getHeight(); + } - void GLES2FBOMultiRenderTarget::unbindSurfaceImpl(size_t attachment) - { - fbo.unbindSurface(attachment); + void GLES2FBOMultiRenderTarget::unbindSurfaceImpl(size_t attachment) + { + fbo.unbindSurface(attachment); - // Set width and height - mWidth = fbo.getWidth(); - mHeight = fbo.getHeight(); - } + // Set width and height + mWidth = fbo.getWidth(); + mHeight = fbo.getHeight(); + } - void GLES2FBOMultiRenderTarget::getCustomAttribute( const String& name, void *pData ) - { - if(name=="FBO") + void GLES2FBOMultiRenderTarget::getCustomAttribute( const String& name, void *pData ) + { + if(name=="FBO") { *static_cast(pData) = &fbo; } - } - //----------------------------------------------------------------------------- - bool GLES2FBOMultiRenderTarget::attachDepthBuffer( DepthBuffer *depthBuffer ) - { - bool result; - if( (result = MultiRenderTarget::attachDepthBuffer( depthBuffer )) ) - fbo.attachDepthBuffer( depthBuffer ); + } + //----------------------------------------------------------------------------- + bool GLES2FBOMultiRenderTarget::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + bool result; + if( (result = MultiRenderTarget::attachDepthBuffer( depthBuffer )) ) + fbo.attachDepthBuffer( depthBuffer ); - return result; - } - //----------------------------------------------------------------------------- - void GLES2FBOMultiRenderTarget::detachDepthBuffer() - { - fbo.detachDepthBuffer(); - MultiRenderTarget::detachDepthBuffer(); - } - //----------------------------------------------------------------------------- - void GLES2FBOMultiRenderTarget::_detachDepthBuffer() - { - fbo.detachDepthBuffer(); - MultiRenderTarget::_detachDepthBuffer(); - } + return result; + } + //----------------------------------------------------------------------------- + void GLES2FBOMultiRenderTarget::detachDepthBuffer() + { + fbo.detachDepthBuffer(); + MultiRenderTarget::detachDepthBuffer(); + } + //----------------------------------------------------------------------------- + void GLES2FBOMultiRenderTarget::_detachDepthBuffer() + { + fbo.detachDepthBuffer(); + MultiRenderTarget::_detachDepthBuffer(); + } } diff --git a/RenderSystems/GLES2/src/OgreGLES2FBORenderTexture.cpp b/RenderSystems/GLES2/src/OgreGLES2FBORenderTexture.cpp index d99f99304a3..04987f7fb10 100644 --- a/RenderSystems/GLES2/src/OgreGLES2FBORenderTexture.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2FBORenderTexture.cpp @@ -59,10 +59,10 @@ namespace Ogre { } } - void GLES2FBORenderTexture::swapBuffers() - { - mFB.swapBuffers(); - } + void GLES2FBORenderTexture::swapBuffers() + { + mFB.swapBuffers(); + } #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID void GLES2FBORenderTexture::notifyOnContextLost() @@ -82,27 +82,27 @@ namespace Ogre { } #endif - //----------------------------------------------------------------------------- - bool GLES2FBORenderTexture::attachDepthBuffer( DepthBuffer *depthBuffer ) - { - bool result; - if( (result = GLES2RenderTexture::attachDepthBuffer( depthBuffer )) ) - mFB.attachDepthBuffer( depthBuffer ); - - return result; - } - //----------------------------------------------------------------------------- - void GLES2FBORenderTexture::detachDepthBuffer() - { - mFB.detachDepthBuffer(); - GLES2RenderTexture::detachDepthBuffer(); - } - //----------------------------------------------------------------------------- - void GLES2FBORenderTexture::_detachDepthBuffer() - { - mFB.detachDepthBuffer(); - GLES2RenderTexture::_detachDepthBuffer(); - } + //----------------------------------------------------------------------------- + bool GLES2FBORenderTexture::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + bool result; + if( (result = GLES2RenderTexture::attachDepthBuffer( depthBuffer )) ) + mFB.attachDepthBuffer( depthBuffer ); + + return result; + } + //----------------------------------------------------------------------------- + void GLES2FBORenderTexture::detachDepthBuffer() + { + mFB.detachDepthBuffer(); + GLES2RenderTexture::detachDepthBuffer(); + } + //----------------------------------------------------------------------------- + void GLES2FBORenderTexture::_detachDepthBuffer() + { + mFB.detachDepthBuffer(); + GLES2RenderTexture::_detachDepthBuffer(); + } // Size of probe texture #define PROBE_SIZE 16 @@ -152,22 +152,22 @@ namespace Ogre { }; #define DEPTHFORMAT_COUNT (sizeof(depthFormats)/sizeof(GLenum)) - GLES2FBOManager::GLES2FBOManager() + GLES2FBOManager::GLES2FBOManager() { detectFBOFormats(); OGRE_CHECK_GL_ERROR(glGenFramebuffers(1, &mTempFBO)); } - GLES2FBOManager::~GLES2FBOManager() - { - if(!mRenderBufferMap.empty()) - { - LogManager::getSingleton().logMessage("GL ES 2: Warning! GLES2FBOManager destructor called, but not all renderbuffers were released."); - } + GLES2FBOManager::~GLES2FBOManager() + { + if(!mRenderBufferMap.empty()) + { + LogManager::getSingleton().logMessage("GL ES 2: Warning! GLES2FBOManager destructor called, but not all renderbuffers were released."); + } OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &mTempFBO)); - } + } void GLES2FBOManager::_reload() { @@ -309,8 +309,8 @@ namespace Ogre { { mProps[x].valid = false; - // Fetch GL format token - GLint internalFormat = GLES2PixelUtil::getGLInternalFormat((PixelFormat)x); + // Fetch GL format token + GLint internalFormat = GLES2PixelUtil::getGLInternalFormat((PixelFormat)x); GLenum fmt = GLES2PixelUtil::getGLOriginFormat((PixelFormat)x); GLenum type = GLES2PixelUtil::getGLOriginDataType((PixelFormat)x); @@ -321,22 +321,22 @@ namespace Ogre { if((internalFormat == GL_NONE || fmt == GL_NONE || type == GL_NONE) && (x != 0)) continue; #endif - // No test for compressed formats + // No test for compressed formats if(PixelUtil::isCompressed((PixelFormat)x)) continue; // Create and attach framebuffer _createTempFramebuffer((PixelFormat)x, internalFormat, fmt, type, fb, tid); - // Ignore status in case of fmt==GL_NONE, because no implementation will accept - // a buffer without *any* attachment. Buffers with only stencil and depth attachment - // might still be supported, so we must continue probing. + // Ignore status in case of fmt==GL_NONE, because no implementation will accept + // a buffer without *any* attachment. Buffers with only stencil and depth attachment + // might still be supported, so we must continue probing. if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { mProps[x].valid = true; - StringStream str; - str << "FBO " << PixelUtil::getFormatName((PixelFormat)x) - << " depth/stencil support: "; + StringStream str; + str << "FBO " << PixelUtil::getFormatName((PixelFormat)x) + << " depth/stencil support: "; // For each depth/stencil formats for (size_t depth = 0; depth < DEPTHFORMAT_COUNT; ++depth) @@ -354,8 +354,8 @@ namespace Ogre { { // StringStream l; // l << "Trying " << PixelUtil::getFormatName((PixelFormat)x) -// << " D" << depthBits[depth] -// << "S" << stencilBits[stencil]; +// << " D" << depthBits[depth] +// << "S" << stencilBits[stencil]; // LogManager::getSingleton().logMessage(l.str()); if (_tryFormat(depthFormats[depth], stencilFormats[stencil])) @@ -407,7 +407,7 @@ namespace Ogre { // Delete texture and framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &fb); - + if (internalFormat != GL_NONE) { glDeleteTextures(1, &tid); @@ -418,7 +418,7 @@ namespace Ogre { // Clear any errors glGetError(); - String fmtstring; + String fmtstring; for(size_t x = 0; x < PF_COUNT; ++x) { if(mProps[x].valid) @@ -454,8 +454,8 @@ namespace Ogre { if(depthFormats[props.modes[mode].depth] == GL_DEPTH24_STENCIL8_OES) // Prefer 24/8 packed desirability += 5000; #if OGRE_NO_GLES3_SUPPORT == 0 - if(depthFormats[props.modes[mode].depth] == GL_DEPTH32F_STENCIL8) // Prefer 32F/8 packed - desirability += 5000; + if(depthFormats[props.modes[mode].depth] == GL_DEPTH32F_STENCIL8) // Prefer 32F/8 packed + desirability += 5000; #endif desirability += stencilBits[props.modes[mode].stencil] + depthBits[props.modes[mode].depth]; @@ -473,15 +473,15 @@ namespace Ogre { } GLES2FBORenderTexture *GLES2FBOManager::createRenderTexture(const String &name, - const GLES2SurfaceDesc &target, bool writeGamma, uint fsaa) + const GLES2SurfaceDesc &target, bool writeGamma, uint fsaa) { GLES2FBORenderTexture *retval = new GLES2FBORenderTexture(this, name, target, writeGamma, fsaa); return retval; } - MultiRenderTarget *GLES2FBOManager::createMultiRenderTarget(const String & name) - { - return new GLES2FBOMultiRenderTarget(this, name); - } + MultiRenderTarget *GLES2FBOManager::createMultiRenderTarget(const String & name) + { + return new GLES2FBOMultiRenderTarget(this, name); + } void GLES2FBOManager::bind(RenderTarget *target) { @@ -512,7 +512,7 @@ namespace Ogre { { retval.buffer = it->second.buffer; retval.zoffset = 0; - retval.numSamples = fsaa; + retval.numSamples = fsaa; // Increase refcount ++it->second.refcount; } @@ -523,7 +523,7 @@ namespace Ogre { mRenderBufferMap[key] = RBRef(rb); retval.buffer = rb; retval.zoffset = 0; - retval.numSamples = fsaa; + retval.numSamples = fsaa; } } // std::cerr << "Requested renderbuffer with format " << std::hex << format << std::dec << " of " << width << "x" << height << " :" << retval.buffer << std::endl; @@ -552,17 +552,17 @@ namespace Ogre { RBFormat key(surface.buffer->getGLFormat(), surface.buffer->getWidth(), surface.buffer->getHeight(), surface.numSamples); RenderBufferMap::iterator it = mRenderBufferMap.find(key); if(it != mRenderBufferMap.end()) - { - // Decrease refcount - --it->second.refcount; - if(it->second.refcount==0) - { - // If refcount reaches zero, delete buffer and remove from map - OGRE_DELETE it->second.buffer; - mRenderBufferMap.erase(it); - //std::cerr << "Destroyed renderbuffer of format " << std::hex << key.format << std::dec - // << " of " << key.width << "x" << key.height << std::endl; - } - } + { + // Decrease refcount + --it->second.refcount; + if(it->second.refcount==0) + { + // If refcount reaches zero, delete buffer and remove from map + OGRE_DELETE it->second.buffer; + mRenderBufferMap.erase(it); + //std::cerr << "Destroyed renderbuffer of format " << std::hex << key.format << std::dec + // << " of " << key.width << "x" << key.height << std::endl; + } + } } } diff --git a/RenderSystems/GLES2/src/OgreGLES2FrameBufferObject.cpp b/RenderSystems/GLES2/src/OgreGLES2FrameBufferObject.cpp index 926f1248354..8d2b763ef3d 100644 --- a/RenderSystems/GLES2/src/OgreGLES2FrameBufferObject.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2FrameBufferObject.cpp @@ -63,20 +63,20 @@ namespace Ogre { mNumSamples = std::min(mNumSamples, (GLsizei)maxSamples); } - // Will we need a second FBO to do multisampling? - if (mNumSamples) - { - OGRE_CHECK_GL_ERROR(glGenFramebuffers(1, &mMultisampleFB)); + // Will we need a second FBO to do multisampling? + if (mNumSamples) + { + OGRE_CHECK_GL_ERROR(glGenFramebuffers(1, &mMultisampleFB)); if(getGLES2SupportRef()->checkExtension("GL_EXT_debug_label")) { OGRE_IF_IOS_VERSION_IS_GREATER_THAN(5.0) OGRE_CHECK_GL_ERROR(glLabelObjectEXT(GL_BUFFER_OBJECT_EXT, mMultisampleFB, 0, ("MSAA FBO #" + StringConverter::toString(mMultisampleFB)).c_str())); } - } - else - { - mMultisampleFB = 0; - } + } + else + { + mMultisampleFB = 0; + } // Initialise state mDepth.buffer = 0; @@ -91,12 +91,12 @@ namespace Ogre { { mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); - mManager->releaseRenderBuffer(mMultisampleColourBuffer); + mManager->releaseRenderBuffer(mMultisampleColourBuffer); // Delete framebuffer object OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &mFB)); - if (mMultisampleFB) - OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &mMultisampleFB)); + if (mMultisampleFB) + OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &mMultisampleFB)); } #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID @@ -104,12 +104,12 @@ namespace Ogre { { mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); - mManager->releaseRenderBuffer(mMultisampleColourBuffer); + mManager->releaseRenderBuffer(mMultisampleColourBuffer); OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &mFB)); - if (mMultisampleFB) - OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &mMultisampleFB)); + if (mMultisampleFB) + OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &mMultisampleFB)); } void GLES2FrameBufferObject::notifyOnContextReset(const GLES2SurfaceDesc &target) @@ -128,26 +128,26 @@ namespace Ogre { { assert(attachment < OGRE_MAX_MULTIPLE_RENDER_TARGETS); mColour[attachment] = target; - // Re-initialise - if(mColour[0].buffer) - initialise(); + // Re-initialise + if(mColour[0].buffer) + initialise(); } void GLES2FrameBufferObject::unbindSurface(size_t attachment) { assert(attachment < OGRE_MAX_MULTIPLE_RENDER_TARGETS); mColour[attachment].buffer = 0; - // Re-initialise if buffer 0 still bound - if(mColour[0].buffer) - initialise(); + // Re-initialise if buffer 0 still bound + if(mColour[0].buffer) + initialise(); } void GLES2FrameBufferObject::initialise() { - // Release depth and stencil, if they were bound + // Release depth and stencil, if they were bound mManager->releaseRenderBuffer(mDepth); mManager->releaseRenderBuffer(mStencil); - mManager->releaseRenderBuffer(mMultisampleColourBuffer); + mManager->releaseRenderBuffer(mMultisampleColourBuffer); // First buffer must be bound if(!mColour[0].buffer) { @@ -156,10 +156,10 @@ namespace Ogre { "GLES2FrameBufferObject::initialise"); } - // If we're doing multisampling, then we need another FBO which contains a - // renderbuffer which is set up to multisample, and we'll blit it to the final - // FBO afterwards to perform the multisample resolve. In that case, the - // mMultisampleFB is bound during rendering and is the one with a depth/stencil + // If we're doing multisampling, then we need another FBO which contains a + // renderbuffer which is set up to multisample, and we'll blit it to the final + // FBO afterwards to perform the multisample resolve. In that case, the + // mMultisampleFB is bound during rendering and is the one with a depth/stencil // Store basic stats uint32 width = mColour[0].buffer->getWidth(); @@ -167,8 +167,8 @@ namespace Ogre { GLuint format = mColour[0].buffer->getGLFormat(); ushort maxSupportedMRTs = Root::getSingleton().getRenderSystem()->getCapabilities()->getNumMultiRenderTargets(); - // Bind simple buffer to add colour attachments - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mFB)); + // Bind simple buffer to add colour attachments + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mFB)); // Bind all attachment points to frame buffer for(unsigned int x = 0; x < maxSupportedMRTs; ++x) @@ -203,63 +203,63 @@ namespace Ogre { } } - // Now deal with depth / stencil - if (mMultisampleFB) - { - // Bind multisample buffer - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB)); + // Now deal with depth / stencil + if (mMultisampleFB) + { + // Bind multisample buffer + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB)); - // Create AA render buffer (colour) - // note, this can be shared too because we blit it to the final FBO - // right after the render is finished - mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); + // Create AA render buffer (colour) + // note, this can be shared too because we blit it to the final FBO + // right after the render is finished + mMultisampleColourBuffer = mManager->requestRenderBuffer(format, width, height, mNumSamples); - // Attach it, because we won't be attaching below and non-multisample has - // actually been attached to other FBO - mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0, - mMultisampleColourBuffer.zoffset); + // Attach it, because we won't be attaching below and non-multisample has + // actually been attached to other FBO + mMultisampleColourBuffer.buffer->bindToFramebuffer(GL_COLOR_ATTACHMENT0, + mMultisampleColourBuffer.zoffset); - // depth & stencil will be dealt with below - } + // depth & stencil will be dealt with below + } // Depth buffer is not handled here anymore. - // See GLES2FrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() + // See GLES2FrameBufferObject::attachDepthBuffer() & RenderSystem::setDepthBufferFor() GLenum bufs[OGRE_MAX_MULTIPLE_RENDER_TARGETS]; - GLsizei n=0; - for(unsigned int x=0; xgetWidth(); - uint32 height = mColour[0].buffer->getHeight(); - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mMultisampleFB)); - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFB)); - OGRE_CHECK_GL_ERROR(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST)); - // Unbind - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, oldfb)); + // Blit from multisample buffer to final buffer, triggers resolve + uint32 width = mColour[0].buffer->getWidth(); + uint32 height = mColour[0].buffer->getHeight(); + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mMultisampleFB)); + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFB)); + OGRE_CHECK_GL_ERROR(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST)); + // Unbind + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, oldfb)); #endif - } - } - - void GLES2FrameBufferObject::attachDepthBuffer( DepthBuffer *depthBuffer ) - { - GLES2DepthBuffer *glDepthBuffer = static_cast(depthBuffer); - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB ? mMultisampleFB : mFB )); - - if( glDepthBuffer ) - { - GLES2RenderBuffer *depthBuf = glDepthBuffer->getDepthBuffer(); - GLES2RenderBuffer *stencilBuf = glDepthBuffer->getStencilBuffer(); - - //Attach depth buffer, if it has one. - if( depthBuf ) - depthBuf->bindToFramebuffer( GL_DEPTH_ATTACHMENT, 0 ); - - //Attach stencil buffer, if it has one. - if( stencilBuf ) - stencilBuf->bindToFramebuffer( GL_STENCIL_ATTACHMENT, 0 ); - } - else - { - OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, + } + } + + void GLES2FrameBufferObject::attachDepthBuffer( DepthBuffer *depthBuffer ) + { + GLES2DepthBuffer *glDepthBuffer = static_cast(depthBuffer); + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB ? mMultisampleFB : mFB )); + + if( glDepthBuffer ) + { + GLES2RenderBuffer *depthBuf = glDepthBuffer->getDepthBuffer(); + GLES2RenderBuffer *stencilBuf = glDepthBuffer->getStencilBuffer(); + + //Attach depth buffer, if it has one. + if( depthBuf ) + depthBuf->bindToFramebuffer( GL_DEPTH_ATTACHMENT, 0 ); + + //Attach stencil buffer, if it has one. + if( stencilBuf ) + stencilBuf->bindToFramebuffer( GL_STENCIL_ATTACHMENT, 0 ); + } + else + { + OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0)); - OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0)); - } - } - //----------------------------------------------------------------------------- - void GLES2FrameBufferObject::detachDepthBuffer() - { - OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB ? mMultisampleFB : mFB )); - OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0 )); - OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + } + } + //----------------------------------------------------------------------------- + void GLES2FrameBufferObject::detachDepthBuffer() + { + OGRE_CHECK_GL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mMultisampleFB ? mMultisampleFB : mFB )); + OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0 )); + OGRE_CHECK_GL_ERROR(glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0 )); - } + } uint32 GLES2FrameBufferObject::getWidth() { @@ -367,7 +367,7 @@ namespace Ogre { assert(mColour[0].buffer); return mColour[0].buffer->getFormat(); } - GLsizei GLES2FrameBufferObject::getFSAA() + GLsizei GLES2FrameBufferObject::getFSAA() { return mNumSamples; } diff --git a/RenderSystems/GLES2/src/OgreGLES2GpuProgram.cpp b/RenderSystems/GLES2/src/OgreGLES2GpuProgram.cpp index b54729a7daa..8f0ddcab1a0 100644 --- a/RenderSystems/GLES2/src/OgreGLES2GpuProgram.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2GpuProgram.cpp @@ -35,14 +35,14 @@ GLenum getGLShaderType(GpuProgramType programType); GLenum getGLShaderType(GpuProgramType programType) { - switch (programType) - { - case GPT_VERTEX_PROGRAM: - default: - return GL_VERTEX_SHADER; - case GPT_FRAGMENT_PROGRAM: - return GL_FRAGMENT_SHADER; - } + switch (programType) + { + case GPT_VERTEX_PROGRAM: + default: + return GL_VERTEX_SHADER; + case GPT_FRAGMENT_PROGRAM: + return GL_FRAGMENT_SHADER; + } } GLES2GpuProgram::GLES2GpuProgram(ResourceManager* creator, const String& name, @@ -77,4 +77,4 @@ size_t GLES2GpuProgram::calculateSize(void) const } - \ No newline at end of file + \ No newline at end of file diff --git a/RenderSystems/GLES2/src/OgreGLES2HardwareBufferManager.cpp b/RenderSystems/GLES2/src/OgreGLES2HardwareBufferManager.cpp index 622fd0d69bb..8acceccca39 100644 --- a/RenderSystems/GLES2/src/OgreGLES2HardwareBufferManager.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2HardwareBufferManager.cpp @@ -41,7 +41,7 @@ namespace Ogre { //----------------------------------------------------------------------- GLES2HardwareBufferManagerBase::GLES2HardwareBufferManagerBase() { - mStateCacheManager = dynamic_cast(Root::getSingleton().getRenderSystem())->getGLES2Support()->getStateCacheManager(); + mStateCacheManager = dynamic_cast(Root::getSingleton().getRenderSystem())->getGLES2Support()->getStateCacheManager(); } GLES2HardwareBufferManagerBase::~GLES2HardwareBufferManagerBase() @@ -90,26 +90,26 @@ namespace Ogre { return HardwareIndexBufferSharedPtr(buf); } - RenderToVertexBufferSharedPtr GLES2HardwareBufferManagerBase::createRenderToVertexBuffer() - { + RenderToVertexBufferSharedPtr GLES2HardwareBufferManagerBase::createRenderToVertexBuffer() + { #if OGRE_NO_GLES3_SUPPORT == 0 - return RenderToVertexBufferSharedPtr(new GLES2RenderToVertexBuffer()); + return RenderToVertexBufferSharedPtr(new GLES2RenderToVertexBuffer()); #else - // not supported - return RenderToVertexBufferSharedPtr(); + // not supported + return RenderToVertexBufferSharedPtr(); #endif - } + } - VertexDeclaration* GLES2HardwareBufferManagerBase::createVertexDeclarationImpl(void) - { - return OGRE_NEW GLES2VertexDeclaration(); - } + VertexDeclaration* GLES2HardwareBufferManagerBase::createVertexDeclarationImpl(void) + { + return OGRE_NEW GLES2VertexDeclaration(); + } void GLES2HardwareBufferManagerBase::destroyVertexDeclarationImpl(VertexDeclaration* decl) - { + { if(decl) OGRE_DELETE decl; - } + } GLenum GLES2HardwareBufferManagerBase::getGLUsage(unsigned int usage) { diff --git a/RenderSystems/GLES2/src/OgreGLES2HardwareIndexBuffer.cpp b/RenderSystems/GLES2/src/OgreGLES2HardwareIndexBuffer.cpp index 8fb0ededdcb..7f02d25cf6d 100644 --- a/RenderSystems/GLES2/src/OgreGLES2HardwareIndexBuffer.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2HardwareIndexBuffer.cpp @@ -35,20 +35,20 @@ THE SOFTWARE. namespace Ogre { GLES2HardwareIndexBuffer::GLES2HardwareIndexBuffer(HardwareBufferManagerBase* mgr, - IndexType idxType, + IndexType idxType, size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer) : HardwareIndexBuffer(mgr, idxType, numIndexes, usage, false, useShadowBuffer) { #if OGRE_NO_GLES3_SUPPORT == 1 - if (!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_32BIT_INDEX) && + if (!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_32BIT_INDEX) && idxType == HardwareIndexBuffer::IT_32BIT) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "32 bit hardware buffers are not allowed in OpenGL ES.", - "GLES2HardwareIndexBuffer"); - } + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "32 bit hardware buffers are not allowed in OpenGL ES.", + "GLES2HardwareIndexBuffer"); + } #endif createBuffer(); } @@ -75,7 +75,7 @@ namespace Ogre { "GLES2HardwareIndexBuffer::GLES2HardwareIndexBuffer"); } - static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId); + static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId); OGRE_CHECK_GL_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)mSizeInBytes, NULL, GLES2HardwareBufferManager::getGLUsage(mUsage))); @@ -83,7 +83,7 @@ namespace Ogre { void GLES2HardwareIndexBuffer::destroyBuffer() { - // Delete the cached value + // Delete the cached value static_cast(mMgr)->getStateCacheManager()->deleteGLBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId); } @@ -177,7 +177,7 @@ namespace Ogre { // return offsetted void *retPtr = static_cast( static_cast(pBuffer) + offset); - mIsLocked = true; + mIsLocked = true; return retPtr; } @@ -224,7 +224,7 @@ namespace Ogre { const void* pSource, bool discardWholeBuffer) { - static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId); + static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId); // Update the shadow buffer if (mUseShadowBuffer) @@ -260,7 +260,7 @@ namespace Ogre { // If the buffer is not in system memory we can use ARB_copy_buffers to do an optimised copy. if (srcBuffer.isSystemMemory()) { - HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer); + HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer); } else { @@ -290,7 +290,7 @@ namespace Ogre { { const void *srcData = mShadowBuffer->lock(mLockStart, mLockSize, HBL_READ_ONLY); - static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId); + static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId); OGRE_CHECK_GL_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)mSizeInBytes, srcData, GLES2HardwareBufferManager::getGLUsage(mUsage))); diff --git a/RenderSystems/GLES2/src/OgreGLES2HardwareOcclusionQuery.cpp b/RenderSystems/GLES2/src/OgreGLES2HardwareOcclusionQuery.cpp index d84bf6c4298..0d9e385b786 100644 --- a/RenderSystems/GLES2/src/OgreGLES2HardwareOcclusionQuery.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2HardwareOcclusionQuery.cpp @@ -55,7 +55,7 @@ GLES2HardwareOcclusionQuery::~GLES2HardwareOcclusionQuery() //------------------------------------------------------------------ void GLES2HardwareOcclusionQuery::createQuery() { - // Check for hardware occlusion support + // Check for hardware occlusion support if(getGLES2SupportRef()->checkExtension("GL_EXT_occlusion_query_boolean") || gleswIsSupported(3, 0)) { @@ -127,7 +127,7 @@ bool GLES2HardwareOcclusionQuery::isStillOutstanding(void) OGRE_CHECK_GL_ERROR(glGetQueryObjectuivEXT(mQueryID, GL_QUERY_RESULT_AVAILABLE_EXT, &available)); } - // GL_TRUE means a wait would occur + // GL_TRUE means a wait would occur return !(available == GL_TRUE); } diff --git a/RenderSystems/GLES2/src/OgreGLES2HardwarePixelBuffer.cpp b/RenderSystems/GLES2/src/OgreGLES2HardwarePixelBuffer.cpp index 40bbcf22407..b1876b9cd39 100644 --- a/RenderSystems/GLES2/src/OgreGLES2HardwarePixelBuffer.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2HardwarePixelBuffer.cpp @@ -452,7 +452,7 @@ namespace Ogre { GLES2PixelUtil::getGLOriginFormat(data.format), GLES2PixelUtil::getGLOriginDataType(data.format), NULL)); break; - } + } if (mUsage & TU_AUTOMIPMAP && (mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_3D)) { OGRE_CHECK_GL_ERROR(glGenerateMipmap(mTarget)); @@ -659,7 +659,7 @@ namespace Ogre { switch(mTarget) { case GL_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP: OGRE_CHECK_GL_ERROR(glTexSubImage2D(mFaceTarget, mLevel, dest.left, dest.top, @@ -775,7 +775,7 @@ namespace Ogre { // @author W.J. van der Laan void GLES2TextureBuffer::blitFromTexture(GLES2TextureBuffer *src, const Image::Box &srcBox, const Image::Box &dstBox) { - return; // todo - add a shader attach... + return; // todo - add a shader attach... // std::cerr << "GLES2TextureBuffer::blitFromTexture " << // src->mTextureID << ":" << srcBox.left << "," << srcBox.top << "," << srcBox.right << "," << srcBox.bottom << " " << // mTextureID << ":" << dstBox.left << "," << dstBox.top << "," << dstBox.right << "," << dstBox.bottom << std::endl; @@ -785,7 +785,7 @@ namespace Ogre { RenderSystem* rsys = Root::getSingleton().getRenderSystem(); rsys->_disableTextureUnitsFrom(0); - glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0); // Disable alpha, depth and scissor testing, disable blending, // and disable culling @@ -895,7 +895,7 @@ namespace Ogre { // Normalise to texture coordinate in 0.0 .. 1.0 w = (w+0.5f) / (float)src->mDepth; - // Finally we're ready to rumble + // Finally we're ready to rumble getGLES2SupportRef()->getStateCacheManager()->bindGLTexture(src->mTarget, src->mTextureID); OGRE_CHECK_GL_ERROR(glEnable(src->mTarget)); diff --git a/RenderSystems/GLES2/src/OgreGLES2HardwareUniformBuffer.cpp b/RenderSystems/GLES2/src/OgreGLES2HardwareUniformBuffer.cpp index 98259fd0b76..261262ca1b2 100644 --- a/RenderSystems/GLES2/src/OgreGLES2HardwareUniformBuffer.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2HardwareUniformBuffer.cpp @@ -123,7 +123,7 @@ namespace Ogre { // return offsetted retPtr = static_cast(static_cast(pBuffer) + offset); - mIsLocked = true; + mIsLocked = true; return retPtr; } @@ -154,7 +154,7 @@ namespace Ogre { // Get data from the real buffer OGRE_CHECK_GL_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, mBufferId)); - OGRE_CHECK_GL_ERROR(glGetBufferPointerv(GL_UNIFORM_BUFFER, GL_BUFFER_MAP_POINTER, &pDest)); + OGRE_CHECK_GL_ERROR(glGetBufferPointerv(GL_UNIFORM_BUFFER, GL_BUFFER_MAP_POINTER, &pDest)); } void GLES2HardwareUniformBuffer::writeData(size_t offset, @@ -187,7 +187,7 @@ namespace Ogre { // If the buffer is not in system memory we can use ARB_copy_buffers to do an optimised copy. if (srcBuffer.isSystemMemory()) { - HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer); + HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer); } else { diff --git a/RenderSystems/GLES2/src/OgreGLES2HardwareVertexBuffer.cpp b/RenderSystems/GLES2/src/OgreGLES2HardwareVertexBuffer.cpp index cda3bc2028e..ebe0ca57517 100644 --- a/RenderSystems/GLES2/src/OgreGLES2HardwareVertexBuffer.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2HardwareVertexBuffer.cpp @@ -35,7 +35,7 @@ THE SOFTWARE. namespace Ogre { GLES2HardwareVertexBuffer::GLES2HardwareVertexBuffer(HardwareBufferManagerBase* mgr, - size_t vertexSize, + size_t vertexSize, size_t numVertices, HardwareBuffer::Usage usage, bool useShadowBuffer) @@ -65,7 +65,7 @@ namespace Ogre { "GLES2HardwareVertexBuffer::GLES2HardwareVertexBuffer"); } - static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ARRAY_BUFFER, mBufferId); + static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ARRAY_BUFFER, mBufferId); OGRE_CHECK_GL_ERROR(glBufferData(GL_ARRAY_BUFFER, mSizeInBytes, NULL, GLES2HardwareBufferManager::getGLUsage(mUsage))); } @@ -148,7 +148,7 @@ namespace Ogre { void* retPtr = static_cast( static_cast(pBuffer) + offset); - mIsLocked = true; + mIsLocked = true; return retPtr; } @@ -216,7 +216,7 @@ namespace Ogre { const void* pSource, bool discardWholeBuffer) { - static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ARRAY_BUFFER, mBufferId); + static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ARRAY_BUFFER, mBufferId); // Update the shadow buffer if(mUseShadowBuffer) @@ -251,7 +251,7 @@ namespace Ogre { // If the buffer is not in system memory we can use ARB_copy_buffers to do an optimised copy. if (srcBuffer.isSystemMemory()) { - HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer); + HardwareBuffer::copyData(srcBuffer, srcOffset, dstOffset, length, discardWholeBuffer); } else { @@ -282,7 +282,7 @@ namespace Ogre { mLockSize, HBL_READ_ONLY); - static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ARRAY_BUFFER, mBufferId); + static_cast(mMgr)->getStateCacheManager()->bindGLBuffer(GL_ARRAY_BUFFER, mBufferId); OGRE_CHECK_GL_ERROR(glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)mSizeInBytes, srcData, GLES2HardwareBufferManager::getGLUsage(mUsage))); diff --git a/RenderSystems/GLES2/src/OgreGLES2PixelFormat.cpp b/RenderSystems/GLES2/src/OgreGLES2PixelFormat.cpp index 1b4d4b855c2..77d672dd535 100644 --- a/RenderSystems/GLES2/src/OgreGLES2PixelFormat.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2PixelFormat.cpp @@ -32,7 +32,7 @@ THE SOFTWARE. #include "OgreBitwise.h" namespace Ogre { - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- GLenum GLES2PixelUtil::getGLOriginFormat(PixelFormat mFormat) { switch (mFormat) @@ -97,18 +97,18 @@ namespace Ogre { #endif #if OGRE_NO_ETC_CODEC == 0 -# ifdef GL_OES_compressed_ETC1_RGB8_texture +# ifdef GL_OES_compressed_ETC1_RGB8_texture case PF_ETC1_RGB8: return GL_ETC1_RGB8_OES; -# endif -# ifdef GL_AMD_compressed_ATC_texture - case PF_ATC_RGB: - return ATC_RGB_AMD; - case PF_ATC_RGBA_EXPLICIT_ALPHA: - return ATC_RGBA_EXPLICIT_ALPHA_AMD; - case PF_ATC_RGBA_INTERPOLATED_ALPHA: - return ATC_RGBA_INTERPOLATED_ALPHA_AMD; -# endif +# endif +# ifdef GL_AMD_compressed_ATC_texture + case PF_ATC_RGB: + return ATC_RGB_AMD; + case PF_ATC_RGBA_EXPLICIT_ALPHA: + return ATC_RGBA_EXPLICIT_ALPHA_AMD; + case PF_ATC_RGBA_INTERPOLATED_ALPHA: + return ATC_RGBA_INTERPOLATED_ALPHA_AMD; +# endif #endif #if OGRE_NO_GLES3_SUPPORT == 0 @@ -129,7 +129,7 @@ namespace Ogre { return GL_RGB; case PF_X8R8G8B8: - case PF_A8R8G8B8: + case PF_A8R8G8B8: case PF_A4R4G4B4: case PF_A1R5G5B5: case PF_B8G8R8A8: @@ -140,7 +140,7 @@ namespace Ogre { #endif case PF_A8B8G8R8: - case PF_R8G8B8A8: + case PF_R8G8B8A8: case PF_A2R10G10B10: case PF_A2B10G10R10: case PF_SHORT_RGBA: @@ -171,21 +171,21 @@ namespace Ogre { case PF_R8_SINT: case PF_R16_SINT: case PF_R32_SINT: - return GL_RED_INTEGER; + return GL_RED_INTEGER; case PF_R8G8_UINT: case PF_R16G16_UINT: case PF_R32G32_UINT: case PF_R8G8_SINT: case PF_R16G16_SINT: case PF_R32G32_SINT: - return GL_RG_INTEGER; + return GL_RG_INTEGER; case PF_R8G8B8_UINT: case PF_R16G16B16_UINT: case PF_R32G32B32_UINT: case PF_R8G8B8_SINT: case PF_R16G16B16_SINT: - case PF_R32G32B32_SINT: - return GL_RGB_INTEGER; + case PF_R32G32B32_SINT: + return GL_RGB_INTEGER; case PF_R8G8B8A8_UINT: case PF_R16G16B16A16_UINT: case PF_R32G32B32A32_UINT: @@ -213,7 +213,7 @@ namespace Ogre { return 0; } } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- GLenum GLES2PixelUtil::getGLOriginDataType(PixelFormat mFormat) { switch (mFormat) @@ -233,7 +233,7 @@ namespace Ogre { case PF_A4R4G4B4: case PF_SHORT_RGB: case PF_SHORT_RGBA: - return GL_UNSIGNED_SHORT_4_4_4_4; + return GL_UNSIGNED_SHORT_4_4_4_4; case PF_A1R5G5B5: return GL_UNSIGNED_SHORT_5_5_5_1; @@ -299,7 +299,7 @@ namespace Ogre { case PF_R8G8_UINT: case PF_R8G8B8_UINT: case PF_R8G8B8A8_UINT: - return GL_UNSIGNED_BYTE; + return GL_UNSIGNED_BYTE; case PF_R32_UINT: case PF_R32G32_UINT: case PF_R32G32B32_UINT: @@ -309,19 +309,19 @@ namespace Ogre { case PF_R16G16_UINT: case PF_R16G16B16_UINT: case PF_R16G16B16A16_UINT: - return GL_UNSIGNED_SHORT; + return GL_UNSIGNED_SHORT; case PF_R16_SINT: case PF_R16G16_SINT: case PF_R16G16B16_SINT: case PF_R16G16B16A16_SINT: - return GL_SHORT; + return GL_SHORT; case PF_R32G32B32_SINT: case PF_R32_SINT: case PF_R32G32_SINT: case PF_R32G32B32A32_SINT: return GL_INT; - case PF_R9G9B9E5_SHAREDEXP: + case PF_R9G9B9E5_SHAREDEXP: return GL_UNSIGNED_INT_5_9_9_9_REV; case PF_R11G11B10_FLOAT: return GL_UNSIGNED_INT_10F_11F_11F_REV; @@ -331,7 +331,7 @@ namespace Ogre { } } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- GLenum GLES2PixelUtil::getGLInternalFormat(PixelFormat fmt, bool hwGamma) { switch (fmt) @@ -356,18 +356,18 @@ namespace Ogre { #endif #if OGRE_NO_ETC_CODEC == 0 -# ifdef GL_OES_compressed_ETC1_RGB8_texture +# ifdef GL_OES_compressed_ETC1_RGB8_texture case PF_ETC1_RGB8: return GL_ETC1_RGB8_OES; -# endif -# ifdef GL_AMD_compressed_ATC_texture - case PF_ATC_RGB: - return ATC_RGB_AMD; - case PF_ATC_RGBA_EXPLICIT_ALPHA: - return ATC_RGBA_EXPLICIT_ALPHA_AMD; - case PF_ATC_RGBA_INTERPOLATED_ALPHA: - return ATC_RGBA_INTERPOLATED_ALPHA_AMD; -# endif +# endif +# ifdef GL_AMD_compressed_ATC_texture + case PF_ATC_RGB: + return ATC_RGB_AMD; + case PF_ATC_RGBA_EXPLICIT_ALPHA: + return ATC_RGBA_EXPLICIT_ALPHA_AMD; + case PF_ATC_RGBA_INTERPOLATED_ALPHA: + return ATC_RGBA_INTERPOLATED_ALPHA_AMD; +# endif #endif #if OGRE_NO_GLES3_SUPPORT == 0 @@ -380,19 +380,19 @@ namespace Ogre { #endif #if OGRE_NO_GLES3_SUPPORT == 0 - case PF_A1R5G5B5: - return GL_RGB5_A1; + case PF_A1R5G5B5: + return GL_RGB5_A1; case PF_R5G6B5: - case PF_B5G6R5: + case PF_B5G6R5: return GL_RGB565; case PF_A4R4G4B4: return GL_RGBA4; case PF_R8G8B8: case PF_B8G8R8: - if (hwGamma) - return GL_SRGB8; - else - return GL_RGB8; + if (hwGamma) + return GL_SRGB8; + else + return GL_RGB8; case PF_A8R8G8B8: #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS return GL_BGRA8_EXT; @@ -400,12 +400,12 @@ namespace Ogre { case PF_B8G8R8A8: case PF_A8B8G8R8: case PF_R8G8B8A8: - case PF_X8B8G8R8: - case PF_X8R8G8B8: - if (hwGamma) - return GL_SRGB8_ALPHA8; - else - return GL_RGBA8; + case PF_X8B8G8R8: + case PF_X8R8G8B8: + if (hwGamma) + return GL_SRGB8_ALPHA8; + else + return GL_RGBA8; case PF_A2R10G10B10: case PF_A2B10G10R10: return GL_RGB10_A2UI; @@ -517,20 +517,20 @@ namespace Ogre { case PF_A4L4: case PF_R3G3B2: case PF_SHORT_GR: - case PF_DXT1: + case PF_DXT1: #if GL_EXT_texture_compression_dxt1 - if (!hwGamma) - return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + if (!hwGamma) + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; #endif case PF_DXT3: #if GL_EXT_texture_compression_s3tc - if (!hwGamma) - return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + if (!hwGamma) + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; #endif case PF_DXT5: #if GL_EXT_texture_compression_s3tc - if (!hwGamma) - return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + if (!hwGamma) + return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; #endif #if (GL_EXT_texture_rg && OGRE_PLATFORM != OGRE_PLATFORM_NACL) || (OGRE_NO_GLES3_SUPPORT == 0) @@ -551,7 +551,7 @@ namespace Ogre { return GL_NONE; } } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- GLenum GLES2PixelUtil::getClosestGLInternalFormat(PixelFormat mFormat, bool hwGamma) { @@ -584,7 +584,7 @@ namespace Ogre { return format; } } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- PixelFormat GLES2PixelUtil::getClosestOGREFormat(GLenum fmt, GLenum dataType) { switch (fmt) @@ -615,18 +615,18 @@ namespace Ogre { #endif #if OGRE_NO_ETC_CODEC == 0 -# ifdef GL_OES_compressed_ETC1_RGB8_texture +# ifdef GL_OES_compressed_ETC1_RGB8_texture case GL_ETC1_RGB8_OES: return PF_ETC1_RGB8; -# endif -# ifdef GL_AMD_compressed_ATC_texture - case ATC_RGB_AMD: - return PF_ATC_RGB; - case ATC_RGBA_EXPLICIT_ALPHA_AMD: - return PF_ATC_RGBA_EXPLICIT_ALPHA; - case ATC_RGBA_INTERPOLATED_ALPHA_AMD: - return PF_ATC_RGBA_INTERPOLATED_ALPHA; -# endif +# endif +# ifdef GL_AMD_compressed_ATC_texture + case ATC_RGB_AMD: + return PF_ATC_RGB; + case ATC_RGBA_EXPLICIT_ALPHA_AMD: + return PF_ATC_RGBA_EXPLICIT_ALPHA; + case ATC_RGBA_INTERPOLATED_ALPHA_AMD: + return PF_ATC_RGBA_INTERPOLATED_ALPHA; +# endif #endif #if OGRE_NO_GLES3_SUPPORT == 0 @@ -794,11 +794,11 @@ namespace Ogre { return PF_A8B8G8R8; }; } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- size_t GLES2PixelUtil::getMaxMipmaps(uint32 width, uint32 height, uint32 depth, PixelFormat format) { - size_t count = 0; + size_t count = 0; if((width > 0) && (height > 0) && (depth > 0)) { do { @@ -818,10 +818,10 @@ namespace Ogre { count++; } while(!(width == 1 && height == 1 && depth == 1)); - } - return count; + } + return count; } - //----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // TODO: Remove uint32 GLES2PixelUtil::optionalPO2(uint32 value) { diff --git a/RenderSystems/GLES2/src/OgreGLES2RenderSystem.cpp b/RenderSystems/GLES2/src/OgreGLES2RenderSystem.cpp index 221da826281..8d70e224d9d 100644 --- a/RenderSystems/GLES2/src/OgreGLES2RenderSystem.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2RenderSystem.cpp @@ -54,12 +54,12 @@ THE SOFTWARE. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS # include "OgreEAGL2Window.h" #elif OGRE_PLATFORM == OGRE_PLATFORM_ANDROID -# include "OgreAndroidEGLWindow.h" -# include "OgreAndroidEGLContext.h" +# include "OgreAndroidEGLWindow.h" +# include "OgreAndroidEGLContext.h" # include "OgreAndroidResourceManager.h" Ogre::AndroidResourceManager* Ogre::GLES2RenderSystem::mResourceManager = NULL; #elif OGRE_PLATFORM == OGRE_PLATFORM_NACL -# include "OgreNaClWindow.h" +# include "OgreNaClWindow.h" #else # include "OgreEGLWindow.h" #endif @@ -76,26 +76,26 @@ namespace Ogre { mGLSLESProgramFactory(0), mHardwareBufferManager(0), mRTTManager(0), - mCurTexMipCount(0) + mCurTexMipCount(0) { size_t i; - LogManager::getSingleton().logMessage(getName() + " created."); + LogManager::getSingleton().logMessage(getName() + " created."); mRenderAttribsBound.reserve(100); #if OGRE_NO_GLES3_SUPPORT == 0 mRenderInstanceAttribsBound.reserve(100); #endif - mEnableFixedPipeline = false; + mEnableFixedPipeline = false; #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID mResourceManager = OGRE_NEW AndroidResourceManager(); #endif - mStateCacheManager = OGRE_NEW GLES2StateCacheManager(); + mStateCacheManager = OGRE_NEW GLES2StateCacheManager(); mGLSupport = getGLSupport(); - mGLSupport->setStateCacheManager(mStateCacheManager); + mGLSupport->setStateCacheManager(mStateCacheManager); mWorldMatrix = Matrix4::IDENTITY; mViewMatrix = Matrix4::IDENTITY; @@ -123,7 +123,7 @@ namespace Ogre { { shutdown(); - // Destroy render windows + // Destroy render windows RenderTargetMap::iterator i; for (i = mRenderTargets.begin(); i != mRenderTargets.end(); ++i) { @@ -139,10 +139,10 @@ namespace Ogre { #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID if (mResourceManager != NULL) - { - OGRE_DELETE mResourceManager; - mResourceManager = NULL; - } + { + OGRE_DELETE mResourceManager; + mResourceManager = NULL; + } #endif } @@ -164,17 +164,17 @@ namespace Ogre { String GLES2RenderSystem::validateConfigOptions(void) { - // XXX Return an error string if something is invalid + // XXX Return an error string if something is invalid return mGLSupport->validateConfig(); } RenderWindow* GLES2RenderSystem::_initialise(bool autoCreateWindow, const String& windowTitle) { - mGLSupport->start(); + mGLSupport->start(); // Create the texture manager - mTextureManager = OGRE_NEW GLES2TextureManager(*mGLSupport); + mTextureManager = OGRE_NEW GLES2TextureManager(*mGLSupport); RenderWindow *autoWindow = mGLSupport->createWindow(autoCreateWindow, this, windowTitle); @@ -190,7 +190,7 @@ namespace Ogre { rsc->setDriverVersion(mDriverVersion); const char* deviceName = (const char*)glGetString(GL_RENDERER); - const char* vendorName = (const char*)glGetString(GL_VENDOR); + const char* vendorName = (const char*)glGetString(GL_VENDOR); if (deviceName) { rsc->setDeviceName(deviceName); @@ -198,17 +198,17 @@ namespace Ogre { rsc->setRenderSystemName(getName()); - // Determine vendor - if (strstr(vendorName, "Imagination Technologies")) - rsc->setVendor(GPU_IMAGINATION_TECHNOLOGIES); - else if (strstr(vendorName, "Apple Computer, Inc.")) - rsc->setVendor(GPU_APPLE); // iOS Simulator - else if (strstr(vendorName, "NVIDIA")) - rsc->setVendor(GPU_NVIDIA); + // Determine vendor + if (strstr(vendorName, "Imagination Technologies")) + rsc->setVendor(GPU_IMAGINATION_TECHNOLOGIES); + else if (strstr(vendorName, "Apple Computer, Inc.")) + rsc->setVendor(GPU_APPLE); // iOS Simulator + else if (strstr(vendorName, "NVIDIA")) + rsc->setVendor(GPU_NVIDIA); else if (strstr(vendorName, "ARM")) - rsc->setVendor(GPU_ARM); + rsc->setVendor(GPU_ARM); else if (strstr(vendorName, "Qualcomm")) - rsc->setVendor(GPU_QUALCOMM); + rsc->setVendor(GPU_QUALCOMM); else rsc->setVendor(GPU_UNKNOWN); @@ -225,7 +225,7 @@ namespace Ogre { if(stencil) { rsc->setCapability(RSC_HWSTENCIL); - rsc->setCapability(RSC_TWO_SIDED_STENCIL); + rsc->setCapability(RSC_TWO_SIDED_STENCIL); rsc->setStencilBufferBitDepth(stencil); } @@ -237,11 +237,11 @@ namespace Ogre { if(mGLSupport->checkExtension("GL_OES_element_index_uint")) rsc->setCapability(RSC_32BIT_INDEX); - // Check for hardware occlusion support - if(mGLSupport->checkExtension("GL_EXT_occlusion_query_boolean") || gleswIsSupported(3, 0)) - { - rsc->setCapability(RSC_HWOCCLUSION); - } + // Check for hardware occlusion support + if(mGLSupport->checkExtension("GL_EXT_occlusion_query_boolean") || gleswIsSupported(3, 0)) + { + rsc->setCapability(RSC_HWOCCLUSION); + } // OpenGL ES - Check for these extensions too // For 2.0, http://www.khronos.org/registry/gles/api/2.0/gl2ext.h @@ -257,7 +257,7 @@ namespace Ogre { if(mGLSupport->checkExtension("GL_IMG_texture_compression_pvrtc") || mGLSupport->checkExtension("GL_IMG_texture_compression_pvrtc2")) rsc->setCapability(RSC_TEXTURE_COMPRESSION_PVRTC); - + if(mGLSupport->checkExtension("GL_EXT_texture_compression_dxt1") && mGLSupport->checkExtension("GL_EXT_texture_compression_s3tc")) rsc->setCapability(RSC_TEXTURE_COMPRESSION_DXT); @@ -268,7 +268,7 @@ namespace Ogre { if(gleswIsSupported(3, 0)) rsc->setCapability(RSC_TEXTURE_COMPRESSION_ETC2); - if(mGLSupport->checkExtension("GL_AMD_compressed_ATC_texture")) + if(mGLSupport->checkExtension("GL_AMD_compressed_ATC_texture")) rsc->setCapability(RSC_TEXTURE_COMPRESSION_ATC); } @@ -323,7 +323,7 @@ namespace Ogre { // Point sprites rsc->setCapability(RSC_POINT_SPRITES); rsc->setCapability(RSC_POINT_EXTENDED_PARAMETERS); - + // GLSL ES is always supported in GL ES 2 rsc->addShaderProfile("glsles"); LogManager::getSingleton().logMessage("GLSL ES support detected"); @@ -379,7 +379,7 @@ namespace Ogre { if(mGLSupport->checkExtension("GL_OES_texture_float") || mGLSupport->checkExtension("GL_OES_texture_half_float") || gleswIsSupported(3, 0)) rsc->setCapability(RSC_TEXTURE_FLOAT); - rsc->setCapability(RSC_TEXTURE_1D); + rsc->setCapability(RSC_TEXTURE_1D); #if OGRE_NO_GLES3_SUPPORT == 0 rsc->setCapability(RSC_TEXTURE_3D); #endif @@ -398,23 +398,23 @@ namespace Ogre { // Alpha to coverage always 'supported' when MSAA is available // although card may ignore it if it doesn't specifically support A2C rsc->setCapability(RSC_ALPHA_TO_COVERAGE); - - // No point sprites, so no size - rsc->setMaxPointSize(0.f); + + // No point sprites, so no size + rsc->setMaxPointSize(0.f); if(mGLSupport->checkExtension("GL_OES_vertex_array_object") || gleswIsSupported(3, 0)) rsc->setCapability(RSC_VAO); #if OGRE_NO_GLES3_SUPPORT == 0 - if (mGLSupport->checkExtension("GL_OES_get_program_binary") || gleswIsSupported(3, 0)) - { - // http://www.khronos.org/registry/gles/extensions/OES/OES_get_program_binary.txt + if (mGLSupport->checkExtension("GL_OES_get_program_binary") || gleswIsSupported(3, 0)) + { + // http://www.khronos.org/registry/gles/extensions/OES/OES_get_program_binary.txt GLint formats; OGRE_CHECK_GL_ERROR(glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats)); if(formats > 0) rsc->setCapability(RSC_CAN_GET_COMPILED_SHADER_BUFFER); - } + } #endif if (mGLSupport->checkExtension("GL_EXT_instanced_arrays") || gleswIsSupported(3, 0)) @@ -423,7 +423,7 @@ namespace Ogre { } #if OGRE_NO_GLES3_SUPPORT == 0 - // Check if render to vertex buffer (transform feedback in OpenGL) + // Check if render to vertex buffer (transform feedback in OpenGL) rsc->setCapability(RSC_HWRENDER_TO_VERTEX_BUFFER); #endif return rsc; @@ -459,11 +459,11 @@ namespace Ogre { mRTTManager = new GLES2FBOManager(); caps->setCapability(RSC_RTT_SEPARATE_DEPTHBUFFER); - Log* defaultLog = LogManager::getSingleton().getDefaultLog(); - if (defaultLog) - { - caps->log(defaultLog); - } + Log* defaultLog = LogManager::getSingleton().getDefaultLog(); + if (defaultLog) + { + caps->log(defaultLog); + } mGLInitialised = true; } @@ -478,14 +478,14 @@ namespace Ogre { { // Deleting the GLSL program factory - if (mGLSLESProgramFactory) - { - // Remove from manager safely - if (HighLevelGpuProgramManager::getSingletonPtr()) - HighLevelGpuProgramManager::getSingleton().removeFactory(mGLSLESProgramFactory); - OGRE_DELETE mGLSLESProgramFactory; - mGLSLESProgramFactory = 0; - } + if (mGLSLESProgramFactory) + { + // Remove from manager safely + if (HighLevelGpuProgramManager::getSingletonPtr()) + HighLevelGpuProgramManager::getSingleton().removeFactory(mGLSLESProgramFactory); + OGRE_DELETE mGLSLESProgramFactory; + mGLSLESProgramFactory = 0; + } #if !OGRE_NO_GLES2_CG_SUPPORT // Deleting the GLSL program factory @@ -498,7 +498,7 @@ namespace Ogre { mGLSLESCgProgramFactory = 0; } #endif - // Deleting the GPU program manager and hardware buffer manager. Has to be done before the mGLSupport->stop(). + // Deleting the GPU program manager and hardware buffer manager. Has to be done before the mGLSupport->stop(). OGRE_DELETE mGpuProgramManager; mGpuProgramManager = 0; @@ -512,17 +512,17 @@ namespace Ogre { mTextureManager = 0; // Delete extra threads contexts - for (GLES2ContextList::iterator i = mBackgroundContextList.begin(); + for (GLES2ContextList::iterator i = mBackgroundContextList.begin(); i != mBackgroundContextList.end(); ++i) - { - GLES2Context* pCurContext = *i; + { + GLES2Context* pCurContext = *i; - pCurContext->releaseContext(); + pCurContext->releaseContext(); - delete pCurContext; - } + delete pCurContext; + } - mBackgroundContextList.clear(); + mBackgroundContextList.clear(); RenderSystem::shutdown(); @@ -541,7 +541,7 @@ namespace Ogre { "GLES2RenderSystem::_createRenderWindow"); } - // Log a message + // Log a message StringStream ss; ss << "GLES2RenderSystem::_createRenderWindow \"" << name << "\", " << width << "x" << height << " "; @@ -562,14 +562,14 @@ namespace Ogre { LogManager::getSingleton().logMessage(ss.str()); } - // Create the window + // Create the window RenderWindow* win = mGLSupport->newWindow(name, width, height, fullScreen, miscParams); attachRenderTarget((Ogre::RenderTarget&) *win); if (!mGLInitialised) { initialiseContext(win); - + StringVector tokens = StringUtil::split(mGLSupport->getGLVersion(), "."); if (!tokens.empty()) { @@ -594,11 +594,11 @@ namespace Ogre { } mNativeShadingLanguageVersion = (StringConverter::parseUnsignedInt(tokens[i]) * 100) + StringConverter::parseUnsignedInt(tokens[i+1]); - // Initialise GL after the first window has been created - // TODO: fire this from emulation options, and don't duplicate Real and Current capabilities + // Initialise GL after the first window has been created + // TODO: fire this from emulation options, and don't duplicate Real and Current capabilities mRealCapabilities = createRenderSystemCapabilities(); - // use real capabilities if custom capabilities are not available + // use real capabilities if custom capabilities are not available if (!mUseCustomCapabilities) mCurrentCapabilities = mRealCapabilities; @@ -606,78 +606,78 @@ namespace Ogre { initialiseFromRenderSystemCapabilities(mCurrentCapabilities, (RenderTarget *) win); - // Initialise the main context + // Initialise the main context _oneTimeContextInitialization(); if (mCurrentContext) mCurrentContext->setInitialized(); } - if( win->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH ) - { - // Unlike D3D9, OGL doesn't allow sharing the main depth buffer, so keep them separate. - // Only Copy does, but Copy means only one depth buffer... - GLES2Context *windowContext = 0; - win->getCustomAttribute( "GLCONTEXT", &windowContext ); - GLES2DepthBuffer *depthBuffer = OGRE_NEW GLES2DepthBuffer( DepthBuffer::POOL_DEFAULT, this, - windowContext, 0, 0, - win->getWidth(), win->getHeight(), - win->getFSAA(), 0, true ); + if( win->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH ) + { + // Unlike D3D9, OGL doesn't allow sharing the main depth buffer, so keep them separate. + // Only Copy does, but Copy means only one depth buffer... + GLES2Context *windowContext = 0; + win->getCustomAttribute( "GLCONTEXT", &windowContext ); + GLES2DepthBuffer *depthBuffer = OGRE_NEW GLES2DepthBuffer( DepthBuffer::POOL_DEFAULT, this, + windowContext, 0, 0, + win->getWidth(), win->getHeight(), + win->getFSAA(), 0, true ); - mDepthBufferPool[depthBuffer->getPoolId()].push_back( depthBuffer ); + mDepthBufferPool[depthBuffer->getPoolId()].push_back( depthBuffer ); - win->attachDepthBuffer( depthBuffer ); - } + win->attachDepthBuffer( depthBuffer ); + } return win; } - //--------------------------------------------------------------------- - DepthBuffer* GLES2RenderSystem::_createDepthBufferFor( RenderTarget *renderTarget ) - { - GLES2DepthBuffer *retVal = 0; + //--------------------------------------------------------------------- + DepthBuffer* GLES2RenderSystem::_createDepthBufferFor( RenderTarget *renderTarget ) + { + GLES2DepthBuffer *retVal = 0; - // Only FBO & pbuffer support different depth buffers, so everything - // else creates dummy (empty) containers - // retVal = mRTTManager->_createDepthBufferFor( renderTarget ); - GLES2FrameBufferObject *fbo = 0; + // Only FBO & pbuffer support different depth buffers, so everything + // else creates dummy (empty) containers + // retVal = mRTTManager->_createDepthBufferFor( renderTarget ); + GLES2FrameBufferObject *fbo = 0; renderTarget->getCustomAttribute("FBO", &fbo); - if( fbo ) - { - // Presence of an FBO means the manager is an FBO Manager, that's why it's safe to downcast - // Find best depth & stencil format suited for the RT's format - GLuint depthFormat, stencilFormat; - static_cast(mRTTManager)->getBestDepthStencil( fbo->getFormat(), - &depthFormat, &stencilFormat ); + if( fbo ) + { + // Presence of an FBO means the manager is an FBO Manager, that's why it's safe to downcast + // Find best depth & stencil format suited for the RT's format + GLuint depthFormat, stencilFormat; + static_cast(mRTTManager)->getBestDepthStencil( fbo->getFormat(), + &depthFormat, &stencilFormat ); - GLES2RenderBuffer *depthBuffer = OGRE_NEW GLES2RenderBuffer( depthFormat, fbo->getWidth(), - fbo->getHeight(), fbo->getFSAA() ); + GLES2RenderBuffer *depthBuffer = OGRE_NEW GLES2RenderBuffer( depthFormat, fbo->getWidth(), + fbo->getHeight(), fbo->getFSAA() ); - GLES2RenderBuffer *stencilBuffer = depthBuffer; - if( + GLES2RenderBuffer *stencilBuffer = depthBuffer; + if( #if OGRE_NO_GLES3_SUPPORT == 0 depthFormat != GL_DEPTH32F_STENCIL8 && #endif depthFormat != GL_DEPTH24_STENCIL8_OES && stencilFormat ) - { + { stencilBuffer = OGRE_NEW GLES2RenderBuffer( stencilFormat, fbo->getWidth(), fbo->getHeight(), fbo->getFSAA() ); - } + } - // No "custom-quality" multisample for now in GL - retVal = OGRE_NEW GLES2DepthBuffer( 0, this, mCurrentContext, depthBuffer, stencilBuffer, - fbo->getWidth(), fbo->getHeight(), fbo->getFSAA(), 0, false ); - } + // No "custom-quality" multisample for now in GL + retVal = OGRE_NEW GLES2DepthBuffer( 0, this, mCurrentContext, depthBuffer, stencilBuffer, + fbo->getWidth(), fbo->getHeight(), fbo->getFSAA(), 0, false ); + } - return retVal; - } - //--------------------------------------------------------------------- - void GLES2RenderSystem::_getDepthStencilFormatFor( GLenum internalColourFormat, GLenum *depthFormat, + return retVal; + } + //--------------------------------------------------------------------- + void GLES2RenderSystem::_getDepthStencilFormatFor( GLenum internalColourFormat, GLenum *depthFormat, GLenum *stencilFormat ) - { - mRTTManager->getBestDepthStencil( internalColourFormat, depthFormat, stencilFormat ); - } + { + mRTTManager->getBestDepthStencil( internalColourFormat, depthFormat, stencilFormat ); + } MultiRenderTarget* GLES2RenderSystem::createMultiRenderTarget(const String & name) { @@ -688,7 +688,7 @@ namespace Ogre { void GLES2RenderSystem::destroyRenderWindow(RenderWindow* pWin) { - // Find it to remove from list + // Find it to remove from list RenderTargetMap::iterator i = mRenderTargets.begin(); while (i != mRenderTargets.end()) @@ -776,55 +776,55 @@ namespace Ogre { void GLES2RenderSystem::_setProjectionMatrix(const Matrix4 &m) { - // Nothing to do but mark clip planes dirty + // Nothing to do but mark clip planes dirty if (!mClipPlanes.empty()) mClipPlanesDirty = true; } void GLES2RenderSystem::_setTexture(size_t stage, bool enabled, const TexturePtr &texPtr) { - GLES2TexturePtr tex = texPtr.staticCast(); + GLES2TexturePtr tex = texPtr.staticCast(); - if (!mStateCacheManager->activateGLTextureUnit(stage)) - return; + if (!mStateCacheManager->activateGLTextureUnit(stage)) + return; - if (enabled) - { + if (enabled) + { #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - mCurTexMipCount = 0; + mCurTexMipCount = 0; #endif - GLuint texID = 0; - if (!tex.isNull()) - { - // Note used - tex->touch(); - mTextureTypes[stage] = tex->getGLES2TextureTarget(); - texID = tex->getGLID(); + GLuint texID = 0; + if (!tex.isNull()) + { + // Note used + tex->touch(); + mTextureTypes[stage] = tex->getGLES2TextureTarget(); + texID = tex->getGLID(); #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - mCurTexMipCount = tex->getNumMipmaps(); + mCurTexMipCount = tex->getNumMipmaps(); #endif - } - else - { - // Assume 2D - mTextureTypes[stage] = GL_TEXTURE_2D; - texID = static_cast(mTextureManager)->getWarningTextureID(); - } + } + else + { + // Assume 2D + mTextureTypes[stage] = GL_TEXTURE_2D; + texID = static_cast(mTextureManager)->getWarningTextureID(); + } mStateCacheManager->bindGLTexture(mTextureTypes[stage], texID); - } - else - { - // Bind zero texture - mStateCacheManager->bindGLTexture(GL_TEXTURE_2D, 0); - } + } + else + { + // Bind zero texture + mStateCacheManager->bindGLTexture(GL_TEXTURE_2D, 0); + } - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } void GLES2RenderSystem::_setTextureCoordSet(size_t stage, size_t index) { - mTextureCoordIndex[stage] = index; + mTextureCoordIndex[stage] = index; } GLint GLES2RenderSystem::getTextureAddressingMode(TextureUnitState::TextureAddressingMode tam) const @@ -844,15 +844,15 @@ namespace Ogre { void GLES2RenderSystem::_setTextureAddressingMode(size_t stage, const TextureUnitState::UVWAddressingMode& uvw) { - if (!mStateCacheManager->activateGLTextureUnit(stage)) - return; + if (!mStateCacheManager->activateGLTextureUnit(stage)) + return; - mStateCacheManager->setTexParameteri(mTextureTypes[stage], GL_TEXTURE_WRAP_S, getTextureAddressingMode(uvw.u)); - mStateCacheManager->setTexParameteri(mTextureTypes[stage], GL_TEXTURE_WRAP_T, getTextureAddressingMode(uvw.v)); + mStateCacheManager->setTexParameteri(mTextureTypes[stage], GL_TEXTURE_WRAP_S, getTextureAddressingMode(uvw.u)); + mStateCacheManager->setTexParameteri(mTextureTypes[stage], GL_TEXTURE_WRAP_T, getTextureAddressingMode(uvw.v)); #if OGRE_NO_GLES3_SUPPORT == 0 - mStateCacheManager->setTexParameteri(mTextureTypes[stage], GL_TEXTURE_WRAP_R, getTextureAddressingMode(uvw.w)); + mStateCacheManager->setTexParameteri(mTextureTypes[stage], GL_TEXTURE_WRAP_R, getTextureAddressingMode(uvw.w)); #endif - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } GLenum GLES2RenderSystem::getBlendMode(SceneBlendFactor ogreBlend) const @@ -885,50 +885,50 @@ namespace Ogre { return GL_ONE; } - void GLES2RenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op) - { - GLenum sourceBlend = getBlendMode(sourceFactor); - GLenum destBlend = getBlendMode(destFactor); - if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO) - { - mStateCacheManager->setDisabled(GL_BLEND); - } - else - { - mStateCacheManager->setEnabled(GL_BLEND); - mStateCacheManager->setBlendFunc(sourceBlend, destBlend); - } + void GLES2RenderSystem::_setSceneBlending(SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendOperation op) + { + GLenum sourceBlend = getBlendMode(sourceFactor); + GLenum destBlend = getBlendMode(destFactor); + if(sourceFactor == SBF_ONE && destFactor == SBF_ZERO) + { + mStateCacheManager->setDisabled(GL_BLEND); + } + else + { + mStateCacheManager->setEnabled(GL_BLEND); + mStateCacheManager->setBlendFunc(sourceBlend, destBlend); + } GLint func = GL_FUNC_ADD; - switch(op) - { - case SBO_ADD: - func = GL_FUNC_ADD; - break; - case SBO_SUBTRACT: - func = GL_FUNC_SUBTRACT; - break; - case SBO_REVERSE_SUBTRACT: - func = GL_FUNC_REVERSE_SUBTRACT; - break; - case SBO_MIN: + switch(op) + { + case SBO_ADD: + func = GL_FUNC_ADD; + break; + case SBO_SUBTRACT: + func = GL_FUNC_SUBTRACT; + break; + case SBO_REVERSE_SUBTRACT: + func = GL_FUNC_REVERSE_SUBTRACT; + break; + case SBO_MIN: if(mGLSupport->checkExtension("GL_EXT_blend_minmax") || gleswIsSupported(3, 0)) func = GL_MIN_EXT; break; - case SBO_MAX: + case SBO_MAX: if(mGLSupport->checkExtension("GL_EXT_blend_minmax") || gleswIsSupported(3, 0)) func = GL_MAX_EXT; - break; - } + break; + } mStateCacheManager->setBlendEquation(func); - } + } - void GLES2RenderSystem::_setSeparateSceneBlending( + void GLES2RenderSystem::_setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp ) - { + { GLenum sourceBlend = getBlendMode(sourceFactor); GLenum destBlend = getBlendMode(destFactor); GLenum sourceBlendAlpha = getBlendMode(sourceFactorAlpha); @@ -990,38 +990,38 @@ namespace Ogre { } OGRE_CHECK_GL_ERROR(glBlendEquationSeparate(func, alphaFunc)); - } + } void GLES2RenderSystem::_setAlphaRejectSettings(CompareFunction func, unsigned char value, bool alphaToCoverage) { - bool a2c = false; - static bool lasta2c = false; + bool a2c = false; + static bool lasta2c = false; if(func != CMPF_ALWAYS_PASS) - { - a2c = alphaToCoverage; + { + a2c = alphaToCoverage; } - if (a2c != lasta2c && getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE)) - { - if (a2c) - mStateCacheManager->setEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE); - else - mStateCacheManager->setDisabled(GL_SAMPLE_ALPHA_TO_COVERAGE); + if (a2c != lasta2c && getCapabilities()->hasCapability(RSC_ALPHA_TO_COVERAGE)) + { + if (a2c) + mStateCacheManager->setEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE); + else + mStateCacheManager->setDisabled(GL_SAMPLE_ALPHA_TO_COVERAGE); - lasta2c = a2c; - } - } + lasta2c = a2c; + } + } void GLES2RenderSystem::_setViewport(Viewport *vp) { - // Check if viewport is different - if (!vp) - { - mActiveViewport = NULL; - _setRenderTarget(NULL); - } - else if (vp != mActiveViewport || vp->_isUpdated()) + // Check if viewport is different + if (!vp) + { + mActiveViewport = NULL; + _setRenderTarget(NULL); + } + else if (vp != mActiveViewport || vp->_isUpdated()) { RenderTarget* target; @@ -1031,7 +1031,7 @@ namespace Ogre { GLsizei x, y, w, h; - // Calculate the "lower-left" corner of the viewport + // Calculate the "lower-left" corner of the viewport w = vp->getActualWidth(); h = vp->getActualHeight(); x = vp->getActualLeft(); @@ -1096,11 +1096,11 @@ namespace Ogre { // Deactivate the viewport clipping. mStateCacheManager->setDisabled(GL_SCISSOR_TEST); - // unbind GPU programs at end of frame - // this is mostly to avoid holding bound programs that might get deleted - // outside via the resource manager - unbindGpuProgram(GPT_VERTEX_PROGRAM); - unbindGpuProgram(GPT_FRAGMENT_PROGRAM); + // unbind GPU programs at end of frame + // this is mostly to avoid holding bound programs that might get deleted + // outside via the resource manager + unbindGpuProgram(GPT_VERTEX_PROGRAM); + unbindGpuProgram(GPT_FRAGMENT_PROGRAM); } void GLES2RenderSystem::setVertexDeclaration(VertexDeclaration* decl) @@ -1224,7 +1224,7 @@ namespace Ogre { Matrix4& dest, bool forGpuProgram) { - // no any conversion request for OpenGL + // no any conversion request for OpenGL dest = matrix; } @@ -1235,13 +1235,13 @@ namespace Ogre { Radian thetaY(fovy / 2.0f); Real tanThetaY = Math::Tan(thetaY); - // Calc matrix elements + // Calc matrix elements Real w = (1.0f / tanThetaY) / aspect; Real h = 1.0f / tanThetaY; Real q, qn; if (farPlane == 0) { - // Infinite far plane + // Infinite far plane q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1; qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2); } @@ -1251,12 +1251,12 @@ namespace Ogre { qn = -2 * (farPlane * nearPlane) / (farPlane - nearPlane); } - // NB This creates Z in range [-1,1] - // - // [ w 0 0 0 ] - // [ 0 h 0 0 ] - // [ 0 0 q qn ] - // [ 0 0 -1 0 ] + // NB This creates Z in range [-1,1] + // + // [ w 0 0 0 ] + // [ 0 h 0 0 ] + // [ 0 0 q qn ] + // [ 0 0 -1 0 ] dest = Matrix4::ZERO; dest[0][0] = w; @@ -1276,7 +1276,7 @@ namespace Ogre { Real q, qn; if (farPlane == 0) { - // Infinite far plane + // Infinite far plane q = Frustum::INFINITE_FAR_PLANE_ADJUST - 1; qn = nearPlane * (Frustum::INFINITE_FAR_PLANE_ADJUST - 2); } @@ -1326,9 +1326,9 @@ namespace Ogre { dest[3][3] = 1; } - //--------------------------------------------------------------------- - HardwareOcclusionQuery* GLES2RenderSystem::createHardwareOcclusionQuery(void) - { + //--------------------------------------------------------------------- + HardwareOcclusionQuery* GLES2RenderSystem::createHardwareOcclusionQuery(void) + { if(mGLSupport->checkExtension("GL_EXT_occlusion_query_boolean") || gleswIsSupported(3, 0)) { GLES2HardwareOcclusionQuery* ret = new GLES2HardwareOcclusionQuery(); @@ -1339,18 +1339,18 @@ namespace Ogre { { return NULL; } - } + } void GLES2RenderSystem::_applyObliqueDepthProjection(Matrix4& matrix, const Plane& plane, bool forGpuProgram) { - // Thanks to Eric Lenyel for posting this calculation at www.terathon.com + // Thanks to Eric Lenyel for posting this calculation at www.terathon.com - // Calculate the clip-space corner point opposite the clipping plane - // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and - // transform it into camera space by multiplying it - // by the inverse of the projection matrix + // Calculate the clip-space corner point opposite the clipping plane + // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and + // transform it into camera space by multiplying it + // by the inverse of the projection matrix Vector4 q; q.x = (Math::Sign(plane.normal.x) + matrix[0][2]) / matrix[0][0]; @@ -1403,20 +1403,20 @@ namespace Ogre { StencilOperation stencilFailOp, StencilOperation depthFailOp, StencilOperation passOp, - bool twoSidedOperation, - bool readBackAsTexture) + bool twoSidedOperation, + bool readBackAsTexture) { - bool flip = false; + bool flip = false; - if (twoSidedOperation) - { - if (!mCurrentCapabilities->hasCapability(RSC_TWO_SIDED_STENCIL)) - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "2-sided stencils are not supported", + if (twoSidedOperation) + { + if (!mCurrentCapabilities->hasCapability(RSC_TWO_SIDED_STENCIL)) + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "2-sided stencils are not supported", "GLES2RenderSystem::setStencilBufferParams"); - // NB: We should always treat CCW as front face for consistent with default - // culling mode. Therefore, we must take care with two-sided stencil settings. - flip = (mInvertVertexWinding && !mActiveRenderTarget->requiresTextureFlipping()) || + // NB: We should always treat CCW as front face for consistent with default + // culling mode. Therefore, we must take care with two-sided stencil settings. + flip = (mInvertVertexWinding && !mActiveRenderTarget->requiresTextureFlipping()) || (!mInvertVertexWinding && mActiveRenderTarget->requiresTextureFlipping()); // Back OGRE_CHECK_GL_ERROR(glStencilMaskSeparate(GL_BACK, writeMask)); @@ -1433,17 +1433,17 @@ namespace Ogre { convertStencilOp(stencilFailOp, flip), convertStencilOp(depthFailOp, flip), convertStencilOp(passOp, flip))); - } - else - { - flip = false; - mStateCacheManager->setStencilMask(writeMask); - OGRE_CHECK_GL_ERROR(glStencilFunc(convertCompareFunction(func), refValue, compareMask)); - OGRE_CHECK_GL_ERROR(glStencilOp( + } + else + { + flip = false; + mStateCacheManager->setStencilMask(writeMask); + OGRE_CHECK_GL_ERROR(glStencilFunc(convertCompareFunction(func), refValue, compareMask)); + OGRE_CHECK_GL_ERROR(glStencilOp( convertStencilOp(stencilFailOp, flip), convertStencilOp(depthFailOp, flip), convertStencilOp(passOp, flip))); - } + } } GLint GLES2RenderSystem::getCombinedMinMipFilter(void) const @@ -1488,24 +1488,24 @@ namespace Ogre { return 0; } - void GLES2RenderSystem::_setTextureUnitFiltering(size_t unit, FilterOptions minFilter, - FilterOptions magFilter, FilterOptions mipFilter) - { - mMipFilter = mipFilter; + void GLES2RenderSystem::_setTextureUnitFiltering(size_t unit, FilterOptions minFilter, + FilterOptions magFilter, FilterOptions mipFilter) + { + mMipFilter = mipFilter; #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - if(mCurTexMipCount == 0 && mMipFilter != FO_NONE) - { - mMipFilter = FO_NONE; - } + if(mCurTexMipCount == 0 && mMipFilter != FO_NONE) + { + mMipFilter = FO_NONE; + } #endif - _setTextureUnitFiltering(unit, FT_MAG, magFilter); - _setTextureUnitFiltering(unit, FT_MIN, minFilter); - } - + _setTextureUnitFiltering(unit, FT_MAG, magFilter); + _setTextureUnitFiltering(unit, FT_MIN, minFilter); + } + void GLES2RenderSystem::_setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions fo) { - if (!mStateCacheManager->activateGLTextureUnit(unit)) - return; + if (!mStateCacheManager->activateGLTextureUnit(unit)) + return; // This is a bit of a hack that will need to fleshed out later. // On iOS cube maps are especially sensitive to texture parameter changes. @@ -1520,11 +1520,11 @@ namespace Ogre { { case FT_MIN: mMinFilter = fo; - // Combine with existing mip filter - mStateCacheManager->setTexParameteri(mTextureTypes[unit], - GL_TEXTURE_MIN_FILTER, - getCombinedMinMipFilter()); - break; + // Combine with existing mip filter + mStateCacheManager->setTexParameteri(mTextureTypes[unit], + GL_TEXTURE_MIN_FILTER, + getCombinedMinMipFilter()); + break; case FT_MAG: switch (fo) { @@ -1553,26 +1553,26 @@ namespace Ogre { break; } - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } GLfloat GLES2RenderSystem::_getCurrentAnisotropy(size_t unit) - { - GLfloat curAniso = 0; + { + GLfloat curAniso = 0; if(mGLSupport->checkExtension("GL_EXT_texture_filter_anisotropic")) mStateCacheManager->getTexParameterfv(mTextureTypes[unit], GL_TEXTURE_MAX_ANISOTROPY_EXT, &curAniso); - return curAniso ? curAniso : 1; - } + return curAniso ? curAniso : 1; + } void GLES2RenderSystem::_setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy) { - if (!mCurrentCapabilities->hasCapability(RSC_ANISOTROPY)) - return; + if (!mCurrentCapabilities->hasCapability(RSC_ANISOTROPY)) + return; - if (!mStateCacheManager->activateGLTextureUnit(unit)) - return; + if (!mStateCacheManager->activateGLTextureUnit(unit)) + return; if(mGLSupport->checkExtension("GL_EXT_texture_filter_anisotropic")) { @@ -1584,7 +1584,7 @@ namespace Ogre { GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)maxAnisotropy); } - mStateCacheManager->activateGLTextureUnit(0); + mStateCacheManager->activateGLTextureUnit(0); } void GLES2RenderSystem::_render(const RenderOperation& op) @@ -1685,7 +1685,7 @@ namespace Ogre { break; } - GLenum polyMode = mStateCacheManager->getPolygonMode(); + GLenum polyMode = mStateCacheManager->getPolygonMode(); if (op.useIndexes) { // If we are using VAO's then only bind the buffer the first time through. Otherwise, always bind. @@ -1737,13 +1737,13 @@ namespace Ogre { } if((mGLSupport->checkExtension("GL_EXT_instanced_arrays") || gleswIsSupported(3, 0)) && hasInstanceData) - { - OGRE_CHECK_GL_ERROR(glDrawArraysInstancedEXT((polyMode == GL_FILL) ? primType : polyMode, 0, static_cast(op.vertexData->vertexCount), static_cast(numberOfInstances))); - } - else - { + { + OGRE_CHECK_GL_ERROR(glDrawArraysInstancedEXT((polyMode == GL_FILL) ? primType : polyMode, 0, static_cast(op.vertexData->vertexCount), static_cast(numberOfInstances))); + } + else + { OGRE_CHECK_GL_ERROR(glDrawArrays((polyMode == GL_FILL) ? primType : polyMode, 0, static_cast(op.vertexData->vertexCount))); - } + } } while (updatePassIterationRenderState()); } @@ -1759,17 +1759,17 @@ namespace Ogre { #endif // Unbind all attributes - for (vector::type::iterator ai = mRenderAttribsBound.begin(); ai != mRenderAttribsBound.end(); ++ai) - { + for (vector::type::iterator ai = mRenderAttribsBound.begin(); ai != mRenderAttribsBound.end(); ++ai) + { mStateCacheManager->setVertexAttribDisabled(*ai); -// OGRE_CHECK_GL_ERROR(glDisableVertexAttribArray(*ai)); - } +// OGRE_CHECK_GL_ERROR(glDisableVertexAttribArray(*ai)); + } // Unbind any instance attributes - for (vector::type::iterator ai = mRenderInstanceAttribsBound.begin(); ai != mRenderInstanceAttribsBound.end(); ++ai) - { - glVertexAttribDivisorEXT(*ai, 0); - } + for (vector::type::iterator ai = mRenderInstanceAttribsBound.begin(); ai != mRenderInstanceAttribsBound.end(); ++ai) + { + glVertexAttribDivisorEXT(*ai, 0); + } mRenderAttribsBound.clear(); mRenderInstanceAttribsBound.clear(); @@ -1833,7 +1833,7 @@ namespace Ogre { if (buffers & FBT_COLOUR) { flags |= GL_COLOR_BUFFER_BIT; - // Enable buffer for writing if it isn't + // Enable buffer for writing if it isn't if (colourMask) { mStateCacheManager->setColourMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -1843,23 +1843,23 @@ namespace Ogre { if (buffers & FBT_DEPTH) { flags |= GL_DEPTH_BUFFER_BIT; - // Enable buffer for writing if it isn't + // Enable buffer for writing if it isn't mStateCacheManager->setDepthMask(GL_TRUE); mStateCacheManager->setClearDepth(depth); } if (buffers & FBT_STENCIL) { flags |= GL_STENCIL_BUFFER_BIT; - // Enable buffer for writing if it isn't + // Enable buffer for writing if it isn't mStateCacheManager->setStencilMask(0xFFFFFFFF); OGRE_CHECK_GL_ERROR(glClearStencil(stencil)); } - // Should be enable scissor test due the clear region is - // relied on scissor box bounds. + // Should be enable scissor test due the clear region is + // relied on scissor box bounds. mStateCacheManager->setEnabled(GL_SCISSOR_TEST); - // Sets the scissor box as same as viewport + // Sets the scissor box as same as viewport GLint viewport[4], scissor[4]; OGRE_CHECK_GL_ERROR(glGetIntegerv(GL_VIEWPORT, viewport)); OGRE_CHECK_GL_ERROR(glGetIntegerv(GL_SCISSOR_BOX, scissor)); @@ -1873,7 +1873,7 @@ namespace Ogre { mStateCacheManager->setDiscardBuffers(buffers); - // Clear buffers + // Clear buffers OGRE_CHECK_GL_ERROR(glClear(flags)); // Restore scissor box @@ -1904,16 +1904,16 @@ namespace Ogre { void GLES2RenderSystem::_switchContext(GLES2Context *context) { - // Unbind GPU programs and rebind to new context later, because - // scene manager treat render system as ONE 'context' ONLY, and it - // cached the GPU programs using state. - if (mCurrentVertexProgram) - mCurrentVertexProgram->unbindProgram(); - if (mCurrentFragmentProgram) - mCurrentFragmentProgram->unbindProgram(); + // Unbind GPU programs and rebind to new context later, because + // scene manager treat render system as ONE 'context' ONLY, and it + // cached the GPU programs using state. + if (mCurrentVertexProgram) + mCurrentVertexProgram->unbindProgram(); + if (mCurrentFragmentProgram) + mCurrentFragmentProgram->unbindProgram(); - // Disable textures - _disableTextureUnitsFrom(0); + // Disable textures + _disableTextureUnitsFrom(0); // It's ready for switching if(mCurrentContext) @@ -1929,10 +1929,10 @@ namespace Ogre { } // Rebind GPU programs to new context - if (mCurrentVertexProgram) - mCurrentVertexProgram->bindProgram(); - if (mCurrentFragmentProgram) - mCurrentFragmentProgram->bindProgram(); + if (mCurrentVertexProgram) + mCurrentVertexProgram->bindProgram(); + if (mCurrentFragmentProgram) + mCurrentFragmentProgram->bindProgram(); // Must reset depth/colour write mask to according with user desired, otherwise, // clearFrameBuffer would be wrong because the value we are recorded may be @@ -1949,16 +1949,16 @@ namespace Ogre { { if (mCurrentContext == context) { - // Change the context to something else so that a valid context - // remains active. When this is the main context being unregistered, - // we set the main context to 0. + // Change the context to something else so that a valid context + // remains active. When this is the main context being unregistered, + // we set the main context to 0. if (mCurrentContext != mMainContext) { _switchContext(mMainContext); } else { - // No contexts remain + // No contexts remain mCurrentContext->endCurrent(); mCurrentContext = 0; mMainContext = 0; @@ -1968,27 +1968,27 @@ namespace Ogre { void GLES2RenderSystem::_oneTimeContextInitialization() { - mStateCacheManager->setDisabled(GL_DITHER); + mStateCacheManager->setDisabled(GL_DITHER); static_cast(mTextureManager)->createWarningTexture(); #if OGRE_NO_GLES3_SUPPORT == 0 - // Enable primitive restarting with fixed indices depending upon the data type - OGRE_CHECK_GL_ERROR(glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX)); + // Enable primitive restarting with fixed indices depending upon the data type + OGRE_CHECK_GL_ERROR(glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX)); #endif } void GLES2RenderSystem::initialiseContext(RenderWindow* primary) { - // Set main and current context + // Set main and current context mMainContext = 0; primary->getCustomAttribute("GLCONTEXT", &mMainContext); mCurrentContext = mMainContext; - // Set primary context as active + // Set primary context as active if (mCurrentContext) mCurrentContext->setCurrent(); - // Setup GLSupport + // Setup GLSupport mGLSupport->initialiseExtensions(); LogManager::getSingleton().logMessage("**************************************"); @@ -2003,30 +2003,30 @@ namespace Ogre { mRTTManager->unbind(mActiveRenderTarget); mActiveRenderTarget = target; - if (target && mRTTManager) - { - // Switch context if different from current one - GLES2Context *newContext = 0; - target->getCustomAttribute("GLCONTEXT", &newContext); - if (newContext && mCurrentContext != newContext) - { - _switchContext(newContext); - } - - // Check the FBO's depth buffer status - GLES2DepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); - - if( target->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH && - (!depthBuffer || depthBuffer->getGLContext() != mCurrentContext ) ) - { - // Depth is automatically managed and there is no depth buffer attached to this RT - // or the Current context doesn't match the one this Depth buffer was created with - setDepthBufferFor( target ); - } - - // Bind frame buffer object - mRTTManager->bind(target); - } + if (target && mRTTManager) + { + // Switch context if different from current one + GLES2Context *newContext = 0; + target->getCustomAttribute("GLCONTEXT", &newContext); + if (newContext && mCurrentContext != newContext) + { + _switchContext(newContext); + } + + // Check the FBO's depth buffer status + GLES2DepthBuffer *depthBuffer = static_cast(target->getDepthBuffer()); + + if( target->getDepthBufferPool() != DepthBuffer::POOL_NO_DEPTH && + (!depthBuffer || depthBuffer->getGLContext() != mCurrentContext ) ) + { + // Depth is automatically managed and there is no depth buffer attached to this RT + // or the Current context doesn't match the one this Depth buffer was created with + setDepthBufferFor( target ); + } + + // Bind frame buffer object + mRTTManager->bind(target); + } } GLint GLES2RenderSystem::convertCompareFunction(CompareFunction func) const @@ -2055,61 +2055,61 @@ namespace Ogre { } GLint GLES2RenderSystem::convertStencilOp(StencilOperation op, bool invert) const - { - switch(op) - { - case SOP_KEEP: - return GL_KEEP; - case SOP_ZERO: - return GL_ZERO; - case SOP_REPLACE: - return GL_REPLACE; + { + switch(op) + { + case SOP_KEEP: + return GL_KEEP; + case SOP_ZERO: + return GL_ZERO; + case SOP_REPLACE: + return GL_REPLACE; case SOP_INCREMENT: - return invert ? GL_DECR : GL_INCR; - case SOP_DECREMENT: - return invert ? GL_INCR : GL_DECR; - case SOP_INCREMENT_WRAP: - return invert ? GL_DECR_WRAP : GL_INCR_WRAP; - case SOP_DECREMENT_WRAP: - return invert ? GL_INCR_WRAP : GL_DECR_WRAP; - case SOP_INVERT: - return GL_INVERT; - }; - // to keep compiler happy - return SOP_KEEP; - } + return invert ? GL_DECR : GL_INCR; + case SOP_DECREMENT: + return invert ? GL_INCR : GL_DECR; + case SOP_INCREMENT_WRAP: + return invert ? GL_DECR_WRAP : GL_INCR_WRAP; + case SOP_DECREMENT_WRAP: + return invert ? GL_INCR_WRAP : GL_DECR_WRAP; + case SOP_INVERT: + return GL_INVERT; + }; + // to keep compiler happy + return SOP_KEEP; + } //--------------------------------------------------------------------- void GLES2RenderSystem::bindGpuProgram(GpuProgram* prg) { - if (!prg) - { - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + if (!prg) + { + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Null program bound.", "GLES2RenderSystem::bindGpuProgram"); - } + } - GLES2GpuProgram* glprg = static_cast(prg); + GLES2GpuProgram* glprg = static_cast(prg); - // Unbind previous gpu program first. - // - // Note: - // 1. Even if both previous and current are the same object, we can't - // bypass re-bind completely since the object itself may be modified. - // But we can bypass unbind based on the assumption that object - // internally GL program type shouldn't be changed after it has - // been created. The behavior of bind to a GL program type twice - // should be same as unbind and rebind that GL program type, even - // for different objects. - // 2. We also assumed that the program's type (vertex or fragment) should - // not be changed during it's in using. If not, the following switch - // statement will confuse GL state completely, and we can't fix it - // here. To fix this case, we must coding the program implementation - // itself, if type is changing (during load/unload, etc), and it's in use, - // unbind and notify render system to correct for its state. - // - switch (glprg->getType()) - { + // Unbind previous gpu program first. + // + // Note: + // 1. Even if both previous and current are the same object, we can't + // bypass re-bind completely since the object itself may be modified. + // But we can bypass unbind based on the assumption that object + // internally GL program type shouldn't be changed after it has + // been created. The behavior of bind to a GL program type twice + // should be same as unbind and rebind that GL program type, even + // for different objects. + // 2. We also assumed that the program's type (vertex or fragment) should + // not be changed during it's in using. If not, the following switch + // statement will confuse GL state completely, and we can't fix it + // here. To fix this case, we must coding the program implementation + // itself, if type is changing (during load/unload, etc), and it's in use, + // unbind and notify render system to correct for its state. + // + switch (glprg->getType()) + { case GPT_VERTEX_PROGRAM: if (mCurrentVertexProgram != glprg) { @@ -2129,37 +2129,37 @@ namespace Ogre { break; default: break; - } + } - // Bind the program - glprg->bindProgram(); + // Bind the program + glprg->bindProgram(); - RenderSystem::bindGpuProgram(prg); + RenderSystem::bindGpuProgram(prg); } void GLES2RenderSystem::unbindGpuProgram(GpuProgramType gptype) { - if (gptype == GPT_VERTEX_PROGRAM && mCurrentVertexProgram) - { - mActiveVertexGpuProgramParameters.setNull(); - mCurrentVertexProgram->unbindProgram(); - mCurrentVertexProgram = 0; - } - else if (gptype == GPT_FRAGMENT_PROGRAM && mCurrentFragmentProgram) - { - mActiveFragmentGpuProgramParameters.setNull(); - mCurrentFragmentProgram->unbindProgram(); - mCurrentFragmentProgram = 0; - } - RenderSystem::unbindGpuProgram(gptype); + if (gptype == GPT_VERTEX_PROGRAM && mCurrentVertexProgram) + { + mActiveVertexGpuProgramParameters.setNull(); + mCurrentVertexProgram->unbindProgram(); + mCurrentVertexProgram = 0; + } + else if (gptype == GPT_FRAGMENT_PROGRAM && mCurrentFragmentProgram) + { + mActiveFragmentGpuProgramParameters.setNull(); + mCurrentFragmentProgram->unbindProgram(); + mCurrentFragmentProgram = 0; + } + RenderSystem::unbindGpuProgram(gptype); } void GLES2RenderSystem::bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params, uint16 mask) { // Just copy params->_copySharedParams(); - switch (gptype) - { + switch (gptype) + { case GPT_VERTEX_PROGRAM: mActiveVertexGpuProgramParameters = params; mCurrentVertexProgram->bindProgramSharedParameters(params, mask); @@ -2170,10 +2170,10 @@ namespace Ogre { break; default: break; - } + } - switch (gptype) - { + switch (gptype) + { case GPT_VERTEX_PROGRAM: mActiveVertexGpuProgramParameters = params; mCurrentVertexProgram->bindProgramParameters(params, mask); @@ -2184,13 +2184,13 @@ namespace Ogre { break; default: break; - } + } } void GLES2RenderSystem::bindGpuProgramPassIterationParameters(GpuProgramType gptype) { - switch (gptype) - { + switch (gptype) + { case GPT_VERTEX_PROGRAM: mCurrentVertexProgram->bindProgramPassIterationParameters(mActiveVertexGpuProgramParameters); break; @@ -2199,64 +2199,64 @@ namespace Ogre { break; default: break; - } + } } void GLES2RenderSystem::registerThread() - { - OGRE_LOCK_MUTEX(mThreadInitMutex); - // This is only valid once we've created the main context - if (!mMainContext) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + { + OGRE_LOCK_MUTEX(mThreadInitMutex); + // This is only valid once we've created the main context + if (!mMainContext) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot register a background thread before the main context " "has been created.", "GLES2RenderSystem::registerThread"); - } - - // Create a new context for this thread. Cloning from the main context - // will ensure that resources are shared with the main context - // We want a separate context so that we can safely create GL - // objects in parallel with the main thread - GLES2Context* newContext = mMainContext->clone(); - mBackgroundContextList.push_back(newContext); - - // Bind this new context to this thread. - newContext->setCurrent(); - - _oneTimeContextInitialization(); - newContext->setInitialized(); - } - - void GLES2RenderSystem::unregisterThread() - { - // nothing to do here? - // Don't need to worry about active context, just make sure we delete - // on shutdown. - } - - void GLES2RenderSystem::preExtraThreadsStarted() - { - OGRE_LOCK_MUTEX(mThreadInitMutex); - // free context, we'll need this to share lists + } + + // Create a new context for this thread. Cloning from the main context + // will ensure that resources are shared with the main context + // We want a separate context so that we can safely create GL + // objects in parallel with the main thread + GLES2Context* newContext = mMainContext->clone(); + mBackgroundContextList.push_back(newContext); + + // Bind this new context to this thread. + newContext->setCurrent(); + + _oneTimeContextInitialization(); + newContext->setInitialized(); + } + + void GLES2RenderSystem::unregisterThread() + { + // nothing to do here? + // Don't need to worry about active context, just make sure we delete + // on shutdown. + } + + void GLES2RenderSystem::preExtraThreadsStarted() + { + OGRE_LOCK_MUTEX(mThreadInitMutex); + // free context, we'll need this to share lists if(mCurrentContext) mCurrentContext->endCurrent(); - } + } - void GLES2RenderSystem::postExtraThreadsStarted() - { - OGRE_LOCK_MUTEX(mThreadInitMutex); - // reacquire context + void GLES2RenderSystem::postExtraThreadsStarted() + { + OGRE_LOCK_MUTEX(mThreadInitMutex); + // reacquire context if(mCurrentContext) mCurrentContext->setCurrent(); - } + } - unsigned int GLES2RenderSystem::getDisplayMonitorCount() const - { - return 1; - } + unsigned int GLES2RenderSystem::getDisplayMonitorCount() const + { + return 1; + } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void GLES2RenderSystem::beginProfileEvent( const String &eventName ) { if(mGLSupport->checkExtension("GL_EXT_debug_marker")) @@ -2277,7 +2277,7 @@ namespace Ogre { if(mGLSupport->checkExtension("GL_EXT_debug_marker")) glInsertEventMarkerEXT(0, eventName.c_str()); } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID void GLES2RenderSystem::resetRenderer(RenderWindow* win) { @@ -2303,7 +2303,7 @@ namespace Ogre { GLES2RenderSystem::mResourceManager->notifyOnContextReset(); - mStateCacheManager->clearCache(); + mStateCacheManager->clearCache(); _setViewport(NULL); _setRenderTarget(win); } @@ -2341,7 +2341,7 @@ namespace Ogre { // FIXME: Having this commented out fixes some rendering issues but leaves VAO's useless if (updateVAO) { - mStateCacheManager->bindGLBuffer(GL_ARRAY_BUFFER, + mStateCacheManager->bindGLBuffer(GL_ARRAY_BUFFER, hwGlBuffer->getGLBufferId()); pBufferData = VBO_BUFFER_OFFSET(elem.getOffset()); diff --git a/RenderSystems/GLES2/src/OgreGLES2RenderToVertexBuffer.cpp b/RenderSystems/GLES2/src/OgreGLES2RenderToVertexBuffer.cpp index 0cfec247d41..e1a466e62da 100644 --- a/RenderSystems/GLES2/src/OgreGLES2RenderToVertexBuffer.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2RenderToVertexBuffer.cpp @@ -43,98 +43,98 @@ THE SOFTWARE. namespace Ogre { //----------------------------------------------------------------------------- - static GLint getR2VBPrimitiveType(RenderOperation::OperationType operationType) - { - switch (operationType) - { - case RenderOperation::OT_POINT_LIST: - return GL_POINTS; - case RenderOperation::OT_LINE_LIST: - return GL_LINES; - case RenderOperation::OT_TRIANGLE_LIST: - return GL_TRIANGLES; - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "GL RenderToVertexBuffer" - "can only output point lists, line lists, or triangle lists", - "OgreGLES2RenderToVertexBuffer::getR2VBPrimitiveType"); - } - } + static GLint getR2VBPrimitiveType(RenderOperation::OperationType operationType) + { + switch (operationType) + { + case RenderOperation::OT_POINT_LIST: + return GL_POINTS; + case RenderOperation::OT_LINE_LIST: + return GL_LINES; + case RenderOperation::OT_TRIANGLE_LIST: + return GL_TRIANGLES; + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "GL RenderToVertexBuffer" + "can only output point lists, line lists, or triangle lists", + "OgreGLES2RenderToVertexBuffer::getR2VBPrimitiveType"); + } + } //----------------------------------------------------------------------------- - static GLint getVertexCountPerPrimitive(RenderOperation::OperationType operationType) - { - //We can only get points, lines or triangles since they are the only - //legal R2VB output primitive types - switch (operationType) - { - case RenderOperation::OT_POINT_LIST: - return 1; - case RenderOperation::OT_LINE_LIST: - return 2; - default: - case RenderOperation::OT_TRIANGLE_LIST: - return 3; - } - } + static GLint getVertexCountPerPrimitive(RenderOperation::OperationType operationType) + { + //We can only get points, lines or triangles since they are the only + //legal R2VB output primitive types + switch (operationType) + { + case RenderOperation::OT_POINT_LIST: + return 1; + case RenderOperation::OT_LINE_LIST: + return 2; + default: + case RenderOperation::OT_TRIANGLE_LIST: + return 3; + } + } //----------------------------------------------------------------------------- - GLES2RenderToVertexBuffer::GLES2RenderToVertexBuffer() : mFrontBufferIndex(-1) - { - mVertexBuffers[0].setNull(); - mVertexBuffers[1].setNull(); + GLES2RenderToVertexBuffer::GLES2RenderToVertexBuffer() : mFrontBufferIndex(-1) + { + mVertexBuffers[0].setNull(); + mVertexBuffers[1].setNull(); // Create query objects - OGRE_CHECK_GL_ERROR(glGenQueries(1, &mPrimitivesDrawnQuery)); - } + OGRE_CHECK_GL_ERROR(glGenQueries(1, &mPrimitivesDrawnQuery)); + } //----------------------------------------------------------------------------- - GLES2RenderToVertexBuffer::~GLES2RenderToVertexBuffer() - { - OGRE_CHECK_GL_ERROR(glDeleteQueries(1, &mPrimitivesDrawnQuery)); - } + GLES2RenderToVertexBuffer::~GLES2RenderToVertexBuffer() + { + OGRE_CHECK_GL_ERROR(glDeleteQueries(1, &mPrimitivesDrawnQuery)); + } //----------------------------------------------------------------------------- - void GLES2RenderToVertexBuffer::getRenderOperation(RenderOperation& op) - { - op.operationType = mOperationType; - op.useIndexes = false; - op.vertexData = mVertexData; - } + void GLES2RenderToVertexBuffer::getRenderOperation(RenderOperation& op) + { + op.operationType = mOperationType; + op.useIndexes = false; + op.vertexData = mVertexData; + } //----------------------------------------------------------------------------- - void GLES2RenderToVertexBuffer::update(SceneManager* sceneMgr) - { - size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; - if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) - { - // Buffers don't match. Need to reallocate. - mResetRequested = true; - } - - // Single pass only for now - Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); - // Set pass before binding buffers to activate the GPU programs - sceneMgr->_setPass(r2vbPass); - - bindVerticesOutput(r2vbPass); + void GLES2RenderToVertexBuffer::update(SceneManager* sceneMgr) + { + size_t bufSize = mVertexData->vertexDeclaration->getVertexSize(0) * mMaxVertexCount; + if (mVertexBuffers[0].isNull() || mVertexBuffers[0]->getSizeInBytes() != bufSize) + { + // Buffers don't match. Need to reallocate. + mResetRequested = true; + } + + // Single pass only for now + Ogre::Pass* r2vbPass = mMaterial->getBestTechnique()->getPass(0); + // Set pass before binding buffers to activate the GPU programs + sceneMgr->_setPass(r2vbPass); + + bindVerticesOutput(r2vbPass); - RenderOperation renderOp; - size_t targetBufferIndex; - if (mResetRequested || mResetsEveryUpdate) - { - // Use source data to render to first buffer - mSourceRenderable->getRenderOperation(renderOp); - targetBufferIndex = 0; - } - else - { - // Use current front buffer to render to back buffer - this->getRenderOperation(renderOp); - targetBufferIndex = 1 - mFrontBufferIndex; - } + RenderOperation renderOp; + size_t targetBufferIndex; + if (mResetRequested || mResetsEveryUpdate) + { + // Use source data to render to first buffer + mSourceRenderable->getRenderOperation(renderOp); + targetBufferIndex = 0; + } + else + { + // Use current front buffer to render to back buffer + this->getRenderOperation(renderOp); + targetBufferIndex = 1 - mFrontBufferIndex; + } - if (mVertexBuffers[targetBufferIndex].isNull() || - mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) - { - reallocateBuffer(targetBufferIndex); - } + if (mVertexBuffers[targetBufferIndex].isNull() || + mVertexBuffers[targetBufferIndex]->getSizeInBytes() != bufSize) + { + reallocateBuffer(targetBufferIndex); + } - GLES2HardwareVertexBuffer* vertexBuffer = static_cast(mVertexBuffers[targetBufferIndex].getPointer()); + GLES2HardwareVertexBuffer* vertexBuffer = static_cast(mVertexBuffers[targetBufferIndex].getPointer()); /* if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLESProgramPipeline* programPipeline = @@ -146,114 +146,114 @@ namespace Ogre { GLSLESLinkProgram* linkProgram = GLSLESLinkProgramManager::getSingleton().getActiveLinkProgram(); linkProgram->getVertexArrayObject()->bind(); } - */ - // Bind the target buffer - OGRE_CHECK_GL_ERROR(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vertexBuffer->getGLBufferId())); + */ + // Bind the target buffer + OGRE_CHECK_GL_ERROR(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vertexBuffer->getGLBufferId())); // Disable rasterization OGRE_CHECK_GL_ERROR(glEnable(GL_RASTERIZER_DISCARD)); - RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); - // Draw the object - targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); - targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); - targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); - if (r2vbPass->hasVertexProgram()) - { - targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, + RenderSystem* targetRenderSystem = Root::getSingleton().getRenderSystem(); + // Draw the object + targetRenderSystem->_setWorldMatrix(Matrix4::IDENTITY); + targetRenderSystem->_setViewMatrix(Matrix4::IDENTITY); + targetRenderSystem->_setProjectionMatrix(Matrix4::IDENTITY); + if (r2vbPass->hasVertexProgram()) + { + targetRenderSystem->bindGpuProgramParameters(GPT_VERTEX_PROGRAM, r2vbPass->getVertexProgramParameters(), GPV_ALL); - } - if (r2vbPass->hasFragmentProgram()) - { - targetRenderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, + } + if (r2vbPass->hasFragmentProgram()) + { + targetRenderSystem->bindGpuProgramParameters(GPT_FRAGMENT_PROGRAM, r2vbPass->getFragmentProgramParameters(), GPV_ALL); - } - if (r2vbPass->hasGeometryProgram()) - { - targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, + } + if (r2vbPass->hasGeometryProgram()) + { + targetRenderSystem->bindGpuProgramParameters(GPT_GEOMETRY_PROGRAM, r2vbPass->getGeometryProgramParameters(), GPV_ALL); - } + } OGRE_CHECK_GL_ERROR(glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mPrimitivesDrawnQuery)); - OGRE_CHECK_GL_ERROR(glBeginTransformFeedback(getR2VBPrimitiveType(mOperationType))); + OGRE_CHECK_GL_ERROR(glBeginTransformFeedback(getR2VBPrimitiveType(mOperationType))); - targetRenderSystem->_render(renderOp); - - OGRE_CHECK_GL_ERROR(glEndTransformFeedback()); + targetRenderSystem->_render(renderOp); + + OGRE_CHECK_GL_ERROR(glEndTransformFeedback()); - // Finish the query - OGRE_CHECK_GL_ERROR(glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)); + // Finish the query + OGRE_CHECK_GL_ERROR(glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)); - OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD)); + OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD)); - // Read back query results - GLuint primitivesWritten; - OGRE_CHECK_GL_ERROR(glGetQueryObjectuiv(mPrimitivesDrawnQuery, GL_QUERY_RESULT, &primitivesWritten)); - mVertexData->vertexCount = primitivesWritten * getVertexCountPerPrimitive(mOperationType); + // Read back query results + GLuint primitivesWritten; + OGRE_CHECK_GL_ERROR(glGetQueryObjectuiv(mPrimitivesDrawnQuery, GL_QUERY_RESULT, &primitivesWritten)); + mVertexData->vertexCount = primitivesWritten * getVertexCountPerPrimitive(mOperationType); - // Switch the vertex binding if necessary - if (targetBufferIndex != mFrontBufferIndex) - { - mVertexData->vertexBufferBinding->unsetAllBindings(); - mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); - mFrontBufferIndex = targetBufferIndex; - } + // Switch the vertex binding if necessary + if (targetBufferIndex != mFrontBufferIndex) + { + mVertexData->vertexBufferBinding->unsetAllBindings(); + mVertexData->vertexBufferBinding->setBinding(0, mVertexBuffers[targetBufferIndex]); + mFrontBufferIndex = targetBufferIndex; + } // Enable rasterization - OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD)); + OGRE_CHECK_GL_ERROR(glDisable(GL_RASTERIZER_DISCARD)); - // Clear the reset flag - mResetRequested = false; - } + // Clear the reset flag + mResetRequested = false; + } //----------------------------------------------------------------------------- - void GLES2RenderToVertexBuffer::reallocateBuffer(size_t index) - { - assert(index == 0 || index == 1); - if (!mVertexBuffers[index].isNull()) - { - mVertexBuffers[index].setNull(); - } - - mVertexBuffers[index] = HardwareBufferManager::getSingleton().createVertexBuffer( - mVertexData->vertexDeclaration->getVertexSize(0), mMaxVertexCount, + void GLES2RenderToVertexBuffer::reallocateBuffer(size_t index) + { + assert(index == 0 || index == 1); + if (!mVertexBuffers[index].isNull()) + { + mVertexBuffers[index].setNull(); + } + + mVertexBuffers[index] = HardwareBufferManager::getSingleton().createVertexBuffer( + mVertexData->vertexDeclaration->getVertexSize(0), mMaxVertexCount, #if OGRE_DEBUG_MODE - //Allow to read the contents of the buffer in debug mode - HardwareBuffer::HBU_DYNAMIC + //Allow to read the contents of the buffer in debug mode + HardwareBuffer::HBU_DYNAMIC #else - HardwareBuffer::HBU_STATIC_WRITE_ONLY + HardwareBuffer::HBU_STATIC_WRITE_ONLY #endif - ); - } + ); + } //----------------------------------------------------------------------------- - String GLES2RenderToVertexBuffer::getSemanticVaryingName(VertexElementSemantic semantic, unsigned short index) - { - switch (semantic) - { - case VES_POSITION: + String GLES2RenderToVertexBuffer::getSemanticVaryingName(VertexElementSemantic semantic, unsigned short index) + { + switch (semantic) + { + case VES_POSITION: return "gl_Position"; - case VES_TEXTURE_COORDINATES: - return String("oUv") + StringConverter::toString(index); - case VES_DIFFUSE: - return "oColour"; - case VES_SPECULAR: - return "oSecColour"; - //TODO : Implement more? - default: - OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, - "Unsupported vertex element sematic in render to vertex buffer", - "OgreGLES2RenderToVertexBuffer::getSemanticVaryingName"); - } - } + case VES_TEXTURE_COORDINATES: + return String("oUv") + StringConverter::toString(index); + case VES_DIFFUSE: + return "oColour"; + case VES_SPECULAR: + return "oSecColour"; + //TODO : Implement more? + default: + OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, + "Unsupported vertex element sematic in render to vertex buffer", + "OgreGLES2RenderToVertexBuffer::getSemanticVaryingName"); + } + } //----------------------------------------------------------------------------- - void GLES2RenderToVertexBuffer::bindVerticesOutput(Pass* pass) - { - VertexDeclaration* declaration = mVertexData->vertexDeclaration; + void GLES2RenderToVertexBuffer::bindVerticesOutput(Pass* pass) + { + VertexDeclaration* declaration = mVertexData->vertexDeclaration; size_t elemCount = declaration->getElementCount(); - if (elemCount > 0) - { + if (elemCount > 0) + { GLuint linkProgramId = 0; - // Have GLSL shaders, using varying attributes + // Have GLSL shaders, using varying attributes if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) { GLSLESProgramPipeline* programPipeline = @@ -270,16 +270,16 @@ namespace Ogre { // So we are using it. Otherwise we could query during rendersystem initialisation and use a dynamic sized array. // But that would require C99. const GLchar *names[64]; - for (unsigned short e = 0; e < elemCount; e++) - { - const VertexElement* element = declaration->getElement(e); - String varyingName = getSemanticVaryingName(element->getSemantic(), element->getIndex()); + for (unsigned short e = 0; e < elemCount; e++) + { + const VertexElement* element = declaration->getElement(e); + String varyingName = getSemanticVaryingName(element->getSemantic(), element->getIndex()); names[e] = varyingName.c_str(); - } + } - OGRE_CHECK_GL_ERROR(glTransformFeedbackVaryings(linkProgramId, elemCount, names, GL_INTERLEAVED_ATTRIBS)); + OGRE_CHECK_GL_ERROR(glTransformFeedbackVaryings(linkProgramId, elemCount, names, GL_INTERLEAVED_ATTRIBS)); OGRE_CHECK_GL_ERROR(glLinkProgram(linkProgramId)); - } - } + } + } } #endif diff --git a/RenderSystems/GLES2/src/OgreGLES2StateCacheManager.cpp b/RenderSystems/GLES2/src/OgreGLES2StateCacheManager.cpp index 1c964a96a56..095b911de18 100644 --- a/RenderSystems/GLES2/src/OgreGLES2StateCacheManager.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2StateCacheManager.cpp @@ -97,9 +97,9 @@ namespace Ogre { } bool GLES2StateCacheManager::activateGLTextureUnit(unsigned char unit) - { + { return mImp->activateGLTextureUnit(unit); - } + } void GLES2StateCacheManager::setBlendFunc(GLenum source, GLenum dest) { diff --git a/RenderSystems/GLES2/src/OgreGLES2Texture.cpp b/RenderSystems/GLES2/src/OgreGLES2Texture.cpp index a9c3e88b203..3ac274a0eda 100644 --- a/RenderSystems/GLES2/src/OgreGLES2Texture.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2Texture.cpp @@ -117,11 +117,11 @@ namespace Ogre { mDepth = GLES2PixelUtil::optionalPO2(mDepth); } - // Adjust format if required + // Adjust format if required mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage); GLenum texTarget = getGLES2TextureTarget(); - // Check requested number of mipmaps + // Check requested number of mipmaps size_t maxMips = GLES2PixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat); if(PixelUtil::isCompressed(mFormat) && (mNumMipmaps == 0)) @@ -131,11 +131,11 @@ namespace Ogre { if (mNumMipmaps > maxMips) mNumMipmaps = maxMips; - // Generate texture name + // Generate texture name OGRE_CHECK_GL_ERROR(glGenTextures(1, &mTextureID)); - // Set texture type - mGLSupport.getStateCacheManager()->bindGLTexture(texTarget, mTextureID); + // Set texture type + mGLSupport.getStateCacheManager()->bindGLTexture(texTarget, mTextureID); // If we can do automip generation and the user desires this, do so mMipmapsHardwareGenerated = @@ -146,13 +146,13 @@ namespace Ogre { // glGenerateMipmap require all mip levels to be prepared. So override how many this texture has. if((mUsage & TU_AUTOMIPMAP) && mMipmapsHardwareGenerated && mNumRequestedMipmaps) - mNumMipmaps = maxMips; + mNumMipmaps = maxMips; if(getGLES2SupportRef()->checkExtension("GL_APPLE_texture_max_level") || gleswIsSupported(3, 0)) - mGLSupport.getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MAX_LEVEL_APPLE, mNumRequestedMipmaps ? mNumMipmaps + 1 : 0); + mGLSupport.getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MAX_LEVEL_APPLE, mNumRequestedMipmaps ? mNumMipmaps + 1 : 0); - // Set some misc default parameters, these can of course be changed later - mGLSupport.getStateCacheManager()->setTexParameteri(texTarget, + // Set some misc default parameters, these can of course be changed later + mGLSupport.getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, ((mUsage & TU_AUTOMIPMAP) && mNumRequestedMipmaps) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST); mGLSupport.getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -211,10 +211,10 @@ namespace Ogre { #endif size = static_cast(PixelUtil::getMemorySize(width, height, depth, mFormat)); - switch(mTextureType) - { - case TEX_TYPE_1D: - case TEX_TYPE_2D: + switch(mTextureType) + { + case TEX_TYPE_1D: + case TEX_TYPE_2D: OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_2D, mip, internalformat, @@ -223,20 +223,20 @@ namespace Ogre { size, tmpdata)); break; - case TEX_TYPE_CUBE_MAP: - for(int face = 0; face < 6; face++) { - OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, internalformat, - width, height, 0, - size, tmpdata)); - } - break; + case TEX_TYPE_CUBE_MAP: + for(int face = 0; face < 6; face++) { + OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, internalformat, + width, height, 0, + size, tmpdata)); + } + break; #if OGRE_NO_GLES3_SUPPORT == 0 - case TEX_TYPE_2D_ARRAY: - case TEX_TYPE_3D: - glCompressedTexImage3D(getGLES2TextureTarget(), mip, format, - width, height, depth, 0, - size, tmpdata); - break; + case TEX_TYPE_2D_ARRAY: + case TEX_TYPE_3D: + glCompressedTexImage3D(getGLES2TextureTarget(), mip, format, + width, height, depth, 0, + size, tmpdata); + break; #endif default: break; @@ -250,7 +250,7 @@ namespace Ogre { { height = height / 2; } - if(depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY) + if(depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY) { depth = depth / 2; } @@ -301,11 +301,11 @@ namespace Ogre { " Datatype: " + StringConverter::toString(datatype, 0, ' ', std::ios::hex) ); #endif - // Normal formats - switch(mTextureType) - { - case TEX_TYPE_1D: - case TEX_TYPE_2D: + // Normal formats + switch(mTextureType) + { + case TEX_TYPE_1D: + case TEX_TYPE_2D: #if OGRE_PLATFORM == OGRE_PLATFORM_NACL if(internalformat != format) { @@ -322,13 +322,13 @@ namespace Ogre { format, datatype, 0)); break; - case TEX_TYPE_CUBE_MAP: - for(int face = 0; face < 6; face++) { - OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, internalformat, - width, height, 0, - format, datatype, 0)); - } - break; + case TEX_TYPE_CUBE_MAP: + for(int face = 0; face < 6; face++) { + OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, internalformat, + width, height, 0, + format, datatype, 0)); + } + break; default: break; }; @@ -349,7 +349,7 @@ namespace Ogre { // Creation / loading methods void GLES2Texture::createInternalResourcesImpl(void) { - _createGLTexResource(); + _createGLTexResource(); _createSurfaceList(); @@ -394,9 +394,9 @@ namespace Ogre { if((*loadedImages)[0].getDepth() > 1 && mTextureType != TEX_TYPE_2D_ARRAY) mTextureType = TEX_TYPE_3D; - // If PVRTC and 0 custom mipmap disable auto mip generation and disable software mipmap creation - if (PixelUtil::isCompressed((*loadedImages)[0].getFormat())) - { + // If PVRTC and 0 custom mipmap disable auto mip generation and disable software mipmap creation + if (PixelUtil::isCompressed((*loadedImages)[0].getFormat())) + { size_t imageMips = (*loadedImages)[0].getNumMipmaps(); if (imageMips == 0) { @@ -404,7 +404,7 @@ namespace Ogre { // Disable flag for auto mip generation mUsage &= ~TU_AUTOMIPMAP; } - } + } } else if (mTextureType == TEX_TYPE_CUBE_MAP) { @@ -539,9 +539,9 @@ namespace Ogre { for (size_t face = 0; face < getNumFaces(); face++) { - uint32 width = mWidth; - uint32 height = mHeight; - uint32 depth = mDepth; + uint32 width = mWidth; + uint32 height = mHeight; + uint32 depth = mDepth; for (uint8 mip = 0; mip <= getNumMipmaps(); mip++) { diff --git a/RenderSystems/GLES2/src/OgreGLES2TextureManager.cpp b/RenderSystems/GLES2/src/OgreGLES2TextureManager.cpp index 2ef65d2d148..38a1d1d7c9e 100644 --- a/RenderSystems/GLES2/src/OgreGLES2TextureManager.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2TextureManager.cpp @@ -94,9 +94,9 @@ namespace Ogre { // if a compressed format not supported, revert to PF_A8R8G8B8 if (PixelUtil::isCompressed(format) && !caps->hasCapability(RSC_TEXTURE_COMPRESSION_DXT) && - !caps->hasCapability(RSC_TEXTURE_COMPRESSION_PVRTC) && - !caps->hasCapability(RSC_TEXTURE_COMPRESSION_ATC) && - !caps->hasCapability(RSC_TEXTURE_COMPRESSION_ETC1)) + !caps->hasCapability(RSC_TEXTURE_COMPRESSION_PVRTC) && + !caps->hasCapability(RSC_TEXTURE_COMPRESSION_ATC) && + !caps->hasCapability(RSC_TEXTURE_COMPRESSION_ETC1)) { return PF_A8R8G8B8; } diff --git a/RenderSystems/GLES2/src/OgreGLES2VertexDeclaration.cpp b/RenderSystems/GLES2/src/OgreGLES2VertexDeclaration.cpp index 6cfdf4fb373..ab6fe8c461b 100644 --- a/RenderSystems/GLES2/src/OgreGLES2VertexDeclaration.cpp +++ b/RenderSystems/GLES2/src/OgreGLES2VertexDeclaration.cpp @@ -32,12 +32,12 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - GLES2VertexDeclaration::GLES2VertexDeclaration() + //----------------------------------------------------------------------- + GLES2VertexDeclaration::GLES2VertexDeclaration() : mVAO(0), mIsInitialised(false) - { + { #if OGRE_NO_GLES2_VAO_SUPPORT == 0 # if defined(GL_OES_vertex_array_object) || (OGRE_NO_GLES3_SUPPORT == 0) OGRE_CHECK_GL_ERROR(glGenVertexArraysOES(1, &mVAO)); @@ -51,20 +51,20 @@ namespace Ogre { } # endif #endif - } + } - //----------------------------------------------------------------------- - GLES2VertexDeclaration::~GLES2VertexDeclaration() - { + //----------------------------------------------------------------------- + GLES2VertexDeclaration::~GLES2VertexDeclaration() + { #if OGRE_NO_GLES2_VAO_SUPPORT == 0 # if defined(GL_OES_vertex_array_object) || (OGRE_NO_GLES3_SUPPORT == 0) // LogManager::getSingleton().logMessage("Deleting VAO " + StringConverter::toString(mVAO)); OGRE_CHECK_GL_ERROR(glDeleteVertexArraysOES(1, &mVAO)); # endif #endif - } + } - //----------------------------------------------------------------------- + //----------------------------------------------------------------------- void GLES2VertexDeclaration::bind(void) { #if OGRE_NO_GLES2_VAO_SUPPORT == 0 diff --git a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2NullStateCacheManagerImp.cpp b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2NullStateCacheManagerImp.cpp index 046515184ac..fd12bdd7ac7 100644 --- a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2NullStateCacheManagerImp.cpp +++ b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2NullStateCacheManagerImp.cpp @@ -88,7 +88,7 @@ namespace Ogre { mDiscardBuffers = 0; mClearDepth = 1.0f; - mClearColour.resize(4); + mClearColour.resize(4); mClearColour[0] = mClearColour[1] = mClearColour[2] = mClearColour[3] = 0.0f; mColourMask.resize(4); @@ -157,7 +157,7 @@ namespace Ogre { } bool GLES2StateCacheManagerImp::activateGLTextureUnit(unsigned char unit) - { + { // Always return true for the currently bound texture unit if (mActiveTextureUnit == unit) return true; @@ -174,7 +174,7 @@ namespace Ogre { { return false; } - } + } void GLES2StateCacheManagerImp::setBlendFunc(GLenum source, GLenum dest) { diff --git a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2NullStateCacheManagerImp.h b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2NullStateCacheManagerImp.h index 37b7d6b254c..30dbdcedb9d 100644 --- a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2NullStateCacheManagerImp.h +++ b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2NullStateCacheManagerImp.h @@ -73,7 +73,7 @@ namespace Ogre /// See GLES2StateCacheManager.clearCache. void clearCache(); - + /// See GLES2StateCacheManager.bindGLBuffer. void bindGLBuffer(GLenum target, GLuint buffer, bool force = false); diff --git a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2StateCacheManagerImp.cpp b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2StateCacheManagerImp.cpp index 94943c02232..d4073e83a9c 100644 --- a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2StateCacheManagerImp.cpp +++ b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2StateCacheManagerImp.cpp @@ -116,23 +116,23 @@ namespace Ogre { void GLES2StateCacheManagerImp::bindGLBuffer(GLenum target, GLuint buffer, GLenum attach, bool force) { - bool update = false; + bool update = false; BindBufferMap::iterator i = mActiveBufferMap.find(target); if (i == mActiveBufferMap.end()) { // Haven't cached this state yet. Insert it into the map mActiveBufferMap.insert(BindBufferMap::value_type(target, buffer)); - update = true; + update = true; } else if((*i).second != buffer || force) // Update the cached value if needed { - (*i).second = buffer; - update = true; + (*i).second = buffer; + update = true; } - // Update GL - if(update) - { + // Update GL + if(update) + { if(target == GL_FRAMEBUFFER) { OGRE_CHECK_GL_ERROR(glBindFramebuffer(target, buffer)); @@ -145,7 +145,7 @@ namespace Ogre { { OGRE_CHECK_GL_ERROR(glBindBuffer(target, buffer)); } - } + } } void GLES2StateCacheManagerImp::deleteGLBuffer(GLenum target, GLuint buffer, GLenum attach, bool force) @@ -158,17 +158,17 @@ namespace Ogre { if (i != mActiveBufferMap.end() && ((*i).second == buffer || force)) { - if(target == GL_FRAMEBUFFER) + if(target == GL_FRAMEBUFFER) { - OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &buffer)); + OGRE_CHECK_GL_ERROR(glDeleteFramebuffers(1, &buffer)); } else if(target == GL_RENDERBUFFER) { - OGRE_CHECK_GL_ERROR(glDeleteRenderbuffers(1, &buffer)); + OGRE_CHECK_GL_ERROR(glDeleteRenderbuffers(1, &buffer)); } else { - OGRE_CHECK_GL_ERROR(glDeleteBuffers(1, &buffer)); + OGRE_CHECK_GL_ERROR(glDeleteBuffers(1, &buffer)); } // Currently bound buffer is being deleted, update the cached value to 0, @@ -280,30 +280,30 @@ namespace Ogre { } bool GLES2StateCacheManagerImp::activateGLTextureUnit(size_t unit) - { - if (mActiveTextureUnit != unit) - { - if (unit < dynamic_cast(Root::getSingleton().getRenderSystem())->getCapabilities()->getNumTextureUnits()) - { - OGRE_CHECK_GL_ERROR(glActiveTexture(GL_TEXTURE0 + unit)); - mActiveTextureUnit = unit; - return true; - } - else if (!unit) - { - // always ok to use the first unit - return true; - } - else - { - return false; - } - } - else - { - return true; - } - } + { + if (mActiveTextureUnit != unit) + { + if (unit < dynamic_cast(Root::getSingleton().getRenderSystem())->getCapabilities()->getNumTextureUnits()) + { + OGRE_CHECK_GL_ERROR(glActiveTexture(GL_TEXTURE0 + unit)); + mActiveTextureUnit = unit; + return true; + } + else if (!unit) + { + // always ok to use the first unit + return true; + } + else + { + return false; + } + } + else + { + return true; + } + } // TODO: Store as high/low bits of a GLuint void GLES2StateCacheManagerImp::setBlendFunc(GLenum source, GLenum dest) diff --git a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2StateCacheManagerImp.h b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2StateCacheManagerImp.h index 6609479a15b..7b0b66cd517 100644 --- a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2StateCacheManagerImp.h +++ b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2StateCacheManagerImp.h @@ -92,7 +92,7 @@ namespace Ogre GLenum mDepthFunc; /// Stores the current stencil mask GLuint mStencilMask; - /// Stores the last bound texture id + /// Stores the last bound texture id GLuint mLastBoundTexID; /// Stores the currently active texture unit GLenum mActiveTextureUnit; @@ -110,7 +110,7 @@ namespace Ogre /// See GLES2StateCacheManager.clearCache. void clearCache(); - + /// See GLES2StateCacheManager.bindGLBuffer. void bindGLBuffer(GLenum target, GLuint buffer, GLenum attach = 0, bool force = false); diff --git a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2UniformCacheImp.cpp b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2UniformCacheImp.cpp index 4426a06dec9..23205ff87c8 100644 --- a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2UniformCacheImp.cpp +++ b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2UniformCacheImp.cpp @@ -56,7 +56,7 @@ namespace Ogre { { // Haven't cached this state yet or the value has changed mUniformValueMap[location] = hash; - return true; + return true; } return false; diff --git a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2UniformCacheImp.h b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2UniformCacheImp.h index bdf14385961..b5272cdf1d6 100644 --- a/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2UniformCacheImp.h +++ b/RenderSystems/GLES2/src/StateCacheManager/OgreGLES2UniformCacheImp.h @@ -52,7 +52,7 @@ namespace Ogre /// Clear out the cache void clearCache(); - + /** Update a uniform @return A boolean value indicating whether this uniform needs to be updated in the GL. */ diff --git a/RenderSystems/GLES2/src/gles2w.cpp b/RenderSystems/GLES2/src/gles2w.cpp index 355e73e2ded..6380c821601 100644 --- a/RenderSystems/GLES2/src/gles2w.cpp +++ b/RenderSystems/GLES2/src/gles2w.cpp @@ -9,22 +9,22 @@ static HMODULE libgl; static void open_libgl(void) { - libgl = LoadLibraryA("libGLESv2.dll"); + libgl = LoadLibraryA("libGLESv2.dll"); } static void close_libgl(void) { - FreeLibrary(libgl); + FreeLibrary(libgl); } static void *get_proc(const char *proc) { - void *res; + void *res; - res = eglGetProcAddress(proc); - if (!res) - res = GetProcAddress(libgl, proc); - return res; + res = eglGetProcAddress(proc); + if (!res) + res = GetProcAddress(libgl, proc); + return res; } #elif defined(__APPLE__) || defined(__APPLE_CC__) #import @@ -41,8 +41,8 @@ std::string exec(const char* cmd) { char buffer[128]; std::string result = ""; while(!feof(pipe)) { - if(fgets(buffer, 128, pipe) != NULL) - result += buffer; + if(fgets(buffer, 128, pipe) != NULL) + result += buffer; } pclose(pipe); return result; @@ -76,32 +76,32 @@ static void open_libgl(void) frameworkPath = CFStringCreateWithCString(kCFAllocatorDefault, tempPath, kCFStringEncodingUTF8); } - bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, frameworkPath, kCFURLPOSIXPathStyle, true); CFRelease(frameworkPath); - bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); + bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); - assert(bundle != NULL); + assert(bundle != NULL); } static void close_libgl(void) { - CFRelease(bundle); - CFRelease(bundleURL); + CFRelease(bundle); + CFRelease(bundleURL); } static void *get_proc(const char *proc) { - void *res; + void *res; - CFStringRef procname = CFStringCreateWithCString(kCFAllocatorDefault, proc, + CFStringRef procname = CFStringCreateWithCString(kCFAllocatorDefault, proc, kCFStringEncodingASCII); - res = CFBundleGetFunctionPointerForName(bundle, procname); - CFRelease(procname); - return res; + res = CFBundleGetFunctionPointerForName(bundle, procname); + CFRelease(procname); + return res; } #else #include @@ -111,24 +111,24 @@ static void *libgl; static void open_libgl(void) { - libgl = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_GLOBAL); + libgl = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_GLOBAL); } static void close_libgl(void) { - dlclose(libgl); + dlclose(libgl); } static void *get_proc(const char *proc) { - void *res; + void *res; res = dlsym(libgl, proc); - return res; + return res; } #endif static struct { - int major, minor; + int major, minor; } version; static int parse_version(void) @@ -136,31 +136,31 @@ static int parse_version(void) version.major = 2; version.minor = 0; - return 0; + return 0; } static void load_procs(void); int gleswInit(void) { - open_libgl(); - load_procs(); - close_libgl(); - return parse_version(); + open_libgl(); + load_procs(); + close_libgl(); + return parse_version(); } int gleswIsSupported(int major, int minor) { - if (major < 2) - return 0; - if (version.major == major) - return version.minor >= minor; - return version.major >= major; + if (major < 2) + return 0; + if (version.major == major) + return version.minor >= minor; + return version.major >= major; } void *gleswGetProcAddress(const char *proc) { - return get_proc(proc); + return get_proc(proc); } PFNGLACTIVETEXTUREPROC gleswActiveTexture; @@ -469,307 +469,307 @@ PFNGLENDTILINGQCOMPROC gleswEndTilingQCOM; static void load_procs(void) { - gleswActiveTexture = (PFNGLACTIVETEXTUREPROC) get_proc("glActiveTexture"); - gleswAttachShader = (PFNGLATTACHSHADERPROC) get_proc("glAttachShader"); - gleswBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) get_proc("glBindAttribLocation"); - gleswBindBuffer = (PFNGLBINDBUFFERPROC) get_proc("glBindBuffer"); - gleswBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) get_proc("glBindFramebuffer"); - gleswBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) get_proc("glBindRenderbuffer"); - gleswBindTexture = (PFNGLBINDTEXTUREPROC) get_proc("glBindTexture"); - gleswBlendColor = (PFNGLBLENDCOLORPROC) get_proc("glBlendColor"); - gleswBlendEquation = (PFNGLBLENDEQUATIONPROC) get_proc("glBlendEquation"); - gleswBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) get_proc("glBlendEquationSeparate"); - gleswBlendFunc = (PFNGLBLENDFUNCPROC) get_proc("glBlendFunc"); - gleswBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) get_proc("glBlendFuncSeparate"); - gleswBufferData = (PFNGLBUFFERDATAPROC) get_proc("glBufferData"); - gleswBufferSubData = (PFNGLBUFFERSUBDATAPROC) get_proc("glBufferSubData"); - gleswCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) get_proc("glCheckFramebufferStatus"); - gleswClear = (PFNGLCLEARPROC) get_proc("glClear"); - gleswClearColor = (PFNGLCLEARCOLORPROC) get_proc("glClearColor"); - gleswClearDepthf = (PFNGLCLEARDEPTHFPROC) get_proc("glClearDepthf"); - gleswClearStencil = (PFNGLCLEARSTENCILPROC) get_proc("glClearStencil"); - gleswColorMask = (PFNGLCOLORMASKPROC) get_proc("glColorMask"); - gleswCompileShader = (PFNGLCOMPILESHADERPROC) get_proc("glCompileShader"); - gleswCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) get_proc("glCompressedTexImage2D"); - gleswCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) get_proc("glCompressedTexSubImage2D"); - gleswCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) get_proc("glCopyTexImage2D"); - gleswCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) get_proc("glCopyTexSubImage2D"); - gleswCreateProgram = (PFNGLCREATEPROGRAMPROC) get_proc("glCreateProgram"); - gleswCreateShader = (PFNGLCREATESHADERPROC) get_proc("glCreateShader"); - gleswCullFace = (PFNGLCULLFACEPROC) get_proc("glCullFace"); - gleswDeleteBuffers = (PFNGLDELETEBUFFERSPROC) get_proc("glDeleteBuffers"); - gleswDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) get_proc("glDeleteFramebuffers"); - gleswDeleteProgram = (PFNGLDELETEPROGRAMPROC) get_proc("glDeleteProgram"); - gleswDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) get_proc("glDeleteRenderbuffers"); - gleswDeleteShader = (PFNGLDELETESHADERPROC) get_proc("glDeleteShader"); - gleswDeleteTextures = (PFNGLDELETETEXTURESPROC) get_proc("glDeleteTextures"); - gleswDepthFunc = (PFNGLDEPTHFUNCPROC) get_proc("glDepthFunc"); - gleswDepthMask = (PFNGLDEPTHMASKPROC) get_proc("glDepthMask"); - gleswDepthRangef = (PFNGLDEPTHRANGEFPROC) get_proc("glDepthRangef"); - gleswDetachShader = (PFNGLDETACHSHADERPROC) get_proc("glDetachShader"); - gleswDisable = (PFNGLDISABLEPROC) get_proc("glDisable"); - gleswDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) get_proc("glDisableVertexAttribArray"); - gleswDrawArrays = (PFNGLDRAWARRAYSPROC) get_proc("glDrawArrays"); - gleswDrawElements = (PFNGLDRAWELEMENTSPROC) get_proc("glDrawElements"); - gleswEnable = (PFNGLENABLEPROC) get_proc("glEnable"); - gleswEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) get_proc("glEnableVertexAttribArray"); - gleswFinish = (PFNGLFINISHPROC) get_proc("glFinish"); - gleswFlush = (PFNGLFLUSHPROC) get_proc("glFlush"); - gleswFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) get_proc("glFramebufferRenderbuffer"); - gleswFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) get_proc("glFramebufferTexture2D"); - gleswFrontFace = (PFNGLFRONTFACEPROC) get_proc("glFrontFace"); - gleswGenBuffers = (PFNGLGENBUFFERSPROC) get_proc("glGenBuffers"); - gleswGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) get_proc("glGenerateMipmap"); - gleswGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) get_proc("glGenFramebuffers"); - gleswGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) get_proc("glGenRenderbuffers"); - gleswGenTextures = (PFNGLGENTEXTURESPROC) get_proc("glGenTextures"); - gleswGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) get_proc("glGetActiveAttrib"); - gleswGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) get_proc("glGetActiveUniform"); - gleswGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) get_proc("glGetAttachedShaders"); - gleswGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) get_proc("glGetAttribLocation"); - gleswGetBooleanv = (PFNGLGETBOOLEANVPROC) get_proc("glGetBooleanv"); - gleswGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) get_proc("glGetBufferParameteriv"); - gleswGetError = (PFNGLGETERRORPROC) get_proc("glGetError"); - gleswGetFloatv = (PFNGLGETFLOATVPROC) get_proc("glGetFloatv"); - gleswGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) get_proc("glGetFramebufferAttachmentParameteriv"); - gleswGetIntegerv = (PFNGLGETINTEGERVPROC) get_proc("glGetIntegerv"); - gleswGetProgramiv = (PFNGLGETPROGRAMIVPROC) get_proc("glGetProgramiv"); - gleswGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) get_proc("glGetProgramInfoLog"); - gleswGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) get_proc("glGetRenderbufferParameteriv"); - gleswGetShaderiv = (PFNGLGETSHADERIVPROC) get_proc("glGetShaderiv"); - gleswGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) get_proc("glGetShaderInfoLog"); - gleswGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) get_proc("glGetShaderPrecisionFormat"); - gleswGetShaderSource = (PFNGLGETSHADERSOURCEPROC) get_proc("glGetShaderSource"); - gleswGetString = (PFNGLGETSTRINGPROC) get_proc("glGetString"); - gleswGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) get_proc("glGetTexParameterfv"); - gleswGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) get_proc("glGetTexParameteriv"); - gleswGetUniformfv = (PFNGLGETUNIFORMFVPROC) get_proc("glGetUniformfv"); - gleswGetUniformiv = (PFNGLGETUNIFORMIVPROC) get_proc("glGetUniformiv"); - gleswGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) get_proc("glGetUniformLocation"); - gleswGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) get_proc("glGetVertexAttribfv"); - gleswGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) get_proc("glGetVertexAttribiv"); - gleswGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) get_proc("glGetVertexAttribPointerv"); - gleswHint = (PFNGLHINTPROC) get_proc("glHint"); - gleswIsBuffer = (PFNGLISBUFFERPROC) get_proc("glIsBuffer"); - gleswIsEnabled = (PFNGLISENABLEDPROC) get_proc("glIsEnabled"); - gleswIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) get_proc("glIsFramebuffer"); - gleswIsProgram = (PFNGLISPROGRAMPROC) get_proc("glIsProgram"); - gleswIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) get_proc("glIsRenderbuffer"); - gleswIsShader = (PFNGLISSHADERPROC) get_proc("glIsShader"); - gleswIsTexture = (PFNGLISTEXTUREPROC) get_proc("glIsTexture"); - gleswLineWidth = (PFNGLLINEWIDTHPROC) get_proc("glLineWidth"); - gleswLinkProgram = (PFNGLLINKPROGRAMPROC) get_proc("glLinkProgram"); - gleswPixelStorei = (PFNGLPIXELSTOREIPROC) get_proc("glPixelStorei"); - gleswPolygonOffset = (PFNGLPOLYGONOFFSETPROC) get_proc("glPolygonOffset"); - gleswReadPixels = (PFNGLREADPIXELSPROC) get_proc("glReadPixels"); - gleswReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) get_proc("glReleaseShaderCompiler"); - gleswRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) get_proc("glRenderbufferStorage"); - gleswSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) get_proc("glSampleCoverage"); - gleswScissor = (PFNGLSCISSORPROC) get_proc("glScissor"); - gleswShaderBinary = (PFNGLSHADERBINARYPROC) get_proc("glShaderBinary"); - gleswShaderSource = (PFNGLSHADERSOURCEPROC) get_proc("glShaderSource"); - gleswStencilFunc = (PFNGLSTENCILFUNCPROC) get_proc("glStencilFunc"); - gleswStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) get_proc("glStencilFuncSeparate"); - gleswStencilMask = (PFNGLSTENCILMASKPROC) get_proc("glStencilMask"); - gleswStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) get_proc("glStencilMaskSeparate"); - gleswStencilOp = (PFNGLSTENCILOPPROC) get_proc("glStencilOp"); - gleswStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) get_proc("glStencilOpSeparate"); - gleswTexImage2D = (PFNGLTEXIMAGE2DPROC) get_proc("glTexImage2D"); - gleswTexParameterf = (PFNGLTEXPARAMETERFPROC) get_proc("glTexParameterf"); - gleswTexParameterfv = (PFNGLTEXPARAMETERFVPROC) get_proc("glTexParameterfv"); - gleswTexParameteri = (PFNGLTEXPARAMETERIPROC) get_proc("glTexParameteri"); - gleswTexParameteriv = (PFNGLTEXPARAMETERIVPROC) get_proc("glTexParameteriv"); - gleswTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) get_proc("glTexSubImage2D"); - gleswUniform1f = (PFNGLUNIFORM1FPROC) get_proc("glUniform1f"); - gleswUniform1fv = (PFNGLUNIFORM1FVPROC) get_proc("glUniform1fv"); - gleswUniform1i = (PFNGLUNIFORM1IPROC) get_proc("glUniform1i"); - gleswUniform1iv = (PFNGLUNIFORM1IVPROC) get_proc("glUniform1iv"); - gleswUniform2f = (PFNGLUNIFORM2FPROC) get_proc("glUniform2f"); - gleswUniform2fv = (PFNGLUNIFORM2FVPROC) get_proc("glUniform2fv"); - gleswUniform2i = (PFNGLUNIFORM2IPROC) get_proc("glUniform2i"); - gleswUniform2iv = (PFNGLUNIFORM2IVPROC) get_proc("glUniform2iv"); - gleswUniform3f = (PFNGLUNIFORM3FPROC) get_proc("glUniform3f"); - gleswUniform3fv = (PFNGLUNIFORM3FVPROC) get_proc("glUniform3fv"); - gleswUniform3i = (PFNGLUNIFORM3IPROC) get_proc("glUniform3i"); - gleswUniform3iv = (PFNGLUNIFORM3IVPROC) get_proc("glUniform3iv"); - gleswUniform4f = (PFNGLUNIFORM4FPROC) get_proc("glUniform4f"); - gleswUniform4fv = (PFNGLUNIFORM4FVPROC) get_proc("glUniform4fv"); - gleswUniform4i = (PFNGLUNIFORM4IPROC) get_proc("glUniform4i"); - gleswUniform4iv = (PFNGLUNIFORM4IVPROC) get_proc("glUniform4iv"); - gleswUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) get_proc("glUniformMatrix2fv"); - gleswUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) get_proc("glUniformMatrix3fv"); - gleswUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) get_proc("glUniformMatrix4fv"); - gleswUseProgram = (PFNGLUSEPROGRAMPROC) get_proc("glUseProgram"); - gleswValidateProgram = (PFNGLVALIDATEPROGRAMPROC) get_proc("glValidateProgram"); - gleswVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) get_proc("glVertexAttrib1f"); - gleswVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) get_proc("glVertexAttrib1fv"); - gleswVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) get_proc("glVertexAttrib2f"); - gleswVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) get_proc("glVertexAttrib2fv"); - gleswVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) get_proc("glVertexAttrib3f"); - gleswVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) get_proc("glVertexAttrib3fv"); - gleswVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) get_proc("glVertexAttrib4f"); - gleswVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) get_proc("glVertexAttrib4fv"); - gleswVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) get_proc("glVertexAttribPointer"); - gleswViewport = (PFNGLVIEWPORTPROC) get_proc("glViewport"); - gleswEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) get_proc("glEGLImageTargetTexture2DOES"); - gleswEGLImageTargetRenderbufferStorageOES = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) get_proc("glEGLImageTargetRenderbufferStorageOES"); - gleswGetProgramBinaryOES = (PFNGLGETPROGRAMBINARYOESPROC) get_proc("glGetProgramBinaryOES"); - gleswProgramBinaryOES = (PFNGLPROGRAMBINARYOESPROC) get_proc("glProgramBinaryOES"); - gleswMapBufferOES = (PFNGLMAPBUFFEROESPROC) get_proc("glMapBufferOES"); - gleswUnmapBufferOES = (PFNGLUNMAPBUFFEROESPROC) get_proc("glUnmapBufferOES"); - gleswGetBufferPointervOES = (PFNGLGETBUFFERPOINTERVOESPROC) get_proc("glGetBufferPointervOES"); - gleswTexImage3DOES = (PFNGLTEXIMAGE3DOESPROC) get_proc("glTexImage3DOES"); - gleswTexSubImage3DOES = (PFNGLTEXSUBIMAGE3DOESPROC) get_proc("glTexSubImage3DOES"); - gleswCopyTexSubImage3DOES = (PFNGLCOPYTEXSUBIMAGE3DOESPROC) get_proc("glCopyTexSubImage3DOES"); - gleswCompressedTexImage3DOES = (PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) get_proc("glCompressedTexImage3DOES"); - gleswCompressedTexSubImage3DOES = (PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) get_proc("glCompressedTexSubImage3DOES"); - gleswFramebufferTexture3DOES = (PFNGLFRAMEBUFFERTEXTURE3DOESPROC) get_proc("glFramebufferTexture3DOES"); - gleswBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC) get_proc("glBindVertexArrayOES"); - gleswDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC) get_proc("glDeleteVertexArraysOES"); - gleswGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC) get_proc("glGenVertexArraysOES"); - gleswIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC) get_proc("glIsVertexArrayOES"); - gleswDebugMessageControlKHR = (PFNGLDEBUGMESSAGECONTROLKHRPROC) get_proc("glDebugMessageControlKHR"); - gleswDebugMessageInsertKHR = (PFNGLDEBUGMESSAGEINSERTKHRPROC) get_proc("glDebugMessageInsertKHR"); - gleswDebugMessageCallbackKHR = (PFNGLDEBUGMESSAGECALLBACKKHRPROC) get_proc("glDebugMessageCallbackKHR"); - gleswGetDebugMessageLogKHR = (PFNGLGETDEBUGMESSAGELOGKHRPROC) get_proc("glGetDebugMessageLogKHR"); - gleswPushDebugGroupKHR = (PFNGLPUSHDEBUGGROUPKHRPROC) get_proc("glPushDebugGroupKHR"); - gleswPopDebugGroupKHR = (PFNGLPOPDEBUGGROUPKHRPROC) get_proc("glPopDebugGroupKHR"); - gleswObjectLabelKHR = (PFNGLOBJECTLABELKHRPROC) get_proc("glObjectLabelKHR"); - gleswGetObjectLabelKHR = (PFNGLGETOBJECTLABELKHRPROC) get_proc("glGetObjectLabelKHR"); - gleswObjectPtrLabelKHR = (PFNGLOBJECTPTRLABELKHRPROC) get_proc("glObjectPtrLabelKHR"); - gleswGetObjectPtrLabelKHR = (PFNGLGETOBJECTPTRLABELKHRPROC) get_proc("glGetObjectPtrLabelKHR"); - gleswGetPointervKHR = (PFNGLGETPOINTERVKHRPROC) get_proc("glGetPointervKHR"); - gleswGetPerfMonitorGroupsAMD = (PFNGLGETPERFMONITORGROUPSAMDPROC) get_proc("glGetPerfMonitorGroupsAMD"); - gleswGetPerfMonitorCountersAMD = (PFNGLGETPERFMONITORCOUNTERSAMDPROC) get_proc("glGetPerfMonitorCountersAMD"); - gleswGetPerfMonitorGroupStringAMD = (PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) get_proc("glGetPerfMonitorGroupStringAMD"); - gleswGetPerfMonitorCounterStringAMD = (PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) get_proc("glGetPerfMonitorCounterStringAMD"); - gleswGetPerfMonitorCounterInfoAMD = (PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) get_proc("glGetPerfMonitorCounterInfoAMD"); - gleswGenPerfMonitorsAMD = (PFNGLGENPERFMONITORSAMDPROC) get_proc("glGenPerfMonitorsAMD"); - gleswDeletePerfMonitorsAMD = (PFNGLDELETEPERFMONITORSAMDPROC) get_proc("glDeletePerfMonitorsAMD"); - gleswSelectPerfMonitorCountersAMD = (PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) get_proc("glSelectPerfMonitorCountersAMD"); - gleswBeginPerfMonitorAMD = (PFNGLBEGINPERFMONITORAMDPROC) get_proc("glBeginPerfMonitorAMD"); - gleswEndPerfMonitorAMD = (PFNGLENDPERFMONITORAMDPROC) get_proc("glEndPerfMonitorAMD"); - gleswGetPerfMonitorCounterDataAMD = (PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) get_proc("glGetPerfMonitorCounterDataAMD"); - gleswBlitFramebufferANGLE = (PFNGLBLITFRAMEBUFFERANGLEPROC) get_proc("glBlitFramebufferANGLE"); - gleswRenderbufferStorageMultisampleANGLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) get_proc("glRenderbufferStorageMultisampleANGLE"); - gleswDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC) get_proc("glDrawArraysInstancedANGLE"); - gleswDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) get_proc("glDrawElementsInstancedANGLE"); - gleswVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC) get_proc("glVertexAttribDivisorANGLE"); - gleswGetTranslatedShaderSourceANGLE = (PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) get_proc("glGetTranslatedShaderSourceANGLE"); - gleswDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC) get_proc("glDrawArraysInstancedEXT"); - gleswDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC) get_proc("glDrawElementsInstancedEXT"); - gleswVertexAttribDivisorEXT = (PFNGLVERTEXATTRIBDIVISOREXTPROC) get_proc("glVertexAttribDivisorEXT"); - gleswCopyTextureLevelsAPPLE = (PFNGLCOPYTEXTURELEVELSAPPLEPROC) get_proc("glCopyTextureLevelsAPPLE"); - gleswRenderbufferStorageMultisampleAPPLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) get_proc("glRenderbufferStorageMultisampleAPPLE"); - gleswResolveMultisampleFramebufferAPPLE = (PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) get_proc("glResolveMultisampleFramebufferAPPLE"); - gleswFenceSyncAPPLE = (PFNGLFENCESYNCAPPLEPROC) get_proc("glFenceSyncAPPLE"); - gleswIsSyncAPPLE = (PFNGLISSYNCAPPLEPROC) get_proc("glIsSyncAPPLE"); - gleswDeleteSyncAPPLE = (PFNGLDELETESYNCAPPLEPROC) get_proc("glDeleteSyncAPPLE"); - gleswClientWaitSyncAPPLE = (PFNGLCLIENTWAITSYNCAPPLEPROC) get_proc("glClientWaitSyncAPPLE"); - gleswWaitSyncAPPLE = (PFNGLWAITSYNCAPPLEPROC) get_proc("glWaitSyncAPPLE"); - gleswGetInteger64vAPPLE = (PFNGLGETINTEGER64VAPPLEPROC) get_proc("glGetInteger64vAPPLE"); - gleswGetSyncivAPPLE = (PFNGLGETSYNCIVAPPLEPROC) get_proc("glGetSyncivAPPLE"); - gleswLabelObjectEXT = (PFNGLLABELOBJECTEXTPROC) get_proc("glLabelObjectEXT"); - gleswGetObjectLabelEXT = (PFNGLGETOBJECTLABELEXTPROC) get_proc("glGetObjectLabelEXT"); - gleswInsertEventMarkerEXT = (PFNGLINSERTEVENTMARKEREXTPROC) get_proc("glInsertEventMarkerEXT"); - gleswPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC) get_proc("glPushGroupMarkerEXT"); - gleswPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC) get_proc("glPopGroupMarkerEXT"); - gleswDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC) get_proc("glDiscardFramebufferEXT"); - gleswGenQueriesEXT = (PFNGLGENQUERIESEXTPROC) get_proc("glGenQueriesEXT"); - gleswDeleteQueriesEXT = (PFNGLDELETEQUERIESEXTPROC) get_proc("glDeleteQueriesEXT"); - gleswIsQueryEXT = (PFNGLISQUERYEXTPROC) get_proc("glIsQueryEXT"); - gleswBeginQueryEXT = (PFNGLBEGINQUERYEXTPROC) get_proc("glBeginQueryEXT"); - gleswEndQueryEXT = (PFNGLENDQUERYEXTPROC) get_proc("glEndQueryEXT"); - gleswQueryCounterEXT = (PFNGLQUERYCOUNTEREXTPROC) get_proc("glQueryCounterEXT"); - gleswGetQueryivEXT = (PFNGLGETQUERYIVEXTPROC) get_proc("glGetQueryivEXT"); - gleswGetQueryObjectivEXT = (PFNGLGETQUERYOBJECTIVEXTPROC) get_proc("glGetQueryObjectivEXT"); - gleswGetQueryObjectuivEXT = (PFNGLGETQUERYOBJECTUIVEXTPROC) get_proc("glGetQueryObjectuivEXT"); - gleswGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC) get_proc("glGetQueryObjecti64vEXT"); - gleswGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC) get_proc("glGetQueryObjectui64vEXT"); - gleswMapBufferRangeEXT = (PFNGLMAPBUFFERRANGEEXTPROC) get_proc("glMapBufferRangeEXT"); - gleswFlushMappedBufferRangeEXT = (PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) get_proc("glFlushMappedBufferRangeEXT"); - gleswRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) get_proc("glRenderbufferStorageMultisampleEXT"); - gleswFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) get_proc("glFramebufferTexture2DMultisampleEXT"); - gleswReadBufferIndexedEXT = (PFNGLREADBUFFERINDEXEDEXTPROC) get_proc("glReadBufferIndexedEXT"); - gleswDrawBuffersIndexedEXT = (PFNGLDRAWBUFFERSINDEXEDEXTPROC) get_proc("glDrawBuffersIndexedEXT"); - gleswGetIntegeri_vEXT = (PFNGLGETINTEGERI_VEXTPROC) get_proc("glGetIntegeri_vEXT"); - gleswMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC) get_proc("glMultiDrawArraysEXT"); - gleswMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC) get_proc("glMultiDrawElementsEXT"); - gleswGetGraphicsResetStatusEXT = (PFNGLGETGRAPHICSRESETSTATUSEXTPROC) get_proc("glGetGraphicsResetStatusEXT"); - gleswReadnPixelsEXT = (PFNGLREADNPIXELSEXTPROC) get_proc("glReadnPixelsEXT"); - gleswGetnUniformfvEXT = (PFNGLGETNUNIFORMFVEXTPROC) get_proc("glGetnUniformfvEXT"); - gleswGetnUniformivEXT = (PFNGLGETNUNIFORMIVEXTPROC) get_proc("glGetnUniformivEXT"); - gleswUseProgramStagesEXT = (PFNGLUSEPROGRAMSTAGESEXTPROC) get_proc("glUseProgramStagesEXT"); - gleswActiveShaderProgramEXT = (PFNGLACTIVESHADERPROGRAMEXTPROC) get_proc("glActiveShaderProgramEXT"); - gleswCreateShaderProgramvEXT = (PFNGLCREATESHADERPROGRAMVEXTPROC) get_proc("glCreateShaderProgramvEXT"); - gleswBindProgramPipelineEXT = (PFNGLBINDPROGRAMPIPELINEEXTPROC) get_proc("glBindProgramPipelineEXT"); - gleswDeleteProgramPipelinesEXT = (PFNGLDELETEPROGRAMPIPELINESEXTPROC) get_proc("glDeleteProgramPipelinesEXT"); - gleswGenProgramPipelinesEXT = (PFNGLGENPROGRAMPIPELINESEXTPROC) get_proc("glGenProgramPipelinesEXT"); - gleswIsProgramPipelineEXT = (PFNGLISPROGRAMPIPELINEEXTPROC) get_proc("glIsProgramPipelineEXT"); - gleswProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC) get_proc("glProgramParameteriEXT"); - gleswGetProgramPipelineivEXT = (PFNGLGETPROGRAMPIPELINEIVEXTPROC) get_proc("glGetProgramPipelineivEXT"); - gleswProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC) get_proc("glProgramUniform1iEXT"); - gleswProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC) get_proc("glProgramUniform2iEXT"); - gleswProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC) get_proc("glProgramUniform3iEXT"); - gleswProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC) get_proc("glProgramUniform4iEXT"); - gleswProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC) get_proc("glProgramUniform1fEXT"); - gleswProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC) get_proc("glProgramUniform2fEXT"); - gleswProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC) get_proc("glProgramUniform3fEXT"); - gleswProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC) get_proc("glProgramUniform4fEXT"); - gleswProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC) get_proc("glProgramUniform1ivEXT"); - gleswProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC) get_proc("glProgramUniform2ivEXT"); - gleswProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC) get_proc("glProgramUniform3ivEXT"); - gleswProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC) get_proc("glProgramUniform4ivEXT"); - gleswProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC) get_proc("glProgramUniform1fvEXT"); - gleswProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC) get_proc("glProgramUniform2fvEXT"); - gleswProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC) get_proc("glProgramUniform3fvEXT"); - gleswProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC) get_proc("glProgramUniform4fvEXT"); - gleswProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) get_proc("glProgramUniformMatrix2fvEXT"); - gleswProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) get_proc("glProgramUniformMatrix3fvEXT"); - gleswProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) get_proc("glProgramUniformMatrix4fvEXT"); - gleswValidateProgramPipelineEXT = (PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) get_proc("glValidateProgramPipelineEXT"); - gleswGetProgramPipelineInfoLogEXT = (PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) get_proc("glGetProgramPipelineInfoLogEXT"); - gleswTexStorage1DEXT = (PFNGLTEXSTORAGE1DEXTPROC) get_proc("glTexStorage1DEXT"); - gleswTexStorage2DEXT = (PFNGLTEXSTORAGE2DEXTPROC) get_proc("glTexStorage2DEXT"); - gleswTexStorage3DEXT = (PFNGLTEXSTORAGE3DEXTPROC) get_proc("glTexStorage3DEXT"); - gleswTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC) get_proc("glTextureStorage1DEXT"); - gleswTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC) get_proc("glTextureStorage2DEXT"); - gleswTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC) get_proc("glTextureStorage3DEXT"); - gleswRenderbufferStorageMultisampleIMG = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) get_proc("glRenderbufferStorageMultisampleIMG"); - gleswFramebufferTexture2DMultisampleIMG = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) get_proc("glFramebufferTexture2DMultisampleIMG"); - gleswCoverageMaskNV = (PFNGLCOVERAGEMASKNVPROC) get_proc("glCoverageMaskNV"); - gleswCoverageOperationNV = (PFNGLCOVERAGEOPERATIONNVPROC) get_proc("glCoverageOperationNV"); - gleswDrawBuffersNV = (PFNGLDRAWBUFFERSNVPROC) get_proc("glDrawBuffersNV"); - gleswDrawArraysInstancedNV = (PFNGLDRAWARRAYSINSTANCEDNVPROC) get_proc("glDrawArraysInstancedNV"); - gleswDrawElementsInstancedNV = (PFNGLDRAWELEMENTSINSTANCEDNVPROC) get_proc("glDrawElementsInstancedNV"); - gleswDeleteFencesNV = (PFNGLDELETEFENCESNVPROC) get_proc("glDeleteFencesNV"); - gleswGenFencesNV = (PFNGLGENFENCESNVPROC) get_proc("glGenFencesNV"); - gleswIsFenceNV = (PFNGLISFENCENVPROC) get_proc("glIsFenceNV"); - gleswTestFenceNV = (PFNGLTESTFENCENVPROC) get_proc("glTestFenceNV"); - gleswGetFenceivNV = (PFNGLGETFENCEIVNVPROC) get_proc("glGetFenceivNV"); - gleswFinishFenceNV = (PFNGLFINISHFENCENVPROC) get_proc("glFinishFenceNV"); - gleswSetFenceNV = (PFNGLSETFENCENVPROC) get_proc("glSetFenceNV"); - gleswBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC) get_proc("glBlitFramebufferNV"); - gleswRenderbufferStorageMultisampleNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) get_proc("glRenderbufferStorageMultisampleNV"); - gleswVertexAttribDivisorNV = (PFNGLVERTEXATTRIBDIVISORNVPROC) get_proc("glVertexAttribDivisorNV"); - gleswReadBufferNV = (PFNGLREADBUFFERNVPROC) get_proc("glReadBufferNV"); - gleswAlphaFuncQCOM = (PFNGLALPHAFUNCQCOMPROC) get_proc("glAlphaFuncQCOM"); - gleswGetDriverControlsQCOM = (PFNGLGETDRIVERCONTROLSQCOMPROC) get_proc("glGetDriverControlsQCOM"); - gleswGetDriverControlStringQCOM = (PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) get_proc("glGetDriverControlStringQCOM"); - gleswEnableDriverControlQCOM = (PFNGLENABLEDRIVERCONTROLQCOMPROC) get_proc("glEnableDriverControlQCOM"); - gleswDisableDriverControlQCOM = (PFNGLDISABLEDRIVERCONTROLQCOMPROC) get_proc("glDisableDriverControlQCOM"); - gleswExtGetTexturesQCOM = (PFNGLEXTGETTEXTURESQCOMPROC) get_proc("glExtGetTexturesQCOM"); - gleswExtGetBuffersQCOM = (PFNGLEXTGETBUFFERSQCOMPROC) get_proc("glExtGetBuffersQCOM"); - gleswExtGetRenderbuffersQCOM = (PFNGLEXTGETRENDERBUFFERSQCOMPROC) get_proc("glExtGetRenderbuffersQCOM"); - gleswExtGetFramebuffersQCOM = (PFNGLEXTGETFRAMEBUFFERSQCOMPROC) get_proc("glExtGetFramebuffersQCOM"); - gleswExtGetTexLevelParameterivQCOM = (PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) get_proc("glExtGetTexLevelParameterivQCOM"); - gleswExtTexObjectStateOverrideiQCOM = (PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) get_proc("glExtTexObjectStateOverrideiQCOM"); - gleswExtGetTexSubImageQCOM = (PFNGLEXTGETTEXSUBIMAGEQCOMPROC) get_proc("glExtGetTexSubImageQCOM"); - gleswExtGetBufferPointervQCOM = (PFNGLEXTGETBUFFERPOINTERVQCOMPROC) get_proc("glExtGetBufferPointervQCOM"); - gleswExtGetShadersQCOM = (PFNGLEXTGETSHADERSQCOMPROC) get_proc("glExtGetShadersQCOM"); - gleswExtGetProgramsQCOM = (PFNGLEXTGETPROGRAMSQCOMPROC) get_proc("glExtGetProgramsQCOM"); - gleswExtIsProgramBinaryQCOM = (PFNGLEXTISPROGRAMBINARYQCOMPROC) get_proc("glExtIsProgramBinaryQCOM"); - gleswExtGetProgramBinarySourceQCOM = (PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) get_proc("glExtGetProgramBinarySourceQCOM"); - gleswStartTilingQCOM = (PFNGLSTARTTILINGQCOMPROC) get_proc("glStartTilingQCOM"); - gleswEndTilingQCOM = (PFNGLENDTILINGQCOMPROC) get_proc("glEndTilingQCOM"); + gleswActiveTexture = (PFNGLACTIVETEXTUREPROC) get_proc("glActiveTexture"); + gleswAttachShader = (PFNGLATTACHSHADERPROC) get_proc("glAttachShader"); + gleswBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) get_proc("glBindAttribLocation"); + gleswBindBuffer = (PFNGLBINDBUFFERPROC) get_proc("glBindBuffer"); + gleswBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) get_proc("glBindFramebuffer"); + gleswBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) get_proc("glBindRenderbuffer"); + gleswBindTexture = (PFNGLBINDTEXTUREPROC) get_proc("glBindTexture"); + gleswBlendColor = (PFNGLBLENDCOLORPROC) get_proc("glBlendColor"); + gleswBlendEquation = (PFNGLBLENDEQUATIONPROC) get_proc("glBlendEquation"); + gleswBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) get_proc("glBlendEquationSeparate"); + gleswBlendFunc = (PFNGLBLENDFUNCPROC) get_proc("glBlendFunc"); + gleswBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) get_proc("glBlendFuncSeparate"); + gleswBufferData = (PFNGLBUFFERDATAPROC) get_proc("glBufferData"); + gleswBufferSubData = (PFNGLBUFFERSUBDATAPROC) get_proc("glBufferSubData"); + gleswCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) get_proc("glCheckFramebufferStatus"); + gleswClear = (PFNGLCLEARPROC) get_proc("glClear"); + gleswClearColor = (PFNGLCLEARCOLORPROC) get_proc("glClearColor"); + gleswClearDepthf = (PFNGLCLEARDEPTHFPROC) get_proc("glClearDepthf"); + gleswClearStencil = (PFNGLCLEARSTENCILPROC) get_proc("glClearStencil"); + gleswColorMask = (PFNGLCOLORMASKPROC) get_proc("glColorMask"); + gleswCompileShader = (PFNGLCOMPILESHADERPROC) get_proc("glCompileShader"); + gleswCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) get_proc("glCompressedTexImage2D"); + gleswCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) get_proc("glCompressedTexSubImage2D"); + gleswCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) get_proc("glCopyTexImage2D"); + gleswCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) get_proc("glCopyTexSubImage2D"); + gleswCreateProgram = (PFNGLCREATEPROGRAMPROC) get_proc("glCreateProgram"); + gleswCreateShader = (PFNGLCREATESHADERPROC) get_proc("glCreateShader"); + gleswCullFace = (PFNGLCULLFACEPROC) get_proc("glCullFace"); + gleswDeleteBuffers = (PFNGLDELETEBUFFERSPROC) get_proc("glDeleteBuffers"); + gleswDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) get_proc("glDeleteFramebuffers"); + gleswDeleteProgram = (PFNGLDELETEPROGRAMPROC) get_proc("glDeleteProgram"); + gleswDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) get_proc("glDeleteRenderbuffers"); + gleswDeleteShader = (PFNGLDELETESHADERPROC) get_proc("glDeleteShader"); + gleswDeleteTextures = (PFNGLDELETETEXTURESPROC) get_proc("glDeleteTextures"); + gleswDepthFunc = (PFNGLDEPTHFUNCPROC) get_proc("glDepthFunc"); + gleswDepthMask = (PFNGLDEPTHMASKPROC) get_proc("glDepthMask"); + gleswDepthRangef = (PFNGLDEPTHRANGEFPROC) get_proc("glDepthRangef"); + gleswDetachShader = (PFNGLDETACHSHADERPROC) get_proc("glDetachShader"); + gleswDisable = (PFNGLDISABLEPROC) get_proc("glDisable"); + gleswDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) get_proc("glDisableVertexAttribArray"); + gleswDrawArrays = (PFNGLDRAWARRAYSPROC) get_proc("glDrawArrays"); + gleswDrawElements = (PFNGLDRAWELEMENTSPROC) get_proc("glDrawElements"); + gleswEnable = (PFNGLENABLEPROC) get_proc("glEnable"); + gleswEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) get_proc("glEnableVertexAttribArray"); + gleswFinish = (PFNGLFINISHPROC) get_proc("glFinish"); + gleswFlush = (PFNGLFLUSHPROC) get_proc("glFlush"); + gleswFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) get_proc("glFramebufferRenderbuffer"); + gleswFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) get_proc("glFramebufferTexture2D"); + gleswFrontFace = (PFNGLFRONTFACEPROC) get_proc("glFrontFace"); + gleswGenBuffers = (PFNGLGENBUFFERSPROC) get_proc("glGenBuffers"); + gleswGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) get_proc("glGenerateMipmap"); + gleswGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) get_proc("glGenFramebuffers"); + gleswGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) get_proc("glGenRenderbuffers"); + gleswGenTextures = (PFNGLGENTEXTURESPROC) get_proc("glGenTextures"); + gleswGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) get_proc("glGetActiveAttrib"); + gleswGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) get_proc("glGetActiveUniform"); + gleswGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) get_proc("glGetAttachedShaders"); + gleswGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) get_proc("glGetAttribLocation"); + gleswGetBooleanv = (PFNGLGETBOOLEANVPROC) get_proc("glGetBooleanv"); + gleswGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) get_proc("glGetBufferParameteriv"); + gleswGetError = (PFNGLGETERRORPROC) get_proc("glGetError"); + gleswGetFloatv = (PFNGLGETFLOATVPROC) get_proc("glGetFloatv"); + gleswGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) get_proc("glGetFramebufferAttachmentParameteriv"); + gleswGetIntegerv = (PFNGLGETINTEGERVPROC) get_proc("glGetIntegerv"); + gleswGetProgramiv = (PFNGLGETPROGRAMIVPROC) get_proc("glGetProgramiv"); + gleswGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) get_proc("glGetProgramInfoLog"); + gleswGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) get_proc("glGetRenderbufferParameteriv"); + gleswGetShaderiv = (PFNGLGETSHADERIVPROC) get_proc("glGetShaderiv"); + gleswGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) get_proc("glGetShaderInfoLog"); + gleswGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) get_proc("glGetShaderPrecisionFormat"); + gleswGetShaderSource = (PFNGLGETSHADERSOURCEPROC) get_proc("glGetShaderSource"); + gleswGetString = (PFNGLGETSTRINGPROC) get_proc("glGetString"); + gleswGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) get_proc("glGetTexParameterfv"); + gleswGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) get_proc("glGetTexParameteriv"); + gleswGetUniformfv = (PFNGLGETUNIFORMFVPROC) get_proc("glGetUniformfv"); + gleswGetUniformiv = (PFNGLGETUNIFORMIVPROC) get_proc("glGetUniformiv"); + gleswGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) get_proc("glGetUniformLocation"); + gleswGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) get_proc("glGetVertexAttribfv"); + gleswGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) get_proc("glGetVertexAttribiv"); + gleswGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) get_proc("glGetVertexAttribPointerv"); + gleswHint = (PFNGLHINTPROC) get_proc("glHint"); + gleswIsBuffer = (PFNGLISBUFFERPROC) get_proc("glIsBuffer"); + gleswIsEnabled = (PFNGLISENABLEDPROC) get_proc("glIsEnabled"); + gleswIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) get_proc("glIsFramebuffer"); + gleswIsProgram = (PFNGLISPROGRAMPROC) get_proc("glIsProgram"); + gleswIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) get_proc("glIsRenderbuffer"); + gleswIsShader = (PFNGLISSHADERPROC) get_proc("glIsShader"); + gleswIsTexture = (PFNGLISTEXTUREPROC) get_proc("glIsTexture"); + gleswLineWidth = (PFNGLLINEWIDTHPROC) get_proc("glLineWidth"); + gleswLinkProgram = (PFNGLLINKPROGRAMPROC) get_proc("glLinkProgram"); + gleswPixelStorei = (PFNGLPIXELSTOREIPROC) get_proc("glPixelStorei"); + gleswPolygonOffset = (PFNGLPOLYGONOFFSETPROC) get_proc("glPolygonOffset"); + gleswReadPixels = (PFNGLREADPIXELSPROC) get_proc("glReadPixels"); + gleswReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) get_proc("glReleaseShaderCompiler"); + gleswRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) get_proc("glRenderbufferStorage"); + gleswSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) get_proc("glSampleCoverage"); + gleswScissor = (PFNGLSCISSORPROC) get_proc("glScissor"); + gleswShaderBinary = (PFNGLSHADERBINARYPROC) get_proc("glShaderBinary"); + gleswShaderSource = (PFNGLSHADERSOURCEPROC) get_proc("glShaderSource"); + gleswStencilFunc = (PFNGLSTENCILFUNCPROC) get_proc("glStencilFunc"); + gleswStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) get_proc("glStencilFuncSeparate"); + gleswStencilMask = (PFNGLSTENCILMASKPROC) get_proc("glStencilMask"); + gleswStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) get_proc("glStencilMaskSeparate"); + gleswStencilOp = (PFNGLSTENCILOPPROC) get_proc("glStencilOp"); + gleswStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) get_proc("glStencilOpSeparate"); + gleswTexImage2D = (PFNGLTEXIMAGE2DPROC) get_proc("glTexImage2D"); + gleswTexParameterf = (PFNGLTEXPARAMETERFPROC) get_proc("glTexParameterf"); + gleswTexParameterfv = (PFNGLTEXPARAMETERFVPROC) get_proc("glTexParameterfv"); + gleswTexParameteri = (PFNGLTEXPARAMETERIPROC) get_proc("glTexParameteri"); + gleswTexParameteriv = (PFNGLTEXPARAMETERIVPROC) get_proc("glTexParameteriv"); + gleswTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) get_proc("glTexSubImage2D"); + gleswUniform1f = (PFNGLUNIFORM1FPROC) get_proc("glUniform1f"); + gleswUniform1fv = (PFNGLUNIFORM1FVPROC) get_proc("glUniform1fv"); + gleswUniform1i = (PFNGLUNIFORM1IPROC) get_proc("glUniform1i"); + gleswUniform1iv = (PFNGLUNIFORM1IVPROC) get_proc("glUniform1iv"); + gleswUniform2f = (PFNGLUNIFORM2FPROC) get_proc("glUniform2f"); + gleswUniform2fv = (PFNGLUNIFORM2FVPROC) get_proc("glUniform2fv"); + gleswUniform2i = (PFNGLUNIFORM2IPROC) get_proc("glUniform2i"); + gleswUniform2iv = (PFNGLUNIFORM2IVPROC) get_proc("glUniform2iv"); + gleswUniform3f = (PFNGLUNIFORM3FPROC) get_proc("glUniform3f"); + gleswUniform3fv = (PFNGLUNIFORM3FVPROC) get_proc("glUniform3fv"); + gleswUniform3i = (PFNGLUNIFORM3IPROC) get_proc("glUniform3i"); + gleswUniform3iv = (PFNGLUNIFORM3IVPROC) get_proc("glUniform3iv"); + gleswUniform4f = (PFNGLUNIFORM4FPROC) get_proc("glUniform4f"); + gleswUniform4fv = (PFNGLUNIFORM4FVPROC) get_proc("glUniform4fv"); + gleswUniform4i = (PFNGLUNIFORM4IPROC) get_proc("glUniform4i"); + gleswUniform4iv = (PFNGLUNIFORM4IVPROC) get_proc("glUniform4iv"); + gleswUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) get_proc("glUniformMatrix2fv"); + gleswUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) get_proc("glUniformMatrix3fv"); + gleswUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) get_proc("glUniformMatrix4fv"); + gleswUseProgram = (PFNGLUSEPROGRAMPROC) get_proc("glUseProgram"); + gleswValidateProgram = (PFNGLVALIDATEPROGRAMPROC) get_proc("glValidateProgram"); + gleswVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) get_proc("glVertexAttrib1f"); + gleswVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) get_proc("glVertexAttrib1fv"); + gleswVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) get_proc("glVertexAttrib2f"); + gleswVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) get_proc("glVertexAttrib2fv"); + gleswVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) get_proc("glVertexAttrib3f"); + gleswVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) get_proc("glVertexAttrib3fv"); + gleswVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) get_proc("glVertexAttrib4f"); + gleswVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) get_proc("glVertexAttrib4fv"); + gleswVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) get_proc("glVertexAttribPointer"); + gleswViewport = (PFNGLVIEWPORTPROC) get_proc("glViewport"); + gleswEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) get_proc("glEGLImageTargetTexture2DOES"); + gleswEGLImageTargetRenderbufferStorageOES = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) get_proc("glEGLImageTargetRenderbufferStorageOES"); + gleswGetProgramBinaryOES = (PFNGLGETPROGRAMBINARYOESPROC) get_proc("glGetProgramBinaryOES"); + gleswProgramBinaryOES = (PFNGLPROGRAMBINARYOESPROC) get_proc("glProgramBinaryOES"); + gleswMapBufferOES = (PFNGLMAPBUFFEROESPROC) get_proc("glMapBufferOES"); + gleswUnmapBufferOES = (PFNGLUNMAPBUFFEROESPROC) get_proc("glUnmapBufferOES"); + gleswGetBufferPointervOES = (PFNGLGETBUFFERPOINTERVOESPROC) get_proc("glGetBufferPointervOES"); + gleswTexImage3DOES = (PFNGLTEXIMAGE3DOESPROC) get_proc("glTexImage3DOES"); + gleswTexSubImage3DOES = (PFNGLTEXSUBIMAGE3DOESPROC) get_proc("glTexSubImage3DOES"); + gleswCopyTexSubImage3DOES = (PFNGLCOPYTEXSUBIMAGE3DOESPROC) get_proc("glCopyTexSubImage3DOES"); + gleswCompressedTexImage3DOES = (PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) get_proc("glCompressedTexImage3DOES"); + gleswCompressedTexSubImage3DOES = (PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) get_proc("glCompressedTexSubImage3DOES"); + gleswFramebufferTexture3DOES = (PFNGLFRAMEBUFFERTEXTURE3DOESPROC) get_proc("glFramebufferTexture3DOES"); + gleswBindVertexArrayOES = (PFNGLBINDVERTEXARRAYOESPROC) get_proc("glBindVertexArrayOES"); + gleswDeleteVertexArraysOES = (PFNGLDELETEVERTEXARRAYSOESPROC) get_proc("glDeleteVertexArraysOES"); + gleswGenVertexArraysOES = (PFNGLGENVERTEXARRAYSOESPROC) get_proc("glGenVertexArraysOES"); + gleswIsVertexArrayOES = (PFNGLISVERTEXARRAYOESPROC) get_proc("glIsVertexArrayOES"); + gleswDebugMessageControlKHR = (PFNGLDEBUGMESSAGECONTROLKHRPROC) get_proc("glDebugMessageControlKHR"); + gleswDebugMessageInsertKHR = (PFNGLDEBUGMESSAGEINSERTKHRPROC) get_proc("glDebugMessageInsertKHR"); + gleswDebugMessageCallbackKHR = (PFNGLDEBUGMESSAGECALLBACKKHRPROC) get_proc("glDebugMessageCallbackKHR"); + gleswGetDebugMessageLogKHR = (PFNGLGETDEBUGMESSAGELOGKHRPROC) get_proc("glGetDebugMessageLogKHR"); + gleswPushDebugGroupKHR = (PFNGLPUSHDEBUGGROUPKHRPROC) get_proc("glPushDebugGroupKHR"); + gleswPopDebugGroupKHR = (PFNGLPOPDEBUGGROUPKHRPROC) get_proc("glPopDebugGroupKHR"); + gleswObjectLabelKHR = (PFNGLOBJECTLABELKHRPROC) get_proc("glObjectLabelKHR"); + gleswGetObjectLabelKHR = (PFNGLGETOBJECTLABELKHRPROC) get_proc("glGetObjectLabelKHR"); + gleswObjectPtrLabelKHR = (PFNGLOBJECTPTRLABELKHRPROC) get_proc("glObjectPtrLabelKHR"); + gleswGetObjectPtrLabelKHR = (PFNGLGETOBJECTPTRLABELKHRPROC) get_proc("glGetObjectPtrLabelKHR"); + gleswGetPointervKHR = (PFNGLGETPOINTERVKHRPROC) get_proc("glGetPointervKHR"); + gleswGetPerfMonitorGroupsAMD = (PFNGLGETPERFMONITORGROUPSAMDPROC) get_proc("glGetPerfMonitorGroupsAMD"); + gleswGetPerfMonitorCountersAMD = (PFNGLGETPERFMONITORCOUNTERSAMDPROC) get_proc("glGetPerfMonitorCountersAMD"); + gleswGetPerfMonitorGroupStringAMD = (PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) get_proc("glGetPerfMonitorGroupStringAMD"); + gleswGetPerfMonitorCounterStringAMD = (PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) get_proc("glGetPerfMonitorCounterStringAMD"); + gleswGetPerfMonitorCounterInfoAMD = (PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) get_proc("glGetPerfMonitorCounterInfoAMD"); + gleswGenPerfMonitorsAMD = (PFNGLGENPERFMONITORSAMDPROC) get_proc("glGenPerfMonitorsAMD"); + gleswDeletePerfMonitorsAMD = (PFNGLDELETEPERFMONITORSAMDPROC) get_proc("glDeletePerfMonitorsAMD"); + gleswSelectPerfMonitorCountersAMD = (PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) get_proc("glSelectPerfMonitorCountersAMD"); + gleswBeginPerfMonitorAMD = (PFNGLBEGINPERFMONITORAMDPROC) get_proc("glBeginPerfMonitorAMD"); + gleswEndPerfMonitorAMD = (PFNGLENDPERFMONITORAMDPROC) get_proc("glEndPerfMonitorAMD"); + gleswGetPerfMonitorCounterDataAMD = (PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) get_proc("glGetPerfMonitorCounterDataAMD"); + gleswBlitFramebufferANGLE = (PFNGLBLITFRAMEBUFFERANGLEPROC) get_proc("glBlitFramebufferANGLE"); + gleswRenderbufferStorageMultisampleANGLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) get_proc("glRenderbufferStorageMultisampleANGLE"); + gleswDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC) get_proc("glDrawArraysInstancedANGLE"); + gleswDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) get_proc("glDrawElementsInstancedANGLE"); + gleswVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC) get_proc("glVertexAttribDivisorANGLE"); + gleswGetTranslatedShaderSourceANGLE = (PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) get_proc("glGetTranslatedShaderSourceANGLE"); + gleswDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC) get_proc("glDrawArraysInstancedEXT"); + gleswDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC) get_proc("glDrawElementsInstancedEXT"); + gleswVertexAttribDivisorEXT = (PFNGLVERTEXATTRIBDIVISOREXTPROC) get_proc("glVertexAttribDivisorEXT"); + gleswCopyTextureLevelsAPPLE = (PFNGLCOPYTEXTURELEVELSAPPLEPROC) get_proc("glCopyTextureLevelsAPPLE"); + gleswRenderbufferStorageMultisampleAPPLE = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) get_proc("glRenderbufferStorageMultisampleAPPLE"); + gleswResolveMultisampleFramebufferAPPLE = (PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) get_proc("glResolveMultisampleFramebufferAPPLE"); + gleswFenceSyncAPPLE = (PFNGLFENCESYNCAPPLEPROC) get_proc("glFenceSyncAPPLE"); + gleswIsSyncAPPLE = (PFNGLISSYNCAPPLEPROC) get_proc("glIsSyncAPPLE"); + gleswDeleteSyncAPPLE = (PFNGLDELETESYNCAPPLEPROC) get_proc("glDeleteSyncAPPLE"); + gleswClientWaitSyncAPPLE = (PFNGLCLIENTWAITSYNCAPPLEPROC) get_proc("glClientWaitSyncAPPLE"); + gleswWaitSyncAPPLE = (PFNGLWAITSYNCAPPLEPROC) get_proc("glWaitSyncAPPLE"); + gleswGetInteger64vAPPLE = (PFNGLGETINTEGER64VAPPLEPROC) get_proc("glGetInteger64vAPPLE"); + gleswGetSyncivAPPLE = (PFNGLGETSYNCIVAPPLEPROC) get_proc("glGetSyncivAPPLE"); + gleswLabelObjectEXT = (PFNGLLABELOBJECTEXTPROC) get_proc("glLabelObjectEXT"); + gleswGetObjectLabelEXT = (PFNGLGETOBJECTLABELEXTPROC) get_proc("glGetObjectLabelEXT"); + gleswInsertEventMarkerEXT = (PFNGLINSERTEVENTMARKEREXTPROC) get_proc("glInsertEventMarkerEXT"); + gleswPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC) get_proc("glPushGroupMarkerEXT"); + gleswPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC) get_proc("glPopGroupMarkerEXT"); + gleswDiscardFramebufferEXT = (PFNGLDISCARDFRAMEBUFFEREXTPROC) get_proc("glDiscardFramebufferEXT"); + gleswGenQueriesEXT = (PFNGLGENQUERIESEXTPROC) get_proc("glGenQueriesEXT"); + gleswDeleteQueriesEXT = (PFNGLDELETEQUERIESEXTPROC) get_proc("glDeleteQueriesEXT"); + gleswIsQueryEXT = (PFNGLISQUERYEXTPROC) get_proc("glIsQueryEXT"); + gleswBeginQueryEXT = (PFNGLBEGINQUERYEXTPROC) get_proc("glBeginQueryEXT"); + gleswEndQueryEXT = (PFNGLENDQUERYEXTPROC) get_proc("glEndQueryEXT"); + gleswQueryCounterEXT = (PFNGLQUERYCOUNTEREXTPROC) get_proc("glQueryCounterEXT"); + gleswGetQueryivEXT = (PFNGLGETQUERYIVEXTPROC) get_proc("glGetQueryivEXT"); + gleswGetQueryObjectivEXT = (PFNGLGETQUERYOBJECTIVEXTPROC) get_proc("glGetQueryObjectivEXT"); + gleswGetQueryObjectuivEXT = (PFNGLGETQUERYOBJECTUIVEXTPROC) get_proc("glGetQueryObjectuivEXT"); + gleswGetQueryObjecti64vEXT = (PFNGLGETQUERYOBJECTI64VEXTPROC) get_proc("glGetQueryObjecti64vEXT"); + gleswGetQueryObjectui64vEXT = (PFNGLGETQUERYOBJECTUI64VEXTPROC) get_proc("glGetQueryObjectui64vEXT"); + gleswMapBufferRangeEXT = (PFNGLMAPBUFFERRANGEEXTPROC) get_proc("glMapBufferRangeEXT"); + gleswFlushMappedBufferRangeEXT = (PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) get_proc("glFlushMappedBufferRangeEXT"); + gleswRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) get_proc("glRenderbufferStorageMultisampleEXT"); + gleswFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) get_proc("glFramebufferTexture2DMultisampleEXT"); + gleswReadBufferIndexedEXT = (PFNGLREADBUFFERINDEXEDEXTPROC) get_proc("glReadBufferIndexedEXT"); + gleswDrawBuffersIndexedEXT = (PFNGLDRAWBUFFERSINDEXEDEXTPROC) get_proc("glDrawBuffersIndexedEXT"); + gleswGetIntegeri_vEXT = (PFNGLGETINTEGERI_VEXTPROC) get_proc("glGetIntegeri_vEXT"); + gleswMultiDrawArraysEXT = (PFNGLMULTIDRAWARRAYSEXTPROC) get_proc("glMultiDrawArraysEXT"); + gleswMultiDrawElementsEXT = (PFNGLMULTIDRAWELEMENTSEXTPROC) get_proc("glMultiDrawElementsEXT"); + gleswGetGraphicsResetStatusEXT = (PFNGLGETGRAPHICSRESETSTATUSEXTPROC) get_proc("glGetGraphicsResetStatusEXT"); + gleswReadnPixelsEXT = (PFNGLREADNPIXELSEXTPROC) get_proc("glReadnPixelsEXT"); + gleswGetnUniformfvEXT = (PFNGLGETNUNIFORMFVEXTPROC) get_proc("glGetnUniformfvEXT"); + gleswGetnUniformivEXT = (PFNGLGETNUNIFORMIVEXTPROC) get_proc("glGetnUniformivEXT"); + gleswUseProgramStagesEXT = (PFNGLUSEPROGRAMSTAGESEXTPROC) get_proc("glUseProgramStagesEXT"); + gleswActiveShaderProgramEXT = (PFNGLACTIVESHADERPROGRAMEXTPROC) get_proc("glActiveShaderProgramEXT"); + gleswCreateShaderProgramvEXT = (PFNGLCREATESHADERPROGRAMVEXTPROC) get_proc("glCreateShaderProgramvEXT"); + gleswBindProgramPipelineEXT = (PFNGLBINDPROGRAMPIPELINEEXTPROC) get_proc("glBindProgramPipelineEXT"); + gleswDeleteProgramPipelinesEXT = (PFNGLDELETEPROGRAMPIPELINESEXTPROC) get_proc("glDeleteProgramPipelinesEXT"); + gleswGenProgramPipelinesEXT = (PFNGLGENPROGRAMPIPELINESEXTPROC) get_proc("glGenProgramPipelinesEXT"); + gleswIsProgramPipelineEXT = (PFNGLISPROGRAMPIPELINEEXTPROC) get_proc("glIsProgramPipelineEXT"); + gleswProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC) get_proc("glProgramParameteriEXT"); + gleswGetProgramPipelineivEXT = (PFNGLGETPROGRAMPIPELINEIVEXTPROC) get_proc("glGetProgramPipelineivEXT"); + gleswProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC) get_proc("glProgramUniform1iEXT"); + gleswProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC) get_proc("glProgramUniform2iEXT"); + gleswProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC) get_proc("glProgramUniform3iEXT"); + gleswProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC) get_proc("glProgramUniform4iEXT"); + gleswProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC) get_proc("glProgramUniform1fEXT"); + gleswProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC) get_proc("glProgramUniform2fEXT"); + gleswProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC) get_proc("glProgramUniform3fEXT"); + gleswProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC) get_proc("glProgramUniform4fEXT"); + gleswProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC) get_proc("glProgramUniform1ivEXT"); + gleswProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC) get_proc("glProgramUniform2ivEXT"); + gleswProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC) get_proc("glProgramUniform3ivEXT"); + gleswProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC) get_proc("glProgramUniform4ivEXT"); + gleswProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC) get_proc("glProgramUniform1fvEXT"); + gleswProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC) get_proc("glProgramUniform2fvEXT"); + gleswProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC) get_proc("glProgramUniform3fvEXT"); + gleswProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC) get_proc("glProgramUniform4fvEXT"); + gleswProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) get_proc("glProgramUniformMatrix2fvEXT"); + gleswProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) get_proc("glProgramUniformMatrix3fvEXT"); + gleswProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) get_proc("glProgramUniformMatrix4fvEXT"); + gleswValidateProgramPipelineEXT = (PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) get_proc("glValidateProgramPipelineEXT"); + gleswGetProgramPipelineInfoLogEXT = (PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) get_proc("glGetProgramPipelineInfoLogEXT"); + gleswTexStorage1DEXT = (PFNGLTEXSTORAGE1DEXTPROC) get_proc("glTexStorage1DEXT"); + gleswTexStorage2DEXT = (PFNGLTEXSTORAGE2DEXTPROC) get_proc("glTexStorage2DEXT"); + gleswTexStorage3DEXT = (PFNGLTEXSTORAGE3DEXTPROC) get_proc("glTexStorage3DEXT"); + gleswTextureStorage1DEXT = (PFNGLTEXTURESTORAGE1DEXTPROC) get_proc("glTextureStorage1DEXT"); + gleswTextureStorage2DEXT = (PFNGLTEXTURESTORAGE2DEXTPROC) get_proc("glTextureStorage2DEXT"); + gleswTextureStorage3DEXT = (PFNGLTEXTURESTORAGE3DEXTPROC) get_proc("glTextureStorage3DEXT"); + gleswRenderbufferStorageMultisampleIMG = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) get_proc("glRenderbufferStorageMultisampleIMG"); + gleswFramebufferTexture2DMultisampleIMG = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) get_proc("glFramebufferTexture2DMultisampleIMG"); + gleswCoverageMaskNV = (PFNGLCOVERAGEMASKNVPROC) get_proc("glCoverageMaskNV"); + gleswCoverageOperationNV = (PFNGLCOVERAGEOPERATIONNVPROC) get_proc("glCoverageOperationNV"); + gleswDrawBuffersNV = (PFNGLDRAWBUFFERSNVPROC) get_proc("glDrawBuffersNV"); + gleswDrawArraysInstancedNV = (PFNGLDRAWARRAYSINSTANCEDNVPROC) get_proc("glDrawArraysInstancedNV"); + gleswDrawElementsInstancedNV = (PFNGLDRAWELEMENTSINSTANCEDNVPROC) get_proc("glDrawElementsInstancedNV"); + gleswDeleteFencesNV = (PFNGLDELETEFENCESNVPROC) get_proc("glDeleteFencesNV"); + gleswGenFencesNV = (PFNGLGENFENCESNVPROC) get_proc("glGenFencesNV"); + gleswIsFenceNV = (PFNGLISFENCENVPROC) get_proc("glIsFenceNV"); + gleswTestFenceNV = (PFNGLTESTFENCENVPROC) get_proc("glTestFenceNV"); + gleswGetFenceivNV = (PFNGLGETFENCEIVNVPROC) get_proc("glGetFenceivNV"); + gleswFinishFenceNV = (PFNGLFINISHFENCENVPROC) get_proc("glFinishFenceNV"); + gleswSetFenceNV = (PFNGLSETFENCENVPROC) get_proc("glSetFenceNV"); + gleswBlitFramebufferNV = (PFNGLBLITFRAMEBUFFERNVPROC) get_proc("glBlitFramebufferNV"); + gleswRenderbufferStorageMultisampleNV = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) get_proc("glRenderbufferStorageMultisampleNV"); + gleswVertexAttribDivisorNV = (PFNGLVERTEXATTRIBDIVISORNVPROC) get_proc("glVertexAttribDivisorNV"); + gleswReadBufferNV = (PFNGLREADBUFFERNVPROC) get_proc("glReadBufferNV"); + gleswAlphaFuncQCOM = (PFNGLALPHAFUNCQCOMPROC) get_proc("glAlphaFuncQCOM"); + gleswGetDriverControlsQCOM = (PFNGLGETDRIVERCONTROLSQCOMPROC) get_proc("glGetDriverControlsQCOM"); + gleswGetDriverControlStringQCOM = (PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) get_proc("glGetDriverControlStringQCOM"); + gleswEnableDriverControlQCOM = (PFNGLENABLEDRIVERCONTROLQCOMPROC) get_proc("glEnableDriverControlQCOM"); + gleswDisableDriverControlQCOM = (PFNGLDISABLEDRIVERCONTROLQCOMPROC) get_proc("glDisableDriverControlQCOM"); + gleswExtGetTexturesQCOM = (PFNGLEXTGETTEXTURESQCOMPROC) get_proc("glExtGetTexturesQCOM"); + gleswExtGetBuffersQCOM = (PFNGLEXTGETBUFFERSQCOMPROC) get_proc("glExtGetBuffersQCOM"); + gleswExtGetRenderbuffersQCOM = (PFNGLEXTGETRENDERBUFFERSQCOMPROC) get_proc("glExtGetRenderbuffersQCOM"); + gleswExtGetFramebuffersQCOM = (PFNGLEXTGETFRAMEBUFFERSQCOMPROC) get_proc("glExtGetFramebuffersQCOM"); + gleswExtGetTexLevelParameterivQCOM = (PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) get_proc("glExtGetTexLevelParameterivQCOM"); + gleswExtTexObjectStateOverrideiQCOM = (PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) get_proc("glExtTexObjectStateOverrideiQCOM"); + gleswExtGetTexSubImageQCOM = (PFNGLEXTGETTEXSUBIMAGEQCOMPROC) get_proc("glExtGetTexSubImageQCOM"); + gleswExtGetBufferPointervQCOM = (PFNGLEXTGETBUFFERPOINTERVQCOMPROC) get_proc("glExtGetBufferPointervQCOM"); + gleswExtGetShadersQCOM = (PFNGLEXTGETSHADERSQCOMPROC) get_proc("glExtGetShadersQCOM"); + gleswExtGetProgramsQCOM = (PFNGLEXTGETPROGRAMSQCOMPROC) get_proc("glExtGetProgramsQCOM"); + gleswExtIsProgramBinaryQCOM = (PFNGLEXTISPROGRAMBINARYQCOMPROC) get_proc("glExtIsProgramBinaryQCOM"); + gleswExtGetProgramBinarySourceQCOM = (PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) get_proc("glExtGetProgramBinarySourceQCOM"); + gleswStartTilingQCOM = (PFNGLSTARTTILINGQCOMPROC) get_proc("glStartTilingQCOM"); + gleswEndTilingQCOM = (PFNGLENDTILINGQCOMPROC) get_proc("glEndTilingQCOM"); } diff --git a/RenderSystems/GLES2/src/gles3w.cpp b/RenderSystems/GLES2/src/gles3w.cpp index 51e495d6948..70ac1213b09 100644 --- a/RenderSystems/GLES2/src/gles3w.cpp +++ b/RenderSystems/GLES2/src/gles3w.cpp @@ -9,22 +9,22 @@ static HMODULE libgl; static void open_libgl(void) { - libgl = LoadLibraryA("libGLESv2.dll"); + libgl = LoadLibraryA("libGLESv2.dll"); } static void close_libgl(void) { - FreeLibrary(libgl); + FreeLibrary(libgl); } static void *get_proc(const char *proc) { - void *res; + void *res; - res = eglGetProcAddress(proc); - if (!res) - res = GetProcAddress(libgl, proc); - return res; + res = eglGetProcAddress(proc); + if (!res) + res = GetProcAddress(libgl, proc); + return res; } #elif defined(__APPLE__) || defined(__APPLE_CC__) #import @@ -41,8 +41,8 @@ std::string exec(const char* cmd) { char buffer[128]; std::string result = ""; while(!feof(pipe)) { - if(fgets(buffer, 128, pipe) != NULL) - result += buffer; + if(fgets(buffer, 128, pipe) != NULL) + result += buffer; } pclose(pipe); return result; @@ -76,32 +76,32 @@ static void open_libgl(void) frameworkPath = CFStringCreateWithCString(kCFAllocatorDefault, tempPath, kCFStringEncodingUTF8); } - bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, frameworkPath, kCFURLPOSIXPathStyle, true); CFRelease(frameworkPath); - bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); + bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL); - assert(bundle != NULL); + assert(bundle != NULL); } static void close_libgl(void) { - CFRelease(bundle); - CFRelease(bundleURL); + CFRelease(bundle); + CFRelease(bundleURL); } static void *get_proc(const char *proc) { - void *res; + void *res; - CFStringRef procname = CFStringCreateWithCString(kCFAllocatorDefault, proc, + CFStringRef procname = CFStringCreateWithCString(kCFAllocatorDefault, proc, kCFStringEncodingASCII); - res = CFBundleGetFunctionPointerForName(bundle, procname); - CFRelease(procname); - return res; + res = CFBundleGetFunctionPointerForName(bundle, procname); + CFRelease(procname); + return res; } #else #include @@ -111,61 +111,61 @@ static void *libgl; static void open_libgl(void) { - libgl = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_GLOBAL); + libgl = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_GLOBAL); } static void close_libgl(void) { - dlclose(libgl); + dlclose(libgl); } static void *get_proc(const char *proc) { - void *res; + void *res; res = dlsym(libgl, proc); - return res; + return res; } #endif static struct { - int major, minor; + int major, minor; } version; static int parse_version(void) { - if (!glGetIntegerv) - return -1; + if (!glGetIntegerv) + return -1; - glGetIntegerv(GL_MAJOR_VERSION, &version.major); - glGetIntegerv(GL_MINOR_VERSION, &version.minor); + glGetIntegerv(GL_MAJOR_VERSION, &version.major); + glGetIntegerv(GL_MINOR_VERSION, &version.minor); - if (version.major < 3) - return -1; - return 0; + if (version.major < 3) + return -1; + return 0; } static void load_procs(void); int gleswInit(void) { - open_libgl(); - load_procs(); - close_libgl(); - return parse_version(); + open_libgl(); + load_procs(); + close_libgl(); + return parse_version(); } int gleswIsSupported(int major, int minor) { - if (major < 3) - return 0; - if (version.major == major) - return version.minor >= minor; - return version.major >= major; + if (major < 3) + return 0; + if (version.major == major) + return version.minor >= minor; + return version.major >= major; } void *gleswGetProcAddress(const char *proc) { - return get_proc(proc); + return get_proc(proc); } PFNGLACTIVETEXTUREPROC gleswActiveTexture; @@ -458,291 +458,291 @@ PFNGLPOPGROUPMARKEREXTPROC gleswPopGroupMarkerEXT; static void load_procs(void) { - gleswActiveTexture = (PFNGLACTIVETEXTUREPROC) get_proc("glActiveTexture"); - gleswAttachShader = (PFNGLATTACHSHADERPROC) get_proc("glAttachShader"); - gleswBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) get_proc("glBindAttribLocation"); - gleswBindBuffer = (PFNGLBINDBUFFERPROC) get_proc("glBindBuffer"); - gleswBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) get_proc("glBindFramebuffer"); - gleswBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) get_proc("glBindRenderbuffer"); - gleswBindTexture = (PFNGLBINDTEXTUREPROC) get_proc("glBindTexture"); - gleswBlendColor = (PFNGLBLENDCOLORPROC) get_proc("glBlendColor"); - gleswBlendEquation = (PFNGLBLENDEQUATIONPROC) get_proc("glBlendEquation"); - gleswBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) get_proc("glBlendEquationSeparate"); - gleswBlendFunc = (PFNGLBLENDFUNCPROC) get_proc("glBlendFunc"); - gleswBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) get_proc("glBlendFuncSeparate"); - gleswBufferData = (PFNGLBUFFERDATAPROC) get_proc("glBufferData"); - gleswBufferSubData = (PFNGLBUFFERSUBDATAPROC) get_proc("glBufferSubData"); - gleswCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) get_proc("glCheckFramebufferStatus"); - gleswClear = (PFNGLCLEARPROC) get_proc("glClear"); - gleswClearColor = (PFNGLCLEARCOLORPROC) get_proc("glClearColor"); - gleswClearDepthf = (PFNGLCLEARDEPTHFPROC) get_proc("glClearDepthf"); - gleswClearStencil = (PFNGLCLEARSTENCILPROC) get_proc("glClearStencil"); - gleswColorMask = (PFNGLCOLORMASKPROC) get_proc("glColorMask"); - gleswCompileShader = (PFNGLCOMPILESHADERPROC) get_proc("glCompileShader"); - gleswCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) get_proc("glCompressedTexImage2D"); - gleswCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) get_proc("glCompressedTexSubImage2D"); - gleswCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) get_proc("glCopyTexImage2D"); - gleswCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) get_proc("glCopyTexSubImage2D"); - gleswCreateProgram = (PFNGLCREATEPROGRAMPROC) get_proc("glCreateProgram"); - gleswCreateShader = (PFNGLCREATESHADERPROC) get_proc("glCreateShader"); - gleswCullFace = (PFNGLCULLFACEPROC) get_proc("glCullFace"); - gleswDeleteBuffers = (PFNGLDELETEBUFFERSPROC) get_proc("glDeleteBuffers"); - gleswDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) get_proc("glDeleteFramebuffers"); - gleswDeleteProgram = (PFNGLDELETEPROGRAMPROC) get_proc("glDeleteProgram"); - gleswDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) get_proc("glDeleteRenderbuffers"); - gleswDeleteShader = (PFNGLDELETESHADERPROC) get_proc("glDeleteShader"); - gleswDeleteTextures = (PFNGLDELETETEXTURESPROC) get_proc("glDeleteTextures"); - gleswDepthFunc = (PFNGLDEPTHFUNCPROC) get_proc("glDepthFunc"); - gleswDepthMask = (PFNGLDEPTHMASKPROC) get_proc("glDepthMask"); - gleswDepthRangef = (PFNGLDEPTHRANGEFPROC) get_proc("glDepthRangef"); - gleswDetachShader = (PFNGLDETACHSHADERPROC) get_proc("glDetachShader"); - gleswDisable = (PFNGLDISABLEPROC) get_proc("glDisable"); - gleswDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) get_proc("glDisableVertexAttribArray"); - gleswDrawArrays = (PFNGLDRAWARRAYSPROC) get_proc("glDrawArrays"); - gleswDrawElements = (PFNGLDRAWELEMENTSPROC) get_proc("glDrawElements"); - gleswEnable = (PFNGLENABLEPROC) get_proc("glEnable"); - gleswEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) get_proc("glEnableVertexAttribArray"); - gleswFinish = (PFNGLFINISHPROC) get_proc("glFinish"); - gleswFlush = (PFNGLFLUSHPROC) get_proc("glFlush"); - gleswFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) get_proc("glFramebufferRenderbuffer"); - gleswFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) get_proc("glFramebufferTexture2D"); - gleswFrontFace = (PFNGLFRONTFACEPROC) get_proc("glFrontFace"); - gleswGenBuffers = (PFNGLGENBUFFERSPROC) get_proc("glGenBuffers"); - gleswGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) get_proc("glGenerateMipmap"); - gleswGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) get_proc("glGenFramebuffers"); - gleswGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) get_proc("glGenRenderbuffers"); - gleswGenTextures = (PFNGLGENTEXTURESPROC) get_proc("glGenTextures"); - gleswGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) get_proc("glGetActiveAttrib"); - gleswGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) get_proc("glGetActiveUniform"); - gleswGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) get_proc("glGetAttachedShaders"); - gleswGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) get_proc("glGetAttribLocation"); - gleswGetBooleanv = (PFNGLGETBOOLEANVPROC) get_proc("glGetBooleanv"); - gleswGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) get_proc("glGetBufferParameteriv"); - gleswGetError = (PFNGLGETERRORPROC) get_proc("glGetError"); - gleswGetFloatv = (PFNGLGETFLOATVPROC) get_proc("glGetFloatv"); - gleswGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) get_proc("glGetFramebufferAttachmentParameteriv"); - gleswGetIntegerv = (PFNGLGETINTEGERVPROC) get_proc("glGetIntegerv"); - gleswGetProgramiv = (PFNGLGETPROGRAMIVPROC) get_proc("glGetProgramiv"); - gleswGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) get_proc("glGetProgramInfoLog"); - gleswGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) get_proc("glGetRenderbufferParameteriv"); - gleswGetShaderiv = (PFNGLGETSHADERIVPROC) get_proc("glGetShaderiv"); - gleswGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) get_proc("glGetShaderInfoLog"); - gleswGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) get_proc("glGetShaderPrecisionFormat"); - gleswGetShaderSource = (PFNGLGETSHADERSOURCEPROC) get_proc("glGetShaderSource"); - gleswGetString = (PFNGLGETSTRINGPROC) get_proc("glGetString"); - gleswGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) get_proc("glGetTexParameterfv"); - gleswGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) get_proc("glGetTexParameteriv"); - gleswGetUniformfv = (PFNGLGETUNIFORMFVPROC) get_proc("glGetUniformfv"); - gleswGetUniformiv = (PFNGLGETUNIFORMIVPROC) get_proc("glGetUniformiv"); - gleswGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) get_proc("glGetUniformLocation"); - gleswGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) get_proc("glGetVertexAttribfv"); - gleswGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) get_proc("glGetVertexAttribiv"); - gleswGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) get_proc("glGetVertexAttribPointerv"); - gleswHint = (PFNGLHINTPROC) get_proc("glHint"); - gleswIsBuffer = (PFNGLISBUFFERPROC) get_proc("glIsBuffer"); - gleswIsEnabled = (PFNGLISENABLEDPROC) get_proc("glIsEnabled"); - gleswIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) get_proc("glIsFramebuffer"); - gleswIsProgram = (PFNGLISPROGRAMPROC) get_proc("glIsProgram"); - gleswIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) get_proc("glIsRenderbuffer"); - gleswIsShader = (PFNGLISSHADERPROC) get_proc("glIsShader"); - gleswIsTexture = (PFNGLISTEXTUREPROC) get_proc("glIsTexture"); - gleswLineWidth = (PFNGLLINEWIDTHPROC) get_proc("glLineWidth"); - gleswLinkProgram = (PFNGLLINKPROGRAMPROC) get_proc("glLinkProgram"); - gleswPixelStorei = (PFNGLPIXELSTOREIPROC) get_proc("glPixelStorei"); - gleswPolygonOffset = (PFNGLPOLYGONOFFSETPROC) get_proc("glPolygonOffset"); - gleswReadPixels = (PFNGLREADPIXELSPROC) get_proc("glReadPixels"); - gleswReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) get_proc("glReleaseShaderCompiler"); - gleswRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) get_proc("glRenderbufferStorage"); - gleswSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) get_proc("glSampleCoverage"); - gleswScissor = (PFNGLSCISSORPROC) get_proc("glScissor"); - gleswShaderBinary = (PFNGLSHADERBINARYPROC) get_proc("glShaderBinary"); - gleswShaderSource = (PFNGLSHADERSOURCEPROC) get_proc("glShaderSource"); - gleswStencilFunc = (PFNGLSTENCILFUNCPROC) get_proc("glStencilFunc"); - gleswStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) get_proc("glStencilFuncSeparate"); - gleswStencilMask = (PFNGLSTENCILMASKPROC) get_proc("glStencilMask"); - gleswStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) get_proc("glStencilMaskSeparate"); - gleswStencilOp = (PFNGLSTENCILOPPROC) get_proc("glStencilOp"); - gleswStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) get_proc("glStencilOpSeparate"); - gleswTexImage2D = (PFNGLTEXIMAGE2DPROC) get_proc("glTexImage2D"); - gleswTexParameterf = (PFNGLTEXPARAMETERFPROC) get_proc("glTexParameterf"); - gleswTexParameterfv = (PFNGLTEXPARAMETERFVPROC) get_proc("glTexParameterfv"); - gleswTexParameteri = (PFNGLTEXPARAMETERIPROC) get_proc("glTexParameteri"); - gleswTexParameteriv = (PFNGLTEXPARAMETERIVPROC) get_proc("glTexParameteriv"); - gleswTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) get_proc("glTexSubImage2D"); - gleswUniform1f = (PFNGLUNIFORM1FPROC) get_proc("glUniform1f"); - gleswUniform1fv = (PFNGLUNIFORM1FVPROC) get_proc("glUniform1fv"); - gleswUniform1i = (PFNGLUNIFORM1IPROC) get_proc("glUniform1i"); - gleswUniform1iv = (PFNGLUNIFORM1IVPROC) get_proc("glUniform1iv"); - gleswUniform2f = (PFNGLUNIFORM2FPROC) get_proc("glUniform2f"); - gleswUniform2fv = (PFNGLUNIFORM2FVPROC) get_proc("glUniform2fv"); - gleswUniform2i = (PFNGLUNIFORM2IPROC) get_proc("glUniform2i"); - gleswUniform2iv = (PFNGLUNIFORM2IVPROC) get_proc("glUniform2iv"); - gleswUniform3f = (PFNGLUNIFORM3FPROC) get_proc("glUniform3f"); - gleswUniform3fv = (PFNGLUNIFORM3FVPROC) get_proc("glUniform3fv"); - gleswUniform3i = (PFNGLUNIFORM3IPROC) get_proc("glUniform3i"); - gleswUniform3iv = (PFNGLUNIFORM3IVPROC) get_proc("glUniform3iv"); - gleswUniform4f = (PFNGLUNIFORM4FPROC) get_proc("glUniform4f"); - gleswUniform4fv = (PFNGLUNIFORM4FVPROC) get_proc("glUniform4fv"); - gleswUniform4i = (PFNGLUNIFORM4IPROC) get_proc("glUniform4i"); - gleswUniform4iv = (PFNGLUNIFORM4IVPROC) get_proc("glUniform4iv"); - gleswUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) get_proc("glUniformMatrix2fv"); - gleswUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) get_proc("glUniformMatrix3fv"); - gleswUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) get_proc("glUniformMatrix4fv"); - gleswUseProgram = (PFNGLUSEPROGRAMPROC) get_proc("glUseProgram"); - gleswValidateProgram = (PFNGLVALIDATEPROGRAMPROC) get_proc("glValidateProgram"); - gleswVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) get_proc("glVertexAttrib1f"); - gleswVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) get_proc("glVertexAttrib1fv"); - gleswVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) get_proc("glVertexAttrib2f"); - gleswVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) get_proc("glVertexAttrib2fv"); - gleswVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) get_proc("glVertexAttrib3f"); - gleswVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) get_proc("glVertexAttrib3fv"); - gleswVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) get_proc("glVertexAttrib4f"); - gleswVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) get_proc("glVertexAttrib4fv"); - gleswVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) get_proc("glVertexAttribPointer"); - gleswViewport = (PFNGLVIEWPORTPROC) get_proc("glViewport"); - gleswReadBuffer = (PFNGLREADBUFFERPROC) get_proc("glReadBuffer"); - gleswDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) get_proc("glDrawRangeElements"); - gleswTexImage3D = (PFNGLTEXIMAGE3DPROC) get_proc("glTexImage3D"); - gleswTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) get_proc("glTexSubImage3D"); - gleswCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) get_proc("glCopyTexSubImage3D"); - gleswCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) get_proc("glCompressedTexImage3D"); - gleswCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) get_proc("glCompressedTexSubImage3D"); - gleswGenQueries = (PFNGLGENQUERIESPROC) get_proc("glGenQueries"); - gleswDeleteQueries = (PFNGLDELETEQUERIESPROC) get_proc("glDeleteQueries"); - gleswIsQuery = (PFNGLISQUERYPROC) get_proc("glIsQuery"); - gleswBeginQuery = (PFNGLBEGINQUERYPROC) get_proc("glBeginQuery"); - gleswEndQuery = (PFNGLENDQUERYPROC) get_proc("glEndQuery"); - gleswGetQueryiv = (PFNGLGETQUERYIVPROC) get_proc("glGetQueryiv"); - gleswGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) get_proc("glGetQueryObjectuiv"); - gleswUnmapBuffer = (PFNGLUNMAPBUFFERPROC) get_proc("glUnmapBuffer"); - gleswGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) get_proc("glGetBufferPointerv"); - gleswDrawBuffers = (PFNGLDRAWBUFFERSPROC) get_proc("glDrawBuffers"); - gleswUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) get_proc("glUniformMatrix2x3fv"); - gleswUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) get_proc("glUniformMatrix3x2fv"); - gleswUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) get_proc("glUniformMatrix2x4fv"); - gleswUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) get_proc("glUniformMatrix4x2fv"); - gleswUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) get_proc("glUniformMatrix3x4fv"); - gleswUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) get_proc("glUniformMatrix4x3fv"); - gleswBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) get_proc("glBlitFramebuffer"); - gleswRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) get_proc("glRenderbufferStorageMultisample"); - gleswFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) get_proc("glFramebufferTextureLayer"); - gleswMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) get_proc("glMapBufferRange"); - gleswFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) get_proc("glFlushMappedBufferRange"); - gleswBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) get_proc("glBindVertexArray"); - gleswDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) get_proc("glDeleteVertexArrays"); - gleswGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) get_proc("glGenVertexArrays"); - gleswIsVertexArray = (PFNGLISVERTEXARRAYPROC) get_proc("glIsVertexArray"); - gleswGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) get_proc("glGetIntegeri_v"); - gleswBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) get_proc("glBeginTransformFeedback"); - gleswEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) get_proc("glEndTransformFeedback"); - gleswBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) get_proc("glBindBufferRange"); - gleswBindBufferBase = (PFNGLBINDBUFFERBASEPROC) get_proc("glBindBufferBase"); - gleswTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) get_proc("glTransformFeedbackVaryings"); - gleswGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) get_proc("glGetTransformFeedbackVarying"); - gleswVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) get_proc("glVertexAttribIPointer"); - gleswGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) get_proc("glGetVertexAttribIiv"); - gleswGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) get_proc("glGetVertexAttribIuiv"); - gleswVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) get_proc("glVertexAttribI4i"); - gleswVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) get_proc("glVertexAttribI4ui"); - gleswVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) get_proc("glVertexAttribI4iv"); - gleswVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) get_proc("glVertexAttribI4uiv"); - gleswGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) get_proc("glGetUniformuiv"); - gleswGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) get_proc("glGetFragDataLocation"); - gleswUniform1ui = (PFNGLUNIFORM1UIPROC) get_proc("glUniform1ui"); - gleswUniform2ui = (PFNGLUNIFORM2UIPROC) get_proc("glUniform2ui"); - gleswUniform3ui = (PFNGLUNIFORM3UIPROC) get_proc("glUniform3ui"); - gleswUniform4ui = (PFNGLUNIFORM4UIPROC) get_proc("glUniform4ui"); - gleswUniform1uiv = (PFNGLUNIFORM1UIVPROC) get_proc("glUniform1uiv"); - gleswUniform2uiv = (PFNGLUNIFORM2UIVPROC) get_proc("glUniform2uiv"); - gleswUniform3uiv = (PFNGLUNIFORM3UIVPROC) get_proc("glUniform3uiv"); - gleswUniform4uiv = (PFNGLUNIFORM4UIVPROC) get_proc("glUniform4uiv"); - gleswClearBufferiv = (PFNGLCLEARBUFFERIVPROC) get_proc("glClearBufferiv"); - gleswClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) get_proc("glClearBufferuiv"); - gleswClearBufferfv = (PFNGLCLEARBUFFERFVPROC) get_proc("glClearBufferfv"); - gleswClearBufferfi = (PFNGLCLEARBUFFERFIPROC) get_proc("glClearBufferfi"); - gleswGetStringi = (PFNGLGETSTRINGIPROC) get_proc("glGetStringi"); - gleswCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) get_proc("glCopyBufferSubData"); - gleswGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) get_proc("glGetUniformIndices"); - gleswGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) get_proc("glGetActiveUniformsiv"); - gleswGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) get_proc("glGetUniformBlockIndex"); - gleswGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) get_proc("glGetActiveUniformBlockiv"); - gleswGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) get_proc("glGetActiveUniformBlockName"); - gleswUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) get_proc("glUniformBlockBinding"); - gleswDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) get_proc("glDrawArraysInstanced"); - gleswDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) get_proc("glDrawElementsInstanced"); - gleswFenceSync = (PFNGLFENCESYNCPROC) get_proc("glFenceSync"); - gleswIsSync = (PFNGLISSYNCPROC) get_proc("glIsSync"); - gleswDeleteSync = (PFNGLDELETESYNCPROC) get_proc("glDeleteSync"); - gleswClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) get_proc("glClientWaitSync"); - gleswWaitSync = (PFNGLWAITSYNCPROC) get_proc("glWaitSync"); - gleswGetInteger64v = (PFNGLGETINTEGER64VPROC) get_proc("glGetInteger64v"); - gleswGetSynciv = (PFNGLGETSYNCIVPROC) get_proc("glGetSynciv"); - gleswGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) get_proc("glGetInteger64i_v"); - gleswGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) get_proc("glGetBufferParameteri64v"); - gleswGenSamplers = (PFNGLGENSAMPLERSPROC) get_proc("glGenSamplers"); - gleswDeleteSamplers = (PFNGLDELETESAMPLERSPROC) get_proc("glDeleteSamplers"); - gleswIsSampler = (PFNGLISSAMPLERPROC) get_proc("glIsSampler"); - gleswBindSampler = (PFNGLBINDSAMPLERPROC) get_proc("glBindSampler"); - gleswSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) get_proc("glSamplerParameteri"); - gleswSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) get_proc("glSamplerParameteriv"); - gleswSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) get_proc("glSamplerParameterf"); - gleswSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) get_proc("glSamplerParameterfv"); - gleswGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) get_proc("glGetSamplerParameteriv"); - gleswGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) get_proc("glGetSamplerParameterfv"); - gleswVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) get_proc("glVertexAttribDivisor"); - gleswBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) get_proc("glBindTransformFeedback"); - gleswDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) get_proc("glDeleteTransformFeedbacks"); - gleswGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) get_proc("glGenTransformFeedbacks"); - gleswIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) get_proc("glIsTransformFeedback"); - gleswPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) get_proc("glPauseTransformFeedback"); - gleswResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) get_proc("glResumeTransformFeedback"); - gleswGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) get_proc("glGetProgramBinary"); - gleswProgramBinary = (PFNGLPROGRAMBINARYPROC) get_proc("glProgramBinary"); - gleswProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) get_proc("glProgramParameteri"); - gleswInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) get_proc("glInvalidateFramebuffer"); - gleswInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) get_proc("glInvalidateSubFramebuffer"); - gleswTexStorage2D = (PFNGLTEXSTORAGE2DPROC) get_proc("glTexStorage2D"); - gleswTexStorage3D = (PFNGLTEXSTORAGE3DPROC) get_proc("glTexStorage3D"); - gleswGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) get_proc("glGetInternalformativ"); - gleswLabelObjectEXT = (PFNGLLABELOBJECTEXTPROC) get_proc("glLabelObjectEXT"); - gleswGetObjectLabelEXT = (PFNGLGETOBJECTLABELEXTPROC) get_proc("glGetObjectLabelEXT"); - gleswInsertEventMarkerEXT = (PFNGLINSERTEVENTMARKEREXTPROC) get_proc("glInsertEventMarkerEXT"); - gleswPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC) get_proc("glPushGroupMarkerEXT"); - gleswPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC) get_proc("glPopGroupMarkerEXT"); - gleswUseProgramStagesEXT = (PFNGLUSEPROGRAMSTAGESEXTPROC) get_proc("glUseProgramStagesEXT"); - gleswActiveShaderProgramEXT = (PFNGLACTIVESHADERPROGRAMEXTPROC) get_proc("glActiveShaderProgramEXT"); - gleswCreateShaderProgramvEXT = (PFNGLCREATESHADERPROGRAMVEXTPROC) get_proc("glCreateShaderProgramvEXT"); - gleswBindProgramPipelineEXT = (PFNGLBINDPROGRAMPIPELINEEXTPROC) get_proc("glBindProgramPipelineEXT"); - gleswDeleteProgramPipelinesEXT = (PFNGLDELETEPROGRAMPIPELINESEXTPROC) get_proc("glDeleteProgramPipelinesEXT"); - gleswGenProgramPipelinesEXT = (PFNGLGENPROGRAMPIPELINESEXTPROC) get_proc("glGenProgramPipelinesEXT"); - gleswIsProgramPipelineEXT = (PFNGLISPROGRAMPIPELINEEXTPROC) get_proc("glIsProgramPipelineEXT"); - gleswProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC) get_proc("glProgramParameteriEXT"); - gleswGetProgramPipelineivEXT = (PFNGLGETPROGRAMPIPELINEIVEXTPROC) get_proc("glGetProgramPipelineivEXT"); - gleswProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC) get_proc("glProgramUniform1iEXT"); - gleswProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC) get_proc("glProgramUniform2iEXT"); - gleswProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC) get_proc("glProgramUniform3iEXT"); - gleswProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC) get_proc("glProgramUniform4iEXT"); - gleswProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC) get_proc("glProgramUniform1fEXT"); - gleswProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC) get_proc("glProgramUniform2fEXT"); - gleswProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC) get_proc("glProgramUniform3fEXT"); - gleswProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC) get_proc("glProgramUniform4fEXT"); - gleswProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC) get_proc("glProgramUniform1ivEXT"); - gleswProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC) get_proc("glProgramUniform2ivEXT"); - gleswProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC) get_proc("glProgramUniform3ivEXT"); - gleswProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC) get_proc("glProgramUniform4ivEXT"); - gleswProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC) get_proc("glProgramUniform1fvEXT"); - gleswProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC) get_proc("glProgramUniform2fvEXT"); - gleswProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC) get_proc("glProgramUniform3fvEXT"); - gleswProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC) get_proc("glProgramUniform4fvEXT"); - gleswProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) get_proc("glProgramUniformMatrix2fvEXT"); - gleswProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) get_proc("glProgramUniformMatrix3fvEXT"); - gleswProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) get_proc("glProgramUniformMatrix4fvEXT"); - gleswProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) get_proc("glProgramUniformMatrix2x3fvEXT"); - gleswProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) get_proc("glProgramUniformMatrix3x2fvEXT"); - gleswProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) get_proc("glProgramUniformMatrix2x4fvEXT"); - gleswProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) get_proc("glProgramUniformMatrix4x2fvEXT"); - gleswProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) get_proc("glProgramUniformMatrix3x4fvEXT"); - gleswProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) get_proc("glProgramUniformMatrix4x3fvEXT"); - gleswValidateProgramPipelineEXT = (PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) get_proc("glValidateProgramPipelineEXT"); - gleswGetProgramPipelineInfoLogEXT = (PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) get_proc("glGetProgramPipelineInfoLogEXT"); + gleswActiveTexture = (PFNGLACTIVETEXTUREPROC) get_proc("glActiveTexture"); + gleswAttachShader = (PFNGLATTACHSHADERPROC) get_proc("glAttachShader"); + gleswBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) get_proc("glBindAttribLocation"); + gleswBindBuffer = (PFNGLBINDBUFFERPROC) get_proc("glBindBuffer"); + gleswBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) get_proc("glBindFramebuffer"); + gleswBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) get_proc("glBindRenderbuffer"); + gleswBindTexture = (PFNGLBINDTEXTUREPROC) get_proc("glBindTexture"); + gleswBlendColor = (PFNGLBLENDCOLORPROC) get_proc("glBlendColor"); + gleswBlendEquation = (PFNGLBLENDEQUATIONPROC) get_proc("glBlendEquation"); + gleswBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) get_proc("glBlendEquationSeparate"); + gleswBlendFunc = (PFNGLBLENDFUNCPROC) get_proc("glBlendFunc"); + gleswBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) get_proc("glBlendFuncSeparate"); + gleswBufferData = (PFNGLBUFFERDATAPROC) get_proc("glBufferData"); + gleswBufferSubData = (PFNGLBUFFERSUBDATAPROC) get_proc("glBufferSubData"); + gleswCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) get_proc("glCheckFramebufferStatus"); + gleswClear = (PFNGLCLEARPROC) get_proc("glClear"); + gleswClearColor = (PFNGLCLEARCOLORPROC) get_proc("glClearColor"); + gleswClearDepthf = (PFNGLCLEARDEPTHFPROC) get_proc("glClearDepthf"); + gleswClearStencil = (PFNGLCLEARSTENCILPROC) get_proc("glClearStencil"); + gleswColorMask = (PFNGLCOLORMASKPROC) get_proc("glColorMask"); + gleswCompileShader = (PFNGLCOMPILESHADERPROC) get_proc("glCompileShader"); + gleswCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) get_proc("glCompressedTexImage2D"); + gleswCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) get_proc("glCompressedTexSubImage2D"); + gleswCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) get_proc("glCopyTexImage2D"); + gleswCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) get_proc("glCopyTexSubImage2D"); + gleswCreateProgram = (PFNGLCREATEPROGRAMPROC) get_proc("glCreateProgram"); + gleswCreateShader = (PFNGLCREATESHADERPROC) get_proc("glCreateShader"); + gleswCullFace = (PFNGLCULLFACEPROC) get_proc("glCullFace"); + gleswDeleteBuffers = (PFNGLDELETEBUFFERSPROC) get_proc("glDeleteBuffers"); + gleswDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) get_proc("glDeleteFramebuffers"); + gleswDeleteProgram = (PFNGLDELETEPROGRAMPROC) get_proc("glDeleteProgram"); + gleswDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) get_proc("glDeleteRenderbuffers"); + gleswDeleteShader = (PFNGLDELETESHADERPROC) get_proc("glDeleteShader"); + gleswDeleteTextures = (PFNGLDELETETEXTURESPROC) get_proc("glDeleteTextures"); + gleswDepthFunc = (PFNGLDEPTHFUNCPROC) get_proc("glDepthFunc"); + gleswDepthMask = (PFNGLDEPTHMASKPROC) get_proc("glDepthMask"); + gleswDepthRangef = (PFNGLDEPTHRANGEFPROC) get_proc("glDepthRangef"); + gleswDetachShader = (PFNGLDETACHSHADERPROC) get_proc("glDetachShader"); + gleswDisable = (PFNGLDISABLEPROC) get_proc("glDisable"); + gleswDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) get_proc("glDisableVertexAttribArray"); + gleswDrawArrays = (PFNGLDRAWARRAYSPROC) get_proc("glDrawArrays"); + gleswDrawElements = (PFNGLDRAWELEMENTSPROC) get_proc("glDrawElements"); + gleswEnable = (PFNGLENABLEPROC) get_proc("glEnable"); + gleswEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) get_proc("glEnableVertexAttribArray"); + gleswFinish = (PFNGLFINISHPROC) get_proc("glFinish"); + gleswFlush = (PFNGLFLUSHPROC) get_proc("glFlush"); + gleswFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) get_proc("glFramebufferRenderbuffer"); + gleswFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) get_proc("glFramebufferTexture2D"); + gleswFrontFace = (PFNGLFRONTFACEPROC) get_proc("glFrontFace"); + gleswGenBuffers = (PFNGLGENBUFFERSPROC) get_proc("glGenBuffers"); + gleswGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) get_proc("glGenerateMipmap"); + gleswGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) get_proc("glGenFramebuffers"); + gleswGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) get_proc("glGenRenderbuffers"); + gleswGenTextures = (PFNGLGENTEXTURESPROC) get_proc("glGenTextures"); + gleswGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) get_proc("glGetActiveAttrib"); + gleswGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) get_proc("glGetActiveUniform"); + gleswGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) get_proc("glGetAttachedShaders"); + gleswGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) get_proc("glGetAttribLocation"); + gleswGetBooleanv = (PFNGLGETBOOLEANVPROC) get_proc("glGetBooleanv"); + gleswGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) get_proc("glGetBufferParameteriv"); + gleswGetError = (PFNGLGETERRORPROC) get_proc("glGetError"); + gleswGetFloatv = (PFNGLGETFLOATVPROC) get_proc("glGetFloatv"); + gleswGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) get_proc("glGetFramebufferAttachmentParameteriv"); + gleswGetIntegerv = (PFNGLGETINTEGERVPROC) get_proc("glGetIntegerv"); + gleswGetProgramiv = (PFNGLGETPROGRAMIVPROC) get_proc("glGetProgramiv"); + gleswGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) get_proc("glGetProgramInfoLog"); + gleswGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) get_proc("glGetRenderbufferParameteriv"); + gleswGetShaderiv = (PFNGLGETSHADERIVPROC) get_proc("glGetShaderiv"); + gleswGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) get_proc("glGetShaderInfoLog"); + gleswGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) get_proc("glGetShaderPrecisionFormat"); + gleswGetShaderSource = (PFNGLGETSHADERSOURCEPROC) get_proc("glGetShaderSource"); + gleswGetString = (PFNGLGETSTRINGPROC) get_proc("glGetString"); + gleswGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) get_proc("glGetTexParameterfv"); + gleswGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) get_proc("glGetTexParameteriv"); + gleswGetUniformfv = (PFNGLGETUNIFORMFVPROC) get_proc("glGetUniformfv"); + gleswGetUniformiv = (PFNGLGETUNIFORMIVPROC) get_proc("glGetUniformiv"); + gleswGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) get_proc("glGetUniformLocation"); + gleswGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) get_proc("glGetVertexAttribfv"); + gleswGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) get_proc("glGetVertexAttribiv"); + gleswGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) get_proc("glGetVertexAttribPointerv"); + gleswHint = (PFNGLHINTPROC) get_proc("glHint"); + gleswIsBuffer = (PFNGLISBUFFERPROC) get_proc("glIsBuffer"); + gleswIsEnabled = (PFNGLISENABLEDPROC) get_proc("glIsEnabled"); + gleswIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) get_proc("glIsFramebuffer"); + gleswIsProgram = (PFNGLISPROGRAMPROC) get_proc("glIsProgram"); + gleswIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) get_proc("glIsRenderbuffer"); + gleswIsShader = (PFNGLISSHADERPROC) get_proc("glIsShader"); + gleswIsTexture = (PFNGLISTEXTUREPROC) get_proc("glIsTexture"); + gleswLineWidth = (PFNGLLINEWIDTHPROC) get_proc("glLineWidth"); + gleswLinkProgram = (PFNGLLINKPROGRAMPROC) get_proc("glLinkProgram"); + gleswPixelStorei = (PFNGLPIXELSTOREIPROC) get_proc("glPixelStorei"); + gleswPolygonOffset = (PFNGLPOLYGONOFFSETPROC) get_proc("glPolygonOffset"); + gleswReadPixels = (PFNGLREADPIXELSPROC) get_proc("glReadPixels"); + gleswReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) get_proc("glReleaseShaderCompiler"); + gleswRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) get_proc("glRenderbufferStorage"); + gleswSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) get_proc("glSampleCoverage"); + gleswScissor = (PFNGLSCISSORPROC) get_proc("glScissor"); + gleswShaderBinary = (PFNGLSHADERBINARYPROC) get_proc("glShaderBinary"); + gleswShaderSource = (PFNGLSHADERSOURCEPROC) get_proc("glShaderSource"); + gleswStencilFunc = (PFNGLSTENCILFUNCPROC) get_proc("glStencilFunc"); + gleswStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) get_proc("glStencilFuncSeparate"); + gleswStencilMask = (PFNGLSTENCILMASKPROC) get_proc("glStencilMask"); + gleswStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) get_proc("glStencilMaskSeparate"); + gleswStencilOp = (PFNGLSTENCILOPPROC) get_proc("glStencilOp"); + gleswStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) get_proc("glStencilOpSeparate"); + gleswTexImage2D = (PFNGLTEXIMAGE2DPROC) get_proc("glTexImage2D"); + gleswTexParameterf = (PFNGLTEXPARAMETERFPROC) get_proc("glTexParameterf"); + gleswTexParameterfv = (PFNGLTEXPARAMETERFVPROC) get_proc("glTexParameterfv"); + gleswTexParameteri = (PFNGLTEXPARAMETERIPROC) get_proc("glTexParameteri"); + gleswTexParameteriv = (PFNGLTEXPARAMETERIVPROC) get_proc("glTexParameteriv"); + gleswTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) get_proc("glTexSubImage2D"); + gleswUniform1f = (PFNGLUNIFORM1FPROC) get_proc("glUniform1f"); + gleswUniform1fv = (PFNGLUNIFORM1FVPROC) get_proc("glUniform1fv"); + gleswUniform1i = (PFNGLUNIFORM1IPROC) get_proc("glUniform1i"); + gleswUniform1iv = (PFNGLUNIFORM1IVPROC) get_proc("glUniform1iv"); + gleswUniform2f = (PFNGLUNIFORM2FPROC) get_proc("glUniform2f"); + gleswUniform2fv = (PFNGLUNIFORM2FVPROC) get_proc("glUniform2fv"); + gleswUniform2i = (PFNGLUNIFORM2IPROC) get_proc("glUniform2i"); + gleswUniform2iv = (PFNGLUNIFORM2IVPROC) get_proc("glUniform2iv"); + gleswUniform3f = (PFNGLUNIFORM3FPROC) get_proc("glUniform3f"); + gleswUniform3fv = (PFNGLUNIFORM3FVPROC) get_proc("glUniform3fv"); + gleswUniform3i = (PFNGLUNIFORM3IPROC) get_proc("glUniform3i"); + gleswUniform3iv = (PFNGLUNIFORM3IVPROC) get_proc("glUniform3iv"); + gleswUniform4f = (PFNGLUNIFORM4FPROC) get_proc("glUniform4f"); + gleswUniform4fv = (PFNGLUNIFORM4FVPROC) get_proc("glUniform4fv"); + gleswUniform4i = (PFNGLUNIFORM4IPROC) get_proc("glUniform4i"); + gleswUniform4iv = (PFNGLUNIFORM4IVPROC) get_proc("glUniform4iv"); + gleswUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) get_proc("glUniformMatrix2fv"); + gleswUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) get_proc("glUniformMatrix3fv"); + gleswUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) get_proc("glUniformMatrix4fv"); + gleswUseProgram = (PFNGLUSEPROGRAMPROC) get_proc("glUseProgram"); + gleswValidateProgram = (PFNGLVALIDATEPROGRAMPROC) get_proc("glValidateProgram"); + gleswVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) get_proc("glVertexAttrib1f"); + gleswVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) get_proc("glVertexAttrib1fv"); + gleswVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) get_proc("glVertexAttrib2f"); + gleswVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) get_proc("glVertexAttrib2fv"); + gleswVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) get_proc("glVertexAttrib3f"); + gleswVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) get_proc("glVertexAttrib3fv"); + gleswVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) get_proc("glVertexAttrib4f"); + gleswVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) get_proc("glVertexAttrib4fv"); + gleswVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) get_proc("glVertexAttribPointer"); + gleswViewport = (PFNGLVIEWPORTPROC) get_proc("glViewport"); + gleswReadBuffer = (PFNGLREADBUFFERPROC) get_proc("glReadBuffer"); + gleswDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) get_proc("glDrawRangeElements"); + gleswTexImage3D = (PFNGLTEXIMAGE3DPROC) get_proc("glTexImage3D"); + gleswTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) get_proc("glTexSubImage3D"); + gleswCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) get_proc("glCopyTexSubImage3D"); + gleswCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) get_proc("glCompressedTexImage3D"); + gleswCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) get_proc("glCompressedTexSubImage3D"); + gleswGenQueries = (PFNGLGENQUERIESPROC) get_proc("glGenQueries"); + gleswDeleteQueries = (PFNGLDELETEQUERIESPROC) get_proc("glDeleteQueries"); + gleswIsQuery = (PFNGLISQUERYPROC) get_proc("glIsQuery"); + gleswBeginQuery = (PFNGLBEGINQUERYPROC) get_proc("glBeginQuery"); + gleswEndQuery = (PFNGLENDQUERYPROC) get_proc("glEndQuery"); + gleswGetQueryiv = (PFNGLGETQUERYIVPROC) get_proc("glGetQueryiv"); + gleswGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) get_proc("glGetQueryObjectuiv"); + gleswUnmapBuffer = (PFNGLUNMAPBUFFERPROC) get_proc("glUnmapBuffer"); + gleswGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) get_proc("glGetBufferPointerv"); + gleswDrawBuffers = (PFNGLDRAWBUFFERSPROC) get_proc("glDrawBuffers"); + gleswUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) get_proc("glUniformMatrix2x3fv"); + gleswUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) get_proc("glUniformMatrix3x2fv"); + gleswUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) get_proc("glUniformMatrix2x4fv"); + gleswUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) get_proc("glUniformMatrix4x2fv"); + gleswUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) get_proc("glUniformMatrix3x4fv"); + gleswUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) get_proc("glUniformMatrix4x3fv"); + gleswBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) get_proc("glBlitFramebuffer"); + gleswRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) get_proc("glRenderbufferStorageMultisample"); + gleswFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) get_proc("glFramebufferTextureLayer"); + gleswMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) get_proc("glMapBufferRange"); + gleswFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) get_proc("glFlushMappedBufferRange"); + gleswBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) get_proc("glBindVertexArray"); + gleswDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) get_proc("glDeleteVertexArrays"); + gleswGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) get_proc("glGenVertexArrays"); + gleswIsVertexArray = (PFNGLISVERTEXARRAYPROC) get_proc("glIsVertexArray"); + gleswGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) get_proc("glGetIntegeri_v"); + gleswBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) get_proc("glBeginTransformFeedback"); + gleswEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) get_proc("glEndTransformFeedback"); + gleswBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) get_proc("glBindBufferRange"); + gleswBindBufferBase = (PFNGLBINDBUFFERBASEPROC) get_proc("glBindBufferBase"); + gleswTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) get_proc("glTransformFeedbackVaryings"); + gleswGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) get_proc("glGetTransformFeedbackVarying"); + gleswVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) get_proc("glVertexAttribIPointer"); + gleswGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) get_proc("glGetVertexAttribIiv"); + gleswGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) get_proc("glGetVertexAttribIuiv"); + gleswVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) get_proc("glVertexAttribI4i"); + gleswVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) get_proc("glVertexAttribI4ui"); + gleswVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) get_proc("glVertexAttribI4iv"); + gleswVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) get_proc("glVertexAttribI4uiv"); + gleswGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) get_proc("glGetUniformuiv"); + gleswGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) get_proc("glGetFragDataLocation"); + gleswUniform1ui = (PFNGLUNIFORM1UIPROC) get_proc("glUniform1ui"); + gleswUniform2ui = (PFNGLUNIFORM2UIPROC) get_proc("glUniform2ui"); + gleswUniform3ui = (PFNGLUNIFORM3UIPROC) get_proc("glUniform3ui"); + gleswUniform4ui = (PFNGLUNIFORM4UIPROC) get_proc("glUniform4ui"); + gleswUniform1uiv = (PFNGLUNIFORM1UIVPROC) get_proc("glUniform1uiv"); + gleswUniform2uiv = (PFNGLUNIFORM2UIVPROC) get_proc("glUniform2uiv"); + gleswUniform3uiv = (PFNGLUNIFORM3UIVPROC) get_proc("glUniform3uiv"); + gleswUniform4uiv = (PFNGLUNIFORM4UIVPROC) get_proc("glUniform4uiv"); + gleswClearBufferiv = (PFNGLCLEARBUFFERIVPROC) get_proc("glClearBufferiv"); + gleswClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) get_proc("glClearBufferuiv"); + gleswClearBufferfv = (PFNGLCLEARBUFFERFVPROC) get_proc("glClearBufferfv"); + gleswClearBufferfi = (PFNGLCLEARBUFFERFIPROC) get_proc("glClearBufferfi"); + gleswGetStringi = (PFNGLGETSTRINGIPROC) get_proc("glGetStringi"); + gleswCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) get_proc("glCopyBufferSubData"); + gleswGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) get_proc("glGetUniformIndices"); + gleswGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) get_proc("glGetActiveUniformsiv"); + gleswGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) get_proc("glGetUniformBlockIndex"); + gleswGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) get_proc("glGetActiveUniformBlockiv"); + gleswGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) get_proc("glGetActiveUniformBlockName"); + gleswUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) get_proc("glUniformBlockBinding"); + gleswDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) get_proc("glDrawArraysInstanced"); + gleswDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) get_proc("glDrawElementsInstanced"); + gleswFenceSync = (PFNGLFENCESYNCPROC) get_proc("glFenceSync"); + gleswIsSync = (PFNGLISSYNCPROC) get_proc("glIsSync"); + gleswDeleteSync = (PFNGLDELETESYNCPROC) get_proc("glDeleteSync"); + gleswClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) get_proc("glClientWaitSync"); + gleswWaitSync = (PFNGLWAITSYNCPROC) get_proc("glWaitSync"); + gleswGetInteger64v = (PFNGLGETINTEGER64VPROC) get_proc("glGetInteger64v"); + gleswGetSynciv = (PFNGLGETSYNCIVPROC) get_proc("glGetSynciv"); + gleswGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) get_proc("glGetInteger64i_v"); + gleswGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) get_proc("glGetBufferParameteri64v"); + gleswGenSamplers = (PFNGLGENSAMPLERSPROC) get_proc("glGenSamplers"); + gleswDeleteSamplers = (PFNGLDELETESAMPLERSPROC) get_proc("glDeleteSamplers"); + gleswIsSampler = (PFNGLISSAMPLERPROC) get_proc("glIsSampler"); + gleswBindSampler = (PFNGLBINDSAMPLERPROC) get_proc("glBindSampler"); + gleswSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) get_proc("glSamplerParameteri"); + gleswSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) get_proc("glSamplerParameteriv"); + gleswSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) get_proc("glSamplerParameterf"); + gleswSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) get_proc("glSamplerParameterfv"); + gleswGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) get_proc("glGetSamplerParameteriv"); + gleswGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) get_proc("glGetSamplerParameterfv"); + gleswVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) get_proc("glVertexAttribDivisor"); + gleswBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) get_proc("glBindTransformFeedback"); + gleswDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) get_proc("glDeleteTransformFeedbacks"); + gleswGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) get_proc("glGenTransformFeedbacks"); + gleswIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) get_proc("glIsTransformFeedback"); + gleswPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) get_proc("glPauseTransformFeedback"); + gleswResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) get_proc("glResumeTransformFeedback"); + gleswGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) get_proc("glGetProgramBinary"); + gleswProgramBinary = (PFNGLPROGRAMBINARYPROC) get_proc("glProgramBinary"); + gleswProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) get_proc("glProgramParameteri"); + gleswInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) get_proc("glInvalidateFramebuffer"); + gleswInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) get_proc("glInvalidateSubFramebuffer"); + gleswTexStorage2D = (PFNGLTEXSTORAGE2DPROC) get_proc("glTexStorage2D"); + gleswTexStorage3D = (PFNGLTEXSTORAGE3DPROC) get_proc("glTexStorage3D"); + gleswGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) get_proc("glGetInternalformativ"); + gleswLabelObjectEXT = (PFNGLLABELOBJECTEXTPROC) get_proc("glLabelObjectEXT"); + gleswGetObjectLabelEXT = (PFNGLGETOBJECTLABELEXTPROC) get_proc("glGetObjectLabelEXT"); + gleswInsertEventMarkerEXT = (PFNGLINSERTEVENTMARKEREXTPROC) get_proc("glInsertEventMarkerEXT"); + gleswPushGroupMarkerEXT = (PFNGLPUSHGROUPMARKEREXTPROC) get_proc("glPushGroupMarkerEXT"); + gleswPopGroupMarkerEXT = (PFNGLPOPGROUPMARKEREXTPROC) get_proc("glPopGroupMarkerEXT"); + gleswUseProgramStagesEXT = (PFNGLUSEPROGRAMSTAGESEXTPROC) get_proc("glUseProgramStagesEXT"); + gleswActiveShaderProgramEXT = (PFNGLACTIVESHADERPROGRAMEXTPROC) get_proc("glActiveShaderProgramEXT"); + gleswCreateShaderProgramvEXT = (PFNGLCREATESHADERPROGRAMVEXTPROC) get_proc("glCreateShaderProgramvEXT"); + gleswBindProgramPipelineEXT = (PFNGLBINDPROGRAMPIPELINEEXTPROC) get_proc("glBindProgramPipelineEXT"); + gleswDeleteProgramPipelinesEXT = (PFNGLDELETEPROGRAMPIPELINESEXTPROC) get_proc("glDeleteProgramPipelinesEXT"); + gleswGenProgramPipelinesEXT = (PFNGLGENPROGRAMPIPELINESEXTPROC) get_proc("glGenProgramPipelinesEXT"); + gleswIsProgramPipelineEXT = (PFNGLISPROGRAMPIPELINEEXTPROC) get_proc("glIsProgramPipelineEXT"); + gleswProgramParameteriEXT = (PFNGLPROGRAMPARAMETERIEXTPROC) get_proc("glProgramParameteriEXT"); + gleswGetProgramPipelineivEXT = (PFNGLGETPROGRAMPIPELINEIVEXTPROC) get_proc("glGetProgramPipelineivEXT"); + gleswProgramUniform1iEXT = (PFNGLPROGRAMUNIFORM1IEXTPROC) get_proc("glProgramUniform1iEXT"); + gleswProgramUniform2iEXT = (PFNGLPROGRAMUNIFORM2IEXTPROC) get_proc("glProgramUniform2iEXT"); + gleswProgramUniform3iEXT = (PFNGLPROGRAMUNIFORM3IEXTPROC) get_proc("glProgramUniform3iEXT"); + gleswProgramUniform4iEXT = (PFNGLPROGRAMUNIFORM4IEXTPROC) get_proc("glProgramUniform4iEXT"); + gleswProgramUniform1fEXT = (PFNGLPROGRAMUNIFORM1FEXTPROC) get_proc("glProgramUniform1fEXT"); + gleswProgramUniform2fEXT = (PFNGLPROGRAMUNIFORM2FEXTPROC) get_proc("glProgramUniform2fEXT"); + gleswProgramUniform3fEXT = (PFNGLPROGRAMUNIFORM3FEXTPROC) get_proc("glProgramUniform3fEXT"); + gleswProgramUniform4fEXT = (PFNGLPROGRAMUNIFORM4FEXTPROC) get_proc("glProgramUniform4fEXT"); + gleswProgramUniform1ivEXT = (PFNGLPROGRAMUNIFORM1IVEXTPROC) get_proc("glProgramUniform1ivEXT"); + gleswProgramUniform2ivEXT = (PFNGLPROGRAMUNIFORM2IVEXTPROC) get_proc("glProgramUniform2ivEXT"); + gleswProgramUniform3ivEXT = (PFNGLPROGRAMUNIFORM3IVEXTPROC) get_proc("glProgramUniform3ivEXT"); + gleswProgramUniform4ivEXT = (PFNGLPROGRAMUNIFORM4IVEXTPROC) get_proc("glProgramUniform4ivEXT"); + gleswProgramUniform1fvEXT = (PFNGLPROGRAMUNIFORM1FVEXTPROC) get_proc("glProgramUniform1fvEXT"); + gleswProgramUniform2fvEXT = (PFNGLPROGRAMUNIFORM2FVEXTPROC) get_proc("glProgramUniform2fvEXT"); + gleswProgramUniform3fvEXT = (PFNGLPROGRAMUNIFORM3FVEXTPROC) get_proc("glProgramUniform3fvEXT"); + gleswProgramUniform4fvEXT = (PFNGLPROGRAMUNIFORM4FVEXTPROC) get_proc("glProgramUniform4fvEXT"); + gleswProgramUniformMatrix2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) get_proc("glProgramUniformMatrix2fvEXT"); + gleswProgramUniformMatrix3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) get_proc("glProgramUniformMatrix3fvEXT"); + gleswProgramUniformMatrix4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) get_proc("glProgramUniformMatrix4fvEXT"); + gleswProgramUniformMatrix2x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) get_proc("glProgramUniformMatrix2x3fvEXT"); + gleswProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) get_proc("glProgramUniformMatrix3x2fvEXT"); + gleswProgramUniformMatrix2x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) get_proc("glProgramUniformMatrix2x4fvEXT"); + gleswProgramUniformMatrix4x2fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) get_proc("glProgramUniformMatrix4x2fvEXT"); + gleswProgramUniformMatrix3x4fvEXT = (PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) get_proc("glProgramUniformMatrix3x4fvEXT"); + gleswProgramUniformMatrix4x3fvEXT = (PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) get_proc("glProgramUniformMatrix4x3fvEXT"); + gleswValidateProgramPipelineEXT = (PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) get_proc("glValidateProgramPipelineEXT"); + gleswGetProgramPipelineInfoLogEXT = (PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) get_proc("glGetProgramPipelineInfoLogEXT"); } diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/DemoApp.cpp b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/DemoApp.cpp index 367271318f5..5d39fa09740 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/DemoApp.cpp +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/DemoApp.cpp @@ -9,90 +9,90 @@ DemoApp::DemoApp() { - m_pCubeNode = 0; - m_pCubeEntity = 0; + m_pCubeNode = 0; + m_pCubeEntity = 0; } //||||||||||||||||||||||||||||||||||||||||||||||| DemoApp::~DemoApp() { - delete OgreFramework::getSingletonPtr(); + delete OgreFramework::getSingletonPtr(); } //||||||||||||||||||||||||||||||||||||||||||||||| void DemoApp::startDemo() { - new OgreFramework(); + new OgreFramework(); if(!OgreFramework::getSingletonPtr()->initOgre("DemoApp v1.0", this, 0)) return; - - m_bShutdown = false; + + m_bShutdown = false; - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Demo initialized!"); + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Demo initialized!"); - setupDemoScene(); - runDemo(); + setupDemoScene(); + runDemo(); } //||||||||||||||||||||||||||||||||||||||||||||||| void DemoApp::setupDemoScene() { - OgreFramework::getSingletonPtr()->m_pSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox"); + OgreFramework::getSingletonPtr()->m_pSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox"); - OgreFramework::getSingletonPtr()->m_pSceneMgr->createLight("Light")->setPosition(75,75,75); + OgreFramework::getSingletonPtr()->m_pSceneMgr->createLight("Light")->setPosition(75,75,75); - m_pCubeEntity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("Cube", "ogrehead.mesh"); - m_pCubeNode = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode("CubeNode"); - m_pCubeNode->attachObject(m_pCubeEntity); + m_pCubeEntity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("Cube", "ogrehead.mesh"); + m_pCubeNode = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode("CubeNode"); + m_pCubeNode->attachObject(m_pCubeEntity); } //||||||||||||||||||||||||||||||||||||||||||||||| void DemoApp::runDemo() { - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Start main loop..."); - - double timeSinceLastFrame = 0; - double startTime = 0; + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Start main loop..."); + + double timeSinceLastFrame = 0; + double startTime = 0; - OgreFramework::getSingletonPtr()->m_pRenderWnd->resetStatistics(); - - while(!m_bShutdown && !OgreFramework::getSingletonPtr()->isOgreToBeShutDown()) - { - if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isClosed())m_bShutdown = true; + OgreFramework::getSingletonPtr()->m_pRenderWnd->resetStatistics(); + + while(!m_bShutdown && !OgreFramework::getSingletonPtr()->isOgreToBeShutDown()) + { + if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isClosed())m_bShutdown = true; #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - Ogre::WindowEventUtilities::messagePump(); -#endif - if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) - { - startTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); - + Ogre::WindowEventUtilities::messagePump(); +#endif + if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) + { + startTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); + #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - OgreFramework::getSingletonPtr()->m_pKeyboard->capture(); + OgreFramework::getSingletonPtr()->m_pKeyboard->capture(); #endif - OgreFramework::getSingletonPtr()->m_pMouse->capture(); - - OgreFramework::getSingletonPtr()->updateOgre(timeSinceLastFrame); - OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); - - timeSinceLastFrame = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - startTime; - } - else - { + OgreFramework::getSingletonPtr()->m_pMouse->capture(); + + OgreFramework::getSingletonPtr()->updateOgre(timeSinceLastFrame); + OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); + + timeSinceLastFrame = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - startTime; + } + else + { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 Sleep(1000); #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE sleep(1000); #endif - } - } + } + } - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Main loop quit"); - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Shutdown OGRE..."); + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Main loop quit"); + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Shutdown OGRE..."); } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -100,23 +100,23 @@ void DemoApp::runDemo() bool DemoApp::keyPressed(const OIS::KeyEvent &keyEventRef) { #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - OgreFramework::getSingletonPtr()->keyPressed(keyEventRef); - - if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_F)) - { - //do something - } + OgreFramework::getSingletonPtr()->keyPressed(keyEventRef); + + if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_F)) + { + //do something + } #endif - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| bool DemoApp::keyReleased(const OIS::KeyEvent &keyEventRef) { - OgreFramework::getSingletonPtr()->keyReleased(keyEventRef); - - return true; + OgreFramework::getSingletonPtr()->keyReleased(keyEventRef); + + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/DemoApp.h b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/DemoApp.h index 54ca82bdbe0..7867f0d560f 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/DemoApp.h +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/DemoApp.h @@ -12,23 +12,23 @@ class DemoApp : public OIS::KeyListener { public: - DemoApp(); - ~DemoApp(); + DemoApp(); + ~DemoApp(); - void startDemo(); - void setupDemoScene(); + void startDemo(); + void setupDemoScene(); void setShutdown(bool flag) { m_bShutdown = flag; } - - bool keyPressed(const OIS::KeyEvent &keyEventRef); - bool keyReleased(const OIS::KeyEvent &keyEventRef); + + bool keyPressed(const OIS::KeyEvent &keyEventRef); + bool keyReleased(const OIS::KeyEvent &keyEventRef); private: - void runDemo(); + void runDemo(); - Ogre::SceneNode* m_pCubeNode; - Ogre::Entity* m_pCubeEntity; + Ogre::SceneNode* m_pCubeNode; + Ogre::Entity* m_pCubeEntity; - bool m_bShutdown; + bool m_bShutdown; }; //||||||||||||||||||||||||||||||||||||||||||||||| diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/OgreFramework.cpp b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/OgreFramework.cpp index ef822361487..60171c975f1 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/OgreFramework.cpp +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/OgreFramework.cpp @@ -16,26 +16,26 @@ template<> OgreFramework* Ogre::Singleton::msSingleton = 0; OgreFramework::OgreFramework() { - m_MoveSpeed = 0.1; - m_RotateSpeed = 0.3; - - m_bShutDownOgre = false; - m_iNumScreenShots = 0; - - m_pRoot = 0; - m_pSceneMgr = 0; - m_pRenderWnd = 0; - m_pCamera = 0; - m_pViewport = 0; - m_pLog = 0; - m_pTimer = 0; - - m_pInputMgr = 0; - m_pKeyboard = 0; - m_pMouse = 0; - - m_pDebugOverlay = 0; - m_pInfoOverlay = 0; + m_MoveSpeed = 0.1; + m_RotateSpeed = 0.3; + + m_bShutDownOgre = false; + m_iNumScreenShots = 0; + + m_pRoot = 0; + m_pSceneMgr = 0; + m_pRenderWnd = 0; + m_pCamera = 0; + m_pViewport = 0; + m_pLog = 0; + m_pTimer = 0; + + m_pInputMgr = 0; + m_pKeyboard = 0; + m_pMouse = 0; + + m_pDebugOverlay = 0; + m_pInfoOverlay = 0; #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE m_ResourcePath = macBundlePath() + "/Contents/Resources/"; @@ -55,9 +55,9 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen { new Ogre::LogManager(); - m_pLog = Ogre::LogManager::getSingleton().createLog("OgreLogfile.log", true, true, false); - m_pLog->setDebugOutputEnabled(true); - + m_pLog = Ogre::LogManager::getSingleton().createLog("OgreLogfile.log", true, true, false); + m_pLog->setDebugOutputEnabled(true); + String pluginsPath; // only use plugins.cfg if not static #ifndef OGRE_STATIC_LIB @@ -73,67 +73,67 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen if(!m_pRoot->showConfigDialog()) return false; - m_pRenderWnd = m_pRoot->initialise(true, wndTitle); + m_pRenderWnd = m_pRoot->initialise(true, wndTitle); #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE m_pRenderWnd->reposition(0, 0); m_pRenderWnd->resize(320, 480); #endif - m_pSceneMgr = m_pRoot->createSceneManager(ST_GENERIC, "SceneManager"); - m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.7, 0.7, 0.7)); - - m_pCamera = m_pSceneMgr->createCamera("Camera"); - m_pCamera->setPosition(Vector3(0, 60, 60)); - m_pCamera->lookAt(Vector3(0,0,0)); - m_pCamera->setNearClipDistance(1); + m_pSceneMgr = m_pRoot->createSceneManager(ST_GENERIC, "SceneManager"); + m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.7, 0.7, 0.7)); + + m_pCamera = m_pSceneMgr->createCamera("Camera"); + m_pCamera->setPosition(Vector3(0, 60, 60)); + m_pCamera->lookAt(Vector3(0,0,0)); + m_pCamera->setNearClipDistance(1); - m_pViewport = m_pRenderWnd->addViewport(m_pCamera); - m_pViewport->setBackgroundColour(ColourValue(0.8, 0.7, 0.6, 1.0)); + m_pViewport = m_pRenderWnd->addViewport(m_pCamera); + m_pViewport->setBackgroundColour(ColourValue(0.8, 0.7, 0.6, 1.0)); - m_pCamera->setAspectRatio(Real(m_pViewport->getActualWidth()) / Real(m_pViewport->getActualHeight())); - - m_pViewport->setCamera(m_pCamera); + m_pCamera->setAspectRatio(Real(m_pViewport->getActualWidth()) / Real(m_pViewport->getActualHeight())); + + m_pViewport->setCamera(m_pCamera); - unsigned long hWnd = 0; + unsigned long hWnd = 0; OIS::ParamList paramList; m_pRenderWnd->getCustomAttribute("WINDOW", &hWnd); - paramList.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(hWnd))); + paramList.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(hWnd))); - m_pInputMgr = OIS::InputManager::createInputSystem(paramList); + m_pInputMgr = OIS::InputManager::createInputSystem(paramList); #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE m_pKeyboard = static_cast(m_pInputMgr->createInputObject(OIS::OISKeyboard, true)); - m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMouse, true)); + m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMouse, true)); - m_pMouse->getMouseState().height = m_pRenderWnd->getHeight(); - m_pMouse->getMouseState().width = m_pRenderWnd->getWidth(); + m_pMouse->getMouseState().height = m_pRenderWnd->getHeight(); + m_pMouse->getMouseState().width = m_pRenderWnd->getWidth(); #else - m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMultiTouch, true)); + m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMultiTouch, true)); #endif #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - if(pKeyListener == 0) - m_pKeyboard->setEventCallback(this); - else - m_pKeyboard->setEventCallback(pKeyListener); + if(pKeyListener == 0) + m_pKeyboard->setEventCallback(this); + else + m_pKeyboard->setEventCallback(pKeyListener); #endif - if(pMouseListener == 0) - m_pMouse->setEventCallback(this); - else - m_pMouse->setEventCallback(pMouseListener); + if(pMouseListener == 0) + m_pMouse->setEventCallback(this); + else + m_pMouse->setEventCallback(pMouseListener); - Ogre::String secName, typeName, archName; - Ogre::ConfigFile cf; + Ogre::String secName, typeName, archName; + Ogre::ConfigFile cf; cf.load(m_ResourcePath + "resources.cfg"); - Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); + Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); while (seci.hasMoreElements()) { secName = seci.peekNextKey(); - Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); + Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); Ogre::ConfigFile::SettingsMultiMap::iterator i; for (i = settings->begin(); i != settings->end(); ++i) { @@ -149,16 +149,16 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName); } } - Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); - Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); + Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - m_pTimer = OGRE_NEW Ogre::Timer(); - m_pTimer->reset(); - - m_pDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); - m_pDebugOverlay->show(); + m_pTimer = OGRE_NEW Ogre::Timer(); + m_pTimer->reset(); + + m_pDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); + m_pDebugOverlay->show(); - m_pRenderWnd->setActive(true); + m_pRenderWnd->setActive(true); return true; } @@ -167,16 +167,16 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen OgreFramework::~OgreFramework() { - if(m_pInputMgr) - { - OIS::InputManager::destroyInputSystem(m_pInputMgr); - } + if(m_pInputMgr) + { + OIS::InputManager::destroyInputSystem(m_pInputMgr); + } #ifdef OGRE_STATIC_LIB m_StaticPluginLoader.unload(); #endif - OGRE_DELETE m_pRoot; + OGRE_DELETE m_pRoot; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -184,62 +184,62 @@ OgreFramework::~OgreFramework() bool OgreFramework::keyPressed(const OIS::KeyEvent &keyEventRef) { #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - m_pLog->logMessage("OgreFramework::keyPressed"); - - if(m_pKeyboard->isKeyDown(OIS::KC_ESCAPE)) - { - m_bShutDownOgre = true; - return true; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_SYSRQ)) - { - std::ostringstream ss; - ss << "screenshot_" << ++m_iNumScreenShots << ".png"; - m_pRenderWnd->writeContentsToFile(ss.str()); - return true; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_M)) - { - static int mode = 0; - - if(mode == 2) - { - m_pCamera->setPolygonMode(PM_SOLID); - mode = 0; - } - else if(mode == 0) - { - m_pCamera->setPolygonMode(PM_WIREFRAME); - mode = 1; - } - else if(mode == 1) - { - m_pCamera->setPolygonMode(PM_POINTS); - mode = 2; - } - } - - if(m_pKeyboard->isKeyDown(OIS::KC_O)) - { - if(m_pDebugOverlay) - { - if(!m_pDebugOverlay->isVisible()) - m_pDebugOverlay->show(); - else - m_pDebugOverlay->hide(); - } - } + m_pLog->logMessage("OgreFramework::keyPressed"); + + if(m_pKeyboard->isKeyDown(OIS::KC_ESCAPE)) + { + m_bShutDownOgre = true; + return true; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_SYSRQ)) + { + std::ostringstream ss; + ss << "screenshot_" << ++m_iNumScreenShots << ".png"; + m_pRenderWnd->writeContentsToFile(ss.str()); + return true; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_M)) + { + static int mode = 0; + + if(mode == 2) + { + m_pCamera->setPolygonMode(PM_SOLID); + mode = 0; + } + else if(mode == 0) + { + m_pCamera->setPolygonMode(PM_WIREFRAME); + mode = 1; + } + else if(mode == 1) + { + m_pCamera->setPolygonMode(PM_POINTS); + mode = 2; + } + } + + if(m_pKeyboard->isKeyDown(OIS::KC_O)) + { + if(m_pDebugOverlay) + { + if(!m_pDebugOverlay->isVisible()) + m_pDebugOverlay->show(); + else + m_pDebugOverlay->hide(); + } + } #endif - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| bool OgreFramework::keyReleased(const OIS::KeyEvent &keyEventRef) { - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -270,10 +270,10 @@ bool OgreFramework::touchMoved(const OIS::MultiTouchEvent &evt) default: break; } - m_pCamera->yaw(Degree(state.X.rel * -0.1)); - m_pCamera->pitch(Degree(state.Y.rel * -0.1)); - - return true; + m_pCamera->yaw(Degree(state.X.rel * -0.1)); + m_pCamera->pitch(Degree(state.Y.rel * -0.1)); + + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -281,7 +281,7 @@ bool OgreFramework::touchMoved(const OIS::MultiTouchEvent &evt) bool OgreFramework::touchPressed(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -289,35 +289,35 @@ bool OgreFramework::touchPressed(const OIS:: MultiTouchEvent &evt) bool OgreFramework::touchReleased(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } bool OgreFramework::touchCancelled(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } #else bool OgreFramework::mouseMoved(const OIS::MouseEvent &evt) { - m_pCamera->yaw(Degree(evt.state.X.rel * -0.1)); - m_pCamera->pitch(Degree(evt.state.Y.rel * -0.1)); - - return true; + m_pCamera->yaw(Degree(evt.state.X.rel * -0.1)); + m_pCamera->pitch(Degree(evt.state.Y.rel * -0.1)); + + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| bool OgreFramework::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| bool OgreFramework::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { - return true; + return true; } #endif @@ -325,22 +325,22 @@ bool OgreFramework::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID void OgreFramework::updateOgre(double timeSinceLastFrame) { - m_MoveScale = m_MoveSpeed * timeSinceLastFrame; - m_RotScale = m_RotateSpeed * timeSinceLastFrame; - - m_TranslateVector = Vector3::ZERO; + m_MoveScale = m_MoveSpeed * timeSinceLastFrame; + m_RotScale = m_RotateSpeed * timeSinceLastFrame; + + m_TranslateVector = Vector3::ZERO; - getInput(); - moveCamera(); + getInput(); + moveCamera(); - updateStats(); + updateStats(); } //||||||||||||||||||||||||||||||||||||||||||||||| void OgreFramework::updateStats() { - static String currFps = "Current FPS: "; + static String currFps = "Current FPS: "; static String avgFps = "Average FPS: "; static String bestFps = "Best FPS: "; static String worstFps = "Worst FPS: "; @@ -352,7 +352,7 @@ void OgreFramework::updateStats() OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps"); OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps"); - const RenderTarget::FrameStats& stats = m_pRenderWnd->getStatistics(); + const RenderTarget::FrameStats& stats = m_pRenderWnd->getStatistics(); guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS)); guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS)); guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS) @@ -363,11 +363,11 @@ void OgreFramework::updateStats() OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris"); guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount)); - OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches"); + OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches"); guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount)); - OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); - guiDbg->setCaption(""); + OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); + guiDbg->setCaption(""); } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -375,9 +375,9 @@ void OgreFramework::updateStats() void OgreFramework::moveCamera() { #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - if(m_pKeyboard->isKeyDown(OIS::KC_LSHIFT)) m_pCamera->moveRelative(m_TranslateVector); + if(m_pKeyboard->isKeyDown(OIS::KC_LSHIFT)) m_pCamera->moveRelative(m_TranslateVector); #endif - m_pCamera->moveRelative(m_TranslateVector / 10); + m_pCamera->moveRelative(m_TranslateVector / 10); } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -385,45 +385,45 @@ void OgreFramework::moveCamera() void OgreFramework::getInput() { #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - if(m_pKeyboard->isKeyDown(OIS::KC_A)) - { - m_TranslateVector.x = -m_MoveScale; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_D)) - { - m_TranslateVector.x = m_MoveScale; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_W)) - { - m_TranslateVector.z = -m_MoveScale; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_S)) - { - m_TranslateVector.z = m_MoveScale; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_LEFT)) - { - m_pCamera->yaw(m_RotScale); - } - - if(m_pKeyboard->isKeyDown(OIS::KC_RIGHT)) - { - m_pCamera->yaw(-m_RotScale); - } - - if(m_pKeyboard->isKeyDown(OIS::KC_UP)) - { - m_pCamera->pitch(m_RotScale); - } - - if(m_pKeyboard->isKeyDown(OIS::KC_DOWN)) - { - m_pCamera->pitch(-m_RotScale); - } + if(m_pKeyboard->isKeyDown(OIS::KC_A)) + { + m_TranslateVector.x = -m_MoveScale; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_D)) + { + m_TranslateVector.x = m_MoveScale; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_W)) + { + m_TranslateVector.z = -m_MoveScale; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_S)) + { + m_TranslateVector.z = m_MoveScale; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_LEFT)) + { + m_pCamera->yaw(m_RotScale); + } + + if(m_pKeyboard->isKeyDown(OIS::KC_RIGHT)) + { + m_pCamera->yaw(-m_RotScale); + } + + if(m_pKeyboard->isKeyDown(OIS::KC_UP)) + { + m_pCamera->pitch(m_RotScale); + } + + if(m_pKeyboard->isKeyDown(OIS::KC_DOWN)) + { + m_pCamera->pitch(-m_RotScale); + } #endif } diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/OgreFramework.h b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/OgreFramework.h index 17db2c69b88..fe6495e6339 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/OgreFramework.h +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/OgreFramework.h @@ -63,49 +63,49 @@ class OgreFramework : public Ogre::Singleton, OIS::KeyListener, O #endif { public: - OgreFramework(); - ~OgreFramework(); + OgreFramework(); + ~OgreFramework(); #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MultiTouchListener *pMouseListener = 0); #else bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MouseListener *pMouseListener = 0); #endif - void updateOgre(double timeSinceLastFrame); - void updateStats(); - void moveCamera(); - void getInput(); + void updateOgre(double timeSinceLastFrame); + void updateStats(); + void moveCamera(); + void getInput(); - bool isOgreToBeShutDown()const{return m_bShutDownOgre;} + bool isOgreToBeShutDown()const{return m_bShutDownOgre;} - bool keyPressed(const OIS::KeyEvent &keyEventRef); - bool keyReleased(const OIS::KeyEvent &keyEventRef); + bool keyPressed(const OIS::KeyEvent &keyEventRef); + bool keyReleased(const OIS::KeyEvent &keyEventRef); #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE - bool touchMoved(const OIS::MultiTouchEvent &evt); - bool touchPressed(const OIS::MultiTouchEvent &evt); - bool touchReleased(const OIS::MultiTouchEvent &evt); - bool touchCancelled(const OIS::MultiTouchEvent &evt); + bool touchMoved(const OIS::MultiTouchEvent &evt); + bool touchPressed(const OIS::MultiTouchEvent &evt); + bool touchReleased(const OIS::MultiTouchEvent &evt); + bool touchCancelled(const OIS::MultiTouchEvent &evt); #else - bool mouseMoved(const OIS::MouseEvent &evt); - bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id); - bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id); + bool mouseMoved(const OIS::MouseEvent &evt); + bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id); + bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id); #endif - - Ogre::Root* m_pRoot; - Ogre::SceneManager* m_pSceneMgr; - Ogre::RenderWindow* m_pRenderWnd; - Ogre::Camera* m_pCamera; - Ogre::Viewport* m_pViewport; - Ogre::Log* m_pLog; - Ogre::Timer* m_pTimer; - - OIS::InputManager* m_pInputMgr; - OIS::Keyboard* m_pKeyboard; + + Ogre::Root* m_pRoot; + Ogre::SceneManager* m_pSceneMgr; + Ogre::RenderWindow* m_pRenderWnd; + Ogre::Camera* m_pCamera; + Ogre::Viewport* m_pViewport; + Ogre::Log* m_pLog; + Ogre::Timer* m_pTimer; + + OIS::InputManager* m_pInputMgr; + OIS::Keyboard* m_pKeyboard; #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE - OIS::MultiTouch* m_pMouse; + OIS::MultiTouch* m_pMouse; #else - OIS::Mouse* m_pMouse; + OIS::Mouse* m_pMouse; #endif protected: @@ -113,20 +113,20 @@ class OgreFramework : public Ogre::Singleton, OIS::KeyListener, O Ogre::String m_ResourcePath; private: - OgreFramework(const OgreFramework&); - OgreFramework& operator= (const OgreFramework&); - - Ogre::Overlay* m_pDebugOverlay; - Ogre::Overlay* m_pInfoOverlay; - int m_iNumScreenShots; - - bool m_bShutDownOgre; - - Ogre::Vector3 m_TranslateVector; - Ogre::Real m_MoveSpeed; - Ogre::Degree m_RotateSpeed; - float m_MoveScale; - Ogre::Degree m_RotScale; + OgreFramework(const OgreFramework&); + OgreFramework& operator= (const OgreFramework&); + + Ogre::Overlay* m_pDebugOverlay; + Ogre::Overlay* m_pInfoOverlay; + int m_iNumScreenShots; + + bool m_bShutDownOgre; + + Ogre::Vector3 m_TranslateVector; + Ogre::Real m_MoveSpeed; + Ogre::Degree m_RotateSpeed; + float m_MoveScale; + Ogre::Degree m_RotScale; #ifdef OGRE_STATIC_LIB Ogre::StaticPluginLoader m_StaticPluginLoader; #endif diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/main.cpp b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/main.cpp index 472dc43a78b..9161f415fc0 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/main.cpp +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/Mac OS X/Classes/main.cpp @@ -58,12 +58,12 @@ int main(int argc, char **argv) [pool release]; return retVal; #else - try + try { - DemoApp demo; - demo.startDemo(); + DemoApp demo; + demo.startDemo(); } - catch(Ogre::Exception& e) + catch(Ogre::Exception& e) { #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBoxA(NULL, e.what(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL); @@ -84,8 +84,8 @@ int main(int argc, char **argv) { DemoApp demo; NSTimer *mTimer; - double timeSinceLastFrame; - double startTime; + double timeSinceLastFrame; + double startTime; } - (void)go; diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/DemoApp.cpp b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/DemoApp.cpp index 367271318f5..5d39fa09740 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/DemoApp.cpp +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/DemoApp.cpp @@ -9,90 +9,90 @@ DemoApp::DemoApp() { - m_pCubeNode = 0; - m_pCubeEntity = 0; + m_pCubeNode = 0; + m_pCubeEntity = 0; } //||||||||||||||||||||||||||||||||||||||||||||||| DemoApp::~DemoApp() { - delete OgreFramework::getSingletonPtr(); + delete OgreFramework::getSingletonPtr(); } //||||||||||||||||||||||||||||||||||||||||||||||| void DemoApp::startDemo() { - new OgreFramework(); + new OgreFramework(); if(!OgreFramework::getSingletonPtr()->initOgre("DemoApp v1.0", this, 0)) return; - - m_bShutdown = false; + + m_bShutdown = false; - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Demo initialized!"); + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Demo initialized!"); - setupDemoScene(); - runDemo(); + setupDemoScene(); + runDemo(); } //||||||||||||||||||||||||||||||||||||||||||||||| void DemoApp::setupDemoScene() { - OgreFramework::getSingletonPtr()->m_pSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox"); + OgreFramework::getSingletonPtr()->m_pSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox"); - OgreFramework::getSingletonPtr()->m_pSceneMgr->createLight("Light")->setPosition(75,75,75); + OgreFramework::getSingletonPtr()->m_pSceneMgr->createLight("Light")->setPosition(75,75,75); - m_pCubeEntity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("Cube", "ogrehead.mesh"); - m_pCubeNode = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode("CubeNode"); - m_pCubeNode->attachObject(m_pCubeEntity); + m_pCubeEntity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("Cube", "ogrehead.mesh"); + m_pCubeNode = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode("CubeNode"); + m_pCubeNode->attachObject(m_pCubeEntity); } //||||||||||||||||||||||||||||||||||||||||||||||| void DemoApp::runDemo() { - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Start main loop..."); - - double timeSinceLastFrame = 0; - double startTime = 0; + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Start main loop..."); + + double timeSinceLastFrame = 0; + double startTime = 0; - OgreFramework::getSingletonPtr()->m_pRenderWnd->resetStatistics(); - - while(!m_bShutdown && !OgreFramework::getSingletonPtr()->isOgreToBeShutDown()) - { - if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isClosed())m_bShutdown = true; + OgreFramework::getSingletonPtr()->m_pRenderWnd->resetStatistics(); + + while(!m_bShutdown && !OgreFramework::getSingletonPtr()->isOgreToBeShutDown()) + { + if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isClosed())m_bShutdown = true; #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - Ogre::WindowEventUtilities::messagePump(); -#endif - if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) - { - startTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); - + Ogre::WindowEventUtilities::messagePump(); +#endif + if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) + { + startTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); + #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - OgreFramework::getSingletonPtr()->m_pKeyboard->capture(); + OgreFramework::getSingletonPtr()->m_pKeyboard->capture(); #endif - OgreFramework::getSingletonPtr()->m_pMouse->capture(); - - OgreFramework::getSingletonPtr()->updateOgre(timeSinceLastFrame); - OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); - - timeSinceLastFrame = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - startTime; - } - else - { + OgreFramework::getSingletonPtr()->m_pMouse->capture(); + + OgreFramework::getSingletonPtr()->updateOgre(timeSinceLastFrame); + OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); + + timeSinceLastFrame = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - startTime; + } + else + { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 Sleep(1000); #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE sleep(1000); #endif - } - } + } + } - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Main loop quit"); - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Shutdown OGRE..."); + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Main loop quit"); + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Shutdown OGRE..."); } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -100,23 +100,23 @@ void DemoApp::runDemo() bool DemoApp::keyPressed(const OIS::KeyEvent &keyEventRef) { #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - OgreFramework::getSingletonPtr()->keyPressed(keyEventRef); - - if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_F)) - { - //do something - } + OgreFramework::getSingletonPtr()->keyPressed(keyEventRef); + + if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_F)) + { + //do something + } #endif - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| bool DemoApp::keyReleased(const OIS::KeyEvent &keyEventRef) { - OgreFramework::getSingletonPtr()->keyReleased(keyEventRef); - - return true; + OgreFramework::getSingletonPtr()->keyReleased(keyEventRef); + + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/DemoApp.h b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/DemoApp.h index 54ca82bdbe0..7867f0d560f 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/DemoApp.h +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/DemoApp.h @@ -12,23 +12,23 @@ class DemoApp : public OIS::KeyListener { public: - DemoApp(); - ~DemoApp(); + DemoApp(); + ~DemoApp(); - void startDemo(); - void setupDemoScene(); + void startDemo(); + void setupDemoScene(); void setShutdown(bool flag) { m_bShutdown = flag; } - - bool keyPressed(const OIS::KeyEvent &keyEventRef); - bool keyReleased(const OIS::KeyEvent &keyEventRef); + + bool keyPressed(const OIS::KeyEvent &keyEventRef); + bool keyReleased(const OIS::KeyEvent &keyEventRef); private: - void runDemo(); + void runDemo(); - Ogre::SceneNode* m_pCubeNode; - Ogre::Entity* m_pCubeEntity; + Ogre::SceneNode* m_pCubeNode; + Ogre::Entity* m_pCubeEntity; - bool m_bShutdown; + bool m_bShutdown; }; //||||||||||||||||||||||||||||||||||||||||||||||| diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreFramework.cpp b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreFramework.cpp index fef94024cb4..5c11e9f0611 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreFramework.cpp +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreFramework.cpp @@ -16,26 +16,26 @@ template<> OgreFramework* Ogre::Singleton::msSingleton = 0; OgreFramework::OgreFramework() { - m_MoveSpeed = 0.1; - m_RotateSpeed = 0.3; + m_MoveSpeed = 0.1; + m_RotateSpeed = 0.3; - m_bShutDownOgre = false; - m_iNumScreenShots = 0; + m_bShutDownOgre = false; + m_iNumScreenShots = 0; - m_pRoot = 0; - m_pSceneMgr = 0; - m_pRenderWnd = 0; - m_pCamera = 0; - m_pViewport = 0; - m_pLog = 0; - m_pTimer = 0; + m_pRoot = 0; + m_pSceneMgr = 0; + m_pRenderWnd = 0; + m_pCamera = 0; + m_pViewport = 0; + m_pLog = 0; + m_pTimer = 0; - m_pInputMgr = 0; - m_pKeyboard = 0; - m_pMouse = 0; + m_pInputMgr = 0; + m_pKeyboard = 0; + m_pMouse = 0; - m_pDebugOverlay = 0; - m_pInfoOverlay = 0; + m_pDebugOverlay = 0; + m_pInfoOverlay = 0; #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE m_ResourcePath = macBundlePath() + "/Contents/Resources/"; @@ -55,9 +55,9 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen { new Ogre::LogManager(); - m_pLog = Ogre::LogManager::getSingleton().createLog("OgreLogfile.log", true, true, false); - m_pLog->setDebugOutputEnabled(true); - + m_pLog = Ogre::LogManager::getSingleton().createLog("OgreLogfile.log", true, true, false); + m_pLog->setDebugOutputEnabled(true); + String pluginsPath; // only use plugins.cfg if not static #ifndef OGRE_STATIC_LIB @@ -73,62 +73,62 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen if(!m_pRoot->showConfigDialog()) return false; - m_pRenderWnd = m_pRoot->initialise(true, wndTitle); + m_pRenderWnd = m_pRoot->initialise(true, wndTitle); - m_pSceneMgr = m_pRoot->createSceneManager(ST_GENERIC, "SceneManager"); - m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.7, 0.7, 0.7)); - - m_pCamera = m_pSceneMgr->createCamera("Camera"); - m_pCamera->setPosition(Vector3(0, 60, 60)); - m_pCamera->lookAt(Vector3(0,0,0)); - m_pCamera->setNearClipDistance(1); + m_pSceneMgr = m_pRoot->createSceneManager(ST_GENERIC, "SceneManager"); + m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.7, 0.7, 0.7)); + + m_pCamera = m_pSceneMgr->createCamera("Camera"); + m_pCamera->setPosition(Vector3(0, 60, 60)); + m_pCamera->lookAt(Vector3(0,0,0)); + m_pCamera->setNearClipDistance(1); - m_pViewport = m_pRenderWnd->addViewport(m_pCamera); - m_pViewport->setBackgroundColour(ColourValue(0.8, 0.7, 0.6, 1.0)); + m_pViewport = m_pRenderWnd->addViewport(m_pCamera); + m_pViewport->setBackgroundColour(ColourValue(0.8, 0.7, 0.6, 1.0)); - m_pCamera->setAspectRatio(Real(m_pViewport->getActualWidth()) / Real(m_pViewport->getActualHeight())); + m_pCamera->setAspectRatio(Real(m_pViewport->getActualWidth()) / Real(m_pViewport->getActualHeight())); - m_pViewport->setCamera(m_pCamera); + m_pViewport->setCamera(m_pCamera); - unsigned long hWnd = 0; + unsigned long hWnd = 0; OIS::ParamList paramList; m_pRenderWnd->getCustomAttribute("WINDOW", &hWnd); - paramList.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(hWnd))); + paramList.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(hWnd))); - m_pInputMgr = OIS::InputManager::createInputSystem(paramList); + m_pInputMgr = OIS::InputManager::createInputSystem(paramList); #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE m_pKeyboard = static_cast(m_pInputMgr->createInputObject(OIS::OISKeyboard, true)); - m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMouse, true)); + m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMouse, true)); - m_pMouse->getMouseState().height = m_pRenderWnd->getHeight(); - m_pMouse->getMouseState().width = m_pRenderWnd->getWidth(); + m_pMouse->getMouseState().height = m_pRenderWnd->getHeight(); + m_pMouse->getMouseState().width = m_pRenderWnd->getWidth(); #else - m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMultiTouch, true)); + m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMultiTouch, true)); #endif #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - if(pKeyListener == 0) - m_pKeyboard->setEventCallback(this); - else - m_pKeyboard->setEventCallback(pKeyListener); + if(pKeyListener == 0) + m_pKeyboard->setEventCallback(this); + else + m_pKeyboard->setEventCallback(pKeyListener); #endif - if(pMouseListener == 0) - m_pMouse->setEventCallback(this); - else - m_pMouse->setEventCallback(pMouseListener); + if(pMouseListener == 0) + m_pMouse->setEventCallback(this); + else + m_pMouse->setEventCallback(pMouseListener); - Ogre::String secName, typeName, archName; - Ogre::ConfigFile cf; + Ogre::String secName, typeName, archName; + Ogre::ConfigFile cf; cf.load(m_ResourcePath + "resources.cfg"); - Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); + Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); while (seci.hasMoreElements()) { secName = seci.peekNextKey(); - Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); + Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); Ogre::ConfigFile::SettingsMultiMap::iterator i; for (i = settings->begin(); i != settings->end(); ++i) { @@ -144,16 +144,16 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName); } } - Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); - Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); + Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - m_pTimer = OGRE_NEW Ogre::Timer(); - m_pTimer->reset(); - - m_pDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); - m_pDebugOverlay->show(); + m_pTimer = OGRE_NEW Ogre::Timer(); + m_pTimer->reset(); - m_pRenderWnd->setActive(true); + m_pDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); + m_pDebugOverlay->show(); + + m_pRenderWnd->setActive(true); return true; } @@ -162,16 +162,16 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen OgreFramework::~OgreFramework() { - if(m_pInputMgr) - { - OIS::InputManager::destroyInputSystem(m_pInputMgr); - } + if(m_pInputMgr) + { + OIS::InputManager::destroyInputSystem(m_pInputMgr); + } #ifdef OGRE_STATIC_LIB m_StaticPluginLoader.unload(); #endif - OGRE_DELETE m_pRoot; + OGRE_DELETE m_pRoot; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -179,62 +179,62 @@ OgreFramework::~OgreFramework() bool OgreFramework::keyPressed(const OIS::KeyEvent &keyEventRef) { #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - m_pLog->logMessage("OgreFramework::keyPressed"); - - if(m_pKeyboard->isKeyDown(OIS::KC_ESCAPE)) - { + m_pLog->logMessage("OgreFramework::keyPressed"); + + if(m_pKeyboard->isKeyDown(OIS::KC_ESCAPE)) + { m_bShutDownOgre = true; return true; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_SYSRQ)) - { - std::ostringstream ss; - ss << "screenshot_" << ++m_iNumScreenShots << ".png"; - m_pRenderWnd->writeContentsToFile(ss.str()); - return true; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_M)) - { - static int mode = 0; - - if(mode == 2) - { - m_pCamera->setPolygonMode(PM_SOLID); - mode = 0; - } - else if(mode == 0) - { + } + + if(m_pKeyboard->isKeyDown(OIS::KC_SYSRQ)) + { + std::ostringstream ss; + ss << "screenshot_" << ++m_iNumScreenShots << ".png"; + m_pRenderWnd->writeContentsToFile(ss.str()); + return true; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_M)) + { + static int mode = 0; + + if(mode == 2) + { + m_pCamera->setPolygonMode(PM_SOLID); + mode = 0; + } + else if(mode == 0) + { m_pCamera->setPolygonMode(PM_WIREFRAME); mode = 1; - } - else if(mode == 1) - { - m_pCamera->setPolygonMode(PM_POINTS); - mode = 2; - } - } - - if(m_pKeyboard->isKeyDown(OIS::KC_O)) - { - if(m_pDebugOverlay) - { - if(!m_pDebugOverlay->isVisible()) - m_pDebugOverlay->show(); - else - m_pDebugOverlay->hide(); - } - } + } + else if(mode == 1) + { + m_pCamera->setPolygonMode(PM_POINTS); + mode = 2; + } + } + + if(m_pKeyboard->isKeyDown(OIS::KC_O)) + { + if(m_pDebugOverlay) + { + if(!m_pDebugOverlay->isVisible()) + m_pDebugOverlay->show(); + else + m_pDebugOverlay->hide(); + } + } #endif - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| bool OgreFramework::keyReleased(const OIS::KeyEvent &keyEventRef) { - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -265,10 +265,10 @@ bool OgreFramework::touchMoved(const OIS::MultiTouchEvent &evt) default: break; } - m_pCamera->yaw(Degree(state.X.rel * -0.1)); - m_pCamera->pitch(Degree(state.Y.rel * -0.1)); - - return true; + m_pCamera->yaw(Degree(state.X.rel * -0.1)); + m_pCamera->pitch(Degree(state.Y.rel * -0.1)); + + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -276,7 +276,7 @@ bool OgreFramework::touchMoved(const OIS::MultiTouchEvent &evt) bool OgreFramework::touchPressed(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -284,35 +284,35 @@ bool OgreFramework::touchPressed(const OIS:: MultiTouchEvent &evt) bool OgreFramework::touchReleased(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } bool OgreFramework::touchCancelled(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } #else bool OgreFramework::mouseMoved(const OIS::MouseEvent &evt) { - m_pCamera->yaw(Degree(evt.state.X.rel * -0.1)); - m_pCamera->pitch(Degree(evt.state.Y.rel * -0.1)); - - return true; + m_pCamera->yaw(Degree(evt.state.X.rel * -0.1)); + m_pCamera->pitch(Degree(evt.state.Y.rel * -0.1)); + + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| bool OgreFramework::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| bool OgreFramework::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { - return true; + return true; } #endif @@ -320,22 +320,22 @@ bool OgreFramework::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID void OgreFramework::updateOgre(double timeSinceLastFrame) { - m_MoveScale = m_MoveSpeed * timeSinceLastFrame; - m_RotScale = m_RotateSpeed * timeSinceLastFrame; + m_MoveScale = m_MoveSpeed * timeSinceLastFrame; + m_RotScale = m_RotateSpeed * timeSinceLastFrame; - m_TranslateVector = Vector3::ZERO; + m_TranslateVector = Vector3::ZERO; - getInput(); - moveCamera(); + getInput(); + moveCamera(); - updateStats(); + updateStats(); } //||||||||||||||||||||||||||||||||||||||||||||||| void OgreFramework::updateStats() { - static String currFps = "Current FPS: "; + static String currFps = "Current FPS: "; static String avgFps = "Average FPS: "; static String bestFps = "Best FPS: "; static String worstFps = "Worst FPS: "; @@ -347,7 +347,7 @@ void OgreFramework::updateStats() OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps"); OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps"); - const RenderTarget::FrameStats& stats = m_pRenderWnd->getStatistics(); + const RenderTarget::FrameStats& stats = m_pRenderWnd->getStatistics(); guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS)); guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS)); guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS) @@ -358,11 +358,11 @@ void OgreFramework::updateStats() OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris"); guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount)); - OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches"); + OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches"); guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount)); - OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); - guiDbg->setCaption(""); + OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); + guiDbg->setCaption(""); } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -370,9 +370,9 @@ void OgreFramework::updateStats() void OgreFramework::moveCamera() { #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - if(m_pKeyboard->isKeyDown(OIS::KC_LSHIFT)) m_pCamera->moveRelative(m_TranslateVector); + if(m_pKeyboard->isKeyDown(OIS::KC_LSHIFT)) m_pCamera->moveRelative(m_TranslateVector); #endif - m_pCamera->moveRelative(m_TranslateVector / 10); + m_pCamera->moveRelative(m_TranslateVector / 10); } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -380,45 +380,45 @@ void OgreFramework::moveCamera() void OgreFramework::getInput() { #if OGRE_PLATFORM != OGRE_PLATFORM_IPHONE - if(m_pKeyboard->isKeyDown(OIS::KC_A)) - { - m_TranslateVector.x = -m_MoveScale; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_D)) - { - m_TranslateVector.x = m_MoveScale; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_W)) - { - m_TranslateVector.z = -m_MoveScale; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_S)) - { - m_TranslateVector.z = m_MoveScale; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_LEFT)) - { - m_pCamera->yaw(m_RotScale); - } - - if(m_pKeyboard->isKeyDown(OIS::KC_RIGHT)) - { - m_pCamera->yaw(-m_RotScale); - } - - if(m_pKeyboard->isKeyDown(OIS::KC_UP)) - { - m_pCamera->pitch(m_RotScale); - } - - if(m_pKeyboard->isKeyDown(OIS::KC_DOWN)) - { - m_pCamera->pitch(-m_RotScale); - } + if(m_pKeyboard->isKeyDown(OIS::KC_A)) + { + m_TranslateVector.x = -m_MoveScale; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_D)) + { + m_TranslateVector.x = m_MoveScale; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_W)) + { + m_TranslateVector.z = -m_MoveScale; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_S)) + { + m_TranslateVector.z = m_MoveScale; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_LEFT)) + { + m_pCamera->yaw(m_RotScale); + } + + if(m_pKeyboard->isKeyDown(OIS::KC_RIGHT)) + { + m_pCamera->yaw(-m_RotScale); + } + + if(m_pKeyboard->isKeyDown(OIS::KC_UP)) + { + m_pCamera->pitch(m_RotScale); + } + + if(m_pKeyboard->isKeyDown(OIS::KC_DOWN)) + { + m_pCamera->pitch(-m_RotScale); + } #endif } diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreFramework.h b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreFramework.h index c92651a7112..d0f25277ba4 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreFramework.h +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreFramework.h @@ -59,49 +59,49 @@ class OgreFramework : public Ogre::Singleton, OIS::KeyListener, O #endif { public: - OgreFramework(); - ~OgreFramework(); + OgreFramework(); + ~OgreFramework(); #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MultiTouchListener *pMouseListener = 0); #else bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MouseListener *pMouseListener = 0); #endif - void updateOgre(double timeSinceLastFrame); - void updateStats(); - void moveCamera(); - void getInput(); + void updateOgre(double timeSinceLastFrame); + void updateStats(); + void moveCamera(); + void getInput(); - bool isOgreToBeShutDown()const{return m_bShutDownOgre;} + bool isOgreToBeShutDown()const{return m_bShutDownOgre;} - bool keyPressed(const OIS::KeyEvent &keyEventRef); - bool keyReleased(const OIS::KeyEvent &keyEventRef); + bool keyPressed(const OIS::KeyEvent &keyEventRef); + bool keyReleased(const OIS::KeyEvent &keyEventRef); #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE - bool touchMoved(const OIS::MultiTouchEvent &evt); - bool touchPressed(const OIS::MultiTouchEvent &evt); - bool touchReleased(const OIS::MultiTouchEvent &evt); - bool touchCancelled(const OIS::MultiTouchEvent &evt); + bool touchMoved(const OIS::MultiTouchEvent &evt); + bool touchPressed(const OIS::MultiTouchEvent &evt); + bool touchReleased(const OIS::MultiTouchEvent &evt); + bool touchCancelled(const OIS::MultiTouchEvent &evt); #else - bool mouseMoved(const OIS::MouseEvent &evt); - bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id); - bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id); + bool mouseMoved(const OIS::MouseEvent &evt); + bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id); + bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id); #endif - - Ogre::Root* m_pRoot; - Ogre::SceneManager* m_pSceneMgr; - Ogre::RenderWindow* m_pRenderWnd; - Ogre::Camera* m_pCamera; - Ogre::Viewport* m_pViewport; - Ogre::Log* m_pLog; - Ogre::Timer* m_pTimer; - - OIS::InputManager* m_pInputMgr; - OIS::Keyboard* m_pKeyboard; + + Ogre::Root* m_pRoot; + Ogre::SceneManager* m_pSceneMgr; + Ogre::RenderWindow* m_pRenderWnd; + Ogre::Camera* m_pCamera; + Ogre::Viewport* m_pViewport; + Ogre::Log* m_pLog; + Ogre::Timer* m_pTimer; + + OIS::InputManager* m_pInputMgr; + OIS::Keyboard* m_pKeyboard; #if OGRE_PLATFORM == OGRE_PLATFORM_IPHONE - OIS::MultiTouch* m_pMouse; + OIS::MultiTouch* m_pMouse; #else - OIS::Mouse* m_pMouse; + OIS::Mouse* m_pMouse; #endif protected: @@ -109,20 +109,20 @@ class OgreFramework : public Ogre::Singleton, OIS::KeyListener, O Ogre::String m_ResourcePath; private: - OgreFramework(const OgreFramework&); - OgreFramework& operator= (const OgreFramework&); - - Ogre::Overlay* m_pDebugOverlay; - Ogre::Overlay* m_pInfoOverlay; - int m_iNumScreenShots; - - bool m_bShutDownOgre; - - Ogre::Vector3 m_TranslateVector; - Ogre::Real m_MoveSpeed; - Ogre::Degree m_RotateSpeed; - float m_MoveScale; - Ogre::Degree m_RotScale; + OgreFramework(const OgreFramework&); + OgreFramework& operator= (const OgreFramework&); + + Ogre::Overlay* m_pDebugOverlay; + Ogre::Overlay* m_pInfoOverlay; + int m_iNumScreenShots; + + bool m_bShutDownOgre; + + Ogre::Vector3 m_TranslateVector; + Ogre::Real m_MoveSpeed; + Ogre::Degree m_RotateSpeed; + float m_MoveScale; + Ogre::Degree m_RotScale; #ifdef OGRE_STATIC_LIB Ogre::StaticPluginLoader m_StaticPluginLoader; #endif diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreStaticPluginLoader.h b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreStaticPluginLoader.h index 64975d00830..e382501614b 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreStaticPluginLoader.h +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/OgreStaticPluginLoader.h @@ -57,134 +57,134 @@ Description: Utility class to load plugins statically namespace Ogre { - /** Utility class for loading some plugins statically. - @remarks - When loading plugins statically, you are limited to loading plugins - that are known about at compile time. You should define preprocessor - symbols depending on which plugins you want to load - the symbol being - OGRE_STATIC_, with pluginname being the usual name of the - plugin DLL (no file extension, no debug suffix, and without the Plugin_ - or RenderSystem_ prefix.) - */ - class StaticPluginLoader - { - protected: + /** Utility class for loading some plugins statically. + @remarks + When loading plugins statically, you are limited to loading plugins + that are known about at compile time. You should define preprocessor + symbols depending on which plugins you want to load - the symbol being + OGRE_STATIC_, with pluginname being the usual name of the + plugin DLL (no file extension, no debug suffix, and without the Plugin_ + or RenderSystem_ prefix.) + */ + class StaticPluginLoader + { + protected: #ifdef OGRE_STATIC_CgProgramManager - CgPlugin* mCgPlugin; + CgPlugin* mCgPlugin; #endif #ifdef OGRE_STATIC_OctreeSceneManager - OctreePlugin* mOctreePlugin; + OctreePlugin* mOctreePlugin; #endif #ifdef OGRE_STATIC_ParticleFX - ParticleFXPlugin* mParticleFXPlugin; + ParticleFXPlugin* mParticleFXPlugin; #endif #ifdef OGRE_STATIC_BSPSceneManager - BspSceneManagerPlugin* mBSPPlugin; + BspSceneManagerPlugin* mBSPPlugin; #endif #ifdef OGRE_STATIC_PCZSceneManager - PCZPlugin* mPCZPlugin; + PCZPlugin* mPCZPlugin; #endif #ifdef OGRE_STATIC_OctreeZone - OctreeZonePlugin* mOctreeZonePlugin; + OctreeZonePlugin* mOctreeZonePlugin; #endif #ifdef OGRE_STATIC_GL - GLPlugin* mGLPlugin; + GLPlugin* mGLPlugin; #endif #ifdef OGRE_STATIC_GLES - GLESPlugin* mGLESPlugin; + GLESPlugin* mGLESPlugin; #endif #ifdef OGRE_STATIC_Direct3D9 - D3D9Plugin* mD3D9Plugin; + D3D9Plugin* mD3D9Plugin; #endif #ifdef OGRE_STATIC_Direct3D11 - D3D11Plugin* mD3D11Plugin; + D3D11Plugin* mD3D11Plugin; #endif - public: - StaticPluginLoader() {} + public: + StaticPluginLoader() {} - /** Load all the enabled plugins against the passed in root object. */ - void load() - { - Root& root = Root::getSingleton(); + /** Load all the enabled plugins against the passed in root object. */ + void load() + { + Root& root = Root::getSingleton(); #ifdef OGRE_STATIC_GL - mGLPlugin = OGRE_NEW GLPlugin(); - root.installPlugin(mGLPlugin); + mGLPlugin = OGRE_NEW GLPlugin(); + root.installPlugin(mGLPlugin); #endif #ifdef OGRE_STATIC_GLES - mGLESPlugin = OGRE_NEW GLESPlugin(); - root.installPlugin(mGLESPlugin); + mGLESPlugin = OGRE_NEW GLESPlugin(); + root.installPlugin(mGLESPlugin); #endif #ifdef OGRE_STATIC_Direct3D9 - mD3D9Plugin = OGRE_NEW D3D9Plugin(); - root.installPlugin(mD3D9Plugin); + mD3D9Plugin = OGRE_NEW D3D9Plugin(); + root.installPlugin(mD3D9Plugin); #endif #ifdef OGRE_STATIC_Direct3D11 - mD3D11Plugin = OGRE_NEW D3D11Plugin(); - root.installPlugin(mD3D11Plugin); + mD3D11Plugin = OGRE_NEW D3D11Plugin(); + root.installPlugin(mD3D11Plugin); #endif #ifdef OGRE_STATIC_CgProgramManager - mCgPlugin = OGRE_NEW CgPlugin(); - root.installPlugin(mCgPlugin); + mCgPlugin = OGRE_NEW CgPlugin(); + root.installPlugin(mCgPlugin); #endif #ifdef OGRE_STATIC_OctreeSceneManager - mOctreePlugin = OGRE_NEW OctreePlugin(); - root.installPlugin(mOctreePlugin); + mOctreePlugin = OGRE_NEW OctreePlugin(); + root.installPlugin(mOctreePlugin); #endif #ifdef OGRE_STATIC_ParticleFX - mParticleFXPlugin = OGRE_NEW ParticleFXPlugin(); - root.installPlugin(mParticleFXPlugin); + mParticleFXPlugin = OGRE_NEW ParticleFXPlugin(); + root.installPlugin(mParticleFXPlugin); #endif #ifdef OGRE_STATIC_BSPSceneManager - mBSPPlugin = OGRE_NEW BspSceneManagerPlugin(); - root.installPlugin(mBSPPlugin); + mBSPPlugin = OGRE_NEW BspSceneManagerPlugin(); + root.installPlugin(mBSPPlugin); #endif #ifdef OGRE_STATIC_PCZSceneManager - mPCZPlugin = OGRE_NEW PCZPlugin(); - root.installPlugin(mPCZPlugin); + mPCZPlugin = OGRE_NEW PCZPlugin(); + root.installPlugin(mPCZPlugin); #endif #ifdef OGRE_STATIC_OctreeZone - mOctreeZonePlugin = OGRE_NEW OctreeZonePlugin(); - root.installPlugin(mOctreeZonePlugin); + mOctreeZonePlugin = OGRE_NEW OctreeZonePlugin(); + root.installPlugin(mOctreeZonePlugin); #endif - } + } - void unload() - { - // don't unload plugins, since Root will have done that. Destroy here. + void unload() + { + // don't unload plugins, since Root will have done that. Destroy here. #ifdef OGRE_STATIC_OctreeZone - OGRE_DELETE mOctreeZonePlugin; + OGRE_DELETE mOctreeZonePlugin; #endif #ifdef OGRE_STATIC_PCZSceneManager - OGRE_DELETE mPCZPlugin; + OGRE_DELETE mPCZPlugin; #endif #ifdef OGRE_STATIC_BSPSceneManager - OGRE_DELETE mBSPPlugin; + OGRE_DELETE mBSPPlugin; #endif #ifdef OGRE_STATIC_ParticleFX - OGRE_DELETE mParticleFXPlugin; + OGRE_DELETE mParticleFXPlugin; #endif #ifdef OGRE_STATIC_OctreeSceneManager - OGRE_DELETE mOctreePlugin; + OGRE_DELETE mOctreePlugin; #endif #ifdef OGRE_STATIC_CgProgramManager - OGRE_DELETE mCgPlugin; + OGRE_DELETE mCgPlugin; #endif #ifdef OGRE_STATIC_Direct3D9 - OGRE_DELETE mD3D9Plugin; + OGRE_DELETE mD3D9Plugin; #endif #ifdef OGRE_STATIC_Direct3D11 - OGRE_DELETE mD3D11Plugin; + OGRE_DELETE mD3D11Plugin; #endif #ifdef OGRE_STATIC_GL - OGRE_DELETE mGLPlugin; + OGRE_DELETE mGLPlugin; #endif #ifdef OGRE_STATIC_GLES - OGRE_DELETE mGLESPlugin; + OGRE_DELETE mGLESPlugin; #endif - } + } - }; + }; } diff --git a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/main.cpp b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/main.cpp index 576e9246475..c883fff5e29 100644 --- a/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/main.cpp +++ b/SDK/OSX/Xcode Templates/Xcode/Project Templates/Ogre/iPhone OS/Classes/main.cpp @@ -59,12 +59,12 @@ int main(int argc, char **argv) [pool release]; return retVal; #else - try + try { - DemoApp demo; - demo.startDemo(); + DemoApp demo; + demo.startDemo(); } - catch(Ogre::Exception& e) + catch(Ogre::Exception& e) { #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBoxA(NULL, e.what(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL); diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/AppDelegate.h b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/AppDelegate.h index 06e9636534e..d69c2896fca 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/AppDelegate.h +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/AppDelegate.h @@ -86,7 +86,7 @@ static id mAppDelegate; Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets(); // Clear event times - Ogre::Root::getSingleton().clearEventTimes(); + Ogre::Root::getSingleton().clearEventTimes(); } catch( Ogre::Exception& e ) { std::cerr << "An exception has occurred: " << e.getFullDescription().c_str() << std::endl; @@ -113,18 +113,18 @@ static id mAppDelegate; if(!OgreFramework::getSingletonPtr()->isOgreToBeShutDown() && Ogre::Root::getSingletonPtr() && Ogre::Root::getSingleton().isInitialised()) { - if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) - { - mStartTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); + if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) + { + mStartTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); - OgreFramework::getSingletonPtr()->m_pKeyboard->capture(); - OgreFramework::getSingletonPtr()->m_pMouse->capture(); + OgreFramework::getSingletonPtr()->m_pKeyboard->capture(); + OgreFramework::getSingletonPtr()->m_pMouse->capture(); - OgreFramework::getSingletonPtr()->updateOgre(mLastFrameTime); - OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); + OgreFramework::getSingletonPtr()->updateOgre(mLastFrameTime); + OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); - mLastFrameTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - mStartTime; - } + mLastFrameTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - mStartTime; + } } else { diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreDemoApp.cpp b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreDemoApp.cpp index 0ac49783f9c..9e4d491df67 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreDemoApp.cpp +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreDemoApp.cpp @@ -2,8 +2,8 @@ DemoApp::DemoApp() { - m_pCubeNode = 0; - m_pCubeEntity = 0; + m_pCubeNode = 0; + m_pCubeEntity = 0; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -24,10 +24,10 @@ DemoApp::~DemoApp() #ifdef INCLUDE_RTSHADER_SYSTEM /*----------------------------------------------------------------------------- - | Initialize the RT Shader system. + | Initialize the RT Shader system. -----------------------------------------------------------------------------*/ bool DemoApp::initialiseRTShaderSystem(Ogre::SceneManager* sceneMgr) -{ +{ if (Ogre::RTShader::ShaderGenerator::initialize()) { mShaderGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr(); @@ -67,11 +67,11 @@ bool DemoApp::initialiseRTShaderSystem(Ogre::SceneManager* sceneMgr) } // Core shader libs not found -> shader generating will fail. - if (shaderCoreLibsPath.empty()) - return false; + if (shaderCoreLibsPath.empty()) + return false; // Create and register the material manager listener. - mMaterialMgrListener = new ShaderGeneratorTechniqueResolverListener(mShaderGenerator); + mMaterialMgrListener = new ShaderGeneratorTechniqueResolverListener(mShaderGenerator); Ogre::MaterialManager::getSingleton().addListener(mMaterialMgrListener); } @@ -88,7 +88,7 @@ void DemoApp::destroyRTShaderSystem() // Unregister the material manager listener. if (mMaterialMgrListener != NULL) - { + { Ogre::MaterialManager::getSingleton().removeListener(mMaterialMgrListener); delete mMaterialMgrListener; mMaterialMgrListener = NULL; @@ -96,7 +96,7 @@ void DemoApp::destroyRTShaderSystem() // Destroy RTShader system. if (mShaderGenerator != NULL) - { + { Ogre::RTShader::ShaderGenerator::destroy(); mShaderGenerator = NULL; } @@ -105,22 +105,22 @@ void DemoApp::destroyRTShaderSystem() void DemoApp::startDemo() { - new OgreFramework(); - if(!OgreFramework::getSingletonPtr()->initOgre("DemoApp v1.0", this, 0)) - return; + new OgreFramework(); + if(!OgreFramework::getSingletonPtr()->initOgre("DemoApp v1.0", this, 0)) + return; - m_bShutdown = false; + m_bShutdown = false; + + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Demo initialized!"); - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Demo initialized!"); - #ifdef INCLUDE_RTSHADER_SYSTEM initialiseRTShaderSystem(OgreFramework::getSingletonPtr()->m_pSceneMgr); - Ogre::MaterialPtr baseWhite = Ogre::MaterialManager::getSingleton().getByName("BaseWhite", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + Ogre::MaterialPtr baseWhite = Ogre::MaterialManager::getSingleton().getByName("BaseWhite", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); baseWhite->setLightingEnabled(false); mShaderGenerator->createShaderBasedTechnique( "BaseWhite", Ogre::MaterialManager::DEFAULT_SCHEME_NAME, - Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); mShaderGenerator->validateMaterial(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, "BaseWhite"); baseWhite->getTechnique(0)->getPass(0)->setVertexProgram( @@ -132,7 +132,7 @@ void DemoApp::startDemo() mShaderGenerator->createShaderBasedTechnique( "BaseWhiteNoLighting", Ogre::MaterialManager::DEFAULT_SCHEME_NAME, - Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); mShaderGenerator->validateMaterial(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, "BaseWhiteNoLighting"); Ogre::MaterialPtr baseWhiteNoLighting = Ogre::MaterialManager::getSingleton().getByName("BaseWhiteNoLighting", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); @@ -142,9 +142,9 @@ void DemoApp::startDemo() baseWhiteNoLighting->getTechnique(1)->getPass(0)->getFragmentProgram()->getName()); #endif - setupDemoScene(); + setupDemoScene(); #if !((OGRE_PLATFORM == OGRE_PLATFORM_APPLE) && __LP64__) - runDemo(); + runDemo(); #endif } @@ -152,62 +152,62 @@ void DemoApp::startDemo() void DemoApp::setupDemoScene() { - OgreFramework::getSingletonPtr()->m_pSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox"); + OgreFramework::getSingletonPtr()->m_pSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox"); - OgreFramework::getSingletonPtr()->m_pSceneMgr->createLight("Light")->setPosition(75,75,75); + OgreFramework::getSingletonPtr()->m_pSceneMgr->createLight("Light")->setPosition(75,75,75); - m_pCubeEntity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("Cube", "ogrehead.mesh"); - m_pCubeNode = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode("CubeNode"); - m_pCubeNode->attachObject(m_pCubeEntity); + m_pCubeEntity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("Cube", "ogrehead.mesh"); + m_pCubeNode = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode("CubeNode"); + m_pCubeNode->attachObject(m_pCubeEntity); } //||||||||||||||||||||||||||||||||||||||||||||||| void DemoApp::runDemo() { - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Start main loop..."); - - double timeSinceLastFrame = 0; - double startTime = 0; + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Start main loop..."); + + double timeSinceLastFrame = 0; + double startTime = 0; OgreFramework::getSingletonPtr()->m_pRenderWnd->resetStatistics(); #if (!defined(OGRE_IS_IOS)) && !((OGRE_PLATFORM == OGRE_PLATFORM_APPLE) && __LP64__) - while(!m_bShutdown && !OgreFramework::getSingletonPtr()->isOgreToBeShutDown()) - { - if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isClosed())m_bShutdown = true; + while(!m_bShutdown && !OgreFramework::getSingletonPtr()->isOgreToBeShutDown()) + { + if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isClosed())m_bShutdown = true; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE - Ogre::WindowEventUtilities::messagePump(); -#endif - if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) - { - startTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); + Ogre::WindowEventUtilities::messagePump(); +#endif + if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) + { + startTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); #if !OGRE_IS_IOS - OgreFramework::getSingletonPtr()->m_pKeyboard->capture(); + OgreFramework::getSingletonPtr()->m_pKeyboard->capture(); #endif - OgreFramework::getSingletonPtr()->m_pMouse->capture(); + OgreFramework::getSingletonPtr()->m_pMouse->capture(); - OgreFramework::getSingletonPtr()->updateOgre(timeSinceLastFrame); - OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); + OgreFramework::getSingletonPtr()->updateOgre(timeSinceLastFrame); + OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); - timeSinceLastFrame = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - startTime; - } - else - { + timeSinceLastFrame = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - startTime; + } + else + { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 Sleep(1000); #else sleep(1); #endif - } - } + } + } #endif #if !defined(OGRE_IS_IOS) - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Main loop quit"); - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Shutdown OGRE..."); + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Main loop quit"); + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Shutdown OGRE..."); #endif } @@ -216,14 +216,14 @@ void DemoApp::runDemo() bool DemoApp::keyPressed(const OIS::KeyEvent &keyEventRef) { #if !defined(OGRE_IS_IOS) - OgreFramework::getSingletonPtr()->keyPressed(keyEventRef); - - if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_F)) - { + OgreFramework::getSingletonPtr()->keyPressed(keyEventRef); + + if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_F)) + { //do something - } + } #endif - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -231,10 +231,10 @@ bool DemoApp::keyPressed(const OIS::KeyEvent &keyEventRef) bool DemoApp::keyReleased(const OIS::KeyEvent &keyEventRef) { #if !defined(OGRE_IS_IOS) - OgreFramework::getSingletonPtr()->keyReleased(keyEventRef); + OgreFramework::getSingletonPtr()->keyReleased(keyEventRef); #endif - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreDemoApp.h b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreDemoApp.h index 773c81f9dd6..b34fb2dbf55 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreDemoApp.h +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreDemoApp.h @@ -21,87 +21,87 @@ class ShaderGeneratorTechniqueResolverListener : public Ogre::MaterialManager::L { public: - ShaderGeneratorTechniqueResolverListener(Ogre::RTShader::ShaderGenerator* pShaderGenerator) - { - mShaderGenerator = pShaderGenerator; - } + ShaderGeneratorTechniqueResolverListener(Ogre::RTShader::ShaderGenerator* pShaderGenerator) + { + mShaderGenerator = pShaderGenerator; + } - /** This is the hook point where shader based technique will be created. + /** This is the hook point where shader based technique will be created. It will be called whenever the material manager won't find appropriate technique that satisfy the target scheme name. If the scheme name is out target RT Shader System scheme name we will try to create shader generated technique for it. */ - virtual Ogre::Technique* handleSchemeNotFound(unsigned short schemeIndex, + virtual Ogre::Technique* handleSchemeNotFound(unsigned short schemeIndex, const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, const Ogre::Renderable* rend) - { - Ogre::Technique* generatedTech = NULL; + { + Ogre::Technique* generatedTech = NULL; - // Case this is the default shader generator scheme. - if (schemeName == Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) - { - bool techniqueCreated; + // Case this is the default shader generator scheme. + if (schemeName == Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) + { + bool techniqueCreated; - // Create shader generated technique for this material. - techniqueCreated = mShaderGenerator->createShaderBasedTechnique( + // Create shader generated technique for this material. + techniqueCreated = mShaderGenerator->createShaderBasedTechnique( originalMaterial->getName(), Ogre::MaterialManager::DEFAULT_SCHEME_NAME, - schemeName); + schemeName); - // Case technique registration succeeded. - if (techniqueCreated) - { - // Force creating the shaders for the generated technique. - mShaderGenerator->validateMaterial(schemeName, originalMaterial->getName()); - - // Grab the generated technique. - Ogre::Material::TechniqueIterator itTech = originalMaterial->getTechniqueIterator(); + // Case technique registration succeeded. + if (techniqueCreated) + { + // Force creating the shaders for the generated technique. + mShaderGenerator->validateMaterial(schemeName, originalMaterial->getName()); - while (itTech.hasMoreElements()) - { - Ogre::Technique* curTech = itTech.getNext(); + // Grab the generated technique. + Ogre::Material::TechniqueIterator itTech = originalMaterial->getTechniqueIterator(); + + while (itTech.hasMoreElements()) + { + Ogre::Technique* curTech = itTech.getNext(); - if (curTech->getSchemeName() == schemeName) - { - generatedTech = curTech; - break; - } - } - } - } + if (curTech->getSchemeName() == schemeName) + { + generatedTech = curTech; + break; + } + } + } + } - return generatedTech; - } + return generatedTech; + } -protected: - Ogre::RTShader::ShaderGenerator* mShaderGenerator; // The shader generator instance. +protected: + Ogre::RTShader::ShaderGenerator* mShaderGenerator; // The shader generator instance. }; #endif class DemoApp : public OIS::KeyListener { public: - DemoApp(); - ~DemoApp(); + DemoApp(); + ~DemoApp(); + + void startDemo(); - void startDemo(); - - bool keyPressed(const OIS::KeyEvent &keyEventRef); - bool keyReleased(const OIS::KeyEvent &keyEventRef); + bool keyPressed(const OIS::KeyEvent &keyEventRef); + bool keyReleased(const OIS::KeyEvent &keyEventRef); private: void setupDemoScene(); - void runDemo(); + void runDemo(); bool initialiseRTShaderSystem(Ogre::SceneManager* sceneMgr); void destroyRTShaderSystem(); - Ogre::SceneNode* m_pCubeNode; - Ogre::Entity* m_pCubeEntity; + Ogre::SceneNode* m_pCubeNode; + Ogre::Entity* m_pCubeEntity; - bool m_bShutdown; + bool m_bShutdown; #ifdef INCLUDE_RTSHADER_SYSTEM - Ogre::RTShader::ShaderGenerator* mShaderGenerator; // The Shader generator instance. - ShaderGeneratorTechniqueResolverListener* mMaterialMgrListener; // Shader generator material manager listener. + Ogre::RTShader::ShaderGenerator* mShaderGenerator; // The Shader generator instance. + ShaderGeneratorTechniqueResolverListener* mMaterialMgrListener; // Shader generator material manager listener. #endif // INCLUDE_RTSHADER_SYSTEM }; diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreFramework.cpp b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreFramework.cpp index 6308fb55d9f..b0fe2185091 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreFramework.cpp +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreFramework.cpp @@ -10,23 +10,23 @@ namespace Ogre OgreFramework::OgreFramework() { - m_MoveSpeed = 0.1f; - m_RotateSpeed = 0.3f; + m_MoveSpeed = 0.1f; + m_RotateSpeed = 0.3f; - m_bShutDownOgre = false; - m_iNumScreenShots = 0; + m_bShutDownOgre = false; + m_iNumScreenShots = 0; - m_pRoot = 0; - m_pSceneMgr = 0; - m_pRenderWnd = 0; - m_pCamera = 0; - m_pViewport = 0; - m_pLog = 0; - m_pTimer = 0; + m_pRoot = 0; + m_pSceneMgr = 0; + m_pRenderWnd = 0; + m_pCamera = 0; + m_pViewport = 0; + m_pLog = 0; + m_pTimer = 0; - m_pInputMgr = 0; - m_pKeyboard = 0; - m_pMouse = 0; + m_pInputMgr = 0; + m_pKeyboard = 0; + m_pMouse = 0; #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE m_ResourcePath = macBundlePath() + "/Contents/Resources/"; @@ -48,8 +48,8 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen { new Ogre::LogManager(); - m_pLog = Ogre::LogManager::getSingleton().createLog("OgreLogfile.log", true, true, false); - m_pLog->setDebugOutputEnabled(true); + m_pLog = Ogre::LogManager::getSingleton().createLog("OgreLogfile.log", true, true, false); + m_pLog->setDebugOutputEnabled(true); String pluginsPath; // only use plugins.cfg if not static @@ -63,64 +63,64 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen m_StaticPluginLoader.load(); #endif - if(!m_pRoot->showConfigDialog()) - return false; - m_pRenderWnd = m_pRoot->initialise(true, wndTitle); + if(!m_pRoot->showConfigDialog()) + return false; + m_pRenderWnd = m_pRoot->initialise(true, wndTitle); - m_pSceneMgr = m_pRoot->createSceneManager(ST_GENERIC, "SceneManager"); - m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.7f, 0.7f, 0.7f)); - - m_pCamera = m_pSceneMgr->createCamera("Camera"); - m_pCamera->setPosition(Vector3(0, 60, 60)); - m_pCamera->lookAt(Vector3(0, 0, 0)); - m_pCamera->setNearClipDistance(1); + m_pSceneMgr = m_pRoot->createSceneManager(ST_GENERIC, "SceneManager"); + m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.7f, 0.7f, 0.7f)); - m_pViewport = m_pRenderWnd->addViewport(m_pCamera); - m_pViewport->setBackgroundColour(ColourValue(0.8f, 0.7f, 0.6f, 1.0f)); + m_pCamera = m_pSceneMgr->createCamera("Camera"); + m_pCamera->setPosition(Vector3(0, 60, 60)); + m_pCamera->lookAt(Vector3(0, 0, 0)); + m_pCamera->setNearClipDistance(1); - m_pCamera->setAspectRatio(Real(m_pViewport->getActualWidth()) / Real(m_pViewport->getActualHeight())); - - m_pViewport->setCamera(m_pCamera); + m_pViewport = m_pRenderWnd->addViewport(m_pCamera); + m_pViewport->setBackgroundColour(ColourValue(0.8f, 0.7f, 0.6f, 1.0f)); - unsigned long hWnd = 0; + m_pCamera->setAspectRatio(Real(m_pViewport->getActualWidth()) / Real(m_pViewport->getActualHeight())); + + m_pViewport->setCamera(m_pCamera); + + unsigned long hWnd = 0; OIS::ParamList paramList; m_pRenderWnd->getCustomAttribute("WINDOW", &hWnd); - paramList.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(hWnd))); + paramList.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(hWnd))); - m_pInputMgr = OIS::InputManager::createInputSystem(paramList); + m_pInputMgr = OIS::InputManager::createInputSystem(paramList); #if !defined(OGRE_IS_IOS) m_pKeyboard = static_cast(m_pInputMgr->createInputObject(OIS::OISKeyboard, true)); - m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMouse, true)); + m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMouse, true)); - m_pMouse->getMouseState().height = m_pRenderWnd->getHeight(); - m_pMouse->getMouseState().width = m_pRenderWnd->getWidth(); + m_pMouse->getMouseState().height = m_pRenderWnd->getHeight(); + m_pMouse->getMouseState().width = m_pRenderWnd->getWidth(); #else - m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMultiTouch, true)); + m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMultiTouch, true)); #endif #if !defined(OGRE_IS_IOS) - if(pKeyListener == 0) - m_pKeyboard->setEventCallback(this); - else - m_pKeyboard->setEventCallback(pKeyListener); + if(pKeyListener == 0) + m_pKeyboard->setEventCallback(this); + else + m_pKeyboard->setEventCallback(pKeyListener); #endif - if(pMouseListener == 0) - m_pMouse->setEventCallback(this); - else - m_pMouse->setEventCallback(pMouseListener); + if(pMouseListener == 0) + m_pMouse->setEventCallback(this); + else + m_pMouse->setEventCallback(pMouseListener); - Ogre::String secName, typeName, archName; - Ogre::ConfigFile cf; + Ogre::String secName, typeName, archName; + Ogre::ConfigFile cf; cf.load(m_ResourcePath + "resources.cfg"); - Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); + Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); while (seci.hasMoreElements()) { secName = seci.peekNextKey(); - Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); + Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); Ogre::ConfigFile::SettingsMultiMap::iterator i; for (i = settings->begin(); i != settings->end(); ++i) { @@ -136,20 +136,20 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName); } } - Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); - Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); + Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - m_pTimer = OGRE_NEW Ogre::Timer(); - m_pTimer->reset(); - - m_pTrayMgr = new OgreBites::SdkTrayManager("TrayMgr", m_pRenderWnd, m_pMouse, this); + m_pTimer = OGRE_NEW Ogre::Timer(); + m_pTimer->reset(); + + m_pTrayMgr = new OgreBites::SdkTrayManager("TrayMgr", m_pRenderWnd, m_pMouse, this); m_pTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT); m_pTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT); m_pTrayMgr->hideCursor(); - m_pRenderWnd->setActive(true); + m_pRenderWnd->setActive(true); - return true; + return true; } OgreFramework::~OgreFramework() @@ -165,43 +165,43 @@ OgreFramework::~OgreFramework() bool OgreFramework::keyPressed(const OIS::KeyEvent &keyEventRef) { #if !defined(OGRE_IS_IOS) - - if(m_pKeyboard->isKeyDown(OIS::KC_ESCAPE)) - { + + if(m_pKeyboard->isKeyDown(OIS::KC_ESCAPE)) + { m_bShutDownOgre = true; return true; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_SYSRQ)) - { - m_pRenderWnd->writeContentsToTimestampedFile("BOF_Screenshot_", ".png"); - return true; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_M)) - { - static int mode = 0; - - if(mode == 2) - { - m_pCamera->setPolygonMode(PM_SOLID); - mode = 0; - } - else if(mode == 0) - { + } + + if(m_pKeyboard->isKeyDown(OIS::KC_SYSRQ)) + { + m_pRenderWnd->writeContentsToTimestampedFile("BOF_Screenshot_", ".png"); + return true; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_M)) + { + static int mode = 0; + + if(mode == 2) + { + m_pCamera->setPolygonMode(PM_SOLID); + mode = 0; + } + else if(mode == 0) + { m_pCamera->setPolygonMode(PM_WIREFRAME); mode = 1; - } - else if(mode == 1) - { - m_pCamera->setPolygonMode(PM_POINTS); - mode = 2; - } - } - - if(m_pKeyboard->isKeyDown(OIS::KC_O)) - { - if(m_pTrayMgr->isLogoVisible()) + } + else if(mode == 1) + { + m_pCamera->setPolygonMode(PM_POINTS); + mode = 2; + } + } + + if(m_pKeyboard->isKeyDown(OIS::KC_O)) + { + if(m_pTrayMgr->isLogoVisible()) { m_pTrayMgr->hideLogo(); m_pTrayMgr->hideFrameStats(); @@ -211,15 +211,15 @@ bool OgreFramework::keyPressed(const OIS::KeyEvent &keyEventRef) m_pTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT); m_pTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT); } - } + } #endif - return true; + return true; } bool OgreFramework::keyReleased(const OIS::KeyEvent &keyEventRef) { - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -252,10 +252,10 @@ bool OgreFramework::touchMoved(const OIS::MultiTouchEvent &evt) break; } #endif - m_pCamera->yaw(Degree(state.X.rel * -0.1)); - m_pCamera->pitch(Degree(state.Y.rel * -0.1)); - - return true; + m_pCamera->yaw(Degree(state.X.rel * -0.1)); + m_pCamera->pitch(Degree(state.Y.rel * -0.1)); + + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -263,7 +263,7 @@ bool OgreFramework::touchMoved(const OIS::MultiTouchEvent &evt) bool OgreFramework::touchPressed(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -271,75 +271,75 @@ bool OgreFramework::touchPressed(const OIS:: MultiTouchEvent &evt) bool OgreFramework::touchReleased(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } bool OgreFramework::touchCancelled(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } #else bool OgreFramework::mouseMoved(const OIS::MouseEvent &evt) { - m_pCamera->yaw(Degree(evt.state.X.rel * -0.1f)); - m_pCamera->pitch(Degree(evt.state.Y.rel * -0.1f)); - - return true; + m_pCamera->yaw(Degree(evt.state.X.rel * -0.1f)); + m_pCamera->pitch(Degree(evt.state.Y.rel * -0.1f)); + + return true; } bool OgreFramework::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { - return true; + return true; } bool OgreFramework::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { - return true; + return true; } #endif void OgreFramework::updateOgre(double timeSinceLastFrame) { - m_MoveScale = m_MoveSpeed * (float)timeSinceLastFrame; - m_RotScale = m_RotateSpeed * (float)timeSinceLastFrame; + m_MoveScale = m_MoveSpeed * (float)timeSinceLastFrame; + m_RotScale = m_RotateSpeed * (float)timeSinceLastFrame; #if OGRE_VERSION >= 0x10800 m_pSceneMgr->setSkyBoxEnabled(true); #endif - m_TranslateVector = Vector3::ZERO; + m_TranslateVector = Vector3::ZERO; - getInput(); - moveCamera(); + getInput(); + moveCamera(); - m_FrameEvent.timeSinceLastFrame = timeSinceLastFrame; + m_FrameEvent.timeSinceLastFrame = timeSinceLastFrame; m_pTrayMgr->frameRenderingQueued(m_FrameEvent); } void OgreFramework::moveCamera() { #if !defined(OGRE_IS_IOS) - if(m_pKeyboard->isKeyDown(OIS::KC_LSHIFT)) - m_pCamera->moveRelative(m_TranslateVector); - else + if(m_pKeyboard->isKeyDown(OIS::KC_LSHIFT)) + m_pCamera->moveRelative(m_TranslateVector); + else #endif - m_pCamera->moveRelative(m_TranslateVector / 10); + m_pCamera->moveRelative(m_TranslateVector / 10); } void OgreFramework::getInput() { #if !defined(OGRE_IS_IOS) - if(m_pKeyboard->isKeyDown(OIS::KC_A)) - m_TranslateVector.x = -m_MoveScale; - - if(m_pKeyboard->isKeyDown(OIS::KC_D)) - m_TranslateVector.x = m_MoveScale; - - if(m_pKeyboard->isKeyDown(OIS::KC_W)) - m_TranslateVector.z = -m_MoveScale; - - if(m_pKeyboard->isKeyDown(OIS::KC_S)) - m_TranslateVector.z = m_MoveScale; + if(m_pKeyboard->isKeyDown(OIS::KC_A)) + m_TranslateVector.x = -m_MoveScale; + + if(m_pKeyboard->isKeyDown(OIS::KC_D)) + m_TranslateVector.x = m_MoveScale; + + if(m_pKeyboard->isKeyDown(OIS::KC_W)) + m_TranslateVector.z = -m_MoveScale; + + if(m_pKeyboard->isKeyDown(OIS::KC_S)) + m_TranslateVector.z = m_MoveScale; #endif } diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreFramework.h b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreFramework.h index 521b483a92f..9a015379b11 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreFramework.h +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/Mac OS X Application.xctemplate/OgreFramework.h @@ -76,48 +76,48 @@ class OgreFramework : public Ogre::Singleton, OIS::KeyListener, O #endif { public: - OgreFramework(); - ~OgreFramework(); + OgreFramework(); + ~OgreFramework(); #ifdef OGRE_IS_IOS bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MultiTouchListener *pMouseListener = 0); #else - bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MouseListener *pMouseListener = 0); + bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MouseListener *pMouseListener = 0); #endif - void updateOgre(double timeSinceLastFrame); - void moveCamera(); - void getInput(); + void updateOgre(double timeSinceLastFrame); + void moveCamera(); + void getInput(); - bool isOgreToBeShutDown()const{return m_bShutDownOgre;} + bool isOgreToBeShutDown()const{return m_bShutDownOgre;} - bool keyPressed(const OIS::KeyEvent &keyEventRef); - bool keyReleased(const OIS::KeyEvent &keyEventRef); + bool keyPressed(const OIS::KeyEvent &keyEventRef); + bool keyReleased(const OIS::KeyEvent &keyEventRef); #ifdef OGRE_IS_IOS - bool touchMoved(const OIS::MultiTouchEvent &evt); - bool touchPressed(const OIS::MultiTouchEvent &evt); - bool touchReleased(const OIS::MultiTouchEvent &evt); - bool touchCancelled(const OIS::MultiTouchEvent &evt); + bool touchMoved(const OIS::MultiTouchEvent &evt); + bool touchPressed(const OIS::MultiTouchEvent &evt); + bool touchReleased(const OIS::MultiTouchEvent &evt); + bool touchCancelled(const OIS::MultiTouchEvent &evt); #else - bool mouseMoved(const OIS::MouseEvent &evt); - bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id); - bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id); + bool mouseMoved(const OIS::MouseEvent &evt); + bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id); + bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id); #endif - - Ogre::Root* m_pRoot; - Ogre::SceneManager* m_pSceneMgr; - Ogre::RenderWindow* m_pRenderWnd; - Ogre::Camera* m_pCamera; - Ogre::Viewport* m_pViewport; - Ogre::Log* m_pLog; - Ogre::Timer* m_pTimer; - - OIS::InputManager* m_pInputMgr; - OIS::Keyboard* m_pKeyboard; + + Ogre::Root* m_pRoot; + Ogre::SceneManager* m_pSceneMgr; + Ogre::RenderWindow* m_pRenderWnd; + Ogre::Camera* m_pCamera; + Ogre::Viewport* m_pViewport; + Ogre::Log* m_pLog; + Ogre::Timer* m_pTimer; + + OIS::InputManager* m_pInputMgr; + OIS::Keyboard* m_pKeyboard; #ifdef OGRE_IS_IOS - OIS::MultiTouch* m_pMouse; + OIS::MultiTouch* m_pMouse; #else - OIS::Mouse* m_pMouse; + OIS::Mouse* m_pMouse; #endif protected: @@ -125,20 +125,20 @@ class OgreFramework : public Ogre::Singleton, OIS::KeyListener, O Ogre::String m_ResourcePath; private: - OgreFramework(const OgreFramework&); - OgreFramework& operator= (const OgreFramework&); + OgreFramework(const OgreFramework&); + OgreFramework& operator= (const OgreFramework&); - OgreBites::SdkTrayManager* m_pTrayMgr; + OgreBites::SdkTrayManager* m_pTrayMgr; Ogre::FrameEvent m_FrameEvent; - int m_iNumScreenShots; + int m_iNumScreenShots; + + bool m_bShutDownOgre; - bool m_bShutDownOgre; - - Ogre::Vector3 m_TranslateVector; - Ogre::Real m_MoveSpeed; - Ogre::Degree m_RotateSpeed; - float m_MoveScale; - Ogre::Degree m_RotScale; + Ogre::Vector3 m_TranslateVector; + Ogre::Real m_MoveSpeed; + Ogre::Degree m_RotateSpeed; + float m_MoveScale; + Ogre::Degree m_RotScale; #ifdef OGRE_STATIC_LIB Ogre::StaticPluginLoader m_StaticPluginLoader; #endif diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/AppDelegate.h b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/AppDelegate.h index 3cbc888ad1e..84c65283a42 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/AppDelegate.h +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/AppDelegate.h @@ -81,7 +81,7 @@ Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets(); // Clear event times - Ogre::Root::getSingleton().clearEventTimes(); + Ogre::Root::getSingleton().clearEventTimes(); } catch( Ogre::Exception& e ) { std::cerr << "An exception has occurred: " << e.getFullDescription().c_str() << std::endl; @@ -168,34 +168,34 @@ if(!OgreFramework::getSingletonPtr()->isOgreToBeShutDown() && Ogre::Root::getSingletonPtr() && Ogre::Root::getSingleton().isInitialised()) { - if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) - { - mStartTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); + if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) + { + mStartTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); - OgreFramework::getSingletonPtr()->m_pMouse->capture(); + OgreFramework::getSingletonPtr()->m_pMouse->capture(); - OgreFramework::getSingletonPtr()->updateOgre(mLastFrameTime); - OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); + OgreFramework::getSingletonPtr()->updateOgre(mLastFrameTime); + OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); - mLastFrameTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - mStartTime; - } + mLastFrameTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - mStartTime; + } } else { - - if (mDisplayLinkSupported) - { - [mDate release]; - mDate = nil; - - [mDisplayLink invalidate]; - mDisplayLink = nil; - } - else - { - [mTimer invalidate]; - mTimer = nil; - } + + if (mDisplayLinkSupported) + { + [mDate release]; + mDate = nil; + + [mDisplayLink invalidate]; + mDisplayLink = nil; + } + else + { + [mTimer invalidate]; + mTimer = nil; + } [[UIApplication sharedApplication] performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; } } diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreDemoApp.cpp b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreDemoApp.cpp index 0ac49783f9c..9e4d491df67 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreDemoApp.cpp +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreDemoApp.cpp @@ -2,8 +2,8 @@ DemoApp::DemoApp() { - m_pCubeNode = 0; - m_pCubeEntity = 0; + m_pCubeNode = 0; + m_pCubeEntity = 0; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -24,10 +24,10 @@ DemoApp::~DemoApp() #ifdef INCLUDE_RTSHADER_SYSTEM /*----------------------------------------------------------------------------- - | Initialize the RT Shader system. + | Initialize the RT Shader system. -----------------------------------------------------------------------------*/ bool DemoApp::initialiseRTShaderSystem(Ogre::SceneManager* sceneMgr) -{ +{ if (Ogre::RTShader::ShaderGenerator::initialize()) { mShaderGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr(); @@ -67,11 +67,11 @@ bool DemoApp::initialiseRTShaderSystem(Ogre::SceneManager* sceneMgr) } // Core shader libs not found -> shader generating will fail. - if (shaderCoreLibsPath.empty()) - return false; + if (shaderCoreLibsPath.empty()) + return false; // Create and register the material manager listener. - mMaterialMgrListener = new ShaderGeneratorTechniqueResolverListener(mShaderGenerator); + mMaterialMgrListener = new ShaderGeneratorTechniqueResolverListener(mShaderGenerator); Ogre::MaterialManager::getSingleton().addListener(mMaterialMgrListener); } @@ -88,7 +88,7 @@ void DemoApp::destroyRTShaderSystem() // Unregister the material manager listener. if (mMaterialMgrListener != NULL) - { + { Ogre::MaterialManager::getSingleton().removeListener(mMaterialMgrListener); delete mMaterialMgrListener; mMaterialMgrListener = NULL; @@ -96,7 +96,7 @@ void DemoApp::destroyRTShaderSystem() // Destroy RTShader system. if (mShaderGenerator != NULL) - { + { Ogre::RTShader::ShaderGenerator::destroy(); mShaderGenerator = NULL; } @@ -105,22 +105,22 @@ void DemoApp::destroyRTShaderSystem() void DemoApp::startDemo() { - new OgreFramework(); - if(!OgreFramework::getSingletonPtr()->initOgre("DemoApp v1.0", this, 0)) - return; + new OgreFramework(); + if(!OgreFramework::getSingletonPtr()->initOgre("DemoApp v1.0", this, 0)) + return; - m_bShutdown = false; + m_bShutdown = false; + + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Demo initialized!"); - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Demo initialized!"); - #ifdef INCLUDE_RTSHADER_SYSTEM initialiseRTShaderSystem(OgreFramework::getSingletonPtr()->m_pSceneMgr); - Ogre::MaterialPtr baseWhite = Ogre::MaterialManager::getSingleton().getByName("BaseWhite", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + Ogre::MaterialPtr baseWhite = Ogre::MaterialManager::getSingleton().getByName("BaseWhite", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); baseWhite->setLightingEnabled(false); mShaderGenerator->createShaderBasedTechnique( "BaseWhite", Ogre::MaterialManager::DEFAULT_SCHEME_NAME, - Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); mShaderGenerator->validateMaterial(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, "BaseWhite"); baseWhite->getTechnique(0)->getPass(0)->setVertexProgram( @@ -132,7 +132,7 @@ void DemoApp::startDemo() mShaderGenerator->createShaderBasedTechnique( "BaseWhiteNoLighting", Ogre::MaterialManager::DEFAULT_SCHEME_NAME, - Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); mShaderGenerator->validateMaterial(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, "BaseWhiteNoLighting"); Ogre::MaterialPtr baseWhiteNoLighting = Ogre::MaterialManager::getSingleton().getByName("BaseWhiteNoLighting", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); @@ -142,9 +142,9 @@ void DemoApp::startDemo() baseWhiteNoLighting->getTechnique(1)->getPass(0)->getFragmentProgram()->getName()); #endif - setupDemoScene(); + setupDemoScene(); #if !((OGRE_PLATFORM == OGRE_PLATFORM_APPLE) && __LP64__) - runDemo(); + runDemo(); #endif } @@ -152,62 +152,62 @@ void DemoApp::startDemo() void DemoApp::setupDemoScene() { - OgreFramework::getSingletonPtr()->m_pSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox"); + OgreFramework::getSingletonPtr()->m_pSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox"); - OgreFramework::getSingletonPtr()->m_pSceneMgr->createLight("Light")->setPosition(75,75,75); + OgreFramework::getSingletonPtr()->m_pSceneMgr->createLight("Light")->setPosition(75,75,75); - m_pCubeEntity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("Cube", "ogrehead.mesh"); - m_pCubeNode = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode("CubeNode"); - m_pCubeNode->attachObject(m_pCubeEntity); + m_pCubeEntity = OgreFramework::getSingletonPtr()->m_pSceneMgr->createEntity("Cube", "ogrehead.mesh"); + m_pCubeNode = OgreFramework::getSingletonPtr()->m_pSceneMgr->getRootSceneNode()->createChildSceneNode("CubeNode"); + m_pCubeNode->attachObject(m_pCubeEntity); } //||||||||||||||||||||||||||||||||||||||||||||||| void DemoApp::runDemo() { - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Start main loop..."); - - double timeSinceLastFrame = 0; - double startTime = 0; + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Start main loop..."); + + double timeSinceLastFrame = 0; + double startTime = 0; OgreFramework::getSingletonPtr()->m_pRenderWnd->resetStatistics(); #if (!defined(OGRE_IS_IOS)) && !((OGRE_PLATFORM == OGRE_PLATFORM_APPLE) && __LP64__) - while(!m_bShutdown && !OgreFramework::getSingletonPtr()->isOgreToBeShutDown()) - { - if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isClosed())m_bShutdown = true; + while(!m_bShutdown && !OgreFramework::getSingletonPtr()->isOgreToBeShutDown()) + { + if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isClosed())m_bShutdown = true; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE - Ogre::WindowEventUtilities::messagePump(); -#endif - if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) - { - startTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); + Ogre::WindowEventUtilities::messagePump(); +#endif + if(OgreFramework::getSingletonPtr()->m_pRenderWnd->isActive()) + { + startTime = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU(); #if !OGRE_IS_IOS - OgreFramework::getSingletonPtr()->m_pKeyboard->capture(); + OgreFramework::getSingletonPtr()->m_pKeyboard->capture(); #endif - OgreFramework::getSingletonPtr()->m_pMouse->capture(); + OgreFramework::getSingletonPtr()->m_pMouse->capture(); - OgreFramework::getSingletonPtr()->updateOgre(timeSinceLastFrame); - OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); + OgreFramework::getSingletonPtr()->updateOgre(timeSinceLastFrame); + OgreFramework::getSingletonPtr()->m_pRoot->renderOneFrame(); - timeSinceLastFrame = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - startTime; - } - else - { + timeSinceLastFrame = OgreFramework::getSingletonPtr()->m_pTimer->getMillisecondsCPU() - startTime; + } + else + { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 Sleep(1000); #else sleep(1); #endif - } - } + } + } #endif #if !defined(OGRE_IS_IOS) - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Main loop quit"); - OgreFramework::getSingletonPtr()->m_pLog->logMessage("Shutdown OGRE..."); + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Main loop quit"); + OgreFramework::getSingletonPtr()->m_pLog->logMessage("Shutdown OGRE..."); #endif } @@ -216,14 +216,14 @@ void DemoApp::runDemo() bool DemoApp::keyPressed(const OIS::KeyEvent &keyEventRef) { #if !defined(OGRE_IS_IOS) - OgreFramework::getSingletonPtr()->keyPressed(keyEventRef); - - if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_F)) - { + OgreFramework::getSingletonPtr()->keyPressed(keyEventRef); + + if(OgreFramework::getSingletonPtr()->m_pKeyboard->isKeyDown(OIS::KC_F)) + { //do something - } + } #endif - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -231,10 +231,10 @@ bool DemoApp::keyPressed(const OIS::KeyEvent &keyEventRef) bool DemoApp::keyReleased(const OIS::KeyEvent &keyEventRef) { #if !defined(OGRE_IS_IOS) - OgreFramework::getSingletonPtr()->keyReleased(keyEventRef); + OgreFramework::getSingletonPtr()->keyReleased(keyEventRef); #endif - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreDemoApp.h b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreDemoApp.h index 773c81f9dd6..b34fb2dbf55 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreDemoApp.h +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreDemoApp.h @@ -21,87 +21,87 @@ class ShaderGeneratorTechniqueResolverListener : public Ogre::MaterialManager::L { public: - ShaderGeneratorTechniqueResolverListener(Ogre::RTShader::ShaderGenerator* pShaderGenerator) - { - mShaderGenerator = pShaderGenerator; - } + ShaderGeneratorTechniqueResolverListener(Ogre::RTShader::ShaderGenerator* pShaderGenerator) + { + mShaderGenerator = pShaderGenerator; + } - /** This is the hook point where shader based technique will be created. + /** This is the hook point where shader based technique will be created. It will be called whenever the material manager won't find appropriate technique that satisfy the target scheme name. If the scheme name is out target RT Shader System scheme name we will try to create shader generated technique for it. */ - virtual Ogre::Technique* handleSchemeNotFound(unsigned short schemeIndex, + virtual Ogre::Technique* handleSchemeNotFound(unsigned short schemeIndex, const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, const Ogre::Renderable* rend) - { - Ogre::Technique* generatedTech = NULL; + { + Ogre::Technique* generatedTech = NULL; - // Case this is the default shader generator scheme. - if (schemeName == Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) - { - bool techniqueCreated; + // Case this is the default shader generator scheme. + if (schemeName == Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) + { + bool techniqueCreated; - // Create shader generated technique for this material. - techniqueCreated = mShaderGenerator->createShaderBasedTechnique( + // Create shader generated technique for this material. + techniqueCreated = mShaderGenerator->createShaderBasedTechnique( originalMaterial->getName(), Ogre::MaterialManager::DEFAULT_SCHEME_NAME, - schemeName); + schemeName); - // Case technique registration succeeded. - if (techniqueCreated) - { - // Force creating the shaders for the generated technique. - mShaderGenerator->validateMaterial(schemeName, originalMaterial->getName()); - - // Grab the generated technique. - Ogre::Material::TechniqueIterator itTech = originalMaterial->getTechniqueIterator(); + // Case technique registration succeeded. + if (techniqueCreated) + { + // Force creating the shaders for the generated technique. + mShaderGenerator->validateMaterial(schemeName, originalMaterial->getName()); - while (itTech.hasMoreElements()) - { - Ogre::Technique* curTech = itTech.getNext(); + // Grab the generated technique. + Ogre::Material::TechniqueIterator itTech = originalMaterial->getTechniqueIterator(); + + while (itTech.hasMoreElements()) + { + Ogre::Technique* curTech = itTech.getNext(); - if (curTech->getSchemeName() == schemeName) - { - generatedTech = curTech; - break; - } - } - } - } + if (curTech->getSchemeName() == schemeName) + { + generatedTech = curTech; + break; + } + } + } + } - return generatedTech; - } + return generatedTech; + } -protected: - Ogre::RTShader::ShaderGenerator* mShaderGenerator; // The shader generator instance. +protected: + Ogre::RTShader::ShaderGenerator* mShaderGenerator; // The shader generator instance. }; #endif class DemoApp : public OIS::KeyListener { public: - DemoApp(); - ~DemoApp(); + DemoApp(); + ~DemoApp(); + + void startDemo(); - void startDemo(); - - bool keyPressed(const OIS::KeyEvent &keyEventRef); - bool keyReleased(const OIS::KeyEvent &keyEventRef); + bool keyPressed(const OIS::KeyEvent &keyEventRef); + bool keyReleased(const OIS::KeyEvent &keyEventRef); private: void setupDemoScene(); - void runDemo(); + void runDemo(); bool initialiseRTShaderSystem(Ogre::SceneManager* sceneMgr); void destroyRTShaderSystem(); - Ogre::SceneNode* m_pCubeNode; - Ogre::Entity* m_pCubeEntity; + Ogre::SceneNode* m_pCubeNode; + Ogre::Entity* m_pCubeEntity; - bool m_bShutdown; + bool m_bShutdown; #ifdef INCLUDE_RTSHADER_SYSTEM - Ogre::RTShader::ShaderGenerator* mShaderGenerator; // The Shader generator instance. - ShaderGeneratorTechniqueResolverListener* mMaterialMgrListener; // Shader generator material manager listener. + Ogre::RTShader::ShaderGenerator* mShaderGenerator; // The Shader generator instance. + ShaderGeneratorTechniqueResolverListener* mMaterialMgrListener; // Shader generator material manager listener. #endif // INCLUDE_RTSHADER_SYSTEM }; diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreFramework.cpp b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreFramework.cpp index 511e3772e9f..168a7a1d479 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreFramework.cpp +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreFramework.cpp @@ -10,23 +10,23 @@ namespace Ogre OgreFramework::OgreFramework() { - m_MoveSpeed = 0.1f; - m_RotateSpeed = 0.3f; + m_MoveSpeed = 0.1f; + m_RotateSpeed = 0.3f; - m_bShutDownOgre = false; - m_iNumScreenShots = 0; + m_bShutDownOgre = false; + m_iNumScreenShots = 0; - m_pRoot = 0; - m_pSceneMgr = 0; - m_pRenderWnd = 0; - m_pCamera = 0; - m_pViewport = 0; - m_pLog = 0; - m_pTimer = 0; + m_pRoot = 0; + m_pSceneMgr = 0; + m_pRenderWnd = 0; + m_pCamera = 0; + m_pViewport = 0; + m_pLog = 0; + m_pTimer = 0; - m_pInputMgr = 0; - m_pKeyboard = 0; - m_pMouse = 0; + m_pInputMgr = 0; + m_pKeyboard = 0; + m_pMouse = 0; #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE m_ResourcePath = macBundlePath() + "/Contents/Resources/"; @@ -48,8 +48,8 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen { new Ogre::LogManager(); - m_pLog = Ogre::LogManager::getSingleton().createLog("OgreLogfile.log", true, true, false); - m_pLog->setDebugOutputEnabled(true); + m_pLog = Ogre::LogManager::getSingleton().createLog("OgreLogfile.log", true, true, false); + m_pLog->setDebugOutputEnabled(true); String pluginsPath; // only use plugins.cfg if not static @@ -63,64 +63,64 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen m_StaticPluginLoader.load(); #endif - if(!m_pRoot->showConfigDialog()) - return false; - m_pRenderWnd = m_pRoot->initialise(true, wndTitle); + if(!m_pRoot->showConfigDialog()) + return false; + m_pRenderWnd = m_pRoot->initialise(true, wndTitle); - m_pSceneMgr = m_pRoot->createSceneManager(ST_GENERIC, "SceneManager"); - m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.7f, 0.7f, 0.7f)); - - m_pCamera = m_pSceneMgr->createCamera("Camera"); - m_pCamera->setPosition(Vector3(0, 60, 60)); - m_pCamera->lookAt(Vector3(0, 0, 0)); - m_pCamera->setNearClipDistance(1); + m_pSceneMgr = m_pRoot->createSceneManager(ST_GENERIC, "SceneManager"); + m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.7f, 0.7f, 0.7f)); - m_pViewport = m_pRenderWnd->addViewport(m_pCamera); - m_pViewport->setBackgroundColour(ColourValue(0.8f, 0.7f, 0.6f, 1.0f)); + m_pCamera = m_pSceneMgr->createCamera("Camera"); + m_pCamera->setPosition(Vector3(0, 60, 60)); + m_pCamera->lookAt(Vector3(0, 0, 0)); + m_pCamera->setNearClipDistance(1); - m_pCamera->setAspectRatio(Real(m_pViewport->getActualWidth()) / Real(m_pViewport->getActualHeight())); - - m_pViewport->setCamera(m_pCamera); + m_pViewport = m_pRenderWnd->addViewport(m_pCamera); + m_pViewport->setBackgroundColour(ColourValue(0.8f, 0.7f, 0.6f, 1.0f)); - unsigned long hWnd = 0; + m_pCamera->setAspectRatio(Real(m_pViewport->getActualWidth()) / Real(m_pViewport->getActualHeight())); + + m_pViewport->setCamera(m_pCamera); + + unsigned long hWnd = 0; OIS::ParamList paramList; m_pRenderWnd->getCustomAttribute("WINDOW", &hWnd); - paramList.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(hWnd))); + paramList.insert(OIS::ParamList::value_type("WINDOW", Ogre::StringConverter::toString(hWnd))); - m_pInputMgr = OIS::InputManager::createInputSystem(paramList); + m_pInputMgr = OIS::InputManager::createInputSystem(paramList); #if !defined(OGRE_IS_IOS) m_pKeyboard = static_cast(m_pInputMgr->createInputObject(OIS::OISKeyboard, true)); - m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMouse, true)); + m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMouse, true)); - m_pMouse->getMouseState().height = m_pRenderWnd->getHeight(); - m_pMouse->getMouseState().width = m_pRenderWnd->getWidth(); + m_pMouse->getMouseState().height = m_pRenderWnd->getHeight(); + m_pMouse->getMouseState().width = m_pRenderWnd->getWidth(); #else - m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMultiTouch, true)); + m_pMouse = static_cast(m_pInputMgr->createInputObject(OIS::OISMultiTouch, true)); #endif #if !defined(OGRE_IS_IOS) - if(pKeyListener == 0) - m_pKeyboard->setEventCallback(this); - else - m_pKeyboard->setEventCallback(pKeyListener); + if(pKeyListener == 0) + m_pKeyboard->setEventCallback(this); + else + m_pKeyboard->setEventCallback(pKeyListener); #endif - if(pMouseListener == 0) - m_pMouse->setEventCallback(this); - else - m_pMouse->setEventCallback(pMouseListener); + if(pMouseListener == 0) + m_pMouse->setEventCallback(this); + else + m_pMouse->setEventCallback(pMouseListener); - Ogre::String secName, typeName, archName; - Ogre::ConfigFile cf; + Ogre::String secName, typeName, archName; + Ogre::ConfigFile cf; cf.load(m_ResourcePath + "resources.cfg"); - Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); + Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); while (seci.hasMoreElements()) { secName = seci.peekNextKey(); - Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); + Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); Ogre::ConfigFile::SettingsMultiMap::iterator i; for (i = settings->begin(); i != settings->end(); ++i) { @@ -136,20 +136,20 @@ bool OgreFramework::initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListen Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName); } } - Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); - Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); + Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - m_pTimer = OGRE_NEW Ogre::Timer(); - m_pTimer->reset(); - - m_pTrayMgr = new OgreBites::SdkTrayManager("TrayMgr", m_pRenderWnd, m_pMouse, this); + m_pTimer = OGRE_NEW Ogre::Timer(); + m_pTimer->reset(); + + m_pTrayMgr = new OgreBites::SdkTrayManager("TrayMgr", m_pRenderWnd, m_pMouse, this); m_pTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT); m_pTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT); m_pTrayMgr->hideCursor(); - m_pRenderWnd->setActive(true); + m_pRenderWnd->setActive(true); - return true; + return true; } OgreFramework::~OgreFramework() @@ -165,43 +165,43 @@ OgreFramework::~OgreFramework() bool OgreFramework::keyPressed(const OIS::KeyEvent &keyEventRef) { #if !defined(OGRE_IS_IOS) - - if(m_pKeyboard->isKeyDown(OIS::KC_ESCAPE)) - { + + if(m_pKeyboard->isKeyDown(OIS::KC_ESCAPE)) + { m_bShutDownOgre = true; return true; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_SYSRQ)) - { - m_pRenderWnd->writeContentsToTimestampedFile("BOF_Screenshot_", ".png"); - return true; - } - - if(m_pKeyboard->isKeyDown(OIS::KC_M)) - { - static int mode = 0; - - if(mode == 2) - { - m_pCamera->setPolygonMode(PM_SOLID); - mode = 0; - } - else if(mode == 0) - { + } + + if(m_pKeyboard->isKeyDown(OIS::KC_SYSRQ)) + { + m_pRenderWnd->writeContentsToTimestampedFile("BOF_Screenshot_", ".png"); + return true; + } + + if(m_pKeyboard->isKeyDown(OIS::KC_M)) + { + static int mode = 0; + + if(mode == 2) + { + m_pCamera->setPolygonMode(PM_SOLID); + mode = 0; + } + else if(mode == 0) + { m_pCamera->setPolygonMode(PM_WIREFRAME); mode = 1; - } - else if(mode == 1) - { - m_pCamera->setPolygonMode(PM_POINTS); - mode = 2; - } - } - - if(m_pKeyboard->isKeyDown(OIS::KC_O)) - { - if(m_pTrayMgr->isLogoVisible()) + } + else if(mode == 1) + { + m_pCamera->setPolygonMode(PM_POINTS); + mode = 2; + } + } + + if(m_pKeyboard->isKeyDown(OIS::KC_O)) + { + if(m_pTrayMgr->isLogoVisible()) { m_pTrayMgr->hideLogo(); m_pTrayMgr->hideFrameStats(); @@ -211,15 +211,15 @@ bool OgreFramework::keyPressed(const OIS::KeyEvent &keyEventRef) m_pTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT); m_pTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT); } - } + } #endif - return true; + return true; } bool OgreFramework::keyReleased(const OIS::KeyEvent &keyEventRef) { - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -252,10 +252,10 @@ bool OgreFramework::touchMoved(const OIS::MultiTouchEvent &evt) break; } #endif - m_pCamera->yaw(Degree(state.X.rel * -0.1)); - m_pCamera->pitch(Degree(state.Y.rel * -0.1)); - - return true; + m_pCamera->yaw(Degree(state.X.rel * -0.1)); + m_pCamera->pitch(Degree(state.Y.rel * -0.1)); + + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -263,7 +263,7 @@ bool OgreFramework::touchMoved(const OIS::MultiTouchEvent &evt) bool OgreFramework::touchPressed(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } //||||||||||||||||||||||||||||||||||||||||||||||| @@ -271,76 +271,76 @@ bool OgreFramework::touchPressed(const OIS:: MultiTouchEvent &evt) bool OgreFramework::touchReleased(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } bool OgreFramework::touchCancelled(const OIS:: MultiTouchEvent &evt) { #pragma unused(evt) - return true; + return true; } #else bool OgreFramework::mouseMoved(const OIS::MouseEvent &evt) { - m_pCamera->yaw(Degree(evt.state.X.rel * -0.1f)); - m_pCamera->pitch(Degree(evt.state.Y.rel * -0.1f)); - - return true; + m_pCamera->yaw(Degree(evt.state.X.rel * -0.1f)); + m_pCamera->pitch(Degree(evt.state.Y.rel * -0.1f)); + + return true; } bool OgreFramework::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { - return true; + return true; } bool OgreFramework::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { - return true; + return true; } #endif void OgreFramework::updateOgre(double timeSinceLastFrame) { - m_MoveScale = m_MoveSpeed * (float)timeSinceLastFrame; - m_RotScale = m_RotateSpeed * (float)timeSinceLastFrame; + m_MoveScale = m_MoveSpeed * (float)timeSinceLastFrame; + m_RotScale = m_RotateSpeed * (float)timeSinceLastFrame; #if OGRE_VERSION >= 0x10800 m_pSceneMgr->setSkyBoxEnabled(true); #endif - m_TranslateVector = Vector3::ZERO; + m_TranslateVector = Vector3::ZERO; - getInput(); - moveCamera(); + getInput(); + moveCamera(); - m_FrameEvent.timeSinceLastFrame = timeSinceLastFrame; + m_FrameEvent.timeSinceLastFrame = timeSinceLastFrame; m_pTrayMgr->frameRenderingQueued(m_FrameEvent); } void OgreFramework::moveCamera() { #if !defined(OGRE_IS_IOS) - if(m_pKeyboard->isKeyDown(OIS::KC_LSHIFT)) - m_pCamera->moveRelative(m_TranslateVector); - else + if(m_pKeyboard->isKeyDown(OIS::KC_LSHIFT)) + m_pCamera->moveRelative(m_TranslateVector); + else #endif - m_pCamera->moveRelative(m_TranslateVector / 10); + m_pCamera->moveRelative(m_TranslateVector / 10); } void OgreFramework::getInput() { #if !defined(OGRE_IS_IOS) - if(m_pKeyboard->isKeyDown(OIS::KC_A)) - m_TranslateVector.x = -m_MoveScale; - - if(m_pKeyboard->isKeyDown(OIS::KC_D)) - m_TranslateVector.x = m_MoveScale; - - if(m_pKeyboard->isKeyDown(OIS::KC_W)) - m_TranslateVector.z = -m_MoveScale; - - if(m_pKeyboard->isKeyDown(OIS::KC_S)) - m_TranslateVector.z = m_MoveScale; + if(m_pKeyboard->isKeyDown(OIS::KC_A)) + m_TranslateVector.x = -m_MoveScale; + + if(m_pKeyboard->isKeyDown(OIS::KC_D)) + m_TranslateVector.x = m_MoveScale; + + if(m_pKeyboard->isKeyDown(OIS::KC_W)) + m_TranslateVector.z = -m_MoveScale; + + if(m_pKeyboard->isKeyDown(OIS::KC_S)) + m_TranslateVector.z = m_MoveScale; #endif } diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreFramework.h b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreFramework.h index 521b483a92f..9a015379b11 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreFramework.h +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreFramework.h @@ -76,48 +76,48 @@ class OgreFramework : public Ogre::Singleton, OIS::KeyListener, O #endif { public: - OgreFramework(); - ~OgreFramework(); + OgreFramework(); + ~OgreFramework(); #ifdef OGRE_IS_IOS bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MultiTouchListener *pMouseListener = 0); #else - bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MouseListener *pMouseListener = 0); + bool initOgre(Ogre::String wndTitle, OIS::KeyListener *pKeyListener = 0, OIS::MouseListener *pMouseListener = 0); #endif - void updateOgre(double timeSinceLastFrame); - void moveCamera(); - void getInput(); + void updateOgre(double timeSinceLastFrame); + void moveCamera(); + void getInput(); - bool isOgreToBeShutDown()const{return m_bShutDownOgre;} + bool isOgreToBeShutDown()const{return m_bShutDownOgre;} - bool keyPressed(const OIS::KeyEvent &keyEventRef); - bool keyReleased(const OIS::KeyEvent &keyEventRef); + bool keyPressed(const OIS::KeyEvent &keyEventRef); + bool keyReleased(const OIS::KeyEvent &keyEventRef); #ifdef OGRE_IS_IOS - bool touchMoved(const OIS::MultiTouchEvent &evt); - bool touchPressed(const OIS::MultiTouchEvent &evt); - bool touchReleased(const OIS::MultiTouchEvent &evt); - bool touchCancelled(const OIS::MultiTouchEvent &evt); + bool touchMoved(const OIS::MultiTouchEvent &evt); + bool touchPressed(const OIS::MultiTouchEvent &evt); + bool touchReleased(const OIS::MultiTouchEvent &evt); + bool touchCancelled(const OIS::MultiTouchEvent &evt); #else - bool mouseMoved(const OIS::MouseEvent &evt); - bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id); - bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id); + bool mouseMoved(const OIS::MouseEvent &evt); + bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id); + bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id); #endif - - Ogre::Root* m_pRoot; - Ogre::SceneManager* m_pSceneMgr; - Ogre::RenderWindow* m_pRenderWnd; - Ogre::Camera* m_pCamera; - Ogre::Viewport* m_pViewport; - Ogre::Log* m_pLog; - Ogre::Timer* m_pTimer; - - OIS::InputManager* m_pInputMgr; - OIS::Keyboard* m_pKeyboard; + + Ogre::Root* m_pRoot; + Ogre::SceneManager* m_pSceneMgr; + Ogre::RenderWindow* m_pRenderWnd; + Ogre::Camera* m_pCamera; + Ogre::Viewport* m_pViewport; + Ogre::Log* m_pLog; + Ogre::Timer* m_pTimer; + + OIS::InputManager* m_pInputMgr; + OIS::Keyboard* m_pKeyboard; #ifdef OGRE_IS_IOS - OIS::MultiTouch* m_pMouse; + OIS::MultiTouch* m_pMouse; #else - OIS::Mouse* m_pMouse; + OIS::Mouse* m_pMouse; #endif protected: @@ -125,20 +125,20 @@ class OgreFramework : public Ogre::Singleton, OIS::KeyListener, O Ogre::String m_ResourcePath; private: - OgreFramework(const OgreFramework&); - OgreFramework& operator= (const OgreFramework&); + OgreFramework(const OgreFramework&); + OgreFramework& operator= (const OgreFramework&); - OgreBites::SdkTrayManager* m_pTrayMgr; + OgreBites::SdkTrayManager* m_pTrayMgr; Ogre::FrameEvent m_FrameEvent; - int m_iNumScreenShots; + int m_iNumScreenShots; + + bool m_bShutDownOgre; - bool m_bShutDownOgre; - - Ogre::Vector3 m_TranslateVector; - Ogre::Real m_MoveSpeed; - Ogre::Degree m_RotateSpeed; - float m_MoveScale; - Ogre::Degree m_RotScale; + Ogre::Vector3 m_TranslateVector; + Ogre::Real m_MoveSpeed; + Ogre::Degree m_RotateSpeed; + float m_MoveScale; + Ogre::Degree m_RotScale; #ifdef OGRE_STATIC_LIB Ogre::StaticPluginLoader m_StaticPluginLoader; #endif diff --git a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreStaticPluginLoader.h b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreStaticPluginLoader.h index c6ebd7c3a05..a93a85df453 100644 --- a/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreStaticPluginLoader.h +++ b/SDK/OSX/Xcode Templates/Xcode4/Project Templates/Ogre/iOS Application.xctemplate/OgreStaticPluginLoader.h @@ -60,144 +60,144 @@ Description: Utility class to load plugins statically namespace Ogre { - /** Utility class for loading some plugins statically. - @remarks - When loading plugins statically, you are limited to loading plugins - that are known about at compile time. You should define preprocessor - symbols depending on which plugins you want to load - the symbol being - OGRE_STATIC_, with pluginname being the usual name of the - plugin DLL (no file extension, no debug suffix, and without the Plugin_ - or RenderSystem_ prefix.) - */ - class StaticPluginLoader - { - protected: + /** Utility class for loading some plugins statically. + @remarks + When loading plugins statically, you are limited to loading plugins + that are known about at compile time. You should define preprocessor + symbols depending on which plugins you want to load - the symbol being + OGRE_STATIC_, with pluginname being the usual name of the + plugin DLL (no file extension, no debug suffix, and without the Plugin_ + or RenderSystem_ prefix.) + */ + class StaticPluginLoader + { + protected: #ifdef OGRE_STATIC_CgProgramManager - CgPlugin* mCgPlugin; + CgPlugin* mCgPlugin; #endif #ifdef OGRE_STATIC_OctreeSceneManager - OctreePlugin* mOctreePlugin; + OctreePlugin* mOctreePlugin; #endif #ifdef OGRE_STATIC_ParticleFX - ParticleFXPlugin* mParticleFXPlugin; + ParticleFXPlugin* mParticleFXPlugin; #endif #ifdef OGRE_STATIC_BSPSceneManager - BspSceneManagerPlugin* mBSPPlugin; + BspSceneManagerPlugin* mBSPPlugin; #endif #ifdef OGRE_STATIC_PCZSceneManager - PCZPlugin* mPCZPlugin; + PCZPlugin* mPCZPlugin; #endif #ifdef OGRE_STATIC_OctreeZone - OctreeZonePlugin* mOctreeZonePlugin; + OctreeZonePlugin* mOctreeZonePlugin; #endif #ifdef OGRE_STATIC_GL - GLPlugin* mGLPlugin; + GLPlugin* mGLPlugin; #endif #ifdef OGRE_STATIC_GLES - GLESPlugin* mGLESPlugin; + GLESPlugin* mGLESPlugin; #endif #ifdef OGRE_STATIC_GLES2 - GLES2Plugin* mGLES2Plugin; + GLES2Plugin* mGLES2Plugin; #endif #ifdef OGRE_STATIC_Direct3D9 - D3D9Plugin* mD3D9Plugin; + D3D9Plugin* mD3D9Plugin; #endif #ifdef OGRE_STATIC_Direct3D10 - D3D10Plugin* mD3D10Plugin; + D3D10Plugin* mD3D10Plugin; #endif - public: - StaticPluginLoader() {} + public: + StaticPluginLoader() {} - /** Load all the enabled plugins against the passed in root object. */ - void load() - { - Root& root = Root::getSingleton(); + /** Load all the enabled plugins against the passed in root object. */ + void load() + { + Root& root = Root::getSingleton(); #ifdef OGRE_STATIC_GL - mGLPlugin = OGRE_NEW GLPlugin(); - root.installPlugin(mGLPlugin); + mGLPlugin = OGRE_NEW GLPlugin(); + root.installPlugin(mGLPlugin); #endif #ifdef OGRE_STATIC_GLES - mGLESPlugin = OGRE_NEW GLESPlugin(); - root.installPlugin(mGLESPlugin); + mGLESPlugin = OGRE_NEW GLESPlugin(); + root.installPlugin(mGLESPlugin); #endif #ifdef OGRE_STATIC_GLES2 - mGLES2Plugin = OGRE_NEW GLES2Plugin(); - root.installPlugin(mGLES2Plugin); + mGLES2Plugin = OGRE_NEW GLES2Plugin(); + root.installPlugin(mGLES2Plugin); #endif #ifdef OGRE_STATIC_Direct3D9 - mD3D9Plugin = OGRE_NEW D3D9Plugin(); - root.installPlugin(mD3D9Plugin); + mD3D9Plugin = OGRE_NEW D3D9Plugin(); + root.installPlugin(mD3D9Plugin); #endif #ifdef OGRE_STATIC_Direct3D10 - mD3D10Plugin = OGRE_NEW D3D10Plugin(); - root.installPlugin(mD3D10Plugin); + mD3D10Plugin = OGRE_NEW D3D10Plugin(); + root.installPlugin(mD3D10Plugin); #endif #ifdef OGRE_STATIC_CgProgramManager - mCgPlugin = OGRE_NEW CgPlugin(); - root.installPlugin(mCgPlugin); + mCgPlugin = OGRE_NEW CgPlugin(); + root.installPlugin(mCgPlugin); #endif #ifdef OGRE_STATIC_OctreeSceneManager - mOctreePlugin = OGRE_NEW OctreePlugin(); - root.installPlugin(mOctreePlugin); + mOctreePlugin = OGRE_NEW OctreePlugin(); + root.installPlugin(mOctreePlugin); #endif #ifdef OGRE_STATIC_ParticleFX - mParticleFXPlugin = OGRE_NEW ParticleFXPlugin(); - root.installPlugin(mParticleFXPlugin); + mParticleFXPlugin = OGRE_NEW ParticleFXPlugin(); + root.installPlugin(mParticleFXPlugin); #endif #ifdef OGRE_STATIC_BSPSceneManager - mBSPPlugin = OGRE_NEW BspSceneManagerPlugin(); - root.installPlugin(mBSPPlugin); + mBSPPlugin = OGRE_NEW BspSceneManagerPlugin(); + root.installPlugin(mBSPPlugin); #endif #ifdef OGRE_STATIC_PCZSceneManager - mPCZPlugin = OGRE_NEW PCZPlugin(); - root.installPlugin(mPCZPlugin); + mPCZPlugin = OGRE_NEW PCZPlugin(); + root.installPlugin(mPCZPlugin); #endif #ifdef OGRE_STATIC_OctreeZone - mOctreeZonePlugin = OGRE_NEW OctreeZonePlugin(); - root.installPlugin(mOctreeZonePlugin); + mOctreeZonePlugin = OGRE_NEW OctreeZonePlugin(); + root.installPlugin(mOctreeZonePlugin); #endif - } + } - void unload() - { - // don't unload plugins, since Root will have done that. Destroy here. + void unload() + { + // don't unload plugins, since Root will have done that. Destroy here. #ifdef OGRE_STATIC_OctreeZone - OGRE_DELETE mOctreeZonePlugin; + OGRE_DELETE mOctreeZonePlugin; #endif #ifdef OGRE_STATIC_PCZSceneManager - OGRE_DELETE mPCZPlugin; + OGRE_DELETE mPCZPlugin; #endif #ifdef OGRE_STATIC_BSPSceneManager - OGRE_DELETE mBSPPlugin; + OGRE_DELETE mBSPPlugin; #endif #ifdef OGRE_STATIC_ParticleFX - OGRE_DELETE mParticleFXPlugin; + OGRE_DELETE mParticleFXPlugin; #endif #ifdef OGRE_STATIC_OctreeSceneManager - OGRE_DELETE mOctreePlugin; + OGRE_DELETE mOctreePlugin; #endif #ifdef OGRE_STATIC_CgProgramManager - OGRE_DELETE mCgPlugin; + OGRE_DELETE mCgPlugin; #endif #ifdef OGRE_STATIC_Direct3D9 - OGRE_DELETE mD3D9Plugin; + OGRE_DELETE mD3D9Plugin; #endif #ifdef OGRE_STATIC_Direct3D10 - OGRE_DELETE mD3D10Plugin; + OGRE_DELETE mD3D10Plugin; #endif #ifdef OGRE_STATIC_GL - OGRE_DELETE mGLPlugin; + OGRE_DELETE mGLPlugin; #endif #ifdef OGRE_STATIC_GLES - OGRE_DELETE mGLESPlugin; + OGRE_DELETE mGLESPlugin; #endif #ifdef OGRE_STATIC_GLES2 - OGRE_DELETE mGLES2Plugin; + OGRE_DELETE mGLES2Plugin; #endif - } + } - }; + }; } diff --git a/Samples/BSP/src/BSP.cpp b/Samples/BSP/src/BSP.cpp index c3898f0ab96..780fb042181 100644 --- a/Samples/BSP/src/BSP.cpp +++ b/Samples/BSP/src/BSP.cpp @@ -12,17 +12,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_BSP; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_BSP; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/BezierPatch/include/BezierPatch.h b/Samples/BezierPatch/include/BezierPatch.h index ec35f3f36c6..0ff5bfe3792 100644 --- a/Samples/BezierPatch/include/BezierPatch.h +++ b/Samples/BezierPatch/include/BezierPatch.h @@ -10,106 +10,106 @@ class _OgreSampleClassExport Sample_BezierPatch : public SdkSample { public: - Sample_BezierPatch() - { - mInfo["Title"] = "Bezier Patch"; - mInfo["Description"] = "A demonstration of the Bezier patch support."; - mInfo["Thumbnail"] = "thumb_bezier.png"; - mInfo["Category"] = "Geometry"; - } - - void checkBoxToggled(CheckBox* box) - { - mPatchPass->setPolygonMode(box->isChecked() ? PM_WIREFRAME : PM_SOLID); + Sample_BezierPatch() + { + mInfo["Title"] = "Bezier Patch"; + mInfo["Description"] = "A demonstration of the Bezier patch support."; + mInfo["Thumbnail"] = "thumb_bezier.png"; + mInfo["Category"] = "Geometry"; + } + + void checkBoxToggled(CheckBox* box) + { + mPatchPass->setPolygonMode(box->isChecked() ? PM_WIREFRAME : PM_SOLID); #ifdef INCLUDE_RTSHADER_SYSTEM - // Invalidate material in order to reflect polygon mode change in the generated shader based pass. - mShaderGenerator->invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, mPatchPass->getParent()->getParent()->getName()); + // Invalidate material in order to reflect polygon mode change in the generated shader based pass. + mShaderGenerator->invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, mPatchPass->getParent()->getParent()->getName()); #endif - } + } - void sliderMoved(Slider* slider) - { - mPatch->setSubdivision(slider->getValue()); - } + void sliderMoved(Slider* slider) + { + mPatch->setSubdivision(slider->getValue()); + } protected: #if OGRE_COMPILER == OGRE_COMPILER_MSVC -# pragma pack(push, 1) +# pragma pack(push, 1) #endif struct PatchVertex - { + { float x, y, z; float nx, ny, nz; float u, v; }; #if OGRE_COMPILER == OGRE_COMPILER_MSVC -# pragma pack(pop) +# pragma pack(pop) #endif - void setupContent() - { - // setup some basic lighting for our scene - mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); + void setupContent() + { + // setup some basic lighting for our scene + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); mSceneMgr->createLight()->setPosition(100, 100, 100); - // define the control point vertices for our patch - PatchVertex verts[9] = - { - {-50, -35, -50, -0.5, 0.5, 0.0, 0.0, 0.0}, - { 0, 0, -50, 0.0, 0.5, 0.0, 0.5, 0.0}, - { 50, 35, -50, 0.5, 0.5, 0.0, 1.0, 0.0}, - {-50, 0, 0, -0.5, 0.5, 0.0, 0.0, 0.5}, - { 0, 0, 0, 0.0, 0.5, 0.0, 0.5, 0.5}, - { 50, 0, 0, 0.5, 0.5, 0.0, 1.0, 0.5}, - {-50, 35, 50, -0.5, 0.5, 0.0, 0.0, 1.0}, - { 0, 0, 50, 0.0, 0.5, 0.0, 0.5, 1.0}, - { 50, -35, 50, 0.5, 0.5, 0.0, 1.0, 1.0} - }; - - // specify a vertex format declaration for our patch: 3 floats for position, 3 floats for normal, 2 floats for UV + // define the control point vertices for our patch + PatchVertex verts[9] = + { + {-50, -35, -50, -0.5, 0.5, 0.0, 0.0, 0.0}, + { 0, 0, -50, 0.0, 0.5, 0.0, 0.5, 0.0}, + { 50, 35, -50, 0.5, 0.5, 0.0, 1.0, 0.0}, + {-50, 0, 0, -0.5, 0.5, 0.0, 0.0, 0.5}, + { 0, 0, 0, 0.0, 0.5, 0.0, 0.5, 0.5}, + { 50, 0, 0, 0.5, 0.5, 0.0, 1.0, 0.5}, + {-50, 35, 50, -0.5, 0.5, 0.0, 0.0, 1.0}, + { 0, 0, 50, 0.0, 0.5, 0.0, 0.5, 1.0}, + { 50, -35, 50, 0.5, 0.5, 0.0, 1.0, 1.0} + }; + + // specify a vertex format declaration for our patch: 3 floats for position, 3 floats for normal, 2 floats for UV mDecl = HardwareBufferManager::getSingleton().createVertexDeclaration(); mDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); mDecl->addElement(0, sizeof(float) * 3, VET_FLOAT3, VES_NORMAL); mDecl->addElement(0, sizeof(float) * 6, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); - // create a patch mesh using vertices and declaration + // create a patch mesh using vertices and declaration mPatch = MeshManager::getSingleton().createBezierPatch("patch", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, (float*)verts, mDecl, 3, 3, 5, 5, PatchSurface::VS_BOTH); + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, (float*)verts, mDecl, 3, 3, 5, 5, PatchSurface::VS_BOTH); mPatch->setSubdivision(0); // start at 0 detail - // create a patch entity from the mesh, give it a material, and attach it to the origin + // create a patch entity from the mesh, give it a material, and attach it to the origin Entity* ent = mSceneMgr->createEntity("Patch", "patch"); - ent->setMaterialName("Examples/BumpyMetal"); + ent->setMaterialName("Examples/BumpyMetal"); mSceneMgr->getRootSceneNode()->attachObject(ent); - // save the main pass of the material so we can toggle wireframe on it - mPatchPass = ent->getSubEntity(0)->getMaterial()->getTechnique(0)->getPass(0); + // save the main pass of the material so we can toggle wireframe on it + mPatchPass = ent->getSubEntity(0)->getMaterial()->getTechnique(0)->getPass(0); - // use an orbit style camera - mCameraMan->setStyle(CS_ORBIT); - mCameraMan->setYawPitchDist(Degree(0), Degree(30), 250); + // use an orbit style camera + mCameraMan->setStyle(CS_ORBIT); + mCameraMan->setYawPitchDist(Degree(0), Degree(30), 250); - mTrayMgr->showCursor(); + mTrayMgr->showCursor(); - // create slider to adjust detail and checkbox to toggle wireframe - mTrayMgr->createThickSlider(TL_TOPLEFT, "Detail", "Detail", 120, 44, 0, 1, 6); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Wireframe", "Wireframe", 120); - } + // create slider to adjust detail and checkbox to toggle wireframe + mTrayMgr->createThickSlider(TL_TOPLEFT, "Detail", "Detail", 120, 44, 0, 1, 6); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Wireframe", "Wireframe", 120); + } void cleanupContent() { HardwareBufferManager::getSingleton().destroyVertexDeclaration(mDecl); - mPatchPass->setPolygonMode(PM_SOLID); - MeshManager::getSingleton().remove(mPatch->getHandle()); + mPatchPass->setPolygonMode(PM_SOLID); + MeshManager::getSingleton().remove(mPatch->getHandle()); } VertexDeclaration* mDecl; - PatchMeshPtr mPatch; - Pass* mPatchPass; + PatchMeshPtr mPatch; + Pass* mPatchPass; }; #endif diff --git a/Samples/BezierPatch/src/BezierPatch.cpp b/Samples/BezierPatch/src/BezierPatch.cpp index 2b1e4cd4e75..9091b5de28a 100644 --- a/Samples/BezierPatch/src/BezierPatch.cpp +++ b/Samples/BezierPatch/src/BezierPatch.cpp @@ -12,17 +12,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_BezierPatch; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_BezierPatch; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Browser/WinRT.Xaml/App.xaml.cpp b/Samples/Browser/WinRT.Xaml/App.xaml.cpp index e4bd6112fa3..a16801ab9d0 100644 --- a/Samples/Browser/WinRT.Xaml/App.xaml.cpp +++ b/Samples/Browser/WinRT.Xaml/App.xaml.cpp @@ -1,4 +1,4 @@ -// +// // App.xaml.cpp // Implementation of the App class. // @@ -30,8 +30,8 @@ using namespace Windows::UI::Xaml::Navigation; /// App::App() { - InitializeComponent(); - Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending); + InitializeComponent(); + Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending); } /// @@ -42,29 +42,29 @@ App::App() /// Details about the launch request and process. void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ pArgs) { - // Do not repeat app initialization when already running, just ensure that - // the window is active - if (pArgs->PreviousExecutionState == ApplicationExecutionState::Running) - { - Window::Current->Activate(); - return; - } + // Do not repeat app initialization when already running, just ensure that + // the window is active + if (pArgs->PreviousExecutionState == ApplicationExecutionState::Running) + { + Window::Current->Activate(); + return; + } - if (pArgs->PreviousExecutionState == ApplicationExecutionState::Terminated) - { - //TODO: Load state from previously suspended application - } + if (pArgs->PreviousExecutionState == ApplicationExecutionState::Terminated) + { + //TODO: Load state from previously suspended application + } - // Create a Frame to act navigation context and navigate to the first page - auto rootFrame = ref new Frame(); - if (!rootFrame->Navigate(TypeName(SampleBrowserWinRT::typeid))) - { - throw ref new FailureException("Failed to create initial page"); - } + // Create a Frame to act navigation context and navigate to the first page + auto rootFrame = ref new Frame(); + if (!rootFrame->Navigate(TypeName(SampleBrowserWinRT::typeid))) + { + throw ref new FailureException("Failed to create initial page"); + } - // Place the frame in the current Window and ensure that it is active - Window::Current->Content = rootFrame; - Window::Current->Activate(); + // Place the frame in the current Window and ensure that it is active + Window::Current->Content = rootFrame; + Window::Current->Activate(); } /// @@ -76,8 +76,8 @@ void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEvent /// Details about the suspend request. void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e) { - (void) sender; // Unused parameter - (void) e; // Unused parameter + (void) sender; // Unused parameter + (void) e; // Unused parameter - //TODO: Save application state and stop any background activity + //TODO: Save application state and stop any background activity } diff --git a/Samples/Browser/WinRT.Xaml/App.xaml.h b/Samples/Browser/WinRT.Xaml/App.xaml.h index 70266810502..7cab22e5a95 100644 --- a/Samples/Browser/WinRT.Xaml/App.xaml.h +++ b/Samples/Browser/WinRT.Xaml/App.xaml.h @@ -1,4 +1,4 @@ -// +// // App.xaml.h // Declaration of the App class. // @@ -10,16 +10,16 @@ namespace SampleBrowserWinRTXaml { - /// - /// Provides application-specific behavior to supplement the default Application class. - /// - ref class App sealed - { - public: - App(); - virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ pArgs) override; + /// + /// Provides application-specific behavior to supplement the default Application class. + /// + ref class App sealed + { + public: + App(); + virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ pArgs) override; - private: - void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e); - }; + private: + void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e); + }; } diff --git a/Samples/Browser/WinRT.Xaml/SampleBrowserWinRT.xaml.cpp b/Samples/Browser/WinRT.Xaml/SampleBrowserWinRT.xaml.cpp index 119c98e3fc8..477a4309dd2 100644 --- a/Samples/Browser/WinRT.Xaml/SampleBrowserWinRT.xaml.cpp +++ b/Samples/Browser/WinRT.Xaml/SampleBrowserWinRT.xaml.cpp @@ -1,4 +1,4 @@ -// +// // BlankPage.xaml.cpp // Implementation of the BlankPage.xaml class. // @@ -23,47 +23,47 @@ using namespace Windows::UI::Xaml::Navigation; SampleBrowserWinRT::SampleBrowserWinRT() { - InitializeComponent(); + InitializeComponent(); - // setup timer at 60 FPS - TimeSpan span; - span.Duration = 10000000 / 60; // convert to 100ns ticks - m_timer = ref new Windows::UI::Xaml::DispatcherTimer; - m_timer->Interval = span; - m_timer->Tick += ref new Windows::Foundation::EventHandler(this, &SampleBrowserWinRT::DisplayCurrentFrame); + // setup timer at 60 FPS + TimeSpan span; + span.Duration = 10000000 / 60; // convert to 100ns ticks + m_timer = ref new Windows::UI::Xaml::DispatcherTimer; + m_timer->Interval = span; + m_timer->Tick += ref new Windows::Foundation::EventHandler(this, &SampleBrowserWinRT::DisplayCurrentFrame); - contentView->SizeChanged += - ref new Windows::UI::Xaml::SizeChangedEventHandler(this, &SampleBrowserWinRT::OnContentViewSizeChanged); + contentView->SizeChanged += + ref new Windows::UI::Xaml::SizeChangedEventHandler(this, &SampleBrowserWinRT::OnContentViewSizeChanged); - StartRendering(); + StartRendering(); } void SampleBrowserWinRT::StartRendering() { - m_sampleBrowser.initAppForWinRT(this->contentView, m_inputManager.GetInputContext()); - m_sampleBrowser.initApp(); + m_sampleBrowser.initAppForWinRT(this->contentView, m_inputManager.GetInputContext()); + m_sampleBrowser.initApp(); - m_timer->Start(); + m_timer->Start(); } void SampleBrowserWinRT::StopRendering() { - m_timer->Stop(); + m_timer->Stop(); - m_sampleBrowser.closeApp(); + m_sampleBrowser.closeApp(); } void SampleBrowserWinRT::DisplayCurrentFrame(Platform::Object^ sender, Platform::Object^ e) { - if(m_windowClosed - || Ogre::Root::getSingleton().endRenderingQueued() - || !Ogre::Root::getSingleton().renderOneFrame(1.0f / 60.0f)) - StopRendering(); + if(m_windowClosed + || Ogre::Root::getSingleton().endRenderingQueued() + || !Ogre::Root::getSingleton().renderOneFrame(1.0f / 60.0f)) + StopRendering(); } void SampleBrowserWinRT::OnContentViewSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e) { - m_sampleBrowser.windowMovedOrResized(); + m_sampleBrowser.windowMovedOrResized(); } @@ -78,12 +78,12 @@ void SampleBrowserWinRT::OnNavigatedTo(NavigationEventArgs^ e) void SampleBrowserWinRT::OnKeyDown(Windows::UI::Xaml::Input::KeyRoutedEventArgs^ args) { - if(m_inputManager.OnKeyAction(args->Key, args->KeyStatus, true)) args->Handled = true; + if(m_inputManager.OnKeyAction(args->Key, args->KeyStatus, true)) args->Handled = true; } void SampleBrowserWinRT::OnKeyUp(Windows::UI::Xaml::Input::KeyRoutedEventArgs^ args) { - if(m_inputManager.OnKeyAction(args->Key, args->KeyStatus, false)) args->Handled = true; + if(m_inputManager.OnKeyAction(args->Key, args->KeyStatus, false)) args->Handled = true; } //void SampleBrowserWinRT::OnCharacterReceived(Windows::UI::Core::CharacterReceivedEventArgs^ args) diff --git a/Samples/Browser/WinRT.Xaml/SampleBrowserWinRT.xaml.h b/Samples/Browser/WinRT.Xaml/SampleBrowserWinRT.xaml.h index aebc056d729..5eeb62ba709 100644 --- a/Samples/Browser/WinRT.Xaml/SampleBrowserWinRT.xaml.h +++ b/Samples/Browser/WinRT.Xaml/SampleBrowserWinRT.xaml.h @@ -1,4 +1,4 @@ -// +// // BlankPage.xaml.h // Declaration of the BlankPage class. // @@ -12,34 +12,34 @@ namespace SampleBrowserWinRTXaml { - /// - /// An empty page that can be used on its own or navigated to within a Frame. - /// - public ref class SampleBrowserWinRT sealed - { - public: - SampleBrowserWinRT(); + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public ref class SampleBrowserWinRT sealed + { + public: + SampleBrowserWinRT(); - protected: - virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override; + protected: + virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override; - void StartRendering(); - void StopRendering(); + void StartRendering(); + void StopRendering(); void DisplayCurrentFrame(Platform::Object^ sender, Platform::Object^ e); - void OnContentViewSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e); + void OnContentViewSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e); - virtual void OnKeyDown(Windows::UI::Xaml::Input::KeyRoutedEventArgs^ args) override; - virtual void OnKeyUp(Windows::UI::Xaml::Input::KeyRoutedEventArgs^ args) override; -// virtual void OnCharacterReceived(Windows::UI::Core::CharacterReceivedEventArgs^ args) override; - virtual void OnPointerPressed(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) override; - virtual void OnPointerReleased(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) override; - virtual void OnPointerMoved(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) override; - virtual void OnPointerWheelChanged(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) override; + virtual void OnKeyDown(Windows::UI::Xaml::Input::KeyRoutedEventArgs^ args) override; + virtual void OnKeyUp(Windows::UI::Xaml::Input::KeyRoutedEventArgs^ args) override; +// virtual void OnCharacterReceived(Windows::UI::Core::CharacterReceivedEventArgs^ args) override; + virtual void OnPointerPressed(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) override; + virtual void OnPointerReleased(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) override; + virtual void OnPointerMoved(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) override; + virtual void OnPointerWheelChanged(Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) override; - private: - Windows::UI::Xaml::DispatcherTimer^ m_timer; - OgreBites::SampleBrowser m_sampleBrowser; - OgreBites::InputManagerWinRT m_inputManager; - bool m_windowClosed; - }; + private: + Windows::UI::Xaml::DispatcherTimer^ m_timer; + OgreBites::SampleBrowser m_sampleBrowser; + OgreBites::InputManagerWinRT m_inputManager; + bool m_windowClosed; + }; } diff --git a/Samples/Browser/WinRT.Xaml/pch.cpp b/Samples/Browser/WinRT.Xaml/pch.cpp index 01484ff5aa4..97b544ec11b 100644 --- a/Samples/Browser/WinRT.Xaml/pch.cpp +++ b/Samples/Browser/WinRT.Xaml/pch.cpp @@ -1,4 +1,4 @@ -// +// // pch.cpp // Include the standard header and generate the precompiled header. // diff --git a/Samples/Browser/WinRT.Xaml/pch.h b/Samples/Browser/WinRT.Xaml/pch.h index 31c1c1e3568..2a73475d957 100644 --- a/Samples/Browser/WinRT.Xaml/pch.h +++ b/Samples/Browser/WinRT.Xaml/pch.h @@ -1,4 +1,4 @@ -// +// // pch.h // Header for standard system include files. // diff --git a/Samples/Browser/include/InputManagerWinRT.h b/Samples/Browser/include/InputManagerWinRT.h index 142a6704bb3..aadcff696d9 100644 --- a/Samples/Browser/include/InputManagerWinRT.h +++ b/Samples/Browser/include/InputManagerWinRT.h @@ -38,10 +38,10 @@ using namespace DirectX; #error This header is for use with WinRT only #endif -#if OIS_VERSION >= 0x010300 // OIS_VERSION >= 1.3.0 -#define OIS_130_CONST const -#else // OIS_VERSION == 1.2.0 -#define OIS_130_CONST +#if OIS_VERSION >= 0x010300 // OIS_VERSION >= 1.3.0 +#define OIS_130_CONST const +#else // OIS_VERSION == 1.2.0 +#define OIS_130_CONST #endif namespace OgreBites { @@ -49,395 +49,395 @@ namespace OgreBites { class InputManagerWinRT { public: - enum EPointerAction - { - PointerPressed, - PointerReleased, - PointerMoved, - PointerWheelChanged, - }; + enum EPointerAction + { + PointerPressed, + PointerReleased, + PointerMoved, + PointerWheelChanged, + }; public: - InputManagerWinRT() - { + InputManagerWinRT() + { #if (OGRE_WINRT_TARGET_TYPE == PHONE) - m_tiltX = 0.0f; - m_tiltY = 0.0f; + m_tiltX = 0.0f; + m_tiltY = 0.0f; #endif - } - void Initialize() - { + } + void Initialize() + { #if (OGRE_WINRT_TARGET_TYPE == PHONE) - // Returns accelerometer ref if there is one; nullptr otherwise. - m_accelerometer = Windows::Devices::Sensors::Accelerometer::GetDefault(); + // Returns accelerometer ref if there is one; nullptr otherwise. + m_accelerometer = Windows::Devices::Sensors::Accelerometer::GetDefault(); #endif - } + } - void Update( Ogre::Real timeTotal, Ogre::Real timeDelta ) - { + void Update( Ogre::Real timeTotal, Ogre::Real timeDelta ) + { #if (OGRE_WINRT_TARGET_TYPE == PHONE) - const float UserInactivityDuration = 60.0f; // in seconds - const float UserInactivityThreshold = 0.01f; - m_tiltX = 0.0f; - m_tiltY = 0.0f; - // Account for touch input. - const float touchScalingFactor = 2.0f; - for (TouchMap::const_iterator iter = m_touches.cbegin(); iter != m_touches.cend(); ++iter) - { - m_tiltX += iter->second.x * touchScalingFactor; - m_tiltY += iter->second.y * touchScalingFactor; - } - - // Account for sensors. - const float acceleromterScalingFactor = 3.5f; - if (m_accelerometer != nullptr) - { - Windows::Devices::Sensors::AccelerometerReading^ reading = - m_accelerometer->GetCurrentReading(); - - if (reading != nullptr) - { - m_tiltX += static_cast(reading->AccelerationX) * acceleromterScalingFactor; - m_tiltY += static_cast(reading->AccelerationY) * acceleromterScalingFactor; - } - } - - Windows::System::VirtualKey vkey = Windows::System::VirtualKey::None; - Windows::UI::Core::CorePhysicalKeyStatus keystatus; - static bool bLeftActive = false; - static bool bRightActive = false; - static bool bForwardActive = false; - static bool bBackActive = false; - bool bTiltLeft = false; - bool bTiltRight = false; - bool bTiltForward = false; - bool bTiltBack = false; - - if (m_tiltX < -1) - { - bTiltLeft = true; - } - else if (m_tiltX > 1) - { - bTiltRight = true; - } - if (m_tiltY < -3) - { - bTiltBack = true; - } - else if (m_tiltY > -1.5 && m_tiltY < -0.5) - { - bTiltForward = true; - } - // Disable any key state the we tilted out of. - if (!bTiltLeft && bLeftActive) - { - keystatus.IsKeyReleased = true; - keystatus.WasKeyDown = false; - keystatus.ScanCode = OIS::KC_A; // Imitate the 'left key' being released. - OnKeyAction( vkey, keystatus, false); - bLeftActive = false; - } - // Enable any key state the we tilted in to. - else if (bTiltLeft && !bLeftActive) - { - keystatus.IsKeyReleased = false; - keystatus.WasKeyDown = true; - keystatus.ScanCode = OIS::KC_A; // Imitate the 'left key' being pressed. - OnKeyAction( vkey, keystatus, true); - bLeftActive = true; - } - - if (!bTiltRight && bRightActive) - { - keystatus.IsKeyReleased = true; - keystatus.WasKeyDown = false; - keystatus.ScanCode = OIS::KC_D; // Imitate the 'right key' being released. - OnKeyAction( vkey, keystatus, false); - bRightActive = false; - } - else if (bTiltRight && !bRightActive) - { - keystatus.IsKeyReleased = false; - keystatus.WasKeyDown = true; - keystatus.ScanCode = OIS::KC_D; // Imitate the 'right key' being pressed. - OnKeyAction( vkey, keystatus, true); - bRightActive = true; - } - if (!bTiltBack && bBackActive) - { - keystatus.IsKeyReleased = true; - keystatus.WasKeyDown = false; - keystatus.ScanCode = OIS::KC_S; // Imitate the 'back key' being released. - OnKeyAction( vkey, keystatus, false); - bBackActive = false; - } - else if (bTiltBack && !bBackActive) - { - keystatus.IsKeyReleased = false; - keystatus.WasKeyDown = true; - keystatus.ScanCode = OIS::KC_S; // Imitate the 'back key' being pressed. - OnKeyAction( vkey, keystatus, true); - bBackActive = true; - } - if (!bTiltForward && bForwardActive) - { - keystatus.IsKeyReleased = true; - keystatus.WasKeyDown = false; - keystatus.ScanCode = OIS::KC_W; // Imitate the 'forward key' being release. - OnKeyAction( vkey, keystatus, false); - bForwardActive = false; - } - else if (bTiltForward && !bForwardActive) - { - keystatus.IsKeyReleased = false; - keystatus.WasKeyDown = true; - keystatus.ScanCode = OIS::KC_W; // Imitate the 'forward key' being pressed. - OnKeyAction( vkey, keystatus, true); - bForwardActive = true; - } + const float UserInactivityDuration = 60.0f; // in seconds + const float UserInactivityThreshold = 0.01f; + m_tiltX = 0.0f; + m_tiltY = 0.0f; + // Account for touch input. + const float touchScalingFactor = 2.0f; + for (TouchMap::const_iterator iter = m_touches.cbegin(); iter != m_touches.cend(); ++iter) + { + m_tiltX += iter->second.x * touchScalingFactor; + m_tiltY += iter->second.y * touchScalingFactor; + } + + // Account for sensors. + const float acceleromterScalingFactor = 3.5f; + if (m_accelerometer != nullptr) + { + Windows::Devices::Sensors::AccelerometerReading^ reading = + m_accelerometer->GetCurrentReading(); + + if (reading != nullptr) + { + m_tiltX += static_cast(reading->AccelerationX) * acceleromterScalingFactor; + m_tiltY += static_cast(reading->AccelerationY) * acceleromterScalingFactor; + } + } + + Windows::System::VirtualKey vkey = Windows::System::VirtualKey::None; + Windows::UI::Core::CorePhysicalKeyStatus keystatus; + static bool bLeftActive = false; + static bool bRightActive = false; + static bool bForwardActive = false; + static bool bBackActive = false; + bool bTiltLeft = false; + bool bTiltRight = false; + bool bTiltForward = false; + bool bTiltBack = false; + + if (m_tiltX < -1) + { + bTiltLeft = true; + } + else if (m_tiltX > 1) + { + bTiltRight = true; + } + if (m_tiltY < -3) + { + bTiltBack = true; + } + else if (m_tiltY > -1.5 && m_tiltY < -0.5) + { + bTiltForward = true; + } + // Disable any key state the we tilted out of. + if (!bTiltLeft && bLeftActive) + { + keystatus.IsKeyReleased = true; + keystatus.WasKeyDown = false; + keystatus.ScanCode = OIS::KC_A; // Imitate the 'left key' being released. + OnKeyAction( vkey, keystatus, false); + bLeftActive = false; + } + // Enable any key state the we tilted in to. + else if (bTiltLeft && !bLeftActive) + { + keystatus.IsKeyReleased = false; + keystatus.WasKeyDown = true; + keystatus.ScanCode = OIS::KC_A; // Imitate the 'left key' being pressed. + OnKeyAction( vkey, keystatus, true); + bLeftActive = true; + } + + if (!bTiltRight && bRightActive) + { + keystatus.IsKeyReleased = true; + keystatus.WasKeyDown = false; + keystatus.ScanCode = OIS::KC_D; // Imitate the 'right key' being released. + OnKeyAction( vkey, keystatus, false); + bRightActive = false; + } + else if (bTiltRight && !bRightActive) + { + keystatus.IsKeyReleased = false; + keystatus.WasKeyDown = true; + keystatus.ScanCode = OIS::KC_D; // Imitate the 'right key' being pressed. + OnKeyAction( vkey, keystatus, true); + bRightActive = true; + } + if (!bTiltBack && bBackActive) + { + keystatus.IsKeyReleased = true; + keystatus.WasKeyDown = false; + keystatus.ScanCode = OIS::KC_S; // Imitate the 'back key' being released. + OnKeyAction( vkey, keystatus, false); + bBackActive = false; + } + else if (bTiltBack && !bBackActive) + { + keystatus.IsKeyReleased = false; + keystatus.WasKeyDown = true; + keystatus.ScanCode = OIS::KC_S; // Imitate the 'back key' being pressed. + OnKeyAction( vkey, keystatus, true); + bBackActive = true; + } + if (!bTiltForward && bForwardActive) + { + keystatus.IsKeyReleased = true; + keystatus.WasKeyDown = false; + keystatus.ScanCode = OIS::KC_W; // Imitate the 'forward key' being release. + OnKeyAction( vkey, keystatus, false); + bForwardActive = false; + } + else if (bTiltForward && !bForwardActive) + { + keystatus.IsKeyReleased = false; + keystatus.WasKeyDown = true; + keystatus.ScanCode = OIS::KC_W; // Imitate the 'forward key' being pressed. + OnKeyAction( vkey, keystatus, true); + bForwardActive = true; + } #endif - } + } - bool OnKeyAction(Windows::System::VirtualKey vkey, Windows::UI::Core::CorePhysicalKeyStatus keystatus, bool pressed) - { - return mOISKeyboard.OnKeyAction(vkey, keystatus, pressed); - } + bool OnKeyAction(Windows::System::VirtualKey vkey, Windows::UI::Core::CorePhysicalKeyStatus keystatus, bool pressed) + { + return mOISKeyboard.OnKeyAction(vkey, keystatus, pressed); + } - bool OnCharacterReceived(unsigned codepoint) - { - return mOISKeyboard.OnCharacterReceived(codepoint); - } + bool OnCharacterReceived(unsigned codepoint) + { + return mOISKeyboard.OnCharacterReceived(codepoint); + } - bool OnPointerAction(Windows::UI::Input::PointerPoint^ currentPoint, EPointerAction action) - { + bool OnPointerAction(Windows::UI::Input::PointerPoint^ currentPoint, EPointerAction action) + { #if (OGRE_WINRT_TARGET_TYPE == PHONE) - //TODO: convert to use onpointerpressed/moved - if (action == PointerPressed) - { - Windows::Foundation::Point pt = currentPoint->Position; - Windows::UI::Input::PointerPointProperties^ properties = currentPoint->Properties; - bool handled = false; - - // Convert from display independent pixels to resolution pixels. - // convert from dips to screen pixels - const OIS::MouseState& ms = mOISMouse.getMouseState(); - float deviceHeight = ms.height; - float deviceWidth = ms.width; - float scaleFactor = deviceWidth / 480.0f; - float dx = (scaleFactor * pt.X); - float dy = (scaleFactor * pt.Y); - - // fake some key presses for touch events at the top of the screen - // Handle touch events in the bottom of the screen as special special cases to emulate Key presses. - if (dy/deviceHeight < 0.1f) - { - Windows::System::VirtualKey vkey = Windows::System::VirtualKey::None; - Windows::UI::Core::CorePhysicalKeyStatus keystatus; - keystatus.IsKeyReleased = false; - keystatus.WasKeyDown = true; - if (dx/deviceWidth < 0.3f) - { - keystatus.ScanCode = OIS::KC_F; // Imitate the 'F' frame rate key being pressed. - return OnKeyAction( vkey, keystatus, true); - } - else if (dx/deviceWidth > 0.7f) - { - keystatus.ScanCode = OIS::KC_R; // Imitate the 'R' being pressed. - } - else - { - keystatus.ScanCode = OIS::KC_F3; // Imitate the 'F3' being pressed. - } - return OnKeyAction( vkey, keystatus, true); - } - } - return mOISMouse.OnPointerAction(currentPoint, action); + //TODO: convert to use onpointerpressed/moved + if (action == PointerPressed) + { + Windows::Foundation::Point pt = currentPoint->Position; + Windows::UI::Input::PointerPointProperties^ properties = currentPoint->Properties; + bool handled = false; + + // Convert from display independent pixels to resolution pixels. + // convert from dips to screen pixels + const OIS::MouseState& ms = mOISMouse.getMouseState(); + float deviceHeight = ms.height; + float deviceWidth = ms.width; + float scaleFactor = deviceWidth / 480.0f; + float dx = (scaleFactor * pt.X); + float dy = (scaleFactor * pt.Y); + + // fake some key presses for touch events at the top of the screen + // Handle touch events in the bottom of the screen as special special cases to emulate Key presses. + if (dy/deviceHeight < 0.1f) + { + Windows::System::VirtualKey vkey = Windows::System::VirtualKey::None; + Windows::UI::Core::CorePhysicalKeyStatus keystatus; + keystatus.IsKeyReleased = false; + keystatus.WasKeyDown = true; + if (dx/deviceWidth < 0.3f) + { + keystatus.ScanCode = OIS::KC_F; // Imitate the 'F' frame rate key being pressed. + return OnKeyAction( vkey, keystatus, true); + } + else if (dx/deviceWidth > 0.7f) + { + keystatus.ScanCode = OIS::KC_R; // Imitate the 'R' being pressed. + } + else + { + keystatus.ScanCode = OIS::KC_F3; // Imitate the 'F3' being pressed. + } + return OnKeyAction( vkey, keystatus, true); + } + } + return mOISMouse.OnPointerAction(currentPoint, action); #else - switch(currentPoint->PointerDevice->PointerDeviceType) - { - case Windows::Devices::Input::PointerDeviceType::Touch: if(currentPoint->Properties->IsPrimary) return mOISMouse.OnPointerAction(currentPoint, action); break; - case Windows::Devices::Input::PointerDeviceType::Pen: if(currentPoint->Properties->IsPrimary) return mOISMouse.OnPointerAction(currentPoint, action); break; - case Windows::Devices::Input::PointerDeviceType::Mouse: if(currentPoint->Properties->IsPrimary) return mOISMouse.OnPointerAction(currentPoint, action); break; - } + switch(currentPoint->PointerDevice->PointerDeviceType) + { + case Windows::Devices::Input::PointerDeviceType::Touch: if(currentPoint->Properties->IsPrimary) return mOISMouse.OnPointerAction(currentPoint, action); break; + case Windows::Devices::Input::PointerDeviceType::Pen: if(currentPoint->Properties->IsPrimary) return mOISMouse.OnPointerAction(currentPoint, action); break; + case Windows::Devices::Input::PointerDeviceType::Mouse: if(currentPoint->Properties->IsPrimary) return mOISMouse.OnPointerAction(currentPoint, action); break; + } #endif - return false; - } + return false; + } - InputContext GetInputContext() - { - InputContext ctx; - ctx.mMouse = &mOISMouse; - ctx.mKeyboard = &mOISKeyboard; - return ctx; - } + InputContext GetInputContext() + { + InputContext ctx; + ctx.mMouse = &mOISMouse; + ctx.mKeyboard = &mOISKeyboard; + return ctx; + } private: - class WinRTMouse - : public OIS::Mouse - { - public: - WinRTMouse() - : OIS::Mouse("", false, 0, nullptr) {} - - // stubs for abstract methods - void setBuffered(bool){}; - void capture(){}; - OIS::Interface* queryInterface(OIS::Interface::IType) {return NULL;}; - void _initialize(){}; - - bool OnPointerAction(Windows::UI::Input::PointerPoint^ currentPoint, EPointerAction action) - { - Windows::Foundation::Point pt = currentPoint->Position; - Windows::UI::Input::PointerPointProperties^ properties = currentPoint->Properties; - bool handled = false; - - // clear relative states - mState.X.rel = mState.Y.rel = mState.Z.rel = 0; - - // Convert from display independent pixels to resolution pixels. - // convert from dips to screen pixels + class WinRTMouse + : public OIS::Mouse + { + public: + WinRTMouse() + : OIS::Mouse("", false, 0, nullptr) {} + + // stubs for abstract methods + void setBuffered(bool){}; + void capture(){}; + OIS::Interface* queryInterface(OIS::Interface::IType) {return NULL;}; + void _initialize(){}; + + bool OnPointerAction(Windows::UI::Input::PointerPoint^ currentPoint, EPointerAction action) + { + Windows::Foundation::Point pt = currentPoint->Position; + Windows::UI::Input::PointerPointProperties^ properties = currentPoint->Properties; + bool handled = false; + + // clear relative states + mState.X.rel = mState.Y.rel = mState.Z.rel = 0; + + // Convert from display independent pixels to resolution pixels. + // convert from dips to screen pixels #if (OGRE_WINRT_TARGET_TYPE == PHONE) - float scaleFactor = mState.width / 480.0f; - int dx = (int)(scaleFactor * pt.X); - int dy = (int)(scaleFactor * pt.Y); + float scaleFactor = mState.width / 480.0f; + int dx = (int)(scaleFactor * pt.X); + int dy = (int)(scaleFactor * pt.Y); #else - int dx = (int)(pt.X); - int dy = (int)(pt.Y); + int dx = (int)(pt.X); + int dy = (int)(pt.Y); #endif - bool bMoved = mState.X.abs != dx && mState.Y.abs != dy; - mState.X.rel = dx - mState.X.abs; - mState.Y.rel = dy - mState.Y.abs; - mState.X.abs = dx; - mState.Y.abs = dy; - - // process wheel actions - switch(action) - { - case PointerWheelChanged: - if(!properties->IsHorizontalMouseWheel) - { - mState.Z.rel = properties->MouseWheelDelta; - if(mListener && mListener->mouseMoved(OIS::MouseEvent(this, mState))) - handled = true; - } - break; - - case PointerPressed: - case PointerReleased: - case PointerMoved: - { - int buttons = - (properties->IsLeftButtonPressed ? 1 << OIS::MB_Left : 0) | - (properties->IsRightButtonPressed ? 1 << OIS::MB_Right : 0) | - (properties->IsMiddleButtonPressed ? 1 << OIS::MB_Middle : 0); - - // set each new bit that was not set before - for(int buttonID = 0, bitmask = 1; (mState.buttons | buttons) != mState.buttons && bitmask != 0; ++buttonID, bitmask <<= 1) - { - if(bitmask & buttons & ~mState.buttons) - { - mState.buttons |= bitmask; - if(mListener && mListener->mousePressed(OIS::MouseEvent(this, mState), (OIS::MouseButtonID)buttonID)) - handled = true; - } - } - - // reset each old bit that is not set now - for(int buttonID = 0, bitmask = 1; (mState.buttons | buttons) != buttons && bitmask != 0; ++buttonID, bitmask <<= 1) - { - if(bitmask & ~buttons & mState.buttons) - { - mState.buttons &= ~bitmask; - if(mListener && mListener->mouseReleased(OIS::MouseEvent(this, mState), (OIS::MouseButtonID)buttonID)) - handled = true; - } - } - - // process pointer moved part - if(bMoved) - { - if(mListener && mListener->mouseMoved(OIS::MouseEvent(this, mState))) - handled = true; - } - } - break; - } - - return handled; - } - }; - - class WinRTKeyboard - : public OIS::Keyboard - { - public: - WinRTKeyboard() - : OIS::Keyboard("", false, 0, nullptr) { memset(KeyBuffer, 0, 256); } - - // stubs for abstract methods - void setBuffered(bool){}; - void capture(){}; - OIS::Interface* queryInterface(OIS::Interface::IType) {return NULL;}; - void _initialize(){}; - - bool isKeyDown(OIS::KeyCode key) OIS_130_CONST { return KeyBuffer[key] != 0; }; - const std::string& getAsString(OIS::KeyCode) { static std::string empty; return empty; }; - void copyKeyStates(char keys[256]) OIS_130_CONST { memcpy(keys, KeyBuffer, 256); }; - - bool OnKeyAction(Windows::System::VirtualKey vkey, Windows::UI::Core::CorePhysicalKeyStatus keystatus, bool pressed) - { - OIS::KeyCode kc = (OIS::KeyCode)keystatus.ScanCode; // OIS::KeyCode is really DirectInput and WM_KEYDOWN/UP scan code - - //Store result in our keyBuffer too - KeyBuffer[kc] = pressed; - - if(pressed) - { - //Turn on modifier - if( kc == OIS::KC_LCONTROL || kc == OIS::KC_RCONTROL ) - mModifiers |= Ctrl; - else if( kc == OIS::KC_LSHIFT || kc == OIS::KC_RSHIFT ) - mModifiers |= Shift; - else if( kc == OIS::KC_LMENU || kc == OIS::KC_RMENU ) - mModifiers |= Alt; - - return mListener && mListener->keyPressed(OIS::KeyEvent(this, kc, 0)); // note - we don`t pass character as it is not known yet - } - else - { - //Turn off modifier - if( kc == OIS::KC_LCONTROL || kc == OIS::KC_RCONTROL ) - mModifiers &= ~Ctrl; - else if( kc == OIS::KC_LSHIFT || kc == OIS::KC_RSHIFT ) - mModifiers &= ~Shift; - else if( kc == OIS::KC_LMENU || kc == OIS::KC_RMENU ) - mModifiers &= ~Alt; - - //Fire off event - return mListener && mListener->keyReleased(OIS::KeyEvent(this, kc, 0)); - } - } - - bool OnCharacterReceived(unsigned codepoint) - { - return mListener && mListener->keyPressed(OIS::KeyEvent(this, OIS::KC_UNASSIGNED, codepoint)); // here we pass already known char, but not pass keycode - } - - private: - unsigned char KeyBuffer[256]; - }; + bool bMoved = mState.X.abs != dx && mState.Y.abs != dy; + mState.X.rel = dx - mState.X.abs; + mState.Y.rel = dy - mState.Y.abs; + mState.X.abs = dx; + mState.Y.abs = dy; + + // process wheel actions + switch(action) + { + case PointerWheelChanged: + if(!properties->IsHorizontalMouseWheel) + { + mState.Z.rel = properties->MouseWheelDelta; + if(mListener && mListener->mouseMoved(OIS::MouseEvent(this, mState))) + handled = true; + } + break; + + case PointerPressed: + case PointerReleased: + case PointerMoved: + { + int buttons = + (properties->IsLeftButtonPressed ? 1 << OIS::MB_Left : 0) | + (properties->IsRightButtonPressed ? 1 << OIS::MB_Right : 0) | + (properties->IsMiddleButtonPressed ? 1 << OIS::MB_Middle : 0); + + // set each new bit that was not set before + for(int buttonID = 0, bitmask = 1; (mState.buttons | buttons) != mState.buttons && bitmask != 0; ++buttonID, bitmask <<= 1) + { + if(bitmask & buttons & ~mState.buttons) + { + mState.buttons |= bitmask; + if(mListener && mListener->mousePressed(OIS::MouseEvent(this, mState), (OIS::MouseButtonID)buttonID)) + handled = true; + } + } + + // reset each old bit that is not set now + for(int buttonID = 0, bitmask = 1; (mState.buttons | buttons) != buttons && bitmask != 0; ++buttonID, bitmask <<= 1) + { + if(bitmask & ~buttons & mState.buttons) + { + mState.buttons &= ~bitmask; + if(mListener && mListener->mouseReleased(OIS::MouseEvent(this, mState), (OIS::MouseButtonID)buttonID)) + handled = true; + } + } + + // process pointer moved part + if(bMoved) + { + if(mListener && mListener->mouseMoved(OIS::MouseEvent(this, mState))) + handled = true; + } + } + break; + } + + return handled; + } + }; + + class WinRTKeyboard + : public OIS::Keyboard + { + public: + WinRTKeyboard() + : OIS::Keyboard("", false, 0, nullptr) { memset(KeyBuffer, 0, 256); } + + // stubs for abstract methods + void setBuffered(bool){}; + void capture(){}; + OIS::Interface* queryInterface(OIS::Interface::IType) {return NULL;}; + void _initialize(){}; + + bool isKeyDown(OIS::KeyCode key) OIS_130_CONST { return KeyBuffer[key] != 0; }; + const std::string& getAsString(OIS::KeyCode) { static std::string empty; return empty; }; + void copyKeyStates(char keys[256]) OIS_130_CONST { memcpy(keys, KeyBuffer, 256); }; + + bool OnKeyAction(Windows::System::VirtualKey vkey, Windows::UI::Core::CorePhysicalKeyStatus keystatus, bool pressed) + { + OIS::KeyCode kc = (OIS::KeyCode)keystatus.ScanCode; // OIS::KeyCode is really DirectInput and WM_KEYDOWN/UP scan code + + //Store result in our keyBuffer too + KeyBuffer[kc] = pressed; + + if(pressed) + { + //Turn on modifier + if( kc == OIS::KC_LCONTROL || kc == OIS::KC_RCONTROL ) + mModifiers |= Ctrl; + else if( kc == OIS::KC_LSHIFT || kc == OIS::KC_RSHIFT ) + mModifiers |= Shift; + else if( kc == OIS::KC_LMENU || kc == OIS::KC_RMENU ) + mModifiers |= Alt; + + return mListener && mListener->keyPressed(OIS::KeyEvent(this, kc, 0)); // note - we don`t pass character as it is not known yet + } + else + { + //Turn off modifier + if( kc == OIS::KC_LCONTROL || kc == OIS::KC_RCONTROL ) + mModifiers &= ~Ctrl; + else if( kc == OIS::KC_LSHIFT || kc == OIS::KC_RSHIFT ) + mModifiers &= ~Shift; + else if( kc == OIS::KC_LMENU || kc == OIS::KC_RMENU ) + mModifiers &= ~Alt; + + //Fire off event + return mListener && mListener->keyReleased(OIS::KeyEvent(this, kc, 0)); + } + } + + bool OnCharacterReceived(unsigned codepoint) + { + return mListener && mListener->keyPressed(OIS::KeyEvent(this, OIS::KC_UNASSIGNED, codepoint)); // here we pass already known char, but not pass keycode + } + + private: + unsigned char KeyBuffer[256]; + }; private: - WinRTMouse mOISMouse; - WinRTKeyboard mOISKeyboard; - + WinRTMouse mOISMouse; + WinRTKeyboard mOISKeyboard; + #if (OGRE_WINRT_TARGET_TYPE == PHONE) - typedef std::map TouchMap; - TouchMap m_touches; - Windows::Devices::Sensors::Accelerometer^ m_accelerometer; - float m_tiltX; - float m_tiltY; + typedef std::map TouchMap; + TouchMap m_touches; + Windows::Devices::Sensors::Accelerometer^ m_accelerometer; + float m_tiltX; + float m_tiltY; #endif }; diff --git a/Samples/Browser/include/SampleBrowser.h b/Samples/Browser/include/SampleBrowser.h index f60dc4a1f65..82846f430fe 100644 --- a/Samples/Browser/include/SampleBrowser.h +++ b/Samples/Browser/include/SampleBrowser.h @@ -58,17 +58,17 @@ # ifdef INCLUDE_RTSHADER_SYSTEM # include "ShaderSystem.h" # endif -# include "DualQuaternion.h" +# include "DualQuaternion.h" # include "DeferredShadingDemo.h" # include "Instancing.h" # include "NewInstancing.h" # include "TextureArray.h" # include "SSAO.h" # include "OceanDemo.h" -# ifdef OGRE_BUILD_COMPONENT_VOLUME -# include "VolumeCSG.h" -# include "VolumeTerrain.h" -# endif +# ifdef OGRE_BUILD_COMPONENT_VOLUME +# include "VolumeCSG.h" +# include "VolumeTerrain.h" +# endif # ifdef OGRE_BUILD_COMPONENT_TERRAIN # include "EndlessWorld.h" # include "Terrain.h" @@ -86,8 +86,8 @@ # include "DynTex.h" # include "FacialAnimation.h" # include "Grass.h" -# include "Hair.h" -# include "Island.h" +# include "Hair.h" +# include "Island.h" # include "Lighting.h" # include "MeshLod.h" # include "ParticleFX.h" @@ -99,14 +99,14 @@ # include "SkyPlane.h" # include "Smoke.h" # include "SphereMapping.h" -# include "Tessellation.h" -# include "TerrainTessellation.h" +# include "Tessellation.h" +# include "TerrainTessellation.h" # include "TextureFX.h" # include "Transparency.h" # if SAMPLES_INCLUDE_PLAYPEN # include "PlayPen.h" # include "PlayPenTestPlugin.h" - PlayPenPlugin* playPenPlugin = 0; + PlayPenPlugin* playPenPlugin = 0; PlaypenTestPlugin* playPenTestPlugin = 0; # endif # ifdef INCLUDE_RTSHADER_SYSTEM @@ -639,7 +639,7 @@ namespace OgreBites bool all = selectedCategory == "All"; Ogre::StringVector sampleTitles; - Ogre::MaterialPtr templateMat = Ogre::MaterialManager::getSingleton().getByName("SdkTrays/SampleThumbnail"); + Ogre::MaterialPtr templateMat = Ogre::MaterialManager::getSingleton().getByName("SdkTrays/SampleThumbnail"); // populate the sample menu and carousel with filtered samples for (SampleSet::iterator i = mLoadedSamples.begin(); i != mLoadedSamples.end(); i++) @@ -679,7 +679,7 @@ namespace OgreBites mSampleMenu->setItems(sampleTitles); if (mSampleMenu->getNumItems() != 0) itemSelected(mSampleMenu); - mSampleSlider->setRange(1, static_cast(sampleTitles.size()), static_cast(sampleTitles.size())); + mSampleSlider->setRange(1, static_cast(sampleTitles.size()), static_cast(sampleTitles.size())); } else if (menu == mSampleMenu) // sample changed, so update slider, label and description { @@ -715,10 +715,10 @@ namespace OgreBites // if the current config value is not in the menu, add it if(optionMenu->containsItem(it->second.currentValue) == false) { - optionMenu->addItem(it->second.currentValue); + optionMenu->addItem(it->second.currentValue); } - optionMenu->selectItem(it->second.currentValue); + optionMenu->selectItem(it->second.currentValue); } windowResized(mWindow); @@ -1087,16 +1087,16 @@ namespace OgreBites mPluginNameMap["Sample_DynTex"] = (OgreBites::SdkSample *) OGRE_NEW Sample_DynTex(); mPluginNameMap["Sample_FacialAnimation"] = (OgreBites::SdkSample *) OGRE_NEW Sample_FacialAnimation(); mPluginNameMap["Sample_Grass"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Grass(); - + mPluginNameMap["Sample_DualQuaternion"] = (OgreBites::SdkSample *) OGRE_NEW Sample_DualQuaternion(); mPluginNameMap["Sample_Instancing"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Instancing(); mPluginNameMap["Sample_NewInstancing"] = (OgreBites::SdkSample *) OGRE_NEW Sample_NewInstancing(); mPluginNameMap["Sample_TextureArray"] = (OgreBites::SdkSample *) OGRE_NEW Sample_TextureArray(); - mPluginNameMap["Sample_Tessellation"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Tessellation(); + mPluginNameMap["Sample_Tessellation"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Tessellation(); mPluginNameMap["Sample_PNTriangles"] = (OgreBites::SdkSample *) OGRE_NEW Sample_PNTriangles(); - mPluginNameMap["Sample_Hair"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Hair(); - mPluginNameMap["Sample_Island"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Island(); - mPluginNameMap["Sample_TerrainTessellation"]= (OgreBites::SdkSample *) OGRE_NEW Sample_TerrainTessellation(); + mPluginNameMap["Sample_Hair"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Hair(); + mPluginNameMap["Sample_Island"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Island(); + mPluginNameMap["Sample_TerrainTessellation"]= (OgreBites::SdkSample *) OGRE_NEW Sample_TerrainTessellation(); # if defined(OGRE_BUILD_COMPONENT_VOLUME) && OGRE_PLATFORM != OGRE_PLATFORM_NACL mPluginNameMap["Sample_VolumeCSG"] = (OgreBites::SdkSample *) OGRE_NEW Sample_VolumeCSG(); mPluginNameMap["Sample_VolumeTerrain"] = (OgreBites::SdkSample *) OGRE_NEW Sample_VolumeTerrain(); @@ -1112,7 +1112,7 @@ namespace OgreBites mPluginNameMap["Sample_SkyDome"] = (OgreBites::SdkSample *) OGRE_NEW Sample_SkyDome(); mPluginNameMap["Sample_SkyPlane"] = (OgreBites::SdkSample *) OGRE_NEW Sample_SkyPlane(); mPluginNameMap["Sample_SphereMapping"] = (OgreBites::SdkSample *) OGRE_NEW Sample_SphereMapping(); - mPluginNameMap["Sample_Tessellation"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Tessellation(); + mPluginNameMap["Sample_Tessellation"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Tessellation(); mPluginNameMap["Sample_TextureFX"] = (OgreBites::SdkSample *) OGRE_NEW Sample_TextureFX(); mPluginNameMap["Sample_Transparency"] = (OgreBites::SdkSample *) OGRE_NEW Sample_Transparency(); @@ -1150,7 +1150,7 @@ namespace OgreBites if(Ogre::GpuProgramManager::getSingleton().canGetCompiledShaderBuffer()) Ogre::GpuProgramManager::getSingleton().setSaveMicrocodesToCache(true); #endif -#if ENABLE_SHADERS_CACHE_LOAD == 1 +#if ENABLE_SHADERS_CACHE_LOAD == 1 // Load for a package version of the shaders. Ogre::String path = getShaderCacheFileName(); FILE * inFile = NULL; @@ -1191,7 +1191,7 @@ namespace OgreBites Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this); // create template material for sample thumbnails - Ogre::MaterialPtr thumbMat = Ogre::MaterialManager::getSingleton().create("SdkTrays/SampleThumbnail", "Essential"); + Ogre::MaterialPtr thumbMat = Ogre::MaterialManager::getSingleton().create("SdkTrays/SampleThumbnail", "Essential"); thumbMat->getTechnique(0)->getPass(0)->createTextureUnitState(); setupWidgets(); @@ -1313,7 +1313,7 @@ namespace OgreBites #ifdef INCLUDE_RTSHADER_SYSTEM // Initialize shader generator. // Must be before resource loading in order to allow parsing extended material attributes. - bool success = initialiseRTShaderSystem(sm); + bool success = initialiseRTShaderSystem(sm); if (!success) { OGRE_EXCEPT(Ogre::Exception::ERR_FILE_NOT_FOUND, @@ -1325,7 +1325,7 @@ namespace OgreBites //newViewport->setMaterialScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); // creates shaders for base material BaseWhite using the RTSS - Ogre::MaterialPtr baseWhite = Ogre::MaterialManager::getSingleton().getByName("BaseWhite", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + Ogre::MaterialPtr baseWhite = Ogre::MaterialManager::getSingleton().getByName("BaseWhite", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); baseWhite->setLightingEnabled(false); mShaderGenerator->createShaderBasedTechnique( "BaseWhite", @@ -1348,7 +1348,7 @@ namespace OgreBites Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); mShaderGenerator->validateMaterial(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, "BaseWhiteNoLighting"); - Ogre::MaterialPtr baseWhiteNoLighting = Ogre::MaterialManager::getSingleton().getByName("BaseWhiteNoLighting", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + Ogre::MaterialPtr baseWhiteNoLighting = Ogre::MaterialManager::getSingleton().getByName("BaseWhiteNoLighting", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); if(baseWhite->getNumTechniques() > 1) { baseWhiteNoLighting->getTechnique(0)->getPass(0)->setVertexProgram( @@ -1395,10 +1395,10 @@ namespace OgreBites sampleList.push_back("Sample_Smoke"); sampleList.push_back("Sample_Water"); sampleList.push_back("Sample_PNTriangles"); - sampleList.push_back("Sample_Tessellation"); - sampleList.push_back("Sample_Hair"); - sampleList.push_back("Sample_Island"); - sampleList.push_back("Sample_TerrainTessellation"); + sampleList.push_back("Sample_Tessellation"); + sampleList.push_back("Sample_Hair"); + sampleList.push_back("Sample_Island"); + sampleList.push_back("Sample_TerrainTessellation"); sampleList.push_back("Sample_Transparency"); sampleList.push_back("Sample_TextureFX"); #else @@ -1782,8 +1782,8 @@ namespace OgreBites unloadSamples(); #ifdef INCLUDE_RTSHADER_SYSTEM - // Destroy the RT Shader System. - destroyRTShaderSystem(); + // Destroy the RT Shader System. + destroyRTShaderSystem(); #endif // INCLUDE_RTSHADER_SYSTEM } @@ -1827,7 +1827,7 @@ namespace OgreBites } /*----------------------------------------------------------------------------- - | Extend to unhide all of sample's temporarily hidden overlays. + | Extend to unhide all of sample's temporarily hidden overlays. -----------------------------------------------------------------------------*/ virtual void unpauseCurrentSample() { @@ -1842,7 +1842,7 @@ namespace OgreBites } /*----------------------------------------------------------------------------- - | Get the name of the RTSS shader cache file + | Get the name of the RTSS shader cache file -----------------------------------------------------------------------------*/ virtual Ogre::String getShaderCacheFileName() { @@ -1858,7 +1858,7 @@ namespace OgreBites /*----------------------------------------------------------------------------- | Initialize the RT Shader system. -----------------------------------------------------------------------------*/ - virtual bool initialiseRTShaderSystem(Ogre::SceneManager* sceneMgr) + virtual bool initialiseRTShaderSystem(Ogre::SceneManager* sceneMgr) { if (Ogre::RTShader::ShaderGenerator::initialize()) { @@ -1924,9 +1924,9 @@ namespace OgreBites } /*----------------------------------------------------------------------------- - | Destroy the RT Shader system. + | Destroy the RT Shader system. -----------------------------------------------------------------------------*/ - virtual void destroyRTShaderSystem() + virtual void destroyRTShaderSystem() { // Restore default scheme. Ogre::MaterialManager::getSingleton().setActiveScheme(Ogre::MaterialManager::DEFAULT_SCHEME_NAME); @@ -1939,10 +1939,10 @@ namespace OgreBites mMaterialMgrListener = NULL; } - // Destroy RTShader system. + // Destroy RTShader system. if (mShaderGenerator != NULL) { - Ogre::RTShader::ShaderGenerator::destroy(); + Ogre::RTShader::ShaderGenerator::destroy(); mShaderGenerator = NULL; } } diff --git a/Samples/Browser/include/SampleBrowser_Android.h b/Samples/Browser/include/SampleBrowser_Android.h index bd8a0e44384..93fa4e70295 100644 --- a/Samples/Browser/include/SampleBrowser_Android.h +++ b/Samples/Browser/include/SampleBrowser_Android.h @@ -263,7 +263,7 @@ namespace OgreBites mInputInjector = NULL; #ifdef OGRE_STATIC_LIB - mStaticPluginLoader->unload(); + mStaticPluginLoader->unload(); delete mStaticPluginLoader; mStaticPluginLoader = NULL; #endif diff --git a/Samples/Browser/include/SampleBrowser_NaCl.h b/Samples/Browser/include/SampleBrowser_NaCl.h index c742a40e63a..509b904b3ef 100644 --- a/Samples/Browser/include/SampleBrowser_NaCl.h +++ b/Samples/Browser/include/SampleBrowser_NaCl.h @@ -633,11 +633,11 @@ namespace Ogre { void initOgre(uint32 width, uint32 height) { - /* Initialize SDL */ - /*if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { - fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); - return(1); - }*/ + /* Initialize SDL */ + /*if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); + return(1); + }*/ try @@ -754,9 +754,9 @@ namespace Ogre { const pp::WheelInputEvent * wheelEvent = reinterpret_cast(&event); - mState.Z.rel = wheelEvent->GetDelta().y(); - if( mListener ) - mListener->mouseMoved( OIS::MouseEvent( this, mState ) ); + mState.Z.rel = wheelEvent->GetDelta().y(); + if( mListener ) + mListener->mouseMoved( OIS::MouseEvent( this, mState ) ); return false; } @@ -787,8 +787,8 @@ namespace Ogre { case PP_INPUTEVENT_TYPE_MOUSEDOWN: if (button != OIS::MB_Button3) { - mState.X.rel = 0; - mState.Y.rel = 0; + mState.X.rel = 0; + mState.Y.rel = 0; mState.buttons |= 1 << button; if( mListener ) return mListener->mousePressed( OIS::MouseEvent( this, mState ), button ); @@ -797,8 +797,8 @@ namespace Ogre { case PP_INPUTEVENT_TYPE_MOUSEUP: if (button != -1) { - mState.X.rel = 0; - mState.Y.rel = 0; + mState.X.rel = 0; + mState.Y.rel = 0; mState.buttons &= ~(1 << button); if( mListener ) return mListener->mouseReleased( OIS::MouseEvent( this, mState ), button ); @@ -807,12 +807,12 @@ namespace Ogre { case PP_INPUTEVENT_TYPE_MOUSEMOVE: if(mState.X.abs != point.x() && mState.Y.abs != point.y()) { - mState.X.rel = point.x() - mState.X.abs; - mState.Y.rel = point.y() - mState.Y.abs; - mState.X.abs = point.x(); - mState.Y.abs = point.y(); - if( mListener ) - mListener->mouseMoved( OIS::MouseEvent( this, mState ) ); + mState.X.rel = point.x() - mState.X.abs; + mState.Y.rel = point.y() - mState.Y.abs; + mState.X.abs = point.x(); + mState.Y.abs = point.y(); + if( mListener ) + mListener->mouseMoved( OIS::MouseEvent( this, mState ) ); } break; case PP_INPUTEVENT_TYPE_MOUSEENTER: @@ -900,17 +900,17 @@ namespace Ogre { /** @copydoc FactoryCreator::createObject */ OIS::Object* createObject(OIS::InputManager* creator, OIS::Type iType, bool bufferMode, const std::string & vendor = "") { - switch( iType ) - { - case OIS::OISKeyboard: + switch( iType ) + { + case OIS::OISKeyboard: return &mOISKeyboard; break; - case OIS::OISMouse: + case OIS::OISMouse: return &mOISMouse; break; - case OIS::OISJoyStick: - default: return NULL; - } + case OIS::OISJoyStick: + default: return NULL; + } } /** @copydoc FactoryCreator::destroyObject */ diff --git a/Samples/Browser/include/SampleBrowser_OSX.h b/Samples/Browser/include/SampleBrowser_OSX.h index 81795680452..228b697ca6c 100644 --- a/Samples/Browser/include/SampleBrowser_OSX.h +++ b/Samples/Browser/include/SampleBrowser_OSX.h @@ -154,7 +154,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets(); // Clear event times - Ogre::Root::getSingleton().clearEventTimes(); + Ogre::Root::getSingleton().clearEventTimes(); } catch( Ogre::Exception& e ) { std::cerr << "An exception has occurred: " << e.getFullDescription().c_str() << std::endl; @@ -177,9 +177,9 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime // Activate the display link ret = CVDisplayLinkStart(mDisplayLink); #else - mTimer = [[NSTimer timerWithTimeInterval: 0.001 target:self selector:@selector(renderOneFrame:) userInfo:self repeats:true] retain]; - [[NSRunLoop currentRunLoop] addTimer:mTimer forMode: NSDefaultRunLoopMode]; - [[NSRunLoop currentRunLoop] addTimer:mTimer forMode: NSEventTrackingRunLoopMode]; // Ensure timer fires during resize + mTimer = [[NSTimer timerWithTimeInterval: 0.001 target:self selector:@selector(renderOneFrame:) userInfo:self repeats:true] retain]; + [[NSRunLoop currentRunLoop] addTimer:mTimer forMode: NSDefaultRunLoopMode]; + [[NSRunLoop currentRunLoop] addTimer:mTimer forMode: NSEventTrackingRunLoopMode]; // Ensure timer fires during resize #endif [pool release]; } diff --git a/Samples/Browser/include/SampleBrowser_iOS.h b/Samples/Browser/include/SampleBrowser_iOS.h index 4906cfad2e5..9e92055c672 100644 --- a/Samples/Browser/include/SampleBrowser_iOS.h +++ b/Samples/Browser/include/SampleBrowser_iOS.h @@ -94,7 +94,7 @@ Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets(); // Clear event times - Ogre::Root::getSingleton().clearEventTimes(); + Ogre::Root::getSingleton().clearEventTimes(); } catch( Ogre::Exception& e ) { std::cerr << "An exception has occurred: " << e.getFullDescription().c_str() << std::endl; diff --git a/Samples/Browser/src/SampleBrowser.cpp b/Samples/Browser/src/SampleBrowser.cpp index 97afae35e00..9e781791af6 100644 --- a/Samples/Browser/src/SampleBrowser.cpp +++ b/Samples/Browser/src/SampleBrowser.cpp @@ -74,20 +74,20 @@ void android_main(struct android_app* state) { int main(int argc, char *argv[]) { #endif #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - int retVal = UIApplicationMain(argc, argv, @"UIApplication", @"AppDelegate"); - [pool release]; - return retVal; + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, @"UIApplication", @"AppDelegate"); + [pool release]; + return retVal; #elif (OGRE_PLATFORM == OGRE_PLATFORM_APPLE) && __LP64__ - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; mAppDelegate = [[AppDelegate alloc] init]; [[NSApplication sharedApplication] setDelegate:mAppDelegate]; - int retVal = NSApplicationMain(argc, (const char **) argv); + int retVal = NSApplicationMain(argc, (const char **) argv); - [pool release]; + [pool release]; - return retVal; + return retVal; #elif OGRE_PLATFORM == OGRE_PLATFORM_ANDROID // Make sure glue isn't stripped. app_dummy(); @@ -96,8 +96,8 @@ int main(int argc, char *argv[]) { OgreAndroidBridge::go(state); #else - try - { + try + { bool nograb = false; if (argc >= 2 && Ogre::String(argv[1]) == "nograb") nograb = true; @@ -113,18 +113,18 @@ int main(int argc, char *argv[]) { // get -1, which is fine. startUpSampleIdx = Ogre::StringConverter::parseInt(Ogre::String(argv[1]), -1); } - OgreBites::SampleBrowser brows (nograb, startUpSampleIdx); - brows.go(); - } - catch (Ogre::Exception& e) - { + OgreBites::SampleBrowser brows (nograb, startUpSampleIdx); + brows.go(); + } + catch (Ogre::Exception& e) + { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - MessageBoxA(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_ICONERROR | MB_TASKMODAL); + MessageBoxA(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_ICONERROR | MB_TASKMODAL); #else - std::cerr << "An exception has occurred: " << e.getFullDescription().c_str() << std::endl; + std::cerr << "An exception has occurred: " << e.getFullDescription().c_str() << std::endl; #endif - } - return 0; + } + return 0; #endif } diff --git a/Samples/CameraTrack/include/CameraTrack.h b/Samples/CameraTrack/include/CameraTrack.h index 25b92940667..b8d40b804d0 100644 --- a/Samples/CameraTrack/include/CameraTrack.h +++ b/Samples/CameraTrack/include/CameraTrack.h @@ -10,48 +10,48 @@ class _OgreSampleClassExport Sample_CameraTrack : public SdkSample { public: - Sample_CameraTrack() - { - mInfo["Title"] = "Camera Tracking"; - mInfo["Description"] = "An example of using AnimationTracks to make a node smoothly follow " - "a predefined path with spline interpolation. Also uses the auto-tracking feature of the camera."; - mInfo["Thumbnail"] = "thumb_camtrack.png"; - mInfo["Category"] = "Unsorted"; - } + Sample_CameraTrack() + { + mInfo["Title"] = "Camera Tracking"; + mInfo["Description"] = "An example of using AnimationTracks to make a node smoothly follow " + "a predefined path with spline interpolation. Also uses the auto-tracking feature of the camera."; + mInfo["Thumbnail"] = "thumb_camtrack.png"; + mInfo["Category"] = "Unsorted"; + } bool frameRenderingQueued(const FrameEvent& evt) { mAnimState->addTime(evt.timeSinceLastFrame); // increment animation time - return SdkSample::frameRenderingQueued(evt); + return SdkSample::frameRenderingQueued(evt); } protected: - void setupContent() - { - // setup some basic lighting for our scene + void setupContent() + { + // setup some basic lighting for our scene mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); mSceneMgr->createLight()->setPosition(20, 80, 50); - mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox"); + mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox"); - // create an ogre head entity and attach it to a node - Entity* head = mSceneMgr->createEntity("Head", "ogrehead.mesh"); + // create an ogre head entity and attach it to a node + Entity* head = mSceneMgr->createEntity("Head", "ogrehead.mesh"); SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - headNode->attachObject(head); + headNode->attachObject(head); - mCameraMan->setStyle(CS_MANUAL); // we will be controlling the camera ourselves, so disable the camera man + mCameraMan->setStyle(CS_MANUAL); // we will be controlling the camera ourselves, so disable the camera man mCamera->setAutoTracking(true, headNode); // make the camera face the head // create a camera node and attach camera to it SceneNode* camNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); camNode->attachObject(mCamera); - - // set up a 10 second animation for our camera, using spline interpolation for nice curves + + // set up a 10 second animation for our camera, using spline interpolation for nice curves Animation* anim = mSceneMgr->createAnimation("CameraTrack", 10); anim->setInterpolationMode(Animation::IM_SPLINE); - // create a track to animate the camera's node + // create a track to animate the camera's node NodeAnimationTrack* track = anim->createNodeTrack(0, camNode); // create keyframes for our track @@ -64,9 +64,9 @@ class _OgreSampleClassExport Sample_CameraTrack : public SdkSample // create a new animation state to track this mAnimState = mSceneMgr->createAnimationState("CameraTrack"); mAnimState->setEnabled(true); - } + } - AnimationState* mAnimState; + AnimationState* mAnimState; }; #endif diff --git a/Samples/CameraTrack/src/CameraTrack.cpp b/Samples/CameraTrack/src/CameraTrack.cpp index f6968527791..76c678ba5e2 100644 --- a/Samples/CameraTrack/src/CameraTrack.cpp +++ b/Samples/CameraTrack/src/CameraTrack.cpp @@ -12,17 +12,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_CameraTrack; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_CameraTrack; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/CelShading/include/CelShading.h b/Samples/CelShading/include/CelShading.h index a47c48d3be4..64b87c3ddbc 100644 --- a/Samples/CelShading/include/CelShading.h +++ b/Samples/CelShading/include/CelShading.h @@ -10,64 +10,64 @@ class _OgreSampleClassExport Sample_CelShading : public SdkSample { public: - Sample_CelShading() - { - mInfo["Title"] = "Cel-shading"; - mInfo["Description"] = "A demo of cel-shaded graphics using vertex & fragment programs."; - mInfo["Thumbnail"] = "thumb_cel.png"; - mInfo["Category"] = "Lighting"; - } - - StringVector getRequiredPlugins() - { - StringVector names; + Sample_CelShading() + { + mInfo["Title"] = "Cel-shading"; + mInfo["Description"] = "A demo of cel-shaded graphics using vertex & fragment programs."; + mInfo["Thumbnail"] = "thumb_cel.png"; + mInfo["Category"] = "Lighting"; + } + + StringVector getRequiredPlugins() + { + StringVector names; if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl150")) names.push_back("Cg Program Manager"); - return names; - } + return names; + } - void testCapabilities(const RenderSystemCapabilities* caps) - { - if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) + void testCapabilities(const RenderSystemCapabilities* caps) + { + if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" - " programs, so you cannot run this sample. Sorry!", "Sample_CelShading::testCapabilities"); + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" + " programs, so you cannot run this sample. Sorry!", "Sample_CelShading::testCapabilities"); } - } + } - bool frameRenderingQueued(const FrameEvent& evt) - { - // make the light revolve around our model if and only if the check box is checked - if (mMoveLight->isChecked()) mLightPivot->yaw(Degree(evt.timeSinceLastFrame * 30)); + bool frameRenderingQueued(const FrameEvent& evt) + { + // make the light revolve around our model if and only if the check box is checked + if (mMoveLight->isChecked()) mLightPivot->yaw(Degree(evt.timeSinceLastFrame * 30)); - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! - } + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + } protected: - void setupContent() - { - mViewport->setBackgroundColour(ColourValue::White); + void setupContent() + { + mViewport->setBackgroundColour(ColourValue::White); - // set our camera to orbit around the origin and show cursor - mCameraMan->setStyle(CS_ORBIT); - mTrayMgr->showCursor(); + // set our camera to orbit around the origin and show cursor + mCameraMan->setStyle(CS_ORBIT); + mTrayMgr->showCursor(); - // create a basic point light with an offset - Light* light = mSceneMgr->createLight(); - light->setPosition(20, 40, 50); + // create a basic point light with an offset + Light* light = mSceneMgr->createLight(); + light->setPosition(20, 40, 50); - // attach the light to a pivot node - mLightPivot = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mLightPivot->attachObject(light); + // attach the light to a pivot node + mLightPivot = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mLightPivot->attachObject(light); - // create our model, give it the shader material, and place it at the origin + // create our model, give it the shader material, and place it at the origin Entity *ent = mSceneMgr->createEntity("Head", "ogrehead.mesh"); - ent->setMaterialName("Examples/CelShading"); - mSceneMgr->getRootSceneNode()->attachObject(ent); + ent->setMaterialName("Examples/CelShading"); + mSceneMgr->getRootSceneNode()->attachObject(ent); /* We set the same material for all parts of the head, but use custom shader parameters to set the - colours for each part. See Examples-Advanced.material for how these are bound to GPU parameters. */ + colours for each part. See Examples-Advanced.material for how these are bound to GPU parameters. */ SubEntity* sub; @@ -91,16 +91,16 @@ class _OgreSampleClassExport Sample_CelShading : public SdkSample sub->setCustomParameter(SP_DIFFUSE, Vector4(1, 1, 0.7, 1)); sub->setCustomParameter(SP_SPECULAR, Vector4(1, 1, 1, 1)); - // create a check box to toggle light movement - mMoveLight = mTrayMgr->createCheckBox(TL_TOPLEFT, "MoveLight", "Move Light"); - mMoveLight->setChecked(true); - } + // create a check box to toggle light movement + mMoveLight = mTrayMgr->createCheckBox(TL_TOPLEFT, "MoveLight", "Move Light"); + mMoveLight->setChecked(true); + } - // custom shader parameter bindings - enum ShaderParam { SP_SHININESS = 1, SP_DIFFUSE, SP_SPECULAR }; + // custom shader parameter bindings + enum ShaderParam { SP_SHININESS = 1, SP_DIFFUSE, SP_SPECULAR }; - SceneNode* mLightPivot; - CheckBox* mMoveLight; + SceneNode* mLightPivot; + CheckBox* mMoveLight; }; #endif diff --git a/Samples/CelShading/src/CelShading.cpp b/Samples/CelShading/src/CelShading.cpp index 071a477911b..1704620c656 100644 --- a/Samples/CelShading/src/CelShading.cpp +++ b/Samples/CelShading/src/CelShading.cpp @@ -12,17 +12,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_CelShading; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_CelShading; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Character/include/CharacterSample.h b/Samples/Character/include/CharacterSample.h index e55b413aa8b..1b7246c792b 100644 --- a/Samples/Character/include/CharacterSample.h +++ b/Samples/Character/include/CharacterSample.h @@ -11,134 +11,134 @@ class _OgreSampleClassExport Sample_Character : public SdkSample { public: - Sample_Character() - { - mInfo["Title"] = "Character"; - mInfo["Description"] = "A demo showing 3rd-person character control and use of TagPoints."; - mInfo["Thumbnail"] = "thumb_char.png"; - mInfo["Category"] = "Animation"; - mInfo["Help"] = "Use the WASD keys to move Sinbad, and the space bar to jump. " - "Use mouse to look around and mouse wheel to zoom. Press Q to take out or put back " - "Sinbad's swords. With the swords equipped, you can left click to slice vertically or " - "right click to slice horizontally. When the swords are not equipped, press E to " - "start/stop a silly dance routine."; - } - - bool frameRenderingQueued(const FrameEvent& evt) - { - // let character update animations and camera - mChara->addTime(evt.timeSinceLastFrame); - return SdkSample::frameRenderingQueued(evt); - } - - bool keyPressed(const OIS::KeyEvent& evt) - { - // relay input events to character controller - if (!mTrayMgr->isDialogVisible()) mChara->injectKeyDown(evt); - return SdkSample::keyPressed(evt); - } - - bool keyReleased(const OIS::KeyEvent& evt) - { - // relay input events to character controller - if (!mTrayMgr->isDialogVisible()) mChara->injectKeyUp(evt); - return SdkSample::keyReleased(evt); - } + Sample_Character() + { + mInfo["Title"] = "Character"; + mInfo["Description"] = "A demo showing 3rd-person character control and use of TagPoints."; + mInfo["Thumbnail"] = "thumb_char.png"; + mInfo["Category"] = "Animation"; + mInfo["Help"] = "Use the WASD keys to move Sinbad, and the space bar to jump. " + "Use mouse to look around and mouse wheel to zoom. Press Q to take out or put back " + "Sinbad's swords. With the swords equipped, you can left click to slice vertically or " + "right click to slice horizontally. When the swords are not equipped, press E to " + "start/stop a silly dance routine."; + } + + bool frameRenderingQueued(const FrameEvent& evt) + { + // let character update animations and camera + mChara->addTime(evt.timeSinceLastFrame); + return SdkSample::frameRenderingQueued(evt); + } + + bool keyPressed(const OIS::KeyEvent& evt) + { + // relay input events to character controller + if (!mTrayMgr->isDialogVisible()) mChara->injectKeyDown(evt); + return SdkSample::keyPressed(evt); + } + + bool keyReleased(const OIS::KeyEvent& evt) + { + // relay input events to character controller + if (!mTrayMgr->isDialogVisible()) mChara->injectKeyUp(evt); + return SdkSample::keyReleased(evt); + } #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - bool touchPressed(const OIS::MultiTouchEvent& evt) - { - // relay input events to character controller - if (!mTrayMgr->isDialogVisible()) mChara->injectMouseDown(evt); - return SdkSample::touchPressed(evt); - } - - bool touchMoved(const OIS::MultiTouchEvent& evt) - { - // relay input events to character controller - if (!mTrayMgr->isDialogVisible()) mChara->injectMouseMove(evt); - return SdkSample::touchMoved(evt); - } + bool touchPressed(const OIS::MultiTouchEvent& evt) + { + // relay input events to character controller + if (!mTrayMgr->isDialogVisible()) mChara->injectMouseDown(evt); + return SdkSample::touchPressed(evt); + } + + bool touchMoved(const OIS::MultiTouchEvent& evt) + { + // relay input events to character controller + if (!mTrayMgr->isDialogVisible()) mChara->injectMouseMove(evt); + return SdkSample::touchMoved(evt); + } #else - bool mouseMoved(const OIS::MouseEvent& evt) - { - // relay input events to character controller - if (!mTrayMgr->isDialogVisible()) mChara->injectMouseMove(evt); - return SdkSample::mouseMoved(evt); - } - - bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id) - { - // relay input events to character controller - if (!mTrayMgr->isDialogVisible()) mChara->injectMouseDown(evt, id); - return SdkSample::mousePressed(evt, id); - } + bool mouseMoved(const OIS::MouseEvent& evt) + { + // relay input events to character controller + if (!mTrayMgr->isDialogVisible()) mChara->injectMouseMove(evt); + return SdkSample::mouseMoved(evt); + } + + bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + { + // relay input events to character controller + if (!mTrayMgr->isDialogVisible()) mChara->injectMouseDown(evt, id); + return SdkSample::mousePressed(evt, id); + } #endif protected: - void setupContent() - { - // set background and some fog - mViewport->setBackgroundColour(ColourValue(1.0f, 1.0f, 0.8f)); - mSceneMgr->setFog(Ogre::FOG_LINEAR, ColourValue(1.0f, 1.0f, 0.8f), 0, 15, 100); + void setupContent() + { + // set background and some fog + mViewport->setBackgroundColour(ColourValue(1.0f, 1.0f, 0.8f)); + mSceneMgr->setFog(Ogre::FOG_LINEAR, ColourValue(1.0f, 1.0f, 0.8f), 0, 15, 100); - // set shadow properties - mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); - mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5)); - mSceneMgr->setShadowTextureSize(1024); - mSceneMgr->setShadowTextureCount(1); + // set shadow properties + mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); + mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5)); + mSceneMgr->setShadowTextureSize(1024); + mSceneMgr->setShadowTextureCount(1); - // disable default camera control so the character can do its own - mCameraMan->setStyle(CS_MANUAL); + // disable default camera control so the character can do its own + mCameraMan->setStyle(CS_MANUAL); - // use a small amount of ambient lighting - mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); + // use a small amount of ambient lighting + mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); - // add a bright light above the scene - Light* light = mSceneMgr->createLight(); - light->setType(Light::LT_POINT); - light->setPosition(-10, 40, 20); - light->setSpecularColour(ColourValue::White); + // add a bright light above the scene + Light* light = mSceneMgr->createLight(); + light->setType(Light::LT_POINT); + light->setPosition(-10, 40, 20); + light->setSpecularColour(ColourValue::White); - // create a floor mesh resource - MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Plane(Vector3::UNIT_Y, 0), 100, 100, 10, 10, true, 1, 10, 10, Vector3::UNIT_Z); + // create a floor mesh resource + MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Plane(Vector3::UNIT_Y, 0), 100, 100, 10, 10, true, 1, 10, 10, Vector3::UNIT_Z); - // create a floor entity, give it a material, and place it at the origin + // create a floor entity, give it a material, and place it at the origin Entity* floor = mSceneMgr->createEntity("Floor", "floor"); floor->setMaterialName("Examples/Rockwall"); - floor->setCastShadows(false); + floor->setCastShadows(false); mSceneMgr->getRootSceneNode()->attachObject(floor); -// LogManager::getSingleton().logMessage("creating sinbad"); - // create our character controller - mChara = new SinbadCharacterController(mCamera); - -// LogManager::getSingleton().logMessage("toggling stats"); - mTrayMgr->toggleAdvancedFrameStats(); - -// LogManager::getSingleton().logMessage("creating panel"); - StringVector items; - items.push_back("Help"); - ParamsPanel* help = mTrayMgr->createParamsPanel(TL_TOPLEFT, "HelpMessage", 100, items); - help->setParamValue("Help", "H / F1"); - -// LogManager::getSingleton().logMessage("all done"); - } - - void cleanupContent() - { - // clean up character controller and the floor mesh - if (mChara) +// LogManager::getSingleton().logMessage("creating sinbad"); + // create our character controller + mChara = new SinbadCharacterController(mCamera); + +// LogManager::getSingleton().logMessage("toggling stats"); + mTrayMgr->toggleAdvancedFrameStats(); + +// LogManager::getSingleton().logMessage("creating panel"); + StringVector items; + items.push_back("Help"); + ParamsPanel* help = mTrayMgr->createParamsPanel(TL_TOPLEFT, "HelpMessage", 100, items); + help->setParamValue("Help", "H / F1"); + +// LogManager::getSingleton().logMessage("all done"); + } + + void cleanupContent() + { + // clean up character controller and the floor mesh + if (mChara) { delete mChara; mChara = 0; } - MeshManager::getSingleton().remove("floor"); - } + MeshManager::getSingleton().remove("floor"); + } - SinbadCharacterController* mChara; + SinbadCharacterController* mChara; }; #endif diff --git a/Samples/Character/include/SinbadCharacterController.h b/Samples/Character/include/SinbadCharacterController.h index 143c6478fa9..c3dad325510 100644 --- a/Samples/Character/include/SinbadCharacterController.h +++ b/Samples/Character/include/SinbadCharacterController.h @@ -19,508 +19,508 @@ class SinbadCharacterController { private: - // all the animations our character has, and a null ID - // some of these affect separate body parts and will be blended together - enum AnimID - { - ANIM_IDLE_BASE, - ANIM_IDLE_TOP, - ANIM_RUN_BASE, - ANIM_RUN_TOP, - ANIM_HANDS_CLOSED, - ANIM_HANDS_RELAXED, - ANIM_DRAW_SWORDS, - ANIM_SLICE_VERTICAL, - ANIM_SLICE_HORIZONTAL, - ANIM_DANCE, - ANIM_JUMP_START, - ANIM_JUMP_LOOP, - ANIM_JUMP_END, - ANIM_NONE - }; + // all the animations our character has, and a null ID + // some of these affect separate body parts and will be blended together + enum AnimID + { + ANIM_IDLE_BASE, + ANIM_IDLE_TOP, + ANIM_RUN_BASE, + ANIM_RUN_TOP, + ANIM_HANDS_CLOSED, + ANIM_HANDS_RELAXED, + ANIM_DRAW_SWORDS, + ANIM_SLICE_VERTICAL, + ANIM_SLICE_HORIZONTAL, + ANIM_DANCE, + ANIM_JUMP_START, + ANIM_JUMP_LOOP, + ANIM_JUMP_END, + ANIM_NONE + }; public: - - SinbadCharacterController(Camera* cam) - { - setupBody(cam->getSceneManager()); - setupCamera(cam); - setupAnimations(); - } - - void addTime(Real deltaTime) - { - updateBody(deltaTime); - updateAnimations(deltaTime); - updateCamera(deltaTime); - } - - void injectKeyDown(const OIS::KeyEvent& evt) - { - if (evt.key == OIS::KC_Q && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) - { - // take swords out (or put them back, since it's the same animation but reversed) - setTopAnimation(ANIM_DRAW_SWORDS, true); - mTimer = 0; - } - else if (evt.key == OIS::KC_E && !mSwordsDrawn) - { - if (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP) - { - // start dancing - setBaseAnimation(ANIM_DANCE, true); - setTopAnimation(ANIM_NONE); - // disable hand animation because the dance controls hands - mAnims[ANIM_HANDS_RELAXED]->setEnabled(false); - } - else if (mBaseAnimID == ANIM_DANCE) - { - // stop dancing - setBaseAnimation(ANIM_IDLE_BASE); - setTopAnimation(ANIM_IDLE_TOP); - // re-enable hand animation - mAnims[ANIM_HANDS_RELAXED]->setEnabled(true); - } - } - - // keep track of the player's intended direction - else if (evt.key == OIS::KC_W) mKeyDirection.z = -1; - else if (evt.key == OIS::KC_A) mKeyDirection.x = -1; - else if (evt.key == OIS::KC_S) mKeyDirection.z = 1; - else if (evt.key == OIS::KC_D) mKeyDirection.x = 1; - - else if (evt.key == OIS::KC_SPACE && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) - { - // jump if on ground - setBaseAnimation(ANIM_JUMP_START, true); - setTopAnimation(ANIM_NONE); - mTimer = 0; - } - - if (!mKeyDirection.isZeroLength() && mBaseAnimID == ANIM_IDLE_BASE) - { - // start running if not already moving and the player wants to move - setBaseAnimation(ANIM_RUN_BASE, true); - if (mTopAnimID == ANIM_IDLE_TOP) setTopAnimation(ANIM_RUN_TOP, true); - } - } - - void injectKeyUp(const OIS::KeyEvent& evt) - { - // keep track of the player's intended direction - if (evt.key == OIS::KC_W && mKeyDirection.z == -1) mKeyDirection.z = 0; - else if (evt.key == OIS::KC_A && mKeyDirection.x == -1) mKeyDirection.x = 0; - else if (evt.key == OIS::KC_S && mKeyDirection.z == 1) mKeyDirection.z = 0; - else if (evt.key == OIS::KC_D && mKeyDirection.x == 1) mKeyDirection.x = 0; - - if (mKeyDirection.isZeroLength() && mBaseAnimID == ANIM_RUN_BASE) - { - // stop running if already moving and the player doesn't want to move - setBaseAnimation(ANIM_IDLE_BASE); - if (mTopAnimID == ANIM_RUN_TOP) setTopAnimation(ANIM_IDLE_TOP); - } - } + + SinbadCharacterController(Camera* cam) + { + setupBody(cam->getSceneManager()); + setupCamera(cam); + setupAnimations(); + } + + void addTime(Real deltaTime) + { + updateBody(deltaTime); + updateAnimations(deltaTime); + updateCamera(deltaTime); + } + + void injectKeyDown(const OIS::KeyEvent& evt) + { + if (evt.key == OIS::KC_Q && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) + { + // take swords out (or put them back, since it's the same animation but reversed) + setTopAnimation(ANIM_DRAW_SWORDS, true); + mTimer = 0; + } + else if (evt.key == OIS::KC_E && !mSwordsDrawn) + { + if (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP) + { + // start dancing + setBaseAnimation(ANIM_DANCE, true); + setTopAnimation(ANIM_NONE); + // disable hand animation because the dance controls hands + mAnims[ANIM_HANDS_RELAXED]->setEnabled(false); + } + else if (mBaseAnimID == ANIM_DANCE) + { + // stop dancing + setBaseAnimation(ANIM_IDLE_BASE); + setTopAnimation(ANIM_IDLE_TOP); + // re-enable hand animation + mAnims[ANIM_HANDS_RELAXED]->setEnabled(true); + } + } + + // keep track of the player's intended direction + else if (evt.key == OIS::KC_W) mKeyDirection.z = -1; + else if (evt.key == OIS::KC_A) mKeyDirection.x = -1; + else if (evt.key == OIS::KC_S) mKeyDirection.z = 1; + else if (evt.key == OIS::KC_D) mKeyDirection.x = 1; + + else if (evt.key == OIS::KC_SPACE && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) + { + // jump if on ground + setBaseAnimation(ANIM_JUMP_START, true); + setTopAnimation(ANIM_NONE); + mTimer = 0; + } + + if (!mKeyDirection.isZeroLength() && mBaseAnimID == ANIM_IDLE_BASE) + { + // start running if not already moving and the player wants to move + setBaseAnimation(ANIM_RUN_BASE, true); + if (mTopAnimID == ANIM_IDLE_TOP) setTopAnimation(ANIM_RUN_TOP, true); + } + } + + void injectKeyUp(const OIS::KeyEvent& evt) + { + // keep track of the player's intended direction + if (evt.key == OIS::KC_W && mKeyDirection.z == -1) mKeyDirection.z = 0; + else if (evt.key == OIS::KC_A && mKeyDirection.x == -1) mKeyDirection.x = 0; + else if (evt.key == OIS::KC_S && mKeyDirection.z == 1) mKeyDirection.z = 0; + else if (evt.key == OIS::KC_D && mKeyDirection.x == 1) mKeyDirection.x = 0; + + if (mKeyDirection.isZeroLength() && mBaseAnimID == ANIM_RUN_BASE) + { + // stop running if already moving and the player doesn't want to move + setBaseAnimation(ANIM_IDLE_BASE); + if (mTopAnimID == ANIM_RUN_TOP) setTopAnimation(ANIM_IDLE_TOP); + } + } #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - void injectMouseMove(const OIS::MultiTouchEvent& evt) - { - // update camera goal based on mouse movement - updateCameraGoal(-0.05f * evt.state.X.rel, -0.05f * evt.state.Y.rel, -0.0005f * evt.state.Z.rel); - } - - void injectMouseDown(const OIS::MultiTouchEvent& evt) - { - if (mSwordsDrawn && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) - { - // if swords are out, and character's not doing something weird, then SLICE! + void injectMouseMove(const OIS::MultiTouchEvent& evt) + { + // update camera goal based on mouse movement + updateCameraGoal(-0.05f * evt.state.X.rel, -0.05f * evt.state.Y.rel, -0.0005f * evt.state.Z.rel); + } + + void injectMouseDown(const OIS::MultiTouchEvent& evt) + { + if (mSwordsDrawn && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) + { + // if swords are out, and character's not doing something weird, then SLICE! setTopAnimation(ANIM_SLICE_VERTICAL, true); - mTimer = 0; - } - } + mTimer = 0; + } + } #else - void injectMouseMove(const OIS::MouseEvent& evt) - { - // update camera goal based on mouse movement - updateCameraGoal(-0.05f * evt.state.X.rel, -0.05f * evt.state.Y.rel, -0.0005f * evt.state.Z.rel); - } - - void injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id) - { - if (mSwordsDrawn && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) - { - // if swords are out, and character's not doing something weird, then SLICE! - if (id == OIS::MB_Left) setTopAnimation(ANIM_SLICE_VERTICAL, true); - else if (id == OIS::MB_Right) setTopAnimation(ANIM_SLICE_HORIZONTAL, true); - mTimer = 0; - } - } + void injectMouseMove(const OIS::MouseEvent& evt) + { + // update camera goal based on mouse movement + updateCameraGoal(-0.05f * evt.state.X.rel, -0.05f * evt.state.Y.rel, -0.0005f * evt.state.Z.rel); + } + + void injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + { + if (mSwordsDrawn && (mTopAnimID == ANIM_IDLE_TOP || mTopAnimID == ANIM_RUN_TOP)) + { + // if swords are out, and character's not doing something weird, then SLICE! + if (id == OIS::MB_Left) setTopAnimation(ANIM_SLICE_VERTICAL, true); + else if (id == OIS::MB_Right) setTopAnimation(ANIM_SLICE_HORIZONTAL, true); + mTimer = 0; + } + } #endif private: - void setupBody(SceneManager* sceneMgr) - { - // create main model - mBodyNode = sceneMgr->getRootSceneNode()->createChildSceneNode(Vector3::UNIT_Y * CHAR_HEIGHT); - mBodyEnt = sceneMgr->createEntity("SinbadBody", "Sinbad.mesh"); - mBodyNode->attachObject(mBodyEnt); - - // create swords and attach to sheath - LogManager::getSingleton().logMessage("Creating swords"); - mSword1 = sceneMgr->createEntity("SinbadSword1", "Sword.mesh"); - mSword2 = sceneMgr->createEntity("SinbadSword2", "Sword.mesh"); - mBodyEnt->attachObjectToBone("Sheath.L", mSword1); - mBodyEnt->attachObjectToBone("Sheath.R", mSword2); - - LogManager::getSingleton().logMessage("Creating the chains"); - // create a couple of ribbon trails for the swords, just for fun - NameValuePairList params; - params["numberOfChains"] = "2"; - params["maxElements"] = "80"; - mSwordTrail = (RibbonTrail*)sceneMgr->createMovableObject("RibbonTrail", ¶ms); - mSwordTrail->setMaterialName("Examples/LightRibbonTrail"); - mSwordTrail->setTrailLength(20); - mSwordTrail->setVisible(false); - sceneMgr->getRootSceneNode()->attachObject(mSwordTrail); - - - for (int i = 0; i < 2; i++) - { - mSwordTrail->setInitialColour(i, 1, 0.8, 0); - mSwordTrail->setColourChange(i, 0.75, 1.25, 1.25, 1.25); - mSwordTrail->setWidthChange(i, 1); - mSwordTrail->setInitialWidth(i, 0.5); - } - - mKeyDirection = Vector3::ZERO; - mVerticalVelocity = 0; - } - - void setupAnimations() - { - // this is very important due to the nature of the exported animations - mBodyEnt->getSkeleton()->setBlendMode(ANIMBLEND_CUMULATIVE); - - String animNames[] = - {"IdleBase", "IdleTop", "RunBase", "RunTop", "HandsClosed", "HandsRelaxed", "DrawSwords", - "SliceVertical", "SliceHorizontal", "Dance", "JumpStart", "JumpLoop", "JumpEnd"}; - - // populate our animation list - for (int i = 0; i < NUM_ANIMS; i++) - { - mAnims[i] = mBodyEnt->getAnimationState(animNames[i]); - mAnims[i]->setLoop(true); - mFadingIn[i] = false; - mFadingOut[i] = false; - } - - // start off in the idle state (top and bottom together) - setBaseAnimation(ANIM_IDLE_BASE); - setTopAnimation(ANIM_IDLE_TOP); - - // relax the hands since we're not holding anything - mAnims[ANIM_HANDS_RELAXED]->setEnabled(true); - - mSwordsDrawn = false; - } - - void setupCamera(Camera* cam) - { - // create a pivot at roughly the character's shoulder - mCameraPivot = cam->getSceneManager()->getRootSceneNode()->createChildSceneNode(); - // this is where the camera should be soon, and it spins around the pivot - mCameraGoal = mCameraPivot->createChildSceneNode(Vector3(0, 0, 15)); - // this is where the camera actually is - mCameraNode = cam->getSceneManager()->getRootSceneNode()->createChildSceneNode(); - mCameraNode->setPosition(mCameraPivot->getPosition() + mCameraGoal->getPosition()); - - mCameraPivot->setFixedYawAxis(true); - mCameraGoal->setFixedYawAxis(true); - mCameraNode->setFixedYawAxis(true); - - // our model is quite small, so reduce the clipping planes - cam->setNearClipDistance(0.1); - cam->setFarClipDistance(100); - mCameraNode->attachObject(cam); - - mPivotPitch = 0; - } - - void updateBody(Real deltaTime) - { - mGoalDirection = Vector3::ZERO; // we will calculate this - - if (mKeyDirection != Vector3::ZERO && mBaseAnimID != ANIM_DANCE) - { - // calculate actually goal direction in world based on player's key directions - mGoalDirection += mKeyDirection.z * mCameraNode->getOrientation().zAxis(); - mGoalDirection += mKeyDirection.x * mCameraNode->getOrientation().xAxis(); - mGoalDirection.y = 0; - mGoalDirection.normalise(); - - Quaternion toGoal = mBodyNode->getOrientation().zAxis().getRotationTo(mGoalDirection); - - // calculate how much the character has to turn to face goal direction - Real yawToGoal = toGoal.getYaw().valueDegrees(); - // this is how much the character CAN turn this frame - Real yawAtSpeed = yawToGoal / Math::Abs(yawToGoal) * deltaTime * TURN_SPEED; - // reduce "turnability" if we're in midair - if (mBaseAnimID == ANIM_JUMP_LOOP) yawAtSpeed *= 0.2f; - - // turn as much as we can, but not more than we need to - if (yawToGoal < 0) yawToGoal = std::min(0, std::max(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp(yawToGoal, yawAtSpeed, 0); - else if (yawToGoal > 0) yawToGoal = std::max(0, std::min(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp(yawToGoal, 0, yawAtSpeed); - - mBodyNode->yaw(Degree(yawToGoal)); - - // move in current body direction (not the goal direction) - mBodyNode->translate(0, 0, deltaTime * RUN_SPEED * mAnims[mBaseAnimID]->getWeight(), - Node::TS_LOCAL); - } - - if (mBaseAnimID == ANIM_JUMP_LOOP) - { - // if we're jumping, add a vertical offset too, and apply gravity - mBodyNode->translate(0, mVerticalVelocity * deltaTime, 0, Node::TS_LOCAL); - mVerticalVelocity -= GRAVITY * deltaTime; - - Vector3 pos = mBodyNode->getPosition(); - if (pos.y <= CHAR_HEIGHT) - { - // if we've hit the ground, change to landing state - pos.y = CHAR_HEIGHT; - mBodyNode->setPosition(pos); - setBaseAnimation(ANIM_JUMP_END, true); - mTimer = 0; - } - } - } - - void updateAnimations(Real deltaTime) - { - Real baseAnimSpeed = 1; - Real topAnimSpeed = 1; - - mTimer += deltaTime; - - if (mTopAnimID == ANIM_DRAW_SWORDS) - { - // flip the draw swords animation if we need to put it back - topAnimSpeed = mSwordsDrawn ? -1 : 1; - - // half-way through the animation is when the hand grasps the handles... - if (mTimer >= mAnims[mTopAnimID]->getLength() / 2 && - mTimer - deltaTime < mAnims[mTopAnimID]->getLength() / 2) - { - // so transfer the swords from the sheaths to the hands - mBodyEnt->detachAllObjectsFromBone(); - mBodyEnt->attachObjectToBone(mSwordsDrawn ? "Sheath.L" : "Handle.L", mSword1); - mBodyEnt->attachObjectToBone(mSwordsDrawn ? "Sheath.R" : "Handle.R", mSword2); - // change the hand state to grab or let go - mAnims[ANIM_HANDS_CLOSED]->setEnabled(!mSwordsDrawn); - mAnims[ANIM_HANDS_RELAXED]->setEnabled(mSwordsDrawn); - - // toggle sword trails - if (mSwordsDrawn) - { - mSwordTrail->setVisible(false); - mSwordTrail->removeNode(mSword1->getParentNode()); - mSwordTrail->removeNode(mSword2->getParentNode()); - } - else - { - mSwordTrail->setVisible(true); - mSwordTrail->addNode(mSword1->getParentNode()); - mSwordTrail->addNode(mSword2->getParentNode()); - } - } - - if (mTimer >= mAnims[mTopAnimID]->getLength()) - { - // animation is finished, so return to what we were doing before - if (mBaseAnimID == ANIM_IDLE_BASE) setTopAnimation(ANIM_IDLE_TOP); - else - { - setTopAnimation(ANIM_RUN_TOP); - mAnims[ANIM_RUN_TOP]->setTimePosition(mAnims[ANIM_RUN_BASE]->getTimePosition()); - } - mSwordsDrawn = !mSwordsDrawn; - } - } - else if (mTopAnimID == ANIM_SLICE_VERTICAL || mTopAnimID == ANIM_SLICE_HORIZONTAL) - { - if (mTimer >= mAnims[mTopAnimID]->getLength()) - { - // animation is finished, so return to what we were doing before - if (mBaseAnimID == ANIM_IDLE_BASE) setTopAnimation(ANIM_IDLE_TOP); - else - { - setTopAnimation(ANIM_RUN_TOP); - mAnims[ANIM_RUN_TOP]->setTimePosition(mAnims[ANIM_RUN_BASE]->getTimePosition()); - } - } - - // don't sway hips from side to side when slicing. that's just embarrassing. - if (mBaseAnimID == ANIM_IDLE_BASE) baseAnimSpeed = 0; - } - else if (mBaseAnimID == ANIM_JUMP_START) - { - if (mTimer >= mAnims[mBaseAnimID]->getLength()) - { - // takeoff animation finished, so time to leave the ground! - setBaseAnimation(ANIM_JUMP_LOOP, true); - // apply a jump acceleration to the character - mVerticalVelocity = JUMP_ACCEL; - } - } - else if (mBaseAnimID == ANIM_JUMP_END) - { - if (mTimer >= mAnims[mBaseAnimID]->getLength()) - { - // safely landed, so go back to running or idling - if (mKeyDirection == Vector3::ZERO) - { - setBaseAnimation(ANIM_IDLE_BASE); - setTopAnimation(ANIM_IDLE_TOP); - } - else - { - setBaseAnimation(ANIM_RUN_BASE, true); - setTopAnimation(ANIM_RUN_TOP, true); - } - } - } - - // increment the current base and top animation times - if (mBaseAnimID != ANIM_NONE) mAnims[mBaseAnimID]->addTime(deltaTime * baseAnimSpeed); - if (mTopAnimID != ANIM_NONE) mAnims[mTopAnimID]->addTime(deltaTime * topAnimSpeed); - - // apply smooth transitioning between our animations - fadeAnimations(deltaTime); - } - - void fadeAnimations(Real deltaTime) - { - for (int i = 0; i < NUM_ANIMS; i++) - { - if (mFadingIn[i]) - { - // slowly fade this animation in until it has full weight - Real newWeight = mAnims[i]->getWeight() + deltaTime * ANIM_FADE_SPEED; - mAnims[i]->setWeight(Math::Clamp(newWeight, 0, 1)); - if (newWeight >= 1) mFadingIn[i] = false; - } - else if (mFadingOut[i]) - { - // slowly fade this animation out until it has no weight, and then disable it - Real newWeight = mAnims[i]->getWeight() - deltaTime * ANIM_FADE_SPEED; - mAnims[i]->setWeight(Math::Clamp(newWeight, 0, 1)); - if (newWeight <= 0) - { - mAnims[i]->setEnabled(false); - mFadingOut[i] = false; - } - } - } - } - - void updateCamera(Real deltaTime) - { - // place the camera pivot roughly at the character's shoulder - mCameraPivot->setPosition(mBodyNode->getPosition() + Vector3::UNIT_Y * CAM_HEIGHT); - // move the camera smoothly to the goal - Vector3 goalOffset = mCameraGoal->_getDerivedPosition() - mCameraNode->getPosition(); - mCameraNode->translate(goalOffset * deltaTime * 9.0f); - // always look at the pivot - mCameraNode->lookAt(mCameraPivot->_getDerivedPosition(), Node::TS_WORLD); - } - - void updateCameraGoal(Real deltaYaw, Real deltaPitch, Real deltaZoom) - { - mCameraPivot->yaw(Degree(deltaYaw), Node::TS_WORLD); - - // bound the pitch - if (!(mPivotPitch + deltaPitch > 25 && deltaPitch > 0) && - !(mPivotPitch + deltaPitch < -60 && deltaPitch < 0)) - { - mCameraPivot->pitch(Degree(deltaPitch), Node::TS_LOCAL); - mPivotPitch += deltaPitch; - } - - Real dist = mCameraGoal->_getDerivedPosition().distance(mCameraPivot->_getDerivedPosition()); - Real distChange = deltaZoom * dist; - - // bound the zoom - if (!(dist + distChange < 8 && distChange < 0) && - !(dist + distChange > 25 && distChange > 0)) - { - mCameraGoal->translate(0, 0, distChange, Node::TS_LOCAL); - } - } - - void setBaseAnimation(AnimID id, bool reset = false) - { - if (mBaseAnimID >= 0 && mBaseAnimID < NUM_ANIMS) - { - // if we have an old animation, fade it out - mFadingIn[mBaseAnimID] = false; - mFadingOut[mBaseAnimID] = true; - } - - mBaseAnimID = id; - - if (id != ANIM_NONE) - { - // if we have a new animation, enable it and fade it in - mAnims[id]->setEnabled(true); - mAnims[id]->setWeight(0); - mFadingOut[id] = false; - mFadingIn[id] = true; - if (reset) mAnims[id]->setTimePosition(0); - } - } - - void setTopAnimation(AnimID id, bool reset = false) - { - if (mTopAnimID >= 0 && mTopAnimID < NUM_ANIMS) - { - // if we have an old animation, fade it out - mFadingIn[mTopAnimID] = false; - mFadingOut[mTopAnimID] = true; - } - - mTopAnimID = id; - - if (id != ANIM_NONE) - { - // if we have a new animation, enable it and fade it in - mAnims[id]->setEnabled(true); - mAnims[id]->setWeight(0); - mFadingOut[id] = false; - mFadingIn[id] = true; - if (reset) mAnims[id]->setTimePosition(0); - } - } - - SceneNode* mBodyNode; - SceneNode* mCameraPivot; - SceneNode* mCameraGoal; - SceneNode* mCameraNode; - Real mPivotPitch; - Entity* mBodyEnt; - Entity* mSword1; - Entity* mSword2; - RibbonTrail* mSwordTrail; - AnimationState* mAnims[NUM_ANIMS]; // master animation list - AnimID mBaseAnimID; // current base (full- or lower-body) animation - AnimID mTopAnimID; // current top (upper-body) animation - bool mFadingIn[NUM_ANIMS]; // which animations are fading in - bool mFadingOut[NUM_ANIMS]; // which animations are fading out - bool mSwordsDrawn; - Vector3 mKeyDirection; // player's local intended direction based on WASD keys - Vector3 mGoalDirection; // actual intended direction in world-space - Real mVerticalVelocity; // for jumping - Real mTimer; // general timer to see how long animations have been playing + void setupBody(SceneManager* sceneMgr) + { + // create main model + mBodyNode = sceneMgr->getRootSceneNode()->createChildSceneNode(Vector3::UNIT_Y * CHAR_HEIGHT); + mBodyEnt = sceneMgr->createEntity("SinbadBody", "Sinbad.mesh"); + mBodyNode->attachObject(mBodyEnt); + + // create swords and attach to sheath + LogManager::getSingleton().logMessage("Creating swords"); + mSword1 = sceneMgr->createEntity("SinbadSword1", "Sword.mesh"); + mSword2 = sceneMgr->createEntity("SinbadSword2", "Sword.mesh"); + mBodyEnt->attachObjectToBone("Sheath.L", mSword1); + mBodyEnt->attachObjectToBone("Sheath.R", mSword2); + + LogManager::getSingleton().logMessage("Creating the chains"); + // create a couple of ribbon trails for the swords, just for fun + NameValuePairList params; + params["numberOfChains"] = "2"; + params["maxElements"] = "80"; + mSwordTrail = (RibbonTrail*)sceneMgr->createMovableObject("RibbonTrail", ¶ms); + mSwordTrail->setMaterialName("Examples/LightRibbonTrail"); + mSwordTrail->setTrailLength(20); + mSwordTrail->setVisible(false); + sceneMgr->getRootSceneNode()->attachObject(mSwordTrail); + + + for (int i = 0; i < 2; i++) + { + mSwordTrail->setInitialColour(i, 1, 0.8, 0); + mSwordTrail->setColourChange(i, 0.75, 1.25, 1.25, 1.25); + mSwordTrail->setWidthChange(i, 1); + mSwordTrail->setInitialWidth(i, 0.5); + } + + mKeyDirection = Vector3::ZERO; + mVerticalVelocity = 0; + } + + void setupAnimations() + { + // this is very important due to the nature of the exported animations + mBodyEnt->getSkeleton()->setBlendMode(ANIMBLEND_CUMULATIVE); + + String animNames[] = + {"IdleBase", "IdleTop", "RunBase", "RunTop", "HandsClosed", "HandsRelaxed", "DrawSwords", + "SliceVertical", "SliceHorizontal", "Dance", "JumpStart", "JumpLoop", "JumpEnd"}; + + // populate our animation list + for (int i = 0; i < NUM_ANIMS; i++) + { + mAnims[i] = mBodyEnt->getAnimationState(animNames[i]); + mAnims[i]->setLoop(true); + mFadingIn[i] = false; + mFadingOut[i] = false; + } + + // start off in the idle state (top and bottom together) + setBaseAnimation(ANIM_IDLE_BASE); + setTopAnimation(ANIM_IDLE_TOP); + + // relax the hands since we're not holding anything + mAnims[ANIM_HANDS_RELAXED]->setEnabled(true); + + mSwordsDrawn = false; + } + + void setupCamera(Camera* cam) + { + // create a pivot at roughly the character's shoulder + mCameraPivot = cam->getSceneManager()->getRootSceneNode()->createChildSceneNode(); + // this is where the camera should be soon, and it spins around the pivot + mCameraGoal = mCameraPivot->createChildSceneNode(Vector3(0, 0, 15)); + // this is where the camera actually is + mCameraNode = cam->getSceneManager()->getRootSceneNode()->createChildSceneNode(); + mCameraNode->setPosition(mCameraPivot->getPosition() + mCameraGoal->getPosition()); + + mCameraPivot->setFixedYawAxis(true); + mCameraGoal->setFixedYawAxis(true); + mCameraNode->setFixedYawAxis(true); + + // our model is quite small, so reduce the clipping planes + cam->setNearClipDistance(0.1); + cam->setFarClipDistance(100); + mCameraNode->attachObject(cam); + + mPivotPitch = 0; + } + + void updateBody(Real deltaTime) + { + mGoalDirection = Vector3::ZERO; // we will calculate this + + if (mKeyDirection != Vector3::ZERO && mBaseAnimID != ANIM_DANCE) + { + // calculate actually goal direction in world based on player's key directions + mGoalDirection += mKeyDirection.z * mCameraNode->getOrientation().zAxis(); + mGoalDirection += mKeyDirection.x * mCameraNode->getOrientation().xAxis(); + mGoalDirection.y = 0; + mGoalDirection.normalise(); + + Quaternion toGoal = mBodyNode->getOrientation().zAxis().getRotationTo(mGoalDirection); + + // calculate how much the character has to turn to face goal direction + Real yawToGoal = toGoal.getYaw().valueDegrees(); + // this is how much the character CAN turn this frame + Real yawAtSpeed = yawToGoal / Math::Abs(yawToGoal) * deltaTime * TURN_SPEED; + // reduce "turnability" if we're in midair + if (mBaseAnimID == ANIM_JUMP_LOOP) yawAtSpeed *= 0.2f; + + // turn as much as we can, but not more than we need to + if (yawToGoal < 0) yawToGoal = std::min(0, std::max(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp(yawToGoal, yawAtSpeed, 0); + else if (yawToGoal > 0) yawToGoal = std::max(0, std::min(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp(yawToGoal, 0, yawAtSpeed); + + mBodyNode->yaw(Degree(yawToGoal)); + + // move in current body direction (not the goal direction) + mBodyNode->translate(0, 0, deltaTime * RUN_SPEED * mAnims[mBaseAnimID]->getWeight(), + Node::TS_LOCAL); + } + + if (mBaseAnimID == ANIM_JUMP_LOOP) + { + // if we're jumping, add a vertical offset too, and apply gravity + mBodyNode->translate(0, mVerticalVelocity * deltaTime, 0, Node::TS_LOCAL); + mVerticalVelocity -= GRAVITY * deltaTime; + + Vector3 pos = mBodyNode->getPosition(); + if (pos.y <= CHAR_HEIGHT) + { + // if we've hit the ground, change to landing state + pos.y = CHAR_HEIGHT; + mBodyNode->setPosition(pos); + setBaseAnimation(ANIM_JUMP_END, true); + mTimer = 0; + } + } + } + + void updateAnimations(Real deltaTime) + { + Real baseAnimSpeed = 1; + Real topAnimSpeed = 1; + + mTimer += deltaTime; + + if (mTopAnimID == ANIM_DRAW_SWORDS) + { + // flip the draw swords animation if we need to put it back + topAnimSpeed = mSwordsDrawn ? -1 : 1; + + // half-way through the animation is when the hand grasps the handles... + if (mTimer >= mAnims[mTopAnimID]->getLength() / 2 && + mTimer - deltaTime < mAnims[mTopAnimID]->getLength() / 2) + { + // so transfer the swords from the sheaths to the hands + mBodyEnt->detachAllObjectsFromBone(); + mBodyEnt->attachObjectToBone(mSwordsDrawn ? "Sheath.L" : "Handle.L", mSword1); + mBodyEnt->attachObjectToBone(mSwordsDrawn ? "Sheath.R" : "Handle.R", mSword2); + // change the hand state to grab or let go + mAnims[ANIM_HANDS_CLOSED]->setEnabled(!mSwordsDrawn); + mAnims[ANIM_HANDS_RELAXED]->setEnabled(mSwordsDrawn); + + // toggle sword trails + if (mSwordsDrawn) + { + mSwordTrail->setVisible(false); + mSwordTrail->removeNode(mSword1->getParentNode()); + mSwordTrail->removeNode(mSword2->getParentNode()); + } + else + { + mSwordTrail->setVisible(true); + mSwordTrail->addNode(mSword1->getParentNode()); + mSwordTrail->addNode(mSword2->getParentNode()); + } + } + + if (mTimer >= mAnims[mTopAnimID]->getLength()) + { + // animation is finished, so return to what we were doing before + if (mBaseAnimID == ANIM_IDLE_BASE) setTopAnimation(ANIM_IDLE_TOP); + else + { + setTopAnimation(ANIM_RUN_TOP); + mAnims[ANIM_RUN_TOP]->setTimePosition(mAnims[ANIM_RUN_BASE]->getTimePosition()); + } + mSwordsDrawn = !mSwordsDrawn; + } + } + else if (mTopAnimID == ANIM_SLICE_VERTICAL || mTopAnimID == ANIM_SLICE_HORIZONTAL) + { + if (mTimer >= mAnims[mTopAnimID]->getLength()) + { + // animation is finished, so return to what we were doing before + if (mBaseAnimID == ANIM_IDLE_BASE) setTopAnimation(ANIM_IDLE_TOP); + else + { + setTopAnimation(ANIM_RUN_TOP); + mAnims[ANIM_RUN_TOP]->setTimePosition(mAnims[ANIM_RUN_BASE]->getTimePosition()); + } + } + + // don't sway hips from side to side when slicing. that's just embarrassing. + if (mBaseAnimID == ANIM_IDLE_BASE) baseAnimSpeed = 0; + } + else if (mBaseAnimID == ANIM_JUMP_START) + { + if (mTimer >= mAnims[mBaseAnimID]->getLength()) + { + // takeoff animation finished, so time to leave the ground! + setBaseAnimation(ANIM_JUMP_LOOP, true); + // apply a jump acceleration to the character + mVerticalVelocity = JUMP_ACCEL; + } + } + else if (mBaseAnimID == ANIM_JUMP_END) + { + if (mTimer >= mAnims[mBaseAnimID]->getLength()) + { + // safely landed, so go back to running or idling + if (mKeyDirection == Vector3::ZERO) + { + setBaseAnimation(ANIM_IDLE_BASE); + setTopAnimation(ANIM_IDLE_TOP); + } + else + { + setBaseAnimation(ANIM_RUN_BASE, true); + setTopAnimation(ANIM_RUN_TOP, true); + } + } + } + + // increment the current base and top animation times + if (mBaseAnimID != ANIM_NONE) mAnims[mBaseAnimID]->addTime(deltaTime * baseAnimSpeed); + if (mTopAnimID != ANIM_NONE) mAnims[mTopAnimID]->addTime(deltaTime * topAnimSpeed); + + // apply smooth transitioning between our animations + fadeAnimations(deltaTime); + } + + void fadeAnimations(Real deltaTime) + { + for (int i = 0; i < NUM_ANIMS; i++) + { + if (mFadingIn[i]) + { + // slowly fade this animation in until it has full weight + Real newWeight = mAnims[i]->getWeight() + deltaTime * ANIM_FADE_SPEED; + mAnims[i]->setWeight(Math::Clamp(newWeight, 0, 1)); + if (newWeight >= 1) mFadingIn[i] = false; + } + else if (mFadingOut[i]) + { + // slowly fade this animation out until it has no weight, and then disable it + Real newWeight = mAnims[i]->getWeight() - deltaTime * ANIM_FADE_SPEED; + mAnims[i]->setWeight(Math::Clamp(newWeight, 0, 1)); + if (newWeight <= 0) + { + mAnims[i]->setEnabled(false); + mFadingOut[i] = false; + } + } + } + } + + void updateCamera(Real deltaTime) + { + // place the camera pivot roughly at the character's shoulder + mCameraPivot->setPosition(mBodyNode->getPosition() + Vector3::UNIT_Y * CAM_HEIGHT); + // move the camera smoothly to the goal + Vector3 goalOffset = mCameraGoal->_getDerivedPosition() - mCameraNode->getPosition(); + mCameraNode->translate(goalOffset * deltaTime * 9.0f); + // always look at the pivot + mCameraNode->lookAt(mCameraPivot->_getDerivedPosition(), Node::TS_WORLD); + } + + void updateCameraGoal(Real deltaYaw, Real deltaPitch, Real deltaZoom) + { + mCameraPivot->yaw(Degree(deltaYaw), Node::TS_WORLD); + + // bound the pitch + if (!(mPivotPitch + deltaPitch > 25 && deltaPitch > 0) && + !(mPivotPitch + deltaPitch < -60 && deltaPitch < 0)) + { + mCameraPivot->pitch(Degree(deltaPitch), Node::TS_LOCAL); + mPivotPitch += deltaPitch; + } + + Real dist = mCameraGoal->_getDerivedPosition().distance(mCameraPivot->_getDerivedPosition()); + Real distChange = deltaZoom * dist; + + // bound the zoom + if (!(dist + distChange < 8 && distChange < 0) && + !(dist + distChange > 25 && distChange > 0)) + { + mCameraGoal->translate(0, 0, distChange, Node::TS_LOCAL); + } + } + + void setBaseAnimation(AnimID id, bool reset = false) + { + if (mBaseAnimID >= 0 && mBaseAnimID < NUM_ANIMS) + { + // if we have an old animation, fade it out + mFadingIn[mBaseAnimID] = false; + mFadingOut[mBaseAnimID] = true; + } + + mBaseAnimID = id; + + if (id != ANIM_NONE) + { + // if we have a new animation, enable it and fade it in + mAnims[id]->setEnabled(true); + mAnims[id]->setWeight(0); + mFadingOut[id] = false; + mFadingIn[id] = true; + if (reset) mAnims[id]->setTimePosition(0); + } + } + + void setTopAnimation(AnimID id, bool reset = false) + { + if (mTopAnimID >= 0 && mTopAnimID < NUM_ANIMS) + { + // if we have an old animation, fade it out + mFadingIn[mTopAnimID] = false; + mFadingOut[mTopAnimID] = true; + } + + mTopAnimID = id; + + if (id != ANIM_NONE) + { + // if we have a new animation, enable it and fade it in + mAnims[id]->setEnabled(true); + mAnims[id]->setWeight(0); + mFadingOut[id] = false; + mFadingIn[id] = true; + if (reset) mAnims[id]->setTimePosition(0); + } + } + + SceneNode* mBodyNode; + SceneNode* mCameraPivot; + SceneNode* mCameraGoal; + SceneNode* mCameraNode; + Real mPivotPitch; + Entity* mBodyEnt; + Entity* mSword1; + Entity* mSword2; + RibbonTrail* mSwordTrail; + AnimationState* mAnims[NUM_ANIMS]; // master animation list + AnimID mBaseAnimID; // current base (full- or lower-body) animation + AnimID mTopAnimID; // current top (upper-body) animation + bool mFadingIn[NUM_ANIMS]; // which animations are fading in + bool mFadingOut[NUM_ANIMS]; // which animations are fading out + bool mSwordsDrawn; + Vector3 mKeyDirection; // player's local intended direction based on WASD keys + Vector3 mGoalDirection; // actual intended direction in world-space + Real mVerticalVelocity; // for jumping + Real mTimer; // general timer to see how long animations have been playing }; #endif diff --git a/Samples/Character/src/CharacterSample.cpp b/Samples/Character/src/CharacterSample.cpp index 57286856201..f27215e1a64 100644 --- a/Samples/Character/src/CharacterSample.cpp +++ b/Samples/Character/src/CharacterSample.cpp @@ -11,17 +11,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Character; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Character; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Common/include/ExampleApplication.h b/Samples/Common/include/ExampleApplication.h index 711df52a9e5..4527e91c22b 100644 --- a/Samples/Common/include/ExampleApplication.h +++ b/Samples/Common/include/ExampleApplication.h @@ -71,43 +71,43 @@ class ShaderGeneratorTechniqueResolverListener : public MaterialManager::Listene { public: - ShaderGeneratorTechniqueResolverListener(RTShader::ShaderGenerator* pShaderGenerator) - { - mShaderGenerator = pShaderGenerator; - } - - virtual Technique* handleSchemeNotFound(unsigned short schemeIndex, - const String& schemeName, Material* originalMaterial, unsigned short lodIndex, - const Renderable* rend) - { - // Case this is the default shader generator scheme. - if (schemeName == RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) - { - MaterialRegisterIterator itFind = mRegisteredMaterials.find(originalMaterial); - bool techniqueCreated = false; - - // This material was not registered before. - if (itFind == mRegisteredMaterials.end()) - { - techniqueCreated = mShaderGenerator->createShaderBasedTechnique( - originalMaterial->getName(), - MaterialManager::DEFAULT_SCHEME_NAME, - schemeName); - } - mRegisteredMaterials[originalMaterial] = techniqueCreated; - } - - return NULL; - } + ShaderGeneratorTechniqueResolverListener(RTShader::ShaderGenerator* pShaderGenerator) + { + mShaderGenerator = pShaderGenerator; + } + + virtual Technique* handleSchemeNotFound(unsigned short schemeIndex, + const String& schemeName, Material* originalMaterial, unsigned short lodIndex, + const Renderable* rend) + { + // Case this is the default shader generator scheme. + if (schemeName == RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) + { + MaterialRegisterIterator itFind = mRegisteredMaterials.find(originalMaterial); + bool techniqueCreated = false; + + // This material was not registered before. + if (itFind == mRegisteredMaterials.end()) + { + techniqueCreated = mShaderGenerator->createShaderBasedTechnique( + originalMaterial->getName(), + MaterialManager::DEFAULT_SCHEME_NAME, + schemeName); + } + mRegisteredMaterials[originalMaterial] = techniqueCreated; + } + + return NULL; + } protected: - typedef std::map MaterialRegisterMap; - typedef MaterialRegisterMap::iterator MaterialRegisterIterator; + typedef std::map MaterialRegisterMap; + typedef MaterialRegisterMap::iterator MaterialRegisterIterator; protected: - MaterialRegisterMap mRegisteredMaterials; // Registered material map. - RTShader::ShaderGenerator* mShaderGenerator; // The shader generator instance. + MaterialRegisterMap mRegisteredMaterials; // Registered material map. + RTShader::ShaderGenerator* mShaderGenerator; // The shader generator instance. }; #endif @@ -124,25 +124,25 @@ class ExampleApplication { mFrameListener = 0; mRoot = 0; - mOverlaySystem=0; + mOverlaySystem=0; - // Provide a nice cross platform solution for locating the configuration files - // On windows files are searched for in the current working directory, on OS X however - // you must provide the full path, the helper function macBundlePath does this for us. + // Provide a nice cross platform solution for locating the configuration files + // On windows files are searched for in the current working directory, on OS X however + // you must provide the full path, the helper function macBundlePath does this for us. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE - mResourcePath = macBundlePath() + "/Contents/Resources/"; + mResourcePath = macBundlePath() + "/Contents/Resources/"; mConfigPath = mResourcePath; #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS mResourcePath = macBundlePath() + "/"; mConfigPath = mResourcePath; #else - mResourcePath = ""; + mResourcePath = ""; mConfigPath = mResourcePath; #endif #ifdef INCLUDE_RTSHADER_SYSTEM - mShaderGenerator = NULL; - mMaterialMgrListener = NULL; + mShaderGenerator = NULL; + mMaterialMgrListener = NULL; #endif } /// Standard destructor @@ -150,17 +150,17 @@ class ExampleApplication { if (mFrameListener) delete mFrameListener; - if (mOverlaySystem) - { - if(mSceneMgr) mSceneMgr->removeRenderQueueListener(mOverlaySystem); + if (mOverlaySystem) + { + if(mSceneMgr) mSceneMgr->removeRenderQueueListener(mOverlaySystem); OGRE_DELETE mOverlaySystem; - } + } if (mRoot) OGRE_DELETE mRoot; #ifdef OGRE_STATIC_LIB - mStaticPluginLoader.unload(); + mStaticPluginLoader.unload(); #endif } @@ -173,30 +173,30 @@ class ExampleApplication mRoot->startRendering(); // clean up - destroyScene(); + destroyScene(); #ifdef INCLUDE_RTSHADER_SYSTEM - // Finalize shader generator. - finalizeShaderGenerator(); + // Finalize shader generator. + finalizeShaderGenerator(); #endif } protected: Root *mRoot; - OverlaySystem* mOverlaySystem; + OverlaySystem* mOverlaySystem; #ifdef OGRE_STATIC_LIB - StaticPluginLoader mStaticPluginLoader; + StaticPluginLoader mStaticPluginLoader; #endif Camera* mCamera; SceneManager* mSceneMgr; ExampleFrameListener* mFrameListener; RenderWindow* mWindow; - Ogre::String mResourcePath; - Ogre::String mConfigPath; + Ogre::String mResourcePath; + Ogre::String mConfigPath; #ifdef INCLUDE_RTSHADER_SYSTEM - RTShader::ShaderGenerator* mShaderGenerator; // The Shader generator instance. - ShaderGeneratorTechniqueResolverListener* mMaterialMgrListener; // Material manager listener. + RTShader::ShaderGenerator* mShaderGenerator; // The Shader generator instance. + ShaderGeneratorTechniqueResolverListener* mMaterialMgrListener; // Material manager listener. #endif // These internal methods package up the stages in the startup process @@ -204,47 +204,47 @@ class ExampleApplication virtual bool setup(void) { - String pluginsPath; - // only use plugins.cfg if not static + String pluginsPath; + // only use plugins.cfg if not static #ifndef OGRE_STATIC_LIB #if OGRE_DEBUG_MODE - pluginsPath = mResourcePath + "plugins_d.cfg"; + pluginsPath = mResourcePath + "plugins_d.cfg"; #else - pluginsPath = mResourcePath + "plugins.cfg"; + pluginsPath = mResourcePath + "plugins.cfg"; #endif #endif - + mRoot = OGRE_NEW Root(pluginsPath, mConfigPath + "ogre.cfg", mResourcePath + "Ogre.log"); - mOverlaySystem = OGRE_NEW OverlaySystem(); + mOverlaySystem = OGRE_NEW OverlaySystem(); #ifdef OGRE_STATIC_LIB - mStaticPluginLoader.load(); + mStaticPluginLoader.load(); #endif setupResources(); bool carryOn = configure(); if (!carryOn) - return false; + return false; chooseSceneManager(); createCamera(); createViewports(); #ifdef INCLUDE_RTSHADER_SYSTEM - // Initialize shader generator. - carryOn = initializeShaderGenerator(mSceneMgr); - if (!carryOn) - return false; + // Initialize shader generator. + carryOn = initializeShaderGenerator(mSceneMgr); + if (!carryOn) + return false; #endif // Set default mipmap level (NB some APIs ignore this) TextureManager::getSingleton().setDefaultNumMipmaps(5); - // Create any resource listeners (for loading screens) - createResourceListener(); - // Load resources - loadResources(); + // Create any resource listeners (for loading screens) + createResourceListener(); + // Load resources + loadResources(); - // Create the scene + // Create the scene createScene(); createFrameListener(); @@ -253,74 +253,74 @@ class ExampleApplication } #ifdef INCLUDE_RTSHADER_SYSTEM - virtual bool initializeShaderGenerator(SceneManager* sceneMgr) - { - if (RTShader::ShaderGenerator::initialize()) - { - mShaderGenerator = RTShader::ShaderGenerator::getSingletonPtr(); - - // Set the scene manager. - mShaderGenerator->addSceneManager(sceneMgr); - - // Setup core libraries and shader cache path. - ResourceGroupManager::LocationList resLocationsList = ResourceGroupManager::getSingleton().getResourceLocationList("Popular"); - ResourceGroupManager::LocationList::iterator it = resLocationsList.begin(); - ResourceGroupManager::LocationList::iterator itEnd = resLocationsList.end(); - String shaderCoreLibsPath; - String shaderCachePath; - - // Default cache path is current directory; - shaderCachePath = "./"; - - // Try to find the location of the core shader lib functions and use it - // as shader cache path as well - this will reduce the number of generated files - // when running from different directories. - for (; it != itEnd; ++it) - { - - if ((*it)->archive->getName().find("RTShaderLib") != String::npos) - { - shaderCoreLibsPath = (*it)->archive->getName() + "/"; - shaderCachePath = shaderCoreLibsPath; - break; - } - } - - // Core shader libs not found -> shader generating will fail. - if (shaderCoreLibsPath.empty()) - return false; - - // Add resource location for the core shader libs. - ResourceGroupManager::getSingleton().addResourceLocation(shaderCoreLibsPath , "FileSystem"); - - // Set shader cache path. - mShaderGenerator->setShaderCachePath(shaderCachePath); - - // Create and register the material manager listener. - mMaterialMgrListener = new ShaderGeneratorTechniqueResolverListener(mShaderGenerator); - MaterialManager::getSingleton().addListener(mMaterialMgrListener); - } - - return true; - } - - virtual void finalizeShaderGenerator() - { - // Unregister the material manager listener. - if (mMaterialMgrListener != NULL) - { - MaterialManager::getSingleton().removeListener(mMaterialMgrListener); - delete mMaterialMgrListener; - mMaterialMgrListener = NULL; - } - - // Finalize CRTShader system. - if (mShaderGenerator != NULL) - { - RTShader::ShaderGenerator::finalize(); - mShaderGenerator = NULL; - } - } + virtual bool initializeShaderGenerator(SceneManager* sceneMgr) + { + if (RTShader::ShaderGenerator::initialize()) + { + mShaderGenerator = RTShader::ShaderGenerator::getSingletonPtr(); + + // Set the scene manager. + mShaderGenerator->addSceneManager(sceneMgr); + + // Setup core libraries and shader cache path. + ResourceGroupManager::LocationList resLocationsList = ResourceGroupManager::getSingleton().getResourceLocationList("Popular"); + ResourceGroupManager::LocationList::iterator it = resLocationsList.begin(); + ResourceGroupManager::LocationList::iterator itEnd = resLocationsList.end(); + String shaderCoreLibsPath; + String shaderCachePath; + + // Default cache path is current directory; + shaderCachePath = "./"; + + // Try to find the location of the core shader lib functions and use it + // as shader cache path as well - this will reduce the number of generated files + // when running from different directories. + for (; it != itEnd; ++it) + { + + if ((*it)->archive->getName().find("RTShaderLib") != String::npos) + { + shaderCoreLibsPath = (*it)->archive->getName() + "/"; + shaderCachePath = shaderCoreLibsPath; + break; + } + } + + // Core shader libs not found -> shader generating will fail. + if (shaderCoreLibsPath.empty()) + return false; + + // Add resource location for the core shader libs. + ResourceGroupManager::getSingleton().addResourceLocation(shaderCoreLibsPath , "FileSystem"); + + // Set shader cache path. + mShaderGenerator->setShaderCachePath(shaderCachePath); + + // Create and register the material manager listener. + mMaterialMgrListener = new ShaderGeneratorTechniqueResolverListener(mShaderGenerator); + MaterialManager::getSingleton().addListener(mMaterialMgrListener); + } + + return true; + } + + virtual void finalizeShaderGenerator() + { + // Unregister the material manager listener. + if (mMaterialMgrListener != NULL) + { + MaterialManager::getSingleton().removeListener(mMaterialMgrListener); + delete mMaterialMgrListener; + mMaterialMgrListener = NULL; + } + + // Finalize CRTShader system. + if (mShaderGenerator != NULL) + { + RTShader::ShaderGenerator::finalize(); + mShaderGenerator = NULL; + } + } #endif /** Configures the application - returns false if the user chooses to abandon configuration. */ virtual bool configure(void) @@ -346,8 +346,8 @@ class ExampleApplication // Create the SceneManager, in this case a generic one mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance"); - if(mOverlaySystem) - mSceneMgr->addRenderQueueListener(mOverlaySystem); + if(mOverlaySystem) + mSceneMgr->addRenderQueueListener(mOverlaySystem); } virtual void createCamera(void) { @@ -395,7 +395,7 @@ class ExampleApplication #if OGRE_DEBUG_MODE cf.load(mResourcePath + "resources_d.cfg"); #else - cf.load(mResourcePath + "resources.cfg"); + cf.load(mResourcePath + "resources.cfg"); #endif // Go through all sections & settings in the file @@ -415,8 +415,8 @@ class ExampleApplication // OS X does not set the working directory relative to the app, // In order to make things portable on OS X we need to provide // the loading with it's own bundle path location - if (!StringUtil::startsWith(archName, "/", false)) // only adjust relative dirs - archName = String(macBundlePath() + "/" + archName); + if (!StringUtil::startsWith(archName, "/", false)) // only adjust relative dirs + archName = String(macBundlePath() + "/" + archName); #endif ResourceGroupManager::getSingleton().addResourceLocation( archName, typeName, secName); @@ -425,20 +425,20 @@ class ExampleApplication } } - /// Optional override method where you can create resource listeners (e.g. for loading screens) - virtual void createResourceListener(void) - { + /// Optional override method where you can create resource listeners (e.g. for loading screens) + virtual void createResourceListener(void) + { - } + } - /// Optional override method where you can perform resource group loading - /// Must at least do ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - virtual void loadResources(void) - { - // Initialise, parse scripts etc - ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + /// Optional override method where you can perform resource group loading + /// Must at least do ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + virtual void loadResources(void) + { + // Initialise, parse scripts etc + ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - } + } }; diff --git a/Samples/Common/include/ExampleFrameListener.h b/Samples/Common/include/ExampleFrameListener.h index 905e980e17b..6176f6da525 100644 --- a/Samples/Common/include/ExampleFrameListener.h +++ b/Samples/Common/include/ExampleFrameListener.h @@ -25,13 +25,13 @@ D: Step right PgUp: Move upwards PgDown: Move downwards F: Toggle frame rate stats on/off - R: Render mode + R: Render mode T: Cycle texture filtering Bilinear, Trilinear, Anisotropic(8) P: Toggle on/off display of camera position / orientation - F2: Set the main viewport material scheme to default material manager scheme. - F3: Set the main viewport material scheme to shader generator default scheme. - F4: Toggle default shader generator lighting model from per vertex to per pixel. + F2: Set the main viewport material scheme to default material manager scheme. + F3: Set the main viewport material scheme to shader generator default scheme. + F4: Toggle default shader generator lighting model from per vertex to per pixel. ----------------------------------------------------------------------------- */ @@ -60,294 +60,294 @@ using namespace Ogre; class ExampleFrameListener: public FrameListener, public WindowEventListener { protected: - virtual void updateStats(void) - { - static String currFps = "Current FPS: "; - static String avgFps = "Average FPS: "; - static String bestFps = "Best FPS: "; - static String worstFps = "Worst FPS: "; - static String tris = "Triangle Count: "; - static String batches = "Batch Count: "; - - // update stats when necessary - try { - OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps"); - OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps"); - OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps"); - OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps"); - - const RenderTarget::FrameStats& stats = mWindow->getStatistics(); - guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS)); - guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS)); - guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS) - +" "+StringConverter::toString(stats.bestFrameTime)+" ms"); - guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS) - +" "+StringConverter::toString(stats.worstFrameTime)+" ms"); - - OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris"); - guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount)); - - OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches"); - guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount)); - - OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); - guiDbg->setCaption(mDebugText); - } - catch(...) { /* ignore */ } - } + virtual void updateStats(void) + { + static String currFps = "Current FPS: "; + static String avgFps = "Average FPS: "; + static String bestFps = "Best FPS: "; + static String worstFps = "Worst FPS: "; + static String tris = "Triangle Count: "; + static String batches = "Batch Count: "; + + // update stats when necessary + try { + OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps"); + OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps"); + OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps"); + OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps"); + + const RenderTarget::FrameStats& stats = mWindow->getStatistics(); + guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS)); + guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS)); + guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS) + +" "+StringConverter::toString(stats.bestFrameTime)+" ms"); + guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS) + +" "+StringConverter::toString(stats.worstFrameTime)+" ms"); + + OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris"); + guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount)); + + OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches"); + guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount)); + + OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); + guiDbg->setCaption(mDebugText); + } + catch(...) { /* ignore */ } + } public: - // Constructor takes a RenderWindow because it uses that to determine input context - ExampleFrameListener(RenderWindow* win, Camera* cam, bool bufferedKeys = false, bool bufferedMouse = false, - bool bufferedJoy = false ) : - mCamera(cam), mTranslateVector(Vector3::ZERO), mCurrentSpeed(0), mWindow(win), mStatsOn(true), mNumScreenShots(0), - mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR), - mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0), - mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0) - { - - mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); - - LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***"); - OIS::ParamList pl; - size_t windowHnd = 0; - std::ostringstream windowHndStr; - - win->getCustomAttribute("WINDOW", &windowHnd); - windowHndStr << windowHnd; - pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); - - mInputManager = OIS::InputManager::createInputSystem( pl ); - - //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse) - mKeyboard = static_cast(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys )); - mMouse = static_cast(mInputManager->createInputObject( OIS::OISMouse, bufferedMouse )); - try { - mJoy = static_cast(mInputManager->createInputObject( OIS::OISJoyStick, bufferedJoy )); - } - catch(...) { - mJoy = 0; - } - - //Set initial mouse clipping size - windowResized(mWindow); - - showDebugOverlay(true); - - //Register as a Window listener - WindowEventUtilities::addWindowEventListener(mWindow, this); - } + // Constructor takes a RenderWindow because it uses that to determine input context + ExampleFrameListener(RenderWindow* win, Camera* cam, bool bufferedKeys = false, bool bufferedMouse = false, + bool bufferedJoy = false ) : + mCamera(cam), mTranslateVector(Vector3::ZERO), mCurrentSpeed(0), mWindow(win), mStatsOn(true), mNumScreenShots(0), + mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR), + mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0), + mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0) + { + + mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); + + LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***"); + OIS::ParamList pl; + size_t windowHnd = 0; + std::ostringstream windowHndStr; + + win->getCustomAttribute("WINDOW", &windowHnd); + windowHndStr << windowHnd; + pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); + + mInputManager = OIS::InputManager::createInputSystem( pl ); + + //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse) + mKeyboard = static_cast(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys )); + mMouse = static_cast(mInputManager->createInputObject( OIS::OISMouse, bufferedMouse )); + try { + mJoy = static_cast(mInputManager->createInputObject( OIS::OISJoyStick, bufferedJoy )); + } + catch(...) { + mJoy = 0; + } + + //Set initial mouse clipping size + windowResized(mWindow); + + showDebugOverlay(true); + + //Register as a Window listener + WindowEventUtilities::addWindowEventListener(mWindow, this); + } #ifdef INCLUDE_RTSHADER_SYSTEM - virtual void processShaderGeneratorInput() - { - // Switch to default scheme. - if (mKeyboard->isKeyDown(OIS::KC_F2)) - { - mCamera->getViewport()->setMaterialScheme(MaterialManager::DEFAULT_SCHEME_NAME); - mDebugText = "Active Viewport Scheme: "; - mDebugText += MaterialManager::DEFAULT_SCHEME_NAME; - } - - // Switch to shader generator scheme. - if (mKeyboard->isKeyDown(OIS::KC_F3)) - { - mCamera->getViewport()->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - mDebugText = "Active Viewport Scheme: "; - mDebugText += RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME; - } - - // Toggles per pixel per light model. - if (mKeyboard->isKeyDown(OIS::KC_F4) && mTimeUntilNextToggle <= 0) - { - mTimeUntilNextToggle = 1.0; - - static bool userPerPixelLightModel = true; - RTShader::ShaderGenerator* shaderGenerator = RTShader::ShaderGenerator::getSingletonPtr(); - RTShader::RenderState* renderState = shaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - - // Remove all global sub render states. - renderState->reset(); - - // Add per pixel lighting sub render state to the global scheme render state. - // It will override the default FFP lighting sub render state. - if (userPerPixelLightModel) - { - RTShader::SubRenderState* perPixelLightModel = shaderGenerator->createSubRenderState(RTShader::PerPixelLighting::Type); - renderState->addTemplateSubRenderState(perPixelLightModel); - - mDebugText = "Per pixel lighting model applied to shader generator default scheme"; - } - else - { - mDebugText = "Per vertex lighting model applied to shader generator default scheme"; - } - - // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. - shaderGenerator->invalidateScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - - userPerPixelLightModel = !userPerPixelLightModel; - } - - } + virtual void processShaderGeneratorInput() + { + // Switch to default scheme. + if (mKeyboard->isKeyDown(OIS::KC_F2)) + { + mCamera->getViewport()->setMaterialScheme(MaterialManager::DEFAULT_SCHEME_NAME); + mDebugText = "Active Viewport Scheme: "; + mDebugText += MaterialManager::DEFAULT_SCHEME_NAME; + } + + // Switch to shader generator scheme. + if (mKeyboard->isKeyDown(OIS::KC_F3)) + { + mCamera->getViewport()->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + mDebugText = "Active Viewport Scheme: "; + mDebugText += RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME; + } + + // Toggles per pixel per light model. + if (mKeyboard->isKeyDown(OIS::KC_F4) && mTimeUntilNextToggle <= 0) + { + mTimeUntilNextToggle = 1.0; + + static bool userPerPixelLightModel = true; + RTShader::ShaderGenerator* shaderGenerator = RTShader::ShaderGenerator::getSingletonPtr(); + RTShader::RenderState* renderState = shaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + + // Remove all global sub render states. + renderState->reset(); + + // Add per pixel lighting sub render state to the global scheme render state. + // It will override the default FFP lighting sub render state. + if (userPerPixelLightModel) + { + RTShader::SubRenderState* perPixelLightModel = shaderGenerator->createSubRenderState(RTShader::PerPixelLighting::Type); + renderState->addTemplateSubRenderState(perPixelLightModel); + + mDebugText = "Per pixel lighting model applied to shader generator default scheme"; + } + else + { + mDebugText = "Per vertex lighting model applied to shader generator default scheme"; + } + + // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. + shaderGenerator->invalidateScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + + userPerPixelLightModel = !userPerPixelLightModel; + } + + } #endif - //Adjust mouse clipping area - virtual void windowResized(RenderWindow* rw) - { - unsigned int width, height, depth; - int left, top; - rw->getMetrics(width, height, depth, left, top); - - const OIS::MouseState &ms = mMouse->getMouseState(); - ms.width = width; - ms.height = height; - } - - //Unattach OIS before window shutdown (very important under Linux) - virtual void windowClosed(RenderWindow* rw) - { - //Only close for window that created OIS (the main window in these demos) - if( rw == mWindow ) - { - if( mInputManager ) - { - mInputManager->destroyInputObject( mMouse ); - mInputManager->destroyInputObject( mKeyboard ); - mInputManager->destroyInputObject( mJoy ); - - OIS::InputManager::destroyInputSystem(mInputManager); - mInputManager = 0; - } - } - } - - virtual ~ExampleFrameListener() - { - //Remove ourself as a Window listener - WindowEventUtilities::removeWindowEventListener(mWindow, this); - windowClosed(mWindow); - } - - virtual bool processUnbufferedKeyInput(const FrameEvent& evt) - { - Real moveScale = mMoveScale; - if(mKeyboard->isKeyDown(OIS::KC_LSHIFT)) - moveScale *= 10; - - if(mKeyboard->isKeyDown(OIS::KC_A)) - mTranslateVector.x = -moveScale; // Move camera left - - if(mKeyboard->isKeyDown(OIS::KC_D)) - mTranslateVector.x = moveScale; // Move camera RIGHT - - if(mKeyboard->isKeyDown(OIS::KC_UP) || mKeyboard->isKeyDown(OIS::KC_W) ) - mTranslateVector.z = -moveScale; // Move camera forward - - if(mKeyboard->isKeyDown(OIS::KC_DOWN) || mKeyboard->isKeyDown(OIS::KC_S) ) - mTranslateVector.z = moveScale; // Move camera backward - - if(mKeyboard->isKeyDown(OIS::KC_PGUP)) - mTranslateVector.y = moveScale; // Move camera up - - if(mKeyboard->isKeyDown(OIS::KC_PGDOWN)) - mTranslateVector.y = -moveScale; // Move camera down - - if(mKeyboard->isKeyDown(OIS::KC_RIGHT)) - mCamera->yaw(-mRotScale); - - if(mKeyboard->isKeyDown(OIS::KC_LEFT)) - mCamera->yaw(mRotScale); - - if( mKeyboard->isKeyDown(OIS::KC_ESCAPE) || mKeyboard->isKeyDown(OIS::KC_Q) ) - return false; - - if( mKeyboard->isKeyDown(OIS::KC_F) && mTimeUntilNextToggle <= 0 ) - { - mStatsOn = !mStatsOn; - showDebugOverlay(mStatsOn); - mTimeUntilNextToggle = 1; - } - - if( mKeyboard->isKeyDown(OIS::KC_T) && mTimeUntilNextToggle <= 0 ) - { - switch(mFiltering) - { - case TFO_BILINEAR: - mFiltering = TFO_TRILINEAR; - mAniso = 1; - break; - case TFO_TRILINEAR: - mFiltering = TFO_ANISOTROPIC; - mAniso = 8; - break; - case TFO_ANISOTROPIC: - mFiltering = TFO_BILINEAR; - mAniso = 1; - break; - default: break; - } - MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering); - MaterialManager::getSingleton().setDefaultAnisotropy(mAniso); - - showDebugOverlay(mStatsOn); - mTimeUntilNextToggle = 1; - } - - if(mKeyboard->isKeyDown(OIS::KC_SYSRQ) && mTimeUntilNextToggle <= 0) - { - std::ostringstream ss; - ss << "screenshot_" << ++mNumScreenShots << ".png"; - mWindow->writeContentsToFile(ss.str()); - mTimeUntilNextToggle = 0.5; - mDebugText = "Saved: " + ss.str(); - } - - if(mKeyboard->isKeyDown(OIS::KC_R) && mTimeUntilNextToggle <=0) - { - mSceneDetailIndex = (mSceneDetailIndex+1)%3 ; - switch(mSceneDetailIndex) { - case 0 : mCamera->setPolygonMode(PM_SOLID); break; - case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break; - case 2 : mCamera->setPolygonMode(PM_POINTS); break; - } - mTimeUntilNextToggle = 0.5; - } - - static bool displayCameraDetails = false; - if(mKeyboard->isKeyDown(OIS::KC_P) && mTimeUntilNextToggle <= 0) - { - displayCameraDetails = !displayCameraDetails; - mTimeUntilNextToggle = 0.5; - if (!displayCameraDetails) - mDebugText = ""; - } - - // Print camera details - if(displayCameraDetails) - mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) + - " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation()); - - // Return true to continue rendering - return true; - } - - virtual bool processUnbufferedMouseInput(const FrameEvent& evt) - { - - // Rotation factors, may not be used if the second mouse button is pressed - // 2nd mouse button - slide, otherwise rotate - const OIS::MouseState &ms = mMouse->getMouseState(); - if( ms.buttonDown( OIS::MB_Right ) ) - { - mTranslateVector.x += ms.X.rel * 0.13; - mTranslateVector.y -= ms.Y.rel * 0.13; - } - else - { - mRotX = Degree(-ms.X.rel * 0.13); - mRotY = Degree(-ms.Y.rel * 0.13); + //Adjust mouse clipping area + virtual void windowResized(RenderWindow* rw) + { + unsigned int width, height, depth; + int left, top; + rw->getMetrics(width, height, depth, left, top); + + const OIS::MouseState &ms = mMouse->getMouseState(); + ms.width = width; + ms.height = height; + } + + //Unattach OIS before window shutdown (very important under Linux) + virtual void windowClosed(RenderWindow* rw) + { + //Only close for window that created OIS (the main window in these demos) + if( rw == mWindow ) + { + if( mInputManager ) + { + mInputManager->destroyInputObject( mMouse ); + mInputManager->destroyInputObject( mKeyboard ); + mInputManager->destroyInputObject( mJoy ); + + OIS::InputManager::destroyInputSystem(mInputManager); + mInputManager = 0; + } + } + } + + virtual ~ExampleFrameListener() + { + //Remove ourself as a Window listener + WindowEventUtilities::removeWindowEventListener(mWindow, this); + windowClosed(mWindow); + } + + virtual bool processUnbufferedKeyInput(const FrameEvent& evt) + { + Real moveScale = mMoveScale; + if(mKeyboard->isKeyDown(OIS::KC_LSHIFT)) + moveScale *= 10; + + if(mKeyboard->isKeyDown(OIS::KC_A)) + mTranslateVector.x = -moveScale; // Move camera left + + if(mKeyboard->isKeyDown(OIS::KC_D)) + mTranslateVector.x = moveScale; // Move camera RIGHT + + if(mKeyboard->isKeyDown(OIS::KC_UP) || mKeyboard->isKeyDown(OIS::KC_W) ) + mTranslateVector.z = -moveScale; // Move camera forward + + if(mKeyboard->isKeyDown(OIS::KC_DOWN) || mKeyboard->isKeyDown(OIS::KC_S) ) + mTranslateVector.z = moveScale; // Move camera backward + + if(mKeyboard->isKeyDown(OIS::KC_PGUP)) + mTranslateVector.y = moveScale; // Move camera up + + if(mKeyboard->isKeyDown(OIS::KC_PGDOWN)) + mTranslateVector.y = -moveScale; // Move camera down + + if(mKeyboard->isKeyDown(OIS::KC_RIGHT)) + mCamera->yaw(-mRotScale); + + if(mKeyboard->isKeyDown(OIS::KC_LEFT)) + mCamera->yaw(mRotScale); + + if( mKeyboard->isKeyDown(OIS::KC_ESCAPE) || mKeyboard->isKeyDown(OIS::KC_Q) ) + return false; + + if( mKeyboard->isKeyDown(OIS::KC_F) && mTimeUntilNextToggle <= 0 ) + { + mStatsOn = !mStatsOn; + showDebugOverlay(mStatsOn); + mTimeUntilNextToggle = 1; + } + + if( mKeyboard->isKeyDown(OIS::KC_T) && mTimeUntilNextToggle <= 0 ) + { + switch(mFiltering) + { + case TFO_BILINEAR: + mFiltering = TFO_TRILINEAR; + mAniso = 1; + break; + case TFO_TRILINEAR: + mFiltering = TFO_ANISOTROPIC; + mAniso = 8; + break; + case TFO_ANISOTROPIC: + mFiltering = TFO_BILINEAR; + mAniso = 1; + break; + default: break; + } + MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering); + MaterialManager::getSingleton().setDefaultAnisotropy(mAniso); + + showDebugOverlay(mStatsOn); + mTimeUntilNextToggle = 1; + } + + if(mKeyboard->isKeyDown(OIS::KC_SYSRQ) && mTimeUntilNextToggle <= 0) + { + std::ostringstream ss; + ss << "screenshot_" << ++mNumScreenShots << ".png"; + mWindow->writeContentsToFile(ss.str()); + mTimeUntilNextToggle = 0.5; + mDebugText = "Saved: " + ss.str(); + } + + if(mKeyboard->isKeyDown(OIS::KC_R) && mTimeUntilNextToggle <=0) + { + mSceneDetailIndex = (mSceneDetailIndex+1)%3 ; + switch(mSceneDetailIndex) { + case 0 : mCamera->setPolygonMode(PM_SOLID); break; + case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break; + case 2 : mCamera->setPolygonMode(PM_POINTS); break; + } + mTimeUntilNextToggle = 0.5; + } + + static bool displayCameraDetails = false; + if(mKeyboard->isKeyDown(OIS::KC_P) && mTimeUntilNextToggle <= 0) + { + displayCameraDetails = !displayCameraDetails; + mTimeUntilNextToggle = 0.5; + if (!displayCameraDetails) + mDebugText = ""; + } + + // Print camera details + if(displayCameraDetails) + mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) + + " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation()); + + // Return true to continue rendering + return true; + } + + virtual bool processUnbufferedMouseInput(const FrameEvent& evt) + { + + // Rotation factors, may not be used if the second mouse button is pressed + // 2nd mouse button - slide, otherwise rotate + const OIS::MouseState &ms = mMouse->getMouseState(); + if( ms.buttonDown( OIS::MB_Right ) ) + { + mTranslateVector.x += ms.X.rel * 0.13; + mTranslateVector.y -= ms.Y.rel * 0.13; + } + else + { + mRotX = Degree(-ms.X.rel * 0.13); + mRotY = Degree(-ms.Y.rel * 0.13); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS // Adjust the input depending upon viewport orientation Radian origRotY, origRotX; @@ -372,146 +372,146 @@ class ExampleFrameListener: public FrameListener, public WindowEventListener break; } #endif - } - - return true; - } - - virtual void moveCamera() - { - // Make all the changes to the camera - // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW - //(e.g. airplane) - mCamera->yaw(mRotX); - mCamera->pitch(mRotY); - mCamera->moveRelative(mTranslateVector); - } - - virtual void showDebugOverlay(bool show) - { - if (mDebugOverlay) - { - if (show) - mDebugOverlay->show(); - else - mDebugOverlay->hide(); - } - } - - // Override frameRenderingQueued event to process that (don't care about frameEnded) - bool frameRenderingQueued(const FrameEvent& evt) - { - - if(mWindow->isClosed()) return false; - - mSpeedLimit = mMoveScale * evt.timeSinceLastFrame; - - //Need to capture/update each device - mKeyboard->capture(); - mMouse->capture(); - if( mJoy ) mJoy->capture(); - - bool buffJ = (mJoy) ? mJoy->buffered() : true; - - Ogre::Vector3 lastMotion = mTranslateVector; - - //Check if one of the devices is not buffered - if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ ) - { - // one of the input modes is immediate, so setup what is needed for immediate movement - if (mTimeUntilNextToggle >= 0) - mTimeUntilNextToggle -= evt.timeSinceLastFrame; - - // Move about 100 units per second - mMoveScale = mMoveSpeed * evt.timeSinceLastFrame; - // Take about 10 seconds for full rotation - mRotScale = mRotateSpeed * evt.timeSinceLastFrame; - - mRotX = 0; - mRotY = 0; - mTranslateVector = Ogre::Vector3::ZERO; - - } - - //Check to see which device is not buffered, and handle it + } + + return true; + } + + virtual void moveCamera() + { + // Make all the changes to the camera + // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW + //(e.g. airplane) + mCamera->yaw(mRotX); + mCamera->pitch(mRotY); + mCamera->moveRelative(mTranslateVector); + } + + virtual void showDebugOverlay(bool show) + { + if (mDebugOverlay) + { + if (show) + mDebugOverlay->show(); + else + mDebugOverlay->hide(); + } + } + + // Override frameRenderingQueued event to process that (don't care about frameEnded) + bool frameRenderingQueued(const FrameEvent& evt) + { + + if(mWindow->isClosed()) return false; + + mSpeedLimit = mMoveScale * evt.timeSinceLastFrame; + + //Need to capture/update each device + mKeyboard->capture(); + mMouse->capture(); + if( mJoy ) mJoy->capture(); + + bool buffJ = (mJoy) ? mJoy->buffered() : true; + + Ogre::Vector3 lastMotion = mTranslateVector; + + //Check if one of the devices is not buffered + if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ ) + { + // one of the input modes is immediate, so setup what is needed for immediate movement + if (mTimeUntilNextToggle >= 0) + mTimeUntilNextToggle -= evt.timeSinceLastFrame; + + // Move about 100 units per second + mMoveScale = mMoveSpeed * evt.timeSinceLastFrame; + // Take about 10 seconds for full rotation + mRotScale = mRotateSpeed * evt.timeSinceLastFrame; + + mRotX = 0; + mRotY = 0; + mTranslateVector = Ogre::Vector3::ZERO; + + } + + //Check to see which device is not buffered, and handle it #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS - if( !mKeyboard->buffered() ) - if( processUnbufferedKeyInput(evt) == false ) - return false; + if( !mKeyboard->buffered() ) + if( processUnbufferedKeyInput(evt) == false ) + return false; #ifdef INCLUDE_RTSHADER_SYSTEM - processShaderGeneratorInput(); + processShaderGeneratorInput(); #endif #endif - if( !mMouse->buffered() ) - if( processUnbufferedMouseInput(evt) == false ) - return false; - - // ramp up / ramp down speed - if (mTranslateVector == Ogre::Vector3::ZERO) - { - // decay (one third speed) - mCurrentSpeed -= evt.timeSinceLastFrame * 0.3; - mTranslateVector = lastMotion; - } - else - { - // ramp up - mCurrentSpeed += evt.timeSinceLastFrame; - - } - // Limit motion speed - if (mCurrentSpeed > 1.0) - mCurrentSpeed = 1.0; - if (mCurrentSpeed < 0.0) - mCurrentSpeed = 0.0; - - mTranslateVector *= mCurrentSpeed; - - - if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ ) - moveCamera(); - - return true; - } - - bool frameEnded(const FrameEvent& evt) - { - updateStats(); - return true; - } + if( !mMouse->buffered() ) + if( processUnbufferedMouseInput(evt) == false ) + return false; + + // ramp up / ramp down speed + if (mTranslateVector == Ogre::Vector3::ZERO) + { + // decay (one third speed) + mCurrentSpeed -= evt.timeSinceLastFrame * 0.3; + mTranslateVector = lastMotion; + } + else + { + // ramp up + mCurrentSpeed += evt.timeSinceLastFrame; + + } + // Limit motion speed + if (mCurrentSpeed > 1.0) + mCurrentSpeed = 1.0; + if (mCurrentSpeed < 0.0) + mCurrentSpeed = 0.0; + + mTranslateVector *= mCurrentSpeed; + + + if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ ) + moveCamera(); + + return true; + } + + bool frameEnded(const FrameEvent& evt) + { + updateStats(); + return true; + } protected: - Camera* mCamera; - - Vector3 mTranslateVector; - Real mCurrentSpeed; - RenderWindow* mWindow; - bool mStatsOn; - - String mDebugText; - - unsigned int mNumScreenShots; - float mMoveScale; - float mSpeedLimit; - Degree mRotScale; - // just to stop toggles flipping too fast - Real mTimeUntilNextToggle ; - Radian mRotX, mRotY; - TextureFilterOptions mFiltering; - int mAniso; - - int mSceneDetailIndex ; - Real mMoveSpeed; - Degree mRotateSpeed; - Overlay* mDebugOverlay; - - //OIS Input devices - OIS::InputManager* mInputManager; - OIS::Mouse* mMouse; - OIS::Keyboard* mKeyboard; - OIS::JoyStick* mJoy; + Camera* mCamera; + + Vector3 mTranslateVector; + Real mCurrentSpeed; + RenderWindow* mWindow; + bool mStatsOn; + + String mDebugText; + + unsigned int mNumScreenShots; + float mMoveScale; + float mSpeedLimit; + Degree mRotScale; + // just to stop toggles flipping too fast + Real mTimeUntilNextToggle ; + Radian mRotX, mRotY; + TextureFilterOptions mFiltering; + int mAniso; + + int mSceneDetailIndex ; + Real mMoveSpeed; + Degree mRotateSpeed; + Overlay* mDebugOverlay; + + //OIS Input devices + OIS::InputManager* mInputManager; + OIS::Mouse* mMouse; + OIS::Keyboard* mKeyboard; + OIS::JoyStick* mJoy; }; #endif diff --git a/Samples/Common/include/ExampleLoadingBar.h b/Samples/Common/include/ExampleLoadingBar.h index 899c55b191d..7f3daecc43e 100644 --- a/Samples/Common/include/ExampleLoadingBar.h +++ b/Samples/Common/include/ExampleLoadingBar.h @@ -29,164 +29,164 @@ the basic resources required for the progress bar and will be loaded automatical using namespace Ogre; /** Defines an example loading progress bar which you can use during - startup, level changes etc to display loading progress. + startup, level changes etc to display loading progress. @remarks - Basically you just need to create an instance of this class, call start() - before loading and finish() afterwards. You may also need to stop areas of - your scene rendering in between since this method will call - RenderWindow::update() to update the display of the bar - we advise using - SceneManager's 'special case render queues' for this, see - SceneManager::addSpecialCaseRenderQueue for details. + Basically you just need to create an instance of this class, call start() + before loading and finish() afterwards. You may also need to stop areas of + your scene rendering in between since this method will call + RenderWindow::update() to update the display of the bar - we advise using + SceneManager's 'special case render queues' for this, see + SceneManager::addSpecialCaseRenderQueue for details. @note - This progress bar relies on you having the OgreCore.zip package already - added to a resource group called 'Bootstrap' - this provides the basic - resources required for the progress bar and will be loaded automatically. + This progress bar relies on you having the OgreCore.zip package already + added to a resource group called 'Bootstrap' - this provides the basic + resources required for the progress bar and will be loaded automatically. */ class ExampleLoadingBar : public ResourceGroupListener { protected: - RenderWindow* mWindow; - Overlay* mLoadOverlay; - Real mInitProportion; - unsigned short mNumGroupsInit; - unsigned short mNumGroupsLoad; - Real mProgressBarMaxSize; - Real mProgressBarScriptSize; - Real mProgressBarInc; - OverlayElement* mLoadingBarElement; - OverlayElement* mLoadingDescriptionElement; - OverlayElement* mLoadingCommentElement; + RenderWindow* mWindow; + Overlay* mLoadOverlay; + Real mInitProportion; + unsigned short mNumGroupsInit; + unsigned short mNumGroupsLoad; + Real mProgressBarMaxSize; + Real mProgressBarScriptSize; + Real mProgressBarInc; + OverlayElement* mLoadingBarElement; + OverlayElement* mLoadingDescriptionElement; + OverlayElement* mLoadingCommentElement; public: - ExampleLoadingBar() {} - virtual ~ExampleLoadingBar(){} - - /** Show the loading bar and start listening. - @param window The window to update - @param numGroupsInit The number of groups you're going to be initialising - @param numGroupsLoad The number of groups you're going to be loading - @param initProportion The proportion of the progress which will be taken - up by initialisation (ie script parsing etc). Defaults to 0.7 since - script parsing can often take the majority of the time. - */ - virtual void start(RenderWindow* window, - unsigned short numGroupsInit = 1, - unsigned short numGroupsLoad = 1, - Real initProportion = 0.70f) - { - mWindow = window; - mNumGroupsInit = numGroupsInit; - mNumGroupsLoad = numGroupsLoad; - mInitProportion = initProportion; - // We need to pre-initialise the 'Bootstrap' group so we can use - // the basic contents in the loading screen - ResourceGroupManager::getSingleton().initialiseResourceGroup("Bootstrap"); - - OverlayManager& omgr = OverlayManager::getSingleton(); - mLoadOverlay = (Overlay*)omgr.getByName("Core/LoadOverlay"); - if (!mLoadOverlay) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Cannot find loading overlay", "ExampleLoadingBar::start"); - } - mLoadOverlay->show(); - - // Save links to the bar and to the loading text, for updates as we go - mLoadingBarElement = omgr.getOverlayElement("Core/LoadPanel/Bar/Progress"); - mLoadingCommentElement = omgr.getOverlayElement("Core/LoadPanel/Comment"); - mLoadingDescriptionElement = omgr.getOverlayElement("Core/LoadPanel/Description"); - - OverlayElement* barContainer = omgr.getOverlayElement("Core/LoadPanel/Bar"); - mProgressBarMaxSize = barContainer->getWidth(); - mLoadingBarElement->setWidth(0); - - // self is listener - ResourceGroupManager::getSingleton().addResourceGroupListener(this); - - - - } - - /** Hide the loading bar and stop listening. - */ - virtual void finish(void) - { - // hide loading screen - mLoadOverlay->hide(); - - // Unregister listener - ResourceGroupManager::getSingleton().removeResourceGroupListener(this); - - } - - - // ResourceGroupListener callbacks - void resourceGroupScriptingStarted(const String& groupName, size_t scriptCount) - { - assert(mNumGroupsInit > 0 && "You stated you were not going to init " - "any groups, but you did! Divide by zero would follow..."); - // Lets assume script loading is 70% - mProgressBarInc = mProgressBarMaxSize * mInitProportion / (Real)scriptCount; - mProgressBarInc /= mNumGroupsInit; - mLoadingDescriptionElement->setCaption("Parsing scripts..."); - mWindow->update(); - } - void scriptParseStarted(const String& scriptName, bool &skipThisScript) - { - mLoadingCommentElement->setCaption(scriptName); - mWindow->update(); - } - void scriptParseEnded(const String& scriptName, bool skipped) - { - mLoadingBarElement->setWidth( - mLoadingBarElement->getWidth() + mProgressBarInc); - mWindow->update(); - } - void resourceGroupScriptingEnded(const String& groupName) - { - } - void resourceGroupLoadStarted(const String& groupName, size_t resourceCount) - { - assert(mNumGroupsLoad > 0 && "You stated you were not going to load " - "any groups, but you did! Divide by zero would follow..."); - mProgressBarInc = mProgressBarMaxSize * (1-mInitProportion) / - (Real)resourceCount; - mProgressBarInc /= mNumGroupsLoad; - mLoadingDescriptionElement->setCaption("Loading resources..."); - mWindow->update(); - } - void resourceLoadStarted(const ResourcePtr& resource) - { - mLoadingCommentElement->setCaption(resource->getName()); - mWindow->update(); - } - void resourceLoadEnded(void) - { - } - void worldGeometryStageStarted(const String& description) - { - mLoadingCommentElement->setCaption(description); - mWindow->update(); - } - void worldGeometryStageEnded(void) - { - mLoadingBarElement->setWidth( - mLoadingBarElement->getWidth() + mProgressBarInc); - mWindow->update(); - } - void resourceGroupLoadEnded(const String& groupName) - { - } - - Ogre::DataStreamPtr resourceLoading(const String &name, const String &group, Resource *resource) - { - return Ogre::DataStreamPtr(); - } - - bool resourceCollision(ResourcePtr &resource, ResourceManager *resourceManager) - { - return false; - } + ExampleLoadingBar() {} + virtual ~ExampleLoadingBar(){} + + /** Show the loading bar and start listening. + @param window The window to update + @param numGroupsInit The number of groups you're going to be initialising + @param numGroupsLoad The number of groups you're going to be loading + @param initProportion The proportion of the progress which will be taken + up by initialisation (ie script parsing etc). Defaults to 0.7 since + script parsing can often take the majority of the time. + */ + virtual void start(RenderWindow* window, + unsigned short numGroupsInit = 1, + unsigned short numGroupsLoad = 1, + Real initProportion = 0.70f) + { + mWindow = window; + mNumGroupsInit = numGroupsInit; + mNumGroupsLoad = numGroupsLoad; + mInitProportion = initProportion; + // We need to pre-initialise the 'Bootstrap' group so we can use + // the basic contents in the loading screen + ResourceGroupManager::getSingleton().initialiseResourceGroup("Bootstrap"); + + OverlayManager& omgr = OverlayManager::getSingleton(); + mLoadOverlay = (Overlay*)omgr.getByName("Core/LoadOverlay"); + if (!mLoadOverlay) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Cannot find loading overlay", "ExampleLoadingBar::start"); + } + mLoadOverlay->show(); + + // Save links to the bar and to the loading text, for updates as we go + mLoadingBarElement = omgr.getOverlayElement("Core/LoadPanel/Bar/Progress"); + mLoadingCommentElement = omgr.getOverlayElement("Core/LoadPanel/Comment"); + mLoadingDescriptionElement = omgr.getOverlayElement("Core/LoadPanel/Description"); + + OverlayElement* barContainer = omgr.getOverlayElement("Core/LoadPanel/Bar"); + mProgressBarMaxSize = barContainer->getWidth(); + mLoadingBarElement->setWidth(0); + + // self is listener + ResourceGroupManager::getSingleton().addResourceGroupListener(this); + + + + } + + /** Hide the loading bar and stop listening. + */ + virtual void finish(void) + { + // hide loading screen + mLoadOverlay->hide(); + + // Unregister listener + ResourceGroupManager::getSingleton().removeResourceGroupListener(this); + + } + + + // ResourceGroupListener callbacks + void resourceGroupScriptingStarted(const String& groupName, size_t scriptCount) + { + assert(mNumGroupsInit > 0 && "You stated you were not going to init " + "any groups, but you did! Divide by zero would follow..."); + // Lets assume script loading is 70% + mProgressBarInc = mProgressBarMaxSize * mInitProportion / (Real)scriptCount; + mProgressBarInc /= mNumGroupsInit; + mLoadingDescriptionElement->setCaption("Parsing scripts..."); + mWindow->update(); + } + void scriptParseStarted(const String& scriptName, bool &skipThisScript) + { + mLoadingCommentElement->setCaption(scriptName); + mWindow->update(); + } + void scriptParseEnded(const String& scriptName, bool skipped) + { + mLoadingBarElement->setWidth( + mLoadingBarElement->getWidth() + mProgressBarInc); + mWindow->update(); + } + void resourceGroupScriptingEnded(const String& groupName) + { + } + void resourceGroupLoadStarted(const String& groupName, size_t resourceCount) + { + assert(mNumGroupsLoad > 0 && "You stated you were not going to load " + "any groups, but you did! Divide by zero would follow..."); + mProgressBarInc = mProgressBarMaxSize * (1-mInitProportion) / + (Real)resourceCount; + mProgressBarInc /= mNumGroupsLoad; + mLoadingDescriptionElement->setCaption("Loading resources..."); + mWindow->update(); + } + void resourceLoadStarted(const ResourcePtr& resource) + { + mLoadingCommentElement->setCaption(resource->getName()); + mWindow->update(); + } + void resourceLoadEnded(void) + { + } + void worldGeometryStageStarted(const String& description) + { + mLoadingCommentElement->setCaption(description); + mWindow->update(); + } + void worldGeometryStageEnded(void) + { + mLoadingBarElement->setWidth( + mLoadingBarElement->getWidth() + mProgressBarInc); + mWindow->update(); + } + void resourceGroupLoadEnded(const String& groupName) + { + } + + Ogre::DataStreamPtr resourceLoading(const String &name, const String &group, Resource *resource) + { + return Ogre::DataStreamPtr(); + } + + bool resourceCollision(ResourcePtr &resource, ResourceManager *resourceManager) + { + return false; + } }; diff --git a/Samples/Common/include/InputContext.h b/Samples/Common/include/InputContext.h index 14e011e66fa..164f238ac3b 100644 --- a/Samples/Common/include/InputContext.h +++ b/Samples/Common/include/InputContext.h @@ -30,84 +30,84 @@ #include "OIS.h" -#if OIS_VERSION >= 0x010300 // OIS_VERSION >= 1.3.0 -#define OIS_WITH_MULTITOUCH 1 -#else // OIS_VERSION == 1.2.0 -#define OIS_WITH_MULTITOUCH 0 +#if OIS_VERSION >= 0x010300 // OIS_VERSION >= 1.3.0 +#define OIS_WITH_MULTITOUCH 1 +#else // OIS_VERSION == 1.2.0 +#define OIS_WITH_MULTITOUCH 0 #endif namespace OgreBites { - /*============================================================================= - | Utility structure for passing OIS devices. Does not own them. - =============================================================================*/ - struct InputContext - { - InputContext() - { - mKeyboard = 0; - mMouse = 0; + /*============================================================================= + | Utility structure for passing OIS devices. Does not own them. + =============================================================================*/ + struct InputContext + { + InputContext() + { + mKeyboard = 0; + mMouse = 0; #if OIS_WITH_MULTITOUCH - mMultiTouch = 0; + mMultiTouch = 0; #endif - mAccelerometer = 0; - } + mAccelerometer = 0; + } - void capture() const - { - if(mKeyboard) - mKeyboard->capture(); - if(mMouse) - mMouse->capture(); + void capture() const + { + if(mKeyboard) + mKeyboard->capture(); + if(mMouse) + mMouse->capture(); #if OIS_WITH_MULTITOUCH - if(mMultiTouch) - mMultiTouch->capture(); + if(mMultiTouch) + mMultiTouch->capture(); #endif - if(mAccelerometer) - mAccelerometer->capture(); - } + if(mAccelerometer) + mAccelerometer->capture(); + } - bool isKeyDown(OIS::KeyCode key) const - { - return mKeyboard && mKeyboard->isKeyDown(key); - } + bool isKeyDown(OIS::KeyCode key) const + { + return mKeyboard && mKeyboard->isKeyDown(key); + } - bool getCursorPosition(Ogre::Real& x, Ogre::Real& y) const - { - // prefer mouse - if(mMouse) - { - x = (Ogre::Real)mMouse->getMouseState().X.abs; - y = (Ogre::Real)mMouse->getMouseState().Y.abs; - return true; - } - + bool getCursorPosition(Ogre::Real& x, Ogre::Real& y) const + { + // prefer mouse + if(mMouse) + { + x = (Ogre::Real)mMouse->getMouseState().X.abs; + y = (Ogre::Real)mMouse->getMouseState().Y.abs; + return true; + } + #if OIS_WITH_MULTITOUCH - // than touch device - if(mMultiTouch) - { - std::vector states = mMultiTouch->getMultiTouchStates(); - if(states.size() > 0) - { - x = (Ogre::Real)states[0].X.abs; - y = (Ogre::Real)states[0].Y.abs; - return true; - } - } + // than touch device + if(mMultiTouch) + { + std::vector states = mMultiTouch->getMultiTouchStates(); + if(states.size() > 0) + { + x = (Ogre::Real)states[0].X.abs; + y = (Ogre::Real)states[0].Y.abs; + return true; + } + } #endif - // fallback - x = y = 0.0; - return false; - } + // fallback + x = y = 0.0; + return false; + } - OIS::Keyboard* mKeyboard; // context keyboard device - OIS::Mouse* mMouse; // context mouse device + OIS::Keyboard* mKeyboard; // context keyboard device + OIS::Mouse* mMouse; // context mouse device #if OIS_WITH_MULTITOUCH - OIS::MultiTouch* mMultiTouch; // context multitouch device + OIS::MultiTouch* mMultiTouch; // context multitouch device #endif - OIS::JoyStick* mAccelerometer; // context accelerometer device - }; + OIS::JoyStick* mAccelerometer; // context accelerometer device + }; } #endif diff --git a/Samples/Common/include/OgreStaticPluginLoader.h b/Samples/Common/include/OgreStaticPluginLoader.h index 1c3e63b5d1d..b61687e44c8 100644 --- a/Samples/Common/include/OgreStaticPluginLoader.h +++ b/Samples/Common/include/OgreStaticPluginLoader.h @@ -65,155 +65,155 @@ Description: Utility class to load plugins statically namespace Ogre { - /** Utility class for loading some plugins statically. - @remarks - When loading plugins statically, you are limited to loading plugins - that are known about at compile time. You should define preprocessor - symbols depending on which plugins you want to load - the symbol being - OGRE_STATIC_, with pluginname being the usual name of the - plugin DLL (no file extension, no debug suffix, and without the Plugin_ - or RenderSystem_ prefix.) - */ - class StaticPluginLoader - { - protected: + /** Utility class for loading some plugins statically. + @remarks + When loading plugins statically, you are limited to loading plugins + that are known about at compile time. You should define preprocessor + symbols depending on which plugins you want to load - the symbol being + OGRE_STATIC_, with pluginname being the usual name of the + plugin DLL (no file extension, no debug suffix, and without the Plugin_ + or RenderSystem_ prefix.) + */ + class StaticPluginLoader + { + protected: #ifdef OGRE_STATIC_CgProgramManager - CgPlugin* mCgPlugin; + CgPlugin* mCgPlugin; #endif #ifdef OGRE_STATIC_OctreeSceneManager - OctreePlugin* mOctreePlugin; + OctreePlugin* mOctreePlugin; #endif #ifdef OGRE_STATIC_ParticleFX - ParticleFXPlugin* mParticleFXPlugin; + ParticleFXPlugin* mParticleFXPlugin; #endif #ifdef OGRE_STATIC_BSPSceneManager - BspSceneManagerPlugin* mBSPPlugin; + BspSceneManagerPlugin* mBSPPlugin; #endif #ifdef OGRE_STATIC_PCZSceneManager - PCZPlugin* mPCZPlugin; + PCZPlugin* mPCZPlugin; #endif #ifdef OGRE_STATIC_OctreeZone - OctreeZonePlugin* mOctreeZonePlugin; + OctreeZonePlugin* mOctreeZonePlugin; #endif #ifdef OGRE_STATIC_GL - GLPlugin* mGLPlugin; + GLPlugin* mGLPlugin; #endif #ifdef OGRE_STATIC_GL3Plus - GL3PlusPlugin* mGL3PlusPlugin; + GL3PlusPlugin* mGL3PlusPlugin; #endif #ifdef OGRE_STATIC_GLES - GLESPlugin* mGLESPlugin; + GLESPlugin* mGLESPlugin; #endif #ifdef OGRE_STATIC_GLES2 - GLES2Plugin* mGLES2Plugin; + GLES2Plugin* mGLES2Plugin; #endif #ifdef OGRE_STATIC_Direct3D9 - D3D9Plugin* mD3D9Plugin; + D3D9Plugin* mD3D9Plugin; #endif #ifdef OGRE_STATIC_Direct3D11 - D3D11Plugin* mD3D11Plugin; + D3D11Plugin* mD3D11Plugin; #endif - public: - StaticPluginLoader() {} + public: + StaticPluginLoader() {} - /** Load all the enabled plugins against the passed in root object. */ - void load() - { - Root& root = Root::getSingleton(); + /** Load all the enabled plugins against the passed in root object. */ + void load() + { + Root& root = Root::getSingleton(); #ifdef OGRE_STATIC_GL - mGLPlugin = OGRE_NEW GLPlugin(); - root.installPlugin(mGLPlugin); + mGLPlugin = OGRE_NEW GLPlugin(); + root.installPlugin(mGLPlugin); #endif #ifdef OGRE_STATIC_GL3Plus - mGL3PlusPlugin = OGRE_NEW GL3PlusPlugin(); - root.installPlugin(mGL3PlusPlugin); + mGL3PlusPlugin = OGRE_NEW GL3PlusPlugin(); + root.installPlugin(mGL3PlusPlugin); #endif #ifdef OGRE_STATIC_GLES - mGLESPlugin = OGRE_NEW GLESPlugin(); - root.installPlugin(mGLESPlugin); + mGLESPlugin = OGRE_NEW GLESPlugin(); + root.installPlugin(mGLESPlugin); #endif #ifdef OGRE_STATIC_GLES2 - mGLES2Plugin = OGRE_NEW GLES2Plugin(); - root.installPlugin(mGLES2Plugin); + mGLES2Plugin = OGRE_NEW GLES2Plugin(); + root.installPlugin(mGLES2Plugin); #endif #ifdef OGRE_STATIC_Direct3D9 - mD3D9Plugin = OGRE_NEW D3D9Plugin(); - root.installPlugin(mD3D9Plugin); + mD3D9Plugin = OGRE_NEW D3D9Plugin(); + root.installPlugin(mD3D9Plugin); #endif #ifdef OGRE_STATIC_Direct3D11 - mD3D11Plugin = OGRE_NEW D3D11Plugin(); - root.installPlugin(mD3D11Plugin); + mD3D11Plugin = OGRE_NEW D3D11Plugin(); + root.installPlugin(mD3D11Plugin); #endif #ifdef OGRE_STATIC_CgProgramManager - mCgPlugin = OGRE_NEW CgPlugin(); - root.installPlugin(mCgPlugin); + mCgPlugin = OGRE_NEW CgPlugin(); + root.installPlugin(mCgPlugin); #endif #ifdef OGRE_STATIC_OctreeSceneManager - mOctreePlugin = OGRE_NEW OctreePlugin(); - root.installPlugin(mOctreePlugin); + mOctreePlugin = OGRE_NEW OctreePlugin(); + root.installPlugin(mOctreePlugin); #endif #ifdef OGRE_STATIC_ParticleFX - mParticleFXPlugin = OGRE_NEW ParticleFXPlugin(); - root.installPlugin(mParticleFXPlugin); + mParticleFXPlugin = OGRE_NEW ParticleFXPlugin(); + root.installPlugin(mParticleFXPlugin); #endif #ifdef OGRE_STATIC_BSPSceneManager - mBSPPlugin = OGRE_NEW BspSceneManagerPlugin(); - root.installPlugin(mBSPPlugin); + mBSPPlugin = OGRE_NEW BspSceneManagerPlugin(); + root.installPlugin(mBSPPlugin); #endif #ifdef OGRE_STATIC_PCZSceneManager - mPCZPlugin = OGRE_NEW PCZPlugin(); - root.installPlugin(mPCZPlugin); + mPCZPlugin = OGRE_NEW PCZPlugin(); + root.installPlugin(mPCZPlugin); #endif #ifdef OGRE_STATIC_OctreeZone - mOctreeZonePlugin = OGRE_NEW OctreeZonePlugin(); - root.installPlugin(mOctreeZonePlugin); + mOctreeZonePlugin = OGRE_NEW OctreeZonePlugin(); + root.installPlugin(mOctreeZonePlugin); #endif - } + } - void unload() - { - // don't unload plugins, since Root will have done that. Destroy here. + void unload() + { + // don't unload plugins, since Root will have done that. Destroy here. #ifdef OGRE_STATIC_OctreeZone - OGRE_DELETE mOctreeZonePlugin; + OGRE_DELETE mOctreeZonePlugin; #endif #ifdef OGRE_STATIC_PCZSceneManager - OGRE_DELETE mPCZPlugin; + OGRE_DELETE mPCZPlugin; #endif #ifdef OGRE_STATIC_BSPSceneManager - OGRE_DELETE mBSPPlugin; + OGRE_DELETE mBSPPlugin; #endif #ifdef OGRE_STATIC_ParticleFX - OGRE_DELETE mParticleFXPlugin; + OGRE_DELETE mParticleFXPlugin; #endif #ifdef OGRE_STATIC_OctreeSceneManager - OGRE_DELETE mOctreePlugin; + OGRE_DELETE mOctreePlugin; #endif #ifdef OGRE_STATIC_CgProgramManager - OGRE_DELETE mCgPlugin; + OGRE_DELETE mCgPlugin; #endif #ifdef OGRE_STATIC_Direct3D9 - OGRE_DELETE mD3D9Plugin; + OGRE_DELETE mD3D9Plugin; #endif #ifdef OGRE_STATIC_Direct3D11 - OGRE_DELETE mD3D11Plugin; + OGRE_DELETE mD3D11Plugin; #endif #ifdef OGRE_STATIC_GL - OGRE_DELETE mGLPlugin; + OGRE_DELETE mGLPlugin; #endif #ifdef OGRE_STATIC_GL3Plus - OGRE_DELETE mGL3PlusPlugin; + OGRE_DELETE mGL3PlusPlugin; #endif #ifdef OGRE_STATIC_GLES - OGRE_DELETE mGLESPlugin; + OGRE_DELETE mGLESPlugin; #endif #ifdef OGRE_STATIC_GLES2 - OGRE_DELETE mGLES2Plugin; + OGRE_DELETE mGLES2Plugin; #endif - } + } - }; + }; } diff --git a/Samples/Common/include/Sample.h b/Samples/Common/include/Sample.h index 9ac4eda9dc9..ec8242632ae 100644 --- a/Samples/Common/include/Sample.h +++ b/Samples/Common/include/Sample.h @@ -36,11 +36,11 @@ #include "OgreFileSystemLayer.h" #ifdef INCLUDE_RTSHADER_SYSTEM -# include "OgreRTShaderSystem.h" +# include "OgreRTShaderSystem.h" #endif //INCLUDE_RTSHADER_SYSTEM #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS -# include "macUtils.h" +# include "macUtils.h" #endif #if OGRE_PLATFORM == OGRE_PLATFORM_NACL && !defined(INCLUDE_RTSHADER_SYSTEM) @@ -51,265 +51,265 @@ namespace OgreBites { - /*============================================================================= - | Base class responsible for everything specific to one sample. - | Designed to be subclassed for each sample. - =============================================================================*/ - class Sample : public Ogre::GeneralAllocatedObject + /*============================================================================= + | Base class responsible for everything specific to one sample. + | Designed to be subclassed for each sample. + =============================================================================*/ + class Sample : public Ogre::GeneralAllocatedObject { public: - /*============================================================================= - | Utility comparison structure for sorting samples using SampleSet. - =============================================================================*/ - struct Comparer - { - bool operator() (Sample* a, Sample* b) - { - Ogre::NameValuePairList::iterator aTitle = a->getInfo().find("Title"); - Ogre::NameValuePairList::iterator bTitle = b->getInfo().find("Title"); - - if (aTitle != a->getInfo().end() && bTitle != b->getInfo().end()) - return aTitle->second.compare(bTitle->second) < 0; - else return false; - } - }; + /*============================================================================= + | Utility comparison structure for sorting samples using SampleSet. + =============================================================================*/ + struct Comparer + { + bool operator() (Sample* a, Sample* b) + { + Ogre::NameValuePairList::iterator aTitle = a->getInfo().find("Title"); + Ogre::NameValuePairList::iterator bTitle = b->getInfo().find("Title"); + + if (aTitle != a->getInfo().end() && bTitle != b->getInfo().end()) + return aTitle->second.compare(bTitle->second) < 0; + else return false; + } + }; #ifdef INCLUDE_RTSHADER_SYSTEM - Sample() : mShaderGenerator(0) + Sample() : mShaderGenerator(0) #else - Sample() + Sample() #endif { - mRoot = Ogre::Root::getSingletonPtr(); - mWindow = 0; - mSceneMgr = 0; - mDone = true; - mResourcesLoaded = false; - mContentSetup = false; - - mFSLayer = 0; + mRoot = Ogre::Root::getSingletonPtr(); + mWindow = 0; + mSceneMgr = 0; + mDone = true; + mResourcesLoaded = false; + mContentSetup = false; + + mFSLayer = 0; mOverlaySystem = 0; } - virtual ~Sample() {} - - /*----------------------------------------------------------------------------- - | Retrieves custom sample info. - -----------------------------------------------------------------------------*/ - Ogre::NameValuePairList& getInfo() - { - return mInfo; - } - - /*----------------------------------------------------------------------------- - | Tests to see if target machine meets any special requirements of - | this sample. Signal a failure by throwing an exception. - -----------------------------------------------------------------------------*/ - virtual void testCapabilities(const Ogre::RenderSystemCapabilities* caps) {} - - /*----------------------------------------------------------------------------- - | If this sample requires a specific render system to run, this method - | will be used to return its name. - -----------------------------------------------------------------------------*/ - virtual Ogre::String getRequiredRenderSystem() - { - return ""; - } - - /*----------------------------------------------------------------------------- - | If this sample requires specific plugins to run, this method will be - | used to return their names. - -----------------------------------------------------------------------------*/ - virtual Ogre::StringVector getRequiredPlugins() - { - return Ogre::StringVector(); - } - - Ogre::SceneManager* getSceneManager() - { - return mSceneMgr; - } - - bool isDone() - { - return mDone; - } - - /*----------------------------------------------------------------------------- - | Sets up a sample. Used by the SampleContext class. Do not call directly. - -----------------------------------------------------------------------------*/ - virtual void _setup(Ogre::RenderWindow* window, InputContext inputContext, Ogre::FileSystemLayer* fsLayer, Ogre::OverlaySystem* overlaySys) - { - // assign mRoot here in case Root was initialised after the Sample's constructor ran. - mRoot = Ogre::Root::getSingletonPtr(); - mOverlaySystem = overlaySys; - mWindow = window; - mInputContext = inputContext; - mFSLayer = fsLayer; - - locateResources(); - createSceneManager(); - setupView(); - - loadResources(); - mResourcesLoaded = true; - setupContent(); - mContentSetup = true; - - mDone = false; - } - - /*----------------------------------------------------------------------------- - | Shuts down a sample. Used by the SampleContext class. Do not call directly. - -----------------------------------------------------------------------------*/ - virtual void _shutdown() - - { - if (mContentSetup) + virtual ~Sample() {} + + /*----------------------------------------------------------------------------- + | Retrieves custom sample info. + -----------------------------------------------------------------------------*/ + Ogre::NameValuePairList& getInfo() + { + return mInfo; + } + + /*----------------------------------------------------------------------------- + | Tests to see if target machine meets any special requirements of + | this sample. Signal a failure by throwing an exception. + -----------------------------------------------------------------------------*/ + virtual void testCapabilities(const Ogre::RenderSystemCapabilities* caps) {} + + /*----------------------------------------------------------------------------- + | If this sample requires a specific render system to run, this method + | will be used to return its name. + -----------------------------------------------------------------------------*/ + virtual Ogre::String getRequiredRenderSystem() + { + return ""; + } + + /*----------------------------------------------------------------------------- + | If this sample requires specific plugins to run, this method will be + | used to return their names. + -----------------------------------------------------------------------------*/ + virtual Ogre::StringVector getRequiredPlugins() + { + return Ogre::StringVector(); + } + + Ogre::SceneManager* getSceneManager() + { + return mSceneMgr; + } + + bool isDone() + { + return mDone; + } + + /*----------------------------------------------------------------------------- + | Sets up a sample. Used by the SampleContext class. Do not call directly. + -----------------------------------------------------------------------------*/ + virtual void _setup(Ogre::RenderWindow* window, InputContext inputContext, Ogre::FileSystemLayer* fsLayer, Ogre::OverlaySystem* overlaySys) + { + // assign mRoot here in case Root was initialised after the Sample's constructor ran. + mRoot = Ogre::Root::getSingletonPtr(); + mOverlaySystem = overlaySys; + mWindow = window; + mInputContext = inputContext; + mFSLayer = fsLayer; + + locateResources(); + createSceneManager(); + setupView(); + + loadResources(); + mResourcesLoaded = true; + setupContent(); + mContentSetup = true; + + mDone = false; + } + + /*----------------------------------------------------------------------------- + | Shuts down a sample. Used by the SampleContext class. Do not call directly. + -----------------------------------------------------------------------------*/ + virtual void _shutdown() + + { + if (mContentSetup) cleanupContent(); - if (mSceneMgr) + if (mSceneMgr) mSceneMgr->clearScene(); - mContentSetup = false; + mContentSetup = false; - if (mResourcesLoaded) + if (mResourcesLoaded) unloadResources(); - mResourcesLoaded = false; - if (mSceneMgr) - { + mResourcesLoaded = false; + if (mSceneMgr) + { #ifdef INCLUDE_RTSHADER_SYSTEM - mShaderGenerator->removeSceneManager(mSceneMgr); + mShaderGenerator->removeSceneManager(mSceneMgr); #endif - mSceneMgr->removeRenderQueueListener(mOverlaySystem); - mRoot->destroySceneManager(mSceneMgr); - } - mSceneMgr = 0; - - mDone = true; - } - - /*----------------------------------------------------------------------------- - | Actions to perform when the context stops sending frame listener events - | and input device events to this sample. - -----------------------------------------------------------------------------*/ - virtual void paused() {} - - /*----------------------------------------------------------------------------- - | Actions to perform when the context continues sending frame listener - | events and input device events to this sample. - -----------------------------------------------------------------------------*/ - virtual void unpaused() {} - - /*----------------------------------------------------------------------------- - | Saves the sample state. Optional. Used during reconfiguration. - -----------------------------------------------------------------------------*/ - virtual void saveState(Ogre::NameValuePairList& state) {} - - /*----------------------------------------------------------------------------- - | Restores the sample state. Optional. Used during reconfiguration. - -----------------------------------------------------------------------------*/ - virtual void restoreState(Ogre::NameValuePairList& state) {} - - // callback interface copied from various listeners to be used by SampleContext - - virtual bool frameStarted(const Ogre::FrameEvent& evt) { return true; } - virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt) { return true; } - virtual bool frameEnded(const Ogre::FrameEvent& evt) { return true; } - virtual void windowMoved(Ogre::RenderWindow* rw) {} - virtual void windowResized(Ogre::RenderWindow* rw) {} - virtual bool windowClosing(Ogre::RenderWindow* rw) { return true; } - virtual void windowClosed(Ogre::RenderWindow* rw) {} - virtual void windowFocusChange(Ogre::RenderWindow* rw) {} - virtual bool keyPressed(const OIS::KeyEvent& evt) { return true; } - virtual bool keyReleased(const OIS::KeyEvent& evt) { return true; } + mSceneMgr->removeRenderQueueListener(mOverlaySystem); + mRoot->destroySceneManager(mSceneMgr); + } + mSceneMgr = 0; + + mDone = true; + } + + /*----------------------------------------------------------------------------- + | Actions to perform when the context stops sending frame listener events + | and input device events to this sample. + -----------------------------------------------------------------------------*/ + virtual void paused() {} + + /*----------------------------------------------------------------------------- + | Actions to perform when the context continues sending frame listener + | events and input device events to this sample. + -----------------------------------------------------------------------------*/ + virtual void unpaused() {} + + /*----------------------------------------------------------------------------- + | Saves the sample state. Optional. Used during reconfiguration. + -----------------------------------------------------------------------------*/ + virtual void saveState(Ogre::NameValuePairList& state) {} + + /*----------------------------------------------------------------------------- + | Restores the sample state. Optional. Used during reconfiguration. + -----------------------------------------------------------------------------*/ + virtual void restoreState(Ogre::NameValuePairList& state) {} + + // callback interface copied from various listeners to be used by SampleContext + + virtual bool frameStarted(const Ogre::FrameEvent& evt) { return true; } + virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt) { return true; } + virtual bool frameEnded(const Ogre::FrameEvent& evt) { return true; } + virtual void windowMoved(Ogre::RenderWindow* rw) {} + virtual void windowResized(Ogre::RenderWindow* rw) {} + virtual bool windowClosing(Ogre::RenderWindow* rw) { return true; } + virtual void windowClosed(Ogre::RenderWindow* rw) {} + virtual void windowFocusChange(Ogre::RenderWindow* rw) {} + virtual bool keyPressed(const OIS::KeyEvent& evt) { return true; } + virtual bool keyReleased(const OIS::KeyEvent& evt) { return true; } #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - virtual bool touchMoved(const OIS::MultiTouchEvent& evt) { return true; } - virtual bool touchPressed(const OIS::MultiTouchEvent& evt) { return true; } - virtual bool touchReleased(const OIS::MultiTouchEvent& evt) { return true; } + virtual bool touchMoved(const OIS::MultiTouchEvent& evt) { return true; } + virtual bool touchPressed(const OIS::MultiTouchEvent& evt) { return true; } + virtual bool touchReleased(const OIS::MultiTouchEvent& evt) { return true; } #else - virtual bool mouseMoved(const OIS::MouseEvent& evt) { return true; } - virtual bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id) { return true; } - virtual bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id) { return true; } + virtual bool mouseMoved(const OIS::MouseEvent& evt) { return true; } + virtual bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id) { return true; } + virtual bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id) { return true; } #endif protected: - /*----------------------------------------------------------------------------- - | Finds sample-specific resources. No such effort is made for most samples, - | but this is useful for special samples with large, exclusive resources. - -----------------------------------------------------------------------------*/ - virtual void locateResources() {} - - /*----------------------------------------------------------------------------- - | Loads sample-specific resources. No such effort is made for most samples, - | but this is useful for special samples with large, exclusive resources. - -----------------------------------------------------------------------------*/ - virtual void loadResources() {} - - /*----------------------------------------------------------------------------- - | Creates a scene manager for the sample. A generic one is the default, - | but many samples require a special kind of scene manager. - -----------------------------------------------------------------------------*/ - virtual void createSceneManager() - { - mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC); + /*----------------------------------------------------------------------------- + | Finds sample-specific resources. No such effort is made for most samples, + | but this is useful for special samples with large, exclusive resources. + -----------------------------------------------------------------------------*/ + virtual void locateResources() {} + + /*----------------------------------------------------------------------------- + | Loads sample-specific resources. No such effort is made for most samples, + | but this is useful for special samples with large, exclusive resources. + -----------------------------------------------------------------------------*/ + virtual void loadResources() {} + + /*----------------------------------------------------------------------------- + | Creates a scene manager for the sample. A generic one is the default, + | but many samples require a special kind of scene manager. + -----------------------------------------------------------------------------*/ + virtual void createSceneManager() + { + mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC); #ifdef INCLUDE_RTSHADER_SYSTEM - mShaderGenerator->addSceneManager(mSceneMgr); + mShaderGenerator->addSceneManager(mSceneMgr); #endif if(mOverlaySystem) mSceneMgr->addRenderQueueListener(mOverlaySystem); - } - - /*----------------------------------------------------------------------------- - | Sets up viewport layout and camera. - -----------------------------------------------------------------------------*/ - virtual void setupView() {} - - /*----------------------------------------------------------------------------- - | Sets up the scene (and anything else you want for the sample). - -----------------------------------------------------------------------------*/ - virtual void setupContent() {} - - /*----------------------------------------------------------------------------- - | Cleans up the scene (and anything else you used). - -----------------------------------------------------------------------------*/ - virtual void cleanupContent() {} - - /*----------------------------------------------------------------------------- - | Unloads sample-specific resources. My method here is simple and good - | enough for most small samples, but your needs may vary. - -----------------------------------------------------------------------------*/ - virtual void unloadResources() - { - Ogre::ResourceGroupManager::ResourceManagerIterator resMgrs = - Ogre::ResourceGroupManager::getSingleton().getResourceManagerIterator(); - - while (resMgrs.hasMoreElements()) - { - resMgrs.getNext()->unloadUnreferencedResources(); - } - } - - Ogre::Root* mRoot; // OGRE root object - Ogre::OverlaySystem* mOverlaySystem; // OverlaySystem - Ogre::RenderWindow* mWindow; // context render window - InputContext mInputContext; - Ogre::FileSystemLayer* mFSLayer; // file system abstraction layer - Ogre::SceneManager* mSceneMgr; // scene manager for this sample - Ogre::NameValuePairList mInfo; // custom sample info - bool mDone; // flag to mark the end of the sample - bool mResourcesLoaded; // whether or not resources have been loaded - bool mContentSetup; // whether or not scene was created + } + + /*----------------------------------------------------------------------------- + | Sets up viewport layout and camera. + -----------------------------------------------------------------------------*/ + virtual void setupView() {} + + /*----------------------------------------------------------------------------- + | Sets up the scene (and anything else you want for the sample). + -----------------------------------------------------------------------------*/ + virtual void setupContent() {} + + /*----------------------------------------------------------------------------- + | Cleans up the scene (and anything else you used). + -----------------------------------------------------------------------------*/ + virtual void cleanupContent() {} + + /*----------------------------------------------------------------------------- + | Unloads sample-specific resources. My method here is simple and good + | enough for most small samples, but your needs may vary. + -----------------------------------------------------------------------------*/ + virtual void unloadResources() + { + Ogre::ResourceGroupManager::ResourceManagerIterator resMgrs = + Ogre::ResourceGroupManager::getSingleton().getResourceManagerIterator(); + + while (resMgrs.hasMoreElements()) + { + resMgrs.getNext()->unloadUnreferencedResources(); + } + } + + Ogre::Root* mRoot; // OGRE root object + Ogre::OverlaySystem* mOverlaySystem; // OverlaySystem + Ogre::RenderWindow* mWindow; // context render window + InputContext mInputContext; + Ogre::FileSystemLayer* mFSLayer; // file system abstraction layer + Ogre::SceneManager* mSceneMgr; // scene manager for this sample + Ogre::NameValuePairList mInfo; // custom sample info + bool mDone; // flag to mark the end of the sample + bool mResourcesLoaded; // whether or not resources have been loaded + bool mContentSetup; // whether or not scene was created #ifdef INCLUDE_RTSHADER_SYSTEM - Ogre::RTShader::ShaderGenerator* mShaderGenerator; // The Shader generator instance. + Ogre::RTShader::ShaderGenerator* mShaderGenerator; // The Shader generator instance. public: - void setShaderGenerator(Ogre::RTShader::ShaderGenerator* shaderGenerator) - { - mShaderGenerator = shaderGenerator; - }; + void setShaderGenerator(Ogre::RTShader::ShaderGenerator* shaderGenerator) + { + mShaderGenerator = shaderGenerator; + }; #endif }; - typedef std::set SampleSet; + typedef std::set SampleSet; } #endif diff --git a/Samples/Common/include/SampleContext.h b/Samples/Common/include/SampleContext.h index 5164dea31c6..96e46cd0b25 100644 --- a/Samples/Common/include/SampleContext.h +++ b/Samples/Common/include/SampleContext.h @@ -52,7 +52,7 @@ # endif # if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WINRT # ifdef OGRE_BUILD_RENDERSYSTEM_D3D9 -# define OGRE_STATIC_Direct3D9 +# define OGRE_STATIC_Direct3D9 # endif // dx11 will only work on vista and above, so be careful about statically linking # ifdef OGRE_BUILD_RENDERSYSTEM_D3D11 @@ -102,128 +102,128 @@ namespace OgreBites { - /*============================================================================= - | Base class responsible for setting up a common context for samples. - | May be subclassed for specific sample types (not specific samples). - | Allows one sample to run at a time, while maintaining a sample queue. - =============================================================================*/ - class SampleContext : - public Ogre::FrameListener, - public Ogre::WindowEventListener, + /*============================================================================= + | Base class responsible for setting up a common context for samples. + | May be subclassed for specific sample types (not specific samples). + | Allows one sample to run at a time, while maintaining a sample queue. + =============================================================================*/ + class SampleContext : + public Ogre::FrameListener, + public Ogre::WindowEventListener, #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) - public OIS::KeyListener, - public OIS::MouseListener + public OIS::KeyListener, + public OIS::MouseListener #else public OIS::MultiTouchListener #endif - { - public: - - SampleContext() - { - mFSLayer = OGRE_NEW_T(Ogre::FileSystemLayer, Ogre::MEMCATEGORY_GENERAL)(OGRE_VERSION_NAME); - mRoot = 0; - mWindow = 0; - mCurrentSample = 0; - mOverlaySystem = 0; - mSamplePaused = false; - mFirstRun = true; - mLastRun = false; - mLastSample = 0; - mInputMgr = 0; - } - - virtual ~SampleContext() - { - OGRE_DELETE_T(mFSLayer, FileSystemLayer, Ogre::MEMCATEGORY_GENERAL); - } - - virtual Ogre::RenderWindow* getRenderWindow() - { - return mWindow; - } - - virtual Sample* getCurrentSample() - { - return mCurrentSample; - } - - /*----------------------------------------------------------------------------- - | Quits the current sample and starts a new one. - -----------------------------------------------------------------------------*/ - virtual void runSample(Sample* s) - { + { + public: + + SampleContext() + { + mFSLayer = OGRE_NEW_T(Ogre::FileSystemLayer, Ogre::MEMCATEGORY_GENERAL)(OGRE_VERSION_NAME); + mRoot = 0; + mWindow = 0; + mCurrentSample = 0; + mOverlaySystem = 0; + mSamplePaused = false; + mFirstRun = true; + mLastRun = false; + mLastSample = 0; + mInputMgr = 0; + } + + virtual ~SampleContext() + { + OGRE_DELETE_T(mFSLayer, FileSystemLayer, Ogre::MEMCATEGORY_GENERAL); + } + + virtual Ogre::RenderWindow* getRenderWindow() + { + return mWindow; + } + + virtual Sample* getCurrentSample() + { + return mCurrentSample; + } + + /*----------------------------------------------------------------------------- + | Quits the current sample and starts a new one. + -----------------------------------------------------------------------------*/ + virtual void runSample(Sample* s) + { #if OGRE_PROFILING Ogre::Profiler* prof = Ogre::Profiler::getSingletonPtr(); if (prof) prof->setEnabled(false); #endif - if (mCurrentSample) - { - mCurrentSample->_shutdown(); // quit current sample - mSamplePaused = false; // don't pause the next sample - } - - mWindow->removeAllViewports(); // wipe viewports - - if (s) - { - // retrieve sample's required plugins and currently installed plugins - Ogre::Root::PluginInstanceList ip = mRoot->getInstalledPlugins(); - Ogre::StringVector rp = s->getRequiredPlugins(); - - for (Ogre::StringVector::iterator j = rp.begin(); j != rp.end(); j++) - { - bool found = false; - // try to find the required plugin in the current installed plugins - for (Ogre::Root::PluginInstanceList::iterator k = ip.begin(); k != ip.end(); k++) - { - if ((*k)->getName() == *j) - { - found = true; - break; - } - } - if (!found) // throw an exception if a plugin is not found - { - Ogre::String desc = "Sample requires plugin: " + *j; - Ogre::String src = "SampleContext::runSample"; - OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED, desc, src); - } - } - - // throw an exception if samples requires the use of another renderer - Ogre::String rrs = s->getRequiredRenderSystem(); - if (!rrs.empty() && rrs != mRoot->getRenderSystem()->getName()) - { - Ogre::String desc = "Sample only runs with renderer: " + rrs; - Ogre::String src = "SampleContext::runSample"; - OGRE_EXCEPT(Ogre::Exception::ERR_INVALID_STATE, desc, src); - } - - // test system capabilities against sample requirements - s->testCapabilities(mRoot->getRenderSystem()->getCapabilities()); - - s->_setup(mWindow, mInputContext, mFSLayer, mOverlaySystem); // start new sample - } + if (mCurrentSample) + { + mCurrentSample->_shutdown(); // quit current sample + mSamplePaused = false; // don't pause the next sample + } + + mWindow->removeAllViewports(); // wipe viewports + + if (s) + { + // retrieve sample's required plugins and currently installed plugins + Ogre::Root::PluginInstanceList ip = mRoot->getInstalledPlugins(); + Ogre::StringVector rp = s->getRequiredPlugins(); + + for (Ogre::StringVector::iterator j = rp.begin(); j != rp.end(); j++) + { + bool found = false; + // try to find the required plugin in the current installed plugins + for (Ogre::Root::PluginInstanceList::iterator k = ip.begin(); k != ip.end(); k++) + { + if ((*k)->getName() == *j) + { + found = true; + break; + } + } + if (!found) // throw an exception if a plugin is not found + { + Ogre::String desc = "Sample requires plugin: " + *j; + Ogre::String src = "SampleContext::runSample"; + OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED, desc, src); + } + } + + // throw an exception if samples requires the use of another renderer + Ogre::String rrs = s->getRequiredRenderSystem(); + if (!rrs.empty() && rrs != mRoot->getRenderSystem()->getName()) + { + Ogre::String desc = "Sample only runs with renderer: " + rrs; + Ogre::String src = "SampleContext::runSample"; + OGRE_EXCEPT(Ogre::Exception::ERR_INVALID_STATE, desc, src); + } + + // test system capabilities against sample requirements + s->testCapabilities(mRoot->getRenderSystem()->getCapabilities()); + + s->_setup(mWindow, mInputContext, mFSLayer, mOverlaySystem); // start new sample + } #if OGRE_PROFILING if (prof) prof->setEnabled(true); #endif - mCurrentSample = s; - } + mCurrentSample = s; + } - /*----------------------------------------------------------------------------- - | This function initializes the render system and resources. - -----------------------------------------------------------------------------*/ - virtual void initApp( Sample* initialSample = 0 ) - { + /*----------------------------------------------------------------------------- + | This function initializes the render system and resources. + -----------------------------------------------------------------------------*/ + virtual void initApp( Sample* initialSample = 0 ) + { #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS createRoot(); - if (!oneTimeConfig()) return; + if (!oneTimeConfig()) return; if (!mFirstRun) mRoot->setRenderSystem(mRoot->getRenderSystemByName(mNextRenderer)); @@ -234,12 +234,12 @@ namespace OgreBites mRoot->saveConfig(); - Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets(); + Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets(); - // Clear event times - Ogre::Root::getSingleton().clearEventTimes(); + // Clear event times + Ogre::Root::getSingleton().clearEventTimes(); #elif OGRE_PLATFORM == OGRE_PLATFORM_ANDROID - createRoot(); + createRoot(); setup(); @@ -248,63 +248,63 @@ namespace OgreBites //mRoot->saveConfig(); - Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets(); + Ogre::Root::getSingleton().getRenderSystem()->_initRenderTargets(); - // Clear event times - Ogre::Root::getSingleton().clearEventTimes(); + // Clear event times + Ogre::Root::getSingleton().clearEventTimes(); #else - createRoot(); + createRoot(); #if OGRE_PLATFORM == OGRE_PLATFORM_NACL mNextRenderer = mRoot->getAvailableRenderers()[0]->getName(); #else - if (!oneTimeConfig()) return; + if (!oneTimeConfig()) return; #endif - // if the context was reconfigured, set requested renderer - if (!mFirstRun) mRoot->setRenderSystem(mRoot->getRenderSystemByName(mNextRenderer)); + // if the context was reconfigured, set requested renderer + if (!mFirstRun) mRoot->setRenderSystem(mRoot->getRenderSystemByName(mNextRenderer)); - setup(); + setup(); - // restore the last sample if there was one or, if not, start initial sample - if (!mFirstRun) recoverLastSample(); - else if (initialSample) runSample(initialSample); + // restore the last sample if there was one or, if not, start initial sample + if (!mFirstRun) recoverLastSample(); + else if (initialSample) runSample(initialSample); #endif - } + } - /*----------------------------------------------------------------------------- - | This function closes down the application - saves the configuration then - | shutdowns. - -----------------------------------------------------------------------------*/ - virtual void closeApp() - { + /*----------------------------------------------------------------------------- + | This function closes down the application - saves the configuration then + | shutdowns. + -----------------------------------------------------------------------------*/ + virtual void closeApp() + { #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID - shutdown(); + shutdown(); #else - mRoot->saveConfig(); - shutdown(); - if (mRoot) - { - OGRE_DELETE mOverlaySystem; - OGRE_DELETE mRoot; - } + mRoot->saveConfig(); + shutdown(); + if (mRoot) + { + OGRE_DELETE mOverlaySystem; + OGRE_DELETE mRoot; + } #ifdef OGRE_STATIC_LIB - mStaticPluginLoader.unload(); + mStaticPluginLoader.unload(); #endif #endif - } + } - /*----------------------------------------------------------------------------- - | This function encapsulates the entire lifetime of the context. - -----------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------- + | This function encapsulates the entire lifetime of the context. + -----------------------------------------------------------------------------*/ #if OGRE_PLATFORM != OGRE_PLATFORM_NACL - virtual void go(Sample* initialSample = 0) - { + virtual void go(Sample* initialSample = 0) + { #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS || ((OGRE_PLATFORM == OGRE_PLATFORM_APPLE) && __LP64__) createRoot(); - if (!oneTimeConfig()) return; + if (!oneTimeConfig()) return; if (!mFirstRun) mRoot->setRenderSystem(mRoot->getRenderSystemByName(mNextRenderer)); @@ -317,142 +317,142 @@ namespace OgreBites mRoot->saveConfig(); #else - while (!mLastRun) - { - mLastRun = true; // assume this is our last run + while (!mLastRun) + { + mLastRun = true; // assume this is our last run - initApp(initialSample); + initApp(initialSample); loadStartUpSample(); if (mRoot->getRenderSystem() != NULL) { - mRoot->startRendering(); // start the render loop + mRoot->startRendering(); // start the render loop } - closeApp(); + closeApp(); - mFirstRun = false; - } + mFirstRun = false; + } #endif - } + } #endif virtual void loadStartUpSample() {} - virtual bool isCurrentSamplePaused() - { - if (mCurrentSample) return mSamplePaused; - return false; - } - - virtual void pauseCurrentSample() - { - if (mCurrentSample && !mSamplePaused) - { - mSamplePaused = true; - mCurrentSample->paused(); - } - } - - virtual void unpauseCurrentSample() - { - if (mCurrentSample && mSamplePaused) - { - mSamplePaused = false; - mCurrentSample->unpaused(); - } - } - - /*----------------------------------------------------------------------------- - | Processes frame started events. - -----------------------------------------------------------------------------*/ - virtual bool frameStarted(const Ogre::FrameEvent& evt) - { - captureInputDevices(); // capture input - - // manually call sample callback to ensure correct order - return (mCurrentSample && !mSamplePaused) ? mCurrentSample->frameStarted(evt) : true; - } - - /*----------------------------------------------------------------------------- - | Processes rendering queued events. - -----------------------------------------------------------------------------*/ - virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt) - { - // manually call sample callback to ensure correct order - return (mCurrentSample && !mSamplePaused) ? mCurrentSample->frameRenderingQueued(evt) : true; - } - - /*----------------------------------------------------------------------------- - | Processes frame ended events. - -----------------------------------------------------------------------------*/ - virtual bool frameEnded(const Ogre::FrameEvent& evt) - { - // manually call sample callback to ensure correct order - if (mCurrentSample && !mSamplePaused && !mCurrentSample->frameEnded(evt)) return false; - // quit if window was closed - if (mWindow->isClosed()) return false; - // go into idle mode if current sample has ended - if (mCurrentSample && mCurrentSample->isDone()) runSample(0); - - return true; - } - - /*----------------------------------------------------------------------------- - | Processes window size change event. Adjusts mouse's region to match that - | of the window. You could also override this method to prevent resizing. - -----------------------------------------------------------------------------*/ - virtual void windowResized(Ogre::RenderWindow* rw) - { - // manually call sample callback to ensure correct order - if (mCurrentSample && !mSamplePaused) mCurrentSample->windowResized(rw); + virtual bool isCurrentSamplePaused() + { + if (mCurrentSample) return mSamplePaused; + return false; + } + + virtual void pauseCurrentSample() + { + if (mCurrentSample && !mSamplePaused) + { + mSamplePaused = true; + mCurrentSample->paused(); + } + } + + virtual void unpauseCurrentSample() + { + if (mCurrentSample && mSamplePaused) + { + mSamplePaused = false; + mCurrentSample->unpaused(); + } + } + + /*----------------------------------------------------------------------------- + | Processes frame started events. + -----------------------------------------------------------------------------*/ + virtual bool frameStarted(const Ogre::FrameEvent& evt) + { + captureInputDevices(); // capture input + + // manually call sample callback to ensure correct order + return (mCurrentSample && !mSamplePaused) ? mCurrentSample->frameStarted(evt) : true; + } + + /*----------------------------------------------------------------------------- + | Processes rendering queued events. + -----------------------------------------------------------------------------*/ + virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt) + { + // manually call sample callback to ensure correct order + return (mCurrentSample && !mSamplePaused) ? mCurrentSample->frameRenderingQueued(evt) : true; + } + + /*----------------------------------------------------------------------------- + | Processes frame ended events. + -----------------------------------------------------------------------------*/ + virtual bool frameEnded(const Ogre::FrameEvent& evt) + { + // manually call sample callback to ensure correct order + if (mCurrentSample && !mSamplePaused && !mCurrentSample->frameEnded(evt)) return false; + // quit if window was closed + if (mWindow->isClosed()) return false; + // go into idle mode if current sample has ended + if (mCurrentSample && mCurrentSample->isDone()) runSample(0); + + return true; + } + + /*----------------------------------------------------------------------------- + | Processes window size change event. Adjusts mouse's region to match that + | of the window. You could also override this method to prevent resizing. + -----------------------------------------------------------------------------*/ + virtual void windowResized(Ogre::RenderWindow* rw) + { + // manually call sample callback to ensure correct order + if (mCurrentSample && !mSamplePaused) mCurrentSample->windowResized(rw); #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) - if(mInputContext.mMouse) - { - const OIS::MouseState& ms = mInputContext.mMouse->getMouseState(); - ms.width = rw->getWidth(); - ms.height = rw->getHeight(); - } -#endif - } - - // window event callbacks which manually call their respective sample callbacks to ensure correct order - - virtual void windowMoved(Ogre::RenderWindow* rw) - { - if (mCurrentSample && !mSamplePaused) mCurrentSample->windowMoved(rw); - } - - virtual bool windowClosing(Ogre::RenderWindow* rw) - { - if (mCurrentSample && !mSamplePaused) return mCurrentSample->windowClosing(rw); - return true; - } - - virtual void windowClosed(Ogre::RenderWindow* rw) - { - if (mCurrentSample && !mSamplePaused) mCurrentSample->windowClosed(rw); - } - - virtual void windowFocusChange(Ogre::RenderWindow* rw) - { - if (mCurrentSample && !mSamplePaused) mCurrentSample->windowFocusChange(rw); - } - - // keyboard and mouse callbacks which manually call their respective sample callbacks to ensure correct order - - virtual bool keyPressed(const OIS::KeyEvent& evt) - { - if (mCurrentSample && !mSamplePaused) return mCurrentSample->keyPressed(evt); - return true; - } - - virtual bool keyReleased(const OIS::KeyEvent& evt) - { - if (mCurrentSample && !mSamplePaused) return mCurrentSample->keyReleased(evt); - return true; - } + if(mInputContext.mMouse) + { + const OIS::MouseState& ms = mInputContext.mMouse->getMouseState(); + ms.width = rw->getWidth(); + ms.height = rw->getHeight(); + } +#endif + } + + // window event callbacks which manually call their respective sample callbacks to ensure correct order + + virtual void windowMoved(Ogre::RenderWindow* rw) + { + if (mCurrentSample && !mSamplePaused) mCurrentSample->windowMoved(rw); + } + + virtual bool windowClosing(Ogre::RenderWindow* rw) + { + if (mCurrentSample && !mSamplePaused) return mCurrentSample->windowClosing(rw); + return true; + } + + virtual void windowClosed(Ogre::RenderWindow* rw) + { + if (mCurrentSample && !mSamplePaused) mCurrentSample->windowClosed(rw); + } + + virtual void windowFocusChange(Ogre::RenderWindow* rw) + { + if (mCurrentSample && !mSamplePaused) mCurrentSample->windowFocusChange(rw); + } + + // keyboard and mouse callbacks which manually call their respective sample callbacks to ensure correct order + + virtual bool keyPressed(const OIS::KeyEvent& evt) + { + if (mCurrentSample && !mSamplePaused) return mCurrentSample->keyPressed(evt); + return true; + } + + virtual bool keyReleased(const OIS::KeyEvent& evt) + { + if (mCurrentSample && !mSamplePaused) return mCurrentSample->keyReleased(evt); + return true; + } #if (OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0) #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) @@ -531,129 +531,129 @@ namespace OgreBites #endif #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - virtual bool touchMoved(const OIS::MultiTouchEvent& evt) - { - if (mCurrentSample && !mSamplePaused) return mCurrentSample->touchMoved(evt); - return true; - } + virtual bool touchMoved(const OIS::MultiTouchEvent& evt) + { + if (mCurrentSample && !mSamplePaused) return mCurrentSample->touchMoved(evt); + return true; + } #else - virtual bool mouseMoved(const OIS::MouseEvent& evt) - { + virtual bool mouseMoved(const OIS::MouseEvent& evt) + { if (mCurrentSample && !mSamplePaused) return mCurrentSample->mouseMoved(evt); - return true; - } + return true; + } #endif #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - virtual bool touchPressed(const OIS::MultiTouchEvent& evt) - { - if (mCurrentSample && !mSamplePaused) return mCurrentSample->touchPressed(evt); - return true; - } + virtual bool touchPressed(const OIS::MultiTouchEvent& evt) + { + if (mCurrentSample && !mSamplePaused) return mCurrentSample->touchPressed(evt); + return true; + } #else - virtual bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id) - { - if (mCurrentSample && !mSamplePaused) return mCurrentSample->mousePressed(evt, id); - return true; - } + virtual bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + { + if (mCurrentSample && !mSamplePaused) return mCurrentSample->mousePressed(evt, id); + return true; + } #endif #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - virtual bool touchReleased(const OIS::MultiTouchEvent& evt) - { - if (mCurrentSample && !mSamplePaused) return mCurrentSample->touchReleased(evt); - return true; - } + virtual bool touchReleased(const OIS::MultiTouchEvent& evt) + { + if (mCurrentSample && !mSamplePaused) return mCurrentSample->touchReleased(evt); + return true; + } #else - virtual bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id) - { - if (mCurrentSample && !mSamplePaused) return mCurrentSample->mouseReleased(evt, id); - return true; - } + virtual bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + { + if (mCurrentSample && !mSamplePaused) return mCurrentSample->mouseReleased(evt, id); + return true; + } #endif bool isFirstRun() { return mFirstRun; } void setFirstRun(bool flag) { mFirstRun = flag; } bool isLastRun() { return mLastRun; } void setLastRun(bool flag) { mLastRun = flag; } - protected: + protected: /*----------------------------------------------------------------------------- | Sets up the context after configuration. -----------------------------------------------------------------------------*/ - virtual void setup() - { - mWindow = createWindow(); - setupInput(); - locateResources(); - loadResources(); + virtual void setup() + { + mWindow = createWindow(); + setupInput(); + locateResources(); + loadResources(); - Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); + Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5); - // adds context as listener to process context-level (above the sample level) events - mRoot->addFrameListener(this); + // adds context as listener to process context-level (above the sample level) events + mRoot->addFrameListener(this); #if OGRE_PLATFORM != OGRE_PLATFORM_ANDROID - Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this); + Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this); #endif - } + } - /*----------------------------------------------------------------------------- - | Creates the OGRE root. - -----------------------------------------------------------------------------*/ - virtual void createRoot() - { + /*----------------------------------------------------------------------------- + | Creates the OGRE root. + -----------------------------------------------------------------------------*/ + virtual void createRoot() + { #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID - mRoot = Ogre::Root::getSingletonPtr(); + mRoot = Ogre::Root::getSingletonPtr(); #else Ogre::String pluginsPath = Ogre::BLANKSTRING; # ifndef OGRE_STATIC_LIB pluginsPath = mFSLayer->getConfigFilePath("plugins.cfg"); # endif - mRoot = OGRE_NEW Ogre::Root(pluginsPath, mFSLayer->getWritablePath("ogre.cfg"), - mFSLayer->getWritablePath("ogre.log")); + mRoot = OGRE_NEW Ogre::Root(pluginsPath, mFSLayer->getWritablePath("ogre.cfg"), + mFSLayer->getWritablePath("ogre.log")); # ifdef OGRE_STATIC_LIB mStaticPluginLoader.load(); # endif #endif - mOverlaySystem = OGRE_NEW Ogre::OverlaySystem(); - } - - /*----------------------------------------------------------------------------- - | Configures the startup settings for OGRE. I use the config dialog here, - | but you can also restore from a config file. Note that this only happens - | when you start the context, and not when you reset it. - -----------------------------------------------------------------------------*/ - virtual bool oneTimeConfig() - { - return mRoot->showConfigDialog(); - // return mRoot->restoreConfig(); - } - - /*----------------------------------------------------------------------------- - | Creates the render window to be used for this context. I use an auto-created - | window here, but you can also create an external window if you wish. - | Just don't forget to initialise the root. - -----------------------------------------------------------------------------*/ - virtual Ogre::RenderWindow* createWindow() - { - return mRoot->initialise(true); - } - - /*----------------------------------------------------------------------------- - | Sets up OIS input. - -----------------------------------------------------------------------------*/ - virtual void setupInput(bool nograb = false) - { + mOverlaySystem = OGRE_NEW Ogre::OverlaySystem(); + } + + /*----------------------------------------------------------------------------- + | Configures the startup settings for OGRE. I use the config dialog here, + | but you can also restore from a config file. Note that this only happens + | when you start the context, and not when you reset it. + -----------------------------------------------------------------------------*/ + virtual bool oneTimeConfig() + { + return mRoot->showConfigDialog(); + // return mRoot->restoreConfig(); + } + + /*----------------------------------------------------------------------------- + | Creates the render window to be used for this context. I use an auto-created + | window here, but you can also create an external window if you wish. + | Just don't forget to initialise the root. + -----------------------------------------------------------------------------*/ + virtual Ogre::RenderWindow* createWindow() + { + return mRoot->initialise(true); + } + + /*----------------------------------------------------------------------------- + | Sets up OIS input. + -----------------------------------------------------------------------------*/ + virtual void setupInput(bool nograb = false) + { #if OGRE_PLATFORM != OGRE_PLATFORM_ANDROID && OGRE_PLATFORM != OGRE_PLATFORM_WINRT - OIS::ParamList pl; - size_t winHandle = 0; - std::ostringstream winHandleStr; + OIS::ParamList pl; + size_t winHandle = 0; + std::ostringstream winHandleStr; - mWindow->getCustomAttribute("WINDOW", &winHandle); - winHandleStr << winHandle; + mWindow->getCustomAttribute("WINDOW", &winHandle); + winHandleStr << winHandle; - pl.insert(std::make_pair("WINDOW", winHandleStr.str())); + pl.insert(std::make_pair("WINDOW", winHandleStr.str())); if (nograb) { pl.insert(std::make_pair("x11_keyboard_grab", "false")); @@ -666,109 +666,109 @@ namespace OgreBites #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) // Pass the view to OIS so the contentScalingFactor can be used - std::ostringstream viewHandleStr; - size_t viewHandle = 0; - mWindow->getCustomAttribute("VIEW", &viewHandle); - viewHandleStr << viewHandle; + std::ostringstream viewHandleStr; + size_t viewHandle = 0; + mWindow->getCustomAttribute("VIEW", &viewHandle); + viewHandleStr << viewHandle; pl.insert(std::make_pair("VIEW", viewHandleStr.str())); #endif - mInputMgr = OIS::InputManager::createInputSystem(pl); + mInputMgr = OIS::InputManager::createInputSystem(pl); - createInputDevices(); // create the specific input devices + createInputDevices(); // create the specific input devices #endif - // attach input devices - windowResized(mWindow); // do an initial adjustment of mouse area + // attach input devices + windowResized(mWindow); // do an initial adjustment of mouse area #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) - if(mInputContext.mKeyboard) - mInputContext.mKeyboard->setEventCallback(this); - if(mInputContext.mMouse) - mInputContext.mMouse->setEventCallback(this); + if(mInputContext.mKeyboard) + mInputContext.mKeyboard->setEventCallback(this); + if(mInputContext.mMouse) + mInputContext.mMouse->setEventCallback(this); #else - if(mInputContext.mMultiTouch) - mInputContext.mMultiTouch->setEventCallback(this); -#endif - } - - /*----------------------------------------------------------------------------- - | Creates the individual input devices. I only create a keyboard and mouse - | here because they are the most common, but you can override this method - | for other modes and devices. - -----------------------------------------------------------------------------*/ - virtual void createInputDevices() - { + if(mInputContext.mMultiTouch) + mInputContext.mMultiTouch->setEventCallback(this); +#endif + } + + /*----------------------------------------------------------------------------- + | Creates the individual input devices. I only create a keyboard and mouse + | here because they are the most common, but you can override this method + | for other modes and devices. + -----------------------------------------------------------------------------*/ + virtual void createInputDevices() + { #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS - mInputContext.mMultiTouch = static_cast(mInputMgr->createInputObject(OIS::OISMultiTouch, true)); - mInputContext.mAccelerometer = static_cast(mInputMgr->createInputObject(OIS::OISJoyStick, true)); + mInputContext.mMultiTouch = static_cast(mInputMgr->createInputObject(OIS::OISMultiTouch, true)); + mInputContext.mAccelerometer = static_cast(mInputMgr->createInputObject(OIS::OISJoyStick, true)); #elif OGRE_PLATFORM == OGRE_PLATFORM_ANDROID - // nothing to do + // nothing to do #elif OGRE_PLATFORM == OGRE_PLATFORM_WINRT - // mInputMgr is NULL and input devices are already passed to us, therefore nothing to do - assert(mInputContext.mKeyboard); - assert(mInputContext.mMouse); + // mInputMgr is NULL and input devices are already passed to us, therefore nothing to do + assert(mInputContext.mKeyboard); + assert(mInputContext.mMouse); #else - mInputContext.mKeyboard = static_cast(mInputMgr->createInputObject(OIS::OISKeyboard, true)); - mInputContext.mMouse = static_cast(mInputMgr->createInputObject(OIS::OISMouse, true)); + mInputContext.mKeyboard = static_cast(mInputMgr->createInputObject(OIS::OISKeyboard, true)); + mInputContext.mMouse = static_cast(mInputMgr->createInputObject(OIS::OISMouse, true)); #endif - } + } - /*----------------------------------------------------------------------------- - | Finds context-wide resource groups. I load paths from a config file here, - | but you can choose your resource locations however you want. - -----------------------------------------------------------------------------*/ - virtual void locateResources() - { + /*----------------------------------------------------------------------------- + | Finds context-wide resource groups. I load paths from a config file here, + | but you can choose your resource locations however you want. + -----------------------------------------------------------------------------*/ + virtual void locateResources() + { #if OGRE_PLATFORM == OGRE_PLATFORM_NACL Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Essential.zip", "EmbeddedZip", "Essential"); Ogre::ResourceGroupManager::getSingleton().addResourceLocation("Popular.zip", "EmbeddedZip", "Popular"); #else - // load resource paths from config file - Ogre::ConfigFile cf; -# if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID + // load resource paths from config file + Ogre::ConfigFile cf; +# if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID cf.load(openAPKFile(mFSLayer->getConfigFilePath("resources.cfg"))); -# else - cf.load(mFSLayer->getConfigFilePath("resources.cfg")); -# endif - Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); - Ogre::String sec, type, arch; - - // go through all specified resource groups - while (seci.hasMoreElements()) - { - sec = seci.peekNextKey(); - Ogre::ConfigFile::SettingsMultiMap* settings = seci.getNext(); - Ogre::ConfigFile::SettingsMultiMap::iterator i; - - // go through all resource paths - for (i = settings->begin(); i != settings->end(); i++) - { - type = i->first; - arch = i->second; - - #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS +# else + cf.load(mFSLayer->getConfigFilePath("resources.cfg")); +# endif + Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator(); + Ogre::String sec, type, arch; + + // go through all specified resource groups + while (seci.hasMoreElements()) + { + sec = seci.peekNextKey(); + Ogre::ConfigFile::SettingsMultiMap* settings = seci.getNext(); + Ogre::ConfigFile::SettingsMultiMap::iterator i; + + // go through all resource paths + for (i = settings->begin(); i != settings->end(); i++) + { + type = i->first; + arch = i->second; + + #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS // OS X does not set the working directory relative to the app, // In order to make things portable on OS X we need to provide // the loading with it's own bundle path location - if (!Ogre::StringUtil::startsWith(arch, "/", false)) // only adjust relative dirs - arch = Ogre::String(Ogre::macBundlePath() + "/" + arch); - #endif - Ogre::ResourceGroupManager::getSingleton().addResourceLocation(arch, type, sec); - } - } + if (!Ogre::StringUtil::startsWith(arch, "/", false)) // only adjust relative dirs + arch = Ogre::String(Ogre::macBundlePath() + "/" + arch); + #endif + Ogre::ResourceGroupManager::getSingleton().addResourceLocation(arch, type, sec); + } + } const Ogre::ResourceGroupManager::LocationList genLocs = Ogre::ResourceGroupManager::getSingleton().getResourceLocationList("General"); arch = genLocs.front()->archive->getName(); -# if OGRE_PLATFORM != OGRE_PLATFORM_ANDROID -# if OGRE_PLATFORM == OGRE_PLATFORM_APPLE +# if OGRE_PLATFORM != OGRE_PLATFORM_ANDROID +# if OGRE_PLATFORM == OGRE_PLATFORM_APPLE arch = Ogre::macBundlePath() + "/Contents/Resources/Media"; -# elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS +# elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS arch = Ogre::macBundlePath() + "/Media"; -# else +# else arch = Ogre::StringUtil::replaceAll(arch, "Media/../../Tests/Media", ""); arch = Ogre::StringUtil::replaceAll(arch, "media/../../Tests/Media", ""); -# endif +# endif type = "FileSystem"; sec = "Popular"; @@ -797,11 +797,11 @@ namespace OgreBites { Ogre::ResourceGroupManager::getSingleton().addResourceLocation(arch + "/materials/programs/HLSL", type, sec); } -# ifdef OGRE_BUILD_PLUGIN_CG +# ifdef OGRE_BUILD_PLUGIN_CG Ogre::ResourceGroupManager::getSingleton().addResourceLocation(arch + "/materials/programs/Cg", type, sec); -# endif +# endif -# ifdef INCLUDE_RTSHADER_SYSTEM +# ifdef INCLUDE_RTSHADER_SYSTEM if(Ogre::GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) { Ogre::ResourceGroupManager::getSingleton().addResourceLocation(arch + "/RTShaderLib/GLSLES", type, sec); @@ -818,39 +818,39 @@ namespace OgreBites { Ogre::ResourceGroupManager::getSingleton().addResourceLocation(arch + "/RTShaderLib/HLSL", type, sec); } -# ifdef OGRE_BUILD_PLUGIN_CG +# ifdef OGRE_BUILD_PLUGIN_CG Ogre::ResourceGroupManager::getSingleton().addResourceLocation(arch + "/RTShaderLib/Cg", type, sec); -# endif -# endif /* INCLUDE_RTSHADER_SYSTEM */ -# endif /* OGRE_PLATFORM != OGRE_PLATFORM_ANDROID */ +# endif +# endif /* INCLUDE_RTSHADER_SYSTEM */ +# endif /* OGRE_PLATFORM != OGRE_PLATFORM_ANDROID */ #endif /* OGRE_PLATFORM == OGRE_PLATFORM_NACL */ - } - - /*----------------------------------------------------------------------------- - | Loads context-wide resource groups. I chose here to simply initialise all - | groups, but you can fully load specific ones if you wish. - -----------------------------------------------------------------------------*/ - virtual void loadResources() - { - Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - } - - /*----------------------------------------------------------------------------- - | Reconfigures the context. Attempts to preserve the current sample state. - -----------------------------------------------------------------------------*/ - virtual void reconfigure(const Ogre::String& renderer, Ogre::NameValuePairList& options) - { - // save current sample state - mLastSample = mCurrentSample; - if (mCurrentSample) mCurrentSample->saveState(mLastSampleState); - - mNextRenderer = renderer; - Ogre::RenderSystem* rs = mRoot->getRenderSystemByName(renderer); - - // set all given render system options - for (Ogre::NameValuePairList::iterator it = options.begin(); it != options.end(); it++) - { - rs->setConfigOption(it->first, it->second); + } + + /*----------------------------------------------------------------------------- + | Loads context-wide resource groups. I chose here to simply initialise all + | groups, but you can fully load specific ones if you wish. + -----------------------------------------------------------------------------*/ + virtual void loadResources() + { + Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + } + + /*----------------------------------------------------------------------------- + | Reconfigures the context. Attempts to preserve the current sample state. + -----------------------------------------------------------------------------*/ + virtual void reconfigure(const Ogre::String& renderer, Ogre::NameValuePairList& options) + { + // save current sample state + mLastSample = mCurrentSample; + if (mCurrentSample) mCurrentSample->saveState(mLastSampleState); + + mNextRenderer = renderer; + Ogre::RenderSystem* rs = mRoot->getRenderSystemByName(renderer); + + // set all given render system options + for (Ogre::NameValuePairList::iterator it = options.begin(); it != options.end(); it++) + { + rs->setConfigOption(it->first, it->second); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS // Change the viewport orientation on the fly if requested @@ -864,91 +864,91 @@ namespace OgreBites mWindow->getViewport(0)->setOrientationMode(Ogre::OR_PORTRAIT, true); } #endif - } + } #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS // Need to save the config on iOS to make sure that changes are kept on disk mRoot->saveConfig(); #endif - mLastRun = false; // we want to go again with the new settings - mRoot->queueEndRendering(); // break from render loop - } - - /*----------------------------------------------------------------------------- - | Recovers the last sample after a reset. You can override in the case that - | the last sample is destroyed in the process of resetting, and you have to - | recover it through another means. - -----------------------------------------------------------------------------*/ - virtual void recoverLastSample() - { - runSample(mLastSample); - mLastSample->restoreState(mLastSampleState); - mLastSample = 0; - mLastSampleState.clear(); - } - - /*----------------------------------------------------------------------------- - | Cleans up and shuts down the context. - -----------------------------------------------------------------------------*/ - virtual void shutdown() - { - if (mCurrentSample) - { - mCurrentSample->_shutdown(); - mCurrentSample = 0; - } - - // remove window event listener before shutting down OIS - Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this); - - shutdownInput(); - } - - /*----------------------------------------------------------------------------- - | Destroys OIS input devices and the input manager. - -----------------------------------------------------------------------------*/ - virtual void shutdownInput() - { - // detach input devices - windowResized(mWindow); // do an initial adjustment of mouse area - if(mInputContext.mKeyboard) - mInputContext.mKeyboard->setEventCallback(NULL); - if(mInputContext.mMouse) - mInputContext.mMouse->setEventCallback(NULL); + mLastRun = false; // we want to go again with the new settings + mRoot->queueEndRendering(); // break from render loop + } + + /*----------------------------------------------------------------------------- + | Recovers the last sample after a reset. You can override in the case that + | the last sample is destroyed in the process of resetting, and you have to + | recover it through another means. + -----------------------------------------------------------------------------*/ + virtual void recoverLastSample() + { + runSample(mLastSample); + mLastSample->restoreState(mLastSampleState); + mLastSample = 0; + mLastSampleState.clear(); + } + + /*----------------------------------------------------------------------------- + | Cleans up and shuts down the context. + -----------------------------------------------------------------------------*/ + virtual void shutdown() + { + if (mCurrentSample) + { + mCurrentSample->_shutdown(); + mCurrentSample = 0; + } + + // remove window event listener before shutting down OIS + Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this); + + shutdownInput(); + } + + /*----------------------------------------------------------------------------- + | Destroys OIS input devices and the input manager. + -----------------------------------------------------------------------------*/ + virtual void shutdownInput() + { + // detach input devices + windowResized(mWindow); // do an initial adjustment of mouse area + if(mInputContext.mKeyboard) + mInputContext.mKeyboard->setEventCallback(NULL); + if(mInputContext.mMouse) + mInputContext.mMouse->setEventCallback(NULL); #if OIS_WITH_MULTITOUCH - if(mInputContext.mMultiTouch) - mInputContext.mMultiTouch->setEventCallback(NULL); + if(mInputContext.mMultiTouch) + mInputContext.mMultiTouch->setEventCallback(NULL); #endif - if(mInputContext.mAccelerometer) + if(mInputContext.mAccelerometer) mInputContext.mAccelerometer->setEventCallback(NULL); #if OGRE_PLATFORM != OGRE_PLATFORM_ANDROID && OGRE_PLATFORM != OGRE_PLATFORM_WINRT - if (mInputMgr) - { - if(mInputContext.mKeyboard) - mInputMgr->destroyInputObject(mInputContext.mKeyboard); - if(mInputContext.mMouse) - mInputMgr->destroyInputObject(mInputContext.mMouse); + if (mInputMgr) + { + if(mInputContext.mKeyboard) + mInputMgr->destroyInputObject(mInputContext.mKeyboard); + if(mInputContext.mMouse) + mInputMgr->destroyInputObject(mInputContext.mMouse); #if OIS_WITH_MULTITOUCH - if(mInputContext.mMultiTouch) - mInputMgr->destroyInputObject(mInputContext.mMultiTouch); + if(mInputContext.mMultiTouch) + mInputMgr->destroyInputObject(mInputContext.mMultiTouch); #endif - if(mInputContext.mAccelerometer) - mInputMgr->destroyInputObject(mInputContext.mAccelerometer); + if(mInputContext.mAccelerometer) + mInputMgr->destroyInputObject(mInputContext.mAccelerometer); - OIS::InputManager::destroyInputSystem(mInputMgr); - mInputMgr = 0; - } + OIS::InputManager::destroyInputSystem(mInputMgr); + mInputMgr = 0; + } #endif - } + } - /*----------------------------------------------------------------------------- - | Captures input device states. - -----------------------------------------------------------------------------*/ - virtual void captureInputDevices() - { - mInputContext.capture(); - } + /*----------------------------------------------------------------------------- + | Captures input device states. + -----------------------------------------------------------------------------*/ + virtual void captureInputDevices() + { + mInputContext.capture(); + } #if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID Ogre::DataStreamPtr openAPKFile(const Ogre::String& fileName) @@ -970,23 +970,23 @@ namespace OgreBites #endif Ogre::FileSystemLayer* mFSLayer; // File system abstraction layer - Ogre::Root* mRoot; // OGRE root - OIS::InputManager* mInputMgr; // OIS input manager - InputContext mInputContext; // all OIS devices are here - Ogre::OverlaySystem* mOverlaySystem; // Overlay system + Ogre::Root* mRoot; // OGRE root + OIS::InputManager* mInputMgr; // OIS input manager + InputContext mInputContext; // all OIS devices are here + Ogre::OverlaySystem* mOverlaySystem; // Overlay system #ifdef OGRE_STATIC_LIB Ogre::StaticPluginLoader mStaticPluginLoader; #endif - Sample* mCurrentSample; // currently running sample - bool mSamplePaused; // whether current sample is paused - bool mFirstRun; // whether or not this is the first run - bool mLastRun; // whether or not this is the final run - Ogre::String mNextRenderer; // name of renderer used for next run - Sample* mLastSample; // last sample run before reconfiguration - Ogre::NameValuePairList mLastSampleState; // state of last sample + Sample* mCurrentSample; // currently running sample + bool mSamplePaused; // whether current sample is paused + bool mFirstRun; // whether or not this is the first run + bool mLastRun; // whether or not this is the final run + Ogre::String mNextRenderer; // name of renderer used for next run + Sample* mLastSample; // last sample run before reconfiguration + Ogre::NameValuePairList mLastSampleState; // state of last sample public: Ogre::RenderWindow* mWindow; // render window - }; + }; } #endif diff --git a/Samples/Common/include/SamplePlugin.h b/Samples/Common/include/SamplePlugin.h index ba65f468075..0bd6d0b1e1f 100644 --- a/Samples/Common/include/SamplePlugin.h +++ b/Samples/Common/include/SamplePlugin.h @@ -43,56 +43,56 @@ # define _OgreSampleExport __attribute__ ((visibility("default"))) # define _OgreSampleClassExport __attribute__ ((visibility("default"))) # else -# define _OgreSampleExport -# define _OgreSampleClassExport +# define _OgreSampleExport +# define _OgreSampleClassExport # endif #endif namespace OgreBites { - /*============================================================================= - | Utility class used to hold a set of samples in an OGRE plugin. - =============================================================================*/ - class _OgreSampleClassExport SamplePlugin : public Ogre::Plugin + /*============================================================================= + | Utility class used to hold a set of samples in an OGRE plugin. + =============================================================================*/ + class _OgreSampleClassExport SamplePlugin : public Ogre::Plugin { public: - SamplePlugin(const Ogre::String& name) - : mName(name) - { - } + SamplePlugin(const Ogre::String& name) + : mName(name) + { + } - const Ogre::String& getName() const - { - return mName; - } + const Ogre::String& getName() const + { + return mName; + } - void install() {} - void uninstall() {} - void initialise() {} - void shutdown() {} + void install() {} + void uninstall() {} + void initialise() {} + void shutdown() {} - /*----------------------------------------------------------------------------- - | Adds a sample to the queue. - -----------------------------------------------------------------------------*/ - void addSample(Sample* s) - { - mSamples.insert(s); - } + /*----------------------------------------------------------------------------- + | Adds a sample to the queue. + -----------------------------------------------------------------------------*/ + void addSample(Sample* s) + { + mSamples.insert(s); + } - /*----------------------------------------------------------------------------- - | Retrieves the queue of samples. - -----------------------------------------------------------------------------*/ - const SampleSet& getSamples() - { - return mSamples; - } + /*----------------------------------------------------------------------------- + | Retrieves the queue of samples. + -----------------------------------------------------------------------------*/ + const SampleSet& getSamples() + { + return mSamples; + } - protected: + protected: - Ogre::String mName; - SampleSet mSamples; + Ogre::String mName; + SampleSet mSamples; }; } diff --git a/Samples/Common/include/SdkCameraMan.h b/Samples/Common/include/SdkCameraMan.h index 2f3fa58c152..b6d4c29d320 100644 --- a/Samples/Common/include/SdkCameraMan.h +++ b/Samples/Common/include/SdkCameraMan.h @@ -34,333 +34,333 @@ namespace OgreBites { - enum CameraStyle // enumerator values for different styles of camera movement - { - CS_FREELOOK, - CS_ORBIT, - CS_MANUAL - }; - - /*============================================================================= - | Utility class for controlling the camera in samples. - =============================================================================*/ - class SdkCameraMan + enum CameraStyle // enumerator values for different styles of camera movement + { + CS_FREELOOK, + CS_ORBIT, + CS_MANUAL + }; + + /*============================================================================= + | Utility class for controlling the camera in samples. + =============================================================================*/ + class SdkCameraMan { public: - SdkCameraMan(Ogre::Camera* cam) - : mCamera(0) - , mTarget(0) - , mOrbiting(false) - , mZooming(false) - , mTopSpeed(150) - , mVelocity(Ogre::Vector3::ZERO) - , mGoingForward(false) - , mGoingBack(false) - , mGoingLeft(false) - , mGoingRight(false) - , mGoingUp(false) - , mGoingDown(false) - , mFastMove(false) - { - - setCamera(cam); - setStyle(CS_FREELOOK); - } - - virtual ~SdkCameraMan() {} - - /*----------------------------------------------------------------------------- - | Swaps the camera on our camera man for another camera. - -----------------------------------------------------------------------------*/ - virtual void setCamera(Ogre::Camera* cam) - { - mCamera = cam; - } - - virtual Ogre::Camera* getCamera() - { - return mCamera; - } - - /*----------------------------------------------------------------------------- - | Sets the target we will revolve around. Only applies for orbit style. - -----------------------------------------------------------------------------*/ - virtual void setTarget(Ogre::SceneNode* target) - { - if (target != mTarget) - { - mTarget = target; - if(target) - { - setYawPitchDist(Ogre::Degree(0), Ogre::Degree(15), 150); - mCamera->setAutoTracking(true, mTarget); - } - else - { - mCamera->setAutoTracking(false); - } - - } - - - } - - virtual Ogre::SceneNode* getTarget() - { - return mTarget; - } - - /*----------------------------------------------------------------------------- - | Sets the spatial offset from the target. Only applies for orbit style. - -----------------------------------------------------------------------------*/ - virtual void setYawPitchDist(Ogre::Radian yaw, Ogre::Radian pitch, Ogre::Real dist) - { - mCamera->setPosition(mTarget->_getDerivedPosition()); - mCamera->setOrientation(mTarget->_getDerivedOrientation()); - mCamera->yaw(yaw); - mCamera->pitch(-pitch); - mCamera->moveRelative(Ogre::Vector3(0, 0, dist)); - } - - /*----------------------------------------------------------------------------- - | Sets the camera's top speed. Only applies for free-look style. - -----------------------------------------------------------------------------*/ - virtual void setTopSpeed(Ogre::Real topSpeed) - { - mTopSpeed = topSpeed; - } - - virtual Ogre::Real getTopSpeed() - { - return mTopSpeed; - } - - /*----------------------------------------------------------------------------- - | Sets the movement style of our camera man. - -----------------------------------------------------------------------------*/ - virtual void setStyle(CameraStyle style) - { - if (mStyle != CS_ORBIT && style == CS_ORBIT) - { - setTarget(mTarget ? mTarget : mCamera->getSceneManager()->getRootSceneNode()); - mCamera->setFixedYawAxis(true); - manualStop(); - setYawPitchDist(Ogre::Degree(0), Ogre::Degree(15), 150); - } - else if (mStyle != CS_FREELOOK && style == CS_FREELOOK) - { - mCamera->setAutoTracking(false); - mCamera->setFixedYawAxis(true); - } - else if (mStyle != CS_MANUAL && style == CS_MANUAL) - { - mCamera->setAutoTracking(false); - manualStop(); - } - mStyle = style; - - } - - virtual CameraStyle getStyle() - { - return mStyle; - } - - /*----------------------------------------------------------------------------- - | Manually stops the camera when in free-look mode. - -----------------------------------------------------------------------------*/ - virtual void manualStop() - { - if (mStyle == CS_FREELOOK) - { - mGoingForward = false; - mGoingBack = false; - mGoingLeft = false; - mGoingRight = false; - mGoingUp = false; - mGoingDown = false; - mVelocity = Ogre::Vector3::ZERO; - } - } - - virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt) - { - if (mStyle == CS_FREELOOK) - { - // build our acceleration vector based on keyboard input composite - Ogre::Vector3 accel = Ogre::Vector3::ZERO; - if (mGoingForward) accel += mCamera->getDirection(); - if (mGoingBack) accel -= mCamera->getDirection(); - if (mGoingRight) accel += mCamera->getRight(); - if (mGoingLeft) accel -= mCamera->getRight(); - if (mGoingUp) accel += mCamera->getUp(); - if (mGoingDown) accel -= mCamera->getUp(); - - // if accelerating, try to reach top speed in a certain time - Ogre::Real topSpeed = mFastMove ? mTopSpeed * 20 : mTopSpeed; - if (accel.squaredLength() != 0) - { - accel.normalise(); - mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10; - } - // if not accelerating, try to stop in a certain time - else mVelocity -= mVelocity * evt.timeSinceLastFrame * 10; - - Ogre::Real tooSmall = std::numeric_limits::epsilon(); - - // keep camera velocity below top speed and above epsilon - if (mVelocity.squaredLength() > topSpeed * topSpeed) - { - mVelocity.normalise(); - mVelocity *= topSpeed; - } - else if (mVelocity.squaredLength() < tooSmall * tooSmall) - mVelocity = Ogre::Vector3::ZERO; - - if (mVelocity != Ogre::Vector3::ZERO) mCamera->move(mVelocity * evt.timeSinceLastFrame); - } - - return true; - } - - /*----------------------------------------------------------------------------- - | Processes key presses for free-look style movement. - -----------------------------------------------------------------------------*/ - virtual void injectKeyDown(const OIS::KeyEvent& evt) - { - if (mStyle == CS_FREELOOK) - { - if (evt.key == OIS::KC_W || evt.key == OIS::KC_UP) mGoingForward = true; - else if (evt.key == OIS::KC_S || evt.key == OIS::KC_DOWN) mGoingBack = true; - else if (evt.key == OIS::KC_A || evt.key == OIS::KC_LEFT) mGoingLeft = true; - else if (evt.key == OIS::KC_D || evt.key == OIS::KC_RIGHT) mGoingRight = true; - else if (evt.key == OIS::KC_PGUP) mGoingUp = true; - else if (evt.key == OIS::KC_PGDOWN) mGoingDown = true; - else if (evt.key == OIS::KC_LSHIFT) mFastMove = true; - } - } - - /*----------------------------------------------------------------------------- - | Processes key releases for free-look style movement. - -----------------------------------------------------------------------------*/ - virtual void injectKeyUp(const OIS::KeyEvent& evt) - { - if (mStyle == CS_FREELOOK) - { - if (evt.key == OIS::KC_W || evt.key == OIS::KC_UP) mGoingForward = false; - else if (evt.key == OIS::KC_S || evt.key == OIS::KC_DOWN) mGoingBack = false; - else if (evt.key == OIS::KC_A || evt.key == OIS::KC_LEFT) mGoingLeft = false; - else if (evt.key == OIS::KC_D || evt.key == OIS::KC_RIGHT) mGoingRight = false; - else if (evt.key == OIS::KC_PGUP) mGoingUp = false; - else if (evt.key == OIS::KC_PGDOWN) mGoingDown = false; - else if (evt.key == OIS::KC_LSHIFT) mFastMove = false; - } - } - - /*----------------------------------------------------------------------------- - | Processes mouse movement differently for each style. - -----------------------------------------------------------------------------*/ + SdkCameraMan(Ogre::Camera* cam) + : mCamera(0) + , mTarget(0) + , mOrbiting(false) + , mZooming(false) + , mTopSpeed(150) + , mVelocity(Ogre::Vector3::ZERO) + , mGoingForward(false) + , mGoingBack(false) + , mGoingLeft(false) + , mGoingRight(false) + , mGoingUp(false) + , mGoingDown(false) + , mFastMove(false) + { + + setCamera(cam); + setStyle(CS_FREELOOK); + } + + virtual ~SdkCameraMan() {} + + /*----------------------------------------------------------------------------- + | Swaps the camera on our camera man for another camera. + -----------------------------------------------------------------------------*/ + virtual void setCamera(Ogre::Camera* cam) + { + mCamera = cam; + } + + virtual Ogre::Camera* getCamera() + { + return mCamera; + } + + /*----------------------------------------------------------------------------- + | Sets the target we will revolve around. Only applies for orbit style. + -----------------------------------------------------------------------------*/ + virtual void setTarget(Ogre::SceneNode* target) + { + if (target != mTarget) + { + mTarget = target; + if(target) + { + setYawPitchDist(Ogre::Degree(0), Ogre::Degree(15), 150); + mCamera->setAutoTracking(true, mTarget); + } + else + { + mCamera->setAutoTracking(false); + } + + } + + + } + + virtual Ogre::SceneNode* getTarget() + { + return mTarget; + } + + /*----------------------------------------------------------------------------- + | Sets the spatial offset from the target. Only applies for orbit style. + -----------------------------------------------------------------------------*/ + virtual void setYawPitchDist(Ogre::Radian yaw, Ogre::Radian pitch, Ogre::Real dist) + { + mCamera->setPosition(mTarget->_getDerivedPosition()); + mCamera->setOrientation(mTarget->_getDerivedOrientation()); + mCamera->yaw(yaw); + mCamera->pitch(-pitch); + mCamera->moveRelative(Ogre::Vector3(0, 0, dist)); + } + + /*----------------------------------------------------------------------------- + | Sets the camera's top speed. Only applies for free-look style. + -----------------------------------------------------------------------------*/ + virtual void setTopSpeed(Ogre::Real topSpeed) + { + mTopSpeed = topSpeed; + } + + virtual Ogre::Real getTopSpeed() + { + return mTopSpeed; + } + + /*----------------------------------------------------------------------------- + | Sets the movement style of our camera man. + -----------------------------------------------------------------------------*/ + virtual void setStyle(CameraStyle style) + { + if (mStyle != CS_ORBIT && style == CS_ORBIT) + { + setTarget(mTarget ? mTarget : mCamera->getSceneManager()->getRootSceneNode()); + mCamera->setFixedYawAxis(true); + manualStop(); + setYawPitchDist(Ogre::Degree(0), Ogre::Degree(15), 150); + } + else if (mStyle != CS_FREELOOK && style == CS_FREELOOK) + { + mCamera->setAutoTracking(false); + mCamera->setFixedYawAxis(true); + } + else if (mStyle != CS_MANUAL && style == CS_MANUAL) + { + mCamera->setAutoTracking(false); + manualStop(); + } + mStyle = style; + + } + + virtual CameraStyle getStyle() + { + return mStyle; + } + + /*----------------------------------------------------------------------------- + | Manually stops the camera when in free-look mode. + -----------------------------------------------------------------------------*/ + virtual void manualStop() + { + if (mStyle == CS_FREELOOK) + { + mGoingForward = false; + mGoingBack = false; + mGoingLeft = false; + mGoingRight = false; + mGoingUp = false; + mGoingDown = false; + mVelocity = Ogre::Vector3::ZERO; + } + } + + virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt) + { + if (mStyle == CS_FREELOOK) + { + // build our acceleration vector based on keyboard input composite + Ogre::Vector3 accel = Ogre::Vector3::ZERO; + if (mGoingForward) accel += mCamera->getDirection(); + if (mGoingBack) accel -= mCamera->getDirection(); + if (mGoingRight) accel += mCamera->getRight(); + if (mGoingLeft) accel -= mCamera->getRight(); + if (mGoingUp) accel += mCamera->getUp(); + if (mGoingDown) accel -= mCamera->getUp(); + + // if accelerating, try to reach top speed in a certain time + Ogre::Real topSpeed = mFastMove ? mTopSpeed * 20 : mTopSpeed; + if (accel.squaredLength() != 0) + { + accel.normalise(); + mVelocity += accel * topSpeed * evt.timeSinceLastFrame * 10; + } + // if not accelerating, try to stop in a certain time + else mVelocity -= mVelocity * evt.timeSinceLastFrame * 10; + + Ogre::Real tooSmall = std::numeric_limits::epsilon(); + + // keep camera velocity below top speed and above epsilon + if (mVelocity.squaredLength() > topSpeed * topSpeed) + { + mVelocity.normalise(); + mVelocity *= topSpeed; + } + else if (mVelocity.squaredLength() < tooSmall * tooSmall) + mVelocity = Ogre::Vector3::ZERO; + + if (mVelocity != Ogre::Vector3::ZERO) mCamera->move(mVelocity * evt.timeSinceLastFrame); + } + + return true; + } + + /*----------------------------------------------------------------------------- + | Processes key presses for free-look style movement. + -----------------------------------------------------------------------------*/ + virtual void injectKeyDown(const OIS::KeyEvent& evt) + { + if (mStyle == CS_FREELOOK) + { + if (evt.key == OIS::KC_W || evt.key == OIS::KC_UP) mGoingForward = true; + else if (evt.key == OIS::KC_S || evt.key == OIS::KC_DOWN) mGoingBack = true; + else if (evt.key == OIS::KC_A || evt.key == OIS::KC_LEFT) mGoingLeft = true; + else if (evt.key == OIS::KC_D || evt.key == OIS::KC_RIGHT) mGoingRight = true; + else if (evt.key == OIS::KC_PGUP) mGoingUp = true; + else if (evt.key == OIS::KC_PGDOWN) mGoingDown = true; + else if (evt.key == OIS::KC_LSHIFT) mFastMove = true; + } + } + + /*----------------------------------------------------------------------------- + | Processes key releases for free-look style movement. + -----------------------------------------------------------------------------*/ + virtual void injectKeyUp(const OIS::KeyEvent& evt) + { + if (mStyle == CS_FREELOOK) + { + if (evt.key == OIS::KC_W || evt.key == OIS::KC_UP) mGoingForward = false; + else if (evt.key == OIS::KC_S || evt.key == OIS::KC_DOWN) mGoingBack = false; + else if (evt.key == OIS::KC_A || evt.key == OIS::KC_LEFT) mGoingLeft = false; + else if (evt.key == OIS::KC_D || evt.key == OIS::KC_RIGHT) mGoingRight = false; + else if (evt.key == OIS::KC_PGUP) mGoingUp = false; + else if (evt.key == OIS::KC_PGDOWN) mGoingDown = false; + else if (evt.key == OIS::KC_LSHIFT) mFastMove = false; + } + } + + /*----------------------------------------------------------------------------- + | Processes mouse movement differently for each style. + -----------------------------------------------------------------------------*/ #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - virtual void injectMouseMove(const OIS::MultiTouchEvent& evt) + virtual void injectMouseMove(const OIS::MultiTouchEvent& evt) #else - virtual void injectMouseMove(const OIS::MouseEvent& evt) + virtual void injectMouseMove(const OIS::MouseEvent& evt) #endif - { - if (mStyle == CS_ORBIT) - { - Ogre::Real dist = (mCamera->getPosition() - mTarget->_getDerivedPosition()).length(); - - if (mOrbiting) // yaw around the target, and pitch locally - { - mCamera->setPosition(mTarget->_getDerivedPosition()); - - mCamera->yaw(Ogre::Degree(-evt.state.X.rel * 0.25f)); - mCamera->pitch(Ogre::Degree(-evt.state.Y.rel * 0.25f)); - - mCamera->moveRelative(Ogre::Vector3(0, 0, dist)); - - // don't let the camera go over the top or around the bottom of the target - } - else if (mZooming) // move the camera toward or away from the target - { - // the further the camera is, the faster it moves - mCamera->moveRelative(Ogre::Vector3(0, 0, evt.state.Y.rel * 0.004f * dist)); - } - else if (evt.state.Z.rel != 0) // move the camera toward or away from the target - { - // the further the camera is, the faster it moves - mCamera->moveRelative(Ogre::Vector3(0, 0, -evt.state.Z.rel * 0.0008f * dist)); - } - } - else if (mStyle == CS_FREELOOK) - { - mCamera->yaw(Ogre::Degree(-evt.state.X.rel * 0.15f)); - mCamera->pitch(Ogre::Degree(-evt.state.Y.rel * 0.15f)); - } - } - - /*----------------------------------------------------------------------------- - | Processes mouse presses. Only applies for orbit style. - | Left button is for orbiting, and right button is for zooming. - -----------------------------------------------------------------------------*/ + { + if (mStyle == CS_ORBIT) + { + Ogre::Real dist = (mCamera->getPosition() - mTarget->_getDerivedPosition()).length(); + + if (mOrbiting) // yaw around the target, and pitch locally + { + mCamera->setPosition(mTarget->_getDerivedPosition()); + + mCamera->yaw(Ogre::Degree(-evt.state.X.rel * 0.25f)); + mCamera->pitch(Ogre::Degree(-evt.state.Y.rel * 0.25f)); + + mCamera->moveRelative(Ogre::Vector3(0, 0, dist)); + + // don't let the camera go over the top or around the bottom of the target + } + else if (mZooming) // move the camera toward or away from the target + { + // the further the camera is, the faster it moves + mCamera->moveRelative(Ogre::Vector3(0, 0, evt.state.Y.rel * 0.004f * dist)); + } + else if (evt.state.Z.rel != 0) // move the camera toward or away from the target + { + // the further the camera is, the faster it moves + mCamera->moveRelative(Ogre::Vector3(0, 0, -evt.state.Z.rel * 0.0008f * dist)); + } + } + else if (mStyle == CS_FREELOOK) + { + mCamera->yaw(Ogre::Degree(-evt.state.X.rel * 0.15f)); + mCamera->pitch(Ogre::Degree(-evt.state.Y.rel * 0.15f)); + } + } + + /*----------------------------------------------------------------------------- + | Processes mouse presses. Only applies for orbit style. + | Left button is for orbiting, and right button is for zooming. + -----------------------------------------------------------------------------*/ #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - virtual void injectMouseDown(const OIS::MultiTouchEvent& evt) - { - if (mStyle == CS_ORBIT) - { + virtual void injectMouseDown(const OIS::MultiTouchEvent& evt) + { + if (mStyle == CS_ORBIT) + { mOrbiting = true; - } - } + } + } #else - virtual void injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id) - { - if (mStyle == CS_ORBIT) - { - if (id == OIS::MB_Left) mOrbiting = true; - else if (id == OIS::MB_Right) mZooming = true; - } - } + virtual void injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + { + if (mStyle == CS_ORBIT) + { + if (id == OIS::MB_Left) mOrbiting = true; + else if (id == OIS::MB_Right) mZooming = true; + } + } #endif - /*----------------------------------------------------------------------------- - | Processes mouse releases. Only applies for orbit style. - | Left button is for orbiting, and right button is for zooming. - -----------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------- + | Processes mouse releases. Only applies for orbit style. + | Left button is for orbiting, and right button is for zooming. + -----------------------------------------------------------------------------*/ #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - virtual void injectMouseUp(const OIS::MultiTouchEvent& evt) - { - if (mStyle == CS_ORBIT) - { + virtual void injectMouseUp(const OIS::MultiTouchEvent& evt) + { + if (mStyle == CS_ORBIT) + { mOrbiting = false; - } - } + } + } #else - virtual void injectMouseUp(const OIS::MouseEvent& evt, OIS::MouseButtonID id) - { - if (mStyle == CS_ORBIT) - { - if (id == OIS::MB_Left) mOrbiting = false; - else if (id == OIS::MB_Right) mZooming = false; - } - } + virtual void injectMouseUp(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + { + if (mStyle == CS_ORBIT) + { + if (id == OIS::MB_Left) mOrbiting = false; + else if (id == OIS::MB_Right) mZooming = false; + } + } #endif protected: - Ogre::Camera* mCamera; - CameraStyle mStyle; - Ogre::SceneNode* mTarget; - bool mOrbiting; - bool mZooming; - Ogre::Real mTopSpeed; - Ogre::Vector3 mVelocity; - bool mGoingForward; - bool mGoingBack; - bool mGoingLeft; - bool mGoingRight; - bool mGoingUp; - bool mGoingDown; - bool mFastMove; + Ogre::Camera* mCamera; + CameraStyle mStyle; + Ogre::SceneNode* mTarget; + bool mOrbiting; + bool mZooming; + Ogre::Real mTopSpeed; + Ogre::Vector3 mVelocity; + bool mGoingForward; + bool mGoingBack; + bool mGoingLeft; + bool mGoingRight; + bool mGoingUp; + bool mGoingDown; + bool mFastMove; }; } diff --git a/Samples/Common/include/SdkSample.h b/Samples/Common/include/SdkSample.h index 1ee3151f3ff..3cf24ac1ff6 100644 --- a/Samples/Common/include/SdkSample.h +++ b/Samples/Common/include/SdkSample.h @@ -40,285 +40,285 @@ namespace OgreBites { - /*============================================================================= - // Base SDK sample class. Includes default player camera and SDK trays. - =============================================================================*/ - class SdkSample : public Sample, public SdkTrayListener + /*============================================================================= + // Base SDK sample class. Includes default player camera and SDK trays. + =============================================================================*/ + class SdkSample : public Sample, public SdkTrayListener { - public: - SdkSample() - { - // so we don't have to worry about checking if these keys exist later - mInfo["Title"] = "Untitled"; - mInfo["Description"] = ""; - mInfo["Category"] = "Unsorted"; - mInfo["Thumbnail"] = ""; - mInfo["Help"] = ""; - - mTrayMgr = 0; - mCameraMan = 0; - mCamera = 0; - mViewport = 0; - mDetailsPanel = 0; - mCursorWasVisible = false; - mDragLook = false; - } - - virtual ~SdkSample() {} - - /*----------------------------------------------------------------------------- - | Manually update the cursor position after being unpaused. - -----------------------------------------------------------------------------*/ - virtual void unpaused() - { - mTrayMgr->refreshCursor(); - } - - /*----------------------------------------------------------------------------- - | Automatically saves position and orientation for free-look cameras. - -----------------------------------------------------------------------------*/ - virtual void saveState(Ogre::NameValuePairList& state) - { - if (mCameraMan->getStyle() == CS_FREELOOK) - { - state["CameraPosition"] = Ogre::StringConverter::toString(mCamera->getPosition()); - state["CameraOrientation"] = Ogre::StringConverter::toString(mCamera->getOrientation()); - } - } - - /*----------------------------------------------------------------------------- - | Automatically restores position and orientation for free-look cameras. - -----------------------------------------------------------------------------*/ - virtual void restoreState(Ogre::NameValuePairList& state) - { - if (state.find("CameraPosition") != state.end() && state.find("CameraOrientation") != state.end()) - { - mCameraMan->setStyle(CS_FREELOOK); - mCamera->setPosition(Ogre::StringConverter::parseVector3(state["CameraPosition"])); - mCamera->setOrientation(Ogre::StringConverter::parseQuaternion(state["CameraOrientation"])); - } - } - - virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt) - { - mTrayMgr->frameRenderingQueued(evt); - - if (!mTrayMgr->isDialogVisible()) - { - mCameraMan->frameRenderingQueued(evt); // if dialog isn't up, then update the camera - - if (mDetailsPanel->isVisible()) // if details panel is visible, then update its contents - { - mDetailsPanel->setParamValue(0, Ogre::StringConverter::toString(mCamera->getDerivedPosition().x)); - mDetailsPanel->setParamValue(1, Ogre::StringConverter::toString(mCamera->getDerivedPosition().y)); - mDetailsPanel->setParamValue(2, Ogre::StringConverter::toString(mCamera->getDerivedPosition().z)); - mDetailsPanel->setParamValue(4, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().w)); - mDetailsPanel->setParamValue(5, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().x)); - mDetailsPanel->setParamValue(6, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().y)); - mDetailsPanel->setParamValue(7, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().z)); + public: + SdkSample() + { + // so we don't have to worry about checking if these keys exist later + mInfo["Title"] = "Untitled"; + mInfo["Description"] = ""; + mInfo["Category"] = "Unsorted"; + mInfo["Thumbnail"] = ""; + mInfo["Help"] = ""; + + mTrayMgr = 0; + mCameraMan = 0; + mCamera = 0; + mViewport = 0; + mDetailsPanel = 0; + mCursorWasVisible = false; + mDragLook = false; + } + + virtual ~SdkSample() {} + + /*----------------------------------------------------------------------------- + | Manually update the cursor position after being unpaused. + -----------------------------------------------------------------------------*/ + virtual void unpaused() + { + mTrayMgr->refreshCursor(); + } + + /*----------------------------------------------------------------------------- + | Automatically saves position and orientation for free-look cameras. + -----------------------------------------------------------------------------*/ + virtual void saveState(Ogre::NameValuePairList& state) + { + if (mCameraMan->getStyle() == CS_FREELOOK) + { + state["CameraPosition"] = Ogre::StringConverter::toString(mCamera->getPosition()); + state["CameraOrientation"] = Ogre::StringConverter::toString(mCamera->getOrientation()); + } + } + + /*----------------------------------------------------------------------------- + | Automatically restores position and orientation for free-look cameras. + -----------------------------------------------------------------------------*/ + virtual void restoreState(Ogre::NameValuePairList& state) + { + if (state.find("CameraPosition") != state.end() && state.find("CameraOrientation") != state.end()) + { + mCameraMan->setStyle(CS_FREELOOK); + mCamera->setPosition(Ogre::StringConverter::parseVector3(state["CameraPosition"])); + mCamera->setOrientation(Ogre::StringConverter::parseQuaternion(state["CameraOrientation"])); + } + } + + virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt) + { + mTrayMgr->frameRenderingQueued(evt); + + if (!mTrayMgr->isDialogVisible()) + { + mCameraMan->frameRenderingQueued(evt); // if dialog isn't up, then update the camera + + if (mDetailsPanel->isVisible()) // if details panel is visible, then update its contents + { + mDetailsPanel->setParamValue(0, Ogre::StringConverter::toString(mCamera->getDerivedPosition().x)); + mDetailsPanel->setParamValue(1, Ogre::StringConverter::toString(mCamera->getDerivedPosition().y)); + mDetailsPanel->setParamValue(2, Ogre::StringConverter::toString(mCamera->getDerivedPosition().z)); + mDetailsPanel->setParamValue(4, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().w)); + mDetailsPanel->setParamValue(5, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().x)); + mDetailsPanel->setParamValue(6, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().y)); + mDetailsPanel->setParamValue(7, Ogre::StringConverter::toString(mCamera->getDerivedOrientation().z)); #ifdef INCLUDE_RTSHADER_SYSTEM - mDetailsPanel->setParamValue(14, Ogre::StringConverter::toString(mShaderGenerator->getVertexShaderCount())); - mDetailsPanel->setParamValue(15, Ogre::StringConverter::toString(mShaderGenerator->getFragmentShaderCount())); + mDetailsPanel->setParamValue(14, Ogre::StringConverter::toString(mShaderGenerator->getVertexShaderCount())); + mDetailsPanel->setParamValue(15, Ogre::StringConverter::toString(mShaderGenerator->getFragmentShaderCount())); #endif - } - } - - return true; - } - - virtual void windowResized(Ogre::RenderWindow* rw) - { - mCamera->setAspectRatio((Ogre::Real)mViewport->getActualWidth() / (Ogre::Real)mViewport->getActualHeight()); - } - - virtual bool keyPressed(const OIS::KeyEvent& evt) - { - if (evt.key == OIS::KC_H || evt.key == OIS::KC_F1) // toggle visibility of help dialog - { - if (!mTrayMgr->isDialogVisible() && mInfo["Help"] != "") mTrayMgr->showOkDialog("Help", mInfo["Help"]); - else mTrayMgr->closeDialog(); - } - - if (mTrayMgr->isDialogVisible()) return true; // don't process any more keys if dialog is up - - if (evt.key == OIS::KC_F) // toggle visibility of advanced frame stats - { - mTrayMgr->toggleAdvancedFrameStats(); - } - else if (evt.key == OIS::KC_G) // toggle visibility of even rarer debugging details - { - if (mDetailsPanel->getTrayLocation() == TL_NONE) - { - mTrayMgr->moveWidgetToTray(mDetailsPanel, TL_TOPRIGHT, 0); - mDetailsPanel->show(); - } - else - { - mTrayMgr->removeWidgetFromTray(mDetailsPanel); - mDetailsPanel->hide(); - } - } - else if (evt.key == OIS::KC_T) // cycle texture filtering mode - { - Ogre::String newVal; - Ogre::TextureFilterOptions tfo; - unsigned int aniso; - - switch (DISPLAY_STRING_TO_STRING(mDetailsPanel->getParamValue(9))[0]) - { - case 'B': - newVal = "Trilinear"; - tfo = Ogre::TFO_TRILINEAR; - aniso = 1; - break; - case 'T': - newVal = "Anisotropic"; - tfo = Ogre::TFO_ANISOTROPIC; - aniso = 8; - break; - case 'A': - newVal = "None"; - tfo = Ogre::TFO_NONE; - aniso = 1; - break; - default: - newVal = "Bilinear"; - tfo = Ogre::TFO_BILINEAR; - aniso = 1; - } - - Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(tfo); - Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(aniso); - mDetailsPanel->setParamValue(9, newVal); - } - else if (evt.key == OIS::KC_R) // cycle polygon rendering mode - { - Ogre::String newVal; - Ogre::PolygonMode pm; - - switch (mCamera->getPolygonMode()) - { - case Ogre::PM_SOLID: - newVal = "Wireframe"; - pm = Ogre::PM_WIREFRAME; - break; - case Ogre::PM_WIREFRAME: - newVal = "Points"; - pm = Ogre::PM_POINTS; - break; - default: - newVal = "Solid"; - pm = Ogre::PM_SOLID; - } - - mCamera->setPolygonMode(pm); - mDetailsPanel->setParamValue(10, newVal); - } - else if(evt.key == OIS::KC_F5) // refresh all textures - { - Ogre::TextureManager::getSingleton().reloadAll(); - } - else if (evt.key == OIS::KC_F6) // take a screenshot - { - mWindow->writeContentsToTimestampedFile("screenshot", ".png"); - } - -#ifdef INCLUDE_RTSHADER_SYSTEM - // Toggle schemes. - else if (evt.key == OIS::KC_F2) - { - if(mRoot->getRenderSystem()->getCapabilities()->hasCapability(Ogre::RSC_FIXED_FUNCTION)) - { - Ogre::Viewport* mainVP = mCamera->getViewport(); - const Ogre::String& curMaterialScheme = mainVP->getMaterialScheme(); - - if (curMaterialScheme == Ogre::MaterialManager::DEFAULT_SCHEME_NAME) - { - mainVP->setMaterialScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - mDetailsPanel->setParamValue(11, "On"); - } - else if (curMaterialScheme == Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) - { - mainVP->setMaterialScheme(Ogre::MaterialManager::DEFAULT_SCHEME_NAME); - mDetailsPanel->setParamValue(11, "Off"); - } - } - } - // Toggles per pixel per light model. - else if (evt.key == OIS::KC_F3) - { - static bool usePerPixelLighting = true; - - // Grab the scheme render state. - Ogre::RTShader::RenderState* schemRenderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - - - // Add per pixel lighting sub render state to the global scheme render state. - // It will override the default FFP lighting sub render state. - if (usePerPixelLighting) - { - Ogre::RTShader::SubRenderState* perPixelLightModel = mShaderGenerator->createSubRenderState(Ogre::RTShader::PerPixelLighting::Type); - - schemRenderState->addTemplateSubRenderState(perPixelLightModel); - } - - // Search the per pixel sub render state and remove it. - else - { - const Ogre::RTShader::SubRenderStateList& subRenderStateList = schemRenderState->getTemplateSubRenderStateList(); - Ogre::RTShader::SubRenderStateListConstIterator it = subRenderStateList.begin(); - Ogre::RTShader::SubRenderStateListConstIterator itEnd = subRenderStateList.end(); - - for (; it != itEnd; ++it) - { - Ogre::RTShader::SubRenderState* curSubRenderState = *it; - - // This is the per pixel sub render state -> remove it. - if (curSubRenderState->getType() == Ogre::RTShader::PerPixelLighting::Type) - { - schemRenderState->removeTemplateSubRenderState(*it); - break; - } - } - } - - // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. - mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - - - // Update UI. - if (usePerPixelLighting) - mDetailsPanel->setParamValue(12, "Pixel"); - else - mDetailsPanel->setParamValue(12, "Vertex"); - usePerPixelLighting = !usePerPixelLighting; - } - - // Switch vertex shader outputs compaction policy. - else if (evt.key == OIS::KC_F4) - { - switch (mShaderGenerator->getVertexShaderOutputsCompactPolicy()) - { - case Ogre::RTShader::VSOCP_LOW: - mShaderGenerator->setVertexShaderOutputsCompactPolicy(Ogre::RTShader::VSOCP_MEDIUM); - mDetailsPanel->setParamValue(13, "Medium"); - break; - - case Ogre::RTShader::VSOCP_MEDIUM: - mShaderGenerator->setVertexShaderOutputsCompactPolicy(Ogre::RTShader::VSOCP_HIGH); - mDetailsPanel->setParamValue(13, "High"); - break; - - case Ogre::RTShader::VSOCP_HIGH: - mShaderGenerator->setVertexShaderOutputsCompactPolicy(Ogre::RTShader::VSOCP_LOW); - mDetailsPanel->setParamValue(13, "Low"); - break; - } - - // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. - mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - } + } + } + + return true; + } + + virtual void windowResized(Ogre::RenderWindow* rw) + { + mCamera->setAspectRatio((Ogre::Real)mViewport->getActualWidth() / (Ogre::Real)mViewport->getActualHeight()); + } + + virtual bool keyPressed(const OIS::KeyEvent& evt) + { + if (evt.key == OIS::KC_H || evt.key == OIS::KC_F1) // toggle visibility of help dialog + { + if (!mTrayMgr->isDialogVisible() && mInfo["Help"] != "") mTrayMgr->showOkDialog("Help", mInfo["Help"]); + else mTrayMgr->closeDialog(); + } + + if (mTrayMgr->isDialogVisible()) return true; // don't process any more keys if dialog is up + + if (evt.key == OIS::KC_F) // toggle visibility of advanced frame stats + { + mTrayMgr->toggleAdvancedFrameStats(); + } + else if (evt.key == OIS::KC_G) // toggle visibility of even rarer debugging details + { + if (mDetailsPanel->getTrayLocation() == TL_NONE) + { + mTrayMgr->moveWidgetToTray(mDetailsPanel, TL_TOPRIGHT, 0); + mDetailsPanel->show(); + } + else + { + mTrayMgr->removeWidgetFromTray(mDetailsPanel); + mDetailsPanel->hide(); + } + } + else if (evt.key == OIS::KC_T) // cycle texture filtering mode + { + Ogre::String newVal; + Ogre::TextureFilterOptions tfo; + unsigned int aniso; + + switch (DISPLAY_STRING_TO_STRING(mDetailsPanel->getParamValue(9))[0]) + { + case 'B': + newVal = "Trilinear"; + tfo = Ogre::TFO_TRILINEAR; + aniso = 1; + break; + case 'T': + newVal = "Anisotropic"; + tfo = Ogre::TFO_ANISOTROPIC; + aniso = 8; + break; + case 'A': + newVal = "None"; + tfo = Ogre::TFO_NONE; + aniso = 1; + break; + default: + newVal = "Bilinear"; + tfo = Ogre::TFO_BILINEAR; + aniso = 1; + } + + Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(tfo); + Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(aniso); + mDetailsPanel->setParamValue(9, newVal); + } + else if (evt.key == OIS::KC_R) // cycle polygon rendering mode + { + Ogre::String newVal; + Ogre::PolygonMode pm; + + switch (mCamera->getPolygonMode()) + { + case Ogre::PM_SOLID: + newVal = "Wireframe"; + pm = Ogre::PM_WIREFRAME; + break; + case Ogre::PM_WIREFRAME: + newVal = "Points"; + pm = Ogre::PM_POINTS; + break; + default: + newVal = "Solid"; + pm = Ogre::PM_SOLID; + } + + mCamera->setPolygonMode(pm); + mDetailsPanel->setParamValue(10, newVal); + } + else if(evt.key == OIS::KC_F5) // refresh all textures + { + Ogre::TextureManager::getSingleton().reloadAll(); + } + else if (evt.key == OIS::KC_F6) // take a screenshot + { + mWindow->writeContentsToTimestampedFile("screenshot", ".png"); + } + +#ifdef INCLUDE_RTSHADER_SYSTEM + // Toggle schemes. + else if (evt.key == OIS::KC_F2) + { + if(mRoot->getRenderSystem()->getCapabilities()->hasCapability(Ogre::RSC_FIXED_FUNCTION)) + { + Ogre::Viewport* mainVP = mCamera->getViewport(); + const Ogre::String& curMaterialScheme = mainVP->getMaterialScheme(); + + if (curMaterialScheme == Ogre::MaterialManager::DEFAULT_SCHEME_NAME) + { + mainVP->setMaterialScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + mDetailsPanel->setParamValue(11, "On"); + } + else if (curMaterialScheme == Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) + { + mainVP->setMaterialScheme(Ogre::MaterialManager::DEFAULT_SCHEME_NAME); + mDetailsPanel->setParamValue(11, "Off"); + } + } + } + // Toggles per pixel per light model. + else if (evt.key == OIS::KC_F3) + { + static bool usePerPixelLighting = true; + + // Grab the scheme render state. + Ogre::RTShader::RenderState* schemRenderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + + + // Add per pixel lighting sub render state to the global scheme render state. + // It will override the default FFP lighting sub render state. + if (usePerPixelLighting) + { + Ogre::RTShader::SubRenderState* perPixelLightModel = mShaderGenerator->createSubRenderState(Ogre::RTShader::PerPixelLighting::Type); + + schemRenderState->addTemplateSubRenderState(perPixelLightModel); + } + + // Search the per pixel sub render state and remove it. + else + { + const Ogre::RTShader::SubRenderStateList& subRenderStateList = schemRenderState->getTemplateSubRenderStateList(); + Ogre::RTShader::SubRenderStateListConstIterator it = subRenderStateList.begin(); + Ogre::RTShader::SubRenderStateListConstIterator itEnd = subRenderStateList.end(); + + for (; it != itEnd; ++it) + { + Ogre::RTShader::SubRenderState* curSubRenderState = *it; + + // This is the per pixel sub render state -> remove it. + if (curSubRenderState->getType() == Ogre::RTShader::PerPixelLighting::Type) + { + schemRenderState->removeTemplateSubRenderState(*it); + break; + } + } + } + + // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. + mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + + + // Update UI. + if (usePerPixelLighting) + mDetailsPanel->setParamValue(12, "Pixel"); + else + mDetailsPanel->setParamValue(12, "Vertex"); + usePerPixelLighting = !usePerPixelLighting; + } + + // Switch vertex shader outputs compaction policy. + else if (evt.key == OIS::KC_F4) + { + switch (mShaderGenerator->getVertexShaderOutputsCompactPolicy()) + { + case Ogre::RTShader::VSOCP_LOW: + mShaderGenerator->setVertexShaderOutputsCompactPolicy(Ogre::RTShader::VSOCP_MEDIUM); + mDetailsPanel->setParamValue(13, "Medium"); + break; + + case Ogre::RTShader::VSOCP_MEDIUM: + mShaderGenerator->setVertexShaderOutputsCompactPolicy(Ogre::RTShader::VSOCP_HIGH); + mDetailsPanel->setParamValue(13, "High"); + break; + + case Ogre::RTShader::VSOCP_HIGH: + mShaderGenerator->setVertexShaderOutputsCompactPolicy(Ogre::RTShader::VSOCP_LOW); + mDetailsPanel->setParamValue(13, "Low"); + break; + } + + // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. + mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + } #endif // INCLUDE_RTSHADER_SYSTEM #if OGRE_PROFILING // Toggle visibility of profiler window @@ -330,159 +330,159 @@ namespace OgreBites } #endif // OGRE_PROFILING - mCameraMan->injectKeyDown(evt); - return true; - } + mCameraMan->injectKeyDown(evt); + return true; + } - virtual bool keyReleased(const OIS::KeyEvent& evt) - { - mCameraMan->injectKeyUp(evt); + virtual bool keyReleased(const OIS::KeyEvent& evt) + { + mCameraMan->injectKeyUp(evt); - return true; - } + return true; + } - /* IMPORTANT: When overriding these following handlers, remember to allow the tray manager - to filter out any interface-related mouse events before processing them in your scene. - If the tray manager handler returns true, the event was meant for the trays, not you. */ + /* IMPORTANT: When overriding these following handlers, remember to allow the tray manager + to filter out any interface-related mouse events before processing them in your scene. + If the tray manager handler returns true, the event was meant for the trays, not you. */ #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - virtual bool touchMoved(const OIS::MultiTouchEvent& evt) + virtual bool touchMoved(const OIS::MultiTouchEvent& evt) #else - virtual bool mouseMoved(const OIS::MouseEvent& evt) + virtual bool mouseMoved(const OIS::MouseEvent& evt) #endif - { - if (mTrayMgr->injectMouseMove(evt)) return true; + { + if (mTrayMgr->injectMouseMove(evt)) return true; - mCameraMan->injectMouseMove(evt); + mCameraMan->injectMouseMove(evt); - return true; - } + return true; + } #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - virtual bool touchPressed(const OIS::MultiTouchEvent& evt) - { - if (mTrayMgr->injectMouseDown(evt)) return true; + virtual bool touchPressed(const OIS::MultiTouchEvent& evt) + { + if (mTrayMgr->injectMouseDown(evt)) return true; - if (mDragLook) - { - mCameraMan->setStyle(CS_FREELOOK); - mTrayMgr->hideCursor(); - } - - mCameraMan->injectMouseDown(evt); + if (mDragLook) + { + mCameraMan->setStyle(CS_FREELOOK); + mTrayMgr->hideCursor(); + } + + mCameraMan->injectMouseDown(evt); - return true; - } + return true; + } #else - virtual bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id) - { - if (mTrayMgr->injectMouseDown(evt, id)) return true; + virtual bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + { + if (mTrayMgr->injectMouseDown(evt, id)) return true; - if (mDragLook && id == OIS::MB_Left) - { - mCameraMan->setStyle(CS_FREELOOK); - mTrayMgr->hideCursor(); - } + if (mDragLook && id == OIS::MB_Left) + { + mCameraMan->setStyle(CS_FREELOOK); + mTrayMgr->hideCursor(); + } - mCameraMan->injectMouseDown(evt, id); + mCameraMan->injectMouseDown(evt, id); - return true; - } + return true; + } #endif #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - virtual bool touchReleased(const OIS::MultiTouchEvent& evt) - { - if (mTrayMgr->injectMouseUp(evt)) return true; + virtual bool touchReleased(const OIS::MultiTouchEvent& evt) + { + if (mTrayMgr->injectMouseUp(evt)) return true; - if (mDragLook) - { - mCameraMan->setStyle(CS_MANUAL); - mTrayMgr->showCursor(); - } + if (mDragLook) + { + mCameraMan->setStyle(CS_MANUAL); + mTrayMgr->showCursor(); + } - mCameraMan->injectMouseUp(evt); + mCameraMan->injectMouseUp(evt); - return true; - } + return true; + } #else - virtual bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id) - { - if (mTrayMgr->injectMouseUp(evt, id)) return true; + virtual bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + { + if (mTrayMgr->injectMouseUp(evt, id)) return true; - if (mDragLook && id == OIS::MB_Left) - { - mCameraMan->setStyle(CS_MANUAL); - mTrayMgr->showCursor(); - } + if (mDragLook && id == OIS::MB_Left) + { + mCameraMan->setStyle(CS_MANUAL); + mTrayMgr->showCursor(); + } - mCameraMan->injectMouseUp(evt, id); + mCameraMan->injectMouseUp(evt, id); - return true; - } + return true; + } #endif - /*----------------------------------------------------------------------------- - | Extended to setup a default tray interface and camera controller. - -----------------------------------------------------------------------------*/ - virtual void _setup(Ogre::RenderWindow* window, InputContext inputContext, Ogre::FileSystemLayer* fsLayer, Ogre::OverlaySystem* overlaySys) - { - // assign mRoot here in case Root was initialised after the Sample's constructor ran. - mRoot = Ogre::Root::getSingletonPtr(); - mWindow = window; - mInputContext = inputContext; - mFSLayer = fsLayer; - mOverlaySystem = overlaySys; - - locateResources(); - createSceneManager(); - setupView(); - - mTrayMgr = new SdkTrayManager("SampleControls", window, inputContext, this); // create a tray interface - - loadResources(); - mResourcesLoaded = true; - - // show stats and logo and hide the cursor - mTrayMgr->showFrameStats(TL_BOTTOMLEFT); - mTrayMgr->showLogo(TL_BOTTOMRIGHT); - mTrayMgr->hideCursor(); - - // create a params panel for displaying sample details - Ogre::StringVector items; - items.push_back("cam.pX"); - items.push_back("cam.pY"); - items.push_back("cam.pZ"); - items.push_back(""); - items.push_back("cam.oW"); - items.push_back("cam.oX"); - items.push_back("cam.oY"); - items.push_back("cam.oZ"); - items.push_back(""); - items.push_back("Filtering"); - items.push_back("Poly Mode"); + /*----------------------------------------------------------------------------- + | Extended to setup a default tray interface and camera controller. + -----------------------------------------------------------------------------*/ + virtual void _setup(Ogre::RenderWindow* window, InputContext inputContext, Ogre::FileSystemLayer* fsLayer, Ogre::OverlaySystem* overlaySys) + { + // assign mRoot here in case Root was initialised after the Sample's constructor ran. + mRoot = Ogre::Root::getSingletonPtr(); + mWindow = window; + mInputContext = inputContext; + mFSLayer = fsLayer; + mOverlaySystem = overlaySys; + + locateResources(); + createSceneManager(); + setupView(); + + mTrayMgr = new SdkTrayManager("SampleControls", window, inputContext, this); // create a tray interface + + loadResources(); + mResourcesLoaded = true; + + // show stats and logo and hide the cursor + mTrayMgr->showFrameStats(TL_BOTTOMLEFT); + mTrayMgr->showLogo(TL_BOTTOMRIGHT); + mTrayMgr->hideCursor(); + + // create a params panel for displaying sample details + Ogre::StringVector items; + items.push_back("cam.pX"); + items.push_back("cam.pY"); + items.push_back("cam.pZ"); + items.push_back(""); + items.push_back("cam.oW"); + items.push_back("cam.oX"); + items.push_back("cam.oY"); + items.push_back("cam.oZ"); + items.push_back(""); + items.push_back("Filtering"); + items.push_back("Poly Mode"); #ifdef INCLUDE_RTSHADER_SYSTEM - items.push_back("RT Shaders"); - items.push_back("Lighting Model"); - items.push_back("Compact Policy"); - items.push_back("Generated VS"); - items.push_back("Generated FS"); - - // fix scene compositor for d3d11 - // Ogre::CompositorManager& compMgr = Ogre::CompositorManager::getSingleton(); - // Ogre::CompositorPtr scene = compMgr.getByName("Ogre/Scene/Default", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); - // scene->getTechnique(0)->getOutputTargetPass()->setMaterialScheme(Ogre::Root::getSingleton().getRenderSystem()->_getDefaultViewportMaterialScheme()); + items.push_back("RT Shaders"); + items.push_back("Lighting Model"); + items.push_back("Compact Policy"); + items.push_back("Generated VS"); + items.push_back("Generated FS"); + + // fix scene compositor for d3d11 + // Ogre::CompositorManager& compMgr = Ogre::CompositorManager::getSingleton(); + // Ogre::CompositorPtr scene = compMgr.getByName("Ogre/Scene/Default", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); + // scene->getTechnique(0)->getOutputTargetPass()->setMaterialScheme(Ogre::Root::getSingleton().getRenderSystem()->_getDefaultViewportMaterialScheme()); #endif - mDetailsPanel = mTrayMgr->createParamsPanel(TL_NONE, "DetailsPanel", 200, items); - mDetailsPanel->hide(); + mDetailsPanel = mTrayMgr->createParamsPanel(TL_NONE, "DetailsPanel", 200, items); + mDetailsPanel->hide(); - mDetailsPanel->setParamValue(9, "Bilinear"); - mDetailsPanel->setParamValue(10, "Solid"); + mDetailsPanel->setParamValue(9, "Bilinear"); + mDetailsPanel->setParamValue(10, "Solid"); #ifdef INCLUDE_RTSHADER_SYSTEM - mDetailsPanel->setParamValue(11, "Off"); + mDetailsPanel->setParamValue(11, "Off"); Ogre::Viewport* mainVP = mCamera->getViewport(); //const Ogre::String& curMaterialScheme = mainVP->getMaterialScheme(); @@ -491,67 +491,67 @@ namespace OgreBites mainVP->setMaterialScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); mDetailsPanel->setParamValue(11, "On"); } - mDetailsPanel->setParamValue(12, "Vertex"); - mDetailsPanel->setParamValue(13, "Low"); - mDetailsPanel->setParamValue(14, "0"); - mDetailsPanel->setParamValue(15, "0"); + mDetailsPanel->setParamValue(12, "Vertex"); + mDetailsPanel->setParamValue(13, "Low"); + mDetailsPanel->setParamValue(14, "0"); + mDetailsPanel->setParamValue(15, "0"); #endif - setupContent(); - mContentSetup = true; + setupContent(); + mContentSetup = true; - mDone = false; - } + mDone = false; + } - virtual void _shutdown() - { - Sample::_shutdown(); + virtual void _shutdown() + { + Sample::_shutdown(); if (mTrayMgr) delete mTrayMgr; - if (mCameraMan) delete mCameraMan; + if (mCameraMan) delete mCameraMan; - // restore settings we may have changed, so as not to affect other samples - Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_BILINEAR); - Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1); - } + // restore settings we may have changed, so as not to affect other samples + Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_BILINEAR); + Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1); + } protected: - virtual void setupView() - { - // setup default viewport layout and camera - mCamera = mSceneMgr->createCamera("MainCamera"); - mViewport = mWindow->addViewport(mCamera); - mCamera->setAspectRatio((Ogre::Real)mViewport->getActualWidth() / (Ogre::Real)mViewport->getActualHeight()); + virtual void setupView() + { + // setup default viewport layout and camera + mCamera = mSceneMgr->createCamera("MainCamera"); + mViewport = mWindow->addViewport(mCamera); + mCamera->setAspectRatio((Ogre::Real)mViewport->getActualWidth() / (Ogre::Real)mViewport->getActualHeight()); mCamera->setAutoAspectRatio(true); - mCamera->setNearClipDistance(5); - - mCameraMan = new SdkCameraMan(mCamera); // create a default camera controller - } - - virtual void setDragLook(bool enabled) - { - if (enabled) - { - mCameraMan->setStyle(CS_MANUAL); - mTrayMgr->showCursor(); - mDragLook = true; - } - else - { - mCameraMan->setStyle(CS_FREELOOK); - mTrayMgr->hideCursor(); - mDragLook = false; - } - } - - Ogre::Viewport* mViewport; // main viewport - Ogre::Camera* mCamera; // main camera - SdkTrayManager* mTrayMgr; // tray interface manager - SdkCameraMan* mCameraMan; // basic camera controller - ParamsPanel* mDetailsPanel; // sample details panel - bool mCursorWasVisible; // was cursor visible before dialog appeared - bool mDragLook; // click and drag to free-look + mCamera->setNearClipDistance(5); + + mCameraMan = new SdkCameraMan(mCamera); // create a default camera controller + } + + virtual void setDragLook(bool enabled) + { + if (enabled) + { + mCameraMan->setStyle(CS_MANUAL); + mTrayMgr->showCursor(); + mDragLook = true; + } + else + { + mCameraMan->setStyle(CS_FREELOOK); + mTrayMgr->hideCursor(); + mDragLook = false; + } + } + + Ogre::Viewport* mViewport; // main viewport + Ogre::Camera* mCamera; // main camera + SdkTrayManager* mTrayMgr; // tray interface manager + SdkCameraMan* mCameraMan; // basic camera controller + ParamsPanel* mDetailsPanel; // sample details panel + bool mCursorWasVisible; // was cursor visible before dialog appeared + bool mDragLook; // click and drag to free-look }; } diff --git a/Samples/Common/include/SdkTrays.h b/Samples/Common/include/SdkTrays.h index bd3b8cd03a2..fcfb175845a 100644 --- a/Samples/Common/include/SdkTrays.h +++ b/Samples/Common/include/SdkTrays.h @@ -45,1884 +45,1884 @@ #endif #if OGRE_UNICODE_SUPPORT -# if OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR -# define DISPLAY_STRING_TO_STRING(DS) (DS.asUTF8_c_str()) -# else -# define DISPLAY_STRING_TO_STRING(DS) (DS.asUTF8()) -# endif +# if OGRE_STRING_USE_CUSTOM_MEMORY_ALLOCATOR +# define DISPLAY_STRING_TO_STRING(DS) (DS.asUTF8_c_str()) +# else +# define DISPLAY_STRING_TO_STRING(DS) (DS.asUTF8()) +# endif #else - #define DISPLAY_STRING_TO_STRING(DS) (DS) + #define DISPLAY_STRING_TO_STRING(DS) (DS) #endif namespace OgreBites { - enum TrayLocation // enumerator values for widget tray anchoring locations - { - TL_TOPLEFT, - TL_TOP, - TL_TOPRIGHT, - TL_LEFT, - TL_CENTER, - TL_RIGHT, - TL_BOTTOMLEFT, - TL_BOTTOM, - TL_BOTTOMRIGHT, - TL_NONE - }; - - enum ButtonState // enumerator values for button states - { - BS_UP, - BS_OVER, - BS_DOWN - }; - - // forward widget class declarations - class Widget; - class Button; - class SelectMenu; - class Label; - class Slider; - class CheckBox; - - /*============================================================================= - | Listener class for responding to tray events. - =============================================================================*/ - class SdkTrayListener + enum TrayLocation // enumerator values for widget tray anchoring locations + { + TL_TOPLEFT, + TL_TOP, + TL_TOPRIGHT, + TL_LEFT, + TL_CENTER, + TL_RIGHT, + TL_BOTTOMLEFT, + TL_BOTTOM, + TL_BOTTOMRIGHT, + TL_NONE + }; + + enum ButtonState // enumerator values for button states + { + BS_UP, + BS_OVER, + BS_DOWN + }; + + // forward widget class declarations + class Widget; + class Button; + class SelectMenu; + class Label; + class Slider; + class CheckBox; + + /*============================================================================= + | Listener class for responding to tray events. + =============================================================================*/ + class SdkTrayListener { public: - virtual ~SdkTrayListener() {} - virtual void buttonHit(Button* button) {} - virtual void itemSelected(SelectMenu* menu) {} - virtual void labelHit(Label* label) {} - virtual void sliderMoved(Slider* slider) {} - virtual void checkBoxToggled(CheckBox* box) {} - virtual void okDialogClosed(const Ogre::DisplayString& message) {} - virtual void yesNoDialogClosed(const Ogre::DisplayString& question, bool yesHit) {} + virtual ~SdkTrayListener() {} + virtual void buttonHit(Button* button) {} + virtual void itemSelected(SelectMenu* menu) {} + virtual void labelHit(Label* label) {} + virtual void sliderMoved(Slider* slider) {} + virtual void checkBoxToggled(CheckBox* box) {} + virtual void okDialogClosed(const Ogre::DisplayString& message) {} + virtual void yesNoDialogClosed(const Ogre::DisplayString& question, bool yesHit) {} }; - /*============================================================================= - | Abstract base class for all widgets. - =============================================================================*/ - class Widget - { - public: - - Widget() - { - mTrayLoc = TL_NONE; - mElement = 0; - mListener = 0; - } - - virtual ~Widget() {} - - void cleanup() - { - if (mElement) nukeOverlayElement(mElement); - mElement = 0; - } - - /*----------------------------------------------------------------------------- - | Static utility method to recursively delete an overlay element plus - | all of its children from the system. - -----------------------------------------------------------------------------*/ - static void nukeOverlayElement(Ogre::OverlayElement* element) - { - Ogre::OverlayContainer* container = dynamic_cast(element); - if (container) - { - std::vector toDelete; - - Ogre::OverlayContainer::ChildIterator children = container->getChildIterator(); - while (children.hasMoreElements()) - { - toDelete.push_back(children.getNext()); - } - - for (unsigned int i = 0; i < toDelete.size(); i++) - { - nukeOverlayElement(toDelete[i]); - } - } - if (element) - { - Ogre::OverlayContainer* parent = element->getParent(); - if (parent) parent->removeChild(element->getName()); - Ogre::OverlayManager::getSingleton().destroyOverlayElement(element); - } - } - - /*----------------------------------------------------------------------------- - | Static utility method to check if the cursor is over an overlay element. - -----------------------------------------------------------------------------*/ - static bool isCursorOver(Ogre::OverlayElement* element, const Ogre::Vector2& cursorPos, Ogre::Real voidBorder = 0) - { - Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); + /*============================================================================= + | Abstract base class for all widgets. + =============================================================================*/ + class Widget + { + public: + + Widget() + { + mTrayLoc = TL_NONE; + mElement = 0; + mListener = 0; + } + + virtual ~Widget() {} + + void cleanup() + { + if (mElement) nukeOverlayElement(mElement); + mElement = 0; + } + + /*----------------------------------------------------------------------------- + | Static utility method to recursively delete an overlay element plus + | all of its children from the system. + -----------------------------------------------------------------------------*/ + static void nukeOverlayElement(Ogre::OverlayElement* element) + { + Ogre::OverlayContainer* container = dynamic_cast(element); + if (container) + { + std::vector toDelete; + + Ogre::OverlayContainer::ChildIterator children = container->getChildIterator(); + while (children.hasMoreElements()) + { + toDelete.push_back(children.getNext()); + } + + for (unsigned int i = 0; i < toDelete.size(); i++) + { + nukeOverlayElement(toDelete[i]); + } + } + if (element) + { + Ogre::OverlayContainer* parent = element->getParent(); + if (parent) parent->removeChild(element->getName()); + Ogre::OverlayManager::getSingleton().destroyOverlayElement(element); + } + } + + /*----------------------------------------------------------------------------- + | Static utility method to check if the cursor is over an overlay element. + -----------------------------------------------------------------------------*/ + static bool isCursorOver(Ogre::OverlayElement* element, const Ogre::Vector2& cursorPos, Ogre::Real voidBorder = 0) + { + Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); Ogre::Real l = element->_getDerivedLeft() * om.getViewportWidth(); Ogre::Real t = element->_getDerivedTop() * om.getViewportHeight(); Ogre::Real r = l + element->getWidth(); Ogre::Real b = t + element->getHeight(); - return (cursorPos.x >= l + voidBorder && cursorPos.x <= r - voidBorder && - cursorPos.y >= t + voidBorder && cursorPos.y <= b - voidBorder); - } - - /*----------------------------------------------------------------------------- - | Static utility method used to get the cursor's offset from the center - | of an overlay element in pixels. - -----------------------------------------------------------------------------*/ - static Ogre::Vector2 cursorOffset(Ogre::OverlayElement* element, const Ogre::Vector2& cursorPos) - { - Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); - return Ogre::Vector2(cursorPos.x - (element->_getDerivedLeft() * om.getViewportWidth() + element->getWidth() / 2), - cursorPos.y - (element->_getDerivedTop() * om.getViewportHeight() + element->getHeight() / 2)); - } - - /*----------------------------------------------------------------------------- - | Static utility method used to get the width of a caption in a text area. - -----------------------------------------------------------------------------*/ - static Ogre::Real getCaptionWidth(const Ogre::DisplayString& caption, Ogre::TextAreaOverlayElement* area) - { - Ogre::Font* font = (Ogre::Font*)Ogre::FontManager::getSingleton().getByName(area->getFontName()).getPointer(); - Ogre::String current = DISPLAY_STRING_TO_STRING(caption); - Ogre::Real lineWidth = 0; - - for (unsigned int i = 0; i < current.length(); i++) - { - // be sure to provide a line width in the text area - if (current[i] == ' ') - { - if (area->getSpaceWidth() != 0) lineWidth += area->getSpaceWidth(); - else lineWidth += font->getGlyphAspectRatio(' ') * area->getCharHeight(); - } - else if (current[i] == '\n') break; - // use glyph information to calculate line width - else lineWidth += font->getGlyphAspectRatio(current[i]) * area->getCharHeight(); - } - - return (unsigned int)lineWidth; - } - - /*----------------------------------------------------------------------------- - | Static utility method to cut off a string to fit in a text area. - -----------------------------------------------------------------------------*/ - static void fitCaptionToArea(const Ogre::DisplayString& caption, Ogre::TextAreaOverlayElement* area, Ogre::Real maxWidth) - { - Ogre::Font* f = (Ogre::Font*)Ogre::FontManager::getSingleton().getByName(area->getFontName()).getPointer(); - Ogre::String s = DISPLAY_STRING_TO_STRING(caption); - - size_t nl = s.find('\n'); - if (nl != Ogre::String::npos) s = s.substr(0, nl); - - Ogre::Real width = 0; - - for (unsigned int i = 0; i < s.length(); i++) - { - if (s[i] == ' ' && area->getSpaceWidth() != 0) width += area->getSpaceWidth(); - else width += f->getGlyphAspectRatio(s[i]) * area->getCharHeight(); - if (width > maxWidth) - { - s = s.substr(0, i); - break; - } - } - - area->setCaption(s); - } - - Ogre::OverlayElement* getOverlayElement() - { - return mElement; - } - - const Ogre::String& getName() - { - return mElement->getName(); - } - - TrayLocation getTrayLocation() - { - return mTrayLoc; - } - - void hide() - { - mElement->hide(); - } - - void show() - { - mElement->show(); - } - - bool isVisible() - { - return mElement->isVisible(); - } - - // callbacks - - virtual void _cursorPressed(const Ogre::Vector2& cursorPos) {} - virtual void _cursorReleased(const Ogre::Vector2& cursorPos) {} - virtual void _cursorMoved(const Ogre::Vector2& cursorPos) {} - virtual void _focusLost() {} - - // internal methods used by SdkTrayManager. do not call directly. - - void _assignToTray(TrayLocation trayLoc) { mTrayLoc = trayLoc; } - void _assignListener(SdkTrayListener* listener) { mListener = listener; } - - protected: - - Ogre::OverlayElement* mElement; - TrayLocation mTrayLoc; - SdkTrayListener* mListener; - }; - - typedef std::vector WidgetList; - typedef Ogre::VectorIterator WidgetIterator; - - /*============================================================================= - | Basic button class. - =============================================================================*/ - class Button : public Widget - { - public: - - // Do not instantiate any widgets directly. Use SdkTrayManager. - Button(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width) - { - mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate("SdkTrays/Button", "BorderPanel", name); - mBP = (Ogre::BorderPanelOverlayElement*)mElement; - mTextArea = (Ogre::TextAreaOverlayElement*)mBP->getChild(mBP->getName() + "/ButtonCaption"); + return (cursorPos.x >= l + voidBorder && cursorPos.x <= r - voidBorder && + cursorPos.y >= t + voidBorder && cursorPos.y <= b - voidBorder); + } + + /*----------------------------------------------------------------------------- + | Static utility method used to get the cursor's offset from the center + | of an overlay element in pixels. + -----------------------------------------------------------------------------*/ + static Ogre::Vector2 cursorOffset(Ogre::OverlayElement* element, const Ogre::Vector2& cursorPos) + { + Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); + return Ogre::Vector2(cursorPos.x - (element->_getDerivedLeft() * om.getViewportWidth() + element->getWidth() / 2), + cursorPos.y - (element->_getDerivedTop() * om.getViewportHeight() + element->getHeight() / 2)); + } + + /*----------------------------------------------------------------------------- + | Static utility method used to get the width of a caption in a text area. + -----------------------------------------------------------------------------*/ + static Ogre::Real getCaptionWidth(const Ogre::DisplayString& caption, Ogre::TextAreaOverlayElement* area) + { + Ogre::Font* font = (Ogre::Font*)Ogre::FontManager::getSingleton().getByName(area->getFontName()).getPointer(); + Ogre::String current = DISPLAY_STRING_TO_STRING(caption); + Ogre::Real lineWidth = 0; + + for (unsigned int i = 0; i < current.length(); i++) + { + // be sure to provide a line width in the text area + if (current[i] == ' ') + { + if (area->getSpaceWidth() != 0) lineWidth += area->getSpaceWidth(); + else lineWidth += font->getGlyphAspectRatio(' ') * area->getCharHeight(); + } + else if (current[i] == '\n') break; + // use glyph information to calculate line width + else lineWidth += font->getGlyphAspectRatio(current[i]) * area->getCharHeight(); + } + + return (unsigned int)lineWidth; + } + + /*----------------------------------------------------------------------------- + | Static utility method to cut off a string to fit in a text area. + -----------------------------------------------------------------------------*/ + static void fitCaptionToArea(const Ogre::DisplayString& caption, Ogre::TextAreaOverlayElement* area, Ogre::Real maxWidth) + { + Ogre::Font* f = (Ogre::Font*)Ogre::FontManager::getSingleton().getByName(area->getFontName()).getPointer(); + Ogre::String s = DISPLAY_STRING_TO_STRING(caption); + + size_t nl = s.find('\n'); + if (nl != Ogre::String::npos) s = s.substr(0, nl); + + Ogre::Real width = 0; + + for (unsigned int i = 0; i < s.length(); i++) + { + if (s[i] == ' ' && area->getSpaceWidth() != 0) width += area->getSpaceWidth(); + else width += f->getGlyphAspectRatio(s[i]) * area->getCharHeight(); + if (width > maxWidth) + { + s = s.substr(0, i); + break; + } + } + + area->setCaption(s); + } + + Ogre::OverlayElement* getOverlayElement() + { + return mElement; + } + + const Ogre::String& getName() + { + return mElement->getName(); + } + + TrayLocation getTrayLocation() + { + return mTrayLoc; + } + + void hide() + { + mElement->hide(); + } + + void show() + { + mElement->show(); + } + + bool isVisible() + { + return mElement->isVisible(); + } + + // callbacks + + virtual void _cursorPressed(const Ogre::Vector2& cursorPos) {} + virtual void _cursorReleased(const Ogre::Vector2& cursorPos) {} + virtual void _cursorMoved(const Ogre::Vector2& cursorPos) {} + virtual void _focusLost() {} + + // internal methods used by SdkTrayManager. do not call directly. + + void _assignToTray(TrayLocation trayLoc) { mTrayLoc = trayLoc; } + void _assignListener(SdkTrayListener* listener) { mListener = listener; } + + protected: + + Ogre::OverlayElement* mElement; + TrayLocation mTrayLoc; + SdkTrayListener* mListener; + }; + + typedef std::vector WidgetList; + typedef Ogre::VectorIterator WidgetIterator; + + /*============================================================================= + | Basic button class. + =============================================================================*/ + class Button : public Widget + { + public: + + // Do not instantiate any widgets directly. Use SdkTrayManager. + Button(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width) + { + mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate("SdkTrays/Button", "BorderPanel", name); + mBP = (Ogre::BorderPanelOverlayElement*)mElement; + mTextArea = (Ogre::TextAreaOverlayElement*)mBP->getChild(mBP->getName() + "/ButtonCaption"); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS mTextArea->setCharHeight(mTextArea->getCharHeight() - 3); #endif - mTextArea->setTop(-(mTextArea->getCharHeight() / 2)); - - if (width > 0) - { - mElement->setWidth(width); - mFitToContents = false; - } - else mFitToContents = true; - - setCaption(caption); - mState = BS_UP; - } - - virtual ~Button() {} - - const Ogre::DisplayString& getCaption() - { - return mTextArea->getCaption(); - } - - void setCaption(const Ogre::DisplayString& caption) - { - mTextArea->setCaption(caption); - if (mFitToContents) mElement->setWidth(getCaptionWidth(caption, mTextArea) + mElement->getHeight() - 12); - } - - const ButtonState& getState() { return mState; } - - void _cursorPressed(const Ogre::Vector2& cursorPos) - { - if (isCursorOver(mElement, cursorPos, 4)) setState(BS_DOWN); - } - - void _cursorReleased(const Ogre::Vector2& cursorPos) - { - if (mState == BS_DOWN) - { - setState(BS_OVER); - if (mListener) mListener->buttonHit(this); - } - } - - void _cursorMoved(const Ogre::Vector2& cursorPos) - { - if (isCursorOver(mElement, cursorPos, 4)) - { - if (mState == BS_UP) setState(BS_OVER); - } - else - { - if (mState != BS_UP) setState(BS_UP); - } - } - - void _focusLost() - { - setState(BS_UP); // reset button if cursor was lost - } - - protected: - - void setState(const ButtonState& bs) - { - if (bs == BS_OVER) - { - mBP->setBorderMaterialName("SdkTrays/Button/Over"); - mBP->setMaterialName("SdkTrays/Button/Over"); - } - else if (bs == BS_UP) - { - mBP->setBorderMaterialName("SdkTrays/Button/Up"); - mBP->setMaterialName("SdkTrays/Button/Up"); - } - else - { - mBP->setBorderMaterialName("SdkTrays/Button/Down"); - mBP->setMaterialName("SdkTrays/Button/Down"); - } - - mState = bs; - } - - ButtonState mState; - Ogre::BorderPanelOverlayElement* mBP; - Ogre::TextAreaOverlayElement* mTextArea; - bool mFitToContents; - }; - - /*============================================================================= - | Scrollable text box widget. - =============================================================================*/ - class TextBox : public Widget - { - public: - - // Do not instantiate any widgets directly. Use SdkTrayManager. - TextBox(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width, Ogre::Real height) - { - mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate("SdkTrays/TextBox", "BorderPanel", name); - mElement->setWidth(width); - mElement->setHeight(height); - Ogre::OverlayContainer* container = (Ogre::OverlayContainer*)mElement; - mTextArea = (Ogre::TextAreaOverlayElement*)container->getChild(getName() + "/TextBoxText"); - mCaptionBar = (Ogre::BorderPanelOverlayElement*)container->getChild(getName() + "/TextBoxCaptionBar"); - mCaptionBar->setWidth(width - 4); - mCaptionTextArea = (Ogre::TextAreaOverlayElement*)mCaptionBar->getChild(mCaptionBar->getName() + "/TextBoxCaption"); - setCaption(caption); - mScrollTrack = (Ogre::BorderPanelOverlayElement*)container->getChild(getName() + "/TextBoxScrollTrack"); - mScrollHandle = (Ogre::PanelOverlayElement*)mScrollTrack->getChild(mScrollTrack->getName() + "/TextBoxScrollHandle"); - mScrollHandle->hide(); - mDragging = false; - mScrollPercentage = 0; - mStartingLine = 0; - mPadding = 15; - mText = ""; + mTextArea->setTop(-(mTextArea->getCharHeight() / 2)); + + if (width > 0) + { + mElement->setWidth(width); + mFitToContents = false; + } + else mFitToContents = true; + + setCaption(caption); + mState = BS_UP; + } + + virtual ~Button() {} + + const Ogre::DisplayString& getCaption() + { + return mTextArea->getCaption(); + } + + void setCaption(const Ogre::DisplayString& caption) + { + mTextArea->setCaption(caption); + if (mFitToContents) mElement->setWidth(getCaptionWidth(caption, mTextArea) + mElement->getHeight() - 12); + } + + const ButtonState& getState() { return mState; } + + void _cursorPressed(const Ogre::Vector2& cursorPos) + { + if (isCursorOver(mElement, cursorPos, 4)) setState(BS_DOWN); + } + + void _cursorReleased(const Ogre::Vector2& cursorPos) + { + if (mState == BS_DOWN) + { + setState(BS_OVER); + if (mListener) mListener->buttonHit(this); + } + } + + void _cursorMoved(const Ogre::Vector2& cursorPos) + { + if (isCursorOver(mElement, cursorPos, 4)) + { + if (mState == BS_UP) setState(BS_OVER); + } + else + { + if (mState != BS_UP) setState(BS_UP); + } + } + + void _focusLost() + { + setState(BS_UP); // reset button if cursor was lost + } + + protected: + + void setState(const ButtonState& bs) + { + if (bs == BS_OVER) + { + mBP->setBorderMaterialName("SdkTrays/Button/Over"); + mBP->setMaterialName("SdkTrays/Button/Over"); + } + else if (bs == BS_UP) + { + mBP->setBorderMaterialName("SdkTrays/Button/Up"); + mBP->setMaterialName("SdkTrays/Button/Up"); + } + else + { + mBP->setBorderMaterialName("SdkTrays/Button/Down"); + mBP->setMaterialName("SdkTrays/Button/Down"); + } + + mState = bs; + } + + ButtonState mState; + Ogre::BorderPanelOverlayElement* mBP; + Ogre::TextAreaOverlayElement* mTextArea; + bool mFitToContents; + }; + + /*============================================================================= + | Scrollable text box widget. + =============================================================================*/ + class TextBox : public Widget + { + public: + + // Do not instantiate any widgets directly. Use SdkTrayManager. + TextBox(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width, Ogre::Real height) + { + mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate("SdkTrays/TextBox", "BorderPanel", name); + mElement->setWidth(width); + mElement->setHeight(height); + Ogre::OverlayContainer* container = (Ogre::OverlayContainer*)mElement; + mTextArea = (Ogre::TextAreaOverlayElement*)container->getChild(getName() + "/TextBoxText"); + mCaptionBar = (Ogre::BorderPanelOverlayElement*)container->getChild(getName() + "/TextBoxCaptionBar"); + mCaptionBar->setWidth(width - 4); + mCaptionTextArea = (Ogre::TextAreaOverlayElement*)mCaptionBar->getChild(mCaptionBar->getName() + "/TextBoxCaption"); + setCaption(caption); + mScrollTrack = (Ogre::BorderPanelOverlayElement*)container->getChild(getName() + "/TextBoxScrollTrack"); + mScrollHandle = (Ogre::PanelOverlayElement*)mScrollTrack->getChild(mScrollTrack->getName() + "/TextBoxScrollHandle"); + mScrollHandle->hide(); + mDragging = false; + mScrollPercentage = 0; + mStartingLine = 0; + mPadding = 15; + mText = ""; #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS mTextArea->setCharHeight(mTextArea->getCharHeight() - 3); mCaptionTextArea->setCharHeight(mCaptionTextArea->getCharHeight() - 3); #endif - refitContents(); - } - - void setPadding(Ogre::Real padding) - { - mPadding = padding; - refitContents(); - } - - Ogre::Real getPadding() - { - return mPadding; - } - - const Ogre::DisplayString& getCaption() - { - return mCaptionTextArea->getCaption(); - } - - void setCaption(const Ogre::DisplayString& caption) - { - mCaptionTextArea->setCaption(caption); - } - - const Ogre::DisplayString& getText() - { - return mText; - } - - /*----------------------------------------------------------------------------- - | Sets text box content. Most of this method is for wordwrap. - -----------------------------------------------------------------------------*/ - void setText(const Ogre::DisplayString& text) - { - mText = text; - mLines.clear(); - - Ogre::Font* font = (Ogre::Font*)Ogre::FontManager::getSingleton().getByName(mTextArea->getFontName()).getPointer(); + refitContents(); + } + + void setPadding(Ogre::Real padding) + { + mPadding = padding; + refitContents(); + } + + Ogre::Real getPadding() + { + return mPadding; + } + + const Ogre::DisplayString& getCaption() + { + return mCaptionTextArea->getCaption(); + } + + void setCaption(const Ogre::DisplayString& caption) + { + mCaptionTextArea->setCaption(caption); + } + + const Ogre::DisplayString& getText() + { + return mText; + } + + /*----------------------------------------------------------------------------- + | Sets text box content. Most of this method is for wordwrap. + -----------------------------------------------------------------------------*/ + void setText(const Ogre::DisplayString& text) + { + mText = text; + mLines.clear(); + + Ogre::Font* font = (Ogre::Font*)Ogre::FontManager::getSingleton().getByName(mTextArea->getFontName()).getPointer(); - Ogre::String current = DISPLAY_STRING_TO_STRING(text); - bool firstWord = true; - unsigned int lastSpace = 0; - unsigned int lineBegin = 0; - Ogre::Real lineWidth = 0; - Ogre::Real rightBoundary = mElement->getWidth() - 2 * mPadding + mScrollTrack->getLeft() + 10; - - for (unsigned int i = 0; i < current.length(); i++) - { - if (current[i] == ' ') - { - if (mTextArea->getSpaceWidth() != 0) lineWidth += mTextArea->getSpaceWidth(); - else lineWidth += font->getGlyphAspectRatio(' ') * mTextArea->getCharHeight(); - firstWord = false; - lastSpace = i; - } - else if (current[i] == '\n') - { - firstWord = true; - lineWidth = 0; - mLines.push_back(current.substr(lineBegin, i - lineBegin)); - lineBegin = i + 1; - } - else - { - // use glyph information to calculate line width - lineWidth += font->getGlyphAspectRatio(current[i]) * mTextArea->getCharHeight(); - if (lineWidth > rightBoundary) - { - if (firstWord) - { - current.insert(i, "\n"); - i = i - 1; - } - else - { - current[lastSpace] = '\n'; - i = lastSpace - 1; - } - } - } - } - - mLines.push_back(current.substr(lineBegin)); - - unsigned int maxLines = getHeightInLines(); - - if (mLines.size() > maxLines) // if too much text, filter based on scroll percentage - { - mScrollHandle->show(); - filterLines(); - } - else // otherwise just show all the text - { - mTextArea->setCaption(current); - mScrollHandle->hide(); - mScrollPercentage = 0; - mScrollHandle->setTop(0); - } - } - - /*----------------------------------------------------------------------------- - | Sets text box content horizontal alignment. - -----------------------------------------------------------------------------*/ - void setTextAlignment(Ogre::TextAreaOverlayElement::Alignment ta) - { - if (ta == Ogre::TextAreaOverlayElement::Left) mTextArea->setHorizontalAlignment(Ogre::GHA_LEFT); - else if (ta == Ogre::TextAreaOverlayElement::Center) mTextArea->setHorizontalAlignment(Ogre::GHA_CENTER); - else mTextArea->setHorizontalAlignment(Ogre::GHA_RIGHT); - refitContents(); - } - - void clearText() - { - setText(""); - } - - void appendText(const Ogre::DisplayString& text) - { - setText(getText() + text); - } - - /*----------------------------------------------------------------------------- - | Makes adjustments based on new padding, size, or alignment info. - -----------------------------------------------------------------------------*/ - void refitContents() - { - mScrollTrack->setHeight(mElement->getHeight() - mCaptionBar->getHeight() - 20); - mScrollTrack->setTop(mCaptionBar->getHeight() + 10); - - mTextArea->setTop(mCaptionBar->getHeight() + mPadding - 5); - if (mTextArea->getHorizontalAlignment() == Ogre::GHA_RIGHT) mTextArea->setLeft(-mPadding + mScrollTrack->getLeft()); - else if (mTextArea->getHorizontalAlignment() == Ogre::GHA_LEFT) mTextArea->setLeft(mPadding); - else mTextArea->setLeft(mScrollTrack->getLeft() / 2); - - setText(getText()); - } - - /*----------------------------------------------------------------------------- - | Sets how far scrolled down the text is as a percentage. - -----------------------------------------------------------------------------*/ - void setScrollPercentage(Ogre::Real percentage) - { - mScrollPercentage = Ogre::Math::Clamp(percentage, 0, 1); - mScrollHandle->setTop((int)(percentage * (mScrollTrack->getHeight() - mScrollHandle->getHeight()))); - filterLines(); - } - - /*----------------------------------------------------------------------------- - | Gets how far scrolled down the text is as a percentage. - -----------------------------------------------------------------------------*/ - Ogre::Real getScrollPercentage() - { - return mScrollPercentage; - } - - /*----------------------------------------------------------------------------- - | Gets how many lines of text can fit in this window. - -----------------------------------------------------------------------------*/ - unsigned int getHeightInLines() - { - return (unsigned int) ((mElement->getHeight() - 2 * mPadding - mCaptionBar->getHeight() + 5) / mTextArea->getCharHeight()); - } - - void _cursorPressed(const Ogre::Vector2& cursorPos) - { - if (!mScrollHandle->isVisible()) return; // don't care about clicks if text not scrollable - - Ogre::Vector2 co = Widget::cursorOffset(mScrollHandle, cursorPos); - - if (co.squaredLength() <= 81) - { - mDragging = true; - mDragOffset = co.y; - } - else if (Widget::isCursorOver(mScrollTrack, cursorPos)) - { - Ogre::Real newTop = mScrollHandle->getTop() + co.y; - Ogre::Real lowerBoundary = mScrollTrack->getHeight() - mScrollHandle->getHeight(); - mScrollHandle->setTop(Ogre::Math::Clamp((int)newTop, 0, (int)lowerBoundary)); - - // update text area contents based on new scroll percentage - mScrollPercentage = Ogre::Math::Clamp(newTop / lowerBoundary, 0, 1); - filterLines(); - } - } - - void _cursorReleased(const Ogre::Vector2& cursorPos) - { - mDragging = false; - } - - void _cursorMoved(const Ogre::Vector2& cursorPos) - { - if (mDragging) - { - Ogre::Vector2 co = Widget::cursorOffset(mScrollHandle, cursorPos); - Ogre::Real newTop = mScrollHandle->getTop() + co.y - mDragOffset; - Ogre::Real lowerBoundary = mScrollTrack->getHeight() - mScrollHandle->getHeight(); - mScrollHandle->setTop(Ogre::Math::Clamp((int)newTop, 0, (int)lowerBoundary)); - - // update text area contents based on new scroll percentage - mScrollPercentage = Ogre::Math::Clamp(newTop / lowerBoundary, 0, 1); - filterLines(); - } - } - - void _focusLost() - { - mDragging = false; // stop dragging if cursor was lost - } - - protected: - - /*----------------------------------------------------------------------------- - | Decides which lines to show. - -----------------------------------------------------------------------------*/ - void filterLines() - { - Ogre::String shown = ""; - unsigned int maxLines = getHeightInLines(); - unsigned int newStart = (unsigned int) (mScrollPercentage * (mLines.size() - maxLines) + 0.5); - - mStartingLine = newStart; - - for (unsigned int i = 0; i < maxLines; i++) - { - shown += mLines[mStartingLine + i] + "\n"; - } - - mTextArea->setCaption(shown); // show just the filtered lines - } - - Ogre::TextAreaOverlayElement* mTextArea; - Ogre::BorderPanelOverlayElement* mCaptionBar; - Ogre::TextAreaOverlayElement* mCaptionTextArea; - Ogre::BorderPanelOverlayElement* mScrollTrack; - Ogre::PanelOverlayElement* mScrollHandle; - Ogre::DisplayString mText; - Ogre::StringVector mLines; - Ogre::Real mPadding; - bool mDragging; - Ogre::Real mScrollPercentage; - Ogre::Real mDragOffset; - unsigned int mStartingLine; - }; - - /*============================================================================= - | Basic selection menu widget. - =============================================================================*/ - class SelectMenu : public Widget - { - public: - - // Do not instantiate any widgets directly. Use SdkTrayManager. - SelectMenu(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width, - Ogre::Real boxWidth, unsigned int maxItemsShown) - : mHighlightIndex(0) - , mDisplayIndex(0) - , mDragOffset(0.0f) - { - mSelectionIndex = -1; - mFitToContents = false; - mCursorOver = false; - mExpanded = false; - mDragging = false; - mMaxItemsShown = maxItemsShown; - mItemsShown = 0; - mElement = (Ogre::BorderPanelOverlayElement*)Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate - ("SdkTrays/SelectMenu", "BorderPanel", name); - mTextArea = (Ogre::TextAreaOverlayElement*)((Ogre::OverlayContainer*)mElement)->getChild(name + "/MenuCaption"); - mSmallBox = (Ogre::BorderPanelOverlayElement*)((Ogre::OverlayContainer*)mElement)->getChild(name + "/MenuSmallBox"); - mSmallBox->setWidth(width - 10); - mSmallTextArea = (Ogre::TextAreaOverlayElement*)mSmallBox->getChild(name + "/MenuSmallBox/MenuSmallText"); - mElement->setWidth(width); + Ogre::String current = DISPLAY_STRING_TO_STRING(text); + bool firstWord = true; + unsigned int lastSpace = 0; + unsigned int lineBegin = 0; + Ogre::Real lineWidth = 0; + Ogre::Real rightBoundary = mElement->getWidth() - 2 * mPadding + mScrollTrack->getLeft() + 10; + + for (unsigned int i = 0; i < current.length(); i++) + { + if (current[i] == ' ') + { + if (mTextArea->getSpaceWidth() != 0) lineWidth += mTextArea->getSpaceWidth(); + else lineWidth += font->getGlyphAspectRatio(' ') * mTextArea->getCharHeight(); + firstWord = false; + lastSpace = i; + } + else if (current[i] == '\n') + { + firstWord = true; + lineWidth = 0; + mLines.push_back(current.substr(lineBegin, i - lineBegin)); + lineBegin = i + 1; + } + else + { + // use glyph information to calculate line width + lineWidth += font->getGlyphAspectRatio(current[i]) * mTextArea->getCharHeight(); + if (lineWidth > rightBoundary) + { + if (firstWord) + { + current.insert(i, "\n"); + i = i - 1; + } + else + { + current[lastSpace] = '\n'; + i = lastSpace - 1; + } + } + } + } + + mLines.push_back(current.substr(lineBegin)); + + unsigned int maxLines = getHeightInLines(); + + if (mLines.size() > maxLines) // if too much text, filter based on scroll percentage + { + mScrollHandle->show(); + filterLines(); + } + else // otherwise just show all the text + { + mTextArea->setCaption(current); + mScrollHandle->hide(); + mScrollPercentage = 0; + mScrollHandle->setTop(0); + } + } + + /*----------------------------------------------------------------------------- + | Sets text box content horizontal alignment. + -----------------------------------------------------------------------------*/ + void setTextAlignment(Ogre::TextAreaOverlayElement::Alignment ta) + { + if (ta == Ogre::TextAreaOverlayElement::Left) mTextArea->setHorizontalAlignment(Ogre::GHA_LEFT); + else if (ta == Ogre::TextAreaOverlayElement::Center) mTextArea->setHorizontalAlignment(Ogre::GHA_CENTER); + else mTextArea->setHorizontalAlignment(Ogre::GHA_RIGHT); + refitContents(); + } + + void clearText() + { + setText(""); + } + + void appendText(const Ogre::DisplayString& text) + { + setText(getText() + text); + } + + /*----------------------------------------------------------------------------- + | Makes adjustments based on new padding, size, or alignment info. + -----------------------------------------------------------------------------*/ + void refitContents() + { + mScrollTrack->setHeight(mElement->getHeight() - mCaptionBar->getHeight() - 20); + mScrollTrack->setTop(mCaptionBar->getHeight() + 10); + + mTextArea->setTop(mCaptionBar->getHeight() + mPadding - 5); + if (mTextArea->getHorizontalAlignment() == Ogre::GHA_RIGHT) mTextArea->setLeft(-mPadding + mScrollTrack->getLeft()); + else if (mTextArea->getHorizontalAlignment() == Ogre::GHA_LEFT) mTextArea->setLeft(mPadding); + else mTextArea->setLeft(mScrollTrack->getLeft() / 2); + + setText(getText()); + } + + /*----------------------------------------------------------------------------- + | Sets how far scrolled down the text is as a percentage. + -----------------------------------------------------------------------------*/ + void setScrollPercentage(Ogre::Real percentage) + { + mScrollPercentage = Ogre::Math::Clamp(percentage, 0, 1); + mScrollHandle->setTop((int)(percentage * (mScrollTrack->getHeight() - mScrollHandle->getHeight()))); + filterLines(); + } + + /*----------------------------------------------------------------------------- + | Gets how far scrolled down the text is as a percentage. + -----------------------------------------------------------------------------*/ + Ogre::Real getScrollPercentage() + { + return mScrollPercentage; + } + + /*----------------------------------------------------------------------------- + | Gets how many lines of text can fit in this window. + -----------------------------------------------------------------------------*/ + unsigned int getHeightInLines() + { + return (unsigned int) ((mElement->getHeight() - 2 * mPadding - mCaptionBar->getHeight() + 5) / mTextArea->getCharHeight()); + } + + void _cursorPressed(const Ogre::Vector2& cursorPos) + { + if (!mScrollHandle->isVisible()) return; // don't care about clicks if text not scrollable + + Ogre::Vector2 co = Widget::cursorOffset(mScrollHandle, cursorPos); + + if (co.squaredLength() <= 81) + { + mDragging = true; + mDragOffset = co.y; + } + else if (Widget::isCursorOver(mScrollTrack, cursorPos)) + { + Ogre::Real newTop = mScrollHandle->getTop() + co.y; + Ogre::Real lowerBoundary = mScrollTrack->getHeight() - mScrollHandle->getHeight(); + mScrollHandle->setTop(Ogre::Math::Clamp((int)newTop, 0, (int)lowerBoundary)); + + // update text area contents based on new scroll percentage + mScrollPercentage = Ogre::Math::Clamp(newTop / lowerBoundary, 0, 1); + filterLines(); + } + } + + void _cursorReleased(const Ogre::Vector2& cursorPos) + { + mDragging = false; + } + + void _cursorMoved(const Ogre::Vector2& cursorPos) + { + if (mDragging) + { + Ogre::Vector2 co = Widget::cursorOffset(mScrollHandle, cursorPos); + Ogre::Real newTop = mScrollHandle->getTop() + co.y - mDragOffset; + Ogre::Real lowerBoundary = mScrollTrack->getHeight() - mScrollHandle->getHeight(); + mScrollHandle->setTop(Ogre::Math::Clamp((int)newTop, 0, (int)lowerBoundary)); + + // update text area contents based on new scroll percentage + mScrollPercentage = Ogre::Math::Clamp(newTop / lowerBoundary, 0, 1); + filterLines(); + } + } + + void _focusLost() + { + mDragging = false; // stop dragging if cursor was lost + } + + protected: + + /*----------------------------------------------------------------------------- + | Decides which lines to show. + -----------------------------------------------------------------------------*/ + void filterLines() + { + Ogre::String shown = ""; + unsigned int maxLines = getHeightInLines(); + unsigned int newStart = (unsigned int) (mScrollPercentage * (mLines.size() - maxLines) + 0.5); + + mStartingLine = newStart; + + for (unsigned int i = 0; i < maxLines; i++) + { + shown += mLines[mStartingLine + i] + "\n"; + } + + mTextArea->setCaption(shown); // show just the filtered lines + } + + Ogre::TextAreaOverlayElement* mTextArea; + Ogre::BorderPanelOverlayElement* mCaptionBar; + Ogre::TextAreaOverlayElement* mCaptionTextArea; + Ogre::BorderPanelOverlayElement* mScrollTrack; + Ogre::PanelOverlayElement* mScrollHandle; + Ogre::DisplayString mText; + Ogre::StringVector mLines; + Ogre::Real mPadding; + bool mDragging; + Ogre::Real mScrollPercentage; + Ogre::Real mDragOffset; + unsigned int mStartingLine; + }; + + /*============================================================================= + | Basic selection menu widget. + =============================================================================*/ + class SelectMenu : public Widget + { + public: + + // Do not instantiate any widgets directly. Use SdkTrayManager. + SelectMenu(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width, + Ogre::Real boxWidth, unsigned int maxItemsShown) + : mHighlightIndex(0) + , mDisplayIndex(0) + , mDragOffset(0.0f) + { + mSelectionIndex = -1; + mFitToContents = false; + mCursorOver = false; + mExpanded = false; + mDragging = false; + mMaxItemsShown = maxItemsShown; + mItemsShown = 0; + mElement = (Ogre::BorderPanelOverlayElement*)Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate + ("SdkTrays/SelectMenu", "BorderPanel", name); + mTextArea = (Ogre::TextAreaOverlayElement*)((Ogre::OverlayContainer*)mElement)->getChild(name + "/MenuCaption"); + mSmallBox = (Ogre::BorderPanelOverlayElement*)((Ogre::OverlayContainer*)mElement)->getChild(name + "/MenuSmallBox"); + mSmallBox->setWidth(width - 10); + mSmallTextArea = (Ogre::TextAreaOverlayElement*)mSmallBox->getChild(name + "/MenuSmallBox/MenuSmallText"); + mElement->setWidth(width); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS mTextArea->setCharHeight(mTextArea->getCharHeight() - 3); mSmallTextArea->setCharHeight(mSmallTextArea->getCharHeight() - 3); #endif - if (boxWidth > 0) // long style - { - if (width <= 0) mFitToContents = true; - mSmallBox->setWidth(boxWidth); - mSmallBox->setTop(2); - mSmallBox->setLeft(width - boxWidth - 5); - mElement->setHeight(mSmallBox->getHeight() + 4); - mTextArea->setHorizontalAlignment(Ogre::GHA_LEFT); - mTextArea->setAlignment(Ogre::TextAreaOverlayElement::Left); - mTextArea->setLeft(12); - mTextArea->setTop(10); - } - - mExpandedBox = (Ogre::BorderPanelOverlayElement*)((Ogre::OverlayContainer*)mElement)->getChild(name + "/MenuExpandedBox"); - mExpandedBox->setWidth(mSmallBox->getWidth() + 10); - mExpandedBox->hide(); - mScrollTrack = (Ogre::BorderPanelOverlayElement*)mExpandedBox->getChild(mExpandedBox->getName() + "/MenuScrollTrack"); - mScrollHandle = (Ogre::PanelOverlayElement*)mScrollTrack->getChild(mScrollTrack->getName() + "/MenuScrollHandle"); - - setCaption(caption); - } - void copyItemsFrom(SelectMenu* other){ - const Ogre::StringVector& items = other->getItems(); - Ogre::StringVector::const_iterator it, itEnd; - itEnd = items.end(); - for(it=items.begin(); it != itEnd; it++){ - this->addItem(*it); - } - } - bool isExpanded() - { - return mExpanded; - } - - const Ogre::DisplayString& getCaption() - { - return mTextArea->getCaption(); - } - - void setCaption(const Ogre::DisplayString& caption) - { - mTextArea->setCaption(caption); - if (mFitToContents) - { - mElement->setWidth(getCaptionWidth(caption, mTextArea) + mSmallBox->getWidth() + 23); - mSmallBox->setLeft(mElement->getWidth() - mSmallBox->getWidth() - 5); - } - } - - const Ogre::StringVector& getItems() - { - return mItems; - } - - size_t getNumItems() - { - return mItems.size(); - } - - void setItems(const Ogre::StringVector& items) - { - mItems = items; - mSelectionIndex = -1; - - for (unsigned int i = 0; i < mItemElements.size(); i++) // destroy all the item elements - { - nukeOverlayElement(mItemElements[i]); - } - mItemElements.clear(); - - mItemsShown = std::max(2, std::min(mMaxItemsShown, (int)mItems.size())); - - for (unsigned int i = 0; i < mItemsShown; i++) // create all the item elements - { - Ogre::BorderPanelOverlayElement* e = - (Ogre::BorderPanelOverlayElement*)Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate - ("SdkTrays/SelectMenuItem", "BorderPanel", - mExpandedBox->getName() + "/Item" + Ogre::StringConverter::toString(i + 1)); - - e->setTop(6 + i * (mSmallBox->getHeight() - 8)); - e->setWidth(mExpandedBox->getWidth() - 32); - - mExpandedBox->addChild(e); - mItemElements.push_back(e); - } - - if (!items.empty()) selectItem(0, false); - else mSmallTextArea->setCaption(""); - } - - void addItem(const Ogre::DisplayString& item) - { - mItems.push_back(item); - setItems(mItems); - } - - void insertItem(int index, const Ogre::DisplayString& item) - { - mItems.insert(mItems.begin() + index, item); - setItems(mItems); - } - - void removeItem(const Ogre::DisplayString& item) - { - for (size_t i=0; i < mItems.size(); i++) - { - if (item == mItems[i]) { - removeItem(static_cast(i)); - i--; // check again same index - } - } - } - - void removeItem(unsigned int index) - { - if(index >= mItems.size()){ - Ogre::String desc = "Menu \"" + getName() + "\" contains no item at position " + - Ogre::StringConverter::toString(index) + "."; - OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "SelectMenu::removeItem"); - } - mItems.erase(mItems.begin() + index); - - if (mItems.size() < mItemsShown) - { - mItemsShown = static_cast(mItems.size()); - nukeOverlayElement(mItemElements.back()); - mItemElements.pop_back(); - } - if((size_t)mSelectionIndex == index){ - if(index < mItems.size()) { - // update the text of the menu - selectItem(index); - } else if (!mItems.empty()){ - // last item was selected and we removed it - selectItem(index - 1); - } else { - // we had only 1 item, but we removed it, so clear caption - mSmallTextArea->setCaption(""); - } - } - } - - void clearItems() - { - mItems.clear(); - mSelectionIndex = -1; - mSmallTextArea->setCaption(""); - } - - size_t getItemsCount() - { - return mItems.size(); - } - - void selectItem(unsigned int index, bool notifyListener = true) - { - if (index >= mItems.size()) - { - Ogre::String desc = "Menu \"" + getName() + "\" contains no item at position " + - Ogre::StringConverter::toString(index) + "."; - OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "SelectMenu::selectItem"); - } - - mSelectionIndex = index; - fitCaptionToArea(mItems[index], mSmallTextArea, mSmallBox->getWidth() - mSmallTextArea->getLeft() * 2); - - if (mListener && notifyListener) mListener->itemSelected(this); - } - - bool containsItem(const Ogre::DisplayString& item) - { - bool res = false; - for (unsigned int i = 0; i < mItems.size(); i++) - { - if (item == mItems[i]) - { - res = true; - break; - } - } - - return res; - } - - void selectItem(const Ogre::DisplayString& item, bool notifyListener = true) - { - for (unsigned int i = 0; i < mItems.size(); i++) - { - if (item == mItems[i]) - { - selectItem(i, notifyListener); - return; - } - } - - Ogre::String desc = "Menu \"" + getName() + "\" contains no item \"" + item + "\"."; - OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "SelectMenu::selectItem"); - } - - Ogre::DisplayString getSelectedItem() - { - if (mSelectionIndex == -1) - { - Ogre::String desc = "Menu \"" + getName() + "\" has no item selected."; - OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "SelectMenu::getSelectedItem"); - return ""; - } - else return mItems[mSelectionIndex]; - } - - int getSelectionIndex() - { - return mSelectionIndex; - } - - void _cursorPressed(const Ogre::Vector2& cursorPos) - { - Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); - - if (mExpanded) - { - if (mScrollHandle->isVisible()) // check for scrolling - { - Ogre::Vector2 co = Widget::cursorOffset(mScrollHandle, cursorPos); - - if (co.squaredLength() <= 81) - { - mDragging = true; - mDragOffset = co.y; - return; - } - else if (Widget::isCursorOver(mScrollTrack, cursorPos)) - { - Ogre::Real newTop = mScrollHandle->getTop() + co.y; - Ogre::Real lowerBoundary = mScrollTrack->getHeight() - mScrollHandle->getHeight(); - mScrollHandle->setTop(Ogre::Math::Clamp((int)newTop, 0, (int)lowerBoundary)); - - Ogre::Real scrollPercentage = Ogre::Math::Clamp(newTop / lowerBoundary, 0, 1); - setDisplayIndex((unsigned int)(scrollPercentage * (mItems.size() - mItemElements.size()) + 0.5)); - return; - } - } - - if (!isCursorOver(mExpandedBox, cursorPos, 3)) retract(); - else - { - Ogre::Real l = mItemElements.front()->_getDerivedLeft() * om.getViewportWidth() + 5; - Ogre::Real t = mItemElements.front()->_getDerivedTop() * om.getViewportHeight() + 5; - Ogre::Real r = l + mItemElements.back()->getWidth() - 10; - Ogre::Real b = mItemElements.back()->_getDerivedTop() * om.getViewportHeight() + - mItemElements.back()->getHeight() - 5; - - if (cursorPos.x >= l && cursorPos.x <= r && cursorPos.y >= t && cursorPos.y <= b) - { - if (mHighlightIndex != mSelectionIndex) selectItem(mHighlightIndex); - retract(); - } - } - } - else - { - if (mItems.size() < 2) return; // don't waste time showing a menu if there's no choice - - if (isCursorOver(mSmallBox, cursorPos, 4)) - { - mExpandedBox->show(); - mSmallBox->hide(); - - // calculate how much vertical space we need - Ogre::Real idealHeight = mItemsShown * (mSmallBox->getHeight() - 8) + 20; - mExpandedBox->setHeight(idealHeight); - mScrollTrack->setHeight(mExpandedBox->getHeight() - 20); - - mExpandedBox->setLeft(mSmallBox->getLeft() - 4); - - // if the expanded menu goes down off the screen, make it go up instead - if (mSmallBox->_getDerivedTop() * om.getViewportHeight() + idealHeight > om.getViewportHeight()) - { - mExpandedBox->setTop(mSmallBox->getTop() + mSmallBox->getHeight() - idealHeight + 3); - // if we're in thick style, hide the caption because it will interfere with the expanded menu - if (mTextArea->getHorizontalAlignment() == Ogre::GHA_CENTER) mTextArea->hide(); - } - else mExpandedBox->setTop(mSmallBox->getTop() + 3); - - mExpanded = true; - mHighlightIndex = mSelectionIndex; - setDisplayIndex(mHighlightIndex); - - if (mItemsShown < mItems.size()) // update scrollbar position - { - mScrollHandle->show(); - Ogre::Real lowerBoundary = mScrollTrack->getHeight() - mScrollHandle->getHeight(); - mScrollHandle->setTop((int)(mDisplayIndex * lowerBoundary / (mItems.size() - mItemElements.size()))); - } - else mScrollHandle->hide(); - } - } - } - - void _cursorReleased(const Ogre::Vector2& cursorPos) - { - mDragging = false; - } - - void _cursorMoved(const Ogre::Vector2& cursorPos) - { - Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); - - if (mExpanded) - { - if (mDragging) - { - Ogre::Vector2 co = Widget::cursorOffset(mScrollHandle, cursorPos); - Ogre::Real newTop = mScrollHandle->getTop() + co.y - mDragOffset; - Ogre::Real lowerBoundary = mScrollTrack->getHeight() - mScrollHandle->getHeight(); - mScrollHandle->setTop(Ogre::Math::Clamp((int)newTop, 0, (int)lowerBoundary)); - - Ogre::Real scrollPercentage = Ogre::Math::Clamp(newTop / lowerBoundary, 0, 1); - int newIndex = (int) (scrollPercentage * (mItems.size() - mItemElements.size()) + 0.5); - if (newIndex != mDisplayIndex) setDisplayIndex(newIndex); - return; - } - - Ogre::Real l = mItemElements.front()->_getDerivedLeft() * om.getViewportWidth() + 5; - Ogre::Real t = mItemElements.front()->_getDerivedTop() * om.getViewportHeight() + 5; - Ogre::Real r = l + mItemElements.back()->getWidth() - 10; - Ogre::Real b = mItemElements.back()->_getDerivedTop() * om.getViewportHeight() + - mItemElements.back()->getHeight() - 5; - - if (cursorPos.x >= l && cursorPos.x <= r && cursorPos.y >= t && cursorPos.y <= b) - { - int newIndex = (int)(mDisplayIndex + (cursorPos.y - t) / (b - t) * mItemElements.size()); - if (mHighlightIndex != newIndex) - { - mHighlightIndex = newIndex; - setDisplayIndex(mDisplayIndex); - } - } - } - else - { - if (isCursorOver(mSmallBox, cursorPos, 4)) - { - mSmallBox->setMaterialName("SdkTrays/MiniTextBox/Over"); - mSmallBox->setBorderMaterialName("SdkTrays/MiniTextBox/Over"); - mCursorOver = true; - } - else - { - if (mCursorOver) - { - mSmallBox->setMaterialName("SdkTrays/MiniTextBox"); - mSmallBox->setBorderMaterialName("SdkTrays/MiniTextBox"); - mCursorOver = false; - } - } - } - } - - void _focusLost() - { - if (mExpandedBox->isVisible()) retract(); - } - - protected: - - /*----------------------------------------------------------------------------- - | Internal method - sets which item goes at the top of the expanded menu. - -----------------------------------------------------------------------------*/ - void setDisplayIndex(unsigned int index) - { - index = std::min(index, (int)(mItems.size() - mItemElements.size())); - mDisplayIndex = index; - - for (int i = 0; i < (int)mItemElements.size(); i++) - { - Ogre::BorderPanelOverlayElement *ie = mItemElements[i]; - Ogre::TextAreaOverlayElement *ta = (Ogre::TextAreaOverlayElement*)ie->getChild(ie->getName() + "/MenuItemText"); - - fitCaptionToArea(mItems[mDisplayIndex + i], ta, ie->getWidth() - 2 * ta->getLeft()); - - if ((mDisplayIndex + i) == mHighlightIndex) - { - ie->setMaterialName("SdkTrays/MiniTextBox/Over"); - ie->setBorderMaterialName("SdkTrays/MiniTextBox/Over"); - } - else - { - ie->setMaterialName("SdkTrays/MiniTextBox"); - ie->setBorderMaterialName("SdkTrays/MiniTextBox"); - } - } - } - - /*----------------------------------------------------------------------------- - | Internal method - cleans up an expanded menu. - -----------------------------------------------------------------------------*/ - void retract() - { - mDragging = false; - mExpanded = false; - mExpandedBox->hide(); - mTextArea->show(); - mSmallBox->show(); - mSmallBox->setMaterialName("SdkTrays/MiniTextBox"); - mSmallBox->setBorderMaterialName("SdkTrays/MiniTextBox"); - } - - Ogre::BorderPanelOverlayElement* mSmallBox; - Ogre::BorderPanelOverlayElement* mExpandedBox; - Ogre::TextAreaOverlayElement* mTextArea; - Ogre::TextAreaOverlayElement* mSmallTextArea; - Ogre::BorderPanelOverlayElement* mScrollTrack; - Ogre::PanelOverlayElement* mScrollHandle; - std::vector mItemElements; - unsigned int mMaxItemsShown; - unsigned int mItemsShown; - bool mCursorOver; - bool mExpanded; - bool mFitToContents; - bool mDragging; - Ogre::StringVector mItems; - int mSelectionIndex; - int mHighlightIndex; - int mDisplayIndex; - Ogre::Real mDragOffset; - }; - - /*============================================================================= - | Basic label widget. - =============================================================================*/ - class Label : public Widget - { - public: - - // Do not instantiate any widgets directly. Use SdkTrayManager. - Label(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width) - { - mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate("SdkTrays/Label", "BorderPanel", name); - mTextArea = (Ogre::TextAreaOverlayElement*)((Ogre::OverlayContainer*)mElement)->getChild(getName() + "/LabelCaption"); + if (boxWidth > 0) // long style + { + if (width <= 0) mFitToContents = true; + mSmallBox->setWidth(boxWidth); + mSmallBox->setTop(2); + mSmallBox->setLeft(width - boxWidth - 5); + mElement->setHeight(mSmallBox->getHeight() + 4); + mTextArea->setHorizontalAlignment(Ogre::GHA_LEFT); + mTextArea->setAlignment(Ogre::TextAreaOverlayElement::Left); + mTextArea->setLeft(12); + mTextArea->setTop(10); + } + + mExpandedBox = (Ogre::BorderPanelOverlayElement*)((Ogre::OverlayContainer*)mElement)->getChild(name + "/MenuExpandedBox"); + mExpandedBox->setWidth(mSmallBox->getWidth() + 10); + mExpandedBox->hide(); + mScrollTrack = (Ogre::BorderPanelOverlayElement*)mExpandedBox->getChild(mExpandedBox->getName() + "/MenuScrollTrack"); + mScrollHandle = (Ogre::PanelOverlayElement*)mScrollTrack->getChild(mScrollTrack->getName() + "/MenuScrollHandle"); + + setCaption(caption); + } + void copyItemsFrom(SelectMenu* other){ + const Ogre::StringVector& items = other->getItems(); + Ogre::StringVector::const_iterator it, itEnd; + itEnd = items.end(); + for(it=items.begin(); it != itEnd; it++){ + this->addItem(*it); + } + } + bool isExpanded() + { + return mExpanded; + } + + const Ogre::DisplayString& getCaption() + { + return mTextArea->getCaption(); + } + + void setCaption(const Ogre::DisplayString& caption) + { + mTextArea->setCaption(caption); + if (mFitToContents) + { + mElement->setWidth(getCaptionWidth(caption, mTextArea) + mSmallBox->getWidth() + 23); + mSmallBox->setLeft(mElement->getWidth() - mSmallBox->getWidth() - 5); + } + } + + const Ogre::StringVector& getItems() + { + return mItems; + } + + size_t getNumItems() + { + return mItems.size(); + } + + void setItems(const Ogre::StringVector& items) + { + mItems = items; + mSelectionIndex = -1; + + for (unsigned int i = 0; i < mItemElements.size(); i++) // destroy all the item elements + { + nukeOverlayElement(mItemElements[i]); + } + mItemElements.clear(); + + mItemsShown = std::max(2, std::min(mMaxItemsShown, (int)mItems.size())); + + for (unsigned int i = 0; i < mItemsShown; i++) // create all the item elements + { + Ogre::BorderPanelOverlayElement* e = + (Ogre::BorderPanelOverlayElement*)Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate + ("SdkTrays/SelectMenuItem", "BorderPanel", + mExpandedBox->getName() + "/Item" + Ogre::StringConverter::toString(i + 1)); + + e->setTop(6 + i * (mSmallBox->getHeight() - 8)); + e->setWidth(mExpandedBox->getWidth() - 32); + + mExpandedBox->addChild(e); + mItemElements.push_back(e); + } + + if (!items.empty()) selectItem(0, false); + else mSmallTextArea->setCaption(""); + } + + void addItem(const Ogre::DisplayString& item) + { + mItems.push_back(item); + setItems(mItems); + } + + void insertItem(int index, const Ogre::DisplayString& item) + { + mItems.insert(mItems.begin() + index, item); + setItems(mItems); + } + + void removeItem(const Ogre::DisplayString& item) + { + for (size_t i=0; i < mItems.size(); i++) + { + if (item == mItems[i]) { + removeItem(static_cast(i)); + i--; // check again same index + } + } + } + + void removeItem(unsigned int index) + { + if(index >= mItems.size()){ + Ogre::String desc = "Menu \"" + getName() + "\" contains no item at position " + + Ogre::StringConverter::toString(index) + "."; + OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "SelectMenu::removeItem"); + } + mItems.erase(mItems.begin() + index); + + if (mItems.size() < mItemsShown) + { + mItemsShown = static_cast(mItems.size()); + nukeOverlayElement(mItemElements.back()); + mItemElements.pop_back(); + } + if((size_t)mSelectionIndex == index){ + if(index < mItems.size()) { + // update the text of the menu + selectItem(index); + } else if (!mItems.empty()){ + // last item was selected and we removed it + selectItem(index - 1); + } else { + // we had only 1 item, but we removed it, so clear caption + mSmallTextArea->setCaption(""); + } + } + } + + void clearItems() + { + mItems.clear(); + mSelectionIndex = -1; + mSmallTextArea->setCaption(""); + } + + size_t getItemsCount() + { + return mItems.size(); + } + + void selectItem(unsigned int index, bool notifyListener = true) + { + if (index >= mItems.size()) + { + Ogre::String desc = "Menu \"" + getName() + "\" contains no item at position " + + Ogre::StringConverter::toString(index) + "."; + OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "SelectMenu::selectItem"); + } + + mSelectionIndex = index; + fitCaptionToArea(mItems[index], mSmallTextArea, mSmallBox->getWidth() - mSmallTextArea->getLeft() * 2); + + if (mListener && notifyListener) mListener->itemSelected(this); + } + + bool containsItem(const Ogre::DisplayString& item) + { + bool res = false; + for (unsigned int i = 0; i < mItems.size(); i++) + { + if (item == mItems[i]) + { + res = true; + break; + } + } + + return res; + } + + void selectItem(const Ogre::DisplayString& item, bool notifyListener = true) + { + for (unsigned int i = 0; i < mItems.size(); i++) + { + if (item == mItems[i]) + { + selectItem(i, notifyListener); + return; + } + } + + Ogre::String desc = "Menu \"" + getName() + "\" contains no item \"" + item + "\"."; + OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "SelectMenu::selectItem"); + } + + Ogre::DisplayString getSelectedItem() + { + if (mSelectionIndex == -1) + { + Ogre::String desc = "Menu \"" + getName() + "\" has no item selected."; + OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "SelectMenu::getSelectedItem"); + return ""; + } + else return mItems[mSelectionIndex]; + } + + int getSelectionIndex() + { + return mSelectionIndex; + } + + void _cursorPressed(const Ogre::Vector2& cursorPos) + { + Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); + + if (mExpanded) + { + if (mScrollHandle->isVisible()) // check for scrolling + { + Ogre::Vector2 co = Widget::cursorOffset(mScrollHandle, cursorPos); + + if (co.squaredLength() <= 81) + { + mDragging = true; + mDragOffset = co.y; + return; + } + else if (Widget::isCursorOver(mScrollTrack, cursorPos)) + { + Ogre::Real newTop = mScrollHandle->getTop() + co.y; + Ogre::Real lowerBoundary = mScrollTrack->getHeight() - mScrollHandle->getHeight(); + mScrollHandle->setTop(Ogre::Math::Clamp((int)newTop, 0, (int)lowerBoundary)); + + Ogre::Real scrollPercentage = Ogre::Math::Clamp(newTop / lowerBoundary, 0, 1); + setDisplayIndex((unsigned int)(scrollPercentage * (mItems.size() - mItemElements.size()) + 0.5)); + return; + } + } + + if (!isCursorOver(mExpandedBox, cursorPos, 3)) retract(); + else + { + Ogre::Real l = mItemElements.front()->_getDerivedLeft() * om.getViewportWidth() + 5; + Ogre::Real t = mItemElements.front()->_getDerivedTop() * om.getViewportHeight() + 5; + Ogre::Real r = l + mItemElements.back()->getWidth() - 10; + Ogre::Real b = mItemElements.back()->_getDerivedTop() * om.getViewportHeight() + + mItemElements.back()->getHeight() - 5; + + if (cursorPos.x >= l && cursorPos.x <= r && cursorPos.y >= t && cursorPos.y <= b) + { + if (mHighlightIndex != mSelectionIndex) selectItem(mHighlightIndex); + retract(); + } + } + } + else + { + if (mItems.size() < 2) return; // don't waste time showing a menu if there's no choice + + if (isCursorOver(mSmallBox, cursorPos, 4)) + { + mExpandedBox->show(); + mSmallBox->hide(); + + // calculate how much vertical space we need + Ogre::Real idealHeight = mItemsShown * (mSmallBox->getHeight() - 8) + 20; + mExpandedBox->setHeight(idealHeight); + mScrollTrack->setHeight(mExpandedBox->getHeight() - 20); + + mExpandedBox->setLeft(mSmallBox->getLeft() - 4); + + // if the expanded menu goes down off the screen, make it go up instead + if (mSmallBox->_getDerivedTop() * om.getViewportHeight() + idealHeight > om.getViewportHeight()) + { + mExpandedBox->setTop(mSmallBox->getTop() + mSmallBox->getHeight() - idealHeight + 3); + // if we're in thick style, hide the caption because it will interfere with the expanded menu + if (mTextArea->getHorizontalAlignment() == Ogre::GHA_CENTER) mTextArea->hide(); + } + else mExpandedBox->setTop(mSmallBox->getTop() + 3); + + mExpanded = true; + mHighlightIndex = mSelectionIndex; + setDisplayIndex(mHighlightIndex); + + if (mItemsShown < mItems.size()) // update scrollbar position + { + mScrollHandle->show(); + Ogre::Real lowerBoundary = mScrollTrack->getHeight() - mScrollHandle->getHeight(); + mScrollHandle->setTop((int)(mDisplayIndex * lowerBoundary / (mItems.size() - mItemElements.size()))); + } + else mScrollHandle->hide(); + } + } + } + + void _cursorReleased(const Ogre::Vector2& cursorPos) + { + mDragging = false; + } + + void _cursorMoved(const Ogre::Vector2& cursorPos) + { + Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); + + if (mExpanded) + { + if (mDragging) + { + Ogre::Vector2 co = Widget::cursorOffset(mScrollHandle, cursorPos); + Ogre::Real newTop = mScrollHandle->getTop() + co.y - mDragOffset; + Ogre::Real lowerBoundary = mScrollTrack->getHeight() - mScrollHandle->getHeight(); + mScrollHandle->setTop(Ogre::Math::Clamp((int)newTop, 0, (int)lowerBoundary)); + + Ogre::Real scrollPercentage = Ogre::Math::Clamp(newTop / lowerBoundary, 0, 1); + int newIndex = (int) (scrollPercentage * (mItems.size() - mItemElements.size()) + 0.5); + if (newIndex != mDisplayIndex) setDisplayIndex(newIndex); + return; + } + + Ogre::Real l = mItemElements.front()->_getDerivedLeft() * om.getViewportWidth() + 5; + Ogre::Real t = mItemElements.front()->_getDerivedTop() * om.getViewportHeight() + 5; + Ogre::Real r = l + mItemElements.back()->getWidth() - 10; + Ogre::Real b = mItemElements.back()->_getDerivedTop() * om.getViewportHeight() + + mItemElements.back()->getHeight() - 5; + + if (cursorPos.x >= l && cursorPos.x <= r && cursorPos.y >= t && cursorPos.y <= b) + { + int newIndex = (int)(mDisplayIndex + (cursorPos.y - t) / (b - t) * mItemElements.size()); + if (mHighlightIndex != newIndex) + { + mHighlightIndex = newIndex; + setDisplayIndex(mDisplayIndex); + } + } + } + else + { + if (isCursorOver(mSmallBox, cursorPos, 4)) + { + mSmallBox->setMaterialName("SdkTrays/MiniTextBox/Over"); + mSmallBox->setBorderMaterialName("SdkTrays/MiniTextBox/Over"); + mCursorOver = true; + } + else + { + if (mCursorOver) + { + mSmallBox->setMaterialName("SdkTrays/MiniTextBox"); + mSmallBox->setBorderMaterialName("SdkTrays/MiniTextBox"); + mCursorOver = false; + } + } + } + } + + void _focusLost() + { + if (mExpandedBox->isVisible()) retract(); + } + + protected: + + /*----------------------------------------------------------------------------- + | Internal method - sets which item goes at the top of the expanded menu. + -----------------------------------------------------------------------------*/ + void setDisplayIndex(unsigned int index) + { + index = std::min(index, (int)(mItems.size() - mItemElements.size())); + mDisplayIndex = index; + + for (int i = 0; i < (int)mItemElements.size(); i++) + { + Ogre::BorderPanelOverlayElement *ie = mItemElements[i]; + Ogre::TextAreaOverlayElement *ta = (Ogre::TextAreaOverlayElement*)ie->getChild(ie->getName() + "/MenuItemText"); + + fitCaptionToArea(mItems[mDisplayIndex + i], ta, ie->getWidth() - 2 * ta->getLeft()); + + if ((mDisplayIndex + i) == mHighlightIndex) + { + ie->setMaterialName("SdkTrays/MiniTextBox/Over"); + ie->setBorderMaterialName("SdkTrays/MiniTextBox/Over"); + } + else + { + ie->setMaterialName("SdkTrays/MiniTextBox"); + ie->setBorderMaterialName("SdkTrays/MiniTextBox"); + } + } + } + + /*----------------------------------------------------------------------------- + | Internal method - cleans up an expanded menu. + -----------------------------------------------------------------------------*/ + void retract() + { + mDragging = false; + mExpanded = false; + mExpandedBox->hide(); + mTextArea->show(); + mSmallBox->show(); + mSmallBox->setMaterialName("SdkTrays/MiniTextBox"); + mSmallBox->setBorderMaterialName("SdkTrays/MiniTextBox"); + } + + Ogre::BorderPanelOverlayElement* mSmallBox; + Ogre::BorderPanelOverlayElement* mExpandedBox; + Ogre::TextAreaOverlayElement* mTextArea; + Ogre::TextAreaOverlayElement* mSmallTextArea; + Ogre::BorderPanelOverlayElement* mScrollTrack; + Ogre::PanelOverlayElement* mScrollHandle; + std::vector mItemElements; + unsigned int mMaxItemsShown; + unsigned int mItemsShown; + bool mCursorOver; + bool mExpanded; + bool mFitToContents; + bool mDragging; + Ogre::StringVector mItems; + int mSelectionIndex; + int mHighlightIndex; + int mDisplayIndex; + Ogre::Real mDragOffset; + }; + + /*============================================================================= + | Basic label widget. + =============================================================================*/ + class Label : public Widget + { + public: + + // Do not instantiate any widgets directly. Use SdkTrayManager. + Label(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width) + { + mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate("SdkTrays/Label", "BorderPanel", name); + mTextArea = (Ogre::TextAreaOverlayElement*)((Ogre::OverlayContainer*)mElement)->getChild(getName() + "/LabelCaption"); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS mTextArea->setCharHeight(mTextArea->getCharHeight() - 3); #endif - setCaption(caption); - if (width <= 0) mFitToTray = true; - else - { - mFitToTray = false; - mElement->setWidth(width); - } - } - - const Ogre::DisplayString& getCaption() - { - return mTextArea->getCaption(); - } - - void setCaption(const Ogre::DisplayString& caption) - { - mTextArea->setCaption(caption); - } - - void _cursorPressed(const Ogre::Vector2& cursorPos) - { - if (mListener && isCursorOver(mElement, cursorPos, 3)) mListener->labelHit(this); - } - - bool _isFitToTray() - { - return mFitToTray; - } - - protected: - - Ogre::TextAreaOverlayElement* mTextArea; - bool mFitToTray; - }; - - /*============================================================================= - | Basic separator widget. - =============================================================================*/ - class Separator : public Widget - { - public: - - // Do not instantiate any widgets directly. Use SdkTrayManager. - Separator(const Ogre::String& name, Ogre::Real width) - { - mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate("SdkTrays/Separator", "Panel", name); - if (width <= 0) mFitToTray = true; - else - { - mFitToTray = false; - mElement->setWidth(width); - } - } - - bool _isFitToTray() - { - return mFitToTray; - } - - protected: - - bool mFitToTray; - }; - - /*============================================================================= - | Basic slider widget. - =============================================================================*/ - class Slider : public Widget - { - public: - - // Do not instantiate any widgets directly. Use SdkTrayManager. - Slider(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width, Ogre::Real trackWidth, - Ogre::Real valueBoxWidth, Ogre::Real minValue, Ogre::Real maxValue, unsigned int snaps) - : mDragOffset(0.0f) - , mValue(0.0f) - , mMinValue(0.0f) - , mMaxValue(0.0f) - , mInterval(0.0f) - { - mDragging = false; - mFitToContents = false; - mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate - ("SdkTrays/Slider", "BorderPanel", name); - mElement->setWidth(width); - Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)mElement; - mTextArea = (Ogre::TextAreaOverlayElement*)c->getChild(getName() + "/SliderCaption"); - Ogre::OverlayContainer* valueBox = (Ogre::OverlayContainer*)c->getChild(getName() + "/SliderValueBox"); - valueBox->setWidth(valueBoxWidth); - valueBox->setLeft(-(valueBoxWidth + 5)); - mValueTextArea = (Ogre::TextAreaOverlayElement*)valueBox->getChild(valueBox->getName() + "/SliderValueText"); - mTrack = (Ogre::BorderPanelOverlayElement*)c->getChild(getName() + "/SliderTrack"); - mHandle = (Ogre::PanelOverlayElement*)mTrack->getChild(mTrack->getName() + "/SliderHandle"); + setCaption(caption); + if (width <= 0) mFitToTray = true; + else + { + mFitToTray = false; + mElement->setWidth(width); + } + } + + const Ogre::DisplayString& getCaption() + { + return mTextArea->getCaption(); + } + + void setCaption(const Ogre::DisplayString& caption) + { + mTextArea->setCaption(caption); + } + + void _cursorPressed(const Ogre::Vector2& cursorPos) + { + if (mListener && isCursorOver(mElement, cursorPos, 3)) mListener->labelHit(this); + } + + bool _isFitToTray() + { + return mFitToTray; + } + + protected: + + Ogre::TextAreaOverlayElement* mTextArea; + bool mFitToTray; + }; + + /*============================================================================= + | Basic separator widget. + =============================================================================*/ + class Separator : public Widget + { + public: + + // Do not instantiate any widgets directly. Use SdkTrayManager. + Separator(const Ogre::String& name, Ogre::Real width) + { + mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate("SdkTrays/Separator", "Panel", name); + if (width <= 0) mFitToTray = true; + else + { + mFitToTray = false; + mElement->setWidth(width); + } + } + + bool _isFitToTray() + { + return mFitToTray; + } + + protected: + + bool mFitToTray; + }; + + /*============================================================================= + | Basic slider widget. + =============================================================================*/ + class Slider : public Widget + { + public: + + // Do not instantiate any widgets directly. Use SdkTrayManager. + Slider(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width, Ogre::Real trackWidth, + Ogre::Real valueBoxWidth, Ogre::Real minValue, Ogre::Real maxValue, unsigned int snaps) + : mDragOffset(0.0f) + , mValue(0.0f) + , mMinValue(0.0f) + , mMaxValue(0.0f) + , mInterval(0.0f) + { + mDragging = false; + mFitToContents = false; + mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate + ("SdkTrays/Slider", "BorderPanel", name); + mElement->setWidth(width); + Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)mElement; + mTextArea = (Ogre::TextAreaOverlayElement*)c->getChild(getName() + "/SliderCaption"); + Ogre::OverlayContainer* valueBox = (Ogre::OverlayContainer*)c->getChild(getName() + "/SliderValueBox"); + valueBox->setWidth(valueBoxWidth); + valueBox->setLeft(-(valueBoxWidth + 5)); + mValueTextArea = (Ogre::TextAreaOverlayElement*)valueBox->getChild(valueBox->getName() + "/SliderValueText"); + mTrack = (Ogre::BorderPanelOverlayElement*)c->getChild(getName() + "/SliderTrack"); + mHandle = (Ogre::PanelOverlayElement*)mTrack->getChild(mTrack->getName() + "/SliderHandle"); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS mTextArea->setCharHeight(mTextArea->getCharHeight() - 3); mValueTextArea->setCharHeight(mValueTextArea->getCharHeight() - 3); #endif - if (trackWidth <= 0) // tall style - { - mTrack->setWidth(width - 16); - } - else // long style - { - if (width <= 0) mFitToContents = true; - mElement->setHeight(34); - mTextArea->setTop(10); - valueBox->setTop(2); - mTrack->setTop(-23); - mTrack->setWidth(trackWidth); - mTrack->setHorizontalAlignment(Ogre::GHA_RIGHT); - mTrack->setLeft(-(trackWidth + valueBoxWidth + 5)); - } - - setCaption(caption); - setRange(minValue, maxValue, snaps, false); - } - - /*----------------------------------------------------------------------------- - | Sets the minimum value, maximum value, and the number of snapping points. - -----------------------------------------------------------------------------*/ - void setRange(Ogre::Real minValue, Ogre::Real maxValue, unsigned int snaps, bool notifyListener = true) - { - mMinValue = minValue; - mMaxValue = maxValue; - - if (snaps <= 1 || mMinValue >= mMaxValue) - { - mInterval = 0; - mHandle->hide(); - mValue = minValue; - if (snaps == 1) mValueTextArea->setCaption(Ogre::StringConverter::toString(mMinValue)); - else mValueTextArea->setCaption(""); - } - else - { - mHandle->show(); - mInterval = (maxValue - minValue) / (snaps - 1); - setValue(minValue, notifyListener); - } - } - - const Ogre::DisplayString& getValueCaption() - { - return mValueTextArea->getCaption(); - } - - /*----------------------------------------------------------------------------- - | You can use this method to manually format how the value is displayed. - -----------------------------------------------------------------------------*/ - void setValueCaption(const Ogre::DisplayString& caption) - { - mValueTextArea->setCaption(caption); - } - - void setValue(Ogre::Real value, bool notifyListener = true) - { - if (mInterval == 0) return; - - mValue = Ogre::Math::Clamp(value, mMinValue, mMaxValue); - - setValueCaption(Ogre::StringConverter::toString(mValue)); - - if (mListener && notifyListener) mListener->sliderMoved(this); - - if (!mDragging) mHandle->setLeft((int)((mValue - mMinValue) / (mMaxValue - mMinValue) * - (mTrack->getWidth() - mHandle->getWidth()))); - } - - Ogre::Real getValue() - { - return mValue; - } - - const Ogre::DisplayString& getCaption() - { - return mTextArea->getCaption(); - } - - void setCaption(const Ogre::DisplayString& caption) - { - mTextArea->setCaption(caption); - - if (mFitToContents) mElement->setWidth(getCaptionWidth(caption, mTextArea) + - mValueTextArea->getParent()->getWidth() + mTrack->getWidth() + 26); - } - - void _cursorPressed(const Ogre::Vector2& cursorPos) - { - if (!mHandle->isVisible()) return; - - Ogre::Vector2 co = Widget::cursorOffset(mHandle, cursorPos); - - if (co.squaredLength() <= 81) - { - mDragging = true; - mDragOffset = co.x; - } - else if (Widget::isCursorOver(mTrack, cursorPos)) - { - Ogre::Real newLeft = mHandle->getLeft() + co.x; - Ogre::Real rightBoundary = mTrack->getWidth() - mHandle->getWidth(); - - mHandle->setLeft(Ogre::Math::Clamp((int)newLeft, 0, (int)rightBoundary)); - setValue(getSnappedValue(newLeft / rightBoundary)); - } - } - - void _cursorReleased(const Ogre::Vector2& cursorPos) - { - if (mDragging) - { - mDragging = false; - mHandle->setLeft((int)((mValue - mMinValue) / (mMaxValue - mMinValue) * - (mTrack->getWidth() - mHandle->getWidth()))); - } - } - - void _cursorMoved(const Ogre::Vector2& cursorPos) - { - if (mDragging) - { - Ogre::Vector2 co = Widget::cursorOffset(mHandle, cursorPos); - Ogre::Real newLeft = mHandle->getLeft() + co.x - mDragOffset; - Ogre::Real rightBoundary = mTrack->getWidth() - mHandle->getWidth(); - - mHandle->setLeft(Ogre::Math::Clamp((int)newLeft, 0, (int)rightBoundary)); - setValue(getSnappedValue(newLeft / rightBoundary)); - } - } - - void _focusLost() - { - mDragging = false; - } - - protected: - - /*----------------------------------------------------------------------------- - | Internal method - given a percentage (from left to right), gets the - | value of the nearest marker. - -----------------------------------------------------------------------------*/ - Ogre::Real getSnappedValue(Ogre::Real percentage) - { - percentage = Ogre::Math::Clamp(percentage, 0, 1); - unsigned int whichMarker = (unsigned int) (percentage * (mMaxValue - mMinValue) / mInterval + 0.5); - return whichMarker * mInterval + mMinValue; - } - - Ogre::TextAreaOverlayElement* mTextArea; - Ogre::TextAreaOverlayElement* mValueTextArea; - Ogre::BorderPanelOverlayElement* mTrack; - Ogre::PanelOverlayElement* mHandle; - bool mDragging; - bool mFitToContents; - Ogre::Real mDragOffset; - Ogre::Real mValue; - Ogre::Real mMinValue; - Ogre::Real mMaxValue; - Ogre::Real mInterval; - }; - - /*============================================================================= - | Basic parameters panel widget. - =============================================================================*/ - class ParamsPanel : public Widget - { - public: - - // Do not instantiate any widgets directly. Use SdkTrayManager. - ParamsPanel(const Ogre::String& name, Ogre::Real width, unsigned int lines) - { - mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate - ("SdkTrays/ParamsPanel", "BorderPanel", name); - Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)mElement; - mNamesArea = (Ogre::TextAreaOverlayElement*)c->getChild(getName() + "/ParamsPanelNames"); - mValuesArea = (Ogre::TextAreaOverlayElement*)c->getChild(getName() + "/ParamsPanelValues"); + if (trackWidth <= 0) // tall style + { + mTrack->setWidth(width - 16); + } + else // long style + { + if (width <= 0) mFitToContents = true; + mElement->setHeight(34); + mTextArea->setTop(10); + valueBox->setTop(2); + mTrack->setTop(-23); + mTrack->setWidth(trackWidth); + mTrack->setHorizontalAlignment(Ogre::GHA_RIGHT); + mTrack->setLeft(-(trackWidth + valueBoxWidth + 5)); + } + + setCaption(caption); + setRange(minValue, maxValue, snaps, false); + } + + /*----------------------------------------------------------------------------- + | Sets the minimum value, maximum value, and the number of snapping points. + -----------------------------------------------------------------------------*/ + void setRange(Ogre::Real minValue, Ogre::Real maxValue, unsigned int snaps, bool notifyListener = true) + { + mMinValue = minValue; + mMaxValue = maxValue; + + if (snaps <= 1 || mMinValue >= mMaxValue) + { + mInterval = 0; + mHandle->hide(); + mValue = minValue; + if (snaps == 1) mValueTextArea->setCaption(Ogre::StringConverter::toString(mMinValue)); + else mValueTextArea->setCaption(""); + } + else + { + mHandle->show(); + mInterval = (maxValue - minValue) / (snaps - 1); + setValue(minValue, notifyListener); + } + } + + const Ogre::DisplayString& getValueCaption() + { + return mValueTextArea->getCaption(); + } + + /*----------------------------------------------------------------------------- + | You can use this method to manually format how the value is displayed. + -----------------------------------------------------------------------------*/ + void setValueCaption(const Ogre::DisplayString& caption) + { + mValueTextArea->setCaption(caption); + } + + void setValue(Ogre::Real value, bool notifyListener = true) + { + if (mInterval == 0) return; + + mValue = Ogre::Math::Clamp(value, mMinValue, mMaxValue); + + setValueCaption(Ogre::StringConverter::toString(mValue)); + + if (mListener && notifyListener) mListener->sliderMoved(this); + + if (!mDragging) mHandle->setLeft((int)((mValue - mMinValue) / (mMaxValue - mMinValue) * + (mTrack->getWidth() - mHandle->getWidth()))); + } + + Ogre::Real getValue() + { + return mValue; + } + + const Ogre::DisplayString& getCaption() + { + return mTextArea->getCaption(); + } + + void setCaption(const Ogre::DisplayString& caption) + { + mTextArea->setCaption(caption); + + if (mFitToContents) mElement->setWidth(getCaptionWidth(caption, mTextArea) + + mValueTextArea->getParent()->getWidth() + mTrack->getWidth() + 26); + } + + void _cursorPressed(const Ogre::Vector2& cursorPos) + { + if (!mHandle->isVisible()) return; + + Ogre::Vector2 co = Widget::cursorOffset(mHandle, cursorPos); + + if (co.squaredLength() <= 81) + { + mDragging = true; + mDragOffset = co.x; + } + else if (Widget::isCursorOver(mTrack, cursorPos)) + { + Ogre::Real newLeft = mHandle->getLeft() + co.x; + Ogre::Real rightBoundary = mTrack->getWidth() - mHandle->getWidth(); + + mHandle->setLeft(Ogre::Math::Clamp((int)newLeft, 0, (int)rightBoundary)); + setValue(getSnappedValue(newLeft / rightBoundary)); + } + } + + void _cursorReleased(const Ogre::Vector2& cursorPos) + { + if (mDragging) + { + mDragging = false; + mHandle->setLeft((int)((mValue - mMinValue) / (mMaxValue - mMinValue) * + (mTrack->getWidth() - mHandle->getWidth()))); + } + } + + void _cursorMoved(const Ogre::Vector2& cursorPos) + { + if (mDragging) + { + Ogre::Vector2 co = Widget::cursorOffset(mHandle, cursorPos); + Ogre::Real newLeft = mHandle->getLeft() + co.x - mDragOffset; + Ogre::Real rightBoundary = mTrack->getWidth() - mHandle->getWidth(); + + mHandle->setLeft(Ogre::Math::Clamp((int)newLeft, 0, (int)rightBoundary)); + setValue(getSnappedValue(newLeft / rightBoundary)); + } + } + + void _focusLost() + { + mDragging = false; + } + + protected: + + /*----------------------------------------------------------------------------- + | Internal method - given a percentage (from left to right), gets the + | value of the nearest marker. + -----------------------------------------------------------------------------*/ + Ogre::Real getSnappedValue(Ogre::Real percentage) + { + percentage = Ogre::Math::Clamp(percentage, 0, 1); + unsigned int whichMarker = (unsigned int) (percentage * (mMaxValue - mMinValue) / mInterval + 0.5); + return whichMarker * mInterval + mMinValue; + } + + Ogre::TextAreaOverlayElement* mTextArea; + Ogre::TextAreaOverlayElement* mValueTextArea; + Ogre::BorderPanelOverlayElement* mTrack; + Ogre::PanelOverlayElement* mHandle; + bool mDragging; + bool mFitToContents; + Ogre::Real mDragOffset; + Ogre::Real mValue; + Ogre::Real mMinValue; + Ogre::Real mMaxValue; + Ogre::Real mInterval; + }; + + /*============================================================================= + | Basic parameters panel widget. + =============================================================================*/ + class ParamsPanel : public Widget + { + public: + + // Do not instantiate any widgets directly. Use SdkTrayManager. + ParamsPanel(const Ogre::String& name, Ogre::Real width, unsigned int lines) + { + mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate + ("SdkTrays/ParamsPanel", "BorderPanel", name); + Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)mElement; + mNamesArea = (Ogre::TextAreaOverlayElement*)c->getChild(getName() + "/ParamsPanelNames"); + mValuesArea = (Ogre::TextAreaOverlayElement*)c->getChild(getName() + "/ParamsPanelValues"); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS mNamesArea->setCharHeight(mNamesArea->getCharHeight() - 3); mValuesArea->setCharHeight(mValuesArea->getCharHeight() - 3); #endif - mElement->setWidth(width); - mElement->setHeight(mNamesArea->getTop() * 2 + lines * mNamesArea->getCharHeight()); - } - - void setAllParamNames(const Ogre::StringVector& paramNames) - { - mNames = paramNames; - mValues.clear(); - mValues.resize(mNames.size(), ""); - mElement->setHeight(mNamesArea->getTop() * 2 + mNames.size() * mNamesArea->getCharHeight()); - updateText(); - } - - const Ogre::StringVector& getAllParamNames() - { - return mNames; - } - - void setAllParamValues(const Ogre::StringVector& paramValues) - { - mValues = paramValues; - mValues.resize(mNames.size(), ""); - updateText(); - } - - void setParamValue(const Ogre::DisplayString& paramName, const Ogre::DisplayString& paramValue) - { - for (unsigned int i = 0; i < mNames.size(); i++) - { - if (mNames[i] == DISPLAY_STRING_TO_STRING(paramName)) - { - mValues[i] = DISPLAY_STRING_TO_STRING(paramValue); - updateText(); - return; - } - } - - Ogre::String desc = "ParamsPanel \"" + getName() + "\" has no parameter \"" + DISPLAY_STRING_TO_STRING(paramName) + "\"."; - OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "ParamsPanel::setParamValue"); - } - - void setParamValue(unsigned int index, const Ogre::DisplayString& paramValue) - { - if (index >= mNames.size()) - { - Ogre::String desc = "ParamsPanel \"" + getName() + "\" has no parameter at position " + - Ogre::StringConverter::toString(index) + "."; - OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "ParamsPanel::setParamValue"); - } - - mValues[index] = DISPLAY_STRING_TO_STRING(paramValue); - updateText(); - } - - Ogre::DisplayString getParamValue(const Ogre::DisplayString& paramName) - { - for (unsigned int i = 0; i < mNames.size(); i++) - { - if (mNames[i] == DISPLAY_STRING_TO_STRING(paramName)) return mValues[i]; - } - - Ogre::String desc = "ParamsPanel \"" + getName() + "\" has no parameter \"" + DISPLAY_STRING_TO_STRING(paramName) + "\"."; - OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "ParamsPanel::getParamValue"); - return ""; - } - - Ogre::DisplayString getParamValue(unsigned int index) - { - if (index >= mNames.size()) - { - Ogre::String desc = "ParamsPanel \"" + getName() + "\" has no parameter at position " + - Ogre::StringConverter::toString(index) + "."; - OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "ParamsPanel::getParamValue"); - } - - return mValues[index]; - } - - const Ogre::StringVector& getAllParamValues() - { - return mValues; - } - - protected: - - /*----------------------------------------------------------------------------- - | Internal method - updates text areas based on name and value lists. - -----------------------------------------------------------------------------*/ - void updateText() - { - Ogre::DisplayString namesDS; - Ogre::DisplayString valuesDS; - - for (unsigned int i = 0; i < mNames.size(); i++) - { - namesDS.append(mNames[i] + ":\n"); - valuesDS.append(mValues[i] + "\n"); - } - - mNamesArea->setCaption(namesDS); - mValuesArea->setCaption(valuesDS); - } - - Ogre::TextAreaOverlayElement* mNamesArea; - Ogre::TextAreaOverlayElement* mValuesArea; - Ogre::StringVector mNames; - Ogre::StringVector mValues; - }; - - /*============================================================================= - | Basic check box widget. - =============================================================================*/ - class CheckBox : public Widget - { - public: - - // Do not instantiate any widgets directly. Use SdkTrayManager. - CheckBox(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width) - { - mCursorOver = false; - mFitToContents = width <= 0; - mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate - ("SdkTrays/CheckBox", "BorderPanel", name); - Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)mElement; - mTextArea = (Ogre::TextAreaOverlayElement*)c->getChild(getName() + "/CheckBoxCaption"); - mSquare = (Ogre::BorderPanelOverlayElement*)c->getChild(getName() + "/CheckBoxSquare"); - mX = mSquare->getChild(mSquare->getName() + "/CheckBoxX"); - mX->hide(); - mElement->setWidth(width); + mElement->setWidth(width); + mElement->setHeight(mNamesArea->getTop() * 2 + lines * mNamesArea->getCharHeight()); + } + + void setAllParamNames(const Ogre::StringVector& paramNames) + { + mNames = paramNames; + mValues.clear(); + mValues.resize(mNames.size(), ""); + mElement->setHeight(mNamesArea->getTop() * 2 + mNames.size() * mNamesArea->getCharHeight()); + updateText(); + } + + const Ogre::StringVector& getAllParamNames() + { + return mNames; + } + + void setAllParamValues(const Ogre::StringVector& paramValues) + { + mValues = paramValues; + mValues.resize(mNames.size(), ""); + updateText(); + } + + void setParamValue(const Ogre::DisplayString& paramName, const Ogre::DisplayString& paramValue) + { + for (unsigned int i = 0; i < mNames.size(); i++) + { + if (mNames[i] == DISPLAY_STRING_TO_STRING(paramName)) + { + mValues[i] = DISPLAY_STRING_TO_STRING(paramValue); + updateText(); + return; + } + } + + Ogre::String desc = "ParamsPanel \"" + getName() + "\" has no parameter \"" + DISPLAY_STRING_TO_STRING(paramName) + "\"."; + OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "ParamsPanel::setParamValue"); + } + + void setParamValue(unsigned int index, const Ogre::DisplayString& paramValue) + { + if (index >= mNames.size()) + { + Ogre::String desc = "ParamsPanel \"" + getName() + "\" has no parameter at position " + + Ogre::StringConverter::toString(index) + "."; + OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "ParamsPanel::setParamValue"); + } + + mValues[index] = DISPLAY_STRING_TO_STRING(paramValue); + updateText(); + } + + Ogre::DisplayString getParamValue(const Ogre::DisplayString& paramName) + { + for (unsigned int i = 0; i < mNames.size(); i++) + { + if (mNames[i] == DISPLAY_STRING_TO_STRING(paramName)) return mValues[i]; + } + + Ogre::String desc = "ParamsPanel \"" + getName() + "\" has no parameter \"" + DISPLAY_STRING_TO_STRING(paramName) + "\"."; + OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "ParamsPanel::getParamValue"); + return ""; + } + + Ogre::DisplayString getParamValue(unsigned int index) + { + if (index >= mNames.size()) + { + Ogre::String desc = "ParamsPanel \"" + getName() + "\" has no parameter at position " + + Ogre::StringConverter::toString(index) + "."; + OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, desc, "ParamsPanel::getParamValue"); + } + + return mValues[index]; + } + + const Ogre::StringVector& getAllParamValues() + { + return mValues; + } + + protected: + + /*----------------------------------------------------------------------------- + | Internal method - updates text areas based on name and value lists. + -----------------------------------------------------------------------------*/ + void updateText() + { + Ogre::DisplayString namesDS; + Ogre::DisplayString valuesDS; + + for (unsigned int i = 0; i < mNames.size(); i++) + { + namesDS.append(mNames[i] + ":\n"); + valuesDS.append(mValues[i] + "\n"); + } + + mNamesArea->setCaption(namesDS); + mValuesArea->setCaption(valuesDS); + } + + Ogre::TextAreaOverlayElement* mNamesArea; + Ogre::TextAreaOverlayElement* mValuesArea; + Ogre::StringVector mNames; + Ogre::StringVector mValues; + }; + + /*============================================================================= + | Basic check box widget. + =============================================================================*/ + class CheckBox : public Widget + { + public: + + // Do not instantiate any widgets directly. Use SdkTrayManager. + CheckBox(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width) + { + mCursorOver = false; + mFitToContents = width <= 0; + mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate + ("SdkTrays/CheckBox", "BorderPanel", name); + Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)mElement; + mTextArea = (Ogre::TextAreaOverlayElement*)c->getChild(getName() + "/CheckBoxCaption"); + mSquare = (Ogre::BorderPanelOverlayElement*)c->getChild(getName() + "/CheckBoxSquare"); + mX = mSquare->getChild(mSquare->getName() + "/CheckBoxX"); + mX->hide(); + mElement->setWidth(width); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS mTextArea->setCharHeight(mTextArea->getCharHeight() - 3); #endif - setCaption(caption); - } - - const Ogre::DisplayString& getCaption() - { - return mTextArea->getCaption(); - } - - void setCaption(const Ogre::DisplayString& caption) - { - mTextArea->setCaption(caption); - if (mFitToContents) mElement->setWidth(getCaptionWidth(caption, mTextArea) + mSquare->getWidth() + 23); - } - - bool isChecked() - { - return mX->isVisible(); - } - - void setChecked(bool checked, bool notifyListener = true) - { - if (checked) mX->show(); - else mX->hide(); - if (mListener && notifyListener) mListener->checkBoxToggled(this); - } - - void toggle(bool notifyListener = true) - { - setChecked(!isChecked(), notifyListener); - } - - void _cursorPressed(const Ogre::Vector2& cursorPos) - { - if (mCursorOver && mListener) toggle(); - } - - void _cursorMoved(const Ogre::Vector2& cursorPos) - { - if (isCursorOver(mSquare, cursorPos, 5)) - { - if (!mCursorOver) - { - mCursorOver = true; - mSquare->setMaterialName("SdkTrays/MiniTextBox/Over"); - mSquare->setBorderMaterialName("SdkTrays/MiniTextBox/Over"); - } - } - else - { - if (mCursorOver) - { - mCursorOver = false; - mSquare->setMaterialName("SdkTrays/MiniTextBox"); - mSquare->setBorderMaterialName("SdkTrays/MiniTextBox"); - } - } - } - - void _focusLost() - { - mSquare->setMaterialName("SdkTrays/MiniTextBox"); - mSquare->setBorderMaterialName("SdkTrays/MiniTextBox"); - mCursorOver = false; - } - - protected: - - Ogre::TextAreaOverlayElement* mTextArea; - Ogre::BorderPanelOverlayElement* mSquare; - Ogre::OverlayElement* mX; - bool mFitToContents; - bool mCursorOver; - }; - - /*============================================================================= - | Custom, decorative widget created from a template. - =============================================================================*/ - class DecorWidget : public Widget - { - public: - - // Do not instantiate any widgets directly. Use SdkTrayManager. - DecorWidget(const Ogre::String& name, const Ogre::String& templateName) - { - mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate(templateName, "", name); - } - }; - - /*============================================================================= - | Basic progress bar widget. - =============================================================================*/ - class ProgressBar : public Widget - { - public: - - // Do not instantiate any widgets directly. Use SdkTrayManager. - ProgressBar(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width, Ogre::Real commentBoxWidth) - : mProgress(0.0f) - { - mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate - ("SdkTrays/ProgressBar", "BorderPanel", name); - mElement->setWidth(width); - Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)mElement; - mTextArea = (Ogre::TextAreaOverlayElement*)c->getChild(getName() + "/ProgressCaption"); - Ogre::OverlayContainer* commentBox = (Ogre::OverlayContainer*)c->getChild(getName() + "/ProgressCommentBox"); - commentBox->setWidth(commentBoxWidth); - commentBox->setLeft(-(commentBoxWidth + 5)); - mCommentTextArea = (Ogre::TextAreaOverlayElement*)commentBox->getChild(commentBox->getName() + "/ProgressCommentText"); - mMeter = c->getChild(getName() + "/ProgressMeter"); - mMeter->setWidth(width - 10); - mFill = ((Ogre::OverlayContainer*)mMeter)->getChild(mMeter->getName() + "/ProgressFill"); - setCaption(caption); - } - - /*----------------------------------------------------------------------------- - | Sets the progress as a percentage. - -----------------------------------------------------------------------------*/ - void setProgress(Ogre::Real progress) - { - mProgress = Ogre::Math::Clamp(progress, 0, 1); - mFill->setWidth(std::max((int)mFill->getHeight(), (int)(mProgress * (mMeter->getWidth() - 2 * mFill->getLeft())))); - } - - /*----------------------------------------------------------------------------- - | Gets the progress as a percentage. - -----------------------------------------------------------------------------*/ - Ogre::Real getProgress() - { - return mProgress; - } - - const Ogre::DisplayString& getCaption() - { - return mTextArea->getCaption(); - } - - void setCaption(const Ogre::DisplayString& caption) - { - mTextArea->setCaption(caption); - } - - const Ogre::DisplayString& getComment() - { - return mCommentTextArea->getCaption(); - } - - void setComment(const Ogre::DisplayString& comment) - { - mCommentTextArea->setCaption(comment); - } - - - protected: - - Ogre::TextAreaOverlayElement* mTextArea; - Ogre::TextAreaOverlayElement* mCommentTextArea; - Ogre::OverlayElement* mMeter; - Ogre::OverlayElement* mFill; - Ogre::Real mProgress; - }; - - /*============================================================================= - | Main class to manage a cursor, backdrop, trays and widgets. - =============================================================================*/ - class SdkTrayManager : public SdkTrayListener, public Ogre::ResourceGroupListener + setCaption(caption); + } + + const Ogre::DisplayString& getCaption() + { + return mTextArea->getCaption(); + } + + void setCaption(const Ogre::DisplayString& caption) + { + mTextArea->setCaption(caption); + if (mFitToContents) mElement->setWidth(getCaptionWidth(caption, mTextArea) + mSquare->getWidth() + 23); + } + + bool isChecked() + { + return mX->isVisible(); + } + + void setChecked(bool checked, bool notifyListener = true) + { + if (checked) mX->show(); + else mX->hide(); + if (mListener && notifyListener) mListener->checkBoxToggled(this); + } + + void toggle(bool notifyListener = true) + { + setChecked(!isChecked(), notifyListener); + } + + void _cursorPressed(const Ogre::Vector2& cursorPos) + { + if (mCursorOver && mListener) toggle(); + } + + void _cursorMoved(const Ogre::Vector2& cursorPos) + { + if (isCursorOver(mSquare, cursorPos, 5)) + { + if (!mCursorOver) + { + mCursorOver = true; + mSquare->setMaterialName("SdkTrays/MiniTextBox/Over"); + mSquare->setBorderMaterialName("SdkTrays/MiniTextBox/Over"); + } + } + else + { + if (mCursorOver) + { + mCursorOver = false; + mSquare->setMaterialName("SdkTrays/MiniTextBox"); + mSquare->setBorderMaterialName("SdkTrays/MiniTextBox"); + } + } + } + + void _focusLost() + { + mSquare->setMaterialName("SdkTrays/MiniTextBox"); + mSquare->setBorderMaterialName("SdkTrays/MiniTextBox"); + mCursorOver = false; + } + + protected: + + Ogre::TextAreaOverlayElement* mTextArea; + Ogre::BorderPanelOverlayElement* mSquare; + Ogre::OverlayElement* mX; + bool mFitToContents; + bool mCursorOver; + }; + + /*============================================================================= + | Custom, decorative widget created from a template. + =============================================================================*/ + class DecorWidget : public Widget { public: - /*----------------------------------------------------------------------------- - | Creates backdrop, cursor, and trays. - -----------------------------------------------------------------------------*/ - SdkTrayManager(const Ogre::String& name, Ogre::RenderWindow* window, InputContext inputContext, SdkTrayListener* listener = 0) : - mName(name), mWindow(window), mInputContext(inputContext), mWidgetDeathRow(), mListener(listener), mWidgetPadding(8), - mWidgetSpacing(2), mTrayPadding(0), mTrayDrag(false), mExpandedMenu(0), mDialog(0), mOk(0), mYes(0), - mNo(0), mCursorWasVisible(false), mFpsLabel(0), mStatsPanel(0), mLogo(0), mLoadBar(0), - mGroupInitProportion(0.0f), mGroupLoadProportion(0.0f), mLoadInc(0.0f) - { - mTimer = Ogre::Root::getSingleton().getTimer(); - mLastStatUpdateTime = 0; + // Do not instantiate any widgets directly. Use SdkTrayManager. + DecorWidget(const Ogre::String& name, const Ogre::String& templateName) + { + mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate(templateName, "", name); + } + }; + + /*============================================================================= + | Basic progress bar widget. + =============================================================================*/ + class ProgressBar : public Widget + { + public: + + // Do not instantiate any widgets directly. Use SdkTrayManager. + ProgressBar(const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width, Ogre::Real commentBoxWidth) + : mProgress(0.0f) + { + mElement = Ogre::OverlayManager::getSingleton().createOverlayElementFromTemplate + ("SdkTrays/ProgressBar", "BorderPanel", name); + mElement->setWidth(width); + Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)mElement; + mTextArea = (Ogre::TextAreaOverlayElement*)c->getChild(getName() + "/ProgressCaption"); + Ogre::OverlayContainer* commentBox = (Ogre::OverlayContainer*)c->getChild(getName() + "/ProgressCommentBox"); + commentBox->setWidth(commentBoxWidth); + commentBox->setLeft(-(commentBoxWidth + 5)); + mCommentTextArea = (Ogre::TextAreaOverlayElement*)commentBox->getChild(commentBox->getName() + "/ProgressCommentText"); + mMeter = c->getChild(getName() + "/ProgressMeter"); + mMeter->setWidth(width - 10); + mFill = ((Ogre::OverlayContainer*)mMeter)->getChild(mMeter->getName() + "/ProgressFill"); + setCaption(caption); + } + + /*----------------------------------------------------------------------------- + | Sets the progress as a percentage. + -----------------------------------------------------------------------------*/ + void setProgress(Ogre::Real progress) + { + mProgress = Ogre::Math::Clamp(progress, 0, 1); + mFill->setWidth(std::max((int)mFill->getHeight(), (int)(mProgress * (mMeter->getWidth() - 2 * mFill->getLeft())))); + } + + /*----------------------------------------------------------------------------- + | Gets the progress as a percentage. + -----------------------------------------------------------------------------*/ + Ogre::Real getProgress() + { + return mProgress; + } + + const Ogre::DisplayString& getCaption() + { + return mTextArea->getCaption(); + } + + void setCaption(const Ogre::DisplayString& caption) + { + mTextArea->setCaption(caption); + } + + const Ogre::DisplayString& getComment() + { + return mCommentTextArea->getCaption(); + } + + void setComment(const Ogre::DisplayString& comment) + { + mCommentTextArea->setCaption(comment); + } + + + protected: + + Ogre::TextAreaOverlayElement* mTextArea; + Ogre::TextAreaOverlayElement* mCommentTextArea; + Ogre::OverlayElement* mMeter; + Ogre::OverlayElement* mFill; + Ogre::Real mProgress; + }; + + /*============================================================================= + | Main class to manage a cursor, backdrop, trays and widgets. + =============================================================================*/ + class SdkTrayManager : public SdkTrayListener, public Ogre::ResourceGroupListener + { + public: + + /*----------------------------------------------------------------------------- + | Creates backdrop, cursor, and trays. + -----------------------------------------------------------------------------*/ + SdkTrayManager(const Ogre::String& name, Ogre::RenderWindow* window, InputContext inputContext, SdkTrayListener* listener = 0) : + mName(name), mWindow(window), mInputContext(inputContext), mWidgetDeathRow(), mListener(listener), mWidgetPadding(8), + mWidgetSpacing(2), mTrayPadding(0), mTrayDrag(false), mExpandedMenu(0), mDialog(0), mOk(0), mYes(0), + mNo(0), mCursorWasVisible(false), mFpsLabel(0), mStatsPanel(0), mLogo(0), mLoadBar(0), + mGroupInitProportion(0.0f), mGroupLoadProportion(0.0f), mLoadInc(0.0f) + { + mTimer = Ogre::Root::getSingleton().getTimer(); + mLastStatUpdateTime = 0; + + Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); + + Ogre::String nameBase = mName + "/"; + std::replace(nameBase.begin(), nameBase.end(), ' ', '_'); + + // create overlay layers for everything + mBackdropLayer = om.create(nameBase + "BackdropLayer"); + mTraysLayer = om.create(nameBase + "WidgetsLayer"); + mPriorityLayer = om.create(nameBase + "PriorityLayer"); + mCursorLayer = om.create(nameBase + "CursorLayer"); + mBackdropLayer->setZOrder(100); + mTraysLayer->setZOrder(200); + mPriorityLayer->setZOrder(300); + mCursorLayer->setZOrder(400); + + // make backdrop and cursor overlay containers + mCursor = (Ogre::OverlayContainer*)om.createOverlayElementFromTemplate("SdkTrays/Cursor", "Panel", nameBase + "Cursor"); + mCursorLayer->add2D(mCursor); + mBackdrop = (Ogre::OverlayContainer*)om.createOverlayElement("Panel", nameBase + "Backdrop"); + mBackdropLayer->add2D(mBackdrop); + mDialogShade = (Ogre::OverlayContainer*)om.createOverlayElement("Panel", nameBase + "DialogShade"); + mDialogShade->setMaterialName("SdkTrays/Shade"); + mDialogShade->hide(); + mPriorityLayer->add2D(mDialogShade); + + Ogre::String trayNames[] = + { "TopLeft", "Top", "TopRight", "Left", "Center", "Right", "BottomLeft", "Bottom", "BottomRight" }; + + for (unsigned int i = 0; i < 9; i++) // make the real trays + { + mTrays[i] = (Ogre::OverlayContainer*)om.createOverlayElementFromTemplate + ("SdkTrays/Tray", "BorderPanel", nameBase + trayNames[i] + "Tray"); + mTraysLayer->add2D(mTrays[i]); + + mTrayWidgetAlign[i] = Ogre::GHA_CENTER; + + // align trays based on location + if (i == TL_TOP || i == TL_CENTER || i == TL_BOTTOM) mTrays[i]->setHorizontalAlignment(Ogre::GHA_CENTER); + if (i == TL_LEFT || i == TL_CENTER || i == TL_RIGHT) mTrays[i]->setVerticalAlignment(Ogre::GVA_CENTER); + if (i == TL_TOPRIGHT || i == TL_RIGHT || i == TL_BOTTOMRIGHT) mTrays[i]->setHorizontalAlignment(Ogre::GHA_RIGHT); + if (i == TL_BOTTOMLEFT || i == TL_BOTTOM || i == TL_BOTTOMRIGHT) mTrays[i]->setVerticalAlignment(Ogre::GVA_BOTTOM); + } + + // create the null tray for free-floating widgets + mTrays[9] = (Ogre::OverlayContainer*)om.createOverlayElement("Panel", nameBase + "NullTray"); + mTrayWidgetAlign[9] = Ogre::GHA_LEFT; + mTraysLayer->add2D(mTrays[9]); + adjustTrays(); + + showTrays(); + showCursor(); + } + + /*----------------------------------------------------------------------------- + | Destroys background, cursor, widgets, and trays. + -----------------------------------------------------------------------------*/ + virtual ~SdkTrayManager() + { + Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); + + destroyAllWidgets(); + + for (unsigned int i = 0; i < mWidgetDeathRow.size(); i++) // delete widgets queued for destruction + { + delete mWidgetDeathRow[i]; + } + mWidgetDeathRow.clear(); + + om.destroy(mBackdropLayer); + om.destroy(mTraysLayer); + om.destroy(mPriorityLayer); + om.destroy(mCursorLayer); + + closeDialog(); + hideLoadingBar(); + + Widget::nukeOverlayElement(mBackdrop); + Widget::nukeOverlayElement(mCursor); + Widget::nukeOverlayElement(mDialogShade); + + for (unsigned int i = 0; i < 10; i++) + { + Widget::nukeOverlayElement(mTrays[i]); + } + } + + /*----------------------------------------------------------------------------- + | Converts a 2D screen coordinate (in pixels) to a 3D ray into the scene. + -----------------------------------------------------------------------------*/ + static Ogre::Ray screenToScene(Ogre::Camera* cam, const Ogre::Vector2& pt) + { + return cam->getCameraToViewportRay(pt.x, pt.y); + } + + /*----------------------------------------------------------------------------- + | Converts a 3D scene position to a 2D screen position (in relative screen size, 0.0-1.0). + -----------------------------------------------------------------------------*/ + static Ogre::Vector2 sceneToScreen(Ogre::Camera* cam, const Ogre::Vector3& pt) + { + Ogre::Vector3 result = cam->getProjectionMatrix() * cam->getViewMatrix() * pt; + return Ogre::Vector2((result.x + 1) / 2, (-result.y + 1) / 2); + } + + // these methods get the underlying overlays and overlay elements + + Ogre::OverlayContainer* getTrayContainer(TrayLocation trayLoc) { return mTrays[trayLoc]; } + Ogre::Overlay* getBackdropLayer() { return mBackdropLayer; } + Ogre::Overlay* getTraysLayer() { return mTraysLayer; } + Ogre::Overlay* getCursorLayer() { return mCursorLayer; } + Ogre::OverlayContainer* getBackdropContainer() { return mBackdrop; } + Ogre::OverlayContainer* getCursorContainer() { return mCursor; } + Ogre::OverlayElement* getCursorImage() { return mCursor->getChild(mCursor->getName() + "/CursorImage"); } + + void setListener(SdkTrayListener* listener) + { + mListener = listener; + } + + SdkTrayListener* getListener() + { + return mListener; + } + + void showAll() + { + showBackdrop(); + showTrays(); + showCursor(); + } + + void hideAll() + { + hideBackdrop(); + hideTrays(); + hideCursor(); + } + + /*----------------------------------------------------------------------------- + | Displays specified material on backdrop, or the last material used if + | none specified. Good for pause menus like in the browser. + -----------------------------------------------------------------------------*/ + void showBackdrop(const Ogre::String& materialName = Ogre::BLANKSTRING) + { + if (materialName != Ogre::BLANKSTRING) mBackdrop->setMaterialName(materialName); + mBackdropLayer->show(); + } + + void hideBackdrop() + { + mBackdropLayer->hide(); + } - Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); - - Ogre::String nameBase = mName + "/"; - std::replace(nameBase.begin(), nameBase.end(), ' ', '_'); - - // create overlay layers for everything - mBackdropLayer = om.create(nameBase + "BackdropLayer"); - mTraysLayer = om.create(nameBase + "WidgetsLayer"); - mPriorityLayer = om.create(nameBase + "PriorityLayer"); - mCursorLayer = om.create(nameBase + "CursorLayer"); - mBackdropLayer->setZOrder(100); - mTraysLayer->setZOrder(200); - mPriorityLayer->setZOrder(300); - mCursorLayer->setZOrder(400); - - // make backdrop and cursor overlay containers - mCursor = (Ogre::OverlayContainer*)om.createOverlayElementFromTemplate("SdkTrays/Cursor", "Panel", nameBase + "Cursor"); - mCursorLayer->add2D(mCursor); - mBackdrop = (Ogre::OverlayContainer*)om.createOverlayElement("Panel", nameBase + "Backdrop"); - mBackdropLayer->add2D(mBackdrop); - mDialogShade = (Ogre::OverlayContainer*)om.createOverlayElement("Panel", nameBase + "DialogShade"); - mDialogShade->setMaterialName("SdkTrays/Shade"); - mDialogShade->hide(); - mPriorityLayer->add2D(mDialogShade); - - Ogre::String trayNames[] = - { "TopLeft", "Top", "TopRight", "Left", "Center", "Right", "BottomLeft", "Bottom", "BottomRight" }; - - for (unsigned int i = 0; i < 9; i++) // make the real trays - { - mTrays[i] = (Ogre::OverlayContainer*)om.createOverlayElementFromTemplate - ("SdkTrays/Tray", "BorderPanel", nameBase + trayNames[i] + "Tray"); - mTraysLayer->add2D(mTrays[i]); - - mTrayWidgetAlign[i] = Ogre::GHA_CENTER; - - // align trays based on location - if (i == TL_TOP || i == TL_CENTER || i == TL_BOTTOM) mTrays[i]->setHorizontalAlignment(Ogre::GHA_CENTER); - if (i == TL_LEFT || i == TL_CENTER || i == TL_RIGHT) mTrays[i]->setVerticalAlignment(Ogre::GVA_CENTER); - if (i == TL_TOPRIGHT || i == TL_RIGHT || i == TL_BOTTOMRIGHT) mTrays[i]->setHorizontalAlignment(Ogre::GHA_RIGHT); - if (i == TL_BOTTOMLEFT || i == TL_BOTTOM || i == TL_BOTTOMRIGHT) mTrays[i]->setVerticalAlignment(Ogre::GVA_BOTTOM); - } - - // create the null tray for free-floating widgets - mTrays[9] = (Ogre::OverlayContainer*)om.createOverlayElement("Panel", nameBase + "NullTray"); - mTrayWidgetAlign[9] = Ogre::GHA_LEFT; - mTraysLayer->add2D(mTrays[9]); - adjustTrays(); - - showTrays(); - showCursor(); - } - - /*----------------------------------------------------------------------------- - | Destroys background, cursor, widgets, and trays. - -----------------------------------------------------------------------------*/ - virtual ~SdkTrayManager() - { - Ogre::OverlayManager& om = Ogre::OverlayManager::getSingleton(); - - destroyAllWidgets(); - - for (unsigned int i = 0; i < mWidgetDeathRow.size(); i++) // delete widgets queued for destruction - { - delete mWidgetDeathRow[i]; - } - mWidgetDeathRow.clear(); - - om.destroy(mBackdropLayer); - om.destroy(mTraysLayer); - om.destroy(mPriorityLayer); - om.destroy(mCursorLayer); - - closeDialog(); - hideLoadingBar(); - - Widget::nukeOverlayElement(mBackdrop); - Widget::nukeOverlayElement(mCursor); - Widget::nukeOverlayElement(mDialogShade); - - for (unsigned int i = 0; i < 10; i++) - { - Widget::nukeOverlayElement(mTrays[i]); - } - } - - /*----------------------------------------------------------------------------- - | Converts a 2D screen coordinate (in pixels) to a 3D ray into the scene. - -----------------------------------------------------------------------------*/ - static Ogre::Ray screenToScene(Ogre::Camera* cam, const Ogre::Vector2& pt) - { - return cam->getCameraToViewportRay(pt.x, pt.y); - } - - /*----------------------------------------------------------------------------- - | Converts a 3D scene position to a 2D screen position (in relative screen size, 0.0-1.0). - -----------------------------------------------------------------------------*/ - static Ogre::Vector2 sceneToScreen(Ogre::Camera* cam, const Ogre::Vector3& pt) - { - Ogre::Vector3 result = cam->getProjectionMatrix() * cam->getViewMatrix() * pt; - return Ogre::Vector2((result.x + 1) / 2, (-result.y + 1) / 2); - } - - // these methods get the underlying overlays and overlay elements - - Ogre::OverlayContainer* getTrayContainer(TrayLocation trayLoc) { return mTrays[trayLoc]; } - Ogre::Overlay* getBackdropLayer() { return mBackdropLayer; } - Ogre::Overlay* getTraysLayer() { return mTraysLayer; } - Ogre::Overlay* getCursorLayer() { return mCursorLayer; } - Ogre::OverlayContainer* getBackdropContainer() { return mBackdrop; } - Ogre::OverlayContainer* getCursorContainer() { return mCursor; } - Ogre::OverlayElement* getCursorImage() { return mCursor->getChild(mCursor->getName() + "/CursorImage"); } - - void setListener(SdkTrayListener* listener) - { - mListener = listener; - } - - SdkTrayListener* getListener() - { - return mListener; - } - - void showAll() - { - showBackdrop(); - showTrays(); - showCursor(); - } - - void hideAll() - { - hideBackdrop(); - hideTrays(); - hideCursor(); - } - - /*----------------------------------------------------------------------------- - | Displays specified material on backdrop, or the last material used if - | none specified. Good for pause menus like in the browser. - -----------------------------------------------------------------------------*/ - void showBackdrop(const Ogre::String& materialName = Ogre::BLANKSTRING) - { - if (materialName != Ogre::BLANKSTRING) mBackdrop->setMaterialName(materialName); - mBackdropLayer->show(); - } - - void hideBackdrop() - { - mBackdropLayer->hide(); - } - - /*----------------------------------------------------------------------------- - | Displays specified material on cursor, or the last material used if - | none specified. Used to change cursor type. - -----------------------------------------------------------------------------*/ - void showCursor(const Ogre::String& materialName = Ogre::BLANKSTRING) - { - if (materialName != Ogre::BLANKSTRING) getCursorImage()->setMaterialName(materialName); - - if (!mCursorLayer->isVisible()) - { - mCursorLayer->show(); - refreshCursor(); - } - } - - void hideCursor() - { - mCursorLayer->hide(); - - // give widgets a chance to reset in case they're in the middle of something - for (unsigned int i = 0; i < 10; i++) - { - for (unsigned int j = 0; j < mWidgets[i].size(); j++) - { - mWidgets[i][j]->_focusLost(); - } - } - - setExpandedMenu(0); - } - - /*----------------------------------------------------------------------------- - | Updates cursor position based on unbuffered mouse state. This is necessary - | because if the tray manager has been cut off from mouse events for a time, - | the cursor position will be out of date. - -----------------------------------------------------------------------------*/ - void refreshCursor() - { + /*----------------------------------------------------------------------------- + | Displays specified material on cursor, or the last material used if + | none specified. Used to change cursor type. + -----------------------------------------------------------------------------*/ + void showCursor(const Ogre::String& materialName = Ogre::BLANKSTRING) + { + if (materialName != Ogre::BLANKSTRING) getCursorImage()->setMaterialName(materialName); + + if (!mCursorLayer->isVisible()) + { + mCursorLayer->show(); + refreshCursor(); + } + } + + void hideCursor() + { + mCursorLayer->hide(); + + // give widgets a chance to reset in case they're in the middle of something + for (unsigned int i = 0; i < 10; i++) + { + for (unsigned int j = 0; j < mWidgets[i].size(); j++) + { + mWidgets[i][j]->_focusLost(); + } + } + + setExpandedMenu(0); + } + + /*----------------------------------------------------------------------------- + | Updates cursor position based on unbuffered mouse state. This is necessary + | because if the tray manager has been cut off from mouse events for a time, + | the cursor position will be out of date. + -----------------------------------------------------------------------------*/ + void refreshCursor() + { #if (OGRE_NO_VIEWPORT_ORIENTATIONMODE == 0) || (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) // TODO: // the position should be based on the orientation, for now simply return @@ -1931,888 +1931,888 @@ namespace OgreBites Ogre::Real x, y; if(mInputContext.getCursorPosition(x, y)) mCursor->setPosition(x, y); - } - - void showTrays() - { - mTraysLayer->show(); - mPriorityLayer->show(); - } - - void hideTrays() - { - mTraysLayer->hide(); - mPriorityLayer->hide(); - - // give widgets a chance to reset in case they're in the middle of something - for (unsigned int i = 0; i < 10; i++) - { - for (unsigned int j = 0; j < mWidgets[i].size(); j++) - { - mWidgets[i][j]->_focusLost(); - } - } - - setExpandedMenu(0); - } - - bool isCursorVisible() { return mCursorLayer->isVisible(); } - bool isBackdropVisible() { return mBackdropLayer->isVisible(); } - bool areTraysVisible() { return mTraysLayer->isVisible(); } - - /*----------------------------------------------------------------------------- - | Sets horizontal alignment of a tray's contents. - -----------------------------------------------------------------------------*/ - void setTrayWidgetAlignment(TrayLocation trayLoc, Ogre::GuiHorizontalAlignment gha) - { - mTrayWidgetAlign[trayLoc] = gha; - - for (unsigned int i = 0; i < mWidgets[trayLoc].size(); i++) - { - mWidgets[trayLoc][i]->getOverlayElement()->setHorizontalAlignment(gha); - } - } - - // padding and spacing methods - - void setWidgetPadding(Ogre::Real padding) - { - mWidgetPadding = std::max((int)padding, 0); - adjustTrays(); - } - - void setWidgetSpacing(Ogre::Real spacing) - { - mWidgetSpacing = std::max((int)spacing, 0); - adjustTrays(); - } - void setTrayPadding(Ogre::Real padding) - { - mTrayPadding = std::max((int)padding, 0); - adjustTrays(); - } - - virtual Ogre::Real getWidgetPadding() const { return mWidgetPadding; } - virtual Ogre::Real getWidgetSpacing() const { return mWidgetSpacing; } - virtual Ogre::Real getTrayPadding() const { return mTrayPadding; } - - /*----------------------------------------------------------------------------- - | Fits trays to their contents and snaps them to their anchor locations. - -----------------------------------------------------------------------------*/ - virtual void adjustTrays() - { - for (unsigned int i = 0; i < 9; i++) // resizes and hides trays if necessary - { - Ogre::Real trayWidth = 0; - Ogre::Real trayHeight = mWidgetPadding; - std::vector labelsAndSeps; - - if (mWidgets[i].empty()) // hide tray if empty - { - mTrays[i]->hide(); - continue; - } - else mTrays[i]->show(); - - // arrange widgets and calculate final tray size and position - for (unsigned int j = 0; j < mWidgets[i].size(); j++) - { - Ogre::OverlayElement* e = mWidgets[i][j]->getOverlayElement(); - - if (j != 0) trayHeight += mWidgetSpacing; // don't space first widget - - e->setVerticalAlignment(Ogre::GVA_TOP); - e->setTop(trayHeight); - - switch (e->getHorizontalAlignment()) - { - case Ogre::GHA_LEFT: - e->setLeft(mWidgetPadding); - break; - case Ogre::GHA_RIGHT: - e->setLeft(-(e->getWidth() + mWidgetPadding)); - break; - default: - e->setLeft(-(e->getWidth() / 2)); - } - - // prevents some weird texture filtering problems (just some) - e->setPosition((int)e->getLeft(), (int)e->getTop()); - e->setDimensions((int)e->getWidth(), (int)e->getHeight()); - - trayHeight += e->getHeight(); - - Label* l = dynamic_cast(mWidgets[i][j]); - if (l && l->_isFitToTray()) - { - labelsAndSeps.push_back(e); - continue; - } - Separator* s = dynamic_cast(mWidgets[i][j]); - if (s && s->_isFitToTray()) - { - labelsAndSeps.push_back(e); - continue; - } - - if (e->getWidth() > trayWidth) trayWidth = e->getWidth(); - } - - // add paddings and resize trays - mTrays[i]->setWidth(trayWidth + 2 * mWidgetPadding); - mTrays[i]->setHeight(trayHeight + mWidgetPadding); - - for (unsigned int j = 0; j < labelsAndSeps.size(); j++) - { - labelsAndSeps[j]->setWidth((int)trayWidth); - labelsAndSeps[j]->setLeft(-(int)(trayWidth / 2)); - } - } - - for (unsigned int i = 0; i < 9; i++) // snap trays to anchors - { - if (i == TL_TOPLEFT || i == TL_LEFT || i == TL_BOTTOMLEFT) - mTrays[i]->setLeft(mTrayPadding); - if (i == TL_TOP || i == TL_CENTER || i == TL_BOTTOM) - mTrays[i]->setLeft(-mTrays[i]->getWidth() / 2); - if (i == TL_TOPRIGHT || i == TL_RIGHT || i == TL_BOTTOMRIGHT) - mTrays[i]->setLeft(-(mTrays[i]->getWidth() + mTrayPadding)); - - if (i == TL_TOPLEFT || i == TL_TOP || i == TL_TOPRIGHT) - mTrays[i]->setTop(mTrayPadding); - if (i == TL_LEFT || i == TL_CENTER || i == TL_RIGHT) - mTrays[i]->setTop(-mTrays[i]->getHeight() / 2); - if (i == TL_BOTTOMLEFT || i == TL_BOTTOM || i == TL_BOTTOMRIGHT) - mTrays[i]->setTop(-mTrays[i]->getHeight() - mTrayPadding); - - // prevents some weird texture filtering problems (just some) - mTrays[i]->setPosition((int)mTrays[i]->getLeft(), (int)mTrays[i]->getTop()); - mTrays[i]->setDimensions((int)mTrays[i]->getWidth(), (int)mTrays[i]->getHeight()); - } - } - - /*----------------------------------------------------------------------------- - | Returns a 3D ray into the scene that is directly underneath the cursor. - -----------------------------------------------------------------------------*/ - Ogre::Ray getCursorRay(Ogre::Camera* cam) - { - return screenToScene(cam, Ogre::Vector2(mCursor->_getLeft(), mCursor->_getTop())); - } - - Button* createButton(TrayLocation trayLoc, const Ogre::String& name, const Ogre::String& caption, Ogre::Real width = 0) - { - Button* b = new Button(name, caption, width); - moveWidgetToTray(b, trayLoc); - b->_assignListener(mListener); - return b; - } - - TextBox* createTextBox(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, - Ogre::Real width, Ogre::Real height) - { - TextBox* tb = new TextBox(name, caption, width, height); - moveWidgetToTray(tb, trayLoc); - tb->_assignListener(mListener); - return tb; - } - - SelectMenu* createThickSelectMenu(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, - Ogre::Real width, unsigned int maxItemsShown, const Ogre::StringVector& items = Ogre::StringVector()) - { - SelectMenu* sm = new SelectMenu(name, caption, width, 0, maxItemsShown); - moveWidgetToTray(sm, trayLoc); - sm->_assignListener(mListener); - if (!items.empty()) sm->setItems(items); - return sm; - } - - SelectMenu* createLongSelectMenu(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, - Ogre::Real width, Ogre::Real boxWidth, unsigned int maxItemsShown, const Ogre::StringVector& items = Ogre::StringVector()) - { - SelectMenu* sm = new SelectMenu(name, caption, width, boxWidth, maxItemsShown); - moveWidgetToTray(sm, trayLoc); - sm->_assignListener(mListener); - if (!items.empty()) sm->setItems(items); - return sm; - } - - SelectMenu* createLongSelectMenu(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, - Ogre::Real boxWidth, unsigned int maxItemsShown, const Ogre::StringVector& items = Ogre::StringVector()) - { - return createLongSelectMenu(trayLoc, name, caption, 0, boxWidth, maxItemsShown, items); - } - - Label* createLabel(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width = 0) - { - Label* l = new Label(name, caption, width); - moveWidgetToTray(l, trayLoc); - l->_assignListener(mListener); - return l; - } - - Separator* createSeparator(TrayLocation trayLoc, const Ogre::String& name, Ogre::Real width = 0) - { - Separator* s = new Separator(name, width); - moveWidgetToTray(s, trayLoc); - return s; - } - - Slider* createThickSlider(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, - Ogre::Real width, Ogre::Real valueBoxWidth, Ogre::Real minValue, Ogre::Real maxValue, unsigned int snaps) - { - Slider* s = new Slider(name, caption, width, 0, valueBoxWidth, minValue, maxValue, snaps); - moveWidgetToTray(s, trayLoc); - s->_assignListener(mListener); - return s; - } - - Slider* createLongSlider(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width, - Ogre::Real trackWidth, Ogre::Real valueBoxWidth, Ogre::Real minValue, Ogre::Real maxValue, unsigned int snaps) - { - if (trackWidth <= 0) trackWidth = 1; - Slider* s = new Slider(name, caption, width, trackWidth, valueBoxWidth, minValue, maxValue, snaps); - moveWidgetToTray(s, trayLoc); - s->_assignListener(mListener); - return s; - } - - Slider* createLongSlider(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, - Ogre::Real trackWidth, Ogre::Real valueBoxWidth, Ogre::Real minValue, Ogre::Real maxValue, unsigned int snaps) - { - return createLongSlider(trayLoc, name, caption, 0, trackWidth, valueBoxWidth, minValue, maxValue, snaps); - } - - ParamsPanel* createParamsPanel(TrayLocation trayLoc, const Ogre::String& name, Ogre::Real width, unsigned int lines) - { - ParamsPanel* pp = new ParamsPanel(name, width, lines); - moveWidgetToTray(pp, trayLoc); - return pp; - } - - ParamsPanel* createParamsPanel(TrayLocation trayLoc, const Ogre::String& name, Ogre::Real width, - const Ogre::StringVector& paramNames) - { - ParamsPanel* pp = new ParamsPanel(name, width, (Ogre::uint)paramNames.size()); - pp->setAllParamNames(paramNames); - moveWidgetToTray(pp, trayLoc); - return pp; - } - - CheckBox* createCheckBox(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, - Ogre::Real width = 0) - { - CheckBox* cb = new CheckBox(name, caption, width); - moveWidgetToTray(cb, trayLoc); - cb->_assignListener(mListener); - return cb; - } - - DecorWidget* createDecorWidget(TrayLocation trayLoc, const Ogre::String& name, const Ogre::String& templateName) - { - DecorWidget* dw = new DecorWidget(name, templateName); - moveWidgetToTray(dw, trayLoc); - return dw; - } - - ProgressBar* createProgressBar(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, - Ogre::Real width, Ogre::Real commentBoxWidth) - { - ProgressBar* pb = new ProgressBar(name, caption, width, commentBoxWidth); - moveWidgetToTray(pb, trayLoc); - return pb; - } - - /*----------------------------------------------------------------------------- - | Shows frame statistics widget set in the specified location. - -----------------------------------------------------------------------------*/ - void showFrameStats(TrayLocation trayLoc, int place = -1) - { - if (!areFrameStatsVisible()) - { - Ogre::StringVector stats; - stats.push_back("Average FPS"); - stats.push_back("Best FPS"); - stats.push_back("Worst FPS"); - stats.push_back("Triangles"); - stats.push_back("Batches"); - - mFpsLabel = createLabel(TL_NONE, mName + "/FpsLabel", "FPS:", 180); - mFpsLabel->_assignListener(this); - mStatsPanel = createParamsPanel(TL_NONE, mName + "/StatsPanel", 180, stats); - } - - moveWidgetToTray(mFpsLabel, trayLoc, place); - moveWidgetToTray(mStatsPanel, trayLoc, locateWidgetInTray(mFpsLabel) + 1); - } - - /*----------------------------------------------------------------------------- - | Hides frame statistics widget set. - -----------------------------------------------------------------------------*/ - void hideFrameStats() - { - if (areFrameStatsVisible()) - { - destroyWidget(mFpsLabel); - destroyWidget(mStatsPanel); - mFpsLabel = 0; - mStatsPanel = 0; - } - } - - bool areFrameStatsVisible() - { - return mFpsLabel != 0; - } - - /*----------------------------------------------------------------------------- - | Toggles visibility of advanced statistics. - -----------------------------------------------------------------------------*/ - void toggleAdvancedFrameStats() - { - if (mFpsLabel) labelHit(mFpsLabel); - } - - /*----------------------------------------------------------------------------- - | Shows logo in the specified location. - -----------------------------------------------------------------------------*/ - void showLogo(TrayLocation trayLoc, int place = -1) - { - if (!isLogoVisible()) mLogo = createDecorWidget(TL_NONE, mName + "/Logo", "SdkTrays/Logo"); - moveWidgetToTray(mLogo, trayLoc, place); - } - - void hideLogo() - { - if (isLogoVisible()) - { - destroyWidget(mLogo); - mLogo = 0; - } - } - - bool isLogoVisible() - { - return mLogo != 0; - } - - /*----------------------------------------------------------------------------- - | Shows loading bar. Also takes job settings: the number of resource groups - | to be initialised, the number of resource groups to be loaded, and the - | proportion of the job that will be taken up by initialisation. Usually, - | script parsing takes up most time, so the default value is 0.7. - -----------------------------------------------------------------------------*/ - void showLoadingBar(unsigned int numGroupsInit = 1, unsigned int numGroupsLoad = 1, - Ogre::Real initProportion = 0.7) - { - if (mDialog) closeDialog(); - if (mLoadBar) hideLoadingBar(); - - mLoadBar = new ProgressBar(mName + "/LoadingBar", "Loading...", 400, 308); - Ogre::OverlayElement* e = mLoadBar->getOverlayElement(); - mDialogShade->addChild(e); - e->setVerticalAlignment(Ogre::GVA_CENTER); - e->setLeft(-(e->getWidth() / 2)); - e->setTop(-(e->getHeight() / 2)); - - Ogre::ResourceGroupManager::getSingleton().addResourceGroupListener(this); - mCursorWasVisible = isCursorVisible(); - hideCursor(); - mDialogShade->show(); - - // calculate the proportion of job required to init/load one group - - if (numGroupsInit == 0 && numGroupsLoad != 0) - { - mGroupInitProportion = 0; - mGroupLoadProportion = 1; - } - else if (numGroupsLoad == 0 && numGroupsInit != 0) - { - mGroupLoadProportion = 0; - if (numGroupsInit != 0) mGroupInitProportion = 1; - } - else if (numGroupsInit == 0 && numGroupsLoad == 0) - { - mGroupInitProportion = 0; - mGroupLoadProportion = 0; - } - else - { - mGroupInitProportion = initProportion / numGroupsInit; - mGroupLoadProportion = (1 - initProportion) / numGroupsLoad; - } - } - - void hideLoadingBar() - { - if (mLoadBar) - { - mLoadBar->cleanup(); - delete mLoadBar; - mLoadBar = 0; - - Ogre::ResourceGroupManager::getSingleton().removeResourceGroupListener(this); - if (mCursorWasVisible) showCursor(); - mDialogShade->hide(); - } - } - - bool isLoadingBarVisible() - { - return mLoadBar != 0; - } - - /*----------------------------------------------------------------------------- - | Pops up a message dialog with an OK button. - -----------------------------------------------------------------------------*/ - void showOkDialog(const Ogre::DisplayString& caption, const Ogre::DisplayString& message) - { - if (mLoadBar) hideLoadingBar(); - - Ogre::OverlayElement* e; - - if (mDialog) - { - mDialog->setCaption(caption); - mDialog->setText(message); - - if (mOk) return; - else - { - mYes->cleanup(); - mNo->cleanup(); - delete mYes; - delete mNo; - mYes = 0; - mNo = 0; - } - } - else - { - // give widgets a chance to reset in case they're in the middle of something - for (unsigned int i = 0; i < 10; i++) - { - for (unsigned int j = 0; j < mWidgets[i].size(); j++) - { - mWidgets[i][j]->_focusLost(); - } - } - - mDialogShade->show(); - - mDialog = new TextBox(mName + "/DialogBox", caption, 300, 208); - mDialog->setText(message); - e = mDialog->getOverlayElement(); - mDialogShade->addChild(e); - e->setVerticalAlignment(Ogre::GVA_CENTER); - e->setLeft(-(e->getWidth() / 2)); - e->setTop(-(e->getHeight() / 2)); - - mCursorWasVisible = isCursorVisible(); - showCursor(); - } - - mOk = new Button(mName + "/OkButton", "OK", 60); - mOk->_assignListener(this); - e = mOk->getOverlayElement(); - mDialogShade->addChild(e); - e->setVerticalAlignment(Ogre::GVA_CENTER); - e->setLeft(-(e->getWidth() / 2)); - e->setTop(mDialog->getOverlayElement()->getTop() + mDialog->getOverlayElement()->getHeight() + 5); - } - - /*----------------------------------------------------------------------------- - | Pops up a question dialog with Yes and No buttons. - -----------------------------------------------------------------------------*/ - void showYesNoDialog(const Ogre::DisplayString& caption, const Ogre::DisplayString& question) - { - if (mLoadBar) hideLoadingBar(); - - Ogre::OverlayElement* e; - - if (mDialog) - { - mDialog->setCaption(caption); - mDialog->setText(question); - - if (mOk) - { - mOk->cleanup(); - delete mOk; - mOk = 0; - } - else return; - } - else - { - // give widgets a chance to reset in case they're in the middle of something - for (unsigned int i = 0; i < 10; i++) - { - for (unsigned int j = 0; j < mWidgets[i].size(); j++) - { - mWidgets[i][j]->_focusLost(); - } - } - - mDialogShade->show(); - - mDialog = new TextBox(mName + "/DialogBox", caption, 300, 208); - mDialog->setText(question); - e = mDialog->getOverlayElement(); - mDialogShade->addChild(e); - e->setVerticalAlignment(Ogre::GVA_CENTER); - e->setLeft(-(e->getWidth() / 2)); - e->setTop(-(e->getHeight() / 2)); - - mCursorWasVisible = isCursorVisible(); - showCursor(); - } - - mYes = new Button(mName + "/YesButton", "Yes", 58); - mYes->_assignListener(this); - e = mYes->getOverlayElement(); - mDialogShade->addChild(e); - e->setVerticalAlignment(Ogre::GVA_CENTER); - e->setLeft(-(e->getWidth() + 2)); - e->setTop(mDialog->getOverlayElement()->getTop() + mDialog->getOverlayElement()->getHeight() + 5); - - mNo = new Button(mName + "/NoButton", "No", 50); - mNo->_assignListener(this); - e = mNo->getOverlayElement(); - mDialogShade->addChild(e); - e->setVerticalAlignment(Ogre::GVA_CENTER); - e->setLeft(3); - e->setTop(mDialog->getOverlayElement()->getTop() + mDialog->getOverlayElement()->getHeight() + 5); - } - - /*----------------------------------------------------------------------------- - | Hides whatever dialog is currently showing. - -----------------------------------------------------------------------------*/ - void closeDialog() - { - if (mDialog) - { - if (mOk) - { - mOk->cleanup(); - delete mOk; - mOk = 0; - } - else - { - mYes->cleanup(); - mNo->cleanup(); - delete mYes; - delete mNo; - mYes = 0; - mNo = 0; - } - - mDialogShade->hide(); - mDialog->cleanup(); - delete mDialog; - mDialog = 0; - - if (!mCursorWasVisible) hideCursor(); - } - } - - /*----------------------------------------------------------------------------- - | Determines if any dialog is currently visible. - -----------------------------------------------------------------------------*/ - bool isDialogVisible() - { - return mDialog != 0; - } - - /*----------------------------------------------------------------------------- - | Gets a widget from a tray by place. - -----------------------------------------------------------------------------*/ - Widget* getWidget(TrayLocation trayLoc, unsigned int place) - { - if (place < mWidgets[trayLoc].size()) return mWidgets[trayLoc][place]; - return 0; - } - - /*----------------------------------------------------------------------------- - | Gets a widget from a tray by name. - -----------------------------------------------------------------------------*/ - Widget* getWidget(TrayLocation trayLoc, const Ogre::String& name) - { - for (unsigned int i = 0; i < mWidgets[trayLoc].size(); i++) - { - if (mWidgets[trayLoc][i]->getName() == name) return mWidgets[trayLoc][i]; - } - return 0; - } - - /*----------------------------------------------------------------------------- - | Gets a widget by name. - -----------------------------------------------------------------------------*/ - Widget* getWidget(const Ogre::String& name) - { - for (unsigned int i = 0; i < 10; i++) - { - for (unsigned int j = 0; j < mWidgets[i].size(); j++) - { - if (mWidgets[i][j]->getName() == name) return mWidgets[i][j]; - } - } - return 0; - } - - /*----------------------------------------------------------------------------- - | Gets the number of widgets in total. - -----------------------------------------------------------------------------*/ - unsigned int getNumWidgets() - { - unsigned int total = 0; - - for (unsigned int i = 0; i < 10; i++) - { - total += mWidgets[i].size(); - } - - return total; - } - - /*----------------------------------------------------------------------------- - | Gets the number of widgets in a tray. - -----------------------------------------------------------------------------*/ - size_t getNumWidgets(TrayLocation trayLoc) - { - return mWidgets[trayLoc].size(); - } - - /*----------------------------------------------------------------------------- - | Gets all the widgets of a specific tray. - -----------------------------------------------------------------------------*/ - WidgetIterator getWidgetIterator(TrayLocation trayLoc) - { - return WidgetIterator(mWidgets[trayLoc].begin(), mWidgets[trayLoc].end()); - } - - /*----------------------------------------------------------------------------- - | Gets a widget's position in its tray. - -----------------------------------------------------------------------------*/ - int locateWidgetInTray(Widget* widget) - { - for (unsigned int i = 0; i < mWidgets[widget->getTrayLocation()].size(); i++) - { - if (mWidgets[widget->getTrayLocation()][i] == widget) return i; - } - return -1; - } - - /*----------------------------------------------------------------------------- - | Destroys a widget. - -----------------------------------------------------------------------------*/ - void destroyWidget(Widget* widget) - { - if (!widget) OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Widget does not exist.", "TrayManager::destroyWidget"); - - // in case special widgets are destroyed manually, set them to 0 - if (widget == mLogo) mLogo = 0; - else if (widget == mStatsPanel) mStatsPanel = 0; - else if (widget == mFpsLabel) mFpsLabel = 0; - - mTrays[widget->getTrayLocation()]->removeChild(widget->getName()); - - WidgetList& wList = mWidgets[widget->getTrayLocation()]; - wList.erase(std::find(wList.begin(), wList.end(), widget)); - if (widget == mExpandedMenu) setExpandedMenu(0); - - widget->cleanup(); - - mWidgetDeathRow.push_back(widget); - - adjustTrays(); - } - - void destroyWidget(TrayLocation trayLoc, unsigned int place) - { - destroyWidget(getWidget(trayLoc, place)); - } - - void destroyWidget(TrayLocation trayLoc, const Ogre::String& name) - { - destroyWidget(getWidget(trayLoc, name)); - } - - void destroyWidget(const Ogre::String& name) - { - destroyWidget(getWidget(name)); - } - - /*----------------------------------------------------------------------------- - | Destroys all widgets in a tray. - -----------------------------------------------------------------------------*/ - void destroyAllWidgetsInTray(TrayLocation trayLoc) - { - while (!mWidgets[trayLoc].empty()) destroyWidget(mWidgets[trayLoc][0]); - } - - /*----------------------------------------------------------------------------- - | Destroys all widgets. - -----------------------------------------------------------------------------*/ - void destroyAllWidgets() - { - for (unsigned int i = 0; i < 10; i++) // destroy every widget in every tray (including null tray) - { - destroyAllWidgetsInTray((TrayLocation)i); - } - } - - /*----------------------------------------------------------------------------- - | Adds a widget to a specified tray. - -----------------------------------------------------------------------------*/ - void moveWidgetToTray(Widget* widget, TrayLocation trayLoc, int place = -1) - { - if (!widget) OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Widget does not exist.", "TrayManager::moveWidgetToTray"); - - // remove widget from old tray - WidgetList& wList = mWidgets[widget->getTrayLocation()]; - WidgetList::iterator it = std::find(wList.begin(), wList.end(), widget); - if (it != wList.end()) - { - wList.erase(it); - mTrays[widget->getTrayLocation()]->removeChild(widget->getName()); - } - - // insert widget into new tray at given position, or at the end if unspecified or invalid - if (place == -1 || place > (int)mWidgets[trayLoc].size()) place = (int)mWidgets[trayLoc].size(); - mWidgets[trayLoc].insert(mWidgets[trayLoc].begin() + place, widget); - mTrays[trayLoc]->addChild(widget->getOverlayElement()); - - widget->getOverlayElement()->setHorizontalAlignment(mTrayWidgetAlign[trayLoc]); - - // adjust trays if necessary - if (widget->getTrayLocation() != TL_NONE || trayLoc != TL_NONE) adjustTrays(); - - widget->_assignToTray(trayLoc); - } - - void moveWidgetToTray(const Ogre::String& name, TrayLocation trayLoc, unsigned int place = -1) - { - moveWidgetToTray(getWidget(name), trayLoc, place); - } - - void moveWidgetToTray(TrayLocation currentTrayLoc, const Ogre::String& name, TrayLocation targetTrayLoc, - int place = -1) - { - moveWidgetToTray(getWidget(currentTrayLoc, name), targetTrayLoc, place); - } - - void moveWidgetToTray(TrayLocation currentTrayLoc, unsigned int currentPlace, TrayLocation targetTrayLoc, - int targetPlace = -1) - { - moveWidgetToTray(getWidget(currentTrayLoc, currentPlace), targetTrayLoc, targetPlace); - } - - /*----------------------------------------------------------------------------- - | Removes a widget from its tray. Same as moving it to the null tray. - -----------------------------------------------------------------------------*/ - void removeWidgetFromTray(Widget* widget) - { - moveWidgetToTray(widget, TL_NONE); - } - - void removeWidgetFromTray(const Ogre::String& name) - { - removeWidgetFromTray(getWidget(name)); - } - - void removeWidgetFromTray(TrayLocation trayLoc, const Ogre::String& name) - { - removeWidgetFromTray(getWidget(trayLoc, name)); - } - - void removeWidgetFromTray(TrayLocation trayLoc, int place) - { - removeWidgetFromTray(getWidget(trayLoc, place)); - } - - /*----------------------------------------------------------------------------- - | Removes all widgets from a widget tray. - -----------------------------------------------------------------------------*/ - void clearTray(TrayLocation trayLoc) - { - if (trayLoc == TL_NONE) return; // can't clear the null tray - - while (!mWidgets[trayLoc].empty()) // remove every widget from given tray - { - removeWidgetFromTray(mWidgets[trayLoc][0]); - } - } - - /*----------------------------------------------------------------------------- - | Removes all widgets from all widget trays. - -----------------------------------------------------------------------------*/ - void clearAllTrays() - { - for (unsigned int i = 0; i < 9; i++) - { - clearTray((TrayLocation)i); - } - } - - /*----------------------------------------------------------------------------- - | Process frame events. Updates frame statistics widget set and deletes - | all widgets queued for destruction. - -----------------------------------------------------------------------------*/ - bool frameRenderingQueued(const Ogre::FrameEvent& evt) - { - for (unsigned int i = 0; i < mWidgetDeathRow.size(); i++) - { - delete mWidgetDeathRow[i]; - } - mWidgetDeathRow.clear(); + } + void showTrays() + { + mTraysLayer->show(); + mPriorityLayer->show(); + } - unsigned long currentTime = mTimer->getMilliseconds(); - if (areFrameStatsVisible() && currentTime - mLastStatUpdateTime > 250) - { - Ogre::RenderTarget::FrameStats stats = mWindow->getStatistics(); + void hideTrays() + { + mTraysLayer->hide(); + mPriorityLayer->hide(); + + // give widgets a chance to reset in case they're in the middle of something + for (unsigned int i = 0; i < 10; i++) + { + for (unsigned int j = 0; j < mWidgets[i].size(); j++) + { + mWidgets[i][j]->_focusLost(); + } + } + + setExpandedMenu(0); + } - mLastStatUpdateTime = currentTime; + bool isCursorVisible() { return mCursorLayer->isVisible(); } + bool isBackdropVisible() { return mBackdropLayer->isVisible(); } + bool areTraysVisible() { return mTraysLayer->isVisible(); } + + /*----------------------------------------------------------------------------- + | Sets horizontal alignment of a tray's contents. + -----------------------------------------------------------------------------*/ + void setTrayWidgetAlignment(TrayLocation trayLoc, Ogre::GuiHorizontalAlignment gha) + { + mTrayWidgetAlign[trayLoc] = gha; + + for (unsigned int i = 0; i < mWidgets[trayLoc].size(); i++) + { + mWidgets[trayLoc][i]->getOverlayElement()->setHorizontalAlignment(gha); + } + } + + // padding and spacing methods + + void setWidgetPadding(Ogre::Real padding) + { + mWidgetPadding = std::max((int)padding, 0); + adjustTrays(); + } + + void setWidgetSpacing(Ogre::Real spacing) + { + mWidgetSpacing = std::max((int)spacing, 0); + adjustTrays(); + } + void setTrayPadding(Ogre::Real padding) + { + mTrayPadding = std::max((int)padding, 0); + adjustTrays(); + } + + virtual Ogre::Real getWidgetPadding() const { return mWidgetPadding; } + virtual Ogre::Real getWidgetSpacing() const { return mWidgetSpacing; } + virtual Ogre::Real getTrayPadding() const { return mTrayPadding; } + + /*----------------------------------------------------------------------------- + | Fits trays to their contents and snaps them to their anchor locations. + -----------------------------------------------------------------------------*/ + virtual void adjustTrays() + { + for (unsigned int i = 0; i < 9; i++) // resizes and hides trays if necessary + { + Ogre::Real trayWidth = 0; + Ogre::Real trayHeight = mWidgetPadding; + std::vector labelsAndSeps; + + if (mWidgets[i].empty()) // hide tray if empty + { + mTrays[i]->hide(); + continue; + } + else mTrays[i]->show(); + + // arrange widgets and calculate final tray size and position + for (unsigned int j = 0; j < mWidgets[i].size(); j++) + { + Ogre::OverlayElement* e = mWidgets[i][j]->getOverlayElement(); + + if (j != 0) trayHeight += mWidgetSpacing; // don't space first widget + + e->setVerticalAlignment(Ogre::GVA_TOP); + e->setTop(trayHeight); + + switch (e->getHorizontalAlignment()) + { + case Ogre::GHA_LEFT: + e->setLeft(mWidgetPadding); + break; + case Ogre::GHA_RIGHT: + e->setLeft(-(e->getWidth() + mWidgetPadding)); + break; + default: + e->setLeft(-(e->getWidth() / 2)); + } + + // prevents some weird texture filtering problems (just some) + e->setPosition((int)e->getLeft(), (int)e->getTop()); + e->setDimensions((int)e->getWidth(), (int)e->getHeight()); + + trayHeight += e->getHeight(); + + Label* l = dynamic_cast(mWidgets[i][j]); + if (l && l->_isFitToTray()) + { + labelsAndSeps.push_back(e); + continue; + } + Separator* s = dynamic_cast(mWidgets[i][j]); + if (s && s->_isFitToTray()) + { + labelsAndSeps.push_back(e); + continue; + } + + if (e->getWidth() > trayWidth) trayWidth = e->getWidth(); + } + + // add paddings and resize trays + mTrays[i]->setWidth(trayWidth + 2 * mWidgetPadding); + mTrays[i]->setHeight(trayHeight + mWidgetPadding); + + for (unsigned int j = 0; j < labelsAndSeps.size(); j++) + { + labelsAndSeps[j]->setWidth((int)trayWidth); + labelsAndSeps[j]->setLeft(-(int)(trayWidth / 2)); + } + } + + for (unsigned int i = 0; i < 9; i++) // snap trays to anchors + { + if (i == TL_TOPLEFT || i == TL_LEFT || i == TL_BOTTOMLEFT) + mTrays[i]->setLeft(mTrayPadding); + if (i == TL_TOP || i == TL_CENTER || i == TL_BOTTOM) + mTrays[i]->setLeft(-mTrays[i]->getWidth() / 2); + if (i == TL_TOPRIGHT || i == TL_RIGHT || i == TL_BOTTOMRIGHT) + mTrays[i]->setLeft(-(mTrays[i]->getWidth() + mTrayPadding)); + + if (i == TL_TOPLEFT || i == TL_TOP || i == TL_TOPRIGHT) + mTrays[i]->setTop(mTrayPadding); + if (i == TL_LEFT || i == TL_CENTER || i == TL_RIGHT) + mTrays[i]->setTop(-mTrays[i]->getHeight() / 2); + if (i == TL_BOTTOMLEFT || i == TL_BOTTOM || i == TL_BOTTOMRIGHT) + mTrays[i]->setTop(-mTrays[i]->getHeight() - mTrayPadding); + + // prevents some weird texture filtering problems (just some) + mTrays[i]->setPosition((int)mTrays[i]->getLeft(), (int)mTrays[i]->getTop()); + mTrays[i]->setDimensions((int)mTrays[i]->getWidth(), (int)mTrays[i]->getHeight()); + } + } + + /*----------------------------------------------------------------------------- + | Returns a 3D ray into the scene that is directly underneath the cursor. + -----------------------------------------------------------------------------*/ + Ogre::Ray getCursorRay(Ogre::Camera* cam) + { + return screenToScene(cam, Ogre::Vector2(mCursor->_getLeft(), mCursor->_getTop())); + } + + Button* createButton(TrayLocation trayLoc, const Ogre::String& name, const Ogre::String& caption, Ogre::Real width = 0) + { + Button* b = new Button(name, caption, width); + moveWidgetToTray(b, trayLoc); + b->_assignListener(mListener); + return b; + } + + TextBox* createTextBox(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, + Ogre::Real width, Ogre::Real height) + { + TextBox* tb = new TextBox(name, caption, width, height); + moveWidgetToTray(tb, trayLoc); + tb->_assignListener(mListener); + return tb; + } + + SelectMenu* createThickSelectMenu(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, + Ogre::Real width, unsigned int maxItemsShown, const Ogre::StringVector& items = Ogre::StringVector()) + { + SelectMenu* sm = new SelectMenu(name, caption, width, 0, maxItemsShown); + moveWidgetToTray(sm, trayLoc); + sm->_assignListener(mListener); + if (!items.empty()) sm->setItems(items); + return sm; + } + + SelectMenu* createLongSelectMenu(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, + Ogre::Real width, Ogre::Real boxWidth, unsigned int maxItemsShown, const Ogre::StringVector& items = Ogre::StringVector()) + { + SelectMenu* sm = new SelectMenu(name, caption, width, boxWidth, maxItemsShown); + moveWidgetToTray(sm, trayLoc); + sm->_assignListener(mListener); + if (!items.empty()) sm->setItems(items); + return sm; + } + + SelectMenu* createLongSelectMenu(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, + Ogre::Real boxWidth, unsigned int maxItemsShown, const Ogre::StringVector& items = Ogre::StringVector()) + { + return createLongSelectMenu(trayLoc, name, caption, 0, boxWidth, maxItemsShown, items); + } + + Label* createLabel(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width = 0) + { + Label* l = new Label(name, caption, width); + moveWidgetToTray(l, trayLoc); + l->_assignListener(mListener); + return l; + } + + Separator* createSeparator(TrayLocation trayLoc, const Ogre::String& name, Ogre::Real width = 0) + { + Separator* s = new Separator(name, width); + moveWidgetToTray(s, trayLoc); + return s; + } + + Slider* createThickSlider(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, + Ogre::Real width, Ogre::Real valueBoxWidth, Ogre::Real minValue, Ogre::Real maxValue, unsigned int snaps) + { + Slider* s = new Slider(name, caption, width, 0, valueBoxWidth, minValue, maxValue, snaps); + moveWidgetToTray(s, trayLoc); + s->_assignListener(mListener); + return s; + } + + Slider* createLongSlider(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, Ogre::Real width, + Ogre::Real trackWidth, Ogre::Real valueBoxWidth, Ogre::Real minValue, Ogre::Real maxValue, unsigned int snaps) + { + if (trackWidth <= 0) trackWidth = 1; + Slider* s = new Slider(name, caption, width, trackWidth, valueBoxWidth, minValue, maxValue, snaps); + moveWidgetToTray(s, trayLoc); + s->_assignListener(mListener); + return s; + } + + Slider* createLongSlider(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, + Ogre::Real trackWidth, Ogre::Real valueBoxWidth, Ogre::Real minValue, Ogre::Real maxValue, unsigned int snaps) + { + return createLongSlider(trayLoc, name, caption, 0, trackWidth, valueBoxWidth, minValue, maxValue, snaps); + } + + ParamsPanel* createParamsPanel(TrayLocation trayLoc, const Ogre::String& name, Ogre::Real width, unsigned int lines) + { + ParamsPanel* pp = new ParamsPanel(name, width, lines); + moveWidgetToTray(pp, trayLoc); + return pp; + } + + ParamsPanel* createParamsPanel(TrayLocation trayLoc, const Ogre::String& name, Ogre::Real width, + const Ogre::StringVector& paramNames) + { + ParamsPanel* pp = new ParamsPanel(name, width, (Ogre::uint)paramNames.size()); + pp->setAllParamNames(paramNames); + moveWidgetToTray(pp, trayLoc); + return pp; + } + + CheckBox* createCheckBox(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, + Ogre::Real width = 0) + { + CheckBox* cb = new CheckBox(name, caption, width); + moveWidgetToTray(cb, trayLoc); + cb->_assignListener(mListener); + return cb; + } + + DecorWidget* createDecorWidget(TrayLocation trayLoc, const Ogre::String& name, const Ogre::String& templateName) + { + DecorWidget* dw = new DecorWidget(name, templateName); + moveWidgetToTray(dw, trayLoc); + return dw; + } + + ProgressBar* createProgressBar(TrayLocation trayLoc, const Ogre::String& name, const Ogre::DisplayString& caption, + Ogre::Real width, Ogre::Real commentBoxWidth) + { + ProgressBar* pb = new ProgressBar(name, caption, width, commentBoxWidth); + moveWidgetToTray(pb, trayLoc); + return pb; + } + + /*----------------------------------------------------------------------------- + | Shows frame statistics widget set in the specified location. + -----------------------------------------------------------------------------*/ + void showFrameStats(TrayLocation trayLoc, int place = -1) + { + if (!areFrameStatsVisible()) + { + Ogre::StringVector stats; + stats.push_back("Average FPS"); + stats.push_back("Best FPS"); + stats.push_back("Worst FPS"); + stats.push_back("Triangles"); + stats.push_back("Batches"); + + mFpsLabel = createLabel(TL_NONE, mName + "/FpsLabel", "FPS:", 180); + mFpsLabel->_assignListener(this); + mStatsPanel = createParamsPanel(TL_NONE, mName + "/StatsPanel", 180, stats); + } + + moveWidgetToTray(mFpsLabel, trayLoc, place); + moveWidgetToTray(mStatsPanel, trayLoc, locateWidgetInTray(mFpsLabel) + 1); + } + + /*----------------------------------------------------------------------------- + | Hides frame statistics widget set. + -----------------------------------------------------------------------------*/ + void hideFrameStats() + { + if (areFrameStatsVisible()) + { + destroyWidget(mFpsLabel); + destroyWidget(mStatsPanel); + mFpsLabel = 0; + mStatsPanel = 0; + } + } + + bool areFrameStatsVisible() + { + return mFpsLabel != 0; + } + + /*----------------------------------------------------------------------------- + | Toggles visibility of advanced statistics. + -----------------------------------------------------------------------------*/ + void toggleAdvancedFrameStats() + { + if (mFpsLabel) labelHit(mFpsLabel); + } + + /*----------------------------------------------------------------------------- + | Shows logo in the specified location. + -----------------------------------------------------------------------------*/ + void showLogo(TrayLocation trayLoc, int place = -1) + { + if (!isLogoVisible()) mLogo = createDecorWidget(TL_NONE, mName + "/Logo", "SdkTrays/Logo"); + moveWidgetToTray(mLogo, trayLoc, place); + } + + void hideLogo() + { + if (isLogoVisible()) + { + destroyWidget(mLogo); + mLogo = 0; + } + } + + bool isLogoVisible() + { + return mLogo != 0; + } + + /*----------------------------------------------------------------------------- + | Shows loading bar. Also takes job settings: the number of resource groups + | to be initialised, the number of resource groups to be loaded, and the + | proportion of the job that will be taken up by initialisation. Usually, + | script parsing takes up most time, so the default value is 0.7. + -----------------------------------------------------------------------------*/ + void showLoadingBar(unsigned int numGroupsInit = 1, unsigned int numGroupsLoad = 1, + Ogre::Real initProportion = 0.7) + { + if (mDialog) closeDialog(); + if (mLoadBar) hideLoadingBar(); + + mLoadBar = new ProgressBar(mName + "/LoadingBar", "Loading...", 400, 308); + Ogre::OverlayElement* e = mLoadBar->getOverlayElement(); + mDialogShade->addChild(e); + e->setVerticalAlignment(Ogre::GVA_CENTER); + e->setLeft(-(e->getWidth() / 2)); + e->setTop(-(e->getHeight() / 2)); + + Ogre::ResourceGroupManager::getSingleton().addResourceGroupListener(this); + mCursorWasVisible = isCursorVisible(); + hideCursor(); + mDialogShade->show(); + + // calculate the proportion of job required to init/load one group + + if (numGroupsInit == 0 && numGroupsLoad != 0) + { + mGroupInitProportion = 0; + mGroupLoadProportion = 1; + } + else if (numGroupsLoad == 0 && numGroupsInit != 0) + { + mGroupLoadProportion = 0; + if (numGroupsInit != 0) mGroupInitProportion = 1; + } + else if (numGroupsInit == 0 && numGroupsLoad == 0) + { + mGroupInitProportion = 0; + mGroupLoadProportion = 0; + } + else + { + mGroupInitProportion = initProportion / numGroupsInit; + mGroupLoadProportion = (1 - initProportion) / numGroupsLoad; + } + } + + void hideLoadingBar() + { + if (mLoadBar) + { + mLoadBar->cleanup(); + delete mLoadBar; + mLoadBar = 0; + + Ogre::ResourceGroupManager::getSingleton().removeResourceGroupListener(this); + if (mCursorWasVisible) showCursor(); + mDialogShade->hide(); + } + } + + bool isLoadingBarVisible() + { + return mLoadBar != 0; + } + + /*----------------------------------------------------------------------------- + | Pops up a message dialog with an OK button. + -----------------------------------------------------------------------------*/ + void showOkDialog(const Ogre::DisplayString& caption, const Ogre::DisplayString& message) + { + if (mLoadBar) hideLoadingBar(); + + Ogre::OverlayElement* e; + + if (mDialog) + { + mDialog->setCaption(caption); + mDialog->setText(message); + + if (mOk) return; + else + { + mYes->cleanup(); + mNo->cleanup(); + delete mYes; + delete mNo; + mYes = 0; + mNo = 0; + } + } + else + { + // give widgets a chance to reset in case they're in the middle of something + for (unsigned int i = 0; i < 10; i++) + { + for (unsigned int j = 0; j < mWidgets[i].size(); j++) + { + mWidgets[i][j]->_focusLost(); + } + } + + mDialogShade->show(); + + mDialog = new TextBox(mName + "/DialogBox", caption, 300, 208); + mDialog->setText(message); + e = mDialog->getOverlayElement(); + mDialogShade->addChild(e); + e->setVerticalAlignment(Ogre::GVA_CENTER); + e->setLeft(-(e->getWidth() / 2)); + e->setTop(-(e->getHeight() / 2)); + + mCursorWasVisible = isCursorVisible(); + showCursor(); + } + + mOk = new Button(mName + "/OkButton", "OK", 60); + mOk->_assignListener(this); + e = mOk->getOverlayElement(); + mDialogShade->addChild(e); + e->setVerticalAlignment(Ogre::GVA_CENTER); + e->setLeft(-(e->getWidth() / 2)); + e->setTop(mDialog->getOverlayElement()->getTop() + mDialog->getOverlayElement()->getHeight() + 5); + } + + /*----------------------------------------------------------------------------- + | Pops up a question dialog with Yes and No buttons. + -----------------------------------------------------------------------------*/ + void showYesNoDialog(const Ogre::DisplayString& caption, const Ogre::DisplayString& question) + { + if (mLoadBar) hideLoadingBar(); + + Ogre::OverlayElement* e; + + if (mDialog) + { + mDialog->setCaption(caption); + mDialog->setText(question); + + if (mOk) + { + mOk->cleanup(); + delete mOk; + mOk = 0; + } + else return; + } + else + { + // give widgets a chance to reset in case they're in the middle of something + for (unsigned int i = 0; i < 10; i++) + { + for (unsigned int j = 0; j < mWidgets[i].size(); j++) + { + mWidgets[i][j]->_focusLost(); + } + } + + mDialogShade->show(); + + mDialog = new TextBox(mName + "/DialogBox", caption, 300, 208); + mDialog->setText(question); + e = mDialog->getOverlayElement(); + mDialogShade->addChild(e); + e->setVerticalAlignment(Ogre::GVA_CENTER); + e->setLeft(-(e->getWidth() / 2)); + e->setTop(-(e->getHeight() / 2)); + + mCursorWasVisible = isCursorVisible(); + showCursor(); + } + + mYes = new Button(mName + "/YesButton", "Yes", 58); + mYes->_assignListener(this); + e = mYes->getOverlayElement(); + mDialogShade->addChild(e); + e->setVerticalAlignment(Ogre::GVA_CENTER); + e->setLeft(-(e->getWidth() + 2)); + e->setTop(mDialog->getOverlayElement()->getTop() + mDialog->getOverlayElement()->getHeight() + 5); + + mNo = new Button(mName + "/NoButton", "No", 50); + mNo->_assignListener(this); + e = mNo->getOverlayElement(); + mDialogShade->addChild(e); + e->setVerticalAlignment(Ogre::GVA_CENTER); + e->setLeft(3); + e->setTop(mDialog->getOverlayElement()->getTop() + mDialog->getOverlayElement()->getHeight() + 5); + } + + /*----------------------------------------------------------------------------- + | Hides whatever dialog is currently showing. + -----------------------------------------------------------------------------*/ + void closeDialog() + { + if (mDialog) + { + if (mOk) + { + mOk->cleanup(); + delete mOk; + mOk = 0; + } + else + { + mYes->cleanup(); + mNo->cleanup(); + delete mYes; + delete mNo; + mYes = 0; + mNo = 0; + } + + mDialogShade->hide(); + mDialog->cleanup(); + delete mDialog; + mDialog = 0; + + if (!mCursorWasVisible) hideCursor(); + } + } - Ogre::String s("FPS: "); - s += Ogre::StringConverter::toString((int)stats.lastFPS); - - mFpsLabel->setCaption(s); + /*----------------------------------------------------------------------------- + | Determines if any dialog is currently visible. + -----------------------------------------------------------------------------*/ + bool isDialogVisible() + { + return mDialog != 0; + } + + /*----------------------------------------------------------------------------- + | Gets a widget from a tray by place. + -----------------------------------------------------------------------------*/ + Widget* getWidget(TrayLocation trayLoc, unsigned int place) + { + if (place < mWidgets[trayLoc].size()) return mWidgets[trayLoc][place]; + return 0; + } + + /*----------------------------------------------------------------------------- + | Gets a widget from a tray by name. + -----------------------------------------------------------------------------*/ + Widget* getWidget(TrayLocation trayLoc, const Ogre::String& name) + { + for (unsigned int i = 0; i < mWidgets[trayLoc].size(); i++) + { + if (mWidgets[trayLoc][i]->getName() == name) return mWidgets[trayLoc][i]; + } + return 0; + } + + /*----------------------------------------------------------------------------- + | Gets a widget by name. + -----------------------------------------------------------------------------*/ + Widget* getWidget(const Ogre::String& name) + { + for (unsigned int i = 0; i < 10; i++) + { + for (unsigned int j = 0; j < mWidgets[i].size(); j++) + { + if (mWidgets[i][j]->getName() == name) return mWidgets[i][j]; + } + } + return 0; + } + + /*----------------------------------------------------------------------------- + | Gets the number of widgets in total. + -----------------------------------------------------------------------------*/ + unsigned int getNumWidgets() + { + unsigned int total = 0; + + for (unsigned int i = 0; i < 10; i++) + { + total += mWidgets[i].size(); + } + + return total; + } + + /*----------------------------------------------------------------------------- + | Gets the number of widgets in a tray. + -----------------------------------------------------------------------------*/ + size_t getNumWidgets(TrayLocation trayLoc) + { + return mWidgets[trayLoc].size(); + } + + /*----------------------------------------------------------------------------- + | Gets all the widgets of a specific tray. + -----------------------------------------------------------------------------*/ + WidgetIterator getWidgetIterator(TrayLocation trayLoc) + { + return WidgetIterator(mWidgets[trayLoc].begin(), mWidgets[trayLoc].end()); + } + + /*----------------------------------------------------------------------------- + | Gets a widget's position in its tray. + -----------------------------------------------------------------------------*/ + int locateWidgetInTray(Widget* widget) + { + for (unsigned int i = 0; i < mWidgets[widget->getTrayLocation()].size(); i++) + { + if (mWidgets[widget->getTrayLocation()][i] == widget) return i; + } + return -1; + } + + /*----------------------------------------------------------------------------- + | Destroys a widget. + -----------------------------------------------------------------------------*/ + void destroyWidget(Widget* widget) + { + if (!widget) OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Widget does not exist.", "TrayManager::destroyWidget"); + + // in case special widgets are destroyed manually, set them to 0 + if (widget == mLogo) mLogo = 0; + else if (widget == mStatsPanel) mStatsPanel = 0; + else if (widget == mFpsLabel) mFpsLabel = 0; + + mTrays[widget->getTrayLocation()]->removeChild(widget->getName()); + + WidgetList& wList = mWidgets[widget->getTrayLocation()]; + wList.erase(std::find(wList.begin(), wList.end(), widget)); + if (widget == mExpandedMenu) setExpandedMenu(0); + + widget->cleanup(); + + mWidgetDeathRow.push_back(widget); + + adjustTrays(); + } + + void destroyWidget(TrayLocation trayLoc, unsigned int place) + { + destroyWidget(getWidget(trayLoc, place)); + } + + void destroyWidget(TrayLocation trayLoc, const Ogre::String& name) + { + destroyWidget(getWidget(trayLoc, name)); + } + + void destroyWidget(const Ogre::String& name) + { + destroyWidget(getWidget(name)); + } + + /*----------------------------------------------------------------------------- + | Destroys all widgets in a tray. + -----------------------------------------------------------------------------*/ + void destroyAllWidgetsInTray(TrayLocation trayLoc) + { + while (!mWidgets[trayLoc].empty()) destroyWidget(mWidgets[trayLoc][0]); + } + + /*----------------------------------------------------------------------------- + | Destroys all widgets. + -----------------------------------------------------------------------------*/ + void destroyAllWidgets() + { + for (unsigned int i = 0; i < 10; i++) // destroy every widget in every tray (including null tray) + { + destroyAllWidgetsInTray((TrayLocation)i); + } + } + + /*----------------------------------------------------------------------------- + | Adds a widget to a specified tray. + -----------------------------------------------------------------------------*/ + void moveWidgetToTray(Widget* widget, TrayLocation trayLoc, int place = -1) + { + if (!widget) OGRE_EXCEPT(Ogre::Exception::ERR_ITEM_NOT_FOUND, "Widget does not exist.", "TrayManager::moveWidgetToTray"); + + // remove widget from old tray + WidgetList& wList = mWidgets[widget->getTrayLocation()]; + WidgetList::iterator it = std::find(wList.begin(), wList.end(), widget); + if (it != wList.end()) + { + wList.erase(it); + mTrays[widget->getTrayLocation()]->removeChild(widget->getName()); + } + + // insert widget into new tray at given position, or at the end if unspecified or invalid + if (place == -1 || place > (int)mWidgets[trayLoc].size()) place = (int)mWidgets[trayLoc].size(); + mWidgets[trayLoc].insert(mWidgets[trayLoc].begin() + place, widget); + mTrays[trayLoc]->addChild(widget->getOverlayElement()); + + widget->getOverlayElement()->setHorizontalAlignment(mTrayWidgetAlign[trayLoc]); + + // adjust trays if necessary + if (widget->getTrayLocation() != TL_NONE || trayLoc != TL_NONE) adjustTrays(); + + widget->_assignToTray(trayLoc); + } + + void moveWidgetToTray(const Ogre::String& name, TrayLocation trayLoc, unsigned int place = -1) + { + moveWidgetToTray(getWidget(name), trayLoc, place); + } + + void moveWidgetToTray(TrayLocation currentTrayLoc, const Ogre::String& name, TrayLocation targetTrayLoc, + int place = -1) + { + moveWidgetToTray(getWidget(currentTrayLoc, name), targetTrayLoc, place); + } + + void moveWidgetToTray(TrayLocation currentTrayLoc, unsigned int currentPlace, TrayLocation targetTrayLoc, + int targetPlace = -1) + { + moveWidgetToTray(getWidget(currentTrayLoc, currentPlace), targetTrayLoc, targetPlace); + } + + /*----------------------------------------------------------------------------- + | Removes a widget from its tray. Same as moving it to the null tray. + -----------------------------------------------------------------------------*/ + void removeWidgetFromTray(Widget* widget) + { + moveWidgetToTray(widget, TL_NONE); + } + + void removeWidgetFromTray(const Ogre::String& name) + { + removeWidgetFromTray(getWidget(name)); + } + + void removeWidgetFromTray(TrayLocation trayLoc, const Ogre::String& name) + { + removeWidgetFromTray(getWidget(trayLoc, name)); + } - if (mStatsPanel->getOverlayElement()->isVisible()) - { - Ogre::StringVector values; - Ogre::StringStream oss; - - oss.str(""); - oss << std::fixed << std::setprecision(1) << stats.avgFPS; - Ogre::String str = oss.str(); - values.push_back(str); + void removeWidgetFromTray(TrayLocation trayLoc, int place) + { + removeWidgetFromTray(getWidget(trayLoc, place)); + } + + /*----------------------------------------------------------------------------- + | Removes all widgets from a widget tray. + -----------------------------------------------------------------------------*/ + void clearTray(TrayLocation trayLoc) + { + if (trayLoc == TL_NONE) return; // can't clear the null tray - oss.str(""); - oss << std::fixed << std::setprecision(1) << stats.bestFPS; - str = oss.str(); - values.push_back(str); + while (!mWidgets[trayLoc].empty()) // remove every widget from given tray + { + removeWidgetFromTray(mWidgets[trayLoc][0]); + } + } + + /*----------------------------------------------------------------------------- + | Removes all widgets from all widget trays. + -----------------------------------------------------------------------------*/ + void clearAllTrays() + { + for (unsigned int i = 0; i < 9; i++) + { + clearTray((TrayLocation)i); + } + } - oss.str(""); - oss << std::fixed << std::setprecision(1) << stats.worstFPS; - str = oss.str(); - values.push_back(str); + /*----------------------------------------------------------------------------- + | Process frame events. Updates frame statistics widget set and deletes + | all widgets queued for destruction. + -----------------------------------------------------------------------------*/ + bool frameRenderingQueued(const Ogre::FrameEvent& evt) + { + for (unsigned int i = 0; i < mWidgetDeathRow.size(); i++) + { + delete mWidgetDeathRow[i]; + } + mWidgetDeathRow.clear(); - str = Ogre::StringConverter::toString(stats.triangleCount); - values.push_back(str); - str = Ogre::StringConverter::toString(stats.batchCount); - values.push_back(str); + unsigned long currentTime = mTimer->getMilliseconds(); + if (areFrameStatsVisible() && currentTime - mLastStatUpdateTime > 250) + { + Ogre::RenderTarget::FrameStats stats = mWindow->getStatistics(); - mStatsPanel->setAllParamValues(values); - } - } + mLastStatUpdateTime = currentTime; - return true; - } + Ogre::String s("FPS: "); + s += Ogre::StringConverter::toString((int)stats.lastFPS); + + mFpsLabel->setCaption(s); + + if (mStatsPanel->getOverlayElement()->isVisible()) + { + Ogre::StringVector values; + Ogre::StringStream oss; + + oss.str(""); + oss << std::fixed << std::setprecision(1) << stats.avgFPS; + Ogre::String str = oss.str(); + values.push_back(str); + + oss.str(""); + oss << std::fixed << std::setprecision(1) << stats.bestFPS; + str = oss.str(); + values.push_back(str); + + oss.str(""); + oss << std::fixed << std::setprecision(1) << stats.worstFPS; + str = oss.str(); + values.push_back(str); + + str = Ogre::StringConverter::toString(stats.triangleCount); + values.push_back(str); + + str = Ogre::StringConverter::toString(stats.batchCount); + values.push_back(str); + + mStatsPanel->setAllParamValues(values); + } + } + + return true; + } void windowUpdate() { @@ -2821,344 +2821,344 @@ namespace OgreBites #endif } - void resourceGroupScriptingStarted(const Ogre::String& groupName, size_t scriptCount) - { - mLoadInc = mGroupInitProportion / scriptCount; - mLoadBar->setCaption("Parsing..."); - windowUpdate(); - } - - void scriptParseStarted(const Ogre::String& scriptName, bool& skipThisScript) - { - mLoadBar->setComment(scriptName); - windowUpdate(); - } - - void scriptParseEnded(const Ogre::String& scriptName, bool skipped) - { - mLoadBar->setProgress(mLoadBar->getProgress() + mLoadInc); - windowUpdate(); - } - - void resourceGroupScriptingEnded(const Ogre::String& groupName) {} - - void resourceGroupLoadStarted(const Ogre::String& groupName, size_t resourceCount) - { - mLoadInc = mGroupLoadProportion / resourceCount; - mLoadBar->setCaption("Loading..."); - windowUpdate(); - } - - void resourceLoadStarted(const Ogre::ResourcePtr& resource) - { - mLoadBar->setComment(resource->getName()); - windowUpdate(); - } - - void resourceLoadEnded() - { - mLoadBar->setProgress(mLoadBar->getProgress() + mLoadInc); - windowUpdate(); - } - - void worldGeometryStageStarted(const Ogre::String& description) - { - mLoadBar->setComment(description); - windowUpdate(); - } - - void worldGeometryStageEnded() - { - mLoadBar->setProgress(mLoadBar->getProgress() + mLoadInc); - windowUpdate(); - } - - void resourceGroupLoadEnded(const Ogre::String& groupName) {} - - /*----------------------------------------------------------------------------- - | Toggles visibility of advanced statistics. - -----------------------------------------------------------------------------*/ - void labelHit(Label* label) - { - if (mStatsPanel->getOverlayElement()->isVisible()) - { - mStatsPanel->getOverlayElement()->hide(); - mFpsLabel->getOverlayElement()->setWidth(150); - removeWidgetFromTray(mStatsPanel); - } - else - { - mStatsPanel->getOverlayElement()->show(); - mFpsLabel->getOverlayElement()->setWidth(180); - moveWidgetToTray(mStatsPanel, mFpsLabel->getTrayLocation(), locateWidgetInTray(mFpsLabel) + 1); - } - } - - /*----------------------------------------------------------------------------- - | Destroys dialog widgets, notifies listener, and ends high priority session. - -----------------------------------------------------------------------------*/ - void buttonHit(Button* button) - { - if (mListener) - { - if (button == mOk) mListener->okDialogClosed(mDialog->getText()); - else mListener->yesNoDialogClosed(mDialog->getText(), button == mYes); - } - closeDialog(); - } - - /*----------------------------------------------------------------------------- - | Processes mouse button down events. Returns true if the event was - | consumed and should not be passed on to other handlers. - -----------------------------------------------------------------------------*/ + void resourceGroupScriptingStarted(const Ogre::String& groupName, size_t scriptCount) + { + mLoadInc = mGroupInitProportion / scriptCount; + mLoadBar->setCaption("Parsing..."); + windowUpdate(); + } + + void scriptParseStarted(const Ogre::String& scriptName, bool& skipThisScript) + { + mLoadBar->setComment(scriptName); + windowUpdate(); + } + + void scriptParseEnded(const Ogre::String& scriptName, bool skipped) + { + mLoadBar->setProgress(mLoadBar->getProgress() + mLoadInc); + windowUpdate(); + } + + void resourceGroupScriptingEnded(const Ogre::String& groupName) {} + + void resourceGroupLoadStarted(const Ogre::String& groupName, size_t resourceCount) + { + mLoadInc = mGroupLoadProportion / resourceCount; + mLoadBar->setCaption("Loading..."); + windowUpdate(); + } + + void resourceLoadStarted(const Ogre::ResourcePtr& resource) + { + mLoadBar->setComment(resource->getName()); + windowUpdate(); + } + + void resourceLoadEnded() + { + mLoadBar->setProgress(mLoadBar->getProgress() + mLoadInc); + windowUpdate(); + } + + void worldGeometryStageStarted(const Ogre::String& description) + { + mLoadBar->setComment(description); + windowUpdate(); + } + + void worldGeometryStageEnded() + { + mLoadBar->setProgress(mLoadBar->getProgress() + mLoadInc); + windowUpdate(); + } + + void resourceGroupLoadEnded(const Ogre::String& groupName) {} + + /*----------------------------------------------------------------------------- + | Toggles visibility of advanced statistics. + -----------------------------------------------------------------------------*/ + void labelHit(Label* label) + { + if (mStatsPanel->getOverlayElement()->isVisible()) + { + mStatsPanel->getOverlayElement()->hide(); + mFpsLabel->getOverlayElement()->setWidth(150); + removeWidgetFromTray(mStatsPanel); + } + else + { + mStatsPanel->getOverlayElement()->show(); + mFpsLabel->getOverlayElement()->setWidth(180); + moveWidgetToTray(mStatsPanel, mFpsLabel->getTrayLocation(), locateWidgetInTray(mFpsLabel) + 1); + } + } + + /*----------------------------------------------------------------------------- + | Destroys dialog widgets, notifies listener, and ends high priority session. + -----------------------------------------------------------------------------*/ + void buttonHit(Button* button) + { + if (mListener) + { + if (button == mOk) mListener->okDialogClosed(mDialog->getText()); + else mListener->yesNoDialogClosed(mDialog->getText(), button == mYes); + } + closeDialog(); + } + + /*----------------------------------------------------------------------------- + | Processes mouse button down events. Returns true if the event was + | consumed and should not be passed on to other handlers. + -----------------------------------------------------------------------------*/ #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - bool injectMouseDown(const OIS::MultiTouchEvent& evt) + bool injectMouseDown(const OIS::MultiTouchEvent& evt) #else - bool injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + bool injectMouseDown(const OIS::MouseEvent& evt, OIS::MouseButtonID id) #endif - { + { #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) - // only process left button when stuff is visible - if (!mCursorLayer->isVisible() || id != OIS::MB_Left) return false; + // only process left button when stuff is visible + if (!mCursorLayer->isVisible() || id != OIS::MB_Left) return false; #else // only process touches when stuff is visible - if (!mCursorLayer->isVisible()) return false; + if (!mCursorLayer->isVisible()) return false; #endif - Ogre::Vector2 cursorPos(mCursor->getLeft(), mCursor->getTop()); - - mTrayDrag = false; - - if (mExpandedMenu) // only check top priority widget until it passes on - { - mExpandedMenu->_cursorPressed(cursorPos); - if (!mExpandedMenu->isExpanded()) setExpandedMenu(0); - return true; - } - - if (mDialog) // only check top priority widget until it passes on - { - mDialog->_cursorPressed(cursorPos); - if (mOk) mOk->_cursorPressed(cursorPos); - else - { - mYes->_cursorPressed(cursorPos); - mNo->_cursorPressed(cursorPos); - } - return true; - } - - for (unsigned int i = 0; i < 9; i++) // check if mouse is over a non-null tray - { - if (mTrays[i]->isVisible() && Widget::isCursorOver(mTrays[i], cursorPos, 2)) - { - mTrayDrag = true; // initiate a drag that originates in a tray - break; - } - } - - for (unsigned int i = 0; i < mWidgets[9].size(); i++) // check if mouse is over a non-null tray's widgets - { - if (mWidgets[9][i]->getOverlayElement()->isVisible() && - Widget::isCursorOver(mWidgets[9][i]->getOverlayElement(), cursorPos)) - { - mTrayDrag = true; // initiate a drag that originates in a tray - break; - } - } - - if (!mTrayDrag) return false; // don't process if mouse press is not in tray - - for (unsigned int i = 0; i < 10; i++) - { - if (!mTrays[i]->isVisible()) continue; - - for (unsigned int j = 0; j < mWidgets[i].size(); j++) - { - Widget* w = mWidgets[i][j]; - if (!w->getOverlayElement()->isVisible()) continue; - w->_cursorPressed(cursorPos); // send event to widget - - SelectMenu* m = dynamic_cast(w); - if (m && m->isExpanded()) // a menu has begun a top priority session - { - setExpandedMenu(m); - return true; - } - } - } - - return true; // a tray click is not to be handled by another party - } - - /*----------------------------------------------------------------------------- - | Processes mouse button up events. Returns true if the event was - | consumed and should not be passed on to other handlers. - -----------------------------------------------------------------------------*/ + Ogre::Vector2 cursorPos(mCursor->getLeft(), mCursor->getTop()); + + mTrayDrag = false; + + if (mExpandedMenu) // only check top priority widget until it passes on + { + mExpandedMenu->_cursorPressed(cursorPos); + if (!mExpandedMenu->isExpanded()) setExpandedMenu(0); + return true; + } + + if (mDialog) // only check top priority widget until it passes on + { + mDialog->_cursorPressed(cursorPos); + if (mOk) mOk->_cursorPressed(cursorPos); + else + { + mYes->_cursorPressed(cursorPos); + mNo->_cursorPressed(cursorPos); + } + return true; + } + + for (unsigned int i = 0; i < 9; i++) // check if mouse is over a non-null tray + { + if (mTrays[i]->isVisible() && Widget::isCursorOver(mTrays[i], cursorPos, 2)) + { + mTrayDrag = true; // initiate a drag that originates in a tray + break; + } + } + + for (unsigned int i = 0; i < mWidgets[9].size(); i++) // check if mouse is over a non-null tray's widgets + { + if (mWidgets[9][i]->getOverlayElement()->isVisible() && + Widget::isCursorOver(mWidgets[9][i]->getOverlayElement(), cursorPos)) + { + mTrayDrag = true; // initiate a drag that originates in a tray + break; + } + } + + if (!mTrayDrag) return false; // don't process if mouse press is not in tray + + for (unsigned int i = 0; i < 10; i++) + { + if (!mTrays[i]->isVisible()) continue; + + for (unsigned int j = 0; j < mWidgets[i].size(); j++) + { + Widget* w = mWidgets[i][j]; + if (!w->getOverlayElement()->isVisible()) continue; + w->_cursorPressed(cursorPos); // send event to widget + + SelectMenu* m = dynamic_cast(w); + if (m && m->isExpanded()) // a menu has begun a top priority session + { + setExpandedMenu(m); + return true; + } + } + } + + return true; // a tray click is not to be handled by another party + } + + /*----------------------------------------------------------------------------- + | Processes mouse button up events. Returns true if the event was + | consumed and should not be passed on to other handlers. + -----------------------------------------------------------------------------*/ #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - bool injectMouseUp(const OIS::MultiTouchEvent& evt) + bool injectMouseUp(const OIS::MultiTouchEvent& evt) #else - bool injectMouseUp(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + bool injectMouseUp(const OIS::MouseEvent& evt, OIS::MouseButtonID id) #endif - { + { #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) - // only process left button when stuff is visible - if (!mCursorLayer->isVisible() || id != OIS::MB_Left) return false; + // only process left button when stuff is visible + if (!mCursorLayer->isVisible() || id != OIS::MB_Left) return false; #else // only process touches when stuff is visible - if (!mCursorLayer->isVisible()) return false; + if (!mCursorLayer->isVisible()) return false; #endif - Ogre::Vector2 cursorPos(mCursor->getLeft(), mCursor->getTop()); - - if (mExpandedMenu) // only check top priority widget until it passes on - { - mExpandedMenu->_cursorReleased(cursorPos); - return true; - } - - if (mDialog) // only check top priority widget until it passes on - { - mDialog->_cursorReleased(cursorPos); - if (mOk) mOk->_cursorReleased(cursorPos); - else - { - mYes->_cursorReleased(cursorPos); - // very important to check if second button still exists, because first button could've closed the popup - if (mNo) mNo->_cursorReleased(cursorPos); - } - return true; - } - - if (!mTrayDrag) return false; // this click did not originate in a tray, so don't process - - Widget* w; - - for (unsigned int i = 0; i < 10; i++) - { - if (!mTrays[i]->isVisible()) continue; - - for (unsigned int j = 0; j < mWidgets[i].size(); j++) - { - w = mWidgets[i][j]; - if (!w->getOverlayElement()->isVisible()) continue; - w->_cursorReleased(cursorPos); // send event to widget - } - } - - mTrayDrag = false; // stop this drag - return true; // this click did originate in this tray, so don't pass it on - } - - /*----------------------------------------------------------------------------- - | Updates cursor position. Returns true if the event was - | consumed and should not be passed on to other handlers. - -----------------------------------------------------------------------------*/ + Ogre::Vector2 cursorPos(mCursor->getLeft(), mCursor->getTop()); + + if (mExpandedMenu) // only check top priority widget until it passes on + { + mExpandedMenu->_cursorReleased(cursorPos); + return true; + } + + if (mDialog) // only check top priority widget until it passes on + { + mDialog->_cursorReleased(cursorPos); + if (mOk) mOk->_cursorReleased(cursorPos); + else + { + mYes->_cursorReleased(cursorPos); + // very important to check if second button still exists, because first button could've closed the popup + if (mNo) mNo->_cursorReleased(cursorPos); + } + return true; + } + + if (!mTrayDrag) return false; // this click did not originate in a tray, so don't process + + Widget* w; + + for (unsigned int i = 0; i < 10; i++) + { + if (!mTrays[i]->isVisible()) continue; + + for (unsigned int j = 0; j < mWidgets[i].size(); j++) + { + w = mWidgets[i][j]; + if (!w->getOverlayElement()->isVisible()) continue; + w->_cursorReleased(cursorPos); // send event to widget + } + } + + mTrayDrag = false; // stop this drag + return true; // this click did originate in this tray, so don't pass it on + } + + /*----------------------------------------------------------------------------- + | Updates cursor position. Returns true if the event was + | consumed and should not be passed on to other handlers. + -----------------------------------------------------------------------------*/ #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - bool injectMouseMove(const OIS::MultiTouchEvent& evt) + bool injectMouseMove(const OIS::MultiTouchEvent& evt) #else - bool injectMouseMove(const OIS::MouseEvent& evt) + bool injectMouseMove(const OIS::MouseEvent& evt) #endif - { - if (!mCursorLayer->isVisible()) return false; // don't process if cursor layer is invisible + { + if (!mCursorLayer->isVisible()) return false; // don't process if cursor layer is invisible Ogre::Vector2 cursorPos(evt.state.X.abs, evt.state.Y.abs); - mCursor->setPosition(cursorPos.x, cursorPos.y); - - if (mExpandedMenu) // only check top priority widget until it passes on - { - mExpandedMenu->_cursorMoved(cursorPos); - return true; - } - - if (mDialog) // only check top priority widget until it passes on - { - mDialog->_cursorMoved(cursorPos); - if (mOk) mOk->_cursorMoved(cursorPos); - else - { - mYes->_cursorMoved(cursorPos); - mNo->_cursorMoved(cursorPos); - } - return true; - } - - Widget* w; - - for (unsigned int i = 0; i < 10; i++) - { - if (!mTrays[i]->isVisible()) continue; - - for (unsigned int j = 0; j < mWidgets[i].size(); j++) - { - w = mWidgets[i][j]; - if (!w->getOverlayElement()->isVisible()) continue; - w->_cursorMoved(cursorPos); // send event to widget - } - } - - if (mTrayDrag) return true; // don't pass this event on if we're in the middle of a drag - return false; - } + mCursor->setPosition(cursorPos.x, cursorPos.y); + + if (mExpandedMenu) // only check top priority widget until it passes on + { + mExpandedMenu->_cursorMoved(cursorPos); + return true; + } + + if (mDialog) // only check top priority widget until it passes on + { + mDialog->_cursorMoved(cursorPos); + if (mOk) mOk->_cursorMoved(cursorPos); + else + { + mYes->_cursorMoved(cursorPos); + mNo->_cursorMoved(cursorPos); + } + return true; + } + + Widget* w; + + for (unsigned int i = 0; i < 10; i++) + { + if (!mTrays[i]->isVisible()) continue; + + for (unsigned int j = 0; j < mWidgets[i].size(); j++) + { + w = mWidgets[i][j]; + if (!w->getOverlayElement()->isVisible()) continue; + w->_cursorMoved(cursorPos); // send event to widget + } + } + + if (mTrayDrag) return true; // don't pass this event on if we're in the middle of a drag + return false; + } protected: - /*----------------------------------------------------------------------------- - | Internal method to prioritise / deprioritise expanded menus. - -----------------------------------------------------------------------------*/ - void setExpandedMenu(SelectMenu* m) - { - if (!mExpandedMenu && m) - { - Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)m->getOverlayElement(); - Ogre::OverlayContainer* eb = (Ogre::OverlayContainer*)c->getChild(m->getName() + "/MenuExpandedBox"); - eb->_update(); - eb->setPosition - ((unsigned int)(eb->_getDerivedLeft() * Ogre::OverlayManager::getSingleton().getViewportWidth()), - (unsigned int)(eb->_getDerivedTop() * Ogre::OverlayManager::getSingleton().getViewportHeight())); - c->removeChild(eb->getName()); - mPriorityLayer->add2D(eb); - } - else if(mExpandedMenu && !m) - { - Ogre::OverlayContainer* eb = mPriorityLayer->getChild(mExpandedMenu->getName() + "/MenuExpandedBox"); - mPriorityLayer->remove2D(eb); - ((Ogre::OverlayContainer*)mExpandedMenu->getOverlayElement())->addChild(eb); - } - - mExpandedMenu = m; - } - - Ogre::String mName; // name of this tray system - Ogre::RenderWindow* mWindow; // render window - InputContext mInputContext; - Ogre::Overlay* mBackdropLayer; // backdrop layer - Ogre::Overlay* mTraysLayer; // widget layer - Ogre::Overlay* mPriorityLayer; // top priority layer - Ogre::Overlay* mCursorLayer; // cursor layer - Ogre::OverlayContainer* mBackdrop; // backdrop - Ogre::OverlayContainer* mTrays[10]; // widget trays - WidgetList mWidgets[10]; // widgets - WidgetList mWidgetDeathRow; // widget queue for deletion - Ogre::OverlayContainer* mCursor; // cursor - SdkTrayListener* mListener; // tray listener - Ogre::Real mWidgetPadding; // widget padding - Ogre::Real mWidgetSpacing; // widget spacing - Ogre::Real mTrayPadding; // tray padding - bool mTrayDrag; // a mouse press was initiated on a tray - SelectMenu* mExpandedMenu; // top priority expanded menu widget - TextBox* mDialog; // top priority dialog widget - Ogre::OverlayContainer* mDialogShade; // top priority dialog shade - Button* mOk; // top priority OK button - Button* mYes; // top priority Yes button - Button* mNo; // top priority No button - bool mCursorWasVisible; // cursor state before showing dialog - Label* mFpsLabel; // FPS label - ParamsPanel* mStatsPanel; // frame stats panel - DecorWidget* mLogo; // logo - ProgressBar* mLoadBar; // loading bar - Ogre::Real mGroupInitProportion; // proportion of load job assigned to initialising one resource group - Ogre::Real mGroupLoadProportion; // proportion of load job assigned to loading one resource group - Ogre::Real mLoadInc; // loading increment - Ogre::GuiHorizontalAlignment mTrayWidgetAlign[10]; // tray widget alignments + /*----------------------------------------------------------------------------- + | Internal method to prioritise / deprioritise expanded menus. + -----------------------------------------------------------------------------*/ + void setExpandedMenu(SelectMenu* m) + { + if (!mExpandedMenu && m) + { + Ogre::OverlayContainer* c = (Ogre::OverlayContainer*)m->getOverlayElement(); + Ogre::OverlayContainer* eb = (Ogre::OverlayContainer*)c->getChild(m->getName() + "/MenuExpandedBox"); + eb->_update(); + eb->setPosition + ((unsigned int)(eb->_getDerivedLeft() * Ogre::OverlayManager::getSingleton().getViewportWidth()), + (unsigned int)(eb->_getDerivedTop() * Ogre::OverlayManager::getSingleton().getViewportHeight())); + c->removeChild(eb->getName()); + mPriorityLayer->add2D(eb); + } + else if(mExpandedMenu && !m) + { + Ogre::OverlayContainer* eb = mPriorityLayer->getChild(mExpandedMenu->getName() + "/MenuExpandedBox"); + mPriorityLayer->remove2D(eb); + ((Ogre::OverlayContainer*)mExpandedMenu->getOverlayElement())->addChild(eb); + } + + mExpandedMenu = m; + } + + Ogre::String mName; // name of this tray system + Ogre::RenderWindow* mWindow; // render window + InputContext mInputContext; + Ogre::Overlay* mBackdropLayer; // backdrop layer + Ogre::Overlay* mTraysLayer; // widget layer + Ogre::Overlay* mPriorityLayer; // top priority layer + Ogre::Overlay* mCursorLayer; // cursor layer + Ogre::OverlayContainer* mBackdrop; // backdrop + Ogre::OverlayContainer* mTrays[10]; // widget trays + WidgetList mWidgets[10]; // widgets + WidgetList mWidgetDeathRow; // widget queue for deletion + Ogre::OverlayContainer* mCursor; // cursor + SdkTrayListener* mListener; // tray listener + Ogre::Real mWidgetPadding; // widget padding + Ogre::Real mWidgetSpacing; // widget spacing + Ogre::Real mTrayPadding; // tray padding + bool mTrayDrag; // a mouse press was initiated on a tray + SelectMenu* mExpandedMenu; // top priority expanded menu widget + TextBox* mDialog; // top priority dialog widget + Ogre::OverlayContainer* mDialogShade; // top priority dialog shade + Button* mOk; // top priority OK button + Button* mYes; // top priority Yes button + Button* mNo; // top priority No button + bool mCursorWasVisible; // cursor state before showing dialog + Label* mFpsLabel; // FPS label + ParamsPanel* mStatsPanel; // frame stats panel + DecorWidget* mLogo; // logo + ProgressBar* mLoadBar; // loading bar + Ogre::Real mGroupInitProportion; // proportion of load job assigned to initialising one resource group + Ogre::Real mGroupLoadProportion; // proportion of load job assigned to loading one resource group + Ogre::Real mLoadInc; // loading increment + Ogre::GuiHorizontalAlignment mTrayWidgetAlign[10]; // tray widget alignments Ogre::Timer* mTimer; // Root::getSingleton().getTimer() unsigned long mLastStatUpdateTime; // The last time the stat text were updated diff --git a/Samples/Common/src/Cocoa/OgreController.h b/Samples/Common/src/Cocoa/OgreController.h index 303ee11adb6..f8874de79f7 100644 --- a/Samples/Common/src/Cocoa/OgreController.h +++ b/Samples/Common/src/Cocoa/OgreController.h @@ -5,8 +5,8 @@ @interface OgreController : NSObject { - IBOutlet OgreView *ogreView; - NSColor *diffuseLight; - NSColor *specularLight; + IBOutlet OgreView *ogreView; + NSColor *diffuseLight; + NSColor *specularLight; } @end diff --git a/Samples/Compositor/include/CompositorDemo_FrameListener.h b/Samples/Compositor/include/CompositorDemo_FrameListener.h index 0c38320f5ee..efe067e1409 100644 --- a/Samples/Compositor/include/CompositorDemo_FrameListener.h +++ b/Samples/Compositor/include/CompositorDemo_FrameListener.h @@ -34,7 +34,7 @@ same license as the rest of the engine. protected: - Ogre::String mDebugText; + Ogre::String mDebugText; CompositorDemo* mMain; Ogre::Vector3 mTranslateVector; @@ -67,13 +67,13 @@ same license as the rest of the engine. bool mMoveBck; bool mMoveLeft; bool mMoveRight; - Ogre::SceneNode* mSpinny; + Ogre::SceneNode* mSpinny; ItemSelectorViewManager* mCompositorSelectorViewManager; - OIS::Mouse *mMouse; - OIS::Keyboard *mKeyboard; - OIS::InputManager* mInputManager; + OIS::Mouse *mMouse; + OIS::Keyboard *mKeyboard; + OIS::InputManager* mInputManager; CEGUI::Renderer* mGuiRenderer; CEGUI::Window* mGuiAvg; @@ -83,28 +83,28 @@ same license as the rest of the engine. CEGUI::Window* mGuiTris; CEGUI::Window* mGuiDbg; CEGUI::Window* mRoot; - CEGUI::Listbox* mDebugRTTListbox; - CEGUI::Window* mDebugRTTStaticImage; - typedef Ogre::vector::type ImageSetList; - ImageSetList mDebugRTTImageSets; + CEGUI::Listbox* mDebugRTTListbox; + CEGUI::Window* mDebugRTTStaticImage; + typedef Ogre::vector::type ImageSetList; + ImageSetList mDebugRTTImageSets; CEGUI::MouseButton convertOISButtonToCegui(int ois_button_id); void CheckMovementKeys( CEGUI::Key::Scan keycode, bool state ); void updateStats(void); void registerCompositors(void); - void initDebugRTTWindow(void); - void updateDebugRTTWindow(void); + void initDebugRTTWindow(void); + void updateDebugRTTWindow(void); public: CompositorDemo_FrameListener(CompositorDemo* main); virtual ~CompositorDemo_FrameListener(); - void setSpinningNode(Ogre::SceneNode* node) { mSpinny = node; } + void setSpinningNode(Ogre::SceneNode* node) { mSpinny = node; } private: void connectEventHandlers(void); - virtual bool mouseMoved(const OIS::MouseEvent &e); - virtual bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id); + virtual bool mouseMoved(const OIS::MouseEvent &e); + virtual bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id); virtual bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id); virtual bool keyPressed(const OIS::KeyEvent &e); @@ -118,7 +118,7 @@ same license as the rest of the engine. bool handleMouseWheelEvent(const CEGUI::EventArgs& e); bool handleKeyDownEvent(const CEGUI::EventArgs& e); bool handleKeyUpEvent(const CEGUI::EventArgs& e); - bool handleRttSelection(const CEGUI::EventArgs& e); + bool handleRttSelection(const CEGUI::EventArgs& e); void itemStateChanged(const size_t index, const bool state); }; diff --git a/Samples/Compositor/include/ItemSelectorViewManager.h b/Samples/Compositor/include/ItemSelectorViewManager.h index f23c07f1e6f..c8bbc9660be 100644 --- a/Samples/Compositor/include/ItemSelectorViewManager.h +++ b/Samples/Compositor/include/ItemSelectorViewManager.h @@ -75,7 +75,7 @@ same license as the rest of the engine. ItemSelector() : CheckBoxWidget(0) {} }; - typedef Ogre::vector::type ItemSelectorContainer; + typedef Ogre::vector::type ItemSelectorContainer; typedef ItemSelectorContainer::iterator ItemSelectorIterator; float mVerticalScrollPosition; diff --git a/Samples/Compositor/src/Compositor.cpp b/Samples/Compositor/src/Compositor.cpp index 8055cfb29a5..4c107d955ae 100644 --- a/Samples/Compositor/src/Compositor.cpp +++ b/Samples/Compositor/src/Compositor.cpp @@ -26,17 +26,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Compositor; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Compositor; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Compositor/src/CompositorDemo_FrameListener.cpp b/Samples/Compositor/src/CompositorDemo_FrameListener.cpp index 183f36c0a9f..e73535c7291 100644 --- a/Samples/Compositor/src/CompositorDemo_FrameListener.cpp +++ b/Samples/Compositor/src/CompositorDemo_FrameListener.cpp @@ -22,17 +22,17 @@ same license as the rest of the engine. inline Ogre::String operator +(const Ogre::String& l,const CEGUI::String& o) { - return l+o.c_str(); + return l+o.c_str(); } /* inline CEGUI::String operator +(const CEGUI::String& l,const Ogre::String& o) { - return l+o.c_str(); + return l+o.c_str(); } */ /************************************************************************* - CompositorDemo_FrameListener methods that handle all input for this Compositor demo. + CompositorDemo_FrameListener methods that handle all input for this Compositor demo. *************************************************************************/ CompositorDemo_FrameListener::CompositorDemo_FrameListener(CompositorDemo* main) @@ -66,41 +66,41 @@ inline CEGUI::String operator +(const CEGUI::String& l,const Ogre::String& o) , mMoveBck(false) , mMoveLeft(false) , mMoveRight(false) - , mSpinny(0) + , mSpinny(0) , mCompositorSelectorViewManager(0) - , mMouse(0) - , mKeyboard(0) + , mMouse(0) + , mKeyboard(0) { Ogre::Root::getSingleton().addFrameListener(this); // using buffered input - OIS::ParamList pl; - size_t windowHnd = 0; - std::ostringstream windowHndStr; + OIS::ParamList pl; + size_t windowHnd = 0; + std::ostringstream windowHndStr; - mMain->getRenderWindow()->getCustomAttribute("WINDOW", &windowHnd); - windowHndStr << windowHnd; - pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); + mMain->getRenderWindow()->getCustomAttribute("WINDOW", &windowHnd); + windowHndStr << windowHnd; + pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); - mInputManager = OIS::InputManager::createInputSystem( pl ); + mInputManager = OIS::InputManager::createInputSystem( pl ); - //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse) - mKeyboard = static_cast(mInputManager->createInputObject( OIS::OISKeyboard, true )); - mMouse = static_cast(mInputManager->createInputObject( OIS::OISMouse, true )); + //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse) + mKeyboard = static_cast(mInputManager->createInputObject( OIS::OISKeyboard, true )); + mMouse = static_cast(mInputManager->createInputObject( OIS::OISMouse, true )); - unsigned int width, height, depth; - int left, top; - mMain->getRenderWindow()->getMetrics(width, height, depth, left, top); + unsigned int width, height, depth; + int left, top; + mMain->getRenderWindow()->getMetrics(width, height, depth, left, top); - //Set Mouse Region.. if window resizes, we should alter this to reflect as well - const OIS::MouseState &ms = mMouse->getMouseState(); - ms.width = width; - ms.height = height; + //Set Mouse Region.. if window resizes, we should alter this to reflect as well + const OIS::MouseState &ms = mMouse->getMouseState(); + ms.width = width; + ms.height = height; - mMouse->setEventCallback(this); - mKeyboard->setEventCallback(this); + mMouse->setEventCallback(this); + mKeyboard->setEventCallback(this); mGuiRenderer = CEGUI::System::getSingleton().getRenderer(); @@ -110,22 +110,22 @@ inline CEGUI::String operator +(const CEGUI::String& l,const Ogre::String& o) mGuiWorst = CEGUI::WindowManager::getSingleton().getWindow("OPWorstFPS"); mGuiTris = CEGUI::WindowManager::getSingleton().getWindow("OPTriCount"); mGuiDbg = CEGUI::WindowManager::getSingleton().getWindow("OPDebugMsg"); - mRoot = CEGUI::WindowManager::getSingleton().getWindow("root"); + mRoot = CEGUI::WindowManager::getSingleton().getWindow("root"); registerCompositors(); - initDebugRTTWindow(); + initDebugRTTWindow(); connectEventHandlers(); } //-------------------------------------------------------------------------- CompositorDemo_FrameListener::~CompositorDemo_FrameListener() { - if(mInputManager) - { - mInputManager->destroyInputObject(mKeyboard); - mInputManager->destroyInputObject(mMouse); - OIS::InputManager::destroyInputSystem(mInputManager); - mInputManager = 0; - } + if(mInputManager) + { + mInputManager->destroyInputObject(mKeyboard); + mInputManager->destroyInputObject(mMouse); + OIS::InputManager::destroyInputSystem(mInputManager); + mInputManager = 0; + } delete mCompositorSelectorViewManager; } @@ -147,11 +147,11 @@ inline CEGUI::String operator +(const CEGUI::String& l,const Ogre::String& o) //-------------------------------------------------------------------------- bool CompositorDemo_FrameListener::frameRenderingQueued(const Ogre::FrameEvent& evt) { - mMouse->capture(); - mKeyboard->capture(); + mMouse->capture(); + mKeyboard->capture(); - if( mMain->getRenderWindow()->isClosed() ) - return false; + if( mMain->getRenderWindow()->isClosed() ) + return false; if (mQuit) return false; @@ -187,8 +187,8 @@ inline CEGUI::String operator +(const CEGUI::String& l,const Ogre::String& o) Ogre::StringConverter::toString(++mNumScreenShots) + ".png"); } - if (mSpinny) - mSpinny->yaw(Ogre::Degree(10 * evt.timeSinceLastFrame)); + if (mSpinny) + mSpinny->yaw(Ogre::Degree(10 * evt.timeSinceLastFrame)); return true; } @@ -198,71 +198,71 @@ inline CEGUI::String operator +(const CEGUI::String& l,const Ogre::String& o) bool CompositorDemo_FrameListener::mouseMoved (const OIS::MouseEvent &e) { CEGUI::System::getSingleton().injectMouseMove( e.state.X.rel, e.state.Y.rel ); - CEGUI::System::getSingleton().injectMouseWheelChange(e.state.Z.rel); - return true; + CEGUI::System::getSingleton().injectMouseWheelChange(e.state.Z.rel); + return true; } //-------------------------------------------------------------------------- - bool CompositorDemo_FrameListener::keyPressed (const OIS::KeyEvent &e) + bool CompositorDemo_FrameListener::keyPressed (const OIS::KeyEvent &e) { // give 'quitting' priority - if (e.key == OIS::KC_ESCAPE) + if (e.key == OIS::KC_ESCAPE) { mQuit = true; return false; } - if (e.key == OIS::KC_V) - mMain->getRenderWindow()->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0,1,0)); + if (e.key == OIS::KC_V) + mMain->getRenderWindow()->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0,1,0)); if (e.key == OIS::KC_SYSRQ ) { - Ogre::StringStream ss; + Ogre::StringStream ss; ss << "screenshot_" << ++mNumScreenShots << ".png"; mMain->getRenderWindow()->writeContentsToFile(ss.str()); mDebugText = "Saved: " + ss.str(); - //mTimeUntilNextToggle = 0.5; + //mTimeUntilNextToggle = 0.5; } // do event injection CEGUI::System& cegui = CEGUI::System::getSingleton(); cegui.injectKeyDown(e.key); - cegui.injectChar(e.text); - return true; + cegui.injectChar(e.text); + return true; } //-------------------------------------------------------------------------- bool CompositorDemo_FrameListener::keyReleased (const OIS::KeyEvent &e) { CEGUI::System::getSingleton().injectKeyUp(e.key); - return true; + return true; } //-------------------------------------------------------------------------- - bool CompositorDemo_FrameListener::mousePressed (const OIS::MouseEvent &e, OIS::MouseButtonID id) + bool CompositorDemo_FrameListener::mousePressed (const OIS::MouseEvent &e, OIS::MouseButtonID id) { CEGUI::System::getSingleton().injectMouseButtonDown(convertOISButtonToCegui(id)); - return true; - } + return true; + } //-------------------------------------------------------------------------- - bool CompositorDemo_FrameListener::mouseReleased (const OIS::MouseEvent &e, OIS::MouseButtonID id) + bool CompositorDemo_FrameListener::mouseReleased (const OIS::MouseEvent &e, OIS::MouseButtonID id) { CEGUI::System::getSingleton().injectMouseButtonUp(convertOISButtonToCegui(id)); - return true; + return true; } //-------------------------------------------------------------------------- CEGUI::MouseButton CompositorDemo_FrameListener::convertOISButtonToCegui(int ois_button_id) { switch (ois_button_id) - { - case 0: return CEGUI::LeftButton; - case 1: return CEGUI::RightButton; - case 2: return CEGUI::MiddleButton; - case 3: return CEGUI::X1Button; - default: return CEGUI::LeftButton; - } + { + case 0: return CEGUI::LeftButton; + case 1: return CEGUI::RightButton; + case 2: return CEGUI::MiddleButton; + case 3: return CEGUI::X1Button; + default: return CEGUI::LeftButton; + } } //-------------------------------------------------------------------------- @@ -457,7 +457,7 @@ inline CEGUI::String operator +(const CEGUI::String& l,const Ogre::String& o) // get the item text and tell compositor manager to set enable state Ogre::CompositorManager::getSingleton().setCompositorEnabled(mMain->getRenderWindow()->getViewport(0), mCompositorSelectorViewManager->getItemSelectorText(index), state); - updateDebugRTTWindow(); + updateDebugRTTWindow(); } //----------------------------------------------------------------------------------- void CompositorDemo_FrameListener::registerCompositors(void) @@ -479,118 +479,118 @@ inline CEGUI::String operator +(const CEGUI::String& l,const Ogre::String& o) // Don't add base Ogre/Scene compositor to view if (compositorName == "Ogre/Scene") continue; - // Don't add the deferred shading compositors, thats a different demo. - if (Ogre::StringUtil::startsWith(compositorName, "DeferredShading", false)) - continue; + // Don't add the deferred shading compositors, thats a different demo. + if (Ogre::StringUtil::startsWith(compositorName, "DeferredShading", false)) + continue; mCompositorSelectorViewManager->addItemSelector(compositorName); - int addPosition = -1; - if (compositorName == "HDR") - { - // HDR must be first in the chain - addPosition = 0; - } - try - { - Ogre::CompositorInstance *instance = Ogre::CompositorManager::getSingleton().addCompositor(vp, compositorName, addPosition); - Ogre::CompositorManager::getSingleton().setCompositorEnabled(vp, compositorName, false); - } catch (...) { - } + int addPosition = -1; + if (compositorName == "HDR") + { + // HDR must be first in the chain + addPosition = 0; + } + try + { + Ogre::CompositorInstance *instance = Ogre::CompositorManager::getSingleton().addCompositor(vp, compositorName, addPosition); + Ogre::CompositorManager::getSingleton().setCompositorEnabled(vp, compositorName, false); + } catch (...) { + } } } - //--------------------------------------------------------------------- - void CompositorDemo_FrameListener::initDebugRTTWindow(void) - { - mDebugRTTStaticImage = CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"DebugRTTImage"); - mDebugRTTListbox = static_cast( - CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"DebugRTTListbox")); - mDebugRTTListbox->subscribeEvent(CEGUI::Listbox::EventSelectionChanged, - CEGUI::Event::Subscriber(&CompositorDemo_FrameListener::handleRttSelection, this)); - } - //--------------------------------------------------------------------- - bool CompositorDemo_FrameListener::handleRttSelection(const CEGUI::EventArgs& e) - { - if (mDebugRTTListbox->getSelectedCount() > 0) - { - // image set is in user data - CEGUI::Imageset* imgSet = (CEGUI::Imageset*)mDebugRTTListbox->getFirstSelectedItem()->getUserData(); - - mDebugRTTStaticImage->setProperty("Image", + //--------------------------------------------------------------------- + void CompositorDemo_FrameListener::initDebugRTTWindow(void) + { + mDebugRTTStaticImage = CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"DebugRTTImage"); + mDebugRTTListbox = static_cast( + CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"DebugRTTListbox")); + mDebugRTTListbox->subscribeEvent(CEGUI::Listbox::EventSelectionChanged, + CEGUI::Event::Subscriber(&CompositorDemo_FrameListener::handleRttSelection, this)); + } + //--------------------------------------------------------------------- + bool CompositorDemo_FrameListener::handleRttSelection(const CEGUI::EventArgs& e) + { + if (mDebugRTTListbox->getSelectedCount() > 0) + { + // image set is in user data + CEGUI::Imageset* imgSet = (CEGUI::Imageset*)mDebugRTTListbox->getFirstSelectedItem()->getUserData(); + + mDebugRTTStaticImage->setProperty("Image", CEGUI::PropertyHelper::imageToString(&imgSet->getImage("RttImage"))); - } - else - { - mDebugRTTStaticImage->setProperty("Image", ""); - - } - return true; - } - //--------------------------------------------------------------------- - void CompositorDemo_FrameListener::updateDebugRTTWindow(void) - { - // Clear listbox - mDebugRTTListbox->resetList(); - // Clear imagesets - mDebugRTTStaticImage->setProperty("Image", ""); - for (ImageSetList::iterator isIt = mDebugRTTImageSets.begin(); - isIt != mDebugRTTImageSets.end(); ++isIt) - { - CEGUI::ImagesetManager::getSingleton().destroyImageset(*isIt); - } - mDebugRTTImageSets.clear(); - Ogre::set::type uniqueTextureNames; - // Add an entry for each render texture for all active compositors - Ogre::Viewport* vp = mMain->getRenderWindow()->getViewport(0); - Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(vp); - Ogre::CompositorChain::InstanceIterator it = chain->getCompositors(); - while (it.hasMoreElements()) - { - Ogre::CompositorInstance* inst = it.getNext(); - if (inst->getEnabled()) - { - Ogre::CompositionTechnique::TextureDefinitionIterator texIt = - inst->getTechnique()->getTextureDefinitionIterator(); - while (texIt.hasMoreElements()) - { - Ogre::CompositionTechnique::TextureDefinition* texDef = texIt.getNext(); - - // Get instance name of texture (NB only index 0 if MRTs for now) - const Ogre::String& instName = inst->getTextureInstanceName(texDef->name, 0); - // Create CEGUI texture from name of OGRE texture - CEGUI::Texture* tex = mMain->getGuiRenderer()->createTexture(instName.c_str()); - // Create imageset - // Note that if we use shared textures in compositor, the same texture name - // will occur more than once, so we have to cater for this - if (uniqueTextureNames.find(instName) == uniqueTextureNames.end()) - { - CEGUI::Imageset* imgSet = - CEGUI::ImagesetManager::getSingleton().createImageset( - instName.c_str(), tex); - mDebugRTTImageSets.push_back(imgSet); - imgSet->defineImage((CEGUI::utf8*)"RttImage", - CEGUI::Point(0.0f, 0.0f), - CEGUI::Size(tex->getWidth(), tex->getHeight()), - CEGUI::Point(0.0f,0.0f)); - - - CEGUI::ListboxTextItem *item = new CEGUI::ListboxTextItem(texDef->name.c_str(), 0, imgSet); - item->setSelectionBrushImage("TaharezLook", "ListboxSelectionBrush"); - item->setSelectionColours(CEGUI::colour(0,0,1)); - mDebugRTTListbox->addItem(item); - - uniqueTextureNames.insert(instName); - } - - } - - } - - } - - - - } + } + else + { + mDebugRTTStaticImage->setProperty("Image", ""); + + } + return true; + } + //--------------------------------------------------------------------- + void CompositorDemo_FrameListener::updateDebugRTTWindow(void) + { + // Clear listbox + mDebugRTTListbox->resetList(); + // Clear imagesets + mDebugRTTStaticImage->setProperty("Image", ""); + for (ImageSetList::iterator isIt = mDebugRTTImageSets.begin(); + isIt != mDebugRTTImageSets.end(); ++isIt) + { + CEGUI::ImagesetManager::getSingleton().destroyImageset(*isIt); + } + mDebugRTTImageSets.clear(); + Ogre::set::type uniqueTextureNames; + // Add an entry for each render texture for all active compositors + Ogre::Viewport* vp = mMain->getRenderWindow()->getViewport(0); + Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(vp); + Ogre::CompositorChain::InstanceIterator it = chain->getCompositors(); + while (it.hasMoreElements()) + { + Ogre::CompositorInstance* inst = it.getNext(); + if (inst->getEnabled()) + { + Ogre::CompositionTechnique::TextureDefinitionIterator texIt = + inst->getTechnique()->getTextureDefinitionIterator(); + while (texIt.hasMoreElements()) + { + Ogre::CompositionTechnique::TextureDefinition* texDef = texIt.getNext(); + + // Get instance name of texture (NB only index 0 if MRTs for now) + const Ogre::String& instName = inst->getTextureInstanceName(texDef->name, 0); + // Create CEGUI texture from name of OGRE texture + CEGUI::Texture* tex = mMain->getGuiRenderer()->createTexture(instName.c_str()); + // Create imageset + // Note that if we use shared textures in compositor, the same texture name + // will occur more than once, so we have to cater for this + if (uniqueTextureNames.find(instName) == uniqueTextureNames.end()) + { + CEGUI::Imageset* imgSet = + CEGUI::ImagesetManager::getSingleton().createImageset( + instName.c_str(), tex); + mDebugRTTImageSets.push_back(imgSet); + imgSet->defineImage((CEGUI::utf8*)"RttImage", + CEGUI::Point(0.0f, 0.0f), + CEGUI::Size(tex->getWidth(), tex->getHeight()), + CEGUI::Point(0.0f,0.0f)); + + + CEGUI::ListboxTextItem *item = new CEGUI::ListboxTextItem(texDef->name.c_str(), 0, imgSet); + item->setSelectionBrushImage("TaharezLook", "ListboxSelectionBrush"); + item->setSelectionColours(CEGUI::colour(0,0,1)); + mDebugRTTListbox->addItem(item); + + uniqueTextureNames.insert(instName); + } + + } + + } + + } + + + + } diff --git a/Samples/Compositor/src/HelperLogics.cpp b/Samples/Compositor/src/HelperLogics.cpp index 7bb122add45..43aab2ad9a1 100644 --- a/Samples/Compositor/src/HelperLogics.cpp +++ b/Samples/Compositor/src/HelperLogics.cpp @@ -34,67 +34,67 @@ class HeatVisionListener: public Ogre::CompositorInstance::Listener class HDRListener: public Ogre::CompositorInstance::Listener { protected: - int mVpWidth, mVpHeight; - int mBloomSize; - // Array params - have to pack in groups of 4 since this is how Cg generates them - // also prevents dependent texture read problems if ops don't require swizzle - float mBloomTexWeights[15][4]; - float mBloomTexOffsetsHorz[15][4]; - float mBloomTexOffsetsVert[15][4]; + int mVpWidth, mVpHeight; + int mBloomSize; + // Array params - have to pack in groups of 4 since this is how Cg generates them + // also prevents dependent texture read problems if ops don't require swizzle + float mBloomTexWeights[15][4]; + float mBloomTexOffsetsHorz[15][4]; + float mBloomTexOffsetsVert[15][4]; public: - HDRListener(); - virtual ~HDRListener(); - void notifyViewportSize(int width, int height); - void notifyCompositor(Ogre::CompositorInstance* instance); - virtual void notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat); - virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat); + HDRListener(); + virtual ~HDRListener(); + void notifyViewportSize(int width, int height); + void notifyCompositor(Ogre::CompositorInstance* instance); + virtual void notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat); + virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat); }; //--------------------------------------------------------------------------- class GaussianListener : public Ogre::CompositorInstance::Listener { protected: - int mVpWidth, mVpHeight; - // Array params - have to pack in groups of 4 since this is how Cg generates them - // also prevents dependent texture read problems if ops don't require swizzle - float mBloomTexWeights[15][4]; - float mBloomTexOffsetsHorz[15][4]; - float mBloomTexOffsetsVert[15][4]; + int mVpWidth, mVpHeight; + // Array params - have to pack in groups of 4 since this is how Cg generates them + // also prevents dependent texture read problems if ops don't require swizzle + float mBloomTexWeights[15][4]; + float mBloomTexOffsetsHorz[15][4]; + float mBloomTexOffsetsVert[15][4]; public: - GaussianListener(); - virtual ~GaussianListener(); - void notifyViewportSize(int width, int height); - virtual void notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat); - virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat); + GaussianListener(); + virtual ~GaussianListener(); + void notifyViewportSize(int width, int height); + virtual void notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat); + virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat); }; //--------------------------------------------------------------------------- Ogre::CompositorInstance::Listener* HDRLogic::createListener(Ogre::CompositorInstance* instance) { - HDRListener* listener = new HDRListener; - Ogre::Viewport* vp = instance->getChain()->getViewport(); - listener->notifyViewportSize(vp->getActualWidth(), vp->getActualHeight()); - listener->notifyCompositor(instance); - return listener; + HDRListener* listener = new HDRListener; + Ogre::Viewport* vp = instance->getChain()->getViewport(); + listener->notifyViewportSize(vp->getActualWidth(), vp->getActualHeight()); + listener->notifyCompositor(instance); + return listener; } //--------------------------------------------------------------------------- Ogre::CompositorInstance::Listener* HeatVisionLogic::createListener(Ogre::CompositorInstance* instance) { - return new HeatVisionListener; + return new HeatVisionListener; } //--------------------------------------------------------------------------- Ogre::CompositorInstance::Listener* GaussianBlurLogic::createListener(Ogre::CompositorInstance* instance) { - GaussianListener* listener = new GaussianListener; - Ogre::Viewport* vp = instance->getChain()->getViewport(); - listener->notifyViewportSize(vp->getActualWidth(), vp->getActualHeight()); - return listener; + GaussianListener* listener = new GaussianListener; + Ogre::Viewport* vp = instance->getChain()->getViewport(); + listener->notifyViewportSize(vp->getActualWidth(), vp->getActualHeight()); + return listener; } /************************************************************************* - HeatVisionListener Methods + HeatVisionListener Methods *************************************************************************/ //--------------------------------------------------------------------------- HeatVisionListener::HeatVisionListener() { - timer = new Ogre::Timer(); + timer = new Ogre::Timer(); start = end = curr = 0.0f; } //--------------------------------------------------------------------------- @@ -151,99 +151,99 @@ HDRListener::~HDRListener() //--------------------------------------------------------------------------- void HDRListener::notifyViewportSize(int width, int height) { - mVpWidth = width; - mVpHeight = height; + mVpWidth = width; + mVpHeight = height; } //--------------------------------------------------------------------------- void HDRListener::notifyCompositor(Ogre::CompositorInstance* instance) { - // Get some RTT dimensions for later calculations - Ogre::CompositionTechnique::TextureDefinitionIterator defIter = - instance->getTechnique()->getTextureDefinitionIterator(); - while (defIter.hasMoreElements()) - { - Ogre::CompositionTechnique::TextureDefinition* def = - defIter.getNext(); - if(def->name == "rt_bloom0") - { - mBloomSize = (int)def->width; // should be square - // Calculate gaussian texture offsets & weights - float deviation = 3.0f; - float texelSize = 1.0f / (float)mBloomSize; + // Get some RTT dimensions for later calculations + Ogre::CompositionTechnique::TextureDefinitionIterator defIter = + instance->getTechnique()->getTextureDefinitionIterator(); + while (defIter.hasMoreElements()) + { + Ogre::CompositionTechnique::TextureDefinition* def = + defIter.getNext(); + if(def->name == "rt_bloom0") + { + mBloomSize = (int)def->width; // should be square + // Calculate gaussian texture offsets & weights + float deviation = 3.0f; + float texelSize = 1.0f / (float)mBloomSize; - // central sample, no offset - mBloomTexOffsetsHorz[0][0] = 0.0f; - mBloomTexOffsetsHorz[0][1] = 0.0f; - mBloomTexOffsetsVert[0][0] = 0.0f; - mBloomTexOffsetsVert[0][1] = 0.0f; - mBloomTexWeights[0][0] = mBloomTexWeights[0][1] = - mBloomTexWeights[0][2] = Ogre::Math::gaussianDistribution(0, 0, deviation); - mBloomTexWeights[0][3] = 1.0f; + // central sample, no offset + mBloomTexOffsetsHorz[0][0] = 0.0f; + mBloomTexOffsetsHorz[0][1] = 0.0f; + mBloomTexOffsetsVert[0][0] = 0.0f; + mBloomTexOffsetsVert[0][1] = 0.0f; + mBloomTexWeights[0][0] = mBloomTexWeights[0][1] = + mBloomTexWeights[0][2] = Ogre::Math::gaussianDistribution(0, 0, deviation); + mBloomTexWeights[0][3] = 1.0f; - // 'pre' samples - for(int i = 1; i < 8; ++i) - { - mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = + // 'pre' samples + for(int i = 1; i < 8; ++i) + { + mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = mBloomTexWeights[i][2] = 1.25f * Ogre::Math::gaussianDistribution((Ogre::Real)i, 0, deviation); - mBloomTexWeights[i][3] = 1.0f; - mBloomTexOffsetsHorz[i][0] = i * texelSize; - mBloomTexOffsetsHorz[i][1] = 0.0f; - mBloomTexOffsetsVert[i][0] = 0.0f; - mBloomTexOffsetsVert[i][1] = i * texelSize; - } - // 'post' samples - for(int i = 8; i < 15; ++i) - { - mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = - mBloomTexWeights[i][2] = mBloomTexWeights[i - 7][0]; - mBloomTexWeights[i][3] = 1.0f; + mBloomTexWeights[i][3] = 1.0f; + mBloomTexOffsetsHorz[i][0] = i * texelSize; + mBloomTexOffsetsHorz[i][1] = 0.0f; + mBloomTexOffsetsVert[i][0] = 0.0f; + mBloomTexOffsetsVert[i][1] = i * texelSize; + } + // 'post' samples + for(int i = 8; i < 15; ++i) + { + mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = + mBloomTexWeights[i][2] = mBloomTexWeights[i - 7][0]; + mBloomTexWeights[i][3] = 1.0f; - mBloomTexOffsetsHorz[i][0] = -mBloomTexOffsetsHorz[i - 7][0]; - mBloomTexOffsetsHorz[i][1] = 0.0f; - mBloomTexOffsetsVert[i][0] = 0.0f; - mBloomTexOffsetsVert[i][1] = -mBloomTexOffsetsVert[i - 7][1]; - } + mBloomTexOffsetsHorz[i][0] = -mBloomTexOffsetsHorz[i - 7][0]; + mBloomTexOffsetsHorz[i][1] = 0.0f; + mBloomTexOffsetsVert[i][0] = 0.0f; + mBloomTexOffsetsVert[i][1] = -mBloomTexOffsetsVert[i - 7][1]; + } - } - } + } + } } //--------------------------------------------------------------------------- void HDRListener::notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) { - // Prepare the fragment params offsets - switch(pass_id) - { - //case 994: // rt_lum4 - case 993: // rt_lum3 - case 992: // rt_lum2 - case 991: // rt_lum1 - case 990: // rt_lum0 - break; - case 800: // rt_brightpass - break; - case 701: // rt_bloom1 - { - // horizontal bloom - mat->load(); - Ogre::GpuProgramParametersSharedPtr fparams = - mat->getBestTechnique()->getPass(0)->getFragmentProgramParameters(); - fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsHorz[0], 15); - fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); + // Prepare the fragment params offsets + switch(pass_id) + { + //case 994: // rt_lum4 + case 993: // rt_lum3 + case 992: // rt_lum2 + case 991: // rt_lum1 + case 990: // rt_lum0 + break; + case 800: // rt_brightpass + break; + case 701: // rt_bloom1 + { + // horizontal bloom + mat->load(); + Ogre::GpuProgramParametersSharedPtr fparams = + mat->getBestTechnique()->getPass(0)->getFragmentProgramParameters(); + fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsHorz[0], 15); + fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); - break; - } - case 700: // rt_bloom0 - { - // vertical bloom - mat->load(); - Ogre::GpuProgramParametersSharedPtr fparams = - mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); - fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsVert[0], 15); - fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); + break; + } + case 700: // rt_bloom0 + { + // vertical bloom + mat->load(); + Ogre::GpuProgramParametersSharedPtr fparams = + mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); + fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsVert[0], 15); + fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); - break; - } - } + break; + } + } } //--------------------------------------------------------------------------- void HDRListener::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) @@ -266,74 +266,74 @@ GaussianListener::~GaussianListener() //--------------------------------------------------------------------------- void GaussianListener::notifyViewportSize(int width, int height) { - mVpWidth = width; - mVpHeight = height; - // Calculate gaussian texture offsets & weights - float deviation = 3.0f; - float texelSize = 1.0f / (float)std::min(mVpWidth, mVpHeight); + mVpWidth = width; + mVpHeight = height; + // Calculate gaussian texture offsets & weights + float deviation = 3.0f; + float texelSize = 1.0f / (float)std::min(mVpWidth, mVpHeight); - // central sample, no offset - mBloomTexOffsetsHorz[0][0] = 0.0f; - mBloomTexOffsetsHorz[0][1] = 0.0f; - mBloomTexOffsetsVert[0][0] = 0.0f; - mBloomTexOffsetsVert[0][1] = 0.0f; - mBloomTexWeights[0][0] = mBloomTexWeights[0][1] = - mBloomTexWeights[0][2] = Ogre::Math::gaussianDistribution(0, 0, deviation); - mBloomTexWeights[0][3] = 1.0f; + // central sample, no offset + mBloomTexOffsetsHorz[0][0] = 0.0f; + mBloomTexOffsetsHorz[0][1] = 0.0f; + mBloomTexOffsetsVert[0][0] = 0.0f; + mBloomTexOffsetsVert[0][1] = 0.0f; + mBloomTexWeights[0][0] = mBloomTexWeights[0][1] = + mBloomTexWeights[0][2] = Ogre::Math::gaussianDistribution(0, 0, deviation); + mBloomTexWeights[0][3] = 1.0f; - // 'pre' samples - for(int i = 1; i < 8; ++i) - { - mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = - mBloomTexWeights[i][2] = Ogre::Math::gaussianDistribution((Ogre::Real)i, 0, deviation); - mBloomTexWeights[i][3] = 1.0f; - mBloomTexOffsetsHorz[i][0] = i * texelSize; - mBloomTexOffsetsHorz[i][1] = 0.0f; - mBloomTexOffsetsVert[i][0] = 0.0f; - mBloomTexOffsetsVert[i][1] = i * texelSize; - } - // 'post' samples - for(int i = 8; i < 15; ++i) - { - mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = - mBloomTexWeights[i][2] = mBloomTexWeights[i - 7][0]; - mBloomTexWeights[i][3] = 1.0f; + // 'pre' samples + for(int i = 1; i < 8; ++i) + { + mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = + mBloomTexWeights[i][2] = Ogre::Math::gaussianDistribution((Ogre::Real)i, 0, deviation); + mBloomTexWeights[i][3] = 1.0f; + mBloomTexOffsetsHorz[i][0] = i * texelSize; + mBloomTexOffsetsHorz[i][1] = 0.0f; + mBloomTexOffsetsVert[i][0] = 0.0f; + mBloomTexOffsetsVert[i][1] = i * texelSize; + } + // 'post' samples + for(int i = 8; i < 15; ++i) + { + mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = + mBloomTexWeights[i][2] = mBloomTexWeights[i - 7][0]; + mBloomTexWeights[i][3] = 1.0f; - mBloomTexOffsetsHorz[i][0] = -mBloomTexOffsetsHorz[i - 7][0]; - mBloomTexOffsetsHorz[i][1] = 0.0f; - mBloomTexOffsetsVert[i][0] = 0.0f; - mBloomTexOffsetsVert[i][1] = -mBloomTexOffsetsVert[i - 7][1]; - } + mBloomTexOffsetsHorz[i][0] = -mBloomTexOffsetsHorz[i - 7][0]; + mBloomTexOffsetsHorz[i][1] = 0.0f; + mBloomTexOffsetsVert[i][0] = 0.0f; + mBloomTexOffsetsVert[i][1] = -mBloomTexOffsetsVert[i - 7][1]; + } } //--------------------------------------------------------------------------- void GaussianListener::notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) { - // Prepare the fragment params offsets - switch(pass_id) - { - case 701: // blur horz - { - // horizontal bloom - mat->load(); - Ogre::GpuProgramParametersSharedPtr fparams = - mat->getBestTechnique()->getPass(0)->getFragmentProgramParameters(); - fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsHorz[0], 15); - fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); + // Prepare the fragment params offsets + switch(pass_id) + { + case 701: // blur horz + { + // horizontal bloom + mat->load(); + Ogre::GpuProgramParametersSharedPtr fparams = + mat->getBestTechnique()->getPass(0)->getFragmentProgramParameters(); + fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsHorz[0], 15); + fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); - break; - } - case 700: // blur vert - { - // vertical bloom - mat->load(); - Ogre::GpuProgramParametersSharedPtr fparams = - mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); - fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsVert[0], 15); - fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); + break; + } + case 700: // blur vert + { + // vertical bloom + mat->load(); + Ogre::GpuProgramParametersSharedPtr fparams = + mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); + fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsVert[0], 15); + fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); - break; - } - } + break; + } + } } //--------------------------------------------------------------------------- void GaussianListener::notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) diff --git a/Samples/CubeMapping/include/CubeMapping.h b/Samples/CubeMapping/include/CubeMapping.h index ecc84a05de5..d287cc42f6b 100644 --- a/Samples/CubeMapping/include/CubeMapping.h +++ b/Samples/CubeMapping/include/CubeMapping.h @@ -10,42 +10,42 @@ class _OgreSampleClassExport Sample_CubeMapping : public SdkSample, public Rende { public: - Sample_CubeMapping() - { - mInfo["Title"] = "Cube Mapping"; - mInfo["Description"] = "Demonstrates the cube mapping feature where a wrap-around environment is reflected " - "off of an object. Uses render-to-texture to create dynamic cubemaps."; - mInfo["Thumbnail"] = "thumb_cubemap.png"; - mInfo["Category"] = "Unsorted"; - } - - void testCapabilities(const RenderSystemCapabilities* caps) - { + Sample_CubeMapping() + { + mInfo["Title"] = "Cube Mapping"; + mInfo["Description"] = "Demonstrates the cube mapping feature where a wrap-around environment is reflected " + "off of an object. Uses render-to-texture to create dynamic cubemaps."; + mInfo["Thumbnail"] = "thumb_cubemap.png"; + mInfo["Category"] = "Unsorted"; + } + + void testCapabilities(const RenderSystemCapabilities* caps) + { if (!caps->hasCapability(RSC_CUBEMAPPING)) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support cube mapping, " - "so you cannot run this sample. Sorry!", "CubeMappingSample::testCapabilities"); + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support cube mapping, " + "so you cannot run this sample. Sorry!", "CubeMappingSample::testCapabilities"); } - } + } bool frameRenderingQueued(const FrameEvent& evt) { - mPivot->yaw(Radian(evt.timeSinceLastFrame)); // spin the fishy around the cube mapped one - mFishSwim->addTime(evt.timeSinceLastFrame * 3); // make the fishy swim - return SdkSample::frameRenderingQueued(evt); // don't forget the parent updates! + mPivot->yaw(Radian(evt.timeSinceLastFrame)); // spin the fishy around the cube mapped one + mFishSwim->addTime(evt.timeSinceLastFrame * 3); // make the fishy swim + return SdkSample::frameRenderingQueued(evt); // don't forget the parent updates! } void preRenderTargetUpdate(const RenderTargetEvent& evt) { mHead->setVisible(false); // hide the head - // point the camera in the right direction based on which face of the cubemap this is - mCubeCamera->setOrientation(Quaternion::IDENTITY); - if (evt.source == mTargets[0]) mCubeCamera->yaw(Degree(-90)); - else if (evt.source == mTargets[1]) mCubeCamera->yaw(Degree(90)); - else if (evt.source == mTargets[2]) mCubeCamera->pitch(Degree(90)); - else if (evt.source == mTargets[3]) mCubeCamera->pitch(Degree(-90)); - else if (evt.source == mTargets[5]) mCubeCamera->yaw(Degree(180)); + // point the camera in the right direction based on which face of the cubemap this is + mCubeCamera->setOrientation(Quaternion::IDENTITY); + if (evt.source == mTargets[0]) mCubeCamera->yaw(Degree(-90)); + else if (evt.source == mTargets[1]) mCubeCamera->yaw(Degree(90)); + else if (evt.source == mTargets[2]) mCubeCamera->pitch(Degree(90)); + else if (evt.source == mTargets[3]) mCubeCamera->pitch(Degree(-90)); + else if (evt.source == mTargets[5]) mCubeCamera->yaw(Degree(180)); } void postRenderTargetUpdate(const RenderTargetEvent& evt) @@ -55,81 +55,81 @@ class _OgreSampleClassExport Sample_CubeMapping : public SdkSample, public Rende protected: - void setupContent() - { - mSceneMgr->setSkyDome(true, "Examples/CloudySky"); + void setupContent() + { + mSceneMgr->setSkyDome(true, "Examples/CloudySky"); - // setup some basic lighting for our scene + // setup some basic lighting for our scene mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); mSceneMgr->createLight()->setPosition(20, 80, 50); - createCubeMap(); + createCubeMap(); - // create an ogre head, give it the dynamic cube map material, and place it at the origin - mHead = mSceneMgr->createEntity("CubeMappedHead", "ogrehead.mesh"); - mHead->setMaterialName("Examples/DynamicCubeMap"); - mSceneMgr->getRootSceneNode()->attachObject(mHead); + // create an ogre head, give it the dynamic cube map material, and place it at the origin + mHead = mSceneMgr->createEntity("CubeMappedHead", "ogrehead.mesh"); + mHead->setMaterialName("Examples/DynamicCubeMap"); + mSceneMgr->getRootSceneNode()->attachObject(mHead); - mPivot = mSceneMgr->getRootSceneNode()->createChildSceneNode(); // create a pivot node + mPivot = mSceneMgr->getRootSceneNode()->createChildSceneNode(); // create a pivot node - Entity* fish = mSceneMgr->createEntity("Fish", "fish.mesh"); - mFishSwim = fish->getAnimationState("swim"); - mFishSwim->setEnabled(true); + Entity* fish = mSceneMgr->createEntity("Fish", "fish.mesh"); + mFishSwim = fish->getAnimationState("swim"); + mFishSwim->setEnabled(true); - // create a child node at an offset and attach a regular ogre head and a nimbus to it - SceneNode* node = mPivot->createChildSceneNode(Vector3(-60, 10, 0)); - node->setScale(7, 7, 7); - node->yaw(Degree(90)); - node->attachObject(fish); + // create a child node at an offset and attach a regular ogre head and a nimbus to it + SceneNode* node = mPivot->createChildSceneNode(Vector3(-60, 10, 0)); + node->setScale(7, 7, 7); + node->yaw(Degree(90)); + node->attachObject(fish); - // create a floor mesh resource - MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Plane(Vector3::UNIT_Y, -30), 1000, 1000, 10, 10, true, 1, 8, 8, Vector3::UNIT_Z); + // create a floor mesh resource + MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Plane(Vector3::UNIT_Y, -30), 1000, 1000, 10, 10, true, 1, 8, 8, Vector3::UNIT_Z); - // create a floor entity, give it a material, and place it at the origin + // create a floor entity, give it a material, and place it at the origin Entity* floor = mSceneMgr->createEntity("Floor", "floor"); floor->setMaterialName("Examples/BumpyMetal"); mSceneMgr->getRootSceneNode()->attachObject(floor); - // set our camera to orbit around the head and show cursor - mCameraMan->setStyle(CS_ORBIT); - mTrayMgr->showCursor(); - } - - void createCubeMap() - { - // create the camera used to render to our cubemap - mCubeCamera = mSceneMgr->createCamera("CubeMapCamera"); - mCubeCamera->setFOVy(Degree(90)); - mCubeCamera->setAspectRatio(1); - mCubeCamera->setFixedYawAxis(false); - mCubeCamera->setNearClipDistance(5); - - // create our dynamic cube map texture - TexturePtr tex = TextureManager::getSingleton().createManual("dyncubemap", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_CUBE_MAP, 128, 128, 0, PF_R8G8B8, TU_RENDERTARGET); - - // assign our camera to all 6 render targets of the texture (1 for each direction) - for (unsigned int i = 0; i < 6; i++) - { - mTargets[i] = tex->getBuffer(i)->getRenderTarget(); - mTargets[i]->addViewport(mCubeCamera)->setOverlaysEnabled(false); - mTargets[i]->addListener(this); - } - } - - void cleanupContent() - { + // set our camera to orbit around the head and show cursor + mCameraMan->setStyle(CS_ORBIT); + mTrayMgr->showCursor(); + } + + void createCubeMap() + { + // create the camera used to render to our cubemap + mCubeCamera = mSceneMgr->createCamera("CubeMapCamera"); + mCubeCamera->setFOVy(Degree(90)); + mCubeCamera->setAspectRatio(1); + mCubeCamera->setFixedYawAxis(false); + mCubeCamera->setNearClipDistance(5); + + // create our dynamic cube map texture + TexturePtr tex = TextureManager::getSingleton().createManual("dyncubemap", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_CUBE_MAP, 128, 128, 0, PF_R8G8B8, TU_RENDERTARGET); + + // assign our camera to all 6 render targets of the texture (1 for each direction) + for (unsigned int i = 0; i < 6; i++) + { + mTargets[i] = tex->getBuffer(i)->getRenderTarget(); + mTargets[i]->addViewport(mCubeCamera)->setOverlaysEnabled(false); + mTargets[i]->addListener(this); + } + } + + void cleanupContent() + { mSceneMgr->destroyCamera(mCubeCamera); - MeshManager::getSingleton().remove("floor"); - TextureManager::getSingleton().remove("dyncubemap"); - } - - Entity* mHead; - Camera* mCubeCamera; - RenderTarget* mTargets[6]; - SceneNode* mPivot; - AnimationState* mFishSwim; + MeshManager::getSingleton().remove("floor"); + TextureManager::getSingleton().remove("dyncubemap"); + } + + Entity* mHead; + Camera* mCubeCamera; + RenderTarget* mTargets[6]; + SceneNode* mPivot; + AnimationState* mFishSwim; }; #endif diff --git a/Samples/CubeMapping/src/CubeMapping.cpp b/Samples/CubeMapping/src/CubeMapping.cpp index ad2a4a8cda8..cfb5f4ca7d1 100644 --- a/Samples/CubeMapping/src/CubeMapping.cpp +++ b/Samples/CubeMapping/src/CubeMapping.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_CubeMapping; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_CubeMapping; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/DeferredShading/include/AmbientLight.h b/Samples/DeferredShading/include/AmbientLight.h index 78dc28833a2..6c52b241d36 100644 --- a/Samples/DeferredShading/include/AmbientLight.h +++ b/Samples/DeferredShading/include/AmbientLight.h @@ -32,22 +32,22 @@ class AmbientLight : public Ogre::SimpleRenderable { public: - AmbientLight(); - ~AmbientLight(); + AmbientLight(); + ~AmbientLight(); - /** @copydoc MovableObject::getBoundingRadius */ - virtual Ogre::Real getBoundingRadius(void) const; - /** @copydoc Renderable::getSquaredViewDepth */ - virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera*) const; - /** @copydoc Renderable::getMaterial */ - virtual const Ogre::MaterialPtr& getMaterial(void) const; + /** @copydoc MovableObject::getBoundingRadius */ + virtual Ogre::Real getBoundingRadius(void) const; + /** @copydoc Renderable::getSquaredViewDepth */ + virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera*) const; + /** @copydoc Renderable::getMaterial */ + virtual const Ogre::MaterialPtr& getMaterial(void) const; - virtual void getWorldTransforms(Ogre::Matrix4* xform) const; + virtual void getWorldTransforms(Ogre::Matrix4* xform) const; - void updateFromCamera(Ogre::Camera* camera); + void updateFromCamera(Ogre::Camera* camera); protected: - Ogre::Real mRadius; - Ogre::MaterialPtr mMatPtr; + Ogre::Real mRadius; + Ogre::MaterialPtr mMatPtr; }; #endif diff --git a/Samples/DeferredShading/include/DLight.h b/Samples/DeferredShading/include/DLight.h index 2181d4b7f06..4f6b5c25a4f 100644 --- a/Samples/DeferredShading/include/DLight.h +++ b/Samples/DeferredShading/include/DLight.h @@ -19,75 +19,75 @@ same license as the rest of the engine. #include "MaterialGenerator.h" /** Deferred light geometry. Each instance matches a normal light. - Should not be created by the user. - XXX support other types of light other than point lights. + Should not be created by the user. + XXX support other types of light other than point lights. */ class DLight: public Ogre::SimpleRenderable { public: - DLight(MaterialGenerator *gen, Ogre::Light* parentLight); - ~DLight(); - - /** Update the information from the light that matches this one - */ - void updateFromParent(); - - /** Update the information that is related to the camera - */ - void updateFromCamera(Ogre::Camera* camera); - - /** Does this light cast shadows? - */ - virtual bool getCastChadows() const; - - /** @copydoc MovableObject::getBoundingRadius */ - virtual Ogre::Real getBoundingRadius(void) const; - /** @copydoc Renderable::getSquaredViewDepth */ - virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera*) const; - /** @copydoc Renderable::getMaterial */ - virtual const Ogre::MaterialPtr& getMaterial(void) const; - /** @copydoc Renderable::getBoundingRadius */ - virtual void getWorldTransforms(Ogre::Matrix4* xform) const; + DLight(MaterialGenerator *gen, Ogre::Light* parentLight); + ~DLight(); + + /** Update the information from the light that matches this one + */ + void updateFromParent(); + + /** Update the information that is related to the camera + */ + void updateFromCamera(Ogre::Camera* camera); + + /** Does this light cast shadows? + */ + virtual bool getCastChadows() const; + + /** @copydoc MovableObject::getBoundingRadius */ + virtual Ogre::Real getBoundingRadius(void) const; + /** @copydoc Renderable::getSquaredViewDepth */ + virtual Ogre::Real getSquaredViewDepth(const Ogre::Camera*) const; + /** @copydoc Renderable::getMaterial */ + virtual const Ogre::MaterialPtr& getMaterial(void) const; + /** @copydoc Renderable::getBoundingRadius */ + virtual void getWorldTransforms(Ogre::Matrix4* xform) const; protected: - /** Check if the camera is inside a light - */ - bool isCameraInsideLight(Ogre::Camera* camera); - - /** Create geometry for this light. - */ - void rebuildGeometry(float radius); - - /** Create a sphere geometry. - */ - void createSphere(float radius, int nRings, int nSegments); - - /** Create a rectangle. - */ - void createRectangle2D(); - - /** Create a cone. - */ - void createCone(float radius, float height, int nVerticesInBase); - - /** Set constant, linear, quadratic Attenuation terms - */ - void setAttenuation(float c, float b, float a); - - /** Set the specular colour - */ - void setSpecularColour(const Ogre::ColourValue &col); - - /// The light that this DLight renders - Ogre::Light* mParentLight; - /// Mode to ignore world orientation/position - bool bIgnoreWorld; - /// Bounding sphere radius - float mRadius; - /// Deferred shading system this minilight is part of - MaterialGenerator *mGenerator; - /// Material permutation - Ogre::uint32 mPermutation; + /** Check if the camera is inside a light + */ + bool isCameraInsideLight(Ogre::Camera* camera); + + /** Create geometry for this light. + */ + void rebuildGeometry(float radius); + + /** Create a sphere geometry. + */ + void createSphere(float radius, int nRings, int nSegments); + + /** Create a rectangle. + */ + void createRectangle2D(); + + /** Create a cone. + */ + void createCone(float radius, float height, int nVerticesInBase); + + /** Set constant, linear, quadratic Attenuation terms + */ + void setAttenuation(float c, float b, float a); + + /** Set the specular colour + */ + void setSpecularColour(const Ogre::ColourValue &col); + + /// The light that this DLight renders + Ogre::Light* mParentLight; + /// Mode to ignore world orientation/position + bool bIgnoreWorld; + /// Bounding sphere radius + float mRadius; + /// Deferred shading system this minilight is part of + MaterialGenerator *mGenerator; + /// Material permutation + Ogre::uint32 mPermutation; }; #endif diff --git a/Samples/DeferredShading/include/DeferredLightCP.h b/Samples/DeferredShading/include/DeferredLightCP.h index b092e6adeef..9e160898d95 100644 --- a/Samples/DeferredShading/include/DeferredLightCP.h +++ b/Samples/DeferredShading/include/DeferredLightCP.h @@ -28,34 +28,34 @@ same license as the rest of the engine. class DeferredLightRenderOperation : public Ogre::CompositorInstance::RenderSystemOperation { public: - DeferredLightRenderOperation(Ogre::CompositorInstance* instance, const Ogre::CompositionPass* pass); - - /** @copydoc CompositorInstance::RenderSystemOperation::execute */ - virtual void execute(Ogre::SceneManager *sm, Ogre::RenderSystem *rs); + DeferredLightRenderOperation(Ogre::CompositorInstance* instance, const Ogre::CompositionPass* pass); + + /** @copydoc CompositorInstance::RenderSystemOperation::execute */ + virtual void execute(Ogre::SceneManager *sm, Ogre::RenderSystem *rs); - virtual ~DeferredLightRenderOperation(); + virtual ~DeferredLightRenderOperation(); private: - /** Create a new deferred light - */ - DLight *createDLight(Ogre::Light* light); - - //The texture names of the GBuffer components - Ogre::String mTexName0; - Ogre::String mTexName1; + /** Create a new deferred light + */ + DLight *createDLight(Ogre::Light* light); + + //The texture names of the GBuffer components + Ogre::String mTexName0; + Ogre::String mTexName1; - //The material generator for the light geometry - MaterialGenerator* mLightMaterialGenerator; + //The material generator for the light geometry + MaterialGenerator* mLightMaterialGenerator; - //The map of deferred light geometries already constructed - typedef std::map LightsMap; - LightsMap mLights; + //The map of deferred light geometries already constructed + typedef std::map LightsMap; + LightsMap mLights; - //The ambient light used to render the scene - AmbientLight* mAmbientLight; + //The ambient light used to render the scene + AmbientLight* mAmbientLight; - //The viewport that we are rendering to - Ogre::Viewport* mViewport; + //The viewport that we are rendering to + Ogre::Viewport* mViewport; }; //The custom composition pass that is used for rendering the light geometry @@ -64,15 +64,15 @@ class DeferredLightCompositionPass : public Ogre::CustomCompositionPass { public: - /** @copydoc CustomCompositionPass::createOperation */ - virtual Ogre::CompositorInstance::RenderSystemOperation* createOperation( - Ogre::CompositorInstance* instance, const Ogre::CompositionPass* pass) - { - return OGRE_NEW DeferredLightRenderOperation(instance, pass); - } + /** @copydoc CustomCompositionPass::createOperation */ + virtual Ogre::CompositorInstance::RenderSystemOperation* createOperation( + Ogre::CompositorInstance* instance, const Ogre::CompositionPass* pass) + { + return OGRE_NEW DeferredLightRenderOperation(instance, pass); + } protected: - virtual ~DeferredLightCompositionPass() {} + virtual ~DeferredLightCompositionPass() {} }; #endif diff --git a/Samples/DeferredShading/include/DeferredShading.h b/Samples/DeferredShading/include/DeferredShading.h index ffab753b3a2..e5522270871 100755 --- a/Samples/DeferredShading/include/DeferredShading.h +++ b/Samples/DeferredShading/include/DeferredShading.h @@ -15,7 +15,7 @@ same license as the rest of the engine. /** Implementation of a Deferred Shading engine in OGRE, using Multiple Render Targets and CG high level language shaders. - // W.J. :wumpus: van der Laan 2005 / Noam Gat 2009 // + // W.J. :wumpus: van der Laan 2005 / Noam Gat 2009 // Deferred shading renders the scene to a 'fat' texture format, using a shader that outputs colour, normal, depth, and possible other attributes per fragment. Multi Render Target is required as we @@ -51,70 +51,70 @@ using namespace OgreBites; /** System to manage Deferred Shading for a camera/render target. * @note With the changes to the compositor framework, this class just - * selects which compositors to enable. + * selects which compositors to enable. */ class DeferredShadingSystem : public Ogre::RenderTargetListener { public: - DeferredShadingSystem(Ogre::Viewport *vp, Ogre::SceneManager *sm, Ogre::Camera *cam); - ~DeferredShadingSystem(); - - enum DSMode - { - DSM_SHOWLIT = 0, // The deferred shading mode - DSM_SHOWCOLOUR = 1, // Show diffuse (for debugging) - DSM_SHOWNORMALS = 2, // Show normals (for debugging) - DSM_SHOWDSP = 3, // Show depth and specular channel (for debugging) - DSM_COUNT = 4 - }; - - //The first render queue that does get rendered into the GBuffer - //place objects (like skies) that should be before gbuffer before this one. - static const Ogre::uint8 PRE_GBUFFER_RENDER_QUEUE; - - //The first render queue that does not get rendered into the GBuffer - //place transparent (or other non gbuffer) objects after this one - static const Ogre::uint8 POST_GBUFFER_RENDER_QUEUE; - - void initialize(); - - /** Set rendering mode (one of DSMode) - */ - void setMode(DSMode mode); - - DSMode getMode(void) const; - - /** Set screen space ambient occlusion mode - */ - void setSSAO(bool ssao); - - bool getSSAO() const; - - /** Activate or deactivate system - */ - void setActive(bool active); - + DeferredShadingSystem(Ogre::Viewport *vp, Ogre::SceneManager *sm, Ogre::Camera *cam); + ~DeferredShadingSystem(); + + enum DSMode + { + DSM_SHOWLIT = 0, // The deferred shading mode + DSM_SHOWCOLOUR = 1, // Show diffuse (for debugging) + DSM_SHOWNORMALS = 2, // Show normals (for debugging) + DSM_SHOWDSP = 3, // Show depth and specular channel (for debugging) + DSM_COUNT = 4 + }; + + //The first render queue that does get rendered into the GBuffer + //place objects (like skies) that should be before gbuffer before this one. + static const Ogre::uint8 PRE_GBUFFER_RENDER_QUEUE; + + //The first render queue that does not get rendered into the GBuffer + //place transparent (or other non gbuffer) objects after this one + static const Ogre::uint8 POST_GBUFFER_RENDER_QUEUE; + + void initialize(); + + /** Set rendering mode (one of DSMode) + */ + void setMode(DSMode mode); + + DSMode getMode(void) const; + + /** Set screen space ambient occlusion mode + */ + void setSSAO(bool ssao); + + bool getSSAO() const; + + /** Activate or deactivate system + */ + void setActive(bool active); + protected: - Ogre::Viewport *mViewport; - Ogre::SceneManager *mSceneMgr; - Ogre::Camera *mCamera; - - Ogre::CompositorInstance *mGBufferInstance; - // Filters - Ogre::CompositorInstance *mInstance[DSM_COUNT]; - Ogre::CompositorInstance* mSSAOInstance; - // Active/inactive - bool mActive; - DSMode mCurrentMode; - bool mSSAO; - - //Used to unregister compositor logics and free memory - typedef map::type CompositorLogicMap; - CompositorLogicMap mCompositorLogics; - - void createResources(); - - void logCurrentMode(void); + Ogre::Viewport *mViewport; + Ogre::SceneManager *mSceneMgr; + Ogre::Camera *mCamera; + + Ogre::CompositorInstance *mGBufferInstance; + // Filters + Ogre::CompositorInstance *mInstance[DSM_COUNT]; + Ogre::CompositorInstance* mSSAOInstance; + // Active/inactive + bool mActive; + DSMode mCurrentMode; + bool mSSAO; + + //Used to unregister compositor logics and free memory + typedef map::type CompositorLogicMap; + CompositorLogicMap mCompositorLogics; + + void createResources(); + + void logCurrentMode(void); }; const ColourValue SAMPLE_COLORS[] = diff --git a/Samples/DeferredShading/include/DeferredShadingDemo.h b/Samples/DeferredShading/include/DeferredShadingDemo.h index a99f3030342..8d1f5232107 100755 --- a/Samples/DeferredShading/include/DeferredShadingDemo.h +++ b/Samples/DeferredShading/include/DeferredShadingDemo.h @@ -15,7 +15,7 @@ same license as the rest of the engine. /** Implementation of a Deferred Shading engine in OGRE, using Multiple Render Targets and CG high level language shaders. - // W.J. :wumpus: van der Laan 2005 / Noam Gat 2009 // + // W.J. :wumpus: van der Laan 2005 / Noam Gat 2009 // Deferred shading renders the scene to a 'fat' texture format, using a shader that outputs colour, normal, depth, and possible other attributes per fragment. Multi Render Target is required as we @@ -53,86 +53,86 @@ using namespace OgreBites; class _OgreSampleClassExport Sample_DeferredShading : public SdkSample, public RenderTargetListener { protected: - DeferredShadingSystem *mSystem; - SelectMenu* mDisplayModeMenu; + DeferredShadingSystem *mSystem; + SelectMenu* mDisplayModeMenu; public: Sample_DeferredShading() - { - mInfo["Title"] = "Deferred Shading"; - mInfo["Description"] = "A sample implementation of a deferred renderer using the compositor framework."; - mInfo["Thumbnail"] = "thumb_deferred.png"; - mInfo["Category"] = "Lighting"; - mInfo["Help"] = "See http://www.ogre3d.org/wiki/index.php/Deferred_Shading for more info"; - } + { + mInfo["Title"] = "Deferred Shading"; + mInfo["Description"] = "A sample implementation of a deferred renderer using the compositor framework."; + mInfo["Thumbnail"] = "thumb_deferred.png"; + mInfo["Category"] = "Lighting"; + mInfo["Help"] = "See http://www.ogre3d.org/wiki/index.php/Deferred_Shading for more info"; + } protected: - void cleanupContent(void) - { - delete ( SharedData::getSingletonPtr() ); + void cleanupContent(void) + { + delete ( SharedData::getSingletonPtr() ); delete mSystem; - } + } - bool frameRenderingQueued(const FrameEvent& evt) - { - if( SdkSample::frameRenderingQueued(evt) == false ) - return false; - SharedData::getSingleton().iLastFrameTime = evt.timeSinceLastFrame; + bool frameRenderingQueued(const FrameEvent& evt) + { + if( SdkSample::frameRenderingQueued(evt) == false ) + return false; + SharedData::getSingleton().iLastFrameTime = evt.timeSinceLastFrame; - if (SharedData::getSingleton().mMLAnimState) - SharedData::getSingleton().mMLAnimState->addTime(evt.timeSinceLastFrame); - return true; - } + if (SharedData::getSingleton().mMLAnimState) + SharedData::getSingleton().mMLAnimState->addTime(evt.timeSinceLastFrame); + return true; + } - void setupControls() - { - mTrayMgr->showCursor(); + void setupControls() + { + mTrayMgr->showCursor(); + + // create checkboxs to toggle ssao and shadows + mTrayMgr->createCheckBox(TL_TOPLEFT, "DeferredShading", "Deferred Shading", 220)->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "SSAO", "Ambient Occlusion", 220)->setChecked(false, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "GlobalLight", "Global Light", 220)->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Shadows", "Shadows", 220)->setChecked(true, false); - // create checkboxs to toggle ssao and shadows - mTrayMgr->createCheckBox(TL_TOPLEFT, "DeferredShading", "Deferred Shading", 220)->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "SSAO", "Ambient Occlusion", 220)->setChecked(false, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "GlobalLight", "Global Light", 220)->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Shadows", "Shadows", 220)->setChecked(true, false); - - // create a menu to choose the model displayed - mDisplayModeMenu = mTrayMgr->createThickSelectMenu(TL_TOPLEFT, "DisplayMode", "Display Mode", 220, 4); - mDisplayModeMenu->addItem("Regular view"); - mDisplayModeMenu->addItem("Debug colours"); - mDisplayModeMenu->addItem("Debug normals"); - mDisplayModeMenu->addItem("Debug depth / specular"); - } + // create a menu to choose the model displayed + mDisplayModeMenu = mTrayMgr->createThickSelectMenu(TL_TOPLEFT, "DisplayMode", "Display Mode", 220, 4); + mDisplayModeMenu->addItem("Regular view"); + mDisplayModeMenu->addItem("Debug colours"); + mDisplayModeMenu->addItem("Debug normals"); + mDisplayModeMenu->addItem("Debug depth / specular"); + } - void itemSelected(SelectMenu* menu) - { - //Options are aligned with the mode enum - SharedData::getSingleton().iSystem->setMode( + void itemSelected(SelectMenu* menu) + { + //Options are aligned with the mode enum + SharedData::getSingleton().iSystem->setMode( (DeferredShadingSystem::DSMode)menu->getSelectionIndex()); - } + } - void checkBoxToggled(CheckBox* box) - { - if (box->getName() == "SSAO") - { - SharedData::getSingleton().iSystem->setSSAO(box->isChecked()); - } - else if (box->getName() == "GlobalLight") - { - SharedData::getSingleton().iGlobalActivate = box->isChecked(); - SharedData::getSingleton().iMainLight->setVisible(box->isChecked()); - } - else if (box->getName() == "Shadows") - { - mSceneMgr->setShadowTechnique(box->isChecked() ? + void checkBoxToggled(CheckBox* box) + { + if (box->getName() == "SSAO") + { + SharedData::getSingleton().iSystem->setSSAO(box->isChecked()); + } + else if (box->getName() == "GlobalLight") + { + SharedData::getSingleton().iGlobalActivate = box->isChecked(); + SharedData::getSingleton().iMainLight->setVisible(box->isChecked()); + } + else if (box->getName() == "Shadows") + { + mSceneMgr->setShadowTechnique(box->isChecked() ? SHADOWTYPE_TEXTURE_ADDITIVE : SHADOWTYPE_NONE); - } - else if (box->getName() == "DeferredShading") - { - SharedData::getSingleton().iSystem->setActive(box->isChecked()); - } - } + } + else if (box->getName() == "DeferredShading") + { + SharedData::getSingleton().iSystem->setActive(box->isChecked()); + } + } //Utility function to help set scene up void setEntityHeight(Entity* ent, Real newHeight) @@ -144,49 +144,49 @@ class _OgreSampleClassExport Sample_DeferredShading : public SdkSample, public R parentNode->setScale(scaleFactor, scaleFactor, scaleFactor); } - void createAtheneScene(SceneNode* rootNode) - { - // Prepare athene mesh for normalmapping + void createAtheneScene(SceneNode* rootNode) + { + // Prepare athene mesh for normalmapping MeshPtr pAthene = MeshManager::getSingleton().load("athene.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); unsigned short src, dest; if (!pAthene->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) pAthene->buildTangentVectors(VES_TANGENT, src, dest); - //Create an athena statue + //Create an athena statue Entity* athena = mSceneMgr->createEntity("Athena", "athene.mesh"); - athena->setMaterialName("DeferredDemo/DeferredAthena"); - SceneNode *aNode = rootNode->createChildSceneNode(); - aNode->attachObject( athena ); - aNode->setPosition(-8.5, 4.5, 0); + athena->setMaterialName("DeferredDemo/DeferredAthena"); + SceneNode *aNode = rootNode->createChildSceneNode(); + aNode->attachObject( athena ); + aNode->setPosition(-8.5, 4.5, 0); setEntityHeight(athena, 4.0); aNode->yaw(Ogre::Degree(90)); - // Create some happy little lights to decorate the athena statue - createSampleLights(); - } + // Create some happy little lights to decorate the athena statue + createSampleLights(); + } - void createKnotScene(SceneNode* rootNode) - { - // Prepare knot mesh for normal mapping - MeshPtr pKnot = MeshManager::getSingleton().load("knot.mesh", + void createKnotScene(SceneNode* rootNode) + { + // Prepare knot mesh for normal mapping + MeshPtr pKnot = MeshManager::getSingleton().load("knot.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - unsigned short src, dest; + unsigned short src, dest; if (!pKnot->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) pKnot->buildTangentVectors(VES_TANGENT, src, dest); - // Create a bunch of knots with spotlights hanging from above - Entity* knotEnt = mSceneMgr->createEntity("Knot", "knot.mesh"); - knotEnt->setMaterialName("DeferredDemo/RockWall"); - //knotEnt->setMeshLodBias(0.25f); + // Create a bunch of knots with spotlights hanging from above + Entity* knotEnt = mSceneMgr->createEntity("Knot", "knot.mesh"); + knotEnt->setMaterialName("DeferredDemo/RockWall"); + //knotEnt->setMeshLodBias(0.25f); Vector3 knotStartPos(25.5, 2, 5.5); Vector3 knotDiff(-3.7, 0, 0); for (int i=0; i < 5; i++) { char cloneName[16]; - sprintf(cloneName, "Knot%d", i); + sprintf(cloneName, "Knot%d", i); Entity* cloneKnot = knotEnt->clone(cloneName); Vector3 clonePos = knotStartPos + knotDiff*i; - SceneNode* cloneNode = rootNode->createChildSceneNode(clonePos); + SceneNode* cloneNode = rootNode->createChildSceneNode(clonePos); cloneNode->attachObject(cloneKnot); setEntityHeight(cloneKnot, 3); cloneNode->yaw(Degree(i*17)); @@ -202,23 +202,23 @@ class _OgreSampleClassExport Sample_DeferredShading : public SdkSample, public R knotLight->setSpotlightRange(Degree(25), Degree(45), 1); knotLight->setAttenuation(6, 1, 0.2, 0); } - } + } - void createObjects(SceneNode* rootNode) - { - // Create ogre heads to decorate the wall - Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh"); - //rootNode->createChildSceneNode( "Head" )->attachObject( ogreHead ); + void createObjects(SceneNode* rootNode) + { + // Create ogre heads to decorate the wall + Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh"); + //rootNode->createChildSceneNode( "Head" )->attachObject( ogreHead ); Vector3 headStartPos[2] = { Vector3(25.25,11,3), Vector3(25.25,11,-3) }; Vector3 headDiff(-3.7,0,0); for (int i=0; i < 12; i++) { char cloneName[16]; - sprintf(cloneName, "OgreHead%d", i); + sprintf(cloneName, "OgreHead%d", i); Entity* cloneHead = ogreHead->clone(cloneName); Vector3 clonePos = headStartPos[i%2] + headDiff*(i/2); if ((i/2) >= 4) clonePos.x -= 0.75; - SceneNode* cloneNode = rootNode->createChildSceneNode(clonePos); + SceneNode* cloneNode = rootNode->createChildSceneNode(clonePos); cloneNode->attachObject(cloneHead); setEntityHeight(cloneHead, 1.5); if (i % 2 == 0) @@ -227,31 +227,31 @@ class _OgreSampleClassExport Sample_DeferredShading : public SdkSample, public R } } - // Create a pile of wood pallets + // Create a pile of wood pallets Entity* woodPallet = mSceneMgr->createEntity("Pallet", "WoodPallet.mesh"); Vector3 woodStartPos(10, 0.5, -5.5); Vector3 woodDiff(0, 0.3, 0); for (int i=0; i < 5; i++) { char cloneName[16]; - sprintf(cloneName, "WoodPallet%d", i); + sprintf(cloneName, "WoodPallet%d", i); Entity* clonePallet = woodPallet->clone(cloneName); Vector3 clonePos = woodStartPos + woodDiff*i; - SceneNode* cloneNode = rootNode->createChildSceneNode(clonePos); + SceneNode* cloneNode = rootNode->createChildSceneNode(clonePos); cloneNode->attachObject(clonePallet); setEntityHeight(clonePallet, 0.3); cloneNode->yaw(Degree(i*20)); } - } + } StringVector getRequiredPlugins() - { - StringVector names; + { + StringVector names; if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl150")) names.push_back("Cg Program Manager"); - return names; - } + return names; + } void testCapabilities(const RenderSystemCapabilities* caps) { @@ -261,7 +261,7 @@ class _OgreSampleClassExport Sample_DeferredShading : public SdkSample, public R "run this demo. Sorry!", "DeferredShading::testCapabilities"); } - if (caps->getNumMultiRenderTargets()<2) + if (caps->getNumMultiRenderTargets()<2) { OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support at least two simultaneous render targets, so cannot " "run this demo. Sorry!", @@ -274,9 +274,9 @@ class _OgreSampleClassExport Sample_DeferredShading : public SdkSample, public R #if OGRE_NO_GLES3_SUPPORT == 0 !GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && #endif - !GpuProgramManager::getSingleton().isSyntaxSupported("glsl150")) + !GpuProgramManager::getSingleton().isSyntaxSupported("glsl150")) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support advanced vertex" + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support advanced vertex" " programs, so you cannot run this sample. Sorry!", "DeferredShading::testCapabilities"); } } @@ -284,202 +284,202 @@ class _OgreSampleClassExport Sample_DeferredShading : public SdkSample, public R // Just override the mandatory create scene method void setupContent(void) { - mCameraMan->setTopSpeed(20.0); - new SharedData(); - mSystem = 0; + mCameraMan->setTopSpeed(20.0); + new SharedData(); + mSystem = 0; // Set ambient light mSceneMgr->setAmbientLight(ColourValue(0.15, 0.00, 0.00)); // Skybox mSceneMgr->setSkyBox(true, "DeferredDemo/SkyBox", 500); // Create main, static light - Light* l1 = mSceneMgr->createLight(); + Light* l1 = mSceneMgr->createLight(); l1->setType(Light::LT_DIRECTIONAL); l1->setDiffuseColour(0.5f, 0.45f, 0.1f); - l1->setDirection(1, -0.5, -0.2); - l1->setShadowFarClipDistance(250); - l1->setShadowFarDistance(75); - //Turn this on to have the directional light cast shadows - l1->setCastShadows(false); - - mCamera->setPosition(25, 5, 0); + l1->setDirection(1, -0.5, -0.2); + l1->setShadowFarClipDistance(250); + l1->setShadowFarDistance(75); + //Turn this on to have the directional light cast shadows + l1->setCastShadows(false); + + mCamera->setPosition(25, 5, 0); mCamera->lookAt(0,0,0); - mCamera->setFarClipDistance(1000.0); + mCamera->setFarClipDistance(1000.0); mCamera->setNearClipDistance(0.5); - setDragLook(true); + setDragLook(true); - mSystem = new DeferredShadingSystem(mWindow->getViewport(0), mSceneMgr, mCamera); - SharedData::getSingleton().iSystem = mSystem; - mSystem->initialize(); + mSystem = new DeferredShadingSystem(mWindow->getViewport(0), mSceneMgr, mCamera); + SharedData::getSingleton().iSystem = mSystem; + mSystem->initialize(); // safely setup application's (not postfilter!) shared data - SharedData::getSingleton().iCamera = mCamera; - SharedData::getSingleton().iRoot = mRoot; - SharedData::getSingleton().iWindow = mWindow; - SharedData::getSingleton().iActivate = true; - SharedData::getSingleton().iGlobalActivate = true; - SharedData::getSingleton().iMainLight = l1; + SharedData::getSingleton().iCamera = mCamera; + SharedData::getSingleton().iRoot = mRoot; + SharedData::getSingleton().iWindow = mWindow; + SharedData::getSingleton().iActivate = true; + SharedData::getSingleton().iGlobalActivate = true; + SharedData::getSingleton().iMainLight = l1; - //Create the scene - // Create "root" node - SceneNode* rootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + //Create the scene + // Create "root" node + SceneNode* rootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); // Create the cathedral - this will be the static scene - Entity* cathedralEnt = mSceneMgr->createEntity("Cathedral", "sibenik.mesh"); + Entity* cathedralEnt = mSceneMgr->createEntity("Cathedral", "sibenik.mesh"); SceneNode* cathedralNode = rootNode->createChildSceneNode(); cathedralNode->attachObject(cathedralEnt); - + createAtheneScene(rootNode); - createKnotScene(rootNode); - createObjects(rootNode); + createKnotScene(rootNode); + createObjects(rootNode); - setupControls(); - } + setupControls(); + } - void createSampleLights() - { - // Create some lights - vector::type lights; - SceneNode *parentNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("LightsParent"); - // Create light nodes - vector::type nodes; + void createSampleLights() + { + // Create some lights + vector::type lights; + SceneNode *parentNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("LightsParent"); + // Create light nodes + vector::type nodes; Vector4 attParams = Vector4(4,1,0,7); Real lightRadius = 25; - Light *a = mSceneMgr->createLight(); - SceneNode *an = parentNode->createChildSceneNode(); - an->attachObject(a); - a->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); - //a->setAttenuation(1.0f, 0.000f, 0.000f); - an->setPosition(0,0,lightRadius); - a->setDiffuseColour(1,0,0); - //a->setSpecularColour(0.5,0,0); - lights.push_back(a); - nodes.push_back(an); + Light *a = mSceneMgr->createLight(); + SceneNode *an = parentNode->createChildSceneNode(); + an->attachObject(a); + a->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); + //a->setAttenuation(1.0f, 0.000f, 0.000f); + an->setPosition(0,0,lightRadius); + a->setDiffuseColour(1,0,0); + //a->setSpecularColour(0.5,0,0); + lights.push_back(a); + nodes.push_back(an); - Light *b = mSceneMgr->createLight(); - SceneNode *bn = parentNode->createChildSceneNode(); - bn->attachObject(b); - b->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); - bn->setPosition(lightRadius,0,0); - b->setDiffuseColour(1,1,0); - //b->setSpecularColour(0.5,0.5,0); - lights.push_back(b); - nodes.push_back(bn); + Light *b = mSceneMgr->createLight(); + SceneNode *bn = parentNode->createChildSceneNode(); + bn->attachObject(b); + b->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); + bn->setPosition(lightRadius,0,0); + b->setDiffuseColour(1,1,0); + //b->setSpecularColour(0.5,0.5,0); + lights.push_back(b); + nodes.push_back(bn); - Light *c = mSceneMgr->createLight(); - SceneNode *cn = parentNode->createChildSceneNode(); - cn->attachObject(c); - c->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); - cn->setPosition(0,0,-lightRadius); - c->setDiffuseColour(0,1,1); - c->setSpecularColour(0.25,1.0,1.0); // Cyan light has specular component - lights.push_back(c); - nodes.push_back(cn); + Light *c = mSceneMgr->createLight(); + SceneNode *cn = parentNode->createChildSceneNode(); + cn->attachObject(c); + c->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); + cn->setPosition(0,0,-lightRadius); + c->setDiffuseColour(0,1,1); + c->setSpecularColour(0.25,1.0,1.0); // Cyan light has specular component + lights.push_back(c); + nodes.push_back(cn); - Light *d = mSceneMgr->createLight(); - SceneNode *dn = parentNode->createChildSceneNode(); - dn->attachObject(d); - d->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); - dn->setPosition(-lightRadius,0,0); - d->setDiffuseColour(1,0,1); - d->setSpecularColour(0.0,0,0.0); - lights.push_back(d); - nodes.push_back(dn); + Light *d = mSceneMgr->createLight(); + SceneNode *dn = parentNode->createChildSceneNode(); + dn->attachObject(d); + d->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); + dn->setPosition(-lightRadius,0,0); + d->setDiffuseColour(1,0,1); + d->setSpecularColour(0.0,0,0.0); + lights.push_back(d); + nodes.push_back(dn); - Light *e = mSceneMgr->createLight(); - SceneNode *en = parentNode->createChildSceneNode(); - en->attachObject(e); - e->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); - en->setPosition(lightRadius,0,lightRadius); - e->setDiffuseColour(0,0,1); - e->setSpecularColour(0,0,0); - lights.push_back(e); - nodes.push_back(en); - - Light *f = mSceneMgr->createLight(); - SceneNode *fn = parentNode->createChildSceneNode(); - fn->attachObject(f); - f->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); - fn->setPosition(-lightRadius,0,-lightRadius); - f->setDiffuseColour(0,1,0); - f->setSpecularColour(0,0.0,0.0); - lights.push_back(f); - nodes.push_back(fn); + Light *e = mSceneMgr->createLight(); + SceneNode *en = parentNode->createChildSceneNode(); + en->attachObject(e); + e->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); + en->setPosition(lightRadius,0,lightRadius); + e->setDiffuseColour(0,0,1); + e->setSpecularColour(0,0,0); + lights.push_back(e); + nodes.push_back(en); - // Create marker meshes to show user where the lights are - Entity *ent; - GeomUtils::createSphere("PointLightMesh", 0.05f, 5, 5, true, true); - for(vector::type::iterator i=lights.begin(); i!=lights.end(); ++i) - { - Light* light = *i; - ent = mSceneMgr->createEntity(light->getName()+"v", "PointLightMesh"); - String matname = light->getName()+"m"; - // Create coloured material - MaterialPtr mat = MaterialManager::getSingleton().create(matname, - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + Light *f = mSceneMgr->createLight(); + SceneNode *fn = parentNode->createChildSceneNode(); + fn->attachObject(f); + f->setAttenuation(attParams.x, attParams.y, attParams.z, attParams.w); + fn->setPosition(-lightRadius,0,-lightRadius); + f->setDiffuseColour(0,1,0); + f->setSpecularColour(0,0.0,0.0); + lights.push_back(f); + nodes.push_back(fn); + + // Create marker meshes to show user where the lights are + Entity *ent; + GeomUtils::createSphere("PointLightMesh", 0.05f, 5, 5, true, true); + for(vector::type::iterator i=lights.begin(); i!=lights.end(); ++i) + { + Light* light = *i; + ent = mSceneMgr->createEntity(light->getName()+"v", "PointLightMesh"); + String matname = light->getName()+"m"; + // Create coloured material + MaterialPtr mat = MaterialManager::getSingleton().create(matname, + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); Pass* pass = mat->getTechnique(0)->getPass(0); pass->setDiffuse(0.0f,0.0f,0.0f,1.0f); - pass->setAmbient(0.0f,0.0f,0.0f); - pass->setSelfIllumination(light->getDiffuseColour()); + pass->setAmbient(0.0f,0.0f,0.0f); + pass->setSelfIllumination(light->getDiffuseColour()); - ent->setMaterialName(matname); - //ent->setRenderQueueGroup(light->getRenderQueueGroup()); - ent->setRenderQueueGroup(DeferredShadingSystem::POST_GBUFFER_RENDER_QUEUE); - static_cast(light->getParentNode())->attachObject(ent); - ent->setVisible(true); - } + ent->setMaterialName(matname); + //ent->setRenderQueueGroup(light->getRenderQueueGroup()); + ent->setRenderQueueGroup(DeferredShadingSystem::POST_GBUFFER_RENDER_QUEUE); + static_cast(light->getParentNode())->attachObject(ent); + ent->setVisible(true); + } - // Store nodes for hiding/showing - SharedData::getSingleton().mLightNodes = nodes; + // Store nodes for hiding/showing + SharedData::getSingleton().mLightNodes = nodes; - // Do some animation for node a-f - // Generate helix structure - float seconds_per_station = 1.0f; - float r = 1.0; - //Vector3 base(0,-30,0); - Vector3 base(-8.75, 3.5, 0); + // Do some animation for node a-f + // Generate helix structure + float seconds_per_station = 1.0f; + float r = 1.0; + //Vector3 base(0,-30,0); + Vector3 base(-8.75, 3.5, 0); - float h=3; - const size_t s_to_top = 16; - const size_t stations = s_to_top*2-1; - float ascend = h/((float)s_to_top); - float stations_per_revolution = 3.5f; - size_t skip = 2; // stations between lights - Vector3 station_pos[stations]; - for(size_t x=0; xcreateAnimation("LightSwarmTrack", stations*seconds_per_station); - // Spline it for nice curves - anim->setInterpolationMode(Animation::IM_SPLINE); - for(unsigned int x=0; xcreateNodeTrack(x, nodes[x]); - for(size_t y=0; y<=stations; ++y) - { - // Setup keyframes - TransformKeyFrame* key = track->createNodeKeyFrame(y*seconds_per_station); // A start position - key->setTranslate(station_pos[(x*skip+y)%stations]); - // Make sure size of light doesn't change - key->setScale(nodes[x]->getScale()); - } - } - // Create a new animation state to track this - SharedData::getSingleton().mMLAnimState = mSceneMgr->createAnimationState("LightSwarmTrack"); - SharedData::getSingleton().mMLAnimState->setEnabled(true); + float h=3; + const size_t s_to_top = 16; + const size_t stations = s_to_top*2-1; + float ascend = h/((float)s_to_top); + float stations_per_revolution = 3.5f; + size_t skip = 2; // stations between lights + Vector3 station_pos[stations]; + for(size_t x=0; xcreateAnimation("LightSwarmTrack", stations*seconds_per_station); + // Spline it for nice curves + anim->setInterpolationMode(Animation::IM_SPLINE); + for(unsigned int x=0; xcreateNodeTrack(x, nodes[x]); + for(size_t y=0; y<=stations; ++y) + { + // Setup keyframes + TransformKeyFrame* key = track->createNodeKeyFrame(y*seconds_per_station); // A start position + key->setTranslate(station_pos[(x*skip+y)%stations]); + // Make sure size of light doesn't change + key->setScale(nodes[x]->getScale()); + } + } + // Create a new animation state to track this + SharedData::getSingleton().mMLAnimState = mSceneMgr->createAnimationState("LightSwarmTrack"); + SharedData::getSingleton().mMLAnimState->setEnabled(true); - /*Light* spotLight = mSceneMgr->createLight("Spotlight1"); + /*Light* spotLight = mSceneMgr->createLight("Spotlight1"); spotLight->setType(Light::LT_SPOTLIGHT); spotLight->setAttenuation(200, 1.0f, 0, 0); spotLight->setSpotlightRange(Degree(30.0), Degree(45.0), 0.8); @@ -487,7 +487,7 @@ class _OgreSampleClassExport Sample_DeferredShading : public SdkSample, public R spotLight->setDirection(0, -1, 0); spotLight->setDiffuseColour(1,1,1); spotLight->setSpecularColour(1,1,1);*/ - } + } }; #endif diff --git a/Samples/DeferredShading/include/GBufferMaterialGenerator.h b/Samples/DeferredShading/include/GBufferMaterialGenerator.h index 2bad99222ed..3edbb59c240 100644 --- a/Samples/DeferredShading/include/GBufferMaterialGenerator.h +++ b/Samples/DeferredShading/include/GBufferMaterialGenerator.h @@ -26,44 +26,44 @@ same license as the rest of the engine. class GBufferMaterialGenerator : public MaterialGenerator { public: - - //Constructor - GBufferMaterialGenerator(); + + //Constructor + GBufferMaterialGenerator(); - //The relevant options for objects that are rendered to the GBuffer - enum GBufferPermutations - { - //(Regular) Textures - GBP_NO_TEXTURES = 0x00000000, - GBP_ONE_TEXTURE = 0x00000001, - GBP_TWO_TEXTURES = 0x00000002, - GBP_THREE_TEXTURES = 0x00000003, - GBP_TEXTURE_MASK = 0x0000000F, - + //The relevant options for objects that are rendered to the GBuffer + enum GBufferPermutations + { + //(Regular) Textures + GBP_NO_TEXTURES = 0x00000000, + GBP_ONE_TEXTURE = 0x00000001, + GBP_TWO_TEXTURES = 0x00000002, + GBP_THREE_TEXTURES = 0x00000003, + GBP_TEXTURE_MASK = 0x0000000F, + //Material properties GBP_HAS_DIFFUSE_COLOUR = 0x00000010, - //The number of texture coordinate sets - GBP_NO_TEXCOORDS = 0x00000000, - GBP_ONE_TEXCOORD = 0x00000100, - GBP_TWO_TEXCOORDS = 0x00000200, - GBP_TEXCOORD_MASK = 0x00000700, + //The number of texture coordinate sets + GBP_NO_TEXCOORDS = 0x00000000, + GBP_ONE_TEXCOORD = 0x00000100, + GBP_TWO_TEXCOORDS = 0x00000200, + GBP_TEXCOORD_MASK = 0x00000700, - //Do we have a normal map - GBP_NORMAL_MAP = 0x00000800, + //Do we have a normal map + GBP_NORMAL_MAP = 0x00000800, - //Are we skinned? - GBP_SKINNED = 0x00010000 - }; - - //The mask of the flags that matter for generating the fragment shader - static const Ogre::uint32 FS_MASK = 0x0000FFFF; - - //The mask of the flags that matter for generating the vertex shader - static const Ogre::uint32 VS_MASK = 0x00FFFF00; - - //The mask of the flags that matter for generating the material - static const Ogre::uint32 MAT_MASK = 0xFF00FFFF; + //Are we skinned? + GBP_SKINNED = 0x00010000 + }; + + //The mask of the flags that matter for generating the fragment shader + static const Ogre::uint32 FS_MASK = 0x0000FFFF; + + //The mask of the flags that matter for generating the vertex shader + static const Ogre::uint32 VS_MASK = 0x00FFFF00; + + //The mask of the flags that matter for generating the material + static const Ogre::uint32 MAT_MASK = 0xFF00FFFF; }; #endif diff --git a/Samples/DeferredShading/include/GBufferSchemeHandler.h b/Samples/DeferredShading/include/GBufferSchemeHandler.h index 4ae23570382..e03f050e90e 100644 --- a/Samples/DeferredShading/include/GBufferSchemeHandler.h +++ b/Samples/DeferredShading/include/GBufferSchemeHandler.h @@ -29,45 +29,45 @@ same license as the rest of the engine. class GBufferSchemeHandler : public Ogre::MaterialManager::Listener { public: - /** @copydoc MaterialManager::Listener::handleSchemeNotFound */ - virtual Ogre::Technique* handleSchemeNotFound(unsigned short schemeIndex, - const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, - const Ogre::Renderable* rend); + /** @copydoc MaterialManager::Listener::handleSchemeNotFound */ + virtual Ogre::Technique* handleSchemeNotFound(unsigned short schemeIndex, + const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, + const Ogre::Renderable* rend); protected: - //The material generator - GBufferMaterialGenerator mMaterialGenerator; - - //The string that will be checked in textures to determine whether they are normal maps - static const Ogre::String NORMAL_MAP_PATTERN; + //The material generator + GBufferMaterialGenerator mMaterialGenerator; + + //The string that will be checked in textures to determine whether they are normal maps + static const Ogre::String NORMAL_MAP_PATTERN; - //A structure for containing the properties of a material, relevant to GBuffer rendering - //You might need to expand this class to support more options - struct PassProperties - { - PassProperties() : isDeferred(true), normalMap(0), isSkinned(false) {} + //A structure for containing the properties of a material, relevant to GBuffer rendering + //You might need to expand this class to support more options + struct PassProperties + { + PassProperties() : isDeferred(true), normalMap(0), isSkinned(false) {} - bool isDeferred; - Ogre::vector::type regularTextures; - Ogre::TextureUnitState* normalMap; - bool isSkinned; + bool isDeferred; + Ogre::vector::type regularTextures; + Ogre::TextureUnitState* normalMap; + bool isSkinned; bool hasDiffuseColour; - - //Example of possible extension : vertex colours - //Ogre::TrackVertexColourType vertexColourType; - }; + + //Example of possible extension : vertex colours + //Ogre::TrackVertexColourType vertexColourType; + }; - //Inspect a technique and return its relevant properties - PassProperties inspectPass(Ogre::Pass* pass, - unsigned short lodIndex, const Ogre::Renderable* rend); + //Inspect a technique and return its relevant properties + PassProperties inspectPass(Ogre::Pass* pass, + unsigned short lodIndex, const Ogre::Renderable* rend); - //Get the permutation of material flags that fit a certain property sheet - MaterialGenerator::Perm getPermutation(const PassProperties& props); + //Get the permutation of material flags that fit a certain property sheet + MaterialGenerator::Perm getPermutation(const PassProperties& props); - //Fill a pass with the specific data from the pass it is based on - void fillPass(Ogre::Pass* gBufferPass, Ogre::Pass* originalPass, const PassProperties& props); + //Fill a pass with the specific data from the pass it is based on + void fillPass(Ogre::Pass* gBufferPass, Ogre::Pass* originalPass, const PassProperties& props); - //Check if a texture is a normal map, and fill property sheet accordingly - bool checkNormalMap(Ogre::TextureUnitState* tus, PassProperties& props); + //Check if a texture is a normal map, and fill property sheet accordingly + bool checkNormalMap(Ogre::TextureUnitState* tus, PassProperties& props); }; #endif diff --git a/Samples/DeferredShading/include/GeomUtils.h b/Samples/DeferredShading/include/GeomUtils.h index 4f7f5b61825..3516741466c 100644 --- a/Samples/DeferredShading/include/GeomUtils.h +++ b/Samples/DeferredShading/include/GeomUtils.h @@ -21,38 +21,38 @@ same license as the rest of the engine. class GeomUtils { public: - // Create a sphere Mesh with a given name, radius, number of rings and number of segments - static void createSphere(const Ogre::String& strName - , float radius - , int nRings, int nSegments - , bool bNormals - , bool bTexCoords - ); - - - // Fill up a fresh copy of VertexData and IndexData with a sphere's coords given the number of rings and the number of segments - static void createSphere(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData - , float radius - , int nRings, int nSegments - , bool bNormals - , bool bTexCoords); - - // Create a cone Mesh with a given name, radius and number of vertices in base - // Created cone will have its head at 0,0,0, and will 'expand to' positive y - static void createCone(const Ogre::String& strName - , float radius - , float height - , int nVerticesInBase); - - // Fill up a fresh copy of VertexData and IndexData with a cone's coords given the radius and number of vertices in base - static void createCone(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData - , float radius - , float height - , int nVerticesInBase); - - - // Fill up a fresh copy of VertexData with a normalized quad - static void createQuad(Ogre::VertexData*& vertexData); + // Create a sphere Mesh with a given name, radius, number of rings and number of segments + static void createSphere(const Ogre::String& strName + , float radius + , int nRings, int nSegments + , bool bNormals + , bool bTexCoords + ); + + + // Fill up a fresh copy of VertexData and IndexData with a sphere's coords given the number of rings and the number of segments + static void createSphere(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData + , float radius + , int nRings, int nSegments + , bool bNormals + , bool bTexCoords); + + // Create a cone Mesh with a given name, radius and number of vertices in base + // Created cone will have its head at 0,0,0, and will 'expand to' positive y + static void createCone(const Ogre::String& strName + , float radius + , float height + , int nVerticesInBase); + + // Fill up a fresh copy of VertexData and IndexData with a cone's coords given the radius and number of vertices in base + static void createCone(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData + , float radius + , float height + , int nVerticesInBase); + + + // Fill up a fresh copy of VertexData with a normalized quad + static void createQuad(Ogre::VertexData*& vertexData); }; diff --git a/Samples/DeferredShading/include/LightMaterialGenerator.h b/Samples/DeferredShading/include/LightMaterialGenerator.h index c3cf0afcd95..28dc32ff0df 100755 --- a/Samples/DeferredShading/include/LightMaterialGenerator.h +++ b/Samples/DeferredShading/include/LightMaterialGenerator.h @@ -20,21 +20,21 @@ same license as the rest of the engine. class LightMaterialGenerator: public MaterialGenerator { public: - /** Permutation of light materials - */ - enum MaterialID - { - MI_POINT = 0x01, // Is a point light - MI_SPOTLIGHT = 0x02, // Is a spot light - MI_DIRECTIONAL = 0x04, // Is a directional light - - MI_ATTENUATED = 0x08, // Rendered attenuated - MI_SPECULAR = 0x10, // Specular component is calculated - MI_SHADOW_CASTER = 0x20 // Will cast shadows - }; + /** Permutation of light materials + */ + enum MaterialID + { + MI_POINT = 0x01, // Is a point light + MI_SPOTLIGHT = 0x02, // Is a spot light + MI_DIRECTIONAL = 0x04, // Is a directional light + + MI_ATTENUATED = 0x08, // Rendered attenuated + MI_SPECULAR = 0x10, // Specular component is calculated + MI_SHADOW_CASTER = 0x20 // Will cast shadows + }; - LightMaterialGenerator(); - virtual ~LightMaterialGenerator(); + LightMaterialGenerator(); + virtual ~LightMaterialGenerator(); }; #endif diff --git a/Samples/DeferredShading/include/ListenerFactoryLogic.h b/Samples/DeferredShading/include/ListenerFactoryLogic.h index d6374e57083..426dad3e915 100644 --- a/Samples/DeferredShading/include/ListenerFactoryLogic.h +++ b/Samples/DeferredShading/include/ListenerFactoryLogic.h @@ -24,27 +24,27 @@ conditions of the standard open source license. class ListenerFactoryLogic : public Ogre::CompositorLogic { public: - /** @copydoc CompositorLogic::compositorInstanceCreated */ - virtual void compositorInstanceCreated(Ogre::CompositorInstance* newInstance) - { - Ogre::CompositorInstance::Listener* listener = createListener(newInstance); - newInstance->addListener(listener); - mListeners[newInstance] = listener; - } - - /** @copydoc CompositorLogic::compositorInstanceDestroyed */ - virtual void compositorInstanceDestroyed(Ogre::CompositorInstance* destroyedInstance) - { - delete mListeners[destroyedInstance]; - mListeners.erase(destroyedInstance); - } + /** @copydoc CompositorLogic::compositorInstanceCreated */ + virtual void compositorInstanceCreated(Ogre::CompositorInstance* newInstance) + { + Ogre::CompositorInstance::Listener* listener = createListener(newInstance); + newInstance->addListener(listener); + mListeners[newInstance] = listener; + } + + /** @copydoc CompositorLogic::compositorInstanceDestroyed */ + virtual void compositorInstanceDestroyed(Ogre::CompositorInstance* destroyedInstance) + { + delete mListeners[destroyedInstance]; + mListeners.erase(destroyedInstance); + } protected: - //This is the method that implementers will need to create - virtual Ogre::CompositorInstance::Listener* createListener(Ogre::CompositorInstance* instance) = 0; + //This is the method that implementers will need to create + virtual Ogre::CompositorInstance::Listener* createListener(Ogre::CompositorInstance* instance) = 0; private: - typedef std::map ListenerMap; - ListenerMap mListeners; + typedef std::map ListenerMap; + ListenerMap mListeners; }; diff --git a/Samples/DeferredShading/include/MaterialGenerator.h b/Samples/DeferredShading/include/MaterialGenerator.h index c516e37ff91..bbee6a9bb32 100755 --- a/Samples/DeferredShading/include/MaterialGenerator.h +++ b/Samples/DeferredShading/include/MaterialGenerator.h @@ -19,64 +19,64 @@ same license as the rest of the engine. #include "OgreStringVector.h" /** Caching, on-the-fly material generator. This is a class that automatically - generates and stores different permutations of a material, and its shaders. - It can be used if you have a material that has lots of slightly different - variations, like whether to use a specular light, skinning, normal mapping - and other options. Writing all these out is a tedious job. Of course it is - possible to always use the material with all features, but that might result - in large, slow shader programs. This class provides an efficient solution - to that. + generates and stores different permutations of a material, and its shaders. + It can be used if you have a material that has lots of slightly different + variations, like whether to use a specular light, skinning, normal mapping + and other options. Writing all these out is a tedious job. Of course it is + possible to always use the material with all features, but that might result + in large, slow shader programs. This class provides an efficient solution + to that. */ class MaterialGenerator { public: - /** Bitfield used to signify a material permutations */ - typedef Ogre::uint32 Perm; - virtual ~MaterialGenerator(); + /** Bitfield used to signify a material permutations */ + typedef Ogre::uint32 Perm; + virtual ~MaterialGenerator(); - const Ogre::MaterialPtr &getMaterial(Perm permutation); + const Ogre::MaterialPtr &getMaterial(Perm permutation); - /** Implementation class that takes care of actual generation or lookup - of the various constituent parts (template material, fragment shader - and vertex shader). These methods are only called once for every permutation, - after which the result is stored and re-used. - */ - class Impl - { - public: - virtual ~Impl(); - virtual Ogre::GpuProgramPtr generateVertexShader(Perm permutation) = 0; - virtual Ogre::GpuProgramPtr generateFragmentShader(Perm permutation) = 0; - virtual Ogre::MaterialPtr generateTemplateMaterial(Perm permutation) = 0; - }; + /** Implementation class that takes care of actual generation or lookup + of the various constituent parts (template material, fragment shader + and vertex shader). These methods are only called once for every permutation, + after which the result is stored and re-used. + */ + class Impl + { + public: + virtual ~Impl(); + virtual Ogre::GpuProgramPtr generateVertexShader(Perm permutation) = 0; + virtual Ogre::GpuProgramPtr generateFragmentShader(Perm permutation) = 0; + virtual Ogre::MaterialPtr generateTemplateMaterial(Perm permutation) = 0; + }; protected: - /** The constructor is protected as this base class should never be constructed - as-is. It is meant to be subclassed so that values can be assigned to - the various fields controlling material generator, and most importantly, the - mImpl field. - */ - MaterialGenerator(); + /** The constructor is protected as this base class should never be constructed + as-is. It is meant to be subclassed so that values can be assigned to + the various fields controlling material generator, and most importantly, the + mImpl field. + */ + MaterialGenerator(); - const Ogre::GpuProgramPtr &getVertexShader(Perm permutation); - const Ogre::GpuProgramPtr &getFragmentShader(Perm permutation); - const Ogre::MaterialPtr &getTemplateMaterial(Perm permutation); - - /// Base name of materials generated by this - Ogre::String materialBaseName; - /// Mask of permutation bits that influence vertex shader choice - Perm vsMask; - /// Mask of permutation bits that influence fragment shader choice - Perm fsMask; - /// Mask of permutation bits that influence template material choice - Perm matMask; - /// Generator - Impl *mImpl; + const Ogre::GpuProgramPtr &getVertexShader(Perm permutation); + const Ogre::GpuProgramPtr &getFragmentShader(Perm permutation); + const Ogre::MaterialPtr &getTemplateMaterial(Perm permutation); + + /// Base name of materials generated by this + Ogre::String materialBaseName; + /// Mask of permutation bits that influence vertex shader choice + Perm vsMask; + /// Mask of permutation bits that influence fragment shader choice + Perm fsMask; + /// Mask of permutation bits that influence template material choice + Perm matMask; + /// Generator + Impl *mImpl; - typedef Ogre::map::type ProgramMap; - typedef Ogre::map::type MaterialMap; + typedef Ogre::map::type ProgramMap; + typedef Ogre::map::type MaterialMap; - ProgramMap mVs, mFs; - MaterialMap mTemplateMat, mMaterials; + ProgramMap mVs, mFs; + MaterialMap mTemplateMat, mMaterials; }; #endif diff --git a/Samples/DeferredShading/include/NullSchemeHandler.h b/Samples/DeferredShading/include/NullSchemeHandler.h index 0a2d4ca1882..03f15b005f1 100644 --- a/Samples/DeferredShading/include/NullSchemeHandler.h +++ b/Samples/DeferredShading/include/NullSchemeHandler.h @@ -22,17 +22,17 @@ same license as the rest of the engine. class NullSchemeHandler : public Ogre::MaterialManager::Listener { public: - /** @copydoc MaterialManager::Listener::handleSchemeNotFound */ - virtual Ogre::Technique* handleSchemeNotFound(unsigned short schemeIndex, - const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, - const Ogre::Renderable* rend) - { - //Creating a technique so the handler only gets called once per material - Ogre::Technique* emptyTech = originalMaterial->createTechnique(); - emptyTech->removeAllPasses(); - emptyTech->setSchemeName(schemeName); - return emptyTech; - } + /** @copydoc MaterialManager::Listener::handleSchemeNotFound */ + virtual Ogre::Technique* handleSchemeNotFound(unsigned short schemeIndex, + const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, + const Ogre::Renderable* rend) + { + //Creating a technique so the handler only gets called once per material + Ogre::Technique* emptyTech = originalMaterial->createTechnique(); + emptyTech->removeAllPasses(); + emptyTech->setSchemeName(schemeName); + return emptyTech; + } }; #endif diff --git a/Samples/DeferredShading/include/SSAOLogic.h b/Samples/DeferredShading/include/SSAOLogic.h index 55e91ed70d0..7c217742e1f 100644 --- a/Samples/DeferredShading/include/SSAOLogic.h +++ b/Samples/DeferredShading/include/SSAOLogic.h @@ -20,8 +20,8 @@ same license as the rest of the engine. class SSAOLogic : public ListenerFactoryLogic { protected: - /** @copydoc ListenerFactoryLogic::createListener */ - virtual Ogre::CompositorInstance::Listener* createListener(Ogre::CompositorInstance* instance); + /** @copydoc ListenerFactoryLogic::createListener */ + virtual Ogre::CompositorInstance::Listener* createListener(Ogre::CompositorInstance* instance); }; #endif diff --git a/Samples/DeferredShading/include/SharedData.h b/Samples/DeferredShading/include/SharedData.h index ec81b1faf8a..346754e4297 100644 --- a/Samples/DeferredShading/include/SharedData.h +++ b/Samples/DeferredShading/include/SharedData.h @@ -22,34 +22,34 @@ class SharedData : public Ogre::Singleton { public: - SharedData() - : iRoot(0), - iCamera(0), - iWindow(0), - mMLAnimState(0), - iMainLight(0) - { - iActivate = false; - } - - ~SharedData() {} - - // shared data across the application - Ogre::Real iLastFrameTime; - Ogre::Root *iRoot; - Ogre::Camera *iCamera; - Ogre::RenderWindow *iWindow; - - DeferredShadingSystem *iSystem; - bool iActivate; - bool iGlobalActivate; - - // Animation state for light swarm - Ogre::AnimationState* mMLAnimState; - - Ogre::Light *iMainLight; - - Ogre::vector::type mLightNodes; + SharedData() + : iRoot(0), + iCamera(0), + iWindow(0), + mMLAnimState(0), + iMainLight(0) + { + iActivate = false; + } + + ~SharedData() {} + + // shared data across the application + Ogre::Real iLastFrameTime; + Ogre::Root *iRoot; + Ogre::Camera *iCamera; + Ogre::RenderWindow *iWindow; + + DeferredShadingSystem *iSystem; + bool iActivate; + bool iGlobalActivate; + + // Animation state for light swarm + Ogre::AnimationState* mMLAnimState; + + Ogre::Light *iMainLight; + + Ogre::vector::type mLightNodes; }; diff --git a/Samples/DeferredShading/src/AmbientLight.cpp b/Samples/DeferredShading/src/AmbientLight.cpp index 369a52b62cb..8df15521348 100644 --- a/Samples/DeferredShading/src/AmbientLight.cpp +++ b/Samples/DeferredShading/src/AmbientLight.cpp @@ -25,23 +25,23 @@ using namespace Ogre; AmbientLight::AmbientLight() { - setRenderQueueGroup(RENDER_QUEUE_2); + setRenderQueueGroup(RENDER_QUEUE_2); - mRenderOp.vertexData = new VertexData(); - mRenderOp.indexData = 0; + mRenderOp.vertexData = new VertexData(); + mRenderOp.indexData = 0; - GeomUtils::createQuad(mRenderOp.vertexData); + GeomUtils::createQuad(mRenderOp.vertexData); - mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; - mRenderOp.useIndexes = false; + mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; + mRenderOp.useIndexes = false; - // Set bounding - setBoundingBox(AxisAlignedBox(-10000,-10000,-10000,10000,10000,10000)); - mRadius = 15000; + // Set bounding + setBoundingBox(AxisAlignedBox(-10000,-10000,-10000,10000,10000,10000)); + mRadius = 15000; - mMatPtr = MaterialManager::getSingleton().getByName("DeferredShading/AmbientLight"); - assert(mMatPtr.isNull()==false); - mMatPtr->load(); + mMatPtr = MaterialManager::getSingleton().getByName("DeferredShading/AmbientLight"); + assert(mMatPtr.isNull()==false); + mMatPtr->load(); // Explicitly bind samplers for OpenGL if(Root::getSingleton().getRenderSystem()->getName().find("OpenGL 3+") != String::npos) @@ -59,48 +59,48 @@ AmbientLight::AmbientLight() AmbientLight::~AmbientLight() { - // need to release IndexData and vertexData created for renderable - delete mRenderOp.indexData; - delete mRenderOp.vertexData; + // need to release IndexData and vertexData created for renderable + delete mRenderOp.indexData; + delete mRenderOp.vertexData; } /** @copydoc MovableObject::getBoundingRadius */ Real AmbientLight::getBoundingRadius(void) const { - return mRadius; + return mRadius; } /** @copydoc Renderable::getSquaredViewDepth */ Real AmbientLight::getSquaredViewDepth(const Camera*) const { - return 0.0; + return 0.0; } const MaterialPtr& AmbientLight::getMaterial(void) const { - return mMatPtr; + return mMatPtr; } void AmbientLight::getWorldTransforms(Ogre::Matrix4* xform) const { - *xform = Matrix4::IDENTITY; + *xform = Matrix4::IDENTITY; } void AmbientLight::updateFromCamera(Ogre::Camera* camera) { - Ogre::Technique* tech = getMaterial()->getBestTechnique(); - Ogre::Vector3 farCorner = camera->getViewMatrix(true) * camera->getWorldSpaceCorners()[4]; - - for (unsigned short i=0; igetNumPasses(); i++) - { - Ogre::Pass* pass = tech->getPass(i); - // get the vertex shader parameters - Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); - // set the camera's far-top-right corner - if (params->_findNamedConstantDefinition("farCorner")) - params->setNamedConstant("farCorner", farCorner); - - params = pass->getFragmentProgramParameters(); - if (params->_findNamedConstantDefinition("farCorner")) - params->setNamedConstant("farCorner", farCorner); - } + Ogre::Technique* tech = getMaterial()->getBestTechnique(); + Ogre::Vector3 farCorner = camera->getViewMatrix(true) * camera->getWorldSpaceCorners()[4]; + + for (unsigned short i=0; igetNumPasses(); i++) + { + Ogre::Pass* pass = tech->getPass(i); + // get the vertex shader parameters + Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); + // set the camera's far-top-right corner + if (params->_findNamedConstantDefinition("farCorner")) + params->setNamedConstant("farCorner", farCorner); + + params = pass->getFragmentProgramParameters(); + if (params->_findNamedConstantDefinition("farCorner")) + params->setNamedConstant("farCorner", farCorner); + } } diff --git a/Samples/DeferredShading/src/DLight.cpp b/Samples/DeferredShading/src/DLight.cpp index b9d0bec10be..09a7fae44ac 100644 --- a/Samples/DeferredShading/src/DLight.cpp +++ b/Samples/DeferredShading/src/DLight.cpp @@ -32,321 +32,321 @@ using namespace Ogre; DLight::DLight(MaterialGenerator *sys, Ogre::Light* parentLight): mParentLight(parentLight), bIgnoreWorld(false), mGenerator(sys), mPermutation(0) { - // Set up geometry - // Allocate render operation - mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; - mRenderOp.indexData = 0; - mRenderOp.vertexData = 0; - mRenderOp.useIndexes = true; + // Set up geometry + // Allocate render operation + mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; + mRenderOp.indexData = 0; + mRenderOp.vertexData = 0; + mRenderOp.useIndexes = true; - updateFromParent(); + updateFromParent(); } //----------------------------------------------------------------------- DLight::~DLight() { - // need to release IndexData and vertexData created for renderable + // need to release IndexData and vertexData created for renderable delete mRenderOp.indexData; delete mRenderOp.vertexData; } //----------------------------------------------------------------------- void DLight::setAttenuation(float c, float b, float a) { - // Set Attenuation parameter to shader - //setCustomParameter(3, Vector4(c, b, a, 0)); - float outerRadius = mParentLight->getAttenuationRange(); - /// There is attenuation? Set material accordingly - if(c != 1.0f || b != 0.0f || a != 0.0f) - { - ENABLE_BIT(mPermutation, LightMaterialGenerator::MI_ATTENUATED); - if (mParentLight->getType() == Light::LT_POINT) - { - //// Calculate radius from Attenuation - int threshold_level = 10;// difference of 10-15 levels deemed unnoticeable - float threshold = 1.0f/((float)threshold_level/256.0f); + // Set Attenuation parameter to shader + //setCustomParameter(3, Vector4(c, b, a, 0)); + float outerRadius = mParentLight->getAttenuationRange(); + /// There is attenuation? Set material accordingly + if(c != 1.0f || b != 0.0f || a != 0.0f) + { + ENABLE_BIT(mPermutation, LightMaterialGenerator::MI_ATTENUATED); + if (mParentLight->getType() == Light::LT_POINT) + { + //// Calculate radius from Attenuation + int threshold_level = 10;// difference of 10-15 levels deemed unnoticeable + float threshold = 1.0f/((float)threshold_level/256.0f); - //// Use quadratic formula to determine outer radius - c = c-threshold; - float d=sqrt(b*b-4*a*c); - outerRadius = (-2*c)/(b+d); - outerRadius *= 1.2; - } - } - else - { - DISABLE_BIT(mPermutation,LightMaterialGenerator::MI_ATTENUATED); - } + //// Use quadratic formula to determine outer radius + c = c-threshold; + float d=sqrt(b*b-4*a*c); + outerRadius = (-2*c)/(b+d); + outerRadius *= 1.2; + } + } + else + { + DISABLE_BIT(mPermutation,LightMaterialGenerator::MI_ATTENUATED); + } - rebuildGeometry(outerRadius); + rebuildGeometry(outerRadius); } //----------------------------------------------------------------------- void DLight::setSpecularColour(const ColourValue &col) { - //setCustomParameter(2, Vector4(col.r, col.g, col.b, col.a)); - /// There is a specular component? Set material accordingly - - if(col.r != 0.0f || col.g != 0.0f || col.b != 0.0f) - ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPECULAR); - else - DISABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPECULAR); - + //setCustomParameter(2, Vector4(col.r, col.g, col.b, col.a)); + /// There is a specular component? Set material accordingly + + if(col.r != 0.0f || col.g != 0.0f || col.b != 0.0f) + ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPECULAR); + else + DISABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPECULAR); + } //----------------------------------------------------------------------- void DLight::rebuildGeometry(float radius) { - //Disable all 3 bits - DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_POINT); - DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_SPOTLIGHT); - DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_DIRECTIONAL); + //Disable all 3 bits + DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_POINT); + DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_SPOTLIGHT); + DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_DIRECTIONAL); - switch (mParentLight->getType()) - { - case Light::LT_DIRECTIONAL: - createRectangle2D(); + switch (mParentLight->getType()) + { + case Light::LT_DIRECTIONAL: + createRectangle2D(); ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_DIRECTIONAL); - break; - case Light::LT_POINT: - /// XXX some more intelligent expression for rings and segments - createSphere(radius, 10, 10); - ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_POINT); - break; - case Light::LT_SPOTLIGHT: - Real height = mParentLight->getAttenuationRange(); - Radian coneRadiusAngle = mParentLight->getSpotlightOuterAngle() / 2; + break; + case Light::LT_POINT: + /// XXX some more intelligent expression for rings and segments + createSphere(radius, 10, 10); + ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_POINT); + break; + case Light::LT_SPOTLIGHT: + Real height = mParentLight->getAttenuationRange(); + Radian coneRadiusAngle = mParentLight->getSpotlightOuterAngle() / 2; Real rad = Math::Tan(coneRadiusAngle) * height; - createCone(rad, height, 20); - ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPOTLIGHT); - break; - } + createCone(rad, height, 20); + ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SPOTLIGHT); + break; + } } //----------------------------------------------------------------------- void DLight::createRectangle2D() { - /// XXX this RenderOp should really be re-used between DLight objects, - /// not generated every time - delete mRenderOp.vertexData; - delete mRenderOp.indexData; + /// XXX this RenderOp should really be re-used between DLight objects, + /// not generated every time + delete mRenderOp.vertexData; + delete mRenderOp.indexData; - mRenderOp.vertexData = new VertexData(); + mRenderOp.vertexData = new VertexData(); mRenderOp.indexData = 0; - GeomUtils::createQuad(mRenderOp.vertexData); + GeomUtils::createQuad(mRenderOp.vertexData); mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP; mRenderOp.useIndexes = false; - // Set bounding + // Set bounding setBoundingBox(AxisAlignedBox(-10000,-10000,-10000,10000,10000,10000)); - mRadius = 15000; - bIgnoreWorld = true; + mRadius = 15000; + bIgnoreWorld = true; } //----------------------------------------------------------------------- void DLight::createSphere(float radius, int nRings, int nSegments) { - delete mRenderOp.vertexData; - delete mRenderOp.indexData; - mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; - mRenderOp.indexData = new IndexData(); - mRenderOp.vertexData = new VertexData(); - mRenderOp.useIndexes = true; + delete mRenderOp.vertexData; + delete mRenderOp.indexData; + mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; + mRenderOp.indexData = new IndexData(); + mRenderOp.vertexData = new VertexData(); + mRenderOp.useIndexes = true; - GeomUtils::createSphere(mRenderOp.vertexData, mRenderOp.indexData - , radius - , nRings, nSegments - , false // no normals - , false // no texture coordinates - ); + GeomUtils::createSphere(mRenderOp.vertexData, mRenderOp.indexData + , radius + , nRings, nSegments + , false // no normals + , false // no texture coordinates + ); - // Set bounding box and sphere - setBoundingBox( AxisAlignedBox( Vector3(-radius, -radius, -radius), Vector3(radius, radius, radius) ) ); - mRadius = radius; - bIgnoreWorld = false; + // Set bounding box and sphere + setBoundingBox( AxisAlignedBox( Vector3(-radius, -radius, -radius), Vector3(radius, radius, radius) ) ); + mRadius = radius; + bIgnoreWorld = false; } //----------------------------------------------------------------------- void DLight::createCone(float radius, float height, int nVerticesInBase) { - delete mRenderOp.vertexData; - delete mRenderOp.indexData; - mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; - mRenderOp.indexData = new IndexData(); - mRenderOp.vertexData = new VertexData(); - mRenderOp.useIndexes = true; + delete mRenderOp.vertexData; + delete mRenderOp.indexData; + mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; + mRenderOp.indexData = new IndexData(); + mRenderOp.vertexData = new VertexData(); + mRenderOp.useIndexes = true; - GeomUtils::createCone(mRenderOp.vertexData, mRenderOp.indexData - , radius - , height, nVerticesInBase); + GeomUtils::createCone(mRenderOp.vertexData, mRenderOp.indexData + , radius + , height, nVerticesInBase); - // Set bounding box and sphere - setBoundingBox( AxisAlignedBox( - Vector3(-radius, 0, -radius), - Vector3(radius, height, radius) ) ); + // Set bounding box and sphere + setBoundingBox( AxisAlignedBox( + Vector3(-radius, 0, -radius), + Vector3(radius, height, radius) ) ); - mRadius = radius; - bIgnoreWorld = false; + mRadius = radius; + bIgnoreWorld = false; } //----------------------------------------------------------------------- Real DLight::getBoundingRadius(void) const { - return mRadius; + return mRadius; } //----------------------------------------------------------------------- Real DLight::getSquaredViewDepth(const Camera* cam) const { - if(bIgnoreWorld) - { - return 0.0f; - } - else - { - Vector3 dist = cam->getDerivedPosition() - getParentSceneNode()->_getDerivedPosition(); - return dist.squaredLength(); - } + if(bIgnoreWorld) + { + return 0.0f; + } + else + { + Vector3 dist = cam->getDerivedPosition() - getParentSceneNode()->_getDerivedPosition(); + return dist.squaredLength(); + } } //----------------------------------------------------------------------- const MaterialPtr& DLight::getMaterial(void) const { - return mGenerator->getMaterial(mPermutation); + return mGenerator->getMaterial(mPermutation); } //----------------------------------------------------------------------- void DLight::getWorldTransforms(Matrix4* xform) const { - if (mParentLight->getType() == Light::LT_SPOTLIGHT) - { - Quaternion quat = Vector3::UNIT_Y.getRotationTo(mParentLight->getDerivedDirection()); - xform->makeTransform(mParentLight->getDerivedPosition(), - Vector3::UNIT_SCALE, quat); - } - else - { - xform->makeTransform(mParentLight->getDerivedPosition(), - Vector3::UNIT_SCALE, Quaternion::IDENTITY); - } - + if (mParentLight->getType() == Light::LT_SPOTLIGHT) + { + Quaternion quat = Vector3::UNIT_Y.getRotationTo(mParentLight->getDerivedDirection()); + xform->makeTransform(mParentLight->getDerivedPosition(), + Vector3::UNIT_SCALE, quat); + } + else + { + xform->makeTransform(mParentLight->getDerivedPosition(), + Vector3::UNIT_SCALE, Quaternion::IDENTITY); + } + } //----------------------------------------------------------------------- void DLight::updateFromParent() { - //TODO : Don't do this unless something changed - setAttenuation(mParentLight->getAttenuationConstant(), - mParentLight->getAttenuationLinear(), mParentLight->getAttenuationQuadric()); - setSpecularColour(mParentLight->getSpecularColour()); + //TODO : Don't do this unless something changed + setAttenuation(mParentLight->getAttenuationConstant(), + mParentLight->getAttenuationLinear(), mParentLight->getAttenuationQuadric()); + setSpecularColour(mParentLight->getSpecularColour()); - if (getCastChadows()) - { - ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SHADOW_CASTER); - } - else - { - DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_SHADOW_CASTER); - } + if (getCastChadows()) + { + ENABLE_BIT(mPermutation,LightMaterialGenerator::MI_SHADOW_CASTER); + } + else + { + DISABLE_BIT(mPermutation, LightMaterialGenerator::MI_SHADOW_CASTER); + } } //----------------------------------------------------------------------- bool DLight::isCameraInsideLight(Ogre::Camera* camera) { - switch (mParentLight->getType()) - { - case Ogre::Light::LT_DIRECTIONAL: - return false; - case Ogre::Light::LT_POINT: - { - Ogre::Real distanceFromLight = camera->getDerivedPosition() - .distance(mParentLight->getDerivedPosition()); - //Small epsilon fix to account for the fact that we aren't a true sphere. - return distanceFromLight <= mRadius + camera->getNearClipDistance() + 0.1; - } - case Ogre::Light::LT_SPOTLIGHT: - { - Ogre::Vector3 lightPos = mParentLight->getDerivedPosition(); - Ogre::Vector3 lightDir = mParentLight->getDerivedDirection(); - Ogre::Radian attAngle = mParentLight->getSpotlightOuterAngle(); - - //Extend the analytic cone's radius by the near clip range by moving its tip accordingly. - //Some trigonometry needed here. - Ogre::Vector3 clipRangeFix = -lightDir * (camera->getNearClipDistance() / Ogre::Math::Tan(attAngle/2)); - lightPos = lightPos + clipRangeFix; + switch (mParentLight->getType()) + { + case Ogre::Light::LT_DIRECTIONAL: + return false; + case Ogre::Light::LT_POINT: + { + Ogre::Real distanceFromLight = camera->getDerivedPosition() + .distance(mParentLight->getDerivedPosition()); + //Small epsilon fix to account for the fact that we aren't a true sphere. + return distanceFromLight <= mRadius + camera->getNearClipDistance() + 0.1; + } + case Ogre::Light::LT_SPOTLIGHT: + { + Ogre::Vector3 lightPos = mParentLight->getDerivedPosition(); + Ogre::Vector3 lightDir = mParentLight->getDerivedDirection(); + Ogre::Radian attAngle = mParentLight->getSpotlightOuterAngle(); + + //Extend the analytic cone's radius by the near clip range by moving its tip accordingly. + //Some trigonometry needed here. + Ogre::Vector3 clipRangeFix = -lightDir * (camera->getNearClipDistance() / Ogre::Math::Tan(attAngle/2)); + lightPos = lightPos + clipRangeFix; - Ogre::Vector3 lightToCamDir = camera->getDerivedPosition() - lightPos; - Ogre::Real distanceFromLight = lightToCamDir.normalise(); + Ogre::Vector3 lightToCamDir = camera->getDerivedPosition() - lightPos; + Ogre::Real distanceFromLight = lightToCamDir.normalise(); - Ogre::Real cosAngle = lightToCamDir.dotProduct(lightDir); - Ogre::Radian angle = Ogre::Math::ACos(cosAngle); - //Check whether we will see the cone from our current POV. + Ogre::Real cosAngle = lightToCamDir.dotProduct(lightDir); + Ogre::Radian angle = Ogre::Math::ACos(cosAngle); + //Check whether we will see the cone from our current POV. return (distanceFromLight <= (mParentLight->getAttenuationRange() / cosAngle + clipRangeFix.length())) && (angle <= attAngle); - } - default: - //Please the compiler - return false; - } + } + default: + //Please the compiler + return false; + } } //----------------------------------------------------------------------- bool DLight::getCastChadows() const { - return - mParentLight->_getManager()->isShadowTechniqueInUse() && - mParentLight->getCastShadows() && - (mParentLight->getType() == Light::LT_DIRECTIONAL || mParentLight->getType() == Light::LT_SPOTLIGHT); + return + mParentLight->_getManager()->isShadowTechniqueInUse() && + mParentLight->getCastShadows() && + (mParentLight->getType() == Light::LT_DIRECTIONAL || mParentLight->getType() == Light::LT_SPOTLIGHT); } //----------------------------------------------------------------------- void DLight::updateFromCamera(Ogre::Camera* camera) { - //Set shader params - const Ogre::MaterialPtr& mat = getMaterial(); - if (!mat->isLoaded()) - { - mat->load(); - } - Ogre::Technique* tech = mat->getBestTechnique(); - Ogre::Vector3 farCorner = camera->getViewMatrix(true) * camera->getWorldSpaceCorners()[4]; + //Set shader params + const Ogre::MaterialPtr& mat = getMaterial(); + if (!mat->isLoaded()) + { + mat->load(); + } + Ogre::Technique* tech = mat->getBestTechnique(); + Ogre::Vector3 farCorner = camera->getViewMatrix(true) * camera->getWorldSpaceCorners()[4]; - for (unsigned short i=0; igetNumPasses(); i++) - { - Ogre::Pass* pass = tech->getPass(i); - // get the vertex shader parameters - Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); - // set the camera's far-top-right corner - if (params->_findNamedConstantDefinition("farCorner")) - params->setNamedConstant("farCorner", farCorner); - - params = pass->getFragmentProgramParameters(); - if (params->_findNamedConstantDefinition("farCorner")) - params->setNamedConstant("farCorner", farCorner); + for (unsigned short i=0; igetNumPasses(); i++) + { + Ogre::Pass* pass = tech->getPass(i); + // get the vertex shader parameters + Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); + // set the camera's far-top-right corner + if (params->_findNamedConstantDefinition("farCorner")) + params->setNamedConstant("farCorner", farCorner); + + params = pass->getFragmentProgramParameters(); + if (params->_findNamedConstantDefinition("farCorner")) + params->setNamedConstant("farCorner", farCorner); - //If inside light geometry, render back faces with CMPF_GREATER, otherwise normally - if (mParentLight->getType() == Ogre::Light::LT_DIRECTIONAL) - { - pass->setCullingMode(Ogre::CULL_CLOCKWISE); - pass->setDepthCheckEnabled(false); - } - else - { - pass->setDepthCheckEnabled(true); - if (isCameraInsideLight(camera)) - { - pass->setCullingMode(Ogre::CULL_ANTICLOCKWISE); - pass->setDepthFunction(Ogre::CMPF_GREATER_EQUAL); - } - else - { - pass->setCullingMode(Ogre::CULL_CLOCKWISE); - pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL); - } - } + //If inside light geometry, render back faces with CMPF_GREATER, otherwise normally + if (mParentLight->getType() == Ogre::Light::LT_DIRECTIONAL) + { + pass->setCullingMode(Ogre::CULL_CLOCKWISE); + pass->setDepthCheckEnabled(false); + } + else + { + pass->setDepthCheckEnabled(true); + if (isCameraInsideLight(camera)) + { + pass->setCullingMode(Ogre::CULL_ANTICLOCKWISE); + pass->setDepthFunction(Ogre::CMPF_GREATER_EQUAL); + } + else + { + pass->setCullingMode(Ogre::CULL_CLOCKWISE); + pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL); + } + } - Camera shadowCam("ShadowCameraSetupCam", 0); - shadowCam._notifyViewport(camera->getViewport()); - SceneManager* sm = mParentLight->_getManager(); - sm->getShadowCameraSetup()->getShadowCamera(sm, - camera, camera->getViewport(), mParentLight, &shadowCam, 0); - - //Get the shadow camera position - if (params->_findNamedConstantDefinition("shadowCamPos")) - { - params->setNamedConstant("shadowCamPos", shadowCam.getPosition()); - } - if (params->_findNamedConstantDefinition("shadowFarClip")) - { - params->setNamedConstant("shadowFarClip", shadowCam.getFarClipDistance()); - } + Camera shadowCam("ShadowCameraSetupCam", 0); + shadowCam._notifyViewport(camera->getViewport()); + SceneManager* sm = mParentLight->_getManager(); + sm->getShadowCameraSetup()->getShadowCamera(sm, + camera, camera->getViewport(), mParentLight, &shadowCam, 0); + + //Get the shadow camera position + if (params->_findNamedConstantDefinition("shadowCamPos")) + { + params->setNamedConstant("shadowCamPos", shadowCam.getPosition()); + } + if (params->_findNamedConstantDefinition("shadowFarClip")) + { + params->setNamedConstant("shadowFarClip", shadowCam.getFarClipDistance()); + } - } + } } diff --git a/Samples/DeferredShading/src/DeferredLightCP.cpp b/Samples/DeferredShading/src/DeferredLightCP.cpp index 7be0d8ca627..553e12e8c31 100644 --- a/Samples/DeferredShading/src/DeferredLightCP.cpp +++ b/Samples/DeferredShading/src/DeferredLightCP.cpp @@ -21,114 +21,114 @@ using namespace Ogre; //----------------------------------------------------------------------- DeferredLightRenderOperation::DeferredLightRenderOperation( - CompositorInstance* instance, const CompositionPass* pass) + CompositorInstance* instance, const CompositionPass* pass) { - mViewport = instance->getChain()->getViewport(); - - //Get the names of the GBuffer textures - const CompositionPass::InputTex& input0 = pass->getInput(0); - mTexName0 = instance->getTextureInstanceName(input0.name, input0.mrtIndex); - const CompositionPass::InputTex& input1 = pass->getInput(1); - mTexName1 = instance->getTextureInstanceName(input1.name, input1.mrtIndex); + mViewport = instance->getChain()->getViewport(); + + //Get the names of the GBuffer textures + const CompositionPass::InputTex& input0 = pass->getInput(0); + mTexName0 = instance->getTextureInstanceName(input0.name, input0.mrtIndex); + const CompositionPass::InputTex& input1 = pass->getInput(1); + mTexName1 = instance->getTextureInstanceName(input1.name, input1.mrtIndex); - // Create lights material generator - mLightMaterialGenerator = new LightMaterialGenerator(); - - // Create the ambient light - mAmbientLight = new AmbientLight(); - const MaterialPtr& mat = mAmbientLight->getMaterial(); - mat->load(); + // Create lights material generator + mLightMaterialGenerator = new LightMaterialGenerator(); + + // Create the ambient light + mAmbientLight = new AmbientLight(); + const MaterialPtr& mat = mAmbientLight->getMaterial(); + mat->load(); } //----------------------------------------------------------------------- DLight* DeferredLightRenderOperation::createDLight(Ogre::Light* light) { - DLight *rv = new DLight(mLightMaterialGenerator,light); - mLights[light] = rv; - return rv; + DLight *rv = new DLight(mLightMaterialGenerator,light); + mLights[light] = rv; + return rv; } //----------------------------------------------------------------------- void injectTechnique(SceneManager* sm, Technique* tech, Renderable* rend, const Ogre::LightList* lightList) { for(unsigned short i=0; igetNumPasses(); ++i) - { - Ogre::Pass* pass = tech->getPass(i); + { + Ogre::Pass* pass = tech->getPass(i); if (lightList != 0) - { - sm->_injectRenderWithPass(pass, rend, false, false, lightList); - } - else - { - sm->_injectRenderWithPass(pass, rend, false); - } - - } + { + sm->_injectRenderWithPass(pass, rend, false, false, lightList); + } + else + { + sm->_injectRenderWithPass(pass, rend, false); + } + + } } //----------------------------------------------------------------------- void DeferredLightRenderOperation::execute(SceneManager *sm, RenderSystem *rs) { Ogre::Camera* cam = mViewport->getCamera(); - mAmbientLight->updateFromCamera(cam); + mAmbientLight->updateFromCamera(cam); Technique* tech = mAmbientLight->getMaterial()->getBestTechnique(); - injectTechnique(sm, tech, mAmbientLight, 0); + injectTechnique(sm, tech, mAmbientLight, 0); - const LightList& lightList = sm->_getLightsAffectingFrustum(); + const LightList& lightList = sm->_getLightsAffectingFrustum(); for (LightList::const_iterator it = lightList.begin(); it != lightList.end(); it++) - { + { Light* light = *it; - Ogre::LightList ll; - ll.push_back(light); + Ogre::LightList ll; + ll.push_back(light); - //if (++i != 2) continue; + //if (++i != 2) continue; //if (light->getType() != Light::LT_DIRECTIONAL) continue; - //if (light->getDiffuseColour() != ColourValue::Red) continue; + //if (light->getDiffuseColour() != ColourValue::Red) continue; - LightsMap::iterator dLightIt = mLights.find(light); - DLight* dLight = 0; - if (dLightIt == mLights.end()) - { - dLight = createDLight(light); - } - else - { - dLight = dLightIt->second; - dLight->updateFromParent(); - } - dLight->updateFromCamera(cam); - tech = dLight->getMaterial()->getBestTechnique(); + LightsMap::iterator dLightIt = mLights.find(light); + DLight* dLight = 0; + if (dLightIt == mLights.end()) + { + dLight = createDLight(light); + } + else + { + dLight = dLightIt->second; + dLight->updateFromParent(); + } + dLight->updateFromCamera(cam); + tech = dLight->getMaterial()->getBestTechnique(); - //Update shadow texture - if (dLight->getCastChadows()) - { - SceneManager::RenderContext* context = sm->_pauseRendering(); + //Update shadow texture + if (dLight->getCastChadows()) + { + SceneManager::RenderContext* context = sm->_pauseRendering(); - sm->prepareShadowTextures(cam, mViewport, &ll); - sm->_resumeRendering(context); - - Pass* pass = tech->getPass(0); - TextureUnitState* tus = pass->getTextureUnitState("ShadowMap"); - assert(tus); - const TexturePtr& shadowTex = sm->getShadowTexture(0); - if (tus->_getTexturePtr() != shadowTex) - { - tus->_setTexturePtr(shadowTex); - } - - } - + sm->prepareShadowTextures(cam, mViewport, &ll); + sm->_resumeRendering(context); + + Pass* pass = tech->getPass(0); + TextureUnitState* tus = pass->getTextureUnitState("ShadowMap"); + assert(tus); + const TexturePtr& shadowTex = sm->getShadowTexture(0); + if (tus->_getTexturePtr() != shadowTex) + { + tus->_setTexturePtr(shadowTex); + } + + } + injectTechnique(sm, tech, dLight, &ll); - } + } } //----------------------------------------------------------------------- DeferredLightRenderOperation::~DeferredLightRenderOperation() { - for (LightsMap::iterator it = mLights.begin(); it != mLights.end(); ++it) - { - delete it->second; - } - mLights.clear(); - - delete mAmbientLight; - delete mLightMaterialGenerator; + for (LightsMap::iterator it = mLights.begin(); it != mLights.end(); ++it) + { + delete it->second; + } + mLights.clear(); + + delete mAmbientLight; + delete mLightMaterialGenerator; } //----------------------------------------------------------------------- diff --git a/Samples/DeferredShading/src/DeferredShading.cpp b/Samples/DeferredShading/src/DeferredShading.cpp index 5a2c78ee699..855be0ec9f6 100755 --- a/Samples/DeferredShading/src/DeferredShading.cpp +++ b/Samples/DeferredShading/src/DeferredShading.cpp @@ -50,154 +50,154 @@ const Ogre::uint8 DeferredShadingSystem::PRE_GBUFFER_RENDER_QUEUE = Ogre::RENDER const Ogre::uint8 DeferredShadingSystem::POST_GBUFFER_RENDER_QUEUE = Ogre::RENDER_QUEUE_8; DeferredShadingSystem::DeferredShadingSystem( - Viewport *vp, SceneManager *sm, Camera *cam - ): - mViewport(vp), mSceneMgr(sm), mCamera(cam) + Viewport *vp, SceneManager *sm, Camera *cam + ): + mViewport(vp), mSceneMgr(sm), mCamera(cam) { - sm->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE); - sm->setShadowTextureCasterMaterial("DeferredShading/Shadows/Caster"); - mSceneMgr->setShadowTextureCount(1); - mSceneMgr->setShadowFarDistance(150); - //Use a value of "2" to use a different depth buffer pool and avoid sharing this with the Backbuffer's - mSceneMgr->setShadowTextureConfig( 0, 512, 512, PF_FLOAT16_R, 0, 2 ); - mSceneMgr->setShadowDirectionalLightExtrusionDistance(75); + sm->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE); + sm->setShadowTextureCasterMaterial("DeferredShading/Shadows/Caster"); + mSceneMgr->setShadowTextureCount(1); + mSceneMgr->setShadowFarDistance(150); + //Use a value of "2" to use a different depth buffer pool and avoid sharing this with the Backbuffer's + mSceneMgr->setShadowTextureConfig( 0, 512, 512, PF_FLOAT16_R, 0, 2 ); + mSceneMgr->setShadowDirectionalLightExtrusionDistance(75); } void DeferredShadingSystem::initialize() { - for(int i=0; i_removeInstance(mInstance[i]); - CompositorManager::getSingleton().removeCompositorChain(mViewport); - - Ogre::CompositorManager& compMgr = Ogre::CompositorManager::getSingleton(); - CompositorLogicMap::const_iterator itor = mCompositorLogics.begin(); - CompositorLogicMap::const_iterator end = mCompositorLogics.end(); - while( itor != end ) - { - compMgr.unregisterCompositorLogic( itor->first ); - delete itor->second; - ++itor; - } - mCompositorLogics.clear(); + CompositorChain *chain = CompositorManager::getSingleton().getCompositorChain(mViewport); + for(int i=0; i_removeInstance(mInstance[i]); + CompositorManager::getSingleton().removeCompositorChain(mViewport); + + Ogre::CompositorManager& compMgr = Ogre::CompositorManager::getSingleton(); + CompositorLogicMap::const_iterator itor = mCompositorLogics.begin(); + CompositorLogicMap::const_iterator end = mCompositorLogics.end(); + while( itor != end ) + { + compMgr.unregisterCompositorLogic( itor->first ); + delete itor->second; + ++itor; + } + mCompositorLogics.clear(); } void DeferredShadingSystem::setMode(DSMode mode) { - assert( 0 <= mode && mode < DSM_COUNT); - - // prevent duplicate setups - if (mCurrentMode == mode && mInstance[mode]->getEnabled()==mActive) - return; - - for(int i=0; isetEnabled(mActive); - } - else - { - mInstance[i]->setEnabled(false); - } - } - - mCurrentMode = mode; - - mSSAOInstance->setEnabled(mActive && mSSAO && mCurrentMode == DSM_SHOWLIT); + assert( 0 <= mode && mode < DSM_COUNT); + + // prevent duplicate setups + if (mCurrentMode == mode && mInstance[mode]->getEnabled()==mActive) + return; + + for(int i=0; isetEnabled(mActive); + } + else + { + mInstance[i]->setEnabled(false); + } + } + + mCurrentMode = mode; + + mSSAOInstance->setEnabled(mActive && mSSAO && mCurrentMode == DSM_SHOWLIT); } void DeferredShadingSystem::setSSAO(bool ssao) { - if (ssao != mSSAO) - { - mSSAO = ssao; - if (mActive && mCurrentMode == DSM_SHOWLIT) - { - mSSAOInstance->setEnabled(ssao); - } - } + if (ssao != mSSAO) + { + mSSAO = ssao; + if (mActive && mCurrentMode == DSM_SHOWLIT) + { + mSSAOInstance->setEnabled(ssao); + } + } } - + bool DeferredShadingSystem::getSSAO() const { - return mSSAO; + return mSSAO; } void DeferredShadingSystem::setActive(bool active) { - if (mActive != active) - { - mActive = active; - mGBufferInstance->setEnabled(active); - - // mCurrentMode could have changed with a prior call to setMode, so iterate all - setMode(mCurrentMode); - } + if (mActive != active) + { + mActive = active; + mGBufferInstance->setEnabled(active); + + // mCurrentMode could have changed with a prior call to setMode, so iterate all + setMode(mCurrentMode); + } } DeferredShadingSystem::DSMode DeferredShadingSystem::getMode(void) const { - return mCurrentMode; + return mCurrentMode; } void DeferredShadingSystem::createResources(void) { - CompositorManager &compMan = CompositorManager::getSingleton(); - - //Hook up the compositor logic and scheme handlers. - //This can theoretically happen in a loaded plugin, but in this case the demo contains the code. - static bool firstTime = true; - if (firstTime) - { - MaterialManager::getSingleton().addListener(new GBufferSchemeHandler, "GBuffer"); - MaterialManager::getSingleton().addListener(new NullSchemeHandler, "NoGBuffer"); - - compMan.registerCustomCompositionPass("DeferredLight", new DeferredLightCompositionPass); - - firstTime = false; - } - - mCompositorLogics["SSAOLogic"] = new SSAOLogic; - compMan.registerCompositorLogic("SSAOLogic", mCompositorLogics["SSAOLogic"]); - - // Create the main GBuffer compositor - mGBufferInstance = compMan.addCompositor(mViewport, "DeferredShading/GBuffer"); - - // Create filters - mInstance[DSM_SHOWLIT] = compMan.addCompositor(mViewport, "DeferredShading/ShowLit"); - mInstance[DSM_SHOWNORMALS] = compMan.addCompositor(mViewport, "DeferredShading/ShowNormals"); - mInstance[DSM_SHOWDSP] = compMan.addCompositor(mViewport, "DeferredShading/ShowDepthSpecular"); - mInstance[DSM_SHOWCOLOUR] = compMan.addCompositor(mViewport, "DeferredShading/ShowColour"); - - mSSAOInstance = compMan.addCompositor(mViewport, "DeferredShading/SSAO"); + CompositorManager &compMan = CompositorManager::getSingleton(); + + //Hook up the compositor logic and scheme handlers. + //This can theoretically happen in a loaded plugin, but in this case the demo contains the code. + static bool firstTime = true; + if (firstTime) + { + MaterialManager::getSingleton().addListener(new GBufferSchemeHandler, "GBuffer"); + MaterialManager::getSingleton().addListener(new NullSchemeHandler, "NoGBuffer"); + + compMan.registerCustomCompositionPass("DeferredLight", new DeferredLightCompositionPass); + + firstTime = false; + } + + mCompositorLogics["SSAOLogic"] = new SSAOLogic; + compMan.registerCompositorLogic("SSAOLogic", mCompositorLogics["SSAOLogic"]); + + // Create the main GBuffer compositor + mGBufferInstance = compMan.addCompositor(mViewport, "DeferredShading/GBuffer"); + + // Create filters + mInstance[DSM_SHOWLIT] = compMan.addCompositor(mViewport, "DeferredShading/ShowLit"); + mInstance[DSM_SHOWNORMALS] = compMan.addCompositor(mViewport, "DeferredShading/ShowNormals"); + mInstance[DSM_SHOWDSP] = compMan.addCompositor(mViewport, "DeferredShading/ShowDepthSpecular"); + mInstance[DSM_SHOWCOLOUR] = compMan.addCompositor(mViewport, "DeferredShading/ShowColour"); + + mSSAOInstance = compMan.addCompositor(mViewport, "DeferredShading/SSAO"); } void DeferredShadingSystem::logCurrentMode(void) { - if (mActive==false) - { - LogManager::getSingleton().logMessage("No Compositor Enabled!"); - return; - } + if (mActive==false) + { + LogManager::getSingleton().logMessage("No Compositor Enabled!"); + return; + } - CompositorInstance* ci = mInstance[mCurrentMode]; - assert(ci->getEnabled()==true); + CompositorInstance* ci = mInstance[mCurrentMode]; + assert(ci->getEnabled()==true); - LogManager::getSingleton().logMessage("Current Mode: "); - LogManager::getSingleton().logMessage(ci->getCompositor()->getName()); + LogManager::getSingleton().logMessage("Current Mode: "); + LogManager::getSingleton().logMessage(ci->getCompositor()->getName()); } diff --git a/Samples/DeferredShading/src/DeferredShadingDemo.cpp b/Samples/DeferredShading/src/DeferredShadingDemo.cpp index ee022748fdf..b62bba818d8 100755 --- a/Samples/DeferredShading/src/DeferredShadingDemo.cpp +++ b/Samples/DeferredShading/src/DeferredShadingDemo.cpp @@ -1,7 +1,7 @@ /** Demo of Deferred Shading in OGRE using Multiple Render Targets and HLSL/GLSL high level language shaders. - // W.J. :wumpus: van der Laan 2005 // + // W.J. :wumpus: van der Laan 2005 // Deferred shading renders the scene to a 'fat' texture format, using a shader that outputs colour, normal, depth, and possible other attributes per fragment. Multi Render Target is required as we @@ -34,17 +34,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_DeferredShading; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_DeferredShading; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/DeferredShading/src/GBufferMaterialGenerator.cpp b/Samples/DeferredShading/src/GBufferMaterialGenerator.cpp index 571914f25da..96d1e221ea9 100644 --- a/Samples/DeferredShading/src/GBufferMaterialGenerator.cpp +++ b/Samples/DeferredShading/src/GBufferMaterialGenerator.cpp @@ -33,35 +33,35 @@ using namespace Ogre; class GBufferMaterialGeneratorImpl : public MaterialGenerator::Impl { public: - GBufferMaterialGeneratorImpl(const String& baseName) : + GBufferMaterialGeneratorImpl(const String& baseName) : mBaseName(baseName) { mIsSm4 = GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0_level_9_1"); mIsGLSL = (GpuProgramManager::getSingleton().isSyntaxSupported("glsl") || GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) && !(GpuProgramManager::getSingleton().isSyntaxSupported("vs_1_1") || GpuProgramManager::getSingleton().isSyntaxSupported("arbvp1")); } - + protected: - String mBaseName; + String mBaseName; bool mIsSm4; bool mIsGLSL; - virtual GpuProgramPtr generateVertexShader(MaterialGenerator::Perm permutation); - virtual GpuProgramPtr generateFragmentShader(MaterialGenerator::Perm permutation); - virtual MaterialPtr generateTemplateMaterial(MaterialGenerator::Perm permutation); + virtual GpuProgramPtr generateVertexShader(MaterialGenerator::Perm permutation); + virtual GpuProgramPtr generateFragmentShader(MaterialGenerator::Perm permutation); + virtual MaterialPtr generateTemplateMaterial(MaterialGenerator::Perm permutation); }; GBufferMaterialGenerator::GBufferMaterialGenerator() { vsMask = VS_MASK; - fsMask = FS_MASK; - matMask = MAT_MASK; - materialBaseName = "DeferredShading/GBuffer/"; - mImpl = new GBufferMaterialGeneratorImpl(materialBaseName); + fsMask = FS_MASK; + matMask = MAT_MASK; + materialBaseName = "DeferredShading/GBuffer/"; + mImpl = new GBufferMaterialGeneratorImpl(materialBaseName); } GpuProgramPtr GBufferMaterialGeneratorImpl::generateVertexShader(MaterialGenerator::Perm permutation) { - StringStream ss; + StringStream ss; if(mIsGLSL) { @@ -119,22 +119,22 @@ GpuProgramPtr GBufferMaterialGeneratorImpl::generateVertexShader(MaterialGenerat ss << "void main()" << std::endl; ss << "{" << std::endl; - ss << " gl_Position = cWorldViewProj * vertex;" << std::endl; - ss << " oNormal = (cWorldView * vec4(normal,0)).xyz;" << std::endl; + ss << " gl_Position = cWorldViewProj * vertex;" << std::endl; + ss << " oNormal = (cWorldView * vec4(normal,0)).xyz;" << std::endl; if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP) { - ss << " oTangent = (cWorldView * vec4(tangent,0)).xyz;" << std::endl; - ss << " oBiNormal = cross(oNormal, oTangent);" << std::endl; + ss << " oTangent = (cWorldView * vec4(tangent,0)).xyz;" << std::endl; + ss << " oBiNormal = cross(oNormal, oTangent);" << std::endl; } #ifdef WRITE_LINEAR_DEPTH - ss << " oViewPos = (cWorldView * vertex).xyz;" << std::endl; + ss << " oViewPos = (cWorldView * vertex).xyz;" << std::endl; #else - ss << " oDepth = gl_Position.w;" << std::endl; + ss << " oDepth = gl_Position.w;" << std::endl; #endif for (uint32 i=0; i> 8; for (uint32 i=0; i> 8; for (uint32 i=0; i 0 && numTextures > 0) { - ss << " oColor0.rgb = tex2D(sTex0, iUV0).rgb;" << std::endl; + ss << " oColor0.rgb = tex2D(sTex0, iUV0).rgb;" << std::endl; if (permutation & GBufferMaterialGenerator::GBP_HAS_DIFFUSE_COLOUR) { - ss << " oColor0.rgb *= cDiffuseColour.rgb;" << std::endl; + ss << " oColor0.rgb *= cDiffuseColour.rgb;" << std::endl; } } else { - ss << " oColor0.rgb = cDiffuseColour.rgb;" << std::endl; + ss << " oColor0.rgb = cDiffuseColour.rgb;" << std::endl; } - ss << " oColor0.a = cSpecularity;" << std::endl; + ss << " oColor0.a = cSpecularity;" << std::endl; if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP) { - ss << " float3 texNormal = (tex2D(sNormalMap, iUV0).rgb-0.5)*2;" << std::endl; - ss << " float3x3 normalRotation = float3x3(iTangent, iBiNormal, iNormal);" << std::endl; - ss << " oColor1.rgb = normalize(mul(texNormal, normalRotation));" << std::endl; + ss << " float3 texNormal = (tex2D(sNormalMap, iUV0).rgb-0.5)*2;" << std::endl; + ss << " float3x3 normalRotation = float3x3(iTangent, iBiNormal, iNormal);" << std::endl; + ss << " oColor1.rgb = normalize(mul(texNormal, normalRotation));" << std::endl; } else { - ss << " oColor1.rgb = normalize(iNormal);" << std::endl; + ss << " oColor1.rgb = normalize(iNormal);" << std::endl; } #ifdef WRITE_LINEAR_DEPTH - ss << " oColor1.a = length(iViewPos) / cFarDistance;" << std::endl; + ss << " oColor1.a = length(iViewPos) / cFarDistance;" << std::endl; #else - ss << " oColor1.a = iDepth;" << std::endl; + ss << " oColor1.a = iDepth;" << std::endl; #endif ss << "}" << std::endl; @@ -581,22 +581,22 @@ GpuProgramPtr GBufferMaterialGeneratorImpl::generateFragmentShader(MaterialGener MaterialPtr GBufferMaterialGeneratorImpl::generateTemplateMaterial(MaterialGenerator::Perm permutation) { - String matName = mBaseName + "Mat_" + StringConverter::toString(permutation); - - MaterialPtr matPtr = MaterialManager::getSingleton().create - (matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - Pass* pass = matPtr->getTechnique(0)->getPass(0); - pass->setName(mBaseName + "Pass_" + StringConverter::toString(permutation)); - pass->setLightingEnabled(false); - if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP) - { - pass->createTextureUnitState(); - } - uint32 numTextures = permutation & GBufferMaterialGenerator::GBP_TEXTURE_MASK; - for (uint32 i=0; icreateTextureUnitState(); - } - - return matPtr; + String matName = mBaseName + "Mat_" + StringConverter::toString(permutation); + + MaterialPtr matPtr = MaterialManager::getSingleton().create + (matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + Pass* pass = matPtr->getTechnique(0)->getPass(0); + pass->setName(mBaseName + "Pass_" + StringConverter::toString(permutation)); + pass->setLightingEnabled(false); + if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP) + { + pass->createTextureUnitState(); + } + uint32 numTextures = permutation & GBufferMaterialGenerator::GBP_TEXTURE_MASK; + for (uint32 i=0; icreateTextureUnitState(); + } + + return matPtr; } diff --git a/Samples/DeferredShading/src/GBufferSchemeHandler.cpp b/Samples/DeferredShading/src/GBufferSchemeHandler.cpp index d3078d85605..628eac5207f 100644 --- a/Samples/DeferredShading/src/GBufferSchemeHandler.cpp +++ b/Samples/DeferredShading/src/GBufferSchemeHandler.cpp @@ -22,114 +22,114 @@ using namespace Ogre; const String GBufferSchemeHandler::NORMAL_MAP_PATTERN = "normal"; Technique* GBufferSchemeHandler::handleSchemeNotFound(unsigned short schemeIndex, - const String& schemeName, Material* originalMaterial, unsigned short lodIndex, - const Renderable* rend) + const String& schemeName, Material* originalMaterial, unsigned short lodIndex, + const Renderable* rend) { - Ogre::MaterialManager& matMgr = Ogre::MaterialManager::getSingleton(); - String curSchemeName = matMgr.getActiveScheme(); - matMgr.setActiveScheme(MaterialManager::DEFAULT_SCHEME_NAME); - Technique* originalTechnique = originalMaterial->getBestTechnique(lodIndex, rend); - matMgr.setActiveScheme(curSchemeName); - - Technique* gBufferTech = originalMaterial->createTechnique(); - gBufferTech->removeAllPasses(); - gBufferTech->setSchemeName(schemeName); - - Technique* noGBufferTech = originalMaterial->createTechnique(); - noGBufferTech->removeAllPasses(); - noGBufferTech->setSchemeName("NoGBuffer"); - - for (unsigned short i=0; igetNumPasses(); i++) - { - Pass* originalPass = originalTechnique->getPass(i); - PassProperties props = inspectPass(originalPass, lodIndex, rend); - - if (!props.isDeferred) - { - //Just copy the technique so it gets rendered regularly - Pass* clonePass = noGBufferTech->createPass(); - *clonePass = *originalPass; - continue; - } - - Pass* newPass = gBufferTech->createPass(); - MaterialGenerator::Perm perm = getPermutation(props); - - const Ogre::MaterialPtr& templateMat = mMaterialGenerator.getMaterial(perm); - - //We assume that the GBuffer technique contains only one pass. But its true. - *newPass = *(templateMat->getTechnique(0)->getPass(0)); - fillPass(newPass, originalPass, props); - } + Ogre::MaterialManager& matMgr = Ogre::MaterialManager::getSingleton(); + String curSchemeName = matMgr.getActiveScheme(); + matMgr.setActiveScheme(MaterialManager::DEFAULT_SCHEME_NAME); + Technique* originalTechnique = originalMaterial->getBestTechnique(lodIndex, rend); + matMgr.setActiveScheme(curSchemeName); + + Technique* gBufferTech = originalMaterial->createTechnique(); + gBufferTech->removeAllPasses(); + gBufferTech->setSchemeName(schemeName); + + Technique* noGBufferTech = originalMaterial->createTechnique(); + noGBufferTech->removeAllPasses(); + noGBufferTech->setSchemeName("NoGBuffer"); + + for (unsigned short i=0; igetNumPasses(); i++) + { + Pass* originalPass = originalTechnique->getPass(i); + PassProperties props = inspectPass(originalPass, lodIndex, rend); + + if (!props.isDeferred) + { + //Just copy the technique so it gets rendered regularly + Pass* clonePass = noGBufferTech->createPass(); + *clonePass = *originalPass; + continue; + } + + Pass* newPass = gBufferTech->createPass(); + MaterialGenerator::Perm perm = getPermutation(props); + + const Ogre::MaterialPtr& templateMat = mMaterialGenerator.getMaterial(perm); + + //We assume that the GBuffer technique contains only one pass. But its true. + *newPass = *(templateMat->getTechnique(0)->getPass(0)); + fillPass(newPass, originalPass, props); + } - return gBufferTech; + return gBufferTech; } bool GBufferSchemeHandler::checkNormalMap( - TextureUnitState* tus, GBufferSchemeHandler::PassProperties& props) + TextureUnitState* tus, GBufferSchemeHandler::PassProperties& props) { - bool isNormal = false; - Ogre::String lowerCaseAlias = tus->getTextureNameAlias(); - Ogre::StringUtil::toLowerCase(lowerCaseAlias); - if (lowerCaseAlias.find(NORMAL_MAP_PATTERN) != Ogre::String::npos) - { - isNormal = true; - } - else - { - Ogre::String lowerCaseName = tus->getTextureName(); - Ogre::StringUtil::toLowerCase(lowerCaseName); - if (lowerCaseName.find(NORMAL_MAP_PATTERN) != Ogre::String::npos) - { - isNormal = true; - } - } - - if (isNormal) - { - if (props.normalMap == 0) - { - props.normalMap = tus; - } - else - { - OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, - "Multiple normal map patterns matches", - "GBufferSchemeHandler::inspectPass"); - } - } - return isNormal; + bool isNormal = false; + Ogre::String lowerCaseAlias = tus->getTextureNameAlias(); + Ogre::StringUtil::toLowerCase(lowerCaseAlias); + if (lowerCaseAlias.find(NORMAL_MAP_PATTERN) != Ogre::String::npos) + { + isNormal = true; + } + else + { + Ogre::String lowerCaseName = tus->getTextureName(); + Ogre::StringUtil::toLowerCase(lowerCaseName); + if (lowerCaseName.find(NORMAL_MAP_PATTERN) != Ogre::String::npos) + { + isNormal = true; + } + } + + if (isNormal) + { + if (props.normalMap == 0) + { + props.normalMap = tus; + } + else + { + OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, + "Multiple normal map patterns matches", + "GBufferSchemeHandler::inspectPass"); + } + } + return isNormal; } GBufferSchemeHandler::PassProperties GBufferSchemeHandler::inspectPass( - Pass* pass, unsigned short lodIndex, const Renderable* rend) + Pass* pass, unsigned short lodIndex, const Renderable* rend) { - PassProperties props; - - //TODO : Use renderable to indicate whether this has skinning. - //Probably use same const cast that renderSingleObject uses. - if (pass->hasVertexProgram()) - { - props.isSkinned = pass->getVertexProgram()->isSkeletalAnimationIncluded(); - } - else - { - props.isSkinned = false; - } - - for (unsigned short i=0; igetNumTextureUnitStates(); i++) - { - TextureUnitState* tus = pass->getTextureUnitState(i); - if (!checkNormalMap(tus, props)) - { - props.regularTextures.push_back(tus); - } - if (tus->getEffects().size() > 0) - { - props.isDeferred = false; - } - - } + PassProperties props; + + //TODO : Use renderable to indicate whether this has skinning. + //Probably use same const cast that renderSingleObject uses. + if (pass->hasVertexProgram()) + { + props.isSkinned = pass->getVertexProgram()->isSkeletalAnimationIncluded(); + } + else + { + props.isSkinned = false; + } + + for (unsigned short i=0; igetNumTextureUnitStates(); i++) + { + TextureUnitState* tus = pass->getTextureUnitState(i); + if (!checkNormalMap(tus, props)) + { + props.regularTextures.push_back(tus); + } + if (tus->getEffects().size() > 0) + { + props.isDeferred = false; + } + + } if (pass->getDiffuse() != ColourValue::White) { @@ -142,81 +142,81 @@ GBufferSchemeHandler::PassProperties GBufferSchemeHandler::inspectPass( //TODO : Better ways to do this props.isDeferred = false; } - return props; + return props; } MaterialGenerator::Perm GBufferSchemeHandler::getPermutation(const PassProperties& props) { - MaterialGenerator::Perm perm = 0; - switch (props.regularTextures.size()) - { - case 0: - perm |= GBufferMaterialGenerator::GBP_NO_TEXTURES; - - if (props.normalMap != 0) - { - perm |= GBufferMaterialGenerator::GBP_ONE_TEXCOORD; - } - else - { - perm |= GBufferMaterialGenerator::GBP_NO_TEXCOORDS; - } - break; - case 1: - perm |= GBufferMaterialGenerator::GBP_ONE_TEXTURE; - perm |= GBufferMaterialGenerator::GBP_ONE_TEXCOORD; - break; - case 2: - perm |= GBufferMaterialGenerator::GBP_TWO_TEXTURES; - //TODO : When do we use two texcoords? - perm |= GBufferMaterialGenerator::GBP_ONE_TEXCOORD; - break; - case 3: - perm |= GBufferMaterialGenerator::GBP_THREE_TEXTURES; - perm |= GBufferMaterialGenerator::GBP_ONE_TEXCOORD; - break; - default: - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, - "Can not generate G-Buffer materials for '>3 regular-texture' objects", - "GBufferSchemeHandler::inspectPass"); - } - - if (props.isSkinned) - { - perm |= GBufferMaterialGenerator::GBP_SKINNED; - } - - if (props.normalMap != 0) - { - perm |= GBufferMaterialGenerator::GBP_NORMAL_MAP; - } + MaterialGenerator::Perm perm = 0; + switch (props.regularTextures.size()) + { + case 0: + perm |= GBufferMaterialGenerator::GBP_NO_TEXTURES; + + if (props.normalMap != 0) + { + perm |= GBufferMaterialGenerator::GBP_ONE_TEXCOORD; + } + else + { + perm |= GBufferMaterialGenerator::GBP_NO_TEXCOORDS; + } + break; + case 1: + perm |= GBufferMaterialGenerator::GBP_ONE_TEXTURE; + perm |= GBufferMaterialGenerator::GBP_ONE_TEXCOORD; + break; + case 2: + perm |= GBufferMaterialGenerator::GBP_TWO_TEXTURES; + //TODO : When do we use two texcoords? + perm |= GBufferMaterialGenerator::GBP_ONE_TEXCOORD; + break; + case 3: + perm |= GBufferMaterialGenerator::GBP_THREE_TEXTURES; + perm |= GBufferMaterialGenerator::GBP_ONE_TEXCOORD; + break; + default: + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, + "Can not generate G-Buffer materials for '>3 regular-texture' objects", + "GBufferSchemeHandler::inspectPass"); + } + + if (props.isSkinned) + { + perm |= GBufferMaterialGenerator::GBP_SKINNED; + } + + if (props.normalMap != 0) + { + perm |= GBufferMaterialGenerator::GBP_NORMAL_MAP; + } if (props.hasDiffuseColour) { perm |= GBufferMaterialGenerator::GBP_HAS_DIFFUSE_COLOUR; } - return perm; + return perm; } void GBufferSchemeHandler::fillPass( - Pass* gBufferPass, Pass* originalPass, const PassProperties& props) + Pass* gBufferPass, Pass* originalPass, const PassProperties& props) { - //Reference the correct textures. Normal map first! - int texUnitIndex = 0; - if (props.normalMap != 0) - { - *(gBufferPass->getTextureUnitState(texUnitIndex)) = *(props.normalMap); - texUnitIndex++; - } - for (size_t i=0; igetTextureUnitState(texUnitIndex)) = *(props.regularTextures[i]); - texUnitIndex++; - } - gBufferPass->setAmbient(originalPass->getAmbient()); - gBufferPass->setDiffuse(originalPass->getDiffuse()); - gBufferPass->setSpecular(originalPass->getSpecular()); - gBufferPass->setShininess(originalPass->getShininess()); + //Reference the correct textures. Normal map first! + int texUnitIndex = 0; + if (props.normalMap != 0) + { + *(gBufferPass->getTextureUnitState(texUnitIndex)) = *(props.normalMap); + texUnitIndex++; + } + for (size_t i=0; igetTextureUnitState(texUnitIndex)) = *(props.regularTextures[i]); + texUnitIndex++; + } + gBufferPass->setAmbient(originalPass->getAmbient()); + gBufferPass->setDiffuse(originalPass->getDiffuse()); + gBufferPass->setSpecular(originalPass->getSpecular()); + gBufferPass->setShininess(originalPass->getShininess()); gBufferPass->setCullingMode(originalPass->getCullingMode()); gBufferPass->setLightingEnabled(false); } diff --git a/Samples/DeferredShading/src/GeomUtils.cpp b/Samples/DeferredShading/src/GeomUtils.cpp index 8dcaaf37a29..094ecd7340b 100644 --- a/Samples/DeferredShading/src/GeomUtils.cpp +++ b/Samples/DeferredShading/src/GeomUtils.cpp @@ -23,232 +23,232 @@ same license as the rest of the engine. using namespace Ogre; void GeomUtils::createSphere( const String& strName - , float radius - , int nRings, int nSegments - , bool bNormals - , bool bTexCoords) + , float radius + , int nRings, int nSegments + , bool bNormals + , bool bTexCoords) { - MeshPtr pSphere = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - SubMesh *pSphereVertex = pSphere->createSubMesh(); - pSphere->sharedVertexData = new VertexData(); - - createSphere(pSphere->sharedVertexData, pSphereVertex->indexData - , radius - , nRings, nSegments - , bNormals // need normals - , bTexCoords // need texture co-ordinates - ); - - // Generate face list - pSphereVertex->useSharedVertices = true; - - // the original code was missing this line: - pSphere->_setBounds( AxisAlignedBox( Vector3(-radius, -radius, -radius), Vector3(radius, radius, radius) ), false ); - pSphere->_setBoundingSphereRadius(radius); - // this line makes clear the mesh is loaded (avoids memory leaks) - pSphere->load(); + MeshPtr pSphere = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + SubMesh *pSphereVertex = pSphere->createSubMesh(); + pSphere->sharedVertexData = new VertexData(); + + createSphere(pSphere->sharedVertexData, pSphereVertex->indexData + , radius + , nRings, nSegments + , bNormals // need normals + , bTexCoords // need texture co-ordinates + ); + + // Generate face list + pSphereVertex->useSharedVertices = true; + + // the original code was missing this line: + pSphere->_setBounds( AxisAlignedBox( Vector3(-radius, -radius, -radius), Vector3(radius, radius, radius) ), false ); + pSphere->_setBoundingSphereRadius(radius); + // this line makes clear the mesh is loaded (avoids memory leaks) + pSphere->load(); } void GeomUtils::createSphere(VertexData*& vertexData, IndexData*& indexData - , float radius - , int nRings, int nSegments - , bool bNormals - , bool bTexCoords) + , float radius + , int nRings, int nSegments + , bool bNormals + , bool bTexCoords) { - assert(vertexData && indexData); - - // define the vertex format - VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; - size_t currOffset = 0; - // positions - vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); - currOffset += VertexElement::getTypeSize(VET_FLOAT3); - - if (bNormals) - { - // normals - vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); - currOffset += VertexElement::getTypeSize(VET_FLOAT3); - - } - // two dimensional texture coordinates - if (bTexCoords) - { - vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); - } - - // allocate the vertex buffer - vertexData->vertexCount = (nRings + 1) * (nSegments+1); - HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - VertexBufferBinding* binding = vertexData->vertexBufferBinding; - binding->setBinding(0, vBuf); - float* pVertex = static_cast(vBuf->lock(HardwareBuffer::HBL_DISCARD)); - - // allocate index buffer - indexData->indexCount = 6 * nRings * (nSegments + 1); - indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer; - unsigned short* pIndices = static_cast(iBuf->lock(HardwareBuffer::HBL_DISCARD)); - - float fDeltaRingAngle = (Math::PI / nRings); - float fDeltaSegAngle = (2 * Math::PI / nSegments); - unsigned short wVerticeIndex = 0 ; - - // Generate the group of rings for the sphere - for( int ring = 0; ring <= nRings; ring++ ) { - float r0 = radius * sinf (ring * fDeltaRingAngle); - float y0 = radius * cosf (ring * fDeltaRingAngle); - - // Generate the group of segments for the current ring - for(int seg = 0; seg <= nSegments; seg++) { - float x0 = r0 * sinf(seg * fDeltaSegAngle); - float z0 = r0 * cosf(seg * fDeltaSegAngle); - - // Add one vertex to the strip which makes up the sphere - *pVertex++ = x0; - *pVertex++ = y0; - *pVertex++ = z0; - - if (bNormals) - { - Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy(); - *pVertex++ = vNormal.x; - *pVertex++ = vNormal.y; - *pVertex++ = vNormal.z; - } - if (bTexCoords) - { - *pVertex++ = (float) seg / (float) nSegments; - *pVertex++ = (float) ring / (float) nRings; - } - - if (ring != nRings) - { - // each vertex (except the last) has six indices pointing to it - *pIndices++ = wVerticeIndex + nSegments + 1; - *pIndices++ = wVerticeIndex; - *pIndices++ = wVerticeIndex + nSegments; - *pIndices++ = wVerticeIndex + nSegments + 1; - *pIndices++ = wVerticeIndex + 1; - *pIndices++ = wVerticeIndex; - wVerticeIndex ++; - } - }; // end for seg - } // end for ring - - // Unlock - vBuf->unlock(); - iBuf->unlock(); + assert(vertexData && indexData); + + // define the vertex format + VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; + size_t currOffset = 0; + // positions + vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); + currOffset += VertexElement::getTypeSize(VET_FLOAT3); + + if (bNormals) + { + // normals + vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); + currOffset += VertexElement::getTypeSize(VET_FLOAT3); + + } + // two dimensional texture coordinates + if (bTexCoords) + { + vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0); + } + + // allocate the vertex buffer + vertexData->vertexCount = (nRings + 1) * (nSegments+1); + HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + VertexBufferBinding* binding = vertexData->vertexBufferBinding; + binding->setBinding(0, vBuf); + float* pVertex = static_cast(vBuf->lock(HardwareBuffer::HBL_DISCARD)); + + // allocate index buffer + indexData->indexCount = 6 * nRings * (nSegments + 1); + indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer; + unsigned short* pIndices = static_cast(iBuf->lock(HardwareBuffer::HBL_DISCARD)); + + float fDeltaRingAngle = (Math::PI / nRings); + float fDeltaSegAngle = (2 * Math::PI / nSegments); + unsigned short wVerticeIndex = 0 ; + + // Generate the group of rings for the sphere + for( int ring = 0; ring <= nRings; ring++ ) { + float r0 = radius * sinf (ring * fDeltaRingAngle); + float y0 = radius * cosf (ring * fDeltaRingAngle); + + // Generate the group of segments for the current ring + for(int seg = 0; seg <= nSegments; seg++) { + float x0 = r0 * sinf(seg * fDeltaSegAngle); + float z0 = r0 * cosf(seg * fDeltaSegAngle); + + // Add one vertex to the strip which makes up the sphere + *pVertex++ = x0; + *pVertex++ = y0; + *pVertex++ = z0; + + if (bNormals) + { + Vector3 vNormal = Vector3(x0, y0, z0).normalisedCopy(); + *pVertex++ = vNormal.x; + *pVertex++ = vNormal.y; + *pVertex++ = vNormal.z; + } + if (bTexCoords) + { + *pVertex++ = (float) seg / (float) nSegments; + *pVertex++ = (float) ring / (float) nRings; + } + + if (ring != nRings) + { + // each vertex (except the last) has six indices pointing to it + *pIndices++ = wVerticeIndex + nSegments + 1; + *pIndices++ = wVerticeIndex; + *pIndices++ = wVerticeIndex + nSegments; + *pIndices++ = wVerticeIndex + nSegments + 1; + *pIndices++ = wVerticeIndex + 1; + *pIndices++ = wVerticeIndex; + wVerticeIndex ++; + } + }; // end for seg + } // end for ring + + // Unlock + vBuf->unlock(); + iBuf->unlock(); } void GeomUtils::createQuad(VertexData*& vertexData) { - assert(vertexData); - - vertexData->vertexCount = 4; - vertexData->vertexStart = 0; - - VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; - VertexBufferBinding* bind = vertexData->vertexBufferBinding; - - vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); - - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - vertexDecl->getVertexSize(0), - vertexData->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - // Bind buffer - bind->setBinding(0, vbuf); - // Upload data - float data[]={ - -1,1,-1, // corner 1 - -1,-1,-1, // corner 2 - 1,1,-1, // corner 3 - 1,-1,-1}; // corner 4 - vbuf->writeData(0, sizeof(data), data, true); + assert(vertexData); + + vertexData->vertexCount = 4; + vertexData->vertexStart = 0; + + VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; + VertexBufferBinding* bind = vertexData->vertexBufferBinding; + + vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); + + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + vertexDecl->getVertexSize(0), + vertexData->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + + // Bind buffer + bind->setBinding(0, vbuf); + // Upload data + float data[]={ + -1,1,-1, // corner 1 + -1,-1,-1, // corner 2 + 1,1,-1, // corner 3 + 1,-1,-1}; // corner 4 + vbuf->writeData(0, sizeof(data), data, true); } void GeomUtils::createCone(const Ogre::String& strName , float radius , float height, int nVerticesInBase) { - MeshPtr pCone = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - SubMesh *pConeVertex = pCone->createSubMesh(); - pCone->sharedVertexData = new VertexData(); - - createCone(pCone->sharedVertexData, pConeVertex->indexData - , radius - , height - , nVerticesInBase); - - // Generate face list - pConeVertex->useSharedVertices = true; - - // the original code was missing this line: - pCone->_setBounds( AxisAlignedBox( - Vector3(-radius, 0, -radius), - Vector3(radius, height, radius) ), false ); - - pCone->_setBoundingSphereRadius(Math::Sqrt(height*height + radius*radius)); - // this line makes clear the mesh is loaded (avoids memory leaks) - pCone->load(); + MeshPtr pCone = MeshManager::getSingleton().createManual(strName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + SubMesh *pConeVertex = pCone->createSubMesh(); + pCone->sharedVertexData = new VertexData(); + + createCone(pCone->sharedVertexData, pConeVertex->indexData + , radius + , height + , nVerticesInBase); + + // Generate face list + pConeVertex->useSharedVertices = true; + + // the original code was missing this line: + pCone->_setBounds( AxisAlignedBox( + Vector3(-radius, 0, -radius), + Vector3(radius, height, radius) ), false ); + + pCone->_setBoundingSphereRadius(Math::Sqrt(height*height + radius*radius)); + // this line makes clear the mesh is loaded (avoids memory leaks) + pCone->load(); } void GeomUtils::createCone(Ogre::VertexData*& vertexData, Ogre::IndexData*& indexData, - float radius , float height, int nVerticesInBase) + float radius , float height, int nVerticesInBase) { - assert(vertexData && indexData); - - // define the vertex format - VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; - // positions - vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); - - // allocate the vertex buffer - vertexData->vertexCount = nVerticesInBase + 1; - HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - VertexBufferBinding* binding = vertexData->vertexBufferBinding; - binding->setBinding(0, vBuf); - float* pVertex = static_cast(vBuf->lock(HardwareBuffer::HBL_DISCARD)); - - // allocate index buffer - cone and base - indexData->indexCount = (3 * nVerticesInBase) + (3 * (nVerticesInBase - 2)); - indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); - HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer; - unsigned short* pIndices = static_cast(iBuf->lock(HardwareBuffer::HBL_DISCARD)); - - //Positions : cone head and base - for (int i=0; i<3; i++) - *pVertex++ = 0.0f; - - //Base : - float fDeltaBaseAngle = (2 * Math::PI) / nVerticesInBase; - for (int i=0; iunlock(); - iBuf->unlock(); + assert(vertexData && indexData); + + // define the vertex format + VertexDeclaration* vertexDecl = vertexData->vertexDeclaration; + // positions + vertexDecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); + + // allocate the vertex buffer + vertexData->vertexCount = nVerticesInBase + 1; + HardwareVertexBufferSharedPtr vBuf = HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(0), vertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + VertexBufferBinding* binding = vertexData->vertexBufferBinding; + binding->setBinding(0, vBuf); + float* pVertex = static_cast(vBuf->lock(HardwareBuffer::HBL_DISCARD)); + + // allocate index buffer - cone and base + indexData->indexCount = (3 * nVerticesInBase) + (3 * (nVerticesInBase - 2)); + indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); + HardwareIndexBufferSharedPtr iBuf = indexData->indexBuffer; + unsigned short* pIndices = static_cast(iBuf->lock(HardwareBuffer::HBL_DISCARD)); + + //Positions : cone head and base + for (int i=0; i<3; i++) + *pVertex++ = 0.0f; + + //Base : + float fDeltaBaseAngle = (2 * Math::PI) / nVerticesInBase; + for (int i=0; iunlock(); + iBuf->unlock(); } diff --git a/Samples/DeferredShading/src/LightMaterialGenerator.cpp b/Samples/DeferredShading/src/LightMaterialGenerator.cpp index 1c8abbd5e69..0c23659de76 100755 --- a/Samples/DeferredShading/src/LightMaterialGenerator.cpp +++ b/Samples/DeferredShading/src/LightMaterialGenerator.cpp @@ -40,206 +40,206 @@ using namespace Ogre; class LightMaterialGeneratorCG : public MaterialGenerator::Impl { public: - typedef MaterialGenerator::Perm Perm; - LightMaterialGeneratorCG(const String &baseName): - mBaseName(baseName) - { + typedef MaterialGenerator::Perm Perm; + LightMaterialGeneratorCG(const String &baseName): + mBaseName(baseName) + { - } - virtual ~LightMaterialGeneratorCG() - { + } + virtual ~LightMaterialGeneratorCG() + { - } + } - virtual GpuProgramPtr generateVertexShader(Perm permutation) - { + virtual GpuProgramPtr generateVertexShader(Perm permutation) + { String programName = "DeferredShading/post/"; - if (permutation & LightMaterialGenerator::MI_DIRECTIONAL) - { - programName += "vs"; - } - else - { - programName += "LightMaterial_vs"; - } - - GpuProgramPtr ptr = HighLevelGpuProgramManager::getSingleton().getByName(programName); - assert(!ptr.isNull()); - return ptr; - } - - virtual GpuProgramPtr generateFragmentShader(Perm permutation) - { - /// Create shader - if (mMasterSource.empty()) - { - DataStreamPtr ptrMasterSource = ResourceGroupManager::getSingleton().openResource( - "DeferredShading/post/LightMaterial_ps.cg" - , ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - assert(ptrMasterSource.isNull()==false); - mMasterSource = ptrMasterSource->getAsString(); - } - - assert(mMasterSource.empty()==false); - - // Create name - String name = mBaseName+StringConverter::toString(permutation)+"_ps"; - - // Create shader object - HighLevelGpuProgramPtr ptrProgram = HighLevelGpuProgramManager::getSingleton().createProgram( - name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - "cg", GPT_FRAGMENT_PROGRAM); - ptrProgram->setSource(mMasterSource); - ptrProgram->setParameter("entry_point","main"); - ptrProgram->setParameter("profiles","ps_2_x arbfp1"); - // set up the preprocessor defines - // Important to do this before any call to get parameters, i.e. before the program gets loaded - ptrProgram->setParameter("compile_arguments", getPPDefines(permutation)); - - setUpBaseParameters(ptrProgram->getDefaultParameters()); - - return GpuProgramPtr(ptrProgram); - } - - virtual MaterialPtr generateTemplateMaterial(Perm permutation) - { - String materialName = mBaseName; - + if (permutation & LightMaterialGenerator::MI_DIRECTIONAL) + { + programName += "vs"; + } + else + { + programName += "LightMaterial_vs"; + } + + GpuProgramPtr ptr = HighLevelGpuProgramManager::getSingleton().getByName(programName); + assert(!ptr.isNull()); + return ptr; + } + + virtual GpuProgramPtr generateFragmentShader(Perm permutation) + { + /// Create shader + if (mMasterSource.empty()) + { + DataStreamPtr ptrMasterSource = ResourceGroupManager::getSingleton().openResource( + "DeferredShading/post/LightMaterial_ps.cg" + , ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + assert(ptrMasterSource.isNull()==false); + mMasterSource = ptrMasterSource->getAsString(); + } + + assert(mMasterSource.empty()==false); + + // Create name + String name = mBaseName+StringConverter::toString(permutation)+"_ps"; + + // Create shader object + HighLevelGpuProgramPtr ptrProgram = HighLevelGpuProgramManager::getSingleton().createProgram( + name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + "cg", GPT_FRAGMENT_PROGRAM); + ptrProgram->setSource(mMasterSource); + ptrProgram->setParameter("entry_point","main"); + ptrProgram->setParameter("profiles","ps_2_x arbfp1"); + // set up the preprocessor defines + // Important to do this before any call to get parameters, i.e. before the program gets loaded + ptrProgram->setParameter("compile_arguments", getPPDefines(permutation)); + + setUpBaseParameters(ptrProgram->getDefaultParameters()); + + return GpuProgramPtr(ptrProgram); + } + + virtual MaterialPtr generateTemplateMaterial(Perm permutation) + { + String materialName = mBaseName; + if(permutation & LightMaterialGenerator::MI_DIRECTIONAL) - { - materialName += "Quad"; - } - else - { - materialName += "Geometry"; - } - - if(permutation & LightMaterialGenerator::MI_SHADOW_CASTER) - { - materialName += "Shadow"; - } - return MaterialManager::getSingleton().getByName(materialName); - } - - protected: - String mBaseName; + { + materialName += "Quad"; + } + else + { + materialName += "Geometry"; + } + + if(permutation & LightMaterialGenerator::MI_SHADOW_CASTER) + { + materialName += "Shadow"; + } + return MaterialManager::getSingleton().getByName(materialName); + } + + protected: + String mBaseName; String mMasterSource; - // Utility method - String getPPDefines(Perm permutation) - { - String strPPD; - - //Get the type of light - String lightType; - if (permutation & LightMaterialGenerator::MI_POINT) - { - lightType = "POINT"; - } - else if (permutation & LightMaterialGenerator::MI_SPOTLIGHT) - { - lightType = "SPOT"; - } - else if (permutation & LightMaterialGenerator::MI_DIRECTIONAL) - { - lightType = "DIRECTIONAL"; - } - else - { - assert(false && "Permutation must have a light type"); - } - strPPD += "-DLIGHT_TYPE=LIGHT_" + lightType + " "; - - //Optional parameters + // Utility method + String getPPDefines(Perm permutation) + { + String strPPD; + + //Get the type of light + String lightType; + if (permutation & LightMaterialGenerator::MI_POINT) + { + lightType = "POINT"; + } + else if (permutation & LightMaterialGenerator::MI_SPOTLIGHT) + { + lightType = "SPOT"; + } + else if (permutation & LightMaterialGenerator::MI_DIRECTIONAL) + { + lightType = "DIRECTIONAL"; + } + else + { + assert(false && "Permutation must have a light type"); + } + strPPD += "-DLIGHT_TYPE=LIGHT_" + lightType + " "; + + //Optional parameters if (permutation & LightMaterialGenerator::MI_SPECULAR) - { - strPPD += "-DIS_SPECULAR "; - } - if (permutation & LightMaterialGenerator::MI_ATTENUATED) - { - strPPD += "-DIS_ATTENUATED "; - } - if (permutation & LightMaterialGenerator::MI_SHADOW_CASTER) - { - strPPD += "-DIS_SHADOW_CASTER "; - } - return strPPD; - } - - void setUpBaseParameters(const GpuProgramParametersSharedPtr& params) - { - assert(params.isNull()==false); - - struct AutoParamPair { String name; GpuProgramParameters::AutoConstantType type; }; - - //A list of auto params that might be present in the shaders generated - static const AutoParamPair AUTO_PARAMS[] = { - { "vpWidth", GpuProgramParameters::ACT_VIEWPORT_WIDTH }, - { "vpHeight", GpuProgramParameters::ACT_VIEWPORT_HEIGHT }, - { "worldView", GpuProgramParameters::ACT_WORLDVIEW_MATRIX }, - { "invProj", GpuProgramParameters::ACT_INVERSE_PROJECTION_MATRIX }, - { "invView", GpuProgramParameters::ACT_INVERSE_VIEW_MATRIX }, - { "flip", GpuProgramParameters::ACT_RENDER_TARGET_FLIPPING }, - { "lightDiffuseColor", GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR }, - { "lightSpecularColor", GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR }, - { "lightFalloff", GpuProgramParameters::ACT_LIGHT_ATTENUATION }, - { "lightPos", GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE }, - { "lightDir", GpuProgramParameters::ACT_LIGHT_DIRECTION_VIEW_SPACE }, - { "spotParams", GpuProgramParameters::ACT_SPOTLIGHT_PARAMS }, - { "farClipDistance", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE }, - { "shadowViewProjMat", GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX } - }; - int numParams = sizeof(AUTO_PARAMS) / sizeof(AutoParamPair); - - for (int i=0; i_findNamedConstantDefinition(AUTO_PARAMS[i].name)) - { - params->setNamedAutoConstant(AUTO_PARAMS[i].name, AUTO_PARAMS[i].type); - } - } - } + { + strPPD += "-DIS_SPECULAR "; + } + if (permutation & LightMaterialGenerator::MI_ATTENUATED) + { + strPPD += "-DIS_ATTENUATED "; + } + if (permutation & LightMaterialGenerator::MI_SHADOW_CASTER) + { + strPPD += "-DIS_SHADOW_CASTER "; + } + return strPPD; + } + + void setUpBaseParameters(const GpuProgramParametersSharedPtr& params) + { + assert(params.isNull()==false); + + struct AutoParamPair { String name; GpuProgramParameters::AutoConstantType type; }; + + //A list of auto params that might be present in the shaders generated + static const AutoParamPair AUTO_PARAMS[] = { + { "vpWidth", GpuProgramParameters::ACT_VIEWPORT_WIDTH }, + { "vpHeight", GpuProgramParameters::ACT_VIEWPORT_HEIGHT }, + { "worldView", GpuProgramParameters::ACT_WORLDVIEW_MATRIX }, + { "invProj", GpuProgramParameters::ACT_INVERSE_PROJECTION_MATRIX }, + { "invView", GpuProgramParameters::ACT_INVERSE_VIEW_MATRIX }, + { "flip", GpuProgramParameters::ACT_RENDER_TARGET_FLIPPING }, + { "lightDiffuseColor", GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR }, + { "lightSpecularColor", GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR }, + { "lightFalloff", GpuProgramParameters::ACT_LIGHT_ATTENUATION }, + { "lightPos", GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE }, + { "lightDir", GpuProgramParameters::ACT_LIGHT_DIRECTION_VIEW_SPACE }, + { "spotParams", GpuProgramParameters::ACT_SPOTLIGHT_PARAMS }, + { "farClipDistance", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE }, + { "shadowViewProjMat", GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX } + }; + int numParams = sizeof(AUTO_PARAMS) / sizeof(AutoParamPair); + + for (int i=0; i_findNamedConstantDefinition(AUTO_PARAMS[i].name)) + { + params->setNamedAutoConstant(AUTO_PARAMS[i].name, AUTO_PARAMS[i].type); + } + } + } }; //GLSL class LightMaterialGeneratorGLSL : public MaterialGenerator::Impl { public: - typedef MaterialGenerator::Perm Perm; - LightMaterialGeneratorGLSL(const String &baseName): + typedef MaterialGenerator::Perm Perm; + LightMaterialGeneratorGLSL(const String &baseName): mBaseName(baseName) - { + { - } - virtual ~LightMaterialGeneratorGLSL() - { + } + virtual ~LightMaterialGeneratorGLSL() + { - } + } - virtual GpuProgramPtr generateVertexShader(Perm permutation) - { + virtual GpuProgramPtr generateVertexShader(Perm permutation) + { String programName = "DeferredShading/post/"; - if (permutation & LightMaterialGenerator::MI_DIRECTIONAL) - { - programName += "vs"; - } - else - { - programName += "LightMaterial_vs"; - } - - GpuProgramPtr ptr = HighLevelGpuProgramManager::getSingleton().getByName(programName); - assert(!ptr.isNull()); - return ptr; - } - - virtual GpuProgramPtr generateFragmentShader(Perm permutation) - { - /// Create shader - if (mMasterSource.empty()) - { - DataStreamPtr ptrMasterSource; + if (permutation & LightMaterialGenerator::MI_DIRECTIONAL) + { + programName += "vs"; + } + else + { + programName += "LightMaterial_vs"; + } + + GpuProgramPtr ptr = HighLevelGpuProgramManager::getSingleton().getByName(programName); + assert(!ptr.isNull()); + return ptr; + } + + virtual GpuProgramPtr generateFragmentShader(Perm permutation) + { + /// Create shader + if (mMasterSource.empty()) + { + DataStreamPtr ptrMasterSource; if(GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) ptrMasterSource = ResourceGroupManager::getSingleton().openResource("DeferredShading/post/LightMaterial_ps.glsles", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); @@ -247,17 +247,17 @@ class LightMaterialGeneratorGLSL : public MaterialGenerator::Impl ptrMasterSource = ResourceGroupManager::getSingleton().openResource("DeferredShading/post/LightMaterial_ps.glsl", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - assert(ptrMasterSource.isNull()==false); - mMasterSource = ptrMasterSource->getAsString(); - } + assert(ptrMasterSource.isNull()==false); + mMasterSource = ptrMasterSource->getAsString(); + } - assert(mMasterSource.empty()==false); + assert(mMasterSource.empty()==false); - // Create name - String name = mBaseName+StringConverter::toString(permutation)+"_ps"; + // Create name + String name = mBaseName+StringConverter::toString(permutation)+"_ps"; - // Create shader object - HighLevelGpuProgramPtr ptrProgram; + // Create shader object + HighLevelGpuProgramPtr ptrProgram; if(GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) { ptrProgram = HighLevelGpuProgramManager::getSingleton().createProgram(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, @@ -271,14 +271,14 @@ class LightMaterialGeneratorGLSL : public MaterialGenerator::Impl ptrProgram->setParameter("profiles", "glsl150"); } ptrProgram->setSource(mMasterSource); - // set up the preprocessor defines - // Important to do this before any call to get parameters, i.e. before the program gets loaded - ptrProgram->setParameter("preprocessor_defines", getPPDefines(permutation)); + // set up the preprocessor defines + // Important to do this before any call to get parameters, i.e. before the program gets loaded + ptrProgram->setParameter("preprocessor_defines", getPPDefines(permutation)); - setUpBaseParameters(ptrProgram->getDefaultParameters()); + setUpBaseParameters(ptrProgram->getDefaultParameters()); // Bind samplers - GpuProgramParametersSharedPtr params = ptrProgram->getDefaultParameters(); + GpuProgramParametersSharedPtr params = ptrProgram->getDefaultParameters(); int numSamplers = 0; params->setNamedConstant("Tex0", (int)numSamplers++); params->setNamedConstant("Tex1", (int)numSamplers++); @@ -286,28 +286,28 @@ class LightMaterialGeneratorGLSL : public MaterialGenerator::Impl if(permutation & LightMaterialGenerator::MI_SHADOW_CASTER) params->setNamedConstant("ShadowTex", (int)numSamplers++); - return GpuProgramPtr(ptrProgram); - } + return GpuProgramPtr(ptrProgram); + } - virtual MaterialPtr generateTemplateMaterial(Perm permutation) - { - String materialName = mBaseName; + virtual MaterialPtr generateTemplateMaterial(Perm permutation) + { + String materialName = mBaseName; if(permutation & LightMaterialGenerator::MI_DIRECTIONAL) - { - materialName += "Quad"; - } - else - { - materialName += "Geometry"; - } - - if(permutation & LightMaterialGenerator::MI_SHADOW_CASTER) - { - materialName += "Shadow"; - } - return MaterialManager::getSingleton().getByName(materialName); - } + { + materialName += "Quad"; + } + else + { + materialName += "Geometry"; + } + + if(permutation & LightMaterialGenerator::MI_SHADOW_CASTER) + { + materialName += "Shadow"; + } + return MaterialManager::getSingleton().getByName(materialName); + } protected: String mBaseName; @@ -390,12 +390,12 @@ class LightMaterialGeneratorGLSL : public MaterialGenerator::Impl LightMaterialGenerator::LightMaterialGenerator() { - vsMask = 0x00000004; - fsMask = 0x0000003F; - matMask = LightMaterialGenerator::MI_DIRECTIONAL | - LightMaterialGenerator::MI_SHADOW_CASTER; - - materialBaseName = "DeferredShading/LightMaterial/"; + vsMask = 0x00000004; + fsMask = 0x0000003F; + matMask = LightMaterialGenerator::MI_DIRECTIONAL | + LightMaterialGenerator::MI_SHADOW_CASTER; + + materialBaseName = "DeferredShading/LightMaterial/"; if ((GpuProgramManager::getSingleton().isSyntaxSupported("glsl") || GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) && !(GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_x") ||GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1"))) mImpl = new LightMaterialGeneratorGLSL("DeferredShading/LightMaterial/"); diff --git a/Samples/DeferredShading/src/MaterialGenerator.cpp b/Samples/DeferredShading/src/MaterialGenerator.cpp index 068df589c9f..fa9239fbae2 100755 --- a/Samples/DeferredShading/src/MaterialGenerator.cpp +++ b/Samples/DeferredShading/src/MaterialGenerator.cpp @@ -28,89 +28,89 @@ same license as the rest of the engine. using namespace Ogre; MaterialGenerator::MaterialGenerator(): - vsMask(0), fsMask(0), matMask(0), mImpl(0) + vsMask(0), fsMask(0), matMask(0), mImpl(0) { } MaterialGenerator::~MaterialGenerator() { - delete mImpl; + delete mImpl; } const MaterialPtr &MaterialGenerator::getMaterial(Perm permutation) { - /// Check if material/shader permutation already was generated - MaterialMap::iterator i = mMaterials.find(permutation); - if(i != mMaterials.end()) - { - return i->second; - } - else - { - /// Create it - MaterialPtr templ = getTemplateMaterial(permutation & matMask); - GpuProgramPtr vs = getVertexShader(permutation & vsMask); - GpuProgramPtr fs = getFragmentShader(permutation & fsMask); - - /// Create material name - String name = materialBaseName + StringConverter::toString(permutation); - - std::cerr << name << " " << vs->getName() << " " << fs->getName() << std::endl; - /// Create material from template, and set shaders - MaterialPtr mat = templ->clone(name); - Technique *tech = mat->getTechnique(0); - Pass *pass = tech->getPass(0); - pass->setFragmentProgram(fs->getName()); - pass->setVertexProgram(vs->getName()); - - /// And store it - mMaterials[permutation] = mat; - return mMaterials[permutation]; - } + /// Check if material/shader permutation already was generated + MaterialMap::iterator i = mMaterials.find(permutation); + if(i != mMaterials.end()) + { + return i->second; + } + else + { + /// Create it + MaterialPtr templ = getTemplateMaterial(permutation & matMask); + GpuProgramPtr vs = getVertexShader(permutation & vsMask); + GpuProgramPtr fs = getFragmentShader(permutation & fsMask); + + /// Create material name + String name = materialBaseName + StringConverter::toString(permutation); + + std::cerr << name << " " << vs->getName() << " " << fs->getName() << std::endl; + /// Create material from template, and set shaders + MaterialPtr mat = templ->clone(name); + Technique *tech = mat->getTechnique(0); + Pass *pass = tech->getPass(0); + pass->setFragmentProgram(fs->getName()); + pass->setVertexProgram(vs->getName()); + + /// And store it + mMaterials[permutation] = mat; + return mMaterials[permutation]; + } } const GpuProgramPtr &MaterialGenerator::getVertexShader(Perm permutation) { - ProgramMap::iterator i = mVs.find(permutation); - if(i != mVs.end()) - { - return i->second; - } - else - { - /// Create it - mVs[permutation] = mImpl->generateVertexShader(permutation); - return mVs[permutation]; - } + ProgramMap::iterator i = mVs.find(permutation); + if(i != mVs.end()) + { + return i->second; + } + else + { + /// Create it + mVs[permutation] = mImpl->generateVertexShader(permutation); + return mVs[permutation]; + } } const GpuProgramPtr &MaterialGenerator::getFragmentShader(Perm permutation) { - ProgramMap::iterator i = mFs.find(permutation); - if(i != mFs.end()) - { - return i->second; - } - else - { - /// Create it - mFs[permutation] = mImpl->generateFragmentShader(permutation); - return mFs[permutation]; - } + ProgramMap::iterator i = mFs.find(permutation); + if(i != mFs.end()) + { + return i->second; + } + else + { + /// Create it + mFs[permutation] = mImpl->generateFragmentShader(permutation); + return mFs[permutation]; + } } const MaterialPtr &MaterialGenerator::getTemplateMaterial(Perm permutation) { - MaterialMap::iterator i = mTemplateMat.find(permutation); - if(i != mTemplateMat.end()) - { - return i->second; - } - else - { - /// Create it - mTemplateMat[permutation] = mImpl->generateTemplateMaterial(permutation); - return mTemplateMat[permutation]; - } + MaterialMap::iterator i = mTemplateMat.find(permutation); + if(i != mTemplateMat.end()) + { + return i->second; + } + else + { + /// Create it + mTemplateMat[permutation] = mImpl->generateTemplateMaterial(permutation); + return mTemplateMat[permutation]; + } } MaterialGenerator::Impl::~Impl() diff --git a/Samples/DeferredShading/src/SSAOLogic.cpp b/Samples/DeferredShading/src/SSAOLogic.cpp index ca858f75c8b..747fb87c3e1 100644 --- a/Samples/DeferredShading/src/SSAOLogic.cpp +++ b/Samples/DeferredShading/src/SSAOLogic.cpp @@ -20,17 +20,17 @@ using namespace Ogre; class ssaoListener: public Ogre::CompositorInstance::Listener { public: - - ssaoListener(Ogre::CompositorInstance* instance) : mInstance(instance) {} + + ssaoListener(Ogre::CompositorInstance* instance) : mInstance(instance) {} - // this callback we will use to modify SSAO parameters + // this callback we will use to modify SSAO parameters void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) { if (pass_id != 42) // not SSAO, return return; // this is the camera you're using - Ogre::Camera *cam = mInstance->getChain()->getViewport()->getCamera(); + Ogre::Camera *cam = mInstance->getChain()->getViewport()->getCamera(); // calculate the far-top-right corner in view-space Ogre::Vector3 farCorner = cam->getViewMatrix(true) * cam->getWorldSpaceCorners()[4]; @@ -58,10 +58,10 @@ class ssaoListener: public Ogre::CompositorInstance::Listener params->setNamedConstant("far", cam->getFarClipDistance()); } private: - Ogre::CompositorInstance* mInstance; + Ogre::CompositorInstance* mInstance; }; Ogre::CompositorInstance::Listener* SSAOLogic::createListener(Ogre::CompositorInstance* instance) { - return new ssaoListener(instance); + return new ssaoListener(instance); } diff --git a/Samples/Dot3Bump/include/Dot3Bump.h b/Samples/Dot3Bump/include/Dot3Bump.h index 7a0a3be3a4a..557157fa8e9 100644 --- a/Samples/Dot3Bump/include/Dot3Bump.h +++ b/Samples/Dot3Bump/include/Dot3Bump.h @@ -11,300 +11,300 @@ class _OgreSampleClassExport Sample_Dot3Bump : public SdkSample { public: - Sample_Dot3Bump() - : mMoveLights (true) - { - mInfo["Title"] = "Bump Mapping"; - mInfo["Description"] = "Shows how to use the dot product blending operation and normalization cube map " - "to achieve a bump mapping effect. Tangent space computations made through the guide of the tutorial " - "on bump mapping from http://users.ox.ac.uk/~univ1234 by paul.baker@univ.ox.ac.uk."; - mInfo["Thumbnail"] = "thumb_bump.png"; - mInfo["Category"] = "Lighting"; - mInfo["Help"] = "Left click and drag anywhere in the scene to look around. Let go again to show " - "cursor and access widgets. Use WASD keys to move."; - } - - StringVector getRequiredPlugins() - { - StringVector names; + Sample_Dot3Bump() + : mMoveLights (true) + { + mInfo["Title"] = "Bump Mapping"; + mInfo["Description"] = "Shows how to use the dot product blending operation and normalization cube map " + "to achieve a bump mapping effect. Tangent space computations made through the guide of the tutorial " + "on bump mapping from http://users.ox.ac.uk/~univ1234 by paul.baker@univ.ox.ac.uk."; + mInfo["Thumbnail"] = "thumb_bump.png"; + mInfo["Category"] = "Lighting"; + mInfo["Help"] = "Left click and drag anywhere in the scene to look around. Let go again to show " + "cursor and access widgets. Use WASD keys to move."; + } + + StringVector getRequiredPlugins() + { + StringVector names; if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl")) names.push_back("Cg Program Manager"); - return names; - } + return names; + } - void testCapabilities(const RenderSystemCapabilities* caps) - { - if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM))) + void testCapabilities(const RenderSystemCapabilities* caps) + { + if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM))) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment programs, " - "so you cannot run this sample. Sorry!", "Dot3BumpSample::testCapabilities"); + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment programs, " + "so you cannot run this sample. Sorry!", "Dot3BumpSample::testCapabilities"); } - if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0") && + if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl") && - !GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model needed for this sample, " - "so you cannot run this sample. Sorry!", "Dot3BumpSample::testCapabilities"); - } - } - - bool frameRenderingQueued(const FrameEvent& evt) - { - if (mMoveLights) - { - // rotate the light pivots - mLightPivot1->roll(Degree(evt.timeSinceLastFrame * 30)); - mLightPivot2->roll(Degree(evt.timeSinceLastFrame * 10)); - } - - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! - } - - void itemSelected(SelectMenu* menu) - { - if (menu == mMeshMenu) - { - // change to the selected entity - mObjectNode->detachAllObjects(); - mObjectNode->attachObject(mSceneMgr->getEntity(mMeshMenu->getSelectedItem())); - - // remember which material is currently selected - int index = std::max(0, mMaterialMenu->getSelectionIndex()); - - // update the material menu's options - mMaterialMenu->setItems(mPossibilities[mMeshMenu->getSelectedItem()]); - - mMaterialMenu->selectItem(index); // select the material with the saved index - } - else - { - // set the selected material for the active mesh - ((Entity*)mObjectNode->getAttachedObject(0))->setMaterialName(menu->getSelectedItem()); - } - } - - void checkBoxToggled(CheckBox* box) - { - if (StringUtil::startsWith(box->getName(), "Light", false)) - { - // get the light pivot that corresponds to this checkbox - SceneNode* pivot = box->getName() == "Light1" ? mLightPivot1 : mLightPivot2; - SceneNode::ObjectIterator it = pivot->getAttachedObjectIterator(); - - while (it.hasMoreElements()) // toggle visibility of light and billboard set - { - MovableObject* o = it.getNext(); - o->setVisible(box->isChecked()); - } - - } - else if (box->getName() == "MoveLights") - { - mMoveLights = !mMoveLights; - } - } + !GpuProgramManager::getSingleton().isSyntaxSupported("glsles")) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model needed for this sample, " + "so you cannot run this sample. Sorry!", "Dot3BumpSample::testCapabilities"); + } + } + + bool frameRenderingQueued(const FrameEvent& evt) + { + if (mMoveLights) + { + // rotate the light pivots + mLightPivot1->roll(Degree(evt.timeSinceLastFrame * 30)); + mLightPivot2->roll(Degree(evt.timeSinceLastFrame * 10)); + } + + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + } + + void itemSelected(SelectMenu* menu) + { + if (menu == mMeshMenu) + { + // change to the selected entity + mObjectNode->detachAllObjects(); + mObjectNode->attachObject(mSceneMgr->getEntity(mMeshMenu->getSelectedItem())); + + // remember which material is currently selected + int index = std::max(0, mMaterialMenu->getSelectionIndex()); + + // update the material menu's options + mMaterialMenu->setItems(mPossibilities[mMeshMenu->getSelectedItem()]); + + mMaterialMenu->selectItem(index); // select the material with the saved index + } + else + { + // set the selected material for the active mesh + ((Entity*)mObjectNode->getAttachedObject(0))->setMaterialName(menu->getSelectedItem()); + } + } + + void checkBoxToggled(CheckBox* box) + { + if (StringUtil::startsWith(box->getName(), "Light", false)) + { + // get the light pivot that corresponds to this checkbox + SceneNode* pivot = box->getName() == "Light1" ? mLightPivot1 : mLightPivot2; + SceneNode::ObjectIterator it = pivot->getAttachedObjectIterator(); + + while (it.hasMoreElements()) // toggle visibility of light and billboard set + { + MovableObject* o = it.getNext(); + o->setVisible(box->isChecked()); + } + + } + else if (box->getName() == "MoveLights") + { + mMoveLights = !mMoveLights; + } + } protected: - void setupContent() - { - // create our main node to attach our entities to - mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + void setupContent() + { + // create our main node to attach our entities to + mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - setupModels(); - setupLights(); - setupControls(); + setupModels(); + setupLights(); + setupControls(); - mCamera->setPosition(0, 0, 500); + mCamera->setPosition(0, 0, 500); #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS - setDragLook(true); + setDragLook(true); #endif - } + } - void loadResources() - { + void loadResources() + { #ifdef INCLUDE_RTSHADER_SYSTEM - Ogre::StringVector groupVector = Ogre::ResourceGroupManager::getSingleton().getResourceGroups(); - Ogre::StringVector::iterator itGroup = groupVector.begin(); - Ogre::StringVector::iterator itGroupEnd = groupVector.end(); - Ogre::String shaderCoreLibsPath; - - - for (; itGroup != itGroupEnd; ++itGroup) - { - Ogre::ResourceGroupManager::LocationList resLocationsList = Ogre::ResourceGroupManager::getSingleton().getResourceLocationList(*itGroup); - Ogre::ResourceGroupManager::LocationList::iterator it = resLocationsList.begin(); - Ogre::ResourceGroupManager::LocationList::iterator itEnd = resLocationsList.end(); - bool coreLibsFound = false; - - // Find the location of the core shader libs - for (; it != itEnd; ++it) - { - if ((*it)->archive->getName().find("RTShaderLib") != Ogre::String::npos) - { - shaderCoreLibsPath = (*it)->archive->getName() + "/"; - coreLibsFound = true; - break; - } - } - - // Core libs path found in the current group. - if (coreLibsFound) - break; - } - + Ogre::StringVector groupVector = Ogre::ResourceGroupManager::getSingleton().getResourceGroups(); + Ogre::StringVector::iterator itGroup = groupVector.begin(); + Ogre::StringVector::iterator itGroupEnd = groupVector.end(); + Ogre::String shaderCoreLibsPath; + + + for (; itGroup != itGroupEnd; ++itGroup) + { + Ogre::ResourceGroupManager::LocationList resLocationsList = Ogre::ResourceGroupManager::getSingleton().getResourceLocationList(*itGroup); + Ogre::ResourceGroupManager::LocationList::iterator it = resLocationsList.begin(); + Ogre::ResourceGroupManager::LocationList::iterator itEnd = resLocationsList.end(); + bool coreLibsFound = false; + + // Find the location of the core shader libs + for (; it != itEnd; ++it) + { + if ((*it)->archive->getName().find("RTShaderLib") != Ogre::String::npos) + { + shaderCoreLibsPath = (*it)->archive->getName() + "/"; + coreLibsFound = true; + break; + } + } + + // Core libs path found in the current group. + if (coreLibsFound) + break; + } + #endif - } + } - void unloadResources() - { + void unloadResources() + { - } + } - void setupModels() - { - StringVector matNames; + void setupModels() + { + StringVector matNames; - matNames.push_back("Examples/BumpMapping/MultiLight"); - matNames.push_back("Examples/BumpMapping/MultiLightSpecular"); - matNames.push_back("Examples/OffsetMapping/Specular"); - matNames.push_back("Examples/ShowUV"); - matNames.push_back("Examples/ShowNormals"); - matNames.push_back("Examples/ShowTangents"); + matNames.push_back("Examples/BumpMapping/MultiLight"); + matNames.push_back("Examples/BumpMapping/MultiLightSpecular"); + matNames.push_back("Examples/OffsetMapping/Specular"); + matNames.push_back("Examples/ShowUV"); + matNames.push_back("Examples/ShowNormals"); + matNames.push_back("Examples/ShowTangents"); #ifdef INCLUDE_RTSHADER_SYSTEM - matNames.push_back("RTSS/NormalMapping_SinglePass"); - matNames.push_back("RTSS/NormalMapping_MultiPass"); + matNames.push_back("RTSS/NormalMapping_SinglePass"); + matNames.push_back("RTSS/NormalMapping_MultiPass"); #endif - - mPossibilities["ogrehead.mesh"] = matNames; - mPossibilities["knot.mesh"] = matNames; - - matNames.clear(); - matNames.push_back("Examples/Athene/NormalMapped"); - matNames.push_back("Examples/Athene/NormalMappedSpecular"); - matNames.push_back("Examples/Athene/NormalMappedSpecular"); - matNames.push_back("Examples/ShowUV"); - matNames.push_back("Examples/ShowNormals"); - matNames.push_back("Examples/ShowTangents"); + + mPossibilities["ogrehead.mesh"] = matNames; + mPossibilities["knot.mesh"] = matNames; + + matNames.clear(); + matNames.push_back("Examples/Athene/NormalMapped"); + matNames.push_back("Examples/Athene/NormalMappedSpecular"); + matNames.push_back("Examples/Athene/NormalMappedSpecular"); + matNames.push_back("Examples/ShowUV"); + matNames.push_back("Examples/ShowNormals"); + matNames.push_back("Examples/ShowTangents"); #ifdef INCLUDE_RTSHADER_SYSTEM - matNames.push_back("RTSS/Athene/NormalMapping_SinglePass"); - matNames.push_back("RTSS/Athene/NormalMapping_MultiPass"); + matNames.push_back("RTSS/Athene/NormalMapping_SinglePass"); + matNames.push_back("RTSS/Athene/NormalMapping_MultiPass"); #endif - mPossibilities["athene.mesh"] = matNames; + mPossibilities["athene.mesh"] = matNames; - for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) - { - // load each mesh with non-default hardware buffer usage options - MeshPtr mesh = MeshManager::getSingleton().load(it->first, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); + for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) + { + // load each mesh with non-default hardware buffer usage options + MeshPtr mesh = MeshManager::getSingleton().load(it->first, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // build tangent vectors for our mesh unsigned short src, dest; if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) { mesh->buildTangentVectors(VES_TANGENT, src, dest); - // this version cleans mirrored and rotated UVs but requires quality models - // mesh->buildTangentVectors(VES_TANGENT, src, dest, true, true); + // this version cleans mirrored and rotated UVs but requires quality models + // mesh->buildTangentVectors(VES_TANGENT, src, dest, true, true); } - // create an entity from the mesh and set the first available material - Entity* ent = mSceneMgr->createEntity(mesh->getName(), mesh->getName()); - ent->setMaterialName(it->second.front()); - } - } - - void setupLights() - { - mSceneMgr->setAmbientLight(ColourValue::Black); // disable ambient lighting - - // create pivot nodes - mLightPivot1 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mLightPivot2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - - Light* l; - BillboardSet* bbs; - - // create white light - l = mSceneMgr->createLight(); - l->setPosition(200, 0, 0); - l->setDiffuseColour(1, 1, 1); - l->setSpecularColour(1, 1, 1); - // create white flare - bbs = mSceneMgr->createBillboardSet(); - bbs->setMaterialName("Examples/Flare"); - bbs->createBillboard(200, 0, 0)->setColour(ColourValue::White); - - mLightPivot1->attachObject(l); - mLightPivot1->attachObject(bbs); - - // create red light - l = mSceneMgr->createLight(); - l->setPosition(40, 200, 50); - l->setDiffuseColour(1, 0, 0); - l->setSpecularColour(1, 0.8, 0.8); - // create white flare - bbs = mSceneMgr->createBillboardSet(); - bbs->setMaterialName("Examples/Flare"); - bbs->createBillboard(50, 200, 50)->setColour(ColourValue::Red); - - mLightPivot2->attachObject(l); - mLightPivot2->attachObject(bbs); - } - - void setupControls() - { - mTrayMgr->showCursor(); - - // make room for the controls - mTrayMgr->showLogo(TL_TOPRIGHT); - mTrayMgr->showFrameStats(TL_TOPRIGHT); - mTrayMgr->toggleAdvancedFrameStats(); - - // create a menu to choose the model displayed - mMeshMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "Mesh", "Mesh", 370, 290, 10); - for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) - mMeshMenu->addItem(it->first); - - // create a menu to choose the material used by the model - mMaterialMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "Material", "Material", 370, 290, 10); - - // create checkboxes to toggle lights - mTrayMgr->createCheckBox(TL_TOPLEFT, "Light1", "Light A")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Light2", "Light B")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "MoveLights", "Move Lights")->setChecked(true, false); - - // a friendly reminder - StringVector names; - names.push_back("Help"); - mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); - - mMeshMenu->selectItem(0); // select first mesh - } - - void cleanupContent() - { - // clean up properly to avoid interfering with subsequent samples - for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) - MeshManager::getSingleton().unload(it->first); - mPossibilities.clear(); - } - - std::map mPossibilities; - SceneNode* mObjectNode; - SceneNode* mLightPivot1; - SceneNode* mLightPivot2; - bool mMoveLights; - SelectMenu* mMeshMenu; - SelectMenu* mMaterialMenu; + // create an entity from the mesh and set the first available material + Entity* ent = mSceneMgr->createEntity(mesh->getName(), mesh->getName()); + ent->setMaterialName(it->second.front()); + } + } + + void setupLights() + { + mSceneMgr->setAmbientLight(ColourValue::Black); // disable ambient lighting + + // create pivot nodes + mLightPivot1 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mLightPivot2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + + Light* l; + BillboardSet* bbs; + + // create white light + l = mSceneMgr->createLight(); + l->setPosition(200, 0, 0); + l->setDiffuseColour(1, 1, 1); + l->setSpecularColour(1, 1, 1); + // create white flare + bbs = mSceneMgr->createBillboardSet(); + bbs->setMaterialName("Examples/Flare"); + bbs->createBillboard(200, 0, 0)->setColour(ColourValue::White); + + mLightPivot1->attachObject(l); + mLightPivot1->attachObject(bbs); + + // create red light + l = mSceneMgr->createLight(); + l->setPosition(40, 200, 50); + l->setDiffuseColour(1, 0, 0); + l->setSpecularColour(1, 0.8, 0.8); + // create white flare + bbs = mSceneMgr->createBillboardSet(); + bbs->setMaterialName("Examples/Flare"); + bbs->createBillboard(50, 200, 50)->setColour(ColourValue::Red); + + mLightPivot2->attachObject(l); + mLightPivot2->attachObject(bbs); + } + + void setupControls() + { + mTrayMgr->showCursor(); + + // make room for the controls + mTrayMgr->showLogo(TL_TOPRIGHT); + mTrayMgr->showFrameStats(TL_TOPRIGHT); + mTrayMgr->toggleAdvancedFrameStats(); + + // create a menu to choose the model displayed + mMeshMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "Mesh", "Mesh", 370, 290, 10); + for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) + mMeshMenu->addItem(it->first); + + // create a menu to choose the material used by the model + mMaterialMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "Material", "Material", 370, 290, 10); + + // create checkboxes to toggle lights + mTrayMgr->createCheckBox(TL_TOPLEFT, "Light1", "Light A")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Light2", "Light B")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "MoveLights", "Move Lights")->setChecked(true, false); + + // a friendly reminder + StringVector names; + names.push_back("Help"); + mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); + + mMeshMenu->selectItem(0); // select first mesh + } + + void cleanupContent() + { + // clean up properly to avoid interfering with subsequent samples + for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) + MeshManager::getSingleton().unload(it->first); + mPossibilities.clear(); + } + + std::map mPossibilities; + SceneNode* mObjectNode; + SceneNode* mLightPivot1; + SceneNode* mLightPivot2; + bool mMoveLights; + SelectMenu* mMeshMenu; + SelectMenu* mMaterialMenu; }; #endif diff --git a/Samples/Dot3Bump/src/Dot3Bump.cpp b/Samples/Dot3Bump/src/Dot3Bump.cpp index fa60daef224..112fb18bab8 100644 --- a/Samples/Dot3Bump/src/Dot3Bump.cpp +++ b/Samples/Dot3Bump/src/Dot3Bump.cpp @@ -11,17 +11,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Dot3Bump; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Dot3Bump; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/DualQuaternion/src/DualQuaternion.cpp b/Samples/DualQuaternion/src/DualQuaternion.cpp index 67e1ab8813a..56f3156e937 100644 --- a/Samples/DualQuaternion/src/DualQuaternion.cpp +++ b/Samples/DualQuaternion/src/DualQuaternion.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_DualQuaternion; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_DualQuaternion; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/DynTex/include/DynTex.h b/Samples/DynTex/include/DynTex.h index 2fefdf38ac2..54fe65e9b5c 100644 --- a/Samples/DynTex/include/DynTex.h +++ b/Samples/DynTex/include/DynTex.h @@ -11,196 +11,196 @@ class _OgreSampleClassExport Sample_DynTex : public SdkSample { public: - Sample_DynTex() : TEXTURE_SIZE(128), SQR_BRUSH_RADIUS(Math::Sqr(12)) - { - mInfo["Title"] = "Dynamic Texturing"; - mInfo["Description"] = "Demonstrates how to create and use dynamically changing textures."; - mInfo["Thumbnail"] = "thumb_dyntex.png"; - mInfo["Category"] = "Unsorted"; - mInfo["Help"] = "Use the left mouse button to wipe away the frost. " - "It's cold though, so the frost will return after a while."; - } + Sample_DynTex() : TEXTURE_SIZE(128), SQR_BRUSH_RADIUS(Math::Sqr(12)) + { + mInfo["Title"] = "Dynamic Texturing"; + mInfo["Description"] = "Demonstrates how to create and use dynamically changing textures."; + mInfo["Thumbnail"] = "thumb_dyntex.png"; + mInfo["Category"] = "Unsorted"; + mInfo["Help"] = "Use the left mouse button to wipe away the frost. " + "It's cold though, so the frost will return after a while."; + } StringVector getRequiredPlugins() - { - StringVector names; + { + StringVector names; if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl150")) names.push_back("Cg Program Manager"); - return names; - } - - bool frameRenderingQueued(const FrameEvent& evt) - { - // shoot a ray from the cursor to the plane - Ray ray = mTrayMgr->getCursorRay(mCamera); - mCursorQuery->setRay(ray); - RaySceneQueryResult& result = mCursorQuery->execute(); - - if (!result.empty()) - { - // using the point of intersection, find the corresponding texel on our texture - Vector3 pt = ray.getPoint(result.back().distance); - mBrushPos = (Vector2(pt.x, -pt.y) / mPlaneSize + Vector2(0.5, 0.5)) * TEXTURE_SIZE; - } - - uint8 freezeAmount = 0; - mTimeSinceLastFreeze += evt.timeSinceLastFrame; - - // find out how much to freeze the plane based on time passed - while (mTimeSinceLastFreeze >= 0.1) - { - mTimeSinceLastFreeze -= 0.1; - freezeAmount += 0x04; - } - - updateTexture(freezeAmount); // rebuild texture contents - - mPenguinAnimState->addTime(evt.timeSinceLastFrame); // increment penguin idle animation time - mPenguinNode->yaw(Radian(evt.timeSinceLastFrame)); // spin the penguin around - - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! - } + return names; + } + + bool frameRenderingQueued(const FrameEvent& evt) + { + // shoot a ray from the cursor to the plane + Ray ray = mTrayMgr->getCursorRay(mCamera); + mCursorQuery->setRay(ray); + RaySceneQueryResult& result = mCursorQuery->execute(); + + if (!result.empty()) + { + // using the point of intersection, find the corresponding texel on our texture + Vector3 pt = ray.getPoint(result.back().distance); + mBrushPos = (Vector2(pt.x, -pt.y) / mPlaneSize + Vector2(0.5, 0.5)) * TEXTURE_SIZE; + } + + uint8 freezeAmount = 0; + mTimeSinceLastFreeze += evt.timeSinceLastFrame; + + // find out how much to freeze the plane based on time passed + while (mTimeSinceLastFreeze >= 0.1) + { + mTimeSinceLastFreeze -= 0.1; + freezeAmount += 0x04; + } + + updateTexture(freezeAmount); // rebuild texture contents + + mPenguinAnimState->addTime(evt.timeSinceLastFrame); // increment penguin idle animation time + mPenguinNode->yaw(Radian(evt.timeSinceLastFrame)); // spin the penguin around + + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + } #if (OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS) || (OGRE_PLATFORM == OGRE_PLATFORM_ANDROID) - bool touchPressed(const OIS::MultiTouchEvent& evt) - { - if (mTrayMgr->injectMouseDown(evt)) return true; - mWiping = true; // wipe frost if user left clicks in the scene - return true; - } - - bool touchReleased(const OIS::MultiTouchEvent& evt) - { - if (mTrayMgr->injectMouseUp(evt)) return true; - mWiping = false; // stop wiping frost if user releases LMB - return true; - } + bool touchPressed(const OIS::MultiTouchEvent& evt) + { + if (mTrayMgr->injectMouseDown(evt)) return true; + mWiping = true; // wipe frost if user left clicks in the scene + return true; + } + + bool touchReleased(const OIS::MultiTouchEvent& evt) + { + if (mTrayMgr->injectMouseUp(evt)) return true; + mWiping = false; // stop wiping frost if user releases LMB + return true; + } #else - bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id) - { - if (mTrayMgr->injectMouseDown(evt, id)) return true; - mWiping = true; // wipe frost if user left clicks in the scene - return true; - } + bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + { + if (mTrayMgr->injectMouseDown(evt, id)) return true; + mWiping = true; // wipe frost if user left clicks in the scene + return true; + } - bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id) - { - if (mTrayMgr->injectMouseUp(evt, id)) return true; - mWiping = false; // stop wiping frost if user releases LMB - return true; - } + bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id) + { + if (mTrayMgr->injectMouseUp(evt, id)) return true; + mWiping = false; // stop wiping frost if user releases LMB + return true; + } #endif protected: - void setupContent() - { - mSceneMgr->setSkyBox(true, "Examples/StormySkyBox"); // add a skybox + void setupContent() + { + mSceneMgr->setSkyBox(true, "Examples/StormySkyBox"); // add a skybox - // setup some basic lighting for our scene - mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); + // setup some basic lighting for our scene + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); mSceneMgr->createLight()->setPosition(20, 80, 50); - // set initial camera position - mCameraMan->setStyle(CS_MANUAL); - mCamera->setPosition(0, 0, 200); + // set initial camera position + mCameraMan->setStyle(CS_MANUAL); + mCamera->setPosition(0, 0, 200); - mTrayMgr->showCursor(); + mTrayMgr->showCursor(); - // create our dynamic texture with 8-bit luminance texels - TexturePtr tex = TextureManager::getSingleton().createManual("thaw", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - TEX_TYPE_2D, TEXTURE_SIZE, TEXTURE_SIZE, 0, PF_L8, TU_DYNAMIC_WRITE_ONLY); + // create our dynamic texture with 8-bit luminance texels + TexturePtr tex = TextureManager::getSingleton().createManual("thaw", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + TEX_TYPE_2D, TEXTURE_SIZE, TEXTURE_SIZE, 0, PF_L8, TU_DYNAMIC_WRITE_ONLY); - mTexBuf = tex->getBuffer(); // save off the texture buffer + mTexBuf = tex->getBuffer(); // save off the texture buffer - // initialise the texture to have full luminance - mConstantTexBuf = new uint8[mTexBuf->getSizeInBytes()]; - memset(mConstantTexBuf, 0xff, mTexBuf->getSizeInBytes()); - memcpy(mTexBuf->lock(HardwareBuffer::HBL_DISCARD), mConstantTexBuf, TEXTURE_SIZE * TEXTURE_SIZE); - mTexBuf->unlock(); + // initialise the texture to have full luminance + mConstantTexBuf = new uint8[mTexBuf->getSizeInBytes()]; + memset(mConstantTexBuf, 0xff, mTexBuf->getSizeInBytes()); + memcpy(mTexBuf->lock(HardwareBuffer::HBL_DISCARD), mConstantTexBuf, TEXTURE_SIZE * TEXTURE_SIZE); + mTexBuf->unlock(); - // create a penguin and attach him to our penguin node - Entity* penguin = mSceneMgr->createEntity("Penguin", "penguin.mesh"); - mPenguinNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mPenguinNode->attachObject(penguin); + // create a penguin and attach him to our penguin node + Entity* penguin = mSceneMgr->createEntity("Penguin", "penguin.mesh"); + mPenguinNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mPenguinNode->attachObject(penguin); - // get and enable the penguin idle animation - mPenguinAnimState = penguin->getAnimationState("amuse"); - mPenguinAnimState->setEnabled(true); + // get and enable the penguin idle animation + mPenguinAnimState = penguin->getAnimationState("amuse"); + mPenguinAnimState->setEnabled(true); - // create a snowstorm over the scene, and fast forward it a little + // create a snowstorm over the scene, and fast forward it a little ParticleSystem* ps = mSceneMgr->createParticleSystem("Snow", "Examples/Snow"); mSceneMgr->getRootSceneNode()->attachObject(ps); ps->fastForward(30); - // create a frosted screen in front of the camera, using our dynamic texture to "thaw" certain areas - Entity* ent = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); - ent->setMaterialName("Examples/Frost"); - SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - node->setPosition(0, 0, 50); - node->attachObject(ent); - - mPlaneSize = ent->getBoundingBox().getSize().x; // remember the size of the plane - - mCursorQuery = mSceneMgr->createRayQuery(Ray()); // create a ray scene query for the cursor - - mTimeSinceLastFreeze = 0; - mWiping = false; - } - - void updateTexture(uint8 freezeAmount) - { - // get access to raw texel data - uint8* data = mConstantTexBuf; - - uint8 temperature; - Real sqrDistToBrush; - - // go through every texel... - for (unsigned int y = 0; y < TEXTURE_SIZE; y++) - { - for (unsigned int x = 0; x < TEXTURE_SIZE; x++) - { - if (freezeAmount != 0) - { - // gradually refreeze anything that isn't completely frozen - temperature = 0xff - *data; - if (temperature > freezeAmount) *data += freezeAmount; - else *data = 0xff; - } - - if (mWiping) - { - // wipe frost from under the cursor - sqrDistToBrush = Math::Sqr(x - mBrushPos.x) + Math::Sqr(y - mBrushPos.y); - if (sqrDistToBrush <= SQR_BRUSH_RADIUS) - *data = std::min(sqrDistToBrush / SQR_BRUSH_RADIUS * 0xff, *data); - } - - data++; - } - } - - memcpy(mTexBuf->lock(HardwareBuffer::HBL_DISCARD), mConstantTexBuf, TEXTURE_SIZE * TEXTURE_SIZE); - mTexBuf->unlock(); - } - - void cleanupContent() - { - delete [] mConstantTexBuf; - TextureManager::getSingleton().remove("thaw"); + // create a frosted screen in front of the camera, using our dynamic texture to "thaw" certain areas + Entity* ent = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); + ent->setMaterialName("Examples/Frost"); + SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + node->setPosition(0, 0, 50); + node->attachObject(ent); + + mPlaneSize = ent->getBoundingBox().getSize().x; // remember the size of the plane + + mCursorQuery = mSceneMgr->createRayQuery(Ray()); // create a ray scene query for the cursor + + mTimeSinceLastFreeze = 0; + mWiping = false; + } + + void updateTexture(uint8 freezeAmount) + { + // get access to raw texel data + uint8* data = mConstantTexBuf; + + uint8 temperature; + Real sqrDistToBrush; + + // go through every texel... + for (unsigned int y = 0; y < TEXTURE_SIZE; y++) + { + for (unsigned int x = 0; x < TEXTURE_SIZE; x++) + { + if (freezeAmount != 0) + { + // gradually refreeze anything that isn't completely frozen + temperature = 0xff - *data; + if (temperature > freezeAmount) *data += freezeAmount; + else *data = 0xff; + } + + if (mWiping) + { + // wipe frost from under the cursor + sqrDistToBrush = Math::Sqr(x - mBrushPos.x) + Math::Sqr(y - mBrushPos.y); + if (sqrDistToBrush <= SQR_BRUSH_RADIUS) + *data = std::min(sqrDistToBrush / SQR_BRUSH_RADIUS * 0xff, *data); + } + + data++; + } + } + + memcpy(mTexBuf->lock(HardwareBuffer::HBL_DISCARD), mConstantTexBuf, TEXTURE_SIZE * TEXTURE_SIZE); + mTexBuf->unlock(); + } + + void cleanupContent() + { + delete [] mConstantTexBuf; + TextureManager::getSingleton().remove("thaw"); mSceneMgr->destroyQuery(mCursorQuery); - } - - const unsigned int TEXTURE_SIZE; - const unsigned int SQR_BRUSH_RADIUS; - HardwarePixelBufferSharedPtr mTexBuf; - uint8* mConstantTexBuf; - Real mPlaneSize; - RaySceneQuery* mCursorQuery; - Vector2 mBrushPos; - Real mTimeSinceLastFreeze; - bool mWiping; - SceneNode* mPenguinNode; - AnimationState* mPenguinAnimState; + } + + const unsigned int TEXTURE_SIZE; + const unsigned int SQR_BRUSH_RADIUS; + HardwarePixelBufferSharedPtr mTexBuf; + uint8* mConstantTexBuf; + Real mPlaneSize; + RaySceneQuery* mCursorQuery; + Vector2 mBrushPos; + Real mTimeSinceLastFreeze; + bool mWiping; + SceneNode* mPenguinNode; + AnimationState* mPenguinAnimState; }; #endif diff --git a/Samples/DynTex/src/DynTex.cpp b/Samples/DynTex/src/DynTex.cpp index cdd6430f791..4323000863c 100755 --- a/Samples/DynTex/src/DynTex.cpp +++ b/Samples/DynTex/src/DynTex.cpp @@ -11,17 +11,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_DynTex; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_DynTex; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/EndlessWorld/include/EndlessWorld.h b/Samples/EndlessWorld/include/EndlessWorld.h index f56b14c966c..a0f056577c5 100644 --- a/Samples/EndlessWorld/include/EndlessWorld.h +++ b/Samples/EndlessWorld/include/EndlessWorld.h @@ -46,437 +46,437 @@ class _OgreSampleClassExport Sample_EndlessWorld : public SdkSample { public: - Sample_EndlessWorld() - : mTerrainGroup(0) - , mTerrainPaging(0) - , mPageManager(0) - , mPagedWorld(0) - , mTerrainPagedWorldSection(0) - , mPerlinNoiseTerrainGenerator(0) + Sample_EndlessWorld() + : mTerrainGroup(0) + , mTerrainPaging(0) + , mPageManager(0) + , mPagedWorld(0) + , mTerrainPagedWorldSection(0) + , mPerlinNoiseTerrainGenerator(0) , mLodStatus(false) - , mAutoLod(true) - , mFly(true) - , mFallVelocity(0) + , mAutoLod(true) + , mFly(true) + , mFallVelocity(0) , mTerrainPos(0,0,0) - { - mInfo["Title"] = "Endless World"; - mInfo["Description"] = "Demonstrates use of the terrain plugin with paging option."; - mInfo["Thumbnail"] = "thumb_terrain.png"; - mInfo["Category"] = "Environment"; - mInfo["Help"] = "Left click and drag anywhere in the scene to look around. Let go again to show " - "cursor and access widgets. Use WASD keys to move. You can increase/decrease terrains' LOD level using Page Up/Page Down." - "Use C to generate another random terrain"; - } + { + mInfo["Title"] = "Endless World"; + mInfo["Description"] = "Demonstrates use of the terrain plugin with paging option."; + mInfo["Thumbnail"] = "thumb_terrain.png"; + mInfo["Category"] = "Environment"; + mInfo["Help"] = "Left click and drag anywhere in the scene to look around. Let go again to show " + "cursor and access widgets. Use WASD keys to move. You can increase/decrease terrains' LOD level using Page Up/Page Down." + "Use C to generate another random terrain"; + } void testCapabilities(const RenderSystemCapabilities* caps) - { + { if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex or fragment shaders, " + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex or fragment shaders, " "so you cannot run this sample. Sorry!", "Sample_EndlessWorld::testCapabilities"); } - } + } - StringVector getRequiredPlugins() - { - StringVector names; + StringVector getRequiredPlugins() + { + StringVector names; if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl150")) names.push_back("Cg Program Manager"); - return names; - } + return names; + } bool frameRenderingQueued(const FrameEvent& evt) { - if (!mFly) - { - // clamp to terrain - Vector3 camPos = mCamera->getPosition(); - Ray ray; - ray.setOrigin(Vector3(camPos.x, mTerrainPos.y + 10000, camPos.z)); - ray.setDirection(Vector3::NEGATIVE_UNIT_Y); - - TerrainGroup::RayResult rayResult = mTerrainGroup->rayIntersects(ray); - const Real distanceAboveTerrain = 50; - if (rayResult.hit) - mCamera->setPosition(camPos.x, rayResult.position.y + distanceAboveTerrain, camPos.z); - } - - if (mTerrainGroup->isDerivedDataUpdateInProgress()) - { - mTrayMgr->moveWidgetToTray(mInfoLabel, TL_TOP, 0); - mInfoLabel->show(); - mInfoLabel->setCaption("Building terrain..."); - } - else - { - mTrayMgr->removeWidgetFromTray(mInfoLabel); - mInfoLabel->hide(); - } - - if (mLodStatus) - { - for(LabelList::iterator li = mLodStatusLabelList.begin(); li != mLodStatusLabelList.end(); li++) - { - mLodInfoOverlayContainer->_removeChild(*li); - OverlayManager::getSingleton().destroyOverlayElement(*li); - } - mLodStatusLabelList.clear(); - - TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); - while(ti.hasMoreElements()) - { - Terrain* t = ti.getNext()->instance; - if (!t) - continue; - - Vector3 pt = mCamera->getProjectionMatrix() * (mCamera->getViewMatrix() * t->getPosition()); - Real x = (pt.x / 2) + 0.5f; - Real y = 1 - ((pt.y / 2) + 0.5f); - - String lName = StringConverter::toString((unsigned long)(t))+"/"+"LodInfoLabel"; - - OverlayElement *l = OverlayManager::getSingleton().createOverlayElement("TextArea", lName); - l->setCaption("Target="+StringConverter::toString(t->getTargetLodLevel())+"\nHighest="+ - StringConverter::toString(t->getHighestLodLoaded())+"\nPrepared="+ - StringConverter::toString(t->getHighestLodPrepared()) - ); - l->setPosition(x, y); - l->setDimensions(0.1, 0.1); // center text in label and its position - l->setParameter("font_name", "SdkTrays/Value"); - l->setParameter("char_height", "0.02f"); - l->setColour(ColourValue(1.0,0.0,0.0)); - - mLodInfoOverlayContainer->addChild(l); - mLodStatusLabelList.push_back(l); - } - } - - mTerrainGroup->autoUpdateLodAll(false, Any( Real(HOLD_LOD_DISTANCE) )); - return SdkSample::frameRenderingQueued(evt); // don't forget the parent updates! + if (!mFly) + { + // clamp to terrain + Vector3 camPos = mCamera->getPosition(); + Ray ray; + ray.setOrigin(Vector3(camPos.x, mTerrainPos.y + 10000, camPos.z)); + ray.setDirection(Vector3::NEGATIVE_UNIT_Y); + + TerrainGroup::RayResult rayResult = mTerrainGroup->rayIntersects(ray); + const Real distanceAboveTerrain = 50; + if (rayResult.hit) + mCamera->setPosition(camPos.x, rayResult.position.y + distanceAboveTerrain, camPos.z); + } + + if (mTerrainGroup->isDerivedDataUpdateInProgress()) + { + mTrayMgr->moveWidgetToTray(mInfoLabel, TL_TOP, 0); + mInfoLabel->show(); + mInfoLabel->setCaption("Building terrain..."); + } + else + { + mTrayMgr->removeWidgetFromTray(mInfoLabel); + mInfoLabel->hide(); + } + + if (mLodStatus) + { + for(LabelList::iterator li = mLodStatusLabelList.begin(); li != mLodStatusLabelList.end(); li++) + { + mLodInfoOverlayContainer->_removeChild(*li); + OverlayManager::getSingleton().destroyOverlayElement(*li); + } + mLodStatusLabelList.clear(); + + TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); + while(ti.hasMoreElements()) + { + Terrain* t = ti.getNext()->instance; + if (!t) + continue; + + Vector3 pt = mCamera->getProjectionMatrix() * (mCamera->getViewMatrix() * t->getPosition()); + Real x = (pt.x / 2) + 0.5f; + Real y = 1 - ((pt.y / 2) + 0.5f); + + String lName = StringConverter::toString((unsigned long)(t))+"/"+"LodInfoLabel"; + + OverlayElement *l = OverlayManager::getSingleton().createOverlayElement("TextArea", lName); + l->setCaption("Target="+StringConverter::toString(t->getTargetLodLevel())+"\nHighest="+ + StringConverter::toString(t->getHighestLodLoaded())+"\nPrepared="+ + StringConverter::toString(t->getHighestLodPrepared()) + ); + l->setPosition(x, y); + l->setDimensions(0.1, 0.1); // center text in label and its position + l->setParameter("font_name", "SdkTrays/Value"); + l->setParameter("char_height", "0.02f"); + l->setColour(ColourValue(1.0,0.0,0.0)); + + mLodInfoOverlayContainer->addChild(l); + mLodStatusLabelList.push_back(l); + } + } + + mTerrainGroup->autoUpdateLodAll(false, Any( Real(HOLD_LOD_DISTANCE) )); + return SdkSample::frameRenderingQueued(evt); // don't forget the parent updates! } - bool keyPressed (const OIS::KeyEvent &e) - { + bool keyPressed (const OIS::KeyEvent &e) + { #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS - switch (e.key) - { - case OIS::KC_PGUP: - { - mAutoBox->setChecked(false); - TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); - while(ti.hasMoreElements()) - { - Terrain* t = ti.getNext()->instance; - if (t) - t->increaseLodLevel(); - } - } - break; - case OIS::KC_PGDOWN: - { - mAutoBox->setChecked(false); - TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); - while(ti.hasMoreElements()) - { - Terrain* t = ti.getNext()->instance; - if (t) - t->decreaseLodLevel(); - } - } - break; - // generate new random offset, to make terrains different - case OIS::KC_C: - if(mPerlinNoiseTerrainGenerator) - { - // random a new origin point - mPerlinNoiseTerrainGenerator->randomize(); - - // reload all terrains - TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); - while(ti.hasMoreElements()) - { - TerrainGroup::TerrainSlot* slot = ti.getNext(); - PageID pageID = mTerrainGroup->packIndex( slot->x, slot->y ); - mTerrainPagedWorldSection->unloadPage(pageID); - mTerrainPagedWorldSection->loadPage(pageID); - } - } - break; - default: - return SdkSample::keyPressed(e); - } + switch (e.key) + { + case OIS::KC_PGUP: + { + mAutoBox->setChecked(false); + TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); + while(ti.hasMoreElements()) + { + Terrain* t = ti.getNext()->instance; + if (t) + t->increaseLodLevel(); + } + } + break; + case OIS::KC_PGDOWN: + { + mAutoBox->setChecked(false); + TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); + while(ti.hasMoreElements()) + { + Terrain* t = ti.getNext()->instance; + if (t) + t->decreaseLodLevel(); + } + } + break; + // generate new random offset, to make terrains different + case OIS::KC_C: + if(mPerlinNoiseTerrainGenerator) + { + // random a new origin point + mPerlinNoiseTerrainGenerator->randomize(); + + // reload all terrains + TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); + while(ti.hasMoreElements()) + { + TerrainGroup::TerrainSlot* slot = ti.getNext(); + PageID pageID = mTerrainGroup->packIndex( slot->x, slot->y ); + mTerrainPagedWorldSection->unloadPage(pageID); + mTerrainPagedWorldSection->loadPage(pageID); + } + } + break; + default: + return SdkSample::keyPressed(e); + } #endif - return true; - } - - void checkBoxToggled(CheckBox* box) - { - if (box == mFlyBox) - { - mFly = mFlyBox->isChecked(); - } - else if (box == mLodStatusBox) - { - mLodStatus = mLodStatusBox->isChecked(); - if (!mLodStatus) - { - for(LabelList::iterator li = mLodStatusLabelList.begin(); li != mLodStatusLabelList.end(); li++) - { - mLodInfoOverlayContainer->_removeChild(*li); - OverlayManager::getSingleton().destroyOverlayElement(*li); - } - mLodStatusLabelList.clear(); - } - } - else if (box == mAutoBox) - { - if(mTerrainGroup) - { - if(!mAutoLod && mAutoBox->isChecked()) - { - mTerrainGroup->setAutoUpdateLod( TerrainAutoUpdateLodFactory::getAutoUpdateLod(BY_DISTANCE) ); - mAutoLod = true; - } - else if(mAutoLod && !mAutoBox->isChecked()) - { - mTerrainGroup->setAutoUpdateLod( TerrainAutoUpdateLodFactory::getAutoUpdateLod(BY_DISTANCE) ); - mAutoLod = false; - } - } - } - } + return true; + } + + void checkBoxToggled(CheckBox* box) + { + if (box == mFlyBox) + { + mFly = mFlyBox->isChecked(); + } + else if (box == mLodStatusBox) + { + mLodStatus = mLodStatusBox->isChecked(); + if (!mLodStatus) + { + for(LabelList::iterator li = mLodStatusLabelList.begin(); li != mLodStatusLabelList.end(); li++) + { + mLodInfoOverlayContainer->_removeChild(*li); + OverlayManager::getSingleton().destroyOverlayElement(*li); + } + mLodStatusLabelList.clear(); + } + } + else if (box == mAutoBox) + { + if(mTerrainGroup) + { + if(!mAutoLod && mAutoBox->isChecked()) + { + mTerrainGroup->setAutoUpdateLod( TerrainAutoUpdateLodFactory::getAutoUpdateLod(BY_DISTANCE) ); + mAutoLod = true; + } + else if(mAutoLod && !mAutoBox->isChecked()) + { + mTerrainGroup->setAutoUpdateLod( TerrainAutoUpdateLodFactory::getAutoUpdateLod(BY_DISTANCE) ); + mAutoLod = false; + } + } + } + } protected: - TerrainGlobalOptions* mTerrainGlobals; - TerrainGroup* mTerrainGroup; - TerrainPaging* mTerrainPaging; - PageManager* mPageManager; - PagedWorld* mPagedWorld; - TerrainPagedWorldSection* mTerrainPagedWorldSection; - PerlinNoiseTerrainGenerator* mPerlinNoiseTerrainGenerator; - bool mLodStatus; - bool mAutoLod; - - /// This class just pretends to provide procedural page content to avoid page loading - class DummyPageProvider : public PageProvider - { - public: - bool prepareProceduralPage(Page* page, PagedWorldSection* section) { return true; } - bool loadProceduralPage(Page* page, PagedWorldSection* section) { return true; } - bool unloadProceduralPage(Page* page, PagedWorldSection* section) { return true; } - bool unprepareProceduralPage(Page* page, PagedWorldSection* section) { return true; } - }; - DummyPageProvider mDummyPageProvider; - - bool mFly; - Real mFallVelocity; - Vector3 mTerrainPos; - CheckBox* mFlyBox; - OgreBites::Label* mInfoLabel; - - typedef std::list LabelList; - LabelList mLodStatusLabelList; - - Overlay *mLodInfoOverlay; - OverlayContainer *mLodInfoOverlayContainer; - - CheckBox *mLodStatusBox; - CheckBox *mAutoBox; - - void configureTerrainDefaults(Light* l) - { - // Configure global - mTerrainGlobals->setMaxPixelError(8); - // testing composite map - mTerrainGlobals->setCompositeMapDistance(3000); - //mTerrainGlobals->setUseRayBoxDistanceCalculation(true); - mTerrainGlobals->getDefaultMaterialGenerator()->setLightmapEnabled(false); - - mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight()); - mTerrainGlobals->setCompositeMapDiffuse(l->getDiffuseColour()); - mTerrainGlobals->setLightMapDirection(l->getDerivedDirection()); - - // Configure default import settings for if we use imported image - Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings(); - defaultimp.terrainSize = TERRAIN_SIZE; - defaultimp.worldSize = TERRAIN_WORLD_SIZE; - defaultimp.inputScale = 600; - defaultimp.minBatchSize = 33; - defaultimp.maxBatchSize = 65; - // textures - defaultimp.layerList.resize(3); - defaultimp.layerList[0].worldSize = 100; - defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds"); - defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds"); - defaultimp.layerList[1].worldSize = 30; - defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds"); - defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds"); - defaultimp.layerList[2].worldSize = 200; - defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds"); - defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds"); - } - - /*----------------------------------------------------------------------------- - | Extends setupView to change some initial camera settings for this sample. - -----------------------------------------------------------------------------*/ - void setupView() - { - SdkSample::setupView(); - // put camera at world center, so that it's difficult to reach the edge - Vector3 worldCenter( - (ENDLESS_PAGE_MAX_X+ENDLESS_PAGE_MIN_X) / 2 * TERRAIN_WORLD_SIZE, - 0, - -(ENDLESS_PAGE_MAX_Y+ENDLESS_PAGE_MIN_Y) / 2 * TERRAIN_WORLD_SIZE - ); - mCamera->setPosition(mTerrainPos+worldCenter); - mCamera->lookAt(mTerrainPos); - mCamera->setNearClipDistance(0.1); - mCamera->setFarClipDistance(50000); - - if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)) + TerrainGlobalOptions* mTerrainGlobals; + TerrainGroup* mTerrainGroup; + TerrainPaging* mTerrainPaging; + PageManager* mPageManager; + PagedWorld* mPagedWorld; + TerrainPagedWorldSection* mTerrainPagedWorldSection; + PerlinNoiseTerrainGenerator* mPerlinNoiseTerrainGenerator; + bool mLodStatus; + bool mAutoLod; + + /// This class just pretends to provide procedural page content to avoid page loading + class DummyPageProvider : public PageProvider + { + public: + bool prepareProceduralPage(Page* page, PagedWorldSection* section) { return true; } + bool loadProceduralPage(Page* page, PagedWorldSection* section) { return true; } + bool unloadProceduralPage(Page* page, PagedWorldSection* section) { return true; } + bool unprepareProceduralPage(Page* page, PagedWorldSection* section) { return true; } + }; + DummyPageProvider mDummyPageProvider; + + bool mFly; + Real mFallVelocity; + Vector3 mTerrainPos; + CheckBox* mFlyBox; + OgreBites::Label* mInfoLabel; + + typedef std::list LabelList; + LabelList mLodStatusLabelList; + + Overlay *mLodInfoOverlay; + OverlayContainer *mLodInfoOverlayContainer; + + CheckBox *mLodStatusBox; + CheckBox *mAutoBox; + + void configureTerrainDefaults(Light* l) + { + // Configure global + mTerrainGlobals->setMaxPixelError(8); + // testing composite map + mTerrainGlobals->setCompositeMapDistance(3000); + //mTerrainGlobals->setUseRayBoxDistanceCalculation(true); + mTerrainGlobals->getDefaultMaterialGenerator()->setLightmapEnabled(false); + + mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight()); + mTerrainGlobals->setCompositeMapDiffuse(l->getDiffuseColour()); + mTerrainGlobals->setLightMapDirection(l->getDerivedDirection()); + + // Configure default import settings for if we use imported image + Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings(); + defaultimp.terrainSize = TERRAIN_SIZE; + defaultimp.worldSize = TERRAIN_WORLD_SIZE; + defaultimp.inputScale = 600; + defaultimp.minBatchSize = 33; + defaultimp.maxBatchSize = 65; + // textures + defaultimp.layerList.resize(3); + defaultimp.layerList[0].worldSize = 100; + defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds"); + defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds"); + defaultimp.layerList[1].worldSize = 30; + defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds"); + defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds"); + defaultimp.layerList[2].worldSize = 200; + defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds"); + defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds"); + } + + /*----------------------------------------------------------------------------- + | Extends setupView to change some initial camera settings for this sample. + -----------------------------------------------------------------------------*/ + void setupView() + { + SdkSample::setupView(); + // put camera at world center, so that it's difficult to reach the edge + Vector3 worldCenter( + (ENDLESS_PAGE_MAX_X+ENDLESS_PAGE_MIN_X) / 2 * TERRAIN_WORLD_SIZE, + 0, + -(ENDLESS_PAGE_MAX_Y+ENDLESS_PAGE_MIN_Y) / 2 * TERRAIN_WORLD_SIZE + ); + mCamera->setPosition(mTerrainPos+worldCenter); + mCamera->lookAt(mTerrainPos); + mCamera->setNearClipDistance(0.1); + mCamera->setFarClipDistance(50000); + + if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)) { mCamera->setFarClipDistance(0); // enable infinite far clip distance if we can } - } - - void setupControls() - { - mTrayMgr->showCursor(); + } + + void setupControls() + { + mTrayMgr->showCursor(); + + // make room for the controls + mTrayMgr->showLogo(TL_TOPRIGHT); + mTrayMgr->showFrameStats(TL_TOPRIGHT); + mTrayMgr->toggleAdvancedFrameStats(); - // make room for the controls - mTrayMgr->showLogo(TL_TOPRIGHT); - mTrayMgr->showFrameStats(TL_TOPRIGHT); - mTrayMgr->toggleAdvancedFrameStats(); + mInfoLabel = mTrayMgr->createLabel(TL_TOP, "TInfo", "", 350); - mInfoLabel = mTrayMgr->createLabel(TL_TOP, "TInfo", "", 350); - - mFlyBox = mTrayMgr->createCheckBox(TL_BOTTOM, "Fly", "Fly"); - mFlyBox->setChecked(false, true); - - mLodStatusBox = mTrayMgr->createCheckBox(TL_BOTTOM, "LODStatus", "LOD Status"); - mLodStatusBox->setChecked(false, true); - - mAutoBox = mTrayMgr->createCheckBox(TL_BOTTOM, "LODAuto", "Auto LOD"); - mAutoBox->setChecked(true, true); - - // a friendly reminder - StringVector names; - names.push_back("Help"); - mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); - } - - class SimpleTerrainDefiner : public TerrainPagedWorldSection::TerrainDefiner - { - public: - virtual void define(TerrainGroup* terrainGroup, long x, long y) - { - Image img; - img.load("terrain.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - if (x % 2) - img.flipAroundY(); - if (y % 2) - img.flipAroundX(); - terrainGroup->defineTerrain(x, y, &img); - } - }; - - void setupContent() - { - mTerrainGlobals = OGRE_NEW TerrainGlobalOptions(); - - // Bugfix for D3D11 Render System because of pixel format incompatibility when using - // vertex compression - if (Ogre::Root::getSingleton().getRenderSystem()->getName() == "Direct3D11 Rendering Subsystem") - mTerrainGlobals->setUseVertexCompressionWhenAvailable(false); - - setupControls(); - mCameraMan->setTopSpeed(100); - - setDragLook(true); - - MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); - MaterialManager::getSingleton().setDefaultAnisotropy(7); - - mSceneMgr->setFog(FOG_LINEAR, ColourValue(0.7, 0.7, 0.8), 0, 4000, 10000); - - LogManager::getSingleton().setLogDetail(LL_BOREME); - - Vector3 lightdir(0.55, -0.3, 0.75); - lightdir.normalise(); - - Light* l = mSceneMgr->createLight("tstLight"); - l->setType(Light::LT_DIRECTIONAL); - l->setDirection(lightdir); - l->setDiffuseColour(ColourValue::White); - l->setSpecularColour(ColourValue(0.4, 0.4, 0.4)); - - mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); - - mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, TERRAIN_WORLD_SIZE); - mTerrainGroup->setFilenameConvention(ENDLESS_TERRAIN_FILE_PREFIX, ENDLESS_TERRAIN_FILE_SUFFIX); - mTerrainGroup->setOrigin(mTerrainPos); - mTerrainGroup->setAutoUpdateLod( TerrainAutoUpdateLodFactory::getAutoUpdateLod(BY_DISTANCE) ); - - configureTerrainDefaults(l); - - // Paging setup - mPageManager = OGRE_NEW PageManager(); - // Since we're not loading any pages from .page files, we need a way just - // to say we've loaded them without them actually being loaded - mPageManager->setPageProvider(&mDummyPageProvider); - mPageManager->addCamera(mCamera); - mPageManager->setDebugDisplayLevel(0); - mTerrainPaging = OGRE_NEW TerrainPaging(mPageManager); - mPagedWorld = mPageManager->createWorld(); - mTerrainPagedWorldSection = mTerrainPaging->createWorldSection(mPagedWorld, mTerrainGroup, 400, 500, - ENDLESS_PAGE_MIN_X, ENDLESS_PAGE_MIN_Y, - ENDLESS_PAGE_MAX_X, ENDLESS_PAGE_MAX_Y); - - mPerlinNoiseTerrainGenerator = OGRE_NEW PerlinNoiseTerrainGenerator; - mTerrainPagedWorldSection->setDefiner( mPerlinNoiseTerrainGenerator ); -// mTerrainPagedWorldSection->setDefiner( OGRE_NEW SimpleTerrainDefiner ); - - mTerrainGroup->freeTemporaryResources(); - - mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); - - // setup LOD info overlay - mLodInfoOverlay = OverlayManager::getSingleton().create("LODInfoOverlay"); - - mLodInfoOverlay->setZOrder(10); - mLodInfoOverlayContainer = (OverlayContainer*)OverlayManager::getSingleton().createOverlayElement("Panel", "LODInfoOverlayPanel"); - mLodInfoOverlayContainer->setDimensions(1.0, 1.0); - mLodInfoOverlayContainer->setPosition(0.0, 0.0); - - mLodInfoOverlay->add2D(mLodInfoOverlayContainer); - mLodInfoOverlay->show(); - } - - void _shutdown() - { - if(mTerrainPaging) - { - OGRE_DELETE mTerrainPaging; - mPageManager->destroyWorld( mPagedWorld ); - OGRE_DELETE mPageManager; - } - OGRE_DELETE mTerrainGlobals; - - for(LabelList::iterator li = mLodStatusLabelList.begin(); li != mLodStatusLabelList.end(); li++) - { - mLodInfoOverlayContainer->_removeChild(*li); - OverlayManager::getSingleton().destroyOverlayElement(*li); - } - mLodStatusLabelList.clear(); - - OverlayManager::getSingleton().destroy(mLodInfoOverlay); - OverlayManager::getSingleton().destroyOverlayElement(mLodInfoOverlayContainer); - - SdkSample::_shutdown(); - } + mFlyBox = mTrayMgr->createCheckBox(TL_BOTTOM, "Fly", "Fly"); + mFlyBox->setChecked(false, true); + + mLodStatusBox = mTrayMgr->createCheckBox(TL_BOTTOM, "LODStatus", "LOD Status"); + mLodStatusBox->setChecked(false, true); + + mAutoBox = mTrayMgr->createCheckBox(TL_BOTTOM, "LODAuto", "Auto LOD"); + mAutoBox->setChecked(true, true); + + // a friendly reminder + StringVector names; + names.push_back("Help"); + mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); + } + + class SimpleTerrainDefiner : public TerrainPagedWorldSection::TerrainDefiner + { + public: + virtual void define(TerrainGroup* terrainGroup, long x, long y) + { + Image img; + img.load("terrain.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + if (x % 2) + img.flipAroundY(); + if (y % 2) + img.flipAroundX(); + terrainGroup->defineTerrain(x, y, &img); + } + }; + + void setupContent() + { + mTerrainGlobals = OGRE_NEW TerrainGlobalOptions(); + + // Bugfix for D3D11 Render System because of pixel format incompatibility when using + // vertex compression + if (Ogre::Root::getSingleton().getRenderSystem()->getName() == "Direct3D11 Rendering Subsystem") + mTerrainGlobals->setUseVertexCompressionWhenAvailable(false); + + setupControls(); + mCameraMan->setTopSpeed(100); + + setDragLook(true); + + MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); + MaterialManager::getSingleton().setDefaultAnisotropy(7); + + mSceneMgr->setFog(FOG_LINEAR, ColourValue(0.7, 0.7, 0.8), 0, 4000, 10000); + + LogManager::getSingleton().setLogDetail(LL_BOREME); + + Vector3 lightdir(0.55, -0.3, 0.75); + lightdir.normalise(); + + Light* l = mSceneMgr->createLight("tstLight"); + l->setType(Light::LT_DIRECTIONAL); + l->setDirection(lightdir); + l->setDiffuseColour(ColourValue::White); + l->setSpecularColour(ColourValue(0.4, 0.4, 0.4)); + + mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); + + mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, TERRAIN_WORLD_SIZE); + mTerrainGroup->setFilenameConvention(ENDLESS_TERRAIN_FILE_PREFIX, ENDLESS_TERRAIN_FILE_SUFFIX); + mTerrainGroup->setOrigin(mTerrainPos); + mTerrainGroup->setAutoUpdateLod( TerrainAutoUpdateLodFactory::getAutoUpdateLod(BY_DISTANCE) ); + + configureTerrainDefaults(l); + + // Paging setup + mPageManager = OGRE_NEW PageManager(); + // Since we're not loading any pages from .page files, we need a way just + // to say we've loaded them without them actually being loaded + mPageManager->setPageProvider(&mDummyPageProvider); + mPageManager->addCamera(mCamera); + mPageManager->setDebugDisplayLevel(0); + mTerrainPaging = OGRE_NEW TerrainPaging(mPageManager); + mPagedWorld = mPageManager->createWorld(); + mTerrainPagedWorldSection = mTerrainPaging->createWorldSection(mPagedWorld, mTerrainGroup, 400, 500, + ENDLESS_PAGE_MIN_X, ENDLESS_PAGE_MIN_Y, + ENDLESS_PAGE_MAX_X, ENDLESS_PAGE_MAX_Y); + + mPerlinNoiseTerrainGenerator = OGRE_NEW PerlinNoiseTerrainGenerator; + mTerrainPagedWorldSection->setDefiner( mPerlinNoiseTerrainGenerator ); +// mTerrainPagedWorldSection->setDefiner( OGRE_NEW SimpleTerrainDefiner ); + + mTerrainGroup->freeTemporaryResources(); + + mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); + + // setup LOD info overlay + mLodInfoOverlay = OverlayManager::getSingleton().create("LODInfoOverlay"); + + mLodInfoOverlay->setZOrder(10); + mLodInfoOverlayContainer = (OverlayContainer*)OverlayManager::getSingleton().createOverlayElement("Panel", "LODInfoOverlayPanel"); + mLodInfoOverlayContainer->setDimensions(1.0, 1.0); + mLodInfoOverlayContainer->setPosition(0.0, 0.0); + + mLodInfoOverlay->add2D(mLodInfoOverlayContainer); + mLodInfoOverlay->show(); + } + + void _shutdown() + { + if(mTerrainPaging) + { + OGRE_DELETE mTerrainPaging; + mPageManager->destroyWorld( mPagedWorld ); + OGRE_DELETE mPageManager; + } + OGRE_DELETE mTerrainGlobals; + + for(LabelList::iterator li = mLodStatusLabelList.begin(); li != mLodStatusLabelList.end(); li++) + { + mLodInfoOverlayContainer->_removeChild(*li); + OverlayManager::getSingleton().destroyOverlayElement(*li); + } + mLodStatusLabelList.clear(); + + OverlayManager::getSingleton().destroy(mLodInfoOverlay); + OverlayManager::getSingleton().destroyOverlayElement(mLodInfoOverlayContainer); + + SdkSample::_shutdown(); + } }; #endif diff --git a/Samples/EndlessWorld/include/PerlinNoiseTerrainGenerator.h b/Samples/EndlessWorld/include/PerlinNoiseTerrainGenerator.h index 7f32c9225ae..299504e502a 100644 --- a/Samples/EndlessWorld/include/PerlinNoiseTerrainGenerator.h +++ b/Samples/EndlessWorld/include/PerlinNoiseTerrainGenerator.h @@ -9,47 +9,47 @@ using namespace Ogre; class PerlinNoiseTerrainGenerator : public TerrainPagedWorldSection::TerrainDefiner { public: - /** Constructor of PerlinNoiseTerrainGenerator - @param alpha The weight when the sum is formed - @param beta The harmonic scaling/spacing - @param iterationNum The iterations num to produce a point. - @param cycle The terrain size maps to one cycle of perlin curve - @param heightScale The height maps to curve amplitude - */ - PerlinNoiseTerrainGenerator(const Real& alpha = 3.3, const Real& beta = 2.2, int iterationNum = 10, const Real& cycle = 128, const Real& heightScale = 4); - - /// Define terrain - virtual void define( Ogre::TerrainGroup* terrainGroup, long x, long y ); - /// Random terrain origin point to make it looks different - void randomize(); + /** Constructor of PerlinNoiseTerrainGenerator + @param alpha The weight when the sum is formed + @param beta The harmonic scaling/spacing + @param iterationNum The iterations num to produce a point. + @param cycle The terrain size maps to one cycle of perlin curve + @param heightScale The height maps to curve amplitude + */ + PerlinNoiseTerrainGenerator(const Real& alpha = 3.3, const Real& beta = 2.2, int iterationNum = 10, const Real& cycle = 128, const Real& heightScale = 4); + + /// Define terrain + virtual void define( Ogre::TerrainGroup* terrainGroup, long x, long y ); + /// Random terrain origin point to make it looks different + void randomize(); private: - /** Produce a noise according to PerlinNoise algorithm - Generate multiple values by calling noise(): - v0=noise(x,y), - v1=noise(x*beta,y*beta), - v2=noise(x*beta*beta,y*beta*beta) - ... - Accumulate them: - result = v0/alpha + v1/(alpha*alpha) + v1/(alpha*alpha*alpha) + ... - */ - Real produceSingleHeight(const Vector2& vec2); - - /// Generate a 2D noise - Real noise(const Vector2& vec2); - - inline Real sCurve(const Real& t) const { return t * t * (3 - 2 * t); } - inline Real lerp(const Real& t, const Real& a, const Real& b) const { return a + t*(b - a); } - void setup( const Real& target, int& b0, int& b1, Real& r0, Real& r1); - - Real mAlpha; - Real mBeta; - int mIterationNum; - Real mCycle; - Real mHeightScale; - Vector2 mOriginPoint; - - int p[B + B + 2]; - Vector3 g3[B + B + 2]; - Vector2 g2[B + B + 2]; - Real g1[B + B + 2]; + /** Produce a noise according to PerlinNoise algorithm + Generate multiple values by calling noise(): + v0=noise(x,y), + v1=noise(x*beta,y*beta), + v2=noise(x*beta*beta,y*beta*beta) + ... + Accumulate them: + result = v0/alpha + v1/(alpha*alpha) + v1/(alpha*alpha*alpha) + ... + */ + Real produceSingleHeight(const Vector2& vec2); + + /// Generate a 2D noise + Real noise(const Vector2& vec2); + + inline Real sCurve(const Real& t) const { return t * t * (3 - 2 * t); } + inline Real lerp(const Real& t, const Real& a, const Real& b) const { return a + t*(b - a); } + void setup( const Real& target, int& b0, int& b1, Real& r0, Real& r1); + + Real mAlpha; + Real mBeta; + int mIterationNum; + Real mCycle; + Real mHeightScale; + Vector2 mOriginPoint; + + int p[B + B + 2]; + Vector3 g3[B + B + 2]; + Vector2 g2[B + B + 2]; + Real g1[B + B + 2]; }; diff --git a/Samples/EndlessWorld/src/EndlessWorld.cpp b/Samples/EndlessWorld/src/EndlessWorld.cpp index 11cb5b0df42..aef7ff8c2ca 100644 --- a/Samples/EndlessWorld/src/EndlessWorld.cpp +++ b/Samples/EndlessWorld/src/EndlessWorld.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_EndlessWorld; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_EndlessWorld; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/EndlessWorld/src/PerlinNoiseTerrainGenerator.cpp b/Samples/EndlessWorld/src/PerlinNoiseTerrainGenerator.cpp index 7f73dea4245..674e91c9518 100644 --- a/Samples/EndlessWorld/src/PerlinNoiseTerrainGenerator.cpp +++ b/Samples/EndlessWorld/src/PerlinNoiseTerrainGenerator.cpp @@ -11,115 +11,115 @@ using namespace Ogre; #define NM 0xfff PerlinNoiseTerrainGenerator::PerlinNoiseTerrainGenerator(const Real& alpha, const Real& beta, int iterationNum, const Real& cycle, const Real& heightScale) - : mAlpha(alpha) - , mBeta(beta) - , mIterationNum(iterationNum) - , mCycle(cycle) - , mHeightScale(heightScale) - , mOriginPoint(0.f) + : mAlpha(alpha) + , mBeta(beta) + , mIterationNum(iterationNum) + , mCycle(cycle) + , mHeightScale(heightScale) + , mOriginPoint(0.f) { - for (int i = 0 ; i < B ; i++) { - p[i] = i; - g1[i] = Math::SymmetricRandom(); - - g2[i] = Vector2(Math::SymmetricRandom(), Math::SymmetricRandom()); - g2[i].normalise(); - - g3[i] = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom()); - g3[i].normalise(); - } - - for (int i = 0 ; i < B ; i++) { - int j = (int) Math::RangeRandom (0,B); - - int k = p[i]; - p[i] = p[j]; - p[j] = k; - } - - for (int i = 0 ; i < B + 2 ; i++) { - p[B + i] = p[i]; - g1[B + i] = g1[i]; - g2[B + i] = g2[i]; - g3[B + i] = g3[i]; - } + for (int i = 0 ; i < B ; i++) { + p[i] = i; + g1[i] = Math::SymmetricRandom(); + + g2[i] = Vector2(Math::SymmetricRandom(), Math::SymmetricRandom()); + g2[i].normalise(); + + g3[i] = Vector3(Math::SymmetricRandom(), Math::SymmetricRandom(), Math::SymmetricRandom()); + g3[i].normalise(); + } + + for (int i = 0 ; i < B ; i++) { + int j = (int) Math::RangeRandom (0,B); + + int k = p[i]; + p[i] = p[j]; + p[j] = k; + } + + for (int i = 0 ; i < B + 2 ; i++) { + p[B + i] = p[i]; + g1[B + i] = g1[i]; + g2[B + i] = g2[i]; + g3[B + i] = g3[i]; + } } void PerlinNoiseTerrainGenerator::define( TerrainGroup* terrainGroup, long x, long y ) { - uint16 terrainSize = terrainGroup->getTerrainSize(); - float* heightMap = OGRE_ALLOC_T(float, terrainSize*terrainSize, MEMCATEGORY_GEOMETRY); - - Vector2 worldOffset( Real(x*(terrainSize-1)), Real(y*(terrainSize-1)) ); - worldOffset += mOriginPoint; - - Vector2 revisedValuePoint; - for( uint16 i=0; idefineTerrain(x,y,heightMap); - OGRE_FREE(heightMap, MEMCATEGORY_GEOMETRY); + uint16 terrainSize = terrainGroup->getTerrainSize(); + float* heightMap = OGRE_ALLOC_T(float, terrainSize*terrainSize, MEMCATEGORY_GEOMETRY); + + Vector2 worldOffset( Real(x*(terrainSize-1)), Real(y*(terrainSize-1)) ); + worldOffset += mOriginPoint; + + Vector2 revisedValuePoint; + for( uint16 i=0; idefineTerrain(x,y,heightMap); + OGRE_FREE(heightMap, MEMCATEGORY_GEOMETRY); } Real PerlinNoiseTerrainGenerator::produceSingleHeight(const Vector2& vec2) { - Vector2 tempVec(vec2); - Real sum = 0; - Real scale = 1; - - for (int i=0;igetInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_FacialAnimation; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Fresnel/include/Fresnel.h b/Samples/Fresnel/include/Fresnel.h index a59d779d6d5..ba4c5a7402f 100644 --- a/Samples/Fresnel/include/Fresnel.h +++ b/Samples/Fresnel/include/Fresnel.h @@ -10,45 +10,45 @@ class _OgreSampleClassExport Sample_Fresnel : public SdkSample, public RenderTar { public: - Sample_Fresnel() : NUM_FISH(30), NUM_FISH_WAYPOINTS(10), FISH_PATH_LENGTH(200), FISH_SCALE(2) - { - mInfo["Title"] = "Fresnel"; - mInfo["Description"] = "Shows how to create reflections and refractions using render-to-texture and shaders."; - mInfo["Thumbnail"] = "thumb_fresnel.png"; - mInfo["Category"] = "Unsorted"; - } - - StringVector getRequiredPlugins() - { - StringVector names; + Sample_Fresnel() : NUM_FISH(30), NUM_FISH_WAYPOINTS(10), FISH_PATH_LENGTH(200), FISH_SCALE(2) + { + mInfo["Title"] = "Fresnel"; + mInfo["Description"] = "Shows how to create reflections and refractions using render-to-texture and shaders."; + mInfo["Thumbnail"] = "thumb_fresnel.png"; + mInfo["Category"] = "Unsorted"; + } + + StringVector getRequiredPlugins() + { + StringVector names; if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl150")) names.push_back("Cg Program Manager"); - return names; - } + return names; + } - void testCapabilities(const RenderSystemCapabilities* caps) - { - if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) + void testCapabilities(const RenderSystemCapabilities* caps) + { + if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" - " programs, so you cannot run this sample. Sorry!", "FresnelSample::testCapabilities"); + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" + " programs, so you cannot run this sample. Sorry!", "FresnelSample::testCapabilities"); } if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") && !GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0") && !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_1_4") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_1_4") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl")) { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support advanced fragment" - " programs, so you cannot run this sample. Sorry!", "FresnelSample::testCapabilities"); + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support advanced fragment" + " programs, so you cannot run this sample. Sorry!", "FresnelSample::testCapabilities"); } - } + } bool frameRenderingQueued(const FrameEvent &evt) { - // update the fish spline path animations and loop as needed + // update the fish spline path animations and loop as needed mFishAnimTime += evt.timeSinceLastFrame; while (mFishAnimTime >= FISH_PATH_LENGTH) mFishAnimTime -= FISH_PATH_LENGTH; @@ -56,11 +56,11 @@ class _OgreSampleClassExport Sample_Fresnel : public SdkSample, public RenderTar { mFishAnimStates[i]->addTime(evt.timeSinceLastFrame * 2); // update fish swim animation - // set the new position based on the spline path and set the direction based on displacement - Vector3 lastPos = mFishNodes[i]->getPosition(); + // set the new position based on the spline path and set the direction based on displacement + Vector3 lastPos = mFishNodes[i]->getPosition(); mFishNodes[i]->setPosition(mFishSplines[i].interpolate(mFishAnimTime / FISH_PATH_LENGTH)); - mFishNodes[i]->setDirection(mFishNodes[i]->getPosition() - lastPos, Node::TS_PARENT, Vector3::NEGATIVE_UNIT_X); - mFishNodes[i]->setFixedYawAxis(true); + mFishNodes[i]->setDirection(mFishNodes[i]->getPosition() - lastPos, Node::TS_PARENT, Vector3::NEGATIVE_UNIT_X); + mFishNodes[i]->setFixedYawAxis(true); } return SdkSample::frameRenderingQueued(evt); @@ -71,16 +71,16 @@ class _OgreSampleClassExport Sample_Fresnel : public SdkSample, public RenderTar mWater->setVisible(false); // hide the water if (evt.source == mReflectionTarget) // for reflection, turn on camera reflection and hide submerged entities - { - mCamera->enableReflection(mWaterPlane); - for (std::vector::iterator i = mSubmergedEnts.begin(); i != mSubmergedEnts.end(); i++) - (*i)->setVisible(false); - } - else // for refraction, hide surface entities - { - for (std::vector::iterator i = mSurfaceEnts.begin(); i != mSurfaceEnts.end(); i++) - (*i)->setVisible(false); - } + { + mCamera->enableReflection(mWaterPlane); + for (std::vector::iterator i = mSubmergedEnts.begin(); i != mSubmergedEnts.end(); i++) + (*i)->setVisible(false); + } + else // for refraction, hide surface entities + { + for (std::vector::iterator i = mSurfaceEnts.begin(); i != mSurfaceEnts.end(); i++) + (*i)->setVisible(false); + } } void postRenderTargetUpdate(const RenderTargetEvent& evt) @@ -88,24 +88,24 @@ class _OgreSampleClassExport Sample_Fresnel : public SdkSample, public RenderTar mWater->setVisible(true); // unhide the water if (evt.source == mReflectionTarget) // for reflection, turn off camera reflection and unhide submerged entities - { - mCamera->disableReflection(); - for (std::vector::iterator i = mSubmergedEnts.begin(); i != mSubmergedEnts.end(); i++) - (*i)->setVisible(true); - } - else // for refraction, unhide surface entities - { - for (std::vector::iterator i = mSurfaceEnts.begin(); i != mSurfaceEnts.end(); i++) - (*i)->setVisible(true); - } + { + mCamera->disableReflection(); + for (std::vector::iterator i = mSubmergedEnts.begin(); i != mSubmergedEnts.end(); i++) + (*i)->setVisible(true); + } + else // for refraction, unhide surface entities + { + for (std::vector::iterator i = mSurfaceEnts.begin(); i != mSurfaceEnts.end(); i++) + (*i)->setVisible(true); + } } protected: - void setupContent() - { + void setupContent() + { mCamera->setPosition(-50, 125, 760); - mCameraMan->setTopSpeed(280); + mCameraMan->setTopSpeed(280); mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); // set ambient light @@ -116,37 +116,37 @@ class _OgreSampleClassExport Sample_Fresnel : public SdkSample, public RenderTar l->setType(Light::LT_DIRECTIONAL); l->setDirection(Vector3::NEGATIVE_UNIT_Y); - setupWater(); - setupProps(); - setupFish(); - } + setupWater(); + setupProps(); + setupFish(); + } - void setupWater() - { - // create our reflection & refraction render textures, and setup their render targets - for (unsigned int i = 0; i < 2; i++) - { - TexturePtr tex = TextureManager::getSingleton().createManual(i == 0 ? "refraction" : "reflection", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 512, 512, 0, PF_R8G8B8, TU_RENDERTARGET); + void setupWater() + { + // create our reflection & refraction render textures, and setup their render targets + for (unsigned int i = 0; i < 2; i++) + { + TexturePtr tex = TextureManager::getSingleton().createManual(i == 0 ? "refraction" : "reflection", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 512, 512, 0, PF_R8G8B8, TU_RENDERTARGET); - RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); - rtt->addViewport(mCamera)->setOverlaysEnabled(false); - rtt->addListener(this); + RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); + rtt->addViewport(mCamera)->setOverlaysEnabled(false); + rtt->addListener(this); - if (i == 0) mRefractionTarget = rtt; - else mReflectionTarget = rtt; - } + if (i == 0) mRefractionTarget = rtt; + else mReflectionTarget = rtt; + } - // create our water plane mesh + // create our water plane mesh mWaterPlane = Plane(Vector3::UNIT_Y, 0); MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, 700, 1300, 10, 10, true, 1, 3, 5, Vector3::UNIT_Z); - // create a water entity using our mesh, give it the shader material, and attach it to the origin + // create a water entity using our mesh, give it the shader material, and attach it to the origin mWater = mSceneMgr->createEntity("Water", "water"); mWater->setMaterialName("Examples/FresnelReflectionRefraction"); mSceneMgr->getRootSceneNode()->attachObject(mWater); - } + } void windowUpdate() { @@ -155,70 +155,70 @@ class _OgreSampleClassExport Sample_Fresnel : public SdkSample, public RenderTar #endif } - void setupProps() - { + void setupProps() + { Entity* ent; - // setting up props might take a while, so create a progress bar for visual feedback - ProgressBar* pb = mTrayMgr->createProgressBar(TL_CENTER, "FresnelBuildingBar", "Creating Props...", 280, 100); - mTrayMgr->showBackdrop("SdkTrays/Shade"); + // setting up props might take a while, so create a progress bar for visual feedback + ProgressBar* pb = mTrayMgr->createProgressBar(TL_CENTER, "FresnelBuildingBar", "Creating Props...", 280, 100); + mTrayMgr->showBackdrop("SdkTrays/Shade"); - pb->setComment("Upper Bath"); - windowUpdate(); + pb->setComment("Upper Bath"); + windowUpdate(); ent = mSceneMgr->createEntity("UpperBath", "RomanBathUpper.mesh" ); - mSceneMgr->getRootSceneNode()->attachObject(ent); + mSceneMgr->getRootSceneNode()->attachObject(ent); mSurfaceEnts.push_back(ent); - pb->setProgress(0.4); + pb->setProgress(0.4); - pb->setComment("Columns"); - windowUpdate(); + pb->setComment("Columns"); + windowUpdate(); ent = mSceneMgr->createEntity("Columns", "columns.mesh"); - mSceneMgr->getRootSceneNode()->attachObject(ent); + mSceneMgr->getRootSceneNode()->attachObject(ent); mSurfaceEnts.push_back(ent); - pb->setProgress(0.5); + pb->setProgress(0.5); - pb->setComment("Ogre Head"); - windowUpdate(); - ent = mSceneMgr->createEntity("Head", "ogrehead.mesh"); - ent->setMaterialName("RomanBath/OgreStone"); + pb->setComment("Ogre Head"); + windowUpdate(); + ent = mSceneMgr->createEntity("Head", "ogrehead.mesh"); + ent->setMaterialName("RomanBath/OgreStone"); mSurfaceEnts.push_back(ent); - pb->setProgress(0.6); + pb->setProgress(0.6); - SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - headNode->setPosition(-350, 55, 130); - headNode->yaw(Degree(90)); + SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + headNode->setPosition(-350, 55, 130); + headNode->yaw(Degree(90)); headNode->attachObject(ent); - pb->setComment("Lower Bath"); - windowUpdate(); - ent = mSceneMgr->createEntity("LowerBath", "RomanBathLower.mesh"); + pb->setComment("Lower Bath"); + windowUpdate(); + ent = mSceneMgr->createEntity("LowerBath", "RomanBathLower.mesh"); mSceneMgr->getRootSceneNode()->attachObject(ent); mSubmergedEnts.push_back(ent); - pb->setProgress(1); - windowUpdate(); + pb->setProgress(1); + windowUpdate(); - mTrayMgr->destroyWidget(pb); - mTrayMgr->hideBackdrop(); - } + mTrayMgr->destroyWidget(pb); + mTrayMgr->hideBackdrop(); + } - void setupFish() - { - mFishNodes.resize(NUM_FISH); - mFishAnimStates.resize(NUM_FISH); - mFishSplines.resize(NUM_FISH); + void setupFish() + { + mFishNodes.resize(NUM_FISH); + mFishAnimStates.resize(NUM_FISH); + mFishSplines.resize(NUM_FISH); - for (unsigned int i = 0; i < NUM_FISH; i++) + for (unsigned int i = 0; i < NUM_FISH; i++) { - // create fish entity + // create fish entity Entity* ent = mSceneMgr->createEntity("Fish" + StringConverter::toString(i + 1), "fish.mesh"); mSubmergedEnts.push_back(ent); - // create an appropriately scaled node and attach the entity - mFishNodes[i] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mFishNodes[i]->setScale(Vector3::UNIT_SCALE * FISH_SCALE); + // create an appropriately scaled node and attach the entity + mFishNodes[i] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mFishNodes[i]->setScale(Vector3::UNIT_SCALE * FISH_SCALE); mFishNodes[i]->attachObject(ent); - // enable and save the swim animation state + // enable and save the swim animation state mFishAnimStates[i] = ent->getAnimationState("swim"); mFishAnimStates[i]->setEnabled(true); @@ -231,49 +231,49 @@ class _OgreSampleClassExport Sample_Fresnel : public SdkSample, public RenderTar if (j > 0) // make sure the waypoint isn't too far from the last, or our fish will be turbo-fish { - const Vector3& lastPos = mFishSplines[i].getPoint(j - 1); - Vector3 delta = pos - lastPos; - if (delta.length() > 750) pos = lastPos + delta.normalisedCopy() * 750; + const Vector3& lastPos = mFishSplines[i].getPoint(j - 1); + Vector3 delta = pos - lastPos; + if (delta.length() > 750) pos = lastPos + delta.normalisedCopy() * 750; } mFishSplines[i].addPoint(pos); } - // close the spline and calculate all the tangents at once + // close the spline and calculate all the tangents at once mFishSplines[i].addPoint(mFishSplines[i].getPoint(0)); mFishSplines[i].recalcTangents(); } - mFishAnimTime = 0; - } - - void cleanupContent() - { - mSurfaceEnts.clear(); - mSubmergedEnts.clear(); - mFishNodes.clear(); - mFishAnimStates.clear(); - mFishSplines.clear(); - - MeshManager::getSingleton().remove("water"); - TextureManager::getSingleton().remove("refraction"); - TextureManager::getSingleton().remove("reflection"); - } - - const unsigned int NUM_FISH; - const unsigned int NUM_FISH_WAYPOINTS; - const unsigned int FISH_PATH_LENGTH; - const Real FISH_SCALE; - std::vector mSurfaceEnts; - std::vector mSubmergedEnts; - RenderTarget* mRefractionTarget; - RenderTarget* mReflectionTarget; - Plane mWaterPlane; - Entity* mWater; - std::vector mFishNodes; - std::vector mFishAnimStates; - std::vector mFishSplines; - Real mFishAnimTime; + mFishAnimTime = 0; + } + + void cleanupContent() + { + mSurfaceEnts.clear(); + mSubmergedEnts.clear(); + mFishNodes.clear(); + mFishAnimStates.clear(); + mFishSplines.clear(); + + MeshManager::getSingleton().remove("water"); + TextureManager::getSingleton().remove("refraction"); + TextureManager::getSingleton().remove("reflection"); + } + + const unsigned int NUM_FISH; + const unsigned int NUM_FISH_WAYPOINTS; + const unsigned int FISH_PATH_LENGTH; + const Real FISH_SCALE; + std::vector mSurfaceEnts; + std::vector mSubmergedEnts; + RenderTarget* mRefractionTarget; + RenderTarget* mReflectionTarget; + Plane mWaterPlane; + Entity* mWater; + std::vector mFishNodes; + std::vector mFishAnimStates; + std::vector mFishSplines; + Real mFishAnimTime; }; #endif diff --git a/Samples/Fresnel/src/Fresnel.cpp b/Samples/Fresnel/src/Fresnel.cpp index b6a77502c6f..6bf5cce2540 100644 --- a/Samples/Fresnel/src/Fresnel.cpp +++ b/Samples/Fresnel/src/Fresnel.cpp @@ -11,17 +11,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Fresnel; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Fresnel; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Grass/src/Grass.cpp b/Samples/Grass/src/Grass.cpp index db29957b2d1..8fba5ebdd48 100644 --- a/Samples/Grass/src/Grass.cpp +++ b/Samples/Grass/src/Grass.cpp @@ -11,17 +11,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Grass; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Grass; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Hair/include/Hair.h b/Samples/Hair/include/Hair.h index 6712a221c51..7a02adb8246 100644 --- a/Samples/Hair/include/Hair.h +++ b/Samples/Hair/include/Hair.h @@ -25,301 +25,301 @@ class _OgreSampleClassExport Sample_Hair : public SdkSample { public: - Sample_Hair() - { - mInfo["Title"] = "Hair"; - mInfo["Description"] = "Sample for terrain, water tessellation and the use of displacement mapping"; - mInfo["Thumbnail"] = "thumb_tesselation.png"; - mInfo["Category"] = "Unsorted"; - mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; - } + Sample_Hair() + { + mInfo["Title"] = "Hair"; + mInfo["Description"] = "Sample for terrain, water tessellation and the use of displacement mapping"; + mInfo["Thumbnail"] = "thumb_tesselation.png"; + mInfo["Category"] = "Unsorted"; + mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; + } - void testCapabilities(const RenderSystemCapabilities* caps) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "This sample is not yet finished." - " Sorry!", "Sample_Hair::testCapabilities"); + void testCapabilities(const RenderSystemCapabilities* caps) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "This sample is not yet finished." + " Sorry!", "Sample_Hair::testCapabilities"); - if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" - " programs, so you cannot run this sample. Sorry!", "Sample_Hair::testCapabilities"); - } - if (!caps->hasCapability(RSC_TESSELLATION_HULL_PROGRAM) || !caps->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Your graphics card does not support tesselation shaders. Sorry!", - "Sample_Hair:testCapabilities"); - } - if (!GpuProgramManager::getSingleton().isSyntaxSupported("vs_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("hs_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ds_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("hlsl")) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model 5.0 needed for this sample, " - "so you cannot run this sample. Sorry!", "Sample_Hair::testCapabilities"); - } - } + if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" + " programs, so you cannot run this sample. Sorry!", "Sample_Hair::testCapabilities"); + } + if (!caps->hasCapability(RSC_TESSELLATION_HULL_PROGRAM) || !caps->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Your graphics card does not support tesselation shaders. Sorry!", + "Sample_Hair:testCapabilities"); + } + if (!GpuProgramManager::getSingleton().isSyntaxSupported("vs_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("hs_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ds_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("hlsl")) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model 5.0 needed for this sample, " + "so you cannot run this sample. Sorry!", "Sample_Hair::testCapabilities"); + } + } - bool frameRenderingQueued(const FrameEvent& evt) - { - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! - } + bool frameRenderingQueued(const FrameEvent& evt) + { + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + } - void checkBoxToggled(CheckBox* box) - { - if (box->getName() == "Wire") - { - if( mCamera->getPolygonMode() == PM_WIREFRAME ) - mCamera->setPolygonMode(PM_SOLID); - else - mCamera->setPolygonMode(PM_WIREFRAME); - } - if (box->getName() == "PlayAnimation") - { - mPlayAnimation = !mPlayAnimation; - } - if (box->getName() == "LoopAnimation") - { - mLoopAnimation = !mLoopAnimation; - } - if (box->getName() == "ShortHair") - { - mShortHair = !mShortHair; - // change mesh / model - } - if (box->getName() == "CurlyHair") - { - mCurlyHair = !mCurlyHair; - // change mesh / model - } - if (box->getName() == "Shadows") - { - mShadows = !mShadows; - // render or not shadows / using Ogre shadows. - } - if (box->getName() == "RenderMStrands") - { - mRenderMStrands = !mRenderMStrands; - - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_RenderMStrands", mRenderMStrands ); - } - if (box->getName() == "RenderSStrands") - { - mRenderSStrands = !mRenderSStrands; - - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_RenderSStrands", mRenderSStrands ); - } - if (box->getName() == "HWTessellation") - { - mHWTessellation = !mHWTessellation; - - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_HWTessellation", mHWTessellation ); - } - if (box->getName() == "DynamicLOD" && mHWTessellation) - { - mDynamicLOD = !mDynamicLOD; - - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_DynamicLOD", mDynamicLOD ); - } - if (box->getName() == "WindForce") - { - mAddWindForce = !mAddWindForce; - } - if (box->getName() == "ComputeShader") - { - mComputeShader = !mComputeShader; - } - if (box->getName() == "SimulationLOD") - { - mSimulationLOD = !mSimulationLOD; - } - if (box->getName() == "Simulate") - { - mSimulate = !mSimulate; - } - if (box->getName() == "ShowCollision") - { - mShowCollision = !mShowCollision; - } - if (box->getName() == "ShowScene") - { - mShowScene = !mShowScene; - } - } + void checkBoxToggled(CheckBox* box) + { + if (box->getName() == "Wire") + { + if( mCamera->getPolygonMode() == PM_WIREFRAME ) + mCamera->setPolygonMode(PM_SOLID); + else + mCamera->setPolygonMode(PM_WIREFRAME); + } + if (box->getName() == "PlayAnimation") + { + mPlayAnimation = !mPlayAnimation; + } + if (box->getName() == "LoopAnimation") + { + mLoopAnimation = !mLoopAnimation; + } + if (box->getName() == "ShortHair") + { + mShortHair = !mShortHair; + // change mesh / model + } + if (box->getName() == "CurlyHair") + { + mCurlyHair = !mCurlyHair; + // change mesh / model + } + if (box->getName() == "Shadows") + { + mShadows = !mShadows; + // render or not shadows / using Ogre shadows. + } + if (box->getName() == "RenderMStrands") + { + mRenderMStrands = !mRenderMStrands; + + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_RenderMStrands", mRenderMStrands ); + } + if (box->getName() == "RenderSStrands") + { + mRenderSStrands = !mRenderSStrands; + + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_RenderSStrands", mRenderSStrands ); + } + if (box->getName() == "HWTessellation") + { + mHWTessellation = !mHWTessellation; + + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_HWTessellation", mHWTessellation ); + } + if (box->getName() == "DynamicLOD" && mHWTessellation) + { + mDynamicLOD = !mDynamicLOD; + + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_DynamicLOD", mDynamicLOD ); + } + if (box->getName() == "WindForce") + { + mAddWindForce = !mAddWindForce; + } + if (box->getName() == "ComputeShader") + { + mComputeShader = !mComputeShader; + } + if (box->getName() == "SimulationLOD") + { + mSimulationLOD = !mSimulationLOD; + } + if (box->getName() == "Simulate") + { + mSimulate = !mSimulate; + } + if (box->getName() == "ShowCollision") + { + mShowCollision = !mShowCollision; + } + if (box->getName() == "ShowScene") + { + mShowScene = !mShowScene; + } + } - void sliderMoved(Slider* slider) - { - if (slider->getName() == "tessellationLOD") - if (!mDynamicLOD && mHWTessellation) - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_ManualLOD", slider->getValue() ); - } - if (slider->getName() == "HairWidth") - if (!mDynamicLOD && mHWTessellation) - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_HairWidth", slider->getValue() ); - } - if (slider->getName()=="LODRate") - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_LODRate", slider->getValue() ); - } - if (slider->getName()=="WindStrength") - if (mAddWindForce) - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_WindStrength", slider->getValue() ); - } - } + void sliderMoved(Slider* slider) + { + if (slider->getName() == "tessellationLOD") + if (!mDynamicLOD && mHWTessellation) + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_ManualLOD", slider->getValue() ); + } + if (slider->getName() == "HairWidth") + if (!mDynamicLOD && mHWTessellation) + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_HairWidth", slider->getValue() ); + } + if (slider->getName()=="LODRate") + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_LODRate", slider->getValue() ); + } + if (slider->getName()=="WindStrength") + if (mAddWindForce) + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Hair" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_WindStrength", slider->getValue() ); + } + } protected: - void setupContent() - { - // create our main node to attach our entities to - mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + void setupContent() + { + // create our main node to attach our entities to + mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000); // set our skybox + mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000); // set our skybox - setupModels(); - setupLights(); - setupControls(); - - // set our camera - mCamera->setFOVy(Ogre::Degree(50.0)); - mCamera->setFOVy(Ogre::Degree(50.0)); - mCamera->setNearClipDistance(0.01f); - mCamera->lookAt(Ogre::Vector3::ZERO); - mCamera->setPosition(0, 0, 500); - + setupModels(); + setupLights(); + setupControls(); + + // set our camera + mCamera->setFOVy(Ogre::Degree(50.0)); + mCamera->setFOVy(Ogre::Degree(50.0)); + mCamera->setNearClipDistance(0.01f); + mCamera->lookAt(Ogre::Vector3::ZERO); + mCamera->setPosition(0, 0, 500); + - // Set our camera to orbit around the origin at a suitable distance - mCameraMan->setStyle(CS_ORBIT); - mCameraMan->setYawPitchDist(Radian(0), Radian(0), 400); + // Set our camera to orbit around the origin at a suitable distance + mCameraMan->setStyle(CS_ORBIT); + mCameraMan->setYawPitchDist(Radian(0), Radian(0), 400); - mTrayMgr->showCursor(); - } + mTrayMgr->showCursor(); + } - void unloadResources() - { + void unloadResources() + { - } + } - void setupModels() - { + void setupModels() + { - } + } - void setupLights() - { - mSceneMgr->setAmbientLight(ColourValue::Black); - mViewport->setBackgroundColour(ColourValue(0.41f, 0.41f, 0.41f)); - } + void setupLights() + { + mSceneMgr->setAmbientLight(ColourValue::Black); + mViewport->setBackgroundColour(ColourValue(0.41f, 0.41f, 0.41f)); + } - void setupControls() - { - mTrayMgr->showCursor(); + void setupControls() + { + mTrayMgr->showCursor(); - // make room for the controls - mTrayMgr->showLogo(TL_TOPRIGHT); - mTrayMgr->showFrameStats(TL_TOPRIGHT); - mTrayMgr->toggleAdvancedFrameStats(); - - mTrayMgr->createCheckBox(TL_TOPLEFT, "Wire", "Render Wire Frame")->setChecked(false, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "PlayAnimation", "Play Animation")->setChecked(false, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "LoopAnimation", "Loop Animation")->setChecked(false, false); - - // create a menu to choose the model displayed - mMeshMenu = mTrayMgr->createLongSelectMenu(TL_LEFT, "Mesh", "Mesh", 370, 290, 10); - for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) - mMeshMenu->addItem(it->first); - - mTrayMgr->createCheckBox(TL_TOPLEFT, "ShortHair", "Short Hair")->setChecked(false, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "CurlyHair", "Curly Hair")->setChecked(false, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Shadows", "Shadows")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "RenderMStrands", "Render M strands")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "RenderSStrands", "Render S strands")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "HWTessellation", "HW Tessellation")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "DynamicLOD", "Dynamic LOD")->setChecked(true, false); - - mManualLOD = mTrayMgr->createThickSlider(TL_TOPLEFT, "tessellationLOD", "Manual tessellation LOD", 200, 40, 1, 50, 50); - mManualLOD->show(); - - mHairWidth = mTrayMgr->createThickSlider(TL_TOPLEFT, "HairWidth", "Hair Width", 200, 40, 1, 100, 100); - mHairWidth->show(); - - mLODRate = mTrayMgr->createThickSlider(TL_TOPLEFT, "LODRate", "LOD Rate", 200, 40, 1, 100, 100); - mLODRate->show(); - - mTrayMgr->createCheckBox(TL_TOPLEFT, "WindForce", "Add wind force")->setChecked(true, false); - - mWindStrength = mTrayMgr->createThickSlider(TL_TOPLEFT, "WindStrength", "Wind Strength", 200, 40, 0.01, 0.25, 25); - mWindStrength->show(); - - mTrayMgr->createCheckBox(TL_TOPLEFT, "ComputeShader", "Compute Shader")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "SimulationLOD", "SimulationLOD")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Simulate", "Simulate")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "ShowCollision", "Show Collision")->setChecked(false, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "ShowScene", "Show Scene")->setChecked(true, false); + // make room for the controls + mTrayMgr->showLogo(TL_TOPRIGHT); + mTrayMgr->showFrameStats(TL_TOPRIGHT); + mTrayMgr->toggleAdvancedFrameStats(); + + mTrayMgr->createCheckBox(TL_TOPLEFT, "Wire", "Render Wire Frame")->setChecked(false, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "PlayAnimation", "Play Animation")->setChecked(false, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "LoopAnimation", "Loop Animation")->setChecked(false, false); + + // create a menu to choose the model displayed + mMeshMenu = mTrayMgr->createLongSelectMenu(TL_LEFT, "Mesh", "Mesh", 370, 290, 10); + for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) + mMeshMenu->addItem(it->first); + + mTrayMgr->createCheckBox(TL_TOPLEFT, "ShortHair", "Short Hair")->setChecked(false, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "CurlyHair", "Curly Hair")->setChecked(false, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Shadows", "Shadows")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "RenderMStrands", "Render M strands")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "RenderSStrands", "Render S strands")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "HWTessellation", "HW Tessellation")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "DynamicLOD", "Dynamic LOD")->setChecked(true, false); + + mManualLOD = mTrayMgr->createThickSlider(TL_TOPLEFT, "tessellationLOD", "Manual tessellation LOD", 200, 40, 1, 50, 50); + mManualLOD->show(); + + mHairWidth = mTrayMgr->createThickSlider(TL_TOPLEFT, "HairWidth", "Hair Width", 200, 40, 1, 100, 100); + mHairWidth->show(); + + mLODRate = mTrayMgr->createThickSlider(TL_TOPLEFT, "LODRate", "LOD Rate", 200, 40, 1, 100, 100); + mLODRate->show(); + + mTrayMgr->createCheckBox(TL_TOPLEFT, "WindForce", "Add wind force")->setChecked(true, false); + + mWindStrength = mTrayMgr->createThickSlider(TL_TOPLEFT, "WindStrength", "Wind Strength", 200, 40, 0.01, 0.25, 25); + mWindStrength->show(); + + mTrayMgr->createCheckBox(TL_TOPLEFT, "ComputeShader", "Compute Shader")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "SimulationLOD", "SimulationLOD")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Simulate", "Simulate")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "ShowCollision", "Show Collision")->setChecked(false, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "ShowScene", "Show Scene")->setChecked(true, false); - // a friendly reminder - StringVector names; - names.push_back("Help"); - mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); - - mPlayAnimation = false; - mLoopAnimation = false; - mShortHair = false; - mCurlyHair = false; - mShadows = true; - mRenderMStrands = true; - mRenderSStrands = true; - mHWTessellation = true; - mDynamicLOD = true; - mAddWindForce = true; - mComputeShader = true; - mSimulationLOD = true; - mSimulate = true; - mShowCollision = false; - mShowScene = true; - } + // a friendly reminder + StringVector names; + names.push_back("Help"); + mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); + + mPlayAnimation = false; + mLoopAnimation = false; + mShortHair = false; + mCurlyHair = false; + mShadows = true; + mRenderMStrands = true; + mRenderSStrands = true; + mHWTessellation = true; + mDynamicLOD = true; + mAddWindForce = true; + mComputeShader = true; + mSimulationLOD = true; + mSimulate = true; + mShowCollision = false; + mShowScene = true; + } - void cleanupContent() - { - // clean up properly to avoid interfering with subsequent samples - } + void cleanupContent() + { + // clean up properly to avoid interfering with subsequent samples + } - SelectMenu* mMeshMenu; - SceneNode* mObjectNode; - bool mPlayAnimation; - bool mLoopAnimation; - - SelectMenu* mColorMenu; - std::map mPossibilities; - - bool mShortHair; - bool mCurlyHair; - bool mShadows; - bool mRenderMStrands; - bool mRenderSStrands; - bool mHWTessellation; - bool mDynamicLOD; - Slider* mManualLOD; - Slider* mHairWidth; - Slider* mLODRate; - bool mAddWindForce; - Slider* mWindStrength; - bool mComputeShader; - bool mSimulationLOD; - bool mSimulate; - bool mShowCollision; - bool mShowScene; + SelectMenu* mMeshMenu; + SceneNode* mObjectNode; + bool mPlayAnimation; + bool mLoopAnimation; + + SelectMenu* mColorMenu; + std::map mPossibilities; + + bool mShortHair; + bool mCurlyHair; + bool mShadows; + bool mRenderMStrands; + bool mRenderSStrands; + bool mHWTessellation; + bool mDynamicLOD; + Slider* mManualLOD; + Slider* mHairWidth; + Slider* mLODRate; + bool mAddWindForce; + Slider* mWindStrength; + bool mComputeShader; + bool mSimulationLOD; + bool mSimulate; + bool mShowCollision; + bool mShowScene; }; #endif \ No newline at end of file diff --git a/Samples/Hair/src/Hair.cpp b/Samples/Hair/src/Hair.cpp index 21fdde4a435..7b1a6d68b30 100644 --- a/Samples/Hair/src/Hair.cpp +++ b/Samples/Hair/src/Hair.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Hair; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Hair; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Instancing/include/Instancing.h b/Samples/Instancing/include/Instancing.h index d3a11a206ee..5291dc9ea13 100644 --- a/Samples/Instancing/include/Instancing.h +++ b/Samples/Instancing/include/Instancing.h @@ -31,369 +31,369 @@ const size_t numTypeMeshes = 4; Ogre::String meshes[]= { - "razor", //0 - "knot", - "tudorhouse", - "WoodPallet"//6 + "razor", //0 + "knot", + "tudorhouse", + "WoodPallet"//6 }; enum CurrentGeomOpt{ - INSTANCE_OPT, - STATIC_OPT, - ENTITY_OPT + INSTANCE_OPT, + STATIC_OPT, + ENTITY_OPT }; class _OgreSampleClassExport Sample_Instancing : public SdkSample { public: - //----------------------------------------------------------------------- - Sample_Instancing() - { - mInfo["Title"] = "Instancing"; - mInfo["Description"] = "A demo of different methods to handle a large number of objects."; - mInfo["Thumbnail"] = "thumb_instancing.png"; - mInfo["Category"] = "Geometry"; - } - - //----------------------------------------------------------------------- - bool frameRenderingQueued(const FrameEvent& evt) - { - burnCPU(); - return SdkSample::frameRenderingQueued(evt); - } + //----------------------------------------------------------------------- + Sample_Instancing() + { + mInfo["Title"] = "Instancing"; + mInfo["Description"] = "A demo of different methods to handle a large number of objects."; + mInfo["Thumbnail"] = "thumb_instancing.png"; + mInfo["Category"] = "Geometry"; + } + + //----------------------------------------------------------------------- + bool frameRenderingQueued(const FrameEvent& evt) + { + burnCPU(); + return SdkSample::frameRenderingQueued(evt); + } protected: - void setObjectCount(size_t val) - { - mNumMeshes=val; - }; - //----------------------------------------------------------------------- - void setBurnedTime(double timeBurned) - { - mBurnAmount=timeBurned; - }; - //----------------------------------------------------------------------- - void changeSelectedMesh(size_t number) - { - mSelectedMesh=number; - } - - //----------------------------------------------------------------------- - void burnCPU() - { - double mStartTime = mTimer->getMicroseconds()/1000000.0f; //convert into seconds - double mCurTime = mStartTime; - double mStopTime = mLastTime + mBurnAmount; - - while( mCurTime < mStopTime ) - { - mCurTime = mTimer->getMicroseconds()/1000000.0f; //convert into seconds - } - - mLastTime = mTimer->getMicroseconds()/1000000.0f; //convert into seconds - } - //----------------------------------------------------------------------- - void destroyCurrentGeomOpt() - { - switch(mCurrentGeomOpt) - { - case INSTANCE_OPT: destroyInstanceGeom(); break; - case STATIC_OPT: destroyStaticGeom(); break; - case ENTITY_OPT: destroyEntityGeom(); break; - } - - assert (mNumRendered == posMatrices.size ()); - for (size_t i = 0; i < mNumRendered; i++) - { - delete [] posMatrices[i]; - } - - posMatrices.clear(); - } - //----------------------------------------------------------------------- - void createCurrentGeomOpt() - { - objectCount = mNumMeshes; - mNumRendered = 1; - - while(objectCount>maxObjectsPerBatch) - { - mNumRendered++; - objectCount-=maxObjectsPerBatch; - } - - assert (mSelectedMesh < numTypeMeshes); - MeshPtr m = MeshManager::getSingleton ().getByName (meshes[mSelectedMesh] + ".mesh"); - if (m.isNull ()) - { - m = MeshManager::getSingleton ().load (meshes[mSelectedMesh] + ".mesh", - ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); - } - const Real radius = m->getBoundingSphereRadius (); - - // could/should print on screen mesh name, - //optimisation type, - //mesh vertices num, - //32 bit or not, - //etC.. - - - - posMatrices.resize (mNumRendered); - posMatrices.reserve (mNumRendered); - - - vector ::type posMatCurr; - posMatCurr.resize (mNumRendered); - posMatCurr.reserve (mNumRendered); - for (size_t i = 0; i < mNumRendered; i++) - { - posMatrices[i] = new Vector3[mNumMeshes]; - posMatCurr[i] = posMatrices[i]; - } - - size_t i = 0, j = 0; - for (size_t p = 0; p < mNumMeshes; p++) - { - for (size_t k = 0; k < mNumRendered; k++) - { - posMatCurr[k]->x = radius*i; - posMatCurr[k]->y = k*radius; - - posMatCurr[k]->z = radius*j; - posMatCurr[k]++; - } - if (++j== 10) - { - j = 0; - i++; - } - - } - posMatCurr.clear (); - - - switch(mCurrentGeomOpt) - { - case INSTANCE_OPT:createInstanceGeom();break; - case STATIC_OPT:createStaticGeom ();break; - case ENTITY_OPT: createEntityGeom ();break; - } - } - //----------------------------------------------------------------------- - void createInstanceGeom() - { - if (Root::getSingleton ().getRenderSystem ()->getCapabilities ()->hasCapability (RSC_VERTEX_PROGRAM) == false) - { - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Your video card doesn't support batching", "Demo_Instance::createScene"); - } - - Entity *ent = mSceneMgr->createEntity(meshes[mSelectedMesh], meshes[mSelectedMesh] + ".mesh"); - - - renderInstance.reserve(mNumRendered); - renderInstance.resize(mNumRendered); - - //Load a mesh to read data from. - InstancedGeometry* batch = mSceneMgr->createInstancedGeometry(meshes[mSelectedMesh] + "s" ); - batch->setCastShadows(true); - - batch->setBatchInstanceDimensions (Vector3(1000000, 1000000, 1000000)); - const size_t batchSize = (mNumMeshes > maxObjectsPerBatch) ? maxObjectsPerBatch :mNumMeshes; - setupInstancedMaterialToEntity(ent); - for(size_t i = 0; i < batchSize ; i++) - { - batch->addEntity(ent, Vector3::ZERO); - } - batch->setOrigin(Vector3::ZERO); - - batch->build(); - - - for (size_t k = 0; k < mNumRendered-1; k++) - { - batch->addBatchInstance(); - } - InstancedGeometry::BatchInstanceIterator regIt = batch->getBatchInstanceIterator(); - size_t k = 0; - while (regIt.hasMoreElements ()) - { - - InstancedGeometry::BatchInstance *r = regIt.getNext(); - - InstancedGeometry::BatchInstance::InstancedObjectIterator bit = r->getObjectIterator(); - int j = 0; - while(bit.hasMoreElements()) - { - InstancedGeometry::InstancedObject* obj = bit.getNext(); - - const Vector3 position (posMatrices[k][j]); - obj->setPosition(position); - ++j; - - } - k++; - - } - batch->setVisible(true); - renderInstance[0] = batch; - - mSceneMgr->destroyEntity (ent); - } - void setupInstancedMaterialToEntity(Entity*ent) - { - for (Ogre::uint i = 0; i < ent->getNumSubEntities(); ++i) - { - SubEntity* se = ent->getSubEntity(i); - String materialName= se->getMaterialName(); - se->setMaterialName(buildInstancedMaterial(materialName)); - } - } - String buildInstancedMaterial(const String &originalMaterialName) - { - // already instanced ? - if (StringUtil::endsWith (originalMaterialName, "/instanced")) - return originalMaterialName; - - MaterialPtr originalMaterial = MaterialManager::getSingleton ().getByName (originalMaterialName); + void setObjectCount(size_t val) + { + mNumMeshes=val; + }; + //----------------------------------------------------------------------- + void setBurnedTime(double timeBurned) + { + mBurnAmount=timeBurned; + }; + //----------------------------------------------------------------------- + void changeSelectedMesh(size_t number) + { + mSelectedMesh=number; + } + + //----------------------------------------------------------------------- + void burnCPU() + { + double mStartTime = mTimer->getMicroseconds()/1000000.0f; //convert into seconds + double mCurTime = mStartTime; + double mStopTime = mLastTime + mBurnAmount; + + while( mCurTime < mStopTime ) + { + mCurTime = mTimer->getMicroseconds()/1000000.0f; //convert into seconds + } + + mLastTime = mTimer->getMicroseconds()/1000000.0f; //convert into seconds + } + //----------------------------------------------------------------------- + void destroyCurrentGeomOpt() + { + switch(mCurrentGeomOpt) + { + case INSTANCE_OPT: destroyInstanceGeom(); break; + case STATIC_OPT: destroyStaticGeom(); break; + case ENTITY_OPT: destroyEntityGeom(); break; + } + + assert (mNumRendered == posMatrices.size ()); + for (size_t i = 0; i < mNumRendered; i++) + { + delete [] posMatrices[i]; + } + + posMatrices.clear(); + } + //----------------------------------------------------------------------- + void createCurrentGeomOpt() + { + objectCount = mNumMeshes; + mNumRendered = 1; + + while(objectCount>maxObjectsPerBatch) + { + mNumRendered++; + objectCount-=maxObjectsPerBatch; + } + + assert (mSelectedMesh < numTypeMeshes); + MeshPtr m = MeshManager::getSingleton ().getByName (meshes[mSelectedMesh] + ".mesh"); + if (m.isNull ()) + { + m = MeshManager::getSingleton ().load (meshes[mSelectedMesh] + ".mesh", + ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + } + const Real radius = m->getBoundingSphereRadius (); + + // could/should print on screen mesh name, + //optimisation type, + //mesh vertices num, + //32 bit or not, + //etC.. + + + + posMatrices.resize (mNumRendered); + posMatrices.reserve (mNumRendered); + + + vector ::type posMatCurr; + posMatCurr.resize (mNumRendered); + posMatCurr.reserve (mNumRendered); + for (size_t i = 0; i < mNumRendered; i++) + { + posMatrices[i] = new Vector3[mNumMeshes]; + posMatCurr[i] = posMatrices[i]; + } + + size_t i = 0, j = 0; + for (size_t p = 0; p < mNumMeshes; p++) + { + for (size_t k = 0; k < mNumRendered; k++) + { + posMatCurr[k]->x = radius*i; + posMatCurr[k]->y = k*radius; + + posMatCurr[k]->z = radius*j; + posMatCurr[k]++; + } + if (++j== 10) + { + j = 0; + i++; + } + + } + posMatCurr.clear (); + + + switch(mCurrentGeomOpt) + { + case INSTANCE_OPT:createInstanceGeom();break; + case STATIC_OPT:createStaticGeom ();break; + case ENTITY_OPT: createEntityGeom ();break; + } + } + //----------------------------------------------------------------------- + void createInstanceGeom() + { + if (Root::getSingleton ().getRenderSystem ()->getCapabilities ()->hasCapability (RSC_VERTEX_PROGRAM) == false) + { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Your video card doesn't support batching", "Demo_Instance::createScene"); + } + + Entity *ent = mSceneMgr->createEntity(meshes[mSelectedMesh], meshes[mSelectedMesh] + ".mesh"); + + + renderInstance.reserve(mNumRendered); + renderInstance.resize(mNumRendered); + + //Load a mesh to read data from. + InstancedGeometry* batch = mSceneMgr->createInstancedGeometry(meshes[mSelectedMesh] + "s" ); + batch->setCastShadows(true); + + batch->setBatchInstanceDimensions (Vector3(1000000, 1000000, 1000000)); + const size_t batchSize = (mNumMeshes > maxObjectsPerBatch) ? maxObjectsPerBatch :mNumMeshes; + setupInstancedMaterialToEntity(ent); + for(size_t i = 0; i < batchSize ; i++) + { + batch->addEntity(ent, Vector3::ZERO); + } + batch->setOrigin(Vector3::ZERO); + + batch->build(); + + + for (size_t k = 0; k < mNumRendered-1; k++) + { + batch->addBatchInstance(); + } + InstancedGeometry::BatchInstanceIterator regIt = batch->getBatchInstanceIterator(); + size_t k = 0; + while (regIt.hasMoreElements ()) + { + + InstancedGeometry::BatchInstance *r = regIt.getNext(); + + InstancedGeometry::BatchInstance::InstancedObjectIterator bit = r->getObjectIterator(); + int j = 0; + while(bit.hasMoreElements()) + { + InstancedGeometry::InstancedObject* obj = bit.getNext(); + + const Vector3 position (posMatrices[k][j]); + obj->setPosition(position); + ++j; + + } + k++; + + } + batch->setVisible(true); + renderInstance[0] = batch; + + mSceneMgr->destroyEntity (ent); + } + void setupInstancedMaterialToEntity(Entity*ent) + { + for (Ogre::uint i = 0; i < ent->getNumSubEntities(); ++i) + { + SubEntity* se = ent->getSubEntity(i); + String materialName= se->getMaterialName(); + se->setMaterialName(buildInstancedMaterial(materialName)); + } + } + String buildInstancedMaterial(const String &originalMaterialName) + { + // already instanced ? + if (StringUtil::endsWith (originalMaterialName, "/instanced")) + return originalMaterialName; + + MaterialPtr originalMaterial = MaterialManager::getSingleton ().getByName (originalMaterialName); #if defined(INCLUDE_RTSHADER_SYSTEM) originalMaterial->getBestTechnique()->setSchemeName(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); #endif - // if originalMat doesn't exists use "Instancing" material name - const String instancedMaterialName (originalMaterial.isNull() ? "Instancing" : originalMaterialName + "/Instanced"); - MaterialPtr instancedMaterial = MaterialManager::getSingleton ().getByName (instancedMaterialName); + // if originalMat doesn't exists use "Instancing" material name + const String instancedMaterialName (originalMaterial.isNull() ? "Instancing" : originalMaterialName + "/Instanced"); + MaterialPtr instancedMaterial = MaterialManager::getSingleton ().getByName (instancedMaterialName); - // already exists ? - if (instancedMaterial.isNull()) - { - instancedMaterial = originalMaterial->clone(instancedMaterialName); - instancedMaterial->load(); - Technique::PassIterator pIt = instancedMaterial->getBestTechnique ()->getPassIterator(); - while (pIt.hasMoreElements()) - { + // already exists ? + if (instancedMaterial.isNull()) + { + instancedMaterial = originalMaterial->clone(instancedMaterialName); + instancedMaterial->load(); + Technique::PassIterator pIt = instancedMaterial->getBestTechnique ()->getPassIterator(); + while (pIt.hasMoreElements()) + { - Pass * const p = pIt.getNext(); - p->setVertexProgram("Instancing", false); - p->setShadowCasterVertexProgram("InstancingShadowCaster"); + Pass * const p = pIt.getNext(); + p->setVertexProgram("Instancing", false); + p->setShadowCasterVertexProgram("InstancingShadowCaster"); - } - } - instancedMaterial->load(); - return instancedMaterialName; + } + } + instancedMaterial->load(); + return instancedMaterialName; - } - //----------------------------------------------------------------------- - void destroyInstanceGeom() - { + } + //----------------------------------------------------------------------- + void destroyInstanceGeom() + { mSceneMgr->destroyAllInstancedGeometry(); - renderInstance.clear(); - } - //----------------------------------------------------------------------- - void createStaticGeom() - { - Entity *ent = mSceneMgr->createEntity(meshes[mSelectedMesh], meshes[mSelectedMesh] + ".mesh"); - - renderStatic.reserve (mNumRendered); - renderStatic.resize (mNumRendered); - - StaticGeometry* geom = mSceneMgr->createStaticGeometry(meshes[mSelectedMesh] + "s"); - - geom->setRegionDimensions (Vector3(1000000, 1000000, 1000000)); - size_t k = 0; - size_t y = 0; - for (size_t i = 0; i < mNumMeshes; i++) - { - if (y==maxObjectsPerBatch) - { - y=0; - k++; - } - geom->addEntity (ent, posMatrices[k][y]); - y++; - } - geom->setCastShadows(true); - geom->build (); - renderStatic[0] = geom; - mSceneMgr->destroyEntity (ent); - } - //----------------------------------------------------------------------- - void destroyStaticGeom() - { + renderInstance.clear(); + } + //----------------------------------------------------------------------- + void createStaticGeom() + { + Entity *ent = mSceneMgr->createEntity(meshes[mSelectedMesh], meshes[mSelectedMesh] + ".mesh"); + + renderStatic.reserve (mNumRendered); + renderStatic.resize (mNumRendered); + + StaticGeometry* geom = mSceneMgr->createStaticGeometry(meshes[mSelectedMesh] + "s"); + + geom->setRegionDimensions (Vector3(1000000, 1000000, 1000000)); + size_t k = 0; + size_t y = 0; + for (size_t i = 0; i < mNumMeshes; i++) + { + if (y==maxObjectsPerBatch) + { + y=0; + k++; + } + geom->addEntity (ent, posMatrices[k][y]); + y++; + } + geom->setCastShadows(true); + geom->build (); + renderStatic[0] = geom; + mSceneMgr->destroyEntity (ent); + } + //----------------------------------------------------------------------- + void destroyStaticGeom() + { mSceneMgr->destroyAllStaticGeometry(); - renderStatic.clear(); - } - //----------------------------------------------------------------------- - void createEntityGeom() - { - size_t k = 0; - size_t y = 0; - renderEntity.reserve (mNumMeshes); - renderEntity.resize (mNumMeshes); - nodes.reserve (mNumMeshes); - nodes.resize (mNumMeshes); - - for (size_t i = 0; i < mNumMeshes; i++) - { - if (y==maxObjectsPerBatch) - { - y=0; - k++; - } - - nodes[i]=mSceneMgr->getRootSceneNode()->createChildSceneNode("node"+StringConverter::toString(i)); - renderEntity[i]=mSceneMgr->createEntity(meshes[mSelectedMesh]+StringConverter::toString(i), meshes[mSelectedMesh] + ".mesh"); - nodes[i]->attachObject(renderEntity[i]); - nodes[i]->setPosition(posMatrices[k][y]); - - y++; - } - - } - //----------------------------------------------------------------------- - void destroyEntityGeom() - { - size_t i; - size_t j=0; - for (i=0;igetName(); - mSceneMgr->destroySceneNode(name); - mSceneMgr->destroyEntity(renderEntity[i]); - j++; - } - } - - void setCurrentGeometryOpt(CurrentGeomOpt opt) - { - mCurrentGeomOpt=opt; - } + renderStatic.clear(); + } + //----------------------------------------------------------------------- + void createEntityGeom() + { + size_t k = 0; + size_t y = 0; + renderEntity.reserve (mNumMeshes); + renderEntity.resize (mNumMeshes); + nodes.reserve (mNumMeshes); + nodes.resize (mNumMeshes); + + for (size_t i = 0; i < mNumMeshes; i++) + { + if (y==maxObjectsPerBatch) + { + y=0; + k++; + } + + nodes[i]=mSceneMgr->getRootSceneNode()->createChildSceneNode("node"+StringConverter::toString(i)); + renderEntity[i]=mSceneMgr->createEntity(meshes[mSelectedMesh]+StringConverter::toString(i), meshes[mSelectedMesh] + ".mesh"); + nodes[i]->attachObject(renderEntity[i]); + nodes[i]->setPosition(posMatrices[k][y]); + + y++; + } + + } + //----------------------------------------------------------------------- + void destroyEntityGeom() + { + size_t i; + size_t j=0; + for (i=0;igetName(); + mSceneMgr->destroySceneNode(name); + mSceneMgr->destroyEntity(renderEntity[i]); + j++; + } + } + + void setCurrentGeometryOpt(CurrentGeomOpt opt) + { + mCurrentGeomOpt=opt; + } - //----------------------------------------------------------------------- - // Just override the mandatory create scene method - void setupContent() - { - // Set ambient light - mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); - Light* l = mSceneMgr->createLight("MainLight"); - //add a skybox - mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox", 1000); - //setup the light - l->setType(Light::LT_DIRECTIONAL); - l->setDirection(-0.5, -0.5, 0); - - mCamera->setPosition(500,500, 1500); - mCamera->lookAt(0,0,0); + //----------------------------------------------------------------------- + // Just override the mandatory create scene method + void setupContent() + { + // Set ambient light + mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); + Light* l = mSceneMgr->createLight("MainLight"); + //add a skybox + mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox", 1000); + //setup the light + l->setType(Light::LT_DIRECTIONAL); + l->setDirection(-0.5, -0.5, 0); + + mCamera->setPosition(500,500, 1500); + mCamera->lookAt(0,0,0); #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS setDragLook(true); #endif - Plane plane; + Plane plane; plane.normal = Vector3::UNIT_Y; plane.d = 100; MeshManager::getSingleton().createPlane("Myplane", @@ -403,122 +403,122 @@ class _OgreSampleClassExport Sample_Instancing : public SdkSample pPlaneEnt->setMaterialName("Examples/Rockwall"); pPlaneEnt->setCastShadows(false); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); - - CompositorManager::getSingleton().addCompositor(mViewport,"Bloom"); - - setupControls(); - - mNumMeshes = 160; - mNumRendered = 0; - mSelectedMesh = 0; - mBurnAmount = 0; - mCurrentGeomOpt = INSTANCE_OPT; - createCurrentGeomOpt(); - - mTimer = new Ogre::Timer(); - mLastTime = mTimer->getMicroseconds() / 1000000.0f; - } - - //----------------------------------------------------------------------- - void setupControls() - { - SelectMenu* technique = mTrayMgr->createThickSelectMenu(TL_TOPLEFT, "TechniqueType", "Instancing Technique", 200, 3); - technique->addItem("Instancing"); - technique->addItem("Static Geometry"); - technique->addItem("Independent Entities"); - - SelectMenu* objectType = mTrayMgr->createThickSelectMenu(TL_TOPLEFT, "ObjectType", "Object : ", 200, 4); - objectType->addItem("razor"); - objectType->addItem("knot"); - objectType->addItem("tudorhouse"); - objectType->addItem("woodpallet"); - - mTrayMgr->createThickSlider(TL_TOPLEFT, "ObjectCountSlider", "Object count", 200, 50, 0, 1000, 101)->setValue(160, false); - - mTrayMgr->createThickSlider(TL_TOPLEFT, "CPUOccupationSlider", "CPU Load (ms)", 200, 75, 0, 1000.0f / 60, 20); - - mTrayMgr->createCheckBox(TL_TOPLEFT, "ShadowCheckBox", "Shadows", 200); - - mTrayMgr->createCheckBox(TL_TOPLEFT, "PostEffectCheckBox", "Post Effect", 200); - - mTrayMgr->showCursor(); - } - - void cleanupContent() - { + + CompositorManager::getSingleton().addCompositor(mViewport,"Bloom"); + + setupControls(); + + mNumMeshes = 160; + mNumRendered = 0; + mSelectedMesh = 0; + mBurnAmount = 0; + mCurrentGeomOpt = INSTANCE_OPT; + createCurrentGeomOpt(); + + mTimer = new Ogre::Timer(); + mLastTime = mTimer->getMicroseconds() / 1000000.0f; + } + + //----------------------------------------------------------------------- + void setupControls() + { + SelectMenu* technique = mTrayMgr->createThickSelectMenu(TL_TOPLEFT, "TechniqueType", "Instancing Technique", 200, 3); + technique->addItem("Instancing"); + technique->addItem("Static Geometry"); + technique->addItem("Independent Entities"); + + SelectMenu* objectType = mTrayMgr->createThickSelectMenu(TL_TOPLEFT, "ObjectType", "Object : ", 200, 4); + objectType->addItem("razor"); + objectType->addItem("knot"); + objectType->addItem("tudorhouse"); + objectType->addItem("woodpallet"); + + mTrayMgr->createThickSlider(TL_TOPLEFT, "ObjectCountSlider", "Object count", 200, 50, 0, 1000, 101)->setValue(160, false); + + mTrayMgr->createThickSlider(TL_TOPLEFT, "CPUOccupationSlider", "CPU Load (ms)", 200, 75, 0, 1000.0f / 60, 20); + + mTrayMgr->createCheckBox(TL_TOPLEFT, "ShadowCheckBox", "Shadows", 200); + + mTrayMgr->createCheckBox(TL_TOPLEFT, "PostEffectCheckBox", "Post Effect", 200); + + mTrayMgr->showCursor(); + } + + void cleanupContent() + { mSceneMgr->destroyAllInstancedGeometry(); mSceneMgr->destroyAllStaticGeometry(); MeshManager::getSingleton().remove("Myplane"); - destroyCurrentGeomOpt(); - delete mTimer; - } - - void sliderMoved(Slider* slider) - { - if (slider->getName() == "ObjectCountSlider") - { - destroyCurrentGeomOpt(); - setObjectCount((size_t)slider->getValue()); - createCurrentGeomOpt(); - } - else if (slider->getName() == "CPUOccupationSlider") - { - setBurnedTime(slider->getValue() / 1000.0f); - } - } - - void itemSelected(SelectMenu* menu) - { - if (menu->getName() == "TechniqueType") - { - //Menu items are synchronized with enum - CurrentGeomOpt selectedOption = (CurrentGeomOpt)menu->getSelectionIndex(); - destroyCurrentGeomOpt(); - setCurrentGeometryOpt(selectedOption); - createCurrentGeomOpt(); - } - else if (menu->getName() == "ObjectType") - { - destroyCurrentGeomOpt(); - changeSelectedMesh(menu->getSelectionIndex()); - createCurrentGeomOpt(); - } - } - - void checkBoxToggled(CheckBox* box) - { - if (box->getName() == "ShadowCheckBox") - { - if (box->isChecked()) - { - mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); - } - else - { - mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); - } - } - else if (box->getName() == "PostEffectCheckBox") - { - CompositorManager::getSingleton().setCompositorEnabled(mViewport,"Bloom",box->isChecked()); - } - } - - double mAvgFrameTime; - size_t mSelectedMesh; - size_t mNumMeshes; - size_t objectCount; - String mDebugText; - CurrentGeomOpt mCurrentGeomOpt; - - size_t mNumRendered; - - Ogre::Timer*mTimer; - double mLastTime, mBurnAmount; - - vector ::type renderInstance; - vector ::type renderStatic; - vector ::type renderEntity; - vector ::type nodes; - vector ::type posMatrices; + destroyCurrentGeomOpt(); + delete mTimer; + } + + void sliderMoved(Slider* slider) + { + if (slider->getName() == "ObjectCountSlider") + { + destroyCurrentGeomOpt(); + setObjectCount((size_t)slider->getValue()); + createCurrentGeomOpt(); + } + else if (slider->getName() == "CPUOccupationSlider") + { + setBurnedTime(slider->getValue() / 1000.0f); + } + } + + void itemSelected(SelectMenu* menu) + { + if (menu->getName() == "TechniqueType") + { + //Menu items are synchronized with enum + CurrentGeomOpt selectedOption = (CurrentGeomOpt)menu->getSelectionIndex(); + destroyCurrentGeomOpt(); + setCurrentGeometryOpt(selectedOption); + createCurrentGeomOpt(); + } + else if (menu->getName() == "ObjectType") + { + destroyCurrentGeomOpt(); + changeSelectedMesh(menu->getSelectionIndex()); + createCurrentGeomOpt(); + } + } + + void checkBoxToggled(CheckBox* box) + { + if (box->getName() == "ShadowCheckBox") + { + if (box->isChecked()) + { + mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); + } + else + { + mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); + } + } + else if (box->getName() == "PostEffectCheckBox") + { + CompositorManager::getSingleton().setCompositorEnabled(mViewport,"Bloom",box->isChecked()); + } + } + + double mAvgFrameTime; + size_t mSelectedMesh; + size_t mNumMeshes; + size_t objectCount; + String mDebugText; + CurrentGeomOpt mCurrentGeomOpt; + + size_t mNumRendered; + + Ogre::Timer*mTimer; + double mLastTime, mBurnAmount; + + vector ::type renderInstance; + vector ::type renderStatic; + vector ::type renderEntity; + vector ::type nodes; + vector ::type posMatrices; }; diff --git a/Samples/Instancing/src/Instancing.cpp b/Samples/Instancing/src/Instancing.cpp index e8221d4ad12..b26f37e816e 100644 --- a/Samples/Instancing/src/Instancing.cpp +++ b/Samples/Instancing/src/Instancing.cpp @@ -28,17 +28,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Instancing; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Instancing; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Island/include/Island.h b/Samples/Island/include/Island.h index d81ce6adcce..10b65870d34 100644 --- a/Samples/Island/include/Island.h +++ b/Samples/Island/include/Island.h @@ -11,177 +11,177 @@ class _OgreSampleClassExport Sample_Island : public SdkSample { public: - Sample_Island() - { - mInfo["Title"] = "Island"; - mInfo["Description"] = "Sample for terrain, water tessellation and the use of displacement mapping"; - mInfo["Thumbnail"] = "thumb_tesselation.png"; - mInfo["Category"] = "Unsorted"; - mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; - } - - void testCapabilities(const RenderSystemCapabilities* caps) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "This sample is not yet finished." - " Sorry!", "Sample_Island::testCapabilities"); - - if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" - " programs, so you cannot run this sample. Sorry!", "Sample_Island::testCapabilities"); - } - if (!caps->hasCapability(RSC_TESSELLATION_HULL_PROGRAM) || !caps->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Your graphics card does not support tesselation shaders. Sorry!", - "Sample_Island:testCapabilities"); - } - if (!GpuProgramManager::getSingleton().isSyntaxSupported("vs_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("hs_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ds_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("hlsl")) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model 5.0 needed for this sample, " - "so you cannot run this sample. Sorry!", "Sample_Island::testCapabilities"); - } - } - - bool frameRenderingQueued(const FrameEvent& evt) - { - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! - } - - void checkBoxToggled(CheckBox* box) - { - if (box->getName() == "Wire") - { - if( mCamera->getPolygonMode() == PM_WIREFRAME ) - mCamera->setPolygonMode(PM_SOLID); - else - mCamera->setPolygonMode(PM_WIREFRAME); - } - if (box->getName() == "Tessellation") - { - g_UseDynamicLOD = !g_UseDynamicLOD; - - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Island" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_UseDynamicLOD", g_UseDynamicLOD ); - } - if (box->getName() == "FrustumCull") - { - g_FrustumCullInHS = !g_FrustumCullInHS; - - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Island" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_FrustumCullInHS", g_FrustumCullInHS ); - } - if (box->getName() == "RenderRefraction") - { - g_RenderCaustics = !g_RenderCaustics; - - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Island" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_RenderCaustics", g_RenderCaustics ); - } - } - - void sliderMoved(Slider* slider) - { - if (slider->getName() == "tessellationLOD") - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Island" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_DynamicTessFactor", slider->getValue() ); - } - if (slider->getName() == "tessellationFactor") - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Island" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_StaticTessFactor", slider->getValue() ); - } - } + Sample_Island() + { + mInfo["Title"] = "Island"; + mInfo["Description"] = "Sample for terrain, water tessellation and the use of displacement mapping"; + mInfo["Thumbnail"] = "thumb_tesselation.png"; + mInfo["Category"] = "Unsorted"; + mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; + } + + void testCapabilities(const RenderSystemCapabilities* caps) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "This sample is not yet finished." + " Sorry!", "Sample_Island::testCapabilities"); + + if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" + " programs, so you cannot run this sample. Sorry!", "Sample_Island::testCapabilities"); + } + if (!caps->hasCapability(RSC_TESSELLATION_HULL_PROGRAM) || !caps->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Your graphics card does not support tesselation shaders. Sorry!", + "Sample_Island:testCapabilities"); + } + if (!GpuProgramManager::getSingleton().isSyntaxSupported("vs_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("hs_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ds_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("hlsl")) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model 5.0 needed for this sample, " + "so you cannot run this sample. Sorry!", "Sample_Island::testCapabilities"); + } + } + + bool frameRenderingQueued(const FrameEvent& evt) + { + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + } + + void checkBoxToggled(CheckBox* box) + { + if (box->getName() == "Wire") + { + if( mCamera->getPolygonMode() == PM_WIREFRAME ) + mCamera->setPolygonMode(PM_SOLID); + else + mCamera->setPolygonMode(PM_WIREFRAME); + } + if (box->getName() == "Tessellation") + { + g_UseDynamicLOD = !g_UseDynamicLOD; + + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Island" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_UseDynamicLOD", g_UseDynamicLOD ); + } + if (box->getName() == "FrustumCull") + { + g_FrustumCullInHS = !g_FrustumCullInHS; + + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Island" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_FrustumCullInHS", g_FrustumCullInHS ); + } + if (box->getName() == "RenderRefraction") + { + g_RenderCaustics = !g_RenderCaustics; + + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Island" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_RenderCaustics", g_RenderCaustics ); + } + } + + void sliderMoved(Slider* slider) + { + if (slider->getName() == "tessellationLOD") + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Island" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_DynamicTessFactor", slider->getValue() ); + } + if (slider->getName() == "tessellationFactor") + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "Island" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_StaticTessFactor", slider->getValue() ); + } + } protected: - void setupContent() - { - // create our main node to attach our entities to - mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - - mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000); // set our skybox - - setupModels(); - setupLights(); - setupControls(); - - // set our camera - mCamera->setFOVy(Ogre::Degree(50.0)); - mCamera->setFOVy(Ogre::Degree(50.0)); - mCamera->setNearClipDistance(0.01f); - mCamera->lookAt(Ogre::Vector3::ZERO); - mCamera->setPosition(0, 0, 500); - - - // Set our camera to orbit around the origin at a suitable distance - mCameraMan->setStyle(CS_ORBIT); - mCameraMan->setYawPitchDist(Radian(0), Radian(0), 400); - - mTrayMgr->showCursor(); - } - - void unloadResources() - { - - } - - void setupModels() - { - - } - - void setupLights() - { - mSceneMgr->setAmbientLight(ColourValue::Black); - mViewport->setBackgroundColour(ColourValue(0.41f, 0.41f, 0.41f)); - } - - void setupControls() - { - mTrayMgr->showCursor(); - - // make room for the controls - mTrayMgr->showLogo(TL_TOPRIGHT); - mTrayMgr->showFrameStats(TL_TOPRIGHT); - mTrayMgr->toggleAdvancedFrameStats(); - - mTrayMgr->createCheckBox(TL_TOPLEFT, "Wire", "Render Wire Frame")->setChecked(false, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Tessellation", "Use Dynamic Tessellation LOD")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "FrustumCull", "Use Frustum Cull in HS")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "RenderRefraction", "Render Refraction Caustics")->setChecked(true, false); - - mTessellationLOD = mTrayMgr->createThickSlider(TL_TOPLEFT, "tessellationLOD", "Dynamic tessellation LOD", 200, 40, 1, 100, 100); - mTessellationLOD->show(); - - mTessellationFactor = mTrayMgr->createThickSlider(TL_TOPLEFT, "tessellationFactor", "Static tessellation factor", 200, 40, 1, 64, 64); - mTessellationFactor->show(); - - // a friendly reminder - StringVector names; - names.push_back("Help"); - mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); - - g_UseDynamicLOD = true; - g_FrustumCullInHS = true; - g_RenderCaustics = true; - } - - void cleanupContent() - { - // clean up properly to avoid interfering with subsequent samples - } - - SceneNode* mObjectNode; - Slider* mTessellationLOD; - Slider* mTessellationFactor; - bool g_UseDynamicLOD; - bool g_FrustumCullInHS; - bool g_RenderCaustics; + void setupContent() + { + // create our main node to attach our entities to + mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + + mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000); // set our skybox + + setupModels(); + setupLights(); + setupControls(); + + // set our camera + mCamera->setFOVy(Ogre::Degree(50.0)); + mCamera->setFOVy(Ogre::Degree(50.0)); + mCamera->setNearClipDistance(0.01f); + mCamera->lookAt(Ogre::Vector3::ZERO); + mCamera->setPosition(0, 0, 500); + + + // Set our camera to orbit around the origin at a suitable distance + mCameraMan->setStyle(CS_ORBIT); + mCameraMan->setYawPitchDist(Radian(0), Radian(0), 400); + + mTrayMgr->showCursor(); + } + + void unloadResources() + { + + } + + void setupModels() + { + + } + + void setupLights() + { + mSceneMgr->setAmbientLight(ColourValue::Black); + mViewport->setBackgroundColour(ColourValue(0.41f, 0.41f, 0.41f)); + } + + void setupControls() + { + mTrayMgr->showCursor(); + + // make room for the controls + mTrayMgr->showLogo(TL_TOPRIGHT); + mTrayMgr->showFrameStats(TL_TOPRIGHT); + mTrayMgr->toggleAdvancedFrameStats(); + + mTrayMgr->createCheckBox(TL_TOPLEFT, "Wire", "Render Wire Frame")->setChecked(false, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Tessellation", "Use Dynamic Tessellation LOD")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "FrustumCull", "Use Frustum Cull in HS")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "RenderRefraction", "Render Refraction Caustics")->setChecked(true, false); + + mTessellationLOD = mTrayMgr->createThickSlider(TL_TOPLEFT, "tessellationLOD", "Dynamic tessellation LOD", 200, 40, 1, 100, 100); + mTessellationLOD->show(); + + mTessellationFactor = mTrayMgr->createThickSlider(TL_TOPLEFT, "tessellationFactor", "Static tessellation factor", 200, 40, 1, 64, 64); + mTessellationFactor->show(); + + // a friendly reminder + StringVector names; + names.push_back("Help"); + mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); + + g_UseDynamicLOD = true; + g_FrustumCullInHS = true; + g_RenderCaustics = true; + } + + void cleanupContent() + { + // clean up properly to avoid interfering with subsequent samples + } + + SceneNode* mObjectNode; + Slider* mTessellationLOD; + Slider* mTessellationFactor; + bool g_UseDynamicLOD; + bool g_FrustumCullInHS; + bool g_RenderCaustics; }; #endif \ No newline at end of file diff --git a/Samples/Island/src/Island.cpp b/Samples/Island/src/Island.cpp index e6c9d2b9e82..e3dee66e949 100644 --- a/Samples/Island/src/Island.cpp +++ b/Samples/Island/src/Island.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Island; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Island; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Isosurf/include/ProceduralTools.h b/Samples/Isosurf/include/ProceduralTools.h index 296559dd645..2835b621315 100644 --- a/Samples/Isosurf/include/ProceduralTools.h +++ b/Samples/Isosurf/include/ProceduralTools.h @@ -8,7 +8,7 @@ class ProceduralTools { public: - static Ogre::MeshPtr generateTetrahedra(); + static Ogre::MeshPtr generateTetrahedra(); }; #endif diff --git a/Samples/Isosurf/src/Isosurf.cpp b/Samples/Isosurf/src/Isosurf.cpp index 6474e2aba8e..4991473860b 100644 --- a/Samples/Isosurf/src/Isosurf.cpp +++ b/Samples/Isosurf/src/Isosurf.cpp @@ -47,12 +47,12 @@ class _OgreSampleClassExport Sample_Isosurf : public SdkSample } StringVector getRequiredPlugins() - { - StringVector names; + { + StringVector names; if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsl150")) names.push_back("Cg Program Manager"); - return names; - } + return names; + } void testCapabilities(const RenderSystemCapabilities* caps) { diff --git a/Samples/Lighting/include/Lighting.h b/Samples/Lighting/include/Lighting.h index 3f692667bba..063718f475f 100644 --- a/Samples/Lighting/include/Lighting.h +++ b/Samples/Lighting/include/Lighting.h @@ -16,346 +16,346 @@ class _OgreSampleClassExport Sample_Lighting : public SdkSample, public RenderOb { public: - Sample_Lighting() : - mGreenLightAnimState(NULL), - mYellowLightAnimState(NULL), - mLight1BBFlare(NULL), - mLight1BBQueryArea(NULL), - mLight1BBQueryVisible(NULL), - mLight2BBFlare(NULL), - mLight2BBQueryArea(NULL), - mLight2BBQueryVisible(NULL), - mLight1QueryArea(NULL), - mLight1QueryVisible(NULL), - mLight2QueryArea(NULL), - mLight2QueryVisible(NULL), + Sample_Lighting() : + mGreenLightAnimState(NULL), + mYellowLightAnimState(NULL), + mLight1BBFlare(NULL), + mLight1BBQueryArea(NULL), + mLight1BBQueryVisible(NULL), + mLight2BBFlare(NULL), + mLight2BBQueryArea(NULL), + mLight2BBQueryVisible(NULL), + mLight1QueryArea(NULL), + mLight1QueryVisible(NULL), + mLight2QueryArea(NULL), + mLight2QueryVisible(NULL), mActiveQuery(NULL), - mUseOcclusionQuery(false), - mDoOcclusionQuery(false) - - { - mInfo["Title"] = "Lighting"; - mInfo["Description"] = "Shows OGRE's lighting support. Also demonstrates " - "usage of occlusion queries and automatic time-relative behaviour " - "using billboards and controllers."; - mInfo["Thumbnail"] = "thumb_lighting.png"; - mInfo["Category"] = "Lighting"; - } + mUseOcclusionQuery(false), + mDoOcclusionQuery(false) + + { + mInfo["Title"] = "Lighting"; + mInfo["Description"] = "Shows OGRE's lighting support. Also demonstrates " + "usage of occlusion queries and automatic time-relative behaviour " + "using billboards and controllers."; + mInfo["Thumbnail"] = "thumb_lighting.png"; + mInfo["Category"] = "Lighting"; + } bool frameRenderingQueued(const FrameEvent& evt) { - // Move the lights along their paths - mGreenLightAnimState->addTime(evt.timeSinceLastFrame); - mYellowLightAnimState->addTime(evt.timeSinceLastFrame); - - // Modulate the light flare according to performed occlusion queries - if (mUseOcclusionQuery) - { - // Stop occlusion queries until we get their information - // (may not happen on the same frame they are requested in) - mDoOcclusionQuery = false; - - // Check if all query information available - if ((mLight1QueryArea->isStillOutstanding() == false) && - (mLight1QueryVisible->isStillOutstanding() == false) && - (mLight2QueryArea->isStillOutstanding() == false) && - (mLight2QueryVisible->isStillOutstanding() == false)) - { - // Modulate the lights according to the query data - unsigned int lightAreaCount; - unsigned int lightVisibleCount; - float ratio; - - mLight1QueryArea->pullOcclusionQuery(&lightAreaCount); - mLight1QueryVisible->pullOcclusionQuery(&lightVisibleCount); - ratio = float(lightVisibleCount) / float(lightAreaCount); - mLight1BBFlare->setColour(mTrail->getInitialColour(0) * ratio); - - mLight2QueryArea->pullOcclusionQuery(&lightAreaCount); - mLight2QueryVisible->pullOcclusionQuery(&lightVisibleCount); - ratio = float(lightVisibleCount) / float(lightAreaCount); - mLight2BBFlare->setColour(mTrail->getInitialColour(1) * ratio); - - // Request new query data - mDoOcclusionQuery = true; - } - } - - - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + // Move the lights along their paths + mGreenLightAnimState->addTime(evt.timeSinceLastFrame); + mYellowLightAnimState->addTime(evt.timeSinceLastFrame); + + // Modulate the light flare according to performed occlusion queries + if (mUseOcclusionQuery) + { + // Stop occlusion queries until we get their information + // (may not happen on the same frame they are requested in) + mDoOcclusionQuery = false; + + // Check if all query information available + if ((mLight1QueryArea->isStillOutstanding() == false) && + (mLight1QueryVisible->isStillOutstanding() == false) && + (mLight2QueryArea->isStillOutstanding() == false) && + (mLight2QueryVisible->isStillOutstanding() == false)) + { + // Modulate the lights according to the query data + unsigned int lightAreaCount; + unsigned int lightVisibleCount; + float ratio; + + mLight1QueryArea->pullOcclusionQuery(&lightAreaCount); + mLight1QueryVisible->pullOcclusionQuery(&lightVisibleCount); + ratio = float(lightVisibleCount) / float(lightAreaCount); + mLight1BBFlare->setColour(mTrail->getInitialColour(0) * ratio); + + mLight2QueryArea->pullOcclusionQuery(&lightAreaCount); + mLight2QueryVisible->pullOcclusionQuery(&lightVisibleCount); + ratio = float(lightVisibleCount) / float(lightAreaCount); + mLight2BBFlare->setColour(mTrail->getInitialColour(1) * ratio); + + // Request new query data + mDoOcclusionQuery = true; + } + } + + + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! } protected: - void setupContent() - { - // Set our camera to orbit around the origin at a suitable distance - mCameraMan->setStyle(CS_ORBIT); - mCameraMan->setYawPitchDist(Radian(0), Radian(0), 400); - - mTrayMgr->showCursor(); - - // Create an ogre head and place it at the origin - Entity* head = mSceneMgr->createEntity("Head", "ogrehead.mesh"); - head->setRenderQueueGroup(cPriorityMain); - mSceneMgr->getRootSceneNode()->attachObject(head); - - setupLights(); - } - - void setupLights() - { - - mSceneMgr->setAmbientLight(ColourValue(0.1, 0.1, 0.1)); // Dim ambient lighting - - // Create a ribbon trail that our lights will leave behind - NameValuePairList params; - params["numberOfChains"] = "2"; - params["maxElements"] = "80"; - mTrail = (RibbonTrail*)mSceneMgr->createMovableObject("RibbonTrail", ¶ms); - mSceneMgr->getRootSceneNode()->attachObject(mTrail); - mTrail->setMaterialName("Examples/LightRibbonTrail"); - mTrail->setTrailLength(400); - mTrail->setRenderQueueGroup(cPriorityLights); - - // Create the occlusion queries to be used in this sample - try { - RenderSystem* renderSystem = Ogre::Root::getSingleton().getRenderSystem(); - mLight1QueryArea = renderSystem->createHardwareOcclusionQuery(); - mLight1QueryVisible = renderSystem->createHardwareOcclusionQuery(); - mLight2QueryArea = renderSystem->createHardwareOcclusionQuery(); - mLight2QueryVisible = renderSystem->createHardwareOcclusionQuery(); - - mUseOcclusionQuery = (mLight1QueryArea != NULL) && - (mLight1QueryVisible != NULL) && - (mLight2QueryArea != NULL) && - (mLight2QueryVisible != NULL); - } - catch (Ogre::Exception e) - { - mUseOcclusionQuery = false; - } - - if (mUseOcclusionQuery == false) - { - LogManager::getSingleton().logMessage("Sample_Lighting - Error: failed to create hardware occlusion query", LML_CRITICAL); - } - - // Create the materials to be used by the objects used fo the occlusion query - MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting"); - MaterialPtr matQueryArea = matBase->clone("QueryArea"); - matQueryArea->setDepthWriteEnabled(false); - matQueryArea->setColourWriteEnabled(false); - matQueryArea->setDepthCheckEnabled(false); // Not occluded by objects - MaterialPtr matQueryVisible = matBase->clone("QueryVisible"); - matQueryVisible->setDepthWriteEnabled(false); - matQueryVisible->setColourWriteEnabled(false); - matQueryVisible->setDepthCheckEnabled(true); // Occluded by objects - - SceneNode* node; - Animation* anim; - NodeAnimationTrack* track; - Light* light; - BillboardSet* bbs; - - // Create a light node - node = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(50, 30, 0)); - - // Create a 14 second animation with spline interpolation - anim = mSceneMgr->createAnimation("Path1", 14); - anim->setInterpolationMode(Animation::IM_SPLINE); - - track = anim->createNodeTrack(1, node); // Create a node track for our animation - - // Enter keyframes for our track to define a path for the light to follow - track->createNodeKeyFrame(0)->setTranslate(Vector3(50, 30, 0)); - track->createNodeKeyFrame(2)->setTranslate(Vector3(100, -30, 0)); - track->createNodeKeyFrame(4)->setTranslate(Vector3(120, -80, 150)); - track->createNodeKeyFrame(6)->setTranslate(Vector3(30, -80, 50)); - track->createNodeKeyFrame(8)->setTranslate(Vector3(-50, 30, -50)); - track->createNodeKeyFrame(10)->setTranslate(Vector3(-150, -20, -100)); - track->createNodeKeyFrame(12)->setTranslate(Vector3(-50, -30, 0)); - track->createNodeKeyFrame(14)->setTranslate(Vector3(50, 30, 0)); - - // Create an animation state from the animation and enable it - mYellowLightAnimState = mSceneMgr->createAnimationState("Path1"); - mYellowLightAnimState->setEnabled(true); - - // Set initial settings for the ribbon mTrail and add the light node - mTrail->setInitialColour(0, 1.0, 0.8, 0); - mTrail->setColourChange(0, 0.5, 0.5, 0.5, 0.5); - mTrail->setInitialWidth(0, 5); - mTrail->addNode(node); - - - // Attach a light with the same colour to the light node - light = mSceneMgr->createLight(); - light->setDiffuseColour(mTrail->getInitialColour(0)); - node->attachObject(light); - - // Attach a flare with the same colour to the light node - bbs = mSceneMgr->createBillboardSet(1); - mLight1BBFlare = bbs->createBillboard(Vector3::ZERO, mTrail->getInitialColour(0)); - bbs->setMaterialName("Examples/Flare"); - bbs->setRenderQueueGroup(cPriorityLights); - node->attachObject(bbs); - - if (mUseOcclusionQuery) - { - // Attach a billboard which will be used to get a relative area occupied by the light - mLight1BBQueryArea = mSceneMgr->createBillboardSet(1); - mLight1BBQueryArea->setDefaultDimensions(10,10); - mLight1BBQueryArea->createBillboard(Vector3::ZERO); - mLight1BBQueryArea->setMaterialName("QueryArea"); - mLight1BBQueryArea->setRenderQueueGroup(cPriorityQuery); - node->attachObject(mLight1BBQueryArea); - - // Attach a billboard which will be used to get the visible area occupied by the light - mLight1BBQueryVisible = mSceneMgr->createBillboardSet(1); - mLight1BBQueryVisible->setDefaultDimensions(10,10); - mLight1BBQueryVisible->createBillboard(Vector3::ZERO); - mLight1BBQueryVisible->setMaterialName("QueryVisible"); - mLight1BBQueryVisible->setRenderQueueGroup(cPriorityQuery); - node->attachObject(mLight1BBQueryVisible); - } - - // Create a second light node - node = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-50, 100, 0)); - - // Create a 10 second animation with spline interpolation - anim = mSceneMgr->createAnimation("Path2", 10); - anim->setInterpolationMode(Animation::IM_SPLINE); - - track = anim->createNodeTrack(1, node); // Create a node track for our animation - - // Enter keyframes for our track to define a path for the light to follow - track->createNodeKeyFrame(0)->setTranslate(Vector3(-50, 100, 0)); - track->createNodeKeyFrame(2)->setTranslate(Vector3(-100, 150, -30)); - track->createNodeKeyFrame(4)->setTranslate(Vector3(-200, 0, 40)); - track->createNodeKeyFrame(6)->setTranslate(Vector3(0, -150, 70)); - track->createNodeKeyFrame(8)->setTranslate(Vector3(50, 0, 30)); - track->createNodeKeyFrame(10)->setTranslate(Vector3(-50, 100, 0)); - - // Create an animation state from the animation and enable it - mGreenLightAnimState = mSceneMgr->createAnimationState("Path2"); - mGreenLightAnimState->setEnabled(true); - - // Set initial settings for the ribbon mTrail and add the light node - mTrail->setInitialColour(1, 0.0, 1.0, 0.4); - mTrail->setColourChange(1, 0.5, 0.5, 0.5, 0.5); - mTrail->setInitialWidth(1, 5); - mTrail->addNode(node); - - // Attach a light with the same colour to the light node - light = mSceneMgr->createLight(); - light->setDiffuseColour(mTrail->getInitialColour(1)); - node->attachObject(light); - - // Attach a flare with the same colour to the light node - bbs = mSceneMgr->createBillboardSet(1); - mLight2BBFlare = bbs->createBillboard(Vector3::ZERO, mTrail->getInitialColour(1)); - bbs->setMaterialName("Examples/Flare"); - bbs->setRenderQueueGroup(cPriorityLights); - node->attachObject(bbs); - - if (mUseOcclusionQuery) - { - // Attach a billboard which will be used to get a relative area occupied by the light - mLight2BBQueryArea = mSceneMgr->createBillboardSet(1); - mLight2BBQueryArea->setDefaultDimensions(10,10); - mLight2BBQueryArea->createBillboard(Vector3::ZERO); - mLight2BBQueryArea->setMaterialName("QueryArea"); - mLight2BBQueryArea->setRenderQueueGroup(cPriorityQuery); - node->attachObject(mLight2BBQueryArea); - - // Attach a billboard which will be used to get the visible area occupied by the light - mLight2BBQueryVisible = mSceneMgr->createBillboardSet(1); - mLight2BBQueryVisible->setDefaultDimensions(10,10); - mLight2BBQueryVisible->createBillboard(Vector3::ZERO); - mLight2BBQueryVisible->setMaterialName("QueryVisible"); - mLight2BBQueryVisible->setRenderQueueGroup(cPriorityQuery); - node->attachObject(mLight2BBQueryVisible); - } - - // Setup the listener for the occlusion query - if (mUseOcclusionQuery) - { - mSceneMgr->addRenderObjectListener(this); - mDoOcclusionQuery = true; - } - } - - // Event raised when render single object started. - virtual void notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, - const LightList* pLightList, bool suppressRenderStateChanges) - { - // - // The following code activates and deactivates the occlusion queries - // so that the queries only include the rendering of their intended targets - // - - // Close the last occlusion query - // Each occlusion query should only last a single rendering - if (mActiveQuery != NULL) - { - mActiveQuery->endOcclusionQuery(); - mActiveQuery = NULL; - } - - // Open a new occlusion query - if (mDoOcclusionQuery == true) - { - // Check if a the object being rendered needs - // to be occlusion queried, and by which query instance. - if (rend == mLight1BBQueryArea) - mActiveQuery = mLight1QueryArea; - else if (rend == mLight1BBQueryVisible) - mActiveQuery = mLight1QueryVisible; - else if (rend == mLight2BBQueryArea) - mActiveQuery = mLight2QueryArea; - else if (rend == mLight2BBQueryVisible) - mActiveQuery = mLight2QueryVisible; - - if (mActiveQuery != NULL) - { - mActiveQuery->beginOcclusionQuery(); - } - } - } + void setupContent() + { + // Set our camera to orbit around the origin at a suitable distance + mCameraMan->setStyle(CS_ORBIT); + mCameraMan->setYawPitchDist(Radian(0), Radian(0), 400); + + mTrayMgr->showCursor(); + + // Create an ogre head and place it at the origin + Entity* head = mSceneMgr->createEntity("Head", "ogrehead.mesh"); + head->setRenderQueueGroup(cPriorityMain); + mSceneMgr->getRootSceneNode()->attachObject(head); + + setupLights(); + } + + void setupLights() + { + + mSceneMgr->setAmbientLight(ColourValue(0.1, 0.1, 0.1)); // Dim ambient lighting + + // Create a ribbon trail that our lights will leave behind + NameValuePairList params; + params["numberOfChains"] = "2"; + params["maxElements"] = "80"; + mTrail = (RibbonTrail*)mSceneMgr->createMovableObject("RibbonTrail", ¶ms); + mSceneMgr->getRootSceneNode()->attachObject(mTrail); + mTrail->setMaterialName("Examples/LightRibbonTrail"); + mTrail->setTrailLength(400); + mTrail->setRenderQueueGroup(cPriorityLights); + + // Create the occlusion queries to be used in this sample + try { + RenderSystem* renderSystem = Ogre::Root::getSingleton().getRenderSystem(); + mLight1QueryArea = renderSystem->createHardwareOcclusionQuery(); + mLight1QueryVisible = renderSystem->createHardwareOcclusionQuery(); + mLight2QueryArea = renderSystem->createHardwareOcclusionQuery(); + mLight2QueryVisible = renderSystem->createHardwareOcclusionQuery(); + + mUseOcclusionQuery = (mLight1QueryArea != NULL) && + (mLight1QueryVisible != NULL) && + (mLight2QueryArea != NULL) && + (mLight2QueryVisible != NULL); + } + catch (Ogre::Exception e) + { + mUseOcclusionQuery = false; + } + + if (mUseOcclusionQuery == false) + { + LogManager::getSingleton().logMessage("Sample_Lighting - Error: failed to create hardware occlusion query", LML_CRITICAL); + } + + // Create the materials to be used by the objects used fo the occlusion query + MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting"); + MaterialPtr matQueryArea = matBase->clone("QueryArea"); + matQueryArea->setDepthWriteEnabled(false); + matQueryArea->setColourWriteEnabled(false); + matQueryArea->setDepthCheckEnabled(false); // Not occluded by objects + MaterialPtr matQueryVisible = matBase->clone("QueryVisible"); + matQueryVisible->setDepthWriteEnabled(false); + matQueryVisible->setColourWriteEnabled(false); + matQueryVisible->setDepthCheckEnabled(true); // Occluded by objects + + SceneNode* node; + Animation* anim; + NodeAnimationTrack* track; + Light* light; + BillboardSet* bbs; + + // Create a light node + node = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(50, 30, 0)); + + // Create a 14 second animation with spline interpolation + anim = mSceneMgr->createAnimation("Path1", 14); + anim->setInterpolationMode(Animation::IM_SPLINE); + + track = anim->createNodeTrack(1, node); // Create a node track for our animation + + // Enter keyframes for our track to define a path for the light to follow + track->createNodeKeyFrame(0)->setTranslate(Vector3(50, 30, 0)); + track->createNodeKeyFrame(2)->setTranslate(Vector3(100, -30, 0)); + track->createNodeKeyFrame(4)->setTranslate(Vector3(120, -80, 150)); + track->createNodeKeyFrame(6)->setTranslate(Vector3(30, -80, 50)); + track->createNodeKeyFrame(8)->setTranslate(Vector3(-50, 30, -50)); + track->createNodeKeyFrame(10)->setTranslate(Vector3(-150, -20, -100)); + track->createNodeKeyFrame(12)->setTranslate(Vector3(-50, -30, 0)); + track->createNodeKeyFrame(14)->setTranslate(Vector3(50, 30, 0)); + + // Create an animation state from the animation and enable it + mYellowLightAnimState = mSceneMgr->createAnimationState("Path1"); + mYellowLightAnimState->setEnabled(true); + + // Set initial settings for the ribbon mTrail and add the light node + mTrail->setInitialColour(0, 1.0, 0.8, 0); + mTrail->setColourChange(0, 0.5, 0.5, 0.5, 0.5); + mTrail->setInitialWidth(0, 5); + mTrail->addNode(node); + + + // Attach a light with the same colour to the light node + light = mSceneMgr->createLight(); + light->setDiffuseColour(mTrail->getInitialColour(0)); + node->attachObject(light); + + // Attach a flare with the same colour to the light node + bbs = mSceneMgr->createBillboardSet(1); + mLight1BBFlare = bbs->createBillboard(Vector3::ZERO, mTrail->getInitialColour(0)); + bbs->setMaterialName("Examples/Flare"); + bbs->setRenderQueueGroup(cPriorityLights); + node->attachObject(bbs); + + if (mUseOcclusionQuery) + { + // Attach a billboard which will be used to get a relative area occupied by the light + mLight1BBQueryArea = mSceneMgr->createBillboardSet(1); + mLight1BBQueryArea->setDefaultDimensions(10,10); + mLight1BBQueryArea->createBillboard(Vector3::ZERO); + mLight1BBQueryArea->setMaterialName("QueryArea"); + mLight1BBQueryArea->setRenderQueueGroup(cPriorityQuery); + node->attachObject(mLight1BBQueryArea); + + // Attach a billboard which will be used to get the visible area occupied by the light + mLight1BBQueryVisible = mSceneMgr->createBillboardSet(1); + mLight1BBQueryVisible->setDefaultDimensions(10,10); + mLight1BBQueryVisible->createBillboard(Vector3::ZERO); + mLight1BBQueryVisible->setMaterialName("QueryVisible"); + mLight1BBQueryVisible->setRenderQueueGroup(cPriorityQuery); + node->attachObject(mLight1BBQueryVisible); + } + + // Create a second light node + node = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-50, 100, 0)); + + // Create a 10 second animation with spline interpolation + anim = mSceneMgr->createAnimation("Path2", 10); + anim->setInterpolationMode(Animation::IM_SPLINE); + + track = anim->createNodeTrack(1, node); // Create a node track for our animation + + // Enter keyframes for our track to define a path for the light to follow + track->createNodeKeyFrame(0)->setTranslate(Vector3(-50, 100, 0)); + track->createNodeKeyFrame(2)->setTranslate(Vector3(-100, 150, -30)); + track->createNodeKeyFrame(4)->setTranslate(Vector3(-200, 0, 40)); + track->createNodeKeyFrame(6)->setTranslate(Vector3(0, -150, 70)); + track->createNodeKeyFrame(8)->setTranslate(Vector3(50, 0, 30)); + track->createNodeKeyFrame(10)->setTranslate(Vector3(-50, 100, 0)); + + // Create an animation state from the animation and enable it + mGreenLightAnimState = mSceneMgr->createAnimationState("Path2"); + mGreenLightAnimState->setEnabled(true); + + // Set initial settings for the ribbon mTrail and add the light node + mTrail->setInitialColour(1, 0.0, 1.0, 0.4); + mTrail->setColourChange(1, 0.5, 0.5, 0.5, 0.5); + mTrail->setInitialWidth(1, 5); + mTrail->addNode(node); + + // Attach a light with the same colour to the light node + light = mSceneMgr->createLight(); + light->setDiffuseColour(mTrail->getInitialColour(1)); + node->attachObject(light); + + // Attach a flare with the same colour to the light node + bbs = mSceneMgr->createBillboardSet(1); + mLight2BBFlare = bbs->createBillboard(Vector3::ZERO, mTrail->getInitialColour(1)); + bbs->setMaterialName("Examples/Flare"); + bbs->setRenderQueueGroup(cPriorityLights); + node->attachObject(bbs); + + if (mUseOcclusionQuery) + { + // Attach a billboard which will be used to get a relative area occupied by the light + mLight2BBQueryArea = mSceneMgr->createBillboardSet(1); + mLight2BBQueryArea->setDefaultDimensions(10,10); + mLight2BBQueryArea->createBillboard(Vector3::ZERO); + mLight2BBQueryArea->setMaterialName("QueryArea"); + mLight2BBQueryArea->setRenderQueueGroup(cPriorityQuery); + node->attachObject(mLight2BBQueryArea); + + // Attach a billboard which will be used to get the visible area occupied by the light + mLight2BBQueryVisible = mSceneMgr->createBillboardSet(1); + mLight2BBQueryVisible->setDefaultDimensions(10,10); + mLight2BBQueryVisible->createBillboard(Vector3::ZERO); + mLight2BBQueryVisible->setMaterialName("QueryVisible"); + mLight2BBQueryVisible->setRenderQueueGroup(cPriorityQuery); + node->attachObject(mLight2BBQueryVisible); + } + + // Setup the listener for the occlusion query + if (mUseOcclusionQuery) + { + mSceneMgr->addRenderObjectListener(this); + mDoOcclusionQuery = true; + } + } + + // Event raised when render single object started. + virtual void notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, + const LightList* pLightList, bool suppressRenderStateChanges) + { + // + // The following code activates and deactivates the occlusion queries + // so that the queries only include the rendering of their intended targets + // + + // Close the last occlusion query + // Each occlusion query should only last a single rendering + if (mActiveQuery != NULL) + { + mActiveQuery->endOcclusionQuery(); + mActiveQuery = NULL; + } + + // Open a new occlusion query + if (mDoOcclusionQuery == true) + { + // Check if a the object being rendered needs + // to be occlusion queried, and by which query instance. + if (rend == mLight1BBQueryArea) + mActiveQuery = mLight1QueryArea; + else if (rend == mLight1BBQueryVisible) + mActiveQuery = mLight1QueryVisible; + else if (rend == mLight2BBQueryArea) + mActiveQuery = mLight2QueryArea; + else if (rend == mLight2BBQueryVisible) + mActiveQuery = mLight2QueryVisible; + + if (mActiveQuery != NULL) + { + mActiveQuery->beginOcclusionQuery(); + } + } + } void cleanupContent() { RenderSystem* renderSystem = Ogre::Root::getSingleton().getRenderSystem(); - if (mLight1QueryArea != NULL) + if (mLight1QueryArea != NULL) renderSystem->destroyHardwareOcclusionQuery(mLight1QueryArea); - if (mLight1QueryVisible != NULL) + if (mLight1QueryVisible != NULL) renderSystem->destroyHardwareOcclusionQuery(mLight1QueryVisible); - if (mLight2QueryArea != NULL) + if (mLight2QueryArea != NULL) renderSystem->destroyHardwareOcclusionQuery(mLight2QueryArea); - if (mLight2QueryVisible != NULL) + if (mLight2QueryVisible != NULL) renderSystem->destroyHardwareOcclusionQuery(mLight2QueryVisible); } - AnimationState* mGreenLightAnimState; - AnimationState* mYellowLightAnimState; + AnimationState* mGreenLightAnimState; + AnimationState* mYellowLightAnimState; - RibbonTrail* mTrail; + RibbonTrail* mTrail; - Billboard* mLight1BBFlare; - BillboardSet* mLight1BBQueryArea; - BillboardSet* mLight1BBQueryVisible; - Billboard* mLight2BBFlare; - BillboardSet* mLight2BBQueryArea; - BillboardSet* mLight2BBQueryVisible; + Billboard* mLight1BBFlare; + BillboardSet* mLight1BBQueryArea; + BillboardSet* mLight1BBQueryVisible; + Billboard* mLight2BBFlare; + BillboardSet* mLight2BBQueryArea; + BillboardSet* mLight2BBQueryVisible; - HardwareOcclusionQuery* mLight1QueryArea; - HardwareOcclusionQuery* mLight1QueryVisible; - HardwareOcclusionQuery* mLight2QueryArea; - HardwareOcclusionQuery* mLight2QueryVisible; - HardwareOcclusionQuery* mActiveQuery; + HardwareOcclusionQuery* mLight1QueryArea; + HardwareOcclusionQuery* mLight1QueryVisible; + HardwareOcclusionQuery* mLight2QueryArea; + HardwareOcclusionQuery* mLight2QueryVisible; + HardwareOcclusionQuery* mActiveQuery; - bool mUseOcclusionQuery; - bool mDoOcclusionQuery; + bool mUseOcclusionQuery; + bool mDoOcclusionQuery; }; #endif diff --git a/Samples/Lighting/src/Lighting.cpp b/Samples/Lighting/src/Lighting.cpp index aae2f04c7fa..f274e40a66a 100644 --- a/Samples/Lighting/src/Lighting.cpp +++ b/Samples/Lighting/src/Lighting.cpp @@ -11,17 +11,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Lighting; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Lighting; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/MeshLod/include/MeshLod.h b/Samples/MeshLod/include/MeshLod.h index 416bb5e677f..63765d7aa30 100644 --- a/Samples/MeshLod/include/MeshLod.h +++ b/Samples/MeshLod/include/MeshLod.h @@ -12,74 +12,74 @@ #define ENABLE_THREADING 1 class _OgreSampleClassExport Sample_MeshLod : - public OgreBites::SdkSample, - public Ogre::LodWorkQueueInjectorListener + public OgreBites::SdkSample, + public Ogre::LodWorkQueueInjectorListener { public: - Sample_MeshLod(); + Sample_MeshLod(); protected: // Events: - void setupContent(); - void cleanupContent(); - void setupControls(int uimode = 0); - void cleanupControls(); - bool frameStarted(const Ogre::FrameEvent& evt); + void setupContent(); + void cleanupContent(); + void setupControls(int uimode = 0); + void cleanupControls(); + bool frameStarted(const Ogre::FrameEvent& evt); // GUI input events: - void buttonHit(OgreBites::Button* button); - void sliderMoved(OgreBites::Slider* slider); - void itemSelected(OgreBites::SelectMenu* menu); - void checkBoxToggled(OgreBites::CheckBox * box); + void buttonHit(OgreBites::Button* button); + void sliderMoved(OgreBites::Slider* slider); + void itemSelected(OgreBites::SelectMenu* menu); + void checkBoxToggled(OgreBites::CheckBox * box); // Queued Lod injector events: - bool shouldInject(Ogre::LodWorkQueueRequest* request); - void injectionCompleted(Ogre::LodWorkQueueRequest* request); + bool shouldInject(Ogre::LodWorkQueueRequest* request); + void injectionCompleted(Ogre::LodWorkQueueRequest* request); // Other functions: - void changeSelectedMesh(const Ogre::String& name); // Changes current mesh to a mesh with given mesh name. - bool loadConfig(); /// Loads the LodConfig with LodConfigSerializer for current mesh. - void saveConfig(); /// Saves the LodConfig with LodConfigSerializer for current mesh. - void loadUserLod(bool useWorkLod = true); /// Loads current Lod config. If useWorkLod is selected only current work Lod level will be shown. - void forceLodLevel(int lodLevelID, bool forceDelayed = true); /// Forces given Lod Level or -1 for disable forcing. + void changeSelectedMesh(const Ogre::String& name); // Changes current mesh to a mesh with given mesh name. + bool loadConfig(); /// Loads the LodConfig with LodConfigSerializer for current mesh. + void saveConfig(); /// Saves the LodConfig with LodConfigSerializer for current mesh. + void loadUserLod(bool useWorkLod = true); /// Loads current Lod config. If useWorkLod is selected only current work Lod level will be shown. + void forceLodLevel(int lodLevelID, bool forceDelayed = true); /// Forces given Lod Level or -1 for disable forcing. - void loadAutomaticLod(); /// Produces acceptable output on any kind of mesh. + void loadAutomaticLod(); /// Produces acceptable output on any kind of mesh. - size_t getUniqueVertexCount(Ogre::MeshPtr mesh); /// Returns the unique vertex count of mesh. - bool getResourceFullPath(Ogre::MeshPtr& mesh, Ogre::String& outPath); /// Sets outPath to full resource file path. Returns true if location is writable. - - void addLodLevel(); /// Adds current work Lod level to the mesh Lod levels. - void loadLodLevel(int id); /// Loads the Lod levels with id to the work Lod level. - void removeLodLevel(); /// Removes currently selected Lod level. + size_t getUniqueVertexCount(Ogre::MeshPtr mesh); /// Returns the unique vertex count of mesh. + bool getResourceFullPath(Ogre::MeshPtr& mesh, Ogre::String& outPath); /// Sets outPath to full resource file path. Returns true if location is writable. + + void addLodLevel(); /// Adds current work Lod level to the mesh Lod levels. + void loadLodLevel(int id); /// Loads the Lod levels with id to the work Lod level. + void removeLodLevel(); /// Removes currently selected Lod level. - void addToProfile(Ogre::Real cost); /// Add the currently reduced last vertex to the profile with given cost. + void addToProfile(Ogre::Real cost); /// Add the currently reduced last vertex to the profile with given cost. - void moveCameraToPixelDistance(Ogre::Real pixels); /// Moves camera to the swapping distance of PixelCountLodStrategy with given pixels. - Ogre::Real getCameraDistance(); /// Returns the distance between camera and mesh in pixels. - void recreateEntity(); + void moveCameraToPixelDistance(Ogre::Real pixels); /// Moves camera to the swapping distance of PixelCountLodStrategy with given pixels. + Ogre::Real getCameraDistance(); /// Returns the distance between camera and mesh in pixels. + void recreateEntity(); // Variables: - int mForcedLodLevel; /// Currently forced Lod level or -1 for disabled. - Ogre::LodLevel mWorkLevel; /// Current Lod Level, which we are seeing. - Ogre::LodConfig mLodConfig; /// Current LodConfig, which we are editing. - Ogre::Entity* mMeshEntity; /// Entity of the mesh. - Ogre::SceneNode* mMeshNode; /// Node of the mesh. + int mForcedLodLevel; /// Currently forced Lod level or -1 for disabled. + Ogre::LodLevel mWorkLevel; /// Current Lod Level, which we are seeing. + Ogre::LodConfig mLodConfig; /// Current LodConfig, which we are editing. + Ogre::Entity* mMeshEntity; /// Entity of the mesh. + Ogre::SceneNode* mMeshNode; /// Node of the mesh. #if SHOW_MESH_HULL - Ogre::Entity* mHullEntity; /// Entity of the mesh hull. - Ogre::SceneNode* mHullNode; /// Node of the mesh hull. + Ogre::Entity* mHullEntity; /// Entity of the mesh hull. + Ogre::SceneNode* mHullNode; /// Node of the mesh hull. #endif // GUI elements: - OgreBites::CheckBox* mUseVertexNormals; - OgreBites::CheckBox* mWireframe; - OgreBites::SelectMenu* mProfileList; - OgreBites::SelectMenu* mLodLevelList; - OgreBites::SelectMenu* mManualMeshes; - OgreBites::Slider* mReductionSlider; - OgreBites::Slider* mOutsideWeightSlider; - OgreBites::Slider* mOutsideWalkAngle; - OgreBites::Label* mDistanceLabel; + OgreBites::CheckBox* mUseVertexNormals; + OgreBites::CheckBox* mWireframe; + OgreBites::SelectMenu* mProfileList; + OgreBites::SelectMenu* mLodLevelList; + OgreBites::SelectMenu* mManualMeshes; + OgreBites::Slider* mReductionSlider; + OgreBites::Slider* mOutsideWeightSlider; + OgreBites::Slider* mOutsideWalkAngle; + OgreBites::Label* mDistanceLabel; }; #endif diff --git a/Samples/MeshLod/src/MeshLod.cpp b/Samples/MeshLod/src/MeshLod.cpp index 01d915f019e..b813dfeccfb 100644 --- a/Samples/MeshLod/src/MeshLod.cpp +++ b/Samples/MeshLod/src/MeshLod.cpp @@ -17,583 +17,583 @@ using namespace OgreBites; Sample_MeshLod::Sample_MeshLod() { - mInfo["Title"] = "Mesh Lod"; - mInfo["Description"] = "Shows how to add Lod levels to a mesh using the ProgressiveMesh class."; - mInfo["Thumbnail"] = "thumb_meshlod.png"; - mInfo["Category"] = "Unsorted"; + mInfo["Title"] = "Mesh Lod"; + mInfo["Description"] = "Shows how to add Lod levels to a mesh using the ProgressiveMesh class."; + mInfo["Thumbnail"] = "thumb_meshlod.png"; + mInfo["Category"] = "Unsorted"; } void Sample_MeshLod::setupContent() { - mCameraMan->setStyle(CS_ORBIT); + mCameraMan->setStyle(CS_ORBIT); - mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); // set ambient light + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); // set ambient light - // make the scene's main light come from above - Light* l = mSceneMgr->createLight(); - l->setType(Light::LT_DIRECTIONAL); - l->setDirection(Vector3::NEGATIVE_UNIT_Y); + // make the scene's main light come from above + Light* l = mSceneMgr->createLight(); + l->setType(Light::LT_DIRECTIONAL); + l->setDirection(Vector3::NEGATIVE_UNIT_Y); - // create a node for the model - mMeshNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mMeshEntity = NULL; + // create a node for the model + mMeshNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mMeshEntity = NULL; #if SHOW_MESH_HULL - mHullNode = mMeshNode->createChildSceneNode(); - mHullNode->scale(1.001,1.001,1.001); - mHullEntity = NULL; + mHullNode = mMeshNode->createChildSceneNode(); + mHullNode->scale(1.001,1.001,1.001); + mHullEntity = NULL; #endif - if(!MeshLodGenerator::getSingletonPtr()) { - new MeshLodGenerator(); - } - MeshLodGenerator::getSingleton()._initWorkQueue(); // needed only for LodWorkQueueInjector::setInjectorListener - LodWorkQueueInjector::getSingleton().setInjectorListener(this); + if(!MeshLodGenerator::getSingletonPtr()) { + new MeshLodGenerator(); + } + MeshLodGenerator::getSingleton()._initWorkQueue(); // needed only for LodWorkQueueInjector::setInjectorListener + LodWorkQueueInjector::getSingleton().setInjectorListener(this); - // setup gui - setupControls(); + // setup gui + setupControls(); - // load mesh - changeSelectedMesh("sinbad.mesh"); + // load mesh + changeSelectedMesh("sinbad.mesh"); } void Sample_MeshLod::cleanupContent() { - Ogre::LodWorkQueueInjector::getSingleton().removeInjectorListener(); - if(mMeshEntity){ - mSceneMgr->destroyEntity(mMeshEntity); - mMeshEntity = 0; - saveConfig(); - } - cleanupControls(); + Ogre::LodWorkQueueInjector::getSingleton().removeInjectorListener(); + if(mMeshEntity){ + mSceneMgr->destroyEntity(mMeshEntity); + mMeshEntity = 0; + saveConfig(); + } + cleanupControls(); } void Sample_MeshLod::setupControls( int uimode /*= 0*/ ) { - cleanupControls(); - - SelectMenu* models = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "cmbModels", "Model:", 150, 8); - models->addItem("sinbad.mesh"); - models->addItem("ogrehead.mesh"); - models->addItem("knot.mesh"); - models->addItem("fish.mesh"); - models->addItem("penguin.mesh"); - models->addItem("ninja.mesh"); - models->addItem("dragon.mesh"); - models->addItem("athene.mesh"); - models->addItem("sibenik.mesh"); - - // Add all meshes from popular: - StringVectorPtr meshes = ResourceGroupManager::getSingleton().findResourceNames("Popular", "*.mesh"); - StringVector::iterator it, itEnd; - it = meshes->begin(); - itEnd = meshes->end(); - for(; it != itEnd; it++){ - models->addItem(*it); - } - - - // Basic options: - mWireframe = mTrayMgr->createCheckBox(TL_TOPLEFT, "chkShowWireframe", "Show wireframe", 200); - mUseVertexNormals = mTrayMgr->createCheckBox(TL_TOPLEFT, "chkUseVertexNormals", "Use vertex normals", 200); - mOutsideWeightSlider = mTrayMgr->createThickSlider(TL_TOPLEFT, "sldOutsideWeight", "Weighten outside", 200, 50, 0, 100, 101); - mOutsideWalkAngle = mTrayMgr->createThickSlider(TL_TOPLEFT, "sldOutsideWalkAngle", "Outside angle", 200, 50, -1, 1, 201); - mManualMeshes = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "cmbManualMesh", "Manual LOD:", 100, 8); - mManualMeshes->copyItemsFrom(models); - mManualMeshes->insertItem(0,""); - mReductionSlider = mTrayMgr->createThickSlider(TL_TOPLEFT, "sldReductionValue", "Reduced vertices", 200, 50, 0, 100, 101); - mTrayMgr->createButton(TL_TOPLEFT, "btnReduceMore","Reduce More"); - mTrayMgr->createButton(TL_TOPLEFT, "btnReduceLess","Reduce Less"); - - // Level options: - mDistanceLabel = mTrayMgr->createLabel(TL_TOPRIGHT, "lblDistance", "Distance: ", 250); - mLodLevelList = mTrayMgr->createLongSelectMenu(TL_TOPRIGHT, "cmbLodLevels", "Lod level:", 150, 4); - mTrayMgr->createButton(TL_TOPRIGHT, "btnRemoveSelectedLodLevel","Remove level", 200); - mTrayMgr->createButton(TL_TOPRIGHT, "btnAddLodLevel","Add level", 200); - - // Serializer options: - mTrayMgr->createButton(TL_TOPRIGHT, "btnShowAll", "Show all levels", 200); - mTrayMgr->createButton(TL_TOPRIGHT, "btnSaveMesh", "Save mesh", 200); - mTrayMgr->createButton(TL_TOPRIGHT, "btnShowMesh", "Show Lod from mesh", 200); - mTrayMgr->createButton(TL_TOPRIGHT, "btnAutoconfigure", "Show autoconfigured mesh", 200); - - // Profile options - mProfileList = mTrayMgr->createLongSelectMenu(TL_TOPRIGHT, "cmbProfiledVertices", "Profile:", 180, 4); - mTrayMgr->createButton(TL_TOPRIGHT, "btnRemoveFromProfile","Remove from profile", 200.0); - mTrayMgr->createButton(TL_TOPRIGHT, "btnAddToProfile","Add to profile", 200.0); - - //mTrayMgr->createTextBox(TL_TOPRIGHT, "Help","Help", 200, 200) - // ->setText("The last reduced vertex is the selected vertex. Use the slider to select the vertex, then decide to keep or remove it. You can export the Lod buffers into the .mesh file after configuration."); - - mTrayMgr->showCursor(); + cleanupControls(); + + SelectMenu* models = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "cmbModels", "Model:", 150, 8); + models->addItem("sinbad.mesh"); + models->addItem("ogrehead.mesh"); + models->addItem("knot.mesh"); + models->addItem("fish.mesh"); + models->addItem("penguin.mesh"); + models->addItem("ninja.mesh"); + models->addItem("dragon.mesh"); + models->addItem("athene.mesh"); + models->addItem("sibenik.mesh"); + + // Add all meshes from popular: + StringVectorPtr meshes = ResourceGroupManager::getSingleton().findResourceNames("Popular", "*.mesh"); + StringVector::iterator it, itEnd; + it = meshes->begin(); + itEnd = meshes->end(); + for(; it != itEnd; it++){ + models->addItem(*it); + } + + + // Basic options: + mWireframe = mTrayMgr->createCheckBox(TL_TOPLEFT, "chkShowWireframe", "Show wireframe", 200); + mUseVertexNormals = mTrayMgr->createCheckBox(TL_TOPLEFT, "chkUseVertexNormals", "Use vertex normals", 200); + mOutsideWeightSlider = mTrayMgr->createThickSlider(TL_TOPLEFT, "sldOutsideWeight", "Weighten outside", 200, 50, 0, 100, 101); + mOutsideWalkAngle = mTrayMgr->createThickSlider(TL_TOPLEFT, "sldOutsideWalkAngle", "Outside angle", 200, 50, -1, 1, 201); + mManualMeshes = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "cmbManualMesh", "Manual LOD:", 100, 8); + mManualMeshes->copyItemsFrom(models); + mManualMeshes->insertItem(0,""); + mReductionSlider = mTrayMgr->createThickSlider(TL_TOPLEFT, "sldReductionValue", "Reduced vertices", 200, 50, 0, 100, 101); + mTrayMgr->createButton(TL_TOPLEFT, "btnReduceMore","Reduce More"); + mTrayMgr->createButton(TL_TOPLEFT, "btnReduceLess","Reduce Less"); + + // Level options: + mDistanceLabel = mTrayMgr->createLabel(TL_TOPRIGHT, "lblDistance", "Distance: ", 250); + mLodLevelList = mTrayMgr->createLongSelectMenu(TL_TOPRIGHT, "cmbLodLevels", "Lod level:", 150, 4); + mTrayMgr->createButton(TL_TOPRIGHT, "btnRemoveSelectedLodLevel","Remove level", 200); + mTrayMgr->createButton(TL_TOPRIGHT, "btnAddLodLevel","Add level", 200); + + // Serializer options: + mTrayMgr->createButton(TL_TOPRIGHT, "btnShowAll", "Show all levels", 200); + mTrayMgr->createButton(TL_TOPRIGHT, "btnSaveMesh", "Save mesh", 200); + mTrayMgr->createButton(TL_TOPRIGHT, "btnShowMesh", "Show Lod from mesh", 200); + mTrayMgr->createButton(TL_TOPRIGHT, "btnAutoconfigure", "Show autoconfigured mesh", 200); + + // Profile options + mProfileList = mTrayMgr->createLongSelectMenu(TL_TOPRIGHT, "cmbProfiledVertices", "Profile:", 180, 4); + mTrayMgr->createButton(TL_TOPRIGHT, "btnRemoveFromProfile","Remove from profile", 200.0); + mTrayMgr->createButton(TL_TOPRIGHT, "btnAddToProfile","Add to profile", 200.0); + + //mTrayMgr->createTextBox(TL_TOPRIGHT, "Help","Help", 200, 200) + // ->setText("The last reduced vertex is the selected vertex. Use the slider to select the vertex, then decide to keep or remove it. You can export the Lod buffers into the .mesh file after configuration."); + + mTrayMgr->showCursor(); } void Sample_MeshLod::cleanupControls() { - mTrayMgr->clearTray(TL_TOPLEFT); - mTrayMgr->clearTray(TL_TOPRIGHT); - mTrayMgr->clearTray(TL_TOP); + mTrayMgr->clearTray(TL_TOPLEFT); + mTrayMgr->clearTray(TL_TOPRIGHT); + mTrayMgr->clearTray(TL_TOP); } void Sample_MeshLod::recreateEntity() { - // If you change the lod of a mesh, every entity referencing it should be recreated. - if(mMeshEntity){ - mSceneMgr->destroyEntity(mMeshEntity); - mMeshEntity = 0; // createEntity may throw exception, so it is safer to reset to 0. - } - mMeshEntity = mSceneMgr->createEntity(mLodConfig.mesh->getName(), mLodConfig.mesh); - mMeshNode->attachObject(mMeshEntity); + // If you change the lod of a mesh, every entity referencing it should be recreated. + if(mMeshEntity){ + mSceneMgr->destroyEntity(mMeshEntity); + mMeshEntity = 0; // createEntity may throw exception, so it is safer to reset to 0. + } + mMeshEntity = mSceneMgr->createEntity(mLodConfig.mesh->getName(), mLodConfig.mesh); + mMeshNode->attachObject(mMeshEntity); } void Sample_MeshLod::changeSelectedMesh( const String& name ) { - if(mMeshEntity){ - mSceneMgr->destroyEntity(mMeshEntity); - mMeshEntity = 0; - saveConfig(); - } - mLodConfig.mesh = MeshManager::getSingleton().load(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - if(mLodConfig.mesh->getBounds().isNull() || mLodConfig.mesh->getBoundingSphereRadius() == 0.0){ - mTrayMgr->showOkDialog("Error", "Failed to load mesh!"); - return; - } - mMeshEntity = mSceneMgr->createEntity(name, mLodConfig.mesh); - mMeshNode->attachObject(mMeshEntity); - mCamera->setPosition(Vector3(0, 0, 0)); - mCamera->moveRelative(Vector3(0, 0, mLodConfig.mesh->getBoundingSphereRadius() * 2)); - mCamera->setNearClipDistance(mLodConfig.mesh->getBoundingSphereRadius() / 16); - mCamera->setFarClipDistance(mLodConfig.mesh->getBoundingSphereRadius() * 256); - - size_t vertexCount = getUniqueVertexCount(mLodConfig.mesh); - mReductionSlider->setRange(0,vertexCount,vertexCount+1,false); - mOutsideWeightSlider->setValue(0, false); - mOutsideWalkAngle->setValue(0, false); - mLodLevelList->clearItems(); - mManualMeshes->selectItem(0, false); - mWorkLevel.distance = 1.0; - mWorkLevel.reductionMethod = LodLevel::VRM_CONSTANT; - mWorkLevel.reductionValue = 0.0; - mWorkLevel.manualMeshName = ""; - - loadConfig(); - - if(mLodLevelList->getNumItems() > 0){ - loadLodLevel(mLodLevelList->getSelectionIndex()); - } else { - loadUserLod(); - } + if(mMeshEntity){ + mSceneMgr->destroyEntity(mMeshEntity); + mMeshEntity = 0; + saveConfig(); + } + mLodConfig.mesh = MeshManager::getSingleton().load(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + if(mLodConfig.mesh->getBounds().isNull() || mLodConfig.mesh->getBoundingSphereRadius() == 0.0){ + mTrayMgr->showOkDialog("Error", "Failed to load mesh!"); + return; + } + mMeshEntity = mSceneMgr->createEntity(name, mLodConfig.mesh); + mMeshNode->attachObject(mMeshEntity); + mCamera->setPosition(Vector3(0, 0, 0)); + mCamera->moveRelative(Vector3(0, 0, mLodConfig.mesh->getBoundingSphereRadius() * 2)); + mCamera->setNearClipDistance(mLodConfig.mesh->getBoundingSphereRadius() / 16); + mCamera->setFarClipDistance(mLodConfig.mesh->getBoundingSphereRadius() * 256); + + size_t vertexCount = getUniqueVertexCount(mLodConfig.mesh); + mReductionSlider->setRange(0,vertexCount,vertexCount+1,false); + mOutsideWeightSlider->setValue(0, false); + mOutsideWalkAngle->setValue(0, false); + mLodLevelList->clearItems(); + mManualMeshes->selectItem(0, false); + mWorkLevel.distance = 1.0; + mWorkLevel.reductionMethod = LodLevel::VRM_CONSTANT; + mWorkLevel.reductionValue = 0.0; + mWorkLevel.manualMeshName = ""; + + loadConfig(); + + if(mLodLevelList->getNumItems() > 0){ + loadLodLevel(mLodLevelList->getSelectionIndex()); + } else { + loadUserLod(); + } #if SHOW_MESH_HULL - const String meshHullName("ConvexHull.mesh"); - if(mHullEntity){ - mHullNode->detachObject(mHullEntity); - mSceneMgr->destroyEntity(mHullEntity); - // Removes from the resources list. - mHullEntity = NULL; - Ogre::MeshManager::getSingleton().remove(meshHullName); - } - - LodData data; - LodInputProviderMesh input(mLodConfig.mesh); - input.initData(&data); - LodOutsideMarker outsideMarker(data.mVertexList, data.mMeshBoundingSphereRadius, 0.0); - MeshPtr meshHull = outsideMarker.createConvexHullMesh(meshHullName); - - mHullEntity = mSceneMgr->createEntity(meshHull); - mHullNode->attachObject(mHullEntity); + const String meshHullName("ConvexHull.mesh"); + if(mHullEntity){ + mHullNode->detachObject(mHullEntity); + mSceneMgr->destroyEntity(mHullEntity); + // Removes from the resources list. + mHullEntity = NULL; + Ogre::MeshManager::getSingleton().remove(meshHullName); + } + + LodData data; + LodInputProviderMesh input(mLodConfig.mesh); + input.initData(&data); + LodOutsideMarker outsideMarker(data.mVertexList, data.mMeshBoundingSphereRadius, 0.0); + MeshPtr meshHull = outsideMarker.createConvexHullMesh(meshHullName); + + mHullEntity = mSceneMgr->createEntity(meshHull); + mHullNode->attachObject(mHullEntity); #endif } bool Sample_MeshLod::loadConfig() { - mLodConfig.advanced = LodConfig::Advanced(); - mLodConfig.strategy = PixelCountLodStrategy::getSingletonPtr(); - mLodConfig.levels.clear(); - mLodConfig.advanced.profile.clear(); - - // The mesh should already be set. - assert(mLodConfig.mesh.get()); - - String filename(mLodConfig.mesh->getName()); - filename += ".lodconfig"; - LodConfigSerializer lcs; - lcs.importLodConfig(&mLodConfig, filename); - - mLodLevelList->clearItems(); - for(size_t i = 0; i < mLodConfig.levels.size(); i++){ - mLodLevelList->addItem(StringConverter::toString(mLodConfig.levels[i].distance) + "px"); - } - - mProfileList->clearItems(); - for(size_t i = 0; i < mLodConfig.advanced.profile.size(); i++){ - mProfileList->addItem(StringConverter::toString(mLodConfig.advanced.profile[i].src)); - } - - mUseVertexNormals->setChecked(mLodConfig.advanced.useVertexNormals, false); - mOutsideWeightSlider->setValue(std::sqrt(mLodConfig.advanced.outsideWeight), false); - mOutsideWalkAngle->setValue(mLodConfig.advanced.outsideWalkAngle, false); - return true; + mLodConfig.advanced = LodConfig::Advanced(); + mLodConfig.strategy = PixelCountLodStrategy::getSingletonPtr(); + mLodConfig.levels.clear(); + mLodConfig.advanced.profile.clear(); + + // The mesh should already be set. + assert(mLodConfig.mesh.get()); + + String filename(mLodConfig.mesh->getName()); + filename += ".lodconfig"; + LodConfigSerializer lcs; + lcs.importLodConfig(&mLodConfig, filename); + + mLodLevelList->clearItems(); + for(size_t i = 0; i < mLodConfig.levels.size(); i++){ + mLodLevelList->addItem(StringConverter::toString(mLodConfig.levels[i].distance) + "px"); + } + + mProfileList->clearItems(); + for(size_t i = 0; i < mLodConfig.advanced.profile.size(); i++){ + mProfileList->addItem(StringConverter::toString(mLodConfig.advanced.profile[i].src)); + } + + mUseVertexNormals->setChecked(mLodConfig.advanced.useVertexNormals, false); + mOutsideWeightSlider->setValue(std::sqrt(mLodConfig.advanced.outsideWeight), false); + mOutsideWalkAngle->setValue(mLodConfig.advanced.outsideWalkAngle, false); + return true; } void Sample_MeshLod::saveConfig() { - String filename(mLodConfig.mesh->getName()); - filename += ".lodconfig"; - LodConfigSerializer lcs; - lcs.exportLodConfig(mLodConfig, filename); + String filename(mLodConfig.mesh->getName()); + filename += ".lodconfig"; + LodConfigSerializer lcs; + lcs.exportLodConfig(mLodConfig, filename); } void Sample_MeshLod::loadAutomaticLod() { - // Remove outdated Lod requests to reduce delay. - LodWorkQueueWorker::getSingleton().clearPendingLodRequests(); - - MeshLodGenerator& gen = MeshLodGenerator::getSingleton(); - //gen.generateAutoconfiguredLodLevels(mLodConfig.mesh); - LodConfig lodConfig; - gen.getAutoconfig(mLodConfig.mesh, lodConfig); - lodConfig.advanced.useBackgroundQueue = ENABLE_THREADING; - lodConfig.advanced.profile = mLodConfig.advanced.profile; - lodConfig.advanced.useVertexNormals = mLodConfig.advanced.useVertexNormals; - gen.generateLodLevels(lodConfig); - recreateEntity(); + // Remove outdated Lod requests to reduce delay. + LodWorkQueueWorker::getSingleton().clearPendingLodRequests(); + + MeshLodGenerator& gen = MeshLodGenerator::getSingleton(); + //gen.generateAutoconfiguredLodLevels(mLodConfig.mesh); + LodConfig lodConfig; + gen.getAutoconfig(mLodConfig.mesh, lodConfig); + lodConfig.advanced.useBackgroundQueue = ENABLE_THREADING; + lodConfig.advanced.profile = mLodConfig.advanced.profile; + lodConfig.advanced.useVertexNormals = mLodConfig.advanced.useVertexNormals; + gen.generateLodLevels(lodConfig); + recreateEntity(); } void Sample_MeshLod::loadUserLod( bool useWorkLod ) { - if(mLodConfig.mesh->getBoundingSphereRadius() == 0){ - // failed to load mesh - return; - } - if(mLodConfig.levels.empty()){ - useWorkLod = true; - } - mTrayMgr->destroyAllWidgetsInTray(TL_TOP); - // Remove outdated Lod requests to reduce delay. - LodWorkQueueWorker::getSingleton().clearPendingLodRequests(); - - MeshLodGenerator& gen = MeshLodGenerator::getSingleton(); - mLodConfig.advanced.useBackgroundQueue = ENABLE_THREADING; - if(!useWorkLod){ - gen.generateLodLevels(mLodConfig); + if(mLodConfig.mesh->getBoundingSphereRadius() == 0){ + // failed to load mesh + return; + } + if(mLodConfig.levels.empty()){ + useWorkLod = true; + } + mTrayMgr->destroyAllWidgetsInTray(TL_TOP); + // Remove outdated Lod requests to reduce delay. + LodWorkQueueWorker::getSingleton().clearPendingLodRequests(); + + MeshLodGenerator& gen = MeshLodGenerator::getSingleton(); + mLodConfig.advanced.useBackgroundQueue = ENABLE_THREADING; + if(!useWorkLod){ + gen.generateLodLevels(mLodConfig); #if !ENABLE_THREADING - recreateEntity(); // Needed for manual Lod levels + recreateEntity(); // Needed for manual Lod levels #endif - forceLodLevel(-1); - } else { - LodConfig config(mLodConfig); - config.levels.clear(); - config.levels.push_back(mWorkLevel); - gen.generateLodLevels(config); - //gen.generateLodLevels(config, new LodCollapseCostQuadric()); // Use quadric error + forceLodLevel(-1); + } else { + LodConfig config(mLodConfig); + config.levels.clear(); + config.levels.push_back(mWorkLevel); + gen.generateLodLevels(config); + //gen.generateLodLevels(config, new LodCollapseCostQuadric()); // Use quadric error #if !ENABLE_THREADING - recreateEntity(); // Needed for manual Lod levels + recreateEntity(); // Needed for manual Lod levels #endif - forceLodLevel(1); - } + forceLodLevel(1); + } } void Sample_MeshLod::forceLodLevel(int lodLevelID, bool forceDelayed) { - mForcedLodLevel = lodLevelID; - // These are the requirements for async Lod generation - if(!forceDelayed || !ENABLE_THREADING || OGRE_THREAD_SUPPORT == 0){ - if(lodLevelID == -1 || mLodConfig.mesh->getNumLodLevels() <= 1) { - // Clear forced Lod level - mMeshEntity->setMeshLodBias(1.0, 0, std::numeric_limits::max()); - } else { - mMeshEntity->setMeshLodBias(1.0, lodLevelID, lodLevelID); - } - } + mForcedLodLevel = lodLevelID; + // These are the requirements for async Lod generation + if(!forceDelayed || !ENABLE_THREADING || OGRE_THREAD_SUPPORT == 0){ + if(lodLevelID == -1 || mLodConfig.mesh->getNumLodLevels() <= 1) { + // Clear forced Lod level + mMeshEntity->setMeshLodBias(1.0, 0, std::numeric_limits::max()); + } else { + mMeshEntity->setMeshLodBias(1.0, lodLevelID, lodLevelID); + } + } } size_t Sample_MeshLod::getUniqueVertexCount( MeshPtr mesh ) { - // The vertex buffer contains the same vertex position multiple times. - // To get the count of the vertices, which has unique positions, we can use progressive mesh. - // It is constructing a mesh grid at the beginning, so if we reduce 0%, we will get the unique vertex count. - LodConfig lodConfig(mesh, PixelCountLodStrategy::getSingletonPtr()); - lodConfig.advanced.useBackgroundQueue = false; // Non-threaded - lodConfig.createGeneratedLodLevel(0, 0); - MeshLodGenerator& gen = MeshLodGenerator::getSingleton(); - gen.generateLodLevels(lodConfig); - //ProgressiveMeshGenerator pm; - //pm.generateLodLevels(lodConfig); - return lodConfig.levels[0].outUniqueVertexCount; + // The vertex buffer contains the same vertex position multiple times. + // To get the count of the vertices, which has unique positions, we can use progressive mesh. + // It is constructing a mesh grid at the beginning, so if we reduce 0%, we will get the unique vertex count. + LodConfig lodConfig(mesh, PixelCountLodStrategy::getSingletonPtr()); + lodConfig.advanced.useBackgroundQueue = false; // Non-threaded + lodConfig.createGeneratedLodLevel(0, 0); + MeshLodGenerator& gen = MeshLodGenerator::getSingleton(); + gen.generateLodLevels(lodConfig); + //ProgressiveMeshGenerator pm; + //pm.generateLodLevels(lodConfig); + return lodConfig.levels[0].outUniqueVertexCount; } void Sample_MeshLod::addLodLevel() { - LodLevel lvl(mWorkLevel); - lvl.distance = getCameraDistance(); - Real distepsilon = lvl.distance + lvl.distance * 0.001; - size_t i = 0; - bool addLevel = true; - for(; i < mLodConfig.levels.size(); i++){ - if(mLodConfig.levels[i].distance < distepsilon){ - addLevel = false; - break; - } - } - if(/*mLodConfig.levels.empty() || */addLevel){ - mLodConfig.levels.push_back(lvl); - mLodLevelList->addItem(StringConverter::toString(lvl.distance) + "px"); - mLodLevelList->selectItem(mLodLevelList->getNumItems() - 1, false); - } else { - mLodConfig.levels.insert(mLodConfig.levels.begin() + i, lvl); - mLodLevelList->insertItem(i, StringConverter::toString(lvl.distance) + "px"); - mLodLevelList->selectItem(i, false); - } + LodLevel lvl(mWorkLevel); + lvl.distance = getCameraDistance(); + Real distepsilon = lvl.distance + lvl.distance * 0.001; + size_t i = 0; + bool addLevel = true; + for(; i < mLodConfig.levels.size(); i++){ + if(mLodConfig.levels[i].distance < distepsilon){ + addLevel = false; + break; + } + } + if(/*mLodConfig.levels.empty() || */addLevel){ + mLodConfig.levels.push_back(lvl); + mLodLevelList->addItem(StringConverter::toString(lvl.distance) + "px"); + mLodLevelList->selectItem(mLodLevelList->getNumItems() - 1, false); + } else { + mLodConfig.levels.insert(mLodConfig.levels.begin() + i, lvl); + mLodLevelList->insertItem(i, StringConverter::toString(lvl.distance) + "px"); + mLodLevelList->selectItem(i, false); + } } void Sample_MeshLod::loadLodLevel( int id ) { - assert(mLodConfig.levels[id].reductionMethod == LodLevel::VRM_CONSTANT); - mWorkLevel = mLodConfig.levels[id]; - mReductionSlider->setValue(mWorkLevel.reductionValue, false); - mLodLevelList->selectItem(id, false); - mManualMeshes->selectItem(mWorkLevel.manualMeshName, false); - loadUserLod(); - moveCameraToPixelDistance(mWorkLevel.distance); + assert(mLodConfig.levels[id].reductionMethod == LodLevel::VRM_CONSTANT); + mWorkLevel = mLodConfig.levels[id]; + mReductionSlider->setValue(mWorkLevel.reductionValue, false); + mLodLevelList->selectItem(id, false); + mManualMeshes->selectItem(mWorkLevel.manualMeshName, false); + loadUserLod(); + moveCameraToPixelDistance(mWorkLevel.distance); } void Sample_MeshLod::removeLodLevel() { - if(mLodConfig.levels.empty()){ - return; - } - int selectedLevel = mLodLevelList->getSelectionIndex(); - mLodConfig.levels.erase(mLodConfig.levels.begin() + selectedLevel); - mLodLevelList->removeItem(selectedLevel); + if(mLodConfig.levels.empty()){ + return; + } + int selectedLevel = mLodLevelList->getSelectionIndex(); + mLodConfig.levels.erase(mLodConfig.levels.begin() + selectedLevel); + mLodLevelList->removeItem(selectedLevel); } Real Sample_MeshLod::getCameraDistance() { - if(mLodConfig.mesh->getBoundingSphereRadius() != 0.0){ - return PixelCountLodStrategy::getSingleton().getValue(mMeshEntity, mCameraMan->getCamera()); - } else { - return 0.0; - } + if(mLodConfig.mesh->getBoundingSphereRadius() != 0.0){ + return PixelCountLodStrategy::getSingleton().getValue(mMeshEntity, mCameraMan->getCamera()); + } else { + return 0.0; + } } void Sample_MeshLod::moveCameraToPixelDistance( Real pixels ) { - PixelCountLodStrategy& strategy = PixelCountLodStrategy::getSingleton(); - Real distance = mLodConfig.mesh->getBoundingSphereRadius() * 4; - const Real epsilon = pixels * 0.000001; - const int iterations = 64; - mCamera->setPosition(Vector3(0, 0, 0)); - mCamera->moveRelative(Vector3(0, 0, distance)); - // We need to find a distance, which is bigger then requested - for(int i=0;igetCamera()); - if (curPixels > pixels) { - distance *= 2.0; - mCamera->moveRelative(Vector3(0, 0, distance)); - } else { - break; - } - } - // Binary search for distance - for(int i=0;igetCamera()); - if(std::abs(curPixels - pixels) < epsilon){ - break; - } - distance /= 2; - if (curPixels > pixels) { - // move camera further - mCamera->moveRelative(Vector3(0, 0, distance)); - } else { - // move camera nearer - mCamera->moveRelative(Vector3(0, 0, -distance)); - } - } + PixelCountLodStrategy& strategy = PixelCountLodStrategy::getSingleton(); + Real distance = mLodConfig.mesh->getBoundingSphereRadius() * 4; + const Real epsilon = pixels * 0.000001; + const int iterations = 64; + mCamera->setPosition(Vector3(0, 0, 0)); + mCamera->moveRelative(Vector3(0, 0, distance)); + // We need to find a distance, which is bigger then requested + for(int i=0;igetCamera()); + if (curPixels > pixels) { + distance *= 2.0; + mCamera->moveRelative(Vector3(0, 0, distance)); + } else { + break; + } + } + // Binary search for distance + for(int i=0;igetCamera()); + if(std::abs(curPixels - pixels) < epsilon){ + break; + } + distance /= 2; + if (curPixels > pixels) { + // move camera further + mCamera->moveRelative(Vector3(0, 0, distance)); + } else { + // move camera nearer + mCamera->moveRelative(Vector3(0, 0, -distance)); + } + } } bool Sample_MeshLod::getResourceFullPath(MeshPtr& mesh, String& outPath) { - ResourceGroupManager& resourceGroupMgr = ResourceGroupManager::getSingleton(); - String group = mesh->getGroup(); - String name = mesh->getName(); + ResourceGroupManager& resourceGroupMgr = ResourceGroupManager::getSingleton(); + String group = mesh->getGroup(); + String name = mesh->getName(); Ogre::FileInfo* info = NULL; - FileInfoListPtr locPtr = resourceGroupMgr.listResourceFileInfo(group); - FileInfoList::iterator it, itEnd; - it = locPtr->begin(); - itEnd = locPtr->end(); - for (; it != itEnd; it++) { - if (stricmp(name.c_str(), it->filename.c_str()) == 0) { - info = &*it; - break; - } - } - if(!info) { - outPath = name; - return false; - } - outPath = info->archive->getName(); - if (outPath[outPath .size()-1] != '/' && outPath[outPath .size()-1] != '\\') { - outPath += '/'; - } - outPath += info->path; - if (outPath[outPath .size()-1] != '/' && outPath[outPath .size()-1] != '\\') { - outPath += '/'; - } - outPath += info->filename; - - return (info->archive->getType() == "FileSystem"); + FileInfoListPtr locPtr = resourceGroupMgr.listResourceFileInfo(group); + FileInfoList::iterator it, itEnd; + it = locPtr->begin(); + itEnd = locPtr->end(); + for (; it != itEnd; it++) { + if (stricmp(name.c_str(), it->filename.c_str()) == 0) { + info = &*it; + break; + } + } + if(!info) { + outPath = name; + return false; + } + outPath = info->archive->getName(); + if (outPath[outPath .size()-1] != '/' && outPath[outPath .size()-1] != '\\') { + outPath += '/'; + } + outPath += info->path; + if (outPath[outPath .size()-1] != '/' && outPath[outPath .size()-1] != '\\') { + outPath += '/'; + } + outPath += info->filename; + + return (info->archive->getType() == "FileSystem"); } void Sample_MeshLod::addToProfile( Real cost ) { - LodConfig config(mLodConfig); - config.levels.clear(); - config.levels.push_back(mWorkLevel); - config.advanced.useBackgroundQueue = false; - MeshLodGenerator& gen = MeshLodGenerator::getSingleton(); - LodCollapserPtr collapser(new LodCollapser()); - LodDataPtr data(new LodData()); - gen.generateLodLevels(config, LodCollapseCostPtr(), data, LodInputProviderPtr(), LodOutputProviderPtr(), collapser); - - ProfiledEdge pv; - if(collapser->_getLastVertexPos(data.get(), pv.src)){ - collapser->_getLastVertexCollapseTo(data.get(), pv.dst); - // Prevent duplicates if you edit the same vertex twice. - size_t size = mLodConfig.advanced.profile.size(); - for(uint i=0;iselectItem(i, false); - loadUserLod(); - return; - } - } - // Copy profile in queued build. - pv.cost = cost; - mLodConfig.advanced.profile.push_back(pv); - mProfileList->addItem(StringConverter::toString(pv.src)); - mProfileList->selectItem(mProfileList->getNumItems() - 1, false); - } else { - mTrayMgr->showOkDialog("Error", "No vertex selected, because the mesh is not reduced."); - } - loadUserLod(); + LodConfig config(mLodConfig); + config.levels.clear(); + config.levels.push_back(mWorkLevel); + config.advanced.useBackgroundQueue = false; + MeshLodGenerator& gen = MeshLodGenerator::getSingleton(); + LodCollapserPtr collapser(new LodCollapser()); + LodDataPtr data(new LodData()); + gen.generateLodLevels(config, LodCollapseCostPtr(), data, LodInputProviderPtr(), LodOutputProviderPtr(), collapser); + + ProfiledEdge pv; + if(collapser->_getLastVertexPos(data.get(), pv.src)){ + collapser->_getLastVertexCollapseTo(data.get(), pv.dst); + // Prevent duplicates if you edit the same vertex twice. + size_t size = mLodConfig.advanced.profile.size(); + for(uint i=0;iselectItem(i, false); + loadUserLod(); + return; + } + } + // Copy profile in queued build. + pv.cost = cost; + mLodConfig.advanced.profile.push_back(pv); + mProfileList->addItem(StringConverter::toString(pv.src)); + mProfileList->selectItem(mProfileList->getNumItems() - 1, false); + } else { + mTrayMgr->showOkDialog("Error", "No vertex selected, because the mesh is not reduced."); + } + loadUserLod(); } bool Sample_MeshLod::frameStarted( const FrameEvent& evt ) { - mDistanceLabel->setCaption("Distance: " + StringConverter::toString(getCameraDistance()) + "px"); - return true; + mDistanceLabel->setCaption("Distance: " + StringConverter::toString(getCameraDistance()) + "px"); + return true; } void Sample_MeshLod::checkBoxToggled( CheckBox * box ) { - if(box->getName() == "chkUseVertexNormals") { - mLodConfig.advanced.useVertexNormals = box->isChecked(); - loadUserLod(); - } else if (box->getName() == "chkShowWireframe") { - mCameraMan->getCamera()->setPolygonMode(mWireframe->isChecked() ? PM_WIREFRAME : PM_SOLID); - } + if(box->getName() == "chkUseVertexNormals") { + mLodConfig.advanced.useVertexNormals = box->isChecked(); + loadUserLod(); + } else if (box->getName() == "chkShowWireframe") { + mCameraMan->getCamera()->setPolygonMode(mWireframe->isChecked() ? PM_WIREFRAME : PM_SOLID); + } } void Sample_MeshLod::itemSelected( SelectMenu* menu ) { - if (menu->getName() == "cmbModels") { - changeSelectedMesh(menu->getSelectedItem()); - } else if(menu->getName() == "cmbLodLevels") { - loadLodLevel(menu->getSelectionIndex()); - } else if(menu->getName() == "cmbManualMesh") { - mWorkLevel.manualMeshName = menu->getSelectedItem(); - loadUserLod(); - } + if (menu->getName() == "cmbModels") { + changeSelectedMesh(menu->getSelectedItem()); + } else if(menu->getName() == "cmbLodLevels") { + loadLodLevel(menu->getSelectionIndex()); + } else if(menu->getName() == "cmbManualMesh") { + mWorkLevel.manualMeshName = menu->getSelectedItem(); + loadUserLod(); + } } void Sample_MeshLod::sliderMoved(Slider* slider) { - if (slider->getName() == "sldReductionValue") { - mWorkLevel.reductionValue = slider->getValue(); - loadUserLod(); - } else if (slider->getName() == "sldOutsideWeight") { - if(mOutsideWeightSlider->getValue() == 100){ - mLodConfig.advanced.outsideWeight = LodData::NEVER_COLLAPSE_COST; - } else { - mLodConfig.advanced.outsideWeight = (mOutsideWeightSlider->getValue() * mOutsideWeightSlider->getValue()) / 10000; - } - loadUserLod(); - } else if (slider->getName() == "sldOutsideWalkAngle") { - mLodConfig.advanced.outsideWalkAngle = mOutsideWalkAngle->getValue(); - loadUserLod(); - } - + if (slider->getName() == "sldReductionValue") { + mWorkLevel.reductionValue = slider->getValue(); + loadUserLod(); + } else if (slider->getName() == "sldOutsideWeight") { + if(mOutsideWeightSlider->getValue() == 100){ + mLodConfig.advanced.outsideWeight = LodData::NEVER_COLLAPSE_COST; + } else { + mLodConfig.advanced.outsideWeight = (mOutsideWeightSlider->getValue() * mOutsideWeightSlider->getValue()) / 10000; + } + loadUserLod(); + } else if (slider->getName() == "sldOutsideWalkAngle") { + mLodConfig.advanced.outsideWalkAngle = mOutsideWalkAngle->getValue(); + loadUserLod(); + } + } void Sample_MeshLod::buttonHit( OgreBites::Button* button ) { - if(button->getName() == "btnReduceMore") { - mReductionSlider->setValue(mReductionSlider->getValue()+1); - } else if(button->getName() == "btnReduceLess") { - mReductionSlider->setValue(mReductionSlider->getValue()-1); - } else if(button->getName() == "btnAddToProfile") { - addToProfile(std::numeric_limits::max()); - } else if(button->getName() == "btnRemoveFromProfile") { - if(!mLodConfig.advanced.profile.empty()){ - LodProfile& profile = mLodConfig.advanced.profile; - profile.erase(profile.begin() + mProfileList->getSelectionIndex()); - mProfileList->removeItem(mProfileList->getSelectionIndex()); - loadUserLod(); - } - } else if(button->getName() == "btnRemoveSelectedLodLevel") { - removeLodLevel(); - } else if(button->getName() == "btnAddLodLevel") { - addLodLevel(); - } else if(button->getName() == "btnAutoconfigure") { - mTrayMgr->destroyAllWidgetsInTray(TL_TOP); - mTrayMgr->createLabel(TL_TOP, "lblWhatYouSee", "Showing autoconfigured LOD", 300); - loadAutomaticLod(); - forceLodLevel(-1); // disable Lod level forcing - } else if (button->getName() == "btnShowAll") { - loadUserLod(false); - mTrayMgr->destroyAllWidgetsInTray(TL_TOP); - mTrayMgr->createLabel(TL_TOP, "lblWhatYouSee", "Showing all LOD levels", 300); - forceLodLevel(-1); // disable Lod level forcing - } else if(button->getName() == "btnShowMesh") { - mTrayMgr->destroyAllWidgetsInTray(TL_TOP); - mTrayMgr->createLabel(TL_TOP, "lblWhatYouSee", "Showing LOD from mesh file", 300); - if(mMeshEntity){ - mSceneMgr->destroyEntity(mMeshEntity); - mMeshEntity = 0; - } - mLodConfig.mesh->reload(); - mMeshEntity = mSceneMgr->createEntity(mLodConfig.mesh->getName(), mLodConfig.mesh); - mMeshNode->attachObject(mMeshEntity); - forceLodLevel(-1); // disable Lod level forcing - //String filename(""); - //getResourceFullPath(mLodConfig.mesh, filename); - //mTrayMgr->showOkDialog("Success", "Showing mesh from: " + filename); - } else if(button->getName() == "btnSaveMesh") { - if(!mTrayMgr->getTrayContainer(TL_TOP)->isVisible() && !mLodConfig.levels.empty()){ - LodWorkQueueWorker::getSingleton().clearPendingLodRequests(); - MeshLodGenerator& gen = MeshLodGenerator::getSingleton(); - mLodConfig.advanced.useBackgroundQueue = false; // Non-threaded - gen.generateLodLevels(mLodConfig); - forceLodLevel(-1); // disable Lod level forcing - } - String filename(""); - if(!getResourceFullPath(mLodConfig.mesh, filename) || filename == "") { - mTrayMgr->showOkDialog("Error", "'" + filename + "' is not a writable path!"); - } else { - MeshSerializer ms; - ms.exportMesh(mLodConfig.mesh.get(), filename); - mTrayMgr->showOkDialog("Success", "Mesh saved to: " + filename); - } - if(!mTrayMgr->getTrayContainer(TL_TOP)->isVisible()){ - loadUserLod(); - } - } + if(button->getName() == "btnReduceMore") { + mReductionSlider->setValue(mReductionSlider->getValue()+1); + } else if(button->getName() == "btnReduceLess") { + mReductionSlider->setValue(mReductionSlider->getValue()-1); + } else if(button->getName() == "btnAddToProfile") { + addToProfile(std::numeric_limits::max()); + } else if(button->getName() == "btnRemoveFromProfile") { + if(!mLodConfig.advanced.profile.empty()){ + LodProfile& profile = mLodConfig.advanced.profile; + profile.erase(profile.begin() + mProfileList->getSelectionIndex()); + mProfileList->removeItem(mProfileList->getSelectionIndex()); + loadUserLod(); + } + } else if(button->getName() == "btnRemoveSelectedLodLevel") { + removeLodLevel(); + } else if(button->getName() == "btnAddLodLevel") { + addLodLevel(); + } else if(button->getName() == "btnAutoconfigure") { + mTrayMgr->destroyAllWidgetsInTray(TL_TOP); + mTrayMgr->createLabel(TL_TOP, "lblWhatYouSee", "Showing autoconfigured LOD", 300); + loadAutomaticLod(); + forceLodLevel(-1); // disable Lod level forcing + } else if (button->getName() == "btnShowAll") { + loadUserLod(false); + mTrayMgr->destroyAllWidgetsInTray(TL_TOP); + mTrayMgr->createLabel(TL_TOP, "lblWhatYouSee", "Showing all LOD levels", 300); + forceLodLevel(-1); // disable Lod level forcing + } else if(button->getName() == "btnShowMesh") { + mTrayMgr->destroyAllWidgetsInTray(TL_TOP); + mTrayMgr->createLabel(TL_TOP, "lblWhatYouSee", "Showing LOD from mesh file", 300); + if(mMeshEntity){ + mSceneMgr->destroyEntity(mMeshEntity); + mMeshEntity = 0; + } + mLodConfig.mesh->reload(); + mMeshEntity = mSceneMgr->createEntity(mLodConfig.mesh->getName(), mLodConfig.mesh); + mMeshNode->attachObject(mMeshEntity); + forceLodLevel(-1); // disable Lod level forcing + //String filename(""); + //getResourceFullPath(mLodConfig.mesh, filename); + //mTrayMgr->showOkDialog("Success", "Showing mesh from: " + filename); + } else if(button->getName() == "btnSaveMesh") { + if(!mTrayMgr->getTrayContainer(TL_TOP)->isVisible() && !mLodConfig.levels.empty()){ + LodWorkQueueWorker::getSingleton().clearPendingLodRequests(); + MeshLodGenerator& gen = MeshLodGenerator::getSingleton(); + mLodConfig.advanced.useBackgroundQueue = false; // Non-threaded + gen.generateLodLevels(mLodConfig); + forceLodLevel(-1); // disable Lod level forcing + } + String filename(""); + if(!getResourceFullPath(mLodConfig.mesh, filename) || filename == "") { + mTrayMgr->showOkDialog("Error", "'" + filename + "' is not a writable path!"); + } else { + MeshSerializer ms; + ms.exportMesh(mLodConfig.mesh.get(), filename); + mTrayMgr->showOkDialog("Success", "Mesh saved to: " + filename); + } + if(!mTrayMgr->getTrayContainer(TL_TOP)->isVisible()){ + loadUserLod(); + } + } } bool Sample_MeshLod::shouldInject( LodWorkQueueRequest* request ) { - return true; + return true; } void Sample_MeshLod::injectionCompleted( LodWorkQueueRequest* request ) { - recreateEntity(); // Needed for manual lod levels. - forceLodLevel(mForcedLodLevel, false); + recreateEntity(); // Needed for manual lod levels. + forceLodLevel(mForcedLodLevel, false); } diff --git a/Samples/MeshLod/src/MeshLodPlugin.cpp b/Samples/MeshLod/src/MeshLodPlugin.cpp index b7beb64b66e..305443f9866 100644 --- a/Samples/MeshLod/src/MeshLodPlugin.cpp +++ b/Samples/MeshLod/src/MeshLodPlugin.cpp @@ -7,17 +7,17 @@ OgreBites::Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_MeshLod; - sp = OGRE_NEW OgreBites::SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Ogre::Root::getSingleton().installPlugin(sp); + s = new Sample_MeshLod; + sp = OGRE_NEW OgreBites::SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Ogre::Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Ogre::Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Ogre::Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/NewInstancing/include/MersenneTwister.h b/Samples/NewInstancing/include/MersenneTwister.h index f1a2e1b058d..3434d2b352b 100644 --- a/Samples/NewInstancing/include/MersenneTwister.h +++ b/Samples/NewInstancing/include/MersenneTwister.h @@ -9,52 +9,52 @@ class MersenneTwister { private: - int seed[MTSZ]; - int index; + int seed[MTSZ]; + int index; - void generate() - { - for (int i = 0; i < MTSZ; i++) - { - int y = (((seed[i] << 31) & 0x80000000) + (seed[(i+1) % MTSZ] & 0x7FFFFFFF)) >> 1; - seed[i] = seed[(i + MTSZSP) % MTSZ] ^ y; - seed[i] ^= (y&1)? 0x9908b0df: 0; - } - } + void generate() + { + for (int i = 0; i < MTSZ; i++) + { + int y = (((seed[i] << 31) & 0x80000000) + (seed[(i+1) % MTSZ] & 0x7FFFFFFF)) >> 1; + seed[i] = seed[(i + MTSZSP) % MTSZ] ^ y; + seed[i] ^= (y&1)? 0x9908b0df: 0; + } + } public: - MersenneTwister() - { - index = 0; - randomize(); - } - - void randomize(int seedVal = 0x12345678) - { - seed[0] = seedVal; - for (int i = 1; i < MTSZ; ++i) - seed[i] = (int)(0x6c078965*((this->seed[i-1] >> 30)+i)); - } - - unsigned int nextUInt() - { - unsigned int ret; - if (index == 0) - generate(); - ret = seed[index]; - - ret ^= ret >> 11; - ret ^= (ret << 7) & 0x9d2c5680; - ret ^= (ret << 15) & 0xefc60000; - ret ^= ret >> 18; - - index = (++index < MTSZ)? index: 0; - - return ret; - } - - float nextFloat() - { - return (nextUInt() / (float)0xFFFFFFFF); - } + MersenneTwister() + { + index = 0; + randomize(); + } + + void randomize(int seedVal = 0x12345678) + { + seed[0] = seedVal; + for (int i = 1; i < MTSZ; ++i) + seed[i] = (int)(0x6c078965*((this->seed[i-1] >> 30)+i)); + } + + unsigned int nextUInt() + { + unsigned int ret; + if (index == 0) + generate(); + ret = seed[index]; + + ret ^= ret >> 11; + ret ^= (ret << 7) & 0x9d2c5680; + ret ^= (ret << 15) & 0xefc60000; + ret ^= ret >> 18; + + index = (++index < MTSZ)? index: 0; + + return ret; + } + + float nextFloat() + { + return (nextUInt() / (float)0xFFFFFFFF); + } }; #endif diff --git a/Samples/NewInstancing/include/NewInstancing.h b/Samples/NewInstancing/include/NewInstancing.h index 89f362d9629..e51afb69fc3 100644 --- a/Samples/NewInstancing/include/NewInstancing.h +++ b/Samples/NewInstancing/include/NewInstancing.h @@ -14,92 +14,92 @@ class _OgreSampleClassExport Sample_NewInstancing : public SdkSample { public: - Sample_NewInstancing(); + Sample_NewInstancing(); - bool frameRenderingQueued(const FrameEvent& evt); + bool frameRenderingQueued(const FrameEvent& evt); - bool keyPressed(const OIS::KeyEvent& evt); - + bool keyPressed(const OIS::KeyEvent& evt); + protected: - void setupContent(); + void setupContent(); - void setupLighting(); - - void switchInstancingTechnique(); + void setupLighting(); + + void switchInstancingTechnique(); - void switchSkinningTechnique(int index); + void switchSkinningTechnique(int index); - void createEntities(); + void createEntities(); - void createInstancedEntities(); + void createInstancedEntities(); - void createSceneNodes(); - - void clearScene(); + void createSceneNodes(); + + void clearScene(); - void destroyManagers(); + void destroyManagers(); - void cleanupContent(); + void cleanupContent(); - void animateUnits( float timeSinceLast ); + void animateUnits( float timeSinceLast ); - void moveUnits( float timeSinceLast ); + void moveUnits( float timeSinceLast ); - //Helper function to look towards normDir, where this vector is normalized, with fixed Yaw - Quaternion lookAt( const Vector3 &normDir ); + //Helper function to look towards normDir, where this vector is normalized, with fixed Yaw + Quaternion lookAt( const Vector3 &normDir ); - void defragmentBatches(); + void defragmentBatches(); - void setupGUI(); + void setupGUI(); - void itemSelected(SelectMenu* menu); + void itemSelected(SelectMenu* menu); - void buttonHit( OgreBites::Button* button ); + void buttonHit( OgreBites::Button* button ); - void checkBoxToggled(CheckBox* box); + void checkBoxToggled(CheckBox* box); - void sliderMoved(Slider* slider); + void sliderMoved(Slider* slider); - void testCapabilities(const RenderSystemCapabilities* caps); + void testCapabilities(const RenderSystemCapabilities* caps); - //The difference between testCapabilities() is that features checked here aren't fatal errors. - //which means the sample can run (with limited functionality) on those computers - void checkHardwareSupport(); + //The difference between testCapabilities() is that features checked here aren't fatal errors. + //which means the sample can run (with limited functionality) on those computers + void checkHardwareSupport(); - //You can also use a union type to switch between Entity and InstancedEntity almost flawlessly: - /* - union FusionEntity - { - Entity entity - InstancedEntity instancedEntity; - }; - */ - int NUM_INST_ROW; - int NUM_INST_COLUMN; - int mInstancingTechnique; - int mCurrentMesh; - std::vector mEntities; - std::vector mMovedInstances; - std::vector mSceneNodes; - std::set mAnimations; - InstanceManager *mCurrentManager; - bool mSupportedTechniques[NUM_TECHNIQUES+1]; - const char** mCurrentMaterialSet; - uint16 mCurrentFlags; + //You can also use a union type to switch between Entity and InstancedEntity almost flawlessly: + /* + union FusionEntity + { + Entity entity + InstancedEntity instancedEntity; + }; + */ + int NUM_INST_ROW; + int NUM_INST_COLUMN; + int mInstancingTechnique; + int mCurrentMesh; + std::vector mEntities; + std::vector mMovedInstances; + std::vector mSceneNodes; + std::set mAnimations; + InstanceManager *mCurrentManager; + bool mSupportedTechniques[NUM_TECHNIQUES+1]; + const char** mCurrentMaterialSet; + uint16 mCurrentFlags; - SelectMenu *mTechniqueMenu; - CheckBox *mMoveInstances; - CheckBox *mAnimateInstances; - SelectMenu *mSkinningTechniques; - CheckBox *mEnableShadows; - CheckBox *mSetStatic; - CheckBox *mUseSceneNodes; - OgreBites::Button *mDefragmentBatches; - CheckBox *mDefragmentOptimumCull; - Slider *mInstancesSlider; + SelectMenu *mTechniqueMenu; + CheckBox *mMoveInstances; + CheckBox *mAnimateInstances; + SelectMenu *mSkinningTechniques; + CheckBox *mEnableShadows; + CheckBox *mSetStatic; + CheckBox *mUseSceneNodes; + OgreBites::Button *mDefragmentBatches; + CheckBox *mDefragmentOptimumCull; + Slider *mInstancesSlider; - MersenneTwister randGenerator; + MersenneTwister randGenerator; }; #endif diff --git a/Samples/NewInstancing/src/NewInstancing.cpp b/Samples/NewInstancing/src/NewInstancing.cpp index 652641d9367..6c8c42e94d4 100644 --- a/Samples/NewInstancing/src/NewInstancing.cpp +++ b/Samples/NewInstancing/src/NewInstancing.cpp @@ -11,127 +11,127 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_NewInstancing; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_NewInstancing; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif static const char *c_instancingTechniques[] = { - "Shader Based", - "Vertex Texture Fetch (VTF)", - "Hardware Instancing Basic", - "Hardware Instancing + VTF", - "Limited Animation - Hardware Instancing + VTF", - "No Instancing" + "Shader Based", + "Vertex Texture Fetch (VTF)", + "Hardware Instancing Basic", + "Hardware Instancing + VTF", + "Limited Animation - Hardware Instancing + VTF", + "No Instancing" }; static const char *c_materialsTechniques[] = { - "Examples/Instancing/ShaderBased/Robot", - "Examples/Instancing/VTF/Robot", - "Examples/Instancing/HWBasic/Robot", - "Examples/Instancing/VTF/HW/Robot", - "Examples/Instancing/VTF/HW/LUT/Robot", - "Examples/Instancing/ShaderBased/Robot" + "Examples/Instancing/ShaderBased/Robot", + "Examples/Instancing/VTF/Robot", + "Examples/Instancing/HWBasic/Robot", + "Examples/Instancing/VTF/HW/Robot", + "Examples/Instancing/VTF/HW/LUT/Robot", + "Examples/Instancing/ShaderBased/Robot" }; static const char *c_materialsTechniques_dq[] = { - "Examples/Instancing/ShaderBased/Robot_dq", - "Examples/Instancing/VTF/Robot_dq", - "Examples/Instancing/HWBasic/Robot", - "Examples/Instancing/VTF/HW/Robot_dq", - "Examples/Instancing/VTF/HW/LUT/Robot_dq", - "Examples/Instancing/ShaderBased/Robot_dq" + "Examples/Instancing/ShaderBased/Robot_dq", + "Examples/Instancing/VTF/Robot_dq", + "Examples/Instancing/HWBasic/Robot", + "Examples/Instancing/VTF/HW/Robot_dq", + "Examples/Instancing/VTF/HW/LUT/Robot_dq", + "Examples/Instancing/ShaderBased/Robot_dq" }; static const char *c_materialsTechniques_dq_two_weights[] = { - "Examples/Instancing/ShaderBased/spine_dq_two_weights", - "Examples/Instancing/VTF/spine_dq_two_weights", - "Examples/Instancing/HWBasic/spine", - "Examples/Instancing/VTF/HW/spine_dq_two_weights", - "Examples/Instancing/VTF/HW/LUT/spine_dq_two_weights", - "Examples/Instancing/ShaderBased/spine_dq_two_weights" + "Examples/Instancing/ShaderBased/spine_dq_two_weights", + "Examples/Instancing/VTF/spine_dq_two_weights", + "Examples/Instancing/HWBasic/spine", + "Examples/Instancing/VTF/HW/spine_dq_two_weights", + "Examples/Instancing/VTF/HW/LUT/spine_dq_two_weights", + "Examples/Instancing/ShaderBased/spine_dq_two_weights" }; static const char *c_meshNames[] = { - "robot.mesh", - "spine.mesh" + "robot.mesh", + "spine.mesh" }; //------------------------------------------------------------------------------ Sample_NewInstancing::Sample_NewInstancing() : NUM_INST_ROW(50), NUM_INST_COLUMN(50), mCurrentManager(0), mCurrentMaterialSet(c_materialsTechniques), mCurrentFlags(0), mSkinningTechniques(NULL) { - mInfo["Title"] = "New Instancing"; - mInfo["Description"] = "Demonstrates how to use the new InstancedManager to setup many dynamic" - " instances of the same mesh with much less performance impact"; - mInfo["Thumbnail"] = "thumb_newinstancing.png"; - mInfo["Category"] = "Environment"; - mInfo["Help"] = "Press Space to switch Instancing Techniques.\n" - "Press B to toggle bounding boxes.\n\n" - "Changes in the slider take effect after switching instancing technique\n" - "Different batch sizes give different results depending on CPU culling" - " and instance numbers on the scene.\n\n" - "If performance is too slow, try defragmenting batches once in a while"; + mInfo["Title"] = "New Instancing"; + mInfo["Description"] = "Demonstrates how to use the new InstancedManager to setup many dynamic" + " instances of the same mesh with much less performance impact"; + mInfo["Thumbnail"] = "thumb_newinstancing.png"; + mInfo["Category"] = "Environment"; + mInfo["Help"] = "Press Space to switch Instancing Techniques.\n" + "Press B to toggle bounding boxes.\n\n" + "Changes in the slider take effect after switching instancing technique\n" + "Different batch sizes give different results depending on CPU culling" + " and instance numbers on the scene.\n\n" + "If performance is too slow, try defragmenting batches once in a while"; } //------------------------------------------------------------------------------ bool Sample_NewInstancing::frameRenderingQueued(const FrameEvent& evt) { - if( mAnimateInstances->isChecked() ) - animateUnits( evt.timeSinceLastEvent ); + if( mAnimateInstances->isChecked() ) + animateUnits( evt.timeSinceLastEvent ); - if( mMoveInstances->isChecked() ) - moveUnits( evt.timeSinceLastEvent ); + if( mMoveInstances->isChecked() ) + moveUnits( evt.timeSinceLastEvent ); - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! } //------------------------------------------------------------------------------ bool Sample_NewInstancing::keyPressed(const OIS::KeyEvent& evt) { - //Toggle bounding boxes with B key unless the help dialog is visible - if (evt.key == OIS::KC_B && !mTrayMgr->isDialogVisible() && mCurrentManager) - { - bool oldShow = mCurrentManager->getSetting( InstanceManager::SHOW_BOUNDINGBOX, - mCurrentMaterialSet[mInstancingTechnique] ); - mCurrentManager->setSetting( InstanceManager::SHOW_BOUNDINGBOX, !oldShow ); - } - - //Switch to next instancing technique with space bar - if (evt.key == OIS::KC_SPACE && !mTrayMgr->isDialogVisible()) - mTechniqueMenu->selectItem( (mTechniqueMenu->getSelectionIndex() + 1) % (NUM_TECHNIQUES+1) ); - - return SdkSample::keyPressed(evt); + //Toggle bounding boxes with B key unless the help dialog is visible + if (evt.key == OIS::KC_B && !mTrayMgr->isDialogVisible() && mCurrentManager) + { + bool oldShow = mCurrentManager->getSetting( InstanceManager::SHOW_BOUNDINGBOX, + mCurrentMaterialSet[mInstancingTechnique] ); + mCurrentManager->setSetting( InstanceManager::SHOW_BOUNDINGBOX, !oldShow ); + } + + //Switch to next instancing technique with space bar + if (evt.key == OIS::KC_SPACE && !mTrayMgr->isDialogVisible()) + mTechniqueMenu->selectItem( (mTechniqueMenu->getSelectionIndex() + 1) % (NUM_TECHNIQUES+1) ); + + return SdkSample::keyPressed(evt); } //------------------------------------------------------------------------------ void Sample_NewInstancing::setupContent() { - //Initialize the techniques and current mesh variables - mInstancingTechnique = 0; - mCurrentMesh = 0; - mCurrentManager = 0; + //Initialize the techniques and current mesh variables + mInstancingTechnique = 0; + mCurrentMesh = 0; + mCurrentManager = 0; - checkHardwareSupport(); + checkHardwareSupport(); mSceneMgr->setShadowTechnique( SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED ); - mSceneMgr->setShadowTextureSelfShadow( true ); - mSceneMgr->setShadowCasterRenderBackFaces( true ); + mSceneMgr->setShadowTextureSelfShadow( true ); + mSceneMgr->setShadowCasterRenderBackFaces( true ); if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL ES 2") == String::npos) { @@ -143,619 +143,619 @@ void Sample_NewInstancing::setupContent() mSceneMgr->setShadowTextureConfig( 0, 512, 512, PF_FLOAT32_R ); } - //LiSPSMShadowCameraSetup *shadowCameraSetup = new LiSPSMShadowCameraSetup(); - FocusedShadowCameraSetup *shadowCameraSetup = new FocusedShadowCameraSetup(); - //PlaneOptimalShadowCameraSetup *shadowCameraSetup = new PlaneOptimalShadowCameraSetup(); + //LiSPSMShadowCameraSetup *shadowCameraSetup = new LiSPSMShadowCameraSetup(); + FocusedShadowCameraSetup *shadowCameraSetup = new FocusedShadowCameraSetup(); + //PlaneOptimalShadowCameraSetup *shadowCameraSetup = new PlaneOptimalShadowCameraSetup(); - mSceneMgr->setShadowCameraSetup( ShadowCameraSetupPtr(shadowCameraSetup) ); + mSceneMgr->setShadowCameraSetup( ShadowCameraSetupPtr(shadowCameraSetup) ); - mEntities.reserve( NUM_INST_ROW * NUM_INST_COLUMN ); - mSceneNodes.reserve( NUM_INST_ROW * NUM_INST_COLUMN ); - - mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); + mEntities.reserve( NUM_INST_ROW * NUM_INST_COLUMN ); + mSceneNodes.reserve( NUM_INST_ROW * NUM_INST_COLUMN ); + + mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); - // create a mesh for our ground - MeshManager::getSingleton().createPlane("ground", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Plane(Vector3::UNIT_Y, 0), 10000, 10000, 20, 20, true, 1, 6, 6, Vector3::UNIT_Z); + // create a mesh for our ground + MeshManager::getSingleton().createPlane("ground", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Plane(Vector3::UNIT_Y, 0), 10000, 10000, 20, 20, true, 1, 6, 6, Vector3::UNIT_Z); - // create a ground entity from our mesh and attach it to the origin - Entity* ground = mSceneMgr->createEntity("Ground", "ground"); - ground->setMaterialName("Examples/Instancing/Misc/Grass"); - ground->setCastShadows(false); - mSceneMgr->getRootSceneNode()->attachObject(ground); + // create a ground entity from our mesh and attach it to the origin + Entity* ground = mSceneMgr->createEntity("Ground", "ground"); + ground->setMaterialName("Examples/Instancing/Misc/Grass"); + ground->setCastShadows(false); + mSceneMgr->getRootSceneNode()->attachObject(ground); - setupLighting(); + setupLighting(); - // set initial camera position and speed - mCamera->setPosition( 0, 120, 100 ); + // set initial camera position and speed + mCamera->setPosition( 0, 120, 100 ); - setupGUI(); + setupGUI(); #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS - setDragLook(true); + setDragLook(true); #endif - switchInstancingTechnique(); + switchInstancingTechnique(); } //------------------------------------------------------------------------------ void Sample_NewInstancing::setupLighting() { - mSceneMgr->setAmbientLight( ColourValue( 0.40f, 0.40f, 0.40f ) ); - - ColourValue lightColour( 1, 0.5, 0.3 ); - - //Create main (point) light - Light* light = mSceneMgr->createLight(); - light->setDiffuseColour(lightColour); - light->setPosition( 0.0f, 25.0f, 0.0f ); - light->setSpecularColour( 0.6, 0.82, 1.0 ); - light->setAttenuation( 3500, 0.085, 0.00008, 0.00006 ); - light->setCastShadows( false ); - - //Create a dummy spot light for shadows - light = mSceneMgr->createLight(); - light->setType( Light::LT_SPOTLIGHT ); - light->setDiffuseColour( ColourValue( 0.15f, 0.35f, 0.44f ) ); - light->setPosition( 250.0f, 200.0f, 250.0f ); - light->setDirection( (Vector3::UNIT_SCALE * -1.0f).normalisedCopy() ); - light->setSpecularColour( 0.2, 0.12, 0.11 ); - light->setAttenuation( 3500, 0.005, 0.00002, 0.00001 ); - light->setSpotlightRange( Degree(80), Degree(90) ); - light->setCastShadows( true ); - light->setLightMask( 0x00000000 ); + mSceneMgr->setAmbientLight( ColourValue( 0.40f, 0.40f, 0.40f ) ); + + ColourValue lightColour( 1, 0.5, 0.3 ); + + //Create main (point) light + Light* light = mSceneMgr->createLight(); + light->setDiffuseColour(lightColour); + light->setPosition( 0.0f, 25.0f, 0.0f ); + light->setSpecularColour( 0.6, 0.82, 1.0 ); + light->setAttenuation( 3500, 0.085, 0.00008, 0.00006 ); + light->setCastShadows( false ); + + //Create a dummy spot light for shadows + light = mSceneMgr->createLight(); + light->setType( Light::LT_SPOTLIGHT ); + light->setDiffuseColour( ColourValue( 0.15f, 0.35f, 0.44f ) ); + light->setPosition( 250.0f, 200.0f, 250.0f ); + light->setDirection( (Vector3::UNIT_SCALE * -1.0f).normalisedCopy() ); + light->setSpecularColour( 0.2, 0.12, 0.11 ); + light->setAttenuation( 3500, 0.005, 0.00002, 0.00001 ); + light->setSpotlightRange( Degree(80), Degree(90) ); + light->setCastShadows( true ); + light->setLightMask( 0x00000000 ); } //------------------------------------------------------------------------------ void Sample_NewInstancing::switchInstancingTechnique() { - randGenerator.randomize(); - //mInstancingTechnique = (mInstancingTechnique+1) % (NUM_TECHNIQUES+1); - mInstancingTechnique = mTechniqueMenu->getSelectionIndex(); - - if( mCurrentManager ) - mSceneMgr->destroyInstanceManager(mCurrentManager); - - if( !mSupportedTechniques[mInstancingTechnique] ) - { - //Hide GUI features available only to instancing - mCurrentManager = 0; - mDefragmentBatches->hide(); - mDefragmentOptimumCull->hide(); - return; - } - - if( mInstancingTechnique < NUM_TECHNIQUES ) - { - //Instancing - - //Create the manager if we haven't already (i.e. first time) - //Because we use IM_USEALL as flags, the actual num of instances per batch might be much lower - //If you're not bandwidth limited, you may want to lift IM_VTFBESTFIT flag away - - InstanceManager::InstancingTechnique technique = InstanceManager::ShaderBased; - - switch( mInstancingTechnique ) - { - case 0: technique = InstanceManager::ShaderBased; break; - case 1: technique = InstanceManager::TextureVTF; break; - case 2: technique = InstanceManager::HWInstancingBasic; break; - case 3: - case 4: technique = InstanceManager::HWInstancingVTF; break; - } - - uint16 flags = IM_USEALL; - flags |= mCurrentFlags; - - if (mInstancingTechnique == 4) - { - flags |= IM_VTFBONEMATRIXLOOKUP; - } - //Only one weight is recommended for the VTF technique, but force the use of more for the demo - if(mInstancingTechnique == 1 && (flags & IM_USEBONEDUALQUATERNIONS)) - { - flags &= ~IM_USEONEWEIGHT; - } - - mCurrentManager = mSceneMgr->createInstanceManager( - "InstanceMgr" + StringConverter::toString(mInstancingTechnique), c_meshNames[mCurrentMesh], - ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, technique, - NUM_INST_ROW * NUM_INST_COLUMN, flags); - - createInstancedEntities(); - - //Show GUI features available only to instancing - mDefragmentBatches->show(); - mDefragmentOptimumCull->show(); - } - else - { - //Non-instancing - createEntities(); - - //Hide GUI features available only to instancing - mCurrentManager = 0; - mDefragmentBatches->hide(); - mDefragmentOptimumCull->hide(); - } - - createSceneNodes(); - - //Show/hide "static" button, and restore config. Do this _after_ createSceneNodes() - if( mInstancingTechnique == InstanceManager::HWInstancingBasic || - mInstancingTechnique == InstanceManager::HWInstancingVTF || - mInstancingTechnique == InstanceManager::HWInstancingVTF + 1) // instancing with lookup - { - if( mSetStatic->isChecked() ) - mCurrentManager->setBatchesAsStaticAndUpdate( mSetStatic->isChecked() ); - mSetStatic->show(); - } - else - mSetStatic->hide(); - if( mInstancingTechnique < NUM_TECHNIQUES) - { - mUseSceneNodes->show(); - } - else - { - mUseSceneNodes->hide(); - } + randGenerator.randomize(); + //mInstancingTechnique = (mInstancingTechnique+1) % (NUM_TECHNIQUES+1); + mInstancingTechnique = mTechniqueMenu->getSelectionIndex(); + + if( mCurrentManager ) + mSceneMgr->destroyInstanceManager(mCurrentManager); + + if( !mSupportedTechniques[mInstancingTechnique] ) + { + //Hide GUI features available only to instancing + mCurrentManager = 0; + mDefragmentBatches->hide(); + mDefragmentOptimumCull->hide(); + return; + } + + if( mInstancingTechnique < NUM_TECHNIQUES ) + { + //Instancing + + //Create the manager if we haven't already (i.e. first time) + //Because we use IM_USEALL as flags, the actual num of instances per batch might be much lower + //If you're not bandwidth limited, you may want to lift IM_VTFBESTFIT flag away + + InstanceManager::InstancingTechnique technique = InstanceManager::ShaderBased; + + switch( mInstancingTechnique ) + { + case 0: technique = InstanceManager::ShaderBased; break; + case 1: technique = InstanceManager::TextureVTF; break; + case 2: technique = InstanceManager::HWInstancingBasic; break; + case 3: + case 4: technique = InstanceManager::HWInstancingVTF; break; + } + + uint16 flags = IM_USEALL; + flags |= mCurrentFlags; + + if (mInstancingTechnique == 4) + { + flags |= IM_VTFBONEMATRIXLOOKUP; + } + //Only one weight is recommended for the VTF technique, but force the use of more for the demo + if(mInstancingTechnique == 1 && (flags & IM_USEBONEDUALQUATERNIONS)) + { + flags &= ~IM_USEONEWEIGHT; + } + + mCurrentManager = mSceneMgr->createInstanceManager( + "InstanceMgr" + StringConverter::toString(mInstancingTechnique), c_meshNames[mCurrentMesh], + ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, technique, + NUM_INST_ROW * NUM_INST_COLUMN, flags); + + createInstancedEntities(); + + //Show GUI features available only to instancing + mDefragmentBatches->show(); + mDefragmentOptimumCull->show(); + } + else + { + //Non-instancing + createEntities(); + + //Hide GUI features available only to instancing + mCurrentManager = 0; + mDefragmentBatches->hide(); + mDefragmentOptimumCull->hide(); + } + + createSceneNodes(); + + //Show/hide "static" button, and restore config. Do this _after_ createSceneNodes() + if( mInstancingTechnique == InstanceManager::HWInstancingBasic || + mInstancingTechnique == InstanceManager::HWInstancingVTF || + mInstancingTechnique == InstanceManager::HWInstancingVTF + 1) // instancing with lookup + { + if( mSetStatic->isChecked() ) + mCurrentManager->setBatchesAsStaticAndUpdate( mSetStatic->isChecked() ); + mSetStatic->show(); + } + else + mSetStatic->hide(); + if( mInstancingTechnique < NUM_TECHNIQUES) + { + mUseSceneNodes->show(); + } + else + { + mUseSceneNodes->hide(); + } } //------------------------------------------------------------------------------ void Sample_NewInstancing::switchSkinningTechnique(int index) { - switch(index) - { - default: - //Linear Skinning - case 0: - mCurrentMesh = 0; - mCurrentMaterialSet = c_materialsTechniques; - mCurrentFlags = 0; - break; - //Dual Quaternion Skinning - case 1: - mCurrentMesh = 0; - mCurrentMaterialSet = c_materialsTechniques_dq; - mCurrentFlags = IM_USEBONEDUALQUATERNIONS; - break; - //Dual Quaternion Skinning with two weights - case 2: - mCurrentMesh = 1; - mCurrentMaterialSet = c_materialsTechniques_dq_two_weights; - mCurrentFlags = IM_USEBONEDUALQUATERNIONS; - break; - }; + switch(index) + { + default: + //Linear Skinning + case 0: + mCurrentMesh = 0; + mCurrentMaterialSet = c_materialsTechniques; + mCurrentFlags = 0; + break; + //Dual Quaternion Skinning + case 1: + mCurrentMesh = 0; + mCurrentMaterialSet = c_materialsTechniques_dq; + mCurrentFlags = IM_USEBONEDUALQUATERNIONS; + break; + //Dual Quaternion Skinning with two weights + case 2: + mCurrentMesh = 1; + mCurrentMaterialSet = c_materialsTechniques_dq_two_weights; + mCurrentFlags = IM_USEBONEDUALQUATERNIONS; + break; + }; } //------------------------------------------------------------------------------ void Sample_NewInstancing::createEntities() { - for( int i=0; icreateEntity( c_meshNames[mCurrentMesh] ); - ent->setMaterialName( mCurrentMaterialSet[NUM_TECHNIQUES] ); - mEntities.push_back( ent ); - - //Get the animation - AnimationState *anim = ent->getAnimationState( "Walk" ); - if (mAnimations.insert( anim ).second) - { - anim->setEnabled( true ); - anim->addTime( randGenerator.nextFloat() * 10 ); //Random start offset - } - } + for( int i=0; icreateEntity( c_meshNames[mCurrentMesh] ); + ent->setMaterialName( mCurrentMaterialSet[NUM_TECHNIQUES] ); + mEntities.push_back( ent ); + + //Get the animation + AnimationState *anim = ent->getAnimationState( "Walk" ); + if (mAnimations.insert( anim ).second) + { + anim->setEnabled( true ); + anim->addTime( randGenerator.nextFloat() * 10 ); //Random start offset + } + } } //------------------------------------------------------------------------------ void Sample_NewInstancing::createInstancedEntities() { - for( int i=0; icreateInstancedEntity(mCurrentMaterialSet[mInstancingTechnique] ); - mEntities.push_back( ent ); - - //HWInstancingBasic is the only technique without animation support - if( mInstancingTechnique != InstanceManager::HWInstancingBasic) - { - //Get the animation - AnimationState *anim = ent->getAnimationState( "Walk" ); - anim->setEnabled( true ); - anim->addTime( randGenerator.nextFloat() * 10); //Random start offset - mAnimations.insert( anim ); - } - - if ((mInstancingTechnique < NUM_TECHNIQUES) && (!mUseSceneNodes->isChecked())) - { - mMovedInstances.push_back( ent ); - ent->setOrientation(Quaternion(Radian(randGenerator.nextFloat() * 10 * 3.14159265359f), Vector3::UNIT_Y)); - ent->setPosition( Ogre::Vector3(mEntities[0]->getBoundingRadius() * (i - NUM_INST_ROW * 0.5f), 0, - mEntities[0]->getBoundingRadius() * (j - NUM_INST_COLUMN * 0.5f)) ); - } - } - } + for( int i=0; icreateInstancedEntity(mCurrentMaterialSet[mInstancingTechnique] ); + mEntities.push_back( ent ); + + //HWInstancingBasic is the only technique without animation support + if( mInstancingTechnique != InstanceManager::HWInstancingBasic) + { + //Get the animation + AnimationState *anim = ent->getAnimationState( "Walk" ); + anim->setEnabled( true ); + anim->addTime( randGenerator.nextFloat() * 10); //Random start offset + mAnimations.insert( anim ); + } + + if ((mInstancingTechnique < NUM_TECHNIQUES) && (!mUseSceneNodes->isChecked())) + { + mMovedInstances.push_back( ent ); + ent->setOrientation(Quaternion(Radian(randGenerator.nextFloat() * 10 * 3.14159265359f), Vector3::UNIT_Y)); + ent->setPosition( Ogre::Vector3(mEntities[0]->getBoundingRadius() * (i - NUM_INST_ROW * 0.5f), 0, + mEntities[0]->getBoundingRadius() * (j - NUM_INST_COLUMN * 0.5f)) ); + } + } + } } //------------------------------------------------------------------------------ void Sample_NewInstancing::createSceneNodes() { - //Here the SceneNodes are created. Since InstancedEntities derive from MovableObject, - //they behave like regular Entities on this. - SceneNode *rootNode = mSceneMgr->getRootSceneNode(); - - for( int i=0; i= NUM_TECHNIQUES) || (mUseSceneNodes->isChecked())) - { - SceneNode *sceneNode = rootNode->createChildSceneNode(); - sceneNode->attachObject( mEntities[idx] ); - sceneNode->yaw( Radian( randGenerator.nextFloat() * 10 * 3.14159265359f )); //Random orientation - sceneNode->setPosition( mEntities[idx]->getBoundingRadius() * (i - NUM_INST_ROW * 0.5f), 0, - mEntities[idx]->getBoundingRadius() * (j - NUM_INST_COLUMN * 0.5f) ); - mSceneNodes.push_back( sceneNode ); - } - - } - } + //Here the SceneNodes are created. Since InstancedEntities derive from MovableObject, + //they behave like regular Entities on this. + SceneNode *rootNode = mSceneMgr->getRootSceneNode(); + + for( int i=0; i= NUM_TECHNIQUES) || (mUseSceneNodes->isChecked())) + { + SceneNode *sceneNode = rootNode->createChildSceneNode(); + sceneNode->attachObject( mEntities[idx] ); + sceneNode->yaw( Radian( randGenerator.nextFloat() * 10 * 3.14159265359f )); //Random orientation + sceneNode->setPosition( mEntities[idx]->getBoundingRadius() * (i - NUM_INST_ROW * 0.5f), 0, + mEntities[idx]->getBoundingRadius() * (j - NUM_INST_COLUMN * 0.5f) ); + mSceneNodes.push_back( sceneNode ); + } + + } + } } //------------------------------------------------------------------------------ void Sample_NewInstancing::clearScene() { - std::vector::const_iterator itor = mEntities.begin(); - std::vector::const_iterator end = mEntities.end(); - - //Note: Destroying the instance manager automatically destroys all instanced entities - //created by this manager (beware of not leaving reference to those pointers) - while( itor != end ) - { - SceneNode *sceneNode = (*itor)->getParentSceneNode(); - if (sceneNode) - { - sceneNode->detachAllObjects(); - sceneNode->getParentSceneNode()->removeAndDestroyChild( sceneNode->getName() ); - } - if( mInstancingTechnique == NUM_TECHNIQUES ) - mSceneMgr->destroyEntity( (*itor)->getName() ); - else - mSceneMgr->destroyInstancedEntity( static_cast(*itor) ); - - ++itor; - } - - //Free some memory, but don't destroy the manager so when we switch this technique - //back again it doesn't take too long - if( mCurrentManager ) - mCurrentManager->cleanupEmptyBatches(); - - mEntities.clear(); - mMovedInstances.clear(); - mSceneNodes.clear(); - mAnimations.clear(); + std::vector::const_iterator itor = mEntities.begin(); + std::vector::const_iterator end = mEntities.end(); + + //Note: Destroying the instance manager automatically destroys all instanced entities + //created by this manager (beware of not leaving reference to those pointers) + while( itor != end ) + { + SceneNode *sceneNode = (*itor)->getParentSceneNode(); + if (sceneNode) + { + sceneNode->detachAllObjects(); + sceneNode->getParentSceneNode()->removeAndDestroyChild( sceneNode->getName() ); + } + if( mInstancingTechnique == NUM_TECHNIQUES ) + mSceneMgr->destroyEntity( (*itor)->getName() ); + else + mSceneMgr->destroyInstancedEntity( static_cast(*itor) ); + + ++itor; + } + + //Free some memory, but don't destroy the manager so when we switch this technique + //back again it doesn't take too long + if( mCurrentManager ) + mCurrentManager->cleanupEmptyBatches(); + + mEntities.clear(); + mMovedInstances.clear(); + mSceneNodes.clear(); + mAnimations.clear(); } //----------------------------------------------------------------------------------- void Sample_NewInstancing::destroyManagers() { - mSceneMgr->destroyInstanceManager(mCurrentManager);; + mSceneMgr->destroyInstanceManager(mCurrentManager);; } //------------------------------------------------------------------------------ void Sample_NewInstancing::cleanupContent() { MeshManager::getSingleton().remove("ground"); - clearScene(); - destroyManagers(); + clearScene(); + destroyManagers(); } //------------------------------------------------------------------------------ void Sample_NewInstancing::animateUnits( float timeSinceLast ) { - //Iterates through all AnimationSets and updates the animation being played. Demonstrates the - //animation is unique and independent to each instance - std::set::const_iterator itor = mAnimations.begin(); - std::set::const_iterator end = mAnimations.end(); - - while( itor != end ) - { - (*itor)->addTime( timeSinceLast ); - ++itor; - } + //Iterates through all AnimationSets and updates the animation being played. Demonstrates the + //animation is unique and independent to each instance + std::set::const_iterator itor = mAnimations.begin(); + std::set::const_iterator end = mAnimations.end(); + + while( itor != end ) + { + (*itor)->addTime( timeSinceLast ); + ++itor; + } } //------------------------------------------------------------------------------ void Sample_NewInstancing::moveUnits( float timeSinceLast ) { - Real fMovSpeed = 1.0f; - - if( !mEntities.empty() ) - fMovSpeed = mEntities[0]->getBoundingRadius() * 0.30f; - - if (!mSceneNodes.empty()) - { - //Randomly move the units along their normal, bouncing around invisible walls - std::vector::const_iterator itor = mSceneNodes.begin(); - std::vector::const_iterator end = mSceneNodes.end(); - - while( itor != end ) - { - //Calculate bounces - Vector3 entityPos = (*itor)->getPosition(); - Vector3 planeNormal = Vector3::ZERO; - if( (*itor)->getPosition().x < -5000.0f ) - { - planeNormal = Vector3::UNIT_X; - entityPos.x = -4999.0f; - } - else if( (*itor)->getPosition().x > 5000.0f ) - { - planeNormal = Vector3::NEGATIVE_UNIT_X; - entityPos.x = 4999.0f; - } - else if( (*itor)->getPosition().z < -5000.0f ) - { - planeNormal = Vector3::UNIT_Z; - entityPos.z = -4999.0f; - } - else if( (*itor)->getPosition().z > 5000.0f ) - { - planeNormal = Vector3::NEGATIVE_UNIT_Z; - entityPos.z = 4999.0f; - } - - if( planeNormal != Vector3::ZERO ) - { - const Vector3 vDir( (*itor)->getOrientation().xAxis().normalisedCopy() ); - (*itor)->setOrientation( lookAt( planeNormal.reflect( vDir ).normalisedCopy() ) ); - (*itor)->setPosition( entityPos ); - } - - //Move along the direction we're looking to - (*itor)->translate( Vector3::UNIT_X * timeSinceLast * fMovSpeed, Node::TS_LOCAL ); - ++itor; - } - } - else - { - //No scene nodes (instanced entities only) - //Update instanced entities directly - - //Randomly move the units along their normal, bouncing around invisible walls - std::vector::const_iterator itor = mMovedInstances.begin(); - std::vector::const_iterator end = mMovedInstances.end(); - - while( itor != end ) - { - //Calculate bounces - InstancedEntity* pEnt = *itor; - Vector3 entityPos = pEnt->getPosition(); - Vector3 planeNormal = Vector3::ZERO; - if( pEnt->getPosition().x < -5000.0f ) - { - planeNormal = Vector3::UNIT_X; - entityPos.x = -4999.0f; - } - else if( pEnt->getPosition().x > 5000.0f ) - { - planeNormal = Vector3::NEGATIVE_UNIT_X; - entityPos.x = 4999.0f; - } - else if( pEnt->getPosition().z < -5000.0f ) - { - planeNormal = Vector3::UNIT_Z; - entityPos.z = -4999.0f; - } - else if( pEnt->getPosition().z > 5000.0f ) - { - planeNormal = Vector3::NEGATIVE_UNIT_Z; - entityPos.z = 4999.0f; - } - - if( planeNormal != Vector3::ZERO ) - { - const Vector3 vDir(pEnt->getOrientation().xAxis().normalisedCopy() ); - pEnt->setOrientation( lookAt( planeNormal.reflect( vDir ).normalisedCopy() ), false ); - pEnt->setPosition( entityPos, false); - } - - //Move along the direction we're looking to - Vector3 transAmount = Vector3::UNIT_X * timeSinceLast * fMovSpeed; - pEnt->setPosition( pEnt->getPosition() + pEnt->getOrientation() * transAmount ); - ++itor; - } - } + Real fMovSpeed = 1.0f; + + if( !mEntities.empty() ) + fMovSpeed = mEntities[0]->getBoundingRadius() * 0.30f; + + if (!mSceneNodes.empty()) + { + //Randomly move the units along their normal, bouncing around invisible walls + std::vector::const_iterator itor = mSceneNodes.begin(); + std::vector::const_iterator end = mSceneNodes.end(); + + while( itor != end ) + { + //Calculate bounces + Vector3 entityPos = (*itor)->getPosition(); + Vector3 planeNormal = Vector3::ZERO; + if( (*itor)->getPosition().x < -5000.0f ) + { + planeNormal = Vector3::UNIT_X; + entityPos.x = -4999.0f; + } + else if( (*itor)->getPosition().x > 5000.0f ) + { + planeNormal = Vector3::NEGATIVE_UNIT_X; + entityPos.x = 4999.0f; + } + else if( (*itor)->getPosition().z < -5000.0f ) + { + planeNormal = Vector3::UNIT_Z; + entityPos.z = -4999.0f; + } + else if( (*itor)->getPosition().z > 5000.0f ) + { + planeNormal = Vector3::NEGATIVE_UNIT_Z; + entityPos.z = 4999.0f; + } + + if( planeNormal != Vector3::ZERO ) + { + const Vector3 vDir( (*itor)->getOrientation().xAxis().normalisedCopy() ); + (*itor)->setOrientation( lookAt( planeNormal.reflect( vDir ).normalisedCopy() ) ); + (*itor)->setPosition( entityPos ); + } + + //Move along the direction we're looking to + (*itor)->translate( Vector3::UNIT_X * timeSinceLast * fMovSpeed, Node::TS_LOCAL ); + ++itor; + } + } + else + { + //No scene nodes (instanced entities only) + //Update instanced entities directly + + //Randomly move the units along their normal, bouncing around invisible walls + std::vector::const_iterator itor = mMovedInstances.begin(); + std::vector::const_iterator end = mMovedInstances.end(); + + while( itor != end ) + { + //Calculate bounces + InstancedEntity* pEnt = *itor; + Vector3 entityPos = pEnt->getPosition(); + Vector3 planeNormal = Vector3::ZERO; + if( pEnt->getPosition().x < -5000.0f ) + { + planeNormal = Vector3::UNIT_X; + entityPos.x = -4999.0f; + } + else if( pEnt->getPosition().x > 5000.0f ) + { + planeNormal = Vector3::NEGATIVE_UNIT_X; + entityPos.x = 4999.0f; + } + else if( pEnt->getPosition().z < -5000.0f ) + { + planeNormal = Vector3::UNIT_Z; + entityPos.z = -4999.0f; + } + else if( pEnt->getPosition().z > 5000.0f ) + { + planeNormal = Vector3::NEGATIVE_UNIT_Z; + entityPos.z = 4999.0f; + } + + if( planeNormal != Vector3::ZERO ) + { + const Vector3 vDir(pEnt->getOrientation().xAxis().normalisedCopy() ); + pEnt->setOrientation( lookAt( planeNormal.reflect( vDir ).normalisedCopy() ), false ); + pEnt->setPosition( entityPos, false); + } + + //Move along the direction we're looking to + Vector3 transAmount = Vector3::UNIT_X * timeSinceLast * fMovSpeed; + pEnt->setPosition( pEnt->getPosition() + pEnt->getOrientation() * transAmount ); + ++itor; + } + } } //------------------------------------------------------------------------------ Quaternion Sample_NewInstancing::lookAt( const Vector3 &normDir ) { - Quaternion retVal; - Vector3 xVec = Vector3::UNIT_Y.crossProduct( normDir ); - xVec.normalise(); + Quaternion retVal; + Vector3 xVec = Vector3::UNIT_Y.crossProduct( normDir ); + xVec.normalise(); - Vector3 yVec = normDir.crossProduct( xVec ); - yVec.normalise(); + Vector3 yVec = normDir.crossProduct( xVec ); + yVec.normalise(); - retVal.FromAxes( xVec, yVec, normDir ); + retVal.FromAxes( xVec, yVec, normDir ); - return retVal; + return retVal; } //------------------------------------------------------------------------------ void Sample_NewInstancing::defragmentBatches() { - //Defragment batches is used after many InstancedEntities were removed (and you won't - //be requesting more). However, then the optimize cull option is on, it can cause - //quite a perf. boost on large batches (i.e. VTF) even if not a single instance was ever removed. - if( mCurrentManager ) - mCurrentManager->defragmentBatches( mDefragmentOptimumCull->isChecked() ); + //Defragment batches is used after many InstancedEntities were removed (and you won't + //be requesting more). However, then the optimize cull option is on, it can cause + //quite a perf. boost on large batches (i.e. VTF) even if not a single instance was ever removed. + if( mCurrentManager ) + mCurrentManager->defragmentBatches( mDefragmentOptimumCull->isChecked() ); } //------------------------------------------------------------------------------ void Sample_NewInstancing::setupGUI() { - mTechniqueMenu = mTrayMgr->createLongSelectMenu( - TL_TOPLEFT, "TechniqueSelectMenu", "Technique", 450, 350, 5); - for( int i=0; iaddItem( text ); - } - //Check box to enable dual quaternion skinning - mSkinningTechniques = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "SkinningTechnique", "Skinning Technique", 450, 285, 5); - mSkinningTechniques->addItem("Linear Skinning"); - mSkinningTechniques->addItem("Dual Quaternion Skinning"); - mSkinningTechniques->addItem("Dual Quaternion Skinning (2 wgts)"); - - //Check box to move the units - mMoveInstances = mTrayMgr->createCheckBox(TL_TOPRIGHT, "MoveInstances", "Move Instances", 175); - mMoveInstances->setChecked(false); - - //Check box to animate the units - mAnimateInstances = mTrayMgr->createCheckBox(TL_TOPRIGHT, "AnimateInstances", - "Animate Instances", 175); - mAnimateInstances->setChecked(false); - - //Checkbox to toggle shadows - mEnableShadows = mTrayMgr->createCheckBox(TL_TOPRIGHT, "EnableShadows", - "Enable Shadows", 175); - mEnableShadows->setChecked(true); - - //Check box to make instances static (where supported) - mSetStatic = mTrayMgr->createCheckBox(TL_TOPRIGHT, "SetStatic", "Set Static", 175); - mSetStatic->setChecked(false); - - //Checkbox to toggle use of scene nodes - mUseSceneNodes = mTrayMgr->createCheckBox(TL_TOPRIGHT, "UseSceneNodes", - "Use Scene Nodes", 175); - mUseSceneNodes->setChecked(true, false); - - //Controls to control batch defragmentation on the fly - mDefragmentBatches = mTrayMgr->createButton(TL_RIGHT, "DefragmentBatches", - "Defragment Batches", 175); - mDefragmentOptimumCull = mTrayMgr->createCheckBox(TL_RIGHT, "DefragmentOptimumCull", - "Optimum Cull", 175); - mDefragmentOptimumCull->setChecked(true); - - //Slider to control max number of instances - mInstancesSlider = mTrayMgr->createThickSlider( TL_TOPLEFT, "InstancesSlider", "Instances (NxN)", - 300, 50, 4, 100, 97 ); - mInstancesSlider->setValue( NUM_INST_ROW ); - - mTrayMgr->showCursor(); + mTechniqueMenu = mTrayMgr->createLongSelectMenu( + TL_TOPLEFT, "TechniqueSelectMenu", "Technique", 450, 350, 5); + for( int i=0; iaddItem( text ); + } + //Check box to enable dual quaternion skinning + mSkinningTechniques = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "SkinningTechnique", "Skinning Technique", 450, 285, 5); + mSkinningTechniques->addItem("Linear Skinning"); + mSkinningTechniques->addItem("Dual Quaternion Skinning"); + mSkinningTechniques->addItem("Dual Quaternion Skinning (2 wgts)"); + + //Check box to move the units + mMoveInstances = mTrayMgr->createCheckBox(TL_TOPRIGHT, "MoveInstances", "Move Instances", 175); + mMoveInstances->setChecked(false); + + //Check box to animate the units + mAnimateInstances = mTrayMgr->createCheckBox(TL_TOPRIGHT, "AnimateInstances", + "Animate Instances", 175); + mAnimateInstances->setChecked(false); + + //Checkbox to toggle shadows + mEnableShadows = mTrayMgr->createCheckBox(TL_TOPRIGHT, "EnableShadows", + "Enable Shadows", 175); + mEnableShadows->setChecked(true); + + //Check box to make instances static (where supported) + mSetStatic = mTrayMgr->createCheckBox(TL_TOPRIGHT, "SetStatic", "Set Static", 175); + mSetStatic->setChecked(false); + + //Checkbox to toggle use of scene nodes + mUseSceneNodes = mTrayMgr->createCheckBox(TL_TOPRIGHT, "UseSceneNodes", + "Use Scene Nodes", 175); + mUseSceneNodes->setChecked(true, false); + + //Controls to control batch defragmentation on the fly + mDefragmentBatches = mTrayMgr->createButton(TL_RIGHT, "DefragmentBatches", + "Defragment Batches", 175); + mDefragmentOptimumCull = mTrayMgr->createCheckBox(TL_RIGHT, "DefragmentOptimumCull", + "Optimum Cull", 175); + mDefragmentOptimumCull->setChecked(true); + + //Slider to control max number of instances + mInstancesSlider = mTrayMgr->createThickSlider( TL_TOPLEFT, "InstancesSlider", "Instances (NxN)", + 300, 50, 4, 100, 97 ); + mInstancesSlider->setValue( NUM_INST_ROW ); + + mTrayMgr->showCursor(); } //------------------------------------------------------------------------------ void Sample_NewInstancing::itemSelected( SelectMenu* menu ) { - if (menu == mTechniqueMenu) - { - clearScene(); - switchInstancingTechnique(); - } - else if(menu == mSkinningTechniques) - { - clearScene(); - switchSkinningTechnique(menu->getSelectionIndex()); - switchInstancingTechnique(); - } + if (menu == mTechniqueMenu) + { + clearScene(); + switchInstancingTechnique(); + } + else if(menu == mSkinningTechniques) + { + clearScene(); + switchSkinningTechnique(menu->getSelectionIndex()); + switchInstancingTechnique(); + } } //------------------------------------------------------------------------------ void Sample_NewInstancing::buttonHit( OgreBites::Button* button ) { - if( button == mDefragmentBatches ) defragmentBatches(); + if( button == mDefragmentBatches ) defragmentBatches(); } //------------------------------------------------------------------------------ void Sample_NewInstancing::checkBoxToggled( CheckBox* box ) { - if( box == mEnableShadows ) - { - mSceneMgr->setShadowTechnique( mEnableShadows->isChecked() ? - SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED : SHADOWTYPE_NONE ); - } - else if( box == mSetStatic && mCurrentManager ) - { - mCurrentManager->setBatchesAsStaticAndUpdate( mSetStatic->isChecked() ); - } - else if (box == mUseSceneNodes) - { - clearScene(); - switchInstancingTechnique(); - } + if( box == mEnableShadows ) + { + mSceneMgr->setShadowTechnique( mEnableShadows->isChecked() ? + SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED : SHADOWTYPE_NONE ); + } + else if( box == mSetStatic && mCurrentManager ) + { + mCurrentManager->setBatchesAsStaticAndUpdate( mSetStatic->isChecked() ); + } + else if (box == mUseSceneNodes) + { + clearScene(); + switchInstancingTechnique(); + } } //------------------------------------------------------------------------------ void Sample_NewInstancing::sliderMoved( Slider* slider ) { - if( slider == mInstancesSlider ) NUM_INST_ROW = static_cast(mInstancesSlider->getValue()); - NUM_INST_COLUMN = static_cast(mInstancesSlider->getValue()); + if( slider == mInstancesSlider ) NUM_INST_ROW = static_cast(mInstancesSlider->getValue()); + NUM_INST_COLUMN = static_cast(mInstancesSlider->getValue()); } //------------------------------------------------------------------------------ void Sample_NewInstancing::testCapabilities( const RenderSystemCapabilities* caps ) { - if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and " - "fragment programs, so you cannot run this sample. Sorry!", - "NewInstancing::testCapabilities"); - } - - if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsl") && + if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and " + "fragment programs, so you cannot run this sample. Sorry!", + "NewInstancing::testCapabilities"); + } + + if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsl") && #if OGRE_NO_GLES3_SUPPORT == 0 - !GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && + !GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && #endif - !GpuProgramManager::getSingleton().isSyntaxSupported("fp40") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_1") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_5_0")) - { + !GpuProgramManager::getSingleton().isSyntaxSupported("fp40") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_1") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_5_0")) + { OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model needed for this sample, " "so you cannot run this sample. Sorry!", "NewInstancing::testCapabilities"); - } + } } //------------------------------------------------------------------------------ void Sample_NewInstancing::checkHardwareSupport() { - //Check Technique support - for( int i=0; igetNumInstancesPerBatch( c_meshNames[mCurrentMesh], - ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, - mCurrentMaterialSet[i], technique, NUM_INST_ROW * NUM_INST_COLUMN, flags ); - - mSupportedTechniques[i] = numInstances > 0; - } - - //Non instancing is always supported - mSupportedTechniques[NUM_TECHNIQUES] = true; + //Check Technique support + for( int i=0; igetNumInstancesPerBatch( c_meshNames[mCurrentMesh], + ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, + mCurrentMaterialSet[i], technique, NUM_INST_ROW * NUM_INST_COLUMN, flags ); + + mSupportedTechniques[i] = numInstances > 0; + } + + //Non instancing is always supported + mSupportedTechniques[NUM_TECHNIQUES] = true; } diff --git a/Samples/OceanDemo/include/MaterialControls.h b/Samples/OceanDemo/include/MaterialControls.h index e5c45bcd591..a29cf77436b 100644 --- a/Samples/OceanDemo/include/MaterialControls.h +++ b/Samples/OceanDemo/include/MaterialControls.h @@ -19,23 +19,23 @@ same license as the rest of the engine. enum ShaderValType { - GPU_VERTEX, GPU_FRAGMENT, MAT_SPECULAR, MAT_DIFFUSE, MAT_AMBIENT, MAT_SHININESS, MAT_EMISSIVE + GPU_VERTEX, GPU_FRAGMENT, MAT_SPECULAR, MAT_DIFFUSE, MAT_AMBIENT, MAT_SHININESS, MAT_EMISSIVE }; //--------------------------------------------------------------------------- struct ShaderControl { Ogre::String Name; - Ogre::String ParamName; - ShaderValType ValType; - float MinVal; - float MaxVal; - size_t ElementIndex; - mutable size_t PhysicalIndex; - - float getRange(void) const { return MaxVal - MinVal; } - float convertParamToScrollPosition(const float val) const { return val - MinVal; } - float convertScrollPositionToParam(const float val) const { return val + MinVal; } + Ogre::String ParamName; + ShaderValType ValType; + float MinVal; + float MaxVal; + size_t ElementIndex; + mutable size_t PhysicalIndex; + + float getRange(void) const { return MaxVal - MinVal; } + float convertParamToScrollPosition(const float val) const { return val - MinVal; } + float convertScrollPositionToParam(const float val) const { return val + MinVal; } }; typedef Ogre::vector::type ShaderControlsContainer; diff --git a/Samples/OceanDemo/include/OceanDemo.h b/Samples/OceanDemo/include/OceanDemo.h index e88c1423945..6bc33d5eae7 100644 --- a/Samples/OceanDemo/include/OceanDemo.h +++ b/Samples/OceanDemo/include/OceanDemo.h @@ -30,56 +30,56 @@ using namespace OgreBites; #define CONTROLS_PER_PAGE 5 enum OceanMaterial { - OCEAN1_CG, - OCEAN1_NATIVE, - OCEAN2_CG, - OCEAN2_NATIVE + OCEAN1_CG, + OCEAN1_NATIVE, + OCEAN2_CG, + OCEAN2_NATIVE }; class _OgreSampleClassExport Sample_Ocean : public SdkSample { public: - Sample_Ocean(); + Sample_Ocean(); protected: - //Things from the frame listener - Ogre::Vector3 mTranslateVector; + //Things from the frame listener + Ogre::Vector3 mTranslateVector; int mSceneDetailIndex; float mUpdateFreq; - bool mSpinLight; + bool mSpinLight; // just to stop toggles flipping too fast Ogre::TextureFilterOptions mFiltering; int mAniso; - Ogre::SceneNode* mMainNode; - Ogre::Entity* mOceanSurfaceEnt; - - size_t mCurrentMaterial; - size_t mCurrentPage; - size_t mNumPages; - Ogre::MaterialPtr mActiveMaterial; - Ogre::Pass* mActivePass; - Ogre::GpuProgramPtr mActiveFragmentProgram; - Ogre::GpuProgramPtr mActiveVertexProgram; - Ogre::GpuProgramParametersSharedPtr mActiveFragmentParameters; - Ogre::GpuProgramParametersSharedPtr mActiveVertexParameters; - Real mRotateSpeed; - Slider* mShaderControls[CONTROLS_PER_PAGE]; - - ShaderControlsContainer mShaderControlContainer; + Ogre::SceneNode* mMainNode; + Ogre::Entity* mOceanSurfaceEnt; + + size_t mCurrentMaterial; + size_t mCurrentPage; + size_t mNumPages; + Ogre::MaterialPtr mActiveMaterial; + Ogre::Pass* mActivePass; + Ogre::GpuProgramPtr mActiveFragmentProgram; + Ogre::GpuProgramPtr mActiveVertexProgram; + Ogre::GpuProgramParametersSharedPtr mActiveFragmentParameters; + Ogre::GpuProgramParametersSharedPtr mActiveVertexParameters; + Real mRotateSpeed; + Slider* mShaderControls[CONTROLS_PER_PAGE]; + + ShaderControlsContainer mShaderControlContainer; MaterialControlsContainer mMaterialControlsContainer; - - void setupGUI(); - void setupScene(); - virtual void setupContent(); - virtual void cleanupContent(); - void sliderMoved(Slider* slider); - void buttonHit(OgreBites::Button* button); - void checkBoxToggled(CheckBox* box); - void selectOceanMaterial(OceanMaterial newMaterial); - void itemSelected(SelectMenu* menu); - void changePage(int nextPage = -1); - virtual bool frameRenderingQueued(const FrameEvent& evt); + void setupGUI(); + void setupScene(); + virtual void setupContent(); + virtual void cleanupContent(); + + void sliderMoved(Slider* slider); + void buttonHit(OgreBites::Button* button); + void checkBoxToggled(CheckBox* box); + void selectOceanMaterial(OceanMaterial newMaterial); + void itemSelected(SelectMenu* menu); + void changePage(int nextPage = -1); + virtual bool frameRenderingQueued(const FrameEvent& evt); }; /********************************************************************** @@ -96,7 +96,7 @@ Ogre::Billboard* mLightFlares[NUM_LIGHTS]; // Positions for lights Ogre::Vector3 mLightPositions[NUM_LIGHTS] = { - Ogre::Vector3(00, 400, 00) + Ogre::Vector3(00, 400, 00) }; // Base orientations of the lights Ogre::Real mLightRotationAngles[NUM_LIGHTS] = { 35 }; @@ -109,18 +109,18 @@ Ogre::Real mLightSpeeds[NUM_LIGHTS] = { 30}; // Colours for the lights Ogre::ColourValue mDiffuseLightColours[NUM_LIGHTS] = { - Ogre::ColourValue(0.6, 0.6, 0.6) + Ogre::ColourValue(0.6, 0.6, 0.6) }; Ogre::ColourValue mSpecularLightColours[NUM_LIGHTS] = { - Ogre::ColourValue(0.5, 0.5, 0.5) + Ogre::ColourValue(0.5, 0.5, 0.5) }; // Which lights are enabled bool mLightState[NUM_LIGHTS] = { - true + true }; // the light nodes @@ -131,19 +131,19 @@ Ogre::SceneNode* mLightPivots[NUM_LIGHTS]; Sample_Ocean::Sample_Ocean() { - mInfo["Title"] = "Ocean"; - mInfo["Description"] = "An example demonstrating ocean rendering using shaders."; - mInfo["Thumbnail"] = "thumb_ocean.png"; - mInfo["Category"] = "Environment"; + mInfo["Title"] = "Ocean"; + mInfo["Description"] = "An example demonstrating ocean rendering using shaders."; + mInfo["Thumbnail"] = "thumb_ocean.png"; + mInfo["Category"] = "Environment"; } /************************************************************************* - Sample_Ocean Methods + Sample_Ocean Methods *************************************************************************/ void Sample_Ocean::cleanupContent() { MeshManager::getSingleton().remove("OceanSurface"); - // get rid of the shared pointers before shutting down ogre or exceptions occur + // get rid of the shared pointers before shutting down ogre or exceptions occur mActiveFragmentProgram.setNull(); mActiveFragmentParameters.setNull(); mActiveVertexProgram.setNull(); @@ -154,36 +154,36 @@ void Sample_Ocean::cleanupContent() //-------------------------------------------------------------------------- void Sample_Ocean::setupGUI(void) { - SelectMenu* selectMenu = mTrayMgr->createLongSelectMenu( - TL_TOPLEFT, "MaterialSelectMenu", "Material", 300, 200, 5); - - for (size_t i=0; iaddItem(mMaterialControlsContainer[i].getDisplayName()); - } - - mTrayMgr->createCheckBox(TL_TOPLEFT, "SpinLightButton", "Spin Light", 175)->setChecked(true); - - mTrayMgr->createButton(TL_TOPRIGHT, "PageButtonControl", "Page", 175); - - for (size_t i=0; icreateThickSlider(TL_TOPRIGHT, - "ShaderControlSlider" + StringConverter::toString(i), "Control", 256, 80, 0, 1, 100); - } - - selectMenu->selectItem(0); - mTrayMgr->showCursor(); + SelectMenu* selectMenu = mTrayMgr->createLongSelectMenu( + TL_TOPLEFT, "MaterialSelectMenu", "Material", 300, 200, 5); + + for (size_t i=0; iaddItem(mMaterialControlsContainer[i].getDisplayName()); + } + + mTrayMgr->createCheckBox(TL_TOPLEFT, "SpinLightButton", "Spin Light", 175)->setChecked(true); + + mTrayMgr->createButton(TL_TOPRIGHT, "PageButtonControl", "Page", 175); + + for (size_t i=0; icreateThickSlider(TL_TOPRIGHT, + "ShaderControlSlider" + StringConverter::toString(i), "Control", 256, 80, 0, 1, 100); + } + + selectMenu->selectItem(0); + mTrayMgr->showCursor(); } //-------------------------------------------------------------------------- void Sample_Ocean::setupContent(void) { - loadAllMaterialControlFiles(mMaterialControlsContainer); - setupScene(); - setupGUI(); - - // Position it at 500 in Z direction + loadAllMaterialControlFiles(mMaterialControlsContainer); + setupScene(); + setupGUI(); + + // Position it at 500 in Z direction mCamera->setPosition(Ogre::Vector3(0,0,0)); // Look back along -Z mCamera->lookAt(Ogre::Vector3(0,0,-300)); @@ -196,9 +196,9 @@ void Sample_Ocean::setupContent(void) void Sample_Ocean::setupScene() { - // Set ambient light + // Set ambient light mSceneMgr->setAmbientLight(Ogre::ColourValue(0.3, 0.3, 0.3)); - mSceneMgr->setSkyBox(true, "SkyBox", 1000); + mSceneMgr->setSkyBox(true, "SkyBox", 1000); mMainNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); @@ -209,25 +209,25 @@ void Sample_Ocean::setupScene() mLightPivots[i]->rotate(mLightRotationAxes[i], Ogre::Angle(mLightRotationAngles[i])); // Create a light, use default parameters mLights[i] = mSceneMgr->createLight("Light" + Ogre::StringConverter::toString(i)); - mLights[i]->setPosition(mLightPositions[i]); - mLights[i]->setDiffuseColour(mDiffuseLightColours[i]); - mLights[i]->setSpecularColour(mSpecularLightColours[i]); - mLights[i]->setVisible(mLightState[i]); - //mLights[i]->setAttenuation(400, 0.1 , 1 , 0); + mLights[i]->setPosition(mLightPositions[i]); + mLights[i]->setDiffuseColour(mDiffuseLightColours[i]); + mLights[i]->setSpecularColour(mSpecularLightColours[i]); + mLights[i]->setVisible(mLightState[i]); + //mLights[i]->setAttenuation(400, 0.1 , 1 , 0); // Attach light mLightPivots[i]->attachObject(mLights[i]); - // Create billboard for light + // Create billboard for light mLightFlareSets[i] = mSceneMgr->createBillboardSet("Flare" + Ogre::StringConverter::toString(i)); - mLightFlareSets[i]->setMaterialName("LightFlare"); - mLightPivots[i]->attachObject(mLightFlareSets[i]); - mLightFlares[i] = mLightFlareSets[i]->createBillboard(mLightPositions[i]); - mLightFlares[i]->setColour(mDiffuseLightColours[i]); - mLightFlareSets[i]->setVisible(mLightState[i]); + mLightFlareSets[i]->setMaterialName("LightFlare"); + mLightPivots[i]->attachObject(mLightFlareSets[i]); + mLightFlares[i] = mLightFlareSets[i]->createBillboard(mLightPositions[i]); + mLightFlares[i]->setColour(mDiffuseLightColours[i]); + mLightFlareSets[i]->setVisible(mLightState[i]); } // move the camera a bit right and make it look at the knot - mCamera->moveRelative(Ogre::Vector3(50, 0, 100)); - mCamera->lookAt(0, 0, 0); + mCamera->moveRelative(Ogre::Vector3(50, 0, 100)); + mCamera->lookAt(0, 0, 0); // Define a plane mesh that will be used for the ocean surface Ogre::Plane oceanSurface; @@ -246,245 +246,245 @@ void Sample_Ocean::setupScene() //-------------------------------------------------------------------------- void Sample_Ocean::sliderMoved(Slider* slider) { - using namespace Ogre; - - int sliderIndex = -1; - for (int i=0; igetValue(); - - if(mActivePass) - { - switch(ActiveShaderDef.ValType) - { - case GPU_VERTEX: - case GPU_FRAGMENT: - { - GpuProgramParametersSharedPtr activeParameters = - (ActiveShaderDef.ValType == GPU_VERTEX) ? - mActiveVertexParameters : mActiveFragmentParameters; - - if(!activeParameters.isNull()) - { - activeParameters->_writeRawConstant( - ActiveShaderDef.PhysicalIndex + ActiveShaderDef.ElementIndex, val); - } - } - break; - - case MAT_SPECULAR: - { - // get the specular values from the material pass - ColourValue OldSpec(mActivePass->getSpecular()); - OldSpec[ActiveShaderDef.ElementIndex] = val; - mActivePass->setSpecular( OldSpec ); - } - - break; - - case MAT_DIFFUSE: - { - // get the specular values from the material pass - ColourValue OldSpec(mActivePass->getDiffuse()); - OldSpec[ActiveShaderDef.ElementIndex] = val; - mActivePass->setDiffuse( OldSpec ); - } - break; - - case MAT_AMBIENT: - { - // get the specular values from the material pass - ColourValue OldSpec(mActivePass->getAmbient()); - OldSpec[ActiveShaderDef.ElementIndex] = val; - mActivePass->setAmbient( OldSpec ); - } - break; - - case MAT_SHININESS: - // get the specular values from the material pass - mActivePass->setShininess( val ); - break; + float val = slider->getValue(); + + if(mActivePass) + { + switch(ActiveShaderDef.ValType) + { + case GPU_VERTEX: + case GPU_FRAGMENT: + { + GpuProgramParametersSharedPtr activeParameters = + (ActiveShaderDef.ValType == GPU_VERTEX) ? + mActiveVertexParameters : mActiveFragmentParameters; + + if(!activeParameters.isNull()) + { + activeParameters->_writeRawConstant( + ActiveShaderDef.PhysicalIndex + ActiveShaderDef.ElementIndex, val); + } + } + break; + + case MAT_SPECULAR: + { + // get the specular values from the material pass + ColourValue OldSpec(mActivePass->getSpecular()); + OldSpec[ActiveShaderDef.ElementIndex] = val; + mActivePass->setSpecular( OldSpec ); + } + + break; + + case MAT_DIFFUSE: + { + // get the specular values from the material pass + ColourValue OldSpec(mActivePass->getDiffuse()); + OldSpec[ActiveShaderDef.ElementIndex] = val; + mActivePass->setDiffuse( OldSpec ); + } + break; + + case MAT_AMBIENT: + { + // get the specular values from the material pass + ColourValue OldSpec(mActivePass->getAmbient()); + OldSpec[ActiveShaderDef.ElementIndex] = val; + mActivePass->setAmbient( OldSpec ); + } + break; + + case MAT_SHININESS: + // get the specular values from the material pass + mActivePass->setShininess( val ); + break; case MAT_EMISSIVE: break; - } - } + } + } } //-------------------------------------------------------------------------- void Sample_Ocean::changePage(int pageNum /* = -1 : toggle */) { - if (mMaterialControlsContainer.empty()) return; - mCurrentPage = (pageNum == -1) ? (mCurrentPage+1) % mNumPages : pageNum; + if (mMaterialControlsContainer.empty()) return; + mCurrentPage = (pageNum == -1) ? (mCurrentPage+1) % mNumPages : pageNum; - static char pageText[64]; - sprintf(pageText, "Parameters %lu / %d", mCurrentPage+1, (int)mNumPages); - static_cast(mTrayMgr->getWidget("PageButtonControl"))->setCaption(pageText); + static char pageText[64]; + sprintf(pageText, "Parameters %lu / %d", mCurrentPage+1, (int)mNumPages); + static_cast(mTrayMgr->getWidget("PageButtonControl"))->setCaption(pageText); if(!mActiveMaterial.isNull() && mActiveMaterial->getNumSupportedTechniques()) - { + { Ogre::Technique* currentTechnique = mActiveMaterial->getSupportedTechnique(0); - if(currentTechnique) - { - mActivePass = currentTechnique->getPass(0); - if(mActivePass) - { + if(currentTechnique) + { + mActivePass = currentTechnique->getPass(0); + if(mActivePass) + { if (mActivePass->hasFragmentProgram()) { - mActiveFragmentProgram = mActivePass->getFragmentProgram(); - mActiveFragmentParameters = mActivePass->getFragmentProgramParameters(); + mActiveFragmentProgram = mActivePass->getFragmentProgram(); + mActiveFragmentParameters = mActivePass->getFragmentProgramParameters(); } if (mActivePass->hasVertexProgram()) { - mActiveVertexProgram = mActivePass->getVertexProgram(); - mActiveVertexParameters = mActivePass->getVertexProgramParameters(); + mActiveVertexProgram = mActivePass->getVertexProgram(); + mActiveVertexParameters = mActivePass->getVertexProgramParameters(); } size_t activeControlCount = mMaterialControlsContainer[mCurrentMaterial].getShaderControlCount(); - - size_t startControlIndex = mCurrentPage * CONTROLS_PER_PAGE; - int numControls = static_cast(activeControlCount - startControlIndex); - if (numControls <= 0) - { - mCurrentPage = 0; - startControlIndex = 0; - numControls = (int)activeControlCount; - } - - for (size_t i=0; ishow(); - size_t controlIndex = startControlIndex + i; - const ShaderControl& ActiveShaderDef = mMaterialControlsContainer[mCurrentMaterial].getShaderControl(controlIndex); - shaderControlSlider->setRange(ActiveShaderDef.MinVal, ActiveShaderDef.MaxVal, 50, false); - shaderControlSlider->setCaption(ActiveShaderDef.Name); - - float uniformVal = 0.0; - switch(ActiveShaderDef.ValType) - { - case GPU_VERTEX: - case GPU_FRAGMENT: - { - Ogre::GpuProgramParametersSharedPtr activeParameters = - (ActiveShaderDef.ValType == GPU_VERTEX) ? - mActiveVertexParameters : mActiveFragmentParameters; - if(!activeParameters.isNull()) - { - // use param name to get index : use appropriate parameters ptr - const Ogre::GpuConstantDefinition& def = - activeParameters->getConstantDefinition(ActiveShaderDef.ParamName); - ActiveShaderDef.PhysicalIndex = def.physicalIndex; - // use index to get RealConstantEntry - const float* pFloat = activeParameters->getFloatPointer(ActiveShaderDef.PhysicalIndex); - // set position of ScrollWidget as param value - uniformVal = pFloat[ActiveShaderDef.ElementIndex]; - } - } - break; - - case MAT_SPECULAR: - { - // get the specular values from the material pass - - Ogre::ColourValue OldSpec(mActivePass->getSpecular()); - uniformVal = OldSpec[ActiveShaderDef.ElementIndex]; - } - break; - - case MAT_DIFFUSE: - { - // get the diffuse values from the material pass - - Ogre::ColourValue OldSpec(mActivePass->getDiffuse()); - uniformVal = OldSpec[ActiveShaderDef.ElementIndex]; - } - break; - - case MAT_AMBIENT: - { - // get the ambient values from the material pass - - Ogre::ColourValue OldSpec(mActivePass->getAmbient()); - uniformVal = OldSpec[ActiveShaderDef.ElementIndex]; - } - break; - - case MAT_SHININESS: - { - // get the ambient values from the material pass - uniformVal = mActivePass->getShininess(); - } - - break; - - case MAT_EMISSIVE: - { - // get the ambient values from the material pass - - //ColourValue OldSpec(mActivePass->gete()); - //activeScrollWidget->setScrollPosition( OldSpec.val[ActiveShaderDef->ElementIndex] ); - } - break; - } - shaderControlSlider->setValue(uniformVal); - - } - else - { - shaderControlSlider->hide(); - } - } - } - } - } + + size_t startControlIndex = mCurrentPage * CONTROLS_PER_PAGE; + int numControls = static_cast(activeControlCount - startControlIndex); + if (numControls <= 0) + { + mCurrentPage = 0; + startControlIndex = 0; + numControls = (int)activeControlCount; + } + + for (size_t i=0; ishow(); + size_t controlIndex = startControlIndex + i; + const ShaderControl& ActiveShaderDef = mMaterialControlsContainer[mCurrentMaterial].getShaderControl(controlIndex); + shaderControlSlider->setRange(ActiveShaderDef.MinVal, ActiveShaderDef.MaxVal, 50, false); + shaderControlSlider->setCaption(ActiveShaderDef.Name); + + float uniformVal = 0.0; + switch(ActiveShaderDef.ValType) + { + case GPU_VERTEX: + case GPU_FRAGMENT: + { + Ogre::GpuProgramParametersSharedPtr activeParameters = + (ActiveShaderDef.ValType == GPU_VERTEX) ? + mActiveVertexParameters : mActiveFragmentParameters; + if(!activeParameters.isNull()) + { + // use param name to get index : use appropriate parameters ptr + const Ogre::GpuConstantDefinition& def = + activeParameters->getConstantDefinition(ActiveShaderDef.ParamName); + ActiveShaderDef.PhysicalIndex = def.physicalIndex; + // use index to get RealConstantEntry + const float* pFloat = activeParameters->getFloatPointer(ActiveShaderDef.PhysicalIndex); + // set position of ScrollWidget as param value + uniformVal = pFloat[ActiveShaderDef.ElementIndex]; + } + } + break; + + case MAT_SPECULAR: + { + // get the specular values from the material pass + + Ogre::ColourValue OldSpec(mActivePass->getSpecular()); + uniformVal = OldSpec[ActiveShaderDef.ElementIndex]; + } + break; + + case MAT_DIFFUSE: + { + // get the diffuse values from the material pass + + Ogre::ColourValue OldSpec(mActivePass->getDiffuse()); + uniformVal = OldSpec[ActiveShaderDef.ElementIndex]; + } + break; + + case MAT_AMBIENT: + { + // get the ambient values from the material pass + + Ogre::ColourValue OldSpec(mActivePass->getAmbient()); + uniformVal = OldSpec[ActiveShaderDef.ElementIndex]; + } + break; + + case MAT_SHININESS: + { + // get the ambient values from the material pass + uniformVal = mActivePass->getShininess(); + } + + break; + + case MAT_EMISSIVE: + { + // get the ambient values from the material pass + + //ColourValue OldSpec(mActivePass->gete()); + //activeScrollWidget->setScrollPosition( OldSpec.val[ActiveShaderDef->ElementIndex] ); + } + break; + } + shaderControlSlider->setValue(uniformVal); + + } + else + { + shaderControlSlider->hide(); + } + } + } + } + } } void Sample_Ocean::itemSelected(SelectMenu *menu) { - //Only one selection menu - the material one - mCurrentMaterial = menu->getSelectionIndex(); - mActiveMaterial = Ogre::MaterialManager::getSingleton().getByName( mMaterialControlsContainer[mCurrentMaterial].getMaterialName() ); - mActiveMaterial->load(); - size_t numShaders = mMaterialControlsContainer[mCurrentMaterial].getShaderControlCount(); - mNumPages = (numShaders / CONTROLS_PER_PAGE) + (numShaders % CONTROLS_PER_PAGE == 0 ? 0 : 1); - changePage(0); - - if (mOceanSurfaceEnt) - mOceanSurfaceEnt->setMaterialName(mMaterialControlsContainer[mCurrentMaterial].getMaterialName()); + //Only one selection menu - the material one + mCurrentMaterial = menu->getSelectionIndex(); + mActiveMaterial = Ogre::MaterialManager::getSingleton().getByName( mMaterialControlsContainer[mCurrentMaterial].getMaterialName() ); + mActiveMaterial->load(); + size_t numShaders = mMaterialControlsContainer[mCurrentMaterial].getShaderControlCount(); + mNumPages = (numShaders / CONTROLS_PER_PAGE) + (numShaders % CONTROLS_PER_PAGE == 0 ? 0 : 1); + changePage(0); + + if (mOceanSurfaceEnt) + mOceanSurfaceEnt->setMaterialName(mMaterialControlsContainer[mCurrentMaterial].getMaterialName()); } bool Sample_Ocean::frameRenderingQueued(const FrameEvent& evt) { - mRotateSpeed = evt.timeSinceLastFrame * 20; - if(mSpinLight) - { - mLightPivots[0]->rotate(mLightRotationAxes[0], Ogre::Angle(mRotateSpeed * 2.0f)); - } - return SdkSample::frameRenderingQueued(evt); + mRotateSpeed = evt.timeSinceLastFrame * 20; + if(mSpinLight) + { + mLightPivots[0]->rotate(mLightRotationAxes[0], Ogre::Angle(mRotateSpeed * 2.0f)); + } + return SdkSample::frameRenderingQueued(evt); } void Sample_Ocean::buttonHit(OgreBites::Button* button) { - //Only one button - change page - changePage(); + //Only one button - change page + changePage(); } void Sample_Ocean::checkBoxToggled(CheckBox* cb) { - //Only one checkbox - mSpinLight = cb->isChecked(); + //Only one checkbox + mSpinLight = cb->isChecked(); } -#endif // end _Sample_Ocean_H_ +#endif // end _Sample_Ocean_H_ diff --git a/Samples/OceanDemo/src/MaterialControls.cpp b/Samples/OceanDemo/src/MaterialControls.cpp index b948fff5f3f..afcac28db52 100644 --- a/Samples/OceanDemo/src/MaterialControls.cpp +++ b/Samples/OceanDemo/src/MaterialControls.cpp @@ -86,14 +86,14 @@ void loadMaterialControlsFile(MaterialControlsContainer& controlsContainer, cons if (!secName.empty() && settings) { materialName = cf.getSetting("material", secName); - - Ogre::MaterialPtr curMat = Ogre::MaterialManager::getSingleton().getByName(materialName); - curMat->load(); - Ogre::Technique * curTec = curMat->getBestTechnique(); - if (!curTec || !curTec->isSupported()) - { - continue; - } + + Ogre::MaterialPtr curMat = Ogre::MaterialManager::getSingleton().getByName(materialName); + curMat->load(); + Ogre::Technique * curTec = curMat->getBestTechnique(); + if (!curTec || !curTec->isSupported()) + { + continue; + } MaterialControls newMaaterialControls(secName, materialName); controlsContainer.push_back(newMaaterialControls); @@ -112,7 +112,7 @@ void loadMaterialControlsFile(MaterialControlsContainer& controlsContainer, cons } } - Ogre::LogManager::getSingleton().logMessage( "Material Controls setup" ); + Ogre::LogManager::getSingleton().logMessage( "Material Controls setup" ); } catch (Ogre::Exception e) { @@ -124,11 +124,11 @@ void loadMaterialControlsFile(MaterialControlsContainer& controlsContainer, cons void loadAllMaterialControlFiles(MaterialControlsContainer& controlsContainer) { Ogre::StringVectorPtr fileStringVector = Ogre::ResourceGroupManager::getSingleton().findResourceNames( "Popular", "*.controls"); - Ogre::StringVector::iterator controlsFileNameIterator = fileStringVector->begin(); + Ogre::StringVector::iterator controlsFileNameIterator = fileStringVector->begin(); while ( controlsFileNameIterator != fileStringVector->end() ) - { + { loadMaterialControlsFile(controlsContainer, *controlsFileNameIterator); ++controlsFileNameIterator; - } + } } diff --git a/Samples/OceanDemo/src/OceanDemo.cpp b/Samples/OceanDemo/src/OceanDemo.cpp index 1d4f3ca79fa..46c716e3169 100644 --- a/Samples/OceanDemo/src/OceanDemo.cpp +++ b/Samples/OceanDemo/src/OceanDemo.cpp @@ -22,16 +22,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Ocean; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Ocean; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/PCZTestApp/include/PCZTestApp.h b/Samples/PCZTestApp/include/PCZTestApp.h index f0662df1f1d..331b3a253c3 100644 --- a/Samples/PCZTestApp/include/PCZTestApp.h +++ b/Samples/PCZTestApp/include/PCZTestApp.h @@ -11,7 +11,7 @@ This file based on the Example App framework from Ogre3d (www.ogre3d.org) PCZTestApp.h \brief Specialisation of OGRE's framework application to test/demo the - Portal Connected Zone (PCZ) Scene Manager Plugin. + Portal Connected Zone (PCZ) Scene Manager Plugin. */ #include "ExampleApplication.h" @@ -29,44 +29,44 @@ class PCZTestFrameListener : public ExampleFrameListener public: PCZTestFrameListener(RenderWindow* win, Camera* cam) : ExampleFrameListener( win, cam ) { - mMoveSpeed = 15.0; + mMoveSpeed = 15.0; } - void moveCamera() - { - // Make all the spatial changes to the camera's scene node - // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW - //(e.g. airplane) + void moveCamera() + { + // Make all the spatial changes to the camera's scene node + // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW + //(e.g. airplane) mCamera->getParentSceneNode()->translate(mTranslateVector, Node::TS_LOCAL); - mCamera->getParentSceneNode()->pitch(mRotY); - mCamera->getParentSceneNode()->yaw(mRotX, Node::TS_WORLD); + mCamera->getParentSceneNode()->pitch(mRotY); + mCamera->getParentSceneNode()->yaw(mRotX, Node::TS_WORLD); buildingNode->translate(buildingTranslate, Node::TS_LOCAL); - } + } bool frameRenderingQueued( const FrameEvent& evt ) { if( ExampleFrameListener::frameRenderingQueued( evt ) == false ) - return false; + return false; buildingTranslate = Vector3(0,0,0); - if( mKeyboard->isKeyDown( OIS::KC_LBRACKET ) ) + if( mKeyboard->isKeyDown( OIS::KC_LBRACKET ) ) { buildingTranslate = Vector3(0,-10,0); } - if( mKeyboard->isKeyDown( OIS::KC_RBRACKET ) ) + if( mKeyboard->isKeyDown( OIS::KC_RBRACKET ) ) { buildingTranslate = Vector3(0,10,0); } - if( mKeyboard->isKeyDown( OIS::KC_LSHIFT ) || - mKeyboard->isKeyDown( OIS::KC_RSHIFT )) + if( mKeyboard->isKeyDown( OIS::KC_LSHIFT ) || + mKeyboard->isKeyDown( OIS::KC_RSHIFT )) { mMoveSpeed = 150; } - else - { + else + { mMoveSpeed = 15; - } + } // test the ray scene query by showing bounding box of whatever the camera is pointing directly at // (takes furthest hit) @@ -81,7 +81,7 @@ class PCZTestFrameListener : public ExampleFrameListener RaySceneQueryResult::iterator i = qryResult.begin(); if (i != qryResult.end()) { - RaySceneQueryResult::reverse_iterator ri = qryResult.rbegin(); + RaySceneQueryResult::reverse_iterator ri = qryResult.rbegin(); MovableObject * mo = ri->movable; if (targetMO != mo) { @@ -108,17 +108,17 @@ class PCZTestApplication : public ExampleApplication } protected: - SceneNode * mCameraNode; + SceneNode * mCameraNode; - virtual void chooseSceneManager(void) + virtual void chooseSceneManager(void) { // Create the SceneManager, in this case a generic one mSceneMgr = mRoot->createSceneManager("PCZSceneManager", "PCZSceneManager"); - // initialize the scene manager using terrain as default zone - String zoneTypeName = "ZoneType_Default"; - String zoneFilename = "none"; - ((PCZSceneManager*)mSceneMgr)->init(zoneTypeName); - //mSceneMgr->showBoundingBoxes(true); + // initialize the scene manager using terrain as default zone + String zoneTypeName = "ZoneType_Default"; + String zoneFilename = "none"; + ((PCZSceneManager*)mSceneMgr)->init(zoneTypeName); + //mSceneMgr->showBoundingBoxes(true); } virtual void createFrameListener(void) { @@ -130,99 +130,99 @@ class PCZTestApplication : public ExampleApplication // Create the camera mCamera = mSceneMgr->createCamera("PlayerCam"); - // NEW: create a node for the camera and control that instead of camera directly. - // We do this because PCZSceneManager requires camera to have a node - mCameraNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("PlayerCamNode"); - // attach the camera to the node - mCameraNode->attachObject(mCamera); - // fix the yaw axis of the camera - mCameraNode->setFixedYawAxis(true); + // NEW: create a node for the camera and control that instead of camera directly. + // We do this because PCZSceneManager requires camera to have a node + mCameraNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("PlayerCamNode"); + // attach the camera to the node + mCameraNode->attachObject(mCamera); + // fix the yaw axis of the camera + mCameraNode->setFixedYawAxis(true); mCamera->setNearClipDistance(2); mCamera->setFarClipDistance( 1000 ); - // set camera zone -// ((PCZSceneNode*)(mCameraNode))->setHomeZone(((PCZSceneManager*)(mSceneMgr))->getDefaultZone()); + // set camera zone +// ((PCZSceneNode*)(mCameraNode))->setHomeZone(((PCZSceneManager*)(mSceneMgr))->getDefaultZone()); } - // utility function to create terrain zones easily - PCZone * createTerrainZone(String & zoneName, String & terrain_cfg) - { - // load terrain into the terrain zone + // utility function to create terrain zones easily + PCZone * createTerrainZone(String & zoneName, String & terrain_cfg) + { + // load terrain into the terrain zone #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE terrain_cfg = mResourcePath + terrain_cfg; #endif - PCZone * terrainZone = ((PCZSceneManager*)mSceneMgr)->createZone(String("ZoneType_Terrain"), zoneName); - terrainZone->notifyCameraCreated(mCamera); - ((PCZSceneManager*)mSceneMgr)->setZoneGeometry( zoneName, (PCZSceneNode*)mSceneMgr->getRootSceneNode(), terrain_cfg ); - - // create aab portal(s) around the terrain - String portalName; - Vector3 corners[2]; - AxisAlignedBox aabb; - - // make portal from terrain to default - Portal * p; - terrainZone->getAABB(aabb); - portalName = Ogre::String("PortalFrom"+zoneName+"ToDefault_Zone"); - p = ((PCZSceneManager*)mSceneMgr)->createPortal(portalName, Ogre::Portal::PORTAL_TYPE_AABB); - corners[0] = aabb.getMinimum(); - corners[1] = aabb.getMaximum(); - p->setCorner(0, corners[0]); - p->setCorner(1, corners[1]); - p->setDirection(Ogre::Vector3::NEGATIVE_UNIT_Z); // this indicates an "inward" pointing normal - // associate the portal with the terrain's main node - p->setNode(terrainZone->getEnclosureNode()); - // IMPORTANT: Update the derived values of the portal - p->updateDerivedValues(); - // add the portal to the zone - terrainZone->_addPortal(p); - - // make portal from default to terrain - portalName = Ogre::String("PortalFromDefault_ZoneTo"+zoneName); - Portal * p2; - p2 = ((PCZSceneManager*)mSceneMgr)->createPortal(portalName, Ogre::Portal::PORTAL_TYPE_AABB); - corners[0] = aabb.getMinimum(); - corners[1] = aabb.getMaximum(); - p2->setCorner(0, corners[0]); - p2->setCorner(1, corners[1]); - p2->setDirection(Ogre::Vector3::UNIT_Z); // this indicates an "outward" pointing normal - // associate the portal with the terrain's main node - p2->setNode(terrainZone->getEnclosureNode()); - // IMPORTANT: Update the derived values of the portal - p2->updateDerivedValues(); - // add the portal to the zone - ((PCZSceneManager*)mSceneMgr)->getDefaultZone()->_addPortal(p2); - - // connect the portals manually - p->setTargetPortal(p2); - p2->setTargetPortal(p); - p->setTargetZone(((PCZSceneManager*)mSceneMgr)->getDefaultZone()); - p2->setTargetZone(terrainZone); - - return terrainZone; - } - - PCZSceneNode* createAntiPortal(const String& name) - { - // Create antiportal test. - PCZSceneNode* antiPortalNode = (PCZSceneNode*)mSceneMgr->getRootSceneNode()->createChildSceneNode(); - PCZone* defaultZone = ((PCZSceneManager*)mSceneMgr)->getDefaultZone(); - AntiPortal* antiPortal = ((PCZSceneManager*)mSceneMgr)->createAntiPortal(name); - antiPortal->setCorner(0, Vector3(100.0f, 100.0f, 0.0f)); - antiPortal->setCorner(1, Vector3(100.0f, -100.0f, 0.0f)); - antiPortal->setCorner(2, Vector3(-100.0f, -100.0f, 0.0f)); - antiPortal->setCorner(3, Vector3(-100.0f, 100.0f, 0.0f)); - antiPortalNode->attachObject(antiPortal); - defaultZone->_addAntiPortal(antiPortal); - ((PCZSceneManager*)mSceneMgr)->addPCZSceneNode(antiPortalNode, defaultZone); - - // Anti portal prop. - Entity* planeEnt = mSceneMgr->createEntity(name + "Entity", SceneManager::PT_PLANE); - planeEnt->setMaterialName("TransparentGlassTinted"); - antiPortalNode->attachObject(planeEnt); - - return antiPortalNode; - } + PCZone * terrainZone = ((PCZSceneManager*)mSceneMgr)->createZone(String("ZoneType_Terrain"), zoneName); + terrainZone->notifyCameraCreated(mCamera); + ((PCZSceneManager*)mSceneMgr)->setZoneGeometry( zoneName, (PCZSceneNode*)mSceneMgr->getRootSceneNode(), terrain_cfg ); + + // create aab portal(s) around the terrain + String portalName; + Vector3 corners[2]; + AxisAlignedBox aabb; + + // make portal from terrain to default + Portal * p; + terrainZone->getAABB(aabb); + portalName = Ogre::String("PortalFrom"+zoneName+"ToDefault_Zone"); + p = ((PCZSceneManager*)mSceneMgr)->createPortal(portalName, Ogre::Portal::PORTAL_TYPE_AABB); + corners[0] = aabb.getMinimum(); + corners[1] = aabb.getMaximum(); + p->setCorner(0, corners[0]); + p->setCorner(1, corners[1]); + p->setDirection(Ogre::Vector3::NEGATIVE_UNIT_Z); // this indicates an "inward" pointing normal + // associate the portal with the terrain's main node + p->setNode(terrainZone->getEnclosureNode()); + // IMPORTANT: Update the derived values of the portal + p->updateDerivedValues(); + // add the portal to the zone + terrainZone->_addPortal(p); + + // make portal from default to terrain + portalName = Ogre::String("PortalFromDefault_ZoneTo"+zoneName); + Portal * p2; + p2 = ((PCZSceneManager*)mSceneMgr)->createPortal(portalName, Ogre::Portal::PORTAL_TYPE_AABB); + corners[0] = aabb.getMinimum(); + corners[1] = aabb.getMaximum(); + p2->setCorner(0, corners[0]); + p2->setCorner(1, corners[1]); + p2->setDirection(Ogre::Vector3::UNIT_Z); // this indicates an "outward" pointing normal + // associate the portal with the terrain's main node + p2->setNode(terrainZone->getEnclosureNode()); + // IMPORTANT: Update the derived values of the portal + p2->updateDerivedValues(); + // add the portal to the zone + ((PCZSceneManager*)mSceneMgr)->getDefaultZone()->_addPortal(p2); + + // connect the portals manually + p->setTargetPortal(p2); + p2->setTargetPortal(p); + p->setTargetZone(((PCZSceneManager*)mSceneMgr)->getDefaultZone()); + p2->setTargetZone(terrainZone); + + return terrainZone; + } + + PCZSceneNode* createAntiPortal(const String& name) + { + // Create antiportal test. + PCZSceneNode* antiPortalNode = (PCZSceneNode*)mSceneMgr->getRootSceneNode()->createChildSceneNode(); + PCZone* defaultZone = ((PCZSceneManager*)mSceneMgr)->getDefaultZone(); + AntiPortal* antiPortal = ((PCZSceneManager*)mSceneMgr)->createAntiPortal(name); + antiPortal->setCorner(0, Vector3(100.0f, 100.0f, 0.0f)); + antiPortal->setCorner(1, Vector3(100.0f, -100.0f, 0.0f)); + antiPortal->setCorner(2, Vector3(-100.0f, -100.0f, 0.0f)); + antiPortal->setCorner(3, Vector3(-100.0f, 100.0f, 0.0f)); + antiPortalNode->attachObject(antiPortal); + defaultZone->_addAntiPortal(antiPortal); + ((PCZSceneManager*)mSceneMgr)->addPCZSceneNode(antiPortalNode, defaultZone); + + // Anti portal prop. + Entity* planeEnt = mSceneMgr->createEntity(name + "Entity", SceneManager::PT_PLANE); + planeEnt->setMaterialName("TransparentGlassTinted"); + antiPortalNode->attachObject(planeEnt); + + return antiPortalNode; + } // Just override the mandatory create scene method void createScene(void) @@ -232,8 +232,8 @@ class PCZTestApplication : public ExampleApplication // Create a skybox mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 500 ); - // put the skybox node in the default zone - ((PCZSceneManager*)mSceneMgr)->setSkyZone(0); + // put the skybox node in the default zone + ((PCZSceneManager*)mSceneMgr)->setSkyZone(0); // Create a light Light* l = mSceneMgr->createLight("MainLight"); @@ -242,8 +242,8 @@ class PCZTestApplication : public ExampleApplication // Accept default settings: point light, white diffuse, just set position // attach light to a scene node so the PCZSM can handle it properly (zone-wise) // IMPORTANT: Lights (just like cameras) MUST be connected to a scene node! - SceneNode * lightNode = mCameraNode->createChildSceneNode("light_Node"); - lightNode->attachObject(l); + SceneNode * lightNode = mCameraNode->createChildSceneNode("light_Node"); + lightNode->attachObject(l); // Fog // NB it's VERY important to set this before calling setWorldGeometry @@ -252,98 +252,98 @@ class PCZTestApplication : public ExampleApplication mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000); mWindow->getViewport(0)->setBackgroundColour(fadeColour); - // create a terrain zone + // create a terrain zone // String terrain_cfg("terrain.cfg"); -// String zoneName("Terrain1_Zone"); -// PCZone * terrainZone = createTerrainZone(zoneName, terrain_cfg); +// String zoneName("Terrain1_Zone"); +// PCZone * terrainZone = createTerrainZone(zoneName, terrain_cfg); -/* // Create another terrain zone +/* // Create another terrain zone terrain_cfg = "terrain.cfg"; - zoneName = "Terrain2_Zone"; - terrainZone = createTerrainZone(zoneName, terrain_cfg); - // move second terrain next to first terrain - terrainZone->getEnclosureNode()->setPosition(1500, 0, 0); + zoneName = "Terrain2_Zone"; + terrainZone = createTerrainZone(zoneName, terrain_cfg); + // move second terrain next to first terrain + terrainZone->getEnclosureNode()->setPosition(1500, 0, 0); - // Create another terrain zone + // Create another terrain zone terrain_cfg = "terrain.cfg"; - zoneName = "Terrain3_Zone"; - terrainZone = createTerrainZone(zoneName, terrain_cfg); - // move terrain next to first terrain - terrainZone->getEnclosureNode()->setPosition(0, 0, 1500); + zoneName = "Terrain3_Zone"; + terrainZone = createTerrainZone(zoneName, terrain_cfg); + // move terrain next to first terrain + terrainZone->getEnclosureNode()->setPosition(0, 0, 1500); - // Create another terrain zone + // Create another terrain zone terrain_cfg = "terrain.cfg"; - zoneName = "Terrain4_Zone"; - terrainZone = createTerrainZone(zoneName, terrain_cfg); - // move terrain next to first terrain - terrainZone->getEnclosureNode()->setPosition(-1500, 0, 0); + zoneName = "Terrain4_Zone"; + terrainZone = createTerrainZone(zoneName, terrain_cfg); + // move terrain next to first terrain + terrainZone->getEnclosureNode()->setPosition(-1500, 0, 0); - // Create another terrain zone + // Create another terrain zone terrain_cfg = "terrain.cfg"; - zoneName = "Terrain5_Zone"; - terrainZone = createTerrainZone(zoneName, terrain_cfg); - // move terrain next to first terrain - terrainZone->getEnclosureNode()->setPosition(0, 0, -1500); + zoneName = "Terrain5_Zone"; + terrainZone = createTerrainZone(zoneName, terrain_cfg); + // move terrain next to first terrain + terrainZone->getEnclosureNode()->setPosition(0, 0, -1500); - // Create another terrain zone + // Create another terrain zone terrain_cfg = "terrain.cfg"; - zoneName = "Terrain6_Zone"; - terrainZone = createTerrainZone(zoneName, terrain_cfg); - // move terrain next to first terrain - terrainZone->getEnclosureNode()->setPosition(1500, 0, 1500); + zoneName = "Terrain6_Zone"; + terrainZone = createTerrainZone(zoneName, terrain_cfg); + // move terrain next to first terrain + terrainZone->getEnclosureNode()->setPosition(1500, 0, 1500); - // Create another terrain zone + // Create another terrain zone terrain_cfg = "terrain.cfg"; - zoneName = "Terrain7_Zone"; - terrainZone = createTerrainZone(zoneName, terrain_cfg); - // move terrain next to first terrain - terrainZone->getEnclosureNode()->setPosition(-1500, 0, -1500); + zoneName = "Terrain7_Zone"; + terrainZone = createTerrainZone(zoneName, terrain_cfg); + // move terrain next to first terrain + terrainZone->getEnclosureNode()->setPosition(-1500, 0, -1500); - // Create another terrain zone + // Create another terrain zone terrain_cfg = "terrain.cfg"; - zoneName = "Terrain8_Zone"; - terrainZone = createTerrainZone(zoneName, terrain_cfg); - // move terrain next to first terrain - terrainZone->getEnclosureNode()->setPosition(-1500, 0, 1500); + zoneName = "Terrain8_Zone"; + terrainZone = createTerrainZone(zoneName, terrain_cfg); + // move terrain next to first terrain + terrainZone->getEnclosureNode()->setPosition(-1500, 0, 1500); - // Create another terrain zone + // Create another terrain zone terrain_cfg = "terrain.cfg"; - zoneName = "Terrain9_Zone"; - terrainZone = createTerrainZone(zoneName, terrain_cfg); - // move terrain next to first terrain - terrainZone->getEnclosureNode()->setPosition(1500, 0, -1500); + zoneName = "Terrain9_Zone"; + terrainZone = createTerrainZone(zoneName, terrain_cfg); + // move terrain next to first terrain + terrainZone->getEnclosureNode()->setPosition(1500, 0, -1500); */ - // set far clip plane to one terrain zone width (we have a LOT of terrain here, so we need to do far clipping!) + // set far clip plane to one terrain zone width (we have a LOT of terrain here, so we need to do far clipping!) mCamera->setFarClipDistance(1500); - // create test buildinig - RoomObject roomObj; - buildingNode = roomObj.createTestBuilding(mSceneMgr, String("1")); - buildingNode->setPosition(500, 165, 570); - //Ogre::Radian r = Radian(3.1416/7.0); - //buildingNode->rotate(Vector3::UNIT_Y, r); + // create test buildinig + RoomObject roomObj; + buildingNode = roomObj.createTestBuilding(mSceneMgr, String("1")); + buildingNode->setPosition(500, 165, 570); + //Ogre::Radian r = Radian(3.1416/7.0); + //buildingNode->rotate(Vector3::UNIT_Y, r); - // create another test buildinig - RoomObject roomObj2; - buildingNode = roomObj2.createTestBuilding(mSceneMgr, String("2")); - buildingNode->setPosition(400, 165, 570); - //Ogre::Radian r = Radian(3.1416/7.0); - //buildingNode->rotate(Vector3::UNIT_Y, r); + // create another test buildinig + RoomObject roomObj2; + buildingNode = roomObj2.createTestBuilding(mSceneMgr, String("2")); + buildingNode->setPosition(400, 165, 570); + //Ogre::Radian r = Radian(3.1416/7.0); + //buildingNode->rotate(Vector3::UNIT_Y, r); - PCZSceneNode* antiPortalNode1 = createAntiPortal("AntiPortal1"); - antiPortalNode1->setPosition(Vector3(450, 200, 800)); - antiPortalNode1->setScale(0.5f, 0.5f, 0.5f); + PCZSceneNode* antiPortalNode1 = createAntiPortal("AntiPortal1"); + antiPortalNode1->setPosition(Vector3(450, 200, 800)); + antiPortalNode1->setScale(0.5f, 0.5f, 0.5f); - PCZSceneNode* antiPortalNode2 = createAntiPortal("AntiPortal2"); - antiPortalNode2->setPosition(Vector3(460, 200, 700)); - antiPortalNode2->setScale(0.5f, 0.5f, 0.5f); + PCZSceneNode* antiPortalNode2 = createAntiPortal("AntiPortal2"); + antiPortalNode2->setPosition(Vector3(460, 200, 700)); + antiPortalNode2->setScale(0.5f, 0.5f, 0.5f); // Position camera in the center of the building mCameraNode->setPosition(buildingNode->getPosition()); // Look back along -Z - mCamera->lookAt(mCameraNode->_getDerivedPosition() + Vector3(0,0,-300)); - // Update bounds for camera - mCameraNode->_updateBounds(); + mCamera->lookAt(mCameraNode->_getDerivedPosition() + Vector3(0,0,-300)); + // Update bounds for camera + mCameraNode->_updateBounds(); // create the ray scene query raySceneQuery = mSceneMgr->createRayQuery( diff --git a/Samples/PCZTestApp/include/RoomObject.h b/Samples/PCZTestApp/include/RoomObject.h index 20b1736a194..b02aa5b50aa 100644 --- a/Samples/PCZTestApp/include/RoomObject.h +++ b/Samples/PCZTestApp/include/RoomObject.h @@ -4,7 +4,7 @@ // each doorway must have a separate portal object created for it (not // done in this class). // -// Filename : RoomObject.h +// Filename : RoomObject.h #ifndef _ROOM_OBJECT_H_ #define _ROOM_OBJECT_H_ @@ -14,62 +14,62 @@ class RoomObject { - enum RoomWalls - { - TOP_WALL, - BOT_WALL, - FRONT_WALL, - BACK_WALL, - LEFT_WALL, - RIGHT_WALL - }; + enum RoomWalls + { + TOP_WALL, + BOT_WALL, + FRONT_WALL, + BACK_WALL, + LEFT_WALL, + RIGHT_WALL + }; private: - void addMaterial(const Ogre::String& mat, - const Ogre::ColourValue &clr, - Ogre::SceneBlendType sbt); - void createPoints(Ogre::Vector3 dimensions, - Ogre::Vector3 doorDimensions); - void createWalls(Ogre::ManualObject* room, - short doorFlags, - bool isEnclosure); - void createPortals(Ogre::SceneManager *scene, - Ogre::ManualObject* room, - Ogre::SceneNode * roomNode, - Ogre::PCZone * zone, - short doorFlags, - bool isEnclosure); - void createPortals(Ogre::SceneManager *scene, - Ogre::Entity* room, - Ogre::SceneNode * roomNode, - Ogre::PCZone * zone, - short doorFlags, - bool isEnclosure); + void addMaterial(const Ogre::String& mat, + const Ogre::ColourValue &clr, + Ogre::SceneBlendType sbt); + void createPoints(Ogre::Vector3 dimensions, + Ogre::Vector3 doorDimensions); + void createWalls(Ogre::ManualObject* room, + short doorFlags, + bool isEnclosure); + void createPortals(Ogre::SceneManager *scene, + Ogre::ManualObject* room, + Ogre::SceneNode * roomNode, + Ogre::PCZone * zone, + short doorFlags, + bool isEnclosure); + void createPortals(Ogre::SceneManager *scene, + Ogre::Entity* room, + Ogre::SceneNode * roomNode, + Ogre::PCZone * zone, + short doorFlags, + bool isEnclosure); private: - Ogre::Vector3 points[32]; - int mPortalCount; + Ogre::Vector3 points[32]; + int mPortalCount; public: - enum RoomDoors - { - DOOR_NONE = 0x00, - DOOR_TOP = 0x01, - DOOR_BOT = 0x02, - DOOR_FRONT = 0x04, - DOOR_BACK = 0x08, - DOOR_LEFT = 0x10, - DOOR_RIGHT = 0x20, - DOOR_ALL = 0xFF - }; + enum RoomDoors + { + DOOR_NONE = 0x00, + DOOR_TOP = 0x01, + DOOR_BOT = 0x02, + DOOR_FRONT = 0x04, + DOOR_BACK = 0x08, + DOOR_LEFT = 0x10, + DOOR_RIGHT = 0x20, + DOOR_ALL = 0xFF + }; - Ogre::PCZSceneNode * createTestBuilding(Ogre::SceneManager *scene, const Ogre::String & name); + Ogre::PCZSceneNode * createTestBuilding(Ogre::SceneManager *scene, const Ogre::String & name); - Ogre::ManualObject*createRoom(Ogre::SceneManager *scene, - const Ogre::String &name, - short doorFlags, - bool isEnclosure, - Ogre::Vector3 dimensions, - Ogre::Vector3 doorDimensions); + Ogre::ManualObject*createRoom(Ogre::SceneManager *scene, + const Ogre::String &name, + short doorFlags, + bool isEnclosure, + Ogre::Vector3 dimensions, + Ogre::Vector3 doorDimensions); }; #endif //--_ROOM_OBJECT_H_ diff --git a/Samples/PCZTestApp/src/PCZTestApp.cpp b/Samples/PCZTestApp/src/PCZTestApp.cpp index 98ed90a1c65..5bf8a5c59e4 100644 --- a/Samples/PCZTestApp/src/PCZTestApp.cpp +++ b/Samples/PCZTestApp/src/PCZTestApp.cpp @@ -9,7 +9,7 @@ PCZTestApp.cpp \brief Demonstrates the Portal Connected Zone Scene Manager. This application - is based on the Skybox demo app and uses the ExampleApplication framework. + is based on the Skybox demo app and uses the ExampleApplication framework. */ #include "PCZTestApp.h" diff --git a/Samples/PCZTestApp/src/RoomObject.cpp b/Samples/PCZTestApp/src/RoomObject.cpp index df47fe119c5..4dd5a5da9d2 100644 --- a/Samples/PCZTestApp/src/RoomObject.cpp +++ b/Samples/PCZTestApp/src/RoomObject.cpp @@ -1,7 +1,7 @@ // // // -// Filename : RoomObject.cpp +// Filename : RoomObject.cpp #include "Ogre.h" #include "OgreMaterial.h" @@ -13,978 +13,978 @@ static int count = 0; PCZSceneNode * RoomObject::createTestBuilding(Ogre::SceneManager *scene, const String & name) { - count++; - mPortalCount = 0; - Ogre::PCZSceneManager * pczSM = (Ogre::PCZSceneManager*)scene; + count++; + mPortalCount = 0; + Ogre::PCZSceneManager * pczSM = (Ogre::PCZSceneManager*)scene; - // set points to building exterior size - createPoints(Vector3(60.0, 40.0, 60.0), Vector3(4.0, 10.0, 4.0)); + // set points to building exterior size + createPoints(Vector3(60.0, 40.0, 60.0), Vector3(4.0, 10.0, 4.0)); - // create the building exterior - Entity *exterior = pczSM->createEntity( name + "_building_exterior", "building_exterior.mesh" ); + // create the building exterior + Entity *exterior = pczSM->createEntity( name + "_building_exterior", "building_exterior.mesh" ); - // make the enclosure a child node of the root scene node - PCZSceneNode * exteriorNode, * baseNode; - baseNode = (PCZSceneNode*)scene->getRootSceneNode()->createChildSceneNode(name +"_base_node"); + // make the enclosure a child node of the root scene node + PCZSceneNode * exteriorNode, * baseNode; + baseNode = (PCZSceneNode*)scene->getRootSceneNode()->createChildSceneNode(name +"_base_node"); exteriorNode = (PCZSceneNode*)baseNode->createChildSceneNode(name +"_building_exterior_node", Vector3( 0.0f, 0.0f, 0.0f ) ); - exteriorNode->attachObject(exterior); - pczSM->addPCZSceneNode(exteriorNode, pczSM->getDefaultZone()); + exteriorNode->attachObject(exterior); + pczSM->addPCZSceneNode(exteriorNode, pczSM->getDefaultZone()); - // create portals for the building exterior - createPortals(scene, - exterior, - exteriorNode, - pczSM->getDefaultZone(), - DOOR_FRONT|DOOR_BACK|DOOR_LEFT|DOOR_RIGHT, - true); + // create portals for the building exterior + createPortals(scene, + exterior, + exteriorNode, + pczSM->getDefaultZone(), + DOOR_FRONT|DOOR_BACK|DOOR_LEFT|DOOR_RIGHT, + true); - // reset points to room size - createPoints(Vector3(20.0, 10.0, 20.0), Vector3(4.0, 10.0, 4.0)); + // reset points to room size + createPoints(Vector3(20.0, 10.0, 20.0), Vector3(4.0, 10.0, 4.0)); - // create an interior room + // create an interior room Entity *room = pczSM->createEntity( name +"_room1", "room_nzpz.mesh" ); - // add the room as a child node to the enclosure node - PCZSceneNode * roomNode; - roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room1_node", Vector3( 0.0f, 0.0f, 20.0f ) ); - roomNode->attachObject(room); - - // room needs it's own zone - Ogre::String zoneType = "ZoneType_Default"; - Ogre::String zoneName = name +"_room1_zone"; - PCZone * newZone = pczSM->createZone(zoneType, zoneName); - newZone->setEnclosureNode(roomNode); - pczSM->addPCZSceneNode(roomNode, newZone); - - // create portals for the room - createPortals(scene, - room, - roomNode, - newZone, - DOOR_FRONT|DOOR_BACK, - false); - - // create another interior room + // add the room as a child node to the enclosure node + PCZSceneNode * roomNode; + roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room1_node", Vector3( 0.0f, 0.0f, 20.0f ) ); + roomNode->attachObject(room); + + // room needs it's own zone + Ogre::String zoneType = "ZoneType_Default"; + Ogre::String zoneName = name +"_room1_zone"; + PCZone * newZone = pczSM->createZone(zoneType, zoneName); + newZone->setEnclosureNode(roomNode); + pczSM->addPCZSceneNode(roomNode, newZone); + + // create portals for the room + createPortals(scene, + room, + roomNode, + newZone, + DOOR_FRONT|DOOR_BACK, + false); + + // create another interior room room = pczSM->createEntity( name +"_room2", "room_nxpxnypynzpz.mesh" ); - // add the room as a child node to the enclosure node - roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room2_node", Vector3( 0.0f, 0.0f, 0.0f ) ); - roomNode->attachObject(room); - - // room needs it's own zone - zoneName = name +"_room2_zone"; - newZone = pczSM->createZone(zoneType, zoneName); - newZone->setEnclosureNode(roomNode); - pczSM->addPCZSceneNode(roomNode, newZone); - - // create portals for the room - createPortals(scene, - room, - roomNode, - newZone, - DOOR_FRONT|DOOR_BACK|DOOR_LEFT|DOOR_RIGHT|DOOR_TOP|DOOR_BOT, - false); - - // create another interior room + // add the room as a child node to the enclosure node + roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room2_node", Vector3( 0.0f, 0.0f, 0.0f ) ); + roomNode->attachObject(room); + + // room needs it's own zone + zoneName = name +"_room2_zone"; + newZone = pczSM->createZone(zoneType, zoneName); + newZone->setEnclosureNode(roomNode); + pczSM->addPCZSceneNode(roomNode, newZone); + + // create portals for the room + createPortals(scene, + room, + roomNode, + newZone, + DOOR_FRONT|DOOR_BACK|DOOR_LEFT|DOOR_RIGHT|DOOR_TOP|DOOR_BOT, + false); + + // create another interior room room = pczSM->createEntity( name +"_room3", "room_nzpz.mesh" ); - // add the room as a child node to the enclosure node - roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room3_node", Vector3( 0.0f, 0.0f, -20.0f ) ); - roomNode->attachObject(room); - - // room needs it's own zone - zoneName = name +"_room3_zone"; - newZone = pczSM->createZone(zoneType, zoneName); - newZone->setEnclosureNode(roomNode); - pczSM->addPCZSceneNode(roomNode, newZone); - - // create portals for the room - createPortals(scene, - room, - roomNode, - newZone, - DOOR_FRONT|DOOR_BACK, - false); - - // create another interior room + // add the room as a child node to the enclosure node + roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room3_node", Vector3( 0.0f, 0.0f, -20.0f ) ); + roomNode->attachObject(room); + + // room needs it's own zone + zoneName = name +"_room3_zone"; + newZone = pczSM->createZone(zoneType, zoneName); + newZone->setEnclosureNode(roomNode); + pczSM->addPCZSceneNode(roomNode, newZone); + + // create portals for the room + createPortals(scene, + room, + roomNode, + newZone, + DOOR_FRONT|DOOR_BACK, + false); + + // create another interior room room = pczSM->createEntity( name +"_room4", "room_nxpx.mesh" ); - // add the room as a child node to the enclosure node - roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room4_node", Vector3( -20.0f, 0.0f, 0.0f ) ); - roomNode->attachObject(room); - - // room needs it's own zone - zoneName = name +"_room4_zone"; - newZone = pczSM->createZone(zoneType, zoneName); - newZone->setEnclosureNode(roomNode); - pczSM->addPCZSceneNode(roomNode, newZone); - - // create portals for the room - createPortals(scene, - room, - roomNode, - newZone, - DOOR_LEFT|DOOR_RIGHT, - false); - - // create another interior room + // add the room as a child node to the enclosure node + roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room4_node", Vector3( -20.0f, 0.0f, 0.0f ) ); + roomNode->attachObject(room); + + // room needs it's own zone + zoneName = name +"_room4_zone"; + newZone = pczSM->createZone(zoneType, zoneName); + newZone->setEnclosureNode(roomNode); + pczSM->addPCZSceneNode(roomNode, newZone); + + // create portals for the room + createPortals(scene, + room, + roomNode, + newZone, + DOOR_LEFT|DOOR_RIGHT, + false); + + // create another interior room room = pczSM->createEntity( name +"_room5", "room_nxpx.mesh" ); - // add the room as a child node to the enclosure node - roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room5_node", Vector3( 20.0f, 0.0f, 0.0f ) ); - roomNode->attachObject(room); - - // room needs it's own zone - zoneName = name +"_room5_zone"; - newZone = pczSM->createZone(zoneType, zoneName); - newZone->setEnclosureNode(roomNode); - pczSM->addPCZSceneNode(roomNode, newZone); - - // create portals for the room - createPortals(scene, - room, - roomNode, - newZone, - DOOR_LEFT|DOOR_RIGHT, - false); - - // create another interior room + // add the room as a child node to the enclosure node + roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room5_node", Vector3( 20.0f, 0.0f, 0.0f ) ); + roomNode->attachObject(room); + + // room needs it's own zone + zoneName = name +"_room5_zone"; + newZone = pczSM->createZone(zoneType, zoneName); + newZone->setEnclosureNode(roomNode); + pczSM->addPCZSceneNode(roomNode, newZone); + + // create portals for the room + createPortals(scene, + room, + roomNode, + newZone, + DOOR_LEFT|DOOR_RIGHT, + false); + + // create another interior room room = pczSM->createEntity( name +"_room6", "ROOM_NY.mesh" ); - // add the room as a child node to the enclosure node - roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room6_node", Vector3( 0.0f, 10.0f, 0.0f ) ); - roomNode->attachObject(room); - - // room needs it's own zone - zoneName = name +"_room6_zone"; - newZone = pczSM->createZone(zoneType, zoneName); - newZone->setEnclosureNode(roomNode); - pczSM->addPCZSceneNode(roomNode, newZone); - - // create portals for the room - createPortals(scene, - room, - roomNode, - newZone, - DOOR_BOT, - false); - - // create another interior room + // add the room as a child node to the enclosure node + roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room6_node", Vector3( 0.0f, 10.0f, 0.0f ) ); + roomNode->attachObject(room); + + // room needs it's own zone + zoneName = name +"_room6_zone"; + newZone = pczSM->createZone(zoneType, zoneName); + newZone->setEnclosureNode(roomNode); + pczSM->addPCZSceneNode(roomNode, newZone); + + // create portals for the room + createPortals(scene, + room, + roomNode, + newZone, + DOOR_BOT, + false); + + // create another interior room room = pczSM->createEntity( name +"_room7", "ROOM_PY.mesh" ); - // add the room as a child node to the enclosure node - roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room7_node", Vector3( 0.0f, -50.0f, 0.0f ) ); - roomNode->attachObject(room); + // add the room as a child node to the enclosure node + roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room7_node", Vector3( 0.0f, -50.0f, 0.0f ) ); + roomNode->attachObject(room); - // room needs it's own zone - zoneName = name +"_room7_zone"; - newZone = pczSM->createZone(zoneType, zoneName); - newZone->setEnclosureNode(roomNode); - pczSM->addPCZSceneNode(roomNode, newZone); + // room needs it's own zone + zoneName = name +"_room7_zone"; + newZone = pczSM->createZone(zoneType, zoneName); + newZone->setEnclosureNode(roomNode); + pczSM->addPCZSceneNode(roomNode, newZone); - // create portals for the room - createPortals(scene, - room, - roomNode, - newZone, - DOOR_TOP, - false); + // create portals for the room + createPortals(scene, + room, + roomNode, + newZone, + DOOR_TOP, + false); - // reset points to tall room size - createPoints(Vector3(20.0, 40.0, 20.0), Vector3(4.0, 10.0, 4.0)); + // reset points to tall room size + createPoints(Vector3(20.0, 40.0, 20.0), Vector3(4.0, 10.0, 4.0)); - // create another interior room + // create another interior room room = pczSM->createEntity( name +"_room8", "room_nypy_4y.mesh" ); - // add the room as a child node to the enclosure node - roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room8_node", Vector3( 0.0f, -25.0f, 0.0f ) ); - roomNode->attachObject(room); + // add the room as a child node to the enclosure node + roomNode = (PCZSceneNode*)baseNode->createChildSceneNode( name +"_room8_node", Vector3( 0.0f, -25.0f, 0.0f ) ); + roomNode->attachObject(room); - // room needs it's own zone - zoneName = name +"_room8_zone"; - newZone = pczSM->createZone(zoneType, zoneName); - newZone->setEnclosureNode(roomNode); - pczSM->addPCZSceneNode(roomNode, newZone); + // room needs it's own zone + zoneName = name +"_room8_zone"; + newZone = pczSM->createZone(zoneType, zoneName); + newZone->setEnclosureNode(roomNode); + pczSM->addPCZSceneNode(roomNode, newZone); - // create portals for the room - createPortals(scene, - room, - roomNode, - newZone, - DOOR_BOT|DOOR_TOP, - false); + // create portals for the room + createPortals(scene, + room, + roomNode, + newZone, + DOOR_BOT|DOOR_TOP, + false); - // resolve portal zone pointers - pczSM->connectPortalsToTargetZonesByLocation(); + // resolve portal zone pointers + pczSM->connectPortalsToTargetZonesByLocation(); - return baseNode; + return baseNode; } Ogre::ManualObject* RoomObject::createRoom(Ogre::SceneManager *scene, - const Ogre::String &name, - short doorFlags, - bool isEnclosure, - Ogre::Vector3 dimensions, - Ogre::Vector3 doorDimensions) + const Ogre::String &name, + short doorFlags, + bool isEnclosure, + Ogre::Vector3 dimensions, + Ogre::Vector3 doorDimensions) { - addMaterial(name, Ogre::ColourValue(1,1,1,.75), Ogre::SBT_TRANSPARENT_ALPHA); + addMaterial(name, Ogre::ColourValue(1,1,1,.75), Ogre::SBT_TRANSPARENT_ALPHA); - Ogre::ManualObject* room = scene->createManualObject(name); + Ogre::ManualObject* room = scene->createManualObject(name); - room->begin(name, Ogre::RenderOperation::OT_TRIANGLE_LIST); + room->begin(name, Ogre::RenderOperation::OT_TRIANGLE_LIST); - // create points - createPoints(dimensions, doorDimensions); + // create points + createPoints(dimensions, doorDimensions); -// Ogre::Real fade=.5; - Ogre::Real solid=.8; - Ogre::ColourValue color = ColourValue(0, 0, solid, solid); +// Ogre::Real fade=.5; + Ogre::Real solid=.8; + Ogre::ColourValue color = ColourValue(0, 0, solid, solid); - // copy to room - for (int i=0;i<32;i++) - { - room->position(points[i]); - room->colour(color); - } + // copy to room + for (int i=0;i<32;i++) + { + room->position(points[i]); + room->colour(color); + } - createWalls(room, doorFlags, isEnclosure); + createWalls(room, doorFlags, isEnclosure); - room->end(); + room->end(); - return room; + return room; } void RoomObject::addMaterial(const Ogre::String &mat, - const Ogre::ColourValue &clr, - Ogre::SceneBlendType sbt) + const Ogre::ColourValue &clr, + Ogre::SceneBlendType sbt) { - static int init=false; - if(init) - return; - else - init=true; - - Ogre::MaterialPtr matptr = Ogre::MaterialManager::getSingleton().create(mat, "General"); - matptr->setReceiveShadows(false); - matptr->getTechnique(0)->setLightingEnabled(true); - matptr->getTechnique(0)->getPass(0)->setDiffuse(clr); - matptr->getTechnique(0)->getPass(0)->setAmbient(clr); - matptr->getTechnique(0)->getPass(0)->setSelfIllumination(clr); - matptr->getTechnique(0)->getPass(0)->setSceneBlending(sbt); - matptr->getTechnique(0)->getPass(0)->setLightingEnabled(false); - matptr->getTechnique(0)->getPass(0)->setVertexColourTracking(Ogre::TVC_DIFFUSE); + static int init=false; + if(init) + return; + else + init=true; + + Ogre::MaterialPtr matptr = Ogre::MaterialManager::getSingleton().create(mat, "General"); + matptr->setReceiveShadows(false); + matptr->getTechnique(0)->setLightingEnabled(true); + matptr->getTechnique(0)->getPass(0)->setDiffuse(clr); + matptr->getTechnique(0)->getPass(0)->setAmbient(clr); + matptr->getTechnique(0)->getPass(0)->setSelfIllumination(clr); + matptr->getTechnique(0)->getPass(0)->setSceneBlending(sbt); + matptr->getTechnique(0)->getPass(0)->setLightingEnabled(false); + matptr->getTechnique(0)->getPass(0)->setVertexColourTracking(Ogre::TVC_DIFFUSE); } void RoomObject::createPoints(Ogre::Vector3 dimensions, - Ogre::Vector3 doorDimensions) + Ogre::Vector3 doorDimensions) { - Ogre::Real l = dimensions.x/2; - Ogre::Real h = dimensions.y/2; - Ogre::Real w = dimensions.z/2; - -// 4 7 + Ogre::Real l = dimensions.x/2; + Ogre::Real h = dimensions.y/2; + Ogre::Real w = dimensions.z/2; + +// 4 7 // *-------* -// /| /| -// / | / | y -// / 5| 3/ 6| | -// 0*---*---*---* *-- x -// | / | / / -// | / | / z -// |/ |/ -// 1*-------*2 - - points[0] = Ogre::Vector3(-l, h, w);//0 - points[1] = Ogre::Vector3(-l, -h, w);//1 - points[2] = Ogre::Vector3(l, -h, w);//2 - points[3] = Ogre::Vector3(l, h, w);//3 - - points[4] = Ogre::Vector3(-l, h, -w);//4 - points[5] = Ogre::Vector3(-l, -h, -w);//5 - points[6] = Ogre::Vector3(l, -h, -w);//6 - points[7] = Ogre::Vector3(l, h, -w);//7 - - // doors - Ogre::Real l2 = doorDimensions.x/2; - Ogre::Real h2 = doorDimensions.y/2; - Ogre::Real w2 = doorDimensions.z/2; - - // front door - points[8] = Ogre::Vector3(-l2, h2, w);//8 - points[9] = Ogre::Vector3(-l2, -h2, w);//9 - points[10] = Ogre::Vector3(l2, -h2, w);//10 - points[11] = Ogre::Vector3(l2, h2, w);//11 - - // back door - points[12] = Ogre::Vector3(-l2, h2, -w);//12 - points[13] = Ogre::Vector3(-l2, -h2, -w);//13 - points[14] = Ogre::Vector3(l2, -h2, -w);//14 - points[15] = Ogre::Vector3(l2, h2, -w);//15 - - // top door - points[16] = Ogre::Vector3(-l2, h, -w2);//16 - points[17] = Ogre::Vector3(-l2, h, w2);//17 - points[18] = Ogre::Vector3(l2, h, w2);//18 - points[19] = Ogre::Vector3(l2, h, -w2);//19 - - // bottom door - points[20] = Ogre::Vector3(-l2, -h, -w2);//20 - points[21] = Ogre::Vector3(-l2, -h, w2);//21 - points[22] = Ogre::Vector3(l2, -h, w2);//22 - points[23] = Ogre::Vector3(l2, -h, -w2);//23 - - // left door - points[24] = Ogre::Vector3(-l, h2, w2);//24 - points[25] = Ogre::Vector3(-l, -h2, w2);//25 - points[26] = Ogre::Vector3(-l, -h2, -w2);//26 - points[27] = Ogre::Vector3(-l, h2, -w2);//27 - - // right door - points[28] = Ogre::Vector3(l, h2, w2);//28 - points[29] = Ogre::Vector3(l, -h2, w2);//29 - points[30] = Ogre::Vector3(l, -h2, -w2);//30 - points[31] = Ogre::Vector3(l, h2, -w2);//31 +// /| /| +// / | / | y +// / 5| 3/ 6| | +// 0*---*---*---* *-- x +// | / | / / +// | / | / z +// |/ |/ +// 1*-------*2 + + points[0] = Ogre::Vector3(-l, h, w);//0 + points[1] = Ogre::Vector3(-l, -h, w);//1 + points[2] = Ogre::Vector3(l, -h, w);//2 + points[3] = Ogre::Vector3(l, h, w);//3 + + points[4] = Ogre::Vector3(-l, h, -w);//4 + points[5] = Ogre::Vector3(-l, -h, -w);//5 + points[6] = Ogre::Vector3(l, -h, -w);//6 + points[7] = Ogre::Vector3(l, h, -w);//7 + + // doors + Ogre::Real l2 = doorDimensions.x/2; + Ogre::Real h2 = doorDimensions.y/2; + Ogre::Real w2 = doorDimensions.z/2; + + // front door + points[8] = Ogre::Vector3(-l2, h2, w);//8 + points[9] = Ogre::Vector3(-l2, -h2, w);//9 + points[10] = Ogre::Vector3(l2, -h2, w);//10 + points[11] = Ogre::Vector3(l2, h2, w);//11 + + // back door + points[12] = Ogre::Vector3(-l2, h2, -w);//12 + points[13] = Ogre::Vector3(-l2, -h2, -w);//13 + points[14] = Ogre::Vector3(l2, -h2, -w);//14 + points[15] = Ogre::Vector3(l2, h2, -w);//15 + + // top door + points[16] = Ogre::Vector3(-l2, h, -w2);//16 + points[17] = Ogre::Vector3(-l2, h, w2);//17 + points[18] = Ogre::Vector3(l2, h, w2);//18 + points[19] = Ogre::Vector3(l2, h, -w2);//19 + + // bottom door + points[20] = Ogre::Vector3(-l2, -h, -w2);//20 + points[21] = Ogre::Vector3(-l2, -h, w2);//21 + points[22] = Ogre::Vector3(l2, -h, w2);//22 + points[23] = Ogre::Vector3(l2, -h, -w2);//23 + + // left door + points[24] = Ogre::Vector3(-l, h2, w2);//24 + points[25] = Ogre::Vector3(-l, -h2, w2);//25 + points[26] = Ogre::Vector3(-l, -h2, -w2);//26 + points[27] = Ogre::Vector3(-l, h2, -w2);//27 + + // right door + points[28] = Ogre::Vector3(l, h2, w2);//28 + points[29] = Ogre::Vector3(l, -h2, w2);//29 + points[30] = Ogre::Vector3(l, -h2, -w2);//30 + points[31] = Ogre::Vector3(l, h2, -w2);//31 } void RoomObject::createWalls(Ogre::ManualObject* room, - short doorFlags, - bool isEnclosure) + short doorFlags, + bool isEnclosure) { - if (isEnclosure) - { - if(doorFlags & DOOR_FRONT) - { - // make front wall outward facing with door - room->quad(0, 8, 11, 3); - room->quad(1, 9, 8, 0); - room->quad(2, 10, 9, 1); - room->quad(3, 11, 10, 2); - } - else - { - // make front wall outward facing without door - room->quad(0, 1, 2, 3); - } - if(doorFlags & DOOR_BACK) - { - // make back wall outward facing with door - room->quad(7, 15, 12, 4); - room->quad(6, 14, 15, 7); - room->quad(5, 13, 14, 6); - room->quad(4, 12, 13, 5); - } - else - { - // make back wall outward facing without door - room->quad(7, 6, 5, 4); - } - if(doorFlags & DOOR_TOP) - { - // make top wall outward facing with door - room->quad(0, 17, 16, 4); - room->quad(4, 16, 19, 7); - room->quad(7, 19, 18, 3); - room->quad(3, 18, 17, 0); - } - else - { - // make top wall outward facing without door - room->quad(0, 3, 7, 4); - } - if(doorFlags & DOOR_BOT) - { - // make bottom wall outward facing with door - room->quad(5, 20, 21, 1); - room->quad(6, 23, 20, 5); - room->quad(2, 22, 23, 6); - room->quad(1, 21, 22, 2); - } - else - { - // make bottom wall outward facing without door - room->quad(2, 1, 5, 6); - } - if(doorFlags & DOOR_LEFT) - { - // make left wall outward facing with door - room->quad(0, 24, 25, 1); - room->quad(4, 27, 24, 0); - room->quad(5, 26, 27, 4); - room->quad(1, 25, 26, 5); - } - else - { - // make left side wall outward facing without door - room->quad(1, 0, 4, 5); - } - if(doorFlags & DOOR_RIGHT) - { - // make right wall outward facing with door - room->quad(2, 29, 28, 3); - room->quad(6, 30, 29, 2); - room->quad(7, 31, 30, 6); - room->quad(3, 28, 31, 7); - } - else - { - // make right side wall outward facing without door - room->quad(3, 2, 6, 7); - } - } - else - { - // front back - if(doorFlags & DOOR_FRONT) - { - // make front wall inward facing with door - room->quad(3, 11, 8, 0); - room->quad(0, 8, 9, 1); - room->quad(1, 9, 10, 2); - room->quad(2, 10, 11, 3); - } - else - { - // make front wall inward facing without door - room->quad(3, 2, 1, 0); - } - if(doorFlags & DOOR_BACK) - { - // make back wall inward facing with door - room->quad(4, 12, 15, 7); - room->quad(7, 15, 14, 6); - room->quad(6, 14, 13, 5); - room->quad(5, 13, 12, 4); - } - else - { - // make back wall inward facing without door - room->quad(4, 5, 6, 7); - } - // top bottom - if(doorFlags & DOOR_TOP) - { - // make top wall inward facing with door - room->quad(4, 16, 17, 0); - room->quad(7, 19, 16, 4); - room->quad(3, 18, 19, 7); - room->quad(0, 17, 18, 3); - } - else - { - // make top wall inward facing without door - room->quad(4, 7, 3, 0); - } - if(doorFlags & DOOR_BOT) - { - // make bottom wall inward facing with door - room->quad(1, 21, 20, 5); - room->quad(5, 20, 23, 6); - room->quad(6, 23, 22, 2); - room->quad(2, 22, 21, 1); - } - else - { - // make bottom wall inward facing without door - room->quad(6, 5, 1, 2); - } - // end caps - if(doorFlags & DOOR_LEFT) - { - // make left wall inward facing with door - room->quad(1, 25, 24, 0); - room->quad(0, 24, 27, 4); - room->quad(4, 27, 26, 5); - room->quad(5, 26, 25, 1); - } - else - { - // make left side wall inward facing without door - room->quad(5, 4, 0, 1); - } - if(doorFlags & DOOR_RIGHT) - { - // make right wall inward facing with door - room->quad(3, 28, 29, 2); - room->quad(2, 29, 30, 6); - room->quad(6, 30, 31, 7); - room->quad(7, 31, 28, 3); - } - else - { - // make right side wall inward facing without door - room->quad(7, 6, 2, 3); - } - } + if (isEnclosure) + { + if(doorFlags & DOOR_FRONT) + { + // make front wall outward facing with door + room->quad(0, 8, 11, 3); + room->quad(1, 9, 8, 0); + room->quad(2, 10, 9, 1); + room->quad(3, 11, 10, 2); + } + else + { + // make front wall outward facing without door + room->quad(0, 1, 2, 3); + } + if(doorFlags & DOOR_BACK) + { + // make back wall outward facing with door + room->quad(7, 15, 12, 4); + room->quad(6, 14, 15, 7); + room->quad(5, 13, 14, 6); + room->quad(4, 12, 13, 5); + } + else + { + // make back wall outward facing without door + room->quad(7, 6, 5, 4); + } + if(doorFlags & DOOR_TOP) + { + // make top wall outward facing with door + room->quad(0, 17, 16, 4); + room->quad(4, 16, 19, 7); + room->quad(7, 19, 18, 3); + room->quad(3, 18, 17, 0); + } + else + { + // make top wall outward facing without door + room->quad(0, 3, 7, 4); + } + if(doorFlags & DOOR_BOT) + { + // make bottom wall outward facing with door + room->quad(5, 20, 21, 1); + room->quad(6, 23, 20, 5); + room->quad(2, 22, 23, 6); + room->quad(1, 21, 22, 2); + } + else + { + // make bottom wall outward facing without door + room->quad(2, 1, 5, 6); + } + if(doorFlags & DOOR_LEFT) + { + // make left wall outward facing with door + room->quad(0, 24, 25, 1); + room->quad(4, 27, 24, 0); + room->quad(5, 26, 27, 4); + room->quad(1, 25, 26, 5); + } + else + { + // make left side wall outward facing without door + room->quad(1, 0, 4, 5); + } + if(doorFlags & DOOR_RIGHT) + { + // make right wall outward facing with door + room->quad(2, 29, 28, 3); + room->quad(6, 30, 29, 2); + room->quad(7, 31, 30, 6); + room->quad(3, 28, 31, 7); + } + else + { + // make right side wall outward facing without door + room->quad(3, 2, 6, 7); + } + } + else + { + // front back + if(doorFlags & DOOR_FRONT) + { + // make front wall inward facing with door + room->quad(3, 11, 8, 0); + room->quad(0, 8, 9, 1); + room->quad(1, 9, 10, 2); + room->quad(2, 10, 11, 3); + } + else + { + // make front wall inward facing without door + room->quad(3, 2, 1, 0); + } + if(doorFlags & DOOR_BACK) + { + // make back wall inward facing with door + room->quad(4, 12, 15, 7); + room->quad(7, 15, 14, 6); + room->quad(6, 14, 13, 5); + room->quad(5, 13, 12, 4); + } + else + { + // make back wall inward facing without door + room->quad(4, 5, 6, 7); + } + // top bottom + if(doorFlags & DOOR_TOP) + { + // make top wall inward facing with door + room->quad(4, 16, 17, 0); + room->quad(7, 19, 16, 4); + room->quad(3, 18, 19, 7); + room->quad(0, 17, 18, 3); + } + else + { + // make top wall inward facing without door + room->quad(4, 7, 3, 0); + } + if(doorFlags & DOOR_BOT) + { + // make bottom wall inward facing with door + room->quad(1, 21, 20, 5); + room->quad(5, 20, 23, 6); + room->quad(6, 23, 22, 2); + room->quad(2, 22, 21, 1); + } + else + { + // make bottom wall inward facing without door + room->quad(6, 5, 1, 2); + } + // end caps + if(doorFlags & DOOR_LEFT) + { + // make left wall inward facing with door + room->quad(1, 25, 24, 0); + room->quad(0, 24, 27, 4); + room->quad(4, 27, 26, 5); + room->quad(5, 26, 25, 1); + } + else + { + // make left side wall inward facing without door + room->quad(5, 4, 0, 1); + } + if(doorFlags & DOOR_RIGHT) + { + // make right wall inward facing with door + room->quad(3, 28, 29, 2); + room->quad(2, 29, 30, 6); + room->quad(6, 30, 31, 7); + room->quad(7, 31, 28, 3); + } + else + { + // make right side wall inward facing without door + room->quad(7, 6, 2, 3); + } + } } // Create portals for every door void RoomObject::createPortals(Ogre::SceneManager *scene, - Ogre::ManualObject* room, - Ogre::SceneNode * roomNode, - Ogre::PCZone * zone, - short doorFlags, - bool isEnclosure) + Ogre::ManualObject* room, + Ogre::SceneNode * roomNode, + Ogre::PCZone * zone, + short doorFlags, + bool isEnclosure) { - Ogre::String portalName; - Vector3 corners[4]; - - if (isEnclosure) - { - if(doorFlags & DOOR_FRONT) - { - // set the corners to the front door corners - corners[0] = points[8]; - corners[1] = points[9]; - corners[2] = points[10]; - corners[3] = points[11]; - // create the portal - portalName = room->getName() + Ogre::String("_FrontDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_BACK) - { - // set the corners to the front door corners - corners[0] = points[15]; - corners[1] = points[14]; - corners[2] = points[13]; - corners[3] = points[12]; - // create the portal - portalName = room->getName() + Ogre::String("_BackDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_TOP) - { - // set the corners to the front door corners - corners[0] = points[16]; - corners[1] = points[17]; - corners[2] = points[18]; - corners[3] = points[19]; - // create the portal - portalName = room->getName() + Ogre::String("_TopDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_BOT) - { - // set the corners to the front door corners - corners[0] = points[23]; - corners[1] = points[22]; - corners[2] = points[21]; - corners[3] = points[20]; - // create the portal - portalName = room->getName() + Ogre::String("_BottomDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_LEFT) - { - // set the corners to the front door corners - corners[0] = points[27]; - corners[1] = points[26]; - corners[2] = points[25]; - corners[3] = points[24]; - // create the portal - portalName = room->getName() + Ogre::String("_LeftDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_RIGHT) - { - // set the corners to the front door corners - corners[0] = points[28]; - corners[1] = points[29]; - corners[2] = points[30]; - corners[3] = points[31]; - // create the portal - portalName = room->getName() + Ogre::String("_RightDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - } - else - { - if(doorFlags & DOOR_FRONT) - { - // set the corners to the front door corners - corners[0] = points[11]; - corners[1] = points[10]; - corners[2] = points[9]; - corners[3] = points[8]; - // create the portal - portalName = room->getName() + Ogre::String("_FrontDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_BACK) - { - // set the corners to the front door corners - corners[0] = points[12]; - corners[1] = points[13]; - corners[2] = points[14]; - corners[3] = points[15]; - // create the portal - portalName = room->getName() + Ogre::String("_BackDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_TOP) - { - // set the corners to the front door corners - corners[0] = points[19]; - corners[1] = points[18]; - corners[2] = points[17]; - corners[3] = points[16]; - // create the portal - portalName = room->getName() + Ogre::String("_TopDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_BOT) - { - // set the corners to the front door corners - corners[0] = points[20]; - corners[1] = points[21]; - corners[2] = points[22]; - corners[3] = points[23]; - // create the portal - portalName = room->getName() + Ogre::String("_BottomDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_LEFT) - { - // set the corners to the front door corners - corners[0] = points[24]; - corners[1] = points[25]; - corners[2] = points[26]; - corners[3] = points[27]; - // create the portal - portalName = room->getName() + Ogre::String("_LeftDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_RIGHT) - { - // set the corners to the front door corners - corners[0] = points[31]; - corners[1] = points[30]; - corners[2] = points[29]; - corners[3] = points[28]; - // create the portal - portalName = room->getName() + Ogre::String("_RightDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - } + Ogre::String portalName; + Vector3 corners[4]; + + if (isEnclosure) + { + if(doorFlags & DOOR_FRONT) + { + // set the corners to the front door corners + corners[0] = points[8]; + corners[1] = points[9]; + corners[2] = points[10]; + corners[3] = points[11]; + // create the portal + portalName = room->getName() + Ogre::String("_FrontDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_BACK) + { + // set the corners to the front door corners + corners[0] = points[15]; + corners[1] = points[14]; + corners[2] = points[13]; + corners[3] = points[12]; + // create the portal + portalName = room->getName() + Ogre::String("_BackDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_TOP) + { + // set the corners to the front door corners + corners[0] = points[16]; + corners[1] = points[17]; + corners[2] = points[18]; + corners[3] = points[19]; + // create the portal + portalName = room->getName() + Ogre::String("_TopDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_BOT) + { + // set the corners to the front door corners + corners[0] = points[23]; + corners[1] = points[22]; + corners[2] = points[21]; + corners[3] = points[20]; + // create the portal + portalName = room->getName() + Ogre::String("_BottomDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_LEFT) + { + // set the corners to the front door corners + corners[0] = points[27]; + corners[1] = points[26]; + corners[2] = points[25]; + corners[3] = points[24]; + // create the portal + portalName = room->getName() + Ogre::String("_LeftDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_RIGHT) + { + // set the corners to the front door corners + corners[0] = points[28]; + corners[1] = points[29]; + corners[2] = points[30]; + corners[3] = points[31]; + // create the portal + portalName = room->getName() + Ogre::String("_RightDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + } + else + { + if(doorFlags & DOOR_FRONT) + { + // set the corners to the front door corners + corners[0] = points[11]; + corners[1] = points[10]; + corners[2] = points[9]; + corners[3] = points[8]; + // create the portal + portalName = room->getName() + Ogre::String("_FrontDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_BACK) + { + // set the corners to the front door corners + corners[0] = points[12]; + corners[1] = points[13]; + corners[2] = points[14]; + corners[3] = points[15]; + // create the portal + portalName = room->getName() + Ogre::String("_BackDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_TOP) + { + // set the corners to the front door corners + corners[0] = points[19]; + corners[1] = points[18]; + corners[2] = points[17]; + corners[3] = points[16]; + // create the portal + portalName = room->getName() + Ogre::String("_TopDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_BOT) + { + // set the corners to the front door corners + corners[0] = points[20]; + corners[1] = points[21]; + corners[2] = points[22]; + corners[3] = points[23]; + // create the portal + portalName = room->getName() + Ogre::String("_BottomDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_LEFT) + { + // set the corners to the front door corners + corners[0] = points[24]; + corners[1] = points[25]; + corners[2] = points[26]; + corners[3] = points[27]; + // create the portal + portalName = room->getName() + Ogre::String("_LeftDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_RIGHT) + { + // set the corners to the front door corners + corners[0] = points[31]; + corners[1] = points[30]; + corners[2] = points[29]; + corners[3] = points[28]; + // create the portal + portalName = room->getName() + Ogre::String("_RightDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + } } // Create portals for every door void RoomObject::createPortals(Ogre::SceneManager *scene, - Ogre::Entity* room, - Ogre::SceneNode * roomNode, - Ogre::PCZone * zone, - short doorFlags, - bool isEnclosure) + Ogre::Entity* room, + Ogre::SceneNode * roomNode, + Ogre::PCZone * zone, + short doorFlags, + bool isEnclosure) { - Ogre::String portalName; - Vector3 corners[4]; - - if (isEnclosure) - { - if(doorFlags & DOOR_FRONT) - { - // set the corners to the front door corners - corners[0] = points[8]; - corners[1] = points[9]; - corners[2] = points[10]; - corners[3] = points[11]; - // create the portal - portalName = room->getName() + Ogre::String("_FrontDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_BACK) - { - // set the corners to the front door corners - corners[0] = points[15]; - corners[1] = points[14]; - corners[2] = points[13]; - corners[3] = points[12]; - // create the portal - portalName = room->getName() + Ogre::String("_BackDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_TOP) - { - // set the corners to the front door corners - corners[0] = points[16]; - corners[1] = points[17]; - corners[2] = points[18]; - corners[3] = points[19]; - // create the portal - portalName = room->getName() + Ogre::String("_TopDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_BOT) - { - // set the corners to the front door corners - corners[0] = points[23]; - corners[1] = points[22]; - corners[2] = points[21]; - corners[3] = points[20]; - // create the portal - portalName = room->getName() + Ogre::String("_BottomDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_LEFT) - { - // set the corners to the front door corners - corners[0] = points[27]; - corners[1] = points[26]; - corners[2] = points[25]; - corners[3] = points[24]; - // create the portal - portalName = room->getName() + Ogre::String("_LeftDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_RIGHT) - { - // set the corners to the front door corners - corners[0] = points[28]; - corners[1] = points[29]; - corners[2] = points[30]; - corners[3] = points[31]; - // create the portal - portalName = room->getName() + Ogre::String("_RightDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - } - else - { - if(doorFlags & DOOR_FRONT) - { - // set the corners to the front door corners - corners[0] = points[11]; - corners[1] = points[10]; - corners[2] = points[9]; - corners[3] = points[8]; - // create the portal - portalName = room->getName() + Ogre::String("_FrontDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_BACK) - { - // set the corners to the front door corners - corners[0] = points[12]; - corners[1] = points[13]; - corners[2] = points[14]; - corners[3] = points[15]; - // create the portal - portalName = room->getName() + Ogre::String("_BackDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_TOP) - { - // set the corners to the front door corners - corners[0] = points[19]; - corners[1] = points[18]; - corners[2] = points[17]; - corners[3] = points[16]; - // create the portal - portalName = room->getName() + Ogre::String("_TopDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_BOT) - { - // set the corners to the front door corners - corners[0] = points[20]; - corners[1] = points[21]; - corners[2] = points[22]; - corners[3] = points[23]; - // create the portal - portalName = room->getName() + Ogre::String("_BottomDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_LEFT) - { - // set the corners to the front door corners - corners[0] = points[24]; - corners[1] = points[25]; - corners[2] = points[26]; - corners[3] = points[27]; - // create the portal - portalName = room->getName() + Ogre::String("_LeftDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - if(doorFlags & DOOR_RIGHT) - { - // set the corners to the front door corners - corners[0] = points[31]; - corners[1] = points[30]; - corners[2] = points[29]; - corners[3] = points[28]; - // create the portal - portalName = room->getName() + Ogre::String("_RightDoorPortal"); - Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); - p->setCorners(corners); - // associate the portal with the roomnode - p->setNode(roomNode); - // add the portal to the zone - zone->_addPortal(p); - // update derived values for the portal - p->updateDerivedValues(); - } - } + Ogre::String portalName; + Vector3 corners[4]; + + if (isEnclosure) + { + if(doorFlags & DOOR_FRONT) + { + // set the corners to the front door corners + corners[0] = points[8]; + corners[1] = points[9]; + corners[2] = points[10]; + corners[3] = points[11]; + // create the portal + portalName = room->getName() + Ogre::String("_FrontDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_BACK) + { + // set the corners to the front door corners + corners[0] = points[15]; + corners[1] = points[14]; + corners[2] = points[13]; + corners[3] = points[12]; + // create the portal + portalName = room->getName() + Ogre::String("_BackDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_TOP) + { + // set the corners to the front door corners + corners[0] = points[16]; + corners[1] = points[17]; + corners[2] = points[18]; + corners[3] = points[19]; + // create the portal + portalName = room->getName() + Ogre::String("_TopDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_BOT) + { + // set the corners to the front door corners + corners[0] = points[23]; + corners[1] = points[22]; + corners[2] = points[21]; + corners[3] = points[20]; + // create the portal + portalName = room->getName() + Ogre::String("_BottomDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_LEFT) + { + // set the corners to the front door corners + corners[0] = points[27]; + corners[1] = points[26]; + corners[2] = points[25]; + corners[3] = points[24]; + // create the portal + portalName = room->getName() + Ogre::String("_LeftDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_RIGHT) + { + // set the corners to the front door corners + corners[0] = points[28]; + corners[1] = points[29]; + corners[2] = points[30]; + corners[3] = points[31]; + // create the portal + portalName = room->getName() + Ogre::String("_RightDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + } + else + { + if(doorFlags & DOOR_FRONT) + { + // set the corners to the front door corners + corners[0] = points[11]; + corners[1] = points[10]; + corners[2] = points[9]; + corners[3] = points[8]; + // create the portal + portalName = room->getName() + Ogre::String("_FrontDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_BACK) + { + // set the corners to the front door corners + corners[0] = points[12]; + corners[1] = points[13]; + corners[2] = points[14]; + corners[3] = points[15]; + // create the portal + portalName = room->getName() + Ogre::String("_BackDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_TOP) + { + // set the corners to the front door corners + corners[0] = points[19]; + corners[1] = points[18]; + corners[2] = points[17]; + corners[3] = points[16]; + // create the portal + portalName = room->getName() + Ogre::String("_TopDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_BOT) + { + // set the corners to the front door corners + corners[0] = points[20]; + corners[1] = points[21]; + corners[2] = points[22]; + corners[3] = points[23]; + // create the portal + portalName = room->getName() + Ogre::String("_BottomDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_LEFT) + { + // set the corners to the front door corners + corners[0] = points[24]; + corners[1] = points[25]; + corners[2] = points[26]; + corners[3] = points[27]; + // create the portal + portalName = room->getName() + Ogre::String("_LeftDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + if(doorFlags & DOOR_RIGHT) + { + // set the corners to the front door corners + corners[0] = points[31]; + corners[1] = points[30]; + corners[2] = points[29]; + corners[3] = points[28]; + // create the portal + portalName = room->getName() + Ogre::String("_RightDoorPortal"); + Portal * p = ((PCZSceneManager*)scene)->createPortal(portalName); + p->setCorners(corners); + // associate the portal with the roomnode + p->setNode(roomNode); + // add the portal to the zone + zone->_addPortal(p); + // update derived values for the portal + p->updateDerivedValues(); + } + } } diff --git a/Samples/PNTrianglesTessellation/include/PNTrianglesTessellation.h b/Samples/PNTrianglesTessellation/include/PNTrianglesTessellation.h index cbc6922de00..66bf78a3394 100644 --- a/Samples/PNTrianglesTessellation/include/PNTrianglesTessellation.h +++ b/Samples/PNTrianglesTessellation/include/PNTrianglesTessellation.h @@ -1,6 +1,6 @@ /** -* Modified by: Juan Camilo Acosta Arango (ja0335 ) -* Date: 09-04-2014 +* Modified by: Juan Camilo Acosta Arango (ja0335 ) +* Date: 09-04-2014 **/ #ifndef __PNTriangles_H__ @@ -17,273 +17,273 @@ class _OgreSampleClassExport Sample_PNTriangles : public SdkSample { public: - Sample_PNTriangles() - : mMoveLights (true) - { - mInfo["Title"] = "PNTriangles"; - mInfo["Description"] = "Sample for parametric PN-Triangles tessellation algorithm"; - mInfo["Thumbnail"] = "thumb_tessellation.png"; - mInfo["Category"] = "Unsorted"; - mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; - } - - void testCapabilities(const RenderSystemCapabilities* caps) - { - if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" - " programs, so you cannot run this sample. Sorry!", "Sample_PNTrianglesTessellation::testCapabilities"); - } - if (!caps->hasCapability(RSC_TESSELLATION_HULL_PROGRAM) || !caps->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Your graphics card does not support tessellation shaders. Sorry!", - "Sample_PNTrianglesTessellation:testCapabilities"); - } - if (!GpuProgramManager::getSingleton().isSyntaxSupported("vs_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("hs_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ds_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("hlsl")) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model 5.0 needed for this sample, " - "so you cannot run this sample. Sorry!", "Sample_PNTrianglesTessellation::testCapabilities"); - } - } - - bool frameRenderingQueued(const FrameEvent& evt) - { - if (mMoveLights) - { - // rotate the light pivots - mLightPivot1->roll(Degree(evt.timeSinceLastFrame * 10)); - mLightPivot2->roll(Degree(evt.timeSinceLastFrame * 15)); - } - - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! - } - - void itemSelected(SelectMenu* menu) - { - if (menu == mMeshMenu) - { - // change to the selected entity - mObjectNode->detachAllObjects(); - mObjectNode->attachObject(mSceneMgr->getEntity(mMeshMenu->getSelectedItem())); - - // remember which material is currently selected - int index = std::max(0, mMaterialMenu->getSelectionIndex()); - - // update the material menu's options - mMaterialMenu->setItems(mPossibilities[mMeshMenu->getSelectedItem()]); - - mMaterialMenu->selectItem(index); // select the material with the saved index - } - else - { - // set the selected material for the active mesh - ((Entity*)mObjectNode->getAttachedObject(0))->setMaterialName(menu->getSelectedItem()); - - if( menu->getSelectionIndex() == 2 ) - mTessellationAmount->show(); - else - mTessellationAmount->hide(); - } - } - - void checkBoxToggled(CheckBox* box) - { - if (box->getName() == "Wire") - { - if( mCamera->getPolygonMode() == PM_WIREFRAME ) - mCamera->setPolygonMode(PM_SOLID); - else - mCamera->setPolygonMode(PM_WIREFRAME); - } - else if (StringUtil::startsWith(box->getName(), "Light", false)) - { - // get the light pivot that corresponds to this checkbox - SceneNode* pivot = box->getName() == "Light1" ? mLightPivot1 : mLightPivot2; - SceneNode::ObjectIterator it = pivot->getAttachedObjectIterator(); - - while (it.hasMoreElements()) // toggle visibility of light and billboard set - { - MovableObject* o = it.getNext(); - o->setVisible(box->isChecked()); - } - - } - else if (box->getName() == "MoveLights") - { - mMoveLights = !mMoveLights; - } - } - - void sliderMoved(Slider* slider) - { - if( slider->getName() == "tessellationAmount" ) - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( mMaterialMenu->getSelectedItem() ); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_tessellationAmount", slider->getValue() ); - } - } + Sample_PNTriangles() + : mMoveLights (true) + { + mInfo["Title"] = "PNTriangles"; + mInfo["Description"] = "Sample for parametric PN-Triangles tessellation algorithm"; + mInfo["Thumbnail"] = "thumb_tessellation.png"; + mInfo["Category"] = "Unsorted"; + mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; + } + + void testCapabilities(const RenderSystemCapabilities* caps) + { + if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" + " programs, so you cannot run this sample. Sorry!", "Sample_PNTrianglesTessellation::testCapabilities"); + } + if (!caps->hasCapability(RSC_TESSELLATION_HULL_PROGRAM) || !caps->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Your graphics card does not support tessellation shaders. Sorry!", + "Sample_PNTrianglesTessellation:testCapabilities"); + } + if (!GpuProgramManager::getSingleton().isSyntaxSupported("vs_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("hs_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ds_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("hlsl")) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model 5.0 needed for this sample, " + "so you cannot run this sample. Sorry!", "Sample_PNTrianglesTessellation::testCapabilities"); + } + } + + bool frameRenderingQueued(const FrameEvent& evt) + { + if (mMoveLights) + { + // rotate the light pivots + mLightPivot1->roll(Degree(evt.timeSinceLastFrame * 10)); + mLightPivot2->roll(Degree(evt.timeSinceLastFrame * 15)); + } + + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + } + + void itemSelected(SelectMenu* menu) + { + if (menu == mMeshMenu) + { + // change to the selected entity + mObjectNode->detachAllObjects(); + mObjectNode->attachObject(mSceneMgr->getEntity(mMeshMenu->getSelectedItem())); + + // remember which material is currently selected + int index = std::max(0, mMaterialMenu->getSelectionIndex()); + + // update the material menu's options + mMaterialMenu->setItems(mPossibilities[mMeshMenu->getSelectedItem()]); + + mMaterialMenu->selectItem(index); // select the material with the saved index + } + else + { + // set the selected material for the active mesh + ((Entity*)mObjectNode->getAttachedObject(0))->setMaterialName(menu->getSelectedItem()); + + if( menu->getSelectionIndex() == 2 ) + mTessellationAmount->show(); + else + mTessellationAmount->hide(); + } + } + + void checkBoxToggled(CheckBox* box) + { + if (box->getName() == "Wire") + { + if( mCamera->getPolygonMode() == PM_WIREFRAME ) + mCamera->setPolygonMode(PM_SOLID); + else + mCamera->setPolygonMode(PM_WIREFRAME); + } + else if (StringUtil::startsWith(box->getName(), "Light", false)) + { + // get the light pivot that corresponds to this checkbox + SceneNode* pivot = box->getName() == "Light1" ? mLightPivot1 : mLightPivot2; + SceneNode::ObjectIterator it = pivot->getAttachedObjectIterator(); + + while (it.hasMoreElements()) // toggle visibility of light and billboard set + { + MovableObject* o = it.getNext(); + o->setVisible(box->isChecked()); + } + + } + else if (box->getName() == "MoveLights") + { + mMoveLights = !mMoveLights; + } + } + + void sliderMoved(Slider* slider) + { + if( slider->getName() == "tessellationAmount" ) + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( mMaterialMenu->getSelectedItem() ); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_tessellationAmount", slider->getValue() ); + } + } protected: - void setupContent() - { - // create our main node to attach our entities to - mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - - setupModels(); - setupLights(); - setupControls(); - - // set our camera - mCamera->setFOVy(Ogre::Degree(50.0)); - mCamera->setFOVy(Ogre::Degree(50.0)); - mCamera->setNearClipDistance(0.01f); - mCamera->lookAt(Ogre::Vector3::ZERO); - mCamera->setPosition(0, 0, 500); - - - // Set our camera to orbit around the origin at a suitable distance - mCameraMan->setStyle(CS_ORBIT); - mCameraMan->setYawPitchDist(Radian(0), Radian(0), 400); - - mTrayMgr->showCursor(); - } - - void unloadResources() - { - - } - - void setupModels() - { - StringVector matNames; - - matNames.push_back("Ogre/NoTessellation"); - matNames.push_back("Ogre/TessellationExample"); - matNames.push_back("Ogre/SimpleTessellation"); - //matNames.push_back("Ogre/AdaptiveTessellation"); - matNames.push_back("Ogre/AdaptivePNTrianglesTessellation"); - - mPossibilities["ogrehead.mesh"] = matNames; - mPossibilities["knot.mesh"] = matNames; - mPossibilities["uv_sphere.mesh"] = matNames; - - for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) - { - // load each mesh with non-default hardware buffer usage options - MeshPtr mesh = MeshManager::getSingleton().load(it->first, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); + void setupContent() + { + // create our main node to attach our entities to + mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + + setupModels(); + setupLights(); + setupControls(); + + // set our camera + mCamera->setFOVy(Ogre::Degree(50.0)); + mCamera->setFOVy(Ogre::Degree(50.0)); + mCamera->setNearClipDistance(0.01f); + mCamera->lookAt(Ogre::Vector3::ZERO); + mCamera->setPosition(0, 0, 500); + + + // Set our camera to orbit around the origin at a suitable distance + mCameraMan->setStyle(CS_ORBIT); + mCameraMan->setYawPitchDist(Radian(0), Radian(0), 400); + + mTrayMgr->showCursor(); + } + + void unloadResources() + { + + } + + void setupModels() + { + StringVector matNames; + + matNames.push_back("Ogre/NoTessellation"); + matNames.push_back("Ogre/TessellationExample"); + matNames.push_back("Ogre/SimpleTessellation"); + //matNames.push_back("Ogre/AdaptiveTessellation"); + matNames.push_back("Ogre/AdaptivePNTrianglesTessellation"); + + mPossibilities["ogrehead.mesh"] = matNames; + mPossibilities["knot.mesh"] = matNames; + mPossibilities["uv_sphere.mesh"] = matNames; + + for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) + { + // load each mesh with non-default hardware buffer usage options + MeshPtr mesh = MeshManager::getSingleton().load(it->first, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // build tangent vectors for our mesh unsigned short src, dest; if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) { mesh->buildTangentVectors(VES_TANGENT, src, dest); - // this version cleans mirrored and rotated UVs but requires quality models - // mesh->buildTangentVectors(VES_TANGENT, src, dest, true, true); + // this version cleans mirrored and rotated UVs but requires quality models + // mesh->buildTangentVectors(VES_TANGENT, src, dest, true, true); } - // create an entity from the mesh and set the first available material - Entity* ent = mSceneMgr->createEntity(mesh->getName(), mesh->getName()); - ent->setMaterialName(it->second.front()); - } - } - - void setupLights() - { - mSceneMgr->setAmbientLight(ColourValue::Black); - mViewport->setBackgroundColour(ColourValue(0.41f, 0.41f, 0.41f)); - - // create pivot nodes - mLightPivot1 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mLightPivot2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - - Light* l; - BillboardSet* bbs; - - // create white light - l = mSceneMgr->createLight(); - l->setDiffuseColour(1.0f, 1.0f, 1.0f); - l->setSpecularColour(1.0f, 1.0f, 1.0f); - l->setDirection(Ogre::Vector3::UNIT_X*-1.0f); - l->setPosition(200, 0, 0); - // create white flare - bbs = mSceneMgr->createBillboardSet(); - bbs->setMaterialName("Examples/Flare"); - bbs->createBillboard(200, 0, 0)->setColour(ColourValue::White); - - mLightPivot1->attachObject(l); - mLightPivot1->attachObject(bbs); - - // create red light - l = mSceneMgr->createLight(); - l->setDiffuseColour(1.0f, 0.0f, 0.0f); - l->setSpecularColour(1.0f, 0.0f, 0.0f); - l->setDirection(Ogre::Vector3::UNIT_X); - l->setPosition(-200, 0, 0); - // create white flare - bbs = mSceneMgr->createBillboardSet(); - bbs->setMaterialName("Examples/Flare"); - bbs->createBillboard(-200, 0, 0)->setColour(ColourValue::Red); - - mLightPivot2->attachObject(l); - mLightPivot2->attachObject(bbs); - } - - void setupControls() - { - mTrayMgr->showCursor(); - - // make room for the controls - mTrayMgr->showLogo(TL_TOPRIGHT); - mTrayMgr->showFrameStats(TL_TOPRIGHT); - mTrayMgr->toggleAdvancedFrameStats(); - - // create a menu to choose the model displayed - mMeshMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "Mesh", "Mesh", 370, 290, 10); - for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) - mMeshMenu->addItem(it->first); - - // create a menu to choose the material used by the model - mMaterialMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "Material", "Material", 370, 290, 10); - - mTrayMgr->createCheckBox(TL_TOPLEFT, "Wire", "Wire Frame")->setChecked(false, false); - // create checkboxes to toggle lights - mTrayMgr->createCheckBox(TL_TOPLEFT, "Light1", "Light A")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Light2", "Light B")->setChecked(true, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "MoveLights", "Move Lights")->setChecked(true, false); - - mTessellationAmount = mTrayMgr->createThickSlider(TL_TOPLEFT, "tessellationAmount", "Tessellation Amount", 200, 40, 1, 8, 8); - mTessellationAmount->hide(); - - // a friendly reminder - StringVector names; - names.push_back("Help"); - mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); - - mMeshMenu->selectItem(0); // select first mesh - } - - void cleanupContent() - { - // clean up properly to avoid interfering with subsequent samples - for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) - MeshManager::getSingleton().unload(it->first); - mPossibilities.clear(); - } - - std::map mPossibilities; - SceneNode* mObjectNode; - SceneNode* mLightPivot1; - SceneNode* mLightPivot2; - bool mMoveLights; - SelectMenu* mMeshMenu; - SelectMenu* mMaterialMenu; - Slider* mTessellationAmount; + // create an entity from the mesh and set the first available material + Entity* ent = mSceneMgr->createEntity(mesh->getName(), mesh->getName()); + ent->setMaterialName(it->second.front()); + } + } + + void setupLights() + { + mSceneMgr->setAmbientLight(ColourValue::Black); + mViewport->setBackgroundColour(ColourValue(0.41f, 0.41f, 0.41f)); + + // create pivot nodes + mLightPivot1 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mLightPivot2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + + Light* l; + BillboardSet* bbs; + + // create white light + l = mSceneMgr->createLight(); + l->setDiffuseColour(1.0f, 1.0f, 1.0f); + l->setSpecularColour(1.0f, 1.0f, 1.0f); + l->setDirection(Ogre::Vector3::UNIT_X*-1.0f); + l->setPosition(200, 0, 0); + // create white flare + bbs = mSceneMgr->createBillboardSet(); + bbs->setMaterialName("Examples/Flare"); + bbs->createBillboard(200, 0, 0)->setColour(ColourValue::White); + + mLightPivot1->attachObject(l); + mLightPivot1->attachObject(bbs); + + // create red light + l = mSceneMgr->createLight(); + l->setDiffuseColour(1.0f, 0.0f, 0.0f); + l->setSpecularColour(1.0f, 0.0f, 0.0f); + l->setDirection(Ogre::Vector3::UNIT_X); + l->setPosition(-200, 0, 0); + // create white flare + bbs = mSceneMgr->createBillboardSet(); + bbs->setMaterialName("Examples/Flare"); + bbs->createBillboard(-200, 0, 0)->setColour(ColourValue::Red); + + mLightPivot2->attachObject(l); + mLightPivot2->attachObject(bbs); + } + + void setupControls() + { + mTrayMgr->showCursor(); + + // make room for the controls + mTrayMgr->showLogo(TL_TOPRIGHT); + mTrayMgr->showFrameStats(TL_TOPRIGHT); + mTrayMgr->toggleAdvancedFrameStats(); + + // create a menu to choose the model displayed + mMeshMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "Mesh", "Mesh", 370, 290, 10); + for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) + mMeshMenu->addItem(it->first); + + // create a menu to choose the material used by the model + mMaterialMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "Material", "Material", 370, 290, 10); + + mTrayMgr->createCheckBox(TL_TOPLEFT, "Wire", "Wire Frame")->setChecked(false, false); + // create checkboxes to toggle lights + mTrayMgr->createCheckBox(TL_TOPLEFT, "Light1", "Light A")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Light2", "Light B")->setChecked(true, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "MoveLights", "Move Lights")->setChecked(true, false); + + mTessellationAmount = mTrayMgr->createThickSlider(TL_TOPLEFT, "tessellationAmount", "Tessellation Amount", 200, 40, 1, 8, 8); + mTessellationAmount->hide(); + + // a friendly reminder + StringVector names; + names.push_back("Help"); + mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); + + mMeshMenu->selectItem(0); // select first mesh + } + + void cleanupContent() + { + // clean up properly to avoid interfering with subsequent samples + for (std::map::iterator it = mPossibilities.begin(); it != mPossibilities.end(); it++) + MeshManager::getSingleton().unload(it->first); + mPossibilities.clear(); + } + + std::map mPossibilities; + SceneNode* mObjectNode; + SceneNode* mLightPivot1; + SceneNode* mLightPivot2; + bool mMoveLights; + SelectMenu* mMeshMenu; + SelectMenu* mMaterialMenu; + Slider* mTessellationAmount; }; diff --git a/Samples/PNTrianglesTessellation/src/PNTrianglesTessellation.cpp b/Samples/PNTrianglesTessellation/src/PNTrianglesTessellation.cpp index 7bf46759299..78d6ee56978 100644 --- a/Samples/PNTrianglesTessellation/src/PNTrianglesTessellation.cpp +++ b/Samples/PNTrianglesTessellation/src/PNTrianglesTessellation.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_PNTriangles; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_PNTriangles; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/ParticleFX/include/ParticleFX.h b/Samples/ParticleFX/include/ParticleFX.h index 9dba7f887ca..8d9ef0133c8 100644 --- a/Samples/ParticleFX/include/ParticleFX.h +++ b/Samples/ParticleFX/include/ParticleFX.h @@ -11,62 +11,62 @@ class _OgreSampleClassExport Sample_ParticleFX : public SdkSample { public: - Sample_ParticleFX() - { - mInfo["Title"] = "Particle Effects"; - mInfo["Description"] = "Demonstrates the creation and usage of particle effects."; - mInfo["Thumbnail"] = "thumb_particles.png"; - mInfo["Category"] = "Effects"; - mInfo["Help"] = "Use the checkboxes to toggle visibility of the individual particle systems."; - } + Sample_ParticleFX() + { + mInfo["Title"] = "Particle Effects"; + mInfo["Description"] = "Demonstrates the creation and usage of particle effects."; + mInfo["Thumbnail"] = "thumb_particles.png"; + mInfo["Category"] = "Effects"; + mInfo["Help"] = "Use the checkboxes to toggle visibility of the individual particle systems."; + } bool frameRenderingQueued(const FrameEvent& evt) { - mFountainPivot->yaw(Degree(evt.timeSinceLastFrame * 30)); // spin the fountains around + mFountainPivot->yaw(Degree(evt.timeSinceLastFrame * 30)); // spin the fountains around - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! } - void checkBoxToggled(CheckBox* box) - { - // show or hide the particle system with the same name as the check box - mSceneMgr->getParticleSystem(box->getName())->setVisible(box->isChecked()); - } + void checkBoxToggled(CheckBox* box) + { + // show or hide the particle system with the same name as the check box + mSceneMgr->getParticleSystem(box->getName())->setVisible(box->isChecked()); + } protected: - void setupContent() - { - // setup some basic lighting for our scene - mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); - mSceneMgr->createLight()->setPosition(20, 80, 50); + void setupContent() + { + // setup some basic lighting for our scene + mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); + mSceneMgr->createLight()->setPosition(20, 80, 50); - // set our camera to orbit around the origin and show cursor - mCameraMan->setStyle(CS_ORBIT); - mCameraMan->setYawPitchDist(Degree(0), Degree(15), 250); - mTrayMgr->showCursor(); + // set our camera to orbit around the origin and show cursor + mCameraMan->setStyle(CS_ORBIT); + mCameraMan->setYawPitchDist(Degree(0), Degree(15), 250); + mTrayMgr->showCursor(); - // create an ogre head entity and place it at the origin + // create an ogre head entity and place it at the origin Entity* ent = mSceneMgr->createEntity("Head", "ogrehead.mesh"); mSceneMgr->getRootSceneNode()->attachObject(ent); - - setupParticles(); // setup particles - setupTogglers(); // setup particle togglers - } + + setupParticles(); // setup particles + setupTogglers(); // setup particle togglers + } - void setupParticles() - { - ParticleSystem::setDefaultNonVisibleUpdateTimeout(5); // set nonvisible timeout + void setupParticles() + { + ParticleSystem::setDefaultNonVisibleUpdateTimeout(5); // set nonvisible timeout - ParticleSystem* ps; + ParticleSystem* ps; // create some nice fireworks and place it at the origin ps = mSceneMgr->createParticleSystem("Fireworks", "Examples/Fireworks"); - mSceneMgr->getRootSceneNode()->attachObject(ps); + mSceneMgr->getRootSceneNode()->attachObject(ps); // create a green nimbus around the ogre head ps = mSceneMgr->createParticleSystem("Nimbus", "Examples/GreenyNimbus"); - mSceneMgr->getRootSceneNode()->attachObject(ps); + mSceneMgr->getRootSceneNode()->attachObject(ps); ps = mSceneMgr->createParticleSystem("Rain", "Examples/Rain"); // create a rainstorm ps->fastForward(5); // fast-forward the rain so it looks more natural @@ -81,26 +81,26 @@ class _OgreSampleClassExport Sample_ParticleFX : public SdkSample ps = mSceneMgr->createParticleSystem("Fountain1", "Examples/PurpleFountain"); // create fountain 1 // attach the fountain to a child node of the pivot at a distance and angle - mFountainPivot->createChildSceneNode(Vector3(200, -100, 0), Quaternion(Degree(20), Vector3::UNIT_Z))->attachObject(ps); + mFountainPivot->createChildSceneNode(Vector3(200, -100, 0), Quaternion(Degree(20), Vector3::UNIT_Z))->attachObject(ps); ps = mSceneMgr->createParticleSystem("Fountain2", "Examples/PurpleFountain"); // create fountain 2 // attach the fountain to a child node of the pivot at a distance and angle - mFountainPivot->createChildSceneNode(Vector3(-200, -100, 0), Quaternion(Degree(-20), Vector3::UNIT_Z))->attachObject(ps); - } - - void setupTogglers() - { - // create check boxes to toggle the visibility of our particle systems - mTrayMgr->createLabel(TL_TOPLEFT, "VisLabel", "Particles"); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Fireworks", "Fireworks", 130)->setChecked(true); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Fountain1", "Fountain A", 130)->setChecked(true); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Fountain2", "Fountain B", 130)->setChecked(true); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Aureola", "Aureola", 130)->setChecked(false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Nimbus", "Nimbus", 130)->setChecked(false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Rain", "Rain", 130)->setChecked(false); - } - - SceneNode* mFountainPivot; + mFountainPivot->createChildSceneNode(Vector3(-200, -100, 0), Quaternion(Degree(-20), Vector3::UNIT_Z))->attachObject(ps); + } + + void setupTogglers() + { + // create check boxes to toggle the visibility of our particle systems + mTrayMgr->createLabel(TL_TOPLEFT, "VisLabel", "Particles"); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Fireworks", "Fireworks", 130)->setChecked(true); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Fountain1", "Fountain A", 130)->setChecked(true); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Fountain2", "Fountain B", 130)->setChecked(true); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Aureola", "Aureola", 130)->setChecked(false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Nimbus", "Nimbus", 130)->setChecked(false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Rain", "Rain", 130)->setChecked(false); + } + + SceneNode* mFountainPivot; }; #endif diff --git a/Samples/ParticleFX/src/ParticleFX.cpp b/Samples/ParticleFX/src/ParticleFX.cpp index b6ddd35277a..3b859fbb827 100644 --- a/Samples/ParticleFX/src/ParticleFX.cpp +++ b/Samples/ParticleFX/src/ParticleFX.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_ParticleFX; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_ParticleFX; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/ParticleGS/include/RandomTools.h b/Samples/ParticleGS/include/RandomTools.h index 6bc3be6b187..6bec729a10e 100644 --- a/Samples/ParticleGS/include/RandomTools.h +++ b/Samples/ParticleGS/include/RandomTools.h @@ -6,7 +6,7 @@ class RandomTools { public: - static Ogre::TexturePtr generateRandomVelocityTexture(); + static Ogre::TexturePtr generateRandomVelocityTexture(); }; #endif diff --git a/Samples/SSAO/include/SSAO.h b/Samples/SSAO/include/SSAO.h index 31cafca5a52..4360c4c2e94 100644 --- a/Samples/SSAO/include/SSAO.h +++ b/Samples/SSAO/include/SSAO.h @@ -62,50 +62,50 @@ using namespace OgreBites; class _OgreSampleClassExport SSAOGBufferSchemeHandler : public Ogre::MaterialManager::Listener { public: - SSAOGBufferSchemeHandler() - { - mGBufRefMat = Ogre::MaterialManager::getSingleton().getByName("SSAO/GBuffer"); - } + SSAOGBufferSchemeHandler() + { + mGBufRefMat = Ogre::MaterialManager::getSingleton().getByName("SSAO/GBuffer"); + } - virtual ~SSAOGBufferSchemeHandler() - { - mGBufRefMat.setNull(); - } + virtual ~SSAOGBufferSchemeHandler() + { + mGBufRefMat.setNull(); + } - /** @copydoc MaterialManager::Listener::handleSchemeNotFound */ - virtual Ogre::Technique* handleSchemeNotFound(unsigned short schemeIndex, - const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, - const Ogre::Renderable* rend) - { - Technique* gBufferTech = originalMaterial->createTechnique(); - gBufferTech->setSchemeName(schemeName); - Ogre::Pass* gbufPass = gBufferTech->createPass(); - *gbufPass = *mGBufRefMat->getTechnique(0)->getPass(0); - return gBufferTech; - } + /** @copydoc MaterialManager::Listener::handleSchemeNotFound */ + virtual Ogre::Technique* handleSchemeNotFound(unsigned short schemeIndex, + const Ogre::String& schemeName, Ogre::Material* originalMaterial, unsigned short lodIndex, + const Ogre::Renderable* rend) + { + Technique* gBufferTech = originalMaterial->createTechnique(); + gBufferTech->setSchemeName(schemeName); + Ogre::Pass* gbufPass = gBufferTech->createPass(); + *gbufPass = *mGBufRefMat->getTechnique(0)->getPass(0); + return gBufferTech; + } private: - Ogre::MaterialPtr mGBufRefMat; + Ogre::MaterialPtr mGBufRefMat; }; class _OgreSampleClassExport Sample_SSAO : public SdkSample { private: - std::vector mMeshNames; - std::vector mMeshes; - int mCurrentMeshIndex; + std::vector mMeshNames; + std::vector mMeshes; + int mCurrentMeshIndex; + + std::vector mCompositorNames; + String mCurrentCompositor; - std::vector mCompositorNames; - String mCurrentCompositor; - - std::vector mPostNames; - String mCurrentPost; - String mCurrentModulateScheme; + std::vector mPostNames; + String mCurrentPost; + String mCurrentModulateScheme; - SSAOGBufferSchemeHandler* mGBufSchemeHandler; + SSAOGBufferSchemeHandler* mGBufSchemeHandler; Light* mLight; public: - Sample_SSAO() + Sample_SSAO() { mInfo["Title"] = "SSAO Techniques"; mInfo["Description"] = "A demo of several Screen Space Ambient Occlusion (SSAO) shading techniques using compositors."; @@ -129,19 +129,19 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample mPostNames.push_back("SSAO/Post/CrossBilateralFilter"); mPostNames.push_back("SSAO/Post/SmartBoxFilter"); mPostNames.push_back("SSAO/Post/BoxFilter"); - + mCurrentCompositor = mCompositorNames[0]; mCurrentPost = mPostNames[0]; - mGBufSchemeHandler = NULL; - mLight = NULL; + mGBufSchemeHandler = NULL; + mLight = NULL; } void cleanupContent() { - MaterialManager::getSingleton().removeListener(mGBufSchemeHandler, "GBuffer"); - delete mGBufSchemeHandler; - mGBufSchemeHandler = NULL; + MaterialManager::getSingleton().removeListener(mGBufSchemeHandler, "GBuffer"); + delete mGBufSchemeHandler; + mGBufSchemeHandler = NULL; CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCurrentCompositor, false); CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCurrentPost, false); @@ -179,18 +179,18 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" " programs, so you cannot run this sample. Sorry!", "Sample_SSAO::testCapabilities"); } - if (!(caps->getRenderSystemName() == "OpenGL Rendering Subsystem" || caps->getRenderSystemName() == "Direct3D9 Rendering Subsystem" || - caps->getRenderSystemName() == "Direct3D11 Rendering Subsystem")) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "This demo currently only supports OpenGL and DirectX9. Sorry!", - "Sample_SSAO:testCapabilities"); - } + if (!(caps->getRenderSystemName() == "OpenGL Rendering Subsystem" || caps->getRenderSystemName() == "Direct3D9 Rendering Subsystem" || + caps->getRenderSystemName() == "Direct3D11 Rendering Subsystem")) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "This demo currently only supports OpenGL and DirectX9. Sorry!", + "Sample_SSAO:testCapabilities"); + } } protected: - /** - * Setup the compositors to be used. - */ + /** + * Setup the compositors to be used. + */ void setupCompositors() { @@ -220,9 +220,9 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCurrentPost, true); } - /** - * Setup the controls, ie. the gui elements. - */ + /** + * Setup the controls, ie. the gui elements. + */ void setupControls(void) { // --- select mesh menu --- @@ -310,9 +310,9 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample 10, 101); // snaps ??? // --- sample length parameter --- - mTrayMgr->createSeparator(TL_TOPLEFT, "sep"); + mTrayMgr->createSeparator(TL_TOPLEFT, "sep"); - mTrayMgr->createCheckBox(TL_TOPLEFT, SSAO_MODUALTE, "Modulate with scene", SSAO_GUI_WIDTH); + mTrayMgr->createCheckBox(TL_TOPLEFT, SSAO_MODUALTE, "Modulate with scene", SSAO_GUI_WIDTH); // --- sample length parameter --- mTrayMgr->createSeparator(TL_TOPLEFT, "sep2"); @@ -419,16 +419,16 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample mTrayMgr->showCursor(); } - /** - * Create the scene and load the content. - */ + /** + * Create the scene and load the content. + */ void setupContent() { mViewport->setBackgroundColour(ColourValue(0.5, 0.5, 0.5, 1)); // set our camera to orbit around the origin and show cursor mCameraMan->setStyle(CS_FREELOOK); - mCameraMan->setTopSpeed(20.0); + mCameraMan->setTopSpeed(20.0); mCamera->move(Vector3(0, 10, 0)); mCamera->setFOVy(Radian(Degree(45).valueRadians())); // i.e. 60deg * 1.3.. maya and ogre use fovX and fovY mCamera->setFarClipDistance(400); @@ -457,14 +457,14 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample changeCompositor(mCompositorNames[0]); changePost(mPostNames[0]); - mGBufSchemeHandler = new SSAOGBufferSchemeHandler(); - MaterialManager::getSingleton().addListener(mGBufSchemeHandler, "GBuffer"); + mGBufSchemeHandler = new SSAOGBufferSchemeHandler(); + MaterialManager::getSingleton().addListener(mGBufSchemeHandler, "GBuffer"); } - /** - * Change the current displayed mesh to the new mesh identified by its index. - * @param index The index of the new mesh in the mesh vector. - */ + /** + * Change the current displayed mesh to the new mesh identified by its index. + * @param index The index of the new mesh in the mesh vector. + */ void changeMesh(int index) { mMeshes[mCurrentMeshIndex]->setVisible(false); @@ -472,10 +472,10 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample mCurrentMeshIndex = index; } - /** - * Change the compositor to be used. - * @param compositor The name of the compositor - */ + /** + * Change the compositor to be used. + * @param compositor The name of the compositor + */ void changeCompositor(Ogre::String compositor) { CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCurrentCompositor, false); @@ -583,17 +583,17 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample } } - /** - * Change the post filter to be used. - * @param post The name of the new post processing filter. - */ + /** + * Change the post filter to be used. + * @param post The name of the new post processing filter. + */ void changePost(Ogre::String post) { CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCurrentPost, false); mCurrentPost = post; CompositorManager::getSingleton().setCompositorEnabled(mViewport, mCurrentPost, true); - - if (post == "SSAO/Post/CrossBilateralFilter") + + if (post == "SSAO/Post/CrossBilateralFilter") { mTrayMgr->getWidget(SSAO_BILATERAL_PHOTOMETRIC_EXPONENT)->show(); mTrayMgr->moveWidgetToTray(SSAO_BILATERAL_PHOTOMETRIC_EXPONENT, TL_TOPLEFT); @@ -605,7 +605,7 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample } } - // sdkTray listener callbacks + // sdkTray listener callbacks void itemSelected(SelectMenu* menu) { if (menu->getName() == SSAO_OBJECT_MENU_NAME) @@ -615,7 +615,7 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample changeCompositor(menu->getSelectedItem()); else if (menu->getName() == SSAO_POST_MENU_NAME) - changePost(menu->getSelectedItem()); + changePost(menu->getSelectedItem()); else if (menu->getName() == SSAO_CAMERA_MENU_NAME) { @@ -700,24 +700,24 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample void checkBoxToggled(OgreBites::CheckBox *box) { - if(box->getName() == SSAO_MODUALTE) - { - if (box->isChecked()) - { - CompositorManager::getSingleton().addCompositor(mViewport, "SSAO/Post/Modulate"); - CompositorManager::getSingleton().setCompositorEnabled(mViewport, "SSAO/Post/Modulate", true); - mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); - mLight = mSceneMgr->createLight(); - mLight->setPosition(30, 80, 30); - } - else - { - mSceneMgr->destroyLight(mLight); - mLight = NULL; + if(box->getName() == SSAO_MODUALTE) + { + if (box->isChecked()) + { + CompositorManager::getSingleton().addCompositor(mViewport, "SSAO/Post/Modulate"); + CompositorManager::getSingleton().setCompositorEnabled(mViewport, "SSAO/Post/Modulate", true); + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); + mLight = mSceneMgr->createLight(); + mLight->setPosition(30, 80, 30); + } + else + { + mSceneMgr->destroyLight(mLight); + mLight = NULL; CompositorManager::getSingleton().setCompositorEnabled(mViewport, "SSAO/Post/Modulate", false); - CompositorManager::getSingleton().removeCompositor(mViewport, "SSAO/Post/Modulate"); - } - } + CompositorManager::getSingleton().removeCompositor(mViewport, "SSAO/Post/Modulate"); + } + } else if (box->getName() == SSAO_SAMPLE_SPACE_NAME) { setUniform("SSAO/Crytek", "SSAO/Crytek", "cSampleInScreenspace", box->isChecked(), false, 1); @@ -743,21 +743,21 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample } } - // The following three methods are for mouse input - /** @see Sample::mousePressed. */ + // The following three methods are for mouse input + /** @see Sample::mousePressed. */ #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) bool mousePressed( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) { if (mTrayMgr->injectMouseDown(evt, id)) return true; - if (id == OIS::MB_Left) - mTrayMgr->hideCursor(); // hide the cursor if user left-clicks in the scene + if (id == OIS::MB_Left) + mTrayMgr->hideCursor(); // hide the cursor if user left-clicks in the scene return true; } - /** @see Sample::mouseReleased. */ + /** @see Sample::mouseReleased. */ bool mouseReleased( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) { if (mTrayMgr->injectMouseUp(evt, id)) @@ -768,7 +768,7 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample return true; } - /** @see Sample::mouseMoved. */ + /** @see Sample::mouseMoved. */ bool mouseMoved( const OIS::MouseEvent& evt ) { // only rotate the camera if cursor is hidden @@ -783,16 +783,16 @@ class _OgreSampleClassExport Sample_SSAO : public SdkSample return true; } #endif - /** - * Set the uniform value in the compositor - * @param compositor The name of the compositor - * @param material The material that contains the uniform - * @param uniform The name of the uniform parameter - * @param value The value - * @param setVisible Whether to set the compositor to visible or not. - * @param position The position at which the compositor should be added again. - * defaults to -1, which means that the compositor is readded at the end of the chain. - */ + /** + * Set the uniform value in the compositor + * @param compositor The name of the compositor + * @param material The material that contains the uniform + * @param uniform The name of the uniform parameter + * @param value The value + * @param setVisible Whether to set the compositor to visible or not. + * @param position The position at which the compositor should be added again. + * defaults to -1, which means that the compositor is readded at the end of the chain. + */ void setUniform(Ogre::String compositor, Ogre::String material, Ogre::String uniform, float value, bool setVisible, int position = -1) { // remove compositor first??? diff --git a/Samples/SSAO/src/SSAO.cpp b/Samples/SSAO/src/SSAO.cpp index 0f649ba2bc0..34bc022de1d 100644 --- a/Samples/SSAO/src/SSAO.cpp +++ b/Samples/SSAO/src/SSAO.cpp @@ -6,15 +6,15 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_SSAO; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_SSAO; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } diff --git a/Samples/ShaderSystem/include/OgreShaderExInstancedViewports.h b/Samples/ShaderSystem/include/OgreShaderExInstancedViewports.h index 87054871b65..85be9465c0d 100644 --- a/Samples/ShaderSystem/include/OgreShaderExInstancedViewports.h +++ b/Samples/ShaderSystem/include/OgreShaderExInstancedViewports.h @@ -50,93 +50,93 @@ class ShaderExInstancedViewports : public SubRenderState // Interface. public: - /** Class default constructor */ - ShaderExInstancedViewports(); - - /** - @see SubRenderState::getType. - */ - virtual const String& getType () const; - - /** - @see SubRenderState::getExecutionOrder. - */ - virtual int getExecutionOrder () const; - - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom (const SubRenderState& rhs); - - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState (const RenderState* renderState, Pass* srcPass, Pass* dstPass); - - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams (Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - - - /** Set the monitors count. */ - void setMonitorsCount (const Vector2 monitorsCount); - - /** Return the monitors count. */ - Vector2 getMonitorsCount () const { return mMonitorsCount; } - - static String Type; + /** Class default constructor */ + ShaderExInstancedViewports(); + + /** + @see SubRenderState::getType. + */ + virtual const String& getType () const; + + /** + @see SubRenderState::getExecutionOrder. + */ + virtual int getExecutionOrder () const; + + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom (const SubRenderState& rhs); + + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState (const RenderState* renderState, Pass* srcPass, Pass* dstPass); + + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams (Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + + + /** Set the monitors count. */ + void setMonitorsCount (const Vector2 monitorsCount); + + /** Return the monitors count. */ + Vector2 getMonitorsCount () const { return mMonitorsCount; } + + static String Type; // Protected methods. protected: - + - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters (ProgramSet* programSet); + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters (ProgramSet* programSet); - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies (ProgramSet* programSet); + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies (ProgramSet* programSet); - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations (ProgramSet* programSet); + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations (ProgramSet* programSet); - /** - Internal method that adds related vertex shader functions invocations. - */ - bool addVSInvocations (Function* vsMain, const int groupOrder); + /** + Internal method that adds related vertex shader functions invocations. + */ + bool addVSInvocations (Function* vsMain, const int groupOrder); - /** - Internal method that adds related pixel shader functions invocations. - */ - bool addPSInvocations (Function* psMain, const int groupOrder); + /** + Internal method that adds related pixel shader functions invocations. + */ + bool addPSInvocations (Function* psMain, const int groupOrder); // Attributes. -protected: - ParameterPtr mVSInPosition; // Vertex shader original input position in projective space. - ParameterPtr mVSOriginalOutPositionProjectiveSpace; // Vertex shader original output position in projective space. - ParameterPtr mVSOutPositionProjectiveSpace; // Vertex shader output texcord position in projective space. - ParameterPtr mPSInPositionProjectiveSpace; // Pixel shader input position in projective space. - UniformParameterPtr mVSInMonitorsCount; // Vertex shader uniform monitors count. - UniformParameterPtr mPSInMonitorsCount; // Pixel shader uniform monitors count. - ParameterPtr mVSInMonitorIndex; // Vertex shader uniform monitor index. - ParameterPtr mVSOutMonitorIndex; // Vertex shader output monitor index. - ParameterPtr mPSInMonitorIndex; // Pixel shader input monitor index. - - ParameterPtr mVSInViewportOffsetMatrixR0; - ParameterPtr mVSInViewportOffsetMatrixR1; - ParameterPtr mVSInViewportOffsetMatrixR2; - ParameterPtr mVSInViewportOffsetMatrixR3; - - UniformParameterPtr mWorldViewMatrix; // world & view parameter. - UniformParameterPtr mProjectionMatrix; // projection parameter. +protected: + ParameterPtr mVSInPosition; // Vertex shader original input position in projective space. + ParameterPtr mVSOriginalOutPositionProjectiveSpace; // Vertex shader original output position in projective space. + ParameterPtr mVSOutPositionProjectiveSpace; // Vertex shader output texcord position in projective space. + ParameterPtr mPSInPositionProjectiveSpace; // Pixel shader input position in projective space. + UniformParameterPtr mVSInMonitorsCount; // Vertex shader uniform monitors count. + UniformParameterPtr mPSInMonitorsCount; // Pixel shader uniform monitors count. + ParameterPtr mVSInMonitorIndex; // Vertex shader uniform monitor index. + ParameterPtr mVSOutMonitorIndex; // Vertex shader output monitor index. + ParameterPtr mPSInMonitorIndex; // Pixel shader input monitor index. + + ParameterPtr mVSInViewportOffsetMatrixR0; + ParameterPtr mVSInViewportOffsetMatrixR1; + ParameterPtr mVSInViewportOffsetMatrixR2; + ParameterPtr mVSInViewportOffsetMatrixR3; + + UniformParameterPtr mWorldViewMatrix; // world & view parameter. + UniformParameterPtr mProjectionMatrix; // projection parameter. Vector2 mMonitorsCount; bool mMonitorsCountChanged; @@ -152,27 +152,27 @@ class ShaderExInstancedViewportsFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType () const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType () const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance (ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance (ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance (MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance (MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl (); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl (); diff --git a/Samples/ShaderSystem/include/ShaderExReflectionMap.h b/Samples/ShaderSystem/include/ShaderExReflectionMap.h index c6828599ef8..2595da3435a 100644 --- a/Samples/ShaderSystem/include/ShaderExReflectionMap.h +++ b/Samples/ShaderSystem/include/ShaderExReflectionMap.h @@ -50,124 +50,124 @@ class ShaderExReflectionMap : public SubRenderState // Interface. public: - /** Class default constructor */ - ShaderExReflectionMap(); - - /** - @see SubRenderState::getType. - */ - virtual const String& getType () const; - - /** - @see SubRenderState::getExecutionOrder. - */ - virtual int getExecutionOrder () const; - - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom (const SubRenderState& rhs); - - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState (const RenderState* renderState, Pass* srcPass, Pass* dstPass); - - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams (Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - - /** Sets the reflection map type. */ - void setReflectionMapType (TextureType type); - - /** Get the reflection map type. */ - TextureType getReflectionMapType () const { return mReflectionMapType; } - - /** Set the reflection map power. */ - void setReflectionPower (const Real reflectionPower); - - /** Return the reflection map power. */ - Real getReflectionPower () const { return mReflectionPowerValue; } - - /** - Set the reflection map texture name. - */ - void setReflectionMapTextureName (const String& textureName) { mReflectionMapTextureName = textureName; } - - /** - Return the reflection map texture name. - */ - const String& getReflectionMapTextureName () const { return mReflectionMapTextureName; } - - - /** - Set the mask map texture name. - */ - void setMaskMapTextureName (const String& textureName) { mMaskMapTextureName = textureName; } - - /** - Return the mask map texture name. - */ - const String& getMaskMapTextureName () const { return mMaskMapTextureName; } - - - static String Type; - + /** Class default constructor */ + ShaderExReflectionMap(); + + /** + @see SubRenderState::getType. + */ + virtual const String& getType () const; + + /** + @see SubRenderState::getExecutionOrder. + */ + virtual int getExecutionOrder () const; + + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom (const SubRenderState& rhs); + + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState (const RenderState* renderState, Pass* srcPass, Pass* dstPass); + + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams (Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + + /** Sets the reflection map type. */ + void setReflectionMapType (TextureType type); + + /** Get the reflection map type. */ + TextureType getReflectionMapType () const { return mReflectionMapType; } + + /** Set the reflection map power. */ + void setReflectionPower (const Real reflectionPower); + + /** Return the reflection map power. */ + Real getReflectionPower () const { return mReflectionPowerValue; } + + /** + Set the reflection map texture name. + */ + void setReflectionMapTextureName (const String& textureName) { mReflectionMapTextureName = textureName; } + + /** + Return the reflection map texture name. + */ + const String& getReflectionMapTextureName () const { return mReflectionMapTextureName; } + + + /** + Set the mask map texture name. + */ + void setMaskMapTextureName (const String& textureName) { mMaskMapTextureName = textureName; } + + /** + Return the mask map texture name. + */ + const String& getMaskMapTextureName () const { return mMaskMapTextureName; } + + + static String Type; + // Protected methods. protected: - + - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters (ProgramSet* programSet); + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters (ProgramSet* programSet); - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies (ProgramSet* programSet); + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies (ProgramSet* programSet); - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations (ProgramSet* programSet); + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations (ProgramSet* programSet); - /** - Internal method that adds related vertex shader functions invocations. - */ - bool addVSInvocations (Function* vsMain, const int groupOrder); + /** + Internal method that adds related vertex shader functions invocations. + */ + bool addVSInvocations (Function* vsMain, const int groupOrder); - /** - Internal method that adds related pixel shader functions invocations. - */ - bool addPSInvocations (Function* psMain, const int groupOrder); + /** + Internal method that adds related pixel shader functions invocations. + */ + bool addPSInvocations (Function* psMain, const int groupOrder); // Attributes. -protected: - String mReflectionMapTextureName; // The reflection map texture name. - String mMaskMapTextureName; // The mask map texture name. - unsigned short mMaskMapSamplerIndex; // Mask map texture sampler index. - unsigned short mReflectionMapSamplerIndex; // Reflection map texture sampler index. - Real mReflectionPowerValue; // The reflection power value. - bool mReflectionPowerChanged; // Indicate if reflection power changed. - TextureType mReflectionMapType; // Reflection map type. Valid are 2D or Cube. - UniformParameterPtr mMaskMapSampler; // Normal map texture sampler parameter. - UniformParameterPtr mReflectionMapSampler; // Reflection map texture sampler parameter. - UniformParameterPtr mReflectionPower; // Reflection map power. - ParameterPtr mVSInMaskTexcoord; // Vertex shader input mask texture coordinates. - ParameterPtr mVSOutMaskTexcoord; // Vertex shader output mask texture coordinates. - ParameterPtr mVSOutReflectionTexcoord; // Vertex shader output reflection texture coordinates. - ParameterPtr mPSInMaskTexcoord; // Pixel shader input mask texture coordinates. - ParameterPtr mPSInReflectionTexcoord; // Pixel shader input reflection texture coordinates. - UniformParameterPtr mWorldMatrix; // World matrix parameter. - UniformParameterPtr mWorldITMatrix; // World inverse transpose matrix parameter. - UniformParameterPtr mViewMatrix; // View matrix parameter. - ParameterPtr mVSInputNormal; // Vertex shader input normal parameter. - ParameterPtr mVSInputPos; // Vertex shader input position parameter. - ParameterPtr mPSOutDiffuse; // Pixel shader output colour. +protected: + String mReflectionMapTextureName; // The reflection map texture name. + String mMaskMapTextureName; // The mask map texture name. + unsigned short mMaskMapSamplerIndex; // Mask map texture sampler index. + unsigned short mReflectionMapSamplerIndex; // Reflection map texture sampler index. + Real mReflectionPowerValue; // The reflection power value. + bool mReflectionPowerChanged; // Indicate if reflection power changed. + TextureType mReflectionMapType; // Reflection map type. Valid are 2D or Cube. + UniformParameterPtr mMaskMapSampler; // Normal map texture sampler parameter. + UniformParameterPtr mReflectionMapSampler; // Reflection map texture sampler parameter. + UniformParameterPtr mReflectionPower; // Reflection map power. + ParameterPtr mVSInMaskTexcoord; // Vertex shader input mask texture coordinates. + ParameterPtr mVSOutMaskTexcoord; // Vertex shader output mask texture coordinates. + ParameterPtr mVSOutReflectionTexcoord; // Vertex shader output reflection texture coordinates. + ParameterPtr mPSInMaskTexcoord; // Pixel shader input mask texture coordinates. + ParameterPtr mPSInReflectionTexcoord; // Pixel shader input reflection texture coordinates. + UniformParameterPtr mWorldMatrix; // World matrix parameter. + UniformParameterPtr mWorldITMatrix; // World inverse transpose matrix parameter. + UniformParameterPtr mViewMatrix; // View matrix parameter. + ParameterPtr mVSInputNormal; // Vertex shader input normal parameter. + ParameterPtr mVSInputPos; // Vertex shader input position parameter. + ParameterPtr mPSOutDiffuse; // Pixel shader output colour. }; @@ -179,28 +179,28 @@ class ShaderExReflectionMapFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType () const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType () const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual SubRenderState* createInstance (ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual SubRenderState* createInstance (ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance (MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance (MaterialSerializer* ser, SubRenderState* subRenderState, Pass* srcPass, Pass* dstPass); protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl (); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl (); diff --git a/Samples/ShaderSystem/include/ShaderSystem.h b/Samples/ShaderSystem/include/ShaderSystem.h index c453a0d44ff..5445b391013 100644 --- a/Samples/ShaderSystem/include/ShaderSystem.h +++ b/Samples/ShaderSystem/include/ShaderSystem.h @@ -10,10 +10,10 @@ using namespace OgreBites; // Lighting models. enum ShaderSystemLightingModel { - SSLM_PerVertexLighting, - SSLM_PerPixelLighting, - SSLM_NormalMapLightingTangentSpace, - SSLM_NormalMapLightingObjectSpace + SSLM_PerVertexLighting, + SSLM_PerPixelLighting, + SSLM_NormalMapLightingTangentSpace, + SSLM_NormalMapLightingObjectSpace }; // a hack class to get infinite frustum - needed by instanced viewports demo @@ -21,29 +21,29 @@ enum ShaderSystemLightingModel class _OgreSampleClassExport InfiniteFrustum : public Frustum { public: - InfiniteFrustum() : Frustum() - { - mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal = Vector3::NEGATIVE_UNIT_X; - mFrustumPlanes[FRUSTUM_PLANE_LEFT].d = 9999999999999999999.0f; - mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal = Vector3::UNIT_X; - mFrustumPlanes[FRUSTUM_PLANE_RIGHT].d = 9999999999999999999.0f; - mFrustumPlanes[FRUSTUM_PLANE_TOP].normal = Vector3::NEGATIVE_UNIT_Y; - mFrustumPlanes[FRUSTUM_PLANE_TOP].d = 9999999999999999999.0f; - mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal = Vector3::UNIT_Y; - mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].d = 9999999999999999999.0f; - mFrustumPlanes[FRUSTUM_PLANE_NEAR].normal = Vector3::NEGATIVE_UNIT_Z; - mFrustumPlanes[FRUSTUM_PLANE_NEAR].d = 9999999999999999999.0f; - mFrustumPlanes[FRUSTUM_PLANE_FAR].normal = Vector3::UNIT_Z; - mFrustumPlanes[FRUSTUM_PLANE_FAR].d = 9999999999999999999.0f; - } - virtual bool isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy = 0) const {return true;}; - virtual bool isVisible(const Sphere& bound, FrustumPlane* culledBy = 0) const {return true;}; - virtual bool isVisible(const Vector3& vert, FrustumPlane* culledBy = 0) const {return true;}; - bool projectSphere(const Sphere& sphere, - Real* left, Real* top, Real* right, Real* bottom) const {*left = *bottom = -1.0f; *right = *top = 1.0f; return true;}; - Real getNearClipDistance(void) const {return 1.0;}; - Real getFarClipDistance(void) const {return 9999999999999.0f;}; - const Plane& getFrustumPlane( unsigned short plane ) const + InfiniteFrustum() : Frustum() + { + mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal = Vector3::NEGATIVE_UNIT_X; + mFrustumPlanes[FRUSTUM_PLANE_LEFT].d = 9999999999999999999.0f; + mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal = Vector3::UNIT_X; + mFrustumPlanes[FRUSTUM_PLANE_RIGHT].d = 9999999999999999999.0f; + mFrustumPlanes[FRUSTUM_PLANE_TOP].normal = Vector3::NEGATIVE_UNIT_Y; + mFrustumPlanes[FRUSTUM_PLANE_TOP].d = 9999999999999999999.0f; + mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal = Vector3::UNIT_Y; + mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].d = 9999999999999999999.0f; + mFrustumPlanes[FRUSTUM_PLANE_NEAR].normal = Vector3::NEGATIVE_UNIT_Z; + mFrustumPlanes[FRUSTUM_PLANE_NEAR].d = 9999999999999999999.0f; + mFrustumPlanes[FRUSTUM_PLANE_FAR].normal = Vector3::UNIT_Z; + mFrustumPlanes[FRUSTUM_PLANE_FAR].d = 9999999999999999999.0f; + } + virtual bool isVisible(const AxisAlignedBox& bound, FrustumPlane* culledBy = 0) const {return true;}; + virtual bool isVisible(const Sphere& bound, FrustumPlane* culledBy = 0) const {return true;}; + virtual bool isVisible(const Vector3& vert, FrustumPlane* culledBy = 0) const {return true;}; + bool projectSphere(const Sphere& sphere, + Real* left, Real* top, Real* right, Real* bottom) const {*left = *bottom = -1.0f; *right = *top = 1.0f; return true;}; + Real getNearClipDistance(void) const {return 1.0;}; + Real getFarClipDistance(void) const {return 9999999999999.0f;}; + const Plane& getFrustumPlane( unsigned short plane ) const { return mFrustumPlanes[plane]; } @@ -55,192 +55,192 @@ class _OgreSampleClassExport InfiniteFrustum : public Frustum class _OgreSampleClassExport Sample_ShaderSystem : public SdkSample { public: - Sample_ShaderSystem(); - ~Sample_ShaderSystem(); - - virtual void _shutdown(); + Sample_ShaderSystem(); + ~Sample_ShaderSystem(); + + virtual void _shutdown(); - /** @see Sample::checkBoxToggled. */ - void checkBoxToggled(CheckBox* box); + /** @see Sample::checkBoxToggled. */ + void checkBoxToggled(CheckBox* box); - /** @see Sample::itemSelected. */ - void itemSelected(SelectMenu* menu); + /** @see Sample::itemSelected. */ + void itemSelected(SelectMenu* menu); - /** @see Sample::buttonHit. */ - virtual void buttonHit(OgreBites::Button* b); + /** @see Sample::buttonHit. */ + virtual void buttonHit(OgreBites::Button* b); - /** @see Sample::sliderMoved. */ - virtual void sliderMoved(Slider* slider); + /** @see Sample::sliderMoved. */ + virtual void sliderMoved(Slider* slider); - /** @see Sample::getRequiredPlugins. */ - StringVector getRequiredPlugins(); + /** @see Sample::getRequiredPlugins. */ + StringVector getRequiredPlugins(); - /** @see Sample::testCapabilities. */ - void testCapabilities(const RenderSystemCapabilities* caps); - - /** @see Sample::frameRenderingQueued. */ + /** @see Sample::testCapabilities. */ + void testCapabilities(const RenderSystemCapabilities* caps); + + /** @see Sample::frameRenderingQueued. */ bool frameRenderingQueued(const FrameEvent& evt); - void updateTargetObjInfo(); + void updateTargetObjInfo(); #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) - /** @see Sample::mousePressed. */ - bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id); + /** @see Sample::mousePressed. */ + bool mousePressed(const OIS::MouseEvent& evt, OIS::MouseButtonID id); - /** @see Sample::mouseReleased. */ - bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id); + /** @see Sample::mouseReleased. */ + bool mouseReleased(const OIS::MouseEvent& evt, OIS::MouseButtonID id); - /** @see Sample::mouseMoved. */ - bool mouseMoved(const OIS::MouseEvent& evt); + /** @see Sample::mouseMoved. */ + bool mouseMoved(const OIS::MouseEvent& evt); #endif protected: - /** Set the current lighting model. */ - void setCurrentLightingModel(ShaderSystemLightingModel lightingModel); + /** Set the current lighting model. */ + void setCurrentLightingModel(ShaderSystemLightingModel lightingModel); - /** Return the current lighting model. */ - ShaderSystemLightingModel getCurrentLightingMode() const { return mCurLightingModel; } + /** Return the current lighting model. */ + ShaderSystemLightingModel getCurrentLightingMode() const { return mCurLightingModel; } - /** Set specular enable state. */ - void setSpecularEnable(bool enable); + /** Set specular enable state. */ + void setSpecularEnable(bool enable); - /** Return current specular state. */ - bool getSpecularEnable() const { return mSpecularEnable; } + /** Return current specular state. */ + bool getSpecularEnable() const { return mSpecularEnable; } - /** Set reflection map enable state. */ - void setReflectionMapEnable(bool enable); + /** Set reflection map enable state. */ + void setReflectionMapEnable(bool enable); - /** Return current reflection map state. */ - bool getReflectionMapEnable() const { return mReflectionMapEnable; } + /** Return current reflection map state. */ + bool getReflectionMapEnable() const { return mReflectionMapEnable; } - /** Set fog per pixel enable state. */ - void setPerPixelFogEnable(bool enable); + /** Set fog per pixel enable state. */ + void setPerPixelFogEnable(bool enable); - /** Set auto border adjustment mode in texture atlasing. */ - void setAtlasBorderMode( bool enable ); + /** Set auto border adjustment mode in texture atlasing. */ + void setAtlasBorderMode( bool enable ); - /** Set instanced viewports enable state. */ - void setInstancedViewportsEnable( bool enable ); + /** Set instanced viewports enable state. */ + void setInstancedViewportsEnable( bool enable ); - /** Create directional light. */ - void createDirectionalLight(); + /** Create directional light. */ + void createDirectionalLight(); - /** Create point light. */ - void createPointLight(); + /** Create point light. */ + void createPointLight(); - /** Create spot light. */ - void createSpotLight(); + /** Create spot light. */ + void createSpotLight(); - /** Toggle adding of lots of models */ - void updateAddLotsOfModels(bool addThem); + /** Toggle adding of lots of models */ + void updateAddLotsOfModels(bool addThem); void addModelToScene(const String & modelName); - /** Toggle instanced viewports */ - void updateInstancedViewports(bool enabled); + /** Toggle instanced viewports */ + void updateInstancedViewports(bool enabled); - /** Toggle light visibility. */ - void updateLightState(const String& lightName, bool visible); + /** Toggle light visibility. */ + void updateLightState(const String& lightName, bool visible); - /** Update runtime generated shaders of the target entities in this demo. */ - void updateSystemShaders(); + /** Update runtime generated shaders of the target entities in this demo. */ + void updateSystemShaders(); - /** Export a given material including RTSS extended attributes.*/ - void exportRTShaderSystemMaterial(const String& fileName, const String& materialName); + /** Export a given material including RTSS extended attributes.*/ + void exportRTShaderSystemMaterial(const String& fileName, const String& materialName); - /** Create shaders based techniques using the given entity based on its sub entities material set. */ - void generateShaders(Entity* entity); + /** Create shaders based techniques using the given entity based on its sub entities material set. */ + void generateShaders(Entity* entity); - /** @see Sample::setupView. */ -// virtual void setupView(); + /** @see Sample::setupView. */ +// virtual void setupView(); - /** @see Sample::setupContent. */ - virtual void setupContent(); + /** @see Sample::setupContent. */ + virtual void setupContent(); - /** Setup the UI for the sample. */ - void setupUI(); - - /** @see Sample::setupContent. */ - virtual void cleanupContent(); + /** Setup the UI for the sample. */ + void setupUI(); + + /** @see Sample::setupContent. */ + virtual void cleanupContent(); - /** @see Sample::loadResources. */ - void loadResources(); + /** @see Sample::loadResources. */ + void loadResources(); - /** Create private resource group. */ - void createPrivateResourceGroup(); - - /** @see Sample::unloadResources. */ - void unloadResources(); + /** Create private resource group. */ + void createPrivateResourceGroup(); + + /** @see Sample::unloadResources. */ + void unloadResources(); - void createInstancedViewports(); - void destroyInstancedViewports(); - void destroyInstancedViewportsFactory(); + void createInstancedViewports(); + void destroyInstancedViewports(); + void destroyInstancedViewportsFactory(); - /** Destroy private resource group. */ - void destroyPrivateResourceGroup(); + /** Destroy private resource group. */ + void destroyPrivateResourceGroup(); - /** Pick the target object. */ - void pickTargetObject( const OIS::MouseEvent &evt ); + /** Pick the target object. */ + void pickTargetObject( const OIS::MouseEvent &evt ); - /** Apply shadow type from the given shadow menu selected index. */ - void applyShadowType(int menuIndex); + /** Apply shadow type from the given shadow menu selected index. */ + void applyShadowType(int menuIndex); - /** Change the current texture layer blend mode. */ - void changeTextureLayerBlendMode(); + /** Change the current texture layer blend mode. */ + void changeTextureLayerBlendMode(); - /** Update layer blend caption. */ - void updateLayerBlendingCaption( RTShader::LayeredBlending::BlendMode nextBlendMode ); + /** Update layer blend caption. */ + void updateLayerBlendingCaption( RTShader::LayeredBlending::BlendMode nextBlendMode ); - ManualObject* createTextureAtlasObject(); - void createMaterialForTexture( const String & texName, bool isTextureAtlasTexture ); - // Types. + ManualObject* createTextureAtlasObject(); + void createMaterialForTexture( const String & texName, bool isTextureAtlasTexture ); + // Types. protected: - typedef vector::type EntityList; - typedef EntityList::iterator EntityListIterator; + typedef vector::type EntityList; + typedef EntityList::iterator EntityListIterator; - typedef map::type StringMap; - typedef StringMap::iterator StringMapIterator; + typedef map::type StringMap; + typedef StringMap::iterator StringMapIterator; protected: - EntityList mTargetEntities; // Target entities that will use runtime shader generated materials. - ShaderSystemLightingModel mCurLightingModel; // The current lighting model. - SelectMenu* mLightingModelMenu; // The lighting model menu. - SelectMenu* mFogModeMenu; // The fog mode menu. - SelectMenu* mLanguageMenu; // The shading language menu. - SelectMenu* mShadowMenu; // The shadow type menu. - bool mPerPixelFogEnable; // When true the RTSS will do per pixel fog calculations. - bool mSpecularEnable; // The current specular state. - RTShader::SubRenderStateFactory* mReflectionMapFactory; // The custom reflection map shader extension factory. - RTShader::SubRenderState* mInstancedViewportsSubRenderState;// todo - doc - bool mInstancedViewportsEnable; // todo - doc - InfiniteFrustum mInfiniteFrustum; // todo - doc - BillboardSet* mBbsFlare; // todo - doc - bool mAddedLotsOfModels; // todo - doc + EntityList mTargetEntities; // Target entities that will use runtime shader generated materials. + ShaderSystemLightingModel mCurLightingModel; // The current lighting model. + SelectMenu* mLightingModelMenu; // The lighting model menu. + SelectMenu* mFogModeMenu; // The fog mode menu. + SelectMenu* mLanguageMenu; // The shading language menu. + SelectMenu* mShadowMenu; // The shadow type menu. + bool mPerPixelFogEnable; // When true the RTSS will do per pixel fog calculations. + bool mSpecularEnable; // The current specular state. + RTShader::SubRenderStateFactory* mReflectionMapFactory; // The custom reflection map shader extension factory. + RTShader::SubRenderState* mInstancedViewportsSubRenderState;// todo - doc + bool mInstancedViewportsEnable; // todo - doc + InfiniteFrustum mInfiniteFrustum; // todo - doc + BillboardSet* mBbsFlare; // todo - doc + bool mAddedLotsOfModels; // todo - doc vector::type mLotsOfModelsEntities; // todo - doc vector::type mLotsOfModelsNodes; // todo - doc int mNumberOfModelsAdded; // todo - doc RTShader::SubRenderStateFactory * mInstancedViewportsFactory; // todo - doc - RTShader::SubRenderState* mReflectionMapSubRS; // The reflection map sub render state. - RTShader::LayeredBlending* mLayerBlendSubRS; // The layer blending sub render state. - Label* mLayerBlendLabel; // The layer blending label. - Slider* mReflectionPowerSlider; // The reflection power controller slider. - bool mReflectionMapEnable; // The current reflection map effect state. - Slider* mModifierValueSlider; // The value of the modifier for the layered blend controller slider. - Entity* mLayeredBlendingEntity; // Entity used to show layered blending SRS - SceneNode* mPointLightNode; // Point light scene node. - SceneNode* mDirectionalLightNode; // Directional light scene node. - RaySceneQuery* mRayQuery; // The ray scene query. - MovableObject* mTargetObj; // The current picked target object. - Label* mTargetObjMatName; // The target object material name label. - Label* mTargetObjVS; // The target object vertex shader label. - Label* mTargetObjFS; // The target object fragment shader label. - CheckBox* mDirLightCheckBox; // The directional light check box. - CheckBox* mPointLightCheckBox; // The point light check box. - CheckBox* mSpotLightCheckBox; // The spot light check box. - String mExportMaterialPath; // The path of the export material. - CheckBox* mInstancedViewportsCheckBox; // The instanced viewports check box. - CheckBox* mAddLotsOfModels; // The "add lots of models" check box. + RTShader::SubRenderState* mReflectionMapSubRS; // The reflection map sub render state. + RTShader::LayeredBlending* mLayerBlendSubRS; // The layer blending sub render state. + Label* mLayerBlendLabel; // The layer blending label. + Slider* mReflectionPowerSlider; // The reflection power controller slider. + bool mReflectionMapEnable; // The current reflection map effect state. + Slider* mModifierValueSlider; // The value of the modifier for the layered blend controller slider. + Entity* mLayeredBlendingEntity; // Entity used to show layered blending SRS + SceneNode* mPointLightNode; // Point light scene node. + SceneNode* mDirectionalLightNode; // Directional light scene node. + RaySceneQuery* mRayQuery; // The ray scene query. + MovableObject* mTargetObj; // The current picked target object. + Label* mTargetObjMatName; // The target object material name label. + Label* mTargetObjVS; // The target object vertex shader label. + Label* mTargetObjFS; // The target object fragment shader label. + CheckBox* mDirLightCheckBox; // The directional light check box. + CheckBox* mPointLightCheckBox; // The point light check box. + CheckBox* mSpotLightCheckBox; // The spot light check box. + String mExportMaterialPath; // The path of the export material. + CheckBox* mInstancedViewportsCheckBox; // The instanced viewports check box. + CheckBox* mAddLotsOfModels; // The "add lots of models" check box. }; #endif diff --git a/Samples/ShaderSystem/src/OgreShaderExInstancedViewports.cpp b/Samples/ShaderSystem/src/OgreShaderExInstancedViewports.cpp index c17a1f6938a..1076868b494 100644 --- a/Samples/ShaderSystem/src/OgreShaderExInstancedViewports.cpp +++ b/Samples/ShaderSystem/src/OgreShaderExInstancedViewports.cpp @@ -40,174 +40,174 @@ namespace RTShader { /************************************************************************/ /* */ /************************************************************************/ -String ShaderExInstancedViewports::Type = "SGX_InstancedViewports"; +String ShaderExInstancedViewports::Type = "SGX_InstancedViewports"; //----------------------------------------------------------------------- -#define SGX_LIB_INSTANCED_VIEWPORTS "SampleLib_InstancedViewports" -#define SGX_FUNC_INSTANCED_VIEWPORTS_TRANSFORM "SGX_InstancedViewportsTransform" -#define SGX_FUNC_INSTANCED_VIEWPORTS_DISCARD_OUT_OF_BOUNDS "SGX_InstancedViewportsDiscardOutOfBounds" +#define SGX_LIB_INSTANCED_VIEWPORTS "SampleLib_InstancedViewports" +#define SGX_FUNC_INSTANCED_VIEWPORTS_TRANSFORM "SGX_InstancedViewportsTransform" +#define SGX_FUNC_INSTANCED_VIEWPORTS_DISCARD_OUT_OF_BOUNDS "SGX_InstancedViewportsDiscardOutOfBounds" //----------------------------------------------------------------------- ShaderExInstancedViewports::ShaderExInstancedViewports() { - mMonitorsCount = Vector2(1.0, 1.0); - mMonitorsCountChanged = true; + mMonitorsCount = Vector2(1.0, 1.0); + mMonitorsCountChanged = true; } //----------------------------------------------------------------------- const String& ShaderExInstancedViewports::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int ShaderExInstancedViewports::getExecutionOrder() const +int ShaderExInstancedViewports::getExecutionOrder() const { - // We place this effect after texturing stage and before fog stage. - return FFP_POST_PROCESS+1; + // We place this effect after texturing stage and before fog stage. + return FFP_POST_PROCESS+1; } //----------------------------------------------------------------------- void ShaderExInstancedViewports::copyFrom(const SubRenderState& rhs) { - const ShaderExInstancedViewports& rhsInstancedViewports = static_cast(rhs); - - // Copy all settings that affect this sub render state output code. - mMonitorsCount = rhsInstancedViewports.mMonitorsCount; - mMonitorsCountChanged = rhsInstancedViewports.mMonitorsCountChanged; + const ShaderExInstancedViewports& rhsInstancedViewports = static_cast(rhs); + + // Copy all settings that affect this sub render state output code. + mMonitorsCount = rhsInstancedViewports.mMonitorsCount; + mMonitorsCountChanged = rhsInstancedViewports.mMonitorsCountChanged; } //----------------------------------------------------------------------- bool ShaderExInstancedViewports::preAddToRenderState( const RenderState* renderState, Pass* srcPass, Pass* dstPass ) { - return srcPass->getParent()->getParent()->getName().find("SdkTrays") == Ogre::String::npos; + return srcPass->getParent()->getParent()->getName().find("SdkTrays") == Ogre::String::npos; } //----------------------------------------------------------------------- bool ShaderExInstancedViewports::resolveParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); - // Resolve vertex shader output position in projective space. + // Resolve vertex shader output position in projective space. - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - mVSOriginalOutPositionProjectiveSpace = vsMain->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); + mVSOriginalOutPositionProjectiveSpace = vsMain->resolveOutputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_PROJECTIVE_SPACE, GCT_FLOAT4); #define SPC_POSITION_PROJECTIVE_SPACE_AS_TEXCORD ((Parameter::Content)(Parameter::SPC_CUSTOM_CONTENT_BEGIN + 1)) - mVSOutPositionProjectiveSpace = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, SPC_POSITION_PROJECTIVE_SPACE_AS_TEXCORD, GCT_FLOAT4); + mVSOutPositionProjectiveSpace = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, SPC_POSITION_PROJECTIVE_SPACE_AS_TEXCORD, GCT_FLOAT4); - // Resolve ps input position in projective space. - mPSInPositionProjectiveSpace = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutPositionProjectiveSpace->getIndex(), - mVSOutPositionProjectiveSpace->getContent(), - GCT_FLOAT4); - // Resolve vertex shader uniform monitors count - mVSInMonitorsCount = vsProgram->resolveParameter(GCT_FLOAT2, -1, (uint16)GPV_GLOBAL, "monitorsCount"); + // Resolve ps input position in projective space. + mPSInPositionProjectiveSpace = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutPositionProjectiveSpace->getIndex(), + mVSOutPositionProjectiveSpace->getContent(), + GCT_FLOAT4); + // Resolve vertex shader uniform monitors count + mVSInMonitorsCount = vsProgram->resolveParameter(GCT_FLOAT2, -1, (uint16)GPV_GLOBAL, "monitorsCount"); - // Resolve pixel shader uniform monitors count - mPSInMonitorsCount = psProgram->resolveParameter(GCT_FLOAT2, -1, (uint16)GPV_GLOBAL, "monitorsCount"); + // Resolve pixel shader uniform monitors count + mPSInMonitorsCount = psProgram->resolveParameter(GCT_FLOAT2, -1, (uint16)GPV_GLOBAL, "monitorsCount"); - // Resolve the current world & view matrices concatenated - mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); + // Resolve the current world & view matrices concatenated + mWorldViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLDVIEW_MATRIX, 0); - // Resolve the current projection matrix - mProjectionMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_PROJECTION_MATRIX, 0); - - + // Resolve the current projection matrix + mProjectionMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_PROJECTION_MATRIX, 0); + + #define SPC_MONITOR_INDEX Parameter::SPC_TEXTURE_COORDINATE3 - // Resolve vertex shader monitor index - mVSInMonitorIndex = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 3, SPC_MONITOR_INDEX, GCT_FLOAT4); + // Resolve vertex shader monitor index + mVSInMonitorIndex = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 3, SPC_MONITOR_INDEX, GCT_FLOAT4); #define SPC_MATRIX_R0 Parameter::SPC_TEXTURE_COORDINATE4 #define SPC_MATRIX_R1 Parameter::SPC_TEXTURE_COORDINATE5 #define SPC_MATRIX_R2 Parameter::SPC_TEXTURE_COORDINATE6 #define SPC_MATRIX_R3 Parameter::SPC_TEXTURE_COORDINATE7 - // Resolve vertex shader viewport offset matrix - mVSInViewportOffsetMatrixR0 = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 4, SPC_MATRIX_R0, GCT_FLOAT4); - mVSInViewportOffsetMatrixR1 = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 5, SPC_MATRIX_R1, GCT_FLOAT4); - mVSInViewportOffsetMatrixR2 = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 6, SPC_MATRIX_R2, GCT_FLOAT4); - mVSInViewportOffsetMatrixR3 = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 7, SPC_MATRIX_R3, GCT_FLOAT4); - - - - // Resolve vertex shader output monitor index. - mVSOutMonitorIndex = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - SPC_MONITOR_INDEX, - GCT_FLOAT4); - - // Resolve ps input monitor index. - mPSInMonitorIndex = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutMonitorIndex->getIndex(), - mVSOutMonitorIndex->getContent(), - GCT_FLOAT4); - - if (!mVSInPosition.get() || !mWorldViewMatrix.get() || !mVSOriginalOutPositionProjectiveSpace.get() || - !mVSOutPositionProjectiveSpace.get() || !mPSInPositionProjectiveSpace.get() || !mVSInMonitorsCount.get() || - !mPSInMonitorsCount.get() || !mVSInMonitorIndex.get() || !mProjectionMatrix.get() || !mVSInViewportOffsetMatrixR0.get() || - !mVSInViewportOffsetMatrixR1.get() || !mVSInViewportOffsetMatrixR2.get() || !mVSInViewportOffsetMatrixR3.get() || - !mVSOutMonitorIndex.get() || !mPSInMonitorIndex.get()) - { - OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, - "Not all parameters could be constructed for the sub-render state.", - "ShaderExInstancedViewports::resolveParameters" ); - } - - - return true; + // Resolve vertex shader viewport offset matrix + mVSInViewportOffsetMatrixR0 = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 4, SPC_MATRIX_R0, GCT_FLOAT4); + mVSInViewportOffsetMatrixR1 = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 5, SPC_MATRIX_R1, GCT_FLOAT4); + mVSInViewportOffsetMatrixR2 = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 6, SPC_MATRIX_R2, GCT_FLOAT4); + mVSInViewportOffsetMatrixR3 = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 7, SPC_MATRIX_R3, GCT_FLOAT4); + + + + // Resolve vertex shader output monitor index. + mVSOutMonitorIndex = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + SPC_MONITOR_INDEX, + GCT_FLOAT4); + + // Resolve ps input monitor index. + mPSInMonitorIndex = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutMonitorIndex->getIndex(), + mVSOutMonitorIndex->getContent(), + GCT_FLOAT4); + + if (!mVSInPosition.get() || !mWorldViewMatrix.get() || !mVSOriginalOutPositionProjectiveSpace.get() || + !mVSOutPositionProjectiveSpace.get() || !mPSInPositionProjectiveSpace.get() || !mVSInMonitorsCount.get() || + !mPSInMonitorsCount.get() || !mVSInMonitorIndex.get() || !mProjectionMatrix.get() || !mVSInViewportOffsetMatrixR0.get() || + !mVSInViewportOffsetMatrixR1.get() || !mVSInViewportOffsetMatrixR2.get() || !mVSInViewportOffsetMatrixR3.get() || + !mVSOutMonitorIndex.get() || !mPSInMonitorIndex.get()) + { + OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, + "Not all parameters could be constructed for the sub-render state.", + "ShaderExInstancedViewports::resolveParameters" ); + } + + + return true; } //----------------------------------------------------------------------- bool ShaderExInstancedViewports::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - - vsProgram->addDependency(FFP_LIB_COMMON); - vsProgram->addDependency(SGX_LIB_INSTANCED_VIEWPORTS); - - psProgram->addDependency(FFP_LIB_COMMON); - psProgram->addDependency(SGX_LIB_INSTANCED_VIEWPORTS); - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + + vsProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(SGX_LIB_INSTANCED_VIEWPORTS); + + psProgram->addDependency(FFP_LIB_COMMON); + psProgram->addDependency(SGX_LIB_INSTANCED_VIEWPORTS); + + return true; } //----------------------------------------------------------------------- bool ShaderExInstancedViewports::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* psMain = psProgram->getEntryPointFunction(); - - - // Add vertex shader invocations. - if (false == addVSInvocations(vsMain, FFP_VS_TRANSFORM + 1)) - return false; - - - // Add pixel shader invocations. - if (false == addPSInvocations(psMain, FFP_PS_PRE_PROCESS + 1)) - return false; - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* psMain = psProgram->getEntryPointFunction(); + + + // Add vertex shader invocations. + if (false == addVSInvocations(vsMain, FFP_VS_TRANSFORM + 1)) + return false; + + + // Add pixel shader invocations. + if (false == addPSInvocations(psMain, FFP_PS_PRE_PROCESS + 1)) + return false; + + return true; } //----------------------------------------------------------------------- bool ShaderExInstancedViewports::addVSInvocations( Function* vsMain, const int groupOrder ) { - FunctionInvocation* funcInvocation = NULL; - int internalCounter = 0; - + FunctionInvocation* funcInvocation = NULL; + int internalCounter = 0; + funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_INSTANCED_VIEWPORTS_TRANSFORM, groupOrder, internalCounter++); funcInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); funcInvocation->pushOperand(mWorldViewMatrix, Operand::OPS_IN); @@ -221,46 +221,46 @@ bool ShaderExInstancedViewports::addVSInvocations( Function* vsMain, const int g funcInvocation->pushOperand(mVSOriginalOutPositionProjectiveSpace, Operand::OPS_OUT); vsMain->addAtomInstance(funcInvocation); - // Output position in projective space. + // Output position in projective space. funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); funcInvocation->pushOperand(mVSOriginalOutPositionProjectiveSpace, Operand::OPS_IN); funcInvocation->pushOperand(mVSOutPositionProjectiveSpace, Operand::OPS_OUT); vsMain->addAtomInstance(funcInvocation); - // Output monitor index. + // Output monitor index. funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); funcInvocation->pushOperand(mVSInMonitorIndex, Operand::OPS_IN); funcInvocation->pushOperand(mVSOutMonitorIndex, Operand::OPS_OUT); vsMain->addAtomInstance(funcInvocation); - return true; + return true; } //----------------------------------------------------------------------- bool ShaderExInstancedViewports::addPSInvocations( Function* psMain, const int groupOrder ) { - FunctionInvocation* funcInvocation = NULL; - int internalCounter = 0; + FunctionInvocation* funcInvocation = NULL; + int internalCounter = 0; - funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_INSTANCED_VIEWPORTS_DISCARD_OUT_OF_BOUNDS, groupOrder, internalCounter++); - funcInvocation->pushOperand(mPSInMonitorsCount, Operand::OPS_IN); - funcInvocation->pushOperand(mPSInMonitorIndex, Operand::OPS_IN); - funcInvocation->pushOperand(mPSInPositionProjectiveSpace, Operand::OPS_IN); - - psMain->addAtomInstance(funcInvocation); + funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_INSTANCED_VIEWPORTS_DISCARD_OUT_OF_BOUNDS, groupOrder, internalCounter++); + funcInvocation->pushOperand(mPSInMonitorsCount, Operand::OPS_IN); + funcInvocation->pushOperand(mPSInMonitorIndex, Operand::OPS_IN); + funcInvocation->pushOperand(mPSInPositionProjectiveSpace, Operand::OPS_IN); + + psMain->addAtomInstance(funcInvocation); - return true; + return true; } //----------------------------------------------------------------------- void ShaderExInstancedViewports::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList) { - if (mMonitorsCountChanged) - { - mVSInMonitorsCount->setGpuParameter(mMonitorsCount + Vector2(0.0001, 0.0001)); - mPSInMonitorsCount->setGpuParameter(mMonitorsCount + Vector2(0.0001, 0.0001)); + if (mMonitorsCountChanged) + { + mVSInMonitorsCount->setGpuParameter(mMonitorsCount + Vector2(0.0001, 0.0001)); + mPSInMonitorsCount->setGpuParameter(mMonitorsCount + Vector2(0.0001, 0.0001)); - mMonitorsCountChanged = false; - } + mMonitorsCountChanged = false; + } } //----------------------------------------------------------------------- void ShaderExInstancedViewports::setMonitorsCount( const Vector2 monitorsCount ) @@ -269,16 +269,16 @@ void ShaderExInstancedViewports::setMonitorsCount( const Vector2 monitorsCount ) mMonitorsCountChanged = true; } //----------------------------------------------------------------------- -SubRenderState* ShaderExInstancedViewportsFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* ShaderExInstancedViewportsFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - SubRenderState* subRenderState = SubRenderStateFactory::createInstance(); - return subRenderState; + SubRenderState* subRenderState = SubRenderStateFactory::createInstance(); + return subRenderState; } //----------------------------------------------------------------------- void ShaderExInstancedViewportsFactory::writeInstance(MaterialSerializer* ser, - SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + SubRenderState* subRenderState, + Pass* srcPass, Pass* dstPass) { } @@ -286,14 +286,14 @@ void ShaderExInstancedViewportsFactory::writeInstance(MaterialSerializer* ser, //----------------------------------------------------------------------- const String& ShaderExInstancedViewportsFactory::getType() const { - return ShaderExInstancedViewports::Type; + return ShaderExInstancedViewports::Type; } //----------------------------------------------------------------------- -SubRenderState* ShaderExInstancedViewportsFactory::createInstanceImpl() +SubRenderState* ShaderExInstancedViewportsFactory::createInstanceImpl() { - return OGRE_NEW ShaderExInstancedViewports; + return OGRE_NEW ShaderExInstancedViewports; } //----------------------------------------------------------------------- diff --git a/Samples/ShaderSystem/src/ShaderExReflectionMap.cpp b/Samples/ShaderSystem/src/ShaderExReflectionMap.cpp index 8439bcd58db..f0c22fd7b95 100644 --- a/Samples/ShaderSystem/src/ShaderExReflectionMap.cpp +++ b/Samples/ShaderSystem/src/ShaderExReflectionMap.cpp @@ -36,401 +36,401 @@ THE SOFTWARE. /************************************************************************/ /* */ /************************************************************************/ -String ShaderExReflectionMap::Type = "SGX_ReflectionMap"; +String ShaderExReflectionMap::Type = "SGX_ReflectionMap"; //----------------------------------------------------------------------- -#define SGX_LIB_REFLECTIONMAP "SampleLib_ReflectionMap" -#define SGX_FUNC_APPLY_REFLECTION_MAP "SGX_ApplyReflectionMap" +#define SGX_LIB_REFLECTIONMAP "SampleLib_ReflectionMap" +#define SGX_FUNC_APPLY_REFLECTION_MAP "SGX_ApplyReflectionMap" //----------------------------------------------------------------------- ShaderExReflectionMap::ShaderExReflectionMap() { - mMaskMapSamplerIndex = 0; - mReflectionMapSamplerIndex = 0; - mReflectionMapType = TEX_TYPE_2D; - mReflectionPowerChanged = true; - mReflectionPowerValue = 0.5; + mMaskMapSamplerIndex = 0; + mReflectionMapSamplerIndex = 0; + mReflectionMapType = TEX_TYPE_2D; + mReflectionPowerChanged = true; + mReflectionPowerValue = 0.5; } //----------------------------------------------------------------------- const String& ShaderExReflectionMap::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int ShaderExReflectionMap::getExecutionOrder() const +int ShaderExReflectionMap::getExecutionOrder() const { - // We place this effect after texturing stage and before fog stage. - return FFP_TEXTURING + 1; + // We place this effect after texturing stage and before fog stage. + return FFP_TEXTURING + 1; } //----------------------------------------------------------------------- void ShaderExReflectionMap::copyFrom(const SubRenderState& rhs) { - const ShaderExReflectionMap& rhsReflectionMap = static_cast(rhs); - - // Copy all settings that affect this sub render state output code. - mMaskMapSamplerIndex = rhsReflectionMap.mMaskMapSamplerIndex; - mReflectionMapSamplerIndex = rhsReflectionMap.mReflectionMapSamplerIndex; - mReflectionMapType = rhsReflectionMap.mReflectionMapType; - mReflectionPowerChanged = rhsReflectionMap.mReflectionPowerChanged; - mReflectionPowerValue = rhsReflectionMap.mReflectionPowerValue; - mReflectionMapTextureName = rhsReflectionMap.mReflectionMapTextureName; - mMaskMapTextureName = rhsReflectionMap.mMaskMapTextureName; + const ShaderExReflectionMap& rhsReflectionMap = static_cast(rhs); + + // Copy all settings that affect this sub render state output code. + mMaskMapSamplerIndex = rhsReflectionMap.mMaskMapSamplerIndex; + mReflectionMapSamplerIndex = rhsReflectionMap.mReflectionMapSamplerIndex; + mReflectionMapType = rhsReflectionMap.mReflectionMapType; + mReflectionPowerChanged = rhsReflectionMap.mReflectionPowerChanged; + mReflectionPowerValue = rhsReflectionMap.mReflectionPowerValue; + mReflectionMapTextureName = rhsReflectionMap.mReflectionMapTextureName; + mMaskMapTextureName = rhsReflectionMap.mMaskMapTextureName; } //----------------------------------------------------------------------- bool ShaderExReflectionMap::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass ) { - TextureUnitState* textureUnit; - - // Create the mask texture unit. - textureUnit = dstPass->createTextureUnitState(); - textureUnit->setTextureName(mMaskMapTextureName); - mMaskMapSamplerIndex = dstPass->getNumTextureUnitStates() - 1; - - // Create the reflection texture unit. - textureUnit = dstPass->createTextureUnitState(); - - if (mReflectionMapType == TEX_TYPE_2D) - { - textureUnit->setTextureName(mReflectionMapTextureName); - } - else - { - textureUnit->setCubicTextureName(mReflectionMapTextureName, true); - } - - mReflectionMapSamplerIndex = dstPass->getNumTextureUnitStates() - 1; - - return true; + TextureUnitState* textureUnit; + + // Create the mask texture unit. + textureUnit = dstPass->createTextureUnitState(); + textureUnit->setTextureName(mMaskMapTextureName); + mMaskMapSamplerIndex = dstPass->getNumTextureUnitStates() - 1; + + // Create the reflection texture unit. + textureUnit = dstPass->createTextureUnitState(); + + if (mReflectionMapType == TEX_TYPE_2D) + { + textureUnit->setTextureName(mReflectionMapTextureName); + } + else + { + textureUnit->setCubicTextureName(mReflectionMapTextureName, true); + } + + mReflectionMapSamplerIndex = dstPass->getNumTextureUnitStates() - 1; + + return true; } //----------------------------------------------------------------------- bool ShaderExReflectionMap::resolveParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - - // Resolve vs input mask texture coordinates. - // NOTE: We use the first texture coordinate hard coded here - // You may want to parametrize this as well - just remember to add it to hash and copy methods. - mVSInMaskTexcoord = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 0, Parameter::SPC_TEXTURE_COORDINATE0, GCT_FLOAT2); - if (mVSInMaskTexcoord.get() == 0) - return false; - - // Resolve vs output mask texture coordinates. - mVSOutMaskTexcoord = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, mVSInMaskTexcoord->getContent(), GCT_FLOAT2); - if (mVSOutMaskTexcoord.get() == 0) - return false; - - // Resolve ps input mask texture coordinates. - mPSInMaskTexcoord = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutMaskTexcoord->getIndex(), - mVSOutMaskTexcoord->getContent(), - GCT_FLOAT2); - - // Resolve vs output reflection texture coordinates. - mVSOutReflectionTexcoord = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::SPC_UNKNOWN, - mReflectionMapType == TEX_TYPE_2D ? GCT_FLOAT2 : GCT_FLOAT3); - if (mVSOutReflectionTexcoord.get() == 0) - return false; - - // Resolve ps input reflection texture coordinates. - mPSInReflectionTexcoord= psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutReflectionTexcoord->getIndex(), - mVSOutReflectionTexcoord->getContent(), - mVSOutReflectionTexcoord->getType()); - - - // Resolve world matrix. - mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - if (mWorldMatrix.get() == NULL) - return false; - - // Resolve world inverse transpose matrix. - mWorldITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, 0); - if (mWorldITMatrix.get() == NULL) - return false; - - - // Resolve view matrix. - mViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEW_MATRIX, 0); - if (mViewMatrix.get() == NULL) - return false; - - // Resolve vertex position. - mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - if (mVSInputPos.get() == NULL) - return false; - - // Resolve vertex normal. - mVSInputNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - if (mVSInputNormal.get() == NULL) - return false; - - // Resolve mask texture sampler parameter. - mMaskMapSampler = psProgram->resolveParameter(GCT_SAMPLER2D, mMaskMapSamplerIndex, (uint16)GPV_GLOBAL, "mask_sampler"); - if (mMaskMapSampler.get() == NULL) - return false; - - // Resolve reflection texture sampler parameter. - mReflectionMapSampler = psProgram->resolveParameter(mReflectionMapType == TEX_TYPE_2D ? GCT_SAMPLER2D : GCT_SAMPLERCUBE, - mReflectionMapSamplerIndex, (uint16)GPV_GLOBAL, "reflection_texture"); - if (mReflectionMapSampler.get() == NULL) - return false; - - // Resolve reflection power parameter. - mReflectionPower = psProgram->resolveParameter(GCT_FLOAT1, -1, (uint16)GPV_GLOBAL, "reflection_power"); - if (mReflectionPower.get() == NULL) - return false; - - // Resolve ps output diffuse colour. - mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - if (mPSOutDiffuse.get() == NULL) - return false; - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + + // Resolve vs input mask texture coordinates. + // NOTE: We use the first texture coordinate hard coded here + // You may want to parametrize this as well - just remember to add it to hash and copy methods. + mVSInMaskTexcoord = vsMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, 0, Parameter::SPC_TEXTURE_COORDINATE0, GCT_FLOAT2); + if (mVSInMaskTexcoord.get() == 0) + return false; + + // Resolve vs output mask texture coordinates. + mVSOutMaskTexcoord = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, mVSInMaskTexcoord->getContent(), GCT_FLOAT2); + if (mVSOutMaskTexcoord.get() == 0) + return false; + + // Resolve ps input mask texture coordinates. + mPSInMaskTexcoord = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutMaskTexcoord->getIndex(), + mVSOutMaskTexcoord->getContent(), + GCT_FLOAT2); + + // Resolve vs output reflection texture coordinates. + mVSOutReflectionTexcoord = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::SPC_UNKNOWN, + mReflectionMapType == TEX_TYPE_2D ? GCT_FLOAT2 : GCT_FLOAT3); + if (mVSOutReflectionTexcoord.get() == 0) + return false; + + // Resolve ps input reflection texture coordinates. + mPSInReflectionTexcoord= psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutReflectionTexcoord->getIndex(), + mVSOutReflectionTexcoord->getContent(), + mVSOutReflectionTexcoord->getType()); + + + // Resolve world matrix. + mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + if (mWorldMatrix.get() == NULL) + return false; + + // Resolve world inverse transpose matrix. + mWorldITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, 0); + if (mWorldITMatrix.get() == NULL) + return false; + + + // Resolve view matrix. + mViewMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_VIEW_MATRIX, 0); + if (mViewMatrix.get() == NULL) + return false; + + // Resolve vertex position. + mVSInputPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + if (mVSInputPos.get() == NULL) + return false; + + // Resolve vertex normal. + mVSInputNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + if (mVSInputNormal.get() == NULL) + return false; + + // Resolve mask texture sampler parameter. + mMaskMapSampler = psProgram->resolveParameter(GCT_SAMPLER2D, mMaskMapSamplerIndex, (uint16)GPV_GLOBAL, "mask_sampler"); + if (mMaskMapSampler.get() == NULL) + return false; + + // Resolve reflection texture sampler parameter. + mReflectionMapSampler = psProgram->resolveParameter(mReflectionMapType == TEX_TYPE_2D ? GCT_SAMPLER2D : GCT_SAMPLERCUBE, + mReflectionMapSamplerIndex, (uint16)GPV_GLOBAL, "reflection_texture"); + if (mReflectionMapSampler.get() == NULL) + return false; + + // Resolve reflection power parameter. + mReflectionPower = psProgram->resolveParameter(GCT_FLOAT1, -1, (uint16)GPV_GLOBAL, "reflection_power"); + if (mReflectionPower.get() == NULL) + return false; + + // Resolve ps output diffuse colour. + mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + if (mPSOutDiffuse.get() == NULL) + return false; + + return true; } //----------------------------------------------------------------------- bool ShaderExReflectionMap::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - - vsProgram->addDependency(FFP_LIB_COMMON); - vsProgram->addDependency(FFP_LIB_TEXTURING); - - psProgram->addDependency(FFP_LIB_COMMON); - psProgram->addDependency(FFP_LIB_TEXTURING); - psProgram->addDependency(SGX_LIB_REFLECTIONMAP); - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + + vsProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(FFP_LIB_TEXTURING); + + psProgram->addDependency(FFP_LIB_COMMON); + psProgram->addDependency(FFP_LIB_TEXTURING); + psProgram->addDependency(SGX_LIB_REFLECTIONMAP); + + return true; } //----------------------------------------------------------------------- bool ShaderExReflectionMap::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* psMain = psProgram->getEntryPointFunction(); - - - // Add vertex shader invocations. - if (false == addVSInvocations(vsMain, FFP_VS_TEXTURING + 1)) - return false; - - - // Add pixel shader invocations. - if (false == addPSInvocations(psMain, FFP_PS_TEXTURING + 1)) - return false; - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* psMain = psProgram->getEntryPointFunction(); + + + // Add vertex shader invocations. + if (false == addVSInvocations(vsMain, FFP_VS_TEXTURING + 1)) + return false; + + + // Add pixel shader invocations. + if (false == addPSInvocations(psMain, FFP_PS_TEXTURING + 1)) + return false; + + return true; } //----------------------------------------------------------------------- bool ShaderExReflectionMap::addVSInvocations( Function* vsMain, const int groupOrder ) { - FunctionInvocation* funcInvocation = NULL; - int internalCounter = 0; - - // Output mask texture coordinates. - funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - funcInvocation->pushOperand(mVSInMaskTexcoord, Operand::OPS_IN); - funcInvocation->pushOperand(mVSOutMaskTexcoord, Operand::OPS_OUT); - vsMain->addAtomInstance(funcInvocation); - - // Output reflection texture coordinates. - if (mReflectionMapType == TEX_TYPE_2D) - { - funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, groupOrder, internalCounter++); - funcInvocation->pushOperand(mWorldITMatrix, Operand::OPS_IN); - funcInvocation->pushOperand(mViewMatrix, Operand::OPS_IN); - funcInvocation->pushOperand(mVSInputNormal, Operand::OPS_IN); - funcInvocation->pushOperand(mVSOutReflectionTexcoord, Operand::OPS_OUT); - vsMain->addAtomInstance(funcInvocation); - } - else - { - funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, groupOrder, internalCounter++); - funcInvocation->pushOperand(mWorldMatrix, Operand::OPS_IN); - funcInvocation->pushOperand(mWorldITMatrix, Operand::OPS_IN); - funcInvocation->pushOperand(mViewMatrix, Operand::OPS_IN); - funcInvocation->pushOperand(mVSInputNormal, Operand::OPS_IN); - funcInvocation->pushOperand(mVSInputPos, Operand::OPS_IN); - funcInvocation->pushOperand(mVSOutReflectionTexcoord, Operand::OPS_OUT); - vsMain->addAtomInstance(funcInvocation); - } - - - - return true; + FunctionInvocation* funcInvocation = NULL; + int internalCounter = 0; + + // Output mask texture coordinates. + funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + funcInvocation->pushOperand(mVSInMaskTexcoord, Operand::OPS_IN); + funcInvocation->pushOperand(mVSOutMaskTexcoord, Operand::OPS_OUT); + vsMain->addAtomInstance(funcInvocation); + + // Output reflection texture coordinates. + if (mReflectionMapType == TEX_TYPE_2D) + { + funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_SPHERE, groupOrder, internalCounter++); + funcInvocation->pushOperand(mWorldITMatrix, Operand::OPS_IN); + funcInvocation->pushOperand(mViewMatrix, Operand::OPS_IN); + funcInvocation->pushOperand(mVSInputNormal, Operand::OPS_IN); + funcInvocation->pushOperand(mVSOutReflectionTexcoord, Operand::OPS_OUT); + vsMain->addAtomInstance(funcInvocation); + } + else + { + funcInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_GENERATE_TEXCOORD_ENV_REFLECT, groupOrder, internalCounter++); + funcInvocation->pushOperand(mWorldMatrix, Operand::OPS_IN); + funcInvocation->pushOperand(mWorldITMatrix, Operand::OPS_IN); + funcInvocation->pushOperand(mViewMatrix, Operand::OPS_IN); + funcInvocation->pushOperand(mVSInputNormal, Operand::OPS_IN); + funcInvocation->pushOperand(mVSInputPos, Operand::OPS_IN); + funcInvocation->pushOperand(mVSOutReflectionTexcoord, Operand::OPS_OUT); + vsMain->addAtomInstance(funcInvocation); + } + + + + return true; } //----------------------------------------------------------------------- bool ShaderExReflectionMap::addPSInvocations( Function* psMain, const int groupOrder ) { - FunctionInvocation* funcInvocation = NULL; - int internalCounter = 0; - - funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_APPLY_REFLECTION_MAP, groupOrder, internalCounter++); - funcInvocation->pushOperand(mMaskMapSampler, Operand::OPS_IN); - funcInvocation->pushOperand(mPSInMaskTexcoord, Operand::OPS_IN); - funcInvocation->pushOperand(mReflectionMapSampler, Operand::OPS_IN); - funcInvocation->pushOperand(mPSInReflectionTexcoord, Operand::OPS_IN); - funcInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - funcInvocation->pushOperand(mReflectionPower, Operand::OPS_IN); - funcInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); - - psMain->addAtomInstance(funcInvocation); - - return true; + FunctionInvocation* funcInvocation = NULL; + int internalCounter = 0; + + funcInvocation = OGRE_NEW FunctionInvocation(SGX_FUNC_APPLY_REFLECTION_MAP, groupOrder, internalCounter++); + funcInvocation->pushOperand(mMaskMapSampler, Operand::OPS_IN); + funcInvocation->pushOperand(mPSInMaskTexcoord, Operand::OPS_IN); + funcInvocation->pushOperand(mReflectionMapSampler, Operand::OPS_IN); + funcInvocation->pushOperand(mPSInReflectionTexcoord, Operand::OPS_IN); + funcInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + funcInvocation->pushOperand(mReflectionPower, Operand::OPS_IN); + funcInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT, Operand::OPM_XYZ); + + psMain->addAtomInstance(funcInvocation); + + return true; } //----------------------------------------------------------------------- void ShaderExReflectionMap::setReflectionMapType( TextureType type ) { - if (type != TEX_TYPE_2D && type != TEX_TYPE_CUBE_MAP) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Invalid texture type set - only 2D or Cube supported", - "ShaderExReflectionMap::setReflectionMapType"); - } - mReflectionMapType = type; + if (type != TEX_TYPE_2D && type != TEX_TYPE_CUBE_MAP) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Invalid texture type set - only 2D or Cube supported", + "ShaderExReflectionMap::setReflectionMapType"); + } + mReflectionMapType = type; } //----------------------------------------------------------------------- void ShaderExReflectionMap::setReflectionPower(const Real reflectionPower) { - mReflectionPowerValue = reflectionPower; - mReflectionPowerChanged = true; + mReflectionPowerValue = reflectionPower; + mReflectionPowerChanged = true; } //----------------------------------------------------------------------- void ShaderExReflectionMap::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList) { - if (mReflectionPowerChanged) - { - GpuProgramParametersSharedPtr fsParams = pass->getFragmentProgramParameters(); + if (mReflectionPowerChanged) + { + GpuProgramParametersSharedPtr fsParams = pass->getFragmentProgramParameters(); - mReflectionPower->setGpuParameter(mReflectionPowerValue); + mReflectionPower->setGpuParameter(mReflectionPowerValue); - mReflectionPowerChanged = false; - } + mReflectionPowerChanged = false; + } } //----------------------------------------------------------------------- -SubRenderState* ShaderExReflectionMapFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* ShaderExReflectionMapFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "rtss_ext_reflection_map") - { - if(prop->values.size() >= 2) - { - String strValue; - AbstractNodeList::const_iterator it = prop->values.begin(); - - // Read reflection map type. - if(false == SGScriptTranslator::getString(*it, &strValue)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - return NULL; - } - ++it; - - SubRenderState* subRenderState = SubRenderStateFactory::createInstance(); - ShaderExReflectionMap* reflectionMapSubRenderState = static_cast(subRenderState); - - - // Reflection map is cubic texture. - if (strValue == "cube_map") - { - reflectionMapSubRenderState->setReflectionMapType(TEX_TYPE_CUBE_MAP); - } - - // Reflection map is 2d texture. - else if (strValue == "2d_map") - { - reflectionMapSubRenderState->setReflectionMapType(TEX_TYPE_2D); - } - - // Read mask texture. - if (false == SGScriptTranslator::getString(*it, &strValue)) - { - compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); - return NULL; - } - reflectionMapSubRenderState->setMaskMapTextureName(strValue); - ++it; - - - // Read reflection texture. - if (false == SGScriptTranslator::getString(*it, &strValue)) - { - compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); - return NULL; - } - reflectionMapSubRenderState->setReflectionMapTextureName(strValue); - ++it; - - // Read reflection power value. - Real reflectionPower = 0.5; - if (false == SGScriptTranslator::getReal(*it, &reflectionPower)) - { - compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); - return NULL; - } - reflectionMapSubRenderState->setReflectionPower(reflectionPower); - - return subRenderState; - - } - } - - return NULL; + if (prop->name == "rtss_ext_reflection_map") + { + if(prop->values.size() >= 2) + { + String strValue; + AbstractNodeList::const_iterator it = prop->values.begin(); + + // Read reflection map type. + if(false == SGScriptTranslator::getString(*it, &strValue)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + return NULL; + } + ++it; + + SubRenderState* subRenderState = SubRenderStateFactory::createInstance(); + ShaderExReflectionMap* reflectionMapSubRenderState = static_cast(subRenderState); + + + // Reflection map is cubic texture. + if (strValue == "cube_map") + { + reflectionMapSubRenderState->setReflectionMapType(TEX_TYPE_CUBE_MAP); + } + + // Reflection map is 2d texture. + else if (strValue == "2d_map") + { + reflectionMapSubRenderState->setReflectionMapType(TEX_TYPE_2D); + } + + // Read mask texture. + if (false == SGScriptTranslator::getString(*it, &strValue)) + { + compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); + return NULL; + } + reflectionMapSubRenderState->setMaskMapTextureName(strValue); + ++it; + + + // Read reflection texture. + if (false == SGScriptTranslator::getString(*it, &strValue)) + { + compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); + return NULL; + } + reflectionMapSubRenderState->setReflectionMapTextureName(strValue); + ++it; + + // Read reflection power value. + Real reflectionPower = 0.5; + if (false == SGScriptTranslator::getReal(*it, &reflectionPower)) + { + compiler->addError(ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line); + return NULL; + } + reflectionMapSubRenderState->setReflectionPower(reflectionPower); + + return subRenderState; + + } + } + + return NULL; } //----------------------------------------------------------------------- void ShaderExReflectionMapFactory::writeInstance(MaterialSerializer* ser, - SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + SubRenderState* subRenderState, + Pass* srcPass, Pass* dstPass) { - ser->writeAttribute(4, "rtss_ext_reflection_map"); - - - ShaderExReflectionMap* reflectionMapSubRenderState = static_cast(subRenderState); - - if (reflectionMapSubRenderState->getReflectionMapType() == TEX_TYPE_CUBE_MAP) - { - ser->writeValue("cube_map"); - } - else if (reflectionMapSubRenderState->getReflectionMapType() == TEX_TYPE_2D) - { - ser->writeValue("2d_map"); - } - - ser->writeValue(reflectionMapSubRenderState->getMaskMapTextureName()); - ser->writeValue(reflectionMapSubRenderState->getReflectionMapTextureName()); - ser->writeValue(StringConverter::toString(reflectionMapSubRenderState->getReflectionPower())); + ser->writeAttribute(4, "rtss_ext_reflection_map"); + + + ShaderExReflectionMap* reflectionMapSubRenderState = static_cast(subRenderState); + + if (reflectionMapSubRenderState->getReflectionMapType() == TEX_TYPE_CUBE_MAP) + { + ser->writeValue("cube_map"); + } + else if (reflectionMapSubRenderState->getReflectionMapType() == TEX_TYPE_2D) + { + ser->writeValue("2d_map"); + } + + ser->writeValue(reflectionMapSubRenderState->getMaskMapTextureName()); + ser->writeValue(reflectionMapSubRenderState->getReflectionMapTextureName()); + ser->writeValue(StringConverter::toString(reflectionMapSubRenderState->getReflectionPower())); } //----------------------------------------------------------------------- const String& ShaderExReflectionMapFactory::getType() const { - return ShaderExReflectionMap::Type; + return ShaderExReflectionMap::Type; } //----------------------------------------------------------------------- -SubRenderState* ShaderExReflectionMapFactory::createInstanceImpl() +SubRenderState* ShaderExReflectionMapFactory::createInstanceImpl() { - return OGRE_NEW ShaderExReflectionMap; + return OGRE_NEW ShaderExReflectionMap; } diff --git a/Samples/ShaderSystem/src/ShaderSystem.cpp b/Samples/ShaderSystem/src/ShaderSystem.cpp index a53b5f44b90..b99f3f9ebb1 100644 --- a/Samples/ShaderSystem/src/ShaderSystem.cpp +++ b/Samples/ShaderSystem/src/ShaderSystem.cpp @@ -9,28 +9,28 @@ using namespace Ogre; using namespace OgreBites; //----------------------------------------------------------------------- -const String DIRECTIONAL_LIGHT_NAME = "DirectionalLight"; -const String POINT_LIGHT_NAME = "PointLight"; -const String INSTANCED_VIEWPORTS_NAME = "InstancedViewports"; -const String ADD_LOTS_OF_MODELS_NAME = "AddLotsOfModels"; -const String SPOT_LIGHT_NAME = "SpotLight"; -const String PER_PIXEL_FOG_BOX = "PerPixelFog"; -const String ATLAS_AUTO_BORDER_MODE = "AutoBorderAtlasing"; -const String MAIN_ENTITY_MESH = "ShaderSystem.mesh"; -const String SPECULAR_BOX = "SpecularBox"; -const String REFLECTIONMAP_BOX = "ReflectionMapBox"; -const String REFLECTIONMAP_POWER_SLIDER = "ReflectionPowerSlider"; -const String MAIN_ENTITY_NAME = "MainEntity"; -const String EXPORT_BUTTON_NAME = "ExportMaterial"; -const String FLUSH_BUTTON_NAME = "FlushShaderCache"; -const String LAYERBLEND_BUTTON_NAME = "ChangeLayerBlendType"; -const String MODIFIER_VALUE_SLIDER = "ModifierValueSlider"; -const String SAMPLE_MATERIAL_GROUP = "RTShaderSystemMaterialsGroup"; +const String DIRECTIONAL_LIGHT_NAME = "DirectionalLight"; +const String POINT_LIGHT_NAME = "PointLight"; +const String INSTANCED_VIEWPORTS_NAME = "InstancedViewports"; +const String ADD_LOTS_OF_MODELS_NAME = "AddLotsOfModels"; +const String SPOT_LIGHT_NAME = "SpotLight"; +const String PER_PIXEL_FOG_BOX = "PerPixelFog"; +const String ATLAS_AUTO_BORDER_MODE = "AutoBorderAtlasing"; +const String MAIN_ENTITY_MESH = "ShaderSystem.mesh"; +const String SPECULAR_BOX = "SpecularBox"; +const String REFLECTIONMAP_BOX = "ReflectionMapBox"; +const String REFLECTIONMAP_POWER_SLIDER = "ReflectionPowerSlider"; +const String MAIN_ENTITY_NAME = "MainEntity"; +const String EXPORT_BUTTON_NAME = "ExportMaterial"; +const String FLUSH_BUTTON_NAME = "FlushShaderCache"; +const String LAYERBLEND_BUTTON_NAME = "ChangeLayerBlendType"; +const String MODIFIER_VALUE_SLIDER = "ModifierValueSlider"; +const String SAMPLE_MATERIAL_GROUP = "RTShaderSystemMaterialsGroup"; const int MESH_ARRAY_SIZE = 2; const String MESH_ARRAY[MESH_ARRAY_SIZE] = { - MAIN_ENTITY_MESH, - "knot.mesh" + MAIN_ENTITY_MESH, + "knot.mesh" }; #ifndef OGRE_STATIC_LIB @@ -41,50 +41,50 @@ Sample* s; //----------------------------------------------------------------------- extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_ShaderSystem; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_ShaderSystem; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } //----------------------------------------------------------------------- extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif //----------------------------------------------------------------------- Sample_ShaderSystem::Sample_ShaderSystem() : - mLayeredBlendingEntity(NULL) + mLayeredBlendingEntity(NULL) { - mInfo["Title"] = "Shader System"; - mInfo["Description"] = "Demonstrate the capabilities of the RT Shader System component." - "1. Fixed Function Pipeline emulation." - "2. On the fly shader generation based on existing material." - "3. On the fly shader synchronization with scene state (Lights, Fog)." - "4. Built in lighting models: Per vertex, Per pixel, Normal map tangent and object space." - "5. Pluggable custom shaders extensions." - "6. Built in material script parsing that includes extended attributes." - "7. Built in material script serialization." - ; - mInfo["Thumbnail"] = "thumb_shadersystem.png"; - mInfo["Category"] = "Lighting"; - mInfo["Help"] = "F2 Toggle Shader System globally. " - "F3 Toggles Global Lighting Model. " - "Modify target model attributes and scene settings and observe the generated shaders count. " - "Press the export button in order to export current target model material. " - "The model above the target will import this material next time the sample reloads. " - "Right click on object to see the shaders it currently uses. " - ; - mPointLightNode = NULL; - mReflectionMapFactory = NULL; - mInstancedViewportsEnable = false; - mInstancedViewportsSubRenderState = NULL; - mInstancedViewportsFactory = NULL; - mBbsFlare = NULL; + mInfo["Title"] = "Shader System"; + mInfo["Description"] = "Demonstrate the capabilities of the RT Shader System component." + "1. Fixed Function Pipeline emulation." + "2. On the fly shader generation based on existing material." + "3. On the fly shader synchronization with scene state (Lights, Fog)." + "4. Built in lighting models: Per vertex, Per pixel, Normal map tangent and object space." + "5. Pluggable custom shaders extensions." + "6. Built in material script parsing that includes extended attributes." + "7. Built in material script serialization." + ; + mInfo["Thumbnail"] = "thumb_shadersystem.png"; + mInfo["Category"] = "Lighting"; + mInfo["Help"] = "F2 Toggle Shader System globally. " + "F3 Toggles Global Lighting Model. " + "Modify target model attributes and scene settings and observe the generated shaders count. " + "Press the export button in order to export current target model material. " + "The model above the target will import this material next time the sample reloads. " + "Right click on object to see the shaders it currently uses. " + ; + mPointLightNode = NULL; + mReflectionMapFactory = NULL; + mInstancedViewportsEnable = false; + mInstancedViewportsSubRenderState = NULL; + mInstancedViewportsFactory = NULL; + mBbsFlare = NULL; mAddedLotsOfModels = false; mNumberOfModelsAdded = 0; } @@ -96,314 +96,314 @@ Sample_ShaderSystem::~Sample_ShaderSystem() void Sample_ShaderSystem::_shutdown() { - destroyInstancedViewports(); - SdkSample::_shutdown(); + destroyInstancedViewports(); + SdkSample::_shutdown(); } //----------------------------------------------------------------------- void Sample_ShaderSystem::checkBoxToggled(CheckBox* box) { - const String& cbName = box->getName(); - - if (cbName == SPECULAR_BOX) - { - setSpecularEnable(box->isChecked()); - } - else if (cbName == REFLECTIONMAP_BOX) - { - setReflectionMapEnable(box->isChecked()); - } - else if (cbName == DIRECTIONAL_LIGHT_NAME) - { - updateLightState(cbName, box->isChecked()); - } - else if (cbName == POINT_LIGHT_NAME) - { - updateLightState(cbName, box->isChecked()); - } - else if (cbName == INSTANCED_VIEWPORTS_NAME) - { - updateInstancedViewports(box->isChecked()); - } - else if (cbName == ADD_LOTS_OF_MODELS_NAME) - { - updateAddLotsOfModels(box->isChecked()); - } - else if (cbName == SPOT_LIGHT_NAME) - { - updateLightState(cbName, box->isChecked()); - } - else if (cbName == PER_PIXEL_FOG_BOX) - { - setPerPixelFogEnable(box->isChecked()); - } - else if (cbName == ATLAS_AUTO_BORDER_MODE) - { - setAtlasBorderMode(box->isChecked()); - } + const String& cbName = box->getName(); + + if (cbName == SPECULAR_BOX) + { + setSpecularEnable(box->isChecked()); + } + else if (cbName == REFLECTIONMAP_BOX) + { + setReflectionMapEnable(box->isChecked()); + } + else if (cbName == DIRECTIONAL_LIGHT_NAME) + { + updateLightState(cbName, box->isChecked()); + } + else if (cbName == POINT_LIGHT_NAME) + { + updateLightState(cbName, box->isChecked()); + } + else if (cbName == INSTANCED_VIEWPORTS_NAME) + { + updateInstancedViewports(box->isChecked()); + } + else if (cbName == ADD_LOTS_OF_MODELS_NAME) + { + updateAddLotsOfModels(box->isChecked()); + } + else if (cbName == SPOT_LIGHT_NAME) + { + updateLightState(cbName, box->isChecked()); + } + else if (cbName == PER_PIXEL_FOG_BOX) + { + setPerPixelFogEnable(box->isChecked()); + } + else if (cbName == ATLAS_AUTO_BORDER_MODE) + { + setAtlasBorderMode(box->isChecked()); + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::itemSelected(SelectMenu* menu) { - if (menu == mLightingModelMenu) - { - int curModelIndex = menu->getSelectionIndex(); - - if (curModelIndex >= SSLM_PerVertexLighting && curModelIndex <= SSLM_NormalMapLightingObjectSpace) - { - setCurrentLightingModel((ShaderSystemLightingModel)curModelIndex); - } - } - else if (menu == mFogModeMenu) - { - int curModeIndex = menu->getSelectionIndex(); - - if (curModeIndex >= FOG_NONE && curModeIndex <= FOG_LINEAR) - { - mSceneMgr->setFog((FogMode)curModeIndex, ColourValue(1.0, 1.0, 1.0, 0.0), 0.0015, 350.0, 1500.0); - } - } - else if (menu == mShadowMenu) - { - int curShadowTypeIndex = menu->getSelectionIndex(); - - applyShadowType(curShadowTypeIndex); - } - else if(menu == mLanguageMenu) - { - ShaderGenerator::getSingletonPtr()->setTargetLanguage(menu->getSelectedItem()); - } + if (menu == mLightingModelMenu) + { + int curModelIndex = menu->getSelectionIndex(); + + if (curModelIndex >= SSLM_PerVertexLighting && curModelIndex <= SSLM_NormalMapLightingObjectSpace) + { + setCurrentLightingModel((ShaderSystemLightingModel)curModelIndex); + } + } + else if (menu == mFogModeMenu) + { + int curModeIndex = menu->getSelectionIndex(); + + if (curModeIndex >= FOG_NONE && curModeIndex <= FOG_LINEAR) + { + mSceneMgr->setFog((FogMode)curModeIndex, ColourValue(1.0, 1.0, 1.0, 0.0), 0.0015, 350.0, 1500.0); + } + } + else if (menu == mShadowMenu) + { + int curShadowTypeIndex = menu->getSelectionIndex(); + + applyShadowType(curShadowTypeIndex); + } + else if(menu == mLanguageMenu) + { + ShaderGenerator::getSingletonPtr()->setTargetLanguage(menu->getSelectedItem()); + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::buttonHit( OgreBites::Button* b ) { - // Case the current material of the main entity should be exported. - if (b->getName() == EXPORT_BUTTON_NAME) - { - const String& materialName = mSceneMgr->getEntity(MAIN_ENTITY_NAME)->getSubEntity(0)->getMaterialName(); - - exportRTShaderSystemMaterial(mExportMaterialPath + "ShaderSystemExport.material", materialName); - } - // Case the shader cache should be flushed. - else if (b->getName() == FLUSH_BUTTON_NAME) - { - mShaderGenerator->flushShaderCache(); - } - - // Case the blend layer type modified. - else if (b->getName() == LAYERBLEND_BUTTON_NAME && mLayerBlendSubRS != NULL) - { - changeTextureLayerBlendMode(); - - } + // Case the current material of the main entity should be exported. + if (b->getName() == EXPORT_BUTTON_NAME) + { + const String& materialName = mSceneMgr->getEntity(MAIN_ENTITY_NAME)->getSubEntity(0)->getMaterialName(); + + exportRTShaderSystemMaterial(mExportMaterialPath + "ShaderSystemExport.material", materialName); + } + // Case the shader cache should be flushed. + else if (b->getName() == FLUSH_BUTTON_NAME) + { + mShaderGenerator->flushShaderCache(); + } + + // Case the blend layer type modified. + else if (b->getName() == LAYERBLEND_BUTTON_NAME && mLayerBlendSubRS != NULL) + { + changeTextureLayerBlendMode(); + + } } //-------------------------------------------------------------------------- void Sample_ShaderSystem::sliderMoved(Slider* slider) { - if (slider->getName() == REFLECTIONMAP_POWER_SLIDER) - { - Real reflectionPower = slider->getValue(); - - if (mReflectionMapSubRS != NULL) - { - ShaderExReflectionMap* reflectionMapSubRS = static_cast(mReflectionMapSubRS); - - // Since RTSS export caps based on the template sub render states we have to update the template reflection sub render state. - reflectionMapSubRS->setReflectionPower(reflectionPower); - - // Grab the instances set and update them with the new reflection power value. - // The instances are the actual sub render states that have been assembled to create the final shaders. - // Every time that the shaders have to be re-generated (light changes, fog changes etc..) a new set of sub render states - // based on the template sub render states assembled for each pass. - // From that set of instances a CPU program is generated and afterward a GPU program finally generated. - RTShader::SubRenderStateSet instanceSet = mReflectionMapSubRS->getAccessor()->getSubRenderStateInstanceSet(); - RTShader::SubRenderStateSetIterator it = instanceSet.begin(); - RTShader::SubRenderStateSetIterator itEnd = instanceSet.end(); - - for (; it != itEnd; ++it) - { - ShaderExReflectionMap* reflectionMapSubRSInstance = static_cast(*it); - - reflectionMapSubRSInstance->setReflectionPower(reflectionPower); - } - } - } - - if (slider->getName() == MODIFIER_VALUE_SLIDER) - { - if (mLayeredBlendingEntity != NULL) - { - Ogre::Real val = mModifierValueSlider->getValue(); - mLayeredBlendingEntity->getSubEntity(0)->setCustomParameter(2, Vector4(val,val,val,0)); - } - } + if (slider->getName() == REFLECTIONMAP_POWER_SLIDER) + { + Real reflectionPower = slider->getValue(); + + if (mReflectionMapSubRS != NULL) + { + ShaderExReflectionMap* reflectionMapSubRS = static_cast(mReflectionMapSubRS); + + // Since RTSS export caps based on the template sub render states we have to update the template reflection sub render state. + reflectionMapSubRS->setReflectionPower(reflectionPower); + + // Grab the instances set and update them with the new reflection power value. + // The instances are the actual sub render states that have been assembled to create the final shaders. + // Every time that the shaders have to be re-generated (light changes, fog changes etc..) a new set of sub render states + // based on the template sub render states assembled for each pass. + // From that set of instances a CPU program is generated and afterward a GPU program finally generated. + RTShader::SubRenderStateSet instanceSet = mReflectionMapSubRS->getAccessor()->getSubRenderStateInstanceSet(); + RTShader::SubRenderStateSetIterator it = instanceSet.begin(); + RTShader::SubRenderStateSetIterator itEnd = instanceSet.end(); + + for (; it != itEnd; ++it) + { + ShaderExReflectionMap* reflectionMapSubRSInstance = static_cast(*it); + + reflectionMapSubRSInstance->setReflectionPower(reflectionPower); + } + } + } + + if (slider->getName() == MODIFIER_VALUE_SLIDER) + { + if (mLayeredBlendingEntity != NULL) + { + Ogre::Real val = mModifierValueSlider->getValue(); + mLayeredBlendingEntity->getSubEntity(0)->setCustomParameter(2, Vector4(val,val,val,0)); + } + } } //----------------------------------------------------------------------- bool Sample_ShaderSystem::frameRenderingQueued( const FrameEvent& evt ) -{ - if (mSceneMgr->hasLight(SPOT_LIGHT_NAME)) - { - Light* light = mSceneMgr->getLight(SPOT_LIGHT_NAME); - - light->setPosition(mCamera->getDerivedPosition() + mCamera->getDerivedUp() * 20.0); - light->setDirection(mCamera->getDerivedDirection()); - } - - if (mPointLightNode != NULL) - { - static Real sToatalTime = 0.0; - - sToatalTime += evt.timeSinceLastFrame; - mPointLightNode->yaw(Degree(evt.timeSinceLastFrame * 15)); - mPointLightNode->setPosition(0.0, Math::Sin(sToatalTime) * 30.0, 0.0); - } - - updateTargetObjInfo(); - - return SdkSample::frameRenderingQueued(evt); +{ + if (mSceneMgr->hasLight(SPOT_LIGHT_NAME)) + { + Light* light = mSceneMgr->getLight(SPOT_LIGHT_NAME); + + light->setPosition(mCamera->getDerivedPosition() + mCamera->getDerivedUp() * 20.0); + light->setDirection(mCamera->getDerivedDirection()); + } + + if (mPointLightNode != NULL) + { + static Real sToatalTime = 0.0; + + sToatalTime += evt.timeSinceLastFrame; + mPointLightNode->yaw(Degree(evt.timeSinceLastFrame * 15)); + mPointLightNode->setPosition(0.0, Math::Sin(sToatalTime) * 30.0, 0.0); + } + + updateTargetObjInfo(); + + return SdkSample::frameRenderingQueued(evt); } //----------------------------------------------------------------------- //void Sample_ShaderSystem::setupView() -//{ -// // setup default viewport layout and camera -// mCamera = mSceneMgr->createCamera("MainCamera"); -// mViewport = mWindow->addViewport(mCamera); -// mCamera->setAspectRatio((Ogre::Real)mViewport->getActualWidth() / (Ogre::Real)mViewport->getActualHeight()); -// mCamera->setNearClipDistance(5); +//{ +// // setup default viewport layout and camera +// mCamera = mSceneMgr->createCamera("MainCamera"); +// mViewport = mWindow->addViewport(mCamera); +// mCamera->setAspectRatio((Ogre::Real)mViewport->getActualWidth() / (Ogre::Real)mViewport->getActualHeight()); +// mCamera->setNearClipDistance(5); // -// mCameraMan = new SdkCameraMan(mCamera); // create a default camera controller +// mCameraMan = new SdkCameraMan(mCamera); // create a default camera controller //} //----------------------------------------------------------------------- void Sample_ShaderSystem::setupContent() { - - // Setup default effects values. - mCurLightingModel = SSLM_PerVertexLighting; - mPerPixelFogEnable = false; - mSpecularEnable = false; - mReflectionMapEnable = false; - mReflectionMapSubRS = NULL; - mLayerBlendSubRS = NULL; - - mRayQuery = mSceneMgr->createRayQuery(Ray()); - mTargetObj = NULL; - - - // Set ambient lighting. - mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); - - // Setup the sky box, - mSceneMgr->setSkyBox(true, "Examples/SceneCubeMap2"); - - MeshManager::getSingleton().createPlane("Myplane", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Plane(Vector3::UNIT_Y, 0), - 1500,1500,25,25,true,1,60,60,Vector3::UNIT_Z); - - Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); - pPlaneEnt->setMaterialName("Examples/Rockwall"); - pPlaneEnt->setCastShadows(false); - mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0))->attachObject(pPlaneEnt); - - - // Load sample meshes and generate tangent vectors. - for (int i=0; i < MESH_ARRAY_SIZE; ++i) - { - const String& curMeshName = MESH_ARRAY[i]; - - MeshPtr pMesh = MeshManager::getSingleton().load(curMeshName, - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, - HardwareBuffer::HBU_STATIC_WRITE_ONLY, - true, true); //so we can still read it - - // Build tangent vectors, all our meshes use only 1 texture coordset - // Note we can build into VES_TANGENT now (SM2+) - unsigned short src, dest; - if (!pMesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) - { - pMesh->buildTangentVectors(VES_TANGENT, src, dest); - } - } - - - - Entity* entity; - SceneNode* childNode; - - // Create the main entity and mark it as the current target object. - entity = mSceneMgr->createEntity(MAIN_ENTITY_NAME, MAIN_ENTITY_MESH); - mTargetEntities.push_back(entity); - childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - childNode->attachObject(entity); - mTargetObj = entity; - childNode->showBoundingBox(true); - - // Create reflection entity that will show the exported material. - const String& mainExportedMaterial = mSceneMgr->getEntity(MAIN_ENTITY_NAME)->getSubEntity(0)->getMaterialName() + "_RTSS_Export"; - MaterialPtr matMainEnt = MaterialManager::getSingleton().getByName(mainExportedMaterial, SAMPLE_MATERIAL_GROUP); - - entity = mSceneMgr->createEntity("ExportedMaterialEntity", MAIN_ENTITY_MESH); - entity->setMaterial(matMainEnt); - childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - childNode->setPosition(0.0, 200.0, -200.0); - childNode->attachObject(entity); - - // Create texture layer blending demonstration entity. - mLayeredBlendingEntity = mSceneMgr->createEntity("LayeredBlendingMaterialEntity", MAIN_ENTITY_MESH); - mLayeredBlendingEntity->setMaterialName("RTSS/LayeredBlending"); - mLayeredBlendingEntity->getSubEntity(0)->setCustomParameter(2, Vector4::ZERO); - childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - childNode->setPosition(300.0, 200.0, -200.0); - childNode->attachObject(mLayeredBlendingEntity); - - // Grab the render state of the material. - RTShader::RenderState* renderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, "RTSS/LayeredBlending", 0); - - if (renderState != NULL) - { - const SubRenderStateList& subRenderStateList = renderState->getTemplateSubRenderStateList(); - SubRenderStateListConstIterator it = subRenderStateList.begin(); - SubRenderStateListConstIterator itEnd = subRenderStateList.end(); - - // Search for the texture layer blend sub state. - for (; it != itEnd; ++it) - { - SubRenderState* curSubRenderState = *it; - - if (curSubRenderState->getType() == LayeredBlending::Type) - { - mLayerBlendSubRS = static_cast(curSubRenderState); - break; - } - } - } - - - // Create per pixel lighting demonstration entity. - entity = mSceneMgr->createEntity("PerPixelEntity", "knot.mesh"); - entity->setMaterialName("RTSS/PerPixel_SinglePass"); - childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - childNode->setPosition(300.0, 100.0, -100.0); - childNode->attachObject(entity); - - // Create normal map lighting demonstration entity. - entity = mSceneMgr->createEntity("NormalMapEntity", "knot.mesh"); - entity->setMaterialName("RTSS/NormalMapping_SinglePass"); - childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - childNode->setPosition(-300.0, 100.0, -100.0); - childNode->attachObject(entity); + + // Setup default effects values. + mCurLightingModel = SSLM_PerVertexLighting; + mPerPixelFogEnable = false; + mSpecularEnable = false; + mReflectionMapEnable = false; + mReflectionMapSubRS = NULL; + mLayerBlendSubRS = NULL; + + mRayQuery = mSceneMgr->createRayQuery(Ray()); + mTargetObj = NULL; + + + // Set ambient lighting. + mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); + + // Setup the sky box, + mSceneMgr->setSkyBox(true, "Examples/SceneCubeMap2"); + + MeshManager::getSingleton().createPlane("Myplane", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Plane(Vector3::UNIT_Y, 0), + 1500,1500,25,25,true,1,60,60,Vector3::UNIT_Z); + + Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); + pPlaneEnt->setMaterialName("Examples/Rockwall"); + pPlaneEnt->setCastShadows(false); + mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0))->attachObject(pPlaneEnt); + + + // Load sample meshes and generate tangent vectors. + for (int i=0; i < MESH_ARRAY_SIZE; ++i) + { + const String& curMeshName = MESH_ARRAY[i]; + + MeshPtr pMesh = MeshManager::getSingleton().load(curMeshName, + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, + HardwareBuffer::HBU_STATIC_WRITE_ONLY, + true, true); //so we can still read it + + // Build tangent vectors, all our meshes use only 1 texture coordset + // Note we can build into VES_TANGENT now (SM2+) + unsigned short src, dest; + if (!pMesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) + { + pMesh->buildTangentVectors(VES_TANGENT, src, dest); + } + } + + + + Entity* entity; + SceneNode* childNode; + + // Create the main entity and mark it as the current target object. + entity = mSceneMgr->createEntity(MAIN_ENTITY_NAME, MAIN_ENTITY_MESH); + mTargetEntities.push_back(entity); + childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + childNode->attachObject(entity); + mTargetObj = entity; + childNode->showBoundingBox(true); + + // Create reflection entity that will show the exported material. + const String& mainExportedMaterial = mSceneMgr->getEntity(MAIN_ENTITY_NAME)->getSubEntity(0)->getMaterialName() + "_RTSS_Export"; + MaterialPtr matMainEnt = MaterialManager::getSingleton().getByName(mainExportedMaterial, SAMPLE_MATERIAL_GROUP); + + entity = mSceneMgr->createEntity("ExportedMaterialEntity", MAIN_ENTITY_MESH); + entity->setMaterial(matMainEnt); + childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + childNode->setPosition(0.0, 200.0, -200.0); + childNode->attachObject(entity); + + // Create texture layer blending demonstration entity. + mLayeredBlendingEntity = mSceneMgr->createEntity("LayeredBlendingMaterialEntity", MAIN_ENTITY_MESH); + mLayeredBlendingEntity->setMaterialName("RTSS/LayeredBlending"); + mLayeredBlendingEntity->getSubEntity(0)->setCustomParameter(2, Vector4::ZERO); + childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + childNode->setPosition(300.0, 200.0, -200.0); + childNode->attachObject(mLayeredBlendingEntity); + + // Grab the render state of the material. + RTShader::RenderState* renderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, "RTSS/LayeredBlending", 0); + + if (renderState != NULL) + { + const SubRenderStateList& subRenderStateList = renderState->getTemplateSubRenderStateList(); + SubRenderStateListConstIterator it = subRenderStateList.begin(); + SubRenderStateListConstIterator itEnd = subRenderStateList.end(); + + // Search for the texture layer blend sub state. + for (; it != itEnd; ++it) + { + SubRenderState* curSubRenderState = *it; + + if (curSubRenderState->getType() == LayeredBlending::Type) + { + mLayerBlendSubRS = static_cast(curSubRenderState); + break; + } + } + } + + + // Create per pixel lighting demonstration entity. + entity = mSceneMgr->createEntity("PerPixelEntity", "knot.mesh"); + entity->setMaterialName("RTSS/PerPixel_SinglePass"); + childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + childNode->setPosition(300.0, 100.0, -100.0); + childNode->attachObject(entity); + + // Create normal map lighting demonstration entity. + entity = mSceneMgr->createEntity("NormalMapEntity", "knot.mesh"); + entity->setMaterialName("RTSS/NormalMapping_SinglePass"); + childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + childNode->setPosition(-300.0, 100.0, -100.0); + childNode->attachObject(entity); // OpenGL ES 2.0 does not support texture atlases. But ES 3.0 does! #if OGRE_NO_GLES3_SUPPORT == 1 - if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL ES 2") == String::npos) + if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL ES 2") == String::npos) #endif { RTShader::RenderState* pMainRenderState = @@ -419,258 +419,258 @@ void Sample_ShaderSystem::setupContent() childNode->attachObject(atlasObject); } - createDirectionalLight(); - createPointLight(); - createSpotLight(); + createDirectionalLight(); + createPointLight(); + createSpotLight(); - RenderState* schemRenderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + RenderState* schemRenderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - // Take responsibility for updating the light count manually. - schemRenderState->setLightCountAutoUpdate(false); - - setupUI(); + // Take responsibility for updating the light count manually. + schemRenderState->setLightCountAutoUpdate(false); + + setupUI(); - mCamera->setPosition(0.0, 300.0, 450.0); - mCamera->lookAt(0.0, 150.0, 0.0); + mCamera->setPosition(0.0, 300.0, 450.0); + mCamera->lookAt(0.0, 150.0, 0.0); - // Make this viewport work with shader generator scheme. - mViewport->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + // Make this viewport work with shader generator scheme. + mViewport->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - // Mark system as on. - mDetailsPanel->setParamValue(11, "On"); + // Mark system as on. + mDetailsPanel->setParamValue(11, "On"); - - // a friendly reminder - StringVector names; - names.push_back("Help"); - mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); + + // a friendly reminder + StringVector names; + names.push_back("Help"); + mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); - updateSystemShaders(); + updateSystemShaders(); } //----------------------------------------------------------------------- void Sample_ShaderSystem::setupUI() { - // Create language selection - mLanguageMenu = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "LangMode", "Language", 220, 120, 10); + // Create language selection + mLanguageMenu = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "LangMode", "Language", 220, 120, 10); // Use GLSL ES in case of OpenGL ES 2 render system. - if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL ES 2") != String::npos) - { - mLanguageMenu->addItem("glsles"); - mShaderGenerator->setTargetLanguage("glsles"); - } + if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL ES 2") != String::npos) + { + mLanguageMenu->addItem("glsles"); + mShaderGenerator->setTargetLanguage("glsles"); + } // Use GLSL in case of OpenGL render system. else if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("OpenGL") != String::npos) - { - mLanguageMenu->addItem("glsl"); - mShaderGenerator->setTargetLanguage("glsl"); - } - - // Use HLSL in case of D3D9 render system. - else if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("Direct3D9") != String::npos) - { - mLanguageMenu->addItem("hlsl"); - mShaderGenerator->setTargetLanguage("hlsl"); - } - mLanguageMenu->addItem("cg"); - - // create check boxes to toggle lights. - mDirLightCheckBox = mTrayMgr->createCheckBox(TL_TOPLEFT, DIRECTIONAL_LIGHT_NAME, "Directional Light", 220); - mPointLightCheckBox = mTrayMgr->createCheckBox(TL_TOPLEFT, POINT_LIGHT_NAME, "Point Light", 220); - mSpotLightCheckBox = mTrayMgr->createCheckBox(TL_TOPLEFT, SPOT_LIGHT_NAME, "Spot Light", 220); - - mInstancedViewportsCheckBox = mTrayMgr->createCheckBox(TL_TOPLEFT, INSTANCED_VIEWPORTS_NAME, "Instanced Viewports", 220); - mAddLotsOfModels = mTrayMgr->createCheckBox(TL_TOPLEFT, ADD_LOTS_OF_MODELS_NAME, "Add lots of models", 220); - - mDirLightCheckBox->setChecked(true); - mPointLightCheckBox->setChecked(true); - mSpotLightCheckBox->setChecked(false); - mInstancedViewportsCheckBox->setChecked(false); - mAddLotsOfModels->setChecked(false); + { + mLanguageMenu->addItem("glsl"); + mShaderGenerator->setTargetLanguage("glsl"); + } + + // Use HLSL in case of D3D9 render system. + else if (Ogre::Root::getSingletonPtr()->getRenderSystem()->getName().find("Direct3D9") != String::npos) + { + mLanguageMenu->addItem("hlsl"); + mShaderGenerator->setTargetLanguage("hlsl"); + } + mLanguageMenu->addItem("cg"); + + // create check boxes to toggle lights. + mDirLightCheckBox = mTrayMgr->createCheckBox(TL_TOPLEFT, DIRECTIONAL_LIGHT_NAME, "Directional Light", 220); + mPointLightCheckBox = mTrayMgr->createCheckBox(TL_TOPLEFT, POINT_LIGHT_NAME, "Point Light", 220); + mSpotLightCheckBox = mTrayMgr->createCheckBox(TL_TOPLEFT, SPOT_LIGHT_NAME, "Spot Light", 220); + + mInstancedViewportsCheckBox = mTrayMgr->createCheckBox(TL_TOPLEFT, INSTANCED_VIEWPORTS_NAME, "Instanced Viewports", 220); + mAddLotsOfModels = mTrayMgr->createCheckBox(TL_TOPLEFT, ADD_LOTS_OF_MODELS_NAME, "Add lots of models", 220); + + mDirLightCheckBox->setChecked(true); + mPointLightCheckBox->setChecked(true); + mSpotLightCheckBox->setChecked(false); + mInstancedViewportsCheckBox->setChecked(false); + mAddLotsOfModels->setChecked(false); #ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS - mTrayMgr->createCheckBox(TL_TOPLEFT, PER_PIXEL_FOG_BOX, "Per Pixel Fog", 220)->setChecked(mPerPixelFogEnable); + mTrayMgr->createCheckBox(TL_TOPLEFT, PER_PIXEL_FOG_BOX, "Per Pixel Fog", 220)->setChecked(mPerPixelFogEnable); #endif #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - mTrayMgr->createCheckBox(TL_TOPLEFT, ATLAS_AUTO_BORDER_MODE, "Atlas auto border", 220)->setChecked(true); - setAtlasBorderMode(true); + mTrayMgr->createCheckBox(TL_TOPLEFT, ATLAS_AUTO_BORDER_MODE, "Atlas auto border", 220)->setChecked(true); + setAtlasBorderMode(true); #endif - // Create fog widgets. - mFogModeMenu = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "FogMode", "Fog Mode", 220, 120, 10); - mFogModeMenu->addItem("None"); - mFogModeMenu->addItem("Exp"); - mFogModeMenu->addItem("Exp2"); - mFogModeMenu->addItem("Linear"); + // Create fog widgets. + mFogModeMenu = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "FogMode", "Fog Mode", 220, 120, 10); + mFogModeMenu->addItem("None"); + mFogModeMenu->addItem("Exp"); + mFogModeMenu->addItem("Exp2"); + mFogModeMenu->addItem("Linear"); - // Create shadow menu. - mShadowMenu = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "ShadowType", "Shadow", 220, 120, 10); - mShadowMenu->addItem("None"); + // Create shadow menu. + mShadowMenu = mTrayMgr->createLongSelectMenu(TL_TOPLEFT, "ShadowType", "Shadow", 220, 120, 10); + mShadowMenu->addItem("None"); #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - mShadowMenu->addItem("PSSM 3"); + mShadowMenu->addItem("PSSM 3"); #endif - // Flush shader cache button. - mTrayMgr->createButton(TL_TOPLEFT, FLUSH_BUTTON_NAME, "Flush Shader Cache", 220); + // Flush shader cache button. + mTrayMgr->createButton(TL_TOPLEFT, FLUSH_BUTTON_NAME, "Flush Shader Cache", 220); - // create target model widgets. - mTargetObjMatName = mTrayMgr->createLabel(TL_TOPLEFT, "TargetObjMatName", "", 220); - mTargetObjVS = mTrayMgr->createLabel(TL_TOPLEFT, "TargetObjVS", "", 220); - mTargetObjFS = mTrayMgr->createLabel(TL_TOPLEFT, "TargetObjFS", "", 220); + // create target model widgets. + mTargetObjMatName = mTrayMgr->createLabel(TL_TOPLEFT, "TargetObjMatName", "", 220); + mTargetObjVS = mTrayMgr->createLabel(TL_TOPLEFT, "TargetObjVS", "", 220); + mTargetObjFS = mTrayMgr->createLabel(TL_TOPLEFT, "TargetObjFS", "", 220); - - // Create main entity widgets. - mTrayMgr->createLabel(TL_BOTTOM, "MainEntityLabel", "Main Entity Settings", 240); - mTrayMgr->createCheckBox(TL_BOTTOM, SPECULAR_BOX, "Specular", 240)->setChecked(mSpecularEnable); + + // Create main entity widgets. + mTrayMgr->createLabel(TL_BOTTOM, "MainEntityLabel", "Main Entity Settings", 240); + mTrayMgr->createCheckBox(TL_BOTTOM, SPECULAR_BOX, "Specular", 240)->setChecked(mSpecularEnable); - // Allow reflection map only on PS3 and above since with all lights on + specular + bump we - // exceed the instruction count limits of PS2. - if (GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0") || + // Allow reflection map only on PS3 and above since with all lights on + specular + bump we + // exceed the instruction count limits of PS2. + if (GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0") || GpuProgramManager::getSingleton().isSyntaxSupported("glsles") || - GpuProgramManager::getSingleton().isSyntaxSupported("fp30")) - { - mTrayMgr->createCheckBox(TL_BOTTOM, REFLECTIONMAP_BOX, "Reflection Map", 240)->setChecked(mReflectionMapEnable); - mReflectionPowerSlider = mTrayMgr->createThickSlider(TL_BOTTOM, REFLECTIONMAP_POWER_SLIDER, "Reflection Power", 240, 80, 0, 1, 100); - mReflectionPowerSlider->setValue(0.5, false); - } + GpuProgramManager::getSingleton().isSyntaxSupported("fp30")) + { + mTrayMgr->createCheckBox(TL_BOTTOM, REFLECTIONMAP_BOX, "Reflection Map", 240)->setChecked(mReflectionMapEnable); + mReflectionPowerSlider = mTrayMgr->createThickSlider(TL_BOTTOM, REFLECTIONMAP_POWER_SLIDER, "Reflection Power", 240, 80, 0, 1, 100); + mReflectionPowerSlider->setValue(0.5, false); + } - mLightingModelMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "TargetModelLighting", "", 240, 230, 10); - mLightingModelMenu ->addItem("Per Vertex"); + mLightingModelMenu = mTrayMgr->createLongSelectMenu(TL_BOTTOM, "TargetModelLighting", "", 240, 230, 10); + mLightingModelMenu ->addItem("Per Vertex"); #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - mLightingModelMenu ->addItem("Per Pixel"); - mLightingModelMenu ->addItem("Normal Map - Tangent Space"); - mLightingModelMenu ->addItem("Normal Map - Object Space"); + mLightingModelMenu ->addItem("Per Pixel"); + mLightingModelMenu ->addItem("Normal Map - Tangent Space"); + mLightingModelMenu ->addItem("Normal Map - Object Space"); #endif - mTrayMgr->createButton(TL_BOTTOM, EXPORT_BUTTON_NAME, "Export Material", 240); - + mTrayMgr->createButton(TL_BOTTOM, EXPORT_BUTTON_NAME, "Export Material", 240); + #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - mLayerBlendLabel = mTrayMgr->createLabel(TL_RIGHT, "Blend Type", "Blend Type", 240); - mTrayMgr->createButton(TL_RIGHT, LAYERBLEND_BUTTON_NAME, "Change Blend Type", 220); - mModifierValueSlider = mTrayMgr->createThickSlider(TL_RIGHT, MODIFIER_VALUE_SLIDER, "Modifier", 240, 80, 0, 1, 100); - mModifierValueSlider->setValue(0.0,false); - // Update the caption. - if(mLayerBlendSubRS) - updateLayerBlendingCaption(mLayerBlendSubRS->getBlendMode(1)); + mLayerBlendLabel = mTrayMgr->createLabel(TL_RIGHT, "Blend Type", "Blend Type", 240); + mTrayMgr->createButton(TL_RIGHT, LAYERBLEND_BUTTON_NAME, "Change Blend Type", 220); + mModifierValueSlider = mTrayMgr->createThickSlider(TL_RIGHT, MODIFIER_VALUE_SLIDER, "Modifier", 240, 80, 0, 1, 100); + mModifierValueSlider->setValue(0.0,false); + // Update the caption. + if(mLayerBlendSubRS) + updateLayerBlendingCaption(mLayerBlendSubRS->getBlendMode(1)); #endif - mTrayMgr->showCursor(); + mTrayMgr->showCursor(); } //----------------------------------------------------------------------- void Sample_ShaderSystem::cleanupContent() -{ - // UnLoad sample meshes and generate tangent vectors. - for (int i=0; i < MESH_ARRAY_SIZE; ++i) - { - const String& curMeshName = MESH_ARRAY[i]; - MeshManager::getSingleton().unload(curMeshName); - } - - MeshManager::getSingleton().remove(MAIN_ENTITY_MESH); - mTargetEntities.clear(); +{ + // UnLoad sample meshes and generate tangent vectors. + for (int i=0; i < MESH_ARRAY_SIZE; ++i) + { + const String& curMeshName = MESH_ARRAY[i]; + MeshManager::getSingleton().unload(curMeshName); + } + + MeshManager::getSingleton().remove(MAIN_ENTITY_MESH); + mTargetEntities.clear(); MeshManager::getSingleton().remove("Myplane"); - mSceneMgr->destroyQuery(mRayQuery); + mSceneMgr->destroyQuery(mRayQuery); } //----------------------------------------------------------------------- void Sample_ShaderSystem::setCurrentLightingModel(ShaderSystemLightingModel lightingModel) { - if (mCurLightingModel != lightingModel) - { - mCurLightingModel = lightingModel; - - EntityListIterator it = mTargetEntities.begin(); - EntityListIterator itEnd = mTargetEntities.end(); - - for (; it != itEnd; ++it) - { - generateShaders(*it); - } - } + if (mCurLightingModel != lightingModel) + { + mCurLightingModel = lightingModel; + + EntityListIterator it = mTargetEntities.begin(); + EntityListIterator itEnd = mTargetEntities.end(); + + for (; it != itEnd; ++it) + { + generateShaders(*it); + } + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::setSpecularEnable(bool enable) { - if (mSpecularEnable != enable) - { - mSpecularEnable = enable; - updateSystemShaders(); - } + if (mSpecularEnable != enable) + { + mSpecularEnable = enable; + updateSystemShaders(); + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::setReflectionMapEnable(bool enable) { - if (mReflectionMapEnable != enable) - { - mReflectionMapEnable = enable; - updateSystemShaders(); - } + if (mReflectionMapEnable != enable) + { + mReflectionMapEnable = enable; + updateSystemShaders(); + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::setPerPixelFogEnable( bool enable ) { #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - if (mPerPixelFogEnable != enable) - { - mPerPixelFogEnable = enable; - - // Grab the scheme render state. - RenderState* schemRenderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - const SubRenderStateList& subRenderStateList = schemRenderState->getTemplateSubRenderStateList(); - SubRenderStateListConstIterator it = subRenderStateList.begin(); - SubRenderStateListConstIterator itEnd = subRenderStateList.end(); - FFPFog* fogSubRenderState = NULL; - - // Search for the fog sub state. - for (; it != itEnd; ++it) - { - SubRenderState* curSubRenderState = *it; - - if (curSubRenderState->getType() == FFPFog::Type) - { - fogSubRenderState = static_cast(curSubRenderState); - break; - } - } - - // Create the fog sub render state if need to. - if (fogSubRenderState == NULL) - { - SubRenderState* subRenderState = mShaderGenerator->createSubRenderState(FFPFog::Type); - - fogSubRenderState = static_cast(subRenderState); - schemRenderState->addTemplateSubRenderState(fogSubRenderState); - } - - - // Select the desired fog calculation mode. - if (mPerPixelFogEnable) - { - fogSubRenderState->setCalcMode(FFPFog::CM_PER_PIXEL); - } - else - { - fogSubRenderState->setCalcMode(FFPFog::CM_PER_VERTEX); - } - - // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. - mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - } + if (mPerPixelFogEnable != enable) + { + mPerPixelFogEnable = enable; + + // Grab the scheme render state. + RenderState* schemRenderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + const SubRenderStateList& subRenderStateList = schemRenderState->getTemplateSubRenderStateList(); + SubRenderStateListConstIterator it = subRenderStateList.begin(); + SubRenderStateListConstIterator itEnd = subRenderStateList.end(); + FFPFog* fogSubRenderState = NULL; + + // Search for the fog sub state. + for (; it != itEnd; ++it) + { + SubRenderState* curSubRenderState = *it; + + if (curSubRenderState->getType() == FFPFog::Type) + { + fogSubRenderState = static_cast(curSubRenderState); + break; + } + } + + // Create the fog sub render state if need to. + if (fogSubRenderState == NULL) + { + SubRenderState* subRenderState = mShaderGenerator->createSubRenderState(FFPFog::Type); + + fogSubRenderState = static_cast(subRenderState); + schemRenderState->addTemplateSubRenderState(fogSubRenderState); + } + + + // Select the desired fog calculation mode. + if (mPerPixelFogEnable) + { + fogSubRenderState->setCalcMode(FFPFog::CM_PER_PIXEL); + } + else + { + fogSubRenderState->setCalcMode(FFPFog::CM_PER_VERTEX); + } + + // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. + mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + } #endif } @@ -678,9 +678,9 @@ void Sample_ShaderSystem::setPerPixelFogEnable( bool enable ) void Sample_ShaderSystem::setAtlasBorderMode( bool enable ) { #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - TextureAtlasSamplerFactory::getSingleton().setDefaultAtlasingAttributes( - TextureAtlasSamplerFactory::ipmRelative, 1, enable); - mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + TextureAtlasSamplerFactory::getSingleton().setDefaultAtlasingAttributes( + TextureAtlasSamplerFactory::ipmRelative, 1, enable); + mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); #endif } @@ -688,223 +688,223 @@ void Sample_ShaderSystem::setAtlasBorderMode( bool enable ) //----------------------------------------------------------------------- void Sample_ShaderSystem::updateSystemShaders() { - EntityListIterator it = mTargetEntities.begin(); - EntityListIterator itEnd = mTargetEntities.end(); + EntityListIterator it = mTargetEntities.begin(); + EntityListIterator itEnd = mTargetEntities.end(); - for (; it != itEnd; ++it) - { - generateShaders(*it); - } + for (; it != itEnd; ++it) + { + generateShaders(*it); + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::generateShaders(Entity* entity) { - for (unsigned int i=0; i < entity->getNumSubEntities(); ++i) - { - SubEntity* curSubEntity = entity->getSubEntity(i); - const String& curMaterialName = curSubEntity->getMaterialName(); - bool success; - - // Create the shader based technique of this material. - success = mShaderGenerator->createShaderBasedTechnique(curMaterialName, - MaterialManager::DEFAULT_SCHEME_NAME, - RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - - - // Setup custom shader sub render states according to current setup. - if (success) - { - MaterialPtr curMaterial = MaterialManager::getSingleton().getByName(curMaterialName); - Pass* curPass = curMaterial->getTechnique(0)->getPass(0); - - if (mSpecularEnable) - { - curPass->setSpecular(ColourValue::White); - curPass->setShininess(32.0); - } - else - { - curPass->setSpecular(ColourValue::Black); - curPass->setShininess(0.0); - } - - - // Grab the first pass render state. - // NOTE: For more complicated samples iterate over the passes and build each one of them as desired. - RTShader::RenderState* renderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, curMaterialName, 0); - - // Remove all sub render states. - renderState->reset(); + for (unsigned int i=0; i < entity->getNumSubEntities(); ++i) + { + SubEntity* curSubEntity = entity->getSubEntity(i); + const String& curMaterialName = curSubEntity->getMaterialName(); + bool success; + + // Create the shader based technique of this material. + success = mShaderGenerator->createShaderBasedTechnique(curMaterialName, + MaterialManager::DEFAULT_SCHEME_NAME, + RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + + + // Setup custom shader sub render states according to current setup. + if (success) + { + MaterialPtr curMaterial = MaterialManager::getSingleton().getByName(curMaterialName); + Pass* curPass = curMaterial->getTechnique(0)->getPass(0); + + if (mSpecularEnable) + { + curPass->setSpecular(ColourValue::White); + curPass->setShininess(32.0); + } + else + { + curPass->setSpecular(ColourValue::Black); + curPass->setShininess(0.0); + } + + + // Grab the first pass render state. + // NOTE: For more complicated samples iterate over the passes and build each one of them as desired. + RTShader::RenderState* renderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, curMaterialName, 0); + + // Remove all sub render states. + renderState->reset(); #ifdef RTSHADER_SYSTEM_BUILD_CORE_SHADERS - if (mCurLightingModel == SSLM_PerVertexLighting) - { - RTShader::SubRenderState* perPerVertexLightModel = mShaderGenerator->createSubRenderState(RTShader::FFPLighting::Type); + if (mCurLightingModel == SSLM_PerVertexLighting) + { + RTShader::SubRenderState* perPerVertexLightModel = mShaderGenerator->createSubRenderState(RTShader::FFPLighting::Type); - renderState->addTemplateSubRenderState(perPerVertexLightModel); - } + renderState->addTemplateSubRenderState(perPerVertexLightModel); + } #endif #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - else if (mCurLightingModel == SSLM_PerPixelLighting) - { - RTShader::SubRenderState* perPixelLightModel = mShaderGenerator->createSubRenderState(RTShader::PerPixelLighting::Type); - - renderState->addTemplateSubRenderState(perPixelLightModel); - } - else if (mCurLightingModel == SSLM_NormalMapLightingTangentSpace) - { - // Apply normal map only on main entity. - if (entity->getName() == MAIN_ENTITY_NAME) - { - RTShader::SubRenderState* subRenderState = mShaderGenerator->createSubRenderState(RTShader::NormalMapLighting::Type); - RTShader::NormalMapLighting* normalMapSubRS = static_cast(subRenderState); - - normalMapSubRS->setNormalMapSpace(RTShader::NormalMapLighting::NMS_TANGENT); - normalMapSubRS->setNormalMapTextureName("Panels_Normal_Tangent.png"); - - renderState->addTemplateSubRenderState(normalMapSubRS); - } - - // It is secondary entity -> use simple per pixel lighting. - else - { - RTShader::SubRenderState* perPixelLightModel = mShaderGenerator->createSubRenderState(RTShader::PerPixelLighting::Type); - renderState->addTemplateSubRenderState(perPixelLightModel); - } - } - else if (mCurLightingModel == SSLM_NormalMapLightingObjectSpace) - { - // Apply normal map only on main entity. - if (entity->getName() == MAIN_ENTITY_NAME) - { - RTShader::SubRenderState* subRenderState = mShaderGenerator->createSubRenderState(RTShader::NormalMapLighting::Type); - RTShader::NormalMapLighting* normalMapSubRS = static_cast(subRenderState); - - normalMapSubRS->setNormalMapSpace(RTShader::NormalMapLighting::NMS_OBJECT); - normalMapSubRS->setNormalMapTextureName("Panels_Normal_Obj.png"); - - renderState->addTemplateSubRenderState(normalMapSubRS); - } - - // It is secondary entity -> use simple per pixel lighting. - else - { - RTShader::SubRenderState* perPixelLightModel = mShaderGenerator->createSubRenderState(RTShader::PerPixelLighting::Type); - renderState->addTemplateSubRenderState(perPixelLightModel); - } - } + else if (mCurLightingModel == SSLM_PerPixelLighting) + { + RTShader::SubRenderState* perPixelLightModel = mShaderGenerator->createSubRenderState(RTShader::PerPixelLighting::Type); + + renderState->addTemplateSubRenderState(perPixelLightModel); + } + else if (mCurLightingModel == SSLM_NormalMapLightingTangentSpace) + { + // Apply normal map only on main entity. + if (entity->getName() == MAIN_ENTITY_NAME) + { + RTShader::SubRenderState* subRenderState = mShaderGenerator->createSubRenderState(RTShader::NormalMapLighting::Type); + RTShader::NormalMapLighting* normalMapSubRS = static_cast(subRenderState); + + normalMapSubRS->setNormalMapSpace(RTShader::NormalMapLighting::NMS_TANGENT); + normalMapSubRS->setNormalMapTextureName("Panels_Normal_Tangent.png"); + + renderState->addTemplateSubRenderState(normalMapSubRS); + } + + // It is secondary entity -> use simple per pixel lighting. + else + { + RTShader::SubRenderState* perPixelLightModel = mShaderGenerator->createSubRenderState(RTShader::PerPixelLighting::Type); + renderState->addTemplateSubRenderState(perPixelLightModel); + } + } + else if (mCurLightingModel == SSLM_NormalMapLightingObjectSpace) + { + // Apply normal map only on main entity. + if (entity->getName() == MAIN_ENTITY_NAME) + { + RTShader::SubRenderState* subRenderState = mShaderGenerator->createSubRenderState(RTShader::NormalMapLighting::Type); + RTShader::NormalMapLighting* normalMapSubRS = static_cast(subRenderState); + + normalMapSubRS->setNormalMapSpace(RTShader::NormalMapLighting::NMS_OBJECT); + normalMapSubRS->setNormalMapTextureName("Panels_Normal_Obj.png"); + + renderState->addTemplateSubRenderState(normalMapSubRS); + } + + // It is secondary entity -> use simple per pixel lighting. + else + { + RTShader::SubRenderState* perPixelLightModel = mShaderGenerator->createSubRenderState(RTShader::PerPixelLighting::Type); + renderState->addTemplateSubRenderState(perPixelLightModel); + } + } #endif - if (mReflectionMapEnable) - { - RTShader::SubRenderState* subRenderState = mShaderGenerator->createSubRenderState(ShaderExReflectionMap::Type); - ShaderExReflectionMap* reflectionMapSubRS = static_cast(subRenderState); - - reflectionMapSubRS->setReflectionMapType(TEX_TYPE_CUBE_MAP); - reflectionMapSubRS->setReflectionPower(mReflectionPowerSlider->getValue()); - - // Setup the textures needed by the reflection effect. - reflectionMapSubRS->setMaskMapTextureName("Panels_refmask.png"); - reflectionMapSubRS->setReflectionMapTextureName("cubescene.jpg"); - - renderState->addTemplateSubRenderState(subRenderState); - mReflectionMapSubRS = subRenderState; - } - else - { - mReflectionMapSubRS = NULL; - } - - // Invalidate this material in order to re-generate its shaders. - mShaderGenerator->invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, curMaterialName); - } - } + if (mReflectionMapEnable) + { + RTShader::SubRenderState* subRenderState = mShaderGenerator->createSubRenderState(ShaderExReflectionMap::Type); + ShaderExReflectionMap* reflectionMapSubRS = static_cast(subRenderState); + + reflectionMapSubRS->setReflectionMapType(TEX_TYPE_CUBE_MAP); + reflectionMapSubRS->setReflectionPower(mReflectionPowerSlider->getValue()); + + // Setup the textures needed by the reflection effect. + reflectionMapSubRS->setMaskMapTextureName("Panels_refmask.png"); + reflectionMapSubRS->setReflectionMapTextureName("cubescene.jpg"); + + renderState->addTemplateSubRenderState(subRenderState); + mReflectionMapSubRS = subRenderState; + } + else + { + mReflectionMapSubRS = NULL; + } + + // Invalidate this material in order to re-generate its shaders. + mShaderGenerator->invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, curMaterialName); + } + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::createDirectionalLight() { - Light* light; - Vector3 dir; + Light* light; + Vector3 dir; - light = mSceneMgr->createLight(DIRECTIONAL_LIGHT_NAME); + light = mSceneMgr->createLight(DIRECTIONAL_LIGHT_NAME); light->setType(Light::LT_DIRECTIONAL); - light->setCastShadows(true); + light->setCastShadows(true); dir.x = 0.5; - dir.y = -1.0; - dir.z = 0.3; + dir.y = -1.0; + dir.z = 0.3; dir.normalise(); light->setDirection(dir); light->setDiffuseColour(0.65, 0.15, 0.15); light->setSpecularColour(0.5, 0.5, 0.5); - // create pivot node - mDirectionalLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - - // Create billboard set. - mBbsFlare = mSceneMgr->createBillboardSet(); - mBbsFlare->setMaterialName("Examples/Flare3"); - mBbsFlare->createBillboard(-dir * 500.0)->setColour(light->getDiffuseColour()); - mBbsFlare->setCastShadows(false); - - mDirectionalLightNode->attachObject(mBbsFlare); - mDirectionalLightNode->attachObject(light); + // create pivot node + mDirectionalLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + + // Create billboard set. + mBbsFlare = mSceneMgr->createBillboardSet(); + mBbsFlare->setMaterialName("Examples/Flare3"); + mBbsFlare->createBillboard(-dir * 500.0)->setColour(light->getDiffuseColour()); + mBbsFlare->setCastShadows(false); + + mDirectionalLightNode->attachObject(mBbsFlare); + mDirectionalLightNode->attachObject(light); } //----------------------------------------------------------------------- void Sample_ShaderSystem::createPointLight() { - Light* light; - Vector3 dir; - - light = mSceneMgr->createLight(POINT_LIGHT_NAME); - light->setType(Light::LT_POINT); - light->setCastShadows(false); - dir.x = 0.5; - dir.y = 0.0; - dir.z = 0.0f; - dir.normalise(); - light->setDirection(dir); - light->setDiffuseColour(0.15, 0.65, 0.15); - light->setSpecularColour(0.5, 0.5, 0.5); - light->setAttenuation(200.0, 1.0, 0.0005, 0.0); - - // create pivot node - mPointLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - - BillboardSet* bbs; - - // Create billboard set. - bbs = mSceneMgr->createBillboardSet(); - bbs->setMaterialName("Examples/Flare3"); - bbs->createBillboard(200, 100, 0)->setColour(light->getDiffuseColour()); - bbs->setCastShadows(false); - - mPointLightNode->attachObject(bbs); - mPointLightNode->createChildSceneNode(Vector3(200, 100, 0))->attachObject(light); + Light* light; + Vector3 dir; + + light = mSceneMgr->createLight(POINT_LIGHT_NAME); + light->setType(Light::LT_POINT); + light->setCastShadows(false); + dir.x = 0.5; + dir.y = 0.0; + dir.z = 0.0f; + dir.normalise(); + light->setDirection(dir); + light->setDiffuseColour(0.15, 0.65, 0.15); + light->setSpecularColour(0.5, 0.5, 0.5); + light->setAttenuation(200.0, 1.0, 0.0005, 0.0); + + // create pivot node + mPointLightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + + BillboardSet* bbs; + + // Create billboard set. + bbs = mSceneMgr->createBillboardSet(); + bbs->setMaterialName("Examples/Flare3"); + bbs->createBillboard(200, 100, 0)->setColour(light->getDiffuseColour()); + bbs->setCastShadows(false); + + mPointLightNode->attachObject(bbs); + mPointLightNode->createChildSceneNode(Vector3(200, 100, 0))->attachObject(light); } //----------------------------------------------------------------------- void Sample_ShaderSystem::createSpotLight() { - Light* light; - Vector3 dir; - - light = mSceneMgr->createLight(SPOT_LIGHT_NAME); - light->setType(Light::LT_SPOTLIGHT); - light->setCastShadows(false); - dir.x = 0.0; - dir.y = 0.0; - dir.z = -1.0f; - dir.normalise(); - light->setSpotlightRange(Degree(20.0), Degree(25.0), 0.95); - light->setDirection(dir); - light->setDiffuseColour(0.15, 0.15, 0.65); - light->setSpecularColour(0.5, 0.5, 0.5); - light->setAttenuation(1000.0, 1.0, 0.0005, 0.0); + Light* light; + Vector3 dir; + + light = mSceneMgr->createLight(SPOT_LIGHT_NAME); + light->setType(Light::LT_SPOTLIGHT); + light->setCastShadows(false); + dir.x = 0.0; + dir.y = 0.0; + dir.z = -1.0f; + dir.normalise(); + light->setSpotlightRange(Degree(20.0), Degree(25.0), 0.95); + light->setDirection(dir); + light->setDiffuseColour(0.15, 0.15, 0.65); + light->setSpecularColour(0.5, 0.5, 0.5); + light->setAttenuation(1000.0, 1.0, 0.0005, 0.0); } void Sample_ShaderSystem::addModelToScene(const String & modelName) @@ -913,15 +913,15 @@ void Sample_ShaderSystem::addModelToScene(const String & modelName) for(int i = 0 ; i < 8 ; i++) { float scaleFactor = 30; - Entity* entity; - SceneNode* childNode; + Entity* entity; + SceneNode* childNode; entity = mSceneMgr->createEntity(modelName); - mLotsOfModelsEntities.push_back(entity); - childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mLotsOfModelsNodes.push_back(childNode); - childNode->setPosition(mNumberOfModelsAdded * scaleFactor, 15, i * scaleFactor); - childNode->attachObject(entity); - MeshPtr modelMesh = MeshManager::getSingleton().getByName(modelName); + mLotsOfModelsEntities.push_back(entity); + childNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mLotsOfModelsNodes.push_back(childNode); + childNode->setPosition(mNumberOfModelsAdded * scaleFactor, 15, i * scaleFactor); + childNode->attachObject(entity); + MeshPtr modelMesh = MeshManager::getSingleton().getByName(modelName); Vector3 modelSize = modelMesh->getBounds().getSize(); childNode->scale(1 / modelSize.x * scaleFactor, 1 / modelSize.y * scaleFactor, @@ -932,8 +932,8 @@ void Sample_ShaderSystem::addModelToScene(const String & modelName) void Sample_ShaderSystem::updateAddLotsOfModels(bool addThem) { - if (mAddedLotsOfModels != addThem) - { + if (mAddedLotsOfModels != addThem) + { mAddedLotsOfModels = addThem; if(mNumberOfModelsAdded == 0) @@ -958,565 +958,565 @@ void Sample_ShaderSystem::updateAddLotsOfModels(bool addThem) //----------------------------------------------------------------------- void Sample_ShaderSystem::updateInstancedViewports(bool enabled) { - if (mInstancedViewportsEnable != enabled) - { - mInstancedViewportsEnable = enabled; - - if (mInstancedViewportsEnable) - { - mCamera->setCullingFrustum(&mInfiniteFrustum); - - // having problems with bb... - mDirectionalLightNode->detachObject(mBbsFlare); - } - else - { - mCamera->setCullingFrustum(NULL); - mDirectionalLightNode->attachObject(mBbsFlare); - } - - - - if(mInstancedViewportsEnable) - { - createInstancedViewports(); - } - else - { - destroyInstancedViewports(); - } - - } + if (mInstancedViewportsEnable != enabled) + { + mInstancedViewportsEnable = enabled; + + if (mInstancedViewportsEnable) + { + mCamera->setCullingFrustum(&mInfiniteFrustum); + + // having problems with bb... + mDirectionalLightNode->detachObject(mBbsFlare); + } + else + { + mCamera->setCullingFrustum(NULL); + mDirectionalLightNode->attachObject(mBbsFlare); + } + + + + if(mInstancedViewportsEnable) + { + createInstancedViewports(); + } + else + { + destroyInstancedViewports(); + } + + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::updateLightState(const String& lightName, bool visible) { - if (mSceneMgr->hasLight(lightName)) - { - // Case it is the point light, - // toggle its visibility and billboard set visibility. - if (lightName == POINT_LIGHT_NAME) - { - if (visible) - { - if (mPointLightNode->isInSceneGraph() == false) - { - mSceneMgr->getRootSceneNode()->addChild(mPointLightNode); - } - } - else - { - if (mPointLightNode->isInSceneGraph() == true) - { - mSceneMgr->getRootSceneNode()->removeChild(mPointLightNode); - } - } - mSceneMgr->getLight(lightName)->setVisible(visible); - } - - // Case it is the directional light, - // toggle its visibility and billboard set visibility. - else if (lightName == DIRECTIONAL_LIGHT_NAME) - { - SceneNode::ObjectIterator it = mDirectionalLightNode->getAttachedObjectIterator(); - - while (it.hasMoreElements()) - { - MovableObject* o = it.getNext(); - o->setVisible(visible); - } - } - - // Spot light has no scene node representation. - else - { - mSceneMgr->getLight(lightName)->setVisible(visible); - } - - RenderState* schemRenderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - - int lightCount[3] = {0}; - - // Update point light count. - if (mSceneMgr->getLight(POINT_LIGHT_NAME)->isVisible()) - { - lightCount[0] = 1; - } - - // Update directional light count. - if (mSceneMgr->getLight(DIRECTIONAL_LIGHT_NAME)->isVisible()) - { - lightCount[1] = 1; - } - - // Update spot light count. - if (mSceneMgr->getLight(SPOT_LIGHT_NAME)->isVisible()) - { - lightCount[2] = 1; - } - - // Update the scheme light count. - schemRenderState->setLightCount(lightCount); - - - // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. - mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - } + if (mSceneMgr->hasLight(lightName)) + { + // Case it is the point light, + // toggle its visibility and billboard set visibility. + if (lightName == POINT_LIGHT_NAME) + { + if (visible) + { + if (mPointLightNode->isInSceneGraph() == false) + { + mSceneMgr->getRootSceneNode()->addChild(mPointLightNode); + } + } + else + { + if (mPointLightNode->isInSceneGraph() == true) + { + mSceneMgr->getRootSceneNode()->removeChild(mPointLightNode); + } + } + mSceneMgr->getLight(lightName)->setVisible(visible); + } + + // Case it is the directional light, + // toggle its visibility and billboard set visibility. + else if (lightName == DIRECTIONAL_LIGHT_NAME) + { + SceneNode::ObjectIterator it = mDirectionalLightNode->getAttachedObjectIterator(); + + while (it.hasMoreElements()) + { + MovableObject* o = it.getNext(); + o->setVisible(visible); + } + } + + // Spot light has no scene node representation. + else + { + mSceneMgr->getLight(lightName)->setVisible(visible); + } + + RenderState* schemRenderState = mShaderGenerator->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + + int lightCount[3] = {0}; + + // Update point light count. + if (mSceneMgr->getLight(POINT_LIGHT_NAME)->isVisible()) + { + lightCount[0] = 1; + } + + // Update directional light count. + if (mSceneMgr->getLight(DIRECTIONAL_LIGHT_NAME)->isVisible()) + { + lightCount[1] = 1; + } + + // Update spot light count. + if (mSceneMgr->getLight(SPOT_LIGHT_NAME)->isVisible()) + { + lightCount[2] = 1; + } + + // Update the scheme light count. + schemRenderState->setLightCount(lightCount); + + + // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. + mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::applyShadowType(int menuIndex) { - // Grab the scheme render state. - Ogre::RTShader::RenderState* schemRenderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + // Grab the scheme render state. + Ogre::RTShader::RenderState* schemRenderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - // No shadow - if (menuIndex == 0) - { - mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); + // No shadow + if (menuIndex == 0) + { + mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - const Ogre::RTShader::SubRenderStateList& subRenderStateList = schemRenderState->getTemplateSubRenderStateList(); - Ogre::RTShader::SubRenderStateListConstIterator it = subRenderStateList.begin(); - Ogre::RTShader::SubRenderStateListConstIterator itEnd = subRenderStateList.end(); - - for (; it != itEnd; ++it) - { - Ogre::RTShader::SubRenderState* curSubRenderState = *it; - - // This is the pssm3 sub render state -> remove it. - if (curSubRenderState->getType() == Ogre::RTShader::IntegratedPSSM3::Type) - { - schemRenderState->removeTemplateSubRenderState(*it); - break; - } - } + const Ogre::RTShader::SubRenderStateList& subRenderStateList = schemRenderState->getTemplateSubRenderStateList(); + Ogre::RTShader::SubRenderStateListConstIterator it = subRenderStateList.begin(); + Ogre::RTShader::SubRenderStateListConstIterator itEnd = subRenderStateList.end(); + + for (; it != itEnd; ++it) + { + Ogre::RTShader::SubRenderState* curSubRenderState = *it; + + // This is the pssm3 sub render state -> remove it. + if (curSubRenderState->getType() == Ogre::RTShader::IntegratedPSSM3::Type) + { + schemRenderState->removeTemplateSubRenderState(*it); + break; + } + } #endif - mTrayMgr->moveWidgetToTray(mDirLightCheckBox, TL_TOPLEFT, 1); - mTrayMgr->moveWidgetToTray(mPointLightCheckBox, TL_TOPLEFT, 2); - mTrayMgr->moveWidgetToTray(mSpotLightCheckBox, TL_TOPLEFT, 3); - - mDirLightCheckBox->show(); - mPointLightCheckBox->show(); - mSpotLightCheckBox->show(); + mTrayMgr->moveWidgetToTray(mDirLightCheckBox, TL_TOPLEFT, 1); + mTrayMgr->moveWidgetToTray(mPointLightCheckBox, TL_TOPLEFT, 2); + mTrayMgr->moveWidgetToTray(mSpotLightCheckBox, TL_TOPLEFT, 3); + + mDirLightCheckBox->show(); + mPointLightCheckBox->show(); + mSpotLightCheckBox->show(); - } + } #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - // Integrated shadow PSSM with 3 splits. - else if (menuIndex == 1) - { - mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED); - - // 3 textures per directional light - mSceneMgr->setShadowTextureCountPerLightType(Ogre::Light::LT_DIRECTIONAL, 3); - mSceneMgr->setShadowTextureSettings(512, 3, PF_FLOAT32_R); - mSceneMgr->setShadowTextureSelfShadow(true); - - // Leave only directional light. - mDirLightCheckBox->setChecked(true); - mPointLightCheckBox->setChecked(false); - mSpotLightCheckBox->setChecked(false); - - mTrayMgr->removeWidgetFromTray(mDirLightCheckBox); - mTrayMgr->removeWidgetFromTray(mPointLightCheckBox); - mTrayMgr->removeWidgetFromTray(mSpotLightCheckBox); - mDirLightCheckBox->hide(); - mPointLightCheckBox->hide(); - mSpotLightCheckBox->hide(); - - - // Set up caster material - this is just a standard depth/shadow map caster - mSceneMgr->setShadowTextureCasterMaterial("PSSM/shadow_caster"); - - - // Disable fog on the caster pass. - MaterialPtr passCaterMaterial = MaterialManager::getSingleton().getByName("PSSM/shadow_caster"); - Pass* pssmCasterPass = passCaterMaterial->getTechnique(0)->getPass(0); - pssmCasterPass->setFog(true); - - // shadow camera setup - PSSMShadowCameraSetup* pssmSetup = new PSSMShadowCameraSetup(); - pssmSetup->calculateSplitPoints(3, 5, 3000); - pssmSetup->setSplitPadding(10); - pssmSetup->setOptimalAdjustFactor(0, 2); - pssmSetup->setOptimalAdjustFactor(1, 1); - pssmSetup->setOptimalAdjustFactor(2, 0.5); - - mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(pssmSetup)); - - - Ogre::RTShader::SubRenderState* subRenderState = mShaderGenerator->createSubRenderState(Ogre::RTShader::IntegratedPSSM3::Type); - Ogre::RTShader::IntegratedPSSM3* pssm3SubRenderState = static_cast(subRenderState); - const PSSMShadowCameraSetup::SplitPointList& srcSplitPoints = pssmSetup->getSplitPoints(); - Ogre::RTShader::IntegratedPSSM3::SplitPointList dstSplitPoints; - - for (unsigned int i=0; i < srcSplitPoints.size(); ++i) - { - dstSplitPoints.push_back(srcSplitPoints[i]); - } - - pssm3SubRenderState->setSplitPoints(dstSplitPoints); - schemRenderState->addTemplateSubRenderState(subRenderState); - } + // Integrated shadow PSSM with 3 splits. + else if (menuIndex == 1) + { + mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED); + + // 3 textures per directional light + mSceneMgr->setShadowTextureCountPerLightType(Ogre::Light::LT_DIRECTIONAL, 3); + mSceneMgr->setShadowTextureSettings(512, 3, PF_FLOAT32_R); + mSceneMgr->setShadowTextureSelfShadow(true); + + // Leave only directional light. + mDirLightCheckBox->setChecked(true); + mPointLightCheckBox->setChecked(false); + mSpotLightCheckBox->setChecked(false); + + mTrayMgr->removeWidgetFromTray(mDirLightCheckBox); + mTrayMgr->removeWidgetFromTray(mPointLightCheckBox); + mTrayMgr->removeWidgetFromTray(mSpotLightCheckBox); + mDirLightCheckBox->hide(); + mPointLightCheckBox->hide(); + mSpotLightCheckBox->hide(); + + + // Set up caster material - this is just a standard depth/shadow map caster + mSceneMgr->setShadowTextureCasterMaterial("PSSM/shadow_caster"); + + + // Disable fog on the caster pass. + MaterialPtr passCaterMaterial = MaterialManager::getSingleton().getByName("PSSM/shadow_caster"); + Pass* pssmCasterPass = passCaterMaterial->getTechnique(0)->getPass(0); + pssmCasterPass->setFog(true); + + // shadow camera setup + PSSMShadowCameraSetup* pssmSetup = new PSSMShadowCameraSetup(); + pssmSetup->calculateSplitPoints(3, 5, 3000); + pssmSetup->setSplitPadding(10); + pssmSetup->setOptimalAdjustFactor(0, 2); + pssmSetup->setOptimalAdjustFactor(1, 1); + pssmSetup->setOptimalAdjustFactor(2, 0.5); + + mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(pssmSetup)); + + + Ogre::RTShader::SubRenderState* subRenderState = mShaderGenerator->createSubRenderState(Ogre::RTShader::IntegratedPSSM3::Type); + Ogre::RTShader::IntegratedPSSM3* pssm3SubRenderState = static_cast(subRenderState); + const PSSMShadowCameraSetup::SplitPointList& srcSplitPoints = pssmSetup->getSplitPoints(); + Ogre::RTShader::IntegratedPSSM3::SplitPointList dstSplitPoints; + + for (unsigned int i=0; i < srcSplitPoints.size(); ++i) + { + dstSplitPoints.push_back(srcSplitPoints[i]); + } + + pssm3SubRenderState->setSplitPoints(dstSplitPoints); + schemRenderState->addTemplateSubRenderState(subRenderState); + } #endif - // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. - mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. + mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); } //----------------------------------------------------------------------- void Sample_ShaderSystem::exportRTShaderSystemMaterial(const String& fileName, const String& materialName) { - // Grab material pointer. - MaterialPtr materialPtr = MaterialManager::getSingleton().getByName(materialName); - - // Create shader based technique. - bool success = mShaderGenerator->createShaderBasedTechnique(materialName, - MaterialManager::DEFAULT_SCHEME_NAME, - RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - - // Case creation of shader based technique succeeded. - if (success) - { - // Force shader generation of the given material. - RTShader::ShaderGenerator::getSingleton().validateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, materialName); - - // Grab the RTSS material serializer listener. - MaterialSerializer::Listener* matRTSSListener = RTShader::ShaderGenerator::getSingleton().getMaterialSerializerListener(); - MaterialSerializer matSer; - - // Add the custom RTSS listener to the serializer. - // It will make sure that every custom parameter needed by the RTSS - // will be added to the exported material script. - matSer.addListener(matRTSSListener); - - // Simply export the material. - matSer.exportMaterial(materialPtr, fileName, false, false, "", materialPtr->getName() + "_RTSS_Export"); - } + // Grab material pointer. + MaterialPtr materialPtr = MaterialManager::getSingleton().getByName(materialName); + + // Create shader based technique. + bool success = mShaderGenerator->createShaderBasedTechnique(materialName, + MaterialManager::DEFAULT_SCHEME_NAME, + RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + + // Case creation of shader based technique succeeded. + if (success) + { + // Force shader generation of the given material. + RTShader::ShaderGenerator::getSingleton().validateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, materialName); + + // Grab the RTSS material serializer listener. + MaterialSerializer::Listener* matRTSSListener = RTShader::ShaderGenerator::getSingleton().getMaterialSerializerListener(); + MaterialSerializer matSer; + + // Add the custom RTSS listener to the serializer. + // It will make sure that every custom parameter needed by the RTSS + // will be added to the exported material script. + matSer.addListener(matRTSSListener); + + // Simply export the material. + matSer.exportMaterial(materialPtr, fileName, false, false, "", materialPtr->getName() + "_RTSS_Export"); + } } //----------------------------------------------------------------------- Ogre::StringVector Sample_ShaderSystem::getRequiredPlugins() { - StringVector names; + StringVector names; if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl")) names.push_back("Cg Program Manager"); - return names; + return names; } //----------------------------------------------------------------------- void Sample_ShaderSystem::testCapabilities( const RenderSystemCapabilities* caps ) { - if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM))) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment programs, " - "so you cannot run this sample. Sorry!", "Sample_ShaderSystem::testCapabilities"); - } - - // Check if D3D10 shader is supported - is so - then we are OK. - if (GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0")) - { - return; - } - - // Check if GLSL type shaders are supported - is so - then we are OK. - if (GpuProgramManager::getSingleton().isSyntaxSupported("glsles") || + if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM))) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment programs, " + "so you cannot run this sample. Sorry!", "Sample_ShaderSystem::testCapabilities"); + } + + // Check if D3D10 shader is supported - is so - then we are OK. + if (GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0")) + { + return; + } + + // Check if GLSL type shaders are supported - is so - then we are OK. + if (GpuProgramManager::getSingleton().isSyntaxSupported("glsles") || GpuProgramManager::getSingleton().isSyntaxSupported("glsl")) - { - return; - } - - if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0")) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support shader model 2, " - "so you cannot run this sample. Sorry!", "Sample_ShaderSystem::testCapabilities"); - } + { + return; + } + + if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0")) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support shader model 2, " + "so you cannot run this sample. Sorry!", "Sample_ShaderSystem::testCapabilities"); + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::loadResources() { - // Create and add the custom reflection map shader extension factory to the shader generator. - mReflectionMapFactory = OGRE_NEW ShaderExReflectionMapFactory; - mShaderGenerator->addSubRenderStateFactory(mReflectionMapFactory); + // Create and add the custom reflection map shader extension factory to the shader generator. + mReflectionMapFactory = OGRE_NEW ShaderExReflectionMapFactory; + mShaderGenerator->addSubRenderStateFactory(mReflectionMapFactory); - createPrivateResourceGroup(); + createPrivateResourceGroup(); } //----------------------------------------------------------------------- void Sample_ShaderSystem::createPrivateResourceGroup() { - // Create the resource group of the RT Shader System Sample. - ResourceGroupManager& rgm = ResourceGroupManager::getSingleton(); + // Create the resource group of the RT Shader System Sample. + ResourceGroupManager& rgm = ResourceGroupManager::getSingleton(); - mExportMaterialPath = "C:/"; + mExportMaterialPath = "C:/"; - rgm.createResourceGroup(SAMPLE_MATERIAL_GROUP, false); - rgm.addResourceLocation(mExportMaterialPath, "FileSystem", SAMPLE_MATERIAL_GROUP); - rgm.initialiseResourceGroup(SAMPLE_MATERIAL_GROUP); - rgm.loadResourceGroup(SAMPLE_MATERIAL_GROUP, true); + rgm.createResourceGroup(SAMPLE_MATERIAL_GROUP, false); + rgm.addResourceLocation(mExportMaterialPath, "FileSystem", SAMPLE_MATERIAL_GROUP); + rgm.initialiseResourceGroup(SAMPLE_MATERIAL_GROUP); + rgm.loadResourceGroup(SAMPLE_MATERIAL_GROUP, true); } //----------------------------------------------------------------------- void Sample_ShaderSystem::unloadResources() { - destroyPrivateResourceGroup(); + destroyPrivateResourceGroup(); - mShaderGenerator->removeAllShaderBasedTechniques("Panels"); - mShaderGenerator->removeAllShaderBasedTechniques("Panels_RTSS_Export"); + mShaderGenerator->removeAllShaderBasedTechniques("Panels"); + mShaderGenerator->removeAllShaderBasedTechniques("Panels_RTSS_Export"); - if (mReflectionMapFactory != NULL) - { - mShaderGenerator->removeSubRenderStateFactory(mReflectionMapFactory); - OGRE_DELETE mReflectionMapFactory; - mReflectionMapFactory = NULL; - } + if (mReflectionMapFactory != NULL) + { + mShaderGenerator->removeSubRenderStateFactory(mReflectionMapFactory); + OGRE_DELETE mReflectionMapFactory; + mReflectionMapFactory = NULL; + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::destroyPrivateResourceGroup() { - // Destroy the resource group of the RT Shader System - ResourceGroupManager& rgm = ResourceGroupManager::getSingleton(); + // Destroy the resource group of the RT Shader System + ResourceGroupManager& rgm = ResourceGroupManager::getSingleton(); - rgm.destroyResourceGroup(SAMPLE_MATERIAL_GROUP); + rgm.destroyResourceGroup(SAMPLE_MATERIAL_GROUP); } //----------------------------------------------------------------------- void Sample_ShaderSystem::pickTargetObject( const OIS::MouseEvent &evt ) { - int xPos = evt.state.X.abs; - int yPos = evt.state.Y.abs; - int width = evt.state.width; - int height = evt.state.height; - - Ray mouseRay = mCamera->getCameraToViewportRay(xPos / float(width), yPos/float(height)); - mRayQuery->setRay(mouseRay); - - RaySceneQueryResult &result = mRayQuery->execute(); - RaySceneQueryResult::iterator it = result.begin(); - RaySceneQueryResult::iterator itEnd = result.end(); - - for (; it != itEnd; ++it) - { - RaySceneQueryResultEntry& curEntry = *it; - - if (mTargetObj != NULL) - { - mTargetObj->getParentSceneNode()->showBoundingBox(false); - } - - mTargetObj = curEntry.movable; - mTargetObj ->getParentSceneNode()->showBoundingBox(true); - } + int xPos = evt.state.X.abs; + int yPos = evt.state.Y.abs; + int width = evt.state.width; + int height = evt.state.height; + + Ray mouseRay = mCamera->getCameraToViewportRay(xPos / float(width), yPos/float(height)); + mRayQuery->setRay(mouseRay); + + RaySceneQueryResult &result = mRayQuery->execute(); + RaySceneQueryResult::iterator it = result.begin(); + RaySceneQueryResult::iterator itEnd = result.end(); + + for (; it != itEnd; ++it) + { + RaySceneQueryResultEntry& curEntry = *it; + + if (mTargetObj != NULL) + { + mTargetObj->getParentSceneNode()->showBoundingBox(false); + } + + mTargetObj = curEntry.movable; + mTargetObj ->getParentSceneNode()->showBoundingBox(true); + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::updateTargetObjInfo() { - if (mTargetObj == NULL) - return; - - String targetObjMaterialName; - - if (mTargetObj->getMovableType() == "Entity") - { - Entity* targetEnt = static_cast(mTargetObj); - targetObjMaterialName = targetEnt->getSubEntity(0)->getMaterialName(); - } - - mTargetObjMatName->setCaption(targetObjMaterialName); - - if (mViewport->getMaterialScheme() == RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) - { - MaterialPtr matMainEnt = MaterialManager::getSingleton().getByName(targetObjMaterialName); - - if (matMainEnt.isNull() == false) - { - Technique* shaderGeneratedTech = NULL; - - for (unsigned int i=0; i < matMainEnt->getNumTechniques(); ++i) - { - Technique* curTech = matMainEnt->getTechnique(i); - - if (curTech->getSchemeName() == RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) - { - shaderGeneratedTech = curTech; - break; - } - } - - if (shaderGeneratedTech != NULL) - { - mTargetObjVS->setCaption("VS: " + shaderGeneratedTech->getPass(0)->getVertexProgramName()); - mTargetObjFS->setCaption("FS: " + shaderGeneratedTech->getPass(0)->getFragmentProgramName()); - } - - } - - - } - else - { - mTargetObjVS->setCaption("VS: N/A"); - mTargetObjFS->setCaption("FS: N/A"); - } + if (mTargetObj == NULL) + return; + + String targetObjMaterialName; + + if (mTargetObj->getMovableType() == "Entity") + { + Entity* targetEnt = static_cast(mTargetObj); + targetObjMaterialName = targetEnt->getSubEntity(0)->getMaterialName(); + } + + mTargetObjMatName->setCaption(targetObjMaterialName); + + if (mViewport->getMaterialScheme() == RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) + { + MaterialPtr matMainEnt = MaterialManager::getSingleton().getByName(targetObjMaterialName); + + if (matMainEnt.isNull() == false) + { + Technique* shaderGeneratedTech = NULL; + + for (unsigned int i=0; i < matMainEnt->getNumTechniques(); ++i) + { + Technique* curTech = matMainEnt->getTechnique(i); + + if (curTech->getSchemeName() == RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME) + { + shaderGeneratedTech = curTech; + break; + } + } + + if (shaderGeneratedTech != NULL) + { + mTargetObjVS->setCaption("VS: " + shaderGeneratedTech->getPass(0)->getVertexProgramName()); + mTargetObjFS->setCaption("FS: " + shaderGeneratedTech->getPass(0)->getFragmentProgramName()); + } + + } + + + } + else + { + mTargetObjVS->setCaption("VS: N/A"); + mTargetObjFS->setCaption("FS: N/A"); + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::changeTextureLayerBlendMode() { - LayeredBlending::BlendMode curBlendMode = mLayerBlendSubRS->getBlendMode(1); - LayeredBlending::BlendMode nextBlendMode; - - // Update the next blend layer mode. - if (curBlendMode == LayeredBlending::LB_BlendLuminosity) - { - nextBlendMode = LayeredBlending::LB_FFPBlend; - } - else - { - nextBlendMode = (LayeredBlending::BlendMode)(curBlendMode + 1); - } - - - mLayerBlendSubRS->setBlendMode(1, nextBlendMode); - mShaderGenerator->invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, "RTSS/LayeredBlending"); - - // Update the caption. - updateLayerBlendingCaption(nextBlendMode); + LayeredBlending::BlendMode curBlendMode = mLayerBlendSubRS->getBlendMode(1); + LayeredBlending::BlendMode nextBlendMode; + + // Update the next blend layer mode. + if (curBlendMode == LayeredBlending::LB_BlendLuminosity) + { + nextBlendMode = LayeredBlending::LB_FFPBlend; + } + else + { + nextBlendMode = (LayeredBlending::BlendMode)(curBlendMode + 1); + } + + + mLayerBlendSubRS->setBlendMode(1, nextBlendMode); + mShaderGenerator->invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, "RTSS/LayeredBlending"); + + // Update the caption. + updateLayerBlendingCaption(nextBlendMode); } //----------------------------------------------------------------------- void Sample_ShaderSystem::updateLayerBlendingCaption( LayeredBlending::BlendMode nextBlendMode ) { - switch (nextBlendMode) - { - case LayeredBlending::LB_FFPBlend: - mLayerBlendLabel->setCaption("FFP Blend"); - break; + switch (nextBlendMode) + { + case LayeredBlending::LB_FFPBlend: + mLayerBlendLabel->setCaption("FFP Blend"); + break; - case LayeredBlending::LB_BlendNormal: - mLayerBlendLabel->setCaption("Normal"); - break; + case LayeredBlending::LB_BlendNormal: + mLayerBlendLabel->setCaption("Normal"); + break; - case LayeredBlending::LB_BlendLighten: - mLayerBlendLabel->setCaption("Lighten"); - break; + case LayeredBlending::LB_BlendLighten: + mLayerBlendLabel->setCaption("Lighten"); + break; - case LayeredBlending::LB_BlendDarken: - mLayerBlendLabel->setCaption("Darken"); - break; - - case LayeredBlending::LB_BlendMultiply: - mLayerBlendLabel->setCaption("Multiply"); - break; - - case LayeredBlending::LB_BlendAverage: - mLayerBlendLabel->setCaption("Average"); - break; - - case LayeredBlending::LB_BlendAdd: - mLayerBlendLabel->setCaption("Add"); - break; - - case LayeredBlending::LB_BlendSubtract: - mLayerBlendLabel->setCaption("Subtract"); - break; - - case LayeredBlending::LB_BlendDifference: - mLayerBlendLabel->setCaption("Difference"); - break; - - case LayeredBlending::LB_BlendNegation: - mLayerBlendLabel->setCaption("Negation"); - break; - - case LayeredBlending::LB_BlendExclusion: - mLayerBlendLabel->setCaption("Exclusion"); - break; - - case LayeredBlending::LB_BlendScreen: - mLayerBlendLabel->setCaption("Screen"); - break; - - case LayeredBlending::LB_BlendOverlay: - mLayerBlendLabel->setCaption("Overlay"); - break; - - case LayeredBlending::LB_BlendSoftLight: - mLayerBlendLabel->setCaption("SoftLight"); - break; - - case LayeredBlending::LB_BlendHardLight: - mLayerBlendLabel->setCaption("HardLight"); - break; - - case LayeredBlending::LB_BlendColorDodge: - mLayerBlendLabel->setCaption("ColorDodge"); - break; - - case LayeredBlending::LB_BlendColorBurn: - mLayerBlendLabel->setCaption("ColorBurn"); - break; - - case LayeredBlending::LB_BlendLinearDodge: - mLayerBlendLabel->setCaption("LinearDodge"); - break; - - case LayeredBlending::LB_BlendLinearBurn: - mLayerBlendLabel->setCaption("LinearBurn"); - break; - - case LayeredBlending::LB_BlendLinearLight: - mLayerBlendLabel->setCaption("LinearLight"); - break; - - case LayeredBlending::LB_BlendVividLight: - mLayerBlendLabel->setCaption("VividLight"); - break; - - case LayeredBlending::LB_BlendPinLight: - mLayerBlendLabel->setCaption("PinLight"); - break; - - case LayeredBlending::LB_BlendHardMix: - mLayerBlendLabel->setCaption("HardMix"); - break; - - case LayeredBlending::LB_BlendReflect: - mLayerBlendLabel->setCaption("Reflect"); - break; - - case LayeredBlending::LB_BlendGlow: - mLayerBlendLabel->setCaption("Glow"); - break; - - case LayeredBlending::LB_BlendPhoenix: - mLayerBlendLabel->setCaption("Phoenix"); - break; + case LayeredBlending::LB_BlendDarken: + mLayerBlendLabel->setCaption("Darken"); + break; + + case LayeredBlending::LB_BlendMultiply: + mLayerBlendLabel->setCaption("Multiply"); + break; + + case LayeredBlending::LB_BlendAverage: + mLayerBlendLabel->setCaption("Average"); + break; + + case LayeredBlending::LB_BlendAdd: + mLayerBlendLabel->setCaption("Add"); + break; + + case LayeredBlending::LB_BlendSubtract: + mLayerBlendLabel->setCaption("Subtract"); + break; + + case LayeredBlending::LB_BlendDifference: + mLayerBlendLabel->setCaption("Difference"); + break; + + case LayeredBlending::LB_BlendNegation: + mLayerBlendLabel->setCaption("Negation"); + break; + + case LayeredBlending::LB_BlendExclusion: + mLayerBlendLabel->setCaption("Exclusion"); + break; + + case LayeredBlending::LB_BlendScreen: + mLayerBlendLabel->setCaption("Screen"); + break; + + case LayeredBlending::LB_BlendOverlay: + mLayerBlendLabel->setCaption("Overlay"); + break; + + case LayeredBlending::LB_BlendSoftLight: + mLayerBlendLabel->setCaption("SoftLight"); + break; + + case LayeredBlending::LB_BlendHardLight: + mLayerBlendLabel->setCaption("HardLight"); + break; + + case LayeredBlending::LB_BlendColorDodge: + mLayerBlendLabel->setCaption("ColorDodge"); + break; + + case LayeredBlending::LB_BlendColorBurn: + mLayerBlendLabel->setCaption("ColorBurn"); + break; + + case LayeredBlending::LB_BlendLinearDodge: + mLayerBlendLabel->setCaption("LinearDodge"); + break; + + case LayeredBlending::LB_BlendLinearBurn: + mLayerBlendLabel->setCaption("LinearBurn"); + break; + + case LayeredBlending::LB_BlendLinearLight: + mLayerBlendLabel->setCaption("LinearLight"); + break; + + case LayeredBlending::LB_BlendVividLight: + mLayerBlendLabel->setCaption("VividLight"); + break; + + case LayeredBlending::LB_BlendPinLight: + mLayerBlendLabel->setCaption("PinLight"); + break; + + case LayeredBlending::LB_BlendHardMix: + mLayerBlendLabel->setCaption("HardMix"); + break; + + case LayeredBlending::LB_BlendReflect: + mLayerBlendLabel->setCaption("Reflect"); + break; + + case LayeredBlending::LB_BlendGlow: + mLayerBlendLabel->setCaption("Glow"); + break; + + case LayeredBlending::LB_BlendPhoenix: + mLayerBlendLabel->setCaption("Phoenix"); + break; - case LayeredBlending::LB_BlendSaturation: - mLayerBlendLabel->setCaption("Saturation"); - break; + case LayeredBlending::LB_BlendSaturation: + mLayerBlendLabel->setCaption("Saturation"); + break; - case LayeredBlending::LB_BlendColor: - mLayerBlendLabel->setCaption("Color"); - break; + case LayeredBlending::LB_BlendColor: + mLayerBlendLabel->setCaption("Color"); + break; - case LayeredBlending::LB_BlendLuminosity: - mLayerBlendLabel->setCaption("Luminosity"); - break; - default: - break; - } + case LayeredBlending::LB_BlendLuminosity: + mLayerBlendLabel->setCaption("Luminosity"); + break; + default: + break; + } } #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) @@ -1524,283 +1524,283 @@ void Sample_ShaderSystem::updateLayerBlendingCaption( LayeredBlending::BlendMode //----------------------------------------------------------------------- bool Sample_ShaderSystem::mousePressed( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) { - if (mTrayMgr->injectMouseDown(evt, id)) - return true; - if (id == OIS::MB_Left) - mTrayMgr->hideCursor(); // hide the cursor if user left-clicks in the scene - if (id == OIS::MB_Right) - pickTargetObject(evt); - - return true; + if (mTrayMgr->injectMouseDown(evt, id)) + return true; + if (id == OIS::MB_Left) + mTrayMgr->hideCursor(); // hide the cursor if user left-clicks in the scene + if (id == OIS::MB_Right) + pickTargetObject(evt); + + return true; } //----------------------------------------------------------------------- bool Sample_ShaderSystem::mouseReleased( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) { - if (mTrayMgr->injectMouseUp(evt, id)) - return true; - if (id == OIS::MB_Left) - mTrayMgr->showCursor(); // unhide the cursor if user lets go of LMB + if (mTrayMgr->injectMouseUp(evt, id)) + return true; + if (id == OIS::MB_Left) + mTrayMgr->showCursor(); // unhide the cursor if user lets go of LMB - return true; + return true; } //----------------------------------------------------------------------- bool Sample_ShaderSystem::mouseMoved( const OIS::MouseEvent& evt ) { - // only rotate the camera if cursor is hidden - if (mTrayMgr->isCursorVisible()) - mTrayMgr->injectMouseMove(evt); - else - mCameraMan->injectMouseMove(evt); + // only rotate the camera if cursor is hidden + if (mTrayMgr->isCursorVisible()) + mTrayMgr->injectMouseMove(evt); + else + mCameraMan->injectMouseMove(evt); - return true; + return true; } #endif //----------------------------------------------------------------------- void Sample_ShaderSystem::destroyInstancedViewports() { - if (mInstancedViewportsSubRenderState) - { - Ogre::RTShader::RenderState* renderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - renderState->removeTemplateSubRenderState(mInstancedViewportsSubRenderState); - mInstancedViewportsSubRenderState = NULL; - } - - if (mRoot->getRenderSystem()->getGlobalInstanceVertexBufferVertexDeclaration() != NULL) - { - Ogre::HardwareBufferManager::getSingleton().destroyVertexDeclaration( - mRoot->getRenderSystem()->getGlobalInstanceVertexBufferVertexDeclaration()); - mRoot->getRenderSystem()->setGlobalInstanceVertexBufferVertexDeclaration(NULL); - } - mRoot->getRenderSystem()->setGlobalNumberOfInstances(1); - mRoot->getRenderSystem()->setGlobalInstanceVertexBuffer(Ogre::HardwareVertexBufferSharedPtr() ); - - mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - mShaderGenerator->validateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - - destroyInstancedViewportsFactory(); + if (mInstancedViewportsSubRenderState) + { + Ogre::RTShader::RenderState* renderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + renderState->removeTemplateSubRenderState(mInstancedViewportsSubRenderState); + mInstancedViewportsSubRenderState = NULL; + } + + if (mRoot->getRenderSystem()->getGlobalInstanceVertexBufferVertexDeclaration() != NULL) + { + Ogre::HardwareBufferManager::getSingleton().destroyVertexDeclaration( + mRoot->getRenderSystem()->getGlobalInstanceVertexBufferVertexDeclaration()); + mRoot->getRenderSystem()->setGlobalInstanceVertexBufferVertexDeclaration(NULL); + } + mRoot->getRenderSystem()->setGlobalNumberOfInstances(1); + mRoot->getRenderSystem()->setGlobalInstanceVertexBuffer(Ogre::HardwareVertexBufferSharedPtr() ); + + mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + mShaderGenerator->validateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + + destroyInstancedViewportsFactory(); } //----------------------------------------------------------------------- void Sample_ShaderSystem::destroyInstancedViewportsFactory() { - if (mInstancedViewportsFactory != NULL) - { - mInstancedViewportsFactory->destroyAllInstances(); - mShaderGenerator->removeSubRenderStateFactory(mInstancedViewportsFactory); - delete mInstancedViewportsFactory; - mInstancedViewportsFactory = NULL; - } + if (mInstancedViewportsFactory != NULL) + { + mInstancedViewportsFactory->destroyAllInstances(); + mShaderGenerator->removeSubRenderStateFactory(mInstancedViewportsFactory); + delete mInstancedViewportsFactory; + mInstancedViewportsFactory = NULL; + } } //----------------------------------------------------------------------- void Sample_ShaderSystem::createInstancedViewports() { - if (mInstancedViewportsFactory == NULL) - { - mInstancedViewportsFactory = OGRE_NEW ShaderExInstancedViewportsFactory; - mShaderGenerator->addSubRenderStateFactory(mInstancedViewportsFactory); - } - - Ogre::Vector2 monitorCount(2.0, 2.0); - mInstancedViewportsSubRenderState = mShaderGenerator->createSubRenderState(Ogre::RTShader::ShaderExInstancedViewports::Type); - Ogre::RTShader::ShaderExInstancedViewports* shaderExInstancedViewports - = static_cast(mInstancedViewportsSubRenderState); - shaderExInstancedViewports->setMonitorsCount(monitorCount); - Ogre::RTShader::RenderState* renderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - renderState->addTemplateSubRenderState(mInstancedViewportsSubRenderState); - - Ogre::VertexDeclaration* vertexDeclaration = Ogre::HardwareBufferManager::getSingleton().createVertexDeclaration(); - size_t offset = 0; - offset = vertexDeclaration->getVertexSize(0); - vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 3); - offset = vertexDeclaration->getVertexSize(0); - vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 4); - offset = vertexDeclaration->getVertexSize(0); - vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 5); - offset = vertexDeclaration->getVertexSize(0); - vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 6); - offset = vertexDeclaration->getVertexSize(0); - vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 7); - - Ogre::HardwareVertexBufferSharedPtr vbuf = - Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( - vertexDeclaration->getVertexSize(0), monitorCount.x * monitorCount.y, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); - vbuf->setInstanceDataStepRate(1); - vbuf->setIsInstanceData(true); - - float * buf = (float *)vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD); - for (float x = 0 ; x < monitorCount.x ; x++) - for (float y = 0 ; y < monitorCount.y ; y++) - { - *buf = x; buf++; - *buf = y; buf++; - *buf = 0; buf++; - *buf = 0; buf++; - - Ogre::Quaternion q; - Ogre::Radian angle = Ogre::Degree(90 / ( monitorCount.x * monitorCount.y) * (x + y * monitorCount.x) ); - q.FromAngleAxis(angle,Ogre::Vector3::UNIT_Y); - q.normalise(); - Ogre::Matrix3 rotMat; - q.ToRotationMatrix(rotMat); - - *buf = rotMat.GetColumn(0).x; buf++; - *buf = rotMat.GetColumn(0).y; buf++; - *buf = rotMat.GetColumn(0).z; buf++; - *buf = x * -20; buf++; - - *buf = rotMat.GetColumn(1).x; buf++; - *buf = rotMat.GetColumn(1).y; buf++; - *buf = rotMat.GetColumn(1).z; buf++; - *buf = 0; buf++; - - *buf = rotMat.GetColumn(2).x; buf++; - *buf = rotMat.GetColumn(2).y; buf++; - *buf = rotMat.GetColumn(2).z; buf++; - *buf = y * 20; buf++; - - *buf = 0; buf++; - *buf = 0; buf++; - *buf = 0; buf++; - *buf = 1; buf++; - } - vbuf->unlock(); - - mRoot->getRenderSystem()->setGlobalInstanceVertexBuffer(vbuf); - mRoot->getRenderSystem()->setGlobalInstanceVertexBufferVertexDeclaration(vertexDeclaration); - mRoot->getRenderSystem()->setGlobalNumberOfInstances(monitorCount.x * monitorCount.y); - - // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. - mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - mShaderGenerator->validateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + if (mInstancedViewportsFactory == NULL) + { + mInstancedViewportsFactory = OGRE_NEW ShaderExInstancedViewportsFactory; + mShaderGenerator->addSubRenderStateFactory(mInstancedViewportsFactory); + } + + Ogre::Vector2 monitorCount(2.0, 2.0); + mInstancedViewportsSubRenderState = mShaderGenerator->createSubRenderState(Ogre::RTShader::ShaderExInstancedViewports::Type); + Ogre::RTShader::ShaderExInstancedViewports* shaderExInstancedViewports + = static_cast(mInstancedViewportsSubRenderState); + shaderExInstancedViewports->setMonitorsCount(monitorCount); + Ogre::RTShader::RenderState* renderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + renderState->addTemplateSubRenderState(mInstancedViewportsSubRenderState); + + Ogre::VertexDeclaration* vertexDeclaration = Ogre::HardwareBufferManager::getSingleton().createVertexDeclaration(); + size_t offset = 0; + offset = vertexDeclaration->getVertexSize(0); + vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 3); + offset = vertexDeclaration->getVertexSize(0); + vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 4); + offset = vertexDeclaration->getVertexSize(0); + vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 5); + offset = vertexDeclaration->getVertexSize(0); + vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 6); + offset = vertexDeclaration->getVertexSize(0); + vertexDeclaration->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_TEXTURE_COORDINATES, 7); + + Ogre::HardwareVertexBufferSharedPtr vbuf = + Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( + vertexDeclaration->getVertexSize(0), monitorCount.x * monitorCount.y, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); + vbuf->setInstanceDataStepRate(1); + vbuf->setIsInstanceData(true); + + float * buf = (float *)vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD); + for (float x = 0 ; x < monitorCount.x ; x++) + for (float y = 0 ; y < monitorCount.y ; y++) + { + *buf = x; buf++; + *buf = y; buf++; + *buf = 0; buf++; + *buf = 0; buf++; + + Ogre::Quaternion q; + Ogre::Radian angle = Ogre::Degree(90 / ( monitorCount.x * monitorCount.y) * (x + y * monitorCount.x) ); + q.FromAngleAxis(angle,Ogre::Vector3::UNIT_Y); + q.normalise(); + Ogre::Matrix3 rotMat; + q.ToRotationMatrix(rotMat); + + *buf = rotMat.GetColumn(0).x; buf++; + *buf = rotMat.GetColumn(0).y; buf++; + *buf = rotMat.GetColumn(0).z; buf++; + *buf = x * -20; buf++; + + *buf = rotMat.GetColumn(1).x; buf++; + *buf = rotMat.GetColumn(1).y; buf++; + *buf = rotMat.GetColumn(1).z; buf++; + *buf = 0; buf++; + + *buf = rotMat.GetColumn(2).x; buf++; + *buf = rotMat.GetColumn(2).y; buf++; + *buf = rotMat.GetColumn(2).z; buf++; + *buf = y * 20; buf++; + + *buf = 0; buf++; + *buf = 0; buf++; + *buf = 0; buf++; + *buf = 1; buf++; + } + vbuf->unlock(); + + mRoot->getRenderSystem()->setGlobalInstanceVertexBuffer(vbuf); + mRoot->getRenderSystem()->setGlobalInstanceVertexBufferVertexDeclaration(vertexDeclaration); + mRoot->getRenderSystem()->setGlobalNumberOfInstances(monitorCount.x * monitorCount.y); + + // Invalidate the scheme in order to re-generate all shaders based technique related to this scheme. + mShaderGenerator->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + mShaderGenerator->validateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); } void Sample_ShaderSystem::createMaterialForTexture( const String & texName, bool isTextureAtlasTexture ) { - MaterialManager * matMgr = MaterialManager::getSingletonPtr(); - if ( matMgr->resourceExists(texName) == false ) - { - MaterialPtr newMat = matMgr->create(texName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - newMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); - TextureUnitState* pState = newMat->getTechnique(0)->getPass(0)->createTextureUnitState(texName); - if(isTextureAtlasTexture) - { - // to solve wrap edge bleed - pState->setTextureFiltering(TFO_TRILINEAR); - } - } + MaterialManager * matMgr = MaterialManager::getSingletonPtr(); + if ( matMgr->resourceExists(texName) == false ) + { + MaterialPtr newMat = matMgr->create(texName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + newMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); + TextureUnitState* pState = newMat->getTechnique(0)->getPass(0)->createTextureUnitState(texName); + if(isTextureAtlasTexture) + { + // to solve wrap edge bleed + pState->setTextureFiltering(TFO_TRILINEAR); + } + } } ManualObject* Sample_ShaderSystem::createTextureAtlasObject() { - TextureAtlasSamplerFactory * textureAtlasSamplerFactory = - static_cast(mShaderGenerator->getSubRenderStateFactory(TextureAtlasSampler::Type)); - TextureAtlasTablePtr textureAtlasTable(new TextureAtlasTable); - - DataStreamPtr taiFile = Ogre::ResourceGroupManager::getSingleton().openResource("TextureAtlasSampleWrap.tai"); - - textureAtlasSamplerFactory->addTexutreAtlasDefinition(taiFile, textureAtlasTable); + TextureAtlasSamplerFactory * textureAtlasSamplerFactory = + static_cast(mShaderGenerator->getSubRenderStateFactory(TextureAtlasSampler::Type)); + TextureAtlasTablePtr textureAtlasTable(new TextureAtlasTable); - //Generate the geometry that will seed the particle system - ManualObject* textureAtlasObject = mSceneMgr->createManualObject("TextureAtlasObject"); + DataStreamPtr taiFile = Ogre::ResourceGroupManager::getSingleton().openResource("TextureAtlasSampleWrap.tai"); - int sliceSize = 30.0; - int wrapSize = 5.0; + textureAtlasSamplerFactory->addTexutreAtlasDefinition(taiFile, textureAtlasTable); - String curMatName; + //Generate the geometry that will seed the particle system + ManualObject* textureAtlasObject = mSceneMgr->createManualObject("TextureAtlasObject"); - // create original texture geometry - for( size_t i = 0 ; i < textureAtlasTable->size() ; i++ ) - { - bool changeMat = (curMatName != (*textureAtlasTable)[i].atlasTextureName); + int sliceSize = 30.0; + int wrapSize = 5.0; - if (changeMat) - { - if (curMatName.empty() == false) // we don't want to end before we begin - { - textureAtlasObject->end(); - } + String curMatName; - curMatName = (*textureAtlasTable)[i].originalTextureName; - createMaterialForTexture(curMatName, false); - textureAtlasObject->begin(curMatName, RenderOperation::OT_TRIANGLE_LIST); - } + // create original texture geometry + for( size_t i = 0 ; i < textureAtlasTable->size() ; i++ ) + { + bool changeMat = (curMatName != (*textureAtlasTable)[i].atlasTextureName); - // triangle 0 - textureAtlasObject->position(i * sliceSize, 0, 0); //Position - textureAtlasObject->textureCoord(0,0); //UV + if (changeMat) + { + if (curMatName.empty() == false) // we don't want to end before we begin + { + textureAtlasObject->end(); + } + + curMatName = (*textureAtlasTable)[i].originalTextureName; + createMaterialForTexture(curMatName, false); + textureAtlasObject->begin(curMatName, RenderOperation::OT_TRIANGLE_LIST); + } - textureAtlasObject->position(i * sliceSize, 0, sliceSize); //Position - textureAtlasObject->textureCoord(0,wrapSize); //UV + // triangle 0 + textureAtlasObject->position(i * sliceSize, 0, 0); //Position + textureAtlasObject->textureCoord(0,0); //UV - textureAtlasObject->position((i + 1) * sliceSize, 0 , sliceSize); //Position - textureAtlasObject->textureCoord(wrapSize,wrapSize); //UV + textureAtlasObject->position(i * sliceSize, 0, sliceSize); //Position + textureAtlasObject->textureCoord(0,wrapSize); //UV - // triangle 1 - textureAtlasObject->position(i * sliceSize, 0, 0); //Position - textureAtlasObject->textureCoord(0,0); //UV + textureAtlasObject->position((i + 1) * sliceSize, 0 , sliceSize); //Position + textureAtlasObject->textureCoord(wrapSize,wrapSize); //UV - textureAtlasObject->position((i + 1) * sliceSize, 0, sliceSize); //Position - textureAtlasObject->textureCoord(wrapSize,wrapSize); //UV + // triangle 1 + textureAtlasObject->position(i * sliceSize, 0, 0); //Position + textureAtlasObject->textureCoord(0,0); //UV - textureAtlasObject->position((i + 1) * sliceSize, 0, 0); //Position - textureAtlasObject->textureCoord(wrapSize, 0); //UV + textureAtlasObject->position((i + 1) * sliceSize, 0, sliceSize); //Position + textureAtlasObject->textureCoord(wrapSize,wrapSize); //UV - } + textureAtlasObject->position((i + 1) * sliceSize, 0, 0); //Position + textureAtlasObject->textureCoord(wrapSize, 0); //UV - // create texture atlas geometry - for( size_t i = 0 ; i < (*textureAtlasTable).size() ; i++ ) - { - bool changeMat = (curMatName != (*textureAtlasTable)[i].atlasTextureName); + } - if (changeMat) - { - if (curMatName.empty() == false) // we don't want to end before we begin - { - textureAtlasObject->end(); - } + // create texture atlas geometry + for( size_t i = 0 ; i < (*textureAtlasTable).size() ; i++ ) + { + bool changeMat = (curMatName != (*textureAtlasTable)[i].atlasTextureName); - curMatName = (*textureAtlasTable)[i].atlasTextureName; - createMaterialForTexture(curMatName, true); - textureAtlasObject->begin(curMatName, RenderOperation::OT_TRIANGLE_LIST); - } + if (changeMat) + { + if (curMatName.empty() == false) // we don't want to end before we begin + { + textureAtlasObject->end(); + } + + curMatName = (*textureAtlasTable)[i].atlasTextureName; + createMaterialForTexture(curMatName, true); + textureAtlasObject->begin(curMatName, RenderOperation::OT_TRIANGLE_LIST); + } - // triangle 0 - textureAtlasObject->position(i * sliceSize, 0, sliceSize); //Position - textureAtlasObject->textureCoord(0,0); //UV - textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID + // triangle 0 + textureAtlasObject->position(i * sliceSize, 0, sliceSize); //Position + textureAtlasObject->textureCoord(0,0); //UV + textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID - textureAtlasObject->position(i * sliceSize, 0, sliceSize * 2); //Position - textureAtlasObject->textureCoord(0,wrapSize); //UV - textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID + textureAtlasObject->position(i * sliceSize, 0, sliceSize * 2); //Position + textureAtlasObject->textureCoord(0,wrapSize); //UV + textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID - textureAtlasObject->position((i + 1) * sliceSize, 0 , sliceSize * 2); //Position - textureAtlasObject->textureCoord(wrapSize,wrapSize); //UV - textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID + textureAtlasObject->position((i + 1) * sliceSize, 0 , sliceSize * 2); //Position + textureAtlasObject->textureCoord(wrapSize,wrapSize); //UV + textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID - // triangle 1 - textureAtlasObject->position(i * sliceSize, 0, sliceSize); //Position - textureAtlasObject->textureCoord(0,0); //UV - textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID + // triangle 1 + textureAtlasObject->position(i * sliceSize, 0, sliceSize); //Position + textureAtlasObject->textureCoord(0,0); //UV + textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID - textureAtlasObject->position((i + 1) * sliceSize, 0, sliceSize * 2); //Position - textureAtlasObject->textureCoord(wrapSize,wrapSize); //UV - textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID + textureAtlasObject->position((i + 1) * sliceSize, 0, sliceSize * 2); //Position + textureAtlasObject->textureCoord(wrapSize,wrapSize); //UV + textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID - textureAtlasObject->position((i + 1) * sliceSize, 0, sliceSize); //Position - textureAtlasObject->textureCoord(wrapSize, 0); //UV - textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID + textureAtlasObject->position((i + 1) * sliceSize, 0, sliceSize); //Position + textureAtlasObject->textureCoord(wrapSize, 0); //UV + textureAtlasObject->textureCoord((*textureAtlasTable)[i].indexInAtlas); //Texture ID - } + } - textureAtlasObject->end(); + textureAtlasObject->end(); - return textureAtlasObject; + return textureAtlasObject; } diff --git a/Samples/ShaderSystemMultiLight/include/RTShaderSRSSegmentedLights.h b/Samples/ShaderSystemMultiLight/include/RTShaderSRSSegmentedLights.h index 226b695f216..0a4fd8da01f 100644 --- a/Samples/ShaderSystemMultiLight/include/RTShaderSRSSegmentedLights.h +++ b/Samples/ShaderSystemMultiLight/include/RTShaderSRSSegmentedLights.h @@ -40,189 +40,189 @@ THE SOFTWARE. class RTShaderSRSSegmentedLights : public Ogre::RTShader::SubRenderState { - // Interface. + // Interface. public: - /** Class default constructor */ - RTShaderSRSSegmentedLights(); + /** Class default constructor */ + RTShaderSRSSegmentedLights(); - /** - @see SubRenderState::getType. - */ - virtual const Ogre::String& getType() const; + /** + @see SubRenderState::getType. + */ + virtual const Ogre::String& getType() const; - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams(Ogre::Renderable* rend, Ogre::Pass* pass, const Ogre::AutoParamDataSource* source, const Ogre::LightList* pLightList); + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams(Ogre::Renderable* rend, Ogre::Pass* pass, const Ogre::AutoParamDataSource* source, const Ogre::LightList* pLightList); - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const Ogre::RTShader::SubRenderState& rhs); + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const Ogre::RTShader::SubRenderState& rhs); - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const Ogre::RTShader::RenderState* renderState, Ogre::Pass* srcPass, Ogre::Pass* dstPass); + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const Ogre::RTShader::RenderState* renderState, Ogre::Pass* srcPass, Ogre::Pass* dstPass); - static Ogre::String Type; + static Ogre::String Type; - // Protected types: + // Protected types: protected: - // Per light parameters. - struct LightParams - { - Ogre::Light::LightTypes mType; // Light type. - Ogre::RTShader::UniformParameterPtr mPosition; // Light position. - Ogre::RTShader::UniformParameterPtr mDirection; // Light direction. - Ogre::RTShader::UniformParameterPtr mSpotParams; // Spot light parameters. - Ogre::RTShader::UniformParameterPtr mDiffuseColour; // Diffuse colour. - Ogre::RTShader::UniformParameterPtr mSpecularColour; // Specular colour. + // Per light parameters. + struct LightParams + { + Ogre::Light::LightTypes mType; // Light type. + Ogre::RTShader::UniformParameterPtr mPosition; // Light position. + Ogre::RTShader::UniformParameterPtr mDirection; // Light direction. + Ogre::RTShader::UniformParameterPtr mSpotParams; // Spot light parameters. + Ogre::RTShader::UniformParameterPtr mDiffuseColour; // Diffuse colour. + Ogre::RTShader::UniformParameterPtr mSpecularColour; // Specular colour. - }; + }; - typedef Ogre::vector::type LightParamsList; - typedef LightParamsList::iterator LightParamsIterator; - typedef LightParamsList::const_iterator LightParamsConstIterator; + typedef Ogre::vector::type LightParamsList; + typedef LightParamsList::iterator LightParamsIterator; + typedef LightParamsList::const_iterator LightParamsConstIterator; - // Protected methods + // Protected methods protected: - /** - Set the track per vertex colour type. Ambient, Diffuse, Specular and Emissive lighting components source - can be the vertex colour component. To establish such a link one should provide the matching flags to this - sub render state. - */ - void setTrackVertexColourType(Ogre::TrackVertexColourType type) { mTrackVertexColourType = type; } - - /** - Return the current track per vertex type. - */ - Ogre::TrackVertexColourType getTrackVertexColourType() const { return mTrackVertexColourType; } - - - /** - Set the light count per light type that this sub render state will generate. - @see ShaderGenerator::setLightCount. - */ - void setLightCount(const int lightCount[3]); - - /** - Get the light count per light type that this sub render state will generate. - @see ShaderGenerator::getLightCount. - */ - void getLightCount(int lightCount[3]) const; - /** - Set the specular component state. If set to true this sub render state will compute a specular - lighting component in addition to the diffuse component. - @param enable Pass true to enable specular component computation. - */ - void setSpecularEnable(bool enable) { mSpecularEnable = enable; } - - /** - Get the specular component state. - */ - bool getSpecularEnable() const { return mSpecularEnable; } - - - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(Ogre::RTShader::ProgramSet* programSet); - - /** Resolve global lighting parameters */ - bool resolveGlobalParameters(Ogre::RTShader::ProgramSet* programSet); - - /** Resolve per light parameters */ - bool resolvePerLightParameters(Ogre::RTShader::ProgramSet* programSet); - - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(Ogre::RTShader::ProgramSet* programSet); - - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(Ogre::RTShader::ProgramSet* programSet); - - - /** - Internal method that adds related vertex shader functions invocations. - */ - bool addVSInvocation(Ogre::RTShader::Function* vsMain, const int groupOrder, int& internalCounter); - - - /** - Internal method that adds global illumination component functions invocations. - */ - bool addPSGlobalIlluminationInvocationBegin(Ogre::RTShader::Function* psMain, const int groupOrder, int& internalCounter); - bool addPSGlobalIlluminationInvocationEnd(Ogre::RTShader::Function* psMain, const int groupOrder, int& internalCounter); - - /** - Internal method that adds per light illumination component functions invocations. - */ - bool addPSIlluminationInvocation(LightParams* curLightParams, Ogre::RTShader::Function* psMain, const int groupOrder, int& internalCounter); - - /** - Internal method that adds light illumination component calculated from the segmented texture. - */ - bool addPSSegmentedTextureLightInvocation(Ogre::RTShader::Function* psMain, const int groupOrder, int& internalCounter); - - /** - Internal method that adds the final colour assignments. - */ - bool addPSFinalAssignmentInvocation(Ogre::RTShader::Function* psMain, const int groupOrder, int& internalCounter); - - - // Attributes. -protected: - Ogre::TrackVertexColourType mTrackVertexColourType; // Track per vertex colour type. - bool mSpecularEnable; // Specular component enabled/disabled. - LightParamsList mLightParamsList; // Light list. - Ogre::RTShader::UniformParameterPtr mWorldMatrix; // World view matrix parameter. - Ogre::RTShader::UniformParameterPtr mWorldITMatrix; // World view matrix inverse transpose parameter. - Ogre::RTShader::ParameterPtr mVSInPosition; // Vertex shader input position parameter. - Ogre::RTShader::ParameterPtr mVSOutWorldPos; // Vertex shader output view position (position in camera space) parameter. - Ogre::RTShader::ParameterPtr mPSInWorldPos; // Pixel shader input view position (position in camera space) parameter. - Ogre::RTShader::ParameterPtr mVSInNormal; // Vertex shader input normal. - Ogre::RTShader::ParameterPtr mVSOutNormal; // Vertex shader output normal. - Ogre::RTShader::ParameterPtr mPSInNormal; // Pixel shader input normal. - Ogre::RTShader::ParameterPtr mPSLocalNormal; - Ogre::RTShader::ParameterPtr mPSTempDiffuseColour; // Pixel shader temporary diffuse calculation parameter. - Ogre::RTShader::ParameterPtr mPSTempSpecularColour; // Pixel shader temporary specular calculation parameter. - Ogre::RTShader::ParameterPtr mPSDiffuse; // Pixel shader input/local diffuse parameter. - Ogre::RTShader::ParameterPtr mPSSpecular; // Pixel shader input/local specular parameter. - Ogre::RTShader::ParameterPtr mPSOutDiffuse; // Pixel shader output diffuse parameter. - Ogre::RTShader::ParameterPtr mPSOutSpecular; // Pixel shader output specular parameter. - Ogre::RTShader::UniformParameterPtr mDerivedSceneColour; // Derived scene colour parameter. - Ogre::RTShader::UniformParameterPtr mLightAmbientColour; // Ambient light colour parameter. - Ogre::RTShader::UniformParameterPtr mDerivedAmbientLightColour; // Derived ambient light colour parameter. - Ogre::RTShader::UniformParameterPtr mSurfaceAmbientColour; // Surface ambient colour parameter. - Ogre::RTShader::UniformParameterPtr mSurfaceDiffuseColour; // Surface diffuse colour parameter. - Ogre::RTShader::UniformParameterPtr mSurfaceSpecularColour; // Surface specular colour parameter. - Ogre::RTShader::UniformParameterPtr mSurfaceEmissiveColour; // Surface emissive colour parameter. - Ogre::RTShader::UniformParameterPtr mSurfaceShininess; // Surface shininess parameter. - - //Segmented texture - bool mUseSegmentedLightTexture; - bool mIsDebugMode; - unsigned short mLightSamplerIndex; - Ogre::RTShader::UniformParameterPtr mPSLightTextureIndexLimit; - Ogre::RTShader::UniformParameterPtr mPSLightTextureLightBounds; - Ogre::RTShader::UniformParameterPtr mPSSegmentedLightTexture; - //Ogre::RTShader::UniformParameterPtr mPSLightAreaBounds; - - static Ogre::Light msBlankLight; // Shared blank light. + /** + Set the track per vertex colour type. Ambient, Diffuse, Specular and Emissive lighting components source + can be the vertex colour component. To establish such a link one should provide the matching flags to this + sub render state. + */ + void setTrackVertexColourType(Ogre::TrackVertexColourType type) { mTrackVertexColourType = type; } + + /** + Return the current track per vertex type. + */ + Ogre::TrackVertexColourType getTrackVertexColourType() const { return mTrackVertexColourType; } + + + /** + Set the light count per light type that this sub render state will generate. + @see ShaderGenerator::setLightCount. + */ + void setLightCount(const int lightCount[3]); + + /** + Get the light count per light type that this sub render state will generate. + @see ShaderGenerator::getLightCount. + */ + void getLightCount(int lightCount[3]) const; + /** + Set the specular component state. If set to true this sub render state will compute a specular + lighting component in addition to the diffuse component. + @param enable Pass true to enable specular component computation. + */ + void setSpecularEnable(bool enable) { mSpecularEnable = enable; } + + /** + Get the specular component state. + */ + bool getSpecularEnable() const { return mSpecularEnable; } + + + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(Ogre::RTShader::ProgramSet* programSet); + + /** Resolve global lighting parameters */ + bool resolveGlobalParameters(Ogre::RTShader::ProgramSet* programSet); + + /** Resolve per light parameters */ + bool resolvePerLightParameters(Ogre::RTShader::ProgramSet* programSet); + + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(Ogre::RTShader::ProgramSet* programSet); + + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(Ogre::RTShader::ProgramSet* programSet); + + + /** + Internal method that adds related vertex shader functions invocations. + */ + bool addVSInvocation(Ogre::RTShader::Function* vsMain, const int groupOrder, int& internalCounter); + + + /** + Internal method that adds global illumination component functions invocations. + */ + bool addPSGlobalIlluminationInvocationBegin(Ogre::RTShader::Function* psMain, const int groupOrder, int& internalCounter); + bool addPSGlobalIlluminationInvocationEnd(Ogre::RTShader::Function* psMain, const int groupOrder, int& internalCounter); + + /** + Internal method that adds per light illumination component functions invocations. + */ + bool addPSIlluminationInvocation(LightParams* curLightParams, Ogre::RTShader::Function* psMain, const int groupOrder, int& internalCounter); + + /** + Internal method that adds light illumination component calculated from the segmented texture. + */ + bool addPSSegmentedTextureLightInvocation(Ogre::RTShader::Function* psMain, const int groupOrder, int& internalCounter); + + /** + Internal method that adds the final colour assignments. + */ + bool addPSFinalAssignmentInvocation(Ogre::RTShader::Function* psMain, const int groupOrder, int& internalCounter); + + + // Attributes. +protected: + Ogre::TrackVertexColourType mTrackVertexColourType; // Track per vertex colour type. + bool mSpecularEnable; // Specular component enabled/disabled. + LightParamsList mLightParamsList; // Light list. + Ogre::RTShader::UniformParameterPtr mWorldMatrix; // World view matrix parameter. + Ogre::RTShader::UniformParameterPtr mWorldITMatrix; // World view matrix inverse transpose parameter. + Ogre::RTShader::ParameterPtr mVSInPosition; // Vertex shader input position parameter. + Ogre::RTShader::ParameterPtr mVSOutWorldPos; // Vertex shader output view position (position in camera space) parameter. + Ogre::RTShader::ParameterPtr mPSInWorldPos; // Pixel shader input view position (position in camera space) parameter. + Ogre::RTShader::ParameterPtr mVSInNormal; // Vertex shader input normal. + Ogre::RTShader::ParameterPtr mVSOutNormal; // Vertex shader output normal. + Ogre::RTShader::ParameterPtr mPSInNormal; // Pixel shader input normal. + Ogre::RTShader::ParameterPtr mPSLocalNormal; + Ogre::RTShader::ParameterPtr mPSTempDiffuseColour; // Pixel shader temporary diffuse calculation parameter. + Ogre::RTShader::ParameterPtr mPSTempSpecularColour; // Pixel shader temporary specular calculation parameter. + Ogre::RTShader::ParameterPtr mPSDiffuse; // Pixel shader input/local diffuse parameter. + Ogre::RTShader::ParameterPtr mPSSpecular; // Pixel shader input/local specular parameter. + Ogre::RTShader::ParameterPtr mPSOutDiffuse; // Pixel shader output diffuse parameter. + Ogre::RTShader::ParameterPtr mPSOutSpecular; // Pixel shader output specular parameter. + Ogre::RTShader::UniformParameterPtr mDerivedSceneColour; // Derived scene colour parameter. + Ogre::RTShader::UniformParameterPtr mLightAmbientColour; // Ambient light colour parameter. + Ogre::RTShader::UniformParameterPtr mDerivedAmbientLightColour; // Derived ambient light colour parameter. + Ogre::RTShader::UniformParameterPtr mSurfaceAmbientColour; // Surface ambient colour parameter. + Ogre::RTShader::UniformParameterPtr mSurfaceDiffuseColour; // Surface diffuse colour parameter. + Ogre::RTShader::UniformParameterPtr mSurfaceSpecularColour; // Surface specular colour parameter. + Ogre::RTShader::UniformParameterPtr mSurfaceEmissiveColour; // Surface emissive colour parameter. + Ogre::RTShader::UniformParameterPtr mSurfaceShininess; // Surface shininess parameter. + + //Segmented texture + bool mUseSegmentedLightTexture; + bool mIsDebugMode; + unsigned short mLightSamplerIndex; + Ogre::RTShader::UniformParameterPtr mPSLightTextureIndexLimit; + Ogre::RTShader::UniformParameterPtr mPSLightTextureLightBounds; + Ogre::RTShader::UniformParameterPtr mPSSegmentedLightTexture; + //Ogre::RTShader::UniformParameterPtr mPSLightAreaBounds; + + static Ogre::Light msBlankLight; // Shared blank light. }; @@ -235,28 +235,28 @@ class RTShaderSRSSegmentedLightsFactory : public Ogre::RTShader::SubRenderStateF { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const Ogre::String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const Ogre::String& getType() const; - /** - @see SubRenderStateFactory::createInstance. - */ - virtual Ogre::RTShader::SubRenderState* createInstance(Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, Ogre::Pass* pass, Ogre::RTShader::SGScriptTranslator* translator); + /** + @see SubRenderStateFactory::createInstance. + */ + virtual Ogre::RTShader::SubRenderState* createInstance(Ogre::ScriptCompiler* compiler, Ogre::PropertyAbstractNode* prop, Ogre::Pass* pass, Ogre::RTShader::SGScriptTranslator* translator); - /** - @see SubRenderStateFactory::writeInstance. - */ - virtual void writeInstance(Ogre::MaterialSerializer* ser, Ogre::RTShader::SubRenderState* subRenderState, Ogre::Pass* srcPass, Ogre::Pass* dstPass); + /** + @see SubRenderStateFactory::writeInstance. + */ + virtual void writeInstance(Ogre::MaterialSerializer* ser, Ogre::RTShader::SubRenderState* subRenderState, Ogre::Pass* srcPass, Ogre::Pass* dstPass); protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual Ogre::RTShader::SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual Ogre::RTShader::SubRenderState* createInstanceImpl(); }; diff --git a/Samples/ShaderSystemMultiLight/include/SegmentedDynamicLightManager.h b/Samples/ShaderSystemMultiLight/include/SegmentedDynamicLightManager.h index 87d69bd5a56..6e36ba7be99 100644 --- a/Samples/ShaderSystemMultiLight/include/SegmentedDynamicLightManager.h +++ b/Samples/ShaderSystemMultiLight/include/SegmentedDynamicLightManager.h @@ -45,119 +45,119 @@ THE SOFTWARE. using namespace Ogre; class SegmentedDynamicLightManager : public Singleton, - public SceneManager::Listener + public SceneManager::Listener { - + public: - SegmentedDynamicLightManager(); - ~SegmentedDynamicLightManager(); - - bool setDebugMode(bool i_IsDebugMode); - //Set the system to active mode - void setSceneManager(SceneManager* i_Manager); - //Tells if the system is active - bool isActive() const { return mManager != NULL; } - //Get the name of the texture used to store the light information - const String& getSDLTextureName(); - - //Get the range of lights in the supplied texture data that need to be calculated for a given renderable - bool getLightListRange(const Renderable* i_Rend, Vector4& o_GridBounds, unsigned int& o_IndexMin, unsigned int& o_IndexMax); - - //Get the width of the texture containing the light information - unsigned int getTextureWidth() const { return mTextureWidth; } - //Get the height of the texture containing the light information - unsigned int getTextureHeight() const { return mTextureHeight; } - //Get the amount of cells the texture is divided into on either axis - unsigned int getGridDivision() const { return SDL_SEGMENT_DIVISIONS; } - //Get whether to display the lights in debug mode - bool isDebugMode() const { return mIsDebugMode; } - - //Implementation of SceneManager::Listener - virtual void postFindVisibleObjects(SceneManager* source, - SceneManager::IlluminationRenderStage irs, Viewport* v); - + SegmentedDynamicLightManager(); + ~SegmentedDynamicLightManager(); + + bool setDebugMode(bool i_IsDebugMode); + //Set the system to active mode + void setSceneManager(SceneManager* i_Manager); + //Tells if the system is active + bool isActive() const { return mManager != NULL; } + //Get the name of the texture used to store the light information + const String& getSDLTextureName(); + + //Get the range of lights in the supplied texture data that need to be calculated for a given renderable + bool getLightListRange(const Renderable* i_Rend, Vector4& o_GridBounds, unsigned int& o_IndexMin, unsigned int& o_IndexMax); + + //Get the width of the texture containing the light information + unsigned int getTextureWidth() const { return mTextureWidth; } + //Get the height of the texture containing the light information + unsigned int getTextureHeight() const { return mTextureHeight; } + //Get the amount of cells the texture is divided into on either axis + unsigned int getGridDivision() const { return SDL_SEGMENT_DIVISIONS; } + //Get whether to display the lights in debug mode + bool isDebugMode() const { return mIsDebugMode; } + + //Implementation of SceneManager::Listener + virtual void postFindVisibleObjects(SceneManager* source, + SceneManager::IlluminationRenderStage irs, Viewport* v); + private: - - class LightData - { - public: - //Constructor for LightData - LightData(); - //Sets the values of the boundaries of the light - void setBounds(const AxisAlignedBox& i_Bounds); - //Add an index to the possible range of indexes - void addIndexToRange(unsigned int i_LightIndex); - - unsigned int getIndexMin() const { return mIndexMin; } - unsigned int getIndexMax() const { return mIndexMax; } - - Real getMinX() const { return mMinX; } - Real getMaxX() const { return mMaxX; } - Real getMinZ() const { return mMinZ; } - Real getMaxZ() const { return mMaxZ; } - - private: - unsigned int mIndexMin; - unsigned int mIndexMax; - - Real mMinX; - Real mMaxX; - Real mMinZ; - Real mMaxZ; - }; - - typedef map::type MapLightData; + + class LightData + { + public: + //Constructor for LightData + LightData(); + //Sets the values of the boundaries of the light + void setBounds(const AxisAlignedBox& i_Bounds); + //Add an index to the possible range of indexes + void addIndexToRange(unsigned int i_LightIndex); + + unsigned int getIndexMin() const { return mIndexMin; } + unsigned int getIndexMax() const { return mIndexMax; } + + Real getMinX() const { return mMinX; } + Real getMaxX() const { return mMaxX; } + Real getMinZ() const { return mMinZ; } + Real getMaxZ() const { return mMaxZ; } + + private: + unsigned int mIndexMin; + unsigned int mIndexMax; + + Real mMinX; + Real mMaxX; + Real mMinZ; + Real mMaxZ; + }; + + typedef map::type MapLightData; private: - //Update the systems internal light lists - void updateLightList(const Camera* i_pCamera, const LightList& i_LightList); - //Initialize the texture to be used to store the light information - bool initTexture(); - //Arrange the lights in the different lists - void arrangeLightsInSegmentedLists(const Camera* i_pCamera, const LightList& i_LightList); - //Repopulate the m_ActiveLights list which keeps track of all lights being rendered in the frame - void regenerateActiveLightList(const LightList& i_LightList); - //Calculate the bounds of a single light - void calculateLightBounds(const Light* i_Light, LightData &o_LightData); - //Calculate the area which bounds area in which the lights exist - void recalculateGridSize(); - //Distribute the lights in the active light list (mActiveLights) in the grid parameter (mSegmentedLightGrid) - void distributeLightsInGrid(); - //Get the index in the grid of a given world position - unsigned int calcGridColumn(Real i_Position, Real i_BoundStart, Real i_BoundEnd); - //Returns a grid index for a given x and y index positions - unsigned int calcGridIndex(unsigned int i_X, unsigned int i_Y); - - //Load the lights information from the internal lists to the texture - void updateTextureFromSegmentedLists(const Camera* i_pCamera); + //Update the systems internal light lists + void updateLightList(const Camera* i_pCamera, const LightList& i_LightList); + //Initialize the texture to be used to store the light information + bool initTexture(); + //Arrange the lights in the different lists + void arrangeLightsInSegmentedLists(const Camera* i_pCamera, const LightList& i_LightList); + //Repopulate the m_ActiveLights list which keeps track of all lights being rendered in the frame + void regenerateActiveLightList(const LightList& i_LightList); + //Calculate the bounds of a single light + void calculateLightBounds(const Light* i_Light, LightData &o_LightData); + //Calculate the area which bounds area in which the lights exist + void recalculateGridSize(); + //Distribute the lights in the active light list (mActiveLights) in the grid parameter (mSegmentedLightGrid) + void distributeLightsInGrid(); + //Get the index in the grid of a given world position + unsigned int calcGridColumn(Real i_Position, Real i_BoundStart, Real i_BoundEnd); + //Returns a grid index for a given x and y index positions + unsigned int calcGridIndex(unsigned int i_X, unsigned int i_Y); + + //Load the lights information from the internal lists to the texture + void updateTextureFromSegmentedLists(const Camera* i_pCamera); private: - //Tells whether to run the lights in debug mode - bool mIsDebugMode; - //Pointer to a scene manager on which the lights will work - SceneManager* mManager; - - //List of active lights in the frame - MapLightData mActiveLights; - - //A Grid structures to contain the lights as they are represented in the light texture - typedef vector::type VecLights; - typedef vector::type SegmentedVecLight; - SegmentedVecLight mSegmentedLightGrid; - - //A pointer to a texture which containing information from which a shader renders the lights - TexturePtr mLightTexture; - //The height of the width information texture - unsigned int mTextureWidth; - //The height of the light information texture - unsigned int mTextureHeight; - - - //Light grid bounds - Real mGridMinX; - Real mGridMinZ; - Real mGridMaxX; - Real mGridMaxZ; + //Tells whether to run the lights in debug mode + bool mIsDebugMode; + //Pointer to a scene manager on which the lights will work + SceneManager* mManager; + + //List of active lights in the frame + MapLightData mActiveLights; + + //A Grid structures to contain the lights as they are represented in the light texture + typedef vector::type VecLights; + typedef vector::type SegmentedVecLight; + SegmentedVecLight mSegmentedLightGrid; + + //A pointer to a texture which containing information from which a shader renders the lights + TexturePtr mLightTexture; + //The height of the width information texture + unsigned int mTextureWidth; + //The height of the light information texture + unsigned int mTextureHeight; + + + //Light grid bounds + Real mGridMinX; + Real mGridMinZ; + Real mGridMaxX; + Real mGridMaxZ; }; #endif diff --git a/Samples/ShaderSystemMultiLight/include/ShaderSystemMultiLight.h b/Samples/ShaderSystemMultiLight/include/ShaderSystemMultiLight.h index deddd8b3781..bcdc1099110 100644 --- a/Samples/ShaderSystemMultiLight/include/ShaderSystemMultiLight.h +++ b/Samples/ShaderSystemMultiLight/include/ShaderSystemMultiLight.h @@ -14,18 +14,18 @@ requires it's own line in the shader. Every time an object receives a different recompiled. Amount of is also limited by the amount of const registers a shader supports. The following example shows a different approach to rendering lights in RTSS. A few points on this system - - Only one directional light is supported. - - Point lights and spot lights are handled through the same code. - - Light attenuation is only controlled by range. all other parameters are ignored (to produce more efficient shader programs) - - point light specular effect is not calculated (to produce more faster shader programs). If any one wants to add it feel free. - - Large amount of lights can be supported. Limited currently by the size of the texture used to send the light information to the - shader (currently set to a 9x9 grid. each grid cell can contain 32 lights). - - No need to recompile the shader when the number of lights on an object changes - - Sample requires shader model 3 or higher to run in order - - The world is divided into a grid of 9x9 cells (can be easily increased). Each cell receives it's own list of lights appropriate - only for it. This can be increased depending on your situation. - - The information of the lights in the grid is transferred onto a texture. Which is sent to the shader. - - The list of lights is iterated over in the shader through a dynamic loop. + - Only one directional light is supported. + - Point lights and spot lights are handled through the same code. + - Light attenuation is only controlled by range. all other parameters are ignored (to produce more efficient shader programs) + - point light specular effect is not calculated (to produce more faster shader programs). If any one wants to add it feel free. + - Large amount of lights can be supported. Limited currently by the size of the texture used to send the light information to the + shader (currently set to a 9x9 grid. each grid cell can contain 32 lights). + - No need to recompile the shader when the number of lights on an object changes + - Sample requires shader model 3 or higher to run in order + - The world is divided into a grid of 9x9 cells (can be easily increased). Each cell receives it's own list of lights appropriate + only for it. This can be increased depending on your situation. + - The information of the lights in the grid is transferred onto a texture. Which is sent to the shader. + - The list of lights is iterated over in the shader through a dynamic loop. Note: @@ -50,68 +50,68 @@ class _OgreSampleClassExport Sample_ShaderSystemMultiLight : public SdkSample { public: - Sample_ShaderSystemMultiLight() : + Sample_ShaderSystemMultiLight() : mTwirlLights(false), - mSRSSegLightFactory(NULL), + mSRSSegLightFactory(NULL), mPathNameGen("RTPath") - { - mInfo["Title"] = "ShaderSystem - Multi Light"; - mInfo["Description"] = "Shows a possible way to support a large varying amount of spot lights in the RTSS using a relatively simple system." - "Note in debug mode green and red lines show the light grid. Blue shows the amount of lights processed per grid position."; - mInfo["Thumbnail"] = "thumb_shadersystemmultilight.png"; - mInfo["Category"] = "Lighting"; - - } - - ~Sample_ShaderSystemMultiLight() - { - - } - - virtual void _shutdown() - { - delete SegmentedDynamicLightManager::getSingletonPtr(); - - RTShader::RenderState* pMainRenderState = - RTShader::ShaderGenerator::getSingleton().createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first; - pMainRenderState->reset(); - - if (mSRSSegLightFactory) - { - RTShader::ShaderGenerator::getSingleton().removeAllShaderBasedTechniques(); - RTShader::ShaderGenerator::getSingleton().removeSubRenderStateFactory(mSRSSegLightFactory); - delete mSRSSegLightFactory; - mSRSSegLightFactory = NULL; - } + { + mInfo["Title"] = "ShaderSystem - Multi Light"; + mInfo["Description"] = "Shows a possible way to support a large varying amount of spot lights in the RTSS using a relatively simple system." + "Note in debug mode green and red lines show the light grid. Blue shows the amount of lights processed per grid position."; + mInfo["Thumbnail"] = "thumb_shadersystemmultilight.png"; + mInfo["Category"] = "Lighting"; + + } + + ~Sample_ShaderSystemMultiLight() + { + + } + + virtual void _shutdown() + { + delete SegmentedDynamicLightManager::getSingletonPtr(); + + RTShader::RenderState* pMainRenderState = + RTShader::ShaderGenerator::getSingleton().createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first; + pMainRenderState->reset(); + + if (mSRSSegLightFactory) + { + RTShader::ShaderGenerator::getSingleton().removeAllShaderBasedTechniques(); + RTShader::ShaderGenerator::getSingleton().removeSubRenderStateFactory(mSRSSegLightFactory); + delete mSRSSegLightFactory; + mSRSSegLightFactory = NULL; + } while (mLights.size()) { removeSpotLight(); } - SdkSample::_shutdown(); - } + SdkSample::_shutdown(); + } bool frameRenderingQueued(const FrameEvent& evt) { - // Move the lights along their paths - for(size_t i = 0 ; i < mLights.size() ; ++i) - { - mLights[i].animState->addTime(evt.timeSinceLastFrame); - if (mTwirlLights) - { - mLights[i].light->setDirection( - Quaternion(Degree(ControllerManager::getSingleton().getElapsedTime() * 150 + 360 * i / (float)mLights.size()), Vector3::UNIT_Y) * - Vector3(0,-1,-1).normalisedCopy()); - } - else - { - mLights[i].light->setDirection(Vector3::NEGATIVE_UNIT_Y); - } - } - - - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + // Move the lights along their paths + for(size_t i = 0 ; i < mLights.size() ; ++i) + { + mLights[i].animState->addTime(evt.timeSinceLastFrame); + if (mTwirlLights) + { + mLights[i].light->setDirection( + Quaternion(Degree(ControllerManager::getSingleton().getElapsedTime() * 150 + 360 * i / (float)mLights.size()), Vector3::UNIT_Y) * + Vector3(0,-1,-1).normalisedCopy()); + } + else + { + mLights[i].light->setDirection(Vector3::NEGATIVE_UNIT_Y); + } + } + + + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! } protected: @@ -119,279 +119,279 @@ class _OgreSampleClassExport Sample_ShaderSystemMultiLight : public SdkSample void testCapabilities( const RenderSystemCapabilities* caps ) { if (!Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("ps_3_0") && - !Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("ps_4_0") && - !Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("ps_4_1") && - !Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("ps_5_0") && - !Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("glsl")) - { + !Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("ps_4_0") && + !Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("ps_4_1") && + !Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("ps_5_0") && + !Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("glsl")) + { OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "This sample uses dynamic loops in Cg or GLSL type shader language, your graphic card must support Shader Profile 3 or above." " You cannot run this sample. Sorry!", "Sample_ShaderSystemMultiLight::testCapabilities"); } } - void setupContent() - { - mTrayMgr->createThickSlider(TL_BOTTOM, NUM_OF_LIGHTS_SLIDER, "Num of lights", 240, 80, 0, 64, 65)->setValue(cInitialLightCount, false); - mTrayMgr->createCheckBox(TL_BOTTOM, TWIRL_LIGHTS_CHECKBOX, "Twirl Lights", 240)->setChecked(false, false); - mTrayMgr->createCheckBox(TL_BOTTOM, DEBUG_MODE_CHECKBOX, "Show Grid", 240)->setChecked(false, false); + void setupContent() + { + mTrayMgr->createThickSlider(TL_BOTTOM, NUM_OF_LIGHTS_SLIDER, "Num of lights", 240, 80, 0, 64, 65)->setValue(cInitialLightCount, false); + mTrayMgr->createCheckBox(TL_BOTTOM, TWIRL_LIGHTS_CHECKBOX, "Twirl Lights", 240)->setChecked(false, false); + mTrayMgr->createCheckBox(TL_BOTTOM, DEBUG_MODE_CHECKBOX, "Show Grid", 240)->setChecked(false, false); - // Set our camera to orbit around the origin at a suitable distance - mCamera->setPosition(0, 100, 600); + // Set our camera to orbit around the origin at a suitable distance + mCamera->setPosition(0, 100, 600); - mTrayMgr->showCursor(); + mTrayMgr->showCursor(); - // create a floor mesh resource - MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Plane(Vector3::UNIT_Y, -30), 1000, 1000, 10, 10, true, 1, 8, 8, Vector3::UNIT_Z); + // create a floor mesh resource + MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Plane(Vector3::UNIT_Y, -30), 1000, 1000, 10, 10, true, 1, 8, 8, Vector3::UNIT_Z); - // create a floor entity, give it a material, and place it at the origin + // create a floor entity, give it a material, and place it at the origin Entity* floor = mSceneMgr->createEntity("Floor", "floor"); floor->setMaterialName("Examples/BumpyMetal"); mSceneMgr->getRootSceneNode()->attachObject(floor); - // Create an ogre head and place it at the origin - Entity* head = mSceneMgr->createEntity("Head", "ogrehead.mesh"); - head->setRenderQueueGroup(cPriorityMain); - mSceneMgr->getRootSceneNode()->attachObject(head); + // Create an ogre head and place it at the origin + Entity* head = mSceneMgr->createEntity("Head", "ogrehead.mesh"); + head->setRenderQueueGroup(cPriorityMain); + mSceneMgr->getRootSceneNode()->attachObject(head); - setupShaderGenerator(); - - setupLights(); - } - - void setupShaderGenerator() - { - new SegmentedDynamicLightManager; + setupShaderGenerator(); + + setupLights(); + } + + void setupShaderGenerator() + { + new SegmentedDynamicLightManager; - SegmentedDynamicLightManager::getSingleton().setSceneManager(mSceneMgr); + SegmentedDynamicLightManager::getSingleton().setSceneManager(mSceneMgr); - RTShader::ShaderGenerator* mGen = RTShader::ShaderGenerator::getSingletonPtr(); + RTShader::ShaderGenerator* mGen = RTShader::ShaderGenerator::getSingletonPtr(); - RTShader::RenderState* pMainRenderState = + RTShader::RenderState* pMainRenderState = mGen->createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first; - pMainRenderState->reset(); - - // If we are using segmented lighting, no auto light update required. (prevent constant invalidation) - pMainRenderState->setLightCountAutoUpdate(false); - - mSRSSegLightFactory = new RTShaderSRSSegmentedLightsFactory; - mGen->addSubRenderStateFactory(mSRSSegLightFactory); - pMainRenderState->addTemplateSubRenderState( - mGen->createSubRenderState(RTShaderSRSSegmentedLights::Type)); - - - mGen->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - - // Make this viewport work with shader generator scheme. - mViewport->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - } - - - void setupLights() - { - mSceneMgr->setAmbientLight(ColourValue(0.1, 0.1, 0.1)); - // set the single directional light - Light* light = mSceneMgr->createLight(); - light->setType(Light::LT_DIRECTIONAL); - light->setDirection(Vector3(-1,-1,0).normalisedCopy()); - light->setDiffuseColour(ColourValue(0.1, 0.1, 0.1)); - light->setCastShadows(false); - - for(unsigned int i = 0 ; i < cInitialLightCount ; ++i) - { - addSpotLight(); - } - } - - void addSpotLight() - { - LightState state; - - // Create a light node - state.node = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(50, 30, 0)); - - String animName = mPathNameGen.generate(); - // Create a 14 second animation with spline interpolation - - const int animPoints = 5; - const int animTimeBetweenPoints = 4; - state.anim = mSceneMgr->createAnimation(animName, animPoints * animTimeBetweenPoints); - state.anim->setInterpolationMode(Animation::IM_SPLINE); - - state.track = state.anim->createNodeTrack(1, state.node); // Create a node track for our animation - - // Enter keyframes for our track to define a path for the light to follow - Vector3 firstFramePos; - for(int i = 0 ; i <= animPoints ; ++i) - { - Vector3 framePos(rand01() * 900 - 500, 10 + rand01() * 100, rand01() * 900 - 500); - if (i == 0) - { - firstFramePos = framePos; - } - if (i == animPoints) - { - framePos = firstFramePos; - } - state.track->createNodeKeyFrame(i * animTimeBetweenPoints)->setTranslate(framePos); - } - - - ColourValue lightColor(rand01(), rand01(), rand01()); - float complement = 1 - std::max(std::max(lightColor.r, lightColor.g), lightColor.b); - lightColor.r += complement; - lightColor.g += complement; - lightColor.b += complement; - - // Create an animation state from the animation and enable it - state.animState = mSceneMgr->createAnimationState(animName); - state.animState->setEnabled(true); - - // Attach a light with the same colour to the light node - state.light = mSceneMgr->createLight(); - state.light->setCastShadows(false); - state.light->setType(mLights.size() % 10 ? Light::LT_SPOTLIGHT : Light::LT_POINT); - state.light->setDirection(Vector3::NEGATIVE_UNIT_Y); - state.light->setAttenuation(200,0,0,0); - state.light->setDiffuseColour(lightColor); - state.node->attachObject(state.light); - - // Attach a flare with the same colour to the light node - state.bbs = mSceneMgr->createBillboardSet(1); - Billboard* bb = state.bbs->createBillboard(Vector3::ZERO, lightColor); - bb->setColour(lightColor); - state.bbs->setMaterialName("Examples/Flare"); - state.bbs->setRenderQueueGroup(cPriorityLights); - state.node->attachObject(state.bbs); - - mLights.push_back(state); - } - - float rand01() - { - return (abs(rand()) % 1000) / 1000.0f; - } - - void setDebugModeState(bool state) - { - bool needInvalidate = SegmentedDynamicLightManager::getSingleton().setDebugMode(state); - if (needInvalidate) - { - RTShader::ShaderGenerator::getSingleton().invalidateScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - } - } - - //-------------------------------------------------------------------------- - void sliderMoved(Slider* slider) - { - if (slider->getName() == NUM_OF_LIGHTS_SLIDER) - { - size_t numOfLights = (size_t)slider->getValue(); - - while (mLights.size() < numOfLights) - { - addSpotLight(); - } - - while (numOfLights < mLights.size()) - { - removeSpotLight(); - } - } - } - - void removeSpotLight() - { - if (!mLights.empty()) - { - LightState& state = mLights[mLights.size() - 1]; - - // Delete the nodes - mSceneMgr->destroyBillboardSet(state.bbs); - mSceneMgr->destroyLight(state.light); - mSceneMgr->destroyAnimationState(state.anim->getName()); - mSceneMgr->destroyAnimation(state.anim->getName()); - mSceneMgr->destroySceneNode(state.node); - - - mLights.resize(mLights.size() - 1); - } - } - - - void checkBoxToggled(CheckBox* box) - { - const String& cbName = box->getName(); - - if (cbName == DEBUG_MODE_CHECKBOX) - { - setDebugModeState(box->isChecked()); - } - if (cbName == TWIRL_LIGHTS_CHECKBOX) - { - mTwirlLights = box->isChecked(); - } - } - - #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) - - //----------------------------------------------------------------------- - bool mousePressed( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) - { - if (mTrayMgr->injectMouseDown(evt, id)) - return true; - if (id == OIS::MB_Left) - mTrayMgr->hideCursor(); // hide the cursor if user left-clicks in the scene - - return true; - } - - //----------------------------------------------------------------------- - bool mouseReleased( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) - { - if (mTrayMgr->injectMouseUp(evt, id)) - return true; - if (id == OIS::MB_Left) - mTrayMgr->showCursor(); // unhide the cursor if user lets go of LMB - - return true; - } - - //----------------------------------------------------------------------- - bool mouseMoved( const OIS::MouseEvent& evt ) - { - // only rotate the camera if cursor is hidden - if (mTrayMgr->isCursorVisible()) - mTrayMgr->injectMouseMove(evt); - else - mCameraMan->injectMouseMove(evt); - - - return true; - } - #endif - - + pMainRenderState->reset(); + + // If we are using segmented lighting, no auto light update required. (prevent constant invalidation) + pMainRenderState->setLightCountAutoUpdate(false); + + mSRSSegLightFactory = new RTShaderSRSSegmentedLightsFactory; + mGen->addSubRenderStateFactory(mSRSSegLightFactory); + pMainRenderState->addTemplateSubRenderState( + mGen->createSubRenderState(RTShaderSRSSegmentedLights::Type)); + + + mGen->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + + // Make this viewport work with shader generator scheme. + mViewport->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + } + + + void setupLights() + { + mSceneMgr->setAmbientLight(ColourValue(0.1, 0.1, 0.1)); + // set the single directional light + Light* light = mSceneMgr->createLight(); + light->setType(Light::LT_DIRECTIONAL); + light->setDirection(Vector3(-1,-1,0).normalisedCopy()); + light->setDiffuseColour(ColourValue(0.1, 0.1, 0.1)); + light->setCastShadows(false); + + for(unsigned int i = 0 ; i < cInitialLightCount ; ++i) + { + addSpotLight(); + } + } + + void addSpotLight() + { + LightState state; + + // Create a light node + state.node = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(50, 30, 0)); + + String animName = mPathNameGen.generate(); + // Create a 14 second animation with spline interpolation + + const int animPoints = 5; + const int animTimeBetweenPoints = 4; + state.anim = mSceneMgr->createAnimation(animName, animPoints * animTimeBetweenPoints); + state.anim->setInterpolationMode(Animation::IM_SPLINE); + + state.track = state.anim->createNodeTrack(1, state.node); // Create a node track for our animation + + // Enter keyframes for our track to define a path for the light to follow + Vector3 firstFramePos; + for(int i = 0 ; i <= animPoints ; ++i) + { + Vector3 framePos(rand01() * 900 - 500, 10 + rand01() * 100, rand01() * 900 - 500); + if (i == 0) + { + firstFramePos = framePos; + } + if (i == animPoints) + { + framePos = firstFramePos; + } + state.track->createNodeKeyFrame(i * animTimeBetweenPoints)->setTranslate(framePos); + } + + + ColourValue lightColor(rand01(), rand01(), rand01()); + float complement = 1 - std::max(std::max(lightColor.r, lightColor.g), lightColor.b); + lightColor.r += complement; + lightColor.g += complement; + lightColor.b += complement; + + // Create an animation state from the animation and enable it + state.animState = mSceneMgr->createAnimationState(animName); + state.animState->setEnabled(true); + + // Attach a light with the same colour to the light node + state.light = mSceneMgr->createLight(); + state.light->setCastShadows(false); + state.light->setType(mLights.size() % 10 ? Light::LT_SPOTLIGHT : Light::LT_POINT); + state.light->setDirection(Vector3::NEGATIVE_UNIT_Y); + state.light->setAttenuation(200,0,0,0); + state.light->setDiffuseColour(lightColor); + state.node->attachObject(state.light); + + // Attach a flare with the same colour to the light node + state.bbs = mSceneMgr->createBillboardSet(1); + Billboard* bb = state.bbs->createBillboard(Vector3::ZERO, lightColor); + bb->setColour(lightColor); + state.bbs->setMaterialName("Examples/Flare"); + state.bbs->setRenderQueueGroup(cPriorityLights); + state.node->attachObject(state.bbs); + + mLights.push_back(state); + } + + float rand01() + { + return (abs(rand()) % 1000) / 1000.0f; + } + + void setDebugModeState(bool state) + { + bool needInvalidate = SegmentedDynamicLightManager::getSingleton().setDebugMode(state); + if (needInvalidate) + { + RTShader::ShaderGenerator::getSingleton().invalidateScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + } + } + + //-------------------------------------------------------------------------- + void sliderMoved(Slider* slider) + { + if (slider->getName() == NUM_OF_LIGHTS_SLIDER) + { + size_t numOfLights = (size_t)slider->getValue(); + + while (mLights.size() < numOfLights) + { + addSpotLight(); + } + + while (numOfLights < mLights.size()) + { + removeSpotLight(); + } + } + } + + void removeSpotLight() + { + if (!mLights.empty()) + { + LightState& state = mLights[mLights.size() - 1]; + + // Delete the nodes + mSceneMgr->destroyBillboardSet(state.bbs); + mSceneMgr->destroyLight(state.light); + mSceneMgr->destroyAnimationState(state.anim->getName()); + mSceneMgr->destroyAnimation(state.anim->getName()); + mSceneMgr->destroySceneNode(state.node); + + + mLights.resize(mLights.size() - 1); + } + } + + + void checkBoxToggled(CheckBox* box) + { + const String& cbName = box->getName(); + + if (cbName == DEBUG_MODE_CHECKBOX) + { + setDebugModeState(box->isChecked()); + } + if (cbName == TWIRL_LIGHTS_CHECKBOX) + { + mTwirlLights = box->isChecked(); + } + } + + #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) + + //----------------------------------------------------------------------- + bool mousePressed( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) + { + if (mTrayMgr->injectMouseDown(evt, id)) + return true; + if (id == OIS::MB_Left) + mTrayMgr->hideCursor(); // hide the cursor if user left-clicks in the scene + + return true; + } + + //----------------------------------------------------------------------- + bool mouseReleased( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) + { + if (mTrayMgr->injectMouseUp(evt, id)) + return true; + if (id == OIS::MB_Left) + mTrayMgr->showCursor(); // unhide the cursor if user lets go of LMB + + return true; + } + + //----------------------------------------------------------------------- + bool mouseMoved( const OIS::MouseEvent& evt ) + { + // only rotate the camera if cursor is hidden + if (mTrayMgr->isCursorVisible()) + mTrayMgr->injectMouseMove(evt); + else + mCameraMan->injectMouseMove(evt); + + + return true; + } + #endif + + private: - struct LightState - { - SceneNode* node; - Animation* anim; - NodeAnimationTrack* track; - AnimationState* animState; - Light* light; - BillboardSet* bbs; - }; + struct LightState + { + SceneNode* node; + Animation* anim; + NodeAnimationTrack* track; + AnimationState* animState; + Light* light; + BillboardSet* bbs; + }; - typedef Ogre::vector::type VecLights; - VecLights mLights; - bool mTwirlLights; + typedef Ogre::vector::type VecLights; + VecLights mLights; + bool mTwirlLights; - RTShaderSRSSegmentedLightsFactory* mSRSSegLightFactory; + RTShaderSRSSegmentedLightsFactory* mSRSSegLightFactory; - NameGenerator mPathNameGen; + NameGenerator mPathNameGen; }; #endif diff --git a/Samples/ShaderSystemMultiLight/src/RTShaderSRSSegmentedLights.cpp b/Samples/ShaderSystemMultiLight/src/RTShaderSRSSegmentedLights.cpp index 687ac6b7294..101f614c13f 100644 --- a/Samples/ShaderSystemMultiLight/src/RTShaderSRSSegmentedLights.cpp +++ b/Samples/ShaderSystemMultiLight/src/RTShaderSRSSegmentedLights.cpp @@ -11,14 +11,14 @@ #include "OgreMaterialSerializer.h" #include "SegmentedDynamicLightManager.h" -#define SL_LIB_PERPIXELLIGHTING "SegmentedPerPixelLighting" -#define SL_FUNC_TRANSFORMNORMAL "SL_TransformNormal" -#define SL_FUNC_TRANSFORMPOSITION "SL_TransformPosition" -#define SL_FUNC_LIGHT_DIRECTIONAL_DIFFUSE "SL_Light_Directional_Diffuse" -#define SL_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR "SL_Light_Directional_DiffuseSpecular" -#define SL_FUNC_LIGHT_AMBIENT_DIFFUSE "SL_Light_Ambient_Diffuse" -#define SL_FUNC_LIGHT_SEGMENT_TEXTURE_AMBIENT_DIFFUSE "SL_Light_Segment_Texture_Ambient_Diffuse" -#define SL_FUNC_LIGHT_SEGMENT_DEBUG "SL_Light_Segment_Debug" +#define SL_LIB_PERPIXELLIGHTING "SegmentedPerPixelLighting" +#define SL_FUNC_TRANSFORMNORMAL "SL_TransformNormal" +#define SL_FUNC_TRANSFORMPOSITION "SL_TransformPosition" +#define SL_FUNC_LIGHT_DIRECTIONAL_DIFFUSE "SL_Light_Directional_Diffuse" +#define SL_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR "SL_Light_Directional_DiffuseSpecular" +#define SL_FUNC_LIGHT_AMBIENT_DIFFUSE "SL_Light_Ambient_Diffuse" +#define SL_FUNC_LIGHT_SEGMENT_TEXTURE_AMBIENT_DIFFUSE "SL_Light_Segment_Texture_Ambient_Diffuse" +#define SL_FUNC_LIGHT_SEGMENT_DEBUG "SL_Light_Segment_Debug" using namespace Ogre; using namespace Ogre::RTShader; @@ -30,164 +30,164 @@ Light RTShaderSRSSegmentedLights::msBlankLight; //----------------------------------------------------------------------- RTShaderSRSSegmentedLights::RTShaderSRSSegmentedLights() { - mTrackVertexColourType = TVC_NONE; - mSpecularEnable = false; - mUseSegmentedLightTexture = false; - mLightSamplerIndex = 0; - - msBlankLight.setDiffuseColour(ColourValue::Black); - msBlankLight.setSpecularColour(ColourValue::Black); - msBlankLight.setAttenuation(0,1,0,0); + mTrackVertexColourType = TVC_NONE; + mSpecularEnable = false; + mUseSegmentedLightTexture = false; + mLightSamplerIndex = 0; + + msBlankLight.setDiffuseColour(ColourValue::Black); + msBlankLight.setSpecularColour(ColourValue::Black); + msBlankLight.setAttenuation(0,1,0,0); } //----------------------------------------------------------------------- const String& RTShaderSRSSegmentedLights::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int RTShaderSRSSegmentedLights::getExecutionOrder() const +int RTShaderSRSSegmentedLights::getExecutionOrder() const { - return FFP_LIGHTING; + return FFP_LIGHTING; } //----------------------------------------------------------------------- void RTShaderSRSSegmentedLights::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, - const LightList* pLightList) + const LightList* pLightList) { - if ((mLightParamsList.empty()) && (!mUseSegmentedLightTexture)) - return; - - const Matrix4& matWorld = source->getWorldMatrix(); - Light::LightTypes curLightType = Light::LT_DIRECTIONAL; - unsigned int curSearchLightIndex = 0; - - //update spot strength - float spotIntensity = 1; - - // Update per light parameters. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - const LightParams& curParams = mLightParamsList[i]; - - if (curLightType != curParams.mType) - { - curLightType = curParams.mType; - curSearchLightIndex = 0; - } - - Light* srcLight = NULL; - Vector4 vParameter; - ColourValue colour; - - // Search a matching light from the current sorted lights of the given renderable. - for (unsigned int j = curSearchLightIndex; j < pLightList->size(); ++j) - { - if (pLightList->at(j)->getType() == curLightType) - { - srcLight = pLightList->at(j); - curSearchLightIndex = j + 1; - break; - } - } - - // No matching light found -> use a blank dummy light for parameter update. - if (srcLight == NULL) - { - srcLight = &msBlankLight; - } - - - switch (curParams.mType) - { - case Light::LT_DIRECTIONAL: - - // Update light direction. - vParameter = matWorld.transformAffine(srcLight->getAs4DVector(true)); - curParams.mDirection->setGpuParameter(vParameter.ptr(),3,1); - break; - - case Light::LT_POINT: - - // Update light position. - vParameter = matWorld.transformAffine(srcLight->getAs4DVector(true)); - curParams.mPosition->setGpuParameter(vParameter.ptr(),3,1); - - // Update light attenuation parameters. - curParams.mSpotParams->setGpuParameter(Ogre::Vector3(1 / srcLight->getAttenuationRange(),0,0)); - break; - - case Light::LT_SPOTLIGHT: - { - Ogre::Vector3 vec3; - Ogre::Matrix3 matWorldIT; - - - // Update light position. - vParameter = matWorld.transformAffine(srcLight->getAs4DVector(true)); - curParams.mPosition->setGpuParameter(vParameter.ptr(),3,1); - - - // Update light direction. - source->getInverseTransposeWorldMatrix().extract3x3Matrix(matWorldIT); - vec3 = matWorldIT * srcLight->getDerivedDirection(); - vec3.normalise(); - - vParameter.x = -vec3.x; - vParameter.y = -vec3.y; - vParameter.z = -vec3.z; - vParameter.w = 0.0; - curParams.mDirection->setGpuParameter(vParameter.ptr(),3,1); - - // Update spotlight parameters. - Real phi = Math::Cos(srcLight->getSpotlightOuterAngle().valueRadians() * 0.5f); - Real theta = Math::Cos(srcLight->getSpotlightInnerAngle().valueRadians() * 0.5f); - - vec3.x = 1 / srcLight->getAttenuationRange(); - vec3.y = phi; - vec3.z = 1 / (theta - phi); - - curParams.mSpotParams->setGpuParameter(vec3); - } - break; - } - - float lightIntensity = 1; - if (curParams.mType == Light::LT_SPOTLIGHT) - { - lightIntensity = spotIntensity; - } - - // Update diffuse colour. - colour = srcLight->getDiffuseColour() * lightIntensity; - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - colour = colour * pass->getDiffuse(); - } - curParams.mDiffuseColour->setGpuParameter(colour.ptr(),3,1); - - // Update specular colour if need to. - if ((mSpecularEnable) && (curParams.mType == Light::LT_DIRECTIONAL)) - { - // Update diffuse colour. - colour = srcLight->getSpecularColour() * lightIntensity; - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - colour = colour * pass->getSpecular(); - } - curParams.mSpecularColour->setGpuParameter(colour.ptr(),3,1); - } - } - - if (mUseSegmentedLightTexture) - { - unsigned int indexStart = 0, indexEnd = 0; - Ogre::Vector4 lightBounds; - SegmentedDynamicLightManager::getSingleton().getLightListRange(rend, lightBounds, indexStart, indexEnd); - mPSLightTextureIndexLimit->setGpuParameter(Ogre::Vector2((Ogre::Real)indexStart, (Ogre::Real)indexEnd)); - mPSLightTextureLightBounds->setGpuParameter(lightBounds); + if ((mLightParamsList.empty()) && (!mUseSegmentedLightTexture)) + return; + + const Matrix4& matWorld = source->getWorldMatrix(); + Light::LightTypes curLightType = Light::LT_DIRECTIONAL; + unsigned int curSearchLightIndex = 0; + + //update spot strength + float spotIntensity = 1; + + // Update per light parameters. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + const LightParams& curParams = mLightParamsList[i]; + + if (curLightType != curParams.mType) + { + curLightType = curParams.mType; + curSearchLightIndex = 0; + } + + Light* srcLight = NULL; + Vector4 vParameter; + ColourValue colour; + + // Search a matching light from the current sorted lights of the given renderable. + for (unsigned int j = curSearchLightIndex; j < pLightList->size(); ++j) + { + if (pLightList->at(j)->getType() == curLightType) + { + srcLight = pLightList->at(j); + curSearchLightIndex = j + 1; + break; + } + } + + // No matching light found -> use a blank dummy light for parameter update. + if (srcLight == NULL) + { + srcLight = &msBlankLight; + } + + + switch (curParams.mType) + { + case Light::LT_DIRECTIONAL: + + // Update light direction. + vParameter = matWorld.transformAffine(srcLight->getAs4DVector(true)); + curParams.mDirection->setGpuParameter(vParameter.ptr(),3,1); + break; + + case Light::LT_POINT: + + // Update light position. + vParameter = matWorld.transformAffine(srcLight->getAs4DVector(true)); + curParams.mPosition->setGpuParameter(vParameter.ptr(),3,1); + + // Update light attenuation parameters. + curParams.mSpotParams->setGpuParameter(Ogre::Vector3(1 / srcLight->getAttenuationRange(),0,0)); + break; + + case Light::LT_SPOTLIGHT: + { + Ogre::Vector3 vec3; + Ogre::Matrix3 matWorldIT; + + + // Update light position. + vParameter = matWorld.transformAffine(srcLight->getAs4DVector(true)); + curParams.mPosition->setGpuParameter(vParameter.ptr(),3,1); + + + // Update light direction. + source->getInverseTransposeWorldMatrix().extract3x3Matrix(matWorldIT); + vec3 = matWorldIT * srcLight->getDerivedDirection(); + vec3.normalise(); + + vParameter.x = -vec3.x; + vParameter.y = -vec3.y; + vParameter.z = -vec3.z; + vParameter.w = 0.0; + curParams.mDirection->setGpuParameter(vParameter.ptr(),3,1); + + // Update spotlight parameters. + Real phi = Math::Cos(srcLight->getSpotlightOuterAngle().valueRadians() * 0.5f); + Real theta = Math::Cos(srcLight->getSpotlightInnerAngle().valueRadians() * 0.5f); + + vec3.x = 1 / srcLight->getAttenuationRange(); + vec3.y = phi; + vec3.z = 1 / (theta - phi); + + curParams.mSpotParams->setGpuParameter(vec3); + } + break; + } + + float lightIntensity = 1; + if (curParams.mType == Light::LT_SPOTLIGHT) + { + lightIntensity = spotIntensity; + } + + // Update diffuse colour. + colour = srcLight->getDiffuseColour() * lightIntensity; + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + colour = colour * pass->getDiffuse(); + } + curParams.mDiffuseColour->setGpuParameter(colour.ptr(),3,1); + + // Update specular colour if need to. + if ((mSpecularEnable) && (curParams.mType == Light::LT_DIRECTIONAL)) + { + // Update diffuse colour. + colour = srcLight->getSpecularColour() * lightIntensity; + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + colour = colour * pass->getSpecular(); + } + curParams.mSpecularColour->setGpuParameter(colour.ptr(),3,1); + } + } + + if (mUseSegmentedLightTexture) + { + unsigned int indexStart = 0, indexEnd = 0; + Ogre::Vector4 lightBounds; + SegmentedDynamicLightManager::getSingleton().getLightListRange(rend, lightBounds, indexStart, indexEnd); + mPSLightTextureIndexLimit->setGpuParameter(Ogre::Vector2((Ogre::Real)indexStart, (Ogre::Real)indexEnd)); + mPSLightTextureLightBounds->setGpuParameter(lightBounds); Ogre::TextureUnitState* pLightTexture = pass->getTextureUnitState(mLightSamplerIndex); const Ogre::String& textureName = SegmentedDynamicLightManager::getSingleton().getSDLTextureName(); @@ -195,399 +195,399 @@ void RTShaderSRSSegmentedLights::updateGpuProgramsParams(Renderable* rend, Pass* { pLightTexture->setTextureName(textureName, Ogre::TEX_TYPE_2D); } - } + } } //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::resolveParameters(ProgramSet* programSet) { - if (false == resolveGlobalParameters(programSet)) - return false; + if (false == resolveGlobalParameters(programSet)) + return false; - if (false == resolvePerLightParameters(programSet)) - return false; + if (false == resolvePerLightParameters(programSet)) + return false; - return true; + return true; } //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::resolveGlobalParameters(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - - - // Resolve world IT matrix. - mWorldITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, 0); - if (mWorldITMatrix.get() == NULL) - return false; - - // Get surface ambient colour if need to. - if ((mTrackVertexColourType & TVC_AMBIENT) == 0) - { - mDerivedAmbientLightColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR, 0); - if (mDerivedAmbientLightColour.get() == NULL) - return false; - } - else - { - mLightAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, 0); - if (mLightAmbientColour.get() == NULL) - return false; - - mSurfaceAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR, 0); - if (mSurfaceAmbientColour.get() == NULL) - return false; - - } - - // Get surface diffuse colour if need to. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - mSurfaceDiffuseColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR, 0); - if (mSurfaceDiffuseColour.get() == NULL) - return false; - } - - // Get surface specular colour if need to. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - mSurfaceSpecularColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR, 0); - if (mSurfaceSpecularColour.get() == NULL) - return false; - } - - - // Get surface emissive colour if need to. - if ((mTrackVertexColourType & TVC_EMISSIVE) == 0) - { - mSurfaceEmissiveColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR, 0); - if (mSurfaceEmissiveColour.get() == NULL) - return false; - } - - // Get derived scene colour. - mDerivedSceneColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, 0); - if (mDerivedSceneColour.get() == NULL) - return false; - - // Get surface shininess. - mSurfaceShininess = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SHININESS, 0); - if (mSurfaceShininess.get() == NULL) - return false; - - - //Check if another SRS already defined a normal in world space to be used - mPSLocalNormal = psMain->getParameterByContent(psMain->getLocalParameters(), Parameter::SPC_NORMAL_WORLD_SPACE, GCT_FLOAT3); - if (mPSLocalNormal.get() == NULL) - { - //create parameters to fetch the normal from the vertex shader - - // Resolve input vertex shader normal. - mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); - if (mVSInNormal.get() == NULL) - return false; - - // Resolve output vertex shader normal. - mVSOutNormal = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_NORMAL_WORLD_SPACE, GCT_FLOAT3); - if (mVSOutNormal.get() == NULL) - return false; - - // Resolve input pixel shader normal. - mPSInNormal = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutNormal->getIndex(), - mVSOutNormal->getContent(), - GCT_FLOAT3); - - if (mPSInNormal.get() == NULL) - return false; - - mPSLocalNormal = psMain->resolveLocalParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_NORMAL_WORLD_SPACE, GCT_FLOAT3); - } - - const ShaderParameterList& inputParams = psMain->getInputParameters(); - const ShaderParameterList& localParams = psMain->getLocalParameters(); - - mPSDiffuse = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - if (mPSDiffuse.get() == NULL) - { - mPSDiffuse = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - if (mPSDiffuse.get() == NULL) - return false; - } - - mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - if (mPSOutDiffuse.get() == NULL) - return false; - - mPSTempDiffuseColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lPerPixelDiffuse", GCT_FLOAT4); - if (mPSTempDiffuseColour.get() == NULL) - return false; - - mVSOutWorldPos = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT3); - if (mVSOutWorldPos.get() == NULL) - return false; - - mPSInWorldPos = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, - mVSOutWorldPos->getIndex(), - mVSOutWorldPos->getContent(), - GCT_FLOAT3); - if (mPSInWorldPos.get() == NULL) - return false; - - mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - if (mWorldMatrix.get() == NULL) - return false; - - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - if (mVSInPosition.get() == NULL) - return false; - - if (mSpecularEnable) - { - mPSSpecular = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - if (mPSSpecular.get() == NULL) - { - mPSSpecular = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); - if (mPSSpecular.get() == NULL) - return false; - } - - mPSTempSpecularColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lPerPixelSpecular", GCT_FLOAT4); - if (mPSTempSpecularColour.get() == NULL) - return false; - - - mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - if (mVSInPosition.get() == NULL) - return false; - - mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - if (mWorldMatrix.get() == NULL) - return false; - } - - - if (mUseSegmentedLightTexture) - { - mPSLightTextureIndexLimit = psProgram->resolveParameter(GCT_FLOAT2, -1, (uint16)GPV_PER_OBJECT, "LightTextureIndexLimits"); - mPSLightTextureLightBounds = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_PER_OBJECT, "LightTextureBounds"); - mPSSegmentedLightTexture = psProgram->resolveParameter(Ogre::GCT_SAMPLER2D, mLightSamplerIndex, (Ogre::uint16)Ogre::GPV_GLOBAL, "segmentedLightTexture"); - } - - return true; + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + + + // Resolve world IT matrix. + mWorldITMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, 0); + if (mWorldITMatrix.get() == NULL) + return false; + + // Get surface ambient colour if need to. + if ((mTrackVertexColourType & TVC_AMBIENT) == 0) + { + mDerivedAmbientLightColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR, 0); + if (mDerivedAmbientLightColour.get() == NULL) + return false; + } + else + { + mLightAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR, 0); + if (mLightAmbientColour.get() == NULL) + return false; + + mSurfaceAmbientColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR, 0); + if (mSurfaceAmbientColour.get() == NULL) + return false; + + } + + // Get surface diffuse colour if need to. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + mSurfaceDiffuseColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR, 0); + if (mSurfaceDiffuseColour.get() == NULL) + return false; + } + + // Get surface specular colour if need to. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + mSurfaceSpecularColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SPECULAR_COLOUR, 0); + if (mSurfaceSpecularColour.get() == NULL) + return false; + } + + + // Get surface emissive colour if need to. + if ((mTrackVertexColourType & TVC_EMISSIVE) == 0) + { + mSurfaceEmissiveColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR, 0); + if (mSurfaceEmissiveColour.get() == NULL) + return false; + } + + // Get derived scene colour. + mDerivedSceneColour = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_DERIVED_SCENE_COLOUR, 0); + if (mDerivedSceneColour.get() == NULL) + return false; + + // Get surface shininess. + mSurfaceShininess = psProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_SURFACE_SHININESS, 0); + if (mSurfaceShininess.get() == NULL) + return false; + + + //Check if another SRS already defined a normal in world space to be used + mPSLocalNormal = psMain->getParameterByContent(psMain->getLocalParameters(), Parameter::SPC_NORMAL_WORLD_SPACE, GCT_FLOAT3); + if (mPSLocalNormal.get() == NULL) + { + //create parameters to fetch the normal from the vertex shader + + // Resolve input vertex shader normal. + mVSInNormal = vsMain->resolveInputParameter(Parameter::SPS_NORMAL, 0, Parameter::SPC_NORMAL_OBJECT_SPACE, GCT_FLOAT3); + if (mVSInNormal.get() == NULL) + return false; + + // Resolve output vertex shader normal. + mVSOutNormal = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_NORMAL_WORLD_SPACE, GCT_FLOAT3); + if (mVSOutNormal.get() == NULL) + return false; + + // Resolve input pixel shader normal. + mPSInNormal = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutNormal->getIndex(), + mVSOutNormal->getContent(), + GCT_FLOAT3); + + if (mPSInNormal.get() == NULL) + return false; + + mPSLocalNormal = psMain->resolveLocalParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_NORMAL_WORLD_SPACE, GCT_FLOAT3); + } + + const ShaderParameterList& inputParams = psMain->getInputParameters(); + const ShaderParameterList& localParams = psMain->getLocalParameters(); + + mPSDiffuse = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + if (mPSDiffuse.get() == NULL) + { + mPSDiffuse = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + if (mPSDiffuse.get() == NULL) + return false; + } + + mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + if (mPSOutDiffuse.get() == NULL) + return false; + + mPSTempDiffuseColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lPerPixelDiffuse", GCT_FLOAT4); + if (mPSTempDiffuseColour.get() == NULL) + return false; + + mVSOutWorldPos = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, Parameter::SPC_POSITION_WORLD_SPACE, GCT_FLOAT3); + if (mVSOutWorldPos.get() == NULL) + return false; + + mPSInWorldPos = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, + mVSOutWorldPos->getIndex(), + mVSOutWorldPos->getContent(), + GCT_FLOAT3); + if (mPSInWorldPos.get() == NULL) + return false; + + mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + if (mWorldMatrix.get() == NULL) + return false; + + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + if (mVSInPosition.get() == NULL) + return false; + + if (mSpecularEnable) + { + mPSSpecular = psMain->getParameterByContent(inputParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + if (mPSSpecular.get() == NULL) + { + mPSSpecular = psMain->getParameterByContent(localParams, Parameter::SPC_COLOR_SPECULAR, GCT_FLOAT4); + if (mPSSpecular.get() == NULL) + return false; + } + + mPSTempSpecularColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, 0, "lPerPixelSpecular", GCT_FLOAT4); + if (mPSTempSpecularColour.get() == NULL) + return false; + + + mVSInPosition = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + if (mVSInPosition.get() == NULL) + return false; + + mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + if (mWorldMatrix.get() == NULL) + return false; + } + + + if (mUseSegmentedLightTexture) + { + mPSLightTextureIndexLimit = psProgram->resolveParameter(GCT_FLOAT2, -1, (uint16)GPV_PER_OBJECT, "LightTextureIndexLimits"); + mPSLightTextureLightBounds = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_PER_OBJECT, "LightTextureBounds"); + mPSSegmentedLightTexture = psProgram->resolveParameter(Ogre::GCT_SAMPLER2D, mLightSamplerIndex, (Ogre::uint16)Ogre::GPV_GLOBAL, "segmentedLightTexture"); + } + + return true; } //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::resolvePerLightParameters(ProgramSet* programSet) { - Program* psProgram = programSet->getCpuFragmentProgram(); - - // Resolve per light parameters. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - switch (mLightParamsList[i].mType) - { - case Light::LT_DIRECTIONAL: - mLightParamsList[i].mDirection = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "light_direction_space"); - if (mLightParamsList[i].mDirection.get() == NULL) - return false; - break; - - case Light::LT_POINT: - case Light::LT_SPOTLIGHT: - mLightParamsList[i].mPosition = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "light_position_space"); - if (mLightParamsList[i].mPosition.get() == NULL) - return false; - - mLightParamsList[i].mDirection = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "light_direction_space"); - if (mLightParamsList[i].mDirection.get() == NULL) - return false; - - mLightParamsList[i].mSpotParams = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "spotlight_params"); - if (mLightParamsList[i].mSpotParams.get() == NULL) - return false; - - break; - } - - // Resolve diffuse colour. - if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) - { - mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS | (uint16)GPV_GLOBAL, "derived_light_diffuse"); - if (mLightParamsList[i].mDiffuseColour.get() == NULL) - return false; - } - else - { - mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "light_diffuse"); - if (mLightParamsList[i].mDiffuseColour.get() == NULL) - return false; - } - - if ((mSpecularEnable) && (mLightParamsList[i].mType == Light::LT_DIRECTIONAL)) - { - // Resolve specular colour. - if ((mTrackVertexColourType & TVC_SPECULAR) == 0) - { - mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS | (uint16)GPV_GLOBAL, "derived_light_specular"); - if (mLightParamsList[i].mSpecularColour.get() == NULL) - return false; - } - else - { - mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "light_specular"); - if (mLightParamsList[i].mSpecularColour.get() == NULL) - return false; - } - } - - } - - return true; + Program* psProgram = programSet->getCpuFragmentProgram(); + + // Resolve per light parameters. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + switch (mLightParamsList[i].mType) + { + case Light::LT_DIRECTIONAL: + mLightParamsList[i].mDirection = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "light_direction_space"); + if (mLightParamsList[i].mDirection.get() == NULL) + return false; + break; + + case Light::LT_POINT: + case Light::LT_SPOTLIGHT: + mLightParamsList[i].mPosition = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "light_position_space"); + if (mLightParamsList[i].mPosition.get() == NULL) + return false; + + mLightParamsList[i].mDirection = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "light_direction_space"); + if (mLightParamsList[i].mDirection.get() == NULL) + return false; + + mLightParamsList[i].mSpotParams = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "spotlight_params"); + if (mLightParamsList[i].mSpotParams.get() == NULL) + return false; + + break; + } + + // Resolve diffuse colour. + if ((mTrackVertexColourType & TVC_DIFFUSE) == 0) + { + mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS | (uint16)GPV_GLOBAL, "derived_light_diffuse"); + if (mLightParamsList[i].mDiffuseColour.get() == NULL) + return false; + } + else + { + mLightParamsList[i].mDiffuseColour = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "light_diffuse"); + if (mLightParamsList[i].mDiffuseColour.get() == NULL) + return false; + } + + if ((mSpecularEnable) && (mLightParamsList[i].mType == Light::LT_DIRECTIONAL)) + { + // Resolve specular colour. + if ((mTrackVertexColourType & TVC_SPECULAR) == 0) + { + mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS | (uint16)GPV_GLOBAL, "derived_light_specular"); + if (mLightParamsList[i].mSpecularColour.get() == NULL) + return false; + } + else + { + mLightParamsList[i].mSpecularColour = psProgram->resolveParameter(GCT_FLOAT3, -1, (uint16)GPV_LIGHTS, "light_specular"); + if (mLightParamsList[i].mSpecularColour.get() == NULL) + return false; + } + } + + } + + return true; } //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::resolveDependencies(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); - vsProgram->addDependency(FFP_LIB_COMMON); - vsProgram->addDependency(SL_LIB_PERPIXELLIGHTING); + vsProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(SL_LIB_PERPIXELLIGHTING); - psProgram->addDependency(FFP_LIB_COMMON); - psProgram->addDependency(SL_LIB_PERPIXELLIGHTING); + psProgram->addDependency(FFP_LIB_COMMON); + psProgram->addDependency(SL_LIB_PERPIXELLIGHTING); - return true; + return true; } //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::addFunctionInvocations(ProgramSet* programSet) { - Program* vsProgram = programSet->getCpuVertexProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* psMain = psProgram->getEntryPointFunction(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* psMain = psProgram->getEntryPointFunction(); - int internalCounter = 0; + int internalCounter = 0; - // Add the global illumination functions. - if (false == addVSInvocation(vsMain, FFP_VS_LIGHTING, internalCounter)) - return false; + // Add the global illumination functions. + if (false == addVSInvocation(vsMain, FFP_VS_LIGHTING, internalCounter)) + return false; - internalCounter = 0; + internalCounter = 0; - // Add the global illumination functions. - if (false == addPSGlobalIlluminationInvocationBegin(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; + // Add the global illumination functions. + if (false == addPSGlobalIlluminationInvocationBegin(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; - // Add per light functions. - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - if (false == addPSIlluminationInvocation(&mLightParamsList[i], psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; - } + // Add per light functions. + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + if (false == addPSIlluminationInvocation(&mLightParamsList[i], psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; + } - if (mUseSegmentedLightTexture) - { - addPSSegmentedTextureLightInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter); - } + if (mUseSegmentedLightTexture) + { + addPSSegmentedTextureLightInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter); + } - // Add the global illumination functions. - if (false == addPSGlobalIlluminationInvocationEnd(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; + // Add the global illumination functions. + if (false == addPSGlobalIlluminationInvocationEnd(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; - // Assign back temporary variables to the ps diffuse and specular components. - if (false == addPSFinalAssignmentInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) - return false; + // Assign back temporary variables to the ps diffuse and specular components. + if (false == addPSFinalAssignmentInvocation(psMain, FFP_PS_COLOUR_BEGIN + 1, internalCounter)) + return false; - return true; + return true; } //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::addVSInvocation(Function* vsMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - if (mVSInNormal.get() != NULL) - { - // Transform normal in world space. - curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldITMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - // Transform world space position if need to. - if (mVSOutWorldPos.get() != NULL) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_TRANSFORMPOSITION, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutWorldPos, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - } - - - return true; + FunctionInvocation* curFuncInvocation = NULL; + + if (mVSInNormal.get() != NULL) + { + // Transform normal in world space. + curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_TRANSFORMNORMAL, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldITMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutNormal, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + // Transform world space position if need to. + if (mVSOutWorldPos.get() != NULL) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_TRANSFORMPOSITION, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutWorldPos, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + } + + + return true; } //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::addPSGlobalIlluminationInvocationBegin(Function* psMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - if (mPSInNormal.get()) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_PRE_PROCESS + 1, internalCounter++); - curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - //alpha channel is controlled by the diffuse value - if (mTrackVertexColourType & TVC_DIFFUSE) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_W); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_W); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN, Operand::OPM_W); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_W); - psMain->addAtomInstance(curFuncInvocation); - } - - ParameterPtr pZeroParam = ParameterFactory::createConstParamVector3(Ogre::Vector3::ZERO); - - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(pZeroParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(pZeroParam, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - return true; + FunctionInvocation* curFuncInvocation = NULL; + + if (mPSInNormal.get()) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_PRE_PROCESS + 1, internalCounter++); + curFuncInvocation->pushOperand(mPSInNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + //alpha channel is controlled by the diffuse value + if (mTrackVertexColourType & TVC_DIFFUSE) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_W); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_W); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN, Operand::OPM_W); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_W); + psMain->addAtomInstance(curFuncInvocation); + } + + ParameterPtr pZeroParam = ParameterFactory::createConstParamVector3(Ogre::Vector3::ZERO); + + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(pZeroParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(pZeroParam, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + return true; } @@ -595,362 +595,362 @@ bool RTShaderSRSSegmentedLights::addPSGlobalIlluminationInvocationBegin(Function //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::addPSGlobalIlluminationInvocationEnd(Function* psMain, const int groupOrder, int& internalCounter) { - FunctionInvocation* curFuncInvocation = NULL; - - // Merge diffuse colour with vertex colour if need to. - if (mTrackVertexColourType & TVC_DIFFUSE) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - // Merge specular colour with vertex colour if need to. - if ((mSpecularEnable == true) && (mTrackVertexColourType & TVC_SPECULAR)) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - - if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && - (mTrackVertexColourType & TVC_EMISSIVE) == 0) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN, (Operand::OPM_XYZ)); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, (Operand::OPM_XYZ)); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - if (mTrackVertexColourType & TVC_AMBIENT) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mDerivedAmbientLightColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - if (mTrackVertexColourType & TVC_EMISSIVE) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mSurfaceEmissiveColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - } - - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - return true; + FunctionInvocation* curFuncInvocation = NULL; + + // Merge diffuse colour with vertex colour if need to. + if (mTrackVertexColourType & TVC_DIFFUSE) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + // Merge specular colour with vertex colour if need to. + if ((mSpecularEnable == true) && (mTrackVertexColourType & TVC_SPECULAR)) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + + if ((mTrackVertexColourType & TVC_AMBIENT) == 0 && + (mTrackVertexColourType & TVC_EMISSIVE) == 0) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mDerivedSceneColour, Operand::OPS_IN, (Operand::OPM_XYZ)); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, (Operand::OPM_XYZ)); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + if (mTrackVertexColourType & TVC_AMBIENT) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_MODULATE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mLightAmbientColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mDerivedAmbientLightColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + if (mTrackVertexColourType & TVC_EMISSIVE) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mSurfaceEmissiveColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + } + + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ADD, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + return true; } //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::addPSIlluminationInvocation(LightParams* curLightParams, Function* psMain, const int groupOrder, int& internalCounter) -{ - FunctionInvocation* curFuncInvocation = NULL; - - - switch (curLightParams->mType) - { - - case Light::LT_DIRECTIONAL: - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - - else - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_DIRECTIONAL_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - break; - - case Light::LT_POINT: - case Light::LT_SPOTLIGHT: - { - curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_AMBIENT_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_INOUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - } - break; - } - - return true; +{ + FunctionInvocation* curFuncInvocation = NULL; + + + switch (curLightParams->mType) + { + + case Light::LT_DIRECTIONAL: + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_DIRECTIONAL_DIFFUSESPECULAR, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mSpecularColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mSurfaceShininess, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + + else + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_DIRECTIONAL_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN, Operand::OPM_XYZ); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_OUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + break; + + case Light::LT_POINT: + case Light::LT_SPOTLIGHT: + { + curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_AMBIENT_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mPosition, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDirection, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mSpotParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(curLightParams->mDiffuseColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_INOUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + } + break; + } + + return true; } bool RTShaderSRSSegmentedLights::addPSSegmentedTextureLightInvocation(Function* psMain, const int groupOrder, int& internalCounter) { - float invWidth = 1.0f / (float)SegmentedDynamicLightManager::getSingleton().getTextureWidth(); - float invHeight = 1.0f / (float)SegmentedDynamicLightManager::getSingleton().getTextureHeight(); - ParameterPtr paramInvWidth = ParameterFactory::createConstParamFloat(invWidth); - ParameterPtr paramInvHeight = ParameterFactory::createConstParamFloat(invHeight); - - FunctionInvocation* curFuncInvocation = NULL; - curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_SEGMENT_TEXTURE_AMBIENT_DIFFUSE, groupOrder, internalCounter++); - curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSSegmentedLightTexture, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSLightTextureIndexLimit, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSLightTextureLightBounds, Operand::OPS_IN); - curFuncInvocation->pushOperand(paramInvWidth, Operand::OPS_IN); - curFuncInvocation->pushOperand(paramInvHeight, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_INOUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curFuncInvocation); - - if (SegmentedDynamicLightManager::getSingleton().isDebugMode()) - { - ParameterPtr psOutColor = psMain->resolveOutputParameter(Parameter::SPS_COLOR, -1, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - - FunctionInvocation* curDebugFuncInvocation = NULL; - curDebugFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_SEGMENT_DEBUG, FFP_PS_COLOUR_END + 1, internalCounter++); - curDebugFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); - curDebugFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); - curDebugFuncInvocation->pushOperand(mPSSegmentedLightTexture, Operand::OPS_IN); - curDebugFuncInvocation->pushOperand(mPSLightTextureIndexLimit, Operand::OPS_IN); - curDebugFuncInvocation->pushOperand(mPSLightTextureLightBounds, Operand::OPS_IN); - curDebugFuncInvocation->pushOperand(paramInvWidth, Operand::OPS_IN); - curDebugFuncInvocation->pushOperand(paramInvHeight, Operand::OPS_IN); - - curDebugFuncInvocation->pushOperand(psOutColor, Operand::OPS_INOUT, Operand::OPM_XYZ); - psMain->addAtomInstance(curDebugFuncInvocation); - } - - return true; + float invWidth = 1.0f / (float)SegmentedDynamicLightManager::getSingleton().getTextureWidth(); + float invHeight = 1.0f / (float)SegmentedDynamicLightManager::getSingleton().getTextureHeight(); + ParameterPtr paramInvWidth = ParameterFactory::createConstParamFloat(invWidth); + ParameterPtr paramInvHeight = ParameterFactory::createConstParamFloat(invHeight); + + FunctionInvocation* curFuncInvocation = NULL; + curFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_SEGMENT_TEXTURE_AMBIENT_DIFFUSE, groupOrder, internalCounter++); + curFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSSegmentedLightTexture, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSLightTextureIndexLimit, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSLightTextureLightBounds, Operand::OPS_IN); + curFuncInvocation->pushOperand(paramInvWidth, Operand::OPS_IN); + curFuncInvocation->pushOperand(paramInvHeight, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_INOUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curFuncInvocation); + + if (SegmentedDynamicLightManager::getSingleton().isDebugMode()) + { + ParameterPtr psOutColor = psMain->resolveOutputParameter(Parameter::SPS_COLOR, -1, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + + FunctionInvocation* curDebugFuncInvocation = NULL; + curDebugFuncInvocation = OGRE_NEW FunctionInvocation(SL_FUNC_LIGHT_SEGMENT_DEBUG, FFP_PS_COLOUR_END + 1, internalCounter++); + curDebugFuncInvocation->pushOperand(mPSLocalNormal, Operand::OPS_IN); + curDebugFuncInvocation->pushOperand(mPSInWorldPos, Operand::OPS_IN); + curDebugFuncInvocation->pushOperand(mPSSegmentedLightTexture, Operand::OPS_IN); + curDebugFuncInvocation->pushOperand(mPSLightTextureIndexLimit, Operand::OPS_IN); + curDebugFuncInvocation->pushOperand(mPSLightTextureLightBounds, Operand::OPS_IN); + curDebugFuncInvocation->pushOperand(paramInvWidth, Operand::OPS_IN); + curDebugFuncInvocation->pushOperand(paramInvHeight, Operand::OPS_IN); + + curDebugFuncInvocation->pushOperand(psOutColor, Operand::OPS_INOUT, Operand::OPM_XYZ); + psMain->addAtomInstance(curDebugFuncInvocation); + } + + return true; } //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::addPSFinalAssignmentInvocation( Function* psMain, const int groupOrder, int& internalCounter ) { - FunctionInvocation* curFuncInvocation; - - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); - curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); - curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - if (mSpecularEnable) - { - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); - curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - } - - return true; + FunctionInvocation* curFuncInvocation; + + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); + curFuncInvocation->pushOperand(mPSTempDiffuseColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); + curFuncInvocation->pushOperand(mPSDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + if (mSpecularEnable) + { + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_ASSIGN, FFP_PS_COLOUR_BEGIN + 1, internalCounter++); + curFuncInvocation->pushOperand(mPSTempSpecularColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSSpecular, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + } + + return true; } //----------------------------------------------------------------------- void RTShaderSRSSegmentedLights::copyFrom(const SubRenderState& rhs) { - const RTShaderSRSSegmentedLights& rhsLighting = static_cast(rhs); + const RTShaderSRSSegmentedLights& rhsLighting = static_cast(rhs); - mUseSegmentedLightTexture = rhsLighting.mUseSegmentedLightTexture; - - int lightCount[3]; + mUseSegmentedLightTexture = rhsLighting.mUseSegmentedLightTexture; + + int lightCount[3]; - rhsLighting.getLightCount(lightCount); - setLightCount(lightCount); + rhsLighting.getLightCount(lightCount); + setLightCount(lightCount); } //----------------------------------------------------------------------- bool RTShaderSRSSegmentedLights::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { - if (srcPass->getLightingEnabled() == false) - return false; - - mUseSegmentedLightTexture = SegmentedDynamicLightManager::getSingleton().isActive(); - setTrackVertexColourType(srcPass->getVertexColourTracking()); - - if (srcPass->getShininess() > 0.0 && - srcPass->getSpecular() != ColourValue::Black) - { - setSpecularEnable(true); - } - else - { - setSpecularEnable(false); - } - - - int lightCount[3]; - renderState->getLightCount(lightCount); - setLightCount(lightCount); - - if (mUseSegmentedLightTexture) - { - const_cast(renderState)->setLightCountAutoUpdate(false); - - Ogre::TextureUnitState* pLightTexture = dstPass->createTextureUnitState(); - pLightTexture->setTextureName(SegmentedDynamicLightManager::getSingleton().getSDLTextureName(), Ogre::TEX_TYPE_2D); - pLightTexture->setTextureFiltering(Ogre::TFO_NONE); - mLightSamplerIndex = dstPass->getNumTextureUnitStates() - 1; - } - - - return true; + if (srcPass->getLightingEnabled() == false) + return false; + + mUseSegmentedLightTexture = SegmentedDynamicLightManager::getSingleton().isActive(); + setTrackVertexColourType(srcPass->getVertexColourTracking()); + + if (srcPass->getShininess() > 0.0 && + srcPass->getSpecular() != ColourValue::Black) + { + setSpecularEnable(true); + } + else + { + setSpecularEnable(false); + } + + + int lightCount[3]; + renderState->getLightCount(lightCount); + setLightCount(lightCount); + + if (mUseSegmentedLightTexture) + { + const_cast(renderState)->setLightCountAutoUpdate(false); + + Ogre::TextureUnitState* pLightTexture = dstPass->createTextureUnitState(); + pLightTexture->setTextureName(SegmentedDynamicLightManager::getSingleton().getSDLTextureName(), Ogre::TEX_TYPE_2D); + pLightTexture->setTextureFiltering(Ogre::TFO_NONE); + mLightSamplerIndex = dstPass->getNumTextureUnitStates() - 1; + } + + + return true; } //----------------------------------------------------------------------- void RTShaderSRSSegmentedLights::setLightCount(const int lightCount[3]) { - mLightParamsList.clear(); - //Set always to have one single directional lights - LightParams curParams; - curParams.mType = Light::LT_DIRECTIONAL; - mLightParamsList.push_back(curParams); - - for (int type=0; type < 3; ++type) - { - for (int i=0; i < lightCount[type]; ++i) - { - - if (type == 0) - curParams.mType = Light::LT_POINT; - //else if (type == 1) - // curParams.mType = Light::LT_DIRECTIONAL; - else if (type == 2) - curParams.mType = Light::LT_SPOTLIGHT; - - if ((!mUseSegmentedLightTexture) || (curParams.mType == Light::LT_DIRECTIONAL)) - { - mLightParamsList.push_back(curParams); - } - } - } + mLightParamsList.clear(); + //Set always to have one single directional lights + LightParams curParams; + curParams.mType = Light::LT_DIRECTIONAL; + mLightParamsList.push_back(curParams); + + for (int type=0; type < 3; ++type) + { + for (int i=0; i < lightCount[type]; ++i) + { + + if (type == 0) + curParams.mType = Light::LT_POINT; + //else if (type == 1) + // curParams.mType = Light::LT_DIRECTIONAL; + else if (type == 2) + curParams.mType = Light::LT_SPOTLIGHT; + + if ((!mUseSegmentedLightTexture) || (curParams.mType == Light::LT_DIRECTIONAL)) + { + mLightParamsList.push_back(curParams); + } + } + } } //----------------------------------------------------------------------- void RTShaderSRSSegmentedLights::getLightCount(int lightCount[3]) const { - lightCount[0] = 0; - lightCount[1] = 0; - lightCount[2] = 0; - - for (unsigned int i=0; i < mLightParamsList.size(); ++i) - { - const LightParams curParams = mLightParamsList[i]; - - if (curParams.mType == Light::LT_POINT) - lightCount[0]++; - else if (curParams.mType == Light::LT_DIRECTIONAL) - lightCount[1]++; - else if (curParams.mType == Light::LT_SPOTLIGHT) - lightCount[2]++; - } + lightCount[0] = 0; + lightCount[1] = 0; + lightCount[2] = 0; + + for (unsigned int i=0; i < mLightParamsList.size(); ++i) + { + const LightParams curParams = mLightParamsList[i]; + + if (curParams.mType == Light::LT_POINT) + lightCount[0]++; + else if (curParams.mType == Light::LT_DIRECTIONAL) + lightCount[1]++; + else if (curParams.mType == Light::LT_SPOTLIGHT) + lightCount[2]++; + } } //----------------------------------------------------------------------- const String& RTShaderSRSSegmentedLightsFactory::getType() const { - return RTShaderSRSSegmentedLights::Type; + return RTShaderSRSSegmentedLights::Type; } //----------------------------------------------------------------------- -SubRenderState* RTShaderSRSSegmentedLightsFactory::createInstance(ScriptCompiler* compiler, - PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) +SubRenderState* RTShaderSRSSegmentedLightsFactory::createInstance(ScriptCompiler* compiler, + PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator) { - if (prop->name == "lighting_stage") - { - if(prop->values.size() == 1) - { - String modelType; - - if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) - { - compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); - return NULL; - } - - if (modelType == "per_pixel") - { - return createOrRetrieveInstance(translator); - } - } - } - - return NULL; + if (prop->name == "lighting_stage") + { + if(prop->values.size() == 1) + { + String modelType; + + if(false == SGScriptTranslator::getString(prop->values.front(), &modelType)) + { + compiler->addError(ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line); + return NULL; + } + + if (modelType == "per_pixel") + { + return createOrRetrieveInstance(translator); + } + } + } + + return NULL; } //----------------------------------------------------------------------- void RTShaderSRSSegmentedLightsFactory::writeInstance(MaterialSerializer* ser, SubRenderState* subRenderState, - Pass* srcPass, Pass* dstPass) + Pass* srcPass, Pass* dstPass) { - ser->writeAttribute(4, "lighting_stage"); - ser->writeValue("per_pixel"); + ser->writeAttribute(4, "lighting_stage"); + ser->writeValue("per_pixel"); } //----------------------------------------------------------------------- -SubRenderState* RTShaderSRSSegmentedLightsFactory::createInstanceImpl() +SubRenderState* RTShaderSRSSegmentedLightsFactory::createInstanceImpl() { - return OGRE_NEW RTShaderSRSSegmentedLights; + return OGRE_NEW RTShaderSRSSegmentedLights; } diff --git a/Samples/ShaderSystemMultiLight/src/SegmentedDynamicLightManager.cpp b/Samples/ShaderSystemMultiLight/src/SegmentedDynamicLightManager.cpp index 7a383e8834e..d57d1ce4a76 100644 --- a/Samples/ShaderSystemMultiLight/src/SegmentedDynamicLightManager.cpp +++ b/Samples/ShaderSystemMultiLight/src/SegmentedDynamicLightManager.cpp @@ -24,401 +24,401 @@ SegmentedDynamicLightManager::SegmentedDynamicLightManager() : mManager(NULL), mSegmentedLightGrid(SDL_SEGMENT_GRID_SIZE), mLightTexture(), - mTextureWidth(0), - mTextureHeight(SDL_TEXTURE_ROWS) + mTextureWidth(0), + mTextureHeight(SDL_TEXTURE_ROWS) { - //calculate needed texture width - mTextureWidth = SDL_LIGHT_DATA_SIZE * SDL_SEGMENT_GRID_SIZE; - //round up to the nearest power of 2 - unsigned int pow2Val = 1; - for( ; mTextureWidth > pow2Val; pow2Val = pow2Val << 1); - mTextureWidth = pow2Val; + //calculate needed texture width + mTextureWidth = SDL_LIGHT_DATA_SIZE * SDL_SEGMENT_GRID_SIZE; + //round up to the nearest power of 2 + unsigned int pow2Val = 1; + for( ; mTextureWidth > pow2Val; pow2Val = pow2Val << 1); + mTextureWidth = pow2Val; } //------------------------------------------------------------------------------ SegmentedDynamicLightManager::~SegmentedDynamicLightManager() { - setSceneManager(NULL); - if (mLightTexture.get()) - { - TextureManager::getSingleton().remove(mLightTexture->getHandle()); - } + setSceneManager(NULL); + if (mLightTexture.get()) + { + TextureManager::getSingleton().remove(mLightTexture->getHandle()); + } } //------------------------------------------------------------------------------ bool SegmentedDynamicLightManager::setDebugMode(bool i_IsDebugMode) { - bool requireInvalidate = false; - if (mIsDebugMode != i_IsDebugMode) - { - mIsDebugMode = i_IsDebugMode; - requireInvalidate = true; - } - return requireInvalidate; + bool requireInvalidate = false; + if (mIsDebugMode != i_IsDebugMode) + { + mIsDebugMode = i_IsDebugMode; + requireInvalidate = true; + } + return requireInvalidate; } - + //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::postFindVisibleObjects(SceneManager* source, - SceneManager::IlluminationRenderStage irs, Viewport* v) + SceneManager::IlluminationRenderStage irs, Viewport* v) { - if (irs == SceneManager::IRS_NONE) - { - updateLightList(v->getCamera(), source->_getLightsAffectingFrustum()); - } + if (irs == SceneManager::IRS_NONE) + { + updateLightList(v->getCamera(), source->_getLightsAffectingFrustum()); + } } //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::setSceneManager(SceneManager* i_Manager) { - if (mManager != i_Manager) - { - if (mManager) mManager->removeListener(this); - mManager = i_Manager; - if (mManager) - { - mManager->addListener(this); - initTexture(); - } - } + if (mManager != i_Manager) + { + if (mManager) mManager->removeListener(this); + mManager = i_Manager; + if (mManager) + { + mManager->addListener(this); + initTexture(); + } + } } - + //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::updateLightList(const Camera* i_pCamera, const LightList& i_LightList) { - if (isActive()) - { - arrangeLightsInSegmentedLists(i_pCamera, i_LightList); - updateTextureFromSegmentedLists(i_pCamera); - } + if (isActive()) + { + arrangeLightsInSegmentedLists(i_pCamera, i_LightList); + updateTextureFromSegmentedLists(i_pCamera); + } } //------------------------------------------------------------------------------ bool SegmentedDynamicLightManager::initTexture() { - if (mLightTexture.get() == NULL) - { - const String& sdlTextureName = getSDLTextureName(); - // create the render texture - mLightTexture = TextureManager::getSingleton().createManual(sdlTextureName, - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,TEX_TYPE_2D, - mTextureWidth,mTextureHeight,0,PF_FLOAT16_RGBA,TU_STATIC_WRITE_ONLY); - } - return mLightTexture.get() != NULL; + if (mLightTexture.get() == NULL) + { + const String& sdlTextureName = getSDLTextureName(); + // create the render texture + mLightTexture = TextureManager::getSingleton().createManual(sdlTextureName, + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,TEX_TYPE_2D, + mTextureWidth,mTextureHeight,0,PF_FLOAT16_RGBA,TU_STATIC_WRITE_ONLY); + } + return mLightTexture.get() != NULL; } //------------------------------------------------------------------------------ const String& SegmentedDynamicLightManager::getSDLTextureName() { - return c_SDLTextureName; + return c_SDLTextureName; } //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::arrangeLightsInSegmentedLists(const Camera* i_pCamera, const LightList& i_LightList) { - //Clear the previous buffers - for(int i = 0; i < SDL_SEGMENT_GRID_SIZE; ++i) - { - mSegmentedLightGrid[i].clear(); - } - mActiveLights.clear(); - - regenerateActiveLightList(i_LightList); - recalculateGridSize(); - distributeLightsInGrid(); + //Clear the previous buffers + for(int i = 0; i < SDL_SEGMENT_GRID_SIZE; ++i) + { + mSegmentedLightGrid[i].clear(); + } + mActiveLights.clear(); + + regenerateActiveLightList(i_LightList); + recalculateGridSize(); + distributeLightsInGrid(); } - + //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::regenerateActiveLightList(const LightList& i_LightList) { - //add the buffers to the segmented lists - LightList::const_iterator itLight = i_LightList.begin(), - itLightEnd = i_LightList.end(); - for(;itLight != itLightEnd ; ++itLight) - { - const Light* pLight = (*itLight); - Light::LightTypes type = pLight->getType(); - if (((type == Light::LT_SPOTLIGHT) || (type == Light::LT_POINT)) && - (pLight->getAttenuationRange() > 0)) - { - - MapLightData::iterator it = mActiveLights.insert( - MapLightData::value_type(pLight,LightData())).first; - LightData& lightData = it->second; - - calculateLightBounds(pLight, lightData); - } - } + //add the buffers to the segmented lists + LightList::const_iterator itLight = i_LightList.begin(), + itLightEnd = i_LightList.end(); + for(;itLight != itLightEnd ; ++itLight) + { + const Light* pLight = (*itLight); + Light::LightTypes type = pLight->getType(); + if (((type == Light::LT_SPOTLIGHT) || (type == Light::LT_POINT)) && + (pLight->getAttenuationRange() > 0)) + { + + MapLightData::iterator it = mActiveLights.insert( + MapLightData::value_type(pLight,LightData())).first; + LightData& lightData = it->second; + + calculateLightBounds(pLight, lightData); + } + } } //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::calculateLightBounds(const Light* i_Light, LightData& o_LightData) { - Real lightRange = i_Light->getAttenuationRange(); - const Vector3& lightPosition = i_Light->getDerivedPosition(true); - - AxisAlignedBox boundBox(lightPosition - lightRange, lightPosition + lightRange); - - if (i_Light->getType() == Light::LT_SPOTLIGHT) - { - static const Radian c_RadianPI(Math::PI); - static const Radian c_RadianZero(0); - - Radian halfOuterAngle = i_Light->getSpotlightOuterAngle() * 0.5; - Real boxOffset = Math::Sin(halfOuterAngle) * lightRange; - const Vector3& lightDirection = i_Light->getDerivedDirection(); - - Radian dirUpAngle(fabs(Math::ASin(lightDirection.y).valueRadians())); - Radian dirUpMaxAngle = std::max(dirUpAngle - halfOuterAngle,c_RadianZero); - Radian dirUpMinAngle = std::min(dirUpAngle + halfOuterAngle, c_RadianPI); - Real dirDistanceMax = Math::Cos(dirUpMaxAngle) * lightRange; - Real dirDistanceMin = Math::Cos(dirUpMinAngle) * lightRange; - - Vector3 flatDirection(lightDirection.x, 0, lightDirection.z); - Real flatDirLen = flatDirection.length(); - if (flatDirLen != 0) flatDirection /= flatDirLen; - else flatDirection = Vector3(1,0,0); - - Vector3 flatDirectionPerp(flatDirection.z, 0, -flatDirection.x); - flatDirectionPerp *= boxOffset; - - Vector3 flatPositionMax = lightPosition + dirDistanceMax * flatDirection; - Vector3 flatPositionMin = lightPosition + dirDistanceMin * flatDirection; - - AxisAlignedBox spotBox; - spotBox.merge(flatPositionMax + flatDirectionPerp); - spotBox.merge(flatPositionMax - flatDirectionPerp); - spotBox.merge(flatPositionMin + flatDirectionPerp); - spotBox.merge(flatPositionMin - flatDirectionPerp); - spotBox.merge(lightPosition); - - boundBox.getMaximum().makeFloor(spotBox.getMaximum()); - boundBox.getMinimum().makeCeil(spotBox.getMinimum()); - } - - o_LightData.setBounds(boundBox); + Real lightRange = i_Light->getAttenuationRange(); + const Vector3& lightPosition = i_Light->getDerivedPosition(true); + + AxisAlignedBox boundBox(lightPosition - lightRange, lightPosition + lightRange); + + if (i_Light->getType() == Light::LT_SPOTLIGHT) + { + static const Radian c_RadianPI(Math::PI); + static const Radian c_RadianZero(0); + + Radian halfOuterAngle = i_Light->getSpotlightOuterAngle() * 0.5; + Real boxOffset = Math::Sin(halfOuterAngle) * lightRange; + const Vector3& lightDirection = i_Light->getDerivedDirection(); + + Radian dirUpAngle(fabs(Math::ASin(lightDirection.y).valueRadians())); + Radian dirUpMaxAngle = std::max(dirUpAngle - halfOuterAngle,c_RadianZero); + Radian dirUpMinAngle = std::min(dirUpAngle + halfOuterAngle, c_RadianPI); + Real dirDistanceMax = Math::Cos(dirUpMaxAngle) * lightRange; + Real dirDistanceMin = Math::Cos(dirUpMinAngle) * lightRange; + + Vector3 flatDirection(lightDirection.x, 0, lightDirection.z); + Real flatDirLen = flatDirection.length(); + if (flatDirLen != 0) flatDirection /= flatDirLen; + else flatDirection = Vector3(1,0,0); + + Vector3 flatDirectionPerp(flatDirection.z, 0, -flatDirection.x); + flatDirectionPerp *= boxOffset; + + Vector3 flatPositionMax = lightPosition + dirDistanceMax * flatDirection; + Vector3 flatPositionMin = lightPosition + dirDistanceMin * flatDirection; + + AxisAlignedBox spotBox; + spotBox.merge(flatPositionMax + flatDirectionPerp); + spotBox.merge(flatPositionMax - flatDirectionPerp); + spotBox.merge(flatPositionMin + flatDirectionPerp); + spotBox.merge(flatPositionMin - flatDirectionPerp); + spotBox.merge(lightPosition); + + boundBox.getMaximum().makeFloor(spotBox.getMaximum()); + boundBox.getMinimum().makeCeil(spotBox.getMinimum()); + } + + o_LightData.setBounds(boundBox); } //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::recalculateGridSize() { - mGridMinX = std::numeric_limits::max(); - mGridMinZ = std::numeric_limits::max(); - mGridMaxX = -std::numeric_limits::max(); - mGridMaxZ = -std::numeric_limits::max(); - - MapLightData::const_iterator it = mActiveLights.begin(), - itEnd = mActiveLights.end(); - for(;it != itEnd ; ++it) - { - const LightData& lightData = it->second; - mGridMinX = std::min(mGridMinX,lightData.getMinX()); - mGridMaxX = std::max(mGridMaxX,lightData.getMaxX()); - mGridMinZ = std::min(mGridMinZ,lightData.getMinZ()); - mGridMaxZ = std::max(mGridMaxZ,lightData.getMaxZ()); - } + mGridMinX = std::numeric_limits::max(); + mGridMinZ = std::numeric_limits::max(); + mGridMaxX = -std::numeric_limits::max(); + mGridMaxZ = -std::numeric_limits::max(); + + MapLightData::const_iterator it = mActiveLights.begin(), + itEnd = mActiveLights.end(); + for(;it != itEnd ; ++it) + { + const LightData& lightData = it->second; + mGridMinX = std::min(mGridMinX,lightData.getMinX()); + mGridMaxX = std::max(mGridMaxX,lightData.getMaxX()); + mGridMinZ = std::min(mGridMinZ,lightData.getMinZ()); + mGridMaxZ = std::max(mGridMaxZ,lightData.getMaxZ()); + } } - + //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::distributeLightsInGrid() { - MapLightData::iterator it = mActiveLights.begin(), - itEnd = mActiveLights.end(); - for(;it != itEnd ; ++it) - { - LightData& lightData = it->second; - unsigned int indexXStart = calcGridColumn(lightData.getMinX(), mGridMinX, mGridMaxX); - unsigned int indexXEnd = calcGridColumn(lightData.getMaxX(), mGridMinX, mGridMaxX); - unsigned int indexZStart = calcGridColumn(lightData.getMinZ(), mGridMinZ, mGridMaxZ); - unsigned int indexZEnd = calcGridColumn(lightData.getMaxZ(), mGridMinZ, mGridMaxZ); - for(unsigned int i = indexXStart ; i <= indexXEnd ; ++i) - { - for(unsigned int j = indexZStart ; j <= indexZEnd ; ++j) - { - VecLights& block = mSegmentedLightGrid[calcGridIndex(i,j)]; - unsigned int lightIndex = (unsigned int)block.size(); - if (lightIndex < SDL_LIGHT_PER_BLOCK) - { - block.push_back(it->first); - lightData.addIndexToRange(lightIndex); - } - } - } - } + MapLightData::iterator it = mActiveLights.begin(), + itEnd = mActiveLights.end(); + for(;it != itEnd ; ++it) + { + LightData& lightData = it->second; + unsigned int indexXStart = calcGridColumn(lightData.getMinX(), mGridMinX, mGridMaxX); + unsigned int indexXEnd = calcGridColumn(lightData.getMaxX(), mGridMinX, mGridMaxX); + unsigned int indexZStart = calcGridColumn(lightData.getMinZ(), mGridMinZ, mGridMaxZ); + unsigned int indexZEnd = calcGridColumn(lightData.getMaxZ(), mGridMinZ, mGridMaxZ); + for(unsigned int i = indexXStart ; i <= indexXEnd ; ++i) + { + for(unsigned int j = indexZStart ; j <= indexZEnd ; ++j) + { + VecLights& block = mSegmentedLightGrid[calcGridIndex(i,j)]; + unsigned int lightIndex = (unsigned int)block.size(); + if (lightIndex < SDL_LIGHT_PER_BLOCK) + { + block.push_back(it->first); + lightData.addIndexToRange(lightIndex); + } + } + } + } } //------------------------------------------------------------------------------ unsigned int SegmentedDynamicLightManager::calcGridColumn(Real i_Position, - Real i_BoundStart, Real i_BoundEnd) + Real i_BoundStart, Real i_BoundEnd) { - int index = (unsigned int) - (((i_Position - i_BoundStart) / (i_BoundEnd - i_BoundStart)) * SDL_SEGMENT_DIVISIONS); - return (unsigned int)Math::Clamp(index, 0 ,SDL_SEGMENT_DIVISIONS - 1); + int index = (unsigned int) + (((i_Position - i_BoundStart) / (i_BoundEnd - i_BoundStart)) * SDL_SEGMENT_DIVISIONS); + return (unsigned int)Math::Clamp(index, 0 ,SDL_SEGMENT_DIVISIONS - 1); } unsigned int SegmentedDynamicLightManager::calcGridIndex(unsigned int i_X, unsigned int i_Y) { - return i_X + i_Y * SDL_SEGMENT_DIVISIONS; + return i_X + i_Y * SDL_SEGMENT_DIVISIONS; } - + //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::updateTextureFromSegmentedLists(const Camera* i_pCamera) { - float spotIntensity = 1; - - HardwarePixelBufferSharedPtr pBuf = mLightTexture->getBuffer(); - void* pStartPos = pBuf->lock(HardwareBuffer::HBL_DISCARD); - uint16* pData = (uint16*)pStartPos; - - size_t remainBufWidth = mTextureWidth; - for(size_t j = 0; j < SDL_SEGMENT_GRID_SIZE; ++j) - { - //assign first row with number of indexes in the block - float maxRow = (float)(mSegmentedLightGrid[j].size() - 1 + SDL_TEXTURE_DATA_ROWS); - PixelUtil::packColour(maxRow,0.0f,0.0f,0.0f,PF_FLOAT16_RGBA, pData); - pData += 4 * SDL_LIGHT_DATA_SIZE; - remainBufWidth -= SDL_LIGHT_DATA_SIZE; - } - - //advance the remaining space of the row - pData += 4 * remainBufWidth; - - for(size_t i = 0 ; i < SDL_LIGHT_PER_BLOCK ; ++i) - { - remainBufWidth = mTextureWidth; - for(size_t j = 0; j < SDL_SEGMENT_GRID_SIZE; ++j) - { - if (i < mSegmentedLightGrid[j].size()) - { - const Light* pLight = mSegmentedLightGrid[j][i]; - - const Vector3& position = pLight->getDerivedPosition(true); - Vector3 direction = -pLight->getDerivedDirection(); - direction.normalise(); - - // Update spotlight parameters. - Vector3 spotParam; - float inverseRange = 1.0f / (float)pLight->getAttenuationRange(); - float spotAngle = -1; - float spotInvAngleRange = std::numeric_limits::max(); - if (pLight->getType() == Light::LT_SPOTLIGHT) - { - Real phi = Math::Cos(pLight->getSpotlightOuterAngle().valueRadians() * 0.5f); - Real theta = Math::Cos(pLight->getSpotlightInnerAngle().valueRadians() * 0.5f); - spotAngle = (float)phi; - spotInvAngleRange = 1.0f / (float)(theta - phi); - } - - PixelUtil::packColour( - (float)position.x, - (float)position.y, - (float)position.z, - inverseRange, - PF_FLOAT16_RGBA, pData); - pData += 4; - - PixelUtil::packColour( - (float)direction.x, - (float)direction.y, - (float)direction.z, - spotAngle, - PF_FLOAT16_RGBA, pData); - pData += 4; - - PixelUtil::packColour( - pLight->getDiffuseColour().r * spotIntensity, - pLight->getDiffuseColour().g * spotIntensity, - pLight->getDiffuseColour().b * spotIntensity, - spotInvAngleRange, - PF_FLOAT16_RGBA, pData); - pData += 4; - - } - else - { - //assign position zero with zero width - PixelUtil::packColour(0.0f,0.0f,0.0f,std::numeric_limits::max(), - PF_FLOAT16_RGBA, pData); - pData += 4; - for(int d = 0 ; d < (SDL_LIGHT_DATA_SIZE - 1) ; ++d) - { - PixelUtil::packColour(0.0f,0.0f,0.0f,0.0f,PF_FLOAT16_RGBA, pData); - pData += 4; - } - } - remainBufWidth -= 3; - } - - //advance the remaining space of the row - pData += 4 * remainBufWidth; - } - - //Check for memory overrun - if (pBuf->getSizeInBytes() != (size_t)((const char*)(void*)pData - (const char*)pStartPos)) - { - throw "memory overrun"; - } - - pBuf->unlock(); + float spotIntensity = 1; + + HardwarePixelBufferSharedPtr pBuf = mLightTexture->getBuffer(); + void* pStartPos = pBuf->lock(HardwareBuffer::HBL_DISCARD); + uint16* pData = (uint16*)pStartPos; + + size_t remainBufWidth = mTextureWidth; + for(size_t j = 0; j < SDL_SEGMENT_GRID_SIZE; ++j) + { + //assign first row with number of indexes in the block + float maxRow = (float)(mSegmentedLightGrid[j].size() - 1 + SDL_TEXTURE_DATA_ROWS); + PixelUtil::packColour(maxRow,0.0f,0.0f,0.0f,PF_FLOAT16_RGBA, pData); + pData += 4 * SDL_LIGHT_DATA_SIZE; + remainBufWidth -= SDL_LIGHT_DATA_SIZE; + } + + //advance the remaining space of the row + pData += 4 * remainBufWidth; + + for(size_t i = 0 ; i < SDL_LIGHT_PER_BLOCK ; ++i) + { + remainBufWidth = mTextureWidth; + for(size_t j = 0; j < SDL_SEGMENT_GRID_SIZE; ++j) + { + if (i < mSegmentedLightGrid[j].size()) + { + const Light* pLight = mSegmentedLightGrid[j][i]; + + const Vector3& position = pLight->getDerivedPosition(true); + Vector3 direction = -pLight->getDerivedDirection(); + direction.normalise(); + + // Update spotlight parameters. + Vector3 spotParam; + float inverseRange = 1.0f / (float)pLight->getAttenuationRange(); + float spotAngle = -1; + float spotInvAngleRange = std::numeric_limits::max(); + if (pLight->getType() == Light::LT_SPOTLIGHT) + { + Real phi = Math::Cos(pLight->getSpotlightOuterAngle().valueRadians() * 0.5f); + Real theta = Math::Cos(pLight->getSpotlightInnerAngle().valueRadians() * 0.5f); + spotAngle = (float)phi; + spotInvAngleRange = 1.0f / (float)(theta - phi); + } + + PixelUtil::packColour( + (float)position.x, + (float)position.y, + (float)position.z, + inverseRange, + PF_FLOAT16_RGBA, pData); + pData += 4; + + PixelUtil::packColour( + (float)direction.x, + (float)direction.y, + (float)direction.z, + spotAngle, + PF_FLOAT16_RGBA, pData); + pData += 4; + + PixelUtil::packColour( + pLight->getDiffuseColour().r * spotIntensity, + pLight->getDiffuseColour().g * spotIntensity, + pLight->getDiffuseColour().b * spotIntensity, + spotInvAngleRange, + PF_FLOAT16_RGBA, pData); + pData += 4; + + } + else + { + //assign position zero with zero width + PixelUtil::packColour(0.0f,0.0f,0.0f,std::numeric_limits::max(), + PF_FLOAT16_RGBA, pData); + pData += 4; + for(int d = 0 ; d < (SDL_LIGHT_DATA_SIZE - 1) ; ++d) + { + PixelUtil::packColour(0.0f,0.0f,0.0f,0.0f,PF_FLOAT16_RGBA, pData); + pData += 4; + } + } + remainBufWidth -= 3; + } + + //advance the remaining space of the row + pData += 4 * remainBufWidth; + } + + //Check for memory overrun + if (pBuf->getSizeInBytes() != (size_t)((const char*)(void*)pData - (const char*)pStartPos)) + { + throw "memory overrun"; + } + + pBuf->unlock(); } //------------------------------------------------------------------------------ bool SegmentedDynamicLightManager::getLightListRange(const Renderable* i_Rend, - Vector4& o_GridBounds, unsigned int& o_IndexMin, unsigned int& o_IndexMax) + Vector4& o_GridBounds, unsigned int& o_IndexMin, unsigned int& o_IndexMax) { - o_IndexMin = 100000; - o_IndexMax = 0; - - const LightList& lights = i_Rend->getLights(); - LightList::const_iterator it = lights.begin(), itEnd = lights.end(); - for(; it != itEnd ; ++it) - { - MapLightData::const_iterator itActive = mActiveLights.find(*it); - if (itActive != mActiveLights.end()) - { - o_IndexMin = (unsigned int)std::min(o_IndexMin, itActive->second.getIndexMin()); - o_IndexMax = (unsigned int)std::max(o_IndexMax, itActive->second.getIndexMax()); - } - } - - o_GridBounds.x = mGridMinX; - o_GridBounds.y = mGridMinZ; - o_GridBounds.z = SDL_SEGMENT_DIVISIONS / (mGridMaxX - mGridMinX); - o_GridBounds.w = SDL_SEGMENT_DIVISIONS / (mGridMaxZ - mGridMinZ); - o_IndexMin += SDL_TEXTURE_DATA_ROWS; - o_IndexMax += SDL_TEXTURE_DATA_ROWS; - return o_IndexMin <= o_IndexMax; + o_IndexMin = 100000; + o_IndexMax = 0; + + const LightList& lights = i_Rend->getLights(); + LightList::const_iterator it = lights.begin(), itEnd = lights.end(); + for(; it != itEnd ; ++it) + { + MapLightData::const_iterator itActive = mActiveLights.find(*it); + if (itActive != mActiveLights.end()) + { + o_IndexMin = (unsigned int)std::min(o_IndexMin, itActive->second.getIndexMin()); + o_IndexMax = (unsigned int)std::max(o_IndexMax, itActive->second.getIndexMax()); + } + } + + o_GridBounds.x = mGridMinX; + o_GridBounds.y = mGridMinZ; + o_GridBounds.z = SDL_SEGMENT_DIVISIONS / (mGridMaxX - mGridMinX); + o_GridBounds.w = SDL_SEGMENT_DIVISIONS / (mGridMaxZ - mGridMinZ); + o_IndexMin += SDL_TEXTURE_DATA_ROWS; + o_IndexMax += SDL_TEXTURE_DATA_ROWS; + return o_IndexMin <= o_IndexMax; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -////// SegmentedDynamicLightManager::LightData +////// SegmentedDynamicLightManager::LightData ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------------ SegmentedDynamicLightManager::LightData::LightData() -{ - mIndexMin = 100000; - mIndexMax = 0; - mMinX = std::numeric_limits::max(); - mMaxX = -std::numeric_limits::max(); - mMinZ = std::numeric_limits::max(); - mMaxZ = -std::numeric_limits::max(); +{ + mIndexMin = 100000; + mIndexMax = 0; + mMinX = std::numeric_limits::max(); + mMaxX = -std::numeric_limits::max(); + mMinZ = std::numeric_limits::max(); + mMaxZ = -std::numeric_limits::max(); } //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::LightData::setBounds(const AxisAlignedBox& i_Bounds) { - mMinX = i_Bounds.getMinimum().x; - mMaxX = i_Bounds.getMaximum().x; - mMinZ = i_Bounds.getMinimum().z; - mMaxZ = i_Bounds.getMaximum().z; + mMinX = i_Bounds.getMinimum().x; + mMaxX = i_Bounds.getMaximum().x; + mMinZ = i_Bounds.getMinimum().z; + mMaxZ = i_Bounds.getMaximum().z; } //------------------------------------------------------------------------------ void SegmentedDynamicLightManager::LightData::addIndexToRange(unsigned int i_LightIndex) { - mIndexMin = (unsigned int)std::min(mIndexMin, i_LightIndex); - mIndexMax = (unsigned int)std::max(mIndexMax, i_LightIndex); + mIndexMin = (unsigned int)std::min(mIndexMin, i_LightIndex); + mIndexMax = (unsigned int)std::max(mIndexMax, i_LightIndex); } diff --git a/Samples/ShaderSystemMultiLight/src/ShaderSystemMultiLight.cpp b/Samples/ShaderSystemMultiLight/src/ShaderSystemMultiLight.cpp index fdf1676ce72..a8a387ee371 100644 --- a/Samples/ShaderSystemMultiLight/src/ShaderSystemMultiLight.cpp +++ b/Samples/ShaderSystemMultiLight/src/ShaderSystemMultiLight.cpp @@ -11,17 +11,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_ShaderSystemMultiLight; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_ShaderSystemMultiLight; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/ShaderSystemTexturedFog/include/RTShaderSRSTexturedFog.h b/Samples/ShaderSystemTexturedFog/include/RTShaderSRSTexturedFog.h index 91c488ce44e..ef46e4b35fe 100644 --- a/Samples/ShaderSystemTexturedFog/include/RTShaderSRSTexturedFog.h +++ b/Samples/ShaderSystemTexturedFog/include/RTShaderSRSTexturedFog.h @@ -47,103 +47,103 @@ class RTShaderSRSTexturedFog : public SubRenderState // Interface. public: - /** Class default constructor */ - RTShaderSRSTexturedFog(RTShaderSRSTexturedFogFactory* factory = NULL); - - /** - @see SubRenderState::getType. - */ - virtual const String& getType() const; - - /** - @see SubRenderState::getType. - */ - virtual int getExecutionOrder() const; - - /** - @see SubRenderState::updateGpuProgramsParams. - */ - virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); - - /** - @see SubRenderState::copyFrom. - */ - virtual void copyFrom(const SubRenderState& rhs); - - /** - @see SubRenderState::preAddToRenderState. - */ - virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); - - /** - Set the fog properties this fog sub render state should emulate. - @param fogMode The fog mode to emulate (FOG_NONE, FOG_EXP, FOG_EXP2, FOG_LINEAR). - @param fogStart Start distance of fog, used for linear mode only. - @param fogEnd End distance of fog, used for linear mode only. - @param fogDensity Fog density used in exponential modes only. - */ - void setFogProperties(FogMode fogMode, float fogStart, float fogEnd, float fogDensity); - - static String Type; + /** Class default constructor */ + RTShaderSRSTexturedFog(RTShaderSRSTexturedFogFactory* factory = NULL); + + /** + @see SubRenderState::getType. + */ + virtual const String& getType() const; + + /** + @see SubRenderState::getType. + */ + virtual int getExecutionOrder() const; + + /** + @see SubRenderState::updateGpuProgramsParams. + */ + virtual void updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, const LightList* pLightList); + + /** + @see SubRenderState::copyFrom. + */ + virtual void copyFrom(const SubRenderState& rhs); + + /** + @see SubRenderState::preAddToRenderState. + */ + virtual bool preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass); + + /** + Set the fog properties this fog sub render state should emulate. + @param fogMode The fog mode to emulate (FOG_NONE, FOG_EXP, FOG_EXP2, FOG_LINEAR). + @param fogStart Start distance of fog, used for linear mode only. + @param fogEnd End distance of fog, used for linear mode only. + @param fogDensity Fog density used in exponential modes only. + */ + void setFogProperties(FogMode fogMode, float fogStart, float fogEnd, float fogDensity); + + static String Type; // Protected methods protected: - /** - @see SubRenderState::resolveParameters. - */ - virtual bool resolveParameters(ProgramSet* programSet); + /** + @see SubRenderState::resolveParameters. + */ + virtual bool resolveParameters(ProgramSet* programSet); - /** - @see SubRenderState::resolveDependencies. - */ - virtual bool resolveDependencies(ProgramSet* programSet); + /** + @see SubRenderState::resolveDependencies. + */ + virtual bool resolveDependencies(ProgramSet* programSet); - /** - @see SubRenderState::addFunctionInvocations. - */ - virtual bool addFunctionInvocations(ProgramSet* programSet); + /** + @see SubRenderState::addFunctionInvocations. + */ + virtual bool addFunctionInvocations(ProgramSet* programSet); // Attributes. -protected: - /// The factory which created the texture fog instance - RTShaderSRSTexturedFogFactory* mFactory; - /// Fog formula. - FogMode mFogMode; - /// Fog parameters (density, start, end, 1/end-start). - Vector4 mFogParamsValue; - /// True if the fog parameters should be taken from the pass. - bool mPassOverrideParams; - /// The index of the background texture unit state in the pass - unsigned int mBackgroundSamplerIndex; - - // World matrix parameter. - UniformParameterPtr mWorldMatrix; - // camera position parameter. - UniformParameterPtr mCameraPos; - // Fog parameters program parameter. - UniformParameterPtr mFogParams; - // Vertex shader input position parameter. - ParameterPtr mVSInPos; - // Fog colour parameter. - ParameterPtr mFogColour; - // Vertex shader output fog colour parameter. - ParameterPtr mVSOutFogFactor; - // Pixel shader input fog factor. - ParameterPtr mPSInFogFactor; - // Vertex shader output depth. - ParameterPtr mVSOutDepth; - // Pixel shader input depth. - ParameterPtr mPSInDepth; - // Vertex shader world position relative to camera. - ParameterPtr mVSOutPosView; - // Pixel shader world position relative to camera. - ParameterPtr mPSInPosView; - // Pixel shader output diffuse colour. - ParameterPtr mPSOutDiffuse; - //Background color texture parameter - ParameterPtr mBackgroundTextureSampler; - +protected: + /// The factory which created the texture fog instance + RTShaderSRSTexturedFogFactory* mFactory; + /// Fog formula. + FogMode mFogMode; + /// Fog parameters (density, start, end, 1/end-start). + Vector4 mFogParamsValue; + /// True if the fog parameters should be taken from the pass. + bool mPassOverrideParams; + /// The index of the background texture unit state in the pass + unsigned int mBackgroundSamplerIndex; + + // World matrix parameter. + UniformParameterPtr mWorldMatrix; + // camera position parameter. + UniformParameterPtr mCameraPos; + // Fog parameters program parameter. + UniformParameterPtr mFogParams; + // Vertex shader input position parameter. + ParameterPtr mVSInPos; + // Fog colour parameter. + ParameterPtr mFogColour; + // Vertex shader output fog colour parameter. + ParameterPtr mVSOutFogFactor; + // Pixel shader input fog factor. + ParameterPtr mPSInFogFactor; + // Vertex shader output depth. + ParameterPtr mVSOutDepth; + // Pixel shader input depth. + ParameterPtr mPSInDepth; + // Vertex shader world position relative to camera. + ParameterPtr mVSOutPosView; + // Pixel shader world position relative to camera. + ParameterPtr mPSInPosView; + // Pixel shader output diffuse colour. + ParameterPtr mPSOutDiffuse; + //Background color texture parameter + ParameterPtr mBackgroundTextureSampler; + }; @@ -155,25 +155,25 @@ class RTShaderSRSTexturedFogFactory : public SubRenderStateFactory { public: - /** - @see SubRenderStateFactory::getType. - */ - virtual const String& getType() const; + /** + @see SubRenderStateFactory::getType. + */ + virtual const String& getType() const; - /** Set the name of the texture to use as a background for the fog */ - const String& getBackgroundTextureName() const { return mBackgroundTextureName; } - /** Return the name of the texture used as a background for the fog */ - void setBackgroundTextureName(const String& name) { mBackgroundTextureName = name; } - + /** Set the name of the texture to use as a background for the fog */ + const String& getBackgroundTextureName() const { return mBackgroundTextureName; } + /** Return the name of the texture used as a background for the fog */ + void setBackgroundTextureName(const String& name) { mBackgroundTextureName = name; } + protected: - /** - @see SubRenderStateFactory::createInstanceImpl. - */ - virtual SubRenderState* createInstanceImpl(); + /** + @see SubRenderStateFactory::createInstanceImpl. + */ + virtual SubRenderState* createInstanceImpl(); private: - String mBackgroundTextureName; + String mBackgroundTextureName; }; #endif diff --git a/Samples/ShaderSystemTexturedFog/include/ShaderSystemTexturedFog.h b/Samples/ShaderSystemTexturedFog/include/ShaderSystemTexturedFog.h index aba813bb6c1..dd45779cf32 100644 --- a/Samples/ShaderSystemTexturedFog/include/ShaderSystemTexturedFog.h +++ b/Samples/ShaderSystemTexturedFog/include/ShaderSystemTexturedFog.h @@ -19,205 +19,205 @@ class _OgreSampleClassExport Sample_ShaderSystemTexturedFog : public SdkSample { public: - Sample_ShaderSystemTexturedFog() : - mSRSTextureFogFactory(NULL), - mEntityNameGen("Head") - { - mInfo["Title"] = "Shader System - Textured Fog"; - mInfo["Description"] = "Shows a simple implementation of a RTSS sub-render state implementing a fog based on texture effect."; - mInfo["Thumbnail"] = "thumb_texturedfog.png"; - mInfo["Category"] = "Lighting"; - } - - ~Sample_ShaderSystemTexturedFog() - { - - } - - virtual void _shutdown() - { - RTShader::RenderState* pMainRenderState = - RTShader::ShaderGenerator::getSingleton().createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first; - pMainRenderState->reset(); - - if (mSRSTextureFogFactory) - { - RTShader::ShaderGenerator::getSingleton().removeAllShaderBasedTechniques(); - RTShader::ShaderGenerator::getSingleton().removeSubRenderStateFactory(mSRSTextureFogFactory); - delete mSRSTextureFogFactory; - mSRSTextureFogFactory = NULL; - } - - SdkSample::_shutdown(); - } + Sample_ShaderSystemTexturedFog() : + mSRSTextureFogFactory(NULL), + mEntityNameGen("Head") + { + mInfo["Title"] = "Shader System - Textured Fog"; + mInfo["Description"] = "Shows a simple implementation of a RTSS sub-render state implementing a fog based on texture effect."; + mInfo["Thumbnail"] = "thumb_texturedfog.png"; + mInfo["Category"] = "Lighting"; + } + + ~Sample_ShaderSystemTexturedFog() + { + + } + + virtual void _shutdown() + { + RTShader::RenderState* pMainRenderState = + RTShader::ShaderGenerator::getSingleton().createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first; + pMainRenderState->reset(); + + if (mSRSTextureFogFactory) + { + RTShader::ShaderGenerator::getSingleton().removeAllShaderBasedTechniques(); + RTShader::ShaderGenerator::getSingleton().removeSubRenderStateFactory(mSRSTextureFogFactory); + delete mSRSTextureFogFactory; + mSRSTextureFogFactory = NULL; + } + + SdkSample::_shutdown(); + } bool frameRenderingQueued(const FrameEvent& evt) { - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! } protected: void setupContent() - { - mTrayMgr->createCheckBox(TL_BOTTOM, ACTIVATE_FOG_BUTTON, "Fog Active")->setChecked(true,false); - mTrayMgr->createCheckBox(TL_BOTTOM, ACTIVATE_SKY_BUTTON, "Sky Box Active")->setChecked(true,false); - mTrayMgr->createThickSlider(TL_BOTTOM, FOG_DISTANCE_SLIDER, "Fog Distance", 240, 80, 20, 2000, 100)->setValue(1000, false); - mTrayMgr->createThickSlider(TL_BOTTOM, FOG_BACKGROUND_SLIDER, "Background", 240, 80, 0, 3, 4)->setValue(0, false); + { + mTrayMgr->createCheckBox(TL_BOTTOM, ACTIVATE_FOG_BUTTON, "Fog Active")->setChecked(true,false); + mTrayMgr->createCheckBox(TL_BOTTOM, ACTIVATE_SKY_BUTTON, "Sky Box Active")->setChecked(true,false); + mTrayMgr->createThickSlider(TL_BOTTOM, FOG_DISTANCE_SLIDER, "Fog Distance", 240, 80, 20, 2000, 100)->setValue(1000, false); + mTrayMgr->createThickSlider(TL_BOTTOM, FOG_BACKGROUND_SLIDER, "Background", 240, 80, 0, 3, 4)->setValue(0, false); setupShaderGenerator(); - mSceneMgr->setFog(FOG_LINEAR, ColourValue::White, 0, 500, 1000); - - mCamera->setPosition(0, -20, 470); + mSceneMgr->setFog(FOG_LINEAR, ColourValue::White, 0, 500, 1000); + + mCamera->setPosition(0, -20, 470); - mTrayMgr->showCursor(); + mTrayMgr->showCursor(); - // create a floor mesh resource - MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Plane(Vector3::UNIT_Y, -30), 1000, 1000, 10, 10, true, 1, 8, 8, Vector3::UNIT_Z); + // create a floor mesh resource + MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Plane(Vector3::UNIT_Y, -30), 1000, 1000, 10, 10, true, 1, 8, 8, Vector3::UNIT_Z); - // create a floor entity, give it a material, and place it at the origin + // create a floor entity, give it a material, and place it at the origin Entity* floor = mSceneMgr->createEntity("Floor", "floor"); floor->setMaterialName("Examples/BumpyMetal"); mSceneMgr->getRootSceneNode()->attachObject(floor); - - addHead(Vector3(100,0,-400)); - addHead(Vector3(100,0,-200)); - addHead(Vector3(100,0,0)); - addHead(Vector3(100,0,200)); - - addHead(Vector3(-100,0,-400)); - addHead(Vector3(-100,0,-200)); - addHead(Vector3(-100,0,0)); - addHead(Vector3(-100,0,200)); - - //We will set the sky box far away so it will render with the color of the background - mSceneMgr->setSkyBox(true,"BaseWhite",2000); - } + + addHead(Vector3(100,0,-400)); + addHead(Vector3(100,0,-200)); + addHead(Vector3(100,0,0)); + addHead(Vector3(100,0,200)); + + addHead(Vector3(-100,0,-400)); + addHead(Vector3(-100,0,-200)); + addHead(Vector3(-100,0,0)); + addHead(Vector3(-100,0,200)); + + //We will set the sky box far away so it will render with the color of the background + mSceneMgr->setSkyBox(true,"BaseWhite",2000); + } void addHead(const Vector3& pos) { - // Create an ogre head and place it at the origin - Entity* head = mSceneMgr->createEntity(mEntityNameGen.generate(), "ogrehead.mesh"); - head->setRenderQueueGroup(cPriorityMain); - mSceneMgr->getRootSceneNode()->createChildSceneNode(pos) - ->attachObject(head); + // Create an ogre head and place it at the origin + Entity* head = mSceneMgr->createEntity(mEntityNameGen.generate(), "ogrehead.mesh"); + head->setRenderQueueGroup(cPriorityMain); + mSceneMgr->getRootSceneNode()->createChildSceneNode(pos) + ->attachObject(head); } - - void setupShaderGenerator() - { - RTShader::ShaderGenerator* mGen = RTShader::ShaderGenerator::getSingletonPtr(); + + void setupShaderGenerator() + { + RTShader::ShaderGenerator* mGen = RTShader::ShaderGenerator::getSingletonPtr(); - RTShader::RenderState* pMainRenderState = + RTShader::RenderState* pMainRenderState = mGen->createOrRetrieveRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME).first; - pMainRenderState->reset(); - - mSRSTextureFogFactory = new RTShaderSRSTexturedFogFactory; - mGen->addSubRenderStateFactory(mSRSTextureFogFactory); - pMainRenderState->addTemplateSubRenderState( - mGen->createSubRenderState(RTShaderSRSTexturedFog::Type)); - - mSRSTextureFogFactory->setBackgroundTextureName("early_morning.jpg"); - - - - mGen->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - - // Make this viewport work with shader generator scheme. - mViewport->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - } - - - - - //-------------------------------------------------------------------------- - void sliderMoved(Slider* slider) - { - if (slider->getName() == FOG_DISTANCE_SLIDER) - { - Real fogDist = slider->getValue(); - mSceneMgr->setFog(mSceneMgr->getFogMode(), ColourValue::White, 0, fogDist * 0.5f, fogDist); - } - if (slider->getName() == FOG_BACKGROUND_SLIDER) - { - String textureName; - size_t back = (size_t)(slider->getValue() + 0.5); - switch (back) - { - case 0: textureName = "early_morning.jpg"; break; - case 1: textureName = "cloudy_noon.jpg"; break; - case 2: textureName = "stormy.jpg"; break; - default: textureName = "evening.jpg"; break; - } - mSRSTextureFogFactory->setBackgroundTextureName(textureName); - RTShader::ShaderGenerator* gen = RTShader::ShaderGenerator::getSingletonPtr(); - gen->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - } - } - - void checkBoxToggled(CheckBox* box) - { - const String& cbName = box->getName(); - if (cbName == ACTIVATE_FOG_BUTTON) - { - //With our shader the 3 middle parameters don't really make a difference. Only the first and last do. - FogMode mode = mSceneMgr->getFogMode() == FOG_NONE ? FOG_LINEAR : FOG_NONE; - mSceneMgr->setFog(mode, ColourValue::White, 0, mSceneMgr->getFogStart(), mSceneMgr->getFogEnd()); - } - if (cbName == ACTIVATE_SKY_BUTTON) - { - mSceneMgr->setSkyBox(!mSceneMgr->isSkyBoxEnabled(),"BaseWhite",2000); - - } - } - - #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) - - //----------------------------------------------------------------------- - bool mousePressed( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) - { - if (mTrayMgr->injectMouseDown(evt, id)) - return true; - if (id == OIS::MB_Left) - mTrayMgr->hideCursor(); // hide the cursor if user left-clicks in the scene - - return true; - } - - //----------------------------------------------------------------------- - bool mouseReleased( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) - { - if (mTrayMgr->injectMouseUp(evt, id)) - return true; - if (id == OIS::MB_Left) - mTrayMgr->showCursor(); // unhide the cursor if user lets go of LMB - - return true; - } - - //----------------------------------------------------------------------- - bool mouseMoved( const OIS::MouseEvent& evt ) - { - // only rotate the camera if cursor is hidden - if (mTrayMgr->isCursorVisible()) - mTrayMgr->injectMouseMove(evt); - else - mCameraMan->injectMouseMove(evt); - - - return true; - } - #endif - - + pMainRenderState->reset(); + + mSRSTextureFogFactory = new RTShaderSRSTexturedFogFactory; + mGen->addSubRenderStateFactory(mSRSTextureFogFactory); + pMainRenderState->addTemplateSubRenderState( + mGen->createSubRenderState(RTShaderSRSTexturedFog::Type)); + + mSRSTextureFogFactory->setBackgroundTextureName("early_morning.jpg"); + + + + mGen->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + + // Make this viewport work with shader generator scheme. + mViewport->setMaterialScheme(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + } + + + + + //-------------------------------------------------------------------------- + void sliderMoved(Slider* slider) + { + if (slider->getName() == FOG_DISTANCE_SLIDER) + { + Real fogDist = slider->getValue(); + mSceneMgr->setFog(mSceneMgr->getFogMode(), ColourValue::White, 0, fogDist * 0.5f, fogDist); + } + if (slider->getName() == FOG_BACKGROUND_SLIDER) + { + String textureName; + size_t back = (size_t)(slider->getValue() + 0.5); + switch (back) + { + case 0: textureName = "early_morning.jpg"; break; + case 1: textureName = "cloudy_noon.jpg"; break; + case 2: textureName = "stormy.jpg"; break; + default: textureName = "evening.jpg"; break; + } + mSRSTextureFogFactory->setBackgroundTextureName(textureName); + RTShader::ShaderGenerator* gen = RTShader::ShaderGenerator::getSingletonPtr(); + gen->invalidateScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + } + } + + void checkBoxToggled(CheckBox* box) + { + const String& cbName = box->getName(); + if (cbName == ACTIVATE_FOG_BUTTON) + { + //With our shader the 3 middle parameters don't really make a difference. Only the first and last do. + FogMode mode = mSceneMgr->getFogMode() == FOG_NONE ? FOG_LINEAR : FOG_NONE; + mSceneMgr->setFog(mode, ColourValue::White, 0, mSceneMgr->getFogStart(), mSceneMgr->getFogEnd()); + } + if (cbName == ACTIVATE_SKY_BUTTON) + { + mSceneMgr->setSkyBox(!mSceneMgr->isSkyBoxEnabled(),"BaseWhite",2000); + + } + } + + #if (OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS) && (OGRE_PLATFORM != OGRE_PLATFORM_ANDROID) + + //----------------------------------------------------------------------- + bool mousePressed( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) + { + if (mTrayMgr->injectMouseDown(evt, id)) + return true; + if (id == OIS::MB_Left) + mTrayMgr->hideCursor(); // hide the cursor if user left-clicks in the scene + + return true; + } + + //----------------------------------------------------------------------- + bool mouseReleased( const OIS::MouseEvent& evt, OIS::MouseButtonID id ) + { + if (mTrayMgr->injectMouseUp(evt, id)) + return true; + if (id == OIS::MB_Left) + mTrayMgr->showCursor(); // unhide the cursor if user lets go of LMB + + return true; + } + + //----------------------------------------------------------------------- + bool mouseMoved( const OIS::MouseEvent& evt ) + { + // only rotate the camera if cursor is hidden + if (mTrayMgr->isCursorVisible()) + mTrayMgr->injectMouseMove(evt); + else + mCameraMan->injectMouseMove(evt); + + + return true; + } + #endif + + private: - RTShaderSRSTexturedFogFactory* mSRSTextureFogFactory; + RTShaderSRSTexturedFogFactory* mSRSTextureFogFactory; - NameGenerator mEntityNameGen; + NameGenerator mEntityNameGen; }; diff --git a/Samples/ShaderSystemTexturedFog/src/RTShaderSRSTexturedFog.cpp b/Samples/ShaderSystemTexturedFog/src/RTShaderSRSTexturedFog.cpp index 1ad8753ecf3..58955c8526e 100644 --- a/Samples/ShaderSystemTexturedFog/src/RTShaderSRSTexturedFog.cpp +++ b/Samples/ShaderSystemTexturedFog/src/RTShaderSRSTexturedFog.cpp @@ -33,7 +33,7 @@ THE SOFTWARE. #include "OgrePass.h" #include "OgreShaderGenerator.h" -#define FFP_FUNC_PIXELFOG_POSITION_DEPTH "FFP_PixelFog_PositionDepth" +#define FFP_FUNC_PIXELFOG_POSITION_DEPTH "FFP_PixelFog_PositionDepth" using namespace Ogre; using namespace RTShader; @@ -45,303 +45,303 @@ String RTShaderSRSTexturedFog::Type = "TexturedFog"; //----------------------------------------------------------------------- RTShaderSRSTexturedFog::RTShaderSRSTexturedFog(RTShaderSRSTexturedFogFactory* factory) { - mFactory = factory; - mFogMode = FOG_NONE; - mPassOverrideParams = false; + mFactory = factory; + mFogMode = FOG_NONE; + mPassOverrideParams = false; } //----------------------------------------------------------------------- const String& RTShaderSRSTexturedFog::getType() const { - return Type; + return Type; } //----------------------------------------------------------------------- -int RTShaderSRSTexturedFog::getExecutionOrder() const +int RTShaderSRSTexturedFog::getExecutionOrder() const { - return FFP_FOG; + return FFP_FOG; } //----------------------------------------------------------------------- void RTShaderSRSTexturedFog::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, - const LightList* pLightList) -{ - if (mFogMode == FOG_NONE) - return; - - FogMode fogMode; - Real newFogStart, newFogEnd, newFogDensity; - - //Check if this is an overlay element if so disable fog - if ((rend->getUseIdentityView() == true) && (rend->getUseIdentityProjection() == true)) - { - fogMode = FOG_NONE; - newFogStart = 100000000; - newFogEnd = 200000000; - newFogDensity = 0; - } - else - { - if (mPassOverrideParams) - { - fogMode = pass->getFogMode(); - newFogStart = pass->getFogStart(); - newFogEnd = pass->getFogEnd(); - newFogDensity = pass->getFogDensity(); - } - else - { - SceneManager* sceneMgr = ShaderGenerator::getSingleton().getActiveSceneManager(); - - fogMode = sceneMgr->getFogMode(); - newFogStart = sceneMgr->getFogStart(); - newFogEnd = sceneMgr->getFogEnd(); - newFogDensity = sceneMgr->getFogDensity(); - } - } - - // Set fog properties. - setFogProperties(fogMode, newFogStart, newFogEnd, newFogDensity); - - mFogParams->setGpuParameter(mFogParamsValue); + const LightList* pLightList) +{ + if (mFogMode == FOG_NONE) + return; + + FogMode fogMode; + Real newFogStart, newFogEnd, newFogDensity; + + //Check if this is an overlay element if so disable fog + if ((rend->getUseIdentityView() == true) && (rend->getUseIdentityProjection() == true)) + { + fogMode = FOG_NONE; + newFogStart = 100000000; + newFogEnd = 200000000; + newFogDensity = 0; + } + else + { + if (mPassOverrideParams) + { + fogMode = pass->getFogMode(); + newFogStart = pass->getFogStart(); + newFogEnd = pass->getFogEnd(); + newFogDensity = pass->getFogDensity(); + } + else + { + SceneManager* sceneMgr = ShaderGenerator::getSingleton().getActiveSceneManager(); + + fogMode = sceneMgr->getFogMode(); + newFogStart = sceneMgr->getFogStart(); + newFogEnd = sceneMgr->getFogEnd(); + newFogDensity = sceneMgr->getFogDensity(); + } + } + + // Set fog properties. + setFogProperties(fogMode, newFogStart, newFogEnd, newFogDensity); + + mFogParams->setGpuParameter(mFogParamsValue); } //----------------------------------------------------------------------- bool RTShaderSRSTexturedFog::resolveParameters(ProgramSet* programSet) { - if (mFogMode == FOG_NONE) - return true; - - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - - - // Resolve world view matrix. - mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); - if (mWorldMatrix.get() == NULL) - return false; - - // Resolve world view matrix. - mCameraPos = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_CAMERA_POSITION, 0); - if (mCameraPos.get() == NULL) - return false; - - // Resolve vertex shader input position. - mVSInPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); - if (mVSInPos.get() == NULL) - return false; - - // Resolve fog colour. - mFogColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "FogColor", GCT_FLOAT4); - if (mFogColour.get() == NULL) - return false; - - // Resolve pixel shader output diffuse color. - mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); - if (mPSOutDiffuse.get() == NULL) - return false; - - // Resolve fog params. - mFogParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "gFogParams"); - if (mFogParams.get() == NULL) - return false; - - // Resolve vertex shader output depth. - mVSOutPosView = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::SPC_POSITION_VIEW_SPACE, - GCT_FLOAT3); - if (mVSOutPosView.get() == NULL) - return false; - - // Resolve pixel shader input depth. - mPSInPosView = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSOutPosView->getIndex(), - mVSOutPosView->getContent(), - GCT_FLOAT3); - if (mPSInPosView.get() == NULL) - return false; - - // Resolve vertex shader output depth. - mVSOutDepth = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, - Parameter::SPC_DEPTH_VIEW_SPACE, - GCT_FLOAT1); - if (mVSOutDepth.get() == NULL) - return false; - - // Resolve pixel shader input depth. - mPSInDepth = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSOutDepth->getIndex(), - mVSOutDepth->getContent(), - GCT_FLOAT1); - if (mPSInDepth.get() == NULL) - return false; - - // Resolve texture sampler parameter. - mBackgroundTextureSampler = psProgram->resolveParameter(GCT_SAMPLERCUBE, mBackgroundSamplerIndex, (uint16)GPV_GLOBAL, "FogBackgroundSampler"); - if (mBackgroundTextureSampler.get() == NULL) - return false; - - - return true; + if (mFogMode == FOG_NONE) + return true; + + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + + + // Resolve world view matrix. + mWorldMatrix = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_WORLD_MATRIX, 0); + if (mWorldMatrix.get() == NULL) + return false; + + // Resolve world view matrix. + mCameraPos = vsProgram->resolveAutoParameterInt(GpuProgramParameters::ACT_CAMERA_POSITION, 0); + if (mCameraPos.get() == NULL) + return false; + + // Resolve vertex shader input position. + mVSInPos = vsMain->resolveInputParameter(Parameter::SPS_POSITION, 0, Parameter::SPC_POSITION_OBJECT_SPACE, GCT_FLOAT4); + if (mVSInPos.get() == NULL) + return false; + + // Resolve fog colour. + mFogColour = psMain->resolveLocalParameter(Parameter::SPS_UNKNOWN, -1, "FogColor", GCT_FLOAT4); + if (mFogColour.get() == NULL) + return false; + + // Resolve pixel shader output diffuse color. + mPSOutDiffuse = psMain->resolveOutputParameter(Parameter::SPS_COLOR, 0, Parameter::SPC_COLOR_DIFFUSE, GCT_FLOAT4); + if (mPSOutDiffuse.get() == NULL) + return false; + + // Resolve fog params. + mFogParams = psProgram->resolveParameter(GCT_FLOAT4, -1, (uint16)GPV_GLOBAL, "gFogParams"); + if (mFogParams.get() == NULL) + return false; + + // Resolve vertex shader output depth. + mVSOutPosView = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::SPC_POSITION_VIEW_SPACE, + GCT_FLOAT3); + if (mVSOutPosView.get() == NULL) + return false; + + // Resolve pixel shader input depth. + mPSInPosView = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSOutPosView->getIndex(), + mVSOutPosView->getContent(), + GCT_FLOAT3); + if (mPSInPosView.get() == NULL) + return false; + + // Resolve vertex shader output depth. + mVSOutDepth = vsMain->resolveOutputParameter(Parameter::SPS_TEXTURE_COORDINATES, -1, + Parameter::SPC_DEPTH_VIEW_SPACE, + GCT_FLOAT1); + if (mVSOutDepth.get() == NULL) + return false; + + // Resolve pixel shader input depth. + mPSInDepth = psMain->resolveInputParameter(Parameter::SPS_TEXTURE_COORDINATES, mVSOutDepth->getIndex(), + mVSOutDepth->getContent(), + GCT_FLOAT1); + if (mPSInDepth.get() == NULL) + return false; + + // Resolve texture sampler parameter. + mBackgroundTextureSampler = psProgram->resolveParameter(GCT_SAMPLERCUBE, mBackgroundSamplerIndex, (uint16)GPV_GLOBAL, "FogBackgroundSampler"); + if (mBackgroundTextureSampler.get() == NULL) + return false; + + + return true; } //----------------------------------------------------------------------- bool RTShaderSRSTexturedFog::resolveDependencies(ProgramSet* programSet) { - if (mFogMode == FOG_NONE) - return true; + if (mFogMode == FOG_NONE) + return true; - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); - vsProgram->addDependency(FFP_LIB_FOG); - psProgram->addDependency(FFP_LIB_COMMON); + vsProgram->addDependency(FFP_LIB_FOG); + psProgram->addDependency(FFP_LIB_COMMON); - psProgram->addDependency(FFP_LIB_FOG); - psProgram->addDependency(FFP_LIB_TEXTURING); - - return true; + psProgram->addDependency(FFP_LIB_FOG); + psProgram->addDependency(FFP_LIB_TEXTURING); + + return true; } //----------------------------------------------------------------------- bool RTShaderSRSTexturedFog::addFunctionInvocations(ProgramSet* programSet) { - if (mFogMode == FOG_NONE) - return true; - - Program* vsProgram = programSet->getCpuVertexProgram(); - Program* psProgram = programSet->getCpuFragmentProgram(); - Function* vsMain = vsProgram->getEntryPointFunction(); - Function* psMain = psProgram->getEntryPointFunction(); - FunctionInvocation* curFuncInvocation = NULL; - int internalCounter; - - internalCounter = 0; - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_POSITION_DEPTH, FFP_VS_FOG, internalCounter++); - curFuncInvocation->pushOperand(mWorldMatrix, Operand::OPS_IN); - curFuncInvocation->pushOperand(mCameraPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); - curFuncInvocation->pushOperand(mVSOutPosView, Operand::OPS_OUT); - curFuncInvocation->pushOperand(mVSOutDepth, Operand::OPS_OUT); - vsMain->addAtomInstance(curFuncInvocation); - - internalCounter = 0; - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE, FFP_PS_FOG, internalCounter++); - curFuncInvocation->pushOperand(mBackgroundTextureSampler, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSInPosView, Operand::OPS_IN); - curFuncInvocation->pushOperand(mFogColour, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - - - switch (mFogMode) - { - case FOG_LINEAR: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_LINEAR, FFP_PS_FOG, internalCounter++); - break; - case FOG_EXP: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP, FFP_PS_FOG, internalCounter++); - break; - case FOG_EXP2: - curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP2, FFP_PS_FOG, internalCounter++); - break; + if (mFogMode == FOG_NONE) + return true; + + Program* vsProgram = programSet->getCpuVertexProgram(); + Program* psProgram = programSet->getCpuFragmentProgram(); + Function* vsMain = vsProgram->getEntryPointFunction(); + Function* psMain = psProgram->getEntryPointFunction(); + FunctionInvocation* curFuncInvocation = NULL; + int internalCounter; + + internalCounter = 0; + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_POSITION_DEPTH, FFP_VS_FOG, internalCounter++); + curFuncInvocation->pushOperand(mWorldMatrix, Operand::OPS_IN); + curFuncInvocation->pushOperand(mCameraPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSInPos, Operand::OPS_IN); + curFuncInvocation->pushOperand(mVSOutPosView, Operand::OPS_OUT); + curFuncInvocation->pushOperand(mVSOutDepth, Operand::OPS_OUT); + vsMain->addAtomInstance(curFuncInvocation); + + internalCounter = 0; + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_SAMPLE_TEXTURE, FFP_PS_FOG, internalCounter++); + curFuncInvocation->pushOperand(mBackgroundTextureSampler, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSInPosView, Operand::OPS_IN); + curFuncInvocation->pushOperand(mFogColour, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + + + switch (mFogMode) + { + case FOG_LINEAR: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_LINEAR, FFP_PS_FOG, internalCounter++); + break; + case FOG_EXP: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP, FFP_PS_FOG, internalCounter++); + break; + case FOG_EXP2: + curFuncInvocation = OGRE_NEW FunctionInvocation(FFP_FUNC_PIXELFOG_EXP2, FFP_PS_FOG, internalCounter++); + break; case FOG_NONE: default: break; - } - - curFuncInvocation->pushOperand(mPSInDepth, Operand::OPS_IN); - curFuncInvocation->pushOperand(mFogParams, Operand::OPS_IN); - curFuncInvocation->pushOperand(mFogColour, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); - curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); - psMain->addAtomInstance(curFuncInvocation); - return true; + } + + curFuncInvocation->pushOperand(mPSInDepth, Operand::OPS_IN); + curFuncInvocation->pushOperand(mFogParams, Operand::OPS_IN); + curFuncInvocation->pushOperand(mFogColour, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_IN); + curFuncInvocation->pushOperand(mPSOutDiffuse, Operand::OPS_OUT); + psMain->addAtomInstance(curFuncInvocation); + return true; } //----------------------------------------------------------------------- void RTShaderSRSTexturedFog::copyFrom(const SubRenderState& rhs) { - const RTShaderSRSTexturedFog& rhsFog = static_cast(rhs); + const RTShaderSRSTexturedFog& rhsFog = static_cast(rhs); - mFogMode = rhsFog.mFogMode; - mFogParamsValue = rhsFog.mFogParamsValue; - mFactory = rhsFog.mFactory; + mFogMode = rhsFog.mFogMode; + mFogParamsValue = rhsFog.mFogParamsValue; + mFactory = rhsFog.mFactory; } //----------------------------------------------------------------------- bool RTShaderSRSTexturedFog::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) -{ - if (mFactory == NULL) - return false; - - FogMode fogMode; - ColourValue newFogColour; - Real newFogStart, newFogEnd, newFogDensity; - - if (srcPass->getFogOverride()) - { - fogMode = srcPass->getFogMode(); - newFogStart = srcPass->getFogStart(); - newFogEnd = srcPass->getFogEnd(); - newFogDensity = srcPass->getFogDensity(); - mPassOverrideParams = true; - } - else - { - SceneManager* sceneMgr = ShaderGenerator::getSingleton().getActiveSceneManager(); - - if (sceneMgr == NULL) - { - fogMode = FOG_NONE; - newFogStart = 0.0; - newFogEnd = 0.0; - newFogDensity = 0.0; - } - else - { - fogMode = sceneMgr->getFogMode(); - newFogStart = sceneMgr->getFogStart(); - newFogEnd = sceneMgr->getFogEnd(); - newFogDensity = sceneMgr->getFogDensity(); - } - mPassOverrideParams = false; - } - - // Set fog properties. - setFogProperties(fogMode, newFogStart, newFogEnd, newFogDensity); - - - // Override scene fog since it will happen in shader. - dstPass->setFog(true, FOG_NONE, ColourValue::White, newFogDensity, newFogStart, newFogEnd); - - TextureUnitState* tus = dstPass->createTextureUnitState(mFactory->getBackgroundTextureName()); - tus->setCubicTextureName(mFactory->getBackgroundTextureName(), true); - mBackgroundSamplerIndex = dstPass->getNumTextureUnitStates() - 1; - - return true; +{ + if (mFactory == NULL) + return false; + + FogMode fogMode; + ColourValue newFogColour; + Real newFogStart, newFogEnd, newFogDensity; + + if (srcPass->getFogOverride()) + { + fogMode = srcPass->getFogMode(); + newFogStart = srcPass->getFogStart(); + newFogEnd = srcPass->getFogEnd(); + newFogDensity = srcPass->getFogDensity(); + mPassOverrideParams = true; + } + else + { + SceneManager* sceneMgr = ShaderGenerator::getSingleton().getActiveSceneManager(); + + if (sceneMgr == NULL) + { + fogMode = FOG_NONE; + newFogStart = 0.0; + newFogEnd = 0.0; + newFogDensity = 0.0; + } + else + { + fogMode = sceneMgr->getFogMode(); + newFogStart = sceneMgr->getFogStart(); + newFogEnd = sceneMgr->getFogEnd(); + newFogDensity = sceneMgr->getFogDensity(); + } + mPassOverrideParams = false; + } + + // Set fog properties. + setFogProperties(fogMode, newFogStart, newFogEnd, newFogDensity); + + + // Override scene fog since it will happen in shader. + dstPass->setFog(true, FOG_NONE, ColourValue::White, newFogDensity, newFogStart, newFogEnd); + + TextureUnitState* tus = dstPass->createTextureUnitState(mFactory->getBackgroundTextureName()); + tus->setCubicTextureName(mFactory->getBackgroundTextureName(), true); + mBackgroundSamplerIndex = dstPass->getNumTextureUnitStates() - 1; + + return true; } //----------------------------------------------------------------------- void RTShaderSRSTexturedFog::setFogProperties(FogMode fogMode, - float fogStart, - float fogEnd, - float fogDensity) + float fogStart, + float fogEnd, + float fogDensity) { - mFogMode = fogMode; - mFogParamsValue.x = fogDensity; - mFogParamsValue.y = fogStart; - mFogParamsValue.z = fogEnd; - mFogParamsValue.w = fogEnd != fogStart ? 1 / (fogEnd - fogStart) : 0; + mFogMode = fogMode; + mFogParamsValue.x = fogDensity; + mFogParamsValue.y = fogStart; + mFogParamsValue.z = fogEnd; + mFogParamsValue.w = fogEnd != fogStart ? 1 / (fogEnd - fogStart) : 0; } //----------------------------------------------------------------------- const String& RTShaderSRSTexturedFogFactory::getType() const { - return RTShaderSRSTexturedFog::Type; + return RTShaderSRSTexturedFog::Type; } //----------------------------------------------------------------------- -SubRenderState* RTShaderSRSTexturedFogFactory::createInstanceImpl() +SubRenderState* RTShaderSRSTexturedFogFactory::createInstanceImpl() { - return OGRE_NEW RTShaderSRSTexturedFog(this); + return OGRE_NEW RTShaderSRSTexturedFog(this); } diff --git a/Samples/ShaderSystemTexturedFog/src/ShaderSystemTexturedFog.cpp b/Samples/ShaderSystemTexturedFog/src/ShaderSystemTexturedFog.cpp index 426b63c947a..4f61859895c 100644 --- a/Samples/ShaderSystemTexturedFog/src/ShaderSystemTexturedFog.cpp +++ b/Samples/ShaderSystemTexturedFog/src/ShaderSystemTexturedFog.cpp @@ -11,17 +11,17 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_ShaderSystemTexturedFog; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_ShaderSystemTexturedFog; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Shadows/include/Shadows.h b/Samples/Shadows/include/Shadows.h index 3cd25176ff6..4ce7cec1662 100644 --- a/Samples/Shadows/include/Shadows.h +++ b/Samples/Shadows/include/Shadows.h @@ -61,7 +61,7 @@ class LightWibbler : public ControllerValue mColourRange.b = maxColour.b - minColour.b; mMinSize = minSize; mSizeRange = maxSize - minSize; - + } virtual Real getValue (void) const @@ -95,125 +95,125 @@ Real timeDelay = 0; class _OgreSampleClassExport Sample_Shadows : public SdkSample { protected: - Entity* mAthene; - AnimationState* mAnimState; - Entity* pPlaneEnt; - vector::type pColumns; - Light* mLight; - Light* mSunLight; - SceneNode* mLightNode; - AnimationState* mLightAnimationState; - ColourValue mMinLightColour; - ColourValue mMaxLightColour; - Real mMinFlareSize; - Real mMaxFlareSize; - Controller* mController; - - enum ShadowProjection - { - UNIFORM, - UNIFORM_FOCUSED, - LISPSM, - PLANE_OPTIMAL - }; - - enum ShadowMaterial - { - MAT_STANDARD, - MAT_DEPTH_FLOAT, - MAT_DEPTH_FLOAT_PCF - }; - - ShadowTechnique mCurrentShadowTechnique; - ShadowProjection mCurrentProjection; - ShadowMaterial mCurrentMaterial; - - GpuProgramParametersSharedPtr mCustomRockwallVparams; - GpuProgramParametersSharedPtr mCustomRockwallFparams; - GpuProgramParametersSharedPtr mCustomAtheneVparams; - GpuProgramParametersSharedPtr mCustomAtheneFparams; - - ShadowCameraSetupPtr mCurrentShadowCameraSetup; - /// Plane that defines plane-optimal shadow mapping basis - MovablePlane* mPlane; - // transient pointer to LiSPSM setup if present - LiSPSMShadowCameraSetup* mLiSPSMSetup; - - bool mIsOpenGL; + Entity* mAthene; + AnimationState* mAnimState; + Entity* pPlaneEnt; + vector::type pColumns; + Light* mLight; + Light* mSunLight; + SceneNode* mLightNode; + AnimationState* mLightAnimationState; + ColourValue mMinLightColour; + ColourValue mMaxLightColour; + Real mMinFlareSize; + Real mMaxFlareSize; + Controller* mController; + + enum ShadowProjection + { + UNIFORM, + UNIFORM_FOCUSED, + LISPSM, + PLANE_OPTIMAL + }; + + enum ShadowMaterial + { + MAT_STANDARD, + MAT_DEPTH_FLOAT, + MAT_DEPTH_FLOAT_PCF + }; + + ShadowTechnique mCurrentShadowTechnique; + ShadowProjection mCurrentProjection; + ShadowMaterial mCurrentMaterial; + + GpuProgramParametersSharedPtr mCustomRockwallVparams; + GpuProgramParametersSharedPtr mCustomRockwallFparams; + GpuProgramParametersSharedPtr mCustomAtheneVparams; + GpuProgramParametersSharedPtr mCustomAtheneFparams; + + ShadowCameraSetupPtr mCurrentShadowCameraSetup; + /// Plane that defines plane-optimal shadow mapping basis + MovablePlane* mPlane; + // transient pointer to LiSPSM setup if present + LiSPSMShadowCameraSetup* mLiSPSMSetup; + + bool mIsOpenGL; public: - bool frameEnded(const FrameEvent& evt) + bool frameEnded(const FrameEvent& evt) + { + if (mAnimState) + mAnimState->addTime(evt.timeSinceLastFrame); + return SdkSample::frameEnded(evt); + } + + Sample_Shadows() + : mAnimState(0) + , mLightNode(0) + , mLightAnimationState(0) + , mMinLightColour(0.2, 0.1, 0.0) + , mMaxLightColour(0.5, 0.3, 0.1) + , mMinFlareSize(40) + , mMaxFlareSize(80) + , mController(0) + , mPlane(0) { - if (mAnimState) - mAnimState->addTime(evt.timeSinceLastFrame); - return SdkSample::frameEnded(evt); - } - - Sample_Shadows() - : mAnimState(0) - , mLightNode(0) - , mLightAnimationState(0) - , mMinLightColour(0.2, 0.1, 0.0) - , mMaxLightColour(0.5, 0.3, 0.1) - , mMinFlareSize(40) - , mMaxFlareSize(80) - , mController(0) - , mPlane(0) - { - mInfo["Title"] = "Shadows"; - mInfo["Description"] = "A demonstration of ogre's various shadowing techniques."; - mInfo["Thumbnail"] = "thumb_shadows.png"; - mInfo["Category"] = "Lighting"; + mInfo["Title"] = "Shadows"; + mInfo["Description"] = "A demonstration of ogre's various shadowing techniques."; + mInfo["Thumbnail"] = "thumb_shadows.png"; + mInfo["Category"] = "Lighting"; } protected: - // Override this to ensure FPU mode - //bool configure(void) - //{ - // // Show the configuration dialog and initialise the system - // // You can skip this and use root.restoreConfig() to load configuration - // // settings if you were sure there are valid ones saved in ogre.cfg - // if(mRoot->showConfigDialog()) - // { - // // Custom option - to use PlaneOptimalShadowCameraSetup we must have - // // double-precision. Thus, set the D3D floating point mode if present, - // // no matter what was chosen - // ConfigOptionMap& optMap = mRoot->getRenderSystem()->getConfigOptions(); - // ConfigOptionMap::iterator i = optMap.find("Floating-point mode"); - // if (i != optMap.end()) - // { - // if (i->second.currentValue != "Consistent") - // { - // i->second.currentValue = "Consistent"; - // LogManager::getSingleton().logMessage("Demo_Shadows: overriding " - // "D3D floating point mode to 'Consistent' to ensure precision " - // "for plane-optimal camera setup option"); - - // } - // } - - // // If returned true, user clicked OK so initialise - // // Here we choose to let the system create a default rendering window by passing 'true' - // mWindow = mRoot->initialise(true); - // return true; - // } - // else - // { - // return false; - // } - //} - + // Override this to ensure FPU mode + //bool configure(void) + //{ + // // Show the configuration dialog and initialise the system + // // You can skip this and use root.restoreConfig() to load configuration + // // settings if you were sure there are valid ones saved in ogre.cfg + // if(mRoot->showConfigDialog()) + // { + // // Custom option - to use PlaneOptimalShadowCameraSetup we must have + // // double-precision. Thus, set the D3D floating point mode if present, + // // no matter what was chosen + // ConfigOptionMap& optMap = mRoot->getRenderSystem()->getConfigOptions(); + // ConfigOptionMap::iterator i = optMap.find("Floating-point mode"); + // if (i != optMap.end()) + // { + // if (i->second.currentValue != "Consistent") + // { + // i->second.currentValue = "Consistent"; + // LogManager::getSingleton().logMessage("Demo_Shadows: overriding " + // "D3D floating point mode to 'Consistent' to ensure precision " + // "for plane-optimal camera setup option"); + + // } + // } + + // // If returned true, user clicked OK so initialise + // // Here we choose to let the system create a default rendering window by passing 'true' + // mWindow = mRoot->initialise(true); + // return true; + // } + // else + // { + // return false; + // } + //} + // Just override the mandatory create scene method void setupContent(void) { - // Need to detect D3D or GL for best depth shadowmapping - mIsOpenGL = Root::getSingleton().getRenderSystem()->getName().find("GL") != String::npos; + // Need to detect D3D or GL for best depth shadowmapping + mIsOpenGL = Root::getSingleton().getRenderSystem()->getName().find("GL") != String::npos; - // do this first so we generate edge lists - if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_HWSTENCIL)) + // do this first so we generate edge lists + if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_HWSTENCIL)) { mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE); mCurrentShadowTechnique = SHADOWTYPE_STENCIL_ADDITIVE; @@ -264,7 +264,7 @@ class _OgreSampleClassExport Sample_Shadows : public SdkSample mMinFlareSize, mMaxFlareSize)); mController = contMgr.createController( contMgr.getFrameTimeSource(), val, func); - + //mLight->setPosition(Vector3(300,250,-300)); mLightNode->setPosition(Vector3(300,1750,-700)); @@ -323,33 +323,33 @@ class _OgreSampleClassExport Sample_Shadows : public SdkSample node->yaw(Degree(90)); Entity* pEnt; - // Columns - for (int x = -2; x <= 2; ++x) - { - for (int z = -2; z <= 2; ++z) - { - if (x != 0 || z != 0) - { - StringStream str; - str << "col" << x << "_" << z; - node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - pEnt = mSceneMgr->createEntity( str.str(), "column.mesh" ); - pEnt->setMaterialName(BASIC_ROCKWALL_MATERIAL); - pColumns.push_back(pEnt); - node->attachObject( pEnt ); - node->translate(x*300,0, z*300); - - } - } - - } + // Columns + for (int x = -2; x <= 2; ++x) + { + for (int z = -2; z <= 2; ++z) + { + if (x != 0 || z != 0) + { + StringStream str; + str << "col" << x << "_" << z; + node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + pEnt = mSceneMgr->createEntity( str.str(), "column.mesh" ); + pEnt->setMaterialName(BASIC_ROCKWALL_MATERIAL); + pColumns.push_back(pEnt); + node->attachObject( pEnt ); + node->translate(x*300,0, z*300); + + } + } + + } // Skybox mSceneMgr->setSkyBox(true, "Examples/StormySkyBox"); // Floor plane (use POSM plane def) - mPlane = new MovablePlane("*mPlane"); + mPlane = new MovablePlane("*mPlane"); mPlane->normal = Vector3::UNIT_Y; mPlane->d = 107; MeshManager::getSingleton().createPlane("Myplane", @@ -360,7 +360,7 @@ class _OgreSampleClassExport Sample_Shadows : public SdkSample pPlaneEnt->setCastShadows(false); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); - if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_HWRENDER_TO_TEXTURE)) + if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_HWRENDER_TO_TEXTURE)) { // In D3D, use a 1024x1024 shadow texture mSceneMgr->setShadowTextureSettings(1024, 2); @@ -374,458 +374,458 @@ class _OgreSampleClassExport Sample_Shadows : public SdkSample mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5)); //mSceneMgr->setShowDebugShadows(true); - setupGUI(); + setupGUI(); #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS - setDragLook(true); + setDragLook(true); #endif } - virtual void setupView() - { - SdkSample::setupView(); + virtual void setupView() + { + SdkSample::setupView(); // incase infinite far distance is not supported mCamera->setFarClipDistance(100000); - mCamera->setPosition(250, 20, 400); - mCamera->lookAt(0, 10, 0); - } - - virtual void cleanupContent() - { - ControllerManager::getSingleton().destroyController(mController); - - MeshManager::getSingleton().remove("Myplane"); - - pColumns.clear(); - } - - /// Change basic shadow technique - void changeShadowTechnique(ShadowTechnique newTech) - { - mSceneMgr->setShadowTechnique(newTech); - - // Below is for projection - //configureShadowCameras(mCurrentShadowTechnique, newTech); - - configureLights(newTech); - - // Advanced modes - materials / compositors - //configureCompositors(mCurrentShadowTechnique, newTech); - //configureTextures(mCurrentShadowTechnique, newTech); - //configureShadowCasterReceiverMaterials(mCurrentShadowTechnique, newTech); - - updateGUI(newTech); - - mCurrentShadowTechnique = newTech; - } - - void configureLights(ShadowTechnique newTech) - { - Vector3 dir; - switch (newTech) - { - case SHADOWTYPE_STENCIL_ADDITIVE: - // Fixed light, dim - mSunLight->setCastShadows(true); - - // Point light, movable, reddish - mLight->setType(Light::LT_POINT); - mLight->setCastShadows(true); - mLight->setDiffuseColour(mMinLightColour); - mLight->setSpecularColour(1, 1, 1); - mLight->setAttenuation(8000,1,0.0005,0); - - break; - case SHADOWTYPE_STENCIL_MODULATIVE: - // Multiple lights cause obvious silhouette edges in modulative mode - // So turn off shadows on the direct light - // Fixed light, dim - mSunLight->setCastShadows(false); - - // Point light, movable, reddish - mLight->setType(Light::LT_POINT); - mLight->setCastShadows(true); - mLight->setDiffuseColour(mMinLightColour); - mLight->setSpecularColour(1, 1, 1); - mLight->setAttenuation(8000,1,0.0005,0); - break; - case SHADOWTYPE_TEXTURE_MODULATIVE: - case SHADOWTYPE_TEXTURE_ADDITIVE: - // Fixed light, dim - mSunLight->setCastShadows(true); - - // Change moving light to spotlight - // Point light, movable, reddish - mLight->setType(Light::LT_SPOTLIGHT); - mLight->setDirection(Vector3::NEGATIVE_UNIT_Z); - mLight->setCastShadows(true); - mLight->setDiffuseColour(mMinLightColour); - mLight->setSpecularColour(1, 1, 1); - mLight->setAttenuation(8000,1,0.0005,0); - mLight->setSpotlightRange(Degree(80),Degree(90)); - - - break; - default: - break; - }; - - } - - SelectMenu* mTechniqueMenu; - SelectMenu* mLightingMenu; - SelectMenu* mProjectionMenu; - SelectMenu* mMaterialMenu; - - Slider* mFixedBiasSlider; - Slider* mSlopedBiasSlider; - Slider* mClampSlider; - - void setupGUI() - { - mTechniqueMenu = mTrayMgr->createLongSelectMenu( - TL_TOPLEFT, "TechniqueSelectMenu", "Technique", 300, 200, 5); - mTechniqueMenu->addItem("Stencil"); - mTechniqueMenu->addItem("Texture"); + mCamera->setPosition(250, 20, 400); + mCamera->lookAt(0, 10, 0); + } + + virtual void cleanupContent() + { + ControllerManager::getSingleton().destroyController(mController); + + MeshManager::getSingleton().remove("Myplane"); + + pColumns.clear(); + } + + /// Change basic shadow technique + void changeShadowTechnique(ShadowTechnique newTech) + { + mSceneMgr->setShadowTechnique(newTech); + + // Below is for projection + //configureShadowCameras(mCurrentShadowTechnique, newTech); + + configureLights(newTech); + + // Advanced modes - materials / compositors + //configureCompositors(mCurrentShadowTechnique, newTech); + //configureTextures(mCurrentShadowTechnique, newTech); + //configureShadowCasterReceiverMaterials(mCurrentShadowTechnique, newTech); + + updateGUI(newTech); + + mCurrentShadowTechnique = newTech; + } + + void configureLights(ShadowTechnique newTech) + { + Vector3 dir; + switch (newTech) + { + case SHADOWTYPE_STENCIL_ADDITIVE: + // Fixed light, dim + mSunLight->setCastShadows(true); + + // Point light, movable, reddish + mLight->setType(Light::LT_POINT); + mLight->setCastShadows(true); + mLight->setDiffuseColour(mMinLightColour); + mLight->setSpecularColour(1, 1, 1); + mLight->setAttenuation(8000,1,0.0005,0); + + break; + case SHADOWTYPE_STENCIL_MODULATIVE: + // Multiple lights cause obvious silhouette edges in modulative mode + // So turn off shadows on the direct light + // Fixed light, dim + mSunLight->setCastShadows(false); + + // Point light, movable, reddish + mLight->setType(Light::LT_POINT); + mLight->setCastShadows(true); + mLight->setDiffuseColour(mMinLightColour); + mLight->setSpecularColour(1, 1, 1); + mLight->setAttenuation(8000,1,0.0005,0); + break; + case SHADOWTYPE_TEXTURE_MODULATIVE: + case SHADOWTYPE_TEXTURE_ADDITIVE: + // Fixed light, dim + mSunLight->setCastShadows(true); + + // Change moving light to spotlight + // Point light, movable, reddish + mLight->setType(Light::LT_SPOTLIGHT); + mLight->setDirection(Vector3::NEGATIVE_UNIT_Z); + mLight->setCastShadows(true); + mLight->setDiffuseColour(mMinLightColour); + mLight->setSpecularColour(1, 1, 1); + mLight->setAttenuation(8000,1,0.0005,0); + mLight->setSpotlightRange(Degree(80),Degree(90)); + + + break; + default: + break; + }; + + } + + SelectMenu* mTechniqueMenu; + SelectMenu* mLightingMenu; + SelectMenu* mProjectionMenu; + SelectMenu* mMaterialMenu; + + Slider* mFixedBiasSlider; + Slider* mSlopedBiasSlider; + Slider* mClampSlider; + + void setupGUI() + { + mTechniqueMenu = mTrayMgr->createLongSelectMenu( + TL_TOPLEFT, "TechniqueSelectMenu", "Technique", 300, 200, 5); + mTechniqueMenu->addItem("Stencil"); + mTechniqueMenu->addItem("Texture"); if(mCurrentShadowTechnique & SHADOWDETAILTYPE_STENCIL) mTechniqueMenu->selectItem("Stencil", false); else mTechniqueMenu->selectItem("Texture", false); - mLightingMenu = mTrayMgr->createLongSelectMenu( - TL_TOPLEFT, "LightingSelectMenu", "Lighting", 300, 200, 5); - mLightingMenu->addItem("Additive"); - mLightingMenu->addItem("Modulative"); + mLightingMenu = mTrayMgr->createLongSelectMenu( + TL_TOPLEFT, "LightingSelectMenu", "Lighting", 300, 200, 5); + mLightingMenu->addItem("Additive"); + mLightingMenu->addItem("Modulative"); if(mCurrentShadowTechnique & SHADOWTYPE_STENCIL_ADDITIVE) mLightingMenu->selectItem("Additive", false); else mLightingMenu->selectItem("Modulative", false); - //These values are synchronized with ShadowProjection enum - mProjectionMenu = mTrayMgr->createLongSelectMenu( - TL_TOPLEFT, "ProjectionSelectMenu", "Projection", 300, 200, 5); - mProjectionMenu->addItem("Uniform"); - mProjectionMenu->addItem("Uniform Focused"); - mProjectionMenu->addItem("LiSPSM"); - mProjectionMenu->addItem("Plane Optimal"); - - mMaterialMenu = mTrayMgr->createLongSelectMenu( - TL_TOPLEFT, "MaterialSelectMenu", "Material", 300, 200, 5); - mMaterialMenu->addItem("Standard"); - mMaterialMenu->addItem("Depth Shadowmap"); - mMaterialMenu->addItem("Depth Shadowmap (PCF)"); - - mFixedBiasSlider = mTrayMgr->createThickSlider(TL_NONE, "FixedBiasSlider", "Fixed Bias", 256, 80, 0, 0.02, 100); - mFixedBiasSlider->setValue(0.0009, false); - mFixedBiasSlider->hide(); - - mSlopedBiasSlider = mTrayMgr->createThickSlider(TL_NONE, "SlopedBiasSlider", "Sloped Bias", 256, 80, 0, 0.2, 100); - mSlopedBiasSlider->setValue(0.0008, false); - mSlopedBiasSlider->hide(); - - mClampSlider = mTrayMgr->createThickSlider(TL_NONE, "SlopeClampSlider", "Slope Clamp", 256, 80, 0, 2, 100); - mClampSlider->setValue(0.2, false); - mClampSlider->hide(); - - updateGUI(mCurrentShadowTechnique); - mTrayMgr->showCursor(); - } - - void updateGUI(ShadowTechnique newTech) - { - bool isTextureBased = (newTech & SHADOWDETAILTYPE_TEXTURE) != 0; - - if (isTextureBased) - { - mProjectionMenu->show(); - mTrayMgr->moveWidgetToTray(mProjectionMenu, TL_TOPLEFT); - mMaterialMenu->show(); - mTrayMgr->moveWidgetToTray(mMaterialMenu, TL_TOPLEFT); - } - else - { - mProjectionMenu->hide(); - mTrayMgr->removeWidgetFromTray(mProjectionMenu); - mMaterialMenu->hide(); - mTrayMgr->removeWidgetFromTray(mMaterialMenu); - } - } - - void itemSelected(SelectMenu* menu) - { - if (menu == mTechniqueMenu) handleShadowTypeChanged(); - else if (menu == mLightingMenu) handleShadowTypeChanged(); - else if (menu == mProjectionMenu) handleProjectionChanged(); - else if (menu == mMaterialMenu) handleMaterialChanged(); - } - - - void handleShadowTypeChanged() - { - bool isStencil = mTechniqueMenu->getSelectionIndex() == 0; - bool isAdditive = mLightingMenu->getSelectionIndex() == 0; - ShadowTechnique newTech = mCurrentShadowTechnique; - - if (isStencil) - { - newTech = static_cast( - (newTech & ~SHADOWDETAILTYPE_TEXTURE) | SHADOWDETAILTYPE_STENCIL); - resetMaterials(); - } - else - { - newTech = static_cast( - (newTech & ~SHADOWDETAILTYPE_STENCIL) | SHADOWDETAILTYPE_TEXTURE); - } - - if (isAdditive) - { - newTech = static_cast( - (newTech & ~SHADOWDETAILTYPE_MODULATIVE) | SHADOWDETAILTYPE_ADDITIVE); - } - else - { - newTech = static_cast( - (newTech & ~SHADOWDETAILTYPE_ADDITIVE) | SHADOWDETAILTYPE_MODULATIVE); - } - - changeShadowTechnique(newTech); - } - - void handleProjectionChanged() - { - ShadowProjection proj = (ShadowProjection)mProjectionMenu->getSelectionIndex(); - - if (proj != mCurrentProjection) - { - switch(proj) - { - case UNIFORM: - mCurrentShadowCameraSetup = - ShadowCameraSetupPtr(new DefaultShadowCameraSetup()); - break; - case UNIFORM_FOCUSED: - mCurrentShadowCameraSetup = - ShadowCameraSetupPtr(new FocusedShadowCameraSetup()); - break; - case LISPSM: - { - mLiSPSMSetup = new LiSPSMShadowCameraSetup(); - //mLiSPSMSetup->setUseAggressiveFocusRegion(false); - mCurrentShadowCameraSetup = ShadowCameraSetupPtr(mLiSPSMSetup); - } - break; - case PLANE_OPTIMAL: - mCurrentShadowCameraSetup = - ShadowCameraSetupPtr(new PlaneOptimalShadowCameraSetup(mPlane)); - break; - - }; - mCurrentProjection = proj; - - mSceneMgr->setShadowCameraSetup(mCurrentShadowCameraSetup); - - //updateTipForCombo(cbo); - if (!mCustomRockwallVparams.isNull() && !mCustomRockwallFparams.isNull()) - { - // set - setDefaultDepthShadowParams(); - } - - } - } - - void updateDepthShadowParams() - { - mCustomRockwallFparams->setNamedConstant("fixedDepthBias", - mFixedBiasSlider->getValue()); - mCustomRockwallFparams->setNamedConstant("gradientScaleBias", - mSlopedBiasSlider->getValue()); - mCustomRockwallFparams->setNamedConstant("gradientClamp", - mClampSlider->getValue()); - - mCustomAtheneFparams->setNamedConstant("fixedDepthBias", - mFixedBiasSlider->getValue()); - mCustomAtheneFparams->setNamedConstant("gradientScaleBias", - mSlopedBiasSlider->getValue()); - mCustomAtheneFparams->setNamedConstant("gradientClamp", - mClampSlider->getValue()); - } - - void setDefaultDepthShadowParams() - { - switch(mCurrentProjection) - { - case UNIFORM: - case UNIFORM_FOCUSED: - case PLANE_OPTIMAL: - mFixedBiasSlider->setValue(0.0f, false); - mSlopedBiasSlider->setValue(0.0f, false); - break; - case LISPSM: - mFixedBiasSlider->setValue(0.009f, false); - mSlopedBiasSlider->setValue(0.04f, false); - break; - }; - - updateDepthShadowParams(); - - } - - void sliderMoved(Slider* slider) - { - if (!mCustomRockwallVparams.isNull() && !mCustomRockwallFparams.isNull()) - { - updateDepthShadowParams(); - } - } - - void rebindDebugShadowOverlays() - { - /*MaterialPtr debugMat = - MaterialManager::getSingleton().getByName("Ogre/DebugShadowMap0"); - TexturePtr shadowTex = mSceneMgr->getShadowTexture(0); - debugMat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(shadowTex->getName()); - - debugMat = - MaterialManager::getSingleton().getByName("Ogre/DebugShadowMap1"); - shadowTex = mSceneMgr->getShadowTexture(1); - debugMat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(shadowTex->getName());*/ - } - - void resetMaterials() - { - // Sort out base materials - pPlaneEnt->setMaterialName(BASIC_ROCKWALL_MATERIAL); - mAthene->setMaterialName(BASIC_ATHENE_MATERIAL); - for (vector::type::iterator i = pColumns.begin(); - i != pColumns.end(); ++i) - { - (*i)->setMaterialName(BASIC_ROCKWALL_MATERIAL); - } - - mCustomRockwallVparams.setNull(); - mCustomRockwallFparams.setNull(); - mCustomAtheneVparams.setNull(); - mCustomAtheneFparams.setNull(); - - } - - void handleMaterialChanged() - { - bool showSliders = false; - ShadowMaterial mat = (ShadowMaterial)mMaterialMenu->getSelectionIndex(); - MaterialPtr themat; - if (mat != mCurrentMaterial) - { - switch(mat) - { - case MAT_STANDARD: - mSceneMgr->setShadowTexturePixelFormat(PF_X8R8G8B8); - mSceneMgr->setShadowTextureCasterMaterial(BLANKSTRING); - mSceneMgr->setShadowTextureReceiverMaterial(BLANKSTRING); - mSceneMgr->setShadowTextureSelfShadow(false); - - resetMaterials(); - - break; - case MAT_DEPTH_FLOAT: - //if (mIsOpenGL) - //{ - // // GL performs much better if you pick half-float format - // mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT16_R); - //} - //else - { - // D3D is the opposite - if you ask for PF_FLOAT16_R you - // get an integer format instead! You can ask for PF_FLOAT16_GR - // but the precision doesn't work well - mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R); - } - mSceneMgr->setShadowTextureCasterMaterial(CUSTOM_CASTER_MATERIAL); - mSceneMgr->setShadowTextureReceiverMaterial(CUSTOM_RECEIVER_MATERIAL); - mSceneMgr->setShadowTextureSelfShadow(true); - // Sort out base materials - pPlaneEnt->setMaterialName(CUSTOM_ROCKWALL_MATERIAL); - mAthene->setMaterialName(CUSTOM_ATHENE_MATERIAL); - for (vector::type::iterator i = pColumns.begin(); - i != pColumns.end(); ++i) - { - (*i)->setMaterialName(CUSTOM_ROCKWALL_MATERIAL); - } - - themat = MaterialManager::getSingleton().getByName(CUSTOM_ROCKWALL_MATERIAL); - mCustomRockwallVparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverVertexProgramParameters(); - mCustomRockwallFparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverFragmentProgramParameters(); - themat = MaterialManager::getSingleton().getByName(CUSTOM_ATHENE_MATERIAL); - mCustomAtheneVparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverVertexProgramParameters(); - mCustomAtheneFparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverFragmentProgramParameters(); - showSliders = true; - - - // set the current params - setDefaultDepthShadowParams(); - break; - case MAT_DEPTH_FLOAT_PCF: - //if (mIsOpenGL) - //{ - // // GL performs much better if you pick half-float format - // mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT16_R); - //} - //else - { - // D3D is the opposite - if you ask for PF_FLOAT16_R you - // get an integer format instead! You can ask for PF_FLOAT16_GR - // but the precision doesn't work well - mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R); - } - mSceneMgr->setShadowTextureCasterMaterial(CUSTOM_CASTER_MATERIAL); - mSceneMgr->setShadowTextureReceiverMaterial(CUSTOM_RECEIVER_MATERIAL + "/PCF"); - mSceneMgr->setShadowTextureSelfShadow(true); - // Sort out base materials - pPlaneEnt->setMaterialName(CUSTOM_ROCKWALL_MATERIAL + "/PCF"); - mAthene->setMaterialName(CUSTOM_ATHENE_MATERIAL + "/PCF"); - for (vector::type::iterator i = pColumns.begin(); - i != pColumns.end(); ++i) - { - (*i)->setMaterialName(CUSTOM_ROCKWALL_MATERIAL + "/PCF"); - } - - themat = MaterialManager::getSingleton().getByName(CUSTOM_ROCKWALL_MATERIAL + "/PCF"); - mCustomRockwallVparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverVertexProgramParameters(); - mCustomRockwallFparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverFragmentProgramParameters(); - themat = MaterialManager::getSingleton().getByName(CUSTOM_ATHENE_MATERIAL + "/PCF"); - mCustomAtheneVparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverVertexProgramParameters(); - mCustomAtheneFparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverFragmentProgramParameters(); - showSliders = true; - - // set the current params - setDefaultDepthShadowParams(); - break; - }; - mCurrentMaterial = mat; - - if (showSliders) - { - mFixedBiasSlider->show(); - mTrayMgr->moveWidgetToTray(mFixedBiasSlider, TL_TOPRIGHT); - mSlopedBiasSlider->show(); - mTrayMgr->moveWidgetToTray(mSlopedBiasSlider, TL_TOPRIGHT); - mClampSlider->show(); - mTrayMgr->moveWidgetToTray(mClampSlider, TL_TOPRIGHT); - } - else - { - mFixedBiasSlider->hide(); - mTrayMgr->removeWidgetFromTray(mFixedBiasSlider); - mSlopedBiasSlider->hide(); - mTrayMgr->removeWidgetFromTray(mSlopedBiasSlider); - mClampSlider->hide(); - mTrayMgr->removeWidgetFromTray(mClampSlider); - } - //updateTipForCombo(cbo); - //rebindDebugShadowOverlays(); - } - } + //These values are synchronized with ShadowProjection enum + mProjectionMenu = mTrayMgr->createLongSelectMenu( + TL_TOPLEFT, "ProjectionSelectMenu", "Projection", 300, 200, 5); + mProjectionMenu->addItem("Uniform"); + mProjectionMenu->addItem("Uniform Focused"); + mProjectionMenu->addItem("LiSPSM"); + mProjectionMenu->addItem("Plane Optimal"); + + mMaterialMenu = mTrayMgr->createLongSelectMenu( + TL_TOPLEFT, "MaterialSelectMenu", "Material", 300, 200, 5); + mMaterialMenu->addItem("Standard"); + mMaterialMenu->addItem("Depth Shadowmap"); + mMaterialMenu->addItem("Depth Shadowmap (PCF)"); + + mFixedBiasSlider = mTrayMgr->createThickSlider(TL_NONE, "FixedBiasSlider", "Fixed Bias", 256, 80, 0, 0.02, 100); + mFixedBiasSlider->setValue(0.0009, false); + mFixedBiasSlider->hide(); + + mSlopedBiasSlider = mTrayMgr->createThickSlider(TL_NONE, "SlopedBiasSlider", "Sloped Bias", 256, 80, 0, 0.2, 100); + mSlopedBiasSlider->setValue(0.0008, false); + mSlopedBiasSlider->hide(); + + mClampSlider = mTrayMgr->createThickSlider(TL_NONE, "SlopeClampSlider", "Slope Clamp", 256, 80, 0, 2, 100); + mClampSlider->setValue(0.2, false); + mClampSlider->hide(); + + updateGUI(mCurrentShadowTechnique); + mTrayMgr->showCursor(); + } + + void updateGUI(ShadowTechnique newTech) + { + bool isTextureBased = (newTech & SHADOWDETAILTYPE_TEXTURE) != 0; + + if (isTextureBased) + { + mProjectionMenu->show(); + mTrayMgr->moveWidgetToTray(mProjectionMenu, TL_TOPLEFT); + mMaterialMenu->show(); + mTrayMgr->moveWidgetToTray(mMaterialMenu, TL_TOPLEFT); + } + else + { + mProjectionMenu->hide(); + mTrayMgr->removeWidgetFromTray(mProjectionMenu); + mMaterialMenu->hide(); + mTrayMgr->removeWidgetFromTray(mMaterialMenu); + } + } + + void itemSelected(SelectMenu* menu) + { + if (menu == mTechniqueMenu) handleShadowTypeChanged(); + else if (menu == mLightingMenu) handleShadowTypeChanged(); + else if (menu == mProjectionMenu) handleProjectionChanged(); + else if (menu == mMaterialMenu) handleMaterialChanged(); + } + + + void handleShadowTypeChanged() + { + bool isStencil = mTechniqueMenu->getSelectionIndex() == 0; + bool isAdditive = mLightingMenu->getSelectionIndex() == 0; + ShadowTechnique newTech = mCurrentShadowTechnique; + + if (isStencil) + { + newTech = static_cast( + (newTech & ~SHADOWDETAILTYPE_TEXTURE) | SHADOWDETAILTYPE_STENCIL); + resetMaterials(); + } + else + { + newTech = static_cast( + (newTech & ~SHADOWDETAILTYPE_STENCIL) | SHADOWDETAILTYPE_TEXTURE); + } + + if (isAdditive) + { + newTech = static_cast( + (newTech & ~SHADOWDETAILTYPE_MODULATIVE) | SHADOWDETAILTYPE_ADDITIVE); + } + else + { + newTech = static_cast( + (newTech & ~SHADOWDETAILTYPE_ADDITIVE) | SHADOWDETAILTYPE_MODULATIVE); + } + + changeShadowTechnique(newTech); + } + + void handleProjectionChanged() + { + ShadowProjection proj = (ShadowProjection)mProjectionMenu->getSelectionIndex(); + + if (proj != mCurrentProjection) + { + switch(proj) + { + case UNIFORM: + mCurrentShadowCameraSetup = + ShadowCameraSetupPtr(new DefaultShadowCameraSetup()); + break; + case UNIFORM_FOCUSED: + mCurrentShadowCameraSetup = + ShadowCameraSetupPtr(new FocusedShadowCameraSetup()); + break; + case LISPSM: + { + mLiSPSMSetup = new LiSPSMShadowCameraSetup(); + //mLiSPSMSetup->setUseAggressiveFocusRegion(false); + mCurrentShadowCameraSetup = ShadowCameraSetupPtr(mLiSPSMSetup); + } + break; + case PLANE_OPTIMAL: + mCurrentShadowCameraSetup = + ShadowCameraSetupPtr(new PlaneOptimalShadowCameraSetup(mPlane)); + break; + + }; + mCurrentProjection = proj; + + mSceneMgr->setShadowCameraSetup(mCurrentShadowCameraSetup); + + //updateTipForCombo(cbo); + if (!mCustomRockwallVparams.isNull() && !mCustomRockwallFparams.isNull()) + { + // set + setDefaultDepthShadowParams(); + } + + } + } + + void updateDepthShadowParams() + { + mCustomRockwallFparams->setNamedConstant("fixedDepthBias", + mFixedBiasSlider->getValue()); + mCustomRockwallFparams->setNamedConstant("gradientScaleBias", + mSlopedBiasSlider->getValue()); + mCustomRockwallFparams->setNamedConstant("gradientClamp", + mClampSlider->getValue()); + + mCustomAtheneFparams->setNamedConstant("fixedDepthBias", + mFixedBiasSlider->getValue()); + mCustomAtheneFparams->setNamedConstant("gradientScaleBias", + mSlopedBiasSlider->getValue()); + mCustomAtheneFparams->setNamedConstant("gradientClamp", + mClampSlider->getValue()); + } + + void setDefaultDepthShadowParams() + { + switch(mCurrentProjection) + { + case UNIFORM: + case UNIFORM_FOCUSED: + case PLANE_OPTIMAL: + mFixedBiasSlider->setValue(0.0f, false); + mSlopedBiasSlider->setValue(0.0f, false); + break; + case LISPSM: + mFixedBiasSlider->setValue(0.009f, false); + mSlopedBiasSlider->setValue(0.04f, false); + break; + }; + + updateDepthShadowParams(); + + } + + void sliderMoved(Slider* slider) + { + if (!mCustomRockwallVparams.isNull() && !mCustomRockwallFparams.isNull()) + { + updateDepthShadowParams(); + } + } + + void rebindDebugShadowOverlays() + { + /*MaterialPtr debugMat = + MaterialManager::getSingleton().getByName("Ogre/DebugShadowMap0"); + TexturePtr shadowTex = mSceneMgr->getShadowTexture(0); + debugMat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(shadowTex->getName()); + + debugMat = + MaterialManager::getSingleton().getByName("Ogre/DebugShadowMap1"); + shadowTex = mSceneMgr->getShadowTexture(1); + debugMat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(shadowTex->getName());*/ + } + + void resetMaterials() + { + // Sort out base materials + pPlaneEnt->setMaterialName(BASIC_ROCKWALL_MATERIAL); + mAthene->setMaterialName(BASIC_ATHENE_MATERIAL); + for (vector::type::iterator i = pColumns.begin(); + i != pColumns.end(); ++i) + { + (*i)->setMaterialName(BASIC_ROCKWALL_MATERIAL); + } + + mCustomRockwallVparams.setNull(); + mCustomRockwallFparams.setNull(); + mCustomAtheneVparams.setNull(); + mCustomAtheneFparams.setNull(); + + } + + void handleMaterialChanged() + { + bool showSliders = false; + ShadowMaterial mat = (ShadowMaterial)mMaterialMenu->getSelectionIndex(); + MaterialPtr themat; + if (mat != mCurrentMaterial) + { + switch(mat) + { + case MAT_STANDARD: + mSceneMgr->setShadowTexturePixelFormat(PF_X8R8G8B8); + mSceneMgr->setShadowTextureCasterMaterial(BLANKSTRING); + mSceneMgr->setShadowTextureReceiverMaterial(BLANKSTRING); + mSceneMgr->setShadowTextureSelfShadow(false); + + resetMaterials(); + + break; + case MAT_DEPTH_FLOAT: + //if (mIsOpenGL) + //{ + // // GL performs much better if you pick half-float format + // mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT16_R); + //} + //else + { + // D3D is the opposite - if you ask for PF_FLOAT16_R you + // get an integer format instead! You can ask for PF_FLOAT16_GR + // but the precision doesn't work well + mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R); + } + mSceneMgr->setShadowTextureCasterMaterial(CUSTOM_CASTER_MATERIAL); + mSceneMgr->setShadowTextureReceiverMaterial(CUSTOM_RECEIVER_MATERIAL); + mSceneMgr->setShadowTextureSelfShadow(true); + // Sort out base materials + pPlaneEnt->setMaterialName(CUSTOM_ROCKWALL_MATERIAL); + mAthene->setMaterialName(CUSTOM_ATHENE_MATERIAL); + for (vector::type::iterator i = pColumns.begin(); + i != pColumns.end(); ++i) + { + (*i)->setMaterialName(CUSTOM_ROCKWALL_MATERIAL); + } + + themat = MaterialManager::getSingleton().getByName(CUSTOM_ROCKWALL_MATERIAL); + mCustomRockwallVparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverVertexProgramParameters(); + mCustomRockwallFparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverFragmentProgramParameters(); + themat = MaterialManager::getSingleton().getByName(CUSTOM_ATHENE_MATERIAL); + mCustomAtheneVparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverVertexProgramParameters(); + mCustomAtheneFparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverFragmentProgramParameters(); + showSliders = true; + + + // set the current params + setDefaultDepthShadowParams(); + break; + case MAT_DEPTH_FLOAT_PCF: + //if (mIsOpenGL) + //{ + // // GL performs much better if you pick half-float format + // mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT16_R); + //} + //else + { + // D3D is the opposite - if you ask for PF_FLOAT16_R you + // get an integer format instead! You can ask for PF_FLOAT16_GR + // but the precision doesn't work well + mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R); + } + mSceneMgr->setShadowTextureCasterMaterial(CUSTOM_CASTER_MATERIAL); + mSceneMgr->setShadowTextureReceiverMaterial(CUSTOM_RECEIVER_MATERIAL + "/PCF"); + mSceneMgr->setShadowTextureSelfShadow(true); + // Sort out base materials + pPlaneEnt->setMaterialName(CUSTOM_ROCKWALL_MATERIAL + "/PCF"); + mAthene->setMaterialName(CUSTOM_ATHENE_MATERIAL + "/PCF"); + for (vector::type::iterator i = pColumns.begin(); + i != pColumns.end(); ++i) + { + (*i)->setMaterialName(CUSTOM_ROCKWALL_MATERIAL + "/PCF"); + } + + themat = MaterialManager::getSingleton().getByName(CUSTOM_ROCKWALL_MATERIAL + "/PCF"); + mCustomRockwallVparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverVertexProgramParameters(); + mCustomRockwallFparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverFragmentProgramParameters(); + themat = MaterialManager::getSingleton().getByName(CUSTOM_ATHENE_MATERIAL + "/PCF"); + mCustomAtheneVparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverVertexProgramParameters(); + mCustomAtheneFparams = themat->getTechnique(0)->getPass(1)->getShadowReceiverFragmentProgramParameters(); + showSliders = true; + + // set the current params + setDefaultDepthShadowParams(); + break; + }; + mCurrentMaterial = mat; + + if (showSliders) + { + mFixedBiasSlider->show(); + mTrayMgr->moveWidgetToTray(mFixedBiasSlider, TL_TOPRIGHT); + mSlopedBiasSlider->show(); + mTrayMgr->moveWidgetToTray(mSlopedBiasSlider, TL_TOPRIGHT); + mClampSlider->show(); + mTrayMgr->moveWidgetToTray(mClampSlider, TL_TOPRIGHT); + } + else + { + mFixedBiasSlider->hide(); + mTrayMgr->removeWidgetFromTray(mFixedBiasSlider); + mSlopedBiasSlider->hide(); + mTrayMgr->removeWidgetFromTray(mSlopedBiasSlider); + mClampSlider->hide(); + mTrayMgr->removeWidgetFromTray(mClampSlider); + } + //updateTipForCombo(cbo); + //rebindDebugShadowOverlays(); + } + } }; diff --git a/Samples/Shadows/src/Shadows.cpp b/Samples/Shadows/src/Shadows.cpp index b42639d4c5f..3b1af99086b 100644 --- a/Samples/Shadows/src/Shadows.cpp +++ b/Samples/Shadows/src/Shadows.cpp @@ -32,16 +32,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Shadows; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Shadows; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/SkeletalAnimation/include/SkeletalAnimation.h b/Samples/SkeletalAnimation/include/SkeletalAnimation.h index 188e2a72c3b..b4105431384 100644 --- a/Samples/SkeletalAnimation/include/SkeletalAnimation.h +++ b/Samples/SkeletalAnimation/include/SkeletalAnimation.h @@ -20,16 +20,16 @@ class _OgreSampleClassExport Sample_SkeletalAnimation : public SdkSample kVisualiseAll }; public: - Sample_SkeletalAnimation() : NUM_MODELS(6), ANIM_CHOP(8) + Sample_SkeletalAnimation() : NUM_MODELS(6), ANIM_CHOP(8) #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - , mSrsHardwareSkinning(0) + , mSrsHardwareSkinning(0) #endif - { - mInfo["Title"] = "Skeletal Animation"; - mInfo["Description"] = "A demo of the skeletal animation feature, including spline animation."; - mInfo["Thumbnail"] = "thumb_skelanim.png"; - mInfo["Category"] = "Animation"; - mInfo["Help"] = "Controls:\n" + { + mInfo["Title"] = "Skeletal Animation"; + mInfo["Description"] = "A demo of the skeletal animation feature, including spline animation."; + mInfo["Thumbnail"] = "thumb_skelanim.png"; + mInfo["Category"] = "Animation"; + mInfo["Help"] = "Controls:\n" "WASD to move the camera. Mouse to look around.\n" "V toggle visualise bounding boxes.\n" "B toggle bone-based bounding boxes on/off."; @@ -38,7 +38,7 @@ class _OgreSampleClassExport Sample_SkeletalAnimation : public SdkSample mBoundingBoxModelIndex = 0; mBoneBoundingBoxes = false; mBoneBoundingBoxesItemName = "Bone AABBs"; - } + } void setVisualiseBoundingBoxMode( VisualiseBoundingBoxMode mode ) { @@ -81,7 +81,7 @@ class _OgreSampleClassExport Sample_SkeletalAnimation : public SdkSample mStatusPanel->setParamValue(mBoneBoundingBoxesItemName, mBoneBoundingBoxes ? "On" : "Off"); } } - bool keyPressed(const OIS::KeyEvent& evt) + bool keyPressed(const OIS::KeyEvent& evt) { // unless the help dialog is visible, if ( !mTrayMgr->isDialogVisible() ) @@ -124,132 +124,132 @@ class _OgreSampleClassExport Sample_SkeletalAnimation : public SdkSample { for (int i = 0; i < NUM_MODELS; i++) { - // update sneaking animation based on speed - mAnimStates[i]->addTime(mAnimSpeeds[i] * evt.timeSinceLastFrame); + // update sneaking animation based on speed + mAnimStates[i]->addTime(mAnimSpeeds[i] * evt.timeSinceLastFrame); - if (mAnimStates[i]->getTimePosition() >= ANIM_CHOP) // when it's time to loop... - { - /* We need reposition the scene node origin, since the animation includes translation. - Position is calculated from an offset to the end position, and rotation is calculated - from how much the animation turns the character. */ + if (mAnimStates[i]->getTimePosition() >= ANIM_CHOP) // when it's time to loop... + { + /* We need reposition the scene node origin, since the animation includes translation. + Position is calculated from an offset to the end position, and rotation is calculated + from how much the animation turns the character. */ - Quaternion rot(Degree(-60), Vector3::UNIT_Y); // how much the animation turns the character + Quaternion rot(Degree(-60), Vector3::UNIT_Y); // how much the animation turns the character - // find current end position and the offset - Vector3 currEnd = mModelNodes[i]->getOrientation() * mSneakEndPos + mModelNodes[i]->getPosition(); - Vector3 offset = rot * mModelNodes[i]->getOrientation() * -mSneakStartPos; + // find current end position and the offset + Vector3 currEnd = mModelNodes[i]->getOrientation() * mSneakEndPos + mModelNodes[i]->getPosition(); + Vector3 offset = rot * mModelNodes[i]->getOrientation() * -mSneakStartPos; - mModelNodes[i]->setPosition(currEnd + offset); - mModelNodes[i]->rotate(rot); + mModelNodes[i]->setPosition(currEnd + offset); + mModelNodes[i]->rotate(rot); - mAnimStates[i]->setTimePosition(0); // reset animation time - } + mAnimStates[i]->setTimePosition(0); // reset animation time + } } - return SdkSample::frameRenderingQueued(evt); + return SdkSample::frameRenderingQueued(evt); } protected: - void setupContent() - { + void setupContent() + { /*#if defined(INCLUDE_RTSHADER_SYSTEM) && defined(RTSHADER_SYSTEM_BUILD_EXT_SHADERS) - //To make glsles work the program will need to be provided with proper - //shadow caster materials - if (mShaderGenerator->getTargetLanguage() != "glsles" && mShaderGenerator->getTargetLanguage() != "glsl") - { - //Add the hardware skinning to the shader generator default render state - mSrsHardwareSkinning = mShaderGenerator->createSubRenderState(Ogre::RTShader::HardwareSkinning::Type); - Ogre::RTShader::RenderState* renderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - renderState->addTemplateSubRenderState(mSrsHardwareSkinning); - - Ogre::MaterialPtr pCast1 = Ogre::MaterialManager::getSingleton().getByName("Ogre/RTShader/shadow_caster_dq_skinning_1weight"); - Ogre::MaterialPtr pCast2 = Ogre::MaterialManager::getSingleton().getByName("Ogre/RTShader/shadow_caster_dq_skinning_2weight"); - Ogre::MaterialPtr pCast3 = Ogre::MaterialManager::getSingleton().getByName("Ogre/RTShader/shadow_caster_dq_skinning_3weight"); - Ogre::MaterialPtr pCast4 = Ogre::MaterialManager::getSingleton().getByName("Ogre/RTShader/shadow_caster_dq_skinning_4weight"); - - Ogre::RTShader::HardwareSkinningFactory::getSingleton().setCustomShadowCasterMaterials( - Ogre::RTShader::ST_DUAL_QUATERNION, pCast1, pCast2, pCast3, pCast4); - } + //To make glsles work the program will need to be provided with proper + //shadow caster materials + if (mShaderGenerator->getTargetLanguage() != "glsles" && mShaderGenerator->getTargetLanguage() != "glsl") + { + //Add the hardware skinning to the shader generator default render state + mSrsHardwareSkinning = mShaderGenerator->createSubRenderState(Ogre::RTShader::HardwareSkinning::Type); + Ogre::RTShader::RenderState* renderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + renderState->addTemplateSubRenderState(mSrsHardwareSkinning); + + Ogre::MaterialPtr pCast1 = Ogre::MaterialManager::getSingleton().getByName("Ogre/RTShader/shadow_caster_dq_skinning_1weight"); + Ogre::MaterialPtr pCast2 = Ogre::MaterialManager::getSingleton().getByName("Ogre/RTShader/shadow_caster_dq_skinning_2weight"); + Ogre::MaterialPtr pCast3 = Ogre::MaterialManager::getSingleton().getByName("Ogre/RTShader/shadow_caster_dq_skinning_3weight"); + Ogre::MaterialPtr pCast4 = Ogre::MaterialManager::getSingleton().getByName("Ogre/RTShader/shadow_caster_dq_skinning_4weight"); + + Ogre::RTShader::HardwareSkinningFactory::getSingleton().setCustomShadowCasterMaterials( + Ogre::RTShader::ST_DUAL_QUATERNION, pCast1, pCast2, pCast3, pCast4); + } #endif*/ - // set shadow properties - mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); - mSceneMgr->setShadowTextureSize(512); - mSceneMgr->setShadowColour(ColourValue(0.6, 0.6, 0.6)); - mSceneMgr->setShadowTextureCount(2); - - // add a little ambient lighting - mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); - - SceneNode* lightsBbsNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - BillboardSet* bbs; - - // Create billboard set for lights . - bbs = mSceneMgr->createBillboardSet(); - bbs->setMaterialName("Examples/Flare"); - lightsBbsNode->attachObject(bbs); - - - // add a blue spotlight - Light* l = mSceneMgr->createLight(); - Vector3 dir; - l->setType(Light::LT_SPOTLIGHT); - l->setPosition(-40, 180, -10); - dir = -l->getPosition(); - dir.normalise(); - l->setDirection(dir); - l->setDiffuseColour(0.0, 0.0, 0.5); - bbs->createBillboard(l->getPosition())->setColour(l->getDiffuseColour()); - - - // add a green spotlight. - l = mSceneMgr->createLight(); - l->setType(Light::LT_SPOTLIGHT); - l->setPosition(0, 150, -100); - dir = -l->getPosition(); - dir.normalise(); - l->setDirection(dir); - l->setDiffuseColour(0.0, 0.5, 0.0); - bbs->createBillboard(l->getPosition())->setColour(l->getDiffuseColour()); - - // create a floor mesh resource - MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Plane(Vector3::UNIT_Y, -1), 250, 250, 25, 25, true, 1, 15, 15, Vector3::UNIT_Z); - - // add a floor to our scene using the floor mesh we created - Entity* floor = mSceneMgr->createEntity("Floor", "floor"); - floor->setMaterialName("Examples/Rockwall"); - floor->setCastShadows(false); - mSceneMgr->getRootSceneNode()->attachObject(floor); - - // set camera initial transform and speed - mCamera->setPosition(100, 20, 0); - mCamera->lookAt(0, 10, 0); - mCameraMan->setTopSpeed(50); - - setupModels(); - } - - void setupModels() - { - tweakSneakAnim(); - - SceneNode* sn = NULL; - Entity* ent = NULL; - AnimationState* as = NULL; - - for (int i = 0; i < NUM_MODELS; i++) - { - // create scene nodes for the models at regular angular intervals - sn = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - sn->yaw(Radian(Math::TWO_PI * (float)i / (float)NUM_MODELS)); - sn->translate(0, 0, -20, Node::TS_LOCAL); - mModelNodes.push_back(sn); - - // create and attach a jaiqua entity - ent = mSceneMgr->createEntity("Jaiqua" + StringConverter::toString(i + 1), "jaiqua.mesh"); + // set shadow properties + mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); + mSceneMgr->setShadowTextureSize(512); + mSceneMgr->setShadowColour(ColourValue(0.6, 0.6, 0.6)); + mSceneMgr->setShadowTextureCount(2); + + // add a little ambient lighting + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); + + SceneNode* lightsBbsNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + BillboardSet* bbs; + + // Create billboard set for lights . + bbs = mSceneMgr->createBillboardSet(); + bbs->setMaterialName("Examples/Flare"); + lightsBbsNode->attachObject(bbs); + + + // add a blue spotlight + Light* l = mSceneMgr->createLight(); + Vector3 dir; + l->setType(Light::LT_SPOTLIGHT); + l->setPosition(-40, 180, -10); + dir = -l->getPosition(); + dir.normalise(); + l->setDirection(dir); + l->setDiffuseColour(0.0, 0.0, 0.5); + bbs->createBillboard(l->getPosition())->setColour(l->getDiffuseColour()); + + + // add a green spotlight. + l = mSceneMgr->createLight(); + l->setType(Light::LT_SPOTLIGHT); + l->setPosition(0, 150, -100); + dir = -l->getPosition(); + dir.normalise(); + l->setDirection(dir); + l->setDiffuseColour(0.0, 0.5, 0.0); + bbs->createBillboard(l->getPosition())->setColour(l->getDiffuseColour()); + + // create a floor mesh resource + MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Plane(Vector3::UNIT_Y, -1), 250, 250, 25, 25, true, 1, 15, 15, Vector3::UNIT_Z); + + // add a floor to our scene using the floor mesh we created + Entity* floor = mSceneMgr->createEntity("Floor", "floor"); + floor->setMaterialName("Examples/Rockwall"); + floor->setCastShadows(false); + mSceneMgr->getRootSceneNode()->attachObject(floor); + + // set camera initial transform and speed + mCamera->setPosition(100, 20, 0); + mCamera->lookAt(0, 10, 0); + mCameraMan->setTopSpeed(50); + + setupModels(); + } + + void setupModels() + { + tweakSneakAnim(); + + SceneNode* sn = NULL; + Entity* ent = NULL; + AnimationState* as = NULL; + + for (int i = 0; i < NUM_MODELS; i++) + { + // create scene nodes for the models at regular angular intervals + sn = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + sn->yaw(Radian(Math::TWO_PI * (float)i / (float)NUM_MODELS)); + sn->translate(0, 0, -20, Node::TS_LOCAL); + mModelNodes.push_back(sn); + + // create and attach a jaiqua entity + ent = mSceneMgr->createEntity("Jaiqua" + StringConverter::toString(i + 1), "jaiqua.mesh"); #ifdef INCLUDE_RTSHADER_SYSTEM if (mShaderGenerator->getTargetLanguage() == "glsles") @@ -259,134 +259,134 @@ class _OgreSampleClassExport Sample_SkeletalAnimation : public SdkSample } #endif ent->setMaterialName("jaiqua"); //"jaiquaDualQuatTest" - sn->attachObject(ent); + sn->attachObject(ent); /*#if defined(INCLUDE_RTSHADER_SYSTEM) && defined(RTSHADER_SYSTEM_BUILD_EXT_SHADERS) - //To make glsles work the program will need to be provided with proper - //shadow caster materials - if (mShaderGenerator->getTargetLanguage() != "glsles") - { - //In case the system uses the RTSS, the following line will ensure - //that the entity is using hardware animation in RTSS as well. - RTShader::HardwareSkinningFactory::getSingleton().prepareEntityForSkinning(ent, Ogre::RTShader::ST_DUAL_QUATERNION, true, false); - - //The following line is needed only because the Jaiqua model material has shaders and - //as such is not automatically reflected in the RTSS system - RTShader::ShaderGenerator::getSingleton().createShaderBasedTechnique( - ent->getSubEntity(0)->getMaterialName(), - Ogre::MaterialManager::DEFAULT_SCHEME_NAME, - Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, - true); - } + //To make glsles work the program will need to be provided with proper + //shadow caster materials + if (mShaderGenerator->getTargetLanguage() != "glsles") + { + //In case the system uses the RTSS, the following line will ensure + //that the entity is using hardware animation in RTSS as well. + RTShader::HardwareSkinningFactory::getSingleton().prepareEntityForSkinning(ent, Ogre::RTShader::ST_DUAL_QUATERNION, true, false); + + //The following line is needed only because the Jaiqua model material has shaders and + //as such is not automatically reflected in the RTSS system + RTShader::ShaderGenerator::getSingleton().createShaderBasedTechnique( + ent->getSubEntity(0)->getMaterialName(), + Ogre::MaterialManager::DEFAULT_SCHEME_NAME, + Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, + true); + } #endif*/ - - // enable the entity's sneaking animation at a random speed and loop it manually since translation is involved - as = ent->getAnimationState("Sneak"); - as->setEnabled(true); - as->setLoop(false); - mAnimSpeeds.push_back(Math::RangeRandom(0.5, 1.5)); - mAnimStates.push_back(as); - } - - // create name and value for skinning mode - StringVector names; + + // enable the entity's sneaking animation at a random speed and loop it manually since translation is involved + as = ent->getAnimationState("Sneak"); + as->setEnabled(true); + as->setLoop(false); + mAnimSpeeds.push_back(Math::RangeRandom(0.5, 1.5)); + mAnimStates.push_back(as); + } + + // create name and value for skinning mode + StringVector names; names.push_back("Help"); - names.push_back("Skinning"); + names.push_back("Skinning"); names.push_back(mBoneBoundingBoxesItemName); - - // create a params panel to display the help and skinning mode - mStatusPanel = mTrayMgr->createParamsPanel(TL_TOPLEFT, "HelpMessage", 200, names); + + // create a params panel to display the help and skinning mode + mStatusPanel = mTrayMgr->createParamsPanel(TL_TOPLEFT, "HelpMessage", 200, names); mStatusPanel->setParamValue("Help", "H / F1"); - String value = "Software"; + String value = "Software"; enableBoneBoundingBoxMode( false ); // update status panel entry // change the value if hardware skinning is enabled - MaterialPtr entityMaterial = ent->getSubEntity(0)->getMaterial(); - if(!entityMaterial.isNull()) - { - Technique* bestTechnique = entityMaterial->getBestTechnique(); - if(bestTechnique) - { - Pass* pass = bestTechnique->getPass(0); - if (pass && pass->hasVertexProgram() && pass->getVertexProgram()->isSkeletalAnimationIncluded()) - { - value = "Hardware"; - } - } - } + MaterialPtr entityMaterial = ent->getSubEntity(0)->getMaterial(); + if(!entityMaterial.isNull()) + { + Technique* bestTechnique = entityMaterial->getBestTechnique(); + if(bestTechnique) + { + Pass* pass = bestTechnique->getPass(0); + if (pass && pass->hasVertexProgram() && pass->getVertexProgram()->isSkeletalAnimationIncluded()) + { + value = "Hardware"; + } + } + } mStatusPanel->setParamValue("Skinning", value); - } - - /*----------------------------------------------------------------------------- - | The jaiqua sneak animation doesn't loop properly. This method tweaks the - | animation to loop properly by altering the Spineroot bone track. - -----------------------------------------------------------------------------*/ - void tweakSneakAnim() - { - // get the skeleton, animation, and the node track iterator - SkeletonPtr skel = SkeletonManager::getSingleton().load("jaiqua.skeleton", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME).staticCast(); - Animation* anim = skel->getAnimation("Sneak"); - Animation::NodeTrackIterator tracks = anim->getNodeTrackIterator(); - - while (tracks.hasMoreElements()) // for every node track... - { - NodeAnimationTrack* track = tracks.getNext(); - - // get the keyframe at the chopping point - TransformKeyFrame oldKf(0, 0); - track->getInterpolatedKeyFrame(ANIM_CHOP, &oldKf); - - // drop all keyframes after the chopping point - while (track->getKeyFrame(track->getNumKeyFrames()-1)->getTime() >= ANIM_CHOP - 0.3f) - track->removeKeyFrame(track->getNumKeyFrames()-1); - - // create a new keyframe at chopping point, and get the first keyframe - TransformKeyFrame* newKf = track->createNodeKeyFrame(ANIM_CHOP); - TransformKeyFrame* startKf = track->getNodeKeyFrame(0); - - Bone* bone = skel->getBone(track->getHandle()); - - if (bone->getName() == "Spineroot") // adjust spine root relative to new location - { - mSneakStartPos = startKf->getTranslate() + bone->getInitialPosition(); - mSneakEndPos = oldKf.getTranslate() + bone->getInitialPosition(); - mSneakStartPos.y = mSneakEndPos.y; - - newKf->setTranslate(oldKf.getTranslate()); - newKf->setRotation(oldKf.getRotation()); - newKf->setScale(oldKf.getScale()); - } - else // make all other bones loop back - { - newKf->setTranslate(startKf->getTranslate()); - newKf->setRotation(startKf->getRotation()); - newKf->setScale(startKf->getScale()); - } - } - } - - void cleanupContent() - { - mModelNodes.clear(); - mAnimStates.clear(); - mAnimSpeeds.clear(); - MeshManager::getSingleton().remove("floor"); + } + + /*----------------------------------------------------------------------------- + | The jaiqua sneak animation doesn't loop properly. This method tweaks the + | animation to loop properly by altering the Spineroot bone track. + -----------------------------------------------------------------------------*/ + void tweakSneakAnim() + { + // get the skeleton, animation, and the node track iterator + SkeletonPtr skel = SkeletonManager::getSingleton().load("jaiqua.skeleton", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME).staticCast(); + Animation* anim = skel->getAnimation("Sneak"); + Animation::NodeTrackIterator tracks = anim->getNodeTrackIterator(); + + while (tracks.hasMoreElements()) // for every node track... + { + NodeAnimationTrack* track = tracks.getNext(); + + // get the keyframe at the chopping point + TransformKeyFrame oldKf(0, 0); + track->getInterpolatedKeyFrame(ANIM_CHOP, &oldKf); + + // drop all keyframes after the chopping point + while (track->getKeyFrame(track->getNumKeyFrames()-1)->getTime() >= ANIM_CHOP - 0.3f) + track->removeKeyFrame(track->getNumKeyFrames()-1); + + // create a new keyframe at chopping point, and get the first keyframe + TransformKeyFrame* newKf = track->createNodeKeyFrame(ANIM_CHOP); + TransformKeyFrame* startKf = track->getNodeKeyFrame(0); + + Bone* bone = skel->getBone(track->getHandle()); + + if (bone->getName() == "Spineroot") // adjust spine root relative to new location + { + mSneakStartPos = startKf->getTranslate() + bone->getInitialPosition(); + mSneakEndPos = oldKf.getTranslate() + bone->getInitialPosition(); + mSneakStartPos.y = mSneakEndPos.y; + + newKf->setTranslate(oldKf.getTranslate()); + newKf->setRotation(oldKf.getRotation()); + newKf->setScale(oldKf.getScale()); + } + else // make all other bones loop back + { + newKf->setTranslate(startKf->getTranslate()); + newKf->setRotation(startKf->getRotation()); + newKf->setScale(startKf->getScale()); + } + } + } + + void cleanupContent() + { + mModelNodes.clear(); + mAnimStates.clear(); + mAnimSpeeds.clear(); + MeshManager::getSingleton().remove("floor"); mSceneMgr->destroyEntity("Jaiqua"); /*#if defined(INCLUDE_RTSHADER_SYSTEM) && defined(RTSHADER_SYSTEM_BUILD_EXT_SHADERS) - //To make glsles work the program will need to be provided with proper - //shadow caster materials - if (mShaderGenerator->getTargetLanguage() != "glsles") - { - Ogre::RTShader::RenderState* renderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); - renderState->removeTemplateSubRenderState(mSrsHardwareSkinning); - } + //To make glsles work the program will need to be provided with proper + //shadow caster materials + if (mShaderGenerator->getTargetLanguage() != "glsles") + { + Ogre::RTShader::RenderState* renderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); + renderState->removeTemplateSubRenderState(mSrsHardwareSkinning); + } #endif*/ - } + } - const int NUM_MODELS; - const Real ANIM_CHOP; + const int NUM_MODELS; + const Real ANIM_CHOP; VisualiseBoundingBoxMode mVisualiseBoundingBoxMode; int mBoundingBoxModelIndex; // which model to show the bounding box for bool mBoneBoundingBoxes; @@ -394,14 +394,14 @@ class _OgreSampleClassExport Sample_SkeletalAnimation : public SdkSample String mBoneBoundingBoxesItemName; std::vector mModelNodes; - std::vector mAnimStates; - std::vector mAnimSpeeds; + std::vector mAnimStates; + std::vector mAnimSpeeds; - Vector3 mSneakStartPos; - Vector3 mSneakEndPos; + Vector3 mSneakStartPos; + Vector3 mSneakEndPos; #ifdef RTSHADER_SYSTEM_BUILD_EXT_SHADERS - RTShader::SubRenderState* mSrsHardwareSkinning; + RTShader::SubRenderState* mSrsHardwareSkinning; #endif }; diff --git a/Samples/SkeletalAnimation/src/SkeletalAnimation.cpp b/Samples/SkeletalAnimation/src/SkeletalAnimation.cpp index b06c1fc40fd..a33e1356e7a 100644 --- a/Samples/SkeletalAnimation/src/SkeletalAnimation.cpp +++ b/Samples/SkeletalAnimation/src/SkeletalAnimation.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_SkeletalAnimation; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_SkeletalAnimation; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/SkyBox/include/SkyBox.h b/Samples/SkyBox/include/SkyBox.h index 25354132448..b136b4597a2 100644 --- a/Samples/SkyBox/include/SkyBox.h +++ b/Samples/SkyBox/include/SkyBox.h @@ -11,54 +11,54 @@ class _OgreSampleClassExport Sample_SkyBox : public SdkSample { public: - Sample_SkyBox() - { - mInfo["Title"] = "Sky Box"; - mInfo["Description"] = "Shows how to use skyboxes (fixed-distance cubes used for backgrounds)."; - mInfo["Thumbnail"] = "thumb_skybox.png"; - mInfo["Category"] = "Environment"; - } + Sample_SkyBox() + { + mInfo["Title"] = "Sky Box"; + mInfo["Description"] = "Shows how to use skyboxes (fixed-distance cubes used for backgrounds)."; + mInfo["Thumbnail"] = "thumb_skybox.png"; + mInfo["Category"] = "Environment"; + } protected: - void setupContent() - { - // setup some basic lighting for our scene + void setupContent() + { + // setup some basic lighting for our scene mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); mSceneMgr->createLight()->setPosition(20, 80, 50); mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000); // set our skybox - // create a spaceship model, and place it at the origin + // create a spaceship model, and place it at the origin mSceneMgr->getRootSceneNode()->attachObject(mSceneMgr->createEntity("Razor", "razor.mesh")); - // create a particle system with 200 quota, then set its material and dimensions + // create a particle system with 200 quota, then set its material and dimensions ParticleSystem* thrusters = mSceneMgr->createParticleSystem(25); thrusters->setMaterialName("Examples/Flare"); thrusters->setDefaultDimensions(25, 25); - // create two emitters for our thruster particle system - for (unsigned int i = 0; i < 2; i++) - { - ParticleEmitter* emitter = thrusters->addEmitter("Point"); // add a point emitter + // create two emitters for our thruster particle system + for (unsigned int i = 0; i < 2; i++) + { + ParticleEmitter* emitter = thrusters->addEmitter("Point"); // add a point emitter - // set the emitter properties - emitter->setAngle(Degree(3)); - emitter->setTimeToLive(0.5); - emitter->setEmissionRate(25); - emitter->setParticleVelocity(25); - emitter->setDirection(Vector3::NEGATIVE_UNIT_Z); - emitter->setColour(ColourValue::White, ColourValue::Red); - emitter->setPosition(Vector3(i == 0 ? 5.7 : -18, 0, 0)); - } + // set the emitter properties + emitter->setAngle(Degree(3)); + emitter->setTimeToLive(0.5); + emitter->setEmissionRate(25); + emitter->setParticleVelocity(25); + emitter->setDirection(Vector3::NEGATIVE_UNIT_Z); + emitter->setColour(ColourValue::White, ColourValue::Red); + emitter->setPosition(Vector3(i == 0 ? 5.7 : -18, 0, 0)); + } - // attach our thruster particles to the rear of the ship + // attach our thruster particles to the rear of the ship mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0, 6.5, -67))->attachObject(thrusters); - // set the camera's initial position and orientation - mCamera->setPosition(0, 0, 150); - mCamera->yaw(Degree(5)); - } + // set the camera's initial position and orientation + mCamera->setPosition(0, 0, 150); + mCamera->yaw(Degree(5)); + } }; #endif diff --git a/Samples/SkyBox/src/SkyBox.cpp b/Samples/SkyBox/src/SkyBox.cpp index bdbc581bf7c..8efb95b4245 100644 --- a/Samples/SkyBox/src/SkyBox.cpp +++ b/Samples/SkyBox/src/SkyBox.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_SkyBox; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_SkyBox; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/SkyDome/include/SkyDome.h b/Samples/SkyDome/include/SkyDome.h index 5a5dac76866..dd625e8bb01 100644 --- a/Samples/SkyDome/include/SkyDome.h +++ b/Samples/SkyDome/include/SkyDome.h @@ -10,63 +10,63 @@ class _OgreSampleClassExport Sample_SkyDome : public SdkSample { public: - Sample_SkyDome() - { - mInfo["Title"] = "Sky Dome"; - mInfo["Description"] = "Shows how to use skydomes (fixed-distance domes used for backgrounds)."; - mInfo["Thumbnail"] = "thumb_skydome.png"; - mInfo["Category"] = "Environment"; - } - - void sliderMoved(Slider* slider) - { - // use the values from the sliders to update the skydome properties - mSceneMgr->setSkyDome(true, "Examples/CloudySky", mCurvatureSlider->getValue(), mTilingSlider->getValue()); - } + Sample_SkyDome() + { + mInfo["Title"] = "Sky Dome"; + mInfo["Description"] = "Shows how to use skydomes (fixed-distance domes used for backgrounds)."; + mInfo["Thumbnail"] = "thumb_skydome.png"; + mInfo["Category"] = "Environment"; + } + + void sliderMoved(Slider* slider) + { + // use the values from the sliders to update the skydome properties + mSceneMgr->setSkyDome(true, "Examples/CloudySky", mCurvatureSlider->getValue(), mTilingSlider->getValue()); + } protected: - void setupContent() - { - // setup some basic lighting for our scene + void setupContent() + { + // setup some basic lighting for our scene mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); mSceneMgr->createLight()->setPosition(20, 80, 50); - // set our camera to orbit around the origin and show cursor - mCameraMan->setStyle(CS_ORBIT); - mCameraMan->setYawPitchDist(Degree(0), Degree(0), 250); - mTrayMgr->showCursor(); + // set our camera to orbit around the origin and show cursor + mCameraMan->setStyle(CS_ORBIT); + mCameraMan->setYawPitchDist(Degree(0), Degree(0), 250); + mTrayMgr->showCursor(); - // create a floor mesh resource - MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Plane(Vector3::UNIT_Y, -30), 1000, 1000, 10, 10, true, 1, 8, 8, Vector3::UNIT_Z); + // create a floor mesh resource + MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Plane(Vector3::UNIT_Y, -30), 1000, 1000, 10, 10, true, 1, 8, 8, Vector3::UNIT_Z); - // create a floor entity, give it a material, and place it at the origin + // create a floor entity, give it a material, and place it at the origin Entity* floor = mSceneMgr->createEntity("Floor", "floor"); floor->setMaterialName("Examples/BumpyMetal"); mSceneMgr->getRootSceneNode()->attachObject(floor); - // create an ogre head entity and place it at the origin + // create an ogre head entity and place it at the origin mSceneMgr->getRootSceneNode()->attachObject(mSceneMgr->createEntity("Head", "ogrehead.mesh")); - // create slider bars to control the dome curvature and texture tiling - mCurvatureSlider = mTrayMgr->createThickSlider(TL_TOPLEFT, "Curvature", "Dome Curvature", 200, 60, 0, 50, 11); - mTilingSlider = mTrayMgr->createThickSlider(TL_TOPLEFT, "Tiling", "Dome Tiling", 200, 60, 1, 20, 191); + // create slider bars to control the dome curvature and texture tiling + mCurvatureSlider = mTrayMgr->createThickSlider(TL_TOPLEFT, "Curvature", "Dome Curvature", 200, 60, 0, 50, 11); + mTilingSlider = mTrayMgr->createThickSlider(TL_TOPLEFT, "Tiling", "Dome Tiling", 200, 60, 1, 20, 191); - /* Here, we set default values for our sliders. We do not need to setup a skydome here, because when - slider values change, the sliderMoved callback is invoked, and we setup the skydome with the appropriate - values in there. See its definition above. */ - mCurvatureSlider->setValue(10); - mTilingSlider->setValue(8); - } + /* Here, we set default values for our sliders. We do not need to setup a skydome here, because when + slider values change, the sliderMoved callback is invoked, and we setup the skydome with the appropriate + values in there. See its definition above. */ + mCurvatureSlider->setValue(10); + mTilingSlider->setValue(8); + } - void cleanupContent() - { - MeshManager::getSingleton().remove("floor"); - } + void cleanupContent() + { + MeshManager::getSingleton().remove("floor"); + } - Slider* mCurvatureSlider; - Slider* mTilingSlider; + Slider* mCurvatureSlider; + Slider* mTilingSlider; }; #endif diff --git a/Samples/SkyDome/src/SkyDome.cpp b/Samples/SkyDome/src/SkyDome.cpp index 7d62374e8bc..819e1016216 100644 --- a/Samples/SkyDome/src/SkyDome.cpp +++ b/Samples/SkyDome/src/SkyDome.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_SkyDome; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_SkyDome; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/SkyPlane/include/SkyPlane.h b/Samples/SkyPlane/include/SkyPlane.h index f3735de3d32..651770ce9bc 100644 --- a/Samples/SkyPlane/include/SkyPlane.h +++ b/Samples/SkyPlane/include/SkyPlane.h @@ -10,32 +10,32 @@ class _OgreSampleClassExport Sample_SkyPlane : public SdkSample { public: - Sample_SkyPlane() - { - mInfo["Title"] = "Sky Plane"; - mInfo["Description"] = "Shows how to use skyplanes (fixed-distance planes used for backgrounds)."; - mInfo["Thumbnail"] = "thumb_skyplane.png"; - mInfo["Category"] = "Environment"; - } + Sample_SkyPlane() + { + mInfo["Title"] = "Sky Plane"; + mInfo["Description"] = "Shows how to use skyplanes (fixed-distance planes used for backgrounds)."; + mInfo["Thumbnail"] = "thumb_skyplane.png"; + mInfo["Category"] = "Environment"; + } protected: - void setupContent() - { - // setup some basic lighting for our scene + void setupContent() + { + // setup some basic lighting for our scene mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); mSceneMgr->createLight()->setPosition(20, 80, 50); - // create a skyplane 5000 units away, facing down, 10000 square units large, with 3x texture tiling + // create a skyplane 5000 units away, facing down, 10000 square units large, with 3x texture tiling mSceneMgr->setSkyPlane(true, Plane(0, -1, 0, 5000), "Examples/SpaceSkyPlane", 10000, 3); // and finally... omg it's a DRAGON! mSceneMgr->getRootSceneNode()->attachObject(mSceneMgr->createEntity("Dragon", "dragon.mesh")); - // turn around and look at the DRAGON! - mCamera->yaw(Degree(210)); - mCamera->pitch(Degree(-10)); - } + // turn around and look at the DRAGON! + mCamera->yaw(Degree(210)); + mCamera->pitch(Degree(-10)); + } }; #endif diff --git a/Samples/SkyPlane/src/SkyPlane.cpp b/Samples/SkyPlane/src/SkyPlane.cpp index 65d81dc77f6..3be6e31a81a 100644 --- a/Samples/SkyPlane/src/SkyPlane.cpp +++ b/Samples/SkyPlane/src/SkyPlane.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_SkyPlane; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_SkyPlane; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Smoke/include/Smoke.h b/Samples/Smoke/include/Smoke.h index cd95e1512de..594f9807664 100644 --- a/Samples/Smoke/include/Smoke.h +++ b/Samples/Smoke/include/Smoke.h @@ -11,49 +11,49 @@ class _OgreSampleClassExport Sample_Smoke : public SdkSample { public: - Sample_Smoke() - { - mInfo["Title"] = "Smoke"; - mInfo["Description"] = "Demonstrates depth-sorting of particles in particle systems."; - mInfo["Thumbnail"] = "thumb_smoke.png"; - mInfo["Category"] = "Effects"; - } - - bool frameRenderingQueued(const FrameEvent& evt) - { - // spin the head around and make it float up and down - mPivot->setPosition(0, Math::Sin(mRoot->getTimer()->getMilliseconds() / 150.0) * 10, 0); - mPivot->yaw(Radian(-evt.timeSinceLastFrame * 1.5)); - return SdkSample::frameRenderingQueued(evt); - } + Sample_Smoke() + { + mInfo["Title"] = "Smoke"; + mInfo["Description"] = "Demonstrates depth-sorting of particles in particle systems."; + mInfo["Thumbnail"] = "thumb_smoke.png"; + mInfo["Category"] = "Effects"; + } + + bool frameRenderingQueued(const FrameEvent& evt) + { + // spin the head around and make it float up and down + mPivot->setPosition(0, Math::Sin(mRoot->getTimer()->getMilliseconds() / 150.0) * 10, 0); + mPivot->yaw(Radian(-evt.timeSinceLastFrame * 1.5)); + return SdkSample::frameRenderingQueued(evt); + } protected: - void setupContent() - { + void setupContent() + { - mSceneMgr->setSkyBox(true, "Examples/EveningSkyBox"); + mSceneMgr->setSkyBox(true, "Examples/EveningSkyBox"); - // dim orange ambient and two bright orange lights to match the skybox - mSceneMgr->setAmbientLight(ColourValue(0.3, 0.2, 0)); - Light* light = mSceneMgr->createLight(); - light->setPosition(2000, 1000, -1000); - light->setDiffuseColour(1, 0.5, 0); - light = mSceneMgr->createLight(); + // dim orange ambient and two bright orange lights to match the skybox + mSceneMgr->setAmbientLight(ColourValue(0.3, 0.2, 0)); + Light* light = mSceneMgr->createLight(); + light->setPosition(2000, 1000, -1000); + light->setDiffuseColour(1, 0.5, 0); + light = mSceneMgr->createLight(); light->setPosition(-2000, 1000, 1000); - light->setDiffuseColour(1, 0.5, 0); + light->setDiffuseColour(1, 0.5, 0); - mPivot = mSceneMgr->getRootSceneNode()->createChildSceneNode(); // create a pivot node + mPivot = mSceneMgr->getRootSceneNode()->createChildSceneNode(); // create a pivot node - // create a child node and attach an ogre head and some smoke to it - SceneNode* headNode = mPivot->createChildSceneNode(Vector3(100, 0, 0)); - headNode->attachObject(mSceneMgr->createEntity("Head", "ogrehead.mesh")); + // create a child node and attach an ogre head and some smoke to it + SceneNode* headNode = mPivot->createChildSceneNode(Vector3(100, 0, 0)); + headNode->attachObject(mSceneMgr->createEntity("Head", "ogrehead.mesh")); headNode->attachObject(mSceneMgr->createParticleSystem("Smoke", "Examples/Smoke")); - mCamera->setPosition(0, 30, 350); - } + mCamera->setPosition(0, 30, 350); + } - SceneNode* mPivot; + SceneNode* mPivot; }; #endif diff --git a/Samples/Smoke/src/Smoke.cpp b/Samples/Smoke/src/Smoke.cpp index fbeae042c39..ba53aec5258 100644 --- a/Samples/Smoke/src/Smoke.cpp +++ b/Samples/Smoke/src/Smoke.cpp @@ -12,16 +12,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Smoke; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Smoke; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/SphereMapping/include/SphereMapping.h b/Samples/SphereMapping/include/SphereMapping.h index 709b51451c5..aba6a492ba7 100644 --- a/Samples/SphereMapping/include/SphereMapping.h +++ b/Samples/SphereMapping/include/SphereMapping.h @@ -14,34 +14,34 @@ class _OgreSampleClassExport Sample_SphereMapping : public SdkSample { public: - Sample_SphereMapping() - { - mInfo["Title"] = "Sphere Mapping"; - mInfo["Description"] = "Shows the sphere mapping feature of materials. " - "Sphere maps are not wrapped, and look the same from all directions."; - mInfo["Thumbnail"] = "thumb_spheremap.png"; - mInfo["Category"] = "Unsorted"; - } + Sample_SphereMapping() + { + mInfo["Title"] = "Sphere Mapping"; + mInfo["Description"] = "Shows the sphere mapping feature of materials. " + "Sphere maps are not wrapped, and look the same from all directions."; + mInfo["Thumbnail"] = "thumb_spheremap.png"; + mInfo["Category"] = "Unsorted"; + } protected: - void setupContent() - { - mViewport->setBackgroundColour(ColourValue::White); + void setupContent() + { + mViewport->setBackgroundColour(ColourValue::White); - // setup some basic lighting for our scene - mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); + // setup some basic lighting for our scene + mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); mSceneMgr->createLight()->setPosition(20, 80, 50); - // set our camera to orbit around the origin and show cursor - mCameraMan->setStyle(CS_ORBIT); - mTrayMgr->showCursor(); + // set our camera to orbit around the origin and show cursor + mCameraMan->setStyle(CS_ORBIT); + mTrayMgr->showCursor(); - // create our model, give it the environment mapped material, and place it at the origin + // create our model, give it the environment mapped material, and place it at the origin Entity *ent = mSceneMgr->createEntity("Head", "ogrehead.mesh"); - ent->setMaterialName("Examples/SphereMappedRustySteel"); - mSceneMgr->getRootSceneNode()->attachObject(ent); - } + ent->setMaterialName("Examples/SphereMappedRustySteel"); + mSceneMgr->getRootSceneNode()->attachObject(ent); + } }; #endif diff --git a/Samples/SphereMapping/src/SphereMapping.cpp b/Samples/SphereMapping/src/SphereMapping.cpp index 3d0beac74ca..066a619e3a4 100644 --- a/Samples/SphereMapping/src/SphereMapping.cpp +++ b/Samples/SphereMapping/src/SphereMapping.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_SphereMapping; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_SphereMapping; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Terrain/include/Terrain.h b/Samples/Terrain/include/Terrain.h index 71176e2d73e..8f28e6f1368 100644 --- a/Samples/Terrain/include/Terrain.h +++ b/Samples/Terrain/include/Terrain.h @@ -756,10 +756,10 @@ class _OgreSampleClassExport Sample_Terrain : public SdkSample mTerrainGlobals = OGRE_NEW TerrainGlobalOptions(); - // Bugfix for D3D11 Render System because of pixel format incompatibility when using - // vertex compression - if (Ogre::Root::getSingleton().getRenderSystem()->getName() == "Direct3D11 Rendering Subsystem") - mTerrainGlobals->setUseVertexCompressionWhenAvailable(false); + // Bugfix for D3D11 Render System because of pixel format incompatibility when using + // vertex compression + if (Ogre::Root::getSingleton().getRenderSystem()->getName() == "Direct3D11 Rendering Subsystem") + mTerrainGlobals->setUseVertexCompressionWhenAvailable(false); mEditMarker = mSceneMgr->createEntity("editMarker", "sphere.mesh"); mEditNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); @@ -794,7 +794,7 @@ class _OgreSampleClassExport Sample_Terrain : public SdkSample mTerrainGroup->setFilenameConvention(TERRAIN_FILE_PREFIX, TERRAIN_FILE_SUFFIX); mTerrainGroup->setOrigin(mTerrainPos); mTerrainGroup->setResourceGroup("Terrain"); - + configureTerrainDefaults(l); #ifdef PAGING // Paging setup @@ -857,7 +857,7 @@ class _OgreSampleClassExport Sample_Terrain : public SdkSample sn->attachObject(e); mHouseList.push_back(e); - mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000); + mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000); } diff --git a/Samples/Terrain/src/Terrain.cpp b/Samples/Terrain/src/Terrain.cpp index 7ba3f01386c..79e30ae21d6 100644 --- a/Samples/Terrain/src/Terrain.cpp +++ b/Samples/Terrain/src/Terrain.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Terrain; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Terrain; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/TerrainTessellation/include/TerrainTessellation.h b/Samples/TerrainTessellation/include/TerrainTessellation.h index 946b0c7ce23..6ca20c96569 100644 --- a/Samples/TerrainTessellation/include/TerrainTessellation.h +++ b/Samples/TerrainTessellation/include/TerrainTessellation.h @@ -42,319 +42,319 @@ class _OgreSampleClassExport Sample_TerrainTessellation : public SdkSample { public: - Sample_TerrainTessellation() - : mTerrainGroup(0) - , mTerrainPaging(0) - , mPageManager(0) - //, mFallVelocity(0) - //, mMode(MODE_NORMAL) - //, mLayerEdit(1) - //, mBrushSizeTerrainSpace(0.02) - //, mHeightUpdateCountDown(0) - , mTerrainsImported(false) + Sample_TerrainTessellation() + : mTerrainGroup(0) + , mTerrainPaging(0) + , mPageManager(0) + //, mFallVelocity(0) + //, mMode(MODE_NORMAL) + //, mLayerEdit(1) + //, mBrushSizeTerrainSpace(0.02) + //, mHeightUpdateCountDown(0) + , mTerrainsImported(false) , mFly(false) , mTerrainPos(1,1,1) - { - mInfo["Title"] = "TerrainTessellation"; - mInfo["Description"] = "Sample for terrain tessellation and the use of displacement mapping"; - mInfo["Thumbnail"] = "thumb_tesselation.png"; - mInfo["Category"] = "Unsorted"; - mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; - } - - void testCapabilities(const RenderSystemCapabilities* caps) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "This sample is not yet finished." - " Sorry!", "Sample_TerrainTessellation::testCapabilities"); - - if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" - " programs, so you cannot run this sample. Sorry!", "Sample_TerrainTessellation::testCapabilities"); - } - if (!caps->hasCapability(RSC_TESSELLATION_HULL_PROGRAM) || !caps->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) - { - OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Your graphics card does not support tesselation shaders. Sorry!", - "Sample_TerrainTessellation:testCapabilities"); - } - if (!GpuProgramManager::getSingleton().isSyntaxSupported("vs_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("hs_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ds_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("ps_5_0") && - !GpuProgramManager::getSingleton().isSyntaxSupported("hlsl")) - { - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model 5.0 needed for this sample, " - "so you cannot run this sample. Sorry!", "Sample_TerrainTessellation::testCapabilities"); - } - } - - bool frameRenderingQueued(const FrameEvent& evt) - { - if (!mFly) - { - // clamp to terrain - Vector3 camPos = mCamera->getPosition(); - Ray ray; - ray.setOrigin(Vector3(camPos.x, mTerrainPos.y + 10000, camPos.z)); - ray.setDirection(Vector3::NEGATIVE_UNIT_Y); - - TerrainGroup::RayResult rayResult = mTerrainGroup->rayIntersects(ray); - const Real distanceAboveTerrain = 50; - if (rayResult.hit) - mCamera->setPosition(camPos.x, rayResult.position.y + distanceAboveTerrain, camPos.z); - } - - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! - } - - void checkBoxToggled(CheckBox* box) - { - if (box->getName() == "Wire") - { - if( mCamera->getPolygonMode() == PM_WIREFRAME ) - mCamera->setPolygonMode(PM_SOLID); - else - mCamera->setPolygonMode(PM_WIREFRAME); - } - if (box->getName() == "Tessellation") - { - // disable tessellation - } - if (box == mFlyBox) - { - mFly = mFlyBox->isChecked(); - } - } - - void sliderMoved(Slider* slider) - { - if (slider->getName() == "tessellationAmount") - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_tessellationAmount", slider->getValue() ); - } - if (slider->getName() == "ridgeOctaves") - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_ridgeOctaves", slider->getValue() ); - } - if (slider->getName() == "fBmOctaves") - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_fBmOctaves", slider->getValue() ); - } - if (slider->getName() == "TwistOctaves") - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_TwistOctaves", slider->getValue() ); - } - if (slider->getName() == "detailNoiseScale") - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_detailNoiseScale", slider->getValue() ); - } - if (slider->getName() == "targetTrianglesWidth") - { - MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); - lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_targetTrianglesWidth", slider->getValue() ); - } - } + { + mInfo["Title"] = "TerrainTessellation"; + mInfo["Description"] = "Sample for terrain tessellation and the use of displacement mapping"; + mInfo["Thumbnail"] = "thumb_tesselation.png"; + mInfo["Category"] = "Unsorted"; + mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; + } + + void testCapabilities(const RenderSystemCapabilities* caps) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "This sample is not yet finished." + " Sorry!", "Sample_TerrainTessellation::testCapabilities"); + + if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !caps->hasCapability(RSC_FRAGMENT_PROGRAM)) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your graphics card does not support vertex and fragment" + " programs, so you cannot run this sample. Sorry!", "Sample_TerrainTessellation::testCapabilities"); + } + if (!caps->hasCapability(RSC_TESSELLATION_HULL_PROGRAM) || !caps->hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM)) + { + OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "Your graphics card does not support tesselation shaders. Sorry!", + "Sample_TerrainTessellation:testCapabilities"); + } + if (!GpuProgramManager::getSingleton().isSyntaxSupported("vs_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("hs_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ds_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("ps_5_0") && + !GpuProgramManager::getSingleton().isSyntaxSupported("hlsl")) + { + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support the shader model 5.0 needed for this sample, " + "so you cannot run this sample. Sorry!", "Sample_TerrainTessellation::testCapabilities"); + } + } + + bool frameRenderingQueued(const FrameEvent& evt) + { + if (!mFly) + { + // clamp to terrain + Vector3 camPos = mCamera->getPosition(); + Ray ray; + ray.setOrigin(Vector3(camPos.x, mTerrainPos.y + 10000, camPos.z)); + ray.setDirection(Vector3::NEGATIVE_UNIT_Y); + + TerrainGroup::RayResult rayResult = mTerrainGroup->rayIntersects(ray); + const Real distanceAboveTerrain = 50; + if (rayResult.hit) + mCamera->setPosition(camPos.x, rayResult.position.y + distanceAboveTerrain, camPos.z); + } + + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + } + + void checkBoxToggled(CheckBox* box) + { + if (box->getName() == "Wire") + { + if( mCamera->getPolygonMode() == PM_WIREFRAME ) + mCamera->setPolygonMode(PM_SOLID); + else + mCamera->setPolygonMode(PM_WIREFRAME); + } + if (box->getName() == "Tessellation") + { + // disable tessellation + } + if (box == mFlyBox) + { + mFly = mFlyBox->isChecked(); + } + } + + void sliderMoved(Slider* slider) + { + if (slider->getName() == "tessellationAmount") + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_tessellationAmount", slider->getValue() ); + } + if (slider->getName() == "ridgeOctaves") + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_ridgeOctaves", slider->getValue() ); + } + if (slider->getName() == "fBmOctaves") + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_fBmOctaves", slider->getValue() ); + } + if (slider->getName() == "TwistOctaves") + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_TwistOctaves", slider->getValue() ); + } + if (slider->getName() == "detailNoiseScale") + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_detailNoiseScale", slider->getValue() ); + } + if (slider->getName() == "targetTrianglesWidth") + { + MaterialPtr lMaterialPtr = MaterialManager::getSingleton().getByName( "TerrainTessellation" ).staticCast(); + lMaterialPtr->getTechnique(0)->getPass(0)->getTessellationHullProgramParameters()->setNamedConstant( "g_targetTrianglesWidth", slider->getValue() ); + } + } protected: - void configureTerrainDefaults(Light* l) - { - // Configure global - mTerrainGlobals->setMaxPixelError(8); - // testing composite map - mTerrainGlobals->setCompositeMapDistance(3000); - //mTerrainGlobals->setUseRayBoxDistanceCalculation(true); - mTerrainGlobals->getDefaultMaterialGenerator()->setLightmapEnabled(false); - - mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight()); - //mTerrainGlobals->setCompositeMapAmbient(ColourValue::Red); - mTerrainGlobals->setCompositeMapDiffuse(l->getDiffuseColour()); - - // Configure default import settings for if we use imported image - Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings(); - defaultimp.terrainSize = TERRAIN_SIZE; - defaultimp.worldSize = TERRAIN_WORLD_SIZE; - defaultimp.inputScale = 600; - defaultimp.minBatchSize = 33; - defaultimp.maxBatchSize = 65; - // textures - defaultimp.layerList.resize(3); - defaultimp.layerList[0].worldSize = 100; - defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds"); - defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds"); - defaultimp.layerList[1].worldSize = 30; - defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds"); - defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds"); - defaultimp.layerList[2].worldSize = 200; - defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds"); - defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds"); - - // Init custom materialgenerator - TerrainMaterialGeneratorPtr terrainMaterialGenerator; - - // Set Ogre Material with the name "TerrainMaterial" in constructor - TerrainTessellationMaterialGenerator *terrainMaterial = OGRE_NEW TerrainTessellationMaterialGenerator("Ogre/TerrainTessellation/Terrain"); - terrainMaterialGenerator.bind( terrainMaterial ); - - mTerrainGlobals->setDefaultMaterialGenerator( terrainMaterialGenerator ); - } - - void setupContent() - { - // create our main node to attach our entities to - mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000); // set our skybox - - setupLights(); - setupControls(); - - // set our camera - mCamera->setFOVy(Ogre::Degree(50.0)); - mCamera->setFOVy(Ogre::Degree(50.0)); - mCamera->setNearClipDistance(0.01f); - mCamera->lookAt(Ogre::Vector3::ZERO); - mCamera->setPosition(0, 0, 500); - mCameraMan->setTopSpeed(100); - - setDragLook(true); - - // Set our camera to orbit around the origin at a suitable distance - mCameraMan->setStyle(CS_ORBIT); - mCameraMan->setYawPitchDist(Radian(0), Radian(0), 400); - - MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); - MaterialManager::getSingleton().setDefaultAnisotropy(7); - - mSceneMgr->setFog(FOG_LINEAR, ColourValue(0.7, 0.7, 0.8), 0, 4000, 10000); - - mTrayMgr->showCursor(); - - mTerrainGlobals = OGRE_NEW TerrainGlobalOptions(); - - mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, TERRAIN_WORLD_SIZE); - mTerrainGroup->setFilenameConvention(TERRAIN_FILE_PREFIX, TERRAIN_FILE_SUFFIX); - mTerrainGroup->setOrigin(mTerrainPos); - mTerrainGroup->setAutoUpdateLod( TerrainAutoUpdateLodFactory::getAutoUpdateLod(BY_DISTANCE) ); // probably will do it in tessellation stages. - - Vector3 lightdir(0.55, -0.3, 0.75); - lightdir.normalise(); - - Light* l = mSceneMgr->createLight("tstLight"); - l->setType(Light::LT_DIRECTIONAL); - l->setDirection(lightdir); - l->setDiffuseColour(ColourValue::White); - l->setSpecularColour(ColourValue(0.4, 0.4, 0.4)); - - configureTerrainDefaults(l); - - mTerrainGroup->freeTemporaryResources(); - } - - void unloadResources() - { - - } - - void setupView() - { - SdkSample::setupView(); - // put camera at world center, so that it's difficult to reach the edge - Vector3 worldCenter(0,0,0); - mCamera->setPosition(mTerrainPos+worldCenter); - mCamera->lookAt(mTerrainPos); - mCamera->setNearClipDistance(0.1); - mCamera->setFarClipDistance(50000); - - if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)) + void configureTerrainDefaults(Light* l) + { + // Configure global + mTerrainGlobals->setMaxPixelError(8); + // testing composite map + mTerrainGlobals->setCompositeMapDistance(3000); + //mTerrainGlobals->setUseRayBoxDistanceCalculation(true); + mTerrainGlobals->getDefaultMaterialGenerator()->setLightmapEnabled(false); + + mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight()); + //mTerrainGlobals->setCompositeMapAmbient(ColourValue::Red); + mTerrainGlobals->setCompositeMapDiffuse(l->getDiffuseColour()); + + // Configure default import settings for if we use imported image + Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings(); + defaultimp.terrainSize = TERRAIN_SIZE; + defaultimp.worldSize = TERRAIN_WORLD_SIZE; + defaultimp.inputScale = 600; + defaultimp.minBatchSize = 33; + defaultimp.maxBatchSize = 65; + // textures + defaultimp.layerList.resize(3); + defaultimp.layerList[0].worldSize = 100; + defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds"); + defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds"); + defaultimp.layerList[1].worldSize = 30; + defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds"); + defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds"); + defaultimp.layerList[2].worldSize = 200; + defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds"); + defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds"); + + // Init custom materialgenerator + TerrainMaterialGeneratorPtr terrainMaterialGenerator; + + // Set Ogre Material with the name "TerrainMaterial" in constructor + TerrainTessellationMaterialGenerator *terrainMaterial = OGRE_NEW TerrainTessellationMaterialGenerator("Ogre/TerrainTessellation/Terrain"); + terrainMaterialGenerator.bind( terrainMaterial ); + + mTerrainGlobals->setDefaultMaterialGenerator( terrainMaterialGenerator ); + } + + void setupContent() + { + // create our main node to attach our entities to + mObjectNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000); // set our skybox + + setupLights(); + setupControls(); + + // set our camera + mCamera->setFOVy(Ogre::Degree(50.0)); + mCamera->setFOVy(Ogre::Degree(50.0)); + mCamera->setNearClipDistance(0.01f); + mCamera->lookAt(Ogre::Vector3::ZERO); + mCamera->setPosition(0, 0, 500); + mCameraMan->setTopSpeed(100); + + setDragLook(true); + + // Set our camera to orbit around the origin at a suitable distance + mCameraMan->setStyle(CS_ORBIT); + mCameraMan->setYawPitchDist(Radian(0), Radian(0), 400); + + MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); + MaterialManager::getSingleton().setDefaultAnisotropy(7); + + mSceneMgr->setFog(FOG_LINEAR, ColourValue(0.7, 0.7, 0.8), 0, 4000, 10000); + + mTrayMgr->showCursor(); + + mTerrainGlobals = OGRE_NEW TerrainGlobalOptions(); + + mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, TERRAIN_WORLD_SIZE); + mTerrainGroup->setFilenameConvention(TERRAIN_FILE_PREFIX, TERRAIN_FILE_SUFFIX); + mTerrainGroup->setOrigin(mTerrainPos); + mTerrainGroup->setAutoUpdateLod( TerrainAutoUpdateLodFactory::getAutoUpdateLod(BY_DISTANCE) ); // probably will do it in tessellation stages. + + Vector3 lightdir(0.55, -0.3, 0.75); + lightdir.normalise(); + + Light* l = mSceneMgr->createLight("tstLight"); + l->setType(Light::LT_DIRECTIONAL); + l->setDirection(lightdir); + l->setDiffuseColour(ColourValue::White); + l->setSpecularColour(ColourValue(0.4, 0.4, 0.4)); + + configureTerrainDefaults(l); + + mTerrainGroup->freeTemporaryResources(); + } + + void unloadResources() + { + + } + + void setupView() + { + SdkSample::setupView(); + // put camera at world center, so that it's difficult to reach the edge + Vector3 worldCenter(0,0,0); + mCamera->setPosition(mTerrainPos+worldCenter); + mCamera->lookAt(mTerrainPos); + mCamera->setNearClipDistance(0.1); + mCamera->setFarClipDistance(50000); + + if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)) { mCamera->setFarClipDistance(0); // enable infinite far clip distance if we can } - } - - void setupLights() - { - mSceneMgr->setAmbientLight(ColourValue::Black); - mViewport->setBackgroundColour(ColourValue(0.41f, 0.41f, 0.41f)); - } - - void setupControls() - { - mTrayMgr->showCursor(); - - // make room for the controls - mTrayMgr->showLogo(TL_TOPRIGHT); - mTrayMgr->showFrameStats(TL_TOPRIGHT); - mTrayMgr->toggleAdvancedFrameStats(); - - mTrayMgr->createCheckBox(TL_TOPLEFT, "Wire", "Wire Frame")->setChecked(false, false); - mTrayMgr->createCheckBox(TL_TOPLEFT, "Tessellation", "Hardware Tessellation")->setChecked(true, false); - - mTessellationAmount = mTrayMgr->createThickSlider(TL_TOPLEFT, "tessellationAmount", "Tessellation Amount", 200, 40, 1, 8, 8); - mTessellationAmount->show(); - - mRidgeOctaves = mTrayMgr->createThickSlider(TL_TOPLEFT, "ridgeOctaves", "Ridge Octaves", 200, 40, 0, 15, 15); - mRidgeOctaves->show(); - - mfBmOctaves = mTrayMgr->createThickSlider(TL_TOPLEFT, "fBmOctaves", "fBm Octaves", 200, 40, 0, 15, 15); - mfBmOctaves->show(); - - mTwistOctaves = mTrayMgr->createThickSlider(TL_TOPLEFT, "TwistOctaves", "Twist Octaves", 200, 40, 0, 15, 15); - mTwistOctaves->show(); - - mDetailNoiseScale = mTrayMgr->createThickSlider(TL_TOPLEFT, "detailNoiseScale", "Detail noise scale", 200, 40, 0, 2.0, 200); - mDetailNoiseScale->show(); - - mTargetTrianglesWidth = mTrayMgr->createThickSlider(TL_TOPLEFT, "targetTrianglesWidth", "Target triangles width", 200, 40, 1, 50, 50); - mTargetTrianglesWidth->show(); - - mFlyBox = mTrayMgr->createCheckBox(TL_BOTTOM, "Fly", "Fly"); - mFlyBox->setChecked(false, true); - - // a friendly reminder - StringVector names; - names.push_back("Help"); - mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); - } - - void cleanupContent() - { - // clean up properly to avoid interfering with subsequent samples - if (mPaging) - { - OGRE_DELETE mTerrainPaging; - OGRE_DELETE mPageManager; - } - else - OGRE_DELETE mTerrainGroup; - - OGRE_DELETE mTerrainGlobals; - } - - SceneNode* mObjectNode; - Slider* mTessellationAmount; - Slider* mRidgeOctaves; - Slider* mfBmOctaves; - Slider* mTwistOctaves; - Slider* mDetailNoiseScale; - Slider* mTargetTrianglesWidth; - CheckBox* mFlyBox; - - TerrainGlobalOptions* mTerrainGlobals; - TerrainGroup* mTerrainGroup; - bool mPaging; - TerrainPaging* mTerrainPaging; - PageManager* mPageManager; - - bool mTerrainsImported; - - bool mFly; - Vector3 mTerrainPos; - + } + + void setupLights() + { + mSceneMgr->setAmbientLight(ColourValue::Black); + mViewport->setBackgroundColour(ColourValue(0.41f, 0.41f, 0.41f)); + } + + void setupControls() + { + mTrayMgr->showCursor(); + + // make room for the controls + mTrayMgr->showLogo(TL_TOPRIGHT); + mTrayMgr->showFrameStats(TL_TOPRIGHT); + mTrayMgr->toggleAdvancedFrameStats(); + + mTrayMgr->createCheckBox(TL_TOPLEFT, "Wire", "Wire Frame")->setChecked(false, false); + mTrayMgr->createCheckBox(TL_TOPLEFT, "Tessellation", "Hardware Tessellation")->setChecked(true, false); + + mTessellationAmount = mTrayMgr->createThickSlider(TL_TOPLEFT, "tessellationAmount", "Tessellation Amount", 200, 40, 1, 8, 8); + mTessellationAmount->show(); + + mRidgeOctaves = mTrayMgr->createThickSlider(TL_TOPLEFT, "ridgeOctaves", "Ridge Octaves", 200, 40, 0, 15, 15); + mRidgeOctaves->show(); + + mfBmOctaves = mTrayMgr->createThickSlider(TL_TOPLEFT, "fBmOctaves", "fBm Octaves", 200, 40, 0, 15, 15); + mfBmOctaves->show(); + + mTwistOctaves = mTrayMgr->createThickSlider(TL_TOPLEFT, "TwistOctaves", "Twist Octaves", 200, 40, 0, 15, 15); + mTwistOctaves->show(); + + mDetailNoiseScale = mTrayMgr->createThickSlider(TL_TOPLEFT, "detailNoiseScale", "Detail noise scale", 200, 40, 0, 2.0, 200); + mDetailNoiseScale->show(); + + mTargetTrianglesWidth = mTrayMgr->createThickSlider(TL_TOPLEFT, "targetTrianglesWidth", "Target triangles width", 200, 40, 1, 50, 50); + mTargetTrianglesWidth->show(); + + mFlyBox = mTrayMgr->createCheckBox(TL_BOTTOM, "Fly", "Fly"); + mFlyBox->setChecked(false, true); + + // a friendly reminder + StringVector names; + names.push_back("Help"); + mTrayMgr->createParamsPanel(TL_TOPLEFT, "Help", 100, names)->setParamValue(0, "H/F1"); + } + + void cleanupContent() + { + // clean up properly to avoid interfering with subsequent samples + if (mPaging) + { + OGRE_DELETE mTerrainPaging; + OGRE_DELETE mPageManager; + } + else + OGRE_DELETE mTerrainGroup; + + OGRE_DELETE mTerrainGlobals; + } + + SceneNode* mObjectNode; + Slider* mTessellationAmount; + Slider* mRidgeOctaves; + Slider* mfBmOctaves; + Slider* mTwistOctaves; + Slider* mDetailNoiseScale; + Slider* mTargetTrianglesWidth; + CheckBox* mFlyBox; + + TerrainGlobalOptions* mTerrainGlobals; + TerrainGroup* mTerrainGroup; + bool mPaging; + TerrainPaging* mTerrainPaging; + PageManager* mPageManager; + + bool mTerrainsImported; + + bool mFly; + Vector3 mTerrainPos; + }; #endif \ No newline at end of file diff --git a/Samples/TerrainTessellation/include/TerrainTessellationMaterialGenerator.h b/Samples/TerrainTessellation/include/TerrainTessellationMaterialGenerator.h index 13df4087bb7..990b94a75e4 100644 --- a/Samples/TerrainTessellation/include/TerrainTessellationMaterialGenerator.h +++ b/Samples/TerrainTessellation/include/TerrainTessellationMaterialGenerator.h @@ -55,13 +55,13 @@ class TerrainTessellationMaterialGenerator : public TerrainMaterialGenerator void requestOptions(Terrain* terrain); - bool isLightmapEnabled() const { return mLightmapEnabled; } - /** Whether to support a light map over the terrain in the shader, - if it's present (default true). - */ - void setLightmapEnabled(bool enabled); + bool isLightmapEnabled() const { return mLightmapEnabled; } + /** Whether to support a light map over the terrain in the shader, + if it's present (default true). + */ + void setLightmapEnabled(bool enabled); - bool mLightmapEnabled; + bool mLightmapEnabled; }; protected: Ogre::String mMaterialName; diff --git a/Samples/TerrainTessellation/src/TerrainTessellation.cpp b/Samples/TerrainTessellation/src/TerrainTessellation.cpp index 3f22970c6af..38e2f056e7d 100644 --- a/Samples/TerrainTessellation/src/TerrainTessellation.cpp +++ b/Samples/TerrainTessellation/src/TerrainTessellation.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_TerrainTessellation; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_TerrainTessellation; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/TerrainTessellation/src/TerrainTessellationMaterialGenerator.cpp b/Samples/TerrainTessellation/src/TerrainTessellationMaterialGenerator.cpp index 31a96c9285d..98ed2b9ca43 100644 --- a/Samples/TerrainTessellation/src/TerrainTessellationMaterialGenerator.cpp +++ b/Samples/TerrainTessellation/src/TerrainTessellationMaterialGenerator.cpp @@ -26,23 +26,23 @@ same license as the rest of the engine. using namespace Ogre; TerrainTessellationMaterialGenerator::TerrainTessellationMaterialGenerator(Ogre::String materialName, bool addNormalmap, bool cloneMaterial) - : mMaterialName(materialName) - , mCloneMaterial(cloneMaterial) + : mMaterialName(materialName) + , mCloneMaterial(cloneMaterial) , mAddNormalMap(addNormalmap) { - mProfiles.push_back(OGRE_NEW Profile(this, materialName, "Profile for rendering Ogre standard material")); - setActiveProfile(materialName); + mProfiles.push_back(OGRE_NEW Profile(this, materialName, "Profile for rendering Ogre standard material")); + setActiveProfile(materialName); } // ----------------------------------------------------------------------------------------------------------------------- void TerrainTessellationMaterialGenerator::setMaterialByName(const Ogre::String materialName) { - mMaterialName = materialName; - _markChanged(); + mMaterialName = materialName; + _markChanged(); } // ----------------------------------------------------------------------------------------------------------------------- TerrainTessellationMaterialGenerator::Profile::Profile(TerrainMaterialGenerator* parent, const Ogre::String& name, const Ogre::String& desc) - : TerrainMaterialGenerator::Profile(parent, name, desc) - , mLightmapEnabled(false) + : TerrainMaterialGenerator::Profile(parent, name, desc) + , mLightmapEnabled(false) { } @@ -54,48 +54,48 @@ TerrainTessellationMaterialGenerator::Profile::~Profile() // ----------------------------------------------------------------------------------------------------------------------- MaterialPtr TerrainTessellationMaterialGenerator::Profile::generate(const Terrain* terrain) { - const Ogre::String& matName = terrain->getMaterialName(); - MaterialPtr mat = MaterialManager::getSingleton().getByName( matName ).staticCast(); + const Ogre::String& matName = terrain->getMaterialName(); + MaterialPtr mat = MaterialManager::getSingleton().getByName( matName ).staticCast(); - if (!mat.isNull()) - MaterialManager::getSingleton().remove(matName); + if (!mat.isNull()) + MaterialManager::getSingleton().remove(matName); - TerrainTessellationMaterialGenerator* parent = (TerrainTessellationMaterialGenerator*)getParent(); - - // Set Ogre material - mat = MaterialManager::getSingleton().getByName( parent->mMaterialName ).staticCast(); + TerrainTessellationMaterialGenerator* parent = (TerrainTessellationMaterialGenerator*)getParent(); + + // Set Ogre material + mat = MaterialManager::getSingleton().getByName( parent->mMaterialName ).staticCast(); - // Clone material - if(parent->mCloneMaterial) - { - mat = mat->clone(matName); - parent->mMaterialName = matName; - } + // Clone material + if(parent->mCloneMaterial) + { + mat = mat->clone(matName); + parent->mMaterialName = matName; + } - // Add normalmap - if(parent->mAddNormalMap) - { - // Get default pass - Pass *p = mat->getTechnique(0)->getPass(0); + // Add normalmap + if(parent->mAddNormalMap) + { + // Get default pass + Pass *p = mat->getTechnique(0)->getPass(0); - // Add terrain's global normalmap to renderpass so the fragment program can find it. - TextureUnitState *tu = p->createTextureUnitState(matName+"/nm"); + // Add terrain's global normalmap to renderpass so the fragment program can find it. + TextureUnitState *tu = p->createTextureUnitState(matName+"/nm"); - TexturePtr nmtx = terrain->getTerrainNormalMap(); - tu->_setTexturePtr(nmtx); - } + TexturePtr nmtx = terrain->getTerrainNormalMap(); + tu->_setTexturePtr(nmtx); + } - return mat; + return mat; } // ----------------------------------------------------------------------------------------------------------------------- MaterialPtr TerrainTessellationMaterialGenerator::Profile::generateForCompositeMap(const Terrain* terrain) { - return terrain->_getCompositeMapMaterial(); + return terrain->_getCompositeMapMaterial(); } // ----------------------------------------------------------------------------------------------------------------------- Ogre::uint8 TerrainTessellationMaterialGenerator::Profile::getMaxLayers(const Terrain* terrain) const { - return 0; + return 0; } // ----------------------------------------------------------------------------------------------------------------------- void TerrainTessellationMaterialGenerator::Profile::updateParams(const MaterialPtr& mat, const Terrain* terrain) @@ -110,17 +110,17 @@ void TerrainTessellationMaterialGenerator::Profile::updateParamsForCompositeMap( // ----------------------------------------------------------------------------------------------------------------------- void TerrainTessellationMaterialGenerator::Profile::requestOptions(Terrain* terrain) { - terrain->_setMorphRequired(false); - terrain->_setNormalMapRequired(true); // enable global normal map - terrain->_setLightMapRequired(false); - terrain->_setCompositeMapRequired(false); + terrain->_setMorphRequired(false); + terrain->_setNormalMapRequired(true); // enable global normal map + terrain->_setLightMapRequired(false); + terrain->_setCompositeMapRequired(false); }; // ----------------------------------------------------------------------------------------------------------------------- void TerrainTessellationMaterialGenerator::Profile::setLightmapEnabled(bool enabled) { - if (enabled != mLightmapEnabled) - { - mLightmapEnabled = enabled; - mParent->_markChanged(); - } + if (enabled != mLightmapEnabled) + { + mLightmapEnabled = enabled; + mParent->_markChanged(); + } }; \ No newline at end of file diff --git a/Samples/Tessellation/src/Tessellation.cpp b/Samples/Tessellation/src/Tessellation.cpp index 86ea44af980..8b59a2b9fbb 100644 --- a/Samples/Tessellation/src/Tessellation.cpp +++ b/Samples/Tessellation/src/Tessellation.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Tessellation; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Tessellation; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/TextureArray/include/TextureArray.h b/Samples/TextureArray/include/TextureArray.h index 5dbcf4cf9c7..46828eec41f 100644 --- a/Samples/TextureArray/include/TextureArray.h +++ b/Samples/TextureArray/include/TextureArray.h @@ -11,24 +11,24 @@ class _OgreSampleClassExport Sample_TextureArray : public SdkSample { public: - Sample_TextureArray() - { - mInfo["Title"] = "Texture Array"; - mInfo["Description"] = "Demonstrates texture array support."; - mInfo["Thumbnail"] = "thumb_texarray.png"; - mInfo["Category"] = "Unsorted"; - mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; - } + Sample_TextureArray() + { + mInfo["Title"] = "Texture Array"; + mInfo["Description"] = "Demonstrates texture array support."; + mInfo["Thumbnail"] = "thumb_texarray.png"; + mInfo["Category"] = "Unsorted"; + mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; + } protected: StringVector getRequiredPlugins() - { - StringVector names; + { + StringVector names; if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl150")) names.push_back("Cg Program Manager"); - return names; - } + return names; + } void testCapabilities( const RenderSystemCapabilities* caps ) { @@ -52,16 +52,16 @@ class _OgreSampleClassExport Sample_TextureArray : public SdkSample } } - void setupContent() - { - mSceneMgr->setSkyBox(true, "Examples/TrippySkyBox"); + void setupContent() + { + mSceneMgr->setSkyBox(true, "Examples/TrippySkyBox"); - // set our camera to orbit around the origin and show cursor - mCameraMan->setStyle(CS_ORBIT); - mTrayMgr->showCursor(); + // set our camera to orbit around the origin and show cursor + mCameraMan->setStyle(CS_ORBIT); + mTrayMgr->showCursor(); - // the names of the textures we will use (all need to be the same size: 512*512 in our case) - vector::type texNames; + // the names of the textures we will use (all need to be the same size: 512*512 in our case) + vector::type texNames; texNames.push_back("BeachStones.jpg"); texNames.push_back("BumpyMetal.jpg"); texNames.push_back("egyptrockyfull.jpg"); @@ -93,8 +93,8 @@ class _OgreSampleClassExport Sample_TextureArray : public SdkSample // add all the textures to a 2d texture array - for (uint32 i = 0; i < static_cast(texNames.size()); i++) - { + for (uint32 i = 0; i < static_cast(texNames.size()); i++) + { Image terrainTex; terrainTex.load(texNames[i], ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); HardwarePixelBufferSharedPtr pixelBufferBuf = tex->getBuffer(0); @@ -109,38 +109,38 @@ class _OgreSampleClassExport Sample_TextureArray : public SdkSample texArrayMat->compile(); Pass * pass = texArrayMat->getBestTechnique()->getPass(0); pass->setLightingEnabled(false); - TextureUnitState* pState = pass->createTextureUnitState(); + TextureUnitState* pState = pass->createTextureUnitState(); pState->setTextureName(tex->getName(), TEX_TYPE_2D_ARRAY); // create a plane with float3 tex coord - the third value will be the texture index in our case - ManualObject* textureArrayObject = mSceneMgr->createManualObject("TextureAtlasObject"); + ManualObject* textureArrayObject = mSceneMgr->createManualObject("TextureAtlasObject"); // create a quad that uses our material int quadSize = 100; - textureArrayObject->begin(texArrayMat->getName(), RenderOperation::OT_TRIANGLE_LIST); - // triangle 0 of the quad - textureArrayObject->position(0, 0, 0); - textureArrayObject->textureCoord(0, 0, 0); - textureArrayObject->position(quadSize, 0, 0); - textureArrayObject->textureCoord(1, 0, 0); - textureArrayObject->position(quadSize, quadSize, 0); - textureArrayObject->textureCoord(1, 1, texNames.size()); - - // triangle 1 of the quad - textureArrayObject->position(0, 0, 0); - textureArrayObject->textureCoord(0, 0, 0); - textureArrayObject->position(quadSize, quadSize, 0); - textureArrayObject->textureCoord(1, 1, texNames.size()); - textureArrayObject->position(0, quadSize, 0); - textureArrayObject->textureCoord(0, 1, texNames.size()); - - textureArrayObject->end(); - - // attach it to a node and position appropriately - SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - node->setPosition(-quadSize / 2, -quadSize / 2, 0); - node->attachObject(textureArrayObject); - } + textureArrayObject->begin(texArrayMat->getName(), RenderOperation::OT_TRIANGLE_LIST); + // triangle 0 of the quad + textureArrayObject->position(0, 0, 0); + textureArrayObject->textureCoord(0, 0, 0); + textureArrayObject->position(quadSize, 0, 0); + textureArrayObject->textureCoord(1, 0, 0); + textureArrayObject->position(quadSize, quadSize, 0); + textureArrayObject->textureCoord(1, 1, texNames.size()); + + // triangle 1 of the quad + textureArrayObject->position(0, 0, 0); + textureArrayObject->textureCoord(0, 0, 0); + textureArrayObject->position(quadSize, quadSize, 0); + textureArrayObject->textureCoord(1, 1, texNames.size()); + textureArrayObject->position(0, quadSize, 0); + textureArrayObject->textureCoord(0, 1, texNames.size()); + + textureArrayObject->end(); + + // attach it to a node and position appropriately + SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + node->setPosition(-quadSize / 2, -quadSize / 2, 0); + node->attachObject(textureArrayObject); + } void cleanupContent() { diff --git a/Samples/TextureArray/src/TextureArray.cpp b/Samples/TextureArray/src/TextureArray.cpp index 20790c171be..26ed7175723 100644 --- a/Samples/TextureArray/src/TextureArray.cpp +++ b/Samples/TextureArray/src/TextureArray.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_TextureArray; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_TextureArray; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/TextureFX/include/TextureFX.h b/Samples/TextureFX/include/TextureFX.h index 02f57f7426b..deeaebfdd85 100644 --- a/Samples/TextureFX/include/TextureFX.h +++ b/Samples/TextureFX/include/TextureFX.h @@ -10,42 +10,42 @@ class _OgreSampleClassExport Sample_TextureFX : public SdkSample { public: - Sample_TextureFX() - { - mInfo["Title"] = "Texture Effects"; - mInfo["Description"] = "Demonstrates OGRE's many different animated texture effects."; - mInfo["Thumbnail"] = "thumb_texfx.png"; - mInfo["Category"] = "Unsorted"; - mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; - } + Sample_TextureFX() + { + mInfo["Title"] = "Texture Effects"; + mInfo["Description"] = "Demonstrates OGRE's many different animated texture effects."; + mInfo["Thumbnail"] = "thumb_texfx.png"; + mInfo["Category"] = "Unsorted"; + mInfo["Help"] = "Top Left: Multi-frame\nTop Right: Scrolling\nBottom Left: Rotation\nBottom Right: Scaling"; + } protected: - void setupContent() - { - mSceneMgr->setSkyBox(true, "Examples/TrippySkyBox"); + void setupContent() + { + mSceneMgr->setSkyBox(true, "Examples/TrippySkyBox"); - // set our camera to orbit around the origin and show cursor - mCameraMan->setStyle(CS_ORBIT); - mTrayMgr->showCursor(); + // set our camera to orbit around the origin and show cursor + mCameraMan->setStyle(CS_ORBIT); + mTrayMgr->showCursor(); - // the names of the four materials we will use - String matNames[] = {"Examples/OgreDance", "Examples/OgreParade", "Examples/OgreSpin", "Examples/OgreWobble"}; + // the names of the four materials we will use + String matNames[] = {"Examples/OgreDance", "Examples/OgreParade", "Examples/OgreSpin", "Examples/OgreWobble"}; - for (unsigned int i = 0; i < 4; i++) - { - // create a standard plane entity - Entity* ent = mSceneMgr->createEntity("Plane" + StringConverter::toString(i + 1), SceneManager::PT_PLANE); + for (unsigned int i = 0; i < 4; i++) + { + // create a standard plane entity + Entity* ent = mSceneMgr->createEntity("Plane" + StringConverter::toString(i + 1), SceneManager::PT_PLANE); - // attach it to a node, scale it, and position appropriately - SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - node->setPosition(i % 2 ? 25 : -25, i / 2 ? -25 : 25, 0); - node->setScale(0.25, 0.25, 0.25); - node->attachObject(ent); + // attach it to a node, scale it, and position appropriately + SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + node->setPosition(i % 2 ? 25 : -25, i / 2 ? -25 : 25, 0); + node->setScale(0.25, 0.25, 0.25); + node->attachObject(ent); - ent->setMaterialName(matNames[i]); // give it the material we prepared - } - } + ent->setMaterialName(matNames[i]); // give it the material we prepared + } + } }; #endif diff --git a/Samples/TextureFX/src/TextureFX.cpp b/Samples/TextureFX/src/TextureFX.cpp index 8adbef8599a..06ee74dbd3d 100644 --- a/Samples/TextureFX/src/TextureFX.cpp +++ b/Samples/TextureFX/src/TextureFX.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_TextureFX; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_TextureFX; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Transparency/include/Transparency.h b/Samples/Transparency/include/Transparency.h index 4dce3c48f20..b4950917242 100644 --- a/Samples/Transparency/include/Transparency.h +++ b/Samples/Transparency/include/Transparency.h @@ -14,63 +14,63 @@ class _OgreSampleClassExport Sample_Transparency : public SdkSample { public: - Sample_Transparency() - { - mInfo["Title"] = "Transparency"; - mInfo["Description"] = "Demonstrates the use of transparent materials (or scene blending)."; - mInfo["Thumbnail"] = "thumb_trans.png"; - mInfo["Category"] = "Lighting"; - } + Sample_Transparency() + { + mInfo["Title"] = "Transparency"; + mInfo["Description"] = "Demonstrates the use of transparent materials (or scene blending)."; + mInfo["Thumbnail"] = "thumb_trans.png"; + mInfo["Category"] = "Lighting"; + } - bool frameRenderingQueued(const FrameEvent& evt) - { - Real theta = mRoot->getTimer()->getMilliseconds() / 1000.0f; + bool frameRenderingQueued(const FrameEvent& evt) + { + Real theta = mRoot->getTimer()->getMilliseconds() / 1000.0f; - // this is the equation for a PQ torus knot - Ogre::Real r = 28 * (2 + Math::Sin(theta * 3 / 2 + 0.2)); - Ogre::Real x = r * Math::Cos(theta); - Ogre::Real y = r * Math::Sin(theta); - Ogre::Real z = 60 * Math::Cos(theta * 3 / 2 + 0.2); + // this is the equation for a PQ torus knot + Ogre::Real r = 28 * (2 + Math::Sin(theta * 3 / 2 + 0.2)); + Ogre::Real x = r * Math::Cos(theta); + Ogre::Real y = r * Math::Sin(theta); + Ogre::Real z = 60 * Math::Cos(theta * 3 / 2 + 0.2); - Vector3 lastPos = mFishNode->getPosition(); // save fishy's last position - mFishNode->setPosition(x, y, z); // set fishy's new position + Vector3 lastPos = mFishNode->getPosition(); // save fishy's last position + mFishNode->setPosition(x, y, z); // set fishy's new position - // set fishy's direction based on the change in position - mFishNode->setDirection(mFishNode->getPosition() - lastPos, Node::TS_PARENT, Vector3::NEGATIVE_UNIT_X); + // set fishy's direction based on the change in position + mFishNode->setDirection(mFishNode->getPosition() - lastPos, Node::TS_PARENT, Vector3::NEGATIVE_UNIT_X); - mFishSwim->addTime(evt.timeSinceLastFrame * 5); // update fishy's swimming animation + mFishSwim->addTime(evt.timeSinceLastFrame * 5); // update fishy's swimming animation - return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! - } + return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates! + } protected: - void setupContent() - { - mSceneMgr->setSkyBox(true, "Examples/TrippySkyBox"); + void setupContent() + { + mSceneMgr->setSkyBox(true, "Examples/TrippySkyBox"); - mCamera->setPosition(0, 0, 300); // set camera's starting position + mCamera->setPosition(0, 0, 300); // set camera's starting position mSceneMgr->createLight()->setPosition(20, 80, 50); // add basic point light - // create a torus knot model, give it the translucent texture, and attach it to the origin - Entity* ent = mSceneMgr->createEntity("Knot", "knot.mesh"); + // create a torus knot model, give it the translucent texture, and attach it to the origin + Entity* ent = mSceneMgr->createEntity("Knot", "knot.mesh"); ent->setMaterialName("Examples/WaterStream"); - mSceneMgr->getRootSceneNode()->attachObject(ent); - - // create a fishy and enable its swimming animation - ent = mSceneMgr->createEntity("Fish", "fish.mesh"); - mFishSwim = ent->getAnimationState("swim"); - mFishSwim->setEnabled(true); - - // create a scene node, attach fishy to it, and scale it by a factor of 2 - mFishNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mFishNode->attachObject(ent); - mFishNode->setScale(2, 2, 2); - } - - SceneNode* mFishNode; - AnimationState* mFishSwim; + mSceneMgr->getRootSceneNode()->attachObject(ent); + + // create a fishy and enable its swimming animation + ent = mSceneMgr->createEntity("Fish", "fish.mesh"); + mFishSwim = ent->getAnimationState("swim"); + mFishSwim->setEnabled(true); + + // create a scene node, attach fishy to it, and scale it by a factor of 2 + mFishNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mFishNode->attachObject(ent); + mFishNode->setScale(2, 2, 2); + } + + SceneNode* mFishNode; + AnimationState* mFishSwim; }; #endif diff --git a/Samples/Transparency/src/Transparency.cpp b/Samples/Transparency/src/Transparency.cpp index 366293b2be7..a1eef1c22a1 100644 --- a/Samples/Transparency/src/Transparency.cpp +++ b/Samples/Transparency/src/Transparency.cpp @@ -11,16 +11,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Transparency; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Transparency; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/VolumeTex/include/Julia.h b/Samples/VolumeTex/include/Julia.h index b18ac50a7ce..54f2c7a223b 100644 --- a/Samples/VolumeTex/include/Julia.h +++ b/Samples/VolumeTex/include/Julia.h @@ -55,57 +55,57 @@ inline void qsqr(Quat &b, const Quat &a) */ class Julia { private: - float global_real, global_imag, global_theta; - Quat oc,c,eio,emio; + float global_real, global_imag, global_theta; + Quat oc,c,eio,emio; public: - Julia(float global_real, float global_imag, float global_theta); - inline float eval(float x, float y, float z) { - Quat q, temp; - int i; - - q.r = x; - q.i = y; - q.j = z; - q.k = 0.0; - - for (i = 30; i > 0; i--) { - qsqr(temp, q); - qmult(q, emio, temp); - qadd(q, c); - - if (q.r*q.r + q.i*q.i + q.j*q.j + q.k*q.k > 8.0) - break; - } - - return((float)i); - } + Julia(float global_real, float global_imag, float global_theta); + inline float eval(float x, float y, float z) { + Quat q, temp; + int i; + + q.r = x; + q.i = y; + q.j = z; + q.k = 0.0; + + for (i = 30; i > 0; i--) { + qsqr(temp, q); + qmult(q, emio, temp); + qadd(q, c); + + if (q.r*q.r + q.i*q.i + q.j*q.j + q.k*q.k > 8.0) + break; + } + + return((float)i); + } }; Julia::Julia(float in_global_real, float in_global_imag, float in_global_theta): - global_real(in_global_real), global_imag(in_global_imag), global_theta(in_global_theta) { + global_real(in_global_real), global_imag(in_global_imag), global_theta(in_global_theta) { - oc.r = global_real; - oc.i = global_imag; - oc.j = oc.k = 0.0; + oc.r = global_real; + oc.i = global_imag; + oc.j = oc.k = 0.0; - eio.r = cos(global_theta); - eio.i = sin(global_theta); - eio.j = 0.0; - eio.k = 0.0; + eio.r = cos(global_theta); + eio.i = sin(global_theta); + eio.j = 0.0; + eio.k = 0.0; - emio.r = cos(-global_theta); - emio.i = sin(-global_theta); - emio.j = 0.0; - emio.k = 0.0; + emio.r = cos(-global_theta); + emio.i = sin(-global_theta); + emio.j = 0.0; + emio.k = 0.0; - /*** - *** multiply eio*c only once at the beginning of iteration - *** (since q |-> sqrt(eio*(q-eio*c))) - *** q -> e-io*q^2 - eio*c - ***/ + /*** + *** multiply eio*c only once at the beginning of iteration + *** (since q |-> sqrt(eio*(q-eio*c))) + *** q -> e-io*q^2 - eio*c + ***/ - qmult(c, eio,oc); + qmult(c, eio,oc); } diff --git a/Samples/VolumeTex/include/ThingRenderable.h b/Samples/VolumeTex/include/ThingRenderable.h index 8ea5c6e2c28..f9cde660738 100644 --- a/Samples/VolumeTex/include/ThingRenderable.h +++ b/Samples/VolumeTex/include/ThingRenderable.h @@ -20,40 +20,40 @@ same license as the rest of the engine. #include "OgreVector3.h" /** Quad fragments that rotate around origin (0,0,0) in a random orbit, always oriented to 0,0,0. - @author W.J. van der Laan + @author W.J. van der Laan */ class ThingRenderable: public Ogre::SimpleRenderable { public: - /** Create one this object. - @param radius Radius of orbits - @param count Number of quads - @param qsize Size of quads - */ - ThingRenderable(float radius, size_t count, float qsize); - ~ThingRenderable(); - /** - * Retrieves ratios of the origin-centered bounding sphere for this - * object. - */ - Ogre::Real getBoundingRadius() const; - /** - * Returns the camera-relative squared depth of this renderable. - */ - Ogre::Real getSquaredViewDepth(const Ogre::Camera*) const; - /** - * Notify that t seconds have elapsed. - */ - void addTime(float t); + /** Create one this object. + @param radius Radius of orbits + @param count Number of quads + @param qsize Size of quads + */ + ThingRenderable(float radius, size_t count, float qsize); + ~ThingRenderable(); + /** + * Retrieves ratios of the origin-centered bounding sphere for this + * object. + */ + Ogre::Real getBoundingRadius() const; + /** + * Returns the camera-relative squared depth of this renderable. + */ + Ogre::Real getSquaredViewDepth(const Ogre::Camera*) const; + /** + * Notify that t seconds have elapsed. + */ + void addTime(float t); protected: - void initialise(); - void fillBuffer(); + void initialise(); + void fillBuffer(); - Ogre::HardwareVertexBufferSharedPtr vbuf;// Our vertex buffer - float mRadius; - size_t mCount; - float mQSize; - Ogre::vector ::type things; - Ogre::vector ::type orbits; + Ogre::HardwareVertexBufferSharedPtr vbuf;// Our vertex buffer + float mRadius; + size_t mCount; + float mQSize; + Ogre::vector ::type things; + Ogre::vector ::type orbits; }; #endif diff --git a/Samples/VolumeTex/include/VolumeRenderable.h b/Samples/VolumeTex/include/VolumeRenderable.h index 97473d03b9e..eb128793c5b 100644 --- a/Samples/VolumeTex/include/VolumeRenderable.h +++ b/Samples/VolumeTex/include/VolumeRenderable.h @@ -17,37 +17,37 @@ same license as the rest of the engine. #include "OgreSimpleRenderable.h" /** Direct Volume Rendering. - TODO: LOD: reduce number of slices in distance - TODO: option to generate normals for lighting - @author W.J. van der Laan + TODO: LOD: reduce number of slices in distance + TODO: option to generate normals for lighting + @author W.J. van der Laan */ class VolumeRenderable: public Ogre::SimpleRenderable { public: - VolumeRenderable(size_t nSlices, float size, const Ogre::String & texture); - ~VolumeRenderable(); - - // Copydoc Ogre::SimpleRenderable::notifyCurrentCamera - void _notifyCurrentCamera( Ogre::Camera* cam ); - void getWorldTransforms( Ogre::Matrix4* xform ) const; - - /** - * Retrieves ratios of the origin-centered bounding sphere for this - * object. - */ - Ogre::Real getBoundingRadius() const; - - /** - * Returns the camera-relative squared depth of this renderable. - */ - Ogre::Real getSquaredViewDepth(const Ogre::Camera*) const; + VolumeRenderable(size_t nSlices, float size, const Ogre::String & texture); + ~VolumeRenderable(); + + // Copydoc Ogre::SimpleRenderable::notifyCurrentCamera + void _notifyCurrentCamera( Ogre::Camera* cam ); + void getWorldTransforms( Ogre::Matrix4* xform ) const; + + /** + * Retrieves ratios of the origin-centered bounding sphere for this + * object. + */ + Ogre::Real getBoundingRadius() const; + + /** + * Returns the camera-relative squared depth of this renderable. + */ + Ogre::Real getSquaredViewDepth(const Ogre::Camera*) const; protected: - void initialise(); + void initialise(); - size_t mSlices; - float mSize; - float mRadius; - Ogre::Matrix3 mFakeOrientation; - Ogre::String mTexture; - Ogre::TextureUnitState *mUnit; + size_t mSlices; + float mSize; + float mRadius; + Ogre::Matrix3 mFakeOrientation; + Ogre::String mTexture; + Ogre::TextureUnitState *mUnit; }; #endif diff --git a/Samples/VolumeTex/src/ThingRenderable.cpp b/Samples/VolumeTex/src/ThingRenderable.cpp index 757fe7e80c1..568c44f2234 100644 --- a/Samples/VolumeTex/src/ThingRenderable.cpp +++ b/Samples/VolumeTex/src/ThingRenderable.cpp @@ -19,13 +19,13 @@ same license as the rest of the engine. using namespace Ogre; ThingRenderable::ThingRenderable(float radius, size_t count, float qsize): - mRadius(radius), - mCount(count), - mQSize(qsize) + mRadius(radius), + mCount(count), + mQSize(qsize) { - mBox = Ogre::AxisAlignedBox(-radius, -radius, -radius, radius, radius, radius); - initialise(); - fillBuffer(); + mBox = Ogre::AxisAlignedBox(-radius, -radius, -radius, radius, radius, radius); + initialise(); + fillBuffer(); } ThingRenderable::~ThingRenderable() { @@ -36,150 +36,150 @@ ThingRenderable::~ThingRenderable() void ThingRenderable::addTime(float t) { - for(size_t x=0; xvertexStart = 0; - vdata->vertexCount = nvertices; - - VertexDeclaration* decl = vdata->vertexDeclaration; - VertexBufferBinding* bind = vdata->vertexBufferBinding; + // Quads + unsigned short *faces = new unsigned short[mCount*6]; + for(x=0; xvertexStart = 0; + vdata->vertexCount = nvertices; + + VertexDeclaration* decl = vdata->vertexDeclaration; + VertexBufferBinding* bind = vdata->vertexBufferBinding; - size_t offset = 0; - decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); - offset += VertexElement::getTypeSize(VET_FLOAT3); + size_t offset = 0; + decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); + offset += VertexElement::getTypeSize(VET_FLOAT3); - vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - offset, nvertices, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); + vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + offset, nvertices, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); - bind->setBinding(0, vbuf); + bind->setBinding(0, vbuf); - //vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); - - HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). - createIndexBuffer( - HardwareIndexBuffer::IT_16BIT, - mCount*6, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); + //vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); + + HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). + createIndexBuffer( + HardwareIndexBuffer::IT_16BIT, + mCount*6, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); - idata->indexBuffer = ibuf; - idata->indexCount = mCount*6; - idata->indexStart = 0; - ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); + idata->indexBuffer = ibuf; + idata->indexCount = mCount*6; + idata->indexStart = 0; + ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); - // Delete temporary buffers - delete [] faces; - - // Now make the render operation - mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; - mRenderOp.indexData = idata; - mRenderOp.vertexData = vdata; - mRenderOp.useIndexes = true; + // Delete temporary buffers + delete [] faces; + + // Now make the render operation + mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; + mRenderOp.indexData = idata; + mRenderOp.vertexData = vdata; + mRenderOp.useIndexes = true; } void ThingRenderable::fillBuffer() { - // Transfer vertices and normals - float *vIdx = static_cast(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); - size_t elemsize = 1*3; // position only - size_t planesize = 4*elemsize; // four vertices per plane - for(size_t x=0; xunlock(); + // Transfer vertices and normals + float *vIdx = static_cast(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); + size_t elemsize = 1*3; // position only + size_t planesize = 4*elemsize; // four vertices per plane + for(size_t x=0; xunlock(); } Ogre::Real ThingRenderable::getBoundingRadius() const { - return mRadius; + return mRadius; } Ogre::Real ThingRenderable::getSquaredViewDepth(const Ogre::Camera* cam) const { - Ogre::Vector3 min, max, mid, dist; + Ogre::Vector3 min, max, mid, dist; - min = mBox.getMinimum(); - max = mBox.getMaximum(); - mid = ((min - max) * 0.5) + min; - dist = cam->getDerivedPosition() - mid; + min = mBox.getMinimum(); + max = mBox.getMaximum(); + mid = ((min - max) * 0.5) + min; + dist = cam->getDerivedPosition() - mid; - return dist.squaredLength(); + return dist.squaredLength(); } diff --git a/Samples/VolumeTex/src/VolumeRenderable.cpp b/Samples/VolumeTex/src/VolumeRenderable.cpp index b27411ca1f1..7f34d7d68d3 100644 --- a/Samples/VolumeTex/src/VolumeRenderable.cpp +++ b/Samples/VolumeTex/src/VolumeRenderable.cpp @@ -26,22 +26,22 @@ same license as the rest of the engine. using namespace Ogre; VolumeRenderable::VolumeRenderable(size_t nSlices, float size, const String &texture): - mSlices(nSlices), - mSize(size), - mTexture(texture) + mSlices(nSlices), + mSize(size), + mTexture(texture) { - mRadius = sqrtf(size*size+size*size+size*size)/2.0f; - mBox = Ogre::AxisAlignedBox(-size, -size, -size, size, size, size); - - // No shadows - setCastShadows(false); - - initialise(); + mRadius = sqrtf(size*size+size*size+size*size)/2.0f; + mBox = Ogre::AxisAlignedBox(-size, -size, -size, size, size, size); + + // No shadows + setCastShadows(false); + + initialise(); } VolumeRenderable::~VolumeRenderable() { - // Remove private material - MaterialManager::getSingleton().remove(mTexture); + // Remove private material + MaterialManager::getSingleton().remove(mTexture); // need to release IndexData and vertexData created for renderable delete mRenderOp.indexData; delete mRenderOp.vertexData; @@ -50,194 +50,194 @@ VolumeRenderable::~VolumeRenderable() void VolumeRenderable::_notifyCurrentCamera( Camera* cam ) { - MovableObject::_notifyCurrentCamera(cam); - - // Fake orientation toward camera - Vector3 zVec = getParentNode()->_getDerivedPosition() - cam->getDerivedPosition(); - zVec.normalise(); - Vector3 fixedAxis = cam->getDerivedOrientation() * Vector3::UNIT_Y ; - - Vector3 xVec = fixedAxis.crossProduct( zVec ); - xVec.normalise(); - - Vector3 yVec = zVec.crossProduct( xVec ); - yVec.normalise(); - - Quaternion oriQuat; - oriQuat.FromAxes( xVec, yVec, zVec ); - - oriQuat.ToRotationMatrix(mFakeOrientation); - - Matrix3 tempMat; - Quaternion q = getParentNode()->_getDerivedOrientation().UnitInverse() * oriQuat ; - q.ToRotationMatrix(tempMat); - - Matrix4 rotMat = Matrix4::IDENTITY; - rotMat = tempMat; - rotMat.setTrans(Vector3(0.5f, 0.5f, 0.5f)); - mUnit->setTextureTransform(rotMat); + MovableObject::_notifyCurrentCamera(cam); + + // Fake orientation toward camera + Vector3 zVec = getParentNode()->_getDerivedPosition() - cam->getDerivedPosition(); + zVec.normalise(); + Vector3 fixedAxis = cam->getDerivedOrientation() * Vector3::UNIT_Y ; + + Vector3 xVec = fixedAxis.crossProduct( zVec ); + xVec.normalise(); + + Vector3 yVec = zVec.crossProduct( xVec ); + yVec.normalise(); + + Quaternion oriQuat; + oriQuat.FromAxes( xVec, yVec, zVec ); + + oriQuat.ToRotationMatrix(mFakeOrientation); + + Matrix3 tempMat; + Quaternion q = getParentNode()->_getDerivedOrientation().UnitInverse() * oriQuat ; + q.ToRotationMatrix(tempMat); + + Matrix4 rotMat = Matrix4::IDENTITY; + rotMat = tempMat; + rotMat.setTrans(Vector3(0.5f, 0.5f, 0.5f)); + mUnit->setTextureTransform(rotMat); } void VolumeRenderable::getWorldTransforms( Matrix4* xform ) const { - Matrix4 destMatrix(Matrix4::IDENTITY); // this initialisation is needed - - const Vector3 &position = getParentNode()->_getDerivedPosition(); - const Vector3 &scale = getParentNode()->_getDerivedScale(); - Matrix3 scale3x3(Matrix3::ZERO); - scale3x3[0][0] = scale.x; - scale3x3[1][1] = scale.y; - scale3x3[2][2] = scale.z; - - destMatrix = mFakeOrientation * scale3x3; - destMatrix.setTrans(position); - - *xform = destMatrix; + Matrix4 destMatrix(Matrix4::IDENTITY); // this initialisation is needed + + const Vector3 &position = getParentNode()->_getDerivedPosition(); + const Vector3 &scale = getParentNode()->_getDerivedScale(); + Matrix3 scale3x3(Matrix3::ZERO); + scale3x3[0][0] = scale.x; + scale3x3[1][1] = scale.y; + scale3x3[2][2] = scale.z; + + destMatrix = mFakeOrientation * scale3x3; + destMatrix.setTrans(position); + + *xform = destMatrix; } void VolumeRenderable::initialise() { - // Create geometry - size_t nvertices = mSlices*4; // n+1 planes - size_t elemsize = 3*3; - size_t dsize = elemsize*nvertices; - size_t x; - - Ogre::IndexData *idata = new Ogre::IndexData(); - Ogre::VertexData *vdata = new Ogre::VertexData(); - - // Create structures - float *vertices = new float[dsize]; - - float coords[4][2] = { - {0.0f, 0.0f}, - {0.0f, 1.0f}, - {1.0f, 0.0f}, - {1.0f, 1.0f} - }; - for(x=0; xvertexStart = 0; - vdata->vertexCount = nvertices; - - VertexDeclaration* decl = vdata->vertexDeclaration; - VertexBufferBinding* bind = vdata->vertexBufferBinding; - - size_t offset = 0; - decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); - offset += VertexElement::getTypeSize(VET_FLOAT3); - decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); - offset += VertexElement::getTypeSize(VET_FLOAT3); - decl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES); - offset += VertexElement::getTypeSize(VET_FLOAT3); - - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - offset, nvertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - bind->setBinding(0, vbuf); - - vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); - - HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). - createIndexBuffer( - HardwareIndexBuffer::IT_16BIT, - mSlices*6, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - idata->indexBuffer = ibuf; - idata->indexCount = mSlices*6; - idata->indexStart = 0; - ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); - - // Delete temporary buffers - delete [] vertices; - delete [] faces; - - // Now make the render operation - mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; - mRenderOp.indexData = idata; - mRenderOp.vertexData = vdata; - mRenderOp.useIndexes = true; - - // Create a brand new private material - if (!ResourceGroupManager::getSingleton().resourceGroupExists("VolumeRenderable")) - { - ResourceGroupManager::getSingleton().createResourceGroup("VolumeRenderable"); - } - MaterialPtr material = - MaterialManager::getSingleton().create(mTexture, "VolumeRenderable", - false, 0); // Manual, loader - - // Remove pre-created technique from defaults - material->removeAllTechniques(); - - // Create a techinique and a pass and a texture unit - Technique * technique = material->createTechnique(); - Pass * pass = technique->createPass(); - TextureUnitState * textureUnit = pass->createTextureUnitState(); - - // Set pass parameters - pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); - pass->setDepthWriteEnabled(false); - pass->setCullingMode(CULL_NONE); - pass->setLightingEnabled(false); - - // Set texture unit parameters - textureUnit->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); - textureUnit->setTextureName(mTexture, TEX_TYPE_3D); - textureUnit->setTextureFiltering(TFO_TRILINEAR); - - mUnit = textureUnit; - mMaterial = material; + // Create geometry + size_t nvertices = mSlices*4; // n+1 planes + size_t elemsize = 3*3; + size_t dsize = elemsize*nvertices; + size_t x; + + Ogre::IndexData *idata = new Ogre::IndexData(); + Ogre::VertexData *vdata = new Ogre::VertexData(); + + // Create structures + float *vertices = new float[dsize]; + + float coords[4][2] = { + {0.0f, 0.0f}, + {0.0f, 1.0f}, + {1.0f, 0.0f}, + {1.0f, 1.0f} + }; + for(x=0; xvertexStart = 0; + vdata->vertexCount = nvertices; + + VertexDeclaration* decl = vdata->vertexDeclaration; + VertexBufferBinding* bind = vdata->vertexBufferBinding; + + size_t offset = 0; + decl->addElement(0, offset, VET_FLOAT3, VES_POSITION); + offset += VertexElement::getTypeSize(VET_FLOAT3); + decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL); + offset += VertexElement::getTypeSize(VET_FLOAT3); + decl->addElement(0, offset, VET_FLOAT3, VES_TEXTURE_COORDINATES); + offset += VertexElement::getTypeSize(VET_FLOAT3); + + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + offset, nvertices, HardwareBuffer::HBU_STATIC_WRITE_ONLY); + + bind->setBinding(0, vbuf); + + vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true); + + HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). + createIndexBuffer( + HardwareIndexBuffer::IT_16BIT, + mSlices*6, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + + idata->indexBuffer = ibuf; + idata->indexCount = mSlices*6; + idata->indexStart = 0; + ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true); + + // Delete temporary buffers + delete [] vertices; + delete [] faces; + + // Now make the render operation + mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; + mRenderOp.indexData = idata; + mRenderOp.vertexData = vdata; + mRenderOp.useIndexes = true; + + // Create a brand new private material + if (!ResourceGroupManager::getSingleton().resourceGroupExists("VolumeRenderable")) + { + ResourceGroupManager::getSingleton().createResourceGroup("VolumeRenderable"); + } + MaterialPtr material = + MaterialManager::getSingleton().create(mTexture, "VolumeRenderable", + false, 0); // Manual, loader + + // Remove pre-created technique from defaults + material->removeAllTechniques(); + + // Create a techinique and a pass and a texture unit + Technique * technique = material->createTechnique(); + Pass * pass = technique->createPass(); + TextureUnitState * textureUnit = pass->createTextureUnitState(); + + // Set pass parameters + pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); + pass->setDepthWriteEnabled(false); + pass->setCullingMode(CULL_NONE); + pass->setLightingEnabled(false); + + // Set texture unit parameters + textureUnit->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); + textureUnit->setTextureName(mTexture, TEX_TYPE_3D); + textureUnit->setTextureFiltering(TFO_TRILINEAR); + + mUnit = textureUnit; + mMaterial = material; } Ogre::Real VolumeRenderable::getBoundingRadius() const { - return mRadius; + return mRadius; } Ogre::Real VolumeRenderable::getSquaredViewDepth(const Ogre::Camera* cam) const { - Ogre::Vector3 min, max, mid, dist; + Ogre::Vector3 min, max, mid, dist; - min = mBox.getMinimum(); - max = mBox.getMaximum(); - mid = ((min - max) * 0.5) + min; - dist = cam->getDerivedPosition() - mid; + min = mBox.getMinimum(); + max = mBox.getMaximum(); + mid = ((min - max) * 0.5) + min; + dist = cam->getDerivedPosition() - mid; - return dist.squaredLength(); + return dist.squaredLength(); } diff --git a/Samples/VolumeTex/src/VolumeTex.cpp b/Samples/VolumeTex/src/VolumeTex.cpp index 320563ae50f..4d2265220d1 100644 --- a/Samples/VolumeTex/src/VolumeTex.cpp +++ b/Samples/VolumeTex/src/VolumeTex.cpp @@ -11,12 +11,12 @@ You may use this sample code for anything you like, it is not covered by the same license as the rest of the engine. ----------------------------------------------------------------------------- */ -/** Generate 3D julia sets and render them as volume texture - This demonstrates - - User generated textures - - Procedural volume textures (Julia makes nice dust clouds) - - Custom renderables - @author W.J. van der Laan +/** Generate 3D julia sets and render them as volume texture + This demonstrates + - User generated textures + - Procedural volume textures (Julia makes nice dust clouds) + - Custom renderables + @author W.J. van der Laan */ #include "SdkSample.h" @@ -47,73 +47,73 @@ class _OgreSampleClassExport Sample_VolumeTex : public SdkSample public: Sample_VolumeTex() - { - mInfo["Title"] = "Volume Textures"; - mInfo["Description"] = "Demonstrates the use of volume textures."; - mInfo["Thumbnail"] = "thumb_voltex.png"; - mInfo["Category"] = "Unsorted"; - } + { + mInfo["Title"] = "Volume Textures"; + mInfo["Description"] = "Demonstrates the use of volume textures."; + mInfo["Thumbnail"] = "thumb_voltex.png"; + mInfo["Category"] = "Unsorted"; + } - void testCapabilities(const RenderSystemCapabilities* caps) - { - if (!caps->hasCapability(RSC_TEXTURE_3D)) + void testCapabilities(const RenderSystemCapabilities* caps) + { + if (!caps->hasCapability(RSC_TEXTURE_3D)) { OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "Your card does not support 3D textures, so cannot " "run this demo. Sorry!", "Sample_VolumeTex::testCapabilities"); } - } + } protected: - float global_real, global_imag, global_theta; + float global_real, global_imag, global_theta; void setupView(void) - { - SdkSample::setupView(); + { + SdkSample::setupView(); - // Create the camera + // Create the camera mCamera->setPosition(Vector3(220,-2,176)); mCamera->lookAt(Vector3(0,0,0)); mCamera->setNearClipDistance(5); - } + } void setupContent(void) { // Create dynamic texture - ptex = TextureManager::getSingleton().createManual( - "DynaTex","General", TEX_TYPE_3D, 64, 64, 64, 0, PF_A8R8G8B8); + ptex = TextureManager::getSingleton().createManual( + "DynaTex","General", TEX_TYPE_3D, 64, 64, 64, 0, PF_A8R8G8B8); - // Set ambient light + // Set ambient light mSceneMgr->setAmbientLight(ColourValue(0.6, 0.6, 0.6)); - mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox", 50 ); + mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox", 50 ); //mRoot->getRenderSystem()->clearFrameBuffer(FBT_COLOUR, ColourValue(255,255,255,0)); // Create a light Light* l = mSceneMgr->createLight("MainLight"); l->setDiffuseColour(0.75, 0.75, 0.80); - l->setSpecularColour(0.9, 0.9, 1); + l->setSpecularColour(0.9, 0.9, 1); l->setPosition(-100,80,50); - mSceneMgr->getRootSceneNode()->attachObject(l); - - // Create volume renderable - snode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0)); - + mSceneMgr->getRootSceneNode()->attachObject(l); + + // Create volume renderable + snode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0)); + vrend = new VolumeRenderable(32, 750.0f, "DynaTex"); snode->attachObject( vrend ); - - trend = new ThingRenderable(90.0f, 32, 7.5f); - trend->setMaterial("Examples/VTDarkStuff"); - snode->attachObject(trend); - - // Ogre head node - fnode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0)); - // Load ogre head - Entity* head = mSceneMgr->createEntity("head", "ogrehead.mesh"); - fnode->attachObject(head); - - // Animation for ogre head - // Create a track for the light + + trend = new ThingRenderable(90.0f, 32, 7.5f); + trend->setMaterial("Examples/VTDarkStuff"); + snode->attachObject(trend); + + // Ogre head node + fnode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0)); + // Load ogre head + Entity* head = mSceneMgr->createEntity("head", "ogrehead.mesh"); + fnode->attachObject(head); + + // Animation for ogre head + // Create a track for the light Animation* anim = mSceneMgr->createAnimation("OgreTrack", 10); // Spline it for nice curves anim->setInterpolationMode(Animation::IM_SPLINE); @@ -132,113 +132,113 @@ class _OgreSampleClassExport Sample_VolumeTex : public SdkSample //mFountainNode->attachObject(pSys2); - //Setup defaults - global_real = 0.4f; - global_imag = 0.6f; - global_theta = 0.0f; + //Setup defaults + global_real = 0.4f; + global_imag = 0.6f; + global_theta = 0.0f; - // show GUI - createControls(); + // show GUI + createControls(); - setDragLook(true); + setDragLook(true); - generate(); + generate(); } - bool frameRenderingQueued( const FrameEvent& evt ) + bool frameRenderingQueued( const FrameEvent& evt ) { - xtime += evt.timeSinceLastFrame; - xtime = fmod(xtime, 10.0f); - //snode->roll(Degree(evt.timeSinceLastFrame * 20.0f)); - //fnode->roll(Degree(evt.timeSinceLastFrame * 20.0f)); - static_cast(trend)->addTime(evt.timeSinceLastFrame * 0.05f); - mOgreAnimState->addTime(evt.timeSinceLastFrame); - return SdkSample::frameRenderingQueued(evt); + xtime += evt.timeSinceLastFrame; + xtime = fmod(xtime, 10.0f); + //snode->roll(Degree(evt.timeSinceLastFrame * 20.0f)); + //fnode->roll(Degree(evt.timeSinceLastFrame * 20.0f)); + static_cast(trend)->addTime(evt.timeSinceLastFrame * 0.05f); + mOgreAnimState->addTime(evt.timeSinceLastFrame); + return SdkSample::frameRenderingQueued(evt); } - void cleanupContent(void) - { - TextureManager::getSingleton().remove("DynaTex"); - delete vrend; - delete trend; - } + void cleanupContent(void) + { + TextureManager::getSingleton().remove("DynaTex"); + delete vrend; + delete trend; + } - void createControls() - { - mTrayMgr->createLabel(TL_TOPLEFT, "JuliaParamLabel", "Julia Parameters", 200); - mTrayMgr->createThickSlider(TL_TOPLEFT, "RealSlider", "Real", 200, 80, -1, 1, 50)->setValue(global_real, false); - mTrayMgr->createThickSlider(TL_TOPLEFT, "ImagSlider", "Imag", 200, 80, -1, 1, 50)->setValue(global_imag, false); - mTrayMgr->createThickSlider(TL_TOPLEFT, "ThetaSlider", "Theta", 200, 80, -1, 1, 50)->setValue(global_theta, false); - mTrayMgr->showCursor(); - } + void createControls() + { + mTrayMgr->createLabel(TL_TOPLEFT, "JuliaParamLabel", "Julia Parameters", 200); + mTrayMgr->createThickSlider(TL_TOPLEFT, "RealSlider", "Real", 200, 80, -1, 1, 50)->setValue(global_real, false); + mTrayMgr->createThickSlider(TL_TOPLEFT, "ImagSlider", "Imag", 200, 80, -1, 1, 50)->setValue(global_imag, false); + mTrayMgr->createThickSlider(TL_TOPLEFT, "ThetaSlider", "Theta", 200, 80, -1, 1, 50)->setValue(global_theta, false); + mTrayMgr->showCursor(); + } - void sliderMoved(Slider* slider) - { - if (slider->getName() == "RealSlider") - { - global_real = slider->getValue(); - } - else if (slider->getName() == "ImagSlider") - { - global_imag = slider->getValue(); - } - else if (slider->getName() == "ThetaSlider") - { - global_theta = slider->getValue(); - } - generate(); - } + void sliderMoved(Slider* slider) + { + if (slider->getName() == "RealSlider") + { + global_real = slider->getValue(); + } + else if (slider->getName() == "ImagSlider") + { + global_imag = slider->getValue(); + } + else if (slider->getName() == "ThetaSlider") + { + global_theta = slider->getValue(); + } + generate(); + } - void generate() - { - /* Evaluate julia fractal for each point */ - Julia julia(global_real, global_imag, global_theta); - const float scale = 2.5; - const float vcut = 29.0f; - const float vscale = 1.0f/vcut; - - HardwarePixelBufferSharedPtr buffer = ptex->getBuffer(0, 0); - Ogre::StringStream d; - d << "HardwarePixelBuffer " << buffer->getWidth() << " " << buffer->getHeight() << " " << buffer->getDepth(); - LogManager::getSingleton().logMessage(d.str()); - - buffer->lock(HardwareBuffer::HBL_NORMAL); - const PixelBox &pb = buffer->getCurrentLock(); - d.str(""); - d << "PixelBox " << pb.getWidth() << " " << pb.getHeight() << " " << pb.getDepth() << " " << pb.rowPitch << " " << pb.slicePitch << " " << pb.data << " " << PixelUtil::getFormatName(pb.format); - LogManager::getSingleton().logMessage(d.str()); - - Ogre::uint32 *pbptr = static_cast(pb.data); - for(size_t z=pb.front; zgetBuffer(0, 0); + Ogre::StringStream d; + d << "HardwarePixelBuffer " << buffer->getWidth() << " " << buffer->getHeight() << " " << buffer->getDepth(); + LogManager::getSingleton().logMessage(d.str()); + + buffer->lock(HardwareBuffer::HBL_NORMAL); + const PixelBox &pb = buffer->getCurrentLock(); + d.str(""); + d << "PixelBox " << pb.getWidth() << " " << pb.getHeight() << " " << pb.getDepth() << " " << pb.rowPitch << " " << pb.slicePitch << " " << pb.data << " " << PixelUtil::getFormatName(pb.format); + LogManager::getSingleton().logMessage(d.str()); + + Ogre::uint32 *pbptr = static_cast(pb.data); + for(size_t z=pb.front; z vcut) - val = vcut; - - PixelUtil::packColour((float)x/pb.getWidth(), (float)y/pb.getHeight(), (float)z/pb.getDepth(), (1.0f-(val*vscale))*0.7f, PF_A8R8G8B8, &pbptr[x]); - - } + else + { + float val = julia.eval(((float)x/pb.getWidth()-0.5f) * scale, + ((float)y/pb.getHeight()-0.5f) * scale, + ((float)z/pb.getDepth()-0.5f) * scale); + if(val > vcut) + val = vcut; + + PixelUtil::packColour((float)x/pb.getWidth(), (float)y/pb.getHeight(), (float)z/pb.getDepth(), (1.0f-(val*vscale))*0.7f, PF_A8R8G8B8, &pbptr[x]); + + } } pbptr += pb.rowPitch; } pbptr += pb.getSliceSkip(); } - buffer->unlock(); - } + buffer->unlock(); + } }; #ifndef OGRE_STATIC_LIB @@ -248,16 +248,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_VolumeTex; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_VolumeTex; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Water/include/Water.h b/Samples/Water/include/Water.h index 83c5ae84237..0fdaba2fe75 100644 --- a/Samples/Water/include/Water.h +++ b/Samples/Water/include/Water.h @@ -31,50 +31,50 @@ using namespace OgreBites; #define ENTITY_NAME "WaterEntity" #define MATERIAL_PREFIX "Examples/Water" #define MATERIAL_NAME "Examples/Water0" -#define COMPLEXITY 64 // watch out - number of polys is 2*ACCURACY*ACCURACY ! +#define COMPLEXITY 64 // watch out - number of polys is 2*ACCURACY*ACCURACY ! #define PLANE_SIZE 3000.0f #define CIRCLES_MATERIAL "Examples/Water/Circles" void prepareCircleMaterial() { - char *bmap = new char[256 * 256 * 4] ; - memset(bmap, 127, 256 * 256 * 4); - for(int b=0;b<16;b++) { - int x0 = b % 4 ; - int y0 = b >> 2 ; - Real radius = 4.0f + 1.4 * (float) b ; - for(int x=0;x<64;x++) { - for(int y=0;y<64;y++) { - Real dist = Math::Sqrt((x-32)*(x-32)+(y-32)*(y-32)); // 0..ca.45 - dist = fabs(dist -radius -2) / 2.0f ; - dist = dist * 255.0f; - if (dist>255) - dist=255 ; - int colour = 255-(int)dist ; - colour = (int)( ((Real)(15-b))/15.0f * (Real) colour ); + char *bmap = new char[256 * 256 * 4] ; + memset(bmap, 127, 256 * 256 * 4); + for(int b=0;b<16;b++) { + int x0 = b % 4 ; + int y0 = b >> 2 ; + Real radius = 4.0f + 1.4 * (float) b ; + for(int x=0;x<64;x++) { + for(int y=0;y<64;y++) { + Real dist = Math::Sqrt((x-32)*(x-32)+(y-32)*(y-32)); // 0..ca.45 + dist = fabs(dist -radius -2) / 2.0f ; + dist = dist * 255.0f; + if (dist>255) + dist=255 ; + int colour = 255-(int)dist ; + colour = (int)( ((Real)(15-b))/15.0f * (Real) colour ); - bmap[4*(256*(y+64*y0)+x+64*x0)+0]=colour ; - bmap[4*(256*(y+64*y0)+x+64*x0)+1]=colour ; - bmap[4*(256*(y+64*y0)+x+64*x0)+2]=colour ; - bmap[4*(256*(y+64*y0)+x+64*x0)+3]=colour ; - } - } - } + bmap[4*(256*(y+64*y0)+x+64*x0)+0]=colour ; + bmap[4*(256*(y+64*y0)+x+64*x0)+1]=colour ; + bmap[4*(256*(y+64*y0)+x+64*x0)+2]=colour ; + bmap[4*(256*(y+64*y0)+x+64*x0)+3]=colour ; + } + } + } - DataStreamPtr imgstream(new MemoryDataStream(bmap, 256 * 256 * 4)); - //~ Image img; - //~ img.loadRawData( imgstream, 256, 256, PF_A8R8G8B8 ); - //~ TextureManager::getSingleton().loadImage( CIRCLES_MATERIAL , img ); - TextureManager::getSingleton().loadRawData(CIRCLES_MATERIAL, + DataStreamPtr imgstream(new MemoryDataStream(bmap, 256 * 256 * 4)); + //~ Image img; + //~ img.loadRawData( imgstream, 256, 256, PF_A8R8G8B8 ); + //~ TextureManager::getSingleton().loadImage( CIRCLES_MATERIAL , img ); + TextureManager::getSingleton().loadRawData(CIRCLES_MATERIAL, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, imgstream, 256, 256, PF_A8R8G8B8); - MaterialPtr material = + MaterialPtr material = MaterialManager::getSingleton().create( CIRCLES_MATERIAL, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - TextureUnitState *texLayer = material->getTechnique(0)->getPass(0)->createTextureUnitState( CIRCLES_MATERIAL ); - texLayer->setTextureAddressingMode( TextureUnitState::TAM_CLAMP ); - material->setSceneBlending( SBT_ADD ); - material->setDepthWriteEnabled( false ) ; + TextureUnitState *texLayer = material->getTechnique(0)->getPass(0)->createTextureUnitState( CIRCLES_MATERIAL ); + texLayer->setTextureAddressingMode( TextureUnitState::TAM_CLAMP ); + material->setSceneBlending( SBT_ADD ); + material->setDepthWriteEnabled( false ) ; material->load(); // finished with bmap so release the memory delete [] bmap; @@ -89,163 +89,163 @@ void prepareCircleMaterial() class WaterCircle { private: - String name ; - SceneNode *node ; - MeshPtr mesh ; - SubMesh *subMesh ; - Entity *entity ; - Real tm ; + String name ; + SceneNode *node ; + MeshPtr mesh ; + SubMesh *subMesh ; + Entity *entity ; + Real tm ; SceneManager *sceneMgr ; - static bool first ; - // some buffers shared by all circles - static HardwareVertexBufferSharedPtr posnormVertexBuffer ; - static HardwareIndexBufferSharedPtr indexBuffer ; // indices for 2 faces - static HardwareVertexBufferSharedPtr *texcoordsVertexBuffers ; + static bool first ; + // some buffers shared by all circles + static HardwareVertexBufferSharedPtr posnormVertexBuffer ; + static HardwareIndexBufferSharedPtr indexBuffer ; // indices for 2 faces + static HardwareVertexBufferSharedPtr *texcoordsVertexBuffers ; - void _prepareMesh() - { - int i,texLvl ; + void _prepareMesh() + { + int i,texLvl ; - mesh = MeshManager::getSingleton().createManual(name, + mesh = MeshManager::getSingleton().createManual(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME) ; - subMesh = mesh->createSubMesh(); - subMesh->useSharedVertices=false; + subMesh = mesh->createSubMesh(); + subMesh->useSharedVertices=false; - int numVertices = 4 ; + int numVertices = 4 ; - if (first) { // first Circle, create some static common data - first = false ; + if (first) { // first Circle, create some static common data + first = false ; - // static buffer for position and normals - posnormVertexBuffer = + // static buffer for position and normals + posnormVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 6*sizeof(float), // size of one vertex data 4, // number of vertices HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage false); // no shadow buffer - float *posnormBufData = (float*) posnormVertexBuffer-> + float *posnormBufData = (float*) posnormVertexBuffer-> lock(HardwareBuffer::HBL_DISCARD); - for(i=0;iunlock(); + for(i=0;iunlock(); - // static buffers for 16 sets of texture coordinates - texcoordsVertexBuffers = new HardwareVertexBufferSharedPtr[16]; - for(texLvl=0;texLvl<16;texLvl++) { - texcoordsVertexBuffers[texLvl] = + // static buffers for 16 sets of texture coordinates + texcoordsVertexBuffers = new HardwareVertexBufferSharedPtr[16]; + for(texLvl=0;texLvl<16;texLvl++) { + texcoordsVertexBuffers[texLvl] = HardwareBufferManager::getSingleton().createVertexBuffer( 2*sizeof(float), // size of one vertex data numVertices, // number of vertices HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage false); // no shadow buffer - float *texcoordsBufData = (float*) texcoordsVertexBuffers[texLvl]-> + float *texcoordsBufData = (float*) texcoordsVertexBuffers[texLvl]-> lock(HardwareBuffer::HBL_DISCARD); - float x0 = (Real)(texLvl % 4) * 0.25 ; - float y0 = (Real)(texLvl / 4) * 0.25 ; - y0 = 0.75-y0 ; // upside down - for(i=0;i<4;i++) { - texcoordsBufData[i*2 + 0]= + float x0 = (Real)(texLvl % 4) * 0.25 ; + float y0 = (Real)(texLvl / 4) * 0.25 ; + y0 = 0.75-y0 ; // upside down + for(i=0;i<4;i++) { + texcoordsBufData[i*2 + 0]= x0 + 0.25 * (Real)(i%2) ; - texcoordsBufData[i*2 + 1]= + texcoordsBufData[i*2 + 1]= y0 + 0.25 * (Real)(i/2) ; - } - texcoordsVertexBuffers[texLvl]->unlock(); - } + } + texcoordsVertexBuffers[texLvl]->unlock(); + } - // Index buffer for 2 faces - unsigned short faces[6] = {2,1,0, 2,3,1}; - indexBuffer = + // Index buffer for 2 faces + unsigned short faces[6] = {2,1,0, 2,3,1}; + indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer( HardwareIndexBuffer::IT_16BIT, 6, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - indexBuffer->writeData(0, + indexBuffer->writeData(0, indexBuffer->getSizeInBytes(), faces, true); // true? - } + } - // Initialize vertex data - subMesh->vertexData = new VertexData(); - subMesh->vertexData->vertexStart = 0; - subMesh->vertexData->vertexCount = 4; - // first, set vertex buffer bindings - VertexBufferBinding *vbind = subMesh->vertexData->vertexBufferBinding ; - vbind->setBinding(0, posnormVertexBuffer); - vbind->setBinding(1, texcoordsVertexBuffers[0]); - // now, set vertex buffer declaration - VertexDeclaration *vdecl = subMesh->vertexData->vertexDeclaration ; - vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); - vdecl->addElement(0, 3*sizeof(float), VET_FLOAT3, VES_NORMAL); - vdecl->addElement(1, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); + // Initialize vertex data + subMesh->vertexData = new VertexData(); + subMesh->vertexData->vertexStart = 0; + subMesh->vertexData->vertexCount = 4; + // first, set vertex buffer bindings + VertexBufferBinding *vbind = subMesh->vertexData->vertexBufferBinding ; + vbind->setBinding(0, posnormVertexBuffer); + vbind->setBinding(1, texcoordsVertexBuffers[0]); + // now, set vertex buffer declaration + VertexDeclaration *vdecl = subMesh->vertexData->vertexDeclaration ; + vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); + vdecl->addElement(0, 3*sizeof(float), VET_FLOAT3, VES_NORMAL); + vdecl->addElement(1, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); - // Initialize index data - subMesh->indexData->indexBuffer = indexBuffer; - subMesh->indexData->indexStart = 0; - subMesh->indexData->indexCount = 6; + // Initialize index data + subMesh->indexData->indexBuffer = indexBuffer; + subMesh->indexData->indexStart = 0; + subMesh->indexData->indexCount = 6; - // set mesh bounds - AxisAlignedBox circleBounds(-CIRCLE_SIZE/2.0f, 0, -CIRCLE_SIZE/2.0f, + // set mesh bounds + AxisAlignedBox circleBounds(-CIRCLE_SIZE/2.0f, 0, -CIRCLE_SIZE/2.0f, CIRCLE_SIZE/2.0f, 0, CIRCLE_SIZE/2.0f); - mesh->_setBounds(circleBounds); + mesh->_setBounds(circleBounds); mesh->load(); mesh->touch(); - } + } public: - int lvl ; - void setTextureLevel() - { - subMesh->vertexData->vertexBufferBinding->setBinding(1, texcoordsVertexBuffers[lvl]); - } - WaterCircle(SceneManager *mgr, const String& inName, Real x, Real y) - { + int lvl ; + void setTextureLevel() + { + subMesh->vertexData->vertexBufferBinding->setBinding(1, texcoordsVertexBuffers[lvl]); + } + WaterCircle(SceneManager *mgr, const String& inName, Real x, Real y) + { sceneMgr = mgr; - name = inName ; - _prepareMesh(); - node = static_cast (sceneMgr->getRootSceneNode()->createChild(name)); - node->translate(x*(PLANE_SIZE/COMPLEXITY), 10, y*(PLANE_SIZE/COMPLEXITY)); - entity = sceneMgr->createEntity(name, name); - entity->setMaterialName(CIRCLES_MATERIAL); - node->attachObject(entity); - tm = 0 ; - lvl = 0 ; - setTextureLevel(); - } - ~WaterCircle() - { - MeshManager::getSingleton().remove(mesh->getHandle()); - sceneMgr->destroyEntity(entity->getName()); - static_cast (sceneMgr->getRootSceneNode())->removeChild(node->getName()); - } - void animate(Real timeSinceLastFrame) - { - int lastlvl = lvl ; - tm += timeSinceLastFrame ; - lvl = (int) ( (Real)(tm)/CIRCLE_TIME * 16 ); - if (lvl<16 && lvl!=lastlvl) { - setTextureLevel(); - } - } - static void clearStaticBuffers() - { - posnormVertexBuffer = HardwareVertexBufferSharedPtr() ; - indexBuffer = HardwareIndexBufferSharedPtr() ; - if(texcoordsVertexBuffers != NULL) - { - for(int i=0;i<16;i++) { - texcoordsVertexBuffers[i] = HardwareVertexBufferSharedPtr() ; - } - delete [] texcoordsVertexBuffers; - texcoordsVertexBuffers = NULL; - } - first = true; - } + name = inName ; + _prepareMesh(); + node = static_cast (sceneMgr->getRootSceneNode()->createChild(name)); + node->translate(x*(PLANE_SIZE/COMPLEXITY), 10, y*(PLANE_SIZE/COMPLEXITY)); + entity = sceneMgr->createEntity(name, name); + entity->setMaterialName(CIRCLES_MATERIAL); + node->attachObject(entity); + tm = 0 ; + lvl = 0 ; + setTextureLevel(); + } + ~WaterCircle() + { + MeshManager::getSingleton().remove(mesh->getHandle()); + sceneMgr->destroyEntity(entity->getName()); + static_cast (sceneMgr->getRootSceneNode())->removeChild(node->getName()); + } + void animate(Real timeSinceLastFrame) + { + int lastlvl = lvl ; + tm += timeSinceLastFrame ; + lvl = (int) ( (Real)(tm)/CIRCLE_TIME * 16 ); + if (lvl<16 && lvl!=lastlvl) { + setTextureLevel(); + } + } + static void clearStaticBuffers() + { + posnormVertexBuffer = HardwareVertexBufferSharedPtr() ; + indexBuffer = HardwareIndexBufferSharedPtr() ; + if(texcoordsVertexBuffers != NULL) + { + for(int i=0;i<16;i++) { + texcoordsVertexBuffers[i] = HardwareVertexBufferSharedPtr() ; + } + delete [] texcoordsVertexBuffers; + texcoordsVertexBuffers = NULL; + } + first = true; + } } ; bool WaterCircle::first = true ; HardwareVertexBufferSharedPtr WaterCircle::posnormVertexBuffer = @@ -259,19 +259,19 @@ class _OgreSampleClassExport Sample_Water : public SdkSample public: Sample_Water(): waterMesh(0) { - mInfo["Title"] = "Water"; - mInfo["Description"] = "A demo of a simple water effect."; - mInfo["Thumbnail"] = "thumb_water.png"; - mInfo["Category"] = "Environment"; + mInfo["Title"] = "Water"; + mInfo["Description"] = "A demo of a simple water effect."; + mInfo["Thumbnail"] = "thumb_water.png"; + mInfo["Category"] = "Environment"; } virtual void _shutdown() { // cleanup all allocated circles - for(unsigned i = 0 ; i < circles.size() ; i++) + for(unsigned i = 0 ; i < circles.size() ; i++) { - delete (circles[i]); - } + delete (circles[i]); + } circles.clear(); @@ -279,9 +279,9 @@ class _OgreSampleClassExport Sample_Water : public SdkSample } protected: - WaterMesh *waterMesh ; - Entity *waterEntity ; - AnimationState* mAnimState; + WaterMesh *waterMesh ; + Entity *waterEntity ; + AnimationState* mAnimState; SceneNode *headNode ; Overlay* waterOverlay ; ParticleSystem *particleSystem ; @@ -291,7 +291,7 @@ class _OgreSampleClassExport Sample_Water : public SdkSample // Just override the mandatory create scene method void setupContent(void) { - sceneMgr = mSceneMgr ; + sceneMgr = mSceneMgr ; // Set ambient light mSceneMgr->setAmbientLight(ColourValue(0.75, 0.75, 0.75)); @@ -302,49 +302,49 @@ class _OgreSampleClassExport Sample_Water : public SdkSample // other objects, but I don't l->setPosition(200,300,100); - // Create water mesh and entity - waterMesh = new WaterMesh(MESH_NAME, PLANE_SIZE, COMPLEXITY); - waterEntity = mSceneMgr->createEntity(ENTITY_NAME, + // Create water mesh and entity + waterMesh = new WaterMesh(MESH_NAME, PLANE_SIZE, COMPLEXITY); + waterEntity = mSceneMgr->createEntity(ENTITY_NAME, MESH_NAME); - //~ waterEntity->setMaterialName(MATERIAL_NAME); - SceneNode *waterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - waterNode->attachObject(waterEntity); + //~ waterEntity->setMaterialName(MATERIAL_NAME); + SceneNode *waterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + waterNode->attachObject(waterEntity); // Add a head, give it it's own node headNode = waterNode->createChildSceneNode(); Entity *ent = mSceneMgr->createEntity("head", "ogrehead.mesh"); headNode->attachObject(ent); - // Make sure the camera track this node + // Make sure the camera track this node //~ mCamera->setAutoTracking(true, headNode); - // Create the camera node, set its position & attach camera + // Create the camera node, set its position & attach camera SceneNode* camNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - camNode->translate(0, 500, PLANE_SIZE); - camNode->yaw(Degree(-45)); + camNode->translate(0, 500, PLANE_SIZE); + camNode->yaw(Degree(-45)); camNode->attachObject(mCamera); - // Create light node + // Create light node SceneNode* lightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - lightNode->attachObject(l); + lightNode->attachObject(l); // set up spline animation of light node Animation* anim = mSceneMgr->createAnimation("WaterLight", 20); - NodeAnimationTrack *track ; + NodeAnimationTrack *track ; TransformKeyFrame *key ; - // create a random spline for light - track = anim->createNodeTrack(0, lightNode); - track->createNodeKeyFrame(0); - for(int ff=1;ff<=19;ff++) { - key = track->createNodeKeyFrame(ff); - Vector3 lpos ( + // create a random spline for light + track = anim->createNodeTrack(0, lightNode); + track->createNodeKeyFrame(0); + for(int ff=1;ff<=19;ff++) { + key = track->createNodeKeyFrame(ff); + Vector3 lpos ( rand()%(int)PLANE_SIZE , //- PLANE_SIZE/2, rand()%300+100, rand()%(int)PLANE_SIZE //- PLANE_SIZE/2 ); - key->setTranslate(lpos); - } - track->createNodeKeyFrame(20); + key->setTranslate(lpos); + } + track->createNodeKeyFrame(20); // Create a new animation state to track this mAnimState = mSceneMgr->createAnimationState("WaterLight"); @@ -353,231 +353,231 @@ class _OgreSampleClassExport Sample_Water : public SdkSample // Put in a bit of fog for the hell of it //mSceneMgr->setFog(FOG_EXP, ColourValue::White, 0.0002); - // Let there be rain + // Let there be rain particleSystem = mSceneMgr->createParticleSystem("rain", "Examples/Water/Rain"); - particleEmitter = particleSystem->getEmitter(0); - particleEmitter->setEmissionRate(0); + particleEmitter = particleSystem->getEmitter(0); + particleEmitter->setEmissionRate(0); SceneNode* rNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); rNode->translate(PLANE_SIZE/2.0f, 3000, PLANE_SIZE/2.0f); rNode->attachObject(particleSystem); // Fast-forward the rain so it looks more natural particleSystem->fastForward(20); - // It can't be set in .particle file, and we need it ;) - static_cast(particleSystem->getRenderer())->setBillboardOrigin(BBO_BOTTOM_CENTER); + // It can't be set in .particle file, and we need it ;) + static_cast(particleSystem->getRenderer())->setBillboardOrigin(BBO_BOTTOM_CENTER); - prepareCircleMaterial(); + prepareCircleMaterial(); - setupControls(); + setupControls(); #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS - setDragLook(true); + setDragLook(true); #endif - timeoutDelay = 0.0f; - } + timeoutDelay = 0.0f; + } #define PANEL_WIDTH 200 - void setupControls() - { - mTrayMgr->createLabel(TL_TOPLEFT, "GeneralLabel", "General", PANEL_WIDTH); - mTrayMgr->createCheckBox(TL_TOPLEFT, "FakeNormalsCB", "Fake normals", PANEL_WIDTH); - mTrayMgr->createCheckBox(TL_TOPLEFT, "SkyboxCB", "Skybox", PANEL_WIDTH); - mTrayMgr->createThickSlider(TL_TOPLEFT, "HeadDepthSlider", "Head Depth", PANEL_WIDTH, 80, 1, 3, 50)->setValue(2.0f); - SelectMenu* waterMaterial = mTrayMgr->createThickSelectMenu(TL_TOPLEFT, "WaterMaterialMenu", "Water material", PANEL_WIDTH, 9); - for (size_t i = 0; i < 9; i++) - { - waterMaterial->addItem(MATERIAL_PREFIX + StringConverter::toString(i)); - } - waterMaterial->selectItem(8); - mTrayMgr->createLabel(TL_TOPLEFT, "RainLabel", "Rain : [Space]", PANEL_WIDTH); - - mTrayMgr->createLabel(TL_TOPRIGHT, "AdvancedLabel", "Advanced", PANEL_WIDTH); - mTrayMgr->createThickSlider(TL_TOPRIGHT, "RippleSpeedSlider", "Ripple Speed", PANEL_WIDTH, 80, 0, 2, 50)->setValue(0.3, false); - mTrayMgr->createThickSlider(TL_TOPRIGHT, "DistanceSlider", "Distance", PANEL_WIDTH, 80, 0.1, 5.0, 50)->setValue(0.4, false); - mTrayMgr->createThickSlider(TL_TOPRIGHT, "ViscositySlider", "Viscosity", PANEL_WIDTH, 80, 0, 1, 50)->setValue(0.05, false); - mTrayMgr->createThickSlider(TL_TOPRIGHT, "FrameTimeSlider", "FrameTime", PANEL_WIDTH, 80, 0, 1, 61)->setValue(0.13, false); + void setupControls() + { + mTrayMgr->createLabel(TL_TOPLEFT, "GeneralLabel", "General", PANEL_WIDTH); + mTrayMgr->createCheckBox(TL_TOPLEFT, "FakeNormalsCB", "Fake normals", PANEL_WIDTH); + mTrayMgr->createCheckBox(TL_TOPLEFT, "SkyboxCB", "Skybox", PANEL_WIDTH); + mTrayMgr->createThickSlider(TL_TOPLEFT, "HeadDepthSlider", "Head Depth", PANEL_WIDTH, 80, 1, 3, 50)->setValue(2.0f); + SelectMenu* waterMaterial = mTrayMgr->createThickSelectMenu(TL_TOPLEFT, "WaterMaterialMenu", "Water material", PANEL_WIDTH, 9); + for (size_t i = 0; i < 9; i++) + { + waterMaterial->addItem(MATERIAL_PREFIX + StringConverter::toString(i)); + } + waterMaterial->selectItem(8); + mTrayMgr->createLabel(TL_TOPLEFT, "RainLabel", "Rain : [Space]", PANEL_WIDTH); + + mTrayMgr->createLabel(TL_TOPRIGHT, "AdvancedLabel", "Advanced", PANEL_WIDTH); + mTrayMgr->createThickSlider(TL_TOPRIGHT, "RippleSpeedSlider", "Ripple Speed", PANEL_WIDTH, 80, 0, 2, 50)->setValue(0.3, false); + mTrayMgr->createThickSlider(TL_TOPRIGHT, "DistanceSlider", "Distance", PANEL_WIDTH, 80, 0.1, 5.0, 50)->setValue(0.4, false); + mTrayMgr->createThickSlider(TL_TOPRIGHT, "ViscositySlider", "Viscosity", PANEL_WIDTH, 80, 0, 1, 50)->setValue(0.05, false); + mTrayMgr->createThickSlider(TL_TOPRIGHT, "FrameTimeSlider", "FrameTime", PANEL_WIDTH, 80, 0, 1, 61)->setValue(0.13, false); - mTrayMgr->showCursor(); - } + mTrayMgr->showCursor(); + } - void cleanupContent() - { - // If when you finish the application is still raining there - // are water circles that are still being processed - unsigned int activeCircles = (unsigned int)this->circles.size (); + void cleanupContent() + { + // If when you finish the application is still raining there + // are water circles that are still being processed + unsigned int activeCircles = (unsigned int)this->circles.size (); - // Kill the active water circles - for (unsigned int i = 0; i < activeCircles; i++) - delete (this->circles[i]); + // Kill the active water circles + for (unsigned int i = 0; i < activeCircles; i++) + delete (this->circles[i]); - delete waterMesh; - waterMesh = 0; + delete waterMesh; + waterMesh = 0; - WaterCircle::clearStaticBuffers(); - } + WaterCircle::clearStaticBuffers(); + } protected: - Real timeoutDelay ; + Real timeoutDelay ; #define RAIN_HEIGHT_RANDOM 5 #define RAIN_HEIGHT_CONSTANT 5 - typedef vector::type WaterCircles ; - WaterCircles circles ; + typedef vector::type WaterCircles ; + WaterCircles circles ; - void processCircles(Real timeSinceLastFrame) - { - for(unsigned int i=0;ianimate(timeSinceLastFrame); - } - bool found ; - do { - found = false ; - for(WaterCircles::iterator it = circles.begin() ; + void processCircles(Real timeSinceLastFrame) + { + for(unsigned int i=0;ianimate(timeSinceLastFrame); + } + bool found ; + do { + found = false ; + for(WaterCircles::iterator it = circles.begin() ; it != circles.end(); ++it) { - if ((*it)->lvl>=16) { - delete (*it); - circles.erase(it); - found = true ; - break ; - } - } - } while (found) ; - } + if ((*it)->lvl>=16) { + delete (*it); + circles.erase(it); + found = true ; + break ; + } + } + } while (found) ; + } - void processParticles() - { - static int pindex = 0 ; - ParticleIterator pit = particleSystem->_getIterator() ; - while(!pit.end()) { - Particle *particle = pit.getNext(); - Vector3 ppos = particle->mPosition; - if (ppos.y<=0 && particle->mTimeToLive>0) { // hits the water! - // delete particle - particle->mTimeToLive = 0.0f; - // push the water - float x = ppos.x / PLANE_SIZE * COMPLEXITY ; - float y = ppos.z / PLANE_SIZE * COMPLEXITY ; - float h = rand() % RAIN_HEIGHT_RANDOM + RAIN_HEIGHT_CONSTANT ; - if (x<1) x=1 ; - if (x>COMPLEXITY-1) x=COMPLEXITY-1; - if (y<1) y=1 ; - if (y>COMPLEXITY-1) y=COMPLEXITY-1; - waterMesh->push(x,y,-h) ; - WaterCircle *circle = new WaterCircle(mSceneMgr, + void processParticles() + { + static int pindex = 0 ; + ParticleIterator pit = particleSystem->_getIterator() ; + while(!pit.end()) { + Particle *particle = pit.getNext(); + Vector3 ppos = particle->mPosition; + if (ppos.y<=0 && particle->mTimeToLive>0) { // hits the water! + // delete particle + particle->mTimeToLive = 0.0f; + // push the water + float x = ppos.x / PLANE_SIZE * COMPLEXITY ; + float y = ppos.z / PLANE_SIZE * COMPLEXITY ; + float h = rand() % RAIN_HEIGHT_RANDOM + RAIN_HEIGHT_CONSTANT ; + if (x<1) x=1 ; + if (x>COMPLEXITY-1) x=COMPLEXITY-1; + if (y<1) y=1 ; + if (y>COMPLEXITY-1) y=COMPLEXITY-1; + waterMesh->push(x,y,-h) ; + WaterCircle *circle = new WaterCircle(mSceneMgr, "Circle#"+StringConverter::toString(pindex++), x, y); - circles.push_back(circle); - } - } - } + circles.push_back(circle); + } + } + } - void sliderMoved(Slider* slider) - { - if (slider->getName() == "HeadDepthSlider") - { - headDepth = slider->getValue(); - } - else if (slider->getName() == "RippleSpeedSlider") - { - waterMesh->PARAM_C = slider->getValue(); - } - else if (slider->getName() == "DistanceSlider") - { - waterMesh->PARAM_D = slider->getValue(); - } - else if (slider->getName() == "ViscositySlider") - { - waterMesh->PARAM_U = slider->getValue(); - } - else if (slider->getName() == "FrameTimeSlider") - { - waterMesh->PARAM_T = slider->getValue(); - } - } + void sliderMoved(Slider* slider) + { + if (slider->getName() == "HeadDepthSlider") + { + headDepth = slider->getValue(); + } + else if (slider->getName() == "RippleSpeedSlider") + { + waterMesh->PARAM_C = slider->getValue(); + } + else if (slider->getName() == "DistanceSlider") + { + waterMesh->PARAM_D = slider->getValue(); + } + else if (slider->getName() == "ViscositySlider") + { + waterMesh->PARAM_U = slider->getValue(); + } + else if (slider->getName() == "FrameTimeSlider") + { + waterMesh->PARAM_T = slider->getValue(); + } + } - void checkBoxToggled(CheckBox* checkBox) - { - if (checkBox->getName() == "FakeNormalsCB") - { - waterMesh->useFakeNormals = checkBox->isChecked(); - } - else if (checkBox->getName() == "SkyboxCB") - { - sceneMgr->setSkyBox(checkBox->isChecked(), "Examples/SceneSkyBox2"); - } - } + void checkBoxToggled(CheckBox* checkBox) + { + if (checkBox->getName() == "FakeNormalsCB") + { + waterMesh->useFakeNormals = checkBox->isChecked(); + } + else if (checkBox->getName() == "SkyboxCB") + { + sceneMgr->setSkyBox(checkBox->isChecked(), "Examples/SceneSkyBox2"); + } + } - void itemSelected(SelectMenu* menu) - { - //Only one menu in this demo - const String& materialName = menu->getSelectedItem(); - MaterialPtr material = MaterialManager::getSingleton().getByName(materialName); - if (material.isNull()) + void itemSelected(SelectMenu* menu) + { + //Only one menu in this demo + const String& materialName = menu->getSelectedItem(); + MaterialPtr material = MaterialManager::getSingleton().getByName(materialName); + if (material.isNull()) { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Material "+materialName+"doesn't exist!", "WaterListener::updateMaterial"); - } - waterEntity->setMaterialName(materialName); - } + } + waterEntity->setMaterialName(materialName); + } - /** Head animation */ - Real headDepth ; - void animateHead(Real timeSinceLastFrame) - { - // sine track? :) - static double sines[4] = {0,100,200,300}; - static const double adds[4] = {0.3,-1.6,1.1,0.5}; - static Vector3 oldPos = Vector3::UNIT_Z; - for(int i=0;i<4;i++) { - sines[i]+=adds[i]*timeSinceLastFrame; - } - Real tx = ((sin(sines[0]) + sin(sines[1])) / 4 + 0.5 ) * (float)(COMPLEXITY-2) + 1 ; - Real ty = ((sin(sines[2]) + sin(sines[3])) / 4 + 0.5 ) * (float)(COMPLEXITY-2) + 1 ; - waterMesh->push(tx,ty, -headDepth); - Real step = PLANE_SIZE / COMPLEXITY ; - headNode->resetToInitialState(); - headNode->scale(3,3,3); - Vector3 newPos = Vector3(step*tx, headDepth, step*ty); - Vector3 diffPos = newPos - oldPos ; - Quaternion headRotation = Vector3::UNIT_Z.getRotationTo(diffPos); - oldPos = newPos ; - headNode->translate(newPos); - headNode->rotate(headRotation); - } + /** Head animation */ + Real headDepth ; + void animateHead(Real timeSinceLastFrame) + { + // sine track? :) + static double sines[4] = {0,100,200,300}; + static const double adds[4] = {0.3,-1.6,1.1,0.5}; + static Vector3 oldPos = Vector3::UNIT_Z; + for(int i=0;i<4;i++) { + sines[i]+=adds[i]*timeSinceLastFrame; + } + Real tx = ((sin(sines[0]) + sin(sines[1])) / 4 + 0.5 ) * (float)(COMPLEXITY-2) + 1 ; + Real ty = ((sin(sines[2]) + sin(sines[3])) / 4 + 0.5 ) * (float)(COMPLEXITY-2) + 1 ; + waterMesh->push(tx,ty, -headDepth); + Real step = PLANE_SIZE / COMPLEXITY ; + headNode->resetToInitialState(); + headNode->scale(3,3,3); + Vector3 newPos = Vector3(step*tx, headDepth, step*ty); + Vector3 diffPos = newPos - oldPos ; + Quaternion headRotation = Vector3::UNIT_Z.getRotationTo(diffPos); + oldPos = newPos ; + headNode->translate(newPos); + headNode->rotate(headRotation); + } public: bool frameRenderingQueued(const FrameEvent& evt) { - if( SdkSample::frameRenderingQueued(evt) == false ) - return false; + if( SdkSample::frameRenderingQueued(evt) == false ) + return false; mAnimState->addTime(evt.timeSinceLastFrame); - // rain - processCircles(evt.timeSinceLastFrame); - if(mInputContext.mKeyboard) - { - particleEmitter->setEmissionRate(mInputContext.mKeyboard->isKeyDown(OIS::KC_SPACE) ? 20.0f : 0.0f); - } - processParticles(); + // rain + processCircles(evt.timeSinceLastFrame); + if(mInputContext.mKeyboard) + { + particleEmitter->setEmissionRate(mInputContext.mKeyboard->isKeyDown(OIS::KC_SPACE) ? 20.0f : 0.0f); + } + processParticles(); - timeoutDelay-=evt.timeSinceLastFrame ; - if (timeoutDelay<=0) - timeoutDelay = 0; + timeoutDelay-=evt.timeSinceLastFrame ; + if (timeoutDelay<=0) + timeoutDelay = 0; - animateHead(evt.timeSinceLastFrame); + animateHead(evt.timeSinceLastFrame); - waterMesh->updateMesh(evt.timeSinceLastFrame); + waterMesh->updateMesh(evt.timeSinceLastFrame); - return true; + return true; } }; diff --git a/Samples/Water/include/WaterMesh.h b/Samples/Water/include/WaterMesh.h index eb20d20f1fb..c288272bbf1 100644 --- a/Samples/Water/include/WaterMesh.h +++ b/Samples/Water/include/WaterMesh.h @@ -24,52 +24,52 @@ using namespace Ogre ; class WaterMesh { private: - MeshPtr mesh ; - SubMesh *subMesh ; - float *vertexBuffers[3] ; // we need 3 vertex buffers - int currentBuffNumber ; - int complexity ; - String meshName ; - int numFaces ; - int numVertices ; - Vector3* vNormals ; + MeshPtr mesh ; + SubMesh *subMesh ; + float *vertexBuffers[3] ; // we need 3 vertex buffers + int currentBuffNumber ; + int complexity ; + String meshName ; + int numFaces ; + int numVertices ; + Vector3* vNormals ; - HardwareVertexBufferSharedPtr posVertexBuffer ; - HardwareVertexBufferSharedPtr normVertexBuffer ; - HardwareVertexBufferSharedPtr texcoordsVertexBuffer ; - HardwareIndexBufferSharedPtr indexBuffer ; + HardwareVertexBufferSharedPtr posVertexBuffer ; + HardwareVertexBufferSharedPtr normVertexBuffer ; + HardwareVertexBufferSharedPtr texcoordsVertexBuffer ; + HardwareIndexBufferSharedPtr indexBuffer ; - Real lastTimeStamp ; - Real lastAnimationTimeStamp; - Real lastFrameTime ; - - void calculateFakeNormals(); - void calculateNormals(); + Real lastTimeStamp ; + Real lastAnimationTimeStamp; + Real lastFrameTime ; + + void calculateFakeNormals(); + void calculateNormals(); public: - WaterMesh(const String& meshName, Real planeSize, int complexity) ; + WaterMesh(const String& meshName, Real planeSize, int complexity) ; virtual ~WaterMesh (); - /** "pushes" a mesh at position [x,y]. Note, that x,y are float, hence - * 4 vertices are actually pushed - * @note - * This should be replaced by push with 'radius' parameter to simulate - * big objects falling into water - */ - void push(Real x, Real y, Real depth, bool absolute=false) ; + /** "pushes" a mesh at position [x,y]. Note, that x,y are float, hence + * 4 vertices are actually pushed + * @note + * This should be replaced by push with 'radius' parameter to simulate + * big objects falling into water + */ + void push(Real x, Real y, Real depth, bool absolute=false) ; - /** gets height at given x and y, takes average value of the closes nodes */ - Real getHeight(Real x, Real y); + /** gets height at given x and y, takes average value of the closes nodes */ + Real getHeight(Real x, Real y); - /** updates mesh */ - void updateMesh(Real timeSinceLastFrame) ; - - Real PARAM_C ; // ripple speed - Real PARAM_D ; // distance - Real PARAM_U ; // viscosity - Real PARAM_T ; // time - bool useFakeNormals ; + /** updates mesh */ + void updateMesh(Real timeSinceLastFrame) ; + + Real PARAM_C ; // ripple speed + Real PARAM_D ; // distance + Real PARAM_U ; // viscosity + Real PARAM_T ; // time + bool useFakeNormals ; } ; #endif diff --git a/Samples/Water/src/Water.cpp b/Samples/Water/src/Water.cpp index 5eddf16eaed..75598af28ef 100644 --- a/Samples/Water/src/Water.cpp +++ b/Samples/Water/src/Water.cpp @@ -28,16 +28,16 @@ Sample* s; extern "C" _OgreSampleExport void dllStartPlugin() { - s = new Sample_Water; - sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); - sp->addSample(s); - Root::getSingleton().installPlugin(sp); + s = new Sample_Water; + sp = OGRE_NEW SamplePlugin(s->getInfo()["Title"] + " Sample"); + sp->addSample(s); + Root::getSingleton().installPlugin(sp); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(sp); - OGRE_DELETE sp; - delete s; + Root::getSingleton().uninstallPlugin(sp); + OGRE_DELETE sp; + delete s; } #endif diff --git a/Samples/Water/src/WaterMesh.cpp b/Samples/Water/src/WaterMesh.cpp index 0a6e5cec2d8..faaa9ae93c1 100644 --- a/Samples/Water/src/WaterMesh.cpp +++ b/Samples/Water/src/WaterMesh.cpp @@ -19,137 +19,137 @@ same license as the rest of the engine. WaterMesh::WaterMesh(const String& inMeshName, Real planeSize, int inComplexity) { - int x,y,b; // I prefer to initialize for() variables inside it, but VC doesn't like it ;( + int x,y,b; // I prefer to initialize for() variables inside it, but VC doesn't like it ;( - this->meshName = inMeshName ; - this->complexity = inComplexity ; - numFaces = 2 * complexity * complexity; - numVertices = (complexity + 1) * (complexity + 1) ; - lastTimeStamp = 0 ; - lastAnimationTimeStamp = 0; - lastFrameTime = 0 ; + this->meshName = inMeshName ; + this->complexity = inComplexity ; + numFaces = 2 * complexity * complexity; + numVertices = (complexity + 1) * (complexity + 1) ; + lastTimeStamp = 0 ; + lastAnimationTimeStamp = 0; + lastFrameTime = 0 ; - // initialize algorithm parameters - PARAM_C = 0.3f ; // ripple speed - PARAM_D = 0.4f ; // distance - PARAM_U = 0.05f ; // viscosity - PARAM_T = 0.13f ; // time - useFakeNormals = false ; + // initialize algorithm parameters + PARAM_C = 0.3f ; // ripple speed + PARAM_D = 0.4f ; // distance + PARAM_U = 0.05f ; // viscosity + PARAM_T = 0.13f ; // time + useFakeNormals = false ; - // allocate space for normal calculation - vNormals = new Vector3[numVertices]; + // allocate space for normal calculation + vNormals = new Vector3[numVertices]; - // create mesh and submesh - mesh = MeshManager::getSingleton().createManual(meshName, + // create mesh and submesh + mesh = MeshManager::getSingleton().createManual(meshName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - subMesh = mesh->createSubMesh(); - subMesh->useSharedVertices=false; + subMesh = mesh->createSubMesh(); + subMesh->useSharedVertices=false; - // Vertex buffers - subMesh->vertexData = new VertexData(); - subMesh->vertexData->vertexStart = 0; - subMesh->vertexData->vertexCount = numVertices; + // Vertex buffers + subMesh->vertexData = new VertexData(); + subMesh->vertexData->vertexStart = 0; + subMesh->vertexData->vertexCount = numVertices; - VertexDeclaration* vdecl = subMesh->vertexData->vertexDeclaration; - VertexBufferBinding* vbind = subMesh->vertexData->vertexBufferBinding; + VertexDeclaration* vdecl = subMesh->vertexData->vertexDeclaration; + VertexBufferBinding* vbind = subMesh->vertexData->vertexBufferBinding; - vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); - vdecl->addElement(1, 0, VET_FLOAT3, VES_NORMAL); - vdecl->addElement(2, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); + vdecl->addElement(0, 0, VET_FLOAT3, VES_POSITION); + vdecl->addElement(1, 0, VET_FLOAT3, VES_NORMAL); + vdecl->addElement(2, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); - // Prepare buffer for positions - todo: first attempt, slow - posVertexBuffer = + // Prepare buffer for positions - todo: first attempt, slow + posVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float), - numVertices, - HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); - vbind->setBinding(0, posVertexBuffer); + numVertices, + HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); + vbind->setBinding(0, posVertexBuffer); - // Prepare buffer for normals - write only - normVertexBuffer = + // Prepare buffer for normals - write only + normVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 3*sizeof(float), - numVertices, - HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); - vbind->setBinding(1, normVertexBuffer); + numVertices, + HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE); + vbind->setBinding(1, normVertexBuffer); - // Prepare texture coords buffer - static one - // todo: optimize to write directly into buffer - float *texcoordsBufData = new float[numVertices*2]; - for(y=0;y<=complexity;y++) { - for(x=0;x<=complexity;x++) { - texcoordsBufData[2*(y*(complexity+1)+x)+0] = (float)x / complexity ; - texcoordsBufData[2*(y*(complexity+1)+x)+1] = 1.0f - ((float)y / (complexity)) ; - } - } - texcoordsVertexBuffer = + // Prepare texture coords buffer - static one + // todo: optimize to write directly into buffer + float *texcoordsBufData = new float[numVertices*2]; + for(y=0;y<=complexity;y++) { + for(x=0;x<=complexity;x++) { + texcoordsBufData[2*(y*(complexity+1)+x)+0] = (float)x / complexity ; + texcoordsBufData[2*(y*(complexity+1)+x)+1] = 1.0f - ((float)y / (complexity)) ; + } + } + texcoordsVertexBuffer = HardwareBufferManager::getSingleton().createVertexBuffer( 2*sizeof(float), - numVertices, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); - texcoordsVertexBuffer->writeData(0, - texcoordsVertexBuffer->getSizeInBytes(), - texcoordsBufData, - true); // true? - delete [] texcoordsBufData; + numVertices, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); + texcoordsVertexBuffer->writeData(0, + texcoordsVertexBuffer->getSizeInBytes(), + texcoordsBufData, + true); // true? + delete [] texcoordsBufData; vbind->setBinding(2, texcoordsVertexBuffer); - // Prepare buffer for indices - indexBuffer = - HardwareBufferManager::getSingleton().createIndexBuffer( - HardwareIndexBuffer::IT_16BIT, - 3*numFaces, - HardwareBuffer::HBU_STATIC, true); - unsigned short *faceVertexIndices = (unsigned short*) - indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD); - for(y=0 ; yunlock(); - // Set index buffer for this submesh - subMesh->indexData->indexBuffer = indexBuffer; - subMesh->indexData->indexStart = 0; - subMesh->indexData->indexCount = 3*numFaces; + // Prepare buffer for indices + indexBuffer = + HardwareBufferManager::getSingleton().createIndexBuffer( + HardwareIndexBuffer::IT_16BIT, + 3*numFaces, + HardwareBuffer::HBU_STATIC, true); + unsigned short *faceVertexIndices = (unsigned short*) + indexBuffer->lock(0, numFaces*3*2, HardwareBuffer::HBL_DISCARD); + for(y=0 ; yunlock(); + // Set index buffer for this submesh + subMesh->indexData->indexBuffer = indexBuffer; + subMesh->indexData->indexStart = 0; + subMesh->indexData->indexCount = 3*numFaces; - /* prepare vertex positions - * note - we use 3 vertex buffers, since algorighm uses two last phases - * to calculate the next one - */ - for(b=0;b<3;b++) { - vertexBuffers[b] = new float[numVertices * 3] ; - for(y=0;y<=complexity;y++) { - for(x=0;x<=complexity;x++) { - int numPoint = y*(complexity+1) + x ; - float* vertex = vertexBuffers[b] + 3*numPoint ; - vertex[0]=(float)(x) / (float)(complexity) * (float) planeSize ; - vertex[1]= 0 ; // rand() % 30 ; - vertex[2]=(float)(y) / (float)(complexity) * (float) planeSize ; - } - } - } + /* prepare vertex positions + * note - we use 3 vertex buffers, since algorighm uses two last phases + * to calculate the next one + */ + for(b=0;b<3;b++) { + vertexBuffers[b] = new float[numVertices * 3] ; + for(y=0;y<=complexity;y++) { + for(x=0;x<=complexity;x++) { + int numPoint = y*(complexity+1) + x ; + float* vertex = vertexBuffers[b] + 3*numPoint ; + vertex[0]=(float)(x) / (float)(complexity) * (float) planeSize ; + vertex[1]= 0 ; // rand() % 30 ; + vertex[2]=(float)(y) / (float)(complexity) * (float) planeSize ; + } + } + } - AxisAlignedBox meshBounds(0,0,0, - planeSize,0, planeSize); - mesh->_setBounds(meshBounds); + AxisAlignedBox meshBounds(0,0,0, + planeSize,0, planeSize); + mesh->_setBounds(meshBounds); - currentBuffNumber = 0 ; - posVertexBuffer->writeData(0, - posVertexBuffer->getSizeInBytes(), // size - vertexBuffers[currentBuffNumber], // source - true); // discard? + currentBuffNumber = 0 ; + posVertexBuffer->writeData(0, + posVertexBuffer->getSizeInBytes(), // size + vertexBuffers[currentBuffNumber], // source + true); // discard? mesh->load(); mesh->touch(); @@ -157,174 +157,174 @@ WaterMesh::WaterMesh(const String& inMeshName, Real planeSize, int inComplexity) /* ========================================================================= */ WaterMesh::~WaterMesh () { - delete[] vertexBuffers[0]; - delete[] vertexBuffers[1]; - delete[] vertexBuffers[2]; + delete[] vertexBuffers[0]; + delete[] vertexBuffers[1]; + delete[] vertexBuffers[2]; - delete[] vNormals; + delete[] vNormals; - MeshManager::getSingleton().remove(meshName); + MeshManager::getSingleton().remove(meshName); } /* ========================================================================= */ void WaterMesh::push(Real x, Real y, Real depth, bool absolute) { - float *buf = vertexBuffers[currentBuffNumber]+1 ; - // scale pressure according to time passed - depth = depth * lastFrameTime * ANIMATIONS_PER_SECOND ; + float *buf = vertexBuffers[currentBuffNumber]+1 ; + // scale pressure according to time passed + depth = depth * lastFrameTime * ANIMATIONS_PER_SECOND ; #define _PREP(addx,addy) { \ - float *vertex=buf+3*((int)(y+addy)*(complexity+1)+(int)(x+addx)) ; \ - float diffy = y - floor(y+addy); \ - float diffx = x - floor(x+addx); \ - float dist=sqrt(diffy*diffy + diffx*diffx) ; \ - float power = 1 - dist ; \ - if (power<0) \ - power = 0; \ - if (absolute) \ - *vertex = depth*power ; \ - else \ - *vertex += depth*power ; \ + float *vertex=buf+3*((int)(y+addy)*(complexity+1)+(int)(x+addx)) ; \ + float diffy = y - floor(y+addy); \ + float diffx = x - floor(x+addx); \ + float dist=sqrt(diffy*diffy + diffx*diffx) ; \ + float power = 1 - dist ; \ + if (power<0) \ + power = 0; \ + if (absolute) \ + *vertex = depth*power ; \ + else \ + *vertex += depth*power ; \ } /* #define */ - _PREP(0,0); - _PREP(0,1); - _PREP(1,0); - _PREP(1,1); + _PREP(0,0); + _PREP(0,1); + _PREP(1,0); + _PREP(1,1); #undef _PREP } /* ========================================================================= */ Real WaterMesh::getHeight(Real x, Real y) { #define hat(_x,_y) buf[3*((int)_y*(complexity+1)+(int)(_x))] - float *buf = vertexBuffers[currentBuffNumber] ; - Real xa = floor(x); - Real xb = xa + 1 ; - Real ya = floor(y); - Real yb = ya + 1 ; - Real yaxavg = hat(xa,ya) * (1.0f-fabs(xa-x)) + hat(xb,ya) * (1.0f-fabs(xb-x)); - Real ybxavg = hat(xa,yb) * (1.0f-fabs(xa-x)) + hat(xb,yb) * (1.0f-fabs(xb-x)); - Real yavg = yaxavg * (1.0f-fabs(ya-y)) + ybxavg * (1.0f-fabs(yb-y)) ; - return yavg ; + float *buf = vertexBuffers[currentBuffNumber] ; + Real xa = floor(x); + Real xb = xa + 1 ; + Real ya = floor(y); + Real yb = ya + 1 ; + Real yaxavg = hat(xa,ya) * (1.0f-fabs(xa-x)) + hat(xb,ya) * (1.0f-fabs(xb-x)); + Real ybxavg = hat(xa,yb) * (1.0f-fabs(xa-x)) + hat(xb,yb) * (1.0f-fabs(xb-x)); + Real yavg = yaxavg * (1.0f-fabs(ya-y)) + ybxavg * (1.0f-fabs(yb-y)) ; + return yavg ; } /* ========================================================================= */ void WaterMesh::calculateFakeNormals() { - int x,y; - float *buf = vertexBuffers[currentBuffNumber] + 1; - float *pNormals = (float*) normVertexBuffer->lock( - 0,normVertexBuffer->getSizeInBytes(), HardwareBuffer::HBL_DISCARD); - for(y=1;yunlock(); + int x,y; + float *buf = vertexBuffers[currentBuffNumber] + 1; + float *pNormals = (float*) normVertexBuffer->lock( + 0,normVertexBuffer->getSizeInBytes(), HardwareBuffer::HBL_DISCARD); + for(y=1;yunlock(); } /* ========================================================================= */ void WaterMesh::calculateNormals() { - int i,x,y; - float *buf = NULL; - // zero normals - for(i=0;ilock( - 0, indexBuffer->getSizeInBytes(), HardwareBuffer::HBL_READ_ONLY); - float *pNormals = (float*) normVertexBuffer->lock( - 0, normVertexBuffer->getSizeInBytes(), HardwareBuffer::HBL_DISCARD); - for(i=0;iunlock(); - normVertexBuffer->unlock(); + int i,x,y; + float *buf = NULL; + // zero normals + for(i=0;ilock( + 0, indexBuffer->getSizeInBytes(), HardwareBuffer::HBL_READ_ONLY); + float *pNormals = (float*) normVertexBuffer->lock( + 0, normVertexBuffer->getSizeInBytes(), HardwareBuffer::HBL_DISCARD); + for(i=0;iunlock(); + normVertexBuffer->unlock(); } /* ========================================================================= */ void WaterMesh::updateMesh(Real timeSinceLastFrame) { - int x, y ; + int x, y ; - lastFrameTime = timeSinceLastFrame ; - lastTimeStamp += timeSinceLastFrame ; + lastFrameTime = timeSinceLastFrame ; + lastTimeStamp += timeSinceLastFrame ; - // do rendering to get ANIMATIONS_PER_SECOND - while(lastAnimationTimeStamp <= lastTimeStamp) { + // do rendering to get ANIMATIONS_PER_SECOND + while(lastAnimationTimeStamp <= lastTimeStamp) { - // switch buffer numbers - currentBuffNumber = (currentBuffNumber + 1) % 3 ; - float *buf = vertexBuffers[currentBuffNumber] + 1 ; // +1 for Y coordinate - float *buf1 = vertexBuffers[(currentBuffNumber+2)%3] + 1 ; - float *buf2 = vertexBuffers[(currentBuffNumber+1)%3] + 1; + // switch buffer numbers + currentBuffNumber = (currentBuffNumber + 1) % 3 ; + float *buf = vertexBuffers[currentBuffNumber] + 1 ; // +1 for Y coordinate + float *buf1 = vertexBuffers[(currentBuffNumber+2)%3] + 1 ; + float *buf2 = vertexBuffers[(currentBuffNumber+1)%3] + 1; - /* we use an algorithm from - * http://collective.valve-erc.com/index.php?go=water_simulation - * The params could be dynamically changed every frame of course - */ - Real C = PARAM_C; // ripple speed - Real D = PARAM_D; // distance - Real U = PARAM_U; // viscosity - Real T = PARAM_T; // time - Real TERM1 = ( 4.0f - 8.0f*C*C*T*T/(D*D) ) / (U*T+2) ; - Real TERM2 = ( U*T-2.0f ) / (U*T+2.0f) ; - Real TERM3 = ( 2.0f * C*C*T*T/(D*D) ) / (U*T+2) ; - for(y=1;ywriteData(0, - posVertexBuffer->getSizeInBytes(), // size - vertexBuffers[currentBuffNumber], // source - true); // discard? + // set vertex buffer + posVertexBuffer->writeData(0, + posVertexBuffer->getSizeInBytes(), // size + vertexBuffers[currentBuffNumber], // source + true); // discard? } diff --git a/Tests/CapsReport/main.cpp b/Tests/CapsReport/main.cpp index dc94a10db60..c3255582bf8 100644 --- a/Tests/CapsReport/main.cpp +++ b/Tests/CapsReport/main.cpp @@ -10,51 +10,51 @@ int main(char argc, char** argv) { - // Try D3D - try - { - Root root("", "", "OgreCapsReportD3D9.log"); - StringStream str; - str << "RenderSystem_Direct3D9" << OGRE_LIB_SUFFIX; - root.loadPlugin(str.str()); - - RenderSystem* rs = root.getAvailableRenderers()->at(0); - ConfigOption& opt = - rs->getConfigOptions().find("Rendering Device")->second; - opt.currentValue = opt.possibleValues[0]; - root.setRenderSystem(rs); - root.initialise(false); - root.createRenderWindow("probe", 100, 100, false); - - } - catch(std::exception&) - { - // failed D3D9 - LogManager::getSingleton().logMessage("D3D9 testing failed - perhaps you " - "don't have the D3D9 runtime installed on this machine?"); - } - - - - // Try GL - try - { - Root root("", "", "OgreCapsReportGL.log"); - StringStream str; - str << "RenderSystem_GL" << OGRE_LIB_SUFFIX; - root.loadPlugin(str.str()); - - RenderSystem* rs = root.getAvailableRenderers()->at(0); - root.setRenderSystem(rs); - root.initialise(false); - root.createRenderWindow("probe", 100, 100, false); - } - catch(std::exception&) - { - // failed GL - LogManager::getSingleton().logMessage("GL testing failed - perhaps you " - "don't have a GL driver installed on this machine?"); - } + // Try D3D + try + { + Root root("", "", "OgreCapsReportD3D9.log"); + StringStream str; + str << "RenderSystem_Direct3D9" << OGRE_LIB_SUFFIX; + root.loadPlugin(str.str()); + + RenderSystem* rs = root.getAvailableRenderers()->at(0); + ConfigOption& opt = + rs->getConfigOptions().find("Rendering Device")->second; + opt.currentValue = opt.possibleValues[0]; + root.setRenderSystem(rs); + root.initialise(false); + root.createRenderWindow("probe", 100, 100, false); + + } + catch(std::exception&) + { + // failed D3D9 + LogManager::getSingleton().logMessage("D3D9 testing failed - perhaps you " + "don't have the D3D9 runtime installed on this machine?"); + } + + + + // Try GL + try + { + Root root("", "", "OgreCapsReportGL.log"); + StringStream str; + str << "RenderSystem_GL" << OGRE_LIB_SUFFIX; + root.loadPlugin(str.str()); + + RenderSystem* rs = root.getAvailableRenderers()->at(0); + root.setRenderSystem(rs); + root.initialise(false); + root.createRenderWindow("probe", 100, 100, false); + } + catch(std::exception&) + { + // failed GL + LogManager::getSingleton().logMessage("GL testing failed - perhaps you " + "don't have a GL driver installed on this machine?"); + } } \ No newline at end of file diff --git a/Tests/Components/Paging/include/PageCoreTests.h b/Tests/Components/Paging/include/PageCoreTests.h index a9534ab32e5..18c6f474d61 100644 --- a/Tests/Components/Paging/include/PageCoreTests.h +++ b/Tests/Components/Paging/include/PageCoreTests.h @@ -42,22 +42,22 @@ using namespace Ogre; class PageCoreTests : public CppUnit::TestFixture { - // CppUnit macros for setting up the test suite - CPPUNIT_TEST_SUITE( PageCoreTests ); - CPPUNIT_TEST(testSimpleCreateSaveLoadWorld); - CPPUNIT_TEST_SUITE_END(); - - Root* mRoot; - PageManager* mPageManager; - SceneManager* mSceneMgr; + // CppUnit macros for setting up the test suite + CPPUNIT_TEST_SUITE( PageCoreTests ); + CPPUNIT_TEST(testSimpleCreateSaveLoadWorld); + CPPUNIT_TEST_SUITE_END(); + + Root* mRoot; + PageManager* mPageManager; + SceneManager* mSceneMgr; FileSystemLayer* mFSLayer; #ifdef OGRE_STATIC_LIB - StaticPluginLoader mStaticPluginLoader; + StaticPluginLoader mStaticPluginLoader; #endif public: - void setUp(); - void tearDown(); - void testSimpleCreateSaveLoadWorld(); - void testLoadWorld(); + void setUp(); + void tearDown(); + void testSimpleCreateSaveLoadWorld(); + void testLoadWorld(); }; diff --git a/Tests/Components/Paging/src/PageCoreTests.cpp b/Tests/Components/Paging/src/PageCoreTests.cpp index f0321bb1026..e37b3e278c3 100644 --- a/Tests/Components/Paging/src/PageCoreTests.cpp +++ b/Tests/Components/Paging/src/PageCoreTests.cpp @@ -34,14 +34,14 @@ CPPUNIT_TEST_SUITE_REGISTRATION( PageCoreTests ); void PageCoreTests::setUp() { // set up silent logging to not pollute output - if(LogManager::getSingletonPtr()) - OGRE_DELETE Ogre::LogManager::getSingletonPtr(); - - if(LogManager::getSingletonPtr() == 0) - { - LogManager* logManager = OGRE_NEW LogManager(); - logManager->createLog("testPageCore.log", true, false); - } + if(LogManager::getSingletonPtr()) + OGRE_DELETE Ogre::LogManager::getSingletonPtr(); + + if(LogManager::getSingletonPtr() == 0) + { + LogManager* logManager = OGRE_NEW LogManager(); + logManager->createLog("testPageCore.log", true, false); + } LogManager::getSingleton().setLogDetail(LL_LOW); mFSLayer = OGRE_NEW_T(Ogre::FileSystemLayer, Ogre::MEMCATEGORY_GENERAL)(OGRE_VERSION_NAME); @@ -50,27 +50,27 @@ void PageCoreTests::setUp() #endif #ifdef OGRE_STATIC_LIB - mRoot = OGRE_NEW Root(BLANKSTRING); + mRoot = OGRE_NEW Root(BLANKSTRING); - mStaticPluginLoader.load(); + mStaticPluginLoader.load(); #else String pluginsPath = mFSLayer->getConfigFilePath("plugins.cfg"); - mRoot = OGRE_NEW Root(pluginsPath); + mRoot = OGRE_NEW Root(pluginsPath); #endif - mPageManager = OGRE_NEW PageManager(); + mPageManager = OGRE_NEW PageManager(); - // make certain the resource location is NOT read-only - ResourceGroupManager::getSingleton().addResourceLocation("./", "FileSystem", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, false); + // make certain the resource location is NOT read-only + ResourceGroupManager::getSingleton().addResourceLocation("./", "FileSystem", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, false); - mSceneMgr = mRoot->createSceneManager(ST_GENERIC); + mSceneMgr = mRoot->createSceneManager(ST_GENERIC); } void PageCoreTests::tearDown() { - OGRE_DELETE mPageManager; - OGRE_DELETE mRoot; + OGRE_DELETE mPageManager; + OGRE_DELETE mRoot; OGRE_DELETE_T(mFSLayer, FileSystemLayer, Ogre::MEMCATEGORY_GENERAL); #if OGRE_STATIC OGRE_DELETE mStaticPluginLoader; @@ -80,31 +80,31 @@ void PageCoreTests::tearDown() void PageCoreTests::testSimpleCreateSaveLoadWorld() { - String worldName = "MyWorld"; - String filename = "myworld.world"; - String sectionName1 = "Section1"; - String sectionName2 = "Section2"; - PagedWorld* world = mPageManager->createWorld(worldName); - PagedWorldSection* section = world->createSection("Grid2D", mSceneMgr, sectionName1); - section = world->createSection("Grid2D", mSceneMgr, sectionName2); + String worldName = "MyWorld"; + String filename = "myworld.world"; + String sectionName1 = "Section1"; + String sectionName2 = "Section2"; + PagedWorld* world = mPageManager->createWorld(worldName); + PagedWorldSection* section = world->createSection("Grid2D", mSceneMgr, sectionName1); + section = world->createSection("Grid2D", mSceneMgr, sectionName2); - // Create a page - Page* p = section->loadOrCreatePage(Vector3::ZERO); + // Create a page + Page* p = section->loadOrCreatePage(Vector3::ZERO); p->createContentCollection("Simple"); - world->save(filename); + world->save(filename); - mPageManager->destroyWorld(world); - world = 0; - world = mPageManager->loadWorld(filename); + mPageManager->destroyWorld(world); + world = 0; + world = mPageManager->loadWorld(filename); - CPPUNIT_ASSERT_EQUAL(worldName, world->getName()); - CPPUNIT_ASSERT_EQUAL((size_t)2, world->getSectionCount()); + CPPUNIT_ASSERT_EQUAL(worldName, world->getName()); + CPPUNIT_ASSERT_EQUAL((size_t)2, world->getSectionCount()); - section = world->getSection(sectionName1); - CPPUNIT_ASSERT(section != 0); - section = world->getSection(sectionName2); - CPPUNIT_ASSERT(section != 0); + section = world->getSection(sectionName1); + CPPUNIT_ASSERT(section != 0); + section = world->getSection(sectionName2); + CPPUNIT_ASSERT(section != 0); } diff --git a/Tests/Components/Property/include/PropertyTests.h b/Tests/Components/Property/include/PropertyTests.h index e435b28442a..4bb7a16006a 100644 --- a/Tests/Components/Property/include/PropertyTests.h +++ b/Tests/Components/Property/include/PropertyTests.h @@ -35,13 +35,13 @@ using namespace Ogre; class PropertyTests : public CppUnit::TestFixture { - // CppUnit macros for setting up the test suite - CPPUNIT_TEST_SUITE( PropertyTests ); - CPPUNIT_TEST(testStringProp); - CPPUNIT_TEST_SUITE_END(); + // CppUnit macros for setting up the test suite + CPPUNIT_TEST_SUITE( PropertyTests ); + CPPUNIT_TEST(testStringProp); + CPPUNIT_TEST_SUITE_END(); public: - void setUp(); - void tearDown(); - void testStringProp(); + void setUp(); + void tearDown(); + void testStringProp(); }; diff --git a/Tests/Components/Property/src/PropertyTests.cpp b/Tests/Components/Property/src/PropertyTests.cpp index b44700f1eed..83e735c1912 100644 --- a/Tests/Components/Property/src/PropertyTests.cpp +++ b/Tests/Components/Property/src/PropertyTests.cpp @@ -41,33 +41,33 @@ void PropertyTests::tearDown() class Foo { protected: - String mName; + String mName; public: - void setName(const String& name) { mName = name; } - const String& getName() const { return mName; } + void setName(const String& name) { mName = name; } + const String& getName() const { return mName; } }; void PropertyTests::testStringProp() { - PropertyDefMap propertyDefs; - Foo foo; - PropertySet props; + PropertyDefMap propertyDefs; + Foo foo; + PropertySet props; - PropertyDefMap::iterator defi = propertyDefs.insert(PropertyDefMap::value_type("name", - PropertyDef("name", - "The name of the object.", PROP_STRING))).first; + PropertyDefMap::iterator defi = propertyDefs.insert(PropertyDefMap::value_type("name", + PropertyDef("name", + "The name of the object.", PROP_STRING))).first; - props.addProperty( - OGRE_NEW Property(&(defi->second), - boost::bind(&Foo::getName, &foo), - boost::bind(&Foo::setName, &foo, _1))); + props.addProperty( + OGRE_NEW Property(&(defi->second), + boost::bind(&Foo::getName, &foo), + boost::bind(&Foo::setName, &foo, _1))); - Ogre::String strName, strTest; - strTest = "A simple name"; - props.setValue("name", strTest); - props.getValue("name", strName); + Ogre::String strName, strTest; + strTest = "A simple name"; + props.setValue("name", strTest); + props.getValue("name", strName); - CPPUNIT_ASSERT_EQUAL(strTest, strName); + CPPUNIT_ASSERT_EQUAL(strTest, strName); } diff --git a/Tests/Components/Terrain/include/TerrainTests.h b/Tests/Components/Terrain/include/TerrainTests.h index c4a50004476..9cf03e31e03 100644 --- a/Tests/Components/Terrain/include/TerrainTests.h +++ b/Tests/Components/Terrain/include/TerrainTests.h @@ -41,22 +41,22 @@ using namespace Ogre; class TerrainTests : public CppUnit::TestFixture { - // CppUnit macros for setting up the test suite - CPPUNIT_TEST_SUITE( TerrainTests ); - CPPUNIT_TEST(testCreate); - CPPUNIT_TEST_SUITE_END(); + // CppUnit macros for setting up the test suite + CPPUNIT_TEST_SUITE( TerrainTests ); + CPPUNIT_TEST(testCreate); + CPPUNIT_TEST_SUITE_END(); #ifdef OGRE_STATIC_LIB StaticPluginLoader mStaticPluginLoader; #endif - Root* mRoot; - SceneManager* mSceneMgr; - TerrainGlobalOptions* mTerrainOpts; + Root* mRoot; + SceneManager* mSceneMgr; + TerrainGlobalOptions* mTerrainOpts; FileSystemLayer* mFSLayer; public: - void setUp(); - void tearDown(); - void testCreate(); + void setUp(); + void tearDown(); + void testCreate(); }; diff --git a/Tests/Components/Terrain/src/TerrainTests.cpp b/Tests/Components/Terrain/src/TerrainTests.cpp index 19a483de45c..e7f450a9867 100644 --- a/Tests/Components/Terrain/src/TerrainTests.cpp +++ b/Tests/Components/Terrain/src/TerrainTests.cpp @@ -40,29 +40,29 @@ CPPUNIT_TEST_SUITE_REGISTRATION( TerrainTests ); void TerrainTests::setUp() { // set up silent logging to not pollute output - if(LogManager::getSingletonPtr()) - OGRE_DELETE Ogre::LogManager::getSingletonPtr(); - - if(LogManager::getSingletonPtr() == 0) - { - LogManager* logManager = OGRE_NEW LogManager(); - logManager->createLog("testTerrain.log", true, false); - } + if(LogManager::getSingletonPtr()) + OGRE_DELETE Ogre::LogManager::getSingletonPtr(); + + if(LogManager::getSingletonPtr() == 0) + { + LogManager* logManager = OGRE_NEW LogManager(); + logManager->createLog("testTerrain.log", true, false); + } LogManager::getSingleton().setLogDetail(LL_LOW); mFSLayer = OGRE_NEW_T(Ogre::FileSystemLayer, Ogre::MEMCATEGORY_GENERAL)(OGRE_VERSION_NAME); #ifdef OGRE_STATIC_LIB - mRoot = OGRE_NEW Root(BLANKSTRING); + mRoot = OGRE_NEW Root(BLANKSTRING); - mStaticPluginLoader.load(); + mStaticPluginLoader.load(); #else String pluginsPath = mFSLayer->getConfigFilePath("plugins.cfg"); - mRoot = OGRE_NEW Root(pluginsPath); + mRoot = OGRE_NEW Root(pluginsPath); #endif - mTerrainOpts = OGRE_NEW TerrainGlobalOptions(); + mTerrainOpts = OGRE_NEW TerrainGlobalOptions(); - // Load resource paths from config file - ConfigFile cf; + // Load resource paths from config file + ConfigFile cf; String resourcesPath; #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 resourcesPath = mFSLayer->getConfigFilePath("resources.cfg"); @@ -72,51 +72,51 @@ void TerrainTests::setUp() cf.load(resourcesPath); - // Go through all sections & settings in the file - ConfigFile::SectionIterator seci = cf.getSectionIterator(); + // Go through all sections & settings in the file + ConfigFile::SectionIterator seci = cf.getSectionIterator(); - String secName, typeName, archName; - while (seci.hasMoreElements()) - { - secName = seci.peekNextKey(); - ConfigFile::SettingsMultiMap *settings = seci.getNext(); - ConfigFile::SettingsMultiMap::iterator i; - for (i = settings->begin(); i != settings->end(); ++i) - { - typeName = i->first; - archName = i->second; - ResourceGroupManager::getSingleton().addResourceLocation( - archName, typeName, secName); + String secName, typeName, archName; + while (seci.hasMoreElements()) + { + secName = seci.peekNextKey(); + ConfigFile::SettingsMultiMap *settings = seci.getNext(); + ConfigFile::SettingsMultiMap::iterator i; + for (i = settings->begin(); i != settings->end(); ++i) + { + typeName = i->first; + archName = i->second; + ResourceGroupManager::getSingleton().addResourceLocation( + archName, typeName, secName); - } - } + } + } - mSceneMgr = mRoot->createSceneManager(ST_GENERIC); + mSceneMgr = mRoot->createSceneManager(ST_GENERIC); } void TerrainTests::tearDown() { - OGRE_DELETE mTerrainOpts; - OGRE_DELETE mRoot; + OGRE_DELETE mTerrainOpts; + OGRE_DELETE mRoot; OGRE_DELETE_T(mFSLayer, FileSystemLayer, Ogre::MEMCATEGORY_GENERAL); } void TerrainTests::testCreate() { - Terrain* t = OGRE_NEW Terrain(mSceneMgr); - Image img; - img.load("terrain.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - Terrain::ImportData imp; - imp.inputImage = &img; - imp.terrainSize = 513; - imp.worldSize = 1000; - imp.minBatchSize = 33; - imp.maxBatchSize = 65; - t->prepare(imp); - // don't load, this requires GPU access - //t->load(); - - OGRE_DELETE t; + Terrain* t = OGRE_NEW Terrain(mSceneMgr); + Image img; + img.load("terrain.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + Terrain::ImportData imp; + imp.inputImage = &img; + imp.terrainSize = 513; + imp.worldSize = 1000; + imp.minBatchSize = 33; + imp.maxBatchSize = 65; + t->prepare(imp); + // don't load, this requires GPU access + //t->load(); + + OGRE_DELETE t; } diff --git a/Tests/OgreMain/include/DualQuaternionTests.h b/Tests/OgreMain/include/DualQuaternionTests.h index 9298a2e6031..964118540b6 100644 --- a/Tests/OgreMain/include/DualQuaternionTests.h +++ b/Tests/OgreMain/include/DualQuaternionTests.h @@ -32,18 +32,18 @@ class DualQuaternionTests : public CppUnit::TestFixture { // CppUnit macros for setting up the test suite CPPUNIT_TEST_SUITE( DualQuaternionTests ); - CPPUNIT_TEST(testConversion); + CPPUNIT_TEST(testConversion); CPPUNIT_TEST(testDefaultValue); - CPPUNIT_TEST(testMatrix); + CPPUNIT_TEST(testMatrix); CPPUNIT_TEST_SUITE_END(); public: void setUp(); void tearDown(); - //Converts back and forth between a dual quaternion and a quaternion and vector + //Converts back and forth between a dual quaternion and a quaternion and vector void testConversion(); - //Tests if the default values of a dual quaternion are the correct identity values + //Tests if the default values of a dual quaternion are the correct identity values void testDefaultValue(); - //Converts back and forth between a dual quaternion and a transformation matrix - void testMatrix(); + //Converts back and forth between a dual quaternion and a transformation matrix + void testMatrix(); }; \ No newline at end of file diff --git a/Tests/OgreMain/include/FileSystemArchiveTests.h b/Tests/OgreMain/include/FileSystemArchiveTests.h index 745334f8836..af95e993515 100644 --- a/Tests/OgreMain/include/FileSystemArchiveTests.h +++ b/Tests/OgreMain/include/FileSystemArchiveTests.h @@ -45,7 +45,7 @@ class FileSystemArchiveTests : public CppUnit::TestFixture CPPUNIT_TEST(testFindFileInfoRecursive); CPPUNIT_TEST(testFileRead); CPPUNIT_TEST(testReadInterleave); - CPPUNIT_TEST(testCreateAndRemoveFile); + CPPUNIT_TEST(testCreateAndRemoveFile); CPPUNIT_TEST_SUITE_END(); protected: String testPath; @@ -63,6 +63,6 @@ class FileSystemArchiveTests : public CppUnit::TestFixture void testFindFileInfoRecursive(); void testFileRead(); void testReadInterleave(); - void testCreateAndRemoveFile(); + void testCreateAndRemoveFile(); }; diff --git a/Tests/OgreMain/include/RadixSortTests.h b/Tests/OgreMain/include/RadixSortTests.h index 9fde99b1ea0..7b41ecb67af 100644 --- a/Tests/OgreMain/include/RadixSortTests.h +++ b/Tests/OgreMain/include/RadixSortTests.h @@ -30,24 +30,24 @@ THE SOFTWARE. class RadixSortTests : public CppUnit::TestFixture { - // CppUnit macros for setting up the test suite - CPPUNIT_TEST_SUITE( RadixSortTests ); - CPPUNIT_TEST(testFloatVector); - CPPUNIT_TEST(testFloatList); - CPPUNIT_TEST(testUnsignedIntList); - CPPUNIT_TEST(testIntList); - CPPUNIT_TEST(testUnsignedIntVector); - CPPUNIT_TEST(testIntVector); - CPPUNIT_TEST_SUITE_END(); + // CppUnit macros for setting up the test suite + CPPUNIT_TEST_SUITE( RadixSortTests ); + CPPUNIT_TEST(testFloatVector); + CPPUNIT_TEST(testFloatList); + CPPUNIT_TEST(testUnsignedIntList); + CPPUNIT_TEST(testIntList); + CPPUNIT_TEST(testUnsignedIntVector); + CPPUNIT_TEST(testIntVector); + CPPUNIT_TEST_SUITE_END(); protected: public: - void setUp(); - void tearDown(); - void testFloatVector(); - void testFloatList(); - void testUnsignedIntList(); - void testIntList(); - void testUnsignedIntVector(); - void testIntVector(); + void setUp(); + void tearDown(); + void testFloatVector(); + void testFloatList(); + void testUnsignedIntList(); + void testIntList(); + void testUnsignedIntVector(); + void testIntVector(); }; diff --git a/Tests/OgreMain/include/StreamSerialiserTests.h b/Tests/OgreMain/include/StreamSerialiserTests.h index 558ea350912..6d59165f33d 100644 --- a/Tests/OgreMain/include/StreamSerialiserTests.h +++ b/Tests/OgreMain/include/StreamSerialiserTests.h @@ -30,17 +30,17 @@ THE SOFTWARE. class StreamSerialiserTests : public CppUnit::TestFixture { - // CppUnit macros for setting up the test suite - CPPUNIT_TEST_SUITE( StreamSerialiserTests ); - CPPUNIT_TEST(testWriteBasic); + // CppUnit macros for setting up the test suite + CPPUNIT_TEST_SUITE( StreamSerialiserTests ); + CPPUNIT_TEST(testWriteBasic); - CPPUNIT_TEST_SUITE_END(); + CPPUNIT_TEST_SUITE_END(); protected: public: - void setUp(); - void tearDown(); + void setUp(); + void tearDown(); - void testWriteBasic(); + void testWriteBasic(); }; diff --git a/Tests/OgreMain/include/StringTests.h b/Tests/OgreMain/include/StringTests.h index b65f71c63ee..b0c33158c23 100755 --- a/Tests/OgreMain/include/StringTests.h +++ b/Tests/OgreMain/include/StringTests.h @@ -38,55 +38,55 @@ class StringTests : public CppUnit::TestFixture CPPUNIT_TEST(testSplitFileNameAbsolutePath); CPPUNIT_TEST(testMatchCaseSensitive); CPPUNIT_TEST(testMatchCaseInSensitive); - CPPUNIT_TEST(testMatchGlobAll); + CPPUNIT_TEST(testMatchGlobAll); CPPUNIT_TEST(testMatchGlobStart); CPPUNIT_TEST(testMatchGlobEnd); CPPUNIT_TEST(testMatchGlobStartAndEnd); CPPUNIT_TEST(testMatchGlobMiddle); CPPUNIT_TEST(testMatchSuperGlobtastic); - CPPUNIT_TEST(testParseReal); - CPPUNIT_TEST(testParseInt); - CPPUNIT_TEST(testParseLong); - CPPUNIT_TEST(testParseUnsignedLong); - CPPUNIT_TEST(testParseVector3); - CPPUNIT_TEST(testParseMatrix4); - CPPUNIT_TEST(testParseQuaternion); - CPPUNIT_TEST(testParseBool); - CPPUNIT_TEST(testParseColourValue); + CPPUNIT_TEST(testParseReal); + CPPUNIT_TEST(testParseInt); + CPPUNIT_TEST(testParseLong); + CPPUNIT_TEST(testParseUnsignedLong); + CPPUNIT_TEST(testParseVector3); + CPPUNIT_TEST(testParseMatrix4); + CPPUNIT_TEST(testParseQuaternion); + CPPUNIT_TEST(testParseBool); + CPPUNIT_TEST(testParseColourValue); CPPUNIT_TEST_SUITE_END(); protected: - Ogre::String testFileNoPath; - Ogre::String testFileRelativePathWindows; - Ogre::String testFileRelativePathUnix; - Ogre::String testFileAbsolutePathWindows; - Ogre::String testFileAbsolutePathUnix; + Ogre::String testFileNoPath; + Ogre::String testFileRelativePathWindows; + Ogre::String testFileRelativePathUnix; + Ogre::String testFileAbsolutePathWindows; + Ogre::String testFileAbsolutePathUnix; public: void setUp(); void tearDown(); - // StringUtil::splitFileName tests + // StringUtil::splitFileName tests void testSplitFileNameNoPath(); void testSplitFileNameRelativePath(); void testSplitFileNameAbsolutePath(); - // StringUtil::match tests + // StringUtil::match tests void testMatchCaseSensitive(); void testMatchCaseInSensitive(); - void testMatchGlobAll(); - void testMatchGlobStart(); - void testMatchGlobEnd(); - void testMatchGlobStartAndEnd(); - void testMatchGlobMiddle(); - void testMatchSuperGlobtastic(); - // StringConverter tests - void testParseReal(); - void testParseInt(); - void testParseLong(); - void testParseUnsignedLong(); - void testParseVector3(); - void testParseMatrix4(); - void testParseQuaternion(); - void testParseBool(); - void testParseColourValue(); + void testMatchGlobAll(); + void testMatchGlobStart(); + void testMatchGlobEnd(); + void testMatchGlobStartAndEnd(); + void testMatchGlobMiddle(); + void testMatchSuperGlobtastic(); + // StringConverter tests + void testParseReal(); + void testParseInt(); + void testParseLong(); + void testParseUnsignedLong(); + void testParseVector3(); + void testParseMatrix4(); + void testParseQuaternion(); + void testParseBool(); + void testParseColourValue(); }; diff --git a/Tests/OgreMain/src/DualQuaternionTests.cpp b/Tests/OgreMain/src/DualQuaternionTests.cpp index d8fc060c71f..5582bd545e4 100644 --- a/Tests/OgreMain/src/DualQuaternionTests.cpp +++ b/Tests/OgreMain/src/DualQuaternionTests.cpp @@ -45,52 +45,52 @@ void DualQuaternionTests::tearDown() void DualQuaternionTests::testConversion() { - DualQuaternion dQuat; - Quaternion quat(Radian(Degree(60)), Vector3::UNIT_Y); - Vector3 translation(0, 0, 10); - dQuat.fromRotationTranslation(quat, translation); - - Quaternion result; - Vector3 resTrans; - dQuat.toRotationTranslation(result, resTrans); - - CPPUNIT_ASSERT_EQUAL(result, quat); - CPPUNIT_ASSERT(resTrans.positionEquals(translation)); + DualQuaternion dQuat; + Quaternion quat(Radian(Degree(60)), Vector3::UNIT_Y); + Vector3 translation(0, 0, 10); + dQuat.fromRotationTranslation(quat, translation); + + Quaternion result; + Vector3 resTrans; + dQuat.toRotationTranslation(result, resTrans); + + CPPUNIT_ASSERT_EQUAL(result, quat); + CPPUNIT_ASSERT(resTrans.positionEquals(translation)); } void DualQuaternionTests::testDefaultValue() { - DualQuaternion dQuatDefault; - - Quaternion quatDefault; - Vector3 transDefault; - - dQuatDefault.toRotationTranslation(quatDefault, transDefault); - - CPPUNIT_ASSERT_EQUAL(quatDefault, Quaternion::IDENTITY); - CPPUNIT_ASSERT(transDefault.positionEquals(Vector3::ZERO)); + DualQuaternion dQuatDefault; + + Quaternion quatDefault; + Vector3 transDefault; + + dQuatDefault.toRotationTranslation(quatDefault, transDefault); + + CPPUNIT_ASSERT_EQUAL(quatDefault, Quaternion::IDENTITY); + CPPUNIT_ASSERT(transDefault.positionEquals(Vector3::ZERO)); } void DualQuaternionTests::testMatrix() { - Matrix4 transform; - Vector3 translation(10, 4, 0); - Vector3 scale = Vector3::UNIT_SCALE; - Quaternion rotation; - rotation.FromAngleAxis(Radian(Math::PI), Vector3::UNIT_Z); - transform.makeTransform(translation, scale, rotation); - - DualQuaternion dQuat; - dQuat.fromTransformationMatrix(transform); - Matrix4 transformResult; - dQuat.toTransformationMatrix(transformResult); - - Vector3 translationResult; - Vector3 scaleResult; - Quaternion rotationResult; - transformResult.decomposition(translationResult, scaleResult, rotationResult); - - CPPUNIT_ASSERT(translationResult.positionEquals(translation)); - CPPUNIT_ASSERT(scaleResult.positionEquals(scale)); - CPPUNIT_ASSERT(rotationResult.equals(rotation, Radian(0.001))); + Matrix4 transform; + Vector3 translation(10, 4, 0); + Vector3 scale = Vector3::UNIT_SCALE; + Quaternion rotation; + rotation.FromAngleAxis(Radian(Math::PI), Vector3::UNIT_Z); + transform.makeTransform(translation, scale, rotation); + + DualQuaternion dQuat; + dQuat.fromTransformationMatrix(transform); + Matrix4 transformResult; + dQuat.toTransformationMatrix(transformResult); + + Vector3 translationResult; + Vector3 scaleResult; + Quaternion rotationResult; + transformResult.decomposition(translationResult, scaleResult, rotationResult); + + CPPUNIT_ASSERT(translationResult.positionEquals(translation)); + CPPUNIT_ASSERT(scaleResult.positionEquals(scale)); + CPPUNIT_ASSERT(rotationResult.equals(rotation, Radian(0.001))); } \ No newline at end of file diff --git a/Tests/OgreMain/src/EdgeBuilderTests.cpp b/Tests/OgreMain/src/EdgeBuilderTests.cpp index 7a35bd44620..da5c4a89fed 100644 --- a/Tests/OgreMain/src/EdgeBuilderTests.cpp +++ b/Tests/OgreMain/src/EdgeBuilderTests.cpp @@ -35,12 +35,12 @@ CPPUNIT_TEST_SUITE_REGISTRATION( EdgeBuilderTests ); void EdgeBuilderTests::setUp() { - OGRE_DELETE LogManager::getSingletonPtr(); - mLogManager = OGRE_NEW LogManager(); - mLogManager->createLog("EdgeBuilderTests.log", true); - mLogManager->setLogDetail(LL_LOW); + OGRE_DELETE LogManager::getSingletonPtr(); + mLogManager = OGRE_NEW LogManager(); + mLogManager->createLog("EdgeBuilderTests.log", true); + mLogManager->setLogDetail(LL_LOW); - mBufMgr = OGRE_NEW DefaultHardwareBufferManager(); + mBufMgr = OGRE_NEW DefaultHardwareBufferManager(); } void EdgeBuilderTests::tearDown() { diff --git a/Tests/OgreMain/src/FileSystemArchiveTests.cpp b/Tests/OgreMain/src/FileSystemArchiveTests.cpp index 5f2566ed3df..104a2fe2532 100644 --- a/Tests/OgreMain/src/FileSystemArchiveTests.cpp +++ b/Tests/OgreMain/src/FileSystemArchiveTests.cpp @@ -47,19 +47,19 @@ void FileSystemArchiveTests::tearDown() void FileSystemArchiveTests::testListNonRecursive() { - try { - FileSystemArchive arch(testPath, "FileSystem", true); - arch.load(); - StringVectorPtr vec = arch.list(false); - - CPPUNIT_ASSERT_EQUAL((unsigned int)2, (unsigned int)vec->size()); - CPPUNIT_ASSERT_EQUAL(String("rootfile.txt"), vec->at(0)); - CPPUNIT_ASSERT_EQUAL(String("rootfile2.txt"), vec->at(1)); - } - catch (Exception& e) - { - std::cout << e.getFullDescription(); - } + try { + FileSystemArchive arch(testPath, "FileSystem", true); + arch.load(); + StringVectorPtr vec = arch.list(false); + + CPPUNIT_ASSERT_EQUAL((unsigned int)2, (unsigned int)vec->size()); + CPPUNIT_ASSERT_EQUAL(String("rootfile.txt"), vec->at(0)); + CPPUNIT_ASSERT_EQUAL(String("rootfile2.txt"), vec->at(1)); + } + catch (Exception& e) + { + std::cout << e.getFullDescription(); + } } void FileSystemArchiveTests::testListRecursive() @@ -280,22 +280,22 @@ void FileSystemArchiveTests::testReadInterleave() void FileSystemArchiveTests::testCreateAndRemoveFile() { - FileSystemArchive arch("./", "FileSystem", false); - arch.load(); + FileSystemArchive arch("./", "FileSystem", false); + arch.load(); - CPPUNIT_ASSERT(!arch.isReadOnly()); + CPPUNIT_ASSERT(!arch.isReadOnly()); - String fileName = "a_test_file.txt"; - DataStreamPtr stream = arch.create(fileName); + String fileName = "a_test_file.txt"; + DataStreamPtr stream = arch.create(fileName); - String testString = "Some text here"; - size_t written = stream->write((void*)testString.c_str(), testString.size()); - CPPUNIT_ASSERT_EQUAL(testString.size(), written); + String testString = "Some text here"; + size_t written = stream->write((void*)testString.c_str(), testString.size()); + CPPUNIT_ASSERT_EQUAL(testString.size(), written); - stream->close(); + stream->close(); - arch.remove(fileName); + arch.remove(fileName); - CPPUNIT_ASSERT(!arch.exists(fileName)); + CPPUNIT_ASSERT(!arch.exists(fileName)); } diff --git a/Tests/OgreMain/src/MeshSerializerTests.cpp b/Tests/OgreMain/src/MeshSerializerTests.cpp index 35ec555fea1..2e872bee698 100644 --- a/Tests/OgreMain/src/MeshSerializerTests.cpp +++ b/Tests/OgreMain/src/MeshSerializerTests.cpp @@ -71,559 +71,559 @@ CPPUNIT_TEST_SUITE_REGISTRATION(MeshSerializerTests); void MeshSerializerTests::setUp() { - errorFactor = 0.05; + errorFactor = 0.05; - OGRE_DELETE LogManager::getSingletonPtr(); - mLogManager = OGRE_NEW LogManager(); - mLogManager->createLog("MeshWithoutIndexDataTests.log", false); - mLogManager->setLogDetail(LL_LOW); + OGRE_DELETE LogManager::getSingletonPtr(); + mLogManager = OGRE_NEW LogManager(); + mLogManager->createLog("MeshWithoutIndexDataTests.log", false); + mLogManager->setLogDetail(LL_LOW); - mFSLayer = OGRE_NEW_T(Ogre::FileSystemLayer, Ogre::MEMCATEGORY_GENERAL)(OGRE_VERSION_NAME); + mFSLayer = OGRE_NEW_T(Ogre::FileSystemLayer, Ogre::MEMCATEGORY_GENERAL)(OGRE_VERSION_NAME); - OGRE_NEW ResourceGroupManager(); - OGRE_NEW LodStrategyManager(); - OGRE_NEW DefaultHardwareBufferManager(); - OGRE_NEW MeshManager(); - OGRE_NEW SkeletonManager(); - ArchiveManager* archiveMgr = OGRE_NEW ArchiveManager(); - archiveMgr->addArchiveFactory(OGRE_NEW FileSystemArchiveFactory()); + OGRE_NEW ResourceGroupManager(); + OGRE_NEW LodStrategyManager(); + OGRE_NEW DefaultHardwareBufferManager(); + OGRE_NEW MeshManager(); + OGRE_NEW SkeletonManager(); + ArchiveManager* archiveMgr = OGRE_NEW ArchiveManager(); + archiveMgr->addArchiveFactory(OGRE_NEW FileSystemArchiveFactory()); - MaterialManager* matMgr = OGRE_NEW MaterialManager(); - matMgr->initialise(); + MaterialManager* matMgr = OGRE_NEW MaterialManager(); + matMgr->initialise(); - // Load resource paths from config file - ConfigFile cf; - String resourcesPath; + // Load resource paths from config file + ConfigFile cf; + String resourcesPath; #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 - resourcesPath = mFSLayer->getConfigFilePath("resources.cfg"); + resourcesPath = mFSLayer->getConfigFilePath("resources.cfg"); #else - resourcesPath = mFSLayer->getConfigFilePath("bin/resources.cfg"); + resourcesPath = mFSLayer->getConfigFilePath("bin/resources.cfg"); #endif - // Go through all sections & settings in the file - cf.load(resourcesPath); - ConfigFile::SectionIterator seci = cf.getSectionIterator(); - - String secName, typeName, archName; - while (seci.hasMoreElements()) { - secName = seci.peekNextKey(); - ConfigFile::SettingsMultiMap* settings = seci.getNext(); - ConfigFile::SettingsMultiMap::iterator i; - for (i = settings->begin(); i != settings->end(); ++i) { - typeName = i->first; - archName = i->second; - if (typeName == "FileSystem") { - ResourceGroupManager::getSingleton().addResourceLocation( - archName, typeName, secName); - } - - } - } - - mMesh = MeshManager::getSingleton().load("knot.mesh", ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); - - getResourceFullPath(mMesh, mMeshFullPath); - if (!copyFile(mMeshFullPath + ".bak", mMeshFullPath)) { - // If there is no backup, create one. - copyFile(mMeshFullPath, mMeshFullPath + ".bak"); - } - mSkeletonFullPath = ""; - mSkeleton = SkeletonManager::getSingleton().load("jaiqua.skeleton", "Popular").staticCast(); - getResourceFullPath(mSkeleton, mSkeletonFullPath); - if (!copyFile(mSkeletonFullPath + ".bak", mSkeletonFullPath)) { - // If there is no backup, create one. - copyFile(mSkeletonFullPath, mSkeletonFullPath + ".bak"); - } - - mMesh->reload(); + // Go through all sections & settings in the file + cf.load(resourcesPath); + ConfigFile::SectionIterator seci = cf.getSectionIterator(); + + String secName, typeName, archName; + while (seci.hasMoreElements()) { + secName = seci.peekNextKey(); + ConfigFile::SettingsMultiMap* settings = seci.getNext(); + ConfigFile::SettingsMultiMap::iterator i; + for (i = settings->begin(); i != settings->end(); ++i) { + typeName = i->first; + archName = i->second; + if (typeName == "FileSystem") { + ResourceGroupManager::getSingleton().addResourceLocation( + archName, typeName, secName); + } + + } + } + + mMesh = MeshManager::getSingleton().load("knot.mesh", ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); + + getResourceFullPath(mMesh, mMeshFullPath); + if (!copyFile(mMeshFullPath + ".bak", mMeshFullPath)) { + // If there is no backup, create one. + copyFile(mMeshFullPath, mMeshFullPath + ".bak"); + } + mSkeletonFullPath = ""; + mSkeleton = SkeletonManager::getSingleton().load("jaiqua.skeleton", "Popular").staticCast(); + getResourceFullPath(mSkeleton, mSkeletonFullPath); + if (!copyFile(mSkeletonFullPath + ".bak", mSkeletonFullPath)) { + // If there is no backup, create one. + copyFile(mSkeletonFullPath, mSkeletonFullPath + ".bak"); + } + + mMesh->reload(); #ifdef OGRE_BUILD_COMPONENT_MESHLODGENERATOR - { - MeshLodGenerator().generateAutoconfiguredLodLevels(mMesh); - } + { + MeshLodGenerator().generateAutoconfiguredLodLevels(mMesh); + } #endif /* ifdef OGRE_BUILD_COMPONENT_MESHLODGENERATOR */ - mOrigMesh = mMesh->clone(mMesh->getName() + ".orig.mesh", mMesh->getGroup()); + mOrigMesh = mMesh->clone(mMesh->getName() + ".orig.mesh", mMesh->getGroup()); } void MeshSerializerTests::tearDown() { - // Copy back original file. - if (!mMeshFullPath.empty()) { - copyFile(mMeshFullPath + ".bak", mMeshFullPath); - } - if (!mSkeletonFullPath.empty()) { - copyFile(mSkeletonFullPath + ".bak", mSkeletonFullPath); - } - if (!mMesh.isNull()) { - mMesh->unload(); - mMesh.setNull(); - } - if (!mOrigMesh.isNull()) { - mOrigMesh->unload(); - mOrigMesh.setNull(); - } - if (!mSkeleton.isNull()) { - mSkeleton->unload(); - mSkeleton.setNull(); - } - OGRE_DELETE MeshManager::getSingletonPtr(); - OGRE_DELETE SkeletonManager::getSingletonPtr(); - OGRE_DELETE DefaultHardwareBufferManager::getSingletonPtr(); - OGRE_DELETE ArchiveManager::getSingletonPtr(); - OGRE_DELETE MaterialManager::getSingletonPtr(); - OGRE_DELETE LodStrategyManager::getSingletonPtr(); - OGRE_DELETE ResourceGroupManager::getSingletonPtr(); - OGRE_DELETE_T(mFSLayer, FileSystemLayer, Ogre::MEMCATEGORY_GENERAL); - OGRE_DELETE mLogManager; + // Copy back original file. + if (!mMeshFullPath.empty()) { + copyFile(mMeshFullPath + ".bak", mMeshFullPath); + } + if (!mSkeletonFullPath.empty()) { + copyFile(mSkeletonFullPath + ".bak", mSkeletonFullPath); + } + if (!mMesh.isNull()) { + mMesh->unload(); + mMesh.setNull(); + } + if (!mOrigMesh.isNull()) { + mOrigMesh->unload(); + mOrigMesh.setNull(); + } + if (!mSkeleton.isNull()) { + mSkeleton->unload(); + mSkeleton.setNull(); + } + OGRE_DELETE MeshManager::getSingletonPtr(); + OGRE_DELETE SkeletonManager::getSingletonPtr(); + OGRE_DELETE DefaultHardwareBufferManager::getSingletonPtr(); + OGRE_DELETE ArchiveManager::getSingletonPtr(); + OGRE_DELETE MaterialManager::getSingletonPtr(); + OGRE_DELETE LodStrategyManager::getSingletonPtr(); + OGRE_DELETE ResourceGroupManager::getSingletonPtr(); + OGRE_DELETE_T(mFSLayer, FileSystemLayer, Ogre::MEMCATEGORY_GENERAL); + OGRE_DELETE mLogManager; } void MeshSerializerTests::testMesh_clone() { - MeshPtr cloneMesh = mMesh->clone(mMesh->getName() + ".clone.mesh", mMesh->getGroup()); - assertMeshClone(mMesh.get(), cloneMesh.get()); + MeshPtr cloneMesh = mMesh->clone(mMesh->getName() + ".clone.mesh", mMesh->getGroup()); + assertMeshClone(mMesh.get(), cloneMesh.get()); } void MeshSerializerTests::testMesh(MeshVersion version) { - MeshSerializer serializer; - serializer.exportMesh(mOrigMesh.get(), mMeshFullPath, version); - mMesh->reload(); - assertMeshClone(mOrigMesh.get(), mMesh.get(), version); + MeshSerializer serializer; + serializer.exportMesh(mOrigMesh.get(), mMeshFullPath, version); + mMesh->reload(); + assertMeshClone(mOrigMesh.get(), mMesh.get(), version); } void MeshSerializerTests::testSkeleton_Version_1_8() { - if (!mSkeleton.isNull()) { - SkeletonSerializer skeletonSerializer; - skeletonSerializer.exportSkeleton(mSkeleton.get(), mSkeletonFullPath, SKELETON_VERSION_1_8); - mSkeleton->reload(); - } + if (!mSkeleton.isNull()) { + SkeletonSerializer skeletonSerializer; + skeletonSerializer.exportSkeleton(mSkeleton.get(), mSkeletonFullPath, SKELETON_VERSION_1_8); + mSkeleton->reload(); + } } void MeshSerializerTests::testSkeleton_Version_1_0() { - if (!mSkeleton.isNull()) { - SkeletonSerializer skeletonSerializer; - skeletonSerializer.exportSkeleton(mSkeleton.get(), mSkeletonFullPath, SKELETON_VERSION_1_0); - mSkeleton->reload(); - } + if (!mSkeleton.isNull()) { + SkeletonSerializer skeletonSerializer; + skeletonSerializer.exportSkeleton(mSkeleton.get(), mSkeletonFullPath, SKELETON_VERSION_1_0); + mSkeleton->reload(); + } } void MeshSerializerTests::testMesh_Version_1_10() { - testMesh(MESH_VERSION_LATEST); + testMesh(MESH_VERSION_LATEST); } void MeshSerializerTests::testMesh_Version_1_8() { - testMesh(MESH_VERSION_1_8); + testMesh(MESH_VERSION_1_8); } void MeshSerializerTests::testMesh_Version_1_41() { - testMesh(MESH_VERSION_1_7); + testMesh(MESH_VERSION_1_7); } void MeshSerializerTests::testMesh_Version_1_4() { - testMesh(MESH_VERSION_1_4); + testMesh(MESH_VERSION_1_4); } void MeshSerializerTests::testMesh_Version_1_3() { - testMesh(MESH_VERSION_1_0); + testMesh(MESH_VERSION_1_0); } void MeshSerializerTests::testMesh_Version_1_2() { - // Exporting legacy Mesh not supported! - // testMesh(MESH_VERSION_LEGACY); + // Exporting legacy Mesh not supported! + // testMesh(MESH_VERSION_LEGACY); #ifdef I_HAVE_LOT_OF_FREE_TIME - // My sandboxing test. Takes a long time to complete! - // Runs on all meshes and exports all to every Lod version. - char* groups [] = { "Popular", "General", "Tests" }; - for (int i = 0; i < 3; i++) { - StringVectorPtr meshes = ResourceGroupManager::getSingleton().findResourceNames(groups[i], "*.mesh"); - StringVector::iterator it, itEnd; - it = meshes->begin(); - itEnd = meshes->end(); - for (; it != itEnd; it++) { - try { - mMesh = MeshManager::getSingleton().load(*it, groups[i]); - } - catch(std::exception e) - { - // OutputDebugStringA(e.what()); - } - getResourceFullPath(mMesh, mMeshFullPath); - if (!copyFile(mMeshFullPath + ".bak", mMeshFullPath)) { - // If there is no backup, create one. - copyFile(mMeshFullPath, mMeshFullPath + ".bak"); - } - mOrigMesh = mMesh->clone(mMesh->getName() + ".orig.mesh", mMesh->getGroup()); - testMesh_XML(); - testMesh(MESH_VERSION_1_10); - testMesh(MESH_VERSION_1_8); - testMesh(MESH_VERSION_1_7); - testMesh(MESH_VERSION_1_4); - testMesh(MESH_VERSION_1_0); - } - meshes = ResourceGroupManager::getSingleton().findResourceNames(groups[i], "*.skeleton"); - it = meshes->begin(); - itEnd = meshes->end(); - for (; it != itEnd; it++) { - mSkeleton = SkeletonManager::getSingleton().load(*it, groups[i]); - getResourceFullPath(mSkeleton, mSkeletonFullPath); - if (!copyFile(mSkeletonFullPath + ".bak", mSkeletonFullPath)) { - // If there is no backup, create one. - copyFile(mSkeletonFullPath, mSkeletonFullPath + ".bak"); - } - SkeletonSerializer skeletonSerializer; - skeletonSerializer.exportSkeleton(mSkeleton.get(), mSkeletonFullPath, SKELETON_VERSION_1_8); - mSkeleton->reload(); - skeletonSerializer.exportSkeleton(mSkeleton.get(), mSkeletonFullPath, SKELETON_VERSION_1_0); - mSkeleton->reload(); - } - } + // My sandboxing test. Takes a long time to complete! + // Runs on all meshes and exports all to every Lod version. + char* groups [] = { "Popular", "General", "Tests" }; + for (int i = 0; i < 3; i++) { + StringVectorPtr meshes = ResourceGroupManager::getSingleton().findResourceNames(groups[i], "*.mesh"); + StringVector::iterator it, itEnd; + it = meshes->begin(); + itEnd = meshes->end(); + for (; it != itEnd; it++) { + try { + mMesh = MeshManager::getSingleton().load(*it, groups[i]); + } + catch(std::exception e) + { + // OutputDebugStringA(e.what()); + } + getResourceFullPath(mMesh, mMeshFullPath); + if (!copyFile(mMeshFullPath + ".bak", mMeshFullPath)) { + // If there is no backup, create one. + copyFile(mMeshFullPath, mMeshFullPath + ".bak"); + } + mOrigMesh = mMesh->clone(mMesh->getName() + ".orig.mesh", mMesh->getGroup()); + testMesh_XML(); + testMesh(MESH_VERSION_1_10); + testMesh(MESH_VERSION_1_8); + testMesh(MESH_VERSION_1_7); + testMesh(MESH_VERSION_1_4); + testMesh(MESH_VERSION_1_0); + } + meshes = ResourceGroupManager::getSingleton().findResourceNames(groups[i], "*.skeleton"); + it = meshes->begin(); + itEnd = meshes->end(); + for (; it != itEnd; it++) { + mSkeleton = SkeletonManager::getSingleton().load(*it, groups[i]); + getResourceFullPath(mSkeleton, mSkeletonFullPath); + if (!copyFile(mSkeletonFullPath + ".bak", mSkeletonFullPath)) { + // If there is no backup, create one. + copyFile(mSkeletonFullPath, mSkeletonFullPath + ".bak"); + } + SkeletonSerializer skeletonSerializer; + skeletonSerializer.exportSkeleton(mSkeleton.get(), mSkeletonFullPath, SKELETON_VERSION_1_8); + mSkeleton->reload(); + skeletonSerializer.exportSkeleton(mSkeleton.get(), mSkeletonFullPath, SKELETON_VERSION_1_0); + mSkeleton->reload(); + } + } #endif /* ifdef I_HAVE_LOT_OF_FREE_TIME */ } void MeshSerializerTests::testMesh_XML() { #ifdef OGRE_TEST_XMLSERIALIZER - XMLMeshSerializer serializerXML; - serializerXML.exportMesh(mOrigMesh.get(), mMeshFullPath + ".xml"); - mMesh = MeshManager::getSingleton().create(mMesh->getName() + ".test.mesh", mMesh->getGroup()); - serializerXML.importMesh(mMeshFullPath + ".xml", VET_COLOUR_ABGR, mMesh.get()); - assertMeshClone(mOrigMesh.get(), mMesh.get()); + XMLMeshSerializer serializerXML; + serializerXML.exportMesh(mOrigMesh.get(), mMeshFullPath + ".xml"); + mMesh = MeshManager::getSingleton().create(mMesh->getName() + ".test.mesh", mMesh->getGroup()); + serializerXML.importMesh(mMeshFullPath + ".xml", VET_COLOUR_ABGR, mMesh.get()); + assertMeshClone(mOrigMesh.get(), mMesh.get()); #endif } void MeshSerializerTests::assertMeshClone(Mesh* a, Mesh* b, MeshVersion version /*= MESH_VERSION_LATEST*/) { - // TODO: Compare skeleton - // TODO: Compare animations - // TODO: Compare pose animations + // TODO: Compare skeleton + // TODO: Compare animations + // TODO: Compare pose animations - // CPPUNIT_ASSERT(a->getGroup() == b->getGroup()); - // CPPUNIT_ASSERT(a->getName() == b->getName()); + // CPPUNIT_ASSERT(a->getGroup() == b->getGroup()); + // CPPUNIT_ASSERT(a->getName() == b->getName()); #ifndef OGRE_TEST_XMLSERIALIZER - // XML serializer fails on these! - CPPUNIT_ASSERT(isEqual(a->getBoundingSphereRadius(), b->getBoundingSphereRadius())); - CPPUNIT_ASSERT(isEqual(a->getBounds().getMinimum(), b->getBounds().getMinimum())); - CPPUNIT_ASSERT(isEqual(a->getBounds().getMaximum(), b->getBounds().getMaximum())); + // XML serializer fails on these! + CPPUNIT_ASSERT(isEqual(a->getBoundingSphereRadius(), b->getBoundingSphereRadius())); + CPPUNIT_ASSERT(isEqual(a->getBounds().getMinimum(), b->getBounds().getMinimum())); + CPPUNIT_ASSERT(isEqual(a->getBounds().getMaximum(), b->getBounds().getMaximum())); #else - StringStream str; - Real val1 = a->getBoundingSphereRadius(); - Real val2 = b->getBoundingSphereRadius(); - Real diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); - if (diff > 1.1) { - str << "bound sphere diff: " << diff << std::endl; - } - val1 = a->getBounds().getMinimum().length(); - val2 = b->getBounds().getMinimum().length(); - diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); - if (diff > 1.1) { - str << "bound min diff: " << diff << std::endl; - } - val1 = a->getBounds().getMaximum().length(); - val2 = b->getBounds().getMaximum().length(); - diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); - if (diff > 1.1) { - str << "bound max diff: " << diff << std::endl; - } - if (!str.str().empty()) { - StringStream str2; - str2 << std::endl << "Mesh name: " << b->getName() << std::endl; - str2 << str.str(); - std::cout << str2.str(); - // OutputDebugStringA(str2.str().c_str()); - } + StringStream str; + Real val1 = a->getBoundingSphereRadius(); + Real val2 = b->getBoundingSphereRadius(); + Real diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); + if (diff > 1.1) { + str << "bound sphere diff: " << diff << std::endl; + } + val1 = a->getBounds().getMinimum().length(); + val2 = b->getBounds().getMinimum().length(); + diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); + if (diff > 1.1) { + str << "bound min diff: " << diff << std::endl; + } + val1 = a->getBounds().getMaximum().length(); + val2 = b->getBounds().getMaximum().length(); + diff = (val1 > val2) ? (val1 / val2) : (val2 / val1); + if (diff > 1.1) { + str << "bound max diff: " << diff << std::endl; + } + if (!str.str().empty()) { + StringStream str2; + str2 << std::endl << "Mesh name: " << b->getName() << std::endl; + str2 << str.str(); + std::cout << str2.str(); + // OutputDebugStringA(str2.str().c_str()); + } #endif /* ifndef OGRE_TEST_XMLSERIALIZER */ - // AutobuildEdgeLists is not saved to mesh file. You need to set it after loading a mesh! - // CPPUNIT_ASSERT(a->getAutoBuildEdgeLists() == b->getAutoBuildEdgeLists()); - CPPUNIT_ASSERT(isHashMapClone(a->getSubMeshNameMap(), b->getSubMeshNameMap())); - - assertVertexDataClone(a->sharedVertexData, b->sharedVertexData); - CPPUNIT_ASSERT(a->getCreator() == b->getCreator()); - CPPUNIT_ASSERT(a->getIndexBufferUsage() == b->getIndexBufferUsage()); - CPPUNIT_ASSERT(a->getSharedVertexDataAnimationIncludesNormals() == b->getSharedVertexDataAnimationIncludesNormals()); - CPPUNIT_ASSERT(a->getSharedVertexDataAnimationType() == b->getSharedVertexDataAnimationType()); - CPPUNIT_ASSERT(a->getVertexBufferUsage() == b->getVertexBufferUsage()); - CPPUNIT_ASSERT(a->hasVertexAnimation() == b->hasVertexAnimation()); + // AutobuildEdgeLists is not saved to mesh file. You need to set it after loading a mesh! + // CPPUNIT_ASSERT(a->getAutoBuildEdgeLists() == b->getAutoBuildEdgeLists()); + CPPUNIT_ASSERT(isHashMapClone(a->getSubMeshNameMap(), b->getSubMeshNameMap())); + + assertVertexDataClone(a->sharedVertexData, b->sharedVertexData); + CPPUNIT_ASSERT(a->getCreator() == b->getCreator()); + CPPUNIT_ASSERT(a->getIndexBufferUsage() == b->getIndexBufferUsage()); + CPPUNIT_ASSERT(a->getSharedVertexDataAnimationIncludesNormals() == b->getSharedVertexDataAnimationIncludesNormals()); + CPPUNIT_ASSERT(a->getSharedVertexDataAnimationType() == b->getSharedVertexDataAnimationType()); + CPPUNIT_ASSERT(a->getVertexBufferUsage() == b->getVertexBufferUsage()); + CPPUNIT_ASSERT(a->hasVertexAnimation() == b->hasVertexAnimation()); #ifndef OGRE_TEST_XMLSERIALIZER - CPPUNIT_ASSERT(a->isEdgeListBuilt() == b->isEdgeListBuilt()); // <== OgreXMLSerializer is doing post processing to generate edgelists! + CPPUNIT_ASSERT(a->isEdgeListBuilt() == b->isEdgeListBuilt()); // <== OgreXMLSerializer is doing post processing to generate edgelists! #endif // !OGRE_TEST_XMLSERIALIZER - if ((a->getNumLodLevels() > 1 || b->getNumLodLevels() > 1) && - ((version < MESH_VERSION_1_8 || (!isLodMixed(a) && !isLodMixed(b))) && // mixed lod only supported in v1.10+ - (version < MESH_VERSION_1_4 || (a->getLodStrategy() == DistanceLodStrategy::getSingletonPtr() && - b->getLodStrategy() == DistanceLodStrategy::getSingletonPtr())))) { // Lod Strategy only supported in v1.41+ - CPPUNIT_ASSERT(a->getNumLodLevels() == b->getNumLodLevels()); - CPPUNIT_ASSERT(a->hasManualLodLevel() == b->hasManualLodLevel()); - CPPUNIT_ASSERT(a->getLodStrategy() == b->getLodStrategy()); - - int numLods = a->getNumLodLevels(); - for (int i = 0; i < numLods; i++) { - if (version != MESH_VERSION_1_0 && a->getAutoBuildEdgeLists() == b->getAutoBuildEdgeLists()) { - assertEdgeDataClone(a->getEdgeList(i), b->getEdgeList(i)); - } else if (a->getLodLevel(i).edgeData != NULL && b->getLodLevel(i).edgeData != NULL) { - assertEdgeDataClone(a->getLodLevel(i).edgeData, b->getLodLevel(i).edgeData); - } - assertLodUsageClone(a->getLodLevel(i), b->getLodLevel(i)); - } - } - CPPUNIT_ASSERT(a->getNumSubMeshes() == b->getNumSubMeshes()); - int numLods = std::min(a->getNumLodLevels(), b->getNumLodLevels()); - int numSubmeshes = a->getNumSubMeshes(); - for (int i = 0; i < numSubmeshes; i++) { - SubMesh* aSubmesh = a->getSubMesh(i); - SubMesh* bSubmesh = b->getSubMesh(i); - - CPPUNIT_ASSERT(aSubmesh->getMaterialName() == bSubmesh->getMaterialName()); - CPPUNIT_ASSERT(aSubmesh->isMatInitialised() == bSubmesh->isMatInitialised()); - CPPUNIT_ASSERT(aSubmesh->useSharedVertices == bSubmesh->useSharedVertices); - CPPUNIT_ASSERT(aSubmesh->getVertexAnimationIncludesNormals() == bSubmesh->getVertexAnimationIncludesNormals()); - CPPUNIT_ASSERT(aSubmesh->getVertexAnimationType() == bSubmesh->getVertexAnimationType()); - CPPUNIT_ASSERT(aSubmesh->getTextureAliasCount() == bSubmesh->getTextureAliasCount()); - CPPUNIT_ASSERT(isContainerClone(aSubmesh->blendIndexToBoneIndexMap, bSubmesh->blendIndexToBoneIndexMap)); - // TODO: Compare getBoneAssignments and getTextureAliases - for (int n = 0; n < numLods; n++) { - if (a->_isManualLodLevel(n)) { - continue; - } - RenderOperation aop, bop; - aSubmesh->_getRenderOperation(aop, n); - bSubmesh->_getRenderOperation(bop, n); - assertIndexDataClone(aop.indexData, bop.indexData); - assertVertexDataClone(aop.vertexData, bop.vertexData); - CPPUNIT_ASSERT(aop.operationType == bop.operationType); - CPPUNIT_ASSERT(aop.useIndexes == bop.useIndexes); - } - } + if ((a->getNumLodLevels() > 1 || b->getNumLodLevels() > 1) && + ((version < MESH_VERSION_1_8 || (!isLodMixed(a) && !isLodMixed(b))) && // mixed lod only supported in v1.10+ + (version < MESH_VERSION_1_4 || (a->getLodStrategy() == DistanceLodStrategy::getSingletonPtr() && + b->getLodStrategy() == DistanceLodStrategy::getSingletonPtr())))) { // Lod Strategy only supported in v1.41+ + CPPUNIT_ASSERT(a->getNumLodLevels() == b->getNumLodLevels()); + CPPUNIT_ASSERT(a->hasManualLodLevel() == b->hasManualLodLevel()); + CPPUNIT_ASSERT(a->getLodStrategy() == b->getLodStrategy()); + + int numLods = a->getNumLodLevels(); + for (int i = 0; i < numLods; i++) { + if (version != MESH_VERSION_1_0 && a->getAutoBuildEdgeLists() == b->getAutoBuildEdgeLists()) { + assertEdgeDataClone(a->getEdgeList(i), b->getEdgeList(i)); + } else if (a->getLodLevel(i).edgeData != NULL && b->getLodLevel(i).edgeData != NULL) { + assertEdgeDataClone(a->getLodLevel(i).edgeData, b->getLodLevel(i).edgeData); + } + assertLodUsageClone(a->getLodLevel(i), b->getLodLevel(i)); + } + } + CPPUNIT_ASSERT(a->getNumSubMeshes() == b->getNumSubMeshes()); + int numLods = std::min(a->getNumLodLevels(), b->getNumLodLevels()); + int numSubmeshes = a->getNumSubMeshes(); + for (int i = 0; i < numSubmeshes; i++) { + SubMesh* aSubmesh = a->getSubMesh(i); + SubMesh* bSubmesh = b->getSubMesh(i); + + CPPUNIT_ASSERT(aSubmesh->getMaterialName() == bSubmesh->getMaterialName()); + CPPUNIT_ASSERT(aSubmesh->isMatInitialised() == bSubmesh->isMatInitialised()); + CPPUNIT_ASSERT(aSubmesh->useSharedVertices == bSubmesh->useSharedVertices); + CPPUNIT_ASSERT(aSubmesh->getVertexAnimationIncludesNormals() == bSubmesh->getVertexAnimationIncludesNormals()); + CPPUNIT_ASSERT(aSubmesh->getVertexAnimationType() == bSubmesh->getVertexAnimationType()); + CPPUNIT_ASSERT(aSubmesh->getTextureAliasCount() == bSubmesh->getTextureAliasCount()); + CPPUNIT_ASSERT(isContainerClone(aSubmesh->blendIndexToBoneIndexMap, bSubmesh->blendIndexToBoneIndexMap)); + // TODO: Compare getBoneAssignments and getTextureAliases + for (int n = 0; n < numLods; n++) { + if (a->_isManualLodLevel(n)) { + continue; + } + RenderOperation aop, bop; + aSubmesh->_getRenderOperation(aop, n); + bSubmesh->_getRenderOperation(bop, n); + assertIndexDataClone(aop.indexData, bop.indexData); + assertVertexDataClone(aop.vertexData, bop.vertexData); + CPPUNIT_ASSERT(aop.operationType == bop.operationType); + CPPUNIT_ASSERT(aop.useIndexes == bop.useIndexes); + } + } } bool MeshSerializerTests::isLodMixed(const Mesh* pMesh) { - if (!pMesh->hasManualLodLevel()) { - return false; - } - - unsigned short numLods = pMesh->getNumLodLevels(); - for (unsigned short i = 1; i < numLods; ++i) { - if (!pMesh->_isManualLodLevel(i)) { - return true; - } - } - - return false; + if (!pMesh->hasManualLodLevel()) { + return false; + } + + unsigned short numLods = pMesh->getNumLodLevels(); + for (unsigned short i = 1; i < numLods; ++i) { + if (!pMesh->_isManualLodLevel(i)) { + return true; + } + } + + return false; } void MeshSerializerTests::assertVertexDataClone(VertexData* a, VertexData* b, MeshVersion version /*= MESH_VERSION_LATEST*/) { - CPPUNIT_ASSERT((a == NULL) == (b == NULL)); - if (a) { - // compare bindings - { - const VertexBufferBinding::VertexBufferBindingMap& aBindings = a->vertexBufferBinding->getBindings(); - const VertexBufferBinding::VertexBufferBindingMap& bBindings = b->vertexBufferBinding->getBindings(); - CPPUNIT_ASSERT(aBindings.size() == bBindings.size()); - typedef VertexBufferBinding::VertexBufferBindingMap::const_iterator bindingIterator; - bindingIterator aIt = aBindings.begin(); - bindingIterator aEndIt = aBindings.end(); - bindingIterator bIt = bBindings.begin(); - for (; aIt != aEndIt; aIt++, bIt++) { - CPPUNIT_ASSERT(aIt->first == bIt->first); - CPPUNIT_ASSERT((aIt->second.get() == NULL) == (bIt->second.get() == NULL)); - if (a) { - CPPUNIT_ASSERT(aIt->second->getManager() == bIt->second->getManager()); - CPPUNIT_ASSERT(aIt->second->getNumVertices() == bIt->second->getNumVertices()); - } - } - } - - { - const VertexDeclaration::VertexElementList& aElements = a->vertexDeclaration->getElements(); - const VertexDeclaration::VertexElementList& bElements = a->vertexDeclaration->getElements(); - CPPUNIT_ASSERT(aElements.size() == bElements.size()); - typedef VertexDeclaration::VertexElementList::const_iterator bindingIterator; - bindingIterator aIt = aElements.begin(); - bindingIterator aEndIt = aElements.end(); - bindingIterator bIt; - for (; aIt != aEndIt; aIt++) { - bIt = std::find(bElements.begin(), bElements.end(), *aIt); - CPPUNIT_ASSERT(bIt != bElements.end()); + CPPUNIT_ASSERT((a == NULL) == (b == NULL)); + if (a) { + // compare bindings + { + const VertexBufferBinding::VertexBufferBindingMap& aBindings = a->vertexBufferBinding->getBindings(); + const VertexBufferBinding::VertexBufferBindingMap& bBindings = b->vertexBufferBinding->getBindings(); + CPPUNIT_ASSERT(aBindings.size() == bBindings.size()); + typedef VertexBufferBinding::VertexBufferBindingMap::const_iterator bindingIterator; + bindingIterator aIt = aBindings.begin(); + bindingIterator aEndIt = aBindings.end(); + bindingIterator bIt = bBindings.begin(); + for (; aIt != aEndIt; aIt++, bIt++) { + CPPUNIT_ASSERT(aIt->first == bIt->first); + CPPUNIT_ASSERT((aIt->second.get() == NULL) == (bIt->second.get() == NULL)); + if (a) { + CPPUNIT_ASSERT(aIt->second->getManager() == bIt->second->getManager()); + CPPUNIT_ASSERT(aIt->second->getNumVertices() == bIt->second->getNumVertices()); + } + } + } + + { + const VertexDeclaration::VertexElementList& aElements = a->vertexDeclaration->getElements(); + const VertexDeclaration::VertexElementList& bElements = a->vertexDeclaration->getElements(); + CPPUNIT_ASSERT(aElements.size() == bElements.size()); + typedef VertexDeclaration::VertexElementList::const_iterator bindingIterator; + bindingIterator aIt = aElements.begin(); + bindingIterator aEndIt = aElements.end(); + bindingIterator bIt; + for (; aIt != aEndIt; aIt++) { + bIt = std::find(bElements.begin(), bElements.end(), *aIt); + CPPUNIT_ASSERT(bIt != bElements.end()); #ifndef OGRE_TEST_XMLSERIALIZER - const VertexElement& aElem = *aIt; - const VertexElement& bElem = *bIt; - HardwareVertexBufferSharedPtr abuf = a->vertexBufferBinding->getBuffer(aElem.getSource()); - HardwareVertexBufferSharedPtr bbuf = b->vertexBufferBinding->getBuffer(bElem.getSource()); - unsigned char* avertex = static_cast(abuf->lock(HardwareBuffer::HBL_READ_ONLY)); - unsigned char* bvertex = static_cast(bbuf->lock(HardwareBuffer::HBL_READ_ONLY)); - size_t avSize = abuf->getVertexSize(); - size_t bvSize = bbuf->getVertexSize(); - size_t elemSize = VertexElement::getTypeSize(aElem.getType()); - unsigned char* avEnd = avertex + a->vertexCount * avSize; - bool error = false; - for (; avertex < avEnd; avertex += avSize, bvertex += bvSize) { - float* afloat, * bfloat; - aElem.baseVertexPointerToElement(avertex, &afloat); - bElem.baseVertexPointerToElement(bvertex, &bfloat); - error |= (memcmp(afloat, bfloat, elemSize) != 0); - } - abuf->unlock(); - bbuf->unlock(); - CPPUNIT_ASSERT(!error && "Content of vertex buffer differs!"); + const VertexElement& aElem = *aIt; + const VertexElement& bElem = *bIt; + HardwareVertexBufferSharedPtr abuf = a->vertexBufferBinding->getBuffer(aElem.getSource()); + HardwareVertexBufferSharedPtr bbuf = b->vertexBufferBinding->getBuffer(bElem.getSource()); + unsigned char* avertex = static_cast(abuf->lock(HardwareBuffer::HBL_READ_ONLY)); + unsigned char* bvertex = static_cast(bbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + size_t avSize = abuf->getVertexSize(); + size_t bvSize = bbuf->getVertexSize(); + size_t elemSize = VertexElement::getTypeSize(aElem.getType()); + unsigned char* avEnd = avertex + a->vertexCount * avSize; + bool error = false; + for (; avertex < avEnd; avertex += avSize, bvertex += bvSize) { + float* afloat, * bfloat; + aElem.baseVertexPointerToElement(avertex, &afloat); + bElem.baseVertexPointerToElement(bvertex, &bfloat); + error |= (memcmp(afloat, bfloat, elemSize) != 0); + } + abuf->unlock(); + bbuf->unlock(); + CPPUNIT_ASSERT(!error && "Content of vertex buffer differs!"); #endif /* ifndef OGRE_TEST_XMLSERIALIZER */ - } - - } - - CPPUNIT_ASSERT(a->vertexStart == b->vertexStart); - CPPUNIT_ASSERT(a->vertexCount == b->vertexCount); - CPPUNIT_ASSERT(a->hwAnimDataItemsUsed == b->hwAnimDataItemsUsed); - - // Compare hwAnimationData - { - const VertexData::HardwareAnimationDataList& aAnimData = a->hwAnimationDataList; - const VertexData::HardwareAnimationDataList& bAnimData = b->hwAnimationDataList; - CPPUNIT_ASSERT(aAnimData.size() == bAnimData.size()); - typedef VertexData::HardwareAnimationDataList::const_iterator bindingIterator; - bindingIterator aIt = aAnimData.begin(); - bindingIterator aEndIt = aAnimData.end(); - bindingIterator bIt = bAnimData.begin(); - for (; aIt != aEndIt; aIt++, bIt++) { - CPPUNIT_ASSERT(aIt->parametric == bIt->parametric); - CPPUNIT_ASSERT(aIt->targetBufferIndex == bIt->targetBufferIndex); - } - } - } + } + + } + + CPPUNIT_ASSERT(a->vertexStart == b->vertexStart); + CPPUNIT_ASSERT(a->vertexCount == b->vertexCount); + CPPUNIT_ASSERT(a->hwAnimDataItemsUsed == b->hwAnimDataItemsUsed); + + // Compare hwAnimationData + { + const VertexData::HardwareAnimationDataList& aAnimData = a->hwAnimationDataList; + const VertexData::HardwareAnimationDataList& bAnimData = b->hwAnimationDataList; + CPPUNIT_ASSERT(aAnimData.size() == bAnimData.size()); + typedef VertexData::HardwareAnimationDataList::const_iterator bindingIterator; + bindingIterator aIt = aAnimData.begin(); + bindingIterator aEndIt = aAnimData.end(); + bindingIterator bIt = bAnimData.begin(); + for (; aIt != aEndIt; aIt++, bIt++) { + CPPUNIT_ASSERT(aIt->parametric == bIt->parametric); + CPPUNIT_ASSERT(aIt->targetBufferIndex == bIt->targetBufferIndex); + } + } + } } template bool MeshSerializerTests::isContainerClone(T& a, T& b) { - return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); + return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); } template bool MeshSerializerTests::isHashMapClone(const HashMap& a, const HashMap& b) { - // if you recreate a HashMap with same elements, then iteration order may differ! - // So isContainerClone is not always working on HashMap. - if (a.size() != b.size()) { - return false; - } - typename HashMap::const_iterator it, itFind, itEnd; - it = a.begin(); - itEnd = a.end(); - for (; it != itEnd; it++) { - itFind = b.find(it->first); - if (itFind == b.end() || itFind->second != it->second) { - return false; - } - } - return true; + // if you recreate a HashMap with same elements, then iteration order may differ! + // So isContainerClone is not always working on HashMap. + if (a.size() != b.size()) { + return false; + } + typename HashMap::const_iterator it, itFind, itEnd; + it = a.begin(); + itEnd = a.end(); + for (; it != itEnd; it++) { + itFind = b.find(it->first); + if (itFind == b.end() || itFind->second != it->second) { + return false; + } + } + return true; } void MeshSerializerTests::assertIndexDataClone(IndexData* a, IndexData* b, MeshVersion version /*= MESH_VERSION_LATEST*/) { - CPPUNIT_ASSERT((a == NULL) == (b == NULL)); - if (a) { - CPPUNIT_ASSERT(a->indexCount == b->indexCount); - // CPPUNIT_ASSERT(a->indexStart == b->indexStart); - CPPUNIT_ASSERT((a->indexBuffer.get() == NULL) == (b->indexBuffer.get() == NULL)); - if (!a->indexBuffer.isNull()) { - CPPUNIT_ASSERT(a->indexBuffer->getManager() == b->indexBuffer->getManager()); - // CPPUNIT_ASSERT(a->indexBuffer->getNumIndexes() == b->indexBuffer->getNumIndexes()); - CPPUNIT_ASSERT(a->indexBuffer->getIndexSize() == b->indexBuffer->getIndexSize()); - CPPUNIT_ASSERT(a->indexBuffer->getType() == b->indexBuffer->getType()); - - char* abuf = (char*) a->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY); - char* bbuf = (char*) b->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY); - size_t size = a->indexBuffer->getIndexSize(); - char* astart = abuf + a->indexStart * size; - char* bstart = bbuf + b->indexStart * size; - CPPUNIT_ASSERT(memcmp(astart, bstart, a->indexCount * size) == 0); - a->indexBuffer->unlock(); - b->indexBuffer->unlock(); - } - } + CPPUNIT_ASSERT((a == NULL) == (b == NULL)); + if (a) { + CPPUNIT_ASSERT(a->indexCount == b->indexCount); + // CPPUNIT_ASSERT(a->indexStart == b->indexStart); + CPPUNIT_ASSERT((a->indexBuffer.get() == NULL) == (b->indexBuffer.get() == NULL)); + if (!a->indexBuffer.isNull()) { + CPPUNIT_ASSERT(a->indexBuffer->getManager() == b->indexBuffer->getManager()); + // CPPUNIT_ASSERT(a->indexBuffer->getNumIndexes() == b->indexBuffer->getNumIndexes()); + CPPUNIT_ASSERT(a->indexBuffer->getIndexSize() == b->indexBuffer->getIndexSize()); + CPPUNIT_ASSERT(a->indexBuffer->getType() == b->indexBuffer->getType()); + + char* abuf = (char*) a->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY); + char* bbuf = (char*) b->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY); + size_t size = a->indexBuffer->getIndexSize(); + char* astart = abuf + a->indexStart * size; + char* bstart = bbuf + b->indexStart * size; + CPPUNIT_ASSERT(memcmp(astart, bstart, a->indexCount * size) == 0); + a->indexBuffer->unlock(); + b->indexBuffer->unlock(); + } + } } void MeshSerializerTests::assertEdgeDataClone(EdgeData* a, EdgeData* b, MeshVersion version /*= MESH_VERSION_LATEST*/) { - CPPUNIT_ASSERT((a == NULL) == (b == NULL)); - if (a) { - CPPUNIT_ASSERT(a->isClosed == b->isClosed); - CPPUNIT_ASSERT(isContainerClone(a->triangleFaceNormals, b->triangleFaceNormals)); - CPPUNIT_ASSERT(isContainerClone(a->triangleLightFacings, b->triangleLightFacings)); - // TODO: Compare triangles and edgeGroups in more detail. - CPPUNIT_ASSERT(a->triangles.size() == b->triangles.size()); - CPPUNIT_ASSERT(a->edgeGroups.size() == b->edgeGroups.size()); - } + CPPUNIT_ASSERT((a == NULL) == (b == NULL)); + if (a) { + CPPUNIT_ASSERT(a->isClosed == b->isClosed); + CPPUNIT_ASSERT(isContainerClone(a->triangleFaceNormals, b->triangleFaceNormals)); + CPPUNIT_ASSERT(isContainerClone(a->triangleLightFacings, b->triangleLightFacings)); + // TODO: Compare triangles and edgeGroups in more detail. + CPPUNIT_ASSERT(a->triangles.size() == b->triangles.size()); + CPPUNIT_ASSERT(a->edgeGroups.size() == b->edgeGroups.size()); + } } void MeshSerializerTests::assertLodUsageClone(const MeshLodUsage& a, const MeshLodUsage& b, MeshVersion version /*= MESH_VERSION_LATEST*/) { - CPPUNIT_ASSERT(a.manualName == b.manualName); - CPPUNIT_ASSERT(isEqual(a.userValue, b.userValue)); - CPPUNIT_ASSERT(isEqual(a.value, b.value)); + CPPUNIT_ASSERT(a.manualName == b.manualName); + CPPUNIT_ASSERT(isEqual(a.userValue, b.userValue)); + CPPUNIT_ASSERT(isEqual(a.value, b.value)); } void MeshSerializerTests::getResourceFullPath(const ResourcePtr& resource, String& outPath) { - ResourceGroupManager& resourceGroupMgr = ResourceGroupManager::getSingleton(); - String group = resource->getGroup(); - String name = resource->getName(); - FileInfo* info = NULL; - FileInfoListPtr locPtr = resourceGroupMgr.listResourceFileInfo(group); - FileInfoList::iterator it, itEnd; - it = locPtr->begin(); - itEnd = locPtr->end(); - for (; it != itEnd; it++) { - if (stricmp(name.c_str(), it->filename.c_str()) == 0) { - info = &*it; - break; - } - } - if(!info) { - outPath = name; - return; - } - outPath = info->archive->getName(); - if (outPath[outPath .size()-1] != '/' && outPath[outPath .size()-1] != '\\') { - outPath += '/'; - } - outPath += info->path; - if (outPath[outPath .size()-1] != '/' && outPath[outPath .size()-1] != '\\') { - outPath += '/'; - } - outPath += info->filename; - - assert(info->archive->getType() == "FileSystem"); + ResourceGroupManager& resourceGroupMgr = ResourceGroupManager::getSingleton(); + String group = resource->getGroup(); + String name = resource->getName(); + FileInfo* info = NULL; + FileInfoListPtr locPtr = resourceGroupMgr.listResourceFileInfo(group); + FileInfoList::iterator it, itEnd; + it = locPtr->begin(); + itEnd = locPtr->end(); + for (; it != itEnd; it++) { + if (stricmp(name.c_str(), it->filename.c_str()) == 0) { + info = &*it; + break; + } + } + if(!info) { + outPath = name; + return; + } + outPath = info->archive->getName(); + if (outPath[outPath .size()-1] != '/' && outPath[outPath .size()-1] != '\\') { + outPath += '/'; + } + outPath += info->path; + if (outPath[outPath .size()-1] != '/' && outPath[outPath .size()-1] != '\\') { + outPath += '/'; + } + outPath += info->filename; + + assert(info->archive->getType() == "FileSystem"); } bool MeshSerializerTests::copyFile(const String& srcPath, const String& dstPath) { - std::ifstream src(srcPath.c_str(), std::ios::binary); - if (!src.is_open()) { - return false; - } - std::ofstream dst(dstPath.c_str(), std::ios::binary); - if (!dst.is_open()) { - return false; - } - - dst << src.rdbuf(); - return true; + std::ifstream src(srcPath.c_str(), std::ios::binary); + if (!src.is_open()) { + return false; + } + std::ofstream dst(dstPath.c_str(), std::ios::binary); + if (!dst.is_open()) { + return false; + } + + dst << src.rdbuf(); + return true; } bool MeshSerializerTests::isEqual(Real a, Real b) { - Real absoluteError = std::abs(a * errorFactor); - return ((a - absoluteError) <= b) && ((a + absoluteError) >= b); + Real absoluteError = std::abs(a * errorFactor); + return ((a - absoluteError) <= b) && ((a + absoluteError) >= b); } bool MeshSerializerTests::isEqual(const Vector3& a, const Vector3& b) { - return isEqual(a.x, b.x) && isEqual(a.y, b.y) && isEqual(a.z, b.z); + return isEqual(a.x, b.x) && isEqual(a.y, b.y) && isEqual(a.z, b.z); } diff --git a/Tests/OgreMain/src/MeshWithoutIndexDataTests.cpp b/Tests/OgreMain/src/MeshWithoutIndexDataTests.cpp index 75a8c3a745d..c8723de79b3 100644 --- a/Tests/OgreMain/src/MeshWithoutIndexDataTests.cpp +++ b/Tests/OgreMain/src/MeshWithoutIndexDataTests.cpp @@ -47,26 +47,26 @@ void MeshWithoutIndexDataTests::setUp() if(LogManager::getSingletonPtr() == 0) mLogManager = OGRE_NEW LogManager(); - LogManager::getSingleton().createLog("MeshWithoutIndexDataTests.log", true); + LogManager::getSingleton().createLog("MeshWithoutIndexDataTests.log", true); LogManager::getSingleton().setLogDetail(LL_LOW); - OGRE_NEW ResourceGroupManager(); - OGRE_NEW LodStrategyManager(); + OGRE_NEW ResourceGroupManager(); + OGRE_NEW LodStrategyManager(); mBufMgr = OGRE_NEW DefaultHardwareBufferManager(); mMeshMgr = OGRE_NEW MeshManager(); archiveMgr = OGRE_NEW ArchiveManager(); archiveMgr->addArchiveFactory(OGRE_NEW FileSystemArchiveFactory()); - MaterialManager* matMgr = OGRE_NEW MaterialManager(); - matMgr->initialise(); + MaterialManager* matMgr = OGRE_NEW MaterialManager(); + matMgr->initialise(); } void MeshWithoutIndexDataTests::tearDown() { OGRE_DELETE mMeshMgr; OGRE_DELETE mBufMgr; OGRE_DELETE archiveMgr; - OGRE_DELETE MaterialManager::getSingletonPtr(); - OGRE_DELETE LodStrategyManager::getSingletonPtr(); - OGRE_DELETE ResourceGroupManager::getSingletonPtr(); + OGRE_DELETE MaterialManager::getSingletonPtr(); + OGRE_DELETE LodStrategyManager::getSingletonPtr(); + OGRE_DELETE ResourceGroupManager::getSingletonPtr(); OGRE_DELETE mLogManager; } @@ -454,7 +454,7 @@ void MeshWithoutIndexDataTests::testBuildTangentVectors() } catch (const InvalidParametersException&) { - // ok + // ok } mMeshMgr->remove( fileName ); @@ -467,8 +467,8 @@ void MeshWithoutIndexDataTests::testGenerateLodLevels() createMeshWithMaterial(fileName); MeshPtr mesh = mMeshMgr->getByName(fileName).staticCast(); - LodConfig lodConfig(mesh); - lodConfig.createGeneratedLodLevel(600, 2, LodLevel::VRM_CONSTANT); + LodConfig lodConfig(mesh); + lodConfig.createGeneratedLodLevel(600, 2, LodLevel::VRM_CONSTANT); MeshLodGenerator().generateLodLevels(lodConfig); // It may be less then 2, when two levels have the same vertex count it will be optimized out and lodLevel.outSkipped=true CPPUNIT_ASSERT(mesh->getNumLodLevels() == 2); @@ -479,7 +479,7 @@ void MeshWithoutIndexDataTests::testGenerateLodLevels() { if (subMesh->indexData->indexCount > 0) { - // This may not be true for all meshes, but in this test we don't have reduced to 0. + // This may not be true for all meshes, but in this test we don't have reduced to 0. CPPUNIT_ASSERT(subMesh->mLodFaceList[j]->indexCount > 0); } else diff --git a/Tests/OgreMain/src/PixelFormatTests.cpp b/Tests/OgreMain/src/PixelFormatTests.cpp index fdd39b4f610..fdee193f576 100644 --- a/Tests/OgreMain/src/PixelFormatTests.cpp +++ b/Tests/OgreMain/src/PixelFormatTests.cpp @@ -105,25 +105,25 @@ void naiveBulkPixelConversion(const PixelBox &src, const PixelBox &dst) unsigned long dstRowSkipBytes = dst.getRowSkip()*dstPixelSize; unsigned long dstSliceSkipBytes = dst.getSliceSkip()*dstPixelSize; - // The brute force fallback - float r,g,b,a; - for(size_t z=src.front; z" << PixelUtil::getFormatName(dstFormat) << "] " << s.str(); + StringStream msg; + msg << "Conversion mismatch [" << PixelUtil::getFormatName(srcFormat) << + "->" << PixelUtil::getFormatName(dstFormat) << "] " << s.str(); CPPUNIT_ASSERT_MESSAGE(msg.str().c_str(), - memcmp(dst1.data, dst2.data, eob) == 0); + memcmp(dst1.data, dst2.data, eob) == 0); } void PixelFormatTests::testBulkConversion() @@ -183,18 +183,18 @@ void PixelFormatTests::testBulkConversion() // Self match testCase(PF_A8R8G8B8, PF_A8R8G8B8); // Optimized - testCase(PF_A8R8G8B8,PF_A8B8G8R8); - testCase(PF_A8R8G8B8,PF_B8G8R8A8); - testCase(PF_A8R8G8B8,PF_R8G8B8A8); - testCase(PF_A8B8G8R8,PF_A8R8G8B8); - testCase(PF_A8B8G8R8,PF_B8G8R8A8); - testCase(PF_A8B8G8R8,PF_R8G8B8A8); - testCase(PF_B8G8R8A8,PF_A8R8G8B8); - testCase(PF_B8G8R8A8,PF_A8B8G8R8); - testCase(PF_B8G8R8A8,PF_R8G8B8A8); - testCase(PF_R8G8B8A8,PF_A8R8G8B8); - testCase(PF_R8G8B8A8,PF_A8B8G8R8); - testCase(PF_R8G8B8A8,PF_B8G8R8A8); + testCase(PF_A8R8G8B8,PF_A8B8G8R8); + testCase(PF_A8R8G8B8,PF_B8G8R8A8); + testCase(PF_A8R8G8B8,PF_R8G8B8A8); + testCase(PF_A8B8G8R8,PF_A8R8G8B8); + testCase(PF_A8B8G8R8,PF_B8G8R8A8); + testCase(PF_A8B8G8R8,PF_R8G8B8A8); + testCase(PF_B8G8R8A8,PF_A8R8G8B8); + testCase(PF_B8G8R8A8,PF_A8B8G8R8); + testCase(PF_B8G8R8A8,PF_R8G8B8A8); + testCase(PF_R8G8B8A8,PF_A8R8G8B8); + testCase(PF_R8G8B8A8,PF_A8B8G8R8); + testCase(PF_R8G8B8A8,PF_B8G8R8A8); testCase(PF_A8B8G8R8, PF_L8); testCase(PF_L8, PF_A8B8G8R8); @@ -214,16 +214,16 @@ void PixelFormatTests::testBulkConversion() testCase(PF_B8G8R8, PF_A8B8G8R8); testCase(PF_R8G8B8, PF_B8G8R8A8); testCase(PF_B8G8R8, PF_B8G8R8A8); - testCase(PF_A8R8G8B8, PF_R8G8B8); - testCase(PF_A8R8G8B8, PF_B8G8R8); - testCase(PF_X8R8G8B8, PF_A8R8G8B8); - testCase(PF_X8R8G8B8, PF_A8B8G8R8); - testCase(PF_X8R8G8B8, PF_B8G8R8A8); - testCase(PF_X8R8G8B8, PF_R8G8B8A8); - testCase(PF_X8B8G8R8, PF_A8R8G8B8); - testCase(PF_X8B8G8R8, PF_A8B8G8R8); - testCase(PF_X8B8G8R8, PF_B8G8R8A8); - testCase(PF_X8B8G8R8, PF_R8G8B8A8); + testCase(PF_A8R8G8B8, PF_R8G8B8); + testCase(PF_A8R8G8B8, PF_B8G8R8); + testCase(PF_X8R8G8B8, PF_A8R8G8B8); + testCase(PF_X8R8G8B8, PF_A8B8G8R8); + testCase(PF_X8R8G8B8, PF_B8G8R8A8); + testCase(PF_X8R8G8B8, PF_R8G8B8A8); + testCase(PF_X8B8G8R8, PF_A8R8G8B8); + testCase(PF_X8B8G8R8, PF_A8B8G8R8); + testCase(PF_X8B8G8R8, PF_B8G8R8A8); + testCase(PF_X8B8G8R8, PF_R8G8B8A8); //CPPUNIT_ASSERT_MESSAGE("Conversion mismatch", false); } diff --git a/Tests/OgreMain/src/RadixSort.cpp b/Tests/OgreMain/src/RadixSort.cpp index 4e0d383f5df..c6e9e0605f6 100644 --- a/Tests/OgreMain/src/RadixSort.cpp +++ b/Tests/OgreMain/src/RadixSort.cpp @@ -36,7 +36,7 @@ CPPUNIT_TEST_SUITE_REGISTRATION( RadixSortTests ); void RadixSortTests::setUp() { - srand(0); + srand(0); } void RadixSortTests::tearDown() { @@ -45,160 +45,160 @@ void RadixSortTests::tearDown() class FloatSortFunctor { public: - float operator()(const float& p) const - { - return p; - } + float operator()(const float& p) const + { + return p; + } }; class IntSortFunctor { public: - int operator()(const int& p) const - { - return p; - } + int operator()(const int& p) const + { + return p; + } }; class UnsignedIntSortFunctor { public: - unsigned int operator()(const unsigned int& p) const - { - return p; - } + unsigned int operator()(const unsigned int& p) const + { + return p; + } }; void RadixSortTests::testFloatVector() { - std::vector container; - FloatSortFunctor func; - RadixSort, float, float> sorter; + std::vector container; + FloatSortFunctor func; + RadixSort, float, float> sorter; - for (int i = 0; i < 1000; ++i) - { - container.push_back((float)Math::RangeRandom(-1e10, 1e10)); - } + for (int i = 0; i < 1000; ++i) + { + container.push_back((float)Math::RangeRandom(-1e10, 1e10)); + } - sorter.sort(container, func); + sorter.sort(container, func); - std::vector::iterator v = container.begin(); - float lastValue = *v++; - for (;v != container.end(); ++v) - { - CPPUNIT_ASSERT(*v >= lastValue); - lastValue = *v; - } + std::vector::iterator v = container.begin(); + float lastValue = *v++; + for (;v != container.end(); ++v) + { + CPPUNIT_ASSERT(*v >= lastValue); + lastValue = *v; + } } void RadixSortTests::testFloatList() { - std::list container; - FloatSortFunctor func; - RadixSort, float, float> sorter; - - for (int i = 0; i < 1000; ++i) - { - container.push_back((float)Math::RangeRandom(-1e10, 1e10)); - } - - sorter.sort(container, func); - - std::list::iterator v = container.begin(); - float lastValue = *v++; - for (;v != container.end(); ++v) - { - CPPUNIT_ASSERT(*v >= lastValue); - lastValue = *v; - } + std::list container; + FloatSortFunctor func; + RadixSort, float, float> sorter; + + for (int i = 0; i < 1000; ++i) + { + container.push_back((float)Math::RangeRandom(-1e10, 1e10)); + } + + sorter.sort(container, func); + + std::list::iterator v = container.begin(); + float lastValue = *v++; + for (;v != container.end(); ++v) + { + CPPUNIT_ASSERT(*v >= lastValue); + lastValue = *v; + } } void RadixSortTests::testUnsignedIntList() { - std::list container; - UnsignedIntSortFunctor func; - RadixSort, unsigned int, unsigned int> sorter; - - for (int i = 0; i < 1000; ++i) - { - container.push_back((unsigned int)Math::RangeRandom(0, 1e10)); - } - - sorter.sort(container, func); - - std::list::iterator v = container.begin(); - unsigned int lastValue = *v++; - for (;v != container.end(); ++v) - { - CPPUNIT_ASSERT(*v >= lastValue); - lastValue = *v; - } + std::list container; + UnsignedIntSortFunctor func; + RadixSort, unsigned int, unsigned int> sorter; + + for (int i = 0; i < 1000; ++i) + { + container.push_back((unsigned int)Math::RangeRandom(0, 1e10)); + } + + sorter.sort(container, func); + + std::list::iterator v = container.begin(); + unsigned int lastValue = *v++; + for (;v != container.end(); ++v) + { + CPPUNIT_ASSERT(*v >= lastValue); + lastValue = *v; + } } void RadixSortTests::testIntList() { - std::list container; - IntSortFunctor func; - RadixSort, int, int> sorter; - - for (int i = 0; i < 1000; ++i) - { - container.push_back((int)Math::RangeRandom(-1e10, 1e10)); - } - - sorter.sort(container, func); - - std::list::iterator v = container.begin(); - int lastValue = *v++; - for (;v != container.end(); ++v) - { - CPPUNIT_ASSERT(*v >= lastValue); - lastValue = *v; - } + std::list container; + IntSortFunctor func; + RadixSort, int, int> sorter; + + for (int i = 0; i < 1000; ++i) + { + container.push_back((int)Math::RangeRandom(-1e10, 1e10)); + } + + sorter.sort(container, func); + + std::list::iterator v = container.begin(); + int lastValue = *v++; + for (;v != container.end(); ++v) + { + CPPUNIT_ASSERT(*v >= lastValue); + lastValue = *v; + } } void RadixSortTests::testUnsignedIntVector() { - std::vector container; - UnsignedIntSortFunctor func; - RadixSort, unsigned int, unsigned int> sorter; - - for (int i = 0; i < 1000; ++i) - { - container.push_back((unsigned int)Math::RangeRandom(0, 1e10)); - } - - sorter.sort(container, func); - - std::vector::iterator v = container.begin(); - unsigned int lastValue = *v++; - for (;v != container.end(); ++v) - { - CPPUNIT_ASSERT(*v >= lastValue); - lastValue = *v; - } + std::vector container; + UnsignedIntSortFunctor func; + RadixSort, unsigned int, unsigned int> sorter; + + for (int i = 0; i < 1000; ++i) + { + container.push_back((unsigned int)Math::RangeRandom(0, 1e10)); + } + + sorter.sort(container, func); + + std::vector::iterator v = container.begin(); + unsigned int lastValue = *v++; + for (;v != container.end(); ++v) + { + CPPUNIT_ASSERT(*v >= lastValue); + lastValue = *v; + } } void RadixSortTests::testIntVector() { - std::vector container; - IntSortFunctor func; - RadixSort, int, int> sorter; - - for (int i = 0; i < 1000; ++i) - { - container.push_back((int)Math::RangeRandom(-1e10, 1e10)); - } - - sorter.sort(container, func); - - std::vector::iterator v = container.begin(); - int lastValue = *v++; - for (;v != container.end(); ++v) - { - CPPUNIT_ASSERT(*v >= lastValue); - lastValue = *v; - } + std::vector container; + IntSortFunctor func; + RadixSort, int, int> sorter; + + for (int i = 0; i < 1000; ++i) + { + container.push_back((int)Math::RangeRandom(-1e10, 1e10)); + } + + sorter.sort(container, func); + + std::vector::iterator v = container.begin(); + int lastValue = *v++; + for (;v != container.end(); ++v) + { + CPPUNIT_ASSERT(*v >= lastValue); + lastValue = *v; + } } diff --git a/Tests/OgreMain/src/RenderSystemCapabilitiesTests.cpp b/Tests/OgreMain/src/RenderSystemCapabilitiesTests.cpp index c950866d1a2..41abf87a992 100644 --- a/Tests/OgreMain/src/RenderSystemCapabilitiesTests.cpp +++ b/Tests/OgreMain/src/RenderSystemCapabilitiesTests.cpp @@ -240,7 +240,7 @@ void RenderSystemCapabilitiesTests::testSerializeShaderCapability() void RenderSystemCapabilitiesTests::testWriteSimpleCapabilities() { using namespace Ogre; - using namespace std; + using namespace std; String name = "simple caps"; String filename = "simpleCapsTest.rendercaps"; @@ -268,7 +268,7 @@ void RenderSystemCapabilitiesTests::testWriteSimpleCapabilities() capsfile.getline(buff, 255); CPPUNIT_ASSERT_EQUAL(String("{"), String(buff)); // scan every line and find the set capabilities it them - std::vector lines; + std::vector lines; while(capsfile.good()) { capsfile.getline(buff, 255); @@ -572,13 +572,13 @@ void RenderSystemCapabilitiesTests::testWriteAndReadComplexCapabilities() caps.setNonPOW2TexturesLimited(true); caps.setVertexTextureUnitsShared(true); - DriverVersion driverversion; - driverversion.major = 11; - driverversion.minor = 13; - driverversion.release = 17; - driverversion.build = 0; + DriverVersion driverversion; + driverversion.major = 11; + driverversion.minor = 13; + driverversion.release = 17; + driverversion.build = 0; - caps.setDriverVersion(driverversion); + caps.setDriverVersion(driverversion); caps.setDeviceName("Dummy Device"); caps.setRenderSystemName("Dummy RenderSystem"); @@ -662,12 +662,12 @@ void RenderSystemCapabilitiesTests::testWriteAndReadComplexCapabilities() CPPUNIT_ASSERT_EQUAL(caps.getMaxPointSize(), caps2.getMaxPointSize()); CPPUNIT_ASSERT_EQUAL(caps.getNonPOW2TexturesLimited(), caps2.getNonPOW2TexturesLimited()); CPPUNIT_ASSERT_EQUAL(caps.getVertexTextureUnitsShared(), caps2.getVertexTextureUnitsShared()); - - // test versions - CPPUNIT_ASSERT_EQUAL(caps.getDriverVersion().major, caps2.getDriverVersion().major); - CPPUNIT_ASSERT_EQUAL(caps.getDriverVersion().minor, caps2.getDriverVersion().minor); - CPPUNIT_ASSERT_EQUAL(caps.getDriverVersion().release, caps2.getDriverVersion().release); - CPPUNIT_ASSERT_EQUAL(0, caps2.getDriverVersion().build); + + // test versions + CPPUNIT_ASSERT_EQUAL(caps.getDriverVersion().major, caps2.getDriverVersion().major); + CPPUNIT_ASSERT_EQUAL(caps.getDriverVersion().minor, caps2.getDriverVersion().minor); + CPPUNIT_ASSERT_EQUAL(caps.getDriverVersion().release, caps2.getDriverVersion().release); + CPPUNIT_ASSERT_EQUAL(0, caps2.getDriverVersion().build); dataStreamPtr.setNull(); } diff --git a/Tests/OgreMain/src/StreamSerialiserTests.cpp b/Tests/OgreMain/src/StreamSerialiserTests.cpp index 85e9ceee6e4..c7af0451e88 100644 --- a/Tests/OgreMain/src/StreamSerialiserTests.cpp +++ b/Tests/OgreMain/src/StreamSerialiserTests.cpp @@ -45,60 +45,60 @@ void StreamSerialiserTests::tearDown() void StreamSerialiserTests::testWriteBasic() { - FileSystemArchive arch("./", "FileSystem", false); - arch.load(); + FileSystemArchive arch("./", "FileSystem", false); + arch.load(); - String fileName = "testSerialiser.dat"; - Vector3 aTestVector(0.3, 15.2, -12.0); - String aTestString = "Some text here"; - int aTestValue = 99; - uint32 chunkID = StreamSerialiser::makeIdentifier("TEST"); - // write the data - { + String fileName = "testSerialiser.dat"; + Vector3 aTestVector(0.3, 15.2, -12.0); + String aTestString = "Some text here"; + int aTestValue = 99; + uint32 chunkID = StreamSerialiser::makeIdentifier("TEST"); + // write the data + { - DataStreamPtr stream = arch.create(fileName); + DataStreamPtr stream = arch.create(fileName); - StreamSerialiser serialiser(stream); + StreamSerialiser serialiser(stream); - serialiser.writeChunkBegin(chunkID); + serialiser.writeChunkBegin(chunkID); - serialiser.write(&aTestVector); - serialiser.write(&aTestString); - serialiser.write(&aTestValue); - serialiser.writeChunkEnd(chunkID); - } + serialiser.write(&aTestVector); + serialiser.write(&aTestString); + serialiser.write(&aTestValue); + serialiser.writeChunkEnd(chunkID); + } - // read it back - { + // read it back + { - DataStreamPtr stream = arch.open(fileName); + DataStreamPtr stream = arch.open(fileName); - StreamSerialiser serialiser(stream); + StreamSerialiser serialiser(stream); - const StreamSerialiser::Chunk* c = serialiser.readChunkBegin(); + const StreamSerialiser::Chunk* c = serialiser.readChunkBegin(); - CPPUNIT_ASSERT_EQUAL(chunkID, c->id); - CPPUNIT_ASSERT_EQUAL(sizeof(Vector3) + sizeof(int) + aTestString.size() + 4, (size_t)c->length); + CPPUNIT_ASSERT_EQUAL(chunkID, c->id); + CPPUNIT_ASSERT_EQUAL(sizeof(Vector3) + sizeof(int) + aTestString.size() + 4, (size_t)c->length); - Vector3 inVector; - String inString; - int inValue; + Vector3 inVector; + String inString; + int inValue; - serialiser.read(&inVector); - serialiser.read(&inString); - serialiser.read(&inValue); - serialiser.readChunkEnd(chunkID); + serialiser.read(&inVector); + serialiser.read(&inString); + serialiser.read(&inValue); + serialiser.readChunkEnd(chunkID); - CPPUNIT_ASSERT_EQUAL(aTestVector, inVector); - CPPUNIT_ASSERT_EQUAL(aTestString, inString); - CPPUNIT_ASSERT_EQUAL(aTestValue, inValue); + CPPUNIT_ASSERT_EQUAL(aTestVector, inVector); + CPPUNIT_ASSERT_EQUAL(aTestString, inString); + CPPUNIT_ASSERT_EQUAL(aTestValue, inValue); - } + } - arch.remove(fileName); + arch.remove(fileName); - CPPUNIT_ASSERT(!arch.exists(fileName)); + CPPUNIT_ASSERT(!arch.exists(fileName)); } diff --git a/Tests/OgreMain/src/StringTests.cpp b/Tests/OgreMain/src/StringTests.cpp index 7198dc5fba9..058dcdaeea4 100755 --- a/Tests/OgreMain/src/StringTests.cpp +++ b/Tests/OgreMain/src/StringTests.cpp @@ -39,11 +39,11 @@ CPPUNIT_TEST_SUITE_REGISTRATION( StringTests ); void StringTests::setUp() { - testFileNoPath = "testfile.txt"; - testFileRelativePathUnix = "this/is/relative/testfile.txt"; - testFileRelativePathWindows = "this\\is\\relative\\testfile.txt"; - testFileAbsolutePathUnix = "/this/is/absolute/testfile.txt"; - testFileAbsolutePathWindows = "c:\\this\\is\\absolute\\testfile.txt"; + testFileNoPath = "testfile.txt"; + testFileRelativePathUnix = "this/is/relative/testfile.txt"; + testFileRelativePathWindows = "this\\is\\relative\\testfile.txt"; + testFileAbsolutePathUnix = "/this/is/absolute/testfile.txt"; + testFileAbsolutePathWindows = "c:\\this\\is\\absolute\\testfile.txt"; } void StringTests::tearDown() { @@ -51,174 +51,174 @@ void StringTests::tearDown() void StringTests::testSplitFileNameNoPath() { - String basename, path; - StringUtil::splitFilename(testFileNoPath, basename, path); + String basename, path; + StringUtil::splitFilename(testFileNoPath, basename, path); CPPUNIT_ASSERT_EQUAL(testFileNoPath, basename); CPPUNIT_ASSERT(path.empty()); } void StringTests::testSplitFileNameRelativePath() { - String basename, path; - // Unix - StringUtil::splitFilename(testFileRelativePathUnix, basename, path); + String basename, path; + // Unix + StringUtil::splitFilename(testFileRelativePathUnix, basename, path); CPPUNIT_ASSERT_EQUAL(String("testfile.txt"), basename); CPPUNIT_ASSERT_EQUAL(String("this/is/relative/"), path); - // Windows - StringUtil::splitFilename(testFileRelativePathWindows, basename, path); + // Windows + StringUtil::splitFilename(testFileRelativePathWindows, basename, path); CPPUNIT_ASSERT_EQUAL(String("testfile.txt"), basename); CPPUNIT_ASSERT_EQUAL(String("this/is/relative/"), path); } void StringTests::testSplitFileNameAbsolutePath() { - String basename, path; - // Unix - StringUtil::splitFilename(testFileAbsolutePathUnix, basename, path); + String basename, path; + // Unix + StringUtil::splitFilename(testFileAbsolutePathUnix, basename, path); CPPUNIT_ASSERT_EQUAL(String("testfile.txt"), basename); CPPUNIT_ASSERT_EQUAL(String("/this/is/absolute/"), path); - // Windows - StringUtil::splitFilename(testFileAbsolutePathWindows, basename, path); + // Windows + StringUtil::splitFilename(testFileAbsolutePathWindows, basename, path); CPPUNIT_ASSERT_EQUAL(String("testfile.txt"), basename); - CPPUNIT_ASSERT_EQUAL(String("c:/this/is/absolute/"), path); + CPPUNIT_ASSERT_EQUAL(String("c:/this/is/absolute/"), path); } void StringTests::testMatchCaseSensitive() { - // Test positive - CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, testFileNoPath, true)); - // Test negative - String upperCase = testFileNoPath; + // Test positive + CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, testFileNoPath, true)); + // Test negative + String upperCase = testFileNoPath; StringUtil::toUpperCase(upperCase); - CPPUNIT_ASSERT(!StringUtil::match(testFileNoPath, upperCase, true)); + CPPUNIT_ASSERT(!StringUtil::match(testFileNoPath, upperCase, true)); } void StringTests::testMatchCaseInSensitive() { - // Test positive - CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, testFileNoPath, false)); - // Test positive - String upperCase = testFileNoPath; - StringUtil::toUpperCase(upperCase); - CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, upperCase, false)); + // Test positive + CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, testFileNoPath, false)); + // Test positive + String upperCase = testFileNoPath; + StringUtil::toUpperCase(upperCase); + CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, upperCase, false)); } void StringTests::testMatchGlobAll() { - CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "*", true)); + CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "*", true)); } void StringTests::testMatchGlobStart() { - CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "*stfile.txt", true)); - CPPUNIT_ASSERT(!StringUtil::match(testFileNoPath, "*astfile.txt", true)); + CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "*stfile.txt", true)); + CPPUNIT_ASSERT(!StringUtil::match(testFileNoPath, "*astfile.txt", true)); } void StringTests::testMatchGlobEnd() { - CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "testfile.*", true)); - CPPUNIT_ASSERT(!StringUtil::match(testFileNoPath, "testfile.d*", true)); + CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "testfile.*", true)); + CPPUNIT_ASSERT(!StringUtil::match(testFileNoPath, "testfile.d*", true)); } void StringTests::testMatchGlobStartAndEnd() { - CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "*stfile.*", true)); - CPPUNIT_ASSERT(!StringUtil::match(testFileNoPath, "*astfile.d*", true)); + CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "*stfile.*", true)); + CPPUNIT_ASSERT(!StringUtil::match(testFileNoPath, "*astfile.d*", true)); } void StringTests::testMatchGlobMiddle() { - CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "test*.txt", true)); - CPPUNIT_ASSERT(!StringUtil::match(testFileNoPath, "last*.txt*", true)); + CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "test*.txt", true)); + CPPUNIT_ASSERT(!StringUtil::match(testFileNoPath, "last*.txt*", true)); } void StringTests::testMatchSuperGlobtastic() { - CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "*e*tf*e.t*t", true)); + CPPUNIT_ASSERT(StringUtil::match(testFileNoPath, "*e*tf*e.t*t", true)); } void StringTests::testParseReal() { - Real r = 23.454; + Real r = 23.454; - String s = StringConverter::toString(r); - Real t = StringConverter::parseReal(s); + String s = StringConverter::toString(r); + Real t = StringConverter::parseReal(s); - CPPUNIT_ASSERT_EQUAL(r, t); + CPPUNIT_ASSERT_EQUAL(r, t); } void StringTests::testParseInt() { - int r = 223546; + int r = 223546; - String s = StringConverter::toString(r); - int t = StringConverter::parseInt(s); + String s = StringConverter::toString(r); + int t = StringConverter::parseInt(s); - CPPUNIT_ASSERT_EQUAL(r, t); + CPPUNIT_ASSERT_EQUAL(r, t); } void StringTests::testParseLong() { - long r = -2147483647; + long r = -2147483647; - String s = StringConverter::toString(r); - long t = StringConverter::parseLong(s); + String s = StringConverter::toString(r); + long t = StringConverter::parseLong(s); - CPPUNIT_ASSERT_EQUAL(r, t); + CPPUNIT_ASSERT_EQUAL(r, t); } void StringTests::testParseUnsignedLong() { - unsigned long r = 4294967295UL; + unsigned long r = 4294967295UL; - String s = StringConverter::toString(r); - unsigned long t = StringConverter::parseUnsignedLong(s); + String s = StringConverter::toString(r); + unsigned long t = StringConverter::parseUnsignedLong(s); - CPPUNIT_ASSERT_EQUAL(r, t); + CPPUNIT_ASSERT_EQUAL(r, t); } void StringTests::testParseVector3() { - Vector3 r(0.12, 3.22, -4.04); + Vector3 r(0.12, 3.22, -4.04); - String s = StringConverter::toString(r); - Vector3 t = StringConverter::parseVector3(s); + String s = StringConverter::toString(r); + Vector3 t = StringConverter::parseVector3(s); - CPPUNIT_ASSERT_EQUAL(r, t); + CPPUNIT_ASSERT_EQUAL(r, t); } void StringTests::testParseMatrix4() { - Matrix4 r(1.12, 0, 0, 34, 0, 0.87, 0, 20, 0, 0, 0.56, 10, 0, 0, 0, 1); + Matrix4 r(1.12, 0, 0, 34, 0, 0.87, 0, 20, 0, 0, 0.56, 10, 0, 0, 0, 1); - String s = StringConverter::toString(r); - Matrix4 t = StringConverter::parseMatrix4(s); + String s = StringConverter::toString(r); + Matrix4 t = StringConverter::parseMatrix4(s); - CPPUNIT_ASSERT_EQUAL(r, t); + CPPUNIT_ASSERT_EQUAL(r, t); } void StringTests::testParseQuaternion() { - Quaternion r(1.12, 0.87, 0.67, 1); + Quaternion r(1.12, 0.87, 0.67, 1); - String s = StringConverter::toString(r); - Quaternion t = StringConverter::parseQuaternion(s); + String s = StringConverter::toString(r); + Quaternion t = StringConverter::parseQuaternion(s); - CPPUNIT_ASSERT_EQUAL(r, t); + CPPUNIT_ASSERT_EQUAL(r, t); } void StringTests::testParseBool() { - bool r = true; - String s = StringConverter::toString(r); - bool t = StringConverter::parseBool(s); - CPPUNIT_ASSERT_EQUAL(r, t); + bool r = true; + String s = StringConverter::toString(r); + bool t = StringConverter::parseBool(s); + CPPUNIT_ASSERT_EQUAL(r, t); - r = false; - s = StringConverter::toString(r); - t = StringConverter::parseBool(s); - CPPUNIT_ASSERT_EQUAL(r, t); + r = false; + s = StringConverter::toString(r); + t = StringConverter::parseBool(s); + CPPUNIT_ASSERT_EQUAL(r, t); } void StringTests::testParseColourValue() { - ColourValue r(0.34, 0.44, 0.77, 1.0); + ColourValue r(0.34, 0.44, 0.77, 1.0); - String s = StringConverter::toString(r); - ColourValue t = StringConverter::parseColourValue(s); - CPPUNIT_ASSERT_EQUAL(r, t); + String s = StringConverter::toString(r); + ColourValue t = StringConverter::parseColourValue(s); + CPPUNIT_ASSERT_EQUAL(r, t); } diff --git a/Tests/OgreMain/src/Suite.cpp b/Tests/OgreMain/src/Suite.cpp index ce3fc3821eb..2f7bd5679db 100644 --- a/Tests/OgreMain/src/Suite.cpp +++ b/Tests/OgreMain/src/Suite.cpp @@ -45,23 +45,23 @@ void setUpSuite() void tearDownSuite() { // shutdown and release managers that might have been created - if(Ogre::HighLevelGpuProgramManager::getSingletonPtr()) - delete Ogre::HighLevelGpuProgramManager::getSingletonPtr(); - if(Ogre::GpuProgramManager::getSingletonPtr()) - delete Ogre::GpuProgramManager::getSingletonPtr(); - if(Ogre::CompositorManager::getSingletonPtr()) - delete Ogre::CompositorManager::getSingletonPtr(); - if(Ogre::MaterialManager::getSingletonPtr()) - delete Ogre::MaterialManager::getSingletonPtr(); - if(Ogre::ResourceGroupManager::getSingletonPtr()) - delete Ogre::ResourceGroupManager::getSingletonPtr(); + if(Ogre::HighLevelGpuProgramManager::getSingletonPtr()) + delete Ogre::HighLevelGpuProgramManager::getSingletonPtr(); + if(Ogre::GpuProgramManager::getSingletonPtr()) + delete Ogre::GpuProgramManager::getSingletonPtr(); + if(Ogre::CompositorManager::getSingletonPtr()) + delete Ogre::CompositorManager::getSingletonPtr(); + if(Ogre::MaterialManager::getSingletonPtr()) + delete Ogre::MaterialManager::getSingletonPtr(); + if(Ogre::ResourceGroupManager::getSingletonPtr()) + delete Ogre::ResourceGroupManager::getSingletonPtr(); - if(Ogre::LogManager::getSingletonPtr()) - delete Ogre::LogManager::getSingletonPtr(); - if(Ogre::ResourceGroupManager::getSingletonPtr()) - delete Ogre::ResourceGroupManager::getSingletonPtr(); - if(Ogre::LodStrategyManager::getSingletonPtr()) - delete Ogre::LodStrategyManager::getSingletonPtr(); + if(Ogre::LogManager::getSingletonPtr()) + delete Ogre::LogManager::getSingletonPtr(); + if(Ogre::ResourceGroupManager::getSingletonPtr()) + delete Ogre::ResourceGroupManager::getSingletonPtr(); + if(Ogre::LodStrategyManager::getSingletonPtr()) + delete Ogre::LodStrategyManager::getSingletonPtr(); } diff --git a/Tests/OgreMain/src/UseCustomCapabilitiesTests.cpp b/Tests/OgreMain/src/UseCustomCapabilitiesTests.cpp index 6a890ed5636..2768d656d2d 100644 --- a/Tests/OgreMain/src/UseCustomCapabilitiesTests.cpp +++ b/Tests/OgreMain/src/UseCustomCapabilitiesTests.cpp @@ -46,25 +46,25 @@ void UseCustomCapabilitiesTests::setUp() { using namespace Ogre; - // write cleanup to log - if(LogManager::getSingletonPtr() == 0) - { - LogManager* logManager = OGRE_NEW LogManager(); - logManager->createLog("testCustomCapabilitiesSetUp.log", true, false); - } + // write cleanup to log + if(LogManager::getSingletonPtr() == 0) + { + LogManager* logManager = OGRE_NEW LogManager(); + logManager->createLog("testCustomCapabilitiesSetUp.log", true, false); + } LogManager::getSingleton().setLogDetail(LL_LOW); - - if(Ogre::HighLevelGpuProgramManager::getSingletonPtr()) - OGRE_DELETE Ogre::HighLevelGpuProgramManager::getSingletonPtr(); - if(Ogre::GpuProgramManager::getSingletonPtr()) - OGRE_DELETE Ogre::GpuProgramManager::getSingletonPtr(); - if(Ogre::CompositorManager::getSingletonPtr()) - OGRE_DELETE Ogre::CompositorManager::getSingletonPtr(); - if(Ogre::MaterialManager::getSingletonPtr()) - OGRE_DELETE Ogre::MaterialManager::getSingletonPtr(); - if(Ogre::ResourceGroupManager::getSingletonPtr()) - OGRE_DELETE Ogre::ResourceGroupManager::getSingletonPtr(); + + if(Ogre::HighLevelGpuProgramManager::getSingletonPtr()) + OGRE_DELETE Ogre::HighLevelGpuProgramManager::getSingletonPtr(); + if(Ogre::GpuProgramManager::getSingletonPtr()) + OGRE_DELETE Ogre::GpuProgramManager::getSingletonPtr(); + if(Ogre::CompositorManager::getSingletonPtr()) + OGRE_DELETE Ogre::CompositorManager::getSingletonPtr(); + if(Ogre::MaterialManager::getSingletonPtr()) + OGRE_DELETE Ogre::MaterialManager::getSingletonPtr(); + if(Ogre::ResourceGroupManager::getSingletonPtr()) + OGRE_DELETE Ogre::ResourceGroupManager::getSingletonPtr(); #if OGRE_STATIC mStaticPluginLoader = OGRE_NEW Ogre::StaticPluginLoader(); @@ -73,10 +73,10 @@ void UseCustomCapabilitiesTests::setUp() void UseCustomCapabilitiesTests::tearDown() { - using namespace Ogre; - // set up silent logging to not pollute output - if(LogManager::getSingletonPtr()) - OGRE_DELETE Ogre::LogManager::getSingletonPtr(); + using namespace Ogre; + // set up silent logging to not pollute output + if(LogManager::getSingletonPtr()) + OGRE_DELETE Ogre::LogManager::getSingletonPtr(); #if OGRE_STATIC OGRE_DELETE mStaticPluginLoader; @@ -162,148 +162,148 @@ void checkCaps(const Ogre::RenderSystemCapabilities* caps) void setUpGLRenderSystemOptions(Ogre::RenderSystem* rs) { - using namespace Ogre; - ConfigOptionMap options = rs->getConfigOptions(); - // set default options - // this should work on every semi-normal system - rs->setConfigOption(String("Colour Depth"), String("32")); - rs->setConfigOption(String("FSAA"), String("0")); - rs->setConfigOption(String("Full Screen"), String("No")); - rs->setConfigOption(String("VSync"), String("No")); - rs->setConfigOption(String("Video Mode"), String("800 x 600")); - - // use the best RTT - ConfigOption optionRTT = options["RTT Preferred Mode"]; - - if(find(optionRTT.possibleValues.begin(), optionRTT.possibleValues.end(), "FBO") != optionRTT.possibleValues.end()) - { - rs->setConfigOption(String("RTT Preferred Mode"), String("FBO")); - } - else if(find(optionRTT.possibleValues.begin(), optionRTT.possibleValues.end(), "PBuffer") != optionRTT.possibleValues.end()) - { - rs->setConfigOption(String("RTT Preferred Mode"), String("PBuffer")); - } - else - rs->setConfigOption(String("RTT Preferred Mode"), String("Copy")); + using namespace Ogre; + ConfigOptionMap options = rs->getConfigOptions(); + // set default options + // this should work on every semi-normal system + rs->setConfigOption(String("Colour Depth"), String("32")); + rs->setConfigOption(String("FSAA"), String("0")); + rs->setConfigOption(String("Full Screen"), String("No")); + rs->setConfigOption(String("VSync"), String("No")); + rs->setConfigOption(String("Video Mode"), String("800 x 600")); + + // use the best RTT + ConfigOption optionRTT = options["RTT Preferred Mode"]; + + if(find(optionRTT.possibleValues.begin(), optionRTT.possibleValues.end(), "FBO") != optionRTT.possibleValues.end()) + { + rs->setConfigOption(String("RTT Preferred Mode"), String("FBO")); + } + else if(find(optionRTT.possibleValues.begin(), optionRTT.possibleValues.end(), "PBuffer") != optionRTT.possibleValues.end()) + { + rs->setConfigOption(String("RTT Preferred Mode"), String("PBuffer")); + } + else + rs->setConfigOption(String("RTT Preferred Mode"), String("Copy")); } void UseCustomCapabilitiesTests::testCustomCapabilitiesGL() { using namespace Ogre; - // set up silent logging to not pollute output - if(LogManager::getSingletonPtr()) - OGRE_DELETE Ogre::LogManager::getSingletonPtr(); - - if(LogManager::getSingletonPtr() == 0) - { - LogManager* logManager = OGRE_NEW LogManager(); - logManager->createLog("testCustomCapabilitiesGL.log", true, false); - } + // set up silent logging to not pollute output + if(LogManager::getSingletonPtr()) + OGRE_DELETE Ogre::LogManager::getSingletonPtr(); + + if(LogManager::getSingletonPtr() == 0) + { + LogManager* logManager = OGRE_NEW LogManager(); + logManager->createLog("testCustomCapabilitiesGL.log", true, false); + } LogManager::getSingleton().setLogDetail(LL_LOW); #ifdef OGRE_STATIC_LIB - Root* root = OGRE_NEW Root(BLANKSTRING); + Root* root = OGRE_NEW Root(BLANKSTRING); - mStaticPluginLoader.load(); + mStaticPluginLoader.load(); #else #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS - Root* root = OGRE_NEW Root(macBundlePath() + "/Contents/Resources/plugins.cfg"); + Root* root = OGRE_NEW Root(macBundlePath() + "/Contents/Resources/plugins.cfg"); #else - Root* root = OGRE_NEW Root("plugins.cfg"); + Root* root = OGRE_NEW Root("plugins.cfg"); #endif #endif - RenderSystem* rs = root->getRenderSystemByName("OpenGL Rendering Subsystem"); - if(rs == 0) - { - CPPUNIT_ASSERT_ASSERTION_PASS("This test is irrelevant because GL RenderSystem is not available"); - } - else - { - try { - setUpGLRenderSystemOptions(rs); - root->setRenderSystem(rs); + RenderSystem* rs = root->getRenderSystemByName("OpenGL Rendering Subsystem"); + if(rs == 0) + { + CPPUNIT_ASSERT_ASSERTION_PASS("This test is irrelevant because GL RenderSystem is not available"); + } + else + { + try { + setUpGLRenderSystemOptions(rs); + root->setRenderSystem(rs); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS - root->initialise(true, "OGRE testCustomCapabilitiesGL Window", + root->initialise(true, "OGRE testCustomCapabilitiesGL Window", macBundlePath() + "/Contents/Resources/Media/CustomCapabilities/customCapabilitiesTest.cfg"); #else - root->initialise(true, "OGRE testCustomCapabilitiesGL Window", + root->initialise(true, "OGRE testCustomCapabilitiesGL Window", "../Tests/Media/CustomCapabilities/customCapabilitiesTest.cfg"); #endif - const RenderSystemCapabilities* caps = rs->getCapabilities(); + const RenderSystemCapabilities* caps = rs->getCapabilities(); - checkCaps(caps); - } - // clean up root, in case of error, and let cppunit to handle the exception - catch(...) - { - } - } + checkCaps(caps); + } + // clean up root, in case of error, and let cppunit to handle the exception + catch(...) + { + } + } OGRE_DELETE root; } void setUpD3D9RenderSystemOptions(Ogre::RenderSystem* rs) { - using namespace Ogre; - ConfigOptionMap options = rs->getConfigOptions(); - // set default options - // this should work on every semi-normal system - rs->setConfigOption(String("Anti aliasing"), String("None")); - rs->setConfigOption(String("Full Screen"), String("No")); - rs->setConfigOption(String("VSync"), String("No")); - rs->setConfigOption(String("Video Mode"), String("800 x 600 @ 32-bit colour")); - - // pick first available device - ConfigOption optionDevice = options["Rendering Device"]; - - rs->setConfigOption(optionDevice.name, optionDevice.currentValue); + using namespace Ogre; + ConfigOptionMap options = rs->getConfigOptions(); + // set default options + // this should work on every semi-normal system + rs->setConfigOption(String("Anti aliasing"), String("None")); + rs->setConfigOption(String("Full Screen"), String("No")); + rs->setConfigOption(String("VSync"), String("No")); + rs->setConfigOption(String("Video Mode"), String("800 x 600 @ 32-bit colour")); + + // pick first available device + ConfigOption optionDevice = options["Rendering Device"]; + + rs->setConfigOption(optionDevice.name, optionDevice.currentValue); } void UseCustomCapabilitiesTests::testCustomCapabilitiesD3D9() { - // set up silent logging to not pollute output - if(LogManager::getSingletonPtr()) - OGRE_DELETE Ogre::LogManager::getSingletonPtr(); - - if(LogManager::getSingletonPtr() == 0) - { - LogManager* logManager = OGRE_NEW LogManager(); - logManager->createLog("testCustomCapabilitiesD3D9.log", true, false); - } + // set up silent logging to not pollute output + if(LogManager::getSingletonPtr()) + OGRE_DELETE Ogre::LogManager::getSingletonPtr(); + + if(LogManager::getSingletonPtr() == 0) + { + LogManager* logManager = OGRE_NEW LogManager(); + logManager->createLog("testCustomCapabilitiesD3D9.log", true, false); + } LogManager::getSingleton().setLogDetail(LL_LOW); #ifdef OGRE_STATIC_LIB - Root* root = OGRE_NEW Root(BLANKSTRING); + Root* root = OGRE_NEW Root(BLANKSTRING); - mStaticPluginLoader.load(); + mStaticPluginLoader.load(); #else - Root* root = OGRE_NEW Root("plugins.cfg"); + Root* root = OGRE_NEW Root("plugins.cfg"); #endif - RenderSystem* rs = root->getRenderSystemByName("Direct3D9 Rendering Subsystem"); - if(rs == 0) - { - CPPUNIT_ASSERT_ASSERTION_PASS("This test is irrelevant because D3D9 RenderSystem is not available"); - } - else - { - try { - setUpD3D9RenderSystemOptions(rs); - root->setRenderSystem(rs); - root->initialise(true, "OGRE testCustomCapabilitiesD3D9 Window", - "../../../Media/CustomCapabilities/customCapabilitiesTest.cfg"); - - const RenderSystemCapabilities* caps = rs->getCapabilities(); - - checkCaps(caps); - } - // clean up root, in case of error, and let cppunit to handle the exception - catch(...) - { - } - } + RenderSystem* rs = root->getRenderSystemByName("Direct3D9 Rendering Subsystem"); + if(rs == 0) + { + CPPUNIT_ASSERT_ASSERTION_PASS("This test is irrelevant because D3D9 RenderSystem is not available"); + } + else + { + try { + setUpD3D9RenderSystemOptions(rs); + root->setRenderSystem(rs); + root->initialise(true, "OGRE testCustomCapabilitiesD3D9 Window", + "../../../Media/CustomCapabilities/customCapabilitiesTest.cfg"); + + const RenderSystemCapabilities* caps = rs->getCapabilities(); + + checkCaps(caps); + } + // clean up root, in case of error, and let cppunit to handle the exception + catch(...) + { + } + } OGRE_DELETE root; } diff --git a/Tests/PlayPen/include/AnimationBlender.h b/Tests/PlayPen/include/AnimationBlender.h index 16f91bc4340..9d25e51639a 100644 --- a/Tests/PlayPen/include/AnimationBlender.h +++ b/Tests/PlayPen/include/AnimationBlender.h @@ -7,34 +7,34 @@ using namespace Ogre; class AnimationBlender { public: - enum BlendingTransition - { - BlendSwitch, // stop source and start dest - BlendWhileAnimating, // cross fade, blend source animation out while blending destination animation in - BlendThenAnimate // blend source to first frame of dest, when done, start dest anim - }; + enum BlendingTransition + { + BlendSwitch, // stop source and start dest + BlendWhileAnimating, // cross fade, blend source animation out while blending destination animation in + BlendThenAnimate // blend source to first frame of dest, when done, start dest anim + }; private: - Entity *mEntity; - AnimationState *mSource; - AnimationState *mTarget; + Entity *mEntity; + AnimationState *mSource; + AnimationState *mTarget; - BlendingTransition mTransition; + BlendingTransition mTransition; - bool loop; + bool loop; - ~AnimationBlender() {} + ~AnimationBlender() {} public: - Real mTimeleft, mDuration; + Real mTimeleft, mDuration; - bool complete; + bool complete; - void blend( const String &animation, BlendingTransition transition, Real duration, bool loop ); - void addTime( Real ); - Real getProgress() { return mTimeleft/ mDuration; } - AnimationState *getSource() { return mSource; } - AnimationState *getTarget() { return mTarget; } - AnimationBlender( Entity *); - void init( const String &animation ); + void blend( const String &animation, BlendingTransition transition, Real duration, bool loop ); + void addTime( Real ); + Real getProgress() { return mTimeleft/ mDuration; } + AnimationState *getSource() { return mSource; } + AnimationState *getTarget() { return mTarget; } + AnimationBlender( Entity *); + void init( const String &animation ); }; diff --git a/Tests/PlayPen/include/PlayPen.h b/Tests/PlayPen/include/PlayPen.h index a5d7c0021b0..96f04f7c0d1 100644 --- a/Tests/PlayPen/include/PlayPen.h +++ b/Tests/PlayPen/include/PlayPen.h @@ -11,8 +11,8 @@ using namespace OgreBites; class _OgreSampleClassExport PlayPenPlugin : public SamplePlugin { public: - PlayPenPlugin(); - ~PlayPenPlugin(); + PlayPenPlugin(); + ~PlayPenPlugin(); }; @@ -23,16 +23,16 @@ class _OgreSampleClassExport PlayPenBase : public SdkSample { public: - /// Resources in this group get destroyed on sample shutdown - static String TRANSIENT_RESOURCE_GROUP; + /// Resources in this group get destroyed on sample shutdown + static String TRANSIENT_RESOURCE_GROUP; - PlayPenBase(); - void unloadResources(); - bool frameStarted(const Ogre::FrameEvent& evt); + PlayPenBase(); + void unloadResources(); + bool frameStarted(const Ogre::FrameEvent& evt); protected: - typedef list::type AnimationStateList; - AnimationStateList mAnimStateList; - void cleanupContent() { mAnimStateList.clear(); } + typedef list::type AnimationStateList; + AnimationStateList mAnimStateList; + void cleanupContent() { mAnimStateList.clear(); } }; diff --git a/Tests/PlayPen/include/PlayPenSamples.h b/Tests/PlayPen/include/PlayPenSamples.h index 53575065951..28e6ccd7bf9 100644 --- a/Tests/PlayPen/include/PlayPenSamples.h +++ b/Tests/PlayPen/include/PlayPenSamples.h @@ -34,38 +34,38 @@ THE SOFTWARE. class _OgreSampleClassExport PlayPen_testManualBlend : public PlayPenBase { public: - PlayPen_testManualBlend(); + PlayPen_testManualBlend(); protected: - void setupContent(); + void setupContent(); }; //--------------------------------------------------------------------- class _OgreSampleClassExport PlayPen_testProjectSphere : public PlayPenBase { public: - PlayPen_testProjectSphere(); - bool frameStarted(const Ogre::FrameEvent& evt); + PlayPen_testProjectSphere(); + bool frameStarted(const Ogre::FrameEvent& evt); protected: - Sphere* mProjectionSphere; - ManualObject* mScissorRect; - void setupContent(); + Sphere* mProjectionSphere; + ManualObject* mScissorRect; + void setupContent(); }; //--------------------------------------------------------------------- class _OgreSampleClassExport PlayPen_testCameraSetDirection : public PlayPenBase { public: - PlayPen_testCameraSetDirection(); + PlayPen_testCameraSetDirection(); - void buttonHit(OgreBites::Button* button); - void checkBoxToggled(OgreBites::CheckBox* box); + void buttonHit(OgreBites::Button* button); + void checkBoxToggled(OgreBites::CheckBox* box); protected: - bool mUseParentNode; - bool mUseFixedYaw; - SceneNode* mParentNode; - Vector3 mFocus; - void setupContent(); - void toggleParentNode(); - void toggleFixedYaw(); - void track(); + bool mUseParentNode; + bool mUseFixedYaw; + SceneNode* mParentNode; + Vector3 mFocus; + void setupContent(); + void toggleParentNode(); + void toggleFixedYaw(); + void track(); }; #ifdef OGRE_BUILD_COMPONENT_MESHLODGENERATOR @@ -73,36 +73,36 @@ class _OgreSampleClassExport PlayPen_testCameraSetDirection : public PlayPenBase class _OgreSampleClassExport PlayPen_testManualLOD : public PlayPenBase { public: - PlayPen_testManualLOD(); + PlayPen_testManualLOD(); protected: - void setupContent(); - String getLODMesh(); + void setupContent(); + String getLODMesh(); }; //--------------------------------------------------------------------- class _OgreSampleClassExport PlayPen_testManualLODFromFile : public PlayPen_testManualLOD { public: - PlayPen_testManualLODFromFile(); + PlayPen_testManualLODFromFile(); protected: - String getLODMesh(); + String getLODMesh(); }; #endif //--------------------------------------------------------------------- class _OgreSampleClassExport PlayPen_testFullScreenSwitch : public PlayPenBase { public: - PlayPen_testFullScreenSwitch(); + PlayPen_testFullScreenSwitch(); - void buttonHit(OgreBites::Button* button); + void buttonHit(OgreBites::Button* button); protected: - void setupContent(); + void setupContent(); - OgreBites::Button* m640x480w; - OgreBites::Button* m800x600w; - OgreBites::Button* m1024x768w; - OgreBites::Button* m640x480fs; - OgreBites::Button* m800x600fs; - OgreBites::Button* m1024x768fs; + OgreBites::Button* m640x480w; + OgreBites::Button* m800x600w; + OgreBites::Button* m1024x768w; + OgreBites::Button* m640x480fs; + OgreBites::Button* m800x600fs; + OgreBites::Button* m1024x768fs; }; @@ -110,33 +110,33 @@ class _OgreSampleClassExport PlayPen_testFullScreenSwitch : public PlayPenBase class _OgreSampleClassExport PlayPen_testMorphAnimationWithNormals : public PlayPenBase { public: - PlayPen_testMorphAnimationWithNormals(); + PlayPen_testMorphAnimationWithNormals(); protected: - void setupContent(); + void setupContent(); }; //--------------------------------------------------------------------- class _OgreSampleClassExport PlayPen_testMorphAnimationWithoutNormals : public PlayPenBase { public: - PlayPen_testMorphAnimationWithoutNormals(); + PlayPen_testMorphAnimationWithoutNormals(); protected: - void setupContent(); + void setupContent(); }; //--------------------------------------------------------------------- class _OgreSampleClassExport PlayPen_testPoseAnimationWithNormals : public PlayPenBase { public: - PlayPen_testPoseAnimationWithNormals(); + PlayPen_testPoseAnimationWithNormals(); protected: - void setupContent(); + void setupContent(); }; //--------------------------------------------------------------------- class _OgreSampleClassExport PlayPen_testPoseAnimationWithoutNormals : public PlayPenBase { public: - PlayPen_testPoseAnimationWithoutNormals(); + PlayPen_testPoseAnimationWithoutNormals(); protected: - void setupContent(); + void setupContent(); }; diff --git a/Tests/PlayPen/include/StaticPluginLoader.h b/Tests/PlayPen/include/StaticPluginLoader.h index 24efb05b4db..6ec565a491d 100644 --- a/Tests/PlayPen/include/StaticPluginLoader.h +++ b/Tests/PlayPen/include/StaticPluginLoader.h @@ -48,102 +48,102 @@ Description: Utility class to load plugins statically namespace Ogre { - /** Utility class for loading some plugins statically. - @remarks - When loading plugins statically, you are limited to loading plugins - that are known about at compile time. You should define preprocessor - symbols depending on which plugins you want to load - the symbol being - ENABLE_PLUGIN_, with pluginname being the usual name of the - plugin DLL (no file extension, no debug suffix, and without the Plugin_ - or RenderSystem_ prefix.) - */ - class StaticPluginLoader - { - protected: + /** Utility class for loading some plugins statically. + @remarks + When loading plugins statically, you are limited to loading plugins + that are known about at compile time. You should define preprocessor + symbols depending on which plugins you want to load - the symbol being + ENABLE_PLUGIN_, with pluginname being the usual name of the + plugin DLL (no file extension, no debug suffix, and without the Plugin_ + or RenderSystem_ prefix.) + */ + class StaticPluginLoader + { + protected: #ifdef ENABLE_PLUGIN_CgProgramManager - CgPlugin* mCgPlugin; + CgPlugin* mCgPlugin; #endif #ifdef ENABLE_PLUGIN_OctreeSceneManager - OctreePlugin* mOctreePlugin; + OctreePlugin* mOctreePlugin; #endif #ifdef ENABLE_PLUGIN_ParticleFX - ParticleFXPlugin* mParticleFXPlugin; + ParticleFXPlugin* mParticleFXPlugin; #endif #ifdef ENABLE_PLUGIN_BSPSceneManager - BspSceneManagerPlugin* mBSPPlugin; + BspSceneManagerPlugin* mBSPPlugin; #endif #ifdef ENABLE_PLUGIN_GL - GLPlugin* mGLPlugin; + GLPlugin* mGLPlugin; #endif #ifdef ENABLE_PLUGIN_GLES - GLESPlugin* mGLESPlugin; + GLESPlugin* mGLESPlugin; #endif #ifdef ENABLE_PLUGIN_Direct3D9 - D3D9Plugin* mD3D9Plugin; + D3D9Plugin* mD3D9Plugin; #endif - public: - StaticPluginLoader() {} + public: + StaticPluginLoader() {} - /** Load all the enabled plugins against the passed in root object. */ - void load(Root& root) - { + /** Load all the enabled plugins against the passed in root object. */ + void load(Root& root) + { #ifdef ENABLE_PLUGIN_GL - mGLPlugin = new GLPlugin(); - root.installPlugin(mGLPlugin); + mGLPlugin = new GLPlugin(); + root.installPlugin(mGLPlugin); #endif #ifdef ENABLE_PLUGIN_GLES - mGLESPlugin = new GLESPlugin(); - root.installPlugin(mGLESPlugin); + mGLESPlugin = new GLESPlugin(); + root.installPlugin(mGLESPlugin); #endif #ifdef ENABLE_PLUGIN_Direct3D9 - mD3D9Plugin = new D3D9Plugin(); - root.installPlugin(mD3D9Plugin); + mD3D9Plugin = new D3D9Plugin(); + root.installPlugin(mD3D9Plugin); #endif #ifdef ENABLE_PLUGIN_CgProgramManager - mCgPlugin = new CgPlugin(); - root.installPlugin(mCgPlugin); + mCgPlugin = new CgPlugin(); + root.installPlugin(mCgPlugin); #endif #ifdef ENABLE_PLUGIN_OctreeSceneManager - mOctreePlugin = new OctreePlugin(); - root.installPlugin(mOctreePlugin); + mOctreePlugin = new OctreePlugin(); + root.installPlugin(mOctreePlugin); #endif #ifdef ENABLE_PLUGIN_ParticleFX - mParticleFXPlugin = new ParticleFXPlugin(); - root.installPlugin(mParticleFXPlugin); + mParticleFXPlugin = new ParticleFXPlugin(); + root.installPlugin(mParticleFXPlugin); #endif #ifdef ENABLE_PLUGIN_BSPSceneManager - mBSPPlugin = new BspSceneManagerPlugin(); - root.installPlugin(mBSPPlugin); + mBSPPlugin = new BspSceneManagerPlugin(); + root.installPlugin(mBSPPlugin); #endif - } + } - void unload() - { - // don't unload plugins, since Root will have done that. Destroy here. + void unload() + { + // don't unload plugins, since Root will have done that. Destroy here. #ifdef ENABLE_PLUGIN_BSPSceneManager - delete mBSPPlugin; + delete mBSPPlugin; #endif #ifdef ENABLE_PLUGIN_ParticleFX - delete mParticleFXPlugin; + delete mParticleFXPlugin; #endif #ifdef ENABLE_PLUGIN_OctreeSceneManager - delete mOctreePlugin; + delete mOctreePlugin; #endif #ifdef ENABLE_PLUGIN_CgProgramManager - delete mCgPlugin; + delete mCgPlugin; #endif #ifdef ENABLE_PLUGIN_Direct3D9 - delete mD3D9Plugin; + delete mD3D9Plugin; #endif #ifdef ENABLE_PLUGIN_GLES - delete mGLESPlugin; + delete mGLESPlugin; #endif - } + } - }; + }; } diff --git a/Tests/PlayPen/src/AnimationBlender.cpp b/Tests/PlayPen/src/AnimationBlender.cpp index 0e58ee6ac74..601f633672c 100644 --- a/Tests/PlayPen/src/AnimationBlender.cpp +++ b/Tests/PlayPen/src/AnimationBlender.cpp @@ -9,131 +9,131 @@ using namespace Ogre; void AnimationBlender::init(const String &animation) { - AnimationStateSet *set = mEntity->getAllAnimationStates(); - AnimationStateIterator it = set->getAnimationStateIterator(); - while(it.hasMoreElements()) - { - AnimationState *anim = it.getNext(); - anim->setEnabled(false); - anim->setWeight(0); - anim->setTimePosition(0); - } - mSource = mEntity->getAnimationState( animation ); - mSource->setEnabled(true); - mSource->setWeight(1); - mTimeleft = 0; - mDuration = 1; - mTarget = 0; - complete=false; + AnimationStateSet *set = mEntity->getAllAnimationStates(); + AnimationStateIterator it = set->getAnimationStateIterator(); + while(it.hasMoreElements()) + { + AnimationState *anim = it.getNext(); + anim->setEnabled(false); + anim->setWeight(0); + anim->setTimePosition(0); + } + mSource = mEntity->getAnimationState( animation ); + mSource->setEnabled(true); + mSource->setWeight(1); + mTimeleft = 0; + mDuration = 1; + mTarget = 0; + complete=false; } void AnimationBlender::blend( const String &animation, BlendingTransition transition, Real duration, bool l ) { - loop=l; - if( transition == AnimationBlender::BlendSwitch ) - { - if( mSource != 0 ) - mSource->setEnabled(false); - mSource = mEntity->getAnimationState( animation ); - mSource->setEnabled(true); - mSource->setWeight(1); - mSource->setTimePosition(0); - mTimeleft = 0; - } - else - { - AnimationState *newTarget = mEntity->getAnimationState( animation ); - if( mTimeleft > 0 ) - { - // oops, weren't finished yet - if( newTarget == mTarget ) - { - // nothing to do! (ignoring duration here) - } - else if( newTarget == mSource ) - { - // going back to the source state, so let's switch - mSource = mTarget; - mTarget = newTarget; - mTimeleft = mDuration - mTimeleft; // i'm ignoring the new duration here - } - else - { - // ok, newTarget is really new, so either we simply replace the target with this one, or - // we make the target the new source - if( mTimeleft < mDuration * 0.5 ) - { - // simply replace the target with this one - mTarget->setEnabled(false); - mTarget->setWeight(0); - } - else - { - // old target becomes new source - mSource->setEnabled(false); - mSource->setWeight(0); - mSource = mTarget; - } - mTarget = newTarget; - mTarget->setEnabled(true); - mTarget->setWeight( 1.0 - mTimeleft / mDuration ); - mTarget->setTimePosition(0); - } - } - else - { - if (mSource == newTarget) - { - mTimeleft = 0; - return; - } - // assert( target == 0, "target should be 0 when not blending" ) - // mSource->setEnabled(true); - // mSource->setWeight(1); - mTransition = transition; - mTimeleft = mDuration = duration; - mTarget = newTarget; - mTarget->setEnabled(true); - mTarget->setWeight(0); - mTarget->setTimePosition(0); - } - } + loop=l; + if( transition == AnimationBlender::BlendSwitch ) + { + if( mSource != 0 ) + mSource->setEnabled(false); + mSource = mEntity->getAnimationState( animation ); + mSource->setEnabled(true); + mSource->setWeight(1); + mSource->setTimePosition(0); + mTimeleft = 0; + } + else + { + AnimationState *newTarget = mEntity->getAnimationState( animation ); + if( mTimeleft > 0 ) + { + // oops, weren't finished yet + if( newTarget == mTarget ) + { + // nothing to do! (ignoring duration here) + } + else if( newTarget == mSource ) + { + // going back to the source state, so let's switch + mSource = mTarget; + mTarget = newTarget; + mTimeleft = mDuration - mTimeleft; // i'm ignoring the new duration here + } + else + { + // ok, newTarget is really new, so either we simply replace the target with this one, or + // we make the target the new source + if( mTimeleft < mDuration * 0.5 ) + { + // simply replace the target with this one + mTarget->setEnabled(false); + mTarget->setWeight(0); + } + else + { + // old target becomes new source + mSource->setEnabled(false); + mSource->setWeight(0); + mSource = mTarget; + } + mTarget = newTarget; + mTarget->setEnabled(true); + mTarget->setWeight( 1.0 - mTimeleft / mDuration ); + mTarget->setTimePosition(0); + } + } + else + { + if (mSource == newTarget) + { + mTimeleft = 0; + return; + } + // assert( target == 0, "target should be 0 when not blending" ) + // mSource->setEnabled(true); + // mSource->setWeight(1); + mTransition = transition; + mTimeleft = mDuration = duration; + mTarget = newTarget; + mTarget->setEnabled(true); + mTarget->setWeight(0); + mTarget->setTimePosition(0); + } + } } void AnimationBlender::addTime( Real time ) { - if( mSource != 0 ) - { - if( mTimeleft > 0 ) - { - mTimeleft -= time; - if( mTimeleft < 0 ) - { - // finish blending - mSource->setEnabled(false); - mSource->setWeight(0); - mSource = mTarget; - mSource->setEnabled(true); - mSource->setWeight(1); - mTarget = 0; - } - else - { - // still blending, advance weights - mSource->setWeight(mTimeleft / mDuration); - mTarget->setWeight(1.0 - mTimeleft / mDuration); - if(mTransition == AnimationBlender::BlendWhileAnimating) - mTarget->addTime(time); - } - } - if (mSource->getTimePosition() >= mSource->getLength()) - { - complete=true; - } - else - { - complete=false; - } - mSource->addTime(time); - mSource->setLoop(loop); - } + if( mSource != 0 ) + { + if( mTimeleft > 0 ) + { + mTimeleft -= time; + if( mTimeleft < 0 ) + { + // finish blending + mSource->setEnabled(false); + mSource->setWeight(0); + mSource = mTarget; + mSource->setEnabled(true); + mSource->setWeight(1); + mTarget = 0; + } + else + { + // still blending, advance weights + mSource->setWeight(mTimeleft / mDuration); + mTarget->setWeight(1.0 - mTimeleft / mDuration); + if(mTransition == AnimationBlender::BlendWhileAnimating) + mTarget->addTime(time); + } + } + if (mSource->getTimePosition() >= mSource->getLength()) + { + complete=true; + } + else + { + complete=false; + } + mSource->addTime(time); + mSource->setLoop(loop); + } } AnimationBlender::AnimationBlender( Entity *entity ) : mEntity(entity) {} diff --git a/Tests/PlayPen/src/PlayPen.cpp b/Tests/PlayPen/src/PlayPen.cpp index cf6275bba04..1f35c0f171f 100644 --- a/Tests/PlayPen/src/PlayPen.cpp +++ b/Tests/PlayPen/src/PlayPen.cpp @@ -33,56 +33,56 @@ THE SOFTWARE. PlayPenPlugin::PlayPenPlugin() : SamplePlugin("PlayPenPlugin") { - // add the samples - addSample(new PlayPen_testManualBlend()); - addSample(new PlayPen_testProjectSphere()); - addSample(new PlayPen_testCameraSetDirection()); + // add the samples + addSample(new PlayPen_testManualBlend()); + addSample(new PlayPen_testProjectSphere()); + addSample(new PlayPen_testCameraSetDirection()); #ifdef OGRE_BUILD_COMPONENT_MESHLODGENERATOR - addSample(new PlayPen_testManualLOD()); - addSample(new PlayPen_testManualLODFromFile()); + addSample(new PlayPen_testManualLOD()); + addSample(new PlayPen_testManualLODFromFile()); #endif - addSample(new PlayPen_testFullScreenSwitch()); - addSample(new PlayPen_testMorphAnimationWithNormals()); - addSample(new PlayPen_testMorphAnimationWithoutNormals()); - addSample(new PlayPen_testPoseAnimationWithNormals()); - addSample(new PlayPen_testPoseAnimationWithoutNormals()); + addSample(new PlayPen_testFullScreenSwitch()); + addSample(new PlayPen_testMorphAnimationWithNormals()); + addSample(new PlayPen_testMorphAnimationWithoutNormals()); + addSample(new PlayPen_testPoseAnimationWithNormals()); + addSample(new PlayPen_testPoseAnimationWithoutNormals()); } //--------------------------------------------------------------------- PlayPenPlugin::~PlayPenPlugin() { - for (SampleSet::iterator i = mSamples.begin(); i != mSamples.end(); ++i) - delete *i; - mSamples.clear(); + for (SampleSet::iterator i = mSamples.begin(); i != mSamples.end(); ++i) + delete *i; + mSamples.clear(); } //--------------------------------------------------------------------- //--------------------------------------------------------------------- String PlayPenBase::TRANSIENT_RESOURCE_GROUP = "PlayPenTransient"; PlayPenBase::PlayPenBase() { - mInfo["Thumbnail"] = "thumb_playpen.png"; - mInfo["Category"] = "Tests"; + mInfo["Thumbnail"] = "thumb_playpen.png"; + mInfo["Category"] = "Tests"; - ResourceGroupManager& rgm = ResourceGroupManager::getSingleton(); - if (!rgm.resourceGroupExists(TRANSIENT_RESOURCE_GROUP)) - rgm.createResourceGroup(TRANSIENT_RESOURCE_GROUP); + ResourceGroupManager& rgm = ResourceGroupManager::getSingleton(); + if (!rgm.resourceGroupExists(TRANSIENT_RESOURCE_GROUP)) + rgm.createResourceGroup(TRANSIENT_RESOURCE_GROUP); } //--------------------------------------------------------------------- void PlayPenBase::unloadResources() { - ResourceGroupManager::getSingleton().clearResourceGroup(TRANSIENT_RESOURCE_GROUP); + ResourceGroupManager::getSingleton().clearResourceGroup(TRANSIENT_RESOURCE_GROUP); - SdkSample::unloadResources(); + SdkSample::unloadResources(); } //--------------------------------------------------------------------- bool PlayPenBase::frameStarted(const FrameEvent& evt) { - for (AnimationStateList::iterator animi = mAnimStateList.begin(); animi != mAnimStateList.end(); ++animi) - { - (*animi)->addTime(evt.timeSinceLastFrame); - } - - return true; - + for (AnimationStateList::iterator animi = mAnimStateList.begin(); animi != mAnimStateList.end(); ++animi) + { + (*animi)->addTime(evt.timeSinceLastFrame); + } + + return true; + } @@ -93,14 +93,14 @@ PlayPenPlugin* playPenPlugin = 0; extern "C" _OgreSampleExport void dllStartPlugin() { - playPenPlugin = OGRE_NEW PlayPenPlugin(); - Root::getSingleton().installPlugin(playPenPlugin); + playPenPlugin = OGRE_NEW PlayPenPlugin(); + Root::getSingleton().installPlugin(playPenPlugin); } extern "C" _OgreSampleExport void dllStopPlugin() { - Root::getSingleton().uninstallPlugin(playPenPlugin); - OGRE_DELETE playPenPlugin; + Root::getSingleton().uninstallPlugin(playPenPlugin); + OGRE_DELETE playPenPlugin; } #endif @@ -231,18 +231,18 @@ extern "C" _OgreSampleExport void dllStopPlugin() //class PlayPenListener : public ExampleFrameListener, public ResourceBackgroundQueue::Listener //{ //protected: -// SceneManager* mSceneMgr; +// SceneManager* mSceneMgr; //public: // PlayPenListener(SceneManager* mgr, RenderWindow* win, Camera* cam) // : ExampleFrameListener(win, cam),mSceneMgr(mgr) // { // } // -// /// Background load completed -// void operationCompleted(BackgroundProcessTicket ticket, const Ogre::BackgroundProcessResult &) -// { -// LogManager::getSingleton().stream() << "Background load complete" ; -// } +// /// Background load completed +// void operationCompleted(BackgroundProcessTicket ticket, const Ogre::BackgroundProcessResult &) +// { +// LogManager::getSingleton().stream() << "Background load complete" ; +// } // // bool frameStarted(const FrameEvent& evt) // { @@ -267,167 +267,167 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // } // -// if (manuallyControlledBone) -// { -// manuallyControlledBone->yaw(Degree(evt.timeSinceLastFrame*100)); -// } +// if (manuallyControlledBone) +// { +// manuallyControlledBone->yaw(Degree(evt.timeSinceLastFrame*100)); +// } // // -// static float reloadtime = 10.0f; -// if (testreload) -// { -// reloadtime -= evt.timeSinceLastFrame; -// if (reloadtime <= 0) -// { -// Entity* e = mSceneMgr->getEntity("1"); -// e->getParentSceneNode()->detachObject("1"); -// e = mSceneMgr->getEntity("2"); -// e->getParentSceneNode()->detachObject("2"); -// mSceneMgr->destroyAllEntities(); -// ResourceGroupManager::getSingleton().unloadResourceGroup("Sinbad"); -// ResourceGroupManager::getSingleton().loadResourceGroup("Sinbad"); +// static float reloadtime = 10.0f; +// if (testreload) +// { +// reloadtime -= evt.timeSinceLastFrame; +// if (reloadtime <= 0) +// { +// Entity* e = mSceneMgr->getEntity("1"); +// e->getParentSceneNode()->detachObject("1"); +// e = mSceneMgr->getEntity("2"); +// e->getParentSceneNode()->detachObject("2"); +// mSceneMgr->destroyAllEntities(); +// ResourceGroupManager::getSingleton().unloadResourceGroup("Sinbad"); +// ResourceGroupManager::getSingleton().loadResourceGroup("Sinbad"); // -// testreload = false; +// testreload = false; // -// } -// } +// } +// } // -// static float backgroundLoadTime = 5.0f; -// if (!testBackgroundLoadGroup.empty()) -// { -// backgroundLoadTime -= evt.timeSinceLastFrame; -// if (backgroundLoadTime < 0) -// { -// ResourceBackgroundQueue::getSingleton().loadResourceGroup(testBackgroundLoadGroup, this); -// testBackgroundLoadGroup.clear(); -// LogManager::getSingleton().stream() << "Background load queued"; -// } +// static float backgroundLoadTime = 5.0f; +// if (!testBackgroundLoadGroup.empty()) +// { +// backgroundLoadTime -= evt.timeSinceLastFrame; +// if (backgroundLoadTime < 0) +// { +// ResourceBackgroundQueue::getSingleton().loadResourceGroup(testBackgroundLoadGroup, this); +// testBackgroundLoadGroup.clear(); +// LogManager::getSingleton().stream() << "Background load queued"; +// } // -// } +// } // // // // // bool ret = ExampleFrameListener::frameStarted(evt); // -// if (reflectCam) -// { -// reflectCam->setOrientation(mCamera->getOrientation()); -// reflectCam->setPosition(mCamera->getPosition()); -// } -// if (camera2) -// { -// camera2->setOrientation(mCamera->getOrientation()); -// camera2->setPosition(mCamera->getPosition()); -// } +// if (reflectCam) +// { +// reflectCam->setOrientation(mCamera->getOrientation()); +// reflectCam->setPosition(mCamera->getPosition()); +// } +// if (camera2) +// { +// camera2->setOrientation(mCamera->getOrientation()); +// camera2->setPosition(mCamera->getPosition()); +// } // // -// if (projectionSphere && scissorRect) -// { -// Real left, top, right, bottom; -// mCamera->projectSphere(*projectionSphere, &left, &top, &right, &bottom); +// if (projectionSphere && scissorRect) +// { +// Real left, top, right, bottom; +// mCamera->projectSphere(*projectionSphere, &left, &top, &right, &bottom); // -// scissorRect->beginUpdate(0); -// scissorRect->position(left, top, 0); -// scissorRect->position(left, bottom, 0); -// scissorRect->position(right, bottom, 0); -// scissorRect->position(right, top, 0); -// scissorRect->quad(0,1,2,3); -// scissorRect->end(); +// scissorRect->beginUpdate(0); +// scissorRect->position(left, top, 0); +// scissorRect->position(left, bottom, 0); +// scissorRect->position(right, bottom, 0); +// scissorRect->position(right, top, 0); +// scissorRect->quad(0,1,2,3); +// scissorRect->end(); // // -// } +// } // // // Neither Terrain nor keyboard input works on iOS //#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS -// if (mTerrain) -// { -// if (mKeyboard->isKeyDown(OIS::KC_PERIOD)) -// { -// mTerrain->setLayerWorldSize(0, mTerrain->getLayerWorldSize(0) + 100 * evt.timeSinceLastFrame); -// } -// else if (mKeyboard->isKeyDown(OIS::KC_COMMA)) -// { -// mTerrain->setLayerWorldSize(0, mTerrain->getLayerWorldSize(0) - 100 * evt.timeSinceLastFrame); -// } -// -// // fire ray -// Ray ray; -// ray = mCamera->getCameraToViewportRay(0.5, 0.5); -// //ray.setOrigin(mCamera->getDerivedPosition()); -// //ray.setDirection(Vector3::NEGATIVE_UNIT_Y); -// std::pair rayResult = mTerrain->rayIntersects(ray); -// -// static SceneNode* testNode = 0; -// if (!testNode) -// { -// testNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// testNode->attachObject(mSceneMgr->createEntity("tst", "sphere.mesh")); -// testNode->setScale(0.05, 0.05, 0.05); -// } -// if (rayResult.first) -// { -// testNode->setPosition(rayResult.second); -// StringStream str; -// str << "HIT: " << rayResult.second; -// -// -// if (mKeyboard->isKeyDown(OIS::KC_SPACE)) -// { -// Vector3 tsPos; -// mTerrain->getTerrainPosition(rayResult.second, &tsPos); -// -// size_t x = tsPos.x * (mTerrain->getSize()-1); -// size_t y = tsPos.y * (mTerrain->getSize()-1); -// float addedHeight = 250.0 * evt.timeSinceLastFrame; -// float newheight = mTerrain->getHeightAtPoint(x, y) + addedHeight; -// -// mTerrain->setHeightAtPoint(x, y, newheight); -// mTerrain->update(); -// -// } -// if (mKeyboard->isKeyDown(OIS::KC_P)) -// { -// Vector3 tsPos; -// mTerrain->getTerrainPosition(rayResult.second, &tsPos); -// TerrainLayerBlendMap* map = mTerrain->getLayerBlendMap(1); -// size_t imgx, imgy; -// map->convertTerrainToImageSpace(tsPos.x, tsPos.y, &imgx, &imgy); -// -// map->setBlendValue(imgx, imgy, 1); -// map->update(); -// -// } -// mDebugText = str.str(); -// -// } -// else -// { -// mDebugText = "MISS"; -// } -// -// static float updateDelay = 0; -// if (mKeyboard->isKeyDown(OIS::KC_U) && updateDelay <= 0) -// { -// mTerrain->dirty(); -// mTerrain->update(); -// updateDelay = 0.3; -// } -// /* -// if (mKeyboard->isKeyDown(OIS::KC_M) && updateDelay <= 0) -// { -// StringVector texNames; -// texNames.push_back("growth_weirdfungus-03_diffusespecular.dds"); -// texNames.push_back("growth_weirdfungus-03_normalheight.dds"); -// mTerrain->addLayer(500, &texNames); -// updateDelay = 0.3; -// } -// */ -// updateDelay -= evt.timeSinceLastFrame; -// } +// if (mTerrain) +// { +// if (mKeyboard->isKeyDown(OIS::KC_PERIOD)) +// { +// mTerrain->setLayerWorldSize(0, mTerrain->getLayerWorldSize(0) + 100 * evt.timeSinceLastFrame); +// } +// else if (mKeyboard->isKeyDown(OIS::KC_COMMA)) +// { +// mTerrain->setLayerWorldSize(0, mTerrain->getLayerWorldSize(0) - 100 * evt.timeSinceLastFrame); +// } +// +// // fire ray +// Ray ray; +// ray = mCamera->getCameraToViewportRay(0.5, 0.5); +// //ray.setOrigin(mCamera->getDerivedPosition()); +// //ray.setDirection(Vector3::NEGATIVE_UNIT_Y); +// std::pair rayResult = mTerrain->rayIntersects(ray); +// +// static SceneNode* testNode = 0; +// if (!testNode) +// { +// testNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// testNode->attachObject(mSceneMgr->createEntity("tst", "sphere.mesh")); +// testNode->setScale(0.05, 0.05, 0.05); +// } +// if (rayResult.first) +// { +// testNode->setPosition(rayResult.second); +// StringStream str; +// str << "HIT: " << rayResult.second; +// +// +// if (mKeyboard->isKeyDown(OIS::KC_SPACE)) +// { +// Vector3 tsPos; +// mTerrain->getTerrainPosition(rayResult.second, &tsPos); +// +// size_t x = tsPos.x * (mTerrain->getSize()-1); +// size_t y = tsPos.y * (mTerrain->getSize()-1); +// float addedHeight = 250.0 * evt.timeSinceLastFrame; +// float newheight = mTerrain->getHeightAtPoint(x, y) + addedHeight; +// +// mTerrain->setHeightAtPoint(x, y, newheight); +// mTerrain->update(); +// +// } +// if (mKeyboard->isKeyDown(OIS::KC_P)) +// { +// Vector3 tsPos; +// mTerrain->getTerrainPosition(rayResult.second, &tsPos); +// TerrainLayerBlendMap* map = mTerrain->getLayerBlendMap(1); +// size_t imgx, imgy; +// map->convertTerrainToImageSpace(tsPos.x, tsPos.y, &imgx, &imgy); +// +// map->setBlendValue(imgx, imgy, 1); +// map->update(); +// +// } +// mDebugText = str.str(); +// +// } +// else +// { +// mDebugText = "MISS"; +// } +// +// static float updateDelay = 0; +// if (mKeyboard->isKeyDown(OIS::KC_U) && updateDelay <= 0) +// { +// mTerrain->dirty(); +// mTerrain->update(); +// updateDelay = 0.3; +// } +// /* +// if (mKeyboard->isKeyDown(OIS::KC_M) && updateDelay <= 0) +// { +// StringVector texNames; +// texNames.push_back("growth_weirdfungus-03_diffusespecular.dds"); +// texNames.push_back("growth_weirdfungus-03_normalheight.dds"); +// mTerrain->addLayer(500, &texNames); +// updateDelay = 0.3; +// } +// */ +// updateDelay -= evt.timeSinceLastFrame; +// } //#endif // -// return ret; +// return ret; // // } // @@ -452,42 +452,42 @@ extern "C" _OgreSampleExport void dllStopPlugin() // if (timeUntilNextToggle >= 0) // timeUntilNextToggle -= evt.timeSinceLastFrame; // -// static bool mWireframe = false; +// static bool mWireframe = false; //#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS -// if (mKeyboard->isKeyDown(OIS::KC_G) && timeUntilNextToggle <= 0) +// if (mKeyboard->isKeyDown(OIS::KC_G) && timeUntilNextToggle <= 0) // { -// mWireframe = !mWireframe; -// if (mWireframe) -// { -// mCamera->setPolygonMode(PM_WIREFRAME); -// } -// else -// { -// mCamera->setPolygonMode(PM_SOLID); -// } -// timeUntilNextToggle = 0.5; -// -// } -// -// if (mKeyboard->isKeyDown(OIS::KC_MINUS) && timeUntilNextToggle <= 0) -// { -// if (mWindow->isFullScreen()) -// { -// mWindow->setFullscreen(false, 800, 600); -// } -// else -// { -// mWindow->setFullscreen(true, 1024, 768); -// } -// timeUntilNextToggle = 5; -// -// } -// if (mKeyboard->isKeyDown(OIS::KC_EQUALS) && timeUntilNextToggle <= 0) -// { -// mWindow->setFullscreen(true, 800, 600); -// timeUntilNextToggle = 0.5; -// -// } +// mWireframe = !mWireframe; +// if (mWireframe) +// { +// mCamera->setPolygonMode(PM_WIREFRAME); +// } +// else +// { +// mCamera->setPolygonMode(PM_SOLID); +// } +// timeUntilNextToggle = 0.5; +// +// } +// +// if (mKeyboard->isKeyDown(OIS::KC_MINUS) && timeUntilNextToggle <= 0) +// { +// if (mWindow->isFullScreen()) +// { +// mWindow->setFullscreen(false, 800, 600); +// } +// else +// { +// mWindow->setFullscreen(true, 1024, 768); +// } +// timeUntilNextToggle = 5; +// +// } +// if (mKeyboard->isKeyDown(OIS::KC_EQUALS) && timeUntilNextToggle <= 0) +// { +// mWindow->setFullscreen(true, 800, 600); +// timeUntilNextToggle = 0.5; +// +// } //#endif // // @@ -501,25 +501,25 @@ extern "C" _OgreSampleExport void dllStopPlugin() // if (mAnimState && animate) // mAnimState->addTime(evt.timeSinceLastFrame); // -// if (animBlender && animate) -// { -// if (animBlender->getProgress() <= 0.0f) -// { -// animBlender->init(animBlendTarget[animBlendTargetIndex]); -// animBlendTargetIndex = (animBlendTargetIndex + 1) % 2; -// animBlender->blend(animBlendTarget[animBlendTargetIndex], AnimationBlender::BlendWhileAnimating, 10, false); -// } -// else -// { -// animBlender->addTime(evt.timeSinceLastFrame); -// } -// } -// -// vector::type::iterator animi; -// for (animi = mAnimStateList.begin(); animi != mAnimStateList.end(); ++animi) -// { -// (*animi)->addTime(evt.timeSinceLastFrame); -// } +// if (animBlender && animate) +// { +// if (animBlender->getProgress() <= 0.0f) +// { +// animBlender->init(animBlendTarget[animBlendTargetIndex]); +// animBlendTargetIndex = (animBlendTargetIndex + 1) % 2; +// animBlender->blend(animBlendTarget[animBlendTargetIndex], AnimationBlender::BlendWhileAnimating, 10, false); +// } +// else +// { +// animBlender->addTime(evt.timeSinceLastFrame); +// } +// } +// +// vector::type::iterator animi; +// for (animi = mAnimStateList.begin(); animi != mAnimStateList.end(); ++animi) +// { +// (*animi)->addTime(evt.timeSinceLastFrame); +// } // //#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS // if (mKeyboard->isKeyDown(OIS::KC_R) && timeUntilNextToggle <= 0) @@ -536,33 +536,33 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // if (rayQuery) // { -// static set::type lastEnts; -// rayQuery->setRay(mCamera->getCameraToViewportRay(0.5, 0.5)); -// -// // Reset last set -// for (set::type::iterator lasti = lastEnts.begin(); -// lasti != lastEnts.end(); ++lasti) -// { -// (*lasti)->setMaterialName("Examples/OgreLogo"); -// } -// lastEnts.clear(); -// -// -// RaySceneQueryResult& results = rayQuery->execute(); -// for (RaySceneQueryResult::iterator mov = results.begin(); -// mov != results.end(); ++mov) -// { +// static set::type lastEnts; +// rayQuery->setRay(mCamera->getCameraToViewportRay(0.5, 0.5)); +// +// // Reset last set +// for (set::type::iterator lasti = lastEnts.begin(); +// lasti != lastEnts.end(); ++lasti) +// { +// (*lasti)->setMaterialName("Examples/OgreLogo"); +// } +// lastEnts.clear(); +// +// +// RaySceneQueryResult& results = rayQuery->execute(); +// for (RaySceneQueryResult::iterator mov = results.begin(); +// mov != results.end(); ++mov) +// { // if (mov->movable) // { -// if (mov->movable->getMovableType() == "Entity") -// { -// Entity* ent = static_cast(mov->movable); -// lastEnts.insert(ent); -// ent->setMaterialName("Examples/TextureEffect2"); -// -// } +// if (mov->movable->getMovableType() == "Entity") +// { +// Entity* ent = static_cast(mov->movable); +// lastEnts.insert(ent); +// ent->setMaterialName("Examples/TextureEffect2"); +// +// } // } -// } +// } // } // // if (intersectionQuery) @@ -601,7 +601,7 @@ extern "C" _OgreSampleExport void dllStopPlugin() // } // // /* -// if (mKeyboard->isKeyDown(OIS::KC_V) && timeUntilNextToggle <= 0) +// if (mKeyboard->isKeyDown(OIS::KC_V) && timeUntilNextToggle <= 0) // { // static bool isVP = false; // if (!isVP) @@ -615,68 +615,68 @@ extern "C" _OgreSampleExport void dllStopPlugin() // skin->getTechnique(0)->getPass(0)->setVertexProgram(""); // isVP = false; // } -// timeUntilNextToggle = 0.5; +// timeUntilNextToggle = 0.5; // } // */ // //#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS -// if (mKeyboard->isKeyDown(OIS::KC_SPACE)) -// { -// if (testremoveNode) -// { -// if (mRibbonTrail && timeUntilNextToggle <= 0) -// { -// mRibbonTrail->removeNode(testremoveNode); -// timeUntilNextToggle = 1.0f; -// } -// } -// } -// if (mKeyboard->isKeyDown(OIS::KC_0)) -// { -// if (testremoveNode) -// { -// if (mRibbonTrail && timeUntilNextToggle <= 0) -// { -// mRibbonTrail->addNode(testremoveNode); -// timeUntilNextToggle = 1.0f; -// } -// } -// } -// if (mTestNode[0]) -// { -// if (mKeyboard->isKeyDown(OIS::KC_P)) -// { -// mTestNode[0]->yaw(Degree(-evt.timeSinceLastFrame * 30)); -// } -// if (mKeyboard->isKeyDown(OIS::KC_O)) -// { -// mTestNode[0]->yaw(Degree(evt.timeSinceLastFrame * 30)); -// } -// if (mKeyboard->isKeyDown(OIS::KC_K)) -// { -// mTestNode[0]->roll(Degree(-evt.timeSinceLastFrame * 30)); -// } -// if (mKeyboard->isKeyDown(OIS::KC_L)) -// { -// mTestNode[0]->roll(Degree(evt.timeSinceLastFrame * 30)); -// } -// if (mKeyboard->isKeyDown(OIS::KC_U)) -// { -// mTestNode[0]->translate(0,0,-evt.timeSinceLastFrame * 30); -// } -// if (mKeyboard->isKeyDown(OIS::KC_J)) -// { -// mTestNode[0]->translate(0,0,evt.timeSinceLastFrame * 30); -// } -// if (mKeyboard->isKeyDown(OIS::KC_M)) -// { -// mTestNode[0]->translate(0,evt.timeSinceLastFrame * 30, 0); -// } -// if (mKeyboard->isKeyDown(OIS::KC_N)) -// { -// mTestNode[0]->translate(0,-evt.timeSinceLastFrame * 30, 0); -// } -// } +// if (mKeyboard->isKeyDown(OIS::KC_SPACE)) +// { +// if (testremoveNode) +// { +// if (mRibbonTrail && timeUntilNextToggle <= 0) +// { +// mRibbonTrail->removeNode(testremoveNode); +// timeUntilNextToggle = 1.0f; +// } +// } +// } +// if (mKeyboard->isKeyDown(OIS::KC_0)) +// { +// if (testremoveNode) +// { +// if (mRibbonTrail && timeUntilNextToggle <= 0) +// { +// mRibbonTrail->addNode(testremoveNode); +// timeUntilNextToggle = 1.0f; +// } +// } +// } +// if (mTestNode[0]) +// { +// if (mKeyboard->isKeyDown(OIS::KC_P)) +// { +// mTestNode[0]->yaw(Degree(-evt.timeSinceLastFrame * 30)); +// } +// if (mKeyboard->isKeyDown(OIS::KC_O)) +// { +// mTestNode[0]->yaw(Degree(evt.timeSinceLastFrame * 30)); +// } +// if (mKeyboard->isKeyDown(OIS::KC_K)) +// { +// mTestNode[0]->roll(Degree(-evt.timeSinceLastFrame * 30)); +// } +// if (mKeyboard->isKeyDown(OIS::KC_L)) +// { +// mTestNode[0]->roll(Degree(evt.timeSinceLastFrame * 30)); +// } +// if (mKeyboard->isKeyDown(OIS::KC_U)) +// { +// mTestNode[0]->translate(0,0,-evt.timeSinceLastFrame * 30); +// } +// if (mKeyboard->isKeyDown(OIS::KC_J)) +// { +// mTestNode[0]->translate(0,0,evt.timeSinceLastFrame * 30); +// } +// if (mKeyboard->isKeyDown(OIS::KC_M)) +// { +// mTestNode[0]->translate(0,evt.timeSinceLastFrame * 30, 0); +// } +// if (mKeyboard->isKeyDown(OIS::KC_N)) +// { +// mTestNode[0]->translate(0,-evt.timeSinceLastFrame * 30, 0); +// } +// } // // if (mKeyboard->isKeyDown(OIS::KC_0) && timeUntilNextToggle <= 0) // { @@ -684,28 +684,28 @@ extern "C" _OgreSampleExport void dllStopPlugin() // timeUntilNextToggle = 0.5; // } // -// if (mEntity && mKeyboard->isKeyDown(OIS::KC_SPACE) && timeUntilNextToggle <= 0) -// { -// mSceneMgr->destroyEntity(mEntity); -// //mLight->setCastShadows(true); -// mEntity = mSceneMgr->createEntity("newEnt", "robot.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(mEntity); -// mAnimStateList.clear(); -// AnimationState* anim = mEntity->getAnimationState("Walk"); -// anim->setEnabled(true); -// mAnimStateList.push_back(anim); -// } +// if (mEntity && mKeyboard->isKeyDown(OIS::KC_SPACE) && timeUntilNextToggle <= 0) +// { +// mSceneMgr->destroyEntity(mEntity); +// //mLight->setCastShadows(true); +// mEntity = mSceneMgr->createEntity("newEnt", "robot.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(mEntity); +// mAnimStateList.clear(); +// AnimationState* anim = mEntity->getAnimationState("Walk"); +// anim->setEnabled(true); +// mAnimStateList.push_back(anim); +// } // -// if (compositorToSwitch && mKeyboard->isKeyDown(OIS::KC_C) && timeUntilNextToggle <= 0) -// { -// ++compositorSchemeIndex; -// compositorSchemeIndex = compositorSchemeIndex % compositorSchemeList.size(); -// compositorToSwitch->setScheme(compositorSchemeList[compositorSchemeIndex]); -// timeUntilNextToggle = 0.5; -// } +// if (compositorToSwitch && mKeyboard->isKeyDown(OIS::KC_C) && timeUntilNextToggle <= 0) +// { +// ++compositorSchemeIndex; +// compositorSchemeIndex = compositorSchemeIndex % compositorSchemeList.size(); +// compositorToSwitch->setScheme(compositorSchemeList[compositorSchemeIndex]); +// timeUntilNextToggle = 0.5; +// } //#endif // -// /** Hack to test frustum vols +// /** Hack to test frustum vols // if (testCam) // { // // reposition the camera planes @@ -724,34 +724,34 @@ extern "C" _OgreSampleExport void dllStopPlugin() // } // */ // -// if (testUpdateMesh) -// { -// static Real updtimeout = 5.0f; -// updtimeout -= evt.timeSinceLastFrame; +// if (testUpdateMesh) +// { +// static Real updtimeout = 5.0f; +// updtimeout -= evt.timeSinceLastFrame; // -// if (updtimeout < 0) -// { -// // change the mesh, add a new submesh +// if (updtimeout < 0) +// { +// // change the mesh, add a new submesh // -// // Load another mesh -// MeshPtr msh = MeshManager::getSingleton().load("ogrehead.mesh", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// for (unsigned short e = 0; e < msh->getNumSubMeshes(); ++e) -// { -// SubMesh* sm = msh->getSubMesh(e); +// // Load another mesh +// MeshPtr msh = MeshManager::getSingleton().load("ogrehead.mesh", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// for (unsigned short e = 0; e < msh->getNumSubMeshes(); ++e) +// { +// SubMesh* sm = msh->getSubMesh(e); // -// SubMesh* newsm = testUpdateMesh->createSubMesh(); -// newsm->useSharedVertices = false; -// newsm->operationType = sm->operationType; -// newsm->vertexData = sm->vertexData->clone(); -// newsm->indexData = sm->indexData->clone(); -// } +// SubMesh* newsm = testUpdateMesh->createSubMesh(); +// newsm->useSharedVertices = false; +// newsm->operationType = sm->operationType; +// newsm->vertexData = sm->vertexData->clone(); +// newsm->indexData = sm->indexData->clone(); +// } // // -// updtimeout = 100000; +// updtimeout = 100000; // -// } -// } +// } +// } // // // // Print camera details @@ -770,8 +770,8 @@ extern "C" _OgreSampleExport void dllStopPlugin() //protected: // RefractionTextureListener mRefractionListener; // ReflectionTextureListener mReflectionListener; -// StaticPluginLoader mStaticPluginLoader; -// RenderWindowList mRenderWindows; +// StaticPluginLoader mStaticPluginLoader; +// RenderWindowList mRenderWindows; //public: // PlayPenApplication() { // @@ -782,114 +782,114 @@ extern "C" _OgreSampleExport void dllStopPlugin() // { // if (frustum) // delete frustum; -// // Early delete so we can destroy static plugins -// if (mFrameListener) -// { -// delete mFrameListener; -// mFrameListener = 0; -// } -// -// delete mTerrain; -// -// if (mRoot) -// { -// delete mRoot; -// mRoot = 0; -// } +// // Early delete so we can destroy static plugins +// if (mFrameListener) +// { +// delete mFrameListener; +// mFrameListener = 0; +// } +// +// delete mTerrain; +// +// if (mRoot) +// { +// delete mRoot; +// mRoot = 0; +// } //#ifdef OGRE_STATIC_LIB -// mStaticPluginLoader.unload(); +// mStaticPluginLoader.unload(); //#endif // } //protected: // -// bool configure(void) -// { -// bool result; +// bool configure(void) +// { +// bool result; // -// if(mRoot->showConfigDialog()) -// { +// if(mRoot->showConfigDialog()) +// { //#ifdef _MULTIPLE_MONITOR_RENDER_MODE_ -// result = createMultipleRenderWindows(); +// result = createMultipleRenderWindows(); //#else -// // If returned true, user clicked OK so initialise -// // Here we choose to let the system create a default rendering window by passing 'true' -// mWindow = mRoot->initialise(true); -//#endif -// result = true; -// } -// else -// { -// result = false; -// } -// -// return result; -// } -// -// bool createMultipleRenderWindows() -// { -// // Create the main window. -// mWindow = mRoot->initialise(true, "RenderWindow_0"); -// -// // Create the rest of the windows. -// for (unsigned i = 1; i < mRoot->getDisplayMonitorCount(); ++i) -// { -// String strWindowName = "RenderWindow_" + StringConverter::toString(i); -// NameValuePairList nvList; -// -// nvList["monitorIndex"] = StringConverter::toString(i); -// -// RenderWindow* currRenderWindow = mRoot->createRenderWindow(strWindowName, -// mWindow->getWidth(), mWindow->getHeight(), mWindow->isFullScreen(), &nvList); -// -// currRenderWindow->setDeactivateOnFocusChange(false); -// -// mRenderWindows.push_back(currRenderWindow); -// } -// -// return true; -// } -// -// virtual void createCamera(void) -// { -// // Create the camera -// mCamera = mSceneMgr->createCamera("PlayerCam"); -// -// // Position it at 500 in Z direction -// mCamera->setPosition(Vector3(0,0,500)); -// // Look back along -Z -// mCamera->lookAt(Vector3(0,0,-300)); -// mCamera->setNearClipDistance(5); -// -// // Attach the main camera to additional render windows. -// attachCameraToAdditionalRenderWindows(); -// } -// -// -// void attachCameraToAdditionalRenderWindows() -// { -// // Create camera for the secondary render windows. -// for (unsigned int i=0; i < mRenderWindows.size(); ++i) -// { -// RenderWindow* pCurWindow = mRenderWindows[i]; -// -// pCurWindow->addViewport(mCamera); -// } -// } +// // If returned true, user clicked OK so initialise +// // Here we choose to let the system create a default rendering window by passing 'true' +// mWindow = mRoot->initialise(true); +//#endif +// result = true; +// } +// else +// { +// result = false; +// } +// +// return result; +// } +// +// bool createMultipleRenderWindows() +// { +// // Create the main window. +// mWindow = mRoot->initialise(true, "RenderWindow_0"); +// +// // Create the rest of the windows. +// for (unsigned i = 1; i < mRoot->getDisplayMonitorCount(); ++i) +// { +// String strWindowName = "RenderWindow_" + StringConverter::toString(i); +// NameValuePairList nvList; +// +// nvList["monitorIndex"] = StringConverter::toString(i); +// +// RenderWindow* currRenderWindow = mRoot->createRenderWindow(strWindowName, +// mWindow->getWidth(), mWindow->getHeight(), mWindow->isFullScreen(), &nvList); +// +// currRenderWindow->setDeactivateOnFocusChange(false); +// +// mRenderWindows.push_back(currRenderWindow); +// } +// +// return true; +// } +// +// virtual void createCamera(void) +// { +// // Create the camera +// mCamera = mSceneMgr->createCamera("PlayerCam"); +// +// // Position it at 500 in Z direction +// mCamera->setPosition(Vector3(0,0,500)); +// // Look back along -Z +// mCamera->lookAt(Vector3(0,0,-300)); +// mCamera->setNearClipDistance(5); +// +// // Attach the main camera to additional render windows. +// attachCameraToAdditionalRenderWindows(); +// } +// +// +// void attachCameraToAdditionalRenderWindows() +// { +// // Create camera for the secondary render windows. +// for (unsigned int i=0; i < mRenderWindows.size(); ++i) +// { +// RenderWindow* pCurWindow = mRenderWindows[i]; +// +// pCurWindow->addViewport(mCamera); +// } +// } // // void chooseSceneManager(void) // { -// // DefaultSceneManager -// //mSceneMgr = mRoot->createSceneManager("DefaultSceneManager", "PlayPenSMInstance"); +// // DefaultSceneManager +// //mSceneMgr = mRoot->createSceneManager("DefaultSceneManager", "PlayPenSMInstance"); // -// // BspSceneManager -// //mSceneMgr = mRoot->createSceneManager("BspSceneManager", "PlayPenSMInstance"); +// // BspSceneManager +// //mSceneMgr = mRoot->createSceneManager("BspSceneManager", "PlayPenSMInstance"); // -// // OctreeSceneManager -// //mSceneMgr = mRoot->createSceneManager("OctreeSceneManager", "PlayPenSMInstance"); +// // OctreeSceneManager +// //mSceneMgr = mRoot->createSceneManager("OctreeSceneManager", "PlayPenSMInstance"); // -// // TerrainSceneManager -// mSceneMgr = mRoot->createSceneManager("TerrainSceneManager", "PlayPenSMInstance"); -// } +// // TerrainSceneManager +// mSceneMgr = mRoot->createSceneManager("TerrainSceneManager", "PlayPenSMInstance"); +// } // // // void createTestBugPlaneMesh3Streams(const String& testMeshName) @@ -903,7 +903,7 @@ extern "C" _OgreSampleExport void dllStopPlugin() // Real yTile = 1.0f; // const Vector3& upVector = Vector3::UNIT_Y; // MeshPtr pMesh = MeshManager::getSingleton().createManual(testMeshName, -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // SubMesh *pSub = pMesh->createSubMesh(); // // // Set up vertex data @@ -1130,334 +1130,334 @@ extern "C" _OgreSampleExport void dllStopPlugin() // void stressTestStaticGeometry(void) // { // -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); // -// // Create a point light -// Light* l = mSceneMgr->createLight("MainLight"); -// l->setType(Light::LT_DIRECTIONAL); -// Vector3 dir(1, -1, -1.5); -// dir.normalise(); -// l->setDirection(dir); -// l->setDiffuseColour(1.0, 0.7, 0.0); +// // Create a point light +// Light* l = mSceneMgr->createLight("MainLight"); +// l->setType(Light::LT_DIRECTIONAL); +// Vector3 dir(1, -1, -1.5); +// dir.normalise(); +// l->setDirection(dir); +// l->setDiffuseColour(1.0, 0.7, 0.0); // // -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 0; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("Examples/GrassFloor"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 0; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("Examples/GrassFloor"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); // -// Vector3 min(-2000,0,-2000); -// Vector3 max(2000,0,2000); +// Vector3 min(-2000,0,-2000); +// Vector3 max(2000,0,2000); // // -// Entity* e = mSceneMgr->createEntity("1", "ogrehead.mesh"); -// StaticGeometry* s = 0; +// Entity* e = mSceneMgr->createEntity("1", "ogrehead.mesh"); +// StaticGeometry* s = 0; // -// unsigned int count = 10; -// while(count--) -// { -// if(s) mSceneMgr->destroyStaticGeometry(s); -// s = mSceneMgr->createStaticGeometry("bing"); +// unsigned int count = 10; +// while(count--) +// { +// if(s) mSceneMgr->destroyStaticGeometry(s); +// s = mSceneMgr->createStaticGeometry("bing"); // -// s->addEntity(e, Vector3(100, 100, 100)); +// s->addEntity(e, Vector3(100, 100, 100)); // -// s->build(); -// } +// s->build(); +// } // // -// //s->setRenderingDistance(1000); -// //s->dump("static.txt"); -// //mSceneMgr->showBoundingBoxes(true); -// mCamera->setLodBias(0.5); +// //s->setRenderingDistance(1000); +// //s->dump("static.txt"); +// //mSceneMgr->showBoundingBoxes(true); +// mCamera->setLodBias(0.5); // // // } // -// void testManualBlend() -// { -// // create material -// MaterialPtr mat = MaterialManager::getSingleton().create("TestMat", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass * p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->createTextureUnitState("Dirt.jpg"); -// TextureUnitState* t = p->createTextureUnitState("PoolFloorLightingMap.png"); -// t->setColourOperationEx(LBX_BLEND_MANUAL, LBS_TEXTURE, LBS_CURRENT, -// ColourValue::White, ColourValue::White, 0.75); -// -// Entity *planeEnt = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(planeEnt); -// planeEnt->setMaterialName("TestManual"); -// -// -// -// } -// -// class TestManualLoader : public ManualResourceLoader -// { -// public: -// void loadResource(Resource* resource) -// { -// resource->_dirtyState(); -// } -// -// }; -// void testManualLoader() -// { -// TestManualLoader loader; -// MeshPtr msh = MeshManager::getSingleton().createManual("test", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, &loader); -// -// msh->load(); -// -// } -// -// void testProjectSphere() -// { -// mSceneMgr->setAmbientLight(ColourValue::White); -// -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 0; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("Examples/GrassFloor"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// projectionSphere = new Sphere(Vector3(0, 2000, 0), 1500.0); -// -// ManualObject* debugSphere = mSceneMgr->createManualObject("debugSphere"); -// debugSphere->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); -// for (int i = 0; i <= 20; ++i) -// { -// Vector3 basePos(projectionSphere->getRadius(), 0, 0); -// Quaternion quat; -// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y); -// basePos = quat * basePos; -// debugSphere->position(basePos); -// } -// for (int i = 0; i <= 20; ++i) -// { -// Vector3 basePos(projectionSphere->getRadius(), 0, 0); -// Quaternion quat; -// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Z); -// basePos = quat * basePos; -// debugSphere->position(basePos); -// } -// debugSphere->end(); -// -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,2000,0))->attachObject(debugSphere); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("scissormat", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setDepthWriteEnabled(false); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// TextureUnitState* t = p->createTextureUnitState(); -// t->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, -// ColourValue::Red); -// t->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f); -// -// -// -// scissorRect = mSceneMgr->createManualObject("scissorrect"); -// scissorRect->setUseIdentityProjection(true); -// scissorRect->setUseIdentityView(true); -// AxisAlignedBox aabb; -// aabb.setInfinite(); -// scissorRect->setBoundingBox(aabb); -// scissorRect->begin(mat->getName()); -// scissorRect->position(Vector3::ZERO); -// scissorRect->position(Vector3::ZERO); -// scissorRect->position(Vector3::ZERO); -// scissorRect->quad(0, 1, 2, 3); -// scissorRect->end(); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(scissorRect); -// -// -// -// -// } -// // Basically a copy of OSMAnimSerializer from oSceneLoaderLib -// class AnimSerializer : public Ogre::Serializer -// { -// public: -// AnimSerializer() -// { -// mVersion = "[oFusion_Serializer_v1.0]"; -// } -// -// void addAnimation(Ogre::Skeleton* skeleton, Ogre::DataStreamPtr& stream) -// { -// Ogre::SkeletonSerializer serializer; -// -// // Check header -// readFileHeader(stream); -// -// Ogre::uint16 numBones; -// -// // Read number of bones needed for this animation -// readShorts(stream, &numBones, 1); -// -// if( numBones != skeleton->getNumBones() ) -// { -// OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, -// "Animation not valid for skeleton: " + skeleton->getName(), -// "AnimSerializer::addAnimation"); -// } -// -// // Workaround the oFusion file-in-file problem: -// // http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=3018 -// // we just chop off the first file part. -// Ogre::DataStreamPtr memStream(new Ogre::MemoryDataStream(stream)); -// serializer.importSkeleton(memStream, skeleton); -// } -// }; -// -// void testMRTCompositorScript() -// { -// -// Entity* e = mSceneMgr->createEntity("e1", "knot.mesh"); -// e->setMaterialName("Ogre/MRTtest/scene"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mCamera->setPosition(0, 0, -100); -// mCamera->lookAt(Vector3::ZERO); -// -// CompositorInstance* compInst = -// CompositorManager::getSingleton().addCompositor(mWindow->getViewport(0), "TestMRT"); -// CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), "TestMRT", true); -// -// // Set up debug panels for each of the MRT outputs -// String texName = compInst->getTextureInstanceName("mrt0", 0); -// addTextureDebugOverlay(TextureManager::getSingleton().getByName(texName), 0); -// texName = compInst->getTextureInstanceName("mrt0", 1); -// addTextureDebugOverlay(TextureManager::getSingleton().getByName(texName), 1); -// texName = compInst->getTextureInstanceName("mrt0", 2); -// addTextureDebugOverlay(TextureManager::getSingleton().getByName(texName), 2); -// texName = compInst->getTextureInstanceName("mrt0", 3); -// addTextureDebugOverlay(TextureManager::getSingleton().getByName(texName), 3); -// } -// -// void testNormalMapMirroredUVs() -// { -// -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// // this mesh has been generated with 4-component tangents, including a parity in w -// Entity* e = mSceneMgr->createEntity("2", "testmirroreduvmesh.mesh"); -// e->setMaterialName("Examples/BumpMapping/MultiLightTangentParity"); -// // here's what it looks like without the parity -// //e->setMaterialName("Examples/BumpMapping/MultiLight"); -// -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// -// Light* l = mSceneMgr->createLight("3"); -// l->setPosition(1000,500,1000); -// -// mCamera->setPosition(0,200,50); -// mCamera->lookAt(Vector3::ZERO); -// -// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); -// } -// -// void testMaterialSerializer() -// { -// MaterialSerializer ser; -// -// // simple material -// MaterialPtr m = MaterialManager::getSingleton().getByName("Examples/EnvMappedRustySteel"); -// ser.queueForExport(m); -// -// // scheme-based but otherwise simple material -// m = MaterialManager::getSingleton().getByName("Examples/MorningSkyBox"); -// ser.queueForExport(m); -// -// // fairly simple shader, with custom param & default params -// m = MaterialManager::getSingleton().getByName("Examples/CelShading"); -// ser.queueForExport(m); -// -// // More complex shader -// m = MaterialManager::getSingleton().getByName("Examples/BumpMapping/SingleLight"); -// ser.queueForExport(m); -// -// // more complex shader, with light iteration -// m = MaterialManager::getSingleton().getByName("Examples/BumpMapping/MultiLight"); -// ser.queueForExport(m); -// -// // With a unified program -// m = MaterialManager::getSingleton().getByName("jaiqua"); -// ser.queueForExport(m); -// -// -// // export -// ser.exportQueued("testexport.material", true); -// -// -// -// -// } -// -// void testTransparencyMipMaps() -// { -// MaterialPtr mat = MaterialManager::getSingleton().create("test", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// // known png with alpha -// Pass* pass = mat->getTechnique(0)->getPass(0); -// pass->createTextureUnitState("ogretext.png"); -// pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// // alpha blend -// pass->setDepthWriteEnabled(false); -// -// // alpha reject -// //pass->setDepthWriteEnabled(true); -// //pass->setAlphaRejectSettings(CMPF_LESS, 128); -// -// // Define a floor plane mesh -// Plane p; -// p.normal = Vector3::UNIT_Y; -// p.d = 200; -// MeshManager::getSingleton().createPlane("FloorPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Z); -// -// // Create an entity (the floor) -// Entity* ent = mSceneMgr->createEntity("floor", "FloorPlane"); -// ent->setMaterialName("test"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// -// mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8); -// mSceneMgr->setAmbientLight(ColourValue::White); -// -// -// { -// -// Real alphaLevel = 0.5f; -// MaterialPtr alphamat = MaterialManager::getSingleton().create("testy", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* pass = alphamat->getTechnique(0)->getPass(0); -// pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// pass->setDepthWriteEnabled(false); -// TextureUnitState* t = pass->createTextureUnitState(); -// t->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, alphaLevel); -// -// ent = mSceneMgr->createEntity("asd", "ogrehead.mesh"); -// ent->setMaterialName("testy"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// -// } -// -// } +// void testManualBlend() +// { +// // create material +// MaterialPtr mat = MaterialManager::getSingleton().create("TestMat", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass * p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->createTextureUnitState("Dirt.jpg"); +// TextureUnitState* t = p->createTextureUnitState("PoolFloorLightingMap.png"); +// t->setColourOperationEx(LBX_BLEND_MANUAL, LBS_TEXTURE, LBS_CURRENT, +// ColourValue::White, ColourValue::White, 0.75); +// +// Entity *planeEnt = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(planeEnt); +// planeEnt->setMaterialName("TestManual"); +// +// +// +// } +// +// class TestManualLoader : public ManualResourceLoader +// { +// public: +// void loadResource(Resource* resource) +// { +// resource->_dirtyState(); +// } +// +// }; +// void testManualLoader() +// { +// TestManualLoader loader; +// MeshPtr msh = MeshManager::getSingleton().createManual("test", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, &loader); +// +// msh->load(); +// +// } +// +// void testProjectSphere() +// { +// mSceneMgr->setAmbientLight(ColourValue::White); +// +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 0; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("Examples/GrassFloor"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// projectionSphere = new Sphere(Vector3(0, 2000, 0), 1500.0); +// +// ManualObject* debugSphere = mSceneMgr->createManualObject("debugSphere"); +// debugSphere->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); +// for (int i = 0; i <= 20; ++i) +// { +// Vector3 basePos(projectionSphere->getRadius(), 0, 0); +// Quaternion quat; +// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y); +// basePos = quat * basePos; +// debugSphere->position(basePos); +// } +// for (int i = 0; i <= 20; ++i) +// { +// Vector3 basePos(projectionSphere->getRadius(), 0, 0); +// Quaternion quat; +// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Z); +// basePos = quat * basePos; +// debugSphere->position(basePos); +// } +// debugSphere->end(); +// +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,2000,0))->attachObject(debugSphere); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("scissormat", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setDepthWriteEnabled(false); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// TextureUnitState* t = p->createTextureUnitState(); +// t->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, +// ColourValue::Red); +// t->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f); +// +// +// +// scissorRect = mSceneMgr->createManualObject("scissorrect"); +// scissorRect->setUseIdentityProjection(true); +// scissorRect->setUseIdentityView(true); +// AxisAlignedBox aabb; +// aabb.setInfinite(); +// scissorRect->setBoundingBox(aabb); +// scissorRect->begin(mat->getName()); +// scissorRect->position(Vector3::ZERO); +// scissorRect->position(Vector3::ZERO); +// scissorRect->position(Vector3::ZERO); +// scissorRect->quad(0, 1, 2, 3); +// scissorRect->end(); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(scissorRect); +// +// +// +// +// } +// // Basically a copy of OSMAnimSerializer from oSceneLoaderLib +// class AnimSerializer : public Ogre::Serializer +// { +// public: +// AnimSerializer() +// { +// mVersion = "[oFusion_Serializer_v1.0]"; +// } +// +// void addAnimation(Ogre::Skeleton* skeleton, Ogre::DataStreamPtr& stream) +// { +// Ogre::SkeletonSerializer serializer; +// +// // Check header +// readFileHeader(stream); +// +// Ogre::uint16 numBones; +// +// // Read number of bones needed for this animation +// readShorts(stream, &numBones, 1); +// +// if( numBones != skeleton->getNumBones() ) +// { +// OGRE_EXCEPT(Ogre::Exception::ERR_RT_ASSERTION_FAILED, +// "Animation not valid for skeleton: " + skeleton->getName(), +// "AnimSerializer::addAnimation"); +// } +// +// // Workaround the oFusion file-in-file problem: +// // http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=3018 +// // we just chop off the first file part. +// Ogre::DataStreamPtr memStream(new Ogre::MemoryDataStream(stream)); +// serializer.importSkeleton(memStream, skeleton); +// } +// }; +// +// void testMRTCompositorScript() +// { +// +// Entity* e = mSceneMgr->createEntity("e1", "knot.mesh"); +// e->setMaterialName("Ogre/MRTtest/scene"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mCamera->setPosition(0, 0, -100); +// mCamera->lookAt(Vector3::ZERO); +// +// CompositorInstance* compInst = +// CompositorManager::getSingleton().addCompositor(mWindow->getViewport(0), "TestMRT"); +// CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0), "TestMRT", true); +// +// // Set up debug panels for each of the MRT outputs +// String texName = compInst->getTextureInstanceName("mrt0", 0); +// addTextureDebugOverlay(TextureManager::getSingleton().getByName(texName), 0); +// texName = compInst->getTextureInstanceName("mrt0", 1); +// addTextureDebugOverlay(TextureManager::getSingleton().getByName(texName), 1); +// texName = compInst->getTextureInstanceName("mrt0", 2); +// addTextureDebugOverlay(TextureManager::getSingleton().getByName(texName), 2); +// texName = compInst->getTextureInstanceName("mrt0", 3); +// addTextureDebugOverlay(TextureManager::getSingleton().getByName(texName), 3); +// } +// +// void testNormalMapMirroredUVs() +// { +// +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// // this mesh has been generated with 4-component tangents, including a parity in w +// Entity* e = mSceneMgr->createEntity("2", "testmirroreduvmesh.mesh"); +// e->setMaterialName("Examples/BumpMapping/MultiLightTangentParity"); +// // here's what it looks like without the parity +// //e->setMaterialName("Examples/BumpMapping/MultiLight"); +// +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// +// Light* l = mSceneMgr->createLight("3"); +// l->setPosition(1000,500,1000); +// +// mCamera->setPosition(0,200,50); +// mCamera->lookAt(Vector3::ZERO); +// +// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); +// } +// +// void testMaterialSerializer() +// { +// MaterialSerializer ser; +// +// // simple material +// MaterialPtr m = MaterialManager::getSingleton().getByName("Examples/EnvMappedRustySteel"); +// ser.queueForExport(m); +// +// // scheme-based but otherwise simple material +// m = MaterialManager::getSingleton().getByName("Examples/MorningSkyBox"); +// ser.queueForExport(m); +// +// // fairly simple shader, with custom param & default params +// m = MaterialManager::getSingleton().getByName("Examples/CelShading"); +// ser.queueForExport(m); +// +// // More complex shader +// m = MaterialManager::getSingleton().getByName("Examples/BumpMapping/SingleLight"); +// ser.queueForExport(m); +// +// // more complex shader, with light iteration +// m = MaterialManager::getSingleton().getByName("Examples/BumpMapping/MultiLight"); +// ser.queueForExport(m); +// +// // With a unified program +// m = MaterialManager::getSingleton().getByName("jaiqua"); +// ser.queueForExport(m); +// +// +// // export +// ser.exportQueued("testexport.material", true); +// +// +// +// +// } +// +// void testTransparencyMipMaps() +// { +// MaterialPtr mat = MaterialManager::getSingleton().create("test", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// // known png with alpha +// Pass* pass = mat->getTechnique(0)->getPass(0); +// pass->createTextureUnitState("ogretext.png"); +// pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// // alpha blend +// pass->setDepthWriteEnabled(false); +// +// // alpha reject +// //pass->setDepthWriteEnabled(true); +// //pass->setAlphaRejectSettings(CMPF_LESS, 128); +// +// // Define a floor plane mesh +// Plane p; +// p.normal = Vector3::UNIT_Y; +// p.d = 200; +// MeshManager::getSingleton().createPlane("FloorPlane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Z); +// +// // Create an entity (the floor) +// Entity* ent = mSceneMgr->createEntity("floor", "FloorPlane"); +// ent->setMaterialName("test"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// +// mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8); +// mSceneMgr->setAmbientLight(ColourValue::White); +// +// +// { +// +// Real alphaLevel = 0.5f; +// MaterialPtr alphamat = MaterialManager::getSingleton().create("testy", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* pass = alphamat->getTechnique(0)->getPass(0); +// pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// pass->setDepthWriteEnabled(false); +// TextureUnitState* t = pass->createTextureUnitState(); +// t->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, alphaLevel); +// +// ent = mSceneMgr->createEntity("asd", "ogrehead.mesh"); +// ent->setMaterialName("testy"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// +// } +// +// } // // void testCthNewBlending(void) // { @@ -1497,8 +1497,8 @@ extern "C" _OgreSampleExport void dllStopPlugin() // p.normal = Vector3::UNIT_Y; // p.d = 200; // MeshManager::getSingleton().createPlane("FloorPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Z); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Z); // // // Create an entity (the floor) // ent = mSceneMgr->createEntity("floor", "FloorPlane"); @@ -1551,8 +1551,8 @@ extern "C" _OgreSampleExport void dllStopPlugin() // p.normal = Vector3::UNIT_Y; // p.d = 200; // MeshManager::getSingleton().createPlane("FloorPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Z); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Z); // // // Create an entity (the floor) // ent = mSceneMgr->createEntity("floor", "FloorPlane"); @@ -1561,8 +1561,8 @@ extern "C" _OgreSampleExport void dllStopPlugin() // mSceneMgr->getRootSceneNode()->attachObject(ent); // // Entity* sphereEnt = mSceneMgr->createEntity("ogre", "ogrehead.mesh"); -// -// mRootNode = mSceneMgr->getRootSceneNode(); +// +// mRootNode = mSceneMgr->getRootSceneNode(); // SceneNode* node = mSceneMgr->createSceneNode(); // node->attachObject(sphereEnt); // mRootNode->addChild(node); @@ -1591,14 +1591,14 @@ extern "C" _OgreSampleExport void dllStopPlugin() // p.normal = Vector3::UNIT_Y; // p.d = 200; // MeshManager::getSingleton().createPlane("FloorPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Z); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Z); // // p.normal = Vector3::UNIT_Z; // p.d = 200; // MeshManager::getSingleton().createPlane("WallPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Y); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// p,2000,2000,1,1,true,1,5,5,Vector3::UNIT_Y); // // // Create an entity (the floor) // ent = mSceneMgr->createEntity("floor", "FloorPlane"); @@ -1613,8 +1613,8 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // // Entity* sphereEnt = mSceneMgr->createEntity("ogre", "ogrehead.mesh"); -// -// mRootNode = mSceneMgr->getRootSceneNode(); +// +// mRootNode = mSceneMgr->getRootSceneNode(); // SceneNode* node = mSceneMgr->createSceneNode(); // node->attachObject(sphereEnt); // mRootNode->addChild(node); @@ -1632,7 +1632,7 @@ extern "C" _OgreSampleExport void dllStopPlugin() // String quakePk3 = cf.getSetting("Pak0Location"); // String quakeLevel = cf.getSetting("Map"); // -// ResourceGroupManager::getSingleton().addResourceLocation(quakePk3, "Zip"); +// ResourceGroupManager::getSingleton().addResourceLocation(quakePk3, "Zip"); // // // // Load world geometry @@ -1677,39 +1677,39 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // } // -// void testAnimationBlend() -// { -// Light* l = mSceneMgr->createLight("MainLight"); -// l->setPosition(200,110,0); -// l->setType(Light::LT_POINT); -// Entity *ent; +// void testAnimationBlend() +// { +// Light* l = mSceneMgr->createLight("MainLight"); +// l->setPosition(200,110,0); +// l->setType(Light::LT_POINT); +// Entity *ent; // -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); // -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.4)); +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.4)); // -// // Create an entity (the plant) -// ent = mSceneMgr->createEntity("1", "sticky.mesh"); +// // Create an entity (the plant) +// ent = mSceneMgr->createEntity("1", "sticky.mesh"); // -// SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// node->attachObject(ent); -// node->scale(2,2,2); +// SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// node->attachObject(ent); +// node->scale(2,2,2); // -// //mAnimState = ent->getAnimationState("triangle"); -// //mAnimState->setEnabled(true); +// //mAnimState = ent->getAnimationState("triangle"); +// //mAnimState->setEnabled(true); // -// animBlender = new AnimationBlender(ent); -// animBlendTarget[0] = "still"; -// animBlendTarget[1] = "triangle"; -// animBlendTargetIndex = 1; -// animBlender->init(animBlendTarget[0]); -// animBlender->blend(animBlendTarget[1], AnimationBlender::BlendWhileAnimating, 10, false); +// animBlender = new AnimationBlender(ent); +// animBlendTarget[0] = "still"; +// animBlendTarget[1] = "triangle"; +// animBlendTargetIndex = 1; +// animBlender->init(animBlendTarget[0]); +// animBlender->blend(animBlendTarget[1], AnimationBlender::BlendWhileAnimating, 10, false); // -// mCamera->setPosition(-50,0,0); -// mCamera->lookAt(0,0,0); +// mCamera->setPosition(-50,0,0); +// mCamera->lookAt(0,0,0); // // -// } +// } // // void testGpuPrograms(void) // { @@ -1756,8 +1756,8 @@ extern "C" _OgreSampleExport void dllStopPlugin() // p.normal = Vector3::UNIT_Z; // p.d = 200; // MeshManager::getSingleton().createPlane("WallPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// p,1500,1500,1,1,true,1,5,5,Vector3::UNIT_Y); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// p,1500,1500,1,1,true,1,5,5,Vector3::UNIT_Y); // pEnt = mSceneMgr->createEntity( "5", "WallPlane" ); // pEnt->setMaterialName("Examples/OgreLogo"); // mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pEnt); @@ -1841,8 +1841,8 @@ extern "C" _OgreSampleExport void dllStopPlugin() // p.normal = Vector3::UNIT_Y; // p.d = 200; // MeshManager::getSingleton().createPlane("FloorPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// p,200000,200000,20,20,true,1,50,50,Vector3::UNIT_Z); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// p,200000,200000,20,20,true,1,50,50,Vector3::UNIT_Z); // // // Create an entity (the floor) // ent = mSceneMgr->createEntity("floor", "FloorPlane"); @@ -1920,9 +1920,9 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // Entity* pEnt; // -// TexturePtr rttTex = TextureManager::getSingleton().createManual("Refraction", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, -// 512, 512, 1, 0, PF_R8G8B8, TU_RENDERTARGET); +// TexturePtr rttTex = TextureManager::getSingleton().createManual("Refraction", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, +// 512, 512, 1, 0, PF_R8G8B8, TU_RENDERTARGET); // { // Viewport *v = rttTex->getBuffer()->getRenderTarget()->addViewport( mCamera ); // MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction"); @@ -1931,9 +1931,9 @@ extern "C" _OgreSampleExport void dllStopPlugin() // rttTex->getBuffer()->getRenderTarget()->addListener(&mRefractionListener); // } // -// rttTex = TextureManager::getSingleton().createManual("Reflection", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, -// 512, 512, 1, 0, PF_R8G8B8, TU_RENDERTARGET); +// rttTex = TextureManager::getSingleton().createManual("Reflection", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, +// 512, 512, 1, 0, PF_R8G8B8, TU_RENDERTARGET); // { // Viewport *v = rttTex->getBuffer()->getRenderTarget()->addViewport( mCamera ); // MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction"); @@ -1946,8 +1946,8 @@ extern "C" _OgreSampleExport void dllStopPlugin() // p.normal = Vector3::UNIT_Y; // p.d = 100; // MeshManager::getSingleton().createPlane("WallPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// p,1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// p,1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); // pPlaneEnt = mSceneMgr->createEntity( "5", "WallPlane" ); // pPlaneEnt->setMaterialName("Examples/FresnelReflectionRefraction"); // mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); @@ -2200,7 +2200,7 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // // Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); -// //ent->setDisplaySkeleton(true); +// //ent->setDisplaySkeleton(true); // // Uncomment the below to test software skinning // ent->setMaterialName("Examples/Rocky"); // // Add entity to the scene node @@ -2225,11 +2225,11 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // Report whether hardware skinning is enabled or not // Technique* t = ent->getSubEntity(0)->getTechnique(); // Pass* p = t->getPass(0); -// OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); +// OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText"); // if (p->hasVertexProgram() && // p->getVertexProgram()->isSkeletalAnimationIncluded()) // { -// guiDbg->setCaption("Hardware skinning is enabled"); +// guiDbg->setCaption("Hardware skinning is enabled"); // } // else // { @@ -2304,22 +2304,22 @@ extern "C" _OgreSampleExport void dllStopPlugin() // for (int i = 0; i < 12; ++i) // { // ent = mSceneMgr->createEntity("robot" + StringConverter::toString(i), "robot.mesh"); -// if (i % 2) -// { -// Entity* ent2 = mSceneMgr->createEntity("plane" + StringConverter::toString(i), "razor.mesh"); -// ent->attachObjectToBone("Joint8", ent2); -// } -// else -// { -// ParticleSystem* psys = mSceneMgr->createParticleSystem("psys" + StringConverter::toString(i), "Examples/PurpleFountain"); -// psys->getEmitter(0)->setTimeToLive(0.2); -// ent->attachObjectToBone("Joint15", psys); -// } +// if (i % 2) +// { +// Entity* ent2 = mSceneMgr->createEntity("plane" + StringConverter::toString(i), "razor.mesh"); +// ent->attachObjectToBone("Joint8", ent2); +// } +// else +// { +// ParticleSystem* psys = mSceneMgr->createParticleSystem("psys" + StringConverter::toString(i), "Examples/PurpleFountain"); +// psys->getEmitter(0)->setTimeToLive(0.2); +// ent->attachObjectToBone("Joint15", psys); +// } // // Add entity to the scene node // mSceneMgr->getRootSceneNode()->createChildSceneNode( // Vector3(0,0,(i*200)-(12*200/2)))->attachObject(ent); // -// ent->getParentNode()->yaw(Degree(i * 45)); +// ent->getParentNode()->yaw(Degree(i * 45)); // } // mAnimState = ent->getAnimationState("Walk"); // mAnimState->setEnabled(true); @@ -2372,7 +2372,7 @@ extern "C" _OgreSampleExport void dllStopPlugin() // plane.normal = Vector3::UNIT_Y; // plane.d = 100; // MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, // 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); // Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); // pPlaneEnt->setMaterialName("2 - Default"); @@ -2387,127 +2387,127 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // } // -// void testManualLOD() -// { -// MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// void testManualLOD() +// { +// MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // // msh1->createManualLodLevel(Math::Sqr(200), "razor.mesh"); -// msh1->createManualLodLevel(Math::Sqr(500), "sphere.mesh"); -// -// Entity *ent; -// for (int i = 0; i < 5; ++i) -// { -// ent = mSceneMgr->createEntity("robot" + StringConverter::toString(i), "robot.mesh"); -// // Add entity to the scene node -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(0,0,(i*50)-(5*50/2)))->attachObject(ent); -// } -// mAnimState = ent->getAnimationState("Walk"); -// mAnimState->setEnabled(true); -// -// -// -// // Give it a little ambience with lights -// Light* l; -// l = mSceneMgr->createLight("BlueLight"); -// l->setPosition(-200,-80,-100); -// l->setDiffuseColour(0.5, 0.5, 1.0); -// -// l = mSceneMgr->createLight("GreenLight"); -// l->setPosition(0,0,-100); -// l->setDiffuseColour(0.5, 1.0, 0.5); -// -// // Position the camera -// mCamera->setPosition(100,50,100); -// mCamera->lookAt(-50,50,0); -// -// mSceneMgr->setAmbientLight(ColourValue::White); -// -// } -// -// void testFallbackResourceGroup() -// { -// // Load all textures from new resource group "Test" -// ResourceGroupManager::getSingleton().removeResourceLocation("../../../Media/materials/textures"); -// ResourceGroupManager::getSingleton().removeResourceLocation("../../../Media/models"); -// ResourceGroupManager::getSingleton().createResourceGroup("Test"); -// ResourceGroupManager::getSingleton().addResourceLocation("../../../Media/materials/textures", "FileSystem", "Test"); -// ResourceGroupManager::getSingleton().addResourceLocation("../../../Media/models", "FileSystem", "Test"); -// -// // Load a texture from default group (won't be found there, but should fall back) -// TextureManager::getSingleton().load("dirt01.jpg", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// -// ResourceGroupManager::getSingleton().unloadUnreferencedResourcesInGroup("Test"); -// -// // Add a few robots for fun -// Entity *ent; -// for (int i = 0; i < 5; ++i) -// { -// ent = mSceneMgr->createEntity("robot" + StringConverter::toString(i), "robot.mesh"); -// // Add entity to the scene node -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(0,0,(i*50)-(5*50/2)))->attachObject(ent); -// } -// // Give it a little ambience with lights -// Light* l; -// l = mSceneMgr->createLight("BlueLight"); -// l->setPosition(-200,-80,-100); -// l->setDiffuseColour(0.5, 0.5, 1.0); -// -// l = mSceneMgr->createLight("GreenLight"); -// l->setPosition(0,0,-100); -// l->setDiffuseColour(0.5, 1.0, 0.5); -// -// // Position the camera -// mCamera->setPosition(100,50,100); -// mCamera->lookAt(-50,50,0); -// -// } -// -// void testGeneratedLOD() -// { -// MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("barrel.mesh", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// -// msh1->removeLodLevels(); -// -// Mesh::LodValueList lodList; +// msh1->createManualLodLevel(Math::Sqr(500), "sphere.mesh"); +// +// Entity *ent; +// for (int i = 0; i < 5; ++i) +// { +// ent = mSceneMgr->createEntity("robot" + StringConverter::toString(i), "robot.mesh"); +// // Add entity to the scene node +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(0,0,(i*50)-(5*50/2)))->attachObject(ent); +// } +// mAnimState = ent->getAnimationState("Walk"); +// mAnimState->setEnabled(true); +// +// +// +// // Give it a little ambience with lights +// Light* l; +// l = mSceneMgr->createLight("BlueLight"); +// l->setPosition(-200,-80,-100); +// l->setDiffuseColour(0.5, 0.5, 1.0); +// +// l = mSceneMgr->createLight("GreenLight"); +// l->setPosition(0,0,-100); +// l->setDiffuseColour(0.5, 1.0, 0.5); +// +// // Position the camera +// mCamera->setPosition(100,50,100); +// mCamera->lookAt(-50,50,0); +// +// mSceneMgr->setAmbientLight(ColourValue::White); +// +// } +// +// void testFallbackResourceGroup() +// { +// // Load all textures from new resource group "Test" +// ResourceGroupManager::getSingleton().removeResourceLocation("../../../Media/materials/textures"); +// ResourceGroupManager::getSingleton().removeResourceLocation("../../../Media/models"); +// ResourceGroupManager::getSingleton().createResourceGroup("Test"); +// ResourceGroupManager::getSingleton().addResourceLocation("../../../Media/materials/textures", "FileSystem", "Test"); +// ResourceGroupManager::getSingleton().addResourceLocation("../../../Media/models", "FileSystem", "Test"); +// +// // Load a texture from default group (won't be found there, but should fall back) +// TextureManager::getSingleton().load("dirt01.jpg", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// +// ResourceGroupManager::getSingleton().unloadUnreferencedResourcesInGroup("Test"); +// +// // Add a few robots for fun +// Entity *ent; +// for (int i = 0; i < 5; ++i) +// { +// ent = mSceneMgr->createEntity("robot" + StringConverter::toString(i), "robot.mesh"); +// // Add entity to the scene node +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(0,0,(i*50)-(5*50/2)))->attachObject(ent); +// } +// // Give it a little ambience with lights +// Light* l; +// l = mSceneMgr->createLight("BlueLight"); +// l->setPosition(-200,-80,-100); +// l->setDiffuseColour(0.5, 0.5, 1.0); +// +// l = mSceneMgr->createLight("GreenLight"); +// l->setPosition(0,0,-100); +// l->setDiffuseColour(0.5, 1.0, 0.5); +// +// // Position the camera +// mCamera->setPosition(100,50,100); +// mCamera->lookAt(-50,50,0); +// +// } +// +// void testGeneratedLOD() +// { +// MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("barrel.mesh", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// +// msh1->removeLodLevels(); +// +// Mesh::LodValueList lodList; // lodList.push_back(Math::Sqr(50)); -// lodList.push_back(Math::Sqr(100)); -// lodList.push_back(Math::Sqr(150)); -// lodList.push_back(Math::Sqr(200)); -// lodList.push_back(Math::Sqr(250)); -// lodList.push_back(Math::Sqr(300)); +// lodList.push_back(Math::Sqr(100)); +// lodList.push_back(Math::Sqr(150)); +// lodList.push_back(Math::Sqr(200)); +// lodList.push_back(Math::Sqr(250)); +// lodList.push_back(Math::Sqr(300)); // -// msh1->generateLodLevels(lodList, ProgressiveMesh::VRQ_PROPORTIONAL, 0.3); +// msh1->generateLodLevels(lodList, ProgressiveMesh::VRQ_PROPORTIONAL, 0.3); // -// Entity *ent; -// for (int i = 0; i < 1; ++i) -// { -// ent = mSceneMgr->createEntity("tst" + StringConverter::toString(i), "barrel.mesh"); -// // Add entity to the scene node -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(0,0,(i*50)-(5*50/2)))->attachObject(ent); -// } +// Entity *ent; +// for (int i = 0; i < 1; ++i) +// { +// ent = mSceneMgr->createEntity("tst" + StringConverter::toString(i), "barrel.mesh"); +// // Add entity to the scene node +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(0,0,(i*50)-(5*50/2)))->attachObject(ent); +// } // -// // Give it a little ambience with lights -// Light* l; -// l = mSceneMgr->createLight("BlueLight"); -// l->setPosition(-200,-80,-100); -// l->setDiffuseColour(0.5, 0.5, 1.0); +// // Give it a little ambience with lights +// Light* l; +// l = mSceneMgr->createLight("BlueLight"); +// l->setPosition(-200,-80,-100); +// l->setDiffuseColour(0.5, 0.5, 1.0); // -// l = mSceneMgr->createLight("GreenLight"); -// l->setPosition(0,0,-100); -// l->setDiffuseColour(0.5, 1.0, 0.5); +// l = mSceneMgr->createLight("GreenLight"); +// l->setPosition(0,0,-100); +// l->setDiffuseColour(0.5, 1.0, 0.5); // -// // Position the camera -// mCamera->setPosition(100,50,100); -// mCamera->lookAt(-50,50,0); +// // Position the camera +// mCamera->setPosition(100,50,100); +// mCamera->lookAt(-50,50,0); // -// mSceneMgr->setAmbientLight(ColourValue::White); +// mSceneMgr->setAmbientLight(ColourValue::White); // -// } +// } // // void clearSceneSetup() // { @@ -2619,8 +2619,8 @@ extern "C" _OgreSampleExport void dllStopPlugin() // p.normal = Vector3::UNIT_Y; // p.d = 200; // MeshManager::getSingleton().createPlane("FloorPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// p,200000,200000,20,20,true,1,50,50,Vector3::UNIT_Z); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// p,200000,200000,20,20,true,1,50,50,Vector3::UNIT_Z); // // // // leak here I know @@ -2663,25 +2663,25 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); // -// // Hardware skin +// // Hardware skin // Entity* pEnt; // pEnt = mSceneMgr->createEntity( "1", "robot.mesh" ); // AnimationState* anim = pEnt->getAnimationState("Walk"); // anim->setEnabled(true); -// mAnimStateList.push_back(anim); -// mTestNode[0]->attachObject( pEnt ); +// mAnimStateList.push_back(anim); +// mTestNode[0]->attachObject( pEnt ); // -// // Software skin -// pEnt = mSceneMgr->createEntity( "12", "robot.mesh" ); -// anim = pEnt->getAnimationState("Walk"); -// anim->setEnabled(true); -// mAnimStateList.push_back(anim); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 0))->attachObject(pEnt); -// pEnt->setMaterialName("Examples/Rocky"); +// // Software skin +// pEnt = mSceneMgr->createEntity( "12", "robot.mesh" ); +// anim = pEnt->getAnimationState("Walk"); +// anim->setEnabled(true); +// mAnimStateList.push_back(anim); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 0))->attachObject(pEnt); +// pEnt->setMaterialName("Examples/Rocky"); // -// // test object -// //pEnt = mSceneMgr->createEntity("tst", "building.mesh"); -// //mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(300, 0, 0))->attachObject(pEnt); +// // test object +// //pEnt = mSceneMgr->createEntity("tst", "building.mesh"); +// //mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(300, 0, 0))->attachObject(pEnt); // // // // Does not receive shadows @@ -2696,18 +2696,18 @@ extern "C" _OgreSampleExport void dllStopPlugin() // pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" ); // pEnt->setMaterialName("Examples/TransparentTest"); // MaterialPtr mat3 = MaterialManager::getSingleton().getByName("Examples/TransparentTest"); -// pEnt->setCastShadows(false); +// pEnt->setCastShadows(false); // mTestNode[3] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(350, 0, -200)); // mTestNode[3]->attachObject( pEnt ); // -// // User test -// /* -// pEnt = mSceneMgr->createEntity( "3.6", "ogre_male_endCaps.mesh" ); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0, 0, 100))->attachObject( pEnt ); -// */ +// // User test +// /* +// pEnt = mSceneMgr->createEntity( "3.6", "ogre_male_endCaps.mesh" ); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0, 0, 100))->attachObject( pEnt ); +// */ // // MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // unsigned short src, dest; // if (!msh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest)) // { @@ -2718,10 +2718,10 @@ extern "C" _OgreSampleExport void dllStopPlugin() // mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 200)); // mTestNode[2]->attachObject( pEnt ); // -// // controller based material -// pEnt = mSceneMgr->createEntity( "432", "knot.mesh" ); -// pEnt->setMaterialName("Examples/TextureEffect2"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 200, 200))->attachObject( pEnt ); +// // controller based material +// pEnt = mSceneMgr->createEntity( "432", "knot.mesh" ); +// pEnt->setMaterialName("Examples/TextureEffect2"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 200, 200))->attachObject( pEnt ); // // ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("smoke", // "Examples/Smoke"); @@ -2736,7 +2736,7 @@ extern "C" _OgreSampleExport void dllStopPlugin() // plane.normal = Vector3::UNIT_Y; // plane.d = 100; // MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, // 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); // Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); // pPlaneEnt->setMaterialName("2 - Default"); @@ -2746,103 +2746,103 @@ extern "C" _OgreSampleExport void dllStopPlugin() // mCamera->setPosition(180, 34, 223); // mCamera->setOrientation(Quaternion(0.7265, -0.2064, 0.6304, 0.1791)); // -// // Create a render texture -// TexturePtr rtt = TextureManager::getSingleton().createManual("rtt0", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// TEX_TYPE_2D, 512, 512, 0, PF_R8G8B8, TU_RENDERTARGET); -// rtt->getBuffer()->getRenderTarget()->addViewport(mCamera); -// // Create an overlay showing the rtt -// MaterialPtr debugMat = MaterialManager::getSingleton().create( -// "DebugRTT", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); -// TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState("rtt0"); -// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); -// OverlayContainer* debugPanel = (OverlayContainer*) -// (OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugShadowPanel")); -// debugPanel->_setPosition(0.6, 0); -// debugPanel->_setDimensions(0.4, 0.6); -// debugPanel->setMaterialName("DebugRTT"); -// Overlay* debugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); -// debugOverlay->add2D(debugPanel); +// // Create a render texture +// TexturePtr rtt = TextureManager::getSingleton().createManual("rtt0", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// TEX_TYPE_2D, 512, 512, 0, PF_R8G8B8, TU_RENDERTARGET); +// rtt->getBuffer()->getRenderTarget()->addViewport(mCamera); +// // Create an overlay showing the rtt +// MaterialPtr debugMat = MaterialManager::getSingleton().create( +// "DebugRTT", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); +// TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState("rtt0"); +// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); +// OverlayContainer* debugPanel = (OverlayContainer*) +// (OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugShadowPanel")); +// debugPanel->_setPosition(0.6, 0); +// debugPanel->_setDimensions(0.4, 0.6); +// debugPanel->setMaterialName("DebugRTT"); +// Overlay* debugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); +// debugOverlay->add2D(debugPanel); // // // } // -// void testStencilShadowsMixedOpSubMeshes(bool pointLight, bool directionalLight) -// { -// mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); -// //mSceneMgr->setShowDebugShadows(true); -// mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000); -// -// //mSceneMgr->setShadowFarDistance(800); -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0.0, 0.0, 0.0)); -// -// // Point light -// if(pointLight) -// { -// mLight = mSceneMgr->createLight("MainLight"); -// mLight->setPosition(-400,400,-300); -// mLight->setDiffuseColour(0.9, 0.9, 1); -// mLight->setSpecularColour(0.9, 0.9, 1); -// mLight->setAttenuation(6000,1,0.001,0); -// } -// // Directional light -// if (directionalLight) -// { -// mLight = mSceneMgr->createLight("Light2"); -// Vector3 dir(-1,-1,0); -// dir.normalise(); -// mLight->setType(Light::LT_DIRECTIONAL); -// mLight->setDirection(dir); -// mLight->setDiffuseColour(1, 1, 0.8); -// mLight->setSpecularColour(1, 1, 1); -// } -// -// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); -// -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// mCamera->setPosition(180, 34, 223); -// mCamera->setOrientation(Quaternion(0.7265, -0.2064, 0.6304, 0.1791)); -// -// -// ManualObject* man = mSceneMgr->createManualObject("testMO"); -// man->begin("2 - Default"); -// man->position(0, 200, 0); -// man->position(0, 50, 100); -// man->position(100, 50, -100); -// man->position(-100, 50, -100); -// man->triangle(0, 1, 2); -// man->triangle(0, 2, 3); -// man->triangle(0, 3, 1); -// man->end(); -// man->begin("2 - Default", RenderOperation::OT_LINE_STRIP); -// man->position(0, 200, 0); -// man->position(50, 250, 0); -// man->position(200, 300, 0); -// man->index(0); -// man->index(1); -// man->index(2); -// man->end(); -// MeshPtr msh = man->convertToMesh("testMO.mesh"); -// -// Entity* e = mSceneMgr->createEntity("34", "testMO.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// -// -// -// } +// void testStencilShadowsMixedOpSubMeshes(bool pointLight, bool directionalLight) +// { +// mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); +// //mSceneMgr->setShowDebugShadows(true); +// mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000); +// +// //mSceneMgr->setShadowFarDistance(800); +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0.0, 0.0, 0.0)); +// +// // Point light +// if(pointLight) +// { +// mLight = mSceneMgr->createLight("MainLight"); +// mLight->setPosition(-400,400,-300); +// mLight->setDiffuseColour(0.9, 0.9, 1); +// mLight->setSpecularColour(0.9, 0.9, 1); +// mLight->setAttenuation(6000,1,0.001,0); +// } +// // Directional light +// if (directionalLight) +// { +// mLight = mSceneMgr->createLight("Light2"); +// Vector3 dir(-1,-1,0); +// dir.normalise(); +// mLight->setType(Light::LT_DIRECTIONAL); +// mLight->setDirection(dir); +// mLight->setDiffuseColour(1, 1, 0.8); +// mLight->setSpecularColour(1, 1, 1); +// } +// +// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); +// +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// mCamera->setPosition(180, 34, 223); +// mCamera->setOrientation(Quaternion(0.7265, -0.2064, 0.6304, 0.1791)); +// +// +// ManualObject* man = mSceneMgr->createManualObject("testMO"); +// man->begin("2 - Default"); +// man->position(0, 200, 0); +// man->position(0, 50, 100); +// man->position(100, 50, -100); +// man->position(-100, 50, -100); +// man->triangle(0, 1, 2); +// man->triangle(0, 2, 3); +// man->triangle(0, 3, 1); +// man->end(); +// man->begin("2 - Default", RenderOperation::OT_LINE_STRIP); +// man->position(0, 200, 0); +// man->position(50, 250, 0); +// man->position(200, 300, 0); +// man->index(0); +// man->index(1); +// man->index(2); +// man->end(); +// MeshPtr msh = man->convertToMesh("testMO.mesh"); +// +// Entity* e = mSceneMgr->createEntity("34", "testMO.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// +// +// +// } // void test2Spotlights() // { // mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); @@ -2873,7 +2873,7 @@ extern "C" _OgreSampleExport void dllStopPlugin() // plane.normal = Vector3::UNIT_Y; // plane.d = 100; // MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, // 3500,3500,100,100,true,1,5,5,Vector3::UNIT_Z); // Entity* pPlaneEnt; // pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); @@ -2882,44 +2882,44 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // } // -// void addTextureShadowDebugOverlay(size_t num) -// { -// for (size_t i = 0; i < num; ++i) -// { -// TexturePtr shadowTex = mSceneMgr->getShadowTexture(i); -// addTextureDebugOverlay(shadowTex, i); -// -// } -// -// } -// void addTextureDebugOverlay(TexturePtr tex, size_t i) -// { -// addTextureDebugOverlay(tex->getName(), i); -// } -// void addTextureDebugOverlay(const String& texname, size_t i) -// { -// Overlay* debugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); -// -// // Set up a debug panel to display the shadow -// MaterialPtr debugMat = MaterialManager::getSingleton().create( -// "Ogre/DebugTexture" + StringConverter::toString(i), -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); -// TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(texname); -// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); -// //t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState("spot_shadow_fade.png"); -// //t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); -// //t->setColourOperation(LBO_ADD); -// -// -// OverlayContainer* debugPanel = (OverlayContainer*) -// (OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i))); -// debugPanel->_setPosition(0.8, i*0.25); -// debugPanel->_setDimensions(0.2, 0.24); -// debugPanel->setMaterialName(debugMat->getName()); -// debugOverlay->add2D(debugPanel); -// -// } +// void addTextureShadowDebugOverlay(size_t num) +// { +// for (size_t i = 0; i < num; ++i) +// { +// TexturePtr shadowTex = mSceneMgr->getShadowTexture(i); +// addTextureDebugOverlay(shadowTex, i); +// +// } +// +// } +// void addTextureDebugOverlay(TexturePtr tex, size_t i) +// { +// addTextureDebugOverlay(tex->getName(), i); +// } +// void addTextureDebugOverlay(const String& texname, size_t i) +// { +// Overlay* debugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); +// +// // Set up a debug panel to display the shadow +// MaterialPtr debugMat = MaterialManager::getSingleton().create( +// "Ogre/DebugTexture" + StringConverter::toString(i), +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); +// TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(texname); +// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); +// //t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState("spot_shadow_fade.png"); +// //t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); +// //t->setColourOperation(LBO_ADD); +// +// +// OverlayContainer* debugPanel = (OverlayContainer*) +// (OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i))); +// debugPanel->_setPosition(0.8, i*0.25); +// debugPanel->_setDimensions(0.2, 0.24); +// debugPanel->setMaterialName(debugMat->getName()); +// debugOverlay->add2D(debugPanel); +// +// } // // // void testTextureShadows(ShadowTechnique tech, bool directional) @@ -2927,10 +2927,10 @@ extern "C" _OgreSampleExport void dllStopPlugin() // mSceneMgr->setShadowTextureSize(1024); // mSceneMgr->setShadowTechnique(tech); // -// //FocusedShadowCameraSetup* lispsmSetup = new FocusedShadowCameraSetup(); -// //LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup(); -// //lispsmSetup->setOptimalAdjustFactor(1.5); -// //mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(lispsmSetup)); +// //FocusedShadowCameraSetup* lispsmSetup = new FocusedShadowCameraSetup(); +// //LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup(); +// //lispsmSetup->setOptimalAdjustFactor(1.5); +// //mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(lispsmSetup)); // // mSceneMgr->setShadowFarDistance(1000); // mSceneMgr->setShadowColour(ColourValue(0.35, 0.35, 0.35)); @@ -2940,66 +2940,66 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // mLight = mSceneMgr->createLight("MainLight"); // -// +// // // Directional test -// if (directional) -// { -// mLight->setType(Light::LT_DIRECTIONAL); -// Vector3 vec(-1,-1,0); -// vec.normalise(); -// mLight->setDirection(vec); -// } +// if (directional) +// { +// mLight->setType(Light::LT_DIRECTIONAL); +// Vector3 vec(-1,-1,0); +// vec.normalise(); +// mLight->setDirection(vec); +// } // // Spotlight test -// else -// { -// mLight->setType(Light::LT_SPOTLIGHT); -// mLight->setAttenuation(1500, 1, 0, 0); -// mLight->setDiffuseColour(1.0, 1.0, 0.8); -// mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// mTestNode[0]->setPosition(800,600,0); -// mTestNode[0]->lookAt(Vector3(0,0,0), Node::TS_WORLD, Vector3::UNIT_Z); -// mTestNode[0]->attachObject(mLight); -// } +// else +// { +// mLight->setType(Light::LT_SPOTLIGHT); +// mLight->setAttenuation(1500, 1, 0, 0); +// mLight->setDiffuseColour(1.0, 1.0, 0.8); +// mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// mTestNode[0]->setPosition(800,600,0); +// mTestNode[0]->lookAt(Vector3(0,0,0), Node::TS_WORLD, Vector3::UNIT_Z); +// mTestNode[0]->attachObject(mLight); +// } // // mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); // // // Entity* pEnt; // pEnt = mSceneMgr->createEntity( "1", "robot.mesh" ); -// //pEnt->setRenderingDistance(100); +// //pEnt->setRenderingDistance(100); // mAnimState = pEnt->getAnimationState("Walk"); // mAnimState->setEnabled(true); // //pEnt->setMaterialName("2 - Default"); // mTestNode[1]->attachObject( pEnt ); // mTestNode[1]->translate(0,-100,0); // -// quat1 = Quaternion::IDENTITY; -// quat2.FromAngleAxis(Degree(360), Vector3::UNIT_Y); +// quat1 = Quaternion::IDENTITY; +// quat2.FromAngleAxis(Degree(360), Vector3::UNIT_Y); // // pEnt = mSceneMgr->createEntity( "3", "knot.mesh" ); // mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-200, 0, -200)); // mTestNode[2]->attachObject( pEnt ); // -// createRandomEntityClones(pEnt, 20, Vector3(-1000,0,-1000), Vector3(1000,0,1000)); +// createRandomEntityClones(pEnt, 20, Vector3(-1000,0,-1000), Vector3(1000,0,1000)); // // // // Transparent object (can force cast shadows) // pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" ); -// MaterialPtr tmat = MaterialManager::getSingleton().create("TestAlphaTransparency", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// tmat->setTransparencyCastsShadows(true); -// Pass* tpass = tmat->getTechnique(0)->getPass(0); -// tpass->setAlphaRejectSettings(CMPF_GREATER, 150); -// tpass->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// tpass->createTextureUnitState("gras_02.png"); -// tpass->setCullingMode(CULL_NONE); +// MaterialPtr tmat = MaterialManager::getSingleton().create("TestAlphaTransparency", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// tmat->setTransparencyCastsShadows(true); +// Pass* tpass = tmat->getTechnique(0)->getPass(0); +// tpass->setAlphaRejectSettings(CMPF_GREATER, 150); +// tpass->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// tpass->createTextureUnitState("gras_02.png"); +// tpass->setCullingMode(CULL_NONE); // // pEnt->setMaterialName("TestAlphaTransparency"); // mTestNode[3] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(350, 0, -200)); // mTestNode[3]->attachObject( pEnt ); // // MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // msh->buildTangentVectors(VES_TANGENT, 0, 0); // pEnt = mSceneMgr->createEntity( "4", "knot.mesh" ); // //pEnt->setMaterialName("Examples/BumpMapping/MultiLightSpecular"); @@ -3013,414 +3013,414 @@ extern "C" _OgreSampleExport void dllStopPlugin() // movablePlane.normal = Vector3::UNIT_Y; // movablePlane.d = 100; // MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, movablePlane, +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, movablePlane, // 2500,2500,10,10,true,1,5,5,Vector3::UNIT_Z); // Entity* pPlaneEnt; // pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// if (tech & SHADOWDETAILTYPE_INTEGRATED) -// { -// pPlaneEnt->setMaterialName("Examples/Plane/IntegratedShadows"); -// } -// else -// { -// pPlaneEnt->setMaterialName("2 - Default"); -// } +// if (tech & SHADOWDETAILTYPE_INTEGRATED) +// { +// pPlaneEnt->setMaterialName("Examples/Plane/IntegratedShadows"); +// } +// else +// { +// pPlaneEnt->setMaterialName("2 - Default"); +// } // pPlaneEnt->setCastShadows(false); // mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); // -// addTextureShadowDebugOverlay(1); +// addTextureShadowDebugOverlay(1); // // -// /* +// /* // ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("smoke", // "Examples/Smoke"); // mTestNode[4] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-300, -100, 200)); // mTestNode[4]->attachObject(pSys2); -// */ +// */ // -// mCamera->setPosition(0, 1000, 500); -// mCamera->lookAt(0,0,0); -// mCamera->setFarClipDistance(10000); +// mCamera->setPosition(0, 1000, 500); +// mCamera->lookAt(0,0,0); +// mCamera->setFarClipDistance(10000); // // // } // -// void testTextureShadowsCustomCasterMat(ShadowTechnique tech, bool directional) -// { -// -// testTextureShadows(tech, directional); -// -// String customCasterMatVp = -// "void customCasterVp(float4 position : POSITION,\n" -// "out float4 oPosition : POSITION,\n" -// "uniform float4x4 worldViewProj)\n" -// "{\n" -// " oPosition = mul(worldViewProj, position);\n" -// "}\n"; -// String customCasterMatFp = -// "void customCasterFp(\n" -// "out float4 oColor : COLOR)\n" -// "{\n" -// " oColor = float4(1,1,0,1); // just a test\n" -// "}\n"; -// -// HighLevelGpuProgramPtr vp = HighLevelGpuProgramManager::getSingleton() -// .createProgram("CustomShadowCasterVp", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// "cg", GPT_VERTEX_PROGRAM); -// vp->setSource(customCasterMatVp); -// vp->setParameter("profiles", "vs_1_1 arbvp1"); -// vp->setParameter("entry_point", "customCasterVp"); -// vp->load(); -// -// HighLevelGpuProgramPtr fp = HighLevelGpuProgramManager::getSingleton() -// .createProgram("CustomShadowCasterFp", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// "cg", GPT_FRAGMENT_PROGRAM); -// fp->setSource(customCasterMatFp); -// fp->setParameter("profiles", "ps_1_1 arbfp1"); -// fp->setParameter("entry_point", "customCasterFp"); -// fp->load(); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("CustomShadowCaster", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setVertexProgram("CustomShadowCasterVp"); -// p->getVertexProgramParameters()->setNamedAutoConstant( -// "worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); -// p->setFragmentProgram("CustomShadowCasterFp"); -// -// mSceneMgr->setShadowTextureCasterMaterial("CustomShadowCaster"); -// -// -// -// -// -// } -// -// void testTextureShadowsCustomReceiverMat(ShadowTechnique tech, bool directional) -// { -// testTextureShadows(tech, directional); -// -// String customReceiverMatVp = -// "void customReceiverVp(float4 position : POSITION,\n" -// "out float4 oPosition : POSITION,\n" -// "out float2 oUV : TEXCOORD0,\n" -// "uniform float4x4 texViewProj,\n" -// "uniform float4x4 worldViewProj)\n" -// "{\n" -// " oPosition = mul(worldViewProj, position);\n" -// " float4 suv = mul(texViewProj, position);\n" -// " oUV = suv.xy / suv.w;\n" -// "}\n"; -// String customReceiverMatFp = -// "void customReceiverFp(\n" -// "float2 uv : TEXCOORD0,\n" -// "uniform sampler2D shadowTex : register(s0),\n" -// "out float4 oColor : COLOR)\n" -// "{\n" -// " float4 shadow = tex2D(shadowTex, uv);\n" -// " oColor = shadow * float4(1,0,1,1); // just a test\n" -// "}\n"; -// -// HighLevelGpuProgramPtr vp = HighLevelGpuProgramManager::getSingleton() -// .createProgram("CustomShadowReceiverVp", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// "cg", GPT_VERTEX_PROGRAM); -// vp->setSource(customReceiverMatVp); -// vp->setParameter("profiles", "vs_1_1 arbvp1"); -// vp->setParameter("entry_point", "customReceiverVp"); -// vp->load(); -// -// HighLevelGpuProgramPtr fp = HighLevelGpuProgramManager::getSingleton() -// .createProgram("CustomShadowReceiverFp", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// "cg", GPT_FRAGMENT_PROGRAM); -// fp->setSource(customReceiverMatFp); -// fp->setParameter("profiles", "ps_1_1 arbfp1"); -// fp->setParameter("entry_point", "customReceiverFp"); -// fp->load(); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("CustomShadowReceiver", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setVertexProgram("CustomShadowReceiverVp"); -// p->getVertexProgramParameters()->setNamedAutoConstant( -// "worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); -// p->getVertexProgramParameters()->setNamedAutoConstant( -// "texViewProj", GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX); -// p->setFragmentProgram("CustomShadowReceiverFp"); -// p->createTextureUnitState(); // shadow texture will populate -// -// mSceneMgr->setShadowTextureReceiverMaterial("CustomShadowReceiver"); -// -// -// -// } -// -// -// //--------------------------------------------------------------------------- -// class GaussianListener: public Ogre::CompositorInstance::Listener -// { -// protected: -// int mVpWidth, mVpHeight; -// // Array params - have to pack in groups of 4 since this is how Cg generates them -// // also prevents dependent texture read problems if ops don't require swizzle -// float mBloomTexWeights[15][4]; -// float mBloomTexOffsetsHorz[15][4]; -// float mBloomTexOffsetsVert[15][4]; -// public: -// GaussianListener() {} -// virtual ~GaussianListener() {} -// void notifyViewportSize(int width, int height) -// { -// mVpWidth = width; -// mVpHeight = height; -// // Calculate gaussian texture offsets & weights -// float deviation = 3.0f; -// float texelSize = 1.0f / (float)std::min(mVpWidth, mVpHeight); -// -// // central sample, no offset -// mBloomTexOffsetsHorz[0][0] = 0.0f; -// mBloomTexOffsetsHorz[0][1] = 0.0f; -// mBloomTexWeights[0][0] = mBloomTexWeights[0][1] = -// mBloomTexWeights[0][2] = Ogre::Math::gaussianDistribution(0, 0, deviation); -// mBloomTexWeights[0][3] = 1.0f; -// -// // 'pre' samples -// for(int i = 1; i < 8; ++i) -// { -// mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = -// mBloomTexWeights[i][2] = Ogre::Math::gaussianDistribution(i, 0, deviation); -// mBloomTexWeights[i][3] = 1.0f; -// mBloomTexOffsetsHorz[i][0] = i * texelSize; -// mBloomTexOffsetsHorz[i][1] = 0.0f; -// mBloomTexOffsetsVert[i][0] = 0.0f; -// mBloomTexOffsetsVert[i][1] = i * texelSize; -// } -// // 'post' samples -// for(int i = 8; i < 15; ++i) -// { -// mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = -// mBloomTexWeights[i][2] = mBloomTexWeights[i - 7][0]; -// mBloomTexWeights[i][3] = 1.0f; -// -// mBloomTexOffsetsHorz[i][0] = -mBloomTexOffsetsHorz[i - 7][0]; -// mBloomTexOffsetsHorz[i][1] = 0.0f; -// mBloomTexOffsetsVert[i][0] = 0.0f; -// mBloomTexOffsetsVert[i][1] = -mBloomTexOffsetsVert[i - 7][1]; -// } -// -// } -// virtual void notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) -// { -// // Prepare the fragment params offsets -// switch(pass_id) -// { -// case 701: // blur horz -// { -// // horizontal bloom -// mat->load(); -// Ogre::GpuProgramParametersSharedPtr fparams = -// mat->getBestTechnique()->getPass(0)->getFragmentProgramParameters(); -// const Ogre::String& progName = mat->getBestTechnique()->getPass(0)->getFragmentProgramName(); -// fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsHorz[0], 15); -// fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); -// -// break; -// } -// case 700: // blur vert -// { -// // vertical bloom -// mat->load(); -// Ogre::GpuProgramParametersSharedPtr fparams = -// mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); -// const Ogre::String& progName = mat->getBestTechnique()->getPass(0)->getFragmentProgramName(); -// fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsVert[0], 15); -// fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); -// -// break; -// } -// } -// -// } -// virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) -// { -// -// } -// }; -// GaussianListener gaussianListener; -// -// void testCompositorTextureShadows(ShadowTechnique tech) -// { -// mSceneMgr->setShadowTextureSize(512); -// mSceneMgr->setShadowTechnique(tech); -// mSceneMgr->setShadowFarDistance(1500); -// mSceneMgr->setShadowColour(ColourValue(0.35, 0.35, 0.35)); -// //mSceneMgr->setShadowFarDistance(800); -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); -// -// mLight = mSceneMgr->createLight("MainLight"); -// -// /* -// // Directional test -// mLight->setType(Light::LT_DIRECTIONAL); -// Vector3 vec(-1,-1,0); -// vec.normalise(); -// mLight->setDirection(vec); -// -// */ -// // Spotlight test -// mLight->setType(Light::LT_SPOTLIGHT); -// mLight->setDiffuseColour(1.0, 1.0, 0.8); -// mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// mTestNode[0]->setPosition(800,600,0); -// mTestNode[0]->lookAt(Vector3(0,0,0), Node::TS_WORLD, Vector3::UNIT_Z); -// mTestNode[0]->attachObject(mLight); -// -// -// mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// -// -// Entity* pEnt; -// pEnt = mSceneMgr->createEntity( "1", "robot.mesh" ); -// //pEnt->setRenderingDistance(100); -// mAnimState = pEnt->getAnimationState("Walk"); -// mAnimState->setEnabled(true); -// //pEnt->setMaterialName("2 - Default"); -// mTestNode[1]->attachObject( pEnt ); -// mTestNode[1]->translate(0,-100,0); -// -// pEnt = mSceneMgr->createEntity( "3", "knot.mesh" ); -// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-200, 0, -200)); -// mTestNode[2]->attachObject( pEnt ); -// -// // Transparent object (can force cast shadows) -// pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" ); -// MaterialPtr tmat = MaterialManager::getSingleton().create("TestAlphaTransparency", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// tmat->setTransparencyCastsShadows(true); -// Pass* tpass = tmat->getTechnique(0)->getPass(0); -// tpass->setAlphaRejectSettings(CMPF_GREATER, 150); -// tpass->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// tpass->createTextureUnitState("gras_02.png"); -// tpass->setCullingMode(CULL_NONE); -// -// pEnt->setMaterialName("TestAlphaTransparency"); -// mTestNode[3] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(350, 0, -200)); -// mTestNode[3]->attachObject( pEnt ); -// -// MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// msh->buildTangentVectors(VES_TANGENT, 0, 0); -// pEnt = mSceneMgr->createEntity( "4", "knot.mesh" ); -// //pEnt->setMaterialName("Examples/BumpMapping/MultiLightSpecular"); -// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 200)); -// mTestNode[2]->attachObject( pEnt ); -// -// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); -// -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt; -// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// // Set up a debug panel to display the shadow -// addTextureShadowDebugOverlay(1); -// -// -// -// ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("smoke", -// "Examples/Smoke"); -// mTestNode[4] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-300, -100, 200)); -// mTestNode[4]->attachObject(pSys2); -// -// TexturePtr shadowTex = mSceneMgr->getShadowTexture(0); -// RenderTarget* shadowRtt = shadowTex->getBuffer()->getRenderTarget(); -// Viewport* vp = shadowRtt->getViewport(0); -// Ogre::CompositorInstance *instance = -// CompositorManager::getSingleton().addCompositor(vp, "Gaussian Blur"); -// CompositorManager::getSingleton().setCompositorEnabled( -// vp, "Gaussian Blur", true); -// instance->addListener(&gaussianListener); -// gaussianListener.notifyViewportSize(vp->getActualWidth(), vp->getActualHeight()); -// -// -// -// -// -// } -// -// void testCompositorTechniqueSwitch(bool sharedTextures) -// { -// CompositorManager& cmgr = CompositorManager::getSingleton(); -// CompositorPtr compositor = cmgr.create("testtechswitch", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// // technique 1 (Invert) -// CompositionTechnique* ctech1 = compositor->createTechnique(); -// CompositionTechnique::TextureDefinition* tdef = ctech1->createTextureDefinition("rt0"); -// tdef->formatList.push_back(PF_A8B8G8R8); -// tdef->width = tdef->height = 0; -// tdef->pooled = sharedTextures; -// -// CompositionTargetPass* tpass = ctech1->createTargetPass(); -// tpass->setOutputName("rt0"); -// tpass->setInputMode(CompositionTargetPass::IM_PREVIOUS); -// CompositionTargetPass* tout = ctech1->getOutputTargetPass(); -// tout->setInputMode(CompositionTargetPass::IM_NONE); -// CompositionPass* pass = tout->createPass(); -// pass->setType(CompositionPass::PT_RENDERQUAD); -// pass->setMaterialName("Ogre/Compositor/Invert"); -// pass->setInput(0, "rt0"); -// -// // technique 2 (Tiling) -// ctech1 = compositor->createTechnique(); -// ctech1->setSchemeName("Tiling"); -// tdef = ctech1->createTextureDefinition("rt0"); -// tdef->formatList.push_back(PF_A8B8G8R8); -// tdef->width = tdef->height = 0; -// tdef->pooled = sharedTextures; -// -// tpass = ctech1->createTargetPass(); -// tpass->setOutputName("rt0"); -// tpass->setInputMode(CompositionTargetPass::IM_PREVIOUS); -// tout = ctech1->getOutputTargetPass(); -// tout->setInputMode(CompositionTargetPass::IM_NONE); -// pass = tout->createPass(); -// pass->setType(CompositionPass::PT_RENDERQUAD); -// pass->setMaterialName("Ogre/Compositor/Tiling"); -// pass->setInput(0, "rt0"); -// -// compositor->load(); -// -// Entity* e = mSceneMgr->createEntity("1", "knot.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 1000); +// void testTextureShadowsCustomCasterMat(ShadowTechnique tech, bool directional) +// { +// +// testTextureShadows(tech, directional); +// +// String customCasterMatVp = +// "void customCasterVp(float4 position : POSITION,\n" +// "out float4 oPosition : POSITION,\n" +// "uniform float4x4 worldViewProj)\n" +// "{\n" +// " oPosition = mul(worldViewProj, position);\n" +// "}\n"; +// String customCasterMatFp = +// "void customCasterFp(\n" +// "out float4 oColor : COLOR)\n" +// "{\n" +// " oColor = float4(1,1,0,1); // just a test\n" +// "}\n"; +// +// HighLevelGpuProgramPtr vp = HighLevelGpuProgramManager::getSingleton() +// .createProgram("CustomShadowCasterVp", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// "cg", GPT_VERTEX_PROGRAM); +// vp->setSource(customCasterMatVp); +// vp->setParameter("profiles", "vs_1_1 arbvp1"); +// vp->setParameter("entry_point", "customCasterVp"); +// vp->load(); +// +// HighLevelGpuProgramPtr fp = HighLevelGpuProgramManager::getSingleton() +// .createProgram("CustomShadowCasterFp", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// "cg", GPT_FRAGMENT_PROGRAM); +// fp->setSource(customCasterMatFp); +// fp->setParameter("profiles", "ps_1_1 arbfp1"); +// fp->setParameter("entry_point", "customCasterFp"); +// fp->load(); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("CustomShadowCaster", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setVertexProgram("CustomShadowCasterVp"); +// p->getVertexProgramParameters()->setNamedAutoConstant( +// "worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); +// p->setFragmentProgram("CustomShadowCasterFp"); +// +// mSceneMgr->setShadowTextureCasterMaterial("CustomShadowCaster"); +// +// +// +// +// +// } +// +// void testTextureShadowsCustomReceiverMat(ShadowTechnique tech, bool directional) +// { +// testTextureShadows(tech, directional); +// +// String customReceiverMatVp = +// "void customReceiverVp(float4 position : POSITION,\n" +// "out float4 oPosition : POSITION,\n" +// "out float2 oUV : TEXCOORD0,\n" +// "uniform float4x4 texViewProj,\n" +// "uniform float4x4 worldViewProj)\n" +// "{\n" +// " oPosition = mul(worldViewProj, position);\n" +// " float4 suv = mul(texViewProj, position);\n" +// " oUV = suv.xy / suv.w;\n" +// "}\n"; +// String customReceiverMatFp = +// "void customReceiverFp(\n" +// "float2 uv : TEXCOORD0,\n" +// "uniform sampler2D shadowTex : register(s0),\n" +// "out float4 oColor : COLOR)\n" +// "{\n" +// " float4 shadow = tex2D(shadowTex, uv);\n" +// " oColor = shadow * float4(1,0,1,1); // just a test\n" +// "}\n"; +// +// HighLevelGpuProgramPtr vp = HighLevelGpuProgramManager::getSingleton() +// .createProgram("CustomShadowReceiverVp", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// "cg", GPT_VERTEX_PROGRAM); +// vp->setSource(customReceiverMatVp); +// vp->setParameter("profiles", "vs_1_1 arbvp1"); +// vp->setParameter("entry_point", "customReceiverVp"); +// vp->load(); +// +// HighLevelGpuProgramPtr fp = HighLevelGpuProgramManager::getSingleton() +// .createProgram("CustomShadowReceiverFp", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// "cg", GPT_FRAGMENT_PROGRAM); +// fp->setSource(customReceiverMatFp); +// fp->setParameter("profiles", "ps_1_1 arbfp1"); +// fp->setParameter("entry_point", "customReceiverFp"); +// fp->load(); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("CustomShadowReceiver", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setVertexProgram("CustomShadowReceiverVp"); +// p->getVertexProgramParameters()->setNamedAutoConstant( +// "worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); +// p->getVertexProgramParameters()->setNamedAutoConstant( +// "texViewProj", GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX); +// p->setFragmentProgram("CustomShadowReceiverFp"); +// p->createTextureUnitState(); // shadow texture will populate +// +// mSceneMgr->setShadowTextureReceiverMaterial("CustomShadowReceiver"); +// +// +// +// } +// +// +// //--------------------------------------------------------------------------- +// class GaussianListener: public Ogre::CompositorInstance::Listener +// { +// protected: +// int mVpWidth, mVpHeight; +// // Array params - have to pack in groups of 4 since this is how Cg generates them +// // also prevents dependent texture read problems if ops don't require swizzle +// float mBloomTexWeights[15][4]; +// float mBloomTexOffsetsHorz[15][4]; +// float mBloomTexOffsetsVert[15][4]; +// public: +// GaussianListener() {} +// virtual ~GaussianListener() {} +// void notifyViewportSize(int width, int height) +// { +// mVpWidth = width; +// mVpHeight = height; +// // Calculate gaussian texture offsets & weights +// float deviation = 3.0f; +// float texelSize = 1.0f / (float)std::min(mVpWidth, mVpHeight); +// +// // central sample, no offset +// mBloomTexOffsetsHorz[0][0] = 0.0f; +// mBloomTexOffsetsHorz[0][1] = 0.0f; +// mBloomTexWeights[0][0] = mBloomTexWeights[0][1] = +// mBloomTexWeights[0][2] = Ogre::Math::gaussianDistribution(0, 0, deviation); +// mBloomTexWeights[0][3] = 1.0f; +// +// // 'pre' samples +// for(int i = 1; i < 8; ++i) +// { +// mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = +// mBloomTexWeights[i][2] = Ogre::Math::gaussianDistribution(i, 0, deviation); +// mBloomTexWeights[i][3] = 1.0f; +// mBloomTexOffsetsHorz[i][0] = i * texelSize; +// mBloomTexOffsetsHorz[i][1] = 0.0f; +// mBloomTexOffsetsVert[i][0] = 0.0f; +// mBloomTexOffsetsVert[i][1] = i * texelSize; +// } +// // 'post' samples +// for(int i = 8; i < 15; ++i) +// { +// mBloomTexWeights[i][0] = mBloomTexWeights[i][1] = +// mBloomTexWeights[i][2] = mBloomTexWeights[i - 7][0]; +// mBloomTexWeights[i][3] = 1.0f; +// +// mBloomTexOffsetsHorz[i][0] = -mBloomTexOffsetsHorz[i - 7][0]; +// mBloomTexOffsetsHorz[i][1] = 0.0f; +// mBloomTexOffsetsVert[i][0] = 0.0f; +// mBloomTexOffsetsVert[i][1] = -mBloomTexOffsetsVert[i - 7][1]; +// } +// +// } +// virtual void notifyMaterialSetup(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) +// { +// // Prepare the fragment params offsets +// switch(pass_id) +// { +// case 701: // blur horz +// { +// // horizontal bloom +// mat->load(); +// Ogre::GpuProgramParametersSharedPtr fparams = +// mat->getBestTechnique()->getPass(0)->getFragmentProgramParameters(); +// const Ogre::String& progName = mat->getBestTechnique()->getPass(0)->getFragmentProgramName(); +// fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsHorz[0], 15); +// fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); +// +// break; +// } +// case 700: // blur vert +// { +// // vertical bloom +// mat->load(); +// Ogre::GpuProgramParametersSharedPtr fparams = +// mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); +// const Ogre::String& progName = mat->getBestTechnique()->getPass(0)->getFragmentProgramName(); +// fparams->setNamedConstant("sampleOffsets", mBloomTexOffsetsVert[0], 15); +// fparams->setNamedConstant("sampleWeights", mBloomTexWeights[0], 15); +// +// break; +// } +// } +// +// } +// virtual void notifyMaterialRender(Ogre::uint32 pass_id, Ogre::MaterialPtr &mat) +// { +// +// } +// }; +// GaussianListener gaussianListener; +// +// void testCompositorTextureShadows(ShadowTechnique tech) +// { +// mSceneMgr->setShadowTextureSize(512); +// mSceneMgr->setShadowTechnique(tech); +// mSceneMgr->setShadowFarDistance(1500); +// mSceneMgr->setShadowColour(ColourValue(0.35, 0.35, 0.35)); +// //mSceneMgr->setShadowFarDistance(800); +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); +// +// mLight = mSceneMgr->createLight("MainLight"); +// +// /* +// // Directional test +// mLight->setType(Light::LT_DIRECTIONAL); +// Vector3 vec(-1,-1,0); +// vec.normalise(); +// mLight->setDirection(vec); +// +// */ +// // Spotlight test +// mLight->setType(Light::LT_SPOTLIGHT); +// mLight->setDiffuseColour(1.0, 1.0, 0.8); +// mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// mTestNode[0]->setPosition(800,600,0); +// mTestNode[0]->lookAt(Vector3(0,0,0), Node::TS_WORLD, Vector3::UNIT_Z); +// mTestNode[0]->attachObject(mLight); +// +// +// mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// +// +// Entity* pEnt; +// pEnt = mSceneMgr->createEntity( "1", "robot.mesh" ); +// //pEnt->setRenderingDistance(100); +// mAnimState = pEnt->getAnimationState("Walk"); +// mAnimState->setEnabled(true); +// //pEnt->setMaterialName("2 - Default"); +// mTestNode[1]->attachObject( pEnt ); +// mTestNode[1]->translate(0,-100,0); +// +// pEnt = mSceneMgr->createEntity( "3", "knot.mesh" ); +// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-200, 0, -200)); +// mTestNode[2]->attachObject( pEnt ); +// +// // Transparent object (can force cast shadows) +// pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" ); +// MaterialPtr tmat = MaterialManager::getSingleton().create("TestAlphaTransparency", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// tmat->setTransparencyCastsShadows(true); +// Pass* tpass = tmat->getTechnique(0)->getPass(0); +// tpass->setAlphaRejectSettings(CMPF_GREATER, 150); +// tpass->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// tpass->createTextureUnitState("gras_02.png"); +// tpass->setCullingMode(CULL_NONE); +// +// pEnt->setMaterialName("TestAlphaTransparency"); +// mTestNode[3] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(350, 0, -200)); +// mTestNode[3]->attachObject( pEnt ); +// +// MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// msh->buildTangentVectors(VES_TANGENT, 0, 0); +// pEnt = mSceneMgr->createEntity( "4", "knot.mesh" ); +// //pEnt->setMaterialName("Examples/BumpMapping/MultiLightSpecular"); +// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 200)); +// mTestNode[2]->attachObject( pEnt ); +// +// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); +// +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt; +// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// // Set up a debug panel to display the shadow +// addTextureShadowDebugOverlay(1); +// +// +// +// ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("smoke", +// "Examples/Smoke"); +// mTestNode[4] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-300, -100, 200)); +// mTestNode[4]->attachObject(pSys2); +// +// TexturePtr shadowTex = mSceneMgr->getShadowTexture(0); +// RenderTarget* shadowRtt = shadowTex->getBuffer()->getRenderTarget(); +// Viewport* vp = shadowRtt->getViewport(0); +// Ogre::CompositorInstance *instance = +// CompositorManager::getSingleton().addCompositor(vp, "Gaussian Blur"); +// CompositorManager::getSingleton().setCompositorEnabled( +// vp, "Gaussian Blur", true); +// instance->addListener(&gaussianListener); +// gaussianListener.notifyViewportSize(vp->getActualWidth(), vp->getActualHeight()); +// +// +// +// +// +// } +// +// void testCompositorTechniqueSwitch(bool sharedTextures) +// { +// CompositorManager& cmgr = CompositorManager::getSingleton(); +// CompositorPtr compositor = cmgr.create("testtechswitch", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// // technique 1 (Invert) +// CompositionTechnique* ctech1 = compositor->createTechnique(); +// CompositionTechnique::TextureDefinition* tdef = ctech1->createTextureDefinition("rt0"); +// tdef->formatList.push_back(PF_A8B8G8R8); +// tdef->width = tdef->height = 0; +// tdef->pooled = sharedTextures; +// +// CompositionTargetPass* tpass = ctech1->createTargetPass(); +// tpass->setOutputName("rt0"); +// tpass->setInputMode(CompositionTargetPass::IM_PREVIOUS); +// CompositionTargetPass* tout = ctech1->getOutputTargetPass(); +// tout->setInputMode(CompositionTargetPass::IM_NONE); +// CompositionPass* pass = tout->createPass(); +// pass->setType(CompositionPass::PT_RENDERQUAD); +// pass->setMaterialName("Ogre/Compositor/Invert"); +// pass->setInput(0, "rt0"); +// +// // technique 2 (Tiling) +// ctech1 = compositor->createTechnique(); +// ctech1->setSchemeName("Tiling"); +// tdef = ctech1->createTextureDefinition("rt0"); +// tdef->formatList.push_back(PF_A8B8G8R8); +// tdef->width = tdef->height = 0; +// tdef->pooled = sharedTextures; +// +// tpass = ctech1->createTargetPass(); +// tpass->setOutputName("rt0"); +// tpass->setInputMode(CompositionTargetPass::IM_PREVIOUS); +// tout = ctech1->getOutputTargetPass(); +// tout->setInputMode(CompositionTargetPass::IM_NONE); +// pass = tout->createPass(); +// pass->setType(CompositionPass::PT_RENDERQUAD); +// pass->setMaterialName("Ogre/Compositor/Tiling"); +// pass->setInput(0, "rt0"); +// +// compositor->load(); +// +// Entity* e = mSceneMgr->createEntity("1", "knot.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 1000); // -// // enable compositor (should pick first technique) -// Viewport* vp = mWindow->getViewport(0); +// // enable compositor (should pick first technique) +// Viewport* vp = mWindow->getViewport(0); // -// compositorToSwitch = cmgr.addCompositor(vp, compositor->getName()); -// compositorSchemeList.push_back(""); -// compositorSchemeList.push_back("Tiling"); +// compositorToSwitch = cmgr.addCompositor(vp, compositor->getName()); +// compositorSchemeList.push_back(""); +// compositorSchemeList.push_back("Tiling"); // -// cmgr.setCompositorEnabled(vp, compositor->getName(), true); +// cmgr.setCompositorEnabled(vp, compositor->getName(), true); // -// mCamera->setPosition(0, 0, -300); -// mCamera->lookAt(Vector3::ZERO); +// mCamera->setPosition(0, 0, -300); +// mCamera->lookAt(Vector3::ZERO); // // // -// } +// } // // void testOverlayZOrder(void) // { @@ -3488,340 +3488,340 @@ extern "C" _OgreSampleExport void dllStopPlugin() // createRandomEntityClones(ent, 100, Vector3(-1000,-1000,-1000), Vector3(1000,1000,1000)); // // rayQuery = mSceneMgr->createRayQuery( -// mCamera->getCameraToViewportRay(0.5, 0.5)); +// mCamera->getCameraToViewportRay(0.5, 0.5)); // rayQuery->setSortByDistance(true, 1); // // bool val = true; // mSceneMgr->setOption("ShowOctree", &val); // -// //mCamera->setFarClipDistance(0); +// //mCamera->setFarClipDistance(0); // // } // -// void testLotsAndLotsOfEntities() -// { -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// -// // Create a point light -// Light* l = mSceneMgr->createLight("MainLight"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(-Vector3::UNIT_Y); -// -// // Create a set of random balls -// Entity* ent = mSceneMgr->createEntity("Ball", "cube.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// createRandomEntityClones(ent, 3000, Vector3(-1000,-1000,-1000), Vector3(1000,1000,1000)); -// -// //bool val = true; -// //mSceneMgr->setOption("ShowOctree", &val); -// -// mCamera->setPosition(0,0, -4000); -// mCamera->lookAt(Vector3::ZERO); -// -// // enable the profiler -// Profiler* prof = Profiler::getSingletonPtr(); -// if (prof) -// prof->setEnabled(true); -// -// -// } -// -// void testSimpleMesh() -// { -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// -// // Create a point light -// Light* l = mSceneMgr->createLight("MainLight"); -// l->setType(Light::LT_DIRECTIONAL); -// Vector3 dir(1, -1, 0); -// dir.normalise(); -// l->setDirection(dir); -// -// // Create a set of random balls -// Entity* ent = mSceneMgr->createEntity("test", "xsicylinder.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// -// } -// -// void testGLSLTangent() -// { -// -// Entity* ent = mSceneMgr->createEntity("test", "athene.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// ent->setMaterialName("testglsl"); -// } -// -// void testInfiniteAAB() -// { -// // When using the BspSceneManager -// //mSceneMgr->setWorldGeometry("ogretestmap.bsp"); -// -// // When using the TerrainSceneManager -// mSceneMgr->setWorldGeometry("terrain.cfg"); -// -// AxisAlignedBox b1; // null -// assert( b1.isNull() ); -// -// AxisAlignedBox b2(Vector3::ZERO, 5.0 * Vector3::UNIT_SCALE); // finite -// assert( b2.isFinite() ); -// -// AxisAlignedBox b3; -// b3.setInfinite(); -// assert( b3.isInfinite() ); -// -// { -// // Create background material -// MaterialPtr material = MaterialManager::getSingleton().create("Background", "General"); -// material->getTechnique(0)->getPass(0)->createTextureUnitState("rockwall.tga"); -// material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); -// material->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); -// material->getTechnique(0)->getPass(0)->setLightingEnabled(false); -// -// // Create left background rectangle -// // NOTE: Uses finite aab -// Rectangle2D* rect1 = new Rectangle2D(true); -// rect1->setCorners(-0.5, 0.1, -0.1, -0.1); -// // Hacky, set small bounding box, to show problem -// rect1->setBoundingBox(AxisAlignedBox(-10.0*Vector3::UNIT_SCALE, 10.0*Vector3::UNIT_SCALE)); -// rect1->setMaterial("Background"); -// rect1->setRenderQueueGroup(RENDER_QUEUE_OVERLAY - 1); -// SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode("Background1"); -// node->attachObject(rect1); -// -// // Create right background rectangle -// // NOTE: Uses infinite aab -// Rectangle2D* rect2 = new Rectangle2D(true); -// rect2->setCorners(0.1, 0.1, 0.5, -0.1); -// AxisAlignedBox aabInf; aabInf.setInfinite(); -// rect2->setBoundingBox(aabInf); -// rect2->setMaterial("Background"); -// rect2->setRenderQueueGroup(RENDER_QUEUE_OVERLAY - 1); -// node = mSceneMgr->getRootSceneNode()->createChildSceneNode("Background2"); -// node->attachObject(rect2); -// -// // Create a manual object for 2D -// ManualObject* manual = mSceneMgr->createManualObject("manual"); -// manual->setUseIdentityProjection(true); -// manual->setUseIdentityView(true); -// manual->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); -// manual->position(-0.2, -0.2, 0.0); -// manual->position( 0.2, -0.2, 0.0); -// manual->position( 0.2, 0.2, 0.0); -// manual->position(-0.2, 0.2, 0.0); -// manual->index(0); -// manual->index(1); -// manual->index(2); -// manual->index(3); -// manual->index(0); -// manual->end(); -// manual->setBoundingBox(aabInf); // Use infinite aab to always stay visible -// rect2->setRenderQueueGroup(RENDER_QUEUE_OVERLAY - 1); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual); -// } -// -// mSceneMgr->showBoundingBoxes(true); -// -// Entity* ent = mSceneMgr->createEntity("test", "ogrehead.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// "test", 50.0 * Vector3::UNIT_X)->attachObject(ent); -// } -// -// void test2Windows(void) -// { -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// -// // Create a point light -// Light* l = mSceneMgr->createLight("MainLight"); -// l->setType(Light::LT_DIRECTIONAL); -// Vector3 dir(1, -1, 0); -// dir.normalise(); -// l->setDirection(dir); -// -// Entity* ent = mSceneMgr->createEntity("head", "robot.mesh"); -// AnimationState* a = ent->getAnimationState("Walk"); -// a->setEnabled(true); -// mAnimStateList.push_back(a); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// -// NameValuePairList valuePair; -// valuePair["top"] = StringConverter::toString(0); -// valuePair["left"] = StringConverter::toString(0); -// -// RenderWindow* win2 = mRoot->createRenderWindow("window2", 800,600, false, &valuePair); -// win2->addViewport(mCamera); -// -// mCamera->setPosition(0,0,-300); -// mCamera->lookAt(Vector3::ZERO); -// -// -// -// } -// -// void testStaticGeometry(void) -// { -// -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0, 0, 0)); -// -// // Create a point light -// Light* l = mSceneMgr->createLight("MainLight"); -// l->setDiffuseColour(0.4, 0.4, 0.4); -// l->setSpecularColour(ColourValue::White); -// -// SceneNode* animNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// Animation* anim = mSceneMgr->createAnimation("an1", 20); -// anim->setInterpolationMode(Animation::IM_SPLINE); -// NodeAnimationTrack* track = anim->createNodeTrack(1, animNode); -// TransformKeyFrame* kf = track->createNodeKeyFrame(0); -// kf->setTranslate(Vector3(2300, 600, 2300)); -// kf = track->createNodeKeyFrame(5); -// kf->setTranslate(Vector3(-2300, 600, 2300)); -// kf = track->createNodeKeyFrame(10); -// kf->setTranslate(Vector3(-2300, 600, -2300)); -// kf = track->createNodeKeyFrame(15); -// kf->setTranslate(Vector3(2300, 600, -2300)); -// kf = track->createNodeKeyFrame(20); -// kf->setTranslate(Vector3(2300, 600, 2300)); -// -// //animNode->attachObject(l); -// l->setPosition(0, 600, 0); -// l->setAttenuation(10000, 1, 0, 0); -// -// AnimationState* animState = mSceneMgr->createAnimationState("an1"); -// animState->setEnabled(true); -// mAnimStateList.push_back(animState); -// -// -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 0; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("Examples/GrassFloor"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// Vector3 min(-2000,30,-2000); -// Vector3 max(2000,30,2000); -// -// -// MeshPtr msh = MeshManager::getSingleton().load("ogrehead.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// msh->buildTangentVectors(); -// -// Entity* e = mSceneMgr->createEntity("1", "ogrehead.mesh"); -// e->setMaterialName("Examples/BumpMapping/MultiLightSpecular"); -// -// StaticGeometry* s = mSceneMgr->createStaticGeometry("bing"); -// s->setCastShadows(true); -// s->setRegionDimensions(Vector3(500,500,500)); -// for (int i = 0; i < 10; ++i) -// { -// Vector3 pos; -// pos.x = Math::RangeRandom(min.x, max.x); -// pos.y = Math::RangeRandom(min.y, max.y); -// pos.z = Math::RangeRandom(min.z, max.z); +// void testLotsAndLotsOfEntities() +// { +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// +// // Create a point light +// Light* l = mSceneMgr->createLight("MainLight"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(-Vector3::UNIT_Y); +// +// // Create a set of random balls +// Entity* ent = mSceneMgr->createEntity("Ball", "cube.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// createRandomEntityClones(ent, 3000, Vector3(-1000,-1000,-1000), Vector3(1000,1000,1000)); +// +// //bool val = true; +// //mSceneMgr->setOption("ShowOctree", &val); +// +// mCamera->setPosition(0,0, -4000); +// mCamera->lookAt(Vector3::ZERO); +// +// // enable the profiler +// Profiler* prof = Profiler::getSingletonPtr(); +// if (prof) +// prof->setEnabled(true); +// +// +// } +// +// void testSimpleMesh() +// { +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// +// // Create a point light +// Light* l = mSceneMgr->createLight("MainLight"); +// l->setType(Light::LT_DIRECTIONAL); +// Vector3 dir(1, -1, 0); +// dir.normalise(); +// l->setDirection(dir); +// +// // Create a set of random balls +// Entity* ent = mSceneMgr->createEntity("test", "xsicylinder.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// +// } +// +// void testGLSLTangent() +// { +// +// Entity* ent = mSceneMgr->createEntity("test", "athene.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// ent->setMaterialName("testglsl"); +// } +// +// void testInfiniteAAB() +// { +// // When using the BspSceneManager +// //mSceneMgr->setWorldGeometry("ogretestmap.bsp"); +// +// // When using the TerrainSceneManager +// mSceneMgr->setWorldGeometry("terrain.cfg"); +// +// AxisAlignedBox b1; // null +// assert( b1.isNull() ); +// +// AxisAlignedBox b2(Vector3::ZERO, 5.0 * Vector3::UNIT_SCALE); // finite +// assert( b2.isFinite() ); +// +// AxisAlignedBox b3; +// b3.setInfinite(); +// assert( b3.isInfinite() ); +// +// { +// // Create background material +// MaterialPtr material = MaterialManager::getSingleton().create("Background", "General"); +// material->getTechnique(0)->getPass(0)->createTextureUnitState("rockwall.tga"); +// material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); +// material->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); +// material->getTechnique(0)->getPass(0)->setLightingEnabled(false); +// +// // Create left background rectangle +// // NOTE: Uses finite aab +// Rectangle2D* rect1 = new Rectangle2D(true); +// rect1->setCorners(-0.5, 0.1, -0.1, -0.1); +// // Hacky, set small bounding box, to show problem +// rect1->setBoundingBox(AxisAlignedBox(-10.0*Vector3::UNIT_SCALE, 10.0*Vector3::UNIT_SCALE)); +// rect1->setMaterial("Background"); +// rect1->setRenderQueueGroup(RENDER_QUEUE_OVERLAY - 1); +// SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode("Background1"); +// node->attachObject(rect1); +// +// // Create right background rectangle +// // NOTE: Uses infinite aab +// Rectangle2D* rect2 = new Rectangle2D(true); +// rect2->setCorners(0.1, 0.1, 0.5, -0.1); +// AxisAlignedBox aabInf; aabInf.setInfinite(); +// rect2->setBoundingBox(aabInf); +// rect2->setMaterial("Background"); +// rect2->setRenderQueueGroup(RENDER_QUEUE_OVERLAY - 1); +// node = mSceneMgr->getRootSceneNode()->createChildSceneNode("Background2"); +// node->attachObject(rect2); +// +// // Create a manual object for 2D +// ManualObject* manual = mSceneMgr->createManualObject("manual"); +// manual->setUseIdentityProjection(true); +// manual->setUseIdentityView(true); +// manual->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); +// manual->position(-0.2, -0.2, 0.0); +// manual->position( 0.2, -0.2, 0.0); +// manual->position( 0.2, 0.2, 0.0); +// manual->position(-0.2, 0.2, 0.0); +// manual->index(0); +// manual->index(1); +// manual->index(2); +// manual->index(3); +// manual->index(0); +// manual->end(); +// manual->setBoundingBox(aabInf); // Use infinite aab to always stay visible +// rect2->setRenderQueueGroup(RENDER_QUEUE_OVERLAY - 1); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual); +// } +// +// mSceneMgr->showBoundingBoxes(true); +// +// Entity* ent = mSceneMgr->createEntity("test", "ogrehead.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// "test", 50.0 * Vector3::UNIT_X)->attachObject(ent); +// } +// +// void test2Windows(void) +// { +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// +// // Create a point light +// Light* l = mSceneMgr->createLight("MainLight"); +// l->setType(Light::LT_DIRECTIONAL); +// Vector3 dir(1, -1, 0); +// dir.normalise(); +// l->setDirection(dir); +// +// Entity* ent = mSceneMgr->createEntity("head", "robot.mesh"); +// AnimationState* a = ent->getAnimationState("Walk"); +// a->setEnabled(true); +// mAnimStateList.push_back(a); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// +// NameValuePairList valuePair; +// valuePair["top"] = StringConverter::toString(0); +// valuePair["left"] = StringConverter::toString(0); +// +// RenderWindow* win2 = mRoot->createRenderWindow("window2", 800,600, false, &valuePair); +// win2->addViewport(mCamera); +// +// mCamera->setPosition(0,0,-300); +// mCamera->lookAt(Vector3::ZERO); +// +// +// +// } +// +// void testStaticGeometry(void) +// { +// +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0, 0, 0)); +// +// // Create a point light +// Light* l = mSceneMgr->createLight("MainLight"); +// l->setDiffuseColour(0.4, 0.4, 0.4); +// l->setSpecularColour(ColourValue::White); +// +// SceneNode* animNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// Animation* anim = mSceneMgr->createAnimation("an1", 20); +// anim->setInterpolationMode(Animation::IM_SPLINE); +// NodeAnimationTrack* track = anim->createNodeTrack(1, animNode); +// TransformKeyFrame* kf = track->createNodeKeyFrame(0); +// kf->setTranslate(Vector3(2300, 600, 2300)); +// kf = track->createNodeKeyFrame(5); +// kf->setTranslate(Vector3(-2300, 600, 2300)); +// kf = track->createNodeKeyFrame(10); +// kf->setTranslate(Vector3(-2300, 600, -2300)); +// kf = track->createNodeKeyFrame(15); +// kf->setTranslate(Vector3(2300, 600, -2300)); +// kf = track->createNodeKeyFrame(20); +// kf->setTranslate(Vector3(2300, 600, 2300)); +// +// //animNode->attachObject(l); +// l->setPosition(0, 600, 0); +// l->setAttenuation(10000, 1, 0, 0); +// +// AnimationState* animState = mSceneMgr->createAnimationState("an1"); +// animState->setEnabled(true); +// mAnimStateList.push_back(animState); +// +// +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 0; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("Examples/GrassFloor"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// Vector3 min(-2000,30,-2000); +// Vector3 max(2000,30,2000); +// +// +// MeshPtr msh = MeshManager::getSingleton().load("ogrehead.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// msh->buildTangentVectors(); +// +// Entity* e = mSceneMgr->createEntity("1", "ogrehead.mesh"); +// e->setMaterialName("Examples/BumpMapping/MultiLightSpecular"); +// +// StaticGeometry* s = mSceneMgr->createStaticGeometry("bing"); +// s->setCastShadows(true); +// s->setRegionDimensions(Vector3(500,500,500)); +// for (int i = 0; i < 10; ++i) +// { +// Vector3 pos; +// pos.x = Math::RangeRandom(min.x, max.x); +// pos.y = Math::RangeRandom(min.y, max.y); +// pos.z = Math::RangeRandom(min.z, max.z); // -// s->addEntity(e, pos); -// Entity* e2 = e->clone("clone" + StringConverter::toString(i)); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(pos+Vector3(0,60,0))->attachObject(e2); +// s->addEntity(e, pos); +// Entity* e2 = e->clone("clone" + StringConverter::toString(i)); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(pos+Vector3(0,60,0))->attachObject(e2); // -// } +// } // -// s->build(); -// mCamera->setLodBias(0.5); +// s->build(); +// mCamera->setLodBias(0.5); // -// //mTestNode[0] = s->getRegionIterator().getNext()->getParentSceneNode(); +// //mTestNode[0] = s->getRegionIterator().getNext()->getParentSceneNode(); // // // -// +// // // // -// } +// } // -// void testStaticGeometryWithLOD(bool stencilShadows) -// { -// if (stencilShadows) -// { -// mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); -// } -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0, 0, 0)); +// void testStaticGeometryWithLOD(bool stencilShadows) +// { +// if (stencilShadows) +// { +// mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); +// } +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0, 0, 0)); // -// // Create a point light -// Light* l = mSceneMgr->createLight("MainLight"); -// l->setDiffuseColour(0.4, 0.4, 0.4); -// l->setSpecularColour(ColourValue::White); +// // Create a point light +// Light* l = mSceneMgr->createLight("MainLight"); +// l->setDiffuseColour(0.4, 0.4, 0.4); +// l->setSpecularColour(ColourValue::White); // -// SceneNode* animNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// Animation* anim = mSceneMgr->createAnimation("an1", 20); -// anim->setInterpolationMode(Animation::IM_SPLINE); -// NodeAnimationTrack* track = anim->createNodeTrack(1, animNode); -// TransformKeyFrame* kf = track->createNodeKeyFrame(0); -// kf->setTranslate(Vector3(2300, 600, 2300)); -// kf = track->createNodeKeyFrame(5); -// kf->setTranslate(Vector3(-2300, 600, 2300)); -// kf = track->createNodeKeyFrame(10); -// kf->setTranslate(Vector3(-2300, 600, -2300)); -// kf = track->createNodeKeyFrame(15); -// kf->setTranslate(Vector3(2300, 600, -2300)); -// kf = track->createNodeKeyFrame(20); -// kf->setTranslate(Vector3(2300, 600, 2300)); +// SceneNode* animNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// Animation* anim = mSceneMgr->createAnimation("an1", 20); +// anim->setInterpolationMode(Animation::IM_SPLINE); +// NodeAnimationTrack* track = anim->createNodeTrack(1, animNode); +// TransformKeyFrame* kf = track->createNodeKeyFrame(0); +// kf->setTranslate(Vector3(2300, 600, 2300)); +// kf = track->createNodeKeyFrame(5); +// kf->setTranslate(Vector3(-2300, 600, 2300)); +// kf = track->createNodeKeyFrame(10); +// kf->setTranslate(Vector3(-2300, 600, -2300)); +// kf = track->createNodeKeyFrame(15); +// kf->setTranslate(Vector3(2300, 600, -2300)); +// kf = track->createNodeKeyFrame(20); +// kf->setTranslate(Vector3(2300, 600, 2300)); // -// //animNode->attachObject(l); -// l->setPosition(0, 600, 0); -// l->setAttenuation(10000, 1, 0, 0); +// //animNode->attachObject(l); +// l->setPosition(0, 600, 0); +// l->setAttenuation(10000, 1, 0, 0); // -// AnimationState* animState = mSceneMgr->createAnimationState("an1"); -// animState->setEnabled(true); -// mAnimStateList.push_back(animState); +// AnimationState* animState = mSceneMgr->createAnimationState("an1"); +// animState->setEnabled(true); +// mAnimStateList.push_back(animState); // // // -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 0; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("Examples/GrassFloor"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 0; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("Examples/GrassFloor"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); // -// Vector3 min(-2000,30,-2000); -// Vector3 max(2000,30,2000); +// Vector3 min(-2000,30,-2000); +// Vector3 max(2000,30,2000); // // -// MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// -// Entity* e = mSceneMgr->createEntity("1", msh->getName()); +// MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// +// Entity* e = mSceneMgr->createEntity("1", msh->getName()); // -// StaticGeometry* s = mSceneMgr->createStaticGeometry("bing"); -// s->setCastShadows(true); -// s->setRegionDimensions(Vector3(500,500,500)); -// for (int i = 0; i < 10; ++i) -// { -// Vector3 pos; -// pos.x = Math::RangeRandom(min.x, max.x); -// pos.y = Math::RangeRandom(min.y, max.y); -// pos.z = Math::RangeRandom(min.z, max.z); +// StaticGeometry* s = mSceneMgr->createStaticGeometry("bing"); +// s->setCastShadows(true); +// s->setRegionDimensions(Vector3(500,500,500)); +// for (int i = 0; i < 10; ++i) +// { +// Vector3 pos; +// pos.x = Math::RangeRandom(min.x, max.x); +// pos.y = Math::RangeRandom(min.y, max.y); +// pos.z = Math::RangeRandom(min.z, max.z); // -// s->addEntity(e, pos); +// s->addEntity(e, pos); // -// } +// } // -// s->build(); -// mCamera->setLodBias(0.5); +// s->build(); +// mCamera->setLodBias(0.5); // -// //mTestNode[0] = s->getRegionIterator().getNext()->getParentSceneNode(); +// //mTestNode[0] = s->getRegionIterator().getNext()->getParentSceneNode(); // // // @@ -3829,1986 +3829,1986 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // // -// } +// } // -// void testReloadResources() -// { -// mSceneMgr->setAmbientLight(ColourValue::White); -// ResourceGroupManager::getSingleton().createResourceGroup("Sinbad"); -// Root::getSingleton().addResourceLocation("../../../Media/models", "FileSystem", "Sinbad"); -// MeshManager& mmgr = MeshManager::getSingleton(); -// mmgr.load("robot.mesh", "Sinbad"); -// mmgr.load("knot.mesh", "Sinbad"); +// void testReloadResources() +// { +// mSceneMgr->setAmbientLight(ColourValue::White); +// ResourceGroupManager::getSingleton().createResourceGroup("Sinbad"); +// Root::getSingleton().addResourceLocation("../../../Media/models", "FileSystem", "Sinbad"); +// MeshManager& mmgr = MeshManager::getSingleton(); +// mmgr.load("robot.mesh", "Sinbad"); +// mmgr.load("knot.mesh", "Sinbad"); // -// Entity* e = mSceneMgr->createEntity("1", "robot.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// e = mSceneMgr->createEntity("2", "robot.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,0,0))->attachObject(e); -// e = mSceneMgr->createEntity("3", "knot.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,300,0))->attachObject(e); +// Entity* e = mSceneMgr->createEntity("1", "robot.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// e = mSceneMgr->createEntity("2", "robot.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,0,0))->attachObject(e); +// e = mSceneMgr->createEntity("3", "knot.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,300,0))->attachObject(e); // -// testreload = true; +// testreload = true; // -// } +// } // -// void testBillboardTextureCoords() -// { -// mSceneMgr->setAmbientLight(ColourValue::White); +// void testBillboardTextureCoords() +// { +// mSceneMgr->setAmbientLight(ColourValue::White); // -// BillboardSet* bbs = mSceneMgr->createBillboardSet("test"); +// BillboardSet* bbs = mSceneMgr->createBillboardSet("test"); // BillboardSet* bbs2 = mSceneMgr->createBillboardSet("test2"); -// float xsegs = 3; -// float ysegs = 3; -// float width = 300; -// float height = 300; -// float gap = 20; -// -// // set up texture coords -// bbs->setTextureStacksAndSlices(ysegs, xsegs); -// bbs->setDefaultDimensions(width/xsegs, height/xsegs); -// bbs2->setDefaultDimensions(width/xsegs, height/xsegs); -// -// for (float y = 0; y < ysegs; ++y) -// { -// for (float x = 0; x < xsegs; ++x) -// { -// Vector3 midPoint; -// midPoint.x = (x * width / xsegs) + ((x-1) * gap); -// midPoint.y = (y * height / ysegs) + ((y-1) * gap); -// midPoint.z = 0; -// Billboard* bb = bbs->createBillboard(midPoint); -// bb->setTexcoordIndex((ysegs - y - 1)*xsegs + x); +// float xsegs = 3; +// float ysegs = 3; +// float width = 300; +// float height = 300; +// float gap = 20; +// +// // set up texture coords +// bbs->setTextureStacksAndSlices(ysegs, xsegs); +// bbs->setDefaultDimensions(width/xsegs, height/xsegs); +// bbs2->setDefaultDimensions(width/xsegs, height/xsegs); +// +// for (float y = 0; y < ysegs; ++y) +// { +// for (float x = 0; x < xsegs; ++x) +// { +// Vector3 midPoint; +// midPoint.x = (x * width / xsegs) + ((x-1) * gap); +// midPoint.y = (y * height / ysegs) + ((y-1) * gap); +// midPoint.z = 0; +// Billboard* bb = bbs->createBillboard(midPoint); +// bb->setTexcoordIndex((ysegs - y - 1)*xsegs + x); // Billboard* bb2 = bbs2->createBillboard(midPoint); // bb2->setTexcoordRect( // FloatRect((x + 0) / xsegs, (ysegs - y - 1) / ysegs, // (x + 1) / xsegs, (ysegs - y - 0) / ysegs)); -// } -// } +// } +// } // -// bbs->setMaterialName("Examples/OgreLogo"); +// bbs->setMaterialName("Examples/OgreLogo"); // bbs2->setMaterialName("Examples/OgreLogo"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(bbs); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(bbs); // mSceneMgr->getRootSceneNode() // ->createChildSceneNode(Vector3(- (width + xsegs * gap), 0, 0)) // ->attachObject(bbs2); // -// } -// -// class SortFunctor -// { -// public: -// int operator()(const int& p) const -// { -// return p; -// } -// -// }; -// void testRadixSort() -// { -// RadixSort::type, int, int> rs; -// SortFunctor f; -// -// list::type particles; -// for (int r = 0; r < 20; ++r) -// { -// particles.push_back((int)Math::RangeRandom(-1e3f, 1e3f)); -// } -// -// list::type::iterator i; -// LogManager::getSingleton().logMessage("BEFORE"); -// for (i = particles.begin(); i != particles.end(); ++i) -// LogManager::getSingleton().stream() << *i; -// -// rs.sort(particles, f); -// -// -// LogManager::getSingleton().logMessage("AFTER"); -// for (i = particles.begin(); i != particles.end(); ++i) -// LogManager::getSingleton().stream() << *i; -// -// -// -// } -// -// void testMorphAnimation() -// { -// bool testStencil = true; -// -// if (testStencil) -// mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); -// -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// Light* l = mSceneMgr->createLight("light1"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(dir); -// -// -// MeshPtr mesh = MeshManager::getSingleton().load("cube.mesh", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// -// SubMesh* sm = mesh->getSubMesh(0); -// // Re-organise geometry since this mesh has no animation and all -// // vertex elements are packed into one buffer -// VertexDeclaration* newDecl = -// sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true); -// sm->vertexData->reorganiseBuffers(newDecl); -// if (testStencil) -// sm->vertexData->prepareForShadowVolume(); // need to re-prep since reorganised -// // get the position buffer (which should now be separate); -// const VertexElement* posElem = -// sm->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); -// HardwareVertexBufferSharedPtr origbuf = -// sm->vertexData->vertexBufferBinding->getBuffer( -// posElem->getSource()); -// -// // Create a new position buffer with updated values -// HardwareVertexBufferSharedPtr newbuf = -// HardwareBufferManager::getSingleton().createVertexBuffer( -// VertexElement::getTypeSize(VET_FLOAT3), -// sm->vertexData->vertexCount, -// HardwareBuffer::HBU_STATIC, true); -// float* pSrc = static_cast(origbuf->lock(HardwareBuffer::HBL_READ_ONLY)); -// float* pDst = static_cast(newbuf->lock(HardwareBuffer::HBL_DISCARD)); -// -// for (size_t v = 0; v < sm->vertexData->vertexCount; ++v) -// { -// // x -// *pDst++ = *pSrc++; -// // y (translate) -// *pDst++ = (*pSrc++) + 100.0f; -// // z -// *pDst++ = *pSrc++; -// } -// -// origbuf->unlock(); -// newbuf->unlock(); -// -// // create a morph animation -// Animation* anim = mesh->createAnimation("testAnim", 10.0f); -// VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_MORPH); -// // re-use start positions for frame 0 -// VertexMorphKeyFrame* kf = vt->createVertexMorphKeyFrame(0); -// kf->setVertexBuffer(origbuf); -// -// // Use translated buffer for mid frame -// kf = vt->createVertexMorphKeyFrame(5.0f); -// kf->setVertexBuffer(newbuf); -// -// // re-use start positions for final frame -// kf = vt->createVertexMorphKeyFrame(10.0f); -// kf->setVertexBuffer(origbuf); -// -// // write -// MeshSerializer ser; -// ser.exportMesh(mesh.get(), "../../../Media/testmorph.mesh"); -// -// -// Entity* e = mSceneMgr->createEntity("test", "testmorph.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// AnimationState* animState = e->getAnimationState("testAnim"); -// animState->setEnabled(true); -// animState->setWeight(1.0f); -// mAnimStateList.push_back(animState); -// -// e = mSceneMgr->createEntity("test2", "testmorph.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,0,0))->attachObject(e); -// // test hardware morph -// e->setMaterialName("Examples/HardwareMorphAnimation"); -// animState = e->getAnimationState("testAnim"); -// animState->setEnabled(true); -// animState->setWeight(1.0f); -// mAnimStateList.push_back(animState); -// -// mCamera->setNearClipDistance(0.5); -// //mSceneMgr->setShowDebugShadows(true); -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 200; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// -// -// } -// -// -// void testPoseAnimation() -// { -// bool testStencil = false; -// -// if (testStencil) -// mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); -// -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// Light* l = mSceneMgr->createLight("light1"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(dir); -// -// MeshPtr mesh = MeshManager::getSingleton().load("cube.mesh", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// -// SubMesh* sm = mesh->getSubMesh(0); -// // Re-organise geometry since this mesh has no animation and all -// // vertex elements are packed into one buffer -// VertexDeclaration* newDecl = -// sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true); -// sm->vertexData->reorganiseBuffers(newDecl); -// if (testStencil) -// sm->vertexData->prepareForShadowVolume(); // need to re-prep since reorganised -// // get the position buffer (which should now be separate); -// const VertexElement* posElem = -// sm->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); -// HardwareVertexBufferSharedPtr origbuf = -// sm->vertexData->vertexBufferBinding->getBuffer( -// posElem->getSource()); -// -// -// // create 2 poses -// Pose* pose = mesh->createPose(1, "pose1"); -// // Pose1 moves vertices 0, 1, 2 and 3 upward -// Vector3 offset1(0, 50, 0); -// pose->addVertex(0, offset1); -// pose->addVertex(1, offset1); -// pose->addVertex(2, offset1); -// pose->addVertex(3, offset1); -// -// pose = mesh->createPose(1, "pose2"); -// // Pose2 moves vertices 3, 4, and 5 to the right -// // Note 3 gets affected by both -// Vector3 offset2(100, 0, 0); -// pose->addVertex(3, offset2); -// pose->addVertex(4, offset2); -// pose->addVertex(5, offset2); -// -// -// Animation* anim = mesh->createAnimation("poseanim", 20.0f); -// VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_POSE); -// -// // Frame 0 - no effect -// VertexPoseKeyFrame* kf = vt->createVertexPoseKeyFrame(0); -// -// // Frame 1 - bring in pose 1 (index 0) -// kf = vt->createVertexPoseKeyFrame(3); -// kf->addPoseReference(0, 1.0f); -// -// // Frame 2 - remove all -// kf = vt->createVertexPoseKeyFrame(6); -// -// // Frame 3 - bring in pose 2 (index 1) -// kf = vt->createVertexPoseKeyFrame(9); -// kf->addPoseReference(1, 1.0f); -// -// // Frame 4 - remove all -// kf = vt->createVertexPoseKeyFrame(12); -// -// -// // Frame 5 - bring in pose 1 at 50%, pose 2 at 100% -// kf = vt->createVertexPoseKeyFrame(15); -// kf->addPoseReference(0, 0.5f); -// kf->addPoseReference(1, 1.0f); -// -// // Frame 6 - bring in pose 1 at 100%, pose 2 at 50% -// kf = vt->createVertexPoseKeyFrame(18); -// kf->addPoseReference(0, 1.0f); -// kf->addPoseReference(1, 0.5f); -// -// // Frame 7 - reset -// kf = vt->createVertexPoseKeyFrame(20); -// -// // write -// MeshSerializer ser; -// ser.exportMesh(mesh.get(), "../../../Media/testpose.mesh"); -// -// -// Entity* e; -// AnimationState* animState; -// // software pose -// e = mSceneMgr->createEntity("test2", "testpose.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(150,0,0))->attachObject(e); -// animState = e->getAnimationState("poseanim"); -// animState->setEnabled(true); -// animState->setWeight(1.0f); -// mAnimStateList.push_back(animState); -// -// // test hardware pose -// e = mSceneMgr->createEntity("test", "testpose.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// e->setMaterialName("Examples/HardwarePoseAnimation"); -// animState = e->getAnimationState("poseanim"); -// animState->setEnabled(true); -// animState->setWeight(1.0f); -// mAnimStateList.push_back(animState); -// -// -// mCamera->setNearClipDistance(0.5); -// mSceneMgr->setShowDebugShadows(true); -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 200; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// mCamera->setPosition(0,0,-300); -// mCamera->lookAt(0,0,0); -// -// -// -// } -// -// void testPoseAnimation2() -// { -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// Vector3 dir(-1, -1, -0.5); -// dir.normalise(); -// Light* l = mSceneMgr->createLight("light1"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(dir); -// -// /* -// MeshPtr mesh = MeshManager::getSingleton().load("facial.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Animation* anim = mesh->createAnimation("pose", 20); -// VertexAnimationTrack* track = anim->createVertexTrack(4, VAT_POSE); -// // Frame 0 - no effect -// VertexPoseKeyFrame* kf = track->createVertexPoseKeyFrame(0); -// -// // bring in pose 4 (happy) -// kf = track->createVertexPoseKeyFrame(5); -// kf->addPoseReference(4, 1.0f); -// -// // bring in pose 5 (sad) -// kf = track->createVertexPoseKeyFrame(10); -// kf->addPoseReference(5, 1.0f); -// -// // bring in pose 6 (mad) -// kf = track->createVertexPoseKeyFrame(15); -// kf->addPoseReference(6, 1.0f); -// -// kf = track->createVertexPoseKeyFrame(20); -// */ -// -// // software pose -// Entity* e = mSceneMgr->createEntity("test2", "facial.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(150,0,0))->attachObject(e); -// AnimationState* animState = e->getAnimationState("Speak"); -// animState->setEnabled(true); -// animState->setWeight(1.0f); -// mAnimStateList.push_back(animState); -// -// -// /* -// // test hardware pose -// e = mSceneMgr->createEntity("test", "testpose.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// e->setMaterialName("Examples/HardwarePoseAnimation"); -// animState = e->getAnimationState("poseanim"); -// animState->setEnabled(true); -// animState->setWeight(1.0f); -// mAnimStateList.push_back(animState); -// */ -// -// -// mCamera->setNearClipDistance(0.5); -// mSceneMgr->setShowDebugShadows(true); -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 200; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// } -// -// -// void testReflectedBillboards() -// { -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); -// -// // Create a light -// Light* l = mSceneMgr->createLight("MainLight"); -// l->setType(Light::LT_DIRECTIONAL); -// Vector3 dir(0.5, -1, 0); -// dir.normalise(); -// l->setDirection(dir); -// l->setDiffuseColour(1.0f, 1.0f, 0.8f); -// l->setSpecularColour(1.0f, 1.0f, 1.0f); -// -// -// // Create a prefab plane -// Plane plane; -// plane.d = 0; -// plane.normal = Vector3::UNIT_Y; -// MeshManager::getSingleton().createPlane("ReflectionPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// plane, 2000, 2000, -// 1, 1, true, 1, 1, 1, Vector3::UNIT_Z); -// Entity* planeEnt = mSceneMgr->createEntity( "Plane", "ReflectionPlane" ); -// -// // Attach the rtt entity to the root of the scene -// SceneNode* rootNode = mSceneMgr->getRootSceneNode(); -// SceneNode* planeNode = rootNode->createChildSceneNode(); -// -// // Attach both the plane entity, and the plane definition -// planeNode->attachObject(planeEnt); -// -// TexturePtr rttTex = TextureManager::getSingleton().createManual("RttTex", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, -// 512, 512, 1, 0, PF_R8G8B8, TU_RENDERTARGET); -// { -// reflectCam = mSceneMgr->createCamera("ReflectCam"); -// reflectCam->setNearClipDistance(mCamera->getNearClipDistance()); -// reflectCam->setFarClipDistance(mCamera->getFarClipDistance()); -// reflectCam->setAspectRatio( -// (Real)mWindow->getViewport(0)->getActualWidth() / -// (Real)mWindow->getViewport(0)->getActualHeight()); -// -// Viewport *v = rttTex->getBuffer()->getRenderTarget()->addViewport( reflectCam ); -// v->setClearEveryFrame( true ); -// v->setBackgroundColour( ColourValue::Black ); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("RttMat", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// TextureUnitState* t = mat->getTechnique(0)->getPass(0)->createTextureUnitState("RustedMetal.jpg"); -// t = mat->getTechnique(0)->getPass(0)->createTextureUnitState("RttTex"); -// // Blend with base texture -// t->setColourOperationEx(LBX_BLEND_MANUAL, LBS_TEXTURE, LBS_CURRENT, ColourValue::White, -// ColourValue::White, 0.25); -// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); -// t->setProjectiveTexturing(true, reflectCam); -// -// // set up linked reflection -// reflectCam->enableReflection(plane); -// // Also clip -// reflectCam->enableCustomNearClipPlane(plane); -// } -// -// // Give the plane a texture -// planeEnt->setMaterialName("RttMat"); -// -// -// // point billboards -// ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("fountain1", -// "Examples/Smoke"); -// // Point the fountain at an angle -// SceneNode* fNode = static_cast(rootNode->createChild()); -// fNode->attachObject(pSys2); -// -// // oriented_self billboards -// ParticleSystem* pSys3 = mSceneMgr->createParticleSystem("fountain2", -// "Examples/PurpleFountain"); -// // Point the fountain at an angle -// fNode = rootNode->createChildSceneNode(); -// fNode->translate(-200,-100,0); -// fNode->rotate(Vector3::UNIT_Z, Degree(-20)); -// fNode->attachObject(pSys3); -// -// -// -// // oriented_common billboards -// ParticleSystem* pSys4 = mSceneMgr->createParticleSystem("rain", -// "Examples/Rain"); -// SceneNode* rNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// rNode->translate(0,1000,0); -// rNode->attachObject(pSys4); -// // Fast-forward the rain so it looks more natural -// pSys4->fastForward(5); -// -// -// mCamera->setPosition(-50, 100, 500); -// mCamera->lookAt(0,0,0); -// } -// -// void testManualObjectNonIndexed() -// { -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// Light* l = mSceneMgr->createLight("light1"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(dir); -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// ManualObject* man = static_cast( -// mSceneMgr->createMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); -// -// man->begin("Examples/OgreLogo"); -// // Define a 40x40 plane, non-indexed -// man->position(-20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 0); -// -// man->position(-20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); -// -// man->position(20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 0); -// -// man->position(-20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); -// -// man->position(20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 1); -// -// man->position(20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 0); -// -// man->end(); -// -// man->begin("Examples/BumpyMetal"); +// } +// +// class SortFunctor +// { +// public: +// int operator()(const int& p) const +// { +// return p; +// } +// +// }; +// void testRadixSort() +// { +// RadixSort::type, int, int> rs; +// SortFunctor f; +// +// list::type particles; +// for (int r = 0; r < 20; ++r) +// { +// particles.push_back((int)Math::RangeRandom(-1e3f, 1e3f)); +// } +// +// list::type::iterator i; +// LogManager::getSingleton().logMessage("BEFORE"); +// for (i = particles.begin(); i != particles.end(); ++i) +// LogManager::getSingleton().stream() << *i; +// +// rs.sort(particles, f); +// +// +// LogManager::getSingleton().logMessage("AFTER"); +// for (i = particles.begin(); i != particles.end(); ++i) +// LogManager::getSingleton().stream() << *i; +// +// +// +// } +// +// void testMorphAnimation() +// { +// bool testStencil = true; +// +// if (testStencil) +// mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); +// +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// Light* l = mSceneMgr->createLight("light1"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(dir); +// +// +// MeshPtr mesh = MeshManager::getSingleton().load("cube.mesh", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// +// SubMesh* sm = mesh->getSubMesh(0); +// // Re-organise geometry since this mesh has no animation and all +// // vertex elements are packed into one buffer +// VertexDeclaration* newDecl = +// sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true); +// sm->vertexData->reorganiseBuffers(newDecl); +// if (testStencil) +// sm->vertexData->prepareForShadowVolume(); // need to re-prep since reorganised +// // get the position buffer (which should now be separate); +// const VertexElement* posElem = +// sm->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); +// HardwareVertexBufferSharedPtr origbuf = +// sm->vertexData->vertexBufferBinding->getBuffer( +// posElem->getSource()); +// +// // Create a new position buffer with updated values +// HardwareVertexBufferSharedPtr newbuf = +// HardwareBufferManager::getSingleton().createVertexBuffer( +// VertexElement::getTypeSize(VET_FLOAT3), +// sm->vertexData->vertexCount, +// HardwareBuffer::HBU_STATIC, true); +// float* pSrc = static_cast(origbuf->lock(HardwareBuffer::HBL_READ_ONLY)); +// float* pDst = static_cast(newbuf->lock(HardwareBuffer::HBL_DISCARD)); +// +// for (size_t v = 0; v < sm->vertexData->vertexCount; ++v) +// { +// // x +// *pDst++ = *pSrc++; +// // y (translate) +// *pDst++ = (*pSrc++) + 100.0f; +// // z +// *pDst++ = *pSrc++; +// } +// +// origbuf->unlock(); +// newbuf->unlock(); +// +// // create a morph animation +// Animation* anim = mesh->createAnimation("testAnim", 10.0f); +// VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_MORPH); +// // re-use start positions for frame 0 +// VertexMorphKeyFrame* kf = vt->createVertexMorphKeyFrame(0); +// kf->setVertexBuffer(origbuf); +// +// // Use translated buffer for mid frame +// kf = vt->createVertexMorphKeyFrame(5.0f); +// kf->setVertexBuffer(newbuf); +// +// // re-use start positions for final frame +// kf = vt->createVertexMorphKeyFrame(10.0f); +// kf->setVertexBuffer(origbuf); +// +// // write +// MeshSerializer ser; +// ser.exportMesh(mesh.get(), "../../../Media/testmorph.mesh"); +// +// +// Entity* e = mSceneMgr->createEntity("test", "testmorph.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// AnimationState* animState = e->getAnimationState("testAnim"); +// animState->setEnabled(true); +// animState->setWeight(1.0f); +// mAnimStateList.push_back(animState); +// +// e = mSceneMgr->createEntity("test2", "testmorph.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,0,0))->attachObject(e); +// // test hardware morph +// e->setMaterialName("Examples/HardwareMorphAnimation"); +// animState = e->getAnimationState("testAnim"); +// animState->setEnabled(true); +// animState->setWeight(1.0f); +// mAnimStateList.push_back(animState); +// +// mCamera->setNearClipDistance(0.5); +// //mSceneMgr->setShowDebugShadows(true); +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 200; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// +// +// } +// +// +// void testPoseAnimation() +// { +// bool testStencil = false; +// +// if (testStencil) +// mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); +// +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// Light* l = mSceneMgr->createLight("light1"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(dir); +// +// MeshPtr mesh = MeshManager::getSingleton().load("cube.mesh", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// +// SubMesh* sm = mesh->getSubMesh(0); +// // Re-organise geometry since this mesh has no animation and all +// // vertex elements are packed into one buffer +// VertexDeclaration* newDecl = +// sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true); +// sm->vertexData->reorganiseBuffers(newDecl); +// if (testStencil) +// sm->vertexData->prepareForShadowVolume(); // need to re-prep since reorganised +// // get the position buffer (which should now be separate); +// const VertexElement* posElem = +// sm->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); +// HardwareVertexBufferSharedPtr origbuf = +// sm->vertexData->vertexBufferBinding->getBuffer( +// posElem->getSource()); +// +// +// // create 2 poses +// Pose* pose = mesh->createPose(1, "pose1"); +// // Pose1 moves vertices 0, 1, 2 and 3 upward +// Vector3 offset1(0, 50, 0); +// pose->addVertex(0, offset1); +// pose->addVertex(1, offset1); +// pose->addVertex(2, offset1); +// pose->addVertex(3, offset1); +// +// pose = mesh->createPose(1, "pose2"); +// // Pose2 moves vertices 3, 4, and 5 to the right +// // Note 3 gets affected by both +// Vector3 offset2(100, 0, 0); +// pose->addVertex(3, offset2); +// pose->addVertex(4, offset2); +// pose->addVertex(5, offset2); +// +// +// Animation* anim = mesh->createAnimation("poseanim", 20.0f); +// VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_POSE); +// +// // Frame 0 - no effect +// VertexPoseKeyFrame* kf = vt->createVertexPoseKeyFrame(0); +// +// // Frame 1 - bring in pose 1 (index 0) +// kf = vt->createVertexPoseKeyFrame(3); +// kf->addPoseReference(0, 1.0f); +// +// // Frame 2 - remove all +// kf = vt->createVertexPoseKeyFrame(6); +// +// // Frame 3 - bring in pose 2 (index 1) +// kf = vt->createVertexPoseKeyFrame(9); +// kf->addPoseReference(1, 1.0f); +// +// // Frame 4 - remove all +// kf = vt->createVertexPoseKeyFrame(12); +// +// +// // Frame 5 - bring in pose 1 at 50%, pose 2 at 100% +// kf = vt->createVertexPoseKeyFrame(15); +// kf->addPoseReference(0, 0.5f); +// kf->addPoseReference(1, 1.0f); +// +// // Frame 6 - bring in pose 1 at 100%, pose 2 at 50% +// kf = vt->createVertexPoseKeyFrame(18); +// kf->addPoseReference(0, 1.0f); +// kf->addPoseReference(1, 0.5f); +// +// // Frame 7 - reset +// kf = vt->createVertexPoseKeyFrame(20); +// +// // write +// MeshSerializer ser; +// ser.exportMesh(mesh.get(), "../../../Media/testpose.mesh"); +// +// +// Entity* e; +// AnimationState* animState; +// // software pose +// e = mSceneMgr->createEntity("test2", "testpose.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(150,0,0))->attachObject(e); +// animState = e->getAnimationState("poseanim"); +// animState->setEnabled(true); +// animState->setWeight(1.0f); +// mAnimStateList.push_back(animState); +// +// // test hardware pose +// e = mSceneMgr->createEntity("test", "testpose.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// e->setMaterialName("Examples/HardwarePoseAnimation"); +// animState = e->getAnimationState("poseanim"); +// animState->setEnabled(true); +// animState->setWeight(1.0f); +// mAnimStateList.push_back(animState); +// +// +// mCamera->setNearClipDistance(0.5); +// mSceneMgr->setShowDebugShadows(true); +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 200; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// mCamera->setPosition(0,0,-300); +// mCamera->lookAt(0,0,0); +// +// +// +// } +// +// void testPoseAnimation2() +// { +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// Vector3 dir(-1, -1, -0.5); +// dir.normalise(); +// Light* l = mSceneMgr->createLight("light1"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(dir); +// +// /* +// MeshPtr mesh = MeshManager::getSingleton().load("facial.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Animation* anim = mesh->createAnimation("pose", 20); +// VertexAnimationTrack* track = anim->createVertexTrack(4, VAT_POSE); +// // Frame 0 - no effect +// VertexPoseKeyFrame* kf = track->createVertexPoseKeyFrame(0); +// +// // bring in pose 4 (happy) +// kf = track->createVertexPoseKeyFrame(5); +// kf->addPoseReference(4, 1.0f); +// +// // bring in pose 5 (sad) +// kf = track->createVertexPoseKeyFrame(10); +// kf->addPoseReference(5, 1.0f); +// +// // bring in pose 6 (mad) +// kf = track->createVertexPoseKeyFrame(15); +// kf->addPoseReference(6, 1.0f); +// +// kf = track->createVertexPoseKeyFrame(20); +// */ +// +// // software pose +// Entity* e = mSceneMgr->createEntity("test2", "facial.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(150,0,0))->attachObject(e); +// AnimationState* animState = e->getAnimationState("Speak"); +// animState->setEnabled(true); +// animState->setWeight(1.0f); +// mAnimStateList.push_back(animState); +// +// +// /* +// // test hardware pose +// e = mSceneMgr->createEntity("test", "testpose.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// e->setMaterialName("Examples/HardwarePoseAnimation"); +// animState = e->getAnimationState("poseanim"); +// animState->setEnabled(true); +// animState->setWeight(1.0f); +// mAnimStateList.push_back(animState); +// */ +// +// +// mCamera->setNearClipDistance(0.5); +// mSceneMgr->setShowDebugShadows(true); +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 200; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// } +// +// +// void testReflectedBillboards() +// { +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); +// +// // Create a light +// Light* l = mSceneMgr->createLight("MainLight"); +// l->setType(Light::LT_DIRECTIONAL); +// Vector3 dir(0.5, -1, 0); +// dir.normalise(); +// l->setDirection(dir); +// l->setDiffuseColour(1.0f, 1.0f, 0.8f); +// l->setSpecularColour(1.0f, 1.0f, 1.0f); +// +// +// // Create a prefab plane +// Plane plane; +// plane.d = 0; +// plane.normal = Vector3::UNIT_Y; +// MeshManager::getSingleton().createPlane("ReflectionPlane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// plane, 2000, 2000, +// 1, 1, true, 1, 1, 1, Vector3::UNIT_Z); +// Entity* planeEnt = mSceneMgr->createEntity( "Plane", "ReflectionPlane" ); +// +// // Attach the rtt entity to the root of the scene +// SceneNode* rootNode = mSceneMgr->getRootSceneNode(); +// SceneNode* planeNode = rootNode->createChildSceneNode(); +// +// // Attach both the plane entity, and the plane definition +// planeNode->attachObject(planeEnt); +// +// TexturePtr rttTex = TextureManager::getSingleton().createManual("RttTex", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, +// 512, 512, 1, 0, PF_R8G8B8, TU_RENDERTARGET); +// { +// reflectCam = mSceneMgr->createCamera("ReflectCam"); +// reflectCam->setNearClipDistance(mCamera->getNearClipDistance()); +// reflectCam->setFarClipDistance(mCamera->getFarClipDistance()); +// reflectCam->setAspectRatio( +// (Real)mWindow->getViewport(0)->getActualWidth() / +// (Real)mWindow->getViewport(0)->getActualHeight()); +// +// Viewport *v = rttTex->getBuffer()->getRenderTarget()->addViewport( reflectCam ); +// v->setClearEveryFrame( true ); +// v->setBackgroundColour( ColourValue::Black ); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("RttMat", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// TextureUnitState* t = mat->getTechnique(0)->getPass(0)->createTextureUnitState("RustedMetal.jpg"); +// t = mat->getTechnique(0)->getPass(0)->createTextureUnitState("RttTex"); +// // Blend with base texture +// t->setColourOperationEx(LBX_BLEND_MANUAL, LBS_TEXTURE, LBS_CURRENT, ColourValue::White, +// ColourValue::White, 0.25); +// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); +// t->setProjectiveTexturing(true, reflectCam); +// +// // set up linked reflection +// reflectCam->enableReflection(plane); +// // Also clip +// reflectCam->enableCustomNearClipPlane(plane); +// } +// +// // Give the plane a texture +// planeEnt->setMaterialName("RttMat"); +// +// +// // point billboards +// ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("fountain1", +// "Examples/Smoke"); +// // Point the fountain at an angle +// SceneNode* fNode = static_cast(rootNode->createChild()); +// fNode->attachObject(pSys2); +// +// // oriented_self billboards +// ParticleSystem* pSys3 = mSceneMgr->createParticleSystem("fountain2", +// "Examples/PurpleFountain"); +// // Point the fountain at an angle +// fNode = rootNode->createChildSceneNode(); +// fNode->translate(-200,-100,0); +// fNode->rotate(Vector3::UNIT_Z, Degree(-20)); +// fNode->attachObject(pSys3); +// +// +// +// // oriented_common billboards +// ParticleSystem* pSys4 = mSceneMgr->createParticleSystem("rain", +// "Examples/Rain"); +// SceneNode* rNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// rNode->translate(0,1000,0); +// rNode->attachObject(pSys4); +// // Fast-forward the rain so it looks more natural +// pSys4->fastForward(5); +// +// +// mCamera->setPosition(-50, 100, 500); +// mCamera->lookAt(0,0,0); +// } +// +// void testManualObjectNonIndexed() +// { +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// Light* l = mSceneMgr->createLight("light1"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(dir); +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// ManualObject* man = static_cast( +// mSceneMgr->createMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); +// +// man->begin("Examples/OgreLogo"); +// // Define a 40x40 plane, non-indexed +// man->position(-20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 0); +// +// man->position(-20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); +// +// man->position(20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 0); +// +// man->position(-20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); +// +// man->position(20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 1); +// +// man->position(20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 0); +// +// man->end(); +// +// man->begin("Examples/BumpyMetal"); // -// // Define a 40x40 plane, non-indexed -// man->position(-20, 20, 20); -// man->normal(0, 1, 0); -// man->textureCoord(0, 0); +// // Define a 40x40 plane, non-indexed +// man->position(-20, 20, 20); +// man->normal(0, 1, 0); +// man->textureCoord(0, 0); // -// man->position(20, 20, 20); -// man->normal(0, 1, 0); -// man->textureCoord(0, 1); +// man->position(20, 20, 20); +// man->normal(0, 1, 0); +// man->textureCoord(0, 1); // -// man->position(20, 20, -20); -// man->normal(0, 1, 0); -// man->textureCoord(1, 1); +// man->position(20, 20, -20); +// man->normal(0, 1, 0); +// man->textureCoord(1, 1); // -// man->position(20, 20, -20); -// man->normal(0, 1, 0); -// man->textureCoord(1, 1); +// man->position(20, 20, -20); +// man->normal(0, 1, 0); +// man->textureCoord(1, 1); // -// man->position(-20, 20, -20); -// man->normal(0, 1, 0); -// man->textureCoord(1, 0); +// man->position(-20, 20, -20); +// man->normal(0, 1, 0); +// man->textureCoord(1, 0); // -// man->position(-20, 20, 20); -// man->normal(0, 1, 0); -// man->textureCoord(0, 0); +// man->position(-20, 20, 20); +// man->normal(0, 1, 0); +// man->textureCoord(0, 0); // -// man->end(); +// man->end(); // // -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(man); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(man); // -// } +// } // -// void testManualObjectNonIndexedUpdateSmaller() -// { -// testManualObjectNonIndexed(); -// ManualObject* man = static_cast( -// mSceneMgr->getMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); -// -// // Redefine but make smaller (one tri less) -// man->beginUpdate(0); -// man->position(-30, 30, 30); -// man->normal(0, 0, 1); -// man->textureCoord(0, 0); -// -// man->position(-30, -30, 30); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); -// -// man->position(90, 30, 30); -// man->normal(0, 0, 1); -// man->textureCoord(1, 0); +// void testManualObjectNonIndexedUpdateSmaller() +// { +// testManualObjectNonIndexed(); +// ManualObject* man = static_cast( +// mSceneMgr->getMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); +// +// // Redefine but make smaller (one tri less) +// man->beginUpdate(0); +// man->position(-30, 30, 30); +// man->normal(0, 0, 1); +// man->textureCoord(0, 0); +// +// man->position(-30, -30, 30); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); +// +// man->position(90, 30, 30); +// man->normal(0, 0, 1); +// man->textureCoord(1, 0); // // -// man->end(); +// man->end(); // -// } +// } // -// void testManualObjectNonIndexedUpdateLarger() -// { -// testManualObjectNonIndexed(); -// ManualObject* man = static_cast( -// mSceneMgr->getMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); +// void testManualObjectNonIndexedUpdateLarger() +// { +// testManualObjectNonIndexed(); +// ManualObject* man = static_cast( +// mSceneMgr->getMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); // -// // Redefine but make larger (2 more tri) -// man->beginUpdate(0); +// // Redefine but make larger (2 more tri) +// man->beginUpdate(0); // -// man->position(-20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 0); +// man->position(-20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 0); // -// man->position(-20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); +// man->position(-20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); // -// man->position(20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 0); +// man->position(20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 0); // -// man->position(-20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); +// man->position(-20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); // -// man->position(20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 1); +// man->position(20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 1); // -// man->position(20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 0); +// man->position(20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 0); // // -// man->position(-20, 40, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 0); +// man->position(-20, 40, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 0); // -// man->position(-20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); +// man->position(-20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); // -// man->position(20, 40, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 0); +// man->position(20, 40, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 0); // -// man->position(-20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); +// man->position(-20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); // -// man->position(20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 1); +// man->position(20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 1); // -// man->position(20, 40, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 0); +// man->position(20, 40, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 0); // // -// man->end(); +// man->end(); // -// } -// void testManualObjectIndexed() -// { -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// Light* l = mSceneMgr->createLight("light1"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(dir); +// } +// void testManualObjectIndexed() +// { +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// Light* l = mSceneMgr->createLight("light1"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(dir); // -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); // -// ManualObject* man = static_cast( -// mSceneMgr->createMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); +// ManualObject* man = static_cast( +// mSceneMgr->createMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); // -// man->begin("Examples/OgreLogo"); -// // Define a 40x40 plane, indexed -// man->position(-20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 0); +// man->begin("Examples/OgreLogo"); +// // Define a 40x40 plane, indexed +// man->position(-20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 0); // -// man->position(-20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); +// man->position(-20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); // -// man->position(20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 1); +// man->position(20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 1); // -// man->position(20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 0); +// man->position(20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 0); // -// man->quad(0, 1, 2, 3); +// man->quad(0, 1, 2, 3); // -// man->end(); +// man->end(); // -// man->begin("Examples/BumpyMetal"); +// man->begin("Examples/BumpyMetal"); // -// // Define a 40x40 plane, indexed -// man->position(-20, 20, 20); -// man->normal(0, 1, 0); -// man->textureCoord(0, 0); +// // Define a 40x40 plane, indexed +// man->position(-20, 20, 20); +// man->normal(0, 1, 0); +// man->textureCoord(0, 0); // -// man->position(20, 20, 20); -// man->normal(0, 1, 0); -// man->textureCoord(0, 1); +// man->position(20, 20, 20); +// man->normal(0, 1, 0); +// man->textureCoord(0, 1); // -// man->position(20, 20, -20); -// man->normal(0, 1, 0); -// man->textureCoord(1, 1); +// man->position(20, 20, -20); +// man->normal(0, 1, 0); +// man->textureCoord(1, 1); // -// man->position(-20, 20, -20); -// man->normal(0, 1, 0); -// man->textureCoord(1, 0); +// man->position(-20, 20, -20); +// man->normal(0, 1, 0); +// man->textureCoord(1, 0); // -// man->quad(0, 1, 2, 3); +// man->quad(0, 1, 2, 3); // -// man->end(); +// man->end(); // // -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(man); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(man); // -// +// // -// } +// } // -// void testManualObjectIndexedUpdateSmaller() -// { -// testManualObjectIndexed(); -// ManualObject* man = static_cast( -// mSceneMgr->getMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); +// void testManualObjectIndexedUpdateSmaller() +// { +// testManualObjectIndexed(); +// ManualObject* man = static_cast( +// mSceneMgr->getMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); // // -// man->beginUpdate(0); -// // 1 tri smaller -// man->position(-20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 0); -// -// man->position(-20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); -// -// man->position(20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 1); -// -// man->triangle(0, 1, 2); -// -// man->end(); -// -// } -// -// void testManualObjectIndexedUpdateLarger() -// { -// testManualObjectIndexed(); -// ManualObject* man = static_cast( -// mSceneMgr->getMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); -// -// -// man->beginUpdate(0); -// // 1 quad larger -// man->position(-20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 0); -// -// man->position(-20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); -// -// man->position(20, -20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 1); -// -// man->position(20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 0); -// -// -// man->position(-20, 40, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 0); -// -// man->position(-20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(0, 1); -// -// man->position(20, 20, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 1); -// -// man->position(20, 40, 20); -// man->normal(0, 0, 1); -// man->textureCoord(1, 0); -// -// man->quad(0, 1, 2, 3); -// man->quad(4, 5, 6, 7); -// -// man->end(); -// -// } -// -// void testBillboardChain() -// { -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// Light* l = mSceneMgr->createLight("light1"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(dir); -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// BillboardChain* chain = static_cast( -// mSceneMgr->createMovableObject("1", "BillboardChain")); -// chain->setUseTextureCoords(true); -// chain->setUseVertexColours(false); -// /* -// BillboardChain::Element elem; -// elem.width = 10; -// elem.texCoord = 0; -// elem.position = Vector3(0,20,0); -// chain->addChainElement(0, elem); -// elem.position = Vector3(20,0,0); -// elem.texCoord = 1.0; -// chain->addChainElement(0, elem); -// elem.position = Vector3(40,10,0); -// elem.texCoord = 2.0; -// chain->addChainElement(0, elem); -// elem.position = Vector3(60,20,0); -// elem.texCoord = 3.0; -// chain->addChainElement(0, elem); -// elem.position = Vector3(80,40,0); -// elem.texCoord = 4.0; -// chain->addChainElement(0, elem); -// elem.position = Vector3(100,70,0); -// elem.texCoord = 5.0; -// chain->addChainElement(0, elem); -// */ -// chain->setMaterialName("Examples/RustySteel"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(chain); -// -// mSceneMgr->showBoundingBoxes(true); -// } -// -// void testCubeDDS() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testcube", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// TextureUnitState* t = p->createTextureUnitState(); -// t->setTextureName("grace_cube.dds", TEX_TYPE_CUBE_MAP); -// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); -// t->setEnvironmentMap(true, TextureUnitState::ENV_REFLECTION); -// Entity* e = mSceneMgr->createEntity("1", "sphere.mesh"); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// -// mCamera->setPosition(300,0,0); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// -// void testDxt1() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// TextureUnitState* t = p->createTextureUnitState("BumpyMetal_dxt1.dds"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// -// mCamera->setPosition(0,0,-300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// void testDxt1FromMemory() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("BumpyMetal_dxt1.dds"); -// // manually load into image -// Image img; -// img.load(stream, "dds"); -// TextureManager::getSingleton().loadImage("testdxtfrommem", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, img); -// -// -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// TextureUnitState* t = p->createTextureUnitState("testdxtfrommem"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// -// mCamera->setPosition(0,0,-300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// void testDxt1Alpha() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// p->setAlphaRejectSettings(CMPF_GREATER, 128); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// TextureUnitState* t = p->createTextureUnitState("gras_02_dxt1.dds"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// void testDxt3() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_dxt3.dds"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// void testDxt3FromMemory() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("ogreborderUp_dxt3.dds"); -// // manually load into image -// Image img; -// img.load(stream, "dds"); -// TextureManager::getSingleton().loadImage("testdxtfrommem", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, img); -// -// -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// p->setAlphaRejectSettings(CMPF_GREATER, 128); -// mat->setReceiveShadows(false); -// TextureUnitState* t = p->createTextureUnitState("testdxtfrommem"); -// t->setTextureScale(0.5,0.5); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// n->setPosition(-50, 0, 35); -// n->yaw(Degree(90)); -// n->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// void testDxt5() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_dxt5.dds"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// void testFloat64DDS() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testdds", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_float64.dds"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// void testFloat128DDS() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testdds", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_float128.dds"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// void testFloat16DDS() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testdds", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// TextureUnitState* t = p->createTextureUnitState("BumpyMetal_float16.dds"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// -// map, int>::type testMap; -// -// void testFloat32DDS() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testdds", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// TextureUnitState* t = p->createTextureUnitState("BumpyMetal_float32.dds"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// // try saving -// TexturePtr tx = TextureManager::getSingleton().getByName("BumpyMetal_float32.dds"); -// float* dataBuf = new float[tx->getWidth() * tx->getHeight() * 4]; -// PixelBox pb(tx->getWidth(), tx->getHeight(), 1, PF_FLOAT32_RGB, dataBuf); -// -// tx->getBuffer()->blitToMemory(pb); -// -// Image img; -// img.loadDynamicImage((uchar*)dataBuf, tx->getWidth(), tx->getHeight(), 1, PF_FLOAT32_RGB); -// img.save("test.hdr"); -// -// -// } +// man->beginUpdate(0); +// // 1 tri smaller +// man->position(-20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 0); +// +// man->position(-20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); +// +// man->position(20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 1); +// +// man->triangle(0, 1, 2); +// +// man->end(); +// +// } +// +// void testManualObjectIndexedUpdateLarger() +// { +// testManualObjectIndexed(); +// ManualObject* man = static_cast( +// mSceneMgr->getMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); +// +// +// man->beginUpdate(0); +// // 1 quad larger +// man->position(-20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 0); +// +// man->position(-20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); +// +// man->position(20, -20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 1); +// +// man->position(20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 0); +// +// +// man->position(-20, 40, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 0); +// +// man->position(-20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(0, 1); +// +// man->position(20, 20, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 1); +// +// man->position(20, 40, 20); +// man->normal(0, 0, 1); +// man->textureCoord(1, 0); +// +// man->quad(0, 1, 2, 3); +// man->quad(4, 5, 6, 7); +// +// man->end(); +// +// } +// +// void testBillboardChain() +// { +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// Light* l = mSceneMgr->createLight("light1"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(dir); +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// BillboardChain* chain = static_cast( +// mSceneMgr->createMovableObject("1", "BillboardChain")); +// chain->setUseTextureCoords(true); +// chain->setUseVertexColours(false); +// /* +// BillboardChain::Element elem; +// elem.width = 10; +// elem.texCoord = 0; +// elem.position = Vector3(0,20,0); +// chain->addChainElement(0, elem); +// elem.position = Vector3(20,0,0); +// elem.texCoord = 1.0; +// chain->addChainElement(0, elem); +// elem.position = Vector3(40,10,0); +// elem.texCoord = 2.0; +// chain->addChainElement(0, elem); +// elem.position = Vector3(60,20,0); +// elem.texCoord = 3.0; +// chain->addChainElement(0, elem); +// elem.position = Vector3(80,40,0); +// elem.texCoord = 4.0; +// chain->addChainElement(0, elem); +// elem.position = Vector3(100,70,0); +// elem.texCoord = 5.0; +// chain->addChainElement(0, elem); +// */ +// chain->setMaterialName("Examples/RustySteel"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(chain); +// +// mSceneMgr->showBoundingBoxes(true); +// } +// +// void testCubeDDS() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testcube", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// TextureUnitState* t = p->createTextureUnitState(); +// t->setTextureName("grace_cube.dds", TEX_TYPE_CUBE_MAP); +// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); +// t->setEnvironmentMap(true, TextureUnitState::ENV_REFLECTION); +// Entity* e = mSceneMgr->createEntity("1", "sphere.mesh"); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// +// mCamera->setPosition(300,0,0); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// +// void testDxt1() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// TextureUnitState* t = p->createTextureUnitState("BumpyMetal_dxt1.dds"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// +// mCamera->setPosition(0,0,-300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// void testDxt1FromMemory() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("BumpyMetal_dxt1.dds"); +// // manually load into image +// Image img; +// img.load(stream, "dds"); +// TextureManager::getSingleton().loadImage("testdxtfrommem", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, img); +// +// +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// TextureUnitState* t = p->createTextureUnitState("testdxtfrommem"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// +// mCamera->setPosition(0,0,-300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// void testDxt1Alpha() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// p->setAlphaRejectSettings(CMPF_GREATER, 128); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// TextureUnitState* t = p->createTextureUnitState("gras_02_dxt1.dds"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// void testDxt3() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_dxt3.dds"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// void testDxt3FromMemory() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("ogreborderUp_dxt3.dds"); +// // manually load into image +// Image img; +// img.load(stream, "dds"); +// TextureManager::getSingleton().loadImage("testdxtfrommem", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, img); +// +// +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// p->setAlphaRejectSettings(CMPF_GREATER, 128); +// mat->setReceiveShadows(false); +// TextureUnitState* t = p->createTextureUnitState("testdxtfrommem"); +// t->setTextureScale(0.5,0.5); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// n->setPosition(-50, 0, 35); +// n->yaw(Degree(90)); +// n->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// void testDxt5() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testdxt", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_dxt5.dds"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// void testFloat64DDS() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testdds", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_float64.dds"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// void testFloat128DDS() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testdds", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_float128.dds"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// void testFloat16DDS() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testdds", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// TextureUnitState* t = p->createTextureUnitState("BumpyMetal_float16.dds"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// +// map, int>::type testMap; +// +// void testFloat32DDS() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testdds", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// TextureUnitState* t = p->createTextureUnitState("BumpyMetal_float32.dds"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// // try saving +// TexturePtr tx = TextureManager::getSingleton().getByName("BumpyMetal_float32.dds"); +// float* dataBuf = new float[tx->getWidth() * tx->getHeight() * 4]; +// PixelBox pb(tx->getWidth(), tx->getHeight(), 1, PF_FLOAT32_RGB, dataBuf); +// +// tx->getBuffer()->blitToMemory(pb); +// +// Image img; +// img.loadDynamicImage((uchar*)dataBuf, tx->getWidth(), tx->getHeight(), 1, PF_FLOAT32_RGB); +// img.save("test.hdr"); +// +// +// } // // void test4bppPVR() // { -// ResourceGroupManager::getSingleton().addResourceLocation("../../../../Tests/Media", "FileSystem"); +// ResourceGroupManager::getSingleton().addResourceLocation("../../../../Tests/Media", "FileSystem"); // -// MaterialPtr mat = MaterialManager::getSingleton().create("testpvr", +// MaterialPtr mat = MaterialManager::getSingleton().create("testpvr", // ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_pvr4.pvr"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_pvr4.pvr"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); // -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); // } // // void test4bppAlphaPVR() // { -// ResourceGroupManager::getSingleton().addResourceLocation("../../../../Tests/Media", "FileSystem"); +// ResourceGroupManager::getSingleton().addResourceLocation("../../../../Tests/Media", "FileSystem"); // -// MaterialPtr mat = MaterialManager::getSingleton().create("testpvr", +// MaterialPtr mat = MaterialManager::getSingleton().create("testpvr", // ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_pvr4a.pvr"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_pvr4a.pvr"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); // -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); // } // // void test2bppPVR() // { -// ResourceGroupManager::getSingleton().addResourceLocation("../../../../Tests/Media", "FileSystem"); +// ResourceGroupManager::getSingleton().addResourceLocation("../../../../Tests/Media", "FileSystem"); // -// MaterialPtr mat = MaterialManager::getSingleton().create("testpvr", +// MaterialPtr mat = MaterialManager::getSingleton().create("testpvr", // ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_pvr2.pvr"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_pvr2.pvr"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); // -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); // } // // void test2bppAlphaPVR() // { -// ResourceGroupManager::getSingleton().addResourceLocation("../../../../Tests/Media", "FileSystem"); +// ResourceGroupManager::getSingleton().addResourceLocation("../../../../Tests/Media", "FileSystem"); // -// MaterialPtr mat = MaterialManager::getSingleton().create("testpvr", +// MaterialPtr mat = MaterialManager::getSingleton().create("testpvr", // ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_pvr2a.pvr"); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// TextureUnitState* t = p->createTextureUnitState("ogreborderUp_pvr2a.pvr"); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); // -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); // } // -// void testRibbonTrail() -// { -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// Light* l = mSceneMgr->createLight("light1"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(dir); -// -// NameValuePairList pairList; -// pairList["numberOfChains"] = "2"; -// pairList["maxElements"] = "80"; -// RibbonTrail* trail = static_cast( -// mSceneMgr->createMovableObject("1", "RibbonTrail", &pairList)); -// trail->setMaterialName("Examples/LightRibbonTrail"); -// trail->setTrailLength(400); -// mRibbonTrail = trail; -// -// -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(trail); -// -// // Create 3 nodes for trail to follow -// SceneNode* animNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// animNode->setPosition(0,20,0); -// Animation* anim = mSceneMgr->createAnimation("an1", 10); -// anim->setInterpolationMode(Animation::IM_SPLINE); -// NodeAnimationTrack* track = anim->createNodeTrack(1, animNode); -// TransformKeyFrame* kf = track->createNodeKeyFrame(0); -// kf->setTranslate(Vector3::ZERO); -// kf = track->createNodeKeyFrame(2); -// kf->setTranslate(Vector3(100, 0, 0)); -// kf = track->createNodeKeyFrame(4); -// kf->setTranslate(Vector3(200, 0, 300)); -// kf = track->createNodeKeyFrame(6); -// kf->setTranslate(Vector3(0, 20, 500)); -// kf = track->createNodeKeyFrame(8); -// kf->setTranslate(Vector3(-100, 10, 100)); -// kf = track->createNodeKeyFrame(10); -// kf->setTranslate(Vector3::ZERO); -// -// testremoveNode = animNode; -// -// AnimationState* animState = mSceneMgr->createAnimationState("an1"); -// animState->setEnabled(true); -// mAnimStateList.push_back(animState); -// -// trail->addNode(animNode); -// trail->setInitialColour(0, 1.0, 0.8, 0); -// trail->setColourChange(0, 0.5, 0.5, 0.5, 0.5); -// trail->setInitialWidth(0, 5); -// -// // Add light -// Light* l2 = mSceneMgr->createLight("l2"); -// l2->setDiffuseColour(trail->getInitialColour(0)); -// animNode->attachObject(l2); -// -// // Add billboard -// BillboardSet* bbs = mSceneMgr->createBillboardSet("bb", 1); -// bbs->createBillboard(Vector3::ZERO, trail->getInitialColour(0)); -// bbs->setMaterialName("Examples/Flare"); -// animNode->attachObject(bbs); -// -// animNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// animNode->setPosition(-50,10,0); -// anim = mSceneMgr->createAnimation("an2", 10); -// anim->setInterpolationMode(Animation::IM_SPLINE); -// track = anim->createNodeTrack(1, animNode); -// kf = track->createNodeKeyFrame(0); -// kf->setTranslate(Vector3::ZERO); -// kf = track->createNodeKeyFrame(2); -// kf->setTranslate(Vector3(-100, 150, -30)); -// kf = track->createNodeKeyFrame(4); -// kf->setTranslate(Vector3(-200, 0, 40)); -// kf = track->createNodeKeyFrame(6); -// kf->setTranslate(Vector3(0, -150, 70)); -// kf = track->createNodeKeyFrame(8); -// kf->setTranslate(Vector3(50, 0, 30)); -// kf = track->createNodeKeyFrame(10); -// kf->setTranslate(Vector3::ZERO); -// -// animState = mSceneMgr->createAnimationState("an2"); -// animState->setEnabled(true); -// mAnimStateList.push_back(animState); -// -// trail->addNode(animNode); -// trail->setInitialColour(1, 0.0, 1.0, 0.4); -// trail->setColourChange(1, 0.5, 0.5, 0.5, 0.5); -// trail->setInitialWidth(1, 5); -// -// -// // Add light -// l2 = mSceneMgr->createLight("l3"); -// l2->setDiffuseColour(trail->getInitialColour(1)); -// animNode->attachObject(l2); -// -// // Add billboard -// bbs = mSceneMgr->createBillboardSet("bb2", 1); -// bbs->createBillboard(Vector3::ZERO, trail->getInitialColour(1)); -// bbs->setMaterialName("Examples/Flare"); -// animNode->attachObject(bbs); -// -// -// -// //mSceneMgr->showBoundingBoxes(true); -// -// } -// -// void testExportPrecompiledAssemblerProgram() -// { -// HighLevelGpuProgramPtr hivp = HighLevelGpuProgramManager::getSingleton().getByName("Ogre/CelShadingVP"); -// hivp->load(); -// // write asm to disk -// std::ofstream of; -// of.open("../../../Media/celshadingvp.asm"); -// of << hivp->_getBindingDelegate()->getSource(); -// of.close(); -// // write named params -// hivp->getNamedConstants().save("../../../Media/celshadingvp.constants"); -// -// HighLevelGpuProgramPtr hifp = HighLevelGpuProgramManager::getSingleton().getByName("Ogre/CelShadingFP"); -// hifp->load(); -// // write asm to disk -// of.open("../../../Media/celshadingfp.asm"); -// of << hifp->_getBindingDelegate()->getSource(); -// of.close(); -// // write named params -// hifp->getNamedConstants().save("../../../Media/celshadingfp.constants"); -// -// -// /* Now you can do this! -// -// vertex_program CelShadingVPASM asm -// { -// source celshadingvp.asm -// syntax vs_1_1 -// manual_named_constants celshadingvp.constants -// -// // I can use named constants in assembler! -// default_params -// { -// param_named_auto lightPosition light_position_object_space 0 -// param_named_auto eyePosition camera_position_object_space -// param_named_auto worldViewProj worldviewproj_matrix -// param_named shininess float 10 -// } -// } -// -// fragment_program CelShadingFPASM asm -// { -// source celshadingfp.asm -// syntax ps_1_1 -// manual_named_constants celshadingfp.constants -// -// // I can use named constants in assembler! -// } -// */ -// } -// -// void testMaterial() -// { -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName("Material.001/TEXFACE/arz.png"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// MaterialPtr m = e->getSubEntity(0)->getMaterial(); -// GpuProgramParametersSharedPtr params = m->getTechnique(0)->getPass(0)->getVertexProgramParameters(); -// params = m->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); -// params = m->getTechnique(0)->getPass(1)->getVertexProgramParameters(); -// params = m->getTechnique(0)->getPass(1)->getFragmentProgramParameters(); -// -// -// -// -// -// mCamera->setPosition(0,0,-300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// -// void testBlendDiffuseColour() -// { -// MaterialPtr mat = MaterialManager::getSingleton().create( -// "testBlendDiffuseColour", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* pass = mat->getTechnique(0)->getPass(0); -// // no lighting, it will mess up vertex colours -// pass->setLightingEnabled(false); -// // Make sure we pull in vertex colour as diffuse -// pass->setVertexColourTracking(TVC_DIFFUSE); -// // Base layer -// TextureUnitState* t = pass->createTextureUnitState("BeachStones.jpg"); -// // don't want to bring in vertex diffuse on base layer -// t->setColourOperation(LBO_REPLACE); -// // Second layer (lerp based on colour) -// t = pass->createTextureUnitState("terr_dirt-grass.jpg"); -// t->setColourOperationEx(LBX_BLEND_DIFFUSE_COLOUR); -// // third layer (lerp based on alpha) -// ManualObject* man = mSceneMgr->createManualObject("quad"); -// man->begin("testBlendDiffuseColour"); -// man->position(-100, 100, 0); -// man->textureCoord(0,0); -// man->colour(0, 0, 0); -// man->position(-100, -100, 0); -// man->textureCoord(0,1); -// man->colour(0.5, 0.5, 0.5); -// man->position(100, -100, 0); -// man->textureCoord(1,1); -// man->colour(1, 1, 1); -// man->position(100, 100, 0); -// man->textureCoord(1,0); -// man->colour(0.5, 0.5, 0.5); -// man->quad(0, 1, 2, 3); -// man->end(); -// -// mSceneMgr->getRootSceneNode()->attachObject(man); -// -// } -// -// void testSplitPassesTooManyTexUnits() -// { -// MaterialPtr mat = MaterialManager::getSingleton().create( -// "Test", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->createTextureUnitState("gras_02.png"); -// p->createTextureUnitState("gras_02.png"); -// p->createTextureUnitState("gras_02.png"); -// p->createTextureUnitState("gras_02.png"); -// p->createTextureUnitState("gras_02.png"); -// p->createTextureUnitState("gras_02.png"); -// p->createTextureUnitState("gras_02.png"); -// p->createTextureUnitState("gras_02.png"); -// p->createTextureUnitState("gras_02.png"); -// -// mat->compile(); -// -// } -// -// void testCustomProjectionMatrix() -// { -// testLotsAndLotsOfEntities(); -// Matrix4 mat = mCamera->getProjectionMatrix(); -// mCamera->setCustomProjectionMatrix(true, mat); -// mat = mCamera->getProjectionMatrix(); -// -// } -// -// void testPointSprites() -// { -// MaterialPtr mat = MaterialManager::getSingleton().create("spriteTest1", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setPointSpritesEnabled(true); -// p->createTextureUnitState("flare.png"); -// p->setLightingEnabled(false); -// p->setDepthWriteEnabled(false); -// p->setSceneBlending(SBT_ADD); -// p->setPointAttenuation(true); -// p->setPointSize(1); -// srand((unsigned)time( NULL ) ); -// -// ManualObject* man = mSceneMgr->createManualObject("man"); -// man->begin("spriteTest1", RenderOperation::OT_POINT_LIST); -// /* -// for (size_t i = 0; i < 1000; ++i) -// { -// man->position(Math::SymmetricRandom() * 500, -// Math::SymmetricRandom() * 500, -// Math::SymmetricRandom() * 500); -// man->colour(Math::RangeRandom(0.5f, 1.0f), -// Math::RangeRandom(0.5f, 1.0f), Math::RangeRandom(0.5f, 1.0f)); -// } -// */ -// for (size_t i = 0; i < 20; ++i) -// { -// for (size_t j = 0; j < 20; ++j) -// { -// for (size_t k = 0; k < 20; ++k) -// { -// man->position(i * 30, j * 30, k * 30); -// } -// } -// } -// -// man->end(); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(man); -// -// } -// -// void testSuppressedShadows(ShadowTechnique shadowTech) -// { -// mSceneMgr->setShadowTechnique(shadowTech); -// -// // Setup lighting -// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); -// Light* light = mSceneMgr->createLight("MainLight"); -// light->setType(Light::LT_DIRECTIONAL); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// light->setDirection(dir); -// -// // Create a skydome -// //mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8); -// -// // Create a floor plane mesh -// Plane plane(Vector3::UNIT_Y, 0.0); -// MeshManager::getSingleton().createPlane( -// "FloorPlane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// plane, 200000, 200000, 20, 20, true, 1, 500, 500, Vector3::UNIT_Z); -// -// -// // Add a floor to the scene -// Entity* entity = mSceneMgr->createEntity("floor", "FloorPlane"); -// entity->setMaterialName("Examples/RustySteel"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entity); -// entity->setCastShadows(false); -// -// // Add the mandatory ogre head -// entity = mSceneMgr->createEntity("head", "ogrehead.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0.0, 10.0, 0.0))->attachObject(entity); -// -// // Position and orient the camera -// mCamera->setPosition(-100.0, 50.0, 90.0); -// mCamera->lookAt(0.0, 10.0, -35.0); -// -// // Add an additional viewport on top of the other one -// Viewport* pip = mWindow->addViewport(mCamera, 1, 0.7, 0.0, 0.3, 0.3); -// -// // Create a render queue invocation sequence for the pip viewport -// RenderQueueInvocationSequence* invocationSequence = -// mRoot->createRenderQueueInvocationSequence("pip"); -// -// // Add an invocation to the sequence -// RenderQueueInvocation* invocation = -// invocationSequence->add(RENDER_QUEUE_MAIN, "main"); -// -// // Disable render state changes and shadows for that invocation -// //invocation->setSuppressRenderStateChanges(true); -// invocation->setSuppressShadows(true); -// -// // Set the render queue invocation sequence for the pip viewport -// pip->setRenderQueueInvocationSequenceName("pip"); -// } -// -// void testViewportNoShadows(ShadowTechnique shadowTech) -// { -// mSceneMgr->setShadowTechnique(shadowTech); -// -// // Setup lighting -// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); -// Light* light = mSceneMgr->createLight("MainLight"); -// light->setType(Light::LT_DIRECTIONAL); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// light->setDirection(dir); -// -// // Create a skydome -// //mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8); -// -// // Create a floor plane mesh -// Plane plane(Vector3::UNIT_Y, 0.0); -// MeshManager::getSingleton().createPlane( -// "FloorPlane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// plane, 200000, 200000, 20, 20, true, 1, 500, 500, Vector3::UNIT_Z); -// -// -// // Add a floor to the scene -// Entity* entity = mSceneMgr->createEntity("floor", "FloorPlane"); -// entity->setMaterialName("Examples/RustySteel"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entity); -// entity->setCastShadows(false); -// -// // Add the mandatory ogre head -// entity = mSceneMgr->createEntity("head", "ogrehead.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0.0, 10.0, 0.0))->attachObject(entity); -// -// // Position and orient the camera -// mCamera->setPosition(-100.0, 50.0, 90.0); -// mCamera->lookAt(0.0, 10.0, -35.0); -// -// // Add an additional viewport on top of the other one -// Viewport* pip = mWindow->addViewport(mCamera, 1, 0.7, 0.0, 0.3, 0.3); -// pip->setShadowsEnabled(false); -// -// } -// -// void testSerialisedColour() -// { -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// Light* l = mSceneMgr->createLight("light1"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(dir); -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// /* -// ManualObject* man = static_cast( -// mSceneMgr->createMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); -// -// man->begin("BaseWhiteNoLighting"); -// // Define a 40x40 plane, non-indexed -// // Define a 40x40 plane, indexed -// man->position(-20, 20, 20); -// man->colour(1, 0, 0); -// -// man->position(-20, -20, 20); -// man->colour(1, 0, 0); -// -// man->position(20, -20, 20); -// man->colour(1, 0, 0); -// -// man->position(20, 20, 20); -// man->colour(1, 0, 0); -// -// man->quad(0, 1, 2, 3); -// man->end(); -// -// MeshPtr mesh = man->convertToMesh("colourtest.mesh"); -// MeshSerializer ms; -// ms.exportMesh(mesh.getPointer(), "colourtest.mesh"); -// -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(man); -// */ -// Entity* c = mSceneMgr->createEntity("1", "colourtest.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(c); -// -// -// -// } -// -// void testBillboardAccurateFacing() -// { -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// Light* l = mSceneMgr->createLight("light1"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(dir); -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// BillboardSet* bbs = mSceneMgr->createBillboardSet("1"); -// bbs->setDefaultDimensions(50,50); -// bbs->createBillboard(-150, 25, 0); -// bbs->setBillboardType(BBT_ORIENTED_COMMON); -// bbs->setCommonDirection(Vector3::UNIT_Y); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(bbs); -// -// bbs = mSceneMgr->createBillboardSet("2"); -// bbs->setDefaultDimensions(50,50); -// bbs->createBillboard(150, 25, 0); -// bbs->setUseAccurateFacing(true); -// bbs->setBillboardType(BBT_ORIENTED_COMMON); -// bbs->setCommonDirection(Vector3::UNIT_Y); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(bbs); -// } -// -// void testMultiSceneManagersSimple() -// { -// // Create a secondary scene manager with it's own camera -// SceneManager* sm2 = Root::getSingleton().createSceneManager(ST_GENERIC); -// camera2 = sm2->createCamera("cam2"); -// camera2->setPosition(0,0,-500); -// camera2->lookAt(Vector3::ZERO); -// Entity* ent = sm2->createEntity("knot2", "knot.mesh"); -// sm2->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// Light* l = sm2->createLight("l2"); -// l->setPosition(100,50,-100); -// l->setDiffuseColour(ColourValue::Green); -// sm2->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); -// -// Viewport* vp = mWindow->addViewport(camera2, 1, 0.67, 0, 0.33, 0.25); -// vp->setOverlaysEnabled(false); -// -// // Use original SM for normal scene -// ent = mSceneMgr->createEntity("head", "ogrehead.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// l = mSceneMgr->createLight("l2"); // note same name, will work since different SM -// l->setPosition(100,50,-100); -// l->setDiffuseColour(ColourValue::Red); -// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); -// -// -// } -// -// void testMultiSceneManagersComplex() -// { -// // Create a secondary scene manager with it's own camera -// SceneManager* sm2 = Root::getSingleton().createSceneManager("TerrainSceneManager"); -// camera2 = sm2->createCamera("cam2"); -// -// Viewport* vp = mWindow->addViewport(camera2, 1, 0.5, 0, 0.5, 0.5); -// vp->setOverlaysEnabled(false); -// // Fog -// // NB it's VERY important to set this before calling setWorldGeometry -// // because the vertex program picked will be different -// ColourValue fadeColour(0.93, 0.86, 0.76); -// sm2->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000); -// vp->setBackgroundColour(fadeColour); -// -// sm2->setWorldGeometry("terrain.cfg"); -// // Infinite far plane? -// if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)) -// { -// camera2->setFarClipDistance(0); -// } -// // Set a nice viewpoint -// camera2->setPosition(707,3500,528); -// camera2->lookAt(Vector3::ZERO); -// camera2->setNearClipDistance( 1 ); -// camera2->setFarClipDistance( 1000 ); -// -// -// // Create a tertiary scene manager with it's own camera -// SceneManager* sm3 = Root::getSingleton().createSceneManager("BspSceneManager"); -// Camera* camera3 = sm3->createCamera("cam3"); -// -// vp = mWindow->addViewport(camera3, 2, 0.5, 0.5, 0.5, 0.5); -// vp->setOverlaysEnabled(false); -// -// // Load Quake3 locations from a file -// ConfigFile cf; -// -// cf.load("quake3settings.cfg"); -// -// String pk3 = cf.getSetting("Pak0Location"); -// String level = cf.getSetting("Map"); -// -// ExampleApplication::setupResources(); -// ResourceGroupManager::getSingleton().createResourceGroup("BSP"); -// ResourceGroupManager::getSingleton().setWorldResourceGroupName("BSP"); -// ResourceGroupManager::getSingleton().addResourceLocation( -// pk3, "Zip", ResourceGroupManager::getSingleton().getWorldResourceGroupName()); -// ResourceGroupManager::getSingleton().initialiseResourceGroup("BSP"); -// sm3->setWorldGeometry(level); -// // modify camera for close work -// camera3->setNearClipDistance(4); -// camera3->setFarClipDistance(4000); -// -// // Also change position, and set Quake-type orientation -// // Get random player start point -// ViewPoint viewp = sm3->getSuggestedViewpoint(true); -// camera3->setPosition(viewp.position); -// camera3->pitch(Degree(90)); // Quake uses X/Y horizon, Z up -// camera3->rotate(viewp.orientation); -// // Don't yaw along variable axis, causes leaning -// camera3->setFixedYawAxis(true, Vector3::UNIT_Z); -// camera3->yaw(Degree(-90)); -// -// -// -// -// -// // Use original SM for normal scene -// testTextureShadows(SHADOWTYPE_TEXTURE_MODULATIVE, true); -// -// } -// -// void testManualBoneMovement(void) -// { -// Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); -// -// //ent->setMaterialName("Examples/Rocky"); -// -// SkeletonInstance* skel = ent->getSkeleton(); -// Animation* anim = skel->getAnimation("Walk"); -// manuallyControlledBone = skel->getBone("Joint10"); -// manuallyControlledBone->setManuallyControlled(true); -// anim->destroyNodeTrack(manuallyControlledBone->getHandle()); -// -// //AnimationState* animState = ent->getAnimationState("Walk"); -// //animState->setEnabled(true); -// -// -// -// } -// -// void testMaterialSchemes() -// { +// void testRibbonTrail() +// { +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// Light* l = mSceneMgr->createLight("light1"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(dir); +// +// NameValuePairList pairList; +// pairList["numberOfChains"] = "2"; +// pairList["maxElements"] = "80"; +// RibbonTrail* trail = static_cast( +// mSceneMgr->createMovableObject("1", "RibbonTrail", &pairList)); +// trail->setMaterialName("Examples/LightRibbonTrail"); +// trail->setTrailLength(400); +// mRibbonTrail = trail; +// +// +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(trail); +// +// // Create 3 nodes for trail to follow +// SceneNode* animNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// animNode->setPosition(0,20,0); +// Animation* anim = mSceneMgr->createAnimation("an1", 10); +// anim->setInterpolationMode(Animation::IM_SPLINE); +// NodeAnimationTrack* track = anim->createNodeTrack(1, animNode); +// TransformKeyFrame* kf = track->createNodeKeyFrame(0); +// kf->setTranslate(Vector3::ZERO); +// kf = track->createNodeKeyFrame(2); +// kf->setTranslate(Vector3(100, 0, 0)); +// kf = track->createNodeKeyFrame(4); +// kf->setTranslate(Vector3(200, 0, 300)); +// kf = track->createNodeKeyFrame(6); +// kf->setTranslate(Vector3(0, 20, 500)); +// kf = track->createNodeKeyFrame(8); +// kf->setTranslate(Vector3(-100, 10, 100)); +// kf = track->createNodeKeyFrame(10); +// kf->setTranslate(Vector3::ZERO); +// +// testremoveNode = animNode; +// +// AnimationState* animState = mSceneMgr->createAnimationState("an1"); +// animState->setEnabled(true); +// mAnimStateList.push_back(animState); +// +// trail->addNode(animNode); +// trail->setInitialColour(0, 1.0, 0.8, 0); +// trail->setColourChange(0, 0.5, 0.5, 0.5, 0.5); +// trail->setInitialWidth(0, 5); +// +// // Add light +// Light* l2 = mSceneMgr->createLight("l2"); +// l2->setDiffuseColour(trail->getInitialColour(0)); +// animNode->attachObject(l2); +// +// // Add billboard +// BillboardSet* bbs = mSceneMgr->createBillboardSet("bb", 1); +// bbs->createBillboard(Vector3::ZERO, trail->getInitialColour(0)); +// bbs->setMaterialName("Examples/Flare"); +// animNode->attachObject(bbs); +// +// animNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// animNode->setPosition(-50,10,0); +// anim = mSceneMgr->createAnimation("an2", 10); +// anim->setInterpolationMode(Animation::IM_SPLINE); +// track = anim->createNodeTrack(1, animNode); +// kf = track->createNodeKeyFrame(0); +// kf->setTranslate(Vector3::ZERO); +// kf = track->createNodeKeyFrame(2); +// kf->setTranslate(Vector3(-100, 150, -30)); +// kf = track->createNodeKeyFrame(4); +// kf->setTranslate(Vector3(-200, 0, 40)); +// kf = track->createNodeKeyFrame(6); +// kf->setTranslate(Vector3(0, -150, 70)); +// kf = track->createNodeKeyFrame(8); +// kf->setTranslate(Vector3(50, 0, 30)); +// kf = track->createNodeKeyFrame(10); +// kf->setTranslate(Vector3::ZERO); +// +// animState = mSceneMgr->createAnimationState("an2"); +// animState->setEnabled(true); +// mAnimStateList.push_back(animState); +// +// trail->addNode(animNode); +// trail->setInitialColour(1, 0.0, 1.0, 0.4); +// trail->setColourChange(1, 0.5, 0.5, 0.5, 0.5); +// trail->setInitialWidth(1, 5); +// +// +// // Add light +// l2 = mSceneMgr->createLight("l3"); +// l2->setDiffuseColour(trail->getInitialColour(1)); +// animNode->attachObject(l2); +// +// // Add billboard +// bbs = mSceneMgr->createBillboardSet("bb2", 1); +// bbs->createBillboard(Vector3::ZERO, trail->getInitialColour(1)); +// bbs->setMaterialName("Examples/Flare"); +// animNode->attachObject(bbs); +// +// +// +// //mSceneMgr->showBoundingBoxes(true); +// +// } +// +// void testExportPrecompiledAssemblerProgram() +// { +// HighLevelGpuProgramPtr hivp = HighLevelGpuProgramManager::getSingleton().getByName("Ogre/CelShadingVP"); +// hivp->load(); +// // write asm to disk +// std::ofstream of; +// of.open("../../../Media/celshadingvp.asm"); +// of << hivp->_getBindingDelegate()->getSource(); +// of.close(); +// // write named params +// hivp->getNamedConstants().save("../../../Media/celshadingvp.constants"); +// +// HighLevelGpuProgramPtr hifp = HighLevelGpuProgramManager::getSingleton().getByName("Ogre/CelShadingFP"); +// hifp->load(); +// // write asm to disk +// of.open("../../../Media/celshadingfp.asm"); +// of << hifp->_getBindingDelegate()->getSource(); +// of.close(); +// // write named params +// hifp->getNamedConstants().save("../../../Media/celshadingfp.constants"); +// +// +// /* Now you can do this! +// +// vertex_program CelShadingVPASM asm +// { +// source celshadingvp.asm +// syntax vs_1_1 +// manual_named_constants celshadingvp.constants +// +// // I can use named constants in assembler! +// default_params +// { +// param_named_auto lightPosition light_position_object_space 0 +// param_named_auto eyePosition camera_position_object_space +// param_named_auto worldViewProj worldviewproj_matrix +// param_named shininess float 10 +// } +// } +// +// fragment_program CelShadingFPASM asm +// { +// source celshadingfp.asm +// syntax ps_1_1 +// manual_named_constants celshadingfp.constants +// +// // I can use named constants in assembler! +// } +// */ +// } +// +// void testMaterial() +// { +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName("Material.001/TEXFACE/arz.png"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// MaterialPtr m = e->getSubEntity(0)->getMaterial(); +// GpuProgramParametersSharedPtr params = m->getTechnique(0)->getPass(0)->getVertexProgramParameters(); +// params = m->getTechnique(0)->getPass(0)->getFragmentProgramParameters(); +// params = m->getTechnique(0)->getPass(1)->getVertexProgramParameters(); +// params = m->getTechnique(0)->getPass(1)->getFragmentProgramParameters(); +// +// +// +// +// +// mCamera->setPosition(0,0,-300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// +// void testBlendDiffuseColour() +// { +// MaterialPtr mat = MaterialManager::getSingleton().create( +// "testBlendDiffuseColour", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* pass = mat->getTechnique(0)->getPass(0); +// // no lighting, it will mess up vertex colours +// pass->setLightingEnabled(false); +// // Make sure we pull in vertex colour as diffuse +// pass->setVertexColourTracking(TVC_DIFFUSE); +// // Base layer +// TextureUnitState* t = pass->createTextureUnitState("BeachStones.jpg"); +// // don't want to bring in vertex diffuse on base layer +// t->setColourOperation(LBO_REPLACE); +// // Second layer (lerp based on colour) +// t = pass->createTextureUnitState("terr_dirt-grass.jpg"); +// t->setColourOperationEx(LBX_BLEND_DIFFUSE_COLOUR); +// // third layer (lerp based on alpha) +// ManualObject* man = mSceneMgr->createManualObject("quad"); +// man->begin("testBlendDiffuseColour"); +// man->position(-100, 100, 0); +// man->textureCoord(0,0); +// man->colour(0, 0, 0); +// man->position(-100, -100, 0); +// man->textureCoord(0,1); +// man->colour(0.5, 0.5, 0.5); +// man->position(100, -100, 0); +// man->textureCoord(1,1); +// man->colour(1, 1, 1); +// man->position(100, 100, 0); +// man->textureCoord(1,0); +// man->colour(0.5, 0.5, 0.5); +// man->quad(0, 1, 2, 3); +// man->end(); +// +// mSceneMgr->getRootSceneNode()->attachObject(man); +// +// } +// +// void testSplitPassesTooManyTexUnits() +// { +// MaterialPtr mat = MaterialManager::getSingleton().create( +// "Test", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->createTextureUnitState("gras_02.png"); +// p->createTextureUnitState("gras_02.png"); +// p->createTextureUnitState("gras_02.png"); +// p->createTextureUnitState("gras_02.png"); +// p->createTextureUnitState("gras_02.png"); +// p->createTextureUnitState("gras_02.png"); +// p->createTextureUnitState("gras_02.png"); +// p->createTextureUnitState("gras_02.png"); +// p->createTextureUnitState("gras_02.png"); +// +// mat->compile(); +// +// } +// +// void testCustomProjectionMatrix() +// { +// testLotsAndLotsOfEntities(); +// Matrix4 mat = mCamera->getProjectionMatrix(); +// mCamera->setCustomProjectionMatrix(true, mat); +// mat = mCamera->getProjectionMatrix(); +// +// } +// +// void testPointSprites() +// { +// MaterialPtr mat = MaterialManager::getSingleton().create("spriteTest1", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setPointSpritesEnabled(true); +// p->createTextureUnitState("flare.png"); +// p->setLightingEnabled(false); +// p->setDepthWriteEnabled(false); +// p->setSceneBlending(SBT_ADD); +// p->setPointAttenuation(true); +// p->setPointSize(1); +// srand((unsigned)time( NULL ) ); +// +// ManualObject* man = mSceneMgr->createManualObject("man"); +// man->begin("spriteTest1", RenderOperation::OT_POINT_LIST); +// /* +// for (size_t i = 0; i < 1000; ++i) +// { +// man->position(Math::SymmetricRandom() * 500, +// Math::SymmetricRandom() * 500, +// Math::SymmetricRandom() * 500); +// man->colour(Math::RangeRandom(0.5f, 1.0f), +// Math::RangeRandom(0.5f, 1.0f), Math::RangeRandom(0.5f, 1.0f)); +// } +// */ +// for (size_t i = 0; i < 20; ++i) +// { +// for (size_t j = 0; j < 20; ++j) +// { +// for (size_t k = 0; k < 20; ++k) +// { +// man->position(i * 30, j * 30, k * 30); +// } +// } +// } +// +// man->end(); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(man); +// +// } +// +// void testSuppressedShadows(ShadowTechnique shadowTech) +// { +// mSceneMgr->setShadowTechnique(shadowTech); +// +// // Setup lighting +// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); +// Light* light = mSceneMgr->createLight("MainLight"); +// light->setType(Light::LT_DIRECTIONAL); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// light->setDirection(dir); +// +// // Create a skydome +// //mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8); +// +// // Create a floor plane mesh +// Plane plane(Vector3::UNIT_Y, 0.0); +// MeshManager::getSingleton().createPlane( +// "FloorPlane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// plane, 200000, 200000, 20, 20, true, 1, 500, 500, Vector3::UNIT_Z); +// +// +// // Add a floor to the scene +// Entity* entity = mSceneMgr->createEntity("floor", "FloorPlane"); +// entity->setMaterialName("Examples/RustySteel"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entity); +// entity->setCastShadows(false); +// +// // Add the mandatory ogre head +// entity = mSceneMgr->createEntity("head", "ogrehead.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0.0, 10.0, 0.0))->attachObject(entity); +// +// // Position and orient the camera +// mCamera->setPosition(-100.0, 50.0, 90.0); +// mCamera->lookAt(0.0, 10.0, -35.0); +// +// // Add an additional viewport on top of the other one +// Viewport* pip = mWindow->addViewport(mCamera, 1, 0.7, 0.0, 0.3, 0.3); +// +// // Create a render queue invocation sequence for the pip viewport +// RenderQueueInvocationSequence* invocationSequence = +// mRoot->createRenderQueueInvocationSequence("pip"); +// +// // Add an invocation to the sequence +// RenderQueueInvocation* invocation = +// invocationSequence->add(RENDER_QUEUE_MAIN, "main"); +// +// // Disable render state changes and shadows for that invocation +// //invocation->setSuppressRenderStateChanges(true); +// invocation->setSuppressShadows(true); +// +// // Set the render queue invocation sequence for the pip viewport +// pip->setRenderQueueInvocationSequenceName("pip"); +// } +// +// void testViewportNoShadows(ShadowTechnique shadowTech) +// { +// mSceneMgr->setShadowTechnique(shadowTech); +// +// // Setup lighting +// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); +// Light* light = mSceneMgr->createLight("MainLight"); +// light->setType(Light::LT_DIRECTIONAL); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// light->setDirection(dir); +// +// // Create a skydome +// //mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8); +// +// // Create a floor plane mesh +// Plane plane(Vector3::UNIT_Y, 0.0); +// MeshManager::getSingleton().createPlane( +// "FloorPlane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// plane, 200000, 200000, 20, 20, true, 1, 500, 500, Vector3::UNIT_Z); +// +// +// // Add a floor to the scene +// Entity* entity = mSceneMgr->createEntity("floor", "FloorPlane"); +// entity->setMaterialName("Examples/RustySteel"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entity); +// entity->setCastShadows(false); +// +// // Add the mandatory ogre head +// entity = mSceneMgr->createEntity("head", "ogrehead.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0.0, 10.0, 0.0))->attachObject(entity); +// +// // Position and orient the camera +// mCamera->setPosition(-100.0, 50.0, 90.0); +// mCamera->lookAt(0.0, 10.0, -35.0); +// +// // Add an additional viewport on top of the other one +// Viewport* pip = mWindow->addViewport(mCamera, 1, 0.7, 0.0, 0.3, 0.3); +// pip->setShadowsEnabled(false); +// +// } +// +// void testSerialisedColour() +// { +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// Light* l = mSceneMgr->createLight("light1"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(dir); +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// /* +// ManualObject* man = static_cast( +// mSceneMgr->createMovableObject("test", ManualObjectFactory::FACTORY_TYPE_NAME)); +// +// man->begin("BaseWhiteNoLighting"); +// // Define a 40x40 plane, non-indexed +// // Define a 40x40 plane, indexed +// man->position(-20, 20, 20); +// man->colour(1, 0, 0); +// +// man->position(-20, -20, 20); +// man->colour(1, 0, 0); +// +// man->position(20, -20, 20); +// man->colour(1, 0, 0); +// +// man->position(20, 20, 20); +// man->colour(1, 0, 0); +// +// man->quad(0, 1, 2, 3); +// man->end(); +// +// MeshPtr mesh = man->convertToMesh("colourtest.mesh"); +// MeshSerializer ms; +// ms.exportMesh(mesh.getPointer(), "colourtest.mesh"); +// +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(man); +// */ +// Entity* c = mSceneMgr->createEntity("1", "colourtest.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(c); +// +// +// +// } +// +// void testBillboardAccurateFacing() +// { +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// Light* l = mSceneMgr->createLight("light1"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(dir); +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// BillboardSet* bbs = mSceneMgr->createBillboardSet("1"); +// bbs->setDefaultDimensions(50,50); +// bbs->createBillboard(-150, 25, 0); +// bbs->setBillboardType(BBT_ORIENTED_COMMON); +// bbs->setCommonDirection(Vector3::UNIT_Y); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(bbs); +// +// bbs = mSceneMgr->createBillboardSet("2"); +// bbs->setDefaultDimensions(50,50); +// bbs->createBillboard(150, 25, 0); +// bbs->setUseAccurateFacing(true); +// bbs->setBillboardType(BBT_ORIENTED_COMMON); +// bbs->setCommonDirection(Vector3::UNIT_Y); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(bbs); +// } +// +// void testMultiSceneManagersSimple() +// { +// // Create a secondary scene manager with it's own camera +// SceneManager* sm2 = Root::getSingleton().createSceneManager(ST_GENERIC); +// camera2 = sm2->createCamera("cam2"); +// camera2->setPosition(0,0,-500); +// camera2->lookAt(Vector3::ZERO); +// Entity* ent = sm2->createEntity("knot2", "knot.mesh"); +// sm2->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// Light* l = sm2->createLight("l2"); +// l->setPosition(100,50,-100); +// l->setDiffuseColour(ColourValue::Green); +// sm2->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); +// +// Viewport* vp = mWindow->addViewport(camera2, 1, 0.67, 0, 0.33, 0.25); +// vp->setOverlaysEnabled(false); +// +// // Use original SM for normal scene +// ent = mSceneMgr->createEntity("head", "ogrehead.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// l = mSceneMgr->createLight("l2"); // note same name, will work since different SM +// l->setPosition(100,50,-100); +// l->setDiffuseColour(ColourValue::Red); +// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); +// +// +// } +// +// void testMultiSceneManagersComplex() +// { +// // Create a secondary scene manager with it's own camera +// SceneManager* sm2 = Root::getSingleton().createSceneManager("TerrainSceneManager"); +// camera2 = sm2->createCamera("cam2"); +// +// Viewport* vp = mWindow->addViewport(camera2, 1, 0.5, 0, 0.5, 0.5); +// vp->setOverlaysEnabled(false); +// // Fog +// // NB it's VERY important to set this before calling setWorldGeometry +// // because the vertex program picked will be different +// ColourValue fadeColour(0.93, 0.86, 0.76); +// sm2->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000); +// vp->setBackgroundColour(fadeColour); +// +// sm2->setWorldGeometry("terrain.cfg"); +// // Infinite far plane? +// if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)) +// { +// camera2->setFarClipDistance(0); +// } +// // Set a nice viewpoint +// camera2->setPosition(707,3500,528); +// camera2->lookAt(Vector3::ZERO); +// camera2->setNearClipDistance( 1 ); +// camera2->setFarClipDistance( 1000 ); +// +// +// // Create a tertiary scene manager with it's own camera +// SceneManager* sm3 = Root::getSingleton().createSceneManager("BspSceneManager"); +// Camera* camera3 = sm3->createCamera("cam3"); +// +// vp = mWindow->addViewport(camera3, 2, 0.5, 0.5, 0.5, 0.5); +// vp->setOverlaysEnabled(false); +// +// // Load Quake3 locations from a file +// ConfigFile cf; +// +// cf.load("quake3settings.cfg"); +// +// String pk3 = cf.getSetting("Pak0Location"); +// String level = cf.getSetting("Map"); +// +// ExampleApplication::setupResources(); +// ResourceGroupManager::getSingleton().createResourceGroup("BSP"); +// ResourceGroupManager::getSingleton().setWorldResourceGroupName("BSP"); +// ResourceGroupManager::getSingleton().addResourceLocation( +// pk3, "Zip", ResourceGroupManager::getSingleton().getWorldResourceGroupName()); +// ResourceGroupManager::getSingleton().initialiseResourceGroup("BSP"); +// sm3->setWorldGeometry(level); +// // modify camera for close work +// camera3->setNearClipDistance(4); +// camera3->setFarClipDistance(4000); +// +// // Also change position, and set Quake-type orientation +// // Get random player start point +// ViewPoint viewp = sm3->getSuggestedViewpoint(true); +// camera3->setPosition(viewp.position); +// camera3->pitch(Degree(90)); // Quake uses X/Y horizon, Z up +// camera3->rotate(viewp.orientation); +// // Don't yaw along variable axis, causes leaning +// camera3->setFixedYawAxis(true, Vector3::UNIT_Z); +// camera3->yaw(Degree(-90)); +// +// +// +// +// +// // Use original SM for normal scene +// testTextureShadows(SHADOWTYPE_TEXTURE_MODULATIVE, true); +// +// } +// +// void testManualBoneMovement(void) +// { +// Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); +// +// //ent->setMaterialName("Examples/Rocky"); +// +// SkeletonInstance* skel = ent->getSkeleton(); +// Animation* anim = skel->getAnimation("Walk"); +// manuallyControlledBone = skel->getBone("Joint10"); +// manuallyControlledBone->setManuallyControlled(true); +// anim->destroyNodeTrack(manuallyControlledBone->getHandle()); +// +// //AnimationState* animState = ent->getAnimationState("Walk"); +// //animState->setEnabled(true); +// +// +// +// } +// +// void testMaterialSchemes() +// { // -// Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("schemetest", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// // default scheme -// mat->getTechnique(0)->getPass(0)->createTextureUnitState("GreenSkin.jpg"); -// -// Technique* t = mat->createTechnique(); -// t->setSchemeName("newscheme"); -// t->createPass()->createTextureUnitState("rockwall.tga"); -// ent->setMaterialName("schemetest"); -// -// // create a second viewport using alternate scheme -// Viewport* vp = mWindow->addViewport(mCamera, 1, 0.75, 0, 0.25, 0.25); -// vp->setMaterialScheme("newscheme"); -// vp->setOverlaysEnabled(false); -// -// } -// class TestMatMgrListener : public MaterialManager::Listener -// { -// public: -// TestMatMgrListener() : mTech(0) {} -// Technique* mTech; -// +// Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("schemetest", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// // default scheme +// mat->getTechnique(0)->getPass(0)->createTextureUnitState("GreenSkin.jpg"); +// +// Technique* t = mat->createTechnique(); +// t->setSchemeName("newscheme"); +// t->createPass()->createTextureUnitState("rockwall.tga"); +// ent->setMaterialName("schemetest"); +// +// // create a second viewport using alternate scheme +// Viewport* vp = mWindow->addViewport(mCamera, 1, 0.75, 0, 0.25, 0.25); +// vp->setMaterialScheme("newscheme"); +// vp->setOverlaysEnabled(false); +// +// } +// class TestMatMgrListener : public MaterialManager::Listener +// { +// public: +// TestMatMgrListener() : mTech(0) {} +// Technique* mTech; +// // -// Technique* handleSchemeNotFound(unsigned short schemeIndex, -// const String& schemeName, Material* originalMaterial, unsigned short lodIndex, -// const Renderable* rend) -// { -// return mTech; -// } -// }; -// TestMatMgrListener schemeListener; -// void testMaterialSchemesListener() -// { -// Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); -// -// // create a second viewport using alternate scheme -// // notice it's not defined in a technique -// Viewport* vp = mWindow->addViewport(mCamera, 1, 0.75, 0, 0.25, 0.25); -// vp->setMaterialScheme("newscheme"); -// vp->setOverlaysEnabled(false); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("schemetest", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// // default scheme -// mat->getTechnique(0)->getPass(0)->createTextureUnitState("GreenSkin.jpg"); +// Technique* handleSchemeNotFound(unsigned short schemeIndex, +// const String& schemeName, Material* originalMaterial, unsigned short lodIndex, +// const Renderable* rend) +// { +// return mTech; +// } +// }; +// TestMatMgrListener schemeListener; +// void testMaterialSchemesListener() +// { +// Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); +// +// // create a second viewport using alternate scheme +// // notice it's not defined in a technique +// Viewport* vp = mWindow->addViewport(mCamera, 1, 0.75, 0, 0.25, 0.25); +// vp->setMaterialScheme("newscheme"); +// vp->setOverlaysEnabled(false); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("schemetest", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// // default scheme +// mat->getTechnique(0)->getPass(0)->createTextureUnitState("GreenSkin.jpg"); // -// schemeListener.mTech = mat->getTechnique(0); +// schemeListener.mTech = mat->getTechnique(0); // -// MaterialManager::getSingleton().addListener(&schemeListener); +// MaterialManager::getSingleton().addListener(&schemeListener); // // -// } +// } // -// void testMaterialSchemesWithLOD() -// { +// void testMaterialSchemesWithLOD() +// { // -// Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); +// Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); // -// MaterialPtr mat = MaterialManager::getSingleton().create("schemetest", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// // default scheme -// mat->getTechnique(0)->getPass(0)->createTextureUnitState("GreenSkin.jpg"); +// MaterialPtr mat = MaterialManager::getSingleton().create("schemetest", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// // default scheme +// mat->getTechnique(0)->getPass(0)->createTextureUnitState("GreenSkin.jpg"); // -// // LOD 0, newscheme -// Technique* t = mat->createTechnique(); -// t->setSchemeName("newscheme"); -// t->createPass()->createTextureUnitState("rockwall.tga"); -// ent->setMaterialName("schemetest"); -// -// // LOD 1, default -// t = mat->createTechnique(); -// t->setLodIndex(1); -// t->createPass()->createTextureUnitState("WeirdEye.png"); -// -// // LOD 1, newscheme -// t = mat->createTechnique(); -// t->setLodIndex(1); -// t->createPass()->createTextureUnitState("r2skin.jpg"); -// t->setSchemeName("newscheme"); -// -// Material::LodValueList ldl; -// ldl.push_back(Math::Sqr(500.0f)); -// mat->setLodLevels(ldl); +// // LOD 0, newscheme +// Technique* t = mat->createTechnique(); +// t->setSchemeName("newscheme"); +// t->createPass()->createTextureUnitState("rockwall.tga"); +// ent->setMaterialName("schemetest"); +// +// // LOD 1, default +// t = mat->createTechnique(); +// t->setLodIndex(1); +// t->createPass()->createTextureUnitState("WeirdEye.png"); +// +// // LOD 1, newscheme +// t = mat->createTechnique(); +// t->setLodIndex(1); +// t->createPass()->createTextureUnitState("r2skin.jpg"); +// t->setSchemeName("newscheme"); +// +// Material::LodValueList ldl; +// ldl.push_back(Math::Sqr(500.0f)); +// mat->setLodLevels(ldl); // // -// ent->setMaterialName("schemetest"); -// -// // create a second viewport using alternate scheme -// Viewport* vp = mWindow->addViewport(mCamera, 1, 0.75, 0, 0.25, 0.25); -// vp->setMaterialScheme("newscheme"); -// vp->setOverlaysEnabled(false); -// -// } -// void testMaterialSchemesWithMismatchedLOD() -// { -// -// Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("schemetest", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// // default scheme -// mat->getTechnique(0)->getPass(0)->createTextureUnitState("GreenSkin.jpg"); -// -// // LOD 0, newscheme -// Technique* t = mat->createTechnique(); -// t->setSchemeName("newscheme"); -// t->createPass()->createTextureUnitState("rockwall.tga"); -// ent->setMaterialName("schemetest"); -// -// // LOD 1, default -// t = mat->createTechnique(); -// t->setLodIndex(1); -// t->createPass()->createTextureUnitState("WeirdEye.png"); -// -// // LOD 2, default -// t = mat->createTechnique(); -// t->setLodIndex(2); -// t->createPass()->createTextureUnitState("clouds.jpg"); -// -// // LOD 1, newscheme -// t = mat->createTechnique(); -// t->setLodIndex(1); -// t->createPass()->createTextureUnitState("r2skin.jpg"); -// t->setSchemeName("newscheme"); +// ent->setMaterialName("schemetest"); +// +// // create a second viewport using alternate scheme +// Viewport* vp = mWindow->addViewport(mCamera, 1, 0.75, 0, 0.25, 0.25); +// vp->setMaterialScheme("newscheme"); +// vp->setOverlaysEnabled(false); +// +// } +// void testMaterialSchemesWithMismatchedLOD() +// { +// +// Entity *ent = mSceneMgr->createEntity("robot", "robot.mesh"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// mSceneMgr->setAmbientLight(ColourValue(0.8, 0.8, 0.8)); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("schemetest", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// // default scheme +// mat->getTechnique(0)->getPass(0)->createTextureUnitState("GreenSkin.jpg"); +// +// // LOD 0, newscheme +// Technique* t = mat->createTechnique(); +// t->setSchemeName("newscheme"); +// t->createPass()->createTextureUnitState("rockwall.tga"); +// ent->setMaterialName("schemetest"); +// +// // LOD 1, default +// t = mat->createTechnique(); +// t->setLodIndex(1); +// t->createPass()->createTextureUnitState("WeirdEye.png"); +// +// // LOD 2, default +// t = mat->createTechnique(); +// t->setLodIndex(2); +// t->createPass()->createTextureUnitState("clouds.jpg"); +// +// // LOD 1, newscheme +// t = mat->createTechnique(); +// t->setLodIndex(1); +// t->createPass()->createTextureUnitState("r2skin.jpg"); +// t->setSchemeName("newscheme"); // -// // No LOD 2 for newscheme! Should fallback on LOD 1 +// // No LOD 2 for newscheme! Should fallback on LOD 1 // -// Material::LodValueList ldl; -// ldl.push_back(Math::Sqr(250.0f)); -// ldl.push_back(Math::Sqr(500.0f)); -// mat->setLodLevels(ldl); +// Material::LodValueList ldl; +// ldl.push_back(Math::Sqr(250.0f)); +// ldl.push_back(Math::Sqr(500.0f)); +// mat->setLodLevels(ldl); // // -// ent->setMaterialName("schemetest"); +// ent->setMaterialName("schemetest"); // -// // create a second viewport using alternate scheme -// Viewport* vp = mWindow->addViewport(mCamera, 1, 0.75, 0, 0.25, 0.25); -// vp->setMaterialScheme("newscheme"); -// vp->setOverlaysEnabled(false); +// // create a second viewport using alternate scheme +// Viewport* vp = mWindow->addViewport(mCamera, 1, 0.75, 0, 0.25, 0.25); +// vp->setMaterialScheme("newscheme"); +// vp->setOverlaysEnabled(false); // -// } +// } // void testSkeletonAnimationOptimise(void) // { // mSceneMgr->setShadowTextureSize(512); @@ -5839,7 +5839,7 @@ extern "C" _OgreSampleExport void dllStopPlugin() // pEnt = mSceneMgr->createEntity( "1", "robot.mesh" ); // AnimationState* a = pEnt->getAnimationState("Walk"); // a->setEnabled(true); -// mAnimStateList.push_back(a); +// mAnimStateList.push_back(a); // mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); // mTestNode[0]->attachObject( pEnt ); // mTestNode[0]->translate(+100,-100,0); @@ -5849,9 +5849,9 @@ extern "C" _OgreSampleExport void dllStopPlugin() // pEnt->setMaterialName("BaseWhite"); // a = pEnt->getAnimationState("Walk"); // a->setEnabled(true); -// mAnimStateList.push_back(a); +// mAnimStateList.push_back(a); // -// mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); // mTestNode[1]->attachObject( pEnt ); // mTestNode[1]->translate(-100,-100,0); // @@ -5860,7 +5860,7 @@ extern "C" _OgreSampleExport void dllStopPlugin() // plane.normal = Vector3::UNIT_Y; // plane.d = 100; // MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, // 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); // Entity* pPlaneEnt; // pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); @@ -5921,7 +5921,7 @@ extern "C" _OgreSampleExport void dllStopPlugin() // plane.normal = Vector3::UNIT_Y; // plane.d = 100; // MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, // 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); // Entity* pPlaneEnt; // pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); @@ -5929,1442 +5929,1442 @@ extern "C" _OgreSampleExport void dllStopPlugin() // pPlaneEnt->setCastShadows(false); // mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); // } -// void testVertexTexture() -// { -// -// // NOTE: DirectX only right now -// -// Light* l = mSceneMgr->createLight("MainLight"); -// l->setType(Light::LT_POINT); -// l->setPosition(0, 200, 0); -// -// -// // Create single-channel floating point texture, no mips -// TexturePtr tex = TextureManager::getSingleton().createManual( -// "vertexTexture", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, -// 128, 128, 0, PF_FLOAT32_R); -// float* pData = static_cast( -// tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD)); -// // write concentric circles into the texture -// for (int y = -64; y < 64; ++y) -// { -// for (int x = -64; x < 64; ++x) -// { -// -// float val = Math::Sqrt(x*x + y*y); -// // repeat every 20 pixels -// val = val * Math::TWO_PI / 20.0f; -// *pData++ = Math::Sin(val); -// } -// } -// tex->getBuffer()->unlock(); -// -// String progSource = -// "void main(\n" -// "float4 pos : POSITION,\n" -// "float2 uv1 : TEXCOORD0,\n" -// "uniform float4x4 world, \n" -// "uniform float4x4 viewProj,\n" -// "uniform float heightscale,\n" -// "uniform sampler2D heightmap,\n" -// "out float4 oPos : POSITION,\n" -// "out float2 oUv1 : TEXCOORD1,\n" -// "out float4 col : COLOR)\n" -// "{\n" -// "oPos = mul(world, pos);\n" -// "// tex2Dlod since no mip\n" -// "float4 t = float4(0,0,0,0);\n" -// "t.xy = uv1.xy;\n" -// "float height = tex2Dlod(heightmap, t);\n" -// "oPos.y = oPos.y + (height * heightscale);\n" -// "oPos = mul(viewProj, oPos);\n" -// "oUv1 = uv1;\n" -// "col = float4(1,1,1,1);\n" -// "}\n"; -// HighLevelGpuProgramPtr prog = HighLevelGpuProgramManager::getSingleton().createProgram( -// "TestVertexTextureFetch", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// "hlsl", GPT_VERTEX_PROGRAM); -// prog->setSource(progSource); -// prog->setParameter("target", "vs_3_0"); -// prog->setVertexTextureFetchRequired(true); -// prog->setParameter("entry_point", "main"); -// prog->load(); -// -// -// MaterialPtr mat = MaterialManager::getSingleton().create("TestVertexTexture", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* pass = mat->getTechnique(0)->getPass(0); -// pass->setLightingEnabled(false); -// pass->setVertexProgram("TestVertexTextureFetch"); -// GpuProgramParametersSharedPtr vp = pass->getVertexProgramParameters(); -// vp->setNamedAutoConstant("world", GpuProgramParameters::ACT_WORLD_MATRIX); -// vp->setNamedAutoConstant("viewProj", GpuProgramParameters::ACT_VIEWPROJ_MATRIX); -// vp->setNamedConstant("heightscale", 30.0f); -// // vertex texture -// TextureUnitState* t = pass->createTextureUnitState("vertexTexture"); -// t->setBindingType(TextureUnitState::BT_VERTEX); -// // regular texture -// pass->createTextureUnitState("BumpyMetal.jpg"); -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// // 128 x 128 segment plane -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,128,128,true,1,1,1,Vector3::UNIT_Z); -// Entity* pPlaneEnt; -// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("TestVertexTexture"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// -// } -// -// void testBackgroundLoadResourceGroup() -// { -// ResourceGroupManager& rgm = ResourceGroupManager::getSingleton(); -// TextureManager& tm = TextureManager::getSingleton(); -// MeshManager& mm = MeshManager::getSingleton(); -// -// testBackgroundLoadGroup = "Deferred"; -// -// rgm.createResourceGroup(testBackgroundLoadGroup); -// -// // define a bunch of textures as deferred loading -// rgm.declareResource("egyptrockyfull.jpg", tm.getResourceType(), testBackgroundLoadGroup); -// rgm.declareResource("fw12b.jpg", tm.getResourceType(), testBackgroundLoadGroup); -// rgm.declareResource("grass_1024.jpg", tm.getResourceType(), testBackgroundLoadGroup); -// rgm.declareResource("GreenSkin.jpg", tm.getResourceType(), testBackgroundLoadGroup); -// rgm.declareResource("MtlPlat2.jpg", tm.getResourceType(), testBackgroundLoadGroup); -// rgm.declareResource("NMBumpsOut.png", tm.getResourceType(), testBackgroundLoadGroup); -// rgm.declareResource("ogrehead.mesh", mm.getResourceType(), testBackgroundLoadGroup); -// // Note: initialise resource group in main thread for this test -// // We will be able to initialise in the background thread too eventually, -// // once resources can be created thread safely as well as loaded -// rgm.initialiseResourceGroup(testBackgroundLoadGroup); -// -// // we won't load it yet, we'll wait for 5 seconds -// -// -// // Create a basic plane to have something in the scene to look at -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt; -// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// -// -// -// } -// -// -// -// void testOverlayRelativeMode() -// { -// -// Overlay* o = OverlayManager::getSingleton().create("Test"); -// OverlayContainer* c = (OverlayContainer*)OverlayManager::getSingleton().createOverlayElement("Panel", "panel1"); -// c->setMetricsMode(GMM_RELATIVE); -// c->setDimensions(1.0, 1.0); -// c->setMaterialName("Core/StatsBlockCenter"); -// c->setPosition(0.0, 0.0); -// -// TextAreaOverlayElement* t = (TextAreaOverlayElement*)OverlayManager::getSingleton().createOverlayElement("TextArea", "text1"); -// t->setMetricsMode(GMM_RELATIVE); -// t->setCaption("Hello"); -// t->setPosition(0,0); -// t->setFontName("BlueHighway"); -// t->setDimensions(0.2, 0.5); -// t->setCharHeight(0.2); -// c->addChild(t); -// -// o->add2D(c); -// o->show(); -// -// } -// -// void testBillboardOrigins() -// { -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// Vector3 dir(-1, -1, 0.5); -// dir.normalise(); -// Light* l = mSceneMgr->createLight("light1"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(dir); -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 0; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// BillboardSet* bbs = mSceneMgr->createBillboardSet("1"); -// bbs->setDefaultDimensions(50,50); -// bbs->createBillboard(0, 0, 0); -// bbs->setBillboardOrigin(BBO_TOP_LEFT); -// //bbs->setBillboardType(BBT_ORIENTED_COMMON); -// bbs->setCommonDirection(Vector3::UNIT_Y); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(bbs); -// -// } -// -// void testDepthBias() -// { -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../../Tests/Media", "FileSystem"); -// -// mSceneMgr->setAmbientLight(ColourValue::White); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("mat1", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->createTextureUnitState("BumpyMetal.jpg"); -// -// const String meshName("cube.mesh"); -// Entity* entity = mSceneMgr->createEntity("base", meshName); -// entity->setMaterialName("mat1"); -// mSceneMgr->getRootSceneNode()->attachObject(entity); -// -// -// entity = mSceneMgr->createEntity("base2", meshName); -// entity->setMaterialName("Examples/EnvMappedRustySteel"); -// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// n->setPosition(-30, 0, 0); -// n->yaw(Degree(45)); -// n->attachObject(entity); -// -// for (size_t i = 0; i <= 6;++i) -// { -// String name("decal"); -// name += StringConverter::toString(i); -// -// MaterialPtr pMat = static_cast(MaterialManager::getSingleton().create( -// name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)); -// -// pMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); -// pMat->getTechnique(0)->getPass(0)->setAlphaRejectSettings(CMPF_GREATER_EQUAL, 128); -// pMat->getTechnique(0)->getPass(0)->setDepthBias(i); -// pMat->getTechnique(0)->getPass(0)->createTextureUnitState(name + ".png"); -// -// entity = mSceneMgr->createEntity(name, meshName); -// entity->setMaterialName(name); -// mSceneMgr->getRootSceneNode()->attachObject(entity); -// } -// -// -// -// mCamera->setPosition(0,0,200); -// mCamera->lookAt(Vector3::ZERO); -// -// -// } -// -// -// class GrassListener : public FrameListener -// { -// protected: -// SceneManager* mSceneManager; -// public: -// GrassListener(SceneManager* sceneManager) : -// mSceneManager(sceneManager) -// { -// } -// void waveGrass(Real timeElapsed) -// { -// static Real xinc = Math::PI * 0.4; -// static Real zinc = Math::PI * 0.55; -// static Real xpos = Math::RangeRandom(-Math::PI, Math::PI); -// static Real zpos = Math::RangeRandom(-Math::PI, Math::PI); -// -// xpos += xinc * timeElapsed; -// zpos += zinc * timeElapsed; -// -// // Update vertex program parameters by binding a value to each renderable -// static Vector4 offset(0,0,0,0); -// Entity *e; -// for (size_t i=0; i<12; i++) -// { -// e = mSceneManager->getEntity("GrassBlades" + StringConverter::toString(i)); -// xpos += e->getParentNode()->_getDerivedPosition().x * 0.001; -// zpos += e->getParentNode()->_getDerivedPosition().z * 0.001; -// offset.x = Math::Sin(xpos) * 0.05; -// offset.z = Math::Sin(zpos) * 0.05; -// e->getSubEntity(0)->setCustomParameter(999, offset); -// } -// } -// -// bool frameStarted(const FrameEvent& evt) -// { -// waveGrass(evt.timeSinceLastFrame); -// return true; -// } -// }; -// -// void testStringTokenising() -// { -// static const String TEST_STRINGS[] = { -// "this is just a normal sample", -// "This one actually \"uses quotes\" and stuff", -// "\"This one\" started with a quote", -// "\"This one\" has more \"than one\" quote in it", -// "\"This one\"\"has no delimeter\"between the two quotes", -// "This one has many spaces that should be disregarded" -// }; -// static const size_t NUM_STRINGS = sizeof(TEST_STRINGS) / sizeof(TEST_STRINGS[0]); -// -// for (size_t i=0; isetShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE); -// -// -// LiSPSMShadowCameraSetup *mLiSPSMSetup = new LiSPSMShadowCameraSetup(); -// //mLiSPSMSetup->setUseAggressiveFocusRegion(false); -// ShadowCameraSetupPtr mCurrentShadowCameraSetup = ShadowCameraSetupPtr(mLiSPSMSetup); -// //ShadowCameraSetupPtr mCurrentShadowCameraSetup = ShadowCameraSetupPtr(new PlaneOptimalShadowCameraSetup(mPlane)); -// mSceneMgr->setShadowCameraSetup(mCurrentShadowCameraSetup); -// -// PixelFormat pxFmt = PF_L8; -// if (Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_TEXTURE_FLOAT)) -// { -// if (Root::getSingleton().getRenderSystem()->getName().find("GL") != String::npos) -// { -// // GL performs much better if you pick half-float format -// pxFmt = PF_FLOAT16_R; -// } -// else -// { -// // D3D is the opposite - if you ask for PF_FLOAT16_R you -// // get an integer format instead! You can ask for PF_FLOAT16_GR -// // but the precision doesn't work well -// pxFmt = PF_FLOAT32_R; -// } -// } -// mSceneMgr->setShadowTextureSettings(1024, 1, pxFmt); -// -// // New depth shadow mapping -// String CUSTOM_ROCKWALL_MATERIAL("Ogre/DepthShadowmap/Receiver/RockWall"); -// String CUSTOM_CASTER_MATERIAL("Ogre/DepthShadowmap/Caster/Float"); -// String CUSTOM_RECEIVER_MATERIAL("Ogre/DepthShadowmap/Receiver/Float"); -// -// mSceneMgr->setShadowTextureCasterMaterial(CUSTOM_CASTER_MATERIAL); -// mSceneMgr->setShadowTextureReceiverMaterial(CUSTOM_RECEIVER_MATERIAL); -// mSceneMgr->setShadowTextureSelfShadow(true); -// -// mSceneMgr->setShadowTextureFadeStart(1.0); -// mSceneMgr->setShadowTextureFadeEnd(1.0); -// -// mSceneMgr->setShadowTextureSelfShadow(true); -// -// MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); -// MaterialManager::getSingleton().setDefaultAnisotropy(5); -// -// mSceneMgr->setShadowDirLightTextureOffset(0.2); -// mSceneMgr->setShadowFarDistance(150); -// //mSceneMgr->setShadowCasterRenderBackFaces(false); -// -// // Create a basic plane to have something in the scene to look at -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshPtr msh = MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 4500,4500,100,100,true,1,40,40,Vector3::UNIT_Z); -// msh->buildTangentVectors(VES_TANGENT); -// Entity* pPlaneEnt; -// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// -// pPlaneEnt->setMaterialName(CUSTOM_ROCKWALL_MATERIAL); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// -// -// // Reorient the plane and create a plane mesh for the test planes -// plane.normal = Vector3::UNIT_Z; -// MeshManager::getSingleton().createPlane( -// "Test_Plane", "OgreTestNonDefaultShadowMaterials", -// plane, 50.0, 50.0, 1, 1, true); -// -// -// const String GRASSMAT("Examples/GrassBladesAdditiveFloatTransparent"); -// //const String GRASSMAT("Examples/DepthShadowmap/CasterReceiver/GrassBlades"); -// //const String GRASSMAT("tree4324");//"tree1.tga"); -// -// -// // Add test plane entities to the scene -// Entity* entity = mSceneMgr->createEntity("GrassBlades0", "Test_Plane"); -// entity->setMaterialName(GRASSMAT); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(0.0, -100.0+25.0, 0.0))->attachObject(entity); -// -// -// entity = mSceneMgr->createEntity("GrassBlades1", "Test_Plane"); -// entity->setMaterialName(GRASSMAT); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(0.0, -100.0+25.0, -20.0))->attachObject(entity); -// -// entity = mSceneMgr->createEntity("GrassBlades2", "Test_Plane"); -// entity->setMaterialName(GRASSMAT); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(0.0, -100.0+25.0, -40.0))->attachObject(entity); -// -// // Add test plane entities to the scene, shadowed partially by athene mesh -// entity = mSceneMgr->createEntity("GrassBlades3", "Test_Plane"); -// entity->setMaterialName(GRASSMAT); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(-80.0, -100.0+25.0, 0.0))->attachObject(entity); -// -// entity = mSceneMgr->createEntity("GrassBlades4", "Test_Plane"); -// entity->setMaterialName(GRASSMAT); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(-130.0, -100.0+25.0, -20.0))->attachObject(entity); -// -// entity = mSceneMgr->createEntity("GrassBlades5", "Test_Plane"); -// entity->setMaterialName(GRASSMAT); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(-180.0, -100.0+25.0, -40.0))->attachObject(entity); -// -// -// -// Entity* ent = mSceneMgr->createEntity("athene", "athene.mesh"); -// ent->setMaterialName(CUSTOM_ROCKWALL_MATERIAL); -// //ent->setMaterialName(GRASSMAT); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,-20,-20))->attachObject(ent); -// -// // Add test plane entities to the scene, one after another -// entity = mSceneMgr->createEntity("GrassBlades6", "Test_Plane"); -// entity->setMaterialName(GRASSMAT); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(-260.0, -100.0+25.0, 0.0))->attachObject(entity); -// -// entity = mSceneMgr->createEntity("GrassBlades7", "Test_Plane"); -// entity->setMaterialName(GRASSMAT); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(-260.0, -100.0+25.0, -10.0))->attachObject(entity); -// -// entity = mSceneMgr->createEntity("GrassBlades8", "Test_Plane"); -// entity->setMaterialName(GRASSMAT); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(-260.0, -100.0+25.0, -20.0))->attachObject(entity); -// -// // Add test plane entities to the scene, alone with other material -// -// const String GRASSMAT_CUSTOM_DEFAULT_CUSTOM("Examples/GrassBladesAdditiveFloat"); -// const String GRASSMAT_CUSTOM_NOSPECIAL_CUSTOM("Examples/GrassBladesAdditive"); -// const String GRASSMAT_ORIG("Examples/GrassBlades"); -// -// entity = mSceneMgr->createEntity("GrassBlades9", "Test_Plane"); -// entity->setMaterialName(GRASSMAT_CUSTOM_DEFAULT_CUSTOM); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(-80.0, -100.0+25.0, -80.0))->attachObject(entity); -// -// entity = mSceneMgr->createEntity("GrassBlades10", "Test_Plane"); -// entity->setMaterialName(GRASSMAT_CUSTOM_NOSPECIAL_CUSTOM); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(-130.0, -100.0+25.0, -90.0))->attachObject(entity); -// -// entity = mSceneMgr->createEntity("GrassBlades11", "Test_Plane"); -// entity->setMaterialName(GRASSMAT_ORIG); -// mSceneMgr->getRootSceneNode()->createChildSceneNode( -// Vector3(-180.0, -100.0+25.0, -90.0))->attachObject(entity); -// -// // Position and orient the camera -// //mCamera->setPosition(-55.0, 40.0, 100.0); -// //mCamera->lookAt(-10.0, 20.0, -35.0); -// mCamera->setPosition(-75.0, 30.0, 150.0); -// mCamera->lookAt(0.0, 20.0, -35.0); -// -// //mSceneMgr->setAmbientLight(ColourValue::Black); -// Light* l; -// -// l = mSceneMgr->createLight("Dir1"); -// l->setType(Light::LT_DIRECTIONAL); -// //l->setAttenuation(5000,1,0,0); -// Vector3 dir1(0.0, -0.7, -0.5); -// dir1.normalise(); -// l->setDirection(dir1); -// l->setCastShadows(true); -// -// l->setDiffuseColour(ColourValue(1.0, 1.0, 1.0)); -// -// -// mSceneMgr->setAmbientLight(ColourValue(0.0, 0.0, 0.2)); -// -// // l = mSceneMgr->createLight("Spot2"); -// // l->setAttenuation(5000,1,0,0); -// // /* // spotlight */ -// // l->setType(Light::LT_SPOTLIGHT); -// // l->setSpotlightRange(Degree(30),Degree(45),1.0f); -// // -// // -// // SceneNode* lightNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// // lightNode2->attachObject(l); -// // lightNode2->setPosition(-500, 200, 500); -// // lightNode2->lookAt(Vector3(0,-200,0), Node::TS_WORLD); -// // l->setDirection(Vector3::NEGATIVE_UNIT_Z); -// //lightNode2->setPosition(-75.0, 30.0, 150.0); -// //lightNode2->lookAt(Vector3(.0, 20.0, -35.0), Node::TS_WORLD); -// -// -// -// addTextureShadowDebugOverlay(1); -// -// Root::getSingleton().addFrameListener(new GrassListener(mSceneMgr)); -// -// } -// -// void testTextureShadowsIntegrated() -// { -// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED); -// //mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); -// MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); -// MaterialManager::getSingleton().setDefaultAnisotropy(5); -// -// mSceneMgr->setShadowTextureSettings(1024, 2); -// -// mSceneMgr->setAmbientLight(ColourValue::Black); -// Light* l = mSceneMgr->createLight("Spot1"); -// l->setType(Light::LT_SPOTLIGHT); -// l->setAttenuation(5000,1,0,0); -// l->setSpotlightRange(Degree(30),Degree(45),1.0f); -// SceneNode* lightNode1 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// lightNode1->attachObject(l); -// lightNode1->setPosition(400, 250, 500); -// lightNode1->lookAt(Vector3(0,-200,0), Node::TS_WORLD); -// l->setDirection(Vector3::NEGATIVE_UNIT_Z); -// l->setDiffuseColour(0.7, 0.7, 0.5); -// -// l = mSceneMgr->createLight("Spot2"); -// l->setAttenuation(5000,1,0,0); -// /* // spotlight */ -// l->setType(Light::LT_SPOTLIGHT); -// l->setSpotlightRange(Degree(30),Degree(45),1.0f); -// /**/ -// // point -// SceneNode* lightNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// lightNode2->attachObject(l); -// lightNode2->setPosition(-500, 200, 500); -// lightNode2->lookAt(Vector3(0,-200,0), Node::TS_WORLD); -// l->setDirection(Vector3::NEGATIVE_UNIT_Z); -// /* // directional -// l->setType(Light::LT_DIRECTIONAL); -// Vector3 dir(0.5, -1, 0.5); -// dir.normalise(); -// l->setDirection(dir); -// */ -// l->setDiffuseColour(1, 0.2, 0.2); -// -// /* -// // Test spot 3 -// l = mSceneMgr->createLight("Spot3"); -// l->setType(Light::LT_SPOTLIGHT); -// l->setAttenuation(5000,1,0,0); -// l->setSpotlightRange(Degree(30),Degree(45),1.0f); -// SceneNode* lightNode3 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// lightNode3->attachObject(l); -// lightNode3->setPosition(700, 250, 500); -// lightNode3->lookAt(Vector3(0,-200,0), Node::TS_WORLD); -// l->setDirection(Vector3::NEGATIVE_UNIT_Z); -// l->setDiffuseColour(0.0, 0.7, 1.0); -// */ -// -// // Create a basic plane to have something in the scene to look at -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshPtr msh = MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 4500,4500,100,100,true,1,40,40,Vector3::UNIT_Z); -// msh->buildTangentVectors(VES_TANGENT); -// Entity* pPlaneEnt; -// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// //pPlaneEnt->setMaterialName("Examples/OffsetMapping/Specular"); -// pPlaneEnt->setMaterialName("Examples/OffsetMapping/IntegratedShadows"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// pPlaneEnt = mSceneMgr->createEntity( "plane2", "Myplane" ); -// //pPlaneEnt->setMaterialName("Examples/OffsetMapping/Specular"); -// pPlaneEnt->setMaterialName("Examples/OffsetMapping/IntegratedShadows"); -// pPlaneEnt->setCastShadows(false); -// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// n->roll(Degree(90)); -// n->translate(100,0,0); -// //n->attachObject(pPlaneEnt); -// -// pPlaneEnt = mSceneMgr->createEntity( "plane3", "Myplane" ); -// //pPlaneEnt->setMaterialName("Examples/OffsetMapping/Specular"); -// pPlaneEnt->setMaterialName("Examples/OffsetMapping/IntegratedShadows"); -// pPlaneEnt->setCastShadows(false); -// n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// n->pitch(Degree(90)); -// n->yaw(Degree(-90)); -// n->translate(0,0,-100); -// n->attachObject(pPlaneEnt); -// -// mCamera->setPosition(-50, 500, 1000); -// mCamera->lookAt(Vector3(-50,-100,0)); -// -// Entity* ent = mSceneMgr->createEntity("athene", "athene.mesh"); -// ent->setMaterialName("Examples/Athene/NormalMapped"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,-20,0))->attachObject(ent); -// -// addTextureShadowDebugOverlay(2); -// -// -// -// } -// -// void testTextureShadowsIntegratedPSSM() -// { -// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED); -// -// // 3 textures per directional light -// mSceneMgr->setShadowTextureCountPerLightType(Ogre::Light::LT_DIRECTIONAL, 3); -// mSceneMgr->setShadowTextureSettings(512, 3, PF_FLOAT32_R); -// mSceneMgr->setShadowTextureSelfShadow(true); -// // Set up caster material - this is just a standard depth/shadow map caster -// mSceneMgr->setShadowTextureCasterMaterial("PSSM/shadow_caster"); -// -// // shadow camera setup -// PSSMShadowCameraSetup* pssmSetup = new PSSMShadowCameraSetup(); -// pssmSetup->calculateSplitPoints(3, mCamera->getNearClipDistance(), mCamera->getFarClipDistance()); -// pssmSetup->setSplitPadding(10); -// pssmSetup->setOptimalAdjustFactor(0, 2); -// pssmSetup->setOptimalAdjustFactor(1, 1); -// pssmSetup->setOptimalAdjustFactor(2, 0.5); -// -// mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(pssmSetup)); -// -// -// mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); -// Light* l = mSceneMgr->createLight("Dir"); -// l->setType(Light::LT_DIRECTIONAL); -// Vector3 dir(0.3, -1, 0.2); -// dir.normalise(); -// l->setDirection(dir); -// -// -// // Create a basic plane to have something in the scene to look at -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshPtr msh = MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 4500,4500,100,100,true,1,40,40,Vector3::UNIT_Z); -// msh->buildTangentVectors(VES_TANGENT); -// Entity* pPlaneEnt; -// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("PSSM/Plane"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// mCamera->setPosition(-50, 500, 1000); -// mCamera->lookAt(Vector3(-50,-100,0)); -// -// Entity* ent = mSceneMgr->createEntity("knot", "knot.mesh"); -// ent->setMaterialName("PSSM/Knot"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0))->attachObject(ent); -// createRandomEntityClones(ent, 20, Vector3(-1000,0,-1000), Vector3(1000,0,1000)); -// -// -// Vector4 splitPoints; -// const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssmSetup->getSplitPoints(); -// for (int i = 0; i < 3; ++i) -// { -// splitPoints[i] = splitPointList[i]; -// } -// MaterialPtr mat = MaterialManager::getSingleton().getByName("PSSM/Plane"); -// mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("pssmSplitPoints", splitPoints); -// mat = MaterialManager::getSingleton().getByName("PSSM/Knot"); -// mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("pssmSplitPoints", splitPoints); -// -// addTextureShadowDebugOverlay(3); -// -// -// -// } -// void testTimeCreateDestroyObject() -// { -// int iterationCount = 100000; -// -// // Create names ahead of time -// StringVector nameList; -// nameList.reserve(iterationCount); -// for (int i = 0; i < iterationCount; ++i) -// { -// nameList.push_back("somerelativelylongtestname" + StringConverter::toString(i)); -// } -// -// Timer timer; -// StringVector::iterator nameIt = nameList.begin(); -// timer.reset(); -// for (int i = 0; i < iterationCount; ++i, ++nameIt) -// { -// ManualObject* man = mSceneMgr->createManualObject(*nameIt); -// } -// unsigned long createTime = timer.getMilliseconds(); -// -// nameIt = nameList.begin(); -// timer.reset(); -// for (int i = 0; i < iterationCount; ++i, ++nameIt) -// { -// ManualObject* man = mSceneMgr->getManualObject(*nameIt); -// // do something so compiler doesn't think I'm doing nothing -// man->setVisible(true); -// } -// unsigned long lookupTime = timer.getMilliseconds(); -// -// nameIt = nameList.begin(); -// timer.reset(); -// for (int i = 0; i < iterationCount; ++i, ++nameIt) -// { -// mSceneMgr->destroyManualObject(*nameIt); -// } -// unsigned long destroyTime = timer.getMilliseconds(); -// -// nameIt = nameList.begin(); -// timer.reset(); -// for (int i = 0; i < iterationCount; ++i, ++nameIt) -// { -// mSceneMgr->createSceneNode(*nameIt); -// } -// unsigned long sncreateTime = timer.getMilliseconds(); -// -// nameIt = nameList.begin(); -// timer.reset(); -// for (int i = 0; i < iterationCount; ++i, ++nameIt) -// { -// mSceneMgr->destroySceneNode(*nameIt); -// } -// unsigned long sndestroyTime = timer.getMilliseconds(); -// -// LogManager::getSingleton().stream() -// << "Object create time: " << ((float)createTime / 1000.0f) << " secs\n" -// << "Object lookup time: " << ((float)lookupTime / 1000.0f) << " secs\n" -// << "Object destroy time: " << ((float)destroyTime / 1000.0f) << " secs\n" -// << "SceneNode create time: " << ((float)sncreateTime / 1000.0f) << " secs\n" -// << "SceneNode destroy time: " << ((float)sndestroyTime / 1000.0f) << " secs\n"; -// -// } -// -// void testLightScissoring(bool cliptoo) -// { -// mSceneMgr->setAmbientLight(ColourValue::White); -// -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 0; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("Examples/GrassFloor"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// Real lightRange = 100; -// -// ManualObject* debugSphere = mSceneMgr->createManualObject("debugSphere"); -// debugSphere->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); -// for (int i = 0; i <= 20; ++i) -// { -// Vector3 basePos(lightRange, 0, 0); -// Quaternion quat; -// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y); -// basePos = quat * basePos; -// debugSphere->position(basePos); -// } -// for (int i = 0; i <= 20; ++i) -// { -// Vector3 basePos(lightRange, 0, 0); -// Quaternion quat; -// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Z); -// basePos = quat * basePos; -// debugSphere->position(basePos); -// } -// debugSphere->end(); -// -// ManualObject* debugSphere2 = mSceneMgr->createManualObject("debugSphere2"); -// debugSphere2->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); -// for (int i = 0; i <= 20; ++i) -// { -// Vector3 basePos(lightRange, 0, 0); -// Quaternion quat; -// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y); -// basePos = quat * basePos; -// debugSphere2->position(basePos); -// } -// for (int i = 0; i <= 20; ++i) -// { -// Vector3 basePos(lightRange, 0, 0); -// Quaternion quat; -// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Z); -// basePos = quat * basePos; -// debugSphere2->position(basePos); -// } -// debugSphere2->end(); -// -// Light* l = mSceneMgr->createLight("l1"); -// l->setAttenuation(lightRange, 1, 0, 0); -// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,95,0)); -// n->attachObject(debugSphere); -// n->attachObject(l); -// -// Light* l2 = mSceneMgr->createLight("l2"); -// l2->setAttenuation(lightRange, 1, 0, 0); -// SceneNode* n2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,50,0)); -// n2->attachObject(debugSphere2); -// n2->attachObject(l2); -// -// // Modify the plane material so that it clips to the light -// // Normally you'd only clip a secondary pass but this is engineered so you -// // can actually see the scissoring effect -// MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/GrassFloor"); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightScissoringEnabled(true); -// if (cliptoo) -// p->setLightClipPlanesEnabled(true); -// -// -// mCamera->setPosition(0, 200, 300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// -// void testLightClipPlanes(bool scissortoo) -// { -// mSceneMgr->setAmbientLight(ColourValue::White); -// -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 0; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("Examples/GrassFloor"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(150,0,100))->attachObject(pPlaneEnt); -// -// Real lightRange = 1000; -// Real spotWidth = 300; -// -// ManualObject* debugSphere = mSceneMgr->createManualObject("debugSphere"); -// debugSphere->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); -// for (int i = 0; i <= 20; ++i) -// { -// Vector3 basePos(spotWidth, 0, 0); -// Quaternion quat; -// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y); -// basePos = quat * basePos; -// debugSphere->position(basePos); -// } -// debugSphere->end(); -// -// Light* l = mSceneMgr->createLight("l1"); -// l->setAttenuation(lightRange, 1, 0, 0); -// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,0,0)); -// n->attachObject(debugSphere); -// /* SPOT LIGHT -// */ -// // match spot width to groud -// Real spotHeight = lightRange * 0.5; -// n = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,spotHeight,0)); -// l->setType(Light::LT_SPOTLIGHT); -// Radian spotAngle = Math::ATan(spotWidth / spotHeight) * 2; -// l->setSpotlightOuterAngle(spotAngle); -// l->setSpotlightInnerAngle(spotAngle * 0.75); -// Vector3 dir(0, -1, 0); -// dir.normalise(); -// l->setDirection(dir); -// -// /* END SPOT LIGHT */ -// n->attachObject(l); -// -// // Modify the plane material so that it clips to the light -// // Normally you'd only clip a secondary pass but this is engineered so you -// // can actually see the scissoring effect -// MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/GrassFloor"); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightClipPlanesEnabled(true); -// if (scissortoo) -// p->setLightScissoringEnabled(true); -// -// mCamera->setPosition(0, 200, 300); -// mCamera->lookAt(Vector3::ZERO); -// -// -// -// } -// -// void testLightClipPlanesMoreLights(bool scissortoo) -// { -// mSceneMgr->setAmbientLight(ColourValue(0.3, 0.25, 0.2, 0)); -// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE); -// mSceneMgr->setShadowTextureCount(3); -// -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 0; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 4500,4500,100,100,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("Examples/GrassFloor"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// Real lightRange = 1000; -// Real spotWidth = 300; -// -// int numLights = 8; -// Real xoff = -numLights * spotWidth * 0.5; -// -// -// for (int i = 0; i < numLights; ++i) -// { -// Light* l = mSceneMgr->createLight("l" + StringConverter::toString(i)); -// l->setAttenuation(lightRange, 1, 0, 0); -// /* SPOT LIGHT -// */ -// // match spot width to groud -// Real spotHeight = lightRange * 0.5; -// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3((spotWidth+50)*i + xoff,spotHeight,0)); -// l->setType(Light::LT_SPOTLIGHT); -// Radian spotAngle = Math::ATan(spotWidth / spotHeight) * 2; -// l->setSpotlightOuterAngle(spotAngle); -// l->setSpotlightInnerAngle(spotAngle * 0.75); -// Vector3 dir(0, -1, 0); -// dir.normalise(); -// l->setDirection(dir); -// -// /* END SPOT LIGHT */ -// n->attachObject(l); -// -// Entity* e = mSceneMgr->createEntity("e" + StringConverter::toString(i), "robot.mesh"); -// SceneNode* en = n->createChildSceneNode(Vector3(0, -200, 0)); -// en->attachObject(e); -// -// -// } -// -// // Modify the plane material so that it clips to the light on the second pass, post ambient -// -// MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/GrassFloor"); -// Pass* p = mat->getTechnique(0)->getPass(0); -// String texname = p->getTextureUnitState(0)->getTextureName(); -// p->removeAllTextureUnitStates(); -// p->setIlluminationStage(IS_AMBIENT); -// p->setDiffuse(ColourValue::Black); -// p = mat->getTechnique(0)->createPass(); -// p->setIlluminationStage(IS_PER_LIGHT); -// p->setIteratePerLight(true, false); -// p->setAmbient(ColourValue::Black); -// p->setLightClipPlanesEnabled(true); -// p->setSceneBlending(SBT_ADD); -// if (scissortoo) -// p->setLightScissoringEnabled(true); -// p = mat->getTechnique(0)->createPass(); -// p->setIlluminationStage(IS_DECAL); -// p->createTextureUnitState(texname); -// p->setLightingEnabled(false); -// p->setSceneBlending(SBT_MODULATE); -// -// -// mCamera->setPosition(0, 200, 300); -// mCamera->lookAt(Vector3::ZERO); -// -// -// -// } -// -// void testMRT() -// { -// TexturePtr Tex[2]; -// MultiRenderTarget* mrtTex; -// -// Viewport* viewport = mWindow->getViewport(0); -// int width = viewport->getActualWidth(); -// int height = viewport->getActualHeight(); -// -// Tex[0] = TextureManager::getSingleton().createManual("diffusemap", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, -// width,height,0,PF_R8G8B8A8,TU_RENDERTARGET); -// Tex[1] = TextureManager::getSingleton().createManual("normalmap",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, -// width,height,0,PF_R8G8B8A8,TU_RENDERTARGET); -// -// // assert(Tex[0]->getFormat() == PF_FLOAT16_RGBA); -// -// mrtTex = Ogre::Root::getSingleton().getRenderSystem()->createMultiRenderTarget("MRT"); -// RenderTexture* rTex[2]; -// rTex[0] = Tex[0]->getBuffer()->getRenderTarget(); -// rTex[1] = Tex[1]->getBuffer()->getRenderTarget(); -// -// rTex[0]->setAutoUpdated(false); -// rTex[1]->setAutoUpdated(false); -// mrtTex->bindSurface(0, rTex[0]); -// mrtTex->bindSurface(1, rTex[1]); -// mrtTex->setAutoUpdated(true); -// -// Viewport *v = mrtTex->addViewport(mCamera); -// v->setMaterialScheme("MRT"); -// v->setClearEveryFrame(true); -// v->setOverlaysEnabled(false); -// v->setSkiesEnabled(false); -// v->setBackgroundColour(ColourValue(0,0,0,0)); -// -// // Create texture overlay here -// Overlay *debugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); -// MaterialPtr debugMat = MaterialManager::getSingleton().create("DebugRTTMat1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); -// TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState("normalmap"); -// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); -// OverlayContainer *debugPanel = (OverlayContainer *) (OverlayManager::getSingleton().createOverlayElement("Panel","DebugRTTPanel1")); -// debugPanel->_setPosition(0.8,0); -// debugPanel->_setDimensions(0.2,0.3); -// debugPanel->setMaterialName(debugMat->getName()); -// debugOverlay->add2D(debugPanel); -// -// debugMat = MaterialManager::getSingleton().create("DebugRTTMat2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); -// t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState("diffusemap"); -// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); -// debugPanel = (OverlayContainer *) (OverlayManager::getSingleton().createOverlayElement("Panel","DebugRTTPanel2")); -// debugPanel->_setPosition(0.8,0.3); -// debugPanel->_setDimensions(0.2,0.3); -// debugPanel->setMaterialName(debugMat->getName()); -// debugOverlay->add2D(debugPanel); -// // Create scene items -// -// // Create a material to render differently to MRT compared to main viewport -// MaterialPtr mat = MaterialManager::getSingleton().create("MRTTest", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// // normal technique (0), leave as default -// Technique* mrtTech = mat->createTechnique(); -// mrtTech->setSchemeName("MRT"); -// Pass* mrtPass = mrtTech->createPass(); -// mrtPass->setVertexProgram("DeferredShading/material/hlsl/vs"); -// mrtPass->setFragmentProgram("DeferredShading/material/hlsl/ps"); -// mrtPass->createTextureUnitState("rockwall.tga"); -// mat->load(); -// -// Entity* ent = mSceneMgr->createEntity("knot", "knot.mesh"); -// ent->setMaterialName("MRTTest"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); -// -// mCamera->setPosition(0, 0, 200); -// mCamera->lookAt(Vector3::ZERO); -// -// -// -// } -// -// void test16Textures() -// { -// -// HighLevelGpuProgramPtr frag; -// if (StringUtil::match(Root::getSingleton().getRenderSystem()->getName(), "*GL*")) -// { -// frag = HighLevelGpuProgramManager::getSingleton().createProgram("frag16", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// "glsl", GPT_FRAGMENT_PROGRAM); -// frag->setSource(" \ -// uniform sampler2D tex0; \ -// uniform sampler2D tex1; \ -// uniform sampler2D tex2; \ -// uniform sampler2D tex3; \ -// uniform sampler2D tex4; \ -// uniform sampler2D tex5; \ -// uniform sampler2D tex6; \ -// uniform sampler2D tex7; \ -// uniform sampler2D tex8; \ -// uniform sampler2D tex9; \ -// uniform sampler2D tex10; \ -// uniform sampler2D tex11; \ -// uniform sampler2D tex12; \ -// uniform sampler2D tex13; \ -// uniform sampler2D tex14; \ -// uniform sampler2D tex15; \ -// void main() \ -// { \ -// gl_FragColor = texture2D(tex15, gl_TexCoord[0].xy); \ -// } \ -// "); -// -// } -// else -// { -// // DirectX -// frag = HighLevelGpuProgramManager::getSingleton().createProgram("frag16", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// "hlsl", GPT_FRAGMENT_PROGRAM); -// frag->setParameter("target", "ps_2_0"); -// frag->setParameter("entry_point", "main"); -// frag->setSource(" \ -// float4 main( \ -// float2 uv : TEXCOORD0, \ -// uniform sampler2D tex0 : register(s0), \ -// uniform sampler2D tex1 : register(s1), \ -// uniform sampler2D tex2 : register(s2), \ -// uniform sampler2D tex3 : register(s3), \ -// uniform sampler2D tex4 : register(s4), \ -// uniform sampler2D tex5 : register(s5), \ -// uniform sampler2D tex6 : register(s6), \ -// uniform sampler2D tex7 : register(s7), \ -// uniform sampler2D tex8 : register(s8), \ -// uniform sampler2D tex9 : register(s9), \ -// uniform sampler2D tex10 : register(s10), \ -// uniform sampler2D tex11 : register(s11), \ -// uniform sampler2D tex12 : register(s12), \ -// uniform sampler2D tex13 : register(s13), \ -// uniform sampler2D tex14 : register(s14), \ -// uniform sampler2D tex15 : register(s15) \ -// ) : COLOR \ -// { \ -// return tex2D(tex15, uv); \ -// } \ -// "); -// } -// frag->load(); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("test16", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setVertexProgram("Ogre/BasicVertexPrograms/AmbientOneTextureUnified"); -// p->setFragmentProgram(frag->getName()); -// // create 15 textures the same -// for (int i = 0; i < 15; ++i) -// { -// p->createTextureUnitState("Dirt.jpg"); -// } -// // create 16th texture differently -// p->createTextureUnitState("ogrelogo.png"); -// if (StringUtil::match(Root::getSingleton().getRenderSystem()->getName(), "*GL*")) -// { -// // map samplers -// GpuProgramParametersSharedPtr params = p->getFragmentProgramParameters(); -// for (int i = 0; i < 16; ++i) -// { -// params->setNamedConstant(String("tex") + StringConverter::toString(i), i); -// } -// -// } -// -// mat->load(); -// -// Entity* e = mSceneMgr->createEntity("1", "knot.mesh"); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// -// mCamera->setPosition(0,0,200); -// mCamera->lookAt(0,0,0); -// -// -// } -// -// // Testing sharedptr bug report -// class CollisionShape -// { -// public: -// CollisionShape() -// : someValue(99), someText(0) -// { -// someText = new char[2000]; -// } -// virtual ~CollisionShape() -// { -// delete [] someText; -// } -// protected: -// int someValue; -// char* someText; -// -// -// }; -// /** SharedPtr of CollisionShape -// */ -// class CollisionShapePtr : public SharedPtr -// { -// public: -// CollisionShapePtr() : SharedPtr() {} -// CollisionShapePtr(CollisionShape* rep) : SharedPtr(rep) {} -// CollisionShapePtr(const CollisionShapePtr& r) : SharedPtr(r) {} -// }; -// -// void testSharedPtrBug() -// { -// CollisionShapePtr mCol[6]; -// mCol[0] = CollisionShapePtr(new CollisionShape()); -// mCol[1] = CollisionShapePtr(new CollisionShape()); -// mCol[2] = CollisionShapePtr(new CollisionShape()); -// mCol[3] = CollisionShapePtr(new CollisionShape()); -// mCol[4] = CollisionShapePtr(new CollisionShape()); -// mCol[5] = CollisionShapePtr(new CollisionShape()); -// mCol[0] = NULL; -// mCol[1] = CollisionShapePtr(new CollisionShape()); -// mCol[2] = CollisionShapePtr(new CollisionShape()); -// mCol[3] = NULL; -// mCol[4] = CollisionShapePtr(new CollisionShape()); -// mCol[5] = CollisionShapePtr(new CollisionShape()); -// -// } -// -// void testSpotlightViewProj(bool worldViewProj) -// { -// // Define programs that use spotlight projection -// -// String vpStr; -// vpStr = -// "void vp(float4 position : POSITION,\n" -// "out float4 oPosition : POSITION,\n" -// "out float4 oUV : TEXCOORD0,\n"; -// if (!worldViewProj) -// { -// vpStr += "uniform float4x4 world,\n" -// "uniform float4x4 spotlightViewProj,\n"; -// } -// else -// { -// vpStr += "uniform float4x4 spotlightWorldViewProj,\n"; -// } -// vpStr += "uniform float4x4 worldViewProj)\n" -// "{\n" -// " oPosition = mul(worldViewProj, position);\n"; -// if (worldViewProj) -// { -// vpStr += " oUV = mul(spotlightWorldViewProj, position);\n"; -// } -// else -// { -// vpStr += " float4 worldPos = mul(world, position);\n" -// " oUV = mul(spotlightViewProj, worldPos);\n"; -// } -// vpStr += "}\n"; -// -// String fpStr = -// "void fp(\n" -// "float4 uv : TEXCOORD0,\n" -// "uniform sampler2D tex : register(s0),\n" -// "out float4 oColor : COLOR)\n" -// "{\n" -// " uv = uv / uv.w;\n" -// " oColor = tex2D(tex, uv.xy);\n" -// "}\n"; -// -// HighLevelGpuProgramPtr vp = HighLevelGpuProgramManager::getSingleton() -// .createProgram("testvp", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// "cg", GPT_VERTEX_PROGRAM); -// vp->setSource(vpStr); -// vp->setParameter("profiles", "vs_1_1 arbvp1"); -// vp->setParameter("entry_point", "vp"); -// vp->load(); -// -// HighLevelGpuProgramPtr fp = HighLevelGpuProgramManager::getSingleton() -// .createProgram("testfp", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// "cg", GPT_FRAGMENT_PROGRAM); -// fp->setSource(fpStr); -// fp->setParameter("profiles", "ps_2_0 arbfp1"); -// fp->setParameter("entry_point", "fp"); -// fp->load(); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("TestSpotlightProj", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setVertexProgram("testvp"); -// p->getVertexProgramParameters()->setNamedAutoConstant( -// "worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); -// -// if (worldViewProj) -// { -// p->getVertexProgramParameters()->setNamedAutoConstant( -// "spotlightWorldViewProj", GpuProgramParameters::ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX); -// } -// else -// { -// p->getVertexProgramParameters()->setNamedAutoConstant( -// "world", GpuProgramParameters::ACT_WORLD_MATRIX); -// p->getVertexProgramParameters()->setNamedAutoConstant( -// "spotlightViewProj", GpuProgramParameters::ACT_SPOTLIGHT_VIEWPROJ_MATRIX); -// } -// p->setFragmentProgram("testfp"); -// p->createTextureUnitState("ogrelogo.png"); -// -// Entity* pEnt; -// -// // Define a plane mesh, use the above material -// Plane plane; -// plane.normal = Vector3::UNIT_Z; -// plane.d = 200; -// MeshManager::getSingleton().createPlane("WallPlane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// plane,1500,1500,100,100,true,1,5,5,Vector3::UNIT_Y); -// pEnt = mSceneMgr->createEntity( "5", "WallPlane" ); -// pEnt->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pEnt); -// -// -// mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// -// mTestNode[0]->translate(0, 0, 750); -// -// Light* spot = mSceneMgr->createLight("l1"); -// spot->setType(Light::LT_SPOTLIGHT); -// spot->setDirection(Vector3::NEGATIVE_UNIT_Z); -// -// mTestNode[0]->attachObject(spot); -// -// -// } -// -// void testManualIlluminationStage(ShadowTechnique tech) -// { -// mSceneMgr->setShadowTechnique(tech); -// mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000); -// MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); -// MaterialManager::getSingleton().setDefaultAnisotropy(5); -// -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0.0, 0.0, 0.0)); -// -// mLight = mSceneMgr->createLight("MainLight"); -// mLight->setPosition(-400,400,-300); -// mLight->setDiffuseColour(0.9, 0.9, 1); -// mLight->setSpecularColour(0.9, 0.9, 1); -// mLight->setAttenuation(6000,1,0.001,0); -// -// -// mLight = mSceneMgr->createLight("Light2"); -// mLight->setPosition(300,200,100); -// mLight->setDiffuseColour(1, 0.6, 0.5); -// mLight->setSpecularColour(0.9, 0.9, 1); -// mLight->setAttenuation(6000,1,0.001,0); -// -// -// -// MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// msh->buildTangentVectors(); -// Entity* pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" ); -// pEnt->setMaterialName("Examples/OffsetMapping/Specular"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject( pEnt ); -// -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshPtr planeMesh = MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 1500,1500,100,100,true,1,15,15,Vector3::UNIT_Z); -// planeMesh->buildTangentVectors(); -// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("Examples/OffsetMapping/Specular"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// mCamera->setPosition(180, 34, 223); -// mCamera->lookAt(0,50,0); -// -// -// } -// -// void testReinitialiseEntityAlteredMesh() -// { -// // test whether an Entity picks up that Mesh has changed -// // and therefore rebuild SubEntities -// -// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); -// -// Light* l = mSceneMgr->createLight("l1"); -// l->setPosition(200, 300, 0); -// -// Entity* pEnt = mSceneMgr->createEntity("testEnt", "knot.mesh"); -// testUpdateMesh = pEnt->getMesh().get(); -// -// mSceneMgr->getRootSceneNode()->attachObject(pEnt); -// -// } +// void testVertexTexture() +// { +// +// // NOTE: DirectX only right now +// +// Light* l = mSceneMgr->createLight("MainLight"); +// l->setType(Light::LT_POINT); +// l->setPosition(0, 200, 0); +// +// +// // Create single-channel floating point texture, no mips +// TexturePtr tex = TextureManager::getSingleton().createManual( +// "vertexTexture", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, +// 128, 128, 0, PF_FLOAT32_R); +// float* pData = static_cast( +// tex->getBuffer()->lock(HardwareBuffer::HBL_DISCARD)); +// // write concentric circles into the texture +// for (int y = -64; y < 64; ++y) +// { +// for (int x = -64; x < 64; ++x) +// { +// +// float val = Math::Sqrt(x*x + y*y); +// // repeat every 20 pixels +// val = val * Math::TWO_PI / 20.0f; +// *pData++ = Math::Sin(val); +// } +// } +// tex->getBuffer()->unlock(); +// +// String progSource = +// "void main(\n" +// "float4 pos : POSITION,\n" +// "float2 uv1 : TEXCOORD0,\n" +// "uniform float4x4 world, \n" +// "uniform float4x4 viewProj,\n" +// "uniform float heightscale,\n" +// "uniform sampler2D heightmap,\n" +// "out float4 oPos : POSITION,\n" +// "out float2 oUv1 : TEXCOORD1,\n" +// "out float4 col : COLOR)\n" +// "{\n" +// "oPos = mul(world, pos);\n" +// "// tex2Dlod since no mip\n" +// "float4 t = float4(0,0,0,0);\n" +// "t.xy = uv1.xy;\n" +// "float height = tex2Dlod(heightmap, t);\n" +// "oPos.y = oPos.y + (height * heightscale);\n" +// "oPos = mul(viewProj, oPos);\n" +// "oUv1 = uv1;\n" +// "col = float4(1,1,1,1);\n" +// "}\n"; +// HighLevelGpuProgramPtr prog = HighLevelGpuProgramManager::getSingleton().createProgram( +// "TestVertexTextureFetch", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// "hlsl", GPT_VERTEX_PROGRAM); +// prog->setSource(progSource); +// prog->setParameter("target", "vs_3_0"); +// prog->setVertexTextureFetchRequired(true); +// prog->setParameter("entry_point", "main"); +// prog->load(); +// +// +// MaterialPtr mat = MaterialManager::getSingleton().create("TestVertexTexture", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* pass = mat->getTechnique(0)->getPass(0); +// pass->setLightingEnabled(false); +// pass->setVertexProgram("TestVertexTextureFetch"); +// GpuProgramParametersSharedPtr vp = pass->getVertexProgramParameters(); +// vp->setNamedAutoConstant("world", GpuProgramParameters::ACT_WORLD_MATRIX); +// vp->setNamedAutoConstant("viewProj", GpuProgramParameters::ACT_VIEWPROJ_MATRIX); +// vp->setNamedConstant("heightscale", 30.0f); +// // vertex texture +// TextureUnitState* t = pass->createTextureUnitState("vertexTexture"); +// t->setBindingType(TextureUnitState::BT_VERTEX); +// // regular texture +// pass->createTextureUnitState("BumpyMetal.jpg"); +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// // 128 x 128 segment plane +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,128,128,true,1,1,1,Vector3::UNIT_Z); +// Entity* pPlaneEnt; +// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("TestVertexTexture"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// +// } +// +// void testBackgroundLoadResourceGroup() +// { +// ResourceGroupManager& rgm = ResourceGroupManager::getSingleton(); +// TextureManager& tm = TextureManager::getSingleton(); +// MeshManager& mm = MeshManager::getSingleton(); +// +// testBackgroundLoadGroup = "Deferred"; +// +// rgm.createResourceGroup(testBackgroundLoadGroup); +// +// // define a bunch of textures as deferred loading +// rgm.declareResource("egyptrockyfull.jpg", tm.getResourceType(), testBackgroundLoadGroup); +// rgm.declareResource("fw12b.jpg", tm.getResourceType(), testBackgroundLoadGroup); +// rgm.declareResource("grass_1024.jpg", tm.getResourceType(), testBackgroundLoadGroup); +// rgm.declareResource("GreenSkin.jpg", tm.getResourceType(), testBackgroundLoadGroup); +// rgm.declareResource("MtlPlat2.jpg", tm.getResourceType(), testBackgroundLoadGroup); +// rgm.declareResource("NMBumpsOut.png", tm.getResourceType(), testBackgroundLoadGroup); +// rgm.declareResource("ogrehead.mesh", mm.getResourceType(), testBackgroundLoadGroup); +// // Note: initialise resource group in main thread for this test +// // We will be able to initialise in the background thread too eventually, +// // once resources can be created thread safely as well as loaded +// rgm.initialiseResourceGroup(testBackgroundLoadGroup); +// +// // we won't load it yet, we'll wait for 5 seconds +// +// +// // Create a basic plane to have something in the scene to look at +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt; +// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// +// +// +// } +// +// +// +// void testOverlayRelativeMode() +// { +// +// Overlay* o = OverlayManager::getSingleton().create("Test"); +// OverlayContainer* c = (OverlayContainer*)OverlayManager::getSingleton().createOverlayElement("Panel", "panel1"); +// c->setMetricsMode(GMM_RELATIVE); +// c->setDimensions(1.0, 1.0); +// c->setMaterialName("Core/StatsBlockCenter"); +// c->setPosition(0.0, 0.0); +// +// TextAreaOverlayElement* t = (TextAreaOverlayElement*)OverlayManager::getSingleton().createOverlayElement("TextArea", "text1"); +// t->setMetricsMode(GMM_RELATIVE); +// t->setCaption("Hello"); +// t->setPosition(0,0); +// t->setFontName("BlueHighway"); +// t->setDimensions(0.2, 0.5); +// t->setCharHeight(0.2); +// c->addChild(t); +// +// o->add2D(c); +// o->show(); +// +// } +// +// void testBillboardOrigins() +// { +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// Vector3 dir(-1, -1, 0.5); +// dir.normalise(); +// Light* l = mSceneMgr->createLight("light1"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(dir); +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 0; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// BillboardSet* bbs = mSceneMgr->createBillboardSet("1"); +// bbs->setDefaultDimensions(50,50); +// bbs->createBillboard(0, 0, 0); +// bbs->setBillboardOrigin(BBO_TOP_LEFT); +// //bbs->setBillboardType(BBT_ORIENTED_COMMON); +// bbs->setCommonDirection(Vector3::UNIT_Y); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(bbs); +// +// } +// +// void testDepthBias() +// { +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../../Tests/Media", "FileSystem"); +// +// mSceneMgr->setAmbientLight(ColourValue::White); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("mat1", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->createTextureUnitState("BumpyMetal.jpg"); +// +// const String meshName("cube.mesh"); +// Entity* entity = mSceneMgr->createEntity("base", meshName); +// entity->setMaterialName("mat1"); +// mSceneMgr->getRootSceneNode()->attachObject(entity); +// +// +// entity = mSceneMgr->createEntity("base2", meshName); +// entity->setMaterialName("Examples/EnvMappedRustySteel"); +// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// n->setPosition(-30, 0, 0); +// n->yaw(Degree(45)); +// n->attachObject(entity); +// +// for (size_t i = 0; i <= 6;++i) +// { +// String name("decal"); +// name += StringConverter::toString(i); +// +// MaterialPtr pMat = static_cast(MaterialManager::getSingleton().create( +// name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)); +// +// pMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); +// pMat->getTechnique(0)->getPass(0)->setAlphaRejectSettings(CMPF_GREATER_EQUAL, 128); +// pMat->getTechnique(0)->getPass(0)->setDepthBias(i); +// pMat->getTechnique(0)->getPass(0)->createTextureUnitState(name + ".png"); // -// void testSRGBtexture(bool enableGamma) -// { -// // NOTE: enable flag only turns on SRGB for texture sampling, you may -// // need to configure the window for the reverse conversion for consistency! -// MaterialPtr mat = MaterialManager::getSingleton().create("testsrgb", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// TextureUnitState* t = p->createTextureUnitState("ogrelogo.png"); -// t->setHardwareGammaEnabled(enableGamma); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// entity = mSceneMgr->createEntity(name, meshName); +// entity->setMaterialName(name); +// mSceneMgr->getRootSceneNode()->attachObject(entity); +// } +// +// +// +// mCamera->setPosition(0,0,200); +// mCamera->lookAt(Vector3::ZERO); +// +// +// } +// +// +// class GrassListener : public FrameListener +// { +// protected: +// SceneManager* mSceneManager; +// public: +// GrassListener(SceneManager* sceneManager) : +// mSceneManager(sceneManager) +// { +// } +// void waveGrass(Real timeElapsed) +// { +// static Real xinc = Math::PI * 0.4; +// static Real zinc = Math::PI * 0.55; +// static Real xpos = Math::RangeRandom(-Math::PI, Math::PI); +// static Real zpos = Math::RangeRandom(-Math::PI, Math::PI); +// +// xpos += xinc * timeElapsed; +// zpos += zinc * timeElapsed; +// +// // Update vertex program parameters by binding a value to each renderable +// static Vector4 offset(0,0,0,0); +// Entity *e; +// for (size_t i=0; i<12; i++) +// { +// e = mSceneManager->getEntity("GrassBlades" + StringConverter::toString(i)); +// xpos += e->getParentNode()->_getDerivedPosition().x * 0.001; +// zpos += e->getParentNode()->_getDerivedPosition().z * 0.001; +// offset.x = Math::Sin(xpos) * 0.05; +// offset.z = Math::Sin(zpos) * 0.05; +// e->getSubEntity(0)->setCustomParameter(999, offset); +// } +// } +// +// bool frameStarted(const FrameEvent& evt) +// { +// waveGrass(evt.timeSinceLastFrame); +// return true; +// } +// }; +// +// void testStringTokenising() +// { +// static const String TEST_STRINGS[] = { +// "this is just a normal sample", +// "This one actually \"uses quotes\" and stuff", +// "\"This one\" started with a quote", +// "\"This one\" has more \"than one\" quote in it", +// "\"This one\"\"has no delimeter\"between the two quotes", +// "This one has many spaces that should be disregarded" +// }; +// static const size_t NUM_STRINGS = sizeof(TEST_STRINGS) / sizeof(TEST_STRINGS[0]); +// +// for (size_t i=0; isetShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE); +// +// +// LiSPSMShadowCameraSetup *mLiSPSMSetup = new LiSPSMShadowCameraSetup(); +// //mLiSPSMSetup->setUseAggressiveFocusRegion(false); +// ShadowCameraSetupPtr mCurrentShadowCameraSetup = ShadowCameraSetupPtr(mLiSPSMSetup); +// //ShadowCameraSetupPtr mCurrentShadowCameraSetup = ShadowCameraSetupPtr(new PlaneOptimalShadowCameraSetup(mPlane)); +// mSceneMgr->setShadowCameraSetup(mCurrentShadowCameraSetup); +// +// PixelFormat pxFmt = PF_L8; +// if (Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_TEXTURE_FLOAT)) +// { +// if (Root::getSingleton().getRenderSystem()->getName().find("GL") != String::npos) +// { +// // GL performs much better if you pick half-float format +// pxFmt = PF_FLOAT16_R; +// } +// else +// { +// // D3D is the opposite - if you ask for PF_FLOAT16_R you +// // get an integer format instead! You can ask for PF_FLOAT16_GR +// // but the precision doesn't work well +// pxFmt = PF_FLOAT32_R; +// } +// } +// mSceneMgr->setShadowTextureSettings(1024, 1, pxFmt); +// +// // New depth shadow mapping +// String CUSTOM_ROCKWALL_MATERIAL("Ogre/DepthShadowmap/Receiver/RockWall"); +// String CUSTOM_CASTER_MATERIAL("Ogre/DepthShadowmap/Caster/Float"); +// String CUSTOM_RECEIVER_MATERIAL("Ogre/DepthShadowmap/Receiver/Float"); +// +// mSceneMgr->setShadowTextureCasterMaterial(CUSTOM_CASTER_MATERIAL); +// mSceneMgr->setShadowTextureReceiverMaterial(CUSTOM_RECEIVER_MATERIAL); +// mSceneMgr->setShadowTextureSelfShadow(true); +// +// mSceneMgr->setShadowTextureFadeStart(1.0); +// mSceneMgr->setShadowTextureFadeEnd(1.0); +// +// mSceneMgr->setShadowTextureSelfShadow(true); +// +// MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); +// MaterialManager::getSingleton().setDefaultAnisotropy(5); +// +// mSceneMgr->setShadowDirLightTextureOffset(0.2); +// mSceneMgr->setShadowFarDistance(150); +// //mSceneMgr->setShadowCasterRenderBackFaces(false); +// +// // Create a basic plane to have something in the scene to look at +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshPtr msh = MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 4500,4500,100,100,true,1,40,40,Vector3::UNIT_Z); +// msh->buildTangentVectors(VES_TANGENT); +// Entity* pPlaneEnt; +// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// +// pPlaneEnt->setMaterialName(CUSTOM_ROCKWALL_MATERIAL); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// +// +// // Reorient the plane and create a plane mesh for the test planes +// plane.normal = Vector3::UNIT_Z; +// MeshManager::getSingleton().createPlane( +// "Test_Plane", "OgreTestNonDefaultShadowMaterials", +// plane, 50.0, 50.0, 1, 1, true); +// +// +// const String GRASSMAT("Examples/GrassBladesAdditiveFloatTransparent"); +// //const String GRASSMAT("Examples/DepthShadowmap/CasterReceiver/GrassBlades"); +// //const String GRASSMAT("tree4324");//"tree1.tga"); +// +// +// // Add test plane entities to the scene +// Entity* entity = mSceneMgr->createEntity("GrassBlades0", "Test_Plane"); +// entity->setMaterialName(GRASSMAT); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(0.0, -100.0+25.0, 0.0))->attachObject(entity); +// +// +// entity = mSceneMgr->createEntity("GrassBlades1", "Test_Plane"); +// entity->setMaterialName(GRASSMAT); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(0.0, -100.0+25.0, -20.0))->attachObject(entity); +// +// entity = mSceneMgr->createEntity("GrassBlades2", "Test_Plane"); +// entity->setMaterialName(GRASSMAT); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(0.0, -100.0+25.0, -40.0))->attachObject(entity); +// +// // Add test plane entities to the scene, shadowed partially by athene mesh +// entity = mSceneMgr->createEntity("GrassBlades3", "Test_Plane"); +// entity->setMaterialName(GRASSMAT); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(-80.0, -100.0+25.0, 0.0))->attachObject(entity); +// +// entity = mSceneMgr->createEntity("GrassBlades4", "Test_Plane"); +// entity->setMaterialName(GRASSMAT); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(-130.0, -100.0+25.0, -20.0))->attachObject(entity); +// +// entity = mSceneMgr->createEntity("GrassBlades5", "Test_Plane"); +// entity->setMaterialName(GRASSMAT); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(-180.0, -100.0+25.0, -40.0))->attachObject(entity); +// +// +// +// Entity* ent = mSceneMgr->createEntity("athene", "athene.mesh"); +// ent->setMaterialName(CUSTOM_ROCKWALL_MATERIAL); +// //ent->setMaterialName(GRASSMAT); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,-20,-20))->attachObject(ent); +// +// // Add test plane entities to the scene, one after another +// entity = mSceneMgr->createEntity("GrassBlades6", "Test_Plane"); +// entity->setMaterialName(GRASSMAT); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(-260.0, -100.0+25.0, 0.0))->attachObject(entity); +// +// entity = mSceneMgr->createEntity("GrassBlades7", "Test_Plane"); +// entity->setMaterialName(GRASSMAT); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(-260.0, -100.0+25.0, -10.0))->attachObject(entity); +// +// entity = mSceneMgr->createEntity("GrassBlades8", "Test_Plane"); +// entity->setMaterialName(GRASSMAT); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(-260.0, -100.0+25.0, -20.0))->attachObject(entity); +// +// // Add test plane entities to the scene, alone with other material +// +// const String GRASSMAT_CUSTOM_DEFAULT_CUSTOM("Examples/GrassBladesAdditiveFloat"); +// const String GRASSMAT_CUSTOM_NOSPECIAL_CUSTOM("Examples/GrassBladesAdditive"); +// const String GRASSMAT_ORIG("Examples/GrassBlades"); +// +// entity = mSceneMgr->createEntity("GrassBlades9", "Test_Plane"); +// entity->setMaterialName(GRASSMAT_CUSTOM_DEFAULT_CUSTOM); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(-80.0, -100.0+25.0, -80.0))->attachObject(entity); +// +// entity = mSceneMgr->createEntity("GrassBlades10", "Test_Plane"); +// entity->setMaterialName(GRASSMAT_CUSTOM_NOSPECIAL_CUSTOM); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(-130.0, -100.0+25.0, -90.0))->attachObject(entity); +// +// entity = mSceneMgr->createEntity("GrassBlades11", "Test_Plane"); +// entity->setMaterialName(GRASSMAT_ORIG); +// mSceneMgr->getRootSceneNode()->createChildSceneNode( +// Vector3(-180.0, -100.0+25.0, -90.0))->attachObject(entity); +// +// // Position and orient the camera +// //mCamera->setPosition(-55.0, 40.0, 100.0); +// //mCamera->lookAt(-10.0, 20.0, -35.0); +// mCamera->setPosition(-75.0, 30.0, 150.0); +// mCamera->lookAt(0.0, 20.0, -35.0); +// +// //mSceneMgr->setAmbientLight(ColourValue::Black); +// Light* l; +// +// l = mSceneMgr->createLight("Dir1"); +// l->setType(Light::LT_DIRECTIONAL); +// //l->setAttenuation(5000,1,0,0); +// Vector3 dir1(0.0, -0.7, -0.5); +// dir1.normalise(); +// l->setDirection(dir1); +// l->setCastShadows(true); +// +// l->setDiffuseColour(ColourValue(1.0, 1.0, 1.0)); +// +// +// mSceneMgr->setAmbientLight(ColourValue(0.0, 0.0, 0.2)); +// +// // l = mSceneMgr->createLight("Spot2"); +// // l->setAttenuation(5000,1,0,0); +// // /* // spotlight */ +// // l->setType(Light::LT_SPOTLIGHT); +// // l->setSpotlightRange(Degree(30),Degree(45),1.0f); +// // +// // +// // SceneNode* lightNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// // lightNode2->attachObject(l); +// // lightNode2->setPosition(-500, 200, 500); +// // lightNode2->lookAt(Vector3(0,-200,0), Node::TS_WORLD); +// // l->setDirection(Vector3::NEGATIVE_UNIT_Z); +// //lightNode2->setPosition(-75.0, 30.0, 150.0); +// //lightNode2->lookAt(Vector3(.0, 20.0, -35.0), Node::TS_WORLD); +// +// +// +// addTextureShadowDebugOverlay(1); +// +// Root::getSingleton().addFrameListener(new GrassListener(mSceneMgr)); +// +// } +// +// void testTextureShadowsIntegrated() +// { +// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED); +// //mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); +// MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); +// MaterialManager::getSingleton().setDefaultAnisotropy(5); +// +// mSceneMgr->setShadowTextureSettings(1024, 2); +// +// mSceneMgr->setAmbientLight(ColourValue::Black); +// Light* l = mSceneMgr->createLight("Spot1"); +// l->setType(Light::LT_SPOTLIGHT); +// l->setAttenuation(5000,1,0,0); +// l->setSpotlightRange(Degree(30),Degree(45),1.0f); +// SceneNode* lightNode1 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// lightNode1->attachObject(l); +// lightNode1->setPosition(400, 250, 500); +// lightNode1->lookAt(Vector3(0,-200,0), Node::TS_WORLD); +// l->setDirection(Vector3::NEGATIVE_UNIT_Z); +// l->setDiffuseColour(0.7, 0.7, 0.5); +// +// l = mSceneMgr->createLight("Spot2"); +// l->setAttenuation(5000,1,0,0); +// /* // spotlight */ +// l->setType(Light::LT_SPOTLIGHT); +// l->setSpotlightRange(Degree(30),Degree(45),1.0f); +// /**/ +// // point +// SceneNode* lightNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// lightNode2->attachObject(l); +// lightNode2->setPosition(-500, 200, 500); +// lightNode2->lookAt(Vector3(0,-200,0), Node::TS_WORLD); +// l->setDirection(Vector3::NEGATIVE_UNIT_Z); +// /* // directional +// l->setType(Light::LT_DIRECTIONAL); +// Vector3 dir(0.5, -1, 0.5); +// dir.normalise(); +// l->setDirection(dir); +// */ +// l->setDiffuseColour(1, 0.2, 0.2); +// +// /* +// // Test spot 3 +// l = mSceneMgr->createLight("Spot3"); +// l->setType(Light::LT_SPOTLIGHT); +// l->setAttenuation(5000,1,0,0); +// l->setSpotlightRange(Degree(30),Degree(45),1.0f); +// SceneNode* lightNode3 = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// lightNode3->attachObject(l); +// lightNode3->setPosition(700, 250, 500); +// lightNode3->lookAt(Vector3(0,-200,0), Node::TS_WORLD); +// l->setDirection(Vector3::NEGATIVE_UNIT_Z); +// l->setDiffuseColour(0.0, 0.7, 1.0); +// */ +// +// // Create a basic plane to have something in the scene to look at +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshPtr msh = MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 4500,4500,100,100,true,1,40,40,Vector3::UNIT_Z); +// msh->buildTangentVectors(VES_TANGENT); +// Entity* pPlaneEnt; +// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// //pPlaneEnt->setMaterialName("Examples/OffsetMapping/Specular"); +// pPlaneEnt->setMaterialName("Examples/OffsetMapping/IntegratedShadows"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// pPlaneEnt = mSceneMgr->createEntity( "plane2", "Myplane" ); +// //pPlaneEnt->setMaterialName("Examples/OffsetMapping/Specular"); +// pPlaneEnt->setMaterialName("Examples/OffsetMapping/IntegratedShadows"); +// pPlaneEnt->setCastShadows(false); +// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// n->roll(Degree(90)); +// n->translate(100,0,0); +// //n->attachObject(pPlaneEnt); +// +// pPlaneEnt = mSceneMgr->createEntity( "plane3", "Myplane" ); +// //pPlaneEnt->setMaterialName("Examples/OffsetMapping/Specular"); +// pPlaneEnt->setMaterialName("Examples/OffsetMapping/IntegratedShadows"); +// pPlaneEnt->setCastShadows(false); +// n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// n->pitch(Degree(90)); +// n->yaw(Degree(-90)); +// n->translate(0,0,-100); +// n->attachObject(pPlaneEnt); +// +// mCamera->setPosition(-50, 500, 1000); +// mCamera->lookAt(Vector3(-50,-100,0)); +// +// Entity* ent = mSceneMgr->createEntity("athene", "athene.mesh"); +// ent->setMaterialName("Examples/Athene/NormalMapped"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,-20,0))->attachObject(ent); +// +// addTextureShadowDebugOverlay(2); +// +// +// +// } +// +// void testTextureShadowsIntegratedPSSM() +// { +// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED); +// +// // 3 textures per directional light +// mSceneMgr->setShadowTextureCountPerLightType(Ogre::Light::LT_DIRECTIONAL, 3); +// mSceneMgr->setShadowTextureSettings(512, 3, PF_FLOAT32_R); +// mSceneMgr->setShadowTextureSelfShadow(true); +// // Set up caster material - this is just a standard depth/shadow map caster +// mSceneMgr->setShadowTextureCasterMaterial("PSSM/shadow_caster"); +// +// // shadow camera setup +// PSSMShadowCameraSetup* pssmSetup = new PSSMShadowCameraSetup(); +// pssmSetup->calculateSplitPoints(3, mCamera->getNearClipDistance(), mCamera->getFarClipDistance()); +// pssmSetup->setSplitPadding(10); +// pssmSetup->setOptimalAdjustFactor(0, 2); +// pssmSetup->setOptimalAdjustFactor(1, 1); +// pssmSetup->setOptimalAdjustFactor(2, 0.5); +// +// mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(pssmSetup)); +// +// +// mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); +// Light* l = mSceneMgr->createLight("Dir"); +// l->setType(Light::LT_DIRECTIONAL); +// Vector3 dir(0.3, -1, 0.2); +// dir.normalise(); +// l->setDirection(dir); +// +// +// // Create a basic plane to have something in the scene to look at +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshPtr msh = MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 4500,4500,100,100,true,1,40,40,Vector3::UNIT_Z); +// msh->buildTangentVectors(VES_TANGENT); +// Entity* pPlaneEnt; +// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("PSSM/Plane"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// mCamera->setPosition(-50, 500, 1000); +// mCamera->lookAt(Vector3(-50,-100,0)); +// +// Entity* ent = mSceneMgr->createEntity("knot", "knot.mesh"); +// ent->setMaterialName("PSSM/Knot"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0))->attachObject(ent); +// createRandomEntityClones(ent, 20, Vector3(-1000,0,-1000), Vector3(1000,0,1000)); +// +// +// Vector4 splitPoints; +// const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssmSetup->getSplitPoints(); +// for (int i = 0; i < 3; ++i) +// { +// splitPoints[i] = splitPointList[i]; +// } +// MaterialPtr mat = MaterialManager::getSingleton().getByName("PSSM/Plane"); +// mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("pssmSplitPoints", splitPoints); +// mat = MaterialManager::getSingleton().getByName("PSSM/Knot"); +// mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstant("pssmSplitPoints", splitPoints); +// +// addTextureShadowDebugOverlay(3); +// +// +// +// } +// void testTimeCreateDestroyObject() +// { +// int iterationCount = 100000; +// +// // Create names ahead of time +// StringVector nameList; +// nameList.reserve(iterationCount); +// for (int i = 0; i < iterationCount; ++i) +// { +// nameList.push_back("somerelativelylongtestname" + StringConverter::toString(i)); +// } +// +// Timer timer; +// StringVector::iterator nameIt = nameList.begin(); +// timer.reset(); +// for (int i = 0; i < iterationCount; ++i, ++nameIt) +// { +// ManualObject* man = mSceneMgr->createManualObject(*nameIt); +// } +// unsigned long createTime = timer.getMilliseconds(); +// +// nameIt = nameList.begin(); +// timer.reset(); +// for (int i = 0; i < iterationCount; ++i, ++nameIt) +// { +// ManualObject* man = mSceneMgr->getManualObject(*nameIt); +// // do something so compiler doesn't think I'm doing nothing +// man->setVisible(true); +// } +// unsigned long lookupTime = timer.getMilliseconds(); +// +// nameIt = nameList.begin(); +// timer.reset(); +// for (int i = 0; i < iterationCount; ++i, ++nameIt) +// { +// mSceneMgr->destroyManualObject(*nameIt); +// } +// unsigned long destroyTime = timer.getMilliseconds(); +// +// nameIt = nameList.begin(); +// timer.reset(); +// for (int i = 0; i < iterationCount; ++i, ++nameIt) +// { +// mSceneMgr->createSceneNode(*nameIt); +// } +// unsigned long sncreateTime = timer.getMilliseconds(); +// +// nameIt = nameList.begin(); +// timer.reset(); +// for (int i = 0; i < iterationCount; ++i, ++nameIt) +// { +// mSceneMgr->destroySceneNode(*nameIt); +// } +// unsigned long sndestroyTime = timer.getMilliseconds(); +// +// LogManager::getSingleton().stream() +// << "Object create time: " << ((float)createTime / 1000.0f) << " secs\n" +// << "Object lookup time: " << ((float)lookupTime / 1000.0f) << " secs\n" +// << "Object destroy time: " << ((float)destroyTime / 1000.0f) << " secs\n" +// << "SceneNode create time: " << ((float)sncreateTime / 1000.0f) << " secs\n" +// << "SceneNode destroy time: " << ((float)sndestroyTime / 1000.0f) << " secs\n"; +// +// } +// +// void testLightScissoring(bool cliptoo) +// { +// mSceneMgr->setAmbientLight(ColourValue::White); +// +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 0; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("Examples/GrassFloor"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// Real lightRange = 100; +// +// ManualObject* debugSphere = mSceneMgr->createManualObject("debugSphere"); +// debugSphere->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); +// for (int i = 0; i <= 20; ++i) +// { +// Vector3 basePos(lightRange, 0, 0); +// Quaternion quat; +// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y); +// basePos = quat * basePos; +// debugSphere->position(basePos); +// } +// for (int i = 0; i <= 20; ++i) +// { +// Vector3 basePos(lightRange, 0, 0); +// Quaternion quat; +// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Z); +// basePos = quat * basePos; +// debugSphere->position(basePos); +// } +// debugSphere->end(); +// +// ManualObject* debugSphere2 = mSceneMgr->createManualObject("debugSphere2"); +// debugSphere2->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); +// for (int i = 0; i <= 20; ++i) +// { +// Vector3 basePos(lightRange, 0, 0); +// Quaternion quat; +// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y); +// basePos = quat * basePos; +// debugSphere2->position(basePos); +// } +// for (int i = 0; i <= 20; ++i) +// { +// Vector3 basePos(lightRange, 0, 0); +// Quaternion quat; +// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Z); +// basePos = quat * basePos; +// debugSphere2->position(basePos); +// } +// debugSphere2->end(); +// +// Light* l = mSceneMgr->createLight("l1"); +// l->setAttenuation(lightRange, 1, 0, 0); +// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,95,0)); +// n->attachObject(debugSphere); +// n->attachObject(l); +// +// Light* l2 = mSceneMgr->createLight("l2"); +// l2->setAttenuation(lightRange, 1, 0, 0); +// SceneNode* n2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,50,0)); +// n2->attachObject(debugSphere2); +// n2->attachObject(l2); +// +// // Modify the plane material so that it clips to the light +// // Normally you'd only clip a secondary pass but this is engineered so you +// // can actually see the scissoring effect +// MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/GrassFloor"); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightScissoringEnabled(true); +// if (cliptoo) +// p->setLightClipPlanesEnabled(true); +// +// +// mCamera->setPosition(0, 200, 300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// +// void testLightClipPlanes(bool scissortoo) +// { +// mSceneMgr->setAmbientLight(ColourValue::White); +// +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 0; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("Examples/GrassFloor"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(150,0,100))->attachObject(pPlaneEnt); +// +// Real lightRange = 1000; +// Real spotWidth = 300; +// +// ManualObject* debugSphere = mSceneMgr->createManualObject("debugSphere"); +// debugSphere->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); +// for (int i = 0; i <= 20; ++i) +// { +// Vector3 basePos(spotWidth, 0, 0); +// Quaternion quat; +// quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y); +// basePos = quat * basePos; +// debugSphere->position(basePos); +// } +// debugSphere->end(); +// +// Light* l = mSceneMgr->createLight("l1"); +// l->setAttenuation(lightRange, 1, 0, 0); +// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,0,0)); +// n->attachObject(debugSphere); +// /* SPOT LIGHT +// */ +// // match spot width to groud +// Real spotHeight = lightRange * 0.5; +// n = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100,spotHeight,0)); +// l->setType(Light::LT_SPOTLIGHT); +// Radian spotAngle = Math::ATan(spotWidth / spotHeight) * 2; +// l->setSpotlightOuterAngle(spotAngle); +// l->setSpotlightInnerAngle(spotAngle * 0.75); +// Vector3 dir(0, -1, 0); +// dir.normalise(); +// l->setDirection(dir); +// +// /* END SPOT LIGHT */ +// n->attachObject(l); +// +// // Modify the plane material so that it clips to the light +// // Normally you'd only clip a secondary pass but this is engineered so you +// // can actually see the scissoring effect +// MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/GrassFloor"); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightClipPlanesEnabled(true); +// if (scissortoo) +// p->setLightScissoringEnabled(true); +// +// mCamera->setPosition(0, 200, 300); +// mCamera->lookAt(Vector3::ZERO); +// +// +// +// } +// +// void testLightClipPlanesMoreLights(bool scissortoo) +// { +// mSceneMgr->setAmbientLight(ColourValue(0.3, 0.25, 0.2, 0)); +// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE); +// mSceneMgr->setShadowTextureCount(3); +// +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 0; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 4500,4500,100,100,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("Examples/GrassFloor"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// Real lightRange = 1000; +// Real spotWidth = 300; +// +// int numLights = 8; +// Real xoff = -numLights * spotWidth * 0.5; +// +// +// for (int i = 0; i < numLights; ++i) +// { +// Light* l = mSceneMgr->createLight("l" + StringConverter::toString(i)); +// l->setAttenuation(lightRange, 1, 0, 0); +// /* SPOT LIGHT +// */ +// // match spot width to groud +// Real spotHeight = lightRange * 0.5; +// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3((spotWidth+50)*i + xoff,spotHeight,0)); +// l->setType(Light::LT_SPOTLIGHT); +// Radian spotAngle = Math::ATan(spotWidth / spotHeight) * 2; +// l->setSpotlightOuterAngle(spotAngle); +// l->setSpotlightInnerAngle(spotAngle * 0.75); +// Vector3 dir(0, -1, 0); +// dir.normalise(); +// l->setDirection(dir); +// +// /* END SPOT LIGHT */ +// n->attachObject(l); +// +// Entity* e = mSceneMgr->createEntity("e" + StringConverter::toString(i), "robot.mesh"); +// SceneNode* en = n->createChildSceneNode(Vector3(0, -200, 0)); +// en->attachObject(e); +// +// +// } +// +// // Modify the plane material so that it clips to the light on the second pass, post ambient +// +// MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/GrassFloor"); +// Pass* p = mat->getTechnique(0)->getPass(0); +// String texname = p->getTextureUnitState(0)->getTextureName(); +// p->removeAllTextureUnitStates(); +// p->setIlluminationStage(IS_AMBIENT); +// p->setDiffuse(ColourValue::Black); +// p = mat->getTechnique(0)->createPass(); +// p->setIlluminationStage(IS_PER_LIGHT); +// p->setIteratePerLight(true, false); +// p->setAmbient(ColourValue::Black); +// p->setLightClipPlanesEnabled(true); +// p->setSceneBlending(SBT_ADD); +// if (scissortoo) +// p->setLightScissoringEnabled(true); +// p = mat->getTechnique(0)->createPass(); +// p->setIlluminationStage(IS_DECAL); +// p->createTextureUnitState(texname); +// p->setLightingEnabled(false); +// p->setSceneBlending(SBT_MODULATE); +// +// +// mCamera->setPosition(0, 200, 300); +// mCamera->lookAt(Vector3::ZERO); +// +// +// +// } +// +// void testMRT() +// { +// TexturePtr Tex[2]; +// MultiRenderTarget* mrtTex; +// +// Viewport* viewport = mWindow->getViewport(0); +// int width = viewport->getActualWidth(); +// int height = viewport->getActualHeight(); +// +// Tex[0] = TextureManager::getSingleton().createManual("diffusemap", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, +// width,height,0,PF_R8G8B8A8,TU_RENDERTARGET); +// Tex[1] = TextureManager::getSingleton().createManual("normalmap",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, +// width,height,0,PF_R8G8B8A8,TU_RENDERTARGET); +// +// // assert(Tex[0]->getFormat() == PF_FLOAT16_RGBA); +// +// mrtTex = Ogre::Root::getSingleton().getRenderSystem()->createMultiRenderTarget("MRT"); +// RenderTexture* rTex[2]; +// rTex[0] = Tex[0]->getBuffer()->getRenderTarget(); +// rTex[1] = Tex[1]->getBuffer()->getRenderTarget(); +// +// rTex[0]->setAutoUpdated(false); +// rTex[1]->setAutoUpdated(false); +// mrtTex->bindSurface(0, rTex[0]); +// mrtTex->bindSurface(1, rTex[1]); +// mrtTex->setAutoUpdated(true); +// +// Viewport *v = mrtTex->addViewport(mCamera); +// v->setMaterialScheme("MRT"); +// v->setClearEveryFrame(true); +// v->setOverlaysEnabled(false); +// v->setSkiesEnabled(false); +// v->setBackgroundColour(ColourValue(0,0,0,0)); +// +// // Create texture overlay here +// Overlay *debugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay"); +// MaterialPtr debugMat = MaterialManager::getSingleton().create("DebugRTTMat1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); +// TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState("normalmap"); +// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); +// OverlayContainer *debugPanel = (OverlayContainer *) (OverlayManager::getSingleton().createOverlayElement("Panel","DebugRTTPanel1")); +// debugPanel->_setPosition(0.8,0); +// debugPanel->_setDimensions(0.2,0.3); +// debugPanel->setMaterialName(debugMat->getName()); +// debugOverlay->add2D(debugPanel); +// +// debugMat = MaterialManager::getSingleton().create("DebugRTTMat2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false); +// t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState("diffusemap"); +// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); +// debugPanel = (OverlayContainer *) (OverlayManager::getSingleton().createOverlayElement("Panel","DebugRTTPanel2")); +// debugPanel->_setPosition(0.8,0.3); +// debugPanel->_setDimensions(0.2,0.3); +// debugPanel->setMaterialName(debugMat->getName()); +// debugOverlay->add2D(debugPanel); +// // Create scene items +// +// // Create a material to render differently to MRT compared to main viewport +// MaterialPtr mat = MaterialManager::getSingleton().create("MRTTest", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// // normal technique (0), leave as default +// Technique* mrtTech = mat->createTechnique(); +// mrtTech->setSchemeName("MRT"); +// Pass* mrtPass = mrtTech->createPass(); +// mrtPass->setVertexProgram("DeferredShading/material/hlsl/vs"); +// mrtPass->setFragmentProgram("DeferredShading/material/hlsl/ps"); +// mrtPass->createTextureUnitState("rockwall.tga"); +// mat->load(); +// +// Entity* ent = mSceneMgr->createEntity("knot", "knot.mesh"); +// ent->setMaterialName("MRTTest"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); +// +// mCamera->setPosition(0, 0, 200); +// mCamera->lookAt(Vector3::ZERO); +// +// +// +// } +// +// void test16Textures() +// { +// +// HighLevelGpuProgramPtr frag; +// if (StringUtil::match(Root::getSingleton().getRenderSystem()->getName(), "*GL*")) +// { +// frag = HighLevelGpuProgramManager::getSingleton().createProgram("frag16", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// "glsl", GPT_FRAGMENT_PROGRAM); +// frag->setSource(" \ +// uniform sampler2D tex0; \ +// uniform sampler2D tex1; \ +// uniform sampler2D tex2; \ +// uniform sampler2D tex3; \ +// uniform sampler2D tex4; \ +// uniform sampler2D tex5; \ +// uniform sampler2D tex6; \ +// uniform sampler2D tex7; \ +// uniform sampler2D tex8; \ +// uniform sampler2D tex9; \ +// uniform sampler2D tex10; \ +// uniform sampler2D tex11; \ +// uniform sampler2D tex12; \ +// uniform sampler2D tex13; \ +// uniform sampler2D tex14; \ +// uniform sampler2D tex15; \ +// void main() \ +// { \ +// gl_FragColor = texture2D(tex15, gl_TexCoord[0].xy); \ +// } \ +// "); +// +// } +// else +// { +// // DirectX +// frag = HighLevelGpuProgramManager::getSingleton().createProgram("frag16", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// "hlsl", GPT_FRAGMENT_PROGRAM); +// frag->setParameter("target", "ps_2_0"); +// frag->setParameter("entry_point", "main"); +// frag->setSource(" \ +// float4 main( \ +// float2 uv : TEXCOORD0, \ +// uniform sampler2D tex0 : register(s0), \ +// uniform sampler2D tex1 : register(s1), \ +// uniform sampler2D tex2 : register(s2), \ +// uniform sampler2D tex3 : register(s3), \ +// uniform sampler2D tex4 : register(s4), \ +// uniform sampler2D tex5 : register(s5), \ +// uniform sampler2D tex6 : register(s6), \ +// uniform sampler2D tex7 : register(s7), \ +// uniform sampler2D tex8 : register(s8), \ +// uniform sampler2D tex9 : register(s9), \ +// uniform sampler2D tex10 : register(s10), \ +// uniform sampler2D tex11 : register(s11), \ +// uniform sampler2D tex12 : register(s12), \ +// uniform sampler2D tex13 : register(s13), \ +// uniform sampler2D tex14 : register(s14), \ +// uniform sampler2D tex15 : register(s15) \ +// ) : COLOR \ +// { \ +// return tex2D(tex15, uv); \ +// } \ +// "); +// } +// frag->load(); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("test16", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setVertexProgram("Ogre/BasicVertexPrograms/AmbientOneTextureUnified"); +// p->setFragmentProgram(frag->getName()); +// // create 15 textures the same +// for (int i = 0; i < 15; ++i) +// { +// p->createTextureUnitState("Dirt.jpg"); +// } +// // create 16th texture differently +// p->createTextureUnitState("ogrelogo.png"); +// if (StringUtil::match(Root::getSingleton().getRenderSystem()->getName(), "*GL*")) +// { +// // map samplers +// GpuProgramParametersSharedPtr params = p->getFragmentProgramParameters(); +// for (int i = 0; i < 16; ++i) +// { +// params->setNamedConstant(String("tex") + StringConverter::toString(i), i); +// } +// +// } +// +// mat->load(); +// +// Entity* e = mSceneMgr->createEntity("1", "knot.mesh"); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// +// mCamera->setPosition(0,0,200); +// mCamera->lookAt(0,0,0); +// +// +// } +// +// // Testing sharedptr bug report +// class CollisionShape +// { +// public: +// CollisionShape() +// : someValue(99), someText(0) +// { +// someText = new char[2000]; +// } +// virtual ~CollisionShape() +// { +// delete [] someText; +// } +// protected: +// int someValue; +// char* someText; +// +// +// }; +// /** SharedPtr of CollisionShape +// */ +// class CollisionShapePtr : public SharedPtr +// { +// public: +// CollisionShapePtr() : SharedPtr() {} +// CollisionShapePtr(CollisionShape* rep) : SharedPtr(rep) {} +// CollisionShapePtr(const CollisionShapePtr& r) : SharedPtr(r) {} +// }; +// +// void testSharedPtrBug() +// { +// CollisionShapePtr mCol[6]; +// mCol[0] = CollisionShapePtr(new CollisionShape()); +// mCol[1] = CollisionShapePtr(new CollisionShape()); +// mCol[2] = CollisionShapePtr(new CollisionShape()); +// mCol[3] = CollisionShapePtr(new CollisionShape()); +// mCol[4] = CollisionShapePtr(new CollisionShape()); +// mCol[5] = CollisionShapePtr(new CollisionShape()); +// mCol[0] = NULL; +// mCol[1] = CollisionShapePtr(new CollisionShape()); +// mCol[2] = CollisionShapePtr(new CollisionShape()); +// mCol[3] = NULL; +// mCol[4] = CollisionShapePtr(new CollisionShape()); +// mCol[5] = CollisionShapePtr(new CollisionShape()); +// +// } +// +// void testSpotlightViewProj(bool worldViewProj) +// { +// // Define programs that use spotlight projection +// +// String vpStr; +// vpStr = +// "void vp(float4 position : POSITION,\n" +// "out float4 oPosition : POSITION,\n" +// "out float4 oUV : TEXCOORD0,\n"; +// if (!worldViewProj) +// { +// vpStr += "uniform float4x4 world,\n" +// "uniform float4x4 spotlightViewProj,\n"; +// } +// else +// { +// vpStr += "uniform float4x4 spotlightWorldViewProj,\n"; +// } +// vpStr += "uniform float4x4 worldViewProj)\n" +// "{\n" +// " oPosition = mul(worldViewProj, position);\n"; +// if (worldViewProj) +// { +// vpStr += " oUV = mul(spotlightWorldViewProj, position);\n"; +// } +// else +// { +// vpStr += " float4 worldPos = mul(world, position);\n" +// " oUV = mul(spotlightViewProj, worldPos);\n"; +// } +// vpStr += "}\n"; +// +// String fpStr = +// "void fp(\n" +// "float4 uv : TEXCOORD0,\n" +// "uniform sampler2D tex : register(s0),\n" +// "out float4 oColor : COLOR)\n" +// "{\n" +// " uv = uv / uv.w;\n" +// " oColor = tex2D(tex, uv.xy);\n" +// "}\n"; +// +// HighLevelGpuProgramPtr vp = HighLevelGpuProgramManager::getSingleton() +// .createProgram("testvp", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// "cg", GPT_VERTEX_PROGRAM); +// vp->setSource(vpStr); +// vp->setParameter("profiles", "vs_1_1 arbvp1"); +// vp->setParameter("entry_point", "vp"); +// vp->load(); +// +// HighLevelGpuProgramPtr fp = HighLevelGpuProgramManager::getSingleton() +// .createProgram("testfp", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// "cg", GPT_FRAGMENT_PROGRAM); +// fp->setSource(fpStr); +// fp->setParameter("profiles", "ps_2_0 arbfp1"); +// fp->setParameter("entry_point", "fp"); +// fp->load(); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("TestSpotlightProj", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setVertexProgram("testvp"); +// p->getVertexProgramParameters()->setNamedAutoConstant( +// "worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); +// +// if (worldViewProj) +// { +// p->getVertexProgramParameters()->setNamedAutoConstant( +// "spotlightWorldViewProj", GpuProgramParameters::ACT_SPOTLIGHT_WORLDVIEWPROJ_MATRIX); +// } +// else +// { +// p->getVertexProgramParameters()->setNamedAutoConstant( +// "world", GpuProgramParameters::ACT_WORLD_MATRIX); +// p->getVertexProgramParameters()->setNamedAutoConstant( +// "spotlightViewProj", GpuProgramParameters::ACT_SPOTLIGHT_VIEWPROJ_MATRIX); +// } +// p->setFragmentProgram("testfp"); +// p->createTextureUnitState("ogrelogo.png"); +// +// Entity* pEnt; +// +// // Define a plane mesh, use the above material +// Plane plane; +// plane.normal = Vector3::UNIT_Z; +// plane.d = 200; +// MeshManager::getSingleton().createPlane("WallPlane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// plane,1500,1500,100,100,true,1,5,5,Vector3::UNIT_Y); +// pEnt = mSceneMgr->createEntity( "5", "WallPlane" ); +// pEnt->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pEnt); +// +// +// mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// +// mTestNode[0]->translate(0, 0, 750); +// +// Light* spot = mSceneMgr->createLight("l1"); +// spot->setType(Light::LT_SPOTLIGHT); +// spot->setDirection(Vector3::NEGATIVE_UNIT_Z); +// +// mTestNode[0]->attachObject(spot); +// +// +// } +// +// void testManualIlluminationStage(ShadowTechnique tech) +// { +// mSceneMgr->setShadowTechnique(tech); +// mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000); +// MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); +// MaterialManager::getSingleton().setDefaultAnisotropy(5); +// +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0.0, 0.0, 0.0)); +// +// mLight = mSceneMgr->createLight("MainLight"); +// mLight->setPosition(-400,400,-300); +// mLight->setDiffuseColour(0.9, 0.9, 1); +// mLight->setSpecularColour(0.9, 0.9, 1); +// mLight->setAttenuation(6000,1,0.001,0); +// +// +// mLight = mSceneMgr->createLight("Light2"); +// mLight->setPosition(300,200,100); +// mLight->setDiffuseColour(1, 0.6, 0.5); +// mLight->setSpecularColour(0.9, 0.9, 1); +// mLight->setAttenuation(6000,1,0.001,0); +// +// +// +// MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// msh->buildTangentVectors(); +// Entity* pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" ); +// pEnt->setMaterialName("Examples/OffsetMapping/Specular"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject( pEnt ); +// +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshPtr planeMesh = MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 1500,1500,100,100,true,1,15,15,Vector3::UNIT_Z); +// planeMesh->buildTangentVectors(); +// Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("Examples/OffsetMapping/Specular"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// mCamera->setPosition(180, 34, 223); +// mCamera->lookAt(0,50,0); +// +// +// } +// +// void testReinitialiseEntityAlteredMesh() +// { +// // test whether an Entity picks up that Mesh has changed +// // and therefore rebuild SubEntities +// +// mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); +// +// Light* l = mSceneMgr->createLight("l1"); +// l->setPosition(200, 300, 0); +// +// Entity* pEnt = mSceneMgr->createEntity("testEnt", "knot.mesh"); +// testUpdateMesh = pEnt->getMesh().get(); +// +// mSceneMgr->getRootSceneNode()->attachObject(pEnt); +// +// } +// +// void testSRGBtexture(bool enableGamma) +// { +// // NOTE: enable flag only turns on SRGB for texture sampling, you may +// // need to configure the window for the reverse conversion for consistency! +// MaterialPtr mat = MaterialManager::getSingleton().create("testsrgb", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// TextureUnitState* t = p->createTextureUnitState("ogrelogo.png"); +// t->setHardwareGammaEnabled(enableGamma); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); // -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); // -// } +// } // -// void testNegativeScale() -// { -// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); -// Light* l = mSceneMgr->createLight("l1"); -// l->setPosition(500, 500, 200); -// l->setDiffuseColour(ColourValue::White); +// void testNegativeScale() +// { +// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); +// Light* l = mSceneMgr->createLight("l1"); +// l->setPosition(500, 500, 200); +// l->setDiffuseColour(ColourValue::White); // -// //mSceneMgr->setFlipCullingOnNegativeScale(false); +// //mSceneMgr->setFlipCullingOnNegativeScale(false); // -// Entity *e = mSceneMgr->createEntity("1", "knot.mesh"); -// -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// -// // one reflection -// e = mSceneMgr->createEntity("2", "knot.mesh"); -// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// n->translate(-200, 0, 0); -// n->scale(-1, 1, 1); -// n->attachObject(e); -// -// // three reflections - will need flipping -// e = mSceneMgr->createEntity("3", "knot.mesh"); -// n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// n->translate(200, 0, 0); -// n->scale(-1, -1, -1); -// n->attachObject(e); +// Entity *e = mSceneMgr->createEntity("1", "knot.mesh"); +// +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// +// // one reflection +// e = mSceneMgr->createEntity("2", "knot.mesh"); +// SceneNode* n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// n->translate(-200, 0, 0); +// n->scale(-1, 1, 1); +// n->attachObject(e); +// +// // three reflections - will need flipping +// e = mSceneMgr->createEntity("3", "knot.mesh"); +// n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// n->translate(200, 0, 0); +// n->scale(-1, -1, -1); +// n->attachObject(e); // -// // two reflections - won't need flipping -// e = mSceneMgr->createEntity("4", "knot.mesh"); -// n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// n->translate(400, 0, 0); -// n->scale(-1, 1, -1); -// n->attachObject(e); +// // two reflections - won't need flipping +// e = mSceneMgr->createEntity("4", "knot.mesh"); +// n = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// n->translate(400, 0, 0); +// n->scale(-1, 1, -1); +// n->attachObject(e); // -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Red); // -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); // -// } +// } // // class TestLodListener // : public LodListener @@ -7516,280 +7516,280 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // // -// void testBug() -// { -// mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) ); -// -// ManualObject* man = mSceneMgr->createManualObject("1"); -// man->begin("testGLSLMat"); -// man->position(-300, 300, 0); -// man->colour(ColourValue::Red); -// man->position(-300, -300, 0); -// man->colour(ColourValue::Green); -// man->position(300, -300, 0); -// man->colour(ColourValue::Blue); -// man->position(300, 300, 0); -// man->colour(ColourValue::Black); -// man->quad(0, 1, 2, 3); -// man->end(); -// SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// node->attachObject(man); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// -// } -// -// void testManualObject2D() -// { -// ManualObject* man = mSceneMgr->createManualObject("1"); -// man->begin("Examples/OgreLogo"); -// man->position( 0.0, 0.0, 0.0); man->textureCoord( 0, 1 ); -// man->position( 0.1, 0.0, 0.0); man->textureCoord( 1, 1 ); -// man->position( 0.1, 0.1, 0.0); man->textureCoord( 1, 0 ); -// man->position( 0.0, 0.1, 0.0); man->textureCoord( 0, 0 ); -// -// man->triangle( 0, 1, 2 ); -// man->triangle( 0, 2, 3 ); -// -// man->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY -1); -// man->end(); -// man->setUseIdentityProjection(true); -// man->setUseIdentityView(true); -// AxisAlignedBox aabb; -// aabb.setInfinite(); -// man->setBoundingBox(aabb); -// -// SceneNode* sn = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// sn->setScale(5,5,1); -// sn->attachObject(man); -// } -// -// void testShadowLod(bool directional, ShadowTechnique tech) -// { -// // Test that LOD is based on main camera, not shadow camera -// -// mSceneMgr->setShadowTextureSize(1024); -// mSceneMgr->setShadowTechnique(tech); -// -// //FocusedShadowCameraSetup* lispsmSetup = new FocusedShadowCameraSetup(); -// //LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup(); -// //lispsmSetup->setOptimalAdjustFactor(1.5); -// //mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(lispsmSetup)); -// -// mSceneMgr->setShadowColour(ColourValue(0.35, 0.35, 0.35)); -// // Set ambient light -// mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); -// -// mLight = mSceneMgr->createLight("MainLight"); -// -// // Directional test -// if (directional) -// { -// mLight->setType(Light::LT_DIRECTIONAL); -// Vector3 vec(-1,-1,0); -// vec.normalise(); -// mLight->setDirection(vec); -// } -// // Spotlight test -// else -// { -// mLight->setType(Light::LT_SPOTLIGHT); -// mLight->setAttenuation(10000, 1, 0, 0); -// mLight->setDiffuseColour(1.0, 1.0, 0.8); -// mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// mTestNode[0]->setPosition(400,300,0); -// mTestNode[0]->lookAt(Vector3(0,0,0), Node::TS_WORLD, Vector3::UNIT_Z); -// mTestNode[0]->attachObject(mLight); -// } -// -// mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// -// -// Entity* pEnt; -// pEnt = mSceneMgr->createEntity( "1", "knot.mesh" ); -// // rendering distance should also be based on main cam -// //pEnt->setRenderingDistance(100); -// //pEnt->setMaterialName("2 - Default"); -// mTestNode[1]->attachObject( pEnt ); -// //mTestNode[1]->translate(0,-100,0); +// void testBug() +// { +// mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) ); +// +// ManualObject* man = mSceneMgr->createManualObject("1"); +// man->begin("testGLSLMat"); +// man->position(-300, 300, 0); +// man->colour(ColourValue::Red); +// man->position(-300, -300, 0); +// man->colour(ColourValue::Green); +// man->position(300, -300, 0); +// man->colour(ColourValue::Blue); +// man->position(300, 300, 0); +// man->colour(ColourValue::Black); +// man->quad(0, 1, 2, 3); +// man->end(); +// SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// node->attachObject(man); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// +// } +// +// void testManualObject2D() +// { +// ManualObject* man = mSceneMgr->createManualObject("1"); +// man->begin("Examples/OgreLogo"); +// man->position( 0.0, 0.0, 0.0); man->textureCoord( 0, 1 ); +// man->position( 0.1, 0.0, 0.0); man->textureCoord( 1, 1 ); +// man->position( 0.1, 0.1, 0.0); man->textureCoord( 1, 0 ); +// man->position( 0.0, 0.1, 0.0); man->textureCoord( 0, 0 ); +// +// man->triangle( 0, 1, 2 ); +// man->triangle( 0, 2, 3 ); +// +// man->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY -1); +// man->end(); +// man->setUseIdentityProjection(true); +// man->setUseIdentityView(true); +// AxisAlignedBox aabb; +// aabb.setInfinite(); +// man->setBoundingBox(aabb); +// +// SceneNode* sn = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// sn->setScale(5,5,1); +// sn->attachObject(man); +// } +// +// void testShadowLod(bool directional, ShadowTechnique tech) +// { +// // Test that LOD is based on main camera, not shadow camera +// +// mSceneMgr->setShadowTextureSize(1024); +// mSceneMgr->setShadowTechnique(tech); +// +// //FocusedShadowCameraSetup* lispsmSetup = new FocusedShadowCameraSetup(); +// //LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup(); +// //lispsmSetup->setOptimalAdjustFactor(1.5); +// //mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(lispsmSetup)); +// +// mSceneMgr->setShadowColour(ColourValue(0.35, 0.35, 0.35)); +// // Set ambient light +// mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); +// +// mLight = mSceneMgr->createLight("MainLight"); +// +// // Directional test +// if (directional) +// { +// mLight->setType(Light::LT_DIRECTIONAL); +// Vector3 vec(-1,-1,0); +// vec.normalise(); +// mLight->setDirection(vec); +// } +// // Spotlight test +// else +// { +// mLight->setType(Light::LT_SPOTLIGHT); +// mLight->setAttenuation(10000, 1, 0, 0); +// mLight->setDiffuseColour(1.0, 1.0, 0.8); +// mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// mTestNode[0]->setPosition(400,300,0); +// mTestNode[0]->lookAt(Vector3(0,0,0), Node::TS_WORLD, Vector3::UNIT_Z); +// mTestNode[0]->attachObject(mLight); +// } +// +// mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// +// +// Entity* pEnt; +// pEnt = mSceneMgr->createEntity( "1", "knot.mesh" ); +// // rendering distance should also be based on main cam +// //pEnt->setRenderingDistance(100); +// //pEnt->setMaterialName("2 - Default"); +// mTestNode[1]->attachObject( pEnt ); +// //mTestNode[1]->translate(0,-100,0); ///* -// pEnt = mSceneMgr->createEntity( "3", "knot.mesh" ); -// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-200, 0, -200)); -// mTestNode[2]->attachObject( pEnt ); -// -// -// createRandomEntityClones(pEnt, 20, Vector3(-1000,0,-1000), Vector3(1000,0,1000)); -// -// -// // Transparent object (can force cast shadows) -// pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" ); -// MaterialPtr tmat = MaterialManager::getSingleton().create("TestAlphaTransparency", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// tmat->setTransparencyCastsShadows(true); -// Pass* tpass = tmat->getTechnique(0)->getPass(0); -// tpass->setAlphaRejectSettings(CMPF_GREATER, 150); -// tpass->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// tpass->createTextureUnitState("gras_02.png"); -// tpass->setCullingMode(CULL_NONE); -// -// pEnt->setMaterialName("TestAlphaTransparency"); -// mTestNode[3] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(350, 0, -200)); -// mTestNode[3]->attachObject( pEnt ); -// -// MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// msh->buildTangentVectors(VES_TANGENT, 0, 0); -// pEnt = mSceneMgr->createEntity( "4", "knot.mesh" ); -// //pEnt->setMaterialName("Examples/BumpMapping/MultiLightSpecular"); -// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 200)); -// mTestNode[2]->attachObject( pEnt ); -// -// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); +// pEnt = mSceneMgr->createEntity( "3", "knot.mesh" ); +// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-200, 0, -200)); +// mTestNode[2]->attachObject( pEnt ); +// +// +// createRandomEntityClones(pEnt, 20, Vector3(-1000,0,-1000), Vector3(1000,0,1000)); +// +// +// // Transparent object (can force cast shadows) +// pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" ); +// MaterialPtr tmat = MaterialManager::getSingleton().create("TestAlphaTransparency", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// tmat->setTransparencyCastsShadows(true); +// Pass* tpass = tmat->getTechnique(0)->getPass(0); +// tpass->setAlphaRejectSettings(CMPF_GREATER, 150); +// tpass->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// tpass->createTextureUnitState("gras_02.png"); +// tpass->setCullingMode(CULL_NONE); +// +// pEnt->setMaterialName("TestAlphaTransparency"); +// mTestNode[3] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(350, 0, -200)); +// mTestNode[3]->attachObject( pEnt ); +// +// MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// msh->buildTangentVectors(VES_TANGENT, 0, 0); +// pEnt = mSceneMgr->createEntity( "4", "knot.mesh" ); +// //pEnt->setMaterialName("Examples/BumpMapping/MultiLightSpecular"); +// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 200)); +// mTestNode[2]->attachObject( pEnt ); +// +// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); //*/ // // -// movablePlane.normal = Vector3::UNIT_Y; -// movablePlane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, movablePlane, -// 2500,2500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt; -// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// if (tech & SHADOWDETAILTYPE_INTEGRATED) -// { -// pPlaneEnt->setMaterialName("Examples/Plane/IntegratedShadows"); -// } -// else -// { -// pPlaneEnt->setMaterialName("2 - Default"); -// } -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// addTextureShadowDebugOverlay(1); -// -// -// /* -// ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("smoke", -// "Examples/Smoke"); -// mTestNode[4] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-300, -100, 200)); -// mTestNode[4]->attachObject(pSys2); -// */ -// -// mCamera->setPosition(0, 1000, 500); -// mCamera->lookAt(0,0,0); -// mCamera->setFarClipDistance(10000); -// -// } -// -// // NOTE: you really need double-precision enabled for this, and even then -// // the default way of updating the camera position doesn't work at high frame rates -// // (really the update should be accumulated in a smaller offset variable and not -// // added each frame to the large existing position) -// void testFarFromOrigin() -// { -// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); -// mSceneMgr->setShadowTextureSettings(1024, 2); -// addTextureShadowDebugOverlay(2); -// -// Vector3 offset(100000, 0, 100000); -// //Vector3 offset(0, 0, 0); -// -// mSceneMgr->setAmbientLight(ColourValue(0.1, 0.1, 0.1)); -// -// // Directional test -// mLight = mSceneMgr->createLight("MainLight"); -// mLight->setType(Light::LT_DIRECTIONAL); -// Vector3 vec(-1,-1,0); -// vec.normalise(); -// mLight->setDirection(vec); -// mLight->setDiffuseColour(ColourValue(0.5, 0.5, 1.0)); -// -// // Spotlight test -// mLight = mSceneMgr->createLight("SpotLight"); -// mLight->setType(Light::LT_SPOTLIGHT); -// mLight->setAttenuation(10000, 1, 0, 0); -// mLight->setDiffuseColour(1.0, 1.0, 0.5); -// -// mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// mTestNode[0]->setPosition(offset + Vector3(-400,300,1000)); -// mTestNode[0]->lookAt(offset, Node::TS_WORLD, Vector3::UNIT_Z); -// mTestNode[0]->attachObject(mLight); -// -// -// mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// mTestNode[1]->setPosition(offset); -// -// Entity* pEnt; -// pEnt = mSceneMgr->createEntity( "1", "knot.mesh" ); -// mTestNode[1]->attachObject( pEnt ); -// -// -// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); -// -// -// Plane plane; -// plane.normal = Vector3::UNIT_Y; -// plane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, -// 2500,2500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt; -// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(offset)->attachObject(pPlaneEnt); -// -// ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("smoke", -// "Examples/Smoke"); -// mTestNode[4] = mSceneMgr->getRootSceneNode()->createChildSceneNode(offset + Vector3(-300, -100, 200)); -// mTestNode[4]->attachObject(pSys2); -// -// mCamera->setPosition(offset + Vector3(0, 1000, 500)); -// mCamera->lookAt(offset); -// mCamera->setFarClipDistance(10000); -// -// mSceneMgr->setCameraRelativeRendering(true); -// -// FocusedShadowCameraSetup* camSetup = new FocusedShadowCameraSetup(); -// mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(camSetup)); -// -// } -// -// void testGeometryShaders(void) +// movablePlane.normal = Vector3::UNIT_Y; +// movablePlane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, movablePlane, +// 2500,2500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt; +// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// if (tech & SHADOWDETAILTYPE_INTEGRATED) +// { +// pPlaneEnt->setMaterialName("Examples/Plane/IntegratedShadows"); +// } +// else +// { +// pPlaneEnt->setMaterialName("2 - Default"); +// } +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// addTextureShadowDebugOverlay(1); +// +// +// /* +// ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("smoke", +// "Examples/Smoke"); +// mTestNode[4] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-300, -100, 200)); +// mTestNode[4]->attachObject(pSys2); +// */ +// +// mCamera->setPosition(0, 1000, 500); +// mCamera->lookAt(0,0,0); +// mCamera->setFarClipDistance(10000); +// +// } +// +// // NOTE: you really need double-precision enabled for this, and even then +// // the default way of updating the camera position doesn't work at high frame rates +// // (really the update should be accumulated in a smaller offset variable and not +// // added each frame to the large existing position) +// void testFarFromOrigin() +// { +// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); +// mSceneMgr->setShadowTextureSettings(1024, 2); +// addTextureShadowDebugOverlay(2); +// +// Vector3 offset(100000, 0, 100000); +// //Vector3 offset(0, 0, 0); +// +// mSceneMgr->setAmbientLight(ColourValue(0.1, 0.1, 0.1)); +// +// // Directional test +// mLight = mSceneMgr->createLight("MainLight"); +// mLight->setType(Light::LT_DIRECTIONAL); +// Vector3 vec(-1,-1,0); +// vec.normalise(); +// mLight->setDirection(vec); +// mLight->setDiffuseColour(ColourValue(0.5, 0.5, 1.0)); +// +// // Spotlight test +// mLight = mSceneMgr->createLight("SpotLight"); +// mLight->setType(Light::LT_SPOTLIGHT); +// mLight->setAttenuation(10000, 1, 0, 0); +// mLight->setDiffuseColour(1.0, 1.0, 0.5); +// +// mTestNode[0] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// mTestNode[0]->setPosition(offset + Vector3(-400,300,1000)); +// mTestNode[0]->lookAt(offset, Node::TS_WORLD, Vector3::UNIT_Z); +// mTestNode[0]->attachObject(mLight); +// +// +// mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// mTestNode[1]->setPosition(offset); +// +// Entity* pEnt; +// pEnt = mSceneMgr->createEntity( "1", "knot.mesh" ); +// mTestNode[1]->attachObject( pEnt ); +// +// +// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); +// +// +// Plane plane; +// plane.normal = Vector3::UNIT_Y; +// plane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, +// 2500,2500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt; +// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(offset)->attachObject(pPlaneEnt); +// +// ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("smoke", +// "Examples/Smoke"); +// mTestNode[4] = mSceneMgr->getRootSceneNode()->createChildSceneNode(offset + Vector3(-300, -100, 200)); +// mTestNode[4]->attachObject(pSys2); +// +// mCamera->setPosition(offset + Vector3(0, 1000, 500)); +// mCamera->lookAt(offset); +// mCamera->setFarClipDistance(10000); +// +// mSceneMgr->setCameraRelativeRendering(true); +// +// FocusedShadowCameraSetup* camSetup = new FocusedShadowCameraSetup(); +// mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(camSetup)); +// +// } +// +// void testGeometryShaders(void) // { -// const String GLSL_MATERIAL_NAME = "Ogre/GPTest/SwizzleGLSL"; -// const String ASM_MATERIAL_NAME = "Ogre/GPTest/SwizzleASM"; -// const String CG_MATERIAL_NAME = "Ogre/GPTest/SwizzleCG"; +// const String GLSL_MATERIAL_NAME = "Ogre/GPTest/SwizzleGLSL"; +// const String ASM_MATERIAL_NAME = "Ogre/GPTest/SwizzleASM"; +// const String CG_MATERIAL_NAME = "Ogre/GPTest/SwizzleCG"; // // // Check capabilities -// const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); +// const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); // if (!caps->hasCapability(RSC_GEOMETRY_PROGRAM)) // { -// OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED, "Your card does not support geometry programs, so cannot " +// OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED, "Your card does not support geometry programs, so cannot " // "run this demo. Sorry!", // "GeometryShading::createScene"); // } -// -// int maxOutputVertices = caps->getGeometryProgramNumOutputVertices(); -// Ogre::LogManager::getSingleton().getDefaultLog()->stream() << -// "Num output vertices per geometry shader run : " << maxOutputVertices; +// +// int maxOutputVertices = caps->getGeometryProgramNumOutputVertices(); +// Ogre::LogManager::getSingleton().getDefaultLog()->stream() << +// "Num output vertices per geometry shader run : " << maxOutputVertices; // // Entity *ent = mSceneMgr->createEntity("head", "ogrehead.mesh"); // mCamera->setPosition(20, 0, 100); // mCamera->lookAt(0,0,0); -// -// //String materialName = GLSL_MATERIAL_NAME; -// String materialName = ASM_MATERIAL_NAME; -// //String materialName = CG_MATERIAL_NAME; -// -// // Set all of the material's sub entities to use the new material -// for (unsigned int i=0; igetNumSubEntities(); i++) -// { -// ent->getSubEntity(i)->setMaterialName(materialName); -// } +// +// //String materialName = GLSL_MATERIAL_NAME; +// String materialName = ASM_MATERIAL_NAME; +// //String materialName = CG_MATERIAL_NAME; +// +// // Set all of the material's sub entities to use the new material +// for (unsigned int i=0; igetNumSubEntities(); i++) +// { +// ent->getSubEntity(i)->setMaterialName(materialName); +// } // // // Add entity to the root scene node // mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); @@ -7797,647 +7797,647 @@ extern "C" _OgreSampleExport void dllStopPlugin() // mWindow->getViewport(0)->setBackgroundColour(ColourValue::Green); // } // -// void testAlphaToCoverage() -// { -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testa2c", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setAlphaRejectSettings(CMPF_GREATER, 96); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setAlphaToCoverageEnabled(true); -// TextureUnitState* t = p->createTextureUnitState("leaf.png"); -// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); -// Entity *e = mSceneMgr->createEntity("PlaneA2C", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 0))->attachObject(e); -// -// -// mat = MaterialManager::getSingleton().create("testnoa2c", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// p = mat->getTechnique(0)->getPass(0); -// p->setAlphaRejectSettings(CMPF_GREATER, 96); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// p->setAlphaToCoverageEnabled(false); -// t = p->createTextureUnitState("leaf.png"); -// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); -// e = mSceneMgr->createEntity("PlaneNoA2C", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-100, 0, 0))->attachObject(e); -// -// mat = MaterialManager::getSingleton().create("bg", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// t = p->createTextureUnitState(); -// t->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue::White); -// e = mSceneMgr->createEntity("PlaneBg", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// e->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND); -// SceneNode* s = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0, 0, -10)); -// s->setScale(5,5,5); -// s->attachObject(e); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// } -// -// void testLiSPSM() -// { -// mSceneMgr->setShadowTextureSize(1024); -// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); -// -// //FocusedShadowCameraSetup* lispsmSetup = new FocusedShadowCameraSetup(); -// LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup(); -// lispsmSetup->setOptimalAdjustFactor(2); -// mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(lispsmSetup)); -// -// mSceneMgr->setShadowFarDistance(3000); -// mSceneMgr->setShadowColour(ColourValue(0.35, 0.35, 0.35)); -// mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); -// -// mLight = mSceneMgr->createLight("MainLight"); -// mLight->setType(Light::LT_DIRECTIONAL); -// Vector3 vec(-1,-1,0); -// vec.normalise(); -// mLight->setDirection(vec); -// -// mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); -// -// -// Entity* pEnt; -// pEnt = mSceneMgr->createEntity( "1", "robot.mesh" ); -// //pEnt->setRenderingDistance(100); -// mAnimState = pEnt->getAnimationState("Walk"); -// mAnimState->setEnabled(true); -// //pEnt->setMaterialName("2 - Default"); -// mTestNode[1]->attachObject( pEnt ); -// mTestNode[1]->translate(0,-100,0); -// -// pEnt = mSceneMgr->createEntity( "3", "knot.mesh" ); -// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-200, 0, -200)); -// mTestNode[2]->attachObject( pEnt ); -// -// createRandomEntityClones(pEnt, 20, Vector3(-1000,0,-1000), Vector3(1000,0,1000)); -// -// // Transparent object (can force cast shadows) -// pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" ); -// MaterialPtr tmat = MaterialManager::getSingleton().create("TestAlphaTransparency", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// tmat->setTransparencyCastsShadows(true); -// Pass* tpass = tmat->getTechnique(0)->getPass(0); -// tpass->setAlphaRejectSettings(CMPF_GREATER, 150); -// tpass->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// tpass->createTextureUnitState("gras_02.png"); -// tpass->setCullingMode(CULL_NONE); -// -// pEnt->setMaterialName("TestAlphaTransparency"); -// mTestNode[3] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(350, 0, -200)); -// mTestNode[3]->attachObject( pEnt ); -// -// MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// msh->buildTangentVectors(VES_TANGENT, 0, 0); -// pEnt = mSceneMgr->createEntity( "4", "knot.mesh" ); -// //pEnt->setMaterialName("Examples/BumpMapping/MultiLightSpecular"); -// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 200)); -// mTestNode[2]->attachObject( pEnt ); -// -// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); -// -// movablePlane.normal = Vector3::UNIT_Y; -// movablePlane.d = 100; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, movablePlane, -// 2500,2500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt; -// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("2 - Default"); -// pPlaneEnt->setCastShadows(false); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// addTextureShadowDebugOverlay(1); -// -// -// mCamera->setPosition(0, 1000, 500); -// mCamera->lookAt(0,0,0); -// mCamera->setFarClipDistance(10000); -// -// -// } -// -// void testBlitSubTextures() -// { -// Image img; -// img.load("ogrelogo.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// -// TexturePtr tex = TextureManager::getSingleton().createManual("testblitdst", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 1024, 1024, 1, 0, PF_R8G8B8A8); -// -// PixelBox srcBox; -// // this box should select from halfway through the head, to the 'OG' part of the logo -// srcBox.left = 376; -// srcBox.top = 379; -// srcBox.right = 376 + 224; -// srcBox.bottom = 379 + 278; -// srcBox.back = 1; -// srcBox.front = 0; -// srcBox.format = img.getFormat(); -// srcBox.data = img.getData(); -// srcBox.rowPitch = img.getWidth(); -// srcBox.slicePitch = img.getWidth() * img.getHeight(); -// -// Image::Box dstBox; -// dstBox.left = srcBox.left; -// dstBox.top = srcBox.top; -// dstBox.right = srcBox.right; -// dstBox.bottom = srcBox.bottom; -// dstBox.back = 1; -// dstBox.front = 0; -// -// tex->getBuffer()->blitFromMemory(srcBox, dstBox); -// -// MaterialPtr mat = MaterialManager::getSingleton().create("testblit", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p = mat->getTechnique(0)->getPass(0); -// p->setLightingEnabled(false); -// p->setCullingMode(CULL_NONE); -// TextureUnitState* t = p->createTextureUnitState(tex->getName()); -// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// -// mCamera->setPosition(0,0,300); -// mCamera->lookAt(Vector3::ZERO); -// -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Green); -// -// -// } -// -// void testDepthShadowMap() -// { -// mSceneMgr->setShadowTextureCount(1); -// mSceneMgr->setShadowTextureConfig(0, 1024, 1024, PF_FLOAT32_R); -// mSceneMgr->setShadowTextureSelfShadow(true); -// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED); -// mSceneMgr->setShadowCasterRenderBackFaces(false); -// -// mSceneMgr->setShadowTextureCasterMaterial("DepthShadowCaster"); -// -// // Single light -// Light* l = mSceneMgr->createLight("l1"); -// l->setType(Light::LT_SPOTLIGHT); -// //l->setPosition(500, 500, -100); -// l->setPosition(0, 500, 0); -// Vector3 dir = -l->getPosition(); -// dir.normalise(); -// l->setDirection(dir); -// l->setSpotlightOuterAngle(Degree(40)); -// l->setSpotlightInnerAngle(Degree(35)); -// -// -// // ground plane -// movablePlane.normal = Vector3::UNIT_Y; -// movablePlane.d = 0; -// MeshManager::getSingleton().createPlane("Myplane", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, movablePlane, -// 5500,5500,10,10,true,1,5,5,Vector3::UNIT_Z); -// Entity* pPlaneEnt; -// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); -// pPlaneEnt->setMaterialName("DepthShadowReceiver"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); -// -// // box -// ManualObject* man = mSceneMgr->createManualObject("box"); -// Real boxsize = 50; -// Real boxsizehalf = boxsize / 2.0; -// man->begin("DepthShadowReceiver"); -// man->position(-boxsizehalf, 0, boxsizehalf); -// man->position(boxsizehalf, 0, boxsizehalf); -// man->position(boxsizehalf, 0, -boxsizehalf); -// man->position(-boxsizehalf, 0, -boxsizehalf); -// man->position(-boxsizehalf, boxsize, boxsizehalf); -// man->position(boxsizehalf, boxsize, boxsizehalf); -// man->position(boxsizehalf, boxsize, -boxsizehalf); -// man->position(-boxsizehalf, boxsize, -boxsizehalf); -// man->quad(3, 2, 1, 0); -// man->quad(4, 5, 6, 7); -// man->quad(0, 1, 5, 4); -// man->quad(1, 2, 6, 5); -// man->quad(2, 3, 7, 6); -// man->quad(3, 0, 4, 7); -// man->end(); -// -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(man); -// -// mCamera->setPosition(0, 200, 100); -// mCamera->lookAt(Vector3::ZERO); -// -// -// // Create RTT -// //TexturePtr rtt = TextureManager::getSingleton().createManual("rtt1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, -// // TEX_TYPE_2D, 1024, 1024, 1, 0, PF_FLOAT32_R); -// -// -// -// } -// -// void testSharedGpuParameters() -// { -// // define a couple of *different* shaders, but each of which refers to some common params -// String vpSrc1 = " \ -// void vp1(float4 position : POSITION, \ -// out float4 oPosition : POSITION, \ -// out float4 oCol : COLOR, \ -// \ -// uniform float4 colourInput, \ -// uniform float someFloatParam, \ -// uniform float4x4 worldViewProj) \ -// { \ -// oPosition = mul(worldViewProj, position); \ -// oCol = colourInput; \ -// oCol.g += someFloatParam; \ -// } \ -// "; -// String vpSrc2 = " \ -// void vp2(float4 position : POSITION, \ -// out float4 oPosition : POSITION, \ -// out float4 oCol : COLOR, \ -// \ -// uniform float4 ambient, \ -// uniform float4 colourInput, \ -// uniform float someFloatParam, \ -// uniform float4x4 worldViewProj) \ -// { \ -// oPosition = mul(worldViewProj, position); \ -// oCol = ambient + colourInput; \ -// oCol.g += someFloatParam; \ -// } \ -// "; -// -// HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton(); -// HighLevelGpuProgramPtr vp1 = hmgr.createProgram("vp1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM); -// vp1->setSource(vpSrc1); -// vp1->setParameter("entry_point", "vp1"); -// vp1->setParameter("profiles", "vs_1_1 arbvp1"); -// vp1->load(); -// HighLevelGpuProgramPtr vp2 = hmgr.createProgram("vp2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM); -// vp2->setSource(vpSrc2); -// vp2->setParameter("entry_point", "vp2"); -// vp2->setParameter("profiles", "vs_1_1 arbvp1"); -// vp2->load(); -// -// testSharedParams = GpuProgramManager::getSingleton().createSharedParameters("SinbadsParams"); -// -// // define the shared param structure -// // deliberately define in the opposite order to programs, shouldn't matter -// testSharedParams->addConstantDefinition("colourInput", GCT_FLOAT4); -// testSharedParams->addConstantDefinition("someFloatParam", GCT_FLOAT1); -// -// // set some initial values -// Vector4 col(0.7, 0.0, 0.0, 1.0); -// testSharedParams->setNamedConstant("colourInput", col); -// testSharedParams->setNamedConstant("someFloatParam", 0.1f); -// -// // define materials -// MaterialManager& mmgr = MaterialManager::getSingleton(); -// MaterialPtr m1 = mmgr.create("m1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p1 = m1->getTechnique(0)->getPass(0); -// p1->setVertexProgram("vp1"); -// GpuProgramParametersSharedPtr params1 = p1->getVertexProgramParameters(); -// params1->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); -// params1->addSharedParameters("SinbadsParams"); -// -// -// MaterialPtr m2 = mmgr.create("m2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* p2 = m2->getTechnique(0)->getPass(0); -// p2->setVertexProgram("vp2"); -// GpuProgramParametersSharedPtr params2 = p2->getVertexProgramParameters(); -// params2->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); -// params2->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR); -// params2->addSharedParameters("SinbadsParams"); -// -// -// Entity* e = mSceneMgr->createEntity("1", "knot.mesh"); -// e->setMaterialName("m1"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-100, 0, 0))->attachObject(e); -// -// e = mSceneMgr->createEntity("2", "knot.mesh"); -// e->setMaterialName("m2"); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 0))->attachObject(e); -// -// mCamera->setPosition(0, 0, 300); -// mCamera->lookAt(Vector3::ZERO); -// -// mWindow->getViewport(0)->setBackgroundColour(ColourValue(0, 1, 1)); -// -// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2, 1.0)); -// -// -// } -// -// void testImageCombine() -// { -// Image combined; -// -// // pick 2 files that are the same size, alpha texture will be made greyscale -// combined.loadTwoImagesAsRGBA("rockwall.tga", "flare.png", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); -// -// TexturePtr tex = TextureManager::getSingleton().createManual("1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 256, 256, 1, 0, PF_BYTE_RGBA); -// tex->loadImage(combined); -// -// MaterialManager& mmgr = MaterialManager::getSingleton(); -// MaterialPtr mat = mmgr.create("m1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// Pass* pass = mat->getTechnique(0)->getPass(0); -// pass->setLightingEnabled(false); -// pass->setCullingMode(CULL_NONE); -// pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); -// pass->setDepthWriteEnabled(false); -// pass->createTextureUnitState(tex->getName()); -// -// Entity *e = mSceneMgr->createEntity("test", SceneManager::PT_PLANE); -// e->setMaterialName(mat->getName()); -// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); -// -// mCamera->setPosition(0, 0, 200); -// mCamera->lookAt(Vector3::ZERO); -// -// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Blue); -// -// } -// -// Terrain* createTerrain() -// { -// Terrain* terrain = OGRE_NEW Terrain(mSceneMgr); -// Image img; -// img.load("terrain.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// //img.load("terrain_flattened.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// //img.load("terrain_onehill.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// -// Terrain::ImportData imp; -// imp.inputImage = &img; -// imp.terrainSize = 513; -// imp.worldSize = 8000; -// imp.inputScale = 600; -// imp.minBatchSize = 33; -// imp.maxBatchSize = 65; -// // textures -// imp.layerList.resize(3); -// imp.layerList[0].worldSize = 100; -// imp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds"); -// imp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds"); -// imp.layerList[1].worldSize = 30; -// imp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds"); -// imp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds"); -// imp.layerList[2].worldSize = 200; -// imp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds"); -// imp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds"); -// terrain->prepare(imp); -// terrain->load(); -// -// TerrainLayerBlendMap* blendMap0 = terrain->getLayerBlendMap(1); -// TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap(2); -// Real minHeight0 = 70; -// Real fadeDist0 = 40; -// Real minHeight1 = 70; -// Real fadeDist1 = 15; -// float* pBlend0 = blendMap0->getBlendPointer(); -// float* pBlend1 = blendMap1->getBlendPointer(); -// for (Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize(); ++y) -// { -// for (Ogre::uint16 x = 0; x < terrain->getLayerBlendMapSize(); ++x) -// { -// Real tx, ty; -// -// blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty); -// Real height = terrain->getHeightAtTerrainPosition(tx, ty); -// Real val = (height - minHeight0) / fadeDist0; -// val = Math::Clamp(val, (Real)0, (Real)1); -// //*pBlend0++ = val; -// -// val = (height - minHeight1) / fadeDist1; -// val = Math::Clamp(val, (Real)0, (Real)1); -// *pBlend1++ = val; -// -// -// } -// } -// blendMap0->dirty(); -// blendMap1->dirty(); -// //blendMap0->loadImage("blendmap1.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// blendMap0->update(); -// blendMap1->update(); -// -// /* -// // set up a colour map -// terrain->setGlobalColourMapEnabled(true); -// Image colourMap; -// colourMap.load("testcolourmap.jpg", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// terrain->getGlobalColourMap()->loadImage(colourMap); -// */ -// -// terrain->freeTemporaryResources(); -// -// return terrain; -// -// } -// -// void testNewTerrain(bool loadTerrain = false, bool saveTerrain = false, const String& filename = "testTerrain.dat") -// { -// MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); -// MaterialManager::getSingleton().setDefaultAnisotropy(7); -// -// LogManager::getSingleton().setLogDetail(LL_BOREME); -// -// Vector3 lightdir(0, -0.3, 0.75); -// lightdir.normalise(); -// -// -// TerrainGlobalOptions::setMaxPixelError(8); -// // testing composite map -// TerrainGlobalOptions::setCompositeMapDistance(2000); -// //TerrainGlobalOptions::setUseRayBoxDistanceCalculation(true); -// //TerrainGlobalOptions::getDefaultMaterialGenerator()->setDebugLevel(1); -// //TerrainGlobalOptions::setLightMapSize(256); -// -// -// -// Light* l = mSceneMgr->createLight("tstLight"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(lightdir); -// l->setDiffuseColour(ColourValue::White); -// l->setSpecularColour(ColourValue(0.4, 0.4, 0.4)); -// -// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); -// -// -// // Important to set these so that the terrain knows what to use for derived (non-realtime) data -// TerrainGlobalOptions::setLightMapDirection(lightdir); -// TerrainGlobalOptions::setCompositeMapAmbient(mSceneMgr->getAmbientLight()); -// //TerrainGlobalOptions::setCompositeMapAmbient(ColourValue::Red); -// TerrainGlobalOptions::setCompositeMapDiffuse(l->getDiffuseColour()); -// -// //mSceneMgr->showBoundingBoxes(true); -// if (loadTerrain) -// { -// mTerrain = OGRE_NEW Terrain(mSceneMgr); -// mTerrain->load(filename); -// } -// else -// { -// mTerrain = createTerrain(); +// void testAlphaToCoverage() +// { +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testa2c", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setAlphaRejectSettings(CMPF_GREATER, 96); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setAlphaToCoverageEnabled(true); +// TextureUnitState* t = p->createTextureUnitState("leaf.png"); +// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); +// Entity *e = mSceneMgr->createEntity("PlaneA2C", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 0))->attachObject(e); +// +// +// mat = MaterialManager::getSingleton().create("testnoa2c", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// p = mat->getTechnique(0)->getPass(0); +// p->setAlphaRejectSettings(CMPF_GREATER, 96); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// p->setAlphaToCoverageEnabled(false); +// t = p->createTextureUnitState("leaf.png"); +// t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); +// e = mSceneMgr->createEntity("PlaneNoA2C", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-100, 0, 0))->attachObject(e); +// +// mat = MaterialManager::getSingleton().create("bg", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// t = p->createTextureUnitState(); +// t->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue::White); +// e = mSceneMgr->createEntity("PlaneBg", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// e->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND); +// SceneNode* s = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0, 0, -10)); +// s->setScale(5,5,5); +// s->attachObject(e); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// } +// +// void testLiSPSM() +// { +// mSceneMgr->setShadowTextureSize(1024); +// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE); +// +// //FocusedShadowCameraSetup* lispsmSetup = new FocusedShadowCameraSetup(); +// LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup(); +// lispsmSetup->setOptimalAdjustFactor(2); +// mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(lispsmSetup)); +// +// mSceneMgr->setShadowFarDistance(3000); +// mSceneMgr->setShadowColour(ColourValue(0.35, 0.35, 0.35)); +// mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); +// +// mLight = mSceneMgr->createLight("MainLight"); +// mLight->setType(Light::LT_DIRECTIONAL); +// Vector3 vec(-1,-1,0); +// vec.normalise(); +// mLight->setDirection(vec); +// +// mTestNode[1] = mSceneMgr->getRootSceneNode()->createChildSceneNode(); +// +// +// Entity* pEnt; +// pEnt = mSceneMgr->createEntity( "1", "robot.mesh" ); +// //pEnt->setRenderingDistance(100); +// mAnimState = pEnt->getAnimationState("Walk"); +// mAnimState->setEnabled(true); +// //pEnt->setMaterialName("2 - Default"); +// mTestNode[1]->attachObject( pEnt ); +// mTestNode[1]->translate(0,-100,0); +// +// pEnt = mSceneMgr->createEntity( "3", "knot.mesh" ); +// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-200, 0, -200)); +// mTestNode[2]->attachObject( pEnt ); +// +// createRandomEntityClones(pEnt, 20, Vector3(-1000,0,-1000), Vector3(1000,0,1000)); +// +// // Transparent object (can force cast shadows) +// pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" ); +// MaterialPtr tmat = MaterialManager::getSingleton().create("TestAlphaTransparency", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// tmat->setTransparencyCastsShadows(true); +// Pass* tpass = tmat->getTechnique(0)->getPass(0); +// tpass->setAlphaRejectSettings(CMPF_GREATER, 150); +// tpass->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// tpass->createTextureUnitState("gras_02.png"); +// tpass->setCullingMode(CULL_NONE); +// +// pEnt->setMaterialName("TestAlphaTransparency"); +// mTestNode[3] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(350, 0, -200)); +// mTestNode[3]->attachObject( pEnt ); +// +// MeshPtr msh = MeshManager::getSingleton().load("knot.mesh", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// msh->buildTangentVectors(VES_TANGENT, 0, 0); +// pEnt = mSceneMgr->createEntity( "4", "knot.mesh" ); +// //pEnt->setMaterialName("Examples/BumpMapping/MultiLightSpecular"); +// mTestNode[2] = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 200)); +// mTestNode[2]->attachObject( pEnt ); +// +// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); +// +// movablePlane.normal = Vector3::UNIT_Y; +// movablePlane.d = 100; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, movablePlane, +// 2500,2500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt; +// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("2 - Default"); +// pPlaneEnt->setCastShadows(false); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// addTextureShadowDebugOverlay(1); +// +// +// mCamera->setPosition(0, 1000, 500); +// mCamera->lookAt(0,0,0); +// mCamera->setFarClipDistance(10000); +// +// +// } +// +// void testBlitSubTextures() +// { +// Image img; +// img.load("ogrelogo.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// +// TexturePtr tex = TextureManager::getSingleton().createManual("testblitdst", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 1024, 1024, 1, 0, PF_R8G8B8A8); +// +// PixelBox srcBox; +// // this box should select from halfway through the head, to the 'OG' part of the logo +// srcBox.left = 376; +// srcBox.top = 379; +// srcBox.right = 376 + 224; +// srcBox.bottom = 379 + 278; +// srcBox.back = 1; +// srcBox.front = 0; +// srcBox.format = img.getFormat(); +// srcBox.data = img.getData(); +// srcBox.rowPitch = img.getWidth(); +// srcBox.slicePitch = img.getWidth() * img.getHeight(); +// +// Image::Box dstBox; +// dstBox.left = srcBox.left; +// dstBox.top = srcBox.top; +// dstBox.right = srcBox.right; +// dstBox.bottom = srcBox.bottom; +// dstBox.back = 1; +// dstBox.front = 0; +// +// tex->getBuffer()->blitFromMemory(srcBox, dstBox); +// +// MaterialPtr mat = MaterialManager::getSingleton().create("testblit", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p = mat->getTechnique(0)->getPass(0); +// p->setLightingEnabled(false); +// p->setCullingMode(CULL_NONE); +// TextureUnitState* t = p->createTextureUnitState(tex->getName()); +// Entity *e = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// +// mCamera->setPosition(0,0,300); +// mCamera->lookAt(Vector3::ZERO); +// +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Green); +// +// +// } +// +// void testDepthShadowMap() +// { +// mSceneMgr->setShadowTextureCount(1); +// mSceneMgr->setShadowTextureConfig(0, 1024, 1024, PF_FLOAT32_R); +// mSceneMgr->setShadowTextureSelfShadow(true); +// mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED); +// mSceneMgr->setShadowCasterRenderBackFaces(false); +// +// mSceneMgr->setShadowTextureCasterMaterial("DepthShadowCaster"); +// +// // Single light +// Light* l = mSceneMgr->createLight("l1"); +// l->setType(Light::LT_SPOTLIGHT); +// //l->setPosition(500, 500, -100); +// l->setPosition(0, 500, 0); +// Vector3 dir = -l->getPosition(); +// dir.normalise(); +// l->setDirection(dir); +// l->setSpotlightOuterAngle(Degree(40)); +// l->setSpotlightInnerAngle(Degree(35)); +// +// +// // ground plane +// movablePlane.normal = Vector3::UNIT_Y; +// movablePlane.d = 0; +// MeshManager::getSingleton().createPlane("Myplane", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, movablePlane, +// 5500,5500,10,10,true,1,5,5,Vector3::UNIT_Z); +// Entity* pPlaneEnt; +// pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); +// pPlaneEnt->setMaterialName("DepthShadowReceiver"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); +// +// // box +// ManualObject* man = mSceneMgr->createManualObject("box"); +// Real boxsize = 50; +// Real boxsizehalf = boxsize / 2.0; +// man->begin("DepthShadowReceiver"); +// man->position(-boxsizehalf, 0, boxsizehalf); +// man->position(boxsizehalf, 0, boxsizehalf); +// man->position(boxsizehalf, 0, -boxsizehalf); +// man->position(-boxsizehalf, 0, -boxsizehalf); +// man->position(-boxsizehalf, boxsize, boxsizehalf); +// man->position(boxsizehalf, boxsize, boxsizehalf); +// man->position(boxsizehalf, boxsize, -boxsizehalf); +// man->position(-boxsizehalf, boxsize, -boxsizehalf); +// man->quad(3, 2, 1, 0); +// man->quad(4, 5, 6, 7); +// man->quad(0, 1, 5, 4); +// man->quad(1, 2, 6, 5); +// man->quad(2, 3, 7, 6); +// man->quad(3, 0, 4, 7); +// man->end(); +// +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(man); +// +// mCamera->setPosition(0, 200, 100); +// mCamera->lookAt(Vector3::ZERO); +// +// +// // Create RTT +// //TexturePtr rtt = TextureManager::getSingleton().createManual("rtt1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, +// // TEX_TYPE_2D, 1024, 1024, 1, 0, PF_FLOAT32_R); +// +// +// +// } +// +// void testSharedGpuParameters() +// { +// // define a couple of *different* shaders, but each of which refers to some common params +// String vpSrc1 = " \ +// void vp1(float4 position : POSITION, \ +// out float4 oPosition : POSITION, \ +// out float4 oCol : COLOR, \ +// \ +// uniform float4 colourInput, \ +// uniform float someFloatParam, \ +// uniform float4x4 worldViewProj) \ +// { \ +// oPosition = mul(worldViewProj, position); \ +// oCol = colourInput; \ +// oCol.g += someFloatParam; \ +// } \ +// "; +// String vpSrc2 = " \ +// void vp2(float4 position : POSITION, \ +// out float4 oPosition : POSITION, \ +// out float4 oCol : COLOR, \ +// \ +// uniform float4 ambient, \ +// uniform float4 colourInput, \ +// uniform float someFloatParam, \ +// uniform float4x4 worldViewProj) \ +// { \ +// oPosition = mul(worldViewProj, position); \ +// oCol = ambient + colourInput; \ +// oCol.g += someFloatParam; \ +// } \ +// "; +// +// HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton(); +// HighLevelGpuProgramPtr vp1 = hmgr.createProgram("vp1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM); +// vp1->setSource(vpSrc1); +// vp1->setParameter("entry_point", "vp1"); +// vp1->setParameter("profiles", "vs_1_1 arbvp1"); +// vp1->load(); +// HighLevelGpuProgramPtr vp2 = hmgr.createProgram("vp2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM); +// vp2->setSource(vpSrc2); +// vp2->setParameter("entry_point", "vp2"); +// vp2->setParameter("profiles", "vs_1_1 arbvp1"); +// vp2->load(); +// +// testSharedParams = GpuProgramManager::getSingleton().createSharedParameters("SinbadsParams"); +// +// // define the shared param structure +// // deliberately define in the opposite order to programs, shouldn't matter +// testSharedParams->addConstantDefinition("colourInput", GCT_FLOAT4); +// testSharedParams->addConstantDefinition("someFloatParam", GCT_FLOAT1); +// +// // set some initial values +// Vector4 col(0.7, 0.0, 0.0, 1.0); +// testSharedParams->setNamedConstant("colourInput", col); +// testSharedParams->setNamedConstant("someFloatParam", 0.1f); +// +// // define materials +// MaterialManager& mmgr = MaterialManager::getSingleton(); +// MaterialPtr m1 = mmgr.create("m1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p1 = m1->getTechnique(0)->getPass(0); +// p1->setVertexProgram("vp1"); +// GpuProgramParametersSharedPtr params1 = p1->getVertexProgramParameters(); +// params1->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); +// params1->addSharedParameters("SinbadsParams"); +// +// +// MaterialPtr m2 = mmgr.create("m2", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* p2 = m2->getTechnique(0)->getPass(0); +// p2->setVertexProgram("vp2"); +// GpuProgramParametersSharedPtr params2 = p2->getVertexProgramParameters(); +// params2->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); +// params2->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR); +// params2->addSharedParameters("SinbadsParams"); +// +// +// Entity* e = mSceneMgr->createEntity("1", "knot.mesh"); +// e->setMaterialName("m1"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-100, 0, 0))->attachObject(e); +// +// e = mSceneMgr->createEntity("2", "knot.mesh"); +// e->setMaterialName("m2"); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 0))->attachObject(e); +// +// mCamera->setPosition(0, 0, 300); +// mCamera->lookAt(Vector3::ZERO); +// +// mWindow->getViewport(0)->setBackgroundColour(ColourValue(0, 1, 1)); +// +// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2, 1.0)); +// +// +// } +// +// void testImageCombine() +// { +// Image combined; +// +// // pick 2 files that are the same size, alpha texture will be made greyscale +// combined.loadTwoImagesAsRGBA("rockwall.tga", "flare.png", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); +// +// TexturePtr tex = TextureManager::getSingleton().createManual("1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 256, 256, 1, 0, PF_BYTE_RGBA); +// tex->loadImage(combined); +// +// MaterialManager& mmgr = MaterialManager::getSingleton(); +// MaterialPtr mat = mmgr.create("m1", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Pass* pass = mat->getTechnique(0)->getPass(0); +// pass->setLightingEnabled(false); +// pass->setCullingMode(CULL_NONE); +// pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); +// pass->setDepthWriteEnabled(false); +// pass->createTextureUnitState(tex->getName()); +// +// Entity *e = mSceneMgr->createEntity("test", SceneManager::PT_PLANE); +// e->setMaterialName(mat->getName()); +// mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); +// +// mCamera->setPosition(0, 0, 200); +// mCamera->lookAt(Vector3::ZERO); +// +// mWindow->getViewport(0)->setBackgroundColour(ColourValue::Blue); +// +// } +// +// Terrain* createTerrain() +// { +// Terrain* terrain = OGRE_NEW Terrain(mSceneMgr); +// Image img; +// img.load("terrain.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// //img.load("terrain_flattened.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// //img.load("terrain_onehill.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// +// Terrain::ImportData imp; +// imp.inputImage = &img; +// imp.terrainSize = 513; +// imp.worldSize = 8000; +// imp.inputScale = 600; +// imp.minBatchSize = 33; +// imp.maxBatchSize = 65; +// // textures +// imp.layerList.resize(3); +// imp.layerList[0].worldSize = 100; +// imp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds"); +// imp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds"); +// imp.layerList[1].worldSize = 30; +// imp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds"); +// imp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds"); +// imp.layerList[2].worldSize = 200; +// imp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds"); +// imp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds"); +// terrain->prepare(imp); +// terrain->load(); +// +// TerrainLayerBlendMap* blendMap0 = terrain->getLayerBlendMap(1); +// TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap(2); +// Real minHeight0 = 70; +// Real fadeDist0 = 40; +// Real minHeight1 = 70; +// Real fadeDist1 = 15; +// float* pBlend0 = blendMap0->getBlendPointer(); +// float* pBlend1 = blendMap1->getBlendPointer(); +// for (Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize(); ++y) +// { +// for (Ogre::uint16 x = 0; x < terrain->getLayerBlendMapSize(); ++x) +// { +// Real tx, ty; +// +// blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty); +// Real height = terrain->getHeightAtTerrainPosition(tx, ty); +// Real val = (height - minHeight0) / fadeDist0; +// val = Math::Clamp(val, (Real)0, (Real)1); +// //*pBlend0++ = val; +// +// val = (height - minHeight1) / fadeDist1; +// val = Math::Clamp(val, (Real)0, (Real)1); +// *pBlend1++ = val; +// +// +// } +// } +// blendMap0->dirty(); +// blendMap1->dirty(); +// //blendMap0->loadImage("blendmap1.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// blendMap0->update(); +// blendMap1->update(); +// +// /* +// // set up a colour map +// terrain->setGlobalColourMapEnabled(true); +// Image colourMap; +// colourMap.load("testcolourmap.jpg", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// terrain->getGlobalColourMap()->loadImage(colourMap); +// */ +// +// terrain->freeTemporaryResources(); +// +// return terrain; +// +// } +// +// void testNewTerrain(bool loadTerrain = false, bool saveTerrain = false, const String& filename = "testTerrain.dat") +// { +// MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); +// MaterialManager::getSingleton().setDefaultAnisotropy(7); +// +// LogManager::getSingleton().setLogDetail(LL_BOREME); +// +// Vector3 lightdir(0, -0.3, 0.75); +// lightdir.normalise(); +// +// +// TerrainGlobalOptions::setMaxPixelError(8); +// // testing composite map +// TerrainGlobalOptions::setCompositeMapDistance(2000); +// //TerrainGlobalOptions::setUseRayBoxDistanceCalculation(true); +// //TerrainGlobalOptions::getDefaultMaterialGenerator()->setDebugLevel(1); +// //TerrainGlobalOptions::setLightMapSize(256); +// +// +// +// Light* l = mSceneMgr->createLight("tstLight"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(lightdir); +// l->setDiffuseColour(ColourValue::White); +// l->setSpecularColour(ColourValue(0.4, 0.4, 0.4)); +// +// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); +// +// +// // Important to set these so that the terrain knows what to use for derived (non-realtime) data +// TerrainGlobalOptions::setLightMapDirection(lightdir); +// TerrainGlobalOptions::setCompositeMapAmbient(mSceneMgr->getAmbientLight()); +// //TerrainGlobalOptions::setCompositeMapAmbient(ColourValue::Red); +// TerrainGlobalOptions::setCompositeMapDiffuse(l->getDiffuseColour()); +// +// //mSceneMgr->showBoundingBoxes(true); +// if (loadTerrain) +// { +// mTerrain = OGRE_NEW Terrain(mSceneMgr); +// mTerrain->load(filename); +// } +// else +// { +// mTerrain = createTerrain(); // -// } +// } // -// //addTextureDebugOverlay(TextureManager::getSingleton().getByName(mTerrain->getTerrainNormalMap()->getName()), 0); +// //addTextureDebugOverlay(TextureManager::getSingleton().getByName(mTerrain->getTerrainNormalMap()->getName()), 0); // -// //mWindow->getViewport(0)->setBackgroundColour(ColourValue::Blue); +// //mWindow->getViewport(0)->setBackgroundColour(ColourValue::Blue); // -// Vector3 terrainPos(10000,0,5000); -// mTerrain->setPosition(terrainPos); +// Vector3 terrainPos(10000,0,5000); +// mTerrain->setPosition(terrainPos); // -// /* -// // create a few entities on the terrain -// for (int i = 0; i < 20; ++i) -// { -// Entity* e = mSceneMgr->createEntity("ninja.mesh"); -// Real x = terrainPos.x + Math::RangeRandom(-2500, 2500); -// Real z = terrainPos.z + Math::RangeRandom(-2500, 2500); -// Real y = mTerrain->getHeightAtWorldPosition(Vector3(x, 0, z)); -// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(x, y, z))->attachObject(e); -// } -// */ -// +// /* +// // create a few entities on the terrain +// for (int i = 0; i < 20; ++i) +// { +// Entity* e = mSceneMgr->createEntity("ninja.mesh"); +// Real x = terrainPos.x + Math::RangeRandom(-2500, 2500); +// Real z = terrainPos.z + Math::RangeRandom(-2500, 2500); +// Real y = mTerrain->getHeightAtWorldPosition(Vector3(x, 0, z)); +// mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(x, y, z))->attachObject(e); +// } +// */ +// // // -// mCamera->setPosition(terrainPos + Vector3(-4000,300,4000)); -// mCamera->lookAt(terrainPos); -// mCamera->setNearClipDistance(5); -// mCamera->setFarClipDistance(50000); +// mCamera->setPosition(terrainPos + Vector3(-4000,300,4000)); +// mCamera->lookAt(terrainPos); +// mCamera->setNearClipDistance(5); +// mCamera->setFarClipDistance(50000); // -// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); +// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); // -// if (saveTerrain) -// { -// mTerrain->save(filename); -// } +// if (saveTerrain) +// { +// mTerrain->save(filename); +// } // -// //addTextureDebugOverlay(mTerrain->getCompositeMap()->getName(), 0); +// //addTextureDebugOverlay(mTerrain->getCompositeMap()->getName(), 0); // -// } +// } // -// void testTwoNewTerrains() -// { -// MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); -// MaterialManager::getSingleton().setDefaultAnisotropy(7); +// void testTwoNewTerrains() +// { +// MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC); +// MaterialManager::getSingleton().setDefaultAnisotropy(7); // -// LogManager::getSingleton().setLogDetail(LL_BOREME); +// LogManager::getSingleton().setLogDetail(LL_BOREME); // -// Vector3 lightdir(0.55, -0.3, 0.75); -// lightdir.normalise(); +// Vector3 lightdir(0.55, -0.3, 0.75); +// lightdir.normalise(); // // -// // Until material implemented -// TerrainGlobalOptions::setMaxPixelError(8); -// //TerrainGlobalOptions::setUseRayBoxDistanceCalculation(true); -// //TerrainGlobalOptions::getDefaultMaterialGenerator()->setDebugLevel(1); -// //TerrainGlobalOptions::setLightMapSize(256); -// TerrainGlobalOptions::setLightMapDirection(lightdir); +// // Until material implemented +// TerrainGlobalOptions::setMaxPixelError(8); +// //TerrainGlobalOptions::setUseRayBoxDistanceCalculation(true); +// //TerrainGlobalOptions::getDefaultMaterialGenerator()->setDebugLevel(1); +// //TerrainGlobalOptions::setLightMapSize(256); +// TerrainGlobalOptions::setLightMapDirection(lightdir); // -// Light* l = mSceneMgr->createLight("tstLight"); -// l->setType(Light::LT_DIRECTIONAL); -// l->setDirection(lightdir); -// l->setDiffuseColour(ColourValue::White); -// l->setSpecularColour(ColourValue(0.4, 0.4, 0.4)); +// Light* l = mSceneMgr->createLight("tstLight"); +// l->setType(Light::LT_DIRECTIONAL); +// l->setDirection(lightdir); +// l->setDiffuseColour(ColourValue::White); +// l->setSpecularColour(ColourValue(0.4, 0.4, 0.4)); // -// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); +// mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2)); // // // -// //mSceneMgr->showBoundingBoxes(true); -// Terrain* terrain1 = createTerrain(); -// Terrain* terrain2 = createTerrain(); +// //mSceneMgr->showBoundingBoxes(true); +// Terrain* terrain1 = createTerrain(); +// Terrain* terrain2 = createTerrain(); // -// for (int i = 0; i < terrain2->getSize()-1; i++) -// terrain2->setHeightAtPoint(0, i, terrain1->getHeightAtPoint(terrain1->getSize()-1, i)); -// terrain2->update(); +// for (int i = 0; i < terrain2->getSize()-1; i++) +// terrain2->setHeightAtPoint(0, i, terrain1->getHeightAtPoint(terrain1->getSize()-1, i)); +// terrain2->update(); // -// //addTextureDebugOverlay(TextureManager::getSingleton().getByName(mTerrain->getTerrainNormalMap()->getName()), 0); +// //addTextureDebugOverlay(TextureManager::getSingleton().getByName(mTerrain->getTerrainNormalMap()->getName()), 0); // -// //mWindow->getViewport(0)->setBackgroundColour(ColourValue::Blue); +// //mWindow->getViewport(0)->setBackgroundColour(ColourValue::Blue); // -// terrain2->setPosition(Vector3(8000,0,0)); +// terrain2->setPosition(Vector3(8000,0,0)); // -// mCamera->setPosition(Vector3(-4000,300,4000)); -// mCamera->lookAt(Vector3::ZERO); -// mCamera->setNearClipDistance(5); -// mCamera->setFarClipDistance(15000); +// mCamera->setPosition(Vector3(-4000,300,4000)); +// mCamera->lookAt(Vector3::ZERO); +// mCamera->setNearClipDistance(5); +// mCamera->setFarClipDistance(15000); // -// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); +// mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); // // -// } +// } // -// void createScene(void) +// void createScene(void) // { // -// //mSceneMgr->setDisplaySceneNodes(true); +// //mSceneMgr->setDisplaySceneNodes(true); // -// mCamera->setPosition(-0.19199729, 1.0310142, -41.884644); -// mCamera->setDirection(Vector3::NEGATIVE_UNIT_Z); -// mCamera->setNearClipDistance(5); -// mCamera->setFarClipDistance(5000); -// Vector3 worldPos(-3.2326765, 2.003727, -59.996029); +// mCamera->setPosition(-0.19199729, 1.0310142, -41.884644); +// mCamera->setDirection(Vector3::NEGATIVE_UNIT_Z); +// mCamera->setNearClipDistance(5); +// mCamera->setFarClipDistance(5000); +// Vector3 worldPos(-3.2326765, 2.003727, -59.996029); // -// Ogre::Vector3 pos = mCamera->getProjectionMatrix() * mCamera->getViewMatrix() * worldPos; -// -// // test image format identification -// DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("ASCII.dds", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// //DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("grassWalpha.tga", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// //DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("GreenSkin.jpg", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// //DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("ogreborder.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); -// String typ = Image::getFileExtFromMagic(stream); +// Ogre::Vector3 pos = mCamera->getProjectionMatrix() * mCamera->getViewMatrix() * worldPos; +// +// // test image format identification +// DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("ASCII.dds", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// //DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("grassWalpha.tga", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// //DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("GreenSkin.jpg", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// //DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource("ogreborder.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// String typ = Image::getFileExtFromMagic(stream); // -// std::cout << pos; +// std::cout << pos; // -// AnyNumeric anyInt1(43); -// AnyNumeric anyInt2(5); -// AnyNumeric anyInt3 = anyInt1 + anyInt2; +// AnyNumeric anyInt1(43); +// AnyNumeric anyInt2(5); +// AnyNumeric anyInt3 = anyInt1 + anyInt2; // -// bool tst = StringConverter::isNumber("3"); -// tst = StringConverter::isNumber("-0.3"); -// tst = StringConverter::isNumber(""); -// tst = StringConverter::isNumber(" "); -// tst = StringConverter::isNumber(" -0.3 "); -// tst = StringConverter::isNumber(" a-0.3 "); +// bool tst = StringConverter::isNumber("3"); +// tst = StringConverter::isNumber("-0.3"); +// tst = StringConverter::isNumber(""); +// tst = StringConverter::isNumber(" "); +// tst = StringConverter::isNumber(" -0.3 "); +// tst = StringConverter::isNumber(" a-0.3 "); // -// const StringVector& l = mCamera->getAnimableValueNames(); +// const StringVector& l = mCamera->getAnimableValueNames(); // -// std::cout << anyInt3; +// std::cout << anyInt3; // -// Any anyString(String("test")); +// Any anyString(String("test")); // -// LogManager::getSingleton().setLogDetail(LL_BOREME); +// LogManager::getSingleton().setLogDetail(LL_BOREME); // // -// Image img2; -// img2.load("apt-BLRD.hdr", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); +// Image img2; +// img2.load("apt-BLRD.hdr", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // // -// //testLiSPSM(); -// testBug(); -// //testSharedPtrBug(); +// //testLiSPSM(); +// testBug(); +// //testSharedPtrBug(); // // testMatrices(); // // //testBsp(); // // testAlpha(); // // testAnimation(); -// //testAnimationBlend(); +// //testAnimationBlend(); // // // testGpuPrograms(); // // testMultiViewports(); @@ -8452,171 +8452,171 @@ extern "C" _OgreSampleExport void dllStopPlugin() // // testSkeletalAnimation(); // // testOrtho(); // // testClearScene(); -// //testInfiniteAAB(); +// //testInfiniteAAB(); // // // testProjection(); // // testStencilShadows(SHADOWTYPE_STENCIL_ADDITIVE, true, true); // // testStencilShadows(SHADOWTYPE_STENCIL_MODULATIVE, false, true); // // testTextureShadows(SHADOWTYPE_TEXTURE_ADDITIVE, true); -// //testTextureShadows(SHADOWTYPE_TEXTURE_MODULATIVE, true); -// //testTextureShadowsIntegrated(); -// //testTextureShadowsIntegratedPSSM(); -// //testStencilShadowsMixedOpSubMeshes(false, true); -// //testTextureShadowsTransparentCaster(); -// //testTextureShadowsCustomCasterMat(SHADOWTYPE_TEXTURE_ADDITIVE, true); -// //testTextureShadowsCustomReceiverMat(SHADOWTYPE_TEXTURE_MODULATIVE, true); -// //testCompositorTextureShadows(SHADOWTYPE_TEXTURE_MODULATIVE); -// //testSplitPassesTooManyTexUnits(); +// //testTextureShadows(SHADOWTYPE_TEXTURE_MODULATIVE, true); +// //testTextureShadowsIntegrated(); +// //testTextureShadowsIntegratedPSSM(); +// //testStencilShadowsMixedOpSubMeshes(false, true); +// //testTextureShadowsTransparentCaster(); +// //testTextureShadowsCustomCasterMat(SHADOWTYPE_TEXTURE_ADDITIVE, true); +// //testTextureShadowsCustomReceiverMat(SHADOWTYPE_TEXTURE_MODULATIVE, true); +// //testCompositorTextureShadows(SHADOWTYPE_TEXTURE_MODULATIVE); +// //testSplitPassesTooManyTexUnits(); // // testOverlayZOrder(); -// //testReflectedBillboards(); -// //testBlendDiffuseColour(); +// //testReflectedBillboards(); +// //testBlendDiffuseColour(); // // // testRaySceneQuery(); -// //testNegativeScale(); -// //testMaterialSerializer(); +// //testNegativeScale(); +// //testMaterialSerializer(); // // testIntersectionSceneQuery(); // // // test2Spotlights(); -// //testDepthBias(); -// -// ////testMaterialSchemesListener(); -// //testManualLOD(); -// //testGeneratedLOD(); -// //testLotsAndLotsOfEntities(); -// //testSimpleMesh(); -// //test2Windows(); -// //testStaticGeometry(); -// //testStaticGeometryWithLOD(true); -// //testBillboardTextureCoords(); -// //testBillboardOrigins(); -// //testReloadResources(); -// //testTransparencyMipMaps(); -// //testRadixSort(); -// //testMorphAnimation(); -// //testPoseAnimation(); -// //testPoseAnimation2(); -// //testNormalMapMirroredUVs(); -// //testMRTCompositorScript(); -// //testSpotlightViewProj(true); -// //test16Textures(); -// //testProjectSphere(); -// //testLightScissoring(true); -// //testLightClipPlanes(false); -// //testManualIlluminationStage(SHADOWTYPE_STENCIL_ADDITIVE); -// //testTimeCreateDestroyObject(); -// //testManualBlend(); -// //testManualObjectNonIndexed(); -// //testManualObjectIndexed(); -// //testManualObjectNonIndexedUpdateSmaller(); -// //testManualObjectNonIndexedUpdateLarger(); -// //testManualObjectIndexedUpdateSmaller(); -// //testManualObjectIndexedUpdateLarger(); -// //testManualObject2D(); -// //testCustomProjectionMatrix(); -// //testPointSprites(); -// //testFallbackResourceGroup(); -// //testSuppressedShadows(SHADOWTYPE_TEXTURE_ADDITIVE); -// //testViewportNoShadows(SHADOWTYPE_TEXTURE_ADDITIVE); -// //testBillboardChain(); -// //testRibbonTrail(); -// //testSerialisedColour(); -// //testBillboardAccurateFacing(); -// //testMultiSceneManagersSimple(); -// //testMultiSceneManagersComplex(); -// //testManualBoneMovement(); -// //testMaterialSchemes(); -// //testMaterialSchemesListener(); -// //testMaterialSchemesWithLOD(); -// //testMaterialSchemesWithMismatchedLOD(); +// //testDepthBias(); +// +// ////testMaterialSchemesListener(); +// //testManualLOD(); +// //testGeneratedLOD(); +// //testLotsAndLotsOfEntities(); +// //testSimpleMesh(); +// //test2Windows(); +// //testStaticGeometry(); +// //testStaticGeometryWithLOD(true); +// //testBillboardTextureCoords(); +// //testBillboardOrigins(); +// //testReloadResources(); +// //testTransparencyMipMaps(); +// //testRadixSort(); +// //testMorphAnimation(); +// //testPoseAnimation(); +// //testPoseAnimation2(); +// //testNormalMapMirroredUVs(); +// //testMRTCompositorScript(); +// //testSpotlightViewProj(true); +// //test16Textures(); +// //testProjectSphere(); +// //testLightScissoring(true); +// //testLightClipPlanes(false); +// //testManualIlluminationStage(SHADOWTYPE_STENCIL_ADDITIVE); +// //testTimeCreateDestroyObject(); +// //testManualBlend(); +// //testManualObjectNonIndexed(); +// //testManualObjectIndexed(); +// //testManualObjectNonIndexedUpdateSmaller(); +// //testManualObjectNonIndexedUpdateLarger(); +// //testManualObjectIndexedUpdateSmaller(); +// //testManualObjectIndexedUpdateLarger(); +// //testManualObject2D(); +// //testCustomProjectionMatrix(); +// //testPointSprites(); +// //testFallbackResourceGroup(); +// //testSuppressedShadows(SHADOWTYPE_TEXTURE_ADDITIVE); +// //testViewportNoShadows(SHADOWTYPE_TEXTURE_ADDITIVE); +// //testBillboardChain(); +// //testRibbonTrail(); +// //testSerialisedColour(); +// //testBillboardAccurateFacing(); +// //testMultiSceneManagersSimple(); +// //testMultiSceneManagersComplex(); +// //testManualBoneMovement(); +// //testMaterialSchemes(); +// //testMaterialSchemesListener(); +// //testMaterialSchemesWithLOD(); +// //testMaterialSchemesWithMismatchedLOD(); // // testSkeletonAnimationOptimise(); // // testBuildTangentOnAnimatedMesh(); -// //testOverlayRelativeMode(); -// //testShadowLod(false, SHADOWTYPE_TEXTURE_MODULATIVE); -// -// //testCubeDDS(); -// //testDxt1(); -// //testDxt1FromMemory(); -// //testDxt3FromMemory(); -// //testDxt1Alpha(); -// //testDxt3(); -// //testDxt5(); -// //testFloat64DDS(); -// //testFloat128DDS(); -// //testFloat16DDS(); -// //testFloat32DDS(); -// //test4bppPVR(); -// //test4bppAlphaPVR(); -// //test2bppPVR(); -// //test2bppAlphaPVR(); -// //testMaterial(); -// //testExportPrecompiledAssemblerProgram(); -// -// //testVertexTexture(); -// //testGLSLTangent(); -// //testBackgroundLoadResourceGroup(); -// //testManualLoader(); -// //testMRT(); -// //testReinitialiseEntityAlteredMesh(); -// //testSRGBtexture(true); -// //testLightClipPlanesMoreLights(true); -// -// //testFarFromOrigin(); -// //testGeometryShaders(); -// //testAlphaToCoverage(); -// //testCompositorTechniqueSwitch(true); -// //testBlitSubTextures(); -// -// //testDepthShadowMap(); +// //testOverlayRelativeMode(); +// //testShadowLod(false, SHADOWTYPE_TEXTURE_MODULATIVE); +// +// //testCubeDDS(); +// //testDxt1(); +// //testDxt1FromMemory(); +// //testDxt3FromMemory(); +// //testDxt1Alpha(); +// //testDxt3(); +// //testDxt5(); +// //testFloat64DDS(); +// //testFloat128DDS(); +// //testFloat16DDS(); +// //testFloat32DDS(); +// //test4bppPVR(); +// //test4bppAlphaPVR(); +// //test2bppPVR(); +// //test2bppAlphaPVR(); +// //testMaterial(); +// //testExportPrecompiledAssemblerProgram(); +// +// //testVertexTexture(); +// //testGLSLTangent(); +// //testBackgroundLoadResourceGroup(); +// //testManualLoader(); +// //testMRT(); +// //testReinitialiseEntityAlteredMesh(); +// //testSRGBtexture(true); +// //testLightClipPlanesMoreLights(true); +// +// //testFarFromOrigin(); +// //testGeometryShaders(); +// //testAlphaToCoverage(); +// //testCompositorTechniqueSwitch(true); +// //testBlitSubTextures(); +// +// //testDepthShadowMap(); // // //testLod(); -// //testSharedGpuParameters(); -// //testNewTerrain(false); -// //testNewTerrain(true); -// //testStringTokenising(); -// //testTwoNewTerrains(); -// //testImageCombine(); -// //testNewTerrain(true, false, "flatterrain.dat"); -// //testImageCombine(); +// //testSharedGpuParameters(); +// //testNewTerrain(false); +// //testNewTerrain(true); +// //testStringTokenising(); +// //testTwoNewTerrains(); +// //testImageCombine(); +// //testNewTerrain(true, false, "flatterrain.dat"); +// //testImageCombine(); // -// Image combined; -// /* -// combined.loadTwoImagesAsRGBA("dirt_grayrocky_DIFFUSE.png", "dirt_grayrocky_SPECULAR.png", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); +// Image combined; +// /* +// combined.loadTwoImagesAsRGBA("dirt_grayrocky_DIFFUSE.png", "dirt_grayrocky_SPECULAR.png", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); // -// combined.save("dirt_grayrocky_diffusespecular.png"); +// combined.save("dirt_grayrocky_diffusespecular.png"); // -// combined.loadTwoImagesAsRGBA("dirt_grayrocky_NORMAL.png", "dirt_grayrocky_DISP.png", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); +// combined.loadTwoImagesAsRGBA("dirt_grayrocky_NORMAL.png", "dirt_grayrocky_DISP.png", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); // -// combined.save("dirt_grayrocky_normalheight.png"); +// combined.save("dirt_grayrocky_normalheight.png"); // -// combined.loadTwoImagesAsRGBA("grass_green-01_DIFFUSE.png", "grass_green-01_SPECULAR.png", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); +// combined.loadTwoImagesAsRGBA("grass_green-01_DIFFUSE.png", "grass_green-01_SPECULAR.png", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); // -// combined.save("grass_green-01_diffusespecular.png"); +// combined.save("grass_green-01_diffusespecular.png"); // -// combined.loadTwoImagesAsRGBA("grass_green-01_NORMAL.png", "grass_green-01_DISP.png", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); +// combined.loadTwoImagesAsRGBA("grass_green-01_NORMAL.png", "grass_green-01_DISP.png", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); // -// combined.save("grass_green-01_normalheight.png"); -// -// combined.loadTwoImagesAsRGBA("growth_weirdfungus-03_DIFFUSE.png", "growth_weirdfungus-03_SPECULAR.png", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); +// combined.save("grass_green-01_normalheight.png"); +// +// combined.loadTwoImagesAsRGBA("growth_weirdfungus-03_DIFFUSE.png", "growth_weirdfungus-03_SPECULAR.png", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); // -// combined.save("growth_weirdfungus-03_diffusespecular.png"); +// combined.save("growth_weirdfungus-03_diffusespecular.png"); // -// combined.loadTwoImagesAsRGBA("growth_weirdfungus-03_NORMAL.png", "growth_weirdfungus-03_DISP.png", -// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); +// combined.loadTwoImagesAsRGBA("growth_weirdfungus-03_NORMAL.png", "growth_weirdfungus-03_DISP.png", +// ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, PF_BYTE_RGBA); // -// combined.save("growth_weirdfungus-03_normalheight.png"); -// */ +// combined.save("growth_weirdfungus-03_normalheight.png"); +// */ // } // // Create new frame listener // void createFrameListener(void) // { // mFrameListener= new PlayPenListener(mSceneMgr, mWindow, mCamera); // mFrameListener->showDebugOverlay(true); -// mRoot->addFrameListener(mFrameListener); +// mRoot->addFrameListener(mFrameListener); // //mRoot->addFrameListener(fl); // // } @@ -8631,53 +8631,53 @@ extern "C" _OgreSampleExport void dllStopPlugin() // mRoot->startRendering(); // } // -// bool setup() -// { -// String pluginsPath = mResourcePath + "plugins.cfg"; -// // only use plugins.cfg if not static +// bool setup() +// { +// String pluginsPath = mResourcePath + "plugins.cfg"; +// // only use plugins.cfg if not static //#ifdef OGRE_STATIC_LIB // #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS // Ogre::String workDir = Ogre::BLANKSTRING; // workDir = Ogre::macBundlePath() + "/"; // -// mRoot = new Root(BLANKSTRING, +// mRoot = new Root(BLANKSTRING, // workDir + "ogre.cfg", mResourcePath + "Ogre.log"); // #else -// mRoot = new Root(BLANKSTRING, +// mRoot = new Root(BLANKSTRING, // mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log"); // #endif // -// mStaticPluginLoader.load(); +// mStaticPluginLoader.load(); //#else -// mRoot = new Root(pluginsPath, -// mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log"); +// mRoot = new Root(pluginsPath, +// mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log"); //#endif -// LogManager::getSingleton().setLogDetail(LL_BOREME); -// setupResources(); +// LogManager::getSingleton().setLogDetail(LL_BOREME); +// setupResources(); // -// bool carryOn = configure(); -// if (!carryOn) return false; +// bool carryOn = configure(); +// if (!carryOn) return false; // -// chooseSceneManager(); -// createCamera(); -// createViewports(); +// chooseSceneManager(); +// createCamera(); +// createViewports(); // -// // Set default mipmap level (NB some APIs ignore this) -// TextureManager::getSingleton().setDefaultNumMipmaps(5); +// // Set default mipmap level (NB some APIs ignore this) +// TextureManager::getSingleton().setDefaultNumMipmaps(5); // -// // Create any resource listeners (for loading screens) -// createResourceListener(); -// // Load resources -// loadResources(); +// // Create any resource listeners (for loading screens) +// createResourceListener(); +// // Load resources +// loadResources(); // -// // Create the scene -// createScene(); +// // Create the scene +// createScene(); // -// createFrameListener(); +// createFrameListener(); // -// return true; +// return true; // -// } +// } // // // @@ -8692,179 +8692,179 @@ extern "C" _OgreSampleExport void dllStopPlugin() //class MemoryTestFrameListener : public FrameListener //{ //protected: -// Real time; -// OIS::Keyboard* mKeyboard; +// Real time; +// OIS::Keyboard* mKeyboard; //public: -// MemoryTestFrameListener(RenderWindow * win) -// { -// time = 0; -// OIS::ParamList pl; -// size_t windowHnd = 0; -// std::ostringstream windowHndStr; -// -// win->getCustomAttribute("WINDOW", &windowHnd); -// windowHndStr << windowHnd; -// pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); -// -// OIS::InputManager &im = *OIS::InputManager::createInputSystem( pl ); -// -// //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse) -// mKeyboard = static_cast(im.createInputObject( OIS::OISKeyboard, false )); -// } -// virtual ~MemoryTestFrameListener() -// { -// time = 0; -// } -// -// bool frameStarted(const FrameEvent& evt) -// { -// if( mKeyboard->isKeyDown( OIS::KC_ESCAPE) ) -// { -// gReload = false; -// return false; -// } -// -// time += evt.timeSinceLastFrame; -// if(time>5) -// { -// LogManager::getSingleton().logMessage("Reloading scene after 5 seconds"); -// gReload = true; -// time=0; -// return false; -// } -// else -// { -// gReload = false; -// return true; -// } -// } -// -// void keyClicked(OIS::KeyEvent* e) {}; -// void keyPressed(OIS::KeyEvent* e) {}; -// void keyReleased(OIS::KeyEvent* e) {}; -// void keyFocusIn(OIS::KeyEvent* e) {} -// void keyFocusOut(OIS::KeyEvent* e) {} +// MemoryTestFrameListener(RenderWindow * win) +// { +// time = 0; +// OIS::ParamList pl; +// size_t windowHnd = 0; +// std::ostringstream windowHndStr; +// +// win->getCustomAttribute("WINDOW", &windowHnd); +// windowHndStr << windowHnd; +// pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); +// +// OIS::InputManager &im = *OIS::InputManager::createInputSystem( pl ); +// +// //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse) +// mKeyboard = static_cast(im.createInputObject( OIS::OISKeyboard, false )); +// } +// virtual ~MemoryTestFrameListener() +// { +// time = 0; +// } +// +// bool frameStarted(const FrameEvent& evt) +// { +// if( mKeyboard->isKeyDown( OIS::KC_ESCAPE) ) +// { +// gReload = false; +// return false; +// } +// +// time += evt.timeSinceLastFrame; +// if(time>5) +// { +// LogManager::getSingleton().logMessage("Reloading scene after 5 seconds"); +// gReload = true; +// time=0; +// return false; +// } +// else +// { +// gReload = false; +// return true; +// } +// } +// +// void keyClicked(OIS::KeyEvent* e) {}; +// void keyPressed(OIS::KeyEvent* e) {}; +// void keyReleased(OIS::KeyEvent* e) {}; +// void keyFocusIn(OIS::KeyEvent* e) {} +// void keyFocusOut(OIS::KeyEvent* e) {} //}; // ///** Application class */ //class MemoryTestApplication : public ExampleApplication //{ //protected: -// MemoryTestFrameListener * mTestFrameListener; +// MemoryTestFrameListener * mTestFrameListener; //public: // -// void go(void) -// { -// mRoot = 0; -// if (!setup()) -// return; -// -// mRoot->startRendering(); -// -// while(gReload) -// { -// // clean up -// destroyScene(); -// destroyResources(); -// if (!setup()) -// return; -// mRoot->startRendering(); -// } -// // clean up -// destroyScene(); -// } -// -// bool setup(void) -// { -// if(!gReload) -// { -// String pluginsPath = mResourcePath + "plugins.cfg"; -// mRoot = new Root(pluginsPath, -// mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log"); -// } -// -// setupResources(); -// -// if(!gReload) -// { -// -// bool carryOn = configure(); -// if (!carryOn) -// return false; -// -// chooseSceneManager(); -// createCamera(); -// createViewports(); -// -// // Set default mipmap level (NB some APIs ignore this) -// TextureManager::getSingleton().setDefaultNumMipmaps(5); -// -// // Create any resource listeners (for loading screens) -// createResourceListener(); -// -// createFrameListener(); -// } -// // Load resources -// loadResources(); -// -// // Create the scene -// createScene(); -// -// return true; -// -// } -// -// /// Method which will define the source of resources (other than current folder) -// virtual void setupResources(void) -// { -// // Custom setup -// ResourceGroupManager::getSingleton().createResourceGroup("CustomResourceGroup"); -// ResourceGroupManager::getSingleton().addResourceLocation( -// "../../../media/ogrehead.zip", "Zip", "CustomResourceGroup"); -// } -// void loadResources(void) -// { -// // Initialise, parse scripts etc -// ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); -// } -// void destroyResources() -// { -// LogManager::getSingleton().logMessage("Destroying resources"); -// ResourceGroupManager::getSingleton().removeResourceLocation( -// "../../../media/ogrehead.zip"); -// ResourceGroupManager::getSingleton().destroyResourceGroup("CustomResourceGroup"); -// } -// -// void createScene(void) -// { -// // Set a very low level of ambient lighting -// mSceneMgr->setAmbientLight(ColourValue(0.1, 0.1, 0.1)); -// -// // Load ogre head -// MeshManager::getSingleton().load("ogrehead.mesh","CustomResourceGroup"); -// Entity* head = mSceneMgr->createEntity("head", "ogrehead.mesh"); -// -// // Attach the head to the scene -// mSceneMgr->getRootSceneNode()->attachObject(head); -// -// } -// -// void createFrameListener(void) -// { -// // This is where we instantiate our own frame listener -// mTestFrameListener= new MemoryTestFrameListener(mWindow); -// mRoot->addFrameListener(mTestFrameListener); -// /*if(!gReload) -// { -// ExampleApplication::createFrameListener(); -// }*/ -// } -// -// void destroyScene(void) -// { -// LogManager::getSingleton().logMessage("Clearing scene"); -// mSceneMgr->clearScene(); -// } +// void go(void) +// { +// mRoot = 0; +// if (!setup()) +// return; +// +// mRoot->startRendering(); +// +// while(gReload) +// { +// // clean up +// destroyScene(); +// destroyResources(); +// if (!setup()) +// return; +// mRoot->startRendering(); +// } +// // clean up +// destroyScene(); +// } +// +// bool setup(void) +// { +// if(!gReload) +// { +// String pluginsPath = mResourcePath + "plugins.cfg"; +// mRoot = new Root(pluginsPath, +// mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log"); +// } +// +// setupResources(); +// +// if(!gReload) +// { +// +// bool carryOn = configure(); +// if (!carryOn) +// return false; +// +// chooseSceneManager(); +// createCamera(); +// createViewports(); +// +// // Set default mipmap level (NB some APIs ignore this) +// TextureManager::getSingleton().setDefaultNumMipmaps(5); +// +// // Create any resource listeners (for loading screens) +// createResourceListener(); +// +// createFrameListener(); +// } +// // Load resources +// loadResources(); +// +// // Create the scene +// createScene(); +// +// return true; +// +// } +// +// /// Method which will define the source of resources (other than current folder) +// virtual void setupResources(void) +// { +// // Custom setup +// ResourceGroupManager::getSingleton().createResourceGroup("CustomResourceGroup"); +// ResourceGroupManager::getSingleton().addResourceLocation( +// "../../../media/ogrehead.zip", "Zip", "CustomResourceGroup"); +// } +// void loadResources(void) +// { +// // Initialise, parse scripts etc +// ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); +// } +// void destroyResources() +// { +// LogManager::getSingleton().logMessage("Destroying resources"); +// ResourceGroupManager::getSingleton().removeResourceLocation( +// "../../../media/ogrehead.zip"); +// ResourceGroupManager::getSingleton().destroyResourceGroup("CustomResourceGroup"); +// } +// +// void createScene(void) +// { +// // Set a very low level of ambient lighting +// mSceneMgr->setAmbientLight(ColourValue(0.1, 0.1, 0.1)); +// +// // Load ogre head +// MeshManager::getSingleton().load("ogrehead.mesh","CustomResourceGroup"); +// Entity* head = mSceneMgr->createEntity("head", "ogrehead.mesh"); +// +// // Attach the head to the scene +// mSceneMgr->getRootSceneNode()->attachObject(head); +// +// } +// +// void createFrameListener(void) +// { +// // This is where we instantiate our own frame listener +// mTestFrameListener= new MemoryTestFrameListener(mWindow); +// mRoot->addFrameListener(mTestFrameListener); +// /*if(!gReload) +// { +// ExampleApplication::createFrameListener(); +// }*/ +// } +// +// void destroyScene(void) +// { +// LogManager::getSingleton().logMessage("Clearing scene"); +// mSceneMgr->clearScene(); +// } //}; // // @@ -8887,15 +8887,15 @@ extern "C" _OgreSampleExport void dllStopPlugin() // [pool release]; // return retVal; //#else -// //EmbeddedMain(hInst, 0, strCmdLine, 0); +// //EmbeddedMain(hInst, 0, strCmdLine, 0); // -// // Create application object +// // Create application object // PlayPenApplication app; -// //MemoryTestApplication app; +// //MemoryTestApplication app; // // try { // app.go(); -// } catch( Ogre::Exception& e ) { +// } catch( Ogre::Exception& e ) { //#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 // MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL); //#else diff --git a/Tests/PlayPen/src/PlayPenSamples.cpp b/Tests/PlayPen/src/PlayPenSamples.cpp index 5a8721bc62f..7fb11ee14bd 100644 --- a/Tests/PlayPen/src/PlayPenSamples.cpp +++ b/Tests/PlayPen/src/PlayPenSamples.cpp @@ -34,120 +34,120 @@ THE SOFTWARE. //--------------------------------------------------------------------- PlayPen_testManualBlend::PlayPen_testManualBlend() { - mInfo["Title"] = "PlayPen: Manual Blend"; - mInfo["Description"] = "Manual blending"; + mInfo["Title"] = "PlayPen: Manual Blend"; + mInfo["Description"] = "Manual blending"; } void PlayPen_testManualBlend::setupContent() { - // create material - MaterialPtr mat = MaterialManager::getSingleton().create("TestMat", - TRANSIENT_RESOURCE_GROUP).staticCast(); - Pass * p = mat->getTechnique(0)->getPass(0); - p->setLightingEnabled(false); - p->createTextureUnitState("Dirt.jpg"); - TextureUnitState* t = p->createTextureUnitState("ogrelogo.png"); - t->setColourOperationEx(LBX_BLEND_MANUAL, LBS_TEXTURE, LBS_CURRENT, - ColourValue::White, ColourValue::White, 0.75); - - Entity *planeEnt = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(planeEnt); - planeEnt->setMaterialName("TestMat"); - - mCamera->setPosition(0,0,600); - mCamera->lookAt(Vector3::ZERO); + // create material + MaterialPtr mat = MaterialManager::getSingleton().create("TestMat", + TRANSIENT_RESOURCE_GROUP).staticCast(); + Pass * p = mat->getTechnique(0)->getPass(0); + p->setLightingEnabled(false); + p->createTextureUnitState("Dirt.jpg"); + TextureUnitState* t = p->createTextureUnitState("ogrelogo.png"); + t->setColourOperationEx(LBX_BLEND_MANUAL, LBS_TEXTURE, LBS_CURRENT, + ColourValue::White, ColourValue::White, 0.75); + + Entity *planeEnt = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(planeEnt); + planeEnt->setMaterialName("TestMat"); + + mCamera->setPosition(0,0,600); + mCamera->lookAt(Vector3::ZERO); } //--------------------------------------------------------------------- PlayPen_testProjectSphere::PlayPen_testProjectSphere() { - mInfo["Title"] = "PlayPen: Project Sphere"; - mInfo["Description"] = "Projecting a sphere's bounds onto the camera"; + mInfo["Title"] = "PlayPen: Project Sphere"; + mInfo["Description"] = "Projecting a sphere's bounds onto the camera"; } void PlayPen_testProjectSphere::setupContent() { - mSceneMgr->setAmbientLight(ColourValue::White); - - - Plane plane; - plane.normal = Vector3::UNIT_Y; - plane.d = 0; - MeshManager::getSingleton().createPlane("Myplane", - TRANSIENT_RESOURCE_GROUP, plane, - 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); - Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); - pPlaneEnt->setMaterialName("Examples/GrassFloor"); - pPlaneEnt->setCastShadows(false); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); - - mProjectionSphere = new Sphere(Vector3(0, 2000, 0), 1500.0); - - ManualObject* debugSphere = mSceneMgr->createManualObject("debugSphere"); - debugSphere->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); - for (int i = 0; i <= 20; ++i) - { - Vector3 basePos(mProjectionSphere->getRadius(), 0, 0); - Quaternion quat; - quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y); - basePos = quat * basePos; - debugSphere->position(basePos); - } - for (int i = 0; i <= 20; ++i) - { - Vector3 basePos(mProjectionSphere->getRadius(), 0, 0); - Quaternion quat; - quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Z); - basePos = quat * basePos; - debugSphere->position(basePos); - } - debugSphere->end(); - - mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,2000,0))->attachObject(debugSphere); - - MaterialPtr mat = MaterialManager::getSingleton().create("scissormat", - TRANSIENT_RESOURCE_GROUP).staticCast(); - Pass* p = mat->getTechnique(0)->getPass(0); - p->setDepthWriteEnabled(false); - p->setSceneBlending(SBT_TRANSPARENT_ALPHA); - TextureUnitState* t = p->createTextureUnitState(); - t->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, - ColourValue::Red); - t->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f); - - - mScissorRect = mSceneMgr->createManualObject("mScissorRect"); - mScissorRect->setUseIdentityProjection(true); - mScissorRect->setUseIdentityView(true); - AxisAlignedBox aabb; - aabb.setInfinite(); - mScissorRect->setBoundingBox(aabb); - mScissorRect->begin(mat->getName()); - mScissorRect->position(Vector3::ZERO); - mScissorRect->position(Vector3::ZERO); - mScissorRect->position(Vector3::ZERO); - mScissorRect->quad(0, 1, 2, 3); - mScissorRect->end(); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(mScissorRect); - - mCamera->setPosition(0,3000,5000); - mCamera->lookAt(mProjectionSphere->getCenter()); + mSceneMgr->setAmbientLight(ColourValue::White); + + + Plane plane; + plane.normal = Vector3::UNIT_Y; + plane.d = 0; + MeshManager::getSingleton().createPlane("Myplane", + TRANSIENT_RESOURCE_GROUP, plane, + 4500,4500,10,10,true,1,5,5,Vector3::UNIT_Z); + Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); + pPlaneEnt->setMaterialName("Examples/GrassFloor"); + pPlaneEnt->setCastShadows(false); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); + + mProjectionSphere = new Sphere(Vector3(0, 2000, 0), 1500.0); + + ManualObject* debugSphere = mSceneMgr->createManualObject("debugSphere"); + debugSphere->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP); + for (int i = 0; i <= 20; ++i) + { + Vector3 basePos(mProjectionSphere->getRadius(), 0, 0); + Quaternion quat; + quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Y); + basePos = quat * basePos; + debugSphere->position(basePos); + } + for (int i = 0; i <= 20; ++i) + { + Vector3 basePos(mProjectionSphere->getRadius(), 0, 0); + Quaternion quat; + quat.FromAngleAxis(Radian(((float)i/(float)20)*Math::TWO_PI), Vector3::UNIT_Z); + basePos = quat * basePos; + debugSphere->position(basePos); + } + debugSphere->end(); + + mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,2000,0))->attachObject(debugSphere); + + MaterialPtr mat = MaterialManager::getSingleton().create("scissormat", + TRANSIENT_RESOURCE_GROUP).staticCast(); + Pass* p = mat->getTechnique(0)->getPass(0); + p->setDepthWriteEnabled(false); + p->setSceneBlending(SBT_TRANSPARENT_ALPHA); + TextureUnitState* t = p->createTextureUnitState(); + t->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, + ColourValue::Red); + t->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f); + + + mScissorRect = mSceneMgr->createManualObject("mScissorRect"); + mScissorRect->setUseIdentityProjection(true); + mScissorRect->setUseIdentityView(true); + AxisAlignedBox aabb; + aabb.setInfinite(); + mScissorRect->setBoundingBox(aabb); + mScissorRect->begin(mat->getName()); + mScissorRect->position(Vector3::ZERO); + mScissorRect->position(Vector3::ZERO); + mScissorRect->position(Vector3::ZERO); + mScissorRect->quad(0, 1, 2, 3); + mScissorRect->end(); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(mScissorRect); + + mCamera->setPosition(0,3000,5000); + mCamera->lookAt(mProjectionSphere->getCenter()); } bool PlayPen_testProjectSphere::frameStarted(const Ogre::FrameEvent& evt) { - Real left, top, right, bottom; - mCamera->projectSphere(*mProjectionSphere, &left, &top, &right, &bottom); + Real left, top, right, bottom; + mCamera->projectSphere(*mProjectionSphere, &left, &top, &right, &bottom); - mScissorRect->beginUpdate(0); - mScissorRect->position(left, top, 0); - mScissorRect->position(left, bottom, 0); - mScissorRect->position(right, bottom, 0); - mScissorRect->position(right, top, 0); - mScissorRect->quad(0,1,2,3); - mScissorRect->end(); + mScissorRect->beginUpdate(0); + mScissorRect->position(left, top, 0); + mScissorRect->position(left, bottom, 0); + mScissorRect->position(right, bottom, 0); + mScissorRect->position(right, top, 0); + mScissorRect->quad(0,1,2,3); + mScissorRect->end(); - return PlayPenBase::frameStarted(evt); + return PlayPenBase::frameStarted(evt); } @@ -157,744 +157,744 @@ PlayPen_testCameraSetDirection::PlayPen_testCameraSetDirection() , mUseFixedYaw(true) , mFocus(100,200,-300) { - mInfo["Title"] = "PlayPen: Camera Set Direction"; - mInfo["Description"] = "Testing various settings for Camera::setDirection"; + mInfo["Title"] = "PlayPen: Camera Set Direction"; + mInfo["Description"] = "Testing various settings for Camera::setDirection"; } void PlayPen_testCameraSetDirection::setupContent() { - mSceneMgr->setAmbientLight(ColourValue::White); + mSceneMgr->setAmbientLight(ColourValue::White); - Entity* e = mSceneMgr->createEntity("1", "knot.mesh"); - mSceneMgr->getRootSceneNode()->createChildSceneNode(mFocus)->attachObject(e); + Entity* e = mSceneMgr->createEntity("1", "knot.mesh"); + mSceneMgr->getRootSceneNode()->createChildSceneNode(mFocus)->attachObject(e); - mCamera->setPosition(200,1000,1000); - mCamera->lookAt(mFocus); + mCamera->setPosition(200,1000,1000); + mCamera->lookAt(mFocus); - mTrayMgr->createButton(OgreBites::TL_BOTTOM, "Look At", "Look At"); - mTrayMgr->createCheckBox(OgreBites::TL_BOTTOM, "tglParent", "Use Parent Node"); - OgreBites::CheckBox* chk = mTrayMgr->createCheckBox(OgreBites::TL_BOTTOM, "tglFixedYaw", "Use Fixed Yaw"); - chk->setChecked(true, false); - mTrayMgr->showCursor(); - setDragLook(true); + mTrayMgr->createButton(OgreBites::TL_BOTTOM, "Look At", "Look At"); + mTrayMgr->createCheckBox(OgreBites::TL_BOTTOM, "tglParent", "Use Parent Node"); + OgreBites::CheckBox* chk = mTrayMgr->createCheckBox(OgreBites::TL_BOTTOM, "tglFixedYaw", "Use Fixed Yaw"); + chk->setChecked(true, false); + mTrayMgr->showCursor(); + setDragLook(true); - mParentNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(1000, 2000, -1000)); + mParentNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(1000, 2000, -1000)); } void PlayPen_testCameraSetDirection::buttonHit(OgreBites::Button* button) { - mCamera->lookAt(mFocus); + mCamera->lookAt(mFocus); } void PlayPen_testCameraSetDirection::checkBoxToggled(OgreBites::CheckBox* box) { - if (box->getName() == "tglParent") - { - mUseParentNode = !mUseParentNode; - - if (mUseParentNode) - mParentNode->attachObject(mCamera); - else - mParentNode->detachAllObjects(); - } - else if (box->getName() == "tglFixedYaw") - { - mUseFixedYaw = !mUseFixedYaw; - if (mUseFixedYaw) - mCamera->setFixedYawAxis(true); - else - mCamera->setFixedYawAxis(false); - - } + if (box->getName() == "tglParent") + { + mUseParentNode = !mUseParentNode; + + if (mUseParentNode) + mParentNode->attachObject(mCamera); + else + mParentNode->detachAllObjects(); + } + else if (box->getName() == "tglFixedYaw") + { + mUseFixedYaw = !mUseFixedYaw; + if (mUseFixedYaw) + mCamera->setFixedYawAxis(true); + else + mCamera->setFixedYawAxis(false); + + } } #ifdef OGRE_BUILD_COMPONENT_MESHLODGENERATOR //--------------------------------------------------------------------- PlayPen_testManualLOD::PlayPen_testManualLOD() { - mInfo["Title"] = "PlayPen: Test Manual LOD"; - mInfo["Description"] = "Testing meshes with manual LODs assigned"; + mInfo["Title"] = "PlayPen: Test Manual LOD"; + mInfo["Description"] = "Testing meshes with manual LODs assigned"; } //--------------------------------------------------------------------- String PlayPen_testManualLOD::getLODMesh() { - MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - LodConfig lodConfig(msh1); - lodConfig.createManualLodLevel(5, "razor.mesh"); - lodConfig.createManualLodLevel(10, "sphere.mesh"); - MeshLodGenerator().generateLodLevels(lodConfig); - - return msh1->getName(); + MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + LodConfig lodConfig(msh1); + lodConfig.createManualLodLevel(5, "razor.mesh"); + lodConfig.createManualLodLevel(10, "sphere.mesh"); + MeshLodGenerator().generateLodLevels(lodConfig); + + return msh1->getName(); } //--------------------------------------------------------------------- void PlayPen_testManualLOD::setupContent() { - String meshName = getLODMesh(); + String meshName = getLODMesh(); - Entity *ent; - for (int i = 0; i < 5; ++i) - { - ent = mSceneMgr->createEntity("robot" + StringConverter::toString(i), meshName); - // Add entity to the scene node - mSceneMgr->getRootSceneNode()->createChildSceneNode( - Vector3(0,0,(i*50)-(5*50/2)))->attachObject(ent); - } - AnimationState* anim = ent->getAnimationState("Walk"); - anim->setEnabled(true); - mAnimStateList.push_back(anim); + Entity *ent; + for (int i = 0; i < 5; ++i) + { + ent = mSceneMgr->createEntity("robot" + StringConverter::toString(i), meshName); + // Add entity to the scene node + mSceneMgr->getRootSceneNode()->createChildSceneNode( + Vector3(0,0,(i*50)-(5*50/2)))->attachObject(ent); + } + AnimationState* anim = ent->getAnimationState("Walk"); + anim->setEnabled(true); + mAnimStateList.push_back(anim); - // Give it a little ambience with lights - Light* l; - l = mSceneMgr->createLight("BlueLight"); - l->setPosition(-200,-80,-100); - l->setDiffuseColour(0.5, 0.5, 1.0); + // Give it a little ambience with lights + Light* l; + l = mSceneMgr->createLight("BlueLight"); + l->setPosition(-200,-80,-100); + l->setDiffuseColour(0.5, 0.5, 1.0); - l = mSceneMgr->createLight("GreenLight"); - l->setPosition(0,0,-100); - l->setDiffuseColour(0.5, 1.0, 0.5); + l = mSceneMgr->createLight("GreenLight"); + l->setPosition(0,0,-100); + l->setDiffuseColour(0.5, 1.0, 0.5); - // Position the camera - mCamera->setPosition(100,50,100); - mCamera->lookAt(-50,50,0); + // Position the camera + mCamera->setPosition(100,50,100); + mCamera->lookAt(-50,50,0); - mSceneMgr->setAmbientLight(ColourValue::White); + mSceneMgr->setAmbientLight(ColourValue::White); } //--------------------------------------------------------------------- PlayPen_testManualLODFromFile::PlayPen_testManualLODFromFile() { - mInfo["Title"] = "PlayPen: Test Manual LOD (file)"; - mInfo["Description"] = "Testing meshes with manual LODs assigned, loaded from a file"; + mInfo["Title"] = "PlayPen: Test Manual LOD (file)"; + mInfo["Description"] = "Testing meshes with manual LODs assigned, loaded from a file"; } //--------------------------------------------------------------------- String PlayPen_testManualLODFromFile::getLODMesh() { - MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - LodConfig lodConfig(msh1); - lodConfig.createManualLodLevel(5, "razor.mesh"); - lodConfig.createManualLodLevel(10, "sphere.mesh"); - MeshLodGenerator().generateLodLevels(lodConfig); - - // this time, we save this data to a file and re-load it - - MeshSerializer ser; - const ResourceGroupManager::LocationList& ll = - ResourceGroupManager::getSingleton().getResourceLocationList(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - String prefix; - for (ResourceGroupManager::LocationList::const_iterator i = ll.begin(); i != ll.end(); ++i) - { - if (StringUtil::endsWith((*i)->archive->getName(), "media")) - { - prefix = (*i)->archive->getName(); - } - } - ser.exportMesh(msh1.get(), prefix + "/testlod.mesh"); - - MeshManager::getSingleton().removeAll(); - return "testlod.mesh"; + MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + LodConfig lodConfig(msh1); + lodConfig.createManualLodLevel(5, "razor.mesh"); + lodConfig.createManualLodLevel(10, "sphere.mesh"); + MeshLodGenerator().generateLodLevels(lodConfig); + + // this time, we save this data to a file and re-load it + + MeshSerializer ser; + const ResourceGroupManager::LocationList& ll = + ResourceGroupManager::getSingleton().getResourceLocationList(ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + String prefix; + for (ResourceGroupManager::LocationList::const_iterator i = ll.begin(); i != ll.end(); ++i) + { + if (StringUtil::endsWith((*i)->archive->getName(), "media")) + { + prefix = (*i)->archive->getName(); + } + } + ser.exportMesh(msh1.get(), prefix + "/testlod.mesh"); + + MeshManager::getSingleton().removeAll(); + return "testlod.mesh"; } #endif //--------------------------------------------------------------------- PlayPen_testFullScreenSwitch::PlayPen_testFullScreenSwitch() { - mInfo["Title"] = "PlayPen: Test full screen"; - mInfo["Description"] = "Testing switching full screen modes without re-initialisation"; + mInfo["Title"] = "PlayPen: Test full screen"; + mInfo["Description"] = "Testing switching full screen modes without re-initialisation"; } //--------------------------------------------------------------------- void PlayPen_testFullScreenSwitch::setupContent() { - m640x480w = mTrayMgr->createButton(TL_CENTER, "m640x480w", "640 x 480 (windowed)", 300); - m640x480fs = mTrayMgr->createButton(TL_CENTER, "m640x480fs", "640 x 480 (fullscreen)", 300); - m800x600w = mTrayMgr->createButton(TL_CENTER, "m800x600w", "800 x 600 (windowed)", 300); - m800x600fs = mTrayMgr->createButton(TL_CENTER, "m800x600fs", "800 x 600 (fullscreen)", 300); - m1024x768w = mTrayMgr->createButton(TL_CENTER, "m1024x768w", "1024 x 768 (windowed)", 300); - m1024x768fs = mTrayMgr->createButton(TL_CENTER, "m1024x768fs", "1024 x 768 (fullscreen)", 300); + m640x480w = mTrayMgr->createButton(TL_CENTER, "m640x480w", "640 x 480 (windowed)", 300); + m640x480fs = mTrayMgr->createButton(TL_CENTER, "m640x480fs", "640 x 480 (fullscreen)", 300); + m800x600w = mTrayMgr->createButton(TL_CENTER, "m800x600w", "800 x 600 (windowed)", 300); + m800x600fs = mTrayMgr->createButton(TL_CENTER, "m800x600fs", "800 x 600 (fullscreen)", 300); + m1024x768w = mTrayMgr->createButton(TL_CENTER, "m1024x768w", "1024 x 768 (windowed)", 300); + m1024x768fs = mTrayMgr->createButton(TL_CENTER, "m1024x768fs", "1024 x 768 (fullscreen)", 300); - mTrayMgr->showCursor(); + mTrayMgr->showCursor(); } //--------------------------------------------------------------------- void PlayPen_testFullScreenSwitch::buttonHit(OgreBites::Button* button) { - if (button == m640x480w) - mWindow->setFullscreen(false, 640, 480); - else if (button == m640x480fs) - mWindow->setFullscreen(true, 640, 480); - else if (button == m800x600w) - mWindow->setFullscreen(false, 800, 600); - else if (button == m800x600fs) - mWindow->setFullscreen(true, 800, 600); - else if (button == m1024x768w) - mWindow->setFullscreen(false, 1024, 768); - else if (button == m1024x768fs) - mWindow->setFullscreen(true, 1024, 768); + if (button == m640x480w) + mWindow->setFullscreen(false, 640, 480); + else if (button == m640x480fs) + mWindow->setFullscreen(true, 640, 480); + else if (button == m800x600w) + mWindow->setFullscreen(false, 800, 600); + else if (button == m800x600fs) + mWindow->setFullscreen(true, 800, 600); + else if (button == m1024x768w) + mWindow->setFullscreen(false, 1024, 768); + else if (button == m1024x768fs) + mWindow->setFullscreen(true, 1024, 768); } //--------------------------------------------------------------------- PlayPen_testMorphAnimationWithNormals::PlayPen_testMorphAnimationWithNormals() { - mInfo["Title"] = "PlayPen: Morph anim (+normals)"; - mInfo["Description"] = "Testing morph animation with normals"; + mInfo["Title"] = "PlayPen: Morph anim (+normals)"; + mInfo["Description"] = "Testing morph animation with normals"; } //--------------------------------------------------------------------- void PlayPen_testMorphAnimationWithNormals::setupContent() { - // Cannot change this to true, not possible to use software morph animation + normals with stencil shadows - // because the former requires pos & normals to be in the same buffer, and the - // latter requires positions to be on their own. - bool testStencil = false; - - if (testStencil) - mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); - - mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); - Vector3 dir(-1, -1, 0.5); - dir.normalise(); - Light* l = mSceneMgr->createLight("light1"); - l->setType(Light::LT_DIRECTIONAL); - l->setDirection(dir); - - - MeshPtr mesh = MeshManager::getSingleton().load("sphere.mesh", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - String morphName = "testmorphwithnormals.mesh"; - mesh = mesh->clone(morphName); - - SubMesh* sm = mesh->getSubMesh(0); - // Re-organise geometry since this mesh has no animation and all - // vertex elements are packed into one buffer - VertexDeclaration* newDecl = - sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true, true); - sm->vertexData->reorganiseBuffers(newDecl); - if (testStencil) - sm->vertexData->prepareForShadowVolume(); // need to re-prep since reorganised - // get the position buffer (which should now be separate); - const VertexElement* posElem = - sm->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr origbuf = - sm->vertexData->vertexBufferBinding->getBuffer( - posElem->getSource()); - - // Create a new position & normal buffer with updated values - HardwareVertexBufferSharedPtr newbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - VertexElement::getTypeSize(VET_FLOAT3) * 2, - sm->vertexData->vertexCount, - HardwareBuffer::HBU_STATIC, true); - float* pSrc = static_cast(origbuf->lock(HardwareBuffer::HBL_READ_ONLY)); - float* pDst = static_cast(newbuf->lock(HardwareBuffer::HBL_DISCARD)); - - // Make the sphere turn into a cube - // Do this just by clamping each of the directions (we shrink it) - float cubeDimension = 0.3f * mesh->getBoundingSphereRadius(); - size_t srcSkip = origbuf->getVertexSize() / sizeof(float) - 3; - for (size_t v = 0; v < sm->vertexData->vertexCount; ++v) - { - // x/y/z position - Vector3 pos; - for (int d = 0; d < 3; ++d) - { - if (*pSrc >= 0) - { - pos.ptr()[d] = std::min(cubeDimension, *pSrc++); - } - else - { - pos.ptr()[d] = std::max(-cubeDimension, *pSrc++); - } - *pDst++ = pos.ptr()[d]; - } - - // normal - // this should point along the major axis - // unfortunately since vertices are not duplicated at edges there will be - // some inaccuracy here but the most important thing is to add sharp edges - Vector3 norm = pos.normalisedCopy(); - norm = norm.primaryAxis(); - *pDst++ = norm.x; - *pDst++ = norm.y; - *pDst++ = norm.z; - - pSrc += srcSkip; - - } - - origbuf->unlock(); - newbuf->unlock(); - - // create a morph animation - Animation* anim = mesh->createAnimation("testAnim", 10.0f); - VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_MORPH); - // re-use start positions for frame 0 - VertexMorphKeyFrame* kf = vt->createVertexMorphKeyFrame(0); - kf->setVertexBuffer(origbuf); - - // Use translated buffer for mid frame - kf = vt->createVertexMorphKeyFrame(4.0f); - kf->setVertexBuffer(newbuf); - - // Pause there - kf = vt->createVertexMorphKeyFrame(6.0f); - kf->setVertexBuffer(newbuf); - - // re-use start positions for final frame - kf = vt->createVertexMorphKeyFrame(10.0f); - kf->setVertexBuffer(origbuf); - - // Export the mesh - DataStreamPtr stream = Root::getSingleton().createFileStream(morphName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); - MeshSerializer ser; - ser.exportMesh(mesh.get(), stream); - stream->close(); - - // Unload old mesh to force reload - MeshManager::getSingleton().remove(mesh->getHandle()); - mesh->unload(); - mesh.setNull(); - - Entity* e = mSceneMgr->createEntity("test", morphName); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); - AnimationState* animState = e->getAnimationState("testAnim"); - animState->setEnabled(true); - animState->setWeight(1.0f); - mAnimStateList.push_back(animState); - - e = mSceneMgr->createEntity("test2", morphName); - mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(200,0,0))->attachObject(e); - // test hardware morph - e->setMaterialName("Examples/HardwareMorphAnimationWithNormals"); - animState = e->getAnimationState("testAnim"); - animState->setEnabled(true); - animState->setWeight(1.0f); - mAnimStateList.push_back(animState); - - mCamera->setNearClipDistance(0.5); - mCamera->setPosition(0,100,-400); - mCamera->lookAt(Vector3::ZERO); - //mSceneMgr->setShowDebugShadows(true); - - Plane plane; - plane.normal = Vector3::UNIT_Y; - plane.d = 200; - MeshManager::getSingleton().createPlane("Myplane", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, - 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); - Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); - pPlaneEnt->setMaterialName("2 - Default"); - pPlaneEnt->setCastShadows(false); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); - + // Cannot change this to true, not possible to use software morph animation + normals with stencil shadows + // because the former requires pos & normals to be in the same buffer, and the + // latter requires positions to be on their own. + bool testStencil = false; + + if (testStencil) + mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); + + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); + Vector3 dir(-1, -1, 0.5); + dir.normalise(); + Light* l = mSceneMgr->createLight("light1"); + l->setType(Light::LT_DIRECTIONAL); + l->setDirection(dir); + + + MeshPtr mesh = MeshManager::getSingleton().load("sphere.mesh", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + String morphName = "testmorphwithnormals.mesh"; + mesh = mesh->clone(morphName); + + SubMesh* sm = mesh->getSubMesh(0); + // Re-organise geometry since this mesh has no animation and all + // vertex elements are packed into one buffer + VertexDeclaration* newDecl = + sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true, true); + sm->vertexData->reorganiseBuffers(newDecl); + if (testStencil) + sm->vertexData->prepareForShadowVolume(); // need to re-prep since reorganised + // get the position buffer (which should now be separate); + const VertexElement* posElem = + sm->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr origbuf = + sm->vertexData->vertexBufferBinding->getBuffer( + posElem->getSource()); + + // Create a new position & normal buffer with updated values + HardwareVertexBufferSharedPtr newbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + VertexElement::getTypeSize(VET_FLOAT3) * 2, + sm->vertexData->vertexCount, + HardwareBuffer::HBU_STATIC, true); + float* pSrc = static_cast(origbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + float* pDst = static_cast(newbuf->lock(HardwareBuffer::HBL_DISCARD)); + + // Make the sphere turn into a cube + // Do this just by clamping each of the directions (we shrink it) + float cubeDimension = 0.3f * mesh->getBoundingSphereRadius(); + size_t srcSkip = origbuf->getVertexSize() / sizeof(float) - 3; + for (size_t v = 0; v < sm->vertexData->vertexCount; ++v) + { + // x/y/z position + Vector3 pos; + for (int d = 0; d < 3; ++d) + { + if (*pSrc >= 0) + { + pos.ptr()[d] = std::min(cubeDimension, *pSrc++); + } + else + { + pos.ptr()[d] = std::max(-cubeDimension, *pSrc++); + } + *pDst++ = pos.ptr()[d]; + } + + // normal + // this should point along the major axis + // unfortunately since vertices are not duplicated at edges there will be + // some inaccuracy here but the most important thing is to add sharp edges + Vector3 norm = pos.normalisedCopy(); + norm = norm.primaryAxis(); + *pDst++ = norm.x; + *pDst++ = norm.y; + *pDst++ = norm.z; + + pSrc += srcSkip; + + } + + origbuf->unlock(); + newbuf->unlock(); + + // create a morph animation + Animation* anim = mesh->createAnimation("testAnim", 10.0f); + VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_MORPH); + // re-use start positions for frame 0 + VertexMorphKeyFrame* kf = vt->createVertexMorphKeyFrame(0); + kf->setVertexBuffer(origbuf); + + // Use translated buffer for mid frame + kf = vt->createVertexMorphKeyFrame(4.0f); + kf->setVertexBuffer(newbuf); + + // Pause there + kf = vt->createVertexMorphKeyFrame(6.0f); + kf->setVertexBuffer(newbuf); + + // re-use start positions for final frame + kf = vt->createVertexMorphKeyFrame(10.0f); + kf->setVertexBuffer(origbuf); + + // Export the mesh + DataStreamPtr stream = Root::getSingleton().createFileStream(morphName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); + MeshSerializer ser; + ser.exportMesh(mesh.get(), stream); + stream->close(); + + // Unload old mesh to force reload + MeshManager::getSingleton().remove(mesh->getHandle()); + mesh->unload(); + mesh.setNull(); + + Entity* e = mSceneMgr->createEntity("test", morphName); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); + AnimationState* animState = e->getAnimationState("testAnim"); + animState->setEnabled(true); + animState->setWeight(1.0f); + mAnimStateList.push_back(animState); + + e = mSceneMgr->createEntity("test2", morphName); + mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(200,0,0))->attachObject(e); + // test hardware morph + e->setMaterialName("Examples/HardwareMorphAnimationWithNormals"); + animState = e->getAnimationState("testAnim"); + animState->setEnabled(true); + animState->setWeight(1.0f); + mAnimStateList.push_back(animState); + + mCamera->setNearClipDistance(0.5); + mCamera->setPosition(0,100,-400); + mCamera->lookAt(Vector3::ZERO); + //mSceneMgr->setShowDebugShadows(true); + + Plane plane; + plane.normal = Vector3::UNIT_Y; + plane.d = 200; + MeshManager::getSingleton().createPlane("Myplane", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, + 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); + Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); + pPlaneEnt->setMaterialName("2 - Default"); + pPlaneEnt->setCastShadows(false); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); + } //--------------------------------------------------------------------- PlayPen_testMorphAnimationWithoutNormals::PlayPen_testMorphAnimationWithoutNormals() { - mInfo["Title"] = "PlayPen: Morph anim (-normals)"; - mInfo["Description"] = "Testing morph animation without normals"; + mInfo["Title"] = "PlayPen: Morph anim (-normals)"; + mInfo["Description"] = "Testing morph animation without normals"; } //--------------------------------------------------------------------- void PlayPen_testMorphAnimationWithoutNormals::setupContent() { - bool testStencil = false; - - if (testStencil) - mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); - - mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); - Vector3 dir(-1, -1, 0.5); - dir.normalise(); - Light* l = mSceneMgr->createLight("light1"); - l->setType(Light::LT_DIRECTIONAL); - l->setDirection(dir); - - - MeshPtr mesh = MeshManager::getSingleton().load("sphere.mesh", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - String morphName = "testmorphnonormals.mesh"; - mesh = mesh->clone(morphName); - - SubMesh* sm = mesh->getSubMesh(0); - // Re-organise geometry since this mesh has no animation and all - // vertex elements are packed into one buffer - VertexDeclaration* newDecl = - sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true, false); - sm->vertexData->reorganiseBuffers(newDecl); - if (testStencil) - sm->vertexData->prepareForShadowVolume(); // need to re-prep since reorganised - // get the position buffer (which should now be separate); - const VertexElement* posElem = - sm->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); - HardwareVertexBufferSharedPtr origbuf = - sm->vertexData->vertexBufferBinding->getBuffer( - posElem->getSource()); - - // Create a new position & normal buffer with updated values - HardwareVertexBufferSharedPtr newbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - VertexElement::getTypeSize(VET_FLOAT3), - sm->vertexData->vertexCount, - HardwareBuffer::HBU_STATIC, true); - float* pSrc = static_cast(origbuf->lock(HardwareBuffer::HBL_READ_ONLY)); - float* pDst = static_cast(newbuf->lock(HardwareBuffer::HBL_DISCARD)); - - // Make the sphere turn into a cube - // Do this just by clamping each of the directions (we shrink it) - float cubeDimension = 0.3f * mesh->getBoundingSphereRadius(); - for (size_t v = 0; v < sm->vertexData->vertexCount; ++v) - { - // x/y/z position - Vector3 pos; - for (int d = 0; d < 3; ++d) - { - if (*pSrc >= 0) - { - pos.ptr()[d] = std::min(cubeDimension, *pSrc++); - } - else - { - pos.ptr()[d] = std::max(-cubeDimension, *pSrc++); - } - *pDst++ = pos.ptr()[d]; - } - - } - - origbuf->unlock(); - newbuf->unlock(); - - // create a morph animation - Animation* anim = mesh->createAnimation("testAnim", 10.0f); - VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_MORPH); - // re-use start positions for frame 0 - VertexMorphKeyFrame* kf = vt->createVertexMorphKeyFrame(0); - kf->setVertexBuffer(origbuf); - - // Use translated buffer for mid frame - kf = vt->createVertexMorphKeyFrame(4.0f); - kf->setVertexBuffer(newbuf); - - // Pause there - kf = vt->createVertexMorphKeyFrame(6.0f); - kf->setVertexBuffer(newbuf); - - // re-use start positions for final frame - kf = vt->createVertexMorphKeyFrame(10.0f); - kf->setVertexBuffer(origbuf); - - // Export the mesh - DataStreamPtr stream = Root::getSingleton().createFileStream(morphName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); - MeshSerializer ser; - ser.exportMesh(mesh.get(), stream); - stream->close(); - - // Unload old mesh to force reload - MeshManager::getSingleton().remove(mesh->getHandle()); - mesh->unload(); - mesh.setNull(); - - Entity* e = mSceneMgr->createEntity("test", morphName); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); - AnimationState* animState = e->getAnimationState("testAnim"); - animState->setEnabled(true); - animState->setWeight(1.0f); - mAnimStateList.push_back(animState); - - e = mSceneMgr->createEntity("test2", morphName); - mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(200,0,0))->attachObject(e); - // test hardware morph - e->setMaterialName("Examples/HardwareMorphAnimation"); - animState = e->getAnimationState("testAnim"); - animState->setEnabled(true); - animState->setWeight(1.0f); - mAnimStateList.push_back(animState); - - mCamera->setNearClipDistance(0.5); - mCamera->setPosition(0,100,-400); - mCamera->lookAt(Vector3::ZERO); - //mSceneMgr->setShowDebugShadows(true); - - Plane plane; - plane.normal = Vector3::UNIT_Y; - plane.d = 200; - MeshManager::getSingleton().createPlane("Myplane", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, - 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); - Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); - pPlaneEnt->setMaterialName("2 - Default"); - pPlaneEnt->setCastShadows(false); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); + bool testStencil = false; + + if (testStencil) + mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); + + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); + Vector3 dir(-1, -1, 0.5); + dir.normalise(); + Light* l = mSceneMgr->createLight("light1"); + l->setType(Light::LT_DIRECTIONAL); + l->setDirection(dir); + + + MeshPtr mesh = MeshManager::getSingleton().load("sphere.mesh", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + String morphName = "testmorphnonormals.mesh"; + mesh = mesh->clone(morphName); + + SubMesh* sm = mesh->getSubMesh(0); + // Re-organise geometry since this mesh has no animation and all + // vertex elements are packed into one buffer + VertexDeclaration* newDecl = + sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true, false); + sm->vertexData->reorganiseBuffers(newDecl); + if (testStencil) + sm->vertexData->prepareForShadowVolume(); // need to re-prep since reorganised + // get the position buffer (which should now be separate); + const VertexElement* posElem = + sm->vertexData->vertexDeclaration->findElementBySemantic(VES_POSITION); + HardwareVertexBufferSharedPtr origbuf = + sm->vertexData->vertexBufferBinding->getBuffer( + posElem->getSource()); + + // Create a new position & normal buffer with updated values + HardwareVertexBufferSharedPtr newbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + VertexElement::getTypeSize(VET_FLOAT3), + sm->vertexData->vertexCount, + HardwareBuffer::HBU_STATIC, true); + float* pSrc = static_cast(origbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + float* pDst = static_cast(newbuf->lock(HardwareBuffer::HBL_DISCARD)); + + // Make the sphere turn into a cube + // Do this just by clamping each of the directions (we shrink it) + float cubeDimension = 0.3f * mesh->getBoundingSphereRadius(); + for (size_t v = 0; v < sm->vertexData->vertexCount; ++v) + { + // x/y/z position + Vector3 pos; + for (int d = 0; d < 3; ++d) + { + if (*pSrc >= 0) + { + pos.ptr()[d] = std::min(cubeDimension, *pSrc++); + } + else + { + pos.ptr()[d] = std::max(-cubeDimension, *pSrc++); + } + *pDst++ = pos.ptr()[d]; + } + + } + + origbuf->unlock(); + newbuf->unlock(); + + // create a morph animation + Animation* anim = mesh->createAnimation("testAnim", 10.0f); + VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_MORPH); + // re-use start positions for frame 0 + VertexMorphKeyFrame* kf = vt->createVertexMorphKeyFrame(0); + kf->setVertexBuffer(origbuf); + + // Use translated buffer for mid frame + kf = vt->createVertexMorphKeyFrame(4.0f); + kf->setVertexBuffer(newbuf); + + // Pause there + kf = vt->createVertexMorphKeyFrame(6.0f); + kf->setVertexBuffer(newbuf); + + // re-use start positions for final frame + kf = vt->createVertexMorphKeyFrame(10.0f); + kf->setVertexBuffer(origbuf); + + // Export the mesh + DataStreamPtr stream = Root::getSingleton().createFileStream(morphName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); + MeshSerializer ser; + ser.exportMesh(mesh.get(), stream); + stream->close(); + + // Unload old mesh to force reload + MeshManager::getSingleton().remove(mesh->getHandle()); + mesh->unload(); + mesh.setNull(); + + Entity* e = mSceneMgr->createEntity("test", morphName); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); + AnimationState* animState = e->getAnimationState("testAnim"); + animState->setEnabled(true); + animState->setWeight(1.0f); + mAnimStateList.push_back(animState); + + e = mSceneMgr->createEntity("test2", morphName); + mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(200,0,0))->attachObject(e); + // test hardware morph + e->setMaterialName("Examples/HardwareMorphAnimation"); + animState = e->getAnimationState("testAnim"); + animState->setEnabled(true); + animState->setWeight(1.0f); + mAnimStateList.push_back(animState); + + mCamera->setNearClipDistance(0.5); + mCamera->setPosition(0,100,-400); + mCamera->lookAt(Vector3::ZERO); + //mSceneMgr->setShowDebugShadows(true); + + Plane plane; + plane.normal = Vector3::UNIT_Y; + plane.d = 200; + MeshManager::getSingleton().createPlane("Myplane", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, + 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); + Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); + pPlaneEnt->setMaterialName("2 - Default"); + pPlaneEnt->setCastShadows(false); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); } //--------------------------------------------------------------------- PlayPen_testPoseAnimationWithNormals::PlayPen_testPoseAnimationWithNormals() { - mInfo["Title"] = "PlayPen: Pose anim (+normals)"; - mInfo["Description"] = "Testing pose animation with normals"; + mInfo["Title"] = "PlayPen: Pose anim (+normals)"; + mInfo["Description"] = "Testing pose animation with normals"; } //--------------------------------------------------------------------- void PlayPen_testPoseAnimationWithNormals::setupContent() { - mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); - Vector3 dir(-1, -1, 0.5); - dir.normalise(); - Light* l = mSceneMgr->createLight("light1"); - l->setType(Light::LT_DIRECTIONAL); - l->setDirection(dir); - - MeshPtr mesh = MeshManager::getSingleton().load("cube.mesh", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - String newName = "testposewithnormals.mesh"; - mesh = mesh->clone(newName); - - - SubMesh* sm = mesh->getSubMesh(0); - // Re-organise geometry since this mesh has no animation and all - // vertex elements are packed into one buffer - VertexDeclaration* newDecl = - sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true, true); - sm->vertexData->reorganiseBuffers(newDecl); - - // create 2 poses - Pose* pose = mesh->createPose(1, "pose1"); - // Pose1 moves vertices 0, 1, 2 and 3 upward and pushes normals left - Vector3 offset1(0, 50, 0); - pose->addVertex(0, offset1, Vector3::NEGATIVE_UNIT_X); - pose->addVertex(1, offset1, Vector3::NEGATIVE_UNIT_X); - pose->addVertex(2, offset1, Vector3::NEGATIVE_UNIT_X); - pose->addVertex(3, offset1, Vector3::NEGATIVE_UNIT_X); - - pose = mesh->createPose(1, "pose2"); - // Pose2 moves vertices 3, 4, and 5 to the right and pushes normals right - // Note 3 gets affected by both - Vector3 offset2(100, 0, 0); - pose->addVertex(3, offset2, Vector3::UNIT_X); - pose->addVertex(4, offset2, Vector3::UNIT_X); - pose->addVertex(5, offset2, Vector3::UNIT_X); - - - Animation* anim = mesh->createAnimation("poseanim", 20.0f); - VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_POSE); - - // Frame 0 - no effect - vt->createVertexPoseKeyFrame(0); - - // Frame 1 - bring in pose 1 (index 0) - VertexPoseKeyFrame* kf = vt->createVertexPoseKeyFrame(3); - kf->addPoseReference(0, 1.0f); - - // Frame 2 - remove all - vt->createVertexPoseKeyFrame(6); - - // Frame 3 - bring in pose 2 (index 1) - kf = vt->createVertexPoseKeyFrame(9); - kf->addPoseReference(1, 1.0f); - - // Frame 4 - remove all - vt->createVertexPoseKeyFrame(12); - - - // Frame 5 - bring in pose 1 at 50%, pose 2 at 100% - kf = vt->createVertexPoseKeyFrame(15); - kf->addPoseReference(0, 0.5f); - kf->addPoseReference(1, 1.0f); - - // Frame 6 - bring in pose 1 at 100%, pose 2 at 50% - kf = vt->createVertexPoseKeyFrame(18); - kf->addPoseReference(0, 1.0f); - kf->addPoseReference(1, 0.5f); - - // Frame 7 - reset - vt->createVertexPoseKeyFrame(20); - - - // Export the mesh - DataStreamPtr stream = Root::getSingleton().createFileStream(newName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); - MeshSerializer ser; - ser.exportMesh(mesh.get(), stream); - stream->close(); - - // Unload old mesh to force reload - MeshManager::getSingleton().remove(mesh->getHandle()); - mesh->unload(); - mesh.setNull(); - - Entity* e; - AnimationState* animState; - // software pose - e = mSceneMgr->createEntity("test2", newName); - mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(150,0,0))->attachObject(e); - animState = e->getAnimationState("poseanim"); - animState->setEnabled(true); - animState->setWeight(1.0f); - mAnimStateList.push_back(animState); - - // test hardware pose - e = mSceneMgr->createEntity("test", newName); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); - e->setMaterialName("Examples/HardwarePoseAnimationWithNormals"); - animState = e->getAnimationState("poseanim"); - animState->setEnabled(true); - animState->setWeight(1.0f); - mAnimStateList.push_back(animState); - - - mCamera->setNearClipDistance(0.5); - mSceneMgr->setShowDebugShadows(true); - - Plane plane; - plane.normal = Vector3::UNIT_Y; - plane.d = 200; - MeshManager::getSingleton().createPlane("Myplane", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, - 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); - Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); - pPlaneEnt->setMaterialName("2 - Default"); - pPlaneEnt->setCastShadows(false); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); - - mCamera->setPosition(0,-200,-300); - mCamera->lookAt(0,0,0); + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); + Vector3 dir(-1, -1, 0.5); + dir.normalise(); + Light* l = mSceneMgr->createLight("light1"); + l->setType(Light::LT_DIRECTIONAL); + l->setDirection(dir); + + MeshPtr mesh = MeshManager::getSingleton().load("cube.mesh", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + String newName = "testposewithnormals.mesh"; + mesh = mesh->clone(newName); + + + SubMesh* sm = mesh->getSubMesh(0); + // Re-organise geometry since this mesh has no animation and all + // vertex elements are packed into one buffer + VertexDeclaration* newDecl = + sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true, true); + sm->vertexData->reorganiseBuffers(newDecl); + + // create 2 poses + Pose* pose = mesh->createPose(1, "pose1"); + // Pose1 moves vertices 0, 1, 2 and 3 upward and pushes normals left + Vector3 offset1(0, 50, 0); + pose->addVertex(0, offset1, Vector3::NEGATIVE_UNIT_X); + pose->addVertex(1, offset1, Vector3::NEGATIVE_UNIT_X); + pose->addVertex(2, offset1, Vector3::NEGATIVE_UNIT_X); + pose->addVertex(3, offset1, Vector3::NEGATIVE_UNIT_X); + + pose = mesh->createPose(1, "pose2"); + // Pose2 moves vertices 3, 4, and 5 to the right and pushes normals right + // Note 3 gets affected by both + Vector3 offset2(100, 0, 0); + pose->addVertex(3, offset2, Vector3::UNIT_X); + pose->addVertex(4, offset2, Vector3::UNIT_X); + pose->addVertex(5, offset2, Vector3::UNIT_X); + + + Animation* anim = mesh->createAnimation("poseanim", 20.0f); + VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_POSE); + + // Frame 0 - no effect + vt->createVertexPoseKeyFrame(0); + + // Frame 1 - bring in pose 1 (index 0) + VertexPoseKeyFrame* kf = vt->createVertexPoseKeyFrame(3); + kf->addPoseReference(0, 1.0f); + + // Frame 2 - remove all + vt->createVertexPoseKeyFrame(6); + + // Frame 3 - bring in pose 2 (index 1) + kf = vt->createVertexPoseKeyFrame(9); + kf->addPoseReference(1, 1.0f); + + // Frame 4 - remove all + vt->createVertexPoseKeyFrame(12); + + + // Frame 5 - bring in pose 1 at 50%, pose 2 at 100% + kf = vt->createVertexPoseKeyFrame(15); + kf->addPoseReference(0, 0.5f); + kf->addPoseReference(1, 1.0f); + + // Frame 6 - bring in pose 1 at 100%, pose 2 at 50% + kf = vt->createVertexPoseKeyFrame(18); + kf->addPoseReference(0, 1.0f); + kf->addPoseReference(1, 0.5f); + + // Frame 7 - reset + vt->createVertexPoseKeyFrame(20); + + + // Export the mesh + DataStreamPtr stream = Root::getSingleton().createFileStream(newName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); + MeshSerializer ser; + ser.exportMesh(mesh.get(), stream); + stream->close(); + + // Unload old mesh to force reload + MeshManager::getSingleton().remove(mesh->getHandle()); + mesh->unload(); + mesh.setNull(); + + Entity* e; + AnimationState* animState; + // software pose + e = mSceneMgr->createEntity("test2", newName); + mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(150,0,0))->attachObject(e); + animState = e->getAnimationState("poseanim"); + animState->setEnabled(true); + animState->setWeight(1.0f); + mAnimStateList.push_back(animState); + + // test hardware pose + e = mSceneMgr->createEntity("test", newName); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); + e->setMaterialName("Examples/HardwarePoseAnimationWithNormals"); + animState = e->getAnimationState("poseanim"); + animState->setEnabled(true); + animState->setWeight(1.0f); + mAnimStateList.push_back(animState); + + + mCamera->setNearClipDistance(0.5); + mSceneMgr->setShowDebugShadows(true); + + Plane plane; + plane.normal = Vector3::UNIT_Y; + plane.d = 200; + MeshManager::getSingleton().createPlane("Myplane", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, + 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); + Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); + pPlaneEnt->setMaterialName("2 - Default"); + pPlaneEnt->setCastShadows(false); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); + + mCamera->setPosition(0,-200,-300); + mCamera->lookAt(0,0,0); } //--------------------------------------------------------------------- PlayPen_testPoseAnimationWithoutNormals::PlayPen_testPoseAnimationWithoutNormals() { - mInfo["Title"] = "PlayPen: Pose anim (-normals)"; - mInfo["Description"] = "Testing pose animation without normals"; + mInfo["Title"] = "PlayPen: Pose anim (-normals)"; + mInfo["Description"] = "Testing pose animation without normals"; } //--------------------------------------------------------------------- void PlayPen_testPoseAnimationWithoutNormals::setupContent() { - mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); - Vector3 dir(-1, -1, 0.5); - dir.normalise(); - Light* l = mSceneMgr->createLight("light1"); - l->setType(Light::LT_DIRECTIONAL); - l->setDirection(dir); - - MeshPtr mesh = MeshManager::getSingleton().load("cube.mesh", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - String newName = "testposenonormals.mesh"; - mesh = mesh->clone(newName); - - - SubMesh* sm = mesh->getSubMesh(0); - // Re-organise geometry since this mesh has no animation and all - // vertex elements are packed into one buffer - VertexDeclaration* newDecl = - sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true, false); - sm->vertexData->reorganiseBuffers(newDecl); - - // create 2 poses - Pose* pose = mesh->createPose(1, "pose1"); - // Pose1 moves vertices 0, 1, 2 and 3 upward - Vector3 offset1(0, 50, 0); - pose->addVertex(0, offset1); - pose->addVertex(1, offset1); - pose->addVertex(2, offset1); - pose->addVertex(3, offset1); - - pose = mesh->createPose(1, "pose2"); - // Pose2 moves vertices 3, 4, and 5 to the right - // Note 3 gets affected by both - Vector3 offset2(100, 0, 0); - pose->addVertex(3, offset2); - pose->addVertex(4, offset2); - pose->addVertex(5, offset2); - - - Animation* anim = mesh->createAnimation("poseanim", 20.0f); - VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_POSE); - - // Frame 0 - no effect - vt->createVertexPoseKeyFrame(0); - - // Frame 1 - bring in pose 1 (index 0) - VertexPoseKeyFrame* kf = vt->createVertexPoseKeyFrame(3); - kf->addPoseReference(0, 1.0f); - - // Frame 2 - remove all - vt->createVertexPoseKeyFrame(6); - - // Frame 3 - bring in pose 2 (index 1) - kf = vt->createVertexPoseKeyFrame(9); - kf->addPoseReference(1, 1.0f); - - // Frame 4 - remove all - vt->createVertexPoseKeyFrame(12); - - - // Frame 5 - bring in pose 1 at 50%, pose 2 at 100% - kf = vt->createVertexPoseKeyFrame(15); - kf->addPoseReference(0, 0.5f); - kf->addPoseReference(1, 1.0f); - - // Frame 6 - bring in pose 1 at 100%, pose 2 at 50% - kf = vt->createVertexPoseKeyFrame(18); - kf->addPoseReference(0, 1.0f); - kf->addPoseReference(1, 0.5f); - - // Frame 7 - reset - vt->createVertexPoseKeyFrame(20); - - // Export the mesh - DataStreamPtr stream = Root::getSingleton().createFileStream(newName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); - MeshSerializer ser; - ser.exportMesh(mesh.get(), stream); - stream->close(); - - // Unload old mesh to force reload - MeshManager::getSingleton().remove(mesh->getHandle()); - mesh->unload(); - mesh.setNull(); - - Entity* e; - AnimationState* animState; - // software pose - e = mSceneMgr->createEntity("test2", newName); - mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(150,0,0))->attachObject(e); - animState = e->getAnimationState("poseanim"); - animState->setEnabled(true); - animState->setWeight(1.0f); - mAnimStateList.push_back(animState); - - // test hardware pose - e = mSceneMgr->createEntity("test", newName); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); - e->setMaterialName("Examples/HardwarePoseAnimation"); - animState = e->getAnimationState("poseanim"); - animState->setEnabled(true); - animState->setWeight(1.0f); - mAnimStateList.push_back(animState); - - - mCamera->setNearClipDistance(0.5); - - Plane plane; - plane.normal = Vector3::UNIT_Y; - plane.d = 200; - MeshManager::getSingleton().createPlane("Myplane", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, - 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); - Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); - pPlaneEnt->setMaterialName("2 - Default"); - pPlaneEnt->setCastShadows(false); - mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); - - mCamera->setPosition(0,-200,-300); - mCamera->lookAt(0,0,0); + mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); + Vector3 dir(-1, -1, 0.5); + dir.normalise(); + Light* l = mSceneMgr->createLight("light1"); + l->setType(Light::LT_DIRECTIONAL); + l->setDirection(dir); + + MeshPtr mesh = MeshManager::getSingleton().load("cube.mesh", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + String newName = "testposenonormals.mesh"; + mesh = mesh->clone(newName); + + + SubMesh* sm = mesh->getSubMesh(0); + // Re-organise geometry since this mesh has no animation and all + // vertex elements are packed into one buffer + VertexDeclaration* newDecl = + sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(false, true, false); + sm->vertexData->reorganiseBuffers(newDecl); + + // create 2 poses + Pose* pose = mesh->createPose(1, "pose1"); + // Pose1 moves vertices 0, 1, 2 and 3 upward + Vector3 offset1(0, 50, 0); + pose->addVertex(0, offset1); + pose->addVertex(1, offset1); + pose->addVertex(2, offset1); + pose->addVertex(3, offset1); + + pose = mesh->createPose(1, "pose2"); + // Pose2 moves vertices 3, 4, and 5 to the right + // Note 3 gets affected by both + Vector3 offset2(100, 0, 0); + pose->addVertex(3, offset2); + pose->addVertex(4, offset2); + pose->addVertex(5, offset2); + + + Animation* anim = mesh->createAnimation("poseanim", 20.0f); + VertexAnimationTrack* vt = anim->createVertexTrack(1, sm->vertexData, VAT_POSE); + + // Frame 0 - no effect + vt->createVertexPoseKeyFrame(0); + + // Frame 1 - bring in pose 1 (index 0) + VertexPoseKeyFrame* kf = vt->createVertexPoseKeyFrame(3); + kf->addPoseReference(0, 1.0f); + + // Frame 2 - remove all + vt->createVertexPoseKeyFrame(6); + + // Frame 3 - bring in pose 2 (index 1) + kf = vt->createVertexPoseKeyFrame(9); + kf->addPoseReference(1, 1.0f); + + // Frame 4 - remove all + vt->createVertexPoseKeyFrame(12); + + + // Frame 5 - bring in pose 1 at 50%, pose 2 at 100% + kf = vt->createVertexPoseKeyFrame(15); + kf->addPoseReference(0, 0.5f); + kf->addPoseReference(1, 1.0f); + + // Frame 6 - bring in pose 1 at 100%, pose 2 at 50% + kf = vt->createVertexPoseKeyFrame(18); + kf->addPoseReference(0, 1.0f); + kf->addPoseReference(1, 0.5f); + + // Frame 7 - reset + vt->createVertexPoseKeyFrame(20); + + // Export the mesh + DataStreamPtr stream = Root::getSingleton().createFileStream(newName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); + MeshSerializer ser; + ser.exportMesh(mesh.get(), stream); + stream->close(); + + // Unload old mesh to force reload + MeshManager::getSingleton().remove(mesh->getHandle()); + mesh->unload(); + mesh.setNull(); + + Entity* e; + AnimationState* animState; + // software pose + e = mSceneMgr->createEntity("test2", newName); + mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(150,0,0))->attachObject(e); + animState = e->getAnimationState("poseanim"); + animState->setEnabled(true); + animState->setWeight(1.0f); + mAnimStateList.push_back(animState); + + // test hardware pose + e = mSceneMgr->createEntity("test", newName); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(e); + e->setMaterialName("Examples/HardwarePoseAnimation"); + animState = e->getAnimationState("poseanim"); + animState->setEnabled(true); + animState->setWeight(1.0f); + mAnimStateList.push_back(animState); + + + mCamera->setNearClipDistance(0.5); + + Plane plane; + plane.normal = Vector3::UNIT_Y; + plane.d = 200; + MeshManager::getSingleton().createPlane("Myplane", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, + 1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z); + Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" ); + pPlaneEnt->setMaterialName("2 - Default"); + pPlaneEnt->setCastShadows(false); + mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); + + mCamera->setPosition(0,-200,-300); + mCamera->lookAt(0,0,0); } diff --git a/Tests/PlayPen/src/WindowEmbedding.cpp b/Tests/PlayPen/src/WindowEmbedding.cpp index 5fcf8ab579d..6aa1755daea 100644 --- a/Tests/PlayPen/src/WindowEmbedding.cpp +++ b/Tests/PlayPen/src/WindowEmbedding.cpp @@ -39,27 +39,27 @@ void setupResources(void); // Just a prototype void setupResources(void) { - // Load resource paths from config file - ConfigFile cf; - cf.load("resources.cfg"); - - // Go through all sections & settings in the file - ConfigFile::SectionIterator seci = cf.getSectionIterator(); - - String secName, typeName, archName; - while (seci.hasMoreElements()) - { - secName = seci.peekNextKey(); - ConfigFile::SettingsMultiMap *settings = seci.getNext(); - ConfigFile::SettingsMultiMap::iterator i; - for (i = settings->begin(); i != settings->end(); ++i) - { - typeName = i->first; - archName = i->second; - ResourceGroupManager::getSingleton().addResourceLocation( - archName, typeName, secName); - } - } + // Load resource paths from config file + ConfigFile cf; + cf.load("resources.cfg"); + + // Go through all sections & settings in the file + ConfigFile::SectionIterator seci = cf.getSectionIterator(); + + String secName, typeName, archName; + while (seci.hasMoreElements()) + { + secName = seci.peekNextKey(); + ConfigFile::SettingsMultiMap *settings = seci.getNext(); + ConfigFile::SettingsMultiMap::iterator i; + for (i = settings->begin(); i != settings->end(); ++i) + { + typeName = i->first; + archName = i->second; + ResourceGroupManager::getSingleton().addResourceLocation( + archName, typeName, secName); + } + } } @@ -75,133 +75,133 @@ bool winSizing = false; LRESULT CALLBACK TestWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { - if (uMsg == WM_CREATE) - { - return 0; - } - - - if (!renderWindow) - return DefWindowProc(hWnd, uMsg, wParam, lParam); - - switch( uMsg ) - { - case WM_ACTIVATE: - winActive = (LOWORD(wParam) != WA_INACTIVE); - break; - - case WM_ENTERSIZEMOVE: - winSizing = true; - break; - - case WM_EXITSIZEMOVE: - renderWindow->windowMovedOrResized(); - renderWindow->update(); - winSizing = false; - break; - - case WM_MOVE: - case WM_SIZE: - if (!winSizing) - renderWindow->windowMovedOrResized(); - break; - - case WM_GETMINMAXINFO: - // Prevent the window from going smaller than some min size - ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100; - ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100; - break; - - case WM_CLOSE: - renderWindow->destroy(); // cleanup and call DestroyWindow - PostQuitMessage(0); - return 0; - case WM_PAINT: - if (!winSizing) - { - renderWindow->update(); - return 0; - } - break; - } - - return DefWindowProc( hWnd, uMsg, wParam, lParam ); + if (uMsg == WM_CREATE) + { + return 0; + } + + + if (!renderWindow) + return DefWindowProc(hWnd, uMsg, wParam, lParam); + + switch( uMsg ) + { + case WM_ACTIVATE: + winActive = (LOWORD(wParam) != WA_INACTIVE); + break; + + case WM_ENTERSIZEMOVE: + winSizing = true; + break; + + case WM_EXITSIZEMOVE: + renderWindow->windowMovedOrResized(); + renderWindow->update(); + winSizing = false; + break; + + case WM_MOVE: + case WM_SIZE: + if (!winSizing) + renderWindow->windowMovedOrResized(); + break; + + case WM_GETMINMAXINFO: + // Prevent the window from going smaller than some min size + ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100; + ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100; + break; + + case WM_CLOSE: + renderWindow->destroy(); // cleanup and call DestroyWindow + PostQuitMessage(0); + return 0; + case WM_PAINT: + if (!winSizing) + { + renderWindow->update(); + return 0; + } + break; + } + + return DefWindowProc( hWnd, uMsg, wParam, lParam ); } INT WINAPI EmbeddedMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) { - try - { - // Create a new window + try + { + // Create a new window - // Style & size - DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW; + // Style & size + DWORD dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW; - // Register the window class - WNDCLASS wc = { 0, TestWndProc, 0, 0, hInst, - LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), - (HBRUSH)GetStockObject(BLACK_BRUSH), 0, "TestWnd" }; - RegisterClass(&wc); + // Register the window class + WNDCLASS wc = { 0, TestWndProc, 0, 0, hInst, + LoadIcon(0, IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), + (HBRUSH)GetStockObject(BLACK_BRUSH), 0, "TestWnd" }; + RegisterClass(&wc); - HWND hwnd = CreateWindow("TestWnd", "Test embedding", dwStyle, - 0, 0, 800, 600, 0, 0, hInst, 0); + HWND hwnd = CreateWindow("TestWnd", "Test embedding", dwStyle, + 0, 0, 800, 600, 0, 0, hInst, 0); - Root root("", ""); + Root root("", ""); - root.loadPlugin("RenderSystem_GL"); - //root.loadPlugin("RenderSystem_Direct3D9"); - root.loadPlugin("Plugin_ParticleFX"); - root.loadPlugin("Plugin_CgProgramManager"); + root.loadPlugin("RenderSystem_GL"); + //root.loadPlugin("RenderSystem_Direct3D9"); + root.loadPlugin("Plugin_ParticleFX"); + root.loadPlugin("Plugin_CgProgramManager"); - // select first renderer & init with no window - root.setRenderSystem(*(root.getAvailableRenderers().begin())); - root.initialise(false); + // select first renderer & init with no window + root.setRenderSystem(*(root.getAvailableRenderers().begin())); + root.initialise(false); - // create first window manually - NameValuePairList options; - options["externalWindowHandle"] = - StringConverter::toString((size_t)hwnd); + // create first window manually + NameValuePairList options; + options["externalWindowHandle"] = + StringConverter::toString((size_t)hwnd); - renderWindow = root.createRenderWindow("embedded", 800, 600, false, &options); + renderWindow = root.createRenderWindow("embedded", 800, 600, false, &options); - setupResources(); - ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + setupResources(); + ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - SceneManager *scene = root.createSceneManager(Ogre::ST_GENERIC, "default"); + SceneManager *scene = root.createSceneManager(Ogre::ST_GENERIC, "default"); - Camera *cam = scene->createCamera("cam"); + Camera *cam = scene->createCamera("cam"); - Viewport* vp = renderWindow->addViewport(cam); - vp->setBackgroundColour(Ogre::ColourValue(0.5, 0.5, 0.7)); - cam->setAutoAspectRatio(true); - cam->setPosition(0,0,300); - cam->setDirection(0,0,-1); + Viewport* vp = renderWindow->addViewport(cam); + vp->setBackgroundColour(Ogre::ColourValue(0.5, 0.5, 0.7)); + cam->setAutoAspectRatio(true); + cam->setPosition(0,0,300); + cam->setDirection(0,0,-1); - Entity* e = scene->createEntity("1", "ogrehead.mesh"); - scene->getRootSceneNode()->createChildSceneNode()->attachObject(e); - Light* l = scene->createLight("l"); - l->setPosition(300, 100, -100); + Entity* e = scene->createEntity("1", "ogrehead.mesh"); + scene->getRootSceneNode()->createChildSceneNode()->attachObject(e); + Light* l = scene->createLight("l"); + l->setPosition(300, 100, -100); - // message loop - MSG msg; - while(GetMessage(&msg, NULL, 0, 0 ) != 0) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } + // message loop + MSG msg; + while(GetMessage(&msg, NULL, 0, 0 ) != 0) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } - } - catch( Exception& e ) - { - MessageBox( NULL, e.getFullDescription().c_str(), - "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL); - } + } + catch( Exception& e ) + { + MessageBox( NULL, e.getFullDescription().c_str(), + "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL); + } - return 0; + return 0; } #endif diff --git a/Tests/VisualTests/PlayPen/src/PlayPenTests.cpp b/Tests/VisualTests/PlayPen/src/PlayPenTests.cpp index 9316956db35..221b84d8514 100644 --- a/Tests/VisualTests/PlayPen/src/PlayPenTests.cpp +++ b/Tests/VisualTests/PlayPen/src/PlayPenTests.cpp @@ -97,10 +97,10 @@ String PlayPen_ManualLOD::getLODMesh() MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh", TRANSIENT_RESOURCE_GROUP); - LodConfig lodConfig(msh1); - lodConfig.createManualLodLevel(5, "razor.mesh"); - lodConfig.createManualLodLevel(10, "sphere.mesh"); - MeshLodGenerator().generateLodLevels(lodConfig); + LodConfig lodConfig(msh1); + lodConfig.createManualLodLevel(5, "razor.mesh"); + lodConfig.createManualLodLevel(10, "sphere.mesh"); + MeshLodGenerator().generateLodLevels(lodConfig); return msh1->getName(); } @@ -120,10 +120,10 @@ String PlayPen_ManualLODFromFile::getLODMesh() MeshPtr msh1 = (MeshPtr)MeshManager::getSingleton().load("robot.mesh", TRANSIENT_RESOURCE_GROUP); - LodConfig lodConfig(msh1); - lodConfig.createManualLodLevel(5, "razor.mesh"); - lodConfig.createManualLodLevel(10, "sphere.mesh"); - MeshLodGenerator().generateLodLevels(lodConfig); + LodConfig lodConfig(msh1); + lodConfig.createManualLodLevel(5, "razor.mesh"); + lodConfig.createManualLodLevel(10, "sphere.mesh"); + MeshLodGenerator().generateLodLevels(lodConfig); // this time, we save this data to a file and re-load it diff --git a/Tests/src/main.cpp b/Tests/src/main.cpp index 28eb051ae60..e4b1078c250 100644 --- a/Tests/src/main.cpp +++ b/Tests/src/main.cpp @@ -41,26 +41,26 @@ int main(int argc, char *argv[]) runner.run( controller ); // Print test results to a file - std::ofstream ofile("OgreTestResults.xml"); - + std::ofstream ofile("OgreTestResults.xml"); + CPPUNIT_NS::XmlOutputter xmlOut(&result, ofile); xmlOut.write(); #if OGRE_COMPILER == OGRE_COMPILER_MSVC - if (IsDebuggerPresent()){ - // Write report to MSVC IDE console for convenience. - // If you click on the assert location then the IDE will jump there! - char separator[82]; - memset(separator, '+', 80); - separator[80] = '\n'; - separator[81] = 0; - Ogre::StringStream str; - str << "\n" << separator << separator; - CPPUNIT_NS::CompilerOutputter txtOut(&result, str); - txtOut.write(); - str << separator << separator << "\n"; - OutputDebugStringA(str.str().c_str()); - } + if (IsDebuggerPresent()){ + // Write report to MSVC IDE console for convenience. + // If you click on the assert location then the IDE will jump there! + char separator[82]; + memset(separator, '+', 80); + separator[80] = '\n'; + separator[81] = 0; + Ogre::StringStream str; + str << "\n" << separator << separator; + CPPUNIT_NS::CompilerOutputter txtOut(&result, str); + txtOut.write(); + str << separator << separator << "\n"; + OutputDebugStringA(str.str().c_str()); + } #endif tearDownSuite(); diff --git a/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/DllEntry.cpp b/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/DllEntry.cpp index 0acaa4f5ded..fb763baf405 100644 --- a/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/DllEntry.cpp +++ b/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/DllEntry.cpp @@ -1,14 +1,14 @@ /********************************************************************** *< - FILE: DllEntry.cpp + FILE: DllEntry.cpp - DESCRIPTION:Contains the Dll Entry stuff + DESCRIPTION:Contains the Dll Entry stuff - CREATED BY: + CREATED BY: - HISTORY: + HISTORY: - *> Copyright (c) 1997, All Rights Reserved. + *> Copyright (c) 1997, All Rights Reserved. **********************************************************************/ #include "PhyExport.h" @@ -20,47 +20,47 @@ int controlsInit = FALSE; BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) { - hInstance = hinstDLL; // Hang on to this DLL's instance handle. - - if (!controlsInit) { - controlsInit = TRUE; - InitCustomControls(hInstance); // Initialize MAX's custom controls - InitCommonControls(); // Initialize Win95 controls - } - - return (TRUE); + hInstance = hinstDLL; // Hang on to this DLL's instance handle. + + if (!controlsInit) { + controlsInit = TRUE; + InitCustomControls(hInstance); // Initialize MAX's custom controls + InitCommonControls(); // Initialize Win95 controls + } + + return (TRUE); } __declspec( dllexport ) const TCHAR* LibDescription() { - return GetString(IDS_LIBDESCRIPTION); + return GetString(IDS_LIBDESCRIPTION); } //TODO: Must change this number when adding a new class __declspec( dllexport ) int LibNumberClasses() { - return 1; + return 1; } __declspec( dllexport ) ClassDesc* LibClassDesc(int i) { - switch(i) { - case 0: return GetPhyExportDesc(); - default: return 0; - } + switch(i) { + case 0: return GetPhyExportDesc(); + default: return 0; + } } __declspec( dllexport ) ULONG LibVersion() { - return VERSION_3DSMAX; + return VERSION_3DSMAX; } TCHAR *GetString(int id) { - static TCHAR buf[256]; + static TCHAR buf[256]; - if (hInstance) - return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL; - return NULL; + if (hInstance) + return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL; + return NULL; } diff --git a/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PhyExport.cpp b/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PhyExport.cpp index 907f711f35d..ab639b9954b 100644 --- a/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PhyExport.cpp +++ b/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PhyExport.cpp @@ -1,55 +1,55 @@ /********************************************************************** *< - FILE: PhyExport.cpp + FILE: PhyExport.cpp - DESCRIPTION: Appwizard generated plugin + DESCRIPTION: Appwizard generated plugin - CREATED BY: + CREATED BY: - HISTORY: + HISTORY: - *> Copyright (c) 1997, All Rights Reserved. + *> Copyright (c) 1997, All Rights Reserved. **********************************************************************/ #include "PhyExport.h" -#define PHYEXPORT_CLASS_ID Class_ID(0x3dc3c42e, 0x185dc5f2) +#define PHYEXPORT_CLASS_ID Class_ID(0x3dc3c42e, 0x185dc5f2) class PhyExport : public GUP { - public: - static HWND hParams; + public: + static HWND hParams; - // GUP Methods - DWORD Start ( ); - void Stop ( ); - DWORD Control ( DWORD parameter ); - - // Loading/Saving - IOResult Save(ISave *isave); - IOResult Load(ILoad *iload); + // GUP Methods + DWORD Start ( ); + void Stop ( ); + DWORD Control ( DWORD parameter ); + + // Loading/Saving + IOResult Save(ISave *isave); + IOResult Load(ILoad *iload); - - //Constructor/Destructor + + //Constructor/Destructor - PhyExport(); - ~PhyExport(); + PhyExport(); + ~PhyExport(); }; class PhyExportClassDesc:public ClassDesc2 { - public: - int IsPublic() { return 1; } - void * Create(BOOL loading = FALSE) { return new PhyExport(); } - const TCHAR * ClassName() { return GetString(IDS_CLASS_NAME); } - SClass_ID SuperClassID() { return GUP_CLASS_ID; } - Class_ID ClassID() { return PHYEXPORT_CLASS_ID; } - const TCHAR* Category() { return GetString(IDS_CATEGORY); } + public: + int IsPublic() { return 1; } + void * Create(BOOL loading = FALSE) { return new PhyExport(); } + const TCHAR * ClassName() { return GetString(IDS_CLASS_NAME); } + SClass_ID SuperClassID() { return GUP_CLASS_ID; } + Class_ID ClassID() { return PHYEXPORT_CLASS_ID; } + const TCHAR* Category() { return GetString(IDS_CATEGORY); } - const TCHAR* InternalName() { return _T("PhyExport"); } // returns fixed parsable name (scripter-visible name) - HINSTANCE HInstance() { return hInstance; } // returns owning module handle + const TCHAR* InternalName() { return _T("PhyExport"); } // returns fixed parsable name (scripter-visible name) + HINSTANCE HInstance() { return hInstance; } // returns owning module handle }; @@ -71,28 +71,28 @@ PhyExport::~PhyExport() // Activate and Stay Resident DWORD PhyExport::Start( ) { - - // TODO: Do plugin initialization here - - // TODO: Return if you want remain loaded or not - return GUPRESULT_KEEP; + + // TODO: Do plugin initialization here + + // TODO: Return if you want remain loaded or not + return GUPRESULT_KEEP; } void PhyExport::Stop( ) { - // TODO: Do plugin un-initialization here + // TODO: Do plugin un-initialization here } DWORD PhyExport::Control( DWORD parameter ) { - return 0; + return 0; } IOResult PhyExport::Save(ISave *isave) { - return IO_OK; + return IO_OK; } IOResult PhyExport::Load(ILoad *iload) { - return IO_OK; + return IO_OK; } diff --git a/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PhyExport.h b/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PhyExport.h index 4d9d3dfa877..4e1a1e165d3 100644 --- a/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PhyExport.h +++ b/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PhyExport.h @@ -1,14 +1,14 @@ /********************************************************************** *< - FILE: PhyExport.h + FILE: PhyExport.h - DESCRIPTION: Template Utility + DESCRIPTION: Template Utility - CREATED BY: + CREATED BY: - HISTORY: + HISTORY: - *> Copyright (c) 1997, All Rights Reserved. + *> Copyright (c) 1997, All Rights Reserved. **********************************************************************/ #ifndef __PHYEXPORT__H diff --git a/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PublishedInterface.cpp b/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PublishedInterface.cpp index 31ad8329c54..bbbee19e08f 100644 --- a/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PublishedInterface.cpp +++ b/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PublishedInterface.cpp @@ -7,198 +7,198 @@ // FP interface descriptor - FnPub-published methods & properties //**************************************************************** static IPhysiqueInterface iPhysiqueInterface (IPHYSIQUEINTERFACE, _T("physiqueOps"), 0, NULL, FP_CORE + FP_STATIC_METHODS, - //methods - IPhysiqueInterface::checkMatrix, _T("checkMatrix"), 0, TYPE_BOOL, 0, 2, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("modifier"), 0, TYPE_REFTARG,f_keyArgDefault, NULL, - - IPhysiqueInterface::getPhysique, _T("getPhysiqueModifier"), 0, TYPE_REFTARG, 0, 2, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("index"), 0, TYPE_INDEX, f_keyArgDefault, 0, - IPhysiqueInterface::getAPIVersion, _T("getAPIVersion"), 0, TYPE_INT, 0, 2, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - - IPhysiqueInterface::getBoneList, _T("getBones"), 0, TYPE_INODE_TAB_BV, 0, 2, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::getBoneCount, _T("getBoneCount"), 0, TYPE_INT, 0, 2, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::getVertexCount, _T("getVertexCount"), 0, TYPE_INT, 0, 2, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - - IPhysiqueInterface::getInitialNodeTM, _T("getInitialNodeTM"), 0, TYPE_MATRIX3_BV, 0, 2, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::getInitialBoneTM, _T("getInitialBoneTM"), 0, TYPE_MATRIX3_BV, 0, 3, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("boneIndex"), 0, TYPE_INDEX, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - - IPhysiqueInterface::getVertexType, _T("getVertexType"), 0, TYPE_ENUM, IPhysiqueInterface::blendingTypeEnum, 0, 3, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("vertexIndex"), 0, TYPE_INDEX, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::getVertexBones, _T("getVertexBones"), 0, TYPE_INODE_TAB_BV, 0, 5, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("vertexIndex"), 0, TYPE_INDEX, - _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true, - _T("blending"), 0, TYPE_bool, f_keyArgDefault, true, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::getVertexBoneCount, _T("getVertexBoneCount"), 0, TYPE_INT, 0, 4, - _T("physiquedNode"), 0, TYPE_INODE, - _T("vertexIndex"), 0, TYPE_INDEX, - _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::getVertexBone, _T("getVertexBone"), 0, TYPE_INODE, 0, 6, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("vertexIndex"), 0, TYPE_INDEX, - _T("boneIndex"), 0, TYPE_INDEX, - _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true, - _T("blending"), 0, TYPE_bool, f_keyArgDefault, true, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::getVertexOffset, _T("getVertexOffset"), 0, TYPE_POINT3_BV, 0, 6, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("vertexIndex"), 0, TYPE_INDEX, - _T("boneIndex"), 0, TYPE_INDEX, - _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true, - _T("blending"), 0, TYPE_bool, f_keyArgDefault, true, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::getVertexDeformableOffset, _T("getVertexDeformableOffset"), 0, TYPE_POINT3_BV, 0, 3, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("vertexIndex"), 0, TYPE_INDEX, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::getVertexWeight, _T("getVertexWeight"), 0, TYPE_FLOAT, 0, 6, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("vertexIndex"), 0, TYPE_INDEX, - _T("boneIndex"), 0, TYPE_INDEX, - _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true, - _T("blending"), 0, TYPE_bool, f_keyArgDefault, true, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - - IPhysiqueInterface::setInitialPose, _T("setInitialPose"), 0, TYPE_VOID, 0, 3, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("state"), 0, TYPE_bool, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::setFigureMode, _T("setFigureMode"), 0, TYPE_bool, 0, 3, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("state"), 0, TYPE_bool, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - - IPhysiqueInterface::attachToNode, _T("attachToNode"), 0, TYPE_bool, 0, 3, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("rootNode"), 0, TYPE_INODE, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::initialize, _T("initialize"), 0, TYPE_bool, 0, 3, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("rootNode"), 0, TYPE_INODE, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - - IPhysiqueInterface::lockVertex, _T("lockVertex"), 0, TYPE_VOID, 0, 3, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("vertexIndex"), 0, TYPE_INDEX, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::unlockVertex, _T("unlockVertex"), 0, TYPE_VOID, 0, 3, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("vertexIndex"), 0, TYPE_INDEX, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - IPhysiqueInterface::setVertexBone, _T("setVertexBone"), 0, TYPE_VOID, 0, 6, - _T("physiqued_Node"), 0, TYPE_INODE, - _T("vertexIndex"), 0, TYPE_INDEX, - _T("bone"), 0, TYPE_INODE, - _T("weight"), 0, TYPE_FLOAT, f_keyArgDefault, 1.0f, - _T("clear"), 0, TYPE_bool, f_keyArgDefault, false, - _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, - -// properties, -// ICoreTestInterface::iobjectInterfaceServer, FP_NO_FUNCTION, _T("interfaceServer"), 0, TYPE_IOBJECT, - enums, - IPhysiqueInterface::blendingTypeEnum, 8, - _T("rigid_type"), RIGID_TYPE, - _T("deformable_type"), DEFORMABLE_TYPE, - _T("blended_type"), BLENDED_TYPE, - _T("floating_type"), FLOATING_TYPE, - _T("rigid_non_blended_type"), RIGID_NON_BLENDED_TYPE, - _T("deformable_non_blended_type"), DEFORMABLE_NON_BLENDED_TYPE, - _T("rigid_blended_type"), RIGID_BLENDED_TYPE, - _T("deformable_blended_type"), DEFORMABLE_BLENDED_TYPE, - IPhysiqueInterface::interfaceTypeEnum, 1, - _T("floatingInterface"), FLOATING_TYPE, - - end - ); + //methods + IPhysiqueInterface::checkMatrix, _T("checkMatrix"), 0, TYPE_BOOL, 0, 2, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("modifier"), 0, TYPE_REFTARG,f_keyArgDefault, NULL, + + IPhysiqueInterface::getPhysique, _T("getPhysiqueModifier"), 0, TYPE_REFTARG, 0, 2, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("index"), 0, TYPE_INDEX, f_keyArgDefault, 0, + IPhysiqueInterface::getAPIVersion, _T("getAPIVersion"), 0, TYPE_INT, 0, 2, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + + IPhysiqueInterface::getBoneList, _T("getBones"), 0, TYPE_INODE_TAB_BV, 0, 2, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::getBoneCount, _T("getBoneCount"), 0, TYPE_INT, 0, 2, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::getVertexCount, _T("getVertexCount"), 0, TYPE_INT, 0, 2, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + + IPhysiqueInterface::getInitialNodeTM, _T("getInitialNodeTM"), 0, TYPE_MATRIX3_BV, 0, 2, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::getInitialBoneTM, _T("getInitialBoneTM"), 0, TYPE_MATRIX3_BV, 0, 3, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("boneIndex"), 0, TYPE_INDEX, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + + IPhysiqueInterface::getVertexType, _T("getVertexType"), 0, TYPE_ENUM, IPhysiqueInterface::blendingTypeEnum, 0, 3, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INDEX, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::getVertexBones, _T("getVertexBones"), 0, TYPE_INODE_TAB_BV, 0, 5, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INDEX, + _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true, + _T("blending"), 0, TYPE_bool, f_keyArgDefault, true, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::getVertexBoneCount, _T("getVertexBoneCount"), 0, TYPE_INT, 0, 4, + _T("physiquedNode"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INDEX, + _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::getVertexBone, _T("getVertexBone"), 0, TYPE_INODE, 0, 6, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INDEX, + _T("boneIndex"), 0, TYPE_INDEX, + _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true, + _T("blending"), 0, TYPE_bool, f_keyArgDefault, true, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::getVertexOffset, _T("getVertexOffset"), 0, TYPE_POINT3_BV, 0, 6, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INDEX, + _T("boneIndex"), 0, TYPE_INDEX, + _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true, + _T("blending"), 0, TYPE_bool, f_keyArgDefault, true, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::getVertexDeformableOffset, _T("getVertexDeformableOffset"), 0, TYPE_POINT3_BV, 0, 3, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INDEX, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::getVertexWeight, _T("getVertexWeight"), 0, TYPE_FLOAT, 0, 6, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INDEX, + _T("boneIndex"), 0, TYPE_INDEX, + _T("rigid"), 0, TYPE_bool, f_keyArgDefault, true, + _T("blending"), 0, TYPE_bool, f_keyArgDefault, true, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + + IPhysiqueInterface::setInitialPose, _T("setInitialPose"), 0, TYPE_VOID, 0, 3, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("state"), 0, TYPE_bool, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::setFigureMode, _T("setFigureMode"), 0, TYPE_bool, 0, 3, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("state"), 0, TYPE_bool, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + + IPhysiqueInterface::attachToNode, _T("attachToNode"), 0, TYPE_bool, 0, 3, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("rootNode"), 0, TYPE_INODE, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::initialize, _T("initialize"), 0, TYPE_bool, 0, 3, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("rootNode"), 0, TYPE_INODE, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + + IPhysiqueInterface::lockVertex, _T("lockVertex"), 0, TYPE_VOID, 0, 3, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INDEX, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::unlockVertex, _T("unlockVertex"), 0, TYPE_VOID, 0, 3, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INDEX, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + IPhysiqueInterface::setVertexBone, _T("setVertexBone"), 0, TYPE_VOID, 0, 6, + _T("physiqued_Node"), 0, TYPE_INODE, + _T("vertexIndex"), 0, TYPE_INDEX, + _T("bone"), 0, TYPE_INODE, + _T("weight"), 0, TYPE_FLOAT, f_keyArgDefault, 1.0f, + _T("clear"), 0, TYPE_bool, f_keyArgDefault, false, + _T("modifier"), 0, TYPE_REFTARG, f_keyArgDefault, NULL, + +// properties, +// ICoreTestInterface::iobjectInterfaceServer, FP_NO_FUNCTION, _T("interfaceServer"), 0, TYPE_IOBJECT, + enums, + IPhysiqueInterface::blendingTypeEnum, 8, + _T("rigid_type"), RIGID_TYPE, + _T("deformable_type"), DEFORMABLE_TYPE, + _T("blended_type"), BLENDED_TYPE, + _T("floating_type"), FLOATING_TYPE, + _T("rigid_non_blended_type"), RIGID_NON_BLENDED_TYPE, + _T("deformable_non_blended_type"), DEFORMABLE_NON_BLENDED_TYPE, + _T("rigid_blended_type"), RIGID_BLENDED_TYPE, + _T("deformable_blended_type"), DEFORMABLE_BLENDED_TYPE, + IPhysiqueInterface::interfaceTypeEnum, 1, + _T("floatingInterface"), FLOATING_TYPE, + + end + ); //SDK level methods //**************************************************************** Modifier* IPhysiqueInterface::FindPhysiqueModifier (INode* nodePtr, int modIndex) { - // Get object from node. Abort if no object. - if (!nodePtr) return NULL; - - Object* ObjectPtr = nodePtr->GetObjectRef(); - - if (!ObjectPtr ) return NULL; - - while (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID && ObjectPtr) - { - // Yes -> Cast. - IDerivedObject* DerivedObjectPtr = (IDerivedObject *)(ObjectPtr); - - // Iterate over all entries of the modifier stack. - int modStackIndex = 0, phyModIndex = 0; - - while (modStackIndex < DerivedObjectPtr->NumModifiers()) - { - // Get current modifier. - Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(modStackIndex); - - // Is this Physique ? - if (ModifierPtr->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)) - { - if (phyModIndex >= modIndex) - { - return ModifierPtr; - } - phyModIndex++; - } - modStackIndex++; - } - ObjectPtr = DerivedObjectPtr->GetObjRef(); - } - - // Not found. - throw MAXException("No physique modifier found"); - return NULL; + // Get object from node. Abort if no object. + if (!nodePtr) return NULL; + + Object* ObjectPtr = nodePtr->GetObjectRef(); + + if (!ObjectPtr ) return NULL; + + while (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID && ObjectPtr) + { + // Yes -> Cast. + IDerivedObject* DerivedObjectPtr = (IDerivedObject *)(ObjectPtr); + + // Iterate over all entries of the modifier stack. + int modStackIndex = 0, phyModIndex = 0; + + while (modStackIndex < DerivedObjectPtr->NumModifiers()) + { + // Get current modifier. + Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(modStackIndex); + + // Is this Physique ? + if (ModifierPtr->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)) + { + if (phyModIndex >= modIndex) + { + return ModifierPtr; + } + phyModIndex++; + } + modStackIndex++; + } + ObjectPtr = DerivedObjectPtr->GetObjRef(); + } + + // Not found. + throw MAXException("No physique modifier found"); + return NULL; } BOOL IPhysiqueInterface::CheckMatrix(INode* node, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - int version = phyExport->Version(); - - if(version == 30) - { - //get the node's initial transformation matrix and store it in a matrix3 - Matrix3 initTM = Matrix3(TRUE); - int msg = phyExport->GetInitNodeTM(node, initTM); + int version = phyExport->Version(); + + if(version == 30) + { + //get the node's initial transformation matrix and store it in a matrix3 + Matrix3 initTM = Matrix3(TRUE); + int msg = phyExport->GetInitNodeTM(node, initTM); - //Release the physique interface + //Release the physique interface - if (msg == NO_MATRIX_SAVED) - return false; - } + if (msg == NO_MATRIX_SAVED) + return false; + } - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - return true; + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + return true; } @@ -206,78 +206,78 @@ BOOL IPhysiqueInterface::CheckMatrix(INode* node, ReferenceTarget* mod) Matrix3 IPhysiqueInterface::GetInitialNodeTM(INode* node, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - - //get the node's initial transformation matrix and store it in a matrix3 - Matrix3 initTM = Matrix3(TRUE); - int msg = phyExport->GetInitNodeTM(node, initTM); - - //Release the physique interface - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - if (msg != MATRIX_RETURNED) - { - switch (msg) - { - case NODE_NOT_FOUND: - throw MAXException ("Node not found"); - case NO_MATRIX_SAVED: - throw MAXException("No matrix saved"); - case INVALID_MOD_POINTER: - throw MAXException("Invalid modifier pointer"); - default: - break; - } - } - - - return initTM; + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + + //get the node's initial transformation matrix and store it in a matrix3 + Matrix3 initTM = Matrix3(TRUE); + int msg = phyExport->GetInitNodeTM(node, initTM); + + //Release the physique interface + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + if (msg != MATRIX_RETURNED) + { + switch (msg) + { + case NODE_NOT_FOUND: + throw MAXException ("Node not found"); + case NO_MATRIX_SAVED: + throw MAXException("No matrix saved"); + case INVALID_MOD_POINTER: + throw MAXException("Invalid modifier pointer"); + default: + break; + } + } + + + return initTM; } Matrix3 IPhysiqueInterface::GetInitialBoneTM(INode* node, int index, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - - //get the list of bones - Tab bones = GetBoneList(node); - if (index <0 || index >= bones.Count()) throw MAXException("The Bone index is not in the valid range"); - - //get the node's initial transformation matrix and store it in a matrix3 - Matrix3 initTM = Matrix3(TRUE); - int msg = phyExport->GetInitNodeTM(bones[index], initTM); - //Release the physique interface - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - - if (msg != MATRIX_RETURNED) - { - switch (msg) - { - case NODE_NOT_FOUND: - throw MAXException ("Node not found"); - case NO_MATRIX_SAVED: - throw MAXException("No matrix saved"); - case INVALID_MOD_POINTER: - throw MAXException("Invalid modifier pointer"); - default: - break; - } - } - return initTM; + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + + //get the list of bones + Tab bones = GetBoneList(node); + if (index <0 || index >= bones.Count()) throw MAXException("The Bone index is not in the valid range"); + + //get the node's initial transformation matrix and store it in a matrix3 + Matrix3 initTM = Matrix3(TRUE); + int msg = phyExport->GetInitNodeTM(bones[index], initTM); + //Release the physique interface + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + + if (msg != MATRIX_RETURNED) + { + switch (msg) + { + case NODE_NOT_FOUND: + throw MAXException ("Node not found"); + case NO_MATRIX_SAVED: + throw MAXException("No matrix saved"); + case INVALID_MOD_POINTER: + throw MAXException("Invalid modifier pointer"); + default: + break; + } + } + return initTM; } int IPhysiqueInterface::GetBoneCount(INode* node, ReferenceTarget* mod) { - //get the list of bones - Tab bones = GetBoneList(node, mod); - return bones.Count(); + //get the list of bones + Tab bones = GetBoneList(node, mod); + return bones.Count(); } @@ -286,716 +286,716 @@ int IPhysiqueInterface::GetBoneCount(INode* node, ReferenceTarget* mod) //**************************************************************************** Tab IPhysiqueInterface::GetBoneList(INode* node, ReferenceTarget* mod) { - int i = 0, x = 0; - Tab bones; - INode* bone; - - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - - //get a pointer to the export context interface - IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); - - //convert to rigid for time independent vertex assignment - mcExport->ConvertToRigid(true); - - //allow blending to export multi-link assignments - mcExport->AllowBlending(true); - - //These are the different types of vertex classes - IPhyBlendedRigidVertex *rb_vtx; - IPhyRigidVertex *r_vtx; - IPhyFloatingVertex *f_vtx; - - //get the vertex count from the export interface - int numverts = mcExport->GetNumberVertices(); - - //iterate through all vertices and gather the bone list - for (i = 0; iGetVertexInterface(i); - if (vi) { - - //check the vertex type and process accordingly - int type = vi->GetVertexType(); - switch (type) - { - //The vertex is rigid, blended vertex. It's assigned to multiple links - case RIGID_BLENDED_TYPE: - //type-cast the node to the proper class - rb_vtx = (IPhyBlendedRigidVertex*)vi; - - //iterate through the bones assigned to this vertex - for (x = 0; xGetNumberNodes(); x++) - { - exists = false; - //get the node by index - bone = rb_vtx->GetNode(x); - - //check to see if we already have this bone - for (int z=0;zGetNode(); - - //check to see if the bone is already in the list - for (x = 0;xGetVertexInterface(i); - for (x = 0; xGetNumberNodes(); x++) - { - exists = false; - - //get the node by index - bone = f_vtx->GetNode(x); - - //check to see if we already have this bone - for (int z=0;zReleaseContextInterface(mcExport); - - //Release the physique interface - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - - return bones; + int i = 0, x = 0; + Tab bones; + INode* bone; + + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + + //get a pointer to the export context interface + IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); + + //convert to rigid for time independent vertex assignment + mcExport->ConvertToRigid(true); + + //allow blending to export multi-link assignments + mcExport->AllowBlending(true); + + //These are the different types of vertex classes + IPhyBlendedRigidVertex *rb_vtx; + IPhyRigidVertex *r_vtx; + IPhyFloatingVertex *f_vtx; + + //get the vertex count from the export interface + int numverts = mcExport->GetNumberVertices(); + + //iterate through all vertices and gather the bone list + for (i = 0; iGetVertexInterface(i); + if (vi) { + + //check the vertex type and process accordingly + int type = vi->GetVertexType(); + switch (type) + { + //The vertex is rigid, blended vertex. It's assigned to multiple links + case RIGID_BLENDED_TYPE: + //type-cast the node to the proper class + rb_vtx = (IPhyBlendedRigidVertex*)vi; + + //iterate through the bones assigned to this vertex + for (x = 0; xGetNumberNodes(); x++) + { + exists = false; + //get the node by index + bone = rb_vtx->GetNode(x); + + //check to see if we already have this bone + for (int z=0;zGetNode(); + + //check to see if the bone is already in the list + for (x = 0;xGetVertexInterface(i); + for (x = 0; xGetNumberNodes(); x++) + { + exists = false; + + //get the node by index + bone = f_vtx->GetNode(x); + + //check to see if we already have this bone + for (int z=0;zReleaseContextInterface(mcExport); + + //Release the physique interface + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + + return bones; } int IPhysiqueInterface::GetAPIVersion(INode* node, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - int version = phyExport->Version(); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + int version = phyExport->Version(); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - return version; + return version; } void IPhysiqueInterface::SetInitialPose(INode* node, bool set, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - phyExport->SetInitialPose(set); - ((ReferenceTarget*)mod)->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + phyExport->SetInitialPose(set); + ((ReferenceTarget*)mod)->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); } int IPhysiqueInterface::GetVertexCount(INode* node, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - //get a pointer to the export context interface - IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); + //get a pointer to the export context interface + IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); - int vertCount = mcExport->GetNumberVertices(); + int vertCount = mcExport->GetNumberVertices(); - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - return vertCount; + return vertCount; } int IPhysiqueInterface::GetVertexType(INode* node, int vertIndex, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - - //get a pointer to the export context interface - IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); - - IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); - if (!vi) - { - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - throw MAXException("No vertex interface found"); - } - - int type = vi->GetVertexType(); - - mcExport->ReleaseVertexInterface(vi); - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - - return type; + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + + //get a pointer to the export context interface + IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); + + IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); + if (!vi) + { + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + throw MAXException("No vertex interface found"); + } + + int type = vi->GetVertexType(); + + mcExport->ReleaseVertexInterface(vi); + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + + return type; } int IPhysiqueInterface::GetVertexBoneCount(INode* node, int vertIndex, bool rigid, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - - //get a pointer to the export context interface - IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); - - if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices()) - throw MAXException("The vertex index is not in the valid range"); - - mcExport->ConvertToRigid(rigid); - int count = 0; - - IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); - if (vi) - { - int type = vi->GetVertexType(); - switch (type) - { - case RIGID_NON_BLENDED_TYPE: - case DEFORMABLE_NON_BLENDED_TYPE: - count += 1; - break; - case RIGID_BLENDED_TYPE: - count += ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); - break; - case DEFORMABLE_BLENDED_TYPE: - throw MAXException("Not a currently supported type"); - break; - case FLOATING_TYPE: - count += ((IPhyFloatingVertex*)vi)->GetNumberNodes(); - break; - } - - mcExport->ReleaseVertexInterface(vi); - - } - - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - - return count; + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + + //get a pointer to the export context interface + IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); + + if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices()) + throw MAXException("The vertex index is not in the valid range"); + + mcExport->ConvertToRigid(rigid); + int count = 0; + + IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); + if (vi) + { + int type = vi->GetVertexType(); + switch (type) + { + case RIGID_NON_BLENDED_TYPE: + case DEFORMABLE_NON_BLENDED_TYPE: + count += 1; + break; + case RIGID_BLENDED_TYPE: + count += ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); + break; + case DEFORMABLE_BLENDED_TYPE: + throw MAXException("Not a currently supported type"); + break; + case FLOATING_TYPE: + count += ((IPhyFloatingVertex*)vi)->GetNumberNodes(); + break; + } + + mcExport->ReleaseVertexInterface(vi); + + } + + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + + return count; } Tab IPhysiqueInterface::GetVertexBones(INode* node, int vertIndex, bool rigid, bool blending, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - - //get a pointer to the export context interface - IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); - mcExport->ConvertToRigid(rigid); - mcExport->AllowBlending(blending); - - if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices()) - throw MAXException("The vertex index is not in the valid range"); - - INode* bone = NULL; - Tab bones; - bones.ZeroCount(); - int count = 0, i = 0; - - IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); - if (vi) - { - int type = vi->GetVertexType(); - switch (type) - { - case RIGID_NON_BLENDED_TYPE: - bone = ((IPhyRigidVertex*)vi)->GetNode(); - bones.Append(1, &bone); - break; - case RIGID_BLENDED_TYPE: - count = ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); - for (i=0;iGetNode(i); - bones.Append(1, &bone); - } - break; - case DEFORMABLE_NON_BLENDED_TYPE: - bone = ((IPhyDeformableOffsetVertex*)vi)->GetNode(); - bones.Append(1, &bone); - break; - case DEFORMABLE_BLENDED_TYPE: - throw MAXException("Not a currently supported type"); - break; - case FLOATING_TYPE: - count += ((IPhyFloatingVertex*)vi)->GetNumberNodes(); - for (i=0;iGetNode(i); - bones.Append(1, &bone); - } - break; - } - - mcExport->ReleaseVertexInterface(vi); - } - - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - - return bones; + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + + //get a pointer to the export context interface + IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); + mcExport->ConvertToRigid(rigid); + mcExport->AllowBlending(blending); + + if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices()) + throw MAXException("The vertex index is not in the valid range"); + + INode* bone = NULL; + Tab bones; + bones.ZeroCount(); + int count = 0, i = 0; + + IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); + if (vi) + { + int type = vi->GetVertexType(); + switch (type) + { + case RIGID_NON_BLENDED_TYPE: + bone = ((IPhyRigidVertex*)vi)->GetNode(); + bones.Append(1, &bone); + break; + case RIGID_BLENDED_TYPE: + count = ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); + for (i=0;iGetNode(i); + bones.Append(1, &bone); + } + break; + case DEFORMABLE_NON_BLENDED_TYPE: + bone = ((IPhyDeformableOffsetVertex*)vi)->GetNode(); + bones.Append(1, &bone); + break; + case DEFORMABLE_BLENDED_TYPE: + throw MAXException("Not a currently supported type"); + break; + case FLOATING_TYPE: + count += ((IPhyFloatingVertex*)vi)->GetNumberNodes(); + for (i=0;iGetNode(i); + bones.Append(1, &bone); + } + break; + } + + mcExport->ReleaseVertexInterface(vi); + } + + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + + return bones; } INode* IPhysiqueInterface::GetVertexBone(INode* node, int vertIndex, int boneIndex, bool rigid, bool blending, ReferenceTarget* mod) { - Tab bones = GetVertexBones(node, vertIndex, rigid, blending, mod); - if (boneIndex < 0 || boneIndex >= bones.Count()) - throw MAXException("The bone index is not in the valid range"); + Tab bones = GetVertexBones(node, vertIndex, rigid, blending, mod); + if (boneIndex < 0 || boneIndex >= bones.Count()) + throw MAXException("The bone index is not in the valid range"); - return bones[boneIndex]; + return bones[boneIndex]; } Point3 IPhysiqueInterface::GetVertexOffset(INode* node, int vertIndex, int boneIndex, bool rigid, bool blending, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - - //get a pointer to the export context interface - IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); - mcExport->ConvertToRigid(rigid); - mcExport->AllowBlending(blending); - - if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices()) - throw MAXException("The vertex index is not in the valid range"); - - Point3 offset = Point3(0,0,0); - Tab offsetTab; - offsetTab.ZeroCount(); - int count = 0, i = 0; - - IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); - if (vi) - { - int type = vi->GetVertexType(); - switch (type) - { - case RIGID_NON_BLENDED_TYPE: - offset = ((IPhyRigidVertex*)vi)->GetOffsetVector(); - offsetTab.Append(1, &offset); - break; - case RIGID_BLENDED_TYPE: - count = ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); - for (i=0;iGetOffsetVector(i); - offsetTab.Append(1, &offset); - } - break; - case DEFORMABLE_NON_BLENDED_TYPE: - offset = ((IPhyDeformableOffsetVertex*)vi)->GetOffsetVector(); - offsetTab.Append(1, &offset); - break; - case DEFORMABLE_BLENDED_TYPE: - throw MAXException("Not a currently supported type"); - break; - case FLOATING_TYPE: - count += ((IPhyFloatingVertex*)vi)->GetNumberNodes(); - for (i=0;iGetOffsetVector(i); - offsetTab.Append(1, &offset); - } - break; - } - - mcExport->ReleaseVertexInterface(vi); - - } - - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - - if (boneIndex < 0 || boneIndex >= offsetTab.Count()) - throw MAXException("The bone index is not in the valid range"); - - return offsetTab[boneIndex]; + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + + //get a pointer to the export context interface + IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); + mcExport->ConvertToRigid(rigid); + mcExport->AllowBlending(blending); + + if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices()) + throw MAXException("The vertex index is not in the valid range"); + + Point3 offset = Point3(0,0,0); + Tab offsetTab; + offsetTab.ZeroCount(); + int count = 0, i = 0; + + IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); + if (vi) + { + int type = vi->GetVertexType(); + switch (type) + { + case RIGID_NON_BLENDED_TYPE: + offset = ((IPhyRigidVertex*)vi)->GetOffsetVector(); + offsetTab.Append(1, &offset); + break; + case RIGID_BLENDED_TYPE: + count = ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); + for (i=0;iGetOffsetVector(i); + offsetTab.Append(1, &offset); + } + break; + case DEFORMABLE_NON_BLENDED_TYPE: + offset = ((IPhyDeformableOffsetVertex*)vi)->GetOffsetVector(); + offsetTab.Append(1, &offset); + break; + case DEFORMABLE_BLENDED_TYPE: + throw MAXException("Not a currently supported type"); + break; + case FLOATING_TYPE: + count += ((IPhyFloatingVertex*)vi)->GetNumberNodes(); + for (i=0;iGetOffsetVector(i); + offsetTab.Append(1, &offset); + } + break; + } + + mcExport->ReleaseVertexInterface(vi); + + } + + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + + if (boneIndex < 0 || boneIndex >= offsetTab.Count()) + throw MAXException("The bone index is not in the valid range"); + + return offsetTab[boneIndex]; } Point3 IPhysiqueInterface::GetVertexDeformableOffset(INode* node, int vertIndex, ReferenceTarget* mod, TimeValue t) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - - //get a pointer to the export context interface - IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); - - if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices()) - throw MAXException("The vertex index is not in the valid range"); - - Point3 offset = Point3(0,0,0); - - IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); - if (vi) - { - int type = vi->GetVertexType(); - switch (type) - { - case RIGID_NON_BLENDED_TYPE: - case RIGID_BLENDED_TYPE: - case FLOATING_TYPE: - break; - case DEFORMABLE_NON_BLENDED_TYPE: - offset = ((IPhyDeformableOffsetVertex*)vi)->GetDeformOffsetVector(t); - break; - case DEFORMABLE_BLENDED_TYPE: - throw MAXException("Not a currently supported type"); - break; - } - mcExport->ReleaseVertexInterface(vi); - } - - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - return offset; + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + + //get a pointer to the export context interface + IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); + + if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices()) + throw MAXException("The vertex index is not in the valid range"); + + Point3 offset = Point3(0,0,0); + + IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); + if (vi) + { + int type = vi->GetVertexType(); + switch (type) + { + case RIGID_NON_BLENDED_TYPE: + case RIGID_BLENDED_TYPE: + case FLOATING_TYPE: + break; + case DEFORMABLE_NON_BLENDED_TYPE: + offset = ((IPhyDeformableOffsetVertex*)vi)->GetDeformOffsetVector(t); + break; + case DEFORMABLE_BLENDED_TYPE: + throw MAXException("Not a currently supported type"); + break; + } + mcExport->ReleaseVertexInterface(vi); + } + + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + return offset; } float IPhysiqueInterface::GetVertexWeight(INode* node, int vertIndex, int boneIndex, bool rigid, bool blending, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - //get a pointer to the export interface - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - - //get a pointer to the export context interface - IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); - mcExport->ConvertToRigid(rigid); - mcExport->AllowBlending(blending); - - if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices()) - throw MAXException("The vertex index is not in the valid range"); - - //Point3 offset = Point3(0,0,0); - //Tab offsetTab; - //offsetTab.ZeroCount(); - int count = 0, i = 0; - float normalizedWeight = 0.0f, totalWeight = 0.0f, weight = 0.0f; - float tempFloat; - - IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); - if (vi) - { - int type = vi->GetVertexType(); - switch (type) - { - case RIGID_NON_BLENDED_TYPE: - case DEFORMABLE_NON_BLENDED_TYPE: - count = 1; - normalizedWeight = 1.0f; - break; - case RIGID_BLENDED_TYPE: - count = ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); - for (i=0;iGetWeight(i); - if (i == boneIndex) normalizedWeight = tempFloat; - } - break; - case DEFORMABLE_BLENDED_TYPE: - throw MAXException("Not a currently supported type"); - break; - case FLOATING_TYPE: - normalizedWeight = 0.0f; - for (i=0;i<((IPhyFloatingVertex*)vi)->GetNumberNodes();i++) - { - tempFloat = ((IPhyFloatingVertex*)vi)->GetWeight(i, weight); - if (count + i == boneIndex) normalizedWeight = tempFloat; - totalWeight += weight; - } - count = count+i; - - if (totalWeight != 0) - normalizedWeight = normalizedWeight/totalWeight; - break; - } - - mcExport->ReleaseVertexInterface(vi); - } - - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - - if (boneIndex < 0 || boneIndex >= count) - throw MAXException("The bone index is not in the valid range"); - - return normalizedWeight; + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + //get a pointer to the export interface + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + + //get a pointer to the export context interface + IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); + mcExport->ConvertToRigid(rigid); + mcExport->AllowBlending(blending); + + if (vertIndex < 0 || vertIndex >= mcExport->GetNumberVertices()) + throw MAXException("The vertex index is not in the valid range"); + + //Point3 offset = Point3(0,0,0); + //Tab offsetTab; + //offsetTab.ZeroCount(); + int count = 0, i = 0; + float normalizedWeight = 0.0f, totalWeight = 0.0f, weight = 0.0f; + float tempFloat; + + IPhyVertexExport* vi = mcExport->GetVertexInterface(vertIndex); + if (vi) + { + int type = vi->GetVertexType(); + switch (type) + { + case RIGID_NON_BLENDED_TYPE: + case DEFORMABLE_NON_BLENDED_TYPE: + count = 1; + normalizedWeight = 1.0f; + break; + case RIGID_BLENDED_TYPE: + count = ((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); + for (i=0;iGetWeight(i); + if (i == boneIndex) normalizedWeight = tempFloat; + } + break; + case DEFORMABLE_BLENDED_TYPE: + throw MAXException("Not a currently supported type"); + break; + case FLOATING_TYPE: + normalizedWeight = 0.0f; + for (i=0;i<((IPhyFloatingVertex*)vi)->GetNumberNodes();i++) + { + tempFloat = ((IPhyFloatingVertex*)vi)->GetWeight(i, weight); + if (count + i == boneIndex) normalizedWeight = tempFloat; + totalWeight += weight; + } + count = count+i; + + if (totalWeight != 0) + normalizedWeight = normalizedWeight/totalWeight; + break; + } + + mcExport->ReleaseVertexInterface(vi); + } + + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + + if (boneIndex < 0 || boneIndex >= count) + throw MAXException("The bone index is not in the valid range"); + + return normalizedWeight; } bool IPhysiqueInterface::SetFigureMode(INode* node, bool state, ReferenceTarget* mod) { - int i = 0, x = 0; - INode* bone; - - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); - IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); - int numverts = mcExport->GetNumberVertices(); - - for (i = 0; iGetVertexInterface(i); - if (vi) { - int type = vi->GetVertexType(); - switch (type) - { - case RIGID_BLENDED_TYPE: - for (x = 0; x<((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); x++) - { - bone = ((IPhyBlendedRigidVertex*)vi)->GetNode(x); - if (BipedFigureMode(bone, state)) - { - mcExport->ReleaseVertexInterface(vi); - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - return true; - } - - } - break; - case RIGID_TYPE: - bone = ((IPhyRigidVertex*)vi)->GetNode(); - if (BipedFigureMode(bone, state)) - { - mcExport->ReleaseVertexInterface(vi); - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - return true; - } - break; - case DEFORMABLE_TYPE: - bone = ((IPhyDeformableOffsetVertex*)vi)->GetNode(); - if (BipedFigureMode(bone, state)) - { - mcExport->ReleaseVertexInterface(vi); - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - return true; - } - break; - case FLOATING_TYPE: - for (x = 0; x<((IPhyFloatingVertex*)vi)->GetNumberNodes(); x++) - { - bone = ((IPhyFloatingVertex*)vi)->GetNode(x); - if (BipedFigureMode(bone, state)) - { - mcExport->ReleaseVertexInterface(vi); - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - return true; - } - } - break; - default: break; - } - } - mcExport->ReleaseVertexInterface(vi); - - } - - phyExport->ReleaseContextInterface(mcExport); - mod->ReleaseInterface(I_PHYINTERFACE, phyExport); - - return false; + int i = 0, x = 0; + INode* bone; + + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + IPhysiqueExport *phyExport = (IPhysiqueExport *)mod->GetInterface(I_PHYINTERFACE); + IPhyContextExport *mcExport = (IPhyContextExport *)phyExport->GetContextInterface(node); + int numverts = mcExport->GetNumberVertices(); + + for (i = 0; iGetVertexInterface(i); + if (vi) { + int type = vi->GetVertexType(); + switch (type) + { + case RIGID_BLENDED_TYPE: + for (x = 0; x<((IPhyBlendedRigidVertex*)vi)->GetNumberNodes(); x++) + { + bone = ((IPhyBlendedRigidVertex*)vi)->GetNode(x); + if (BipedFigureMode(bone, state)) + { + mcExport->ReleaseVertexInterface(vi); + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + return true; + } + + } + break; + case RIGID_TYPE: + bone = ((IPhyRigidVertex*)vi)->GetNode(); + if (BipedFigureMode(bone, state)) + { + mcExport->ReleaseVertexInterface(vi); + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + return true; + } + break; + case DEFORMABLE_TYPE: + bone = ((IPhyDeformableOffsetVertex*)vi)->GetNode(); + if (BipedFigureMode(bone, state)) + { + mcExport->ReleaseVertexInterface(vi); + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + return true; + } + break; + case FLOATING_TYPE: + for (x = 0; x<((IPhyFloatingVertex*)vi)->GetNumberNodes(); x++) + { + bone = ((IPhyFloatingVertex*)vi)->GetNode(x); + if (BipedFigureMode(bone, state)) + { + mcExport->ReleaseVertexInterface(vi); + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + return true; + } + } + break; + default: break; + } + } + mcExport->ReleaseVertexInterface(vi); + + } + + phyExport->ReleaseContextInterface(mcExport); + mod->ReleaseInterface(I_PHYINTERFACE, phyExport); + + return false; } bool IPhysiqueInterface::BipedFigureMode(INode* node, bool state) { - if (node->IsRootNode()) return false; + if (node->IsRootNode()) return false; - Control* c = node->GetTMController(); + Control* c = node->GetTMController(); if ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) || (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) || (c->ClassID() == FOOTPRINT_CLASS_ID)) { IBipedExport *iBiped = (IBipedExport *) c->GetInterface(I_BIPINTERFACE); if (iBiped) - { - //iBiped->RemoveNonUniformScale((BOOL)state); - if (state) iBiped->BeginFigureMode(0); - else iBiped->EndFigureMode(0); - - Control* iMaster = (Control *) c->GetInterface(I_MASTER); - iMaster->NotifyDependents(FOREVER, PART_TM, REFMSG_CHANGE); - - c->ReleaseInterface(I_MASTER,iMaster); - c->ReleaseInterface(I_BIPINTERFACE,iBiped); - return true; - } - } - return false; + { + //iBiped->RemoveNonUniformScale((BOOL)state); + if (state) iBiped->BeginFigureMode(0); + else iBiped->EndFigureMode(0); + + Control* iMaster = (Control *) c->GetInterface(I_MASTER); + iMaster->NotifyDependents(FOREVER, PART_TM, REFMSG_CHANGE); + + c->ReleaseInterface(I_MASTER,iMaster); + c->ReleaseInterface(I_BIPINTERFACE,iBiped); + return true; + } + } + return false; } bool IPhysiqueInterface::AttachToNode(INode* node, INode* rootNode, ReferenceTarget* mod, TimeValue t) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT); - bool val = false; - if (phyImport->AttachRootNode(rootNode, t)) - val = true; - mod->ReleaseInterface(I_PHYIMPORT, phyImport); - return val; + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT); + bool val = false; + if (phyImport->AttachRootNode(rootNode, t)) + val = true; + mod->ReleaseInterface(I_PHYIMPORT, phyImport); + return val; } bool IPhysiqueInterface::Initialize(INode* node, INode* rootNode, ReferenceTarget* mod, TimeValue t) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT); - bool val = false; - if (phyImport->InitializePhysique(rootNode, t)) - val = true; - mod->ReleaseInterface(I_PHYIMPORT, phyImport); - return val; + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT); + bool val = false; + if (phyImport->InitializePhysique(rootNode, t)) + val = true; + mod->ReleaseInterface(I_PHYIMPORT, phyImport); + return val; } void IPhysiqueInterface::LockVertex(INode* node, int vertexIndex, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT); - IPhyContextImport *mcImport = (IPhyContextImport *)phyImport->GetContextInterface(node); - IPhyVertexImport *vi = mcImport->SetVertexInterface(vertexIndex, RIGID_BLENDED_TYPE); - - vi->LockVertex(TRUE); - mcImport->ReleaseVertexInterface(vi); - phyImport->ReleaseContextInterface(mcImport); - mod->ReleaseInterface(I_PHYIMPORT, phyImport); + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT); + IPhyContextImport *mcImport = (IPhyContextImport *)phyImport->GetContextInterface(node); + IPhyVertexImport *vi = mcImport->SetVertexInterface(vertexIndex, RIGID_BLENDED_TYPE); + + vi->LockVertex(TRUE); + mcImport->ReleaseVertexInterface(vi); + phyImport->ReleaseContextInterface(mcImport); + mod->ReleaseInterface(I_PHYIMPORT, phyImport); } void IPhysiqueInterface::UnLockVertex(INode* node, int vertexIndex, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT); - IPhyContextImport *mcImport = (IPhyContextImport *)phyImport->GetContextInterface(node); - IPhyVertexImport *vi = mcImport->SetVertexInterface(vertexIndex, RIGID_BLENDED_TYPE); - - vi->LockVertex(FALSE); - mcImport->ReleaseVertexInterface(vi); - phyImport->ReleaseContextInterface(mcImport); - mod->ReleaseInterface(I_PHYIMPORT, phyImport); + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT); + IPhyContextImport *mcImport = (IPhyContextImport *)phyImport->GetContextInterface(node); + IPhyVertexImport *vi = mcImport->SetVertexInterface(vertexIndex, RIGID_BLENDED_TYPE); + + vi->LockVertex(FALSE); + mcImport->ReleaseVertexInterface(vi); + phyImport->ReleaseContextInterface(mcImport); + mod->ReleaseInterface(I_PHYIMPORT, phyImport); } void IPhysiqueInterface::SetVertexBone(INode* node, int vertexIndex, INode* bone, float weight, bool clear, ReferenceTarget* mod) { - if (!mod) mod = FindPhysiqueModifier(node, 0); - if (!mod) throw MAXException("No Physique modifier was found on this node"); - - IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT); - IPhyContextImport *mcImport = (IPhyContextImport *)phyImport->GetContextInterface(node); - IPhyVertexImport *viImport = mcImport->SetVertexInterface(vertexIndex, RIGID_BLENDED_TYPE); - - int numverts = mcImport->GetNumberVertices(); - - if (!clear) //if you don't clear it check to see if it already exists - { - Tab bones = GetVertexBones(node, vertexIndex, true, true, mod); - Tab weights; - weights.ZeroCount(); - bool exists = false; - int i; - - for(i=0;iGetVertexType(); - ((IPhyBlendedRigidVertexImport*)viImport)->SetWeightedNode(bone, curWeight, tempClear); - } - } - else - { - ((IPhyBlendedRigidVertexImport*)viImport)->SetWeightedNode(bone, weight, FALSE); - } - } - else ((IPhyBlendedRigidVertexImport*)viImport)->SetWeightedNode(bone, weight, TRUE); - - mcImport->ReleaseVertexInterface(viImport); - phyImport->ReleaseContextInterface(mcImport); - mod->ReleaseInterface(I_PHYIMPORT, phyImport); + if (!mod) mod = FindPhysiqueModifier(node, 0); + if (!mod) throw MAXException("No Physique modifier was found on this node"); + + IPhysiqueImport *phyImport = (IPhysiqueImport *)mod->GetInterface(I_PHYIMPORT); + IPhyContextImport *mcImport = (IPhyContextImport *)phyImport->GetContextInterface(node); + IPhyVertexImport *viImport = mcImport->SetVertexInterface(vertexIndex, RIGID_BLENDED_TYPE); + + int numverts = mcImport->GetNumberVertices(); + + if (!clear) //if you don't clear it check to see if it already exists + { + Tab bones = GetVertexBones(node, vertexIndex, true, true, mod); + Tab weights; + weights.ZeroCount(); + bool exists = false; + int i; + + for(i=0;iGetVertexType(); + ((IPhyBlendedRigidVertexImport*)viImport)->SetWeightedNode(bone, curWeight, tempClear); + } + } + else + { + ((IPhyBlendedRigidVertexImport*)viImport)->SetWeightedNode(bone, weight, FALSE); + } + } + else ((IPhyBlendedRigidVertexImport*)viImport)->SetWeightedNode(bone, weight, TRUE); + + mcImport->ReleaseVertexInterface(viImport); + phyImport->ReleaseContextInterface(mcImport); + mod->ReleaseInterface(I_PHYIMPORT, phyImport); } diff --git a/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PublishedInterface.h b/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PublishedInterface.h index f54ae295cd2..5b76ba4c729 100644 --- a/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PublishedInterface.h +++ b/Tools/3dsmaxExport/MaxscriptExport/plugins/PhysiqueInterface_sources/PublishedInterface.h @@ -13,78 +13,78 @@ class IPhysiqueInterface : public FPStaticInterface { - public: - Modifier* FindPhysiqueModifier (INode* physiquedNode, int modIndex = 0); - BOOL CheckMatrix(INode* node, ReferenceTarget* mod); - Matrix3 GetInitialNodeTM(INode* physiquedNode, ReferenceTarget* mod = NULL); - Matrix3 GetInitialBoneTM(INode* physiquedNode, int index, ReferenceTarget* mod = NULL); - int GetBoneCount(INode* physiquedNode, ReferenceTarget* mod = NULL); - Tab GetBoneList(INode* physiquedNode, ReferenceTarget* mod = NULL); + public: + Modifier* FindPhysiqueModifier (INode* physiquedNode, int modIndex = 0); + BOOL CheckMatrix(INode* node, ReferenceTarget* mod); + Matrix3 GetInitialNodeTM(INode* physiquedNode, ReferenceTarget* mod = NULL); + Matrix3 GetInitialBoneTM(INode* physiquedNode, int index, ReferenceTarget* mod = NULL); + int GetBoneCount(INode* physiquedNode, ReferenceTarget* mod = NULL); + Tab GetBoneList(INode* physiquedNode, ReferenceTarget* mod = NULL); - int GetAPIVersion(INode* physiquedNode, ReferenceTarget* mod = NULL); + int GetAPIVersion(INode* physiquedNode, ReferenceTarget* mod = NULL); - int GetVertexCount(INode* physiquedNode, ReferenceTarget* mod = NULL); + int GetVertexCount(INode* physiquedNode, ReferenceTarget* mod = NULL); - int GetVertexType(INode* physiquedNode, int vertIndex, ReferenceTarget* mod = NULL); + int GetVertexType(INode* physiquedNode, int vertIndex, ReferenceTarget* mod = NULL); - int GetVertexBoneCount(INode* physiquedNode, int vertIndex, bool rigid = true, ReferenceTarget* mod = NULL); - Tab GetVertexBones(INode* node, int vertIndex, bool rigid, bool blending, ReferenceTarget* mod); - INode* GetVertexBone(INode* physiquedNode, int vertIndex, int boneIndex, bool rigid = true, bool blending = true, ReferenceTarget* mod = NULL); - Point3 GetVertexOffset(INode* physiquedNode, int vertIndex, int boneIndex, bool rigid = true, bool blending = true, ReferenceTarget* mod = NULL); - Point3 GetVertexDeformableOffset(INode* physiquedNode, int vertIndex, ReferenceTarget* mod = NULL, TimeValue t = 0); - float GetVertexWeight(INode* physiquedNode, int vertIndex, int boneIndex, bool rigid = true, bool blending = true, ReferenceTarget* mod = NULL); - - bool SetFigureMode(INode* physiquedNode, bool state, ReferenceTarget* mod = NULL); - bool BipedFigureMode(INode* node, bool state); - void SetInitialPose(INode* physiquedNode, bool set, ReferenceTarget* mod = NULL); + int GetVertexBoneCount(INode* physiquedNode, int vertIndex, bool rigid = true, ReferenceTarget* mod = NULL); + Tab GetVertexBones(INode* node, int vertIndex, bool rigid, bool blending, ReferenceTarget* mod); + INode* GetVertexBone(INode* physiquedNode, int vertIndex, int boneIndex, bool rigid = true, bool blending = true, ReferenceTarget* mod = NULL); + Point3 GetVertexOffset(INode* physiquedNode, int vertIndex, int boneIndex, bool rigid = true, bool blending = true, ReferenceTarget* mod = NULL); + Point3 GetVertexDeformableOffset(INode* physiquedNode, int vertIndex, ReferenceTarget* mod = NULL, TimeValue t = 0); + float GetVertexWeight(INode* physiquedNode, int vertIndex, int boneIndex, bool rigid = true, bool blending = true, ReferenceTarget* mod = NULL); + + bool SetFigureMode(INode* physiquedNode, bool state, ReferenceTarget* mod = NULL); + bool BipedFigureMode(INode* node, bool state); + void SetInitialPose(INode* physiquedNode, bool set, ReferenceTarget* mod = NULL); - bool AttachToNode(INode* physiquedNode, INode* rootNode, ReferenceTarget* mod = NULL, TimeValue t = GetCOREInterface()->GetTime()); - bool Initialize(INode* physiquedNode, INode* rootNode, ReferenceTarget* mod = NULL, TimeValue t = GetCOREInterface()->GetTime()); - - void LockVertex(INode* physiquedNode, int vertexIndex, ReferenceTarget* mod = NULL); - void UnLockVertex(INode* physiquedNode, int vertexIndex, ReferenceTarget* mod = NULL); - void SetVertexBone(INode* physiquedNode, int vertexIndex, INode* bone, float weight = 1.0f, bool clear = false, ReferenceTarget* mod = NULL); - - //function ids - enum{getAPIVersion, checkMatrix,getPhysique, - getBoneList, getBoneCount, getVertexCount, - getInitialNodeTM, getInitialBoneTM, - getVertexType, getVertexBones, getVertexBoneCount, getVertexBone, - getVertexOffset, getVertexDeformableOffset, getVertexWeight, - setInitialPose, setFigureMode, - attachToNode, initialize, lockVertex, unlockVertex, setVertexBone, - }; - //symbolic enumerator values - enum{blendingTypeEnum, interfaceTypeEnum, }; + bool AttachToNode(INode* physiquedNode, INode* rootNode, ReferenceTarget* mod = NULL, TimeValue t = GetCOREInterface()->GetTime()); + bool Initialize(INode* physiquedNode, INode* rootNode, ReferenceTarget* mod = NULL, TimeValue t = GetCOREInterface()->GetTime()); + + void LockVertex(INode* physiquedNode, int vertexIndex, ReferenceTarget* mod = NULL); + void UnLockVertex(INode* physiquedNode, int vertexIndex, ReferenceTarget* mod = NULL); + void SetVertexBone(INode* physiquedNode, int vertexIndex, INode* bone, float weight = 1.0f, bool clear = false, ReferenceTarget* mod = NULL); + + //function ids + enum{getAPIVersion, checkMatrix,getPhysique, + getBoneList, getBoneCount, getVertexCount, + getInitialNodeTM, getInitialBoneTM, + getVertexType, getVertexBones, getVertexBoneCount, getVertexBone, + getVertexOffset, getVertexDeformableOffset, getVertexWeight, + setInitialPose, setFigureMode, + attachToNode, initialize, lockVertex, unlockVertex, setVertexBone, + }; + //symbolic enumerator values + enum{blendingTypeEnum, interfaceTypeEnum, }; - DECLARE_DESCRIPTOR(IPhysiqueInterface); + DECLARE_DESCRIPTOR(IPhysiqueInterface); - BEGIN_FUNCTION_MAP - FN_2(getPhysique, TYPE_REFTARG, FindPhysiqueModifier, TYPE_INODE, TYPE_INDEX); - FN_2(checkMatrix,TYPE_BOOL,CheckMatrix,TYPE_INODE,TYPE_REFTARG); - FN_2(getInitialNodeTM, TYPE_MATRIX3_BV, GetInitialNodeTM, TYPE_INODE, TYPE_REFTARG); - FN_3(getInitialBoneTM, TYPE_MATRIX3_BV, GetInitialBoneTM, TYPE_INODE, TYPE_INDEX, TYPE_REFTARG); - FN_2(getBoneCount, TYPE_INT, GetBoneCount, TYPE_INODE, TYPE_REFTARG); - FN_2(getBoneList, TYPE_INODE_TAB_BV, GetBoneList, TYPE_INODE, TYPE_REFTARG); - FN_2(getAPIVersion, TYPE_INT, GetAPIVersion, TYPE_INODE, TYPE_REFTARG); - VFN_3(setInitialPose, SetInitialPose, TYPE_INODE, TYPE_bool, TYPE_REFTARG); - - FN_2(getVertexCount, TYPE_INT, GetVertexCount, TYPE_INODE, TYPE_REFTARG); - FN_3(getVertexType, TYPE_ENUM, GetVertexType, TYPE_INODE, TYPE_INDEX, TYPE_REFTARG); - FN_4(getVertexBoneCount, TYPE_INT, GetVertexBoneCount, TYPE_INODE, TYPE_INDEX, TYPE_bool, TYPE_REFTARG); - FN_5(getVertexBones, TYPE_INODE_TAB_BV, GetVertexBones, TYPE_INODE, TYPE_INDEX, TYPE_bool, TYPE_bool, TYPE_REFTARG); - FN_6(getVertexBone, TYPE_INODE, GetVertexBone, TYPE_INODE, TYPE_INDEX, TYPE_INDEX, TYPE_bool, TYPE_bool, TYPE_REFTARG); - FN_6(getVertexOffset, TYPE_POINT3_BV, GetVertexOffset, TYPE_INODE, TYPE_INDEX, TYPE_INDEX, TYPE_bool, TYPE_bool, TYPE_REFTARG); - FNT_3(getVertexDeformableOffset, TYPE_POINT3_BV, GetVertexDeformableOffset, TYPE_INODE, TYPE_INDEX, TYPE_REFTARG); - FN_6(getVertexWeight, TYPE_FLOAT, GetVertexWeight, TYPE_INODE, TYPE_INDEX, TYPE_INDEX, TYPE_bool, TYPE_bool, TYPE_REFTARG); + BEGIN_FUNCTION_MAP + FN_2(getPhysique, TYPE_REFTARG, FindPhysiqueModifier, TYPE_INODE, TYPE_INDEX); + FN_2(checkMatrix,TYPE_BOOL,CheckMatrix,TYPE_INODE,TYPE_REFTARG); + FN_2(getInitialNodeTM, TYPE_MATRIX3_BV, GetInitialNodeTM, TYPE_INODE, TYPE_REFTARG); + FN_3(getInitialBoneTM, TYPE_MATRIX3_BV, GetInitialBoneTM, TYPE_INODE, TYPE_INDEX, TYPE_REFTARG); + FN_2(getBoneCount, TYPE_INT, GetBoneCount, TYPE_INODE, TYPE_REFTARG); + FN_2(getBoneList, TYPE_INODE_TAB_BV, GetBoneList, TYPE_INODE, TYPE_REFTARG); + FN_2(getAPIVersion, TYPE_INT, GetAPIVersion, TYPE_INODE, TYPE_REFTARG); + VFN_3(setInitialPose, SetInitialPose, TYPE_INODE, TYPE_bool, TYPE_REFTARG); + + FN_2(getVertexCount, TYPE_INT, GetVertexCount, TYPE_INODE, TYPE_REFTARG); + FN_3(getVertexType, TYPE_ENUM, GetVertexType, TYPE_INODE, TYPE_INDEX, TYPE_REFTARG); + FN_4(getVertexBoneCount, TYPE_INT, GetVertexBoneCount, TYPE_INODE, TYPE_INDEX, TYPE_bool, TYPE_REFTARG); + FN_5(getVertexBones, TYPE_INODE_TAB_BV, GetVertexBones, TYPE_INODE, TYPE_INDEX, TYPE_bool, TYPE_bool, TYPE_REFTARG); + FN_6(getVertexBone, TYPE_INODE, GetVertexBone, TYPE_INODE, TYPE_INDEX, TYPE_INDEX, TYPE_bool, TYPE_bool, TYPE_REFTARG); + FN_6(getVertexOffset, TYPE_POINT3_BV, GetVertexOffset, TYPE_INODE, TYPE_INDEX, TYPE_INDEX, TYPE_bool, TYPE_bool, TYPE_REFTARG); + FNT_3(getVertexDeformableOffset, TYPE_POINT3_BV, GetVertexDeformableOffset, TYPE_INODE, TYPE_INDEX, TYPE_REFTARG); + FN_6(getVertexWeight, TYPE_FLOAT, GetVertexWeight, TYPE_INODE, TYPE_INDEX, TYPE_INDEX, TYPE_bool, TYPE_bool, TYPE_REFTARG); - FN_3(setFigureMode, TYPE_bool, SetFigureMode, TYPE_INODE, TYPE_bool, TYPE_REFTARG); - FNT_3(attachToNode, TYPE_bool, AttachToNode, TYPE_INODE, TYPE_INODE, TYPE_REFTARG); - FNT_3(initialize, TYPE_bool, Initialize, TYPE_INODE, TYPE_INODE, TYPE_REFTARG); - VFN_3(lockVertex, LockVertex, TYPE_INODE, TYPE_INDEX, TYPE_REFTARG); - VFN_3(unlockVertex, UnLockVertex, TYPE_INODE, TYPE_INDEX, TYPE_REFTARG); - VFN_6(setVertexBone, SetVertexBone, TYPE_INODE, TYPE_INDEX, TYPE_INODE, TYPE_FLOAT, TYPE_bool, TYPE_REFTARG); - END_FUNCTION_MAP + FN_3(setFigureMode, TYPE_bool, SetFigureMode, TYPE_INODE, TYPE_bool, TYPE_REFTARG); + FNT_3(attachToNode, TYPE_bool, AttachToNode, TYPE_INODE, TYPE_INODE, TYPE_REFTARG); + FNT_3(initialize, TYPE_bool, Initialize, TYPE_INODE, TYPE_INODE, TYPE_REFTARG); + VFN_3(lockVertex, LockVertex, TYPE_INODE, TYPE_INDEX, TYPE_REFTARG); + VFN_3(unlockVertex, UnLockVertex, TYPE_INODE, TYPE_INDEX, TYPE_REFTARG); + VFN_6(setVertexBone, SetVertexBone, TYPE_INODE, TYPE_INDEX, TYPE_INODE, TYPE_FLOAT, TYPE_bool, TYPE_REFTARG); + END_FUNCTION_MAP }; #endif //__IPHYSIQUEINTERFACE__H \ No newline at end of file diff --git a/Tools/3dsmaxExport/OgreExport/include/OgreExport.h b/Tools/3dsmaxExport/OgreExport/include/OgreExport.h index a817eb6b7c6..6a199aee043 100644 --- a/Tools/3dsmaxExport/OgreExport/include/OgreExport.h +++ b/Tools/3dsmaxExport/OgreExport/include/OgreExport.h @@ -50,206 +50,206 @@ inline void enableControl(HWND dlg, INT id) { EnableWindow(GetDlgItem(dlg, id), class OgreMaxExport_TabPaneHandler { public: - HWND getDialogHandle() { return m_hDlg; } - void setExportInterface(ExpInterface* ei, Interface* i) { m_ei = ei; m_i = i; } - virtual void onInitDialog(HWND hDlg) { m_hDlg = hDlg; } - virtual void update() = 0; + HWND getDialogHandle() { return m_hDlg; } + void setExportInterface(ExpInterface* ei, Interface* i) { m_ei = ei; m_i = i; } + virtual void onInitDialog(HWND hDlg) { m_hDlg = hDlg; } + virtual void update() = 0; protected: - HWND m_hDlg; - ExpInterface* m_ei; - Interface* m_i; + HWND m_hDlg; + ExpInterface* m_ei; + Interface* m_i; }; class OgreMaxExport_General : public OgreMaxExport_TabPaneHandler { - // this contains the switch/case statement that fires the events that this class handles - friend INT_PTR CALLBACK GeneralTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + // this contains the switch/case statement that fires the events that this class handles + friend INT_PTR CALLBACK GeneralTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); public: - // config holds all of the settings - OgreMaxExport_General(OgreMax::Config& config, OgreMaxExport* e) : m_config(config), m_exp(e) { } - virtual ~OgreMaxExport_General() {} + // config holds all of the settings + OgreMaxExport_General(OgreMax::Config& config, OgreMaxExport* e) : m_config(config), m_exp(e) { } + virtual ~OgreMaxExport_General() {} - // all dialog handlers need to do this -- on demand, read data from their panes - void update(); + // all dialog handlers need to do this -- on demand, read data from their panes + void update(); - // all dialog handlers need to catch the WM_DESTROY message too - void onDestroy(); + // all dialog handlers need to catch the WM_DESTROY message too + void onDestroy(); - // event handlers - void onInitDialog(HWND hDlg); - void onExportDirectoryChanged(const std::string& newDirectory); - void onInvertYZ(bool checked); - void onSetScale(float newScale); + // event handlers + void onInitDialog(HWND hDlg); + void onExportDirectoryChanged(const std::string& newDirectory); + void onInvertYZ(bool checked); + void onSetScale(float newScale); private: - OgreMax::Config& m_config; - OgreMaxExport* m_exp; + OgreMax::Config& m_config; + OgreMaxExport* m_exp; }; class OgreMaxExport_Mesh : public OgreMaxExport_TabPaneHandler { - // this contains the switch/case statement that fires the events that this class handles - friend INT_PTR CALLBACK MeshTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + // this contains the switch/case statement that fires the events that this class handles + friend INT_PTR CALLBACK MeshTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); public: - // config holds all of the settings - OgreMaxExport_Mesh(OgreMax::Config& config, OgreMaxExport* e) : m_config(config), m_exp(e) { } - virtual ~OgreMaxExport_Mesh() {} + // config holds all of the settings + OgreMaxExport_Mesh(OgreMax::Config& config, OgreMaxExport* e) : m_config(config), m_exp(e) { } + virtual ~OgreMaxExport_Mesh() {} - // all dialog handlers need to do this -- on demand, read data from their panes - void update(); + // all dialog handlers need to do this -- on demand, read data from their panes + void update(); - // all dialog handlers need to catch the WM_DESTROY message too - void onDestroy(); + // all dialog handlers need to catch the WM_DESTROY message too + void onDestroy(); - // event handlers - void onInitDialog(HWND hDlg); - void onClickBinaryMesh(); + // event handlers + void onInitDialog(HWND hDlg); + void onClickBinaryMesh(); protected: - // internal utils - void setControlStates(); + // internal utils + void setControlStates(); private: - OgreMax::Config& m_config; - OgreMaxExport* m_exp; + OgreMax::Config& m_config; + OgreMaxExport* m_exp; }; class OgreMaxExport_SkeletalAnimation : public OgreMaxExport_TabPaneHandler { - // this contains the switch/case statement that fires the events that this class handles - friend INT_PTR CALLBACK SkeletalAnimationTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + // this contains the switch/case statement that fires the events that this class handles + friend INT_PTR CALLBACK SkeletalAnimationTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); public: - // config holds all of the settings - OgreMaxExport_SkeletalAnimation(OgreMax::Config& config, OgreMaxExport* e) : m_config(config), m_exp(e) { } - virtual ~OgreMaxExport_SkeletalAnimation() {} + // config holds all of the settings + OgreMaxExport_SkeletalAnimation(OgreMax::Config& config, OgreMaxExport* e) : m_config(config), m_exp(e) { } + virtual ~OgreMaxExport_SkeletalAnimation() {} - // all dialog handlers need to do this -- on demand, read data from their panes - void update(); + // all dialog handlers need to do this -- on demand, read data from their panes + void update(); - // all dialog handlers need to catch the WM_DESTROY message too - void onDestroy(); + // all dialog handlers need to catch the WM_DESTROY message too + void onDestroy(); - // event handlers - void onInitDialog(HWND hDlg); - void onAddAnimation(); - void onDeleteAnimation(); + // event handlers + void onInitDialog(HWND hDlg); + void onAddAnimation(); + void onDeleteAnimation(); protected: - // utility methods - void addAnimation(); - void deleteAnimation(); + // utility methods + void addAnimation(); + void deleteAnimation(); private: - OgreMax::Config& m_config; - OgreMaxExport* m_exp; + OgreMax::Config& m_config; + OgreMaxExport* m_exp; }; class OgreMaxExport_VertexAnimation : public OgreMaxExport_TabPaneHandler { - // this contains the switch/case statement that fires the events that this class handles - friend INT_PTR CALLBACK VertexAnimationTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + // this contains the switch/case statement that fires the events that this class handles + friend INT_PTR CALLBACK VertexAnimationTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); public: - // config holds all of the settings - OgreMaxExport_VertexAnimation(OgreMax::Config& config, OgreMaxExport* e) : m_config(config), m_exp(e) { } - virtual ~OgreMaxExport_VertexAnimation() {} + // config holds all of the settings + OgreMaxExport_VertexAnimation(OgreMax::Config& config, OgreMaxExport* e) : m_config(config), m_exp(e) { } + virtual ~OgreMaxExport_VertexAnimation() {} - // all dialog handlers need to do this -- on demand, read data from their panes - void update(); + // all dialog handlers need to do this -- on demand, read data from their panes + void update(); - // all dialog handlers need to catch the WM_DESTROY message too - void onDestroy(); + // all dialog handlers need to catch the WM_DESTROY message too + void onDestroy(); - // event handlers - void onInitDialog(HWND hDlg); + // event handlers + void onInitDialog(HWND hDlg); private: - OgreMax::Config& m_config; - OgreMaxExport* m_exp; + OgreMax::Config& m_config; + OgreMaxExport* m_exp; }; class OgreMaxExport_Material : public OgreMaxExport_TabPaneHandler { - // this contains the switch/case statement that fires the events that this class handles - friend INT_PTR CALLBACK MaterialTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + // this contains the switch/case statement that fires the events that this class handles + friend INT_PTR CALLBACK MaterialTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); public: - // config holds all of the settings - OgreMaxExport_Material(OgreMax::Config& config, OgreMaxExport* e) : m_config(config), m_exp(e) { } - virtual ~OgreMaxExport_Material() {} + // config holds all of the settings + OgreMaxExport_Material(OgreMax::Config& config, OgreMaxExport* e) : m_config(config), m_exp(e) { } + virtual ~OgreMaxExport_Material() {} - // all dialog handlers need to do this -- on demand, read data from their panes - void update(); + // all dialog handlers need to do this -- on demand, read data from their panes + void update(); - // all dialog handlers need to catch the WM_DESTROY message too - void onDestroy(); + // all dialog handlers need to catch the WM_DESTROY message too + void onDestroy(); - // event handlers - void onInitDialog(HWND hDlg); + // event handlers + void onInitDialog(HWND hDlg); private: - OgreMax::Config& m_config; - OgreMaxExport* m_exp; + OgreMax::Config& m_config; + OgreMaxExport* m_exp; }; class OgreMaxExport : public SceneExport { - friend INT_PTR CALLBACK ExportPropertiesDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); - friend class OgreMaxExport_General; - friend class OgreMaxExport_Mesh; - friend class OgreMaxExport_SkeletalAnimation; - friend class OgreMaxExport_VertexAnimation; - friend class OgreMaxExport_Material; + friend INT_PTR CALLBACK ExportPropertiesDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + friend class OgreMaxExport_General; + friend class OgreMaxExport_Mesh; + friend class OgreMaxExport_SkeletalAnimation; + friend class OgreMaxExport_VertexAnimation; + friend class OgreMaxExport_Material; public: - OgreMaxExport(HINSTANCE hInst); - virtual ~OgreMaxExport(); - virtual int ExtCount(); // Number of extemsions supported - virtual const TCHAR * Ext(int n); // Extension #n (i.e. "3DS") - virtual const TCHAR * LongDesc(); // Long ASCII description (i.e. "Autodesk 3D Studio File") - virtual const TCHAR * ShortDesc(); // Short ASCII description (i.e. "3D Studio") - virtual const TCHAR * AuthorName(); // ASCII Author name - virtual const TCHAR * CopyrightMessage(); // ASCII Copyright message - virtual const TCHAR * OtherMessage1(); // Other message #1 - virtual const TCHAR * OtherMessage2(); // Other message #2 - virtual unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301) - virtual void ShowAbout(HWND hWnd); // Show DLL's "About..." box - virtual int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0); // Export file - virtual BOOL SupportsOptions(int ext, DWORD options); // Returns TRUE if all option bits set are supported for this extension + OgreMaxExport(HINSTANCE hInst); + virtual ~OgreMaxExport(); + virtual int ExtCount(); // Number of extemsions supported + virtual const TCHAR * Ext(int n); // Extension #n (i.e. "3DS") + virtual const TCHAR * LongDesc(); // Long ASCII description (i.e. "Autodesk 3D Studio File") + virtual const TCHAR * ShortDesc(); // Short ASCII description (i.e. "3D Studio") + virtual const TCHAR * AuthorName(); // ASCII Author name + virtual const TCHAR * CopyrightMessage(); // ASCII Copyright message + virtual const TCHAR * OtherMessage1(); // Other message #1 + virtual const TCHAR * OtherMessage2(); // Other message #2 + virtual unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301) + virtual void ShowAbout(HWND hWnd); // Show DLL's "About..." box + virtual int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0); // Export file + virtual BOOL SupportsOptions(int ext, DWORD options); // Returns TRUE if all option bits set are supported for this extension protected: - OgreMax::Config m_config; - OgreMax::MaterialMap m_materialMap; - - HINSTANCE m_hInstance; - HWND m_hWndDlgExport; - OgreMaxExport_TabPaneHandler* m_tabDisplay; - - // Export implementations - OgreMax::MeshExporter m_meshExporter; - OgreMax::MeshXMLExporter m_meshXMLExporter; - OgreMax::MaterialExporter m_materialExporter; - - // Property Page Dialog Handlers - OgreMaxExport_General m_tabGeneral; - OgreMaxExport_Mesh m_tabMesh; - OgreMaxExport_SkeletalAnimation m_tabSkeletalAnimation; - OgreMaxExport_VertexAnimation m_tabVertexAnimation; - OgreMaxExport_Material m_tabMaterial; - - // utility methods - BOOL setupExportProperties(); - bool export(); - - // properties page message handlers - void onTabSelectChange(HWND hTabControl, INT iTabId); + OgreMax::Config m_config; + OgreMax::MaterialMap m_materialMap; + + HINSTANCE m_hInstance; + HWND m_hWndDlgExport; + OgreMaxExport_TabPaneHandler* m_tabDisplay; + + // Export implementations + OgreMax::MeshExporter m_meshExporter; + OgreMax::MeshXMLExporter m_meshXMLExporter; + OgreMax::MaterialExporter m_materialExporter; + + // Property Page Dialog Handlers + OgreMaxExport_General m_tabGeneral; + OgreMaxExport_Mesh m_tabMesh; + OgreMaxExport_SkeletalAnimation m_tabSkeletalAnimation; + OgreMaxExport_VertexAnimation m_tabVertexAnimation; + OgreMaxExport_Material m_tabMaterial; + + // utility methods + BOOL setupExportProperties(); + bool export(); + + // properties page message handlers + void onTabSelectChange(HWND hTabControl, INT iTabId); }; class OgreMaxExportClassDesc : public ClassDesc { public: - int IsPublic(); - void * Create(BOOL loading = FALSE); - const TCHAR * ClassName(); - SClass_ID SuperClassID(); - Class_ID ClassID(); - const TCHAR* Category(); + int IsPublic(); + void * Create(BOOL loading = FALSE); + const TCHAR * ClassName(); + SClass_ID SuperClassID(); + Class_ID ClassID(); + const TCHAR* Category(); }; diff --git a/Tools/3dsmaxExport/OgreExport/include/OgreMaxConfig.h b/Tools/3dsmaxExport/OgreExport/include/OgreMaxConfig.h index ef0e9aaddcf..22c9da7b18d 100644 --- a/Tools/3dsmaxExport/OgreExport/include/OgreMaxConfig.h +++ b/Tools/3dsmaxExport/OgreExport/include/OgreMaxConfig.h @@ -6,240 +6,240 @@ namespace OgreMax { - const int NAME_MAX_LEN = 256; - const int MAX_PATH = 260; // same as Windows -- no point in including windows.h for that - const unsigned int CURRENTVERSION = 2; - - typedef enum { - DIRECT3D = 0, - OPENGL - } VertexColourFormat; - - typedef enum { - NATIVE = 0, - BIG, - LITTLE - } Endian; - - typedef enum { - UV, - VW, - WU - } Tex2D; - - - // class for managing exporter configuration data - class Config - { - public: - Config(); - Config(const Config& config); // copy c'tor - virtual ~Config(); - - // serialization - void save(); - void load(); - - // assignment operator - Config& operator=(const Config& rhs); - - // - // General Exporter Settings - // - // exporting one file per object or putting all objects as submeshes in a single file - void setExportMultipleFiles(bool exportMultipleFiles); - bool getExportMultipleFiles() const { return m_exportMultipleFiles; } - - // exporting one file per object or putting all objects as submeshes in a single file - void setUseSingleSkeleton(bool singleSkeleton); - bool getUseSingleSkeleton() const { return m_useSingleSkeleton; } - - // enable skeleton file export - void setExportSkeleton(bool useSkeleton); - bool getExportSkeleton() const { return m_exportSkeleton; } - - // enable material file export - void setExportMaterial(bool exportMaterial); - bool getExportMaterial() const { return m_exportMaterial; } - - // enable mesh binary file export - void setExportBinaryMesh(bool export); - bool getExportBinaryMesh() const { return m_exportBinaryMesh; } - - // enable mesh XML file export - void setExportXMLMesh(bool export); - bool getExportXMLMesh() const { return m_exportXMLMesh; } - - // enable vertex color export - void setExportVertexColours(bool exportVC); - bool getExportVertexColours() const { return m_exportVertexColors; } - - // rebuild normals on export - void setRebuildNormals(bool rebuild); - bool getRebuildNormals() const { return m_rebuildNormals; } - - // invert normals on export - void setInvertNormals(bool invert); - bool getInvertNormals() const { return m_invertNormals; } - - // invert Y and Z on export (rotate 90 in other words) - void setInvertYZ(bool invert); - bool getInvertYZ() const { return m_flipYZ; } - - // default material name to use when none is provided for a mesh - void setDefaultMaterialName(const std::string& materialName); - const std::string& getDefaultMaterialName() const { return m_defaultMaterialName; } - - // set scale to use when exporting - void setScale(float scale); - float getScale() const { return m_scale; } - - // set fps to use when sampling keyframes - void setFPS(float fps); - float getFPS() const { return m_fps; } - - // set fps to use when sampling keyframes - void setTexCoord2D(Tex2D texCoord); - Tex2D getTexCoord2D() const { return m_2DTexCoord; } - - // export directory - void setExportPath(const std::string& path); - const std::string& getExportPath() const { return m_exportPath; } - - // export filename - void setExportFilename(const std::string& name); - const std::string& getExportFilename() const { return m_exportFilename; } - - // export basename -- this is read-only, based on the filename the user set coming in - const std::string& getExportBasename() const { return m_exportBasename; } - - // material filename - void setMaterialFilename(const std::string& filename); - const std::string& getMaterialFilename() const { return m_materialFilename; } - - // skeleton filename - void setSkeletonFilename(const std::string& filename); - const std::string& getSkeletonFilename() const { return m_skeletonFilename; } - - // - // Binary mesh export settings - // - // tangent vector generation - void setGenerateTangents(bool generateTangents); - bool getGenerateTangents() const { return m_generateTangents; } - - // automatic LoD generation - void setGenerateLod(bool generateLod); - bool getGenerateLod() const { return m_generateLod; } - - // edge lists - void setBuildEdgeLists(bool buildEdgeLists); - bool getBuildEdgeLists() const { return m_edgeLists; } - - // optimize layout - void setOptmizeBinaryMesh(bool optimize); - bool getOptmizeBinaryMesh() const { return m_optimizeBinaryLayout; } - - // vertex colour format - void setVertexColourFormat(VertexColourFormat format); - VertexColourFormat getVertexColourFormat() const { return m_colourFormat; } - - // endianness - void setEndian(Endian endian); - Endian getEndian() const { return m_endian; } - - // number of LoD levels - void setNumLodLevels(unsigned int levels); - unsigned int getNumLodLevels() const { return m_numLodLevels; } - - // LoD distance - void setLodDistance(float distance); - float getLodDistance() const { return m_lodDistance; } - - // LoD percent reduction - void setLodPercentReduction(float percent); - float getLodPercentReduction() const { return m_lodPercent; } - - // LoD vertex reduction - void setLodVertexReduction(int count); - int getLodVertexReduction() const { return m_lodVertexCount; } - - // export only selected or all objects - void setExportSelected(bool selected); - bool getExportSelected() const { return m_exportSelectedObjects; } - - // - // version 2 - // - // merge meshes based on material likeness - void setMergeMeshes(bool merge); - bool getMergeMeshes() const { return m_mergeMeshes; } - - private: - - // config file version number -- use this to tell if new features are saved in the file or not. - // Version 1 was a basic XML exporter (mesh, material and Biped animation skeleton) - unsigned int m_version; - - // general exporter settings - bool m_exportMultipleFiles; // export subobjects to multiple mesh or XML files - bool m_useSingleSkeleton; // use a single skeleton file when exporting multiple mesh files - bool m_exportSkeleton; // export skeleton file for skeletal animation - bool m_rebuildNormals; // rebuild mesh normals prior to export - bool m_exportMaterial; // alernate is to use default material - bool m_invertNormals; // flip normals in the mesh on export - bool m_flipYZ; // flip the "up" axis to/from Z and Y - bool m_exportVertexColors; // export vertex colors - float m_scale; // scale to use when exporting - float m_fps; // default keyframe sampling rate - Tex2D m_2DTexCoord; // interpretation of 2D texture coordinates (UV, VW, WU) - - // XML mesh settings - bool m_exportXMLMesh; - - // binary mesh settings - bool m_exportBinaryMesh; // enable binary mesh export - bool m_optimizeBinaryLayout; // enable binary mesh layout optimization - bool m_generateTangents; // generate tangents (normal/offset mapping) - bool m_generateLod; // generate LoD meshes automatically - bool m_edgeLists; // build edge lists (shadow volumes) - float m_lodDistance; // distance increment per LoD level - unsigned int m_numLodLevels; // number of LoD meshes to generate - float m_lodPercent; // if > 0.0, decimate on a percentage reduction basis - int m_lodVertexCount; // if > 0, decimate on a vertex count reduction basis - VertexColourFormat m_colourFormat; // Direct3D or OpenGL - Endian m_endian; // Native, Big or Little - - - TCHAR m_bufDefaultMaterialName[NAME_MAX_LEN]; // actual buffer written when config saved to disk - TCHAR m_bufExportPath[MAX_PATH]; // actual buffer written when config saved to disk - TCHAR m_bufExportBasename[NAME_MAX_LEN]; // actual buffer written when config saved to disk - TCHAR m_bufExportFilename[NAME_MAX_LEN]; // actual buffer written when config saved to disk - TCHAR m_bufMaterialFilename[NAME_MAX_LEN]; // actual buffer written when config saved to disk - TCHAR m_bufSkeletonFilename[NAME_MAX_LEN]; // actual buffer written when config saved to disk - - - // add new version data after this point - - // version 2 -- added mesh merge capability - bool m_mergeMeshes; // merge submeshes into single mesh based on material likeness - - - // since we are doing a new-in-place type of config save/load (because I'm lazy) we can't write these to disk, and - // instead have to "fix" them up on config load and write them out to the buffers above on save. These are used, however, - // for the convenience of the setter/getters in the class. - std::string m_defaultMaterialName; // default material name to use when none is provided for a mesh - std::string m_exportPath; // path to contain exported files - std::string m_exportFilename; // exported base filename - std::string m_exportBasename; // exported base filename, sans extension - std::string m_materialFilename; // exported material filename - std::string m_skeletonFilename; // exported skeleton filename (for shared skeleton export) - - // we can also track temporary info that we do not want to save in the config file, but want to pass around in - // the config object - bool m_exportSelectedObjects; // true = export only selected objects, false = export all objects - - }; + const int NAME_MAX_LEN = 256; + const int MAX_PATH = 260; // same as Windows -- no point in including windows.h for that + const unsigned int CURRENTVERSION = 2; + + typedef enum { + DIRECT3D = 0, + OPENGL + } VertexColourFormat; + + typedef enum { + NATIVE = 0, + BIG, + LITTLE + } Endian; + + typedef enum { + UV, + VW, + WU + } Tex2D; + + + // class for managing exporter configuration data + class Config + { + public: + Config(); + Config(const Config& config); // copy c'tor + virtual ~Config(); + + // serialization + void save(); + void load(); + + // assignment operator + Config& operator=(const Config& rhs); + + // + // General Exporter Settings + // + // exporting one file per object or putting all objects as submeshes in a single file + void setExportMultipleFiles(bool exportMultipleFiles); + bool getExportMultipleFiles() const { return m_exportMultipleFiles; } + + // exporting one file per object or putting all objects as submeshes in a single file + void setUseSingleSkeleton(bool singleSkeleton); + bool getUseSingleSkeleton() const { return m_useSingleSkeleton; } + + // enable skeleton file export + void setExportSkeleton(bool useSkeleton); + bool getExportSkeleton() const { return m_exportSkeleton; } + + // enable material file export + void setExportMaterial(bool exportMaterial); + bool getExportMaterial() const { return m_exportMaterial; } + + // enable mesh binary file export + void setExportBinaryMesh(bool export); + bool getExportBinaryMesh() const { return m_exportBinaryMesh; } + + // enable mesh XML file export + void setExportXMLMesh(bool export); + bool getExportXMLMesh() const { return m_exportXMLMesh; } + + // enable vertex color export + void setExportVertexColours(bool exportVC); + bool getExportVertexColours() const { return m_exportVertexColors; } + + // rebuild normals on export + void setRebuildNormals(bool rebuild); + bool getRebuildNormals() const { return m_rebuildNormals; } + + // invert normals on export + void setInvertNormals(bool invert); + bool getInvertNormals() const { return m_invertNormals; } + + // invert Y and Z on export (rotate 90 in other words) + void setInvertYZ(bool invert); + bool getInvertYZ() const { return m_flipYZ; } + + // default material name to use when none is provided for a mesh + void setDefaultMaterialName(const std::string& materialName); + const std::string& getDefaultMaterialName() const { return m_defaultMaterialName; } + + // set scale to use when exporting + void setScale(float scale); + float getScale() const { return m_scale; } + + // set fps to use when sampling keyframes + void setFPS(float fps); + float getFPS() const { return m_fps; } + + // set fps to use when sampling keyframes + void setTexCoord2D(Tex2D texCoord); + Tex2D getTexCoord2D() const { return m_2DTexCoord; } + + // export directory + void setExportPath(const std::string& path); + const std::string& getExportPath() const { return m_exportPath; } + + // export filename + void setExportFilename(const std::string& name); + const std::string& getExportFilename() const { return m_exportFilename; } + + // export basename -- this is read-only, based on the filename the user set coming in + const std::string& getExportBasename() const { return m_exportBasename; } + + // material filename + void setMaterialFilename(const std::string& filename); + const std::string& getMaterialFilename() const { return m_materialFilename; } + + // skeleton filename + void setSkeletonFilename(const std::string& filename); + const std::string& getSkeletonFilename() const { return m_skeletonFilename; } + + // + // Binary mesh export settings + // + // tangent vector generation + void setGenerateTangents(bool generateTangents); + bool getGenerateTangents() const { return m_generateTangents; } + + // automatic LoD generation + void setGenerateLod(bool generateLod); + bool getGenerateLod() const { return m_generateLod; } + + // edge lists + void setBuildEdgeLists(bool buildEdgeLists); + bool getBuildEdgeLists() const { return m_edgeLists; } + + // optimize layout + void setOptmizeBinaryMesh(bool optimize); + bool getOptmizeBinaryMesh() const { return m_optimizeBinaryLayout; } + + // vertex colour format + void setVertexColourFormat(VertexColourFormat format); + VertexColourFormat getVertexColourFormat() const { return m_colourFormat; } + + // endianness + void setEndian(Endian endian); + Endian getEndian() const { return m_endian; } + + // number of LoD levels + void setNumLodLevels(unsigned int levels); + unsigned int getNumLodLevels() const { return m_numLodLevels; } + + // LoD distance + void setLodDistance(float distance); + float getLodDistance() const { return m_lodDistance; } + + // LoD percent reduction + void setLodPercentReduction(float percent); + float getLodPercentReduction() const { return m_lodPercent; } + + // LoD vertex reduction + void setLodVertexReduction(int count); + int getLodVertexReduction() const { return m_lodVertexCount; } + + // export only selected or all objects + void setExportSelected(bool selected); + bool getExportSelected() const { return m_exportSelectedObjects; } + + // + // version 2 + // + // merge meshes based on material likeness + void setMergeMeshes(bool merge); + bool getMergeMeshes() const { return m_mergeMeshes; } + + private: + + // config file version number -- use this to tell if new features are saved in the file or not. + // Version 1 was a basic XML exporter (mesh, material and Biped animation skeleton) + unsigned int m_version; + + // general exporter settings + bool m_exportMultipleFiles; // export subobjects to multiple mesh or XML files + bool m_useSingleSkeleton; // use a single skeleton file when exporting multiple mesh files + bool m_exportSkeleton; // export skeleton file for skeletal animation + bool m_rebuildNormals; // rebuild mesh normals prior to export + bool m_exportMaterial; // alernate is to use default material + bool m_invertNormals; // flip normals in the mesh on export + bool m_flipYZ; // flip the "up" axis to/from Z and Y + bool m_exportVertexColors; // export vertex colors + float m_scale; // scale to use when exporting + float m_fps; // default keyframe sampling rate + Tex2D m_2DTexCoord; // interpretation of 2D texture coordinates (UV, VW, WU) + + // XML mesh settings + bool m_exportXMLMesh; + + // binary mesh settings + bool m_exportBinaryMesh; // enable binary mesh export + bool m_optimizeBinaryLayout; // enable binary mesh layout optimization + bool m_generateTangents; // generate tangents (normal/offset mapping) + bool m_generateLod; // generate LoD meshes automatically + bool m_edgeLists; // build edge lists (shadow volumes) + float m_lodDistance; // distance increment per LoD level + unsigned int m_numLodLevels; // number of LoD meshes to generate + float m_lodPercent; // if > 0.0, decimate on a percentage reduction basis + int m_lodVertexCount; // if > 0, decimate on a vertex count reduction basis + VertexColourFormat m_colourFormat; // Direct3D or OpenGL + Endian m_endian; // Native, Big or Little + + + TCHAR m_bufDefaultMaterialName[NAME_MAX_LEN]; // actual buffer written when config saved to disk + TCHAR m_bufExportPath[MAX_PATH]; // actual buffer written when config saved to disk + TCHAR m_bufExportBasename[NAME_MAX_LEN]; // actual buffer written when config saved to disk + TCHAR m_bufExportFilename[NAME_MAX_LEN]; // actual buffer written when config saved to disk + TCHAR m_bufMaterialFilename[NAME_MAX_LEN]; // actual buffer written when config saved to disk + TCHAR m_bufSkeletonFilename[NAME_MAX_LEN]; // actual buffer written when config saved to disk + + + // add new version data after this point + + // version 2 -- added mesh merge capability + bool m_mergeMeshes; // merge submeshes into single mesh based on material likeness + + + // since we are doing a new-in-place type of config save/load (because I'm lazy) we can't write these to disk, and + // instead have to "fix" them up on config load and write them out to the buffers above on save. These are used, however, + // for the convenience of the setter/getters in the class. + std::string m_defaultMaterialName; // default material name to use when none is provided for a mesh + std::string m_exportPath; // path to contain exported files + std::string m_exportFilename; // exported base filename + std::string m_exportBasename; // exported base filename, sans extension + std::string m_materialFilename; // exported material filename + std::string m_skeletonFilename; // exported skeleton filename (for shared skeleton export) + + // we can also track temporary info that we do not want to save in the config file, but want to pass around in + // the config object + bool m_exportSelectedObjects; // true = export only selected objects, false = export all objects + + }; } diff --git a/Tools/3dsmaxExport/OgreExport/include/OgreMaxExport.h b/Tools/3dsmaxExport/OgreExport/include/OgreMaxExport.h index 7f268373a27..4d93e834024 100644 --- a/Tools/3dsmaxExport/OgreExport/include/OgreMaxExport.h +++ b/Tools/3dsmaxExport/OgreExport/include/OgreMaxExport.h @@ -6,21 +6,21 @@ class Interface; namespace OgreMax { - class Config; + class Config; - class OgreMaxExporter { - public: - OgreMaxExporter(const Config& config) : m_config(config) {} + class OgreMaxExporter { + public: + OgreMaxExporter(const Config& config) : m_config(config) {} - void setMaxInterface(ExpInterface* ei, Interface* i) { m_ei = ei; m_i = i; } + void setMaxInterface(ExpInterface* ei, Interface* i) { m_ei = ei; m_i = i; } - protected: - // configuration data - const Config& m_config; + protected: + // configuration data + const Config& m_config; - ExpInterface *m_ei; - Interface *m_i; - }; + ExpInterface *m_ei; + Interface *m_i; + }; } diff --git a/Tools/3dsmaxExport/OgreExport/include/OgreMaxMaterialExport.h b/Tools/3dsmaxExport/OgreExport/include/OgreMaxMaterialExport.h index b0aad4410ef..47f31f8d490 100644 --- a/Tools/3dsmaxExport/OgreExport/include/OgreMaxMaterialExport.h +++ b/Tools/3dsmaxExport/OgreExport/include/OgreMaxMaterialExport.h @@ -44,32 +44,32 @@ class IGameMaterial; namespace OgreMax { - //typedef std::map< std::string, Mtl* > MaterialMap; - typedef std::map< std::string, IGameMaterial* > MaterialMap; + //typedef std::map< std::string, Mtl* > MaterialMap; + typedef std::map< std::string, IGameMaterial* > MaterialMap; - class MaterialExporter : public OgreMaxExporter - { + class MaterialExporter : public OgreMaxExporter + { - public: - MaterialExporter(const Config& config, MaterialMap& map); - virtual ~MaterialExporter(); + public: + MaterialExporter(const Config& config, MaterialMap& map); + virtual ~MaterialExporter(); - // take in a list of INode* for assembly into Ogre::Mesh form; returns - // a map of filename --> XML stringstream. - bool buildMaterial(std::string& output); - bool buildMaterial(IGameMaterial *mtl, const std::string& matName, std::string &of); + // take in a list of INode* for assembly into Ogre::Mesh form; returns + // a map of filename --> XML stringstream. + bool buildMaterial(std::string& output); + bool buildMaterial(IGameMaterial *mtl, const std::string& matName, std::string &of); - protected: - // material file stream functions - bool streamPass(std::ostream &of, IGameMaterial *mtl); - bool streamMaterial(std::ostream &of); + protected: + // material file stream functions + bool streamPass(std::ostream &of, IGameMaterial *mtl); + bool streamMaterial(std::ostream &of); - std::string removeSpaces(const std::string &s); + std::string removeSpaces(const std::string &s); - private: + private: - MaterialMap& m_materialMap; - }; + MaterialMap& m_materialMap; + }; } #endif diff --git a/Tools/3dsmaxExport/OgreExport/include/OgreMaxMeshExport.h b/Tools/3dsmaxExport/OgreExport/include/OgreMaxMeshExport.h index 8056aa8083b..c6b0f20414d 100644 --- a/Tools/3dsmaxExport/OgreExport/include/OgreMaxMeshExport.h +++ b/Tools/3dsmaxExport/OgreExport/include/OgreMaxMeshExport.h @@ -40,20 +40,20 @@ typedef std::list NodeList; namespace OgreMax { - class MeshExporter : public OgreMaxExporter - { - public: + class MeshExporter : public OgreMaxExporter + { + public: - MeshExporter(const Config& config); - virtual ~MeshExporter(); + MeshExporter(const Config& config); + virtual ~MeshExporter(); - // take in a list of INode* for assembly into Ogre::Mesh form; returns - // a MeshPtr pointing to the newly minted Ogre Mesh object. - Ogre::MeshPtr buildMesh(NodeList nodeList); + // take in a list of INode* for assembly into Ogre::Mesh form; returns + // a MeshPtr pointing to the newly minted Ogre Mesh object. + Ogre::MeshPtr buildMesh(NodeList nodeList); - private: + private: - // Pointer to Mesh object for export - Ogre::MeshPtr m_pMesh; - }; + // Pointer to Mesh object for export + Ogre::MeshPtr m_pMesh; + }; } \ No newline at end of file diff --git a/Tools/3dsmaxExport/OgreExport/include/OgreMaxMeshXMLExport.h b/Tools/3dsmaxExport/OgreExport/include/OgreMaxMeshXMLExport.h index d949f1acf18..762292cb4e1 100644 --- a/Tools/3dsmaxExport/OgreExport/include/OgreMaxMeshXMLExport.h +++ b/Tools/3dsmaxExport/OgreExport/include/OgreMaxMeshXMLExport.h @@ -45,52 +45,52 @@ class IGameMaterial; namespace OgreMax { - class MeshXMLExporter : public OgreMaxExporter, public ITreeEnumProc - { - typedef struct { - std::string name; - int start; - int end; - } NamedAnimation; - - public: - typedef std::map< std::string, std::string > OutputMap; - - MeshXMLExporter(const Config& config, MaterialMap& materialMap); - virtual ~MeshXMLExporter(); - - // generates a list of INode* for assembly into Ogre::Mesh form; returns - // a map of filename --> XML stringstream. - bool buildMeshXML(OutputMap& output); - - protected: - // mesh file stream functions - bool streamFileHeader(std::ostream &of); - bool streamFileFooter(std::ostream &of); - bool streamSubmesh(std::ostream &of, IGameObject *obj, std::string &mtlName); - bool streamBoneAssignments(std::ostream &of, Modifier *mod, IGameNode *node); - - int getBoneIndex(char *name); - std::string removeSpaces(const std::string &s); - - int callback(INode *node); - - private: - - bool export(OutputMap& output); - - bool m_createSkeletonLink; - std::string m_exportFilename; // filename provided by - std::string m_filename; // filename provided by - std::string m_skeletonFilename; - std::queue< std::string > m_submeshNames; - MaterialMap& m_materialMap; - std::map< std::string, int > m_boneIndexMap; - int m_currentBoneIndex; - - IGameScene* m_pGame; - Tab m_nodeTab; - }; + class MeshXMLExporter : public OgreMaxExporter, public ITreeEnumProc + { + typedef struct { + std::string name; + int start; + int end; + } NamedAnimation; + + public: + typedef std::map< std::string, std::string > OutputMap; + + MeshXMLExporter(const Config& config, MaterialMap& materialMap); + virtual ~MeshXMLExporter(); + + // generates a list of INode* for assembly into Ogre::Mesh form; returns + // a map of filename --> XML stringstream. + bool buildMeshXML(OutputMap& output); + + protected: + // mesh file stream functions + bool streamFileHeader(std::ostream &of); + bool streamFileFooter(std::ostream &of); + bool streamSubmesh(std::ostream &of, IGameObject *obj, std::string &mtlName); + bool streamBoneAssignments(std::ostream &of, Modifier *mod, IGameNode *node); + + int getBoneIndex(char *name); + std::string removeSpaces(const std::string &s); + + int callback(INode *node); + + private: + + bool export(OutputMap& output); + + bool m_createSkeletonLink; + std::string m_exportFilename; // filename provided by + std::string m_filename; // filename provided by + std::string m_skeletonFilename; + std::queue< std::string > m_submeshNames; + MaterialMap& m_materialMap; + std::map< std::string, int > m_boneIndexMap; + int m_currentBoneIndex; + + IGameScene* m_pGame; + Tab m_nodeTab; + }; } #endif \ No newline at end of file diff --git a/Tools/3dsmaxExport/OgreExport/include/OgreMaxSkeletonXMLExport.h b/Tools/3dsmaxExport/OgreExport/include/OgreMaxSkeletonXMLExport.h index aa38903496f..5219233c758 100644 --- a/Tools/3dsmaxExport/OgreExport/include/OgreMaxSkeletonXMLExport.h +++ b/Tools/3dsmaxExport/OgreExport/include/OgreMaxSkeletonXMLExport.h @@ -1,515 +1,515 @@ /* - // if skeleton data is present, stream skeleton file - if (m_config.getExportSkeleton()) { - // open the skeleton.xml output file - of.open((m_config.getExportPath() + "\\" + m_skeletonFilename).c_str(), std::ios::out); + // if skeleton data is present, stream skeleton file + if (m_config.getExportSkeleton()) { + // open the skeleton.xml output file + of.open((m_config.getExportPath() + "\\" + m_skeletonFilename).c_str(), std::ios::out); - // stream the skeleton file - streamSkeleton(of); - of.close(); - } + // stream the skeleton file + streamSkeleton(of); + of.close(); + } */ #ifdef 0 - // ******************************************************************************* - // Skeleton streaming functions - // ******************************************************************************* + // ******************************************************************************* + // Skeleton streaming functions + // ******************************************************************************* - std::string MeshXMLExporter::removeSpaces(const std::string &src) { - std::string s(src); - std::string::size_type pos; - while ((pos=s.find_first_of(" \t\n")) != std::string::npos) - s.replace(pos, 1, "_"); + std::string MeshXMLExporter::removeSpaces(const std::string &src) { + std::string s(src); + std::string::size_type pos; + while ((pos=s.find_first_of(" \t\n")) != std::string::npos) + s.replace(pos, 1, "_"); - return s; - } + return s; + } - bool MeshXMLExporter::streamSkeleton(std::ostream &of) { + bool MeshXMLExporter::streamSkeleton(std::ostream &of) { - // go through and sort out the bone hierarchy (include all of the non-null bones that were not - // skinned, as those could still be needed in the application) - of << "" << std::endl << "" << std::endl; - of << "\t" << std::endl; + // go through and sort out the bone hierarchy (include all of the non-null bones that were not + // skinned, as those could still be needed in the application) + of << "" << std::endl << "" << std::endl; + of << "\t" << std::endl; - // write out the bone rest pose data - std::map< std::string, int >::const_iterator it = m_boneIndexMap.begin(); - while (it != m_boneIndexMap.end()) { + // write out the bone rest pose data + std::map< std::string, int >::const_iterator it = m_boneIndexMap.begin(); + while (it != m_boneIndexMap.end()) { - INode *thisNode = m_i->GetINodeByName(it->first.c_str()); + INode *thisNode = m_i->GetINodeByName(it->first.c_str()); - of << "\t\tsecond << "\" name=\"" << removeSpaces(it->first) << "\" >" << std::endl; + of << "\t\tsecond << "\" name=\"" << removeSpaces(it->first) << "\" >" << std::endl; - // assume rest pose is at time zero - TimeValue start = m_i->GetAnimRange().Start(); - ObjectState os = thisNode->EvalWorldState(start); - Object *obj = os.obj; - SClass_ID scid = obj->SuperClassID(); + // assume rest pose is at time zero + TimeValue start = m_i->GetAnimRange().Start(); + ObjectState os = thisNode->EvalWorldState(start); + Object *obj = os.obj; + SClass_ID scid = obj->SuperClassID(); - // SKELOBJ_CLASS_ID = 0x9125 = 37157 - // BIPED_CLASS_ID = 0x9155 = 37205 - // BIPSLAVE_CONTROL_CLASS_ID = 0x9154 = 37204 - // BIPBODY_CONTROL_CLASS_ID = 0x9156 = 37206 - // FOOTPRINT_CLASS_ID = 0x3011 = 12305 - // DUMMY_CLASS_ID = 0x876234 = 8872500 - Matrix3 tm(thisNode->GetNodeTM(start)); - Matrix3 ptm(thisNode->GetParentTM(start)); - Control *tmc = thisNode->GetTMController(); + // SKELOBJ_CLASS_ID = 0x9125 = 37157 + // BIPED_CLASS_ID = 0x9155 = 37205 + // BIPSLAVE_CONTROL_CLASS_ID = 0x9154 = 37204 + // BIPBODY_CONTROL_CLASS_ID = 0x9156 = 37206 + // FOOTPRINT_CLASS_ID = 0x3011 = 12305 + // DUMMY_CLASS_ID = 0x876234 = 8872500 + Matrix3 tm(thisNode->GetNodeTM(start)); + Matrix3 ptm(thisNode->GetParentTM(start)); + Control *tmc = thisNode->GetTMController(); - TCHAR *nm = thisNode->GetName(); - Class_ID cid = tmc->ClassID(); + TCHAR *nm = thisNode->GetName(); + Class_ID cid = tmc->ClassID(); - if (cid == BIPBODY_CONTROL_CLASS_ID || cid == BIPED_CLASS_ID) { - if (m_config.getInvertYZ()) { - Matrix3 m = RotateXMatrix(PI / 2.0f); - tm = tm * Inverse(m); - } - } - else - tm = tm * Inverse(ptm); + if (cid == BIPBODY_CONTROL_CLASS_ID || cid == BIPED_CLASS_ID) { + if (m_config.getInvertYZ()) { + Matrix3 m = RotateXMatrix(PI / 2.0f); + tm = tm * Inverse(m); + } + } + else + tm = tm * Inverse(ptm); - Point3 pos = tm.GetTrans(); - AngAxis aa(tm); + Point3 pos = tm.GetTrans(); + AngAxis aa(tm); - of << "\t\t\t" << std::endl; + of << "\t\t\t" << std::endl; - // there is still a lingering Max/Ogre handed-ness issue even after rotating to get the axes correct - // so we negate the angle of rotation here - of << "\t\t\t" << std::endl; - of << "\t\t\t\t" << std::endl; - of << "\t\t\t" << std::endl; - of << "\t\t" << std::endl; + // there is still a lingering Max/Ogre handed-ness issue even after rotating to get the axes correct + // so we negate the angle of rotation here + of << "\t\t\t" << std::endl; + of << "\t\t\t\t" << std::endl; + of << "\t\t\t" << std::endl; + of << "\t\t" << std::endl; - it++; - } + it++; + } - of << "\t" << std::endl; + of << "\t" << std::endl; - // write out the bone hierarchy - it = m_boneIndexMap.begin(); - of << "\t" << std::endl; - while (it != m_boneIndexMap.end()) { - INode *thisNode = m_i->GetINodeByName(it->first.c_str()); + // write out the bone hierarchy + it = m_boneIndexMap.begin(); + of << "\t" << std::endl; + while (it != m_boneIndexMap.end()) { + INode *thisNode = m_i->GetINodeByName(it->first.c_str()); - if (thisNode != 0) { - INode *parentNode = thisNode->GetParentNode(); + if (thisNode != 0) { + INode *parentNode = thisNode->GetParentNode(); - if (parentNode != 0 && parentNode != m_i->GetRootNode()) - of << "\t\tfirst) << "\" parent=\"" << removeSpaces(std::string(parentNode->GetName())) << "\"/>" << std::endl; - } + if (parentNode != 0 && parentNode != m_i->GetRootNode()) + of << "\t\tfirst) << "\" parent=\"" << removeSpaces(std::string(parentNode->GetName())) << "\"/>" << std::endl; + } - it++; - } - of << "\t" << std::endl; + it++; + } + of << "\t" << std::endl; - // the fun bits.... - // Animations are named by the user during export; Max has no concept of animation subset names, - // so we have to get the user to do that manually. If the user has entered anything for animations, - // spit it all out here. - std::list::iterator anim = m_animations.begin(); + // the fun bits.... + // Animations are named by the user during export; Max has no concept of animation subset names, + // so we have to get the user to do that manually. If the user has entered anything for animations, + // spit it all out here. + std::list::iterator anim = m_animations.begin(); - if (anim != m_animations.end()) { - of << "\t" << std::endl; + if (anim != m_animations.end()) { + of << "\t" << std::endl; - while (anim != m_animations.end()) { + while (anim != m_animations.end()) { - NamedAnimation a = *anim; - anim++; + NamedAnimation a = *anim; + anim++; - float fps = (float)GetFrameRate(); - float length = (a.end - a.start) / fps; - - of << "\t\t" << std::endl; - - streamAnimTracks(of, a.start, a.end); - - of << "\t\t" << std::endl; - } - - of << "\t" << std::endl; - } - - of << "" << std::endl; - - return true; - } - - static int _compare_func(const void *a, const void *b) { return *(( int *)a) - *(( int *)b); } - - bool MeshXMLExporter::streamAnimTracks(std::ostream &of, int startFrame, int endFrame) { - - int start = startFrame * GetTicksPerFrame(); - int end = endFrame * GetTicksPerFrame(); - - std::map< std::string, int >::const_iterator it = m_boneIndexMap.begin(); - - of << "\t\t\t" << std::endl; - - // need this for calculating keyframe values - Matrix3 initTM, bipedMasterTM0; - IBipMaster *bip = 0; - bipedMasterTM0.IdentityMatrix(); - - while (it != m_boneIndexMap.end()) { - - INode *thisNode = m_i->GetINodeByName(it->first.c_str()); - it++; - - Control *c = thisNode->GetTMController(); - Class_ID cid = c->ClassID(); - - Tab keyTimes; - Interval interval(start, end); - - /* - -- gets initial transform at frame 0f - at time 0f ( - initTform = d.transform ; - if (not isRootUniversal2 d) then ( - mparent = d.parent.transform ; - initTform = initTform*inverse(mparent) ; - ) - else if (flipYZ) then ( - if (not g_MAX) then - format " - flipping root track..." ; - -- we add the bip Transform - --initTform = initTform * d.controller.rootNode.transform ; - initTform = flipYZTransform initTform ; - ) - ) - */ - - initTM = thisNode->GetNodeTM(0); - - // must have at least a frame at the start... - keyTimes.Append(1, &start); - - TCHAR *tch = thisNode->GetName(); - - // SKELOBJ_CLASS_ID = 0x9125 = 37157 - // BIPED_CLASS_ID = 0x9155 = 37205 - // BIPSLAVE_CONTROL_CLASS_ID = 0x9154 = 37204 - // BIPBODY_CONTROL_CLASS_ID = 0x9156 = 37206 - // FOOTPRINT_CLASS_ID = 0x3011 = 12305 - // DUMMY_CLASS_ID = 0x876234 = 8872500 - - // three-part controller for Biped root -- taking this cue from the old MaxScript exporter code - if (cid == BIPBODY_CONTROL_CLASS_ID) { - - // we deal with the initial transform as-is, except that it might need to - // be rotated (since the root transform is in world coords) - if (m_config.getInvertYZ()) - initTM = initTM * Inverse(RotateXMatrix(PI/2.0f)); - - if (cid == BIPBODY_CONTROL_CLASS_ID) { - // get the keys from the horiz, vert and turn controllers - bip = GetBipMasterInterface(c); - Control *biph = bip->GetHorizontalControl(); - Control *bipv = bip->GetVerticalControl(); - Control *bipr = bip->GetTurnControl(); - - biph->GetKeyTimes(keyTimes, interval, KEYAT_POSITION | KEYAT_ROTATION); - bipv->GetKeyTimes(keyTimes, interval, KEYAT_POSITION | KEYAT_ROTATION); - bipr->GetKeyTimes(keyTimes, interval, KEYAT_POSITION | KEYAT_ROTATION); - } - } - else if (cid == BIPSLAVE_CONTROL_CLASS_ID) { - // slaves just have keys, apparently - c->GetKeyTimes(keyTimes, interval, KEYAT_POSITION | KEYAT_ROTATION); - - // put initial transform into local coordinates -- since this is relative to the - // parent, we don't need to sweat that possible rotations here - initTM = initTM * Inverse(thisNode->GetParentTM(0)); - } - - // ...and stick a frame at the end as well...it will get sorted out if it is redundant - keyTimes.Append(1, &end); - - // skip redundant key times here - keyTimes.Sort(_compare_func); - - // if (cid == BIPSLAVE_CONTROL_CLASS_ID || cid == BIPBODY_CONTROL_CLASS_ID || cid == FOOTPRINT_CLASS_ID) { - // - // if (cid == BIPBODY_CONTROL_CLASS_ID) { - // initTM = thisNode->GetNodeTM(0); - // - // if (m_flipYZ) - // initTM = initTM * RotateXMatrix(PI/2.0f); - // bipedMasterTM0 = initTM; - // } - // else - // initTM = bipedMasterTM0; - // - // streamBipedKeyframes(of, bip, thisNode, keyTimes, interval, initTM); - // } - // else - streamKeyframes(of, thisNode, keyTimes, interval, initTM); - } - - of << "\t\t\t" << std::endl; - - return true; - } - - bool MeshXMLExporter::streamKeyframes(std::ostream &of, INode *thisNode, Tab &keyTimes, Interval &interval, Matrix3 &initTM) { - - of << "\t\t\t\tGetName())) << "\">" << std::endl; - of << "\t\t\t\t\t" << std::endl; - - int i; - int keyTime = -1; - int start = interval.Start(); - int end = interval.End(); - - /* - - -- gets initial transform at frame 0f - at time 0f ( - initTform = d.transform ; - if (not isRootUniversal2 d) then ( - mparent = d.parent.transform ; - initTform = initTform*inverse(mparent) ; - ) - else if (flipYZ) then ( - if (not g_MAX) then - format " - flipping root track..." ; - -- we add the bip Transform - --initTform = initTform * d.controller.rootNode.transform ; - initTform = flipYZTransform initTform ; - ) - ) - */ - initTM = thisNode->GetNodeTM(0); - - Control *c = thisNode->GetTMController(); - Control *pc = thisNode->GetParentNode()->GetTMController(); - bool isRoot = false; - - if (c > 0) - if (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) - isRoot = true; - // if (pc > 0) - // if (pc->ClassID() == BIPBODY_CONTROL_CLASS_ID || pc->ClassID() == FOOTPRINT_CLASS_ID) - // isRoot = true; - - TCHAR *tc = thisNode->GetName(); - if (!isRoot) { - Matrix3 ptm = thisNode->GetParentTM(0); - initTM = initTM * Inverse(ptm); - } - else if (m_config.getInvertYZ()) { - initTM = initTM * Inverse(RotateXMatrix(PI/2.0f)); - } - - for (i=0; i end) - break; - - // ignore key times we've already processed - if (keyTimes[i] != keyTime) { - - keyTime = keyTimes[i]; - float keyTimef = (float) (keyTimes[i] - start) / (float)GetTicksPerFrame() / (float)GetFrameRate(); - - of << "\t\t\t\t\t\t" << std::endl; - - /* - - function flipYZTransform Tform = ( - local axis1,axis2,axis3,t,m - - -- computes the matrix - axis1 = point3 1 0 0 ; - axis2 = point3 0 0 1 ; - axis3 = point3 0 -1 0 ; - t = point3 0 0 0 ; - m=matrix3 axis1 axis2 axis3 t ; - - -- multiplies by the inverse - Tform = Tform*inverse(m) ; - - return Tform ; - ) - - - -- First, rotation which depends on initial transformation - Tform = d.transform ; - */ - Matrix3 tm = thisNode->GetNodeTM(keyTime); - - /* - -- if this is the pelvis - if (isRootUniversal2 d) then ( - mparent = matrix3 1 ; - - if (flipYZ) then - Tform = flipYZTransform Tform ; - ) - else - mparent = d.parent.transform ; - */ - - // if this node's parent's controller is the biped controller, then this is either Pelvis or Footsteps, - // and both should be treated as root nodes - - Matrix3 ident; - Matrix3 ptm; - ident.IdentityMatrix(); - Control *tmc = thisNode->GetTMController(); - TCHAR *tc = thisNode->GetName(); - - if (tmc->ClassID() == BIPBODY_CONTROL_CLASS_ID) { - - ptm = ident; - if (m_config.getInvertYZ()) { - tm = tm * Inverse(RotateXMatrix(PI/2.0f)); - } - } - else - ptm = thisNode->GetParentNode()->GetNodeTM(keyTime); - - /* - - - -- computes rotation - mref = initTform*mparent ; - Tform = Tform*inverse(mref) ; - */ - - Matrix3 mref = initTM * ptm; - tm = tm * Inverse(mref); - - /* - - -- rotation part is saved. - rot = toAngleAxis Tform.rotation ; - axis = rot.axis; - angle = - rot.angle; - */ - - AngAxis aa(tm); - - /* - -- Then, position which depends on parent - Tform=d.transform ; - Tform=Tform*inverse(mparent) ; - - */ - - tm = thisNode->GetNodeTM(keyTime) * Inverse(ptm); - - /* - - -- if this is the root bone and flipYZ == true - if (isRootUniversal2 d and flipYZ) then ( - Tform = flipYZTransform Tform ; - ) - - */ - - if (m_config.getInvertYZ() && thisNode->GetParentNode()->GetParentTM(0).IsIdentity()) { - tm = tm * Inverse(RotateXMatrix(PI/2.0f)); - } - - /* - -- substracts position of the initial transform - Tform.pos -= initTform.pos ; - Tform.pos = Tform.pos * scale ; - - pos = Tform.pos ; - */ - Point3 trans = tm.GetTrans(); - trans -= initTM.GetTrans(); - - of << "\t\t\t\t\t\t\t" << std::endl; - of << "\t\t\t\t\t\t\t" << std::endl; - of << "\t\t\t\t\t\t\t\t" << std::endl; - of << "\t\t\t\t\t\t\t" << std::endl; - - of << "\t\t\t\t\t\t" << std::endl; - } - } - - of << "\t\t\t\t\t" << std::endl; - of << "\t\t\t\t" << std::endl; - - return true; - } - - bool MeshXMLExporter::streamBipedKeyframes(std::ostream &of, IBipMaster *bip, INode *thisNode, Tab &keyTimes, Interval &interval, Matrix3 &initTM) { - - of << "\t\t\t\tGetName())) << "\">" << std::endl; - of << "\t\t\t\t\t" << std::endl; - - int i; - int keyTime = -1; - int start = interval.Start(); - int end = interval.End(); - Matrix3 tm(thisNode->GetNodeTM(start)); - Matrix3 ptm(thisNode->GetParentTM(start)); - - for (i=0; i end) - break; - - // ignore key times we've already processed - if (keyTimes[i] != keyTime) { - - keyTime = keyTimes[i]; - float keyTimef = (float) (keyTimes[i] - start) / (float)GetTicksPerFrame() / (float)GetFrameRate(); - - of << "\t\t\t\t\t\t" << std::endl; - - Control *tmc = thisNode->GetTMController(); + float fps = (float)GetFrameRate(); + float length = (a.end - a.start) / fps; + + of << "\t\t" << std::endl; + + streamAnimTracks(of, a.start, a.end); + + of << "\t\t" << std::endl; + } + + of << "\t" << std::endl; + } + + of << "" << std::endl; + + return true; + } + + static int _compare_func(const void *a, const void *b) { return *(( int *)a) - *(( int *)b); } + + bool MeshXMLExporter::streamAnimTracks(std::ostream &of, int startFrame, int endFrame) { + + int start = startFrame * GetTicksPerFrame(); + int end = endFrame * GetTicksPerFrame(); + + std::map< std::string, int >::const_iterator it = m_boneIndexMap.begin(); + + of << "\t\t\t" << std::endl; + + // need this for calculating keyframe values + Matrix3 initTM, bipedMasterTM0; + IBipMaster *bip = 0; + bipedMasterTM0.IdentityMatrix(); + + while (it != m_boneIndexMap.end()) { + + INode *thisNode = m_i->GetINodeByName(it->first.c_str()); + it++; + + Control *c = thisNode->GetTMController(); + Class_ID cid = c->ClassID(); + + Tab keyTimes; + Interval interval(start, end); + + /* + -- gets initial transform at frame 0f + at time 0f ( + initTform = d.transform ; + if (not isRootUniversal2 d) then ( + mparent = d.parent.transform ; + initTform = initTform*inverse(mparent) ; + ) + else if (flipYZ) then ( + if (not g_MAX) then + format " - flipping root track..." ; + -- we add the bip Transform + --initTform = initTform * d.controller.rootNode.transform ; + initTform = flipYZTransform initTform ; + ) + ) + */ + + initTM = thisNode->GetNodeTM(0); + + // must have at least a frame at the start... + keyTimes.Append(1, &start); + + TCHAR *tch = thisNode->GetName(); + + // SKELOBJ_CLASS_ID = 0x9125 = 37157 + // BIPED_CLASS_ID = 0x9155 = 37205 + // BIPSLAVE_CONTROL_CLASS_ID = 0x9154 = 37204 + // BIPBODY_CONTROL_CLASS_ID = 0x9156 = 37206 + // FOOTPRINT_CLASS_ID = 0x3011 = 12305 + // DUMMY_CLASS_ID = 0x876234 = 8872500 + + // three-part controller for Biped root -- taking this cue from the old MaxScript exporter code + if (cid == BIPBODY_CONTROL_CLASS_ID) { + + // we deal with the initial transform as-is, except that it might need to + // be rotated (since the root transform is in world coords) + if (m_config.getInvertYZ()) + initTM = initTM * Inverse(RotateXMatrix(PI/2.0f)); + + if (cid == BIPBODY_CONTROL_CLASS_ID) { + // get the keys from the horiz, vert and turn controllers + bip = GetBipMasterInterface(c); + Control *biph = bip->GetHorizontalControl(); + Control *bipv = bip->GetVerticalControl(); + Control *bipr = bip->GetTurnControl(); + + biph->GetKeyTimes(keyTimes, interval, KEYAT_POSITION | KEYAT_ROTATION); + bipv->GetKeyTimes(keyTimes, interval, KEYAT_POSITION | KEYAT_ROTATION); + bipr->GetKeyTimes(keyTimes, interval, KEYAT_POSITION | KEYAT_ROTATION); + } + } + else if (cid == BIPSLAVE_CONTROL_CLASS_ID) { + // slaves just have keys, apparently + c->GetKeyTimes(keyTimes, interval, KEYAT_POSITION | KEYAT_ROTATION); + + // put initial transform into local coordinates -- since this is relative to the + // parent, we don't need to sweat that possible rotations here + initTM = initTM * Inverse(thisNode->GetParentTM(0)); + } + + // ...and stick a frame at the end as well...it will get sorted out if it is redundant + keyTimes.Append(1, &end); + + // skip redundant key times here + keyTimes.Sort(_compare_func); + + // if (cid == BIPSLAVE_CONTROL_CLASS_ID || cid == BIPBODY_CONTROL_CLASS_ID || cid == FOOTPRINT_CLASS_ID) { + // + // if (cid == BIPBODY_CONTROL_CLASS_ID) { + // initTM = thisNode->GetNodeTM(0); + // + // if (m_flipYZ) + // initTM = initTM * RotateXMatrix(PI/2.0f); + // bipedMasterTM0 = initTM; + // } + // else + // initTM = bipedMasterTM0; + // + // streamBipedKeyframes(of, bip, thisNode, keyTimes, interval, initTM); + // } + // else + streamKeyframes(of, thisNode, keyTimes, interval, initTM); + } + + of << "\t\t\t" << std::endl; + + return true; + } + + bool MeshXMLExporter::streamKeyframes(std::ostream &of, INode *thisNode, Tab &keyTimes, Interval &interval, Matrix3 &initTM) { + + of << "\t\t\t\tGetName())) << "\">" << std::endl; + of << "\t\t\t\t\t" << std::endl; + + int i; + int keyTime = -1; + int start = interval.Start(); + int end = interval.End(); + + /* + + -- gets initial transform at frame 0f + at time 0f ( + initTform = d.transform ; + if (not isRootUniversal2 d) then ( + mparent = d.parent.transform ; + initTform = initTform*inverse(mparent) ; + ) + else if (flipYZ) then ( + if (not g_MAX) then + format " - flipping root track..." ; + -- we add the bip Transform + --initTform = initTform * d.controller.rootNode.transform ; + initTform = flipYZTransform initTform ; + ) + ) + */ + initTM = thisNode->GetNodeTM(0); + + Control *c = thisNode->GetTMController(); + Control *pc = thisNode->GetParentNode()->GetTMController(); + bool isRoot = false; + + if (c > 0) + if (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) + isRoot = true; + // if (pc > 0) + // if (pc->ClassID() == BIPBODY_CONTROL_CLASS_ID || pc->ClassID() == FOOTPRINT_CLASS_ID) + // isRoot = true; + + TCHAR *tc = thisNode->GetName(); + if (!isRoot) { + Matrix3 ptm = thisNode->GetParentTM(0); + initTM = initTM * Inverse(ptm); + } + else if (m_config.getInvertYZ()) { + initTM = initTM * Inverse(RotateXMatrix(PI/2.0f)); + } + + for (i=0; i end) + break; + + // ignore key times we've already processed + if (keyTimes[i] != keyTime) { + + keyTime = keyTimes[i]; + float keyTimef = (float) (keyTimes[i] - start) / (float)GetTicksPerFrame() / (float)GetFrameRate(); + + of << "\t\t\t\t\t\t" << std::endl; + + /* + + function flipYZTransform Tform = ( + local axis1,axis2,axis3,t,m + + -- computes the matrix + axis1 = point3 1 0 0 ; + axis2 = point3 0 0 1 ; + axis3 = point3 0 -1 0 ; + t = point3 0 0 0 ; + m=matrix3 axis1 axis2 axis3 t ; + + -- multiplies by the inverse + Tform = Tform*inverse(m) ; + + return Tform ; + ) + + + -- First, rotation which depends on initial transformation + Tform = d.transform ; + */ + Matrix3 tm = thisNode->GetNodeTM(keyTime); + + /* + -- if this is the pelvis + if (isRootUniversal2 d) then ( + mparent = matrix3 1 ; + + if (flipYZ) then + Tform = flipYZTransform Tform ; + ) + else + mparent = d.parent.transform ; + */ + + // if this node's parent's controller is the biped controller, then this is either Pelvis or Footsteps, + // and both should be treated as root nodes + + Matrix3 ident; + Matrix3 ptm; + ident.IdentityMatrix(); + Control *tmc = thisNode->GetTMController(); + TCHAR *tc = thisNode->GetName(); + + if (tmc->ClassID() == BIPBODY_CONTROL_CLASS_ID) { + + ptm = ident; + if (m_config.getInvertYZ()) { + tm = tm * Inverse(RotateXMatrix(PI/2.0f)); + } + } + else + ptm = thisNode->GetParentNode()->GetNodeTM(keyTime); + + /* + + + -- computes rotation + mref = initTform*mparent ; + Tform = Tform*inverse(mref) ; + */ + + Matrix3 mref = initTM * ptm; + tm = tm * Inverse(mref); + + /* + + -- rotation part is saved. + rot = toAngleAxis Tform.rotation ; + axis = rot.axis; + angle = - rot.angle; + */ + + AngAxis aa(tm); + + /* + -- Then, position which depends on parent + Tform=d.transform ; + Tform=Tform*inverse(mparent) ; + + */ + + tm = thisNode->GetNodeTM(keyTime) * Inverse(ptm); + + /* + + -- if this is the root bone and flipYZ == true + if (isRootUniversal2 d and flipYZ) then ( + Tform = flipYZTransform Tform ; + ) + + */ + + if (m_config.getInvertYZ() && thisNode->GetParentNode()->GetParentTM(0).IsIdentity()) { + tm = tm * Inverse(RotateXMatrix(PI/2.0f)); + } + + /* + -- substracts position of the initial transform + Tform.pos -= initTform.pos ; + Tform.pos = Tform.pos * scale ; + + pos = Tform.pos ; + */ + Point3 trans = tm.GetTrans(); + trans -= initTM.GetTrans(); + + of << "\t\t\t\t\t\t\t" << std::endl; + of << "\t\t\t\t\t\t\t" << std::endl; + of << "\t\t\t\t\t\t\t\t" << std::endl; + of << "\t\t\t\t\t\t\t" << std::endl; + + of << "\t\t\t\t\t\t" << std::endl; + } + } + + of << "\t\t\t\t\t" << std::endl; + of << "\t\t\t\t" << std::endl; + + return true; + } + + bool MeshXMLExporter::streamBipedKeyframes(std::ostream &of, IBipMaster *bip, INode *thisNode, Tab &keyTimes, Interval &interval, Matrix3 &initTM) { + + of << "\t\t\t\tGetName())) << "\">" << std::endl; + of << "\t\t\t\t\t" << std::endl; + + int i; + int keyTime = -1; + int start = interval.Start(); + int end = interval.End(); + Matrix3 tm(thisNode->GetNodeTM(start)); + Matrix3 ptm(thisNode->GetParentTM(start)); + + for (i=0; i end) + break; + + // ignore key times we've already processed + if (keyTimes[i] != keyTime) { + + keyTime = keyTimes[i]; + float keyTimef = (float) (keyTimes[i] - start) / (float)GetTicksPerFrame() / (float)GetFrameRate(); + + of << "\t\t\t\t\t\t" << std::endl; + + Control *tmc = thisNode->GetTMController(); - TCHAR *nm = thisNode->GetName(); - Class_ID cid = tmc->ClassID(); + TCHAR *nm = thisNode->GetName(); + Class_ID cid = tmc->ClassID(); - if (cid == BIPBODY_CONTROL_CLASS_ID || cid == BIPED_CLASS_ID) { - if (m_config.getInvertYZ()) { - Matrix3 m = RotateXMatrix(PI / 2.0f); - tm = tm * Inverse(m); - } - } - else - tm = tm * Inverse(ptm); - - //Point3 trans = bip->GetBipedPos(keyTime, thisNode); - //Quat q = bip->GetBipedRot(keyTime, thisNode); - - Point3 trans = tm.GetTrans(); - trans = trans * Inverse(initTM); - trans -= initTM.GetTrans(); + if (cid == BIPBODY_CONTROL_CLASS_ID || cid == BIPED_CLASS_ID) { + if (m_config.getInvertYZ()) { + Matrix3 m = RotateXMatrix(PI / 2.0f); + tm = tm * Inverse(m); + } + } + else + tm = tm * Inverse(ptm); + + //Point3 trans = bip->GetBipedPos(keyTime, thisNode); + //Quat q = bip->GetBipedRot(keyTime, thisNode); + + Point3 trans = tm.GetTrans(); + trans = trans * Inverse(initTM); + trans -= initTM.GetTrans(); - //AngAxis aa(q); - AngAxis aa(tm); - float ang = aa.angle; - Point3 axis = aa.axis; - - of << "\t\t\t\t\t\t\t" << std::endl; - of << "\t\t\t\t\t\t\t" << std::endl; - of << "\t\t\t\t\t\t\t\t" << std::endl; - of << "\t\t\t\t\t\t\t" << std::endl; - - of << "\t\t\t\t\t\t" << std::endl; - } - } - - of << "\t\t\t\t\t" << std::endl; - of << "\t\t\t\t" << std::endl; - - return true; - } - - - + //AngAxis aa(q); + AngAxis aa(tm); + float ang = aa.angle; + Point3 axis = aa.axis; + + of << "\t\t\t\t\t\t\t" << std::endl; + of << "\t\t\t\t\t\t\t" << std::endl; + of << "\t\t\t\t\t\t\t\t" << std::endl; + of << "\t\t\t\t\t\t\t" << std::endl; + + of << "\t\t\t\t\t\t" << std::endl; + } + } + + of << "\t\t\t\t\t" << std::endl; + of << "\t\t\t\t" << std::endl; + + return true; + } + + + #endif \ No newline at end of file diff --git a/Tools/3dsmaxExport/OgreExport/include/OgreMaxVertex.h b/Tools/3dsmaxExport/OgreExport/include/OgreMaxVertex.h index 33d61c3ec31..fc25eeeb9c9 100644 --- a/Tools/3dsmaxExport/OgreExport/include/OgreMaxVertex.h +++ b/Tools/3dsmaxExport/OgreExport/include/OgreMaxVertex.h @@ -34,44 +34,44 @@ THE SOFTWARE. namespace OgreMax { - typedef std::map TexCoordMap; - - class Vertex { - public: - - Vertex(float x, float y, float z); - - void setNormal(float x, float y, float z); - void setColour(float r, float g, float b, float a = 1.0); - void addTexCoord(int mapIndex, float u, float v, float w = 0.0); - - bool operator==(Vertex& other); - - const Ogre::Vector3& getPosition() const { return m_position; } - const Ogre::Vector3& getNormal() const { return m_normal; } - const Ogre::ColourValue& getColour() const { return m_colour; } - const Ogre::Vector3& getUVW(int mapIndex) const { return m_uvwMap.find(mapIndex)->second; } - - private: - bool hasSameTexCoords(std::map& uvwMap) ; - Ogre::Vector3 m_position; - Ogre::Vector3 m_normal; - Ogre::ColourValue m_colour; - TexCoordMap m_uvwMap; - }; - - class VertexList { - public: - // returns the index into the list for the inserted element - unsigned int add(Vertex& v); - size_t size() { return m_vertexList.size(); } - const Vertex& front() { return m_vertexList.front(); } - void pop() { m_vertexList.pop_front(); } - - private: - std::list m_vertexList; - - }; + typedef std::map TexCoordMap; + + class Vertex { + public: + + Vertex(float x, float y, float z); + + void setNormal(float x, float y, float z); + void setColour(float r, float g, float b, float a = 1.0); + void addTexCoord(int mapIndex, float u, float v, float w = 0.0); + + bool operator==(Vertex& other); + + const Ogre::Vector3& getPosition() const { return m_position; } + const Ogre::Vector3& getNormal() const { return m_normal; } + const Ogre::ColourValue& getColour() const { return m_colour; } + const Ogre::Vector3& getUVW(int mapIndex) const { return m_uvwMap.find(mapIndex)->second; } + + private: + bool hasSameTexCoords(std::map& uvwMap) ; + Ogre::Vector3 m_position; + Ogre::Vector3 m_normal; + Ogre::ColourValue m_colour; + TexCoordMap m_uvwMap; + }; + + class VertexList { + public: + // returns the index into the list for the inserted element + unsigned int add(Vertex& v); + size_t size() { return m_vertexList.size(); } + const Vertex& front() { return m_vertexList.front(); } + void pop() { m_vertexList.pop_front(); } + + private: + std::list m_vertexList; + + }; } diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxConfig.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxConfig.cpp index cc43c03f079..9baa276d13d 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxConfig.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxConfig.cpp @@ -3,286 +3,286 @@ namespace OgreMax { - Config::Config() { - // set defaults - m_exportSelectedObjects = false; // default to exporting everything in the scene - m_exportMultipleFiles = true; // default is to export a file per mesh object in the scene - m_useSingleSkeleton = true; // default for multiple meshes is to reference a single .skeleton file where applicable - m_rebuildNormals = false; // rebuild the normals before exporting mesh data - - m_exportMaterial = true; // default is to export material scripts - m_defaultMaterialName = "DefaultMaterial"; - m_2DTexCoord = UV; // default is UV interpretation of 2D tex coords - - m_invertNormals = false; // flip normals; will also reorder triangle vertex indices - m_flipYZ = false; // swap X and Z axes, so that Y becomes the One True Up Vector - m_exportVertexColors = false; // useful for vertex painting - m_scale = 1.0f; // export at normal size (scale) -- all vertices get multiplied by this - - m_exportSkeleton = false; // initially we don't assume any skeletal data - - m_fps = 25.0; // used for controller types (such as Biped) that do not support keyframes directly -- this is the sampling rate - - m_exportBinaryMesh = false; - m_exportXMLMesh = true; - - m_generateTangents = false; - m_edgeLists = true; - m_generateLod = false; - m_lodDistance = 0.0f; - m_numLodLevels = 0; - m_lodPercent = -1.0f; - m_lodVertexCount = -1; - m_endian = NATIVE; // let Ogre figure it out - m_colourFormat = DIRECT3D; // we can default to this since Max only runs on Windows - m_optimizeBinaryLayout = true; // why wouldn't we? ;) - - // version 2 - m_mergeMeshes = false; - } - - Config::Config(const Config& config) - { - *this = config; - } - - Config& Config::operator=(const Config& rhs) - { - m_generateTangents = rhs.m_generateTangents; - m_edgeLists = rhs.m_edgeLists; - m_generateLod = rhs.m_generateLod; - m_lodDistance = rhs.m_lodDistance; - m_numLodLevels = rhs.m_numLodLevels; - m_lodPercent = rhs.m_lodPercent; - m_lodVertexCount = rhs.m_lodVertexCount; - - return *this; - } - - Config::~Config() - { - } - - void Config::save() { - // write "this" to file named .cfg; note that we do not need to do the same massaging of - // file sizes that we do for reads since this will always output the latest version - std::ofstream of; - std::string fname = m_exportBasename + ".cfg"; - - // copy strings to buffers - strcpy(m_bufDefaultMaterialName, m_defaultMaterialName.c_str()); - strcpy(m_bufExportPath, m_exportPath.c_str()); - strcpy(m_bufExportBasename, m_exportBasename.c_str()); - strcpy(m_bufExportFilename, m_exportFilename.c_str()); - strcpy(m_bufMaterialFilename, m_materialFilename.c_str()); - strcpy(m_bufSkeletonFilename, m_skeletonFilename.c_str()); - - // set version number for sure - m_version = CURRENTVERSION; - - of.open(fname.c_str(), std::ios::binary | std::ios::out); - if (of.is_open()) { - of.write((char *)this, offsetof(Config, m_defaultMaterialName)); - of.close(); - } - } - - void Config::load() { - // read "this" from file named .cfg - std::ifstream f; - std::string fname = m_exportBasename + ".cfg"; - - f.open(fname.c_str(), std::ios::binary | std::ios::in); - if (f.is_open()) { - - // we need to check the version to see how much to read - f.read((char*)&m_version, sizeof(unsigned int)); - - // default size for latest version - size_t sz = offsetof(Config, m_defaultMaterialName); - - if (m_version < CURRENTVERSION) { - switch(m_version) { - case 1: - sz = offsetof(Config, m_bufSkeletonFilename) + sizeof(m_bufSkeletonFilename); - break; - case 2: - sz = offsetof(Config, m_mergeMeshes) + sizeof(m_mergeMeshes); - break; - } - } - - // read the calculated size, minus the unsigned int we already read - f.read(((char *)this + sizeof(unsigned int)), sz - sizeof(unsigned int)); - f.close(); - - // make strings from buffers - m_defaultMaterialName = m_bufDefaultMaterialName; - m_exportPath = m_bufExportPath; - m_exportBasename = m_bufExportBasename; - m_exportFilename = m_bufExportFilename; - m_materialFilename = m_bufMaterialFilename; - m_skeletonFilename = m_bufSkeletonFilename; - } - - // if we could not open the config file for any reason, skip it -- more than likely a new export - } - - void Config::setExportPath(const std::string& path) { - m_exportPath = path; - } - - void Config::setMaterialFilename(const std::string& name) { - m_materialFilename = name; - } - - void Config::setExportFilename(const std::string& name) { - // extract the filename and the export path - std::string filename = name; - size_t offset = filename.find_last_of('\\'); - m_exportPath = filename.substr(0, offset); - m_exportFilename = filename.substr(offset+1); - - // strip extension, if any - offset = m_exportFilename.find_last_of('.'); - if (m_exportFilename.substr(offset) == ".xml") - offset = m_exportFilename.substr(0, offset).find_last_of('.'); - - // set base filename - m_exportBasename = m_exportFilename.substr(0, offset); - } - - void Config::setSkeletonFilename(const std::string& name) { - m_skeletonFilename = name; - } - - void Config::setDefaultMaterialName(const std::string& name) { - m_defaultMaterialName = name; - } - - void Config::setTexCoord2D(Tex2D texCoord) { - m_2DTexCoord = texCoord; - } - - void Config::setScale(float scale) { - m_scale = scale; - } - - void Config::setFPS(float fps) { - m_fps = fps; - } - - void Config::setInvertYZ(bool invert) - { - m_flipYZ = invert; - } - - void Config::setInvertNormals(bool invert) - { - m_invertNormals = invert; - } - - void Config::setExportBinaryMesh(bool export) - { - m_exportBinaryMesh = export; - } - - void Config::setExportXMLMesh(bool export) - { - m_exportXMLMesh = export; - } - - void Config::setRebuildNormals(bool rebuild) - { - m_rebuildNormals = rebuild; - } - - void Config::setUseSingleSkeleton(bool useSingle) - { - m_useSingleSkeleton = useSingle; - } - - void Config::setExportSkeleton(bool exportSkeleton) - { - m_exportSkeleton = exportSkeleton; - } - - void Config::setExportMultipleFiles(bool exportMultiple) - { - m_exportMultipleFiles = exportMultiple; - } - - void Config::setExportVertexColours(bool exportVC) - { - m_exportVertexColors = exportVC; - } - - void Config::setExportMaterial(bool exportMaterial) - { - m_exportMaterial = exportMaterial; - } - - void Config::setBuildEdgeLists(bool buildEdgeLists) - { - m_edgeLists = buildEdgeLists; - } - - void Config::setGenerateLod(bool generateLod) - { - m_generateLod = generateLod; - } - - void Config::setGenerateTangents(bool generateTangents) - { - m_generateTangents = generateTangents; - } - - void Config::setOptmizeBinaryMesh(bool optimize) - { - m_optimizeBinaryLayout = optimize; - } - - void Config::setVertexColourFormat(VertexColourFormat format) - { - m_colourFormat = format; - } - - void Config::setEndian(Endian endian) - { - m_endian = endian; - } - - void Config::setNumLodLevels(unsigned int levels) - { - m_numLodLevels = levels; - } - - void Config::setLodDistance(float dist) - { - m_lodDistance = dist; - } - - void Config::setLodPercentReduction(float percent) - { - m_lodPercent = percent; - } - - void Config::setLodVertexReduction(int count) - { - m_lodVertexCount = count; - } - - void Config::setExportSelected(bool selected) - { - m_exportSelectedObjects = selected; - } - - // - // version 2 - // - void Config::setMergeMeshes(bool merge) - { - m_mergeMeshes = merge; - } + Config::Config() { + // set defaults + m_exportSelectedObjects = false; // default to exporting everything in the scene + m_exportMultipleFiles = true; // default is to export a file per mesh object in the scene + m_useSingleSkeleton = true; // default for multiple meshes is to reference a single .skeleton file where applicable + m_rebuildNormals = false; // rebuild the normals before exporting mesh data + + m_exportMaterial = true; // default is to export material scripts + m_defaultMaterialName = "DefaultMaterial"; + m_2DTexCoord = UV; // default is UV interpretation of 2D tex coords + + m_invertNormals = false; // flip normals; will also reorder triangle vertex indices + m_flipYZ = false; // swap X and Z axes, so that Y becomes the One True Up Vector + m_exportVertexColors = false; // useful for vertex painting + m_scale = 1.0f; // export at normal size (scale) -- all vertices get multiplied by this + + m_exportSkeleton = false; // initially we don't assume any skeletal data + + m_fps = 25.0; // used for controller types (such as Biped) that do not support keyframes directly -- this is the sampling rate + + m_exportBinaryMesh = false; + m_exportXMLMesh = true; + + m_generateTangents = false; + m_edgeLists = true; + m_generateLod = false; + m_lodDistance = 0.0f; + m_numLodLevels = 0; + m_lodPercent = -1.0f; + m_lodVertexCount = -1; + m_endian = NATIVE; // let Ogre figure it out + m_colourFormat = DIRECT3D; // we can default to this since Max only runs on Windows + m_optimizeBinaryLayout = true; // why wouldn't we? ;) + + // version 2 + m_mergeMeshes = false; + } + + Config::Config(const Config& config) + { + *this = config; + } + + Config& Config::operator=(const Config& rhs) + { + m_generateTangents = rhs.m_generateTangents; + m_edgeLists = rhs.m_edgeLists; + m_generateLod = rhs.m_generateLod; + m_lodDistance = rhs.m_lodDistance; + m_numLodLevels = rhs.m_numLodLevels; + m_lodPercent = rhs.m_lodPercent; + m_lodVertexCount = rhs.m_lodVertexCount; + + return *this; + } + + Config::~Config() + { + } + + void Config::save() { + // write "this" to file named .cfg; note that we do not need to do the same massaging of + // file sizes that we do for reads since this will always output the latest version + std::ofstream of; + std::string fname = m_exportBasename + ".cfg"; + + // copy strings to buffers + strcpy(m_bufDefaultMaterialName, m_defaultMaterialName.c_str()); + strcpy(m_bufExportPath, m_exportPath.c_str()); + strcpy(m_bufExportBasename, m_exportBasename.c_str()); + strcpy(m_bufExportFilename, m_exportFilename.c_str()); + strcpy(m_bufMaterialFilename, m_materialFilename.c_str()); + strcpy(m_bufSkeletonFilename, m_skeletonFilename.c_str()); + + // set version number for sure + m_version = CURRENTVERSION; + + of.open(fname.c_str(), std::ios::binary | std::ios::out); + if (of.is_open()) { + of.write((char *)this, offsetof(Config, m_defaultMaterialName)); + of.close(); + } + } + + void Config::load() { + // read "this" from file named .cfg + std::ifstream f; + std::string fname = m_exportBasename + ".cfg"; + + f.open(fname.c_str(), std::ios::binary | std::ios::in); + if (f.is_open()) { + + // we need to check the version to see how much to read + f.read((char*)&m_version, sizeof(unsigned int)); + + // default size for latest version + size_t sz = offsetof(Config, m_defaultMaterialName); + + if (m_version < CURRENTVERSION) { + switch(m_version) { + case 1: + sz = offsetof(Config, m_bufSkeletonFilename) + sizeof(m_bufSkeletonFilename); + break; + case 2: + sz = offsetof(Config, m_mergeMeshes) + sizeof(m_mergeMeshes); + break; + } + } + + // read the calculated size, minus the unsigned int we already read + f.read(((char *)this + sizeof(unsigned int)), sz - sizeof(unsigned int)); + f.close(); + + // make strings from buffers + m_defaultMaterialName = m_bufDefaultMaterialName; + m_exportPath = m_bufExportPath; + m_exportBasename = m_bufExportBasename; + m_exportFilename = m_bufExportFilename; + m_materialFilename = m_bufMaterialFilename; + m_skeletonFilename = m_bufSkeletonFilename; + } + + // if we could not open the config file for any reason, skip it -- more than likely a new export + } + + void Config::setExportPath(const std::string& path) { + m_exportPath = path; + } + + void Config::setMaterialFilename(const std::string& name) { + m_materialFilename = name; + } + + void Config::setExportFilename(const std::string& name) { + // extract the filename and the export path + std::string filename = name; + size_t offset = filename.find_last_of('\\'); + m_exportPath = filename.substr(0, offset); + m_exportFilename = filename.substr(offset+1); + + // strip extension, if any + offset = m_exportFilename.find_last_of('.'); + if (m_exportFilename.substr(offset) == ".xml") + offset = m_exportFilename.substr(0, offset).find_last_of('.'); + + // set base filename + m_exportBasename = m_exportFilename.substr(0, offset); + } + + void Config::setSkeletonFilename(const std::string& name) { + m_skeletonFilename = name; + } + + void Config::setDefaultMaterialName(const std::string& name) { + m_defaultMaterialName = name; + } + + void Config::setTexCoord2D(Tex2D texCoord) { + m_2DTexCoord = texCoord; + } + + void Config::setScale(float scale) { + m_scale = scale; + } + + void Config::setFPS(float fps) { + m_fps = fps; + } + + void Config::setInvertYZ(bool invert) + { + m_flipYZ = invert; + } + + void Config::setInvertNormals(bool invert) + { + m_invertNormals = invert; + } + + void Config::setExportBinaryMesh(bool export) + { + m_exportBinaryMesh = export; + } + + void Config::setExportXMLMesh(bool export) + { + m_exportXMLMesh = export; + } + + void Config::setRebuildNormals(bool rebuild) + { + m_rebuildNormals = rebuild; + } + + void Config::setUseSingleSkeleton(bool useSingle) + { + m_useSingleSkeleton = useSingle; + } + + void Config::setExportSkeleton(bool exportSkeleton) + { + m_exportSkeleton = exportSkeleton; + } + + void Config::setExportMultipleFiles(bool exportMultiple) + { + m_exportMultipleFiles = exportMultiple; + } + + void Config::setExportVertexColours(bool exportVC) + { + m_exportVertexColors = exportVC; + } + + void Config::setExportMaterial(bool exportMaterial) + { + m_exportMaterial = exportMaterial; + } + + void Config::setBuildEdgeLists(bool buildEdgeLists) + { + m_edgeLists = buildEdgeLists; + } + + void Config::setGenerateLod(bool generateLod) + { + m_generateLod = generateLod; + } + + void Config::setGenerateTangents(bool generateTangents) + { + m_generateTangents = generateTangents; + } + + void Config::setOptmizeBinaryMesh(bool optimize) + { + m_optimizeBinaryLayout = optimize; + } + + void Config::setVertexColourFormat(VertexColourFormat format) + { + m_colourFormat = format; + } + + void Config::setEndian(Endian endian) + { + m_endian = endian; + } + + void Config::setNumLodLevels(unsigned int levels) + { + m_numLodLevels = levels; + } + + void Config::setLodDistance(float dist) + { + m_lodDistance = dist; + } + + void Config::setLodPercentReduction(float percent) + { + m_lodPercent = percent; + } + + void Config::setLodVertexReduction(int count) + { + m_lodVertexCount = count; + } + + void Config::setExportSelected(bool selected) + { + m_exportSelectedObjects = selected; + } + + // + // version 2 + // + void Config::setMergeMeshes(bool merge) + { + m_mergeMeshes = merge; + } } \ No newline at end of file diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExport.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExport.cpp index e314096d566..4bcc7e99b23 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExport.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExport.cpp @@ -49,316 +49,316 @@ THE SOFTWARE. static OgreMaxExport* _exp = 0; OgreMaxExport::OgreMaxExport(HINSTANCE hInst) : - m_meshExporter(m_config), - m_meshXMLExporter(m_config, m_materialMap), - m_materialExporter(m_config, m_materialMap), - m_tabGeneral(m_config, this), - m_tabMesh(m_config, this), - m_tabSkeletalAnimation(m_config, this), - m_tabVertexAnimation(m_config, this), - m_tabMaterial(m_config, this) + m_meshExporter(m_config), + m_meshXMLExporter(m_config, m_materialMap), + m_materialExporter(m_config, m_materialMap), + m_tabGeneral(m_config, this), + m_tabMesh(m_config, this), + m_tabSkeletalAnimation(m_config, this), + m_tabVertexAnimation(m_config, this), + m_tabMaterial(m_config, this) { - m_hInstance = hInst; - m_hWndDlgExport = 0; - m_tabDisplay = NULL; + m_hInstance = hInst; + m_hWndDlgExport = 0; + m_tabDisplay = NULL; } OgreMaxExport::~OgreMaxExport() { } -int OgreMaxExport::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options) { - - // this sets the export path as well - m_config.setExportFilename(name); - m_config.load(); // can only do this after the export fname has been set and parsed out into its parts - - // if material and skeleton filenames are not set, do so now - if (m_config.getMaterialFilename() == "") - m_config.setMaterialFilename(m_config.getExportBasename() + ".material"); - - if (m_config.getSkeletonFilename() == "") - m_config.setSkeletonFilename(m_config.getExportBasename() + ".skeleton"); - - m_meshExporter.setMaxInterface(ei, i); - m_meshXMLExporter.setMaxInterface(ei, i); - - m_tabGeneral.setExportInterface(ei, i); - m_tabMesh.setExportInterface(ei, i); - m_tabSkeletalAnimation.setExportInterface(ei, i); - m_tabVertexAnimation.setExportInterface(ei, i); - m_tabMaterial.setExportInterface(ei, i); - - // Max will supply a nonzero (specifically, SCENE_EXPORT_SELECTED) value for options if the user - // chose "Export Selected..." instead of "Export..." from the File menu - //m_meshExporter.setExportSelected(options == SCENE_EXPORT_SELECTED); - //m_meshXMLExporter.setExportSelected(options == SCENE_EXPORT_SELECTED); - m_config.setExportSelected(options == SCENE_EXPORT_SELECTED); - - int result = DialogBoxParam(m_hInstance, - MAKEINTRESOURCE(IDD_BINARY_EXPORT), - GetActiveWindow(), - ExportPropertiesDialogProc, - (LPARAM) this); - - switch (result) { - case 0: - return IMPEXP_CANCEL; - break; - case 1: - MessageBox(GetActiveWindow(), "Export Succeeded", "Sucessful Export", MB_ICONINFORMATION); - return IMPEXP_SUCCESS; - break; - default: - return IMPEXP_FAIL; - break; - } +int OgreMaxExport::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options) { + + // this sets the export path as well + m_config.setExportFilename(name); + m_config.load(); // can only do this after the export fname has been set and parsed out into its parts + + // if material and skeleton filenames are not set, do so now + if (m_config.getMaterialFilename() == "") + m_config.setMaterialFilename(m_config.getExportBasename() + ".material"); + + if (m_config.getSkeletonFilename() == "") + m_config.setSkeletonFilename(m_config.getExportBasename() + ".skeleton"); + + m_meshExporter.setMaxInterface(ei, i); + m_meshXMLExporter.setMaxInterface(ei, i); + + m_tabGeneral.setExportInterface(ei, i); + m_tabMesh.setExportInterface(ei, i); + m_tabSkeletalAnimation.setExportInterface(ei, i); + m_tabVertexAnimation.setExportInterface(ei, i); + m_tabMaterial.setExportInterface(ei, i); + + // Max will supply a nonzero (specifically, SCENE_EXPORT_SELECTED) value for options if the user + // chose "Export Selected..." instead of "Export..." from the File menu + //m_meshExporter.setExportSelected(options == SCENE_EXPORT_SELECTED); + //m_meshXMLExporter.setExportSelected(options == SCENE_EXPORT_SELECTED); + m_config.setExportSelected(options == SCENE_EXPORT_SELECTED); + + int result = DialogBoxParam(m_hInstance, + MAKEINTRESOURCE(IDD_BINARY_EXPORT), + GetActiveWindow(), + ExportPropertiesDialogProc, + (LPARAM) this); + + switch (result) { + case 0: + return IMPEXP_CANCEL; + break; + case 1: + MessageBox(GetActiveWindow(), "Export Succeeded", "Sucessful Export", MB_ICONINFORMATION); + return IMPEXP_SUCCESS; + break; + default: + return IMPEXP_FAIL; + break; + } } INT_PTR CALLBACK ExportPropertiesDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - switch(message) { - case WM_INITDIALOG: - _exp = (OgreMaxExport*) lParam; - - if (_exp == 0) { - MessageBox(NULL, "Error: Cannot initialize exporter options dialog, aborting", "Error", MB_ICONEXCLAMATION); - EndDialog(hDlg, 0); - return TRUE; - } - - _exp->m_hWndDlgExport = hDlg; - - return _exp->setupExportProperties(); - break; - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDOK: - case IDC_EXPORT: - if (_exp->export()) - EndDialog(hDlg, 1); - else - EndDialog(hDlg, 2); - return TRUE; - case IDCANCEL: - EndDialog(hDlg, 0); - return TRUE; - } - break; - case WM_NOTIFY: - switch(wParam) { - case IDC_TABCONTROL: - switch(((LPNMHDR)lParam)->code) { - case TCN_SELCHANGE: - _exp->onTabSelectChange(((LPNMHDR)lParam)->hwndFrom, ((LPNMHDR)lParam)->idFrom); - break; - } - break; - } - break; - } - return FALSE; + switch(message) { + case WM_INITDIALOG: + _exp = (OgreMaxExport*) lParam; + + if (_exp == 0) { + MessageBox(NULL, "Error: Cannot initialize exporter options dialog, aborting", "Error", MB_ICONEXCLAMATION); + EndDialog(hDlg, 0); + return TRUE; + } + + _exp->m_hWndDlgExport = hDlg; + + return _exp->setupExportProperties(); + break; + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDOK: + case IDC_EXPORT: + if (_exp->export()) + EndDialog(hDlg, 1); + else + EndDialog(hDlg, 2); + return TRUE; + case IDCANCEL: + EndDialog(hDlg, 0); + return TRUE; + } + break; + case WM_NOTIFY: + switch(wParam) { + case IDC_TABCONTROL: + switch(((LPNMHDR)lParam)->code) { + case TCN_SELCHANGE: + _exp->onTabSelectChange(((LPNMHDR)lParam)->hwndFrom, ((LPNMHDR)lParam)->idFrom); + break; + } + break; + } + break; + } + return FALSE; } bool OgreMaxExport::export() { - // do mesh export -- either/both of XML and binary - if (m_config.getExportXMLMesh()) { + // do mesh export -- either/both of XML and binary + if (m_config.getExportXMLMesh()) { - if (m_tabDisplay != 0) - m_tabDisplay->update(); + if (m_tabDisplay != 0) + m_tabDisplay->update(); - OgreMax::MeshXMLExporter::OutputMap output; + OgreMax::MeshXMLExporter::OutputMap output; - if (m_meshXMLExporter.buildMeshXML(output)) { - m_config.save(); + if (m_meshXMLExporter.buildMeshXML(output)) { + m_config.save(); - // write each of the files and their contents - OgreMax::MeshXMLExporter::OutputMap::iterator it = output.begin(); + // write each of the files and their contents + OgreMax::MeshXMLExporter::OutputMap::iterator it = output.begin(); - while (it != output.end()) { - std::ofstream of; - of.open(it->first.c_str(), std::ios::out); - of << it->second; - of.close(); - it++; - } + while (it != output.end()) { + std::ofstream of; + of.open(it->first.c_str(), std::ios::out); + of << it->second; + of.close(); + it++; + } - // export material for this (these) mesh(es) - /* - if (m_config.getExportMaterial()) { + // export material for this (these) mesh(es) + /* + if (m_config.getExportMaterial()) { - std::string materialScript; + std::string materialScript; - std::ofstream of; - if (m_materialExporter.buildMaterial(materialScript)) { - of.open((m_config.getExportPath() + "\\" + m_config.getMaterialFilename()).c_str(), std::ios::out); + std::ofstream of; + if (m_materialExporter.buildMaterial(materialScript)) { + of.open((m_config.getExportPath() + "\\" + m_config.getMaterialFilename()).c_str(), std::ios::out); - if (of.is_open()) { - of << materialScript; - of.close(); - } - } - } - */ - } - else { - } - } + if (of.is_open()) { + of << materialScript; + of.close(); + } + } + } + */ + } + else { + } + } - return true; + return true; } void OgreMaxExport::onTabSelectChange(HWND hWnd, INT id) { - int iSel = TabCtrl_GetCurSel(hWnd); - - // clear any existing property page - if (m_tabDisplay != NULL) { - m_tabDisplay->update(); - DestroyWindow(m_tabDisplay->getDialogHandle()); - } - - // create a new property page - switch(iSel) { - case 0: - CreateDialogParam( - m_hInstance, - MAKEINTRESOURCE(IDD_TAB_GENERAL), - hWnd, - GeneralTabDialogProc, - (LPARAM)&m_tabGeneral); - m_tabDisplay = &m_tabGeneral; - break; - case 1: - CreateDialogParam( - m_hInstance, - MAKEINTRESOURCE(IDD_TAB_MESH), - hWnd, - MeshTabDialogProc, - (LPARAM)&m_tabMesh); - m_tabDisplay = &m_tabMesh; - break; - case 2: - CreateDialogParam( - m_hInstance, - MAKEINTRESOURCE(IDD_TAB_SKELETAL_ANIMATION), - hWnd, - SkeletalAnimationTabDialogProc, - (LPARAM)&m_tabSkeletalAnimation); - m_tabDisplay = &m_tabSkeletalAnimation; - break; - case 3: - CreateDialogParam( - m_hInstance, - MAKEINTRESOURCE(IDD_TAB_VERTEX_ANIMATION), - hWnd, - VertexAnimationTabDialogProc, - (LPARAM)&m_tabVertexAnimation); - m_tabDisplay = &m_tabVertexAnimation; - break; - case 4: - CreateDialogParam( - m_hInstance, - MAKEINTRESOURCE(IDD_TAB_MATERIAL), - hWnd, - MaterialTabDialogProc, - (LPARAM)&m_tabMaterial); - m_tabDisplay = &m_tabMaterial; - break; - } + int iSel = TabCtrl_GetCurSel(hWnd); + + // clear any existing property page + if (m_tabDisplay != NULL) { + m_tabDisplay->update(); + DestroyWindow(m_tabDisplay->getDialogHandle()); + } + + // create a new property page + switch(iSel) { + case 0: + CreateDialogParam( + m_hInstance, + MAKEINTRESOURCE(IDD_TAB_GENERAL), + hWnd, + GeneralTabDialogProc, + (LPARAM)&m_tabGeneral); + m_tabDisplay = &m_tabGeneral; + break; + case 1: + CreateDialogParam( + m_hInstance, + MAKEINTRESOURCE(IDD_TAB_MESH), + hWnd, + MeshTabDialogProc, + (LPARAM)&m_tabMesh); + m_tabDisplay = &m_tabMesh; + break; + case 2: + CreateDialogParam( + m_hInstance, + MAKEINTRESOURCE(IDD_TAB_SKELETAL_ANIMATION), + hWnd, + SkeletalAnimationTabDialogProc, + (LPARAM)&m_tabSkeletalAnimation); + m_tabDisplay = &m_tabSkeletalAnimation; + break; + case 3: + CreateDialogParam( + m_hInstance, + MAKEINTRESOURCE(IDD_TAB_VERTEX_ANIMATION), + hWnd, + VertexAnimationTabDialogProc, + (LPARAM)&m_tabVertexAnimation); + m_tabDisplay = &m_tabVertexAnimation; + break; + case 4: + CreateDialogParam( + m_hInstance, + MAKEINTRESOURCE(IDD_TAB_MATERIAL), + hWnd, + MaterialTabDialogProc, + (LPARAM)&m_tabMaterial); + m_tabDisplay = &m_tabMaterial; + break; + } } BOOL OgreMaxExport::setupExportProperties() { - // add tabs to the tab control - TCITEM tci; - HWND tabCtrl = GetDlgItem(m_hWndDlgExport, IDC_TABCONTROL); + // add tabs to the tab control + TCITEM tci; + HWND tabCtrl = GetDlgItem(m_hWndDlgExport, IDC_TABCONTROL); - tci.mask = TCIF_TEXT; - tci.pszText = "General"; - TabCtrl_InsertItem(tabCtrl, 0, &tci); - tci.pszText = "Mesh"; - TabCtrl_InsertItem(tabCtrl, 1, &tci); - tci.pszText = "Skeletal Animation"; - TabCtrl_InsertItem(tabCtrl, 2, &tci); - tci.pszText = "Vertex Animation"; - TabCtrl_InsertItem(tabCtrl, 3, &tci); - tci.pszText = "Material"; - TabCtrl_InsertItem(tabCtrl, 4, &tci); + tci.mask = TCIF_TEXT; + tci.pszText = "General"; + TabCtrl_InsertItem(tabCtrl, 0, &tci); + tci.pszText = "Mesh"; + TabCtrl_InsertItem(tabCtrl, 1, &tci); + tci.pszText = "Skeletal Animation"; + TabCtrl_InsertItem(tabCtrl, 2, &tci); + tci.pszText = "Vertex Animation"; + TabCtrl_InsertItem(tabCtrl, 3, &tci); + tci.pszText = "Material"; + TabCtrl_InsertItem(tabCtrl, 4, &tci); - // simulate tab select - onTabSelectChange(tabCtrl, IDC_TABCONTROL); + // simulate tab select + onTabSelectChange(tabCtrl, IDC_TABCONTROL); - std::string filename; + std::string filename; - CenterWindow(m_hWndDlgExport,GetParent(m_hWndDlgExport)); + CenterWindow(m_hWndDlgExport,GetParent(m_hWndDlgExport)); - return TRUE; + return TRUE; } int OgreMaxExport::ExtCount() { - // support .xml, .mesh, .material, .skeleton - return 4; + // support .xml, .mesh, .material, .skeleton + return 4; } const TCHAR * OgreMaxExport::Ext(int n) { - switch (n) { - case 0: - return _T("xml"); - break; - case 1: - return _T("mesh"); - break; - case 2: - return _T("skeleton"); - break; - case 3: - return _T("material"); - break; - default: - return 0; - break; - } + switch (n) { + case 0: + return _T("xml"); + break; + case 1: + return _T("mesh"); + break; + case 2: + return _T("skeleton"); + break; + case 3: + return _T("material"); + break; + default: + return 0; + break; + } } const TCHAR * OgreMaxExport::LongDesc() { - return _T("OGRE 3D Mesh/Animation/Material Exporter"); + return _T("OGRE 3D Mesh/Animation/Material Exporter"); } const TCHAR * OgreMaxExport::ShortDesc() { - return _T("OGRE 3D Exporter"); + return _T("OGRE 3D Exporter"); } const TCHAR * OgreMaxExport::AuthorName() { - return _T("Gregory 'Xavier' Junker"); + return _T("Gregory 'Xavier' Junker"); } const TCHAR * OgreMaxExport::CopyrightMessage() { - return _T("The OGRE 3D Team (c) 2006"); + return _T("The OGRE 3D Team (c) 2006"); } const TCHAR * OgreMaxExport::OtherMessage1() { - return 0; + return 0; } const TCHAR * OgreMaxExport::OtherMessage2() { - return 0; + return 0; } unsigned int OgreMaxExport::Version() { - return 122; + return 122; } void OgreMaxExport::ShowAbout(HWND hWnd) { - MessageBox(hWnd, "OGRE 3D Mesh, Material and Animation Exporter", "About", 0); + MessageBox(hWnd, "OGRE 3D Mesh, Material and Animation Exporter", "About", 0); } BOOL OgreMaxExport::SupportsOptions(int ext, DWORD options) { - // currently, only SCENE_EXPORT_SELECTED is passed to this; we support exporting - // of selected files only, so return TRUE (if they ever add anything later, we'll - // either support it too, or check what they are asking and return accordingly). - return TRUE; + // currently, only SCENE_EXPORT_SELECTED is passed to this; we support exporting + // of selected files only, so return TRUE (if they ever add anything later, we'll + // either support it too, or check what they are asking and return accordingly). + return TRUE; } diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabGeneral.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabGeneral.cpp index fff3fa27b5b..eb23b771881 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabGeneral.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabGeneral.cpp @@ -4,83 +4,83 @@ static OgreMaxExport_General* sInst; void OgreMaxExport_General::onInitDialog(HWND hDlg) { - OgreMaxExport_TabPaneHandler::onInitDialog(hDlg); + OgreMaxExport_TabPaneHandler::onInitDialog(hDlg); - // set the initial dialog state - std::stringstream ss; - SetWindowText(GetDlgItem(m_hDlg, IDC_TXT_EXPORT_DIR), m_config.getExportPath().c_str()); - SendMessage(GetDlgItem(m_hDlg, IDC_CHK_FLIP_YZ), BM_SETCHECK, (m_config.getInvertYZ() ? BST_CHECKED : BST_UNCHECKED), 0); + // set the initial dialog state + std::stringstream ss; + SetWindowText(GetDlgItem(m_hDlg, IDC_TXT_EXPORT_DIR), m_config.getExportPath().c_str()); + SendMessage(GetDlgItem(m_hDlg, IDC_CHK_FLIP_YZ), BM_SETCHECK, (m_config.getInvertYZ() ? BST_CHECKED : BST_UNCHECKED), 0); - ss << m_config.getScale(); - SetWindowText(GetDlgItem(m_hDlg, IDC_TXT_SCALE), ss.str().c_str()); + ss << m_config.getScale(); + SetWindowText(GetDlgItem(m_hDlg, IDC_TXT_SCALE), ss.str().c_str()); } void OgreMaxExport_General::onInvertYZ(bool checked) { - m_config.setInvertYZ(checked); + m_config.setInvertYZ(checked); } void OgreMaxExport_General::onSetScale(float newScale) { } void OgreMaxExport_General::onExportDirectoryChanged(const std::string& newDirectory) { - m_config.setExportPath(newDirectory); + m_config.setExportPath(newDirectory); } void OgreMaxExport_General::onDestroy() { - update(); + update(); } // read the contents from the dialog controls void OgreMaxExport_General::update() { - char buf[64]; + char buf[64]; - // export path is not settable in the dialog at this time, skip it + // export path is not settable in the dialog at this time, skip it - // get the scale and invert-YZ settings - m_config.setInvertYZ(BST_CHECKED==IsDlgButtonChecked(m_hDlg, IDC_CHK_FLIP_YZ)); + // get the scale and invert-YZ settings + m_config.setInvertYZ(BST_CHECKED==IsDlgButtonChecked(m_hDlg, IDC_CHK_FLIP_YZ)); - // we really can only do this here unless we want to process every keystroke in the scale edit box - GetWindowText(GetDlgItem(m_hDlg, IDC_TXT_SCALE), buf, 64); - float scale = atof(buf); + // we really can only do this here unless we want to process every keystroke in the scale edit box + GetWindowText(GetDlgItem(m_hDlg, IDC_TXT_SCALE), buf, 64); + float scale = atof(buf); - if (scale == 0.0f) //sets to 0.0 if the text cannot be converted; change to 1.0 in that case - scale = 1.0f; + if (scale == 0.0f) //sets to 0.0 if the text cannot be converted; change to 1.0 in that case + scale = 1.0f; - m_config.setScale(scale); + m_config.setScale(scale); } // for the sake of sanity, keep the dlgproc and the handler class implementation here in the same source file INT_PTR CALLBACK GeneralTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - switch(message) { - case WM_INITDIALOG: - sInst = (OgreMaxExport_General*) lParam; - - sInst->onInitDialog(hDlg); - SetWindowPos(hDlg, HWND_TOP, 10, 40, 0, 0, SWP_NOSIZE); - ShowWindow(hDlg, SW_SHOW); - break; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDC_SELECT_EXPORT_DIR: - switch(HIWORD(wParam)) { - case BN_CLICKED: - break; - - } - break; - case IDC_CHK_FLIP_YZ: - sInst->onInvertYZ(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_CHK_FLIP_YZ)); - break; - } - break; - - case WM_DESTROY: - sInst->onDestroy(); - break; - } - return FALSE; + switch(message) { + case WM_INITDIALOG: + sInst = (OgreMaxExport_General*) lParam; + + sInst->onInitDialog(hDlg); + SetWindowPos(hDlg, HWND_TOP, 10, 40, 0, 0, SWP_NOSIZE); + ShowWindow(hDlg, SW_SHOW); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_SELECT_EXPORT_DIR: + switch(HIWORD(wParam)) { + case BN_CLICKED: + break; + + } + break; + case IDC_CHK_FLIP_YZ: + sInst->onInvertYZ(BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_CHK_FLIP_YZ)); + break; + } + break; + + case WM_DESTROY: + sInst->onDestroy(); + break; + } + return FALSE; } diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabMaterial.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabMaterial.cpp index 3f291e5fc3a..3c95a19d337 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabMaterial.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabMaterial.cpp @@ -4,11 +4,11 @@ static OgreMaxExport_Material* sInst; void OgreMaxExport_Material::onInitDialog(HWND hDlg) { - OgreMaxExport_TabPaneHandler::onInitDialog(hDlg); + OgreMaxExport_TabPaneHandler::onInitDialog(hDlg); } void OgreMaxExport_Material::onDestroy() { - update(); + update(); } // read the contents from the dialog controls @@ -19,23 +19,23 @@ void OgreMaxExport_Material::update() { // for the sake of sanity, keep the dlgproc and the handler class implementation here in the same source file INT_PTR CALLBACK MaterialTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - switch(message) { - case WM_INITDIALOG: - sInst = (OgreMaxExport_Material*) lParam; - - sInst->onInitDialog(hDlg); - SetWindowPos(hDlg, HWND_TOP, 10, 40, 0, 0, SWP_NOSIZE); - ShowWindow(hDlg, SW_SHOW); - break; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - } - break; - - case WM_DESTROY: - sInst->onDestroy(); - break; - } - return FALSE; + switch(message) { + case WM_INITDIALOG: + sInst = (OgreMaxExport_Material*) lParam; + + sInst->onInitDialog(hDlg); + SetWindowPos(hDlg, HWND_TOP, 10, 40, 0, 0, SWP_NOSIZE); + ShowWindow(hDlg, SW_SHOW); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + } + break; + + case WM_DESTROY: + sInst->onDestroy(); + break; + } + return FALSE; } diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabMesh.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabMesh.cpp index e1ab81cf1a4..909f499ef4f 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabMesh.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabMesh.cpp @@ -4,149 +4,149 @@ static OgreMaxExport_Mesh* sInst; void OgreMaxExport_Mesh::onInitDialog(HWND hDlg) { - OgreMaxExport_TabPaneHandler::onInitDialog(hDlg); - - // set tab pane initial values - CheckDlgButton(hDlg, IDC_RADIO_EXPORT_SUBMESHES, m_config.getExportMultipleFiles() ? BST_UNCHECKED : BST_CHECKED); - CheckDlgButton(hDlg, IDC_RADIO_EXPORT_FILES, m_config.getExportMultipleFiles() ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hDlg, IDC_CHK_SHARE_SKELETON, m_config.getUseSingleSkeleton() ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hDlg, IDC_CHK_REBUILD_NORMALS, m_config.getRebuildNormals() ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hDlg, IDC_CHK_INVERT_NORMALS, m_config.getInvertNormals() ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hDlg, IDC_CHK_VERTEX_COLORS, m_config.getExportVertexColours() ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hDlg, IDC_CHK_MERGE_MESHES, m_config.getMergeMeshes() ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hDlg, IDC_CHK_BINARY_MESH, m_config.getExportBinaryMesh() ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hDlg, IDC_CHK_GENERATE_TANGENTS, m_config.getGenerateTangents() ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hDlg, IDC_CHK_GENERATE_EDGELISTS, m_config.getBuildEdgeLists() ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hDlg, IDC_CHK_OPTIMIZE, m_config.getOptmizeBinaryMesh() ? BST_CHECKED : BST_UNCHECKED); - - SendMessage(GetDlgItem(hDlg, IDC_COLOR_FORMAT), CB_ADDSTRING, 0, (LPARAM)_T("Direct3D")); - SendMessage(GetDlgItem(hDlg, IDC_COLOR_FORMAT), CB_SETITEMDATA, 0, (LPARAM)(DWORD)OgreMax::DIRECT3D); - SendMessage(GetDlgItem(hDlg, IDC_COLOR_FORMAT), CB_ADDSTRING, 0, (LPARAM)_T("OpenGL")); - SendMessage(GetDlgItem(hDlg, IDC_COLOR_FORMAT), CB_SETITEMDATA, 1, (LPARAM)(DWORD)OgreMax::OPENGL); - - SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_ADDSTRING, 0, (LPARAM)_T("Native")); - SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_SETITEMDATA, 0, (LPARAM)(DWORD)OgreMax::NATIVE); - SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_ADDSTRING, 0, (LPARAM)_T("Big Endian")); - SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_SETITEMDATA, 1, (LPARAM)(DWORD)OgreMax::BIG); - SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_ADDSTRING, 0, (LPARAM)_T("Little Endian")); - SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_SETITEMDATA, 2, (LPARAM)(DWORD)OgreMax::LITTLE); - - SendMessage(GetDlgItem(hDlg, IDC_COLOR_FORMAT), CB_SETCURSEL, (WPARAM)m_config.getVertexColourFormat(), 0); - SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_SETCURSEL, (WPARAM)m_config.getEndian(), 0); - - CheckDlgButton(hDlg, IDC_CHK_GENERATE_LOD, m_config.getGenerateLod() ? BST_CHECKED : BST_UNCHECKED); - - std::stringstream ss; - ss << m_config.getNumLodLevels(); - SetWindowText(GetDlgItem(hDlg, IDC_LOD_NUM_LEVELS), ss.str().c_str()); - - ss.str(""); - ss << m_config.getLodDistance(); - SetWindowText(GetDlgItem(hDlg, IDC_LOD_DISTANCE), ss.str().c_str()); - - ss.str(""); - ss << m_config.getLodPercentReduction(); - SetWindowText(GetDlgItem(hDlg, IDC_LOD_PERCENT), ss.str().c_str()); - - ss.str(""); - ss << m_config.getLodVertexReduction(); - SetWindowText(GetDlgItem(hDlg, IDC_LOD_VERTEX_COUNT), ss.str().c_str()); - - // disable controls that are not "on" in particular modes - setControlStates(); + OgreMaxExport_TabPaneHandler::onInitDialog(hDlg); + + // set tab pane initial values + CheckDlgButton(hDlg, IDC_RADIO_EXPORT_SUBMESHES, m_config.getExportMultipleFiles() ? BST_UNCHECKED : BST_CHECKED); + CheckDlgButton(hDlg, IDC_RADIO_EXPORT_FILES, m_config.getExportMultipleFiles() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_CHK_SHARE_SKELETON, m_config.getUseSingleSkeleton() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_CHK_REBUILD_NORMALS, m_config.getRebuildNormals() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_CHK_INVERT_NORMALS, m_config.getInvertNormals() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_CHK_VERTEX_COLORS, m_config.getExportVertexColours() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_CHK_MERGE_MESHES, m_config.getMergeMeshes() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_CHK_BINARY_MESH, m_config.getExportBinaryMesh() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_CHK_GENERATE_TANGENTS, m_config.getGenerateTangents() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_CHK_GENERATE_EDGELISTS, m_config.getBuildEdgeLists() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hDlg, IDC_CHK_OPTIMIZE, m_config.getOptmizeBinaryMesh() ? BST_CHECKED : BST_UNCHECKED); + + SendMessage(GetDlgItem(hDlg, IDC_COLOR_FORMAT), CB_ADDSTRING, 0, (LPARAM)_T("Direct3D")); + SendMessage(GetDlgItem(hDlg, IDC_COLOR_FORMAT), CB_SETITEMDATA, 0, (LPARAM)(DWORD)OgreMax::DIRECT3D); + SendMessage(GetDlgItem(hDlg, IDC_COLOR_FORMAT), CB_ADDSTRING, 0, (LPARAM)_T("OpenGL")); + SendMessage(GetDlgItem(hDlg, IDC_COLOR_FORMAT), CB_SETITEMDATA, 1, (LPARAM)(DWORD)OgreMax::OPENGL); + + SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_ADDSTRING, 0, (LPARAM)_T("Native")); + SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_SETITEMDATA, 0, (LPARAM)(DWORD)OgreMax::NATIVE); + SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_ADDSTRING, 0, (LPARAM)_T("Big Endian")); + SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_SETITEMDATA, 1, (LPARAM)(DWORD)OgreMax::BIG); + SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_ADDSTRING, 0, (LPARAM)_T("Little Endian")); + SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_SETITEMDATA, 2, (LPARAM)(DWORD)OgreMax::LITTLE); + + SendMessage(GetDlgItem(hDlg, IDC_COLOR_FORMAT), CB_SETCURSEL, (WPARAM)m_config.getVertexColourFormat(), 0); + SendMessage(GetDlgItem(hDlg, IDC_ENDIAN), CB_SETCURSEL, (WPARAM)m_config.getEndian(), 0); + + CheckDlgButton(hDlg, IDC_CHK_GENERATE_LOD, m_config.getGenerateLod() ? BST_CHECKED : BST_UNCHECKED); + + std::stringstream ss; + ss << m_config.getNumLodLevels(); + SetWindowText(GetDlgItem(hDlg, IDC_LOD_NUM_LEVELS), ss.str().c_str()); + + ss.str(""); + ss << m_config.getLodDistance(); + SetWindowText(GetDlgItem(hDlg, IDC_LOD_DISTANCE), ss.str().c_str()); + + ss.str(""); + ss << m_config.getLodPercentReduction(); + SetWindowText(GetDlgItem(hDlg, IDC_LOD_PERCENT), ss.str().c_str()); + + ss.str(""); + ss << m_config.getLodVertexReduction(); + SetWindowText(GetDlgItem(hDlg, IDC_LOD_VERTEX_COUNT), ss.str().c_str()); + + // disable controls that are not "on" in particular modes + setControlStates(); } void OgreMaxExport_Mesh::onDestroy() { - update(); + update(); } // read the contents from the dialog controls void OgreMaxExport_Mesh::update() { - // get tab pane values - m_config.setExportMultipleFiles(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_RADIO_EXPORT_FILES)); - m_config.setUseSingleSkeleton(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_SHARE_SKELETON)); - m_config.setRebuildNormals(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_REBUILD_NORMALS)); - m_config.setInvertNormals(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_INVERT_NORMALS)); - m_config.setExportVertexColours(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_VERTEX_COLORS)); - m_config.setMergeMeshes(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_MERGE_MESHES)); - m_config.setExportBinaryMesh(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_BINARY_MESH)); - m_config.setGenerateTangents(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_GENERATE_TANGENTS)); - m_config.setBuildEdgeLists(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_GENERATE_EDGELISTS)); - m_config.setOptmizeBinaryMesh(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_OPTIMIZE)); - - LRESULT item = SendMessage(GetDlgItem(m_hDlg, IDC_COLOR_FORMAT), CB_GETCURSEL, 0, 0); - m_config.setVertexColourFormat((OgreMax::VertexColourFormat)SendMessage(GetDlgItem(m_hDlg, IDC_COLOR_FORMAT), CB_GETITEMDATA, item, 0)); - item = SendMessage(GetDlgItem(m_hDlg, IDC_ENDIAN), CB_GETCURSEL, 0, 0); - m_config.setEndian((OgreMax::Endian)SendMessage(GetDlgItem(m_hDlg, IDC_ENDIAN), CB_GETITEMDATA, item, 0)); - - m_config.setGenerateLod(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_GENERATE_LOD)); - - char buf[16]; - GetWindowText(GetDlgItem(m_hDlg, IDC_LOD_NUM_LEVELS), buf, 16); - m_config.setNumLodLevels(atoi(buf)); - GetWindowText(GetDlgItem(m_hDlg, IDC_LOD_DISTANCE), buf, 16); - m_config.setLodDistance(atof(buf)); - GetWindowText(GetDlgItem(m_hDlg, IDC_LOD_PERCENT), buf, 16); - m_config.setLodPercentReduction(atof(buf)); - GetWindowText(GetDlgItem(m_hDlg, IDC_LOD_VERTEX_COUNT), buf, 16); - m_config.setLodVertexReduction(atoi(buf)); + // get tab pane values + m_config.setExportMultipleFiles(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_RADIO_EXPORT_FILES)); + m_config.setUseSingleSkeleton(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_SHARE_SKELETON)); + m_config.setRebuildNormals(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_REBUILD_NORMALS)); + m_config.setInvertNormals(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_INVERT_NORMALS)); + m_config.setExportVertexColours(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_VERTEX_COLORS)); + m_config.setMergeMeshes(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_MERGE_MESHES)); + m_config.setExportBinaryMesh(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_BINARY_MESH)); + m_config.setGenerateTangents(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_GENERATE_TANGENTS)); + m_config.setBuildEdgeLists(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_GENERATE_EDGELISTS)); + m_config.setOptmizeBinaryMesh(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_OPTIMIZE)); + + LRESULT item = SendMessage(GetDlgItem(m_hDlg, IDC_COLOR_FORMAT), CB_GETCURSEL, 0, 0); + m_config.setVertexColourFormat((OgreMax::VertexColourFormat)SendMessage(GetDlgItem(m_hDlg, IDC_COLOR_FORMAT), CB_GETITEMDATA, item, 0)); + item = SendMessage(GetDlgItem(m_hDlg, IDC_ENDIAN), CB_GETCURSEL, 0, 0); + m_config.setEndian((OgreMax::Endian)SendMessage(GetDlgItem(m_hDlg, IDC_ENDIAN), CB_GETITEMDATA, item, 0)); + + m_config.setGenerateLod(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_GENERATE_LOD)); + + char buf[16]; + GetWindowText(GetDlgItem(m_hDlg, IDC_LOD_NUM_LEVELS), buf, 16); + m_config.setNumLodLevels(atoi(buf)); + GetWindowText(GetDlgItem(m_hDlg, IDC_LOD_DISTANCE), buf, 16); + m_config.setLodDistance(atof(buf)); + GetWindowText(GetDlgItem(m_hDlg, IDC_LOD_PERCENT), buf, 16); + m_config.setLodPercentReduction(atof(buf)); + GetWindowText(GetDlgItem(m_hDlg, IDC_LOD_VERTEX_COUNT), buf, 16); + m_config.setLodVertexReduction(atoi(buf)); } void OgreMaxExport_Mesh::onClickBinaryMesh() { - m_config.setExportBinaryMesh(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_BINARY_MESH)); - setControlStates(); + m_config.setExportBinaryMesh(BST_CHECKED == IsDlgButtonChecked(m_hDlg, IDC_CHK_BINARY_MESH)); + setControlStates(); } // set control enabled/disabled states void OgreMaxExport_Mesh::setControlStates() { - BOOL enable = FALSE; - if (m_config.getExportBinaryMesh()) { - enable = TRUE; - } - - EnableWindow(GetDlgItem(m_hDlg, IDC_CHK_GENERATE_TANGENTS), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_CHK_GENERATE_EDGELISTS), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_CHK_OPTIMIZE), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_USE_PERCENT), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_USE_VERTEX), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_COLOR_FORMAT), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_ENDIAN), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_CHK_GENERATE_LOD), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_NUM_LEVELS), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_DISTANCE), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_PERCENT), enable); - EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_VERTEX_COUNT), enable); + BOOL enable = FALSE; + if (m_config.getExportBinaryMesh()) { + enable = TRUE; + } + + EnableWindow(GetDlgItem(m_hDlg, IDC_CHK_GENERATE_TANGENTS), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_CHK_GENERATE_EDGELISTS), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_CHK_OPTIMIZE), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_USE_PERCENT), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_USE_VERTEX), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_COLOR_FORMAT), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_ENDIAN), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_CHK_GENERATE_LOD), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_NUM_LEVELS), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_DISTANCE), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_PERCENT), enable); + EnableWindow(GetDlgItem(m_hDlg, IDC_LOD_VERTEX_COUNT), enable); } // for the sake of sanity, keep the dlgproc and the handler class implementation here in the same source file INT_PTR CALLBACK MeshTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - switch(message) { - case WM_INITDIALOG: - sInst = (OgreMaxExport_Mesh*) lParam; - - sInst->onInitDialog(hDlg); - SetWindowPos(hDlg, HWND_TOP, 10, 40, 0, 0, SWP_NOSIZE); - ShowWindow(hDlg, SW_SHOW); - break; - - case WM_COMMAND: - switch(HIWORD(wParam)) { - case BN_CLICKED: - switch(LOWORD(wParam)) { - case IDC_CHK_BINARY_MESH: - sInst->onClickBinaryMesh(); - break; - } - break; - } - break; - - case WM_DESTROY: - sInst->onDestroy(); - break; - } - return FALSE; + switch(message) { + case WM_INITDIALOG: + sInst = (OgreMaxExport_Mesh*) lParam; + + sInst->onInitDialog(hDlg); + SetWindowPos(hDlg, HWND_TOP, 10, 40, 0, 0, SWP_NOSIZE); + ShowWindow(hDlg, SW_SHOW); + break; + + case WM_COMMAND: + switch(HIWORD(wParam)) { + case BN_CLICKED: + switch(LOWORD(wParam)) { + case IDC_CHK_BINARY_MESH: + sInst->onClickBinaryMesh(); + break; + } + break; + } + break; + + case WM_DESTROY: + sInst->onDestroy(); + break; + } + return FALSE; } diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabSkeletalAnimation.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabSkeletalAnimation.cpp index b8e5683da07..ad39fce6be1 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabSkeletalAnimation.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabSkeletalAnimation.cpp @@ -4,58 +4,58 @@ static OgreMaxExport_SkeletalAnimation* sInst; void OgreMaxExport_SkeletalAnimation::onInitDialog(HWND hDlg) { - OgreMaxExport_TabPaneHandler::onInitDialog(hDlg); - - // set up animation listbox - int frameStart = m_i->GetAnimRange().Start(); - int frameEnd = m_i->GetAnimRange().End(); - - HWND anims = GetDlgItem(m_hDlg, IDC_LIST_ANIMATIONS); - - Rect r; - GetWindowRect(anims, &r); - - LVCOLUMN lvc; - ZeroMemory(&lvc, sizeof(LVCOLUMN)); - lvc.mask = LVCF_TEXT | LVCF_WIDTH; - lvc.cx = r.w() * 0.6; - lvc.pszText = "Animation"; - ListView_InsertColumn(anims, 0, &lvc); - lvc.cx = r.w() * 0.2; - lvc.pszText = "Begin"; - ListView_InsertColumn(anims, 1, &lvc); - lvc.pszText = "End"; - ListView_InsertColumn(anims, 2, &lvc); - - // add a spanning entry to the animation list as a default - LVITEM lvi; - char buf[32]; - ZeroMemory(&lvi, sizeof(LVITEM)); - - lvi.mask = LVIF_TEXT; - lvi.pszText = "Animation"; - lvi.iItem = 10000; - int idx = ListView_InsertItem(anims, &lvi); - - sprintf(buf, "%d", frameStart / GetTicksPerFrame()); - lvi.iItem = idx; - lvi.iSubItem = 1; - lvi.pszText = buf; - ListView_SetItem(anims, &lvi); - - sprintf(buf, "%d", frameEnd / GetTicksPerFrame()); - lvi.iSubItem = 2; - lvi.pszText = buf; - ListView_SetItem(anims, &lvi); - - // populate the frame range info box - sprintf(buf, "%d to %d", frameStart / GetTicksPerFrame(), frameEnd / GetTicksPerFrame()); - SendMessage(GetDlgItem(m_hDlg, IDC_TXT_FRAME_RANGE), WM_SETTEXT, 0, (LPARAM)buf); - SendMessage(GetDlgItem(m_hDlg, IDC_TXT_FPS), WM_SETTEXT, 0, (LPARAM)_T("1.0")); + OgreMaxExport_TabPaneHandler::onInitDialog(hDlg); + + // set up animation listbox + int frameStart = m_i->GetAnimRange().Start(); + int frameEnd = m_i->GetAnimRange().End(); + + HWND anims = GetDlgItem(m_hDlg, IDC_LIST_ANIMATIONS); + + Rect r; + GetWindowRect(anims, &r); + + LVCOLUMN lvc; + ZeroMemory(&lvc, sizeof(LVCOLUMN)); + lvc.mask = LVCF_TEXT | LVCF_WIDTH; + lvc.cx = r.w() * 0.6; + lvc.pszText = "Animation"; + ListView_InsertColumn(anims, 0, &lvc); + lvc.cx = r.w() * 0.2; + lvc.pszText = "Begin"; + ListView_InsertColumn(anims, 1, &lvc); + lvc.pszText = "End"; + ListView_InsertColumn(anims, 2, &lvc); + + // add a spanning entry to the animation list as a default + LVITEM lvi; + char buf[32]; + ZeroMemory(&lvi, sizeof(LVITEM)); + + lvi.mask = LVIF_TEXT; + lvi.pszText = "Animation"; + lvi.iItem = 10000; + int idx = ListView_InsertItem(anims, &lvi); + + sprintf(buf, "%d", frameStart / GetTicksPerFrame()); + lvi.iItem = idx; + lvi.iSubItem = 1; + lvi.pszText = buf; + ListView_SetItem(anims, &lvi); + + sprintf(buf, "%d", frameEnd / GetTicksPerFrame()); + lvi.iSubItem = 2; + lvi.pszText = buf; + ListView_SetItem(anims, &lvi); + + // populate the frame range info box + sprintf(buf, "%d to %d", frameStart / GetTicksPerFrame(), frameEnd / GetTicksPerFrame()); + SendMessage(GetDlgItem(m_hDlg, IDC_TXT_FRAME_RANGE), WM_SETTEXT, 0, (LPARAM)buf); + SendMessage(GetDlgItem(m_hDlg, IDC_TXT_FPS), WM_SETTEXT, 0, (LPARAM)_T("1.0")); } void OgreMaxExport_SkeletalAnimation::onDestroy() { - update(); + update(); } // read the contents from the dialog controls @@ -64,121 +64,121 @@ void OgreMaxExport_SkeletalAnimation::update() { } void OgreMaxExport_SkeletalAnimation::onAddAnimation() { - addAnimation(); + addAnimation(); } void OgreMaxExport_SkeletalAnimation::onDeleteAnimation() { - deleteAnimation(); + deleteAnimation(); } void OgreMaxExport_SkeletalAnimation::addAnimation() { - char buf[256]; - int start, end; - HWND anims = GetDlgItem(m_hDlg, IDC_LIST_ANIMATIONS); - - SendMessage(GetDlgItem(m_hDlg, IDC_TXT_FPS), WM_GETTEXT, 256, (LPARAM)buf); - float fps = atof(buf); - - if (fps <= 0.0) { - MessageBox(NULL, "FPS must be >= 0.0", "Invalid Entry", MB_ICONEXCLAMATION); - return; - } - - int minAnimTime = m_i->GetAnimRange().Start() / GetTicksPerFrame(); - int maxAnimTime = m_i->GetAnimRange().End() / GetTicksPerFrame(); - - // get animation start and end times - SendMessage(GetDlgItem(m_hDlg, IDC_TXT_ANIM_START), WM_GETTEXT, 256, (LPARAM)buf); - start = atoi(buf); - - if (start < minAnimTime) { - sprintf(buf, "Start time must be >= %d", start); - MessageBox(NULL, buf, "Invalid Entry", MB_ICONEXCLAMATION); - return; - } - - SendMessage(GetDlgItem(m_hDlg, IDC_TXT_ANIM_END), WM_GETTEXT, 256, (LPARAM)buf); - end = atoi(buf); - - if (end > maxAnimTime) { - sprintf(buf, "End time must be <= %d", end); - MessageBox(NULL, buf, "Invalid Entry", MB_ICONEXCLAMATION); - return; - } - - // get animation name - SendMessage(GetDlgItem(m_hDlg, IDC_TXT_ANIMATION_NAME), WM_GETTEXT, 256, (LPARAM)buf); - std::string name(buf); - - if (name.length() == 0) { - MessageBox(NULL, "Animation name must not be empty", "Invalid Entry", MB_ICONEXCLAMATION); - return; - } - - // if, after all that, we have valid data, stick it in the listview - LVITEM lvi; - ZeroMemory(&lvi, sizeof(LVITEM)); - - lvi.mask = LVIF_TEXT; - lvi.pszText = buf; - lvi.iItem = 10000; - int idx = ListView_InsertItem(anims, &lvi); - - lvi.iItem = idx; - lvi.iSubItem = 1; - sprintf(buf, "%d", start); - lvi.pszText = buf; - ListView_SetItem(anims, &lvi); - lvi.iSubItem = 2; - sprintf(buf, "%d", end); - lvi.pszText = buf; - ListView_SetItem(anims, &lvi); - - // Finally, clear out the entry controls - SetWindowText(GetDlgItem(m_hDlg, IDC_TXT_ANIMATION_NAME), ""); - SetWindowText(GetDlgItem(m_hDlg, IDC_TXT_ANIM_START), ""); - SetWindowText(GetDlgItem(m_hDlg, IDC_TXT_ANIM_END), ""); + char buf[256]; + int start, end; + HWND anims = GetDlgItem(m_hDlg, IDC_LIST_ANIMATIONS); + + SendMessage(GetDlgItem(m_hDlg, IDC_TXT_FPS), WM_GETTEXT, 256, (LPARAM)buf); + float fps = atof(buf); + + if (fps <= 0.0) { + MessageBox(NULL, "FPS must be >= 0.0", "Invalid Entry", MB_ICONEXCLAMATION); + return; + } + + int minAnimTime = m_i->GetAnimRange().Start() / GetTicksPerFrame(); + int maxAnimTime = m_i->GetAnimRange().End() / GetTicksPerFrame(); + + // get animation start and end times + SendMessage(GetDlgItem(m_hDlg, IDC_TXT_ANIM_START), WM_GETTEXT, 256, (LPARAM)buf); + start = atoi(buf); + + if (start < minAnimTime) { + sprintf(buf, "Start time must be >= %d", start); + MessageBox(NULL, buf, "Invalid Entry", MB_ICONEXCLAMATION); + return; + } + + SendMessage(GetDlgItem(m_hDlg, IDC_TXT_ANIM_END), WM_GETTEXT, 256, (LPARAM)buf); + end = atoi(buf); + + if (end > maxAnimTime) { + sprintf(buf, "End time must be <= %d", end); + MessageBox(NULL, buf, "Invalid Entry", MB_ICONEXCLAMATION); + return; + } + + // get animation name + SendMessage(GetDlgItem(m_hDlg, IDC_TXT_ANIMATION_NAME), WM_GETTEXT, 256, (LPARAM)buf); + std::string name(buf); + + if (name.length() == 0) { + MessageBox(NULL, "Animation name must not be empty", "Invalid Entry", MB_ICONEXCLAMATION); + return; + } + + // if, after all that, we have valid data, stick it in the listview + LVITEM lvi; + ZeroMemory(&lvi, sizeof(LVITEM)); + + lvi.mask = LVIF_TEXT; + lvi.pszText = buf; + lvi.iItem = 10000; + int idx = ListView_InsertItem(anims, &lvi); + + lvi.iItem = idx; + lvi.iSubItem = 1; + sprintf(buf, "%d", start); + lvi.pszText = buf; + ListView_SetItem(anims, &lvi); + lvi.iSubItem = 2; + sprintf(buf, "%d", end); + lvi.pszText = buf; + ListView_SetItem(anims, &lvi); + + // Finally, clear out the entry controls + SetWindowText(GetDlgItem(m_hDlg, IDC_TXT_ANIMATION_NAME), ""); + SetWindowText(GetDlgItem(m_hDlg, IDC_TXT_ANIM_START), ""); + SetWindowText(GetDlgItem(m_hDlg, IDC_TXT_ANIM_END), ""); } void OgreMaxExport_SkeletalAnimation::deleteAnimation() { - HWND anims = GetDlgItem(m_hDlg, IDC_LIST_ANIMATIONS); + HWND anims = GetDlgItem(m_hDlg, IDC_LIST_ANIMATIONS); - // delete selected animation(s) from the listview - int idx; - while ((idx=ListView_GetNextItem(anims, -1, LVNI_SELECTED)) != -1) - ListView_DeleteItem(anims, idx); + // delete selected animation(s) from the listview + int idx; + while ((idx=ListView_GetNextItem(anims, -1, LVNI_SELECTED)) != -1) + ListView_DeleteItem(anims, idx); } // for the sake of sanity, keep the dlgproc and the handler class implementation here in the same source file INT_PTR CALLBACK SkeletalAnimationTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - switch(message) { - case WM_INITDIALOG: - sInst = (OgreMaxExport_SkeletalAnimation*) lParam; - - sInst->onInitDialog(hDlg); - SetWindowPos(hDlg, HWND_TOP, 10, 40, 0, 0, SWP_NOSIZE); - ShowWindow(hDlg, SW_SHOW); - break; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDC_CMD_DELETE_ANIMATION: - sInst->onDeleteAnimation(); - break; - case IDC_CMD_ADD_ANIMATION: - sInst->onAddAnimation(); - break; - } - break; - - case WM_NOTIFY: - break; - - case WM_DESTROY: - sInst->onDestroy(); - break; - } - return FALSE; + switch(message) { + case WM_INITDIALOG: + sInst = (OgreMaxExport_SkeletalAnimation*) lParam; + + sInst->onInitDialog(hDlg); + SetWindowPos(hDlg, HWND_TOP, 10, 40, 0, 0, SWP_NOSIZE); + ShowWindow(hDlg, SW_SHOW); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_CMD_DELETE_ANIMATION: + sInst->onDeleteAnimation(); + break; + case IDC_CMD_ADD_ANIMATION: + sInst->onAddAnimation(); + break; + } + break; + + case WM_NOTIFY: + break; + + case WM_DESTROY: + sInst->onDestroy(); + break; + } + return FALSE; } diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabVertexAnimation.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabVertexAnimation.cpp index 23e9094cd06..566b150def5 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabVertexAnimation.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxExportTabVertexAnimation.cpp @@ -4,11 +4,11 @@ static OgreMaxExport_VertexAnimation* sInst; void OgreMaxExport_VertexAnimation::onInitDialog(HWND hDlg) { - OgreMaxExport_TabPaneHandler::onInitDialog(hDlg); + OgreMaxExport_TabPaneHandler::onInitDialog(hDlg); } void OgreMaxExport_VertexAnimation::onDestroy() { - update(); + update(); } // read the contents from the dialog controls @@ -19,23 +19,23 @@ void OgreMaxExport_VertexAnimation::update() { // for the sake of sanity, keep the dlgproc and the handler class implementation here in the same source file INT_PTR CALLBACK VertexAnimationTabDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - switch(message) { - case WM_INITDIALOG: - sInst = (OgreMaxExport_VertexAnimation*) lParam; - - sInst->onInitDialog(hDlg); - SetWindowPos(hDlg, HWND_TOP, 10, 40, 0, 0, SWP_NOSIZE); - ShowWindow(hDlg, SW_SHOW); - break; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - } - break; - - case WM_DESTROY: - sInst->onDestroy(); - break; - } - return FALSE; + switch(message) { + case WM_INITDIALOG: + sInst = (OgreMaxExport_VertexAnimation*) lParam; + + sInst->onInitDialog(hDlg); + SetWindowPos(hDlg, HWND_TOP, 10, 40, 0, 0, SWP_NOSIZE); + ShowWindow(hDlg, SW_SHOW); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + } + break; + + case WM_DESTROY: + sInst->onDestroy(); + break; + } + return FALSE; } diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxMaterialExport.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxMaterialExport.cpp index c6a75bb86c9..c4c28b42139 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxMaterialExport.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxMaterialExport.cpp @@ -7,203 +7,203 @@ namespace OgreMax { - MaterialExporter::MaterialExporter(const Config& config, MaterialMap& map) : m_materialMap(map), OgreMaxExporter(config) - { - } - - MaterialExporter::~MaterialExporter() - { - } - - - bool MaterialExporter::buildMaterial(std::string& output) { - - std::stringstream of; - of.precision(6); - of << std::fixed; - output = ""; - - if (streamMaterial(of)) - output = of.str(); - else - return false; - - return true; - } - - //bool MaterialExporter::streamPass(std::ostream &of, Mtl *mtl) { - bool MaterialExporter::streamPass(std::ostream &of, IGameMaterial *mtl) { - of << "\t\tpass" << std::endl; - of << "\t\t{" << std::endl; - - int subMtlCt = mtl->GetSubMaterialCount(); - - Point4 val4; - Point3 val3; - PropType pt; - IGameProperty* p = mtl->GetAmbientData(); - - if (p) { - pt = p->GetType(); - - if (pt == IGAME_POINT3_PROP) { - p->GetPropertyValue(val3); - of << "\t\t\tambient " << val3.x << " " << val3.y << " " << val3.z << " " << std::endl; - } - - if (pt == IGAME_POINT4_PROP) { - p->GetPropertyValue(val4); - of << "\t\t\tambient " << val4.x << " " << val4.y << " " << val4.z << " " << val4.w << " " << std::endl; - } - } - - p = mtl->GetDiffuseData(); - if (p) { - pt = p->GetType(); - - if (pt == IGAME_POINT3_PROP) { - p->GetPropertyValue(val3); - of << "\t\t\tdiffuse " << val3.x << " " << val3.y << " " << val3.z << " " << std::endl; - } - - if (pt == IGAME_POINT4_PROP) { - p->GetPropertyValue(val4); - of << "\t\t\tdiffuse " << val4.x << " " << val4.y << " " << val4.z << " " << val4.w << " " << std::endl; - } - } - - p = mtl->GetSpecularData(); - if (p) { - pt = p->GetType(); - - if (pt == IGAME_POINT3_PROP) { - p->GetPropertyValue(val3); - of << "\t\t\tspecular " << val3.x << " " << val3.y << " " << val3.z << " " << std::endl; - } - - if (pt == IGAME_POINT4_PROP) { - p->GetPropertyValue(val4); - of << "\t\t\tspecular " << val4.x << " " << val4.y << " " << val4.z << " " << val4.w << " " << std::endl; - } - } - - p = mtl->GetEmissiveData(); - if (p) { - pt = p->GetType(); - - if (pt == IGAME_POINT3_PROP) { - p->GetPropertyValue(val3); - of << "\t\t\temissive " << val3.x << " " << val3.y << " " << val3.z << " " << std::endl; - } - - if (pt == IGAME_POINT4_PROP) { - p->GetPropertyValue(val4); - of << "\t\t\temissive " << val4.x << " " << val4.y << " " << val4.z << " " << val4.w << " " << std::endl; - } - } - - int numTexMaps = mtl->GetNumberOfTextureMaps(); - if (numTexMaps > 0) { - - for (int texMapIdx = 0; texMapIdx < numTexMaps; texMapIdx++) { - IGameTextureMap* tmap = mtl->GetIGameTextureMap(texMapIdx); - if (tmap) { - of << "\n\t\t\ttexture_unit " << std::endl; - of << "\t\t\t{" << std::endl; - - std::string bmap(tmap->GetBitmapFileName()); - bmap = bmap.substr(bmap.find_last_of('\\') + 1); - of << "\t\t\t\ttexture " << bmap << std::endl; - of << "\t\t\t}" << std::endl; - } - } - } - - of << "\t\t}" << std::endl; - - return true; - } - - bool MaterialExporter::buildMaterial(IGameMaterial *material, const std::string& matName, std::string &script) { - - std::stringstream of; - - of << "material " << matName << std::endl; - of << std::showpoint; - of << "{" << std::endl; - - of << "\ttechnique" << std::endl; - of << "\t{" << std::endl; - - int numSubMtl = 0; - - if (material != NULL) { - numSubMtl = material->GetSubMaterialCount(); - - if (numSubMtl > 0) { - int i; - for (i=0; iGetSubMaterial(i)); - } - } - else - streamPass(of, material); - } - else { - streamPass(of, material); - } - - of << "\t}" << std::endl; - of << "}" << std::endl; - - script = of.str(); - - return true; - } - - bool MaterialExporter::streamMaterial(std::ostream &of) { - - // serialize this information to the material file - MaterialMap::iterator it = m_materialMap.begin(); - - while (it != m_materialMap.end()) { - std::string matName(it->first); - IGameMaterial *mtl = it->second; - - of << "material " << matName << std::endl; - of << std::showpoint; - of << "{" << std::endl; - - of << "\ttechnique" << std::endl; - of << "\t{" << std::endl; - - int numSubMtl = 0; - - if (mtl != NULL) { - numSubMtl = mtl->GetSubMaterialCount(); - - if (numSubMtl > 0) { - int i; - for (i=0; iGetSubMaterial(i)); - } - } - else - streamPass(of, mtl); - } - else { - streamPass(of, mtl); - } - - of << "\t}" << std::endl; - of << "}" << std::endl; - - it++; - } - - m_materialMap.clear(); - - return true; - } + MaterialExporter::MaterialExporter(const Config& config, MaterialMap& map) : m_materialMap(map), OgreMaxExporter(config) + { + } + + MaterialExporter::~MaterialExporter() + { + } + + + bool MaterialExporter::buildMaterial(std::string& output) { + + std::stringstream of; + of.precision(6); + of << std::fixed; + output = ""; + + if (streamMaterial(of)) + output = of.str(); + else + return false; + + return true; + } + + //bool MaterialExporter::streamPass(std::ostream &of, Mtl *mtl) { + bool MaterialExporter::streamPass(std::ostream &of, IGameMaterial *mtl) { + of << "\t\tpass" << std::endl; + of << "\t\t{" << std::endl; + + int subMtlCt = mtl->GetSubMaterialCount(); + + Point4 val4; + Point3 val3; + PropType pt; + IGameProperty* p = mtl->GetAmbientData(); + + if (p) { + pt = p->GetType(); + + if (pt == IGAME_POINT3_PROP) { + p->GetPropertyValue(val3); + of << "\t\t\tambient " << val3.x << " " << val3.y << " " << val3.z << " " << std::endl; + } + + if (pt == IGAME_POINT4_PROP) { + p->GetPropertyValue(val4); + of << "\t\t\tambient " << val4.x << " " << val4.y << " " << val4.z << " " << val4.w << " " << std::endl; + } + } + + p = mtl->GetDiffuseData(); + if (p) { + pt = p->GetType(); + + if (pt == IGAME_POINT3_PROP) { + p->GetPropertyValue(val3); + of << "\t\t\tdiffuse " << val3.x << " " << val3.y << " " << val3.z << " " << std::endl; + } + + if (pt == IGAME_POINT4_PROP) { + p->GetPropertyValue(val4); + of << "\t\t\tdiffuse " << val4.x << " " << val4.y << " " << val4.z << " " << val4.w << " " << std::endl; + } + } + + p = mtl->GetSpecularData(); + if (p) { + pt = p->GetType(); + + if (pt == IGAME_POINT3_PROP) { + p->GetPropertyValue(val3); + of << "\t\t\tspecular " << val3.x << " " << val3.y << " " << val3.z << " " << std::endl; + } + + if (pt == IGAME_POINT4_PROP) { + p->GetPropertyValue(val4); + of << "\t\t\tspecular " << val4.x << " " << val4.y << " " << val4.z << " " << val4.w << " " << std::endl; + } + } + + p = mtl->GetEmissiveData(); + if (p) { + pt = p->GetType(); + + if (pt == IGAME_POINT3_PROP) { + p->GetPropertyValue(val3); + of << "\t\t\temissive " << val3.x << " " << val3.y << " " << val3.z << " " << std::endl; + } + + if (pt == IGAME_POINT4_PROP) { + p->GetPropertyValue(val4); + of << "\t\t\temissive " << val4.x << " " << val4.y << " " << val4.z << " " << val4.w << " " << std::endl; + } + } + + int numTexMaps = mtl->GetNumberOfTextureMaps(); + if (numTexMaps > 0) { + + for (int texMapIdx = 0; texMapIdx < numTexMaps; texMapIdx++) { + IGameTextureMap* tmap = mtl->GetIGameTextureMap(texMapIdx); + if (tmap) { + of << "\n\t\t\ttexture_unit " << std::endl; + of << "\t\t\t{" << std::endl; + + std::string bmap(tmap->GetBitmapFileName()); + bmap = bmap.substr(bmap.find_last_of('\\') + 1); + of << "\t\t\t\ttexture " << bmap << std::endl; + of << "\t\t\t}" << std::endl; + } + } + } + + of << "\t\t}" << std::endl; + + return true; + } + + bool MaterialExporter::buildMaterial(IGameMaterial *material, const std::string& matName, std::string &script) { + + std::stringstream of; + + of << "material " << matName << std::endl; + of << std::showpoint; + of << "{" << std::endl; + + of << "\ttechnique" << std::endl; + of << "\t{" << std::endl; + + int numSubMtl = 0; + + if (material != NULL) { + numSubMtl = material->GetSubMaterialCount(); + + if (numSubMtl > 0) { + int i; + for (i=0; iGetSubMaterial(i)); + } + } + else + streamPass(of, material); + } + else { + streamPass(of, material); + } + + of << "\t}" << std::endl; + of << "}" << std::endl; + + script = of.str(); + + return true; + } + + bool MaterialExporter::streamMaterial(std::ostream &of) { + + // serialize this information to the material file + MaterialMap::iterator it = m_materialMap.begin(); + + while (it != m_materialMap.end()) { + std::string matName(it->first); + IGameMaterial *mtl = it->second; + + of << "material " << matName << std::endl; + of << std::showpoint; + of << "{" << std::endl; + + of << "\ttechnique" << std::endl; + of << "\t{" << std::endl; + + int numSubMtl = 0; + + if (mtl != NULL) { + numSubMtl = mtl->GetSubMaterialCount(); + + if (numSubMtl > 0) { + int i; + for (i=0; iGetSubMaterial(i)); + } + } + else + streamPass(of, mtl); + } + else { + streamPass(of, mtl); + } + + of << "\t}" << std::endl; + of << "}" << std::endl; + + it++; + } + + m_materialMap.clear(); + + return true; + } } \ No newline at end of file diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxMeshExport.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxMeshExport.cpp index 6e9ef77ff1f..8a1dff9fe8e 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxMeshExport.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxMeshExport.cpp @@ -29,16 +29,16 @@ THE SOFTWARE. namespace OgreMax { - MeshExporter::MeshExporter(const Config& config) : OgreMaxExporter(config) - { - } + MeshExporter::MeshExporter(const Config& config) : OgreMaxExporter(config) + { + } - MeshExporter::~MeshExporter() - { - } + MeshExporter::~MeshExporter() + { + } - Ogre::MeshPtr MeshExporter::buildMesh(NodeList nodeList) - { - return m_pMesh; - } + Ogre::MeshPtr MeshExporter::buildMesh(NodeList nodeList) + { + return m_pMesh; + } } \ No newline at end of file diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxMeshXMLExport.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxMeshXMLExport.cpp index f58bd224e8e..bff476a052e 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxMeshXMLExport.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxMeshXMLExport.cpp @@ -44,973 +44,973 @@ THE SOFTWARE. namespace OgreMax { - MeshXMLExporter::MeshXMLExporter(const Config& config, MaterialMap& map) : m_materialMap(map), OgreMaxExporter(config) - { - m_createSkeletonLink = false; - m_pGame = 0; - - m_currentBoneIndex = 0; // used to map bone names to bone indices for vertex assignment and later skeleton export - } - - MeshXMLExporter::~MeshXMLExporter() - { - } - - bool MeshXMLExporter::buildMeshXML(OutputMap& output) - { - return export(output); - } - - - // "callback" is called in response to the EnumTree() call made below. That call visits every node in the - // scene and calls this procedure for each one. - int MeshXMLExporter::callback(INode *node) { - - // SKELOBJ_CLASS_ID = 0x9125 = 37157 - // BIPED_CLASS_ID = 0x9155 = 37205 - // BIPSLAVE_CONTROL_CLASS_ID = 0x9154 = 37204 - // BIPBODY_CONTROL_CLASS_ID = 0x9156 = 37206 - // FOOTPRINT_CLASS_ID = 0x3011 = 12305 - // DUMMY_CLASS_ID = 0x876234 = 8872500 - - TimeValue start = m_i->GetAnimRange().Start(); - Object *obj = node->EvalWorldState(start).obj; - Class_ID cid = obj->ClassID(); - - // nodes that have Biped controllers are bones -- ignore the ones that are dummies - if (cid == Class_ID(DUMMY_CLASS_ID, 0)) - return TREE_CONTINUE; - - Control *c = node->GetTMController(); - if ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) || - (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) || - (c->ClassID() == FOOTPRINT_CLASS_ID)) { - - if (node->GetParentNode() != NULL) { - // stick this in the bone-index map for later use - m_boneIndexMap.insert(std::map< std::string, int >::value_type(std::string(node->GetName()), m_currentBoneIndex++)); - } - - return TREE_CONTINUE; - } - // if the node cannot be converted to a TriObject (mesh), ignore it - if (!obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) - return TREE_CONTINUE; - - // create a list of nodes to process - if (m_config.getExportSelected()) { - if (node->Selected()) { - m_nodeTab.Append(1, &node); - } - } - else { - m_nodeTab.Append(1, &node); - } - - return TREE_CONTINUE; - } - - //////////////////////////////////////////////////////////////////////////////// - // Regardless of whether the user chooses to export submesh-per-file or to put - // all submeshes in the same file, we will deal with submaterials by creating - // "duplicate" vertices based on normal and texcoord differences. In other words, - // "unique" vertices will be based on smoothing-group normals (if used, face normals if - // not) and face texcoords, not the inherent vertex normals and texcoords. - // - // The basic concept is the same as used in the MaxScript exporter (as well as - // the exporters for other 3D tools): iterate the faces, extracting normal and - // texcoord info along with the position and color data; vertices are "unique-ified" - // as they are added to the vertex list. - //////////////////////////////////////////////////////////////////////////////// - - bool MeshXMLExporter::export(OutputMap& output) { - - try { - - // write XML to a strstream - std::stringstream of; - - while (!m_submeshNames.empty()) - m_submeshNames.pop(); - - if (m_pGame) { - m_pGame->ReleaseIGame(); - m_pGame = 0; - } - - m_ei->theScene->EnumTree(this); - - m_pGame = GetIGameInterface(); - IGameConversionManager* cm = GetConversionManager(); - cm->SetCoordSystem(IGameConversionManager::IGAME_OGL); - m_pGame->InitialiseIGame(m_nodeTab, false); - m_pGame->SetStaticFrame(0); - int nodeCount = m_pGame->GetTopLevelNodeCount(); - - if (nodeCount == 0) { - MessageBox(GetActiveWindow(), "No nodes available to export, aborting...", "Nothing To Export", MB_ICONINFORMATION); - m_pGame->ReleaseIGame(); - return false; - } - - // if we are writing everything to one file, use the name provided when the user first started the export; - // otherwise, create filenames on the basis of the node (submesh) names - std::string fileName; - IGameNode* node = m_pGame->GetTopLevelNode(0); - if (!m_config.getExportMultipleFiles()) - fileName = m_config.getExportFilename(); - else { - fileName = m_config.getExportPath() + "\\"; - fileName += node->GetName(); - fileName += ".mesh.xml"; - } - - // write start of XML data - streamFileHeader(of); - - int nodeIdx = 0; - std::map materialScripts; - - while (nodeIdx < nodeCount) { - - std::string mtlName; - IGameNode* node = m_pGame->GetTopLevelNode(nodeIdx); - IGameObject* obj = node->GetIGameObject(); - - // InitializeData() is important -- it performs all of the WSM/time eval for us; no data without it - obj->InitializeData(); - - IGameMaterial* mtl = node->GetNodeMaterial(); - if (mtl == NULL) - mtlName = m_config.getDefaultMaterialName(); - else - mtlName = mtl->GetMaterialName(); - - // clean out any spaces the user left in their material name - std::string::size_type pos; - while ((pos = mtlName.find_first_of(' ')) != std::string::npos) - mtlName.replace(pos, 1, _T("_")); - - if (materialScripts.find(mtlName) == materialScripts.end()) { - - // export new material script - MaterialExporter mexp(m_config, m_materialMap); - std::string script; - - mexp.buildMaterial(mtl, mtlName, script); - materialScripts[mtlName] = script; - } - - //if (streamSubmesh(of, node, mtlName)) - if (streamSubmesh(of, obj, mtlName)) - m_submeshNames.push(std::string(node->GetName())); + MeshXMLExporter::MeshXMLExporter(const Config& config, MaterialMap& map) : m_materialMap(map), OgreMaxExporter(config) + { + m_createSkeletonLink = false; + m_pGame = 0; + + m_currentBoneIndex = 0; // used to map bone names to bone indices for vertex assignment and later skeleton export + } + + MeshXMLExporter::~MeshXMLExporter() + { + } + + bool MeshXMLExporter::buildMeshXML(OutputMap& output) + { + return export(output); + } + + + // "callback" is called in response to the EnumTree() call made below. That call visits every node in the + // scene and calls this procedure for each one. + int MeshXMLExporter::callback(INode *node) { + + // SKELOBJ_CLASS_ID = 0x9125 = 37157 + // BIPED_CLASS_ID = 0x9155 = 37205 + // BIPSLAVE_CONTROL_CLASS_ID = 0x9154 = 37204 + // BIPBODY_CONTROL_CLASS_ID = 0x9156 = 37206 + // FOOTPRINT_CLASS_ID = 0x3011 = 12305 + // DUMMY_CLASS_ID = 0x876234 = 8872500 + + TimeValue start = m_i->GetAnimRange().Start(); + Object *obj = node->EvalWorldState(start).obj; + Class_ID cid = obj->ClassID(); + + // nodes that have Biped controllers are bones -- ignore the ones that are dummies + if (cid == Class_ID(DUMMY_CLASS_ID, 0)) + return TREE_CONTINUE; + + Control *c = node->GetTMController(); + if ((c->ClassID() == BIPSLAVE_CONTROL_CLASS_ID) || + (c->ClassID() == BIPBODY_CONTROL_CLASS_ID) || + (c->ClassID() == FOOTPRINT_CLASS_ID)) { + + if (node->GetParentNode() != NULL) { + // stick this in the bone-index map for later use + m_boneIndexMap.insert(std::map< std::string, int >::value_type(std::string(node->GetName()), m_currentBoneIndex++)); + } + + return TREE_CONTINUE; + } + // if the node cannot be converted to a TriObject (mesh), ignore it + if (!obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) + return TREE_CONTINUE; + + // create a list of nodes to process + if (m_config.getExportSelected()) { + if (node->Selected()) { + m_nodeTab.Append(1, &node); + } + } + else { + m_nodeTab.Append(1, &node); + } + + return TREE_CONTINUE; + } + + //////////////////////////////////////////////////////////////////////////////// + // Regardless of whether the user chooses to export submesh-per-file or to put + // all submeshes in the same file, we will deal with submaterials by creating + // "duplicate" vertices based on normal and texcoord differences. In other words, + // "unique" vertices will be based on smoothing-group normals (if used, face normals if + // not) and face texcoords, not the inherent vertex normals and texcoords. + // + // The basic concept is the same as used in the MaxScript exporter (as well as + // the exporters for other 3D tools): iterate the faces, extracting normal and + // texcoord info along with the position and color data; vertices are "unique-ified" + // as they are added to the vertex list. + //////////////////////////////////////////////////////////////////////////////// + + bool MeshXMLExporter::export(OutputMap& output) { + + try { + + // write XML to a strstream + std::stringstream of; + + while (!m_submeshNames.empty()) + m_submeshNames.pop(); + + if (m_pGame) { + m_pGame->ReleaseIGame(); + m_pGame = 0; + } + + m_ei->theScene->EnumTree(this); + + m_pGame = GetIGameInterface(); + IGameConversionManager* cm = GetConversionManager(); + cm->SetCoordSystem(IGameConversionManager::IGAME_OGL); + m_pGame->InitialiseIGame(m_nodeTab, false); + m_pGame->SetStaticFrame(0); + int nodeCount = m_pGame->GetTopLevelNodeCount(); + + if (nodeCount == 0) { + MessageBox(GetActiveWindow(), "No nodes available to export, aborting...", "Nothing To Export", MB_ICONINFORMATION); + m_pGame->ReleaseIGame(); + return false; + } + + // if we are writing everything to one file, use the name provided when the user first started the export; + // otherwise, create filenames on the basis of the node (submesh) names + std::string fileName; + IGameNode* node = m_pGame->GetTopLevelNode(0); + if (!m_config.getExportMultipleFiles()) + fileName = m_config.getExportFilename(); + else { + fileName = m_config.getExportPath() + "\\"; + fileName += node->GetName(); + fileName += ".mesh.xml"; + } + + // write start of XML data + streamFileHeader(of); + + int nodeIdx = 0; + std::map materialScripts; + + while (nodeIdx < nodeCount) { + + std::string mtlName; + IGameNode* node = m_pGame->GetTopLevelNode(nodeIdx); + IGameObject* obj = node->GetIGameObject(); + + // InitializeData() is important -- it performs all of the WSM/time eval for us; no data without it + obj->InitializeData(); + + IGameMaterial* mtl = node->GetNodeMaterial(); + if (mtl == NULL) + mtlName = m_config.getDefaultMaterialName(); + else + mtlName = mtl->GetMaterialName(); + + // clean out any spaces the user left in their material name + std::string::size_type pos; + while ((pos = mtlName.find_first_of(' ')) != std::string::npos) + mtlName.replace(pos, 1, _T("_")); + + if (materialScripts.find(mtlName) == materialScripts.end()) { + + // export new material script + MaterialExporter mexp(m_config, m_materialMap); + std::string script; + + mexp.buildMaterial(mtl, mtlName, script); + materialScripts[mtlName] = script; + } + + //if (streamSubmesh(of, node, mtlName)) + if (streamSubmesh(of, obj, mtlName)) + m_submeshNames.push(std::string(node->GetName())); - node->ReleaseIGameObject(); - nodeIdx++; + node->ReleaseIGameObject(); + nodeIdx++; - if (m_config.getExportMultipleFiles() || nodeIdx == nodeCount) { + if (m_config.getExportMultipleFiles() || nodeIdx == nodeCount) { - // write end of this file's XML - streamFileFooter(of); - - // insert new filename --> stream pair into output map - output[fileName] = std::string(of.str()); - of.str(""); + // write end of this file's XML + streamFileFooter(of); + + // insert new filename --> stream pair into output map + output[fileName] = std::string(of.str()); + of.str(""); - if (nodeIdx != nodeCount) { - fileName = m_config.getExportPath() + "\\"; - node = m_pGame->GetTopLevelNode(nodeIdx); - fileName += node->GetName(); - fileName += ".mesh.xml"; + if (nodeIdx != nodeCount) { + fileName = m_config.getExportPath() + "\\"; + node = m_pGame->GetTopLevelNode(nodeIdx); + fileName += node->GetName(); + fileName += ".mesh.xml"; - // start over again with new data - streamFileHeader(of); - } - } - } + // start over again with new data + streamFileHeader(of); + } + } + } - m_pGame->ReleaseIGame(); - - // export materials if we are writing those - if (m_config.getExportMaterial()) { - - std::ofstream materialFile; - materialFile.open((m_config.getExportPath() + "\\" + m_config.getMaterialFilename()).c_str(), std::ios::out); + m_pGame->ReleaseIGame(); + + // export materials if we are writing those + if (m_config.getExportMaterial()) { + + std::ofstream materialFile; + materialFile.open((m_config.getExportPath() + "\\" + m_config.getMaterialFilename()).c_str(), std::ios::out); - if (materialFile.is_open()) { - for (std::map::iterator it = materialScripts.begin(); - it != materialScripts.end(); ++it) - { - materialFile << it->second; - } + if (materialFile.is_open()) { + for (std::map::iterator it = materialScripts.begin(); + it != materialScripts.end(); ++it) + { + materialFile << it->second; + } - materialFile.close(); - } - } + materialFile.close(); + } + } - return true; - } - catch (...) { - MessageBox(GetActiveWindow(), "An unexpected error has occurred while trying to export, aborting", "Error", MB_ICONEXCLAMATION); + return true; + } + catch (...) { + MessageBox(GetActiveWindow(), "An unexpected error has occurred while trying to export, aborting", "Error", MB_ICONEXCLAMATION); - if (m_pGame) - m_pGame->ReleaseIGame(); + if (m_pGame) + m_pGame->ReleaseIGame(); - return false; - } - } + return false; + } + } - bool MeshXMLExporter::streamFileHeader(std::ostream &of) { + bool MeshXMLExporter::streamFileHeader(std::ostream &of) { - // write the XML header tags - of << "" << std::endl; - of << "" << std::endl; + // write the XML header tags + of << "" << std::endl; + of << "" << std::endl; - // *************** Export Submeshes *************** - of << "\t" << std::endl; + // *************** Export Submeshes *************** + of << "\t" << std::endl; - of.precision(6); - of << std::fixed; + of.precision(6); + of << std::fixed; - return true; - } + return true; + } - bool MeshXMLExporter::streamFileFooter(std::ostream &of) { + bool MeshXMLExporter::streamFileFooter(std::ostream &of) { - of << "\t" << std::endl; - // *************** End Submeshes Export *********** + of << "\t" << std::endl; + // *************** End Submeshes Export *********** - // if there is a skeleton involved, link that filename here - if (m_createSkeletonLink) { - std::string skeletonFilename(m_skeletonFilename); - skeletonFilename = skeletonFilename.substr(0, skeletonFilename.find(".xml")); + // if there is a skeleton involved, link that filename here + if (m_createSkeletonLink) { + std::string skeletonFilename(m_skeletonFilename); + skeletonFilename = skeletonFilename.substr(0, skeletonFilename.find(".xml")); - of << "\t" << std::endl; - } + of << "\t" << std::endl; + } - // *************** Export Submesh Names *************** - of << "\t" << std::endl; + // *************** Export Submesh Names *************** + of << "\t" << std::endl; - int idx = 0; - while (!m_submeshNames.empty()) { - of << "\t\t" << std::endl; - idx++; - m_submeshNames.pop(); - } + int idx = 0; + while (!m_submeshNames.empty()) { + of << "\t\t" << std::endl; + idx++; + m_submeshNames.pop(); + } - of << "\t" << std::endl; - // *************** End Submesh Names Export *********** + of << "\t" << std::endl; + // *************** End Submesh Names Export *********** - of << "" << std::endl; + of << "" << std::endl; - return true; - } + return true; + } - //bool MeshXMLExporter::streamSubmesh(std::ostream &of, IGameNode *node, std::string &mtlName) { - bool MeshXMLExporter::streamSubmesh(std::ostream &of, IGameObject *obj, std::string &mtlName) { - - //IGameObject* obj = node->GetIGameObject(); - if (obj->GetIGameType() != IGameMesh::IGAME_MESH) - return false; + //bool MeshXMLExporter::streamSubmesh(std::ostream &of, IGameNode *node, std::string &mtlName) { + bool MeshXMLExporter::streamSubmesh(std::ostream &of, IGameObject *obj, std::string &mtlName) { + + //IGameObject* obj = node->GetIGameObject(); + if (obj->GetIGameType() != IGameMesh::IGAME_MESH) + return false; - // InitializeData() is important -- it performs all of the WSM/time eval for us; no face data without it -// obj->InitializeData(); - IGameMesh* mesh = (IGameMesh*) obj; - int vertCount = mesh->GetNumberOfVerts(); - int faceCount = mesh->GetNumberOfFaces(); + // InitializeData() is important -- it performs all of the WSM/time eval for us; no face data without it +// obj->InitializeData(); + IGameMesh* mesh = (IGameMesh*) obj; + int vertCount = mesh->GetNumberOfVerts(); + int faceCount = mesh->GetNumberOfFaces(); - Tab matIds = mesh->GetActiveMatIDs(); - Tab smGrpIds = mesh->GetActiveSmgrps(); - Tab texMaps = mesh->GetActiveMapChannelNum(); + Tab matIds = mesh->GetActiveMatIDs(); + Tab smGrpIds = mesh->GetActiveSmgrps(); + Tab texMaps = mesh->GetActiveMapChannelNum(); - of << "\t\t 0) - of << "material=\"" << mtlName << "\" "; + of << "\t\t 0) + of << "material=\"" << mtlName << "\" "; - of << "usesharedvertices=\"false\" use32bitindexes=\""; - of << (vertCount > 65535); - of << "\">" << std::endl; + of << "usesharedvertices=\"false\" use32bitindexes=\""; + of << (vertCount > 65535); + of << "\">" << std::endl; - // *************** Export Face List *************** - of << "\t\t\t" << std::endl; + // *************** Export Face List *************** + of << "\t\t\t" << std::endl; - //std::vectorGetFace(i); + of << "\t\t\t\tGetFace(i); - // do this for each vertex on the face - for (int vi=0; vi<3; vi++) { - Point3 p = mesh->GetVertex(face->vert[vi]); + // do this for each vertex on the face + for (int vi=0; vi<3; vi++) { + Point3 p = mesh->GetVertex(face->vert[vi]); - Vertex v(p.x, p.y, p.z); + Vertex v(p.x, p.y, p.z); - if (m_config.getExportVertexColours()) { - Point3 c = mesh->GetColorVertex(face->vert[vi]); - float a = mesh->GetAlphaVertex(face->vert[vi]); + if (m_config.getExportVertexColours()) { + Point3 c = mesh->GetColorVertex(face->vert[vi]); + float a = mesh->GetAlphaVertex(face->vert[vi]); - v.setColour(c.x, c.y, c.z, a); - } + v.setColour(c.x, c.y, c.z, a); + } - Point3 n = mesh->GetNormal(face, vi); - v.setNormal(n.x, n.y, n.z); + Point3 n = mesh->GetNormal(face, vi); + v.setNormal(n.x, n.y, n.z); - // get each set of texcoords for this vertex - for (int ch=0; ch < texMaps.Count(); ch++) { + // get each set of texcoords for this vertex + for (int ch=0; ch < texMaps.Count(); ch++) { - Point3 tv; - DWORD indices[3]; + Point3 tv; + DWORD indices[3]; - if (mesh->GetMapFaceIndex(texMaps[ch], i, indices)) - tv = mesh->GetMapVertex(texMaps[ch], indices[vi]); - else - tv = mesh->GetMapVertex(texMaps[ch], face->vert[vi]); + if (mesh->GetMapFaceIndex(texMaps[ch], i, indices)) + tv = mesh->GetMapVertex(texMaps[ch], indices[vi]); + else + tv = mesh->GetMapVertex(texMaps[ch], face->vert[vi]); - v.addTexCoord(texMaps[ch], tv.x, tv.y, tv.z); - } + v.addTexCoord(texMaps[ch], tv.x, tv.y, tv.z); + } - int actualVertexIndex = vertexList.add(v); + int actualVertexIndex = vertexList.add(v); - of << " v" << vi + 1 << "=\"" << actualVertexIndex << "\""; - } + of << " v" << vi + 1 << "=\"" << actualVertexIndex << "\""; + } - of << " />" << std::endl; - } + of << " />" << std::endl; + } - of << "\t\t\t" << std::endl; - // *************** End Export Face List *************** + of << "\t\t\t" << std::endl; + // *************** End Export Face List *************** - // *************** Export Geometry *************** - of << "\t\t\t" << std::endl; + // *************** Export Geometry *************** + of << "\t\t\t" << std::endl; - // *************** Export Vertex Buffer *************** - bool exportNormals = true; + // *************** Export Vertex Buffer *************** + bool exportNormals = true; - of << std::boolalpha; - of << "\t\t\t\t" << std::endl; + of << std::boolalpha; + of << "\t\t\t\t" << std::endl; - int numVerts = vertexList.size(); - for (i=0; i < numVerts; i++) { + int numVerts = vertexList.size(); + for (i=0; i < numVerts; i++) { - const Vertex& v = vertexList.front(); + const Vertex& v = vertexList.front(); - of << "\t\t\t\t\t" << std::endl; - of << std::showpoint; + of << "\t\t\t\t\t" << std::endl; + of << std::showpoint; - const Ogre::Vector3& p = v.getPosition(); - float x = p.x; - float y = p.y; - float z = p.z; + const Ogre::Vector3& p = v.getPosition(); + float x = p.x; + float y = p.y; + float z = p.z; - of << "\t\t\t\t\t\t" << std::endl; + of << "\t\t\t\t\t\t" << std::endl; - if (m_config.getExportVertexColours()) { + if (m_config.getExportVertexColours()) { - float r = v.getColour().r; - float g = v.getColour().g; - float b = v.getColour().b; + float r = v.getColour().r; + float g = v.getColour().g; + float b = v.getColour().b; - of << "\t\t\t\t\t\t" << std::endl; - } + of << "\t\t\t\t\t\t" << std::endl; + } - if (exportNormals) { + if (exportNormals) { - const Ogre::Vector3& n = v.getNormal(); - float x = n.x; - float y = n.y; - float z = n.z; + const Ogre::Vector3& n = v.getNormal(); + float x = n.x; + float y = n.y; + float z = n.z; - of << "\t\t\t\t\t\t" << std::endl; - } + of << "\t\t\t\t\t\t" << std::endl; + } - // output the tex coords for each map used - for (int ti=0; ti" << std::endl; - break; - case OgreMax::VW: - of << "\t\t\t\t\t\t" << std::endl; - break; - case OgreMax::WU: - of << "\t\t\t\t\t\t" << std::endl; - break; - } - } - - of << std::noshowpoint; - of << "\t\t\t\t\t" << std::endl; - vertexList.pop(); - } + switch (m_config.getTexCoord2D()) { + case OgreMax::UV: + of << "\t\t\t\t\t\t" << std::endl; + break; + case OgreMax::VW: + of << "\t\t\t\t\t\t" << std::endl; + break; + case OgreMax::WU: + of << "\t\t\t\t\t\t" << std::endl; + break; + } + } + + of << std::noshowpoint; + of << "\t\t\t\t\t" << std::endl; + vertexList.pop(); + } - of << "\t\t\t\t" << std::endl; - // *************** End Export Vertex Buffer *************** + of << "\t\t\t\t" << std::endl; + // *************** End Export Vertex Buffer *************** - of << "\t\t\t" << std::endl; - // *************** End Export Geometry *********** + of << "\t\t\t" << std::endl; + // *************** End Export Geometry *********** - of << "\t\t" << std::endl; + of << "\t\t" << std::endl; - // this skin extraction code based on an article found here: - // http://www.cfxweb.net/modules.php?name=News&file=article&sid=1029 -/* Object *oRef = node->GetObjectRef(); + // this skin extraction code based on an article found here: + // http://www.cfxweb.net/modules.php?name=News&file=article&sid=1029 +/* Object *oRef = node->GetObjectRef(); - if (oRef->SuperClassID() == GEN_DERIVOB_CLASS_ID) { - IDerivedObject *dObj = (IDerivedObject *)oRef; - Modifier *oMod = dObj->GetModifier(0); + if (oRef->SuperClassID() == GEN_DERIVOB_CLASS_ID) { + IDerivedObject *dObj = (IDerivedObject *)oRef; + Modifier *oMod = dObj->GetModifier(0); - if (oMod->ClassID() == SKIN_CLASSID) { + if (oMod->ClassID() == SKIN_CLASSID) { - // flag the export of a skeleton link element - m_createSkeletonLink = true; + // flag the export of a skeleton link element + m_createSkeletonLink = true; - // stream the boneassignments element - streamBoneAssignments(of, oMod, node); - } - } + // stream the boneassignments element + streamBoneAssignments(of, oMod, node); + } + } - of << "\t\t" << std::endl; + of << "\t\t" << std::endl; - if (obj != tri) - delete tri; + if (obj != tri) + delete tri; */ -// node->ReleaseIGameObject(); - return true; - } +// node->ReleaseIGameObject(); + return true; + } - //bool MeshXMLExporter::streamBoneAssignments(std::ostream &of, Modifier *oMod, INode *node) { - bool MeshXMLExporter::streamBoneAssignments(std::ostream &of, Modifier *oMod, IGameNode *node) { + //bool MeshXMLExporter::streamBoneAssignments(std::ostream &of, Modifier *oMod, INode *node) { + bool MeshXMLExporter::streamBoneAssignments(std::ostream &of, Modifier *oMod, IGameNode *node) { - // wrangle a pointer to the skinning data -/* ISkin *skin = (ISkin *) oMod->GetInterface(I_SKIN); - ISkinContextData *skinData = skin->GetContextInterface(node); + // wrangle a pointer to the skinning data +/* ISkin *skin = (ISkin *) oMod->GetInterface(I_SKIN); + ISkinContextData *skinData = skin->GetContextInterface(node); - // loop through all the vertices, writing out skinning data as we go - int skinnedVertexCount = skinData->GetNumPoints(); + // loop through all the vertices, writing out skinning data as we go + int skinnedVertexCount = skinData->GetNumPoints(); - if (skinnedVertexCount > 0) { + if (skinnedVertexCount > 0) { - of << "\t\t\t" << std::endl; + of << "\t\t\t" << std::endl; - int i; - for(i=0; iGetNumAssignedBones(i); + // grab the bone indices for this vertex + int vertexBoneInfluences = skinData->GetNumAssignedBones(i); - if (vertexBoneInfluences > 0) { + if (vertexBoneInfluences > 0) { - int j; - for (j=0; j < vertexBoneInfluences; j++) { + int j; + for (j=0; j < vertexBoneInfluences; j++) { - // get weight per bone influence -- Ogre will ignore bones above - // 4 and sum the weights to make it work, so leverage that feature - int boneIdx = getBoneIndex(skin->GetBoneName(skinData->GetAssignedBone(i, j))); - float vertexWeight = skinData->GetBoneWeight(i, j); + // get weight per bone influence -- Ogre will ignore bones above + // 4 and sum the weights to make it work, so leverage that feature + int boneIdx = getBoneIndex(skin->GetBoneName(skinData->GetAssignedBone(i, j))); + float vertexWeight = skinData->GetBoneWeight(i, j); - of << "\t\t\t\t" << std::endl; - } - } - } - - of << "\t\t\t" << std::endl; - } + of << "\t\t\t\t" << std::endl; + } + } + } + + of << "\t\t\t" << std::endl; + } */ - return true; - } + return true; + } - int MeshXMLExporter::getBoneIndex(char *boneName) { + int MeshXMLExporter::getBoneIndex(char *boneName) { - std::map< std::string, int >::const_iterator it = m_boneIndexMap.find(std::string(boneName)); - if (it == m_boneIndexMap.end()) { - m_boneIndexMap.insert(std::map< std::string, int >::value_type(std::string(boneName), m_currentBoneIndex)); - return m_currentBoneIndex++; - } - else - return it->second; - } + std::map< std::string, int >::const_iterator it = m_boneIndexMap.find(std::string(boneName)); + if (it == m_boneIndexMap.end()) { + m_boneIndexMap.insert(std::map< std::string, int >::value_type(std::string(boneName), m_currentBoneIndex)); + return m_currentBoneIndex++; + } + else + return it->second; + } #if 0 - bool MeshXMLExporter::export(OutputMap& output) { - - try { - - // all options have been set when actions were taken, so we can just start exporting stuff here - - // write XML to a strstream - std::stringstream of; - bool rtn = true; - - // clear the node list and submesh name list - m_nodeList.clear(); - while (!m_submeshNames.empty()) - m_submeshNames.pop(); + bool MeshXMLExporter::export(OutputMap& output) { + + try { + + // all options have been set when actions were taken, so we can just start exporting stuff here + + // write XML to a strstream + std::stringstream of; + bool rtn = true; + + // clear the node list and submesh name list + m_nodeList.clear(); + while (!m_submeshNames.empty()) + m_submeshNames.pop(); - // populate the node list - m_ei->theScene->EnumTree(this); + // populate the node list + m_ei->theScene->EnumTree(this); - // check to see if there's anything to export - if (m_nodeList.size() == 0) { - MessageBox(GetActiveWindow(), "No nodes available to export, aborting...", "Nothing To Export", MB_ICONINFORMATION); - return false; - } + // check to see if there's anything to export + if (m_nodeList.size() == 0) { + MessageBox(GetActiveWindow(), "No nodes available to export, aborting...", "Nothing To Export", MB_ICONINFORMATION); + return false; + } - // if we are writing everything to one file, use the name provided when the user first started the export; - // otherwise, create filenames on the basis of the node (submesh) names - std::string fileName; - if (!m_config.getExportMultipleFiles()) - fileName = m_config.getExportFilename(); - else { - fileName = m_config.getExportPath() + "\\"; - INode *n = *(m_nodeList.begin()); - fileName += n->GetName(); - fileName += ".mesh.xml"; - } + // if we are writing everything to one file, use the name provided when the user first started the export; + // otherwise, create filenames on the basis of the node (submesh) names + std::string fileName; + if (!m_config.getExportMultipleFiles()) + fileName = m_config.getExportFilename(); + else { + fileName = m_config.getExportPath() + "\\"; + INode *n = *(m_nodeList.begin()); + fileName += n->GetName(); + fileName += ".mesh.xml"; + } - // write start of XML data - streamFileHeader(of); + // write start of XML data + streamFileHeader(of); - std::list::iterator it = m_nodeList.begin(); + std::list::iterator it = m_nodeList.begin(); - // user request -- if no material is assigned to this node, then use an export-specified - // default material name - Mtl *nodeMtl = (*it)->GetMtl(); - if (nodeMtl == NULL) { - m_materialMap[m_config.getDefaultMaterialName()] = 0; // we can do this as often as we like -- it will just overwrite zero with zero - } + // user request -- if no material is assigned to this node, then use an export-specified + // default material name + Mtl *nodeMtl = (*it)->GetMtl(); + if (nodeMtl == NULL) { + m_materialMap[m_config.getDefaultMaterialName()] = 0; // we can do this as often as we like -- it will just overwrite zero with zero + } - while (it != m_nodeList.end()) { + while (it != m_nodeList.end()) { - // we already filtered out nodes that had NULL materials, and those that could - // not be converted to TriObjects, so now we know everything we have is good + // we already filtered out nodes that had NULL materials, and those that could + // not be converted to TriObjects, so now we know everything we have is good - INode *node = *it; - std::string mtlName; - - Mtl *mtl = node->GetMtl(); - if (mtl == NULL) - mtlName = m_config.getDefaultMaterialName(); - else - mtlName = mtl->GetName(); + INode *node = *it; + std::string mtlName; + + Mtl *mtl = node->GetMtl(); + if (mtl == NULL) + mtlName = m_config.getDefaultMaterialName(); + else + mtlName = mtl->GetName(); - // map a material name to its Mtl pointer so that we can retrieve these later - std::string::size_type pos; + // map a material name to its Mtl pointer so that we can retrieve these later + std::string::size_type pos; - // clean out any spaces the user left in their material name - while ((pos = mtlName.find_first_of(' ')) != std::string::npos) - mtlName.replace(pos, 1, _T("_")); + // clean out any spaces the user left in their material name + while ((pos = mtlName.find_first_of(' ')) != std::string::npos) + mtlName.replace(pos, 1, _T("_")); - m_materialMap[mtlName] = mtl; + m_materialMap[mtlName] = mtl; - if (streamSubmesh(of, node, mtlName)) - m_submeshNames.push(std::string((*it)->GetName())); + if (streamSubmesh(of, node, mtlName)) + m_submeshNames.push(std::string((*it)->GetName())); - it++; + it++; - // if we are doing one mesh per file, then close this one and open a new one - if (m_config.getExportMultipleFiles() || it == m_nodeList.end()) { + // if we are doing one mesh per file, then close this one and open a new one + if (m_config.getExportMultipleFiles() || it == m_nodeList.end()) { - // write end of this file's XML - streamFileFooter(of); + // write end of this file's XML + streamFileFooter(of); - // insert new filename --> stream pair into output map - output[fileName] = std::string(of.str()); - of.str(""); + // insert new filename --> stream pair into output map + output[fileName] = std::string(of.str()); + of.str(""); - if (it != m_nodeList.end()) { - fileName = m_config.getExportPath() + "\\"; - INode *n = *it; - fileName += n->GetName(); - fileName += ".mesh.xml"; + if (it != m_nodeList.end()) { + fileName = m_config.getExportPath() + "\\"; + INode *n = *it; + fileName += n->GetName(); + fileName += ".mesh.xml"; - // start over again with new data - streamFileHeader(of); - } - } - } + // start over again with new data + streamFileHeader(of); + } + } + } - return rtn; - } - catch (...) { - MessageBox(GetActiveWindow(), "An unexpected error has occurred while trying to export, aborting", "Error", MB_ICONEXCLAMATION); - return false; - } - } + return rtn; + } + catch (...) { + MessageBox(GetActiveWindow(), "An unexpected error has occurred while trying to export, aborting", "Error", MB_ICONEXCLAMATION); + return false; + } + } - bool MeshXMLExporter::streamFileHeader(std::ostream &of) { + bool MeshXMLExporter::streamFileHeader(std::ostream &of) { - // write the XML header tags - of << "" << std::endl; - of << "" << std::endl; + // write the XML header tags + of << "" << std::endl; + of << "" << std::endl; - // *************** Export Submeshes *************** - of << "\t" << std::endl; + // *************** Export Submeshes *************** + of << "\t" << std::endl; - of.precision(6); - of << std::fixed; + of.precision(6); + of << std::fixed; - return true; - } + return true; + } - bool MeshXMLExporter::streamFileFooter(std::ostream &of) { + bool MeshXMLExporter::streamFileFooter(std::ostream &of) { - of << "\t" << std::endl; - // *************** End Submeshes Export *********** + of << "\t" << std::endl; + // *************** End Submeshes Export *********** - // if there is a skeleton involved, link that filename here - if (m_createSkeletonLink) { - std::string skeletonFilename(m_skeletonFilename); - skeletonFilename = skeletonFilename.substr(0, skeletonFilename.find(".xml")); + // if there is a skeleton involved, link that filename here + if (m_createSkeletonLink) { + std::string skeletonFilename(m_skeletonFilename); + skeletonFilename = skeletonFilename.substr(0, skeletonFilename.find(".xml")); - of << "\t" << std::endl; - } + of << "\t" << std::endl; + } - // *************** Export Submesh Names *************** - of << "\t" << std::endl; + // *************** Export Submesh Names *************** + of << "\t" << std::endl; - int idx = 0; - while (!m_submeshNames.empty()) { - of << "\t\t" << std::endl; - idx++; - m_submeshNames.pop(); - } + int idx = 0; + while (!m_submeshNames.empty()) { + of << "\t\t" << std::endl; + idx++; + m_submeshNames.pop(); + } - of << "\t" << std::endl; - // *************** End Submesh Names Export *********** + of << "\t" << std::endl; + // *************** End Submesh Names Export *********** - of << "" << std::endl; + of << "" << std::endl; - return true; - } + return true; + } - bool MeshXMLExporter::streamSubmesh(std::ostream &of, INode *node, std::string &mtlName) { - - Object *obj = node->EvalWorldState(m_i->GetTime()).obj; - TriObject *tri = (TriObject *) obj->ConvertToType(m_i->GetTime(), Class_ID(TRIOBJ_CLASS_ID, 0)); + bool MeshXMLExporter::streamSubmesh(std::ostream &of, INode *node, std::string &mtlName) { + + Object *obj = node->EvalWorldState(m_i->GetTime()).obj; + TriObject *tri = (TriObject *) obj->ConvertToType(m_i->GetTime(), Class_ID(TRIOBJ_CLASS_ID, 0)); - int i; - Mesh mesh = tri->GetMesh(); - Mtl* mtl = node->GetMtl(); - Matrix3 ptm = node->GetObjTMAfterWSM(m_i->GetTime()); + int i; + Mesh mesh = tri->GetMesh(); + Mtl* mtl = node->GetMtl(); + Matrix3 ptm = node->GetObjTMAfterWSM(m_i->GetTime()); - int vertCount = mesh.getNumVerts(); - int faceCount = mesh.getNumFaces(); + int vertCount = mesh.getNumVerts(); + int faceCount = mesh.getNumFaces(); - of << "\t\t 0) - of << "material=\"" << mtlName << "\" "; + of << "\t\t 0) + of << "material=\"" << mtlName << "\" "; - of << "usesharedvertices=\"false\" use32bitindexes=\""; - of << (vertCount > 65535); - of << "\">" << std::endl; + of << "usesharedvertices=\"false\" use32bitindexes=\""; + of << (vertCount > 65535); + of << "\">" << std::endl; - // *************** Export Face List *************** - of << "\t\t\t" << std::endl; + // *************** Export Face List *************** + of << "\t\t\t" << std::endl; - // store UV coords from the faces, not from the vertices themselves - std::vector texCoords; - texCoords.reserve(vertCount); + // store UV coords from the faces, not from the vertices themselves + std::vector texCoords; + texCoords.reserve(vertCount); - for (i=0; i" << std::endl; - } - - of << "\t\t\t" << std::endl; - // *************** End Export Face List *************** - - - // *************** Export Geometry *************** - of << "\t\t\t" << std::endl; - - // *************** Export Vertex Buffer *************** - if (m_config.getRebuildNormals()) { - mesh.buildNormals(); - } - - bool exportNormals = (mesh.normalsBuilt > 0); - - of << std::boolalpha; - - // NB: we don't export tex coords unless we are exporting a material as well - // NB: apparently Max cannot just tell us how many texmaps a material uses...so we have to add them up - - // we need a list of enabled map indices for later - std::list texMaps; - if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { - StdMat* sMtl = (StdMat*) mtl; - if (m_config.getExportMaterial()) { - for (int t=0; tNumSubTexmaps(); t++) - - if (sMtl->MapEnabled(t)) { - BitmapTex* TMap = (BitmapTex*)sMtl->GetSubTexmap(ID_DI); - if (!TMap) - return false; - - //Check if we have a Bitmap Texture material (BitmapTex) - if (TMap->ClassID() != Class_ID(BMTEX_CLASS_ID,0)) - return false; //Not interesting - - UVGen * pUVGen = TMap->GetTheUVGen() ; - if(!pUVGen) - return false; - - const int iAxis = pUVGen->GetAxis(); - texMaps.push_back(t); - } - } - } - - of << "\t\t\t\t" << std::endl; - - for (i=0; i" << std::endl; - of << std::showpoint; - - float x = v.x;// * m_scale; - float y = v.y;// * m_scale; - float z = v.z;// * m_scale; - - if (m_config.getInvertYZ()) { - float tmp = y; - y = z; - z = -tmp; - } - - of << "\t\t\t\t\t\t" << std::endl; - - if (m_config.getExportVertexColours()) - of << "\t\t\t\t\t\t" << std::endl; - - if (exportNormals) { - // Point3 n = mesh.getNormal(i); - RVertex *rv = mesh.getRVertPtr(i); - Point3 n = rv->rn.getNormal(); - n = n.Normalize(); - - float x = n.x; - float y = n.y; - float z = n.z; - - if (m_config.getInvertYZ()) { - float tmp = y; - y = z; - z = -tmp; - } - - if (m_config.getInvertNormals()) - of << "\t\t\t\t\t\t" << std::endl; - else - of << "\t\t\t\t\t\t" << std::endl; - } - - // output the tex coords for each map used - std::list::iterator texMap = texMaps.begin(); - while (texMap != texMaps.end()) { - UVVert uv; - - if (*texMap <= 1) - uv = mesh.tVerts[i]; - else - uv = mesh.mapVerts(*texMap)[i]; - - switch (m_config.getTexCoord2D()) { - case OgreMax::UV: - of << "\t\t\t\t\t\t" << std::endl; - break; - case OgreMax::VW: - of << "\t\t\t\t\t\t" << std::endl; - break; - case OgreMax::WU: - of << "\t\t\t\t\t\t" << std::endl; - break; - } - - texMap++; - } - - of << std::noshowpoint; - of << "\t\t\t\t\t" << std::endl; - } - - of << "\t\t\t\t" << std::endl; - // *************** End Export Vertex Buffer *************** - - of << "\t\t\t" << std::endl; - // *************** End Export Geometry *********** - - // this skin extraction code based on an article found here: - // http://www.cfxweb.net/modules.php?name=News&file=article&sid=1029 - Object *oRef = node->GetObjectRef(); - - if (oRef->SuperClassID() == GEN_DERIVOB_CLASS_ID) { - IDerivedObject *dObj = (IDerivedObject *)oRef; - Modifier *oMod = dObj->GetModifier(0); - - if (oMod->ClassID() == SKIN_CLASSID) { - - // flag the export of a skeleton link element - m_createSkeletonLink = true; - - // stream the boneassignments element - streamBoneAssignments(of, oMod, node); - } - } - - of << "\t\t" << std::endl; - - if (obj != tri) - delete tri; - - return true; - } - - bool MeshXMLExporter::streamBoneAssignments(std::ostream &of, Modifier *oMod, INode *node) { - - - // wrangle a pointer to the skinning data - ISkin *skin = (ISkin *) oMod->GetInterface(I_SKIN); - ISkinContextData *skinData = skin->GetContextInterface(node); - - // loop through all the vertices, writing out skinning data as we go - int skinnedVertexCount = skinData->GetNumPoints(); - - if (skinnedVertexCount > 0) { - - of << "\t\t\t" << std::endl; - - int i; - for(i=0; iGetNumAssignedBones(i); - - if (vertexBoneInfluences > 0) { - - int j; - for (j=0; j < vertexBoneInfluences; j++) { - - // get weight per bone influence -- Ogre will ignore bones above - // 4 and sum the weights to make it work, so leverage that feature - int boneIdx = getBoneIndex(skin->GetBoneName(skinData->GetAssignedBone(i, j))); - float vertexWeight = skinData->GetBoneWeight(i, j); - - of << "\t\t\t\t" << std::endl; - } - } - } - - of << "\t\t\t" << std::endl; - } - - return true; - } - - int MeshXMLExporter::getBoneIndex(char *boneName) { - - std::map< std::string, int >::const_iterator it = m_boneIndexMap.find(std::string(boneName)); - if (it == m_boneIndexMap.end()) { - m_boneIndexMap.insert(std::map< std::string, int >::value_type(std::string(boneName), m_currentBoneIndex)); - return m_currentBoneIndex++; - } - else - return it->second; - } - - // pulled directly from the Sparks site: - // http://sparks.discreet.com/Knowledgebase/sdkdocs_v8/prog/cs/cs_physique_export.html - // Also available in the SDK docs. Used to find out if this node has a physique modifier or not. - // If it does, it returns a pointer to the modifier, and if not, returns NULL. This can be used to - // determine whether a node is bone or mesh -- mesh nodes will have Physique modifiers, bone nodes - // will not. - Modifier* MeshXMLExporter::FindPhysiqueModifier (INode* nodePtr) - { - // Get object from node. Abort if no object. - Object* ObjectPtr = nodePtr->GetObjectRef(); - - if (!ObjectPtr) return NULL; - - // Is derived object ? - while (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID && ObjectPtr) - { - // Yes -> Cast. - IDerivedObject *DerivedObjectPtr = (IDerivedObject *)(ObjectPtr); - - // Iterate over all entries of the modifier stack. - int ModStackIndex = 0; - while (ModStackIndex < DerivedObjectPtr->NumModifiers()) - { - // Get current modifier. - Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(ModStackIndex); - - // Is this Physique ? - if (ModifierPtr->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)) - { - // Yes -> Exit. - return ModifierPtr; - } - - // Next modifier stack entry. - ModStackIndex++; - } - ObjectPtr = DerivedObjectPtr->GetObjRef(); - } - - // Not found. - return NULL; - } + of << "\t\t\t\t" << std::endl; + } + + of << "\t\t\t" << std::endl; + // *************** End Export Face List *************** + + + // *************** Export Geometry *************** + of << "\t\t\t" << std::endl; + + // *************** Export Vertex Buffer *************** + if (m_config.getRebuildNormals()) { + mesh.buildNormals(); + } + + bool exportNormals = (mesh.normalsBuilt > 0); + + of << std::boolalpha; + + // NB: we don't export tex coords unless we are exporting a material as well + // NB: apparently Max cannot just tell us how many texmaps a material uses...so we have to add them up + + // we need a list of enabled map indices for later + std::list texMaps; + if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { + StdMat* sMtl = (StdMat*) mtl; + if (m_config.getExportMaterial()) { + for (int t=0; tNumSubTexmaps(); t++) + + if (sMtl->MapEnabled(t)) { + BitmapTex* TMap = (BitmapTex*)sMtl->GetSubTexmap(ID_DI); + if (!TMap) + return false; + + //Check if we have a Bitmap Texture material (BitmapTex) + if (TMap->ClassID() != Class_ID(BMTEX_CLASS_ID,0)) + return false; //Not interesting + + UVGen * pUVGen = TMap->GetTheUVGen() ; + if(!pUVGen) + return false; + + const int iAxis = pUVGen->GetAxis(); + texMaps.push_back(t); + } + } + } + + of << "\t\t\t\t" << std::endl; + + for (i=0; i" << std::endl; + of << std::showpoint; + + float x = v.x;// * m_scale; + float y = v.y;// * m_scale; + float z = v.z;// * m_scale; + + if (m_config.getInvertYZ()) { + float tmp = y; + y = z; + z = -tmp; + } + + of << "\t\t\t\t\t\t" << std::endl; + + if (m_config.getExportVertexColours()) + of << "\t\t\t\t\t\t" << std::endl; + + if (exportNormals) { + // Point3 n = mesh.getNormal(i); + RVertex *rv = mesh.getRVertPtr(i); + Point3 n = rv->rn.getNormal(); + n = n.Normalize(); + + float x = n.x; + float y = n.y; + float z = n.z; + + if (m_config.getInvertYZ()) { + float tmp = y; + y = z; + z = -tmp; + } + + if (m_config.getInvertNormals()) + of << "\t\t\t\t\t\t" << std::endl; + else + of << "\t\t\t\t\t\t" << std::endl; + } + + // output the tex coords for each map used + std::list::iterator texMap = texMaps.begin(); + while (texMap != texMaps.end()) { + UVVert uv; + + if (*texMap <= 1) + uv = mesh.tVerts[i]; + else + uv = mesh.mapVerts(*texMap)[i]; + + switch (m_config.getTexCoord2D()) { + case OgreMax::UV: + of << "\t\t\t\t\t\t" << std::endl; + break; + case OgreMax::VW: + of << "\t\t\t\t\t\t" << std::endl; + break; + case OgreMax::WU: + of << "\t\t\t\t\t\t" << std::endl; + break; + } + + texMap++; + } + + of << std::noshowpoint; + of << "\t\t\t\t\t" << std::endl; + } + + of << "\t\t\t\t" << std::endl; + // *************** End Export Vertex Buffer *************** + + of << "\t\t\t" << std::endl; + // *************** End Export Geometry *********** + + // this skin extraction code based on an article found here: + // http://www.cfxweb.net/modules.php?name=News&file=article&sid=1029 + Object *oRef = node->GetObjectRef(); + + if (oRef->SuperClassID() == GEN_DERIVOB_CLASS_ID) { + IDerivedObject *dObj = (IDerivedObject *)oRef; + Modifier *oMod = dObj->GetModifier(0); + + if (oMod->ClassID() == SKIN_CLASSID) { + + // flag the export of a skeleton link element + m_createSkeletonLink = true; + + // stream the boneassignments element + streamBoneAssignments(of, oMod, node); + } + } + + of << "\t\t" << std::endl; + + if (obj != tri) + delete tri; + + return true; + } + + bool MeshXMLExporter::streamBoneAssignments(std::ostream &of, Modifier *oMod, INode *node) { + + + // wrangle a pointer to the skinning data + ISkin *skin = (ISkin *) oMod->GetInterface(I_SKIN); + ISkinContextData *skinData = skin->GetContextInterface(node); + + // loop through all the vertices, writing out skinning data as we go + int skinnedVertexCount = skinData->GetNumPoints(); + + if (skinnedVertexCount > 0) { + + of << "\t\t\t" << std::endl; + + int i; + for(i=0; iGetNumAssignedBones(i); + + if (vertexBoneInfluences > 0) { + + int j; + for (j=0; j < vertexBoneInfluences; j++) { + + // get weight per bone influence -- Ogre will ignore bones above + // 4 and sum the weights to make it work, so leverage that feature + int boneIdx = getBoneIndex(skin->GetBoneName(skinData->GetAssignedBone(i, j))); + float vertexWeight = skinData->GetBoneWeight(i, j); + + of << "\t\t\t\t" << std::endl; + } + } + } + + of << "\t\t\t" << std::endl; + } + + return true; + } + + int MeshXMLExporter::getBoneIndex(char *boneName) { + + std::map< std::string, int >::const_iterator it = m_boneIndexMap.find(std::string(boneName)); + if (it == m_boneIndexMap.end()) { + m_boneIndexMap.insert(std::map< std::string, int >::value_type(std::string(boneName), m_currentBoneIndex)); + return m_currentBoneIndex++; + } + else + return it->second; + } + + // pulled directly from the Sparks site: + // http://sparks.discreet.com/Knowledgebase/sdkdocs_v8/prog/cs/cs_physique_export.html + // Also available in the SDK docs. Used to find out if this node has a physique modifier or not. + // If it does, it returns a pointer to the modifier, and if not, returns NULL. This can be used to + // determine whether a node is bone or mesh -- mesh nodes will have Physique modifiers, bone nodes + // will not. + Modifier* MeshXMLExporter::FindPhysiqueModifier (INode* nodePtr) + { + // Get object from node. Abort if no object. + Object* ObjectPtr = nodePtr->GetObjectRef(); + + if (!ObjectPtr) return NULL; + + // Is derived object ? + while (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID && ObjectPtr) + { + // Yes -> Cast. + IDerivedObject *DerivedObjectPtr = (IDerivedObject *)(ObjectPtr); + + // Iterate over all entries of the modifier stack. + int ModStackIndex = 0; + while (ModStackIndex < DerivedObjectPtr->NumModifiers()) + { + // Get current modifier. + Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(ModStackIndex); + + // Is this Physique ? + if (ModifierPtr->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)) + { + // Yes -> Exit. + return ModifierPtr; + } + + // Next modifier stack entry. + ModStackIndex++; + } + ObjectPtr = DerivedObjectPtr->GetObjRef(); + } + + // Not found. + return NULL; + } #endif } diff --git a/Tools/3dsmaxExport/OgreExport/src/OgreMaxVertex.cpp b/Tools/3dsmaxExport/OgreExport/src/OgreMaxVertex.cpp index de150dee14d..0f929e03ae6 100644 --- a/Tools/3dsmaxExport/OgreExport/src/OgreMaxVertex.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/OgreMaxVertex.cpp @@ -2,74 +2,74 @@ namespace OgreMax { - Vertex::Vertex(float x, float y, float z) { - m_position.x = x; - m_position.y = y; - m_position.z = z; - } - - void Vertex::setNormal(float x, float y, float z) { - m_normal.x = x; - m_normal.y = y; - m_normal.z = z; - } - - void Vertex::setColour(float r, float g, float b, float a) { - m_colour.r = r; - m_colour.g = g; - m_colour.b = b; - m_colour.a = a; - } - - void Vertex::addTexCoord(int mapIndex, float u, float v, float w) { - Ogre::Vector3 uvw; - - uvw.x = u; - uvw.y = v; - uvw.z = w; - - m_uvwMap[mapIndex] = uvw; - } - - bool Vertex::hasSameTexCoords(std::map& uvwMap) { - std::map::const_iterator it = uvwMap.begin(); - - while (it != uvwMap.end()) { - try { - if (m_uvwMap[it->first] != it->second) - return false; - } - catch (...) { - return false; - } - - ++it; - } - - return true; - } - - bool Vertex::operator == (Vertex& other) { - return ( - m_position == other.m_position && - m_normal == other.m_normal && - m_colour == other.m_colour && - other.hasSameTexCoords(m_uvwMap) - ); - } - - - unsigned int VertexList::add(Vertex& v) { - - int idx = 0; - for (std::list::iterator it = m_vertexList.begin(); it != m_vertexList.end(); ++it, ++idx) { - if (*it == v) - break; - } - - if (it == m_vertexList.end()) - m_vertexList.push_back(v); - - return idx; - } + Vertex::Vertex(float x, float y, float z) { + m_position.x = x; + m_position.y = y; + m_position.z = z; + } + + void Vertex::setNormal(float x, float y, float z) { + m_normal.x = x; + m_normal.y = y; + m_normal.z = z; + } + + void Vertex::setColour(float r, float g, float b, float a) { + m_colour.r = r; + m_colour.g = g; + m_colour.b = b; + m_colour.a = a; + } + + void Vertex::addTexCoord(int mapIndex, float u, float v, float w) { + Ogre::Vector3 uvw; + + uvw.x = u; + uvw.y = v; + uvw.z = w; + + m_uvwMap[mapIndex] = uvw; + } + + bool Vertex::hasSameTexCoords(std::map& uvwMap) { + std::map::const_iterator it = uvwMap.begin(); + + while (it != uvwMap.end()) { + try { + if (m_uvwMap[it->first] != it->second) + return false; + } + catch (...) { + return false; + } + + ++it; + } + + return true; + } + + bool Vertex::operator == (Vertex& other) { + return ( + m_position == other.m_position && + m_normal == other.m_normal && + m_colour == other.m_colour && + other.hasSameTexCoords(m_uvwMap) + ); + } + + + unsigned int VertexList::add(Vertex& v) { + + int idx = 0; + for (std::list::iterator it = m_vertexList.begin(); it != m_vertexList.end(); ++it, ++idx) { + if (*it == v) + break; + } + + if (it == m_vertexList.end()) + m_vertexList.push_back(v); + + return idx; + } } \ No newline at end of file diff --git a/Tools/3dsmaxExport/OgreExport/src/dllmain.cpp b/Tools/3dsmaxExport/OgreExport/src/dllmain.cpp index 374f3d43258..d6487daf94f 100644 --- a/Tools/3dsmaxExport/OgreExport/src/dllmain.cpp +++ b/Tools/3dsmaxExport/OgreExport/src/dllmain.cpp @@ -36,69 +36,69 @@ static int controlsInit = FALSE; static HINSTANCE hInstance; BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) { - hInstance = hinstDLL; - if ( !controlsInit ) { - controlsInit = TRUE; - - // jaguar controls - InitCustomControls(hInstance); - - // initialize Chicago controls - InitCommonControls(); - } - switch(fdwReason) { - case DLL_PROCESS_ATTACH: - //MessageBox(NULL,_T("3DSIMP.DLL: DllMain"),_T("3DSIMP"),MB_OK); - if (FAILED(CoInitialize(NULL))) - return FALSE; - break; - case DLL_THREAD_ATTACH: - break; - case DLL_THREAD_DETACH: - break; - case DLL_PROCESS_DETACH: - break; - } - return(TRUE); - } + hInstance = hinstDLL; + if ( !controlsInit ) { + controlsInit = TRUE; + + // jaguar controls + InitCustomControls(hInstance); + + // initialize Chicago controls + InitCommonControls(); + } + switch(fdwReason) { + case DLL_PROCESS_ATTACH: + //MessageBox(NULL,_T("3DSIMP.DLL: DllMain"),_T("3DSIMP"),MB_OK); + if (FAILED(CoInitialize(NULL))) + return FALSE; + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + case DLL_PROCESS_DETACH: + break; + } + return(TRUE); + } //------------------------------------------------------ static OgreMaxExportClassDesc OgreMaxExportDescInst; int OgreMaxExportClassDesc::IsPublic() { - return 1; + return 1; } void * OgreMaxExportClassDesc::Create(BOOL loading) { - OgreMaxExport *inst = new OgreMaxExport(hInstance); - return inst; + OgreMaxExport *inst = new OgreMaxExport(hInstance); + return inst; } const TCHAR * OgreMaxExportClassDesc::ClassName() { - return _T("Ogre 3DSMax Exporter"); + return _T("Ogre 3DSMax Exporter"); } SClass_ID OgreMaxExportClassDesc::SuperClassID() { - return SCENE_EXPORT_CLASS_ID; + return SCENE_EXPORT_CLASS_ID; } Class_ID OgreMaxExportClassDesc::ClassID() { - return Class_ID(0x2a961d1d, 0x8160db1); + return Class_ID(0x2a961d1d, 0x8160db1); } const TCHAR* OgreMaxExportClassDesc::Category() { - return _T("Ogre 3DSMax Exporter"); + return _T("Ogre 3DSMax Exporter"); } TCHAR *GetString(int id) { - static TCHAR buf[256]; + static TCHAR buf[256]; - if (hInstance) - return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL; - return NULL; + if (hInstance) + return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL; + return NULL; } extern "C" { @@ -109,39 +109,39 @@ extern "C" { // what does this DLL contain? __declspec( dllexport ) const TCHAR * LibDescription() { - return _T("Ogre 3DSMax Exporter"); + return _T("Ogre 3DSMax Exporter"); } // how many plugin classes do we implement in this DLL? __declspec( dllexport ) int LibNumberClasses() { - return 1; + return 1; } // return a class descriptor class for each plugin class in this DLL; // 0-based, so i==0 is the first plugin in this DLL, and so on __declspec( dllexport ) ClassDesc * LibClassDesc(int i) { - switch(i) { - case 0: - return &OgreMaxExportDescInst; - break; - default: - return 0; - break; - } + switch(i) { + case 0: + return &OgreMaxExportDescInst; + break; + default: + return 0; + break; + } } // Return version so can detect obsolete DLLs __declspec( dllexport ) ULONG LibVersion() { - return VERSION_3DSMAX; + return VERSION_3DSMAX; } // Let the plug-in register itself for deferred loading __declspec( dllexport ) ULONG CanAutoDefer() { - return 1; + return 1; } } \ No newline at end of file diff --git a/Tools/LightwaveConverter/include/BitArray.h b/Tools/LightwaveConverter/include/BitArray.h index d30683af9cf..76d04b767cd 100644 --- a/Tools/LightwaveConverter/include/BitArray.h +++ b/Tools/LightwaveConverter/include/BitArray.h @@ -5,115 +5,115 @@ class BitArray { private: /** The number of bits in this array - */ - unsigned long arraysize; - /** The number of unsigned longs for storing at least arraysize bits - */ - unsigned long bitlongs; - /** The array of unsigned longs containing the bits - */ - unsigned long *bits; + */ + unsigned long arraysize; + /** The number of unsigned longs for storing at least arraysize bits + */ + unsigned long bitlongs; + /** The array of unsigned longs containing the bits + */ + unsigned long *bits; public: /** Constructors. */ - BitArray(unsigned long newsize); - BitArray(const BitArray& b); - - BitArray(unsigned long newsize, bool setclear); - BitArray(unsigned long newsize, unsigned long *newbits); - + BitArray(unsigned long newsize); + BitArray(const BitArray& b); + + BitArray(unsigned long newsize, bool setclear); + BitArray(unsigned long newsize, unsigned long *newbits); + /** Destructor. */ - ~BitArray(); - - BitArray& operator =(const BitArray& b); - BitArray operator ~(void); - BitArray& operator ^=(const BitArray& b); - BitArray& operator &=(const BitArray& b); - BitArray& operator |=(const BitArray& b); - BitArray operator ^(const BitArray& b); - BitArray operator &(const BitArray& b); - BitArray operator |(const BitArray& b); - - /** Test to see if a single bit is set. - */ - inline bool bitSet(unsigned long index) const - { - return bits[(index>>5)] >> (index & 0x0000001f) & 0x00000001; - } - /** Clear all bits in this array. - */ - inline void clear(void) - { - fillBitArray(0x00000000); - } - /** Clear a single bit. - */ - inline void clearBit(unsigned long index) - { - bits[index >> 5] &= ~(0x00000001 << (index & 0x0000001f)); - } - /** fill with a 32-bit pattern. - */ - inline void fillBitArray(unsigned long pattern) - { - for (unsigned long i=0; i < bitlongs; bits[i++]=pattern); - } + ~BitArray(); + + BitArray& operator =(const BitArray& b); + BitArray operator ~(void); + BitArray& operator ^=(const BitArray& b); + BitArray& operator &=(const BitArray& b); + BitArray& operator |=(const BitArray& b); + BitArray operator ^(const BitArray& b); + BitArray operator &(const BitArray& b); + BitArray operator |(const BitArray& b); + + /** Test to see if a single bit is set. + */ + inline bool bitSet(unsigned long index) const + { + return bits[(index>>5)] >> (index & 0x0000001f) & 0x00000001; + } + /** Clear all bits in this array. + */ + inline void clear(void) + { + fillBitArray(0x00000000); + } + /** Clear a single bit. + */ + inline void clearBit(unsigned long index) + { + bits[index >> 5] &= ~(0x00000001 << (index & 0x0000001f)); + } + /** fill with a 32-bit pattern. + */ + inline void fillBitArray(unsigned long pattern) + { + for (unsigned long i=0; i < bitlongs; bits[i++]=pattern); + } - /** flip a single bit. - */ - inline void flipBit(unsigned long index) - { - if (bitSet(index)) - clearBit(index); - else - setBit(index); - }; + /** flip a single bit. + */ + inline void flipBit(unsigned long index) + { + if (bitSet(index)) + clearBit(index); + else + setBit(index); + }; - /** Returns index of next set bit in array (wraps around) + /** Returns index of next set bit in array (wraps around) + */ + inline long getNextSet(unsigned long index) + { + unsigned long i; + for (i=index+1;i0;i--) if (bitSet(i)) return i; + if (bitSet(0)) return 0; + } + for (i=arraysize-1;i>index;i--) if (bitSet(i)) return i; + return -1; + } + + /** Set all bits in this array. + */ + inline void set(void) + { + fillBitArray(0xffffffff); + } + + /** Set a single bit. */ - inline long getNextSet(unsigned long index) - { - unsigned long i; - for (i=index+1;i> 5] |= 0x00000001 << (index & 0x0000001f); + } + + /** return the number of bits in this bit array.. */ - inline long getPreviousSet(unsigned long index) - { - unsigned long i; - if (index != 0) - { - for (i=index-1;i>0;i--) if (bitSet(i)) return i; - if (bitSet(0)) return 0; - } - for (i=arraysize-1;i>index;i--) if (bitSet(i)) return i; - return -1; - } - - /** Set all bits in this array. - */ - inline void set(void) - { - fillBitArray(0xffffffff); - } - - /** Set a single bit. - */ - inline void setBit(unsigned long index) - { - bits[index >> 5] |= 0x00000001 << (index & 0x0000001f); - } - - /** return the number of bits in this bit array.. - */ - inline unsigned long size(void) - { - return arraysize; - } + inline unsigned long size(void) + { + return arraysize; + } }; #endif // _BITARRAY_H_ diff --git a/Tools/LightwaveConverter/include/Point.h b/Tools/LightwaveConverter/include/Point.h index 99a97fd11a2..a86c805df0b 100644 --- a/Tools/LightwaveConverter/include/Point.h +++ b/Tools/LightwaveConverter/include/Point.h @@ -7,36 +7,36 @@ using namespace std; class Point3 { - public: - inline Point3() {} - - inline Point3(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {} - - inline Point3& operator =(const Vector3& v) - { - x = v.x; - y = v.y; - z = v.z; - return (*this); - } - - inline Point3& operator *=(float t) - { - x *= t; - y *= t; - z *= t; - return (*this); - } - - inline Point3& operator /=(float t) - { - float f = 1.0F / t; - x *= f; - y *= f; - z *= f; - return (*this); - } - + public: + inline Point3() {} + + inline Point3(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {} + + inline Point3& operator =(const Vector3& v) + { + x = v.x; + y = v.y; + z = v.z; + return (*this); + } + + inline Point3& operator *=(float t) + { + x *= t; + y *= t; + z *= t; + return (*this); + } + + inline Point3& operator /=(float t) + { + float f = 1.0F / t; + x *= f; + y *= f; + z *= f; + return (*this); + } + inline bool operator == ( const Point3& p ) const { return ( x == p.x && y == p.y && z == p.z ); @@ -47,47 +47,47 @@ class Point3 { return ( x != p.x || y != p.y || z != p.z ); } - inline Point3 operator -(void) const - { - return (Point3(-x, -y, -z)); - } - - // Sum of point and vector (direction) is a point - inline Point3 operator +(const Vector3& v) const - { - return (Point3(x + v.x, y + v.y, z + v.z)); - } - - // Difference of point and vector (direction) is a point - inline Point3 operator -(const Vector3& v) const - { - return (Point3(x - v.x, y - v.y, z - v.z)); - } - - // Difference between to points is a vector (direction) - inline Vector3 operator -(const Point3& p) const - { - return (Vector3(x - p.x, y - p.y, z - p.z)); - } - - inline Point3 operator *(float t) const - { - return (Point3(x * t, y * t, z * t)); - } - - inline Point3 operator /(float t) const - { - float f = 1.0F / t; - return (Point3(x * f, y * f, z * f)); - } - - // Dot product - inline float operator *(const Vector3& v) const - { - return (x * v.x + y * v.y + z * v.z); - } + inline Point3 operator -(void) const + { + return (Point3(-x, -y, -z)); + } + + // Sum of point and vector (direction) is a point + inline Point3 operator +(const Vector3& v) const + { + return (Point3(x + v.x, y + v.y, z + v.z)); + } + + // Difference of point and vector (direction) is a point + inline Point3 operator -(const Vector3& v) const + { + return (Point3(x - v.x, y - v.y, z - v.z)); + } + + // Difference between to points is a vector (direction) + inline Vector3 operator -(const Point3& p) const + { + return (Vector3(x - p.x, y - p.y, z - p.z)); + } + + inline Point3 operator *(float t) const + { + return (Point3(x * t, y * t, z * t)); + } + + inline Point3 operator /(float t) const + { + float f = 1.0F / t; + return (Point3(x * f, y * f, z * f)); + } + + // Dot product + inline float operator *(const Vector3& v) const + { + return (x * v.x + y * v.y + z * v.z); + } - float x, y, z; + float x, y, z; }; #endif // _POINT_H_ diff --git a/Tools/LightwaveConverter/include/Vector3.h b/Tools/LightwaveConverter/include/Vector3.h index e06b9d37e26..54cde5779e9 100644 --- a/Tools/LightwaveConverter/include/Vector3.h +++ b/Tools/LightwaveConverter/include/Vector3.h @@ -6,213 +6,213 @@ class Vector3 { public: - float x, y, z; + float x, y, z; - inline Vector3() {} - - inline Vector3( float nx, float ny, float nz ) : x(nx), y(ny), z(nz) {} - - inline Vector3( float v[3] ) : x(v[0]), y(v[1]), z(v[2]) {} - - inline Vector3( int v[3] ): x((float)v[0]), y((float)v[1]), z((float)v[2]) {} - - inline Vector3( const float* const v ) : x(v[0]), y(v[1]), z(v[2]) {} - - inline Vector3( const Vector3& v ) : x(v.x), y(v.y), z(v.z) {} - - inline float operator [] ( unsigned i ) const - { - return *(&x+i); - } - - inline float& operator [] ( unsigned i ) - { - return *(&x+i); - } - - inline Vector3& operator = ( const Vector3& v ) - { - x = v.x; - y = v.y; - z = v.z; - - return *this; - } - - inline bool operator == ( const Vector3& v ) const - { - return ( x == v.x && y == v.y && z == v.z ); - } - - inline bool operator != ( const Vector3& v ) const - { - return ( x != v.x || y != v.y || z != v.z ); - } - - // arithmetic operations - inline Vector3 operator + ( const Vector3& v ) const - { - return Vector3(x + v.x, y + v.y, z + v.z); - } - - inline Vector3 operator - ( const Vector3& v ) const - { - return Vector3(x - v.x, y - v.y, z - v.z); - } - - inline Vector3 operator * ( float f ) const - { - return Vector3(x * f, y * f, z * f); - } - - inline Vector3 operator * ( const Vector3& v) const - { - return Vector3(x * v.x, y * v.y, z * v.z); - } - - inline Vector3 operator / ( float f ) const - { - f = 1.0f / f; - return Vector3(x * f, y * f, z * f); - } - - inline Vector3 operator - () const - { - return Vector3( -x, -y, -z); - } - - inline friend Vector3 operator * ( float f, const Vector3& v ) - { - return Vector3(f * v.x, f * v.y, f * v.z); - } - - // arithmetic updates - inline Vector3& operator += ( const Vector3& v ) - { - x += v.x; - y += v.y; - z += v.z; - - return *this; - } - - inline Vector3& operator -= ( const Vector3& v ) - { - x -= v.x; - y -= v.y; - z -= v.z; - - return *this; - } - - inline Vector3& operator *= ( float f ) - { - x *= f; - y *= f; - z *= f; - return *this; - } - - inline Vector3& operator /= ( float f ) - { - f = 1.0f / f; - - x *= f; - y *= f; - z *= f; - - return *this; - } - - inline float length () const - { - return (float)sqrt( x * x + y * y + z * z ); - } - - inline float squaredLength () const - { - return x * x + y * y + z * z; - } - - inline float dotProduct(const Vector3& v) const - { - return x * v.x + y * v.y + z * v.z; - } - - inline Vector3 & normalise() - { - float f = (float)sqrt( x * x + y * y + z * z ); - - // Will also work for zero-sized vectors, but will change nothing - if ( f > 1e-06f ) - { - f = 1.0f / f; - x *= f; - y *= f; - z *= f; - } - - return *this; - } - - inline Vector3 crossProduct( const Vector3& v ) const - { - return Vector3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); - } - - inline Vector3 midPoint( const Vector3& v ) const - { - return Vector3( ( x + v.x ) * 0.5f, ( y + v.y ) * 0.5f, ( z + v.z ) * 0.5f ); - } - - inline bool operator < ( const Vector3& v ) const - { - return ( x < v.x && y < v.y && z < v.z ); - } - - inline bool operator > ( const Vector3& v ) const - { - return ( x > v.x && y > v.y && z > v.z ); - } - - inline void makeFloor( const Vector3& v ) - { - if( v.x < x ) x = v.x; - if( v.y < y ) y = v.y; - if( v.z < z ) z = v.z; - } - - inline void makeCeil( const Vector3& v ) - { - if( v.x > x ) x = v.x; - if( v.y > y ) y = v.y; - if( v.z > z ) z = v.z; - } - - inline Vector3 perpendicular(void) - { - static float fSquareZero = 1e-06f * 1e-06f; - - Vector3 perp = this->crossProduct( Vector3::UNIT_X ); - - // Check length - if( perp.squaredLength() < fSquareZero ) - { - /* This vector is the Y axis multiplied by a scalar, so we have - to use another axis. - */ - perp = this->crossProduct( Vector3::UNIT_Y ); - } - - return perp; - } - - // special points - static const Vector3 ZERO; - static const Vector3 UNIT_X; - static const Vector3 UNIT_Y; - static const Vector3 UNIT_Z; - static const Vector3 UNIT_SCALE; + inline Vector3() {} + + inline Vector3( float nx, float ny, float nz ) : x(nx), y(ny), z(nz) {} + + inline Vector3( float v[3] ) : x(v[0]), y(v[1]), z(v[2]) {} + + inline Vector3( int v[3] ): x((float)v[0]), y((float)v[1]), z((float)v[2]) {} + + inline Vector3( const float* const v ) : x(v[0]), y(v[1]), z(v[2]) {} + + inline Vector3( const Vector3& v ) : x(v.x), y(v.y), z(v.z) {} + + inline float operator [] ( unsigned i ) const + { + return *(&x+i); + } + + inline float& operator [] ( unsigned i ) + { + return *(&x+i); + } + + inline Vector3& operator = ( const Vector3& v ) + { + x = v.x; + y = v.y; + z = v.z; + + return *this; + } + + inline bool operator == ( const Vector3& v ) const + { + return ( x == v.x && y == v.y && z == v.z ); + } + + inline bool operator != ( const Vector3& v ) const + { + return ( x != v.x || y != v.y || z != v.z ); + } + + // arithmetic operations + inline Vector3 operator + ( const Vector3& v ) const + { + return Vector3(x + v.x, y + v.y, z + v.z); + } + + inline Vector3 operator - ( const Vector3& v ) const + { + return Vector3(x - v.x, y - v.y, z - v.z); + } + + inline Vector3 operator * ( float f ) const + { + return Vector3(x * f, y * f, z * f); + } + + inline Vector3 operator * ( const Vector3& v) const + { + return Vector3(x * v.x, y * v.y, z * v.z); + } + + inline Vector3 operator / ( float f ) const + { + f = 1.0f / f; + return Vector3(x * f, y * f, z * f); + } + + inline Vector3 operator - () const + { + return Vector3( -x, -y, -z); + } + + inline friend Vector3 operator * ( float f, const Vector3& v ) + { + return Vector3(f * v.x, f * v.y, f * v.z); + } + + // arithmetic updates + inline Vector3& operator += ( const Vector3& v ) + { + x += v.x; + y += v.y; + z += v.z; + + return *this; + } + + inline Vector3& operator -= ( const Vector3& v ) + { + x -= v.x; + y -= v.y; + z -= v.z; + + return *this; + } + + inline Vector3& operator *= ( float f ) + { + x *= f; + y *= f; + z *= f; + return *this; + } + + inline Vector3& operator /= ( float f ) + { + f = 1.0f / f; + + x *= f; + y *= f; + z *= f; + + return *this; + } + + inline float length () const + { + return (float)sqrt( x * x + y * y + z * z ); + } + + inline float squaredLength () const + { + return x * x + y * y + z * z; + } + + inline float dotProduct(const Vector3& v) const + { + return x * v.x + y * v.y + z * v.z; + } + + inline Vector3 & normalise() + { + float f = (float)sqrt( x * x + y * y + z * z ); + + // Will also work for zero-sized vectors, but will change nothing + if ( f > 1e-06f ) + { + f = 1.0f / f; + x *= f; + y *= f; + z *= f; + } + + return *this; + } + + inline Vector3 crossProduct( const Vector3& v ) const + { + return Vector3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); + } + + inline Vector3 midPoint( const Vector3& v ) const + { + return Vector3( ( x + v.x ) * 0.5f, ( y + v.y ) * 0.5f, ( z + v.z ) * 0.5f ); + } + + inline bool operator < ( const Vector3& v ) const + { + return ( x < v.x && y < v.y && z < v.z ); + } + + inline bool operator > ( const Vector3& v ) const + { + return ( x > v.x && y > v.y && z > v.z ); + } + + inline void makeFloor( const Vector3& v ) + { + if( v.x < x ) x = v.x; + if( v.y < y ) y = v.y; + if( v.z < z ) z = v.z; + } + + inline void makeCeil( const Vector3& v ) + { + if( v.x > x ) x = v.x; + if( v.y > y ) y = v.y; + if( v.z > z ) z = v.z; + } + + inline Vector3 perpendicular(void) + { + static float fSquareZero = 1e-06f * 1e-06f; + + Vector3 perp = this->crossProduct( Vector3::UNIT_X ); + + // Check length + if( perp.squaredLength() < fSquareZero ) + { + /* This vector is the Y axis multiplied by a scalar, so we have + to use another axis. + */ + perp = this->crossProduct( Vector3::UNIT_Y ); + } + + return perp; + } + + // special points + static const Vector3 ZERO; + static const Vector3 UNIT_X; + static const Vector3 UNIT_Y; + static const Vector3 UNIT_Z; + static const Vector3 UNIT_SCALE; }; #endif // _VECTOR3_H_ diff --git a/Tools/LightwaveConverter/include/lwClip.h b/Tools/LightwaveConverter/include/lwClip.h index 4e0f798301c..8f3ea99ea6f 100644 --- a/Tools/LightwaveConverter/include/lwClip.h +++ b/Tools/LightwaveConverter/include/lwClip.h @@ -4,153 +4,153 @@ class lwClipStill { public: - lwClipStill() - { - name = 0; - } - ~lwClipStill() - { - if (name) free(name); - } - char *name; + lwClipStill() + { + name = 0; + } + ~lwClipStill() + { + if (name) free(name); + } + char *name; }; class lwClipSeq { public: - lwClipSeq() - { - prefix = 0; - suffix = 0; - } - ~lwClipSeq() - { - if (prefix) free(prefix); - if (suffix) free(suffix); - } - char *prefix; /* filename before sequence digits */ - char *suffix; /* after digits, e.g. extensions */ - int digits; - int flags; - int offset; - int start; - int end; + lwClipSeq() + { + prefix = 0; + suffix = 0; + } + ~lwClipSeq() + { + if (prefix) free(prefix); + if (suffix) free(suffix); + } + char *prefix; /* filename before sequence digits */ + char *suffix; /* after digits, e.g. extensions */ + int digits; + int flags; + int offset; + int start; + int end; }; class lwClipAnim { public: - lwClipAnim() - { - name = 0; - server = 0; - data = 0; - } - ~lwClipAnim() - { - if (name) free(name); - if (server) free(server); - if (data) free(data); - } - char *name; - char *server; /* anim loader plug-in */ - void *data; + lwClipAnim() + { + name = 0; + server = 0; + data = 0; + } + ~lwClipAnim() + { + if (name) free(name); + if (server) free(server); + if (data) free(data); + } + char *name; + char *server; /* anim loader plug-in */ + void *data; }; class lwClipXRef { public: - lwClipXRef() - { - string = 0; - clip = 0; - } - ~lwClipXRef() - { - if (string) free(string); - } + lwClipXRef() + { + string = 0; + clip = 0; + } + ~lwClipXRef() + { + if (string) free(string); + } - char *string; - int index; - class lwClip *clip; + char *string; + int index; + class lwClip *clip; }; class lwClipCycle { public: - lwClipCycle() - { - name = 0; - } - ~lwClipCycle() - { - if (name) free(name); - } - char *name; - int lo; - int hi; + lwClipCycle() + { + name = 0; + } + ~lwClipCycle() + { + if (name) free(name); + } + char *name; + int lo; + int hi; }; class lwClip { public: - lwClip() - { - source.still = 0; - contrast.val = 1.0f; - brightness.val = 1.0f; - saturation.val = 1.0f; - gamma.val = 1.0f; - } - - ~lwClip() - { - unsigned int i; - for (i=0; i < ifilters.size(); delete ifilters[i++]); - for (i=0; i < pfilters.size(); delete pfilters[i++]); - - if (source.still) - { - switch (type) - { - case ID_STIL: - delete source.still; - break; - case ID_ISEQ: - delete source.seq; - break; - case ID_ANIM: - delete source.anim; - break; - case ID_XREF: - delete source.xref; - break; - case ID_STCC: - delete source.cycle; - break; - default: - ; - } - } - } - int index; - unsigned int type; /* ID_STIL, ID_ISEQ, etc. */ - union { - lwClipStill *still; - lwClipSeq *seq; - lwClipAnim *anim; - lwClipXRef *xref; - lwClipCycle *cycle; - } source; - float start_time; - float duration; - float frame_rate; - lwEParam contrast; - lwEParam brightness; - lwEParam saturation; - lwEParam hue; - lwEParam gamma; - int negative; - vplugins ifilters; /* linked list of image filters */ - vplugins pfilters; /* linked list of pixel filters */ + lwClip() + { + source.still = 0; + contrast.val = 1.0f; + brightness.val = 1.0f; + saturation.val = 1.0f; + gamma.val = 1.0f; + } + + ~lwClip() + { + unsigned int i; + for (i=0; i < ifilters.size(); delete ifilters[i++]); + for (i=0; i < pfilters.size(); delete pfilters[i++]); + + if (source.still) + { + switch (type) + { + case ID_STIL: + delete source.still; + break; + case ID_ISEQ: + delete source.seq; + break; + case ID_ANIM: + delete source.anim; + break; + case ID_XREF: + delete source.xref; + break; + case ID_STCC: + delete source.cycle; + break; + default: + ; + } + } + } + int index; + unsigned int type; /* ID_STIL, ID_ISEQ, etc. */ + union { + lwClipStill *still; + lwClipSeq *seq; + lwClipAnim *anim; + lwClipXRef *xref; + lwClipCycle *cycle; + } source; + float start_time; + float duration; + float frame_rate; + lwEParam contrast; + lwEParam brightness; + lwEParam saturation; + lwEParam hue; + lwEParam gamma; + int negative; + vplugins ifilters; /* linked list of image filters */ + vplugins pfilters; /* linked list of pixel filters */ }; typedef vector vclips; diff --git a/Tools/LightwaveConverter/include/lwEnvelope.h b/Tools/LightwaveConverter/include/lwEnvelope.h index 6d98dc499ad..b9462521189 100644 --- a/Tools/LightwaveConverter/include/lwEnvelope.h +++ b/Tools/LightwaveConverter/include/lwEnvelope.h @@ -8,21 +8,21 @@ class lwKey { public: - lwKey(float ntime, float nvalue) : time(ntime), value(nvalue) {} - float time; - float value; - unsigned int shape; /* ID_TCB, ID_BEZ2, etc. */ - float tension; - float continuity; - float bias; - float param[ 4 ]; + lwKey(float ntime, float nvalue) : time(ntime), value(nvalue) {} + float time; + float value; + unsigned int shape; /* ID_TCB, ID_BEZ2, etc. */ + float tension; + float continuity; + float bias; + float param[ 4 ]; }; typedef vector vkeys; inline bool operator < (const lwKey &k1, const lwKey &k2) { - return k1.time < k2.time; + return k1.time < k2.time; } #define BEH_RESET 0 @@ -34,38 +34,38 @@ inline bool operator < (const lwKey &k1, const lwKey &k2) class lwEnvelope { - float range( float v, float lo, float hi, int *i ); - void hermite( float t, float *h1, float *h2, float *h3, float *h4 ); - float bezier( float x0, float x1, float x2, float x3, float t ); - float bez2_time( float x0, float x1, float x2, float x3, float time, float *t0, float *t1 ); - float bez2( lwKey *key0, lwKey *key1, float time ); - float outgoing( unsigned int key0, unsigned int key1 ); - float incoming( unsigned int key0, unsigned int key1 ); - + float range( float v, float lo, float hi, int *i ); + void hermite( float t, float *h1, float *h2, float *h3, float *h4 ); + float bezier( float x0, float x1, float x2, float x3, float t ); + float bez2_time( float x0, float x1, float x2, float x3, float time, float *t0, float *t1 ); + float bez2( lwKey *key0, lwKey *key1, float time ); + float outgoing( unsigned int key0, unsigned int key1 ); + float incoming( unsigned int key0, unsigned int key1 ); + public: - lwEnvelope() - { - name = 0; - } + lwEnvelope() + { + name = 0; + } - ~lwEnvelope() - { - if (name) free(name); - unsigned int i; - for (i=0; i venvelopes; diff --git a/Tools/LightwaveConverter/include/lwLayer.h b/Tools/LightwaveConverter/include/lwLayer.h index 12acd0019a4..c79507735a2 100644 --- a/Tools/LightwaveConverter/include/lwLayer.h +++ b/Tools/LightwaveConverter/include/lwLayer.h @@ -6,44 +6,44 @@ class lwLayer { public: - lwLayer() - { - name = 0; - pointsoffset = 0; - polygonsoffset = 0; - } - - ~lwLayer() - { - if (name) free(name); - unsigned int i; - for (i=0; i < points.size(); delete points[i++]); - for (i=0; i < polygons.size(); delete polygons[i++]); - for (i=0; i < vmaps.size(); delete vmaps[i++]); - } + lwLayer() + { + name = 0; + pointsoffset = 0; + polygonsoffset = 0; + } + + ~lwLayer() + { + if (name) free(name); + unsigned int i; + for (i=0; i < points.size(); delete points[i++]); + for (i=0; i < polygons.size(); delete polygons[i++]); + for (i=0; i < vmaps.size(); delete vmaps[i++]); + } - void lwResolveVertexPoints(void); - void lwGetPointPolygons(void); - void calculatePolygonNormals(void); - void triangulatePolygons(void); - void lwGetPointVMaps(void); - void lwGetPolyVMaps(void); - void lwGetBoundingBox(void); - void calculateVertexNormals(void); - int lwResolvePolySurfaces( vsurfaces &surfaces, vtags &tags ); - - char *name; - int index; - int parent; - int flags; - Point3 pivot; - Point3 bboxmin; - Point3 bboxmax; - int pointsoffset; /* only used during reading */ - vpoints points; /* array of points */ - int polygonsoffset; /* only used during reading */ - vpolygons polygons; /* array of polygons */ - vvmaps vmaps; /* linked list of vmaps */ + void lwResolveVertexPoints(void); + void lwGetPointPolygons(void); + void calculatePolygonNormals(void); + void triangulatePolygons(void); + void lwGetPointVMaps(void); + void lwGetPolyVMaps(void); + void lwGetBoundingBox(void); + void calculateVertexNormals(void); + int lwResolvePolySurfaces( vsurfaces &surfaces, vtags &tags ); + + char *name; + int index; + int parent; + int flags; + Point3 pivot; + Point3 bboxmin; + Point3 bboxmax; + int pointsoffset; /* only used during reading */ + vpoints points; /* array of points */ + int polygonsoffset; /* only used during reading */ + vpolygons polygons; /* array of polygons */ + vvmaps vmaps; /* linked list of vmaps */ }; typedef vector vlayers; diff --git a/Tools/LightwaveConverter/include/lwObject.h b/Tools/LightwaveConverter/include/lwObject.h index 569c0cbb781..3a8a26d4d24 100644 --- a/Tools/LightwaveConverter/include/lwObject.h +++ b/Tools/LightwaveConverter/include/lwObject.h @@ -9,53 +9,53 @@ class lwObject { public: - lwObject() - { - tagsoffset = 0; - } + lwObject() + { + tagsoffset = 0; + } - ~lwObject() - { - unsigned int i; + ~lwObject() + { + unsigned int i; - for (i=0; i < layers.size(); delete layers[i++]); - for (i=0; i < envelopes.size(); delete envelopes[i++]); - for (i=0; i < clips.size(); delete clips[i++]); - for (i=0; i < surfaces.size(); i++) - { - lwSurface *s = surfaces[i]; - if(s) - { - for (unsigned int j = i+1; j < surfaces.size(); j++) - if (s == surfaces[j]) surfaces[j] = 0; - delete s; - } - } - for (i=0; i < tags.size(); free(tags[i++])); - } + for (i=0; i < layers.size(); delete layers[i++]); + for (i=0; i < envelopes.size(); delete envelopes[i++]); + for (i=0; i < clips.size(); delete clips[i++]); + for (i=0; i < surfaces.size(); i++) + { + lwSurface *s = surfaces[i]; + if(s) + { + for (unsigned int j = i+1; j < surfaces.size(); j++) + if (s == surfaces[j]) surfaces[j] = 0; + delete s; + } + } + for (i=0; i < tags.size(); free(tags[i++])); + } - lwClip *lwFindClip( int index ) - { - for (unsigned int i = 0; i < clips.size(); i++) - if (clips[i]->index == index) - return clips[i]; - return 0; - } + lwClip *lwFindClip( int index ) + { + for (unsigned int i = 0; i < clips.size(); i++) + if (clips[i]->index == index) + return clips[i]; + return 0; + } - lwEnvelope *lwFindEnvelope( int index ) - { - for (unsigned int i = 0; i < envelopes.size(); i++) - if (envelopes[i]->index == index) - return envelopes[i]; - return 0; - } + lwEnvelope *lwFindEnvelope( int index ) + { + for (unsigned int i = 0; i < envelopes.size(); i++) + if (envelopes[i]->index == index) + return envelopes[i]; + return 0; + } - vlayers layers; /* linked list of layers */ - venvelopes envelopes; /* linked list of envelopes */ - vclips clips; /* linked list of clips */ - vsurfaces surfaces; /* linked list of surfaces */ - int tagsoffset; - vtags tags; /* array of strings */ + vlayers layers; /* linked list of layers */ + venvelopes envelopes; /* linked list of envelopes */ + vclips clips; /* linked list of clips */ + vsurfaces surfaces; /* linked list of surfaces */ + int tagsoffset; + vtags tags; /* array of strings */ }; typedef vector vobjects; diff --git a/Tools/LightwaveConverter/include/lwPolygon.h b/Tools/LightwaveConverter/include/lwPolygon.h index e9e71e0323f..6eba9fd5f4e 100644 --- a/Tools/LightwaveConverter/include/lwPolygon.h +++ b/Tools/LightwaveConverter/include/lwPolygon.h @@ -5,40 +5,40 @@ class lwPolygon { public: - lwPolygon() - { - } + lwPolygon() + { + } - lwPolygon(const lwPolygon &p) - { - surface = p.surface; - surfidx = p.surfidx; - part = p.part; - smoothgrp = p.smoothgrp; - flags = p.flags; - type = p.type; - normal = p.normal; - } + lwPolygon(const lwPolygon &p) + { + surface = p.surface; + surfidx = p.surfidx; + part = p.part; + smoothgrp = p.smoothgrp; + flags = p.flags; + type = p.type; + normal = p.normal; + } - ~lwPolygon() - { - for (unsigned int i=0; i < vertices.size(); delete vertices[i++]); - } + ~lwPolygon() + { + for (unsigned int i=0; i < vertices.size(); delete vertices[i++]); + } - Vector3 &calculateNormal(void); - vpolygons triangulate(void); - void flip(void); + Vector3 &calculateNormal(void); + vpolygons triangulate(void); + void flip(void); private: - lwPolygon *makeTriangle(long ia, long ib, long ic); + lwPolygon *makeTriangle(long ia, long ib, long ic); public: - lwSurface *surface; - int surfidx; /* surface index */ - int part; /* part index */ - int smoothgrp; /* smoothing group */ - int flags; - unsigned int type; - Vector3 normal; - vvertices vertices; /* array of vertex records */ + lwSurface *surface; + int surfidx; /* surface index */ + int part; /* part index */ + int smoothgrp; /* smoothing group */ + int flags; + unsigned int type; + Vector3 normal; + vvertices vertices; /* array of vertex records */ }; #endif // _LWPOLYGON_H_ diff --git a/Tools/LightwaveConverter/include/lwReader.h b/Tools/LightwaveConverter/include/lwReader.h index 5ab744752b5..20695c644c2 100644 --- a/Tools/LightwaveConverter/include/lwReader.h +++ b/Tools/LightwaveConverter/include/lwReader.h @@ -9,64 +9,64 @@ class lwReader { public: - lwObject *readObjectFromFile( const char *nfilename); - lwObject *readObjectFromStream( istream *nis); + lwObject *readObjectFromFile( const char *nfilename); + lwObject *readObjectFromStream( istream *nis); private: - istream *is; - unsigned long chunksize; - unsigned long currentchunkid; - unsigned long formsize; - unsigned long flen; + istream *is; + unsigned long chunksize; + unsigned long currentchunkid; + unsigned long formsize; + unsigned long flen; - bool *flags; + bool *flags; - lwObject *lwGetLWLO(); - lwObject *lwGetLWO2(); + lwObject *lwGetLWLO(); + lwObject *lwGetLWO2(); - int lwGetPoints( vpoints &points ); - int lwGetPolygons( vpolygons &polygons, int ptoffset ); - int lwGetLWOBPolygons( vpolygons &polygons, int ptoffset ); - int lwGetTags( vtags &tags ); - int lwGetPolygonTags( vtags &tags, int tagsoffset, vpolygons &polygons, int polygonsoffset ); - lwVMap *lwGetVMap( int ptoffset, int poloffset, int perpoly ); - lwClip *lwGetClip(); - lwEnvelope *lwGetEnvelope(); - int lwGetTHeader( int hsz, lwTexture &tex ); - int lwGetTMap( int tmapsz, lwTMap &tmap ); - lwImageMap *lwGetImageMap( int rsz, lwTexture &tex ); - lwProcedural *lwGetProcedural( int rsz, lwTexture &tex ); - lwGradient *lwGetGradient( int rsz, lwTexture &tex ); - lwTexture *lwGetTexture( int bloksz, unsigned int type ); - lwPlugin *lwGetShader( int bloksz ); - lwSurface *lwGetSurface(); - lwSurface *lwGetLWOBSurface( lwObject *obj ); + int lwGetPoints( vpoints &points ); + int lwGetPolygons( vpolygons &polygons, int ptoffset ); + int lwGetLWOBPolygons( vpolygons &polygons, int ptoffset ); + int lwGetTags( vtags &tags ); + int lwGetPolygonTags( vtags &tags, int tagsoffset, vpolygons &polygons, int polygonsoffset ); + lwVMap *lwGetVMap( int ptoffset, int poloffset, int perpoly ); + lwClip *lwGetClip(); + lwEnvelope *lwGetEnvelope(); + int lwGetTHeader( int hsz, lwTexture &tex ); + int lwGetTMap( int tmapsz, lwTMap &tmap ); + lwImageMap *lwGetImageMap( int rsz, lwTexture &tex ); + lwProcedural *lwGetProcedural( int rsz, lwTexture &tex ); + lwGradient *lwGetGradient( int rsz, lwTexture &tex ); + lwTexture *lwGetTexture( int bloksz, unsigned int type ); + lwPlugin *lwGetShader( int bloksz ); + lwSurface *lwGetSurface(); + lwSurface *lwGetLWOBSurface( lwObject *obj ); - int add_clip( char *s, vclips &clips ); - int add_tvel( float pos[], float vel[], venvelopes &envelopes ); - lwTexture *get_texture( char *s ); + int add_clip( char *s, vclips &clips ); + int add_tvel( float pos[], float vel[], venvelopes &envelopes ); + lwTexture *get_texture( char *s ); - char *getbytes( int size ); - void skipbytes( int n ); - short getI2(); - long getI4(); - unsigned char getU1(); - unsigned short getU2(); - unsigned long getU4(); - int getVX(); - float getF4(); - char *getS0(); - short sgetI2( char **bp ); - long sgetI4( char **bp ); - unsigned char sgetU1( char **bp ); - unsigned short sgetU2( char **bp ); - unsigned long sgetU4( char **bp ); - int sgetVX( char **bp ); - float sgetF4( char **bp ); - char *sgetS0( char **bp ); + char *getbytes( int size ); + void skipbytes( int n ); + short getI2(); + long getI4(); + unsigned char getU1(); + unsigned short getU2(); + unsigned long getU4(); + int getVX(); + float getF4(); + char *getS0(); + short sgetI2( char **bp ); + long sgetI4( char **bp ); + unsigned char sgetU1( char **bp ); + unsigned short sgetU2( char **bp ); + unsigned long sgetU4( char **bp ); + int sgetVX( char **bp ); + float sgetF4( char **bp ); + char *sgetS0( char **bp ); - unsigned short swappedShort(unsigned short w); - unsigned long swappedLong(unsigned long w); - void revbytes( void *bp, int elsize, int elcount ); + unsigned short swappedShort(unsigned short w); + unsigned long swappedLong(unsigned long w); + void revbytes( void *bp, int elsize, int elcount ); }; #endif // _LWREADER_H_ diff --git a/Tools/LightwaveConverter/include/lwo.h b/Tools/LightwaveConverter/include/lwo.h index 94127fa6f42..dd481033211 100644 --- a/Tools/LightwaveConverter/include/lwo.h +++ b/Tools/LightwaveConverter/include/lwo.h @@ -210,55 +210,55 @@ Lightwave SDK. class lwPlugin { public: - lwPlugin() - { - ord = 0; - name = 0; - data = 0; - } - - ~lwPlugin() - { - if (ord) free(ord); - if (name) free(name); - if (data) free(data); - } - - char *ord; - char *name; - int flags; - void *data; + lwPlugin() + { + ord = 0; + name = 0; + data = 0; + } + + ~lwPlugin() + { + if (ord) free(ord); + if (name) free(name); + if (data) free(data); + } + + char *ord; + char *name; + int flags; + void *data; }; typedef vector vplugins; inline bool operator < (const lwPlugin &p1, const lwPlugin &p2 ) { - return strcmp( p1.ord, p2.ord ) < 0; + return strcmp( p1.ord, p2.ord ) < 0; } class lwEParam { public: - lwEParam() - { - val = 0.0f; - eindex = 0; - } - float val; - int eindex; + lwEParam() + { + val = 0.0f; + eindex = 0; + } + float val; + int eindex; }; class lwVParam { public: - lwVParam() - { - val[0] = val[1] = val[2] = 0.0f; - eindex = 0; - } - float val[ 3 ]; - int eindex; + lwVParam() + { + val[0] = val[1] = val[2] = 0.0f; + eindex = 0; + } + float val[ 3 ]; + int eindex; }; @@ -268,49 +268,49 @@ class lwVParam class lwTMap { public: - lwTMap() - { - ref_object = 0; - } - - ~lwTMap() - { - if (ref_object) free(ref_object); - } - lwVParam size; - lwVParam center; - lwVParam rotate; - lwVParam falloff; - int fall_type; - char *ref_object; - int coord_sys; + lwTMap() + { + ref_object = 0; + } + + ~lwTMap() + { + if (ref_object) free(ref_object); + } + lwVParam size; + lwVParam center; + lwVParam rotate; + lwVParam falloff; + int fall_type; + char *ref_object; + int coord_sys; }; class lwImageMap { public: - lwImageMap() - { - vmap_name = 0; - } - - ~lwImageMap() - { - if (vmap_name) free(vmap_name); - } - - int cindex; - int projection; - char *vmap_name; - int axis; - int wrapw_type; - int wraph_type; - lwEParam wrapw; - lwEParam wraph; - float aa_strength; - int aas_flags; - int pblend; - lwEParam stck; - lwEParam amplitude; + lwImageMap() + { + vmap_name = 0; + } + + ~lwImageMap() + { + if (vmap_name) free(vmap_name); + } + + int cindex; + int projection; + char *vmap_name; + int axis; + int wrapw_type; + int wraph_type; + lwEParam wrapw; + lwEParam wraph; + float aa_strength; + int aas_flags; + int pblend; + lwEParam stck; + lwEParam amplitude; }; #define PROJ_PLANAR 0 @@ -326,108 +326,108 @@ class lwImageMap { class lwProcedural { public: - lwProcedural() - { - name = 0; - data = 0; - } - - ~lwProcedural() - { - if (name) free(name); - if (data) free(data); - } - - int axis; - float value[ 3 ]; - char *name; - void *data; + lwProcedural() + { + name = 0; + data = 0; + } + + ~lwProcedural() + { + if (name) free(name); + if (data) free(data); + } + + int axis; + float value[ 3 ]; + char *name; + void *data; }; class lwGradKey { public: - float value; - float rgba[ 4 ]; + float value; + float rgba[ 4 ]; }; class lwGradient { public: - lwGradient() - { - paramname = 0; - itemname = 0; - key = 0; - ikey = 0; - } - - ~lwGradient() - { - if (paramname) free(paramname); - if (itemname) free(itemname); - if (key) free(key); - if (ikey) free(ikey); - } - - char *paramname; - char *itemname; - float start; - float end; - int repeat; - lwGradKey *key; /* array of gradient keys */ - short *ikey; /* array of interpolation codes */ + lwGradient() + { + paramname = 0; + itemname = 0; + key = 0; + ikey = 0; + } + + ~lwGradient() + { + if (paramname) free(paramname); + if (itemname) free(itemname); + if (key) free(key); + if (ikey) free(ikey); + } + + char *paramname; + char *itemname; + float start; + float end; + int repeat; + lwGradKey *key; /* array of gradient keys */ + short *ikey; /* array of interpolation codes */ } ; class lwTexture { public: - lwTexture() - { - ord = 0; - param.imap = 0; - - tmap.size.val[ 0 ] = - tmap.size.val[ 1 ] = - tmap.size.val[ 2 ] = 1.0f; - opacity.val = 1.0f; - enabled = 1; - } - - ~lwTexture() - { - if (ord) free(ord); - if(param.imap) - { - switch (type) - { - case ID_IMAP: - delete param.imap; - break; - case ID_PROC: - delete param.proc; - break; - case ID_GRAD: - delete param.grad; - break; - default: - ; - } - } - } - char *ord; - unsigned int type; - unsigned int chan; - lwEParam opacity; - short opac_type; - short enabled; - short negative; - short axis; - union - { - lwImageMap *imap; - lwProcedural *proc; - lwGradient *grad; - } param; - lwTMap tmap; + lwTexture() + { + ord = 0; + param.imap = 0; + + tmap.size.val[ 0 ] = + tmap.size.val[ 1 ] = + tmap.size.val[ 2 ] = 1.0f; + opacity.val = 1.0f; + enabled = 1; + } + + ~lwTexture() + { + if (ord) free(ord); + if(param.imap) + { + switch (type) + { + case ID_IMAP: + delete param.imap; + break; + case ID_PROC: + delete param.proc; + break; + case ID_GRAD: + delete param.grad; + break; + default: + ; + } + } + } + char *ord; + unsigned int type; + unsigned int chan; + lwEParam opacity; + short opac_type; + short enabled; + short negative; + short axis; + union + { + lwImageMap *imap; + lwProcedural *proc; + lwGradient *grad; + } param; + lwTMap tmap; }; typedef vector vtextures; @@ -437,51 +437,51 @@ typedef vector vtextures; class lwTParam { public: - lwTParam() - { - val = 0; - eindex = 0; - } - - ~lwTParam() - { - for (unsigned int i=0; i < textures.size(); delete textures[i++]); - } - - void addTexture( lwTexture *tex ) - { - textures.insert(lower_bound(textures.begin(), textures.end(), tex), tex); - } - - float val; - int eindex; - vtextures textures; /* linked list of texture layers */ + lwTParam() + { + val = 0; + eindex = 0; + } + + ~lwTParam() + { + for (unsigned int i=0; i < textures.size(); delete textures[i++]); + } + + void addTexture( lwTexture *tex ) + { + textures.insert(lower_bound(textures.begin(), textures.end(), tex), tex); + } + + float val; + int eindex; + vtextures textures; /* linked list of texture layers */ }; class lwCParam { public: - lwCParam() - { - rgb[0] = 0.78431f; - rgb[1] = 0.78431f; - rgb[2] = 0.78431f; - eindex = 0; - } - - ~lwCParam() - { - for (unsigned int i=0; i < textures.size(); delete textures[i++]); - } - - void addTexture( lwTexture *tex ) - { - textures.insert(lower_bound(textures.begin(), textures.end(), tex), tex); - } - - float rgb[ 3 ]; - int eindex; - vtextures textures; /* linked list of texture layers */ + lwCParam() + { + rgb[0] = 0.78431f; + rgb[1] = 0.78431f; + rgb[2] = 0.78431f; + eindex = 0; + } + + ~lwCParam() + { + for (unsigned int i=0; i < textures.size(); delete textures[i++]); + } + + void addTexture( lwTexture *tex ) + { + textures.insert(lower_bound(textures.begin(), textures.end(), tex), tex); + } + + float rgb[ 3 ]; + int eindex; + vtextures textures; /* linked list of texture layers */ }; @@ -490,138 +490,138 @@ class lwCParam class lwGlow { public: - short enabled; - short type; - lwEParam intensity; - lwEParam size; + short enabled; + short type; + lwEParam intensity; + lwEParam size; }; class lwRMap { public: - lwRMap() - { - options = 0; - cindex = 0; - seam_angle = 0.0f; - } - lwTParam val; - int options; - int cindex; - float seam_angle; + lwRMap() + { + options = 0; + cindex = 0; + seam_angle = 0.0f; + } + lwTParam val; + int options; + int cindex; + float seam_angle; }; class lwLine { public: - short enabled; - unsigned short flags; - lwEParam size; + short enabled; + unsigned short flags; + lwEParam size; }; class lwSurface { public: - lwSurface() - { - name = 0; - srcname = 0; - diffuse.val = 1.0f; - glossiness.val = 0.4f; - bump.val = 1.0f; - eta.val = 1.0f; - sideflags = 1; - } - - ~lwSurface() - { - if (name) free(name); - if (srcname) free(srcname); - for (unsigned int i=0; i < shaders.size(); delete shaders[i++]); - } - - int addTexture( lwTexture *tex ) - { - switch ( tex->chan ) - { - case ID_COLR: - color.addTexture(tex); - break; - case ID_LUMI: - luminosity.addTexture(tex); - break; - case ID_DIFF: - diffuse.addTexture(tex); - break; - case ID_SPEC: - specularity.addTexture(tex); - break; - case ID_GLOS: - glossiness.addTexture(tex); - break; - case ID_REFL: - reflection.val.addTexture(tex); - break; - case ID_TRAN: - transparency.val.addTexture(tex); - break; - case ID_RIND: - eta.addTexture(tex); - break; - case ID_TRNL: - translucency.addTexture(tex); - break; - case ID_BUMP: - bump.addTexture(tex); - break; - default: - return 0; - } - return 1; - } - - static lwSurface *lwDefaultSurface( void ) - { - return new lwSurface; - } - - char *setname(const char *newname) - { - unsigned int slength = strlen(newname); - - if (name && slength > strlen(name)) - { - free(name); - name = 0; - } - if (!name) name = (char *)malloc(slength+1); - - return strcpy(name, newname); - } - - char *name; - char *srcname; - lwCParam color; - lwTParam luminosity; - lwTParam diffuse; - lwTParam specularity; - lwTParam glossiness; - lwRMap reflection; - lwRMap transparency; - lwTParam eta; - lwTParam translucency; - lwTParam bump; - float smooth; - int sideflags; - float alpha; - int alpha_mode; - lwEParam color_hilite; - lwEParam color_filter; - lwEParam add_trans; - lwEParam dif_sharp; - lwEParam glow; - lwLine line; - vplugins shaders; /* linked list of shaders */ + lwSurface() + { + name = 0; + srcname = 0; + diffuse.val = 1.0f; + glossiness.val = 0.4f; + bump.val = 1.0f; + eta.val = 1.0f; + sideflags = 1; + } + + ~lwSurface() + { + if (name) free(name); + if (srcname) free(srcname); + for (unsigned int i=0; i < shaders.size(); delete shaders[i++]); + } + + int addTexture( lwTexture *tex ) + { + switch ( tex->chan ) + { + case ID_COLR: + color.addTexture(tex); + break; + case ID_LUMI: + luminosity.addTexture(tex); + break; + case ID_DIFF: + diffuse.addTexture(tex); + break; + case ID_SPEC: + specularity.addTexture(tex); + break; + case ID_GLOS: + glossiness.addTexture(tex); + break; + case ID_REFL: + reflection.val.addTexture(tex); + break; + case ID_TRAN: + transparency.val.addTexture(tex); + break; + case ID_RIND: + eta.addTexture(tex); + break; + case ID_TRNL: + translucency.addTexture(tex); + break; + case ID_BUMP: + bump.addTexture(tex); + break; + default: + return 0; + } + return 1; + } + + static lwSurface *lwDefaultSurface( void ) + { + return new lwSurface; + } + + char *setname(const char *newname) + { + unsigned int slength = strlen(newname); + + if (name && slength > strlen(name)) + { + free(name); + name = 0; + } + if (!name) name = (char *)malloc(slength+1); + + return strcpy(name, newname); + } + + char *name; + char *srcname; + lwCParam color; + lwTParam luminosity; + lwTParam diffuse; + lwTParam specularity; + lwTParam glossiness; + lwRMap reflection; + lwRMap transparency; + lwTParam eta; + lwTParam translucency; + lwTParam bump; + float smooth; + int sideflags; + float alpha; + int alpha_mode; + lwEParam color_hilite; + lwEParam color_filter; + lwEParam add_trans; + lwEParam dif_sharp; + lwEParam glow; + lwLine line; + vplugins shaders; /* linked list of shaders */ }; typedef vector vsurfaces; @@ -631,47 +631,47 @@ typedef vector vsurfaces; class lwVMap { public: - lwVMap() - { - name = 0; - vindex = 0; - pindex = 0; - val = 0; - } - - ~lwVMap() - { - if (name) free(name); - if (vindex) free(vindex); - if (pindex) free(pindex); - - if (val) - { - for (unsigned int i = 0; i < nverts; free(val[i++])); - free (val); - } - } - - char *name; - unsigned int type; - unsigned int dim; - unsigned int nverts; - int perpoly; - int *vindex; /* array of point indexes */ - int *pindex; /* array of polygon indexes */ - float **val; + lwVMap() + { + name = 0; + vindex = 0; + pindex = 0; + val = 0; + } + + ~lwVMap() + { + if (name) free(name); + if (vindex) free(vindex); + if (pindex) free(pindex); + + if (val) + { + for (unsigned int i = 0; i < nverts; free(val[i++])); + free (val); + } + } + + char *name; + unsigned int type; + unsigned int dim; + unsigned int nverts; + int perpoly; + int *vindex; /* array of point indexes */ + int *pindex; /* array of polygon indexes */ + float **val; }; typedef vector vvmaps; class lwVMapPt { - lwVMapPt(); + lwVMapPt(); public: - lwVMapPt(lwVMap *nvmap, int nindex) : vmap(nvmap), index(nindex) {}; + lwVMapPt(lwVMap *nvmap, int nindex) : vmap(nvmap), index(nindex) {}; - lwVMap *vmap; - int index; /* vindex or pindex element */ + lwVMap *vmap; + int index; /* vindex or pindex element */ }; typedef vector vvmapptrs; @@ -683,36 +683,36 @@ typedef vector vpolygons; class lwPoint: public Point3 { - lwPoint(); + lwPoint(); public: - lwPoint(float r, float s, float t) : Point3(r, s, t) {}; + lwPoint(float r, float s, float t) : Point3(r, s, t) {}; - vvmapptrs vmaps; /* array of vmap references */ - vpolygons polygons; /* array of polygon indexes */ - unsigned short index; + vvmapptrs vmaps; /* array of vmap references */ + vpolygons polygons; /* array of polygon indexes */ + unsigned short index; }; typedef vector vpoints; class lwVertex { - lwVertex(); + lwVertex(); public: - lwVertex(int nindex) : index(nindex) {} - - lwVertex(const lwVertex &v) - { - index = v.index; - point = v.point; - normal = v.normal; - vmaps = v.vmaps; - } - - int index; /* index into the point array */ - lwPoint *point; - Vector3 normal; - vvmapptrs vmaps; /* array of vmap references */ + lwVertex(int nindex) : index(nindex) {} + + lwVertex(const lwVertex &v) + { + index = v.index; + point = v.point; + normal = v.normal; + vmaps = v.vmaps; + } + + int index; /* index into the point array */ + lwPoint *point; + Vector3 normal; + vvmapptrs vmaps; /* array of vmap references */ }; typedef vector vvertices; @@ -721,7 +721,7 @@ typedef vector vtags; inline bool operator < (const lwTexture &t1, const lwTexture &t2 ) { - return strcmp( t1.ord, t2.ord ) < 0; + return strcmp( t1.ord, t2.ord ) < 0; } #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_WIN32 diff --git a/Tools/LightwaveConverter/include/lwo2mesh.h b/Tools/LightwaveConverter/include/lwo2mesh.h index 6303d33ea95..93ef375ed81 100644 --- a/Tools/LightwaveConverter/include/lwo2mesh.h +++ b/Tools/LightwaveConverter/include/lwo2mesh.h @@ -1,10 +1,10 @@ /* - Lwo2MeshWriter based on the MilkShape exporter - Dennis Verbeek (dennis.verbeek@chello.nl) + Lwo2MeshWriter based on the MilkShape exporter + Dennis Verbeek (dennis.verbeek@chello.nl) - Linux port by Magnus Møller Petersen (magnus@moaner.dk] + Linux port by Magnus Møller Petersen (magnus@moaner.dk] - doExportSkeleton is unfinished + doExportSkeleton is unfinished */ #ifndef _LWO2MESH_H_ @@ -28,7 +28,7 @@ // Function prototypes. void _splitpath( const char *_fn, char *_drive, char *_dir, char *_node, char *_ext ); void _makepath( char *_fn, const char *_drive, const char *_dir, const char *_node, - const char *_ext ); + const char *_ext ); #endif @@ -36,70 +36,70 @@ using namespace Ogre; enum Parameters { - InfoOnly, - PrintVMaps, - UseSharedVertexData, - UseSeparateLayers, - GenerateLOD, - GenerateEdgeLists, - GenerateTangents, - UseFixedMethod, - ExportMaterials, - RenameMaterials, - UseInteractiveMethod, - UseObjectMethod, - UsePrefixMethod, - ExportSkeleton, - HasNormals, - MakeNewSubMesh, - LinearCopy + InfoOnly, + PrintVMaps, + UseSharedVertexData, + UseSeparateLayers, + GenerateLOD, + GenerateEdgeLists, + GenerateTangents, + UseFixedMethod, + ExportMaterials, + RenameMaterials, + UseInteractiveMethod, + UseObjectMethod, + UsePrefixMethod, + ExportSkeleton, + HasNormals, + MakeNewSubMesh, + LinearCopy }; #define NUMFLAGS 17 class Lwo2MeshWriter { -public: - bool writeLwo2Mesh(lwObject *nobject, char *ndest); +public: + bool writeLwo2Mesh(lwObject *nobject, char *ndest); private: - void prepLwObject(void); - - void doExportMaterials(void); - - Skeleton *doExportSkeleton(const String &skelName, int layer); - - VertexData *setupVertexData(unsigned short vertexCount, VertexData *oldVertexData = 0, bool deleteOldVertexData = true); - void copyPoints(int surfaceIndex, unsigned long polygontype, vpoints &sourcepoints, vpoints &destpoints); - void copyPolygons(int surfaceIndex, unsigned long polygontype, vpolygons &sourcepolygons, vpolygons &destpolygons); - void copyDataToVertexData(vpoints &points, - vpolygons &polygons, - vvmaps &vmaps, - IndexData *indexData, - VertexData *vertexData, - unsigned short vertexDataOffset = 0); - - inline int getPointIndex(lwPoint *point, vpoints &points); - inline void getTextureVMaps(vtextures &textures, vvmaps &svmaps, vvmaps &dvmaps); - - inline String makeLayerFileName(char* dest, unsigned int l, char *layername); - inline String makeMaterialFileName(char* dest); - - char *dest; - lwObject *object; - MeshPtr ogreMesh; - - unsigned int nLayers; - unsigned int nSurfaces; - - unsigned int numPolygons; - unsigned int *numLayerPolygons; - unsigned int *numLayerSurfacePolygons; - unsigned int *numSurfacePolygons; - - unsigned int vertexCount; - unsigned int *numLayerVertices; - unsigned int *numLayerSurfaceVertices; - unsigned int *numSurfaceVertices; + void prepLwObject(void); + + void doExportMaterials(void); + + Skeleton *doExportSkeleton(const String &skelName, int layer); + + VertexData *setupVertexData(unsigned short vertexCount, VertexData *oldVertexData = 0, bool deleteOldVertexData = true); + void copyPoints(int surfaceIndex, unsigned long polygontype, vpoints &sourcepoints, vpoints &destpoints); + void copyPolygons(int surfaceIndex, unsigned long polygontype, vpolygons &sourcepolygons, vpolygons &destpolygons); + void copyDataToVertexData(vpoints &points, + vpolygons &polygons, + vvmaps &vmaps, + IndexData *indexData, + VertexData *vertexData, + unsigned short vertexDataOffset = 0); + + inline int getPointIndex(lwPoint *point, vpoints &points); + inline void getTextureVMaps(vtextures &textures, vvmaps &svmaps, vvmaps &dvmaps); + + inline String makeLayerFileName(char* dest, unsigned int l, char *layername); + inline String makeMaterialFileName(char* dest); + + char *dest; + lwObject *object; + MeshPtr ogreMesh; + + unsigned int nLayers; + unsigned int nSurfaces; + + unsigned int numPolygons; + unsigned int *numLayerPolygons; + unsigned int *numLayerSurfacePolygons; + unsigned int *numSurfacePolygons; + + unsigned int vertexCount; + unsigned int *numLayerVertices; + unsigned int *numLayerSurfaceVertices; + unsigned int *numSurfaceVertices; }; #endif // _LWO2MESH_H_ diff --git a/Tools/LightwaveConverter/src/BitArray.cpp b/Tools/LightwaveConverter/src/BitArray.cpp index fb963766dc6..3bf7cdbbf65 100644 --- a/Tools/LightwaveConverter/src/BitArray.cpp +++ b/Tools/LightwaveConverter/src/BitArray.cpp @@ -2,113 +2,113 @@ BitArray::BitArray(unsigned long newsize) { - arraysize = newsize; - bitlongs = ((arraysize - 1) >> 5) + 1; - bits = new unsigned long[bitlongs]; + arraysize = newsize; + bitlongs = ((arraysize - 1) >> 5) + 1; + bits = new unsigned long[bitlongs]; } BitArray::BitArray(const BitArray& b) { - arraysize = b.arraysize; - bitlongs = b.bitlongs; - bits = new unsigned long[bitlongs]; - for (unsigned long i = 0; i < bitlongs; i++) - bits[i] = b.bits[i]; + arraysize = b.arraysize; + bitlongs = b.bitlongs; + bits = new unsigned long[bitlongs]; + for (unsigned long i = 0; i < bitlongs; i++) + bits[i] = b.bits[i]; } BitArray::BitArray(unsigned long newsize, bool bitvalues) { - arraysize = newsize; - bitlongs = ((arraysize - 1) >> 5) + 1; - bits = new unsigned long[bitlongs]; + arraysize = newsize; + bitlongs = ((arraysize - 1) >> 5) + 1; + bits = new unsigned long[bitlongs]; if (bitvalues) set(); else clear(); } BitArray::BitArray(unsigned long newsize, unsigned long *newbits) { - arraysize = newsize; - bitlongs = ((arraysize - 1) >> 5) + 1; - bits = new unsigned long[bitlongs]; - for (unsigned long i = 0; i < bitlongs; i++) - bits[i] = newbits[i]; + arraysize = newsize; + bitlongs = ((arraysize - 1) >> 5) + 1; + bits = new unsigned long[bitlongs]; + for (unsigned long i = 0; i < bitlongs; i++) + bits[i] = newbits[i]; } BitArray::~BitArray() { - delete []bits; + delete []bits; } BitArray& BitArray::operator =(const BitArray& b) { - bool equalsize = arraysize == b.arraysize; - - arraysize = b.arraysize; - bitlongs = b.bitlongs; - - if (!equalsize) { - delete []bits; - bits = new unsigned long[bitlongs]; - } - for (unsigned long i = 0; i < bitlongs; i++) - bits[i] = b.bits[i]; - - return (*this); + bool equalsize = arraysize == b.arraysize; + + arraysize = b.arraysize; + bitlongs = b.bitlongs; + + if (!equalsize) { + delete []bits; + bits = new unsigned long[bitlongs]; + } + for (unsigned long i = 0; i < bitlongs; i++) + bits[i] = b.bits[i]; + + return (*this); } BitArray BitArray::operator ~(void) { - BitArray result(arraysize); - - for (unsigned long i = 0; i < bitlongs; i++) - result.bits[i] = ~bits[i]; - - return (result); + BitArray result(arraysize); + + for (unsigned long i = 0; i < bitlongs; i++) + result.bits[i] = ~bits[i]; + + return (result); } BitArray& BitArray::operator ^=(const BitArray& b) { - for (unsigned long i = 0; i < ((bitlongs < b.bitlongs) ? bitlongs : b.bitlongs); i++) - bits[i] ^= b.bits[i]; - return (*this); + for (unsigned long i = 0; i < ((bitlongs < b.bitlongs) ? bitlongs : b.bitlongs); i++) + bits[i] ^= b.bits[i]; + return (*this); } BitArray& BitArray::operator &=(const BitArray& b) { - for (unsigned long i = 0; i < ((bitlongs < b.bitlongs) ? bitlongs : b.bitlongs); i++) - bits[i] &= b.bits[i]; - return (*this); + for (unsigned long i = 0; i < ((bitlongs < b.bitlongs) ? bitlongs : b.bitlongs); i++) + bits[i] &= b.bits[i]; + return (*this); } BitArray& BitArray::operator |=(const BitArray& b) { - for (unsigned long i = 0; i < (bitlongs < b.bitlongs ? bitlongs : b.bitlongs); i++) - bits[i] |= b.bits[i]; - return (*this); + for (unsigned long i = 0; i < (bitlongs < b.bitlongs ? bitlongs : b.bitlongs); i++) + bits[i] |= b.bits[i]; + return (*this); } BitArray BitArray::operator ^(const BitArray& b) { - BitArray result((arraysize < b.arraysize) ? arraysize : b.arraysize); - - for (unsigned long i = 0; i < result.bitlongs; i++) - result.bits[i] = bits[i] ^ b.bits[i]; - return (result); + BitArray result((arraysize < b.arraysize) ? arraysize : b.arraysize); + + for (unsigned long i = 0; i < result.bitlongs; i++) + result.bits[i] = bits[i] ^ b.bits[i]; + return (result); } BitArray BitArray::operator &(const BitArray& b) { - BitArray result((arraysize < b.arraysize) ? arraysize : b.arraysize); - - for (unsigned long i = 0; i < result.bitlongs; i++) - result.bits[i] = bits[i] & b.bits[i]; - return (result); + BitArray result((arraysize < b.arraysize) ? arraysize : b.arraysize); + + for (unsigned long i = 0; i < result.bitlongs; i++) + result.bits[i] = bits[i] & b.bits[i]; + return (result); } BitArray BitArray::operator |(const BitArray& b) { - BitArray result((arraysize < b.arraysize) ? arraysize : b.arraysize); - - for (unsigned long i = 0; i < result.bitlongs; i++) - result.bits[i] = bits[i] | b.bits[i]; - return (result); + BitArray result((arraysize < b.arraysize) ? arraysize : b.arraysize); + + for (unsigned long i = 0; i < result.bitlongs; i++) + result.bits[i] = bits[i] | b.bits[i]; + return (result); } diff --git a/Tools/LightwaveConverter/src/lwEnvelope.cpp b/Tools/LightwaveConverter/src/lwEnvelope.cpp index de47584b912..0af21b9060d 100644 --- a/Tools/LightwaveConverter/src/lwEnvelope.cpp +++ b/Tools/LightwaveConverter/src/lwEnvelope.cpp @@ -2,9 +2,9 @@ lwKey *lwEnvelope::addKey( float time, float value ) { - lwKey *key = new lwKey(time, value); - keys.insert(lower_bound(keys.begin(), keys.end(), key), key); - return key; + lwKey *key = new lwKey(time, value); + keys.insert(lower_bound(keys.begin(), keys.end(), key), key); + return key; } /*====================================================================== @@ -13,25 +13,25 @@ range() Given the value v of a periodic function, returns the equivalent value v2 in the principal interval [lo, hi]. If i isn't NULL, it receives the number of wavelengths between v and v2. - + v2 = v - i * (hi - lo) - + For example, range( 3 pi, 0, 2 pi, i ) returns pi, with i = 1. ====================================================================== */ float lwEnvelope::range( float v, float lo, float hi, int *i ) { - float v2, r = hi - lo; - - if ( r == 0.0 ) { - if ( i ) *i = 0; - return lo; - } - - v2 = lo + v - r * ( float ) floor(( double ) v / r ); - if ( i ) *i = -( int )(( v2 - v ) / r + ( v2 > v ? 0.5 : -0.5 )); - - return v2; + float v2, r = hi - lo; + + if ( r == 0.0 ) { + if ( i ) *i = 0; + return lo; + } + + v2 = lo + v - r * ( float ) floor(( double ) v / r ); + if ( i ) *i = -( int )(( v2 - v ) / r + ( v2 > v ? 0.5 : -0.5 )); + + return v2; } /*====================================================================== @@ -42,15 +42,15 @@ Calculate the Hermite coefficients. void lwEnvelope::hermite( float t, float *h1, float *h2, float *h3, float *h4 ) { - float t2, t3; - - t2 = t * t; - t3 = t * t2; - - *h2 = 3.0f * t2 - t3 - t3; - *h1 = 1.0f - *h2; - *h4 = t3 - t2; - *h3 = *h4 - t2 + t; + float t2, t3; + + t2 = t * t; + t3 = t * t2; + + *h2 = 3.0f * t2 - t3 - t3; + *h1 = 1.0f - *h2; + *h4 = t3 - t2; + *h3 = *h4 - t2 + t; } /*====================================================================== @@ -61,16 +61,16 @@ Interpolate the value of a 1D Bezier curve. float lwEnvelope::bezier( float x0, float x1, float x2, float x3, float t ) { - float a, b, c, t2, t3; - - t2 = t * t; - t3 = t2 * t; - - c = 3.0f * ( x1 - x0 ); - b = 3.0f * ( x2 - x1 ) - c; - a = x3 - x0 - c - b; - - return a * t3 + b * t2 + c * t + x0; + float a, b, c, t2, t3; + + t2 = t * t; + t3 = t2 * t; + + c = 3.0f * ( x1 - x0 ); + b = 3.0f * ( x2 - x1 ) - c; + a = x3 - x0 - c - b; + + return a * t3 + b * t2 + c * t + x0; } @@ -83,21 +83,21 @@ endpoints of a BEZ2 curve represent the control points, and these have parameter for this curve type. ====================================================================== */ -float lwEnvelope::bez2_time( float x0, float x1, float x2, float x3, float time, float *t0, float *t1 ) +float lwEnvelope::bez2_time( float x0, float x1, float x2, float x3, float time, float *t0, float *t1 ) { - float v, t; - - t = *t0 + ( *t1 - *t0 ) * 0.5f; - v = bezier( x0, x1, x2, x3, t ); - if ( fabs( time - v ) > .0001f ) { - if ( v > time ) - *t1 = t; - else - *t0 = t; - return bez2_time( x0, x1, x2, x3, time, t0, t1 ); - } - else - return t; + float v, t; + + t = *t0 + ( *t1 - *t0 ) * 0.5f; + v = bezier( x0, x1, x2, x3, t ); + if ( fabs( time - v ) > .0001f ) { + if ( v > time ) + *t1 = t; + else + *t0 = t; + return bez2_time( x0, x1, x2, x3, time, t0, t1 ); + } + else + return t; } @@ -105,27 +105,27 @@ float lwEnvelope::bez2_time( float x0, float x1, float x2, float x3, float time, ====================================================================== bez2() - Interpolate the value of a BEZ2 curve. + Interpolate the value of a BEZ2 curve. ====================================================================== */ float lwEnvelope::bez2( lwKey *key0, lwKey *key1, float time ) { - float x, y, t, t0 = 0.0f, t1 = 1.0f; - - if ( key0->shape == ID_BEZ2 ) - x = key0->time + key0->param[ 2 ]; - else - x = key0->time + ( key1->time - key0->time ) / 3.0f; - - t = bez2_time( key0->time, x, key1->time + key1->param[ 0 ], key1->time, - time, &t0, &t1 ); - - if ( key0->shape == ID_BEZ2 ) - y = key0->value + key0->param[ 3 ]; - else - y = key0->value + key0->param[ 1 ] / 3.0f; - - return bezier( key0->value, y, key1->param[ 1 ] + key1->value, key1->value, t ); + float x, y, t, t0 = 0.0f, t1 = 1.0f; + + if ( key0->shape == ID_BEZ2 ) + x = key0->time + key0->param[ 2 ]; + else + x = key0->time + ( key1->time - key0->time ) / 3.0f; + + t = bez2_time( key0->time, x, key1->time + key1->param[ 0 ], key1->time, + time, &t0, &t1 ); + + if ( key0->shape == ID_BEZ2 ) + y = key0->value + key0->param[ 3 ]; + else + y = key0->value + key0->param[ 1 ] / 3.0f; + + return bezier( key0->value, y, key1->param[ 1 ] + key1->value, key1->value, t ); } @@ -133,71 +133,71 @@ float lwEnvelope::bez2( lwKey *key0, lwKey *key1, float time ) ====================================================================== outgoing() - Return the outgoing tangent to the curve at key0. The value returned - for the BEZ2 case is used when extrapolating a linear pre behavior and - when interpolating a non-BEZ2 span. + Return the outgoing tangent to the curve at key0. The value returned + for the BEZ2 case is used when extrapolating a linear pre behavior and + when interpolating a non-BEZ2 span. ====================================================================== */ float lwEnvelope::outgoing( unsigned int key0, unsigned int key1 ) { - float a, b, d, t, tout; - - switch ( keys[key0]->shape ) - { - case ID_TCB: - a = ( 1.0f - keys[key0]->tension ) - * ( 1.0f + keys[key0]->continuity ) - * ( 1.0f + keys[key0]->bias ); - b = ( 1.0f - keys[key0]->tension ) - * ( 1.0f - keys[key0]->continuity ) - * ( 1.0f - keys[key0]->bias ); - d = keys[key1]->value - keys[key0]->value; - - - if ( key0 > 0 ) - { - t = ( keys[key1]->time - keys[key0]->time ) / ( keys[key1]->time - keys[ key0-1 ]->time ); - tout = t * ( a * ( keys[key0]->value - keys[ key0-1 ]->value ) + b * d ); - } - else - tout = b * d; - break; - - case ID_LINE: - d = keys[key1]->value - keys[key0]->value; - if ( key0 > 0 ) - { - t = ( keys[key1]->time - keys[key0]->time ) / ( keys[key1]->time - keys[ key0-1 ]->time ); - tout = t * ( keys[key0]->value - keys[ key0-1 ]->value + d ); - } - else - tout = d; - break; - - case ID_BEZI: - case ID_HERM: - tout = keys[key0]->param[ 1 ]; - - if ( key0 > 0 ) - tout *= ( keys[key1]->time - keys[key0]->time ) / ( keys[key1]->time - keys[ key0-1 ]->time ); - - break; - - case ID_BEZ2: - tout = keys[key0]->param[ 3 ] * ( keys[key1]->time - keys[key0]->time ); - if ( fabs( keys[key0]->param[ 2 ] ) > 1e-5f ) - tout /= keys[key0]->param[ 2 ]; - else - tout *= 1e5f; - break; - - case ID_STEP: - default: - tout = 0.0f; - break; - } - - return tout; + float a, b, d, t, tout; + + switch ( keys[key0]->shape ) + { + case ID_TCB: + a = ( 1.0f - keys[key0]->tension ) + * ( 1.0f + keys[key0]->continuity ) + * ( 1.0f + keys[key0]->bias ); + b = ( 1.0f - keys[key0]->tension ) + * ( 1.0f - keys[key0]->continuity ) + * ( 1.0f - keys[key0]->bias ); + d = keys[key1]->value - keys[key0]->value; + + + if ( key0 > 0 ) + { + t = ( keys[key1]->time - keys[key0]->time ) / ( keys[key1]->time - keys[ key0-1 ]->time ); + tout = t * ( a * ( keys[key0]->value - keys[ key0-1 ]->value ) + b * d ); + } + else + tout = b * d; + break; + + case ID_LINE: + d = keys[key1]->value - keys[key0]->value; + if ( key0 > 0 ) + { + t = ( keys[key1]->time - keys[key0]->time ) / ( keys[key1]->time - keys[ key0-1 ]->time ); + tout = t * ( keys[key0]->value - keys[ key0-1 ]->value + d ); + } + else + tout = d; + break; + + case ID_BEZI: + case ID_HERM: + tout = keys[key0]->param[ 1 ]; + + if ( key0 > 0 ) + tout *= ( keys[key1]->time - keys[key0]->time ) / ( keys[key1]->time - keys[ key0-1 ]->time ); + + break; + + case ID_BEZ2: + tout = keys[key0]->param[ 3 ] * ( keys[key1]->time - keys[key0]->time ); + if ( fabs( keys[key0]->param[ 2 ] ) > 1e-5f ) + tout /= keys[key0]->param[ 2 ]; + else + tout *= 1e5f; + break; + + case ID_STEP: + default: + tout = 0.0f; + break; + } + + return tout; } @@ -210,62 +210,62 @@ for the BEZ2 case is used when extrapolating a linear post behavior. float lwEnvelope::incoming( unsigned int key0, unsigned int key1 ) { - float a, b, d, t, tin; - - switch ( keys[key1]->shape ) - { - case ID_LINE: - d = keys[key1]->value - keys[key0]->value; - - if ( key1 < keys.size()-1 ) - { - t = ( keys[key1]->time - keys[key0]->time ) / ( keys[ key1+1 ]->time - keys[key0]->time ); - tin = t * ( keys[ key1+1 ]->value - keys[key1]->value + d ); - } - else - tin = d; - - break; - - case ID_TCB: - a = ( 1.0f - keys[key1]->tension ) - * ( 1.0f - keys[key1]->continuity ) - * ( 1.0f + keys[key1]->bias ); - b = ( 1.0f - keys[key1]->tension ) - * ( 1.0f + keys[key1]->continuity ) - * ( 1.0f - keys[key1]->bias ); - d = keys[key1]->value - keys[key0]->value; - if ( key1 < keys.size()-1 ) { - t = ( keys[key1]->time - keys[key0]->time ) / ( keys[ key1+1 ]->time - keys[key0]->time ); - tin = t * ( b * ( keys[ key1+1 ]->value - keys[key1]->value ) + a * d ); - } - else - tin = a * d; - break; - - case ID_BEZI: - case ID_HERM: - tin = keys[key1]->param[ 0 ]; - if ( key1 < keys.size()-1 ) - tin *= ( keys[key1]->time - keys[key0]->time ) / ( keys[ key1+1 ]->time - keys[key0]->time ); - break; - return tin; - - case ID_BEZ2: - tin = keys[key1]->param[ 1 ] * ( keys[key1]->time - keys[key0]->time ); - if ( fabs( keys[key1]->param[ 0 ] ) > 1e-5f ) - tin /= keys[key1]->param[ 0 ]; - else - tin *= 1e5f; - break; - - case ID_STEP: - default: - tin = 0.0f; - break; - } - - return tin; + float a, b, d, t, tin; + + switch ( keys[key1]->shape ) + { + case ID_LINE: + d = keys[key1]->value - keys[key0]->value; + + if ( key1 < keys.size()-1 ) + { + t = ( keys[key1]->time - keys[key0]->time ) / ( keys[ key1+1 ]->time - keys[key0]->time ); + tin = t * ( keys[ key1+1 ]->value - keys[key1]->value + d ); + } + else + tin = d; + + break; + + case ID_TCB: + a = ( 1.0f - keys[key1]->tension ) + * ( 1.0f - keys[key1]->continuity ) + * ( 1.0f + keys[key1]->bias ); + b = ( 1.0f - keys[key1]->tension ) + * ( 1.0f + keys[key1]->continuity ) + * ( 1.0f - keys[key1]->bias ); + d = keys[key1]->value - keys[key0]->value; + if ( key1 < keys.size()-1 ) { + t = ( keys[key1]->time - keys[key0]->time ) / ( keys[ key1+1 ]->time - keys[key0]->time ); + tin = t * ( b * ( keys[ key1+1 ]->value - keys[key1]->value ) + a * d ); + } + else + tin = a * d; + break; + + case ID_BEZI: + case ID_HERM: + tin = keys[key1]->param[ 0 ]; + if ( key1 < keys.size()-1 ) + tin *= ( keys[key1]->time - keys[key0]->time ) / ( keys[ key1+1 ]->time - keys[key0]->time ); + break; + return tin; + + case ID_BEZ2: + tin = keys[key1]->param[ 1 ] * ( keys[key1]->time - keys[key0]->time ); + if ( fabs( keys[key1]->param[ 0 ] ) > 1e-5f ) + tin /= keys[key1]->param[ 0 ]; + else + tin *= 1e5f; + break; + + case ID_STEP: + default: + tin = 0.0f; + break; + } + + return tin; } /*====================================================================== @@ -277,133 +277,133 @@ envelope at that time. float lwEnvelope::evaluate( float time ) { - lwKey *key0, *key1, *skey, *ekey; - float t, h1, h2, h3, h4, tin, tout, offset = 0.0f; - int noff; - int key0index, key1index; - - - /* if there's no key, the value is 0 */ - - if ( keys.size() == 0 ) return 0.0f; - - /* if there's only one key, the value is constant */ - - if ( keys.size() == 1 ) return keys[0]->value; - - /* find the first and last keys */ - - key0index = 0; - key1index = keys.size()-1; - skey = keys[key0index]; - ekey = keys[key1index]; - - /* use pre-behavior if time is before first key time */ - - if ( time < skey->time ) - { - switch ( behavior[ 0 ] ) - { - case BEH_RESET: - return 0.0f; - - case BEH_CONSTANT: - return skey->value; - - case BEH_REPEAT: - time = range( time, skey->time, ekey->time, NULL ); - break; - - case BEH_OSCILLATE: - time = range( time, skey->time, ekey->time, &noff ); - if ( noff % 2 ) - time = ekey->time - skey->time - time; - break; - - case BEH_OFFSET: - time = range( time, skey->time, ekey->time, &noff ); - offset = noff * ( ekey->value - skey->value ); - break; - - case BEH_LINEAR: - tout = outgoing( key0index, key0index+1 ) / ( keys[key0index+1]->time - keys[key0index]->time ); + lwKey *key0, *key1, *skey, *ekey; + float t, h1, h2, h3, h4, tin, tout, offset = 0.0f; + int noff; + int key0index, key1index; + + + /* if there's no key, the value is 0 */ + + if ( keys.size() == 0 ) return 0.0f; + + /* if there's only one key, the value is constant */ + + if ( keys.size() == 1 ) return keys[0]->value; + + /* find the first and last keys */ + + key0index = 0; + key1index = keys.size()-1; + skey = keys[key0index]; + ekey = keys[key1index]; + + /* use pre-behavior if time is before first key time */ + + if ( time < skey->time ) + { + switch ( behavior[ 0 ] ) + { + case BEH_RESET: + return 0.0f; + + case BEH_CONSTANT: + return skey->value; + + case BEH_REPEAT: + time = range( time, skey->time, ekey->time, NULL ); + break; + + case BEH_OSCILLATE: + time = range( time, skey->time, ekey->time, &noff ); + if ( noff % 2 ) + time = ekey->time - skey->time - time; + break; + + case BEH_OFFSET: + time = range( time, skey->time, ekey->time, &noff ); + offset = noff * ( ekey->value - skey->value ); + break; + + case BEH_LINEAR: + tout = outgoing( key0index, key0index+1 ) / ( keys[key0index+1]->time - keys[key0index]->time ); - return tout * ( time - skey->time ) + skey->value; - } - } - - /* use post-behavior if time is after last key time */ - - else if ( time > ekey->time ) { - switch ( behavior[ 1 ] ) - { - case BEH_RESET: - return 0.0f; - - case BEH_CONSTANT: - return ekey->value; - - case BEH_REPEAT: - time = range( time, skey->time, ekey->time, NULL ); - break; - - case BEH_OSCILLATE: - time = range( time, skey->time, ekey->time, &noff ); - if ( noff % 2 ) - time = ekey->time - skey->time - time; - break; - - case BEH_OFFSET: - time = range( time, skey->time, ekey->time, &noff ); - offset = noff * ( ekey->value - skey->value ); - break; - - case BEH_LINEAR: - tin = incoming( key1index-1, key1index ) / ( ekey->time - keys[key1index-1]->time ); - return tin * ( time - ekey->time ) + ekey->value; - } - } - - /* get the endpoints of the interval being evaluated */ - - key0index = keys.size()-2; - key1index = keys.size()-1; - key0 = keys[key0index]; - key1 = keys[key1index]; - - /* check for singularities first */ - - if ( time == key0->time ) - return key0->value + offset; - else if ( time == key1->time ) - return key1->value + offset; - - /* get interval length, time in [0, 1] */ - - t = ( time - key0->time ) / ( key1->time - key0->time ); - - /* interpolate */ - - switch ( key1->shape ) - { - case ID_TCB: - case ID_BEZI: - case ID_HERM: - tout = outgoing( key0index, key1index ); - tin = incoming( key0index, key1index ); - hermite( t, &h1, &h2, &h3, &h4 ); - return h1 * key0->value + h2 * key1->value + h3 * tout + h4 * tin + offset; - - case ID_BEZ2: - return bez2( key0, key1, time ) + offset; - - case ID_LINE: - return key0->value + t * ( key1->value - key0->value ) + offset; - - case ID_STEP: - return key0->value + offset; - - default: - return offset; - } + return tout * ( time - skey->time ) + skey->value; + } + } + + /* use post-behavior if time is after last key time */ + + else if ( time > ekey->time ) { + switch ( behavior[ 1 ] ) + { + case BEH_RESET: + return 0.0f; + + case BEH_CONSTANT: + return ekey->value; + + case BEH_REPEAT: + time = range( time, skey->time, ekey->time, NULL ); + break; + + case BEH_OSCILLATE: + time = range( time, skey->time, ekey->time, &noff ); + if ( noff % 2 ) + time = ekey->time - skey->time - time; + break; + + case BEH_OFFSET: + time = range( time, skey->time, ekey->time, &noff ); + offset = noff * ( ekey->value - skey->value ); + break; + + case BEH_LINEAR: + tin = incoming( key1index-1, key1index ) / ( ekey->time - keys[key1index-1]->time ); + return tin * ( time - ekey->time ) + ekey->value; + } + } + + /* get the endpoints of the interval being evaluated */ + + key0index = keys.size()-2; + key1index = keys.size()-1; + key0 = keys[key0index]; + key1 = keys[key1index]; + + /* check for singularities first */ + + if ( time == key0->time ) + return key0->value + offset; + else if ( time == key1->time ) + return key1->value + offset; + + /* get interval length, time in [0, 1] */ + + t = ( time - key0->time ) / ( key1->time - key0->time ); + + /* interpolate */ + + switch ( key1->shape ) + { + case ID_TCB: + case ID_BEZI: + case ID_HERM: + tout = outgoing( key0index, key1index ); + tin = incoming( key0index, key1index ); + hermite( t, &h1, &h2, &h3, &h4 ); + return h1 * key0->value + h2 * key1->value + h3 * tout + h4 * tin + offset; + + case ID_BEZ2: + return bez2( key0, key1, time ) + offset; + + case ID_LINE: + return key0->value + t * ( key1->value - key0->value ) + offset; + + case ID_STEP: + return key0->value + offset; + + default: + return offset; + } } diff --git a/Tools/LightwaveConverter/src/lwLayer.cpp b/Tools/LightwaveConverter/src/lwLayer.cpp index 65e090306ed..c8413311f6e 100644 --- a/Tools/LightwaveConverter/src/lwLayer.cpp +++ b/Tools/LightwaveConverter/src/lwLayer.cpp @@ -10,17 +10,17 @@ lwResolveVertexPoints() void lwLayer::lwResolveVertexPoints(void) { - unsigned int i, j; - - for ( i = 0; i < polygons.size(); i++ ) - { - lwPolygon *polygon = polygons[ i ]; - for ( j = 0; j < polygon->vertices.size(); j++ ) - { - lwVertex *vertex = polygon->vertices[ j ]; - vertex->point = points[ vertex->index ]; - } - } + unsigned int i, j; + + for ( i = 0; i < polygons.size(); i++ ) + { + lwPolygon *polygon = polygons[ i ]; + for ( j = 0; j < polygon->vertices.size(); j++ ) + { + lwVertex *vertex = polygon->vertices[ j ]; + vertex->point = points[ vertex->index ]; + } + } } /*====================================================================== @@ -31,14 +31,14 @@ For each point, fill in the indexes of the polygons that share the point. void lwLayer::lwGetPointPolygons(void) { - unsigned int i, j; - - for ( i = 0; i < polygons.size(); i++ ) - { - lwPolygon *polygon = polygons[ i ]; - for ( j = 0; j < polygon->vertices.size(); j++ ) - polygon->vertices[ j ]->point->polygons.push_back(polygon); - } + unsigned int i, j; + + for ( i = 0; i < polygons.size(); i++ ) + { + lwPolygon *polygon = polygons[ i ]; + for ( j = 0; j < polygon->vertices.size(); j++ ) + polygon->vertices[ j ]->point->polygons.push_back(polygon); + } } /* @@ -52,37 +52,37 @@ calculatePolygonNormals() void lwLayer::calculatePolygonNormals(void) { - for (unsigned int i = 0; i < polygons.size(); polygons[i++]->calculateNormal()); + for (unsigned int i = 0; i < polygons.size(); polygons[i++]->calculateNormal()); } void lwLayer::triangulatePolygons(void) { - vpolygons newpolygons; - vpolygons newtriangles; - - unsigned int i, j; - - for (i = 0; i < polygons.size(); i++) - { - lwPolygon *polygon = polygons[i]; - - if (polygon->vertices.size() > 3) // needs triangulation ! - { - newtriangles = polygon->triangulate(); - delete polygon; - - for (j = 0; j < newtriangles.size(); j++) - { - polygon = newtriangles[j]; - polygon->calculateNormal(); - newpolygons.push_back(polygon); - } - } - else - newpolygons.push_back(polygon); - } - - polygons = newpolygons; + vpolygons newpolygons; + vpolygons newtriangles; + + unsigned int i, j; + + for (i = 0; i < polygons.size(); i++) + { + lwPolygon *polygon = polygons[i]; + + if (polygon->vertices.size() > 3) // needs triangulation ! + { + newtriangles = polygon->triangulate(); + delete polygon; + + for (j = 0; j < newtriangles.size(); j++) + { + polygon = newtriangles[j]; + polygon->calculateNormal(); + newpolygons.push_back(polygon); + } + } + else + newpolygons.push_back(polygon); + } + + polygons = newpolygons; } /* @@ -95,36 +95,36 @@ lwGetBoundingBox() void lwLayer::lwGetBoundingBox(void) { - unsigned int i; - - if ( points.size() == 0 ) return; - - if ( bboxmin.x != 0.0f ) return; - if ( bboxmin.y != 0.0f ) return; - if ( bboxmin.z != 0.0f ) return; - if ( bboxmax.x != 0.0f ) return; - if ( bboxmax.y != 0.0f ) return; - if ( bboxmax.z != 0.0f ) return; - - bboxmin.x = bboxmin.y = bboxmin.z = 1e20f; - bboxmax.x = bboxmax.y = bboxmax.z = -1e20f; - - for ( i = 0; i < points.size(); i++ ) - { - if ( bboxmin.x > points[ i ]->x ) - bboxmin.x = points[ i ]->x; - if ( bboxmin.y > points[ i ]->y ) - bboxmin.y = points[ i ]->y; - if ( bboxmin.z > points[ i ]->z ) - bboxmin.z = points[ i ]->z; - - if ( bboxmax.x < points[ i ]->x ) - bboxmax.x = points[ i ]->x; - if ( bboxmax.y < points[ i ]->y ) - bboxmax.y = points[ i ]->y; - if ( bboxmax.z < points[ i ]->z ) - bboxmax.z = points[ i ]->z; - } + unsigned int i; + + if ( points.size() == 0 ) return; + + if ( bboxmin.x != 0.0f ) return; + if ( bboxmin.y != 0.0f ) return; + if ( bboxmin.z != 0.0f ) return; + if ( bboxmax.x != 0.0f ) return; + if ( bboxmax.y != 0.0f ) return; + if ( bboxmax.z != 0.0f ) return; + + bboxmin.x = bboxmin.y = bboxmin.z = 1e20f; + bboxmax.x = bboxmax.y = bboxmax.z = -1e20f; + + for ( i = 0; i < points.size(); i++ ) + { + if ( bboxmin.x > points[ i ]->x ) + bboxmin.x = points[ i ]->x; + if ( bboxmin.y > points[ i ]->y ) + bboxmin.y = points[ i ]->y; + if ( bboxmin.z > points[ i ]->z ) + bboxmin.z = points[ i ]->z; + + if ( bboxmax.x < points[ i ]->x ) + bboxmax.x = points[ i ]->x; + if ( bboxmax.y < points[ i ]->y ) + bboxmax.y = points[ i ]->y; + if ( bboxmax.z < points[ i ]->z ) + bboxmax.z = points[ i ]->z; + } } /* @@ -138,51 +138,51 @@ lwResolvePolySurfaces() int lwLayer::lwResolvePolySurfaces( vsurfaces &surfaces, vtags &tags ) { - if ( tags.size() == 0 ) return 1; - - lwSurface **s = (lwSurface **)malloc (tags.size() * sizeof(lwSurface *)); - - if ( !s ) return 0; - - unsigned int i, j, index; - - for ( i = 0; i < tags.size(); i++ ) - { - s[i] = 0; - for (j = 0; j < surfaces.size(); j++) - { - if ( !strcmp( surfaces[j]->name, tags[i] )) - { - s[i] = surfaces[j]; - break; - } - } - if ( !s[i]) - { - s[i] = lwSurface::lwDefaultSurface(); - if ( !s[i] ) return 0; - - s[i]->name = (char *)malloc(strlen(tags[i])+1); - if ( !s[i]->name ) return 0; - - strcpy( s[i]->name, tags[i] ); - } - } - - surfaces.clear(); - surfaces.reserve(tags.size()); - for (i = 0; i < tags.size(); i++ ) - surfaces.push_back(s[i]); - - for (i = 0; i < polygons.size(); i++ ) - { - index = polygons[i]->surfidx; - if ( index < 0 || index > tags.size() ) return 0; - polygons[i]->surface = s[index]; - } - - free(s); - return 1; + if ( tags.size() == 0 ) return 1; + + lwSurface **s = (lwSurface **)malloc (tags.size() * sizeof(lwSurface *)); + + if ( !s ) return 0; + + unsigned int i, j, index; + + for ( i = 0; i < tags.size(); i++ ) + { + s[i] = 0; + for (j = 0; j < surfaces.size(); j++) + { + if ( !strcmp( surfaces[j]->name, tags[i] )) + { + s[i] = surfaces[j]; + break; + } + } + if ( !s[i]) + { + s[i] = lwSurface::lwDefaultSurface(); + if ( !s[i] ) return 0; + + s[i]->name = (char *)malloc(strlen(tags[i])+1); + if ( !s[i]->name ) return 0; + + strcpy( s[i]->name, tags[i] ); + } + } + + surfaces.clear(); + surfaces.reserve(tags.size()); + for (i = 0; i < tags.size(); i++ ) + surfaces.push_back(s[i]); + + for (i = 0; i < polygons.size(); i++ ) + { + index = polygons[i]->surfidx; + if ( index < 0 || index > tags.size() ) return 0; + polygons[i]->surface = s[index]; + } + + free(s); + return 1; } @@ -197,44 +197,44 @@ calculateVertexNormals() adjacent polygon is excluded from the sum. It's also excluded if the polygons aren't in the same smoothing group. - Assumes that lwGetPointPolygons(), lwGetPolyNormals() and - lwResolvePolySurfaces() have already been called. + Assumes that lwGetPointPolygons(), lwGetPolyNormals() and + lwResolvePolySurfaces() have already been called. ====================================================================== */ void lwLayer::calculateVertexNormals(void) { - unsigned int j, n, g; - float a; - lwPolygon *outerpolygon; - lwPolygon *innerpolygon; - lwVertex *vertex; - lwPoint *point; - - for ( j = 0; j < polygons.size(); j++ ) - { - outerpolygon = polygons[j]; - for ( n = 0; n < outerpolygon->vertices.size(); n++ ) - { - vertex = outerpolygon->vertices[n]; - vertex->normal = outerpolygon->normal; - - if ( outerpolygon->surface->smooth <= 0 ) continue; - - point = points[vertex->index]; - - for ( g = 0; g < point->polygons.size(); g++ ) - { - innerpolygon = point->polygons[ g ]; - if ( innerpolygon == outerpolygon ) continue; - if ( outerpolygon->smoothgrp != innerpolygon->smoothgrp ) continue; - a = (float)acos( outerpolygon->normal.dotProduct(innerpolygon->normal) ); - if ( a > outerpolygon->surface->smooth ) continue; - vertex->normal += innerpolygon->normal; - } - - vertex->normal.normalise(); - } - } + unsigned int j, n, g; + float a; + lwPolygon *outerpolygon; + lwPolygon *innerpolygon; + lwVertex *vertex; + lwPoint *point; + + for ( j = 0; j < polygons.size(); j++ ) + { + outerpolygon = polygons[j]; + for ( n = 0; n < outerpolygon->vertices.size(); n++ ) + { + vertex = outerpolygon->vertices[n]; + vertex->normal = outerpolygon->normal; + + if ( outerpolygon->surface->smooth <= 0 ) continue; + + point = points[vertex->index]; + + for ( g = 0; g < point->polygons.size(); g++ ) + { + innerpolygon = point->polygons[ g ]; + if ( innerpolygon == outerpolygon ) continue; + if ( outerpolygon->smoothgrp != innerpolygon->smoothgrp ) continue; + a = (float)acos( outerpolygon->normal.dotProduct(innerpolygon->normal) ); + if ( a > outerpolygon->surface->smooth ) continue; + vertex->normal += innerpolygon->normal; + } + + vertex->normal.normalise(); + } + } } /* @@ -246,20 +246,20 @@ lwGetPointVMaps() void lwLayer::lwGetPointVMaps(void) { - lwVMap *vm; - unsigned int i, j; - - for (j = 0; j < vmaps.size(); j++) - { - vm = vmaps[j]; - if ( !vm->perpoly ) - { - for ( i = 0; i < vm->nverts; i++ ) - { - points[ vm->vindex[ i ] ]->vmaps.push_back( lwVMapPt(vm, i) ); - } - } - } + lwVMap *vm; + unsigned int i, j; + + for (j = 0; j < vmaps.size(); j++) + { + vm = vmaps[j]; + if ( !vm->perpoly ) + { + for ( i = 0; i < vm->nverts; i++ ) + { + points[ vm->vindex[ i ] ]->vmaps.push_back( lwVMapPt(vm, i) ); + } + } + } } @@ -272,28 +272,28 @@ lwGetPolyVMaps() void lwLayer::lwGetPolyVMaps(void) { - lwVMap *vm; - lwVertex *pv; - unsigned int i, j, k; - - /* fill in vmap references for each mapped point */ - for (k = 0; k < vmaps.size(); k++) - { - vm = vmaps[k]; - if ( vm->perpoly ) - { - for ( i = 0; i < vm->nverts; i++ ) - { - for ( j = 0; j < polygons[ vm->pindex[ i ]]->vertices.size(); j++ ) - { - pv = polygons[ vm->pindex[ i ]]->vertices[ j ]; - if ( vm->vindex[ i ] == pv->index ) - { - pv->vmaps.push_back( lwVMapPt(vm, i) ); - break; - } - } - } - } - } + lwVMap *vm; + lwVertex *pv; + unsigned int i, j, k; + + /* fill in vmap references for each mapped point */ + for (k = 0; k < vmaps.size(); k++) + { + vm = vmaps[k]; + if ( vm->perpoly ) + { + for ( i = 0; i < vm->nverts; i++ ) + { + for ( j = 0; j < polygons[ vm->pindex[ i ]]->vertices.size(); j++ ) + { + pv = polygons[ vm->pindex[ i ]]->vertices[ j ]; + if ( vm->vindex[ i ] == pv->index ) + { + pv->vmaps.push_back( lwVMapPt(vm, i) ); + break; + } + } + } + } + } } diff --git a/Tools/LightwaveConverter/src/lwPolygon.cpp b/Tools/LightwaveConverter/src/lwPolygon.cpp index e60f0dd0af1..b067b15a147 100644 --- a/Tools/LightwaveConverter/src/lwPolygon.cpp +++ b/Tools/LightwaveConverter/src/lwPolygon.cpp @@ -6,167 +6,167 @@ const float epsilon = 0.001F; // error margin void lwPolygon::flip(void) { - vvertices flipvertices; - flipvertices.reserve(vertices.size()); - vvertices::reverse_iterator i = vertices.rbegin(); - vvertices::reverse_iterator end = vertices.rend(); - for(; i!=end ; ++i) - flipvertices.push_back(*i); - vertices = flipvertices; + vvertices flipvertices; + flipvertices.reserve(vertices.size()); + vvertices::reverse_iterator i = vertices.rbegin(); + vvertices::reverse_iterator end = vertices.rend(); + for(; i!=end ; ++i) + flipvertices.push_back(*i); + vertices = flipvertices; } lwPolygon *lwPolygon::makeTriangle(long ia, long ib, long ic) { - lwPolygon *triangle = new lwPolygon(*this); - - triangle->vertices.push_back(new lwVertex(*vertices[ia])); - triangle->vertices.push_back(new lwVertex(*vertices[ib])); - triangle->vertices.push_back(new lwVertex(*vertices[ic])); - - return triangle; + lwPolygon *triangle = new lwPolygon(*this); + + triangle->vertices.push_back(new lwVertex(*vertices[ia])); + triangle->vertices.push_back(new lwVertex(*vertices[ib])); + triangle->vertices.push_back(new lwVertex(*vertices[ic])); + + return triangle; } Vector3 &lwPolygon::calculateNormal() { - if ( vertices.size() < 3 ) return normal; + if ( vertices.size() < 3 ) return normal; - Point3 *p1 = vertices[ 0 ]->point; - Point3 *p2 = vertices[ 1 ]->point; - Point3 *pn = vertices[vertices.size() - 1]->point; - - normal = (*p2 - *p1).crossProduct(*pn - *p1); - normal.normalise(); + Point3 *p1 = vertices[ 0 ]->point; + Point3 *p2 = vertices[ 1 ]->point; + Point3 *pn = vertices[vertices.size() - 1]->point; + + normal = (*p2 - *p1).crossProduct(*pn - *p1); + normal.normalise(); - return normal; + return normal; } vpolygons lwPolygon::triangulate() { - vpolygons triangles; + vpolygons triangles; - BitArray active(vertices.size(), true); // vertex part of polygon ? - - long vertexCount = vertices.size(); + BitArray active(vertices.size(), true); // vertex part of polygon ? + + long vertexCount = vertices.size(); - long triangleCount = 0; - long start = 0; - - long p1 = 0; - long p2 = 1; - long m1 = vertexCount - 1; - long m2 = vertexCount - 2; - - bool lastPositive = false; - for (;;) - { - if (p2 == m2) - { - triangles.push_back(makeTriangle(m1, p1, p2)); - break; - } - - const Point3 vp1 = *vertices[p1]->point; - const Point3 vp2 = *vertices[p2]->point; - const Point3 vm1 = *vertices[m1]->point; - const Point3 vm2 = *vertices[m2]->point; - - bool positive = false; - bool negative = false; - - Vector3 n1 = normal.crossProduct((vm1 - vp2).normalise()); - if (n1.dotProduct(vp1 - vp2) > epsilon) - { - positive = true; - - Vector3 n2 = normal.crossProduct((vp1 - vm1).normalise()); - Vector3 n3 = normal.crossProduct((vp2 - vp1).normalise()); - - for (long a = 0; a < vertexCount; a++) - { - if ((a != p1) && (a != p2) && (a != m1) && active.bitSet(a)) - { - const Point3 v = *vertices[a]->point; - if (n1.dotProduct((v - vp2).normalise()) > -epsilon && n2.dotProduct((v - vm1).normalise()) > -epsilon && n3.dotProduct((v - vp1).normalise()) > -epsilon) - { - positive = false; - break; - } - } - } - } - - n1 = normal.crossProduct((vm2 - vp1).normalise()); - if (n1.dotProduct(vm1 - vp1) > epsilon) - { - negative = true; - - Vector3 n2 = normal.crossProduct((vm1 - vm2).normalise()); - Vector3 n3 = normal.crossProduct((vp1 - vm1).normalise()); - - for (long a = 0; a < vertexCount; a++) - { - if ((a != m1) && (a != m2) && (a != p1) && active.bitSet(a)) - { - const Point3 v = *vertices[a]->point; - if (n1.dotProduct((v - vp1).normalise()) > -epsilon && n2.dotProduct((v - vm2).normalise()) > -epsilon && n3.dotProduct((v - vm1).normalise()) > -epsilon) - { - negative = false; - break; - } - } - } - } - - if ((positive) && (negative)) - { - float pd = (vp2 - vm1).normalise().dotProduct((vm2 - vm1).normalise()); - float md = (vm2 - vp1).normalise().dotProduct((vp2 - vp1).normalise()); - - if (fabs(pd - md) < epsilon) - { - if (lastPositive) positive = false; - else negative = false; - } - else - { - if (pd < md) negative = false; - else positive = false; - } - } - - if (positive) - { - active.clearBit(p1); - triangles.push_back(makeTriangle(m1, p1, p2)); - - p1 = active.getNextSet(p1); - p2 = active.getNextSet(p2); - - lastPositive = true; - start = -1; - } - else if (negative) - { - active.clearBit(m1); - triangles.push_back(makeTriangle(m2, m1, p1)); - - m1 = active.getPreviousSet(m1); - m2 = active.getPreviousSet(m2); - - lastPositive = false; - start = -1; - } - else - { - if (start == -1) start = p2; - else if (p2 == start) break; - - m2 = m1; - m1 = p1; - p1 = p2; - p2 = active.getNextSet(p2); - } - } - - return triangles; + long triangleCount = 0; + long start = 0; + + long p1 = 0; + long p2 = 1; + long m1 = vertexCount - 1; + long m2 = vertexCount - 2; + + bool lastPositive = false; + for (;;) + { + if (p2 == m2) + { + triangles.push_back(makeTriangle(m1, p1, p2)); + break; + } + + const Point3 vp1 = *vertices[p1]->point; + const Point3 vp2 = *vertices[p2]->point; + const Point3 vm1 = *vertices[m1]->point; + const Point3 vm2 = *vertices[m2]->point; + + bool positive = false; + bool negative = false; + + Vector3 n1 = normal.crossProduct((vm1 - vp2).normalise()); + if (n1.dotProduct(vp1 - vp2) > epsilon) + { + positive = true; + + Vector3 n2 = normal.crossProduct((vp1 - vm1).normalise()); + Vector3 n3 = normal.crossProduct((vp2 - vp1).normalise()); + + for (long a = 0; a < vertexCount; a++) + { + if ((a != p1) && (a != p2) && (a != m1) && active.bitSet(a)) + { + const Point3 v = *vertices[a]->point; + if (n1.dotProduct((v - vp2).normalise()) > -epsilon && n2.dotProduct((v - vm1).normalise()) > -epsilon && n3.dotProduct((v - vp1).normalise()) > -epsilon) + { + positive = false; + break; + } + } + } + } + + n1 = normal.crossProduct((vm2 - vp1).normalise()); + if (n1.dotProduct(vm1 - vp1) > epsilon) + { + negative = true; + + Vector3 n2 = normal.crossProduct((vm1 - vm2).normalise()); + Vector3 n3 = normal.crossProduct((vp1 - vm1).normalise()); + + for (long a = 0; a < vertexCount; a++) + { + if ((a != m1) && (a != m2) && (a != p1) && active.bitSet(a)) + { + const Point3 v = *vertices[a]->point; + if (n1.dotProduct((v - vp1).normalise()) > -epsilon && n2.dotProduct((v - vm2).normalise()) > -epsilon && n3.dotProduct((v - vm1).normalise()) > -epsilon) + { + negative = false; + break; + } + } + } + } + + if ((positive) && (negative)) + { + float pd = (vp2 - vm1).normalise().dotProduct((vm2 - vm1).normalise()); + float md = (vm2 - vp1).normalise().dotProduct((vp2 - vp1).normalise()); + + if (fabs(pd - md) < epsilon) + { + if (lastPositive) positive = false; + else negative = false; + } + else + { + if (pd < md) negative = false; + else positive = false; + } + } + + if (positive) + { + active.clearBit(p1); + triangles.push_back(makeTriangle(m1, p1, p2)); + + p1 = active.getNextSet(p1); + p2 = active.getNextSet(p2); + + lastPositive = true; + start = -1; + } + else if (negative) + { + active.clearBit(m1); + triangles.push_back(makeTriangle(m2, m1, p1)); + + m1 = active.getPreviousSet(m1); + m2 = active.getPreviousSet(m2); + + lastPositive = false; + start = -1; + } + else + { + if (start == -1) start = p2; + else if (p2 == start) break; + + m2 = m1; + m1 = p1; + p1 = p2; + p2 = active.getNextSet(p2); + } + } + + return triangles; } diff --git a/Tools/LightwaveConverter/src/lwReader.cpp b/Tools/LightwaveConverter/src/lwReader.cpp index fbea899e5c3..c9167556b24 100644 --- a/Tools/LightwaveConverter/src/lwReader.cpp +++ b/Tools/LightwaveConverter/src/lwReader.cpp @@ -2,321 +2,321 @@ lwObject *lwReader::readObjectFromFile( const char *nfilename) { - lwObject *nobject = NULL; - - ifstream *ifs = new ifstream(); - try - { - ifs->open(nfilename, ios::in|ios::binary); - if (ifs->fail()) - cout << "Could not open file: " << nfilename << endl; - else - nobject = readObjectFromStream( ifs ); - } - catch (...) - { - if (nobject) delete nobject; - nobject = NULL; - } - ifs->close(); - delete ifs; - return nobject; + lwObject *nobject = NULL; + + ifstream *ifs = new ifstream(); + try + { + ifs->open(nfilename, ios::in|ios::binary); + if (ifs->fail()) + cout << "Could not open file: " << nfilename << endl; + else + nobject = readObjectFromStream( ifs ); + } + catch (...) + { + if (nobject) delete nobject; + nobject = NULL; + } + ifs->close(); + delete ifs; + return nobject; } lwObject *lwReader::readObjectFromStream( istream *nis) { - lwObject *nobject = 0; - chunksize = 0; - currentchunkid = 0; - formsize = 0; - flen = 0; - - is = nis; - - try - { - long id = getU4(); - if ( id == ID_FORM ) - { - formsize = getU4(); - long type = getU4(); - - switch(type) - { - case ID_LWO2: - nobject = lwGetLWO2(); // FORM0000LWXX -> filelength - 12 - break; - case ID_LWOB: - case ID_LWLO: - nobject = lwGetLWLO(); // FORM0000LWXX -> filelength - 12 - break; - default: - throw "File does not contain Lightwave object."; - } - } - else - throw "Not an IFF FORM file."; - } - catch (char *errstr) - { - cout << "Error near byte " << is->tellg() << " in chunk " << currentchunkid << " : " << errstr << endl; - } - catch (...) - { - if (nobject) delete nobject; - nobject = NULL; - } - return nobject; + lwObject *nobject = 0; + chunksize = 0; + currentchunkid = 0; + formsize = 0; + flen = 0; + + is = nis; + + try + { + long id = getU4(); + if ( id == ID_FORM ) + { + formsize = getU4(); + long type = getU4(); + + switch(type) + { + case ID_LWO2: + nobject = lwGetLWO2(); // FORM0000LWXX -> filelength - 12 + break; + case ID_LWOB: + case ID_LWLO: + nobject = lwGetLWLO(); // FORM0000LWXX -> filelength - 12 + break; + default: + throw "File does not contain Lightwave object."; + } + } + else + throw "Not an IFF FORM file."; + } + catch (char *errstr) + { + cout << "Error near byte " << is->tellg() << " in chunk " << currentchunkid << " : " << errstr << endl; + } + catch (...) + { + if (nobject) delete nobject; + nobject = NULL; + } + return nobject; } lwObject *lwReader::lwGetLWLO() { - long filepos = is->tellg(); - if (filepos == -1) return NULL; - long formstart = filepos; - long formend = filepos + formsize; // FORM0000LWXX -> filelength - 12 - - lwObject *object = new lwObject; - if ( !object ) return NULL; - - lwLayer *layer = new lwLayer; - if ( !layer ) goto Fail; - - lwSurface *surface; - unsigned int rlen; - unsigned long i; - while ( filepos < formend ) - { - currentchunkid = getU4(); - chunksize = getU4(); - chunksize += chunksize & 1; - - switch ( currentchunkid ) - { - case ID_SRFS: - if ( !lwGetTags(object->tags )) - goto Fail; - break; - case ID_LAYR: - if ( object->layers.size() > 0 ) - { - layer = new lwLayer; - if ( !layer ) goto Fail; - } - object->layers.push_back(layer); - - - flen = 0; - layer->index = getU2(); - layer->flags = getU2(); - layer->name = getS0(); - - rlen = flen; - if ( rlen < 0 || rlen > chunksize ) goto Fail; - if ( rlen < chunksize ) - is->seekg(chunksize - rlen, ios_base::cur); - break; - case ID_PNTS: - if ( !lwGetPoints(layer->points )) - goto Fail; - break; - - case ID_POLS: - if ( !lwGetLWOBPolygons(layer->polygons, layer->pointsoffset )) - goto Fail; - break; - - case ID_SURF: - surface = lwGetLWOBSurface(object ); - if ( surface ) object->surfaces.push_back( surface ); - break; - - case ID_SHCP: - default: - is->seekg(chunksize, ios_base::cur); - break; - } - - /* end of the file? */ - - filepos = is->tellg(); - if ( filepos == -1 ) break; - if ( filepos > formend ) break; // read too much - } - - if ( object->layers.size() == 0 ) - object->layers.push_back(layer); - - for (i = 0; i < object->layers.size(); i++) - { - layer = object->layers[i]; - layer->lwGetBoundingBox(); - layer->lwResolveVertexPoints(); - layer->calculatePolygonNormals(); - layer->lwGetPointPolygons(); - - if ( !layer->lwResolvePolySurfaces(object->surfaces, object->tags)) goto Fail; - layer->calculateVertexNormals(); - } - - return object; + long filepos = is->tellg(); + if (filepos == -1) return NULL; + long formstart = filepos; + long formend = filepos + formsize; // FORM0000LWXX -> filelength - 12 + + lwObject *object = new lwObject; + if ( !object ) return NULL; + + lwLayer *layer = new lwLayer; + if ( !layer ) goto Fail; + + lwSurface *surface; + unsigned int rlen; + unsigned long i; + while ( filepos < formend ) + { + currentchunkid = getU4(); + chunksize = getU4(); + chunksize += chunksize & 1; + + switch ( currentchunkid ) + { + case ID_SRFS: + if ( !lwGetTags(object->tags )) + goto Fail; + break; + case ID_LAYR: + if ( object->layers.size() > 0 ) + { + layer = new lwLayer; + if ( !layer ) goto Fail; + } + object->layers.push_back(layer); + + + flen = 0; + layer->index = getU2(); + layer->flags = getU2(); + layer->name = getS0(); + + rlen = flen; + if ( rlen < 0 || rlen > chunksize ) goto Fail; + if ( rlen < chunksize ) + is->seekg(chunksize - rlen, ios_base::cur); + break; + case ID_PNTS: + if ( !lwGetPoints(layer->points )) + goto Fail; + break; + + case ID_POLS: + if ( !lwGetLWOBPolygons(layer->polygons, layer->pointsoffset )) + goto Fail; + break; + + case ID_SURF: + surface = lwGetLWOBSurface(object ); + if ( surface ) object->surfaces.push_back( surface ); + break; + + case ID_SHCP: + default: + is->seekg(chunksize, ios_base::cur); + break; + } + + /* end of the file? */ + + filepos = is->tellg(); + if ( filepos == -1 ) break; + if ( filepos > formend ) break; // read too much + } + + if ( object->layers.size() == 0 ) + object->layers.push_back(layer); + + for (i = 0; i < object->layers.size(); i++) + { + layer = object->layers[i]; + layer->lwGetBoundingBox(); + layer->lwResolveVertexPoints(); + layer->calculatePolygonNormals(); + layer->lwGetPointPolygons(); + + if ( !layer->lwResolvePolySurfaces(object->surfaces, object->tags)) goto Fail; + layer->calculateVertexNormals(); + } + + return object; Fail: - if (object) delete object; - return NULL; + if (object) delete object; + return NULL; } lwObject *lwReader::lwGetLWO2() { - long filepos = is->tellg(); - if (filepos == -1) return NULL; - long formstart = filepos; - long formend = filepos + formsize; // FORM0000LWXX -> filelength - 12 - - /* allocate an object and a default layer */ - - lwObject *object = new lwObject; - if ( !object ) return NULL; - - lwLayer *layer = new lwLayer; - if ( !layer ) goto Fail; - - unsigned int i, rlen; - - lwVMap *vmap; - lwEnvelope *envelope; - lwClip *clip; - lwSurface *surface; - - /* process chunks as they're encountered */ - - while ( filepos < formend ) - { - currentchunkid = getU4(); - chunksize = getU4(); - chunksize += chunksize & 1; - - switch ( currentchunkid ) - { - case ID_LAYR: - if ( object->layers.size() > 0 ) - { - layer = new lwLayer; - if ( !layer ) goto Fail; - } - object->layers.push_back(layer); - - flen = 0; - layer->index = getU2(); - layer->flags = getU2(); - layer->pivot.x = getF4(); - layer->pivot.y = getF4(); - layer->pivot.z = getF4(); - layer->name = getS0(); - - rlen = flen; - if ( rlen < 0 || rlen > chunksize ) goto Fail; - if ( rlen <= chunksize - 2 ) - layer->parent = getU2(); - rlen = flen; - if ( rlen < chunksize ) - is->seekg(chunksize - rlen, ios_base::cur); - break; - - case ID_PNTS: - if ( !lwGetPoints(layer->points )) - goto Fail; - break; - - case ID_POLS: - if ( !lwGetPolygons(layer->polygons, layer->pointsoffset )) - goto Fail; - break; - - case ID_VMAP: - case ID_VMAD: - vmap = lwGetVMap(layer->pointsoffset, layer->polygonsoffset, currentchunkid == ID_VMAD ); - if ( !vmap ) goto Fail; - layer->vmaps.push_back(vmap); - break; - - case ID_PTAG: - if ( !lwGetPolygonTags(object->tags, object->tagsoffset, layer->polygons, layer->polygonsoffset )) - goto Fail; - break; - - case ID_BBOX: - flen = 0; - layer->bboxmin.x = getF4(); - layer->bboxmin.y = getF4(); - layer->bboxmin.z = getF4(); - layer->bboxmax.x = getF4(); - layer->bboxmax.y = getF4(); - layer->bboxmax.z = getF4(); - rlen = flen; - if ( rlen < 0 || rlen > chunksize ) goto Fail; - if ( rlen < chunksize ) - is->seekg(chunksize - rlen, ios_base::cur ); - break; - - case ID_TAGS: - if ( !lwGetTags(object->tags )) - goto Fail; - break; - - case ID_ENVL: - envelope = lwGetEnvelope(); - if ( !envelope ) goto Fail; - object->envelopes.push_back( envelope ); - break; - - case ID_CLIP: - clip = lwGetClip(); - if ( !clip ) goto Fail; - object->clips.push_back( clip ); - break; - - case ID_SURF: - surface = lwGetSurface(); - if ( !surface ) goto Fail; - object->surfaces.push_back( surface ); - break; - - case ID_DESC: - case ID_TEXT: - case ID_ICON: - default: - is->seekg(chunksize, ios_base::cur ); - break; - } - - /* end of the file? */ - filepos = is->tellg(); - if ( filepos == -1 ) break; - if ( filepos > formend ) break; // read too much - } - - if ( object->layers.size() == 0 ) - object->layers.push_back(layer); - - for (i = 0; i < object->layers.size(); i++) - { - layer = object->layers[i]; - if ( !layer->lwResolvePolySurfaces(object->surfaces, object->tags)) goto Fail; - - layer->lwGetBoundingBox(); - layer->lwResolveVertexPoints(); - layer->calculatePolygonNormals(); - layer->lwGetPointPolygons(); - layer->calculateVertexNormals(); - layer->lwGetPointVMaps(); - layer->lwGetPolyVMaps(); - } - - return object; + long filepos = is->tellg(); + if (filepos == -1) return NULL; + long formstart = filepos; + long formend = filepos + formsize; // FORM0000LWXX -> filelength - 12 + + /* allocate an object and a default layer */ + + lwObject *object = new lwObject; + if ( !object ) return NULL; + + lwLayer *layer = new lwLayer; + if ( !layer ) goto Fail; + + unsigned int i, rlen; + + lwVMap *vmap; + lwEnvelope *envelope; + lwClip *clip; + lwSurface *surface; + + /* process chunks as they're encountered */ + + while ( filepos < formend ) + { + currentchunkid = getU4(); + chunksize = getU4(); + chunksize += chunksize & 1; + + switch ( currentchunkid ) + { + case ID_LAYR: + if ( object->layers.size() > 0 ) + { + layer = new lwLayer; + if ( !layer ) goto Fail; + } + object->layers.push_back(layer); + + flen = 0; + layer->index = getU2(); + layer->flags = getU2(); + layer->pivot.x = getF4(); + layer->pivot.y = getF4(); + layer->pivot.z = getF4(); + layer->name = getS0(); + + rlen = flen; + if ( rlen < 0 || rlen > chunksize ) goto Fail; + if ( rlen <= chunksize - 2 ) + layer->parent = getU2(); + rlen = flen; + if ( rlen < chunksize ) + is->seekg(chunksize - rlen, ios_base::cur); + break; + + case ID_PNTS: + if ( !lwGetPoints(layer->points )) + goto Fail; + break; + + case ID_POLS: + if ( !lwGetPolygons(layer->polygons, layer->pointsoffset )) + goto Fail; + break; + + case ID_VMAP: + case ID_VMAD: + vmap = lwGetVMap(layer->pointsoffset, layer->polygonsoffset, currentchunkid == ID_VMAD ); + if ( !vmap ) goto Fail; + layer->vmaps.push_back(vmap); + break; + + case ID_PTAG: + if ( !lwGetPolygonTags(object->tags, object->tagsoffset, layer->polygons, layer->polygonsoffset )) + goto Fail; + break; + + case ID_BBOX: + flen = 0; + layer->bboxmin.x = getF4(); + layer->bboxmin.y = getF4(); + layer->bboxmin.z = getF4(); + layer->bboxmax.x = getF4(); + layer->bboxmax.y = getF4(); + layer->bboxmax.z = getF4(); + rlen = flen; + if ( rlen < 0 || rlen > chunksize ) goto Fail; + if ( rlen < chunksize ) + is->seekg(chunksize - rlen, ios_base::cur ); + break; + + case ID_TAGS: + if ( !lwGetTags(object->tags )) + goto Fail; + break; + + case ID_ENVL: + envelope = lwGetEnvelope(); + if ( !envelope ) goto Fail; + object->envelopes.push_back( envelope ); + break; + + case ID_CLIP: + clip = lwGetClip(); + if ( !clip ) goto Fail; + object->clips.push_back( clip ); + break; + + case ID_SURF: + surface = lwGetSurface(); + if ( !surface ) goto Fail; + object->surfaces.push_back( surface ); + break; + + case ID_DESC: + case ID_TEXT: + case ID_ICON: + default: + is->seekg(chunksize, ios_base::cur ); + break; + } + + /* end of the file? */ + filepos = is->tellg(); + if ( filepos == -1 ) break; + if ( filepos > formend ) break; // read too much + } + + if ( object->layers.size() == 0 ) + object->layers.push_back(layer); + + for (i = 0; i < object->layers.size(); i++) + { + layer = object->layers[i]; + if ( !layer->lwResolvePolySurfaces(object->surfaces, object->tags)) goto Fail; + + layer->lwGetBoundingBox(); + layer->lwResolveVertexPoints(); + layer->calculatePolygonNormals(); + layer->lwGetPointPolygons(); + layer->calculateVertexNormals(); + layer->lwGetPointVMaps(); + layer->lwGetPolyVMaps(); + } + + return object; Fail: - if(object) delete object; - return NULL; + if(object) delete object; + return NULL; } #define FLEN_ERROR INT_MIN @@ -329,8 +329,8 @@ revbytes() Reverses byte order in place. INPUTS -bp bytes to reverse -elsize size of the underlying data type +bp bytes to reverse +elsize size of the underlying data type elcount number of elements to swap RESULTS @@ -343,744 +343,744 @@ platforms. unsigned short lwReader::swappedShort(unsigned short w) { - unsigned short tmp; - tmp = (w & 0x00ff); - tmp = ((w & 0xff00) >> 0x08) | (tmp << 0x08); - return tmp; + unsigned short tmp; + tmp = (w & 0x00ff); + tmp = ((w & 0xff00) >> 0x08) | (tmp << 0x08); + return tmp; } unsigned long lwReader::swappedLong(unsigned long w) { - unsigned long tmp; - tmp = (w & 0x000000ff); - tmp = ((w & 0x0000ff00) >> 0x08) | (tmp << 0x08); - tmp = ((w & 0x00ff0000) >> 0x10) | (tmp << 0x08); - tmp = ((w & 0xff000000) >> 0x18) | (tmp << 0x08); - return tmp; + unsigned long tmp; + tmp = (w & 0x000000ff); + tmp = ((w & 0x0000ff00) >> 0x08) | (tmp << 0x08); + tmp = ((w & 0x00ff0000) >> 0x10) | (tmp << 0x08); + tmp = ((w & 0xff000000) >> 0x18) | (tmp << 0x08); + return tmp; } void lwReader::revbytes( void *bp, int elsize, int elcount ) { - register char *p, *q; - - p = ( char * ) bp; - - if ( elsize == 2 ) { - q = p + 1; - while ( elcount-- ) { - *p ^= *q; - *q ^= *p; - *p ^= *q; - p += 2; - q += 2; - } - return; - } - - while ( elcount-- ) { - q = p + elsize - 1; - while ( p < q ) { - *p ^= *q; - *q ^= *p; - *p ^= *q; - ++p; - --q; - } - p += elsize >> 1; - } + register char *p, *q; + + p = ( char * ) bp; + + if ( elsize == 2 ) { + q = p + 1; + while ( elcount-- ) { + *p ^= *q; + *q ^= *p; + *p ^= *q; + p += 2; + q += 2; + } + return; + } + + while ( elcount-- ) { + q = p + elsize - 1; + while ( p < q ) { + *p ^= *q; + *q ^= *p; + *p ^= *q; + ++p; + --q; + } + p += elsize >> 1; + } } #endif char *lwReader::getbytes( int size ) { - char *data; - - if ( flen == FLEN_ERROR ) return NULL; - if ( size < 0 ) { - flen = FLEN_ERROR; - return NULL; - } - if ( size == 0 ) return NULL; - - data = (char*)malloc(size); - - if ( !data ) - { - flen = FLEN_ERROR; - return NULL; - } - - is->read((char *)data, size); - if (is->gcount() != size) - { - flen = FLEN_ERROR; - free (data); - return NULL; - } - - flen += size; - return data; + char *data; + + if ( flen == FLEN_ERROR ) return NULL; + if ( size < 0 ) { + flen = FLEN_ERROR; + return NULL; + } + if ( size == 0 ) return NULL; + + data = (char*)malloc(size); + + if ( !data ) + { + flen = FLEN_ERROR; + return NULL; + } + + is->read((char *)data, size); + if (is->gcount() != size) + { + flen = FLEN_ERROR; + free (data); + return NULL; + } + + flen += size; + return data; } void lwReader::skipbytes( int n ) { - if ( flen == FLEN_ERROR ) return; - - is->seekg(n, ios_base::cur); - - if (is->bad()) - flen = FLEN_ERROR; - else - flen += n; + if ( flen == FLEN_ERROR ) return; + + is->seekg(n, ios_base::cur); + + if (is->bad()) + flen = FLEN_ERROR; + else + flen += n; } short lwReader::getI2() { - short i; - - if ( flen == FLEN_ERROR ) return 0; - - is->read((char *)&i, 2); - if (is->gcount() != 2) - { - flen = FLEN_ERROR; - return 0; - } - revbytes( &i, 2, 1 ); - flen += 2; - return i; + short i; + + if ( flen == FLEN_ERROR ) return 0; + + is->read((char *)&i, 2); + if (is->gcount() != 2) + { + flen = FLEN_ERROR; + return 0; + } + revbytes( &i, 2, 1 ); + flen += 2; + return i; } long lwReader::getI4() { - long i; - - if ( flen == FLEN_ERROR ) return 0; - - is->read((char *)&i, 4); - if (is->gcount() != 4) { - flen = FLEN_ERROR; - return 0; - } - revbytes( &i, 4, 1 ); - flen += 4; - return i; + long i; + + if ( flen == FLEN_ERROR ) return 0; + + is->read((char *)&i, 4); + if (is->gcount() != 4) { + flen = FLEN_ERROR; + return 0; + } + revbytes( &i, 4, 1 ); + flen += 4; + return i; } unsigned char lwReader::getU1() { - unsigned char i; - - if ( flen == FLEN_ERROR ) return 0; - is->read((char *)&i, 1); - if (is->gcount() != 1) - { - flen = FLEN_ERROR; - return 0; - } - flen += 1; - return i; + unsigned char i; + + if ( flen == FLEN_ERROR ) return 0; + is->read((char *)&i, 1); + if (is->gcount() != 1) + { + flen = FLEN_ERROR; + return 0; + } + flen += 1; + return i; } unsigned short lwReader::getU2() { - unsigned short i; - - if ( flen == FLEN_ERROR ) return 0; - is->read((char *)&i, 2); - if (is->gcount() != 2) - { - flen = FLEN_ERROR; - return 0; - } - revbytes( &i, 2, 1 ); - flen += 2; - return i; + unsigned short i; + + if ( flen == FLEN_ERROR ) return 0; + is->read((char *)&i, 2); + if (is->gcount() != 2) + { + flen = FLEN_ERROR; + return 0; + } + revbytes( &i, 2, 1 ); + flen += 2; + return i; } unsigned long lwReader::getU4() { - unsigned long i; - - if ( flen == FLEN_ERROR ) return 0; - is->read((char *)&i, 4); - if (is->gcount() != 4) - { - flen = FLEN_ERROR; - return 0; - } - revbytes( &i, 4, 1 ); - flen += 4; - return i; + unsigned long i; + + if ( flen == FLEN_ERROR ) return 0; + is->read((char *)&i, 4); + if (is->gcount() != 4) + { + flen = FLEN_ERROR; + return 0; + } + revbytes( &i, 4, 1 ); + flen += 4; + return i; } int lwReader::getVX() { - int i; - short c; - - if ( flen == FLEN_ERROR ) return 0; - - is->read((char *)&c, 2); - - if ( (c & 0x00FF) != 0xFF ) - { - i = swappedShort(c); - flen += 2; - } - else - { - i = (swappedShort(c) & 0x00FF) << 16; - is->read((char *)&c, 2); - i |= swappedShort(c); - flen += 4; - } - - if ( is->bad() ) { - flen = FLEN_ERROR; - return 0; - } - return i; + int i; + short c; + + if ( flen == FLEN_ERROR ) return 0; + + is->read((char *)&c, 2); + + if ( (c & 0x00FF) != 0xFF ) + { + i = swappedShort(c); + flen += 2; + } + else + { + i = (swappedShort(c) & 0x00FF) << 16; + is->read((char *)&c, 2); + i |= swappedShort(c); + flen += 4; + } + + if ( is->bad() ) { + flen = FLEN_ERROR; + return 0; + } + return i; } float lwReader::getF4() { - float f; - - if ( flen == FLEN_ERROR ) return 0.0f; - is->read((char *)&f, 4); - if (is->gcount() != 4) - { - flen = FLEN_ERROR; - return 0.0f; - } - revbytes( &f, 4, 1 ); - flen += 4; - return f; + float f; + + if ( flen == FLEN_ERROR ) return 0.0f; + is->read((char *)&f, 4); + if (is->gcount() != 4) + { + flen = FLEN_ERROR; + return 0.0f; + } + revbytes( &f, 4, 1 ); + flen += 4; + return f; } char *lwReader::getS0() { - char *s; - int i, len, pos; - char c; - - if ( flen == FLEN_ERROR ) return NULL; - - pos = is->tellg(); - if (pos == -1) return 0; - - i = 0; - do - { - is->read(&c, 1); - i ++; - } - while (c > 0); - - if ( i == 1 ) // word align - { - is->read(&c, 1); - flen += 2; - return NULL; - } - - len = i + ( i & 1 ); - - s = (char *)malloc(len); - if ( !s ) - { - flen = FLEN_ERROR; - return NULL; - } - - is->seekg(pos, ios_base::beg); - if (is->bad()) - { - flen = FLEN_ERROR; - return NULL; - } - - is->read(s, len); - if (is->gcount() != len) - { - flen = FLEN_ERROR; - return NULL; - } - - flen += len; - return s; + char *s; + int i, len, pos; + char c; + + if ( flen == FLEN_ERROR ) return NULL; + + pos = is->tellg(); + if (pos == -1) return 0; + + i = 0; + do + { + is->read(&c, 1); + i ++; + } + while (c > 0); + + if ( i == 1 ) // word align + { + is->read(&c, 1); + flen += 2; + return NULL; + } + + len = i + ( i & 1 ); + + s = (char *)malloc(len); + if ( !s ) + { + flen = FLEN_ERROR; + return NULL; + } + + is->seekg(pos, ios_base::beg); + if (is->bad()) + { + flen = FLEN_ERROR; + return NULL; + } + + is->read(s, len); + if (is->gcount() != len) + { + flen = FLEN_ERROR; + return NULL; + } + + flen += len; + return s; } short lwReader::sgetI2( char **bp ) { - short i; - - if ( flen == FLEN_ERROR ) return 0; - memcpy( &i, *bp, 2 ); - revbytes( &i, 2, 1 ); - flen += 2; - *bp += 2; - return i; + short i; + + if ( flen == FLEN_ERROR ) return 0; + memcpy( &i, *bp, 2 ); + revbytes( &i, 2, 1 ); + flen += 2; + *bp += 2; + return i; } long lwReader::sgetI4( char **bp ) { - long i; - - if ( flen == FLEN_ERROR ) return 0; - memcpy( &i, *bp, 4 ); - revbytes( &i, 4, 1 ); - flen += 4; - *bp += 4; - return i; + long i; + + if ( flen == FLEN_ERROR ) return 0; + memcpy( &i, *bp, 4 ); + revbytes( &i, 4, 1 ); + flen += 4; + *bp += 4; + return i; } unsigned char lwReader::sgetU1( char **bp ) { - unsigned char c; - - if ( flen == FLEN_ERROR ) return 0; - c = **bp; - flen += 1; - *bp++; - return c; + unsigned char c; + + if ( flen == FLEN_ERROR ) return 0; + c = **bp; + flen += 1; + *bp++; + return c; } unsigned short lwReader::sgetU2(char **bp ) { - unsigned char *buf = (unsigned char *)*bp; - unsigned short i; - - if ( flen == FLEN_ERROR ) return 0; - i = ( buf[ 0 ] << 8 ) | buf[ 1 ]; - flen += 2; - *bp += 2; - return i; + unsigned char *buf = (unsigned char *)*bp; + unsigned short i; + + if ( flen == FLEN_ERROR ) return 0; + i = ( buf[ 0 ] << 8 ) | buf[ 1 ]; + flen += 2; + *bp += 2; + return i; } unsigned long lwReader::sgetU4( char **bp ) { - unsigned long i; - - if ( flen == FLEN_ERROR ) return 0; - memcpy( &i, *bp, 4 ); - revbytes( &i, 4, 1 ); - flen += 4; - *bp += 4; - return i; + unsigned long i; + + if ( flen == FLEN_ERROR ) return 0; + memcpy( &i, *bp, 4 ); + revbytes( &i, 4, 1 ); + flen += 4; + *bp += 4; + return i; } int lwReader::sgetVX( char **bp ) { - unsigned char *buf = (unsigned char *)*bp; - int i; - - if ( flen == FLEN_ERROR ) return 0; - - if ( buf[ 0 ] != 0xFF ) - { - i = buf[ 0 ] << 8 | buf[ 1 ]; - flen += 2; - *bp += 2; - } - else - { - i = ( buf[ 1 ] << 16 ) | ( buf[ 2 ] << 8 ) | buf[ 3 ]; - flen += 4; - *bp += 4; - } - return i; + unsigned char *buf = (unsigned char *)*bp; + int i; + + if ( flen == FLEN_ERROR ) return 0; + + if ( buf[ 0 ] != 0xFF ) + { + i = buf[ 0 ] << 8 | buf[ 1 ]; + flen += 2; + *bp += 2; + } + else + { + i = ( buf[ 1 ] << 16 ) | ( buf[ 2 ] << 8 ) | buf[ 3 ]; + flen += 4; + *bp += 4; + } + return i; } float lwReader::sgetF4( char **bp ) { - float f; - - if ( flen == FLEN_ERROR ) return 0.0f; - memcpy( &f, *bp, 4 ); - revbytes( &f, 4, 1 ); - flen += 4; - *bp += 4; - return f; + float f; + + if ( flen == FLEN_ERROR ) return 0.0f; + memcpy( &f, *bp, 4 ); + revbytes( &f, 4, 1 ); + flen += 4; + *bp += 4; + return f; } char *lwReader::sgetS0( char **bp ) { - char *s; - const char *buf = (const char *)*bp; - unsigned int len; - - if ( flen == FLEN_ERROR ) return NULL; - - len = strlen( buf ) + 1; - if ( len == 1 ) { - flen += 2; - *bp += 2; - return NULL; - } - len += len & 1; - s = (char *)malloc(len); - if ( !s ) - { - flen = FLEN_ERROR; - return NULL; - } - - memcpy( s, buf, len ); - flen += len; - *bp += len; - return s; + char *s; + const char *buf = (const char *)*bp; + unsigned int len; + + if ( flen == FLEN_ERROR ) return NULL; + + len = strlen( buf ) + 1; + if ( len == 1 ) { + flen += 2; + *bp += 2; + return NULL; + } + len += len & 1; + s = (char *)malloc(len); + if ( !s ) + { + flen = FLEN_ERROR; + return NULL; + } + + memcpy( s, buf, len ); + flen += len; + *bp += len; + return s; } lwClip *lwReader::lwGetClip() { - lwClip *clip; - lwPlugin *filt; - unsigned int id; - unsigned short sz; - unsigned int pos, rlen; - - - /* allocate the Clip structure */ - - clip = new lwClip; - if ( !clip ) goto Fail; - - /* remember where we started */ - - flen = 0; - pos = is->tellg(); - - /* index */ - - clip->index = getI4(); - - /* first subchunk header */ - - clip->type = getU4(); - sz = getU2(); - if ( 0 > flen ) goto Fail; - - sz += sz & 1; - flen = 0; - - switch ( clip->type ) - { - case ID_STIL: - { - lwClipStill *still = new lwClipStill; - still->name = getS0(); - clip->source.still = still; - } - break; - - case ID_ISEQ: - { - lwClipSeq *seq = new lwClipSeq; - seq->digits = getU1(); - seq->flags = getU1(); - seq->offset = getI2(); - getU2(); /* reserved */ - seq->start = getI2(); - seq->end = getI2(); - seq->prefix = getS0(); - seq->suffix = getS0(); - clip->source.seq = seq; - } - break; - - case ID_ANIM: - { - lwClipAnim *anim = new lwClipAnim; - anim->name = getS0(); - anim->server = getS0(); - rlen = flen; - anim->data = getbytes( sz - rlen ); - clip->source.anim = anim; - } - break; - - case ID_XREF: - { - lwClipXRef *xref = new lwClipXRef; - xref->index = getI4(); - xref->string = getS0(); - clip->source.xref = xref; - } - break; - - case ID_STCC: - { - lwClipCycle *cycle = new lwClipCycle; - cycle->lo = getI2(); - cycle->hi = getI2(); - cycle->name = getS0(); - clip->source.cycle = cycle; - } - break; - - default: - break; - } - - /* error while reading current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) goto Fail; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the CLIP chunk? */ - - rlen = is->tellg(); - rlen -= pos; - if ( chunksize < rlen ) goto Fail; - if ( chunksize == rlen ) - return clip; - - /* process subchunks as they're encountered */ - - id = getU4(); - sz = getU2(); - if ( 0 > flen ) goto Fail; - - for (;;) { - sz += sz & 1; - flen = 0; - - switch ( id ) { - case ID_TIME: + lwClip *clip; + lwPlugin *filt; + unsigned int id; + unsigned short sz; + unsigned int pos, rlen; + + + /* allocate the Clip structure */ + + clip = new lwClip; + if ( !clip ) goto Fail; + + /* remember where we started */ + + flen = 0; + pos = is->tellg(); + + /* index */ + + clip->index = getI4(); + + /* first subchunk header */ + + clip->type = getU4(); + sz = getU2(); + if ( 0 > flen ) goto Fail; + + sz += sz & 1; + flen = 0; + + switch ( clip->type ) + { + case ID_STIL: + { + lwClipStill *still = new lwClipStill; + still->name = getS0(); + clip->source.still = still; + } + break; + + case ID_ISEQ: + { + lwClipSeq *seq = new lwClipSeq; + seq->digits = getU1(); + seq->flags = getU1(); + seq->offset = getI2(); + getU2(); /* reserved */ + seq->start = getI2(); + seq->end = getI2(); + seq->prefix = getS0(); + seq->suffix = getS0(); + clip->source.seq = seq; + } + break; + + case ID_ANIM: + { + lwClipAnim *anim = new lwClipAnim; + anim->name = getS0(); + anim->server = getS0(); + rlen = flen; + anim->data = getbytes( sz - rlen ); + clip->source.anim = anim; + } + break; + + case ID_XREF: + { + lwClipXRef *xref = new lwClipXRef; + xref->index = getI4(); + xref->string = getS0(); + clip->source.xref = xref; + } + break; + + case ID_STCC: + { + lwClipCycle *cycle = new lwClipCycle; + cycle->lo = getI2(); + cycle->hi = getI2(); + cycle->name = getS0(); + clip->source.cycle = cycle; + } + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the CLIP chunk? */ + + rlen = is->tellg(); + rlen -= pos; + if ( chunksize < rlen ) goto Fail; + if ( chunksize == rlen ) + return clip; + + /* process subchunks as they're encountered */ + + id = getU4(); + sz = getU2(); + if ( 0 > flen ) goto Fail; + + for (;;) { + sz += sz & 1; + flen = 0; + + switch ( id ) { + case ID_TIME: clip->start_time = getF4(); clip->duration = getF4(); clip->frame_rate = getF4(); break; - - case ID_CONT: + + case ID_CONT: clip->contrast.val = getF4(); clip->contrast.eindex = getVX(); break; - - case ID_BRIT: + + case ID_BRIT: clip->brightness.val = getF4(); clip->brightness.eindex = getVX(); break; - - case ID_SATR: + + case ID_SATR: clip->saturation.val = getF4(); clip->saturation.eindex = getVX(); break; - - case ID_HUE: + + case ID_HUE: clip->hue.val = getF4(); clip->hue.eindex = getVX(); break; - - case ID_GAMM: + + case ID_GAMM: clip->gamma.val = getF4(); clip->gamma.eindex = getVX(); break; - - case ID_NEGA: + + case ID_NEGA: clip->negative = getU2(); break; - - case ID_IFLT: - case ID_PFLT: + + case ID_IFLT: + case ID_PFLT: filt = new lwPlugin; if ( !filt ) goto Fail; - + filt->name = getS0(); filt->flags = getU2(); rlen = flen; filt->data = getbytes( sz - rlen ); - + if ( id == ID_IFLT ) - clip->ifilters.push_back(filt); + clip->ifilters.push_back(filt); else - clip->pfilters.push_back(filt); - - break; - - default: - break; - } - - /* error while reading current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) goto Fail; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the CLIP chunk? */ - - rlen = is->tellg(); - rlen -= pos; - if ( chunksize < rlen ) goto Fail; - if ( chunksize == rlen ) break; - - /* get the next chunk header */ - - flen = 0; - id = getU4(); - sz = getU2(); - if ( 6 != flen ) goto Fail; - } - - return clip; - + clip->pfilters.push_back(filt); + + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the CLIP chunk? */ + + rlen = is->tellg(); + rlen -= pos; + if ( chunksize < rlen ) goto Fail; + if ( chunksize == rlen ) break; + + /* get the next chunk header */ + + flen = 0; + id = getU4(); + sz = getU2(); + if ( 6 != flen ) goto Fail; + } + + return clip; + Fail: - delete clip; - return NULL; + delete clip; + return NULL; } lwEnvelope *lwReader::lwGetEnvelope() { - lwEnvelope *env; - lwKey *key; - lwPlugin *plug; - unsigned int id; - unsigned short sz; - float f[ 4 ]; - int i, nparams, pos; - unsigned int rlen; - - /* allocate the Envelope structure */ - - env = new lwEnvelope; - if ( !env ) goto Fail; - - /* remember where we started */ - - flen = 0; - pos = is->tellg(); - - /* index */ - - env->index = getVX(); - - /* first subchunk header */ - - id = getU4(); - sz = getU2(); - if ( 0 > flen ) goto Fail; - - /* process subchunks as they're encountered */ - - for (;;) { - sz += sz & 1; - flen = 0; - - switch ( id ) { - case ID_TYPE: + lwEnvelope *env; + lwKey *key; + lwPlugin *plug; + unsigned int id; + unsigned short sz; + float f[ 4 ]; + int i, nparams, pos; + unsigned int rlen; + + /* allocate the Envelope structure */ + + env = new lwEnvelope; + if ( !env ) goto Fail; + + /* remember where we started */ + + flen = 0; + pos = is->tellg(); + + /* index */ + + env->index = getVX(); + + /* first subchunk header */ + + id = getU4(); + sz = getU2(); + if ( 0 > flen ) goto Fail; + + /* process subchunks as they're encountered */ + + for (;;) { + sz += sz & 1; + flen = 0; + + switch ( id ) { + case ID_TYPE: env->type = getU2(); break; - - case ID_NAME: + + case ID_NAME: env->name = getS0(); break; - - case ID_PRE: + + case ID_PRE: env->behavior[ 0 ] = getU2(); break; - - case ID_POST: + + case ID_POST: env->behavior[ 1 ] = getU2(); break; - - case ID_KEY: - key = env->addKey(getF4(), getF4()); + + case ID_KEY: + key = env->addKey(getF4(), getF4()); break; - - case ID_SPAN: + + case ID_SPAN: if ( !key ) goto Fail; key->shape = getU4(); - + nparams = ( sz - 4 ) / 4; if ( nparams > 4 ) nparams = 4; for ( i = 0; i < nparams; i++ ) - f[ i ] = getF4(); - + f[ i ] = getF4(); + switch ( key->shape ) { - case ID_TCB: - key->tension = f[ 0 ]; - key->continuity = f[ 1 ]; - key->bias = f[ 2 ]; - break; - - case ID_BEZI: - case ID_HERM: - case ID_BEZ2: - for ( i = 0; i < nparams; i++ ) - key->param[ i ] = f[ i ]; - break; + case ID_TCB: + key->tension = f[ 0 ]; + key->continuity = f[ 1 ]; + key->bias = f[ 2 ]; + break; + + case ID_BEZI: + case ID_HERM: + case ID_BEZ2: + for ( i = 0; i < nparams; i++ ) + key->param[ i ] = f[ i ]; + break; } break; - - case ID_CHAN: - plug = new lwPlugin; - if ( !plug ) goto Fail; - - plug->name = getS0(); - plug->flags = getU2(); - plug->data = getbytes( sz - flen ); - - env->cfilters.push_back( plug ); - env->ncfilters++; - break; - - default: - break; - } - - /* error while reading current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) goto Fail; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the ENVL chunk? */ - - rlen = is->tellg(); - rlen -= pos; - if ( chunksize < rlen ) goto Fail; - if ( chunksize == rlen ) break; - - /* get the next subchunk header */ - - flen = 0; - id = getU4(); - sz = getU2(); - if ( 6 != flen ) goto Fail; - } - - return env; - + + case ID_CHAN: + plug = new lwPlugin; + if ( !plug ) goto Fail; + + plug->name = getS0(); + plug->flags = getU2(); + plug->data = getbytes( sz - flen ); + + env->cfilters.push_back( plug ); + env->ncfilters++; + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the ENVL chunk? */ + + rlen = is->tellg(); + rlen -= pos; + if ( chunksize < rlen ) goto Fail; + if ( chunksize == rlen ) break; + + /* get the next subchunk header */ + + flen = 0; + id = getU4(); + sz = getU2(); + if ( 6 != flen ) goto Fail; + } + + return env; + Fail: - delete env; - return NULL; + delete env; + return NULL; } /* @@ -1093,28 +1093,28 @@ lwGetPoints() int lwReader::lwGetPoints( vpoints &points ) { - if ( chunksize == 1 ) return 1; + if ( chunksize == 1 ) return 1; - int npoints; + int npoints; - npoints = chunksize / 12; + npoints = chunksize / 12; - int rpoints = npoints >= 4096 ? 4096 : npoints; - float *f = (float *)malloc(rpoints * 3 * sizeof(float)); + int rpoints = npoints >= 4096 ? 4096 : npoints; + float *f = (float *)malloc(rpoints * 3 * sizeof(float)); - while(npoints > 0) - { - is->read((char *)f, rpoints * 3 * sizeof(float)); - revbytes( f, sizeof(float), rpoints * 3 ); - for (int i = 0 ; i < rpoints * 3; i += 3 ) - points.push_back(new lwPoint(f[ i ], f[ i + 1 ], f[ i + 2 ])); + while(npoints > 0) + { + is->read((char *)f, rpoints * 3 * sizeof(float)); + revbytes( f, sizeof(float), rpoints * 3 ); + for (int i = 0 ; i < rpoints * 3; i += 3 ) + points.push_back(new lwPoint(f[ i ], f[ i + 1 ], f[ i + 2 ])); - npoints -= rpoints; - rpoints = npoints >= 4096 ? 4096 : npoints; - } + npoints -= rpoints; + rpoints = npoints >= 4096 ? 4096 : npoints; + } - free(f); - return 1; + free(f); + return 1; } /* @@ -1127,126 +1127,126 @@ are added to the array in the vpolygons. int lwReader::lwGetLWOBPolygons( vpolygons &polygons, int ptoffset ) { - lwPolygon *polygon; + lwPolygon *polygon; - char *buf, *bp; - int i, j, k, nv, nvertices, npolygons; + char *buf, *bp; + int i, j, k, nv, nvertices, npolygons; - if ( chunksize == 0 ) return 1; + if ( chunksize == 0 ) return 1; - /* read the whole chunk */ + /* read the whole chunk */ - flen = 0; - buf = getbytes( chunksize ); - if ( !buf ) goto Fail; + flen = 0; + buf = getbytes( chunksize ); + if ( !buf ) goto Fail; - /* count the polygons and vertices */ + /* count the polygons and vertices */ - nvertices = 0; - npolygons = 0; - bp = buf; + nvertices = 0; + npolygons = 0; + bp = buf; - while ( bp < buf + chunksize ) - { - nv = sgetU2( &bp ); - nvertices += nv; - npolygons++; - bp += 2 * nv; - i = sgetI2( &bp ); - if ( i < 0 ) bp += 2; /* detail polygons */ - } + while ( bp < buf + chunksize ) + { + nv = sgetU2( &bp ); + nvertices += nv; + npolygons++; + bp += 2 * nv; + i = sgetI2( &bp ); + if ( i < 0 ) bp += 2; /* detail polygons */ + } - k = 0; - bp = buf; + k = 0; + bp = buf; - for ( i = 0; i < npolygons; i++ ) - { - polygon = new lwPolygon; - nv = sgetU2( &bp ); + for ( i = 0; i < npolygons; i++ ) + { + polygon = new lwPolygon; + nv = sgetU2( &bp ); - polygon->type = ID_FACE; - for ( j = 0; j < nv; j++ ) - polygon->vertices.push_back(new lwVertex(sgetU2( &bp ) + ptoffset)); + polygon->type = ID_FACE; + for ( j = 0; j < nv; j++ ) + polygon->vertices.push_back(new lwVertex(sgetU2( &bp ) + ptoffset)); - j = sgetI2( &bp ); - if ( j < 0 ) { - j = -j; - bp += 2; - } - j -= 1; + j = sgetI2( &bp ); + if ( j < 0 ) { + j = -j; + bp += 2; + } + j -= 1; - polygon->surfidx = j; - polygons.push_back(polygon); - } + polygon->surfidx = j; + polygons.push_back(polygon); + } - free(buf); - return 1; + free(buf); + return 1; Fail: - free(buf); - return 0; + free(buf); + return 0; } int lwReader::lwGetPolygons( vpolygons &polygons, int ptoffset ) { - lwPolygon *polygon; - char *buf, *bp; - - int i, j, flags, nv, nvertices, npolygons; - unsigned int type; - - if ( chunksize == 0 ) return 1; - - /* read the whole chunk */ - - flen = 0; - type = getU4(); - buf = getbytes( chunksize - 4 ); - if ( chunksize != flen ) goto Fail; - - /* count the polygons and vertices */ - - nvertices = 0; - npolygons = 0; - bp = buf; - - while ( bp < buf + chunksize - 4 ) - { - nv = sgetU2( &bp ); - nv &= 0x03FF; - nvertices += nv; - npolygons++; - for ( i = 0; i < nv; i++ ) - j = sgetVX( &bp ); - } - - /* fill in the new polygons */ - - bp = buf; - - for ( i = 0; i < npolygons; i++ ) - { - nv = sgetU2( &bp ); - flags = nv & 0xFC00; - nv &= 0x03FF; - - polygon = new lwPolygon; - - polygon->flags = flags; - polygon->type = type; - - for (j = 0; j < nv; j++ ) - polygon->vertices.push_back(new lwVertex( sgetVX( &bp ) + ptoffset )); - - polygons.push_back(polygon); - } - - free(buf); - return 1; - + lwPolygon *polygon; + char *buf, *bp; + + int i, j, flags, nv, nvertices, npolygons; + unsigned int type; + + if ( chunksize == 0 ) return 1; + + /* read the whole chunk */ + + flen = 0; + type = getU4(); + buf = getbytes( chunksize - 4 ); + if ( chunksize != flen ) goto Fail; + + /* count the polygons and vertices */ + + nvertices = 0; + npolygons = 0; + bp = buf; + + while ( bp < buf + chunksize - 4 ) + { + nv = sgetU2( &bp ); + nv &= 0x03FF; + nvertices += nv; + npolygons++; + for ( i = 0; i < nv; i++ ) + j = sgetVX( &bp ); + } + + /* fill in the new polygons */ + + bp = buf; + + for ( i = 0; i < npolygons; i++ ) + { + nv = sgetU2( &bp ); + flags = nv & 0xFC00; + nv &= 0x03FF; + + polygon = new lwPolygon; + + polygon->flags = flags; + polygon->type = type; + + for (j = 0; j < nv; j++ ) + polygon->vertices.push_back(new lwVertex( sgetVX( &bp ) + ptoffset )); + + polygons.push_back(polygon); + } + + free(buf); + return 1; + Fail: - free(buf); - return 0; + free(buf); + return 0; } /* @@ -1259,22 +1259,22 @@ lwGetTags() int lwReader::lwGetTags( vtags &tags ) { - char *buf, *bp; - - if ( chunksize == 0 ) return 1; - - /* read the whole chunk */ - - flen = 0; - buf = getbytes( chunksize ); - if ( !buf ) return 0; - - bp = buf; - while ( bp < buf + chunksize ) - tags.push_back( sgetS0( &bp )); - - free(buf); - return 1; + char *buf, *bp; + + if ( chunksize == 0 ) return 1; + + /* read the whole chunk */ + + flen = 0; + buf = getbytes( chunksize ); + if ( !buf ) return 0; + + bp = buf; + while ( bp < buf + chunksize ) + tags.push_back( sgetS0( &bp )); + + free(buf); + return 1; } @@ -1287,63 +1287,63 @@ lwGetPolygonTags() int lwReader::lwGetPolygonTags( vtags &tags, int tagsoffset, vpolygons &polygons, int polygonsoffset ) { - unsigned int type; - unsigned int rlen; - int i, j; - - flen = 0; - type = getU4(); - rlen = flen; - if ( rlen < 0 ) return 0; - - if ( type != ID_SURF && type != ID_PART && type != ID_SMGP ) { - is->seekg(chunksize - 4, ios_base::cur ); - return 1; - } - - switch ( type ) - { - case ID_SURF: - while ( rlen < chunksize ) - { - i = getVX() + polygonsoffset; - j = getVX() + tagsoffset; - - rlen = flen; - if ( rlen < 0 || rlen > chunksize ) return 0; - - polygons[ i ]->surface = 0; - polygons[ i ]->surfidx = j; - } - break; - case ID_PART: - while ( rlen < chunksize ) - { - i = getVX() + polygonsoffset; - j = getVX() + tagsoffset; - rlen = flen; - if ( rlen < 0 || rlen > chunksize ) return 0; - - polygons[ i ]->part = j; - - } - break; - case ID_SMGP: - while ( rlen < chunksize ) - { - i = getVX() + polygonsoffset; - j = getVX() + tagsoffset; - rlen = flen; - if ( rlen < 0 || rlen > chunksize ) return 0; - - polygons[ i ]->smoothgrp = j; - - } - break; - } - - - return 1; + unsigned int type; + unsigned int rlen; + int i, j; + + flen = 0; + type = getU4(); + rlen = flen; + if ( rlen < 0 ) return 0; + + if ( type != ID_SURF && type != ID_PART && type != ID_SMGP ) { + is->seekg(chunksize - 4, ios_base::cur ); + return 1; + } + + switch ( type ) + { + case ID_SURF: + while ( rlen < chunksize ) + { + i = getVX() + polygonsoffset; + j = getVX() + tagsoffset; + + rlen = flen; + if ( rlen < 0 || rlen > chunksize ) return 0; + + polygons[ i ]->surface = 0; + polygons[ i ]->surfidx = j; + } + break; + case ID_PART: + while ( rlen < chunksize ) + { + i = getVX() + polygonsoffset; + j = getVX() + tagsoffset; + rlen = flen; + if ( rlen < 0 || rlen > chunksize ) return 0; + + polygons[ i ]->part = j; + + } + break; + case ID_SMGP: + while ( rlen < chunksize ) + { + i = getVX() + polygonsoffset; + j = getVX() + tagsoffset; + rlen = flen; + if ( rlen < 0 || rlen > chunksize ) return 0; + + polygons[ i ]->smoothgrp = j; + + } + break; + } + + + return 1; } /* @@ -1358,88 +1358,88 @@ lwGetTHeader() int lwReader::lwGetTHeader( int hsz, lwTexture &tex ) { - unsigned int id; - unsigned short sz; - int pos, rlen; - - /* remember where we started */ - - flen = 0; - pos = is->tellg(); - - /* ordinal string */ - - tex.ord = getS0(); - - /* first subchunk header */ - - id = getU4(); - sz = getU2(); - if ( 0 > flen ) return 0; - - /* process subchunks as they're encountered */ - - for (;;) { - sz += sz & 1; - flen = 0; - - switch ( id ) { - case ID_CHAN: - tex.chan = getU4(); - break; - - case ID_OPAC: - tex.opac_type = getU2(); - tex.opacity.val = getF4(); - tex.opacity.eindex = getVX(); - break; - - case ID_ENAB: - tex.enabled = getU2(); - break; - - case ID_NEGA: - tex.negative = getU2(); - break; - - case ID_AXIS: - tex.axis = getU2(); - break; - - default: - break; - } - - /* error while reading current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) return 0; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the texture header subchunk? */ - - int fpos = is->tellg(); - if ( fpos == -1 ) break; - if ( hsz + pos <= fpos ) break; - -// if ( hsz + pos <= is->tellg()) -// break; - - /* get the next subchunk header */ - - flen = 0; - id = getU4(); - sz = getU2(); - if ( 6 != flen ) return 0; - }; - - int g = is->tellg(); - flen = g - pos; - return 1; + unsigned int id; + unsigned short sz; + int pos, rlen; + + /* remember where we started */ + + flen = 0; + pos = is->tellg(); + + /* ordinal string */ + + tex.ord = getS0(); + + /* first subchunk header */ + + id = getU4(); + sz = getU2(); + if ( 0 > flen ) return 0; + + /* process subchunks as they're encountered */ + + for (;;) { + sz += sz & 1; + flen = 0; + + switch ( id ) { + case ID_CHAN: + tex.chan = getU4(); + break; + + case ID_OPAC: + tex.opac_type = getU2(); + tex.opacity.val = getF4(); + tex.opacity.eindex = getVX(); + break; + + case ID_ENAB: + tex.enabled = getU2(); + break; + + case ID_NEGA: + tex.negative = getU2(); + break; + + case ID_AXIS: + tex.axis = getU2(); + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) return 0; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the texture header subchunk? */ + + int fpos = is->tellg(); + if ( fpos == -1 ) break; + if ( hsz + pos <= fpos ) break; + +// if ( hsz + pos <= is->tellg()) +// break; + + /* get the next subchunk header */ + + flen = 0; + id = getU4(); + sz = getU2(); + if ( 6 != flen ) return 0; + }; + + int g = is->tellg(); + flen = g - pos; + return 1; } /*====================================================================== @@ -1451,86 +1451,86 @@ lwGetTMap() int lwReader::lwGetTMap( int tmapsz, lwTMap &tmap ) { - unsigned int id; - unsigned short sz; - int rlen, pos, i; - - pos = is->tellg(); - id = getU4(); - sz = getU2(); - if ( 0 > flen ) return 0; - - for (;;) { - sz += sz & 1; - flen = 0; - - switch ( id ) { - case ID_SIZE: - for ( i = 0; i < 3; i++ ) - tmap.size.val[ i ] = getF4(); - tmap.size.eindex = getVX(); - break; - - case ID_CNTR: - for ( i = 0; i < 3; i++ ) - tmap.center.val[ i ] = getF4(); - tmap.center.eindex = getVX(); - break; - - case ID_ROTA: - for ( i = 0; i < 3; i++ ) - tmap.rotate.val[ i ] = getF4(); - tmap.rotate.eindex = getVX(); - break; - - case ID_FALL: - tmap.fall_type = getU2(); - for ( i = 0; i < 3; i++ ) - tmap.falloff.val[ i ] = getF4(); - tmap.falloff.eindex = getVX(); - break; - - case ID_OREF: - tmap.ref_object = getS0(); - break; - - case ID_CSYS: - tmap.coord_sys = getU2(); - break; - - default: - break; - } - - /* error while reading the current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) return 0; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the TMAP subchunk? */ - int fpos = is->tellg(); - if ( fpos == -1 ) break; - if ( tmapsz + pos <= fpos ) break; - -// if ( tmapsz + pos <= is->tellg() ) -// break; - - /* get the next subchunk header */ - - flen = 0; - id = getU4(); - sz = getU2(); - if ( 6 != flen ) return 0; - }; - - int g = is->tellg(); - flen = g - pos; - return 1; + unsigned int id; + unsigned short sz; + int rlen, pos, i; + + pos = is->tellg(); + id = getU4(); + sz = getU2(); + if ( 0 > flen ) return 0; + + for (;;) { + sz += sz & 1; + flen = 0; + + switch ( id ) { + case ID_SIZE: + for ( i = 0; i < 3; i++ ) + tmap.size.val[ i ] = getF4(); + tmap.size.eindex = getVX(); + break; + + case ID_CNTR: + for ( i = 0; i < 3; i++ ) + tmap.center.val[ i ] = getF4(); + tmap.center.eindex = getVX(); + break; + + case ID_ROTA: + for ( i = 0; i < 3; i++ ) + tmap.rotate.val[ i ] = getF4(); + tmap.rotate.eindex = getVX(); + break; + + case ID_FALL: + tmap.fall_type = getU2(); + for ( i = 0; i < 3; i++ ) + tmap.falloff.val[ i ] = getF4(); + tmap.falloff.eindex = getVX(); + break; + + case ID_OREF: + tmap.ref_object = getS0(); + break; + + case ID_CSYS: + tmap.coord_sys = getU2(); + break; + + default: + break; + } + + /* error while reading the current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) return 0; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the TMAP subchunk? */ + int fpos = is->tellg(); + if ( fpos == -1 ) break; + if ( tmapsz + pos <= fpos ) break; + +// if ( tmapsz + pos <= is->tellg() ) +// break; + + /* get the next subchunk header */ + + flen = 0; + id = getU4(); + sz = getU2(); + if ( 6 != flen ) return 0; + }; + + int g = is->tellg(); + flen = g - pos; + return 1; } /*====================================================================== @@ -1541,111 +1541,111 @@ Read an lwImageMap from a SURF.BLOK in an LWO2 file. lwImageMap *lwReader::lwGetImageMap( int rsz, lwTexture &tex ) { - unsigned int id; - unsigned short sz; - int rlen, pos; - - pos = is->tellg(); - id = getU4(); - sz = getU2(); - if ( 0 > flen ) return 0; - - lwImageMap *imap = new lwImageMap; - if (!imap) return NULL; - - for (;;) { - sz += sz & 1; - flen = 0; - - switch ( id ) { - case ID_TMAP: - if ( !lwGetTMap( sz, tex.tmap )) return 0; - break; - - case ID_PROJ: - imap->projection = getU2(); - break; - - case ID_VMAP: - imap->vmap_name = getS0(); - break; - - case ID_AXIS: - imap->axis = getU2(); - break; - - case ID_IMAG: - imap->cindex = getVX(); - break; - - case ID_WRAP: - imap->wrapw_type = getU2(); - imap->wraph_type = getU2(); - break; - - case ID_WRPW: - imap->wrapw.val = getF4(); - imap->wrapw.eindex = getVX(); - break; - - case ID_WRPH: - imap->wraph.val = getF4(); - imap->wraph.eindex = getVX(); - break; - - case ID_AAST: - imap->aas_flags = getU2(); - imap->aa_strength = getF4(); - break; - - case ID_PIXB: - imap->pblend = getU2(); - break; - - case ID_STCK: - imap->stck.val = getF4(); - imap->stck.eindex = getVX(); - break; - - case ID_TAMP: - imap->amplitude.val = getF4(); - imap->amplitude.eindex = getVX(); - break; - - default: - break; - } - - /* error while reading the current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) return 0; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the image map? */ - - int fpos = is->tellg(); - if ( fpos == -1 ) break; - if ( rsz + pos <= fpos ) break; - -// if ( rsz + pos <= is->tellg() ) -// break; - - /* get the next subchunk header */ - - flen = 0; - id = getU4(); - sz = getU2(); - if ( 6 != flen ) return 0; - }; - - int g = is->tellg(); - flen = g - pos; - return imap; + unsigned int id; + unsigned short sz; + int rlen, pos; + + pos = is->tellg(); + id = getU4(); + sz = getU2(); + if ( 0 > flen ) return 0; + + lwImageMap *imap = new lwImageMap; + if (!imap) return NULL; + + for (;;) { + sz += sz & 1; + flen = 0; + + switch ( id ) { + case ID_TMAP: + if ( !lwGetTMap( sz, tex.tmap )) return 0; + break; + + case ID_PROJ: + imap->projection = getU2(); + break; + + case ID_VMAP: + imap->vmap_name = getS0(); + break; + + case ID_AXIS: + imap->axis = getU2(); + break; + + case ID_IMAG: + imap->cindex = getVX(); + break; + + case ID_WRAP: + imap->wrapw_type = getU2(); + imap->wraph_type = getU2(); + break; + + case ID_WRPW: + imap->wrapw.val = getF4(); + imap->wrapw.eindex = getVX(); + break; + + case ID_WRPH: + imap->wraph.val = getF4(); + imap->wraph.eindex = getVX(); + break; + + case ID_AAST: + imap->aas_flags = getU2(); + imap->aa_strength = getF4(); + break; + + case ID_PIXB: + imap->pblend = getU2(); + break; + + case ID_STCK: + imap->stck.val = getF4(); + imap->stck.eindex = getVX(); + break; + + case ID_TAMP: + imap->amplitude.val = getF4(); + imap->amplitude.eindex = getVX(); + break; + + default: + break; + } + + /* error while reading the current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) return 0; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the image map? */ + + int fpos = is->tellg(); + if ( fpos == -1 ) break; + if ( rsz + pos <= fpos ) break; + +// if ( rsz + pos <= is->tellg() ) +// break; + + /* get the next subchunk header */ + + flen = 0; + id = getU4(); + sz = getU2(); + if ( 6 != flen ) return 0; + }; + + int g = is->tellg(); + flen = g - pos; + return imap; } @@ -1659,84 +1659,84 @@ Read an lwProcedural from a SURF.BLOK in an LWO2 file. lwProcedural *lwReader::lwGetProcedural( int rsz, lwTexture &tex ) { - unsigned int id; - unsigned short sz; - int rlen, pos, fpos; - - pos = is->tellg(); - id = getU4(); - sz = getU2(); - if ( 0 > flen ) return 0; - - lwProcedural *proc = new lwProcedural; - if (!proc) return NULL; - - for (;;) { - sz += sz & 1; - flen = 0; - - switch ( id ) { - case ID_TMAP: - if ( !lwGetTMap( sz, tex.tmap )) return 0; - break; - - case ID_AXIS: - proc->axis = getU2(); - break; - - case ID_VALU: - proc->value[ 0 ] = getF4(); - if ( sz >= 8 ) proc->value[ 1 ] = getF4(); - if ( sz >= 12 ) proc->value[ 2 ] = getF4(); - break; - - case ID_FUNC: - proc->name = getS0(); - rlen = flen; - proc->data = getbytes( sz - rlen ); - break; - - default: - break; - } - - /* error while reading the current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) return 0; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the procedural block? */ - - fpos = is->tellg(); - - if (fpos == -1) - { - flen = -pos; - return proc; - } - - if ( rsz + pos <= fpos ) - break; - - // if ( rsz + pos <= is->tellg()) - // break; - - /* get the next subchunk header */ - - flen = 0; - id = getU4(); - sz = getU2(); - if ( 6 != flen ) return 0; - }; - - int g = is->tellg(); - flen = g - pos; - return proc; + unsigned int id; + unsigned short sz; + int rlen, pos, fpos; + + pos = is->tellg(); + id = getU4(); + sz = getU2(); + if ( 0 > flen ) return 0; + + lwProcedural *proc = new lwProcedural; + if (!proc) return NULL; + + for (;;) { + sz += sz & 1; + flen = 0; + + switch ( id ) { + case ID_TMAP: + if ( !lwGetTMap( sz, tex.tmap )) return 0; + break; + + case ID_AXIS: + proc->axis = getU2(); + break; + + case ID_VALU: + proc->value[ 0 ] = getF4(); + if ( sz >= 8 ) proc->value[ 1 ] = getF4(); + if ( sz >= 12 ) proc->value[ 2 ] = getF4(); + break; + + case ID_FUNC: + proc->name = getS0(); + rlen = flen; + proc->data = getbytes( sz - rlen ); + break; + + default: + break; + } + + /* error while reading the current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) return 0; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the procedural block? */ + + fpos = is->tellg(); + + if (fpos == -1) + { + flen = -pos; + return proc; + } + + if ( rsz + pos <= fpos ) + break; + + // if ( rsz + pos <= is->tellg()) + // break; + + /* get the next subchunk header */ + + flen = 0; + id = getU4(); + sz = getU2(); + if ( 6 != flen ) return 0; + }; + + int g = is->tellg(); + flen = g - pos; + return proc; } @@ -1749,100 +1749,100 @@ Read an lwGradient from a SURF.BLOK in an LWO2 file. lwGradient *lwReader::lwGetGradient( int rsz, lwTexture &tex ) { - unsigned int id; - unsigned short sz; - int rlen, pos, i, j, nkeys; - - pos = is->tellg(); - id = getU4(); - sz = getU2(); - if ( 0 > flen ) return 0; - - lwGradient *grad = new lwGradient; - if (!grad) return NULL; - - for (;;) { - sz += sz & 1; - flen = 0; - - switch ( id ) { - case ID_TMAP: - if ( !lwGetTMap( sz, tex.tmap )) return 0; - break; - - case ID_PNAM: - grad->paramname = getS0(); - break; - - case ID_INAM: - grad->itemname = getS0(); - break; - - case ID_GRST: - grad->start = getF4(); - break; - - case ID_GREN: - grad->end = getF4(); - break; - - case ID_GRPT: - grad->repeat = getU2(); - break; - - case ID_FKEY: - nkeys = sz / sizeof( lwGradKey ); - grad->key = (lwGradKey *)malloc(nkeys * sizeof(lwGradKey)); - if ( !grad->key ) return 0; - for ( i = 0; i < nkeys; i++ ) { - grad->key[ i ].value = getF4(); - for ( j = 0; j < 4; j++ ) - grad->key[ i ].rgba[ j ] = getF4(); - } - break; - - case ID_IKEY: - nkeys = sz / 2; - grad->ikey = (short *)malloc(nkeys * sizeof(short)); - if ( !grad->ikey ) return 0; - for ( i = 0; i < nkeys; i++ ) - grad->ikey[ i ] = getU2(); - break; - - default: - break; - } - - /* error while reading the current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) return 0; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the gradient? */ - - int fpos = is->tellg(); - if ( fpos == -1 ) break; - if ( rsz + pos <= fpos ) break; - -// if ( rsz + pos <= is->tellg() ) -// break; - - /* get the next subchunk header */ - - flen = 0; - id = getU4(); - sz = getU2(); - if ( 6 != flen ) return 0; - }; - - int g = is->tellg(); - flen = g - pos; - return grad; + unsigned int id; + unsigned short sz; + int rlen, pos, i, j, nkeys; + + pos = is->tellg(); + id = getU4(); + sz = getU2(); + if ( 0 > flen ) return 0; + + lwGradient *grad = new lwGradient; + if (!grad) return NULL; + + for (;;) { + sz += sz & 1; + flen = 0; + + switch ( id ) { + case ID_TMAP: + if ( !lwGetTMap( sz, tex.tmap )) return 0; + break; + + case ID_PNAM: + grad->paramname = getS0(); + break; + + case ID_INAM: + grad->itemname = getS0(); + break; + + case ID_GRST: + grad->start = getF4(); + break; + + case ID_GREN: + grad->end = getF4(); + break; + + case ID_GRPT: + grad->repeat = getU2(); + break; + + case ID_FKEY: + nkeys = sz / sizeof( lwGradKey ); + grad->key = (lwGradKey *)malloc(nkeys * sizeof(lwGradKey)); + if ( !grad->key ) return 0; + for ( i = 0; i < nkeys; i++ ) { + grad->key[ i ].value = getF4(); + for ( j = 0; j < 4; j++ ) + grad->key[ i ].rgba[ j ] = getF4(); + } + break; + + case ID_IKEY: + nkeys = sz / 2; + grad->ikey = (short *)malloc(nkeys * sizeof(short)); + if ( !grad->ikey ) return 0; + for ( i = 0; i < nkeys; i++ ) + grad->ikey[ i ] = getU2(); + break; + + default: + break; + } + + /* error while reading the current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) return 0; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the gradient? */ + + int fpos = is->tellg(); + if ( fpos == -1 ) break; + if ( rsz + pos <= fpos ) break; + +// if ( rsz + pos <= is->tellg() ) +// break; + + /* get the next subchunk header */ + + flen = 0; + id = getU4(); + sz = getU2(); + if ( 6 != flen ) return 0; + }; + + int g = is->tellg(); + flen = g - pos; + return grad; } @@ -1855,47 +1855,47 @@ Read an lwTexture from a SURF.BLOK in an LWO2 file. lwTexture *lwReader::lwGetTexture( int bloksz, unsigned int type ) { - lwTexture *tex; - unsigned short sz; - bool ok; - - tex = new lwTexture; - if ( !tex ) return NULL; - - tex->type = type; - - sz = getU2(); - if ( !lwGetTHeader( sz, *tex )) { - delete tex; - return NULL; - } - - sz = bloksz - sz - 6; - switch ( type ) { - case ID_IMAP: - tex->param.imap = lwGetImageMap( sz, *tex ); - ok = tex->param.imap!=0; - break; - case ID_PROC: - tex->param.proc = lwGetProcedural( sz, *tex ); - ok = tex->param.proc!=0; - break; - case ID_GRAD: - tex->param.grad = lwGetGradient( sz, *tex ); - ok = tex->param.grad!=0; - break; - default: - ok = !is->seekg(sz, ios_base::cur ); - } - - if ( !ok ) - { - delete tex; - return NULL; - } - - flen = bloksz; - return tex; + lwTexture *tex; + unsigned short sz; + bool ok; + + tex = new lwTexture; + if ( !tex ) return NULL; + + tex->type = type; + + sz = getU2(); + if ( !lwGetTHeader( sz, *tex )) { + delete tex; + return NULL; + } + + sz = bloksz - sz - 6; + switch ( type ) { + case ID_IMAP: + tex->param.imap = lwGetImageMap( sz, *tex ); + ok = tex->param.imap!=0; + break; + case ID_PROC: + tex->param.proc = lwGetProcedural( sz, *tex ); + ok = tex->param.proc!=0; + break; + case ID_GRAD: + tex->param.grad = lwGetGradient( sz, *tex ); + ok = tex->param.grad!=0; + break; + default: + ok = !is->seekg(sz, ios_base::cur ); + } + + if ( !ok ) + { + delete tex; + return NULL; + } + + flen = bloksz; + return tex; } /* @@ -1907,93 +1907,93 @@ Read a shader record from a SURF.BLOK in an LWO2 file. lwPlugin *lwReader::lwGetShader( int bloksz ) { - lwPlugin *shdr; - unsigned int id; - unsigned short sz; - int hsz, rlen, pos; - int g = 0; - - shdr = new lwPlugin; - if ( !shdr ) return NULL; - - pos = is->tellg(); - flen = 0; - hsz = getU2(); - shdr->ord = getS0(); - id = getU4(); - sz = getU2(); - if ( 0 > flen ) goto Fail; - - while ( hsz > 0 ) - { - sz += sz & 1; - hsz -= sz; - if ( id == ID_ENAB ) { - shdr->flags = getU2(); - break; - } - else { - is->seekg(sz, ios_base::cur ); - id = getU4(); - sz = getU2(); - } - } - - id = getU4(); - sz = getU2(); - if ( 0 > flen ) goto Fail; - - for (;;) - { - sz += sz & 1; - flen = 0; - - switch ( id ) { - case ID_FUNC: - shdr->name = getS0(); - rlen = flen; - shdr->data = getbytes( sz - rlen ); - break; - - default: - break; - } - - /* error while reading the current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) goto Fail; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the shader block? */ - - int fpos = is->tellg(); - if ( fpos == -1 ) break; - if ( bloksz + pos <= fpos ) break; - - - // if ( bloksz + pos <= is->tellg() ) - // break; - - /* get the next subchunk header */ - - flen = 0; - id = getU4(); - sz = getU2(); - if ( 6 != flen ) goto Fail; - }; - - g = is->tellg(); - flen = g - pos; - return shdr; - + lwPlugin *shdr; + unsigned int id; + unsigned short sz; + int hsz, rlen, pos; + int g = 0; + + shdr = new lwPlugin; + if ( !shdr ) return NULL; + + pos = is->tellg(); + flen = 0; + hsz = getU2(); + shdr->ord = getS0(); + id = getU4(); + sz = getU2(); + if ( 0 > flen ) goto Fail; + + while ( hsz > 0 ) + { + sz += sz & 1; + hsz -= sz; + if ( id == ID_ENAB ) { + shdr->flags = getU2(); + break; + } + else { + is->seekg(sz, ios_base::cur ); + id = getU4(); + sz = getU2(); + } + } + + id = getU4(); + sz = getU2(); + if ( 0 > flen ) goto Fail; + + for (;;) + { + sz += sz & 1; + flen = 0; + + switch ( id ) { + case ID_FUNC: + shdr->name = getS0(); + rlen = flen; + shdr->data = getbytes( sz - rlen ); + break; + + default: + break; + } + + /* error while reading the current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the shader block? */ + + int fpos = is->tellg(); + if ( fpos == -1 ) break; + if ( bloksz + pos <= fpos ) break; + + + // if ( bloksz + pos <= is->tellg() ) + // break; + + /* get the next subchunk header */ + + flen = 0; + id = getU4(); + sz = getU2(); + if ( 6 != flen ) goto Fail; + }; + + g = is->tellg(); + flen = g - pos; + return shdr; + Fail: - delete shdr; - return NULL; + delete shdr; + return NULL; } /*====================================================================== @@ -2005,33 +2005,33 @@ TIMG surface subchunk. int lwReader::add_clip( char *s, vclips &clips ) { - lwClip *clip; - char *p; - - clip = new lwClip; - if ( !clip ) return 0; - - if ( p = strstr( s, "(sequence)" )) - { - p[ -1 ] = 0; - clip->type = ID_ISEQ; - lwClipSeq *seq = new lwClipSeq; - seq->prefix = s; - seq->digits = 3; - clip->source.seq = seq; - } - else - { - clip->type = ID_STIL; - lwClipStill *still = new lwClipStill; - still->name = s; - clip->source.still = still; - } - - clips.push_back( clip ); - clip->index = clips.size()-1; - - return clip->index; + lwClip *clip; + char *p; + + clip = new lwClip; + if ( !clip ) return 0; + + if ( p = strstr( s, "(sequence)" )) + { + p[ -1 ] = 0; + clip->type = ID_ISEQ; + lwClipSeq *seq = new lwClipSeq; + seq->prefix = s; + seq->digits = 3; + clip->source.seq = seq; + } + else + { + clip->type = ID_STIL; + lwClipStill *still = new lwClipStill; + still->name = s; + clip->source.still = still; + } + + clips.push_back( clip ); + clip->index = clips.size()-1; + + return clip->index; } @@ -2044,36 +2044,36 @@ parameters. int lwReader::add_tvel( float pos[], float vel[], venvelopes &envelopes ) { - lwEnvelope *env; - lwKey *key0, *key1; - int i; - - for ( i = 0; i < 3; i++ ) - { - env = new lwEnvelope; - key0 = new lwKey(0.0f, pos[ i ]); - key1 = new lwKey(1.0f, pos[ i ] + vel[ i ] * 30.0f); // 30.0f == NTSC related ? - - key0->shape = key1->shape = ID_LINE; - - env->keys.push_back( key0 ); - env->keys.push_back( key1 ); - - env->type = 0x0301 + i; - env->name = (char *)malloc(11); - if ( env->name ) - { - strcpy( env->name, "Position.X" ); - env->name[ 9 ] += i; - } - - env->behavior[ 0 ] = BEH_LINEAR; - env->behavior[ 1 ] = BEH_LINEAR; - - envelopes.push_back( env ); - env->index = envelopes.size()-1; - } - return env->index - 2; + lwEnvelope *env; + lwKey *key0, *key1; + int i; + + for ( i = 0; i < 3; i++ ) + { + env = new lwEnvelope; + key0 = new lwKey(0.0f, pos[ i ]); + key1 = new lwKey(1.0f, pos[ i ] + vel[ i ] * 30.0f); // 30.0f == NTSC related ? + + key0->shape = key1->shape = ID_LINE; + + env->keys.push_back( key0 ); + env->keys.push_back( key1 ); + + env->type = 0x0301 + i; + env->name = (char *)malloc(11); + if ( env->name ) + { + strcpy( env->name, "Position.X" ); + env->name[ 9 ] += i; + } + + env->behavior[ 0 ] = BEH_LINEAR; + env->behavior[ 1 ] = BEH_LINEAR; + + envelopes.push_back( env ); + env->index = envelopes.size()-1; + } + return env->index - 2; } @@ -2085,320 +2085,320 @@ Create a new texture for BTEX, CTEX, etc. subchunks. lwTexture *lwReader::get_texture( char *s ) { - lwTexture *tex = new lwTexture; - if ( !tex ) return NULL; - - if ( strstr( s, "Image Map" )) - { - tex->type = ID_IMAP; - lwImageMap *imap = new lwImageMap; - tex->param.imap = imap; - if ( strstr( s, "Planar" )) imap->projection = 0; - else if ( strstr( s, "Cylindrical" )) imap->projection = 1; - else if ( strstr( s, "Spherical" )) imap->projection = 2; - else if ( strstr( s, "Cubic" )) imap->projection = 3; - else if ( strstr( s, "Front" )) imap->projection = 4; - imap->aa_strength = 1.0f; - imap->amplitude.val = 1.0f; - free(s); - } - else - { - tex->type = ID_PROC; - lwProcedural *proc = new lwProcedural; - tex->param.proc = proc; - proc->name = s; - } - return tex; + lwTexture *tex = new lwTexture; + if ( !tex ) return NULL; + + if ( strstr( s, "Image Map" )) + { + tex->type = ID_IMAP; + lwImageMap *imap = new lwImageMap; + tex->param.imap = imap; + if ( strstr( s, "Planar" )) imap->projection = 0; + else if ( strstr( s, "Cylindrical" )) imap->projection = 1; + else if ( strstr( s, "Spherical" )) imap->projection = 2; + else if ( strstr( s, "Cubic" )) imap->projection = 3; + else if ( strstr( s, "Front" )) imap->projection = 4; + imap->aa_strength = 1.0f; + imap->amplitude.val = 1.0f; + free(s); + } + else + { + tex->type = ID_PROC; + lwProcedural *proc = new lwProcedural; + tex->param.proc = proc; + proc->name = s; + } + return tex; } lwSurface *lwReader::lwGetLWOBSurface( lwObject *obj ) { - lwTexture *tex = 0; - lwPlugin *shdr = 0; - char *s; - float v[ 3 ]; - unsigned int flags; - unsigned short sz; - int rlen, i; - - long filepos = is->tellg(); - long chunkstart = filepos; - long chunkend = chunkstart + chunksize; - - /* allocate the Surface structure */ - - lwSurface *surf = new lwSurface; - if ( !surf ) return NULL; - - /* name */ - - surf->name = getS0(); - - /* process subchunks as they're encountered */ - filepos = is->tellg(); - if (filepos == -1) return surf; - if ( filepos > chunkend ) return surf; // error: read too much - - while( filepos < chunkend ) - { - currentchunkid = getU4(); - sz = getU2(); - sz += sz & 1; - flen = 0; - - switch ( currentchunkid ) - { - case ID_COLR: - surf->color.rgb[ 0 ] = getU1() / 255.0f; - surf->color.rgb[ 1 ] = getU1() / 255.0f; - surf->color.rgb[ 2 ] = getU1() / 255.0f; - break; - - case ID_FLAG: - flags = getU2(); - if ( flags & 4 ) surf->smooth = 1.56207f; - if ( flags & 8 ) surf->color_hilite.val = 1.0f; - if ( flags & 16 ) surf->color_filter.val = 1.0f; - if ( flags & 128 ) surf->dif_sharp.val = 0.5f; - if ( flags & 256 ) surf->sideflags = 3; - if ( flags & 512 ) surf->add_trans.val = 1.0f; - break; - - case ID_LUMI: - surf->luminosity.val = getI2() / 256.0f; - break; - - case ID_VLUM: - surf->luminosity.val = getF4(); - break; - - case ID_DIFF: - surf->diffuse.val = getI2() / 256.0f; - break; - - case ID_VDIF: - surf->diffuse.val = getF4(); - break; - - case ID_SPEC: - surf->specularity.val = getI2() / 256.0f; - break; - - case ID_VSPC: - surf->specularity.val = getF4(); - break; - - case ID_GLOS: - surf->glossiness.val = (float)log((double)getU2()) / 20.7944f; - break; - - case ID_SMAN: - surf->smooth = getF4(); - break; - - case ID_REFL: - surf->reflection.val.val = getI2() / 256.0f; - break; - - case ID_RFLT: - surf->reflection.options = getU2(); - break; - - case ID_RIMG: - s = getS0(); - surf->reflection.cindex = add_clip( s, obj->clips ); - surf->reflection.options = 3; - break; - - case ID_RSAN: - surf->reflection.seam_angle = getF4(); - break; - - case ID_TRAN: - surf->transparency.val.val = getI2() / 256.0f; - break; - - case ID_RIND: - surf->eta.val = getF4(); - break; - - case ID_BTEX: - s = getbytes( sz ); - tex = get_texture( s ); - surf->bump.textures.push_back( tex ); - break; - - case ID_CTEX: - s = getbytes( sz ); - tex = get_texture( s ); - surf->color.textures.push_back( tex ); - break; - - case ID_DTEX: - s = getbytes( sz ); - tex = get_texture( s ); - surf->diffuse.textures.push_back( tex ); - break; - - case ID_LTEX: - s = getbytes( sz ); - tex = get_texture( s ); - surf->luminosity.textures.push_back( tex ); - break; - - case ID_RTEX: - s = getbytes( sz ); - tex = get_texture( s ); - surf->reflection.val.textures.push_back( tex ); - break; - - case ID_STEX: - s = getbytes( sz ); - tex = get_texture( s ); - surf->specularity.textures.push_back( tex ); - break; - - case ID_TTEX: - s = getbytes( sz ); - tex = get_texture( s ); - surf->transparency.val.textures.push_back( tex ); - break; - - case ID_TFLG: - flags = getU2(); - - if ( flags & 1 ) i = 0; - if ( flags & 2 ) i = 1; - if ( flags & 4 ) i = 2; - tex->axis = i; - if ( tex->type == ID_IMAP ) - { - tex->param.imap->axis = i; - if ( flags & 32 ) - tex->param.imap->pblend = 1; - if ( flags & 64 ) - { - tex->param.imap->aa_strength = 1.0f; - tex->param.imap->aas_flags = 1; - } - } - if ( tex->type == ID_PROC ) - tex->param.proc->axis = i; - - if ( flags & 8 ) tex->tmap.coord_sys = 1; - if ( flags & 16 ) tex->negative = 1; - break; - - case ID_TSIZ: - for ( i = 0; i < 3; i++ ) - tex->tmap.size.val[ i ] = getF4(); - break; - - case ID_TCTR: - for ( i = 0; i < 3; i++ ) - tex->tmap.center.val[ i ] = getF4(); - break; - - case ID_TFAL: - for ( i = 0; i < 3; i++ ) - tex->tmap.falloff.val[ i ] = getF4(); - break; - - case ID_TVEL: - for ( i = 0; i < 3; i++ ) - v[ i ] = getF4(); - tex->tmap.center.eindex = add_tvel( tex->tmap.center.val, v, obj->envelopes ); - break; - - case ID_TCLR: - if ( tex->type == ID_PROC ) - for ( i = 0; i < 3; i++ ) - tex->param.proc->value[ i ] = getU1() / 255.0f; - break; - - case ID_TVAL: - if ( tex->type == ID_PROC ) - tex->param.proc->value[ 0 ] = getI2() / 256.0f; - break; - - case ID_TAMP: - if ( tex->type == ID_IMAP ) - tex->param.imap->amplitude.val = getF4(); - break; - - case ID_TIMG: - if ( tex->type == ID_IMAP ) - { - s = getS0(); - tex->param.imap->cindex = add_clip( s, obj->clips ); - } - break; - - case ID_TAAS: - if ( tex->type == ID_IMAP ) - { - tex->param.imap->aa_strength = getF4(); - tex->param.imap->aas_flags = 1; - } - break; - - case ID_TREF: - tex->tmap.ref_object = getbytes( sz ); - break; - - case ID_TOPC: - tex->opacity.val = getF4(); - break; - - case ID_TFP0: - if ( tex->type == ID_IMAP ) - tex->param.imap->wrapw.val = getF4(); - break; - - case ID_TFP1: - if ( tex->type == ID_IMAP ) - tex->param.imap->wraph.val = getF4(); - break; - - case ID_SHDR: - shdr = new lwPlugin; - if ( !shdr ) goto Fail; - shdr->name = getbytes( sz ); - surf->shaders.push_back( shdr ); - break; - - case ID_SDAT: - shdr->data = getbytes( sz ); - break; - default: - break; - } - - /* error while reading current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) goto Fail; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the SURF chunk? */ - - filepos = is->tellg(); - if ( filepos == -1 ) break; // end of file ? - if ( filepos > chunkend ) // error: read too much - { - is->seekg(chunkend, ios_base::beg ); - break; - } - } - return surf; + lwTexture *tex = 0; + lwPlugin *shdr = 0; + char *s; + float v[ 3 ]; + unsigned int flags; + unsigned short sz; + int rlen, i; + + long filepos = is->tellg(); + long chunkstart = filepos; + long chunkend = chunkstart + chunksize; + + /* allocate the Surface structure */ + + lwSurface *surf = new lwSurface; + if ( !surf ) return NULL; + + /* name */ + + surf->name = getS0(); + + /* process subchunks as they're encountered */ + filepos = is->tellg(); + if (filepos == -1) return surf; + if ( filepos > chunkend ) return surf; // error: read too much + + while( filepos < chunkend ) + { + currentchunkid = getU4(); + sz = getU2(); + sz += sz & 1; + flen = 0; + + switch ( currentchunkid ) + { + case ID_COLR: + surf->color.rgb[ 0 ] = getU1() / 255.0f; + surf->color.rgb[ 1 ] = getU1() / 255.0f; + surf->color.rgb[ 2 ] = getU1() / 255.0f; + break; + + case ID_FLAG: + flags = getU2(); + if ( flags & 4 ) surf->smooth = 1.56207f; + if ( flags & 8 ) surf->color_hilite.val = 1.0f; + if ( flags & 16 ) surf->color_filter.val = 1.0f; + if ( flags & 128 ) surf->dif_sharp.val = 0.5f; + if ( flags & 256 ) surf->sideflags = 3; + if ( flags & 512 ) surf->add_trans.val = 1.0f; + break; + + case ID_LUMI: + surf->luminosity.val = getI2() / 256.0f; + break; + + case ID_VLUM: + surf->luminosity.val = getF4(); + break; + + case ID_DIFF: + surf->diffuse.val = getI2() / 256.0f; + break; + + case ID_VDIF: + surf->diffuse.val = getF4(); + break; + + case ID_SPEC: + surf->specularity.val = getI2() / 256.0f; + break; + + case ID_VSPC: + surf->specularity.val = getF4(); + break; + + case ID_GLOS: + surf->glossiness.val = (float)log((double)getU2()) / 20.7944f; + break; + + case ID_SMAN: + surf->smooth = getF4(); + break; + + case ID_REFL: + surf->reflection.val.val = getI2() / 256.0f; + break; + + case ID_RFLT: + surf->reflection.options = getU2(); + break; + + case ID_RIMG: + s = getS0(); + surf->reflection.cindex = add_clip( s, obj->clips ); + surf->reflection.options = 3; + break; + + case ID_RSAN: + surf->reflection.seam_angle = getF4(); + break; + + case ID_TRAN: + surf->transparency.val.val = getI2() / 256.0f; + break; + + case ID_RIND: + surf->eta.val = getF4(); + break; + + case ID_BTEX: + s = getbytes( sz ); + tex = get_texture( s ); + surf->bump.textures.push_back( tex ); + break; + + case ID_CTEX: + s = getbytes( sz ); + tex = get_texture( s ); + surf->color.textures.push_back( tex ); + break; + + case ID_DTEX: + s = getbytes( sz ); + tex = get_texture( s ); + surf->diffuse.textures.push_back( tex ); + break; + + case ID_LTEX: + s = getbytes( sz ); + tex = get_texture( s ); + surf->luminosity.textures.push_back( tex ); + break; + + case ID_RTEX: + s = getbytes( sz ); + tex = get_texture( s ); + surf->reflection.val.textures.push_back( tex ); + break; + + case ID_STEX: + s = getbytes( sz ); + tex = get_texture( s ); + surf->specularity.textures.push_back( tex ); + break; + + case ID_TTEX: + s = getbytes( sz ); + tex = get_texture( s ); + surf->transparency.val.textures.push_back( tex ); + break; + + case ID_TFLG: + flags = getU2(); + + if ( flags & 1 ) i = 0; + if ( flags & 2 ) i = 1; + if ( flags & 4 ) i = 2; + tex->axis = i; + if ( tex->type == ID_IMAP ) + { + tex->param.imap->axis = i; + if ( flags & 32 ) + tex->param.imap->pblend = 1; + if ( flags & 64 ) + { + tex->param.imap->aa_strength = 1.0f; + tex->param.imap->aas_flags = 1; + } + } + if ( tex->type == ID_PROC ) + tex->param.proc->axis = i; + + if ( flags & 8 ) tex->tmap.coord_sys = 1; + if ( flags & 16 ) tex->negative = 1; + break; + + case ID_TSIZ: + for ( i = 0; i < 3; i++ ) + tex->tmap.size.val[ i ] = getF4(); + break; + + case ID_TCTR: + for ( i = 0; i < 3; i++ ) + tex->tmap.center.val[ i ] = getF4(); + break; + + case ID_TFAL: + for ( i = 0; i < 3; i++ ) + tex->tmap.falloff.val[ i ] = getF4(); + break; + + case ID_TVEL: + for ( i = 0; i < 3; i++ ) + v[ i ] = getF4(); + tex->tmap.center.eindex = add_tvel( tex->tmap.center.val, v, obj->envelopes ); + break; + + case ID_TCLR: + if ( tex->type == ID_PROC ) + for ( i = 0; i < 3; i++ ) + tex->param.proc->value[ i ] = getU1() / 255.0f; + break; + + case ID_TVAL: + if ( tex->type == ID_PROC ) + tex->param.proc->value[ 0 ] = getI2() / 256.0f; + break; + + case ID_TAMP: + if ( tex->type == ID_IMAP ) + tex->param.imap->amplitude.val = getF4(); + break; + + case ID_TIMG: + if ( tex->type == ID_IMAP ) + { + s = getS0(); + tex->param.imap->cindex = add_clip( s, obj->clips ); + } + break; + + case ID_TAAS: + if ( tex->type == ID_IMAP ) + { + tex->param.imap->aa_strength = getF4(); + tex->param.imap->aas_flags = 1; + } + break; + + case ID_TREF: + tex->tmap.ref_object = getbytes( sz ); + break; + + case ID_TOPC: + tex->opacity.val = getF4(); + break; + + case ID_TFP0: + if ( tex->type == ID_IMAP ) + tex->param.imap->wrapw.val = getF4(); + break; + + case ID_TFP1: + if ( tex->type == ID_IMAP ) + tex->param.imap->wraph.val = getF4(); + break; + + case ID_SHDR: + shdr = new lwPlugin; + if ( !shdr ) goto Fail; + shdr->name = getbytes( sz ); + surf->shaders.push_back( shdr ); + break; + + case ID_SDAT: + shdr->data = getbytes( sz ); + break; + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the SURF chunk? */ + + filepos = is->tellg(); + if ( filepos == -1 ) break; // end of file ? + if ( filepos > chunkend ) // error: read too much + { + is->seekg(chunkend, ios_base::beg ); + break; + } + } + return surf; Fail: - if ( surf ) delete surf; - return NULL; + if ( surf ) delete surf; + return NULL; } @@ -2411,209 +2411,209 @@ Read an lwSurface from an LWO2 file. lwSurface *lwReader::lwGetSurface() { - lwSurface *surf; - lwTexture *tex; - lwPlugin *shdr; - unsigned int id, type; - unsigned short sz; - unsigned int pos, rlen, fpos; - - /* allocate the Surface structure */ - - surf = new lwSurface; - if ( !surf ) goto Fail; - - /* remember where we started */ - - flen = 0; - pos = is->tellg(); - - /* names */ - - surf->name = getS0(); - surf->srcname = getS0(); - - /* first subchunk header */ - - id = getU4(); - sz = getU2(); - if ( 0 > flen ) goto Fail; - - /* process subchunks as they're encountered */ - - for (;;) { - sz += sz & 1; - flen = 0; - - switch ( id ) { - case ID_COLR: - surf->color.rgb[ 0 ] = getF4(); - surf->color.rgb[ 1 ] = getF4(); - surf->color.rgb[ 2 ] = getF4(); - surf->color.eindex = getVX(); - break; - - case ID_LUMI: - surf->luminosity.val = getF4(); - surf->luminosity.eindex = getVX(); - break; - - case ID_DIFF: - surf->diffuse.val = getF4(); - surf->diffuse.eindex = getVX(); - break; - - case ID_SPEC: - surf->specularity.val = getF4(); - surf->specularity.eindex = getVX(); - break; - - case ID_GLOS: - surf->glossiness.val = getF4(); - surf->glossiness.eindex = getVX(); - break; - - case ID_REFL: - surf->reflection.val.val = getF4(); - surf->reflection.val.eindex = getVX(); - break; - - case ID_RFOP: - surf->reflection.options = getU2(); - break; - - case ID_RIMG: - surf->reflection.cindex = getVX(); - break; - - case ID_RSAN: - surf->reflection.seam_angle = getF4(); - break; - - case ID_TRAN: - surf->transparency.val.val = getF4(); - surf->transparency.val.eindex = getVX(); - break; - - case ID_TROP: - surf->transparency.options = getU2(); - break; - - case ID_TIMG: - surf->transparency.cindex = getVX(); - break; - - case ID_RIND: - surf->eta.val = getF4(); - surf->eta.eindex = getVX(); - break; - - case ID_TRNL: - surf->translucency.val = getF4(); - surf->translucency.eindex = getVX(); - break; - - case ID_BUMP: - surf->bump.val = getF4(); - surf->bump.eindex = getVX(); - break; - - case ID_SMAN: - surf->smooth = getF4(); - break; - - case ID_SIDE: - surf->sideflags = getU2(); - break; - - case ID_CLRH: - surf->color_hilite.val = getF4(); - surf->color_hilite.eindex = getVX(); - break; - - case ID_CLRF: - surf->color_filter.val = getF4(); - surf->color_filter.eindex = getVX(); - break; - - case ID_ADTR: - surf->add_trans.val = getF4(); - surf->add_trans.eindex = getVX(); - break; - - case ID_SHRP: - surf->dif_sharp.val = getF4(); - surf->dif_sharp.eindex = getVX(); - break; - - case ID_GVAL: - surf->glow.val = getF4(); - surf->glow.eindex = getVX(); - break; - - case ID_LINE: - surf->line.enabled = 1; - if ( sz >= 2 ) surf->line.flags = getU2(); - if ( sz >= 6 ) surf->line.size.val = getF4(); - if ( sz >= 8 ) surf->line.size.eindex = getVX(); - break; - - case ID_ALPH: - surf->alpha_mode = getU2(); - surf->alpha = getF4(); - break; - - case ID_AVAL: - surf->alpha = getF4(); - break; - - case ID_BLOK: - type = getU4(); - - switch ( type ) { - case ID_IMAP: - case ID_PROC: - case ID_GRAD: - tex = lwGetTexture( sz - 4, type ); - if ( !tex ) goto Fail; - if ( !surf->addTexture(tex) ) delete tex; - flen += 4; - break; - case ID_SHDR: - shdr = lwGetShader( sz - 4 ); - if ( !shdr ) goto Fail; - surf->shaders.insert(lower_bound(surf->shaders.begin(), surf->shaders.end(), shdr), shdr); - flen += 4; - break; - } - break; - - default: - break; - } - - /* error while reading current subchunk? */ - - rlen = flen; - if ( rlen < 0 || rlen > sz ) goto Fail; - - /* skip unread parts of the current subchunk */ - - if ( rlen < sz ) - is->seekg(sz - rlen, ios_base::cur ); - - /* end of the SURF chunk? */ - - fpos = is->tellg(); - if ( fpos == -1 ) break; - if ( chunksize + pos <= fpos ) break; - - /* get the next subchunk header */ - - flen = 0; - id = getU4(); - sz = getU2(); - if ( 6 != flen ) goto Fail; + lwSurface *surf; + lwTexture *tex; + lwPlugin *shdr; + unsigned int id, type; + unsigned short sz; + unsigned int pos, rlen, fpos; + + /* allocate the Surface structure */ + + surf = new lwSurface; + if ( !surf ) goto Fail; + + /* remember where we started */ + + flen = 0; + pos = is->tellg(); + + /* names */ + + surf->name = getS0(); + surf->srcname = getS0(); + + /* first subchunk header */ + + id = getU4(); + sz = getU2(); + if ( 0 > flen ) goto Fail; + + /* process subchunks as they're encountered */ + + for (;;) { + sz += sz & 1; + flen = 0; + + switch ( id ) { + case ID_COLR: + surf->color.rgb[ 0 ] = getF4(); + surf->color.rgb[ 1 ] = getF4(); + surf->color.rgb[ 2 ] = getF4(); + surf->color.eindex = getVX(); + break; + + case ID_LUMI: + surf->luminosity.val = getF4(); + surf->luminosity.eindex = getVX(); + break; + + case ID_DIFF: + surf->diffuse.val = getF4(); + surf->diffuse.eindex = getVX(); + break; + + case ID_SPEC: + surf->specularity.val = getF4(); + surf->specularity.eindex = getVX(); + break; + + case ID_GLOS: + surf->glossiness.val = getF4(); + surf->glossiness.eindex = getVX(); + break; + + case ID_REFL: + surf->reflection.val.val = getF4(); + surf->reflection.val.eindex = getVX(); + break; + + case ID_RFOP: + surf->reflection.options = getU2(); + break; + + case ID_RIMG: + surf->reflection.cindex = getVX(); + break; + + case ID_RSAN: + surf->reflection.seam_angle = getF4(); + break; + + case ID_TRAN: + surf->transparency.val.val = getF4(); + surf->transparency.val.eindex = getVX(); + break; + + case ID_TROP: + surf->transparency.options = getU2(); + break; + + case ID_TIMG: + surf->transparency.cindex = getVX(); + break; + + case ID_RIND: + surf->eta.val = getF4(); + surf->eta.eindex = getVX(); + break; + + case ID_TRNL: + surf->translucency.val = getF4(); + surf->translucency.eindex = getVX(); + break; + + case ID_BUMP: + surf->bump.val = getF4(); + surf->bump.eindex = getVX(); + break; + + case ID_SMAN: + surf->smooth = getF4(); + break; + + case ID_SIDE: + surf->sideflags = getU2(); + break; + + case ID_CLRH: + surf->color_hilite.val = getF4(); + surf->color_hilite.eindex = getVX(); + break; + + case ID_CLRF: + surf->color_filter.val = getF4(); + surf->color_filter.eindex = getVX(); + break; + + case ID_ADTR: + surf->add_trans.val = getF4(); + surf->add_trans.eindex = getVX(); + break; + + case ID_SHRP: + surf->dif_sharp.val = getF4(); + surf->dif_sharp.eindex = getVX(); + break; + + case ID_GVAL: + surf->glow.val = getF4(); + surf->glow.eindex = getVX(); + break; + + case ID_LINE: + surf->line.enabled = 1; + if ( sz >= 2 ) surf->line.flags = getU2(); + if ( sz >= 6 ) surf->line.size.val = getF4(); + if ( sz >= 8 ) surf->line.size.eindex = getVX(); + break; + + case ID_ALPH: + surf->alpha_mode = getU2(); + surf->alpha = getF4(); + break; + + case ID_AVAL: + surf->alpha = getF4(); + break; + + case ID_BLOK: + type = getU4(); + + switch ( type ) { + case ID_IMAP: + case ID_PROC: + case ID_GRAD: + tex = lwGetTexture( sz - 4, type ); + if ( !tex ) goto Fail; + if ( !surf->addTexture(tex) ) delete tex; + flen += 4; + break; + case ID_SHDR: + shdr = lwGetShader( sz - 4 ); + if ( !shdr ) goto Fail; + surf->shaders.insert(lower_bound(surf->shaders.begin(), surf->shaders.end(), shdr), shdr); + flen += 4; + break; + } + break; + + default: + break; + } + + /* error while reading current subchunk? */ + + rlen = flen; + if ( rlen < 0 || rlen > sz ) goto Fail; + + /* skip unread parts of the current subchunk */ + + if ( rlen < sz ) + is->seekg(sz - rlen, ios_base::cur ); + + /* end of the SURF chunk? */ + + fpos = is->tellg(); + if ( fpos == -1 ) break; + if ( chunksize + pos <= fpos ) break; + + /* get the next subchunk header */ + + flen = 0; + id = getU4(); + sz = getU2(); + if ( 6 != flen ) goto Fail; } return surf; @@ -2632,79 +2632,79 @@ lwGetVMap() lwVMap *lwReader::lwGetVMap( int ptoffset, int poloffset, int perpoly ) { - char *buf, *bp; - lwVMap *vmap; - unsigned int i, j, npts, rlen; - - /* read the whole chunk */ - - flen = 0; - buf = getbytes( chunksize ); - if ( !buf ) return NULL; - - vmap = new lwVMap; - if ( !vmap ) { - free(buf); - return NULL; - } - - /* initialize the vmap */ - - vmap->perpoly = perpoly; - - bp = buf; - flen = 0; - vmap->type = sgetU4( &bp ); - vmap->dim = sgetU2( &bp ); - vmap->name = sgetS0( &bp ); - rlen = flen; - - /* count the vmap records */ - - npts = 0; - while ( bp < buf + chunksize ) { - i = sgetVX( &bp ); - if ( perpoly ) - i = sgetVX( &bp ); - bp += vmap->dim * sizeof( float ); - ++npts; - } - - /* allocate the vmap */ - - vmap->nverts = npts; - vmap->vindex = (int *)malloc(npts * sizeof(int)); - if ( !vmap->vindex ) goto Fail; - if ( perpoly ) - { - vmap->pindex = (int *)malloc(npts * sizeof(int)); - if ( !vmap->pindex ) goto Fail; - } - - if ( vmap->dim > 0 ) - { - vmap->val = (float **)malloc(npts * sizeof(float *)); - if ( !vmap->val ) goto Fail; - for ( i = 0; i < npts; i++ ) - vmap->val[ i ] = (float *)malloc(vmap->dim * sizeof( float )); - } - - /* fill in the vmap values */ - - bp = buf + rlen; - for ( i = 0; i < npts; i++ ) { - vmap->vindex[ i ] = sgetVX( &bp ); - if ( perpoly ) - vmap->pindex[ i ] = sgetVX( &bp ); - for ( j = 0; j < vmap->dim; j++ ) - vmap->val[ i ][ j ] = sgetF4( &bp ); - } - - free(buf); - return vmap; - + char *buf, *bp; + lwVMap *vmap; + unsigned int i, j, npts, rlen; + + /* read the whole chunk */ + + flen = 0; + buf = getbytes( chunksize ); + if ( !buf ) return NULL; + + vmap = new lwVMap; + if ( !vmap ) { + free(buf); + return NULL; + } + + /* initialize the vmap */ + + vmap->perpoly = perpoly; + + bp = buf; + flen = 0; + vmap->type = sgetU4( &bp ); + vmap->dim = sgetU2( &bp ); + vmap->name = sgetS0( &bp ); + rlen = flen; + + /* count the vmap records */ + + npts = 0; + while ( bp < buf + chunksize ) { + i = sgetVX( &bp ); + if ( perpoly ) + i = sgetVX( &bp ); + bp += vmap->dim * sizeof( float ); + ++npts; + } + + /* allocate the vmap */ + + vmap->nverts = npts; + vmap->vindex = (int *)malloc(npts * sizeof(int)); + if ( !vmap->vindex ) goto Fail; + if ( perpoly ) + { + vmap->pindex = (int *)malloc(npts * sizeof(int)); + if ( !vmap->pindex ) goto Fail; + } + + if ( vmap->dim > 0 ) + { + vmap->val = (float **)malloc(npts * sizeof(float *)); + if ( !vmap->val ) goto Fail; + for ( i = 0; i < npts; i++ ) + vmap->val[ i ] = (float *)malloc(vmap->dim * sizeof( float )); + } + + /* fill in the vmap values */ + + bp = buf + rlen; + for ( i = 0; i < npts; i++ ) { + vmap->vindex[ i ] = sgetVX( &bp ); + if ( perpoly ) + vmap->pindex[ i ] = sgetVX( &bp ); + for ( j = 0; j < vmap->dim; j++ ) + vmap->val[ i ][ j ] = sgetF4( &bp ); + } + + free(buf); + return vmap; + Fail: - free(buf); - delete vmap; - return NULL; + free(buf); + delete vmap; + return NULL; } diff --git a/Tools/LightwaveConverter/src/lwo2mesh.cpp b/Tools/LightwaveConverter/src/lwo2mesh.cpp index 45d7743530b..0c6d1c07694 100644 --- a/Tools/LightwaveConverter/src/lwo2mesh.cpp +++ b/Tools/LightwaveConverter/src/lwo2mesh.cpp @@ -92,224 +92,224 @@ void _makepath( char *_fn, const char *_drive, const char *_dir, void Lwo2MeshWriter::doExportMaterials() { - char - drive[ _MAX_DRIVE ], - dir[ _MAX_DIR ], - node[ _MAX_FNAME ], - ext[ _MAX_EXT ], - texname [128]; - - unsigned int slength = 0; - - if (flags[RenameMaterials]) - { - if (flags[UseInteractiveMethod]) - { - for (unsigned int i = 0; i < object->surfaces.size(); ++i) - { - lwSurface *surface = object->surfaces[i]; - cout << "Rename surface " << surface->name << " to: "; - cin >> texname; - surface->setname(texname); - } - } else { - _splitpath( dest, drive, dir, node, ext ); - - for (unsigned int i = 0; i < object->surfaces.size(); ++i) - { - lwSurface *surface = object->surfaces[i]; - if (flags[UsePrefixMethod]) - strcpy(texname,matPrefix); - else - { - strcpy(texname,node); - strcat(texname,"_"); - } - - strcat(texname, surface->name); - surface->setname(texname); - } - } - } - - for (unsigned int i = 0; i < object->surfaces.size(); ++i) - { - lwSurface *surface = object->surfaces[i]; - - // Create deferred material so no load - MaterialPtr ogreMat = MaterialManager::getSingleton().getByName(surface->name); - - if (ogreMat.isNull()) - { - ogreMat = MaterialManager::getSingleton().create(surface->name, + char + drive[ _MAX_DRIVE ], + dir[ _MAX_DIR ], + node[ _MAX_FNAME ], + ext[ _MAX_EXT ], + texname [128]; + + unsigned int slength = 0; + + if (flags[RenameMaterials]) + { + if (flags[UseInteractiveMethod]) + { + for (unsigned int i = 0; i < object->surfaces.size(); ++i) + { + lwSurface *surface = object->surfaces[i]; + cout << "Rename surface " << surface->name << " to: "; + cin >> texname; + surface->setname(texname); + } + } else { + _splitpath( dest, drive, dir, node, ext ); + + for (unsigned int i = 0; i < object->surfaces.size(); ++i) + { + lwSurface *surface = object->surfaces[i]; + if (flags[UsePrefixMethod]) + strcpy(texname,matPrefix); + else + { + strcpy(texname,node); + strcat(texname,"_"); + } + + strcat(texname, surface->name); + surface->setname(texname); + } + } + } + + for (unsigned int i = 0; i < object->surfaces.size(); ++i) + { + lwSurface *surface = object->surfaces[i]; + + // Create deferred material so no load + MaterialPtr ogreMat = MaterialManager::getSingleton().getByName(surface->name); + + if (ogreMat.isNull()) + { + ogreMat = MaterialManager::getSingleton().create(surface->name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - ogreMat->setAmbient - ( - surface->color.rgb[0], - surface->color.rgb[1], - surface->color.rgb[2] - ); - - ogreMat->setDiffuse - ( - surface->diffuse.val * surface->color.rgb[0], - surface->diffuse.val * surface->color.rgb[1], - surface->diffuse.val * surface->color.rgb[2], - 1.0f - ); - - ogreMat->setSpecular - ( - surface->specularity.val * surface->color.rgb[0], - surface->specularity.val * surface->color.rgb[1], - surface->specularity.val * surface->color.rgb[2], - 1.0f - ); - - ogreMat->setShininess(surface->glossiness.val); - - ogreMat->setSelfIllumination - ( - surface->luminosity.val * surface->color.rgb[0], - surface->luminosity.val * surface->color.rgb[1], - surface->luminosity.val * surface->color.rgb[2] - ); - - unsigned int j; - lwTexture *tex; - int cindex; - lwClip *clip; - - for (j = 0; j < surface->color.textures.size(); j++) - { - tex = surface->color.textures[j]; - cindex = tex->param.imap->cindex; - clip = object->lwFindClip(cindex); - - if (clip) - { - _splitpath( clip->source.still->name, drive, dir, node, ext ); - _makepath( texname, 0, 0, node, ext ); - ogreMat->getTechnique(0)->getPass(0)->createTextureUnitState(texname); - } - } - - for (j = 0; j < surface->transparency.val.textures.size(); j++) - { - tex = surface->transparency.val.textures[j]; - cindex = tex->param.imap->cindex; - clip = object->lwFindClip(cindex); - - if (clip) - { - _splitpath( clip->source.still->name, drive, dir, node, ext ); - _makepath( texname, 0, 0, node, ext ); - ogreMat->getTechnique(0)->getPass(0)->createTextureUnitState(texname); - } - } - materialSerializer->queueForExport(ogreMat); - } - } + + ogreMat->setAmbient + ( + surface->color.rgb[0], + surface->color.rgb[1], + surface->color.rgb[2] + ); + + ogreMat->setDiffuse + ( + surface->diffuse.val * surface->color.rgb[0], + surface->diffuse.val * surface->color.rgb[1], + surface->diffuse.val * surface->color.rgb[2], + 1.0f + ); + + ogreMat->setSpecular + ( + surface->specularity.val * surface->color.rgb[0], + surface->specularity.val * surface->color.rgb[1], + surface->specularity.val * surface->color.rgb[2], + 1.0f + ); + + ogreMat->setShininess(surface->glossiness.val); + + ogreMat->setSelfIllumination + ( + surface->luminosity.val * surface->color.rgb[0], + surface->luminosity.val * surface->color.rgb[1], + surface->luminosity.val * surface->color.rgb[2] + ); + + unsigned int j; + lwTexture *tex; + int cindex; + lwClip *clip; + + for (j = 0; j < surface->color.textures.size(); j++) + { + tex = surface->color.textures[j]; + cindex = tex->param.imap->cindex; + clip = object->lwFindClip(cindex); + + if (clip) + { + _splitpath( clip->source.still->name, drive, dir, node, ext ); + _makepath( texname, 0, 0, node, ext ); + ogreMat->getTechnique(0)->getPass(0)->createTextureUnitState(texname); + } + } + + for (j = 0; j < surface->transparency.val.textures.size(); j++) + { + tex = surface->transparency.val.textures[j]; + cindex = tex->param.imap->cindex; + clip = object->lwFindClip(cindex); + + if (clip) + { + _splitpath( clip->source.still->name, drive, dir, node, ext ); + _makepath( texname, 0, 0, node, ext ); + ogreMat->getTechnique(0)->getPass(0)->createTextureUnitState(texname); + } + } + materialSerializer->queueForExport(ogreMat); + } + } } Skeleton *Lwo2MeshWriter::doExportSkeleton(const String &skelName, int l) { - vpolygons bones; - bones.clear(); - bones.reserve(256); - - vpoints bonepoints; - bonepoints.clear(); - bonepoints.reserve(512); - - if (l == -1) - { - for (l = 0; l < object->layers.size(); ++l) - { - copyPoints(-1, ID_BONE, object->layers[l]->points, bonepoints); - copyPolygons(-1, ID_BONE, object->layers[l]->polygons, bones); - } - } - else - { - copyPoints(-1, ID_BONE, object->layers[l]->points, bonepoints); - copyPolygons(-1, ID_BONE, object->layers[l]->polygons, bones); - } - - if (!bones.size()) return NULL; // no bones means no skeleton - - SkeletonPtr ogreskel = Ogre::SkeletonManager::getSingleton().create(skelName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - - unsigned int i; - // Create all the bones in turn - for (i = 0; i < bones.size(); ++i) - { - lwPolygon* bone = bones[i]; - if (bone->vertices.size() != 2) continue; // a bone has only 2 sides - - Bone* ogreBone = ogreskel->createBone("Bone"); - - Ogre::Vector3 bonePos(bone->vertices[0]->point->x, bone->vertices[0]->point->y, bone->vertices[0]->point->z); - - ogreBone->setPosition(bonePos); - // Hmm, Milkshape has chosen a Euler angle representation of orientation which is not smart - // Rotation Matrix or Quaternion would have been the smarter choice - // Might we have Gimbal lock here? What order are these 3 angles supposed to be applied? - // Grr, we'll try our best anyway... - Quaternion qx, qy, qz, qfinal; + vpolygons bones; + bones.clear(); + bones.reserve(256); + + vpoints bonepoints; + bonepoints.clear(); + bonepoints.reserve(512); + + if (l == -1) + { + for (l = 0; l < object->layers.size(); ++l) + { + copyPoints(-1, ID_BONE, object->layers[l]->points, bonepoints); + copyPolygons(-1, ID_BONE, object->layers[l]->polygons, bones); + } + } + else + { + copyPoints(-1, ID_BONE, object->layers[l]->points, bonepoints); + copyPolygons(-1, ID_BONE, object->layers[l]->polygons, bones); + } + + if (!bones.size()) return NULL; // no bones means no skeleton + + SkeletonPtr ogreskel = Ogre::SkeletonManager::getSingleton().create(skelName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + unsigned int i; + // Create all the bones in turn + for (i = 0; i < bones.size(); ++i) + { + lwPolygon* bone = bones[i]; + if (bone->vertices.size() != 2) continue; // a bone has only 2 sides + + Bone* ogreBone = ogreskel->createBone("Bone"); + + Ogre::Vector3 bonePos(bone->vertices[0]->point->x, bone->vertices[0]->point->y, bone->vertices[0]->point->z); + + ogreBone->setPosition(bonePos); + // Hmm, Milkshape has chosen a Euler angle representation of orientation which is not smart + // Rotation Matrix or Quaternion would have been the smarter choice + // Might we have Gimbal lock here? What order are these 3 angles supposed to be applied? + // Grr, we'll try our best anyway... + Quaternion qx, qy, qz, qfinal; /* - qx.FromAngleAxis(msBoneRot[0], Vector3::UNIT_X); - qy.FromAngleAxis(msBoneRot[1], Vector3::UNIT_Y); - qz.FromAngleAxis(msBoneRot[2], Vector3::UNIT_Z); + qx.FromAngleAxis(msBoneRot[0], Vector3::UNIT_X); + qy.FromAngleAxis(msBoneRot[1], Vector3::UNIT_Y); + qz.FromAngleAxis(msBoneRot[2], Vector3::UNIT_Z); */ - // Assume rotate by x then y then z - qfinal = qz * qy * qx; - ogreBone->setOrientation(qfinal); - } + // Assume rotate by x then y then z + qfinal = qz * qy * qx; + ogreBone->setOrientation(qfinal); + } /* - for (i = 0; i < numBones; ++i) - { - msBone* bone = msModel_GetBoneAt(pModel, i); - - if (strlen(bone->szParentName) == 0) - { - } - else - { - Bone* ogrechild = ogreskel->getBone(bone->szName); - Bone* ogreparent = ogreskel->getBone(bone->szParentName); - - if (ogrechild == 0) - { - continue; - } - if (ogreparent == 0) - { - continue; - } - // Make child - ogreparent->addChild(ogrechild); - } - - - } - - // Create the Animation(s) - doExportAnimations(pModel, ogreskel); - - // Create skeleton serializer & export - SkeletonSerializer serializer; - serializer.exportSkeleton(ogreskel, szFile); - - ogreMesh->_notifySkeleton(ogreskel); - - return ogreskel; + for (i = 0; i < numBones; ++i) + { + msBone* bone = msModel_GetBoneAt(pModel, i); + + if (strlen(bone->szParentName) == 0) + { + } + else + { + Bone* ogrechild = ogreskel->getBone(bone->szName); + Bone* ogreparent = ogreskel->getBone(bone->szParentName); + + if (ogrechild == 0) + { + continue; + } + if (ogreparent == 0) + { + continue; + } + // Make child + ogreparent->addChild(ogrechild); + } + + + } + + // Create the Animation(s) + doExportAnimations(pModel, ogreskel); + + // Create skeleton serializer & export + SkeletonSerializer serializer; + serializer.exportSkeleton(ogreskel, szFile); + + ogreMesh->_notifySkeleton(ogreskel); + + return ogreskel; */ if (!ogreskel.isNull()) Ogre::SkeletonManager::getSingleton().remove(ogreskel->getHandle()); - return NULL; + return NULL; } #define POSITION_BINDING 0 @@ -318,32 +318,32 @@ Skeleton *Lwo2MeshWriter::doExportSkeleton(const String &skelName, int l) VertexData *Lwo2MeshWriter::setupVertexData(unsigned short vertexCount, VertexData *oldVertexData, bool deleteOldVertexData) { - VertexData *vertexData = new VertexData(); + VertexData *vertexData = new VertexData(); - if (oldVertexData) - { + if (oldVertexData) + { // Basic vertex info vertexData->vertexStart = oldVertexData->vertexStart; - vertexData->vertexCount = oldVertexData->vertexCount + vertexCount; + vertexData->vertexCount = oldVertexData->vertexCount + vertexCount; - const VertexBufferBinding::VertexBufferBindingMap bindings = oldVertexData->vertexBufferBinding->getBindings(); - VertexBufferBinding::VertexBufferBindingMap::const_iterator vbi, vbend; - vbend = bindings.end(); + const VertexBufferBinding::VertexBufferBindingMap bindings = oldVertexData->vertexBufferBinding->getBindings(); + VertexBufferBinding::VertexBufferBindingMap::const_iterator vbi, vbend; + vbend = bindings.end(); - for (vbi = bindings.begin(); vbi != vbend; ++vbi) - { - HardwareVertexBufferSharedPtr srcbuf = vbi->second; - // create new buffer with the same settings - HardwareVertexBufferSharedPtr dstBuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - srcbuf->getVertexSize(), srcbuf->getNumVertices() + vertexCount, srcbuf->getUsage(), srcbuf->isSystemMemory()); + for (vbi = bindings.begin(); vbi != vbend; ++vbi) + { + HardwareVertexBufferSharedPtr srcbuf = vbi->second; + // create new buffer with the same settings + HardwareVertexBufferSharedPtr dstBuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + srcbuf->getVertexSize(), srcbuf->getNumVertices() + vertexCount, srcbuf->getUsage(), srcbuf->isSystemMemory()); - // copy data - dstBuf->copyData(*srcbuf, 0, 0, srcbuf->getSizeInBytes(), true); + // copy data + dstBuf->copyData(*srcbuf, 0, 0, srcbuf->getSizeInBytes(), true); - // Copy binding - vertexData->vertexBufferBinding->setBinding(vbi->first, dstBuf); - } + // Copy binding + vertexData->vertexBufferBinding->setBinding(vbi->first, dstBuf); + } // Copy elements const VertexDeclaration::VertexElementList elems = oldVertexData->vertexDeclaration->getElements(); @@ -358,407 +358,407 @@ VertexData *Lwo2MeshWriter::setupVertexData(unsigned short vertexCount, VertexDa ei->getSemantic(), ei->getIndex() ); } - if (deleteOldVertexData) delete oldVertexData; - } - else - { - vertexData->vertexCount = vertexCount; - - VertexBufferBinding* bind = vertexData->vertexBufferBinding; - VertexDeclaration* decl = vertexData->vertexDeclaration; - - decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); - HardwareVertexBufferSharedPtr pbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POSITION_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false); - bind->setBinding(POSITION_BINDING, pbuf); - - decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL); - HardwareVertexBufferSharedPtr nbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(NORMAL_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false); - bind->setBinding(NORMAL_BINDING, nbuf); - - decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); - HardwareVertexBufferSharedPtr tbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(TEXCOORD_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false); - bind->setBinding(TEXCOORD_BINDING, tbuf); - } - return vertexData; + if (deleteOldVertexData) delete oldVertexData; + } + else + { + vertexData->vertexCount = vertexCount; + + VertexBufferBinding* bind = vertexData->vertexBufferBinding; + VertexDeclaration* decl = vertexData->vertexDeclaration; + + decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION); + HardwareVertexBufferSharedPtr pbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POSITION_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false); + bind->setBinding(POSITION_BINDING, pbuf); + + decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL); + HardwareVertexBufferSharedPtr nbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(NORMAL_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false); + bind->setBinding(NORMAL_BINDING, nbuf); + + decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES); + HardwareVertexBufferSharedPtr tbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(TEXCOORD_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false); + bind->setBinding(TEXCOORD_BINDING, tbuf); + } + return vertexData; } void Lwo2MeshWriter::copyPoints(int surfaceIndex, unsigned long polygontype, vpoints &sourcepoints, vpoints &destpoints) { - for (unsigned int i = 0; i < sourcepoints.size(); i++) - { - lwPoint *point = sourcepoints[i]; - - for (unsigned int j = 0; j < point->polygons.size(); j++) - { - lwPolygon *polygon = point->polygons[j]; - if (polygon->type == polygontype) - if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx) - { - destpoints.push_back(point); - break; - } - } - } + for (unsigned int i = 0; i < sourcepoints.size(); i++) + { + lwPoint *point = sourcepoints[i]; + + for (unsigned int j = 0; j < point->polygons.size(); j++) + { + lwPolygon *polygon = point->polygons[j]; + if (polygon->type == polygontype) + if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx) + { + destpoints.push_back(point); + break; + } + } + } } void Lwo2MeshWriter::copyPolygons(int surfaceIndex, unsigned long polygontype, vpolygons &sourcepolygons, vpolygons &destpolygons) { - for (unsigned int i = 0; i < sourcepolygons.size(); i++) - { - lwPolygon *polygon = sourcepolygons[i]; - if (polygon->type == polygontype) - if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx) - destpolygons.push_back(polygon); - } + for (unsigned int i = 0; i < sourcepolygons.size(); i++) + { + lwPolygon *polygon = sourcepolygons[i]; + if (polygon->type == polygontype) + if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx) + destpolygons.push_back(polygon); + } } void Lwo2MeshWriter::copyDataToVertexData(vpoints &points, - vpolygons &polygons, - vvmaps &vmaps, - IndexData *indexData, - VertexData *vertexData, - unsigned short vertexDataOffset) + vpolygons &polygons, + vvmaps &vmaps, + IndexData *indexData, + VertexData *vertexData, + unsigned short vertexDataOffset) { - lwVMap *vmap = 0; - unsigned int ni; - - HardwareVertexBufferSharedPtr pbuf = vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); - HardwareVertexBufferSharedPtr nbuf = vertexData->vertexBufferBinding->getBuffer(NORMAL_BINDING); - HardwareVertexBufferSharedPtr tbuf = vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING); - HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; - - float* pPos = static_cast(pbuf->lock(HardwareBuffer::HBL_DISCARD)); - float* pNor = static_cast(nbuf->lock(HardwareBuffer::HBL_DISCARD)); - float* pTex = static_cast(tbuf->lock(HardwareBuffer::HBL_DISCARD)); - unsigned short *pIdx = static_cast(ibuf->lock(HardwareBuffer::HBL_DISCARD)); - - for (unsigned int p = 0; p < polygons.size(); p++) - { - lwPolygon *polygon = polygons[p]; - - if (polygon->vertices.size() != 3) continue; // only copy triangles; - - for (unsigned int v = 0; v < polygon->vertices.size(); v++) - { - lwVertex *vertex = polygon->vertices[v]; - lwPoint *point = vertex->point; - unsigned short i = getPointIndex(point, points); - - pIdx[p*3 + v] = vertexDataOffset + i; - - ni = (vertexDataOffset + i) * 3; - - pPos[ni] = vertex->point->x; - pPos[ni + 1] = vertex->point->y; - pPos[ni + 2] = vertex->point->z; - - pNor[ni] = vertex->normal.x; - pNor[ni + 1] = vertex->normal.y; - pNor[ni + 2] = vertex->normal.z; - - bool found = false; - - ni = (vertexDataOffset + i) * 2; - - for (unsigned int v = 0; v < point->vmaps.size(); v++) - { - for (unsigned int vr = 0; vr < vmaps.size(); vr++) - { - vmap = vmaps[vr]; - if (point->vmaps[v].vmap == vmap) - { - int n = point->vmaps[v].index; - - pTex[ni] = vmap->val[n][0]; - pTex[ni + 1] = 1.0f - vmap->val[n][1]; - found = true; - break; - } - } - if (found) break; - } - } - } + lwVMap *vmap = 0; + unsigned int ni; + + HardwareVertexBufferSharedPtr pbuf = vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING); + HardwareVertexBufferSharedPtr nbuf = vertexData->vertexBufferBinding->getBuffer(NORMAL_BINDING); + HardwareVertexBufferSharedPtr tbuf = vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING); + HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer; + + float* pPos = static_cast(pbuf->lock(HardwareBuffer::HBL_DISCARD)); + float* pNor = static_cast(nbuf->lock(HardwareBuffer::HBL_DISCARD)); + float* pTex = static_cast(tbuf->lock(HardwareBuffer::HBL_DISCARD)); + unsigned short *pIdx = static_cast(ibuf->lock(HardwareBuffer::HBL_DISCARD)); + + for (unsigned int p = 0; p < polygons.size(); p++) + { + lwPolygon *polygon = polygons[p]; + + if (polygon->vertices.size() != 3) continue; // only copy triangles; + + for (unsigned int v = 0; v < polygon->vertices.size(); v++) + { + lwVertex *vertex = polygon->vertices[v]; + lwPoint *point = vertex->point; + unsigned short i = getPointIndex(point, points); + + pIdx[p*3 + v] = vertexDataOffset + i; + + ni = (vertexDataOffset + i) * 3; + + pPos[ni] = vertex->point->x; + pPos[ni + 1] = vertex->point->y; + pPos[ni + 2] = vertex->point->z; + + pNor[ni] = vertex->normal.x; + pNor[ni + 1] = vertex->normal.y; + pNor[ni + 2] = vertex->normal.z; + + bool found = false; + + ni = (vertexDataOffset + i) * 2; + + for (unsigned int v = 0; v < point->vmaps.size(); v++) + { + for (unsigned int vr = 0; vr < vmaps.size(); vr++) + { + vmap = vmaps[vr]; + if (point->vmaps[v].vmap == vmap) + { + int n = point->vmaps[v].index; + + pTex[ni] = vmap->val[n][0]; + pTex[ni + 1] = 1.0f - vmap->val[n][1]; + found = true; + break; + } + } + if (found) break; + } + } + } pbuf->unlock(); nbuf->unlock(); tbuf->unlock(); - ibuf->unlock(); + ibuf->unlock(); } void Lwo2MeshWriter::prepLwObject(void) { - unsigned int l, p; - - for (l = 0; l < object->layers.size(); l++) - { - lwLayer *layer = object->layers[l]; - + unsigned int l, p; + + for (l = 0; l < object->layers.size(); l++) + { + lwLayer *layer = object->layers[l]; + #ifdef _DEBUG - cout << "Triangulating layer " << l << ", Polygons before: " << layer->polygons.size(); + cout << "Triangulating layer " << l << ", Polygons before: " << layer->polygons.size(); #endif - layer->triangulatePolygons(); + layer->triangulatePolygons(); #ifdef _DEBUG - cout << ", Polygons after: " << layer->polygons.size() << endl; + cout << ", Polygons after: " << layer->polygons.size() << endl; #endif - - // Mirror x-coord for Ogre; - for (p = 0; p < layer->points.size(); p++) - { - layer->points[p]->x *= -1.0f; - layer->points[p]->polygons.clear(); - } - // Unscrew the bounding box - float x = layer->bboxmin.x * -1.0f; - layer->bboxmin.x = layer->bboxmax.x * -1.0f; - layer->bboxmax.x = x; - - for ( p = 0; p < layer->polygons.size(); p++ ) - { - lwPolygon *polygon = layer->polygons[ p ]; - for (unsigned int j = 0; j < polygon->vertices.size(); j++ ) - polygon->vertices[ j ]->point->polygons.push_back(polygon); - } - - for (p = 0; p < layer->polygons.size(); p++) - layer->polygons[p]->flip(); - - layer->calculatePolygonNormals(); - layer->calculateVertexNormals(); - } + + // Mirror x-coord for Ogre; + for (p = 0; p < layer->points.size(); p++) + { + layer->points[p]->x *= -1.0f; + layer->points[p]->polygons.clear(); + } + // Unscrew the bounding box + float x = layer->bboxmin.x * -1.0f; + layer->bboxmin.x = layer->bboxmax.x * -1.0f; + layer->bboxmax.x = x; + + for ( p = 0; p < layer->polygons.size(); p++ ) + { + lwPolygon *polygon = layer->polygons[ p ]; + for (unsigned int j = 0; j < polygon->vertices.size(); j++ ) + polygon->vertices[ j ]->point->polygons.push_back(polygon); + } + + for (p = 0; p < layer->polygons.size(); p++) + layer->polygons[p]->flip(); + + layer->calculatePolygonNormals(); + layer->calculateVertexNormals(); + } } inline int Lwo2MeshWriter::getPointIndex(lwPoint *point, vpoints &points) { - for (unsigned int i = 0; i < points.size(); ++i) - if (points[i] == point) return i; - - return -1; + for (unsigned int i = 0; i < points.size(); ++i) + if (points[i] == point) return i; + + return -1; } inline String Lwo2MeshWriter::makeLayerFileName(char* dest, unsigned int l, char *layername) { - char - drive[ _MAX_DRIVE ], - dir[ _MAX_DIR ], - node[ _MAX_FNAME ], - ext[ _MAX_EXT ], - buf[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 5 ]; + char + drive[ _MAX_DRIVE ], + dir[ _MAX_DIR ], + node[ _MAX_FNAME ], + ext[ _MAX_EXT ], + buf[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 5 ]; - String LayerFileName; - String TempName; + String LayerFileName; + String TempName; - _splitpath( dest, drive, dir, node, ext ); + _splitpath( dest, drive, dir, node, ext ); - TempName = String( node ); + TempName = String( node ); - if (layername) { - TempName += "."; - TempName += layername; - } else { - TempName += ".layer" + StringConverter::toString(l); - } + if (layername) { + TempName += "."; + TempName += layername; + } else { + TempName += ".layer" + StringConverter::toString(l); + } - _makepath( buf, drive, dir, TempName.c_str(), ext ); - LayerFileName = String( buf ); + _makepath( buf, drive, dir, TempName.c_str(), ext ); + LayerFileName = String( buf ); - return LayerFileName; + return LayerFileName; } inline String Lwo2MeshWriter::makeMaterialFileName(char* dest) { - char - drive[ _MAX_DRIVE ], - dir[ _MAX_DIR ], - node[ _MAX_FNAME ], - ext[ _MAX_EXT ], - buf[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 5 ]; + char + drive[ _MAX_DRIVE ], + dir[ _MAX_DIR ], + node[ _MAX_FNAME ], + ext[ _MAX_EXT ], + buf[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 5 ]; - String MaterialFileName; + String MaterialFileName; - _splitpath( dest, drive, dir, node, ext ); - _makepath( buf, drive, dir, node, ".material" ); + _splitpath( dest, drive, dir, node, ext ); + _makepath( buf, drive, dir, node, ".material" ); - const char *test = MaterialFileName.c_str(); - MaterialFileName = String( buf ); + const char *test = MaterialFileName.c_str(); + MaterialFileName = String( buf ); - return MaterialFileName; + return MaterialFileName; } inline void Lwo2MeshWriter::getTextureVMaps(vtextures &textures, vvmaps &svmaps, vvmaps &dvmaps) { - for (unsigned int i = 0; i < textures.size(); i++) - { - lwTexture *texture = textures[i]; - - if (texture->type == ID_IMAP && texture->param.imap) - { - char *mapname = texture->param.imap->vmap_name; - if (mapname) - for (unsigned int v = 0; v < svmaps.size(); v++) - { - lwVMap *vmap = svmaps[v]; - if (strcmp(mapname, vmap->name) == 0) dvmaps.push_back(vmap); - } - } - } - return; + for (unsigned int i = 0; i < textures.size(); i++) + { + lwTexture *texture = textures[i]; + + if (texture->type == ID_IMAP && texture->param.imap) + { + char *mapname = texture->param.imap->vmap_name; + if (mapname) + for (unsigned int v = 0; v < svmaps.size(); v++) + { + lwVMap *vmap = svmaps[v]; + if (strcmp(mapname, vmap->name) == 0) dvmaps.push_back(vmap); + } + } + } + return; } bool Lwo2MeshWriter::writeLwo2Mesh(lwObject *nobject, char *ndest) { - object = nobject; - dest = ndest; - - if (!object) return false; - if (!object->layers.size()) return false; - - prepLwObject(); - - vpoints points; - vpolygons polygons; - vvmaps vmaps; - - MeshSerializer meshserializer; - - if (flags[ExportMaterials]) - { - doExportMaterials(); - materialSerializer->exportQueued(makeMaterialFileName(dest)); - } - - unsigned int ml = object->layers.size(); - - bool SeparateLayers = flags[UseSeparateLayers] && ml > 1; + object = nobject; + dest = ndest; + + if (!object) return false; + if (!object->layers.size()) return false; + + prepLwObject(); + + vpoints points; + vpolygons polygons; + vvmaps vmaps; + + MeshSerializer meshserializer; + + if (flags[ExportMaterials]) + { + doExportMaterials(); + materialSerializer->exportQueued(makeMaterialFileName(dest)); + } + + unsigned int ml = object->layers.size(); + + bool SeparateLayers = flags[UseSeparateLayers] && ml > 1; if (!SeparateLayers) ogreMesh = Ogre::MeshManager::getSingleton().create(ndest, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - Ogre::Vector3 boundingBoxMin(FLT_MAX, FLT_MAX, FLT_MAX); - Ogre::Vector3 boundingBoxMax(FLT_MIN, FLT_MIN, FLT_MIN); - - - for( unsigned int ol = 0; ol < ml; ++ol ) - { - if (!object->layers[ol]->polygons.size()) - continue; - - Ogre::Vector3 currentMin(object->layers[ol]->bboxmin.x, - object->layers[ol]->bboxmin.y, - object->layers[ol]->bboxmin.z); - Ogre::Vector3 currentMax(object->layers[ol]->bboxmax.x, - object->layers[ol]->bboxmax.y, - object->layers[ol]->bboxmax.z); - - if (SeparateLayers) - { - ogreMesh = Ogre::MeshManager::getSingleton().create(ndest, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - ogreMesh->_setBounds(Ogre::AxisAlignedBox(currentMin, currentMax)); - ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(std::max(currentMin.squaredLength(), currentMax.squaredLength()))); - } - else - { - boundingBoxMin.makeFloor(currentMin); - boundingBoxMax.makeCeil(currentMax); - } - - for (unsigned int s = 0; s < object->surfaces.size(); s++) - { - lwSurface *surface = object->surfaces[s]; - - points.clear(); - polygons.clear(); - vmaps.clear(); - - unsigned int l = ol; - - for( unsigned int il = 0; il < ml; ++il ) - { - if (!SeparateLayers) l = il; - - copyPoints(s, ID_FACE, object->layers[l]->points, points); - copyPolygons(s, ID_FACE, object->layers[l]->polygons, polygons); - getTextureVMaps(surface->color.textures, object->layers[l]->vmaps, vmaps); - - if (SeparateLayers) break; - } - - if (!polygons.size()) continue; - - SubMesh *ogreSubMesh = ogreMesh->createSubMesh(); - ogreSubMesh->useSharedVertices = flags[UseSharedVertexData] && points.size() < POINTLIMIT; - - ogreSubMesh->indexData->indexCount = polygons.size() * 3; - ogreSubMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, ogreSubMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - ogreSubMesh->setMaterialName(surface->name); - - - if (ogreSubMesh->useSharedVertices) - { - unsigned short vertexDataOffset = 0; - if (ogreMesh->sharedVertexData) vertexDataOffset = ogreMesh->sharedVertexData->vertexCount; - ogreMesh->sharedVertexData = setupVertexData(points.size(), ogreMesh->sharedVertexData); - copyDataToVertexData(points, polygons, vmaps, ogreSubMesh->indexData, ogreMesh->sharedVertexData, vertexDataOffset); - } - else - { - ogreSubMesh->vertexData = setupVertexData(points.size()); - copyDataToVertexData(points, polygons, vmaps, ogreSubMesh->indexData, ogreSubMesh->vertexData); - } - } - - if (!SeparateLayers) - { - ogreMesh->_setBounds(Ogre::AxisAlignedBox(boundingBoxMin, boundingBoxMax)); - ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(std::max(boundingBoxMin.squaredLength(), boundingBoxMax.squaredLength()))); - } - - String fname = SeparateLayers ? makeLayerFileName(dest, ol, object->layers[ol]->name) : dest; - - Skeleton *skeleton = 0; - - if (flags[ExportSkeleton]) - if (SeparateLayers) - skeleton = doExportSkeleton(fname, ol); - else - if (!ol) skeleton = doExportSkeleton(fname, -1); - - if (flags[GenerateLOD]) - { - ProgressiveMesh::VertexReductionQuota quota; - - if (flags[UseFixedMethod]) - quota = ProgressiveMesh::VRQ_CONSTANT; - else - quota = ProgressiveMesh::VRQ_PROPORTIONAL; - - ogreMesh->generateLodLevels(distanceList, quota, reduction); - } - - if (flags[GenerateEdgeLists]) - { - ogreMesh->buildEdgeList(); - } - - if (flags[GenerateTangents]) - { - ogreMesh->buildTangentVectors(); - } - - try - { - meshserializer.exportMesh(ogreMesh.getPointer(), fname); - } - catch (...) - { - cout << "Could not export to file: " << fname << endl; - } - - ogreMesh->unload(); - - Ogre::MeshManager::getSingleton().remove(ogreMesh->getHandle()); - if (flags[ExportSkeleton] && skeleton) delete skeleton; - - if (!SeparateLayers) break; - } - - return true; + Ogre::Vector3 boundingBoxMin(FLT_MAX, FLT_MAX, FLT_MAX); + Ogre::Vector3 boundingBoxMax(FLT_MIN, FLT_MIN, FLT_MIN); + + + for( unsigned int ol = 0; ol < ml; ++ol ) + { + if (!object->layers[ol]->polygons.size()) + continue; + + Ogre::Vector3 currentMin(object->layers[ol]->bboxmin.x, + object->layers[ol]->bboxmin.y, + object->layers[ol]->bboxmin.z); + Ogre::Vector3 currentMax(object->layers[ol]->bboxmax.x, + object->layers[ol]->bboxmax.y, + object->layers[ol]->bboxmax.z); + + if (SeparateLayers) + { + ogreMesh = Ogre::MeshManager::getSingleton().create(ndest, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + ogreMesh->_setBounds(Ogre::AxisAlignedBox(currentMin, currentMax)); + ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(std::max(currentMin.squaredLength(), currentMax.squaredLength()))); + } + else + { + boundingBoxMin.makeFloor(currentMin); + boundingBoxMax.makeCeil(currentMax); + } + + for (unsigned int s = 0; s < object->surfaces.size(); s++) + { + lwSurface *surface = object->surfaces[s]; + + points.clear(); + polygons.clear(); + vmaps.clear(); + + unsigned int l = ol; + + for( unsigned int il = 0; il < ml; ++il ) + { + if (!SeparateLayers) l = il; + + copyPoints(s, ID_FACE, object->layers[l]->points, points); + copyPolygons(s, ID_FACE, object->layers[l]->polygons, polygons); + getTextureVMaps(surface->color.textures, object->layers[l]->vmaps, vmaps); + + if (SeparateLayers) break; + } + + if (!polygons.size()) continue; + + SubMesh *ogreSubMesh = ogreMesh->createSubMesh(); + ogreSubMesh->useSharedVertices = flags[UseSharedVertexData] && points.size() < POINTLIMIT; + + ogreSubMesh->indexData->indexCount = polygons.size() * 3; + ogreSubMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, ogreSubMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY); + ogreSubMesh->setMaterialName(surface->name); + + + if (ogreSubMesh->useSharedVertices) + { + unsigned short vertexDataOffset = 0; + if (ogreMesh->sharedVertexData) vertexDataOffset = ogreMesh->sharedVertexData->vertexCount; + ogreMesh->sharedVertexData = setupVertexData(points.size(), ogreMesh->sharedVertexData); + copyDataToVertexData(points, polygons, vmaps, ogreSubMesh->indexData, ogreMesh->sharedVertexData, vertexDataOffset); + } + else + { + ogreSubMesh->vertexData = setupVertexData(points.size()); + copyDataToVertexData(points, polygons, vmaps, ogreSubMesh->indexData, ogreSubMesh->vertexData); + } + } + + if (!SeparateLayers) + { + ogreMesh->_setBounds(Ogre::AxisAlignedBox(boundingBoxMin, boundingBoxMax)); + ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(std::max(boundingBoxMin.squaredLength(), boundingBoxMax.squaredLength()))); + } + + String fname = SeparateLayers ? makeLayerFileName(dest, ol, object->layers[ol]->name) : dest; + + Skeleton *skeleton = 0; + + if (flags[ExportSkeleton]) + if (SeparateLayers) + skeleton = doExportSkeleton(fname, ol); + else + if (!ol) skeleton = doExportSkeleton(fname, -1); + + if (flags[GenerateLOD]) + { + ProgressiveMesh::VertexReductionQuota quota; + + if (flags[UseFixedMethod]) + quota = ProgressiveMesh::VRQ_CONSTANT; + else + quota = ProgressiveMesh::VRQ_PROPORTIONAL; + + ogreMesh->generateLodLevels(distanceList, quota, reduction); + } + + if (flags[GenerateEdgeLists]) + { + ogreMesh->buildEdgeList(); + } + + if (flags[GenerateTangents]) + { + ogreMesh->buildTangentVectors(); + } + + try + { + meshserializer.exportMesh(ogreMesh.getPointer(), fname); + } + catch (...) + { + cout << "Could not export to file: " << fname << endl; + } + + ogreMesh->unload(); + + Ogre::MeshManager::getSingleton().remove(ogreMesh->getHandle()); + if (flags[ExportSkeleton] && skeleton) delete skeleton; + + if (!SeparateLayers) break; + } + + return true; } diff --git a/Tools/LightwaveConverter/src/main.cpp b/Tools/LightwaveConverter/src/main.cpp index 6da1940772c..766be18d640 100644 --- a/Tools/LightwaveConverter/src/main.cpp +++ b/Tools/LightwaveConverter/src/main.cpp @@ -27,23 +27,23 @@ DefaultHardwareBufferManager* bufferMgr; bool flags[NUMFLAGS] = { - false, // lightwave info - false, // dump vmaps - true, // shared geometry - false, // layers - false, // generate LOD - true, // generate edge lists - true, // generate tangents - true, // use fixed method - true, // materials - false, // RenameMaterials - false, // UseInteractiveMethod - true, // UseObjectMethod, default - false, // UsePrefixMethod - true, // skeleton - true, // has normals - true, // new submesh - true // linear copy + false, // lightwave info + false, // dump vmaps + true, // shared geometry + false, // layers + false, // generate LOD + true, // generate edge lists + true, // generate tangents + true, // use fixed method + true, // materials + false, // RenameMaterials + false, // UseInteractiveMethod + true, // UseObjectMethod, default + false, // UsePrefixMethod + true, // skeleton + true, // has normals + true, // new submesh + true // linear copy }; Mesh::LodDistanceList distanceList; @@ -52,7 +52,7 @@ char *matPrefix = 0; ostream& nl(ostream& os) { - return os << '\n'; + return os << '\n'; } int nobjects = 0, nlayers = 0, nsurfs = 0, nenvs = 0, nclips = 0, npoints = 0, npolygons = 0; @@ -63,78 +63,78 @@ print_vmaps1() Print vmap values for a layer, looping through the vmaps. - for each vmap - print vmap statistics - for each mapped point - print point index and position - if vmad, print polygon index and vertex number - print vmap values + for each vmap + print vmap statistics + for each mapped point + print point index and position + if vmad, print polygon index and vertex number + print vmap values ====================================================================== */ static void print_vmaps1( FILE *fp, lwLayer *layer ) { - lwPoint *pt; - lwVMap *vmap; - char *tag; - unsigned int i, j, k, n; - - fprintf( fp, "\n\nVertex Maps (%d)\n\n", layer->vmaps.size() ); - - for ( i = 0; i < layer->vmaps.size(); i++ ) - { - vmap = layer->vmaps[i]; - - tag = ( char * ) &vmap->type; - - fprintf( fp, "%c%c%c%c \"%s\" dim %d nverts %d vmad (%s)\n", - tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], - vmap->name, - vmap->dim, - vmap->nverts, - vmap->perpoly ? "yes" : "no" ); - - printf( "%c%c%c%c \"%s\" dim %d nverts %d vmad (%s)\n", - tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], - vmap->name, - vmap->dim, - vmap->nverts, - vmap->perpoly ? "yes" : "no" ); - - for ( j = 0; j < vmap->nverts; j++ ) { - /* point index */ - fprintf( fp, " point %d ", vmap->vindex[ j ] ); - - /* if vmad */ - if ( vmap->perpoly ) { - lwPolygon *pol; - - /* polygon index */ - k = vmap->pindex[ j ]; - fprintf( fp, " poly %d ", k ); - - /* vertex index */ - pol = layer->polygons[ k ]; - for ( n = 0; n < pol->vertices.size(); n++ ) - if ( pol->vertices[ n ]->index == vmap->vindex[ j ] ) break; - fprintf( fp, " vert %d ", n ); - } - - /* point coords */ - pt = layer->points[ vmap->vindex[ j ]]; - fprintf( fp, " (%g, %g, %g) ", pt->x, pt->y, pt->z ); - - /* vmap values */ - for ( k = 0; k < vmap->dim; k++ ) - fprintf( fp, " %g", vmap->val[ j ][ k ] ); - - /* done with this point */ - fprintf( fp, "\n" ); - } - /* done with this vmap */ - fprintf( fp, "\n" ); - } - /* done with this layer */ - fprintf( fp, "\n\n" ); + lwPoint *pt; + lwVMap *vmap; + char *tag; + unsigned int i, j, k, n; + + fprintf( fp, "\n\nVertex Maps (%d)\n\n", layer->vmaps.size() ); + + for ( i = 0; i < layer->vmaps.size(); i++ ) + { + vmap = layer->vmaps[i]; + + tag = ( char * ) &vmap->type; + + fprintf( fp, "%c%c%c%c \"%s\" dim %d nverts %d vmad (%s)\n", + tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], + vmap->name, + vmap->dim, + vmap->nverts, + vmap->perpoly ? "yes" : "no" ); + + printf( "%c%c%c%c \"%s\" dim %d nverts %d vmad (%s)\n", + tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], + vmap->name, + vmap->dim, + vmap->nverts, + vmap->perpoly ? "yes" : "no" ); + + for ( j = 0; j < vmap->nverts; j++ ) { + /* point index */ + fprintf( fp, " point %d ", vmap->vindex[ j ] ); + + /* if vmad */ + if ( vmap->perpoly ) { + lwPolygon *pol; + + /* polygon index */ + k = vmap->pindex[ j ]; + fprintf( fp, " poly %d ", k ); + + /* vertex index */ + pol = layer->polygons[ k ]; + for ( n = 0; n < pol->vertices.size(); n++ ) + if ( pol->vertices[ n ]->index == vmap->vindex[ j ] ) break; + fprintf( fp, " vert %d ", n ); + } + + /* point coords */ + pt = layer->points[ vmap->vindex[ j ]]; + fprintf( fp, " (%g, %g, %g) ", pt->x, pt->y, pt->z ); + + /* vmap values */ + for ( k = 0; k < vmap->dim; k++ ) + fprintf( fp, " %g", vmap->val[ j ][ k ] ); + + /* done with this point */ + fprintf( fp, "\n" ); + } + /* done with this vmap */ + fprintf( fp, "\n" ); + } + /* done with this layer */ + fprintf( fp, "\n\n" ); } @@ -144,59 +144,59 @@ print_vmaps2() Print vmap values for a layer, looping through the points. - for each point - print point index, position, number of vmaps, polygon indexes - for each vmap on the point - print vmap name, type and values + for each point + print point index, position, number of vmaps, polygon indexes + for each vmap on the point + print vmap name, type and values ====================================================================== */ static void print_vmaps2( FILE *fp, lwLayer *layer ) { - lwPoint *pt; - lwVMap *vmap; - char *tag; - unsigned int i, j, k, n; - - fprintf( fp, "\n\nPoints (%d)\n\n", layer->points.size() ); - - for ( i = 0; i < layer->points.size(); i++ ) { - pt = layer->points[ i ]; - - /* point index and position */ - fprintf( fp, "%d (%g, %g, %g)", i, pt->x, pt->y, pt->z ); - - /* number of vmaps and polygons */ - fprintf( fp, " nvmaps %d npolygons %d", pt->vmaps.size(), pt->polygons.size() ); - - /* polygon indexes */ - fprintf( fp, " [" ); - for ( j = 0; j < pt->polygons.size(); j++ ) - fprintf( fp, " %d", pt->polygons[ j ] ); - fprintf( fp, "]\n" ); - - /* vmaps for this point */ - for ( j = 0; j < pt->vmaps.size(); j++ ) { - vmap = pt->vmaps[ j ].vmap; - n = pt->vmaps[ j ].index; - - tag = ( char * ) &vmap->type; - - fprintf( fp, " %c%c%c%c \"%s\" vmad (%s)", - tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], vmap->name, - vmap->perpoly ? "yes" : "no" ); - - /* vmap values */ - for ( k = 0; k < vmap->dim; k++ ) - fprintf( fp, " %g", vmap->val[ n ][ k ] ); - - /* done with this vmap */ - fprintf( fp, "\n" ); - } - /* done with this point */ - fprintf( fp, "\n" ); - } - /* done with this layer */ - fprintf( fp, "\n\n" ); + lwPoint *pt; + lwVMap *vmap; + char *tag; + unsigned int i, j, k, n; + + fprintf( fp, "\n\nPoints (%d)\n\n", layer->points.size() ); + + for ( i = 0; i < layer->points.size(); i++ ) { + pt = layer->points[ i ]; + + /* point index and position */ + fprintf( fp, "%d (%g, %g, %g)", i, pt->x, pt->y, pt->z ); + + /* number of vmaps and polygons */ + fprintf( fp, " nvmaps %d npolygons %d", pt->vmaps.size(), pt->polygons.size() ); + + /* polygon indexes */ + fprintf( fp, " [" ); + for ( j = 0; j < pt->polygons.size(); j++ ) + fprintf( fp, " %d", pt->polygons[ j ] ); + fprintf( fp, "]\n" ); + + /* vmaps for this point */ + for ( j = 0; j < pt->vmaps.size(); j++ ) { + vmap = pt->vmaps[ j ].vmap; + n = pt->vmaps[ j ].index; + + tag = ( char * ) &vmap->type; + + fprintf( fp, " %c%c%c%c \"%s\" vmad (%s)", + tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], vmap->name, + vmap->perpoly ? "yes" : "no" ); + + /* vmap values */ + for ( k = 0; k < vmap->dim; k++ ) + fprintf( fp, " %g", vmap->val[ n ][ k ] ); + + /* done with this vmap */ + fprintf( fp, "\n" ); + } + /* done with this point */ + fprintf( fp, "\n" ); + } + /* done with this layer */ + fprintf( fp, "\n\n" ); } @@ -206,84 +206,84 @@ print_vmaps3() Print vmap values for a layer, looping through the polygons. - for each polygon - print polygon index, number of points - for each vertex - print point index, position, number of vmaps - for each vmap on the point - print vmap name, type and values + for each polygon + print polygon index, number of points + for each vertex + print point index, position, number of vmaps + for each vmap on the point + print vmap name, type and values ====================================================================== */ static void print_vmaps3( FILE *fp, lwLayer *layer ) { - lwPoint *pt; - lwPolygon *pol; - lwVMap *vmap; - char *tag; - unsigned int i, j, k, m, n; - - fprintf( fp, "\n\nPolygons (%d)\n\n", layer->polygons.size() ); - - for ( i = 0; i < layer->polygons.size(); i++ ) { - pol = layer->polygons[ i ]; - - /* polygon index, type, number of vertices */ - tag = ( char * ) &pol->type; - fprintf( fp, "%d %c%c%c%c nverts %d\n", i, - tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], pol->vertices.size() ); - - for ( k = 0; k < pol->vertices.size(); k++ ) { - /* point index, position, number of vmads and vmaps */ - n = pol->vertices[ k ]->index; - pt = layer->points[ n ]; - fprintf( fp, "%d (%g, %g, %g) nvmads %d nvmaps %d\n", n, - pt->x, pt->y, pt->z, - pol->vertices[ k ]->vmaps.size(), pt->vmaps.size() - pol->vertices[ k ]->vmaps.size() ); - - /* vmads for this vertex */ - for ( j = 0; j < pol->vertices[ k ]->vmaps.size(); j++ ) { - vmap = pol->vertices[ k ]->vmaps[ j ].vmap; - n = pol->vertices[ k ]->vmaps[ j ].index; - - tag = ( char * ) &vmap->type; - fprintf( fp, " %c%c%c%c vmad \"%s\"", - tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], vmap->name ); - - /* vmap values */ - for ( m = 0; m < vmap->dim; m++ ) - fprintf( fp, " %g", vmap->val[ m ][ n ] ); - - /* done with this vmad */ - fprintf( fp, "\n" ); - } - - /* vmaps for this vertex */ - for ( j = 0; j < pt->vmaps.size(); j++ ) { - vmap = pt->vmaps[ j ].vmap; - if ( vmap->perpoly ) continue; - n = pt->vmaps[ j ].index; - - tag = ( char * ) &vmap->type; - fprintf( fp, " %c%c%c%c vmap \"%s\"", - tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], vmap->name ); - - /* vmap values */ - for ( m = 0; m < vmap->dim; m++ ) - fprintf( fp, " %g", vmap->val[ m ][ n ] ); - - /* done with this vmap */ - fprintf( fp, "\n" ); - } - - /* done with this vertex */ - if ( pt->vmaps.size() ) - fprintf( fp, "\n" ); - } - /* done with this polygon */ - fprintf( fp, "\n" ); - } - /* done with this layer */ - fprintf( fp, "\n\n" ); + lwPoint *pt; + lwPolygon *pol; + lwVMap *vmap; + char *tag; + unsigned int i, j, k, m, n; + + fprintf( fp, "\n\nPolygons (%d)\n\n", layer->polygons.size() ); + + for ( i = 0; i < layer->polygons.size(); i++ ) { + pol = layer->polygons[ i ]; + + /* polygon index, type, number of vertices */ + tag = ( char * ) &pol->type; + fprintf( fp, "%d %c%c%c%c nverts %d\n", i, + tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], pol->vertices.size() ); + + for ( k = 0; k < pol->vertices.size(); k++ ) { + /* point index, position, number of vmads and vmaps */ + n = pol->vertices[ k ]->index; + pt = layer->points[ n ]; + fprintf( fp, "%d (%g, %g, %g) nvmads %d nvmaps %d\n", n, + pt->x, pt->y, pt->z, + pol->vertices[ k ]->vmaps.size(), pt->vmaps.size() - pol->vertices[ k ]->vmaps.size() ); + + /* vmads for this vertex */ + for ( j = 0; j < pol->vertices[ k ]->vmaps.size(); j++ ) { + vmap = pol->vertices[ k ]->vmaps[ j ].vmap; + n = pol->vertices[ k ]->vmaps[ j ].index; + + tag = ( char * ) &vmap->type; + fprintf( fp, " %c%c%c%c vmad \"%s\"", + tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], vmap->name ); + + /* vmap values */ + for ( m = 0; m < vmap->dim; m++ ) + fprintf( fp, " %g", vmap->val[ m ][ n ] ); + + /* done with this vmad */ + fprintf( fp, "\n" ); + } + + /* vmaps for this vertex */ + for ( j = 0; j < pt->vmaps.size(); j++ ) { + vmap = pt->vmaps[ j ].vmap; + if ( vmap->perpoly ) continue; + n = pt->vmaps[ j ].index; + + tag = ( char * ) &vmap->type; + fprintf( fp, " %c%c%c%c vmap \"%s\"", + tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], vmap->name ); + + /* vmap values */ + for ( m = 0; m < vmap->dim; m++ ) + fprintf( fp, " %g", vmap->val[ m ][ n ] ); + + /* done with this vmap */ + fprintf( fp, "\n" ); + } + + /* done with this vertex */ + if ( pt->vmaps.size() ) + fprintf( fp, "\n" ); + } + /* done with this polygon */ + fprintf( fp, "\n" ); + } + /* done with this layer */ + fprintf( fp, "\n\n" ); } @@ -293,231 +293,231 @@ print_vmaps() Print vmap values for a layer. - Calls print_vmaps1(), print_vmaps2() and print_vmaps3(). + Calls print_vmaps1(), print_vmaps2() and print_vmaps3(). ====================================================================== */ void print_vmaps( lwObject *obj ) { - FILE *fp[ 3 ]; - char buf[ 64 ]; - lwLayer *layer; - unsigned int i, j; - - for ( i = 0; i < 3; i++ ) { - sprintf( buf, "vmapout%d.txt", i + 1 ); - fp[ i ] = fopen( buf, "w" ); - if ( !fp[ i ] ) { - for ( j = i - 1; j >= 0; j-- ) - fclose( fp[ j ] ); - return; - } - } - - for ( i = 0; i < obj->layers.size(); i++ ) - { - layer = obj->layers[i]; - - fprintf( fp[ 0 ], "------------------------\nLayer %d\n", i ); - print_vmaps1( fp[ 0 ], layer ); - - fprintf( fp[ 1 ], "------------------------\nLayer %d\n", i ); - print_vmaps2( fp[ 1 ], layer ); - - fprintf( fp[ 2 ], "------------------------\nLayer %d\n", i ); - print_vmaps3( fp[ 2 ], layer ); - } - - for ( i = 0; i < 3; i++ ) - fclose( fp[ i ] ); + FILE *fp[ 3 ]; + char buf[ 64 ]; + lwLayer *layer; + unsigned int i, j; + + for ( i = 0; i < 3; i++ ) { + sprintf( buf, "vmapout%d.txt", i + 1 ); + fp[ i ] = fopen( buf, "w" ); + if ( !fp[ i ] ) { + for ( j = i - 1; j >= 0; j-- ) + fclose( fp[ j ] ); + return; + } + } + + for ( i = 0; i < obj->layers.size(); i++ ) + { + layer = obj->layers[i]; + + fprintf( fp[ 0 ], "------------------------\nLayer %d\n", i ); + print_vmaps1( fp[ 0 ], layer ); + + fprintf( fp[ 1 ], "------------------------\nLayer %d\n", i ); + print_vmaps2( fp[ 1 ], layer ); + + fprintf( fp[ 2 ], "------------------------\nLayer %d\n", i ); + print_vmaps3( fp[ 2 ], layer ); + } + + for ( i = 0; i < 3; i++ ) + fclose( fp[ i ] ); } int make_filename( char *spec, char *name, char *fullname ) { - char - drive[ _MAX_DRIVE ], - dir[ _MAX_DIR ], - node[ _MAX_FNAME ], - ext[ _MAX_EXT ]; - - _splitpath( spec, drive, dir, node, ext ); - _makepath( fullname, drive, dir, name, NULL ); - return 1; + char + drive[ _MAX_DRIVE ], + dir[ _MAX_DIR ], + node[ _MAX_FNAME ], + ext[ _MAX_EXT ]; + + _splitpath( spec, drive, dir, node, ext ); + _makepath( fullname, drive, dir, name, NULL ); + return 1; } int make_destname( char *spec, char *name, char *fullname ) { - char - drive[ _MAX_DRIVE ], - dir[ _MAX_DIR ], - node[ _MAX_FNAME ], - ext[ _MAX_EXT ], - dnode[ _MAX_FNAME ]; - - _splitpath( name, drive, dir, dnode, ext ); - _splitpath( spec, drive, dir, node, ext ); - _makepath( fullname, drive, dir, dnode, ".mesh" ); - return 1; + char + drive[ _MAX_DRIVE ], + dir[ _MAX_DIR ], + node[ _MAX_FNAME ], + ext[ _MAX_EXT ], + dnode[ _MAX_FNAME ]; + + _splitpath( name, drive, dir, dnode, ext ); + _splitpath( spec, drive, dir, node, ext ); + _makepath( fullname, drive, dir, dnode, ".mesh" ); + return 1; } int make_filespec( char *spec, char *subdir, char *fullname ) { - char - name[ _MAX_FNAME ], - drive[ _MAX_DRIVE ], - dir[ _MAX_DIR ], - node[ _MAX_FNAME ], - ext[ _MAX_EXT ]; - - _splitpath( spec, drive, dir, node, ext ); - _makepath( name, drive, dir, subdir, NULL ); - _makepath( fullname, NULL, name, node, ext ); - return 1; + char + name[ _MAX_FNAME ], + drive[ _MAX_DRIVE ], + dir[ _MAX_DIR ], + node[ _MAX_FNAME ], + ext[ _MAX_EXT ]; + + _splitpath( spec, drive, dir, node, ext ); + _makepath( name, drive, dir, subdir, NULL ); + _makepath( fullname, NULL, name, node, ext ); + return 1; } void help( char *filename ) { - cout << "lwo2mesh v0.89b (2005.02.09) by Dennis Verbeek." << nl - << "Converts a Lightwave object to an Ogre mesh." << nl - << "Please send any feedback to: dennis.verbeek@chello.nl" << nl << nl + cout << "lwo2mesh v0.89b (2005.02.09) by Dennis Verbeek." << nl + << "Converts a Lightwave object to an Ogre mesh." << nl + << "Please send any feedback to: dennis.verbeek@chello.nl" << nl << nl #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX - << "Linux Port (2004.10.16) by Magnus Møller Petersen." << nl - << "Please send feedback concerning Linux to: magnus@moaner.dk" << nl << nl + << "Linux Port (2004.10.16) by Magnus Møller Petersen." << nl + << "Please send feedback concerning Linux to: magnus@moaner.dk" << nl << nl #endif - << "Usage: " << filename << " [options] source [dest]" << nl - << "options:" << nl - << "-g do not use shared geometry" << nl - << "-d generate level of detail information" << nl - << " method (f)ixed or (p)roportional" << nl - << " reduction (fixed) or reductionfactor (proportional)" << nl - << " number of LOD levels" << nl - << " distances" << nl - << " example: -dp 0.5 4 1000.0 2000.0 4000.0 8000.0" << nl - << "-l save layers separately" << nl - << "-m do not export materials" << nl - << "-r rename materials" << nl - << " method (i)nteractive, (o)bjectname or (p)refix" << nl - << " example: -rp prefix_" << nl - << "-s do not export skeleton" << nl - << "-i info on .lwo only, no conversion to mesh" << nl - << " -v dump vertex maps" << endl; - exit(0); + << "Usage: " << filename << " [options] source [dest]" << nl + << "options:" << nl + << "-g do not use shared geometry" << nl + << "-d generate level of detail information" << nl + << " method (f)ixed or (p)roportional" << nl + << " reduction (fixed) or reductionfactor (proportional)" << nl + << " number of LOD levels" << nl + << " distances" << nl + << " example: -dp 0.5 4 1000.0 2000.0 4000.0 8000.0" << nl + << "-l save layers separately" << nl + << "-m do not export materials" << nl + << "-r rename materials" << nl + << " method (i)nteractive, (o)bjectname or (p)refix" << nl + << " example: -rp prefix_" << nl + << "-s do not export skeleton" << nl + << "-i info on .lwo only, no conversion to mesh" << nl + << " -v dump vertex maps" << endl; + exit(0); } void info(lwObject *object, char *filename) { - unsigned int points = 0; - unsigned int polygons = 0; - - nlayers += object->layers.size(); - nsurfs += object->surfaces.size(); - nclips += object->clips.size(); - nenvs += object->envelopes.size(); - - cout << "File: " << filename << nl - << setw(8) << object->layers.size() << " layers" << nl - << setw(8) << object->surfaces.size() << " surfaces" << nl - << setw(8) << object->clips.size() << " clips" << nl - << setw(8) << object->envelopes.size() << " envelopes" << endl; - - if (object->layers.size() > 1) - { - for( unsigned int i = 0; i < object->layers.size(); i++ ) - { - points += object->layers[i]->points.size(); - cout << setw(8) << object->layers[i]->points.size() << " points (layer " << i; - - if (object->layers[i]->name) - cout << ", " << object->layers[i]->name << ")" << endl; - else - cout << ")" << endl; - - polygons += object->layers[i]->polygons.size(); - cout << setw(8) << object->layers[i]->polygons.size() << " polygons (layer " << i; - - if (object->layers[i]->name) - cout << ", " << object->layers[i]->name << ")" << endl; - else - cout << ")" << endl; - } - } - else - { - points += object->layers[0]->points.size(); - polygons += object->layers[0]->polygons.size(); - } - - cout << setw(8) << points << " points (total)" << nl - << setw(8) << polygons << " polygons (total)" << nl << endl; - - nobjects++; - npoints += points; - npolygons += polygons; - - if (flags[PrintVMaps]) - print_vmaps( object ); + unsigned int points = 0; + unsigned int polygons = 0; + + nlayers += object->layers.size(); + nsurfs += object->surfaces.size(); + nclips += object->clips.size(); + nenvs += object->envelopes.size(); + + cout << "File: " << filename << nl + << setw(8) << object->layers.size() << " layers" << nl + << setw(8) << object->surfaces.size() << " surfaces" << nl + << setw(8) << object->clips.size() << " clips" << nl + << setw(8) << object->envelopes.size() << " envelopes" << endl; + + if (object->layers.size() > 1) + { + for( unsigned int i = 0; i < object->layers.size(); i++ ) + { + points += object->layers[i]->points.size(); + cout << setw(8) << object->layers[i]->points.size() << " points (layer " << i; + + if (object->layers[i]->name) + cout << ", " << object->layers[i]->name << ")" << endl; + else + cout << ")" << endl; + + polygons += object->layers[i]->polygons.size(); + cout << setw(8) << object->layers[i]->polygons.size() << " polygons (layer " << i; + + if (object->layers[i]->name) + cout << ", " << object->layers[i]->name << ")" << endl; + else + cout << ")" << endl; + } + } + else + { + points += object->layers[0]->points.size(); + polygons += object->layers[0]->polygons.size(); + } + + cout << setw(8) << points << " points (total)" << nl + << setw(8) << polygons << " polygons (total)" << nl << endl; + + nobjects++; + npoints += points; + npolygons += polygons; + + if (flags[PrintVMaps]) + print_vmaps( object ); } #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 int readFiles( char *source, char *dest) { - long h, err; - struct _finddata_t data; - char *filename, *prevname, *destname; - unsigned int failID; - int failpos; - lwReader reader; - Lwo2MeshWriter lwo2mesh; - - filename = (char *)malloc(3 * 512); - if ( !filename ) return 0; - prevname = filename + 512; - destname = filename + 1024; - - err = h = _findfirst( source, &data ); - if ( err == -1 ) - { - printf( "No files found: '%s'\n", source ); - return 0; - } - - while ( err != -1 ) - { - if (( data.attrib & _A_SUBDIR ) && data.name[ 0 ] != '.' ) - { - make_filespec( source, data.name, filename ); - readFiles( filename, dest ); - } - if ( !( data.attrib & _A_SUBDIR )) - { - make_filename( source, data.name, filename ); - - if ( !strcmp( filename, prevname )) break; - strcpy( prevname, filename ); - failID = failpos = 0; - - lwObject *object = reader.readObjectFromFile( filename ); - if ( object ) - { - if (flags[InfoOnly]) - info(object, filename); - else - { - make_destname( dest, data.name, destname ); - lwo2mesh.writeLwo2Mesh(object, destname); - } - delete object; - } - } - err = _findnext( h, &data ); - } - - _findclose( h ); - free (filename); - return 1; + long h, err; + struct _finddata_t data; + char *filename, *prevname, *destname; + unsigned int failID; + int failpos; + lwReader reader; + Lwo2MeshWriter lwo2mesh; + + filename = (char *)malloc(3 * 512); + if ( !filename ) return 0; + prevname = filename + 512; + destname = filename + 1024; + + err = h = _findfirst( source, &data ); + if ( err == -1 ) + { + printf( "No files found: '%s'\n", source ); + return 0; + } + + while ( err != -1 ) + { + if (( data.attrib & _A_SUBDIR ) && data.name[ 0 ] != '.' ) + { + make_filespec( source, data.name, filename ); + readFiles( filename, dest ); + } + if ( !( data.attrib & _A_SUBDIR )) + { + make_filename( source, data.name, filename ); + + if ( !strcmp( filename, prevname )) break; + strcpy( prevname, filename ); + failID = failpos = 0; + + lwObject *object = reader.readObjectFromFile( filename ); + if ( object ) + { + if (flags[InfoOnly]) + info(object, filename); + else + { + make_destname( dest, data.name, destname ); + lwo2mesh.writeLwo2Mesh(object, destname); + } + delete object; + } + } + err = _findnext( h, &data ); + } + + _findclose( h ); + free (filename); + return 1; } #elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX int readFiles( char *source, char *dest ) { - return 1; + return 1; } #else #define readFiles( a, b ) @@ -525,206 +525,206 @@ int readFiles( char *source, char *dest ) { int main( int argc, char *argv[] ) { - int i = 1; - unsigned int ndistances = 0; - Real distance = 0; - char *source = 0; - char *dest = 0; - - if ( argc < 2 ) help(argv[0]); - - while (i < argc) - { - if (argv[i][0] == '-' || argv[i][0] == '/') - { - switch (argv[i++][1]) - { - case 'd': - case 'D': - i--; - flags[GenerateLOD] = true; - switch (argv[i++][2]) - { - case 'f': - case 'F': - flags[UseFixedMethod] = true; - break; - case 'p': - case 'P': - flags[UseFixedMethod] = false; - break; - default: - help(argv[0]); - } - try - { - reduction = atof(argv[i++]); - ndistances = atoi(argv[i++]); - while (ndistances > 0) - { - if (i < argc && argv[i][0] != '-' && argv[i][0] != '/') - distanceList.push_back(atof(argv[i++])); - else - ndistances = 0; - ndistances--; - } - } - catch (Exception *e) - { - ndistances = 0; - distanceList.clear(); - flags[GenerateLOD] = false; - } - break; - case 'g': - case 'G': - flags[UseSharedVertexData] = false; - break; - case 'i': - case 'I': - flags[InfoOnly] = true; - break; - case 'l': - case 'L': - flags[UseSeparateLayers] = true; - break; - case 'm': - case 'M': - flags[ExportMaterials] = false; - break; - case 'r': - case 'R': - flags[RenameMaterials] = true; - if (strlen(argv[i-1]) > 2) { - i--; - switch (argv[i++][2]) - { - case 'i': - case 'I': - flags[UseInteractiveMethod] = true; - break; - case 'o': - case 'O': - flags[UseObjectMethod] = true; // default - break; - case 'p': - case 'P': - flags[UsePrefixMethod] = true; - if (argv[i][0] != '-' && argv[i][0] != '/') - matPrefix = argv[i++]; - else - help(argv[0]); - break; - default: - help(argv[0]); - } - } - break; - case 's': - case 'S': - flags[ExportSkeleton] = false; - break; - case 'v': - case 'V': - flags[PrintVMaps] = true; - break; - default: - help(argv[0]); - } - } - else - { - if (!source) source = argv[i]; - else - if (!dest) dest = argv[i]; - i++; - } - } - - if ( !source ) help(argv[0]); - - if (!dest) dest = "\0"; - - float t1, t2; - - t1 = ( float ) clock() / CLOCKS_PER_SEC; - - if (!flags[InfoOnly]) - { - logMgr = new LogManager(); - logMgr->createLog("lwo2mesh.log", true); - resourceGroupMgr = new ResourceGroupManager(); - mth = new Math(); - matMgr = new MaterialManager(); - matMgr->initialise(); - meshMgr = new MeshManager(); - skelMgr = new SkeletonManager(); - meshSerializer = new MeshSerializer(); - materialSerializer = new MaterialSerializer(); - skeletonSerializer = new SkeletonSerializer(); - bufferMgr = new DefaultHardwareBufferManager(); // needed because we don't have a rendersystem - } - - if ( strchr(source, '*') ) - // On Linux this will only be called if you pass the source argument in - // quotation marks (e.g. as LightwaveConverter "abc..*" ). Otherwise the - // shell will expand the arguments. At least, this is how it works with - // bash. - readFiles( source, dest ); - else - { - lwReader reader; - lwObject *object = reader.readObjectFromFile(source); - if ( object ) - { - if (flags[InfoOnly]) - info(object, source); - else - { - char *destname = (char *)malloc(512); - if ( !destname ) return 1; - - if (strlen(dest)) - make_destname(dest, dest, destname); - else - make_destname(dest, source, destname); - - Lwo2MeshWriter lwo2mesh; - lwo2mesh.writeLwo2Mesh(object, destname); - free(destname); - } - delete object; - } - } - - t2 = ( float ) clock() / CLOCKS_PER_SEC - t1; - - if (flags[InfoOnly]) - { - cout << "Total:" << nl - << setw(8) << nobjects << " objects" << nl - << setw(8) << nlayers << " layers" << nl - << setw(8) << nsurfs << " surfaces" << nl - << setw(8) << nclips << " clips" << nl - << setw(8) << nenvs << " envelopes" << nl - << setw(8) << npoints << " points" << nl - << setw(8) << npolygons << " polygons" << nl - << setw(8) << t2 << " seconds processing time." << endl; - } - else - { - delete bufferMgr; - delete skeletonSerializer; - delete materialSerializer; - delete meshSerializer; - delete meshMgr; - delete skelMgr; - delete matMgr; - delete mth; - delete resourceGroupMgr; - delete logMgr; - } - - return 0; - + int i = 1; + unsigned int ndistances = 0; + Real distance = 0; + char *source = 0; + char *dest = 0; + + if ( argc < 2 ) help(argv[0]); + + while (i < argc) + { + if (argv[i][0] == '-' || argv[i][0] == '/') + { + switch (argv[i++][1]) + { + case 'd': + case 'D': + i--; + flags[GenerateLOD] = true; + switch (argv[i++][2]) + { + case 'f': + case 'F': + flags[UseFixedMethod] = true; + break; + case 'p': + case 'P': + flags[UseFixedMethod] = false; + break; + default: + help(argv[0]); + } + try + { + reduction = atof(argv[i++]); + ndistances = atoi(argv[i++]); + while (ndistances > 0) + { + if (i < argc && argv[i][0] != '-' && argv[i][0] != '/') + distanceList.push_back(atof(argv[i++])); + else + ndistances = 0; + ndistances--; + } + } + catch (Exception *e) + { + ndistances = 0; + distanceList.clear(); + flags[GenerateLOD] = false; + } + break; + case 'g': + case 'G': + flags[UseSharedVertexData] = false; + break; + case 'i': + case 'I': + flags[InfoOnly] = true; + break; + case 'l': + case 'L': + flags[UseSeparateLayers] = true; + break; + case 'm': + case 'M': + flags[ExportMaterials] = false; + break; + case 'r': + case 'R': + flags[RenameMaterials] = true; + if (strlen(argv[i-1]) > 2) { + i--; + switch (argv[i++][2]) + { + case 'i': + case 'I': + flags[UseInteractiveMethod] = true; + break; + case 'o': + case 'O': + flags[UseObjectMethod] = true; // default + break; + case 'p': + case 'P': + flags[UsePrefixMethod] = true; + if (argv[i][0] != '-' && argv[i][0] != '/') + matPrefix = argv[i++]; + else + help(argv[0]); + break; + default: + help(argv[0]); + } + } + break; + case 's': + case 'S': + flags[ExportSkeleton] = false; + break; + case 'v': + case 'V': + flags[PrintVMaps] = true; + break; + default: + help(argv[0]); + } + } + else + { + if (!source) source = argv[i]; + else + if (!dest) dest = argv[i]; + i++; + } + } + + if ( !source ) help(argv[0]); + + if (!dest) dest = "\0"; + + float t1, t2; + + t1 = ( float ) clock() / CLOCKS_PER_SEC; + + if (!flags[InfoOnly]) + { + logMgr = new LogManager(); + logMgr->createLog("lwo2mesh.log", true); + resourceGroupMgr = new ResourceGroupManager(); + mth = new Math(); + matMgr = new MaterialManager(); + matMgr->initialise(); + meshMgr = new MeshManager(); + skelMgr = new SkeletonManager(); + meshSerializer = new MeshSerializer(); + materialSerializer = new MaterialSerializer(); + skeletonSerializer = new SkeletonSerializer(); + bufferMgr = new DefaultHardwareBufferManager(); // needed because we don't have a rendersystem + } + + if ( strchr(source, '*') ) + // On Linux this will only be called if you pass the source argument in + // quotation marks (e.g. as LightwaveConverter "abc..*" ). Otherwise the + // shell will expand the arguments. At least, this is how it works with + // bash. + readFiles( source, dest ); + else + { + lwReader reader; + lwObject *object = reader.readObjectFromFile(source); + if ( object ) + { + if (flags[InfoOnly]) + info(object, source); + else + { + char *destname = (char *)malloc(512); + if ( !destname ) return 1; + + if (strlen(dest)) + make_destname(dest, dest, destname); + else + make_destname(dest, source, destname); + + Lwo2MeshWriter lwo2mesh; + lwo2mesh.writeLwo2Mesh(object, destname); + free(destname); + } + delete object; + } + } + + t2 = ( float ) clock() / CLOCKS_PER_SEC - t1; + + if (flags[InfoOnly]) + { + cout << "Total:" << nl + << setw(8) << nobjects << " objects" << nl + << setw(8) << nlayers << " layers" << nl + << setw(8) << nsurfs << " surfaces" << nl + << setw(8) << nclips << " clips" << nl + << setw(8) << nenvs << " envelopes" << nl + << setw(8) << npoints << " points" << nl + << setw(8) << npolygons << " polygons" << nl + << setw(8) << t2 << " seconds processing time." << endl; + } + else + { + delete bufferMgr; + delete skeletonSerializer; + delete materialSerializer; + delete meshSerializer; + delete meshMgr; + delete skelMgr; + delete matMgr; + delete mth; + delete resourceGroupMgr; + delete logMgr; + } + + return 0; + } diff --git a/Tools/MaterialEditor/MaterialEditor/include/CallTipManager.h b/Tools/MaterialEditor/MaterialEditor/include/CallTipManager.h index 48e39ccc8f0..97ad60eee9f 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/CallTipManager.h +++ b/Tools/MaterialEditor/MaterialEditor/include/CallTipManager.h @@ -41,23 +41,23 @@ typedef list TriggerList; class CallTipManager { public: - CallTipManager(); - virtual ~CallTipManager(); + CallTipManager(); + virtual ~CallTipManager(); - void load(wxString& path); + void load(wxString& path); - void addTip(wxString& key, wxString& tip); - void removeTip(wxString& key); + void addTip(wxString& key, wxString& tip); + void removeTip(wxString& key); - void addTrigger(wxChar& trigger); - void removeTrigger(wxChar& trigger); - bool isTrigger(wxChar& ch); + void addTrigger(wxChar& trigger); + void removeTrigger(wxChar& trigger); + bool isTrigger(wxChar& ch); - wxString* find(wxString& s); + wxString* find(wxString& s); protected: - CallTipMap mCallTips; - TriggerList mTriggers; + CallTipMap mCallTips; + TriggerList mTriggers; }; #endif // _CALLTIPMANAGER_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/CgEditor.h b/Tools/MaterialEditor/MaterialEditor/include/CgEditor.h index b990224b892..163c9e344c5 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/CgEditor.h +++ b/Tools/MaterialEditor/MaterialEditor/include/CgEditor.h @@ -33,20 +33,20 @@ THE SOFTWARE. class CgEditor : public ScintillaEditor { public: - CgEditor(wxWindow* parent, wxWindowID id = -1, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxVSCROLL - ); + CgEditor(wxWindow* parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxVSCROLL + ); - virtual ~CgEditor(); + virtual ~CgEditor(); - void OnCharAdded(wxScintillaEvent &event); - + void OnCharAdded(wxScintillaEvent &event); + protected: - void initialize(); + void initialize(); - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _CGEDITOR_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/CodeEditor.h b/Tools/MaterialEditor/MaterialEditor/include/CodeEditor.h index 34f4c7ec282..51df1943b09 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/CodeEditor.h +++ b/Tools/MaterialEditor/MaterialEditor/include/CodeEditor.h @@ -6,90 +6,90 @@ class CodeEditor : public wxScintilla { public: - CodeEditor(wxWindow *parent, wxWindowID id = -1, - const wxPoint &pos = wxDefaultPosition, - const wxSize &size = wxDefaultSize, - long style = wxVSCROLL - ); + CodeEditor(wxWindow *parent, wxWindowID id = -1, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxVSCROLL + ); - ~CodeEditor(); + ~CodeEditor(); - void OnSize(wxSizeEvent &event); - // Edit - void OnEditRedo(wxCommandEvent &event); - void OnEditUndo(wxCommandEvent &event); - void OnEditClear(wxCommandEvent &event); - void OnEditCut(wxCommandEvent &event); - void OnEditCopy(wxCommandEvent &event); - void OnEditPaste(wxCommandEvent &event); - // Find - void OnFind(wxCommandEvent &event); - void OnFindNext(wxCommandEvent &event); - void OnReplace(wxCommandEvent &event); - void OnReplaceNext(wxCommandEvent &event); - void OnBraceMatch(wxCommandEvent &event); - void OnGoto(wxCommandEvent &event); - void OnEditIndentInc(wxCommandEvent &event); - void OnEditIndentRed(wxCommandEvent &event); - void OnEditSelectAll(wxCommandEvent &event); - void OnEditSelectLine(wxCommandEvent &event); - // View - void OnHilightLang(wxCommandEvent &event); - void OnDisplayEOL(wxCommandEvent &event); - void OnIndentGuide(wxCommandEvent &event); - void OnLineNumber(wxCommandEvent &event); - void OnLongLineOn(wxCommandEvent &event); - void OnWhiteSpace(wxCommandEvent &event); - void OnFoldToggle(wxCommandEvent &event); - void OnSetOverType(wxCommandEvent &event); - void OnSetReadOnly(wxCommandEvent &event); - void OnWrapModeOn(wxCommandEvent &event); - void OnUseCharset(wxCommandEvent &event); - // Extra - void OnChangeCase(wxCommandEvent &event); - void OnConvertEOL(wxCommandEvent &event); - // Styled text - void OnMarginClick(wxScintillaEvent &event); - void OnCharAdded(wxScintillaEvent &event); - void OnUpdateUI(wxScintillaEvent &event); + void OnSize(wxSizeEvent &event); + // Edit + void OnEditRedo(wxCommandEvent &event); + void OnEditUndo(wxCommandEvent &event); + void OnEditClear(wxCommandEvent &event); + void OnEditCut(wxCommandEvent &event); + void OnEditCopy(wxCommandEvent &event); + void OnEditPaste(wxCommandEvent &event); + // Find + void OnFind(wxCommandEvent &event); + void OnFindNext(wxCommandEvent &event); + void OnReplace(wxCommandEvent &event); + void OnReplaceNext(wxCommandEvent &event); + void OnBraceMatch(wxCommandEvent &event); + void OnGoto(wxCommandEvent &event); + void OnEditIndentInc(wxCommandEvent &event); + void OnEditIndentRed(wxCommandEvent &event); + void OnEditSelectAll(wxCommandEvent &event); + void OnEditSelectLine(wxCommandEvent &event); + // View + void OnHilightLang(wxCommandEvent &event); + void OnDisplayEOL(wxCommandEvent &event); + void OnIndentGuide(wxCommandEvent &event); + void OnLineNumber(wxCommandEvent &event); + void OnLongLineOn(wxCommandEvent &event); + void OnWhiteSpace(wxCommandEvent &event); + void OnFoldToggle(wxCommandEvent &event); + void OnSetOverType(wxCommandEvent &event); + void OnSetReadOnly(wxCommandEvent &event); + void OnWrapModeOn(wxCommandEvent &event); + void OnUseCharset(wxCommandEvent &event); + // Extra + void OnChangeCase(wxCommandEvent &event); + void OnConvertEOL(wxCommandEvent &event); + // Styled text + void OnMarginClick(wxScintillaEvent &event); + void OnCharAdded(wxScintillaEvent &event); + void OnUpdateUI(wxScintillaEvent &event); - // Language/Lexer - //wxString DeterminePrefs (const wxString &filename); - //bool InitializePrefs (const wxString &filename); - //bool UserSettings (const wxString &filename); - //LanguageInfo const* GetLanguageInfo () {return m_language;}; + // Language/Lexer + //wxString DeterminePrefs (const wxString &filename); + //bool InitializePrefs (const wxString &filename); + //bool UserSettings (const wxString &filename); + //LanguageInfo const* GetLanguageInfo () {return m_language;}; - // Load/Save file - bool LoadFile(); - bool LoadFile(const wxString &filename); - bool SaveFile(); - bool SaveFile(const wxString &filename); - bool Modified(); - wxString GetFilename() {return mFileName;}; - void SetFilename(const wxString &filename) { mFileName = filename; }; + // Load/Save file + bool LoadFile(); + bool LoadFile(const wxString &filename); + bool SaveFile(); + bool SaveFile(const wxString &filename); + bool Modified(); + wxString GetFilename() {return mFileName;}; + void SetFilename(const wxString &filename) { mFileName = filename; }; protected: - wxChar GetLastNonWhitespaceChar(int position = -1); - wxString CodeEditor::GetLineIndentString(int line); - int FindBlockStart(int position, wxChar blockStart, wxChar blockEnd, bool skipNested = true); + wxChar GetLastNonWhitespaceChar(int position = -1); + wxString CodeEditor::GetLineIndentString(int line); + int FindBlockStart(int position, wxChar blockStart, wxChar blockEnd, bool skipNested = true); - void HighlightBraces(); + void HighlightBraces(); private: - // File - wxString mFileName; + // File + wxString mFileName; - // lanugage properties - //LanguageInfo const* m_language; + // lanugage properties + //LanguageInfo const* m_language; - // Margin variables - int mLineNumID; - int mLineNumMargin; - int mFoldingID; - int mFoldingMargin; - int mDividerID; + // Margin variables + int mLineNumID; + int mLineNumMargin; + int mFoldingID; + int mFoldingMargin; + int mDividerID; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _CODEEDITOR_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/DocManager.h b/Tools/MaterialEditor/MaterialEditor/include/DocManager.h index bf0b09f5143..02a1727a06e 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/DocManager.h +++ b/Tools/MaterialEditor/MaterialEditor/include/DocManager.h @@ -40,18 +40,18 @@ typedef map DocMap; class DocManager { public: - DocManager(); - virtual ~DocManager(); + DocManager(); + virtual ~DocManager(); - void load(wxString& path); + void load(wxString& path); - void addDoc(wxString& key, wxString& doc); - void removeDoc(wxString& key); + void addDoc(wxString& key, wxString& doc); + void removeDoc(wxString& key); - wxString* find(wxString& s); + wxString* find(wxString& s); protected: - DocMap mDocs; + DocMap mDocs; }; #endif // _DOCMANAGER_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/DocPanel.h b/Tools/MaterialEditor/MaterialEditor/include/DocPanel.h index 2b10c881e11..787b74826bf 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/DocPanel.h +++ b/Tools/MaterialEditor/MaterialEditor/include/DocPanel.h @@ -16,17 +16,17 @@ using Ogre::String; class DocPanel : public wxPanel { public: - DocPanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = "LogPanel"); - ~DocPanel(); + DocPanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = "LogPanel"); + ~DocPanel(); - void OnActiveEditorChanged(EventArgs& args); - void OnFocusedWordChanged(EventArgs& args); + void OnActiveEditorChanged(EventArgs& args); + void OnFocusedWordChanged(EventArgs& args); protected: - wxBoxSizer* mBoxSizer; - wxTextCtrl* mTextControl; + wxBoxSizer* mBoxSizer; + wxTextCtrl* mTextControl; - ScintillaEditor* mEditor; + ScintillaEditor* mEditor; }; #endif // _DOCPANEL_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/Editor.h b/Tools/MaterialEditor/MaterialEditor/include/Editor.h index 680fa09d31b..63a06bee77b 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/Editor.h +++ b/Tools/MaterialEditor/MaterialEditor/include/Editor.h @@ -45,53 +45,53 @@ using Ogre::String; class Editor : public EventContainer { public: - enum EditorEvent - { - NameChanged, - DirtyStateChanged - }; - - Editor(); - Editor(EditorInput* input); - virtual ~Editor(); - - wxControl* getControl() const; - void setControl(wxControl* control); - - EditorInput* getEditorInput() const; - void setEditorInput(EditorInput* input); - - EditorContributor* getEditorContributor() const; - - const wxString& getName() const; - void setName(const wxString& name); - - virtual void activate(); - virtual void deactivate(); - - virtual bool isDirty(); - virtual void save(); - virtual void saveAs(); - virtual bool isSaveAsAllowed(); - - virtual bool isRedoable(); - virtual void redo(); - virtual bool isUndoable(); - virtual void undo(); - - virtual bool isCuttable(); - virtual void cut(); - virtual bool isCopyable(); - virtual void copy(); - virtual bool isPastable(); - virtual void paste(); + enum EditorEvent + { + NameChanged, + DirtyStateChanged + }; + + Editor(); + Editor(EditorInput* input); + virtual ~Editor(); + + wxControl* getControl() const; + void setControl(wxControl* control); + + EditorInput* getEditorInput() const; + void setEditorInput(EditorInput* input); + + EditorContributor* getEditorContributor() const; + + const wxString& getName() const; + void setName(const wxString& name); + + virtual void activate(); + virtual void deactivate(); + + virtual bool isDirty(); + virtual void save(); + virtual void saveAs(); + virtual bool isSaveAsAllowed(); + + virtual bool isRedoable(); + virtual void redo(); + virtual bool isUndoable(); + virtual void undo(); + + virtual bool isCuttable(); + virtual void cut(); + virtual bool isCopyable(); + virtual void copy(); + virtual bool isPastable(); + virtual void paste(); private: - void registerEvents(); + void registerEvents(); - EditorInput* mEditorInput; - wxControl* mControl; - wxString mName; + EditorInput* mEditorInput; + wxControl* mControl; + wxString mName; }; #endif // _EDITOR_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/EditorContributor.h b/Tools/MaterialEditor/MaterialEditor/include/EditorContributor.h index 84c62383e71..1cfd1c4f3fd 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/EditorContributor.h +++ b/Tools/MaterialEditor/MaterialEditor/include/EditorContributor.h @@ -33,11 +33,11 @@ THE SOFTWARE. class EditorContributor { public: - EditorContributor() {} - virtual ~EditorContributor() {} + EditorContributor() {} + virtual ~EditorContributor() {} - virtual void contributeToMenu(wxMenu* menu) {} - virtual void contributeToToolBar(wxToolBar* toolBar) {} + virtual void contributeToMenu(wxMenu* menu) {} + virtual void contributeToToolBar(wxToolBar* toolBar) {} }; #endif // _EDITORCONTRIBUTOR_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/EditorEventArgs.h b/Tools/MaterialEditor/MaterialEditor/include/EditorEventArgs.h index 37e18ca091e..8dbad5fd08e 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/EditorEventArgs.h +++ b/Tools/MaterialEditor/MaterialEditor/include/EditorEventArgs.h @@ -30,11 +30,11 @@ THE SOFTWARE. class EditorEventArgs : public EventArgs { public: - EditorEventArgs(Editor* editor) : mEditor(editor) {} - virtual ~EditorEventArgs() {} + EditorEventArgs(Editor* editor) : mEditor(editor) {} + virtual ~EditorEventArgs() {} - Editor* getEditor() { return mEditor; } + Editor* getEditor() { return mEditor; } protected: - Editor* mEditor; + Editor* mEditor; }; \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/EditorInput.h b/Tools/MaterialEditor/MaterialEditor/include/EditorInput.h index 5850c4b232f..c42b7cb98bf 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/EditorInput.h +++ b/Tools/MaterialEditor/MaterialEditor/include/EditorInput.h @@ -38,11 +38,11 @@ using Ogre::String; class EditorInput { public: - EditorInput(); - virtual ~EditorInput(); + EditorInput(); + virtual ~EditorInput(); - virtual String& getName() = 0; - virtual String& getToolTipText() = 0; + virtual String& getName() = 0; + virtual String& getToolTipText() = 0; }; #endif // _EDITORINPUT_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/EditorManager.h b/Tools/MaterialEditor/MaterialEditor/include/EditorManager.h index 556f7055311..6f166636cfc 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/EditorManager.h +++ b/Tools/MaterialEditor/MaterialEditor/include/EditorManager.h @@ -54,76 +54,76 @@ using Ogre::String; class EditorManager : public wxEvtHandler, public Ogre::Singleton, public EventContainer { public: - enum EditorManagerEvent - { - EditorOpened, - EditorClosed, - ActiveEditorChanged - }; - - EditorManager(wxAuiNotebook* notebook); - virtual ~EditorManager(); - - wxAuiNotebook* getEditorNotebook() const; - void setEditorNotebook(wxAuiNotebook* notebook); - - void openEditor(Editor* editor); - //void openEditor(EditorInput* input); - void closeEditor(Editor* editor); - //void closeEditor(EditorInput* input); - Editor* findEditor(const wxString& name); - - Editor* getActiveEditor() const; - void setActiveEditor(Editor* editor); - - const EditorList& getEditors() const; - - void nameChanged(EventArgs& args); - - void OnPageChanged(wxAuiNotebookEvent& event); - void OnPageClosed(wxAuiNotebookEvent& event); - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static EditorManager& getSingleton(void); - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static EditorManager* getSingletonPtr(void); + enum EditorManagerEvent + { + EditorOpened, + EditorClosed, + ActiveEditorChanged + }; + + EditorManager(wxAuiNotebook* notebook); + virtual ~EditorManager(); + + wxAuiNotebook* getEditorNotebook() const; + void setEditorNotebook(wxAuiNotebook* notebook); + + void openEditor(Editor* editor); + //void openEditor(EditorInput* input); + void closeEditor(Editor* editor); + //void closeEditor(EditorInput* input); + Editor* findEditor(const wxString& name); + + Editor* getActiveEditor() const; + void setActiveEditor(Editor* editor); + + const EditorList& getEditors() const; + + void nameChanged(EventArgs& args); + + void OnPageChanged(wxAuiNotebookEvent& event); + void OnPageClosed(wxAuiNotebookEvent& event); + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static EditorManager& getSingleton(void); + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static EditorManager* getSingletonPtr(void); protected: - void registerEvents(); + void registerEvents(); - EditorList mEditors; - EditorIndexMap mEditorIndexMap; - Editor* mActiveEditor; - wxAuiNotebook* mEditorNotebook; + EditorList mEditors; + EditorIndexMap mEditorIndexMap; + Editor* mActiveEditor; + wxAuiNotebook* mEditorNotebook; }; #endif // _EDITORMANAGER_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/EventArgs.h b/Tools/MaterialEditor/MaterialEditor/include/EventArgs.h index 84ceae590ee..cbb82f4c56a 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/EventArgs.h +++ b/Tools/MaterialEditor/MaterialEditor/include/EventArgs.h @@ -31,8 +31,8 @@ THE SOFTWARE class EventArgs { public: - EventArgs() {} - virtual ~EventArgs() {} + EventArgs() {} + virtual ~EventArgs() {} }; #endif // _EVENTARGS_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/EventContainer.h b/Tools/MaterialEditor/MaterialEditor/include/EventContainer.h index 75ff7b7db06..97c662c983f 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/EventContainer.h +++ b/Tools/MaterialEditor/MaterialEditor/include/EventContainer.h @@ -43,18 +43,18 @@ typedef std::map DelegateMap; class EventContainer { public: - EventContainer(); - virtual ~EventContainer(); + EventContainer(); + virtual ~EventContainer(); - void subscribe(int eventId, EventHandler handler); - void unsubscribe(int eventId, EventHandler handler); - + void subscribe(int eventId, EventHandler handler); + void unsubscribe(int eventId, EventHandler handler); + protected: - void registerEvent(int eventId); - void fireEvent(int eventId, EventArgs& args); - + void registerEvent(int eventId); + void fireEvent(int eventId, EventArgs& args); + private: - DelegateMap mDelegates; + DelegateMap mDelegates; }; #endif // _EVENTCONTAINER_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/GLSLEditor.h b/Tools/MaterialEditor/MaterialEditor/include/GLSLEditor.h index 4394c63153f..9687d1b5840 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/GLSLEditor.h +++ b/Tools/MaterialEditor/MaterialEditor/include/GLSLEditor.h @@ -33,20 +33,20 @@ THE SOFTWARE. class GLSLEditor : public ScintillaEditor { public: - GLSLEditor(wxWindow* parent, wxWindowID id = -1, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxVSCROLL - ); + GLSLEditor(wxWindow* parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxVSCROLL + ); - virtual ~GLSLEditor(); + virtual ~GLSLEditor(); - void OnCharAdded(wxScintillaEvent &event); - + void OnCharAdded(wxScintillaEvent &event); + protected: - void initialize(); + void initialize(); - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; diff --git a/Tools/MaterialEditor/MaterialEditor/include/HLSLEditor.h b/Tools/MaterialEditor/MaterialEditor/include/HLSLEditor.h index e48c26332a6..4503fed1df5 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/HLSLEditor.h +++ b/Tools/MaterialEditor/MaterialEditor/include/HLSLEditor.h @@ -33,16 +33,16 @@ THE SOFTWARE. class HLSLEditor : public ScintillaEditor { public: - HLSLEditor(wxWindow* parent, wxWindowID id = -1, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxVSCROLL - ); - - virtual ~HLSLEditor(); - + HLSLEditor(wxWindow* parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxVSCROLL + ); + + virtual ~HLSLEditor(); + protected: - void initialize(); + void initialize(); }; #endif // _HLSLEDITOR_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/IconManager.h b/Tools/MaterialEditor/MaterialEditor/include/IconManager.h index 0def9996512..4604839d153 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/IconManager.h +++ b/Tools/MaterialEditor/MaterialEditor/include/IconManager.h @@ -52,37 +52,37 @@ THE SOFTWARE class IconManager : public Ogre::Singleton { public: - IconManager(); - ~IconManager(); + IconManager(); + ~IconManager(); - enum IconType - { - CLOSE, - COPY, - CUT, - MATERIAL, - MATERIAL_SCRIPT, - OGRE, - PASS, - PASTE, - PROGRAM_SCRIPT, - PROJECT, - PROJECT_NEW, - PROJECT_SAVE, - SAVE, - SAVE_AS, - SHADER, - TECHNIQUE, - WORKSPACE - }; + enum IconType + { + CLOSE, + COPY, + CUT, + MATERIAL, + MATERIAL_SCRIPT, + OGRE, + PASS, + PASTE, + PROGRAM_SCRIPT, + PROJECT, + PROJECT_NEW, + PROJECT_SAVE, + SAVE, + SAVE_AS, + SHADER, + TECHNIQUE, + WORKSPACE + }; - const wxBitmap& getIcon(IconType type) const; + const wxBitmap& getIcon(IconType type) const; - static IconManager& getSingleton(void); - static IconManager* getSingletonPtr(void); + static IconManager& getSingleton(void); + static IconManager* getSingletonPtr(void); private: - typedef std::map IconMap; - IconMap mIconMap; + typedef std::map IconMap; + IconMap mIconMap; }; #endif diff --git a/Tools/MaterialEditor/MaterialEditor/include/LogPanel.h b/Tools/MaterialEditor/MaterialEditor/include/LogPanel.h index 719dc115adf..eee0bbaa122 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/LogPanel.h +++ b/Tools/MaterialEditor/MaterialEditor/include/LogPanel.h @@ -16,17 +16,17 @@ using Ogre::String; class LogPanel : public wxPanel, public Ogre::LogListener { public: - LogPanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = "LogPanel"); - ~LogPanel(); + LogPanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = "LogPanel"); + ~LogPanel(); - void attachLog(Ogre::Log *log); - void detachLog(Ogre::Log *log); + void attachLog(Ogre::Log *log); + void detachLog(Ogre::Log *log); - virtual void messageLogged(const Ogre::String& message, Ogre::LogMessageLevel lml, bool maskDebug, const Ogre::String &logName); + virtual void messageLogged(const Ogre::String& message, Ogre::LogMessageLevel lml, bool maskDebug, const Ogre::String &logName); protected: - wxBoxSizer* mBoxSizer; - wxTextCtrl* mTextControl; + wxBoxSizer* mBoxSizer; + wxTextCtrl* mTextControl; }; #endif // _LOGPANEL_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/LogToTextRedirector.h b/Tools/MaterialEditor/MaterialEditor/include/LogToTextRedirector.h index 1cd3ca9a5b5..907706974ce 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/LogToTextRedirector.h +++ b/Tools/MaterialEditor/MaterialEditor/include/LogToTextRedirector.h @@ -15,14 +15,14 @@ using Ogre::String; class LogToTextRedirector : public LogListener { public: - LogToTextRedirector(wxTextCtrl* textCtrl, const String& logName); - ~LogToTextRedirector(); + LogToTextRedirector(wxTextCtrl* textCtrl, const String& logName); + ~LogToTextRedirector(); - void messageLogged(const String& message, LogMessageLevel level, bool maskDebug, const String &logName); + void messageLogged(const String& message, LogMessageLevel level, bool maskDebug, const String &logName); protected: - wxTextCtrl* mTextControl; - String mLogName; + wxTextCtrl* mTextControl; + String mLogName; }; #endif // _LOGTOTEXTREDIRECTOR_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/MaterialController.h b/Tools/MaterialEditor/MaterialEditor/include/MaterialController.h index 768beffd798..142719b485f 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/MaterialController.h +++ b/Tools/MaterialEditor/MaterialEditor/include/MaterialController.h @@ -38,7 +38,7 @@ THE SOFTWARE namespace Ogre { - class Technique; + class Technique; } class TechniqueController; @@ -50,62 +50,62 @@ typedef std::list TechniqueControllerList; class MaterialController : public EventContainer { public: - enum MaterialEvent - { - NameChanged, - TechniqueAdded, - TechniqueRemoved - }; - - MaterialController(); - MaterialController(MaterialPtr material); - virtual ~MaterialController(); - - MaterialPtr getMaterial() const; - void setMaterial(MaterialPtr mp); - - TechniqueController* getTechniqueController(const String& name); - const TechniqueControllerList* getTechniqueControllers() const; - - void setName(const String& name); - void setReceiveShadows(bool enabled); - void setTransparencyCastsShadows(bool enabled); - TechniqueController* createTechnique(void); - TechniqueController* createTechnique(const String& name); - void removeTechnique(unsigned short index); - void removeAllTechniques(void); - - void setAmbient(const ColourValue& ambient); - void setAmbient(Real red, Real green, Real blue); - void setColourWriteEnabled(bool enabled); - void setCullingMode(CullingMode mode); - void setDepthBias(float constantBias, float slopeScaleBias); - void setDepthCheckEnabled(bool enabled); - void setDepthFunction(CompareFunction func); - void setDepthWriteEnabled(bool enabled); - void setDiffuse(const ColourValue& diffuse); - void setDiffuse(Real red, Real green, Real blue, Real alpha); - void setFog(bool overrideScene, FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 0.001, Real linearStart = 0.0, Real linearEnd = 1.0); - void setLightingEnabled(bool enabled); - void setManualCullingMode(ManualCullingMode mode); - void setPointSize(Real ps); - void setSceneBlending(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor); - void setSceneBlending(const SceneBlendType sbt); - void setSelfIllumination(const ColourValue& selfIllum); - void setSelfIllumination(Real red, Real green, Real blue); - void setShadingMode(ShadeOptions mode); - void setShininess(Real val); - void setSpecular(const ColourValue& specular); - void setSpecular(Real red, Real green, Real blue, Real alpha); - void setTextureAnisotropy(unsigned int maxAniso); - void setTextureFiltering(TextureFilterOptions filterType); + enum MaterialEvent + { + NameChanged, + TechniqueAdded, + TechniqueRemoved + }; + + MaterialController(); + MaterialController(MaterialPtr material); + virtual ~MaterialController(); + + MaterialPtr getMaterial() const; + void setMaterial(MaterialPtr mp); + + TechniqueController* getTechniqueController(const String& name); + const TechniqueControllerList* getTechniqueControllers() const; + + void setName(const String& name); + void setReceiveShadows(bool enabled); + void setTransparencyCastsShadows(bool enabled); + TechniqueController* createTechnique(void); + TechniqueController* createTechnique(const String& name); + void removeTechnique(unsigned short index); + void removeAllTechniques(void); + + void setAmbient(const ColourValue& ambient); + void setAmbient(Real red, Real green, Real blue); + void setColourWriteEnabled(bool enabled); + void setCullingMode(CullingMode mode); + void setDepthBias(float constantBias, float slopeScaleBias); + void setDepthCheckEnabled(bool enabled); + void setDepthFunction(CompareFunction func); + void setDepthWriteEnabled(bool enabled); + void setDiffuse(const ColourValue& diffuse); + void setDiffuse(Real red, Real green, Real blue, Real alpha); + void setFog(bool overrideScene, FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 0.001, Real linearStart = 0.0, Real linearEnd = 1.0); + void setLightingEnabled(bool enabled); + void setManualCullingMode(ManualCullingMode mode); + void setPointSize(Real ps); + void setSceneBlending(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor); + void setSceneBlending(const SceneBlendType sbt); + void setSelfIllumination(const ColourValue& selfIllum); + void setSelfIllumination(Real red, Real green, Real blue); + void setShadingMode(ShadeOptions mode); + void setShininess(Real val); + void setSpecular(const ColourValue& specular); + void setSpecular(Real red, Real green, Real blue, Real alpha); + void setTextureAnisotropy(unsigned int maxAniso); + void setTextureFiltering(TextureFilterOptions filterType); protected: - void registerEvents(); + void registerEvents(); - MaterialPtr mMaterialPtr; + MaterialPtr mMaterialPtr; - TechniqueControllerList mTechniqueControllers; + TechniqueControllerList mTechniqueControllers; }; #endif // _MATERIALCONTROLLER_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/MaterialDescriptor.h b/Tools/MaterialEditor/MaterialEditor/include/MaterialDescriptor.h index a342ebb4033..e3c4b3390c5 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/MaterialDescriptor.h +++ b/Tools/MaterialEditor/MaterialEditor/include/MaterialDescriptor.h @@ -42,23 +42,23 @@ using Ogre::String; class MaterialDescriptor { public: - MaterialDescriptor(); - MaterialDescriptor(const String& name); - virtual ~MaterialDescriptor(); - - const String& getName() const; - const String& getScript() const; - MaterialController* getMaterialController(); - MaterialPtr& getMaterial(); - void setMaterial(MaterialPtr& mp); - - void OnRootInitialized(EventArgs& args); - void OnRootShutdown(EventArgs& args); - + MaterialDescriptor(); + MaterialDescriptor(const String& name); + virtual ~MaterialDescriptor(); + + const String& getName() const; + const String& getScript() const; + MaterialController* getMaterialController(); + MaterialPtr& getMaterial(); + void setMaterial(MaterialPtr& mp); + + void OnRootInitialized(EventArgs& args); + void OnRootShutdown(EventArgs& args); + protected: - String mName; - String mScript; - MaterialController* mMaterialController; + String mName; + String mScript; + MaterialController* mMaterialController; }; #endif _MATERIALDESCRIPTOR_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/MaterialEditorApp.h b/Tools/MaterialEditor/MaterialEditor/include/MaterialEditorApp.h index 7539b4a6921..b54e11f434c 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/MaterialEditorApp.h +++ b/Tools/MaterialEditor/MaterialEditor/include/MaterialEditorApp.h @@ -35,13 +35,13 @@ using Ogre::Root; class MaterialEditorApp : public wxApp { public: - virtual ~MaterialEditorApp(); + virtual ~MaterialEditorApp(); private: - virtual bool OnInit(); - virtual int OnExit(); + virtual bool OnInit(); + virtual int OnExit(); - Root* mRoot; + Root* mRoot; }; IMPLEMENT_APP(MaterialEditorApp) diff --git a/Tools/MaterialEditor/MaterialEditor/include/MaterialEditorFrame.h b/Tools/MaterialEditor/MaterialEditor/include/MaterialEditorFrame.h index 79a405e349f..9a851ea66b9 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/MaterialEditorFrame.h +++ b/Tools/MaterialEditor/MaterialEditor/include/MaterialEditorFrame.h @@ -41,8 +41,8 @@ class wxTreeCtrl; namespace { - class RenderSystem; - class Root; + class RenderSystem; + class Root; } class DocPanel; @@ -56,73 +56,73 @@ class wxOgre; class MaterialEditorFrame : public wxFrame { public: - MaterialEditorFrame(wxWindow* parent = NULL); - ~MaterialEditorFrame(); + MaterialEditorFrame(wxWindow* parent = NULL); + ~MaterialEditorFrame(); protected: - void createAuiManager(void); - void createAuiNotebookPane(void); - void createManagementPane(void); - void createInformationPane(void); - void createPropertiesPane(); - void createOgrePane(void); - - void createMenuBar(void); - void createFileMenu(void); - void createEditMenu(void); - void createViewMenu(void); - void createToolsMenu(void); - void createWindowMenu(void); - void createHelpMenu(void); - - void OnActivate(wxActivateEvent& event); - - void OnActiveEditorChanged(EventArgs& args); - - void OnNewProject(wxCommandEvent& event); - void OnNewMaterial(wxCommandEvent& event); - void OnFileOpen(wxCommandEvent& event); - void OnFileSave(wxCommandEvent& event); - void OnFileSaveAs(wxCommandEvent& event); - void OnFileClose(wxCommandEvent& event); - void OnFileExit(wxCommandEvent& event); - void OnEditUndo(wxCommandEvent& event); - void OnEditRedo(wxCommandEvent& event); - void OnEditCut(wxCommandEvent& event); - void OnEditCopy(wxCommandEvent& event); - void OnEditPaste(wxCommandEvent& event); - void OnViewOpenGL(wxCommandEvent& event); - void OnViewDirectX(wxCommandEvent& event); + void createAuiManager(void); + void createAuiNotebookPane(void); + void createManagementPane(void); + void createInformationPane(void); + void createPropertiesPane(); + void createOgrePane(void); + + void createMenuBar(void); + void createFileMenu(void); + void createEditMenu(void); + void createViewMenu(void); + void createToolsMenu(void); + void createWindowMenu(void); + void createHelpMenu(void); + + void OnActivate(wxActivateEvent& event); + + void OnActiveEditorChanged(EventArgs& args); + + void OnNewProject(wxCommandEvent& event); + void OnNewMaterial(wxCommandEvent& event); + void OnFileOpen(wxCommandEvent& event); + void OnFileSave(wxCommandEvent& event); + void OnFileSaveAs(wxCommandEvent& event); + void OnFileClose(wxCommandEvent& event); + void OnFileExit(wxCommandEvent& event); + void OnEditUndo(wxCommandEvent& event); + void OnEditRedo(wxCommandEvent& event); + void OnEditCut(wxCommandEvent& event); + void OnEditCopy(wxCommandEvent& event); + void OnEditPaste(wxCommandEvent& event); + void OnViewOpenGL(wxCommandEvent& event); + void OnViewDirectX(wxCommandEvent& event); private: - wxMenuBar* mMenuBar; - wxMenu* mFileMenu; - wxMenu* mEditMenu; - wxMenu* mViewMenu; - wxMenu* mToolsMenu; - wxMenu* mWindowMenu; - wxMenu* mHelpMenu; - - wxAuiManager* mAuiManager; - - wxAuiNotebook* mAuiNotebook; - wxAuiNotebook* mManagementNotebook; - wxAuiNotebook* mInformationNotebook; - WorkspacePanel* mWorkspacePanel; - ResourcePanel* mResourcePanel; - PropertiesPanel* mPropertiesPanel; - - Ogre::Root* mRoot; - Ogre::Entity* mEntity; - - LogPanel* mLogPanel; - DocPanel* mDocPanel; - wxOgre* mOgreControl; - - Ogre::RenderSystem* mDirectXRenderSystem; - Ogre::RenderSystem* mOpenGLRenderSystem; - - DECLARE_EVENT_TABLE(); + wxMenuBar* mMenuBar; + wxMenu* mFileMenu; + wxMenu* mEditMenu; + wxMenu* mViewMenu; + wxMenu* mToolsMenu; + wxMenu* mWindowMenu; + wxMenu* mHelpMenu; + + wxAuiManager* mAuiManager; + + wxAuiNotebook* mAuiNotebook; + wxAuiNotebook* mManagementNotebook; + wxAuiNotebook* mInformationNotebook; + WorkspacePanel* mWorkspacePanel; + ResourcePanel* mResourcePanel; + PropertiesPanel* mPropertiesPanel; + + Ogre::Root* mRoot; + Ogre::Entity* mEntity; + + LogPanel* mLogPanel; + DocPanel* mDocPanel; + wxOgre* mOgreControl; + + Ogre::RenderSystem* mDirectXRenderSystem; + Ogre::RenderSystem* mOpenGLRenderSystem; + + DECLARE_EVENT_TABLE(); }; #endif // _MATERIALEDITORFRAME_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/MaterialEventArgs.h b/Tools/MaterialEditor/MaterialEditor/include/MaterialEventArgs.h index e55f0da5613..52630eccbfc 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/MaterialEventArgs.h +++ b/Tools/MaterialEditor/MaterialEditor/include/MaterialEventArgs.h @@ -36,15 +36,15 @@ class TechniqueController; class MaterialEventArgs : public EventArgs { public: - MaterialEventArgs(MaterialController* mc); - MaterialEventArgs(MaterialController* mc, TechniqueController* tc); + MaterialEventArgs(MaterialController* mc); + MaterialEventArgs(MaterialController* mc, TechniqueController* tc); - MaterialController* getMaterialController() const; - TechniqueController* getTechniqueController() const; + MaterialController* getMaterialController() const; + TechniqueController* getTechniqueController() const; protected: - MaterialController* mMaterialController; - TechniqueController* mTechniqueController; + MaterialController* mMaterialController; + TechniqueController* mTechniqueController; }; #endif // _MATERIALEVENTARGS_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/MaterialPage.h b/Tools/MaterialEditor/MaterialEditor/include/MaterialPage.h index 6f9530d5895..05ecbcb596d 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/MaterialPage.h +++ b/Tools/MaterialEditor/MaterialEditor/include/MaterialPage.h @@ -40,23 +40,23 @@ class Project; class MaterialPage : public wxWizardPageSimple { public: - MaterialPage(wxWizard* parent); - virtual ~MaterialPage(); + MaterialPage(wxWizard* parent); + virtual ~MaterialPage(); - void getName(wxString& name) const; - Project* getProject() const; - void setProject(Project* project); + void getName(wxString& name) const; + Project* getProject() const; + void setProject(Project* project); protected: - void createPage(); + void createPage(); - wxBoxSizer* mSizer; - wxStaticText* mProjectLabel; - wxComboBox* mProjectComboBox; - wxStaticText* mNameLabel; - wxTextCtrl* mNameText; + wxBoxSizer* mSizer; + wxStaticText* mProjectLabel; + wxComboBox* mProjectComboBox; + wxStaticText* mNameLabel; + wxTextCtrl* mNameText; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _MATERIALPAGE_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/MaterialPropertyGridPage.h b/Tools/MaterialEditor/MaterialEditor/include/MaterialPropertyGridPage.h index 2bf02afa9b2..c15090499ee 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/MaterialPropertyGridPage.h +++ b/Tools/MaterialEditor/MaterialEditor/include/MaterialPropertyGridPage.h @@ -36,20 +36,20 @@ class MaterialController; class MaterialPropertyGridPage : public wxPropertyGridPage { public: - MaterialPropertyGridPage(MaterialController* controller); - virtual ~MaterialPropertyGridPage(); - virtual void populate(); + MaterialPropertyGridPage(MaterialController* controller); + virtual ~MaterialPropertyGridPage(); + virtual void populate(); protected: - virtual void propertyChange(wxPropertyGridEvent& event); + virtual void propertyChange(wxPropertyGridEvent& event); - MaterialController* mController; + MaterialController* mController; - wxPGId mPropertyNameId; - wxPGId mPropertyReceiveShadowsId; - wxPGId mPropertyTransparencyCastsShadowsId; + wxPGId mPropertyNameId; + wxPGId mPropertyReceiveShadowsId; + wxPGId mPropertyTransparencyCastsShadowsId; - DECLARE_EVENT_TABLE(); + DECLARE_EVENT_TABLE(); }; #endif // _MATERIALPROPERTYGRIDPAGE_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/MaterialScriptEditor.h b/Tools/MaterialEditor/MaterialEditor/include/MaterialScriptEditor.h index ebcb9566ca7..f6db617cfee 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/MaterialScriptEditor.h +++ b/Tools/MaterialEditor/MaterialEditor/include/MaterialScriptEditor.h @@ -33,20 +33,20 @@ THE SOFTWARE. class MaterialScriptEditor : public ScintillaEditor { public: - MaterialScriptEditor(wxWindow* parent, wxWindowID id = -1, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxVSCROLL - ); + MaterialScriptEditor(wxWindow* parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxVSCROLL + ); - virtual ~MaterialScriptEditor(); + virtual ~MaterialScriptEditor(); - void OnCharAdded(wxScintillaEvent &event); + void OnCharAdded(wxScintillaEvent &event); protected: - void initialize(); + void initialize(); - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _MATERIALSCRIPTEDITOR_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/MaterialWizard.h b/Tools/MaterialEditor/MaterialEditor/include/MaterialWizard.h index 86f57a30c94..aa7380bc039 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/MaterialWizard.h +++ b/Tools/MaterialEditor/MaterialEditor/include/MaterialWizard.h @@ -35,19 +35,19 @@ THE SOFTWARE class MaterialWizard : public wxWizard { public: - MaterialWizard(); - virtual ~MaterialWizard(); + MaterialWizard(); + virtual ~MaterialWizard(); - bool Create(wxWindow* parent, int id = -1, const wxString& title = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, const wxPoint& pos = wxDefaultPosition, long style = wxDEFAULT_DIALOG_STYLE); + bool Create(wxWindow* parent, int id = -1, const wxString& title = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, const wxPoint& pos = wxDefaultPosition, long style = wxDEFAULT_DIALOG_STYLE); - MaterialPage* getMaterialPage() const; + MaterialPage* getMaterialPage() const; - void OnFinish(wxWizardEvent& event); + void OnFinish(wxWizardEvent& event); protected: - MaterialPage* mMaterialPage; + MaterialPage* mMaterialPage; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _MATERIALWIZARD_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/PassController.h b/Tools/MaterialEditor/MaterialEditor/include/PassController.h index dda4ee35332..920e76ffdb9 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/PassController.h +++ b/Tools/MaterialEditor/MaterialEditor/include/PassController.h @@ -12,8 +12,8 @@ namespace Ogre { - class ColourValue; - class Pass; + class ColourValue; + class Pass; } class TechniqueController; @@ -23,102 +23,102 @@ using namespace Ogre; class PassController : public EventContainer { public: - enum PassEvent - { - NameChanged, - AmbientChanged, - DiffuseChanged, - SpecularChanged, - ShininessChanged, - SelfIllumChanged, - VertexColourTrackingChanged, - PointSizeChanged, - PointSpritesChanged, - PointAttenuationChanged, - PointMinSizeChanged, - PointMaxSizeChanged, - SceneBlendingTypeChanged, - SceneBlendSrcFactorChanged, - SceneBlendDestFactorChanged, - DepthCheckChanged, - DepthWriteChanged, - DepthFunctionChanged, - ColourWriteChanged, - CullingModeChanged, - ManualCullingModeChanged, - LightingChanged, - MaxLightsChanged, - StartLightChanged, - ShadingModeChanged, - PolygonModeChanged, - FogChanged, - DepthBiasChanged, - AlphaRejectionChanged, - IteratePerLightChanged, - LightCountPerIterationChanged, - }; + enum PassEvent + { + NameChanged, + AmbientChanged, + DiffuseChanged, + SpecularChanged, + ShininessChanged, + SelfIllumChanged, + VertexColourTrackingChanged, + PointSizeChanged, + PointSpritesChanged, + PointAttenuationChanged, + PointMinSizeChanged, + PointMaxSizeChanged, + SceneBlendingTypeChanged, + SceneBlendSrcFactorChanged, + SceneBlendDestFactorChanged, + DepthCheckChanged, + DepthWriteChanged, + DepthFunctionChanged, + ColourWriteChanged, + CullingModeChanged, + ManualCullingModeChanged, + LightingChanged, + MaxLightsChanged, + StartLightChanged, + ShadingModeChanged, + PolygonModeChanged, + FogChanged, + DepthBiasChanged, + AlphaRejectionChanged, + IteratePerLightChanged, + LightCountPerIterationChanged, + }; - PassController(Pass* pass); - PassController(TechniqueController* parent, Pass* pass); - virtual ~PassController(); - - TechniqueController* getParentController() const; - Pass* getPass() const; - - void registerEvents(); + PassController(Pass* pass); + PassController(TechniqueController* parent, Pass* pass); + virtual ~PassController(); + + TechniqueController* getParentController() const; + Pass* getPass() const; + + void registerEvents(); - void setName(const String& name); - void setAmbient(Real red, Real green, Real blue); - void setAmbient(const ColourValue& ambient); - void setDiffuse(Real red, Real green, Real blue, Real alpha); - void setDiffuse(const ColourValue &diffuse); - void setSpecular(Real red, Real green, Real blue, Real alpha); - void setSpecular(const ColourValue &specular); - void setShininess(Real val); - void setSelfIllumination(Real red, Real green, Real blue); - void setSelfIllumination(const ColourValue &selfIllum); - void setVertexColourTracking(TrackVertexColourType tracking); - void setPointSize(Real ps); - void setPointSpritesEnabled(bool enabled); - void setPointAttenuation(bool enabled, Real constant=0.0f, Real linear=1.0f, Real quadratic=0.0f); - void setPointMinSize(Real min); - void setPointMaxSize(Real max); - void setSceneBlending(const SceneBlendType sbt); - void setSceneBlending(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor); - void setDepthCheckEnabled(bool enabled); - void setDepthWriteEnabled(bool enabled); - void setDepthFunction(CompareFunction func); - void setColourWriteEnabled(bool enabled); - void setCullingMode(CullingMode mode); - void setManualCullingMode(ManualCullingMode mode); - void setLightingEnabled(bool enabled); - void setMaxSimultaneousLights(unsigned short maxLights); - void setStartLight(unsigned short startLight); - void setShadingMode(ShadeOptions mode); - void setPolygonMode(PolygonMode mode); - void setFog(bool overrideScene, FogMode mode=FOG_NONE, const ColourValue &colour=ColourValue::White, Real expDensity=0.001, Real linearStart=0.0, Real linearEnd=1.0); - void setDepthBias(float constantBias, float slopeScaleBias=0.0f); - void setAlphaRejectSettings(CompareFunction func, unsigned char value); - void setAlphaRejectFunction(CompareFunction func); - void setAlphaRejectValue(unsigned char val); - void setIteratePerLight(bool enabled, bool onlyForOneLightType=true, Light::LightTypes lightType=Light::LT_POINT); - void setLightCountPerIteration(unsigned short c); - void setVertexProgram(const String &name, bool resetParams=true); - void setVertexProgramParameters(GpuProgramParametersSharedPtr params); - void setShadowCasterVertexProgram(const String &name); - void setShadowCasterVertexProgramParameters(GpuProgramParametersSharedPtr params); - void setShadowReceiverVertexProgram(const String &name); - void setShadowReceiverVertexProgramParameters(GpuProgramParametersSharedPtr params); - void setShadowReceiverFragmentProgram(const String &name); - void setShadowReceiverFragmentProgramParameters(GpuProgramParametersSharedPtr params); - void setFragmentProgram(const String &name, bool resetParams=true); - void setFragmentProgramParameters(GpuProgramParametersSharedPtr params); - void setTextureFiltering(TextureFilterOptions filterType); - void setTextureAnisotropy(unsigned int maxAniso); - + void setName(const String& name); + void setAmbient(Real red, Real green, Real blue); + void setAmbient(const ColourValue& ambient); + void setDiffuse(Real red, Real green, Real blue, Real alpha); + void setDiffuse(const ColourValue &diffuse); + void setSpecular(Real red, Real green, Real blue, Real alpha); + void setSpecular(const ColourValue &specular); + void setShininess(Real val); + void setSelfIllumination(Real red, Real green, Real blue); + void setSelfIllumination(const ColourValue &selfIllum); + void setVertexColourTracking(TrackVertexColourType tracking); + void setPointSize(Real ps); + void setPointSpritesEnabled(bool enabled); + void setPointAttenuation(bool enabled, Real constant=0.0f, Real linear=1.0f, Real quadratic=0.0f); + void setPointMinSize(Real min); + void setPointMaxSize(Real max); + void setSceneBlending(const SceneBlendType sbt); + void setSceneBlending(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor); + void setDepthCheckEnabled(bool enabled); + void setDepthWriteEnabled(bool enabled); + void setDepthFunction(CompareFunction func); + void setColourWriteEnabled(bool enabled); + void setCullingMode(CullingMode mode); + void setManualCullingMode(ManualCullingMode mode); + void setLightingEnabled(bool enabled); + void setMaxSimultaneousLights(unsigned short maxLights); + void setStartLight(unsigned short startLight); + void setShadingMode(ShadeOptions mode); + void setPolygonMode(PolygonMode mode); + void setFog(bool overrideScene, FogMode mode=FOG_NONE, const ColourValue &colour=ColourValue::White, Real expDensity=0.001, Real linearStart=0.0, Real linearEnd=1.0); + void setDepthBias(float constantBias, float slopeScaleBias=0.0f); + void setAlphaRejectSettings(CompareFunction func, unsigned char value); + void setAlphaRejectFunction(CompareFunction func); + void setAlphaRejectValue(unsigned char val); + void setIteratePerLight(bool enabled, bool onlyForOneLightType=true, Light::LightTypes lightType=Light::LT_POINT); + void setLightCountPerIteration(unsigned short c); + void setVertexProgram(const String &name, bool resetParams=true); + void setVertexProgramParameters(GpuProgramParametersSharedPtr params); + void setShadowCasterVertexProgram(const String &name); + void setShadowCasterVertexProgramParameters(GpuProgramParametersSharedPtr params); + void setShadowReceiverVertexProgram(const String &name); + void setShadowReceiverVertexProgramParameters(GpuProgramParametersSharedPtr params); + void setShadowReceiverFragmentProgram(const String &name); + void setShadowReceiverFragmentProgramParameters(GpuProgramParametersSharedPtr params); + void setFragmentProgram(const String &name, bool resetParams=true); + void setFragmentProgramParameters(GpuProgramParametersSharedPtr params); + void setTextureFiltering(TextureFilterOptions filterType); + void setTextureAnisotropy(unsigned int maxAniso); + protected: - Pass* mPass; - TechniqueController* mParentController; + Pass* mPass; + TechniqueController* mParentController; }; #endif // _PASSCONTROLLER_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/PassEventArgs.h b/Tools/MaterialEditor/MaterialEditor/include/PassEventArgs.h index 750477eefe8..d570d460eb1 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/PassEventArgs.h +++ b/Tools/MaterialEditor/MaterialEditor/include/PassEventArgs.h @@ -35,12 +35,12 @@ class PassController; class PassEventArgs : public EventArgs { public: - PassEventArgs(PassController* pass); + PassEventArgs(PassController* pass); - PassController* getPassController() const; + PassController* getPassController() const; protected: - PassController* mPassController; + PassController* mPassController; }; #endif // _PASSEVENTARGS_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/PassPage.h b/Tools/MaterialEditor/MaterialEditor/include/PassPage.h index bcf1d8d171d..2cb5c4452c7 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/PassPage.h +++ b/Tools/MaterialEditor/MaterialEditor/include/PassPage.h @@ -43,48 +43,48 @@ class TechniqueController; class PassPage : public wxWizardPageSimple { public: - PassPage(wxWizard* parent); - PassPage(wxWizard* parent, Project* project); - PassPage(wxWizard* parent, Project* project, MaterialController* mc); - PassPage(wxWizard* parent, Project* project, MaterialController* mc, TechniqueController* tc); - virtual ~PassPage(); + PassPage(wxWizard* parent); + PassPage(wxWizard* parent, Project* project); + PassPage(wxWizard* parent, Project* project, MaterialController* mc); + PassPage(wxWizard* parent, Project* project, MaterialController* mc, TechniqueController* tc); + virtual ~PassPage(); - void getName(wxString& name) const; + void getName(wxString& name) const; - Project* getProject() const; - void setProject(Project* project); + Project* getProject() const; + void setProject(Project* project); - MaterialController* getMaterial() const; - void setMaterial(MaterialController* mc); + MaterialController* getMaterial() const; + void setMaterial(MaterialController* mc); - TechniqueController* getTechnique() const; - void setTechnique(TechniqueController* mc); + TechniqueController* getTechnique() const; + void setTechnique(TechniqueController* mc); - void populateMaterials(const MaterialControllerList* materials); - void populateTechniques(const TechniqueControllerList* techniques); + void populateMaterials(const MaterialControllerList* materials); + void populateTechniques(const TechniqueControllerList* techniques); - void OnProjectSelected(wxCommandEvent& event); - void OnMaterialSelected(wxCommandEvent& event); - //void OnTechniqueSelected(wxCommandEvent& event); + void OnProjectSelected(wxCommandEvent& event); + void OnMaterialSelected(wxCommandEvent& event); + //void OnTechniqueSelected(wxCommandEvent& event); protected: - void createPage(); - - wxBoxSizer* mSizer; - wxStaticText* mProjectLabel; - wxComboBox* mProjectComboBox; - wxStaticText* mMaterialLabel; - wxComboBox* mMaterialComboBox; - wxStaticText* mTechniqueLabel; - wxComboBox* mTechniqueComboBox; - wxStaticText* mNameLabel; - wxTextCtrl* mNameText; - - Project* mProject; - MaterialController* mMaterial; - TechniqueController* mTechnique; - - DECLARE_EVENT_TABLE() + void createPage(); + + wxBoxSizer* mSizer; + wxStaticText* mProjectLabel; + wxComboBox* mProjectComboBox; + wxStaticText* mMaterialLabel; + wxComboBox* mMaterialComboBox; + wxStaticText* mTechniqueLabel; + wxComboBox* mTechniqueComboBox; + wxStaticText* mNameLabel; + wxTextCtrl* mNameText; + + Project* mProject; + MaterialController* mMaterial; + TechniqueController* mTechnique; + + DECLARE_EVENT_TABLE() }; #endif // _PASSPAGE_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/PassPropertyGridPage.h b/Tools/MaterialEditor/MaterialEditor/include/PassPropertyGridPage.h index 40a483bf1c6..3474b314a10 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/PassPropertyGridPage.h +++ b/Tools/MaterialEditor/MaterialEditor/include/PassPropertyGridPage.h @@ -36,76 +36,76 @@ class PassController; class PassPropertyGridPage : public wxPropertyGridPage { public: - PassPropertyGridPage(PassController* controller); - virtual ~PassPropertyGridPage(); + PassPropertyGridPage(PassController* controller); + virtual ~PassPropertyGridPage(); - virtual void populate(); + virtual void populate(); protected: - virtual void createGeneralCategory(); - virtual void createReflectanceCategory(); - virtual void createPointCategory(); - virtual void createSceneBlendingCategory(); - virtual void createDepthCategory(); - virtual void createCullingCategory(); - virtual void createIlluminationCategory(); - virtual void createFogCategory(); - virtual void createAlphaRejectionCategory(); - virtual void createMiscCategory(); - - virtual void propertyChanged(wxPropertyGridEvent& event); - - PassController* mController; - - wxPGId mNameId; - - wxPGId mAmbientId; - wxPGId mDiffuseId; - wxPGId mSpecularId; - wxPGId mShininessId; - - wxPGId mPointSizeId; - wxPGId mPointSpritesId; - wxPGId mAttenuationId; - wxPGId mPointAttenuationId; - wxPGId mPointMinSizeId; - wxPGId mPointMaxSizeId; - wxPGId mPointAttenuationConstantId; - wxPGId mPointAttenuationLinearId; - wxPGId mPointAttenuationQuadraticId; - - wxPGId mSceneBlendTypeId; - wxPGId mSrcSceneBlendTypeId; - wxPGId mDestSceneBlendTypeId; - - wxPGId mDepthCheckId; - wxPGId mDepthWriteId; - wxPGId mDepthFunctionId; - wxPGId mDepthBiasId; - wxPGId mDepthBiasConstantId; - wxPGId mDepthBiasSlopeId; - - wxPGId mManualCullingModeId; - - wxPGId mLightingId; - wxPGId mMaxLightsId; - wxPGId mStartLightId; - wxPGId mIterationId; - wxPGId mShadingModeId; - wxPGId mSelfIlluminationId; - - wxPGId mOverrideSceneId; - wxPGId mFogOverrideId; - wxPGId mFogModeId; - - wxPGId mAlphaRejectFuncId; - wxPGId mAlphaRejectValueId; - - wxPGId mColourWriteId; - wxPGId mPolygonModeId; - wxPGId mTrackVertexColourTypeId; - - DECLARE_EVENT_TABLE(); + virtual void createGeneralCategory(); + virtual void createReflectanceCategory(); + virtual void createPointCategory(); + virtual void createSceneBlendingCategory(); + virtual void createDepthCategory(); + virtual void createCullingCategory(); + virtual void createIlluminationCategory(); + virtual void createFogCategory(); + virtual void createAlphaRejectionCategory(); + virtual void createMiscCategory(); + + virtual void propertyChanged(wxPropertyGridEvent& event); + + PassController* mController; + + wxPGId mNameId; + + wxPGId mAmbientId; + wxPGId mDiffuseId; + wxPGId mSpecularId; + wxPGId mShininessId; + + wxPGId mPointSizeId; + wxPGId mPointSpritesId; + wxPGId mAttenuationId; + wxPGId mPointAttenuationId; + wxPGId mPointMinSizeId; + wxPGId mPointMaxSizeId; + wxPGId mPointAttenuationConstantId; + wxPGId mPointAttenuationLinearId; + wxPGId mPointAttenuationQuadraticId; + + wxPGId mSceneBlendTypeId; + wxPGId mSrcSceneBlendTypeId; + wxPGId mDestSceneBlendTypeId; + + wxPGId mDepthCheckId; + wxPGId mDepthWriteId; + wxPGId mDepthFunctionId; + wxPGId mDepthBiasId; + wxPGId mDepthBiasConstantId; + wxPGId mDepthBiasSlopeId; + + wxPGId mManualCullingModeId; + + wxPGId mLightingId; + wxPGId mMaxLightsId; + wxPGId mStartLightId; + wxPGId mIterationId; + wxPGId mShadingModeId; + wxPGId mSelfIlluminationId; + + wxPGId mOverrideSceneId; + wxPGId mFogOverrideId; + wxPGId mFogModeId; + + wxPGId mAlphaRejectFuncId; + wxPGId mAlphaRejectValueId; + + wxPGId mColourWriteId; + wxPGId mPolygonModeId; + wxPGId mTrackVertexColourTypeId; + + DECLARE_EVENT_TABLE(); }; #endif // _PASSPROPERTYGRIDPAGE_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/PassWizard.h b/Tools/MaterialEditor/MaterialEditor/include/PassWizard.h index aee32c3bbb4..15e025718ed 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/PassWizard.h +++ b/Tools/MaterialEditor/MaterialEditor/include/PassWizard.h @@ -35,19 +35,19 @@ THE SOFTWARE class PassWizard : public wxWizard { public: - PassWizard(); - virtual ~PassWizard(); + PassWizard(); + virtual ~PassWizard(); - bool Create(wxWindow* parent, int id = -1, const wxString& title = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, const wxPoint& pos = wxDefaultPosition, long style = wxDEFAULT_DIALOG_STYLE); + bool Create(wxWindow* parent, int id = -1, const wxString& title = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, const wxPoint& pos = wxDefaultPosition, long style = wxDEFAULT_DIALOG_STYLE); - PassPage* getPassPage() const; + PassPage* getPassPage() const; - void OnFinish(wxWizardEvent& event); + void OnFinish(wxWizardEvent& event); protected: - PassPage* mPassPage; + PassPage* mPassPage; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _PASSWIZARD_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/Project.h b/Tools/MaterialEditor/MaterialEditor/include/Project.h index f4f09ec9a57..ff06ed11b5b 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/Project.h +++ b/Tools/MaterialEditor/MaterialEditor/include/Project.h @@ -39,7 +39,7 @@ THE SOFTWARE. namespace Ogre { - class SceneManager; + class SceneManager; } class MaterialController; @@ -55,57 +55,57 @@ typedef std::list MaterialControllerList; class Project : public EventContainer { public: - enum ProjectEvent - { - NameChanged, - MaterialAdded, - MaterialRemoved, - ActiveMaterialChanged - }; - - Project(); - Project(const String& name); - virtual ~Project(); - - void registerEvents(); - - const String& getName() const; - void setName(const String& name); - - void addMaterial(MaterialPtr materialPtr); - void createMaterial(const String& name); - - void removeMaterial(MaterialController* controller); - void removeMaterial(Material* material); - void removeMaterial(const String& name); - - MaterialController* getActiveMaterial() const; - void setActiveMaterial(MaterialController* controller); - void setActiveMaterial(Material* material); - void setActiveMaterial(const String& name); - - MaterialController* getMaterialController(const String& name); - - const MaterialControllerList* getMaterials() const; - - void open(); - void close(); - - bool isOpen(); - bool isClosed(); - - void generateScene(Ogre::SceneManager* sceneManager); - - void OnRootInitialized(EventArgs& args); - void OnRootShutdown(EventArgs& args); + enum ProjectEvent + { + NameChanged, + MaterialAdded, + MaterialRemoved, + ActiveMaterialChanged + }; + + Project(); + Project(const String& name); + virtual ~Project(); + + void registerEvents(); + + const String& getName() const; + void setName(const String& name); + + void addMaterial(MaterialPtr materialPtr); + void createMaterial(const String& name); + + void removeMaterial(MaterialController* controller); + void removeMaterial(Material* material); + void removeMaterial(const String& name); + + MaterialController* getActiveMaterial() const; + void setActiveMaterial(MaterialController* controller); + void setActiveMaterial(Material* material); + void setActiveMaterial(const String& name); + + MaterialController* getMaterialController(const String& name); + + const MaterialControllerList* getMaterials() const; + + void open(); + void close(); + + bool isOpen(); + bool isClosed(); + + void generateScene(Ogre::SceneManager* sceneManager); + + void OnRootInitialized(EventArgs& args); + void OnRootShutdown(EventArgs& args); protected: - String mName; - bool mOpen; - MaterialController* mActiveMaterial; - MaterialControllerList mMaterialControllers; - - void subscribeTo(RootEventPlugin* plugin); + String mName; + bool mOpen; + MaterialController* mActiveMaterial; + MaterialControllerList mMaterialControllers; + + void subscribeTo(RootEventPlugin* plugin); }; #endif // _PROJECT_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/ProjectEventArgs.h b/Tools/MaterialEditor/MaterialEditor/include/ProjectEventArgs.h index 7267cd97fd9..47f95b28006 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/ProjectEventArgs.h +++ b/Tools/MaterialEditor/MaterialEditor/include/ProjectEventArgs.h @@ -36,15 +36,15 @@ class MaterialController; class ProjectEventArgs : public EventArgs { public: - ProjectEventArgs(Project* project); - ProjectEventArgs(Project* project, MaterialController* material); + ProjectEventArgs(Project* project); + ProjectEventArgs(Project* project, MaterialController* material); - Project* getProject() const; - MaterialController* getMaterial() const; + Project* getProject() const; + MaterialController* getMaterial() const; protected: - Project* mProject; - MaterialController* mMaterial; + Project* mProject; + MaterialController* mMaterial; }; #endif // _PROJECTEVENTARGS_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/ProjectPage.h b/Tools/MaterialEditor/MaterialEditor/include/ProjectPage.h index 7422f6f2dba..e69c10e9781 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/ProjectPage.h +++ b/Tools/MaterialEditor/MaterialEditor/include/ProjectPage.h @@ -38,25 +38,25 @@ class wxTextCtrl; class ProjectPage : public wxWizardPageSimple { public: - ProjectPage(wxWizard* parent); - virtual ~ProjectPage(); + ProjectPage(wxWizard* parent); + virtual ~ProjectPage(); - void getName(wxString& name) const; - void getLocation(wxString& location) const; + void getName(wxString& name) const; + void getLocation(wxString& location) const; - void OnBrowse(wxCommandEvent& event); + void OnBrowse(wxCommandEvent& event); protected: - void createPage(); + void createPage(); - wxBoxSizer* mSizer; - wxStaticText* mNameLabel; - wxTextCtrl* mNameText; - wxStaticText* mLocationLabel; - wxTextCtrl* mLocationText; - wxButton* mBrowseButton; + wxBoxSizer* mSizer; + wxStaticText* mNameLabel; + wxTextCtrl* mNameText; + wxStaticText* mLocationLabel; + wxTextCtrl* mLocationText; + wxButton* mBrowseButton; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _PROJECTPAGE_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/ProjectWizard.h b/Tools/MaterialEditor/MaterialEditor/include/ProjectWizard.h index 6008d847342..05138701204 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/ProjectWizard.h +++ b/Tools/MaterialEditor/MaterialEditor/include/ProjectWizard.h @@ -35,19 +35,19 @@ THE SOFTWARE class ProjectWizard : public wxWizard { public: - ProjectWizard(); - virtual ~ProjectWizard(); + ProjectWizard(); + virtual ~ProjectWizard(); - bool Create(wxWindow* parent, int id = -1, const wxString& title = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, const wxPoint& pos = wxDefaultPosition, long style = wxDEFAULT_DIALOG_STYLE); + bool Create(wxWindow* parent, int id = -1, const wxString& title = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, const wxPoint& pos = wxDefaultPosition, long style = wxDEFAULT_DIALOG_STYLE); - ProjectPage* getProjectPage() const; + ProjectPage* getProjectPage() const; - void OnFinish(wxWizardEvent& event); + void OnFinish(wxWizardEvent& event); protected: - ProjectPage* mProjectPage; + ProjectPage* mProjectPage; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _PROJECTWIZARD_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/PropertiesPanel.h b/Tools/MaterialEditor/MaterialEditor/include/PropertiesPanel.h index 595ebace115..492ef935aea 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/PropertiesPanel.h +++ b/Tools/MaterialEditor/MaterialEditor/include/PropertiesPanel.h @@ -56,31 +56,31 @@ typedef std::map PassPageIndexMap; class PropertiesPanel : public wxPanel { public: - PropertiesPanel(wxWindow* parent, - wxWindowID id = wxID_ANY, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxTAB_TRAVERSAL | wxNO_BORDER, - const wxString& name = wxT("Properties Panel")); + PropertiesPanel(wxWindow* parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTAB_TRAVERSAL | wxNO_BORDER, + const wxString& name = wxT("Properties Panel")); - virtual ~PropertiesPanel(); + virtual ~PropertiesPanel(); - void selectionChanged(EventArgs& args); + void selectionChanged(EventArgs& args); - void projectRemoved(EventArgs& args); - void materialRemoved(EventArgs& args); - void techniqueRemoved(EventArgs& args); - void passRemoved(EventArgs& args); + void projectRemoved(EventArgs& args); + void materialRemoved(EventArgs& args); + void techniqueRemoved(EventArgs& args); + void passRemoved(EventArgs& args); protected: - wxGridSizer* mGridSizer; - wxPropertyGridManager* mPropertyGrid; + wxGridSizer* mGridSizer; + wxPropertyGridManager* mPropertyGrid; - MaterialPageIndexMap mMaterialPageIndexMap; - TechniquePageIndexMap mTechniquePageIndexMap; - PassPageIndexMap mPassPageIndexMap; + MaterialPageIndexMap mMaterialPageIndexMap; + TechniquePageIndexMap mTechniquePageIndexMap; + PassPageIndexMap mPassPageIndexMap; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _PROPERTIESPANEL_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/ResourcePanel.h b/Tools/MaterialEditor/MaterialEditor/include/ResourcePanel.h index c7218a568c3..899c6851aa2 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/ResourcePanel.h +++ b/Tools/MaterialEditor/MaterialEditor/include/ResourcePanel.h @@ -9,12 +9,12 @@ class wxTreeCtrl; class ResourcePanel : public wxPanel { public: - ResourcePanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = "ResourcePanel"); - ~ResourcePanel(); + ResourcePanel(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL, const wxString& name = "ResourcePanel"); + ~ResourcePanel(); private: - wxBoxSizer* mBoxSizer; - wxTreeCtrl* mTreeControl; + wxBoxSizer* mBoxSizer; + wxTreeCtrl* mTreeControl; }; #endif // _RESOURCEPANEL_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/RootEventArgs.h b/Tools/MaterialEditor/MaterialEditor/include/RootEventArgs.h index 62e87fea864..ddd319f0ac3 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/RootEventArgs.h +++ b/Tools/MaterialEditor/MaterialEditor/include/RootEventArgs.h @@ -33,7 +33,7 @@ THE SOFTWARE class RootEventArgs : public EventArgs { public: - RootEventArgs() {} + RootEventArgs() {} }; #endif // _ROOTEVENTARGS_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/RootEventPlugin.h b/Tools/MaterialEditor/MaterialEditor/include/RootEventPlugin.h index e5b37d423ca..0cc076f25a1 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/RootEventPlugin.h +++ b/Tools/MaterialEditor/MaterialEditor/include/RootEventPlugin.h @@ -41,58 +41,58 @@ using Ogre::String; class RootEventPlugin : public Singleton, Plugin, EventContainer { public: - enum RootEvent - { - Initialized, - Shutdown, - }; - - RootEventPlugin(); - virtual ~RootEventPlugin(); - - const String& getName() const; - void install(); - void initialise(); - void shutdown(); - void uninstall(); - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static RootEventPlugin& getSingleton(void); + enum RootEvent + { + Initialized, + Shutdown, + }; + + RootEventPlugin(); + virtual ~RootEventPlugin(); + + const String& getName() const; + void install(); + void initialise(); + void shutdown(); + void uninstall(); + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static RootEventPlugin& getSingleton(void); - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static RootEventPlugin* getSingletonPtr(void); + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static RootEventPlugin* getSingletonPtr(void); protected: - void registerEvents(); + void registerEvents(); }; #endif // _ROOTEVENTPLUGIN_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/ScintillaEditor.h b/Tools/MaterialEditor/MaterialEditor/include/ScintillaEditor.h index f18cd6c255f..9ab59823f72 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/ScintillaEditor.h +++ b/Tools/MaterialEditor/MaterialEditor/include/ScintillaEditor.h @@ -13,98 +13,98 @@ class ScintillaEditor; class ScintillaEditorEventArgs : public EventArgs { public: - ScintillaEditorEventArgs(ScintillaEditor* editor, wxString word) : mEditor(editor), mFocusedWord(word) {} - ~ScintillaEditorEventArgs() {} + ScintillaEditorEventArgs(ScintillaEditor* editor, wxString word) : mEditor(editor), mFocusedWord(word) {} + ~ScintillaEditorEventArgs() {} - ScintillaEditor* getEditor() { return mEditor; } - wxString& getFocusedWord() { return mFocusedWord; } + ScintillaEditor* getEditor() { return mEditor; } + wxString& getFocusedWord() { return mFocusedWord; } protected: - ScintillaEditor* mEditor; - wxString mFocusedWord; + ScintillaEditor* mEditor; + wxString mFocusedWord; }; class ScintillaEditor : public wxScintilla, public Editor { public: - enum ScintillaEditorEvent - { - NameChanged, // Editor Event - DirtyStateChanged, // Editor Event - FocusedWordChanged - }; - - ScintillaEditor(wxWindow* parent, wxWindowID id = -1, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxVSCROLL - ); - - virtual ~ScintillaEditor(); - - virtual void activate(); - virtual void deactivate(); - - DocManager& getDocManager(); - CallTipManager& getCallTipManager(); - - virtual bool isDirty(); - virtual void save(); - virtual void saveAs(); - virtual bool isSaveAsAllowed(); - - virtual bool isRedoable(); - virtual void redo(); - virtual bool isUndoable(); - virtual void undo(); - - virtual bool isCuttable(); - virtual void cut(); - virtual bool isCopyable(); - virtual void copy(); - virtual bool isPastable(); - virtual void paste(); - - virtual void loadKeywords(wxString& path); - - virtual bool loadFile(); - virtual bool loadFile(const wxString &filename); - - void OnSize(wxSizeEvent &event); - void OnMarginClick(wxScintillaEvent &event); - void OnCharAdded(wxScintillaEvent &event); - void OnUpdateUI(wxScintillaEvent &event); + enum ScintillaEditorEvent + { + NameChanged, // Editor Event + DirtyStateChanged, // Editor Event + FocusedWordChanged + }; + + ScintillaEditor(wxWindow* parent, wxWindowID id = -1, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxVSCROLL + ); + + virtual ~ScintillaEditor(); + + virtual void activate(); + virtual void deactivate(); + + DocManager& getDocManager(); + CallTipManager& getCallTipManager(); + + virtual bool isDirty(); + virtual void save(); + virtual void saveAs(); + virtual bool isSaveAsAllowed(); + + virtual bool isRedoable(); + virtual void redo(); + virtual bool isUndoable(); + virtual void undo(); + + virtual bool isCuttable(); + virtual void cut(); + virtual bool isCopyable(); + virtual void copy(); + virtual bool isPastable(); + virtual void paste(); + + virtual void loadKeywords(wxString& path); + + virtual bool loadFile(); + virtual bool loadFile(const wxString &filename); + + void OnSize(wxSizeEvent &event); + void OnMarginClick(wxScintillaEvent &event); + void OnCharAdded(wxScintillaEvent &event); + void OnUpdateUI(wxScintillaEvent &event); protected: - wxString getSurroundingWord(int pos = -1); - wxChar getLastNonWhitespaceChar(int position = -1); - wxString getLineIndentString(int line); - int findBlockStart(int position, wxChar blockStart, wxChar blockEnd, bool skipNested = true); + wxString getSurroundingWord(int pos = -1); + wxChar getLastNonWhitespaceChar(int position = -1); + wxString getLineIndentString(int line); + int findBlockStart(int position, wxChar blockStart, wxChar blockEnd, bool skipNested = true); - void highlightBraces(); + void highlightBraces(); - void setDirty(bool dirty); + void setDirty(bool dirty); - CallTipManager mCallTipManager; - DocManager mDocManager; + CallTipManager mCallTipManager; + DocManager mDocManager; - bool mDirty; + bool mDirty; - int mLastPos; - wxString mLastWord; + int mLastPos; + wxString mLastWord; - // File - wxString mFileName; + // File + wxString mFileName; private: - // Margin variables - int mLineNumID; - int mLineNumMargin; - int mFoldingID; - int mFoldingMargin; - int mDividerID; - - DECLARE_EVENT_TABLE() + // Margin variables + int mLineNumID; + int mLineNumMargin; + int mFoldingID; + int mFoldingMargin; + int mDividerID; + + DECLARE_EVENT_TABLE() }; #endif // _SCINTILLAEDITOR_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/SelectionEventArgs.h b/Tools/MaterialEditor/MaterialEditor/include/SelectionEventArgs.h index 2bec87ac299..ffe960891d2 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/SelectionEventArgs.h +++ b/Tools/MaterialEditor/MaterialEditor/include/SelectionEventArgs.h @@ -39,16 +39,16 @@ typedef std::list SelectionList; class SelectionEventArgs : public EventArgs { public: - SelectionEventArgs(SelectionList& selection); - SelectionEventArgs(boost::any& source, SelectionList& selection); - virtual ~SelectionEventArgs(); - - const boost::any& getSource() const; - const SelectionList& getSelection() const; + SelectionEventArgs(SelectionList& selection); + SelectionEventArgs(boost::any& source, SelectionList& selection); + virtual ~SelectionEventArgs(); + + const boost::any& getSource() const; + const SelectionList& getSelection() const; protected: - boost::any mSource; - SelectionList mSelection; + boost::any mSource; + SelectionList mSelection; }; #endif _SELECTIONEVENTARGS_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/SelectionService.h b/Tools/MaterialEditor/MaterialEditor/include/SelectionService.h index 3c67fbb5e22..d72e94a78fd 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/SelectionService.h +++ b/Tools/MaterialEditor/MaterialEditor/include/SelectionService.h @@ -34,7 +34,7 @@ THE SOFTWARE. namespace boost { - class any; + class any; } typedef std::list SelectionList; @@ -42,56 +42,56 @@ typedef std::list SelectionList; class SelectionService : public Ogre::Singleton, public EventContainer { public: - enum SelectionEvent - { - SelectionChanged - }; - - SelectionService(); - virtual ~SelectionService(); - - const SelectionList& getSelection() const; - void setSelection(boost::any& sel); - void setSelection(const SelectionList& sel); - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static SelectionService& getSingleton(void); + enum SelectionEvent + { + SelectionChanged + }; + + SelectionService(); + virtual ~SelectionService(); + + const SelectionList& getSelection() const; + void setSelection(boost::any& sel); + void setSelection(const SelectionList& sel); + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static SelectionService& getSingleton(void); - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static SelectionService* getSingletonPtr(void); - + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static SelectionService* getSingletonPtr(void); + protected: - void registerEvents(); - - SelectionList mSelection; + void registerEvents(); + + SelectionList mSelection; }; diff --git a/Tools/MaterialEditor/MaterialEditor/include/Subject.h b/Tools/MaterialEditor/MaterialEditor/include/Subject.h index 7648b5739ce..22cd6853e69 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/Subject.h +++ b/Tools/MaterialEditor/MaterialEditor/include/Subject.h @@ -13,10 +13,10 @@ class Subject { virtual void attach(Observer*); virtual void detach(Observer*); virtual void notify(); - + protected: Subject(); - + private: ObserverList mObservers; }; @@ -24,8 +24,8 @@ class Subject { Subject::Subject() {} Subject::~Subject() -{ - // TODO: Clear list! +{ + // TODO: Clear list! } void Subject::attach(Observer* o) { @@ -38,10 +38,10 @@ void Subject::detach(Observer* o) { void Subject::notify () { ObserverList::iterator it; - for(it = mObservers.begin(); it != mObservers.end(); ++it) - { - *it->update(this); - } + for(it = mObservers.begin(); it != mObservers.end(); ++it) + { + *it->update(this); + } } #endif // _SUBJECT_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/TechniqueController.h b/Tools/MaterialEditor/MaterialEditor/include/TechniqueController.h index 4291e76972a..7895e607e50 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/TechniqueController.h +++ b/Tools/MaterialEditor/MaterialEditor/include/TechniqueController.h @@ -38,8 +38,8 @@ THE SOFTWARE. namespace Ogre { - class ColourValue; - class Technique; + class ColourValue; + class Technique; } class MaterialController; @@ -52,63 +52,63 @@ typedef std::list PassControllerList; class TechniqueController : public EventContainer { public: - enum TechniqueEvent - { - NameChanged, - SchemeChanged, - LodIndexChanged, - PassAdded, - PassRemoved - }; - - TechniqueController(Technique* technique); - TechniqueController(MaterialController* parent, Technique* technique); - virtual ~TechniqueController(); - - MaterialController* getParentController() const; - const Technique* getTechnique() const; - const PassControllerList* getPassControllers() const; - - PassController* createPass(void); - PassController* createPass(const String& name); - void removeAllPasses(void); - void removePass(unsigned short index); - - void movePass(const unsigned short sourceIndex, const unsigned short destIndex); - void setName(const String& name); - void setSchemeName(const String& schemeName); - void setLodIndex(unsigned short index); - - void setAmbient(const ColourValue& ambient); - void setAmbient(Real red, Real green, Real blue); - void setColourWriteEnabled(bool enabled); - void setCullingMode(CullingMode mode); - void setDepthBias(float constantBias, float slopeScaleBias); - void setDepthCheckEnabled(bool enabled); - void setDepthFunction(CompareFunction func); - void setDepthWriteEnabled(bool enabled); - void setDiffuse(const ColourValue& diffuse); - void setDiffuse(Real red, Real green, Real blue, Real alpha); - void setFog(bool overrideScene, FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 0.001, Real linearStart = 0.0, Real linearEnd = 1.0); - void setLightingEnabled(bool enabled); - void setManualCullingMode(ManualCullingMode mode); - void setPointSize(Real ps); - void setSceneBlending(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor); - void setSceneBlending(const SceneBlendType sbt); - void setSelfIllumination(const ColourValue& selfIllum); - void setSelfIllumination(Real red, Real green, Real blue); - void setShadingMode(ShadeOptions mode); - void setShininess(Real val); - void setSpecular(const ColourValue& specular); - void setSpecular(Real red, Real green, Real blue, Real alpha); - void setTextureAnisotropy(unsigned int maxAniso); - void setTextureFiltering(TextureFilterOptions filterType); + enum TechniqueEvent + { + NameChanged, + SchemeChanged, + LodIndexChanged, + PassAdded, + PassRemoved + }; + + TechniqueController(Technique* technique); + TechniqueController(MaterialController* parent, Technique* technique); + virtual ~TechniqueController(); + + MaterialController* getParentController() const; + const Technique* getTechnique() const; + const PassControllerList* getPassControllers() const; + + PassController* createPass(void); + PassController* createPass(const String& name); + void removeAllPasses(void); + void removePass(unsigned short index); + + void movePass(const unsigned short sourceIndex, const unsigned short destIndex); + void setName(const String& name); + void setSchemeName(const String& schemeName); + void setLodIndex(unsigned short index); + + void setAmbient(const ColourValue& ambient); + void setAmbient(Real red, Real green, Real blue); + void setColourWriteEnabled(bool enabled); + void setCullingMode(CullingMode mode); + void setDepthBias(float constantBias, float slopeScaleBias); + void setDepthCheckEnabled(bool enabled); + void setDepthFunction(CompareFunction func); + void setDepthWriteEnabled(bool enabled); + void setDiffuse(const ColourValue& diffuse); + void setDiffuse(Real red, Real green, Real blue, Real alpha); + void setFog(bool overrideScene, FogMode mode = FOG_NONE, const ColourValue& colour = ColourValue::White, Real expDensity = 0.001, Real linearStart = 0.0, Real linearEnd = 1.0); + void setLightingEnabled(bool enabled); + void setManualCullingMode(ManualCullingMode mode); + void setPointSize(Real ps); + void setSceneBlending(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor); + void setSceneBlending(const SceneBlendType sbt); + void setSelfIllumination(const ColourValue& selfIllum); + void setSelfIllumination(Real red, Real green, Real blue); + void setShadingMode(ShadeOptions mode); + void setShininess(Real val); + void setSpecular(const ColourValue& specular); + void setSpecular(Real red, Real green, Real blue, Real alpha); + void setTextureAnisotropy(unsigned int maxAniso); + void setTextureFiltering(TextureFilterOptions filterType); protected: - void registerEvents(); + void registerEvents(); - MaterialController* mParentController; - Technique* mTechnique; - PassControllerList mPassControllers; + MaterialController* mParentController; + Technique* mTechnique; + PassControllerList mPassControllers; }; #endif // _TECHNIQUECONTROLLER_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/TechniqueEventArgs.h b/Tools/MaterialEditor/MaterialEditor/include/TechniqueEventArgs.h index eb69940a950..0c6eaec9b92 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/TechniqueEventArgs.h +++ b/Tools/MaterialEditor/MaterialEditor/include/TechniqueEventArgs.h @@ -36,15 +36,15 @@ class TechniqueController; class TechniqueEventArgs : public EventArgs { public: - TechniqueEventArgs(TechniqueController* tc); - TechniqueEventArgs(TechniqueController* tc, PassController* pc); + TechniqueEventArgs(TechniqueController* tc); + TechniqueEventArgs(TechniqueController* tc, PassController* pc); - TechniqueController* getTechniqueController() const; - PassController* getPassController() const; + TechniqueController* getTechniqueController() const; + PassController* getPassController() const; protected: - TechniqueController* mTechniqueController; - PassController* mPassController; + TechniqueController* mTechniqueController; + PassController* mPassController; }; #endif // _PROJECTEVENTARGS_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/TechniquePage.h b/Tools/MaterialEditor/MaterialEditor/include/TechniquePage.h index 6d52b10fcd9..bff00aaef39 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/TechniquePage.h +++ b/Tools/MaterialEditor/MaterialEditor/include/TechniquePage.h @@ -42,38 +42,38 @@ class TechniqueController; class TechniquePage : public wxWizardPageSimple { public: - TechniquePage(wxWizard* parent); - TechniquePage(wxWizard* parent, Project* project); - TechniquePage(wxWizard* parent, Project* project, MaterialController* mc); - virtual ~TechniquePage(); + TechniquePage(wxWizard* parent); + TechniquePage(wxWizard* parent, Project* project); + TechniquePage(wxWizard* parent, Project* project, MaterialController* mc); + virtual ~TechniquePage(); - void getName(wxString& name) const; + void getName(wxString& name) const; - Project* getProject() const; - void setProject(Project* project); + Project* getProject() const; + void setProject(Project* project); - MaterialController* getMaterial() const; - void setMaterial(MaterialController* mc); + MaterialController* getMaterial() const; + void setMaterial(MaterialController* mc); - void populateMaterials(const MaterialControllerList* materials); + void populateMaterials(const MaterialControllerList* materials); - void OnProjectSelected(wxCommandEvent& event); + void OnProjectSelected(wxCommandEvent& event); protected: - void createPage(); + void createPage(); - wxBoxSizer* mSizer; - wxStaticText* mProjectLabel; - wxComboBox* mProjectComboBox; - wxStaticText* mMaterialLabel; - wxComboBox* mMaterialComboBox; - wxStaticText* mNameLabel; - wxTextCtrl* mNameText; + wxBoxSizer* mSizer; + wxStaticText* mProjectLabel; + wxComboBox* mProjectComboBox; + wxStaticText* mMaterialLabel; + wxComboBox* mMaterialComboBox; + wxStaticText* mNameLabel; + wxTextCtrl* mNameText; - Project* mProject; - MaterialController* mMaterial; + Project* mProject; + MaterialController* mMaterial; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _TECHNIQUEPAGE_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/TechniquePropertyGridPage.h b/Tools/MaterialEditor/MaterialEditor/include/TechniquePropertyGridPage.h index 874c4cd74bb..466032a3c67 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/TechniquePropertyGridPage.h +++ b/Tools/MaterialEditor/MaterialEditor/include/TechniquePropertyGridPage.h @@ -37,25 +37,25 @@ class EventArgs; class TechniquePropertyGridPage : public wxPropertyGridPage { public: - TechniquePropertyGridPage(TechniqueController* controller); - virtual ~TechniquePropertyGridPage(); + TechniquePropertyGridPage(TechniqueController* controller); + virtual ~TechniquePropertyGridPage(); - virtual void populate(); + virtual void populate(); - void nameChanged(EventArgs& args); - void schemeNameChanged(EventArgs& args); - void lodIndexChanged(EventArgs& args); + void nameChanged(EventArgs& args); + void schemeNameChanged(EventArgs& args); + void lodIndexChanged(EventArgs& args); protected: - virtual void propertyChanged(wxPropertyGridEvent& event); - - TechniqueController* mController; + virtual void propertyChanged(wxPropertyGridEvent& event); + + TechniqueController* mController; - wxPGId mNameId; - wxPGId mSchemeNameId; - wxPGId mLodIndexId; + wxPGId mNameId; + wxPGId mSchemeNameId; + wxPGId mLodIndexId; - DECLARE_EVENT_TABLE(); + DECLARE_EVENT_TABLE(); }; #endif // _TECHNIQUEPROPERTYGRIDPAGE_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/TechniqueWizard.h b/Tools/MaterialEditor/MaterialEditor/include/TechniqueWizard.h index 6ac3308c74e..0d37a1dc611 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/TechniqueWizard.h +++ b/Tools/MaterialEditor/MaterialEditor/include/TechniqueWizard.h @@ -35,19 +35,19 @@ THE SOFTWARE class TechniqueWizard : public wxWizard { public: - TechniqueWizard(); - virtual ~TechniqueWizard(); + TechniqueWizard(); + virtual ~TechniqueWizard(); - bool Create(wxWindow* parent, int id = -1, const wxString& title = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, const wxPoint& pos = wxDefaultPosition, long style = wxDEFAULT_DIALOG_STYLE); + bool Create(wxWindow* parent, int id = -1, const wxString& title = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, const wxPoint& pos = wxDefaultPosition, long style = wxDEFAULT_DIALOG_STYLE); - TechniquePage* getTechniquePage() const; + TechniquePage* getTechniquePage() const; - void OnFinish(wxWizardEvent& event); + void OnFinish(wxWizardEvent& event); protected: - TechniquePage* mTechniquePage; + TechniquePage* mTechniquePage; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #endif // _TECHNIQUEWIZARD_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/TextureUnitController.h b/Tools/MaterialEditor/MaterialEditor/include/TextureUnitController.h index 532e64a4a37..5469f985dd0 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/TextureUnitController.h +++ b/Tools/MaterialEditor/MaterialEditor/include/TextureUnitController.h @@ -47,123 +47,123 @@ class TextureUnitController; class TextureUnitEventArgs : public EventArgs { public: - TextureUnitEventArgs(TextureUnitController* tuc) : mController(tuc) {} - ~TextureUnitEventArgs() {} + TextureUnitEventArgs(TextureUnitController* tuc) : mController(tuc) {} + ~TextureUnitEventArgs() {} - TextureUnitController* getController() { return mController; } + TextureUnitController* getController() { return mController; } protected: - TextureUnitController* mController; + TextureUnitController* mController; }; class TextureUnitController : public EventContainer { public: - enum TextureUnitEvent - { - TextureNameChanged, - CubicTextureNameChanged, - AnimatedTextureNameChanged, - TextureDimensionsChanged, - CurrentFrameChanged, - FrameTextureNameChanged, - FrameTextureNameAdded, - FrameTextureNameRemoved, - BindingTypeChanged, - ContentTypeChanged, - PixelFormatChanged, - NumMipmapsChanged, - AlphaChanged, - TextureCoordSetChanged, - TextureTransformChanged, - TextureScrollChanged, - TextureUScrollChanged, - TextureVScrollChanged, - TextureUScaleChanged, - TextureVScaleChanged, - TextureRotateChanged, - TextureAddressingModeChanged, - TextureBorderColourChanged, - ColourOperationChanged, - ColourOperationExChanged, - ColourOpMultipassFallbackChanged, - AlphaOperationChanged, - EffectAdded, - EnvironmentMapChanged, - ScrollAnimationChanged, - RotateAnimationChanged, - TransformAnimationChanged, - ProjectiveTexturingChanged, - EffectRemoved, - Blanked, - TextureFilteringChanged, - TextureAnisotropyChanged, - TextureMipMapBiasChanged, - NameChanged, - TextureNameAliasChanged - }; - - TextureUnitController(); - TextureUnitController(TextureUnitState* textureUnit); - TextureUnitController(PassController* parent, TextureUnitState* textureUnit); - virtual ~TextureUnitController(); - - TextureUnitState* getTextureUnit() const; - void getTextureUnit(TextureUnitState* tus); - - PassController* getParentController() const; - - void setTextureName(const String &name, TextureType ttype); - void setCubicTextureName(const String &name, bool forUVW = false); - void setCubicTextureName(const String *const names, bool forUVW = false); - void setAnimatedTextureName(const String &name, unsigned int numFrames, Real duration = 0); - void setAnimatedTextureName(const String *const names, unsigned int numFrames, Real duration = 0); - void setCurrentFrame(unsigned int frameNumber); - void setFrameTextureName(const String &name, unsigned int frameNumber); - void addFrameTextureName(const String &name); - void deleteFrameTextureName(const size_t frameNumber); - void setBindingType(TextureUnitState::BindingType bt); - void setContentType(TextureUnitState::ContentType ct); - void setDesiredFormat(PixelFormat desiredFormat); - void setNumMipmaps(int numMipmaps); - void setTextureCoordSet(unsigned int set); - void setTextureTransform(const Matrix4 &xform); - void setTextureScroll(Real u, Real v); - void setTextureUScroll(Real value); - void setTextureUScale(Real value); - void setTextureVScale(Real value); - void setTextureScale(Real uScale, Real vScale); - void setTextureRotate(const Radian &angle); - void setTextureAddressingMode(TextureUnitState::TextureAddressingMode tam); - void setTextureAddressingMode(TextureUnitState::TextureAddressingMode u, TextureUnitState::TextureAddressingMode v, TextureUnitState::TextureAddressingMode w); - void setTextureAddressingMode(const TextureUnitState::UVWAddressingMode &uvw); - void setTextureBorderColour(const ColourValue &colour); - void setColourOperationEx(LayerBlendOperationEx op, LayerBlendSource source1 = LBS_TEXTURE, LayerBlendSource source2 = LBS_CURRENT, const ColourValue &arg1 = ColourValue::White, const ColourValue &arg2 = ColourValue::White, Real manualBlend = 0.0); - void setColourOperation(const LayerBlendOperation op); - void setColourOpMultipassFallback(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor); - void setAlphaOperation(LayerBlendOperationEx op, LayerBlendSource source1 = LBS_TEXTURE, LayerBlendSource source2 = LBS_CURRENT, Real arg1 = 1.0, Real arg2 = 1.0, Real manualBlend = 0.0); - void addEffect(TextureUnitState::TextureEffect& effect); - void setEnvironmentMap(bool enable, TextureUnitState::EnvMapType envMapType); - void setScrollAnimation(Real uSpeed, Real vSpeed); - void setRotateAnimation(Real speed); - void setTransformAnimation(const TextureUnitState::TextureTransformType ttype, const WaveformType waveType, Real base = 0, Real frequency = 1, Real phase = 0, Real amplitude = 1); - void setProjectiveTexturing(bool enabled, const Frustum* projectionSettings = 0); - void removeAllEffects(void); - void removeEffect(const TextureUnitState::TextureEffectType type); - void setBlank(void); - void setTextureFiltering(TextureFilterOptions filterType); - void setTextureFiltering(FilterOptions minFilter, FilterOptions magFilter, FilterOptions mipFilter); - void setTextureAnisotropy(unsigned int maxAniso); - void setTextureMipmapBias(float bias); - void setName(const String &name); - void setTextureNameAlias(const String &name); - bool applyTextureAliases(const AliasTextureNamePairList &aliasList, const bool apply = true); - + enum TextureUnitEvent + { + TextureNameChanged, + CubicTextureNameChanged, + AnimatedTextureNameChanged, + TextureDimensionsChanged, + CurrentFrameChanged, + FrameTextureNameChanged, + FrameTextureNameAdded, + FrameTextureNameRemoved, + BindingTypeChanged, + ContentTypeChanged, + PixelFormatChanged, + NumMipmapsChanged, + AlphaChanged, + TextureCoordSetChanged, + TextureTransformChanged, + TextureScrollChanged, + TextureUScrollChanged, + TextureVScrollChanged, + TextureUScaleChanged, + TextureVScaleChanged, + TextureRotateChanged, + TextureAddressingModeChanged, + TextureBorderColourChanged, + ColourOperationChanged, + ColourOperationExChanged, + ColourOpMultipassFallbackChanged, + AlphaOperationChanged, + EffectAdded, + EnvironmentMapChanged, + ScrollAnimationChanged, + RotateAnimationChanged, + TransformAnimationChanged, + ProjectiveTexturingChanged, + EffectRemoved, + Blanked, + TextureFilteringChanged, + TextureAnisotropyChanged, + TextureMipMapBiasChanged, + NameChanged, + TextureNameAliasChanged + }; + + TextureUnitController(); + TextureUnitController(TextureUnitState* textureUnit); + TextureUnitController(PassController* parent, TextureUnitState* textureUnit); + virtual ~TextureUnitController(); + + TextureUnitState* getTextureUnit() const; + void getTextureUnit(TextureUnitState* tus); + + PassController* getParentController() const; + + void setTextureName(const String &name, TextureType ttype); + void setCubicTextureName(const String &name, bool forUVW = false); + void setCubicTextureName(const String *const names, bool forUVW = false); + void setAnimatedTextureName(const String &name, unsigned int numFrames, Real duration = 0); + void setAnimatedTextureName(const String *const names, unsigned int numFrames, Real duration = 0); + void setCurrentFrame(unsigned int frameNumber); + void setFrameTextureName(const String &name, unsigned int frameNumber); + void addFrameTextureName(const String &name); + void deleteFrameTextureName(const size_t frameNumber); + void setBindingType(TextureUnitState::BindingType bt); + void setContentType(TextureUnitState::ContentType ct); + void setDesiredFormat(PixelFormat desiredFormat); + void setNumMipmaps(int numMipmaps); + void setTextureCoordSet(unsigned int set); + void setTextureTransform(const Matrix4 &xform); + void setTextureScroll(Real u, Real v); + void setTextureUScroll(Real value); + void setTextureUScale(Real value); + void setTextureVScale(Real value); + void setTextureScale(Real uScale, Real vScale); + void setTextureRotate(const Radian &angle); + void setTextureAddressingMode(TextureUnitState::TextureAddressingMode tam); + void setTextureAddressingMode(TextureUnitState::TextureAddressingMode u, TextureUnitState::TextureAddressingMode v, TextureUnitState::TextureAddressingMode w); + void setTextureAddressingMode(const TextureUnitState::UVWAddressingMode &uvw); + void setTextureBorderColour(const ColourValue &colour); + void setColourOperationEx(LayerBlendOperationEx op, LayerBlendSource source1 = LBS_TEXTURE, LayerBlendSource source2 = LBS_CURRENT, const ColourValue &arg1 = ColourValue::White, const ColourValue &arg2 = ColourValue::White, Real manualBlend = 0.0); + void setColourOperation(const LayerBlendOperation op); + void setColourOpMultipassFallback(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor); + void setAlphaOperation(LayerBlendOperationEx op, LayerBlendSource source1 = LBS_TEXTURE, LayerBlendSource source2 = LBS_CURRENT, Real arg1 = 1.0, Real arg2 = 1.0, Real manualBlend = 0.0); + void addEffect(TextureUnitState::TextureEffect& effect); + void setEnvironmentMap(bool enable, TextureUnitState::EnvMapType envMapType); + void setScrollAnimation(Real uSpeed, Real vSpeed); + void setRotateAnimation(Real speed); + void setTransformAnimation(const TextureUnitState::TextureTransformType ttype, const WaveformType waveType, Real base = 0, Real frequency = 1, Real phase = 0, Real amplitude = 1); + void setProjectiveTexturing(bool enabled, const Frustum* projectionSettings = 0); + void removeAllEffects(void); + void removeEffect(const TextureUnitState::TextureEffectType type); + void setBlank(void); + void setTextureFiltering(TextureFilterOptions filterType); + void setTextureFiltering(FilterOptions minFilter, FilterOptions magFilter, FilterOptions mipFilter); + void setTextureAnisotropy(unsigned int maxAniso); + void setTextureMipmapBias(float bias); + void setName(const String &name); + void setTextureNameAlias(const String &name); + bool applyTextureAliases(const AliasTextureNamePairList &aliasList, const bool apply = true); + protected: - void registerEvents(); + void registerEvents(); - PassController* mParentController; - TextureUnitState* mTextureUnit; + PassController* mParentController; + TextureUnitState* mTextureUnit; }; #endif // _TEXTUREUNITCONTROLLER_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/TextureUnitPropertyGridPage.h b/Tools/MaterialEditor/MaterialEditor/include/TextureUnitPropertyGridPage.h index e9ce0363c9f..6969744c9f7 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/TextureUnitPropertyGridPage.h +++ b/Tools/MaterialEditor/MaterialEditor/include/TextureUnitPropertyGridPage.h @@ -37,54 +37,54 @@ class EventArgs; class TextureUnitPropertyGridPage : public wxPropertyGridPage { public: - TextureUnitPropertyGridPage(TextureUnitController* controller); - virtual ~TextureUnitPropertyGridPage(); + TextureUnitPropertyGridPage(TextureUnitController* controller); + virtual ~TextureUnitPropertyGridPage(); - virtual void populate(); + virtual void populate(); - void textureNameChanged(EventArgs& args); - void cubicTextureNameChanged(EventArgs& args); - void animatedTextureNameChanged(EventArgs& args); - void textureDimensionsChanged(EventArgs& args); - void currentFrameChanged(EventArgs& args); - void frameTextureNameChanged(EventArgs& args); - void frameTextureNameAdded(EventArgs& args); - void frameTextureNameRemoved(EventArgs& args); - void bindingTypeChanged(EventArgs& args); - void contentTypeChanged(EventArgs& args); - void pixelFormatChanged(EventArgs& args); - void numMipmapsChanged(EventArgs& args); - void alphaChanged(EventArgs& args); - void textureCoordSetChanged(EventArgs& args); - void textureTransformChanged(EventArgs& args); - void textureScrollChanged(EventArgs& args); - void textureUScrollChanged(EventArgs& args); - void textureVScrollChanged(EventArgs& args); - void textureUScaleChanged(EventArgs& args); - void textureVScaleChanged(EventArgs& args); - void textureRotateChanged(EventArgs& args); - void textureAddressingModeChanged(EventArgs& args); - void textureBorderColourChanged(EventArgs& args); - void colourOperationExChanged(EventArgs& args); - void colourOpMultipassFallbackChanged(EventArgs& args); - void alphaOperationChanged(EventArgs& args); - void environmentMapChanged(EventArgs& args); - void scrollAnimationChanged(EventArgs& args); - void rotateAnimationChanged(EventArgs& args); - void transformAnimationChanged(EventArgs& args); - void projectiveTexturingChanged(EventArgs& args); - void textureFilteringChanged(EventArgs& args); - void textureAnisotropyChanged(EventArgs& args); - void textureMipMapBiasChanged(EventArgs& args); - void nameChanged(EventArgs& args); - void textureNameAliasChanged(EventArgs& args); + void textureNameChanged(EventArgs& args); + void cubicTextureNameChanged(EventArgs& args); + void animatedTextureNameChanged(EventArgs& args); + void textureDimensionsChanged(EventArgs& args); + void currentFrameChanged(EventArgs& args); + void frameTextureNameChanged(EventArgs& args); + void frameTextureNameAdded(EventArgs& args); + void frameTextureNameRemoved(EventArgs& args); + void bindingTypeChanged(EventArgs& args); + void contentTypeChanged(EventArgs& args); + void pixelFormatChanged(EventArgs& args); + void numMipmapsChanged(EventArgs& args); + void alphaChanged(EventArgs& args); + void textureCoordSetChanged(EventArgs& args); + void textureTransformChanged(EventArgs& args); + void textureScrollChanged(EventArgs& args); + void textureUScrollChanged(EventArgs& args); + void textureVScrollChanged(EventArgs& args); + void textureUScaleChanged(EventArgs& args); + void textureVScaleChanged(EventArgs& args); + void textureRotateChanged(EventArgs& args); + void textureAddressingModeChanged(EventArgs& args); + void textureBorderColourChanged(EventArgs& args); + void colourOperationExChanged(EventArgs& args); + void colourOpMultipassFallbackChanged(EventArgs& args); + void alphaOperationChanged(EventArgs& args); + void environmentMapChanged(EventArgs& args); + void scrollAnimationChanged(EventArgs& args); + void rotateAnimationChanged(EventArgs& args); + void transformAnimationChanged(EventArgs& args); + void projectiveTexturingChanged(EventArgs& args); + void textureFilteringChanged(EventArgs& args); + void textureAnisotropyChanged(EventArgs& args); + void textureMipMapBiasChanged(EventArgs& args); + void nameChanged(EventArgs& args); + void textureNameAliasChanged(EventArgs& args); protected: - virtual void propertyChanged(wxPropertyGridEvent& event); + virtual void propertyChanged(wxPropertyGridEvent& event); - TextureUnitController* mController; + TextureUnitController* mController; - wxPGId mTextureNameId; + wxPGId mTextureNameId; wxPGId mCubicTextureNameId; wxPGId mAnimatedTextureNameId; wxPGId mTextureDimensionsId; @@ -120,7 +120,7 @@ class TextureUnitPropertyGridPage : public wxPropertyGridPage wxPGId mTextureNameAliasId; - DECLARE_EVENT_TABLE(); + DECLARE_EVENT_TABLE(); }; #endif // _TEXTUREUNITPROPERTYGRIDPAGE_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/Workspace.h b/Tools/MaterialEditor/MaterialEditor/include/Workspace.h index ac584126508..fd0cdb19091 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/Workspace.h +++ b/Tools/MaterialEditor/MaterialEditor/include/Workspace.h @@ -45,61 +45,61 @@ using Ogre::String; class Workspace : public Ogre::Singleton, public EventContainer { public: - enum WorkspaceEvent - { - ProjectAdded, - ProjectRemoved - }; - - Workspace(); - virtual ~Workspace(); - - void addProject(Project* project); - void removeProject(Project* project); - void removeProject(const String& name); - - Project* getProject(const Ogre::String& name); - const ProjectList* getProjects() const; - - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static Workspace& getSingleton(void); - - /** Override standard Singleton retrieval. - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static Workspace* getSingletonPtr(void); + enum WorkspaceEvent + { + ProjectAdded, + ProjectRemoved + }; + + Workspace(); + virtual ~Workspace(); + + void addProject(Project* project); + void removeProject(Project* project); + void removeProject(const String& name); + + Project* getProject(const Ogre::String& name); + const ProjectList* getProjects() const; + + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static Workspace& getSingleton(void); + + /** Override standard Singleton retrieval. + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static Workspace* getSingletonPtr(void); protected: - void registerEvents(); + void registerEvents(); - ProjectList mProjects; + ProjectList mProjects; }; #endif // WORKSPACE_H \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/WorkspaceEventArgs.h b/Tools/MaterialEditor/MaterialEditor/include/WorkspaceEventArgs.h index 95cb3bc470b..6c3fdede129 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/WorkspaceEventArgs.h +++ b/Tools/MaterialEditor/MaterialEditor/include/WorkspaceEventArgs.h @@ -36,17 +36,17 @@ class Workspace; class WorkspaceEventArgs : public EventArgs { public: - WorkspaceEventArgs(); - WorkspaceEventArgs(Workspace* workspace, Project* project); + WorkspaceEventArgs(); + WorkspaceEventArgs(Workspace* workspace, Project* project); - virtual ~WorkspaceEventArgs(); + virtual ~WorkspaceEventArgs(); - Workspace* getWorkspace(); - Project* getProject(); + Workspace* getWorkspace(); + Project* getProject(); protected: - Workspace* mWorkspace; - Project* mProject; + Workspace* mWorkspace; + Project* mProject; }; #endif // _WORKSPACEEVENTARGS_H_ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/include/WorkspacePanel.h b/Tools/MaterialEditor/MaterialEditor/include/WorkspacePanel.h index 04dc5445940..370d52c3ba6 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/WorkspacePanel.h +++ b/Tools/MaterialEditor/MaterialEditor/include/WorkspacePanel.h @@ -53,91 +53,91 @@ typedef std::map PassIdMap; class WorkspacePanel : public wxPanel { public: - WorkspacePanel(wxWindow* parent, - wxWindowID id = wxID_ANY, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxTAB_TRAVERSAL | wxNO_BORDER, - const wxString& name = wxT("Workspace Panel")); - - virtual ~WorkspacePanel(); - - void OnRightClick(wxTreeEvent& event); - void OnActivate(wxTreeEvent& event); - void OnSelectionChanged(wxTreeEvent& event); - void OnNewProject(wxCommandEvent& event); - void OnNewMaterialScript(wxCommandEvent& event); - void OnNewMaterial(wxCommandEvent& event); - void OnNewTechnique(wxCommandEvent& event); - void OnNewPass(wxCommandEvent& event); - void OnAddMaterial(wxCommandEvent& event); - void OnEdit(wxCommandEvent& event); - void OnUpdateProjectMenuItem(wxUpdateUIEvent& event); - void OnUpdateMaterialMenuItem(wxUpdateUIEvent& event); - void OnUpdateTechniqueMenuItem(wxUpdateUIEvent& event); - void OnUpdatePassMenuItem(wxUpdateUIEvent& event); - - // Workspace Event Handlers - void projectAdded(EventArgs& args); - void projectRemoved(EventArgs& args); - - // Project Event Handlers - void projectNameChanged(EventArgs& args); - void projectMaterialAdded(EventArgs& args); - void projectMaterialRemoved(EventArgs& args); - - // Material Event Handlers - void materialNameChanged(EventArgs& args); - void materialTechniqueAdded(EventArgs& args); - void materialTechniqueRemoved(EventArgs& args); - - // Technique Event Handlers - void techniqueNameChanged(EventArgs& args); - void techniquePassAdded(EventArgs& args); - void techniquePassRemoved(EventArgs& args); + WorkspacePanel(wxWindow* parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTAB_TRAVERSAL | wxNO_BORDER, + const wxString& name = wxT("Workspace Panel")); + + virtual ~WorkspacePanel(); + + void OnRightClick(wxTreeEvent& event); + void OnActivate(wxTreeEvent& event); + void OnSelectionChanged(wxTreeEvent& event); + void OnNewProject(wxCommandEvent& event); + void OnNewMaterialScript(wxCommandEvent& event); + void OnNewMaterial(wxCommandEvent& event); + void OnNewTechnique(wxCommandEvent& event); + void OnNewPass(wxCommandEvent& event); + void OnAddMaterial(wxCommandEvent& event); + void OnEdit(wxCommandEvent& event); + void OnUpdateProjectMenuItem(wxUpdateUIEvent& event); + void OnUpdateMaterialMenuItem(wxUpdateUIEvent& event); + void OnUpdateTechniqueMenuItem(wxUpdateUIEvent& event); + void OnUpdatePassMenuItem(wxUpdateUIEvent& event); + + // Workspace Event Handlers + void projectAdded(EventArgs& args); + void projectRemoved(EventArgs& args); + + // Project Event Handlers + void projectNameChanged(EventArgs& args); + void projectMaterialAdded(EventArgs& args); + void projectMaterialRemoved(EventArgs& args); + + // Material Event Handlers + void materialNameChanged(EventArgs& args); + void materialTechniqueAdded(EventArgs& args); + void materialTechniqueRemoved(EventArgs& args); + + // Technique Event Handlers + void techniqueNameChanged(EventArgs& args); + void techniquePassAdded(EventArgs& args); + void techniquePassRemoved(EventArgs& args); protected: - void createPanel(); - wxImageList* getImageList(); - - void appendNewMenu(wxMenu* menu); - void showContextMenu(wxPoint point, wxTreeItemId id); - void appendProjectMenuItems(wxMenu* menu); - void appendMaterialMenuItems(wxMenu* memu); - void appendTechniqueMenuItems(wxMenu* menu); - void appendPassMenuItems(wxMenu* menu); - - Project* getProject(wxTreeItemId id); - MaterialController* getMaterial(wxTreeItemId id); - TechniqueController* getTechnique(wxTreeItemId id); - PassController* getPass(wxTreeItemId id); - - bool isWorkspace(wxTreeItemId id); - bool isProject(wxTreeItemId id); - bool isMaterial(wxTreeItemId id); - bool isTechnique(wxTreeItemId id); - bool isPass(wxTreeItemId id); - - // Event Handling Utils - void subscribe(Project* project); - void subscribe(MaterialController* material); - void subscribe(TechniqueController* technique); - - wxImageList* mImageList; - wxFlexGridSizer* mSizer; - wxPanel* mToolBarPanel; - wxTreeCtrl* mTreeCtrl; - - wxTreeItemId mRootId; - - wxMenu* mNewMenu; - - ProjectIdMap mProjectIdMap; - MaterialIdMap mMaterialIdMap; - TechniqueIdMap mTechniqueIdMap; - PassIdMap mPassIdMap; - - DECLARE_EVENT_TABLE() + void createPanel(); + wxImageList* getImageList(); + + void appendNewMenu(wxMenu* menu); + void showContextMenu(wxPoint point, wxTreeItemId id); + void appendProjectMenuItems(wxMenu* menu); + void appendMaterialMenuItems(wxMenu* memu); + void appendTechniqueMenuItems(wxMenu* menu); + void appendPassMenuItems(wxMenu* menu); + + Project* getProject(wxTreeItemId id); + MaterialController* getMaterial(wxTreeItemId id); + TechniqueController* getTechnique(wxTreeItemId id); + PassController* getPass(wxTreeItemId id); + + bool isWorkspace(wxTreeItemId id); + bool isProject(wxTreeItemId id); + bool isMaterial(wxTreeItemId id); + bool isTechnique(wxTreeItemId id); + bool isPass(wxTreeItemId id); + + // Event Handling Utils + void subscribe(Project* project); + void subscribe(MaterialController* material); + void subscribe(TechniqueController* technique); + + wxImageList* mImageList; + wxFlexGridSizer* mSizer; + wxPanel* mToolBarPanel; + wxTreeCtrl* mTreeCtrl; + + wxTreeItemId mRootId; + + wxMenu* mNewMenu; + + ProjectIdMap mProjectIdMap; + MaterialIdMap mMaterialIdMap; + TechniqueIdMap mTechniqueIdMap; + PassIdMap mPassIdMap; + + DECLARE_EVENT_TABLE() }; #endif // _WORKSPACEPANEL_H_ diff --git a/Tools/MaterialEditor/MaterialEditor/include/wxOgre.h b/Tools/MaterialEditor/MaterialEditor/include/wxOgre.h index 44ca05d1a74..eba507494ad 100644 --- a/Tools/MaterialEditor/MaterialEditor/include/wxOgre.h +++ b/Tools/MaterialEditor/MaterialEditor/include/wxOgre.h @@ -4,116 +4,116 @@ #include "Ogre.h" #include "wx/wx.h" - /** - @brief WX widget for and Ogre rendering window - - This WX widget is a self-contained SINGLETON Ogre rendering window; - meaning it contains all Ogre objects necessary to create a rendering - window and currently supports only one rendering window at a time! - This is due to the limitation of the self contained class. - - @usage Simply create a new wxOgre object and pass a wxFrame as its - parent window. Then work with it just like ay other wxControl object. - It can even be passed to an wxAUI pane. - */ - class wxOgre : - public wxControl, - public Ogre::Singleton - { - DECLARE_CLASS(wxOgre) - public: - /** A new wxOgre must receive a parent frame to which to attach - itself to */ - wxOgre (wxFrame* parent, Ogre::RenderSystem* renderSystem = 0); - ~wxOgre(); - - /** Renders a single Ogre frame */ - void update(); - - /** Returns the currently used camera */ - inline Ogre::Camera* getCamera() const {return mCamera;} - /** Sets a new camera for rendering */ - inline void setCamera(Ogre::Camera* camera){mCamera = camera;} - - inline Ogre::SceneManager* getSceneManager() const {return mSceneMgr;} - void setZoomScale(Ogre::Real zoomScale) {mZoomScale = zoomScale;} - inline Ogre::Light* getLight() const {return mLight;} - - void resetCamera(); - - protected: - DECLARE_EVENT_TABLE() - - private: - /** Creates an ogre rendering window and all other default objects - such as the Ogre Root, default camera, default scene manager etc */ - void createOgreRenderWindow(Ogre::RenderSystem* renderSystem); - /** Toggles the rendering timer on/off */ - void toggleTimerRendering(); - - /** WX Callbacks */ - void OnSize(wxSizeEvent& event); - void OnPaint(wxPaintEvent& event); - void OnEraseBackground(wxEraseEvent& event); - void OnRenderTimer(wxTimerEvent& event); - void OnMouseDown(wxMouseEvent& event); - void OnMouseMotion(wxMouseEvent& event); - void OnMouseWheel(wxMouseEvent& event); - - /** Rendering timer */ - wxTimer mTimer; - wxPoint mPrevPos; - - /* Ogre members */ - Ogre::Root* mRoot; - Ogre::Viewport* mViewPort; - Ogre::Camera* mCamera; - Ogre::SceneManager* mSceneMgr; - Ogre::RenderWindow* mRenderWindow; - Ogre::SceneNode *mCameraYawNode, *mCameraPitchNode; - Ogre::SceneNode *mLightYawNode, *mLightPitchNode; - Ogre::Real mZoomScale; - Ogre::Light* mLight; - - public: - // ***************************************************** - - // ----------------------------------------------------- - /** - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static wxOgre& getSingleton(); - /** - @remarks - Why do we do this? Well, it's because the Singleton - implementation is in a .h file, which means it gets compiled - into anybody who includes it. This is needed for the - Singleton template to work, but we actually only want it - compiled into the implementation of the class based on the - Singleton, not all of them. If we don't change this, we get - link errors when trying to use the Singleton-based class from - an outside dll. - @par - This method just delegates to the template version anyway, - but the implementation stays in this single compilation unit, - preventing link errors. - */ - static wxOgre* getSingletonPtr(); - - - }; + /** + @brief WX widget for and Ogre rendering window + + This WX widget is a self-contained SINGLETON Ogre rendering window; + meaning it contains all Ogre objects necessary to create a rendering + window and currently supports only one rendering window at a time! + This is due to the limitation of the self contained class. + + @usage Simply create a new wxOgre object and pass a wxFrame as its + parent window. Then work with it just like ay other wxControl object. + It can even be passed to an wxAUI pane. + */ + class wxOgre : + public wxControl, + public Ogre::Singleton + { + DECLARE_CLASS(wxOgre) + public: + /** A new wxOgre must receive a parent frame to which to attach + itself to */ + wxOgre (wxFrame* parent, Ogre::RenderSystem* renderSystem = 0); + ~wxOgre(); + + /** Renders a single Ogre frame */ + void update(); + + /** Returns the currently used camera */ + inline Ogre::Camera* getCamera() const {return mCamera;} + /** Sets a new camera for rendering */ + inline void setCamera(Ogre::Camera* camera){mCamera = camera;} + + inline Ogre::SceneManager* getSceneManager() const {return mSceneMgr;} + void setZoomScale(Ogre::Real zoomScale) {mZoomScale = zoomScale;} + inline Ogre::Light* getLight() const {return mLight;} + + void resetCamera(); + + protected: + DECLARE_EVENT_TABLE() + + private: + /** Creates an ogre rendering window and all other default objects + such as the Ogre Root, default camera, default scene manager etc */ + void createOgreRenderWindow(Ogre::RenderSystem* renderSystem); + /** Toggles the rendering timer on/off */ + void toggleTimerRendering(); + + /** WX Callbacks */ + void OnSize(wxSizeEvent& event); + void OnPaint(wxPaintEvent& event); + void OnEraseBackground(wxEraseEvent& event); + void OnRenderTimer(wxTimerEvent& event); + void OnMouseDown(wxMouseEvent& event); + void OnMouseMotion(wxMouseEvent& event); + void OnMouseWheel(wxMouseEvent& event); + + /** Rendering timer */ + wxTimer mTimer; + wxPoint mPrevPos; + + /* Ogre members */ + Ogre::Root* mRoot; + Ogre::Viewport* mViewPort; + Ogre::Camera* mCamera; + Ogre::SceneManager* mSceneMgr; + Ogre::RenderWindow* mRenderWindow; + Ogre::SceneNode *mCameraYawNode, *mCameraPitchNode; + Ogre::SceneNode *mLightYawNode, *mLightPitchNode; + Ogre::Real mZoomScale; + Ogre::Light* mLight; + + public: + // ***************************************************** + + // ----------------------------------------------------- + /** + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static wxOgre& getSingleton(); + /** + @remarks + Why do we do this? Well, it's because the Singleton + implementation is in a .h file, which means it gets compiled + into anybody who includes it. This is needed for the + Singleton template to work, but we actually only want it + compiled into the implementation of the class based on the + Singleton, not all of them. If we don't change this, we get + link errors when trying to use the Singleton-based class from + an outside dll. + @par + This method just delegates to the template version anyway, + but the implementation stays in this single compilation unit, + preventing link errors. + */ + static wxOgre* getSingletonPtr(); + + + }; #endif // __WXOGRE_H__ \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/CallTipManager.cpp b/Tools/MaterialEditor/MaterialEditor/src/CallTipManager.cpp index 6ee0364cd57..418aad29c28 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/CallTipManager.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/CallTipManager.cpp @@ -45,88 +45,88 @@ CallTipManager::~CallTipManager() void CallTipManager::load(wxString& path) { - // TODO: Clear tips list - - std::ifstream fp; - fp.open(path, std::ios::in | std::ios::binary); - if(fp) - { - DataStreamPtr stream(new FileStreamDataStream(path.c_str(), &fp, false)); - - int index = -1; - String line; - String key; - while(!stream->eof()) - { - line = stream->getLine(); - - // Ignore blank lines and comments (comment lines start with '#') - if(line.length() > 0 && line.at(0) != '#') - { - if(line.at(0) == '[') - { - int endBrace = (int)line.find(']'); - if(endBrace != -1) - { - key = line.substr(1, endBrace - 1); - } - } - else - { - if(mCallTips.find(key) != mCallTips.end()) - mCallTips[key] = mCallTips[key] + "\n" + line; - else - mCallTips[key] = line; - } - } - } - } + // TODO: Clear tips list + + std::ifstream fp; + fp.open(path, std::ios::in | std::ios::binary); + if(fp) + { + DataStreamPtr stream(new FileStreamDataStream(path.c_str(), &fp, false)); + + int index = -1; + String line; + String key; + while(!stream->eof()) + { + line = stream->getLine(); + + // Ignore blank lines and comments (comment lines start with '#') + if(line.length() > 0 && line.at(0) != '#') + { + if(line.at(0) == '[') + { + int endBrace = (int)line.find(']'); + if(endBrace != -1) + { + key = line.substr(1, endBrace - 1); + } + } + else + { + if(mCallTips.find(key) != mCallTips.end()) + mCallTips[key] = mCallTips[key] + "\n" + line; + else + mCallTips[key] = line; + } + } + } + } } void CallTipManager::addTip(wxString& key, wxString& tip) { - mCallTips[key] = tip; + mCallTips[key] = tip; } void CallTipManager::removeTip(wxString& key) { - CallTipMap::iterator it = mCallTips.find(key); - if(it != mCallTips.end()) mCallTips.erase(it); + CallTipMap::iterator it = mCallTips.find(key); + if(it != mCallTips.end()) mCallTips.erase(it); } void CallTipManager::addTrigger(wxChar& trigger) { - mTriggers.push_back(trigger); + mTriggers.push_back(trigger); } void CallTipManager::removeTrigger(wxChar& trigger) { - TriggerList::iterator it; - for(it = mTriggers.begin(); it != mTriggers.end(); ++it) - { - if((*it) == trigger) - { - mTriggers.erase(it); - return; - } - } + TriggerList::iterator it; + for(it = mTriggers.begin(); it != mTriggers.end(); ++it) + { + if((*it) == trigger) + { + mTriggers.erase(it); + return; + } + } } bool CallTipManager::isTrigger(wxChar& ch) { - TriggerList::iterator it; - for(it = mTriggers.begin(); it != mTriggers.end(); ++it) - { - if((*it) == ch) return true; - } + TriggerList::iterator it; + for(it = mTriggers.begin(); it != mTriggers.end(); ++it) + { + if((*it) == ch) return true; + } - return false; + return false; } wxString* CallTipManager::find(wxString& s) { - if(mCallTips.find(s) != mCallTips.end()) - return &mCallTips[s]; + if(mCallTips.find(s) != mCallTips.end()) + return &mCallTips[s]; - return NULL; + return NULL; } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/CgEditor.cpp b/Tools/MaterialEditor/MaterialEditor/src/CgEditor.cpp index 06d8d318cd5..540c1fcfcb0 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/CgEditor.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/CgEditor.cpp @@ -28,17 +28,17 @@ THE SOFTWARE. #include "CgEditor.h" BEGIN_EVENT_TABLE(CgEditor, ScintillaEditor) - // Scintilla - EVT_SCI_CHARADDED (-1, CgEditor::OnCharAdded) + // Scintilla + EVT_SCI_CHARADDED (-1, CgEditor::OnCharAdded) END_EVENT_TABLE() CgEditor::CgEditor(wxWindow* parent, wxWindowID id /*= -1*/, - const wxPoint& pos /*= wxDefaultPosition*/, - const wxSize& size /*= wxDefaultSize*/, - long style /*= wxVSCROLL*/ - ) : ScintillaEditor(parent, id, pos, size, style) + const wxPoint& pos /*= wxDefaultPosition*/, + const wxSize& size /*= wxDefaultSize*/, + long style /*= wxVSCROLL*/ + ) : ScintillaEditor(parent, id, pos, size, style) { - initialize(); + initialize(); } CgEditor::~CgEditor() @@ -47,59 +47,59 @@ CgEditor::~CgEditor() void CgEditor::initialize() { - StyleClearAll(); - SetLexer(wxSCI_LEX_CPP); + StyleClearAll(); + SetLexer(wxSCI_LEX_CPP); - // Load keywords - wxString path = wxT("../lexers/cg/keywords"); - loadKeywords(path); + // Load keywords + wxString path = wxT("../lexers/cg/keywords"); + loadKeywords(path); - // Load call tips - path = wxT("../lexers/cg/calltips"); - getCallTipManager().load(path); - wxChar trigger('('); - getCallTipManager().addTrigger(trigger); - - // Set styles - StyleSetForeground(wxSCI_C_COMMENT, wxColour(0, 128, 0)); - StyleSetFontAttr(wxSCI_C_COMMENT, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_C_COMMENTLINE, wxColour(0, 128, 0)); - StyleSetFontAttr(wxSCI_C_COMMENTLINE, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_C_NUMBER, wxColour(0, 0, 128)); - StyleSetFontAttr(wxSCI_C_NUMBER, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_C_STRING, wxColour(200, 200, 200)); - StyleSetFontAttr(wxSCI_C_STRING, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_C_WORD, wxColour(0, 0, 255)); - StyleSetFontAttr(wxSCI_C_WORD, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_C_WORD2, wxColour(136, 0, 0)); - StyleSetFontAttr(wxSCI_C_WORD2, 10, "Courier New", false, false, false); + // Load call tips + path = wxT("../lexers/cg/calltips"); + getCallTipManager().load(path); + wxChar trigger('('); + getCallTipManager().addTrigger(trigger); + + // Set styles + StyleSetForeground(wxSCI_C_COMMENT, wxColour(0, 128, 0)); + StyleSetFontAttr(wxSCI_C_COMMENT, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_C_COMMENTLINE, wxColour(0, 128, 0)); + StyleSetFontAttr(wxSCI_C_COMMENTLINE, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_C_NUMBER, wxColour(0, 0, 128)); + StyleSetFontAttr(wxSCI_C_NUMBER, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_C_STRING, wxColour(200, 200, 200)); + StyleSetFontAttr(wxSCI_C_STRING, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_C_WORD, wxColour(0, 0, 255)); + StyleSetFontAttr(wxSCI_C_WORD, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_C_WORD2, wxColour(136, 0, 0)); + StyleSetFontAttr(wxSCI_C_WORD2, 10, "Courier New", false, false, false); } void CgEditor::OnCharAdded(wxScintillaEvent &event) { - char ch = event.GetKey(); - if(getCallTipManager().isTrigger(ch)) - { - int lineNum = GetCurrentLine(); - if(lineNum != -1) - { - wxString line = GetLine(lineNum); - int pos = GetCurrentPos() - 1; + char ch = event.GetKey(); + if(getCallTipManager().isTrigger(ch)) + { + int lineNum = GetCurrentLine(); + if(lineNum != -1) + { + wxString line = GetLine(lineNum); + int pos = GetCurrentPos() - 1; - wxString word(""); - wxChar ch; - while(pos) - { - ch = GetCharAt(--pos); - if(ch != ' ' || ch != '\n') word.Prepend(ch); - else break; - } + wxString word(""); + wxChar ch; + while(pos) + { + ch = GetCharAt(--pos); + if(ch != ' ' || ch != '\n') word.Prepend(ch); + else break; + } - wxString* tips = getCallTipManager().find(word); - if(tips != NULL) - { - CallTipShow(pos, *tips); - } - } - } + wxString* tips = getCallTipManager().find(word); + if(tips != NULL) + { + CallTipShow(pos, *tips); + } + } + } } diff --git a/Tools/MaterialEditor/MaterialEditor/src/CodeEditor.cpp b/Tools/MaterialEditor/MaterialEditor/src/CodeEditor.cpp index 339fe0a749e..a4f8cf18c70 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/CodeEditor.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/CodeEditor.cpp @@ -44,42 +44,42 @@ THE SOFTWARE BEGIN_EVENT_TABLE(CodeEditor, wxScintilla) EVT_SIZE (CodeEditor::OnSize) // Edit -EVT_MENU (wxID_CLEAR, CodeEditor::OnEditClear) -EVT_MENU (wxID_CUT, CodeEditor::OnEditCut) -EVT_MENU (wxID_COPY, CodeEditor::OnEditCopy) -EVT_MENU (wxID_PASTE, CodeEditor::OnEditPaste) -EVT_MENU (ID_INDENTINC, CodeEditor::OnEditIndentInc) -EVT_MENU (ID_INDENTRED, CodeEditor::OnEditIndentRed) -EVT_MENU (wxID_SELECTALL, CodeEditor::OnEditSelectAll) -EVT_MENU (ID_SELECTLINE, CodeEditor::OnEditSelectLine) -EVT_MENU (wxID_REDO, CodeEditor::OnEditRedo) -EVT_MENU (wxID_UNDO, CodeEditor::OnEditUndo) +EVT_MENU (wxID_CLEAR, CodeEditor::OnEditClear) +EVT_MENU (wxID_CUT, CodeEditor::OnEditCut) +EVT_MENU (wxID_COPY, CodeEditor::OnEditCopy) +EVT_MENU (wxID_PASTE, CodeEditor::OnEditPaste) +EVT_MENU (ID_INDENTINC, CodeEditor::OnEditIndentInc) +EVT_MENU (ID_INDENTRED, CodeEditor::OnEditIndentRed) +EVT_MENU (wxID_SELECTALL, CodeEditor::OnEditSelectAll) +EVT_MENU (ID_SELECTLINE, CodeEditor::OnEditSelectLine) +EVT_MENU (wxID_REDO, CodeEditor::OnEditRedo) +EVT_MENU (wxID_UNDO, CodeEditor::OnEditUndo) // Find -EVT_MENU (wxID_FIND, CodeEditor::OnFind) -EVT_MENU (ID_FINDNEXT, CodeEditor::OnFindNext) -EVT_MENU (ID_REPLACE, CodeEditor::OnReplace) -EVT_MENU (ID_REPLACENEXT, CodeEditor::OnReplaceNext) -EVT_MENU (ID_BRACEMATCH, CodeEditor::OnBraceMatch) -EVT_MENU (ID_GOTO, CodeEditor::OnGoto) +EVT_MENU (wxID_FIND, CodeEditor::OnFind) +EVT_MENU (ID_FINDNEXT, CodeEditor::OnFindNext) +EVT_MENU (ID_REPLACE, CodeEditor::OnReplace) +EVT_MENU (ID_REPLACENEXT, CodeEditor::OnReplaceNext) +EVT_MENU (ID_BRACEMATCH, CodeEditor::OnBraceMatch) +EVT_MENU (ID_GOTO, CodeEditor::OnGoto) // View EVT_MENU_RANGE (ID_HILIGHTFIRST, ID_HILIGHTLAST, CodeEditor::OnHilightLang) -EVT_MENU (ID_DISPLAYEOL, CodeEditor::OnDisplayEOL) -EVT_MENU (ID_INDENTGUIDE, CodeEditor::OnIndentGuide) -EVT_MENU (ID_LINENUMBER, CodeEditor::OnLineNumber) -EVT_MENU (ID_LONGLINEON, CodeEditor::OnLongLineOn) -EVT_MENU (ID_WHITESPACE, CodeEditor::OnWhiteSpace) -EVT_MENU (ID_FOLDTOGGLE, CodeEditor::OnFoldToggle) -EVT_MENU (ID_OVERTYPE, CodeEditor::OnSetOverType) -EVT_MENU (ID_READONLY, CodeEditor::OnSetReadOnly) -EVT_MENU (ID_WRAPMODEON, CodeEditor::OnWrapModeOn) -EVT_MENU (ID_CHARSETANSI, CodeEditor::OnUseCharset) -EVT_MENU (ID_CHARSETMAC, CodeEditor::OnUseCharset) +EVT_MENU (ID_DISPLAYEOL, CodeEditor::OnDisplayEOL) +EVT_MENU (ID_INDENTGUIDE, CodeEditor::OnIndentGuide) +EVT_MENU (ID_LINENUMBER, CodeEditor::OnLineNumber) +EVT_MENU (ID_LONGLINEON, CodeEditor::OnLongLineOn) +EVT_MENU (ID_WHITESPACE, CodeEditor::OnWhiteSpace) +EVT_MENU (ID_FOLDTOGGLE, CodeEditor::OnFoldToggle) +EVT_MENU (ID_OVERTYPE, CodeEditor::OnSetOverType) +EVT_MENU (ID_READONLY, CodeEditor::OnSetReadOnly) +EVT_MENU (ID_WRAPMODEON, CodeEditor::OnWrapModeOn) +EVT_MENU (ID_CHARSETANSI, CodeEditor::OnUseCharset) +EVT_MENU (ID_CHARSETMAC, CodeEditor::OnUseCharset) // Extra -EVT_MENU (ID_CHANGELOWER, CodeEditor::OnChangeCase) -EVT_MENU (ID_CHANGEUPPER, CodeEditor::OnChangeCase) -EVT_MENU (ID_CONVERTCR, CodeEditor::OnConvertEOL) -EVT_MENU (ID_CONVERTCRLF, CodeEditor::OnConvertEOL) -EVT_MENU (ID_CONVERTLF, CodeEditor::OnConvertEOL) +EVT_MENU (ID_CHANGELOWER, CodeEditor::OnChangeCase) +EVT_MENU (ID_CHANGEUPPER, CodeEditor::OnChangeCase) +EVT_MENU (ID_CONVERTCR, CodeEditor::OnConvertEOL) +EVT_MENU (ID_CONVERTCRLF, CodeEditor::OnConvertEOL) +EVT_MENU (ID_CONVERTLF, CodeEditor::OnConvertEOL) // scintilla EVT_SCI_MARGINCLICK (-1, CodeEditor::OnMarginClick) EVT_SCI_CHARADDED (-1, CodeEditor::OnCharAdded) @@ -88,126 +88,126 @@ EVT_SCI_UPDATEUI(-1, CodeEditor::OnUpdateUI) END_EVENT_TABLE() CodeEditor::CodeEditor(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) - : wxScintilla (parent, id, pos, size, style) -{ - mFileName = _T(""); - //m_language = NULL; - - mLineNumID = 0; - mLineNumMargin = TextWidth(wxSCI_STYLE_LINENUMBER, _T("99999")); - mFoldingID = 1; - mFoldingMargin = 16; - mDividerID = 1; - - SetProperty(wxT("fold"), wxT("1")); - SetFoldFlags(16); - SetMarginType(mFoldingID, wxSCI_MARGIN_SYMBOL); - SetMarginMask(mFoldingID, wxSCI_MASK_FOLDERS); - SetMarginSensitive(mFoldingID, true); - SetMarginWidth(mFoldingID, mFoldingMargin); - - MarkerDefine(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_BOXMINUS); - MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_BOXPLUS); - MarkerSetForeground(wxSCI_MARKNUM_FOLDER, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDER, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_VLINE); - MarkerSetForeground(wxSCI_MARKNUM_FOLDERSUB, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDERSUB, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_LCORNER); - MarkerSetForeground(wxSCI_MARKNUM_FOLDERTAIL, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDERTAIL, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_BOXPLUSCONNECTED); - MarkerSetForeground(wxSCI_MARKNUM_FOLDEREND, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDEREND, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_BOXMINUSCONNECTED); - MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPENMID, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPENMID, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_TCORNER); - MarkerSetForeground(wxSCI_MARKNUM_FOLDERMIDTAIL, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDERMIDTAIL, wxColour(0x80, 0x80, 0x80)); - - // Set defaults, these should eventually be set via user prefs - SetViewEOL(false); - SetIndentationGuides(false); - SetMarginWidth(mLineNumID, mLineNumMargin); - //SetMarginWidth(mFoldingID, mFoldingMargin); - //SetMarginSensitive(mFoldingID, true); - SetEdgeMode(wxSCI_EDGE_LINE); - //SetViewWhiteSpace(wxSCI_WS_VISIBLEALWAYS); - SetOvertype(false); - SetReadOnly(false); - SetWrapMode(wxSCI_WRAP_NONE); - - wxFont font(10, wxTELETYPE, wxNORMAL, wxNORMAL); - StyleSetFont(wxSCI_STYLE_DEFAULT, font); - StyleSetForeground(wxSCI_STYLE_DEFAULT, wxColour(wxT("BLACK"))); - StyleSetBackground(wxSCI_STYLE_DEFAULT, wxColour(wxT("WHITE"))); - StyleSetForeground(wxSCI_STYLE_LINENUMBER, wxColour(wxT("DARK BLUE"))); - StyleSetBackground(wxSCI_STYLE_LINENUMBER, wxColour(wxT("WHITE"))); - StyleSetForeground(wxSCI_STYLE_INDENTGUIDE, wxColour(wxT("DARK GREY"))); - - StyleSetBold(wxSCI_STYLE_BRACELIGHT, true); - - //InitializePrefs(DEFAULT_LANGUAGE); - SetTabWidth(4); - SetUseTabs(false); - SetTabIndents(true); - SetBackSpaceUnIndents(true); - SetIndent(4); - - // Set visibility - SetVisiblePolicy(wxSCI_VISIBLE_STRICT | wxSCI_VISIBLE_SLOP, 1); - SetXCaretPolicy(wxSCI_CARET_EVEN | wxSCI_VISIBLE_STRICT | wxSCI_CARET_SLOP, 1); - SetYCaretPolicy(wxSCI_CARET_EVEN | wxSCI_VISIBLE_STRICT | wxSCI_CARET_SLOP, 1); - - SetCaretLineVisible(true); - SetCaretLineBackground(wxColour(225, 235, 224)); - - // Markers - //MarkerDefine(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_BOXPLUS); - //MarkerSetBackground(wxSCI_MARKNUM_FOLDER, wxColour(_T("BLACK"))); - //MarkerSetForeground(wxSCI_MARKNUM_FOLDER, wxColour(_T("WHITE"))); - //MarkerDefine(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_BOXMINUS); - //MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(_T("BLACK"))); - //MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(_T("WHITE"))); - //MarkerDefine(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_EMPTY); - //MarkerDefine(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_SHORTARROW); - //MarkerDefine(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_ARROWDOWN); - //MarkerDefine(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_EMPTY); - //MarkerDefine(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_EMPTY); - - // Clear wrong default keys + : wxScintilla (parent, id, pos, size, style) +{ + mFileName = _T(""); + //m_language = NULL; + + mLineNumID = 0; + mLineNumMargin = TextWidth(wxSCI_STYLE_LINENUMBER, _T("99999")); + mFoldingID = 1; + mFoldingMargin = 16; + mDividerID = 1; + + SetProperty(wxT("fold"), wxT("1")); + SetFoldFlags(16); + SetMarginType(mFoldingID, wxSCI_MARGIN_SYMBOL); + SetMarginMask(mFoldingID, wxSCI_MASK_FOLDERS); + SetMarginSensitive(mFoldingID, true); + SetMarginWidth(mFoldingID, mFoldingMargin); + + MarkerDefine(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_BOXMINUS); + MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_BOXPLUS); + MarkerSetForeground(wxSCI_MARKNUM_FOLDER, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDER, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_VLINE); + MarkerSetForeground(wxSCI_MARKNUM_FOLDERSUB, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDERSUB, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_LCORNER); + MarkerSetForeground(wxSCI_MARKNUM_FOLDERTAIL, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDERTAIL, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_BOXPLUSCONNECTED); + MarkerSetForeground(wxSCI_MARKNUM_FOLDEREND, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDEREND, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_BOXMINUSCONNECTED); + MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPENMID, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPENMID, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_TCORNER); + MarkerSetForeground(wxSCI_MARKNUM_FOLDERMIDTAIL, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDERMIDTAIL, wxColour(0x80, 0x80, 0x80)); + + // Set defaults, these should eventually be set via user prefs + SetViewEOL(false); + SetIndentationGuides(false); + SetMarginWidth(mLineNumID, mLineNumMargin); + //SetMarginWidth(mFoldingID, mFoldingMargin); + //SetMarginSensitive(mFoldingID, true); + SetEdgeMode(wxSCI_EDGE_LINE); + //SetViewWhiteSpace(wxSCI_WS_VISIBLEALWAYS); + SetOvertype(false); + SetReadOnly(false); + SetWrapMode(wxSCI_WRAP_NONE); + + wxFont font(10, wxTELETYPE, wxNORMAL, wxNORMAL); + StyleSetFont(wxSCI_STYLE_DEFAULT, font); + StyleSetForeground(wxSCI_STYLE_DEFAULT, wxColour(wxT("BLACK"))); + StyleSetBackground(wxSCI_STYLE_DEFAULT, wxColour(wxT("WHITE"))); + StyleSetForeground(wxSCI_STYLE_LINENUMBER, wxColour(wxT("DARK BLUE"))); + StyleSetBackground(wxSCI_STYLE_LINENUMBER, wxColour(wxT("WHITE"))); + StyleSetForeground(wxSCI_STYLE_INDENTGUIDE, wxColour(wxT("DARK GREY"))); + + StyleSetBold(wxSCI_STYLE_BRACELIGHT, true); + + //InitializePrefs(DEFAULT_LANGUAGE); + SetTabWidth(4); + SetUseTabs(false); + SetTabIndents(true); + SetBackSpaceUnIndents(true); + SetIndent(4); + + // Set visibility + SetVisiblePolicy(wxSCI_VISIBLE_STRICT | wxSCI_VISIBLE_SLOP, 1); + SetXCaretPolicy(wxSCI_CARET_EVEN | wxSCI_VISIBLE_STRICT | wxSCI_CARET_SLOP, 1); + SetYCaretPolicy(wxSCI_CARET_EVEN | wxSCI_VISIBLE_STRICT | wxSCI_CARET_SLOP, 1); + + SetCaretLineVisible(true); + SetCaretLineBackground(wxColour(225, 235, 224)); + + // Markers + //MarkerDefine(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_BOXPLUS); + //MarkerSetBackground(wxSCI_MARKNUM_FOLDER, wxColour(_T("BLACK"))); + //MarkerSetForeground(wxSCI_MARKNUM_FOLDER, wxColour(_T("WHITE"))); + //MarkerDefine(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_BOXMINUS); + //MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(_T("BLACK"))); + //MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(_T("WHITE"))); + //MarkerDefine(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_EMPTY); + //MarkerDefine(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_SHORTARROW); + //MarkerDefine(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_ARROWDOWN); + //MarkerDefine(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_EMPTY); + //MarkerDefine(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_EMPTY); + + // Clear wrong default keys #if !defined(__WXGTK__) - //CmdKeyClear(wxSCI_KEY_TAB, 0); - CmdKeyClear(wxSCI_KEY_TAB, wxSCI_SCMOD_SHIFT); + //CmdKeyClear(wxSCI_KEY_TAB, 0); + CmdKeyClear(wxSCI_KEY_TAB, wxSCI_SCMOD_SHIFT); #endif - CmdKeyClear('A', wxSCI_SCMOD_CTRL); + CmdKeyClear('A', wxSCI_SCMOD_CTRL); #if !defined(__WXGTK__) - CmdKeyClear('C', wxSCI_SCMOD_CTRL); + CmdKeyClear('C', wxSCI_SCMOD_CTRL); #endif - CmdKeyClear('D', wxSCI_SCMOD_CTRL); - CmdKeyClear('D', wxSCI_SCMOD_SHIFT | wxSCI_SCMOD_CTRL); - CmdKeyClear('F', wxSCI_SCMOD_ALT | wxSCI_SCMOD_CTRL); - CmdKeyClear('L', wxSCI_SCMOD_CTRL); - CmdKeyClear('L', wxSCI_SCMOD_SHIFT | wxSCI_SCMOD_CTRL); - CmdKeyClear('T', wxSCI_SCMOD_CTRL); - CmdKeyClear('T', wxSCI_SCMOD_SHIFT | wxSCI_SCMOD_CTRL); - CmdKeyClear('U', wxSCI_SCMOD_CTRL); - CmdKeyClear('U', wxSCI_SCMOD_SHIFT | wxSCI_SCMOD_CTRL); + CmdKeyClear('D', wxSCI_SCMOD_CTRL); + CmdKeyClear('D', wxSCI_SCMOD_SHIFT | wxSCI_SCMOD_CTRL); + CmdKeyClear('F', wxSCI_SCMOD_ALT | wxSCI_SCMOD_CTRL); + CmdKeyClear('L', wxSCI_SCMOD_CTRL); + CmdKeyClear('L', wxSCI_SCMOD_SHIFT | wxSCI_SCMOD_CTRL); + CmdKeyClear('T', wxSCI_SCMOD_CTRL); + CmdKeyClear('T', wxSCI_SCMOD_SHIFT | wxSCI_SCMOD_CTRL); + CmdKeyClear('U', wxSCI_SCMOD_CTRL); + CmdKeyClear('U', wxSCI_SCMOD_SHIFT | wxSCI_SCMOD_CTRL); #if !defined(__WXGTK__) - CmdKeyClear('V', wxSCI_SCMOD_CTRL); - CmdKeyClear('X', wxSCI_SCMOD_CTRL); + CmdKeyClear('V', wxSCI_SCMOD_CTRL); + CmdKeyClear('X', wxSCI_SCMOD_CTRL); #endif - CmdKeyClear('Y', wxSCI_SCMOD_CTRL); + CmdKeyClear('Y', wxSCI_SCMOD_CTRL); #if !defined(__WXGTK__) - CmdKeyClear('Z', wxSCI_SCMOD_CTRL); + CmdKeyClear('Z', wxSCI_SCMOD_CTRL); #endif - UsePopUp(0); - SetLayoutCache(wxSCI_CACHE_PAGE); - SetBufferedDraw(1); + UsePopUp(0); + SetLayoutCache(wxSCI_CACHE_PAGE); + SetBufferedDraw(1); } CodeEditor::~CodeEditor() @@ -217,105 +217,105 @@ CodeEditor::~CodeEditor() wxChar CodeEditor::GetLastNonWhitespaceChar(int position /* = -1 */) { - if (position == -1) - position = GetCurrentPos(); - - int count = 0; // Used to count the number of blank lines - bool foundlf = false; // For the rare case of CR's without LF's - while (position) - { - wxChar c = GetCharAt(--position); - int style = GetStyleAt(position); - bool inComment = style == wxSCI_C_COMMENT || - style == wxSCI_C_COMMENTDOC || - style == wxSCI_C_COMMENTDOCKEYWORD || - style == wxSCI_C_COMMENTDOCKEYWORDERROR || - style == wxSCI_C_COMMENTLINE || - style == wxSCI_C_COMMENTLINEDOC; - if (c == wxT('\n')) - { - count++; - foundlf = true; - } - else if (c == wxT('\r') && !foundlf) - count++; - else - foundlf = false; - if (count > 1) return 0; // Don't over-indent - if (!inComment && c != wxT(' ') && c != wxT('\t') && c != wxT('\n') && c != wxT('\r')) - return c; - } - - return 0; + if (position == -1) + position = GetCurrentPos(); + + int count = 0; // Used to count the number of blank lines + bool foundlf = false; // For the rare case of CR's without LF's + while (position) + { + wxChar c = GetCharAt(--position); + int style = GetStyleAt(position); + bool inComment = style == wxSCI_C_COMMENT || + style == wxSCI_C_COMMENTDOC || + style == wxSCI_C_COMMENTDOCKEYWORD || + style == wxSCI_C_COMMENTDOCKEYWORDERROR || + style == wxSCI_C_COMMENTLINE || + style == wxSCI_C_COMMENTLINEDOC; + if (c == wxT('\n')) + { + count++; + foundlf = true; + } + else if (c == wxT('\r') && !foundlf) + count++; + else + foundlf = false; + if (count > 1) return 0; // Don't over-indent + if (!inComment && c != wxT(' ') && c != wxT('\t') && c != wxT('\n') && c != wxT('\r')) + return c; + } + + return 0; } wxString CodeEditor::GetLineIndentString(int line) { - int currLine = (line == -1) ? LineFromPosition(GetCurrentPos()) : line; + int currLine = (line == -1) ? LineFromPosition(GetCurrentPos()) : line; - wxString text = GetLine(currLine); - int length = (int)text.Length(); - wxString indent; - for (int i = 0; i < length; ++i) - { - if (text[i] == wxT(' ') || text[i] == wxT('\t')) - indent << text[i]; - else - break; - } + wxString text = GetLine(currLine); + int length = (int)text.Length(); + wxString indent; + for (int i = 0; i < length; ++i) + { + if (text[i] == wxT(' ') || text[i] == wxT('\t')) + indent << text[i]; + else + break; + } - return indent; + return indent; } int CodeEditor::FindBlockStart(int position, wxChar blockStart, wxChar blockEnd, bool skipNested /* = true */) { - int level = 0; - wxChar ch = GetCharAt(position); - while (ch) - { - if (ch == blockEnd) - ++level; + int level = 0; + wxChar ch = GetCharAt(position); + while (ch) + { + if (ch == blockEnd) + ++level; - else if (ch == blockStart) - { - if (level == 0) return position; - --level; - } + else if (ch == blockStart) + { + if (level == 0) return position; + --level; + } - --position; + --position; - ch = GetCharAt(position); - } + ch = GetCharAt(position); + } - return -1; + return -1; } void CodeEditor::HighlightBraces() { - int currPos = GetCurrentPos(); - int newPos = BraceMatch(currPos); - if (newPos == wxSCI_INVALID_POSITION) - { - if(currPos > 0) - newPos = BraceMatch(--currPos); - } - - wxChar ch = GetCharAt(currPos); - if (ch == wxT('{') || ch == wxT('[') || ch == wxT('(') || - ch == wxT('}') || ch == wxT(']') || ch == wxT(')')) - { - if (newPos != wxSCI_INVALID_POSITION) - { - BraceHighlight(currPos, newPos); - } - else - { - BraceBadLight(currPos); - } - } - else BraceHighlight(-1, -1); - - Refresh(false); + int currPos = GetCurrentPos(); + int newPos = BraceMatch(currPos); + if (newPos == wxSCI_INVALID_POSITION) + { + if(currPos > 0) + newPos = BraceMatch(--currPos); + } + + wxChar ch = GetCharAt(currPos); + if (ch == wxT('{') || ch == wxT('[') || ch == wxT('(') || + ch == wxT('}') || ch == wxT(']') || ch == wxT(')')) + { + if (newPos != wxSCI_INVALID_POSITION) + { + BraceHighlight(currPos, newPos); + } + else + { + BraceBadLight(currPos); + } + } + else BraceHighlight(-1, -1); + + Refresh(false); } @@ -323,54 +323,54 @@ void CodeEditor::HighlightBraces() // Common event handlers void CodeEditor::OnSize(wxSizeEvent& event) { - int x = GetClientSize().x + mLineNumMargin + mFoldingMargin; + int x = GetClientSize().x + mLineNumMargin + mFoldingMargin; - if (x > 0) SetScrollWidth(x); + if (x > 0) SetScrollWidth(x); - event.Skip(); + event.Skip(); } // Edit event handlers void CodeEditor::OnEditRedo(wxCommandEvent &WXUNUSED(event)) { - if (!CanRedo()) return; + if (!CanRedo()) return; - Redo(); + Redo(); } void CodeEditor::OnEditUndo(wxCommandEvent &WXUNUSED(event)) { - if (!CanUndo()) return; + if (!CanUndo()) return; - Undo(); + Undo(); } void CodeEditor::OnEditClear(wxCommandEvent &WXUNUSED(event)) { - if (GetReadOnly()) return; + if (GetReadOnly()) return; - Clear(); + Clear(); } void CodeEditor::OnEditCut(wxCommandEvent &WXUNUSED(event)) { - if (GetReadOnly() || (GetSelectionEnd()-GetSelectionStart() <= 0)) return; + if (GetReadOnly() || (GetSelectionEnd()-GetSelectionStart() <= 0)) return; - Cut(); + Cut(); } void CodeEditor::OnEditCopy(wxCommandEvent &WXUNUSED(event)) { - if (GetSelectionEnd()-GetSelectionStart() <= 0) return; + if (GetSelectionEnd()-GetSelectionStart() <= 0) return; - Copy(); + Copy(); } void CodeEditor::OnEditPaste(wxCommandEvent &WXUNUSED(event)) { - if(!CanPaste()) return; + if(!CanPaste()) return; - Paste(); + Paste(); } void CodeEditor::OnFind(wxCommandEvent &WXUNUSED(event)) @@ -391,17 +391,17 @@ void CodeEditor::OnReplaceNext(wxCommandEvent &WXUNUSED(event)) void CodeEditor::OnBraceMatch(wxCommandEvent &WXUNUSED(event)) { - int min = GetCurrentPos(); - int max = BraceMatch(min); - if (max > (min+1)) - { - BraceHighlight(min + 1, max); - SetSelection(min + 1, max); - } - else - { - BraceBadLight(min); - } + int min = GetCurrentPos(); + int max = BraceMatch(min); + if (max > (min+1)) + { + BraceHighlight(min + 1, max); + SetSelection(min + 1, max); + } + else + { + BraceBadLight(min); + } } void CodeEditor::OnGoto(wxCommandEvent &WXUNUSED(event)) @@ -410,247 +410,247 @@ void CodeEditor::OnGoto(wxCommandEvent &WXUNUSED(event)) void CodeEditor::OnEditIndentInc(wxCommandEvent &WXUNUSED(event)) { - CmdKeyExecute(wxSCI_CMD_TAB); + CmdKeyExecute(wxSCI_CMD_TAB); } void CodeEditor::OnEditIndentRed(wxCommandEvent &WXUNUSED(event)) { - CmdKeyExecute(wxSCI_CMD_DELETEBACK); + CmdKeyExecute(wxSCI_CMD_DELETEBACK); } void CodeEditor::OnEditSelectAll(wxCommandEvent &WXUNUSED(event)) { - SetSelection(0, GetLength()); + SetSelection(0, GetLength()); } void CodeEditor::OnEditSelectLine(wxCommandEvent &WXUNUSED(event)) { - int lineStart = PositionFromLine(GetCurrentLine()); - int lineEnd = PositionFromLine(GetCurrentLine() + 1); - SetSelection(lineStart, lineEnd); + int lineStart = PositionFromLine(GetCurrentLine()); + int lineEnd = PositionFromLine(GetCurrentLine() + 1); + SetSelection(lineStart, lineEnd); } void CodeEditor::OnHilightLang(wxCommandEvent &event) { - //InitializePrefs(g_LanguagePrefs [event.GetId() - myID_HILIGHTFIRST].name); + //InitializePrefs(g_LanguagePrefs [event.GetId() - myID_HILIGHTFIRST].name); } void CodeEditor::OnDisplayEOL(wxCommandEvent &WXUNUSED(event)) { - SetViewEOL (!GetViewEOL()); + SetViewEOL (!GetViewEOL()); } void CodeEditor::OnIndentGuide(wxCommandEvent &WXUNUSED(event)) { - SetIndentationGuides(!GetIndentationGuides()); + SetIndentationGuides(!GetIndentationGuides()); } void CodeEditor::OnLineNumber(wxCommandEvent &WXUNUSED(event)) { - SetMarginWidth(mLineNumID, GetMarginWidth(mLineNumID) == 0 ? mLineNumMargin : 0); + SetMarginWidth(mLineNumID, GetMarginWidth(mLineNumID) == 0 ? mLineNumMargin : 0); } void CodeEditor::OnLongLineOn(wxCommandEvent &WXUNUSED(event)) { - SetEdgeMode(GetEdgeMode() == 0? wxSCI_EDGE_LINE: wxSCI_EDGE_NONE); + SetEdgeMode(GetEdgeMode() == 0? wxSCI_EDGE_LINE: wxSCI_EDGE_NONE); } void CodeEditor::OnWhiteSpace(wxCommandEvent &WXUNUSED(event)) { - SetViewWhiteSpace (GetViewWhiteSpace() == 0 ? wxSCI_WS_VISIBLEALWAYS : wxSCI_WS_INVISIBLE); + SetViewWhiteSpace (GetViewWhiteSpace() == 0 ? wxSCI_WS_VISIBLEALWAYS : wxSCI_WS_INVISIBLE); } void CodeEditor::OnFoldToggle(wxCommandEvent &WXUNUSED(event)) { - ToggleFold(GetFoldParent(GetCurrentLine())); + ToggleFold(GetFoldParent(GetCurrentLine())); } void CodeEditor::OnSetOverType(wxCommandEvent &WXUNUSED(event)) { - SetOvertype(!GetOvertype()); + SetOvertype(!GetOvertype()); } void CodeEditor::OnSetReadOnly(wxCommandEvent &WXUNUSED(event)) { - SetReadOnly(!GetReadOnly()); + SetReadOnly(!GetReadOnly()); } void CodeEditor::OnWrapModeOn(wxCommandEvent &WXUNUSED(event)) { - SetWrapMode(GetWrapMode() == 0 ? wxSCI_WRAP_WORD : wxSCI_WRAP_NONE); + SetWrapMode(GetWrapMode() == 0 ? wxSCI_WRAP_WORD : wxSCI_WRAP_NONE); } void CodeEditor::OnUseCharset(wxCommandEvent &event) { - /* - int Nr; - int charset = GetCodePage(); + /* + int Nr; + int charset = GetCodePage(); - switch (event.GetId()) - { - case ID_CHARSETANSI: { charset = wxSCI_CHARSET_ANSI; break; } - case ID_CHARSETMAC: { charset = wxSCI_CHARSET_ANSI; break; } - } + switch (event.GetId()) + { + case ID_CHARSETANSI: { charset = wxSCI_CHARSET_ANSI; break; } + case ID_CHARSETMAC: { charset = wxSCI_CHARSET_ANSI; break; } + } - for (Nr = 0; Nr < wxSCI_STYLE_LASTPREDEFINED; Nr++) - { - StyleSetCharacterSet(Nr, charset); - } + for (Nr = 0; Nr < wxSCI_STYLE_LASTPREDEFINED; Nr++) + { + StyleSetCharacterSet(Nr, charset); + } - SetCodePage(charset); - */ + SetCodePage(charset); + */ } void CodeEditor::OnChangeCase(wxCommandEvent &event) { - int id = event.GetId(); - if(id == ID_CHANGELOWER) CmdKeyExecute(wxSCI_CMD_LOWERCASE); - else if(id == ID_CHANGEUPPER) CmdKeyExecute(wxSCI_CMD_UPPERCASE); + int id = event.GetId(); + if(id == ID_CHANGELOWER) CmdKeyExecute(wxSCI_CMD_LOWERCASE); + else if(id == ID_CHANGEUPPER) CmdKeyExecute(wxSCI_CMD_UPPERCASE); } void CodeEditor::OnConvertEOL(wxCommandEvent &event) { - int eolMode = GetEOLMode(); + int eolMode = GetEOLMode(); - const int id = event.GetId(); - if(id == ID_CONVERTCR) eolMode = wxSCI_EOL_CR; - else if(id == ID_CONVERTCRLF) eolMode = wxSCI_EOL_CRLF; - else if(id == ID_CONVERTLF) eolMode = wxSCI_EOL_LF; + const int id = event.GetId(); + if(id == ID_CONVERTCR) eolMode = wxSCI_EOL_CR; + else if(id == ID_CONVERTCRLF) eolMode = wxSCI_EOL_CRLF; + else if(id == ID_CONVERTLF) eolMode = wxSCI_EOL_LF; - ConvertEOLs(eolMode); - SetEOLMode(eolMode); + ConvertEOLs(eolMode); + SetEOLMode(eolMode); } void CodeEditor::OnMarginClick(wxScintillaEvent &event) { - if (event.GetMargin() == 1) - { - int lineClick = LineFromPosition(event.GetPosition()); - int levelClick = GetFoldLevel(lineClick); - if ((levelClick & wxSCI_FOLDLEVELHEADERFLAG) > 0) - { - ToggleFold (lineClick); - } - } + if (event.GetMargin() == 1) + { + int lineClick = LineFromPosition(event.GetPosition()); + int levelClick = GetFoldLevel(lineClick); + if ((levelClick & wxSCI_FOLDLEVELHEADERFLAG) > 0) + { + ToggleFold (lineClick); + } + } } void CodeEditor::OnCharAdded(wxScintillaEvent &event) { - char ch = event.GetKey(); - int currentLine = GetCurrentLine(); - int pos = GetCurrentPos(); - - if (ch == wxT('\n') && currentLine > 0) - { - BeginUndoAction(); - - wxString indent = GetLineIndentString(currentLine - 1); - - wxChar b = GetLastNonWhitespaceChar(); - if(b == wxT('{')) - { - if(GetUseTabs()) - indent << wxT("\t"); - else - indent << wxT(" "); - } - - InsertText(pos, indent); - GotoPos((int)(pos + indent.Length())); - ChooseCaretX(); - - EndUndoAction(); - } - else if(ch == wxT('}')) - { - BeginUndoAction(); - - wxString line = GetLine(currentLine); - line.Trim(false); - line.Trim(true); - if(line.Matches(wxT("}"))) - { - pos = GetCurrentPos() - 2; - pos = FindBlockStart(pos, wxT('{'), wxT('}')); - - if(pos != -1) - { - wxString indent = GetLineIndentString(LineFromPosition(pos)); - indent << wxT('}'); - DelLineLeft(); - DelLineRight(); - pos = GetCurrentPos(); - InsertText(pos, indent); - GotoPos((int)(pos + indent.Length())); - ChooseCaretX(); - } - } - - EndUndoAction(); - } + char ch = event.GetKey(); + int currentLine = GetCurrentLine(); + int pos = GetCurrentPos(); + + if (ch == wxT('\n') && currentLine > 0) + { + BeginUndoAction(); + + wxString indent = GetLineIndentString(currentLine - 1); + + wxChar b = GetLastNonWhitespaceChar(); + if(b == wxT('{')) + { + if(GetUseTabs()) + indent << wxT("\t"); + else + indent << wxT(" "); + } + + InsertText(pos, indent); + GotoPos((int)(pos + indent.Length())); + ChooseCaretX(); + + EndUndoAction(); + } + else if(ch == wxT('}')) + { + BeginUndoAction(); + + wxString line = GetLine(currentLine); + line.Trim(false); + line.Trim(true); + if(line.Matches(wxT("}"))) + { + pos = GetCurrentPos() - 2; + pos = FindBlockStart(pos, wxT('{'), wxT('}')); + + if(pos != -1) + { + wxString indent = GetLineIndentString(LineFromPosition(pos)); + indent << wxT('}'); + DelLineLeft(); + DelLineRight(); + pos = GetCurrentPos(); + InsertText(pos, indent); + GotoPos((int)(pos + indent.Length())); + ChooseCaretX(); + } + } + + EndUndoAction(); + } } void CodeEditor::OnUpdateUI(wxScintillaEvent &event) { - HighlightBraces(); + HighlightBraces(); } bool CodeEditor::LoadFile() { - // Get filname - if (!mFileName) - { - wxFileDialog dlg (this, _T("Open file"), _T(""), _T(""), - _T("Any file (*)|*"), wxOPEN | wxFILE_MUST_EXIST | wxCHANGE_DIR); - if (dlg.ShowModal() != wxID_OK) return false; - mFileName = dlg.GetPath(); - } + // Get filname + if (!mFileName) + { + wxFileDialog dlg (this, _T("Open file"), _T(""), _T(""), + _T("Any file (*)|*"), wxOPEN | wxFILE_MUST_EXIST | wxCHANGE_DIR); + if (dlg.ShowModal() != wxID_OK) return false; + mFileName = dlg.GetPath(); + } - // Load file - return LoadFile(mFileName); + // Load file + return LoadFile(mFileName); } bool CodeEditor::LoadFile(const wxString &filename) { - // Load file in edit and clear undo - if (!filename.IsEmpty()) mFileName = filename; - if (!wxScintilla::LoadFile(mFileName)) return false; + // Load file in edit and clear undo + if (!filename.IsEmpty()) mFileName = filename; + if (!wxScintilla::LoadFile(mFileName)) return false; - // Determine lexer language - //wxFileName fname(mFileName); - //InitializePrefs(DeterminePrefs(fname.GetFullName())); + // Determine lexer language + //wxFileName fname(mFileName); + //InitializePrefs(DeterminePrefs(fname.GetFullName())); - return true; + return true; } bool CodeEditor::SaveFile() { - // Return if no change - if (!Modified()) return true; + // Return if no change + if (!Modified()) return true; - // Get file name - if (!mFileName) - { - wxFileDialog dlg (this, _T("Save file"), _T(""), _T(""), _T("Any file (*)|*"), - wxSAVE | wxOVERWRITE_PROMPT); - if (dlg.ShowModal() != wxID_OK) return false; - mFileName = dlg.GetPath(); - } + // Get file name + if (!mFileName) + { + wxFileDialog dlg (this, _T("Save file"), _T(""), _T(""), _T("Any file (*)|*"), + wxSAVE | wxOVERWRITE_PROMPT); + if (dlg.ShowModal() != wxID_OK) return false; + mFileName = dlg.GetPath(); + } - // Save file - return SaveFile(mFileName); + // Save file + return SaveFile(mFileName); } bool CodeEditor::SaveFile(const wxString &filename) { - // Return if no change - if (!Modified()) return true; + // Return if no change + if (!Modified()) return true; - return wxScintilla::SaveFile(filename); + return wxScintilla::SaveFile(filename); } bool CodeEditor::Modified() { - // Return modified state - return (GetModify() && !GetReadOnly()); + // Return modified state + return (GetModify() && !GetReadOnly()); } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/DocManager.cpp b/Tools/MaterialEditor/MaterialEditor/src/DocManager.cpp index 4010f396dbe..b5fcc4460b3 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/DocManager.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/DocManager.cpp @@ -45,58 +45,58 @@ DocManager::~DocManager() void DocManager::load(wxString& path) { - // TODO: Clear tips list - - std::ifstream fp; - fp.open(path, std::ios::in | std::ios::binary); - if(fp) - { - DataStreamPtr stream(new FileStreamDataStream(path.c_str(), &fp, false)); - - int index = -1; - String line; - String key; - while(!stream->eof()) - { - line = stream->getLine(); - - // Ignore comments - if(line.length() > 0 && line.at(0) == '#') continue; - - if(line.length() > 0 && line.at(0) == '[') - { - int endBrace = (int)line.find(']'); - if(endBrace != -1) - { - key = line.substr(1, endBrace - 1); - } - } - else - { - if(mDocs.find(key) != mDocs.end()) - mDocs[key] = mDocs[key] + "\n" + line; - else - mDocs[key] = line; - } - } - } + // TODO: Clear tips list + + std::ifstream fp; + fp.open(path, std::ios::in | std::ios::binary); + if(fp) + { + DataStreamPtr stream(new FileStreamDataStream(path.c_str(), &fp, false)); + + int index = -1; + String line; + String key; + while(!stream->eof()) + { + line = stream->getLine(); + + // Ignore comments + if(line.length() > 0 && line.at(0) == '#') continue; + + if(line.length() > 0 && line.at(0) == '[') + { + int endBrace = (int)line.find(']'); + if(endBrace != -1) + { + key = line.substr(1, endBrace - 1); + } + } + else + { + if(mDocs.find(key) != mDocs.end()) + mDocs[key] = mDocs[key] + "\n" + line; + else + mDocs[key] = line; + } + } + } } void DocManager::addDoc(wxString& key, wxString& doc) { - mDocs[key] = doc; + mDocs[key] = doc; } void DocManager::removeDoc(wxString& key) { - DocMap::iterator it = mDocs.find(key); - if(it != mDocs.end()) mDocs.erase(it); + DocMap::iterator it = mDocs.find(key); + if(it != mDocs.end()) mDocs.erase(it); } wxString* DocManager::find(wxString& s) { - if(mDocs.find(s) != mDocs.end()) - return &mDocs[s]; + if(mDocs.find(s) != mDocs.end()) + return &mDocs[s]; - return NULL; + return NULL; } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/DocPanel.cpp b/Tools/MaterialEditor/MaterialEditor/src/DocPanel.cpp index 1e2b23c83a4..4bcb5cb2c28 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/DocPanel.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/DocPanel.cpp @@ -23,18 +23,18 @@ DocPanel::DocPanel(wxWindow* parent, wxWindowID id /* = wxID_ANY */, const wxPoint& pos /* = wxDefaultPosition */, const wxSize& size /* = wxDeafultSize */, long style /* = wxTAB_TRAVERSAL */, const wxString& name /* = */) : wxPanel(parent, id, pos, size, style, name), mEditor(NULL) { - mBoxSizer = new wxBoxSizer(wxVERTICAL); + mBoxSizer = new wxBoxSizer(wxVERTICAL); - mTextControl = new wxTextCtrl(this, -1, wxT(""), wxDefaultPosition, wxSize(200,150), wxNO_BORDER | wxTE_MULTILINE); - mTextControl->SetEditable(false); - mTextControl->SetBackgroundColour(wxColor(255, 255, 225)); - mTextControl->AppendText("N/A"); - mBoxSizer->Add(mTextControl, 1, wxEXPAND | wxALL, 0); + mTextControl = new wxTextCtrl(this, -1, wxT(""), wxDefaultPosition, wxSize(200,150), wxNO_BORDER | wxTE_MULTILINE); + mTextControl->SetEditable(false); + mTextControl->SetBackgroundColour(wxColor(255, 255, 225)); + mTextControl->AppendText("N/A"); + mBoxSizer->Add(mTextControl, 1, wxEXPAND | wxALL, 0); - SetSizer(mBoxSizer); - Layout(); + SetSizer(mBoxSizer); + Layout(); - EditorManager::getSingletonPtr()->subscribe(EditorManager::ActiveEditorChanged, boost::bind(&DocPanel::OnActiveEditorChanged, this, _1)); + EditorManager::getSingletonPtr()->subscribe(EditorManager::ActiveEditorChanged, boost::bind(&DocPanel::OnActiveEditorChanged, this, _1)); } DocPanel::~DocPanel() @@ -43,38 +43,38 @@ DocPanel::~DocPanel() void DocPanel::OnActiveEditorChanged(EventArgs& args) { - EditorEventArgs eea = dynamic_cast(args); - Editor* editor = eea.getEditor(); - - // TODO: Unsubscribe from previous editor - - // FIXME - if(typeid(*editor) == typeid(ScintillaEditor) || - typeid(*editor) == typeid(MaterialScriptEditor) || - typeid(*editor) == typeid(CgEditor) || - typeid(*editor) == typeid(GLSLEditor) || - typeid(*editor) == typeid(HLSLEditor)) - { - mEditor = dynamic_cast(editor); - mEditor->subscribe(ScintillaEditor::FocusedWordChanged, boost::bind(&DocPanel::OnFocusedWordChanged, this, _1)); - } - else mEditor = NULL; + EditorEventArgs eea = dynamic_cast(args); + Editor* editor = eea.getEditor(); + + // TODO: Unsubscribe from previous editor + + // FIXME + if(typeid(*editor) == typeid(ScintillaEditor) || + typeid(*editor) == typeid(MaterialScriptEditor) || + typeid(*editor) == typeid(CgEditor) || + typeid(*editor) == typeid(GLSLEditor) || + typeid(*editor) == typeid(HLSLEditor)) + { + mEditor = dynamic_cast(editor); + mEditor->subscribe(ScintillaEditor::FocusedWordChanged, boost::bind(&DocPanel::OnFocusedWordChanged, this, _1)); + } + else mEditor = NULL; } void DocPanel::OnFocusedWordChanged(EventArgs& args) { - mTextControl->Clear(); - if(mEditor != NULL) - { - ScintillaEditorEventArgs seea = dynamic_cast(args); - wxString* doc = mEditor->getDocManager().find(seea.getFocusedWord()); - - if(doc != NULL && !doc->IsEmpty() && (*doc) != "") - { - mTextControl->AppendText(*doc); - return; - } - } - - mTextControl->AppendText("N/A"); + mTextControl->Clear(); + if(mEditor != NULL) + { + ScintillaEditorEventArgs seea = dynamic_cast(args); + wxString* doc = mEditor->getDocManager().find(seea.getFocusedWord()); + + if(doc != NULL && !doc->IsEmpty() && (*doc) != "") + { + mTextControl->AppendText(*doc); + return; + } + } + + mTextControl->AppendText("N/A"); } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/Editor.cpp b/Tools/MaterialEditor/MaterialEditor/src/Editor.cpp index 3c4c25cc86d..9da76c895b6 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/Editor.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/Editor.cpp @@ -35,13 +35,13 @@ THE SOFTWARE. Editor::Editor() : mEditorInput(NULL), mName("Editor") { - registerEvents(); + registerEvents(); } Editor::Editor(EditorInput* input) : mEditorInput(input) { - registerEvents(); + registerEvents(); } Editor::~Editor() @@ -50,124 +50,124 @@ Editor::~Editor() wxControl* Editor::getControl() const { - return mControl; + return mControl; } void Editor::setControl(wxControl* control) { - mControl = control; + mControl = control; } void Editor::registerEvents() { - registerEvent(NameChanged); - registerEvent(DirtyStateChanged); + registerEvent(NameChanged); + registerEvent(DirtyStateChanged); } EditorInput* Editor::getEditorInput() const { - return mEditorInput; + return mEditorInput; } void Editor::setEditorInput(EditorInput* input) { - mEditorInput = input; + mEditorInput = input; } EditorContributor* Editor::getEditorContributor() const { - return NULL; + return NULL; } const wxString& Editor::getName() const { - return mName; + return mName; } void Editor::setName(const wxString& name) { - mName = name; + mName = name; - fireEvent(NameChanged, EditorEventArgs(this)); + fireEvent(NameChanged, EditorEventArgs(this)); } void Editor::activate() { - // Do nothing + // Do nothing } void Editor::deactivate() { - // Do nothing + // Do nothing } bool Editor::isDirty() { - return false; + return false; } void Editor::save() { - // Do nothing + // Do nothing } void Editor::saveAs() { - // Do nothing + // Do nothing } bool Editor::isSaveAsAllowed() { - return false; + return false; } bool Editor::isRedoable() { - return false; + return false; } void Editor::redo() { - // Do nothing + // Do nothing } bool Editor::isUndoable() { - return false; + return false; } void Editor::undo() { - // Do nothing + // Do nothing } bool Editor::isCuttable() { - return false; + return false; } void Editor::cut() { - // Do nothing + // Do nothing } bool Editor::isCopyable() { - return false; + return false; } void Editor::copy() { - // Do nothing + // Do nothing } bool Editor::isPastable() { - return false; + return false; } void Editor::paste() { - // Do nothing + // Do nothing } diff --git a/Tools/MaterialEditor/MaterialEditor/src/EditorManager.cpp b/Tools/MaterialEditor/MaterialEditor/src/EditorManager.cpp index f981352a871..2cfe17f2983 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/EditorManager.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/EditorManager.cpp @@ -38,26 +38,26 @@ template<> EditorManager* Ogre::Singleton::msSingleton = 0; EditorManager& EditorManager::getSingleton(void) { - assert( msSingleton ); return ( *msSingleton ); + assert( msSingleton ); return ( *msSingleton ); } EditorManager* EditorManager::getSingletonPtr(void) { - return msSingleton; + return msSingleton; } EditorManager::EditorManager(wxAuiNotebook* notebook) : mEditorNotebook(notebook), mActiveEditor(NULL) { - registerEvents(); + registerEvents(); - if(mEditorNotebook != NULL) - { - Connect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler(EditorManager::OnPageChanged)); - Connect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler(EditorManager::OnPageClosed)); + if(mEditorNotebook != NULL) + { + Connect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler(EditorManager::OnPageChanged)); + Connect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler(EditorManager::OnPageClosed)); - mEditorNotebook->PushEventHandler(this); - } + mEditorNotebook->PushEventHandler(this); + } } EditorManager::~EditorManager() @@ -67,208 +67,208 @@ EditorManager::~EditorManager() wxAuiNotebook* EditorManager::getEditorNotebook() const { - return mEditorNotebook; + return mEditorNotebook; } void EditorManager::setEditorNotebook(wxAuiNotebook* notebook) { - if(mEditorNotebook != NULL) - { - Disconnect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler(EditorManager::OnPageChanged)); - Disconnect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler(EditorManager::OnPageClosed)); - - mEditorNotebook->RemoveEventHandler(this); - } - - mEditorNotebook = notebook; - - if(mEditorNotebook != NULL) - { - Connect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler(EditorManager::OnPageChanged)); - Connect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler(EditorManager::OnPageClosed)); - - mEditorNotebook->PushEventHandler(this); - } + if(mEditorNotebook != NULL) + { + Disconnect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler(EditorManager::OnPageChanged)); + Disconnect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler(EditorManager::OnPageClosed)); + + mEditorNotebook->RemoveEventHandler(this); + } + + mEditorNotebook = notebook; + + if(mEditorNotebook != NULL) + { + Connect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler(EditorManager::OnPageChanged)); + Connect(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEventHandler(EditorManager::OnPageClosed)); + + mEditorNotebook->PushEventHandler(this); + } } void EditorManager::openEditor(Editor* editor) { - assert(mEditorNotebook != NULL); + assert(mEditorNotebook != NULL); - mEditors.push_back(editor); - mEditorNotebook->AddPage(editor->getControl(), editor->getName(), true); + mEditors.push_back(editor); + mEditorNotebook->AddPage(editor->getControl(), editor->getName(), true); - mEditorIndexMap[editor] = mEditorNotebook->GetPageIndex(editor->getControl()); + mEditorIndexMap[editor] = mEditorNotebook->GetPageIndex(editor->getControl()); - editor->subscribe(Editor::NameChanged, boost::bind(&EditorManager::nameChanged, this, _1)); + editor->subscribe(Editor::NameChanged, boost::bind(&EditorManager::nameChanged, this, _1)); - setActiveEditor(editor); + setActiveEditor(editor); } void EditorManager::closeEditor(Editor* editor) { - assert(mEditorNotebook != NULL); + assert(mEditorNotebook != NULL); - if(mEditorIndexMap.find(editor) != mEditorIndexMap.end()) - { - if(mActiveEditor == editor) - { - mActiveEditor->deactivate(); - mActiveEditor = NULL; - } + if(mEditorIndexMap.find(editor) != mEditorIndexMap.end()) + { + if(mActiveEditor == editor) + { + mActiveEditor->deactivate(); + mActiveEditor = NULL; + } - int index = mEditorIndexMap[editor]; - mEditorNotebook->RemovePage(index); + int index = mEditorIndexMap[editor]; + mEditorNotebook->RemovePage(index); - fireEvent(EditorClosed, EditorEventArgs(editor)); - } + fireEvent(EditorClosed, EditorEventArgs(editor)); + } } Editor* EditorManager::findEditor(const wxString& name) { - EditorList::iterator it; - Editor* editor = NULL; - for(it = mEditors.begin(); it != mEditors.end(); ++it) - { - editor = (*it); - if(editor->getName() == name) return editor; - } - - return NULL; + EditorList::iterator it; + Editor* editor = NULL; + for(it = mEditors.begin(); it != mEditors.end(); ++it) + { + editor = (*it); + if(editor->getName() == name) return editor; + } + + return NULL; } Editor* EditorManager::getActiveEditor() const { - return mActiveEditor; + return mActiveEditor; } void EditorManager::setActiveEditor(Editor* editor) { - if(mActiveEditor == editor) return; + if(mActiveEditor == editor) return; - if(mActiveEditor != NULL) mActiveEditor->deactivate(); + if(mActiveEditor != NULL) mActiveEditor->deactivate(); - mActiveEditor = editor; + mActiveEditor = editor; - if(mActiveEditor != NULL) - { - mActiveEditor->activate(); + if(mActiveEditor != NULL) + { + mActiveEditor->activate(); - if(mEditorNotebook != NULL && (mEditorIndexMap.find(mActiveEditor) != mEditorIndexMap.end())) - { - mEditorNotebook->SetSelection(mEditorIndexMap[mActiveEditor]); - } - } + if(mEditorNotebook != NULL && (mEditorIndexMap.find(mActiveEditor) != mEditorIndexMap.end())) + { + mEditorNotebook->SetSelection(mEditorIndexMap[mActiveEditor]); + } + } - fireEvent(ActiveEditorChanged, EditorEventArgs(mActiveEditor)); + fireEvent(ActiveEditorChanged, EditorEventArgs(mActiveEditor)); } const EditorList& EditorManager::getEditors() const { - return mEditors; + return mEditors; } void EditorManager::registerEvents() { - registerEvent(EditorOpened); - registerEvent(EditorClosed); - registerEvent(ActiveEditorChanged); + registerEvent(EditorOpened); + registerEvent(EditorClosed); + registerEvent(ActiveEditorChanged); } void EditorManager::nameChanged(EventArgs& args) { - EditorEventArgs eea = dynamic_cast(args); - Editor* editor = eea.getEditor(); - if(mEditorIndexMap.find(editor) != mEditorIndexMap.end()) - { - int index = mEditorIndexMap[editor]; - mEditorNotebook->SetPageText(index, editor->getName()); - } + EditorEventArgs eea = dynamic_cast(args); + Editor* editor = eea.getEditor(); + if(mEditorIndexMap.find(editor) != mEditorIndexMap.end()) + { + int index = mEditorIndexMap[editor]; + mEditorNotebook->SetPageText(index, editor->getName()); + } } void EditorManager::OnPageChanged(wxAuiNotebookEvent& event) { - int index = event.GetSelection(); - - if(mActiveEditor != NULL) - { - if(mEditorIndexMap.find(mActiveEditor) != mEditorIndexMap.end()) - { - int oldIndex = mEditorIndexMap[mActiveEditor]; - - if(index != oldIndex) - { - mActiveEditor->deactivate(); - - EditorIndexMap::iterator it; - for(it = mEditorIndexMap.begin(); it != mEditorIndexMap.end(); ++it) - { - if(it->second == index) - { - setActiveEditor(it->first); - break; - } - } - } - } - } - else - { - EditorIndexMap::iterator it; - for(it = mEditorIndexMap.begin(); it != mEditorIndexMap.end(); ++it) - { - if(it->second == index) - { - setActiveEditor(it->first); - } - } - } + int index = event.GetSelection(); + + if(mActiveEditor != NULL) + { + if(mEditorIndexMap.find(mActiveEditor) != mEditorIndexMap.end()) + { + int oldIndex = mEditorIndexMap[mActiveEditor]; + + if(index != oldIndex) + { + mActiveEditor->deactivate(); + + EditorIndexMap::iterator it; + for(it = mEditorIndexMap.begin(); it != mEditorIndexMap.end(); ++it) + { + if(it->second == index) + { + setActiveEditor(it->first); + break; + } + } + } + } + } + else + { + EditorIndexMap::iterator it; + for(it = mEditorIndexMap.begin(); it != mEditorIndexMap.end(); ++it) + { + if(it->second == index) + { + setActiveEditor(it->first); + } + } + } } void EditorManager::OnPageClosed(wxAuiNotebookEvent& event) { - int index = event.GetSelection(); - - Editor* editor = NULL; - EditorIndexMap::iterator it; - for(it = mEditorIndexMap.begin(); it != mEditorIndexMap.end(); ++it) - { - if(it->second == index) - { - editor = it->first; - editor->deactivate(); - mEditorIndexMap.erase(it); - break; - } - } - - if(editor != NULL) - { - if(editor == mActiveEditor) - mActiveEditor = NULL; - - EditorList::iterator lit; - for(lit = mEditors.begin(); lit != mEditors.end(); ++lit) - { - if((*lit) == editor) - { - mEditors.erase(lit); - break; - } - } - } - - fireEvent(EditorClosed, EditorEventArgs(editor)); - - // Is this handled by OnPageChanged? - int selIndex = event.GetSelection(); - for(it = mEditorIndexMap.begin(); it != mEditorIndexMap.end(); ++it) - { - if(it->second == index) - { - setActiveEditor(it->first); - break; - } - } + int index = event.GetSelection(); + + Editor* editor = NULL; + EditorIndexMap::iterator it; + for(it = mEditorIndexMap.begin(); it != mEditorIndexMap.end(); ++it) + { + if(it->second == index) + { + editor = it->first; + editor->deactivate(); + mEditorIndexMap.erase(it); + break; + } + } + + if(editor != NULL) + { + if(editor == mActiveEditor) + mActiveEditor = NULL; + + EditorList::iterator lit; + for(lit = mEditors.begin(); lit != mEditors.end(); ++lit) + { + if((*lit) == editor) + { + mEditors.erase(lit); + break; + } + } + } + + fireEvent(EditorClosed, EditorEventArgs(editor)); + + // Is this handled by OnPageChanged? + int selIndex = event.GetSelection(); + for(it = mEditorIndexMap.begin(); it != mEditorIndexMap.end(); ++it) + { + if(it->second == index) + { + setActiveEditor(it->first); + break; + } + } } diff --git a/Tools/MaterialEditor/MaterialEditor/src/EventContainer.cpp b/Tools/MaterialEditor/MaterialEditor/src/EventContainer.cpp index 2cf3bac3512..8703fb704bb 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/EventContainer.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/EventContainer.cpp @@ -39,25 +39,25 @@ EventContainer::~EventContainer() void EventContainer::subscribe(int eventId, EventHandler handler) { - DelegateMap::iterator it = mDelegates.find(eventId); - it->second->connect(handler); + DelegateMap::iterator it = mDelegates.find(eventId); + it->second->connect(handler); } // TODO: Implement unsubscribe void EventContainer::unsubscribe(int eventId,EventHandler handler) { - DelegateMap::iterator it = mDelegates.find(eventId); - //it->second->disconnect(handler); + DelegateMap::iterator it = mDelegates.find(eventId); + //it->second->disconnect(handler); } // Should we throw an exception on duplicate event IDs? void EventContainer::registerEvent(int eventId) { - mDelegates[eventId] = new Delegate(); + mDelegates[eventId] = new Delegate(); } void EventContainer::fireEvent(int eventId, EventArgs& args) { - DelegateMap::iterator it = mDelegates.find(eventId); - (*(it->second))(args); + DelegateMap::iterator it = mDelegates.find(eventId); + (*(it->second))(args); } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/GLSLEditor.cpp b/Tools/MaterialEditor/MaterialEditor/src/GLSLEditor.cpp index 99f80921064..0b8ca4b1030 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/GLSLEditor.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/GLSLEditor.cpp @@ -28,17 +28,17 @@ THE SOFTWARE. #include "GLSLEditor.h" BEGIN_EVENT_TABLE(GLSLEditor, ScintillaEditor) - // Scintilla - EVT_SCI_CHARADDED (-1, GLSLEditor::OnCharAdded) + // Scintilla + EVT_SCI_CHARADDED (-1, GLSLEditor::OnCharAdded) END_EVENT_TABLE() GLSLEditor::GLSLEditor(wxWindow* parent, wxWindowID id /*= -1*/, - const wxPoint& pos /*= wxDefaultPosition*/, - const wxSize& size /*= wxDefaultSize*/, - long style /*= wxVSCROLL*/ - ) : ScintillaEditor(parent, id, pos, size, style) + const wxPoint& pos /*= wxDefaultPosition*/, + const wxSize& size /*= wxDefaultSize*/, + long style /*= wxVSCROLL*/ + ) : ScintillaEditor(parent, id, pos, size, style) { - initialize(); + initialize(); } GLSLEditor::~GLSLEditor() @@ -47,59 +47,59 @@ GLSLEditor::~GLSLEditor() void GLSLEditor::initialize() { - StyleClearAll(); - SetLexer(wxSCI_LEX_CPP); + StyleClearAll(); + SetLexer(wxSCI_LEX_CPP); - // Load keywords - wxString path = wxT("../lexers/glsl/keywords"); - loadKeywords(path); + // Load keywords + wxString path = wxT("../lexers/glsl/keywords"); + loadKeywords(path); - // Load call tips - path = wxT("../lexers/glsl/calltips"); - getCallTipManager().load(path); - wxChar trigger('('); - getCallTipManager().addTrigger(trigger); + // Load call tips + path = wxT("../lexers/glsl/calltips"); + getCallTipManager().load(path); + wxChar trigger('('); + getCallTipManager().addTrigger(trigger); - // Set styles - StyleSetForeground(wxSCI_C_COMMENT, wxColour(0, 128, 0)); - StyleSetFontAttr(wxSCI_C_COMMENT, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_C_COMMENTLINE, wxColour(0, 128, 0)); - StyleSetFontAttr(wxSCI_C_COMMENTLINE, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_C_NUMBER, wxColour(0, 0, 128)); - StyleSetFontAttr(wxSCI_C_NUMBER, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_C_STRING, wxColour(200, 200, 200)); - StyleSetFontAttr(wxSCI_C_STRING, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_C_WORD, wxColour(0, 0, 255)); - StyleSetFontAttr(wxSCI_C_WORD, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_C_WORD2, wxColour(136, 0, 0)); - StyleSetFontAttr(wxSCI_C_WORD2, 10, "Courier New", false, false, false); + // Set styles + StyleSetForeground(wxSCI_C_COMMENT, wxColour(0, 128, 0)); + StyleSetFontAttr(wxSCI_C_COMMENT, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_C_COMMENTLINE, wxColour(0, 128, 0)); + StyleSetFontAttr(wxSCI_C_COMMENTLINE, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_C_NUMBER, wxColour(0, 0, 128)); + StyleSetFontAttr(wxSCI_C_NUMBER, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_C_STRING, wxColour(200, 200, 200)); + StyleSetFontAttr(wxSCI_C_STRING, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_C_WORD, wxColour(0, 0, 255)); + StyleSetFontAttr(wxSCI_C_WORD, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_C_WORD2, wxColour(136, 0, 0)); + StyleSetFontAttr(wxSCI_C_WORD2, 10, "Courier New", false, false, false); } void GLSLEditor::OnCharAdded(wxScintillaEvent &event) { - char ch = event.GetKey(); - if(getCallTipManager().isTrigger(ch)) - { - int lineNum = GetCurrentLine(); - if(lineNum != -1) - { - wxString line = GetLine(lineNum); - int pos = GetCurrentPos() - 1; + char ch = event.GetKey(); + if(getCallTipManager().isTrigger(ch)) + { + int lineNum = GetCurrentLine(); + if(lineNum != -1) + { + wxString line = GetLine(lineNum); + int pos = GetCurrentPos() - 1; - wxString word(""); - wxChar ch; - while(pos) - { - ch = GetCharAt(--pos); - if(ch != ' ' || ch != '\n') word.Prepend(ch); - else break; - } + wxString word(""); + wxChar ch; + while(pos) + { + ch = GetCharAt(--pos); + if(ch != ' ' || ch != '\n') word.Prepend(ch); + else break; + } - wxString* tips = getCallTipManager().find(word); - if(tips != NULL) - { - CallTipShow(pos, *tips); - } - } - } + wxString* tips = getCallTipManager().find(word); + if(tips != NULL) + { + CallTipShow(pos, *tips); + } + } + } } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/HLSLEditor.cpp b/Tools/MaterialEditor/MaterialEditor/src/HLSLEditor.cpp index 7e0638db7a7..03f894a529a 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/HLSLEditor.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/HLSLEditor.cpp @@ -28,12 +28,12 @@ THE SOFTWARE. #include "HLSLEditor.h" HLSLEditor::HLSLEditor(wxWindow* parent, wxWindowID id /*= -1*/, - const wxPoint& pos /*= wxDefaultPosition*/, - const wxSize& size /*= wxDefaultSize*/, - long style /*= wxVSCROLL*/ - ) : ScintillaEditor(parent, id, pos, size, style) + const wxPoint& pos /*= wxDefaultPosition*/, + const wxSize& size /*= wxDefaultSize*/, + long style /*= wxVSCROLL*/ + ) : ScintillaEditor(parent, id, pos, size, style) { - initialize(); + initialize(); } HLSLEditor::~HLSLEditor() @@ -42,24 +42,24 @@ HLSLEditor::~HLSLEditor() void HLSLEditor::initialize() { - StyleClearAll(); - SetLexer(wxSCI_LEX_OMS); + StyleClearAll(); + SetLexer(wxSCI_LEX_OMS); - // Load keywords - wxString path = wxT("../lexers/hlsl/keywords"); - loadKeywords(path); - - // Set styles - StyleSetForeground(wxSCI_OMS_DEFAULT, wxColour(0, 0, 0)); - StyleSetFontAttr(wxSCI_OMS_DEFAULT, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_OMS_COMMENT, wxColour(0, 128, 0)); - StyleSetFontAttr(wxSCI_OMS_COMMENT, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_OMS_PRIMARY, wxColour(0, 0, 255)); - StyleSetFontAttr(wxSCI_OMS_PRIMARY, 10, "Courier New", true, false, false); - StyleSetForeground(wxSCI_OMS_ATTRIBUTE, wxColour(136, 0, 0)); - StyleSetFontAttr(wxSCI_OMS_ATTRIBUTE, 10, "Courier New", true, false, false); - StyleSetForeground(wxSCI_OMS_VALUE, wxColour(160, 0, 160)); - StyleSetFontAttr(wxSCI_OMS_VALUE, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_OMS_NUMBER, wxColour(0, 0, 128)); - StyleSetFontAttr(wxSCI_OMS_NUMBER, 10, "Courier New", false, false, false); + // Load keywords + wxString path = wxT("../lexers/hlsl/keywords"); + loadKeywords(path); + + // Set styles + StyleSetForeground(wxSCI_OMS_DEFAULT, wxColour(0, 0, 0)); + StyleSetFontAttr(wxSCI_OMS_DEFAULT, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_OMS_COMMENT, wxColour(0, 128, 0)); + StyleSetFontAttr(wxSCI_OMS_COMMENT, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_OMS_PRIMARY, wxColour(0, 0, 255)); + StyleSetFontAttr(wxSCI_OMS_PRIMARY, 10, "Courier New", true, false, false); + StyleSetForeground(wxSCI_OMS_ATTRIBUTE, wxColour(136, 0, 0)); + StyleSetFontAttr(wxSCI_OMS_ATTRIBUTE, 10, "Courier New", true, false, false); + StyleSetForeground(wxSCI_OMS_VALUE, wxColour(160, 0, 160)); + StyleSetFontAttr(wxSCI_OMS_VALUE, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_OMS_NUMBER, wxColour(0, 0, 128)); + StyleSetFontAttr(wxSCI_OMS_NUMBER, 10, "Courier New", false, false, false); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/IconManager.cpp b/Tools/MaterialEditor/MaterialEditor/src/IconManager.cpp index 407a3829fb0..2412a168e63 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/IconManager.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/IconManager.cpp @@ -4,23 +4,23 @@ template<> IconManager* Ogre::Singleton::msSingleton = 0; IconManager::IconManager() { - mIconMap[CLOSE] = wxBitmap(close_xpm); - mIconMap[COPY] = wxBitmap(copy_xpm); - mIconMap[CUT] = wxBitmap(cut_xpm); - mIconMap[MATERIAL] = wxBitmap(material_xpm); - mIconMap[MATERIAL_SCRIPT] = wxBitmap(material_script_xpm); - mIconMap[OGRE] = wxBitmap(ogre_xpm); - mIconMap[PASS] = wxBitmap(pass_xpm); - mIconMap[PASTE] = wxBitmap(paste_xpm); - mIconMap[PROGRAM_SCRIPT] = wxBitmap(program_script_xpm); - mIconMap[PROJECT] = wxBitmap(project_xpm); - mIconMap[PROJECT_NEW] = wxBitmap(project_new_xpm); - mIconMap[PROJECT_SAVE] = wxBitmap(project_save_xpm); - mIconMap[SAVE] = wxBitmap(save_xpm); - mIconMap[SAVE_AS] = wxBitmap(save_as_xpm); - mIconMap[SHADER] = wxBitmap(shader_xpm); - mIconMap[TECHNIQUE] = wxBitmap(technique_xpm); - mIconMap[WORKSPACE] = wxBitmap(workspace_xpm); + mIconMap[CLOSE] = wxBitmap(close_xpm); + mIconMap[COPY] = wxBitmap(copy_xpm); + mIconMap[CUT] = wxBitmap(cut_xpm); + mIconMap[MATERIAL] = wxBitmap(material_xpm); + mIconMap[MATERIAL_SCRIPT] = wxBitmap(material_script_xpm); + mIconMap[OGRE] = wxBitmap(ogre_xpm); + mIconMap[PASS] = wxBitmap(pass_xpm); + mIconMap[PASTE] = wxBitmap(paste_xpm); + mIconMap[PROGRAM_SCRIPT] = wxBitmap(program_script_xpm); + mIconMap[PROJECT] = wxBitmap(project_xpm); + mIconMap[PROJECT_NEW] = wxBitmap(project_new_xpm); + mIconMap[PROJECT_SAVE] = wxBitmap(project_save_xpm); + mIconMap[SAVE] = wxBitmap(save_xpm); + mIconMap[SAVE_AS] = wxBitmap(save_as_xpm); + mIconMap[SHADER] = wxBitmap(shader_xpm); + mIconMap[TECHNIQUE] = wxBitmap(technique_xpm); + mIconMap[WORKSPACE] = wxBitmap(workspace_xpm); } IconManager::~IconManager() @@ -29,15 +29,15 @@ IconManager::~IconManager() const wxBitmap& IconManager::getIcon(IconType type) const { - IconMap::const_iterator iconItr = mIconMap.find(type); - if(iconItr == mIconMap.end()) - { - return wxNullBitmap; - } - else - { - return iconItr->second; - } + IconMap::const_iterator iconItr = mIconMap.find(type); + if(iconItr == mIconMap.end()) + { + return wxNullBitmap; + } + else + { + return iconItr->second; + } } IconManager* IconManager::getSingletonPtr(void) diff --git a/Tools/MaterialEditor/MaterialEditor/src/LogPanel.cpp b/Tools/MaterialEditor/MaterialEditor/src/LogPanel.cpp index 5319505f61e..4218d0457da 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/LogPanel.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/LogPanel.cpp @@ -10,14 +10,14 @@ LogPanel::LogPanel(wxWindow* parent, wxWindowID id /* = wxID_ANY */, const wxPoint& pos /* = wxDefaultPosition */, const wxSize& size /* = wxDeafultSize */, long style /* = wxTAB_TRAVERSAL */, const wxString& name /* = */) : wxPanel(parent, id, pos, size, style, name) { - mBoxSizer = new wxBoxSizer(wxVERTICAL); - - mTextControl = new wxTextCtrl(this, -1, wxT(""), wxDefaultPosition, wxSize(200,150), wxNO_BORDER | wxTE_MULTILINE); - mTextControl->SetEditable(false); - mBoxSizer->Add(mTextControl, 1, wxEXPAND | wxALL, 0); - - SetSizer(mBoxSizer); - Layout(); + mBoxSizer = new wxBoxSizer(wxVERTICAL); + + mTextControl = new wxTextCtrl(this, -1, wxT(""), wxDefaultPosition, wxSize(200,150), wxNO_BORDER | wxTE_MULTILINE); + mTextControl->SetEditable(false); + mBoxSizer->Add(mTextControl, 1, wxEXPAND | wxALL, 0); + + SetSizer(mBoxSizer); + Layout(); } LogPanel::~LogPanel() @@ -25,19 +25,19 @@ LogPanel::~LogPanel() void LogPanel::attachLog(Ogre::Log *log) { - log->addListener(this); + log->addListener(this); } void LogPanel::detachLog(Ogre::Log *log) { - log->removeListener(this); + log->removeListener(this); } void LogPanel::messageLogged(const Ogre::String& message, Ogre::LogMessageLevel lml, bool maskDebug, const Ogre::String &logName) { - if(lml == Ogre::LML_CRITICAL || lml == Ogre::LML_NORMAL) - { - mTextControl->AppendText(wxT(message.c_str())); - mTextControl->AppendText(wxT("\n")); - } + if(lml == Ogre::LML_CRITICAL || lml == Ogre::LML_NORMAL) + { + mTextControl->AppendText(wxT(message.c_str())); + mTextControl->AppendText(wxT("\n")); + } } diff --git a/Tools/MaterialEditor/MaterialEditor/src/LogToTextRedirector.cpp b/Tools/MaterialEditor/MaterialEditor/src/LogToTextRedirector.cpp index 2e7a4b9d357..22ceb45c016 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/LogToTextRedirector.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/LogToTextRedirector.cpp @@ -6,22 +6,22 @@ LogToTextRedirector::LogToTextRedirector(wxTextCtrl* textCtrl, const String& logName) : mTextControl(textCtrl) { - mLogName = logName; - Log* log = LogManager::getSingletonPtr()->getLog(mLogName); - if(log) log->addListener(this); + mLogName = logName; + Log* log = LogManager::getSingletonPtr()->getLog(mLogName); + if(log) log->addListener(this); } LogToTextRedirector::~LogToTextRedirector() { - if(LogManager::getSingletonPtr()) - { - Log* log = LogManager::getSingletonPtr()->getLog(mLogName); - if(log) log->removeListener(this); - } + if(LogManager::getSingletonPtr()) + { + Log* log = LogManager::getSingletonPtr()->getLog(mLogName); + if(log) log->removeListener(this); + } } void LogToTextRedirector::messageLogged(const String& message, LogMessageLevel level, bool maskDebug, const String &logName) { - if(mTextControl && !mTextControl->IsBeingDeleted()) - *mTextControl << "[" << logName << "] " << message << "\n"; + if(mTextControl && !mTextControl->IsBeingDeleted()) + *mTextControl << "[" << logName << "] " << message << "\n"; } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/MaterialController.cpp b/Tools/MaterialEditor/MaterialEditor/src/MaterialController.cpp index c56e477d8a0..24508d1a230 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/MaterialController.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/MaterialController.cpp @@ -36,13 +36,13 @@ THE SOFTWARE MaterialController::MaterialController() : mMaterialPtr(NULL) { - registerEvents(); + registerEvents(); } MaterialController::MaterialController(MaterialPtr materialPtr) : mMaterialPtr(materialPtr) { - registerEvents(); + registerEvents(); } MaterialController::~MaterialController() @@ -51,261 +51,261 @@ MaterialController::~MaterialController() void MaterialController::registerEvents() { - registerEvent(NameChanged); - registerEvent(TechniqueAdded); - registerEvent(TechniqueRemoved); + registerEvent(NameChanged); + registerEvent(TechniqueAdded); + registerEvent(TechniqueRemoved); } MaterialPtr MaterialController::getMaterial() const { - return mMaterialPtr; + return mMaterialPtr; } void MaterialController::setMaterial(MaterialPtr mp) { - mMaterialPtr = mp; + mMaterialPtr = mp; } TechniqueController* MaterialController::getTechniqueController(const String& name) { - TechniqueController* tc; - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - { - tc = (*it); - if(tc->getTechnique()->getName() == name) return tc; - } + TechniqueController* tc; + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + { + tc = (*it); + if(tc->getTechnique()->getName() == name) return tc; + } - return NULL; + return NULL; } const TechniqueControllerList* MaterialController::getTechniqueControllers() const { - return &mTechniqueControllers; + return &mTechniqueControllers; } void MaterialController::setName(const String& name) { - // ??? + // ??? } void MaterialController::setReceiveShadows(bool enabled) { - mMaterialPtr->setReceiveShadows(enabled); + mMaterialPtr->setReceiveShadows(enabled); } void MaterialController::setTransparencyCastsShadows(bool enabled) { - mMaterialPtr->setTransparencyCastsShadows(enabled); + mMaterialPtr->setTransparencyCastsShadows(enabled); } TechniqueController* MaterialController::createTechnique(void) { - Technique* t = mMaterialPtr->createTechnique(); + Technique* t = mMaterialPtr->createTechnique(); - // Create controller - TechniqueController* tc = new TechniqueController(t); - mTechniqueControllers.push_back(tc); + // Create controller + TechniqueController* tc = new TechniqueController(t); + mTechniqueControllers.push_back(tc); - fireEvent(TechniqueAdded, MaterialEventArgs(this, tc)); + fireEvent(TechniqueAdded, MaterialEventArgs(this, tc)); - return tc; + return tc; } TechniqueController* MaterialController::createTechnique(const String& name) { - Technique* t = mMaterialPtr->createTechnique(); - t->setName(name); + Technique* t = mMaterialPtr->createTechnique(); + t->setName(name); - // Create controller - TechniqueController* tc = new TechniqueController(t); - mTechniqueControllers.push_back(tc); + // Create controller + TechniqueController* tc = new TechniqueController(t); + mTechniqueControllers.push_back(tc); - fireEvent(TechniqueAdded, MaterialEventArgs(this, tc)); + fireEvent(TechniqueAdded, MaterialEventArgs(this, tc)); - return tc; + return tc; } void MaterialController::removeTechnique(unsigned short index) { - mMaterialPtr->removeTechnique(index); + mMaterialPtr->removeTechnique(index); - fireEvent(TechniqueRemoved, MaterialEventArgs(this)); + fireEvent(TechniqueRemoved, MaterialEventArgs(this)); } void MaterialController::removeAllTechniques(void) { - mMaterialPtr->removeAllTechniques(); + mMaterialPtr->removeAllTechniques(); - fireEvent(TechniqueRemoved, MaterialEventArgs(this)); + fireEvent(TechniqueRemoved, MaterialEventArgs(this)); } void MaterialController::setAmbient(const ColourValue& ambient) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setAmbient(ambient); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setAmbient(ambient); } void MaterialController::setAmbient(Real red, Real green, Real blue) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setAmbient(red, green, blue); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setAmbient(red, green, blue); } void MaterialController::setColourWriteEnabled(bool enabled) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setColourWriteEnabled(enabled); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setColourWriteEnabled(enabled); } void MaterialController::setCullingMode(CullingMode mode) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setCullingMode(mode); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setCullingMode(mode); } void MaterialController::setDepthBias(float constantBias, float slopeScaleBias) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setDepthBias(constantBias, slopeScaleBias); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setDepthBias(constantBias, slopeScaleBias); } void MaterialController::setDepthCheckEnabled(bool enabled) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setDepthCheckEnabled(enabled); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setDepthCheckEnabled(enabled); } void MaterialController::setDepthFunction(CompareFunction func) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setDepthFunction(func); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setDepthFunction(func); } void MaterialController::setDepthWriteEnabled(bool enabled) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setDepthWriteEnabled(enabled); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setDepthWriteEnabled(enabled); } void MaterialController::setDiffuse(const ColourValue& diffuse) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setDiffuse(diffuse); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setDiffuse(diffuse); } void MaterialController::setDiffuse(Real red, Real green, Real blue, Real alpha) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setDiffuse(red, green, blue, alpha); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setDiffuse(red, green, blue, alpha); } void MaterialController::setFog(bool overrideScene, FogMode mode /* = FOG_NONE */, const ColourValue& colour /* = ColourValue::White */, Real expDensity /* = 0.001 */, Real linearStart /* = 0.0 */, Real linearEnd /* = 1.0 */) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setFog(overrideScene, mode, colour, expDensity, linearStart, linearEnd); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setFog(overrideScene, mode, colour, expDensity, linearStart, linearEnd); } void MaterialController::setLightingEnabled(bool enabled) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setLightingEnabled(true); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setLightingEnabled(true); } void MaterialController::setManualCullingMode(ManualCullingMode mode) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setManualCullingMode(mode); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setManualCullingMode(mode); } void MaterialController::setPointSize(Real ps) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setPointSize(ps); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setPointSize(ps); } void MaterialController::setSceneBlending(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setSceneBlending(sourceFactor, destFactor); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setSceneBlending(sourceFactor, destFactor); } void MaterialController::setSceneBlending(const SceneBlendType sbt) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setSceneBlending(sbt); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setSceneBlending(sbt); } void MaterialController::setSelfIllumination(const ColourValue& selfIllum) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setSelfIllumination(selfIllum); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setSelfIllumination(selfIllum); } void MaterialController::setSelfIllumination(Real red, Real green, Real blue) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setSelfIllumination(red, green, blue); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setSelfIllumination(red, green, blue); } void MaterialController::setShadingMode(ShadeOptions mode) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setShadingMode(mode); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setShadingMode(mode); } void MaterialController::setShininess(Real val) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setShininess(val); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setShininess(val); } void MaterialController::setSpecular(const ColourValue& specular) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setSpecular(specular); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setSpecular(specular); } void MaterialController::setSpecular(Real red, Real green, Real blue, Real alpha) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setSpecular(red, green, blue, alpha); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setSpecular(red, green, blue, alpha); } void MaterialController::setTextureAnisotropy(unsigned int maxAniso) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setTextureAnisotropy(maxAniso); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setTextureAnisotropy(maxAniso); } void MaterialController::setTextureFiltering(TextureFilterOptions filterType) { - TechniqueControllerList::iterator it; - for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) - (*it)->setTextureFiltering(filterType); + TechniqueControllerList::iterator it; + for(it = mTechniqueControllers.begin(); it != mTechniqueControllers.end(); ++it) + (*it)->setTextureFiltering(filterType); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/MaterialDescriptor.cpp b/Tools/MaterialEditor/MaterialEditor/src/MaterialDescriptor.cpp index 18d0846d82c..b0aaaa92d9b 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/MaterialDescriptor.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/MaterialDescriptor.cpp @@ -42,29 +42,29 @@ MaterialDescriptor::MaterialDescriptor(const String& name) MaterialDescriptor::~MaterialDescriptor() { } - + const String& MaterialDescriptor::getName() const { - return mName; + return mName; } const String& MaterialDescriptor::getScript() const { - return mScript; + return mScript; } MaterialController* MaterialDescriptor::getMaterialController() { - return mMaterialController; + return mMaterialController; } void MaterialDescriptor::OnRootInitialized(EventArgs& args) { - if(mMaterialController != NULL) - { - delete mMaterialController; - mMaterialController = NULL; - } + if(mMaterialController != NULL) + { + delete mMaterialController; + mMaterialController = NULL; + } } void MaterialDescriptor::OnRootShutdown(EventArgs& args) diff --git a/Tools/MaterialEditor/MaterialEditor/src/MaterialEditorApp.cpp b/Tools/MaterialEditor/MaterialEditor/src/MaterialEditorApp.cpp index 96bbd545963..85fd0feb4c9 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/MaterialEditorApp.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/MaterialEditorApp.cpp @@ -47,37 +47,37 @@ MaterialEditorApp::~MaterialEditorApp() bool MaterialEditorApp::OnInit() { - wxInitAllImageHandlers(); + wxInitAllImageHandlers(); - wxBitmap bitmap; - if(bitmap.LoadFile("../lexers/splash.png", wxBITMAP_TYPE_PNG)) - { - wxSplashScreen* splash = new wxSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT, - 2000, NULL, -1, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER | wxSTAY_ON_TOP); - } + wxBitmap bitmap; + if(bitmap.LoadFile("../lexers/splash.png", wxBITMAP_TYPE_PNG)) + { + wxSplashScreen* splash = new wxSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT, + 2000, NULL, -1, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER | wxSTAY_ON_TOP); + } - // Create Selection Service - new SelectionService(); + // Create Selection Service + new SelectionService(); - // Ensure Workspace is created - new Workspace(); + // Ensure Workspace is created + new Workspace(); - // Create the IconManager - new IconManager(); + // Create the IconManager + new IconManager(); - MaterialEditorFrame* frame = new MaterialEditorFrame(); - frame->SetIcon(wxIcon(ogre_xpm)); - frame->Show(true); + MaterialEditorFrame* frame = new MaterialEditorFrame(); + frame->SetIcon(wxIcon(ogre_xpm)); + frame->Show(true); - SetTopWindow(frame); + SetTopWindow(frame); - return true; + return true; } int MaterialEditorApp::OnExit() { - // Minimally clean up the IconManager - delete IconManager::getSingletonPtr(); + // Minimally clean up the IconManager + delete IconManager::getSingletonPtr(); - return 0; + return 0; } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/MaterialEditorFrame.cpp b/Tools/MaterialEditor/MaterialEditor/src/MaterialEditorFrame.cpp index 52e0c3c4296..645ec969417 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/MaterialEditorFrame.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/MaterialEditorFrame.cpp @@ -100,471 +100,471 @@ const long ID_VIEW_MENU_OPENGL = wxNewId(); const long ID_VIEW_MENU_DIRECTX = wxNewId(); BEGIN_EVENT_TABLE(MaterialEditorFrame, wxFrame) - EVT_ACTIVATE(MaterialEditorFrame::OnActivate) - // File Menu - EVT_MENU (ID_FILE_NEW_MENU_PROJECT, MaterialEditorFrame::OnNewProject) - EVT_MENU (ID_FILE_NEW_MENU_MATERIAL, MaterialEditorFrame::OnNewMaterial) - EVT_MENU (ID_FILE_MENU_OPEN, MaterialEditorFrame::OnFileOpen) - EVT_MENU (ID_FILE_MENU_SAVE, MaterialEditorFrame::OnFileSave) - EVT_MENU (ID_FILE_MENU_SAVE_AS, MaterialEditorFrame::OnFileSaveAs) - EVT_MENU (ID_FILE_MENU_CLOSE, MaterialEditorFrame::OnFileClose) - EVT_MENU (ID_FILE_MENU_EXIT, MaterialEditorFrame::OnFileExit) - // Edit Menu - EVT_MENU (ID_EDIT_MENU_UNDO, MaterialEditorFrame::OnEditUndo) - EVT_MENU (ID_EDIT_MENU_REDO, MaterialEditorFrame::OnEditRedo) - EVT_MENU (ID_EDIT_MENU_CUT, MaterialEditorFrame::OnEditCut) - EVT_MENU (ID_EDIT_MENU_COPY, MaterialEditorFrame::OnEditCopy) - EVT_MENU (ID_EDIT_MENU_PASTE, MaterialEditorFrame::OnEditPaste) - // View Menu - EVT_MENU (ID_VIEW_MENU_OPENGL , MaterialEditorFrame::OnViewOpenGL) - EVT_MENU (ID_VIEW_MENU_DIRECTX, MaterialEditorFrame::OnViewDirectX) + EVT_ACTIVATE(MaterialEditorFrame::OnActivate) + // File Menu + EVT_MENU (ID_FILE_NEW_MENU_PROJECT, MaterialEditorFrame::OnNewProject) + EVT_MENU (ID_FILE_NEW_MENU_MATERIAL, MaterialEditorFrame::OnNewMaterial) + EVT_MENU (ID_FILE_MENU_OPEN, MaterialEditorFrame::OnFileOpen) + EVT_MENU (ID_FILE_MENU_SAVE, MaterialEditorFrame::OnFileSave) + EVT_MENU (ID_FILE_MENU_SAVE_AS, MaterialEditorFrame::OnFileSaveAs) + EVT_MENU (ID_FILE_MENU_CLOSE, MaterialEditorFrame::OnFileClose) + EVT_MENU (ID_FILE_MENU_EXIT, MaterialEditorFrame::OnFileExit) + // Edit Menu + EVT_MENU (ID_EDIT_MENU_UNDO, MaterialEditorFrame::OnEditUndo) + EVT_MENU (ID_EDIT_MENU_REDO, MaterialEditorFrame::OnEditRedo) + EVT_MENU (ID_EDIT_MENU_CUT, MaterialEditorFrame::OnEditCut) + EVT_MENU (ID_EDIT_MENU_COPY, MaterialEditorFrame::OnEditCopy) + EVT_MENU (ID_EDIT_MENU_PASTE, MaterialEditorFrame::OnEditPaste) + // View Menu + EVT_MENU (ID_VIEW_MENU_OPENGL , MaterialEditorFrame::OnViewOpenGL) + EVT_MENU (ID_VIEW_MENU_DIRECTX, MaterialEditorFrame::OnViewDirectX) END_EVENT_TABLE() MaterialEditorFrame::MaterialEditorFrame(wxWindow* parent) : - wxFrame(parent, - 1, wxT("Ogre Material Editor"), wxDefaultPosition, wxSize(512, 512), wxDEFAULT_FRAME_STYLE), - mMenuBar(0), - mFileMenu(0), - mEditMenu(0), - mViewMenu(0), - mToolsMenu(0), - mWindowMenu(0), - mHelpMenu(0), - mAuiManager(0), - mAuiNotebook(0), - mManagementNotebook(0), - mInformationNotebook(0), - mWorkspacePanel(0), - mResourcePanel(0), - mPropertiesPanel(0), - mRoot(0), - mEntity(0), - mLogPanel(0), - mDocPanel(0), - mOgreControl(0), - mDirectXRenderSystem(0), - mOpenGLRenderSystem(0) + wxFrame(parent, - 1, wxT("Ogre Material Editor"), wxDefaultPosition, wxSize(512, 512), wxDEFAULT_FRAME_STYLE), + mMenuBar(0), + mFileMenu(0), + mEditMenu(0), + mViewMenu(0), + mToolsMenu(0), + mWindowMenu(0), + mHelpMenu(0), + mAuiManager(0), + mAuiNotebook(0), + mManagementNotebook(0), + mInformationNotebook(0), + mWorkspacePanel(0), + mResourcePanel(0), + mPropertiesPanel(0), + mRoot(0), + mEntity(0), + mLogPanel(0), + mDocPanel(0), + mOgreControl(0), + mDirectXRenderSystem(0), + mOpenGLRenderSystem(0) { - createAuiManager(); - createMenuBar(); - - CreateToolBar(); - CreateStatusBar(); - - /* - ** We have to create the OgrePanel first - ** since some of the other panels rely on Ogre. - */ - createAuiNotebookPane(); - createOgrePane(); - createInformationPane(); - createManagementPane(); - createPropertiesPane(); - - mAuiManager->Update(); + createAuiManager(); + createMenuBar(); + + CreateToolBar(); + CreateStatusBar(); + + /* + ** We have to create the OgrePanel first + ** since some of the other panels rely on Ogre. + */ + createAuiNotebookPane(); + createOgrePane(); + createInformationPane(); + createManagementPane(); + createPropertiesPane(); + + mAuiManager->Update(); } MaterialEditorFrame::~MaterialEditorFrame() { - mLogPanel->detachLog(Ogre::LogManager::getSingleton().getDefaultLog()); + mLogPanel->detachLog(Ogre::LogManager::getSingleton().getDefaultLog()); - if(mAuiManager) - { - mAuiManager->UnInit(); - delete mAuiManager; - } + if(mAuiManager) + { + mAuiManager->UnInit(); + delete mAuiManager; + } } void MaterialEditorFrame::createAuiManager() { - mAuiManager = new wxAuiManager(); - mAuiManager->SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_ALLOW_ACTIVE_PANE | wxAUI_MGR_TRANSPARENT_DRAG); - mAuiManager->SetManagedWindow(this); - - wxAuiDockArt* art = mAuiManager->GetArtProvider(); - art->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1); - art->SetMetric(wxAUI_DOCKART_SASH_SIZE, 4); - art->SetMetric(wxAUI_DOCKART_CAPTION_SIZE, 17); - art->SetColour(wxAUI_DOCKART_ACTIVE_CAPTION_COLOUR, wxColour(49, 106, 197)); - art->SetColour(wxAUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR, wxColour(90, 135, 208)); - art->SetColour(wxAUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR, wxColour(255, 255, 255)); - art->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR, wxColour(200, 198, 183)); - art->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR, wxColour(228, 226, 209)); - art->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR, wxColour(0, 0, 0)); - - mAuiManager->Update(); + mAuiManager = new wxAuiManager(); + mAuiManager->SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_ALLOW_ACTIVE_PANE | wxAUI_MGR_TRANSPARENT_DRAG); + mAuiManager->SetManagedWindow(this); + + wxAuiDockArt* art = mAuiManager->GetArtProvider(); + art->SetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE, 1); + art->SetMetric(wxAUI_DOCKART_SASH_SIZE, 4); + art->SetMetric(wxAUI_DOCKART_CAPTION_SIZE, 17); + art->SetColour(wxAUI_DOCKART_ACTIVE_CAPTION_COLOUR, wxColour(49, 106, 197)); + art->SetColour(wxAUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR, wxColour(90, 135, 208)); + art->SetColour(wxAUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR, wxColour(255, 255, 255)); + art->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR, wxColour(200, 198, 183)); + art->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR, wxColour(228, 226, 209)); + art->SetColour(wxAUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR, wxColour(0, 0, 0)); + + mAuiManager->Update(); } void MaterialEditorFrame::createAuiNotebookPane() { - mAuiNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_DEFAULT_STYLE | wxNO_BORDER); + mAuiNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_DEFAULT_STYLE | wxNO_BORDER); - // Create EditorManager singleton - new EditorManager(mAuiNotebook); + // Create EditorManager singleton + new EditorManager(mAuiNotebook); - wxAuiPaneInfo info; + wxAuiPaneInfo info; - info.Floatable(false); - info.Movable(false); - info.CenterPane(); + info.Floatable(false); + info.Movable(false); + info.CenterPane(); - mAuiManager->AddPane(mAuiNotebook, info); + mAuiManager->AddPane(mAuiNotebook, info); } void MaterialEditorFrame::createManagementPane() { - mManagementNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxNO_BORDER); + mManagementNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxNO_BORDER); - mWorkspacePanel = new WorkspacePanel(mManagementNotebook); - //mMaterialTree = new wxTreeCtrl(mWorkspaceNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); - mManagementNotebook->AddPage(mWorkspacePanel, "Materials"); + mWorkspacePanel = new WorkspacePanel(mManagementNotebook); + //mMaterialTree = new wxTreeCtrl(mWorkspaceNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); + mManagementNotebook->AddPage(mWorkspacePanel, "Materials"); - mResourcePanel = new ResourcePanel(mManagementNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); - mManagementNotebook->AddPage(mResourcePanel, "Resources"); + mResourcePanel = new ResourcePanel(mManagementNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); + mManagementNotebook->AddPage(mResourcePanel, "Resources"); - wxAuiPaneInfo info; - info.Caption(wxT("Management")); - info.MaximizeButton(true); - info.BestSize(256, 512); - info.Left(); - info.Layer(1); + wxAuiPaneInfo info; + info.Caption(wxT("Management")); + info.MaximizeButton(true); + info.BestSize(256, 512); + info.Left(); + info.Layer(1); - mAuiManager->AddPane(mManagementNotebook, info); + mAuiManager->AddPane(mManagementNotebook, info); } void MaterialEditorFrame::createInformationPane() { - mInformationNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxNO_BORDER); + mInformationNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxNO_BORDER); - mLogPanel = new LogPanel(mInformationNotebook); - mInformationNotebook->AddPage(mLogPanel, "Log"); - mLogPanel->attachLog(Ogre::LogManager::getSingleton().getDefaultLog()); + mLogPanel = new LogPanel(mInformationNotebook); + mInformationNotebook->AddPage(mLogPanel, "Log"); + mLogPanel->attachLog(Ogre::LogManager::getSingleton().getDefaultLog()); - mDocPanel = new DocPanel(mInformationNotebook); - mInformationNotebook->AddPage(mDocPanel, "Documentation"); + mDocPanel = new DocPanel(mInformationNotebook); + mInformationNotebook->AddPage(mDocPanel, "Documentation"); - wxAuiPaneInfo info; - info.Caption(wxT("Information")); - info.MaximizeButton(true); - info.BestSize(256, 128); - info.Bottom(); + wxAuiPaneInfo info; + info.Caption(wxT("Information")); + info.MaximizeButton(true); + info.BestSize(256, 128); + info.Bottom(); - mAuiManager->AddPane(mInformationNotebook, info); + mAuiManager->AddPane(mInformationNotebook, info); } void MaterialEditorFrame::createPropertiesPane() { - mPropertiesPanel = new PropertiesPanel(this); + mPropertiesPanel = new PropertiesPanel(this); - wxAuiPaneInfo info; - info.Caption(wxT("Properties")); - info.MaximizeButton(true); - info.BestSize(256, 512); - info.Left(); - info.Layer(1); + wxAuiPaneInfo info; + info.Caption(wxT("Properties")); + info.MaximizeButton(true); + info.BestSize(256, 512); + info.Left(); + info.Layer(1); - mAuiManager->AddPane(mPropertiesPanel, info); + mAuiManager->AddPane(mPropertiesPanel, info); } void MaterialEditorFrame::createOgrePane() { - mRoot = new Ogre::Root(); - - // Find Render Systems - // Testing only, this will be deleted once Projects can tell us - // which rendering system they want used - mDirectXRenderSystem = NULL; - mOpenGLRenderSystem = NULL; - const RenderSystemList &rl = mRoot.getAvailableRenderers(); - if (rl->empty()) - { - wxMessageBox("No render systems found", "Error"); - return; - } - for(RenderSystemList::const_iterator it = rl.begin(); it != rl.end(); ++it) - { - Ogre::RenderSystem *rs = (*it); - rs->setConfigOption("Full Screen", "No"); - rs->setConfigOption("VSync", "No"); - rs->setConfigOption("Video Mode", "512 x 512 @ 32-bit"); - - if(rs->getName() == "OpenGL Rendering Subsystem") - mOpenGLRenderSystem = *it; - else if(rs->getName() == "Direct3D9 Rendering Subsystem") - mDirectXRenderSystem = *it; - } - - // We'll see if there is already and Ogre.cfg, if not we'll - // default to OpenGL since we know that will work on all - // platforms - if(!mRoot->restoreConfig()) - { - mRoot->setRenderSystem(mOpenGLRenderSystem); - } - - mOgreControl = new wxOgre(this); - - ConfigFile cf; - cf.load("resources.cfg"); - - ConfigFile::SectionIterator seci = cf.getSectionIterator(); - - Ogre::String secName, typeName, archName; - while(seci.hasMoreElements()) - { - secName = seci.peekNextKey(); - ConfigFile::SettingsMultiMap *settings = seci.getNext(); - ConfigFile::SettingsMultiMap::iterator i; - for(i = settings->begin(); i != settings->end(); ++i) - { - typeName = i->first; - archName = i->second; - Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName); - } - } - - Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); - - wxString caption; - String rs = mRoot->getRenderSystem()->getName(); - if(rs == "OpenGL Rendering Subsystem") caption = "OGRE - OpenGL"; - else caption = "OGRE - DirectX"; - - wxAuiPaneInfo info; - info.Caption(caption); - info.MaximizeButton(true); - info.MinimizeButton(true); - info.Floatable(true); - info.BestSize(512, 512); - info.Left(); - - mAuiManager->AddPane(mOgreControl, info); + mRoot = new Ogre::Root(); + + // Find Render Systems + // Testing only, this will be deleted once Projects can tell us + // which rendering system they want used + mDirectXRenderSystem = NULL; + mOpenGLRenderSystem = NULL; + const RenderSystemList &rl = mRoot.getAvailableRenderers(); + if (rl->empty()) + { + wxMessageBox("No render systems found", "Error"); + return; + } + for(RenderSystemList::const_iterator it = rl.begin(); it != rl.end(); ++it) + { + Ogre::RenderSystem *rs = (*it); + rs->setConfigOption("Full Screen", "No"); + rs->setConfigOption("VSync", "No"); + rs->setConfigOption("Video Mode", "512 x 512 @ 32-bit"); + + if(rs->getName() == "OpenGL Rendering Subsystem") + mOpenGLRenderSystem = *it; + else if(rs->getName() == "Direct3D9 Rendering Subsystem") + mDirectXRenderSystem = *it; + } + + // We'll see if there is already and Ogre.cfg, if not we'll + // default to OpenGL since we know that will work on all + // platforms + if(!mRoot->restoreConfig()) + { + mRoot->setRenderSystem(mOpenGLRenderSystem); + } + + mOgreControl = new wxOgre(this); + + ConfigFile cf; + cf.load("resources.cfg"); + + ConfigFile::SectionIterator seci = cf.getSectionIterator(); + + Ogre::String secName, typeName, archName; + while(seci.hasMoreElements()) + { + secName = seci.peekNextKey(); + ConfigFile::SettingsMultiMap *settings = seci.getNext(); + ConfigFile::SettingsMultiMap::iterator i; + for(i = settings->begin(); i != settings->end(); ++i) + { + typeName = i->first; + archName = i->second; + Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName); + } + } + + Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + + wxString caption; + String rs = mRoot->getRenderSystem()->getName(); + if(rs == "OpenGL Rendering Subsystem") caption = "OGRE - OpenGL"; + else caption = "OGRE - DirectX"; + + wxAuiPaneInfo info; + info.Caption(caption); + info.MaximizeButton(true); + info.MinimizeButton(true); + info.Floatable(true); + info.BestSize(512, 512); + info.Left(); + + mAuiManager->AddPane(mOgreControl, info); } void MaterialEditorFrame::createMenuBar() { - mMenuBar = new wxMenuBar(); + mMenuBar = new wxMenuBar(); - createFileMenu(); - createEditMenu(); - createViewMenu(); - createToolsMenu(); - createWindowMenu(); - createHelpMenu(); + createFileMenu(); + createEditMenu(); + createViewMenu(); + createToolsMenu(); + createWindowMenu(); + createHelpMenu(); - SetMenuBar(mMenuBar); + SetMenuBar(mMenuBar); } void MaterialEditorFrame::createFileMenu() -{ - mFileMenu = new wxMenu(); +{ + mFileMenu = new wxMenu(); - // New sub menu - wxMenu* newMenu = new wxMenu(); + // New sub menu + wxMenu* newMenu = new wxMenu(); - wxMenuItem *menuItem = new wxMenuItem(newMenu, ID_FILE_NEW_MENU_PROJECT, "&Project"); - menuItem->SetBitmap(IconManager::getSingleton().getIcon(IconManager::PROJECT_NEW)); - newMenu->Append(menuItem); + wxMenuItem *menuItem = new wxMenuItem(newMenu, ID_FILE_NEW_MENU_PROJECT, "&Project"); + menuItem->SetBitmap(IconManager::getSingleton().getIcon(IconManager::PROJECT_NEW)); + newMenu->Append(menuItem); - menuItem = new wxMenuItem(newMenu, ID_FILE_NEW_MENU_MATERIAL, "&Material"); - menuItem->SetBitmap(IconManager::getSingleton().getIcon(IconManager::MATERIAL)); - newMenu->Append(menuItem); + menuItem = new wxMenuItem(newMenu, ID_FILE_NEW_MENU_MATERIAL, "&Material"); + menuItem->SetBitmap(IconManager::getSingleton().getIcon(IconManager::MATERIAL)); + newMenu->Append(menuItem); - mFileMenu->AppendSubMenu(newMenu, wxT("&New")); + mFileMenu->AppendSubMenu(newMenu, wxT("&New")); - menuItem = new wxMenuItem(mFileMenu, ID_FILE_MENU_OPEN, "&Open"); - mFileMenu->Append(menuItem); + menuItem = new wxMenuItem(mFileMenu, ID_FILE_MENU_OPEN, "&Open"); + mFileMenu->Append(menuItem); - menuItem = new wxMenuItem(mFileMenu, ID_FILE_MENU_SAVE, "&Save"); - menuItem->SetBitmap(IconManager::getSingleton().getIcon(IconManager::SAVE)); - mFileMenu->Append(menuItem); + menuItem = new wxMenuItem(mFileMenu, ID_FILE_MENU_SAVE, "&Save"); + menuItem->SetBitmap(IconManager::getSingleton().getIcon(IconManager::SAVE)); + mFileMenu->Append(menuItem); - menuItem = new wxMenuItem(mFileMenu, ID_FILE_MENU_SAVE_AS, "Save &As..."); - menuItem->SetBitmap(IconManager::getSingleton().getIcon(IconManager::SAVE_AS)); - mFileMenu->Append(menuItem); + menuItem = new wxMenuItem(mFileMenu, ID_FILE_MENU_SAVE_AS, "Save &As..."); + menuItem->SetBitmap(IconManager::getSingleton().getIcon(IconManager::SAVE_AS)); + mFileMenu->Append(menuItem); - mFileMenu->AppendSeparator(); + mFileMenu->AppendSeparator(); - menuItem = new wxMenuItem(mFileMenu, ID_FILE_MENU_CLOSE, "&Close"); - menuItem->SetBitmap(IconManager::getSingleton().getIcon(IconManager::CLOSE)); - mFileMenu->Append(menuItem); + menuItem = new wxMenuItem(mFileMenu, ID_FILE_MENU_CLOSE, "&Close"); + menuItem->SetBitmap(IconManager::getSingleton().getIcon(IconManager::CLOSE)); + mFileMenu->Append(menuItem); - mFileMenu->AppendSeparator(); + mFileMenu->AppendSeparator(); - menuItem = new wxMenuItem(mFileMenu, ID_FILE_MENU_EXIT, "E&xit"); - mFileMenu->Append(menuItem); - mFileMenu->UpdateUI(); + menuItem = new wxMenuItem(mFileMenu, ID_FILE_MENU_EXIT, "E&xit"); + mFileMenu->Append(menuItem); + mFileMenu->UpdateUI(); - mMenuBar->Append(mFileMenu, wxT("&File")); + mMenuBar->Append(mFileMenu, wxT("&File")); } void MaterialEditorFrame::createEditMenu() { - mEditMenu = new wxMenu(""); - mEditMenu->Append(ID_EDIT_MENU_UNDO, wxT("Undo")); - mEditMenu->Append(ID_EDIT_MENU_REDO, wxT("Redo")); - mEditMenu->AppendSeparator(); - mEditMenu->Append(ID_EDIT_MENU_CUT, wxT("Cut")); - mEditMenu->Append(ID_EDIT_MENU_COPY, wxT("Copy")); - mEditMenu->Append(ID_EDIT_MENU_PASTE, wxT("Paste")); - - mMenuBar->Append(mEditMenu, wxT("&Edit")); + mEditMenu = new wxMenu(""); + mEditMenu->Append(ID_EDIT_MENU_UNDO, wxT("Undo")); + mEditMenu->Append(ID_EDIT_MENU_REDO, wxT("Redo")); + mEditMenu->AppendSeparator(); + mEditMenu->Append(ID_EDIT_MENU_CUT, wxT("Cut")); + mEditMenu->Append(ID_EDIT_MENU_COPY, wxT("Copy")); + mEditMenu->Append(ID_EDIT_MENU_PASTE, wxT("Paste")); + + mMenuBar->Append(mEditMenu, wxT("&Edit")); } void MaterialEditorFrame::createViewMenu() { - mViewMenu = new wxMenu(""); - mViewMenu->Append(ID_VIEW_MENU_OPENGL, wxT("OpenGL")); - mViewMenu->Append(ID_VIEW_MENU_DIRECTX, wxT("DirectX")); - mMenuBar->Append(mViewMenu, wxT("&View")); + mViewMenu = new wxMenu(""); + mViewMenu->Append(ID_VIEW_MENU_OPENGL, wxT("OpenGL")); + mViewMenu->Append(ID_VIEW_MENU_DIRECTX, wxT("DirectX")); + mMenuBar->Append(mViewMenu, wxT("&View")); } void MaterialEditorFrame::createToolsMenu() { - mToolsMenu = new wxMenu(""); - wxMenu* resourceMenu = new wxMenu(""); - resourceMenu->Append(ID_TOOLS_MENU_RESOURCES_MENU_ADD_GROUP, wxT("Add Group")); - resourceMenu->Append(ID_TOOLS_MENU_RESOURCES_MENU_REMOVE_GROUP, wxT("Remove Group")); - resourceMenu->Append(ID_TOOLS_MENU_RESOURCES_MENU_ADD, wxT("Add")); - resourceMenu->Append(ID_TOOLS_MENU_RESOURCES_MENU_REMOVE, wxT("Remove")); - mToolsMenu->AppendSubMenu(resourceMenu, wxT("Resources")); - mMenuBar->Append(mToolsMenu, wxT("&Tools")); + mToolsMenu = new wxMenu(""); + wxMenu* resourceMenu = new wxMenu(""); + resourceMenu->Append(ID_TOOLS_MENU_RESOURCES_MENU_ADD_GROUP, wxT("Add Group")); + resourceMenu->Append(ID_TOOLS_MENU_RESOURCES_MENU_REMOVE_GROUP, wxT("Remove Group")); + resourceMenu->Append(ID_TOOLS_MENU_RESOURCES_MENU_ADD, wxT("Add")); + resourceMenu->Append(ID_TOOLS_MENU_RESOURCES_MENU_REMOVE, wxT("Remove")); + mToolsMenu->AppendSubMenu(resourceMenu, wxT("Resources")); + mMenuBar->Append(mToolsMenu, wxT("&Tools")); } void MaterialEditorFrame::createWindowMenu() { - mWindowMenu = new wxMenu(""); - mMenuBar->Append(mWindowMenu, wxT("&Window")); + mWindowMenu = new wxMenu(""); + mMenuBar->Append(mWindowMenu, wxT("&Window")); } void MaterialEditorFrame::createHelpMenu() { - mHelpMenu = new wxMenu(""); - mMenuBar->Append(mHelpMenu, wxT("&Help")); + mHelpMenu = new wxMenu(""); + mMenuBar->Append(mHelpMenu, wxT("&Help")); } void MaterialEditorFrame::OnActivate(wxActivateEvent& event) { - //if(mOgreControl) mOgreControl->initOgre(); + //if(mOgreControl) mOgreControl->initOgre(); } void MaterialEditorFrame::OnActiveEditorChanged(EventArgs& args) { - EditorEventArgs eea = dynamic_cast(args); - Editor* editor = eea.getEditor(); + EditorEventArgs eea = dynamic_cast(args); + Editor* editor = eea.getEditor(); - // TODO: Update menu item enablement + // TODO: Update menu item enablement } void MaterialEditorFrame::OnNewProject(wxCommandEvent& event) { - //wxBitmap projectImage; - //projectImage.LoadFile("resources/images/new_project.gif", wxBITMAP_TYPE_GIF); + //wxBitmap projectImage; + //projectImage.LoadFile("resources/images/new_project.gif", wxBITMAP_TYPE_GIF); - ProjectWizard* wizard = new ProjectWizard(); - wizard->Create(this, wxID_ANY, wxT("New Project"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); - wizard->RunWizard(wizard->getProjectPage()); // This seems unnatural, seems there must be a better way to deal with wizards + ProjectWizard* wizard = new ProjectWizard(); + wizard->Create(this, wxID_ANY, wxT("New Project"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + wizard->RunWizard(wizard->getProjectPage()); // This seems unnatural, seems there must be a better way to deal with wizards - wizard->Destroy(); + wizard->Destroy(); } void MaterialEditorFrame::OnNewMaterial(wxCommandEvent& event) { - //wxBitmap materialImage; - //materialImage.LoadFile("resources/images/new_material.gif", wxBITMAP_TYPE_GIF); + //wxBitmap materialImage; + //materialImage.LoadFile("resources/images/new_material.gif", wxBITMAP_TYPE_GIF); - MaterialWizard* wizard = new MaterialWizard(); - wizard->Create(this, wxID_ANY, wxT("New Material"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); - wizard->RunWizard(wizard->getMaterialPage());// This seems unnatural, seems there must be a better way to deal with wizards + MaterialWizard* wizard = new MaterialWizard(); + wizard->Create(this, wxID_ANY, wxT("New Material"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + wizard->RunWizard(wizard->getMaterialPage());// This seems unnatural, seems there must be a better way to deal with wizards - wizard->Destroy(); + wizard->Destroy(); } void MaterialEditorFrame::OnFileOpen(wxCommandEvent& event) { - wxFileDialog * openDialog = new wxFileDialog(this, wxT("Choose a file to open"), wxEmptyString, wxEmptyString, - wxT("All Ogre Files (*.material;*.mesh;*.program;*.cg;*.vert;*.frag)|*.material;*.mesh;*.program;*.cg;*.vert;*.frag|Material Files (*.material)|*.material|Mesh Files (*.mesh)|*.mesh|Program Files (*.program)|*.program|Cg Files (*.cg)|*.cg|GLSL Files(*.vert; *.frag)|*.vert;*.frag|All Files (*.*)|*.*")); - - if(openDialog->ShowModal() == wxID_OK) - { - wxString path = openDialog->GetPath(); - if(path.EndsWith(wxT(".material")) || path.EndsWith(wxT(".program"))) - { - MaterialScriptEditor* editor = new MaterialScriptEditor(EditorManager::getSingletonPtr()->getEditorNotebook()); - editor->loadFile(path); - int index = (int)path.find_last_of('\\'); - if(index == -1) index = (int)path.find_last_of('/'); - editor->setName((index != -1) ? path.substr(index + 1, path.Length()) : path); - - EditorManager::getSingletonPtr()->openEditor(editor); - } - else if(path.EndsWith(wxT(".cg"))) - { - CgEditor* editor = new CgEditor(EditorManager::getSingletonPtr()->getEditorNotebook()); - editor->loadFile(path); - int index = (int)path.find_last_of('\\'); - if(index == -1) index = (int)path.find_last_of('/'); - editor->setName((index != -1) ? path.substr(index + 1, path.Length()) : path); - - EditorManager::getSingletonPtr()->openEditor(editor); - } - else if(path.EndsWith(wxT(".mesh"))) - { - Ogre::SceneManager *sceneMgr = wxOgre::getSingleton().getSceneManager(); - Ogre::Camera *camera = wxOgre::getSingleton().getCamera(); - - if(mEntity) - { - sceneMgr->getRootSceneNode()->detachObject(mEntity); - sceneMgr->destroyEntity(mEntity); - mEntity = 0; - } - - static int meshNumber = 0; - Ogre::String meshName = Ogre::String("Mesh") + Ogre::StringConverter::toString(meshNumber++); - - int index = (int)path.find_last_of('\\'); - if(index == -1) index = (int)path.find_last_of('/'); - wxString mesh = (index != -1) ? path.substr(index + 1, path.Length()) : path; - - mEntity = sceneMgr->createEntity(meshName, mesh.GetData()); - sceneMgr->getRootSceneNode()->attachObject(mEntity); - - Ogre::AxisAlignedBox box = mEntity->getBoundingBox(); - Ogre::Vector3 minPoint = box.getMinimum(); - Ogre::Vector3 maxPoint = box.getMaximum(); - Ogre::Vector3 size = box.getSize(); - - wxOgre::getSingleton().setZoomScale(max(size.x, max(size.y, size.z))); - wxOgre::getSingleton().resetCamera(); - - Ogre::Vector3 camPos; - camPos.x = minPoint.x + (size.x / 2.0); - camPos.y = minPoint.y + (size.y / 2.0); - Ogre::Real width = max(size.x, size.y); - camPos.z = (width / tan(camera->getFOVy().valueRadians())) + size.z / 2; - - wxOgre::getSingleton().getCamera()->setPosition(camPos); - wxOgre::getSingleton().getCamera()->lookAt(0,0,0); - - wxOgre::getSingleton().getLight()->setPosition(maxPoint * 2); - } - } + wxFileDialog * openDialog = new wxFileDialog(this, wxT("Choose a file to open"), wxEmptyString, wxEmptyString, + wxT("All Ogre Files (*.material;*.mesh;*.program;*.cg;*.vert;*.frag)|*.material;*.mesh;*.program;*.cg;*.vert;*.frag|Material Files (*.material)|*.material|Mesh Files (*.mesh)|*.mesh|Program Files (*.program)|*.program|Cg Files (*.cg)|*.cg|GLSL Files(*.vert; *.frag)|*.vert;*.frag|All Files (*.*)|*.*")); + + if(openDialog->ShowModal() == wxID_OK) + { + wxString path = openDialog->GetPath(); + if(path.EndsWith(wxT(".material")) || path.EndsWith(wxT(".program"))) + { + MaterialScriptEditor* editor = new MaterialScriptEditor(EditorManager::getSingletonPtr()->getEditorNotebook()); + editor->loadFile(path); + int index = (int)path.find_last_of('\\'); + if(index == -1) index = (int)path.find_last_of('/'); + editor->setName((index != -1) ? path.substr(index + 1, path.Length()) : path); + + EditorManager::getSingletonPtr()->openEditor(editor); + } + else if(path.EndsWith(wxT(".cg"))) + { + CgEditor* editor = new CgEditor(EditorManager::getSingletonPtr()->getEditorNotebook()); + editor->loadFile(path); + int index = (int)path.find_last_of('\\'); + if(index == -1) index = (int)path.find_last_of('/'); + editor->setName((index != -1) ? path.substr(index + 1, path.Length()) : path); + + EditorManager::getSingletonPtr()->openEditor(editor); + } + else if(path.EndsWith(wxT(".mesh"))) + { + Ogre::SceneManager *sceneMgr = wxOgre::getSingleton().getSceneManager(); + Ogre::Camera *camera = wxOgre::getSingleton().getCamera(); + + if(mEntity) + { + sceneMgr->getRootSceneNode()->detachObject(mEntity); + sceneMgr->destroyEntity(mEntity); + mEntity = 0; + } + + static int meshNumber = 0; + Ogre::String meshName = Ogre::String("Mesh") + Ogre::StringConverter::toString(meshNumber++); + + int index = (int)path.find_last_of('\\'); + if(index == -1) index = (int)path.find_last_of('/'); + wxString mesh = (index != -1) ? path.substr(index + 1, path.Length()) : path; + + mEntity = sceneMgr->createEntity(meshName, mesh.GetData()); + sceneMgr->getRootSceneNode()->attachObject(mEntity); + + Ogre::AxisAlignedBox box = mEntity->getBoundingBox(); + Ogre::Vector3 minPoint = box.getMinimum(); + Ogre::Vector3 maxPoint = box.getMaximum(); + Ogre::Vector3 size = box.getSize(); + + wxOgre::getSingleton().setZoomScale(max(size.x, max(size.y, size.z))); + wxOgre::getSingleton().resetCamera(); + + Ogre::Vector3 camPos; + camPos.x = minPoint.x + (size.x / 2.0); + camPos.y = minPoint.y + (size.y / 2.0); + Ogre::Real width = max(size.x, size.y); + camPos.z = (width / tan(camera->getFOVy().valueRadians())) + size.z / 2; + + wxOgre::getSingleton().getCamera()->setPosition(camPos); + wxOgre::getSingleton().getCamera()->lookAt(0,0,0); + + wxOgre::getSingleton().getLight()->setPosition(maxPoint * 2); + } + } } void MaterialEditorFrame::OnFileSave(wxCommandEvent& event) { - Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); - if(editor != NULL) editor->save(); + Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); + if(editor != NULL) editor->save(); - // TODO: Support project & workspace save + // TODO: Support project & workspace save } void MaterialEditorFrame::OnFileSaveAs(wxCommandEvent& event) { - Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); - if(editor != NULL) editor->saveAs(); + Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); + if(editor != NULL) editor->saveAs(); - // TODO: Support project & workspace saveAs + // TODO: Support project & workspace saveAs } void MaterialEditorFrame::OnFileClose(wxCommandEvent& event) @@ -573,88 +573,88 @@ void MaterialEditorFrame::OnFileClose(wxCommandEvent& event) void MaterialEditorFrame::OnFileExit(wxCommandEvent& event) { - Close(); + Close(); } void MaterialEditorFrame::OnEditUndo(wxCommandEvent& event) { - Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); - if(editor != NULL) editor->undo(); + Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); + if(editor != NULL) editor->undo(); } void MaterialEditorFrame::OnEditRedo(wxCommandEvent& event) { - Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); - if(editor != NULL) editor->redo(); + Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); + if(editor != NULL) editor->redo(); } void MaterialEditorFrame::OnEditCut(wxCommandEvent& event) { - Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); - if(editor != NULL) editor->cut(); + Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); + if(editor != NULL) editor->cut(); } void MaterialEditorFrame::OnEditCopy(wxCommandEvent& event) { - Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); - if(editor != NULL) editor->copy(); + Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); + if(editor != NULL) editor->copy(); } void MaterialEditorFrame::OnEditPaste(wxCommandEvent& event) { - Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); - if(editor != NULL) editor->paste(); + Editor* editor = EditorManager::getSingletonPtr()->getActiveEditor(); + if(editor != NULL) editor->paste(); } void MaterialEditorFrame::OnViewOpenGL(wxCommandEvent& event) { - //if(mOpenGLRenderSystem == NULL) - //{ - // wxMessageBox("OpenGL Render System not found", "Error"); - // return; - //} + //if(mOpenGLRenderSystem == NULL) + //{ + // wxMessageBox("OpenGL Render System not found", "Error"); + // return; + //} - //mOgreControl->SetRenderSystem(mOpenGLRenderSystem); + //mOgreControl->SetRenderSystem(mOpenGLRenderSystem); - //wxAuiPaneInfo info = mAuiManager->GetPane(mOgreControl); - //if(!info.IsOk()) - //{ - // info.MaximizeButton(true); - // info.MinimizeButton(true); - // info.Float(); + //wxAuiPaneInfo info = mAuiManager->GetPane(mOgreControl); + //if(!info.IsOk()) + //{ + // info.MaximizeButton(true); + // info.MinimizeButton(true); + // info.Float(); - // mAuiManager->AddPane(mOgreControl, info); - //} + // mAuiManager->AddPane(mOgreControl, info); + //} - //info.Caption(wxT("OGRE - OpenGL")); + //info.Caption(wxT("OGRE - OpenGL")); - //mAuiManager->Update(); + //mAuiManager->Update(); } void MaterialEditorFrame::OnViewDirectX(wxCommandEvent& event) { - /* - if(mDirectXRenderSystem == NULL) - { - wxMessageBox("DirectX Render System not found", "Error"); - return; - } + /* + if(mDirectXRenderSystem == NULL) + { + wxMessageBox("DirectX Render System not found", "Error"); + return; + } - mOgreControl->SetRenderSystem(mDirectXRenderSystem); + mOgreControl->SetRenderSystem(mDirectXRenderSystem); - wxAuiPaneInfo info = mAuiManager->GetPane(mOgreControl); - if(!info.IsOk()) - { - info.MaximizeButton(true); - info.MinimizeButton(true); - info.Float(); + wxAuiPaneInfo info = mAuiManager->GetPane(mOgreControl); + if(!info.IsOk()) + { + info.MaximizeButton(true); + info.MinimizeButton(true); + info.Float(); - mAuiManager->AddPane(mOgreControl, info); - } + mAuiManager->AddPane(mOgreControl, info); + } - info.Caption(wxT("OGRE - DirectX")); + info.Caption(wxT("OGRE - DirectX")); - mAuiManager->Update(); - */ + mAuiManager->Update(); + */ } diff --git a/Tools/MaterialEditor/MaterialEditor/src/MaterialEventArgs.cpp b/Tools/MaterialEditor/MaterialEditor/src/MaterialEventArgs.cpp index 2373c49c9aa..df2dd6122f7 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/MaterialEventArgs.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/MaterialEventArgs.cpp @@ -42,10 +42,10 @@ MaterialEventArgs::MaterialEventArgs(MaterialController* mc, TechniqueController MaterialController* MaterialEventArgs::getMaterialController() const { - return mMaterialController; + return mMaterialController; } TechniqueController* MaterialEventArgs::getTechniqueController() const { - return mTechniqueController; + return mTechniqueController; } diff --git a/Tools/MaterialEditor/MaterialEditor/src/MaterialPage.cpp b/Tools/MaterialEditor/MaterialEditor/src/MaterialPage.cpp index fb3f0839c9b..21cfbcec7db 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/MaterialPage.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/MaterialPage.cpp @@ -43,7 +43,7 @@ END_EVENT_TABLE() MaterialPage::MaterialPage(wxWizard* parent) : wxWizardPageSimple(parent) { - createPage(); + createPage(); } MaterialPage::~MaterialPage() @@ -52,49 +52,49 @@ MaterialPage::~MaterialPage() void MaterialPage::createPage() { - mSizer = new wxBoxSizer(wxVERTICAL); - - // Project Label - mProjectLabel = new wxStaticText(this, wxID_ANY, wxT("Project:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mProjectLabel, 0, wxALL, 5); - - // Project Combo Box - wxArrayString projectNames; - const ProjectList* projects = Workspace::getSingletonPtr()->getProjects(); - for(ProjectList::const_iterator it = projects->begin(); it != projects->end(); ++it) - projectNames.Add((*it)->getName().c_str()); - - // TODO: Select first Project - mProjectComboBox = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, projectNames, wxCB_DROPDOWN); - mProjectComboBox->SetEditable(false); - mSizer->Add(mProjectComboBox, 0, wxALL | wxEXPAND, 5); - - // Name Label - mNameLabel = new wxStaticText(this, wxID_ANY, wxT("Name:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mNameLabel, 0, wxALL, 5); - - // Name Text - mNameText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); - mSizer->Add(mNameText, 0, wxALL | wxEXPAND, 5); - - SetSizer(mSizer); - Layout(); + mSizer = new wxBoxSizer(wxVERTICAL); + + // Project Label + mProjectLabel = new wxStaticText(this, wxID_ANY, wxT("Project:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mProjectLabel, 0, wxALL, 5); + + // Project Combo Box + wxArrayString projectNames; + const ProjectList* projects = Workspace::getSingletonPtr()->getProjects(); + for(ProjectList::const_iterator it = projects->begin(); it != projects->end(); ++it) + projectNames.Add((*it)->getName().c_str()); + + // TODO: Select first Project + mProjectComboBox = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, projectNames, wxCB_DROPDOWN); + mProjectComboBox->SetEditable(false); + mSizer->Add(mProjectComboBox, 0, wxALL | wxEXPAND, 5); + + // Name Label + mNameLabel = new wxStaticText(this, wxID_ANY, wxT("Name:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mNameLabel, 0, wxALL, 5); + + // Name Text + mNameText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); + mSizer->Add(mNameText, 0, wxALL | wxEXPAND, 5); + + SetSizer(mSizer); + Layout(); } void MaterialPage::getName(wxString& name) const { - name = mNameText->GetValue(); + name = mNameText->GetValue(); } Project* MaterialPage::getProject() const { - wxString project = mProjectComboBox->GetValue(); + wxString project = mProjectComboBox->GetValue(); - return Workspace::getSingletonPtr()->getProject(project.c_str()); + return Workspace::getSingletonPtr()->getProject(project.c_str()); } void MaterialPage::setProject(Project* project) { - mProjectComboBox->SetValue(project != NULL ? project->getName().c_str() : wxEmptyString); + mProjectComboBox->SetValue(project != NULL ? project->getName().c_str() : wxEmptyString); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/MaterialPropertyGridPage.cpp b/Tools/MaterialEditor/MaterialEditor/src/MaterialPropertyGridPage.cpp index e951ffafc09..8a3066c6470 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/MaterialPropertyGridPage.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/MaterialPropertyGridPage.cpp @@ -32,13 +32,13 @@ THE SOFTWARE #include "MaterialController.h" BEGIN_EVENT_TABLE(MaterialPropertyGridPage, wxPropertyGridPage) - EVT_PG_CHANGED(-1, MaterialPropertyGridPage::propertyChange) + EVT_PG_CHANGED(-1, MaterialPropertyGridPage::propertyChange) END_EVENT_TABLE() MaterialPropertyGridPage::MaterialPropertyGridPage(MaterialController* controller) : mController(controller) { - + } MaterialPropertyGridPage::~MaterialPropertyGridPage() @@ -47,24 +47,24 @@ MaterialPropertyGridPage::~MaterialPropertyGridPage() void MaterialPropertyGridPage::populate() { - mPropertyNameId = Append(wxStringProperty(wxT("Name"), wxPG_LABEL, mController->getMaterial()->getName())); - mPropertyReceiveShadowsId = Append(wxBoolProperty(wxT("Receive Shadows"), wxPG_LABEL, mController->getMaterial()->getReceiveShadows())); - mPropertyTransparencyCastsShadowsId = Append(wxBoolProperty(wxT("Transparency Casts Shadows"), wxPG_LABEL, mController->getMaterial()->getTransparencyCastsShadows())); + mPropertyNameId = Append(wxStringProperty(wxT("Name"), wxPG_LABEL, mController->getMaterial()->getName())); + mPropertyReceiveShadowsId = Append(wxBoolProperty(wxT("Receive Shadows"), wxPG_LABEL, mController->getMaterial()->getReceiveShadows())); + mPropertyTransparencyCastsShadowsId = Append(wxBoolProperty(wxT("Transparency Casts Shadows"), wxPG_LABEL, mController->getMaterial()->getTransparencyCastsShadows())); } void MaterialPropertyGridPage::propertyChange(wxPropertyGridEvent& event) { - wxPGId id = event.GetProperty(); - if(id == mPropertyNameId) - { - - } - else if(id == mPropertyReceiveShadowsId) - { - mController->setReceiveShadows(event.GetPropertyValueAsBool()); - } - else if(id == mPropertyTransparencyCastsShadowsId) - { - mController->setTransparencyCastsShadows(event.GetPropertyValueAsBool()); - } + wxPGId id = event.GetProperty(); + if(id == mPropertyNameId) + { + + } + else if(id == mPropertyReceiveShadowsId) + { + mController->setReceiveShadows(event.GetPropertyValueAsBool()); + } + else if(id == mPropertyTransparencyCastsShadowsId) + { + mController->setTransparencyCastsShadows(event.GetPropertyValueAsBool()); + } } diff --git a/Tools/MaterialEditor/MaterialEditor/src/MaterialScriptEditor.cpp b/Tools/MaterialEditor/MaterialEditor/src/MaterialScriptEditor.cpp index e6e8e72aea4..759f9b0ef35 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/MaterialScriptEditor.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/MaterialScriptEditor.cpp @@ -28,17 +28,17 @@ THE SOFTWARE. #include "MaterialScriptEditor.h" BEGIN_EVENT_TABLE(MaterialScriptEditor, ScintillaEditor) - // Scintilla - EVT_SCI_CHARADDED(-1, MaterialScriptEditor::OnCharAdded) + // Scintilla + EVT_SCI_CHARADDED(-1, MaterialScriptEditor::OnCharAdded) END_EVENT_TABLE() MaterialScriptEditor::MaterialScriptEditor(wxWindow* parent, wxWindowID id /*= -1*/, - const wxPoint& pos /*= wxDefaultPosition*/, - const wxSize& size /*= wxDefaultSize*/, - long style /*= wxVSCROLL*/ - ) : ScintillaEditor(parent, id, pos, size, style) + const wxPoint& pos /*= wxDefaultPosition*/, + const wxSize& size /*= wxDefaultSize*/, + long style /*= wxVSCROLL*/ + ) : ScintillaEditor(parent, id, pos, size, style) { - initialize(); + initialize(); } MaterialScriptEditor::~MaterialScriptEditor() @@ -47,67 +47,67 @@ MaterialScriptEditor::~MaterialScriptEditor() void MaterialScriptEditor::initialize() { - //StyleClearAll(); - SetLexer(wxSCI_LEX_OMS); - - // Load keywords - wxString path = wxT("../lexers/oms/keywords"); - loadKeywords(path); - - // Load call tips - path = wxT("../lexers/oms/calltips"); - getCallTipManager().load(path); - wxChar trigger(' '); - getCallTipManager().addTrigger(trigger); - - // Load docs - path = wxT("../lexers/oms/docs"); - getDocManager().load(path); - - // Set styles - StyleSetForeground(wxSCI_OMS_DEFAULT, wxColour(0, 0, 0)); - StyleSetFontAttr(wxSCI_OMS_DEFAULT, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_OMS_COMMENT, wxColour(0, 128, 0)); - StyleSetFontAttr(wxSCI_OMS_COMMENT, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_OMS_PRIMARY, wxColour(0, 0, 255)); - StyleSetFontAttr(wxSCI_OMS_PRIMARY, 10, "Courier New", true, false, false); - StyleSetForeground(wxSCI_OMS_ATTRIBUTE, wxColour(136, 0, 0)); - StyleSetFontAttr(wxSCI_OMS_ATTRIBUTE, 10, "Courier New", true, false, false); - StyleSetForeground(wxSCI_OMS_VALUE, wxColour(160, 0, 160)); - StyleSetFontAttr(wxSCI_OMS_VALUE, 10, "Courier New", false, false, false); - StyleSetForeground(wxSCI_OMS_NUMBER, wxColour(0, 0, 128)); - StyleSetFontAttr(wxSCI_OMS_NUMBER, 10, "Courier New", false, false, false); + //StyleClearAll(); + SetLexer(wxSCI_LEX_OMS); + + // Load keywords + wxString path = wxT("../lexers/oms/keywords"); + loadKeywords(path); + + // Load call tips + path = wxT("../lexers/oms/calltips"); + getCallTipManager().load(path); + wxChar trigger(' '); + getCallTipManager().addTrigger(trigger); + + // Load docs + path = wxT("../lexers/oms/docs"); + getDocManager().load(path); + + // Set styles + StyleSetForeground(wxSCI_OMS_DEFAULT, wxColour(0, 0, 0)); + StyleSetFontAttr(wxSCI_OMS_DEFAULT, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_OMS_COMMENT, wxColour(0, 128, 0)); + StyleSetFontAttr(wxSCI_OMS_COMMENT, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_OMS_PRIMARY, wxColour(0, 0, 255)); + StyleSetFontAttr(wxSCI_OMS_PRIMARY, 10, "Courier New", true, false, false); + StyleSetForeground(wxSCI_OMS_ATTRIBUTE, wxColour(136, 0, 0)); + StyleSetFontAttr(wxSCI_OMS_ATTRIBUTE, 10, "Courier New", true, false, false); + StyleSetForeground(wxSCI_OMS_VALUE, wxColour(160, 0, 160)); + StyleSetFontAttr(wxSCI_OMS_VALUE, 10, "Courier New", false, false, false); + StyleSetForeground(wxSCI_OMS_NUMBER, wxColour(0, 0, 128)); + StyleSetFontAttr(wxSCI_OMS_NUMBER, 10, "Courier New", false, false, false); } void MaterialScriptEditor::OnCharAdded(wxScintillaEvent &event) { - ScintillaEditor::OnCharAdded(event); - - char ch = event.GetKey(); - if(getCallTipManager().isTrigger(ch)) - { - int lineNum = GetCurrentLine(); - if(lineNum != -1) - { - wxString line = GetLine(lineNum); - int pos = GetCurrentPos() - 1; - - wxString word(""); - wxChar ch; - while(pos) - { - ch = GetCharAt(--pos); - if(ch != ' ' && ch != '\n' && ch != '\r' && ch != '\t' && ch != '{' && ch != '}') word.Prepend(ch); - else break; - } - - wxString* tips = getCallTipManager().find(word); - if(tips != NULL) - { - CallTipShow(pos, *tips); - } - } - } + ScintillaEditor::OnCharAdded(event); + + char ch = event.GetKey(); + if(getCallTipManager().isTrigger(ch)) + { + int lineNum = GetCurrentLine(); + if(lineNum != -1) + { + wxString line = GetLine(lineNum); + int pos = GetCurrentPos() - 1; + + wxString word(""); + wxChar ch; + while(pos) + { + ch = GetCharAt(--pos); + if(ch != ' ' && ch != '\n' && ch != '\r' && ch != '\t' && ch != '{' && ch != '}') word.Prepend(ch); + else break; + } + + wxString* tips = getCallTipManager().find(word); + if(tips != NULL) + { + CallTipShow(pos, *tips); + } + } + } } diff --git a/Tools/MaterialEditor/MaterialEditor/src/MaterialWizard.cpp b/Tools/MaterialEditor/MaterialEditor/src/MaterialWizard.cpp index 7a2bc2fcee3..04773f9371d 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/MaterialWizard.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/MaterialWizard.cpp @@ -34,7 +34,7 @@ THE SOFTWARE #include "Workspace.h" BEGIN_EVENT_TABLE(MaterialWizard, wxWizard) - EVT_WIZARD_FINISHED(wxID_ANY, MaterialWizard::OnFinish) + EVT_WIZARD_FINISHED(wxID_ANY, MaterialWizard::OnFinish) END_EVENT_TABLE() MaterialWizard::MaterialWizard() @@ -47,26 +47,26 @@ MaterialWizard::~MaterialWizard() bool MaterialWizard::Create(wxWindow* parent, int id /* = -1 */, const wxString& title /* = wxEmptyString */, const wxBitmap& bitmap /* = wxNullBitmap */, const wxPoint& pos /* = wxDefaultPosition */, long style /* = wxDEFAULT_DIALOG_STYLE */) { - bool result = wxWizard::Create(parent, id, title, bitmap, pos, style); + bool result = wxWizard::Create(parent, id, title, bitmap, pos, style); - mMaterialPage = new MaterialPage(this); + mMaterialPage = new MaterialPage(this); - GetPageAreaSizer()->Add(mMaterialPage); + GetPageAreaSizer()->Add(mMaterialPage); - return result; + return result; } MaterialPage* MaterialWizard::getMaterialPage() const { - return mMaterialPage; + return mMaterialPage; } void MaterialWizard::OnFinish(wxWizardEvent& event) { - Project* project = mMaterialPage->getProject(); + Project* project = mMaterialPage->getProject(); - wxString name; - mMaterialPage->getName(name); + wxString name; + mMaterialPage->getName(name); - project->createMaterial(name.c_str()); + project->createMaterial(name.c_str()); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/PassController.cpp b/Tools/MaterialEditor/MaterialEditor/src/PassController.cpp index 6b1653b50cf..3950d85a5e9 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/PassController.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/PassController.cpp @@ -35,13 +35,13 @@ THE SOFTWARE. PassController::PassController(Pass* pass) : mParentController(NULL), mPass(pass) { - registerEvents(); + registerEvents(); } PassController::PassController(TechniqueController* parent, Pass* pass) : mParentController(parent), mPass(pass) { - registerEvents(); + registerEvents(); } PassController::~PassController() @@ -50,382 +50,382 @@ PassController::~PassController() void PassController::registerEvents() { - registerEvent(NameChanged); - registerEvent(AmbientChanged); - registerEvent(DiffuseChanged); - registerEvent(SpecularChanged); - registerEvent(ShininessChanged); - registerEvent(SelfIllumChanged); - registerEvent(VertexColourTrackingChanged); - registerEvent(PointSizeChanged); - registerEvent(PointSpritesChanged); - registerEvent(PointAttenuationChanged); - registerEvent(PointMinSizeChanged); - registerEvent(PointMaxSizeChanged); - registerEvent(SceneBlendingTypeChanged); - registerEvent(SceneBlendSrcFactorChanged); - registerEvent(SceneBlendDestFactorChanged); - registerEvent(DepthCheckChanged); - registerEvent(DepthWriteChanged); - registerEvent(DepthFunctionChanged); - registerEvent(ColourWriteChanged); - registerEvent(CullingModeChanged); - registerEvent(ManualCullingModeChanged); - registerEvent(LightingChanged); - registerEvent(MaxLightsChanged); - registerEvent(StartLightChanged); - registerEvent(ShadingModeChanged); - registerEvent(PolygonModeChanged); - registerEvent(FogChanged); - registerEvent(DepthBiasChanged); - registerEvent(AlphaRejectionChanged); - registerEvent(IteratePerLightChanged); - registerEvent(LightCountPerIterationChanged); + registerEvent(NameChanged); + registerEvent(AmbientChanged); + registerEvent(DiffuseChanged); + registerEvent(SpecularChanged); + registerEvent(ShininessChanged); + registerEvent(SelfIllumChanged); + registerEvent(VertexColourTrackingChanged); + registerEvent(PointSizeChanged); + registerEvent(PointSpritesChanged); + registerEvent(PointAttenuationChanged); + registerEvent(PointMinSizeChanged); + registerEvent(PointMaxSizeChanged); + registerEvent(SceneBlendingTypeChanged); + registerEvent(SceneBlendSrcFactorChanged); + registerEvent(SceneBlendDestFactorChanged); + registerEvent(DepthCheckChanged); + registerEvent(DepthWriteChanged); + registerEvent(DepthFunctionChanged); + registerEvent(ColourWriteChanged); + registerEvent(CullingModeChanged); + registerEvent(ManualCullingModeChanged); + registerEvent(LightingChanged); + registerEvent(MaxLightsChanged); + registerEvent(StartLightChanged); + registerEvent(ShadingModeChanged); + registerEvent(PolygonModeChanged); + registerEvent(FogChanged); + registerEvent(DepthBiasChanged); + registerEvent(AlphaRejectionChanged); + registerEvent(IteratePerLightChanged); + registerEvent(LightCountPerIterationChanged); } TechniqueController* PassController::getParentController() const { - return mParentController; + return mParentController; } Pass* PassController::getPass() const { - return mPass; + return mPass; } void PassController::setName(const String& name) { - mPass->setName(name); + mPass->setName(name); - fireEvent(NameChanged, PassEventArgs(this)); + fireEvent(NameChanged, PassEventArgs(this)); } void PassController::setAmbient(Real red, Real green, Real blue) { - mPass->setAmbient(red, green, blue); + mPass->setAmbient(red, green, blue); - fireEvent(AmbientChanged, PassEventArgs(this)); + fireEvent(AmbientChanged, PassEventArgs(this)); } void PassController::setAmbient(const ColourValue& ambient) { - mPass->setAmbient(ambient); + mPass->setAmbient(ambient); - fireEvent(AmbientChanged, PassEventArgs(this)); + fireEvent(AmbientChanged, PassEventArgs(this)); } void PassController::setDiffuse(Real red, Real green, Real blue, Real alpha) { - mPass->setDiffuse(red, green, blue, alpha); + mPass->setDiffuse(red, green, blue, alpha); - fireEvent(DiffuseChanged, PassEventArgs(this)); + fireEvent(DiffuseChanged, PassEventArgs(this)); } void PassController::setDiffuse(const ColourValue &diffuse) { - mPass->setDiffuse(diffuse); + mPass->setDiffuse(diffuse); - fireEvent(DiffuseChanged, PassEventArgs(this)); + fireEvent(DiffuseChanged, PassEventArgs(this)); } void PassController::setSpecular(Real red, Real green, Real blue, Real alpha) { - mPass->setSpecular(red, green, blue, alpha); + mPass->setSpecular(red, green, blue, alpha); - fireEvent(SpecularChanged, PassEventArgs(this)); + fireEvent(SpecularChanged, PassEventArgs(this)); } void PassController::setSpecular(const ColourValue &specular) { - mPass->setSpecular(specular); + mPass->setSpecular(specular); - fireEvent(SpecularChanged, PassEventArgs(this)); + fireEvent(SpecularChanged, PassEventArgs(this)); } void PassController::setShininess(Real val) { - mPass->setShininess(val); + mPass->setShininess(val); - fireEvent(ShininessChanged, PassEventArgs(this)); + fireEvent(ShininessChanged, PassEventArgs(this)); } void PassController::setSelfIllumination(Real red, Real green, Real blue) { - mPass->setSelfIllumination(red, green, blue); + mPass->setSelfIllumination(red, green, blue); - fireEvent(SelfIllumChanged, PassEventArgs(this)); + fireEvent(SelfIllumChanged, PassEventArgs(this)); } void PassController::setSelfIllumination(const ColourValue& selfIllum) { - mPass->setSelfIllumination(selfIllum); + mPass->setSelfIllumination(selfIllum); - fireEvent(SelfIllumChanged, PassEventArgs(this)); + fireEvent(SelfIllumChanged, PassEventArgs(this)); } void PassController::setVertexColourTracking(TrackVertexColourType tracking) { - mPass->setVertexColourTracking(tracking); + mPass->setVertexColourTracking(tracking); - fireEvent(VertexColourTrackingChanged, PassEventArgs(this)); + fireEvent(VertexColourTrackingChanged, PassEventArgs(this)); } void PassController::setPointSize(Real ps) { - mPass->setPointSize(ps); + mPass->setPointSize(ps); - fireEvent(PointSizeChanged, PassEventArgs(this)); + fireEvent(PointSizeChanged, PassEventArgs(this)); } void PassController::setPointSpritesEnabled(bool enabled) { - mPass->setPointSpritesEnabled(enabled); + mPass->setPointSpritesEnabled(enabled); - fireEvent(PointSpritesChanged, PassEventArgs(this)); + fireEvent(PointSpritesChanged, PassEventArgs(this)); } void PassController::setPointAttenuation(bool enabled, Real constant /* =0.0f */, Real linear /* =1.0f */, Real quadratic /* =0.0f */) { - mPass->setPointAttenuation(enabled, constant, linear, quadratic); + mPass->setPointAttenuation(enabled, constant, linear, quadratic); - fireEvent(PointAttenuationChanged, PassEventArgs(this)); + fireEvent(PointAttenuationChanged, PassEventArgs(this)); } void PassController::setPointMinSize(Real min) { - mPass->setPointMinSize(min); + mPass->setPointMinSize(min); - fireEvent(PointMinSizeChanged, PassEventArgs(this)); + fireEvent(PointMinSizeChanged, PassEventArgs(this)); } void PassController::setPointMaxSize(Real max) { - mPass->setPointMaxSize(max); + mPass->setPointMaxSize(max); - fireEvent(PointMaxSizeChanged, PassEventArgs(this)); + fireEvent(PointMaxSizeChanged, PassEventArgs(this)); } void PassController::setSceneBlending(const SceneBlendType sbt) { - mPass->setSceneBlending(sbt); + mPass->setSceneBlending(sbt); - fireEvent(SceneBlendingTypeChanged, PassEventArgs(this)); + fireEvent(SceneBlendingTypeChanged, PassEventArgs(this)); } void PassController::setSceneBlending(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor) { - mPass->setSceneBlending(sourceFactor, destFactor); + mPass->setSceneBlending(sourceFactor, destFactor); - fireEvent(SceneBlendSrcFactorChanged, PassEventArgs(this)); + fireEvent(SceneBlendSrcFactorChanged, PassEventArgs(this)); } void PassController::setDepthCheckEnabled(bool enabled) { - mPass->setDepthCheckEnabled(enabled); + mPass->setDepthCheckEnabled(enabled); - fireEvent(DepthCheckChanged, PassEventArgs(this)); + fireEvent(DepthCheckChanged, PassEventArgs(this)); } void PassController::setDepthWriteEnabled(bool enabled) { - mPass->setDepthWriteEnabled(enabled); + mPass->setDepthWriteEnabled(enabled); - fireEvent(DepthWriteChanged, PassEventArgs(this)); + fireEvent(DepthWriteChanged, PassEventArgs(this)); } void PassController::setDepthFunction(CompareFunction func) { - mPass->setDepthFunction(func); + mPass->setDepthFunction(func); - fireEvent(DepthFunctionChanged, PassEventArgs(this)); + fireEvent(DepthFunctionChanged, PassEventArgs(this)); } void PassController::setColourWriteEnabled(bool enabled) { - mPass->setColourWriteEnabled(enabled); + mPass->setColourWriteEnabled(enabled); - fireEvent(ColourWriteChanged, PassEventArgs(this)); + fireEvent(ColourWriteChanged, PassEventArgs(this)); } void PassController::setCullingMode(CullingMode mode) { - mPass->setCullingMode(mode); + mPass->setCullingMode(mode); - fireEvent(CullingModeChanged, PassEventArgs(this)); + fireEvent(CullingModeChanged, PassEventArgs(this)); } void PassController::setManualCullingMode(ManualCullingMode mode) { - mPass->setManualCullingMode(mode); + mPass->setManualCullingMode(mode); - fireEvent(ManualCullingModeChanged, PassEventArgs(this)); + fireEvent(ManualCullingModeChanged, PassEventArgs(this)); } void PassController::setLightingEnabled(bool enabled) { - mPass->setLightingEnabled(enabled); + mPass->setLightingEnabled(enabled); - fireEvent(LightingChanged, PassEventArgs(this)); + fireEvent(LightingChanged, PassEventArgs(this)); } void PassController::setMaxSimultaneousLights(unsigned short maxLights) { - mPass->setMaxSimultaneousLights(maxLights); + mPass->setMaxSimultaneousLights(maxLights); - fireEvent(MaxLightsChanged, PassEventArgs(this)); + fireEvent(MaxLightsChanged, PassEventArgs(this)); } void PassController::setStartLight(unsigned short startLight) { - mPass->setStartLight(startLight); + mPass->setStartLight(startLight); - fireEvent(StartLightChanged, PassEventArgs(this)); + fireEvent(StartLightChanged, PassEventArgs(this)); } void PassController::setShadingMode(ShadeOptions mode) { - mPass->setShadingMode(mode); + mPass->setShadingMode(mode); - fireEvent(ShadingModeChanged, PassEventArgs(this)); + fireEvent(ShadingModeChanged, PassEventArgs(this)); } void PassController::setPolygonMode(PolygonMode mode) { - mPass->setPolygonMode(mode); + mPass->setPolygonMode(mode); - fireEvent(PolygonModeChanged, PassEventArgs(this)); + fireEvent(PolygonModeChanged, PassEventArgs(this)); } void PassController::setFog(bool overrideScene, FogMode mode /* =FOG_NONE */, const ColourValue& colour /* =ColourValue::White */, Real expDensity /* =0.001 */, Real linearStart /* =0.0 */, Real linearEnd /* =1.0 */) { - mPass->setFog(overrideScene, mode, colour, expDensity, linearStart, linearEnd); + mPass->setFog(overrideScene, mode, colour, expDensity, linearStart, linearEnd); - fireEvent(FogChanged, PassEventArgs(this)); + fireEvent(FogChanged, PassEventArgs(this)); } void PassController::setDepthBias(float constantBias, float slopeScaleBias /* =0.0f */) { - mPass->setDepthBias(constantBias, slopeScaleBias); + mPass->setDepthBias(constantBias, slopeScaleBias); - fireEvent(DepthBiasChanged, PassEventArgs(this)); + fireEvent(DepthBiasChanged, PassEventArgs(this)); } void PassController::setAlphaRejectSettings(CompareFunction func, unsigned char value) { - mPass->setAlphaRejectSettings(func, value); + mPass->setAlphaRejectSettings(func, value); - fireEvent(AlphaRejectionChanged, PassEventArgs(this)); + fireEvent(AlphaRejectionChanged, PassEventArgs(this)); } void PassController::setAlphaRejectFunction(CompareFunction func) { - mPass->setAlphaRejectFunction(func); + mPass->setAlphaRejectFunction(func); - fireEvent(AlphaRejectionChanged, PassEventArgs(this)); + fireEvent(AlphaRejectionChanged, PassEventArgs(this)); } void PassController::setAlphaRejectValue(unsigned char val) { - mPass->setAlphaRejectValue(val); + mPass->setAlphaRejectValue(val); - fireEvent(AlphaRejectionChanged, PassEventArgs(this)); + fireEvent(AlphaRejectionChanged, PassEventArgs(this)); } void PassController::setIteratePerLight(bool enabled, bool onlyForOneLightType /* =true */, Light::LightTypes lightType /*=Light::LT_POINT */) { - mPass->setIteratePerLight(enabled, onlyForOneLightType, lightType); + mPass->setIteratePerLight(enabled, onlyForOneLightType, lightType); - fireEvent(IteratePerLightChanged, PassEventArgs(this)); + fireEvent(IteratePerLightChanged, PassEventArgs(this)); } void PassController::setLightCountPerIteration(unsigned short c) { - mPass->setLightCountPerIteration(c); + mPass->setLightCountPerIteration(c); - fireEvent(LightCountPerIterationChanged, PassEventArgs(this)); + fireEvent(LightCountPerIterationChanged, PassEventArgs(this)); } void PassController::setVertexProgram(const String& name, bool resetParams /* =true */) { - mPass->setVertexProgram(name, resetParams); + mPass->setVertexProgram(name, resetParams); - // TODO: Fire event + // TODO: Fire event } void PassController::setVertexProgramParameters(GpuProgramParametersSharedPtr params) { - mPass->setVertexProgramParameters(params); + mPass->setVertexProgramParameters(params); - // TODO: Fire event + // TODO: Fire event } void PassController::setShadowCasterVertexProgram(const String& name) { - mPass->setShadowCasterVertexProgram(name); + mPass->setShadowCasterVertexProgram(name); - // TODO: Fire event + // TODO: Fire event } void PassController::setShadowCasterVertexProgramParameters(GpuProgramParametersSharedPtr params) { - mPass->setShadowCasterVertexProgramParameters(params); + mPass->setShadowCasterVertexProgramParameters(params); - // TODO: Fire event + // TODO: Fire event } void PassController::setShadowReceiverVertexProgram(const String& name) { - mPass->setShadowReceiverVertexProgram(name); + mPass->setShadowReceiverVertexProgram(name); - // TODO: Fire event + // TODO: Fire event } void PassController::setShadowReceiverVertexProgramParameters(GpuProgramParametersSharedPtr params) { - mPass->setShadowReceiverVertexProgramParameters(params); + mPass->setShadowReceiverVertexProgramParameters(params); - // TODO: Fire event + // TODO: Fire event } void PassController::setShadowReceiverFragmentProgram(const String& name) { - mPass->setShadowReceiverFragmentProgram(name); + mPass->setShadowReceiverFragmentProgram(name); - // TODO: Fire event + // TODO: Fire event } void PassController::setShadowReceiverFragmentProgramParameters(GpuProgramParametersSharedPtr params) { - mPass->setShadowReceiverFragmentProgramParameters(params); + mPass->setShadowReceiverFragmentProgramParameters(params); - // TODO: Fire event + // TODO: Fire event } void PassController::setFragmentProgram(const String& name, bool resetParams /* =true */) { - mPass->setFragmentProgram(name, resetParams); + mPass->setFragmentProgram(name, resetParams); - // TODO: Fire event + // TODO: Fire event } void PassController::setFragmentProgramParameters(GpuProgramParametersSharedPtr params) { - mPass->setFragmentProgramParameters(params); + mPass->setFragmentProgramParameters(params); - // TODO: Fire event + // TODO: Fire event } void PassController::setTextureFiltering(TextureFilterOptions filterType) { - mPass->setTextureFiltering(filterType); + mPass->setTextureFiltering(filterType); - // TODO: Fire event + // TODO: Fire event } void PassController::setTextureAnisotropy(unsigned int maxAniso) { - mPass->setTextureAnisotropy(maxAniso); + mPass->setTextureAnisotropy(maxAniso); - // TODO: Fire event + // TODO: Fire event } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/PassEventArgs.cpp b/Tools/MaterialEditor/MaterialEditor/src/PassEventArgs.cpp index 49a27b744a2..8563773197e 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/PassEventArgs.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/PassEventArgs.cpp @@ -36,5 +36,5 @@ PassEventArgs::PassEventArgs(PassController* controller) PassController* PassEventArgs::getPassController() const { - return mPassController; + return mPassController; } diff --git a/Tools/MaterialEditor/MaterialEditor/src/PassPage.cpp b/Tools/MaterialEditor/MaterialEditor/src/PassPage.cpp index dffbdf7f617..8f74dc5e46b 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/PassPage.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/PassPage.cpp @@ -47,34 +47,34 @@ const long ID_MATERIAL_COMBO_BOX = wxNewId(); const long ID_TECHNIQUE_COMBO_BOX = wxNewId(); BEGIN_EVENT_TABLE(PassPage, wxWizardPageSimple) - EVT_CHOICE(ID_PROJECT_COMBO_BOX, PassPage::OnProjectSelected) - EVT_CHOICE(ID_MATERIAL_COMBO_BOX, PassPage::OnMaterialSelected) - //EVT_CHOICE(ID_TECHNIQUE_COMBO_BOX, TechniquePage::OnTechniqueSelected) + EVT_CHOICE(ID_PROJECT_COMBO_BOX, PassPage::OnProjectSelected) + EVT_CHOICE(ID_MATERIAL_COMBO_BOX, PassPage::OnMaterialSelected) + //EVT_CHOICE(ID_TECHNIQUE_COMBO_BOX, TechniquePage::OnTechniqueSelected) END_EVENT_TABLE() PassPage::PassPage(wxWizard* parent) : wxWizardPageSimple(parent), mProject(NULL), mMaterial(NULL), mTechnique(NULL) { - createPage(); + createPage(); } PassPage::PassPage(wxWizard* parent, Project* project) : wxWizardPageSimple(parent), mProject(project), mMaterial(NULL), mTechnique(NULL) { - createPage(); + createPage(); } PassPage::PassPage(wxWizard* parent, Project* project, MaterialController* mc) : wxWizardPageSimple(parent), mProject(project), mMaterial(mc), mTechnique(NULL) { - createPage(); + createPage(); } PassPage::PassPage(wxWizard* parent, Project* project, MaterialController* mc, TechniqueController* tc) : wxWizardPageSimple(parent), mProject(project), mMaterial(mc), mTechnique(tc) { - createPage(); + createPage(); } @@ -84,143 +84,143 @@ PassPage::~PassPage() void PassPage::createPage() { - mSizer = new wxBoxSizer(wxVERTICAL); + mSizer = new wxBoxSizer(wxVERTICAL); - // Project Label - mProjectLabel = new wxStaticText(this, wxID_ANY, wxT("Project:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mProjectLabel, 0, wxALL, 0); + // Project Label + mProjectLabel = new wxStaticText(this, wxID_ANY, wxT("Project:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mProjectLabel, 0, wxALL, 0); - // Project Combo Box - wxArrayString projectNames; - const ProjectList* projects = Workspace::getSingletonPtr()->getProjects(); - for(ProjectList::const_iterator it = projects->begin(); it != projects->end(); ++it) - projectNames.Add((*it)->getName().c_str()); + // Project Combo Box + wxArrayString projectNames; + const ProjectList* projects = Workspace::getSingletonPtr()->getProjects(); + for(ProjectList::const_iterator it = projects->begin(); it != projects->end(); ++it) + projectNames.Add((*it)->getName().c_str()); - // TODO: Select first Project - mProjectComboBox = new wxComboBox(this, ID_PROJECT_COMBO_BOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, projectNames, wxCB_DROPDOWN); - mSizer->Add(mProjectComboBox, 0, wxALL | wxEXPAND, 0); + // TODO: Select first Project + mProjectComboBox = new wxComboBox(this, ID_PROJECT_COMBO_BOX, wxEmptyString, wxDefaultPosition, wxDefaultSize, projectNames, wxCB_DROPDOWN); + mSizer->Add(mProjectComboBox, 0, wxALL | wxEXPAND, 0); - // Material Label - mMaterialLabel = new wxStaticText(this, wxID_ANY, wxT("Material:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mMaterialLabel, 0, wxALL, 0); + // Material Label + mMaterialLabel = new wxStaticText(this, wxID_ANY, wxT("Material:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mMaterialLabel, 0, wxALL, 0); - // Material Combo Box - mMaterialComboBox = new wxComboBox(this, ID_MATERIAL_COMBO_BOX); - mSizer->Add(mMaterialComboBox, 0, wxALL | wxEXPAND, 0); + // Material Combo Box + mMaterialComboBox = new wxComboBox(this, ID_MATERIAL_COMBO_BOX); + mSizer->Add(mMaterialComboBox, 0, wxALL | wxEXPAND, 0); - // Technique Label - mTechniqueLabel = new wxStaticText(this, wxID_ANY, wxT("Technique:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mTechniqueLabel, 0, wxALL, 0); + // Technique Label + mTechniqueLabel = new wxStaticText(this, wxID_ANY, wxT("Technique:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mTechniqueLabel, 0, wxALL, 0); - // Technique Combo Box - mTechniqueComboBox = new wxComboBox(this, ID_TECHNIQUE_COMBO_BOX); - mSizer->Add(mTechniqueComboBox, 0, wxALL | wxEXPAND, 0); + // Technique Combo Box + mTechniqueComboBox = new wxComboBox(this, ID_TECHNIQUE_COMBO_BOX); + mSizer->Add(mTechniqueComboBox, 0, wxALL | wxEXPAND, 0); - // Name Label - mNameLabel = new wxStaticText(this, wxID_ANY, wxT("Name:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mNameLabel, 0, wxALL, 0); + // Name Label + mNameLabel = new wxStaticText(this, wxID_ANY, wxT("Name:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mNameLabel, 0, wxALL, 0); - // Name Text - mNameText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); - mSizer->Add(mNameText, 0, wxALL | wxEXPAND, 0); + // Name Text + mNameText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); + mSizer->Add(mNameText, 0, wxALL | wxEXPAND, 0); - SetSizer(mSizer); - Layout(); + SetSizer(mSizer); + Layout(); } void PassPage::getName(wxString& name) const { - name = mNameText->GetValue(); + name = mNameText->GetValue(); } Project* PassPage::getProject() const { - wxString project = mProjectComboBox->GetValue(); + wxString project = mProjectComboBox->GetValue(); - return Workspace::getSingletonPtr()->getProject(project.c_str()); + return Workspace::getSingletonPtr()->getProject(project.c_str()); } MaterialController* PassPage::getMaterial() const { - wxString material = mMaterialComboBox->GetValue(); + wxString material = mMaterialComboBox->GetValue(); - return getProject()->getMaterialController(material.c_str()); + return getProject()->getMaterialController(material.c_str()); } TechniqueController* PassPage::getTechnique() const { - wxString technique = mTechniqueComboBox->GetValue(); + wxString technique = mTechniqueComboBox->GetValue(); - return getMaterial()->getTechniqueController(technique.c_str()); + return getMaterial()->getTechniqueController(technique.c_str()); } void PassPage::setProject(Project* project) { - mProjectComboBox->SetValue(project != NULL ? project->getName().c_str() : wxEmptyString); - populateMaterials(project != NULL ? project->getMaterials() : NULL); + mProjectComboBox->SetValue(project != NULL ? project->getName().c_str() : wxEmptyString); + populateMaterials(project != NULL ? project->getMaterials() : NULL); } void PassPage::setMaterial(MaterialController* mc) { - mMaterialComboBox->SetValue(mc != NULL ? mc->getMaterial()->getName().c_str() : wxEmptyString); - populateTechniques(mc != NULL ? mc->getTechniqueControllers() : NULL); + mMaterialComboBox->SetValue(mc != NULL ? mc->getMaterial()->getName().c_str() : wxEmptyString); + populateTechniques(mc != NULL ? mc->getTechniqueControllers() : NULL); } void PassPage::setTechnique(TechniqueController* tc) { - mTechniqueComboBox->SetValue(tc != NULL ? tc->getTechnique()->getName().c_str() : wxEmptyString); + mTechniqueComboBox->SetValue(tc != NULL ? tc->getTechnique()->getName().c_str() : wxEmptyString); } void PassPage::OnProjectSelected(wxCommandEvent& event) { - Project* project = getProject(); - if(project != NULL) - populateMaterials(project->getMaterials()); + Project* project = getProject(); + if(project != NULL) + populateMaterials(project->getMaterials()); } void PassPage::OnMaterialSelected(wxCommandEvent& event) { - MaterialController* mc = getMaterial(); - if(mc != NULL) - populateTechniques(mc->getTechniqueControllers()); + MaterialController* mc = getMaterial(); + if(mc != NULL) + populateTechniques(mc->getTechniqueControllers()); } void PassPage::populateMaterials(const MaterialControllerList* materials) { - if(materials == NULL) - { - mMaterialComboBox->Clear(); - return; - } + if(materials == NULL) + { + mMaterialComboBox->Clear(); + return; + } - wxArrayString materialNames; - MaterialControllerList::const_iterator it; - for(it = materials->begin(); it != materials->end(); ++it) - { - materialNames.Add((*it)->getMaterial()->getName().c_str()); - } + wxArrayString materialNames; + MaterialControllerList::const_iterator it; + for(it = materials->begin(); it != materials->end(); ++it) + { + materialNames.Add((*it)->getMaterial()->getName().c_str()); + } - mMaterialComboBox->Clear(); - mMaterialComboBox->Append(materialNames); + mMaterialComboBox->Clear(); + mMaterialComboBox->Append(materialNames); } void PassPage::populateTechniques(const TechniqueControllerList* techniques) { - if(techniques == NULL) - { - mTechniqueComboBox->Clear(); - return; - } - - wxArrayString techniqueNames; - TechniqueControllerList::const_iterator it; - for(it = techniques->begin(); it != techniques->end(); ++it) - { - techniqueNames.Add((*it)->getTechnique()->getName().c_str()); - } - - mTechniqueComboBox->Clear(); - mTechniqueComboBox->Append(techniqueNames); + if(techniques == NULL) + { + mTechniqueComboBox->Clear(); + return; + } + + wxArrayString techniqueNames; + TechniqueControllerList::const_iterator it; + for(it = techniques->begin(); it != techniques->end(); ++it) + { + techniqueNames.Add((*it)->getTechnique()->getName().c_str()); + } + + mTechniqueComboBox->Clear(); + mTechniqueComboBox->Append(techniqueNames); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/PassPropertyGridPage.cpp b/Tools/MaterialEditor/MaterialEditor/src/PassPropertyGridPage.cpp index e463fd7da36..9bf9a6cb9cd 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/PassPropertyGridPage.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/PassPropertyGridPage.cpp @@ -41,7 +41,7 @@ THE SOFTWARE. using namespace Ogre; BEGIN_EVENT_TABLE(PassPropertyGridPage, wxPropertyGridPage) - EVT_PG_CHANGED(-1, PassPropertyGridPage::propertyChanged) + EVT_PG_CHANGED(-1, PassPropertyGridPage::propertyChanged) END_EVENT_TABLE() PassPropertyGridPage::PassPropertyGridPage(PassController* controller) @@ -54,471 +54,471 @@ PassPropertyGridPage::~PassPropertyGridPage() } void PassPropertyGridPage::populate() -{ - createGeneralCategory(); - createReflectanceCategory(); - createPointCategory(); - createSceneBlendingCategory(); - createDepthCategory(); - createCullingCategory(); - createIlluminationCategory(); - createFogCategory(); - createAlphaRejectionCategory(); - createMiscCategory(); +{ + createGeneralCategory(); + createReflectanceCategory(); + createPointCategory(); + createSceneBlendingCategory(); + createDepthCategory(); + createCullingCategory(); + createIlluminationCategory(); + createFogCategory(); + createAlphaRejectionCategory(); + createMiscCategory(); } void PassPropertyGridPage::createGeneralCategory() { - const Pass* pass = mController->getPass(); + const Pass* pass = mController->getPass(); - Append(wxPropertyCategory(wxT("General"))); + Append(wxPropertyCategory(wxT("General"))); - // Name - mNameId = Append(wxStringProperty(wxT("Name"), wxPG_LABEL, pass->getName())); - SetPropertyHelpString(mNameId, wxT("Name of this Pass")); + // Name + mNameId = Append(wxStringProperty(wxT("Name"), wxPG_LABEL, pass->getName())); + SetPropertyHelpString(mNameId, wxT("Name of this Pass")); } void PassPropertyGridPage::createReflectanceCategory() { - const Pass* pass = mController->getPass(); + const Pass* pass = mController->getPass(); - Append(wxPropertyCategory(wxT("Reflectance"))); + Append(wxPropertyCategory(wxT("Reflectance"))); - // Ambient - ColourValue ambient = pass->getAmbient(); - mAmbientId = Append(wxColourProperty(wxT("Ambient"), wxPG_LABEL, wxColour((int)(255 * ambient.r), (int)(255 * ambient.g), (int)(255 * ambient.b)))); - SetPropertyHelpString(mAmbientId, wxT("Ambient colour reflectance")); + // Ambient + ColourValue ambient = pass->getAmbient(); + mAmbientId = Append(wxColourProperty(wxT("Ambient"), wxPG_LABEL, wxColour((int)(255 * ambient.r), (int)(255 * ambient.g), (int)(255 * ambient.b)))); + SetPropertyHelpString(mAmbientId, wxT("Ambient colour reflectance")); - // Diffuse - ColourValue diffuse = pass->getDiffuse(); - mDiffuseId = Append(wxColourProperty(wxT("Diffuse"), wxPG_LABEL, wxColour((int)(255 * diffuse.r), (int)(255 * diffuse.g), (int)(255 * diffuse.b)))); - SetPropertyHelpString(mDiffuseId, wxT("Diffuse colour reflectance")); + // Diffuse + ColourValue diffuse = pass->getDiffuse(); + mDiffuseId = Append(wxColourProperty(wxT("Diffuse"), wxPG_LABEL, wxColour((int)(255 * diffuse.r), (int)(255 * diffuse.g), (int)(255 * diffuse.b)))); + SetPropertyHelpString(mDiffuseId, wxT("Diffuse colour reflectance")); - // Specular - ColourValue specular = pass->getSpecular(); - mSpecularId = Append(wxColourProperty(wxT("Specular"), wxPG_LABEL, wxColour((int)(255 * specular.r), (int)(255 * specular.g), (int)(255 * specular.b)))); - SetPropertyHelpString(mSpecularId, wxT("Specular colour reflectance")); + // Specular + ColourValue specular = pass->getSpecular(); + mSpecularId = Append(wxColourProperty(wxT("Specular"), wxPG_LABEL, wxColour((int)(255 * specular.r), (int)(255 * specular.g), (int)(255 * specular.b)))); + SetPropertyHelpString(mSpecularId, wxT("Specular colour reflectance")); - // Shininess - mShininessId = Append(wxFloatProperty(wxT("Shininess"), wxPG_LABEL, pass->getShininess())); - SetPropertyHelpString(mShininessId, wxT("Shininess, affecting the size of specular highlights")); + // Shininess + mShininessId = Append(wxFloatProperty(wxT("Shininess"), wxPG_LABEL, pass->getShininess())); + SetPropertyHelpString(mShininessId, wxT("Shininess, affecting the size of specular highlights")); } void PassPropertyGridPage::createPointCategory() { - const Pass* pass = mController->getPass(); - - Append(wxPropertyCategory(wxT("Point"), wxPG_LABEL)); - - // Point Size - wxPGId pointSize = Append(wxParentProperty(wxT("Size"), wxPG_LABEL)); - mPointSizeId = AppendIn(pointSize, wxFloatProperty(wxT("Size"), wxPG_LABEL, pass->getPointSize())); - SetPropertyHelpString(mPointSizeId, wxT("Point size, affecting the size of points when rendering a point list, or a list of point sprites")); - - // Point Sprites - mPointSpritesId = Append(wxBoolProperty(wxT("Point Sprites"), wxPG_LABEL, pass->getPointSpritesEnabled())); - - // Point Attenuation - mAttenuationId = Append(wxParentProperty(wxT("Attenuation"),wxPG_LABEL)); - SetPropertyHelpString(mAttenuationId, wxT("Determines how points are attenuated with distance")); - mPointAttenuationId = AppendIn(mAttenuationId, wxBoolProperty(wxT("Enabled"), wxPG_LABEL, pass->isPointAttenuationEnabled())); - mPointMinSizeId = AppendIn(mAttenuationId, wxFloatProperty(wxT("Min"), wxPG_LABEL, pass->getPointMinSize())); - SetPropertyHelpString(mPointMinSizeId, wxT("Minimum point size, when point attenuation is in use")); - mPointMaxSizeId = AppendIn(mAttenuationId, wxFloatProperty(wxT("Max"), wxPG_LABEL, pass->getPointMaxSize())); - SetPropertyHelpString(mAttenuationId, wxT("Maximum point size, when point attenuation is in use")); - mPointAttenuationConstantId = AppendIn(mAttenuationId, wxFloatProperty(wxT("Constant"), wxPG_LABEL, pass->getPointAttenuationConstant())); - SetPropertyHelpString(mPointAttenuationConstantId, wxT("Constant coefficient of the point attenuation")); - mPointAttenuationLinearId = AppendIn(mAttenuationId, wxFloatProperty(wxT("Linear"), wxPG_LABEL, pass->getPointAttenuationLinear())); - SetPropertyHelpString(mPointAttenuationLinearId, wxT("Linear coefficient of the point attenuation")); - mPointAttenuationQuadraticId = AppendIn(mAttenuationId, wxFloatProperty(wxT("Quadratic"), wxPG_LABEL, pass->getPointAttenuationQuadratic())); - SetPropertyHelpString(mPointAttenuationQuadraticId, wxT("Quadratic coefficient of the point attenuation")); + const Pass* pass = mController->getPass(); + + Append(wxPropertyCategory(wxT("Point"), wxPG_LABEL)); + + // Point Size + wxPGId pointSize = Append(wxParentProperty(wxT("Size"), wxPG_LABEL)); + mPointSizeId = AppendIn(pointSize, wxFloatProperty(wxT("Size"), wxPG_LABEL, pass->getPointSize())); + SetPropertyHelpString(mPointSizeId, wxT("Point size, affecting the size of points when rendering a point list, or a list of point sprites")); + + // Point Sprites + mPointSpritesId = Append(wxBoolProperty(wxT("Point Sprites"), wxPG_LABEL, pass->getPointSpritesEnabled())); + + // Point Attenuation + mAttenuationId = Append(wxParentProperty(wxT("Attenuation"),wxPG_LABEL)); + SetPropertyHelpString(mAttenuationId, wxT("Determines how points are attenuated with distance")); + mPointAttenuationId = AppendIn(mAttenuationId, wxBoolProperty(wxT("Enabled"), wxPG_LABEL, pass->isPointAttenuationEnabled())); + mPointMinSizeId = AppendIn(mAttenuationId, wxFloatProperty(wxT("Min"), wxPG_LABEL, pass->getPointMinSize())); + SetPropertyHelpString(mPointMinSizeId, wxT("Minimum point size, when point attenuation is in use")); + mPointMaxSizeId = AppendIn(mAttenuationId, wxFloatProperty(wxT("Max"), wxPG_LABEL, pass->getPointMaxSize())); + SetPropertyHelpString(mAttenuationId, wxT("Maximum point size, when point attenuation is in use")); + mPointAttenuationConstantId = AppendIn(mAttenuationId, wxFloatProperty(wxT("Constant"), wxPG_LABEL, pass->getPointAttenuationConstant())); + SetPropertyHelpString(mPointAttenuationConstantId, wxT("Constant coefficient of the point attenuation")); + mPointAttenuationLinearId = AppendIn(mAttenuationId, wxFloatProperty(wxT("Linear"), wxPG_LABEL, pass->getPointAttenuationLinear())); + SetPropertyHelpString(mPointAttenuationLinearId, wxT("Linear coefficient of the point attenuation")); + mPointAttenuationQuadraticId = AppendIn(mAttenuationId, wxFloatProperty(wxT("Quadratic"), wxPG_LABEL, pass->getPointAttenuationQuadratic())); + SetPropertyHelpString(mPointAttenuationQuadraticId, wxT("Quadratic coefficient of the point attenuation")); } void PassPropertyGridPage::createSceneBlendingCategory() { - const Pass* pass = mController->getPass(); - - Append(wxPropertyCategory(wxT("Scene Blending"))); - - wxPGChoices sbtChoices; - sbtChoices.Add(wxT("N/A") -1); - sbtChoices.Add(wxT("Transparent Alpha"), SBT_TRANSPARENT_ALPHA); - sbtChoices.Add(wxT("Transparent Colour"), SBT_TRANSPARENT_COLOUR); - sbtChoices.Add(wxT("Add"), SBT_ADD); - sbtChoices.Add(wxT("Modulate"), SBT_MODULATE); - sbtChoices.Add(wxT("Replace"), SBT_REPLACE); - - wxPGChoices sbfChoices; - sbfChoices.Add(wxT("One"), SBF_ONE); - sbfChoices.Add(wxT("Zero"), SBF_ZERO); - sbfChoices.Add(wxT("Dest Colour"), SBF_DEST_COLOUR); - sbfChoices.Add(wxT("Src Colour"), SBF_SOURCE_COLOUR); - sbfChoices.Add(wxT("One Minus Dest Colour"), SBF_ONE_MINUS_DEST_COLOUR); - sbfChoices.Add(wxT("One Minus Src Colour"), SBF_ONE_MINUS_SOURCE_COLOUR); - sbfChoices.Add(wxT("Dest Alpha"), SBF_DEST_ALPHA); - sbfChoices.Add(wxT("Source Alpha"), SBF_SOURCE_ALPHA); - sbfChoices.Add(wxT("One Minus Dest Alpha"), SBF_ONE_MINUS_DEST_ALPHA); - sbfChoices.Add(wxT("One Minus Source Alpha"), SBF_ONE_MINUS_SOURCE_ALPHA); - - // Scene Blend Type - bool type = true; - SceneBlendType blendType; - SceneBlendFactor srcFactor = pass->getSourceBlendFactor(); - SceneBlendFactor destFactor = pass->getDestBlendFactor(); - if(srcFactor == SBF_SOURCE_ALPHA && destFactor == SBF_ONE_MINUS_SOURCE_ALPHA) - blendType = SBT_TRANSPARENT_ALPHA; - else if(srcFactor == SBF_SOURCE_COLOUR && destFactor == SBF_ONE_MINUS_SOURCE_COLOUR) - blendType = SBT_TRANSPARENT_COLOUR; - else if(srcFactor == SBF_DEST_COLOUR && destFactor == SBF_ZERO) - blendType = SBT_MODULATE; - else if(srcFactor == SBF_ONE && destFactor == SBF_ONE) - blendType = SBT_ADD; - else if(srcFactor == SBF_ONE && destFactor == SBF_ZERO) - blendType= SBT_REPLACE; - else type = false; - - mSceneBlendTypeId = Append(wxEnumProperty(wxT("Type"), wxPG_LABEL, sbtChoices, (type) ? blendType : 0)); - - // Source Scene Blend Type - mSrcSceneBlendTypeId = Append(wxEnumProperty(wxT("Src Factor"), wxPG_LABEL, sbfChoices, srcFactor)); - - // Destination Scene Blend Type - mDestSceneBlendTypeId = Append(wxEnumProperty(wxT("Dest Factor"), wxPG_LABEL, sbfChoices, destFactor)); + const Pass* pass = mController->getPass(); + + Append(wxPropertyCategory(wxT("Scene Blending"))); + + wxPGChoices sbtChoices; + sbtChoices.Add(wxT("N/A") -1); + sbtChoices.Add(wxT("Transparent Alpha"), SBT_TRANSPARENT_ALPHA); + sbtChoices.Add(wxT("Transparent Colour"), SBT_TRANSPARENT_COLOUR); + sbtChoices.Add(wxT("Add"), SBT_ADD); + sbtChoices.Add(wxT("Modulate"), SBT_MODULATE); + sbtChoices.Add(wxT("Replace"), SBT_REPLACE); + + wxPGChoices sbfChoices; + sbfChoices.Add(wxT("One"), SBF_ONE); + sbfChoices.Add(wxT("Zero"), SBF_ZERO); + sbfChoices.Add(wxT("Dest Colour"), SBF_DEST_COLOUR); + sbfChoices.Add(wxT("Src Colour"), SBF_SOURCE_COLOUR); + sbfChoices.Add(wxT("One Minus Dest Colour"), SBF_ONE_MINUS_DEST_COLOUR); + sbfChoices.Add(wxT("One Minus Src Colour"), SBF_ONE_MINUS_SOURCE_COLOUR); + sbfChoices.Add(wxT("Dest Alpha"), SBF_DEST_ALPHA); + sbfChoices.Add(wxT("Source Alpha"), SBF_SOURCE_ALPHA); + sbfChoices.Add(wxT("One Minus Dest Alpha"), SBF_ONE_MINUS_DEST_ALPHA); + sbfChoices.Add(wxT("One Minus Source Alpha"), SBF_ONE_MINUS_SOURCE_ALPHA); + + // Scene Blend Type + bool type = true; + SceneBlendType blendType; + SceneBlendFactor srcFactor = pass->getSourceBlendFactor(); + SceneBlendFactor destFactor = pass->getDestBlendFactor(); + if(srcFactor == SBF_SOURCE_ALPHA && destFactor == SBF_ONE_MINUS_SOURCE_ALPHA) + blendType = SBT_TRANSPARENT_ALPHA; + else if(srcFactor == SBF_SOURCE_COLOUR && destFactor == SBF_ONE_MINUS_SOURCE_COLOUR) + blendType = SBT_TRANSPARENT_COLOUR; + else if(srcFactor == SBF_DEST_COLOUR && destFactor == SBF_ZERO) + blendType = SBT_MODULATE; + else if(srcFactor == SBF_ONE && destFactor == SBF_ONE) + blendType = SBT_ADD; + else if(srcFactor == SBF_ONE && destFactor == SBF_ZERO) + blendType= SBT_REPLACE; + else type = false; + + mSceneBlendTypeId = Append(wxEnumProperty(wxT("Type"), wxPG_LABEL, sbtChoices, (type) ? blendType : 0)); + + // Source Scene Blend Type + mSrcSceneBlendTypeId = Append(wxEnumProperty(wxT("Src Factor"), wxPG_LABEL, sbfChoices, srcFactor)); + + // Destination Scene Blend Type + mDestSceneBlendTypeId = Append(wxEnumProperty(wxT("Dest Factor"), wxPG_LABEL, sbfChoices, destFactor)); } void PassPropertyGridPage::createDepthCategory() { - const Pass* pass = mController->getPass(); + const Pass* pass = mController->getPass(); - Append(wxPropertyCategory(wxT("Depth"))); + Append(wxPropertyCategory(wxT("Depth"))); - // Depth Check - mDepthCheckId = Append(wxBoolProperty(wxT("Depth Check"), wxPG_LABEL, pass->getDepthCheckEnabled())); + // Depth Check + mDepthCheckId = Append(wxBoolProperty(wxT("Depth Check"), wxPG_LABEL, pass->getDepthCheckEnabled())); - // Depth Write - mDepthWriteId = Append(wxBoolProperty(wxT("Depth Write"), wxPG_LABEL, pass->getDepthWriteEnabled())); + // Depth Write + mDepthWriteId = Append(wxBoolProperty(wxT("Depth Write"), wxPG_LABEL, pass->getDepthWriteEnabled())); - // Depth Function - wxPGChoices compareFuncChoices; - compareFuncChoices.Add(wxT("Fail"), CMPF_ALWAYS_FAIL); - compareFuncChoices.Add(wxT("Pass"), CMPF_ALWAYS_PASS); - compareFuncChoices.Add(wxT("<"), CMPF_LESS); - compareFuncChoices.Add(wxT("<="), CMPF_LESS_EQUAL); - compareFuncChoices.Add(wxT("=="), CMPF_EQUAL); - compareFuncChoices.Add(wxT("!="), CMPF_NOT_EQUAL); - compareFuncChoices.Add(wxT(">="), CMPF_GREATER_EQUAL); - compareFuncChoices.Add(wxT(">"), CMPF_GREATER); + // Depth Function + wxPGChoices compareFuncChoices; + compareFuncChoices.Add(wxT("Fail"), CMPF_ALWAYS_FAIL); + compareFuncChoices.Add(wxT("Pass"), CMPF_ALWAYS_PASS); + compareFuncChoices.Add(wxT("<"), CMPF_LESS); + compareFuncChoices.Add(wxT("<="), CMPF_LESS_EQUAL); + compareFuncChoices.Add(wxT("=="), CMPF_EQUAL); + compareFuncChoices.Add(wxT("!="), CMPF_NOT_EQUAL); + compareFuncChoices.Add(wxT(">="), CMPF_GREATER_EQUAL); + compareFuncChoices.Add(wxT(">"), CMPF_GREATER); - mDepthFunctionId = Append(wxEnumProperty(wxT("Depth Function"), wxPG_LABEL, compareFuncChoices, pass->getDepthFunction())); + mDepthFunctionId = Append(wxEnumProperty(wxT("Depth Function"), wxPG_LABEL, compareFuncChoices, pass->getDepthFunction())); - mDepthBiasId = Append(wxParentProperty(wxT("Depth Bias"), wxPG_LABEL)); + mDepthBiasId = Append(wxParentProperty(wxT("Depth Bias"), wxPG_LABEL)); - // Constant Bias - mDepthBiasConstantId = AppendIn(mDepthBiasId, wxFloatProperty(wxT("Constant"), wxPG_LABEL, pass->getDepthBiasConstant())); + // Constant Bias + mDepthBiasConstantId = AppendIn(mDepthBiasId, wxFloatProperty(wxT("Constant"), wxPG_LABEL, pass->getDepthBiasConstant())); - // Slope Bias - mDepthBiasSlopeId = AppendIn(mDepthBiasId, wxFloatProperty(wxT("Slope Scale"), wxPG_LABEL, pass->getDepthBiasSlopeScale())); + // Slope Bias + mDepthBiasSlopeId = AppendIn(mDepthBiasId, wxFloatProperty(wxT("Slope Scale"), wxPG_LABEL, pass->getDepthBiasSlopeScale())); } void PassPropertyGridPage::createCullingCategory() { - const Pass* pass = mController->getPass(); + const Pass* pass = mController->getPass(); - Append(wxPropertyCategory(wxT("Culling"))); + Append(wxPropertyCategory(wxT("Culling"))); - // Culling Mode - wxPGChoices cullingModeChoices; - cullingModeChoices.Add(wxT("None"), CULL_NONE); - cullingModeChoices.Add(wxT("Clockwise"), CULL_CLOCKWISE); - cullingModeChoices.Add(wxT("Counterclockwise"), CULL_ANTICLOCKWISE); + // Culling Mode + wxPGChoices cullingModeChoices; + cullingModeChoices.Add(wxT("None"), CULL_NONE); + cullingModeChoices.Add(wxT("Clockwise"), CULL_CLOCKWISE); + cullingModeChoices.Add(wxT("Counterclockwise"), CULL_ANTICLOCKWISE); - Append(wxEnumProperty(wxT("Culling Mode"), wxPG_LABEL, cullingModeChoices, pass->getDepthFunction())); + Append(wxEnumProperty(wxT("Culling Mode"), wxPG_LABEL, cullingModeChoices, pass->getDepthFunction())); - // Manual Culling Mode - wxPGChoices manualCullingModeChoices; - manualCullingModeChoices.Add(wxT("None"), MANUAL_CULL_NONE); - manualCullingModeChoices.Add(wxT("Back"), MANUAL_CULL_BACK); - manualCullingModeChoices.Add(wxT("Front"), MANUAL_CULL_FRONT); + // Manual Culling Mode + wxPGChoices manualCullingModeChoices; + manualCullingModeChoices.Add(wxT("None"), MANUAL_CULL_NONE); + manualCullingModeChoices.Add(wxT("Back"), MANUAL_CULL_BACK); + manualCullingModeChoices.Add(wxT("Front"), MANUAL_CULL_FRONT); - mManualCullingModeId = Append(wxEnumProperty(wxT("Manual Culling Mode"), wxPG_LABEL, manualCullingModeChoices, pass->getManualCullingMode())); + mManualCullingModeId = Append(wxEnumProperty(wxT("Manual Culling Mode"), wxPG_LABEL, manualCullingModeChoices, pass->getManualCullingMode())); } void PassPropertyGridPage::createIlluminationCategory() { - const Pass* pass = mController->getPass(); + const Pass* pass = mController->getPass(); - Append(wxPropertyCategory(wxT("Illumination"))); + Append(wxPropertyCategory(wxT("Illumination"))); - mLightingId = Append(wxBoolProperty(wxT("Lighting"), wxPG_LABEL, pass->getLightingEnabled())); + mLightingId = Append(wxBoolProperty(wxT("Lighting"), wxPG_LABEL, pass->getLightingEnabled())); - // Max Simultaneous Lights - mMaxLightsId = Append(wxIntProperty(wxT("Max Lights"), wxPG_LABEL, pass->getMaxSimultaneousLights())); + // Max Simultaneous Lights + mMaxLightsId = Append(wxIntProperty(wxT("Max Lights"), wxPG_LABEL, pass->getMaxSimultaneousLights())); - // Start Light - mStartLightId = Append(wxIntProperty(wxT("Start Light"), wxPG_LABEL, pass->getStartLight())); + // Start Light + mStartLightId = Append(wxIntProperty(wxT("Start Light"), wxPG_LABEL, pass->getStartLight())); - // Light Iteration - mIterationId = Append(wxBoolProperty(wxT("Iteration"), wxPG_LABEL, pass->getIteratePerLight())); + // Light Iteration + mIterationId = Append(wxBoolProperty(wxT("Iteration"), wxPG_LABEL, pass->getIteratePerLight())); - // Shading Mode - wxPGChoices shadingModeChoices; - shadingModeChoices.Add(wxT("Flat"), SO_FLAT); - shadingModeChoices.Add(wxT("Gouraud"), SO_GOURAUD); - shadingModeChoices.Add(wxT("Phong"), SO_PHONG); + // Shading Mode + wxPGChoices shadingModeChoices; + shadingModeChoices.Add(wxT("Flat"), SO_FLAT); + shadingModeChoices.Add(wxT("Gouraud"), SO_GOURAUD); + shadingModeChoices.Add(wxT("Phong"), SO_PHONG); - mShadingModeId = Append(wxEnumProperty(wxT("Shading Mode"), wxPG_LABEL, shadingModeChoices, pass->getShadingMode())); + mShadingModeId = Append(wxEnumProperty(wxT("Shading Mode"), wxPG_LABEL, shadingModeChoices, pass->getShadingMode())); - // Self Illumination - ColourValue selfIllum = pass->getSelfIllumination(); - mSelfIlluminationId = Append(wxColourProperty(wxT("Self Illumination"), wxPG_LABEL, wxColour((int)(255 * selfIllum.r), (int)(255 * selfIllum.g), (int)(255 * selfIllum.b)))); + // Self Illumination + ColourValue selfIllum = pass->getSelfIllumination(); + mSelfIlluminationId = Append(wxColourProperty(wxT("Self Illumination"), wxPG_LABEL, wxColour((int)(255 * selfIllum.r), (int)(255 * selfIllum.g), (int)(255 * selfIllum.b)))); } void PassPropertyGridPage::createFogCategory() { - const Pass* pass = mController->getPass(); + const Pass* pass = mController->getPass(); - mOverrideSceneId = Append(wxPropertyCategory(wxT("Fog"))); + mOverrideSceneId = Append(wxPropertyCategory(wxT("Fog"))); - // Fog Enabled - mFogOverrideId = Append(wxBoolProperty(wxT("Override Scene"), wxPG_LABEL, pass->getFogOverride())); + // Fog Enabled + mFogOverrideId = Append(wxBoolProperty(wxT("Override Scene"), wxPG_LABEL, pass->getFogOverride())); - // Fog Mode - wxPGChoices fogModeChoices; - fogModeChoices.Add(wxT("None"), FOG_NONE); - fogModeChoices.Add(wxT("EXP"), FOG_EXP); - fogModeChoices.Add(wxT("EXP2"), FOG_EXP2); - fogModeChoices.Add(wxT("Linear"), FOG_LINEAR); + // Fog Mode + wxPGChoices fogModeChoices; + fogModeChoices.Add(wxT("None"), FOG_NONE); + fogModeChoices.Add(wxT("EXP"), FOG_EXP); + fogModeChoices.Add(wxT("EXP2"), FOG_EXP2); + fogModeChoices.Add(wxT("Linear"), FOG_LINEAR); - mFogModeId = Append(wxEnumProperty(wxT("Fog Mode"), wxPG_LABEL, fogModeChoices, pass->getFogMode())); + mFogModeId = Append(wxEnumProperty(wxT("Fog Mode"), wxPG_LABEL, fogModeChoices, pass->getFogMode())); } // Possibly better as a wxParentProperty within Misc? void PassPropertyGridPage::createAlphaRejectionCategory() { - const Pass* pass = mController->getPass(); - Append(wxPropertyCategory(wxT("Alpha Rejection"), wxPG_LABEL)); - - // Alpha Reject Func - wxPGChoices compareFuncChoices; - compareFuncChoices.Add(wxT("Fail"), CMPF_ALWAYS_FAIL); - compareFuncChoices.Add(wxT("Pass"), CMPF_ALWAYS_PASS); - compareFuncChoices.Add(wxT("<"), CMPF_LESS); - compareFuncChoices.Add(wxT("<="), CMPF_LESS_EQUAL); - compareFuncChoices.Add(wxT("=="), CMPF_EQUAL); - compareFuncChoices.Add(wxT("!="), CMPF_NOT_EQUAL); - compareFuncChoices.Add(wxT(">="), CMPF_GREATER_EQUAL); - compareFuncChoices.Add(wxT(">"), CMPF_GREATER); - mAlphaRejectFuncId = Append(wxEnumProperty(wxT("Function"), wxPG_LABEL, compareFuncChoices, pass->getAlphaRejectFunction())); - - // Alpha Reject Value - mAlphaRejectValueId = Append(wxIntProperty(wxT("Value"), wxPG_LABEL, pass->getAlphaRejectValue())); + const Pass* pass = mController->getPass(); + Append(wxPropertyCategory(wxT("Alpha Rejection"), wxPG_LABEL)); + + // Alpha Reject Func + wxPGChoices compareFuncChoices; + compareFuncChoices.Add(wxT("Fail"), CMPF_ALWAYS_FAIL); + compareFuncChoices.Add(wxT("Pass"), CMPF_ALWAYS_PASS); + compareFuncChoices.Add(wxT("<"), CMPF_LESS); + compareFuncChoices.Add(wxT("<="), CMPF_LESS_EQUAL); + compareFuncChoices.Add(wxT("=="), CMPF_EQUAL); + compareFuncChoices.Add(wxT("!="), CMPF_NOT_EQUAL); + compareFuncChoices.Add(wxT(">="), CMPF_GREATER_EQUAL); + compareFuncChoices.Add(wxT(">"), CMPF_GREATER); + mAlphaRejectFuncId = Append(wxEnumProperty(wxT("Function"), wxPG_LABEL, compareFuncChoices, pass->getAlphaRejectFunction())); + + // Alpha Reject Value + mAlphaRejectValueId = Append(wxIntProperty(wxT("Value"), wxPG_LABEL, pass->getAlphaRejectValue())); } void PassPropertyGridPage::createMiscCategory() { - const Pass* pass = mController->getPass(); + const Pass* pass = mController->getPass(); - Append(wxPropertyCategory(wxT("Misc"))); + Append(wxPropertyCategory(wxT("Misc"))); - // Colour Write - mColourWriteId = Append(wxBoolProperty(wxT("Colour Write"), wxPG_LABEL, pass->getColourWriteEnabled())); + // Colour Write + mColourWriteId = Append(wxBoolProperty(wxT("Colour Write"), wxPG_LABEL, pass->getColourWriteEnabled())); - // Polygon Mode - wxPGChoices polygonModeChoices; - polygonModeChoices.Add(wxT("Points"), PM_POINTS); - polygonModeChoices.Add(wxT("Wireframe"), PM_WIREFRAME); - polygonModeChoices.Add(wxT("Solid"), PM_SOLID); + // Polygon Mode + wxPGChoices polygonModeChoices; + polygonModeChoices.Add(wxT("Points"), PM_POINTS); + polygonModeChoices.Add(wxT("Wireframe"), PM_WIREFRAME); + polygonModeChoices.Add(wxT("Solid"), PM_SOLID); - mPolygonModeId = Append(wxEnumProperty(wxT("Polygon Mode"), wxPG_LABEL, polygonModeChoices, pass->getPolygonMode())); + mPolygonModeId = Append(wxEnumProperty(wxT("Polygon Mode"), wxPG_LABEL, polygonModeChoices, pass->getPolygonMode())); - // Track Vertex Colour Type - wxPGChoices vertexColourTypeChoices; - vertexColourTypeChoices.Add(wxT("None"), TVC_NONE); - vertexColourTypeChoices.Add(wxT("Ambient"), TVC_AMBIENT); - vertexColourTypeChoices.Add(wxT("Diffuse"), TVC_DIFFUSE); - vertexColourTypeChoices.Add(wxT("Specular"), TVC_SPECULAR); - vertexColourTypeChoices.Add(wxT("Emissive"), TVC_EMISSIVE); + // Track Vertex Colour Type + wxPGChoices vertexColourTypeChoices; + vertexColourTypeChoices.Add(wxT("None"), TVC_NONE); + vertexColourTypeChoices.Add(wxT("Ambient"), TVC_AMBIENT); + vertexColourTypeChoices.Add(wxT("Diffuse"), TVC_DIFFUSE); + vertexColourTypeChoices.Add(wxT("Specular"), TVC_SPECULAR); + vertexColourTypeChoices.Add(wxT("Emissive"), TVC_EMISSIVE); - mTrackVertexColourTypeId = Append(wxEnumProperty(wxT("Track Vertex Colour Type"), wxPG_LABEL, vertexColourTypeChoices, pass->getVertexColourTracking())); + mTrackVertexColourTypeId = Append(wxEnumProperty(wxT("Track Vertex Colour Type"), wxPG_LABEL, vertexColourTypeChoices, pass->getVertexColourTracking())); } void PassPropertyGridPage::propertyChanged(wxPropertyGridEvent& event) { - wxPGId id = event.GetProperty(); - if(id == mNameId) - { - mController->setName(event.GetPropertyValueAsString().c_str()); - } - else if(id == mAmbientId) - { - // TODO - } - else if(id == mDiffuseId) - { - // TODO - } - else if(id == mSpecularId) - { - // TODO - } - else if(id == mShininessId) - { - mController->setShininess((Real)event.GetPropertyValueAsDouble()); - } - else if(id == mPointSizeId) - { - mController->setPointSize((Real)event.GetPropertyValueAsDouble()); - } - else if(id == mPointSpritesId) - { - mController->setPointSpritesEnabled(event.GetPropertyValueAsBool()); - } - //else if(id == mAttenuationId) - //{ - //} - else if(id == mPointAttenuationId) - { - const Pass* pass = mController->getPass(); - mController->setPointAttenuation(event.GetPropertyValueAsBool(), - pass->getPointAttenuationConstant(), pass->getPointAttenuationLinear(), - pass->getPointAttenuationQuadratic()); - } - else if(id == mPointMinSizeId) - { - mController->setPointMinSize((Real)event.GetPropertyValueAsDouble()); - } - else if(id == mPointMaxSizeId) - { - mController->setPointMaxSize((Real)event.GetPropertyValueAsDouble()); - } - else if(id == mPointAttenuationConstantId) - { - const Pass* pass = mController->getPass(); - mController->setPointAttenuation(pass->isPointAttenuationEnabled(), - (Real)event.GetPropertyValueAsDouble(), pass->getPointAttenuationLinear(), - pass->getPointAttenuationQuadratic()); - } - else if(id == mPointAttenuationLinearId) - { - const Pass* pass = mController->getPass(); - mController->setPointAttenuation(pass->isPointAttenuationEnabled(), - pass->getPointAttenuationConstant(), (Real)event.GetPropertyValueAsDouble(), - pass->getPointAttenuationQuadratic()); - } - else if(id == mPointAttenuationQuadraticId) - { - const Pass* pass = mController->getPass(); - mController->setPointAttenuation(pass->isPointAttenuationEnabled(), - pass->getPointAttenuationConstant(), pass->getPointAttenuationLinear(), - (Real)event.GetPropertyValueAsDouble()); - } - else if(id == mSceneBlendTypeId) - { - mController->setSceneBlending((SceneBlendType)event.GetPropertyValueAsInt()); - } - else if(id == mSrcSceneBlendTypeId) - { - mController->setSceneBlending((SceneBlendFactor)event.GetPropertyValueAsInt(), - mController->getPass()->getDestBlendFactor()); - } - else if(id == mDestSceneBlendTypeId) - { - mController->setSceneBlending(mController->getPass()->getSourceBlendFactor(), - (SceneBlendFactor)event.GetPropertyValueAsInt()); - } - else if(id == mDepthCheckId) - { - mController->setDepthCheckEnabled(event.GetPropertyValueAsBool()); - } - else if(id == mDepthWriteId) - { - mController->setDepthWriteEnabled(event.GetPropertyValueAsBool()); - } - else if(id == mDepthFunctionId) - { - mController->setDepthFunction((CompareFunction)event.GetPropertyValueAsInt()); - } - //else if(id == mDepthBiasId) - //{ - //} - else if(id == mDepthBiasConstantId) - { - mController->setDepthBias(event.GetPropertyValueAsDouble(), mController->getPass()->getDepthBiasSlopeScale()); - } - else if(id == mDepthBiasSlopeId) - { - mController->setDepthBias(mController->getPass()->getDepthBiasConstant(), event.GetPropertyValueAsDouble()); - } - else if(id == mManualCullingModeId) - { - mController->setManualCullingMode((ManualCullingMode)event.GetPropertyValueAsInt()); - } - else if(id == mLightingId) - { - mController->setLightingEnabled(event.GetPropertyValueAsBool()); - } - else if(id == mMaxLightsId) - { - mController->setMaxSimultaneousLights(event.GetPropertyValueAsInt()); - } - else if(id == mStartLightId) - { - mController->setStartLight(event.GetPropertyValueAsInt()); - } - else if(id == mIterationId) - { - mController->setLightCountPerIteration(event.GetPropertyValueAsInt()); - } - else if(id == mShadingModeId) - { - mController->setShadingMode((ShadeOptions)event.GetPropertyValueAsInt()); - } - else if(id == mSelfIlluminationId) - { - // TODO - } - else if(id == mOverrideSceneId) - { - const Pass* pass = mController->getPass(); - mController->setFog(event.GetPropertyValueAsBool(), pass->getFogMode(), pass->getFogColour(), - pass->getFogDensity(), pass->getFogStart(), pass->getFogEnd()); - } - else if(id == mFogOverrideId) - { - const Pass* pass = mController->getPass(); - mController->setFog(event.GetPropertyValueAsBool(), pass->getFogMode(), pass->getFogColour(), - pass->getFogDensity(), pass->getFogStart(), pass->getFogEnd()); - } - else if(id == mFogModeId) - { - const Pass* pass = mController->getPass(); - mController->setFog(pass->getFogOverride(), (FogMode)event.GetPropertyValueAsInt(), pass->getFogColour(), - pass->getFogDensity(), pass->getFogStart(), pass->getFogEnd()); - } - else if(id == mAlphaRejectFuncId) - { - mController->setAlphaRejectFunction((CompareFunction)event.GetPropertyValueAsInt()); - } - else if(id == mAlphaRejectValueId) - { - mController->setAlphaRejectValue(event.GetPropertyValueAsInt()); - } - else if(id == mColourWriteId) - { - mController->setColourWriteEnabled(event.GetPropertyValueAsBool()); - } - else if(id == mPolygonModeId) - { - mController->setPolygonMode((PolygonMode)event.GetPropertyValueAsInt()); - } - else if(id == mTrackVertexColourTypeId) - { - mController->setVertexColourTracking((TrackVertexColourType)event.GetPropertyValueAsInt()); - } + wxPGId id = event.GetProperty(); + if(id == mNameId) + { + mController->setName(event.GetPropertyValueAsString().c_str()); + } + else if(id == mAmbientId) + { + // TODO + } + else if(id == mDiffuseId) + { + // TODO + } + else if(id == mSpecularId) + { + // TODO + } + else if(id == mShininessId) + { + mController->setShininess((Real)event.GetPropertyValueAsDouble()); + } + else if(id == mPointSizeId) + { + mController->setPointSize((Real)event.GetPropertyValueAsDouble()); + } + else if(id == mPointSpritesId) + { + mController->setPointSpritesEnabled(event.GetPropertyValueAsBool()); + } + //else if(id == mAttenuationId) + //{ + //} + else if(id == mPointAttenuationId) + { + const Pass* pass = mController->getPass(); + mController->setPointAttenuation(event.GetPropertyValueAsBool(), + pass->getPointAttenuationConstant(), pass->getPointAttenuationLinear(), + pass->getPointAttenuationQuadratic()); + } + else if(id == mPointMinSizeId) + { + mController->setPointMinSize((Real)event.GetPropertyValueAsDouble()); + } + else if(id == mPointMaxSizeId) + { + mController->setPointMaxSize((Real)event.GetPropertyValueAsDouble()); + } + else if(id == mPointAttenuationConstantId) + { + const Pass* pass = mController->getPass(); + mController->setPointAttenuation(pass->isPointAttenuationEnabled(), + (Real)event.GetPropertyValueAsDouble(), pass->getPointAttenuationLinear(), + pass->getPointAttenuationQuadratic()); + } + else if(id == mPointAttenuationLinearId) + { + const Pass* pass = mController->getPass(); + mController->setPointAttenuation(pass->isPointAttenuationEnabled(), + pass->getPointAttenuationConstant(), (Real)event.GetPropertyValueAsDouble(), + pass->getPointAttenuationQuadratic()); + } + else if(id == mPointAttenuationQuadraticId) + { + const Pass* pass = mController->getPass(); + mController->setPointAttenuation(pass->isPointAttenuationEnabled(), + pass->getPointAttenuationConstant(), pass->getPointAttenuationLinear(), + (Real)event.GetPropertyValueAsDouble()); + } + else if(id == mSceneBlendTypeId) + { + mController->setSceneBlending((SceneBlendType)event.GetPropertyValueAsInt()); + } + else if(id == mSrcSceneBlendTypeId) + { + mController->setSceneBlending((SceneBlendFactor)event.GetPropertyValueAsInt(), + mController->getPass()->getDestBlendFactor()); + } + else if(id == mDestSceneBlendTypeId) + { + mController->setSceneBlending(mController->getPass()->getSourceBlendFactor(), + (SceneBlendFactor)event.GetPropertyValueAsInt()); + } + else if(id == mDepthCheckId) + { + mController->setDepthCheckEnabled(event.GetPropertyValueAsBool()); + } + else if(id == mDepthWriteId) + { + mController->setDepthWriteEnabled(event.GetPropertyValueAsBool()); + } + else if(id == mDepthFunctionId) + { + mController->setDepthFunction((CompareFunction)event.GetPropertyValueAsInt()); + } + //else if(id == mDepthBiasId) + //{ + //} + else if(id == mDepthBiasConstantId) + { + mController->setDepthBias(event.GetPropertyValueAsDouble(), mController->getPass()->getDepthBiasSlopeScale()); + } + else if(id == mDepthBiasSlopeId) + { + mController->setDepthBias(mController->getPass()->getDepthBiasConstant(), event.GetPropertyValueAsDouble()); + } + else if(id == mManualCullingModeId) + { + mController->setManualCullingMode((ManualCullingMode)event.GetPropertyValueAsInt()); + } + else if(id == mLightingId) + { + mController->setLightingEnabled(event.GetPropertyValueAsBool()); + } + else if(id == mMaxLightsId) + { + mController->setMaxSimultaneousLights(event.GetPropertyValueAsInt()); + } + else if(id == mStartLightId) + { + mController->setStartLight(event.GetPropertyValueAsInt()); + } + else if(id == mIterationId) + { + mController->setLightCountPerIteration(event.GetPropertyValueAsInt()); + } + else if(id == mShadingModeId) + { + mController->setShadingMode((ShadeOptions)event.GetPropertyValueAsInt()); + } + else if(id == mSelfIlluminationId) + { + // TODO + } + else if(id == mOverrideSceneId) + { + const Pass* pass = mController->getPass(); + mController->setFog(event.GetPropertyValueAsBool(), pass->getFogMode(), pass->getFogColour(), + pass->getFogDensity(), pass->getFogStart(), pass->getFogEnd()); + } + else if(id == mFogOverrideId) + { + const Pass* pass = mController->getPass(); + mController->setFog(event.GetPropertyValueAsBool(), pass->getFogMode(), pass->getFogColour(), + pass->getFogDensity(), pass->getFogStart(), pass->getFogEnd()); + } + else if(id == mFogModeId) + { + const Pass* pass = mController->getPass(); + mController->setFog(pass->getFogOverride(), (FogMode)event.GetPropertyValueAsInt(), pass->getFogColour(), + pass->getFogDensity(), pass->getFogStart(), pass->getFogEnd()); + } + else if(id == mAlphaRejectFuncId) + { + mController->setAlphaRejectFunction((CompareFunction)event.GetPropertyValueAsInt()); + } + else if(id == mAlphaRejectValueId) + { + mController->setAlphaRejectValue(event.GetPropertyValueAsInt()); + } + else if(id == mColourWriteId) + { + mController->setColourWriteEnabled(event.GetPropertyValueAsBool()); + } + else if(id == mPolygonModeId) + { + mController->setPolygonMode((PolygonMode)event.GetPropertyValueAsInt()); + } + else if(id == mTrackVertexColourTypeId) + { + mController->setVertexColourTracking((TrackVertexColourType)event.GetPropertyValueAsInt()); + } } diff --git a/Tools/MaterialEditor/MaterialEditor/src/PassWizard.cpp b/Tools/MaterialEditor/MaterialEditor/src/PassWizard.cpp index 27e2e08a79d..995ca7684db 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/PassWizard.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/PassWizard.cpp @@ -50,28 +50,28 @@ PassWizard::~PassWizard() bool PassWizard::Create(wxWindow* parent, int id /* = -1 */, const wxString& title /* = wxEmptyString */, const wxBitmap& bitmap /* = wxNullBitmap */, const wxPoint& pos /* = wxDefaultPosition */, long style /* = wxDEFAULT_DIALOG_STYLE */) { - bool result = wxWizard::Create(parent, id, title, bitmap, pos, style); + bool result = wxWizard::Create(parent, id, title, bitmap, pos, style); - mPassPage = new PassPage(this); + mPassPage = new PassPage(this); - GetPageAreaSizer()->Add(mPassPage); + GetPageAreaSizer()->Add(mPassPage); - return result; + return result; } PassPage* PassWizard::getPassPage() const { - return mPassPage; + return mPassPage; } void PassWizard::OnFinish(wxWizardEvent& event) { - Project* project = mPassPage->getProject(); - MaterialController* mc = mPassPage->getMaterial(); - TechniqueController* tc = mPassPage->getTechnique(); + Project* project = mPassPage->getProject(); + MaterialController* mc = mPassPage->getMaterial(); + TechniqueController* tc = mPassPage->getTechnique(); - wxString name; - mPassPage->getName(name); + wxString name; + mPassPage->getName(name); - tc->createPass(name.c_str()); + tc->createPass(name.c_str()); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/Project.cpp b/Tools/MaterialEditor/MaterialEditor/src/Project.cpp index af8cde0e346..50086d089bc 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/Project.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/Project.cpp @@ -42,132 +42,132 @@ using Ogre::MaterialManager; Project::Project() : mActiveMaterial(NULL) { - registerEvents(); + registerEvents(); } Project::Project(const String& name) : mActiveMaterial(NULL), mName(name) { - registerEvents(); + registerEvents(); } Project::~Project() { - MaterialControllerList::iterator it; - for(it = mMaterialControllers.begin(); it != mMaterialControllers.end(); ++it) - { - delete *it; - } - - mMaterialControllers.clear(); + MaterialControllerList::iterator it; + for(it = mMaterialControllers.begin(); it != mMaterialControllers.end(); ++it) + { + delete *it; + } + + mMaterialControllers.clear(); } void Project::registerEvents() { - registerEvent(NameChanged); - registerEvent(MaterialAdded); - registerEvent(MaterialRemoved); - registerEvent(ActiveMaterialChanged); + registerEvent(NameChanged); + registerEvent(MaterialAdded); + registerEvent(MaterialRemoved); + registerEvent(ActiveMaterialChanged); } const String& Project::getName() const { - return mName; + return mName; } void Project::setName(const String& name) { - mName = name; - - fireEvent(NameChanged, ProjectEventArgs(this)); + mName = name; + + fireEvent(NameChanged, ProjectEventArgs(this)); } void Project::addMaterial(MaterialPtr materialPtr) { - MaterialController* controller = new MaterialController(materialPtr); - mMaterialControllers.push_back(controller); - - fireEvent(MaterialAdded, ProjectEventArgs(this, controller)); + MaterialController* controller = new MaterialController(materialPtr); + mMaterialControllers.push_back(controller); + + fireEvent(MaterialAdded, ProjectEventArgs(this, controller)); } void Project::createMaterial(const String& name) { - // TODO: Projects should probably have their own resource groups instead of using the default - MaterialPtr materialPtr = (MaterialPtr)MaterialManager::getSingletonPtr()->create(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + // TODO: Projects should probably have their own resource groups instead of using the default + MaterialPtr materialPtr = (MaterialPtr)MaterialManager::getSingletonPtr()->create(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - MaterialController* controller = new MaterialController(materialPtr); - mMaterialControllers.push_back(controller); + MaterialController* controller = new MaterialController(materialPtr); + mMaterialControllers.push_back(controller); - fireEvent(MaterialAdded, ProjectEventArgs(this, controller)); + fireEvent(MaterialAdded, ProjectEventArgs(this, controller)); } void Project::removeMaterial(MaterialController* controller) { - MaterialControllerList::iterator it; - for(it = mMaterialControllers.begin(); it != mMaterialControllers.end(); ++it) - { - if(*it == controller) - { - mMaterialControllers.erase(it); - break; - } - } - - // Consider: Should this be fired BEFORE the actual removal? - fireEvent(MaterialRemoved, ProjectEventArgs(this, controller)); + MaterialControllerList::iterator it; + for(it = mMaterialControllers.begin(); it != mMaterialControllers.end(); ++it) + { + if(*it == controller) + { + mMaterialControllers.erase(it); + break; + } + } + + // Consider: Should this be fired BEFORE the actual removal? + fireEvent(MaterialRemoved, ProjectEventArgs(this, controller)); } void Project::removeMaterial(Material* material) { - removeMaterial(getMaterialController(material->getName())); + removeMaterial(getMaterialController(material->getName())); } void Project::removeMaterial(const String& name) { - removeMaterial(getMaterialController(name)); + removeMaterial(getMaterialController(name)); } MaterialController* Project::getActiveMaterial() const { - return mActiveMaterial; + return mActiveMaterial; } void Project::setActiveMaterial(MaterialController* controller) { - assert(controller); - - if(controller == mActiveMaterial) return; + assert(controller); + + if(controller == mActiveMaterial) return; - mActiveMaterial = controller; - - fireEvent(ActiveMaterialChanged, ProjectEventArgs(this)); + mActiveMaterial = controller; + + fireEvent(ActiveMaterialChanged, ProjectEventArgs(this)); } void Project::setActiveMaterial(Material* material) { - setActiveMaterial(getMaterialController(material->getName())); + setActiveMaterial(getMaterialController(material->getName())); } void Project::setActiveMaterial(const String& name) { - setActiveMaterial(getMaterialController(name)); + setActiveMaterial(getMaterialController(name)); } MaterialController* Project::getMaterialController(const String& name) { - MaterialController* mc; - MaterialControllerList::iterator it; - for(it = mMaterialControllers.begin(); it != mMaterialControllers.end(); ++it) - { - mc = (*it); - if(mc->getMaterial()->getName() == name) return mc; - } + MaterialController* mc; + MaterialControllerList::iterator it; + for(it = mMaterialControllers.begin(); it != mMaterialControllers.end(); ++it) + { + mc = (*it); + if(mc->getMaterial()->getName() == name) return mc; + } - return NULL; + return NULL; } const MaterialControllerList* Project::getMaterials() const { - return &mMaterialControllers; + return &mMaterialControllers; } void Project::open() @@ -180,15 +180,15 @@ void Project::close() void Project::generateScene(Ogre::SceneManager* sceneManager) { - sceneManager->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); + sceneManager->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); - Light* light = sceneManager->createLight("MainLight"); - light->setPosition(20,80,50); + Light* light = sceneManager->createLight("MainLight"); + light->setPosition(20,80,50); - Entity* entity = sceneManager->createEntity("head", "ogrehead.mesh"); - entity->setMaterialName(mActiveMaterial->getMaterial()->getName()); + Entity* entity = sceneManager->createEntity("head", "ogrehead.mesh"); + entity->setMaterialName(mActiveMaterial->getMaterial()->getName()); - sceneManager->getRootSceneNode()->createChildSceneNode()->attachObject(entity); + sceneManager->getRootSceneNode()->createChildSceneNode()->attachObject(entity); } void Project::subscribeTo(RootEventPlugin* plugin) diff --git a/Tools/MaterialEditor/MaterialEditor/src/ProjectEventArgs.cpp b/Tools/MaterialEditor/MaterialEditor/src/ProjectEventArgs.cpp index 21527d049f8..c5a636c82a6 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/ProjectEventArgs.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/ProjectEventArgs.cpp @@ -39,10 +39,10 @@ ProjectEventArgs::ProjectEventArgs(Project* project, MaterialController* materia Project* ProjectEventArgs::getProject() const { - return mProject; + return mProject; } MaterialController* ProjectEventArgs::getMaterial() const { - return mMaterial; + return mMaterial; } diff --git a/Tools/MaterialEditor/MaterialEditor/src/ProjectPage.cpp b/Tools/MaterialEditor/MaterialEditor/src/ProjectPage.cpp index ba9e06eed39..c46e66fb524 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/ProjectPage.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/ProjectPage.cpp @@ -34,13 +34,13 @@ THE SOFTWARE. #include BEGIN_EVENT_TABLE(ProjectPage, wxWizardPageSimple) - EVT_BUTTON(wxID_ANY, ProjectPage::OnBrowse) + EVT_BUTTON(wxID_ANY, ProjectPage::OnBrowse) END_EVENT_TABLE() ProjectPage::ProjectPage(wxWizard* parent) : wxWizardPageSimple(parent) { - createPage(); + createPage(); } ProjectPage::~ProjectPage() @@ -49,43 +49,43 @@ ProjectPage::~ProjectPage() void ProjectPage::createPage() { - mSizer = new wxBoxSizer(wxVERTICAL); - - mNameLabel = new wxStaticText(this, wxID_ANY, wxT("Name:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mNameLabel, 0, wxALL, 5); + mSizer = new wxBoxSizer(wxVERTICAL); + + mNameLabel = new wxStaticText(this, wxID_ANY, wxT("Name:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mNameLabel, 0, wxALL, 5); - mNameText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); - mSizer->Add(mNameText, 0, wxALL | wxEXPAND, 5); + mNameText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); + mSizer->Add(mNameText, 0, wxALL | wxEXPAND, 5); - mLocationLabel = new wxStaticText(this, wxID_ANY, wxT("Location:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mLocationLabel, 0, wxALL, 5); + mLocationLabel = new wxStaticText(this, wxID_ANY, wxT("Location:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mLocationLabel, 0, wxALL, 5); - mLocationText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); - mSizer->Add(mLocationText, 0, wxALL | wxEXPAND, 5); + mLocationText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); + mSizer->Add(mLocationText, 0, wxALL | wxEXPAND, 5); - mBrowseButton = new wxButton(this, wxID_ANY, wxT("Browse..."), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mBrowseButton, 0, wxALL | wxALIGN_RIGHT, 5); + mBrowseButton = new wxButton(this, wxID_ANY, wxT("Browse..."), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mBrowseButton, 0, wxALL | wxALIGN_RIGHT, 5); - SetSizer(mSizer); - Layout(); + SetSizer(mSizer); + Layout(); } void ProjectPage::getName(wxString& name) const { - name = mNameText->GetValue(); + name = mNameText->GetValue(); } void ProjectPage::getLocation(wxString& location) const { - location = mLocationText->GetValue(); + location = mLocationText->GetValue(); } void ProjectPage::OnBrowse(wxCommandEvent& event) { - wxDirDialog* dlg = new wxDirDialog(this, wxT("Project Directory"), wxT("/"), wxDD_NEW_DIR_BUTTON); - if(dlg->ShowModal()== wxID_OK) - { - mLocationText->SetValue(dlg->GetPath()); - mLocationText->SetSelection(0, mLocationText->GetValue().length() - 1); - } + wxDirDialog* dlg = new wxDirDialog(this, wxT("Project Directory"), wxT("/"), wxDD_NEW_DIR_BUTTON); + if(dlg->ShowModal()== wxID_OK) + { + mLocationText->SetValue(dlg->GetPath()); + mLocationText->SetSelection(0, mLocationText->GetValue().length() - 1); + } } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/ProjectWizard.cpp b/Tools/MaterialEditor/MaterialEditor/src/ProjectWizard.cpp index cbb26c788b7..9a2137cc3a3 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/ProjectWizard.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/ProjectWizard.cpp @@ -33,7 +33,7 @@ THE SOFTWARE #include "Workspace.h" BEGIN_EVENT_TABLE(ProjectWizard, wxWizard) - EVT_WIZARD_FINISHED(wxID_ANY, ProjectWizard::OnFinish) + EVT_WIZARD_FINISHED(wxID_ANY, ProjectWizard::OnFinish) END_EVENT_TABLE() ProjectWizard::ProjectWizard() @@ -46,28 +46,28 @@ ProjectWizard::~ProjectWizard() bool ProjectWizard::Create(wxWindow* parent, int id /* = -1 */, const wxString& title /* = wxEmptyString */, const wxBitmap& bitmap /* = wxNullBitmap */, const wxPoint& pos /* = wxDefaultPosition */, long style /* = wxDEFAULT_DIALOG_STYLE */) { - bool result = wxWizard::Create(parent, id, title, bitmap, pos, style); + bool result = wxWizard::Create(parent, id, title, bitmap, pos, style); - mProjectPage = new ProjectPage(this); + mProjectPage = new ProjectPage(this); - GetPageAreaSizer()->Add(mProjectPage); + GetPageAreaSizer()->Add(mProjectPage); - return result; + return result; } ProjectPage* ProjectWizard::getProjectPage() const { - return mProjectPage; + return mProjectPage; } void ProjectWizard::OnFinish(wxWizardEvent& event) { - wxString name; - mProjectPage->getName(name); + wxString name; + mProjectPage->getName(name); - wxString location; - mProjectPage->getLocation(location); + wxString location; + mProjectPage->getLocation(location); - Project* project = new Project(name.c_str()); - Workspace::getSingletonPtr()->addProject(project); + Project* project = new Project(name.c_str()); + Workspace::getSingletonPtr()->addProject(project); } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/PropertiesPanel.cpp b/Tools/MaterialEditor/MaterialEditor/src/PropertiesPanel.cpp index 9aef363ca28..47d93cb08cb 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/PropertiesPanel.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/PropertiesPanel.cpp @@ -68,40 +68,40 @@ BEGIN_EVENT_TABLE(PropertiesPanel, wxPanel) END_EVENT_TABLE() PropertiesPanel::PropertiesPanel(wxWindow* parent, - wxWindowID id /* = wxID_ANY */, - const wxPoint& pos /* = wxDefaultPosition */, - const wxSize& size /* = wxDefaultSize */, - long style /* = wxTAB_TRAVERSAL | wxNO_BORDER */, - const wxString& name /* = wxT("Workspace Panel")) */) - : wxPanel(parent, id, pos, size, style, name) + wxWindowID id /* = wxID_ANY */, + const wxPoint& pos /* = wxDefaultPosition */, + const wxSize& size /* = wxDefaultSize */, + long style /* = wxTAB_TRAVERSAL | wxNO_BORDER */, + const wxString& name /* = wxT("Workspace Panel")) */) + : wxPanel(parent, id, pos, size, style, name) { - mGridSizer = new wxGridSizer(1, 1, 0, 0); + mGridSizer = new wxGridSizer(1, 1, 0, 0); - mPropertyGrid = new wxPropertyGridManager(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxPG_BOLD_MODIFIED | wxPG_SPLITTER_AUTO_CENTER | wxPG_DESCRIPTION | wxPGMAN_DEFAULT_STYLE); + mPropertyGrid = new wxPropertyGridManager(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, + wxPG_BOLD_MODIFIED | wxPG_SPLITTER_AUTO_CENTER | wxPG_DESCRIPTION | wxPGMAN_DEFAULT_STYLE); - // Adding a page sets target page to the one added, so - // we don't have to call SetTargetPage if we are filling - // it right after adding. - //MaterialController* controller = new MaterialController((MaterialPtr)MaterialManager::getSingletonPtr()->create("Test", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)); - //TechniqueController* tc = controller->createTechnique(); - //PassController* pc = tc->createPass(); - //PassPropertyGridPage* page = new PassPropertyGridPage(pc); - //TechniquePropertyGridPage* page = new TechniquePropertyGridPage(tc); - //MaterialPropertyGridPage* page = new MaterialPropertyGridPage(controller); - //mPropertyGrid->AddPage(wxEmptyString, wxPG_NULL_BITMAP, page); - //page->populate(); + // Adding a page sets target page to the one added, so + // we don't have to call SetTargetPage if we are filling + // it right after adding. + //MaterialController* controller = new MaterialController((MaterialPtr)MaterialManager::getSingletonPtr()->create("Test", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)); + //TechniqueController* tc = controller->createTechnique(); + //PassController* pc = tc->createPass(); + //PassPropertyGridPage* page = new PassPropertyGridPage(pc); + //TechniquePropertyGridPage* page = new TechniquePropertyGridPage(tc); + //MaterialPropertyGridPage* page = new MaterialPropertyGridPage(controller); + //mPropertyGrid->AddPage(wxEmptyString, wxPG_NULL_BITMAP, page); + //page->populate(); - // For total safety, finally reset the target page. - //mPropertyGrid->SetTargetPage(0); + // For total safety, finally reset the target page. + //mPropertyGrid->SetTargetPage(0); - mGridSizer->Add(mPropertyGrid, 0, wxALL | wxEXPAND, 0); + mGridSizer->Add(mPropertyGrid, 0, wxALL | wxEXPAND, 0); - SetSizer(mGridSizer); - Layout(); + SetSizer(mGridSizer); + Layout(); - SelectionService::getSingletonPtr()->subscribe(SelectionService::SelectionChanged, boost::bind(&PropertiesPanel::selectionChanged, this, _1)); - Workspace::getSingletonPtr()->subscribe(Workspace::ProjectRemoved, boost::bind(&PropertiesPanel::projectRemoved, this, _1)); + SelectionService::getSingletonPtr()->subscribe(SelectionService::SelectionChanged, boost::bind(&PropertiesPanel::selectionChanged, this, _1)); + Workspace::getSingletonPtr()->subscribe(Workspace::ProjectRemoved, boost::bind(&PropertiesPanel::projectRemoved, this, _1)); } PropertiesPanel::~PropertiesPanel() @@ -110,134 +110,134 @@ PropertiesPanel::~PropertiesPanel() void PropertiesPanel::selectionChanged(EventArgs& args) { - SelectionEventArgs sea = dynamic_cast(args); - SelectionList selection = sea.getSelection(); - if(!selection.empty()) - { - boost::any sel = selection.front(); - if(sel.type() == typeid(Project)) - { - } - else if(sel.type() == typeid(MaterialController*)) - { - MaterialController* mc = any_cast(sel); - - MaterialPageIndexMap::iterator it = mMaterialPageIndexMap.find(mc); - if(it != mMaterialPageIndexMap.end()) - { - int index = mMaterialPageIndexMap[mc]; - mPropertyGrid->SelectPage(index); - } - else - { - MaterialPropertyGridPage* page = new MaterialPropertyGridPage(mc); - - int index = mPropertyGrid->AddPage(wxEmptyString, wxPG_NULL_BITMAP, page); - page->populate(); - - mMaterialPageIndexMap[mc] = index; - - mPropertyGrid->SelectPage(index); - } - } - else if(sel.type() == typeid(TechniqueController*)) - { - TechniqueController* tc = any_cast(sel); - - TechniquePageIndexMap::iterator it = mTechniquePageIndexMap.find(tc); - if(it != mTechniquePageIndexMap.end()) - { - int index = mTechniquePageIndexMap[tc]; - mPropertyGrid->SelectPage(index); - } - else - { - TechniquePropertyGridPage* page = new TechniquePropertyGridPage(tc); - - int index = mPropertyGrid->AddPage(wxEmptyString, wxPG_NULL_BITMAP, page); - page->populate(); - - mTechniquePageIndexMap[tc] = index; - - mPropertyGrid->SelectPage(index); - } - } - else if(sel.type() == typeid(PassController*)) - { - PassController* pc = any_cast(sel); - - PassPageIndexMap::iterator it = mPassPageIndexMap.find(pc); - if(it != mPassPageIndexMap.end()) - { - int index = mPassPageIndexMap[pc]; - mPropertyGrid->SelectPage(index); - } - else - { - PassPropertyGridPage* page = new PassPropertyGridPage(pc); - - int index = mPropertyGrid->AddPage(wxEmptyString, wxPG_NULL_BITMAP, page); - page->populate(); - - mPassPageIndexMap[pc] = index; - - mPropertyGrid->SelectPage(index); - } - } - - mPropertyGrid->Refresh(); - } + SelectionEventArgs sea = dynamic_cast(args); + SelectionList selection = sea.getSelection(); + if(!selection.empty()) + { + boost::any sel = selection.front(); + if(sel.type() == typeid(Project)) + { + } + else if(sel.type() == typeid(MaterialController*)) + { + MaterialController* mc = any_cast(sel); + + MaterialPageIndexMap::iterator it = mMaterialPageIndexMap.find(mc); + if(it != mMaterialPageIndexMap.end()) + { + int index = mMaterialPageIndexMap[mc]; + mPropertyGrid->SelectPage(index); + } + else + { + MaterialPropertyGridPage* page = new MaterialPropertyGridPage(mc); + + int index = mPropertyGrid->AddPage(wxEmptyString, wxPG_NULL_BITMAP, page); + page->populate(); + + mMaterialPageIndexMap[mc] = index; + + mPropertyGrid->SelectPage(index); + } + } + else if(sel.type() == typeid(TechniqueController*)) + { + TechniqueController* tc = any_cast(sel); + + TechniquePageIndexMap::iterator it = mTechniquePageIndexMap.find(tc); + if(it != mTechniquePageIndexMap.end()) + { + int index = mTechniquePageIndexMap[tc]; + mPropertyGrid->SelectPage(index); + } + else + { + TechniquePropertyGridPage* page = new TechniquePropertyGridPage(tc); + + int index = mPropertyGrid->AddPage(wxEmptyString, wxPG_NULL_BITMAP, page); + page->populate(); + + mTechniquePageIndexMap[tc] = index; + + mPropertyGrid->SelectPage(index); + } + } + else if(sel.type() == typeid(PassController*)) + { + PassController* pc = any_cast(sel); + + PassPageIndexMap::iterator it = mPassPageIndexMap.find(pc); + if(it != mPassPageIndexMap.end()) + { + int index = mPassPageIndexMap[pc]; + mPropertyGrid->SelectPage(index); + } + else + { + PassPropertyGridPage* page = new PassPropertyGridPage(pc); + + int index = mPropertyGrid->AddPage(wxEmptyString, wxPG_NULL_BITMAP, page); + page->populate(); + + mPassPageIndexMap[pc] = index; + + mPropertyGrid->SelectPage(index); + } + } + + mPropertyGrid->Refresh(); + } } void PropertiesPanel::projectRemoved(EventArgs& args) { - // Consider: Should this method also attempt to remove all - // of the page associated with this Projects, - // Materials, Techniques, and Passes? + // Consider: Should this method also attempt to remove all + // of the page associated with this Projects, + // Materials, Techniques, and Passes? } void PropertiesPanel::materialRemoved(EventArgs& args) { - // Consider: Should this method also attempt to remove all - // of the page associated with this Materials, Techniques, - // and Passes? - - ProjectEventArgs pea = dynamic_cast(args); - MaterialController* mc = pea.getMaterial(); - - MaterialPageIndexMap::iterator it = mMaterialPageIndexMap.find(mc); - if(it != mMaterialPageIndexMap.end()) - { - mPropertyGrid->RemovePage(mMaterialPageIndexMap[mc]); - mMaterialPageIndexMap.erase(it); - } + // Consider: Should this method also attempt to remove all + // of the page associated with this Materials, Techniques, + // and Passes? + + ProjectEventArgs pea = dynamic_cast(args); + MaterialController* mc = pea.getMaterial(); + + MaterialPageIndexMap::iterator it = mMaterialPageIndexMap.find(mc); + if(it != mMaterialPageIndexMap.end()) + { + mPropertyGrid->RemovePage(mMaterialPageIndexMap[mc]); + mMaterialPageIndexMap.erase(it); + } } void PropertiesPanel::techniqueRemoved(EventArgs& args) { - // Consider: Should this method also attempt to remove all - // of the page associated with this Techniques, Passes? - - MaterialEventArgs mea = dynamic_cast(args); - TechniqueController* tc = mea.getTechniqueController(); - - TechniquePageIndexMap::iterator it = mTechniquePageIndexMap.find(tc); - if(it != mTechniquePageIndexMap.end()) - { - mPropertyGrid->RemovePage(mTechniquePageIndexMap[tc]); - mTechniquePageIndexMap.erase(it); - } + // Consider: Should this method also attempt to remove all + // of the page associated with this Techniques, Passes? + + MaterialEventArgs mea = dynamic_cast(args); + TechniqueController* tc = mea.getTechniqueController(); + + TechniquePageIndexMap::iterator it = mTechniquePageIndexMap.find(tc); + if(it != mTechniquePageIndexMap.end()) + { + mPropertyGrid->RemovePage(mTechniquePageIndexMap[tc]); + mTechniquePageIndexMap.erase(it); + } } void PropertiesPanel::passRemoved(EventArgs& args) { - TechniqueEventArgs tea = dynamic_cast(args); - PassController* pc = tea.getPassController(); - - PassPageIndexMap::iterator it = mPassPageIndexMap.find(pc); - if(it != mPassPageIndexMap.end()) - { - mPropertyGrid->RemovePage(mPassPageIndexMap[pc]); - mPassPageIndexMap.erase(it); - } + TechniqueEventArgs tea = dynamic_cast(args); + PassController* pc = tea.getPassController(); + + PassPageIndexMap::iterator it = mPassPageIndexMap.find(pc); + if(it != mPassPageIndexMap.end()) + { + mPropertyGrid->RemovePage(mPassPageIndexMap[pc]); + mPassPageIndexMap.erase(it); + } } diff --git a/Tools/MaterialEditor/MaterialEditor/src/ResourcePanel.cpp b/Tools/MaterialEditor/MaterialEditor/src/ResourcePanel.cpp index e3d7717788d..cb5fdfd1434 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/ResourcePanel.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/ResourcePanel.cpp @@ -14,27 +14,27 @@ using Ogre::StringVector; ResourcePanel::ResourcePanel(wxWindow* parent, wxWindowID id /* = wxID_ANY */, const wxPoint& pos /* = wxDefaultPosition */, const wxSize& size /* = wxDeafultSize */, long style /* = wxTAB_TRAVERSAL */, const wxString& name /* = */) : wxPanel(parent, id, pos, size, style, name) { - mBoxSizer = new wxBoxSizer(wxVERTICAL); - - mTreeControl = new wxTreeCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); - mBoxSizer->Add(mTreeControl, 1, wxEXPAND | wxALL); - - wxTreeItemId rootId = mTreeControl->AddRoot("Resources"); - - StringVector groups = ResourceGroupManager::getSingletonPtr()->getResourceGroups(); - for(StringVector::iterator it = groups.begin(); it != groups.end(); ++it) - { - wxTreeItemId groupId = mTreeControl->AppendItem(rootId, *it); - ResourceGroupManager::ResourceDeclarationList resources = ResourceGroupManager::getSingletonPtr()->getResourceDeclarationList(*it); - for(ResourceGroupManager::ResourceDeclarationList::iterator rit = resources.begin(); rit != resources.end(); ++rit) - { - mTreeControl->AppendItem(groupId, (*rit).resourceName); - } - } - - - SetSizer(mBoxSizer); - Layout(); + mBoxSizer = new wxBoxSizer(wxVERTICAL); + + mTreeControl = new wxTreeCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); + mBoxSizer->Add(mTreeControl, 1, wxEXPAND | wxALL); + + wxTreeItemId rootId = mTreeControl->AddRoot("Resources"); + + StringVector groups = ResourceGroupManager::getSingletonPtr()->getResourceGroups(); + for(StringVector::iterator it = groups.begin(); it != groups.end(); ++it) + { + wxTreeItemId groupId = mTreeControl->AppendItem(rootId, *it); + ResourceGroupManager::ResourceDeclarationList resources = ResourceGroupManager::getSingletonPtr()->getResourceDeclarationList(*it); + for(ResourceGroupManager::ResourceDeclarationList::iterator rit = resources.begin(); rit != resources.end(); ++rit) + { + mTreeControl->AppendItem(groupId, (*rit).resourceName); + } + } + + + SetSizer(mBoxSizer); + Layout(); } ResourcePanel::~ResourcePanel() diff --git a/Tools/MaterialEditor/MaterialEditor/src/RootEventPlugin.cpp b/Tools/MaterialEditor/MaterialEditor/src/RootEventPlugin.cpp index 1e65d51ee3a..b24448dbeee 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/RootEventPlugin.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/RootEventPlugin.cpp @@ -33,17 +33,17 @@ template<> RootEventPlugin* Ogre::Singleton::msSingleton = 0; RootEventPlugin& RootEventPlugin::getSingleton(void) { - assert( msSingleton ); return ( *msSingleton ); + assert( msSingleton ); return ( *msSingleton ); } RootEventPlugin* RootEventPlugin::getSingletonPtr(void) { - return msSingleton; + return msSingleton; } RootEventPlugin::RootEventPlugin() { - registerEvents(); + registerEvents(); } RootEventPlugin::~RootEventPlugin() @@ -52,7 +52,7 @@ RootEventPlugin::~RootEventPlugin() const String& RootEventPlugin::getName() const { - return "Root Event Plugin"; + return "Root Event Plugin"; } void RootEventPlugin::install() @@ -61,12 +61,12 @@ void RootEventPlugin::install() void RootEventPlugin::initialise() { - fireEvent(Initialized, RootEventArgs()); + fireEvent(Initialized, RootEventArgs()); } void RootEventPlugin::shutdown() { - fireEvent(Shutdown, RootEventArgs()); + fireEvent(Shutdown, RootEventArgs()); } void RootEventPlugin::uninstall() @@ -74,6 +74,6 @@ void RootEventPlugin::uninstall() } void RootEventPlugin::registerEvents() { - registerEvent(Initialized); - registerEvent(Shutdown); + registerEvent(Initialized); + registerEvent(Shutdown); } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/ScintillaEditor.cpp b/Tools/MaterialEditor/MaterialEditor/src/ScintillaEditor.cpp index fa50908d573..db77d44c2b6 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/ScintillaEditor.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/ScintillaEditor.cpp @@ -34,115 +34,115 @@ using Ogre::DataStreamPtr; using Ogre::FileStreamDataStream; BEGIN_EVENT_TABLE(ScintillaEditor, wxScintilla) - EVT_SIZE (ScintillaEditor::OnSize) - // Scintilla - EVT_SCI_MARGINCLICK (-1, ScintillaEditor::OnMarginClick) - EVT_SCI_CHARADDED (-1, ScintillaEditor::OnCharAdded) - EVT_SCI_UPDATEUI(-1, ScintillaEditor::OnUpdateUI) + EVT_SIZE (ScintillaEditor::OnSize) + // Scintilla + EVT_SCI_MARGINCLICK (-1, ScintillaEditor::OnMarginClick) + EVT_SCI_CHARADDED (-1, ScintillaEditor::OnCharAdded) + EVT_SCI_UPDATEUI(-1, ScintillaEditor::OnUpdateUI) END_EVENT_TABLE() ScintillaEditor::ScintillaEditor(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) : wxScintilla (parent, id, pos, size, style), mDirty(false) { - registerEvent(FocusedWordChanged); - - setControl(this); - - mLineNumID = 0; - mLineNumMargin = TextWidth(wxSCI_STYLE_LINENUMBER, _T("99999")); - mFoldingID = 1; - mFoldingMargin = 16; - mDividerID = 1; - - SetProperty(wxT("fold"), wxT("1")); - SetFoldFlags(16); - SetMarginType(mFoldingID, wxSCI_MARGIN_SYMBOL); - SetMarginMask(mFoldingID, wxSCI_MASK_FOLDERS); - SetMarginSensitive(mFoldingID, true); - SetMarginWidth(mFoldingID, mFoldingMargin); - - MarkerDefine(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_BOXMINUS); - MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_BOXPLUS); - MarkerSetForeground(wxSCI_MARKNUM_FOLDER, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDER, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_VLINE); - MarkerSetForeground(wxSCI_MARKNUM_FOLDERSUB, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDERSUB, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_LCORNER); - MarkerSetForeground(wxSCI_MARKNUM_FOLDERTAIL, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDERTAIL, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_BOXPLUSCONNECTED); - MarkerSetForeground(wxSCI_MARKNUM_FOLDEREND, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDEREND, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_BOXMINUSCONNECTED); - MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPENMID, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPENMID, wxColour(0x80, 0x80, 0x80)); - MarkerDefine(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_TCORNER); - MarkerSetForeground(wxSCI_MARKNUM_FOLDERMIDTAIL, wxColour(0xff, 0xff, 0xff)); - MarkerSetBackground(wxSCI_MARKNUM_FOLDERMIDTAIL, wxColour(0x80, 0x80, 0x80)); - - // Set defaults, these should eventually be set via user prefs - SetViewEOL(false); - SetIndentationGuides(false); - SetMarginWidth(mLineNumID, mLineNumMargin); - //SetMarginWidth(mFoldingID, mFoldingMargin); - //SetMarginSensitive(mFoldingID, true); - SetEdgeMode(wxSCI_EDGE_LINE); - //SetViewWhiteSpace(wxSCI_WS_VISIBLEALWAYS); - SetOvertype(false); - SetReadOnly(false); - SetWrapMode(wxSCI_WRAP_NONE); - - wxFont font(10, wxTELETYPE, wxNORMAL, wxNORMAL); - StyleSetFont(wxSCI_STYLE_DEFAULT, font); - StyleSetForeground(wxSCI_STYLE_DEFAULT, wxColour(wxT("BLACK"))); - StyleSetBackground(wxSCI_STYLE_DEFAULT, wxColour(wxT("WHITE"))); - StyleSetForeground(wxSCI_STYLE_LINENUMBER, wxColour(wxT("DARK BLUE"))); - StyleSetBackground(wxSCI_STYLE_LINENUMBER, wxColour(wxT("WHITE"))); - StyleSetForeground(wxSCI_STYLE_INDENTGUIDE, wxColour(wxT("DARK GREY"))); - - // Brace Hilighting - StyleSetBackground(wxSCI_STYLE_BRACELIGHT, wxColour(wxT("GREEN"))); - StyleSetBold(wxSCI_STYLE_BRACELIGHT, true); - StyleSetBold(wxSCI_STYLE_BRACEBAD, true); - - // Call Tips - CallTipSetBackground(wxColor(255, 255, 225)); - CallTipSetForeground(wxColor(128, 128, 128)); - CallTipSetForegroundHighlight(wxColor(0, 0, 0)); - - SetTabWidth(4); - SetUseTabs(false); - SetTabIndents(true); - SetBackSpaceUnIndents(true); - SetIndent(4); - - // Set visibility - SetVisiblePolicy(wxSCI_VISIBLE_STRICT | wxSCI_VISIBLE_SLOP, 1); - SetXCaretPolicy(wxSCI_CARET_EVEN | wxSCI_VISIBLE_STRICT | wxSCI_CARET_SLOP, 1); - SetYCaretPolicy(wxSCI_CARET_EVEN | wxSCI_VISIBLE_STRICT | wxSCI_CARET_SLOP, 1); - - SetCaretLineVisible(true); - SetCaretLineBackground(wxColour(225, 235, 224)); - - // Markers - //MarkerDefine(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_BOXPLUS); - //MarkerSetBackground(wxSCI_MARKNUM_FOLDER, wxColour(_T("BLACK"))); - //MarkerSetForeground(wxSCI_MARKNUM_FOLDER, wxColour(_T("WHITE"))); - //MarkerDefine(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_BOXMINUS); - //MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(_T("BLACK"))); - //MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(_T("WHITE"))); - //MarkerDefine(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_EMPTY); - //MarkerDefine(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_SHORTARROW); - //MarkerDefine(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_ARROWDOWN); - //MarkerDefine(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_EMPTY); - //MarkerDefine(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_EMPTY); - - UsePopUp(0); - SetLayoutCache(wxSCI_CACHE_PAGE); - SetBufferedDraw(1); + registerEvent(FocusedWordChanged); + + setControl(this); + + mLineNumID = 0; + mLineNumMargin = TextWidth(wxSCI_STYLE_LINENUMBER, _T("99999")); + mFoldingID = 1; + mFoldingMargin = 16; + mDividerID = 1; + + SetProperty(wxT("fold"), wxT("1")); + SetFoldFlags(16); + SetMarginType(mFoldingID, wxSCI_MARGIN_SYMBOL); + SetMarginMask(mFoldingID, wxSCI_MASK_FOLDERS); + SetMarginSensitive(mFoldingID, true); + SetMarginWidth(mFoldingID, mFoldingMargin); + + MarkerDefine(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_BOXMINUS); + MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_BOXPLUS); + MarkerSetForeground(wxSCI_MARKNUM_FOLDER, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDER, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_VLINE); + MarkerSetForeground(wxSCI_MARKNUM_FOLDERSUB, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDERSUB, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_LCORNER); + MarkerSetForeground(wxSCI_MARKNUM_FOLDERTAIL, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDERTAIL, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_BOXPLUSCONNECTED); + MarkerSetForeground(wxSCI_MARKNUM_FOLDEREND, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDEREND, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_BOXMINUSCONNECTED); + MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPENMID, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPENMID, wxColour(0x80, 0x80, 0x80)); + MarkerDefine(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_TCORNER); + MarkerSetForeground(wxSCI_MARKNUM_FOLDERMIDTAIL, wxColour(0xff, 0xff, 0xff)); + MarkerSetBackground(wxSCI_MARKNUM_FOLDERMIDTAIL, wxColour(0x80, 0x80, 0x80)); + + // Set defaults, these should eventually be set via user prefs + SetViewEOL(false); + SetIndentationGuides(false); + SetMarginWidth(mLineNumID, mLineNumMargin); + //SetMarginWidth(mFoldingID, mFoldingMargin); + //SetMarginSensitive(mFoldingID, true); + SetEdgeMode(wxSCI_EDGE_LINE); + //SetViewWhiteSpace(wxSCI_WS_VISIBLEALWAYS); + SetOvertype(false); + SetReadOnly(false); + SetWrapMode(wxSCI_WRAP_NONE); + + wxFont font(10, wxTELETYPE, wxNORMAL, wxNORMAL); + StyleSetFont(wxSCI_STYLE_DEFAULT, font); + StyleSetForeground(wxSCI_STYLE_DEFAULT, wxColour(wxT("BLACK"))); + StyleSetBackground(wxSCI_STYLE_DEFAULT, wxColour(wxT("WHITE"))); + StyleSetForeground(wxSCI_STYLE_LINENUMBER, wxColour(wxT("DARK BLUE"))); + StyleSetBackground(wxSCI_STYLE_LINENUMBER, wxColour(wxT("WHITE"))); + StyleSetForeground(wxSCI_STYLE_INDENTGUIDE, wxColour(wxT("DARK GREY"))); + + // Brace Hilighting + StyleSetBackground(wxSCI_STYLE_BRACELIGHT, wxColour(wxT("GREEN"))); + StyleSetBold(wxSCI_STYLE_BRACELIGHT, true); + StyleSetBold(wxSCI_STYLE_BRACEBAD, true); + + // Call Tips + CallTipSetBackground(wxColor(255, 255, 225)); + CallTipSetForeground(wxColor(128, 128, 128)); + CallTipSetForegroundHighlight(wxColor(0, 0, 0)); + + SetTabWidth(4); + SetUseTabs(false); + SetTabIndents(true); + SetBackSpaceUnIndents(true); + SetIndent(4); + + // Set visibility + SetVisiblePolicy(wxSCI_VISIBLE_STRICT | wxSCI_VISIBLE_SLOP, 1); + SetXCaretPolicy(wxSCI_CARET_EVEN | wxSCI_VISIBLE_STRICT | wxSCI_CARET_SLOP, 1); + SetYCaretPolicy(wxSCI_CARET_EVEN | wxSCI_VISIBLE_STRICT | wxSCI_CARET_SLOP, 1); + + SetCaretLineVisible(true); + SetCaretLineBackground(wxColour(225, 235, 224)); + + // Markers + //MarkerDefine(wxSCI_MARKNUM_FOLDER, wxSCI_MARK_BOXPLUS); + //MarkerSetBackground(wxSCI_MARKNUM_FOLDER, wxColour(_T("BLACK"))); + //MarkerSetForeground(wxSCI_MARKNUM_FOLDER, wxColour(_T("WHITE"))); + //MarkerDefine(wxSCI_MARKNUM_FOLDEROPEN, wxSCI_MARK_BOXMINUS); + //MarkerSetBackground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(_T("BLACK"))); + //MarkerSetForeground(wxSCI_MARKNUM_FOLDEROPEN, wxColour(_T("WHITE"))); + //MarkerDefine(wxSCI_MARKNUM_FOLDERSUB, wxSCI_MARK_EMPTY); + //MarkerDefine(wxSCI_MARKNUM_FOLDEREND, wxSCI_MARK_SHORTARROW); + //MarkerDefine(wxSCI_MARKNUM_FOLDEROPENMID, wxSCI_MARK_ARROWDOWN); + //MarkerDefine(wxSCI_MARKNUM_FOLDERMIDTAIL, wxSCI_MARK_EMPTY); + //MarkerDefine(wxSCI_MARKNUM_FOLDERTAIL, wxSCI_MARK_EMPTY); + + UsePopUp(0); + SetLayoutCache(wxSCI_CACHE_PAGE); + SetBufferedDraw(1); } ScintillaEditor::~ScintillaEditor() @@ -151,460 +151,460 @@ ScintillaEditor::~ScintillaEditor() void ScintillaEditor::activate() { - // TODO: Connect to update ui event + // TODO: Connect to update ui event } void ScintillaEditor::deactivate() { - // TODO: Disconnect from update ui event + // TODO: Disconnect from update ui event } bool ScintillaEditor::isDirty() { - return mDirty; + return mDirty; } void ScintillaEditor::save() { - if (!mDirty) return; - if(!mFileName || mFileName.length() == 0) - { - saveAs(); - return; - } + if (!mDirty) return; + if(!mFileName || mFileName.length() == 0) + { + saveAs(); + return; + } - if(SaveFile(mFileName)) - { - setDirty(false); - int index = (int)mFileName.find_last_of('\\'); - if(index == -1) index = (int)mFileName.find_last_of('/'); - setName((index != -1) ? mFileName.substr(index + 1, mFileName.Length()) : mFileName); - } + if(SaveFile(mFileName)) + { + setDirty(false); + int index = (int)mFileName.find_last_of('\\'); + if(index == -1) index = (int)mFileName.find_last_of('/'); + setName((index != -1) ? mFileName.substr(index + 1, mFileName.Length()) : mFileName); + } } void ScintillaEditor::saveAs() { - if (!mDirty) return; + if (!mDirty) return; - // Get file name - wxFileDialog dlg (this, _T("Save file"), _T(""), _T(""), _T("Any file (*)|*"), - wxSAVE | wxOVERWRITE_PROMPT); - if (dlg.ShowModal() != wxID_OK) return; - mFileName = dlg.GetPath(); + // Get file name + wxFileDialog dlg (this, _T("Save file"), _T(""), _T(""), _T("Any file (*)|*"), + wxSAVE | wxOVERWRITE_PROMPT); + if (dlg.ShowModal() != wxID_OK) return; + mFileName = dlg.GetPath(); - save(); + save(); } bool ScintillaEditor::isSaveAsAllowed() { - return true; + return true; } bool ScintillaEditor::isRedoable() { - return CanRedo(); + return CanRedo(); } void ScintillaEditor::redo() { - if(!CanRedo()) return; - - Redo(); + if(!CanRedo()) return; + + Redo(); } bool ScintillaEditor::isUndoable() { - return CanUndo(); + return CanUndo(); } void ScintillaEditor::undo() { - if(!CanUndo()) return; - - Undo(); + if(!CanUndo()) return; + + Undo(); } bool ScintillaEditor::isCuttable() { - return GetReadOnly() || (GetSelectionEnd() - GetSelectionStart() <= 0); + return GetReadOnly() || (GetSelectionEnd() - GetSelectionStart() <= 0); } void ScintillaEditor::cut() { - if(GetReadOnly() || (GetSelectionEnd() - GetSelectionStart() <= 0)) return; - - Cut(); + if(GetReadOnly() || (GetSelectionEnd() - GetSelectionStart() <= 0)) return; + + Cut(); } bool ScintillaEditor::isCopyable() { - return GetReadOnly() || (GetSelectionEnd() - GetSelectionStart() <= 0); + return GetReadOnly() || (GetSelectionEnd() - GetSelectionStart() <= 0); } void ScintillaEditor::copy() { - if(GetSelectionEnd() - GetSelectionStart() <= 0) return; - - Copy(); + if(GetSelectionEnd() - GetSelectionStart() <= 0) return; + + Copy(); } bool ScintillaEditor::isPastable() { - return CanPaste(); + return CanPaste(); } void ScintillaEditor::paste() { - if(!CanPaste()) return; - - Paste(); + if(!CanPaste()) return; + + Paste(); } bool ScintillaEditor::loadFile() { - // Get filname - if (!mFileName) - { - wxFileDialog dlg (this, _T("Open file"), _T(""), _T(""), - _T("Any file (*)|*"), wxOPEN | wxFILE_MUST_EXIST | wxCHANGE_DIR); - if (dlg.ShowModal() != wxID_OK) return false; - mFileName = dlg.GetPath(); - } + // Get filname + if (!mFileName) + { + wxFileDialog dlg (this, _T("Open file"), _T(""), _T(""), + _T("Any file (*)|*"), wxOPEN | wxFILE_MUST_EXIST | wxCHANGE_DIR); + if (dlg.ShowModal() != wxID_OK) return false; + mFileName = dlg.GetPath(); + } - // Load file - return LoadFile(mFileName); + // Load file + return LoadFile(mFileName); } bool ScintillaEditor::loadFile(const wxString &filename) { - // Load file in edit and clear undo - if (!filename.IsEmpty()) mFileName = filename; - if (!wxScintilla::LoadFile(mFileName)) return false; + // Load file in edit and clear undo + if (!filename.IsEmpty()) mFileName = filename; + if (!wxScintilla::LoadFile(mFileName)) return false; - return true; + return true; } void ScintillaEditor::loadKeywords(wxString& path) { - std::ifstream fp; - fp.open(path, std::ios::in | std::ios::binary); - if(fp) - { - DataStreamPtr stream(new FileStreamDataStream(path.c_str(), &fp, false)); - - int index = -1; - String line; - wxString keywords; - while(!stream->eof()) - { - line = stream->getLine(); - - // Ignore blank lines and comments (comment lines start with '#') - if(line.length() > 0 && line.at(0) != '#') - { - if(line.at(0) == '[') - { - if(index != -1) - { - SetKeyWords(index, keywords); - keywords.clear(); - } - - ++index; - } - else - { - keywords.Append(line); - keywords.Append(" "); - } - } - } - - SetKeyWords(index, keywords); - } + std::ifstream fp; + fp.open(path, std::ios::in | std::ios::binary); + if(fp) + { + DataStreamPtr stream(new FileStreamDataStream(path.c_str(), &fp, false)); + + int index = -1; + String line; + wxString keywords; + while(!stream->eof()) + { + line = stream->getLine(); + + // Ignore blank lines and comments (comment lines start with '#') + if(line.length() > 0 && line.at(0) != '#') + { + if(line.at(0) == '[') + { + if(index != -1) + { + SetKeyWords(index, keywords); + keywords.clear(); + } + + ++index; + } + else + { + keywords.Append(line); + keywords.Append(" "); + } + } + } + + SetKeyWords(index, keywords); + } } CallTipManager& ScintillaEditor::getCallTipManager() { - return mCallTipManager; + return mCallTipManager; } DocManager& ScintillaEditor::getDocManager() { - return mDocManager; + return mDocManager; } wxString ScintillaEditor::getSurroundingWord(int pos /* = -1 */) { - if(pos == -1) pos = GetCurrentPos(); + if(pos == -1) pos = GetCurrentPos(); - int lineNum = GetCurrentLine(); - wxString word(""); - if(lineNum != -1) - { - wxString line = GetLine(lineNum); + int lineNum = GetCurrentLine(); + wxString word(""); + if(lineNum != -1) + { + wxString line = GetLine(lineNum); - wxChar ch; - while(pos) - { - ch = GetCharAt(--pos); - if(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '.' || ch == '(' || ch == ',' || ch == ';') break; - } + wxChar ch; + while(pos) + { + ch = GetCharAt(--pos); + if(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '.' || ch == '(' || ch == ',' || ch == ';') break; + } - if(!pos) return word; + if(!pos) return word; - while(pos < line.Length()) - { - ch = GetCharAt(++pos); - if(ch != ' ' && ch != ')' && ch!= '\n' && ch!= '\r' && ch !='\t' && ch != '.' && ch != '(' && ch != ')' && ch != ';' && ch != ',') word += ch; - else break; - } - } + while(pos < line.Length()) + { + ch = GetCharAt(++pos); + if(ch != ' ' && ch != ')' && ch!= '\n' && ch!= '\r' && ch !='\t' && ch != '.' && ch != '(' && ch != ')' && ch != ';' && ch != ',') word += ch; + else break; + } + } - return word; + return word; } wxChar ScintillaEditor::getLastNonWhitespaceChar(int position /* = -1 */) { - if (position == -1) - position = GetCurrentPos(); - - int count = 0; // Used to count the number of blank lines - bool foundlf = false; // For the rare case of CR's without LF's - while (position) - { - wxChar c = GetCharAt(--position); - int style = GetStyleAt(position); - bool inComment = style == wxSCI_C_COMMENT || - style == wxSCI_C_COMMENTDOC || - style == wxSCI_C_COMMENTDOCKEYWORD || - style == wxSCI_C_COMMENTDOCKEYWORDERROR || - style == wxSCI_C_COMMENTLINE || - style == wxSCI_C_COMMENTLINEDOC; - if (c == wxT('\n')) - { - count++; - foundlf = true; - } - else if (c == wxT('\r') && !foundlf) - count++; - else - foundlf = false; - if (count > 1) return 0; // Don't over-indent - if (!inComment && c != wxT(' ') && c != wxT('\t') && c != wxT('\n') && c != wxT('\r')) - return c; - } - - return 0; + if (position == -1) + position = GetCurrentPos(); + + int count = 0; // Used to count the number of blank lines + bool foundlf = false; // For the rare case of CR's without LF's + while (position) + { + wxChar c = GetCharAt(--position); + int style = GetStyleAt(position); + bool inComment = style == wxSCI_C_COMMENT || + style == wxSCI_C_COMMENTDOC || + style == wxSCI_C_COMMENTDOCKEYWORD || + style == wxSCI_C_COMMENTDOCKEYWORDERROR || + style == wxSCI_C_COMMENTLINE || + style == wxSCI_C_COMMENTLINEDOC; + if (c == wxT('\n')) + { + count++; + foundlf = true; + } + else if (c == wxT('\r') && !foundlf) + count++; + else + foundlf = false; + if (count > 1) return 0; // Don't over-indent + if (!inComment && c != wxT(' ') && c != wxT('\t') && c != wxT('\n') && c != wxT('\r')) + return c; + } + + return 0; } wxString ScintillaEditor::getLineIndentString(int line) { - int currLine = (line == -1) ? LineFromPosition(GetCurrentPos()) : line; + int currLine = (line == -1) ? LineFromPosition(GetCurrentPos()) : line; - wxString text = GetLine(currLine); - int length = (int)text.Length(); - wxString indent; - for (int i = 0; i < length; ++i) - { - if (text[i] == wxT(' ') || text[i] == wxT('\t')) - indent << text[i]; - else - break; - } + wxString text = GetLine(currLine); + int length = (int)text.Length(); + wxString indent; + for (int i = 0; i < length; ++i) + { + if (text[i] == wxT(' ') || text[i] == wxT('\t')) + indent << text[i]; + else + break; + } - return indent; + return indent; } int ScintillaEditor::findBlockStart(int position, wxChar blockStart, wxChar blockEnd, bool skipNested /* = true */) { - int level = 0; - wxChar ch = GetCharAt(position); - while (ch) - { - if (ch == blockEnd) - ++level; + int level = 0; + wxChar ch = GetCharAt(position); + while (ch) + { + if (ch == blockEnd) + ++level; - else if (ch == blockStart) - { - if (level == 0) return position; - --level; - } + else if (ch == blockStart) + { + if (level == 0) return position; + --level; + } - --position; + --position; - ch = GetCharAt(position); - } + ch = GetCharAt(position); + } - return -1; + return -1; } void ScintillaEditor::highlightBraces() { - int p = GetCurrentPos(); - int c1 = GetCharAt(p); - int c2 = (p > 1 ? GetCharAt(p - 1) : 0); - if(c2 == '(' || c2 == ')' || c1 == '(' || c1 == ')') - { - int start = (c2 == '(' || c2 == ')') ? p - 1 : p; - int end = BraceMatch(start); - if(end == wxSCI_INVALID_POSITION) - { - BraceBadLight(start); - } - else - { - BraceHighlight(start, end); - } - } - else if(c2 == '{' || c2 == '}' || c1 == '{' || c1 == '}') - { - int start = (c2 == '{' || c2 == '}') ? p - 1 : p; - int end = BraceMatch(start); - if(end == wxSCI_INVALID_POSITION) - { - BraceBadLight(start); - } - else - { - BraceHighlight(start, end); - } - } - else - { - BraceBadLight(wxSCI_INVALID_POSITION); - } - /* - int currPos = GetCurrentPos(); - int newPos = BraceMatch(currPos); - if (newPos == wxSCI_INVALID_POSITION) - { - if(currPos > 0) - newPos = BraceMatch(--currPos); - } - - wxChar ch = GetCharAt(currPos); - if (ch == wxT('{') || ch == wxT('[') || ch == wxT('(') || - ch == wxT('}') || ch == wxT(']') || ch == wxT(')')) - { - if (newPos != wxSCI_INVALID_POSITION) - { - BraceHighlight(currPos, newPos); - } - else - { - BraceBadLight(currPos); - } - } - else BraceHighlight(-1, -1); - - Refresh(false); - */ + int p = GetCurrentPos(); + int c1 = GetCharAt(p); + int c2 = (p > 1 ? GetCharAt(p - 1) : 0); + if(c2 == '(' || c2 == ')' || c1 == '(' || c1 == ')') + { + int start = (c2 == '(' || c2 == ')') ? p - 1 : p; + int end = BraceMatch(start); + if(end == wxSCI_INVALID_POSITION) + { + BraceBadLight(start); + } + else + { + BraceHighlight(start, end); + } + } + else if(c2 == '{' || c2 == '}' || c1 == '{' || c1 == '}') + { + int start = (c2 == '{' || c2 == '}') ? p - 1 : p; + int end = BraceMatch(start); + if(end == wxSCI_INVALID_POSITION) + { + BraceBadLight(start); + } + else + { + BraceHighlight(start, end); + } + } + else + { + BraceBadLight(wxSCI_INVALID_POSITION); + } + /* + int currPos = GetCurrentPos(); + int newPos = BraceMatch(currPos); + if (newPos == wxSCI_INVALID_POSITION) + { + if(currPos > 0) + newPos = BraceMatch(--currPos); + } + + wxChar ch = GetCharAt(currPos); + if (ch == wxT('{') || ch == wxT('[') || ch == wxT('(') || + ch == wxT('}') || ch == wxT(']') || ch == wxT(')')) + { + if (newPos != wxSCI_INVALID_POSITION) + { + BraceHighlight(currPos, newPos); + } + else + { + BraceBadLight(currPos); + } + } + else BraceHighlight(-1, -1); + + Refresh(false); + */ } //---------------------------------------------------------------------------- // Common event handlers void ScintillaEditor::OnSize(wxSizeEvent& event) { - int x = GetClientSize().x;// + GetMarginLeft(); //mLineNumMargin + mFoldingMargin; + int x = GetClientSize().x;// + GetMarginLeft(); //mLineNumMargin + mFoldingMargin; - if (x > 0) SetScrollWidth(x); + if (x > 0) SetScrollWidth(x); - event.Skip(); + event.Skip(); } void ScintillaEditor::OnMarginClick(wxScintillaEvent &event) { - if (event.GetMargin() == 1) - { - int lineClick = LineFromPosition(event.GetPosition()); - int levelClick = GetFoldLevel(lineClick); - if ((levelClick & wxSCI_FOLDLEVELHEADERFLAG) > 0) - { - ToggleFold (lineClick); - } - } + if (event.GetMargin() == 1) + { + int lineClick = LineFromPosition(event.GetPosition()); + int levelClick = GetFoldLevel(lineClick); + if ((levelClick & wxSCI_FOLDLEVELHEADERFLAG) > 0) + { + ToggleFold (lineClick); + } + } } void ScintillaEditor::OnCharAdded(wxScintillaEvent &event) { - char ch = event.GetKey(); - int currentLine = GetCurrentLine(); - int pos = GetCurrentPos(); - - if (ch == wxT('\n') && currentLine > 0) - { - BeginUndoAction(); - - wxString indent = getLineIndentString(currentLine - 1); - - wxChar b = getLastNonWhitespaceChar(); - if(b == wxT('{')) - { - if(GetUseTabs()) - indent << wxT("\t"); - else - indent << wxT(" "); - } - - InsertText(pos, indent); - GotoPos((int)(pos + indent.Length())); - ChooseCaretX(); - - EndUndoAction(); - } - else if(ch == wxT('}')) - { - BeginUndoAction(); - - wxString line = GetLine(currentLine); - line.Trim(false); - line.Trim(true); - if(line.Matches(wxT("}"))) - { - pos = GetCurrentPos() - 2; - pos = findBlockStart(pos, wxT('{'), wxT('}')); - - if(pos != -1) - { - wxString indent = getLineIndentString(LineFromPosition(pos)); - indent << wxT('}'); - DelLineLeft(); - DelLineRight(); - pos = GetCurrentPos(); - InsertText(pos, indent); - GotoPos((int)(pos + indent.Length())); - ChooseCaretX(); - } - } - - EndUndoAction(); - } - - setDirty(true); + char ch = event.GetKey(); + int currentLine = GetCurrentLine(); + int pos = GetCurrentPos(); + + if (ch == wxT('\n') && currentLine > 0) + { + BeginUndoAction(); + + wxString indent = getLineIndentString(currentLine - 1); + + wxChar b = getLastNonWhitespaceChar(); + if(b == wxT('{')) + { + if(GetUseTabs()) + indent << wxT("\t"); + else + indent << wxT(" "); + } + + InsertText(pos, indent); + GotoPos((int)(pos + indent.Length())); + ChooseCaretX(); + + EndUndoAction(); + } + else if(ch == wxT('}')) + { + BeginUndoAction(); + + wxString line = GetLine(currentLine); + line.Trim(false); + line.Trim(true); + if(line.Matches(wxT("}"))) + { + pos = GetCurrentPos() - 2; + pos = findBlockStart(pos, wxT('{'), wxT('}')); + + if(pos != -1) + { + wxString indent = getLineIndentString(LineFromPosition(pos)); + indent << wxT('}'); + DelLineLeft(); + DelLineRight(); + pos = GetCurrentPos(); + InsertText(pos, indent); + GotoPos((int)(pos + indent.Length())); + ChooseCaretX(); + } + } + + EndUndoAction(); + } + + setDirty(true); } void ScintillaEditor::OnUpdateUI(wxScintillaEvent &event) { - highlightBraces(); + highlightBraces(); - int pos = GetCurrentPos(); - if(pos != mLastPos) - { - mLastPos = pos; - wxString word = getSurroundingWord(pos); - if(word != mLastWord) - { - mLastWord = word; - fireEvent(FocusedWordChanged, ScintillaEditorEventArgs(this, word)); - } - } + int pos = GetCurrentPos(); + if(pos != mLastPos) + { + mLastPos = pos; + wxString word = getSurroundingWord(pos); + if(word != mLastWord) + { + mLastWord = word; + fireEvent(FocusedWordChanged, ScintillaEditorEventArgs(this, word)); + } + } } void ScintillaEditor::setDirty(const bool dirty) { - if(mDirty == dirty) return; - mDirty = dirty; - //fireEvent(DirtyStateChanged, new EditorEventArgs(this, getEditorInput())); + if(mDirty == dirty) return; + mDirty = dirty; + //fireEvent(DirtyStateChanged, new EditorEventArgs(this, getEditorInput())); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/SelectionEventArgs.cpp b/Tools/MaterialEditor/MaterialEditor/src/SelectionEventArgs.cpp index 5077b0b4acf..5552c4eeb4a 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/SelectionEventArgs.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/SelectionEventArgs.cpp @@ -42,13 +42,13 @@ SelectionEventArgs::SelectionEventArgs(boost::any& source, SelectionList& select SelectionEventArgs::~SelectionEventArgs() { } - + const boost::any& SelectionEventArgs::getSource() const { - return mSource; + return mSource; } const SelectionList& SelectionEventArgs::getSelection() const { - return mSelection; + return mSelection; } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/SelectionService.cpp b/Tools/MaterialEditor/MaterialEditor/src/SelectionService.cpp index 0b0c1fa30d9..e452e9210a5 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/SelectionService.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/SelectionService.cpp @@ -33,17 +33,17 @@ template<> SelectionService* Ogre::Singleton::msSingleton = 0; SelectionService& SelectionService::getSingleton(void) { - assert( msSingleton ); return ( *msSingleton ); + assert( msSingleton ); return ( *msSingleton ); } SelectionService* SelectionService::getSingletonPtr(void) { - return msSingleton; + return msSingleton; } SelectionService::SelectionService() { - registerEvents(); + registerEvents(); } SelectionService::~SelectionService() @@ -52,27 +52,27 @@ SelectionService::~SelectionService() void SelectionService::registerEvents() { - registerEvent(SelectionChanged); + registerEvent(SelectionChanged); } const SelectionList& SelectionService::getSelection() const { - return mSelection; + return mSelection; } void SelectionService::setSelection(boost::any& sel) { - mSelection.clear(); - - mSelection.push_back(sel); - - fireEvent(SelectionChanged, SelectionEventArgs(mSelection)); + mSelection.clear(); + + mSelection.push_back(sel); + + fireEvent(SelectionChanged, SelectionEventArgs(mSelection)); } void SelectionService::setSelection(const SelectionList& sel) { - mSelection = sel; + mSelection = sel; - fireEvent(SelectionChanged, SelectionEventArgs(mSelection)); + fireEvent(SelectionChanged, SelectionEventArgs(mSelection)); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/TechniqueController.cpp b/Tools/MaterialEditor/MaterialEditor/src/TechniqueController.cpp index ca5894afeca..69dd0f7c35b 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/TechniqueController.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/TechniqueController.cpp @@ -36,13 +36,13 @@ THE SOFTWARE. TechniqueController::TechniqueController(Technique* technique) : mParentController(NULL), mTechnique(technique) { - registerEvents(); + registerEvents(); } TechniqueController::TechniqueController(MaterialController* parent, Technique* technique) : mParentController(parent), mTechnique(technique) { - registerEvents(); + registerEvents(); } TechniqueController::~TechniqueController() @@ -51,53 +51,53 @@ TechniqueController::~TechniqueController() void TechniqueController::registerEvents() { - registerEvent(NameChanged); - registerEvent(SchemeChanged); - registerEvent(LodIndexChanged); - registerEvent(PassAdded); - registerEvent(PassRemoved); + registerEvent(NameChanged); + registerEvent(SchemeChanged); + registerEvent(LodIndexChanged); + registerEvent(PassAdded); + registerEvent(PassRemoved); } const Technique* TechniqueController::getTechnique() const { - return mTechnique; + return mTechnique; } MaterialController* TechniqueController::getParentController() const { - return mParentController; + return mParentController; } const PassControllerList* TechniqueController::getPassControllers() const { - return &mPassControllers; + return &mPassControllers; } PassController* TechniqueController::createPass(void) { - Pass* pass = mTechnique->createPass(); + Pass* pass = mTechnique->createPass(); - // Create controller - PassController* pc = new PassController(this, pass); - mPassControllers.push_back(pc); + // Create controller + PassController* pc = new PassController(this, pass); + mPassControllers.push_back(pc); - fireEvent(PassAdded, TechniqueEventArgs(this, pc)); + fireEvent(PassAdded, TechniqueEventArgs(this, pc)); - return pc; + return pc; } PassController* TechniqueController::createPass(const String& name) { - Pass* pass = mTechnique->createPass(); - pass->setName(name); + Pass* pass = mTechnique->createPass(); + pass->setName(name); - // Create controller - PassController* pc = new PassController(this, pass); - mPassControllers.push_back(pc); + // Create controller + PassController* pc = new PassController(this, pass); + mPassControllers.push_back(pc); - fireEvent(PassAdded, TechniqueEventArgs(this, pc)); + fireEvent(PassAdded, TechniqueEventArgs(this, pc)); - return pc; + return pc; } void TechniqueController::removeAllPasses(void) @@ -114,191 +114,191 @@ void TechniqueController::movePass(const unsigned short sourceIndex, const unsig void TechniqueController::setName(const String& name) { - mTechnique->setName(name); + mTechnique->setName(name); - fireEvent(NameChanged, TechniqueEventArgs(this)); + fireEvent(NameChanged, TechniqueEventArgs(this)); } void TechniqueController::setSchemeName(const String& schemeName) { - mTechnique->setSchemeName(schemeName); + mTechnique->setSchemeName(schemeName); - fireEvent(SchemeChanged, TechniqueEventArgs(this)); + fireEvent(SchemeChanged, TechniqueEventArgs(this)); } void TechniqueController::setLodIndex(unsigned short index) { - mTechnique->setLodIndex(index); + mTechnique->setLodIndex(index); - fireEvent(LodIndexChanged, TechniqueEventArgs(this)); + fireEvent(LodIndexChanged, TechniqueEventArgs(this)); } void TechniqueController::setAmbient(const ColourValue& ambient) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setAmbient(ambient); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setAmbient(ambient); } void TechniqueController::setAmbient(Real red, Real green, Real blue) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setAmbient(red, green, blue); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setAmbient(red, green, blue); } void TechniqueController::setColourWriteEnabled(bool enabled) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setColourWriteEnabled(enabled); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setColourWriteEnabled(enabled); } void TechniqueController::setCullingMode(CullingMode mode) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setCullingMode(mode); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setCullingMode(mode); } void TechniqueController::setDepthBias(float constantBias, float slopeScaleBias) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setDepthBias(constantBias, slopeScaleBias); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setDepthBias(constantBias, slopeScaleBias); } void TechniqueController::setDepthCheckEnabled(bool enabled) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setDepthCheckEnabled(enabled); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setDepthCheckEnabled(enabled); } void TechniqueController::setDepthFunction(CompareFunction func) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setDepthFunction(func); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setDepthFunction(func); } void TechniqueController::setDepthWriteEnabled(bool enabled) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setDepthWriteEnabled(enabled); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setDepthWriteEnabled(enabled); } void TechniqueController::setDiffuse(const ColourValue& diffuse) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setDiffuse(diffuse); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setDiffuse(diffuse); } void TechniqueController::setDiffuse(Real red, Real green, Real blue, Real alpha) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setDiffuse(red, green, blue, alpha); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setDiffuse(red, green, blue, alpha); } void TechniqueController::setFog(bool overrideScene, FogMode mode /* = FOG_NONE */, const ColourValue& colour /* = ColourValue::White */, Real expDensity /* = 0.001 */, Real linearStart /* = 0.0 */, Real linearEnd /* = 1.0 */) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setFog(overrideScene, mode, colour, expDensity, linearStart, linearEnd); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setFog(overrideScene, mode, colour, expDensity, linearStart, linearEnd); } void TechniqueController::setLightingEnabled(bool enabled) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setLightingEnabled(true); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setLightingEnabled(true); } void TechniqueController::setManualCullingMode(ManualCullingMode mode) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setManualCullingMode(mode); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setManualCullingMode(mode); } void TechniqueController::setPointSize(Real ps) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setPointSize(ps); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setPointSize(ps); } void TechniqueController::setSceneBlending(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setSceneBlending(sourceFactor, destFactor); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setSceneBlending(sourceFactor, destFactor); } void TechniqueController::setSceneBlending(const SceneBlendType sbt) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setSceneBlending(sbt); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setSceneBlending(sbt); } void TechniqueController::setSelfIllumination(const ColourValue& selfIllum) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setSelfIllumination(selfIllum); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setSelfIllumination(selfIllum); } void TechniqueController::setSelfIllumination(Real red, Real green, Real blue) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setSelfIllumination(red, green, blue); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setSelfIllumination(red, green, blue); } void TechniqueController::setShadingMode(ShadeOptions mode) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setShadingMode(mode); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setShadingMode(mode); } void TechniqueController::setShininess(Real val) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setShininess(val); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setShininess(val); } void TechniqueController::setSpecular(const ColourValue& specular) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setSpecular(specular); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setSpecular(specular); } void TechniqueController::setSpecular(Real red, Real green, Real blue, Real alpha) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setSpecular(red, green, blue, alpha); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setSpecular(red, green, blue, alpha); } void TechniqueController::setTextureAnisotropy(unsigned int maxAniso) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setTextureAnisotropy(maxAniso); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setTextureAnisotropy(maxAniso); } void TechniqueController::setTextureFiltering(TextureFilterOptions filterType) { - PassControllerList::iterator it; - for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) - (*it)->setTextureFiltering(filterType); + PassControllerList::iterator it; + for(it = mPassControllers.begin(); it != mPassControllers.end(); ++it) + (*it)->setTextureFiltering(filterType); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/TechniqueEventArgs.cpp b/Tools/MaterialEditor/MaterialEditor/src/TechniqueEventArgs.cpp index be996ef67c0..d306acd862f 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/TechniqueEventArgs.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/TechniqueEventArgs.cpp @@ -42,10 +42,10 @@ TechniqueEventArgs::TechniqueEventArgs(TechniqueController* tc, PassController* TechniqueController* TechniqueEventArgs::getTechniqueController() const { - return mTechniqueController; + return mTechniqueController; } PassController* TechniqueEventArgs::getPassController() const { - return mPassController; + return mPassController; } diff --git a/Tools/MaterialEditor/MaterialEditor/src/TechniquePage.cpp b/Tools/MaterialEditor/MaterialEditor/src/TechniquePage.cpp index 04333469ddd..c3577984b46 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/TechniquePage.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/TechniquePage.cpp @@ -40,26 +40,26 @@ THE SOFTWARE. const long ID_MATERIAL_COMBO_BOX = wxNewId(); BEGIN_EVENT_TABLE(TechniquePage, wxWizardPageSimple) - EVT_CHOICE(ID_MATERIAL_COMBO_BOX, TechniquePage::OnProjectSelected) + EVT_CHOICE(ID_MATERIAL_COMBO_BOX, TechniquePage::OnProjectSelected) END_EVENT_TABLE() TechniquePage::TechniquePage(wxWizard* parent) : wxWizardPageSimple(parent), mProject(NULL), mMaterial(NULL) { - createPage(); + createPage(); } TechniquePage::TechniquePage(wxWizard* parent, Project* project) : wxWizardPageSimple(parent), mProject(project), mMaterial(NULL) { - createPage(); + createPage(); } TechniquePage::TechniquePage(wxWizard* parent, Project* project, MaterialController* mc) : wxWizardPageSimple(parent), mProject(project), mMaterial(mc) { - createPage(); + createPage(); } @@ -69,89 +69,89 @@ TechniquePage::~TechniquePage() void TechniquePage::createPage() { - mSizer = new wxBoxSizer(wxVERTICAL); + mSizer = new wxBoxSizer(wxVERTICAL); - // Project Label - mProjectLabel = new wxStaticText(this, wxID_ANY, wxT("Project:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mProjectLabel, 0, wxALL, 5); + // Project Label + mProjectLabel = new wxStaticText(this, wxID_ANY, wxT("Project:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mProjectLabel, 0, wxALL, 5); - // Project Combo Box - wxArrayString projectNames; - const ProjectList* projects = Workspace::getSingletonPtr()->getProjects(); - for(ProjectList::const_iterator it = projects->begin(); it != projects->end(); ++it) - projectNames.Add((*it)->getName().c_str()); + // Project Combo Box + wxArrayString projectNames; + const ProjectList* projects = Workspace::getSingletonPtr()->getProjects(); + for(ProjectList::const_iterator it = projects->begin(); it != projects->end(); ++it) + projectNames.Add((*it)->getName().c_str()); - // TODO: Select first Project - mProjectComboBox = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, projectNames, wxCB_DROPDOWN); - mSizer->Add(mProjectComboBox, 0, wxALL | wxEXPAND, 5); + // TODO: Select first Project + mProjectComboBox = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, projectNames, wxCB_DROPDOWN); + mSizer->Add(mProjectComboBox, 0, wxALL | wxEXPAND, 5); - // Material Label - mMaterialLabel = new wxStaticText(this, wxID_ANY, wxT("Material:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mMaterialLabel, 0, wxALL, 5); + // Material Label + mMaterialLabel = new wxStaticText(this, wxID_ANY, wxT("Material:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mMaterialLabel, 0, wxALL, 5); - // Material Combo Box - mMaterialComboBox = new wxComboBox(this, ID_MATERIAL_COMBO_BOX); - mSizer->Add(mMaterialComboBox, 0, wxALL | wxEXPAND, 5); + // Material Combo Box + mMaterialComboBox = new wxComboBox(this, ID_MATERIAL_COMBO_BOX); + mSizer->Add(mMaterialComboBox, 0, wxALL | wxEXPAND, 5); - // Name Label - mNameLabel = new wxStaticText(this, wxID_ANY, wxT("Name:"), wxDefaultPosition, wxDefaultSize, 0); - mSizer->Add(mNameLabel, 0, wxALL, 5); + // Name Label + mNameLabel = new wxStaticText(this, wxID_ANY, wxT("Name:"), wxDefaultPosition, wxDefaultSize, 0); + mSizer->Add(mNameLabel, 0, wxALL, 5); - // Name Text - mNameText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); - mSizer->Add(mNameText, 0, wxALL | wxEXPAND, 5); + // Name Text + mNameText = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize); + mSizer->Add(mNameText, 0, wxALL | wxEXPAND, 5); - SetSizer(mSizer); - Layout(); + SetSizer(mSizer); + Layout(); } void TechniquePage::getName(wxString& name) const { - name = mNameText->GetValue(); + name = mNameText->GetValue(); } Project* TechniquePage::getProject() const { - wxString project = mProjectComboBox->GetValue(); + wxString project = mProjectComboBox->GetValue(); - return Workspace::getSingletonPtr()->getProject(project.c_str()); + return Workspace::getSingletonPtr()->getProject(project.c_str()); } MaterialController* TechniquePage::getMaterial() const { - wxString material = mMaterialComboBox->GetValue(); + wxString material = mMaterialComboBox->GetValue(); - return getProject()->getMaterialController(material.c_str()); + return getProject()->getMaterialController(material.c_str()); } void TechniquePage::setProject(Project* project) { - mProjectComboBox->SetValue(project != NULL ? project->getName().c_str() : wxEmptyString); - populateMaterials(project->getMaterials()); + mProjectComboBox->SetValue(project != NULL ? project->getName().c_str() : wxEmptyString); + populateMaterials(project->getMaterials()); } void TechniquePage::setMaterial(MaterialController* mc) { - mMaterialComboBox->SetValue(mc != NULL ? mc->getMaterial()->getName().c_str() : wxEmptyString); + mMaterialComboBox->SetValue(mc != NULL ? mc->getMaterial()->getName().c_str() : wxEmptyString); } void TechniquePage::OnProjectSelected(wxCommandEvent& event) { - Project* project = getProject(); - if(project != NULL) - populateMaterials(project->getMaterials()); + Project* project = getProject(); + if(project != NULL) + populateMaterials(project->getMaterials()); } void TechniquePage::populateMaterials(const MaterialControllerList* materials) { - wxArrayString materialNames; - MaterialControllerList::const_iterator it; - for(it = materials->begin(); it != materials->end(); ++it) - { - materialNames.Add((*it)->getMaterial()->getName().c_str()); - } - - mMaterialComboBox->Clear(); - mMaterialComboBox->Append(materialNames); + wxArrayString materialNames; + MaterialControllerList::const_iterator it; + for(it = materials->begin(); it != materials->end(); ++it) + { + materialNames.Add((*it)->getMaterial()->getName().c_str()); + } + + mMaterialComboBox->Clear(); + mMaterialComboBox->Append(materialNames); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/TechniquePropertyGridPage.cpp b/Tools/MaterialEditor/MaterialEditor/src/TechniquePropertyGridPage.cpp index 428e86f110f..2804b9c6570 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/TechniquePropertyGridPage.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/TechniquePropertyGridPage.cpp @@ -37,15 +37,15 @@ THE SOFTWARE. #include "TechniqueEventArgs.h" BEGIN_EVENT_TABLE(TechniquePropertyGridPage, wxPropertyGridPage) - EVT_PG_CHANGED(-1, TechniquePropertyGridPage::propertyChanged) + EVT_PG_CHANGED(-1, TechniquePropertyGridPage::propertyChanged) END_EVENT_TABLE() TechniquePropertyGridPage::TechniquePropertyGridPage(TechniqueController* controller) : mController(controller) { - mController->subscribe(TechniqueController::NameChanged, boost::bind(&TechniquePropertyGridPage::nameChanged, this, _1)); - mController->subscribe(TechniqueController::SchemeChanged, boost::bind(&TechniquePropertyGridPage::schemeNameChanged, this, _1)); - mController->subscribe(TechniqueController::LodIndexChanged, boost::bind(&TechniquePropertyGridPage::lodIndexChanged, this, _1)); + mController->subscribe(TechniqueController::NameChanged, boost::bind(&TechniquePropertyGridPage::nameChanged, this, _1)); + mController->subscribe(TechniqueController::SchemeChanged, boost::bind(&TechniquePropertyGridPage::schemeNameChanged, this, _1)); + mController->subscribe(TechniqueController::LodIndexChanged, boost::bind(&TechniquePropertyGridPage::lodIndexChanged, this, _1)); } TechniquePropertyGridPage::~TechniquePropertyGridPage() @@ -54,56 +54,56 @@ TechniquePropertyGridPage::~TechniquePropertyGridPage() void TechniquePropertyGridPage::populate() { - mNameId = Append(wxStringProperty(wxT("Name"), wxPG_LABEL, mController->getTechnique()->getName())); - mSchemeNameId = Append(wxStringProperty(wxT("Scheme Name"), wxPG_LABEL, mController->getTechnique()->getSchemeName())); - mLodIndexId = Append(wxIntProperty(wxT("LOD Index"), wxPG_LABEL, mController->getTechnique()->getLodIndex())); + mNameId = Append(wxStringProperty(wxT("Name"), wxPG_LABEL, mController->getTechnique()->getName())); + mSchemeNameId = Append(wxStringProperty(wxT("Scheme Name"), wxPG_LABEL, mController->getTechnique()->getSchemeName())); + mLodIndexId = Append(wxIntProperty(wxT("LOD Index"), wxPG_LABEL, mController->getTechnique()->getLodIndex())); } void TechniquePropertyGridPage::propertyChanged(wxPropertyGridEvent& event) { - wxPGId id = event.GetProperty(); - if(id == mNameId) - { - mController->setName(event.GetPropertyValueAsString().c_str()); - } - else if(id == mSchemeNameId) - { - mController->setSchemeName(event.GetPropertyValueAsString().c_str()); - } - else if(id = mLodIndexId) - { - mController->setLodIndex(event.GetPropertyValueAsInt()); - } + wxPGId id = event.GetProperty(); + if(id == mNameId) + { + mController->setName(event.GetPropertyValueAsString().c_str()); + } + else if(id == mSchemeNameId) + { + mController->setSchemeName(event.GetPropertyValueAsString().c_str()); + } + else if(id = mLodIndexId) + { + mController->setLodIndex(event.GetPropertyValueAsInt()); + } } void TechniquePropertyGridPage::nameChanged(EventArgs& args) { - TechniqueEventArgs tea = dynamic_cast(args); - TechniqueController* tc = tea.getTechniqueController(); + TechniqueEventArgs tea = dynamic_cast(args); + TechniqueController* tc = tea.getTechniqueController(); - wxPGProperty* prop = GetPropertyPtr(mNameId); - if(prop == NULL) return; - prop->SetValueFromString(tc->getTechnique()->getName().c_str()); + wxPGProperty* prop = GetPropertyPtr(mNameId); + if(prop == NULL) return; + prop->SetValueFromString(tc->getTechnique()->getName().c_str()); } void TechniquePropertyGridPage::schemeNameChanged(EventArgs& args) { - TechniqueEventArgs tea = dynamic_cast(args); - TechniqueController* tc = tea.getTechniqueController(); + TechniqueEventArgs tea = dynamic_cast(args); + TechniqueController* tc = tea.getTechniqueController(); - wxPGProperty* prop = GetPropertyPtr(mSchemeNameId); - if(prop == NULL) return; - prop->SetValueFromString(tc->getTechnique()->getSchemeName().c_str()); + wxPGProperty* prop = GetPropertyPtr(mSchemeNameId); + if(prop == NULL) return; + prop->SetValueFromString(tc->getTechnique()->getSchemeName().c_str()); } void TechniquePropertyGridPage::lodIndexChanged(EventArgs& args) { - TechniqueEventArgs tea = dynamic_cast(args); - TechniqueController* tc = tea.getTechniqueController(); + TechniqueEventArgs tea = dynamic_cast(args); + TechniqueController* tc = tea.getTechniqueController(); - wxPGProperty* prop = GetPropertyPtr(mLodIndexId); - if(prop == NULL) return; - prop->SetValueFromInt(tc->getTechnique()->getLodIndex()); + wxPGProperty* prop = GetPropertyPtr(mLodIndexId); + if(prop == NULL) return; + prop->SetValueFromInt(tc->getTechnique()->getLodIndex()); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/TechniqueWizard.cpp b/Tools/MaterialEditor/MaterialEditor/src/TechniqueWizard.cpp index bc93593cce5..d53dfc088d2 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/TechniqueWizard.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/TechniqueWizard.cpp @@ -36,7 +36,7 @@ THE SOFTWARE #include "Workspace.h" BEGIN_EVENT_TABLE(TechniqueWizard, wxWizard) - EVT_WIZARD_FINISHED(wxID_ANY, TechniqueWizard::OnFinish) + EVT_WIZARD_FINISHED(wxID_ANY, TechniqueWizard::OnFinish) END_EVENT_TABLE() TechniqueWizard::TechniqueWizard() @@ -49,27 +49,27 @@ TechniqueWizard::~TechniqueWizard() bool TechniqueWizard::Create(wxWindow* parent, int id /* = -1 */, const wxString& title /* = wxEmptyString */, const wxBitmap& bitmap /* = wxNullBitmap */, const wxPoint& pos /* = wxDefaultPosition */, long style /* = wxDEFAULT_DIALOG_STYLE */) { - bool result = wxWizard::Create(parent, id, title, bitmap, pos, style); + bool result = wxWizard::Create(parent, id, title, bitmap, pos, style); - mTechniquePage = new TechniquePage(this); + mTechniquePage = new TechniquePage(this); - GetPageAreaSizer()->Add(mTechniquePage); + GetPageAreaSizer()->Add(mTechniquePage); - return result; + return result; } TechniquePage* TechniqueWizard::getTechniquePage() const { - return mTechniquePage; + return mTechniquePage; } void TechniqueWizard::OnFinish(wxWizardEvent& event) { - Project* project = mTechniquePage->getProject(); - MaterialController* mc = mTechniquePage->getMaterial(); + Project* project = mTechniquePage->getProject(); + MaterialController* mc = mTechniquePage->getMaterial(); - wxString name; - mTechniquePage->getName(name); + wxString name; + mTechniquePage->getName(name); - mc->createTechnique(name.c_str()); + mc->createTechnique(name.c_str()); } diff --git a/Tools/MaterialEditor/MaterialEditor/src/TextureUnitController.cpp b/Tools/MaterialEditor/MaterialEditor/src/TextureUnitController.cpp index 40536b5164b..cd3aa17c60d 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/TextureUnitController.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/TextureUnitController.cpp @@ -34,19 +34,19 @@ THE SOFTWARE. TextureUnitController::TextureUnitController() : mParentController(NULL), mTextureUnit(NULL) { - registerEvents(); + registerEvents(); } TextureUnitController::TextureUnitController(TextureUnitState* tus) : mParentController(NULL), mTextureUnit(tus) { - registerEvents(); + registerEvents(); } TextureUnitController::TextureUnitController(PassController* parent, TextureUnitState* tus) : mParentController(parent), mTextureUnit(tus) { - registerEvents(); + registerEvents(); } TextureUnitController::~TextureUnitController() @@ -55,375 +55,375 @@ TextureUnitController::~TextureUnitController() void TextureUnitController::registerEvents() { - registerEvent(TextureNameChanged); - registerEvent(CubicTextureNameChanged); - registerEvent(AnimatedTextureNameChanged); - registerEvent(TextureDimensionsChanged); - registerEvent(CurrentFrameChanged); - registerEvent(FrameTextureNameChanged); - registerEvent(FrameTextureNameAdded); - registerEvent(FrameTextureNameRemoved); - registerEvent(BindingTypeChanged); - registerEvent(ContentTypeChanged); - registerEvent(PixelFormatChanged); - registerEvent(NumMipmapsChanged); - registerEvent(AlphaChanged); - registerEvent(TextureCoordSetChanged); - registerEvent(TextureTransformChanged); - registerEvent(TextureScrollChanged); - registerEvent(TextureUScrollChanged); - registerEvent(TextureVScrollChanged); - registerEvent(TextureUScaleChanged); - registerEvent(TextureVScaleChanged); - registerEvent(TextureRotateChanged); - registerEvent(TextureAddressingModeChanged); - registerEvent(TextureBorderColourChanged); - registerEvent(ColourOperationChanged); - registerEvent(ColourOperationExChanged); - registerEvent(ColourOpMultipassFallbackChanged); - registerEvent(AlphaOperationChanged); - registerEvent(EffectAdded); - registerEvent(EnvironmentMapChanged); - registerEvent(ScrollAnimationChanged); - registerEvent(RotateAnimationChanged); - registerEvent(TransformAnimationChanged); - registerEvent(ProjectiveTexturingChanged); - registerEvent(EffectRemoved); - registerEvent(Blanked); - registerEvent(TextureFilteringChanged); - registerEvent(TextureAnisotropyChanged); - registerEvent(TextureMipMapBiasChanged); - registerEvent(NameChanged); - registerEvent(TextureNameAliasChanged); + registerEvent(TextureNameChanged); + registerEvent(CubicTextureNameChanged); + registerEvent(AnimatedTextureNameChanged); + registerEvent(TextureDimensionsChanged); + registerEvent(CurrentFrameChanged); + registerEvent(FrameTextureNameChanged); + registerEvent(FrameTextureNameAdded); + registerEvent(FrameTextureNameRemoved); + registerEvent(BindingTypeChanged); + registerEvent(ContentTypeChanged); + registerEvent(PixelFormatChanged); + registerEvent(NumMipmapsChanged); + registerEvent(AlphaChanged); + registerEvent(TextureCoordSetChanged); + registerEvent(TextureTransformChanged); + registerEvent(TextureScrollChanged); + registerEvent(TextureUScrollChanged); + registerEvent(TextureVScrollChanged); + registerEvent(TextureUScaleChanged); + registerEvent(TextureVScaleChanged); + registerEvent(TextureRotateChanged); + registerEvent(TextureAddressingModeChanged); + registerEvent(TextureBorderColourChanged); + registerEvent(ColourOperationChanged); + registerEvent(ColourOperationExChanged); + registerEvent(ColourOpMultipassFallbackChanged); + registerEvent(AlphaOperationChanged); + registerEvent(EffectAdded); + registerEvent(EnvironmentMapChanged); + registerEvent(ScrollAnimationChanged); + registerEvent(RotateAnimationChanged); + registerEvent(TransformAnimationChanged); + registerEvent(ProjectiveTexturingChanged); + registerEvent(EffectRemoved); + registerEvent(Blanked); + registerEvent(TextureFilteringChanged); + registerEvent(TextureAnisotropyChanged); + registerEvent(TextureMipMapBiasChanged); + registerEvent(NameChanged); + registerEvent(TextureNameAliasChanged); } PassController* TextureUnitController::getParentController() const { - return mParentController; + return mParentController; } TextureUnitState* TextureUnitController::getTextureUnit() const { - return mTextureUnit; + return mTextureUnit; } void TextureUnitController::setTextureName(const String &name, TextureType ttype /* = TEX_TYPE_2D */) { - mTextureUnit->setTextureName(name, ttype); - - fireEvent(TextureNameChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureName(name, ttype); + + fireEvent(TextureNameChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setCubicTextureName(const String &name, bool forUVW /* = false */) { - mTextureUnit->setCubicTextureName(name, forUVW); - - fireEvent(CubicTextureNameChanged, TextureUnitEventArgs(this)); + mTextureUnit->setCubicTextureName(name, forUVW); + + fireEvent(CubicTextureNameChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setCubicTextureName(const String *const names, bool forUVW /* = false */) { - mTextureUnit->setCubicTextureName(names, forUVW); - - fireEvent(CubicTextureNameChanged, TextureUnitEventArgs(this)); + mTextureUnit->setCubicTextureName(names, forUVW); + + fireEvent(CubicTextureNameChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setAnimatedTextureName(const String &name, unsigned int numFrames, Real duration /* = 0 */) { - mTextureUnit->setAnimatedTextureName(&name, numFrames, duration); - - fireEvent(AnimatedTextureNameChanged, TextureUnitEventArgs(this)); + mTextureUnit->setAnimatedTextureName(&name, numFrames, duration); + + fireEvent(AnimatedTextureNameChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setAnimatedTextureName(const String *const names, unsigned int numFrames, Real duration /* = 0 */) { - mTextureUnit->setAnimatedTextureName(names, numFrames, duration); - - fireEvent(AnimatedTextureNameChanged, TextureUnitEventArgs(this)); + mTextureUnit->setAnimatedTextureName(names, numFrames, duration); + + fireEvent(AnimatedTextureNameChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setCurrentFrame(unsigned int frameNumber) { - mTextureUnit->setCurrentFrame(frameNumber); - - fireEvent(CurrentFrameChanged, TextureUnitEventArgs(this)); + mTextureUnit->setCurrentFrame(frameNumber); + + fireEvent(CurrentFrameChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setFrameTextureName(const String &name, unsigned int frameNumber) { - mTextureUnit->setFrameTextureName(name, frameNumber); - - fireEvent(FrameTextureNameChanged, TextureUnitEventArgs(this)); + mTextureUnit->setFrameTextureName(name, frameNumber); + + fireEvent(FrameTextureNameChanged, TextureUnitEventArgs(this)); } void TextureUnitController::addFrameTextureName(const String &name) { - mTextureUnit->addFrameTextureName(name); - - fireEvent(FrameTextureNameAdded, TextureUnitEventArgs(this)); + mTextureUnit->addFrameTextureName(name); + + fireEvent(FrameTextureNameAdded, TextureUnitEventArgs(this)); } void TextureUnitController::deleteFrameTextureName(const size_t frameNumber) { - mTextureUnit->deleteFrameTextureName(frameNumber); - - fireEvent(FrameTextureNameRemoved, TextureUnitEventArgs(this)); + mTextureUnit->deleteFrameTextureName(frameNumber); + + fireEvent(FrameTextureNameRemoved, TextureUnitEventArgs(this)); } void TextureUnitController::setBindingType(TextureUnitState::BindingType bt) { - mTextureUnit->setBindingType(bt); - - fireEvent(BindingTypeChanged, TextureUnitEventArgs(this)); + mTextureUnit->setBindingType(bt); + + fireEvent(BindingTypeChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setContentType(TextureUnitState::ContentType ct) { - mTextureUnit->setContentType(ct); - - fireEvent(ContentTypeChanged, TextureUnitEventArgs(this)); + mTextureUnit->setContentType(ct); + + fireEvent(ContentTypeChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setDesiredFormat(PixelFormat desiredFormat) { - mTextureUnit->setDesiredFormat(desiredFormat); - - fireEvent(PixelFormatChanged, TextureUnitEventArgs(this)); + mTextureUnit->setDesiredFormat(desiredFormat); + + fireEvent(PixelFormatChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setNumMipmaps(int numMipmaps) { - mTextureUnit->setNumMipmaps(numMipmaps); - - fireEvent(NumMipmapsChanged, TextureUnitEventArgs(this)); + mTextureUnit->setNumMipmaps(numMipmaps); + + fireEvent(NumMipmapsChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureCoordSet(unsigned int set) { - mTextureUnit->setTextureCoordSet(set); - - fireEvent(TextureCoordSetChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureCoordSet(set); + + fireEvent(TextureCoordSetChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureTransform(const Matrix4 &xform) { - mTextureUnit->setTextureTransform(xform); - - fireEvent(TextureTransformChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureTransform(xform); + + fireEvent(TextureTransformChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureScroll(Real u, Real v) { - mTextureUnit->setTextureScroll(u, v); - - fireEvent(TextureScrollChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureScroll(u, v); + + fireEvent(TextureScrollChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureUScroll(Real value) { - mTextureUnit->setTextureUScroll(value); - - fireEvent(TextureUScrollChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureUScroll(value); + + fireEvent(TextureUScrollChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureUScale(Real value) { - mTextureUnit->setTextureUScale(value); - - fireEvent(TextureUScaleChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureUScale(value); + + fireEvent(TextureUScaleChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureVScale(Real value) { - mTextureUnit->setTextureVScale(value); - - fireEvent(TextureVScaleChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureVScale(value); + + fireEvent(TextureVScaleChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureScale(Real uScale, Real vScale) { - mTextureUnit->setTextureScale(uScale, vScale); - - fireEvent(TextureUScaleChanged, TextureUnitEventArgs(this)); - fireEvent(TextureVScaleChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureScale(uScale, vScale); + + fireEvent(TextureUScaleChanged, TextureUnitEventArgs(this)); + fireEvent(TextureVScaleChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureRotate(const Radian &angle) { - mTextureUnit->setTextureRotate(angle); - - fireEvent(TextureRotateChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureRotate(angle); + + fireEvent(TextureRotateChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureAddressingMode(TextureUnitState::TextureAddressingMode tam) { - mTextureUnit->setTextureAddressingMode(tam); - - fireEvent(TextureAddressingModeChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureAddressingMode(tam); + + fireEvent(TextureAddressingModeChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureAddressingMode(TextureUnitState::TextureAddressingMode u, TextureUnitState::TextureAddressingMode v, TextureUnitState::TextureAddressingMode w) { - mTextureUnit->setTextureAddressingMode(u, v, w); - - fireEvent(TextureAddressingModeChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureAddressingMode(u, v, w); + + fireEvent(TextureAddressingModeChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureAddressingMode(const TextureUnitState::UVWAddressingMode &uvw) { - mTextureUnit->setTextureAddressingMode(uvw); - - fireEvent(TextureAddressingModeChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureAddressingMode(uvw); + + fireEvent(TextureAddressingModeChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureBorderColour(const ColourValue &colour) { - mTextureUnit->setTextureBorderColour(colour); - - fireEvent(TextureBorderColourChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureBorderColour(colour); + + fireEvent(TextureBorderColourChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setColourOperationEx(LayerBlendOperationEx op, LayerBlendSource source1 /* = LBS_TEXTURE */, LayerBlendSource source2 /* = LBS_CURRENT */, const ColourValue &arg1 /* = ColourValue::White */, const ColourValue &arg2 /* = ColourValue::White */, Real manualBlend /* = 0.0 */) { - mTextureUnit->setColourOperationEx(op, source1, source2, arg1, arg2, manualBlend); - - fireEvent(ColourOperationExChanged, TextureUnitEventArgs(this)); + mTextureUnit->setColourOperationEx(op, source1, source2, arg1, arg2, manualBlend); + + fireEvent(ColourOperationExChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setColourOperation(const LayerBlendOperation op) { - mTextureUnit->setColourOperation(op); - - fireEvent(ColourOperationChanged, TextureUnitEventArgs(this)); + mTextureUnit->setColourOperation(op); + + fireEvent(ColourOperationChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setColourOpMultipassFallback(const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor) { - mTextureUnit->setColourOpMultipassFallback(sourceFactor, destFactor); - - fireEvent(ColourOpMultipassFallbackChanged, TextureUnitEventArgs(this)); + mTextureUnit->setColourOpMultipassFallback(sourceFactor, destFactor); + + fireEvent(ColourOpMultipassFallbackChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setAlphaOperation(LayerBlendOperationEx op, LayerBlendSource source1, LayerBlendSource source2, Real arg1, Real arg2, Real manualBlend) { - mTextureUnit->setAlphaOperation(op, source1, source2, arg1, arg2, manualBlend); - - fireEvent(AlphaOperationChanged, TextureUnitEventArgs(this)); + mTextureUnit->setAlphaOperation(op, source1, source2, arg1, arg2, manualBlend); + + fireEvent(AlphaOperationChanged, TextureUnitEventArgs(this)); } void TextureUnitController::addEffect(TextureUnitState::TextureEffect& effect) { - mTextureUnit->addEffect(effect); - - fireEvent(EffectAdded, TextureUnitEventArgs(this)); + mTextureUnit->addEffect(effect); + + fireEvent(EffectAdded, TextureUnitEventArgs(this)); } void TextureUnitController::setEnvironmentMap(bool enable, TextureUnitState::EnvMapType envMapType) { - mTextureUnit->setEnvironmentMap(enable, envMapType); - - fireEvent(EnvironmentMapChanged, TextureUnitEventArgs(this)); + mTextureUnit->setEnvironmentMap(enable, envMapType); + + fireEvent(EnvironmentMapChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setScrollAnimation(Real uSpeed, Real vSpeed) { - mTextureUnit->setScrollAnimation(uSpeed, vSpeed); - - fireEvent(ScrollAnimationChanged, TextureUnitEventArgs(this)); + mTextureUnit->setScrollAnimation(uSpeed, vSpeed); + + fireEvent(ScrollAnimationChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setRotateAnimation(Real speed) { - mTextureUnit->setRotateAnimation(speed); - - fireEvent(AlphaOperationChanged, TextureUnitEventArgs(this)); + mTextureUnit->setRotateAnimation(speed); + + fireEvent(AlphaOperationChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTransformAnimation(const TextureUnitState::TextureTransformType ttype, const WaveformType waveType, Real base, Real frequency, Real phase, Real amplitude) { - mTextureUnit->setTransformAnimation(ttype, waveType, base, frequency, phase, amplitude); - - fireEvent(TransformAnimationChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTransformAnimation(ttype, waveType, base, frequency, phase, amplitude); + + fireEvent(TransformAnimationChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setProjectiveTexturing(bool enabled, const Frustum* projectionSettings) { - mTextureUnit->setProjectiveTexturing(enabled, projectionSettings); - - fireEvent(ProjectiveTexturingChanged, TextureUnitEventArgs(this)); + mTextureUnit->setProjectiveTexturing(enabled, projectionSettings); + + fireEvent(ProjectiveTexturingChanged, TextureUnitEventArgs(this)); } void TextureUnitController::removeAllEffects(void) { - mTextureUnit->removeAllEffects(); - - fireEvent(EffectRemoved, TextureUnitEventArgs(this)); + mTextureUnit->removeAllEffects(); + + fireEvent(EffectRemoved, TextureUnitEventArgs(this)); } void TextureUnitController::removeEffect(const TextureUnitState::TextureEffectType type) { - mTextureUnit->removeEffect(type); - - fireEvent(EffectRemoved, TextureUnitEventArgs(this)); + mTextureUnit->removeEffect(type); + + fireEvent(EffectRemoved, TextureUnitEventArgs(this)); } void TextureUnitController::setBlank(void) { - mTextureUnit->setBlank(); - - fireEvent(Blanked, TextureUnitEventArgs(this)); + mTextureUnit->setBlank(); + + fireEvent(Blanked, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureFiltering(TextureFilterOptions filterType) { - mTextureUnit->setTextureFiltering(filterType); - - fireEvent(TextureFilteringChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureFiltering(filterType); + + fireEvent(TextureFilteringChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureFiltering(FilterOptions minFilter, FilterOptions magFilter, FilterOptions mipFilter) { - mTextureUnit->setTextureFiltering(minFilter, magFilter, mipFilter); - - fireEvent(TextureFilteringChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureFiltering(minFilter, magFilter, mipFilter); + + fireEvent(TextureFilteringChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureAnisotropy(unsigned int maxAniso) { - mTextureUnit->setTextureAnisotropy(maxAniso); - - fireEvent(TextureAnisotropyChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureAnisotropy(maxAniso); + + fireEvent(TextureAnisotropyChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureMipmapBias(float bias) { - mTextureUnit->setTextureMipmapBias(bias); - - fireEvent(TextureMipMapBiasChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureMipmapBias(bias); + + fireEvent(TextureMipMapBiasChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setName(const String &name) { - mTextureUnit->setName(name); - - fireEvent(NameChanged, TextureUnitEventArgs(this)); + mTextureUnit->setName(name); + + fireEvent(NameChanged, TextureUnitEventArgs(this)); } void TextureUnitController::setTextureNameAlias(const String &name) { - mTextureUnit->setTextureNameAlias(name); - - fireEvent(TextureNameAliasChanged, TextureUnitEventArgs(this)); + mTextureUnit->setTextureNameAlias(name); + + fireEvent(TextureNameAliasChanged, TextureUnitEventArgs(this)); } bool TextureUnitController::applyTextureAliases(const AliasTextureNamePairList &aliasList, const bool apply) { - bool result = mTextureUnit->applyTextureAliases(aliasList, apply); - - fireEvent(TextureNameAliasChanged, TextureUnitEventArgs(this)); + bool result = mTextureUnit->applyTextureAliases(aliasList, apply); + + fireEvent(TextureNameAliasChanged, TextureUnitEventArgs(this)); - return result; + return result; } diff --git a/Tools/MaterialEditor/MaterialEditor/src/TextureUnitPropertyGridPage.cpp b/Tools/MaterialEditor/MaterialEditor/src/TextureUnitPropertyGridPage.cpp index b0314df6286..04fd6cb3368 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/TextureUnitPropertyGridPage.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/TextureUnitPropertyGridPage.cpp @@ -45,45 +45,45 @@ END_EVENT_TABLE() TextureUnitPropertyGridPage::TextureUnitPropertyGridPage(TextureUnitController* controller) : mController(controller) { - mController->subscribe(TextureUnitController::TextureNameChanged, boost::bind(&TextureUnitPropertyGridPage::textureNameChanged, this, _1)); - mController->subscribe(TextureUnitController::CubicTextureNameChanged, boost::bind(&TextureUnitPropertyGridPage::cubicTextureNameChanged, this, _1)); - mController->subscribe(TextureUnitController::AnimatedTextureNameChanged, boost::bind(&TextureUnitPropertyGridPage::animatedTextureNameChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureDimensionsChanged, boost::bind(&TextureUnitPropertyGridPage::textureDimensionsChanged, this, _1)); - mController->subscribe(TextureUnitController::CurrentFrameChanged, boost::bind(&TextureUnitPropertyGridPage::currentFrameChanged, this, _1)); - mController->subscribe(TextureUnitController::FrameTextureNameChanged, boost::bind(&TextureUnitPropertyGridPage::frameTextureNameChanged, this, _1)); - mController->subscribe(TextureUnitController::FrameTextureNameAdded, boost::bind(&TextureUnitPropertyGridPage::frameTextureNameAdded, this, _1)); - mController->subscribe(TextureUnitController::FrameTextureNameRemoved, boost::bind(&TextureUnitPropertyGridPage::frameTextureNameRemoved, this, _1)); - mController->subscribe(TextureUnitController::BindingTypeChanged, boost::bind(&TextureUnitPropertyGridPage::bindingTypeChanged, this, _1)); - mController->subscribe(TextureUnitController::ContentTypeChanged, boost::bind(&TextureUnitPropertyGridPage::contentTypeChanged, this, _1)); - mController->subscribe(TextureUnitController::PixelFormatChanged, boost::bind(&TextureUnitPropertyGridPage::pixelFormatChanged, this, _1)); - mController->subscribe(TextureUnitController::NumMipmapsChanged, boost::bind(&TextureUnitPropertyGridPage::numMipmapsChanged, this, _1)); - mController->subscribe(TextureUnitController::AlphaChanged, boost::bind(&TextureUnitPropertyGridPage::alphaChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureCoordSetChanged, boost::bind(&TextureUnitPropertyGridPage::textureCoordSetChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureTransformChanged, boost::bind(&TextureUnitPropertyGridPage::textureTransformChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureScrollChanged, boost::bind(&TextureUnitPropertyGridPage::textureScrollChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureUScrollChanged, boost::bind(&TextureUnitPropertyGridPage::textureUScrollChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureVScrollChanged, boost::bind(&TextureUnitPropertyGridPage::textureVScrollChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureUScaleChanged, boost::bind(&TextureUnitPropertyGridPage::textureUScaleChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureVScaleChanged, boost::bind(&TextureUnitPropertyGridPage::textureVScaleChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureRotateChanged, boost::bind(&TextureUnitPropertyGridPage::textureRotateChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureAddressingModeChanged, boost::bind(&TextureUnitPropertyGridPage::textureAddressingModeChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureBorderColourChanged, boost::bind(&TextureUnitPropertyGridPage::textureBorderColourChanged, this, _1)); - mController->subscribe(TextureUnitController::ColourOperationExChanged, boost::bind(&TextureUnitPropertyGridPage::colourOperationExChanged, this, _1)); - mController->subscribe(TextureUnitController::ColourOpMultipassFallbackChanged, boost::bind(&TextureUnitPropertyGridPage::colourOpMultipassFallbackChanged, this, _1)); - mController->subscribe(TextureUnitController::AlphaOperationChanged, boost::bind(&TextureUnitPropertyGridPage::alphaOperationChanged, this, _1)); - //mController->subscribe(TextureUnitController::EffectAdded, boost::bind(&TextureUnitPropertyGridPage::effectAdded, this, _1)); - mController->subscribe(TextureUnitController::EnvironmentMapChanged, boost::bind(&TextureUnitPropertyGridPage::environmentMapChanged, this, _1)); - mController->subscribe(TextureUnitController::ScrollAnimationChanged, boost::bind(&TextureUnitPropertyGridPage::scrollAnimationChanged, this, _1)); - mController->subscribe(TextureUnitController::RotateAnimationChanged, boost::bind(&TextureUnitPropertyGridPage::rotateAnimationChanged, this, _1)); - mController->subscribe(TextureUnitController::TransformAnimationChanged, boost::bind(&TextureUnitPropertyGridPage::projectiveTexturingChanged, this, _1)); - mController->subscribe(TextureUnitController::ProjectiveTexturingChanged, boost::bind(&TextureUnitPropertyGridPage::projectiveTexturingChanged, this, _1)); - //mController->subscribe(TextureUnitController::EffectRemoved, boost::bind(&TextureUnitPropertyGridPage::effectRemoved, this, _1)); - //mController->subscribe(TextureUnitController::Blanked, boost::bind(&TextureUnitPropertyGridPage::blanked, this, _1)); - mController->subscribe(TextureUnitController::TextureFilteringChanged, boost::bind(&TextureUnitPropertyGridPage::textureFilteringChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureAnisotropyChanged, boost::bind(&TextureUnitPropertyGridPage::textureAnisotropyChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureMipMapBiasChanged, boost::bind(&TextureUnitPropertyGridPage::textureMipMapBiasChanged, this, _1)); - mController->subscribe(TextureUnitController::NameChanged, boost::bind(&TextureUnitPropertyGridPage::nameChanged, this, _1)); - mController->subscribe(TextureUnitController::TextureNameAliasChanged, boost::bind(&TextureUnitPropertyGridPage::textureNameAliasChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureNameChanged, boost::bind(&TextureUnitPropertyGridPage::textureNameChanged, this, _1)); + mController->subscribe(TextureUnitController::CubicTextureNameChanged, boost::bind(&TextureUnitPropertyGridPage::cubicTextureNameChanged, this, _1)); + mController->subscribe(TextureUnitController::AnimatedTextureNameChanged, boost::bind(&TextureUnitPropertyGridPage::animatedTextureNameChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureDimensionsChanged, boost::bind(&TextureUnitPropertyGridPage::textureDimensionsChanged, this, _1)); + mController->subscribe(TextureUnitController::CurrentFrameChanged, boost::bind(&TextureUnitPropertyGridPage::currentFrameChanged, this, _1)); + mController->subscribe(TextureUnitController::FrameTextureNameChanged, boost::bind(&TextureUnitPropertyGridPage::frameTextureNameChanged, this, _1)); + mController->subscribe(TextureUnitController::FrameTextureNameAdded, boost::bind(&TextureUnitPropertyGridPage::frameTextureNameAdded, this, _1)); + mController->subscribe(TextureUnitController::FrameTextureNameRemoved, boost::bind(&TextureUnitPropertyGridPage::frameTextureNameRemoved, this, _1)); + mController->subscribe(TextureUnitController::BindingTypeChanged, boost::bind(&TextureUnitPropertyGridPage::bindingTypeChanged, this, _1)); + mController->subscribe(TextureUnitController::ContentTypeChanged, boost::bind(&TextureUnitPropertyGridPage::contentTypeChanged, this, _1)); + mController->subscribe(TextureUnitController::PixelFormatChanged, boost::bind(&TextureUnitPropertyGridPage::pixelFormatChanged, this, _1)); + mController->subscribe(TextureUnitController::NumMipmapsChanged, boost::bind(&TextureUnitPropertyGridPage::numMipmapsChanged, this, _1)); + mController->subscribe(TextureUnitController::AlphaChanged, boost::bind(&TextureUnitPropertyGridPage::alphaChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureCoordSetChanged, boost::bind(&TextureUnitPropertyGridPage::textureCoordSetChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureTransformChanged, boost::bind(&TextureUnitPropertyGridPage::textureTransformChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureScrollChanged, boost::bind(&TextureUnitPropertyGridPage::textureScrollChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureUScrollChanged, boost::bind(&TextureUnitPropertyGridPage::textureUScrollChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureVScrollChanged, boost::bind(&TextureUnitPropertyGridPage::textureVScrollChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureUScaleChanged, boost::bind(&TextureUnitPropertyGridPage::textureUScaleChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureVScaleChanged, boost::bind(&TextureUnitPropertyGridPage::textureVScaleChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureRotateChanged, boost::bind(&TextureUnitPropertyGridPage::textureRotateChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureAddressingModeChanged, boost::bind(&TextureUnitPropertyGridPage::textureAddressingModeChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureBorderColourChanged, boost::bind(&TextureUnitPropertyGridPage::textureBorderColourChanged, this, _1)); + mController->subscribe(TextureUnitController::ColourOperationExChanged, boost::bind(&TextureUnitPropertyGridPage::colourOperationExChanged, this, _1)); + mController->subscribe(TextureUnitController::ColourOpMultipassFallbackChanged, boost::bind(&TextureUnitPropertyGridPage::colourOpMultipassFallbackChanged, this, _1)); + mController->subscribe(TextureUnitController::AlphaOperationChanged, boost::bind(&TextureUnitPropertyGridPage::alphaOperationChanged, this, _1)); + //mController->subscribe(TextureUnitController::EffectAdded, boost::bind(&TextureUnitPropertyGridPage::effectAdded, this, _1)); + mController->subscribe(TextureUnitController::EnvironmentMapChanged, boost::bind(&TextureUnitPropertyGridPage::environmentMapChanged, this, _1)); + mController->subscribe(TextureUnitController::ScrollAnimationChanged, boost::bind(&TextureUnitPropertyGridPage::scrollAnimationChanged, this, _1)); + mController->subscribe(TextureUnitController::RotateAnimationChanged, boost::bind(&TextureUnitPropertyGridPage::rotateAnimationChanged, this, _1)); + mController->subscribe(TextureUnitController::TransformAnimationChanged, boost::bind(&TextureUnitPropertyGridPage::projectiveTexturingChanged, this, _1)); + mController->subscribe(TextureUnitController::ProjectiveTexturingChanged, boost::bind(&TextureUnitPropertyGridPage::projectiveTexturingChanged, this, _1)); + //mController->subscribe(TextureUnitController::EffectRemoved, boost::bind(&TextureUnitPropertyGridPage::effectRemoved, this, _1)); + //mController->subscribe(TextureUnitController::Blanked, boost::bind(&TextureUnitPropertyGridPage::blanked, this, _1)); + mController->subscribe(TextureUnitController::TextureFilteringChanged, boost::bind(&TextureUnitPropertyGridPage::textureFilteringChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureAnisotropyChanged, boost::bind(&TextureUnitPropertyGridPage::textureAnisotropyChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureMipMapBiasChanged, boost::bind(&TextureUnitPropertyGridPage::textureMipMapBiasChanged, this, _1)); + mController->subscribe(TextureUnitController::NameChanged, boost::bind(&TextureUnitPropertyGridPage::nameChanged, this, _1)); + mController->subscribe(TextureUnitController::TextureNameAliasChanged, boost::bind(&TextureUnitPropertyGridPage::textureNameAliasChanged, this, _1)); } TextureUnitPropertyGridPage::~TextureUnitPropertyGridPage() @@ -92,442 +92,442 @@ TextureUnitPropertyGridPage::~TextureUnitPropertyGridPage() void TextureUnitPropertyGridPage::populate() { - const TextureUnitState* tus = mController->getTextureUnit(); - - mTextureNameId = Append(wxStringProperty(wxT("Texture Name"), wxPG_LABEL, tus->getTextureName())); - mCurrentFrameId = Append(wxIntProperty(wxT("Current Frame"), wxPG_LABEL, tus->getCurrentFrame())); - - wxPGChoices btChoices; - btChoices.Add(wxT("Fragment"), TextureUnitState::BT_FRAGMENT); - btChoices.Add(wxT("Vertex"), TextureUnitState::BT_VERTEX); - mBindingTypeId = Append(wxEnumProperty(wxT("Binding Type"), wxPG_LABEL, btChoices, TextureUnitState::BT_FRAGMENT)); - - wxPGChoices ctChoices; - ctChoices.Add(wxT("Named"), TextureUnitState::CONTENT_NAMED); - ctChoices.Add(wxT("Shadow"), TextureUnitState::CONTENT_SHADOW); - mContentTypeId = Append(wxEnumProperty(wxT("Content Type"), wxPG_LABEL, ctChoices, TextureUnitState::CONTENT_NAMED)); - - wxPGChoices pfChoices; - pfChoices.Add(wxT("Unknown"), PF_UNKNOWN); - pfChoices.Add(wxT("L8"), PF_L8); - pfChoices.Add(wxT("BYTE_L"), PF_BYTE_L); - pfChoices.Add(wxT("L16"), PF_L16); - pfChoices.Add(wxT("SHORT_L"), PF_SHORT_L); - pfChoices.Add(wxT("A8"), PF_A8); - pfChoices.Add(wxT("BYTE_A"), PF_BYTE_A); - pfChoices.Add(wxT("A4L4"), PF_A4L4); - pfChoices.Add(wxT("BYTE_LA"), PF_BYTE_LA); - pfChoices.Add(wxT("R5G6B5"), PF_R5G6B5); - pfChoices.Add(wxT("B5G6R5"), PF_B5G6R5); - pfChoices.Add(wxT("R3G3B2"), PF_R3G3B2); - pfChoices.Add(wxT("A4R4G4B4"), PF_A4R4G4B4); - pfChoices.Add(wxT("A1R5G5B5"), PF_A1R5G5B5); - pfChoices.Add(wxT("R8G8B8"), PF_R8G8B8); - pfChoices.Add(wxT("B8G8R8"), PF_B8G8R8); - pfChoices.Add(wxT("A8R8G8B8"), PF_A8R8G8B8); - pfChoices.Add(wxT("A8B8G8R8"), PF_A8B8G8R8); - pfChoices.Add(wxT("B8G8R8A8"), PF_B8G8R8A8); - pfChoices.Add(wxT("R8G8B8A8"), PF_R8G8B8A8); - pfChoices.Add(wxT("X8R8G8B8"), PF_X8R8G8B8); - pfChoices.Add(wxT("X8B8G8R8"), PF_X8B8G8R8); - pfChoices.Add(wxT("BYTE_RGB"), PF_BYTE_RGB); - pfChoices.Add(wxT("BYTE_BGR"), PF_BYTE_BGR); - pfChoices.Add(wxT("BYTE_BGRA"), PF_BYTE_BGRA); - pfChoices.Add(wxT("BYTE_RGBA"), PF_BYTE_RGBA); - pfChoices.Add(wxT("A2R10G10B10"), PF_A2R10G10B10); - pfChoices.Add(wxT("A2B10G10R10"), PF_A2B10G10R10); - pfChoices.Add(wxT("DXT1"), PF_DXT1); - pfChoices.Add(wxT("DXT2"), PF_DXT2); - pfChoices.Add(wxT("DXT3"), PF_DXT3); - pfChoices.Add(wxT("DXT4"), PF_DXT4); - pfChoices.Add(wxT("DXT5"), PF_DXT5); - pfChoices.Add(wxT("FLOAT16_R"), PF_FLOAT16_R); - pfChoices.Add(wxT("FLOAT16_RGB"), PF_FLOAT16_RGB); - pfChoices.Add(wxT("FLOAT16_RGBA"), PF_FLOAT16_RGBA); - pfChoices.Add(wxT("FLOAT32_R"), PF_FLOAT32_R); - pfChoices.Add(wxT("FLOAT32_RGB"), PF_FLOAT32_RGB); - pfChoices.Add(wxT("FLOAT32_RGBA"), PF_FLOAT32_RGBA); - pfChoices.Add(wxT("FLOAT16_GR"), PF_FLOAT16_GR); - pfChoices.Add(wxT("FLOAT32_GR"), PF_FLOAT32_GR); - pfChoices.Add(wxT("PF_DEPTH"), PF_DEPTH); - pfChoices.Add(wxT("SHORT_RGBA"), PF_SHORT_RGBA); - pfChoices.Add(wxT("SHORT_GR"), PF_SHORT_GR); - pfChoices.Add(wxT("SHORT_RGB"), PF_SHORT_RGB); - pfChoices.Add(wxT("PF_COUNT"), PF_COUNT); - mPixelFormatId = Append(wxEnumProperty(wxT("Desired Format"), wxPG_LABEL, pfChoices, PF_UNKNOWN)); - - mNumMipMapsId = Append(wxIntProperty(wxT("Mip Maps"))); + const TextureUnitState* tus = mController->getTextureUnit(); + + mTextureNameId = Append(wxStringProperty(wxT("Texture Name"), wxPG_LABEL, tus->getTextureName())); + mCurrentFrameId = Append(wxIntProperty(wxT("Current Frame"), wxPG_LABEL, tus->getCurrentFrame())); + + wxPGChoices btChoices; + btChoices.Add(wxT("Fragment"), TextureUnitState::BT_FRAGMENT); + btChoices.Add(wxT("Vertex"), TextureUnitState::BT_VERTEX); + mBindingTypeId = Append(wxEnumProperty(wxT("Binding Type"), wxPG_LABEL, btChoices, TextureUnitState::BT_FRAGMENT)); + + wxPGChoices ctChoices; + ctChoices.Add(wxT("Named"), TextureUnitState::CONTENT_NAMED); + ctChoices.Add(wxT("Shadow"), TextureUnitState::CONTENT_SHADOW); + mContentTypeId = Append(wxEnumProperty(wxT("Content Type"), wxPG_LABEL, ctChoices, TextureUnitState::CONTENT_NAMED)); + + wxPGChoices pfChoices; + pfChoices.Add(wxT("Unknown"), PF_UNKNOWN); + pfChoices.Add(wxT("L8"), PF_L8); + pfChoices.Add(wxT("BYTE_L"), PF_BYTE_L); + pfChoices.Add(wxT("L16"), PF_L16); + pfChoices.Add(wxT("SHORT_L"), PF_SHORT_L); + pfChoices.Add(wxT("A8"), PF_A8); + pfChoices.Add(wxT("BYTE_A"), PF_BYTE_A); + pfChoices.Add(wxT("A4L4"), PF_A4L4); + pfChoices.Add(wxT("BYTE_LA"), PF_BYTE_LA); + pfChoices.Add(wxT("R5G6B5"), PF_R5G6B5); + pfChoices.Add(wxT("B5G6R5"), PF_B5G6R5); + pfChoices.Add(wxT("R3G3B2"), PF_R3G3B2); + pfChoices.Add(wxT("A4R4G4B4"), PF_A4R4G4B4); + pfChoices.Add(wxT("A1R5G5B5"), PF_A1R5G5B5); + pfChoices.Add(wxT("R8G8B8"), PF_R8G8B8); + pfChoices.Add(wxT("B8G8R8"), PF_B8G8R8); + pfChoices.Add(wxT("A8R8G8B8"), PF_A8R8G8B8); + pfChoices.Add(wxT("A8B8G8R8"), PF_A8B8G8R8); + pfChoices.Add(wxT("B8G8R8A8"), PF_B8G8R8A8); + pfChoices.Add(wxT("R8G8B8A8"), PF_R8G8B8A8); + pfChoices.Add(wxT("X8R8G8B8"), PF_X8R8G8B8); + pfChoices.Add(wxT("X8B8G8R8"), PF_X8B8G8R8); + pfChoices.Add(wxT("BYTE_RGB"), PF_BYTE_RGB); + pfChoices.Add(wxT("BYTE_BGR"), PF_BYTE_BGR); + pfChoices.Add(wxT("BYTE_BGRA"), PF_BYTE_BGRA); + pfChoices.Add(wxT("BYTE_RGBA"), PF_BYTE_RGBA); + pfChoices.Add(wxT("A2R10G10B10"), PF_A2R10G10B10); + pfChoices.Add(wxT("A2B10G10R10"), PF_A2B10G10R10); + pfChoices.Add(wxT("DXT1"), PF_DXT1); + pfChoices.Add(wxT("DXT2"), PF_DXT2); + pfChoices.Add(wxT("DXT3"), PF_DXT3); + pfChoices.Add(wxT("DXT4"), PF_DXT4); + pfChoices.Add(wxT("DXT5"), PF_DXT5); + pfChoices.Add(wxT("FLOAT16_R"), PF_FLOAT16_R); + pfChoices.Add(wxT("FLOAT16_RGB"), PF_FLOAT16_RGB); + pfChoices.Add(wxT("FLOAT16_RGBA"), PF_FLOAT16_RGBA); + pfChoices.Add(wxT("FLOAT32_R"), PF_FLOAT32_R); + pfChoices.Add(wxT("FLOAT32_RGB"), PF_FLOAT32_RGB); + pfChoices.Add(wxT("FLOAT32_RGBA"), PF_FLOAT32_RGBA); + pfChoices.Add(wxT("FLOAT16_GR"), PF_FLOAT16_GR); + pfChoices.Add(wxT("FLOAT32_GR"), PF_FLOAT32_GR); + pfChoices.Add(wxT("PF_DEPTH"), PF_DEPTH); + pfChoices.Add(wxT("SHORT_RGBA"), PF_SHORT_RGBA); + pfChoices.Add(wxT("SHORT_GR"), PF_SHORT_GR); + pfChoices.Add(wxT("SHORT_RGB"), PF_SHORT_RGB); + pfChoices.Add(wxT("PF_COUNT"), PF_COUNT); + mPixelFormatId = Append(wxEnumProperty(wxT("Desired Format"), wxPG_LABEL, pfChoices, PF_UNKNOWN)); + + mNumMipMapsId = Append(wxIntProperty(wxT("Mip Maps"))); } void TextureUnitPropertyGridPage::propertyChanged(wxPropertyGridEvent& event) { - wxPGId id = event.GetProperty(); - if(id == mTextureNameId) {} - else if(id == mCubicTextureNameId) {} - else if(id == mAnimatedTextureNameId) {} - else if(id == mTextureDimensionsId) {} - else if(id == mCurrentFrameId) {} - else if(id == mFrameTextureNameId) {} - else if(id == mBindingTypeId) {} - else if(id == mContentTypeId) {} - else if(id == mPixelFormatId) {} - else if(id == mNumMipMapsId) {} - else if(id == mAlphaId) {} - else if(id == mTextureCoordSetId) {} - else if(id == mTextureTransformId) {} - else if(id == mTextureScrollId) {} - else if(id == mTextureUScrollId) {} - else if(id == mTextureVScrollId) {} - else if(id == mTextureUScaleId) {} - else if(id == mTextureVScaleId) {} - else if(id == mTextureRotateId) {} - else if(id == mTextureAddressingModeId) {} - else if(id == mTextureBorderColourId) {} - else if(id == mColourOperationExId) {} - else if(id == mColourOpMultipassFallbackId) {} - else if(id == mAlphaOperationId) {} - else if(id == mEnvironmentMapId) {} - else if(id == mScrollAnimationId) {} - else if(id == mRotateAnimationId) {} - else if(id == mTransformAnimationId) {} - else if(id == mProjectiveTexturingId) {} - else if(id == mTextureFilteringId) {} - else if(id == mTextureAnisotropyId) {} - else if(id == mTextureMipMapBiasId) {} - else if(id == mNameId) {} - else if(id == mTextureNameAliasId) {} + wxPGId id = event.GetProperty(); + if(id == mTextureNameId) {} + else if(id == mCubicTextureNameId) {} + else if(id == mAnimatedTextureNameId) {} + else if(id == mTextureDimensionsId) {} + else if(id == mCurrentFrameId) {} + else if(id == mFrameTextureNameId) {} + else if(id == mBindingTypeId) {} + else if(id == mContentTypeId) {} + else if(id == mPixelFormatId) {} + else if(id == mNumMipMapsId) {} + else if(id == mAlphaId) {} + else if(id == mTextureCoordSetId) {} + else if(id == mTextureTransformId) {} + else if(id == mTextureScrollId) {} + else if(id == mTextureUScrollId) {} + else if(id == mTextureVScrollId) {} + else if(id == mTextureUScaleId) {} + else if(id == mTextureVScaleId) {} + else if(id == mTextureRotateId) {} + else if(id == mTextureAddressingModeId) {} + else if(id == mTextureBorderColourId) {} + else if(id == mColourOperationExId) {} + else if(id == mColourOpMultipassFallbackId) {} + else if(id == mAlphaOperationId) {} + else if(id == mEnvironmentMapId) {} + else if(id == mScrollAnimationId) {} + else if(id == mRotateAnimationId) {} + else if(id == mTransformAnimationId) {} + else if(id == mProjectiveTexturingId) {} + else if(id == mTextureFilteringId) {} + else if(id == mTextureAnisotropyId) {} + else if(id == mTextureMipMapBiasId) {} + else if(id == mNameId) {} + else if(id == mTextureNameAliasId) {} } void TextureUnitPropertyGridPage::textureNameChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureNameId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureNameId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::cubicTextureNameChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mCubicTextureNameId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mCubicTextureNameId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::animatedTextureNameChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mAnimatedTextureNameId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mAnimatedTextureNameId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureDimensionsChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureDimensionsId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureDimensionsId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::currentFrameChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mCurrentFrameId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mCurrentFrameId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::frameTextureNameChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mFrameTextureNameId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mFrameTextureNameId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::frameTextureNameAdded(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mFrameTextureNameId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mFrameTextureNameId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::frameTextureNameRemoved(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mFrameTextureNameId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mFrameTextureNameId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::bindingTypeChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mBindingTypeId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mBindingTypeId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::contentTypeChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mContentTypeId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mContentTypeId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::pixelFormatChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mPixelFormatId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mPixelFormatId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::numMipmapsChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mNumMipMapsId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mNumMipMapsId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::alphaChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mAlphaId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mAlphaId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureCoordSetChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureCoordSetId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureCoordSetId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureTransformChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureTransformId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureTransformId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureScrollChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureScrollId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureScrollId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureUScrollChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureUScrollId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureUScrollId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureVScrollChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureVScrollId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureVScrollId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureUScaleChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureUScaleId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureUScaleId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureVScaleChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureVScaleId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureVScaleId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureRotateChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureRotateId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureRotateId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureAddressingModeChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureAddressingModeId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureAddressingModeId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureBorderColourChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureBorderColourId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureBorderColourId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::colourOperationExChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mColourOperationExId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mColourOperationExId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::colourOpMultipassFallbackChanged( - EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + EventArgs& args) { + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mColourOpMultipassFallbackId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mColourOpMultipassFallbackId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::alphaOperationChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mAlphaOperationId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mAlphaOperationId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::environmentMapChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mEnvironmentMapId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mEnvironmentMapId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::scrollAnimationChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mScrollAnimationId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mScrollAnimationId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::rotateAnimationChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mRotateAnimationId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mRotateAnimationId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::transformAnimationChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTransformAnimationId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTransformAnimationId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::projectiveTexturingChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mProjectiveTexturingId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mProjectiveTexturingId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureFilteringChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureFilteringId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureFilteringId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureAnisotropyChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureAnisotropyId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureAnisotropyId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureMipMapBiasChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureMipMapBiasId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureMipMapBiasId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::nameChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mNameId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mNameId); + if (prop == NULL) + return; } void TextureUnitPropertyGridPage::textureNameAliasChanged(EventArgs& args) { - TextureUnitEventArgs tuea = dynamic_cast(args); - TextureUnitController* tc = tuea.getController(); + TextureUnitEventArgs tuea = dynamic_cast(args); + TextureUnitController* tc = tuea.getController(); - wxPGProperty* prop = GetPropertyPtr(mTextureNameAliasId); - if (prop == NULL) - return; + wxPGProperty* prop = GetPropertyPtr(mTextureNameAliasId); + if (prop == NULL) + return; } diff --git a/Tools/MaterialEditor/MaterialEditor/src/Workspace.cpp b/Tools/MaterialEditor/MaterialEditor/src/Workspace.cpp index 8a81aa0a132..770cce65aa8 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/Workspace.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/Workspace.cpp @@ -35,67 +35,67 @@ template<> Workspace* Ogre::Singleton::msSingleton = 0; Workspace& Workspace::getSingleton(void) { - assert( msSingleton ); return ( *msSingleton ); + assert( msSingleton ); return ( *msSingleton ); } Workspace* Workspace::getSingletonPtr(void) { - return msSingleton; + return msSingleton; } Workspace::Workspace() { - registerEvents(); + registerEvents(); } Workspace::~Workspace() { - ProjectList::iterator it; - for(it = mProjects.begin(); it != mProjects.end(); ++it) - { - delete *it; - } + ProjectList::iterator it; + for(it = mProjects.begin(); it != mProjects.end(); ++it) + { + delete *it; + } } void Workspace::registerEvents() { - registerEvent(ProjectAdded); - registerEvent(ProjectRemoved); + registerEvent(ProjectAdded); + registerEvent(ProjectRemoved); } void Workspace::addProject(Project* project) { - mProjects.push_back(project); - - fireEvent(ProjectAdded, WorkspaceEventArgs(this, project)); + mProjects.push_back(project); + + fireEvent(ProjectAdded, WorkspaceEventArgs(this, project)); } void Workspace::removeProject(Project* project) { - mProjects.remove(project); - fireEvent(ProjectAdded, WorkspaceEventArgs(this, project)); - delete project; + mProjects.remove(project); + fireEvent(ProjectAdded, WorkspaceEventArgs(this, project)); + delete project; } void Workspace::removeProject(const String& name) { - removeProject(getProject(name)); + removeProject(getProject(name)); } Project* Workspace::getProject(const String& name) { - Project* p; - ProjectList::iterator it; - for(it = mProjects.begin(); it != mProjects.end(); ++it) - { - p = (*it); - if(p->getName() == name) return p; - } - - return NULL; + Project* p; + ProjectList::iterator it; + for(it = mProjects.begin(); it != mProjects.end(); ++it) + { + p = (*it); + if(p->getName() == name) return p; + } + + return NULL; } const ProjectList* Workspace::getProjects() const { - return &mProjects; + return &mProjects; } \ No newline at end of file diff --git a/Tools/MaterialEditor/MaterialEditor/src/WorkspaceEventArgs.cpp b/Tools/MaterialEditor/MaterialEditor/src/WorkspaceEventArgs.cpp index 4462f258a78..6ae67d5a89d 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/WorkspaceEventArgs.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/WorkspaceEventArgs.cpp @@ -45,11 +45,11 @@ WorkspaceEventArgs::~WorkspaceEventArgs() Workspace* WorkspaceEventArgs::getWorkspace() { - return mWorkspace; + return mWorkspace; } Project* WorkspaceEventArgs::getProject() { - return mProject; + return mProject; } diff --git a/Tools/MaterialEditor/MaterialEditor/src/WorkspacePanel.cpp b/Tools/MaterialEditor/MaterialEditor/src/WorkspacePanel.cpp index 82fe36f7512..24a627c21bd 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/WorkspacePanel.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/WorkspacePanel.cpp @@ -70,7 +70,7 @@ THE SOFTWARE. namespace { - class Ogre::MaterialSerializer; + class Ogre::MaterialSerializer; } const long ID_TREE_CTRL = wxNewId(); @@ -86,33 +86,33 @@ const long ID_MENU_PASS_ENABLED = wxNewId(); const long ID_MENU_DELETE = wxNewId(); BEGIN_EVENT_TABLE(WorkspacePanel, wxPanel) - EVT_TREE_ITEM_RIGHT_CLICK(ID_TREE_CTRL, WorkspacePanel::OnRightClick) - EVT_TREE_ITEM_ACTIVATED(ID_TREE_CTRL, WorkspacePanel::OnActivate) - EVT_TREE_SEL_CHANGED(ID_TREE_CTRL, WorkspacePanel::OnSelectionChanged) - EVT_MENU(ID_MENU_NEW_PROJECT, WorkspacePanel::OnNewProject) - EVT_MENU(ID_MENU_NEW_MATERIAL_SCRIPT, WorkspacePanel::OnNewMaterialScript) - EVT_MENU(ID_MENU_NEW_MATERIAL, WorkspacePanel::OnNewMaterial) - EVT_MENU(ID_MENU_NEW_TECHNIQUE, WorkspacePanel::OnNewTechnique) - EVT_MENU(ID_MENU_NEW_PASS, WorkspacePanel::OnNewPass) - EVT_MENU(ID_MENU_ADD_MATERIAL, WorkspacePanel::OnAddMaterial) - EVT_MENU(ID_MENU_EDIT, WorkspacePanel::OnEdit) - EVT_UPDATE_UI(ID_MENU_NEW_MATERIAL, WorkspacePanel::OnUpdateMaterialMenuItem) - EVT_UPDATE_UI(ID_MENU_NEW_TECHNIQUE, WorkspacePanel::OnUpdateTechniqueMenuItem) - EVT_UPDATE_UI(ID_MENU_NEW_PASS, WorkspacePanel::OnUpdatePassMenuItem) + EVT_TREE_ITEM_RIGHT_CLICK(ID_TREE_CTRL, WorkspacePanel::OnRightClick) + EVT_TREE_ITEM_ACTIVATED(ID_TREE_CTRL, WorkspacePanel::OnActivate) + EVT_TREE_SEL_CHANGED(ID_TREE_CTRL, WorkspacePanel::OnSelectionChanged) + EVT_MENU(ID_MENU_NEW_PROJECT, WorkspacePanel::OnNewProject) + EVT_MENU(ID_MENU_NEW_MATERIAL_SCRIPT, WorkspacePanel::OnNewMaterialScript) + EVT_MENU(ID_MENU_NEW_MATERIAL, WorkspacePanel::OnNewMaterial) + EVT_MENU(ID_MENU_NEW_TECHNIQUE, WorkspacePanel::OnNewTechnique) + EVT_MENU(ID_MENU_NEW_PASS, WorkspacePanel::OnNewPass) + EVT_MENU(ID_MENU_ADD_MATERIAL, WorkspacePanel::OnAddMaterial) + EVT_MENU(ID_MENU_EDIT, WorkspacePanel::OnEdit) + EVT_UPDATE_UI(ID_MENU_NEW_MATERIAL, WorkspacePanel::OnUpdateMaterialMenuItem) + EVT_UPDATE_UI(ID_MENU_NEW_TECHNIQUE, WorkspacePanel::OnUpdateTechniqueMenuItem) + EVT_UPDATE_UI(ID_MENU_NEW_PASS, WorkspacePanel::OnUpdatePassMenuItem) END_EVENT_TABLE() WorkspacePanel::WorkspacePanel(wxWindow* parent, - wxWindowID id /* = wxID_ANY */, - const wxPoint& pos /* = wxDefaultPosition */, - const wxSize& size /* = wxDefaultSize */, - long style /* = wxTAB_TRAVERSAL | wxNO_BORDER */, - const wxString& name /* = wxT("Workspace Panel")) */) - : mImageList(NULL), wxPanel(parent, id, pos, size, style, name) + wxWindowID id /* = wxID_ANY */, + const wxPoint& pos /* = wxDefaultPosition */, + const wxSize& size /* = wxDefaultSize */, + long style /* = wxTAB_TRAVERSAL | wxNO_BORDER */, + const wxString& name /* = wxT("Workspace Panel")) */) + : mImageList(NULL), wxPanel(parent, id, pos, size, style, name) { - createPanel(); + createPanel(); - Workspace::getSingletonPtr()->subscribe(Workspace::ProjectAdded, boost::bind(&WorkspacePanel::projectAdded, this, _1)); - Workspace::getSingletonPtr()->subscribe(Workspace::ProjectRemoved, boost::bind(&WorkspacePanel::projectRemoved, this, _1)); + Workspace::getSingletonPtr()->subscribe(Workspace::ProjectAdded, boost::bind(&WorkspacePanel::projectAdded, this, _1)); + Workspace::getSingletonPtr()->subscribe(Workspace::ProjectRemoved, boost::bind(&WorkspacePanel::projectRemoved, this, _1)); } WorkspacePanel::~WorkspacePanel() @@ -121,69 +121,69 @@ WorkspacePanel::~WorkspacePanel() void WorkspacePanel::createPanel() { - mSizer = new wxFlexGridSizer(1, 1, 0, 0); - mSizer->AddGrowableCol(0); - mSizer->AddGrowableRow(0); - mSizer->SetFlexibleDirection(wxVERTICAL); - mSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + mSizer = new wxFlexGridSizer(1, 1, 0, 0); + mSizer->AddGrowableCol(0); + mSizer->AddGrowableRow(0); + mSizer->SetFlexibleDirection(wxVERTICAL); + mSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - //mToolBarPanel = new wxPanel(this); - //mSizer->Add(mToolBarPanel, 1, wxALL | wxEXPAND, 0); + //mToolBarPanel = new wxPanel(this); + //mSizer->Add(mToolBarPanel, 1, wxALL | wxEXPAND, 0); - mTreeCtrl = new wxTreeCtrl(this, ID_TREE_CTRL, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxTR_FULL_ROW_HIGHLIGHT | wxTR_HAS_BUTTONS | wxTR_SINGLE); - mTreeCtrl->AssignImageList(getImageList()); - mRootId = mTreeCtrl->AddRoot(wxT("Workspace"), WORKSPACE_IMAGE); + mTreeCtrl = new wxTreeCtrl(this, ID_TREE_CTRL, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxTR_FULL_ROW_HIGHLIGHT | wxTR_HAS_BUTTONS | wxTR_SINGLE); + mTreeCtrl->AssignImageList(getImageList()); + mRootId = mTreeCtrl->AddRoot(wxT("Workspace"), WORKSPACE_IMAGE); - mSizer->Add(mTreeCtrl, 0, wxALL | wxEXPAND, 0); + mSizer->Add(mTreeCtrl, 0, wxALL | wxEXPAND, 0); - SetSizer(mSizer); - Layout(); + SetSizer(mSizer); + Layout(); } wxImageList* WorkspacePanel::getImageList() { - if(mImageList == NULL) - { - mImageList = new wxImageList(16, 16, true, 6); - mImageList->Add(IconManager::getSingleton().getIcon(IconManager::WORKSPACE)); - mImageList->Add(IconManager::getSingleton().getIcon(IconManager::PROJECT)); - mImageList->Add(IconManager::getSingleton().getIcon(IconManager::MATERIAL_SCRIPT)); - mImageList->Add(IconManager::getSingleton().getIcon(IconManager::MATERIAL)); - mImageList->Add(IconManager::getSingleton().getIcon(IconManager::TECHNIQUE)); - mImageList->Add(IconManager::getSingleton().getIcon(IconManager::PASS)); - } + if(mImageList == NULL) + { + mImageList = new wxImageList(16, 16, true, 6); + mImageList->Add(IconManager::getSingleton().getIcon(IconManager::WORKSPACE)); + mImageList->Add(IconManager::getSingleton().getIcon(IconManager::PROJECT)); + mImageList->Add(IconManager::getSingleton().getIcon(IconManager::MATERIAL_SCRIPT)); + mImageList->Add(IconManager::getSingleton().getIcon(IconManager::MATERIAL)); + mImageList->Add(IconManager::getSingleton().getIcon(IconManager::TECHNIQUE)); + mImageList->Add(IconManager::getSingleton().getIcon(IconManager::PASS)); + } - return mImageList; + return mImageList; } void WorkspacePanel::showContextMenu(wxPoint point, wxTreeItemId id) { - wxMenu contextMenu; - appendNewMenu(&contextMenu); - contextMenu.AppendSeparator(); - if(isProject(id)) appendProjectMenuItems(&contextMenu); - else if(isMaterial(id)) appendMaterialMenuItems(&contextMenu); - else if(isTechnique(id)) appendTechniqueMenuItems(&contextMenu); - //else appendPassMenuItems(&contextMenu); - contextMenu.Append(ID_MENU_EDIT, wxT("Edit")); - PopupMenu(&contextMenu, point); + wxMenu contextMenu; + appendNewMenu(&contextMenu); + contextMenu.AppendSeparator(); + if(isProject(id)) appendProjectMenuItems(&contextMenu); + else if(isMaterial(id)) appendMaterialMenuItems(&contextMenu); + else if(isTechnique(id)) appendTechniqueMenuItems(&contextMenu); + //else appendPassMenuItems(&contextMenu); + contextMenu.Append(ID_MENU_EDIT, wxT("Edit")); + PopupMenu(&contextMenu, point); } void WorkspacePanel::appendNewMenu(wxMenu* menu) { - wxMenu* newMenu = new wxMenu(); - newMenu->Append(ID_MENU_NEW_PROJECT, wxT("Project")); - newMenu->Append(ID_MENU_NEW_MATERIAL_SCRIPT, wxT("Material Script")); - newMenu->Append(ID_MENU_NEW_MATERIAL, wxT("Material")); - newMenu->Append(ID_MENU_NEW_TECHNIQUE, wxT("Technique")); - newMenu->Append(ID_MENU_NEW_PASS, wxT("Pass")); + wxMenu* newMenu = new wxMenu(); + newMenu->Append(ID_MENU_NEW_PROJECT, wxT("Project")); + newMenu->Append(ID_MENU_NEW_MATERIAL_SCRIPT, wxT("Material Script")); + newMenu->Append(ID_MENU_NEW_MATERIAL, wxT("Material")); + newMenu->Append(ID_MENU_NEW_TECHNIQUE, wxT("Technique")); + newMenu->Append(ID_MENU_NEW_PASS, wxT("Pass")); - menu->AppendSubMenu(newMenu, wxT("New")); + menu->AppendSubMenu(newMenu, wxT("New")); } void WorkspacePanel::appendProjectMenuItems(wxMenu* menu) { - menu->Append(ID_MENU_ADD_MATERIAL, wxT("Add Material")); + menu->Append(ID_MENU_ADD_MATERIAL, wxT("Add Material")); } void WorkspacePanel::appendMaterialMenuItems(wxMenu* menu) @@ -196,429 +196,429 @@ void WorkspacePanel::appendTechniqueMenuItems(wxMenu* menu) void WorkspacePanel::appendPassMenuItems(wxMenu* menu) { - menu->AppendCheckItem(ID_MENU_PASS_ENABLED, wxT("Enabled")); + menu->AppendCheckItem(ID_MENU_PASS_ENABLED, wxT("Enabled")); } Project* WorkspacePanel::getProject(wxTreeItemId id) { - for(ProjectIdMap::iterator it = mProjectIdMap.begin(); it != mProjectIdMap.end(); ++it) - { - if(it->second == id) return it->first; - } + for(ProjectIdMap::iterator it = mProjectIdMap.begin(); it != mProjectIdMap.end(); ++it) + { + if(it->second == id) return it->first; + } - return NULL; + return NULL; } MaterialController* WorkspacePanel::getMaterial(wxTreeItemId id) { - for(MaterialIdMap::iterator it = mMaterialIdMap.begin(); it != mMaterialIdMap.end(); ++it) - { - if(it->second == id) return it->first; - } + for(MaterialIdMap::iterator it = mMaterialIdMap.begin(); it != mMaterialIdMap.end(); ++it) + { + if(it->second == id) return it->first; + } - return NULL; + return NULL; } TechniqueController* WorkspacePanel::getTechnique(wxTreeItemId id) { - for(TechniqueIdMap::iterator it = mTechniqueIdMap.begin(); it != mTechniqueIdMap.end(); ++it) - { - if(it->second == id) return it->first; - } + for(TechniqueIdMap::iterator it = mTechniqueIdMap.begin(); it != mTechniqueIdMap.end(); ++it) + { + if(it->second == id) return it->first; + } - return NULL; + return NULL; } PassController* WorkspacePanel::getPass(wxTreeItemId id) { - for(PassIdMap::iterator it = mPassIdMap.begin(); it != mPassIdMap.end(); ++it) - { - if(it->second == id) return it->first; - } + for(PassIdMap::iterator it = mPassIdMap.begin(); it != mPassIdMap.end(); ++it) + { + if(it->second == id) return it->first; + } - return NULL; + return NULL; } bool WorkspacePanel::isWorkspace(wxTreeItemId id) { - return mRootId == id; + return mRootId == id; } bool WorkspacePanel::isProject(wxTreeItemId id) { - return getProject(id) != NULL; + return getProject(id) != NULL; } bool WorkspacePanel::isMaterial(wxTreeItemId id) { - return getMaterial(id) != NULL; + return getMaterial(id) != NULL; } bool WorkspacePanel::isTechnique(wxTreeItemId id) { - return getTechnique(id) != NULL; + return getTechnique(id) != NULL; } bool WorkspacePanel::isPass(wxTreeItemId id) { - return getPass(id) != NULL; + return getPass(id) != NULL; } void WorkspacePanel::subscribe(Project* project) { - project->subscribe(Project::NameChanged, boost::bind(&WorkspacePanel::projectNameChanged, this, _1)); - project->subscribe(Project::MaterialAdded, boost::bind(&WorkspacePanel::projectMaterialAdded, this, _1)); - project->subscribe(Project::MaterialRemoved, boost::bind(&WorkspacePanel::projectMaterialRemoved, this, _1)); + project->subscribe(Project::NameChanged, boost::bind(&WorkspacePanel::projectNameChanged, this, _1)); + project->subscribe(Project::MaterialAdded, boost::bind(&WorkspacePanel::projectMaterialAdded, this, _1)); + project->subscribe(Project::MaterialRemoved, boost::bind(&WorkspacePanel::projectMaterialRemoved, this, _1)); } void WorkspacePanel::subscribe(MaterialController* material) { - material->subscribe(MaterialController::NameChanged, boost::bind(&WorkspacePanel::materialNameChanged, this, _1)); - material->subscribe(MaterialController::TechniqueAdded, boost::bind(&WorkspacePanel::materialTechniqueAdded, this, _1)); - material->subscribe(MaterialController::TechniqueRemoved, boost::bind(&WorkspacePanel::materialTechniqueRemoved, this, _1)); + material->subscribe(MaterialController::NameChanged, boost::bind(&WorkspacePanel::materialNameChanged, this, _1)); + material->subscribe(MaterialController::TechniqueAdded, boost::bind(&WorkspacePanel::materialTechniqueAdded, this, _1)); + material->subscribe(MaterialController::TechniqueRemoved, boost::bind(&WorkspacePanel::materialTechniqueRemoved, this, _1)); } void WorkspacePanel::subscribe(TechniqueController* technique) { - technique->subscribe(TechniqueController::NameChanged, boost::bind(&WorkspacePanel::techniqueNameChanged, this, _1)); - technique->subscribe(TechniqueController::PassAdded, boost::bind(&WorkspacePanel::techniquePassAdded, this, _1)); - technique->subscribe(TechniqueController::PassRemoved, boost::bind(&WorkspacePanel::techniquePassRemoved, this, _1)); + technique->subscribe(TechniqueController::NameChanged, boost::bind(&WorkspacePanel::techniqueNameChanged, this, _1)); + technique->subscribe(TechniqueController::PassAdded, boost::bind(&WorkspacePanel::techniquePassAdded, this, _1)); + technique->subscribe(TechniqueController::PassRemoved, boost::bind(&WorkspacePanel::techniquePassRemoved, this, _1)); } void WorkspacePanel::OnRightClick(wxTreeEvent& event) { - showContextMenu(event.GetPoint(), event.GetItem()); + showContextMenu(event.GetPoint(), event.GetItem()); } void WorkspacePanel::OnActivate(wxTreeEvent& event) { - OnEdit(event); + OnEdit(event); } void WorkspacePanel::OnSelectionChanged(wxTreeEvent& event) { - SelectionList list; - wxTreeItemId id = event.GetItem(); - if(isProject(id)) list.push_back(getProject(id)); - else if(isMaterial(id)) list.push_back(getMaterial(id)); - else if(isTechnique(id)) list.push_back(getTechnique(id)); - else if(isPass(id)) list.push_back(getPass(id)); - // else its the workspace so just leave the list empty as if nothing were selected + SelectionList list; + wxTreeItemId id = event.GetItem(); + if(isProject(id)) list.push_back(getProject(id)); + else if(isMaterial(id)) list.push_back(getMaterial(id)); + else if(isTechnique(id)) list.push_back(getTechnique(id)); + else if(isPass(id)) list.push_back(getPass(id)); + // else its the workspace so just leave the list empty as if nothing were selected - SelectionService::getSingletonPtr()->setSelection(list); + SelectionService::getSingletonPtr()->setSelection(list); } void WorkspacePanel::OnNewProject(wxCommandEvent& event) { - ProjectWizard* wizard = new ProjectWizard(); - wizard->Create(this, wxID_ANY, wxT("New Project"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); - wizard->RunWizard(wizard->getProjectPage()); // This seems unnatural, seems there must be a better way to deal with wizards + ProjectWizard* wizard = new ProjectWizard(); + wizard->Create(this, wxID_ANY, wxT("New Project"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + wizard->RunWizard(wizard->getProjectPage()); // This seems unnatural, seems there must be a better way to deal with wizards - wizard->Destroy(); + wizard->Destroy(); - delete wizard; + delete wizard; } void WorkspacePanel::OnNewMaterialScript(wxCommandEvent& event) { - wxTreeItemId id = mTreeCtrl->GetSelection(); - mTreeCtrl->AppendItem(id, "Material Script", MATERIAL_SCRIPT_IMAGE); + wxTreeItemId id = mTreeCtrl->GetSelection(); + mTreeCtrl->AppendItem(id, "Material Script", MATERIAL_SCRIPT_IMAGE); } void WorkspacePanel::OnNewMaterial(wxCommandEvent& event) { - wxTreeItemId id = mTreeCtrl->GetSelection(); + wxTreeItemId id = mTreeCtrl->GetSelection(); - MaterialWizard* wizard = new MaterialWizard(); - wizard->Create(this, wxID_ANY, wxT("New Project"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); - wizard->getMaterialPage()->setProject(getProject(id)); - wizard->RunWizard(wizard->getMaterialPage()); // This seems unnatural, seems there must be a better way to deal with wizards + MaterialWizard* wizard = new MaterialWizard(); + wizard->Create(this, wxID_ANY, wxT("New Project"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + wizard->getMaterialPage()->setProject(getProject(id)); + wizard->RunWizard(wizard->getMaterialPage()); // This seems unnatural, seems there must be a better way to deal with wizards - wizard->Destroy(); + wizard->Destroy(); - delete wizard; + delete wizard; } void WorkspacePanel::OnNewTechnique(wxCommandEvent& event) { - Project* project = NULL; - MaterialController* material = NULL; + Project* project = NULL; + MaterialController* material = NULL; - wxTreeItemId selId = mTreeCtrl->GetSelection(); - if(isProject(selId)) - { - project = getProject(selId); - } - else if(isMaterial(selId)) - { - wxTreeItemId projectId = mTreeCtrl->GetItemParent(selId); - project = getProject(projectId); + wxTreeItemId selId = mTreeCtrl->GetSelection(); + if(isProject(selId)) + { + project = getProject(selId); + } + else if(isMaterial(selId)) + { + wxTreeItemId projectId = mTreeCtrl->GetItemParent(selId); + project = getProject(projectId); - material = getMaterial(selId); - } + material = getMaterial(selId); + } - TechniqueWizard* wizard = new TechniqueWizard(); - wizard->Create(this, wxID_ANY, wxT("New Technique"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); - wizard->getTechniquePage()->setProject(project); - wizard->getTechniquePage()->setMaterial(material); - wizard->RunWizard(wizard->getTechniquePage()); // This seems unnatural, seems there must be a better way to deal with wizards + TechniqueWizard* wizard = new TechniqueWizard(); + wizard->Create(this, wxID_ANY, wxT("New Technique"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + wizard->getTechniquePage()->setProject(project); + wizard->getTechniquePage()->setMaterial(material); + wizard->RunWizard(wizard->getTechniquePage()); // This seems unnatural, seems there must be a better way to deal with wizards - wizard->Destroy(); + wizard->Destroy(); - delete wizard; + delete wizard; } void WorkspacePanel::OnNewPass(wxCommandEvent& event) { - Project* project = NULL; - MaterialController* material = NULL; - TechniqueController* technique = NULL; - - wxTreeItemId selId = mTreeCtrl->GetSelection(); - if(isProject(selId)) - { - project = getProject(selId); - } - else if(isMaterial(selId)) - { - wxTreeItemId projectId = mTreeCtrl->GetItemParent(selId); - project = getProject(projectId); - - material = getMaterial(selId); - } - else if(isTechnique(selId)) - { - wxTreeItemId materialId = mTreeCtrl->GetItemParent(selId); - material = getMaterial(materialId); - - wxTreeItemId projectId = mTreeCtrl->GetItemParent(materialId); - project = getProject(projectId); - - technique = getTechnique(selId); - } - - PassWizard* wizard = new PassWizard(); - wizard->Create(this, wxID_ANY, wxT("New Pass"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); - wizard->getPassPage()->setProject(project); - wizard->getPassPage()->setMaterial(material); - wizard->getPassPage()->setTechnique(technique); - wizard->RunWizard(wizard->getPassPage()); - - wizard->Destroy(); - - delete wizard; + Project* project = NULL; + MaterialController* material = NULL; + TechniqueController* technique = NULL; + + wxTreeItemId selId = mTreeCtrl->GetSelection(); + if(isProject(selId)) + { + project = getProject(selId); + } + else if(isMaterial(selId)) + { + wxTreeItemId projectId = mTreeCtrl->GetItemParent(selId); + project = getProject(projectId); + + material = getMaterial(selId); + } + else if(isTechnique(selId)) + { + wxTreeItemId materialId = mTreeCtrl->GetItemParent(selId); + material = getMaterial(materialId); + + wxTreeItemId projectId = mTreeCtrl->GetItemParent(materialId); + project = getProject(projectId); + + technique = getTechnique(selId); + } + + PassWizard* wizard = new PassWizard(); + wizard->Create(this, wxID_ANY, wxT("New Pass"), wxNullBitmap, wxDefaultPosition, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + wizard->getPassPage()->setProject(project); + wizard->getPassPage()->setMaterial(material); + wizard->getPassPage()->setTechnique(technique); + wizard->RunWizard(wizard->getPassPage()); + + wizard->Destroy(); + + delete wizard; } void WorkspacePanel::OnAddMaterial(wxCommandEvent& event) { - wxFileDialog * openDialog = new wxFileDialog(this, wxT("Add a Material"), wxEmptyString, wxEmptyString, - wxT("Material Files (*.material)|*.material|All Files (*.*)|*.*")); + wxFileDialog * openDialog = new wxFileDialog(this, wxT("Add a Material"), wxEmptyString, wxEmptyString, + wxT("Material Files (*.material)|*.material|All Files (*.*)|*.*")); - if(openDialog->ShowModal() == wxID_OK) - { - wxString path = openDialog->GetPath(); - if(path.EndsWith(wxT(".material"))) - { - wxTreeItemId selId = mTreeCtrl->GetSelection(); - if(isProject(selId)) - { - Project* project = getProject(selId); + if(openDialog->ShowModal() == wxID_OK) + { + wxString path = openDialog->GetPath(); + if(path.EndsWith(wxT(".material"))) + { + wxTreeItemId selId = mTreeCtrl->GetSelection(); + if(isProject(selId)) + { + Project* project = getProject(selId); - MaterialScriptEditor* editor = new MaterialScriptEditor(EditorManager::getSingletonPtr()->getEditorNotebook()); - editor->loadFile(path); - int index = (int)path.find_last_of('\\'); - if(index == -1) index = (int)path.find_last_of('/'); - editor->setName((index != -1) ? path.substr(index + 1, path.Length()) : path); + MaterialScriptEditor* editor = new MaterialScriptEditor(EditorManager::getSingletonPtr()->getEditorNotebook()); + editor->loadFile(path); + int index = (int)path.find_last_of('\\'); + if(index == -1) index = (int)path.find_last_of('/'); + editor->setName((index != -1) ? path.substr(index + 1, path.Length()) : path); - EditorManager::getSingletonPtr()->openEditor(editor); + EditorManager::getSingletonPtr()->openEditor(editor); - Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName("Ogre/Earring"); - project->addMaterial(mat); - } - } - } + Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName("Ogre/Earring"); + project->addMaterial(mat); + } + } + } } void WorkspacePanel::OnEdit(wxCommandEvent& event) { - wxTreeItemId selId = mTreeCtrl->GetSelection(); - if(isMaterial(selId)) - { - MaterialController* mc = getMaterial(selId); - - EditorManager* editorManager = EditorManager::getSingletonPtr(); - Editor* editor = editorManager->findEditor(mc->getMaterial()->getName().c_str()); - Editor* editorMat = editorManager->findEditor(Ogre::String(mc->getMaterial()->getName() + ".material").c_str()); - if(editor != NULL) - { - editorManager->setActiveEditor(editor); - } - else if(editorMat != NULL) - { - editorManager->setActiveEditor(editorMat); - } - else - { - MaterialSerializer* ms = new MaterialSerializer(); - ms->queueForExport(mc->getMaterial(), true); - String script = ms->getQueuedAsString(); - - MaterialScriptEditor* materialEditor = new MaterialScriptEditor(editorManager->getEditorNotebook(), wxID_ANY); - wxString name = mc->getMaterial()->getName().c_str(); - name += wxT(".material"); - materialEditor->setName(name); - materialEditor->SetText(script); - - editorManager->openEditor(materialEditor); - } - } + wxTreeItemId selId = mTreeCtrl->GetSelection(); + if(isMaterial(selId)) + { + MaterialController* mc = getMaterial(selId); + + EditorManager* editorManager = EditorManager::getSingletonPtr(); + Editor* editor = editorManager->findEditor(mc->getMaterial()->getName().c_str()); + Editor* editorMat = editorManager->findEditor(Ogre::String(mc->getMaterial()->getName() + ".material").c_str()); + if(editor != NULL) + { + editorManager->setActiveEditor(editor); + } + else if(editorMat != NULL) + { + editorManager->setActiveEditor(editorMat); + } + else + { + MaterialSerializer* ms = new MaterialSerializer(); + ms->queueForExport(mc->getMaterial(), true); + String script = ms->getQueuedAsString(); + + MaterialScriptEditor* materialEditor = new MaterialScriptEditor(editorManager->getEditorNotebook(), wxID_ANY); + wxString name = mc->getMaterial()->getName().c_str(); + name += wxT(".material"); + materialEditor->setName(name); + materialEditor->SetText(script); + + editorManager->openEditor(materialEditor); + } + } } void WorkspacePanel::OnUpdateMaterialMenuItem(wxUpdateUIEvent& event) { - event.Enable(!Workspace::getSingletonPtr()->getProjects()->empty()); + event.Enable(!Workspace::getSingletonPtr()->getProjects()->empty()); } void WorkspacePanel::OnUpdateTechniqueMenuItem(wxUpdateUIEvent& event) { - bool enable = false; - const ProjectList* projects = Workspace::getSingletonPtr()->getProjects(); - - ProjectList::const_iterator it; - for(it = projects->begin(); it != projects->end(); ++it) - { - if(!(*it)->getMaterials()->empty()) - { - enable = true; - break; - } - } - - event.Enable(enable); + bool enable = false; + const ProjectList* projects = Workspace::getSingletonPtr()->getProjects(); + + ProjectList::const_iterator it; + for(it = projects->begin(); it != projects->end(); ++it) + { + if(!(*it)->getMaterials()->empty()) + { + enable = true; + break; + } + } + + event.Enable(enable); } void WorkspacePanel::OnUpdatePassMenuItem(wxUpdateUIEvent& event) { - bool enable = false; - const ProjectList* projects = Workspace::getSingletonPtr()->getProjects(); - - ProjectList::const_iterator pit; - for(pit = projects->begin(); pit != projects->end(); ++pit) - { - const MaterialControllerList* materials = (*pit)->getMaterials(); - MaterialControllerList::const_iterator mit; - for(mit = materials->begin(); mit != materials->end(); ++mit) - { - if(!(*mit)->getTechniqueControllers()->empty()) - { - enable = true; - break; - } - } - } - - event.Enable(enable); + bool enable = false; + const ProjectList* projects = Workspace::getSingletonPtr()->getProjects(); + + ProjectList::const_iterator pit; + for(pit = projects->begin(); pit != projects->end(); ++pit) + { + const MaterialControllerList* materials = (*pit)->getMaterials(); + MaterialControllerList::const_iterator mit; + for(mit = materials->begin(); mit != materials->end(); ++mit) + { + if(!(*mit)->getTechniqueControllers()->empty()) + { + enable = true; + break; + } + } + } + + event.Enable(enable); } void WorkspacePanel::projectAdded(EventArgs& args) { - WorkspaceEventArgs wea = dynamic_cast(args); - Project* project = wea.getProject(); - subscribe(project); + WorkspaceEventArgs wea = dynamic_cast(args); + Project* project = wea.getProject(); + subscribe(project); - wxTreeItemId id = mTreeCtrl->AppendItem(mRootId, project->getName().c_str(), PROJECT_IMAGE); - mTreeCtrl->SelectItem(id, true); + wxTreeItemId id = mTreeCtrl->AppendItem(mRootId, project->getName().c_str(), PROJECT_IMAGE); + mTreeCtrl->SelectItem(id, true); - mProjectIdMap[project] = id; + mProjectIdMap[project] = id; } void WorkspacePanel::projectRemoved(EventArgs& args) { - // TODO: Implement projectRemoved + // TODO: Implement projectRemoved } void WorkspacePanel::projectNameChanged(EventArgs& args) { - ProjectEventArgs pea = dynamic_cast(args); - Project* project = pea.getProject(); + ProjectEventArgs pea = dynamic_cast(args); + Project* project = pea.getProject(); - wxTreeItemId projectId = mProjectIdMap[project]; - mTreeCtrl->SetItemText(projectId, project->getName().c_str()); + wxTreeItemId projectId = mProjectIdMap[project]; + mTreeCtrl->SetItemText(projectId, project->getName().c_str()); } void WorkspacePanel::projectMaterialAdded(EventArgs& args) { - ProjectEventArgs pea = dynamic_cast(args); - Project* project = pea.getProject(); - MaterialController* material = pea.getMaterial(); + ProjectEventArgs pea = dynamic_cast(args); + Project* project = pea.getProject(); + MaterialController* material = pea.getMaterial(); - wxTreeItemId projectId = mProjectIdMap[project]; - wxTreeItemId id = mTreeCtrl->AppendItem(projectId, material->getMaterial()->getName().c_str(), MATERIAL_IMAGE); - mTreeCtrl->SelectItem(id, true); + wxTreeItemId projectId = mProjectIdMap[project]; + wxTreeItemId id = mTreeCtrl->AppendItem(projectId, material->getMaterial()->getName().c_str(), MATERIAL_IMAGE); + mTreeCtrl->SelectItem(id, true); - mMaterialIdMap[material] = id; + mMaterialIdMap[material] = id; - subscribe(material); + subscribe(material); } void WorkspacePanel::projectMaterialRemoved(EventArgs& args) { - // TODO: Implement projectMaterialRemoved + // TODO: Implement projectMaterialRemoved } void WorkspacePanel::materialNameChanged(EventArgs& args) { - MaterialEventArgs mea = dynamic_cast(args); - MaterialController* mc = mea.getMaterialController(); + MaterialEventArgs mea = dynamic_cast(args); + MaterialController* mc = mea.getMaterialController(); - wxTreeItemId materialId = mMaterialIdMap[mc]; - mTreeCtrl->SetItemText(materialId, mc->getMaterial()->getName().c_str()); + wxTreeItemId materialId = mMaterialIdMap[mc]; + mTreeCtrl->SetItemText(materialId, mc->getMaterial()->getName().c_str()); } void WorkspacePanel::materialTechniqueAdded(EventArgs& args) { - MaterialEventArgs mea = dynamic_cast(args); - MaterialController* mc = mea.getMaterialController(); - TechniqueController* tc = mea.getTechniqueController(); + MaterialEventArgs mea = dynamic_cast(args); + MaterialController* mc = mea.getMaterialController(); + TechniqueController* tc = mea.getTechniqueController(); - wxTreeItemId materialId = mMaterialIdMap[mc]; - wxTreeItemId id = mTreeCtrl->AppendItem(materialId, tc->getTechnique()->getName().c_str(), TECHNIQUE_IMAGE); - mTreeCtrl->SelectItem(id, true); - - mTechniqueIdMap[tc] = id; + wxTreeItemId materialId = mMaterialIdMap[mc]; + wxTreeItemId id = mTreeCtrl->AppendItem(materialId, tc->getTechnique()->getName().c_str(), TECHNIQUE_IMAGE); + mTreeCtrl->SelectItem(id, true); + + mTechniqueIdMap[tc] = id; - subscribe(tc); + subscribe(tc); } void WorkspacePanel::materialTechniqueRemoved(EventArgs& args) { - // TODO: Implement materialTechniqueRemoved + // TODO: Implement materialTechniqueRemoved } void WorkspacePanel::techniqueNameChanged(EventArgs& args) { - TechniqueEventArgs tea = dynamic_cast(args); - TechniqueController* tc = tea.getTechniqueController(); + TechniqueEventArgs tea = dynamic_cast(args); + TechniqueController* tc = tea.getTechniqueController(); - wxTreeItemId techniqueId = mTechniqueIdMap[tc]; - mTreeCtrl->SetItemText(techniqueId, tc->getTechnique()->getName().c_str()); + wxTreeItemId techniqueId = mTechniqueIdMap[tc]; + mTreeCtrl->SetItemText(techniqueId, tc->getTechnique()->getName().c_str()); } void WorkspacePanel::techniquePassAdded(EventArgs& args) { - TechniqueEventArgs tea = dynamic_cast(args); - TechniqueController* tc = tea.getTechniqueController(); - PassController* pc = tea.getPassController(); + TechniqueEventArgs tea = dynamic_cast(args); + TechniqueController* tc = tea.getTechniqueController(); + PassController* pc = tea.getPassController(); - wxTreeItemId techniqueId = mTechniqueIdMap[tc]; - wxTreeItemId id = mTreeCtrl->AppendItem(techniqueId, pc->getPass()->getName().c_str(), PASS_IMAGE); - mTreeCtrl->SelectItem(id, true); + wxTreeItemId techniqueId = mTechniqueIdMap[tc]; + wxTreeItemId id = mTreeCtrl->AppendItem(techniqueId, pc->getPass()->getName().c_str(), PASS_IMAGE); + mTreeCtrl->SelectItem(id, true); - mPassIdMap[pc] = id; + mPassIdMap[pc] = id; } void WorkspacePanel::techniquePassRemoved(EventArgs& args) { - // TODO: Implement materialTechniqueRemoved + // TODO: Implement materialTechniqueRemoved } diff --git a/Tools/MaterialEditor/MaterialEditor/src/wxOgre.cpp b/Tools/MaterialEditor/MaterialEditor/src/wxOgre.cpp index 2f24a20d234..3a0c9982dd7 100644 --- a/Tools/MaterialEditor/MaterialEditor/src/wxOgre.cpp +++ b/Tools/MaterialEditor/MaterialEditor/src/wxOgre.cpp @@ -13,245 +13,245 @@ IMPLEMENT_CLASS(wxOgre, wxControl) // Required for WX BEGIN_EVENT_TABLE(wxOgre, wxControl) - EVT_SIZE(wxOgre::OnSize) - // EVT_PAINT(wxOgre::OnPaint) // Produces flickers and runs too fast! - EVT_ERASE_BACKGROUND(wxOgre::OnEraseBackground) - EVT_TIMER(ID_RENDERTIMER, wxOgre::OnRenderTimer) - EVT_LEFT_DOWN(wxOgre::OnMouseDown) - EVT_MIDDLE_DOWN(wxOgre::OnMouseDown) - EVT_RIGHT_DOWN(wxOgre::OnMouseDown) - EVT_MOTION(wxOgre::OnMouseMotion) - EVT_MOUSEWHEEL(wxOgre::OnMouseWheel) + EVT_SIZE(wxOgre::OnSize) + // EVT_PAINT(wxOgre::OnPaint) // Produces flickers and runs too fast! + EVT_ERASE_BACKGROUND(wxOgre::OnEraseBackground) + EVT_TIMER(ID_RENDERTIMER, wxOgre::OnRenderTimer) + EVT_LEFT_DOWN(wxOgre::OnMouseDown) + EVT_MIDDLE_DOWN(wxOgre::OnMouseDown) + EVT_RIGHT_DOWN(wxOgre::OnMouseDown) + EVT_MOTION(wxOgre::OnMouseMotion) + EVT_MOUSEWHEEL(wxOgre::OnMouseWheel) END_EVENT_TABLE() wxOgre::wxOgre(wxFrame* parent, Ogre::RenderSystem* renderSystem) : - wxControl(parent, -1), - mTimer(this, ID_RENDERTIMER), - mRoot(0), - mViewPort(0), - mCamera(0), - mSceneMgr(0), - mRenderWindow(0), - mCameraYawNode(0), - mCameraPitchNode(0), - mLightYawNode(0), - mLightPitchNode(0), - mZoomScale(1) + wxControl(parent, -1), + mTimer(this, ID_RENDERTIMER), + mRoot(0), + mViewPort(0), + mCamera(0), + mSceneMgr(0), + mRenderWindow(0), + mCameraYawNode(0), + mCameraPitchNode(0), + mLightYawNode(0), + mLightPitchNode(0), + mZoomScale(1) { - // Create all Ogre objects - createOgreRenderWindow(renderSystem); - // Start the rendering timer - toggleTimerRendering(); + // Create all Ogre objects + createOgreRenderWindow(renderSystem); + // Start the rendering timer + toggleTimerRendering(); } void wxOgre::createOgreRenderWindow(Ogre::RenderSystem* renderSystem) { - // See if an Ogre::Root already exists - mRoot = Ogre::Root::getSingletonPtr(); - // If not, create one - if(!mRoot) - { - mRoot = new Ogre::Root(); - } - - // If we got an Ogre::RenderSystem, we'll use that - if(renderSystem) - { - mRoot->setRenderSystem(renderSystem); - } - // If not, maybe the Root already has one - else if(!mRoot->getRenderSystem()) - { - // At this point there are no rendersystems, so we - // can try to load in the previous configuration - if(!mRoot->restoreConfig()) - { - // That failed so we have to show the Dialog - if(!mRoot->showConfigDialog()) - { - // If the user canceled that there's nothing else we can do! - OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "No RenderSystem chosen", "wxOgre::createOgreRenderWindow"); - } - } - } + // See if an Ogre::Root already exists + mRoot = Ogre::Root::getSingletonPtr(); + // If not, create one + if(!mRoot) + { + mRoot = new Ogre::Root(); + } + + // If we got an Ogre::RenderSystem, we'll use that + if(renderSystem) + { + mRoot->setRenderSystem(renderSystem); + } + // If not, maybe the Root already has one + else if(!mRoot->getRenderSystem()) + { + // At this point there are no rendersystems, so we + // can try to load in the previous configuration + if(!mRoot->restoreConfig()) + { + // That failed so we have to show the Dialog + if(!mRoot->showConfigDialog()) + { + // If the user canceled that there's nothing else we can do! + OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, "No RenderSystem chosen", "wxOgre::createOgreRenderWindow"); + } + } + } - mRenderWindow = mRoot->initialise(false); + mRenderWindow = mRoot->initialise(false); - // -------------------- - // Create a new parameters list according to compiled OS - Ogre::NameValuePairList params; - Ogre::String handle; + // -------------------- + // Create a new parameters list according to compiled OS + Ogre::NameValuePairList params; + Ogre::String handle; #ifdef __WXMSW__ - handle = Ogre::StringConverter::toString((size_t)((HWND)GetHandle())); + handle = Ogre::StringConverter::toString((size_t)((HWND)GetHandle())); #elif defined(__WXGTK__) - // TODO: Someone test this. you might to use "parentWindowHandle" if this - // does not work. Ogre 1.2 + Linux + GLX platform wants a string of the - // format display:screen:window, which has variable types ulong:uint:ulong. - GtkWidget* widget = GetHandle(); - gtk_widget_realize( widget ); // Mandatory. Otherwise, a segfault happens. - std::stringstream handleStream; - Display* display = GDK_WINDOW_XDISPLAY( widget->window ); - Window wid = GDK_WINDOW_XWINDOW( widget->window ); // Window is a typedef for XID, which is a typedef for unsigned int - /* Get the right display (DisplayString() returns ":display.screen") */ - std::string displayStr = DisplayString( display ); - displayStr = displayStr.substr( 1, ( displayStr.find( ".", 0 ) - 1 ) ); - /* Put all together */ - handleStream << displayStr << ':' << DefaultScreen( display ) << ':' << wid; - handle = handleStream.str(); + // TODO: Someone test this. you might to use "parentWindowHandle" if this + // does not work. Ogre 1.2 + Linux + GLX platform wants a string of the + // format display:screen:window, which has variable types ulong:uint:ulong. + GtkWidget* widget = GetHandle(); + gtk_widget_realize( widget ); // Mandatory. Otherwise, a segfault happens. + std::stringstream handleStream; + Display* display = GDK_WINDOW_XDISPLAY( widget->window ); + Window wid = GDK_WINDOW_XWINDOW( widget->window ); // Window is a typedef for XID, which is a typedef for unsigned int + /* Get the right display (DisplayString() returns ":display.screen") */ + std::string displayStr = DisplayString( display ); + displayStr = displayStr.substr( 1, ( displayStr.find( ".", 0 ) - 1 ) ); + /* Put all together */ + handleStream << displayStr << ':' << DefaultScreen( display ) << ':' << wid; + handle = handleStream.str(); #else - #error Not supported on this platform. + #error Not supported on this platform. #endif - params["externalWindowHandle"] = handle; + params["externalWindowHandle"] = handle; - // Get wx control window size - int width; - int height; - GetSize(&width, &height); - // Create the render window - mRenderWindow = Ogre::Root::getSingleton().createRenderWindow("OgreRenderWindow", width, height, false, ¶ms); + // Get wx control window size + int width; + int height; + GetSize(&width, &height); + // Create the render window + mRenderWindow = Ogre::Root::getSingleton().createRenderWindow("OgreRenderWindow", width, height, false, ¶ms); - // -------------------- - // Create the SceneManager, in this case a generic one - mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC, "ExampleSMInstance"); - mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f)); + // -------------------- + // Create the SceneManager, in this case a generic one + mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC, "ExampleSMInstance"); + mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f)); - // -------------------- - // Create the camera - mCamera = mSceneMgr->createCamera("EntityCamera"); - // Set up the SceneNodes to control the camera - mCameraYawNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - mCameraPitchNode = mCameraYawNode->createChildSceneNode(); - mCameraPitchNode->attachObject(mCamera); - mCamera->setNearClipDistance(0.1); - // Set the viewport - mViewPort = mRenderWindow->addViewport(mCamera); - // Set the background to match the wxWindow background color - mViewPort->setBackgroundColour(Ogre::ColourValue(212.0f/255.0f, 208.0f/255.0f, 200.0f/255.0f, 1.0f)); + // -------------------- + // Create the camera + mCamera = mSceneMgr->createCamera("EntityCamera"); + // Set up the SceneNodes to control the camera + mCameraYawNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + mCameraPitchNode = mCameraYawNode->createChildSceneNode(); + mCameraPitchNode->attachObject(mCamera); + mCamera->setNearClipDistance(0.1); + // Set the viewport + mViewPort = mRenderWindow->addViewport(mCamera); + // Set the background to match the wxWindow background color + mViewPort->setBackgroundColour(Ogre::ColourValue(212.0f/255.0f, 208.0f/255.0f, 200.0f/255.0f, 1.0f)); - mLightYawNode = mCameraPitchNode->createChildSceneNode(); - mLightPitchNode = mLightYawNode->createChildSceneNode(); - mLight = mSceneMgr->createLight("SceneLight"); - mLight->setType(Ogre::Light::LT_POINT); - mLightPitchNode->attachObject(mLight); + mLightYawNode = mCameraPitchNode->createChildSceneNode(); + mLightPitchNode = mLightYawNode->createChildSceneNode(); + mLight = mSceneMgr->createLight("SceneLight"); + mLight->setType(Ogre::Light::LT_POINT); + mLightPitchNode->attachObject(mLight); } void wxOgre::resetCamera() { - mCameraYawNode->setPosition(Ogre::Vector3::ZERO); - mCameraYawNode->setOrientation(Ogre::Quaternion::IDENTITY); - mCameraPitchNode->setOrientation(Ogre::Quaternion::IDENTITY); - mCamera->setPosition(Ogre::Vector3::ZERO); + mCameraYawNode->setPosition(Ogre::Vector3::ZERO); + mCameraYawNode->setOrientation(Ogre::Quaternion::IDENTITY); + mCameraPitchNode->setOrientation(Ogre::Quaternion::IDENTITY); + mCamera->setPosition(Ogre::Vector3::ZERO); } void wxOgre::toggleTimerRendering() { - // Toggle Start/Stop - if (mTimer.IsRunning()) - mTimer.Stop(); - mTimer.Start(10); + // Toggle Start/Stop + if (mTimer.IsRunning()) + mTimer.Stop(); + mTimer.Start(10); } wxOgre::~wxOgre() { - // destroy Viewport and RenderWindow - if (mViewPort) - { - mRenderWindow->removeViewport(mViewPort->getZOrder()); - mViewPort = 0; - } + // destroy Viewport and RenderWindow + if (mViewPort) + { + mRenderWindow->removeViewport(mViewPort->getZOrder()); + mViewPort = 0; + } - Ogre::Root::getSingleton().detachRenderTarget(mRenderWindow); - mRenderWindow = 0; + Ogre::Root::getSingleton().detachRenderTarget(mRenderWindow); + mRenderWindow = 0; delete mRoot; } void wxOgre::OnSize(wxSizeEvent& event) { - // Setting new size; - int width; - int height; - GetSize(&width, &height); - mRenderWindow->resize( width, height ); - // Letting Ogre know the window has been resized; - mRenderWindow->windowMovedOrResized(); - // Set the aspect ratio for the new size; - if (mCamera) - mCamera->setAspectRatio(Ogre::Real(width) / Ogre::Real(height)); + // Setting new size; + int width; + int height; + GetSize(&width, &height); + mRenderWindow->resize( width, height ); + // Letting Ogre know the window has been resized; + mRenderWindow->windowMovedOrResized(); + // Set the aspect ratio for the new size; + if (mCamera) + mCamera->setAspectRatio(Ogre::Real(width) / Ogre::Real(height)); - update(); + update(); } void wxOgre::OnPaint(wxPaintEvent& event) { -// update(); // Produces flickers and runs too fast! +// update(); // Produces flickers and runs too fast! } void wxOgre::OnEraseBackground(wxEraseEvent& event) { - update(); + update(); } void wxOgre::OnRenderTimer(wxTimerEvent& event) { - update(); + update(); } void wxOgre::OnMouseDown(wxMouseEvent& event) { - mPrevPos = event.GetPosition(); - event.Skip(); + mPrevPos = event.GetPosition(); + event.Skip(); } void wxOgre::OnMouseMotion(wxMouseEvent& event) { - if(event.Dragging()) - { - wxPoint pos = event.GetPosition(); - wxPoint change = pos - mPrevPos; + if(event.Dragging()) + { + wxPoint pos = event.GetPosition(); + wxPoint change = pos - mPrevPos; - if(event.LeftIsDown()) - { - mCameraYawNode->yaw(Ogre::Degree(-change.x / (event.ShiftDown() ? 20.0 : 2.0))); - mCameraPitchNode->pitch(Ogre::Degree(-change.y / (event.ShiftDown() ? 20.0 : 2.0))); - } - else if(event.MiddleIsDown()) - { - int left, top, width, height; - mCamera->getViewport()->getActualDimensions(left, top, width, height); + if(event.LeftIsDown()) + { + mCameraYawNode->yaw(Ogre::Degree(-change.x / (event.ShiftDown() ? 20.0 : 2.0))); + mCameraPitchNode->pitch(Ogre::Degree(-change.y / (event.ShiftDown() ? 20.0 : 2.0))); + } + else if(event.MiddleIsDown()) + { + int left, top, width, height; + mCamera->getViewport()->getActualDimensions(left, top, width, height); - float moveX = ((float)-change.x / (float)width) * mZoomScale * (event.ShiftDown() ? 0.1 : 1.0); - float moveY = ((float)change.y / (float)height) * mZoomScale * (event.ShiftDown() ? 0.1 : 1.0); + float moveX = ((float)-change.x / (float)width) * mZoomScale * (event.ShiftDown() ? 0.1 : 1.0); + float moveY = ((float)change.y / (float)height) * mZoomScale * (event.ShiftDown() ? 0.1 : 1.0); - mCamera->moveRelative(Ogre::Vector3(moveX, moveY, 0)); - } - else if(event.RightIsDown()) - { - mLightYawNode->yaw(Ogre::Degree(change.x / (event.ShiftDown() ? 20.0 : 2.0))); - mLightPitchNode->pitch(Ogre::Degree(change.y /(event.ShiftDown() ? 20.0 : 2.0))); - } + mCamera->moveRelative(Ogre::Vector3(moveX, moveY, 0)); + } + else if(event.RightIsDown()) + { + mLightYawNode->yaw(Ogre::Degree(change.x / (event.ShiftDown() ? 20.0 : 2.0))); + mLightPitchNode->pitch(Ogre::Degree(change.y /(event.ShiftDown() ? 20.0 : 2.0))); + } - mPrevPos = pos; - } + mPrevPos = pos; + } } void wxOgre::OnMouseWheel(wxMouseEvent& event) { - float moveZ = ((float)event.GetWheelRotation() / 120.0) / 100.0; - moveZ = moveZ * mZoomScale * (event.ShiftDown() ? 1.0 : 10.0); + float moveZ = ((float)event.GetWheelRotation() / 120.0) / 100.0; + moveZ = moveZ * mZoomScale * (event.ShiftDown() ? 1.0 : 10.0); - mCamera->moveRelative(Ogre::Vector3(0, 0, moveZ)); + mCamera->moveRelative(Ogre::Vector3(0, 0, moveZ)); } void wxOgre::update() { - Ogre::Root::getSingletonPtr()->renderOneFrame(); + Ogre::Root::getSingletonPtr()->renderOneFrame(); } template<> wxOgre* Ogre::Singleton::msSingleton = 0; wxOgre& wxOgre::getSingleton() { - return ( *msSingleton ); + return ( *msSingleton ); } wxOgre* wxOgre::getSingletonPtr() { - return msSingleton; + return msSingleton; } \ No newline at end of file diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Accessor.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Accessor.h index 0b2c4baee25..efa963755fd 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Accessor.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Accessor.h @@ -16,63 +16,63 @@ typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len); */ class Accessor { protected: - enum {extremePosition=0x7FFFFFFF}; - /** @a bufferSize is a trade off between time taken to copy the characters - * and retrieval overhead. - * @a slopSize positions the buffer before the desired position - * in case there is some backtracking. */ - enum {bufferSize=4000, slopSize=bufferSize/8}; - char buf[bufferSize+1]; - int startPos; - int endPos; - int codePage; + enum {extremePosition=0x7FFFFFFF}; + /** @a bufferSize is a trade off between time taken to copy the characters + * and retrieval overhead. + * @a slopSize positions the buffer before the desired position + * in case there is some backtracking. */ + enum {bufferSize=4000, slopSize=bufferSize/8}; + char buf[bufferSize+1]; + int startPos; + int endPos; + int codePage; - virtual bool InternalIsLeadByte(char ch)=0; - virtual void Fill(int position)=0; + virtual bool InternalIsLeadByte(char ch)=0; + virtual void Fill(int position)=0; public: - Accessor() : startPos(extremePosition), endPos(0), codePage(0) {} - virtual ~Accessor() {} - char operator[](int position) { - if (position < startPos || position >= endPos) { - Fill(position); - } - return buf[position - startPos]; - } - /** Safe version of operator[], returning a defined value for invalid position. */ - char SafeGetCharAt(int position, char chDefault=' ') { - if (position < startPos || position >= endPos) { - Fill(position); - if (position < startPos || position >= endPos) { - // Position is outside range of document - return chDefault; - } - } - return buf[position - startPos]; - } - bool IsLeadByte(char ch) { - return codePage && InternalIsLeadByte(ch); - } - void SetCodePage(int codePage_) { codePage = codePage_; } + Accessor() : startPos(extremePosition), endPos(0), codePage(0) {} + virtual ~Accessor() {} + char operator[](int position) { + if (position < startPos || position >= endPos) { + Fill(position); + } + return buf[position - startPos]; + } + /** Safe version of operator[], returning a defined value for invalid position. */ + char SafeGetCharAt(int position, char chDefault=' ') { + if (position < startPos || position >= endPos) { + Fill(position); + if (position < startPos || position >= endPos) { + // Position is outside range of document + return chDefault; + } + } + return buf[position - startPos]; + } + bool IsLeadByte(char ch) { + return codePage && InternalIsLeadByte(ch); + } + void SetCodePage(int codePage_) { codePage = codePage_; } - virtual bool Match(int pos, const char *s)=0; - virtual char StyleAt(int position)=0; - virtual int GetLine(int position)=0; - virtual int LineStart(int line)=0; - virtual int LevelAt(int line)=0; - virtual int Length()=0; - virtual void Flush()=0; - virtual int GetLineState(int line)=0; - virtual int SetLineState(int line, int state)=0; - virtual int GetPropertyInt(const char *key, int defaultValue=0)=0; - virtual char *GetProperties()=0; + virtual bool Match(int pos, const char *s)=0; + virtual char StyleAt(int position)=0; + virtual int GetLine(int position)=0; + virtual int LineStart(int line)=0; + virtual int LevelAt(int line)=0; + virtual int Length()=0; + virtual void Flush()=0; + virtual int GetLineState(int line)=0; + virtual int SetLineState(int line, int state)=0; + virtual int GetPropertyInt(const char *key, int defaultValue=0)=0; + virtual char *GetProperties()=0; - // Style setting - virtual void StartAt(unsigned int start, char chMask=31)=0; - virtual void SetFlags(char chFlags_, char chWhile_)=0; - virtual unsigned int GetStartSegment()=0; - virtual void StartSegment(unsigned int pos)=0; - virtual void ColourTo(unsigned int pos, int chAttr)=0; - virtual void SetLevel(int line, int level)=0; - virtual int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0)=0; + // Style setting + virtual void StartAt(unsigned int start, char chMask=31)=0; + virtual void SetFlags(char chFlags_, char chWhile_)=0; + virtual unsigned int GetStartSegment()=0; + virtual void StartSegment(unsigned int pos)=0; + virtual void ColourTo(unsigned int pos, int chAttr)=0; + virtual void SetLevel(int line, int level)=0; + virtual int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0)=0; }; diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/KeyWords.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/KeyWords.h index 059ac0da0fd..dcf12fd00b4 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/KeyWords.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/KeyWords.h @@ -15,40 +15,40 @@ typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyl */ class LexerModule { protected: - const LexerModule *next; - int language; - LexerFunction fnLexer; - LexerFunction fnFolder; - const char * const * wordListDescriptions; - int styleBits; + const LexerModule *next; + int language; + LexerFunction fnLexer; + LexerFunction fnFolder; + const char * const * wordListDescriptions; + int styleBits; - static const LexerModule *base; - static int nextLanguage; + static const LexerModule *base; + static int nextLanguage; public: - const char *languageName; - LexerModule(int language_, - LexerFunction fnLexer_, - const char *languageName_=0, - LexerFunction fnFolder_=0, - const char * const wordListDescriptions_[] = NULL, - int styleBits_=5); - virtual ~LexerModule() { - } - int GetLanguage() const { return language; } + const char *languageName; + LexerModule(int language_, + LexerFunction fnLexer_, + const char *languageName_=0, + LexerFunction fnFolder_=0, + const char * const wordListDescriptions_[] = NULL, + int styleBits_=5); + virtual ~LexerModule() { + } + int GetLanguage() const { return language; } - // -1 is returned if no WordList information is available - int GetNumWordLists() const; - const char *GetWordListDescription(int index) const; + // -1 is returned if no WordList information is available + int GetNumWordLists() const; + const char *GetWordListDescription(int index) const; - int GetStyleBitsNeeded() const; + int GetStyleBitsNeeded() const; - virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle, + virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler) const; - virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle, + virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle, WordList *keywordlists[], Accessor &styler) const; - static const LexerModule *Find(int language); - static const LexerModule *Find(const char *languageName); + static const LexerModule *Find(int language); + static const LexerModule *Find(const char *languageName); }; /** @@ -60,23 +60,23 @@ inline bool isspacechar(unsigned char ch) { } inline bool iswordchar(char ch) { - return isascii(ch) && (isalnum(ch) || ch == '.' || ch == '_'); + return isascii(ch) && (isalnum(ch) || ch == '.' || ch == '_'); } inline bool iswordstart(char ch) { - return isascii(ch) && (isalnum(ch) || ch == '_'); + return isascii(ch) && (isalnum(ch) || ch == '_'); } inline bool isoperator(char ch) { - if (isascii(ch) && isalnum(ch)) - return false; - // '.' left out as it is used to make up numbers - if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || - ch == '(' || ch == ')' || ch == '-' || ch == '+' || - ch == '=' || ch == '|' || ch == '{' || ch == '}' || - ch == '[' || ch == ']' || ch == ':' || ch == ';' || - ch == '<' || ch == '>' || ch == ',' || ch == '/' || - ch == '?' || ch == '!' || ch == '.' || ch == '~') - return true; - return false; + if (isascii(ch) && isalnum(ch)) + return false; + // '.' left out as it is used to make up numbers + if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || + ch == '(' || ch == ')' || ch == '-' || ch == '+' || + ch == '=' || ch == '|' || ch == '{' || ch == '}' || + ch == '[' || ch == ']' || ch == ':' || ch == ';' || + ch == '<' || ch == '>' || ch == ',' || ch == '/' || + ch == '?' || ch == '!' || ch == '.' || ch == '~') + return true; + return false; } diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Platform.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Platform.h index c848168e7e9..d20692bf043 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Platform.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Platform.h @@ -65,15 +65,15 @@ typedef void *IdlerID; */ class Point { public: - int x; - int y; + int x; + int y; - explicit Point(int x_=0, int y_=0) : x(x_), y(y_) { - } + explicit Point(int x_=0, int y_=0) : x(x_), y(y_) { + } - // Other automatically defined methods (assignment, copy constructor, destructor) are fine + // Other automatically defined methods (assignment, copy constructor, destructor) are fine - static Point FromLong(long lpoint); + static Point FromLong(long lpoint); }; /** @@ -83,41 +83,41 @@ class Point { */ class PRectangle { public: - int left; - int top; - int right; - int bottom; - - PRectangle(int left_=0, int top_=0, int right_=0, int bottom_ = 0) : - left(left_), top(top_), right(right_), bottom(bottom_) { - } - - // Other automatically defined methods (assignment, copy constructor, destructor) are fine - - bool operator==(PRectangle &rc) { - return (rc.left == left) && (rc.right == right) && - (rc.top == top) && (rc.bottom == bottom); - } - bool Contains(Point pt) { - return (pt.x >= left) && (pt.x <= right) && - (pt.y >= top) && (pt.y <= bottom); - } - bool Contains(PRectangle rc) { - return (rc.left >= left) && (rc.right <= right) && - (rc.top >= top) && (rc.bottom <= bottom); - } - bool Intersects(PRectangle other) { - return (right > other.left) && (left < other.right) && - (bottom > other.top) && (top < other.bottom); - } - void Move(int xDelta, int yDelta) { - left += xDelta; - top += yDelta; - right += xDelta; - bottom += yDelta; - } - int Width() { return right - left; } - int Height() { return bottom - top; } + int left; + int top; + int right; + int bottom; + + PRectangle(int left_=0, int top_=0, int right_=0, int bottom_ = 0) : + left(left_), top(top_), right(right_), bottom(bottom_) { + } + + // Other automatically defined methods (assignment, copy constructor, destructor) are fine + + bool operator==(PRectangle &rc) { + return (rc.left == left) && (rc.right == right) && + (rc.top == top) && (rc.bottom == bottom); + } + bool Contains(Point pt) { + return (pt.x >= left) && (pt.x <= right) && + (pt.y >= top) && (pt.y <= bottom); + } + bool Contains(PRectangle rc) { + return (rc.left >= left) && (rc.right <= right) && + (rc.top >= top) && (rc.bottom <= bottom); + } + bool Intersects(PRectangle other) { + return (right > other.left) && (left < other.right) && + (bottom > other.top) && (top < other.bottom); + } + void Move(int xDelta, int yDelta) { + left += xDelta; + top += yDelta; + right += xDelta; + bottom += yDelta; + } + int Width() { return right - left; } + int Height() { return bottom - top; } }; /** @@ -136,138 +136,138 @@ class PRectangle { * Holds a desired RGB colour. */ class ColourDesired { - long co; + long co; public: - ColourDesired(long lcol=0) { - co = lcol; - } - - ColourDesired(unsigned int red, unsigned int green, unsigned int blue) { - Set(red, green, blue); - } - - bool operator==(const ColourDesired &other) const { - return co == other.co; - } - - void Set(long lcol) { - co = lcol; - } - - void Set(unsigned int red, unsigned int green, unsigned int blue) { - co = red | (green << 8) | (blue << 16); - } - - static inline unsigned int ValueOfHex(const char ch) { - if (ch >= '0' && ch <= '9') - return ch - '0'; - else if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - else if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - else - return 0; - } - - void Set(const char *val) { - if (*val == '#') { - val++; - } - unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]); - unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]); - unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]); - Set(r, g, b); - } - - long AsLong() const { - return co; - } - - unsigned int GetRed() { - return co & 0xff; - } - - unsigned int GetGreen() { - return (co >> 8) & 0xff; - } - - unsigned int GetBlue() { - return (co >> 16) & 0xff; - } + ColourDesired(long lcol=0) { + co = lcol; + } + + ColourDesired(unsigned int red, unsigned int green, unsigned int blue) { + Set(red, green, blue); + } + + bool operator==(const ColourDesired &other) const { + return co == other.co; + } + + void Set(long lcol) { + co = lcol; + } + + void Set(unsigned int red, unsigned int green, unsigned int blue) { + co = red | (green << 8) | (blue << 16); + } + + static inline unsigned int ValueOfHex(const char ch) { + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + else + return 0; + } + + void Set(const char *val) { + if (*val == '#') { + val++; + } + unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]); + unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]); + unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]); + Set(r, g, b); + } + + long AsLong() const { + return co; + } + + unsigned int GetRed() { + return co & 0xff; + } + + unsigned int GetGreen() { + return (co >> 8) & 0xff; + } + + unsigned int GetBlue() { + return (co >> 16) & 0xff; + } }; /** * Holds an allocated RGB colour which may be an approximation to the desired colour. */ class ColourAllocated { - long coAllocated; + long coAllocated; public: - ColourAllocated(long lcol=0) { - coAllocated = lcol; - } + ColourAllocated(long lcol=0) { + coAllocated = lcol; + } - void Set(long lcol) { - coAllocated = lcol; - } + void Set(long lcol) { + coAllocated = lcol; + } - long AsLong() const { - return coAllocated; - } + long AsLong() const { + return coAllocated; + } }; /** * Colour pairs hold a desired colour and an allocated colour. */ struct ColourPair { - ColourDesired desired; - ColourAllocated allocated; - - ColourPair(ColourDesired desired_=ColourDesired(0,0,0)) { - desired = desired_; - allocated.Set(desired.AsLong()); - } - void Copy() { - allocated.Set(desired.AsLong()); - } + ColourDesired desired; + ColourAllocated allocated; + + ColourPair(ColourDesired desired_=ColourDesired(0,0,0)) { + desired = desired_; + allocated.Set(desired.AsLong()); + } + void Copy() { + allocated.Set(desired.AsLong()); + } }; -class Window; // Forward declaration for Palette +class Window; // Forward declaration for Palette /** * Colour palette management. */ class Palette { - int used; - int size; - ColourPair *entries; + int used; + int size; + ColourPair *entries; #if PLAT_GTK - void *allocatedPalette; // GdkColor * - int allocatedLen; + void *allocatedPalette; // GdkColor * + int allocatedLen; #endif - // Private so Palette objects can not be copied - Palette(const Palette &) {} - Palette &operator=(const Palette &) { return *this; } + // Private so Palette objects can not be copied + Palette(const Palette &) {} + Palette &operator=(const Palette &) { return *this; } public: #if PLAT_WIN - void *hpal; + void *hpal; #endif - bool allowRealization; + bool allowRealization; - Palette(); - ~Palette(); + Palette(); + ~Palette(); - void Release(); + void Release(); - /** - * This method either adds a colour to the list of wanted colours (want==true) - * or retrieves the allocated colour back to the ColourPair. - * This is one method to make it easier to keep the code for wanting and retrieving in sync. - */ - void WantFind(ColourPair &cp, bool want); + /** + * This method either adds a colour to the list of wanted colours (want==true) + * or retrieves the allocated colour back to the ColourPair. + * This is one method to make it easier to keep the code for wanting and retrieving in sync. + */ + void WantFind(ColourPair &cp, bool want); - void Allocate(Window &w); + void Allocate(Window &w); }; /** @@ -275,25 +275,25 @@ class Palette { */ class Font { protected: - FontID id; + FontID id; #if PLAT_WX - int ascent; + int ascent; #endif - // Private so Font objects can not be copied - Font(const Font &) {} - Font &operator=(const Font &) { id=0; return *this; } + // Private so Font objects can not be copied + Font(const Font &) {} + Font &operator=(const Font &) { id=0; return *this; } public: - Font(); - virtual ~Font(); + Font(); + virtual ~Font(); - virtual void Create(const char *faceName, int characterSet, int size, - bool bold, bool italic, bool extraFontFlag=false); - virtual void Release(); + virtual void Create(const char *faceName, int characterSet, int size, + bool bold, bool italic, bool extraFontFlag=false); + virtual void Release(); - FontID GetID() { return id; } - // Alias another font - caller guarantees not to Release - void SetID(FontID id_) { id = id_; } - friend class Surface; + FontID GetID() { return id; } + // Alias another font - caller guarantees not to Release + void SetID(FontID id_) { id = id_; } + friend class Surface; friend class SurfaceImpl; }; @@ -302,54 +302,54 @@ class Font { */ class Surface { private: - // Private so Surface objects can not be copied - Surface(const Surface &) {} - Surface &operator=(const Surface &) { return *this; } + // Private so Surface objects can not be copied + Surface(const Surface &) {} + Surface &operator=(const Surface &) { return *this; } public: - Surface() {}; - virtual ~Surface() {}; - static Surface *Allocate(); - - virtual void Init(WindowID wid)=0; - virtual void Init(SurfaceID sid, WindowID wid)=0; - virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0; - - virtual void Release()=0; - virtual bool Initialised()=0; - virtual void PenColour(ColourAllocated fore)=0; - virtual int LogPixelsY()=0; - virtual int DeviceHeightFont(int points)=0; - virtual void MoveTo(int x_, int y_)=0; - virtual void LineTo(int x_, int y_)=0; - virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back)=0; - virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; - virtual void FillRectangle(PRectangle rc, ColourAllocated back)=0; - virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; - virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; - virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, - ColourAllocated outline, int alphaOutline, int flags)=0; - virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; - virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; - - virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; - virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; - virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore)=0; - virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions)=0; - virtual int WidthText(Font &font_, const char *s, int len)=0; - virtual int WidthChar(Font &font_, char ch)=0; - virtual int Ascent(Font &font_)=0; - virtual int Descent(Font &font_)=0; - virtual int InternalLeading(Font &font_)=0; - virtual int ExternalLeading(Font &font_)=0; - virtual int Height(Font &font_)=0; - virtual int AverageCharWidth(Font &font_)=0; - - virtual int SetPalette(Palette *pal, bool inBackGround)=0; - virtual void SetClip(PRectangle rc)=0; - virtual void FlushCachedState()=0; - - virtual void SetUnicodeMode(bool unicodeMode_)=0; - virtual void SetDBCSMode(int codePage)=0; + Surface() {}; + virtual ~Surface() {}; + static Surface *Allocate(); + + virtual void Init(WindowID wid)=0; + virtual void Init(SurfaceID sid, WindowID wid)=0; + virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0; + + virtual void Release()=0; + virtual bool Initialised()=0; + virtual void PenColour(ColourAllocated fore)=0; + virtual int LogPixelsY()=0; + virtual int DeviceHeightFont(int points)=0; + virtual void MoveTo(int x_, int y_)=0; + virtual void LineTo(int x_, int y_)=0; + virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back)=0; + virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; + virtual void FillRectangle(PRectangle rc, ColourAllocated back)=0; + virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; + virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; + virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, + ColourAllocated outline, int alphaOutline, int flags)=0; + virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; + virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; + + virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; + virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; + virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore)=0; + virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions)=0; + virtual int WidthText(Font &font_, const char *s, int len)=0; + virtual int WidthChar(Font &font_, char ch)=0; + virtual int Ascent(Font &font_)=0; + virtual int Descent(Font &font_)=0; + virtual int InternalLeading(Font &font_)=0; + virtual int ExternalLeading(Font &font_)=0; + virtual int Height(Font &font_)=0; + virtual int AverageCharWidth(Font &font_)=0; + + virtual int SetPalette(Palette *pal, bool inBackGround)=0; + virtual void SetClip(PRectangle rc)=0; + virtual void FlushCachedState()=0; + + virtual void SetUnicodeMode(bool unicodeMode_)=0; + virtual void SetDBCSMode(int codePage)=0; }; /** @@ -363,32 +363,32 @@ typedef void (*CallBackAction)(void*); */ class Window { protected: - WindowID id; + WindowID id; public: - Window() : id(0), cursorLast(cursorInvalid) {} - Window(const Window &source) : id(source.id), cursorLast(cursorInvalid) {} - virtual ~Window(); - Window &operator=(WindowID id_) { - id = id_; - return *this; - } - WindowID GetID() const { return id; } - bool Created() const { return id != 0; } - void Destroy(); - bool HasFocus(); - PRectangle GetPosition(); - void SetPosition(PRectangle rc); - void SetPositionRelative(PRectangle rc, Window relativeTo); - PRectangle GetClientPosition(); - void Show(bool show=true); - void InvalidateAll(); - void InvalidateRectangle(PRectangle rc); - virtual void SetFont(Font &font); - enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand }; - void SetCursor(Cursor curs); - void SetTitle(const char *s); + Window() : id(0), cursorLast(cursorInvalid) {} + Window(const Window &source) : id(source.id), cursorLast(cursorInvalid) {} + virtual ~Window(); + Window &operator=(WindowID id_) { + id = id_; + return *this; + } + WindowID GetID() const { return id; } + bool Created() const { return id != 0; } + void Destroy(); + bool HasFocus(); + PRectangle GetPosition(); + void SetPosition(PRectangle rc); + void SetPositionRelative(PRectangle rc, Window relativeTo); + PRectangle GetClientPosition(); + void Show(bool show=true); + void InvalidateAll(); + void InvalidateRectangle(PRectangle rc); + virtual void SetFont(Font &font); + enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand }; + void SetCursor(Cursor curs); + void SetTitle(const char *s); private: - Cursor cursorLast; + Cursor cursorLast; }; /** @@ -397,49 +397,49 @@ class Window { class ListBox : public Window { public: - ListBox(); - virtual ~ListBox(); - static ListBox *Allocate(); - - virtual void SetFont(Font &font)=0; - virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_)=0; - virtual void SetAverageCharWidth(int width)=0; - virtual void SetVisibleRows(int rows)=0; - virtual int GetVisibleRows() const=0; - virtual PRectangle GetDesiredRect()=0; - virtual int CaretFromEdge()=0; - virtual void Clear()=0; - virtual void Append(char *s, int type = -1)=0; - virtual int Length()=0; - virtual void Select(int n)=0; - virtual int GetSelection()=0; - virtual int Find(const char *prefix)=0; - virtual void GetValue(int n, char *value, int len)=0; - virtual void RegisterImage(int type, const char *xpm_data)=0; - virtual void ClearRegisteredImages()=0; - virtual void SetDoubleClickAction(CallBackAction, void *)=0; - virtual void SetList(const char* list, char separator, char typesep)=0; + ListBox(); + virtual ~ListBox(); + static ListBox *Allocate(); + + virtual void SetFont(Font &font)=0; + virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_)=0; + virtual void SetAverageCharWidth(int width)=0; + virtual void SetVisibleRows(int rows)=0; + virtual int GetVisibleRows() const=0; + virtual PRectangle GetDesiredRect()=0; + virtual int CaretFromEdge()=0; + virtual void Clear()=0; + virtual void Append(char *s, int type = -1)=0; + virtual int Length()=0; + virtual void Select(int n)=0; + virtual int GetSelection()=0; + virtual int Find(const char *prefix)=0; + virtual void GetValue(int n, char *value, int len)=0; + virtual void RegisterImage(int type, const char *xpm_data)=0; + virtual void ClearRegisteredImages()=0; + virtual void SetDoubleClickAction(CallBackAction, void *)=0; + virtual void SetList(const char* list, char separator, char typesep)=0; }; /** * Menu management. */ class Menu { - MenuID id; + MenuID id; public: - Menu(); - MenuID GetID() { return id; } - void CreatePopUp(); - void Destroy(); - void Show(Point pt, Window &w); + Menu(); + MenuID GetID() { return id; } + void CreatePopUp(); + void Destroy(); + void Show(Point pt, Window &w); }; class ElapsedTime { - long bigBit; - long littleBit; + long bigBit; + long littleBit; public: - ElapsedTime(); - double Duration(bool reset=false); + ElapsedTime(); + double Duration(bool reset=false); }; /** @@ -447,16 +447,16 @@ class ElapsedTime { */ class DynamicLibrary { public: - virtual ~DynamicLibrary() {}; + virtual ~DynamicLibrary() {}; - /// @return Pointer to function "name", or NULL on failure. - virtual Function FindFunction(const char *name) = 0; + /// @return Pointer to function "name", or NULL on failure. + virtual Function FindFunction(const char *name) = 0; - /// @return true if the library was loaded successfully. - virtual bool IsValid() = 0; + /// @return true if the library was loaded successfully. + virtual bool IsValid() = 0; - /// @return An instance of a DynamicLibrary subclass with "modulePath" loaded. - static DynamicLibrary *Load(const char *modulePath); + /// @return An instance of a DynamicLibrary subclass with "modulePath" loaded. + static DynamicLibrary *Load(const char *modulePath); }; /** @@ -464,47 +464,47 @@ class DynamicLibrary { * and chrome colour. Not a creatable object, more of a module with several functions. */ class Platform { - // Private so Platform objects can not be copied - Platform(const Platform &) {} - Platform &operator=(const Platform &) { return *this; } + // Private so Platform objects can not be copied + Platform(const Platform &) {} + Platform &operator=(const Platform &) { return *this; } public: - // Should be private because no new Platforms are ever created - // but gcc warns about this - Platform() {} - ~Platform() {} - static ColourDesired Chrome(); - static ColourDesired ChromeHighlight(); - static const char *DefaultFont(); - static int DefaultFontSize(); - static unsigned int DoubleClickTime(); - static bool MouseButtonBounce(); - static void DebugDisplay(const char *s); - static bool IsKeyDown(int key); - static long SendScintilla( - WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0); - static long SendScintillaPointer( - WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0); - static bool IsDBCSLeadByte(int codePage, char ch); - static int DBCSCharLength(int codePage, const char *s); - static int DBCSCharMaxLength(); - - // These are utility functions not really tied to a platform - static int Minimum(int a, int b); - static int Maximum(int a, int b); - // Next three assume 16 bit shorts and 32 bit longs - static long LongFromTwoShorts(short a,short b) { - return (a) | ((b) << 16); - } - static short HighShortFromLong(long x) { - return static_cast(x >> 16); - } - static short LowShortFromLong(long x) { - return static_cast(x & 0xffff); - } - static void DebugPrintf(const char *format, ...); - static bool ShowAssertionPopUps(bool assertionPopUps_); - static void Assert(const char *c, const char *file, int line); - static int Clamp(int val, int minVal, int maxVal); + // Should be private because no new Platforms are ever created + // but gcc warns about this + Platform() {} + ~Platform() {} + static ColourDesired Chrome(); + static ColourDesired ChromeHighlight(); + static const char *DefaultFont(); + static int DefaultFontSize(); + static unsigned int DoubleClickTime(); + static bool MouseButtonBounce(); + static void DebugDisplay(const char *s); + static bool IsKeyDown(int key); + static long SendScintilla( + WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0); + static long SendScintillaPointer( + WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0); + static bool IsDBCSLeadByte(int codePage, char ch); + static int DBCSCharLength(int codePage, const char *s); + static int DBCSCharMaxLength(); + + // These are utility functions not really tied to a platform + static int Minimum(int a, int b); + static int Maximum(int a, int b); + // Next three assume 16 bit shorts and 32 bit longs + static long LongFromTwoShorts(short a,short b) { + return (a) | ((b) << 16); + } + static short HighShortFromLong(long x) { + return static_cast(x >> 16); + } + static short LowShortFromLong(long x) { + return static_cast(x & 0xffff); + } + static void DebugPrintf(const char *format, ...); + static bool ShowAssertionPopUps(bool assertionPopUps_); + static void Assert(const char *c, const char *file, int line); + static int Clamp(int val, int minVal, int maxVal); }; #ifdef NDEBUG diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/PropSet.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/PropSet.h index e38de7dc408..61f3da96c96 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/PropSet.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/PropSet.h @@ -14,94 +14,94 @@ bool EqualCaseInsensitive(const char *a, const char *b); bool isprefix(const char *target, const char *prefix); struct Property { - unsigned int hash; - char *key; - char *val; - Property *next; - Property() : hash(0), key(0), val(0), next(0) {} + unsigned int hash; + char *key; + char *val; + Property *next; + Property() : hash(0), key(0), val(0), next(0) {} }; /** */ class PropSet { protected: - enum { hashRoots=31 }; - Property *props[hashRoots]; - Property *enumnext; - int enumhash; - static bool caseSensitiveFilenames; - static unsigned int HashString(const char *s, size_t len) { - unsigned int ret = 0; - while (len--) { - ret <<= 4; - ret ^= *s; - s++; - } - return ret; - } - static bool IncludesVar(const char *value, const char *key); + enum { hashRoots=31 }; + Property *props[hashRoots]; + Property *enumnext; + int enumhash; + static bool caseSensitiveFilenames; + static unsigned int HashString(const char *s, size_t len) { + unsigned int ret = 0; + while (len--) { + ret <<= 4; + ret ^= *s; + s++; + } + return ret; + } + static bool IncludesVar(const char *value, const char *key); public: - PropSet *superPS; - PropSet(); - ~PropSet(); - void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1); - void Set(const char *keyVal); - void Unset(const char *key, int lenKey=-1); - void SetMultiple(const char *s); - SString Get(const char *key); - SString GetExpanded(const char *key); - SString Expand(const char *withVars, int maxExpands=100); - int GetInt(const char *key, int defaultValue=0); - SString GetWild(const char *keybase, const char *filename); - SString GetNewExpand(const char *keybase, const char *filename=""); - void Clear(); - char *ToString(); // Caller must delete[] the return value - bool GetFirst(char **key, char **val); - bool GetNext(char **key, char **val); - static void SetCaseSensitiveFilenames(bool caseSensitiveFilenames_) { - caseSensitiveFilenames = caseSensitiveFilenames_; - } + PropSet *superPS; + PropSet(); + ~PropSet(); + void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1); + void Set(const char *keyVal); + void Unset(const char *key, int lenKey=-1); + void SetMultiple(const char *s); + SString Get(const char *key); + SString GetExpanded(const char *key); + SString Expand(const char *withVars, int maxExpands=100); + int GetInt(const char *key, int defaultValue=0); + SString GetWild(const char *keybase, const char *filename); + SString GetNewExpand(const char *keybase, const char *filename=""); + void Clear(); + char *ToString(); // Caller must delete[] the return value + bool GetFirst(char **key, char **val); + bool GetNext(char **key, char **val); + static void SetCaseSensitiveFilenames(bool caseSensitiveFilenames_) { + caseSensitiveFilenames = caseSensitiveFilenames_; + } private: - // copy-value semantics not implemented - PropSet(const PropSet ©); - void operator=(const PropSet &assign); + // copy-value semantics not implemented + PropSet(const PropSet ©); + void operator=(const PropSet &assign); }; /** */ class WordList { public: - // Each word contains at least one character - a empty word acts as sentinel at the end. - char **words; - char **wordsNoCase; - char *list; - int len; - bool onlyLineEnds; ///< Delimited by any white space or only line ends - bool sorted; - bool sortedNoCase; - int starts[256]; - WordList(bool onlyLineEnds_ = false) : - words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_), - sorted(false), sortedNoCase(false) {} - ~WordList() { Clear(); } - operator bool() { return len ? true : false; } - char *operator[](int ind) { return words[ind]; } - void Clear(); - void Set(const char *s); - char *Allocate(int size); - void SetFromAllocated(); - bool InList(const char *s); - bool InListAbbreviated(const char *s, const char marker); - const char *GetNearestWord(const char *wordStart, int searchLen, - bool ignoreCase = false, SString wordCharacters="", int wordIndex = -1); - char *GetNearestWords(const char *wordStart, int searchLen, - bool ignoreCase=false, char otherSeparator='\0', bool exactLen=false); + // Each word contains at least one character - a empty word acts as sentinel at the end. + char **words; + char **wordsNoCase; + char *list; + int len; + bool onlyLineEnds; ///< Delimited by any white space or only line ends + bool sorted; + bool sortedNoCase; + int starts[256]; + WordList(bool onlyLineEnds_ = false) : + words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_), + sorted(false), sortedNoCase(false) {} + ~WordList() { Clear(); } + operator bool() { return len ? true : false; } + char *operator[](int ind) { return words[ind]; } + void Clear(); + void Set(const char *s); + char *Allocate(int size); + void SetFromAllocated(); + bool InList(const char *s); + bool InListAbbreviated(const char *s, const char marker); + const char *GetNearestWord(const char *wordStart, int searchLen, + bool ignoreCase = false, SString wordCharacters="", int wordIndex = -1); + char *GetNearestWords(const char *wordStart, int searchLen, + bool ignoreCase=false, char otherSeparator='\0', bool exactLen=false); }; inline bool IsAlphabetic(unsigned int ch) { - return ((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')); + return ((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')); } diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/SString.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/SString.h index 38a206ccf22..2b9e3802db2 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/SString.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/SString.h @@ -23,44 +23,44 @@ bool EqualCaseInsensitive(const char *a, const char *b); */ class SContainer { public: - /** Type of string lengths (sizes) and positions (indexes). */ - typedef size_t lenpos_t; - /** Out of bounds value indicating that the string argument should be measured. */ - enum { measure_length=0xffffffffU}; + /** Type of string lengths (sizes) and positions (indexes). */ + typedef size_t lenpos_t; + /** Out of bounds value indicating that the string argument should be measured. */ + enum { measure_length=0xffffffffU}; protected: - char *s; ///< The C string - lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string + char *s; ///< The C string + lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string - SContainer() : s(0), sSize(0) {} - ~SContainer() { - delete []s; // Suppose it was allocated using StringAllocate - s = 0; - sSize = 0; - } - /** Size of buffer. */ - lenpos_t size() const { - if (s) { - return sSize; - } else { - return 0; - } - } + SContainer() : s(0), sSize(0) {} + ~SContainer() { + delete []s; // Suppose it was allocated using StringAllocate + s = 0; + sSize = 0; + } + /** Size of buffer. */ + lenpos_t size() const { + if (s) { + return sSize; + } else { + return 0; + } + } public: - /** - * Allocate uninitialized memory big enough to fit a string of the given length. - * @return the pointer to the new string - */ - static char *StringAllocate(lenpos_t len); - /** - * Duplicate a buffer/C string. - * Allocate memory of the given size, or big enough to fit the string if length isn't given; - * then copy the given string in the allocated memory. - * @return the pointer to the new string - */ - static char *StringAllocate( - const char *s, ///< The string to duplicate - lenpos_t len=measure_length); ///< The length of memory to allocate. Optional. + /** + * Allocate uninitialized memory big enough to fit a string of the given length. + * @return the pointer to the new string + */ + static char *StringAllocate(lenpos_t len); + /** + * Duplicate a buffer/C string. + * Allocate memory of the given size, or big enough to fit the string if length isn't given; + * then copy the given string in the allocated memory. + * @return the pointer to the new string + */ + static char *StringAllocate( + const char *s, ///< The string to duplicate + lenpos_t len=measure_length); ///< The length of memory to allocate. Optional. }; @@ -77,46 +77,46 @@ class SContainer { */ class SBuffer : protected SContainer { public: - SBuffer(lenpos_t len) { - s = StringAllocate(len); - if (s) { - *s = '\0'; - sSize = len; - } else { - sSize = 0; - } - } + SBuffer(lenpos_t len) { + s = StringAllocate(len); + if (s) { + *s = '\0'; + sSize = len; + } else { + sSize = 0; + } + } private: - /// Copy constructor - // Here only to be on the safe size, user should avoid returning SBuffer values. - SBuffer(const SBuffer &source) : SContainer() { - s = StringAllocate(source.s, source.sSize); - sSize = (s) ? source.sSize : 0; - } - /// Default assignment operator - // Same here, shouldn't be used - SBuffer &operator=(const SBuffer &source) { - if (this != &source) { - delete []s; - s = StringAllocate(source.s, source.sSize); - sSize = (s) ? source.sSize : 0; - } - return *this; - } + /// Copy constructor + // Here only to be on the safe size, user should avoid returning SBuffer values. + SBuffer(const SBuffer &source) : SContainer() { + s = StringAllocate(source.s, source.sSize); + sSize = (s) ? source.sSize : 0; + } + /// Default assignment operator + // Same here, shouldn't be used + SBuffer &operator=(const SBuffer &source) { + if (this != &source) { + delete []s; + s = StringAllocate(source.s, source.sSize); + sSize = (s) ? source.sSize : 0; + } + return *this; + } public: - /** Provide direct read/write access to buffer. */ - char *ptr() { - return s; - } - /** Ownership of the buffer have been taken, so release it. */ - void reset() { - s = 0; - sSize = 0; - } - /** Size of buffer. */ - lenpos_t size() const { - return SContainer::size(); - } + /** Provide direct read/write access to buffer. */ + char *ptr() { + return s; + } + /** Ownership of the buffer have been taken, so release it. */ + void reset() { + s = 0; + sSize = 0; + } + /** Size of buffer. */ + lenpos_t size() const { + return SContainer::size(); + } }; @@ -129,138 +129,138 @@ class SBuffer : protected SContainer { * functions to allow reliable manipulations of these strings, other than simple appends, etc. */ class SString : protected SContainer { - lenpos_t sLen; ///< The size of the string in s - lenpos_t sizeGrowth; ///< Minimum growth size when appending strings - enum { sizeGrowthDefault = 64 }; + lenpos_t sLen; ///< The size of the string in s + lenpos_t sizeGrowth; ///< Minimum growth size when appending strings + enum { sizeGrowthDefault = 64 }; - bool grow(lenpos_t lenNew); - SString &assign(const char *sOther, lenpos_t sSize_=measure_length); + bool grow(lenpos_t lenNew); + SString &assign(const char *sOther, lenpos_t sSize_=measure_length); public: - SString() : sLen(0), sizeGrowth(sizeGrowthDefault) {} - SString(const SString &source) : SContainer(), sizeGrowth(sizeGrowthDefault) { - s = StringAllocate(source.s, source.sLen); - sSize = sLen = (s) ? source.sLen : 0; - } - SString(const char *s_) : sizeGrowth(sizeGrowthDefault) { - s = StringAllocate(s_); - sSize = sLen = (s) ? strlen(s) : 0; - } - SString(SBuffer &buf) : sizeGrowth(sizeGrowthDefault) { - s = buf.ptr(); - sSize = sLen = buf.size(); - // Consumes the given buffer! - buf.reset(); - } - SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) { - // note: expects the "last" argument to point one beyond the range end (a la STL iterators) - s = StringAllocate(s_ + first, last - first); - sSize = sLen = (s) ? last - first : 0; - } - SString(int i); - SString(double d, int precision); - ~SString() { - sLen = 0; - } - void clear() { - if (s) { - *s = '\0'; - } - sLen = 0; - } - /** Size of buffer. */ - lenpos_t size() const { - return SContainer::size(); - } - /** Size of string in buffer. */ - lenpos_t length() const { - return sLen; - } - /** Read access to a character of the string. */ - char operator[](lenpos_t i) const { - return (s && i < sSize) ? s[i] : '\0'; - } - SString &operator=(const char *source) { - return assign(source); - } - SString &operator=(const SString &source) { - if (this != &source) { - assign(source.s, source.sLen); - } - return *this; - } - bool operator==(const SString &sOther) const; - bool operator!=(const SString &sOther) const { - return !operator==(sOther); - } - bool operator==(const char *sOther) const; - bool operator!=(const char *sOther) const { - return !operator==(sOther); - } - bool contains(char ch) const { - return (s && *s) ? strchr(s, ch) != 0 : false; - } - void setsizegrowth(lenpos_t sizeGrowth_) { - sizeGrowth = sizeGrowth_; - } - const char *c_str() const { - return s ? s : ""; - } - /** Give ownership of buffer to caller which must use delete[] to free buffer. */ - char *detach() { - char *sRet = s; - s = 0; - sSize = 0; - sLen = 0; - return sRet; - } - SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const; - SString &lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length); - SString &uppercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length); - SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0'); - SString &operator+=(const char *sOther) { - return append(sOther, static_cast(measure_length)); - } - SString &operator+=(const SString &sOther) { - return append(sOther.s, sOther.sLen); - } - SString &operator+=(char ch) { - return append(&ch, 1); - } - SString &appendwithseparator(const char *sOther, char sep) { - return append(sOther, strlen(sOther), sep); - } - SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length); + SString() : sLen(0), sizeGrowth(sizeGrowthDefault) {} + SString(const SString &source) : SContainer(), sizeGrowth(sizeGrowthDefault) { + s = StringAllocate(source.s, source.sLen); + sSize = sLen = (s) ? source.sLen : 0; + } + SString(const char *s_) : sizeGrowth(sizeGrowthDefault) { + s = StringAllocate(s_); + sSize = sLen = (s) ? strlen(s) : 0; + } + SString(SBuffer &buf) : sizeGrowth(sizeGrowthDefault) { + s = buf.ptr(); + sSize = sLen = buf.size(); + // Consumes the given buffer! + buf.reset(); + } + SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) { + // note: expects the "last" argument to point one beyond the range end (a la STL iterators) + s = StringAllocate(s_ + first, last - first); + sSize = sLen = (s) ? last - first : 0; + } + SString(int i); + SString(double d, int precision); + ~SString() { + sLen = 0; + } + void clear() { + if (s) { + *s = '\0'; + } + sLen = 0; + } + /** Size of buffer. */ + lenpos_t size() const { + return SContainer::size(); + } + /** Size of string in buffer. */ + lenpos_t length() const { + return sLen; + } + /** Read access to a character of the string. */ + char operator[](lenpos_t i) const { + return (s && i < sSize) ? s[i] : '\0'; + } + SString &operator=(const char *source) { + return assign(source); + } + SString &operator=(const SString &source) { + if (this != &source) { + assign(source.s, source.sLen); + } + return *this; + } + bool operator==(const SString &sOther) const; + bool operator!=(const SString &sOther) const { + return !operator==(sOther); + } + bool operator==(const char *sOther) const; + bool operator!=(const char *sOther) const { + return !operator==(sOther); + } + bool contains(char ch) const { + return (s && *s) ? strchr(s, ch) != 0 : false; + } + void setsizegrowth(lenpos_t sizeGrowth_) { + sizeGrowth = sizeGrowth_; + } + const char *c_str() const { + return s ? s : ""; + } + /** Give ownership of buffer to caller which must use delete[] to free buffer. */ + char *detach() { + char *sRet = s; + s = 0; + sSize = 0; + sLen = 0; + return sRet; + } + SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const; + SString &lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length); + SString &uppercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length); + SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0'); + SString &operator+=(const char *sOther) { + return append(sOther, static_cast(measure_length)); + } + SString &operator+=(const SString &sOther) { + return append(sOther.s, sOther.sLen); + } + SString &operator+=(char ch) { + return append(&ch, 1); + } + SString &appendwithseparator(const char *sOther, char sep) { + return append(sOther, strlen(sOther), sep); + } + SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length); - /** - * Remove @a len characters from the @a pos position, included. - * Characters at pos + len and beyond replace characters at pos. - * If @a len is 0, or greater than the length of the string - * starting at @a pos, the string is just truncated at @a pos. - */ - void remove(lenpos_t pos, lenpos_t len); + /** + * Remove @a len characters from the @a pos position, included. + * Characters at pos + len and beyond replace characters at pos. + * If @a len is 0, or greater than the length of the string + * starting at @a pos, the string is just truncated at @a pos. + */ + void remove(lenpos_t pos, lenpos_t len); - SString &change(lenpos_t pos, char ch) { - if (pos < sLen) { // character changed must be in string bounds - *(s + pos) = ch; - } - return *this; - } - /** Read an integral numeric value from the string. */ - int value() const { - return s ? atoi(s) : 0; - } - bool startswith(const char *prefix); - bool endswith(const char *suffix); - int search(const char *sFind, lenpos_t start=0) const; - bool contains(const char *sFind) const { - return search(sFind) >= 0; - } - int substitute(char chFind, char chReplace); - int substitute(const char *sFind, const char *sReplace); - int remove(const char *sFind) { - return substitute(sFind, ""); - } + SString &change(lenpos_t pos, char ch) { + if (pos < sLen) { // character changed must be in string bounds + *(s + pos) = ch; + } + return *this; + } + /** Read an integral numeric value from the string. */ + int value() const { + return s ? atoi(s) : 0; + } + bool startswith(const char *prefix); + bool endswith(const char *suffix); + int search(const char *sFind, lenpos_t start=0) const; + bool contains(const char *sFind) const { + return search(sFind) >= 0; + } + int substitute(char chFind, char chReplace); + int substitute(const char *sFind, const char *sReplace); + int remove(const char *sFind) { + return substitute(sFind, ""); + } }; @@ -271,10 +271,10 @@ class SString : protected SContainer { * @return the pointer to the new string */ inline char *StringDup( - const char *s, ///< The string to duplicate - SContainer::lenpos_t len=SContainer::measure_length) ///< The length of memory to allocate. Optional. + const char *s, ///< The string to duplicate + SContainer::lenpos_t len=SContainer::measure_length) ///< The length of memory to allocate. Optional. { - return SContainer::StringAllocate(s, len); + return SContainer::StringAllocate(s, len); } #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Scintilla.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Scintilla.h index 5d2adb21828..36e77c6cc2b 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Scintilla.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/Scintilla.h @@ -699,19 +699,19 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, // So older code that treats Scintilla as a RichEdit will work. struct CharacterRange { - long cpMin; - long cpMax; + long cpMin; + long cpMax; }; struct TextRange { - struct CharacterRange chrg; - char *lpstrText; + struct CharacterRange chrg; + char *lpstrText; }; struct TextToFind { - struct CharacterRange chrg; - char *lpstrText; - struct CharacterRange chrgText; + struct CharacterRange chrg; + char *lpstrText; + struct CharacterRange chrgText; }; #ifdef PLATFORM_H @@ -720,43 +720,43 @@ struct TextToFind { // from Platform.h. Not needed by most client code. struct RangeToFormat { - SurfaceID hdc; - SurfaceID hdcTarget; - PRectangle rc; - PRectangle rcPage; - CharacterRange chrg; + SurfaceID hdc; + SurfaceID hdcTarget; + PRectangle rc; + PRectangle rcPage; + CharacterRange chrg; }; #endif struct NotifyHeader { - // Compatible with Windows NMHDR. - // hwndFrom is really an environment specific window handle or pointer - // but most clients of Scintilla.h do not have this type visible. - void *hwndFrom; - uptr_t idFrom; - unsigned int code; + // Compatible with Windows NMHDR. + // hwndFrom is really an environment specific window handle or pointer + // but most clients of Scintilla.h do not have this type visible. + void *hwndFrom; + uptr_t idFrom; + unsigned int code; }; struct SCNotification { - struct NotifyHeader nmhdr; - int position; // SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND - int ch; // SCN_CHARADDED, SCN_KEY - int modifiers; // SCN_KEY - int modificationType; // SCN_MODIFIED - const char *text; // SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION - int length; // SCN_MODIFIED - int linesAdded; // SCN_MODIFIED - int message; // SCN_MACRORECORD - uptr_t wParam; // SCN_MACRORECORD - sptr_t lParam; // SCN_MACRORECORD - int line; // SCN_MODIFIED - int foldLevelNow; // SCN_MODIFIED - int foldLevelPrev; // SCN_MODIFIED - int margin; // SCN_MARGINCLICK - int listType; // SCN_USERLISTSELECTION - int x; // SCN_DWELLSTART, SCN_DWELLEND - int y; // SCN_DWELLSTART, SCN_DWELLEND + struct NotifyHeader nmhdr; + int position; // SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND + int ch; // SCN_CHARADDED, SCN_KEY + int modifiers; // SCN_KEY + int modificationType; // SCN_MODIFIED + const char *text; // SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION + int length; // SCN_MODIFIED + int linesAdded; // SCN_MODIFIED + int message; // SCN_MACRORECORD + uptr_t wParam; // SCN_MACRORECORD + sptr_t lParam; // SCN_MACRORECORD + int line; // SCN_MODIFIED + int foldLevelNow; // SCN_MODIFIED + int foldLevelPrev; // SCN_MODIFIED + int margin; // SCN_MARGINCLICK + int listType; // SCN_USERLISTSELECTION + int x; // SCN_DWELLSTART, SCN_DWELLEND + int y; // SCN_DWELLSTART, SCN_DWELLEND }; // Deprecation section listing all API features that are deprecated and will diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/ScintillaWidget.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/ScintillaWidget.h index 9d23ce2a918..5313c18e3a6 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/ScintillaWidget.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/ScintillaWidget.h @@ -23,26 +23,26 @@ typedef struct _ScintillaObject ScintillaObject; typedef struct _ScintillaClass ScintillaClass; struct _ScintillaObject { - GtkContainer cont; - void *pscin; + GtkContainer cont; + void *pscin; }; struct _ScintillaClass { - GtkContainerClass parent_class; + GtkContainerClass parent_class; - void (* command) (ScintillaObject *ttt); - void (* notify) (ScintillaObject *ttt); + void (* command) (ScintillaObject *ttt); + void (* notify) (ScintillaObject *ttt); }; #if GLIB_MAJOR_VERSION < 2 -GtkType scintilla_get_type (void); +GtkType scintilla_get_type (void); #else -GType scintilla_get_type (void); +GType scintilla_get_type (void); #endif -GtkWidget* scintilla_new (void); -void scintilla_set_id (ScintillaObject *sci, uptr_t id); -sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam); -void scintilla_release_resources(void); +GtkWidget* scintilla_new (void); +void scintilla_set_id (ScintillaObject *sci, uptr_t id); +sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam); +void scintilla_release_resources(void); #if GTK_MAJOR_VERSION < 2 #define SCINTILLA_NOTIFY "notify" diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/WindowAccessor.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/WindowAccessor.h index 6c16b150f26..dae354dd86f 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/WindowAccessor.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/include/WindowAccessor.h @@ -9,49 +9,49 @@ /** */ class WindowAccessor : public Accessor { - // Private so WindowAccessor objects can not be copied - WindowAccessor(const WindowAccessor &source) : Accessor(), props(source.props) {} - WindowAccessor &operator=(const WindowAccessor &) { return *this; } + // Private so WindowAccessor objects can not be copied + WindowAccessor(const WindowAccessor &source) : Accessor(), props(source.props) {} + WindowAccessor &operator=(const WindowAccessor &) { return *this; } protected: - WindowID id; - PropSet &props; - int lenDoc; + WindowID id; + PropSet &props; + int lenDoc; - char styleBuf[bufferSize]; - int validLen; - char chFlags; - char chWhile; - unsigned int startSeg; + char styleBuf[bufferSize]; + int validLen; + char chFlags; + char chWhile; + unsigned int startSeg; - bool InternalIsLeadByte(char ch); - void Fill(int position); + bool InternalIsLeadByte(char ch); + void Fill(int position); public: - WindowAccessor(WindowID id_, PropSet &props_) : - Accessor(), id(id_), props(props_), - lenDoc(-1), validLen(0), chFlags(0), chWhile(0) { - } - ~WindowAccessor(); - bool Match(int pos, const char *s); - char StyleAt(int position); - int GetLine(int position); - int LineStart(int line); - int LevelAt(int line); - int Length(); - void Flush(); - int GetLineState(int line); - int SetLineState(int line, int state); - int GetPropertyInt(const char *key, int defaultValue=0) { - return props.GetInt(key, defaultValue); - } - char *GetProperties() { - return props.ToString(); - } + WindowAccessor(WindowID id_, PropSet &props_) : + Accessor(), id(id_), props(props_), + lenDoc(-1), validLen(0), chFlags(0), chWhile(0) { + } + ~WindowAccessor(); + bool Match(int pos, const char *s); + char StyleAt(int position); + int GetLine(int position); + int LineStart(int line); + int LevelAt(int line); + int Length(); + void Flush(); + int GetLineState(int line); + int SetLineState(int line, int state); + int GetPropertyInt(const char *key, int defaultValue=0) { + return props.GetInt(key, defaultValue); + } + char *GetProperties() { + return props.ToString(); + } - void StartAt(unsigned int start, char chMask=31); - void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; }; - unsigned int GetStartSegment() { return startSeg; } - void StartSegment(unsigned int pos); - void ColourTo(unsigned int pos, int chAttr); - void SetLevel(int line, int level); - int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); + void StartAt(unsigned int start, char chMask=31); + void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; }; + unsigned int GetStartSegment() { return startSeg; } + void StartSegment(unsigned int pos); + void ColourTo(unsigned int pos, int chAttr); + void SetLevel(int line, int level); + int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); }; diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/AutoComplete.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/AutoComplete.h index 10577ca3805..7268a157385 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/AutoComplete.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/AutoComplete.h @@ -11,60 +11,60 @@ /** */ class AutoComplete { - bool active; - char stopChars[256]; - char fillUpChars[256]; - char separator; - char typesep; // Type seperator + bool active; + char stopChars[256]; + char fillUpChars[256]; + char separator; + char typesep; // Type seperator public: - bool ignoreCase; - bool chooseSingle; - ListBox *lb; - int posStart; - int startLen; - /// Should autocompletion be canceled if editor's currentPos <= startPos? - bool cancelAtStartPos; - bool autoHide; - bool dropRestOfWord; + bool ignoreCase; + bool chooseSingle; + ListBox *lb; + int posStart; + int startLen; + /// Should autocompletion be canceled if editor's currentPos <= startPos? + bool cancelAtStartPos; + bool autoHide; + bool dropRestOfWord; - AutoComplete(); - ~AutoComplete(); + AutoComplete(); + ~AutoComplete(); - /// Is the auto completion list displayed? - bool Active(); + /// Is the auto completion list displayed? + bool Active(); - /// Display the auto completion list positioned to be near a character position - void Start(Window &parent, int ctrlID, int position, Point location, - int startLen_, int lineHeight, bool unicodeMode); + /// Display the auto completion list positioned to be near a character position + void Start(Window &parent, int ctrlID, int position, Point location, + int startLen_, int lineHeight, bool unicodeMode); - /// The stop chars are characters which, when typed, cause the auto completion list to disappear - void SetStopChars(const char *stopChars_); - bool IsStopChar(char ch); + /// The stop chars are characters which, when typed, cause the auto completion list to disappear + void SetStopChars(const char *stopChars_); + bool IsStopChar(char ch); - /// The fillup chars are characters which, when typed, fill up the selected word - void SetFillUpChars(const char *fillUpChars_); - bool IsFillUpChar(char ch); + /// The fillup chars are characters which, when typed, fill up the selected word + void SetFillUpChars(const char *fillUpChars_); + bool IsFillUpChar(char ch); - /// The separator character is used when interpreting the list in SetList - void SetSeparator(char separator_); - char GetSeparator(); + /// The separator character is used when interpreting the list in SetList + void SetSeparator(char separator_); + char GetSeparator(); - /// The typesep character is used for seperating the word from the type - void SetTypesep(char separator_); - char GetTypesep(); + /// The typesep character is used for seperating the word from the type + void SetTypesep(char separator_); + char GetTypesep(); - /// The list string contains a sequence of words separated by the separator character - void SetList(const char *list); + /// The list string contains a sequence of words separated by the separator character + void SetList(const char *list); - void Show(bool show); - void Cancel(); + void Show(bool show); + void Cancel(); - /// Move the current list element by delta, scrolling appropriately - void Move(int delta); + /// Move the current list element by delta, scrolling appropriately + void Move(int delta); - /// Select a list element that starts with word as the current element - void Select(const char *word); + /// Select a list element that starts with word as the current element + void Select(const char *word); }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CallTip.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CallTip.h index 9848a10af98..55acba4b458 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CallTip.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CallTip.h @@ -11,69 +11,69 @@ /** */ class CallTip { - int startHighlight; // character offset to start and... - int endHighlight; // ...end of highlighted text - char *val; - Font font; - PRectangle rectUp; // rectangle of last up angle in the tip - PRectangle rectDown; // rectangle of last down arrow in the tip - int lineHeight; // vertical line spacing - int offsetMain; // The alignment point of the call tip - int tabSize; // Tab size in pixels, <=0 no TAB expand - bool useStyleCallTip; // if true, STYLE_CALLTIP should be used + int startHighlight; // character offset to start and... + int endHighlight; // ...end of highlighted text + char *val; + Font font; + PRectangle rectUp; // rectangle of last up angle in the tip + PRectangle rectDown; // rectangle of last down arrow in the tip + int lineHeight; // vertical line spacing + int offsetMain; // The alignment point of the call tip + int tabSize; // Tab size in pixels, <=0 no TAB expand + bool useStyleCallTip; // if true, STYLE_CALLTIP should be used - // Private so CallTip objects can not be copied - CallTip(const CallTip &) {} - CallTip &operator=(const CallTip &) { return *this; } - void DrawChunk(Surface *surface, int &x, const char *s, - int posStart, int posEnd, int ytext, PRectangle rcClient, - bool highlight, bool draw); - int PaintContents(Surface *surfaceWindow, bool draw); - bool IsTabCharacter(char c); - int NextTabPos(int x); + // Private so CallTip objects can not be copied + CallTip(const CallTip &) {} + CallTip &operator=(const CallTip &) { return *this; } + void DrawChunk(Surface *surface, int &x, const char *s, + int posStart, int posEnd, int ytext, PRectangle rcClient, + bool highlight, bool draw); + int PaintContents(Surface *surfaceWindow, bool draw); + bool IsTabCharacter(char c); + int NextTabPos(int x); public: - Window wCallTip; - Window wDraw; - bool inCallTipMode; - int posStartCallTip; - ColourPair colourBG; - ColourPair colourUnSel; - ColourPair colourSel; - ColourPair colourShade; - ColourPair colourLight; - int codePage; - int clickPlace; + Window wCallTip; + Window wDraw; + bool inCallTipMode; + int posStartCallTip; + ColourPair colourBG; + ColourPair colourUnSel; + ColourPair colourSel; + ColourPair colourShade; + ColourPair colourLight; + int codePage; + int clickPlace; - CallTip(); - ~CallTip(); + CallTip(); + ~CallTip(); - /// Claim or accept palette entries for the colours required to paint a calltip. - void RefreshColourPalette(Palette &pal, bool want); + /// Claim or accept palette entries for the colours required to paint a calltip. + void RefreshColourPalette(Palette &pal, bool want); - void PaintCT(Surface *surfaceWindow); + void PaintCT(Surface *surfaceWindow); - void MouseClick(Point pt); + void MouseClick(Point pt); - /// Setup the calltip and return a rectangle of the area required. - PRectangle CallTipStart(int pos, Point pt, const char *defn, - const char *faceName, int size, int codePage_, - int characterSet, Window &wParent); + /// Setup the calltip and return a rectangle of the area required. + PRectangle CallTipStart(int pos, Point pt, const char *defn, + const char *faceName, int size, int codePage_, + int characterSet, Window &wParent); - void CallTipCancel(); + void CallTipCancel(); - /// Set a range of characters to be displayed in a highlight style. - /// Commonly used to highlight the current parameter. - void SetHighlight(int start, int end); + /// Set a range of characters to be displayed in a highlight style. + /// Commonly used to highlight the current parameter. + void SetHighlight(int start, int end); - /// Set the tab size in pixels for the call tip. 0 or -ve means no tab expand. - void SetTabSize(int tabSz); + /// Set the tab size in pixels for the call tip. 0 or -ve means no tab expand. + void SetTabSize(int tabSz); - /// Used to determine which STYLE_xxxx to use for call tip information - bool UseStyleCallTip() const { return useStyleCallTip;} + /// Used to determine which STYLE_xxxx to use for call tip information + bool UseStyleCallTip() const { return useStyleCallTip;} - // Modify foreground and background colours - void SetForeBack(const ColourPair &fore, const ColourPair &back); + // Modify foreground and background colours + void SetForeBack(const ColourPair &fore, const ColourPair &back); }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CellBuffer.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CellBuffer.h index bb81fd5722d..255535d87f0 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CellBuffer.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CellBuffer.h @@ -13,28 +13,28 @@ * MarkerHandleNumbers are members of lists. */ struct MarkerHandleNumber { - int handle; - int number; - MarkerHandleNumber *next; + int handle; + int number; + MarkerHandleNumber *next; }; /** * A marker handle set contains any number of MarkerHandleNumbers. */ class MarkerHandleSet { - MarkerHandleNumber *root; + MarkerHandleNumber *root; public: - MarkerHandleSet(); - ~MarkerHandleSet(); - int Length(); - int NumberFromHandle(int handle); - int MarkValue(); ///< Bit set of marker numbers. - bool Contains(int handle); - bool InsertHandle(int handle, int markerNum); - void RemoveHandle(int handle); - bool RemoveNumber(int markerNum); - void CombineWith(MarkerHandleSet *other); + MarkerHandleSet(); + ~MarkerHandleSet(); + int Length(); + int NumberFromHandle(int handle); + int MarkValue(); ///< Bit set of marker numbers. + bool Contains(int handle); + bool InsertHandle(int handle, int markerNum); + void RemoveHandle(int handle); + bool RemoveNumber(int markerNum); + void CombineWith(MarkerHandleSet *other); }; /** @@ -42,10 +42,10 @@ class MarkerHandleSet { * and potentially a marker handle set. Often a line will not have any attached markers. */ struct LineData { - int startPosition; - MarkerHandleSet *handleSet; - LineData() : startPosition(0), handleSet(0) { - } + int startPosition; + MarkerHandleSet *handleSet; + LineData() : startPosition(0), handleSet(0) { + } }; /** @@ -53,33 +53,33 @@ struct LineData { */ class LineVector { public: - int growSize; - int lines; - LineData *linesData; - int size; - int *levels; - int sizeLevels; - - /// Handles are allocated sequentially and should never have to be reused as 32 bit ints are very big. - int handleCurrent; - - LineVector(); - ~LineVector(); - void Init(); - - void Expand(int sizeNew); - void ExpandLevels(int sizeNew=-1); - void ClearLevels(); - void InsertValue(int pos, int value); - void SetValue(int pos, int value); - void Remove(int pos); - int LineFromPosition(int pos); - - int AddMark(int line, int marker); - void MergeMarkers(int pos); - void DeleteMark(int line, int markerNum, bool all); - void DeleteMarkFromHandle(int markerHandle); - int LineFromHandle(int markerHandle); + int growSize; + int lines; + LineData *linesData; + int size; + int *levels; + int sizeLevels; + + /// Handles are allocated sequentially and should never have to be reused as 32 bit ints are very big. + int handleCurrent; + + LineVector(); + ~LineVector(); + void Init(); + + void Expand(int sizeNew); + void ExpandLevels(int sizeNew=-1); + void ClearLevels(); + void InsertValue(int pos, int value); + void SetValue(int pos, int value); + void Remove(int pos); + int LineFromPosition(int pos); + + int AddMark(int line, int marker); + void MergeMarkers(int pos); + void DeleteMark(int line, int markerNum, bool all); + void DeleteMarkFromHandle(int markerHandle); + int LineFromHandle(int markerHandle); }; enum actionType { insertAction, removeAction, startAction }; @@ -89,58 +89,58 @@ enum actionType { insertAction, removeAction, startAction }; */ class Action { public: - actionType at; - int position; - char *data; - int lenData; - bool mayCoalesce; - - Action(); - ~Action(); - void Create(actionType at_, int position_=0, char *data_=0, int lenData_=0, bool mayCoalesce_=true); - void Destroy(); - void Grab(Action *source); + actionType at; + int position; + char *data; + int lenData; + bool mayCoalesce; + + Action(); + ~Action(); + void Create(actionType at_, int position_=0, char *data_=0, int lenData_=0, bool mayCoalesce_=true); + void Destroy(); + void Grab(Action *source); }; /** * */ class UndoHistory { - Action *actions; - int lenActions; - int maxAction; - int currentAction; - int undoSequenceDepth; - int savePoint; + Action *actions; + int lenActions; + int maxAction; + int currentAction; + int undoSequenceDepth; + int savePoint; - void EnsureUndoRoom(); + void EnsureUndoRoom(); public: - UndoHistory(); - ~UndoHistory(); - - void AppendAction(actionType at, int position, char *data, int length); - - void BeginUndoAction(); - void EndUndoAction(); - void DropUndoSequence(); - void DeleteUndoHistory(); - - /// The save point is a marker in the undo stack where the container has stated that - /// the buffer was saved. Undo and redo can move over the save point. - void SetSavePoint(); - bool IsSavePoint() const; - - /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is - /// called that many times. Similarly for redo. - bool CanUndo() const; - int StartUndo(); - const Action &GetUndoStep() const; - void CompletedUndoStep(); - bool CanRedo() const; - int StartRedo(); - const Action &GetRedoStep() const; - void CompletedRedoStep(); + UndoHistory(); + ~UndoHistory(); + + void AppendAction(actionType at, int position, char *data, int length); + + void BeginUndoAction(); + void EndUndoAction(); + void DropUndoSequence(); + void DeleteUndoHistory(); + + /// The save point is a marker in the undo stack where the container has stated that + /// the buffer was saved. Undo and redo can move over the save point. + void SetSavePoint(); + bool IsSavePoint() const; + + /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is + /// called that many times. Similarly for redo. + bool CanUndo() const; + int StartUndo(); + const Action &GetUndoStep() const; + void CompletedUndoStep(); + bool CanRedo() const; + int StartRedo(); + const Action &GetRedoStep() const; + void CompletedRedoStep(); }; /** @@ -150,101 +150,101 @@ class UndoHistory { */ class CellBuffer { private: - char *body; ///< The cell buffer itself. - int size; ///< Allocated size of the buffer. - int length; ///< Total length of the data. - int part1len; ///< Length of the first part. - int gaplen; ///< Length of the gap between the two parts. - char *part2body; ///< The second part of the cell buffer. - ///< Doesn't point after the gap but set so that - ///< part2body[position] is consistent with body[position]. - bool readOnly; - int growSize; + char *body; ///< The cell buffer itself. + int size; ///< Allocated size of the buffer. + int length; ///< Total length of the data. + int part1len; ///< Length of the first part. + int gaplen; ///< Length of the gap between the two parts. + char *part2body; ///< The second part of the cell buffer. + ///< Doesn't point after the gap but set so that + ///< part2body[position] is consistent with body[position]. + bool readOnly; + int growSize; - bool collectingUndo; - UndoHistory uh; + bool collectingUndo; + UndoHistory uh; - LineVector lv; + LineVector lv; - SVector lineStates; + SVector lineStates; - void GapTo(int position); - void RoomFor(int insertionLength); + void GapTo(int position); + void RoomFor(int insertionLength); - inline char ByteAt(int position); - void SetByteAt(int position, char ch); + inline char ByteAt(int position); + void SetByteAt(int position, char ch); public: - CellBuffer(int initialLength = 4000); - ~CellBuffer(); - - /// Retrieving positions outside the range of the buffer works and returns 0 - char CharAt(int position); - void GetCharRange(char *buffer, int position, int lengthRetrieve); - char StyleAt(int position); - - int ByteLength(); - int Length(); - void Allocate(int newSize); - int Lines(); - int LineStart(int line); - int LineFromPosition(int pos) { return lv.LineFromPosition(pos); } - const char *InsertString(int position, char *s, int insertLength); - - /// Setting styles for positions outside the range of the buffer is safe and has no effect. - /// @return true if the style of a character is changed. - bool SetStyleAt(int position, char style, char mask='\377'); - bool SetStyleFor(int position, int length, char style, char mask); - - const char *DeleteChars(int position, int deleteLength); - - bool IsReadOnly(); - void SetReadOnly(bool set); - - /// The save point is a marker in the undo stack where the container has stated that - /// the buffer was saved. Undo and redo can move over the save point. - void SetSavePoint(); - bool IsSavePoint(); - - /// Line marker functions - int AddMark(int line, int markerNum); - void DeleteMark(int line, int markerNum); - void DeleteMarkFromHandle(int markerHandle); - int GetMark(int line); - void DeleteAllMarks(int markerNum); - int LineFromHandle(int markerHandle); - - /// Actions without undo - void BasicInsertString(int position, char *s, int insertLength); - void BasicDeleteChars(int position, int deleteLength); - - bool SetUndoCollection(bool collectUndo); - bool IsCollectingUndo(); - void BeginUndoAction(); - void EndUndoAction(); - void DeleteUndoHistory(); - - /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is - /// called that many times. Similarly for redo. - bool CanUndo(); - int StartUndo(); - const Action &GetUndoStep() const; - void PerformUndoStep(); - bool CanRedo(); - int StartRedo(); - const Action &GetRedoStep() const; - void PerformRedoStep(); - - int SetLineState(int line, int state); - int GetLineState(int line); - int GetMaxLineState(); - - int SetLevel(int line, int level); - int GetLevel(int line); - void ClearLevels(); + CellBuffer(int initialLength = 4000); + ~CellBuffer(); + + /// Retrieving positions outside the range of the buffer works and returns 0 + char CharAt(int position); + void GetCharRange(char *buffer, int position, int lengthRetrieve); + char StyleAt(int position); + + int ByteLength(); + int Length(); + void Allocate(int newSize); + int Lines(); + int LineStart(int line); + int LineFromPosition(int pos) { return lv.LineFromPosition(pos); } + const char *InsertString(int position, char *s, int insertLength); + + /// Setting styles for positions outside the range of the buffer is safe and has no effect. + /// @return true if the style of a character is changed. + bool SetStyleAt(int position, char style, char mask='\377'); + bool SetStyleFor(int position, int length, char style, char mask); + + const char *DeleteChars(int position, int deleteLength); + + bool IsReadOnly(); + void SetReadOnly(bool set); + + /// The save point is a marker in the undo stack where the container has stated that + /// the buffer was saved. Undo and redo can move over the save point. + void SetSavePoint(); + bool IsSavePoint(); + + /// Line marker functions + int AddMark(int line, int markerNum); + void DeleteMark(int line, int markerNum); + void DeleteMarkFromHandle(int markerHandle); + int GetMark(int line); + void DeleteAllMarks(int markerNum); + int LineFromHandle(int markerHandle); + + /// Actions without undo + void BasicInsertString(int position, char *s, int insertLength); + void BasicDeleteChars(int position, int deleteLength); + + bool SetUndoCollection(bool collectUndo); + bool IsCollectingUndo(); + void BeginUndoAction(); + void EndUndoAction(); + void DeleteUndoHistory(); + + /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is + /// called that many times. Similarly for redo. + bool CanUndo(); + int StartUndo(); + const Action &GetUndoStep() const; + void PerformUndoStep(); + bool CanRedo(); + int StartRedo(); + const Action &GetRedoStep() const; + void PerformRedoStep(); + + int SetLineState(int line, int state); + int GetLineState(int line); + int GetMaxLineState(); + + int SetLevel(int line, int level); + int GetLevel(int line); + void ClearLevels(); }; -#define CELL_SIZE 2 +#define CELL_SIZE 2 #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CharClassify.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CharClassify.h index 881d3a114b3..e06704576b8 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CharClassify.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/CharClassify.h @@ -10,16 +10,16 @@ class CharClassify { public: - CharClassify(); + CharClassify(); - enum cc { ccSpace, ccNewLine, ccWord, ccPunctuation }; - void SetDefaultCharClasses(bool includeWordClass); - void SetCharClasses(const unsigned char *chars, cc newCharClass); - cc GetClass(unsigned char ch) const { return static_cast(charClass[ch]);} - bool IsWord(unsigned char ch) const { return static_cast(charClass[ch]) == ccWord;} + enum cc { ccSpace, ccNewLine, ccWord, ccPunctuation }; + void SetDefaultCharClasses(bool includeWordClass); + void SetCharClasses(const unsigned char *chars, cc newCharClass); + cc GetClass(unsigned char ch) const { return static_cast(charClass[ch]);} + bool IsWord(unsigned char ch) const { return static_cast(charClass[ch]) == ccWord;} private: - enum { maxChar=256 }; - unsigned char charClass[maxChar]; // not type cc to save space + enum { maxChar=256 }; + unsigned char charClass[maxChar]; // not type cc to save space }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ContractionState.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ContractionState.h index e15ee3bbe62..bfd2bf144a1 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ContractionState.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ContractionState.h @@ -12,54 +12,54 @@ */ class OneLine { public: - int displayLine; ///< Position within set of visible lines - //int docLine; ///< Inverse of @a displayLine - int height; ///< Number of display lines needed to show all of the line - bool visible; - bool expanded; + int displayLine; ///< Position within set of visible lines + //int docLine; ///< Inverse of @a displayLine + int height; ///< Number of display lines needed to show all of the line + bool visible; + bool expanded; - OneLine(); - virtual ~OneLine() {} + OneLine(); + virtual ~OneLine() {} }; /** */ class ContractionState { - void Grow(int sizeNew); - enum { growSize = 4000 }; - int linesInDoc; - mutable int linesInDisplay; - mutable OneLine *lines; - int size; - mutable int *docLines; - mutable int sizeDocLines; - mutable bool valid; - void MakeValid() const; + void Grow(int sizeNew); + enum { growSize = 4000 }; + int linesInDoc; + mutable int linesInDisplay; + mutable OneLine *lines; + int size; + mutable int *docLines; + mutable int sizeDocLines; + mutable bool valid; + void MakeValid() const; public: - ContractionState(); - virtual ~ContractionState(); + ContractionState(); + virtual ~ContractionState(); - void Clear(); + void Clear(); - int LinesInDoc() const; - int LinesDisplayed() const; - int DisplayFromDoc(int lineDoc) const; - int DocFromDisplay(int lineDisplay) const; + int LinesInDoc() const; + int LinesDisplayed() const; + int DisplayFromDoc(int lineDoc) const; + int DocFromDisplay(int lineDisplay) const; - void InsertLines(int lineDoc, int lineCount); - void DeleteLines(int lineDoc, int lineCount); + void InsertLines(int lineDoc, int lineCount); + void DeleteLines(int lineDoc, int lineCount); - bool GetVisible(int lineDoc) const; - bool SetVisible(int lineDocStart, int lineDocEnd, bool visible); + bool GetVisible(int lineDoc) const; + bool SetVisible(int lineDocStart, int lineDocEnd, bool visible); - bool GetExpanded(int lineDoc) const; - bool SetExpanded(int lineDoc, bool expanded); + bool GetExpanded(int lineDoc) const; + bool SetExpanded(int lineDoc, bool expanded); - int GetHeight(int lineDoc) const; - bool SetHeight(int lineDoc, int height); + int GetHeight(int lineDoc) const; + bool SetHeight(int lineDoc, int height); - void ShowAll(); + void ShowAll(); }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Document.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Document.h index d774d5664e3..338cfc142fc 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Document.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Document.h @@ -23,49 +23,49 @@ const Position invalidPosition = -1; */ class Range { public: - Position start; - Position end; - - Range(Position pos=0) : - start(pos), end(pos) { - }; - Range(Position start_, Position end_) : - start(start_), end(end_) { - }; - - bool Valid() const { - return (start != invalidPosition) && (end != invalidPosition); - } - - // Is the position within the range? - bool Contains(Position pos) const { - if (start < end) { - return (pos >= start && pos <= end); - } else { - return (pos <= start && pos >= end); - } - } - - // Is the character after pos within the range? - bool ContainsCharacter(Position pos) const { - if (start < end) { - return (pos >= start && pos < end); - } else { - return (pos < start && pos >= end); - } - } - - bool Contains(Range other) const { - return Contains(other.start) && Contains(other.end); - } - - bool Overlaps(Range other) const { - return - Contains(other.start) || - Contains(other.end) || - other.Contains(start) || - other.Contains(end); - } + Position start; + Position end; + + Range(Position pos=0) : + start(pos), end(pos) { + }; + Range(Position start_, Position end_) : + start(start_), end(end_) { + }; + + bool Valid() const { + return (start != invalidPosition) && (end != invalidPosition); + } + + // Is the position within the range? + bool Contains(Position pos) const { + if (start < end) { + return (pos >= start && pos <= end); + } else { + return (pos <= start && pos >= end); + } + } + + // Is the character after pos within the range? + bool ContainsCharacter(Position pos) const { + if (start < end) { + return (pos >= start && pos < end); + } else { + return (pos < start && pos >= end); + } + } + + bool Contains(Range other) const { + return Contains(other.start) && Contains(other.end); + } + + bool Overlaps(Range other) const { + return + Contains(other.start) || + Contains(other.end) || + other.Contains(start) || + other.Contains(end); + } }; class DocWatcher; @@ -77,176 +77,176 @@ class RESearch; class Document { public: - /** Used to pair watcher pointer with user data. */ - class WatcherWithUserData { - public: - DocWatcher *watcher; - void *userData; - WatcherWithUserData() { - watcher = 0; - userData = 0; - } - }; - - enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation }; + /** Used to pair watcher pointer with user data. */ + class WatcherWithUserData { + public: + DocWatcher *watcher; + void *userData; + WatcherWithUserData() { + watcher = 0; + userData = 0; + } + }; + + enum charClassification { ccSpace, ccNewLine, ccWord, ccPunctuation }; private: - int refCount; - CellBuffer cb; - CharClassify charClass; - char stylingMask; - int endStyled; - int styleClock; - int enteredCount; - int enteredReadOnlyCount; - - WatcherWithUserData *watchers; - int lenWatchers; - - bool matchesValid; - RESearch *pre; - char *substituted; + int refCount; + CellBuffer cb; + CharClassify charClass; + char stylingMask; + int endStyled; + int styleClock; + int enteredCount; + int enteredReadOnlyCount; + + WatcherWithUserData *watchers; + int lenWatchers; + + bool matchesValid; + RESearch *pre; + char *substituted; public: - int stylingBits; - int stylingBitsMask; - - int eolMode; - /// Can also be SC_CP_UTF8 to enable UTF-8 mode - int dbcsCodePage; - int tabInChars; - int indentInChars; - int actualIndentInChars; - bool useTabs; - bool tabIndents; - bool backspaceUnindents; - - Document(); - virtual ~Document(); - - int AddRef(); - int Release(); - - int LineFromPosition(int pos); - int ClampPositionIntoDocument(int pos); - bool IsCrLf(int pos); - int LenChar(int pos); - int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); - - // Gateways to modifying document - void ModifiedAt(int pos); - bool DeleteChars(int pos, int len); - bool InsertStyledString(int position, char *s, int insertLength); - int Undo(); - int Redo(); - bool CanUndo() { return cb.CanUndo(); } - bool CanRedo() { return cb.CanRedo(); } - void DeleteUndoHistory() { cb.DeleteUndoHistory(); } - bool SetUndoCollection(bool collectUndo) { - return cb.SetUndoCollection(collectUndo); - } - bool IsCollectingUndo() { return cb.IsCollectingUndo(); } - void BeginUndoAction() { cb.BeginUndoAction(); } - void EndUndoAction() { cb.EndUndoAction(); } - void SetSavePoint(); - bool IsSavePoint() { return cb.IsSavePoint(); } - - int GetLineIndentation(int line); - void SetLineIndentation(int line, int indent); - int GetLineIndentPosition(int line); - int GetColumn(int position); - int FindColumn(int line, int column); - void Indent(bool forwards, int lineBottom, int lineTop); - static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode); - void ConvertLineEnds(int eolModeSet); - void SetReadOnly(bool set) { cb.SetReadOnly(set); } - bool IsReadOnly() { return cb.IsReadOnly(); } - - bool InsertChar(int pos, char ch); - bool InsertString(int position, const char *s); - bool InsertString(int position, const char *s, size_t insertLength); - void ChangeChar(int pos, char ch); - void DelChar(int pos); - void DelCharBack(int pos); - - char CharAt(int position) { return cb.CharAt(position); } - void GetCharRange(char *buffer, int position, int lengthRetrieve) { - cb.GetCharRange(buffer, position, lengthRetrieve); - } - char StyleAt(int position) { return cb.StyleAt(position); } - int GetMark(int line) { return cb.GetMark(line); } - int AddMark(int line, int markerNum); - void AddMarkSet(int line, int valueSet); - void DeleteMark(int line, int markerNum); - void DeleteMarkFromHandle(int markerHandle); - void DeleteAllMarks(int markerNum); - int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); } - int LineStart(int line); - int LineEnd(int line); - int LineEndPosition(int position); - int VCHomePosition(int position); - - int SetLevel(int line, int level); - int GetLevel(int line) { return cb.GetLevel(line); } - void ClearLevels() { cb.ClearLevels(); } - int GetLastChild(int lineParent, int level=-1); - int GetFoldParent(int line); - - void Indent(bool forwards); - int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false); - int NextWordStart(int pos, int delta); - int NextWordEnd(int pos, int delta); - int Length() { return cb.Length(); } - void Allocate(int newSize) { cb.Allocate(newSize*2); } - long FindText(int minPos, int maxPos, const char *s, - bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length); - long FindText(int iMessage, unsigned long wParam, long lParam); - const char *SubstituteByPosition(const char *text, int *length); - int LinesTotal(); - - void ChangeCase(Range r, bool makeUpperCase); - - void SetDefaultCharClasses(bool includeWordClass); - void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass); - void SetStylingBits(int bits); - void StartStyling(int position, char mask); - bool SetStyleFor(int length, char style); - bool SetStyles(int length, char *styles); - int GetEndStyled() { return endStyled; } - bool EnsureStyledTo(int pos); - int GetStyleClock() { return styleClock; } - void IncrementStyleClock(); - - int SetLineState(int line, int state) { return cb.SetLineState(line, state); } - int GetLineState(int line) { return cb.GetLineState(line); } - int GetMaxLineState() { return cb.GetMaxLineState(); } - - bool AddWatcher(DocWatcher *watcher, void *userData); - bool RemoveWatcher(DocWatcher *watcher, void *userData); - const WatcherWithUserData *GetWatchers() const { return watchers; } - int GetLenWatchers() const { return lenWatchers; } - - bool IsWordPartSeparator(char ch); - int WordPartLeft(int pos); - int WordPartRight(int pos); - int ExtendStyleRange(int pos, int delta, bool singleLine = false); - bool IsWhiteLine(int line); - int ParaUp(int pos); - int ParaDown(int pos); - int IndentSize() { return actualIndentInChars; } - int BraceMatch(int position, int maxReStyle); + int stylingBits; + int stylingBitsMask; + + int eolMode; + /// Can also be SC_CP_UTF8 to enable UTF-8 mode + int dbcsCodePage; + int tabInChars; + int indentInChars; + int actualIndentInChars; + bool useTabs; + bool tabIndents; + bool backspaceUnindents; + + Document(); + virtual ~Document(); + + int AddRef(); + int Release(); + + int LineFromPosition(int pos); + int ClampPositionIntoDocument(int pos); + bool IsCrLf(int pos); + int LenChar(int pos); + int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); + + // Gateways to modifying document + void ModifiedAt(int pos); + bool DeleteChars(int pos, int len); + bool InsertStyledString(int position, char *s, int insertLength); + int Undo(); + int Redo(); + bool CanUndo() { return cb.CanUndo(); } + bool CanRedo() { return cb.CanRedo(); } + void DeleteUndoHistory() { cb.DeleteUndoHistory(); } + bool SetUndoCollection(bool collectUndo) { + return cb.SetUndoCollection(collectUndo); + } + bool IsCollectingUndo() { return cb.IsCollectingUndo(); } + void BeginUndoAction() { cb.BeginUndoAction(); } + void EndUndoAction() { cb.EndUndoAction(); } + void SetSavePoint(); + bool IsSavePoint() { return cb.IsSavePoint(); } + + int GetLineIndentation(int line); + void SetLineIndentation(int line, int indent); + int GetLineIndentPosition(int line); + int GetColumn(int position); + int FindColumn(int line, int column); + void Indent(bool forwards, int lineBottom, int lineTop); + static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode); + void ConvertLineEnds(int eolModeSet); + void SetReadOnly(bool set) { cb.SetReadOnly(set); } + bool IsReadOnly() { return cb.IsReadOnly(); } + + bool InsertChar(int pos, char ch); + bool InsertString(int position, const char *s); + bool InsertString(int position, const char *s, size_t insertLength); + void ChangeChar(int pos, char ch); + void DelChar(int pos); + void DelCharBack(int pos); + + char CharAt(int position) { return cb.CharAt(position); } + void GetCharRange(char *buffer, int position, int lengthRetrieve) { + cb.GetCharRange(buffer, position, lengthRetrieve); + } + char StyleAt(int position) { return cb.StyleAt(position); } + int GetMark(int line) { return cb.GetMark(line); } + int AddMark(int line, int markerNum); + void AddMarkSet(int line, int valueSet); + void DeleteMark(int line, int markerNum); + void DeleteMarkFromHandle(int markerHandle); + void DeleteAllMarks(int markerNum); + int LineFromHandle(int markerHandle) { return cb.LineFromHandle(markerHandle); } + int LineStart(int line); + int LineEnd(int line); + int LineEndPosition(int position); + int VCHomePosition(int position); + + int SetLevel(int line, int level); + int GetLevel(int line) { return cb.GetLevel(line); } + void ClearLevels() { cb.ClearLevels(); } + int GetLastChild(int lineParent, int level=-1); + int GetFoldParent(int line); + + void Indent(bool forwards); + int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false); + int NextWordStart(int pos, int delta); + int NextWordEnd(int pos, int delta); + int Length() { return cb.Length(); } + void Allocate(int newSize) { cb.Allocate(newSize*2); } + long FindText(int minPos, int maxPos, const char *s, + bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length); + long FindText(int iMessage, unsigned long wParam, long lParam); + const char *SubstituteByPosition(const char *text, int *length); + int LinesTotal(); + + void ChangeCase(Range r, bool makeUpperCase); + + void SetDefaultCharClasses(bool includeWordClass); + void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass); + void SetStylingBits(int bits); + void StartStyling(int position, char mask); + bool SetStyleFor(int length, char style); + bool SetStyles(int length, char *styles); + int GetEndStyled() { return endStyled; } + bool EnsureStyledTo(int pos); + int GetStyleClock() { return styleClock; } + void IncrementStyleClock(); + + int SetLineState(int line, int state) { return cb.SetLineState(line, state); } + int GetLineState(int line) { return cb.GetLineState(line); } + int GetMaxLineState() { return cb.GetMaxLineState(); } + + bool AddWatcher(DocWatcher *watcher, void *userData); + bool RemoveWatcher(DocWatcher *watcher, void *userData); + const WatcherWithUserData *GetWatchers() const { return watchers; } + int GetLenWatchers() const { return lenWatchers; } + + bool IsWordPartSeparator(char ch); + int WordPartLeft(int pos); + int WordPartRight(int pos); + int ExtendStyleRange(int pos, int delta, bool singleLine = false); + bool IsWhiteLine(int line); + int ParaUp(int pos); + int ParaDown(int pos); + int IndentSize() { return actualIndentInChars; } + int BraceMatch(int position, int maxReStyle); private: - void CheckReadOnly(); + void CheckReadOnly(); - CharClassify::cc WordCharClass(unsigned char ch); - bool IsWordStartAt(int pos); - bool IsWordEndAt(int pos); - bool IsWordAt(int start, int end); + CharClassify::cc WordCharClass(unsigned char ch); + bool IsWordStartAt(int pos); + bool IsWordEndAt(int pos); + bool IsWordAt(int start, int end); - void NotifyModifyAttempt(); - void NotifySavePoint(bool atSavePoint); - void NotifyModified(DocModification mh); + void NotifyModifyAttempt(); + void NotifySavePoint(bool atSavePoint); + void NotifyModified(DocModification mh); }; /** @@ -256,35 +256,35 @@ class Document { */ class DocModification { public: - int modificationType; - int position; - int length; - int linesAdded; /**< Negative if lines deleted. */ - const char *text; /**< Only valid for changes to text, not for changes to style. */ - int line; - int foldLevelNow; - int foldLevelPrev; - - DocModification(int modificationType_, int position_=0, int length_=0, - int linesAdded_=0, const char *text_=0, int line_=0) : - modificationType(modificationType_), - position(position_), - length(length_), - linesAdded(linesAdded_), - text(text_), - line(line_), - foldLevelNow(0), - foldLevelPrev(0) {} - - DocModification(int modificationType_, const Action &act, int linesAdded_=0) : - modificationType(modificationType_), - position(act.position), - length(act.lenData), - linesAdded(linesAdded_), - text(act.data), - line(0), - foldLevelNow(0), - foldLevelPrev(0) {} + int modificationType; + int position; + int length; + int linesAdded; /**< Negative if lines deleted. */ + const char *text; /**< Only valid for changes to text, not for changes to style. */ + int line; + int foldLevelNow; + int foldLevelPrev; + + DocModification(int modificationType_, int position_=0, int length_=0, + int linesAdded_=0, const char *text_=0, int line_=0) : + modificationType(modificationType_), + position(position_), + length(length_), + linesAdded(linesAdded_), + text(text_), + line(line_), + foldLevelNow(0), + foldLevelPrev(0) {} + + DocModification(int modificationType_, const Action &act, int linesAdded_=0) : + modificationType(modificationType_), + position(act.position), + length(act.lenData), + linesAdded(linesAdded_), + text(act.data), + line(0), + foldLevelNow(0), + foldLevelPrev(0) {} }; /** @@ -293,13 +293,13 @@ class DocModification { */ class DocWatcher { public: - virtual ~DocWatcher() {} + virtual ~DocWatcher() {} - virtual void NotifyModifyAttempt(Document *doc, void *userData) = 0; - virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0; - virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0; - virtual void NotifyDeleted(Document *doc, void *userData) = 0; - virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0; + virtual void NotifyModifyAttempt(Document *doc, void *userData) = 0; + virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0; + virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0; + virtual void NotifyDeleted(Document *doc, void *userData) = 0; + virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0; }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/DocumentAccessor.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/DocumentAccessor.h index 74065204523..807fa6053c5 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/DocumentAccessor.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/DocumentAccessor.h @@ -11,57 +11,57 @@ class Document; /** */ class DocumentAccessor : public Accessor { - // Private so DocumentAccessor objects can not be copied - DocumentAccessor(const DocumentAccessor &source) : Accessor(), props(source.props) {} - DocumentAccessor &operator=(const DocumentAccessor &) { return *this; } + // Private so DocumentAccessor objects can not be copied + DocumentAccessor(const DocumentAccessor &source) : Accessor(), props(source.props) {} + DocumentAccessor &operator=(const DocumentAccessor &) { return *this; } protected: - Document *pdoc; - PropSet &props; - WindowID id; - int lenDoc; + Document *pdoc; + PropSet &props; + WindowID id; + int lenDoc; - char styleBuf[bufferSize]; - int validLen; - char chFlags; - char chWhile; - unsigned int startSeg; - int startPosStyling; - int mask; + char styleBuf[bufferSize]; + int validLen; + char chFlags; + char chWhile; + unsigned int startSeg; + int startPosStyling; + int mask; - bool InternalIsLeadByte(char ch); - void Fill(int position); + bool InternalIsLeadByte(char ch); + void Fill(int position); public: - DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) : - Accessor(), pdoc(pdoc_), props(props_), id(id_), - lenDoc(-1), validLen(0), chFlags(0), chWhile(0), - startSeg(0), startPosStyling(0), - mask(127) { // Initialize the mask to be big enough for any lexer. - } - ~DocumentAccessor(); - bool Match(int pos, const char *s); - char StyleAt(int position); - int GetLine(int position); - int LineStart(int line); - int LevelAt(int line); - int Length(); - void Flush(); - int GetLineState(int line); - int SetLineState(int line, int state); - int GetPropertyInt(const char *key, int defaultValue=0) { - return props.GetInt(key, defaultValue); - } - char *GetProperties() { - return props.ToString(); - } - WindowID GetWindow() { return id; } + DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) : + Accessor(), pdoc(pdoc_), props(props_), id(id_), + lenDoc(-1), validLen(0), chFlags(0), chWhile(0), + startSeg(0), startPosStyling(0), + mask(127) { // Initialize the mask to be big enough for any lexer. + } + ~DocumentAccessor(); + bool Match(int pos, const char *s); + char StyleAt(int position); + int GetLine(int position); + int LineStart(int line); + int LevelAt(int line); + int Length(); + void Flush(); + int GetLineState(int line); + int SetLineState(int line, int state); + int GetPropertyInt(const char *key, int defaultValue=0) { + return props.GetInt(key, defaultValue); + } + char *GetProperties() { + return props.ToString(); + } + WindowID GetWindow() { return id; } - void StartAt(unsigned int start, char chMask=31); - void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; }; - unsigned int GetStartSegment() { return startSeg; } - void StartSegment(unsigned int pos); - void ColourTo(unsigned int pos, int chAttr); - void SetLevel(int line, int level); - int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); + void StartAt(unsigned int start, char chMask=31); + void SetFlags(char chFlags_, char chWhile_) {chFlags = chFlags_; chWhile = chWhile_; }; + unsigned int GetStartSegment() { return startSeg; } + void StartSegment(unsigned int pos); + void ColourTo(unsigned int pos, int chAttr); + void SetLevel(int line, int level); + int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); }; diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Editor.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Editor.h index 282874be779..2d06048cb6b 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Editor.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Editor.h @@ -12,119 +12,119 @@ */ class Caret { public: - bool active; - bool on; - int period; + bool active; + bool on; + int period; - Caret(); + Caret(); }; /** */ class Timer { public: - bool ticking; - int ticksToWait; - enum {tickSize = 100}; - TickerID tickerID; + bool ticking; + int ticksToWait; + enum {tickSize = 100}; + TickerID tickerID; - Timer(); + Timer(); }; /** */ class Idler { public: - bool state; - IdlerID idlerID; + bool state; + IdlerID idlerID; - Idler(); + Idler(); }; /** */ class LineLayout { private: - friend class LineLayoutCache; - int *lineStarts; - int lenLineStarts; - /// Drawing is only performed for @a maxLineLength characters on each line. - int lineNumber; - bool inCache; + friend class LineLayoutCache; + int *lineStarts; + int lenLineStarts; + /// Drawing is only performed for @a maxLineLength characters on each line. + int lineNumber; + bool inCache; public: - enum { wrapWidthInfinite = 0x7ffffff }; - int maxLineLength; - int numCharsInLine; - enum validLevel { llInvalid, llCheckTextAndStyle, llPositions, llLines } validity; - int xHighlightGuide; - bool highlightColumn; - int selStart; - int selEnd; - bool containsCaret; - int edgeColumn; - char *chars; - unsigned char *styles; - int styleBitsSet; - char *indicators; - int *positions; - char bracePreviousStyles[2]; - - // Hotspot support - int hsStart; - int hsEnd; - - // Wrapped line support - int widthLine; - int lines; - - LineLayout(int maxLineLength_); - virtual ~LineLayout(); - void Resize(int maxLineLength_); - void Free(); - void Invalidate(validLevel validity_); - int LineStart(int line) { - if (line <= 0) { - return 0; - } else if ((line >= lines) || !lineStarts) { - return numCharsInLine; - } else { - return lineStarts[line]; - } - } - void SetLineStart(int line, int start); - void SetBracesHighlight(Range rangeLine, Position braces[], - char bracesMatchStyle, int xHighlight); - void RestoreBracesHighlight(Range rangeLine, Position braces[]); + enum { wrapWidthInfinite = 0x7ffffff }; + int maxLineLength; + int numCharsInLine; + enum validLevel { llInvalid, llCheckTextAndStyle, llPositions, llLines } validity; + int xHighlightGuide; + bool highlightColumn; + int selStart; + int selEnd; + bool containsCaret; + int edgeColumn; + char *chars; + unsigned char *styles; + int styleBitsSet; + char *indicators; + int *positions; + char bracePreviousStyles[2]; + + // Hotspot support + int hsStart; + int hsEnd; + + // Wrapped line support + int widthLine; + int lines; + + LineLayout(int maxLineLength_); + virtual ~LineLayout(); + void Resize(int maxLineLength_); + void Free(); + void Invalidate(validLevel validity_); + int LineStart(int line) { + if (line <= 0) { + return 0; + } else if ((line >= lines) || !lineStarts) { + return numCharsInLine; + } else { + return lineStarts[line]; + } + } + void SetLineStart(int line, int start); + void SetBracesHighlight(Range rangeLine, Position braces[], + char bracesMatchStyle, int xHighlight); + void RestoreBracesHighlight(Range rangeLine, Position braces[]); }; /** */ class LineLayoutCache { - int level; - int length; - int size; - LineLayout **cache; - bool allInvalidated; - int styleClock; - int useCount; - void Allocate(int length_); - void AllocateForLevel(int linesOnScreen, int linesInDoc); + int level; + int length; + int size; + LineLayout **cache; + bool allInvalidated; + int styleClock; + int useCount; + void Allocate(int length_); + void AllocateForLevel(int linesOnScreen, int linesInDoc); public: - LineLayoutCache(); - virtual ~LineLayoutCache(); - void Deallocate(); - enum { - llcNone=SC_CACHE_NONE, - llcCaret=SC_CACHE_CARET, - llcPage=SC_CACHE_PAGE, - llcDocument=SC_CACHE_DOCUMENT - }; - void Invalidate(LineLayout::validLevel validity_); - void SetLevel(int level_); - int GetLevel() { return level; } - LineLayout *Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_, - int linesOnScreen, int linesInDoc); - void Dispose(LineLayout *ll); + LineLayoutCache(); + virtual ~LineLayoutCache(); + void Deallocate(); + enum { + llcNone=SC_CACHE_NONE, + llcCaret=SC_CACHE_CARET, + llcPage=SC_CACHE_PAGE, + llcDocument=SC_CACHE_DOCUMENT + }; + void Invalidate(LineLayout::validLevel validity_); + void SetLevel(int level_); + int GetLevel() { return level; } + LineLayout *Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_, + int linesOnScreen, int linesInDoc); + void Dispose(LineLayout *ll); }; /** @@ -133,411 +133,411 @@ class LineLayoutCache { */ class SelectionText { public: - char *s; - int len; - bool rectangular; - int codePage; - int characterSet; - SelectionText() : s(0), len(0), rectangular(false), codePage(0), characterSet(0) {} - ~SelectionText() { - Free(); - } - void Free() { - Set(0, 0, 0, 0, false); - } - void Set(char *s_, int len_, int codePage_, int characterSet_, bool rectangular_) { - delete []s; - s = s_; - if (s) - len = len_; - else - len = 0; - codePage = codePage_; - characterSet = characterSet_; - rectangular = rectangular_; - } - void Copy(const char *s_, int len_, int codePage_, int characterSet_, bool rectangular_) { - delete []s; - s = new char[len_]; - if (s) { - len = len_; - for (int i = 0; i < len_; i++) { - s[i] = s_[i]; - } - } else { - len = 0; - } - codePage = codePage_; - characterSet = characterSet_; - rectangular = rectangular_; - } - void Copy(const SelectionText &other) { - Copy(other.s, other.len, other.codePage, other.characterSet, other.rectangular); - } + char *s; + int len; + bool rectangular; + int codePage; + int characterSet; + SelectionText() : s(0), len(0), rectangular(false), codePage(0), characterSet(0) {} + ~SelectionText() { + Free(); + } + void Free() { + Set(0, 0, 0, 0, false); + } + void Set(char *s_, int len_, int codePage_, int characterSet_, bool rectangular_) { + delete []s; + s = s_; + if (s) + len = len_; + else + len = 0; + codePage = codePage_; + characterSet = characterSet_; + rectangular = rectangular_; + } + void Copy(const char *s_, int len_, int codePage_, int characterSet_, bool rectangular_) { + delete []s; + s = new char[len_]; + if (s) { + len = len_; + for (int i = 0; i < len_; i++) { + s[i] = s_[i]; + } + } else { + len = 0; + } + codePage = codePage_; + characterSet = characterSet_; + rectangular = rectangular_; + } + void Copy(const SelectionText &other) { + Copy(other.s, other.len, other.codePage, other.characterSet, other.rectangular); + } }; /** */ class Editor : public DocWatcher { - // Private so Editor objects can not be copied - Editor(const Editor &) : DocWatcher() {} - Editor &operator=(const Editor &) { return *this; } - -protected: // ScintillaBase subclass needs access to much of Editor - - /** On GTK+, Scintilla is a container widget holding two scroll bars - * whereas on Windows there is just one window with both scroll bars turned on. */ - Window wMain; ///< The Scintilla parent window - - /** Style resources may be expensive to allocate so are cached between uses. - * When a style attribute is changed, this cache is flushed. */ - bool stylesValid; - ViewStyle vs; - Palette palette; - - int printMagnification; - int printColourMode; - int printWrapState; - int cursorMode; - int controlCharSymbol; - - bool hasFocus; - bool hideSelection; - bool inOverstrike; - int errorStatus; - bool mouseDownCaptures; - - /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to - * the screen. This avoids flashing but is about 30% slower. */ - bool bufferedDraw; - /** In twoPhaseDraw mode, drawing is performed in two phases, first the background - * and then the foreground. This avoids chopping off characters that overlap the next run. */ - bool twoPhaseDraw; - - int xOffset; ///< Horizontal scrolled amount in pixels - int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret - bool horizontalScrollBarVisible; - int scrollWidth; - bool verticalScrollBarVisible; - bool endAtLastLine; - bool caretSticky; - - Surface *pixmapLine; - Surface *pixmapSelMargin; - Surface *pixmapSelPattern; - Surface *pixmapIndentGuide; - Surface *pixmapIndentGuideHighlight; - - LineLayoutCache llc; - - KeyMap kmap; - - Caret caret; - Timer timer; - Timer autoScrollTimer; - enum { autoScrollDelay = 200 }; - - Idler idler; - - Point lastClick; - unsigned int lastClickTime; - int dwellDelay; - int ticksToDwell; - bool dwelling; - enum { selChar, selWord, selLine } selectionType; - Point ptMouseLast; - bool inDragDrop; - bool dropWentOutside; - int posDrag; - int posDrop; - int lastXChosen; - int lineAnchor; - int originalAnchorPos; - int currentPos; - int anchor; - int targetStart; - int targetEnd; - int searchFlags; - int topLine; - int posTopLine; - int lengthForEncode; - - bool needUpdateUI; - Position braces[2]; - int bracesMatchStyle; - int highlightGuideColumn; - - int theEdge; - - enum { notPainting, painting, paintAbandoned } paintState; - PRectangle rcPaint; - bool paintingAllText; - - int modEventMask; - - SelectionText drag; - enum selTypes { noSel, selStream, selRectangle, selLines }; - selTypes selType; - bool moveExtendsSelection; - int xStartSelect; ///< x position of start of rectangular selection - int xEndSelect; ///< x position of end of rectangular selection - bool primarySelection; - - int caretXPolicy; - int caretXSlop; ///< Ensure this many pixels visible on both sides of caret - - int caretYPolicy; - int caretYSlop; ///< Ensure this many lines visible on both sides of caret - - int visiblePolicy; - int visibleSlop; - - int searchAnchor; - - bool recordingMacro; - - int foldFlags; - ContractionState cs; - - // Hotspot support - int hsStart; - int hsEnd; - - // Wrapping support - enum { eWrapNone, eWrapWord, eWrapChar } wrapState; - bool backgroundWrapEnabled; - int wrapWidth; - int docLineLastWrapped; - int docLastLineToWrap; - int wrapVisualFlags; - int wrapVisualFlagsLocation; - int wrapVisualStartIndent; - int actualWrapVisualStartIndent; - - bool convertPastes; - - Document *pdoc; - - Editor(); - virtual ~Editor(); - virtual void Initialise() = 0; - virtual void Finalise(); - - void InvalidateStyleData(); - void InvalidateStyleRedraw(); - virtual void RefreshColourPalette(Palette &pal, bool want); - void RefreshStyleData(); - void DropGraphics(); - - virtual PRectangle GetClientRectangle(); - PRectangle GetTextRectangle(); - - int LinesOnScreen(); - int LinesToScroll(); - int MaxScrollPos(); - Point LocationFromPosition(int pos); - int XFromPosition(int pos); - int PositionFromLocation(Point pt); - int PositionFromLocationClose(Point pt); - int PositionFromLineX(int line, int x); - int LineFromLocation(Point pt); - void SetTopLine(int topLineNew); - - bool AbandonPaint(); - void RedrawRect(PRectangle rc); - void Redraw(); - void RedrawSelMargin(int line=-1); - PRectangle RectangleFromRange(int start, int end); - void InvalidateRange(int start, int end); - - int CurrentPosition(); - bool SelectionEmpty(); - int SelectionStart(); - int SelectionEnd(); - void SetRectangularRange(); - void InvalidateSelection(int currentPos_, int anchor_); - void SetSelection(int currentPos_, int anchor_); - void SetSelection(int currentPos_); - void SetEmptySelection(int currentPos_); - bool RangeContainsProtected(int start, int end) const; - bool SelectionContainsProtected(); - int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); - int MovePositionTo(int newPos, selTypes sel=noSel, bool ensureVisible=true); - int MovePositionSoVisible(int pos, int moveDir); - void SetLastXChosen(); - - void ScrollTo(int line, bool moveThumb=true); - virtual void ScrollText(int linesToMove); - void HorizontalScrollTo(int xPos); - void MoveCaretInsideView(bool ensureVisible=true); - int DisplayFromPosition(int pos); - void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true); - void ShowCaretAtCurrentPosition(); - void DropCaret(); - void InvalidateCaret(); - virtual void UpdateSystemCaret(); - - void NeedWrapping(int docLineStartWrapping = 0, int docLineEndWrapping = 0x7ffffff); - bool WrapLines(bool fullWrap, int priorityWrapLineStart); - void LinesJoin(); - void LinesSplit(int pixelWidth); - - int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault); - void PaintSelMargin(Surface *surface, PRectangle &rc); - LineLayout *RetrieveLineLayout(int lineNumber); - void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll, - int width=LineLayout::wrapWidthInfinite); - ColourAllocated SelectionBackground(ViewStyle &vsDraw); - ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll); - void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight); - void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourAllocated wrapColour); - void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll, - int line, int lineEnd, int xStart, int subLine, int subLineStart, - bool overrideBackground, ColourAllocated background, - bool drawWrapMark, ColourAllocated wrapColour); - void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, - PRectangle rcLine, LineLayout *ll, int subLine=0); - void RefreshPixMaps(Surface *surfaceWindow); - void Paint(Surface *surfaceWindow, PRectangle rcArea); - long FormatRange(bool draw, RangeToFormat *pfr); - int TextWidth(int style, const char *text); - - virtual void SetVerticalScrollPos() = 0; - virtual void SetHorizontalScrollPos() = 0; - virtual bool ModifyScrollBars(int nMax, int nPage) = 0; - virtual void ReconfigureScrollBars(); - void SetScrollBars(); - void ChangeSize(); - - void AddChar(char ch); - virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false); - void ClearSelection(); - void ClearAll(); - void ClearDocumentStyle(); - void Cut(); - void PasteRectangular(int pos, const char *ptr, int len); - virtual void Copy() = 0; - virtual bool CanPaste(); - virtual void Paste() = 0; - void Clear(); - void SelectAll(); - void Undo(); - void Redo(); - void DelChar(); - void DelCharBack(bool allowLineStartDeletion); - virtual void ClaimSelection() = 0; - - virtual void NotifyChange() = 0; - virtual void NotifyFocus(bool focus); - virtual int GetCtrlID() { return ctrlID; } - virtual void NotifyParent(SCNotification scn) = 0; - virtual void NotifyStyleToNeeded(int endStyleNeeded); - void NotifyChar(int ch); - void NotifyMove(int position); - void NotifySavePoint(bool isSavePoint); - void NotifyModifyAttempt(); - virtual void NotifyDoubleClick(Point pt, bool shift); - void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt); - void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt); - void NotifyUpdateUI(); - void NotifyPainted(); - bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); - void NotifyNeedShown(int pos, int len); - void NotifyDwelling(Point pt, bool state); - void NotifyZoom(); - - void NotifyModifyAttempt(Document *document, void *userData); - void NotifySavePoint(Document *document, void *userData, bool atSavePoint); - void CheckModificationForWrap(DocModification mh); - void NotifyModified(Document *document, DocModification mh, void *userData); - void NotifyDeleted(Document *document, void *userData); - void NotifyStyleNeeded(Document *doc, void *userData, int endPos); - void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - - void PageMove(int direction, selTypes sel=noSel, bool stuttered = false); - void ChangeCaseOfSelection(bool makeUpperCase); - void LineTranspose(); - void Duplicate(bool forLine); - virtual void CancelModes(); - void NewLine(); - void CursorUpOrDown(int direction, selTypes sel=noSel); - void ParaUpOrDown(int direction, selTypes sel=noSel); - int StartEndDisplayLine(int pos, bool start); - virtual int KeyCommand(unsigned int iMessage); - virtual int KeyDefault(int /* key */, int /*modifiers*/); - int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0); - - int GetWhitespaceVisible(); - void SetWhitespaceVisible(int view); - - void Indent(bool forwards); - - long FindText(uptr_t wParam, sptr_t lParam); - void SearchAnchor(); - long SearchText(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - long SearchInTarget(const char *text, int length); - void GoToLine(int lineNo); - - virtual void CopyToClipboard(const SelectionText &selectedText) = 0; - char *CopyRange(int start, int end); - void CopySelectionFromRange(SelectionText *ss, int start, int end); - void CopySelectionRange(SelectionText *ss); - void CopyRangeToClipboard(int start, int end); - void CopyText(int length, const char *text); - void SetDragPosition(int newPos); - virtual void DisplayCursor(Window::Cursor c); - virtual void StartDrag(); - void DropAt(int position, const char *value, bool moving, bool rectangular); - /** PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after. - * Before means either before any line of selection or before selection on its line, with a similar meaning to after. */ - int PositionInSelection(int pos); - bool PointInSelection(Point pt); - bool PointInSelMargin(Point pt); - void LineSelection(int lineCurrent_, int lineAnchor_); - void DwellEnd(bool mouseMoved); - virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); - void ButtonMove(Point pt); - void ButtonUp(Point pt, unsigned int curTime, bool ctrl); - - void Tick(); - bool Idle(); - virtual void SetTicking(bool on) = 0; - virtual bool SetIdle(bool) { return false; } - virtual void SetMouseCapture(bool on) = 0; - virtual bool HaveMouseCapture() = 0; - void SetFocusState(bool focusState); - - virtual bool PaintContains(PRectangle rc); - bool PaintContainsMargin(); - void CheckForChangeOutsidePaint(Range r); - void SetBraceHighlight(Position pos0, Position pos1, int matchStyle); - - void SetDocPointer(Document *document); - - void Expand(int &line, bool doExpand); - void ToggleContraction(int line); - void EnsureLineVisible(int lineDoc, bool enforcePolicy); - int ReplaceTarget(bool replacePatterns, const char *text, int length=-1); - - bool PositionIsHotspot(int position); - bool PointIsHotspot(Point pt); - void SetHotSpotRange(Point *pt); - void GetHotSpotRange(int& hsStart, int& hsEnd); - - int CodePage() const; - int WrapCount(int line); - - virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0; + // Private so Editor objects can not be copied + Editor(const Editor &) : DocWatcher() {} + Editor &operator=(const Editor &) { return *this; } + +protected: // ScintillaBase subclass needs access to much of Editor + + /** On GTK+, Scintilla is a container widget holding two scroll bars + * whereas on Windows there is just one window with both scroll bars turned on. */ + Window wMain; ///< The Scintilla parent window + + /** Style resources may be expensive to allocate so are cached between uses. + * When a style attribute is changed, this cache is flushed. */ + bool stylesValid; + ViewStyle vs; + Palette palette; + + int printMagnification; + int printColourMode; + int printWrapState; + int cursorMode; + int controlCharSymbol; + + bool hasFocus; + bool hideSelection; + bool inOverstrike; + int errorStatus; + bool mouseDownCaptures; + + /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to + * the screen. This avoids flashing but is about 30% slower. */ + bool bufferedDraw; + /** In twoPhaseDraw mode, drawing is performed in two phases, first the background + * and then the foreground. This avoids chopping off characters that overlap the next run. */ + bool twoPhaseDraw; + + int xOffset; ///< Horizontal scrolled amount in pixels + int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret + bool horizontalScrollBarVisible; + int scrollWidth; + bool verticalScrollBarVisible; + bool endAtLastLine; + bool caretSticky; + + Surface *pixmapLine; + Surface *pixmapSelMargin; + Surface *pixmapSelPattern; + Surface *pixmapIndentGuide; + Surface *pixmapIndentGuideHighlight; + + LineLayoutCache llc; + + KeyMap kmap; + + Caret caret; + Timer timer; + Timer autoScrollTimer; + enum { autoScrollDelay = 200 }; + + Idler idler; + + Point lastClick; + unsigned int lastClickTime; + int dwellDelay; + int ticksToDwell; + bool dwelling; + enum { selChar, selWord, selLine } selectionType; + Point ptMouseLast; + bool inDragDrop; + bool dropWentOutside; + int posDrag; + int posDrop; + int lastXChosen; + int lineAnchor; + int originalAnchorPos; + int currentPos; + int anchor; + int targetStart; + int targetEnd; + int searchFlags; + int topLine; + int posTopLine; + int lengthForEncode; + + bool needUpdateUI; + Position braces[2]; + int bracesMatchStyle; + int highlightGuideColumn; + + int theEdge; + + enum { notPainting, painting, paintAbandoned } paintState; + PRectangle rcPaint; + bool paintingAllText; + + int modEventMask; + + SelectionText drag; + enum selTypes { noSel, selStream, selRectangle, selLines }; + selTypes selType; + bool moveExtendsSelection; + int xStartSelect; ///< x position of start of rectangular selection + int xEndSelect; ///< x position of end of rectangular selection + bool primarySelection; + + int caretXPolicy; + int caretXSlop; ///< Ensure this many pixels visible on both sides of caret + + int caretYPolicy; + int caretYSlop; ///< Ensure this many lines visible on both sides of caret + + int visiblePolicy; + int visibleSlop; + + int searchAnchor; + + bool recordingMacro; + + int foldFlags; + ContractionState cs; + + // Hotspot support + int hsStart; + int hsEnd; + + // Wrapping support + enum { eWrapNone, eWrapWord, eWrapChar } wrapState; + bool backgroundWrapEnabled; + int wrapWidth; + int docLineLastWrapped; + int docLastLineToWrap; + int wrapVisualFlags; + int wrapVisualFlagsLocation; + int wrapVisualStartIndent; + int actualWrapVisualStartIndent; + + bool convertPastes; + + Document *pdoc; + + Editor(); + virtual ~Editor(); + virtual void Initialise() = 0; + virtual void Finalise(); + + void InvalidateStyleData(); + void InvalidateStyleRedraw(); + virtual void RefreshColourPalette(Palette &pal, bool want); + void RefreshStyleData(); + void DropGraphics(); + + virtual PRectangle GetClientRectangle(); + PRectangle GetTextRectangle(); + + int LinesOnScreen(); + int LinesToScroll(); + int MaxScrollPos(); + Point LocationFromPosition(int pos); + int XFromPosition(int pos); + int PositionFromLocation(Point pt); + int PositionFromLocationClose(Point pt); + int PositionFromLineX(int line, int x); + int LineFromLocation(Point pt); + void SetTopLine(int topLineNew); + + bool AbandonPaint(); + void RedrawRect(PRectangle rc); + void Redraw(); + void RedrawSelMargin(int line=-1); + PRectangle RectangleFromRange(int start, int end); + void InvalidateRange(int start, int end); + + int CurrentPosition(); + bool SelectionEmpty(); + int SelectionStart(); + int SelectionEnd(); + void SetRectangularRange(); + void InvalidateSelection(int currentPos_, int anchor_); + void SetSelection(int currentPos_, int anchor_); + void SetSelection(int currentPos_); + void SetEmptySelection(int currentPos_); + bool RangeContainsProtected(int start, int end) const; + bool SelectionContainsProtected(); + int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true); + int MovePositionTo(int newPos, selTypes sel=noSel, bool ensureVisible=true); + int MovePositionSoVisible(int pos, int moveDir); + void SetLastXChosen(); + + void ScrollTo(int line, bool moveThumb=true); + virtual void ScrollText(int linesToMove); + void HorizontalScrollTo(int xPos); + void MoveCaretInsideView(bool ensureVisible=true); + int DisplayFromPosition(int pos); + void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true); + void ShowCaretAtCurrentPosition(); + void DropCaret(); + void InvalidateCaret(); + virtual void UpdateSystemCaret(); + + void NeedWrapping(int docLineStartWrapping = 0, int docLineEndWrapping = 0x7ffffff); + bool WrapLines(bool fullWrap, int priorityWrapLineStart); + void LinesJoin(); + void LinesSplit(int pixelWidth); + + int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault); + void PaintSelMargin(Surface *surface, PRectangle &rc); + LineLayout *RetrieveLineLayout(int lineNumber); + void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout *ll, + int width=LineLayout::wrapWidthInfinite); + ColourAllocated SelectionBackground(ViewStyle &vsDraw); + ColourAllocated TextBackground(ViewStyle &vsDraw, bool overrideBackground, ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll); + void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight); + void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourAllocated wrapColour); + void DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, LineLayout *ll, + int line, int lineEnd, int xStart, int subLine, int subLineStart, + bool overrideBackground, ColourAllocated background, + bool drawWrapMark, ColourAllocated wrapColour); + void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, + PRectangle rcLine, LineLayout *ll, int subLine=0); + void RefreshPixMaps(Surface *surfaceWindow); + void Paint(Surface *surfaceWindow, PRectangle rcArea); + long FormatRange(bool draw, RangeToFormat *pfr); + int TextWidth(int style, const char *text); + + virtual void SetVerticalScrollPos() = 0; + virtual void SetHorizontalScrollPos() = 0; + virtual bool ModifyScrollBars(int nMax, int nPage) = 0; + virtual void ReconfigureScrollBars(); + void SetScrollBars(); + void ChangeSize(); + + void AddChar(char ch); + virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false); + void ClearSelection(); + void ClearAll(); + void ClearDocumentStyle(); + void Cut(); + void PasteRectangular(int pos, const char *ptr, int len); + virtual void Copy() = 0; + virtual bool CanPaste(); + virtual void Paste() = 0; + void Clear(); + void SelectAll(); + void Undo(); + void Redo(); + void DelChar(); + void DelCharBack(bool allowLineStartDeletion); + virtual void ClaimSelection() = 0; + + virtual void NotifyChange() = 0; + virtual void NotifyFocus(bool focus); + virtual int GetCtrlID() { return ctrlID; } + virtual void NotifyParent(SCNotification scn) = 0; + virtual void NotifyStyleToNeeded(int endStyleNeeded); + void NotifyChar(int ch); + void NotifyMove(int position); + void NotifySavePoint(bool isSavePoint); + void NotifyModifyAttempt(); + virtual void NotifyDoubleClick(Point pt, bool shift); + void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt); + void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt); + void NotifyUpdateUI(); + void NotifyPainted(); + bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); + void NotifyNeedShown(int pos, int len); + void NotifyDwelling(Point pt, bool state); + void NotifyZoom(); + + void NotifyModifyAttempt(Document *document, void *userData); + void NotifySavePoint(Document *document, void *userData, bool atSavePoint); + void CheckModificationForWrap(DocModification mh); + void NotifyModified(Document *document, DocModification mh, void *userData); + void NotifyDeleted(Document *document, void *userData); + void NotifyStyleNeeded(Document *doc, void *userData, int endPos); + void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + + void PageMove(int direction, selTypes sel=noSel, bool stuttered = false); + void ChangeCaseOfSelection(bool makeUpperCase); + void LineTranspose(); + void Duplicate(bool forLine); + virtual void CancelModes(); + void NewLine(); + void CursorUpOrDown(int direction, selTypes sel=noSel); + void ParaUpOrDown(int direction, selTypes sel=noSel); + int StartEndDisplayLine(int pos, bool start); + virtual int KeyCommand(unsigned int iMessage); + virtual int KeyDefault(int /* key */, int /*modifiers*/); + int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0); + + int GetWhitespaceVisible(); + void SetWhitespaceVisible(int view); + + void Indent(bool forwards); + + long FindText(uptr_t wParam, sptr_t lParam); + void SearchAnchor(); + long SearchText(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + long SearchInTarget(const char *text, int length); + void GoToLine(int lineNo); + + virtual void CopyToClipboard(const SelectionText &selectedText) = 0; + char *CopyRange(int start, int end); + void CopySelectionFromRange(SelectionText *ss, int start, int end); + void CopySelectionRange(SelectionText *ss); + void CopyRangeToClipboard(int start, int end); + void CopyText(int length, const char *text); + void SetDragPosition(int newPos); + virtual void DisplayCursor(Window::Cursor c); + virtual void StartDrag(); + void DropAt(int position, const char *value, bool moving, bool rectangular); + /** PositionInSelection returns 0 if position in selection, -1 if position before selection, and 1 if after. + * Before means either before any line of selection or before selection on its line, with a similar meaning to after. */ + int PositionInSelection(int pos); + bool PointInSelection(Point pt); + bool PointInSelMargin(Point pt); + void LineSelection(int lineCurrent_, int lineAnchor_); + void DwellEnd(bool mouseMoved); + virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); + void ButtonMove(Point pt); + void ButtonUp(Point pt, unsigned int curTime, bool ctrl); + + void Tick(); + bool Idle(); + virtual void SetTicking(bool on) = 0; + virtual bool SetIdle(bool) { return false; } + virtual void SetMouseCapture(bool on) = 0; + virtual bool HaveMouseCapture() = 0; + void SetFocusState(bool focusState); + + virtual bool PaintContains(PRectangle rc); + bool PaintContainsMargin(); + void CheckForChangeOutsidePaint(Range r); + void SetBraceHighlight(Position pos0, Position pos1, int matchStyle); + + void SetDocPointer(Document *document); + + void Expand(int &line, bool doExpand); + void ToggleContraction(int line); + void EnsureLineVisible(int lineDoc, bool enforcePolicy); + int ReplaceTarget(bool replacePatterns, const char *text, int length=-1); + + bool PositionIsHotspot(int position); + bool PointIsHotspot(Point pt); + void SetHotSpotRange(Point *pt); + void GetHotSpotRange(int& hsStart, int& hsEnd); + + int CodePage() const; + int WrapCount(int line); + + virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0; public: - // Public so the COM thunks can access it. - bool IsUnicodeMode() const; - // Public so scintilla_send_message can use it. - virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - // Public so scintilla_set_id can use it. - int ctrlID; - friend class AutoSurface; - friend class SelectionLineIterator; + // Public so the COM thunks can access it. + bool IsUnicodeMode() const; + // Public so scintilla_send_message can use it. + virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + // Public so scintilla_set_id can use it. + int ctrlID; + friend class AutoSurface; + friend class SelectionLineIterator; }; /** @@ -545,37 +545,37 @@ class Editor : public DocWatcher { */ class AutoSurface { private: - Surface *surf; + Surface *surf; public: - AutoSurface(Editor *ed) : surf(0) { - if (ed->wMain.GetID()) { - surf = Surface::Allocate(); - if (surf) { - surf->Init(ed->wMain.GetID()); - surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); - surf->SetDBCSMode(ed->CodePage()); - } - } - } - AutoSurface(SurfaceID sid, Editor *ed) : surf(0) { - if (ed->wMain.GetID()) { - surf = Surface::Allocate(); - if (surf) { - surf->Init(sid, ed->wMain.GetID()); - surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); - surf->SetDBCSMode(ed->CodePage()); - } - } - } - ~AutoSurface() { - delete surf; - } - Surface *operator->() const { - return surf; - } - operator Surface *() const { - return surf; - } + AutoSurface(Editor *ed) : surf(0) { + if (ed->wMain.GetID()) { + surf = Surface::Allocate(); + if (surf) { + surf->Init(ed->wMain.GetID()); + surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); + surf->SetDBCSMode(ed->CodePage()); + } + } + } + AutoSurface(SurfaceID sid, Editor *ed) : surf(0) { + if (ed->wMain.GetID()) { + surf = Surface::Allocate(); + if (surf) { + surf->Init(sid, ed->wMain.GetID()); + surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); + surf->SetDBCSMode(ed->CodePage()); + } + } + } + ~AutoSurface() { + delete surf; + } + Surface *operator->() const { + return surf; + } + operator Surface *() const { + return surf; + } }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ExternalLexer.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ExternalLexer.h index 76cd5938efd..744dace115d 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ExternalLexer.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ExternalLexer.h @@ -28,68 +28,68 @@ typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, in /// Sub-class of LexerModule to use an external lexer. class ExternalLexerModule : protected LexerModule { protected: - ExtLexerFunction fneLexer; - ExtFoldFunction fneFolder; - int externalLanguage; - char name[100]; + ExtLexerFunction fneLexer; + ExtFoldFunction fneFolder; + int externalLanguage; + char name[100]; public: - ExternalLexerModule(int language_, LexerFunction fnLexer_, - const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_){ - strncpy(name, languageName_, sizeof(name)); - languageName = name; - }; - virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle, - WordList *keywordlists[], Accessor &styler) const; - virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle, - WordList *keywordlists[], Accessor &styler) const; - virtual void SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index); + ExternalLexerModule(int language_, LexerFunction fnLexer_, + const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_){ + strncpy(name, languageName_, sizeof(name)); + languageName = name; + }; + virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle, + WordList *keywordlists[], Accessor &styler) const; + virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle, + WordList *keywordlists[], Accessor &styler) const; + virtual void SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index); }; /// LexerMinder points to an ExternalLexerModule - so we don't leak them. class LexerMinder { public: - ExternalLexerModule *self; - LexerMinder *next; + ExternalLexerModule *self; + LexerMinder *next; }; /// LexerLibrary exists for every External Lexer DLL, contains LexerMinders. class LexerLibrary { - DynamicLibrary *lib; - LexerMinder *first; - LexerMinder *last; + DynamicLibrary *lib; + LexerMinder *first; + LexerMinder *last; public: - LexerLibrary(const char* ModuleName); - ~LexerLibrary(); - void Release(); - - LexerLibrary *next; - SString m_sModuleName; + LexerLibrary(const char* ModuleName); + ~LexerLibrary(); + void Release(); + + LexerLibrary *next; + SString m_sModuleName; }; /// LexerManager manages external lexers, contains LexerLibrarys. class LexerManager { public: - ~LexerManager(); - - static LexerManager *GetInstance(); - static void DeleteInstance(); - - void Load(const char* path); - void Clear(); + ~LexerManager(); + + static LexerManager *GetInstance(); + static void DeleteInstance(); + + void Load(const char* path); + void Clear(); private: - LexerManager(); - static LexerManager *theInstance; + LexerManager(); + static LexerManager *theInstance; - void LoadLexerLibrary(const char* module); - LexerLibrary *first; - LexerLibrary *last; + void LoadLexerLibrary(const char* module); + LexerLibrary *first; + LexerLibrary *last; }; class LMMinder { public: - ~LMMinder(); + ~LMMinder(); }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Indicator.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Indicator.h index 716db1051fe..d9d344127e9 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Indicator.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Indicator.h @@ -12,11 +12,11 @@ */ class Indicator { public: - int style; - ColourPair fore; - Indicator() : style(INDIC_PLAIN), fore(ColourDesired(0,0,0)) { - } - void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine); + int style; + ColourPair fore; + Indicator() : style(INDIC_PLAIN), fore(ColourDesired(0,0,0)) { + } + void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine); }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/KeyMap.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/KeyMap.h index 364df684f61..c73b1c7a8eb 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/KeyMap.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/KeyMap.h @@ -19,25 +19,25 @@ */ class KeyToCommand { public: - int key; - int modifiers; - unsigned int msg; + int key; + int modifiers; + unsigned int msg; }; /** */ class KeyMap { - KeyToCommand *kmap; - int len; - int alloc; - static const KeyToCommand MapDefault[]; + KeyToCommand *kmap; + int len; + int alloc; + static const KeyToCommand MapDefault[]; public: - KeyMap(); - ~KeyMap(); - void Clear(); - void AssignCmdKey(int key, int modifiers, unsigned int msg); - unsigned int Find(int key, int modifiers); // 0 returned on failure + KeyMap(); + ~KeyMap(); + void Clear(); + void AssignCmdKey(int key, int modifiers, unsigned int msg); + unsigned int Find(int key, int modifiers); // 0 returned on failure }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/LineMarker.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/LineMarker.h index 8ebdce49183..1cfd883d97a 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/LineMarker.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/LineMarker.h @@ -12,43 +12,43 @@ */ class LineMarker { public: - int markType; - ColourPair fore; - ColourPair back; - int alpha; - XPM *pxpm; - LineMarker() { - markType = SC_MARK_CIRCLE; - fore = ColourDesired(0,0,0); - back = ColourDesired(0xff,0xff,0xff); - alpha = SC_ALPHA_NOALPHA; - pxpm = NULL; - } - LineMarker(const LineMarker &) { - // Defined to avoid pxpm being blindly copied, not as real copy constructor - markType = SC_MARK_CIRCLE; - fore = ColourDesired(0,0,0); - back = ColourDesired(0xff,0xff,0xff); - alpha = SC_ALPHA_NOALPHA; - pxpm = NULL; - } - ~LineMarker() { - delete pxpm; - } - LineMarker &operator=(const LineMarker &) { - // Defined to avoid pxpm being blindly copied, not as real assignment operator - markType = SC_MARK_CIRCLE; - fore = ColourDesired(0,0,0); - back = ColourDesired(0xff,0xff,0xff); - alpha = SC_ALPHA_NOALPHA; - delete pxpm; - pxpm = NULL; - return *this; - } - void RefreshColourPalette(Palette &pal, bool want); - void SetXPM(const char *textForm); - void SetXPM(const char * const *linesForm); - void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter); + int markType; + ColourPair fore; + ColourPair back; + int alpha; + XPM *pxpm; + LineMarker() { + markType = SC_MARK_CIRCLE; + fore = ColourDesired(0,0,0); + back = ColourDesired(0xff,0xff,0xff); + alpha = SC_ALPHA_NOALPHA; + pxpm = NULL; + } + LineMarker(const LineMarker &) { + // Defined to avoid pxpm being blindly copied, not as real copy constructor + markType = SC_MARK_CIRCLE; + fore = ColourDesired(0,0,0); + back = ColourDesired(0xff,0xff,0xff); + alpha = SC_ALPHA_NOALPHA; + pxpm = NULL; + } + ~LineMarker() { + delete pxpm; + } + LineMarker &operator=(const LineMarker &) { + // Defined to avoid pxpm being blindly copied, not as real assignment operator + markType = SC_MARK_CIRCLE; + fore = ColourDesired(0,0,0); + back = ColourDesired(0xff,0xff,0xff); + alpha = SC_ALPHA_NOALPHA; + delete pxpm; + pxpm = NULL; + return *this; + } + void RefreshColourPalette(Palette &pal, bool want); + void SetXPM(const char *textForm); + void SetXPM(const char * const *linesForm); + void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter); }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/RESearch.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/RESearch.h index aa855791842..953b53ac11e 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/RESearch.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/RESearch.h @@ -13,53 +13,53 @@ * The following defines are not meant to be changeable. * They are for readability only. */ -#define MAXCHR 256 -#define CHRBIT 8 -#define BITBLK MAXCHR/CHRBIT +#define MAXCHR 256 +#define CHRBIT 8 +#define BITBLK MAXCHR/CHRBIT class CharacterIndexer { public: - virtual char CharAt(int index)=0; - virtual ~CharacterIndexer() { - } + virtual char CharAt(int index)=0; + virtual ~CharacterIndexer() { + } }; class RESearch { public: - RESearch(CharClassify *charClassTable); - ~RESearch(); - bool GrabMatches(CharacterIndexer &ci); - const char *Compile(const char *pat, int length, bool caseSensitive, bool posix); - int Execute(CharacterIndexer &ci, int lp, int endp); - int Substitute(CharacterIndexer &ci, char *src, char *dst); + RESearch(CharClassify *charClassTable); + ~RESearch(); + bool GrabMatches(CharacterIndexer &ci); + const char *Compile(const char *pat, int length, bool caseSensitive, bool posix); + int Execute(CharacterIndexer &ci, int lp, int endp); + int Substitute(CharacterIndexer &ci, char *src, char *dst); - enum {MAXTAG=10}; - enum {MAXNFA=2048}; - enum {NOTFOUND=-1}; + enum {MAXTAG=10}; + enum {MAXNFA=2048}; + enum {NOTFOUND=-1}; - int bopat[MAXTAG]; - int eopat[MAXTAG]; - char *pat[MAXTAG]; + int bopat[MAXTAG]; + int eopat[MAXTAG]; + char *pat[MAXTAG]; private: - void Init(); - void Clear(); - void ChSet(char c); - void ChSetWithCase(char c, bool caseSensitive); + void Init(); + void Clear(); + void ChSet(char c); + void ChSetWithCase(char c, bool caseSensitive); - int PMatch(CharacterIndexer &ci, int lp, int endp, char *ap); + int PMatch(CharacterIndexer &ci, int lp, int endp, char *ap); - int bol; - int tagstk[MAXTAG]; /* subpat tag stack */ - char nfa[MAXNFA]; /* automaton */ - int sta; - char bittab[BITBLK]; /* bit table for CCL pre-set bits */ - int failure; - CharClassify *charClass; - bool iswordc(unsigned char x) { - return charClass->IsWord(x); - } + int bol; + int tagstk[MAXTAG]; /* subpat tag stack */ + char nfa[MAXNFA]; /* automaton */ + int sta; + char bittab[BITBLK]; /* bit table for CCL pre-set bits */ + int failure; + CharClassify *charClass; + bool iswordc(unsigned char x) { + return charClass->IsWord(x); + } }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/SVector.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/SVector.h index c8edb513bc3..4b02cb6f8c6 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/SVector.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/SVector.h @@ -14,114 +14,114 @@ * This makes it very lightweight unless used so is a good match for optional features. */ class SVector { - enum { allocSize = 4000 }; - - int *v; ///< The vector - unsigned int size; ///< Number of elements allocated - unsigned int len; ///< Number of elements used in vector - bool allocFailure; ///< A memory allocation call has failed - - /** Internally allocate more elements than the user wants - * to avoid thrashing the memory allocator. */ - void SizeTo(int newSize) { - if (newSize < allocSize) - newSize += allocSize; - else - newSize = (newSize * 3) / 2; - int* newv = new int[newSize]; - if (!newv) { - allocFailure = true; - return; - } - size = newSize; - unsigned int i=0; - for (; i 0) { - SizeTo(other.Length()); - if (!allocFailure) { - for (int i=0;i 0) { - SizeTo(other.Length()); - if (!allocFailure) { - for (int i=0;i= len) { - if (i >= size) { - SizeTo(i); - } - len = i+1; - } - return v[i]; - } - /// Reset vector. - void Free() { - delete []v; - v = 0; - size = 0; - len = 0; - } - /** @brief Grow vector size. - * Doesn't allow a vector to be shrinked. */ - void SetLength(unsigned int newLength) { - if (newLength > len) { - if (newLength >= size) { - SizeTo(newLength); - } - } - len = newLength; - } - /// Get the current length (number of used elements) of the vector. - int Length() const { - return len; - } + SVector() { + allocFailure = false; + v = 0; + len = 0; + size = 0; + } + ~SVector() { + Free(); + } + /// Constructor from another vector. + SVector(const SVector &other) { + allocFailure = false; + v = 0; + len = 0; + size = 0; + if (other.Length() > 0) { + SizeTo(other.Length()); + if (!allocFailure) { + for (int i=0;i 0) { + SizeTo(other.Length()); + if (!allocFailure) { + for (int i=0;i= len) { + if (i >= size) { + SizeTo(i); + } + len = i+1; + } + return v[i]; + } + /// Reset vector. + void Free() { + delete []v; + v = 0; + size = 0; + len = 0; + } + /** @brief Grow vector size. + * Doesn't allow a vector to be shrinked. */ + void SetLength(unsigned int newLength) { + if (newLength > len) { + if (newLength >= size) { + SizeTo(newLength); + } + } + len = newLength; + } + /// Get the current length (number of used elements) of the vector. + int Length() const { + return len; + } }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ScintillaBase.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ScintillaBase.h index cb85b55b511..82f622b00f4 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ScintillaBase.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ScintillaBase.h @@ -11,83 +11,83 @@ /** */ class ScintillaBase : public Editor { - // Private so ScintillaBase objects can not be copied - ScintillaBase(const ScintillaBase &) : Editor() {} - ScintillaBase &operator=(const ScintillaBase &) { return *this; } + // Private so ScintillaBase objects can not be copied + ScintillaBase(const ScintillaBase &) : Editor() {} + ScintillaBase &operator=(const ScintillaBase &) { return *this; } protected: - /** Enumeration of commands and child windows. */ - enum { - idCallTip=1, - idAutoComplete=2, + /** Enumeration of commands and child windows. */ + enum { + idCallTip=1, + idAutoComplete=2, - idcmdUndo=10, - idcmdRedo=11, - idcmdCut=12, - idcmdCopy=13, - idcmdPaste=14, - idcmdDelete=15, - idcmdSelectAll=16 - }; + idcmdUndo=10, + idcmdRedo=11, + idcmdCut=12, + idcmdCopy=13, + idcmdPaste=14, + idcmdDelete=15, + idcmdSelectAll=16 + }; - bool displayPopupMenu; - Menu popup; - AutoComplete ac; + bool displayPopupMenu; + Menu popup; + AutoComplete ac; - CallTip ct; + CallTip ct; - int listType; ///< 0 is an autocomplete list - SString listSelected; ///< Receives listbox selected string - int maxListWidth; /// Maximum width of list, in average character widths + int listType; ///< 0 is an autocomplete list + SString listSelected; ///< Receives listbox selected string + int maxListWidth; /// Maximum width of list, in average character widths - bool performingStyle; ///< Prevent reentrance + bool performingStyle; ///< Prevent reentrance #ifdef SCI_LEXER - int lexLanguage; - const LexerModule *lexCurrent; - PropSet props; - enum {numWordLists=KEYWORDSET_MAX+1}; - WordList *keyWordLists[numWordLists+1]; - void SetLexer(uptr_t wParam); - void SetLexerLanguage(const char *languageName); - void Colourise(int start, int end); + int lexLanguage; + const LexerModule *lexCurrent; + PropSet props; + enum {numWordLists=KEYWORDSET_MAX+1}; + WordList *keyWordLists[numWordLists+1]; + void SetLexer(uptr_t wParam); + void SetLexerLanguage(const char *languageName); + void Colourise(int start, int end); #endif - ScintillaBase(); - virtual ~ScintillaBase(); - virtual void Initialise() = 0; - virtual void Finalise() = 0; + ScintillaBase(); + virtual ~ScintillaBase(); + virtual void Initialise() = 0; + virtual void Finalise() = 0; - virtual void RefreshColourPalette(Palette &pal, bool want); + virtual void RefreshColourPalette(Palette &pal, bool want); - virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false); - void Command(int cmdId); - virtual void CancelModes(); - virtual int KeyCommand(unsigned int iMessage); + virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false); + void Command(int cmdId); + virtual void CancelModes(); + virtual int KeyCommand(unsigned int iMessage); - void AutoCompleteStart(int lenEntered, const char *list); - void AutoCompleteCancel(); - void AutoCompleteMove(int delta); - int AutoCompleteGetCurrent(); - void AutoCompleteCharacterAdded(char ch); - void AutoCompleteCharacterDeleted(); - void AutoCompleteCompleted(); - void AutoCompleteMoveToCurrentWord(); - static void AutoCompleteDoubleClick(void* p); + void AutoCompleteStart(int lenEntered, const char *list); + void AutoCompleteCancel(); + void AutoCompleteMove(int delta); + int AutoCompleteGetCurrent(); + void AutoCompleteCharacterAdded(char ch); + void AutoCompleteCharacterDeleted(); + void AutoCompleteCompleted(); + void AutoCompleteMoveToCurrentWord(); + static void AutoCompleteDoubleClick(void* p); - void CallTipClick(); - void CallTipShow(Point pt, const char *defn); - virtual void CreateCallTipWindow(PRectangle rc) = 0; + void CallTipClick(); + void CallTipShow(Point pt, const char *defn); + virtual void CreateCallTipWindow(PRectangle rc) = 0; - virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0; - void ContextMenu(Point pt); + virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0; + void ContextMenu(Point pt); - virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); + virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); - virtual void NotifyStyleToNeeded(int endStyleNeeded); + virtual void NotifyStyleToNeeded(int endStyleNeeded); public: - // Public so scintilla_send_message can use it - virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); + // Public so scintilla_send_message can use it + virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Style.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Style.h index c0f7eca266a..a1a5cc7a46f 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Style.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/Style.h @@ -12,45 +12,45 @@ */ class Style { public: - ColourPair fore; - ColourPair back; - bool aliasOfDefaultFont; - bool bold; - bool italic; - int size; - const char *fontName; - int characterSet; - bool eolFilled; - bool underline; - enum ecaseForced {caseMixed, caseUpper, caseLower}; - ecaseForced caseForce; - bool visible; - bool changeable; - bool hotspot; + ColourPair fore; + ColourPair back; + bool aliasOfDefaultFont; + bool bold; + bool italic; + int size; + const char *fontName; + int characterSet; + bool eolFilled; + bool underline; + enum ecaseForced {caseMixed, caseUpper, caseLower}; + ecaseForced caseForce; + bool visible; + bool changeable; + bool hotspot; - Font font; - int sizeZoomed; - unsigned int lineHeight; - unsigned int ascent; - unsigned int descent; - unsigned int externalLeading; - unsigned int aveCharWidth; - unsigned int spaceWidth; + Font font; + int sizeZoomed; + unsigned int lineHeight; + unsigned int ascent; + unsigned int descent; + unsigned int externalLeading; + unsigned int aveCharWidth; + unsigned int spaceWidth; - Style(); - Style(const Style &source); - ~Style(); - Style &operator=(const Style &source); - void Clear(ColourDesired fore_, ColourDesired back_, - int size_, - const char *fontName_, int characterSet_, - bool bold_, bool italic_, bool eolFilled_, - bool underline_, ecaseForced caseForce_, - bool visible_, bool changeable_, bool hotspot_); - void ClearTo(const Style &source); - bool EquivalentFontTo(const Style *other) const; - void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, bool extraFontFlag = false); - bool IsProtected() const { return !(changeable && visible);}; + Style(); + Style(const Style &source); + ~Style(); + Style &operator=(const Style &source); + void Clear(ColourDesired fore_, ColourDesired back_, + int size_, + const char *fontName_, int characterSet_, + bool bold_, bool italic_, bool eolFilled_, + bool underline_, ecaseForced caseForce_, + bool visible_, bool changeable_, bool hotspot_); + void ClearTo(const Style &source); + bool EquivalentFontTo(const Style *other) const; + void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, bool extraFontFlag = false); + bool IsProtected() const { return !(changeable && visible);}; }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/StyleContext.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/StyleContext.h index 36b50f9142f..7e66f3ca064 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/StyleContext.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/StyleContext.h @@ -10,140 +10,140 @@ // DBCS treated specially as the second character can be < 0x80 and hence // syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80 class StyleContext { - Accessor &styler; - unsigned int endPos; - StyleContext& operator=(const StyleContext&) { - return *this; - } - void GetNextChar(unsigned int pos) { - chNext = static_cast(styler.SafeGetCharAt(pos+1)); - if (styler.IsLeadByte(static_cast(chNext))) { - chNext = chNext << 8; - chNext |= static_cast(styler.SafeGetCharAt(pos+2)); - } - // End of line? - // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) - // or on LF alone (Unix). Avoid triggering two times on Dos/Win. - atLineEnd = (ch == '\r' && chNext != '\n') || - (ch == '\n') || - (currentPos >= endPos); - } + Accessor &styler; + unsigned int endPos; + StyleContext& operator=(const StyleContext&) { + return *this; + } + void GetNextChar(unsigned int pos) { + chNext = static_cast(styler.SafeGetCharAt(pos+1)); + if (styler.IsLeadByte(static_cast(chNext))) { + chNext = chNext << 8; + chNext |= static_cast(styler.SafeGetCharAt(pos+2)); + } + // End of line? + // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) + // or on LF alone (Unix). Avoid triggering two times on Dos/Win. + atLineEnd = (ch == '\r' && chNext != '\n') || + (ch == '\n') || + (currentPos >= endPos); + } public: - unsigned int currentPos; - bool atLineStart; - bool atLineEnd; - int state; - int chPrev; - int ch; - int chNext; + unsigned int currentPos; + bool atLineStart; + bool atLineEnd; + int state; + int chPrev; + int ch; + int chNext; - StyleContext(unsigned int startPos, unsigned int length, + StyleContext(unsigned int startPos, unsigned int length, int initStyle, Accessor &styler_, char chMask=31) : - styler(styler_), - endPos(startPos + length), - currentPos(startPos), - atLineStart(true), - atLineEnd(false), - state(initStyle & chMask), // Mask off all bits which aren't in the chMask. - chPrev(0), - ch(0), - chNext(0) { - styler.StartAt(startPos, chMask); - styler.StartSegment(startPos); - unsigned int pos = currentPos; - ch = static_cast(styler.SafeGetCharAt(pos)); - if (styler.IsLeadByte(static_cast(ch))) { - pos++; - ch = ch << 8; - ch |= static_cast(styler.SafeGetCharAt(pos)); - } - GetNextChar(pos); - } - void Complete() { - styler.ColourTo(currentPos - 1, state); - } - bool More() { - return currentPos < endPos; - } - void Forward() { - if (currentPos < endPos) { - atLineStart = atLineEnd; - chPrev = ch; - currentPos++; - if (ch >= 0x100) - currentPos++; - ch = chNext; - GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0)); - } else { - atLineStart = false; - chPrev = ' '; - ch = ' '; - chNext = ' '; - atLineEnd = true; - } - } - void Forward(int nb) { - for (int i = 0; i < nb; i++) { - Forward(); - } - } - void ChangeState(int state_) { - state = state_; - } - void SetState(int state_) { - styler.ColourTo(currentPos - 1, state); - state = state_; - } - void ForwardSetState(int state_) { - Forward(); - styler.ColourTo(currentPos - 1, state); - state = state_; - } - int LengthCurrent() { - return currentPos - styler.GetStartSegment(); - } - int GetRelative(int n) { - return static_cast(styler.SafeGetCharAt(currentPos+n)); - } - bool Match(char ch0) { - return ch == ch0; - } - bool Match(char ch0, char ch1) { - return (ch == ch0) && (chNext == ch1); - } - bool Match(const char *s) { - if (ch != *s) - return false; - s++; - if (chNext != *s) - return false; - s++; - for (int n=2; *s; n++) { - if (*s != styler.SafeGetCharAt(currentPos+n)) - return false; - s++; - } - return true; - } - bool MatchIgnoreCase(const char *s) { - if (tolower(ch) != *s) - return false; - s++; - if (tolower(chNext) != *s) - return false; - s++; - for (int n=2; *s; n++) { - if (*s != - tolower(static_cast(styler.SafeGetCharAt(currentPos+n)))) - return false; - s++; - } - return true; - } - // Non-inline - void GetCurrent(char *s, unsigned int len); - void GetCurrentLowered(char *s, unsigned int len); + styler(styler_), + endPos(startPos + length), + currentPos(startPos), + atLineStart(true), + atLineEnd(false), + state(initStyle & chMask), // Mask off all bits which aren't in the chMask. + chPrev(0), + ch(0), + chNext(0) { + styler.StartAt(startPos, chMask); + styler.StartSegment(startPos); + unsigned int pos = currentPos; + ch = static_cast(styler.SafeGetCharAt(pos)); + if (styler.IsLeadByte(static_cast(ch))) { + pos++; + ch = ch << 8; + ch |= static_cast(styler.SafeGetCharAt(pos)); + } + GetNextChar(pos); + } + void Complete() { + styler.ColourTo(currentPos - 1, state); + } + bool More() { + return currentPos < endPos; + } + void Forward() { + if (currentPos < endPos) { + atLineStart = atLineEnd; + chPrev = ch; + currentPos++; + if (ch >= 0x100) + currentPos++; + ch = chNext; + GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0)); + } else { + atLineStart = false; + chPrev = ' '; + ch = ' '; + chNext = ' '; + atLineEnd = true; + } + } + void Forward(int nb) { + for (int i = 0; i < nb; i++) { + Forward(); + } + } + void ChangeState(int state_) { + state = state_; + } + void SetState(int state_) { + styler.ColourTo(currentPos - 1, state); + state = state_; + } + void ForwardSetState(int state_) { + Forward(); + styler.ColourTo(currentPos - 1, state); + state = state_; + } + int LengthCurrent() { + return currentPos - styler.GetStartSegment(); + } + int GetRelative(int n) { + return static_cast(styler.SafeGetCharAt(currentPos+n)); + } + bool Match(char ch0) { + return ch == ch0; + } + bool Match(char ch0, char ch1) { + return (ch == ch0) && (chNext == ch1); + } + bool Match(const char *s) { + if (ch != *s) + return false; + s++; + if (chNext != *s) + return false; + s++; + for (int n=2; *s; n++) { + if (*s != styler.SafeGetCharAt(currentPos+n)) + return false; + s++; + } + return true; + } + bool MatchIgnoreCase(const char *s) { + if (tolower(ch) != *s) + return false; + s++; + if (tolower(chNext) != *s) + return false; + s++; + for (int n=2; *s; n++) { + if (*s != + tolower(static_cast(styler.SafeGetCharAt(currentPos+n)))) + return false; + s++; + } + return true; + } + // Non-inline + void GetCurrent(char *s, unsigned int len); + void GetCurrentLowered(char *s, unsigned int len); }; inline bool IsASpace(unsigned int ch) { @@ -151,19 +151,19 @@ inline bool IsASpace(unsigned int ch) { } inline bool IsASpaceOrTab(unsigned int ch) { - return (ch == ' ') || (ch == '\t'); + return (ch == ' ') || (ch == '\t'); } inline bool IsADigit(unsigned int ch) { - return (ch >= '0') && (ch <= '9'); + return (ch >= '0') && (ch <= '9'); } inline bool IsADigit(unsigned int ch, unsigned int base) { - if (base <= 10) { - return (ch >= '0') && (ch < '0' + base); - } else { - return ((ch >= '0') && (ch <= '9')) || - ((ch >= 'A') && (ch < 'A' + base - 10)) || - ((ch >= 'a') && (ch < 'a' + base - 10)); - } + if (base <= 10) { + return (ch >= '0') && (ch < '0' + base); + } else { + return ((ch >= '0') && (ch <= '9')) || + ((ch >= 'A') && (ch < 'A' + base - 10)) || + ((ch >= 'a') && (ch < 'a' + base - 10)); + } } diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ViewStyle.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ViewStyle.h index 892fdc59d06..8542eee0550 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ViewStyle.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/ViewStyle.h @@ -12,25 +12,25 @@ */ class MarginStyle { public: - bool symbol; - int width; - int mask; - bool sensitive; - MarginStyle(); + bool symbol; + int width; + int mask; + bool sensitive; + MarginStyle(); }; /** */ class FontNames { private: - char *names[STYLE_MAX + 1]; - int max; + char *names[STYLE_MAX + 1]; + int max; public: - FontNames(); - ~FontNames(); - void Clear(); - const char *Save(const char *name); + FontNames(); + ~FontNames(); + void Clear(); + const char *Save(const char *name); }; enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2}; @@ -39,70 +39,70 @@ enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterInden */ class ViewStyle { public: - FontNames fontNames; - Style styles[STYLE_MAX + 1]; - LineMarker markers[MARKER_MAX + 1]; - Indicator indicators[INDIC_MAX + 1]; - int lineHeight; - unsigned int maxAscent; - unsigned int maxDescent; - unsigned int aveCharWidth; - unsigned int spaceWidth; - bool selforeset; - ColourPair selforeground; - bool selbackset; - ColourPair selbackground; - ColourPair selbackground2; - int selAlpha; - bool whitespaceForegroundSet; - ColourPair whitespaceForeground; - bool whitespaceBackgroundSet; - ColourPair whitespaceBackground; - ColourPair selbar; - ColourPair selbarlight; - bool foldmarginColourSet; - ColourPair foldmarginColour; - bool foldmarginHighlightColourSet; - ColourPair foldmarginHighlightColour; - bool hotspotForegroundSet; - ColourPair hotspotForeground; - bool hotspotBackgroundSet; - ColourPair hotspotBackground; - bool hotspotUnderline; - bool hotspotSingleLine; - /// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin - enum { margins=5 }; - int leftMarginWidth; ///< Spacing margin on left of text - int rightMarginWidth; ///< Spacing margin on left of text - bool symbolMargin; - int maskInLine; ///< Mask for markers to be put into text because there is nowhere for them to go in margin - MarginStyle ms[margins]; - int fixedColumnWidth; - int zoomLevel; - WhiteSpaceVisibility viewWhitespace; - bool viewIndentationGuides; - bool viewEOL; - bool showMarkedLines; - ColourPair caretcolour; - bool showCaretLineBackground; - ColourPair caretLineBackground; - int caretLineAlpha; - ColourPair edgecolour; - int edgeState; - int caretWidth; - bool someStylesProtected; - bool extraFontFlag; + FontNames fontNames; + Style styles[STYLE_MAX + 1]; + LineMarker markers[MARKER_MAX + 1]; + Indicator indicators[INDIC_MAX + 1]; + int lineHeight; + unsigned int maxAscent; + unsigned int maxDescent; + unsigned int aveCharWidth; + unsigned int spaceWidth; + bool selforeset; + ColourPair selforeground; + bool selbackset; + ColourPair selbackground; + ColourPair selbackground2; + int selAlpha; + bool whitespaceForegroundSet; + ColourPair whitespaceForeground; + bool whitespaceBackgroundSet; + ColourPair whitespaceBackground; + ColourPair selbar; + ColourPair selbarlight; + bool foldmarginColourSet; + ColourPair foldmarginColour; + bool foldmarginHighlightColourSet; + ColourPair foldmarginHighlightColour; + bool hotspotForegroundSet; + ColourPair hotspotForeground; + bool hotspotBackgroundSet; + ColourPair hotspotBackground; + bool hotspotUnderline; + bool hotspotSingleLine; + /// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin + enum { margins=5 }; + int leftMarginWidth; ///< Spacing margin on left of text + int rightMarginWidth; ///< Spacing margin on left of text + bool symbolMargin; + int maskInLine; ///< Mask for markers to be put into text because there is nowhere for them to go in margin + MarginStyle ms[margins]; + int fixedColumnWidth; + int zoomLevel; + WhiteSpaceVisibility viewWhitespace; + bool viewIndentationGuides; + bool viewEOL; + bool showMarkedLines; + ColourPair caretcolour; + bool showCaretLineBackground; + ColourPair caretLineBackground; + int caretLineAlpha; + ColourPair edgecolour; + int edgeState; + int caretWidth; + bool someStylesProtected; + bool extraFontFlag; - ViewStyle(); - ViewStyle(const ViewStyle &source); - ~ViewStyle(); - void Init(); - void RefreshColourPalette(Palette &pal, bool want); - void Refresh(Surface &surface); - void ResetDefaultStyle(); - void ClearStyles(); - void SetStyleFontName(int styleIndex, const char *name); - bool ProtectionActive() const; + ViewStyle(); + ViewStyle(const ViewStyle &source); + ~ViewStyle(); + void Init(); + void RefreshColourPalette(Palette &pal, bool want); + void Refresh(Surface &surface); + void ResetDefaultStyle(); + void ClearStyles(); + void SetStyleFontName(int styleIndex, const char *name); + bool ProtectionActive() const; }; #endif diff --git a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/XPM.h b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/XPM.h index 4d3da28d36e..9032af22b54 100644 --- a/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/XPM.h +++ b/Tools/MaterialEditor/wxscintilla_1.69.2/src/scintilla/src/XPM.h @@ -12,61 +12,61 @@ * Hold a pixmap in XPM format. */ class XPM { - int id; // Assigned by container - int height; - int width; - int nColours; - char *data; - char codeTransparent; - char *codes; - ColourPair *colours; - ColourAllocated ColourFromCode(int ch); - void FillRun(Surface *surface, int code, int startX, int y, int x); - char **lines; - ColourPair *colourCodeTable[256]; + int id; // Assigned by container + int height; + int width; + int nColours; + char *data; + char codeTransparent; + char *codes; + ColourPair *colours; + ColourAllocated ColourFromCode(int ch); + void FillRun(Surface *surface, int code, int startX, int y, int x); + char **lines; + ColourPair *colourCodeTable[256]; public: - XPM(const char *textForm); - XPM(const char * const *linesForm); - ~XPM(); - void Init(const char *textForm); - void Init(const char * const *linesForm); - void Clear(); - /// Similar to same named method in ViewStyle: - void RefreshColourPalette(Palette &pal, bool want); - /// No palette used, so just copy the desired colours to the allocated colours - void CopyDesiredColours(); - /// Decompose image into runs and use FillRectangle for each run - void Draw(Surface *surface, PRectangle &rc); - char **InLinesForm() { return lines; } - void SetId(int id_) { id = id_; } - int GetId() { return id; } - int GetHeight() { return height; } - int GetWidth() { return width; } - static const char **LinesFormFromTextForm(const char *textForm); + XPM(const char *textForm); + XPM(const char * const *linesForm); + ~XPM(); + void Init(const char *textForm); + void Init(const char * const *linesForm); + void Clear(); + /// Similar to same named method in ViewStyle: + void RefreshColourPalette(Palette &pal, bool want); + /// No palette used, so just copy the desired colours to the allocated colours + void CopyDesiredColours(); + /// Decompose image into runs and use FillRectangle for each run + void Draw(Surface *surface, PRectangle &rc); + char **InLinesForm() { return lines; } + void SetId(int id_) { id = id_; } + int GetId() { return id; } + int GetHeight() { return height; } + int GetWidth() { return width; } + static const char **LinesFormFromTextForm(const char *textForm); }; /** * A collection of pixmaps indexed by integer id. */ class XPMSet { - XPM **set; ///< The stored XPMs. - int len; ///< Current number of XPMs. - int maximum; ///< Current maximum number of XPMs, increased by steps if reached. - int height; ///< Memorize largest height of the set. - int width; ///< Memorize largest width of the set. + XPM **set; ///< The stored XPMs. + int len; ///< Current number of XPMs. + int maximum; ///< Current maximum number of XPMs, increased by steps if reached. + int height; ///< Memorize largest height of the set. + int width; ///< Memorize largest width of the set. public: - XPMSet(); - ~XPMSet(); - /// Remove all XPMs. - void Clear(); - /// Add a XPM. - void Add(int id, const char *textForm); - /// Get XPM by id. - XPM *Get(int id); - /// Give the largest height of the set. - int GetHeight(); - /// Give the largest width of the set. - int GetWidth(); + XPMSet(); + ~XPMSet(); + /// Remove all XPMs. + void Clear(); + /// Add a XPM. + void Add(int id, const char *textForm); + /// Get XPM by id. + XPM *Get(int id); + /// Give the largest height of the set. + int GetHeight(); + /// Give the largest width of the set. + int GetWidth(); }; #endif diff --git a/Tools/MayaExport/include/_singleton.h b/Tools/MayaExport/include/_singleton.h index 7e459a3a3d9..e97843d439e 100644 --- a/Tools/MayaExport/include/_singleton.h +++ b/Tools/MayaExport/include/_singleton.h @@ -41,19 +41,19 @@ namespace OgreMayaExporter public: Singleton(){ assert( !msSingleton ); - msSingleton = static_cast< T* >( this ); + msSingleton = static_cast< T* >( this ); } ~Singleton(){ - assert( msSingleton ); - msSingleton = 0; - } - static T& getSingleton(){ - assert( msSingleton ); - return ( *msSingleton ); - } + assert( msSingleton ); + msSingleton = 0; + } + static T& getSingleton(){ + assert( msSingleton ); + return ( *msSingleton ); + } static T* getSingletonPtr(){ - return msSingleton; - } + return msSingleton; + } }; }; // end namespace diff --git a/Tools/MayaExport/include/animation.h b/Tools/MayaExport/include/animation.h index 8e5415d6210..fd83785abdb 100644 --- a/Tools/MayaExport/include/animation.h +++ b/Tools/MayaExport/include/animation.h @@ -23,128 +23,128 @@ namespace OgreMayaExporter { - // Track type - typedef enum { TT_SKELETON, TT_MORPH, TT_POSE } trackType; - - // Target - typedef enum { T_MESH, T_SUBMESH } target; - - // Vertex position - typedef struct vertexPositiontag - { - float x,y,z; - } vertexPosition; - - // Vertex pose reference - typedef struct vertexPoseReftag - { - int poseIndex; - float poseWeight; - } vertexPoseRef; - - // Vertex animation keyframe - typedef struct vertexKeyframetag - { - float time; - std::vector positions; - std::vector poserefs; - } vertexKeyframe; - - // Skeleton animation keyframe - typedef struct skeletonKeyframeTag - { - float time; //time of keyframe - double tx,ty,tz; //translation - double angle,axis_x,axis_y,axis_z; //rotation - float sx,sy,sz; //scale - } skeletonKeyframe; - - // Blend shape data - typedef struct vertexOffestTag - { - long index; - float x,y,z; - } vertexOffset; - - typedef struct poseTag - { - target poseTarget; - long index; - int blendShapeIndex; - MString name; - std::vector offsets; - } pose; - - // A class for storing an animation track - // each track can be either skeleton, morph or pose animation - class Track - { - public: - //constructor - Track() { - clear(); - }; - //destructor - ~Track() { - clear(); - } - //clear track data - void clear() { - m_type = TT_SKELETON; - m_target = T_MESH; - m_index = 0; - m_bone = ""; - m_vertexKeyframes.clear(); - m_skeletonKeyframes.clear(); - } - //add vertex animation keyframe - void addVertexKeyframe(vertexKeyframe& k) { - m_vertexKeyframes.push_back(k); - } - //add skeleton animation keyframe - void addSkeletonKeyframe(skeletonKeyframe& k) { - m_skeletonKeyframes.push_back(k); - } - - //public members - trackType m_type; - target m_target; - int m_index; - MString m_bone; - std::vector m_vertexKeyframes; - std::vector m_skeletonKeyframes; - }; - - - // A class for storing animation information - // an animation is a collection of different tracks - class Animation - { - public: - //constructor - Animation() { - clear(); - } - //destructor - ~Animation() { - clear(); - }; - //clear animation data - void clear() { - m_name = ""; - m_length = 0; - m_tracks.clear(); - }; - //add track - void addTrack(Track& t) { - m_tracks.push_back(t); - } - - //public memebers - MString m_name; - float m_length; - std::vector m_tracks; - }; + // Track type + typedef enum { TT_SKELETON, TT_MORPH, TT_POSE } trackType; + + // Target + typedef enum { T_MESH, T_SUBMESH } target; + + // Vertex position + typedef struct vertexPositiontag + { + float x,y,z; + } vertexPosition; + + // Vertex pose reference + typedef struct vertexPoseReftag + { + int poseIndex; + float poseWeight; + } vertexPoseRef; + + // Vertex animation keyframe + typedef struct vertexKeyframetag + { + float time; + std::vector positions; + std::vector poserefs; + } vertexKeyframe; + + // Skeleton animation keyframe + typedef struct skeletonKeyframeTag + { + float time; //time of keyframe + double tx,ty,tz; //translation + double angle,axis_x,axis_y,axis_z; //rotation + float sx,sy,sz; //scale + } skeletonKeyframe; + + // Blend shape data + typedef struct vertexOffestTag + { + long index; + float x,y,z; + } vertexOffset; + + typedef struct poseTag + { + target poseTarget; + long index; + int blendShapeIndex; + MString name; + std::vector offsets; + } pose; + + // A class for storing an animation track + // each track can be either skeleton, morph or pose animation + class Track + { + public: + //constructor + Track() { + clear(); + }; + //destructor + ~Track() { + clear(); + } + //clear track data + void clear() { + m_type = TT_SKELETON; + m_target = T_MESH; + m_index = 0; + m_bone = ""; + m_vertexKeyframes.clear(); + m_skeletonKeyframes.clear(); + } + //add vertex animation keyframe + void addVertexKeyframe(vertexKeyframe& k) { + m_vertexKeyframes.push_back(k); + } + //add skeleton animation keyframe + void addSkeletonKeyframe(skeletonKeyframe& k) { + m_skeletonKeyframes.push_back(k); + } + + //public members + trackType m_type; + target m_target; + int m_index; + MString m_bone; + std::vector m_vertexKeyframes; + std::vector m_skeletonKeyframes; + }; + + + // A class for storing animation information + // an animation is a collection of different tracks + class Animation + { + public: + //constructor + Animation() { + clear(); + } + //destructor + ~Animation() { + clear(); + }; + //clear animation data + void clear() { + m_name = ""; + m_length = 0; + m_tracks.clear(); + }; + //add track + void addTrack(Track& t) { + m_tracks.push_back(t); + } + + //public memebers + MString m_name; + float m_length; + std::vector m_tracks; + }; } // end namespace diff --git a/Tools/MayaExport/include/blendshape.h b/Tools/MayaExport/include/blendshape.h index fdd3b19ea05..7a0ff08147a 100644 --- a/Tools/MayaExport/include/blendshape.h +++ b/Tools/MayaExport/include/blendshape.h @@ -26,77 +26,77 @@ namespace OgreMayaExporter { - typedef struct - { - MPlugArray srcConnections; - MPlugArray dstConnections; - } weightConnections; + typedef struct + { + MPlugArray srcConnections; + MPlugArray dstConnections; + } weightConnections; - typedef struct - { - int targetIndex; - std::vector poses; - } poseGroup; + typedef struct + { + int targetIndex; + std::vector poses; + } poseGroup; - // Blend Shape Class - class BlendShape - { - public: - // Constructor - BlendShape(); - // Destructor - ~BlendShape(); - // Clear blend shape data - void clear(); - // Load blend shape deformer from Maya - MStatus load(MObject &blendShapeObj); - // Load blend shape poses for shared geometry - MStatus loadPosesShared(MDagPath& meshDag,ParamList ¶ms,std::vector &vertices, - long numVertices,long offset=0); - // Load blend shape poses for a submesh - MStatus loadPosesSubmesh(MDagPath& meshDag,ParamList ¶ms,std::vector &vertices, - std::vector& indices,long targetIndex=0); - //load a blend shape animation track - Track loadTrack(float start,float stop,float rate,ParamList& params,int targetIndex,int startPoseId); - // Get blend shape deformer name - MString getName(); - // Get blend shape poses - stdext::hash_map& getPoseGroups(); - // Set maya blend shape deformer envelope - void setEnvelope(float envelope); - // Restore maya blend shape deformer original envelope - void restoreEnvelope(); - // Break connections to this blendshape - void breakConnections(); - // Restore connections on this blendshape - void restoreConnections(); - // Public members - MFnBlendShapeDeformer* m_pBlendShapeFn; + // Blend Shape Class + class BlendShape + { + public: + // Constructor + BlendShape(); + // Destructor + ~BlendShape(); + // Clear blend shape data + void clear(); + // Load blend shape deformer from Maya + MStatus load(MObject &blendShapeObj); + // Load blend shape poses for shared geometry + MStatus loadPosesShared(MDagPath& meshDag,ParamList ¶ms,std::vector &vertices, + long numVertices,long offset=0); + // Load blend shape poses for a submesh + MStatus loadPosesSubmesh(MDagPath& meshDag,ParamList ¶ms,std::vector &vertices, + std::vector& indices,long targetIndex=0); + //load a blend shape animation track + Track loadTrack(float start,float stop,float rate,ParamList& params,int targetIndex,int startPoseId); + // Get blend shape deformer name + MString getName(); + // Get blend shape poses + stdext::hash_map& getPoseGroups(); + // Set maya blend shape deformer envelope + void setEnvelope(float envelope); + // Restore maya blend shape deformer original envelope + void restoreEnvelope(); + // Break connections to this blendshape + void breakConnections(); + // Restore connections on this blendshape + void restoreConnections(); + // Public members + MFnBlendShapeDeformer* m_pBlendShapeFn; - protected: - // Internal methods - //load a blend shape pose for shared geometry - MStatus loadPoseShared(MDagPath& meshDag,ParamList& params,std::vector& vertices, - long numVertices,long offset,MString poseName, int blendShapeIndex); - //load a blend shape pose for a submesh - MStatus loadPoseSubmesh(MDagPath& meshDag,ParamList& params,std::vector& vertices, - std::vector& indices,MString poseName,int targetIndex, int blendShapeIndex); - //load a blend shape animation keyframe - vertexKeyframe loadKeyframe(float time,ParamList& params,int targetIndex,int startPoseId); + protected: + // Internal methods + //load a blend shape pose for shared geometry + MStatus loadPoseShared(MDagPath& meshDag,ParamList& params,std::vector& vertices, + long numVertices,long offset,MString poseName, int blendShapeIndex); + //load a blend shape pose for a submesh + MStatus loadPoseSubmesh(MDagPath& meshDag,ParamList& params,std::vector& vertices, + std::vector& indices,MString poseName,int targetIndex, int blendShapeIndex); + //load a blend shape animation keyframe + vertexKeyframe loadKeyframe(float time,ParamList& params,int targetIndex,int startPoseId); - // Protected members - //original values to restore after export - float m_origEnvelope; - std::vector m_origWeights; - //blend shape poses - stdext::hash_map m_poseGroups; - //blend shape target (shared geometry or submesh) - target m_target; - //blend shape weights connections - std::vector m_weightConnections; - }; + // Protected members + //original values to restore after export + float m_origEnvelope; + std::vector m_origWeights; + //blend shape poses + stdext::hash_map m_poseGroups; + //blend shape target (shared geometry or submesh) + target m_target; + //blend shape weights connections + std::vector m_weightConnections; + }; -} // end namespace +} // end namespace #endif \ No newline at end of file diff --git a/Tools/MayaExport/include/material.h b/Tools/MayaExport/include/material.h index dee80fdab1e..b7d35b85d23 100644 --- a/Tools/MayaExport/include/material.h +++ b/Tools/MayaExport/include/material.h @@ -25,76 +25,76 @@ namespace OgreMayaExporter { - typedef enum {MT_SURFACE_SHADER,MT_LAMBERT,MT_PHONG,MT_BLINN,MT_CGFX} MaterialType; + typedef enum {MT_SURFACE_SHADER,MT_LAMBERT,MT_PHONG,MT_BLINN,MT_CGFX} MaterialType; - typedef enum {TOT_REPLACE,TOT_MODULATE,TOT_ADD,TOT_ALPHABLEND} TexOpType; + typedef enum {TOT_REPLACE,TOT_MODULATE,TOT_ADD,TOT_ALPHABLEND} TexOpType; - typedef enum {TAM_CLAMP,TAM_BORDER,TAM_WRAP,TAM_MIRROR} TexAddressMode; + typedef enum {TAM_CLAMP,TAM_BORDER,TAM_WRAP,TAM_MIRROR} TexAddressMode; - class Texture - { - public: - //constructor - Texture() { - scale_u = scale_v = 1; - scroll_u = scroll_v = 0; - rot = 0; - am_u = am_v = TAM_CLAMP; - } - //destructor - ~Texture(){}; - - //public members - MString filename; - MString absFilename; - TexOpType opType; - MString uvsetName; - int uvsetIndex; - TexAddressMode am_u,am_v; - double scale_u,scale_v; - double scroll_u,scroll_v; - double rot; - }; + class Texture + { + public: + //constructor + Texture() { + scale_u = scale_v = 1; + scroll_u = scroll_v = 0; + rot = 0; + am_u = am_v = TAM_CLAMP; + } + //destructor + ~Texture(){}; + + //public members + MString filename; + MString absFilename; + TexOpType opType; + MString uvsetName; + int uvsetIndex; + TexAddressMode am_u,am_v; + double scale_u,scale_v; + double scroll_u,scroll_v; + double rot; + }; - /***** Class Material *****/ - class Material - { - public: - //constructor - Material(); - //destructor - ~Material(); - //get material name - MString& name(); - //clear material data - void clear(); - //load material data - MStatus load(MFnDependencyNode* pShader,MStringArray& uvsets,ParamList& params); - //load a specific material type - MStatus loadSurfaceShader(MFnDependencyNode* pShader); - MStatus loadLambert(MFnDependencyNode* pShader); - MStatus loadPhong(MFnDependencyNode* pShader); - MStatus loadBlinn(MFnDependencyNode* pShader); - MStatus loadCgFxShader(MFnDependencyNode* pShader); - //write material data to Ogre material script - MStatus writeOgreScript(ParamList ¶ms); - //copy textures to path specified by params - MStatus copyTextures(ParamList ¶ms); - public: - //load texture data - MStatus loadTexture(MFnDependencyNode* pTexNode,TexOpType& opType,MStringArray& uvsets,ParamList& params); + /***** Class Material *****/ + class Material + { + public: + //constructor + Material(); + //destructor + ~Material(); + //get material name + MString& name(); + //clear material data + void clear(); + //load material data + MStatus load(MFnDependencyNode* pShader,MStringArray& uvsets,ParamList& params); + //load a specific material type + MStatus loadSurfaceShader(MFnDependencyNode* pShader); + MStatus loadLambert(MFnDependencyNode* pShader); + MStatus loadPhong(MFnDependencyNode* pShader); + MStatus loadBlinn(MFnDependencyNode* pShader); + MStatus loadCgFxShader(MFnDependencyNode* pShader); + //write material data to Ogre material script + MStatus writeOgreScript(ParamList ¶ms); + //copy textures to path specified by params + MStatus copyTextures(ParamList ¶ms); + public: + //load texture data + MStatus loadTexture(MFnDependencyNode* pTexNode,TexOpType& opType,MStringArray& uvsets,ParamList& params); - MString m_name; - MaterialType m_type; - MColor m_ambient, m_diffuse, m_specular, m_emissive; - bool m_lightingOff; - bool m_isTransparent; - bool m_isTextured; - bool m_isMultiTextured; - std::vector m_textures; - }; + MString m_name; + MaterialType m_type; + MColor m_ambient, m_diffuse, m_specular, m_emissive; + bool m_lightingOff; + bool m_isTransparent; + bool m_isTextured; + bool m_isMultiTextured; + std::vector m_textures; + }; -}; //end of namespace +}; //end of namespace #endif \ No newline at end of file diff --git a/Tools/MayaExport/include/materialSet.h b/Tools/MayaExport/include/materialSet.h index 24b9cb6a61c..d3ac66b9742 100644 --- a/Tools/MayaExport/include/materialSet.h +++ b/Tools/MayaExport/include/materialSet.h @@ -25,89 +25,89 @@ namespace OgreMayaExporter { - class MaterialSet : public Singleton - { - public: - //constructor - MaterialSet(){ - //create a default material - m_pDefaultMat = new Material(); - m_pDefaultMat->m_type = MT_LAMBERT; - m_pDefaultMat->m_name = "defaultLambert"; - m_pDefaultMat->m_ambient = MColor(0,0,0,1); - m_pDefaultMat->m_emissive = MColor(0,0,0,1); - m_pDefaultMat->m_diffuse = MColor(0.5,0.5,0.5,1); - }; - //destructor - ~MaterialSet(){ - clear(); - if (m_pDefaultMat) - delete m_pDefaultMat; - } - //clear - void clear(){ - for (int i=0; iname() == pMat->name()) - { - found = true; - delete pMat; - } - } - if (!found) - m_materials.push_back(pMat); - } - //get material - Material* getMaterial(const MString& name){ - for (int i=0; iname() == name) - return m_materials[i]; - } - return NULL; - }; - //get default material - Material* getDefaultMaterial() - { - return m_pDefaultMat; - }; - //get material set - static MaterialSet& getSingleton(){ - assert(msSingleton); - return (*msSingleton); - }; - static MaterialSet* getSingletonPtr(){ - return msSingleton; - }; - //write materials to Ogre XML - MStatus writeOgreScript(ParamList ¶ms){ - MStatus stat; - for (int i=0; iwriteOgreScript(params); - if (MS::kSuccess != stat) - { - MString msg = "Error writing material "; - msg += m_materials[i]->name(); - msg += ", aborting operation"; - MGlobal::displayInfo(msg); - } - } - return MS::kSuccess; - }; + class MaterialSet : public Singleton + { + public: + //constructor + MaterialSet(){ + //create a default material + m_pDefaultMat = new Material(); + m_pDefaultMat->m_type = MT_LAMBERT; + m_pDefaultMat->m_name = "defaultLambert"; + m_pDefaultMat->m_ambient = MColor(0,0,0,1); + m_pDefaultMat->m_emissive = MColor(0,0,0,1); + m_pDefaultMat->m_diffuse = MColor(0.5,0.5,0.5,1); + }; + //destructor + ~MaterialSet(){ + clear(); + if (m_pDefaultMat) + delete m_pDefaultMat; + } + //clear + void clear(){ + for (int i=0; iname() == pMat->name()) + { + found = true; + delete pMat; + } + } + if (!found) + m_materials.push_back(pMat); + } + //get material + Material* getMaterial(const MString& name){ + for (int i=0; iname() == name) + return m_materials[i]; + } + return NULL; + }; + //get default material + Material* getDefaultMaterial() + { + return m_pDefaultMat; + }; + //get material set + static MaterialSet& getSingleton(){ + assert(msSingleton); + return (*msSingleton); + }; + static MaterialSet* getSingletonPtr(){ + return msSingleton; + }; + //write materials to Ogre XML + MStatus writeOgreScript(ParamList ¶ms){ + MStatus stat; + for (int i=0; iwriteOgreScript(params); + if (MS::kSuccess != stat) + { + MString msg = "Error writing material "; + msg += m_materials[i]->name(); + msg += ", aborting operation"; + MGlobal::displayInfo(msg); + } + } + return MS::kSuccess; + }; - protected: - std::vector m_materials; - Material* m_pDefaultMat; - }; + protected: + std::vector m_materials; + Material* m_pDefaultMat; + }; -}; //end namespace +}; //end namespace #endif \ No newline at end of file diff --git a/Tools/MayaExport/include/mayaExportLayer.h b/Tools/MayaExport/include/mayaExportLayer.h index 534bfe739ac..21a97d75991 100644 --- a/Tools/MayaExport/include/mayaExportLayer.h +++ b/Tools/MayaExport/include/mayaExportLayer.h @@ -29,9 +29,9 @@ #include #ifdef MAC_PLUGIN - #include + #include #else - #include + #include #endif // Maya API diff --git a/Tools/MayaExport/include/mesh.h b/Tools/MayaExport/include/mesh.h index 39330949546..dd6fca40b0d 100644 --- a/Tools/MayaExport/include/mesh.h +++ b/Tools/MayaExport/include/mesh.h @@ -26,111 +26,111 @@ namespace OgreMayaExporter { - /***** structures to store shared geometry *****/ - typedef struct dagInfotag - { - long offset; - long numVertices; - MDagPath dagPath; - BlendShape* pBlendShape; - } dagInfo; + /***** structures to store shared geometry *****/ + typedef struct dagInfotag + { + long offset; + long numVertices; + MDagPath dagPath; + BlendShape* pBlendShape; + } dagInfo; - typedef struct sharedGeometrytag - { - std::vector vertices; - std::vector dagMap; - } sharedGeometry; + typedef struct sharedGeometrytag + { + std::vector vertices; + std::vector dagMap; + } sharedGeometry; - typedef stdext::hash_map submeshPoseRemapping; + typedef stdext::hash_map submeshPoseRemapping; - typedef stdext::hash_map poseRemapping; + typedef stdext::hash_map poseRemapping; - /***** Class Mesh *****/ - class Mesh - { - public: - //constructor - Mesh(const MString& name = ""); - //destructor - ~Mesh(); - //clear data - void clear(); - //get pointer to linked skeleton - Skeleton* getSkeleton(); - //load mesh data from a maya Fn - MStatus load(const MDagPath& meshDag,ParamList ¶ms); - //load vertex animations - MStatus loadAnims(ParamList ¶ms); - //load blend shape deformers - MStatus loadBlendShapes(ParamList ¶ms); - //load blend shape animations - MStatus loadBlendShapeAnimations(ParamList& params); - //write to a OGRE binary mesh - MStatus writeOgreBinary(ParamList ¶ms); + /***** Class Mesh *****/ + class Mesh + { + public: + //constructor + Mesh(const MString& name = ""); + //destructor + ~Mesh(); + //clear data + void clear(); + //get pointer to linked skeleton + Skeleton* getSkeleton(); + //load mesh data from a maya Fn + MStatus load(const MDagPath& meshDag,ParamList ¶ms); + //load vertex animations + MStatus loadAnims(ParamList ¶ms); + //load blend shape deformers + MStatus loadBlendShapes(ParamList ¶ms); + //load blend shape animations + MStatus loadBlendShapeAnimations(ParamList& params); + //write to a OGRE binary mesh + MStatus writeOgreBinary(ParamList ¶ms); - protected: - //get uvsets info from the maya mesh - MStatus getUVSets(const MDagPath& meshDag); - //get skin cluster linked to the maya mesh - MStatus getSkinCluster(const MDagPath& meshDag,ParamList& params); - //get blend shape deformer linked to the maya mesh - MStatus getBlendShapeDeformer(const MDagPath& meshDag,ParamList& params); - //get connected shaders - MStatus getShaders(const MDagPath& meshDag); - //get vertex data - MStatus getVertices(const MDagPath& meshDag,ParamList& params); - //get vertex bone assignements - MStatus getVertexBoneWeights(const MDagPath& meshDag,OgreMayaExporter::ParamList ¶ms); - //get faces data - MStatus getFaces(const MDagPath& meshDag,ParamList& params); - //build shared geometry - MStatus buildSharedGeometry(const MDagPath& meshDag,ParamList& params); - //create submeshes - MStatus createSubmeshes(const MDagPath& meshDag,ParamList& params); - //load a vertex animation clip - MStatus loadClip(MString& clipName,float start,float stop,float rate,ParamList& params); - //load a vertex animation track for the whole mesh - MStatus loadMeshTrack(Animation& a,std::vector& times,ParamList& params); - //load all submesh animation tracks (one for each submesh) - MStatus loadSubmeshTracks(Animation& a,std::vector& times,ParamList& params); - //load a keyframe for the whole mesh - MStatus loadKeyframe(Track& t,float time,ParamList& params); - //write shared geometry data to an Ogre compatible mesh - MStatus createOgreSharedGeometry(Ogre::MeshPtr pMesh,ParamList& params); - //create an Ogre compatible vertex buffer - MStatus createOgreVertexBuffer(Ogre::MeshPtr pMesh,Ogre::VertexDeclaration* pDecl,const std::vector& vertices); - //create Ogre poses for pose animation - MStatus createOgrePoses(Ogre::MeshPtr pMesh,ParamList& params); - //create vertex animations for an Ogre mesh - MStatus createOgreVertexAnimations(Ogre::MeshPtr pMesh,ParamList& params); - //create pose animations for an Ogre mesh - MStatus createOgrePoseAnimations(Ogre::MeshPtr pMesh,ParamList& params); + protected: + //get uvsets info from the maya mesh + MStatus getUVSets(const MDagPath& meshDag); + //get skin cluster linked to the maya mesh + MStatus getSkinCluster(const MDagPath& meshDag,ParamList& params); + //get blend shape deformer linked to the maya mesh + MStatus getBlendShapeDeformer(const MDagPath& meshDag,ParamList& params); + //get connected shaders + MStatus getShaders(const MDagPath& meshDag); + //get vertex data + MStatus getVertices(const MDagPath& meshDag,ParamList& params); + //get vertex bone assignements + MStatus getVertexBoneWeights(const MDagPath& meshDag,OgreMayaExporter::ParamList ¶ms); + //get faces data + MStatus getFaces(const MDagPath& meshDag,ParamList& params); + //build shared geometry + MStatus buildSharedGeometry(const MDagPath& meshDag,ParamList& params); + //create submeshes + MStatus createSubmeshes(const MDagPath& meshDag,ParamList& params); + //load a vertex animation clip + MStatus loadClip(MString& clipName,float start,float stop,float rate,ParamList& params); + //load a vertex animation track for the whole mesh + MStatus loadMeshTrack(Animation& a,std::vector& times,ParamList& params); + //load all submesh animation tracks (one for each submesh) + MStatus loadSubmeshTracks(Animation& a,std::vector& times,ParamList& params); + //load a keyframe for the whole mesh + MStatus loadKeyframe(Track& t,float time,ParamList& params); + //write shared geometry data to an Ogre compatible mesh + MStatus createOgreSharedGeometry(Ogre::MeshPtr pMesh,ParamList& params); + //create an Ogre compatible vertex buffer + MStatus createOgreVertexBuffer(Ogre::MeshPtr pMesh,Ogre::VertexDeclaration* pDecl,const std::vector& vertices); + //create Ogre poses for pose animation + MStatus createOgrePoses(Ogre::MeshPtr pMesh,ParamList& params); + //create vertex animations for an Ogre mesh + MStatus createOgreVertexAnimations(Ogre::MeshPtr pMesh,ParamList& params); + //create pose animations for an Ogre mesh + MStatus createOgrePoseAnimations(Ogre::MeshPtr pMesh,ParamList& params); - //internal members - MString m_name; - long m_numTriangles; - std::vector m_uvsets; - std::vector m_submeshes; - Skeleton* m_pSkeleton; - sharedGeometry m_sharedGeom; - std::vector m_vertexClips; - std::vector m_BSClips; - //temporary members (existing only during translation from maya mesh) - std::vector newvertices; - std::vector newweights; - std::vector newjointIds; - MPointArray newpoints; - MFloatVectorArray newnormals; - MStringArray newuvsets; - MFnSkinCluster* pSkinCluster; - BlendShape* pBlendShape; - MObjectArray shaders; - MIntArray shaderPolygonMapping; - std::vector polygonSets; - bool opposite; - poseRemapping m_poseRemapping; - }; + //internal members + MString m_name; + long m_numTriangles; + std::vector m_uvsets; + std::vector m_submeshes; + Skeleton* m_pSkeleton; + sharedGeometry m_sharedGeom; + std::vector m_vertexClips; + std::vector m_BSClips; + //temporary members (existing only during translation from maya mesh) + std::vector newvertices; + std::vector newweights; + std::vector newjointIds; + MPointArray newpoints; + MFloatVectorArray newnormals; + MStringArray newuvsets; + MFnSkinCluster* pSkinCluster; + BlendShape* pBlendShape; + MObjectArray shaders; + MIntArray shaderPolygonMapping; + std::vector polygonSets; + bool opposite; + poseRemapping m_poseRemapping; + }; }; // end of namespace diff --git a/Tools/MayaExport/include/ogreExporter.h b/Tools/MayaExport/include/ogreExporter.h index 8e883729d0f..c6441c43915 100644 --- a/Tools/MayaExport/include/ogreExporter.h +++ b/Tools/MayaExport/include/ogreExporter.h @@ -43,68 +43,68 @@ namespace OgreMayaExporter { - class OgreExporter : public MPxCommand - { - public: - // Public methods - //constructor - OgreExporter(); - //destructor - virtual ~OgreExporter(); - //override of MPxCommand methods - static void* creator(); - MStatus doIt(const MArgList& args); - bool isUndoable() const; + class OgreExporter : public MPxCommand + { + public: + // Public methods + //constructor + OgreExporter(); + //destructor + virtual ~OgreExporter(); + //override of MPxCommand methods + static void* creator(); + MStatus doIt(const MArgList& args); + bool isUndoable() const; - protected: - // Internal methods - //analyses a dag node in Maya and translates it to the OGRE format, - //it is recursively applied until the whole dag nodes tree has been visited - MStatus translateNode(MDagPath& dagPath); - //writes animation data to an extra .anim file - MStatus writeAnim(MFnAnimCurve& anim); - //writes camera data to an extra .camera file - MStatus writeCamera(MFnCamera& camera); - //writes all translated data to a group of OGRE files - MStatus writeOgreData(); - //cleans up memory and exits - void exit(); + protected: + // Internal methods + //analyses a dag node in Maya and translates it to the OGRE format, + //it is recursively applied until the whole dag nodes tree has been visited + MStatus translateNode(MDagPath& dagPath); + //writes animation data to an extra .anim file + MStatus writeAnim(MFnAnimCurve& anim); + //writes camera data to an extra .camera file + MStatus writeCamera(MFnCamera& camera); + //writes all translated data to a group of OGRE files + MStatus writeOgreData(); + //cleans up memory and exits + void exit(); - private: - // private members - MStatus stat; - ParamList m_params; - Mesh* m_pMesh; - MaterialSet* m_pMaterialSet; - MSelectionList m_selList; - MTime m_curTime; - }; + private: + // private members + MStatus stat; + ParamList m_params; + Mesh* m_pMesh; + MaterialSet* m_pMaterialSet; + MSelectionList m_selList; + MTime m_curTime; + }; - /********************************************************************************************* - * INLINE Functions * - *********************************************************************************************/ - // Standard constructor - inline OgreExporter::OgreExporter() - :m_pMesh(0), m_pMaterialSet(0) - { - MGlobal::displayInfo("Translating scene to OGRE format"); - } + /********************************************************************************************* + * INLINE Functions * + *********************************************************************************************/ + // Standard constructor + inline OgreExporter::OgreExporter() + :m_pMesh(0), m_pMaterialSet(0) + { + MGlobal::displayInfo("Translating scene to OGRE format"); + } - // Routine for creating the plug-in - inline void* OgreExporter::creator() - { - return new OgreExporter(); - } + // Routine for creating the plug-in + inline void* OgreExporter::creator() + { + return new OgreExporter(); + } - // It tells that this command is not undoable - inline bool OgreExporter::isUndoable() const - { - MGlobal::displayInfo("Command is not undoable"); - return false; - } + // It tells that this command is not undoable + inline bool OgreExporter::isUndoable() const + { + MGlobal::displayInfo("Command is not undoable"); + return false; + } -} //end namespace +} //end namespace #endif \ No newline at end of file diff --git a/Tools/MayaExport/include/paramlist.h b/Tools/MayaExport/include/paramlist.h index a186d106480..8fe79233c73 100644 --- a/Tools/MayaExport/include/paramlist.h +++ b/Tools/MayaExport/include/paramlist.h @@ -32,200 +32,200 @@ namespace OgreMayaExporter { - class Submesh; - - typedef struct clipInfoTag - { - float start; //start time of the clip - float stop; //end time of the clip - float rate; //sample rate of anim curves, -1 means auto - MString name; //clip name - } clipInfo; - - typedef enum - { - NPT_CURFRAME, - NPT_BINDPOSE - } NeutralPoseType; - - typedef enum - { - TS_TEXCOORD, - TS_TANGENT - } TangentSemantic; - - /***** Class ParamList *****/ - class ParamList - { - public: - // class members - bool exportMesh, exportMaterial, exportAnimCurves, exportCameras, exportAll, exportVBA, - exportVertNorm, exportVertCol, exportTexCoord, exportCamerasAnim, - exportSkeleton, exportSkelAnims, exportBSAnims, exportVertAnims, exportBlendShapes, - exportWorldCoords, useSharedGeom, lightingOff, copyTextures, exportParticles, - buildTangents, buildEdges, skelBB, bsBB, vertBB, - tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity; - - float lum; // Length Unit Multiplier - - MString meshFilename, skeletonFilename, materialFilename, animFilename, camerasFilename, matPrefix, - texOutputDir, particlesFilename; - - std::ofstream outMaterial, outAnim, outCameras, outParticles; - - MStringArray writtenMaterials; - - std::vector skelClipList; - std::vector BSClipList; - std::vector vertClipList; - - NeutralPoseType neutralPoseType; - TangentSemantic tangentSemantic; - - std::vector loadedSubmeshes; - std::vector currentRootJoints; - - // constructor - ParamList() { - lum = 1.0; - exportMesh = false; - exportMaterial = false; - exportSkeleton = false; - exportSkelAnims = false; - exportBSAnims = false; - exportVertAnims = false; - exportBlendShapes = false; - exportAnimCurves = false; - exportCameras = false; - exportParticles = false; - exportAll = false; - exportWorldCoords = false; - exportVBA = false; - exportVertNorm = false; - exportVertCol = false; - exportTexCoord = false; - exportCamerasAnim = false; - useSharedGeom = false; - lightingOff = false; - copyTextures = false; - skelBB = false; - bsBB = false; - vertBB = false; - meshFilename = ""; - skeletonFilename = ""; - materialFilename = ""; - animFilename = ""; - camerasFilename = ""; - particlesFilename = ""; - matPrefix = ""; - texOutputDir = ""; - skelClipList.clear(); - BSClipList.clear(); - vertClipList.clear(); - neutralPoseType = NPT_CURFRAME; - buildEdges = false; - buildTangents = false; - tangentsSplitMirrored = false; - tangentsSplitRotated = false; - tangentsUseParity = false; - tangentSemantic = TS_TANGENT; - loadedSubmeshes.clear(); - currentRootJoints.clear(); - } - - ParamList& operator=(ParamList& source) - { - int i; - lum = source.lum; - exportMesh = source.exportMesh; - exportMaterial = source.exportMaterial; - exportSkeleton = source.exportSkeleton; - exportSkelAnims = source.exportSkelAnims; - exportBSAnims = source.exportBSAnims; - exportVertAnims = source.exportVertAnims; - exportBlendShapes = source.exportBlendShapes; - exportAnimCurves = source.exportAnimCurves; - exportCameras = source.exportCameras; - exportAll = source.exportAll; - exportWorldCoords = source.exportWorldCoords; - exportVBA = source.exportVBA; - exportVertNorm = source.exportVertNorm; - exportVertCol = source.exportVertCol; - exportTexCoord = source.exportTexCoord; - exportCamerasAnim = source.exportCamerasAnim; - exportParticles = source.exportParticles; - useSharedGeom = source.useSharedGeom; - lightingOff = source.lightingOff; - copyTextures = source.copyTextures; - skelBB = source.skelBB; - bsBB = source.bsBB; - vertBB = source.vertBB; - meshFilename = source.meshFilename; - skeletonFilename = source.skeletonFilename; - materialFilename = source.materialFilename; - animFilename = source.animFilename; - camerasFilename = source.camerasFilename; - particlesFilename = source.particlesFilename; - matPrefix = source.matPrefix; - texOutputDir = source.texOutputDir; - buildEdges = source.buildEdges; - buildTangents = source.buildTangents; - tangentsSplitMirrored = source.tangentsSplitMirrored; - tangentsSplitRotated = source.tangentsSplitRotated; - tangentsUseParity = source.tangentsUseParity; - tangentSemantic = source.tangentSemantic; - skelClipList.resize(source.skelClipList.size()); - for (i=0; i< skelClipList.size(); i++) - { - skelClipList[i].name = source.skelClipList[i].name; - skelClipList[i].start = source.skelClipList[i].start; - skelClipList[i].stop = source.skelClipList[i].stop; - skelClipList[i].rate = source.skelClipList[i].rate; - } - BSClipList.resize(source.BSClipList.size()); - for (i=0; i< BSClipList.size(); i++) - { - BSClipList[i].name = source.BSClipList[i].name; - BSClipList[i].start = source.BSClipList[i].start; - BSClipList[i].stop = source.BSClipList[i].stop; - BSClipList[i].rate = source.BSClipList[i].rate; - } - vertClipList.resize(source.vertClipList.size()); - for (i=0; i< vertClipList.size(); i++) - { - vertClipList[i].name = source.vertClipList[i].name; - vertClipList[i].start = source.vertClipList[i].start; - vertClipList[i].stop = source.vertClipList[i].stop; - vertClipList[i].rate = source.vertClipList[i].rate; - } - neutralPoseType = source.neutralPoseType; - for (i=0; i skelClipList; + std::vector BSClipList; + std::vector vertClipList; + + NeutralPoseType neutralPoseType; + TangentSemantic tangentSemantic; + + std::vector loadedSubmeshes; + std::vector currentRootJoints; + + // constructor + ParamList() { + lum = 1.0; + exportMesh = false; + exportMaterial = false; + exportSkeleton = false; + exportSkelAnims = false; + exportBSAnims = false; + exportVertAnims = false; + exportBlendShapes = false; + exportAnimCurves = false; + exportCameras = false; + exportParticles = false; + exportAll = false; + exportWorldCoords = false; + exportVBA = false; + exportVertNorm = false; + exportVertCol = false; + exportTexCoord = false; + exportCamerasAnim = false; + useSharedGeom = false; + lightingOff = false; + copyTextures = false; + skelBB = false; + bsBB = false; + vertBB = false; + meshFilename = ""; + skeletonFilename = ""; + materialFilename = ""; + animFilename = ""; + camerasFilename = ""; + particlesFilename = ""; + matPrefix = ""; + texOutputDir = ""; + skelClipList.clear(); + BSClipList.clear(); + vertClipList.clear(); + neutralPoseType = NPT_CURFRAME; + buildEdges = false; + buildTangents = false; + tangentsSplitMirrored = false; + tangentsSplitRotated = false; + tangentsUseParity = false; + tangentSemantic = TS_TANGENT; + loadedSubmeshes.clear(); + currentRootJoints.clear(); + } + + ParamList& operator=(ParamList& source) + { + int i; + lum = source.lum; + exportMesh = source.exportMesh; + exportMaterial = source.exportMaterial; + exportSkeleton = source.exportSkeleton; + exportSkelAnims = source.exportSkelAnims; + exportBSAnims = source.exportBSAnims; + exportVertAnims = source.exportVertAnims; + exportBlendShapes = source.exportBlendShapes; + exportAnimCurves = source.exportAnimCurves; + exportCameras = source.exportCameras; + exportAll = source.exportAll; + exportWorldCoords = source.exportWorldCoords; + exportVBA = source.exportVBA; + exportVertNorm = source.exportVertNorm; + exportVertCol = source.exportVertCol; + exportTexCoord = source.exportTexCoord; + exportCamerasAnim = source.exportCamerasAnim; + exportParticles = source.exportParticles; + useSharedGeom = source.useSharedGeom; + lightingOff = source.lightingOff; + copyTextures = source.copyTextures; + skelBB = source.skelBB; + bsBB = source.bsBB; + vertBB = source.vertBB; + meshFilename = source.meshFilename; + skeletonFilename = source.skeletonFilename; + materialFilename = source.materialFilename; + animFilename = source.animFilename; + camerasFilename = source.camerasFilename; + particlesFilename = source.particlesFilename; + matPrefix = source.matPrefix; + texOutputDir = source.texOutputDir; + buildEdges = source.buildEdges; + buildTangents = source.buildTangents; + tangentsSplitMirrored = source.tangentsSplitMirrored; + tangentsSplitRotated = source.tangentsSplitRotated; + tangentsUseParity = source.tangentsUseParity; + tangentSemantic = source.tangentSemantic; + skelClipList.resize(source.skelClipList.size()); + for (i=0; i< skelClipList.size(); i++) + { + skelClipList[i].name = source.skelClipList[i].name; + skelClipList[i].start = source.skelClipList[i].start; + skelClipList[i].stop = source.skelClipList[i].stop; + skelClipList[i].rate = source.skelClipList[i].rate; + } + BSClipList.resize(source.BSClipList.size()); + for (i=0; i< BSClipList.size(); i++) + { + BSClipList[i].name = source.BSClipList[i].name; + BSClipList[i].start = source.BSClipList[i].start; + BSClipList[i].stop = source.BSClipList[i].stop; + BSClipList[i].rate = source.BSClipList[i].rate; + } + vertClipList.resize(source.vertClipList.size()); + for (i=0; i< vertClipList.size(); i++) + { + vertClipList[i].name = source.vertClipList[i].name; + vertClipList[i].start = source.vertClipList[i].start; + vertClipList[i].stop = source.vertClipList[i].stop; + vertClipList[i].rate = source.vertClipList[i].rate; + } + neutralPoseType = source.neutralPoseType; + for (i=0; i CParticlesTrack; #ifdef MAC_PLUGIN @@ -103,93 +103,93 @@ typedef stdext::hash_map CParticlesData; template inline void Interpolate( const T &v1, const T &v2, float fCoeff, T *pRes ) { - pRes->Interpolate( v1, v2, fCoeff ); + pRes->Interpolate( v1, v2, fCoeff ); } //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Interpolate( const int &v1, const int &v2, float fCoeff, int *pRes ) { - *pRes = v1; + *pRes = v1; } //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Interpolate( const float &v1, const float &v2, float fCoeff, float *pRes ) { - *pRes = ( 1 - fCoeff ) * v1 + fCoeff * v2; + *pRes = ( 1 - fCoeff ) * v1 + fCoeff * v2; } //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Interpolate( const SPos &v1, const SPos &v2, float fCoeff, SPos *pRes ) { - Interpolate( v1.x, v2.x, fCoeff, &pRes->x ); - Interpolate( v1.y, v2.y, fCoeff, &pRes->y ); - Interpolate( v1.z, v2.z, fCoeff, &pRes->z ); + Interpolate( v1.x, v2.x, fCoeff, &pRes->x ); + Interpolate( v1.y, v2.y, fCoeff, &pRes->y ); + Interpolate( v1.z, v2.z, fCoeff, &pRes->z ); } //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Interpolate( const SColor &v1, const SColor &v2, float fCoeff, SColor *pRes ) { - Interpolate( v1.r, v2.r, fCoeff, &pRes->r ); - Interpolate( v1.g, v2.g, fCoeff, &pRes->g ); - Interpolate( v1.b, v2.b, fCoeff, &pRes->b ); - Interpolate( v1.a, v2.a, fCoeff, &pRes->a ); + Interpolate( v1.r, v2.r, fCoeff, &pRes->r ); + Interpolate( v1.g, v2.g, fCoeff, &pRes->g ); + Interpolate( v1.b, v2.b, fCoeff, &pRes->b ); + Interpolate( v1.a, v2.a, fCoeff, &pRes->a ); } //////////////////////////////////////////////////////////////////////////////////////////////////// inline void Interpolate( const SScale &v1, const SScale &v2, float fCoeff, SScale *pRes ) { - Interpolate( v1.x, v2.x, fCoeff, &pRes->x ); - Interpolate( v1.y, v2.y, fCoeff, &pRes->y ); + Interpolate( v1.x, v2.x, fCoeff, &pRes->x ); + Interpolate( v1.y, v2.y, fCoeff, &pRes->y ); } //////////////////////////////////////////////////////////////////////////////////////////////////// template class TKey { public: - T value; - int nTime; + T value; + int nTime; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template class TKeyTrack { public: - std::vector > keys; + std::vector > keys; protected: - void GetValueBinSearch( float fTime, T *pRes ) const - { - int nLeft = 0, nRight = keys.size() - 1; - int nTime = int( fTime - 0.5f ); - while( nLeft - nRight > 1 ) - { - int nTemp = ( nLeft + nRight ) / 2; - if ( keys[nTemp].nTime <= nTime ) - nLeft = nTemp; - else - nRight = nTemp; - } - //// - const TKey &end = keys[nRight]; - const TKey &start = keys[nLeft]; - float fCoeff = ( fTime - start.nTime ) / ( end.nTime - start.nTime ); - Interpolate( start.value, end.value, fCoeff, pRes ); - } + void GetValueBinSearch( float fTime, T *pRes ) const + { + int nLeft = 0, nRight = keys.size() - 1; + int nTime = int( fTime - 0.5f ); + while( nLeft - nRight > 1 ) + { + int nTemp = ( nLeft + nRight ) / 2; + if ( keys[nTemp].nTime <= nTime ) + nLeft = nTemp; + else + nRight = nTemp; + } + //// + const TKey &end = keys[nRight]; + const TKey &start = keys[nLeft]; + float fCoeff = ( fTime - start.nTime ) / ( end.nTime - start.nTime ); + Interpolate( start.value, end.value, fCoeff, pRes ); + } public: - void GetValue( float fTime, T *pRes ) const - { - if ( keys.size() == 1 ) - *pRes = keys[0].value; - else - GetValueBinSearch( fTime, pRes ); - } + void GetValue( float fTime, T *pRes ) const + { + if ( keys.size() == 1 ) + *pRes = keys[0].value; + else + GetValueBinSearch( fTime, pRes ); + } }; //////////////////////////////////////////////////////////////////////////////////////////////////// struct SParticle { - int nEndTime; - int nStartTime; - TKeyTrack sprite; - TKeyTrack pos; - TKeyTrack color; - TKeyTrack scale; - TKeyTrack rotation; + int nEndTime; + int nStartTime; + TKeyTrack sprite; + TKeyTrack pos; + TKeyTrack color; + TKeyTrack scale; + TKeyTrack rotation; }; //////////////////////////////////////////////////////////////////////////////////////////////////// // Particles @@ -197,22 +197,22 @@ struct SParticle class Particles { private: - CParticlesData data; - //// - int nFrames; - std::vector particleTracks; + CParticlesData data; + //// + int nFrames; + std::vector particleTracks; protected: - MStatus ExportFrame( MDagPath &dagPath, int nFrame ); - MStatus FinalizeData( int nMinFrame, int nMaxFrame ); + MStatus ExportFrame( MDagPath &dagPath, int nFrame ); + MStatus FinalizeData( int nMinFrame, int nMaxFrame ); public: - Particles(); - virtual ~Particles(); + Particles(); + virtual ~Particles(); - MStatus load( MDagPath& dagPath, ParamList& params ); - MStatus writeToXML( ParamList& params ); - void clear(); + MStatus load( MDagPath& dagPath, ParamList& params ); + MStatus writeToXML( ParamList& params ); + void clear(); }; //////////////////////////////////////////////////////////////////////////////////////////////////// }; // end of namespace diff --git a/Tools/MayaExport/include/skeleton.h b/Tools/MayaExport/include/skeleton.h index 93176ea9b11..56e43f0be13 100644 --- a/Tools/MayaExport/include/skeleton.h +++ b/Tools/MayaExport/include/skeleton.h @@ -25,63 +25,63 @@ namespace OgreMayaExporter { - /***** structure to hold joint info *****/ - typedef struct jointTag - { - MString name; - int id; - MMatrix localMatrix; - MMatrix bindMatrix; - int parentIndex; - double posx,posy,posz; - double angle; - double axisx,axisy,axisz; - float scalex,scaley,scalez; - MDagPath jointDag; - } joint; + /***** structure to hold joint info *****/ + typedef struct jointTag + { + MString name; + int id; + MMatrix localMatrix; + MMatrix bindMatrix; + int parentIndex; + double posx,posy,posz; + double angle; + double axisx,axisy,axisz; + float scalex,scaley,scalez; + MDagPath jointDag; + } joint; - /*********** Class Skeleton **********************/ - class Skeleton - { - public: - //constructor - Skeleton(); - //destructor - ~Skeleton(); - //clear skeleton data - void clear(); - //load skeleton data - MStatus load(MFnSkinCluster* pSkinCluster,ParamList& params); - //load skeletal animations - MStatus loadAnims(ParamList& params); - //get joints - std::vector& getJoints(); - //get animations - std::vector& getAnimations(); - //restore skeleton pose - void restorePose(); - //write to an OGRE binary skeleton - MStatus writeOgreBinary(ParamList ¶ms); + /*********** Class Skeleton **********************/ + class Skeleton + { + public: + //constructor + Skeleton(); + //destructor + ~Skeleton(); + //clear skeleton data + void clear(); + //load skeleton data + MStatus load(MFnSkinCluster* pSkinCluster,ParamList& params); + //load skeletal animations + MStatus loadAnims(ParamList& params); + //get joints + std::vector& getJoints(); + //get animations + std::vector& getAnimations(); + //restore skeleton pose + void restorePose(); + //write to an OGRE binary skeleton + MStatus writeOgreBinary(ParamList ¶ms); - protected: - //load a joint - MStatus loadJoint(MDagPath& jointDag, joint* parent, ParamList& params,MFnSkinCluster* pSkinCluster); - //load a clip - MStatus loadClip(MString clipName,float start,float stop,float rate,ParamList& params); - //load a keyframe for a particular joint at current time - skeletonKeyframe loadKeyframe(joint& j,float time,ParamList& params); - //write joints to an Ogre skeleton - MStatus createOgreBones(Ogre::SkeletonPtr pSkeleton,ParamList& params); - // write skeleton animations to an Ogre skeleton - MStatus createOgreSkeletonAnimations(Ogre::SkeletonPtr pSkeleton,ParamList& params); + protected: + //load a joint + MStatus loadJoint(MDagPath& jointDag, joint* parent, ParamList& params,MFnSkinCluster* pSkinCluster); + //load a clip + MStatus loadClip(MString clipName,float start,float stop,float rate,ParamList& params); + //load a keyframe for a particular joint at current time + skeletonKeyframe loadKeyframe(joint& j,float time,ParamList& params); + //write joints to an Ogre skeleton + MStatus createOgreBones(Ogre::SkeletonPtr pSkeleton,ParamList& params); + // write skeleton animations to an Ogre skeleton + MStatus createOgreSkeletonAnimations(Ogre::SkeletonPtr pSkeleton,ParamList& params); - std::vector m_joints; - std::vector m_animations; - std::vector m_roots; - MString m_restorePose; - }; + std::vector m_joints; + std::vector m_animations; + std::vector m_roots; + MString m_restorePose; + }; -} //end namespace +} //end namespace #endif diff --git a/Tools/MayaExport/include/submesh.h b/Tools/MayaExport/include/submesh.h index 37b1c1cb7c6..e61a43fd1f7 100644 --- a/Tools/MayaExport/include/submesh.h +++ b/Tools/MayaExport/include/submesh.h @@ -28,48 +28,48 @@ namespace OgreMayaExporter { - /***** Class Submesh *****/ - class Submesh - { - public: - //constructor - Submesh(const MString& name = ""); - //destructor - ~Submesh(); - //clear data - void clear(); - //load data - MStatus loadMaterial(MObject& shader,MStringArray& uvsets,ParamList& params); - MStatus load(const MDagPath& dag,std::vector& faces, std::vector& vertInfo, MPointArray& points, - MFloatVectorArray& normals, MStringArray& texcoordsets,ParamList& params,bool opposite = false); - //load a keyframe for the whole mesh - MStatus loadKeyframe(Track& t,float time,ParamList& params); - //get number of triangles composing the submesh - long numTriangles(); - //get number of vertices - long numVertices(); - //get submesh name - MString& name(); - //write submesh data to an Ogre compatible mesh - MStatus createOgreSubmesh(Ogre::MeshPtr pMesh,const ParamList& params); - //create an Ogre compatible vertex buffer - MStatus createOgreVertexBuffer(Ogre::SubMesh* pSubmesh,Ogre::VertexDeclaration* pDecl,const std::vector& vertices); + /***** Class Submesh *****/ + class Submesh + { + public: + //constructor + Submesh(const MString& name = ""); + //destructor + ~Submesh(); + //clear data + void clear(); + //load data + MStatus loadMaterial(MObject& shader,MStringArray& uvsets,ParamList& params); + MStatus load(const MDagPath& dag,std::vector& faces, std::vector& vertInfo, MPointArray& points, + MFloatVectorArray& normals, MStringArray& texcoordsets,ParamList& params,bool opposite = false); + //load a keyframe for the whole mesh + MStatus loadKeyframe(Track& t,float time,ParamList& params); + //get number of triangles composing the submesh + long numTriangles(); + //get number of vertices + long numVertices(); + //get submesh name + MString& name(); + //write submesh data to an Ogre compatible mesh + MStatus createOgreSubmesh(Ogre::MeshPtr pMesh,const ParamList& params); + //create an Ogre compatible vertex buffer + MStatus createOgreVertexBuffer(Ogre::SubMesh* pSubmesh,Ogre::VertexDeclaration* pDecl,const std::vector& vertices); - public: - //public members - MString m_name; - Material* m_pMaterial; - long m_numTriangles; - long m_numVertices; - std::vector m_indices; - std::vector m_vertices; - std::vector m_faces; - std::vector m_uvsets; - bool m_use32bitIndexes; - MDagPath m_dagPath; - BlendShape* m_pBlendShape; - MBoundingBox m_boundingBox; - }; + public: + //public members + MString m_name; + Material* m_pMaterial; + long m_numTriangles; + long m_numVertices; + std::vector m_indices; + std::vector m_vertices; + std::vector m_faces; + std::vector m_uvsets; + bool m_use32bitIndexes; + MDagPath m_dagPath; + BlendShape* m_pBlendShape; + MBoundingBox m_boundingBox; + }; }; // end of namespace diff --git a/Tools/MayaExport/include/vertex.h b/Tools/MayaExport/include/vertex.h index bb619ac88a4..33667524421 100644 --- a/Tools/MayaExport/include/vertex.h +++ b/Tools/MayaExport/include/vertex.h @@ -20,55 +20,55 @@ #define _VERTEX_H /***** structure for uvsets info *****/ - typedef struct uvsettag - { - short size; //number of coordinates (between 1 and 3) - } uvset; - /***** structure for texture coordinates *****/ - typedef struct texcoordstag - { - float u, v, w; //texture coordinates - } texcoord; + typedef struct uvsettag + { + short size; //number of coordinates (between 1 and 3) + } uvset; + /***** structure for texture coordinates *****/ + typedef struct texcoordstag + { + float u, v, w; //texture coordinates + } texcoord; - /***** structure for vertex bone assignements *****/ - typedef struct vbatag - { - float weight; //weight - int jointIdx; //index of associated joint - } vba; + /***** structure for vertex bone assignements *****/ + typedef struct vbatag + { + float weight; //weight + int jointIdx; //index of associated joint + } vba; - /***** structure for vertex data *****/ - typedef struct vertextag - { - double x, y, z; //vertex coordinates - MVector n; //vertex normal - float r,g,b,a; //vertex colour - std::vector texcoords; //vertex texture coordinates - std::vector vbas; //vertex bone assignements - long index; //vertex index in the maya mesh to which this vertex refers - } vertex; + /***** structure for vertex data *****/ + typedef struct vertextag + { + double x, y, z; //vertex coordinates + MVector n; //vertex normal + float r,g,b,a; //vertex colour + std::vector texcoords; //vertex texture coordinates + std::vector vbas; //vertex bone assignements + long index; //vertex index in the maya mesh to which this vertex refers + } vertex; - /***** structure for vertex info *****/ - // used to hold indices to access MFnMesh data - typedef struct vertexInfotag - { - int pointIdx; //index to points list (position) - int normalIdx; //index to normals list - float r,g,b,a; //colour - std::vector u; //u texture coordinates - std::vector v; //v texture coordinates - std::vector vba; //vertex bone assignements - std::vector jointIds; //ids of joints affecting this vertex - int next; //index of next vertex with same position - } vertexInfo; + /***** structure for vertex info *****/ + // used to hold indices to access MFnMesh data + typedef struct vertexInfotag + { + int pointIdx; //index to points list (position) + int normalIdx; //index to normals list + float r,g,b,a; //colour + std::vector u; //u texture coordinates + std::vector v; //v texture coordinates + std::vector vba; //vertex bone assignements + std::vector jointIds; //ids of joints affecting this vertex + int next; //index of next vertex with same position + } vertexInfo; - /***** structure for face info *****/ - typedef struct facetag - { - long v[3]; //vertex indices - } face; + /***** structure for face info *****/ + typedef struct facetag + { + long v[3]; //vertex indices + } face; - /***** array of face infos *****/ - typedef std::vector faceArray; + /***** array of face infos *****/ + typedef std::vector faceArray; #endif \ No newline at end of file diff --git a/Tools/MayaExport/src/blendshape.cpp b/Tools/MayaExport/src/blendshape.cpp index da99ca079e2..1b412965221 100644 --- a/Tools/MayaExport/src/blendshape.cpp +++ b/Tools/MayaExport/src/blendshape.cpp @@ -21,517 +21,517 @@ namespace OgreMayaExporter { - // Constructor - BlendShape::BlendShape() - { - m_pBlendShapeFn = NULL; - clear(); - } + // Constructor + BlendShape::BlendShape() + { + m_pBlendShapeFn = NULL; + clear(); + } - // Destructor - BlendShape::~BlendShape() - { - clear(); - } + // Destructor + BlendShape::~BlendShape() + { + clear(); + } - // Clear blend shape data - void BlendShape::clear() - { - if (m_pBlendShapeFn) - delete m_pBlendShapeFn; - m_pBlendShapeFn = NULL; - m_origEnvelope = 0; - m_origWeights.clear(); - m_poseGroups.clear(); - poseGroup pg; - pg.targetIndex = 0; - m_poseGroups.insert(std::pair(0, pg)); - m_target = T_MESH; - m_weightConnections.clear(); - } + // Clear blend shape data + void BlendShape::clear() + { + if (m_pBlendShapeFn) + delete m_pBlendShapeFn; + m_pBlendShapeFn = NULL; + m_origEnvelope = 0; + m_origWeights.clear(); + m_poseGroups.clear(); + poseGroup pg; + pg.targetIndex = 0; + m_poseGroups.insert(std::pair(0, pg)); + m_target = T_MESH; + m_weightConnections.clear(); + } - // Load blend shape deformer from Maya - MStatus BlendShape::load(MObject &blendShapeObj) - { - // Create a Fn for relative Maya blend shape deformer - m_pBlendShapeFn = new MFnBlendShapeDeformer(blendShapeObj); - // Save original envelope value for the deformer - m_origEnvelope = m_pBlendShapeFn->envelope(); - // Save original target weights - m_origWeights.clear(); - MIntArray indexList; - m_pBlendShapeFn->weightIndexList(indexList); - for (int i=0; iweight(indexList[i])); - } - return MS::kSuccess; - } + // Load blend shape deformer from Maya + MStatus BlendShape::load(MObject &blendShapeObj) + { + // Create a Fn for relative Maya blend shape deformer + m_pBlendShapeFn = new MFnBlendShapeDeformer(blendShapeObj); + // Save original envelope value for the deformer + m_origEnvelope = m_pBlendShapeFn->envelope(); + // Save original target weights + m_origWeights.clear(); + MIntArray indexList; + m_pBlendShapeFn->weightIndexList(indexList); + for (int i=0; iweight(indexList[i])); + } + return MS::kSuccess; + } - // Load blend shape poses for shared geometry - MStatus BlendShape::loadPosesShared(MDagPath& meshDag,ParamList ¶ms, - std::vector &vertices,long numVertices,long offset) - { - MStatus stat; - // Set blend shape target - m_target = T_MESH; - // Set blend shape deformer envelope to 1 to get target shapes - m_pBlendShapeFn->setEnvelope(1); - // Break connections on weights - breakConnections(); - // Set weight to 0 for all targets - MIntArray indexList; - m_pBlendShapeFn->weightIndexList(indexList); - for (int i=0; isetWeight(indexList[i],0); - if (MS::kSuccess != stat) - { - std::cout << "Error setting weight " << indexList[i] << " to 0 on blendhape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; - std::cout << stat.errorString().asChar() << "\n"; - std::cout.flush(); - } - } - // Get pose names - MStringArray poseNames; - MString cmd = "aliasAttr -q " + m_pBlendShapeFn->name(); - MGlobal::executeCommand(cmd,poseNames,false,false); - // Get all poses: set iteratively weight to 1 for current target shape and keep 0 for the other targets - for (int i=0; isetWeight(indexList[i],1); - if (MS::kSuccess != stat) - { - std::cout << "Error setting weight " << indexList[i] << " to 1 on blend shape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; - std::cout << stat.errorString().asChar() << "\n"; - std::cout.flush(); - } - // load the pose - stat = loadPoseShared(meshDag,params,vertices,numVertices,offset,poseName,i); - if (stat != MS::kSuccess) - { - std::cout << "Failed loading target pose " << indexList[i] << "\n"; - std::cout << stat.errorString().asChar(); - std::cout.flush(); - } - // set weight to 0 - stat = m_pBlendShapeFn->setWeight(indexList[i],0); - if (MS::kSuccess != stat) - { - std::cout << "Error resetting weight " << indexList[i] << " to 0 on blend shape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; - std::cout << stat.errorString().asChar() << "\n"; - std::cout.flush(); - } - } - // Set blend shape envelope to 0 - m_pBlendShapeFn->setEnvelope(0); - // Restore targets weights - for (int i=0; isetWeight(indexList[i],m_origWeights[i]); - } - // Restore connections on weights - restoreConnections(); - return MS::kSuccess; - } + // Load blend shape poses for shared geometry + MStatus BlendShape::loadPosesShared(MDagPath& meshDag,ParamList ¶ms, + std::vector &vertices,long numVertices,long offset) + { + MStatus stat; + // Set blend shape target + m_target = T_MESH; + // Set blend shape deformer envelope to 1 to get target shapes + m_pBlendShapeFn->setEnvelope(1); + // Break connections on weights + breakConnections(); + // Set weight to 0 for all targets + MIntArray indexList; + m_pBlendShapeFn->weightIndexList(indexList); + for (int i=0; isetWeight(indexList[i],0); + if (MS::kSuccess != stat) + { + std::cout << "Error setting weight " << indexList[i] << " to 0 on blendhape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; + std::cout << stat.errorString().asChar() << "\n"; + std::cout.flush(); + } + } + // Get pose names + MStringArray poseNames; + MString cmd = "aliasAttr -q " + m_pBlendShapeFn->name(); + MGlobal::executeCommand(cmd,poseNames,false,false); + // Get all poses: set iteratively weight to 1 for current target shape and keep 0 for the other targets + for (int i=0; isetWeight(indexList[i],1); + if (MS::kSuccess != stat) + { + std::cout << "Error setting weight " << indexList[i] << " to 1 on blend shape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; + std::cout << stat.errorString().asChar() << "\n"; + std::cout.flush(); + } + // load the pose + stat = loadPoseShared(meshDag,params,vertices,numVertices,offset,poseName,i); + if (stat != MS::kSuccess) + { + std::cout << "Failed loading target pose " << indexList[i] << "\n"; + std::cout << stat.errorString().asChar(); + std::cout.flush(); + } + // set weight to 0 + stat = m_pBlendShapeFn->setWeight(indexList[i],0); + if (MS::kSuccess != stat) + { + std::cout << "Error resetting weight " << indexList[i] << " to 0 on blend shape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; + std::cout << stat.errorString().asChar() << "\n"; + std::cout.flush(); + } + } + // Set blend shape envelope to 0 + m_pBlendShapeFn->setEnvelope(0); + // Restore targets weights + for (int i=0; isetWeight(indexList[i],m_origWeights[i]); + } + // Restore connections on weights + restoreConnections(); + return MS::kSuccess; + } - // Load blend shape poses for a submesh - MStatus BlendShape::loadPosesSubmesh(MDagPath& meshDag,ParamList ¶ms, - std::vector &vertices,std::vector& indices,long targetIndex) - { - MStatus stat; - // Set blend shape target - m_target = T_SUBMESH; - // Set blend shape deformer envelope to 1 to get target shapes - m_pBlendShapeFn->setEnvelope(1); - // Break connections on weights - breakConnections(); - // Set weight to 0 for all targets - MIntArray indexList; - m_pBlendShapeFn->weightIndexList(indexList); - for (int i=0; isetWeight(indexList[i],0); - if (MS::kSuccess != stat) - { - std::cout << "Error setting weight " << indexList[i] << " to 0 on blendhape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; - std::cout << stat.errorString().asChar() << "\n"; - std::cout.flush(); - } - } + // Load blend shape poses for a submesh + MStatus BlendShape::loadPosesSubmesh(MDagPath& meshDag,ParamList ¶ms, + std::vector &vertices,std::vector& indices,long targetIndex) + { + MStatus stat; + // Set blend shape target + m_target = T_SUBMESH; + // Set blend shape deformer envelope to 1 to get target shapes + m_pBlendShapeFn->setEnvelope(1); + // Break connections on weights + breakConnections(); + // Set weight to 0 for all targets + MIntArray indexList; + m_pBlendShapeFn->weightIndexList(indexList); + for (int i=0; isetWeight(indexList[i],0); + if (MS::kSuccess != stat) + { + std::cout << "Error setting weight " << indexList[i] << " to 0 on blendhape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; + std::cout << stat.errorString().asChar() << "\n"; + std::cout.flush(); + } + } - // Get pose names - MStringArray poseNames; - MString cmd = "aliasAttr -q " + m_pBlendShapeFn->name(); - MGlobal::executeCommand(cmd,poseNames,false,false); - // Get all poses: set iteratively weight to 1 for current target shape and keep 0 for the other targets - poseGroup pg; - pg.targetIndex = targetIndex; - m_poseGroups.insert(std::pair(targetIndex,pg)); - for (int i=0; isetWeight(indexList[i],1); - if (MS::kSuccess != stat) - { - std::cout << "Error setting weight " << indexList[i] << " to 1 on blend shape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; - std::cout << stat.errorString().asChar() << "\n"; - std::cout.flush(); - } - // load the pose - stat = loadPoseSubmesh(meshDag,params,vertices,indices,poseName,targetIndex,i); - if (stat != MS::kSuccess) - { - std::cout << "Failed loading target pose " << indexList[i] << "\n"; - std::cout << stat.errorString().asChar(); - std::cout.flush(); - } - // set weight to 0 - stat = m_pBlendShapeFn->setWeight(indexList[i],0); - if (MS::kSuccess != stat) - { - std::cout << "Error resetting weight " << indexList[i] << " to 0 on blend shape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; - std::cout << stat.errorString().asChar() << "\n"; - std::cout.flush(); - } - } - // Set blend shape envelope to 0 - m_pBlendShapeFn->setEnvelope(0); - // Restore targets weights - for (int i=0; isetWeight(indexList[i],m_origWeights[i]); - } - // Restore connections on weights - restoreConnections(); - return MS::kSuccess; - } + // Get pose names + MStringArray poseNames; + MString cmd = "aliasAttr -q " + m_pBlendShapeFn->name(); + MGlobal::executeCommand(cmd,poseNames,false,false); + // Get all poses: set iteratively weight to 1 for current target shape and keep 0 for the other targets + poseGroup pg; + pg.targetIndex = targetIndex; + m_poseGroups.insert(std::pair(targetIndex,pg)); + for (int i=0; isetWeight(indexList[i],1); + if (MS::kSuccess != stat) + { + std::cout << "Error setting weight " << indexList[i] << " to 1 on blend shape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; + std::cout << stat.errorString().asChar() << "\n"; + std::cout.flush(); + } + // load the pose + stat = loadPoseSubmesh(meshDag,params,vertices,indices,poseName,targetIndex,i); + if (stat != MS::kSuccess) + { + std::cout << "Failed loading target pose " << indexList[i] << "\n"; + std::cout << stat.errorString().asChar(); + std::cout.flush(); + } + // set weight to 0 + stat = m_pBlendShapeFn->setWeight(indexList[i],0); + if (MS::kSuccess != stat) + { + std::cout << "Error resetting weight " << indexList[i] << " to 0 on blend shape deformer " << m_pBlendShapeFn->name().asChar() << "\n"; + std::cout << stat.errorString().asChar() << "\n"; + std::cout.flush(); + } + } + // Set blend shape envelope to 0 + m_pBlendShapeFn->setEnvelope(0); + // Restore targets weights + for (int i=0; isetWeight(indexList[i],m_origWeights[i]); + } + // Restore connections on weights + restoreConnections(); + return MS::kSuccess; + } - // Load a single blend shape pose for shared geometry - MStatus BlendShape::loadPoseShared(MDagPath& meshDag,ParamList ¶ms,std::vector &vertices, - long numVertices,long offset,MString poseName,int blendShapeIndex) - { - // get the mesh Fn - MFnMesh mesh(meshDag); - // get pose group - poseGroup& pg = m_poseGroups.find(0)->second; - // create a new pose - pose p; - p.poseTarget = m_target; - p.index = 0; - p.blendShapeIndex = blendShapeIndex; - p.name = poseName.asChar(); - // get vertex positions - MFloatPointArray points; - if (params.exportWorldCoords) - mesh.getPoints(points,MSpace::kWorld); - else - mesh.getPoints(points,MSpace::kObject); - // calculate vertex offsets - for (int i=0; i 0) - pg.poses.push_back(p); - if (params.bsBB) - { - // update bounding boxes of loaded submeshes - for (int i=0; im_dagPath); - MPoint min = mesh.boundingBox().min(); - MPoint max = mesh.boundingBox().max(); - MBoundingBox bbox(min,max); - if (params.exportWorldCoords) - bbox.transformUsing(params.loadedSubmeshes[i]->m_dagPath.inclusiveMatrix()); - min = bbox.min() * params.lum; - max = bbox.max() * params.lum; - MBoundingBox newbbox(min,max); - params.loadedSubmeshes[i]->m_boundingBox.expand(newbbox); - } - } - // pose loaded succesfully - return MS::kSuccess; - } + // Load a single blend shape pose for shared geometry + MStatus BlendShape::loadPoseShared(MDagPath& meshDag,ParamList ¶ms,std::vector &vertices, + long numVertices,long offset,MString poseName,int blendShapeIndex) + { + // get the mesh Fn + MFnMesh mesh(meshDag); + // get pose group + poseGroup& pg = m_poseGroups.find(0)->second; + // create a new pose + pose p; + p.poseTarget = m_target; + p.index = 0; + p.blendShapeIndex = blendShapeIndex; + p.name = poseName.asChar(); + // get vertex positions + MFloatPointArray points; + if (params.exportWorldCoords) + mesh.getPoints(points,MSpace::kWorld); + else + mesh.getPoints(points,MSpace::kObject); + // calculate vertex offsets + for (int i=0; i 0) + pg.poses.push_back(p); + if (params.bsBB) + { + // update bounding boxes of loaded submeshes + for (int i=0; im_dagPath); + MPoint min = mesh.boundingBox().min(); + MPoint max = mesh.boundingBox().max(); + MBoundingBox bbox(min,max); + if (params.exportWorldCoords) + bbox.transformUsing(params.loadedSubmeshes[i]->m_dagPath.inclusiveMatrix()); + min = bbox.min() * params.lum; + max = bbox.max() * params.lum; + MBoundingBox newbbox(min,max); + params.loadedSubmeshes[i]->m_boundingBox.expand(newbbox); + } + } + // pose loaded succesfully + return MS::kSuccess; + } - // Load a single blend shape pose for a submesh - MStatus BlendShape::loadPoseSubmesh(MDagPath& meshDag,ParamList ¶ms,std::vector& vertices, - std::vector& indices,MString poseName,int targetIndex,int blendShapeIndex) - { - // get the mesh Fn - MFnMesh mesh(meshDag); - // get pose group - poseGroup& pg = m_poseGroups.find(targetIndex)->second; - // create a new pose - pose p; - p.poseTarget = m_target; - p.index = targetIndex; - p.blendShapeIndex = blendShapeIndex; - p.name = poseName.asChar(); - // get vertex positions - MFloatPointArray points; - if (params.exportWorldCoords) - mesh.getPoints(points,MSpace::kWorld); - else - mesh.getPoints(points,MSpace::kObject); - // calculate vertex offsets - for (int i=0; i 0) - pg.poses.push_back(p); - if (params.bsBB) - { - // update bounding boxes of loaded submeshes - for (int i=0; im_dagPath); - MPoint min = mesh.boundingBox().min(); - MPoint max = mesh.boundingBox().max(); - MBoundingBox bbox(min,max); - if (params.exportWorldCoords) - bbox.transformUsing(params.loadedSubmeshes[i]->m_dagPath.inclusiveMatrix()); - min = bbox.min() * params.lum; - max = bbox.max() * params.lum; - MBoundingBox newbbox(min,max); - params.loadedSubmeshes[i]->m_boundingBox.expand(newbbox); - } - } - // pose loaded succesfully - return MS::kSuccess; - } + // Load a single blend shape pose for a submesh + MStatus BlendShape::loadPoseSubmesh(MDagPath& meshDag,ParamList ¶ms,std::vector& vertices, + std::vector& indices,MString poseName,int targetIndex,int blendShapeIndex) + { + // get the mesh Fn + MFnMesh mesh(meshDag); + // get pose group + poseGroup& pg = m_poseGroups.find(targetIndex)->second; + // create a new pose + pose p; + p.poseTarget = m_target; + p.index = targetIndex; + p.blendShapeIndex = blendShapeIndex; + p.name = poseName.asChar(); + // get vertex positions + MFloatPointArray points; + if (params.exportWorldCoords) + mesh.getPoints(points,MSpace::kWorld); + else + mesh.getPoints(points,MSpace::kObject); + // calculate vertex offsets + for (int i=0; i 0) + pg.poses.push_back(p); + if (params.bsBB) + { + // update bounding boxes of loaded submeshes + for (int i=0; im_dagPath); + MPoint min = mesh.boundingBox().min(); + MPoint max = mesh.boundingBox().max(); + MBoundingBox bbox(min,max); + if (params.exportWorldCoords) + bbox.transformUsing(params.loadedSubmeshes[i]->m_dagPath.inclusiveMatrix()); + min = bbox.min() * params.lum; + max = bbox.max() * params.lum; + MBoundingBox newbbox(min,max); + params.loadedSubmeshes[i]->m_boundingBox.expand(newbbox); + } + } + // pose loaded succesfully + return MS::kSuccess; + } - // Load a blend shape animation track - Track BlendShape::loadTrack(float start,float stop,float rate,ParamList& params,int targetIndex,int startPoseId) - { - MStatus stat; - MString msg; - std::vector times; - // Create a track for current clip - Track t; - t.m_type = TT_POSE; - t.m_target = m_target; - t.m_index = targetIndex; - t.m_vertexKeyframes.clear(); - // Calculate times from clip sample rate - times.clear(); - if (rate <= 0) - { - std::cout << "invalid sample rate for the clip (must be >0), we skip it\n"; - std::cout.flush(); - return t; - } - for (float time=start; time= 0) - length = times[times.size()-1] - times[0]; - if (length < 0) - { - std::cout << "invalid time range for the clip, we skip it\n"; - std::cout.flush(); - return t; - } - // Evaluate animation curves at selected times - for (int i=0; i 0) - t.addVertexKeyframe(key); - } - // Clip successfully loaded - return t; - } + // Load a blend shape animation track + Track BlendShape::loadTrack(float start,float stop,float rate,ParamList& params,int targetIndex,int startPoseId) + { + MStatus stat; + MString msg; + std::vector times; + // Create a track for current clip + Track t; + t.m_type = TT_POSE; + t.m_target = m_target; + t.m_index = targetIndex; + t.m_vertexKeyframes.clear(); + // Calculate times from clip sample rate + times.clear(); + if (rate <= 0) + { + std::cout << "invalid sample rate for the clip (must be >0), we skip it\n"; + std::cout.flush(); + return t; + } + for (float time=start; time= 0) + length = times[times.size()-1] - times[0]; + if (length < 0) + { + std::cout << "invalid time range for the clip, we skip it\n"; + std::cout.flush(); + return t; + } + // Evaluate animation curves at selected times + for (int i=0; i 0) + t.addVertexKeyframe(key); + } + // Clip successfully loaded + return t; + } - // Load a blend shape animation keyframe - vertexKeyframe BlendShape::loadKeyframe(float time,ParamList& params,int targetIndex, int startPoseId) - { - poseGroup& pg = m_poseGroups.find(targetIndex)->second; - // Create keyframe - vertexKeyframe key; - key.time = time; - key.poserefs.clear(); - // Read weights of all poses at current time - // Get blend shape deformer envelope - float envelope = m_pBlendShapeFn->envelope(); - // Get weights of all targets - MIntArray indexList; - m_pBlendShapeFn->weightIndexList(indexList); - for (int i=0; iweight(indexList[p.blendShapeIndex]); - key.poserefs.push_back(poseref); - } - return key; - } + // Load a blend shape animation keyframe + vertexKeyframe BlendShape::loadKeyframe(float time,ParamList& params,int targetIndex, int startPoseId) + { + poseGroup& pg = m_poseGroups.find(targetIndex)->second; + // Create keyframe + vertexKeyframe key; + key.time = time; + key.poserefs.clear(); + // Read weights of all poses at current time + // Get blend shape deformer envelope + float envelope = m_pBlendShapeFn->envelope(); + // Get weights of all targets + MIntArray indexList; + m_pBlendShapeFn->weightIndexList(indexList); + for (int i=0; iweight(indexList[p.blendShapeIndex]); + key.poserefs.push_back(poseref); + } + return key; + } - // Get blend shape deformer name - MString BlendShape::getName() - { - return m_pBlendShapeFn->name(); - } + // Get blend shape deformer name + MString BlendShape::getName() + { + return m_pBlendShapeFn->name(); + } - // Get blend shape poses - stdext::hash_map& BlendShape::getPoseGroups() - { - return m_poseGroups; - } + // Get blend shape poses + stdext::hash_map& BlendShape::getPoseGroups() + { + return m_poseGroups; + } - // Set maya blend shape deformer envelope - void BlendShape::setEnvelope(float envelope) - { - m_pBlendShapeFn->setEnvelope(envelope); - } - // Restore maya blend shape deformer original envelope - void BlendShape::restoreEnvelope() - { - m_pBlendShapeFn->setEnvelope(m_origEnvelope); - } - // Break connections to this blendshape - void BlendShape::breakConnections() - { - MStatus stat; - MDagModifier dagModifier; - // Clear the stored connections - m_weightConnections.clear(); - // Save node connections and break them - MPlug weightsPlug = m_pBlendShapeFn->findPlug("weight",true); - for (int i=0; isetEnvelope(envelope); + } + // Restore maya blend shape deformer original envelope + void BlendShape::restoreEnvelope() + { + m_pBlendShapeFn->setEnvelope(m_origEnvelope); + } + // Break connections to this blendshape + void BlendShape::breakConnections() + { + MStatus stat; + MDagModifier dagModifier; + // Clear the stored connections + m_weightConnections.clear(); + // Save node connections and break them + MPlug weightsPlug = m_pBlendShapeFn->findPlug("weight",true); + for (int i=0; ifindPlug("weight",true); - for (int i=0; ifindPlug("weight",true); + for (int i=0; iname(); - MStringArray tmpStrArray; - tmpStr.split(':',tmpStrArray); - m_name = ""; - for (int i=0; iobject().hasFn(MFn::kPhong)) - { - stat = loadPhong(pShader); - } - else if (pShader->object().hasFn(MFn::kBlinn)) - { - stat = loadBlinn(pShader); - } - else if (pShader->object().hasFn(MFn::kLambert)) - { - stat = loadLambert(pShader); - } - else if (pShader->object().hasFn(MFn::kPluginHwShaderNode)) - { - stat = loadCgFxShader(pShader); - } - else - { - stat = loadSurfaceShader(pShader); - } - - // Get textures data - MPlugArray colorSrcPlugs; - MPlugArray texSrcPlugs; - MPlugArray placetexSrcPlugs; - if (m_isTextured) - { - // Translate multiple textures if material is multitextured - if (m_isMultiTextured) - { - // Get layered texture node - MFnDependencyNode* pLayeredTexNode = NULL; - if (m_type == MT_SURFACE_SHADER) - pShader->findPlug("outColor").connectedTo(colorSrcPlugs,true,false); - else - pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false); - for (int i=0; ifindPlug("inputs"); - - // Scan inputs and export textures - for (int i=inputsPlug.numElements()-1; i>=0; i--) - { - MFnDependencyNode* pTextureNode = NULL; - // Search for a connected texture - inputsPlug[i].child(0).connectedTo(colorSrcPlugs,true,false); - for (int j=0; jfindPlug("outColor").connectedTo(colorSrcPlugs,true,false); - else - pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false); - for (int i=0; ifindPlug("outColor").connectedTo(colorSrcPlugs,true,false); - for (int i=0; ifindPlug("outTransparencyR").getValue(trasp); - if (pShader->findPlug("outTransparency").isConnected() || trasp>0.0f) - m_isTransparent = true; - - // Get material colours - if (m_isTextured) - m_diffuse = MColor(1.0,1.0,1.0,1.0); - else - { - pShader->findPlug("outColorR").getValue(m_diffuse.r); - pShader->findPlug("outColorG").getValue(m_diffuse.g); - pShader->findPlug("outColorB").getValue(m_diffuse.b); - float trasp; - pShader->findPlug("outTransparencyR").getValue(trasp); - m_diffuse.a = 1.0 - trasp; - } - m_ambient = MColor(0,0,0,1); - m_emissive = MColor(0,0,0,1); - m_specular = MColor(0,0,0,1); - return MS::kSuccess; - } - - // Load a lambert shader - MStatus Material::loadLambert(MFnDependencyNode *pShader) - { - MPlugArray colorSrcPlugs; - m_type = MT_LAMBERT; - MFnLambertShader* pLambert = new MFnLambertShader(pShader->object()); - // Check if material is textured - pLambert->findPlug("color").connectedTo(colorSrcPlugs,true,false); - for (int i=0; ifindPlug("transparency").isConnected() || pLambert->transparency().r>0.0f) - m_isTransparent = true; - - // Get material colours - //diffuse colour - if (m_isTextured) - m_diffuse = MColor(1.0,1.0,1.0,1.0); - else - { - m_diffuse = pLambert->color(); - m_diffuse.a = 1.0 - pLambert->transparency().r; - } - //ambient colour - m_ambient = pLambert->ambientColor(); - //emissive colour - m_emissive = pLambert->incandescence(); - //specular colour - m_specular = MColor(0,0,0,1); - delete pLambert; - return MS::kSuccess; - } - - // Load a phong shader - MStatus Material::loadPhong(MFnDependencyNode *pShader) - { - MPlugArray colorSrcPlugs; - m_type = MT_PHONG; - MFnPhongShader* pPhong = new MFnPhongShader(pShader->object()); - // Check if material is textured - pPhong->findPlug("color").connectedTo(colorSrcPlugs,true,false); - for (int i=0; ifindPlug("transparency").isConnected() || pPhong->transparency().r>0.0f) - m_isTransparent = true; - - // Get material colours - //diffuse colour - if (m_isTextured) - m_diffuse = MColor(1.0,1.0,1.0,1.0); - else - { - m_diffuse = pPhong->color(); - m_diffuse.a = 1.0 - pPhong->transparency().r; - } - //ambient colour - m_ambient = pPhong->ambientColor(); - //emissive colour - m_emissive = pPhong->incandescence(); - //specular colour - m_specular = pPhong->specularColor(); - m_specular.a = pPhong->cosPower()*1.28; - delete pPhong; - return MS::kSuccess; - } - - // load a blinn shader - MStatus Material::loadBlinn(MFnDependencyNode *pShader) - { - MPlugArray colorSrcPlugs; - m_type = MT_BLINN; - MFnBlinnShader* pBlinn = new MFnBlinnShader(pShader->object()); - // Check if material is textured - pBlinn->findPlug("color").connectedTo(colorSrcPlugs,true,false); - for (int i=0; ifindPlug("transparency").isConnected() || pBlinn->transparency().r>0.0f) - m_isTransparent = true; - - // Get material colours - //diffuse colour - if (m_isTextured) - m_diffuse = MColor(1.0,1.0,1.0,1.0); - else - { - m_diffuse = pBlinn->color(); - m_diffuse.a = 1.0 - pBlinn->transparency().r; - } - //ambient colour - m_ambient = pBlinn->ambientColor(); - //emissive colour - m_emissive = pBlinn->incandescence(); - //specular colour - m_specular = pBlinn->specularColor(); - m_specular.a = 128.0-(128.0*pBlinn->eccentricity()); - delete pBlinn; - return MS::kSuccess; - } - - // load a cgFx shader - MStatus Material::loadCgFxShader(MFnDependencyNode *pShader) - { - m_type = MT_CGFX; - // Create a default white lambert - m_isTextured = false; - m_isMultiTextured = false; - m_diffuse = MColor(1.0,1.0,1.0,1.0); - m_specular = MColor(0,0,0,1); - m_emissive = MColor(0,0,0,1); - m_ambient = MColor(0,0,0,1); - return MS::kSuccess; - } - - // Load texture data from a texture node - MStatus Material::loadTexture(MFnDependencyNode* pTexNode,TexOpType& opType,MStringArray& uvsets,ParamList& params) - { - Texture tex; - // Get texture filename - MString filename, absFilename; - MRenderUtil::exactFileTextureName(pTexNode->object(),absFilename); - filename = absFilename.substring(absFilename.rindex('/')+1,absFilename.length()-1); - MString command = "toNativePath(\""; - command += absFilename; - command += "\")"; - MGlobal::executeCommand(command,absFilename); - tex.absFilename = absFilename; - tex.filename = filename; - tex.uvsetIndex = 0; - tex.uvsetName = ""; - // Set texture operation type - tex.opType = opType; - // Get connections to uvCoord attribute of texture node - MPlugArray texSrcPlugs; - pTexNode->findPlug("uvCoord").connectedTo(texSrcPlugs,true,false); - // Get place2dtexture node (if connected) - MFnDependencyNode* pPlace2dTexNode = NULL; - for (int j=0; jfindPlug("uvCoord").connectedTo(placetexSrcPlugs,true,false); - for (int j=0; jfindPlug("uvSets"); - MPlugArray uvsetsSrcPlugs; - for (int i=0; ifindPlug("wrapU").getValue(wrapU); - pPlace2dTexNode->findPlug("mirrorU").getValue(mirrorU); - if (mirrorU) - tex.am_u = TAM_MIRROR; - else if (wrapU) - tex.am_u = TAM_WRAP; - else - tex.am_u = TAM_CLAMP; - // V - bool wrapV,mirrorV; - pPlace2dTexNode->findPlug("wrapV").getValue(wrapV); - pPlace2dTexNode->findPlug("mirrorV").getValue(mirrorV); - if (mirrorV) - tex.am_v = TAM_MIRROR; - else if (wrapV) - tex.am_v = TAM_WRAP; - else - tex.am_v = TAM_CLAMP; - // Get texture scale - double covU,covV; - pPlace2dTexNode->findPlug("coverageU").getValue(covU); - pPlace2dTexNode->findPlug("coverageV").getValue(covV); - tex.scale_u = covU; - if (fabs(tex.scale_u) < PRECISION) - tex.scale_u = 0; - tex.scale_v = covV; - if (fabs(tex.scale_v) < PRECISION) - tex.scale_v = 0; - // Get texture scroll - double transU,transV; - pPlace2dTexNode->findPlug("translateFrameU").getValue(transU); - pPlace2dTexNode->findPlug("translateFrameV").getValue(transV); - tex.scroll_u = -0.5 * (covU-1.0)/covU - transU/covU; - if (fabs(tex.scroll_u) < PRECISION) - tex.scroll_u = 0; - tex.scroll_v = 0.5 * (covV-1.0)/covV + transV/covV; - if (fabs(tex.scroll_v) < PRECISION) - tex.scroll_v = 0; - // Get texture rotation - double rot; - pPlace2dTexNode->findPlug("rotateFrame").getValue(rot); - tex.rot = -rot; - if (fabs(rot) < PRECISION) - tex.rot = 0; - } - // add texture to material texture list - m_textures.push_back(tex); - // free up memory - if (pUvChooserNode) - delete pUvChooserNode; - if (pPlace2dTexNode) - delete pPlace2dTexNode; - - return MS::kSuccess; - } - - - // Write material data to an Ogre material script file - MStatus Material::writeOgreScript(ParamList ¶ms) - { - //Start material description - params.outMaterial << "material " << m_name.asChar() << "\n"; - params.outMaterial << "{\n"; - - //Start technique description - params.outMaterial << "\ttechnique\n"; - params.outMaterial << "\t{\n"; - - //Start render pass description - params.outMaterial << "\t\tpass\n"; - params.outMaterial << "\t\t{\n"; - //set lighting off option if requested - if (m_lightingOff) - params.outMaterial << "\t\t\tlighting off\n\n"; - //set phong shading if requested (default is gouraud) - if (m_type == MT_PHONG) - params.outMaterial << "\t\t\tshading phong\n"; - //ambient colour - params.outMaterial << "\t\t\tambient " << m_ambient.r << " " << m_ambient.g << " " << m_ambient.b - << " " << m_ambient.a << "\n"; - //diffuse colour - params.outMaterial << "\t\t\tdiffuse " << m_diffuse.r << " " << m_diffuse.g << " " << m_diffuse.b - << " " << m_diffuse.a << "\n"; - //specular colour - params.outMaterial << "\t\t\tspecular " << m_specular.r << " " << m_specular.g << " " << m_specular.b - << " " << m_specular.a << "\n"; - //emissive colour - params.outMaterial << "\t\t\temissive " << m_emissive.r << " " << m_emissive.g << " " - << m_emissive.b << "\n"; - //if material is transparent set blend mode and turn off depth_writing - if (m_isTransparent) - { - params.outMaterial << "\n\t\t\tscene_blend alpha_blend\n"; - params.outMaterial << "\t\t\tdepth_write off\n"; - } - //write texture units - for (int i=0; iname(); + MStringArray tmpStrArray; + tmpStr.split(':',tmpStrArray); + m_name = ""; + for (int i=0; iobject().hasFn(MFn::kPhong)) + { + stat = loadPhong(pShader); + } + else if (pShader->object().hasFn(MFn::kBlinn)) + { + stat = loadBlinn(pShader); + } + else if (pShader->object().hasFn(MFn::kLambert)) + { + stat = loadLambert(pShader); + } + else if (pShader->object().hasFn(MFn::kPluginHwShaderNode)) + { + stat = loadCgFxShader(pShader); + } + else + { + stat = loadSurfaceShader(pShader); + } + + // Get textures data + MPlugArray colorSrcPlugs; + MPlugArray texSrcPlugs; + MPlugArray placetexSrcPlugs; + if (m_isTextured) + { + // Translate multiple textures if material is multitextured + if (m_isMultiTextured) + { + // Get layered texture node + MFnDependencyNode* pLayeredTexNode = NULL; + if (m_type == MT_SURFACE_SHADER) + pShader->findPlug("outColor").connectedTo(colorSrcPlugs,true,false); + else + pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false); + for (int i=0; ifindPlug("inputs"); + + // Scan inputs and export textures + for (int i=inputsPlug.numElements()-1; i>=0; i--) + { + MFnDependencyNode* pTextureNode = NULL; + // Search for a connected texture + inputsPlug[i].child(0).connectedTo(colorSrcPlugs,true,false); + for (int j=0; jfindPlug("outColor").connectedTo(colorSrcPlugs,true,false); + else + pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false); + for (int i=0; ifindPlug("outColor").connectedTo(colorSrcPlugs,true,false); + for (int i=0; ifindPlug("outTransparencyR").getValue(trasp); + if (pShader->findPlug("outTransparency").isConnected() || trasp>0.0f) + m_isTransparent = true; + + // Get material colours + if (m_isTextured) + m_diffuse = MColor(1.0,1.0,1.0,1.0); + else + { + pShader->findPlug("outColorR").getValue(m_diffuse.r); + pShader->findPlug("outColorG").getValue(m_diffuse.g); + pShader->findPlug("outColorB").getValue(m_diffuse.b); + float trasp; + pShader->findPlug("outTransparencyR").getValue(trasp); + m_diffuse.a = 1.0 - trasp; + } + m_ambient = MColor(0,0,0,1); + m_emissive = MColor(0,0,0,1); + m_specular = MColor(0,0,0,1); + return MS::kSuccess; + } + + // Load a lambert shader + MStatus Material::loadLambert(MFnDependencyNode *pShader) + { + MPlugArray colorSrcPlugs; + m_type = MT_LAMBERT; + MFnLambertShader* pLambert = new MFnLambertShader(pShader->object()); + // Check if material is textured + pLambert->findPlug("color").connectedTo(colorSrcPlugs,true,false); + for (int i=0; ifindPlug("transparency").isConnected() || pLambert->transparency().r>0.0f) + m_isTransparent = true; + + // Get material colours + //diffuse colour + if (m_isTextured) + m_diffuse = MColor(1.0,1.0,1.0,1.0); + else + { + m_diffuse = pLambert->color(); + m_diffuse.a = 1.0 - pLambert->transparency().r; + } + //ambient colour + m_ambient = pLambert->ambientColor(); + //emissive colour + m_emissive = pLambert->incandescence(); + //specular colour + m_specular = MColor(0,0,0,1); + delete pLambert; + return MS::kSuccess; + } + + // Load a phong shader + MStatus Material::loadPhong(MFnDependencyNode *pShader) + { + MPlugArray colorSrcPlugs; + m_type = MT_PHONG; + MFnPhongShader* pPhong = new MFnPhongShader(pShader->object()); + // Check if material is textured + pPhong->findPlug("color").connectedTo(colorSrcPlugs,true,false); + for (int i=0; ifindPlug("transparency").isConnected() || pPhong->transparency().r>0.0f) + m_isTransparent = true; + + // Get material colours + //diffuse colour + if (m_isTextured) + m_diffuse = MColor(1.0,1.0,1.0,1.0); + else + { + m_diffuse = pPhong->color(); + m_diffuse.a = 1.0 - pPhong->transparency().r; + } + //ambient colour + m_ambient = pPhong->ambientColor(); + //emissive colour + m_emissive = pPhong->incandescence(); + //specular colour + m_specular = pPhong->specularColor(); + m_specular.a = pPhong->cosPower()*1.28; + delete pPhong; + return MS::kSuccess; + } + + // load a blinn shader + MStatus Material::loadBlinn(MFnDependencyNode *pShader) + { + MPlugArray colorSrcPlugs; + m_type = MT_BLINN; + MFnBlinnShader* pBlinn = new MFnBlinnShader(pShader->object()); + // Check if material is textured + pBlinn->findPlug("color").connectedTo(colorSrcPlugs,true,false); + for (int i=0; ifindPlug("transparency").isConnected() || pBlinn->transparency().r>0.0f) + m_isTransparent = true; + + // Get material colours + //diffuse colour + if (m_isTextured) + m_diffuse = MColor(1.0,1.0,1.0,1.0); + else + { + m_diffuse = pBlinn->color(); + m_diffuse.a = 1.0 - pBlinn->transparency().r; + } + //ambient colour + m_ambient = pBlinn->ambientColor(); + //emissive colour + m_emissive = pBlinn->incandescence(); + //specular colour + m_specular = pBlinn->specularColor(); + m_specular.a = 128.0-(128.0*pBlinn->eccentricity()); + delete pBlinn; + return MS::kSuccess; + } + + // load a cgFx shader + MStatus Material::loadCgFxShader(MFnDependencyNode *pShader) + { + m_type = MT_CGFX; + // Create a default white lambert + m_isTextured = false; + m_isMultiTextured = false; + m_diffuse = MColor(1.0,1.0,1.0,1.0); + m_specular = MColor(0,0,0,1); + m_emissive = MColor(0,0,0,1); + m_ambient = MColor(0,0,0,1); + return MS::kSuccess; + } + + // Load texture data from a texture node + MStatus Material::loadTexture(MFnDependencyNode* pTexNode,TexOpType& opType,MStringArray& uvsets,ParamList& params) + { + Texture tex; + // Get texture filename + MString filename, absFilename; + MRenderUtil::exactFileTextureName(pTexNode->object(),absFilename); + filename = absFilename.substring(absFilename.rindex('/')+1,absFilename.length()-1); + MString command = "toNativePath(\""; + command += absFilename; + command += "\")"; + MGlobal::executeCommand(command,absFilename); + tex.absFilename = absFilename; + tex.filename = filename; + tex.uvsetIndex = 0; + tex.uvsetName = ""; + // Set texture operation type + tex.opType = opType; + // Get connections to uvCoord attribute of texture node + MPlugArray texSrcPlugs; + pTexNode->findPlug("uvCoord").connectedTo(texSrcPlugs,true,false); + // Get place2dtexture node (if connected) + MFnDependencyNode* pPlace2dTexNode = NULL; + for (int j=0; jfindPlug("uvCoord").connectedTo(placetexSrcPlugs,true,false); + for (int j=0; jfindPlug("uvSets"); + MPlugArray uvsetsSrcPlugs; + for (int i=0; ifindPlug("wrapU").getValue(wrapU); + pPlace2dTexNode->findPlug("mirrorU").getValue(mirrorU); + if (mirrorU) + tex.am_u = TAM_MIRROR; + else if (wrapU) + tex.am_u = TAM_WRAP; + else + tex.am_u = TAM_CLAMP; + // V + bool wrapV,mirrorV; + pPlace2dTexNode->findPlug("wrapV").getValue(wrapV); + pPlace2dTexNode->findPlug("mirrorV").getValue(mirrorV); + if (mirrorV) + tex.am_v = TAM_MIRROR; + else if (wrapV) + tex.am_v = TAM_WRAP; + else + tex.am_v = TAM_CLAMP; + // Get texture scale + double covU,covV; + pPlace2dTexNode->findPlug("coverageU").getValue(covU); + pPlace2dTexNode->findPlug("coverageV").getValue(covV); + tex.scale_u = covU; + if (fabs(tex.scale_u) < PRECISION) + tex.scale_u = 0; + tex.scale_v = covV; + if (fabs(tex.scale_v) < PRECISION) + tex.scale_v = 0; + // Get texture scroll + double transU,transV; + pPlace2dTexNode->findPlug("translateFrameU").getValue(transU); + pPlace2dTexNode->findPlug("translateFrameV").getValue(transV); + tex.scroll_u = -0.5 * (covU-1.0)/covU - transU/covU; + if (fabs(tex.scroll_u) < PRECISION) + tex.scroll_u = 0; + tex.scroll_v = 0.5 * (covV-1.0)/covV + transV/covV; + if (fabs(tex.scroll_v) < PRECISION) + tex.scroll_v = 0; + // Get texture rotation + double rot; + pPlace2dTexNode->findPlug("rotateFrame").getValue(rot); + tex.rot = -rot; + if (fabs(rot) < PRECISION) + tex.rot = 0; + } + // add texture to material texture list + m_textures.push_back(tex); + // free up memory + if (pUvChooserNode) + delete pUvChooserNode; + if (pPlace2dTexNode) + delete pPlace2dTexNode; + + return MS::kSuccess; + } + + + // Write material data to an Ogre material script file + MStatus Material::writeOgreScript(ParamList ¶ms) + { + //Start material description + params.outMaterial << "material " << m_name.asChar() << "\n"; + params.outMaterial << "{\n"; + + //Start technique description + params.outMaterial << "\ttechnique\n"; + params.outMaterial << "\t{\n"; + + //Start render pass description + params.outMaterial << "\t\tpass\n"; + params.outMaterial << "\t\t{\n"; + //set lighting off option if requested + if (m_lightingOff) + params.outMaterial << "\t\t\tlighting off\n\n"; + //set phong shading if requested (default is gouraud) + if (m_type == MT_PHONG) + params.outMaterial << "\t\t\tshading phong\n"; + //ambient colour + params.outMaterial << "\t\t\tambient " << m_ambient.r << " " << m_ambient.g << " " << m_ambient.b + << " " << m_ambient.a << "\n"; + //diffuse colour + params.outMaterial << "\t\t\tdiffuse " << m_diffuse.r << " " << m_diffuse.g << " " << m_diffuse.b + << " " << m_diffuse.a << "\n"; + //specular colour + params.outMaterial << "\t\t\tspecular " << m_specular.r << " " << m_specular.g << " " << m_specular.b + << " " << m_specular.a << "\n"; + //emissive colour + params.outMaterial << "\t\t\temissive " << m_emissive.r << " " << m_emissive.g << " " + << m_emissive.b << "\n"; + //if material is transparent set blend mode and turn off depth_writing + if (m_isTransparent) + { + params.outMaterial << "\n\t\t\tscene_blend alpha_blend\n"; + params.outMaterial << "\t\t\tdepth_write off\n"; + } + //write texture units + for (int i=0; i MaterialSet* Singleton::msSingleton = 0; -}; //end namespace \ No newline at end of file + template<> MaterialSet* Singleton::msSingleton = 0; +}; //end namespace \ No newline at end of file diff --git a/Tools/MayaExport/src/mesh.cpp b/Tools/MayaExport/src/mesh.cpp index 62376505aa6..959c865c5b3 100644 --- a/Tools/MayaExport/src/mesh.cpp +++ b/Tools/MayaExport/src/mesh.cpp @@ -21,1574 +21,1574 @@ namespace OgreMayaExporter { - /***** Class Mesh *****/ - // constructor - Mesh::Mesh(const MString& name) - { - m_name = name; - m_numTriangles = 0; - m_pSkeleton = NULL; - m_sharedGeom.vertices.clear(); - m_sharedGeom.dagMap.clear(); - m_vertexClips.clear(); - m_BSClips.clear(); - } + /***** Class Mesh *****/ + // constructor + Mesh::Mesh(const MString& name) + { + m_name = name; + m_numTriangles = 0; + m_pSkeleton = NULL; + m_sharedGeom.vertices.clear(); + m_sharedGeom.dagMap.clear(); + m_vertexClips.clear(); + m_BSClips.clear(); + } - // destructor - Mesh::~Mesh() - { - clear(); - } + // destructor + Mesh::~Mesh() + { + clear(); + } - // clear data - void Mesh::clear() - { - m_name = ""; - m_numTriangles = 0; - for (int i=0; isetEnvelope(0.0f); - } - // Get connected shaders - stat = getShaders(meshDag); - if (stat != MS::kSuccess) - { - std::cout << "Error getting shaders connected to current mesh\n"; - std::cout.flush(); - } - // Get vertex data - stat = getVertices(meshDag,params); - if (stat != MS::kSuccess) - { - std::cout << "Error retrieving vertex data for current mesh\n"; - std::cout.flush(); - } - // Get vertex bone weights - if (pSkinCluster) - { - getVertexBoneWeights(meshDag,params); - if (stat != MS::kSuccess) - { - std::cout << "Error retrieving veretex bone assignements for current mesh\n"; - std::cout.flush(); - } - } - // Get faces data - stat = getFaces(meshDag,params); - if (stat != MS::kSuccess) - { - std::cout << "Error retrieving faces data for current mesh\n"; - std::cout.flush(); - } - // Build shared geometry - if (params.useSharedGeom) - { - stat = buildSharedGeometry(meshDag,params); - if (stat != MS::kSuccess) - { - std::cout << "Error building shared geometry for current mesh\n"; - std::cout.flush(); - } - } - // Create submeshes (a different submesh for every different shader linked to the mesh) - stat = createSubmeshes(meshDag,params); - if (stat != MS::kSuccess) - { - std::cout << "Error creating submeshes for current mesh\n"; - std::cout.flush(); - } - // Restore blendshape envelope - if (pBlendShape) - { - pBlendShape->restoreEnvelope(); - } - // Free up memory - newvertices.clear(); - newweights.clear(); - newjointIds.clear(); - newpoints.clear(); - newnormals.clear(); - newuvsets.clear(); - shaders.clear(); - shaderPolygonMapping.clear(); - polygonSets.clear(); - if (pSkinCluster) - delete pSkinCluster; - pBlendShape = NULL; + // Get mesh uvsets + stat = getUVSets(meshDag); + if (stat != MS::kSuccess) + { + std::cout << "Error retrieving uvsets for current mesh\n"; + std::cout.flush(); + } + // Get linked skin cluster + stat = getSkinCluster(meshDag,params); + if (stat != MS::kSuccess) + { + std::cout << "Error retrieving skin cluster linked to current mesh\n"; + std::cout.flush(); + } + // Get linked blend shape deformer + stat = getBlendShapeDeformer(meshDag,params); + if (stat != MS::kSuccess) + { + std::cout << "Error retrieving blend shape deformer linked to current mesh\n"; + std::cout.flush(); + } + // Set blend shape deformer envelope to 0, to get base mesh + if (pBlendShape) + { + pBlendShape->setEnvelope(0.0f); + } + // Get connected shaders + stat = getShaders(meshDag); + if (stat != MS::kSuccess) + { + std::cout << "Error getting shaders connected to current mesh\n"; + std::cout.flush(); + } + // Get vertex data + stat = getVertices(meshDag,params); + if (stat != MS::kSuccess) + { + std::cout << "Error retrieving vertex data for current mesh\n"; + std::cout.flush(); + } + // Get vertex bone weights + if (pSkinCluster) + { + getVertexBoneWeights(meshDag,params); + if (stat != MS::kSuccess) + { + std::cout << "Error retrieving veretex bone assignements for current mesh\n"; + std::cout.flush(); + } + } + // Get faces data + stat = getFaces(meshDag,params); + if (stat != MS::kSuccess) + { + std::cout << "Error retrieving faces data for current mesh\n"; + std::cout.flush(); + } + // Build shared geometry + if (params.useSharedGeom) + { + stat = buildSharedGeometry(meshDag,params); + if (stat != MS::kSuccess) + { + std::cout << "Error building shared geometry for current mesh\n"; + std::cout.flush(); + } + } + // Create submeshes (a different submesh for every different shader linked to the mesh) + stat = createSubmeshes(meshDag,params); + if (stat != MS::kSuccess) + { + std::cout << "Error creating submeshes for current mesh\n"; + std::cout.flush(); + } + // Restore blendshape envelope + if (pBlendShape) + { + pBlendShape->restoreEnvelope(); + } + // Free up memory + newvertices.clear(); + newweights.clear(); + newjointIds.clear(); + newpoints.clear(); + newnormals.clear(); + newuvsets.clear(); + shaders.clear(); + shaderPolygonMapping.clear(); + polygonSets.clear(); + if (pSkinCluster) + delete pSkinCluster; + pBlendShape = NULL; - return MS::kSuccess; - } + return MS::kSuccess; + } - /******************************************************************************* - * Load mesh animations from Maya * - *******************************************************************************/ - // Load vertex animations - MStatus Mesh::loadAnims(ParamList& params) - { - MStatus stat; - // save current time for later restore - MTime curTime = MAnimControl::currentTime(); - std::cout << "Loading vertex animations...\n"; - std::cout.flush(); - // clear animations data - m_vertexClips.clear(); - // load the requested clips - for (int i=0; isetEnvelope(0); - } - } - else - { - for (int i=0; im_pBlendShape) - pSubmesh->m_pBlendShape->setEnvelope(0); - } - } - // Get the blend shape poses - if (params.useSharedGeom) - { - for (int i=0; iloadPosesShared(di.dagPath,params,m_sharedGeom.vertices,di.numVertices,di.offset); - } - } - else - { - for (int i=0; im_pBlendShape) - pSubmesh->m_pBlendShape->loadPosesSubmesh(pSubmesh->m_dagPath,params,pSubmesh->m_vertices, - pSubmesh->m_indices,i+1); - } - } - // Enable constraints, IK, etc... - MGlobal::executeCommand("doEnableNodeItems true all",true); - // Restore blend shape deformers original envelopes - if (params.useSharedGeom) - { - for (int i=0; irestoreEnvelope(); - } - } - else - { - for (int i=0; im_pBlendShape) - pSubmesh->m_pBlendShape->restoreEnvelope(); - } - } - // Read blend shape animations - if (params.exportBSAnims) - { - stat = loadBlendShapeAnimations(params); - } - return MS::kSuccess; - } + // Load blend shape deformers + MStatus Mesh::loadBlendShapes(ParamList ¶ms) + { + MStatus stat; + std::cout << "Loading blend shape poses...\n"; + std::cout.flush(); + // Disable constraints, IK, etc... + MGlobal::executeCommand("doEnableNodeItems false all",true); + // Set envelopes of all blend shape deformers to 0 + if (params.useSharedGeom) + { + for (int i=0; isetEnvelope(0); + } + } + else + { + for (int i=0; im_pBlendShape) + pSubmesh->m_pBlendShape->setEnvelope(0); + } + } + // Get the blend shape poses + if (params.useSharedGeom) + { + for (int i=0; iloadPosesShared(di.dagPath,params,m_sharedGeom.vertices,di.numVertices,di.offset); + } + } + else + { + for (int i=0; im_pBlendShape) + pSubmesh->m_pBlendShape->loadPosesSubmesh(pSubmesh->m_dagPath,params,pSubmesh->m_vertices, + pSubmesh->m_indices,i+1); + } + } + // Enable constraints, IK, etc... + MGlobal::executeCommand("doEnableNodeItems true all",true); + // Restore blend shape deformers original envelopes + if (params.useSharedGeom) + { + for (int i=0; irestoreEnvelope(); + } + } + else + { + for (int i=0; im_pBlendShape) + pSubmesh->m_pBlendShape->restoreEnvelope(); + } + } + // Read blend shape animations + if (params.exportBSAnims) + { + stat = loadBlendShapeAnimations(params); + } + return MS::kSuccess; + } - // Load blend shape animations - MStatus Mesh::loadBlendShapeAnimations(ParamList& params) - { - std::cout << "Loading blend shape animations...\n"; - std::cout.flush(); - // Read the list of blend shape clips to export - for (int i=0; i tracks; - for (int j=0; jloadTrack(ci.start,ci.stop,ci.rate,params,0,startPoseId); - tracks.push_back(t); - startPoseId += di.pBlendShape->getPoseGroups().find(0)->second.poses.size(); - } - } - // Merge the tracks into a single track (shared geometry must have a single animation track) - if (tracks.size() > 0) - { - Track newTrack; - // Merge keyframes at the same time position from all tracks - for (int j=0; jposerefs.size(); pri++) - { - // Create a new pose reference - vertexPoseRef poseref; - // Copy pose reference settings from source keyframe - poseref.poseIndex = pSrcKeyframe->poserefs[pri].poseIndex; - poseref.poseWeight = pSrcKeyframe->poserefs[pri].poseWeight; - // Add the new pose reference to the new keyframe - newKeyframe.poserefs.push_back(poseref); - } - } - // Add the keyframe to the new joined track - newTrack.m_vertexKeyframes.push_back(newKeyframe); - } - // Add the joined track to current animation clip - a.addTrack(newTrack); - } - } - else - { - // Create a track for each submesh - std::vector tracks; - for (int j=0; jm_pBlendShape) - { - int startPoseId = 0; - Track t = pSubmesh->m_pBlendShape->loadTrack(ci.start,ci.stop,ci.rate,params,j+1,startPoseId); - a.addTrack(t); - } - } - } - if (a.m_tracks.size() > 0) - { - std::cout << "length: " << a.m_length << "\n"; - std::cout << "num keyframes: " << a.m_tracks[0].m_vertexKeyframes.size() << "\n"; - std::cout.flush(); - m_BSClips.push_back(a); - } - else - { - std::cout << "no tracks exported: skipped. \n"; - std::cout.flush(); - } - } - return MS::kSuccess; - } + // Load blend shape animations + MStatus Mesh::loadBlendShapeAnimations(ParamList& params) + { + std::cout << "Loading blend shape animations...\n"; + std::cout.flush(); + // Read the list of blend shape clips to export + for (int i=0; i tracks; + for (int j=0; jloadTrack(ci.start,ci.stop,ci.rate,params,0,startPoseId); + tracks.push_back(t); + startPoseId += di.pBlendShape->getPoseGroups().find(0)->second.poses.size(); + } + } + // Merge the tracks into a single track (shared geometry must have a single animation track) + if (tracks.size() > 0) + { + Track newTrack; + // Merge keyframes at the same time position from all tracks + for (int j=0; jposerefs.size(); pri++) + { + // Create a new pose reference + vertexPoseRef poseref; + // Copy pose reference settings from source keyframe + poseref.poseIndex = pSrcKeyframe->poserefs[pri].poseIndex; + poseref.poseWeight = pSrcKeyframe->poserefs[pri].poseWeight; + // Add the new pose reference to the new keyframe + newKeyframe.poserefs.push_back(poseref); + } + } + // Add the keyframe to the new joined track + newTrack.m_vertexKeyframes.push_back(newKeyframe); + } + // Add the joined track to current animation clip + a.addTrack(newTrack); + } + } + else + { + // Create a track for each submesh + std::vector tracks; + for (int j=0; jm_pBlendShape) + { + int startPoseId = 0; + Track t = pSubmesh->m_pBlendShape->loadTrack(ci.start,ci.stop,ci.rate,params,j+1,startPoseId); + a.addTrack(t); + } + } + } + if (a.m_tracks.size() > 0) + { + std::cout << "length: " << a.m_length << "\n"; + std::cout << "num keyframes: " << a.m_tracks[0].m_vertexKeyframes.size() << "\n"; + std::cout.flush(); + m_BSClips.push_back(a); + } + else + { + std::cout << "no tracks exported: skipped. \n"; + std::cout.flush(); + } + } + return MS::kSuccess; + } /******************** Methods to parse geometry data from Maya ************************/ - // Get uvsets info from the maya mesh - MStatus Mesh::getUVSets(const MDagPath& meshDag) - { - MFnMesh mesh(meshDag); - MStatus stat; - // Get uv texture coordinate sets' names - if (mesh.numUVSets() > 0) - { - stat = mesh.getUVSetNames(newuvsets); - if (MS::kSuccess != stat) - { - std::cout << "Error retrieving UV sets names\n"; - std::cout.flush(); - return MS::kFailure; - } - } - // Save uvsets info - for (int i=m_uvsets.size(); i 0) + { + stat = mesh.getUVSetNames(newuvsets); + if (MS::kSuccess != stat) + { + std::cout << "Error retrieving UV sets names\n"; + std::cout.flush(); + return MS::kFailure; + } + } + // Save uvsets info + for (int i=m_uvsets.size(); inumOutputConnections(); - for(uint uiGeometry = 0; uiGeometry < uiNumGeometries; ++uiGeometry ) - { - unsigned int uiIndex = pSkinCluster->indexForOutputConnection(uiGeometry); - MObject kOutputObject = pSkinCluster->outputShapeAtIndex(uiIndex); - if(kOutputObject == mesh.object()) - { - std::cout << "Found skin cluster " << pSkinCluster->name().asChar() << " for mesh " - << mesh.name().asChar() << "\n"; - std::cout.flush(); - } - else - { - delete pSkinCluster; - pSkinCluster = NULL; - } - } - } - if (pSkinCluster) - { - // load the skeleton - std::cout << "Loading skeleton data...\n"; - std::cout.flush(); - if (!m_pSkeleton) - m_pSkeleton = new Skeleton(); - stat = m_pSkeleton->load(pSkinCluster,params); - if (MS::kSuccess != stat) - { - std::cout << "Error loading skeleton data\n"; - std::cout.flush(); - } - else - { - std::cout << "OK\n"; - std::cout.flush(); - } - } - } - return MS::kSuccess; - } + // Get skin cluster linked to the maya mesh + MStatus Mesh::getSkinCluster(const MDagPath &meshDag, ParamList ¶ms) + { + MStatus stat; + MFnMesh mesh(meshDag); + pSkinCluster = NULL; + if (params.exportVBA || params.exportSkeleton) + { + // get connected skin clusters (if present) + MItDependencyNodes kDepNodeIt( MFn::kSkinClusterFilter ); + for( ;!kDepNodeIt.isDone() && !pSkinCluster; kDepNodeIt.next()) + { + MObject kObject = kDepNodeIt.item(); + pSkinCluster = new MFnSkinCluster(kObject); + unsigned int uiNumGeometries = pSkinCluster->numOutputConnections(); + for(uint uiGeometry = 0; uiGeometry < uiNumGeometries; ++uiGeometry ) + { + unsigned int uiIndex = pSkinCluster->indexForOutputConnection(uiGeometry); + MObject kOutputObject = pSkinCluster->outputShapeAtIndex(uiIndex); + if(kOutputObject == mesh.object()) + { + std::cout << "Found skin cluster " << pSkinCluster->name().asChar() << " for mesh " + << mesh.name().asChar() << "\n"; + std::cout.flush(); + } + else + { + delete pSkinCluster; + pSkinCluster = NULL; + } + } + } + if (pSkinCluster) + { + // load the skeleton + std::cout << "Loading skeleton data...\n"; + std::cout.flush(); + if (!m_pSkeleton) + m_pSkeleton = new Skeleton(); + stat = m_pSkeleton->load(pSkinCluster,params); + if (MS::kSuccess != stat) + { + std::cout << "Error loading skeleton data\n"; + std::cout.flush(); + } + else + { + std::cout << "OK\n"; + std::cout.flush(); + } + } + } + return MS::kSuccess; + } - // Get blend shape deformer linked to the maya mesh - MStatus Mesh::getBlendShapeDeformer(const MDagPath &meshDag, OgreMayaExporter::ParamList ¶ms) - { - MStatus stat; - MFnMesh mesh(meshDag); - if (params.exportBlendShapes) - { - // get connected blend shape deformer (if present) - MItDependencyNodes kDepNodeIt( MFn::kBlendShape ); - for( ;!kDepNodeIt.isDone() && !pBlendShape; kDepNodeIt.next()) - { - MObject kObject = kDepNodeIt.item(); - MItDependencyGraph itGraph(kObject,MFn::kMesh,MItDependencyGraph::kDownstream,MItDependencyGraph::kDepthFirst); - for (;!itGraph.isDone() && !pBlendShape; itGraph.next()) - { - MFnMesh connectedMesh(itGraph.thisNode()); - if (connectedMesh.fullPathName() == mesh.fullPathName()) - { - pBlendShape = new BlendShape(); - pBlendShape->load(kObject); - std::cout << "Found blend shape deformer " << pBlendShape->getName().asChar() << " for mesh " - << mesh.name().asChar() << "\n"; - } - } - } - } - return MS::kSuccess; - } - // Get connected shaders - MStatus Mesh::getShaders(const MDagPath& meshDag) - { - MStatus stat; - MFnMesh mesh(meshDag); - stat = mesh.getConnectedShaders(0,shaders,shaderPolygonMapping); - std::cout.flush(); - if (MS::kSuccess != stat) - { - std::cout << "Error getting connected shaders\n"; - std::cout.flush(); - return MS::kFailure; - } - std::cout << "Found " << shaders.length() << " connected shaders\n"; - std::cout.flush(); - if (shaders.length() <= 0) - { - std::cout << "No connected shaders, skipping mesh\n"; - std::cout.flush(); - return MS::kFailure; - } - // create a series of arrays of faces for each different submesh - polygonSets.clear(); - polygonSets.resize(shaders.length()); - return MS::kSuccess; - } + // Get blend shape deformer linked to the maya mesh + MStatus Mesh::getBlendShapeDeformer(const MDagPath &meshDag, OgreMayaExporter::ParamList ¶ms) + { + MStatus stat; + MFnMesh mesh(meshDag); + if (params.exportBlendShapes) + { + // get connected blend shape deformer (if present) + MItDependencyNodes kDepNodeIt( MFn::kBlendShape ); + for( ;!kDepNodeIt.isDone() && !pBlendShape; kDepNodeIt.next()) + { + MObject kObject = kDepNodeIt.item(); + MItDependencyGraph itGraph(kObject,MFn::kMesh,MItDependencyGraph::kDownstream,MItDependencyGraph::kDepthFirst); + for (;!itGraph.isDone() && !pBlendShape; itGraph.next()) + { + MFnMesh connectedMesh(itGraph.thisNode()); + if (connectedMesh.fullPathName() == mesh.fullPathName()) + { + pBlendShape = new BlendShape(); + pBlendShape->load(kObject); + std::cout << "Found blend shape deformer " << pBlendShape->getName().asChar() << " for mesh " + << mesh.name().asChar() << "\n"; + } + } + } + } + return MS::kSuccess; + } + // Get connected shaders + MStatus Mesh::getShaders(const MDagPath& meshDag) + { + MStatus stat; + MFnMesh mesh(meshDag); + stat = mesh.getConnectedShaders(0,shaders,shaderPolygonMapping); + std::cout.flush(); + if (MS::kSuccess != stat) + { + std::cout << "Error getting connected shaders\n"; + std::cout.flush(); + return MS::kFailure; + } + std::cout << "Found " << shaders.length() << " connected shaders\n"; + std::cout.flush(); + if (shaders.length() <= 0) + { + std::cout << "No connected shaders, skipping mesh\n"; + std::cout.flush(); + return MS::kFailure; + } + // create a series of arrays of faces for each different submesh + polygonSets.clear(); + polygonSets.resize(shaders.length()); + return MS::kSuccess; + } - // Get vertex data - MStatus Mesh::getVertices(const MDagPath &meshDag, OgreMayaExporter::ParamList ¶ms) - { - MFnMesh mesh(meshDag); - // prepare vertex table - newvertices.resize(mesh.numVertices()); - newweights.resize(mesh.numVertices()); - newjointIds.resize(mesh.numVertices()); - for (int i=0; igetWeights(meshDag,component,vertexWeights,numWeights); - // save the normalized weights - newweights[i]=vertexWeights; - if (MS::kSuccess != stat) - { - std::cout << "Error retrieving vertex weights\n"; - std::cout.flush(); - } - // get ids for the joints - if (m_pSkeleton) - { - MDagPathArray influenceObjs; - pSkinCluster->influenceObjects(influenceObjs,&stat); - if (MS::kSuccess != stat) - { - std::cout << "Error retrieving influence objects for given skin cluster\n"; - std::cout.flush(); - } - newjointIds[i].setLength(newweights[i].length()); - for (int j=0; jgetJoints().size() && !foundJoint; k++) - { - if (partialPathName == m_pSkeleton->getJoints()[k].name) - { - foundJoint=true; - newjointIds[i][j] = m_pSkeleton->getJoints()[k].id; - } - } - } - } - } - return MS::kSuccess; - } + // Get vertex bone assignements + MStatus Mesh::getVertexBoneWeights(const MDagPath& meshDag, OgreMayaExporter::ParamList ¶ms) + { + unsigned int numWeights; + MStatus stat; + std::cout << "Get vbas\n"; + std::cout.flush(); + MItGeometry iterGeom(meshDag); + for (int i=0; !iterGeom.isDone(); iterGeom.next(), i++) + { + MObject component = iterGeom.component(); + MFloatArray vertexWeights; + stat=pSkinCluster->getWeights(meshDag,component,vertexWeights,numWeights); + // save the normalized weights + newweights[i]=vertexWeights; + if (MS::kSuccess != stat) + { + std::cout << "Error retrieving vertex weights\n"; + std::cout.flush(); + } + // get ids for the joints + if (m_pSkeleton) + { + MDagPathArray influenceObjs; + pSkinCluster->influenceObjects(influenceObjs,&stat); + if (MS::kSuccess != stat) + { + std::cout << "Error retrieving influence objects for given skin cluster\n"; + std::cout.flush(); + } + newjointIds[i].setLength(newweights[i].length()); + for (int j=0; jgetJoints().size() && !foundJoint; k++) + { + if (partialPathName == m_pSkeleton->getJoints()[k].name) + { + foundJoint=true; + newjointIds[i][j] = m_pSkeleton->getJoints()[k].id; + } + } + } + } + } + return MS::kSuccess; + } - // Get faces data - MStatus Mesh::getFaces(const MDagPath &meshDag, ParamList ¶ms) - { - MStatus stat; - MFnMesh mesh(meshDag); - // create an iterator to go through mesh polygons - if (mesh.numPolygons() > 0) - { - std::cout << "Iterate over mesh polygons\n"; - std::cout.flush(); - MItMeshPolygon faceIter(mesh.object(),&stat); - if (MS::kSuccess != stat) - { - std::cout << "Error accessing mesh polygons\n"; - std::cout.flush(); - return MS::kFailure; - } - std::cout << "num polygons = " << mesh.numPolygons() << "\n"; - std::cout.flush(); - // iterate over mesh polygons - for (; !faceIter.isDone(); faceIter.next()) - { - int numTris=0; - bool different; - int vtxIdx, nrmIdx; - faceIter.numTriangles(numTris); - // for every triangle composing current polygon extract triangle info - for (int iTris=0; iTris 0) + { + std::cout << "Iterate over mesh polygons\n"; + std::cout.flush(); + MItMeshPolygon faceIter(mesh.object(),&stat); + if (MS::kSuccess != stat) + { + std::cout << "Error accessing mesh polygons\n"; + std::cout.flush(); + return MS::kFailure; + } + std::cout << "num polygons = " << mesh.numPolygons() << "\n"; + std::cout.flush(); + // iterate over mesh polygons + for (; !faceIter.isDone(); faceIter.next()) + { + int numTris=0; + bool different; + int vtxIdx, nrmIdx; + faceIter.numTriangles(numTris); + // for every triangle composing current polygon extract triangle info + for (int iTris=0; iTris 1) - color.r = 1; - else if (color.r < PRECISION) - color.r = 0; - if (color.g > 1) - color.g = 1; - else if (color.g < PRECISION) - color.g = 0; - if (color.b > 1) - color.b = 1; - else if (color.b < PRECISION) - color.b = 0; - if (color.a > 1) - color.a = 1; - else if (color.a < PRECISION) - color.a = 0; - } - else - { - color = MColor(1,1,1,1); - } - if (newvertices[vtxIdx].next == -2) // first time we encounter a vertex in this position - { - // save vertex position - newpoints[vtxIdx].cartesianize(); - newvertices[vtxIdx].pointIdx = vtxIdx; - // save vertex normal - newvertices[vtxIdx].normalIdx = nrmIdx; - // save vertex colour - newvertices[vtxIdx].r = color.r; - newvertices[vtxIdx].g = color.g; - newvertices[vtxIdx].b = color.b; - newvertices[vtxIdx].a = color.a; - // save vertex texture coordinates - newvertices[vtxIdx].u.resize(newuvsets.length()); - newvertices[vtxIdx].v.resize(newuvsets.length()); - // save vbas - newvertices[vtxIdx].vba.resize(newweights[vtxIdx].length()); - for (int j=0; j 1) + color.r = 1; + else if (color.r < PRECISION) + color.r = 0; + if (color.g > 1) + color.g = 1; + else if (color.g < PRECISION) + color.g = 0; + if (color.b > 1) + color.b = 1; + else if (color.b < PRECISION) + color.b = 0; + if (color.a > 1) + color.a = 1; + else if (color.a < PRECISION) + color.a = 0; + } + else + { + color = MColor(1,1,1,1); + } + if (newvertices[vtxIdx].next == -2) // first time we encounter a vertex in this position + { + // save vertex position + newpoints[vtxIdx].cartesianize(); + newvertices[vtxIdx].pointIdx = vtxIdx; + // save vertex normal + newvertices[vtxIdx].normalIdx = nrmIdx; + // save vertex colour + newvertices[vtxIdx].r = color.r; + newvertices[vtxIdx].g = color.g; + newvertices[vtxIdx].b = color.b; + newvertices[vtxIdx].a = color.a; + // save vertex texture coordinates + newvertices[vtxIdx].u.resize(newuvsets.length()); + newvertices[vtxIdx].v.resize(newuvsets.length()); + // save vbas + newvertices[vtxIdx].vba.resize(newweights[vtxIdx].length()); + for (int j=0; j= 0) - polygonSets[shaderPolygonMapping[faceIter.index()]].push_back(newFace); - } // end iteration of triangles - } - } - std::cout << "done reading mesh triangles\n"; - std::cout.flush(); - return MS::kSuccess; - } + idx = k; + } + // if no identical vertex has been saved, then save the vertex info + if (different) + { + vertexInfo vtx; + // save vertex position + vtx.pointIdx = vtxIdx; + // save vertex normal + vtx.normalIdx = nrmIdx; + // save vertex colour + vtx.r = color.r; + vtx.g = color.g; + vtx.b = color.b; + vtx.a = color.a; + // save vertex vba + vtx.vba.resize(newweights[vtxIdx].length()); + for (int j=0; j= 0) + polygonSets[shaderPolygonMapping[faceIter.index()]].push_back(newFace); + } // end iteration of triangles + } + } + std::cout << "done reading mesh triangles\n"; + std::cout.flush(); + return MS::kSuccess; + } - // Build shared geometry - MStatus Mesh::buildSharedGeometry(const MDagPath &meshDag,ParamList& params) - { - std::cout << "Create list of shared vertices\n"; - std::cout.flush(); - // save a new entry in the shared geometry map: we associate the index of the first - // vertex we're loading with the dag path from which it has been read - dagInfo di; - di.offset = m_sharedGeom.vertices.size(); - di.dagPath = meshDag; - di.pBlendShape = pBlendShape; - // load shared vertices - for (int i=0; itexcoords.size(); jtexcoords.push_back(newTexCoords); - } - } - // save number of vertices referring to this mesh dag in the dag path map - di.numVertices = m_sharedGeom.vertices.size() - di.offset; - m_sharedGeom.dagMap.push_back(di); - std::cout << "done creating vertices list\n"; - std::cout.flush(); - return MS::kSuccess; - } + // Build shared geometry + MStatus Mesh::buildSharedGeometry(const MDagPath &meshDag,ParamList& params) + { + std::cout << "Create list of shared vertices\n"; + std::cout.flush(); + // save a new entry in the shared geometry map: we associate the index of the first + // vertex we're loading with the dag path from which it has been read + dagInfo di; + di.offset = m_sharedGeom.vertices.size(); + di.dagPath = meshDag; + di.pBlendShape = pBlendShape; + // load shared vertices + for (int i=0; itexcoords.size(); jtexcoords.push_back(newTexCoords); + } + } + // save number of vertices referring to this mesh dag in the dag path map + di.numVertices = m_sharedGeom.vertices.size() - di.offset; + m_sharedGeom.dagMap.push_back(di); + std::cout << "done creating vertices list\n"; + std::cout.flush(); + return MS::kSuccess; + } - // Create submeshes - MStatus Mesh::createSubmeshes(const MDagPath& meshDag,ParamList& params) - { - MStatus stat; - MFnMesh mesh(meshDag); - for (int i=0; i 0) - { - //create a name for the submesh - MString submesh_name = meshDag.partialPathName(); - MFnDependencyNode shader_node(shaders[i]); - if (shaders.length()>1) - { - submesh_name += "_"; - submesh_name += shader_node.name(); - } - //create new submesh - Submesh* pSubmesh = new Submesh(submesh_name); - //load linked shader - stat = pSubmesh->loadMaterial(shaders[i],newuvsets,params); - if (stat != MS::kSuccess) - { - MFnDependencyNode shadingGroup(shaders[i]); - std::cout << "Error loading material for submesh: " << submesh_name.asChar() << "\n"; - std::cout.flush(); - return MS::kFailure; - } - //load vertex and face data - stat = pSubmesh->load(meshDag,polygonSets[i],newvertices,newpoints,newnormals,newuvsets,params,opposite); - //if we're not using shared geometry, save a pointer to the blend shape deformer - if (pBlendShape && !params.useSharedGeom) - pSubmesh->m_pBlendShape = pBlendShape; - //add submesh to current mesh - m_submeshes.push_back(pSubmesh); - //update number of triangles composing the mesh - m_numTriangles += pSubmesh->numTriangles(); - } - } - return MS::kSuccess; - } + // Create submeshes + MStatus Mesh::createSubmeshes(const MDagPath& meshDag,ParamList& params) + { + MStatus stat; + MFnMesh mesh(meshDag); + for (int i=0; i 0) + { + //create a name for the submesh + MString submesh_name = meshDag.partialPathName(); + MFnDependencyNode shader_node(shaders[i]); + if (shaders.length()>1) + { + submesh_name += "_"; + submesh_name += shader_node.name(); + } + //create new submesh + Submesh* pSubmesh = new Submesh(submesh_name); + //load linked shader + stat = pSubmesh->loadMaterial(shaders[i],newuvsets,params); + if (stat != MS::kSuccess) + { + MFnDependencyNode shadingGroup(shaders[i]); + std::cout << "Error loading material for submesh: " << submesh_name.asChar() << "\n"; + std::cout.flush(); + return MS::kFailure; + } + //load vertex and face data + stat = pSubmesh->load(meshDag,polygonSets[i],newvertices,newpoints,newnormals,newuvsets,params,opposite); + //if we're not using shared geometry, save a pointer to the blend shape deformer + if (pBlendShape && !params.useSharedGeom) + pSubmesh->m_pBlendShape = pBlendShape; + //add submesh to current mesh + m_submeshes.push_back(pSubmesh); + //update number of triangles composing the mesh + m_numTriangles += pSubmesh->numTriangles(); + } + } + return MS::kSuccess; + } /******************** Methods to read vertex animations from Maya ************************/ - //load a vertex animation clip - MStatus Mesh::loadClip(MString& clipName,float start,float stop,float rate,ParamList& params) - { - MStatus stat; - MString msg; - std::vector times; - // calculate times from clip sample rate - times.clear(); - for (float t=start; t= 0) - length = times[times.size()-1] - times[0]; - if (length < 0) - { - std::cout << "invalid time range for the clip, we skip it\n"; - std::cout.flush(); - return MS::kFailure; - } - // create a new animation - Animation a; - a.m_name = clipName; - a.m_length = length; - a.m_tracks.clear(); - // if we're using shared geometry, create a single animation track for the whole mesh - if (params.useSharedGeom) - { - // load the animation track - stat = loadMeshTrack(a,times,params); - if (stat != MS::kSuccess) - { - std::cout << "Error loading mesh vertex animation\n"; - std::cout.flush(); - } - } - // else creae a different animation track for each submesh - else - { - // load all tracks (one for each submesh) - stat = loadSubmeshTracks(a,times,params); - if (stat != MS::kSuccess) - { - std::cout << "Error loading submeshes vertex animation\n"; - std::cout.flush(); - return MS::kFailure; - } - } - // add newly created animation to animations list - m_vertexClips.push_back(a); - // display info - std::cout << "length: " << a.m_length << "\n"; - std::cout << "num keyframes: " << a.m_tracks[0].m_vertexKeyframes.size() << "\n"; - std::cout.flush(); - // clip successfully loaded - return MS::kSuccess; - } + //load a vertex animation clip + MStatus Mesh::loadClip(MString& clipName,float start,float stop,float rate,ParamList& params) + { + MStatus stat; + MString msg; + std::vector times; + // calculate times from clip sample rate + times.clear(); + for (float t=start; t= 0) + length = times[times.size()-1] - times[0]; + if (length < 0) + { + std::cout << "invalid time range for the clip, we skip it\n"; + std::cout.flush(); + return MS::kFailure; + } + // create a new animation + Animation a; + a.m_name = clipName; + a.m_length = length; + a.m_tracks.clear(); + // if we're using shared geometry, create a single animation track for the whole mesh + if (params.useSharedGeom) + { + // load the animation track + stat = loadMeshTrack(a,times,params); + if (stat != MS::kSuccess) + { + std::cout << "Error loading mesh vertex animation\n"; + std::cout.flush(); + } + } + // else creae a different animation track for each submesh + else + { + // load all tracks (one for each submesh) + stat = loadSubmeshTracks(a,times,params); + if (stat != MS::kSuccess) + { + std::cout << "Error loading submeshes vertex animation\n"; + std::cout.flush(); + return MS::kFailure; + } + } + // add newly created animation to animations list + m_vertexClips.push_back(a); + // display info + std::cout << "length: " << a.m_length << "\n"; + std::cout << "num keyframes: " << a.m_tracks[0].m_vertexKeyframes.size() << "\n"; + std::cout.flush(); + // clip successfully loaded + return MS::kSuccess; + } - //load an animation track for the whole mesh (using shared geometry) - MStatus Mesh::loadMeshTrack(Animation& a,std::vector ×, OgreMayaExporter::ParamList ¶ms) - { - MStatus stat; - // create a new track - Track t; - t.m_type = TT_MORPH; - t.m_target = T_MESH; - t.m_vertexKeyframes.clear(); - // get keyframes at given times - for (int i=0; i ×, OgreMayaExporter::ParamList ¶ms) + { + MStatus stat; + // create a new track + Track t; + t.m_type = TT_MORPH; + t.m_target = T_MESH; + t.m_vertexKeyframes.clear(); + // get keyframes at given times + for (int i=0; i ×, OgreMayaExporter::ParamList ¶ms) - { - MStatus stat; - // create a new track for each submesh - std::vector tracks; - for (int i=0; iloadKeyframe(tracks[j],times[i]-times[0],params); - if (stat != MS::kSuccess) - { - std::cout << "Error reading animation keyframe at time: " << times[i] << " for submesh: " << j << "\n"; - std::cout.flush(); - } - } - } - // add tracks to given animation - for (int i=0; i< tracks.size(); i++) - a.addTrack(tracks[i]); - // track sucessfully loaded - return MS::kSuccess; - return MS::kSuccess; - } + //load all submesh animation tracks (one for each submesh) + MStatus Mesh::loadSubmeshTracks(Animation& a,std::vector ×, OgreMayaExporter::ParamList ¶ms) + { + MStatus stat; + // create a new track for each submesh + std::vector tracks; + for (int i=0; iloadKeyframe(tracks[j],times[i]-times[0],params); + if (stat != MS::kSuccess) + { + std::cout << "Error reading animation keyframe at time: " << times[i] << " for submesh: " << j << "\n"; + std::cout.flush(); + } + } + } + // add tracks to given animation + for (int i=0; i< tracks.size(); i++) + a.addTrack(tracks[i]); + // track sucessfully loaded + return MS::kSuccess; + return MS::kSuccess; + } - // Load a keyframe for the whole mesh - MStatus Mesh::loadKeyframe(Track& t,float time,ParamList& params) - { - // create a new keyframe - vertexKeyframe k; - // set keyframe time - k.time = time; - for (int i=0; icreateOgreSubmesh(pMesh,params); - } - // Set skeleton link (if present) - if (m_pSkeleton && params.exportSkeleton) - { - int ri = params.skeletonFilename.rindex('\\'); - int end = params.skeletonFilename.length() - 1; - MString filename = params.skeletonFilename.substring(ri+1,end); - pMesh->setSkeletonName(filename.asChar()); - } - // Write poses - if (params.exportBlendShapes) - { - createOgrePoses(pMesh,params); - } - // Write vertex animations - if (params.exportVertAnims) - { - createOgreVertexAnimations(pMesh,params); - } - // Write pose animations - if (params.exportBSAnims) - { - createOgrePoseAnimations(pMesh,params); - } - // Create a bounding box for the mesh - Ogre::AxisAlignedBox bbox = pMesh->getBounds(); - for(int i=0; im_boundingBox.min(); - MPoint max1 = m_submeshes[i]->m_boundingBox.max(); - Ogre::Vector3 min2(min1.x,min1.y,min1.z); - Ogre::Vector3 max2(max1.x,max1.y,max1.z); - Ogre::AxisAlignedBox newbbox; - newbbox.setExtents(min2,max2); - bbox.merge(newbbox); - } - // Define mesh bounds - pMesh->_setBounds(bbox,false); - // Build edges list - if (params.buildEdges) - { - pMesh->buildEdgeList(); - } - // Build tangents - if (params.buildTangents) - { - Ogre::VertexElementSemantic targetSemantic = params.tangentSemantic == TS_TANGENT ? - Ogre::VES_TANGENT : Ogre::VES_TEXTURE_COORDINATES; - bool canBuild = true; - unsigned short srcTex, destTex; - try { - canBuild = !pMesh->suggestTangentVectorBuildParams(targetSemantic, srcTex, destTex); - } catch(Ogre::Exception e) { - canBuild = false; - } - if (canBuild) - pMesh->buildTangentVectors(targetSemantic, srcTex, destTex, - params.tangentsSplitMirrored, params.tangentsSplitRotated, params.tangentsUseParity); - } - // Export the binary mesh - Ogre::MeshSerializer serializer; - serializer.exportMesh(pMesh.getPointer(),params.meshFilename.asChar()); - pMesh.setNull(); - return MS::kSuccess; - } + // Write to a OGRE binary mesh + MStatus Mesh::writeOgreBinary(ParamList ¶ms) + { + MStatus stat; + // If no mesh have been exported, skip mesh creation + if (m_submeshes.size() <= 0) + { + std::cout << "Warning: No meshes selected for export\n"; + std::cout.flush(); + return MS::kFailure; + } + // Construct mesh + Ogre::MeshPtr pMesh = Ogre::MeshManager::getSingleton().createManual(m_name.asChar(), + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + // Write shared geometry data + if (params.useSharedGeom) + { + createOgreSharedGeometry(pMesh,params); + } + // Write submeshes data + for (int i=0; icreateOgreSubmesh(pMesh,params); + } + // Set skeleton link (if present) + if (m_pSkeleton && params.exportSkeleton) + { + int ri = params.skeletonFilename.rindex('\\'); + int end = params.skeletonFilename.length() - 1; + MString filename = params.skeletonFilename.substring(ri+1,end); + pMesh->setSkeletonName(filename.asChar()); + } + // Write poses + if (params.exportBlendShapes) + { + createOgrePoses(pMesh,params); + } + // Write vertex animations + if (params.exportVertAnims) + { + createOgreVertexAnimations(pMesh,params); + } + // Write pose animations + if (params.exportBSAnims) + { + createOgrePoseAnimations(pMesh,params); + } + // Create a bounding box for the mesh + Ogre::AxisAlignedBox bbox = pMesh->getBounds(); + for(int i=0; im_boundingBox.min(); + MPoint max1 = m_submeshes[i]->m_boundingBox.max(); + Ogre::Vector3 min2(min1.x,min1.y,min1.z); + Ogre::Vector3 max2(max1.x,max1.y,max1.z); + Ogre::AxisAlignedBox newbbox; + newbbox.setExtents(min2,max2); + bbox.merge(newbbox); + } + // Define mesh bounds + pMesh->_setBounds(bbox,false); + // Build edges list + if (params.buildEdges) + { + pMesh->buildEdgeList(); + } + // Build tangents + if (params.buildTangents) + { + Ogre::VertexElementSemantic targetSemantic = params.tangentSemantic == TS_TANGENT ? + Ogre::VES_TANGENT : Ogre::VES_TEXTURE_COORDINATES; + bool canBuild = true; + unsigned short srcTex, destTex; + try { + canBuild = !pMesh->suggestTangentVectorBuildParams(targetSemantic, srcTex, destTex); + } catch(Ogre::Exception e) { + canBuild = false; + } + if (canBuild) + pMesh->buildTangentVectors(targetSemantic, srcTex, destTex, + params.tangentsSplitMirrored, params.tangentsSplitRotated, params.tangentsUseParity); + } + // Export the binary mesh + Ogre::MeshSerializer serializer; + serializer.exportMesh(pMesh.getPointer(),params.meshFilename.asChar()); + pMesh.setNull(); + return MS::kSuccess; + } - // Create shared geometry data for an Ogre mesh - MStatus Mesh::createOgreSharedGeometry(Ogre::MeshPtr pMesh,ParamList& params) - { - MStatus stat; - pMesh->sharedVertexData = new Ogre::VertexData(); - pMesh->sharedVertexData->vertexCount = m_sharedGeom.vertices.size(); - // Define a new vertex declaration - Ogre::VertexDeclaration* pDecl = new Ogre::VertexDeclaration(); - pMesh->sharedVertexData->vertexDeclaration = pDecl; - unsigned buf = 0; - size_t offset = 0; - // Add vertex position - pDecl->addElement(buf,offset,Ogre::VET_FLOAT3,Ogre::VES_POSITION); - offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); - // Add vertex normal - if (params.exportVertNorm) - { - pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); - offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); - } - // Add vertex colour - if (params.exportVertCol) - { - pDecl->addElement(buf, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); + // Create shared geometry data for an Ogre mesh + MStatus Mesh::createOgreSharedGeometry(Ogre::MeshPtr pMesh,ParamList& params) + { + MStatus stat; + pMesh->sharedVertexData = new Ogre::VertexData(); + pMesh->sharedVertexData->vertexCount = m_sharedGeom.vertices.size(); + // Define a new vertex declaration + Ogre::VertexDeclaration* pDecl = new Ogre::VertexDeclaration(); + pMesh->sharedVertexData->vertexDeclaration = pDecl; + unsigned buf = 0; + size_t offset = 0; + // Add vertex position + pDecl->addElement(buf,offset,Ogre::VET_FLOAT3,Ogre::VES_POSITION); + offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); + // Add vertex normal + if (params.exportVertNorm) + { + pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); + offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); + } + // Add vertex colour + if (params.exportVertCol) + { + pDecl->addElement(buf, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR); - } - // Add texture coordinates - for (int i=0; iaddElement(buf, offset, uvType, Ogre::VES_TEXTURE_COORDINATES, i); - offset += Ogre::VertexElement::getTypeSize(uvType); - } - // Get optimal vertex declaration - Ogre::VertexDeclaration* pOptimalDecl = pDecl->getAutoOrganisedDeclaration(params.exportVBA,params.exportBlendShapes || params.exportVertAnims); - // Create the vertex buffer using the newly created vertex declaration - stat = createOgreVertexBuffer(pMesh,pDecl,m_sharedGeom.vertices); - // Write vertex bone assignements list - if (params.exportVBA) - { - // Create a new vertex bone assignements list - Ogre::Mesh::VertexBoneAssignmentList vbas; - // Scan list of shared geometry vertices - for (int i=0; i 0.0f) - vbas.insert(Ogre::Mesh::VertexBoneAssignmentList::value_type(i, vba)); - } - } - // Rationalise the bone assignements list - pMesh->_rationaliseBoneAssignments(pMesh->sharedVertexData->vertexCount,vbas); - // Add bone assignements to the mesh - for (Ogre::Mesh::VertexBoneAssignmentList::iterator bi = vbas.begin(); bi != vbas.end(); bi++) - { - pMesh->addBoneAssignment(bi->second); - } - pMesh->_compileBoneAssignments(); - pMesh->_updateCompiledBoneAssignments(); - } - // Reorganize vertex buffers - pMesh->sharedVertexData->reorganiseBuffers(pOptimalDecl); - - return MS::kSuccess; - } + } + // Add texture coordinates + for (int i=0; iaddElement(buf, offset, uvType, Ogre::VES_TEXTURE_COORDINATES, i); + offset += Ogre::VertexElement::getTypeSize(uvType); + } + // Get optimal vertex declaration + Ogre::VertexDeclaration* pOptimalDecl = pDecl->getAutoOrganisedDeclaration(params.exportVBA,params.exportBlendShapes || params.exportVertAnims); + // Create the vertex buffer using the newly created vertex declaration + stat = createOgreVertexBuffer(pMesh,pDecl,m_sharedGeom.vertices); + // Write vertex bone assignements list + if (params.exportVBA) + { + // Create a new vertex bone assignements list + Ogre::Mesh::VertexBoneAssignmentList vbas; + // Scan list of shared geometry vertices + for (int i=0; i 0.0f) + vbas.insert(Ogre::Mesh::VertexBoneAssignmentList::value_type(i, vba)); + } + } + // Rationalise the bone assignements list + pMesh->_rationaliseBoneAssignments(pMesh->sharedVertexData->vertexCount,vbas); + // Add bone assignements to the mesh + for (Ogre::Mesh::VertexBoneAssignmentList::iterator bi = vbas.begin(); bi != vbas.end(); bi++) + { + pMesh->addBoneAssignment(bi->second); + } + pMesh->_compileBoneAssignments(); + pMesh->_updateCompiledBoneAssignments(); + } + // Reorganize vertex buffers + pMesh->sharedVertexData->reorganiseBuffers(pOptimalDecl); + + return MS::kSuccess; + } - // Create an Ogre compatible vertex buffer - MStatus Mesh::createOgreVertexBuffer(Ogre::MeshPtr pMesh,Ogre::VertexDeclaration* pDecl,const std::vector& vertices) - { - Ogre::HardwareVertexBufferSharedPtr vbuf = - Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(pDecl->getVertexSize(0), - pMesh->sharedVertexData->vertexCount, - Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); - pMesh->sharedVertexData->vertexBufferBinding->setBinding(0, vbuf); - size_t vertexSize = pDecl->getVertexSize(0); - char* pBase = static_cast(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); - Ogre::VertexDeclaration::VertexElementList elems = pDecl->findElementsBySource(0); - Ogre::VertexDeclaration::VertexElementList::iterator ei, eiend; - eiend = elems.end(); - float* pFloat; - Ogre::RGBA* pRGBA; - // Fill the vertex buffer with shared geometry data - Ogre::ColourValue col; - float ucoord, vcoord; - for (long vi=0; viunlock(); - return MS::kSuccess; - } - // Create mesh poses for an Ogre mesh - MStatus Mesh::createOgrePoses(Ogre::MeshPtr pMesh,ParamList& params) - { - int poseCounter = 0; - if (params.useSharedGeom) - { - // Create an entry in the submesh pose remapping table for the shared geometry - submeshPoseRemapping new_sbr; - m_poseRemapping.insert(std::pair(0,new_sbr)); - submeshPoseRemapping& sbr = m_poseRemapping.find(0)->second; - // Read poses associated from all blendshapes associated to the shared geometry - for (int i=0; igetPoseGroups().find(0)->second; - for (int j=0; jname == "") - { - p->name = "pose"; - p->name += poseCounter; - } - // Create a new pose for the ogre mesh - Ogre::Pose* pPose = pMesh->createPose(0,p->name.asChar()); - // Set the pose attributes - for (int k=0; koffsets.size(); k++) - { - Ogre::Vector3 offset(p->offsets[k].x,p->offsets[k].y,p->offsets[k].z); - pPose->addVertex(p->offsets[k].index,offset); - } - // Add a pose remapping for current pose - sbr.insert(std::pair(poseCounter,poseCounter)); - poseCounter++; - } - } - } - } - else - { - // Get poses associated to the submeshes - for (int i=0; im_pBlendShape; - // Check if this submesh has a blend shape deformer associated - if (pBS) - { - // Create an entry in the submesh pose remapping table for this submesh - submeshPoseRemapping new_sbr; - m_poseRemapping.insert(std::pair(i+1,new_sbr)); - submeshPoseRemapping& sbr = m_poseRemapping.find(i+1)->second; - // Get the pose group corresponding to the current submesh - poseGroup& pg = pBS->getPoseGroups().find(i+1)->second; - // Get all poses from current blend shape deformer and current pose group - for (int j=0; jname == "") - { - p->name = "pose"; - p->name += poseCounter; - } - // Create a new pose for the ogre mesh - Ogre::Pose* pPose = pMesh->createPose(p->index,p->name.asChar()); - // Set the pose attributes - for (int k=0; koffsets.size(); k++) - { - Ogre::Vector3 offset(p->offsets[k].x,p->offsets[k].y,p->offsets[k].z); - pPose->addVertex(p->offsets[k].index,offset); - } - // Add a pose remapping for current pose - sbr.insert(std::pair(j,poseCounter)); - - poseCounter++; - } - } - } - } - return MS::kSuccess; - } - // Create vertex animations for an Ogre mesh - MStatus Mesh::createOgreVertexAnimations(Ogre::MeshPtr pMesh,ParamList& params) - { - // Read the list of vertex animation clips - for (int i=0; icreateAnimation(m_vertexClips[i].m_name.asChar(),m_vertexClips[i].m_length); - // Create all tracks for current animation - for (int j=0; jm_target == T_MESH) - pTrack = pAnimation->createVertexTrack(0,pMesh->sharedVertexData,Ogre::VAT_MORPH); - else - { - pTrack = pAnimation->createVertexTrack(t->m_index+1,pMesh->getSubMesh(t->m_index)->vertexData, - Ogre::VAT_MORPH); - } - // Create keyframes for current track - for (int k=0; km_vertexKeyframes.size(); k++) - { - // Create a new keyframe - Ogre::VertexMorphKeyFrame* pKeyframe = pTrack->createVertexMorphKeyFrame(t->m_vertexKeyframes[k].time); - // Create vertex buffer for current keyframe - Ogre::HardwareVertexBufferSharedPtr pBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( - Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3), - t->m_vertexKeyframes[k].positions.size(), - Ogre::HardwareBuffer::HBU_STATIC, true); - float* pFloat = static_cast(pBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); - // Fill the vertex buffer with vertex positions - std::vector& positions = t->m_vertexKeyframes[k].positions; - for (int vi=0; vi(positions[vi].x); - *pFloat++ = static_cast(positions[vi].y); - *pFloat++ = static_cast(positions[vi].z); - } - // Unlock vertex buffer - pBuffer->unlock(); - // Set vertex buffer for current keyframe - pKeyframe->setVertexBuffer(pBuffer); - } - } - } - return MS::kSuccess; - } - // Create pose animations for an Ogre mesh - MStatus Mesh::createOgrePoseAnimations(Ogre::MeshPtr pMesh,ParamList& params) - { - // Get all loaded blend shape clips - for (int i=0; icreateAnimation(m_BSClips[i].m_name.asChar(),m_BSClips[i].m_length); - // Create animation tracks for this animation - for (int j=0; jm_target == T_MESH) - pTrack = pAnimation->createVertexTrack(0,pMesh->sharedVertexData,Ogre::VAT_POSE); - else - { - pTrack = pAnimation->createVertexTrack(t->m_index,pMesh->getSubMesh(t->m_index-1)->vertexData, - Ogre::VAT_POSE); - } - // Create keyframes for current track - for (int k=0; km_vertexKeyframes.size(); k++) - { - Ogre::VertexPoseKeyFrame* pKeyframe = pTrack->createVertexPoseKeyFrame(t->m_vertexKeyframes[k].time); - for (int pri=0; prim_vertexKeyframes[k].poserefs.size(); pri++) - { - vertexPoseRef* pr = &t->m_vertexKeyframes[k].poserefs[pri]; - // Get the correct absolute index of the pose from the remapping - int poseIndex = m_poseRemapping.find(t->m_index)->second.find(pr->poseIndex)->second; - pKeyframe->addPoseReference(poseIndex,pr->poseWeight); - } - } - } - } - return MS::kSuccess; - } + // Create an Ogre compatible vertex buffer + MStatus Mesh::createOgreVertexBuffer(Ogre::MeshPtr pMesh,Ogre::VertexDeclaration* pDecl,const std::vector& vertices) + { + Ogre::HardwareVertexBufferSharedPtr vbuf = + Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(pDecl->getVertexSize(0), + pMesh->sharedVertexData->vertexCount, + Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); + pMesh->sharedVertexData->vertexBufferBinding->setBinding(0, vbuf); + size_t vertexSize = pDecl->getVertexSize(0); + char* pBase = static_cast(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); + Ogre::VertexDeclaration::VertexElementList elems = pDecl->findElementsBySource(0); + Ogre::VertexDeclaration::VertexElementList::iterator ei, eiend; + eiend = elems.end(); + float* pFloat; + Ogre::RGBA* pRGBA; + // Fill the vertex buffer with shared geometry data + Ogre::ColourValue col; + float ucoord, vcoord; + for (long vi=0; viunlock(); + return MS::kSuccess; + } + // Create mesh poses for an Ogre mesh + MStatus Mesh::createOgrePoses(Ogre::MeshPtr pMesh,ParamList& params) + { + int poseCounter = 0; + if (params.useSharedGeom) + { + // Create an entry in the submesh pose remapping table for the shared geometry + submeshPoseRemapping new_sbr; + m_poseRemapping.insert(std::pair(0,new_sbr)); + submeshPoseRemapping& sbr = m_poseRemapping.find(0)->second; + // Read poses associated from all blendshapes associated to the shared geometry + for (int i=0; igetPoseGroups().find(0)->second; + for (int j=0; jname == "") + { + p->name = "pose"; + p->name += poseCounter; + } + // Create a new pose for the ogre mesh + Ogre::Pose* pPose = pMesh->createPose(0,p->name.asChar()); + // Set the pose attributes + for (int k=0; koffsets.size(); k++) + { + Ogre::Vector3 offset(p->offsets[k].x,p->offsets[k].y,p->offsets[k].z); + pPose->addVertex(p->offsets[k].index,offset); + } + // Add a pose remapping for current pose + sbr.insert(std::pair(poseCounter,poseCounter)); + poseCounter++; + } + } + } + } + else + { + // Get poses associated to the submeshes + for (int i=0; im_pBlendShape; + // Check if this submesh has a blend shape deformer associated + if (pBS) + { + // Create an entry in the submesh pose remapping table for this submesh + submeshPoseRemapping new_sbr; + m_poseRemapping.insert(std::pair(i+1,new_sbr)); + submeshPoseRemapping& sbr = m_poseRemapping.find(i+1)->second; + // Get the pose group corresponding to the current submesh + poseGroup& pg = pBS->getPoseGroups().find(i+1)->second; + // Get all poses from current blend shape deformer and current pose group + for (int j=0; jname == "") + { + p->name = "pose"; + p->name += poseCounter; + } + // Create a new pose for the ogre mesh + Ogre::Pose* pPose = pMesh->createPose(p->index,p->name.asChar()); + // Set the pose attributes + for (int k=0; koffsets.size(); k++) + { + Ogre::Vector3 offset(p->offsets[k].x,p->offsets[k].y,p->offsets[k].z); + pPose->addVertex(p->offsets[k].index,offset); + } + // Add a pose remapping for current pose + sbr.insert(std::pair(j,poseCounter)); + + poseCounter++; + } + } + } + } + return MS::kSuccess; + } + // Create vertex animations for an Ogre mesh + MStatus Mesh::createOgreVertexAnimations(Ogre::MeshPtr pMesh,ParamList& params) + { + // Read the list of vertex animation clips + for (int i=0; icreateAnimation(m_vertexClips[i].m_name.asChar(),m_vertexClips[i].m_length); + // Create all tracks for current animation + for (int j=0; jm_target == T_MESH) + pTrack = pAnimation->createVertexTrack(0,pMesh->sharedVertexData,Ogre::VAT_MORPH); + else + { + pTrack = pAnimation->createVertexTrack(t->m_index+1,pMesh->getSubMesh(t->m_index)->vertexData, + Ogre::VAT_MORPH); + } + // Create keyframes for current track + for (int k=0; km_vertexKeyframes.size(); k++) + { + // Create a new keyframe + Ogre::VertexMorphKeyFrame* pKeyframe = pTrack->createVertexMorphKeyFrame(t->m_vertexKeyframes[k].time); + // Create vertex buffer for current keyframe + Ogre::HardwareVertexBufferSharedPtr pBuffer = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer( + Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3), + t->m_vertexKeyframes[k].positions.size(), + Ogre::HardwareBuffer::HBU_STATIC, true); + float* pFloat = static_cast(pBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); + // Fill the vertex buffer with vertex positions + std::vector& positions = t->m_vertexKeyframes[k].positions; + for (int vi=0; vi(positions[vi].x); + *pFloat++ = static_cast(positions[vi].y); + *pFloat++ = static_cast(positions[vi].z); + } + // Unlock vertex buffer + pBuffer->unlock(); + // Set vertex buffer for current keyframe + pKeyframe->setVertexBuffer(pBuffer); + } + } + } + return MS::kSuccess; + } + // Create pose animations for an Ogre mesh + MStatus Mesh::createOgrePoseAnimations(Ogre::MeshPtr pMesh,ParamList& params) + { + // Get all loaded blend shape clips + for (int i=0; icreateAnimation(m_BSClips[i].m_name.asChar(),m_BSClips[i].m_length); + // Create animation tracks for this animation + for (int j=0; jm_target == T_MESH) + pTrack = pAnimation->createVertexTrack(0,pMesh->sharedVertexData,Ogre::VAT_POSE); + else + { + pTrack = pAnimation->createVertexTrack(t->m_index,pMesh->getSubMesh(t->m_index-1)->vertexData, + Ogre::VAT_POSE); + } + // Create keyframes for current track + for (int k=0; km_vertexKeyframes.size(); k++) + { + Ogre::VertexPoseKeyFrame* pKeyframe = pTrack->createVertexPoseKeyFrame(t->m_vertexKeyframes[k].time); + for (int pri=0; prim_vertexKeyframes[k].poserefs.size(); pri++) + { + vertexPoseRef* pr = &t->m_vertexKeyframes[k].poserefs[pri]; + // Get the correct absolute index of the pose from the remapping + int poseIndex = m_poseRemapping.find(t->m_index)->second.find(pr->poseIndex)->second; + pKeyframe->addPoseReference(poseIndex,pr->poseWeight); + } + } + } + } + return MS::kSuccess; + } }; //end of namespace diff --git a/Tools/MayaExport/src/ogreExporter.cpp b/Tools/MayaExport/src/ogreExporter.cpp index 693e5cfc322..f14f270e929 100644 --- a/Tools/MayaExport/src/ogreExporter.cpp +++ b/Tools/MayaExport/src/ogreExporter.cpp @@ -20,537 +20,537 @@ namespace OgreMayaExporter { - OgreExporter::~OgreExporter() - { - exit(); - } - // Restore the scene to a state previous to the export, clean up memory and exit - void OgreExporter::exit() - { - // Restore active selection list - MGlobal::setActiveSelectionList(m_selList); - // Restore current time - MAnimControl::setCurrentTime(m_curTime); - // Free memory - delete m_pMesh; - m_pMesh = 0; - delete m_pMaterialSet; - m_pMaterialSet = 0; - // Close output files - m_params.closeFiles(); - std::cout.flush(); - } - - // Execute the command - MStatus OgreExporter::doIt(const MArgList& args) - { - // clean up - delete m_pMesh; - delete m_pMaterialSet; - - // Parse the arguments. - m_params.parseArgs(args); - // Create output files - m_params.openFiles(); - // Create a new empty mesh - m_pMesh = new Mesh(); - // Create a new empty material set - m_pMaterialSet = new MaterialSet(); - // Save current time for later restore - m_curTime = MAnimControl::currentTime(); - // Save active selection list for later restore - MGlobal::getActiveSelectionList(m_selList); - /**************************** LOAD DATA **********************************/ - if (m_params.exportAll) - { // We are exporting the whole scene - std::cout << "Export the whole scene\n"; - std::cout.flush(); - MItDag dagIter; - MFnDagNode worldDag (dagIter.root()); - MDagPath worldPath; - worldDag.getPath(worldPath); - stat = translateNode(worldPath); - } - else - { // We are translating a selection - std::cout << "Export selected objects\n"; - std::cout.flush(); - // Get the selection list - MSelectionList activeList; - stat = MGlobal::getActiveSelectionList(activeList); - if (MS::kSuccess != stat) - { - std::cout << "Error retrieving selection list\n"; - std::cout.flush(); - exit(); - return MS::kFailure; - } - MItSelectionList iter(activeList); - - for ( ; !iter.isDone(); iter.next()) - { - MDagPath dagPath; - stat = iter.getDagPath(dagPath); - stat = translateNode(dagPath); - } - } - - // Load vertex animations - if (m_params.exportVertAnims) - m_pMesh->loadAnims(m_params); - - // Load blend shapes - if (m_params.exportBlendShapes) - m_pMesh->loadBlendShapes(m_params); - - // Restore skeleton to correct pose - if (m_pMesh->getSkeleton()) - m_pMesh->getSkeleton()->restorePose(); - - // Load skeleton animation (do it now, so we have loaded all needed joints) - if (m_pMesh->getSkeleton() && m_params.exportSkelAnims) - { - // Load skeleton animations - m_pMesh->getSkeleton()->loadAnims(m_params); - } - - /**************************** WRITE DATA **********************************/ - stat = writeOgreData(); - - std::cout << "Export completed succesfully\n"; - std::cout.flush(); - exit(); - - return MS::kSuccess; - } - - - /**************************** TRANSLATE A NODE **********************************/ - // Method for iterating over nodes in a dependency graph from top to bottom - MStatus OgreExporter::translateNode(MDagPath& dagPath) - { - if (m_params.exportAnimCurves) - { - MObject dagPathNode = dagPath.node(); - MItDependencyGraph animIter( dagPathNode, - MFn::kAnimCurve, - MItDependencyGraph::kUpstream, - MItDependencyGraph::kDepthFirst, - MItDependencyGraph::kNodeLevel, - &stat ); - - if (stat) - { - for (; !animIter.isDone(); animIter.next()) - { - MObject anim = animIter.thisNode(&stat); - MFnAnimCurve animFn(anim,&stat); - std::cout << "Found animation curve: " << animFn.name().asChar() << "\n"; - std::cout << "Translating animation curve: " << animFn.name().asChar() << "...\n"; - std::cout.flush(); - stat = writeAnim(animFn); - if (MS::kSuccess == stat) - { - std::cout << "OK\n"; - std::cout.flush(); - } - else - { - std::cout << "Error, Aborting operation\n"; - std::cout.flush(); - return MS::kFailure; - } - } - } - } - if (dagPath.hasFn(MFn::kMesh)&&(m_params.exportMesh||m_params.exportMaterial||m_params.exportSkeleton) - && (dagPath.childCount() == 0)) - { // we have found a mesh shape node, it can't have any children, and it contains - // all the mesh geometry data - MDagPath meshDag = dagPath; - MFnMesh meshFn(meshDag); - if (!meshFn.isIntermediateObject()) - { - std::cout << "Found mesh node: " << meshDag.fullPathName().asChar() << "\n"; - std::cout << "Loading mesh node " << meshDag.fullPathName().asChar() << "...\n"; - std::cout.flush(); - stat = m_pMesh->load(meshDag,m_params); - if (MS::kSuccess == stat) - { - std::cout << "OK\n"; - std::cout.flush(); - } - else - { - std::cout << "Error, mesh skipped\n"; - std::cout.flush(); - } - } - } - else if (dagPath.hasFn(MFn::kCamera)&&(m_params.exportCameras) && (!dagPath.hasFn(MFn::kShape))) - { // we have found a camera shape node, it can't have any children, and it contains - // all information about the camera - MFnCamera cameraFn(dagPath); - if (!cameraFn.isIntermediateObject()) - { - std::cout << "Found camera node: "<< dagPath.fullPathName().asChar() << "\n"; - std::cout << "Translating camera node: "<< dagPath.fullPathName().asChar() << "...\n"; - std::cout.flush(); - stat = writeCamera(cameraFn); - if (MS::kSuccess == stat) - { - std::cout << "OK\n"; - std::cout.flush(); - } - else - { - std::cout << "Error, Aborting operation\n"; - std::cout.flush(); - return MS::kFailure; - } - } - } - else if ( ( dagPath.apiType() == MFn::kParticle ) && m_params.exportParticles ) - { // we have found a set of particles - MFnDagNode fnNode(dagPath); - if (!fnNode.isIntermediateObject()) - { - std::cout << "Found particles node: "<< dagPath.fullPathName().asChar() << "\n"; - std::cout << "Translating particles node: "<< dagPath.fullPathName().asChar() << "...\n"; - std::cout.flush(); - Particles particles; - particles.load(dagPath,m_params); - stat = particles.writeToXML(m_params); - if (MS::kSuccess == stat) - { - std::cout << "OK\n"; - std::cout.flush(); - } - else - { - std::cout << "Error, Aborting operation\n"; - std::cout.flush(); - return MS::kFailure; - } - } - } - // look for meshes and cameras within the node's children - for (uint i=0; ipartialPathName().asChar() << "\n"; - m_params.outCameras << "{\n"; - - //write camera type - m_params.outCameras << "\ttype "; - if (camera.isOrtho()) - m_params.outCameras << "ortho\n"; - else - m_params.outCameras << "persp\n"; - - // write translation data - m_params.outCameras << "\ttranslation\n"; - m_params.outCameras << "\t{\n"; - //translateX - m_params.outCameras << "\t\tx "; - plug = cameraTransform->findPlug("translateX"); - if (plug.isConnected() && m_params.exportCamerasAnim) - { - plug.connectedTo(srcplugarray,true,false,&stat); - for (int i=0; i < srcplugarray.length(); i++) - { - if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) - { - if (animCurve) - delete animCurve; - animCurve = new MFnAnimCurve(srcplugarray[i].node()); - continue; - } - else if (i == srcplugarray.length()-1) - { - std::cout << "Invalid link to translateX attribute\n"; - return MS::kFailure; - } - } - m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; - } - else - { - plug.getValue(dist); - m_params.outCameras << "= " << dist << "\n"; - } - //translateY - m_params.outCameras << "\t\ty "; - plug = cameraTransform->findPlug("translateY"); - if (plug.isConnected() && m_params.exportCamerasAnim) - { - plug.connectedTo(srcplugarray,true,false,&stat); - for (int i=0; i< srcplugarray.length(); i++) - { - if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) - { - if (animCurve) - delete animCurve; - animCurve = new MFnAnimCurve(srcplugarray[i].node()); - continue; - } - else if (i == srcplugarray.length()-1) - { - std::cout << "Invalid link to translateY attribute\n"; - return MS::kFailure; - } - } - m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; - } - else - { - plug.getValue(dist); - m_params.outCameras << "= " << dist << "\n"; - } - //translateZ - m_params.outCameras << "\t\tz "; - plug = cameraTransform->findPlug("translateZ"); - if (plug.isConnected() && m_params.exportCamerasAnim) - { - plug.connectedTo(srcplugarray,true,false,&stat); - for (int i=0; i< srcplugarray.length(); i++) - { - if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) - { - if (animCurve) - delete animCurve; - animCurve = new MFnAnimCurve(srcplugarray[i].node()); - continue; - } - else if (i == srcplugarray.length()-1) - { - std::cout << "Invalid link to translateZ attribute\n"; - return MS::kFailure; - } - } - m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; - } - else - { - plug.getValue(dist); - m_params.outCameras << "= " << dist << "\n"; - } - m_params.outCameras << "\t}\n"; - - // write rotation data - m_params.outCameras << "\trotation\n"; - m_params.outCameras << "\t{\n"; - m_params.outCameras << "\t\tx "; - //rotateX - plug = cameraTransform->findPlug("rotateX"); - if (plug.isConnected() && m_params.exportCamerasAnim) - { - plug.connectedTo(srcplugarray,true,false,&stat); - for (int i=0; i< srcplugarray.length(); i++) - { - if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) - { - if (animCurve) - delete animCurve; - animCurve = new MFnAnimCurve(srcplugarray[i].node()); - continue; - } - else if (i == srcplugarray.length()-1) - { - std::cout << "Invalid link to rotateX attribute\n"; - return MS::kFailure; - } - } - m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; - } - else - { - plug.getValue(angle); - m_params.outCameras << "= " << angle.asDegrees() << "\n"; - } - //rotateY - m_params.outCameras << "\t\ty "; - plug = cameraTransform->findPlug("rotateY"); - if (plug.isConnected() && m_params.exportCamerasAnim) - { - plug.connectedTo(srcplugarray,true,false,&stat); - for (int i=0; i< srcplugarray.length(); i++) - { - if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) - { - if (animCurve) - delete animCurve; - animCurve = new MFnAnimCurve(srcplugarray[i].node()); - continue; - } - else if (i == srcplugarray.length()-1) - { - std::cout << "Invalid link to rotateY attribute\n"; - return MS::kFailure; - } - } - m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; - } - else - { - plug.getValue(angle); - m_params.outCameras << "= " << angle.asDegrees() << "\n"; - } - //rotateZ - m_params.outCameras << "\t\tz "; - plug = cameraTransform->findPlug("rotateZ"); - if (plug.isConnected() && m_params.exportCamerasAnim) - { - plug.connectedTo(srcplugarray,true,false,&stat); - for (int i=0; i< srcplugarray.length(); i++) - { - if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) - { - if (animCurve) - delete animCurve; - animCurve = new MFnAnimCurve(srcplugarray[i].node()); - continue; - } - else if (i == srcplugarray.length()-1) - { - std::cout << "Invalid link to rotateZ attribute\n"; - return MS::kFailure; - } - } - m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; - } - else - { - plug.getValue(angle); - m_params.outCameras << "= " << angle.asDegrees() << "\n"; - } - m_params.outCameras << "\t}\n"; - - // end camera description - m_params.outCameras << "}\n\n"; - if (cameraTransform != NULL) - delete cameraTransform; - if (animCurve != NULL) - delete animCurve; - return MS::kSuccess; - } - - /******************************************************************************************************** - * Method to write data to OGRE format * - ********************************************************************************************************/ - MStatus OgreExporter::writeOgreData() - { - // Create singletons - Ogre::LogManager logMgr; - Ogre::ResourceGroupManager rgm; - Ogre::MeshManager meshMgr; - Ogre::SkeletonManager skelMgr; - Ogre::MaterialManager matMgr; - Ogre::DefaultHardwareBufferManager hardwareBufMgr; - - // Create a log - logMgr.createLog("ogreMayaExporter.log", true); - - // Write mesh binary - if (m_params.exportMesh) - { - std::cout << "Writing mesh binary...\n"; - std::cout.flush(); - stat = m_pMesh->writeOgreBinary(m_params); - if (stat != MS::kSuccess) - { - std::cout << "Error writing mesh binary file\n"; - std::cout.flush(); - } - } - - // Write skeleton binary - if (m_params.exportSkeleton) - { - if (m_pMesh->getSkeleton()) - { - std::cout << "Writing skeleton binary...\n"; - std::cout.flush(); - stat = m_pMesh->getSkeleton()->writeOgreBinary(m_params); - if (stat != MS::kSuccess) - { - std::cout << "Error writing mesh binary file\n"; - std::cout.flush(); - } - } - } - - // Write materials data - if (m_params.exportMaterial) - { - std::cout << "Writing materials data...\n"; - std::cout.flush(); - stat = m_pMaterialSet->writeOgreScript(m_params); - if (stat != MS::kSuccess) - { - std::cout << "Error writing materials file\n"; - std::cout.flush(); - } - } - - return MS::kSuccess; - } + OgreExporter::~OgreExporter() + { + exit(); + } + // Restore the scene to a state previous to the export, clean up memory and exit + void OgreExporter::exit() + { + // Restore active selection list + MGlobal::setActiveSelectionList(m_selList); + // Restore current time + MAnimControl::setCurrentTime(m_curTime); + // Free memory + delete m_pMesh; + m_pMesh = 0; + delete m_pMaterialSet; + m_pMaterialSet = 0; + // Close output files + m_params.closeFiles(); + std::cout.flush(); + } + + // Execute the command + MStatus OgreExporter::doIt(const MArgList& args) + { + // clean up + delete m_pMesh; + delete m_pMaterialSet; + + // Parse the arguments. + m_params.parseArgs(args); + // Create output files + m_params.openFiles(); + // Create a new empty mesh + m_pMesh = new Mesh(); + // Create a new empty material set + m_pMaterialSet = new MaterialSet(); + // Save current time for later restore + m_curTime = MAnimControl::currentTime(); + // Save active selection list for later restore + MGlobal::getActiveSelectionList(m_selList); + /**************************** LOAD DATA **********************************/ + if (m_params.exportAll) + { // We are exporting the whole scene + std::cout << "Export the whole scene\n"; + std::cout.flush(); + MItDag dagIter; + MFnDagNode worldDag (dagIter.root()); + MDagPath worldPath; + worldDag.getPath(worldPath); + stat = translateNode(worldPath); + } + else + { // We are translating a selection + std::cout << "Export selected objects\n"; + std::cout.flush(); + // Get the selection list + MSelectionList activeList; + stat = MGlobal::getActiveSelectionList(activeList); + if (MS::kSuccess != stat) + { + std::cout << "Error retrieving selection list\n"; + std::cout.flush(); + exit(); + return MS::kFailure; + } + MItSelectionList iter(activeList); + + for ( ; !iter.isDone(); iter.next()) + { + MDagPath dagPath; + stat = iter.getDagPath(dagPath); + stat = translateNode(dagPath); + } + } + + // Load vertex animations + if (m_params.exportVertAnims) + m_pMesh->loadAnims(m_params); + + // Load blend shapes + if (m_params.exportBlendShapes) + m_pMesh->loadBlendShapes(m_params); + + // Restore skeleton to correct pose + if (m_pMesh->getSkeleton()) + m_pMesh->getSkeleton()->restorePose(); + + // Load skeleton animation (do it now, so we have loaded all needed joints) + if (m_pMesh->getSkeleton() && m_params.exportSkelAnims) + { + // Load skeleton animations + m_pMesh->getSkeleton()->loadAnims(m_params); + } + + /**************************** WRITE DATA **********************************/ + stat = writeOgreData(); + + std::cout << "Export completed succesfully\n"; + std::cout.flush(); + exit(); + + return MS::kSuccess; + } + + + /**************************** TRANSLATE A NODE **********************************/ + // Method for iterating over nodes in a dependency graph from top to bottom + MStatus OgreExporter::translateNode(MDagPath& dagPath) + { + if (m_params.exportAnimCurves) + { + MObject dagPathNode = dagPath.node(); + MItDependencyGraph animIter( dagPathNode, + MFn::kAnimCurve, + MItDependencyGraph::kUpstream, + MItDependencyGraph::kDepthFirst, + MItDependencyGraph::kNodeLevel, + &stat ); + + if (stat) + { + for (; !animIter.isDone(); animIter.next()) + { + MObject anim = animIter.thisNode(&stat); + MFnAnimCurve animFn(anim,&stat); + std::cout << "Found animation curve: " << animFn.name().asChar() << "\n"; + std::cout << "Translating animation curve: " << animFn.name().asChar() << "...\n"; + std::cout.flush(); + stat = writeAnim(animFn); + if (MS::kSuccess == stat) + { + std::cout << "OK\n"; + std::cout.flush(); + } + else + { + std::cout << "Error, Aborting operation\n"; + std::cout.flush(); + return MS::kFailure; + } + } + } + } + if (dagPath.hasFn(MFn::kMesh)&&(m_params.exportMesh||m_params.exportMaterial||m_params.exportSkeleton) + && (dagPath.childCount() == 0)) + { // we have found a mesh shape node, it can't have any children, and it contains + // all the mesh geometry data + MDagPath meshDag = dagPath; + MFnMesh meshFn(meshDag); + if (!meshFn.isIntermediateObject()) + { + std::cout << "Found mesh node: " << meshDag.fullPathName().asChar() << "\n"; + std::cout << "Loading mesh node " << meshDag.fullPathName().asChar() << "...\n"; + std::cout.flush(); + stat = m_pMesh->load(meshDag,m_params); + if (MS::kSuccess == stat) + { + std::cout << "OK\n"; + std::cout.flush(); + } + else + { + std::cout << "Error, mesh skipped\n"; + std::cout.flush(); + } + } + } + else if (dagPath.hasFn(MFn::kCamera)&&(m_params.exportCameras) && (!dagPath.hasFn(MFn::kShape))) + { // we have found a camera shape node, it can't have any children, and it contains + // all information about the camera + MFnCamera cameraFn(dagPath); + if (!cameraFn.isIntermediateObject()) + { + std::cout << "Found camera node: "<< dagPath.fullPathName().asChar() << "\n"; + std::cout << "Translating camera node: "<< dagPath.fullPathName().asChar() << "...\n"; + std::cout.flush(); + stat = writeCamera(cameraFn); + if (MS::kSuccess == stat) + { + std::cout << "OK\n"; + std::cout.flush(); + } + else + { + std::cout << "Error, Aborting operation\n"; + std::cout.flush(); + return MS::kFailure; + } + } + } + else if ( ( dagPath.apiType() == MFn::kParticle ) && m_params.exportParticles ) + { // we have found a set of particles + MFnDagNode fnNode(dagPath); + if (!fnNode.isIntermediateObject()) + { + std::cout << "Found particles node: "<< dagPath.fullPathName().asChar() << "\n"; + std::cout << "Translating particles node: "<< dagPath.fullPathName().asChar() << "...\n"; + std::cout.flush(); + Particles particles; + particles.load(dagPath,m_params); + stat = particles.writeToXML(m_params); + if (MS::kSuccess == stat) + { + std::cout << "OK\n"; + std::cout.flush(); + } + else + { + std::cout << "Error, Aborting operation\n"; + std::cout.flush(); + return MS::kFailure; + } + } + } + // look for meshes and cameras within the node's children + for (uint i=0; ipartialPathName().asChar() << "\n"; + m_params.outCameras << "{\n"; + + //write camera type + m_params.outCameras << "\ttype "; + if (camera.isOrtho()) + m_params.outCameras << "ortho\n"; + else + m_params.outCameras << "persp\n"; + + // write translation data + m_params.outCameras << "\ttranslation\n"; + m_params.outCameras << "\t{\n"; + //translateX + m_params.outCameras << "\t\tx "; + plug = cameraTransform->findPlug("translateX"); + if (plug.isConnected() && m_params.exportCamerasAnim) + { + plug.connectedTo(srcplugarray,true,false,&stat); + for (int i=0; i < srcplugarray.length(); i++) + { + if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) + { + if (animCurve) + delete animCurve; + animCurve = new MFnAnimCurve(srcplugarray[i].node()); + continue; + } + else if (i == srcplugarray.length()-1) + { + std::cout << "Invalid link to translateX attribute\n"; + return MS::kFailure; + } + } + m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; + } + else + { + plug.getValue(dist); + m_params.outCameras << "= " << dist << "\n"; + } + //translateY + m_params.outCameras << "\t\ty "; + plug = cameraTransform->findPlug("translateY"); + if (plug.isConnected() && m_params.exportCamerasAnim) + { + plug.connectedTo(srcplugarray,true,false,&stat); + for (int i=0; i< srcplugarray.length(); i++) + { + if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) + { + if (animCurve) + delete animCurve; + animCurve = new MFnAnimCurve(srcplugarray[i].node()); + continue; + } + else if (i == srcplugarray.length()-1) + { + std::cout << "Invalid link to translateY attribute\n"; + return MS::kFailure; + } + } + m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; + } + else + { + plug.getValue(dist); + m_params.outCameras << "= " << dist << "\n"; + } + //translateZ + m_params.outCameras << "\t\tz "; + plug = cameraTransform->findPlug("translateZ"); + if (plug.isConnected() && m_params.exportCamerasAnim) + { + plug.connectedTo(srcplugarray,true,false,&stat); + for (int i=0; i< srcplugarray.length(); i++) + { + if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) + { + if (animCurve) + delete animCurve; + animCurve = new MFnAnimCurve(srcplugarray[i].node()); + continue; + } + else if (i == srcplugarray.length()-1) + { + std::cout << "Invalid link to translateZ attribute\n"; + return MS::kFailure; + } + } + m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; + } + else + { + plug.getValue(dist); + m_params.outCameras << "= " << dist << "\n"; + } + m_params.outCameras << "\t}\n"; + + // write rotation data + m_params.outCameras << "\trotation\n"; + m_params.outCameras << "\t{\n"; + m_params.outCameras << "\t\tx "; + //rotateX + plug = cameraTransform->findPlug("rotateX"); + if (plug.isConnected() && m_params.exportCamerasAnim) + { + plug.connectedTo(srcplugarray,true,false,&stat); + for (int i=0; i< srcplugarray.length(); i++) + { + if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) + { + if (animCurve) + delete animCurve; + animCurve = new MFnAnimCurve(srcplugarray[i].node()); + continue; + } + else if (i == srcplugarray.length()-1) + { + std::cout << "Invalid link to rotateX attribute\n"; + return MS::kFailure; + } + } + m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; + } + else + { + plug.getValue(angle); + m_params.outCameras << "= " << angle.asDegrees() << "\n"; + } + //rotateY + m_params.outCameras << "\t\ty "; + plug = cameraTransform->findPlug("rotateY"); + if (plug.isConnected() && m_params.exportCamerasAnim) + { + plug.connectedTo(srcplugarray,true,false,&stat); + for (int i=0; i< srcplugarray.length(); i++) + { + if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) + { + if (animCurve) + delete animCurve; + animCurve = new MFnAnimCurve(srcplugarray[i].node()); + continue; + } + else if (i == srcplugarray.length()-1) + { + std::cout << "Invalid link to rotateY attribute\n"; + return MS::kFailure; + } + } + m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; + } + else + { + plug.getValue(angle); + m_params.outCameras << "= " << angle.asDegrees() << "\n"; + } + //rotateZ + m_params.outCameras << "\t\tz "; + plug = cameraTransform->findPlug("rotateZ"); + if (plug.isConnected() && m_params.exportCamerasAnim) + { + plug.connectedTo(srcplugarray,true,false,&stat); + for (int i=0; i< srcplugarray.length(); i++) + { + if (srcplugarray[i].node().hasFn(MFn::kAnimCurve)) + { + if (animCurve) + delete animCurve; + animCurve = new MFnAnimCurve(srcplugarray[i].node()); + continue; + } + else if (i == srcplugarray.length()-1) + { + std::cout << "Invalid link to rotateZ attribute\n"; + return MS::kFailure; + } + } + m_params.outCameras << "anim " << animCurve->name().asChar() << "\n"; + } + else + { + plug.getValue(angle); + m_params.outCameras << "= " << angle.asDegrees() << "\n"; + } + m_params.outCameras << "\t}\n"; + + // end camera description + m_params.outCameras << "}\n\n"; + if (cameraTransform != NULL) + delete cameraTransform; + if (animCurve != NULL) + delete animCurve; + return MS::kSuccess; + } + + /******************************************************************************************************** + * Method to write data to OGRE format * + ********************************************************************************************************/ + MStatus OgreExporter::writeOgreData() + { + // Create singletons + Ogre::LogManager logMgr; + Ogre::ResourceGroupManager rgm; + Ogre::MeshManager meshMgr; + Ogre::SkeletonManager skelMgr; + Ogre::MaterialManager matMgr; + Ogre::DefaultHardwareBufferManager hardwareBufMgr; + + // Create a log + logMgr.createLog("ogreMayaExporter.log", true); + + // Write mesh binary + if (m_params.exportMesh) + { + std::cout << "Writing mesh binary...\n"; + std::cout.flush(); + stat = m_pMesh->writeOgreBinary(m_params); + if (stat != MS::kSuccess) + { + std::cout << "Error writing mesh binary file\n"; + std::cout.flush(); + } + } + + // Write skeleton binary + if (m_params.exportSkeleton) + { + if (m_pMesh->getSkeleton()) + { + std::cout << "Writing skeleton binary...\n"; + std::cout.flush(); + stat = m_pMesh->getSkeleton()->writeOgreBinary(m_params); + if (stat != MS::kSuccess) + { + std::cout << "Error writing mesh binary file\n"; + std::cout.flush(); + } + } + } + + // Write materials data + if (m_params.exportMaterial) + { + std::cout << "Writing materials data...\n"; + std::cout.flush(); + stat = m_pMaterialSet->writeOgreScript(m_params); + if (stat != MS::kSuccess) + { + std::cout << "Error writing materials file\n"; + std::cout.flush(); + } + } + + return MS::kSuccess; + } } // end namespace @@ -558,28 +558,28 @@ namespace OgreMayaExporter // Routine for registering the command within Maya MStatus initializePlugin( MObject obj ) { - MStatus status; - MFnPlugin plugin( obj, "OgreExporter", "7.0", "Any"); - status = plugin.registerCommand( "ogreExport", OgreMayaExporter::OgreExporter::creator ); - if (!status) { - status.perror("registerCommand"); - return status; - } - - return status; + MStatus status; + MFnPlugin plugin( obj, "OgreExporter", "7.0", "Any"); + status = plugin.registerCommand( "ogreExport", OgreMayaExporter::OgreExporter::creator ); + if (!status) { + status.perror("registerCommand"); + return status; + } + + return status; } // Routine for unregistering the command within Maya MStatus uninitializePlugin( MObject obj) { - MStatus status; - MFnPlugin plugin( obj ); - status = plugin.deregisterCommand( "ogreExport" ); - if (!status) { - status.perror("deregisterCommand"); - return status; - } - - return status; + MStatus status; + MFnPlugin plugin( obj ); + status = plugin.deregisterCommand( "ogreExport" ); + if (!status) { + status.perror("deregisterCommand"); + return status; + } + + return status; } diff --git a/Tools/MayaExport/src/paramlist.cpp b/Tools/MayaExport/src/paramlist.cpp index e5402521632..fd350ca590f 100644 --- a/Tools/MayaExport/src/paramlist.cpp +++ b/Tools/MayaExport/src/paramlist.cpp @@ -23,451 +23,451 @@ // method to parse arguments from command line namespace OgreMayaExporter { - void ParamList::parseArgs(const MArgList &args) - { - MStatus stat; - // Parse arguments from command line - for (uint i=0; i < args.length(); i++ ) - { - if ((MString("-all") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - exportAll = true; - else if ((MString("-world") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - exportWorldCoords = true; - else if ((MString("-lu") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - MString lengthUnit = args.asString(++i,&stat); - if (MString("pref") == lengthUnit) - { - MGlobal::executeCommand("currentUnit -q -l",lengthUnit,false); - } - if (MString("mm") == lengthUnit) - lum = CM2MM; - else if (MString("cm") == lengthUnit) - lum = CM2CM; - else if (MString("m") == lengthUnit) - lum = CM2M; - else if (MString("in") == lengthUnit) - lum = CM2IN; - else if (MString("ft") == lengthUnit) - lum = CM2FT; - else if (MString("yd") == lengthUnit) - lum = CM2YD; - } - else if ((MString("-scale") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - float s = args.asDouble(++i,&stat); - lum *= s; - } - else if ((MString("-mesh") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportMesh = true; - meshFilename = args.asString(++i,&stat); - } - else if ((MString("-mat") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportMaterial = true; - materialFilename = args.asString(++i,&stat); - } - else if ((MString("-matPrefix") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - matPrefix = args.asString(++i,&stat); - } - else if ((MString("-copyTex") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - copyTextures = true; - texOutputDir = args.asString(++i,&stat); - } - else if ((MString("-lightOff") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - lightingOff = true; - } - else if ((MString("-skel") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportSkeleton = true; - skeletonFilename = args.asString(++i,&stat); - } - else if ((MString("-skeletonAnims") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportSkelAnims = true; - } - else if ((MString("-vertexAnims") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportVertAnims = true; - } - else if ((MString("-blendShapes") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportBlendShapes = true; - } - else if ((MString("-BSAnims") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportBSAnims = true; - } - else if ((MString("-skelBB") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - skelBB = true; - } - else if ((MString("-bsBB") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - bsBB = true; - } - else if ((MString("-vertBB") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - vertBB = true; - } - else if ((MString("-animCur") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportAnimCurves = true; - animFilename = args.asString(++i,&stat); - } - else if ((MString("-cam") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportCameras = true; - camerasFilename = args.asString(++i,&stat); - } - else if ((MString("-v") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportVBA = true; - } - else if ((MString("-n") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportVertNorm = true; - } - else if ((MString("-c") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportVertCol = true; - } - else if ((MString("-t") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportTexCoord = true; - } - else if ((MString("-edges") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - buildEdges = true; - } - else if ((MString("-tangents") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - buildTangents = true; - MString tanSem = args.asString(++i,&stat); - if (tanSem == "TEXCOORD") - tangentSemantic = TS_TEXCOORD; - else if (tanSem == "TANGENT") - tangentSemantic = TS_TANGENT; - } - else if ((MString("-tangentsplitmirrored") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - tangentsSplitMirrored = true; - } - else if ((MString("-tangentsplitrotated") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - tangentsSplitRotated = true; - } - else if ((MString("-tangentuseparity") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - tangentsUseParity = true; - } - else if ((MString("-camAnim") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportCamerasAnim = true; - } - else if ((MString("-particles") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - exportParticles = true; - particlesFilename = args.asString(++i,&stat); - } - else if ((MString("-shared") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - useSharedGeom = true; - } - else if ((MString("-np") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - MString npType = args.asString(++i,&stat); - if (npType == "curFrame") - neutralPoseType = NPT_CURFRAME; - else if (npType == "bindPose") - neutralPoseType = NPT_BINDPOSE; - } - else if ((MString("-skeletonClip") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - //get clip name - MString clipName = args.asString(++i,&stat); - //check if name is unique, otherwise skip the clip - bool uniqueName = true; - for (int k=0; k convert to seconds - MTime t1(startTime, MTime::uiUnit()); - MTime t2(stopTime, MTime::uiUnit()); - startTime = t1.as(MTime::kSeconds); - stopTime = t2.as(MTime::kSeconds); - } - } - else - { - //range specified by time slider - MTime t1 = MAnimControl::minTime(); - MTime t2 = MAnimControl::maxTime(); - startTime = t1.as(MTime::kSeconds); - stopTime = t2.as(MTime::kSeconds); - } - // get sample rate - float rate; - MString sampleRateType = args.asString(++i,&stat); - if (sampleRateType == "sampleByFrames") - { - // rate specified in frames - int intRate = args.asInt(++i,&stat); - MTime t = MTime(intRate, MTime::uiUnit()); - rate = t.as(MTime::kSeconds); - } - else - { - // rate specified in seconds - rate = args.asDouble(++i,&stat); - } - //add clip info - clipInfo clip; - clip.name = clipName; - clip.start = startTime; - clip.stop = stopTime; - clip.rate = rate; - skelClipList.push_back(clip); - std::cout << "skeleton clip " << clipName.asChar() << "\n"; - std::cout << "start: " << startTime << ", stop: " << stopTime << "\n"; - std::cout << "rate: " << rate << "\n"; - std::cout << "-----------------\n"; - std::cout.flush(); - } - //warn of duplicate clip name - else - { - std::cout << "Warning! A skeleton clip with name \"" << clipName.asChar() << "\" already exists\n"; - std::cout.flush(); - } - } - else if ((MString("-BSClip") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - //get clip name - MString clipName = args.asString(++i,&stat); - //check if name is unique, otherwise skip the clip - bool uniqueName = true; - for (int k=0; k convert to seconds - MTime t1(startTime, MTime::uiUnit()); - MTime t2(stopTime, MTime::uiUnit()); - startTime = t1.as(MTime::kSeconds); - stopTime = t2.as(MTime::kSeconds); - } - } - else - { - //range specified by time slider - MTime t1 = MAnimControl::minTime(); - MTime t2 = MAnimControl::maxTime(); - startTime = t1.as(MTime::kSeconds); - stopTime = t2.as(MTime::kSeconds); - } - // get sample rate - float rate; - MString sampleRateType = args.asString(++i,&stat); - if (sampleRateType == "sampleByFrames") - { - // rate specified in frames - int intRate = args.asInt(++i,&stat); - MTime t = MTime(intRate, MTime::uiUnit()); - rate = t.as(MTime::kSeconds); - } - else - { - // rate specified in seconds - rate = args.asDouble(++i,&stat); - } - //add clip info - clipInfo clip; - clip.name = clipName; - clip.start = startTime; - clip.stop = stopTime; - clip.rate = rate; - BSClipList.push_back(clip); - std::cout << "blend shape clip " << clipName.asChar() << "\n"; - std::cout << "start: " << startTime << ", stop: " << stopTime << "\n"; - std::cout << "rate: " << rate << "\n"; - std::cout << "-----------------\n"; - std::cout.flush(); - } - //warn of duplicate clip name - else - { - std::cout << "Warning! A blend shape clip with name \"" << clipName.asChar() << "\" already exists\n"; - std::cout.flush(); - } - } - else if ((MString("-vertexClip") == args.asString(i,&stat)) && (MS::kSuccess == stat)) - { - //get clip name - MString clipName = args.asString(++i,&stat); - //check if name is unique, otherwise skip the clip - bool uniqueName = true; - for (int k=0; k convert to seconds - MTime t1(startTime, MTime::uiUnit()); - MTime t2(stopTime, MTime::uiUnit()); - startTime = t1.as(MTime::kSeconds); - stopTime = t2.as(MTime::kSeconds); - } - } - else - { - //range specified by time slider - MTime t1 = MAnimControl::minTime(); - MTime t2 = MAnimControl::maxTime(); - startTime = t1.as(MTime::kSeconds); - stopTime = t2.as(MTime::kSeconds); - } - // get sample rate - float rate; - MString sampleRateType = args.asString(++i,&stat); - if (sampleRateType == "sampleByFrames") - { - // rate specified in frames - int intRate = args.asInt(++i,&stat); - MTime t = MTime(intRate, MTime::uiUnit()); - rate = t.as(MTime::kSeconds); - } - else - { - // rate specified in seconds - rate = args.asDouble(++i,&stat); - } - //add clip info - clipInfo clip; - clip.name = clipName; - clip.start = startTime; - clip.stop = stopTime; - clip.rate = rate; - vertClipList.push_back(clip); - std::cout << "vertex clip " << clipName.asChar() << "\n"; - std::cout << "start: " << startTime << ", stop: " << stopTime << "\n"; - std::cout << "rate: " << rate << "\n"; - std::cout << "-----------------\n"; - std::cout.flush(); - } - //warn of duplicate clip name - else - { - std::cout << "Warning! A vertex animation clip with name \"" << clipName.asChar() << "\" already exists\n"; - std::cout.flush(); - } - } - } - } + void ParamList::parseArgs(const MArgList &args) + { + MStatus stat; + // Parse arguments from command line + for (uint i=0; i < args.length(); i++ ) + { + if ((MString("-all") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + exportAll = true; + else if ((MString("-world") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + exportWorldCoords = true; + else if ((MString("-lu") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + MString lengthUnit = args.asString(++i,&stat); + if (MString("pref") == lengthUnit) + { + MGlobal::executeCommand("currentUnit -q -l",lengthUnit,false); + } + if (MString("mm") == lengthUnit) + lum = CM2MM; + else if (MString("cm") == lengthUnit) + lum = CM2CM; + else if (MString("m") == lengthUnit) + lum = CM2M; + else if (MString("in") == lengthUnit) + lum = CM2IN; + else if (MString("ft") == lengthUnit) + lum = CM2FT; + else if (MString("yd") == lengthUnit) + lum = CM2YD; + } + else if ((MString("-scale") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + float s = args.asDouble(++i,&stat); + lum *= s; + } + else if ((MString("-mesh") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportMesh = true; + meshFilename = args.asString(++i,&stat); + } + else if ((MString("-mat") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportMaterial = true; + materialFilename = args.asString(++i,&stat); + } + else if ((MString("-matPrefix") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + matPrefix = args.asString(++i,&stat); + } + else if ((MString("-copyTex") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + copyTextures = true; + texOutputDir = args.asString(++i,&stat); + } + else if ((MString("-lightOff") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + lightingOff = true; + } + else if ((MString("-skel") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportSkeleton = true; + skeletonFilename = args.asString(++i,&stat); + } + else if ((MString("-skeletonAnims") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportSkelAnims = true; + } + else if ((MString("-vertexAnims") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportVertAnims = true; + } + else if ((MString("-blendShapes") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportBlendShapes = true; + } + else if ((MString("-BSAnims") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportBSAnims = true; + } + else if ((MString("-skelBB") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + skelBB = true; + } + else if ((MString("-bsBB") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + bsBB = true; + } + else if ((MString("-vertBB") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + vertBB = true; + } + else if ((MString("-animCur") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportAnimCurves = true; + animFilename = args.asString(++i,&stat); + } + else if ((MString("-cam") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportCameras = true; + camerasFilename = args.asString(++i,&stat); + } + else if ((MString("-v") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportVBA = true; + } + else if ((MString("-n") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportVertNorm = true; + } + else if ((MString("-c") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportVertCol = true; + } + else if ((MString("-t") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportTexCoord = true; + } + else if ((MString("-edges") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + buildEdges = true; + } + else if ((MString("-tangents") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + buildTangents = true; + MString tanSem = args.asString(++i,&stat); + if (tanSem == "TEXCOORD") + tangentSemantic = TS_TEXCOORD; + else if (tanSem == "TANGENT") + tangentSemantic = TS_TANGENT; + } + else if ((MString("-tangentsplitmirrored") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + tangentsSplitMirrored = true; + } + else if ((MString("-tangentsplitrotated") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + tangentsSplitRotated = true; + } + else if ((MString("-tangentuseparity") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + tangentsUseParity = true; + } + else if ((MString("-camAnim") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportCamerasAnim = true; + } + else if ((MString("-particles") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + exportParticles = true; + particlesFilename = args.asString(++i,&stat); + } + else if ((MString("-shared") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + useSharedGeom = true; + } + else if ((MString("-np") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + MString npType = args.asString(++i,&stat); + if (npType == "curFrame") + neutralPoseType = NPT_CURFRAME; + else if (npType == "bindPose") + neutralPoseType = NPT_BINDPOSE; + } + else if ((MString("-skeletonClip") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + //get clip name + MString clipName = args.asString(++i,&stat); + //check if name is unique, otherwise skip the clip + bool uniqueName = true; + for (int k=0; k convert to seconds + MTime t1(startTime, MTime::uiUnit()); + MTime t2(stopTime, MTime::uiUnit()); + startTime = t1.as(MTime::kSeconds); + stopTime = t2.as(MTime::kSeconds); + } + } + else + { + //range specified by time slider + MTime t1 = MAnimControl::minTime(); + MTime t2 = MAnimControl::maxTime(); + startTime = t1.as(MTime::kSeconds); + stopTime = t2.as(MTime::kSeconds); + } + // get sample rate + float rate; + MString sampleRateType = args.asString(++i,&stat); + if (sampleRateType == "sampleByFrames") + { + // rate specified in frames + int intRate = args.asInt(++i,&stat); + MTime t = MTime(intRate, MTime::uiUnit()); + rate = t.as(MTime::kSeconds); + } + else + { + // rate specified in seconds + rate = args.asDouble(++i,&stat); + } + //add clip info + clipInfo clip; + clip.name = clipName; + clip.start = startTime; + clip.stop = stopTime; + clip.rate = rate; + skelClipList.push_back(clip); + std::cout << "skeleton clip " << clipName.asChar() << "\n"; + std::cout << "start: " << startTime << ", stop: " << stopTime << "\n"; + std::cout << "rate: " << rate << "\n"; + std::cout << "-----------------\n"; + std::cout.flush(); + } + //warn of duplicate clip name + else + { + std::cout << "Warning! A skeleton clip with name \"" << clipName.asChar() << "\" already exists\n"; + std::cout.flush(); + } + } + else if ((MString("-BSClip") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + //get clip name + MString clipName = args.asString(++i,&stat); + //check if name is unique, otherwise skip the clip + bool uniqueName = true; + for (int k=0; k convert to seconds + MTime t1(startTime, MTime::uiUnit()); + MTime t2(stopTime, MTime::uiUnit()); + startTime = t1.as(MTime::kSeconds); + stopTime = t2.as(MTime::kSeconds); + } + } + else + { + //range specified by time slider + MTime t1 = MAnimControl::minTime(); + MTime t2 = MAnimControl::maxTime(); + startTime = t1.as(MTime::kSeconds); + stopTime = t2.as(MTime::kSeconds); + } + // get sample rate + float rate; + MString sampleRateType = args.asString(++i,&stat); + if (sampleRateType == "sampleByFrames") + { + // rate specified in frames + int intRate = args.asInt(++i,&stat); + MTime t = MTime(intRate, MTime::uiUnit()); + rate = t.as(MTime::kSeconds); + } + else + { + // rate specified in seconds + rate = args.asDouble(++i,&stat); + } + //add clip info + clipInfo clip; + clip.name = clipName; + clip.start = startTime; + clip.stop = stopTime; + clip.rate = rate; + BSClipList.push_back(clip); + std::cout << "blend shape clip " << clipName.asChar() << "\n"; + std::cout << "start: " << startTime << ", stop: " << stopTime << "\n"; + std::cout << "rate: " << rate << "\n"; + std::cout << "-----------------\n"; + std::cout.flush(); + } + //warn of duplicate clip name + else + { + std::cout << "Warning! A blend shape clip with name \"" << clipName.asChar() << "\" already exists\n"; + std::cout.flush(); + } + } + else if ((MString("-vertexClip") == args.asString(i,&stat)) && (MS::kSuccess == stat)) + { + //get clip name + MString clipName = args.asString(++i,&stat); + //check if name is unique, otherwise skip the clip + bool uniqueName = true; + for (int k=0; k convert to seconds + MTime t1(startTime, MTime::uiUnit()); + MTime t2(stopTime, MTime::uiUnit()); + startTime = t1.as(MTime::kSeconds); + stopTime = t2.as(MTime::kSeconds); + } + } + else + { + //range specified by time slider + MTime t1 = MAnimControl::minTime(); + MTime t2 = MAnimControl::maxTime(); + startTime = t1.as(MTime::kSeconds); + stopTime = t2.as(MTime::kSeconds); + } + // get sample rate + float rate; + MString sampleRateType = args.asString(++i,&stat); + if (sampleRateType == "sampleByFrames") + { + // rate specified in frames + int intRate = args.asInt(++i,&stat); + MTime t = MTime(intRate, MTime::uiUnit()); + rate = t.as(MTime::kSeconds); + } + else + { + // rate specified in seconds + rate = args.asDouble(++i,&stat); + } + //add clip info + clipInfo clip; + clip.name = clipName; + clip.start = startTime; + clip.stop = stopTime; + clip.rate = rate; + vertClipList.push_back(clip); + std::cout << "vertex clip " << clipName.asChar() << "\n"; + std::cout << "start: " << startTime << ", stop: " << stopTime << "\n"; + std::cout << "rate: " << rate << "\n"; + std::cout << "-----------------\n"; + std::cout.flush(); + } + //warn of duplicate clip name + else + { + std::cout << "Warning! A vertex animation clip with name \"" << clipName.asChar() << "\" already exists\n"; + std::cout.flush(); + } + } + } + } - // method to open output files for writing - MStatus ParamList::openFiles() - { - MString msg; - if (exportMaterial) - { - outMaterial.open(materialFilename.asChar()); - if (!outMaterial) - { - std::cout << "Error opening file: " << materialFilename.asChar() << "\n"; - return MS::kFailure; - } - } - if (exportAnimCurves) - { - outAnim.open(animFilename.asChar()); - if (!outAnim) - { - std::cout << "Error opening file: " << animFilename.asChar() << "\n"; - return MS::kFailure; - } - } - if (exportCameras) - { - outCameras.open(camerasFilename.asChar()); - if (!outCameras) - { - std::cout << "Error opening file: " << camerasFilename.asChar() << "\n"; - return MS::kFailure; - } - } - if (exportParticles) - { - outParticles.open(particlesFilename.asChar()); - if (!outParticles) - { - std::cout << "Error opening file: " << particlesFilename.asChar() << "\n"; - return MS::kFailure; - } - } - return MS::kSuccess; - } + // method to open output files for writing + MStatus ParamList::openFiles() + { + MString msg; + if (exportMaterial) + { + outMaterial.open(materialFilename.asChar()); + if (!outMaterial) + { + std::cout << "Error opening file: " << materialFilename.asChar() << "\n"; + return MS::kFailure; + } + } + if (exportAnimCurves) + { + outAnim.open(animFilename.asChar()); + if (!outAnim) + { + std::cout << "Error opening file: " << animFilename.asChar() << "\n"; + return MS::kFailure; + } + } + if (exportCameras) + { + outCameras.open(camerasFilename.asChar()); + if (!outCameras) + { + std::cout << "Error opening file: " << camerasFilename.asChar() << "\n"; + return MS::kFailure; + } + } + if (exportParticles) + { + outParticles.open(particlesFilename.asChar()); + if (!outParticles) + { + std::cout << "Error opening file: " << particlesFilename.asChar() << "\n"; + return MS::kFailure; + } + } + return MS::kSuccess; + } - // method to close open output files - MStatus ParamList::closeFiles() - { - if (exportMaterial) - outMaterial.close(); - - if (exportAnimCurves) - outAnim.close(); - - if (exportCameras) - outCameras.close(); - - return MS::kSuccess; - } + // method to close open output files + MStatus ParamList::closeFiles() + { + if (exportMaterial) + outMaterial.close(); + + if (exportAnimCurves) + outAnim.close(); + + if (exportCameras) + outCameras.close(); + + return MS::kSuccess; + } -} //end namespace \ No newline at end of file +} //end namespace \ No newline at end of file diff --git a/Tools/MayaExport/src/particles.cpp b/Tools/MayaExport/src/particles.cpp index 042705ce678..216ad4284bc 100644 --- a/Tools/MayaExport/src/particles.cpp +++ b/Tools/MayaExport/src/particles.cpp @@ -29,46 +29,46 @@ template void writeTrackToXML( std::ofstream &outStream, const TKeyTrac // Particles //////////////////////////////////////////////////////////////////////////////////////////////////// Particles::Particles(): - nFrames(0) + nFrames(0) { } //////////////////////////////////////////////////////////////////////////////////////////////////// Particles::~Particles() { - clear(); + clear(); } //////////////////////////////////////////////////////////////////////////////////////////////////// MStatus Particles::load( MDagPath& dagPath, ParamList& params ) { - int nMaxFrame, nMinFrame; - MGlobal::executeCommand( "playbackOptions -q -max", nMaxFrame ); - MGlobal::executeCommand( "playbackOptions -q -min", nMinFrame ); - if ( nMinFrame > 0 ) - nMinFrame = 0; + int nMaxFrame, nMinFrame; + MGlobal::executeCommand( "playbackOptions -q -max", nMaxFrame ); + MGlobal::executeCommand( "playbackOptions -q -min", nMinFrame ); + if ( nMinFrame > 0 ) + nMinFrame = 0; - for ( int nFrame = nMinFrame; nFrame <= nMaxFrame; ++nFrame ) - ExportFrame( dagPath, nFrame ); + for ( int nFrame = nMinFrame; nFrame <= nMaxFrame; ++nFrame ) + ExportFrame( dagPath, nFrame ); - FinalizeData( nMinFrame, nMaxFrame ); - return MS::kSuccess; + FinalizeData( nMinFrame, nMaxFrame ); + return MS::kSuccess; } //////////////////////////////////////////////////////////////////////////////////////////////////// MStatus Particles::writeToXML( ParamList& params ) { - params.outParticles << "\n"; - for ( uint nTemp = 0; nTemp < particleTracks.size(); ++nTemp ) - { - const SParticle &particle = particleTracks[nTemp]; - params.outParticles << "\t\n"; - writeTrackToXML( params.outParticles, particle.pos, "position" ); - writeTrackToXML( params.outParticles, particle.rotation, "rotation" ); - writeTrackToXML( params.outParticles, particle.scale, "scale" ); - writeTrackToXML( params.outParticles, particle.color, "color" ); - writeTrackToXML( params.outParticles, particle.sprite, "sprite" ); - params.outParticles << "\t\n"; - } - params.outParticles << "\n"; - return MS::kSuccess; + params.outParticles << "\n"; + for ( uint nTemp = 0; nTemp < particleTracks.size(); ++nTemp ) + { + const SParticle &particle = particleTracks[nTemp]; + params.outParticles << "\t\n"; + writeTrackToXML( params.outParticles, particle.pos, "position" ); + writeTrackToXML( params.outParticles, particle.rotation, "rotation" ); + writeTrackToXML( params.outParticles, particle.scale, "scale" ); + writeTrackToXML( params.outParticles, particle.color, "color" ); + writeTrackToXML( params.outParticles, particle.sprite, "sprite" ); + params.outParticles << "\t\n"; + } + params.outParticles << "\n"; + return MS::kSuccess; } //////////////////////////////////////////////////////////////////////////////////////////////////// void Particles::clear() @@ -77,275 +77,275 @@ void Particles::clear() //////////////////////////////////////////////////////////////////////////////////////////////////// MStatus Particles::ExportFrame( MDagPath &dagPath, int nFrame ) { - MGlobal::viewFrame( nFrame ); + MGlobal::viewFrame( nFrame ); - MStatus retStatus; - MFnDagNode dagNode( dagPath ); - //// - int nParticles = 0; - MPlug countPlug = dagNode.findPlug( MString( "count" ), &retStatus ); - retStatus = countPlug.getValue( nParticles ); - if ( nParticles <= 0 ) - return MS::kFailure; - //// - std::vector idIndex( nParticles ); - std::vector sortedId( nParticles ); - std::vector particlesFrame( nParticles ); - //// - MObject tempObj; - MPlug mappingPlug = dagNode.findPlug( MString( "idMapping" ), &retStatus ); - //// - MPlug idPlug = mappingPlug.child( 0 ); - retStatus = idPlug.getValue( tempObj ); - MFnIntArrayData sSortedIDArray( tempObj, &retStatus ); - for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) - sortedId[nTemp] = sSortedIDArray[nTemp]; - //// - MPlug indexPlug = mappingPlug.child( 1 ); - retStatus = indexPlug.getValue( tempObj ); - MFnIntArrayData idIndexArray( tempObj, &retStatus ); - for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) - idIndex[nTemp] = idIndexArray[nTemp]; - //// Position - MPlug posPlug = dagNode.findPlug( MString( "worldPosition" ), &retStatus ); - retStatus = posPlug.getValue( tempObj ); - MFnVectorArrayData posData( tempObj, &retStatus ); - for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) - { - SParticleData &particle = particlesFrame[nTemp]; - particle.nFrame = nFrame; - particle.pos.x = (float)posData[idIndex[nTemp]].x; - particle.pos.y = (float)posData[idIndex[nTemp]].y; - particle.pos.z = (float)posData[idIndex[nTemp]].z; - } - //// Rotation - MPlug rotPlug = dagNode.findPlug( MString( "spriteTwistPP" ), &retStatus ); - if ( retStatus == MS::kSuccess ) - { - retStatus = rotPlug.getValue( tempObj ); - MFnDoubleArrayData rotPlug( tempObj, &retStatus ); - for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) - particlesFrame[nTemp].fRotation = ToRadians( (float)rotPlug[idIndex[nTemp]] ); - } - //// ScaleX - MPlug scaleXPlug = dagNode.findPlug( MString( "spriteScaleXPP" ), &retStatus ); - if ( retStatus == MS::kSuccess ) - { - retStatus = scaleXPlug.getValue( tempObj ); - MFnDoubleArrayData scaleX( tempObj, &retStatus ); - for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) - particlesFrame[nTemp].scale.x = float( scaleX[idIndex[nTemp]] ); - } - //// ScaleY - MPlug scaleYPlug = dagNode.findPlug( MString( "spriteScaleYPP" ), &retStatus ); - if ( retStatus == MS::kSuccess ) - { - retStatus = scaleYPlug.getValue( tempObj ); - MFnDoubleArrayData scaleY( tempObj, &retStatus ); - for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) - particlesFrame[nTemp].scale.y = float( scaleY[idIndex[nTemp]] ); - } - //// Sprite - MPlug spritePlug = dagNode.findPlug( MString( "spriteNumPP" ), &retStatus ); - if ( retStatus == MS::kSuccess ) - { - retStatus = spritePlug.getValue( tempObj ); - MFnDoubleArrayData sprite( tempObj, &retStatus ); - for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) - particlesFrame[nTemp].nSprite = int( sprite[idIndex[nTemp]] - 1 ); - } - //// Color - MPlug colorPlug = dagNode.findPlug( MString( "rgbPP" ), &retStatus ); - if ( retStatus == MS::kSuccess ) - { - retStatus = colorPlug.getValue( tempObj ); - MFnVectorArrayData rgbData( tempObj, &retStatus ); - for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) - { - particlesFrame[nTemp].color.r = float( rgbData[idIndex[nTemp]].x ); - particlesFrame[nTemp].color.g = float( rgbData[idIndex[nTemp]].y ); - particlesFrame[nTemp].color.b = float( rgbData[idIndex[nTemp]].z ); - } - } - //// Opacity - MPlug alphaPlug = dagNode.findPlug( MString( "opacityPP" ), &retStatus ); - if ( retStatus == MS::kSuccess ) - { - retStatus = alphaPlug.getValue( tempObj ); - MFnDoubleArrayData alphaData( tempObj, &retStatus ); - for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) - particlesFrame[nTemp].color.a = float( alphaData[idIndex[nTemp]] ); - } + MStatus retStatus; + MFnDagNode dagNode( dagPath ); + //// + int nParticles = 0; + MPlug countPlug = dagNode.findPlug( MString( "count" ), &retStatus ); + retStatus = countPlug.getValue( nParticles ); + if ( nParticles <= 0 ) + return MS::kFailure; + //// + std::vector idIndex( nParticles ); + std::vector sortedId( nParticles ); + std::vector particlesFrame( nParticles ); + //// + MObject tempObj; + MPlug mappingPlug = dagNode.findPlug( MString( "idMapping" ), &retStatus ); + //// + MPlug idPlug = mappingPlug.child( 0 ); + retStatus = idPlug.getValue( tempObj ); + MFnIntArrayData sSortedIDArray( tempObj, &retStatus ); + for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) + sortedId[nTemp] = sSortedIDArray[nTemp]; + //// + MPlug indexPlug = mappingPlug.child( 1 ); + retStatus = indexPlug.getValue( tempObj ); + MFnIntArrayData idIndexArray( tempObj, &retStatus ); + for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) + idIndex[nTemp] = idIndexArray[nTemp]; + //// Position + MPlug posPlug = dagNode.findPlug( MString( "worldPosition" ), &retStatus ); + retStatus = posPlug.getValue( tempObj ); + MFnVectorArrayData posData( tempObj, &retStatus ); + for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) + { + SParticleData &particle = particlesFrame[nTemp]; + particle.nFrame = nFrame; + particle.pos.x = (float)posData[idIndex[nTemp]].x; + particle.pos.y = (float)posData[idIndex[nTemp]].y; + particle.pos.z = (float)posData[idIndex[nTemp]].z; + } + //// Rotation + MPlug rotPlug = dagNode.findPlug( MString( "spriteTwistPP" ), &retStatus ); + if ( retStatus == MS::kSuccess ) + { + retStatus = rotPlug.getValue( tempObj ); + MFnDoubleArrayData rotPlug( tempObj, &retStatus ); + for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) + particlesFrame[nTemp].fRotation = ToRadians( (float)rotPlug[idIndex[nTemp]] ); + } + //// ScaleX + MPlug scaleXPlug = dagNode.findPlug( MString( "spriteScaleXPP" ), &retStatus ); + if ( retStatus == MS::kSuccess ) + { + retStatus = scaleXPlug.getValue( tempObj ); + MFnDoubleArrayData scaleX( tempObj, &retStatus ); + for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) + particlesFrame[nTemp].scale.x = float( scaleX[idIndex[nTemp]] ); + } + //// ScaleY + MPlug scaleYPlug = dagNode.findPlug( MString( "spriteScaleYPP" ), &retStatus ); + if ( retStatus == MS::kSuccess ) + { + retStatus = scaleYPlug.getValue( tempObj ); + MFnDoubleArrayData scaleY( tempObj, &retStatus ); + for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) + particlesFrame[nTemp].scale.y = float( scaleY[idIndex[nTemp]] ); + } + //// Sprite + MPlug spritePlug = dagNode.findPlug( MString( "spriteNumPP" ), &retStatus ); + if ( retStatus == MS::kSuccess ) + { + retStatus = spritePlug.getValue( tempObj ); + MFnDoubleArrayData sprite( tempObj, &retStatus ); + for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) + particlesFrame[nTemp].nSprite = int( sprite[idIndex[nTemp]] - 1 ); + } + //// Color + MPlug colorPlug = dagNode.findPlug( MString( "rgbPP" ), &retStatus ); + if ( retStatus == MS::kSuccess ) + { + retStatus = colorPlug.getValue( tempObj ); + MFnVectorArrayData rgbData( tempObj, &retStatus ); + for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) + { + particlesFrame[nTemp].color.r = float( rgbData[idIndex[nTemp]].x ); + particlesFrame[nTemp].color.g = float( rgbData[idIndex[nTemp]].y ); + particlesFrame[nTemp].color.b = float( rgbData[idIndex[nTemp]].z ); + } + } + //// Opacity + MPlug alphaPlug = dagNode.findPlug( MString( "opacityPP" ), &retStatus ); + if ( retStatus == MS::kSuccess ) + { + retStatus = alphaPlug.getValue( tempObj ); + MFnDoubleArrayData alphaData( tempObj, &retStatus ); + for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) + particlesFrame[nTemp].color.a = float( alphaData[idIndex[nTemp]] ); + } - for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) - data[sortedId[nTemp]].push_back( particlesFrame[nTemp] ); + for ( int nTemp = 0; nTemp < nParticles; ++nTemp ) + data[sortedId[nTemp]].push_back( particlesFrame[nTemp] ); - return MS::kSuccess; + return MS::kSuccess; } //////////////////////////////////////////////////////////////////////////////////////////////////// MStatus Particles::FinalizeData( int nMinFrame, int nMaxFrame ) { - nFrames = nMaxFrame - nMinFrame + 1; - particleTracks.resize( data.size() ); + nFrames = nMaxFrame - nMinFrame + 1; + particleTracks.resize( data.size() ); - int nTemp = 0; - for ( CParticlesData::const_iterator iTemp = data.begin(); iTemp != data.end(); ++iTemp, ++nTemp ) - { - SParticle &particle = particleTracks[nTemp]; - //// - const CParticlesTrack &particlesTrack = iTemp->second; - int nEndFrame = particlesTrack.back().nFrame; - int nStartFrame = particlesTrack.front().nFrame; - int nFrames = nEndFrame - nStartFrame + 1; - //// - if ( nFrames != particlesTrack.size() ) - { - std::cout << "ERROR: particle dosn't exist in some frames (unsupported)!\n"; - std::cout.flush(); - return MS::kFailure; - } - //// - int nBeginTime = nStartFrame; - particle.nEndTime = nEndFrame; - particle.nStartTime = nStartFrame; - //// - std::vector tmpPos( nFrames ); - for ( int nTemp = 0; nTemp < nFrames; ++nTemp ) - tmpPos[nTemp] = particlesTrack[nTemp].pos; - MakeLinearSpline( tmpPos, nBeginTime, FP_MINDELTA, &particle.pos ); - //// - std::vector tmpRot( nFrames ); - for ( int nTemp = 0; nTemp < nFrames; ++nTemp ) - tmpRot[nTemp] = particlesTrack[nTemp].fRotation; - MakeLinearSpline( tmpRot, nBeginTime, FP_MINDELTA, &particle.rotation ); - //// - std::vector tmpScale( nFrames ); - for ( int nTemp = 0; nTemp < nFrames; ++nTemp ) - tmpScale[nTemp] = particlesTrack[nTemp].scale; - MakeLinearSpline( tmpScale, nBeginTime, FP_MINDELTA, &particle.scale ); - //// - std::vector tmpColor( nFrames ); - for ( int nTemp = 0; nTemp < nFrames; ++nTemp ) - tmpColor[nTemp] = particlesTrack[nTemp].color; - MakeLinearSpline( tmpColor, nBeginTime, FP_MINDELTA, &particle.color ); - //// - std::vector tmpSprite( nFrames ); - for ( int nTemp = 0; nTemp < nFrames; ++nTemp ) - tmpSprite[nTemp] = particlesTrack[nTemp].nSprite; - DropSame( tmpSprite, nBeginTime, &particle.sprite ); - } + int nTemp = 0; + for ( CParticlesData::const_iterator iTemp = data.begin(); iTemp != data.end(); ++iTemp, ++nTemp ) + { + SParticle &particle = particleTracks[nTemp]; + //// + const CParticlesTrack &particlesTrack = iTemp->second; + int nEndFrame = particlesTrack.back().nFrame; + int nStartFrame = particlesTrack.front().nFrame; + int nFrames = nEndFrame - nStartFrame + 1; + //// + if ( nFrames != particlesTrack.size() ) + { + std::cout << "ERROR: particle dosn't exist in some frames (unsupported)!\n"; + std::cout.flush(); + return MS::kFailure; + } + //// + int nBeginTime = nStartFrame; + particle.nEndTime = nEndFrame; + particle.nStartTime = nStartFrame; + //// + std::vector tmpPos( nFrames ); + for ( int nTemp = 0; nTemp < nFrames; ++nTemp ) + tmpPos[nTemp] = particlesTrack[nTemp].pos; + MakeLinearSpline( tmpPos, nBeginTime, FP_MINDELTA, &particle.pos ); + //// + std::vector tmpRot( nFrames ); + for ( int nTemp = 0; nTemp < nFrames; ++nTemp ) + tmpRot[nTemp] = particlesTrack[nTemp].fRotation; + MakeLinearSpline( tmpRot, nBeginTime, FP_MINDELTA, &particle.rotation ); + //// + std::vector tmpScale( nFrames ); + for ( int nTemp = 0; nTemp < nFrames; ++nTemp ) + tmpScale[nTemp] = particlesTrack[nTemp].scale; + MakeLinearSpline( tmpScale, nBeginTime, FP_MINDELTA, &particle.scale ); + //// + std::vector tmpColor( nFrames ); + for ( int nTemp = 0; nTemp < nFrames; ++nTemp ) + tmpColor[nTemp] = particlesTrack[nTemp].color; + MakeLinearSpline( tmpColor, nBeginTime, FP_MINDELTA, &particle.color ); + //// + std::vector tmpSprite( nFrames ); + for ( int nTemp = 0; nTemp < nFrames; ++nTemp ) + tmpSprite[nTemp] = particlesTrack[nTemp].nSprite; + DropSame( tmpSprite, nBeginTime, &particle.sprite ); + } - return MS::kSuccess; + return MS::kSuccess; } //////////////////////////////////////////////////////////////////////////////////////////////////// template bool CanDropValue( const T &value, const T &prevVal, const T &nextVal, int nDelta, int nRange, float fEpsilon ) { - T resVal; - float fCoeff = float( nDelta ) / nRange; - Interpolate( prevVal, nextVal, fCoeff, &resVal ); - if ( fabs( resVal - value ) < fEpsilon ) - return true; - //// - return false; + T resVal; + float fCoeff = float( nDelta ) / nRange; + Interpolate( prevVal, nextVal, fCoeff, &resVal ); + if ( fabs( resVal - value ) < fEpsilon ) + return true; + //// + return false; } //////////////////////////////////////////////////////////////////////////////////////////////////// template void MakeLinearSpline( const std::vector &values, int nBeginTime, float fEpsilon, TKeyTrack *pRes ) { - if ( values.size() == 0 ) - return; - //// - TKey startKey; - startKey.nTime = nBeginTime; - startKey.value = values.front(); - pRes->keys.push_back( startKey ); - if ( values.size() == 1 ) - return; - //// - uint nIndex = 0; - uint nPrevIndex = 0; - while( nIndex < values.size() - 1 ) - { - if ( !CanDropValue( values[nIndex], values[nPrevIndex], values[nIndex + 1], nIndex - nPrevIndex, nIndex - nPrevIndex + 1, fEpsilon ) ) - { - nPrevIndex = nIndex; - TKey resKey; - resKey.nTime = nBeginTime + nIndex; - resKey.value = values[nIndex]; - pRes->keys.push_back( resKey ); - } - //// - nIndex++; - } - //// - TKey endKey; - endKey.nTime = nBeginTime + values.size() - 1; - endKey.value = values.back(); - pRes->keys.push_back( endKey ); + if ( values.size() == 0 ) + return; + //// + TKey startKey; + startKey.nTime = nBeginTime; + startKey.value = values.front(); + pRes->keys.push_back( startKey ); + if ( values.size() == 1 ) + return; + //// + uint nIndex = 0; + uint nPrevIndex = 0; + while( nIndex < values.size() - 1 ) + { + if ( !CanDropValue( values[nIndex], values[nPrevIndex], values[nIndex + 1], nIndex - nPrevIndex, nIndex - nPrevIndex + 1, fEpsilon ) ) + { + nPrevIndex = nIndex; + TKey resKey; + resKey.nTime = nBeginTime + nIndex; + resKey.value = values[nIndex]; + pRes->keys.push_back( resKey ); + } + //// + nIndex++; + } + //// + TKey endKey; + endKey.nTime = nBeginTime + values.size() - 1; + endKey.value = values.back(); + pRes->keys.push_back( endKey ); } //////////////////////////////////////////////////////////////////////////////////////////////////// template void DropSame( const std::vector &values, int nBeginTime, TKeyTrack *pRes ) { - if ( values.size() == 0 ) - return; - //// - TKey startKey; - startKey.nTime = nBeginTime; - startKey.value = values.front(); - pRes->keys.push_back( startKey ); - if ( values.size() == 1 ) - return; - //// - T nCurrent = values.front(); - TKey curKey; - for ( uint nTemp = 1; nTemp < values.size() - 1; ++nTemp ) - { - if ( values[nTemp] != nCurrent ) - { - curKey.nTime = nBeginTime + nTemp; - curKey.value = values[nTemp]; - pRes->keys.push_back( curKey ); - //// - nCurrent = values[nTemp]; - } - } - //// - TKey endKey; - endKey.nTime = nBeginTime + values.size() - 1; - endKey.value = values.back(); - pRes->keys.push_back( endKey ); + if ( values.size() == 0 ) + return; + //// + TKey startKey; + startKey.nTime = nBeginTime; + startKey.value = values.front(); + pRes->keys.push_back( startKey ); + if ( values.size() == 1 ) + return; + //// + T nCurrent = values.front(); + TKey curKey; + for ( uint nTemp = 1; nTemp < values.size() - 1; ++nTemp ) + { + if ( values[nTemp] != nCurrent ) + { + curKey.nTime = nBeginTime + nTemp; + curKey.value = values[nTemp]; + pRes->keys.push_back( curKey ); + //// + nCurrent = values[nTemp]; + } + } + //// + TKey endKey; + endKey.nTime = nBeginTime + values.size() - 1; + endKey.value = values.back(); + pRes->keys.push_back( endKey ); } //////////////////////////////////////////////////////////////////////////////////////////////////// template void writeKeyToXML( std::ofstream &outStream, const TKey &data ) { - outStream << "\t\t\t\n"; + outStream << "\t\t\t\n"; } //////////////////////////////////////////////////////////////////////////////////////////////////// void writeKeyToXML( std::ofstream &outStream, const TKey &data ) { - outStream << "\t\t\t\n"; + outStream << "\t\t\t\n"; } //////////////////////////////////////////////////////////////////////////////////////////////////// void writeKeyToXML( std::ofstream &outStream, const TKey &data ) { - outStream << "\t\t\t\n"; + outStream << "\t\t\t\n"; } //////////////////////////////////////////////////////////////////////////////////////////////////// void writeKeyToXML( std::ofstream &outStream, const TKey &data ) { - outStream << "\t\t\t\n"; + outStream << "\t\t\t\n"; } //////////////////////////////////////////////////////////////////////////////////////////////////// template void writeTrackToXML( std::ofstream &outStream, const TKeyTrack &dataTrack, const std::string &name ) { - outStream << "\t\t<" << name.c_str() << " keys=\"" << dataTrack.keys.size() << "\" >\n"; - for ( uint nTemp = 0; nTemp < dataTrack.keys.size(); ++nTemp ) - writeKeyToXML( outStream, dataTrack.keys[nTemp] ); - outStream << "\t\t\n"; + outStream << "\t\t<" << name.c_str() << " keys=\"" << dataTrack.keys.size() << "\" >\n"; + for ( uint nTemp = 0; nTemp < dataTrack.keys.size(); ++nTemp ) + writeKeyToXML( outStream, dataTrack.keys[nTemp] ); + outStream << "\t\t\n"; } //////////////////////////////////////////////////////////////////////////////////////////////////// } // NAMESPACE diff --git a/Tools/MayaExport/src/skeleton.cpp b/Tools/MayaExport/src/skeleton.cpp index cce970d99d9..3a9a6fc275e 100644 --- a/Tools/MayaExport/src/skeleton.cpp +++ b/Tools/MayaExport/src/skeleton.cpp @@ -23,613 +23,613 @@ namespace OgreMayaExporter { - // Constructor - Skeleton::Skeleton() - { - m_joints.clear(); - m_animations.clear(); - m_restorePose = ""; - } - - - // Destructor - Skeleton::~Skeleton() - { - clear(); - } - - - // Clear skeleton data - void Skeleton::clear() - { - m_joints.clear(); - m_animations.clear(); - m_restorePose = ""; - } - - - // Load skeleton data from given skin cluster - MStatus Skeleton::load(MFnSkinCluster* pSkinCluster,ParamList& params) - { - MStatus stat; - //check for valid skin cluster pointer - if (!pSkinCluster) - { - std::cout << "Could not load skeleton data, no skin cluster specified\n"; - std::cout.flush(); - return MS::kFailure; - } - //retrieve and load joints from the skin cluster - MDagPath jointDag,rootDag; - MDagPathArray influenceDags; - int numInfluenceObjs = pSkinCluster->influenceObjects(influenceDags,&stat); - std::cout << "num influence objects: " << numInfluenceObjs << "\n"; - std::cout.flush(); - for (int i=0; i0) - { - jointDag.pop(); - if (jointDag.hasFn(MFn::kJoint) && jointDag.length()>0) - rootDag = jointDag; - } - //check if skeleton has already been loaded - bool skip = false; - for (int j=0; jname.asChar() << ")\n"; - std::cout.flush(); - } - else - { - std::cout << "\n"; - std::cout.flush(); - } - // Get parent index - int idx=-1; - if (parent) - { - for (int i=0; iname) - idx=i; - } - } - // Get world bind matrix - MMatrix bindMatrix = jointDag.inclusiveMatrix();; - // Calculate local bind matrix - MMatrix localMatrix; - if (parent) - localMatrix = bindMatrix * parent->bindMatrix.inverse(); - else - { // root node of skeleton - localMatrix = bindMatrix; - } - // Get translation - MVector translation = ((MTransformationMatrix)localMatrix).translation(MSpace::kPostTransform); - if (fabs(translation.x) < PRECISION) - translation.x = 0; - if (fabs(translation.y) < PRECISION) - translation.y = 0; - if (fabs(translation.z) < PRECISION) - translation.z = 0; - // Calculate rotation data - double qx,qy,qz,qw; - ((MTransformationMatrix)localMatrix).getRotationQuaternion(qx,qy,qz,qw); - MQuaternion rotation(qx,qy,qz,qw); - MVector axis; - double theta; - rotation.getAxisAngle(axis,theta); - if (fabs(axis.x) < PRECISION) - axis.x = 0; - if (fabs(axis.y) < PRECISION) - axis.y = 0; - if (fabs(axis.z) < PRECISION) - axis.z = 0; - axis.normalize(); - if (fabs(theta) < PRECISION) - theta = 0; - if (axis.length() < 0.5) - { - axis.x = 0; - axis.y = 1; - axis.z = 0; - theta = 0; - } - // Get joint scale - double scale[3]; - ((MTransformationMatrix)localMatrix).getScale(scale,MSpace::kPostTransform); - if (fabs(scale[0]) < PRECISION) - scale[0] = 0; - if (fabs(scale[1]) < PRECISION) - scale[1] = 0; - if (fabs(scale[2]) < PRECISION) - scale[2] = 0; - // Set joint info - newJoint.name = jointFn.partialPathName(); - newJoint.id = m_joints.size(); - newJoint.parentIndex = idx; - newJoint.bindMatrix = bindMatrix; - newJoint.localMatrix = localMatrix; - newJoint.posx = translation.x * params.lum; - newJoint.posy = translation.y * params.lum; - newJoint.posz = translation.z * params.lum; - newJoint.angle = theta; - newJoint.axisx = axis.x; - newJoint.axisy = axis.y; - newJoint.axisz = axis.z; - newJoint.scalex = scale[0]; - newJoint.scaley = scale[1]; - newJoint.scalez = scale[2]; - newJoint.jointDag = jointDag; - m_joints.push_back(newJoint); - // If root is a root joint, save its index in the roots list - if (idx < 0) - { - m_roots.push_back(m_joints.size() - 1); - } - // Get pointer to newly created joint - parentJoint = &newJoint; - } - // Load child joints - for (int i=0; i times; - // if skeleton has no joints we can't load the clip - if (m_joints.size() < 0) - return MS::kFailure; - // display clip name - std::cout << "clip \"" << clipName.asChar() << "\"\n"; - std::cout.flush(); - // calculate times from clip sample rate - times.clear(); - if (rate <= 0) - { - std::cout << "invalid sample rate for the clip (must be >0), we skip it\n"; - std::cout.flush(); - return MS::kFailure; - } - for (float t=start; t= 0) - length = times[times.size()-1] - times[0]; - if (length < 0) - { - std::cout << "invalid time range for the clip, we skip it\n"; - std::cout.flush(); - return MS::kFailure; - } - // create the animation - Animation a; - a.m_name = clipName.asChar(); - a.m_tracks.clear(); - a.m_length = length; - m_animations.push_back(a); - int animIdx = m_animations.size() - 1; - // create a track for current clip for all joints - std::vector animTracks; - for (int i=0; im_dagPath); - MPoint min = mesh.boundingBox().min(); - MPoint max = mesh.boundingBox().max(); - MBoundingBox bbox(min,max); - if (params.exportWorldCoords) - bbox.transformUsing(params.loadedSubmeshes[j]->m_dagPath.inclusiveMatrix()); - min = bbox.min() * params.lum; - max = bbox.max() * params.lum; - MBoundingBox newbbox(min,max); - params.loadedSubmeshes[j]->m_boundingBox.expand(newbbox); - } - } - } - // add created tracks to current clip - for (int i=0; i= 0) - { - // Get parent joint - MDagPath parentDag = m_joints[parentIdx].jointDag; - localMatrix = worldMatrix * parentDag.inclusiveMatrixInverse(); - } - else - { // Root node of skeleton - if (params.exportWorldCoords) - localMatrix = worldMatrix; - else - localMatrix = worldMatrix * j.jointDag.exclusiveMatrixInverse(); - } - // Get relative transformation matrix - MMatrix relMatrix = localMatrix * j.localMatrix.inverse(); - // Get relative translation - MVector translation = ((MTransformationMatrix)localMatrix).translation(MSpace::kPostTransform) - - ((MTransformationMatrix)j.localMatrix).translation(MSpace::kPostTransform); - if (fabs(translation.x) < PRECISION) - translation.x = 0; - if (fabs(translation.y) < PRECISION) - translation.y = 0; - if (fabs(translation.z) < PRECISION) - translation.z = 0; - // Get relative rotation - double qx,qy,qz,qw; - ((MTransformationMatrix)relMatrix).getRotationQuaternion(qx,qy,qz,qw); - MQuaternion rotation(qx,qy,qz,qw); - MVector axis; - double theta; - rotation.getAxisAngle(axis,theta); - while (theta > Ogre::Math::PI) - { - theta -= Ogre::Math::TWO_PI; - } - while (theta < -Ogre::Math::PI) - { - theta += Ogre::Math::TWO_PI; - } - if (fabs(axis.x) < PRECISION) - axis.x = 0; - if (fabs(axis.y) < PRECISION) - axis.y = 0; - if (fabs(axis.z) < PRECISION) - axis.z = 0; - axis.normalize(); - if (fabs(theta) < PRECISION) - theta = 0; - if (axis.length() < 0.5) - { - axis.x = 0; - axis.y = 1; - axis.z = 0; - theta = 0; - } - // Get relative scale - double scale[3]; - ((MTransformationMatrix)relMatrix).getScale(scale,MSpace::kPostTransform); - if (fabs(scale[0]) < PRECISION) - scale[0] = 0; - if (fabs(scale[1]) < PRECISION) - scale[1] = 0; - if (fabs(scale[2]) < PRECISION) - scale[2] = 0; - //create keyframe - skeletonKeyframe key; - key.time = time; - key.tx = translation.x * params.lum; - key.ty = translation.y * params.lum; - key.tz = translation.z * params.lum; - key.angle = theta; - key.axis_x = axis.x; - key.axis_y = axis.y; - key.axis_z = axis.z; - key.sx = scale[0]; - key.sy = scale[1]; - key.sz = scale[2]; - return key; - } - - - // Restore skeleton pose - void Skeleton::restorePose() - { - //enable constraints, IK, etc... - MGlobal::executeCommand("doEnableNodeItems true all",true); - // save current selection list - MSelectionList selectionList; - MGlobal::getActiveSelectionList(selectionList); - // restore the pose on all parts of the skeleton - for (int i=0; i& Skeleton::getJoints() - { - return m_joints; - } - - - - // Get animations - std::vector& Skeleton::getAnimations() - { - return m_animations; - } - - - - // Write to an OGRE binary skeleton - MStatus Skeleton::writeOgreBinary(ParamList ¶ms) - { - MStatus stat; - // Construct skeleton - MString name = "exportSkeleton"; - Ogre::SkeletonPtr pSkeleton = Ogre::SkeletonManager::getSingleton().create(name.asChar(), - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - // Create skeleton bones - stat = createOgreBones(pSkeleton,params); - if (stat != MS::kSuccess) - { - std::cout << "Error writing skeleton binary file\n"; - std::cout.flush(); - } - // Create skeleton animation - if (params.exportSkelAnims) - { - stat = createOgreSkeletonAnimations(pSkeleton,params); - if (stat != MS::kSuccess) - { - std::cout << "Error writing ogre skeleton animations\n"; - std::cout.flush(); - } - } - pSkeleton->setBindingPose(); - // Optimise animations - pSkeleton->optimiseAllAnimations(); - // Export skeleton binary - Ogre::SkeletonSerializer serializer; - serializer.exportSkeleton(pSkeleton.getPointer(),params.skeletonFilename.asChar()); - pSkeleton.setNull(); - // Skeleton successfully exported - return MS::kSuccess; - } - - // Write joints to an Ogre skeleton - MStatus Skeleton::createOgreBones(Ogre::SkeletonPtr pSkeleton,ParamList& params) - { - // Create the bones - for (int i=0; iname.asChar(); - int jointId = j->id; - Ogre::Bone* pBone = pSkeleton->createBone(jointName, jointId); - // Set bone position (relative to it's parent) - pBone->setPosition(j->posx,j->posy,j->posz); - // Set bone orientation (relative to it's parent) - Ogre::Quaternion orient; - orient.FromAngleAxis(Ogre::Radian(j->angle),Ogre::Vector3(j->axisx,j->axisy,j->axisz)); - pBone->setOrientation(orient); - // Set bone scale (relative to it's parent) - pBone->setScale(j->scalex,j->scaley,j->scalez); - } - // Create the hierarchy - for (int i=0; iparentIndex; - if (parentIdx >= 0) - { - // Get the parent joint - joint* parentJoint = &m_joints[parentIdx]; - unsigned short parentId = m_joints[parentIdx].id; - Ogre::String parentName = parentJoint->name.asChar(); - Ogre::Bone* pParent = pSkeleton->getBone(parentName); - // Get current joint from skeleton - unsigned short jointId = j->id; - Ogre::String jointName = j->name.asChar(); - Ogre::Bone* pBone = pSkeleton->getBone(jointName); - // Place current bone in the parent's child list - pParent->addChild(pBone); - } - } - return MS::kSuccess; - } - - - // Write skeleton animations to an Ogre skeleton - MStatus Skeleton::createOgreSkeletonAnimations(Ogre::SkeletonPtr pSkeleton,ParamList& params) - { - // Read loaded skeleton animations - for (int i=0; icreateAnimation(m_animations[i].m_name.asChar(), - m_animations[i].m_length); - // Create tracks for current animation - for (int j=0; jcreateNodeTrack(j, - pSkeleton->getBone(t->m_bone.asChar())); - // Create keyframes for current track - for (int k=0; km_skeletonKeyframes.size(); k++) - { - skeletonKeyframe* keyframe = &t->m_skeletonKeyframes[k]; - // Create a new keyframe - Ogre::TransformKeyFrame* pKeyframe = pTrack->createNodeKeyFrame(keyframe->time); - // Set translation - pKeyframe->setTranslate(Ogre::Vector3(keyframe->tx,keyframe->ty,keyframe->tz)); - // Set rotation - Ogre::Quaternion rot; - rot.FromAngleAxis(Ogre::Radian(keyframe->angle), - Ogre::Vector3(keyframe->axis_x,keyframe->axis_y,keyframe->axis_z)); - pKeyframe->setRotation(rot); - // Set scale - pKeyframe->setScale(Ogre::Vector3(keyframe->sx,keyframe->sy,keyframe->sz)); - } - } - } - return MS::kSuccess; - } - - -}; //end namespace \ No newline at end of file + // Constructor + Skeleton::Skeleton() + { + m_joints.clear(); + m_animations.clear(); + m_restorePose = ""; + } + + + // Destructor + Skeleton::~Skeleton() + { + clear(); + } + + + // Clear skeleton data + void Skeleton::clear() + { + m_joints.clear(); + m_animations.clear(); + m_restorePose = ""; + } + + + // Load skeleton data from given skin cluster + MStatus Skeleton::load(MFnSkinCluster* pSkinCluster,ParamList& params) + { + MStatus stat; + //check for valid skin cluster pointer + if (!pSkinCluster) + { + std::cout << "Could not load skeleton data, no skin cluster specified\n"; + std::cout.flush(); + return MS::kFailure; + } + //retrieve and load joints from the skin cluster + MDagPath jointDag,rootDag; + MDagPathArray influenceDags; + int numInfluenceObjs = pSkinCluster->influenceObjects(influenceDags,&stat); + std::cout << "num influence objects: " << numInfluenceObjs << "\n"; + std::cout.flush(); + for (int i=0; i0) + { + jointDag.pop(); + if (jointDag.hasFn(MFn::kJoint) && jointDag.length()>0) + rootDag = jointDag; + } + //check if skeleton has already been loaded + bool skip = false; + for (int j=0; jname.asChar() << ")\n"; + std::cout.flush(); + } + else + { + std::cout << "\n"; + std::cout.flush(); + } + // Get parent index + int idx=-1; + if (parent) + { + for (int i=0; iname) + idx=i; + } + } + // Get world bind matrix + MMatrix bindMatrix = jointDag.inclusiveMatrix();; + // Calculate local bind matrix + MMatrix localMatrix; + if (parent) + localMatrix = bindMatrix * parent->bindMatrix.inverse(); + else + { // root node of skeleton + localMatrix = bindMatrix; + } + // Get translation + MVector translation = ((MTransformationMatrix)localMatrix).translation(MSpace::kPostTransform); + if (fabs(translation.x) < PRECISION) + translation.x = 0; + if (fabs(translation.y) < PRECISION) + translation.y = 0; + if (fabs(translation.z) < PRECISION) + translation.z = 0; + // Calculate rotation data + double qx,qy,qz,qw; + ((MTransformationMatrix)localMatrix).getRotationQuaternion(qx,qy,qz,qw); + MQuaternion rotation(qx,qy,qz,qw); + MVector axis; + double theta; + rotation.getAxisAngle(axis,theta); + if (fabs(axis.x) < PRECISION) + axis.x = 0; + if (fabs(axis.y) < PRECISION) + axis.y = 0; + if (fabs(axis.z) < PRECISION) + axis.z = 0; + axis.normalize(); + if (fabs(theta) < PRECISION) + theta = 0; + if (axis.length() < 0.5) + { + axis.x = 0; + axis.y = 1; + axis.z = 0; + theta = 0; + } + // Get joint scale + double scale[3]; + ((MTransformationMatrix)localMatrix).getScale(scale,MSpace::kPostTransform); + if (fabs(scale[0]) < PRECISION) + scale[0] = 0; + if (fabs(scale[1]) < PRECISION) + scale[1] = 0; + if (fabs(scale[2]) < PRECISION) + scale[2] = 0; + // Set joint info + newJoint.name = jointFn.partialPathName(); + newJoint.id = m_joints.size(); + newJoint.parentIndex = idx; + newJoint.bindMatrix = bindMatrix; + newJoint.localMatrix = localMatrix; + newJoint.posx = translation.x * params.lum; + newJoint.posy = translation.y * params.lum; + newJoint.posz = translation.z * params.lum; + newJoint.angle = theta; + newJoint.axisx = axis.x; + newJoint.axisy = axis.y; + newJoint.axisz = axis.z; + newJoint.scalex = scale[0]; + newJoint.scaley = scale[1]; + newJoint.scalez = scale[2]; + newJoint.jointDag = jointDag; + m_joints.push_back(newJoint); + // If root is a root joint, save its index in the roots list + if (idx < 0) + { + m_roots.push_back(m_joints.size() - 1); + } + // Get pointer to newly created joint + parentJoint = &newJoint; + } + // Load child joints + for (int i=0; i times; + // if skeleton has no joints we can't load the clip + if (m_joints.size() < 0) + return MS::kFailure; + // display clip name + std::cout << "clip \"" << clipName.asChar() << "\"\n"; + std::cout.flush(); + // calculate times from clip sample rate + times.clear(); + if (rate <= 0) + { + std::cout << "invalid sample rate for the clip (must be >0), we skip it\n"; + std::cout.flush(); + return MS::kFailure; + } + for (float t=start; t= 0) + length = times[times.size()-1] - times[0]; + if (length < 0) + { + std::cout << "invalid time range for the clip, we skip it\n"; + std::cout.flush(); + return MS::kFailure; + } + // create the animation + Animation a; + a.m_name = clipName.asChar(); + a.m_tracks.clear(); + a.m_length = length; + m_animations.push_back(a); + int animIdx = m_animations.size() - 1; + // create a track for current clip for all joints + std::vector animTracks; + for (int i=0; im_dagPath); + MPoint min = mesh.boundingBox().min(); + MPoint max = mesh.boundingBox().max(); + MBoundingBox bbox(min,max); + if (params.exportWorldCoords) + bbox.transformUsing(params.loadedSubmeshes[j]->m_dagPath.inclusiveMatrix()); + min = bbox.min() * params.lum; + max = bbox.max() * params.lum; + MBoundingBox newbbox(min,max); + params.loadedSubmeshes[j]->m_boundingBox.expand(newbbox); + } + } + } + // add created tracks to current clip + for (int i=0; i= 0) + { + // Get parent joint + MDagPath parentDag = m_joints[parentIdx].jointDag; + localMatrix = worldMatrix * parentDag.inclusiveMatrixInverse(); + } + else + { // Root node of skeleton + if (params.exportWorldCoords) + localMatrix = worldMatrix; + else + localMatrix = worldMatrix * j.jointDag.exclusiveMatrixInverse(); + } + // Get relative transformation matrix + MMatrix relMatrix = localMatrix * j.localMatrix.inverse(); + // Get relative translation + MVector translation = ((MTransformationMatrix)localMatrix).translation(MSpace::kPostTransform) - + ((MTransformationMatrix)j.localMatrix).translation(MSpace::kPostTransform); + if (fabs(translation.x) < PRECISION) + translation.x = 0; + if (fabs(translation.y) < PRECISION) + translation.y = 0; + if (fabs(translation.z) < PRECISION) + translation.z = 0; + // Get relative rotation + double qx,qy,qz,qw; + ((MTransformationMatrix)relMatrix).getRotationQuaternion(qx,qy,qz,qw); + MQuaternion rotation(qx,qy,qz,qw); + MVector axis; + double theta; + rotation.getAxisAngle(axis,theta); + while (theta > Ogre::Math::PI) + { + theta -= Ogre::Math::TWO_PI; + } + while (theta < -Ogre::Math::PI) + { + theta += Ogre::Math::TWO_PI; + } + if (fabs(axis.x) < PRECISION) + axis.x = 0; + if (fabs(axis.y) < PRECISION) + axis.y = 0; + if (fabs(axis.z) < PRECISION) + axis.z = 0; + axis.normalize(); + if (fabs(theta) < PRECISION) + theta = 0; + if (axis.length() < 0.5) + { + axis.x = 0; + axis.y = 1; + axis.z = 0; + theta = 0; + } + // Get relative scale + double scale[3]; + ((MTransformationMatrix)relMatrix).getScale(scale,MSpace::kPostTransform); + if (fabs(scale[0]) < PRECISION) + scale[0] = 0; + if (fabs(scale[1]) < PRECISION) + scale[1] = 0; + if (fabs(scale[2]) < PRECISION) + scale[2] = 0; + //create keyframe + skeletonKeyframe key; + key.time = time; + key.tx = translation.x * params.lum; + key.ty = translation.y * params.lum; + key.tz = translation.z * params.lum; + key.angle = theta; + key.axis_x = axis.x; + key.axis_y = axis.y; + key.axis_z = axis.z; + key.sx = scale[0]; + key.sy = scale[1]; + key.sz = scale[2]; + return key; + } + + + // Restore skeleton pose + void Skeleton::restorePose() + { + //enable constraints, IK, etc... + MGlobal::executeCommand("doEnableNodeItems true all",true); + // save current selection list + MSelectionList selectionList; + MGlobal::getActiveSelectionList(selectionList); + // restore the pose on all parts of the skeleton + for (int i=0; i& Skeleton::getJoints() + { + return m_joints; + } + + + + // Get animations + std::vector& Skeleton::getAnimations() + { + return m_animations; + } + + + + // Write to an OGRE binary skeleton + MStatus Skeleton::writeOgreBinary(ParamList ¶ms) + { + MStatus stat; + // Construct skeleton + MString name = "exportSkeleton"; + Ogre::SkeletonPtr pSkeleton = Ogre::SkeletonManager::getSingleton().create(name.asChar(), + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + // Create skeleton bones + stat = createOgreBones(pSkeleton,params); + if (stat != MS::kSuccess) + { + std::cout << "Error writing skeleton binary file\n"; + std::cout.flush(); + } + // Create skeleton animation + if (params.exportSkelAnims) + { + stat = createOgreSkeletonAnimations(pSkeleton,params); + if (stat != MS::kSuccess) + { + std::cout << "Error writing ogre skeleton animations\n"; + std::cout.flush(); + } + } + pSkeleton->setBindingPose(); + // Optimise animations + pSkeleton->optimiseAllAnimations(); + // Export skeleton binary + Ogre::SkeletonSerializer serializer; + serializer.exportSkeleton(pSkeleton.getPointer(),params.skeletonFilename.asChar()); + pSkeleton.setNull(); + // Skeleton successfully exported + return MS::kSuccess; + } + + // Write joints to an Ogre skeleton + MStatus Skeleton::createOgreBones(Ogre::SkeletonPtr pSkeleton,ParamList& params) + { + // Create the bones + for (int i=0; iname.asChar(); + int jointId = j->id; + Ogre::Bone* pBone = pSkeleton->createBone(jointName, jointId); + // Set bone position (relative to it's parent) + pBone->setPosition(j->posx,j->posy,j->posz); + // Set bone orientation (relative to it's parent) + Ogre::Quaternion orient; + orient.FromAngleAxis(Ogre::Radian(j->angle),Ogre::Vector3(j->axisx,j->axisy,j->axisz)); + pBone->setOrientation(orient); + // Set bone scale (relative to it's parent) + pBone->setScale(j->scalex,j->scaley,j->scalez); + } + // Create the hierarchy + for (int i=0; iparentIndex; + if (parentIdx >= 0) + { + // Get the parent joint + joint* parentJoint = &m_joints[parentIdx]; + unsigned short parentId = m_joints[parentIdx].id; + Ogre::String parentName = parentJoint->name.asChar(); + Ogre::Bone* pParent = pSkeleton->getBone(parentName); + // Get current joint from skeleton + unsigned short jointId = j->id; + Ogre::String jointName = j->name.asChar(); + Ogre::Bone* pBone = pSkeleton->getBone(jointName); + // Place current bone in the parent's child list + pParent->addChild(pBone); + } + } + return MS::kSuccess; + } + + + // Write skeleton animations to an Ogre skeleton + MStatus Skeleton::createOgreSkeletonAnimations(Ogre::SkeletonPtr pSkeleton,ParamList& params) + { + // Read loaded skeleton animations + for (int i=0; icreateAnimation(m_animations[i].m_name.asChar(), + m_animations[i].m_length); + // Create tracks for current animation + for (int j=0; jcreateNodeTrack(j, + pSkeleton->getBone(t->m_bone.asChar())); + // Create keyframes for current track + for (int k=0; km_skeletonKeyframes.size(); k++) + { + skeletonKeyframe* keyframe = &t->m_skeletonKeyframes[k]; + // Create a new keyframe + Ogre::TransformKeyFrame* pKeyframe = pTrack->createNodeKeyFrame(keyframe->time); + // Set translation + pKeyframe->setTranslate(Ogre::Vector3(keyframe->tx,keyframe->ty,keyframe->tz)); + // Set rotation + Ogre::Quaternion rot; + rot.FromAngleAxis(Ogre::Radian(keyframe->angle), + Ogre::Vector3(keyframe->axis_x,keyframe->axis_y,keyframe->axis_z)); + pKeyframe->setRotation(rot); + // Set scale + pKeyframe->setScale(Ogre::Vector3(keyframe->sx,keyframe->sy,keyframe->sz)); + } + } + } + return MS::kSuccess; + } + + +}; //end namespace \ No newline at end of file diff --git a/Tools/MayaExport/src/submesh.cpp b/Tools/MayaExport/src/submesh.cpp index 3e67e988220..85c16e8a63a 100644 --- a/Tools/MayaExport/src/submesh.cpp +++ b/Tools/MayaExport/src/submesh.cpp @@ -20,514 +20,514 @@ namespace OgreMayaExporter { - /***** Class Submesh *****/ - // constructor - Submesh::Submesh(const MString& name) - { - m_pBlendShape = NULL; - clear(); - m_name = name; - } + /***** Class Submesh *****/ + // constructor + Submesh::Submesh(const MString& name) + { + m_pBlendShape = NULL; + clear(); + m_name = name; + } - // destructor - Submesh::~Submesh() - { - clear(); - } + // destructor + Submesh::~Submesh() + { + clear(); + } - // clear data - void Submesh::clear() - { - m_name = ""; - m_numTriangles = 0; - m_pMaterial = NULL; - m_indices.clear(); - m_vertices.clear(); - m_faces.clear(); - m_uvsets.clear(); - m_use32bitIndexes = false; - m_pBlendShape = NULL; - } + // clear data + void Submesh::clear() + { + m_name = ""; + m_numTriangles = 0; + m_pMaterial = NULL; + m_indices.clear(); + m_vertices.clear(); + m_faces.clear(); + m_uvsets.clear(); + m_use32bitIndexes = false; + m_pBlendShape = NULL; + } - // return number of triangles composing the mesh - long Submesh::numTriangles() - { - return m_numTriangles; - } + // return number of triangles composing the mesh + long Submesh::numTriangles() + { + return m_numTriangles; + } - // return number of vertices composing the mesh - long Submesh::numVertices() - { - return m_numVertices; - } + // return number of vertices composing the mesh + long Submesh::numVertices() + { + return m_numVertices; + } - // return submesh name - MString& Submesh::name() - { - return m_name; - } + // return submesh name + MString& Submesh::name() + { + return m_name; + } /***** load data *****/ - MStatus Submesh::loadMaterial(MObject& shader,MStringArray& uvsets,ParamList& params) - { - MPlug plug; - MPlugArray srcplugarray; - bool foundShader = false; - MStatus stat; - MFnDependencyNode* pShader; - //get shader from shading group - MFnDependencyNode shadingGroup(shader); - plug = shadingGroup.findPlug("surfaceShader"); - plug.connectedTo(srcplugarray,true,false,&stat); - for (int i=0; iname().asChar() << "\n"; - std::cout.flush(); - //check if this material has already been created - //fix material name, adding the requested prefix - MString tmpStr = params.matPrefix; - if (tmpStr != "") - tmpStr += "/"; - tmpStr += pShader->name(); - MStringArray tmpStrArray; - tmpStr.split(':',tmpStrArray); - MString name = ""; - for (int i=0; iload(pShader,uvsets,params); - m_pMaterial = pMaterial; - MaterialSet::getSingleton().addMaterial(pMaterial); - } - //delete temporary shader - delete pShader; - } - else - { - std::cout << "Unsupported material, replacing with default lambert\n"; - std::cout.flush(); - m_pMaterial = MaterialSet::getSingleton().getDefaultMaterial(); - } - - //loading complete - return MS::kSuccess; - } + MStatus Submesh::loadMaterial(MObject& shader,MStringArray& uvsets,ParamList& params) + { + MPlug plug; + MPlugArray srcplugarray; + bool foundShader = false; + MStatus stat; + MFnDependencyNode* pShader; + //get shader from shading group + MFnDependencyNode shadingGroup(shader); + plug = shadingGroup.findPlug("surfaceShader"); + plug.connectedTo(srcplugarray,true,false,&stat); + for (int i=0; iname().asChar() << "\n"; + std::cout.flush(); + //check if this material has already been created + //fix material name, adding the requested prefix + MString tmpStr = params.matPrefix; + if (tmpStr != "") + tmpStr += "/"; + tmpStr += pShader->name(); + MStringArray tmpStrArray; + tmpStr.split(':',tmpStrArray); + MString name = ""; + for (int i=0; iload(pShader,uvsets,params); + m_pMaterial = pMaterial; + MaterialSet::getSingleton().addMaterial(pMaterial); + } + //delete temporary shader + delete pShader; + } + else + { + std::cout << "Unsupported material, replacing with default lambert\n"; + std::cout.flush(); + m_pMaterial = MaterialSet::getSingleton().getDefaultMaterial(); + } + + //loading complete + return MS::kSuccess; + } - MStatus Submesh::load(const MDagPath& dag,std::vector& faces, std::vector& vertInfo, MPointArray& points, - MFloatVectorArray& normals, MStringArray& texcoordsets,ParamList& params,bool opposite) - { - //save the dag path of the maya node from which this submesh will be created - m_dagPath = dag; - //create the mesh Fn - MFnMesh mesh(dag); - std::cout << "Loading submesh : " << m_name.asChar() << "..."; - std::cout.flush(); - //save uvsets info - for (int i=m_uvsets.size(); i vtx_mapping; - vtx_mapping.resize(vertInfo.size()); - for (int i=0; i PRECISION) - v.vbas.push_back(newVba); - } - // save texture coordinates - for (int k=0; k 65535) || (m_faces.size() > 65535)) - m_use32bitIndexes = true; - else - m_use32bitIndexes = false; - // get submesh bounding box - MPoint min = mesh.boundingBox().min(); - MPoint max = mesh.boundingBox().max(); - MBoundingBox bbox(min,max); - if (params.exportWorldCoords) - bbox.transformUsing(dag.inclusiveMatrix()); - min = bbox.min() * params.lum; - max = bbox.max() * params.lum; - MBoundingBox newbbox(min,max); - m_boundingBox = newbbox; - // add submesh pointer to parameters list - params.loadedSubmeshes.push_back(this); + MStatus Submesh::load(const MDagPath& dag,std::vector& faces, std::vector& vertInfo, MPointArray& points, + MFloatVectorArray& normals, MStringArray& texcoordsets,ParamList& params,bool opposite) + { + //save the dag path of the maya node from which this submesh will be created + m_dagPath = dag; + //create the mesh Fn + MFnMesh mesh(dag); + std::cout << "Loading submesh : " << m_name.asChar() << "..."; + std::cout.flush(); + //save uvsets info + for (int i=m_uvsets.size(); i vtx_mapping; + vtx_mapping.resize(vertInfo.size()); + for (int i=0; i PRECISION) + v.vbas.push_back(newVba); + } + // save texture coordinates + for (int k=0; k 65535) || (m_faces.size() > 65535)) + m_use32bitIndexes = true; + else + m_use32bitIndexes = false; + // get submesh bounding box + MPoint min = mesh.boundingBox().min(); + MPoint max = mesh.boundingBox().max(); + MBoundingBox bbox(min,max); + if (params.exportWorldCoords) + bbox.transformUsing(dag.inclusiveMatrix()); + min = bbox.min() * params.lum; + max = bbox.max() * params.lum; + MBoundingBox newbbox(min,max); + m_boundingBox = newbbox; + // add submesh pointer to parameters list + params.loadedSubmeshes.push_back(this); - std::cout << "DONE\n"; - std::cout.flush(); - return MS::kSuccess; - } + std::cout << "DONE\n"; + std::cout.flush(); + return MS::kSuccess; + } - // Load a keyframe for this submesh - MStatus Submesh::loadKeyframe(Track& t,float time,ParamList& params) - { - // create a new keyframe - vertexKeyframe k; - // set keyframe time - k.time = time; - // get the mesh Fn - MFnMesh mesh(m_dagPath); - // get vertex positions - MFloatPointArray points; - if (params.exportWorldCoords) - mesh.getPoints(points,MSpace::kWorld); - else - mesh.getPoints(points,MSpace::kObject); - // calculate vertex offsets - for (int i=0; icreateSubMesh(m_name.asChar()); - else - pSubmesh = pMesh->createSubMesh(); - // Set material + // Write submesh data to an Ogre compatible mesh + MStatus Submesh::createOgreSubmesh(Ogre::MeshPtr pMesh,const ParamList& params) + { + MStatus stat; + // Create a new submesh + Ogre::SubMesh* pSubmesh; + if (m_name != "") + pSubmesh = pMesh->createSubMesh(m_name.asChar()); + else + pSubmesh = pMesh->createSubMesh(); + // Set material pSubmesh->setMaterialName(m_pMaterial->name().asChar()); // Set use shared geometry flag - pSubmesh->useSharedVertices = params.useSharedGeom; - // Create vertex data for current submesh - pSubmesh->vertexData = new Ogre::VertexData(); + pSubmesh->useSharedVertices = params.useSharedGeom; + // Create vertex data for current submesh + pSubmesh->vertexData = new Ogre::VertexData(); // Set number of indexes pSubmesh->indexData->indexCount = 3*m_faces.size(); - pSubmesh->vertexData->vertexCount = m_vertices.size(); - // Check if we need to use 32 bit indexes - bool use32BitIndexes = false; - if (m_vertices.size() > 65536 || params.useSharedGeom) - { - use32BitIndexes = true; - } - // Create a new index buffer - pSubmesh->indexData->indexBuffer = - Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( - use32BitIndexes ? Ogre::HardwareIndexBuffer::IT_32BIT : Ogre::HardwareIndexBuffer::IT_16BIT, - pSubmesh->indexData->indexCount, - Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); - // Fill the index buffer with faces data - if (use32BitIndexes) + pSubmesh->vertexData->vertexCount = m_vertices.size(); + // Check if we need to use 32 bit indexes + bool use32BitIndexes = false; + if (m_vertices.size() > 65536 || params.useSharedGeom) + { + use32BitIndexes = true; + } + // Create a new index buffer + pSubmesh->indexData->indexBuffer = + Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( + use32BitIndexes ? Ogre::HardwareIndexBuffer::IT_32BIT : Ogre::HardwareIndexBuffer::IT_16BIT, + pSubmesh->indexData->indexCount, + Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); + // Fill the index buffer with faces data + if (use32BitIndexes) { - Ogre::uint32* pIdx = static_cast( - pSubmesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); - for (int i=0; i(m_faces[i].v[0]); - *pIdx++ = static_cast(m_faces[i].v[1]); - *pIdx++ = static_cast(m_faces[i].v[2]); - } - pSubmesh->indexData->indexBuffer->unlock(); + Ogre::uint32* pIdx = static_cast( + pSubmesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); + for (int i=0; i(m_faces[i].v[0]); + *pIdx++ = static_cast(m_faces[i].v[1]); + *pIdx++ = static_cast(m_faces[i].v[2]); + } + pSubmesh->indexData->indexBuffer->unlock(); } else { Ogre::uint16* pIdx = static_cast( - pSubmesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); + pSubmesh->indexData->indexBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD)); for (int i=0; i(m_faces[i].v[0]); - *pIdx++ = static_cast(m_faces[i].v[1]); - *pIdx++ = static_cast(m_faces[i].v[2]); - } - pSubmesh->indexData->indexBuffer->unlock(); - } - // Define vertex declaration (only if we're not using shared geometry) - if(!params.useSharedGeom) - { - Ogre::VertexDeclaration* pDecl = pSubmesh->vertexData->vertexDeclaration; - unsigned buf = 0; - size_t offset = 0; - // Add vertex position - pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); - offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); - // Add vertex normal - if (params.exportVertNorm) - { - pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); - offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); - } - // Add vertex colour - if(params.exportVertCol) - { - pDecl->addElement(buf, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); - offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR); - } - // Add texture coordinates - for (int i=0; iaddElement(buf, offset, uvType, Ogre::VES_TEXTURE_COORDINATES, i); - offset += Ogre::VertexElement::getTypeSize(uvType); - } - Ogre::VertexDeclaration* pOptimalDecl = pDecl->getAutoOrganisedDeclaration( - params.exportVBA,params.exportBlendShapes || params.exportVertAnims); - // Fill the vertex buffer using the newly created vertex declaration - stat = createOgreVertexBuffer(pSubmesh,pDecl,m_vertices); - // Write vertex bone assignements list - if (params.exportVBA) - { - // Create a new vertex bone assignements list - Ogre::SubMesh::VertexBoneAssignmentList vbas; - // Scan list of shared geometry vertices - for (int i=0; iparent->_rationaliseBoneAssignments(pSubmesh->vertexData->vertexCount,vbas); - // Add bone assignements to the submesh - for (Ogre::SubMesh::VertexBoneAssignmentList::iterator bi = vbas.begin(); bi != vbas.end(); bi++) - { - pSubmesh->addBoneAssignment(bi->second); - } - pSubmesh->_compileBoneAssignments(); - } - pSubmesh->vertexData->reorganiseBuffers(pOptimalDecl); - } - return MS::kSuccess; - } + { + *pIdx++ = static_cast(m_faces[i].v[0]); + *pIdx++ = static_cast(m_faces[i].v[1]); + *pIdx++ = static_cast(m_faces[i].v[2]); + } + pSubmesh->indexData->indexBuffer->unlock(); + } + // Define vertex declaration (only if we're not using shared geometry) + if(!params.useSharedGeom) + { + Ogre::VertexDeclaration* pDecl = pSubmesh->vertexData->vertexDeclaration; + unsigned buf = 0; + size_t offset = 0; + // Add vertex position + pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION); + offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); + // Add vertex normal + if (params.exportVertNorm) + { + pDecl->addElement(buf, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL); + offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3); + } + // Add vertex colour + if(params.exportVertCol) + { + pDecl->addElement(buf, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE); + offset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR); + } + // Add texture coordinates + for (int i=0; iaddElement(buf, offset, uvType, Ogre::VES_TEXTURE_COORDINATES, i); + offset += Ogre::VertexElement::getTypeSize(uvType); + } + Ogre::VertexDeclaration* pOptimalDecl = pDecl->getAutoOrganisedDeclaration( + params.exportVBA,params.exportBlendShapes || params.exportVertAnims); + // Fill the vertex buffer using the newly created vertex declaration + stat = createOgreVertexBuffer(pSubmesh,pDecl,m_vertices); + // Write vertex bone assignements list + if (params.exportVBA) + { + // Create a new vertex bone assignements list + Ogre::SubMesh::VertexBoneAssignmentList vbas; + // Scan list of shared geometry vertices + for (int i=0; iparent->_rationaliseBoneAssignments(pSubmesh->vertexData->vertexCount,vbas); + // Add bone assignements to the submesh + for (Ogre::SubMesh::VertexBoneAssignmentList::iterator bi = vbas.begin(); bi != vbas.end(); bi++) + { + pSubmesh->addBoneAssignment(bi->second); + } + pSubmesh->_compileBoneAssignments(); + } + pSubmesh->vertexData->reorganiseBuffers(pOptimalDecl); + } + return MS::kSuccess; + } - // Create an Ogre compatible vertex buffer - MStatus Submesh::createOgreVertexBuffer(Ogre::SubMesh* pSubmesh,Ogre::VertexDeclaration* pDecl,const std::vector& vertices) - { - Ogre::HardwareVertexBufferSharedPtr vbuf = - Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(pDecl->getVertexSize(0), - pSubmesh->vertexData->vertexCount, - Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); - pSubmesh->vertexData->vertexBufferBinding->setBinding(0, vbuf); - size_t vertexSize = pDecl->getVertexSize(0); - char* pBase = static_cast(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); - Ogre::VertexDeclaration::VertexElementList elems = pDecl->findElementsBySource(0); - Ogre::VertexDeclaration::VertexElementList::iterator ei, eiend; - eiend = elems.end(); - float* pFloat; - Ogre::RGBA* pRGBA; - // Fill the vertex buffer with shared geometry data - Ogre::ColourValue col; - float ucoord, vcoord; - for (long vi=0; viunlock(); - return MS::kSuccess; - } + // Create an Ogre compatible vertex buffer + MStatus Submesh::createOgreVertexBuffer(Ogre::SubMesh* pSubmesh,Ogre::VertexDeclaration* pDecl,const std::vector& vertices) + { + Ogre::HardwareVertexBufferSharedPtr vbuf = + Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(pDecl->getVertexSize(0), + pSubmesh->vertexData->vertexCount, + Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY); + pSubmesh->vertexData->vertexBufferBinding->setBinding(0, vbuf); + size_t vertexSize = pDecl->getVertexSize(0); + char* pBase = static_cast(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD)); + Ogre::VertexDeclaration::VertexElementList elems = pDecl->findElementsBySource(0); + Ogre::VertexDeclaration::VertexElementList::iterator ei, eiend; + eiend = elems.end(); + float* pFloat; + Ogre::RGBA* pRGBA; + // Fill the vertex buffer with shared geometry data + Ogre::ColourValue col; + float ucoord, vcoord; + for (long vi=0; viunlock(); + return MS::kSuccess; + } }; //end of namespace diff --git a/Tools/MeshUpgrader/src/main.cpp b/Tools/MeshUpgrader/src/main.cpp index db1d80405a5..72bc931231c 100644 --- a/Tools/MeshUpgrader/src/main.cpp +++ b/Tools/MeshUpgrader/src/main.cpp @@ -50,28 +50,28 @@ void help(void) cout << endl << "OgreMeshUpgrader: Upgrades or downgrades .mesh file versions." << endl; cout << "Provided for OGRE by Steve Streeting 2004-2014" << endl << endl; cout << "Usage: OgreMeshUpgrader [opts] sourcefile [destfile] " << endl; - cout << "-i = Interactive mode, prompt for options" << endl; - cout << "-autogen = Generate autoconfigured LOD. No more LOD options needed!" << endl; - cout << "-l lodlevels = number of LOD levels" << endl; - cout << "-d loddist = distance increment to reduce LOD" << endl; - cout << "-p lodpercent = Percentage triangle reduction amount per LOD" << endl; - cout << "-f lodnumtris = Fixed vertex reduction per LOD" << endl; + cout << "-i = Interactive mode, prompt for options" << endl; + cout << "-autogen = Generate autoconfigured LOD. No more LOD options needed!" << endl; + cout << "-l lodlevels = number of LOD levels" << endl; + cout << "-d loddist = distance increment to reduce LOD" << endl; + cout << "-p lodpercent = Percentage triangle reduction amount per LOD" << endl; + cout << "-f lodnumtris = Fixed vertex reduction per LOD" << endl; cout << "-e = DON'T generate edge lists (for stencil shadows)" << endl; cout << "-t = Generate tangents (for normal mapping)" << endl; - cout << "-td [uvw|tangent]" << endl; - cout << " = Tangent vertex semantic destination (default tangent)" << endl; - cout << "-ts [3|4] = Tangent size (3 or 4 components, 4 includes parity, default 3)" << endl; - cout << "-tm = Split tangent vertices at UV mirror points" << endl; - cout << "-tr = Split tangent vertices where basis is rotated > 90 degrees" << endl; - cout << "-r = DON'T reorganise buffers to recommended format" << endl; - cout << "-d3d = Convert to D3D colour formats" << endl; - cout << "-gl = Convert to GL colour formats" << endl; - cout << "-srcd3d = Interpret ambiguous colours as D3D style" << endl; - cout << "-srcgl = Interpret ambiguous colours as GL style" << endl; - cout << "-E endian = Set endian mode 'big' 'little' or 'native' (default)" << endl; - cout << "-b = Recalculate bounding box (static meshes only)" << endl; - cout << "-V version = Specify OGRE version format to write instead of latest" << endl; - cout << " Options are: 1.10, 1.8, 1.7, 1.4, 1.0" << endl; + cout << "-td [uvw|tangent]" << endl; + cout << " = Tangent vertex semantic destination (default tangent)" << endl; + cout << "-ts [3|4] = Tangent size (3 or 4 components, 4 includes parity, default 3)" << endl; + cout << "-tm = Split tangent vertices at UV mirror points" << endl; + cout << "-tr = Split tangent vertices where basis is rotated > 90 degrees" << endl; + cout << "-r = DON'T reorganise buffers to recommended format" << endl; + cout << "-d3d = Convert to D3D colour formats" << endl; + cout << "-gl = Convert to GL colour formats" << endl; + cout << "-srcd3d = Interpret ambiguous colours as D3D style" << endl; + cout << "-srcgl = Interpret ambiguous colours as GL style" << endl; + cout << "-E endian = Set endian mode 'big' 'little' or 'native' (default)" << endl; + cout << "-b = Recalculate bounding box (static meshes only)" << endl; + cout << "-V version = Specify OGRE version format to write instead of latest" << endl; + cout << " Options are: 1.10, 1.8, 1.7, 1.4, 1.0" << endl; cout << "sourcefile = name of file to convert" << endl; cout << "destfile = optional name of file to write to. If you don't" << endl; cout << " specify this OGRE overwrites the existing file." << endl; @@ -80,27 +80,27 @@ void help(void) } struct UpgradeOptions { - bool interactive; - bool suppressEdgeLists; - bool generateTangents; - VertexElementSemantic tangentSemantic; - bool tangentUseParity; - bool tangentSplitMirrored; - bool tangentSplitRotated; - bool dontReorganise; - bool destColourFormatSet; - VertexElementType destColourFormat; - bool srcColourFormatSet; - VertexElementType srcColourFormat; - bool lodAutoconfigure; - unsigned short numLods; - Real lodDist; - Real lodPercent; - size_t lodFixed; - bool usePercent; - Serializer::Endian endian; - bool recalcBounds; - MeshVersion targetVersion; + bool interactive; + bool suppressEdgeLists; + bool generateTangents; + VertexElementSemantic tangentSemantic; + bool tangentUseParity; + bool tangentSplitMirrored; + bool tangentSplitRotated; + bool dontReorganise; + bool destColourFormatSet; + VertexElementType destColourFormat; + bool srcColourFormatSet; + VertexElementType srcColourFormat; + bool lodAutoconfigure; + unsigned short numLods; + Real lodDist; + Real lodPercent; + size_t lodFixed; + bool usePercent; + Serializer::Endian endian; + bool recalcBounds; + MeshVersion targetVersion; }; @@ -122,1052 +122,1052 @@ UpgradeOptions opts; void parseOpts(UnaryOptionList& unOpts, BinaryOptionList& binOpts) { - opts.interactive = false; - opts.suppressEdgeLists = false; - opts.generateTangents = false; - opts.tangentSemantic = VES_TANGENT; - opts.tangentUseParity = false; - opts.tangentSplitMirrored = false; - opts.tangentSplitRotated = false; - opts.dontReorganise = false; - opts.endian = Serializer::ENDIAN_NATIVE; - opts.destColourFormatSet = false; - opts.srcColourFormatSet = false; - - opts.lodAutoconfigure = false; - opts.lodDist = 500; - opts.lodFixed = 0; - opts.lodPercent = 20; - opts.numLods = 0; - opts.usePercent = true; - opts.recalcBounds = false; - opts.targetVersion = MESH_VERSION_LATEST; - - - UnaryOptionList::iterator ui = unOpts.find("-e"); - opts.suppressEdgeLists = ui->second; - ui = unOpts.find("-t"); - opts.generateTangents = ui->second; - ui = unOpts.find("-tm"); - opts.tangentSplitMirrored = ui->second; - ui = unOpts.find("-tr"); - opts.tangentSplitRotated = ui->second; - - ui = unOpts.find("-autogen"); - opts.lodAutoconfigure = ui->second; - - ui = unOpts.find("-i"); - opts.interactive = ui->second; - ui = unOpts.find("-r"); - opts.dontReorganise = ui->second; - ui = unOpts.find("-d3d"); - if (ui->second) { - opts.destColourFormatSet = true; - opts.destColourFormat = VET_COLOUR_ARGB; - } - ui = unOpts.find("-gl"); - if (ui->second) { - opts.destColourFormatSet = true; - opts.destColourFormat = VET_COLOUR_ABGR; - } - ui = unOpts.find("-srcd3d"); - if (ui->second) { - opts.srcColourFormatSet = true; - opts.srcColourFormat = VET_COLOUR_ARGB; - } - ui = unOpts.find("-srcgl"); - if (ui->second) { - opts.srcColourFormatSet = true; - opts.srcColourFormat = VET_COLOUR_ABGR; - } - ui = unOpts.find("-b"); - if (ui->second) { - opts.recalcBounds = true; - } - - - BinaryOptionList::iterator bi = binOpts.find("-l"); - if (!bi->second.empty()) { - opts.numLods = StringConverter::parseInt(bi->second); - } - - bi = binOpts.find("-d"); - if (!bi->second.empty()) { - opts.lodDist = StringConverter::parseReal(bi->second); - } - - bi = binOpts.find("-p"); - if (!bi->second.empty()) { - opts.lodPercent = StringConverter::parseReal(bi->second); - opts.usePercent = true; - } - - - bi = binOpts.find("-f"); - if (!bi->second.empty()) { - opts.lodFixed = StringConverter::parseInt(bi->second); - opts.usePercent = false; - } - - bi = binOpts.find("-E"); - if (!bi->second.empty()) { - if (bi->second == "big") { + opts.interactive = false; + opts.suppressEdgeLists = false; + opts.generateTangents = false; + opts.tangentSemantic = VES_TANGENT; + opts.tangentUseParity = false; + opts.tangentSplitMirrored = false; + opts.tangentSplitRotated = false; + opts.dontReorganise = false; + opts.endian = Serializer::ENDIAN_NATIVE; + opts.destColourFormatSet = false; + opts.srcColourFormatSet = false; + + opts.lodAutoconfigure = false; + opts.lodDist = 500; + opts.lodFixed = 0; + opts.lodPercent = 20; + opts.numLods = 0; + opts.usePercent = true; + opts.recalcBounds = false; + opts.targetVersion = MESH_VERSION_LATEST; + + + UnaryOptionList::iterator ui = unOpts.find("-e"); + opts.suppressEdgeLists = ui->second; + ui = unOpts.find("-t"); + opts.generateTangents = ui->second; + ui = unOpts.find("-tm"); + opts.tangentSplitMirrored = ui->second; + ui = unOpts.find("-tr"); + opts.tangentSplitRotated = ui->second; + + ui = unOpts.find("-autogen"); + opts.lodAutoconfigure = ui->second; + + ui = unOpts.find("-i"); + opts.interactive = ui->second; + ui = unOpts.find("-r"); + opts.dontReorganise = ui->second; + ui = unOpts.find("-d3d"); + if (ui->second) { + opts.destColourFormatSet = true; + opts.destColourFormat = VET_COLOUR_ARGB; + } + ui = unOpts.find("-gl"); + if (ui->second) { + opts.destColourFormatSet = true; + opts.destColourFormat = VET_COLOUR_ABGR; + } + ui = unOpts.find("-srcd3d"); + if (ui->second) { + opts.srcColourFormatSet = true; + opts.srcColourFormat = VET_COLOUR_ARGB; + } + ui = unOpts.find("-srcgl"); + if (ui->second) { + opts.srcColourFormatSet = true; + opts.srcColourFormat = VET_COLOUR_ABGR; + } + ui = unOpts.find("-b"); + if (ui->second) { + opts.recalcBounds = true; + } + + + BinaryOptionList::iterator bi = binOpts.find("-l"); + if (!bi->second.empty()) { + opts.numLods = StringConverter::parseInt(bi->second); + } + + bi = binOpts.find("-d"); + if (!bi->second.empty()) { + opts.lodDist = StringConverter::parseReal(bi->second); + } + + bi = binOpts.find("-p"); + if (!bi->second.empty()) { + opts.lodPercent = StringConverter::parseReal(bi->second); + opts.usePercent = true; + } + + + bi = binOpts.find("-f"); + if (!bi->second.empty()) { + opts.lodFixed = StringConverter::parseInt(bi->second); + opts.usePercent = false; + } + + bi = binOpts.find("-E"); + if (!bi->second.empty()) { + if (bi->second == "big") { opts.endian = Serializer::ENDIAN_BIG; - } else if (bi->second == "little") { + } else if (bi->second == "little") { opts.endian = Serializer::ENDIAN_LITTLE; - } else { + } else { opts.endian = Serializer::ENDIAN_NATIVE; } - } - bi = binOpts.find("-td"); - if (!bi->second.empty()) { - if (bi->second == "uvw") { - opts.tangentSemantic = VES_TEXTURE_COORDINATES; - } else { // if (bi->second == "tangent"), or anything else - opts.tangentSemantic = VES_TANGENT; - } - } - bi = binOpts.find("-ts"); - if (!bi->second.empty()) { - if (bi->second == "4") { - opts.tangentUseParity = true; - } - } - - bi = binOpts.find("-V"); - if (!bi->second.empty()) { - if (bi->second == "1.10") { - opts.targetVersion = MESH_VERSION_1_10; - } else if (bi->second == "1.8") { - opts.targetVersion = MESH_VERSION_1_8; - } else if (bi->second == "1.7") { - opts.targetVersion = MESH_VERSION_1_7; - } else if (bi->second == "1.4") { - opts.targetVersion = MESH_VERSION_1_4; - } else if (bi->second == "1.0") { - opts.targetVersion = MESH_VERSION_1_0; - } else { - logMgr->stream() << "Unrecognised target mesh version '" << bi->second << "'"; - } - } - + } + bi = binOpts.find("-td"); + if (!bi->second.empty()) { + if (bi->second == "uvw") { + opts.tangentSemantic = VES_TEXTURE_COORDINATES; + } else { // if (bi->second == "tangent"), or anything else + opts.tangentSemantic = VES_TANGENT; + } + } + bi = binOpts.find("-ts"); + if (!bi->second.empty()) { + if (bi->second == "4") { + opts.tangentUseParity = true; + } + } + + bi = binOpts.find("-V"); + if (!bi->second.empty()) { + if (bi->second == "1.10") { + opts.targetVersion = MESH_VERSION_1_10; + } else if (bi->second == "1.8") { + opts.targetVersion = MESH_VERSION_1_8; + } else if (bi->second == "1.7") { + opts.targetVersion = MESH_VERSION_1_7; + } else if (bi->second == "1.4") { + opts.targetVersion = MESH_VERSION_1_4; + } else if (bi->second == "1.0") { + opts.targetVersion = MESH_VERSION_1_0; + } else { + logMgr->stream() << "Unrecognised target mesh version '" << bi->second << "'"; + } + } + } String describeSemantic(VertexElementSemantic sem) { - switch (sem) { - case VES_POSITION: - return "Positions"; + switch (sem) { + case VES_POSITION: + return "Positions"; - case VES_NORMAL: - return "Normals"; + case VES_NORMAL: + return "Normals"; - case VES_BLEND_WEIGHTS: - return "Blend Weights"; + case VES_BLEND_WEIGHTS: + return "Blend Weights"; - case VES_BLEND_INDICES: - return "Blend Indices"; + case VES_BLEND_INDICES: + return "Blend Indices"; - case VES_DIFFUSE: - return "Diffuse"; + case VES_DIFFUSE: + return "Diffuse"; - case VES_SPECULAR: - return "Specular"; + case VES_SPECULAR: + return "Specular"; - case VES_TEXTURE_COORDINATES: - return "Texture coordinates"; + case VES_TEXTURE_COORDINATES: + return "Texture coordinates"; - case VES_BINORMAL: - return "Binormals"; + case VES_BINORMAL: + return "Binormals"; - case VES_TANGENT: - return "Tangents"; - } + case VES_TANGENT: + return "Tangents"; + } return ""; } void displayVertexBuffers(VertexDeclaration::VertexElementList& elemList) { - // Iterate per buffer - unsigned short currentBuffer = 999; - unsigned short elemNum = 0; - VertexDeclaration::VertexElementList::iterator i, iend; - iend = elemList.end(); - for (i = elemList.begin(); i != iend; ++i) { - if (i->getSource() != currentBuffer) { - currentBuffer = i->getSource(); - cout << "> Buffer " << currentBuffer << ":" << endl; - } - cout << " - Element " << elemNum++ << ": " << describeSemantic(i->getSemantic()); - if (i->getSemantic() == VES_TEXTURE_COORDINATES) { - cout << " (index " << i->getIndex() << ")"; - } - cout << endl; - - } + // Iterate per buffer + unsigned short currentBuffer = 999; + unsigned short elemNum = 0; + VertexDeclaration::VertexElementList::iterator i, iend; + iend = elemList.end(); + for (i = elemList.begin(); i != iend; ++i) { + if (i->getSource() != currentBuffer) { + currentBuffer = i->getSource(); + cout << "> Buffer " << currentBuffer << ":" << endl; + } + cout << " - Element " << elemNum++ << ": " << describeSemantic(i->getSemantic()); + if (i->getSemantic() == VES_TEXTURE_COORDINATES) { + cout << " (index " << i->getIndex() << ")"; + } + cout << endl; + + } } // Sort routine for VertexElement bool vertexElementLess(const VertexElement& e1, const VertexElement& e2) { - // Sort by source first - if (e1.getSource() < e2.getSource()) { - return true; - } else if (e1.getSource() == e2.getSource()) { - // Use ordering of semantics to sort - if (e1.getSemantic() < e2.getSemantic()) { - return true; - } else if (e1.getSemantic() == e2.getSemantic()) { - // Use index to sort - if (e1.getIndex() < e2.getIndex()) { - return true; - } - } - } - return false; + // Sort by source first + if (e1.getSource() < e2.getSource()) { + return true; + } else if (e1.getSource() == e2.getSource()) { + // Use ordering of semantics to sort + if (e1.getSemantic() < e2.getSemantic()) { + return true; + } else if (e1.getSemantic() == e2.getSemantic()) { + // Use index to sort + if (e1.getIndex() < e2.getIndex()) { + return true; + } + } + } + return false; } void copyElems(VertexDeclaration* decl, VertexDeclaration::VertexElementList* elemList) { - - elemList->clear(); - const VertexDeclaration::VertexElementList& origElems = decl->getElements(); + + elemList->clear(); + const VertexDeclaration::VertexElementList& origElems = decl->getElements(); VertexDeclaration::VertexElementList::const_iterator i, iend; - iend = origElems.end(); - for (i = origElems.begin(); i != iend; ++i) { - elemList->push_back(*i); - } - elemList->sort(VertexDeclaration::vertexElementLess); + iend = origElems.end(); + for (i = origElems.begin(); i != iend; ++i) { + elemList->push_back(*i); + } + elemList->sort(VertexDeclaration::vertexElementLess); } // Utility function to allow the user to modify the layout of vertex buffers. void reorganiseVertexBuffers(const String& desc, Mesh& mesh, SubMesh* sm, VertexData* vertexData) { - cout << endl << desc << ":- " << endl; - // Copy elements into a list - VertexDeclaration::VertexElementList elemList; - copyElems(vertexData->vertexDeclaration, &elemList); - - bool finish = false; - bool anyChanges = false; - while (!finish) { - displayVertexBuffers(elemList); - cout << endl; - - cout << "Options: (a)utomatic" << endl; + cout << endl << desc << ":- " << endl; + // Copy elements into a list + VertexDeclaration::VertexElementList elemList; + copyElems(vertexData->vertexDeclaration, &elemList); + + bool finish = false; + bool anyChanges = false; + while (!finish) { + displayVertexBuffers(elemList); + cout << endl; + + cout << "Options: (a)utomatic" << endl; cout << " (m)ove element" << endl; - cout << " (d)elete element" << endl; - cout << " (r)eset" << endl; - cout << " (f)inish" << endl; - String response = ""; - while (response.empty()) { - cin >> response; - StringUtil::toLowerCase(response); - - if (response == "m") { - String moveResp; - cout << "Which element do you want to move (type number): "; - cin >> moveResp; - if (!moveResp.empty()) { - int eindex = StringConverter::parseInt(moveResp); - VertexDeclaration::VertexElementList::iterator movei = elemList.begin(); - std::advance(movei, eindex); - cout << endl << "Move element " << eindex << "(" + describeSemantic(movei->getSemantic()) << - ") to which buffer: "; - cin >> moveResp; - if (!moveResp.empty()) { - int bindex = StringConverter::parseInt(moveResp); - // Move (note offset will be wrong) - *movei = VertexElement(bindex, 0, movei->getType(), - movei->getSemantic(), movei->getIndex()); - elemList.sort(vertexElementLess); + cout << " (d)elete element" << endl; + cout << " (r)eset" << endl; + cout << " (f)inish" << endl; + String response = ""; + while (response.empty()) { + cin >> response; + StringUtil::toLowerCase(response); + + if (response == "m") { + String moveResp; + cout << "Which element do you want to move (type number): "; + cin >> moveResp; + if (!moveResp.empty()) { + int eindex = StringConverter::parseInt(moveResp); + VertexDeclaration::VertexElementList::iterator movei = elemList.begin(); + std::advance(movei, eindex); + cout << endl << "Move element " << eindex << "(" + describeSemantic(movei->getSemantic()) << + ") to which buffer: "; + cin >> moveResp; + if (!moveResp.empty()) { + int bindex = StringConverter::parseInt(moveResp); + // Move (note offset will be wrong) + *movei = VertexElement(bindex, 0, movei->getType(), + movei->getSemantic(), movei->getIndex()); + elemList.sort(vertexElementLess); anyChanges = true; - - } - } - } else if (response == "a") { + + } + } + } else if (response == "a") { // Automatic VertexDeclaration* newDcl = vertexData->vertexDeclaration->getAutoOrganisedDeclaration( mesh.hasSkeleton(), mesh.hasVertexAnimation(), - sm ? sm->getVertexAnimationIncludesNormals() : mesh.getSharedVertexDataAnimationIncludesNormals()); + sm ? sm->getVertexAnimationIncludesNormals() : mesh.getSharedVertexDataAnimationIncludesNormals()); copyElems(newDcl, &elemList); HardwareBufferManager::getSingleton().destroyVertexDeclaration(newDcl); anyChanges = true; - } else if (response == "d") { - String moveResp; - cout << "Which element do you want to delete (type number): "; - cin >> moveResp; - if (!moveResp.empty()) { - int eindex = StringConverter::parseInt(moveResp); - VertexDeclaration::VertexElementList::iterator movei = elemList.begin(); - std::advance(movei, eindex); + } else if (response == "d") { + String moveResp; + cout << "Which element do you want to delete (type number): "; + cin >> moveResp; + if (!moveResp.empty()) { + int eindex = StringConverter::parseInt(moveResp); + VertexDeclaration::VertexElementList::iterator movei = elemList.begin(); + std::advance(movei, eindex); cout << std::endl << "Delete element " << eindex << "(" + describeSemantic(movei->getSemantic()) << ")?: "; - cin >> moveResp; - StringUtil::toLowerCase(moveResp); - if (moveResp == "y") { - elemList.erase(movei); + cin >> moveResp; + StringUtil::toLowerCase(moveResp); + if (moveResp == "y") { + elemList.erase(movei); anyChanges = true; - } - } - } else if (response == "r") { - // reset - copyElems(vertexData->vertexDeclaration, &elemList); - anyChanges = false; - } else if (response == "f") { - // finish - finish = true; - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - - } - } - - if (anyChanges) { - String response; - while (response.empty()) { - displayVertexBuffers(elemList); - cout << "Really reorganise the vertex buffers this way? "; - cin >> response; - StringUtil::toLowerCase(response); - if (response == "y") { - VertexDeclaration* newDecl = HardwareBufferManager::getSingleton().createVertexDeclaration(); - VertexDeclaration::VertexElementList::iterator i, iend; - iend = elemList.end(); - unsigned short currentBuffer = 999; - size_t offset = 0; - for (i = elemList.begin(); i != iend; ++i) { - // Calc offsets since reorg changes them - if (i->getSource() != currentBuffer) { - offset = 0; - currentBuffer = i->getSource(); - } - newDecl->addElement( - currentBuffer, - offset, - i->getType(), - i->getSemantic(), - i->getIndex()); - - offset += VertexElement::getTypeSize(i->getType()); - - } + } + } + } else if (response == "r") { + // reset + copyElems(vertexData->vertexDeclaration, &elemList); + anyChanges = false; + } else if (response == "f") { + // finish + finish = true; + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + + } + } + + if (anyChanges) { + String response; + while (response.empty()) { + displayVertexBuffers(elemList); + cout << "Really reorganise the vertex buffers this way? "; + cin >> response; + StringUtil::toLowerCase(response); + if (response == "y") { + VertexDeclaration* newDecl = HardwareBufferManager::getSingleton().createVertexDeclaration(); + VertexDeclaration::VertexElementList::iterator i, iend; + iend = elemList.end(); + unsigned short currentBuffer = 999; + size_t offset = 0; + for (i = elemList.begin(); i != iend; ++i) { + // Calc offsets since reorg changes them + if (i->getSource() != currentBuffer) { + offset = 0; + currentBuffer = i->getSource(); + } + newDecl->addElement( + currentBuffer, + offset, + i->getType(), + i->getSemantic(), + i->getIndex()); + + offset += VertexElement::getTypeSize(i->getType()); + + } // Usages don't matter here since we're onlly exporting BufferUsageList bufferUsages; - for (size_t u = 0; u <= newDecl->getMaxSource(); ++u) { + for (size_t u = 0; u <= newDecl->getMaxSource(); ++u) { bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY); - } - vertexData->reorganiseBuffers(newDecl, bufferUsages); - } else if (response == "n") { - // do nothing - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } + } + vertexData->reorganiseBuffers(newDecl, bufferUsages); + } else if (response == "n") { + // do nothing + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } } - - } - + + } + } // Utility function to allow the user to modify the layout of vertex buffers. void reorganiseVertexBuffers(Mesh& mesh) { - // Make sure animation types up to date - mesh._determineAnimationTypes(); - - if (mesh.sharedVertexData) { - if (opts.interactive) { - reorganiseVertexBuffers("Shared Geometry", mesh, 0, mesh.sharedVertexData); - } else { - // Automatic - VertexDeclaration* newDcl = - mesh.sharedVertexData->vertexDeclaration->getAutoOrganisedDeclaration( - mesh.hasSkeleton(), mesh.hasVertexAnimation(), mesh.getSharedVertexDataAnimationIncludesNormals()); - if (*newDcl != *(mesh.sharedVertexData->vertexDeclaration)) { - // Usages don't matter here since we're onlly exporting - BufferUsageList bufferUsages; - for (size_t u = 0; u <= newDcl->getMaxSource(); ++u) { - bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY); - } - mesh.sharedVertexData->reorganiseBuffers(newDcl, bufferUsages); - } - - } - } + // Make sure animation types up to date + mesh._determineAnimationTypes(); + + if (mesh.sharedVertexData) { + if (opts.interactive) { + reorganiseVertexBuffers("Shared Geometry", mesh, 0, mesh.sharedVertexData); + } else { + // Automatic + VertexDeclaration* newDcl = + mesh.sharedVertexData->vertexDeclaration->getAutoOrganisedDeclaration( + mesh.hasSkeleton(), mesh.hasVertexAnimation(), mesh.getSharedVertexDataAnimationIncludesNormals()); + if (*newDcl != *(mesh.sharedVertexData->vertexDeclaration)) { + // Usages don't matter here since we're onlly exporting + BufferUsageList bufferUsages; + for (size_t u = 0; u <= newDcl->getMaxSource(); ++u) { + bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY); + } + mesh.sharedVertexData->reorganiseBuffers(newDcl, bufferUsages); + } + + } + } Mesh::SubMeshIterator smIt = mesh.getSubMeshIterator(); - unsigned short idx = 0; - while (smIt.hasMoreElements()) { - SubMesh* sm = smIt.getNext(); - if (!sm->useSharedVertices) { - if (opts.interactive) { - StringStream str; - str << "SubMesh " << idx++; - reorganiseVertexBuffers(str.str(), mesh, sm, sm->vertexData); - } else { - const bool hasVertexAnim = sm->getVertexAnimationType() != Ogre::VAT_NONE; - - // Automatic - VertexDeclaration* newDcl = - sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration( - mesh.hasSkeleton(), hasVertexAnim, sm->getVertexAnimationIncludesNormals() ); - if (*newDcl != *(sm->vertexData->vertexDeclaration)) { - // Usages don't matter here since we're onlly exporting - BufferUsageList bufferUsages; - for (size_t u = 0; u <= newDcl->getMaxSource(); ++u) { - bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY); - } - sm->vertexData->reorganiseBuffers(newDcl, bufferUsages); - } - - } - } - } + unsigned short idx = 0; + while (smIt.hasMoreElements()) { + SubMesh* sm = smIt.getNext(); + if (!sm->useSharedVertices) { + if (opts.interactive) { + StringStream str; + str << "SubMesh " << idx++; + reorganiseVertexBuffers(str.str(), mesh, sm, sm->vertexData); + } else { + const bool hasVertexAnim = sm->getVertexAnimationType() != Ogre::VAT_NONE; + + // Automatic + VertexDeclaration* newDcl = + sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration( + mesh.hasSkeleton(), hasVertexAnim, sm->getVertexAnimationIncludesNormals() ); + if (*newDcl != *(sm->vertexData->vertexDeclaration)) { + // Usages don't matter here since we're onlly exporting + BufferUsageList bufferUsages; + for (size_t u = 0; u <= newDcl->getMaxSource(); ++u) { + bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY); + } + sm->vertexData->reorganiseBuffers(newDcl, bufferUsages); + } + + } + } + } } void vertexBufferReorg(Mesh& mesh) { - String response; - - if (opts.interactive) { - - // Check to see whether we would like to reorganise vertex buffers - std::cout << "\nWould you like to reorganise the vertex buffers for this mesh? "; - while (response.empty()) { - cin >> response; - StringUtil::toLowerCase(response); - if (response == "y") { - reorganiseVertexBuffers(mesh); - } else if (response == "n") { - // Do nothing - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } - } else if (!opts.dontReorganise) { - reorganiseVertexBuffers(mesh); - } + String response; + + if (opts.interactive) { + + // Check to see whether we would like to reorganise vertex buffers + std::cout << "\nWould you like to reorganise the vertex buffers for this mesh? "; + while (response.empty()) { + cin >> response; + StringUtil::toLowerCase(response); + if (response == "y") { + reorganiseVertexBuffers(mesh); + } else if (response == "n") { + // Do nothing + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } + } else if (!opts.dontReorganise) { + reorganiseVertexBuffers(mesh); + } } void recalcBounds(const VertexData* vdata, AxisAlignedBox& aabb, Real& radius) { - const VertexElement* posElem = - vdata->vertexDeclaration->findElementBySemantic(VES_POSITION); - - const HardwareVertexBufferSharedPtr buf = vdata->vertexBufferBinding->getBuffer( - posElem->getSource()); - void* pBase = buf->lock(HardwareBuffer::HBL_READ_ONLY); + const VertexElement* posElem = + vdata->vertexDeclaration->findElementBySemantic(VES_POSITION); + + const HardwareVertexBufferSharedPtr buf = vdata->vertexBufferBinding->getBuffer( + posElem->getSource()); + void* pBase = buf->lock(HardwareBuffer::HBL_READ_ONLY); - for (size_t v = 0; v < vdata->vertexCount; ++v) { - float* pFloat; - posElem->baseVertexPointerToElement(pBase, &pFloat); - - Vector3 pos(pFloat[0], pFloat[1], pFloat[2]); - aabb.merge(pos); - radius = std::max(radius, pos.length()); + for (size_t v = 0; v < vdata->vertexCount; ++v) { + float* pFloat; + posElem->baseVertexPointerToElement(pBase, &pFloat); + + Vector3 pos(pFloat[0], pFloat[1], pFloat[2]); + aabb.merge(pos); + radius = std::max(radius, pos.length()); - pBase = static_cast(static_cast(pBase) + buf->getVertexSize()); + pBase = static_cast(static_cast(pBase) + buf->getVertexSize()); - } + } - buf->unlock(); + buf->unlock(); } void recalcBounds(Mesh* mesh) { - AxisAlignedBox aabb; - Real radius = 0.0f; - - if (mesh->sharedVertexData) { - recalcBounds(mesh->sharedVertexData, aabb, radius); - } - for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { - SubMesh* sm = mesh->getSubMesh(i); - if (!sm->useSharedVertices) { - recalcBounds(sm->vertexData, aabb, radius); - } - } - - mesh->_setBounds(aabb, false); - mesh->_setBoundingSphereRadius(radius); + AxisAlignedBox aabb; + Real radius = 0.0f; + + if (mesh->sharedVertexData) { + recalcBounds(mesh->sharedVertexData, aabb, radius); + } + for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { + SubMesh* sm = mesh->getSubMesh(i); + if (!sm->useSharedVertices) { + recalcBounds(sm->vertexData, aabb, radius); + } + } + + mesh->_setBounds(aabb, false); + mesh->_setBoundingSphereRadius(radius); } void printLodConfig(const LodConfig& lodConfig) { - cout << "\n\nLOD config summary:"; - cout << "\n lodConfig.strategy=" << lodConfig.strategy->getName(); - String reductionMethod("Unknown"); - if (lodConfig.levels[0].reductionMethod == LodLevel::VRM_PROPORTIONAL) { - reductionMethod = "VRM_PROPORTIONAL"; - } else if (lodConfig.levels[0].reductionMethod == LodLevel::VRM_CONSTANT) { - reductionMethod = "VRM_PROPORTIONAL"; - } else if (lodConfig.levels[0].reductionMethod == LodLevel::VRM_COLLAPSE_COST) { - reductionMethod = "VRM_COLLAPSE_COST"; - } - String distQuantity; - if (lodConfig.strategy == PixelCountLodStrategy::getSingletonPtr()) { - distQuantity = "px"; - } - for (unsigned short i = 0; i < lodConfig.levels.size(); i++) { - const LodLevel& lodLevel = lodConfig.levels[i]; - cout << "\n lodConfig.levels[" << i << "].distance=" << lodLevel.distance << distQuantity; - cout << "\n lodConfig.levels[" << i << "].reductionMethod=" << - (lodLevel.manualMeshName.empty() ? reductionMethod : "N/A"); - cout << "\n lodConfig.levels[" << i << "].reductionValue=" << - (lodLevel.manualMeshName.empty() ? StringConverter::toString(lodLevel.reductionValue) : "N/A"); - cout << "\n lodConfig.levels[" << i << "].manualMeshName=" << - (lodLevel.manualMeshName.empty() ? "N/A" : lodLevel.manualMeshName); - } + cout << "\n\nLOD config summary:"; + cout << "\n lodConfig.strategy=" << lodConfig.strategy->getName(); + String reductionMethod("Unknown"); + if (lodConfig.levels[0].reductionMethod == LodLevel::VRM_PROPORTIONAL) { + reductionMethod = "VRM_PROPORTIONAL"; + } else if (lodConfig.levels[0].reductionMethod == LodLevel::VRM_CONSTANT) { + reductionMethod = "VRM_PROPORTIONAL"; + } else if (lodConfig.levels[0].reductionMethod == LodLevel::VRM_COLLAPSE_COST) { + reductionMethod = "VRM_COLLAPSE_COST"; + } + String distQuantity; + if (lodConfig.strategy == PixelCountLodStrategy::getSingletonPtr()) { + distQuantity = "px"; + } + for (unsigned short i = 0; i < lodConfig.levels.size(); i++) { + const LodLevel& lodLevel = lodConfig.levels[i]; + cout << "\n lodConfig.levels[" << i << "].distance=" << lodLevel.distance << distQuantity; + cout << "\n lodConfig.levels[" << i << "].reductionMethod=" << + (lodLevel.manualMeshName.empty() ? reductionMethod : "N/A"); + cout << "\n lodConfig.levels[" << i << "].reductionValue=" << + (lodLevel.manualMeshName.empty() ? StringConverter::toString(lodLevel.reductionValue) : "N/A"); + cout << "\n lodConfig.levels[" << i << "].manualMeshName=" << + (lodLevel.manualMeshName.empty() ? "N/A" : lodLevel.manualMeshName); + } } size_t getUniqueVertexCount(MeshPtr mesh) { - // The vertex buffer contains the same vertex position multiple times. - // To get the count of the vertices, which has unique positions, we can use progressive mesh. - // It is constructing a mesh grid at the beginning, so if we reduce 0%, we will get the unique vertex count. - LodConfig lodConfig(mesh, PixelCountLodStrategy::getSingletonPtr()); - lodConfig.advanced.useBackgroundQueue = false; // Non-threaded - lodConfig.createGeneratedLodLevel(0.0f, 0.0f); - MeshLodGenerator().generateLodLevels(lodConfig); - return lodConfig.levels[0].outUniqueVertexCount; + // The vertex buffer contains the same vertex position multiple times. + // To get the count of the vertices, which has unique positions, we can use progressive mesh. + // It is constructing a mesh grid at the beginning, so if we reduce 0%, we will get the unique vertex count. + LodConfig lodConfig(mesh, PixelCountLodStrategy::getSingletonPtr()); + lodConfig.advanced.useBackgroundQueue = false; // Non-threaded + lodConfig.createGeneratedLodLevel(0.0f, 0.0f); + MeshLodGenerator().generateLodLevels(lodConfig); + return lodConfig.levels[0].outUniqueVertexCount; } void buildLod(MeshPtr& mesh) { - String response; - - // Prompt for LOD generation? - bool genLod = (opts.numLods != 0 || opts.interactive || opts.lodAutoconfigure); - bool askLodDtls = opts.interactive; - if (genLod) { // otherwise only ask if not specified on command line - if (mesh->getNumLodLevels() > 1) { - do { - std::cout << "\nMesh already contains level-of-detail information.\n" - "Do you want to: (u)se it, (r)eplace it, or (d)rop it? "; - cin >> response; - StringUtil::toLowerCase(response); - if (response == "u") { - genLod = false; - askLodDtls = false; - } else if (response == "d") { - mesh->removeLodLevels(); - genLod = false; - askLodDtls = false; - } else if (response == "r") { - genLod = true; - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } while (response == ""); - } else if (askLodDtls) { - do { - std::cout << "\nWould you like to generate level-of-detail information? (y/n) "; - cin >> response; - StringUtil::toLowerCase(response); - if (response == "n") { - genLod = false; - } else if (response == "y") { - genLod = true; - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } while (response == ""); - } - } - - if (!genLod) { - return; - } - - int numLod; - LodConfig lodConfig; - lodConfig.mesh = mesh; - lodConfig.strategy = DistanceLodStrategy::getSingletonPtr(); - if (askLodDtls) { - do { - std::cout << - "\nDo you want to (m)anually configure or (a)utoconfigure it?\nautoconfigure=no more questions asked!(m/a) "; - cin >> response; - StringUtil::toLowerCase(response); - if (response == "a") { - opts.lodAutoconfigure = true; - } else if (response == "m") { - opts.lodAutoconfigure = false; - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } while (response == ""); - if (!opts.lodAutoconfigure) { - do { - std::cout << "\nDo you want to use (p)ixels or (d)istance to determine where the LOD activates? (p/d) "; - cin >> response; - StringUtil::toLowerCase(response); - if (response == "p") { - lodConfig.strategy = PixelCountLodStrategy::getSingletonPtr(); - } else if (response == "d") { - lodConfig.strategy = DistanceLodStrategy::getSingletonPtr(); - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } while (response == ""); - LodLevel lodLevel; - size_t vertexCount = 0; - do { - cout << - "\nWhat unit of reduction would you like to use(fixed=constant vertex number; proportional=percentage):" << - "\n(f)ixed or (p)roportional? "; - cin >> response; - StringUtil::toLowerCase(response); - if (response == "f") { - lodLevel.reductionMethod = LodLevel::VRM_CONSTANT; - vertexCount = getUniqueVertexCount(mesh); - } else if (response == "p") { - lodLevel.reductionMethod = LodLevel::VRM_PROPORTIONAL; - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } while (response == ""); - - numLod = 0; - while (numLod < 1 || numLod > 99) { - cout << "\nHow many extra LOD levels would you like to generate? (1-99)"; - cin >> response; - numLod = StringConverter::parseInt(response); - } - Real minReduction = 0.0; - Real minDistance = lodConfig.strategy->getBaseValue(); - for (int iLod = 0; iLod < numLod; ++iLod) { - do { - cout << "\nShould LOD" << (iLod + 1) << " be a (m)anual or (g)enerated LOD level? (m/g)"; - cin >> response; - StringUtil::toLowerCase(response); - if (response == "m") { - while (lodLevel.manualMeshName.empty()) { - cout << "\nEnter the mesh name to show for LOD" << (iLod + 1) << ". (e.g. Sinbad_LOD1.mesh)"; - cout << "\nIt should have the same animation states and it should not have LOD levels!\n"; - cin >> lodLevel.manualMeshName; - } - } else if (response == "g") { - if (lodLevel.reductionMethod == LodLevel::VRM_PROPORTIONAL) { - cout << "\nWhat percentage of remaining vertices should be removed at LOD" << - (iLod + 1) << "? (e.g. 40 = remove 40% of vertices)"; - cout << "\nIt should be between " << minReduction << "%-100%\n"; - } else { - cout << "\nHow many vertices should be removed at LOD" << - (iLod + 1) << "? (e.g. 50 = remove 50 vertices)"; - cout << "\nIt should be between " << (int) minReduction << "-" << vertexCount << " vertices\n"; - } - while (1) { - cin >> response; - lodLevel.reductionValue = StringConverter::parseReal(response); - if (lodLevel.reductionMethod == LodLevel::VRM_PROPORTIONAL) { - if (lodLevel.reductionValue > minReduction && lodLevel.reductionValue <= 100.0) { - minReduction = lodLevel.reductionValue; - lodLevel.reductionValue *= 0.01; - if (minReduction == 100.0) { - cout << "\nCan't insert more LOD levels!"; - iLod = numLod; - } - break; - } else { - cout << "\nWrong answer! It should be between " << minReduction << "%-100%."; - } - } else { - if ((int) lodLevel.reductionValue > (int) minReduction && (int) lodLevel.reductionValue <= (int)vertexCount) { - minReduction = lodLevel.reductionValue; - break; - } else { - cout << "\nIt should be between " << (int) minReduction << "-" << vertexCount << " vertices."; - } - } - } - - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } while (response == ""); - - if (lodConfig.strategy == DistanceLodStrategy::getSingletonPtr()) { - cout << "\nEnter the distance for LOD" << - (iLod + 1) << " to activate. (distance of camera and mesh in Ogre units)"; - cout << "\nIt should be more then last Lod level: " << minDistance << "\n"; - } else { - cout << "\nEnter the pixel count for LOD" << - (iLod + 1) << " to activate. (pixels of the bounding sphere in the render output)"; - cout << "\nIt should be LESS then last Lod level: " << minDistance << "\n"; - } - while (1) { - cin >> response; - lodLevel.distance = StringConverter::parseReal(response); - if (lodConfig.strategy == DistanceLodStrategy::getSingletonPtr()) { - if (lodLevel.distance > minDistance) { - break; - } else { - cout << "\nWrong answer! It should be more than " << minDistance << "."; - } - } else { - if (lodLevel.distance < minDistance && lodLevel.distance >= 0) { - break; - } else { - cout << "\nWrong answer! It should be less than " << minDistance << "px."; - } - } - } - minDistance = lodLevel.distance; - cout << "\nLOD" << (iLod + 1) << " level summary:"; - cout << "\n lodLevel.distance=" << lodLevel.distance; - String reductionMethod = - ((lodLevel.reductionMethod == LodLevel::VRM_PROPORTIONAL) ? "VRM_PROPORTIONAL" : "VRM_CONSTANT"); - cout << "\n lodLevel.reductionMethod=" << (lodLevel.manualMeshName.empty() ? reductionMethod : "N/A"); - cout << "\n lodLevel.reductionValue=" << - (lodLevel.manualMeshName.empty() ? StringConverter::toString(lodLevel.reductionValue) : "N/A"); - cout << "\n lodLevel.manualMeshName=" << (lodLevel.manualMeshName.empty() ? "N/A" : lodLevel.manualMeshName); - lodConfig.levels.push_back(lodLevel); - } - } - } else { - // not interactive: read parameters from console - numLod = opts.numLods; - LodLevel lodLevel; - lodLevel.distance = 0.0; - for (unsigned short iLod = 0; iLod < numLod; ++iLod) { - - lodLevel.reductionMethod = opts.usePercent ? - LodLevel::VRM_PROPORTIONAL : LodLevel::VRM_CONSTANT; - if (opts.usePercent) { - lodLevel.reductionValue += opts.lodPercent * 0.01f; - } else { - lodLevel.reductionValue += (Ogre::Real)opts.lodFixed; - } - - lodLevel.distance += opts.lodDist; - lodConfig.levels.push_back(lodLevel); - } - } - - // ensure we use correct bounds - recalcBounds(mesh.get()); - - MeshLodGenerator gen; - if (opts.lodAutoconfigure) { - // In this case we ignore other settings - gen.getAutoconfig(mesh, lodConfig); - } - printLodConfig(lodConfig); - - - cout << "\n\nGenerating LOD levels..."; - gen.generateLodLevels(lodConfig); - cout << "success\n"; + String response; + + // Prompt for LOD generation? + bool genLod = (opts.numLods != 0 || opts.interactive || opts.lodAutoconfigure); + bool askLodDtls = opts.interactive; + if (genLod) { // otherwise only ask if not specified on command line + if (mesh->getNumLodLevels() > 1) { + do { + std::cout << "\nMesh already contains level-of-detail information.\n" + "Do you want to: (u)se it, (r)eplace it, or (d)rop it? "; + cin >> response; + StringUtil::toLowerCase(response); + if (response == "u") { + genLod = false; + askLodDtls = false; + } else if (response == "d") { + mesh->removeLodLevels(); + genLod = false; + askLodDtls = false; + } else if (response == "r") { + genLod = true; + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } while (response == ""); + } else if (askLodDtls) { + do { + std::cout << "\nWould you like to generate level-of-detail information? (y/n) "; + cin >> response; + StringUtil::toLowerCase(response); + if (response == "n") { + genLod = false; + } else if (response == "y") { + genLod = true; + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } while (response == ""); + } + } + + if (!genLod) { + return; + } + + int numLod; + LodConfig lodConfig; + lodConfig.mesh = mesh; + lodConfig.strategy = DistanceLodStrategy::getSingletonPtr(); + if (askLodDtls) { + do { + std::cout << + "\nDo you want to (m)anually configure or (a)utoconfigure it?\nautoconfigure=no more questions asked!(m/a) "; + cin >> response; + StringUtil::toLowerCase(response); + if (response == "a") { + opts.lodAutoconfigure = true; + } else if (response == "m") { + opts.lodAutoconfigure = false; + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } while (response == ""); + if (!opts.lodAutoconfigure) { + do { + std::cout << "\nDo you want to use (p)ixels or (d)istance to determine where the LOD activates? (p/d) "; + cin >> response; + StringUtil::toLowerCase(response); + if (response == "p") { + lodConfig.strategy = PixelCountLodStrategy::getSingletonPtr(); + } else if (response == "d") { + lodConfig.strategy = DistanceLodStrategy::getSingletonPtr(); + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } while (response == ""); + LodLevel lodLevel; + size_t vertexCount = 0; + do { + cout << + "\nWhat unit of reduction would you like to use(fixed=constant vertex number; proportional=percentage):" << + "\n(f)ixed or (p)roportional? "; + cin >> response; + StringUtil::toLowerCase(response); + if (response == "f") { + lodLevel.reductionMethod = LodLevel::VRM_CONSTANT; + vertexCount = getUniqueVertexCount(mesh); + } else if (response == "p") { + lodLevel.reductionMethod = LodLevel::VRM_PROPORTIONAL; + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } while (response == ""); + + numLod = 0; + while (numLod < 1 || numLod > 99) { + cout << "\nHow many extra LOD levels would you like to generate? (1-99)"; + cin >> response; + numLod = StringConverter::parseInt(response); + } + Real minReduction = 0.0; + Real minDistance = lodConfig.strategy->getBaseValue(); + for (int iLod = 0; iLod < numLod; ++iLod) { + do { + cout << "\nShould LOD" << (iLod + 1) << " be a (m)anual or (g)enerated LOD level? (m/g)"; + cin >> response; + StringUtil::toLowerCase(response); + if (response == "m") { + while (lodLevel.manualMeshName.empty()) { + cout << "\nEnter the mesh name to show for LOD" << (iLod + 1) << ". (e.g. Sinbad_LOD1.mesh)"; + cout << "\nIt should have the same animation states and it should not have LOD levels!\n"; + cin >> lodLevel.manualMeshName; + } + } else if (response == "g") { + if (lodLevel.reductionMethod == LodLevel::VRM_PROPORTIONAL) { + cout << "\nWhat percentage of remaining vertices should be removed at LOD" << + (iLod + 1) << "? (e.g. 40 = remove 40% of vertices)"; + cout << "\nIt should be between " << minReduction << "%-100%\n"; + } else { + cout << "\nHow many vertices should be removed at LOD" << + (iLod + 1) << "? (e.g. 50 = remove 50 vertices)"; + cout << "\nIt should be between " << (int) minReduction << "-" << vertexCount << " vertices\n"; + } + while (1) { + cin >> response; + lodLevel.reductionValue = StringConverter::parseReal(response); + if (lodLevel.reductionMethod == LodLevel::VRM_PROPORTIONAL) { + if (lodLevel.reductionValue > minReduction && lodLevel.reductionValue <= 100.0) { + minReduction = lodLevel.reductionValue; + lodLevel.reductionValue *= 0.01; + if (minReduction == 100.0) { + cout << "\nCan't insert more LOD levels!"; + iLod = numLod; + } + break; + } else { + cout << "\nWrong answer! It should be between " << minReduction << "%-100%."; + } + } else { + if ((int) lodLevel.reductionValue > (int) minReduction && (int) lodLevel.reductionValue <= (int)vertexCount) { + minReduction = lodLevel.reductionValue; + break; + } else { + cout << "\nIt should be between " << (int) minReduction << "-" << vertexCount << " vertices."; + } + } + } + + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } while (response == ""); + + if (lodConfig.strategy == DistanceLodStrategy::getSingletonPtr()) { + cout << "\nEnter the distance for LOD" << + (iLod + 1) << " to activate. (distance of camera and mesh in Ogre units)"; + cout << "\nIt should be more then last Lod level: " << minDistance << "\n"; + } else { + cout << "\nEnter the pixel count for LOD" << + (iLod + 1) << " to activate. (pixels of the bounding sphere in the render output)"; + cout << "\nIt should be LESS then last Lod level: " << minDistance << "\n"; + } + while (1) { + cin >> response; + lodLevel.distance = StringConverter::parseReal(response); + if (lodConfig.strategy == DistanceLodStrategy::getSingletonPtr()) { + if (lodLevel.distance > minDistance) { + break; + } else { + cout << "\nWrong answer! It should be more than " << minDistance << "."; + } + } else { + if (lodLevel.distance < minDistance && lodLevel.distance >= 0) { + break; + } else { + cout << "\nWrong answer! It should be less than " << minDistance << "px."; + } + } + } + minDistance = lodLevel.distance; + cout << "\nLOD" << (iLod + 1) << " level summary:"; + cout << "\n lodLevel.distance=" << lodLevel.distance; + String reductionMethod = + ((lodLevel.reductionMethod == LodLevel::VRM_PROPORTIONAL) ? "VRM_PROPORTIONAL" : "VRM_CONSTANT"); + cout << "\n lodLevel.reductionMethod=" << (lodLevel.manualMeshName.empty() ? reductionMethod : "N/A"); + cout << "\n lodLevel.reductionValue=" << + (lodLevel.manualMeshName.empty() ? StringConverter::toString(lodLevel.reductionValue) : "N/A"); + cout << "\n lodLevel.manualMeshName=" << (lodLevel.manualMeshName.empty() ? "N/A" : lodLevel.manualMeshName); + lodConfig.levels.push_back(lodLevel); + } + } + } else { + // not interactive: read parameters from console + numLod = opts.numLods; + LodLevel lodLevel; + lodLevel.distance = 0.0; + for (unsigned short iLod = 0; iLod < numLod; ++iLod) { + + lodLevel.reductionMethod = opts.usePercent ? + LodLevel::VRM_PROPORTIONAL : LodLevel::VRM_CONSTANT; + if (opts.usePercent) { + lodLevel.reductionValue += opts.lodPercent * 0.01f; + } else { + lodLevel.reductionValue += (Ogre::Real)opts.lodFixed; + } + + lodLevel.distance += opts.lodDist; + lodConfig.levels.push_back(lodLevel); + } + } + + // ensure we use correct bounds + recalcBounds(mesh.get()); + + MeshLodGenerator gen; + if (opts.lodAutoconfigure) { + // In this case we ignore other settings + gen.getAutoconfig(mesh, lodConfig); + } + printLodConfig(lodConfig); + + + cout << "\n\nGenerating LOD levels..."; + gen.generateLodLevels(lodConfig); + cout << "success\n"; } void checkColour(VertexData* vdata, bool& hasColour, bool& hasAmbiguousColour, VertexElementType& originalType) { - const VertexDeclaration::VertexElementList& elemList = vdata->vertexDeclaration->getElements(); - for (VertexDeclaration::VertexElementList::const_iterator i = elemList.begin(); - i != elemList.end(); ++i) { - const VertexElement& elem = *i; - switch (elem.getType()) { - case VET_COLOUR: - hasAmbiguousColour = true; - - case VET_COLOUR_ABGR: - case VET_COLOUR_ARGB: - hasColour = true; - originalType = elem.getType(); - - default: - // do nothing - ; - } - } + const VertexDeclaration::VertexElementList& elemList = vdata->vertexDeclaration->getElements(); + for (VertexDeclaration::VertexElementList::const_iterator i = elemList.begin(); + i != elemList.end(); ++i) { + const VertexElement& elem = *i; + switch (elem.getType()) { + case VET_COLOUR: + hasAmbiguousColour = true; + + case VET_COLOUR_ABGR: + case VET_COLOUR_ARGB: + hasColour = true; + originalType = elem.getType(); + + default: + // do nothing + ; + } + } } void resolveColourAmbiguities(Mesh* mesh) { - // Check what we're dealing with - bool hasColour = false; - bool hasAmbiguousColour = false; - VertexElementType originalType = VET_FLOAT1; - if (mesh->sharedVertexData) { - checkColour(mesh->sharedVertexData, hasColour, hasAmbiguousColour, originalType); - } - for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { - SubMesh* sm = mesh->getSubMesh(i); - if (sm->useSharedVertices == false) { - checkColour(sm->vertexData, hasColour, hasAmbiguousColour, originalType); - } - } - - String response; - if (hasAmbiguousColour) { - if (opts.srcColourFormatSet) { - originalType = opts.srcColourFormat; - } else { - // unknown input colour, have to ask - std::cout << "\nYour mesh has vertex colours but I don't know whether they were generated\n" - << "using GL or D3D ordering. Please indicate which was used when the mesh was\n" - << "created (type 'gl' or 'd3d').\n"; - while (response.empty()) { - cin >> response; - StringUtil::toLowerCase(response); - if (response == "d3d") { - originalType = VET_COLOUR_ARGB; - } else if (response == "gl") { - originalType = VET_COLOUR_ABGR; - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } - } - } - - // Ask what format we want to save in - VertexElementType desiredType = VET_FLOAT1; - if (hasColour) { - if (opts.destColourFormatSet) { - desiredType = opts.destColourFormat; - } else { - if (opts.interactive) { - - response = ""; - std::cout << "\nYour mesh has vertex colours, which can be stored in one of two layouts,\n" - << "each of which will be slightly faster to load in a different render system.\n" - << "Do you want to prefer Direct3D (d3d) or OpenGL (gl)?\n"; - while (response.empty()) { - cin >> response; - StringUtil::toLowerCase(response); - if (response == "d3d") { - desiredType = VET_COLOUR_ARGB; - } else if (response == "gl") { - desiredType = VET_COLOUR_ABGR; - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } - } else { - // 'do no harm' - return; - } - } - - } - - if (mesh->sharedVertexData && hasColour) { - mesh->sharedVertexData->convertPackedColour(originalType, desiredType); - } - for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { - SubMesh* sm = mesh->getSubMesh(i); - if (sm->useSharedVertices == false && hasColour) { - sm->vertexData->convertPackedColour(originalType, desiredType); - } - } + // Check what we're dealing with + bool hasColour = false; + bool hasAmbiguousColour = false; + VertexElementType originalType = VET_FLOAT1; + if (mesh->sharedVertexData) { + checkColour(mesh->sharedVertexData, hasColour, hasAmbiguousColour, originalType); + } + for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { + SubMesh* sm = mesh->getSubMesh(i); + if (sm->useSharedVertices == false) { + checkColour(sm->vertexData, hasColour, hasAmbiguousColour, originalType); + } + } + + String response; + if (hasAmbiguousColour) { + if (opts.srcColourFormatSet) { + originalType = opts.srcColourFormat; + } else { + // unknown input colour, have to ask + std::cout << "\nYour mesh has vertex colours but I don't know whether they were generated\n" + << "using GL or D3D ordering. Please indicate which was used when the mesh was\n" + << "created (type 'gl' or 'd3d').\n"; + while (response.empty()) { + cin >> response; + StringUtil::toLowerCase(response); + if (response == "d3d") { + originalType = VET_COLOUR_ARGB; + } else if (response == "gl") { + originalType = VET_COLOUR_ABGR; + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } + } + } + + // Ask what format we want to save in + VertexElementType desiredType = VET_FLOAT1; + if (hasColour) { + if (opts.destColourFormatSet) { + desiredType = opts.destColourFormat; + } else { + if (opts.interactive) { + + response = ""; + std::cout << "\nYour mesh has vertex colours, which can be stored in one of two layouts,\n" + << "each of which will be slightly faster to load in a different render system.\n" + << "Do you want to prefer Direct3D (d3d) or OpenGL (gl)?\n"; + while (response.empty()) { + cin >> response; + StringUtil::toLowerCase(response); + if (response == "d3d") { + desiredType = VET_COLOUR_ARGB; + } else if (response == "gl") { + desiredType = VET_COLOUR_ABGR; + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } + } else { + // 'do no harm' + return; + } + } + + } + + if (mesh->sharedVertexData && hasColour) { + mesh->sharedVertexData->convertPackedColour(originalType, desiredType); + } + for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i) { + SubMesh* sm = mesh->getSubMesh(i); + if (sm->useSharedVertices == false && hasColour) { + sm->vertexData->convertPackedColour(originalType, desiredType); + } + } } int main(int numargs, char** args) { - if (numargs < 2) { + if (numargs < 2) { help(); return -1; } - int retCode = 0; - try - { - logMgr = new LogManager(); - logMgr->createLog("OgreMeshUpgrade.log", true); - rgm = new ResourceGroupManager(); - mth = new Math(); - lodMgr = new LodStrategyManager(); - matMgr = new MaterialManager(); - matMgr->initialise(); - skelMgr = new SkeletonManager(); - meshSerializer = new MeshSerializer(); - skeletonSerializer = new SkeletonSerializer(); - bufferManager = new DefaultHardwareBufferManager(); // needed because we don't have a rendersystem - meshMgr = new MeshManager(); - // don't pad during upgrade - meshMgr->setBoundsPaddingFactor(0.0f); - - - UnaryOptionList unOptList; - BinaryOptionList binOptList; - - unOptList["-i"] = false; - unOptList["-e"] = false; - unOptList["-t"] = false; - unOptList["-tm"] = false; - unOptList["-tr"] = false; - unOptList["-r"] = false; - unOptList["-gl"] = false; - unOptList["-d3d"] = false; - unOptList["-srcgl"] = false; - unOptList["-srcd3d"] = false; - unOptList["-autogen"] = false; - unOptList["-b"] = false; - binOptList["-l"] = ""; - binOptList["-d"] = ""; - binOptList["-p"] = ""; - binOptList["-f"] = ""; - binOptList["-E"] = ""; - binOptList["-td"] = ""; - binOptList["-ts"] = ""; - binOptList["-V"] = ""; - - int startIdx = findCommandLineOpts(numargs, args, unOptList, binOptList); - parseOpts(unOptList, binOptList); - - String source(args[startIdx]); - - - // Load the mesh - struct stat tagStat; - - FILE* pFile = fopen( source.c_str(), "rb" ); - if (!pFile) { - OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, - "File " + source + " not found.", "OgreMeshUpgrade"); - } - stat( source.c_str(), &tagStat ); - MemoryDataStream* memstream = new MemoryDataStream(source, tagStat.st_size, true); - size_t result = fread( (void*)memstream->getPtr(), 1, tagStat.st_size, pFile ); - if (result != tagStat.st_size) - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Unexpected error while reading file " + source, "OgreMeshUpgrade"); - fclose( pFile ); - - MeshPtr meshPtr = MeshManager::getSingleton().createManual("conversion", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - Mesh* mesh = meshPtr.get(); - - DataStreamPtr stream(memstream); - meshSerializer->importMesh(stream, mesh); - - // Write out the converted mesh - String dest; - if (numargs == startIdx + 2) { - dest = args[startIdx + 1]; - } else { - dest = source; - } - - String response; - - vertexBufferReorg(*mesh); - - // Deal with VET_COLOUR ambiguities - resolveColourAmbiguities(mesh); - - buildLod(meshPtr); - - if (opts.interactive) { - do { - std::cout << "\nWould you like to (b)uild/(r)emove/(k)eep Edge lists? (b/r/k) "; - cin >> response; - StringUtil::toLowerCase(response); - if (response == "k") { - // Do nothing - } else if (response == "b") { - cout << "\nGenerating edge lists..."; - mesh->buildEdgeList(); - cout << "success\n"; - } else if (response == "r") { - mesh->freeEdgeList(); - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } while (response == ""); - } else { - // Make sure we generate edge lists, provided they are not deliberately disabled - if (!opts.suppressEdgeLists) { - cout << "\nGenerating edge lists..."; - mesh->buildEdgeList(); - cout << "success\n"; - } else { - mesh->freeEdgeList(); - } - } - if (opts.interactive) { - do { - std::cout << "\nWould you like to (g)enerate/(k)eep tangent buffer? (g/k) "; - cin >> response; - StringUtil::toLowerCase(response); - if (response == "k") { - opts.generateTangents = false; - } else if (response == "g") { - opts.generateTangents = true; - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - } while (response == ""); - } - // Generate tangents? - if (opts.generateTangents) { - unsigned short srcTex, destTex; - bool existing = mesh->suggestTangentVectorBuildParams(opts.tangentSemantic, srcTex, destTex); - if (existing) { - if (opts.interactive) { - do { - std::cout << "\nThis mesh appears to already have a set of tangents, " << - "which would suggest tangent vectors have already been calculated. Do you really " << - "want to generate new tangent vectors (may duplicate)? (y/n) "; - cin >> response; - StringUtil::toLowerCase(response); - if (response == "y") { - // Do nothing - } else if (response == "n") { - opts.generateTangents = false; - } else { - std::cout << "Wrong answer!\n"; - response = ""; - } - - } while (response == ""); - } else { - // safe - opts.generateTangents = false; - } - - } - if (opts.generateTangents) { - cout << "\nGenerating tangent vectors...."; - mesh->buildTangentVectors(opts.tangentSemantic, srcTex, destTex, - opts.tangentSplitMirrored, opts.tangentSplitRotated, - opts.tangentUseParity); - cout << "success" << std::endl; - } - } - - - if (opts.recalcBounds) { - recalcBounds(mesh); - } - - meshSerializer->exportMesh(mesh, dest, opts.targetVersion, opts.endian); + int retCode = 0; + try + { + logMgr = new LogManager(); + logMgr->createLog("OgreMeshUpgrade.log", true); + rgm = new ResourceGroupManager(); + mth = new Math(); + lodMgr = new LodStrategyManager(); + matMgr = new MaterialManager(); + matMgr->initialise(); + skelMgr = new SkeletonManager(); + meshSerializer = new MeshSerializer(); + skeletonSerializer = new SkeletonSerializer(); + bufferManager = new DefaultHardwareBufferManager(); // needed because we don't have a rendersystem + meshMgr = new MeshManager(); + // don't pad during upgrade + meshMgr->setBoundsPaddingFactor(0.0f); + + + UnaryOptionList unOptList; + BinaryOptionList binOptList; + + unOptList["-i"] = false; + unOptList["-e"] = false; + unOptList["-t"] = false; + unOptList["-tm"] = false; + unOptList["-tr"] = false; + unOptList["-r"] = false; + unOptList["-gl"] = false; + unOptList["-d3d"] = false; + unOptList["-srcgl"] = false; + unOptList["-srcd3d"] = false; + unOptList["-autogen"] = false; + unOptList["-b"] = false; + binOptList["-l"] = ""; + binOptList["-d"] = ""; + binOptList["-p"] = ""; + binOptList["-f"] = ""; + binOptList["-E"] = ""; + binOptList["-td"] = ""; + binOptList["-ts"] = ""; + binOptList["-V"] = ""; + + int startIdx = findCommandLineOpts(numargs, args, unOptList, binOptList); + parseOpts(unOptList, binOptList); + + String source(args[startIdx]); + + + // Load the mesh + struct stat tagStat; + + FILE* pFile = fopen( source.c_str(), "rb" ); + if (!pFile) { + OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, + "File " + source + " not found.", "OgreMeshUpgrade"); + } + stat( source.c_str(), &tagStat ); + MemoryDataStream* memstream = new MemoryDataStream(source, tagStat.st_size, true); + size_t result = fread( (void*)memstream->getPtr(), 1, tagStat.st_size, pFile ); + if (result != tagStat.st_size) + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Unexpected error while reading file " + source, "OgreMeshUpgrade"); + fclose( pFile ); + + MeshPtr meshPtr = MeshManager::getSingleton().createManual("conversion", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + Mesh* mesh = meshPtr.get(); + + DataStreamPtr stream(memstream); + meshSerializer->importMesh(stream, mesh); + + // Write out the converted mesh + String dest; + if (numargs == startIdx + 2) { + dest = args[startIdx + 1]; + } else { + dest = source; + } + + String response; + + vertexBufferReorg(*mesh); + + // Deal with VET_COLOUR ambiguities + resolveColourAmbiguities(mesh); + + buildLod(meshPtr); + + if (opts.interactive) { + do { + std::cout << "\nWould you like to (b)uild/(r)emove/(k)eep Edge lists? (b/r/k) "; + cin >> response; + StringUtil::toLowerCase(response); + if (response == "k") { + // Do nothing + } else if (response == "b") { + cout << "\nGenerating edge lists..."; + mesh->buildEdgeList(); + cout << "success\n"; + } else if (response == "r") { + mesh->freeEdgeList(); + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } while (response == ""); + } else { + // Make sure we generate edge lists, provided they are not deliberately disabled + if (!opts.suppressEdgeLists) { + cout << "\nGenerating edge lists..."; + mesh->buildEdgeList(); + cout << "success\n"; + } else { + mesh->freeEdgeList(); + } + } + if (opts.interactive) { + do { + std::cout << "\nWould you like to (g)enerate/(k)eep tangent buffer? (g/k) "; + cin >> response; + StringUtil::toLowerCase(response); + if (response == "k") { + opts.generateTangents = false; + } else if (response == "g") { + opts.generateTangents = true; + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + } while (response == ""); + } + // Generate tangents? + if (opts.generateTangents) { + unsigned short srcTex, destTex; + bool existing = mesh->suggestTangentVectorBuildParams(opts.tangentSemantic, srcTex, destTex); + if (existing) { + if (opts.interactive) { + do { + std::cout << "\nThis mesh appears to already have a set of tangents, " << + "which would suggest tangent vectors have already been calculated. Do you really " << + "want to generate new tangent vectors (may duplicate)? (y/n) "; + cin >> response; + StringUtil::toLowerCase(response); + if (response == "y") { + // Do nothing + } else if (response == "n") { + opts.generateTangents = false; + } else { + std::cout << "Wrong answer!\n"; + response = ""; + } + + } while (response == ""); + } else { + // safe + opts.generateTangents = false; + } + + } + if (opts.generateTangents) { + cout << "\nGenerating tangent vectors...."; + mesh->buildTangentVectors(opts.tangentSemantic, srcTex, destTex, + opts.tangentSplitMirrored, opts.tangentSplitRotated, + opts.tangentUseParity); + cout << "success" << std::endl; + } + } + + + if (opts.recalcBounds) { + recalcBounds(mesh); + } + + meshSerializer->exportMesh(mesh, dest, opts.targetVersion, opts.endian); - } - catch (Exception& e) - { - cout << "Exception caught: " << e.getDescription(); - retCode = 1; - } + } + catch (Exception& e) + { + cout << "Exception caught: " << e.getDescription(); + retCode = 1; + } delete meshMgr; @@ -1175,7 +1175,7 @@ int main(int numargs, char** args) delete meshSerializer; delete skelMgr; delete matMgr; - delete lodMgr; + delete lodMgr; delete mth; delete rgm; delete logMgr; diff --git a/Tools/MilkshapeExport/include/MilkshapePlugin.h b/Tools/MilkshapeExport/include/MilkshapePlugin.h index 41b0a2d1430..d4e3a075e63 100644 --- a/Tools/MilkshapeExport/include/MilkshapePlugin.h +++ b/Tools/MilkshapeExport/include/MilkshapePlugin.h @@ -47,7 +47,7 @@ class MilkshapePlugin : public cMsPlugIn char mTitle[64]; public: - MilkshapePlugin (); + MilkshapePlugin (); virtual ~MilkshapePlugin (); public: @@ -69,10 +69,10 @@ class MilkshapePlugin : public cMsPlugIn bool generateLods; bool generateEdgeLists; bool generateTangents; - Ogre::VertexElementSemantic tangentSemantic; - bool tangentsSplitMirrored; - bool tangentsSplitRotated; - bool tangentsUseParity; + Ogre::VertexElementSemantic tangentSemantic; + bool tangentsSplitMirrored; + bool tangentsSplitRotated; + bool tangentsUseParity; unsigned short numLods; float lodDepthIncrement; Ogre::ProgressiveMesh::VertexReductionQuota lodReductionMethod; @@ -89,7 +89,7 @@ class MilkshapePlugin : public cMsPlugIn void doExportAnimations(msModel* pModel, Ogre::SkeletonPtr& skel); Ogre::SkeletonPtr doExportSkeleton(msModel* pModel, Ogre::MeshPtr& mesh); // Skeleton returned for deletion later bool locateSkeleton(Ogre::MeshPtr& mesh); - Ogre::ColourValue msVec4ToColourValue(float prop[4]); + Ogre::ColourValue msVec4ToColourValue(float prop[4]); }; #endif diff --git a/Tools/MilkshapeExport/include/msLib.h b/Tools/MilkshapeExport/include/msLib.h index 9f0eaaf8a58..0c0203ad778 100644 --- a/Tools/MilkshapeExport/include/msLib.h +++ b/Tools/MilkshapeExport/include/msLib.h @@ -40,11 +40,11 @@ extern "C" { #define MS_MAX_NAME 32 #define MS_MAX_PATH 256 -#define MAX_VERTICES 65534 -#define MAX_TRIANGLES 65534 -#define MAX_GROUPS 255 -#define MAX_MATERIALS 128 -#define MAX_JOINTS 128 +#define MAX_VERTICES 65534 +#define MAX_TRIANGLES 65534 +#define MAX_GROUPS 255 +#define MAX_MATERIALS 128 +#define MAX_JOINTS 128 @@ -94,9 +94,9 @@ typedef struct msVertex /* msVertexEx: used internally only, DO NOT USE DIRECTLY, USE API INSTEAD */ typedef struct msVertexEx { - char nBoneIndices[3]; - byte nBoneWeights[3]; - unsigned int nExtra; + char nBoneIndices[3]; + byte nBoneWeights[3]; + unsigned int nExtra; } msVertexEx; /* msTriangle: used internally only, DO NOT USE DIRECTLY, USE API INSTEAD */ @@ -112,8 +112,8 @@ typedef struct msTriangle /* msTriangleEx: used internally only, DO NOT USE DIRECTLY, USE API INSTEAD */ typedef struct msTriangleEx { - msVec3 Normals[3]; - msVec2 TexCoords[3]; + msVec3 Normals[3]; + msVec2 TexCoords[3]; } msTriangleEx; /* msMesh: used internally only, DO NOT USE DIRECTLY, USE API INSTEAD */ @@ -135,9 +135,9 @@ typedef struct msMesh word nNumAllocedTriangles; msTriangle* pTriangles; - char* pszComment; - msVertexEx *pVertexExs; - msTriangleEx *pTriangleExs; + char* pszComment; + msVertexEx *pVertexExs; + msTriangleEx *pTriangleExs; } msMesh; /* msMaterial: used internally only, DO NOT USE DIRECTLY, USE API INSTEAD */ @@ -154,7 +154,7 @@ typedef struct msMaterial char szDiffuseTexture[MS_MAX_PATH]; char szAlphaTexture[MS_MAX_PATH]; int nName; - char* pszComment; + char* pszComment; } msMaterial; /* msPositionKey */ @@ -187,7 +187,7 @@ typedef struct msBone int nNumRotationKeys; int nNumAllocedRotationKeys; msRotationKey* pRotationKeys; - char* pszComment; + char* pszComment; } msBone; /* msModel: used internally only, DO NOT USE DIRECTLY, USE API INSTEAD */ @@ -211,10 +211,10 @@ typedef struct msModel msVec3 Position; msVec3 Rotation; - msVec3 CameraPosition; - msVec2 CameraRotationXY; + msVec3 CameraPosition; + msVec2 CameraRotationXY; - char* pszComment; + char* pszComment; } msModel; diff --git a/Tools/MilkshapeExport/include/msPlugIn.h b/Tools/MilkshapeExport/include/msPlugIn.h index 4fafa1c2560..d692332f970 100644 --- a/Tools/MilkshapeExport/include/msPlugIn.h +++ b/Tools/MilkshapeExport/include/msPlugIn.h @@ -12,13 +12,13 @@ class cMsPlugIn eTypeImport = 1, eTypeExport = 2, eTypeTool = 3, - eTypeEdit = 4, - eTypeVertex = 5, - eTypeFace = 6, - eTypeAnimate = 7, - eTypeMask = 0x000F, + eTypeEdit = 4, + eTypeVertex = 5, + eTypeFace = 6, + eTypeAnimate = 7, + eTypeMask = 0x000F, - eNormalsAndTexCoordsPerTriangleVertex = 128 + eNormalsAndTexCoordsPerTriangleVertex = 128 }; public: diff --git a/Tools/MilkshapeExport/src/MilkshapeExporter.cpp b/Tools/MilkshapeExport/src/MilkshapeExporter.cpp index 354e0e2d13f..f3387a61dd3 100644 --- a/Tools/MilkshapeExport/src/MilkshapeExporter.cpp +++ b/Tools/MilkshapeExport/src/MilkshapeExporter.cpp @@ -37,15 +37,15 @@ cMsPlugIn* CreatePlugIn () BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved - ) + ) { switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; } return TRUE; } diff --git a/Tools/MilkshapeExport/src/MilkshapePlugin.cpp b/Tools/MilkshapeExport/src/MilkshapePlugin.cpp index b98d5bc84e0..d9c68feae12 100644 --- a/Tools/MilkshapeExport/src/MilkshapePlugin.cpp +++ b/Tools/MilkshapeExport/src/MilkshapePlugin.cpp @@ -63,13 +63,13 @@ int MilkshapePlugin::Execute (msModel* pModel) if (!pModel) return -1; - Ogre::LogManager logMgr; - logMgr.createLog("msOgreExporter.log", true); - logMgr.logMessage("OGRE Milkshape Exporter Log"); - logMgr.logMessage("---------------------------"); - Ogre::ResourceGroupManager resGrpMgr; + Ogre::LogManager logMgr; + logMgr.createLog("msOgreExporter.log", true); + logMgr.logMessage("OGRE Milkshape Exporter Log"); + logMgr.logMessage("---------------------------"); + Ogre::ResourceGroupManager resGrpMgr; - // + // // check, if we have something to export // if (msModel_GetMeshCount (pModel) == 0) @@ -97,7 +97,7 @@ BOOL MilkshapePlugin::DlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam #endif { HWND hwndDlgItem; - int sel; + int sel; switch (iMsg) { @@ -140,11 +140,11 @@ BOOL MilkshapePlugin::DlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam hwndDlgItem = GetDlgItem(hDlg, IDC_EXPORT_SKEL); SendMessage(hwndDlgItem, BM_SETCHECK, BST_CHECKED,0); - // Set tangents option - hwndDlgItem = GetDlgItem(hDlg, IDC_TANGENTS_TARGET); - SendMessage(hwndDlgItem, CB_ADDSTRING, 0, (LPARAM)"Tangent Semantic"); - SendMessage(hwndDlgItem, CB_ADDSTRING, 0, (LPARAM)"Texture Coord Semantic"); - SendMessage(hwndDlgItem, CB_SETCURSEL, 0, 0); + // Set tangents option + hwndDlgItem = GetDlgItem(hDlg, IDC_TANGENTS_TARGET); + SendMessage(hwndDlgItem, CB_ADDSTRING, 0, (LPARAM)"Tangent Semantic"); + SendMessage(hwndDlgItem, CB_ADDSTRING, 0, (LPARAM)"Texture Coord Semantic"); + SendMessage(hwndDlgItem, CB_SETCURSEL, 0, 0); @@ -219,24 +219,24 @@ BOOL MilkshapePlugin::DlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam hwndDlgItem = GetDlgItem(hDlg, IDC_TANGENT_VECTORS); plugin->generateTangents = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; - hwndDlgItem = GetDlgItem(hDlg, IDC_TANGENTS_TARGET); - sel = SendMessage(hwndDlgItem, CB_GETCURSEL,0,0); - if (sel == 0) - { - // tangents - plugin->tangentSemantic = Ogre::VES_TANGENT; - } - else - { - // texture coords - plugin->tangentSemantic = Ogre::VES_TEXTURE_COORDINATES; - } - hwndDlgItem = GetDlgItem(hDlg, IDC_TANG_SPLIT_MIRR); - plugin->tangentsSplitMirrored = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; - hwndDlgItem = GetDlgItem(hDlg, IDC_TANG_SPLIT_ROT); - plugin->tangentsSplitRotated = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; - hwndDlgItem = GetDlgItem(hDlg, IDC_4D_TANGENTS); - plugin->tangentsUseParity = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; + hwndDlgItem = GetDlgItem(hDlg, IDC_TANGENTS_TARGET); + sel = SendMessage(hwndDlgItem, CB_GETCURSEL,0,0); + if (sel == 0) + { + // tangents + plugin->tangentSemantic = Ogre::VES_TANGENT; + } + else + { + // texture coords + plugin->tangentSemantic = Ogre::VES_TEXTURE_COORDINATES; + } + hwndDlgItem = GetDlgItem(hDlg, IDC_TANG_SPLIT_MIRR); + plugin->tangentsSplitMirrored = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; + hwndDlgItem = GetDlgItem(hDlg, IDC_TANG_SPLIT_ROT); + plugin->tangentsSplitRotated = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; + hwndDlgItem = GetDlgItem(hDlg, IDC_4D_TANGENTS); + plugin->tangentsUseParity = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; hwndDlgItem = GetDlgItem(hDlg, IDC_EXPORT_SKEL); plugin->exportSkeleton = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; @@ -245,10 +245,10 @@ BOOL MilkshapePlugin::DlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam hwndDlgItem = GetDlgItem(hDlg, IDC_SPLIT_ANIMATION); plugin->splitAnimations = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; - hwndDlgItem = GetDlgItem(hDlg, IDC_EXPORT_MATERIALS); - plugin->exportMaterials = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; + hwndDlgItem = GetDlgItem(hDlg, IDC_EXPORT_MATERIALS); + plugin->exportMaterials = (SendMessage(hwndDlgItem, BM_GETCHECK, 0, 0) == BST_CHECKED) ? true : false; - hwndDlgItem = GetDlgItem(hDlg, IDC_FPS); + hwndDlgItem = GetDlgItem(hDlg, IDC_FPS); GetWindowText(hwndDlgItem, val, 20); plugin->fps = atof(val); if (!plugin->fps) @@ -277,7 +277,7 @@ bool MilkshapePlugin::showOptions(void) exportMesh = true; exportSkeleton = false; - return (DialogBox(hInst, MAKEINTRESOURCE(IDD_OPTIONS), NULL, DlgProc) == TRUE); + return (DialogBox(hInst, MAKEINTRESOURCE(IDD_OPTIONS), NULL, DlgProc) == TRUE); @@ -293,8 +293,8 @@ void MilkshapePlugin::doExportMesh(msModel* pModel) // Create singletons Ogre::SkeletonManager skelMgr; Ogre::DefaultHardwareBufferManager defHWBufMgr; - Ogre::LogManager& logMgr = Ogre::LogManager::getSingleton(); - Ogre::MeshManager meshMgr; + Ogre::LogManager& logMgr = Ogre::LogManager::getSingleton(); + Ogre::MeshManager meshMgr; // @@ -332,8 +332,8 @@ void MilkshapePlugin::doExportMesh(msModel* pModel) // No shared geometry int i; - int wh, numbones; - int intweight[3], intbones[3]; + int wh, numbones; + int intweight[3], intbones[3]; size_t j; Ogre::Vector3 min, max, currpos; Ogre::Real maxSquaredRadius; @@ -402,7 +402,7 @@ void MilkshapePlugin::doExportMesh(msModel* pModel) { logMgr.logMessage("Doing vertex " + Ogre::StringConverter::toString(j)); msVertex *pVertex = msMesh_GetVertexAt (pMesh, (int)j); - msVertexEx *pVertexEx=msMesh_GetVertexExAt(pMesh, (int)j); + msVertexEx *pVertexEx=msMesh_GetVertexExAt(pMesh, (int)j); msVec3 Vertex; msVertex_GetVertex (pVertex, Vertex); @@ -427,58 +427,58 @@ void MilkshapePlugin::doExportMesh(msModel* pModel) int boneIdx = msVertex_GetBoneIndex(pVertex); if (boneIdx != -1) { - foundBoneAssignment = true; - numbones = 1; - intbones[0] = intbones[1] = intbones[2] = -1; - intweight[0] = intweight[1] = intweight[2] = 0; - for(wh = 0; wh < 3; ++wh) - { - intbones[wh] = msVertexEx_GetBoneIndices(pVertexEx, wh); - if(intbones[wh] == -1) - break; - - ++numbones; - intweight[wh] = msVertexEx_GetBoneWeights(pVertexEx, wh); - - } // for(k) - Ogre::VertexBoneAssignment vertAssign; - vertAssign.boneIndex = boneIdx; - vertAssign.vertexIndex = (unsigned int)j; - if(numbones == 1) - { - vertAssign.weight = 1.0; - } // single assignment - else - { - vertAssign.weight=(Ogre::Real)intweight[0]/100.0; - } - ogreSubMesh->addBoneAssignment(vertAssign); - if(numbones > 1) - { - // this somewhat contorted logic is because the first weight [0] matches to the bone assignment - // located with pVertex. The next two weights [1][2] match up to the first two bones found - // with pVertexEx [0][1]. The weight for the fourth bone, if present, is the unassigned weight - for(wh = 0; wh < 3; wh++) - { - boneIdx = intbones[wh]; - if(boneIdx == -1) - break; - vertAssign.boneIndex = boneIdx; - vertAssign.vertexIndex = (unsigned int)j; - if(wh == 2) - { - // fourth weight is 1.0-(sumoffirstthreeweights) - vertAssign.weight = 1.0-(((Ogre::Real)intweight[0]/100.0)+ - ((Ogre::Real)intweight[1]/100.0)+((Ogre::Real)intweight[2]/100.0)); - } - else - { - vertAssign.weight=(Ogre::Real)intweight[wh+1]; - } - ogreSubMesh->addBoneAssignment(vertAssign); - } // for(k) - } // if(numbones) - } + foundBoneAssignment = true; + numbones = 1; + intbones[0] = intbones[1] = intbones[2] = -1; + intweight[0] = intweight[1] = intweight[2] = 0; + for(wh = 0; wh < 3; ++wh) + { + intbones[wh] = msVertexEx_GetBoneIndices(pVertexEx, wh); + if(intbones[wh] == -1) + break; + + ++numbones; + intweight[wh] = msVertexEx_GetBoneWeights(pVertexEx, wh); + + } // for(k) + Ogre::VertexBoneAssignment vertAssign; + vertAssign.boneIndex = boneIdx; + vertAssign.vertexIndex = (unsigned int)j; + if(numbones == 1) + { + vertAssign.weight = 1.0; + } // single assignment + else + { + vertAssign.weight=(Ogre::Real)intweight[0]/100.0; + } + ogreSubMesh->addBoneAssignment(vertAssign); + if(numbones > 1) + { + // this somewhat contorted logic is because the first weight [0] matches to the bone assignment + // located with pVertex. The next two weights [1][2] match up to the first two bones found + // with pVertexEx [0][1]. The weight for the fourth bone, if present, is the unassigned weight + for(wh = 0; wh < 3; wh++) + { + boneIdx = intbones[wh]; + if(boneIdx == -1) + break; + vertAssign.boneIndex = boneIdx; + vertAssign.vertexIndex = (unsigned int)j; + if(wh == 2) + { + // fourth weight is 1.0-(sumoffirstthreeweights) + vertAssign.weight = 1.0-(((Ogre::Real)intweight[0]/100.0)+ + ((Ogre::Real)intweight[1]/100.0)+((Ogre::Real)intweight[2]/100.0)); + } + else + { + vertAssign.weight=(Ogre::Real)intweight[wh+1]; + } + ogreSubMesh->addBoneAssignment(vertAssign); + } // for(k) + } // if(numbones) + } } pbuf->unlock(); @@ -504,7 +504,7 @@ void MilkshapePlugin::doExportMesh(msModel* pModel) for (j = 0; j < ogreSubMesh->indexData->indexCount; j+=3) { msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, (int)j/3); - msTriangleEx *pTriangleEx=msMesh_GetTriangleExAt(pMesh, (int)j/3); + msTriangleEx *pTriangleEx=msMesh_GetTriangleExAt(pMesh, (int)j/3); word nIndices[3]; msTriangle_GetVertexIndices (pTriangle, nIndices); msVec3 Normal; @@ -519,10 +519,10 @@ void MilkshapePlugin::doExportMesh(msModel* pModel) // Vertex normals // For the moment, ignore any discrepancies per vertex - msTriangleEx_GetNormal(pTriangleEx, k, &Normal[0]); - msTriangleEx_GetTexCoord(pTriangleEx, k, &uv[0]); - pTex[(vertIdx*2)]=uv[0]; - pTex[(vertIdx*2)+1]=uv[1]; + msTriangleEx_GetNormal(pTriangleEx, k, &Normal[0]); + msTriangleEx_GetTexCoord(pTriangleEx, k, &uv[0]); + pTex[(vertIdx*2)]=uv[0]; + pTex[(vertIdx*2)+1]=uv[1]; pNorm[(vertIdx*3)] = Normal[0]; pNorm[(vertIdx*3)+1] = Normal[1]; pNorm[(vertIdx*3)+2] = Normal[2]; @@ -596,14 +596,14 @@ void MilkshapePlugin::doExportMesh(msModel* pModel) if (generateTangents) { - unsigned short src, dest; - ogreMesh->suggestTangentVectorBuildParams(tangentSemantic, src, dest); - ogreMesh->buildTangentVectors(tangentSemantic, src, dest, tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity); + unsigned short src, dest; + ogreMesh->suggestTangentVectorBuildParams(tangentSemantic, src, dest); + ogreMesh->buildTangentVectors(tangentSemantic, src, dest, tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity); } // Export Ogre::String msg; - msg = "Exporting mesh data to file '" + Ogre::String(szFile) + "'"; + msg = "Exporting mesh data to file '" + Ogre::String(szFile) + "'"; logMgr.logMessage(msg); serializer.exportMesh(ogreMesh.getPointer(), szFile); logMgr.logMessage("Export successful"); @@ -612,10 +612,10 @@ void MilkshapePlugin::doExportMesh(msModel* pModel) if (!pSkel.isNull()) Ogre::SkeletonManager::getSingleton().remove(pSkel->getHandle()); - if (exportMaterials && msModel_GetMaterialCount(pModel) > 0) - { - doExportMaterials(pModel); - } + if (exportMaterials && msModel_GetMaterialCount(pModel) > 0) + { + doExportMaterials(pModel); + } } @@ -665,7 +665,7 @@ Ogre::SkeletonPtr MilkshapePlugin::doExportSkeleton(msModel* pModel, Ogre::MeshP // Do the bones int numBones = msModel_GetBoneCount(pModel); - msg = "Number of bones: " + Ogre::StringConverter::toString(numBones); + msg = "Number of bones: " + Ogre::StringConverter::toString(numBones); logMgr.logMessage(msg); int i; @@ -694,8 +694,8 @@ Ogre::SkeletonPtr MilkshapePlugin::doExportSkeleton(msModel* pModel, Ogre::MeshP qfinal = qz * qy * qx; ogrebone->setOrientation(qfinal); - Ogre::LogManager::getSingleton().stream() - << "Bone #" << i << ": " << + Ogre::LogManager::getSingleton().stream() + << "Bone #" << i << ": " << "Name='" << bone->szName << "' " << "Position: " << bonePos << " " << "Ms3d Rotation: {" << msBoneRot[0] << ", " << msBoneRot[1] << ", " << msBoneRot[2] << "} " << @@ -713,7 +713,7 @@ Ogre::SkeletonPtr MilkshapePlugin::doExportSkeleton(msModel* pModel, Ogre::MeshP { // Root bone msg = "Root bone detected: Name='" + Ogre::String(bone->szName) + "' Index=" - + Ogre::StringConverter::toString(i); + + Ogre::StringConverter::toString(i); logMgr.logMessage(msg); } else @@ -724,14 +724,14 @@ Ogre::SkeletonPtr MilkshapePlugin::doExportSkeleton(msModel* pModel, Ogre::MeshP if (ogrechild == 0) { msg = "Error: could not locate child bone '" + - Ogre::String(bone->szName) + "'"; + Ogre::String(bone->szName) + "'"; logMgr.logMessage(msg); continue; } if (ogreparent == 0) { msg = "Error: could not locate parent bone '" - + Ogre::String(bone->szParentName) + "'"; + + Ogre::String(bone->szParentName) + "'"; logMgr.logMessage(msg); continue; } @@ -821,88 +821,88 @@ struct SplitAnimationStruct void MilkshapePlugin::doExportMaterials(msModel* pModel) { - Ogre::LogManager& logMgr = Ogre::LogManager::getSingleton(); - Ogre::MaterialManager matMgrSgl; - Ogre::String msg; + Ogre::LogManager& logMgr = Ogre::LogManager::getSingleton(); + Ogre::MaterialManager matMgrSgl; + Ogre::String msg; matMgrSgl.initialise(); - int numMaterials = msModel_GetMaterialCount(pModel); - msg = "Number of materials: " + Ogre::StringConverter::toString(numMaterials); - logMgr.logMessage(msg); - - OPENFILENAME ofn; - memset (&ofn, 0, sizeof (OPENFILENAME)); - - char szFile[MS_MAX_PATH]; - char szFileTitle[MS_MAX_PATH]; - char szDefExt[32] = "material"; - char szFilter[128] = "OGRE .material Files (*.material)\0*.material\0All Files (*.*)\0*.*\0\0"; - szFile[0] = '\0'; - szFileTitle[0] = '\0'; - - ofn.lStructSize = sizeof (OPENFILENAME); - ofn.lpstrDefExt = szDefExt; - ofn.lpstrFilter = szFilter; - ofn.lpstrFile = szFile; - ofn.nMaxFile = MS_MAX_PATH; - ofn.lpstrFileTitle = szFileTitle; - ofn.nMaxFileTitle = MS_MAX_PATH; - ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; - ofn.lpstrTitle = "Export to OGRE Material"; - - if (!::GetSaveFileName (&ofn)) - return; - - // Strip off the path - Ogre::String matName = szFile; - size_t lastSlash = matName.find_last_of("\\"); - matName = matName.substr(lastSlash+1); - - // Set up - logMgr.logMessage("Trying to create Material object"); - - Ogre::MaterialSerializer matSer; - - for (int i = 0; i < numMaterials; ++i) - { - msMaterial *mat = msModel_GetMaterialAt(pModel, i); - - msg = "Creating material " + Ogre::String(mat->szName); - logMgr.logMessage(msg); + int numMaterials = msModel_GetMaterialCount(pModel); + msg = "Number of materials: " + Ogre::StringConverter::toString(numMaterials); + logMgr.logMessage(msg); + + OPENFILENAME ofn; + memset (&ofn, 0, sizeof (OPENFILENAME)); + + char szFile[MS_MAX_PATH]; + char szFileTitle[MS_MAX_PATH]; + char szDefExt[32] = "material"; + char szFilter[128] = "OGRE .material Files (*.material)\0*.material\0All Files (*.*)\0*.*\0\0"; + szFile[0] = '\0'; + szFileTitle[0] = '\0'; + + ofn.lStructSize = sizeof (OPENFILENAME); + ofn.lpstrDefExt = szDefExt; + ofn.lpstrFilter = szFilter; + ofn.lpstrFile = szFile; + ofn.nMaxFile = MS_MAX_PATH; + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = MS_MAX_PATH; + ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; + ofn.lpstrTitle = "Export to OGRE Material"; + + if (!::GetSaveFileName (&ofn)) + return; + + // Strip off the path + Ogre::String matName = szFile; + size_t lastSlash = matName.find_last_of("\\"); + matName = matName.substr(lastSlash+1); + + // Set up + logMgr.logMessage("Trying to create Material object"); + + Ogre::MaterialSerializer matSer; + + for (int i = 0; i < numMaterials; ++i) + { + msMaterial *mat = msModel_GetMaterialAt(pModel, i); + + msg = "Creating material " + Ogre::String(mat->szName); + logMgr.logMessage(msg); Ogre::MaterialPtr ogremat = matMgrSgl.create(mat->szName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - logMgr.logMessage("Created."); + logMgr.logMessage("Created."); - ogremat->setAmbient(msVec4ToColourValue(mat->Ambient)); - ogremat->setDiffuse(msVec4ToColourValue(mat->Diffuse)); - ogremat->setSpecular(msVec4ToColourValue(mat->Specular)); - ogremat->setShininess(mat->fShininess); + ogremat->setAmbient(msVec4ToColourValue(mat->Ambient)); + ogremat->setDiffuse(msVec4ToColourValue(mat->Diffuse)); + ogremat->setSpecular(msVec4ToColourValue(mat->Specular)); + ogremat->setShininess(mat->fShininess); - if (0 < strlen(mat->szDiffuseTexture)) - ogremat->getTechnique(0)->getPass(0)->createTextureUnitState(mat->szDiffuseTexture); + if (0 < strlen(mat->szDiffuseTexture)) + ogremat->getTechnique(0)->getPass(0)->createTextureUnitState(mat->szDiffuseTexture); if (0 < strlen(mat->szAlphaTexture)) - ogremat->getTechnique(0)->getPass(0)->createTextureUnitState(mat->szAlphaTexture); + ogremat->getTechnique(0)->getPass(0)->createTextureUnitState(mat->szAlphaTexture); - matSer.queueForExport(ogremat); - } + matSer.queueForExport(ogremat); + } - msg = "Exporting materials to " + matName; - logMgr.logMessage(msg); - matSer.exportQueued(matName); + msg = "Exporting materials to " + matName; + logMgr.logMessage(msg); + matSer.exportQueued(matName); } Ogre::ColourValue MilkshapePlugin::msVec4ToColourValue(float prop[4]) { - Ogre::ColourValue colour; - colour.r = prop[0]; - colour.g = prop[1]; - colour.b = prop[2]; - colour.a = prop[3]; + Ogre::ColourValue colour; + colour.r = prop[0]; + colour.g = prop[1]; + colour.b = prop[2]; + colour.a = prop[3]; - return colour; + return colour; } void MilkshapePlugin::doExportAnimations(msModel* pModel, Ogre::SkeletonPtr& ogreskel) @@ -913,19 +913,19 @@ void MilkshapePlugin::doExportAnimations(msModel* pModel, Ogre::SkeletonPtr& ogr Ogre::String msg; int numFrames = msModel_GetTotalFrames(pModel); - msg = "Number of frames: " + Ogre::StringConverter::toString(numFrames); + msg = "Number of frames: " + Ogre::StringConverter::toString(numFrames); logMgr.logMessage(msg); if (splitAnimations) { // Explain msg = "You have chosen to create multiple discrete animations by splitting up the frames in " - "the animation sequence. In order to do this, you must supply a simple text file " + "the animation sequence. In order to do this, you must supply a simple text file " "describing the separate animations, which has a single line per animation in the format: \n\n" "startFrame,endFrame,animationName\n\nFor example: \n\n" "1,20,Walk\n21,35,Run\n36,40,Shoot\n\n" "..creates 3 separate animations (the frame numbers are inclusive)." - "You must browse to this file in the next dialog."; + "You must browse to this file in the next dialog."; MessageBox(0,msg.c_str(), "Splitting Animations",MB_ICONINFORMATION | MB_OK); // Prompt for a file which contains animation splitting info OPENFILENAME ofn; @@ -978,7 +978,7 @@ void MilkshapePlugin::doExportAnimations(msModel* pModel, Ogre::SkeletonPtr& ogr continue; // Split on ',' - std::vector svec = Ogre::StringUtil::split(line, ",\n"); + std::vector svec = Ogre::StringUtil::split(line, ",\n"); // Basic validation on number of elements if (svec.size() != 3) @@ -988,7 +988,7 @@ void MilkshapePlugin::doExportAnimations(msModel* pModel, Ogre::SkeletonPtr& ogr continue; } // Remove any embedded spaces - Ogre::StringUtil::trim(svec[0]); + Ogre::StringUtil::trim(svec[0]); Ogre::StringUtil::trim(svec[1]); Ogre::StringUtil::trim(svec[2]); // Create split info @@ -1030,14 +1030,14 @@ void MilkshapePlugin::doExportAnimations(msModel* pModel, Ogre::SkeletonPtr& ogr // Create animation frameTime = currSplit.end - currSplit.start; realTime = frameTime / fps; - Ogre::LogManager::getSingleton().stream() - << "Trying to create Animation object for animation " - << currSplit.name << " For Frames " << currSplit.start << " to " + Ogre::LogManager::getSingleton().stream() + << "Trying to create Animation object for animation " + << currSplit.name << " For Frames " << currSplit.start << " to " << currSplit.end << " inclusive. "; - Ogre::LogManager::getSingleton().stream() - << "Frame time = " - << frameTime << ", Seconds = " << realTime; + Ogre::LogManager::getSingleton().stream() + << "Frame time = " + << frameTime << ", Seconds = " << realTime; Ogre::Animation *ogreanim = ogreskel->createAnimation(currSplit.name, realTime); @@ -1052,7 +1052,7 @@ void MilkshapePlugin::doExportAnimations(msModel* pModel, Ogre::SkeletonPtr& ogr Ogre::Bone* ogrebone = ogreskel->getBone(bone->szName); // Create animation tracks - msg = "Creating AnimationTrack for bone " + Ogre::StringConverter::toString(i); + msg = "Creating AnimationTrack for bone " + Ogre::StringConverter::toString(i); logMgr.logMessage(msg); Ogre::NodeAnimationTrack *ogretrack = ogreanim->createNodeTrack(i, ogrebone); @@ -1089,23 +1089,23 @@ void MilkshapePlugin::doExportAnimations(msModel* pModel, Ogre::SkeletonPtr& ogr Ogre::TransformKeyFrame *ogrekey = ogretrack->createNodeKeyFrame(realTime); logMgr.logMessage("KeyFrame created"); - Ogre::Vector3 kfPos; - // Imported milkshape animations may not have positions - // for all rotation keys - if ( currKeyIdx < bone->nNumPositionKeys ) { - kfPos.x = currPosKey->Position[0]; - kfPos.y = currPosKey->Position[1]; - kfPos.z = currPosKey->Position[2]; - } - else { - kfPos.x = bone->Position[0]; - kfPos.y = bone->Position[1]; - kfPos.z = bone->Position[2]; - } + Ogre::Vector3 kfPos; + // Imported milkshape animations may not have positions + // for all rotation keys + if ( currKeyIdx < bone->nNumPositionKeys ) { + kfPos.x = currPosKey->Position[0]; + kfPos.y = currPosKey->Position[1]; + kfPos.z = currPosKey->Position[2]; + } + else { + kfPos.x = bone->Position[0]; + kfPos.y = bone->Position[1]; + kfPos.z = bone->Position[2]; + } Ogre::Quaternion qx, qy, qz, kfQ; - // Milkshape translations are local to own orientation, not parent - kfPos = ogrebone->getOrientation() * kfPos; + // Milkshape translations are local to own orientation, not parent + kfPos = ogrebone->getOrientation() * kfPos; ogrekey->setTranslate(kfPos); qx.FromAngleAxis(Ogre::Radian(currRotKey->Rotation[0]), Ogre::Vector3::UNIT_X); @@ -1114,12 +1114,12 @@ void MilkshapePlugin::doExportAnimations(msModel* pModel, Ogre::SkeletonPtr& ogr kfQ = qz * qy * qx; ogrekey->setRotation(kfQ); - Ogre::LogManager::getSingleton().stream() - << "KeyFrame details: Adjusted Frame Time=" << frameTime - << " Seconds: " << realTime << " Position=" << kfPos << " " - << "Ms3d Rotation= {" << currRotKey->Rotation[0] << ", " - << currRotKey->Rotation[1] << ", " << currRotKey->Rotation[2] - << "} " << "Orientation=" << kfQ; + Ogre::LogManager::getSingleton().stream() + << "KeyFrame details: Adjusted Frame Time=" << frameTime + << " Seconds: " << realTime << " Position=" << kfPos << " " + << "Ms3d Rotation= {" << currRotKey->Rotation[0] << ", " + << currRotKey->Rotation[1] << ", " << currRotKey->Rotation[2] + << "} " << "Orientation=" << kfQ; } // keyframe creation } // keys diff --git a/Tools/OgreZip2Cpp/src/OgreZip2Cpp.cpp b/Tools/OgreZip2Cpp/src/OgreZip2Cpp.cpp index d9576d29f9b..28dcbed9f95 100644 --- a/Tools/OgreZip2Cpp/src/OgreZip2Cpp.cpp +++ b/Tools/OgreZip2Cpp/src/OgreZip2Cpp.cpp @@ -92,7 +92,7 @@ int main(int numargs, char** args) // open, read the data to memory and close the in file std::ifstream roStream; - roStream.open(zipFileName.c_str(), std::ifstream::in | std::ifstream::binary); + roStream.open(zipFileName.c_str(), std::ifstream::in | std::ifstream::binary); roStream.read((char *)inFileData, fileSize); roStream.close(); @@ -107,26 +107,26 @@ int main(int numargs, char** args) // ---------------------------------- // add the include - outFileDataPos+= sprintf(outFileDataPos, "#include \"OgreZip.h\"\n\n"); + outFileDataPos+= sprintf(outFileDataPos, "#include \"OgreZip.h\"\n\n"); // start the names place - outFileDataPos+= sprintf(outFileDataPos, "namespace Ogre {\n"); - + outFileDataPos+= sprintf(outFileDataPos, "namespace Ogre {\n"); + // declare the struct outFileDataPos+= sprintf(outFileDataPos, "struct %s{\n", structName.c_str()); // add a data member for the file name - outFileDataPos+= sprintf(outFileDataPos, "\tconst char * fileName;\n"); + outFileDataPos+= sprintf(outFileDataPos, "\tconst char * fileName;\n"); // the struct contractor - outFileDataPos+= sprintf(outFileDataPos, "\t%s() : fileName(\"%s\")\n", structName.c_str(), zipFileName.c_str()); - outFileDataPos+= sprintf(outFileDataPos, "\t{\n"); + outFileDataPos+= sprintf(outFileDataPos, "\t%s() : fileName(\"%s\")\n", structName.c_str(), zipFileName.c_str()); + outFileDataPos+= sprintf(outFileDataPos, "\t{\n"); // declare and init the content of the zip file to a static buffer - outFileDataPos+= sprintf(outFileDataPos, "\t\tstatic uint8 fileData[] = \n"); - outFileDataPos+= sprintf(outFileDataPos, "\t\t{\n\t\t\t"); - int posCurOutInLine = 0; - for( std::streamsize i = 0 ; i < fileSize ; i++ ) + outFileDataPos+= sprintf(outFileDataPos, "\t\tstatic uint8 fileData[] = \n"); + outFileDataPos+= sprintf(outFileDataPos, "\t\t{\n\t\t\t"); + int posCurOutInLine = 0; + for( std::streamsize i = 0 ; i < fileSize ; i++ ) { // get the current char unsigned char outChar = inFileData[i]; @@ -139,61 +139,61 @@ int main(int numargs, char** args) if(outChar < 10) outFileDataPos+= sprintf(outFileDataPos, " "); if(outChar < 100) - outFileDataPos+= sprintf(outFileDataPos, " "); + outFileDataPos+= sprintf(outFileDataPos, " "); // output the char to the out cpp file - outFileDataPos+= sprintf(outFileDataPos, "%d", outChar); - posCurOutInLine+=3; + outFileDataPos+= sprintf(outFileDataPos, "%d", outChar); + posCurOutInLine+=3; // add a comman after every char but the last - if(i + 1 != fileSize) { - outFileDataPos+= sprintf(outFileDataPos, ", "); - posCurOutInLine+=2; - } + if(i + 1 != fileSize) { + outFileDataPos+= sprintf(outFileDataPos, ", "); + posCurOutInLine+=2; + } // cut the line every 100 chars - if (posCurOutInLine > 100) { - outFileDataPos+= sprintf(outFileDataPos, "\n\t\t\t"); - posCurOutInLine = 0; - } - } + if (posCurOutInLine > 100) { + outFileDataPos+= sprintf(outFileDataPos, "\n\t\t\t"); + posCurOutInLine = 0; + } + } // close the static buffer that holds the file data - outFileDataPos+= sprintf(outFileDataPos, "\n\t\t};\n"); + outFileDataPos+= sprintf(outFileDataPos, "\n\t\t};\n"); // register the file buffer to tEmbeddedZipArchiveFactory - outFileDataPos+= sprintf(outFileDataPos, "\t\tEmbeddedZipArchiveFactory::addEmbbeddedFile(fileName, fileData, sizeof(fileData), NULL);\n"); + outFileDataPos+= sprintf(outFileDataPos, "\t\tEmbeddedZipArchiveFactory::addEmbbeddedFile(fileName, fileData, sizeof(fileData), NULL);\n"); // close the contractor - outFileDataPos+= sprintf(outFileDataPos, "}\n"); + outFileDataPos+= sprintf(outFileDataPos, "}\n"); // This code may be risky in some case and is not relevant in most case for this tool so I am leaving it out. // // the distractor -// outFileDataPos+= sprintf(outFileDataPos, "\t~%s()\n", structName.c_str()); -// outFileDataPos+= sprintf(outFileDataPos, "\t{\n"); +// outFileDataPos+= sprintf(outFileDataPos, "\t~%s()\n", structName.c_str()); +// outFileDataPos+= sprintf(outFileDataPos, "\t{\n"); // // remove the file from tEmbeddedZipArchiveFactory in the distractor (for the case of dynamic plugin unload?) -// outFileDataPos+= sprintf(outFileDataPos, "\t\tEmbeddedZipArchiveFactory::removeEmbbeddedFile(fileName);\n"); -// outFileDataPos+= sprintf(outFileDataPos, "\t}\n"); +// outFileDataPos+= sprintf(outFileDataPos, "\t\tEmbeddedZipArchiveFactory::removeEmbbeddedFile(fileName);\n"); +// outFileDataPos+= sprintf(outFileDataPos, "\t}\n"); // close the class - outFileDataPos+= sprintf(outFileDataPos, "};\n"); - outFileDataPos+= sprintf(outFileDataPos, "\n"); + outFileDataPos+= sprintf(outFileDataPos, "};\n"); + outFileDataPos+= sprintf(outFileDataPos, "\n"); // declare a global (static) variable so the struct contractor will be called when the program starts // or the plugin loads. - outFileDataPos+= sprintf(outFileDataPos, "%s g_%s;\n", structName.c_str(), structName.c_str()); - outFileDataPos+= sprintf(outFileDataPos, "\n"); + outFileDataPos+= sprintf(outFileDataPos, "%s g_%s;\n", structName.c_str(), structName.c_str()); + outFileDataPos+= sprintf(outFileDataPos, "\n"); // close the Ogre name space - outFileDataPos+= sprintf(outFileDataPos, "}\n"); + outFileDataPos+= sprintf(outFileDataPos, "}\n"); // write out the cpp file std::ofstream writeStream; - writeStream.open(cppFileName.c_str(), std::ifstream::out | std::ofstream::binary); + writeStream.open(cppFileName.c_str(), std::ifstream::out | std::ofstream::binary); writeStream.write(outFileData, ((std::streamsize)(outFileDataPos - outFileData))); writeStream.close(); // done, let go home and drink some beers - return 0; + return 0; } diff --git a/Tools/VRMLConverter/src/VRML2mesh.cpp b/Tools/VRMLConverter/src/VRML2mesh.cpp index 43c02cbea37..ad784e9f5e2 100644 --- a/Tools/VRMLConverter/src/VRML2mesh.cpp +++ b/Tools/VRMLConverter/src/VRML2mesh.cpp @@ -1,27 +1,27 @@ #include "stdafx.h" struct vertex { - int pos, tc, normal, colour; - - bool operator<(const vertex &v) const { - if (pos < v.pos) return true; - if (pos > v.pos) return false; - if (normal < v.normal) return true; - if (normal > v.normal) return false; - if (tc < v.tc) return true; - if (tc > v.tc) return false; - return colour < v.colour; - } + int pos, tc, normal, colour; + + bool operator<(const vertex &v) const { + if (pos < v.pos) return true; + if (pos > v.pos) return false; + if (normal < v.normal) return true; + if (normal > v.normal) return false; + if (tc < v.tc) return true; + if (tc > v.tc) return false; + return colour < v.colour; + } }; // VRML face struct face { - std::vector indices; + std::vector indices; }; // OGRE face struct triangle { - int vertices[3]; + int vertices[3]; }; typedef std::vector Vec3Vec; @@ -38,11 +38,11 @@ void parseNode(Mesh *, const vrmllib::node *, Matrix4 = Matrix4::IDENTITY); // generate a SubMesh from a Shape void parseShape(Mesh *, const Shape *, Matrix4); - // helpers: - Ogre::MaterialPtr parseMaterial(const Appearance *, const String &name); - void parseFaces(FaceVec &, const IndexedFaceSet *); - void triangulateAndExpand(TriVec &, VertVec &, const FaceVec &, const Shape *); - void copyToSubMesh(SubMesh *, const TriVec &, const VertVec &, const Shape *, const Matrix4 &); + // helpers: + Ogre::MaterialPtr parseMaterial(const Appearance *, const String &name); + void parseFaces(FaceVec &, const IndexedFaceSet *); + void triangulateAndExpand(TriVec &, VertVec &, const FaceVec &, const Shape *); + void copyToSubMesh(SubMesh *, const TriVec &, const VertVec &, const Shape *, const Matrix4 &); // get the array index for a VRML vertex property int getIndex(const IntVec &coordIndex, const IntVec &, bool perVertex, int facenr, int vertnr); @@ -71,470 +71,470 @@ int main(int argc, char **argv) { try { - String inname, outname, path; - - if (argc != 2 && argc != 3) - throw - "Wrong number of arguments.\n" - " Usage: VRML2mesh [output mesh file]"; - - inname = argv[1]; - - // get base name - gBaseName = inname; - size_t p = gBaseName.find_last_of("/\\"); - if (p != gBaseName.npos) { - path.assign(gBaseName, 0, p+1); - gBaseName.erase(0, p+1); - } - p = gBaseName.rfind('.'); - if (p != gBaseName.npos) - gBaseName.erase(p); - - if (argc == 3) - outname = argv[2]; - else - outname = path + gBaseName + ".mesh"; - - LogManager log; - log.createLog(path + "VRML2mesh.log"); - - Math math; + String inname, outname, path; + + if (argc != 2 && argc != 3) + throw + "Wrong number of arguments.\n" + " Usage: VRML2mesh [output mesh file]"; + + inname = argv[1]; + + // get base name + gBaseName = inname; + size_t p = gBaseName.find_last_of("/\\"); + if (p != gBaseName.npos) { + path.assign(gBaseName, 0, p+1); + gBaseName.erase(0, p+1); + } + p = gBaseName.rfind('.'); + if (p != gBaseName.npos) + gBaseName.erase(p); + + if (argc == 3) + outname = argv[2]; + else + outname = path + gBaseName + ".mesh"; + + LogManager log; + log.createLog(path + "VRML2mesh.log"); + + Math math; ResourceGroupManager resGrpMgr; - MaterialManager materialMgr; - MeshSerializer meshSer; - - Mesh mesh("conversionTarget"); - - try { - log.logMessage("Reading " + inname); - - // read VRML file - std::ifstream infile(inname.c_str()); - if (!infile.is_open()) - throw "failed to open input file"; - - vrmllib::file vfile(infile); - log.logMessage("Finished parsing VRML file"); - - // populate name map - for (vrmllib::file::defs_t::iterator i=vfile.defs.begin(), e=vfile.defs.end(); i!=e; ++i) - gNameMap[i->second] = i->first; - - // search from SubMeshes - parseFile(&mesh, vfile); - - if (mesh.getNumSubMeshes() == 0) - throw "No SubMeshes were generated, aborting."; - - log.logMessage("Exporting Mesh"); - meshSer.exportMesh(&mesh, outname, true); - - log.logMessage("Done."); - } - catch (const char *e) { - log.logMessage(LML_NORMAL, "Error: %s", e); - return 1; - } - catch (std::exception &e) { - log.logMessage(LML_NORMAL, "Exception: %s", e.what()); - return 1; - } - catch (Exception &e) { - log.logMessage("Exception: " + e.getFullDescription()); - return 1; - } + MaterialManager materialMgr; + MeshSerializer meshSer; + + Mesh mesh("conversionTarget"); + + try { + log.logMessage("Reading " + inname); + + // read VRML file + std::ifstream infile(inname.c_str()); + if (!infile.is_open()) + throw "failed to open input file"; + + vrmllib::file vfile(infile); + log.logMessage("Finished parsing VRML file"); + + // populate name map + for (vrmllib::file::defs_t::iterator i=vfile.defs.begin(), e=vfile.defs.end(); i!=e; ++i) + gNameMap[i->second] = i->first; + + // search from SubMeshes + parseFile(&mesh, vfile); + + if (mesh.getNumSubMeshes() == 0) + throw "No SubMeshes were generated, aborting."; + + log.logMessage("Exporting Mesh"); + meshSer.exportMesh(&mesh, outname, true); + + log.logMessage("Done."); + } + catch (const char *e) { + log.logMessage(LML_NORMAL, "Error: %s", e); + return 1; + } + catch (std::exception &e) { + log.logMessage(LML_NORMAL, "Exception: %s", e.what()); + return 1; + } + catch (Exception &e) { + log.logMessage("Exception: " + e.getFullDescription()); + return 1; + } } catch (Exception &e) { - std::cerr << "Exception: " << e.getFullDescription() << std::endl; - return 1; + std::cerr << "Exception: " << e.getFullDescription() << std::endl; + return 1; } catch (const char *e) { - std::cerr << e << std::endl; - return 1; + std::cerr << e << std::endl; + return 1; } } void parseFile(Mesh *mesh, const vrmllib::file &file) { - for (vrmllib::file::roots_t::const_iterator i=file.roots.begin(), e=file.roots.end(); i!=e; ++i) - parseNode(mesh, *i); + for (vrmllib::file::roots_t::const_iterator i=file.roots.begin(), e=file.roots.end(); i!=e; ++i) + parseNode(mesh, *i); } void parseNode(Mesh *mesh, const vrmllib::node *n, Matrix4 m) { - if (const Transform *tr = dynamic_cast(n)) { - // TODO: handle center, scaleOrientation - - Matrix4 trans; - trans.makeTrans(vec(tr->translation)); - - Matrix4 scale = Matrix4::IDENTITY; - scale[0][0] = tr->scale.x; - scale[1][1] = tr->scale.y; - scale[2][2] = tr->scale.z; - - Matrix3 rot3; - rot3.FromAxisAngle(vec(tr->rotation.vector), tr->rotation.radians); - Matrix4 rot = Matrix4::IDENTITY; - rot = rot3; - - m = m * transMat(tr->translation) * transMat(tr->center) - * rotMat(tr->rotation) * rotMat(tr->scaleOrientation) * scaleMat(tr->scale) - * rotMat(tr->scaleOrientation, true) * transMat(tr->center, true); - } - - if (const grouping_node *gn = dynamic_cast(n)) { - for (std::vector::const_iterator - i=gn->children.begin(), e=gn->children.end(); i!=e; ++i) - parseNode(mesh, *i, m); - - } else if (const Shape *sh = dynamic_cast(n)) - parseShape(mesh, sh, m); + if (const Transform *tr = dynamic_cast(n)) { + // TODO: handle center, scaleOrientation + + Matrix4 trans; + trans.makeTrans(vec(tr->translation)); + + Matrix4 scale = Matrix4::IDENTITY; + scale[0][0] = tr->scale.x; + scale[1][1] = tr->scale.y; + scale[2][2] = tr->scale.z; + + Matrix3 rot3; + rot3.FromAxisAngle(vec(tr->rotation.vector), tr->rotation.radians); + Matrix4 rot = Matrix4::IDENTITY; + rot = rot3; + + m = m * transMat(tr->translation) * transMat(tr->center) + * rotMat(tr->rotation) * rotMat(tr->scaleOrientation) * scaleMat(tr->scale) + * rotMat(tr->scaleOrientation, true) * transMat(tr->center, true); + } + + if (const grouping_node *gn = dynamic_cast(n)) { + for (std::vector::const_iterator + i=gn->children.begin(), e=gn->children.end(); i!=e; ++i) + parseNode(mesh, *i, m); + + } else if (const Shape *sh = dynamic_cast(n)) + parseShape(mesh, sh, m); } void parseShape(Mesh *mesh, const Shape *sh, Matrix4 mat) { try { - LogManager &log = LogManager::getSingleton(); - log.logMessage("Found a Shape..."); - - IndexedFaceSet *ifs = dynamic_cast(sh->geometry); - if (!ifs) - throw "Geometry was not an IndexedFaceSet, keep looking"; - - Coordinate *coord = dynamic_cast(ifs->coord); - if (!coord) - throw "Invalid Coordinate node"; - if (coord->point.empty()) - throw "No coordinates found, ignoring this Shape"; - - SubMesh *sub; - if (const String *name = findNameRecursive(sh)) { - log.logMessage("Creating SubMesh: " + *name); - sub = mesh->createSubMesh(*name); - } else { - log.logMessage("Creating unnamed SubMesh"); - sub = mesh->createSubMesh(); - } - - Appearance *app = dynamic_cast(sh->appearance); - TextureCoordinate *tcs = dynamic_cast(ifs->texCoord); - Normal *norm = dynamic_cast(ifs->normal); - Color *color = dynamic_cast(ifs->color); - - String message = "Found: geometry"; - if (tcs) - message += ", texcoords"; - if (norm) - message += ", normals"; - if (color) - message += ", colours"; - log.logMessage(message); - - if (!tcs && !norm && !color) - log.logMessage("Warning: OGRE will refuse to render SubMeshes that have neither\n" - "\ttexture coordinates, normals or vertex colours."); - - if (!norm) { - log.logMessage("Warning: No normals found.\n" - "\tVRML dictates that normals should be generated, but this program\n" - "\tdoes not do so. If you want the resulting mesh to contain normals,\n" - "\tmake sure they are exported."); - } - - // process material - static std::map matMap; - - Ogre::MaterialPtr material = matMap[app]; - if (!material->isNull() && app) { - log.logMessage("Using material " + material->getName()); - sub->setMaterialName(material->getName()); - } else { - String matName; - const String *mn; - if (mn = findName(app)) - matName = *mn; - else if (app && (mn = findName(app->material))) { - static std::map postfix; - std::stringstream ss; - int &num = postfix[*mn]; - ss << *mn << '/' << num++; - matName = ss.str(); - } else { - static int matNum; - std::stringstream ss; - ss << gBaseName << '/' << matNum++; - matName = ss.str(); - log.logMessage("No material name found, using " + matName); - } - log.logMessage("Reading material " + matName); - - material = parseMaterial(app, matName); - - sub->setMaterialName(matName); - } - - FaceVec faces; - parseFaces(faces, ifs); - - VertVec vertices; - TriVec triangles; - - log.logMessage("Processing geometry..."); - triangulateAndExpand(triangles, vertices, faces, sh); - - copyToSubMesh(sub, triangles, vertices, sh, mat); - - log.logMessage("Done with this SubMesh."); + LogManager &log = LogManager::getSingleton(); + log.logMessage("Found a Shape..."); + + IndexedFaceSet *ifs = dynamic_cast(sh->geometry); + if (!ifs) + throw "Geometry was not an IndexedFaceSet, keep looking"; + + Coordinate *coord = dynamic_cast(ifs->coord); + if (!coord) + throw "Invalid Coordinate node"; + if (coord->point.empty()) + throw "No coordinates found, ignoring this Shape"; + + SubMesh *sub; + if (const String *name = findNameRecursive(sh)) { + log.logMessage("Creating SubMesh: " + *name); + sub = mesh->createSubMesh(*name); + } else { + log.logMessage("Creating unnamed SubMesh"); + sub = mesh->createSubMesh(); + } + + Appearance *app = dynamic_cast(sh->appearance); + TextureCoordinate *tcs = dynamic_cast(ifs->texCoord); + Normal *norm = dynamic_cast(ifs->normal); + Color *color = dynamic_cast(ifs->color); + + String message = "Found: geometry"; + if (tcs) + message += ", texcoords"; + if (norm) + message += ", normals"; + if (color) + message += ", colours"; + log.logMessage(message); + + if (!tcs && !norm && !color) + log.logMessage("Warning: OGRE will refuse to render SubMeshes that have neither\n" + "\ttexture coordinates, normals or vertex colours."); + + if (!norm) { + log.logMessage("Warning: No normals found.\n" + "\tVRML dictates that normals should be generated, but this program\n" + "\tdoes not do so. If you want the resulting mesh to contain normals,\n" + "\tmake sure they are exported."); + } + + // process material + static std::map matMap; + + Ogre::MaterialPtr material = matMap[app]; + if (!material->isNull() && app) { + log.logMessage("Using material " + material->getName()); + sub->setMaterialName(material->getName()); + } else { + String matName; + const String *mn; + if (mn = findName(app)) + matName = *mn; + else if (app && (mn = findName(app->material))) { + static std::map postfix; + std::stringstream ss; + int &num = postfix[*mn]; + ss << *mn << '/' << num++; + matName = ss.str(); + } else { + static int matNum; + std::stringstream ss; + ss << gBaseName << '/' << matNum++; + matName = ss.str(); + log.logMessage("No material name found, using " + matName); + } + log.logMessage("Reading material " + matName); + + material = parseMaterial(app, matName); + + sub->setMaterialName(matName); + } + + FaceVec faces; + parseFaces(faces, ifs); + + VertVec vertices; + TriVec triangles; + + log.logMessage("Processing geometry..."); + triangulateAndExpand(triangles, vertices, faces, sh); + + copyToSubMesh(sub, triangles, vertices, sh, mat); + + log.logMessage("Done with this SubMesh."); } catch (const char *e) { - LogManager::getSingleton().logMessage(e); + LogManager::getSingleton().logMessage(e); } } void copyToSubMesh(SubMesh *sub, const TriVec &triangles, const VertVec &vertices, - const Shape *sh, const Matrix4 &mat) + const Shape *sh, const Matrix4 &mat) { - IndexedFaceSet *ifs = dynamic_cast(sh->geometry); - Coordinate *coord = dynamic_cast(ifs->coord); - TextureCoordinate *tcs = dynamic_cast(ifs->texCoord); - Normal *norm = dynamic_cast(ifs->normal); - Color *color = dynamic_cast(ifs->color); - - int nvertices = vertices.size(); - int nfaces = triangles.size(); - - GeometryData &geom = sub->geometry; - sub->useSharedVertices = false; - sub->numFaces = nfaces; - sub->faceVertexIndices = new unsigned short[nfaces*3]; - - geom.hasColours = color; - geom.hasNormals = norm; - geom.numTexCoords = tcs ? 1 : 0; - geom.numTexCoordDimensions[0] = 2; - geom.numVertices = nvertices; - - geom.pVertices = new Real[nvertices*3]; - if (tcs) - geom.pTexCoords[0] = new Real[nvertices*2]; - if (norm) - geom.pNormals = new Real[nvertices*3]; - if (color) - geom.pColours = new unsigned long[nvertices]; - - Matrix3 normMat; - mat.extract3x3Matrix(normMat); - normMat = normMat.Inverse().Transpose(); - - // populate face list - for (int i=0; i!=nfaces; ++i) { - unsigned short *f = sub->faceVertexIndices + i*3; - f[0] = triangles[i].vertices[0]; - f[1] = triangles[i].vertices[1]; - f[2] = triangles[i].vertices[2]; - } - - // populate vertex arrays - for (int i=0; i!=nvertices; ++i) { - const vertex &v = vertices[i]; - - Real *pos = geom.pVertices + i*3; - Real *tc = geom.pTexCoords[0] + i*2; - Real *n = geom.pNormals + i*3; - unsigned long *col = geom.pColours + i; - - copyVec(pos, mat * vec(coord->point[v.pos])); - if (norm) { - Vector3 t = normMat * vec(norm->vector[v.normal]); - t.normalise(); - copyVec(n, t); - } - if (tcs) - copyVec(tc, tcs->point[v.tc]); - if (color) { - col3 c = color->color[v.colour]; - ColourValue cv(c.r, c.g, c.b); - *col = cv.getAsLongRGBA(); - } - } + IndexedFaceSet *ifs = dynamic_cast(sh->geometry); + Coordinate *coord = dynamic_cast(ifs->coord); + TextureCoordinate *tcs = dynamic_cast(ifs->texCoord); + Normal *norm = dynamic_cast(ifs->normal); + Color *color = dynamic_cast(ifs->color); + + int nvertices = vertices.size(); + int nfaces = triangles.size(); + + GeometryData &geom = sub->geometry; + sub->useSharedVertices = false; + sub->numFaces = nfaces; + sub->faceVertexIndices = new unsigned short[nfaces*3]; + + geom.hasColours = color; + geom.hasNormals = norm; + geom.numTexCoords = tcs ? 1 : 0; + geom.numTexCoordDimensions[0] = 2; + geom.numVertices = nvertices; + + geom.pVertices = new Real[nvertices*3]; + if (tcs) + geom.pTexCoords[0] = new Real[nvertices*2]; + if (norm) + geom.pNormals = new Real[nvertices*3]; + if (color) + geom.pColours = new unsigned long[nvertices]; + + Matrix3 normMat; + mat.extract3x3Matrix(normMat); + normMat = normMat.Inverse().Transpose(); + + // populate face list + for (int i=0; i!=nfaces; ++i) { + unsigned short *f = sub->faceVertexIndices + i*3; + f[0] = triangles[i].vertices[0]; + f[1] = triangles[i].vertices[1]; + f[2] = triangles[i].vertices[2]; + } + + // populate vertex arrays + for (int i=0; i!=nvertices; ++i) { + const vertex &v = vertices[i]; + + Real *pos = geom.pVertices + i*3; + Real *tc = geom.pTexCoords[0] + i*2; + Real *n = geom.pNormals + i*3; + unsigned long *col = geom.pColours + i; + + copyVec(pos, mat * vec(coord->point[v.pos])); + if (norm) { + Vector3 t = normMat * vec(norm->vector[v.normal]); + t.normalise(); + copyVec(n, t); + } + if (tcs) + copyVec(tc, tcs->point[v.tc]); + if (color) { + col3 c = color->color[v.colour]; + ColourValue cv(c.r, c.g, c.b); + *col = cv.getAsLongRGBA(); + } + } } void triangulateAndExpand(TriVec &triangles, VertVec &vertices, const FaceVec &faces, const Shape *sh) { - IndexedFaceSet *ifs = dynamic_cast(sh->geometry); - Coordinate *coord = dynamic_cast(ifs->coord); - TextureCoordinate *tcs = dynamic_cast(ifs->texCoord); - Normal *norm = dynamic_cast(ifs->normal); - Color *color = dynamic_cast(ifs->color); - - VertMap vertexMap; - - // triangulate and expand vertices - for (FaceVec::const_iterator f=faces.begin(), e=faces.end(); f!=e; ++f) { - int faceNr = f - faces.begin(); - int triVertNr = 0; - int triVerts[2] = { -1, -1 }; - for (IntVec::const_iterator i = f->indices.begin(), e=f->indices.end(); i!=e; ++i, ++triVertNr) { - int triVertNr = i - f->indices.begin(); - int index = *i; - - vertex vert; - - // get full indices for vertex data - vert.pos = ifs->coordIndex[index]; - vert.normal = norm ? getIndex(ifs->coordIndex, ifs->normalIndex, - ifs->normalPerVertex, faceNr, index) : 0; - vert.colour = color ? getIndex(ifs->coordIndex, ifs->colorIndex, - ifs->colorPerVertex, faceNr, index) : 0; - vert.tc = tcs ? getIndex(ifs->coordIndex, ifs->texCoordIndex, - true, faceNr, index) : 0; - - // avoid duplication - int nvert = vertexMap.size(); - int &vpos = vertexMap[vert]; - if (nvert != vertexMap.size()) { - vpos = vertices.size(); - vertices.push_back(vert); - } - - // emit triangle (maybe) - if (triVertNr == 0) - triVerts[0] = vpos; - else if (triVertNr == 1) - triVerts[1] = vpos; - else { - triangle t; - t.vertices[0] = triVerts[0]; - t.vertices[1] = triVerts[1]; - t.vertices[2] = vpos; - - if (!ifs->ccw) - std::swap(t.vertices[1], t.vertices[2]); - - triangles.push_back(t); - - triVerts[1] = vpos; - } - } - } + IndexedFaceSet *ifs = dynamic_cast(sh->geometry); + Coordinate *coord = dynamic_cast(ifs->coord); + TextureCoordinate *tcs = dynamic_cast(ifs->texCoord); + Normal *norm = dynamic_cast(ifs->normal); + Color *color = dynamic_cast(ifs->color); + + VertMap vertexMap; + + // triangulate and expand vertices + for (FaceVec::const_iterator f=faces.begin(), e=faces.end(); f!=e; ++f) { + int faceNr = f - faces.begin(); + int triVertNr = 0; + int triVerts[2] = { -1, -1 }; + for (IntVec::const_iterator i = f->indices.begin(), e=f->indices.end(); i!=e; ++i, ++triVertNr) { + int triVertNr = i - f->indices.begin(); + int index = *i; + + vertex vert; + + // get full indices for vertex data + vert.pos = ifs->coordIndex[index]; + vert.normal = norm ? getIndex(ifs->coordIndex, ifs->normalIndex, + ifs->normalPerVertex, faceNr, index) : 0; + vert.colour = color ? getIndex(ifs->coordIndex, ifs->colorIndex, + ifs->colorPerVertex, faceNr, index) : 0; + vert.tc = tcs ? getIndex(ifs->coordIndex, ifs->texCoordIndex, + true, faceNr, index) : 0; + + // avoid duplication + int nvert = vertexMap.size(); + int &vpos = vertexMap[vert]; + if (nvert != vertexMap.size()) { + vpos = vertices.size(); + vertices.push_back(vert); + } + + // emit triangle (maybe) + if (triVertNr == 0) + triVerts[0] = vpos; + else if (triVertNr == 1) + triVerts[1] = vpos; + else { + triangle t; + t.vertices[0] = triVerts[0]; + t.vertices[1] = triVerts[1]; + t.vertices[2] = vpos; + + if (!ifs->ccw) + std::swap(t.vertices[1], t.vertices[2]); + + triangles.push_back(t); + + triVerts[1] = vpos; + } + } + } } int getIndex(const IntVec &coordIndex, const IntVec &vec, bool perVertex, int facenr, int index) { - if (!perVertex) { - if (!vec.empty()) - return vec[facenr]; - else - return facenr; - } else { - if (!vec.empty()) - return vec[index]; - else - return coordIndex[index]; - } + if (!perVertex) { + if (!vec.empty()) + return vec[facenr]; + else + return facenr; + } else { + if (!vec.empty()) + return vec[index]; + else + return coordIndex[index]; + } } const String *findName(const vrmllib::node *n) { - NameMap::const_iterator i = gNameMap.find(n); - if (i == gNameMap.end()) - return 0; - else - return &i->second; + NameMap::const_iterator i = gNameMap.find(n); + if (i == gNameMap.end()) + return 0; + else + return &i->second; } const String *findNameRecursive(const vrmllib::node *n) { - if (const String *name = findName(n)) - return name; - else if (n->parent) - return findNameRecursive(n->parent); - else - return 0; + if (const String *name = findName(n)) + return name; + else if (n->parent) + return findNameRecursive(n->parent); + else + return 0; } void parseFaces(FaceVec &faces, const IndexedFaceSet *ifs) { - face f; - for (IntVec::const_iterator i=ifs->coordIndex.begin(), e=ifs->coordIndex.end(); i!=e; ++i) { - if (*i == -1) { - faces.resize(faces.size()+1); - faces.back().indices.swap(f.indices); - } else - f.indices.push_back(i - ifs->coordIndex.begin()); - } - if (!f.indices.empty()) { - faces.resize(faces.size()+1); - faces.back().indices.swap(f.indices); - } + face f; + for (IntVec::const_iterator i=ifs->coordIndex.begin(), e=ifs->coordIndex.end(); i!=e; ++i) { + if (*i == -1) { + faces.resize(faces.size()+1); + faces.back().indices.swap(f.indices); + } else + f.indices.push_back(i - ifs->coordIndex.begin()); + } + if (!f.indices.empty()) { + faces.resize(faces.size()+1); + faces.back().indices.swap(f.indices); + } } Ogre::MaterialPtr parseMaterial(const Appearance *app, const String &name) { - vrmllib::Material *vm = app ? dynamic_cast(app->material) : 0; - vrmllib::ImageTexture *texture = app ? dynamic_cast(app->texture) : 0; + vrmllib::Material *vm = app ? dynamic_cast(app->material) : 0; + vrmllib::ImageTexture *texture = app ? dynamic_cast(app->texture) : 0; - Ogre::MaterialPtr m = MaterialManager::getSingleton().create(name, + Ogre::MaterialPtr m = MaterialManager::getSingleton().create(name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - ColourValue diffuse = texture ? ColourValue::White : col(vm->diffuseColor); - // diffuse colour is unused by VRML when a texture is avaliable, - // set to white to give the same effect in OGRE - - ColourValue a = diffuse; - a.r *= vm->ambientIntensity; - a.g *= vm->ambientIntensity; - a.b *= vm->ambientIntensity; - m->setAmbient(a); - m->setDiffuse(diffuse); - m->setSelfIllumination(col(vm->emissiveColor)); - m->setShininess(vm->shininess); - m->setSpecular(col(vm->specularColor)); - - m->setLightingEnabled(app); - - if (texture && !texture->url.empty()) { - String texName = texture->url.front(); - size_t p = texName.find_last_of("/\\"); - if (p != texName.npos) { - LogManager::getSingleton().logMessage("Stripping path from texture " + texName); - texName.erase(0, p+1); - } - - LogManager::getSingleton().logMessage("Adding texture layer for " + texName); - - Ogre::TextureUnitState *l = m->addTextureLayer(texName); - l->setTextureAddressingMode(texture->repeatS ? - Ogre::TextureUnitState::TAM_WRAP : Ogre::TextureUnitState::TAM_CLAMP); - } - - return m; + ColourValue diffuse = texture ? ColourValue::White : col(vm->diffuseColor); + // diffuse colour is unused by VRML when a texture is avaliable, + // set to white to give the same effect in OGRE + + ColourValue a = diffuse; + a.r *= vm->ambientIntensity; + a.g *= vm->ambientIntensity; + a.b *= vm->ambientIntensity; + m->setAmbient(a); + m->setDiffuse(diffuse); + m->setSelfIllumination(col(vm->emissiveColor)); + m->setShininess(vm->shininess); + m->setSpecular(col(vm->specularColor)); + + m->setLightingEnabled(app); + + if (texture && !texture->url.empty()) { + String texName = texture->url.front(); + size_t p = texName.find_last_of("/\\"); + if (p != texName.npos) { + LogManager::getSingleton().logMessage("Stripping path from texture " + texName); + texName.erase(0, p+1); + } + + LogManager::getSingleton().logMessage("Adding texture layer for " + texName); + + Ogre::TextureUnitState *l = m->addTextureLayer(texName); + l->setTextureAddressingMode(texture->repeatS ? + Ogre::TextureUnitState::TAM_WRAP : Ogre::TextureUnitState::TAM_CLAMP); + } + + return m; } Matrix4 transMat(vrmllib::vec3 v, bool inverse) { - if (inverse) - return Matrix4::getTrans(-v.x, -v.y, -v.z); - else - return Matrix4::getTrans(v.x, v.y, v.z); + if (inverse) + return Matrix4::getTrans(-v.x, -v.y, -v.z); + else + return Matrix4::getTrans(v.x, v.y, v.z); } Matrix4 scaleMat(vrmllib::vec3 v, bool inverse) { - if (inverse) - return Matrix4::getScale(1/v.x, 1/v.y, 1/v.z); - else - return Matrix4::getScale(v.x, v.y, v.z); + if (inverse) + return Matrix4::getScale(1/v.x, 1/v.y, 1/v.z); + else + return Matrix4::getScale(v.x, v.y, v.z); } Matrix4 rotMat(vrmllib::rot r, bool inverse) { - Matrix3 rot3; - rot3.FromAxisAngle(vec(r.vector), inverse ? -r.radians : r.radians); - Matrix4 rot = Matrix4::IDENTITY; - rot = rot3; - return rot; + Matrix3 rot3; + rot3.FromAxisAngle(vec(r.vector), inverse ? -r.radians : r.radians); + Matrix4 rot = Matrix4::IDENTITY; + rot = rot3; + return rot; } diff --git a/Tools/VRMLConverter/vrmllib/include/vrmllib/file.h b/Tools/VRMLConverter/vrmllib/include/vrmllib/file.h index bd6ac5b2c68..8f8084971e8 100644 --- a/Tools/VRMLConverter/vrmllib/include/vrmllib/file.h +++ b/Tools/VRMLConverter/vrmllib/include/vrmllib/file.h @@ -16,16 +16,16 @@ namespace vrmllib { * destroyed. */ class file { public: - explicit file(std::istream &); - ~file(); + explicit file(std::istream &); + ~file(); - typedef std::map defs_t; - typedef std::vector nodes_t; - typedef std::vector roots_t; + typedef std::map defs_t; + typedef std::vector nodes_t; + typedef std::vector roots_t; - defs_t defs; - nodes_t nodes; - roots_t roots; + defs_t defs; + nodes_t nodes; + roots_t roots; }; } // namespace vrmllib diff --git a/Tools/VRMLConverter/vrmllib/include/vrmllib/node.h b/Tools/VRMLConverter/vrmllib/include/vrmllib/node.h index e18a9b636da..cd6fd0c6b87 100644 --- a/Tools/VRMLConverter/vrmllib/include/vrmllib/node.h +++ b/Tools/VRMLConverter/vrmllib/include/vrmllib/node.h @@ -13,22 +13,22 @@ class node; class grouping_node; namespace bits { - void parse_value(node *&, std::istream &, file &); + void parse_value(node *&, std::istream &, file &); } // namespace bits class node { - friend class file; - static node *parse_node(std::istream &, file &, const std::string &type); - static node *parse_node_xdef(std::istream &, file &, const std::string &firstWord); - static node *create_node(const std::string &type); + friend class file; + static node *parse_node(std::istream &, file &, const std::string &type); + static node *parse_node_xdef(std::istream &, file &, const std::string &firstWord); + static node *create_node(const std::string &type); protected: - virtual void parse_attribute(const std::string &name, std::istream &, - file &); - friend void bits::parse_value(node *&, std::istream &, file &); + virtual void parse_attribute(const std::string &name, std::istream &, + file &); + friend void bits::parse_value(node *&, std::istream &, file &); public: - virtual ~node() = 0; + virtual ~node() = 0; - grouping_node *parent; + grouping_node *parent; }; } // namespace vrmllib diff --git a/Tools/VRMLConverter/vrmllib/include/vrmllib/nodes.h b/Tools/VRMLConverter/vrmllib/include/vrmllib/nodes.h index 7d3e9428193..b6dac7c31bd 100644 --- a/Tools/VRMLConverter/vrmllib/include/vrmllib/nodes.h +++ b/Tools/VRMLConverter/vrmllib/include/vrmllib/nodes.h @@ -8,155 +8,155 @@ namespace vrmllib { #define VRMLLIB_NODE_CLASS2(name, base) \ - public: \ - name(); \ - VRMLLIB_NODE_CLASS2_ND(name, base) + public: \ + name(); \ + VRMLLIB_NODE_CLASS2_ND(name, base) #define VRMLLIB_NODE_CLASS2_ND(name, base) \ - protected: \ - void parse_attribute(const std::string &, std::istream &, file &);\ - private: \ - typedef base base_type; + protected: \ + void parse_attribute(const std::string &, std::istream &, file &);\ + private: \ + typedef base base_type; #define VRMLLIB_NODE_CLASS(name) \ - VRMLLIB_NODE_CLASS2(name, node) + VRMLLIB_NODE_CLASS2(name, node) #define VRMLLIB_NODE_CLASS_ND(name) \ - VRMLLIB_NODE_CLASS2_ND(name, node) + VRMLLIB_NODE_CLASS2_ND(name, node) class grouping_node : public node { - VRMLLIB_NODE_CLASS_ND(grouping_node) + VRMLLIB_NODE_CLASS_ND(grouping_node) public: - std::vector children; + std::vector children; }; class Transform : public grouping_node { - VRMLLIB_NODE_CLASS2(Transform, grouping_node) + VRMLLIB_NODE_CLASS2(Transform, grouping_node) public: - vec3 translation, center, scale; - rot rotation, scaleOrientation; + vec3 translation, center, scale; + rot rotation, scaleOrientation; }; class Group : public grouping_node { - VRMLLIB_NODE_CLASS2_ND(Group, grouping_node) + VRMLLIB_NODE_CLASS2_ND(Group, grouping_node) public: }; class Switch : public node { - VRMLLIB_NODE_CLASS(Switch) + VRMLLIB_NODE_CLASS(Switch) public: - std::vector choice; - int whichChoice; + std::vector choice; + int whichChoice; }; class Shape : public node { - VRMLLIB_NODE_CLASS(Shape) + VRMLLIB_NODE_CLASS(Shape) public: - node *appearance; - node *geometry; + node *appearance; + node *geometry; }; class Appearance : public node { - VRMLLIB_NODE_CLASS(Appearance) + VRMLLIB_NODE_CLASS(Appearance) public: - node *material; - node *texture; + node *material; + node *texture; }; class WorldInfo : public node { - VRMLLIB_NODE_CLASS_ND(WorldInfo) + VRMLLIB_NODE_CLASS_ND(WorldInfo) public: - std::string title; - std::vector info; + std::string title; + std::vector info; }; class Viewpoint : public node { - VRMLLIB_NODE_CLASS(Viewpoint) + VRMLLIB_NODE_CLASS(Viewpoint) public: - float fieldOfView; - rot orientation; - vec3 position; - std::string description; + float fieldOfView; + rot orientation; + vec3 position; + std::string description; }; class Material : public node { - VRMLLIB_NODE_CLASS(Material) + VRMLLIB_NODE_CLASS(Material) public: - col3 diffuseColor; - col3 specularColor; - col3 emissiveColor; - float ambientIntensity; - float shininess; - float transparency; + col3 diffuseColor; + col3 specularColor; + col3 emissiveColor; + float ambientIntensity; + float shininess; + float transparency; }; class IndexedFaceSet : public node { - VRMLLIB_NODE_CLASS(IndexedFaceSet) -public: - bool solid; - bool convex; - bool ccw; - bool normalPerVertex; - bool colorPerVertex; - node *coord; - node *normal; - node *texCoord; - node *color; - std::vector coordIndex; - std::vector texCoordIndex; - std::vector normalIndex; - std::vector colorIndex; - -public: - // extract the geometry - void geometry(std::vector &triangles, - std::vector &geometry, - std::vector &normals, - std::vector &texcoords, - std::vector &colors) const; + VRMLLIB_NODE_CLASS(IndexedFaceSet) +public: + bool solid; + bool convex; + bool ccw; + bool normalPerVertex; + bool colorPerVertex; + node *coord; + node *normal; + node *texCoord; + node *color; + std::vector coordIndex; + std::vector texCoordIndex; + std::vector normalIndex; + std::vector colorIndex; + +public: + // extract the geometry + void geometry(std::vector &triangles, + std::vector &geometry, + std::vector &normals, + std::vector &texcoords, + std::vector &colors) const; }; class Coordinate : public node { - VRMLLIB_NODE_CLASS_ND(Coordinate) + VRMLLIB_NODE_CLASS_ND(Coordinate) public: - std::vector point; + std::vector point; }; class TextureCoordinate : public node { - VRMLLIB_NODE_CLASS_ND(TextureCoordinate) + VRMLLIB_NODE_CLASS_ND(TextureCoordinate) public: - std::vector point; + std::vector point; }; class Normal : public node { - VRMLLIB_NODE_CLASS_ND(Normal) + VRMLLIB_NODE_CLASS_ND(Normal) public: - std::vector vector; + std::vector vector; }; class Color : public node { - VRMLLIB_NODE_CLASS_ND(Color) + VRMLLIB_NODE_CLASS_ND(Color) public: - std::vector color; + std::vector color; }; class Box : public node { - VRMLLIB_NODE_CLASS_ND(Box) + VRMLLIB_NODE_CLASS_ND(Box) public: - vec3 size; + vec3 size; }; class Sphere : public node { - VRMLLIB_NODE_CLASS_ND(Sphere) + VRMLLIB_NODE_CLASS_ND(Sphere) public: - float radius; + float radius; }; class ImageTexture : public node { - VRMLLIB_NODE_CLASS(ImageTexture) + VRMLLIB_NODE_CLASS(ImageTexture) public: - std::vector url; - bool repeatS, repeatT; + std::vector url; + bool repeatS, repeatT; }; } // namespace vrmllib diff --git a/Tools/VRMLConverter/vrmllib/include/vrmllib/types.h b/Tools/VRMLConverter/vrmllib/include/vrmllib/types.h index 3e63cd7eefd..f2e7948c414 100644 --- a/Tools/VRMLConverter/vrmllib/include/vrmllib/types.h +++ b/Tools/VRMLConverter/vrmllib/include/vrmllib/types.h @@ -6,28 +6,28 @@ namespace vrmllib { struct vec2 { - float x, y; + float x, y; }; struct vec3 { - float x, y, z; - vec3() {} - vec3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) {} + float x, y, z; + vec3() {} + vec3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) {} }; struct col3 { - float r, g, b; - col3() {} - col3(float r_, float g_, float b_) : r(r_), g(g_), b(b_) {} + float r, g, b; + col3() {} + col3(float r_, float g_, float b_) : r(r_), g(g_), b(b_) {} }; class rot { public: - rot() : vector(0,0,1), radians(0) {} - rot(float x, float y, float z, float r) : vector(x,y,z), radians(r) {} + rot() : vector(0,0,1), radians(0) {} + rot(float x, float y, float z, float r) : vector(x,y,z), radians(r) {} - vec3 vector; - float radians; + vec3 vector; + float radians; }; } // namespace vrmllib diff --git a/Tools/VRMLConverter/vrmllib/include/vrmllib/types_bits.h b/Tools/VRMLConverter/vrmllib/include/vrmllib/types_bits.h index a44aa6ed118..91bdb8d5a50 100644 --- a/Tools/VRMLConverter/vrmllib/include/vrmllib/types_bits.h +++ b/Tools/VRMLConverter/vrmllib/include/vrmllib/types_bits.h @@ -20,35 +20,35 @@ void parse_value(std::string &, std::istream &, file &); void parse_value(rot &, std::istream &, file &); template void parse_value(T &v, std::istream &s, file &) - { s >> v; } + { s >> v; } template void parse_vector(std::vector &l, std::istream &s, - file &data) + file &data) { - char c; - s >> c; - if (c == '[') { - l.clear(); - T t; - while (s >> c) { - if (c == ']') - break; - else - s.putback(c); - - parse_value(t, s, data); - - l.push_back(t); - s >> c; - if (c != ',') - s.putback(c); - } - } else { - l.clear(); - l.push_back(T()); - s.putback(c); - parse_value(l.back(), s, data); - } + char c; + s >> c; + if (c == '[') { + l.clear(); + T t; + while (s >> c) { + if (c == ']') + break; + else + s.putback(c); + + parse_value(t, s, data); + + l.push_back(t); + s >> c; + if (c != ',') + s.putback(c); + } + } else { + l.clear(); + l.push_back(T()); + s.putback(c); + parse_value(l.back(), s, data); + } } } // namespace bits diff --git a/Tools/VRMLConverter/vrmllib/src/commentstream.cpp b/Tools/VRMLConverter/vrmllib/src/commentstream.cpp index fc0ad91d76f..ee12c152187 100644 --- a/Tools/VRMLConverter/vrmllib/src/commentstream.cpp +++ b/Tools/VRMLConverter/vrmllib/src/commentstream.cpp @@ -3,53 +3,53 @@ namespace utillib { class commentstreambuf : public std::streambuf { - std::streambuf * const m_sbuf; - char m_buf[512]; - const int m_start; - const int m_end; - bool m_comment; + std::streambuf * const m_sbuf; + char m_buf[512]; + const int m_start; + const int m_end; + bool m_comment; public: - commentstreambuf(std::streambuf *, char start, char end); + commentstreambuf(std::streambuf *, char start, char end); - int underflow(); + int underflow(); }; commentstreambuf::commentstreambuf(std::streambuf *sb, char start, char end) - : m_sbuf(sb), m_start(static_cast(start)), - m_end(static_cast(end)), m_comment(false) + : m_sbuf(sb), m_start(static_cast(start)), + m_end(static_cast(end)), m_comment(false) { - setg(m_buf, m_buf, m_buf); + setg(m_buf, m_buf, m_buf); } int commentstreambuf::underflow() { - char *p = m_buf; - int ch; - while (p != m_buf + sizeof m_buf && (ch = m_sbuf->sgetc()) != EOF) { - m_sbuf->sbumpc(); + char *p = m_buf; + int ch; + while (p != m_buf + sizeof m_buf && (ch = m_sbuf->sgetc()) != EOF) { + m_sbuf->sbumpc(); - if (ch == m_start) m_comment = true; - else if (ch == m_end) m_comment = false; + if (ch == m_start) m_comment = true; + else if (ch == m_end) m_comment = false; - if (!m_comment) - *p++ = ch; - } + if (!m_comment) + *p++ = ch; + } - if (p == m_buf) - return EOF; + if (p == m_buf) + return EOF; - setg(m_buf, m_buf, p); - return *m_buf; + setg(m_buf, m_buf, p); + return *m_buf; } commentstream::commentstream(std::istream &s, char start, char end) - : std::basic_istream(new commentstreambuf(s.rdbuf(), start, end)) + : std::basic_istream(new commentstreambuf(s.rdbuf(), start, end)) { } commentstream::~commentstream() { - delete rdbuf(); + delete rdbuf(); } } // namespace utillib diff --git a/Tools/VRMLConverter/vrmllib/src/commentstream.h b/Tools/VRMLConverter/vrmllib/src/commentstream.h index 79d8a36fc73..189496d1d51 100644 --- a/Tools/VRMLConverter/vrmllib/src/commentstream.h +++ b/Tools/VRMLConverter/vrmllib/src/commentstream.h @@ -11,9 +11,9 @@ namespace utillib { * character. */ class commentstream : public std::istream { public: - explicit commentstream(std::istream &, char start = '#', - char end = '\n'); - ~commentstream(); + explicit commentstream(std::istream &, char start = '#', + char end = '\n'); + ~commentstream(); }; } // namespace utillib diff --git a/Tools/VRMLConverter/vrmllib/src/file.cpp b/Tools/VRMLConverter/vrmllib/src/file.cpp index d5abaa4455f..241ff2026eb 100644 --- a/Tools/VRMLConverter/vrmllib/src/file.cpp +++ b/Tools/VRMLConverter/vrmllib/src/file.cpp @@ -12,74 +12,74 @@ namespace { void set_parent(std::vector &c, grouping_node *p) { - for (std::vector::iterator i=c.begin(); i!=c.end(); ++i) { - if (!*i) - continue; - (*i)->parent = p; - if (grouping_node *n = dynamic_cast(*i)) - set_parent(n->children, n); - } + for (std::vector::iterator i=c.begin(); i!=c.end(); ++i) { + if (!*i) + continue; + (*i)->parent = p; + if (grouping_node *n = dynamic_cast(*i)) + set_parent(n->children, n); + } } } // anonymous namespace file::file(std::istream &sarg) { - utillib::commentstream s(sarg, '#', '\n'); - std::ios::iostate exceptions = sarg.exceptions(); - sarg.exceptions(std::ios::goodbit); + utillib::commentstream s(sarg, '#', '\n'); + std::ios::iostate exceptions = sarg.exceptions(); + sarg.exceptions(std::ios::goodbit); - try { - for (;;) { - char t; - s >> t; - if (s) - s.putback(t); - else if (s.eof()) - break; - else - throw std::runtime_error( - "parse error: unexpected end of file"); + try { + for (;;) { + char t; + s >> t; + if (s) + s.putback(t); + else if (s.eof()) + break; + else + throw std::runtime_error( + "parse error: unexpected end of file"); - s.exceptions(std::ios::badbit - | std::ios::failbit - | std::ios::eofbit); + s.exceptions(std::ios::badbit + | std::ios::failbit + | std::ios::eofbit); - std::string word; - s >> word; + std::string word; + s >> word; - if (word == "ROUTE") { - s >> word; - s >> word; // TO - s >> word; - } else { - node *n = node::parse_node_xdef(s, *this, word); - if (n) - roots.push_back(n); - } - - s.exceptions(std::ios::goodbit); - } + if (word == "ROUTE") { + s >> word; + s >> word; // TO + s >> word; + } else { + node *n = node::parse_node_xdef(s, *this, word); + if (n) + roots.push_back(n); + } + + s.exceptions(std::ios::goodbit); + } - } catch (std::ios::failure &e) { - sarg.exceptions(exceptions); - throw std::runtime_error(std::string("parse error: stream failure: ") + e.what()); - } catch (...) { - sarg.exceptions(exceptions); - throw; - } - sarg.exceptions(exceptions); + } catch (std::ios::failure &e) { + sarg.exceptions(exceptions); + throw std::runtime_error(std::string("parse error: stream failure: ") + e.what()); + } catch (...) { + sarg.exceptions(exceptions); + throw; + } + sarg.exceptions(exceptions); - set_parent(roots, 0); + set_parent(roots, 0); } namespace { - inline void delnode(node *n) { delete n; } + inline void delnode(node *n) { delete n; } } file::~file() { - std::for_each(nodes.begin(), nodes.end(), delnode); + std::for_each(nodes.begin(), nodes.end(), delnode); } } // namespace vrmllib diff --git a/Tools/VRMLConverter/vrmllib/src/indexed_face_set.cpp b/Tools/VRMLConverter/vrmllib/src/indexed_face_set.cpp index 60eac107657..8711e1296b5 100644 --- a/Tools/VRMLConverter/vrmllib/src/indexed_face_set.cpp +++ b/Tools/VRMLConverter/vrmllib/src/indexed_face_set.cpp @@ -7,22 +7,22 @@ namespace vrmllib { namespace bits { struct index_set { - index_set() : geom(0), tex(0), norm(0), col(0) {} - int geom; - int tex; - int norm; - int col; + index_set() : geom(0), tex(0), norm(0), col(0) {} + int geom; + int tex; + int norm; + int col; }; bool operator<(const index_set &a, const index_set &b) { - if (a.geom < b.geom) return true; - if (a.geom > b.geom) return false; - if (a.tex < b.tex) return true; - if (a.tex > b.tex) return false; - if (a.norm < b.norm) return true; - if (a.norm > b.norm) return false; - return a.col < b.col; + if (a.geom < b.geom) return true; + if (a.geom > b.geom) return false; + if (a.tex < b.tex) return true; + if (a.tex > b.tex) return false; + if (a.norm < b.norm) return true; + if (a.norm > b.norm) return false; + return a.col < b.col; } } // namespace bits @@ -34,125 +34,125 @@ using std::map; using std::runtime_error; void IndexedFaceSet::geometry(vector &triangles, - vector &geometry, vector &normals, - vector &texcoords, vector &colors) const + vector &geometry, vector &normals, + vector &texcoords, vector &colors) const { - std::map index_map; - vector final_indices; - - Coordinate *coord = dynamic_cast(this->coord); - if (!coord) throw runtime_error("no coordinates for indexed face set"); - - TextureCoordinate *texCoord = - dynamic_cast(this->texCoord); - Normal *normal = dynamic_cast(this->normal); - Color *color = dynamic_cast(this->color); - - int colcase = 0; - if (color) { - colcase += colorIndex.empty() ? 2 : 1; - colcase += colorPerVertex ? 2 : 0; - } - int normcase = 0; - if (normal) { - normcase += normalIndex.empty() ? 2 : 1; - normcase += normalPerVertex ? 2 : 0; - } - - // map vrml index tuples to vertices and output indices - triangles.clear(); - int facenum = 0, num_in_face = 0; - for (unsigned i=0; i!=coordIndex.size(); ++i) { - if (coordIndex[i] == -1) { - if (num_in_face != 3) - throw runtime_error( - "polygon is not a triangle"); - num_in_face = 0; - ++facenum; - continue; - } else - ++num_in_face; - - index_set is; - is.geom = coordIndex[i]; - if (texCoord) { - if (!texCoordIndex.empty()) - is.tex = texCoordIndex[i]; - else - is.tex = coordIndex[i]; - } - switch (colcase) { - case 1: // !perVertex, !colorIndex.empty - is.col = colorIndex[facenum]; - break; - case 2: // !perVertex, colorIndex.empty - is.col = facenum; - break; - case 3: // perVertex, !colorIndex.empty - is.col = colorIndex[i]; - break; - case 4: // perVertex, colorIndex.empty - is.col = coordIndex[i]; - break; - }; - switch (normcase) { - case 1: // !perVertex, !normalIndex.empty - is.norm = normalIndex[facenum]; - break; - case 2: // !perVertex, normalIndex.empty - is.norm = facenum; - break; - case 3: // perVertex, !normalIndex.empty - is.norm = normalIndex[i]; - break; - case 4: // perVertex, normalIndex.empty - is.norm = coordIndex[i]; - break; - }; - - if (final_indices.empty()) { - index_map[is] = 0; - final_indices.push_back(is); - triangles.push_back(0); - } else { - map::iterator i - = index_map.find(is); - if (i == index_map.end()) { - index_map[is] = final_indices.size(); - triangles.push_back(final_indices.size()); - final_indices.push_back(is); - } else - triangles.push_back(i->second); - } - } - - // generate attributes - geometry.resize(final_indices.size()); - for (unsigned i=0; i!=final_indices.size(); ++i) - geometry[i] = coord->point[final_indices[i].geom]; - if (normal) { - normals.resize(final_indices.size()); - for (unsigned i=0; i!=final_indices.size(); ++i) - normals[i] = normal->vector[final_indices[i].norm]; - } else - normals.clear(); - if (texCoord) { - texcoords.resize(final_indices.size()); - for (unsigned i=0; i!=final_indices.size(); ++i) - texcoords[i] = texCoord->point[final_indices[i].tex]; - } else - texcoords.clear(); - if (color) { - colors.resize(final_indices.size()); - for (unsigned i=0; i!=final_indices.size(); ++i) - colors[i] = color->color[final_indices[i].col]; - } else - colors.clear(); - - // convert to ccw - if (!ccw) - for (unsigned i=0; i!=triangles.size(); i+=3) - std::swap(triangles[i+1], triangles[i+2]); + std::map index_map; + vector final_indices; + + Coordinate *coord = dynamic_cast(this->coord); + if (!coord) throw runtime_error("no coordinates for indexed face set"); + + TextureCoordinate *texCoord = + dynamic_cast(this->texCoord); + Normal *normal = dynamic_cast(this->normal); + Color *color = dynamic_cast(this->color); + + int colcase = 0; + if (color) { + colcase += colorIndex.empty() ? 2 : 1; + colcase += colorPerVertex ? 2 : 0; + } + int normcase = 0; + if (normal) { + normcase += normalIndex.empty() ? 2 : 1; + normcase += normalPerVertex ? 2 : 0; + } + + // map vrml index tuples to vertices and output indices + triangles.clear(); + int facenum = 0, num_in_face = 0; + for (unsigned i=0; i!=coordIndex.size(); ++i) { + if (coordIndex[i] == -1) { + if (num_in_face != 3) + throw runtime_error( + "polygon is not a triangle"); + num_in_face = 0; + ++facenum; + continue; + } else + ++num_in_face; + + index_set is; + is.geom = coordIndex[i]; + if (texCoord) { + if (!texCoordIndex.empty()) + is.tex = texCoordIndex[i]; + else + is.tex = coordIndex[i]; + } + switch (colcase) { + case 1: // !perVertex, !colorIndex.empty + is.col = colorIndex[facenum]; + break; + case 2: // !perVertex, colorIndex.empty + is.col = facenum; + break; + case 3: // perVertex, !colorIndex.empty + is.col = colorIndex[i]; + break; + case 4: // perVertex, colorIndex.empty + is.col = coordIndex[i]; + break; + }; + switch (normcase) { + case 1: // !perVertex, !normalIndex.empty + is.norm = normalIndex[facenum]; + break; + case 2: // !perVertex, normalIndex.empty + is.norm = facenum; + break; + case 3: // perVertex, !normalIndex.empty + is.norm = normalIndex[i]; + break; + case 4: // perVertex, normalIndex.empty + is.norm = coordIndex[i]; + break; + }; + + if (final_indices.empty()) { + index_map[is] = 0; + final_indices.push_back(is); + triangles.push_back(0); + } else { + map::iterator i + = index_map.find(is); + if (i == index_map.end()) { + index_map[is] = final_indices.size(); + triangles.push_back(final_indices.size()); + final_indices.push_back(is); + } else + triangles.push_back(i->second); + } + } + + // generate attributes + geometry.resize(final_indices.size()); + for (unsigned i=0; i!=final_indices.size(); ++i) + geometry[i] = coord->point[final_indices[i].geom]; + if (normal) { + normals.resize(final_indices.size()); + for (unsigned i=0; i!=final_indices.size(); ++i) + normals[i] = normal->vector[final_indices[i].norm]; + } else + normals.clear(); + if (texCoord) { + texcoords.resize(final_indices.size()); + for (unsigned i=0; i!=final_indices.size(); ++i) + texcoords[i] = texCoord->point[final_indices[i].tex]; + } else + texcoords.clear(); + if (color) { + colors.resize(final_indices.size()); + for (unsigned i=0; i!=final_indices.size(); ++i) + colors[i] = color->color[final_indices[i].col]; + } else + colors.clear(); + + // convert to ccw + if (!ccw) + for (unsigned i=0; i!=triangles.size(); i+=3) + std::swap(triangles[i+1], triangles[i+2]); } } // namespace vrmllib diff --git a/Tools/VRMLConverter/vrmllib/src/node.cpp b/Tools/VRMLConverter/vrmllib/src/node.cpp index 1f3badae06c..c768bd77b0c 100644 --- a/Tools/VRMLConverter/vrmllib/src/node.cpp +++ b/Tools/VRMLConverter/vrmllib/src/node.cpp @@ -10,11 +10,11 @@ namespace bits { void parse_value(node *&n, std::istream &s, file &data) { - std::string word; - s >> word; - if (!s) - throw std::runtime_error("parse error: end of file wile reading node"); - n = node::parse_node_xdef(s, data, word); + std::string word; + s >> word; + if (!s) + throw std::runtime_error("parse error: end of file wile reading node"); + n = node::parse_node_xdef(s, data, word); } } // namespace bits @@ -25,101 +25,101 @@ node::~node() void node::parse_attribute(const std::string &name, std::istream &s, file &data) { - std::cerr << "unknown attribute: " << name << std::endl; - std::string val; - s >> val; - if (!s) - throw std::runtime_error("parse error: end of file while reading unknown attribute"); - if (val == "[") { - char c = 0; - int depth = 1; - s >> c; - while (depth != 0) { - if (!(s >> c)) - throw std::runtime_error("parse error: end of file while scanning for end of unknown attribute"); - if (c == '[') - ++depth; - else if (c == ']') - --depth; - } - } else if (val == "TRUE" || val == "FALSE" || val[0] == '-' || isdigit(val[0])) { - char c; - while (s.get(c) && c != '\n' && c != '\r') - ; - if (!s) - throw std::runtime_error("parse error: end of file while scanning for end of line"); - } else { - parse_node_xdef(s, data, val); - } + std::cerr << "unknown attribute: " << name << std::endl; + std::string val; + s >> val; + if (!s) + throw std::runtime_error("parse error: end of file while reading unknown attribute"); + if (val == "[") { + char c = 0; + int depth = 1; + s >> c; + while (depth != 0) { + if (!(s >> c)) + throw std::runtime_error("parse error: end of file while scanning for end of unknown attribute"); + if (c == '[') + ++depth; + else if (c == ']') + --depth; + } + } else if (val == "TRUE" || val == "FALSE" || val[0] == '-' || isdigit(val[0])) { + char c; + while (s.get(c) && c != '\n' && c != '\r') + ; + if (!s) + throw std::runtime_error("parse error: end of file while scanning for end of line"); + } else { + parse_node_xdef(s, data, val); + } } node *node::parse_node(std::istream &s, file &data, - const std::string &type) + const std::string &type) { - node *n = create_node(type); - if (!n) { - char c = 0; - int depth = 1; - s >> c; - if (c != '{') - throw std::runtime_error( - std::string("parse error: expected {, got: ") + c); - while (depth != 0) { - if (!(s >> c)) - throw std::runtime_error("parse error: end of file while scanning for end of unknown node"); - if (c == '{') - ++depth; - else if (c == '}') - --depth; - } - return 0; - } - data.nodes.push_back(n); + node *n = create_node(type); + if (!n) { + char c = 0; + int depth = 1; + s >> c; + if (c != '{') + throw std::runtime_error( + std::string("parse error: expected {, got: ") + c); + while (depth != 0) { + if (!(s >> c)) + throw std::runtime_error("parse error: end of file while scanning for end of unknown node"); + if (c == '{') + ++depth; + else if (c == '}') + --depth; + } + return 0; + } + data.nodes.push_back(n); - char c; - s >> c; - if (c != '{') - throw std::runtime_error( - std::string("parse error: expected {, got: ") + c); + char c; + s >> c; + if (c != '{') + throw std::runtime_error( + std::string("parse error: expected {, got: ") + c); - std::string str; - for (;;) { - s >> c; - if (c == '}') - break; - else - s.putback(c); + std::string str; + for (;;) { + s >> c; + if (c == '}') + break; + else + s.putback(c); - s >> str; - n->parse_attribute(str, s, data); - } + s >> str; + n->parse_attribute(str, s, data); + } - return n; + return n; } node *node::parse_node_xdef(std::istream &s, file &data, const std::string &fword) { - if (fword == "DEF") { - std::string word; - s >> word; - std::string name = word; - s >> word; - node *n = parse_node(s, data, word); - node *&dest = data.defs[name]; - if (dest) - throw std::runtime_error( - "parse error: node already defined: " + name); - return dest = n; - } else if (fword == "USE") { - std::string word; - s >> word; - if (node *n = data.defs[word]) - return n; - else - throw std::runtime_error( - "parse error: node is not defined: " + word); - } else - return parse_node(s, data, fword); + if (fword == "DEF") { + std::string word; + s >> word; + std::string name = word; + s >> word; + node *n = parse_node(s, data, word); + node *&dest = data.defs[name]; + if (dest) + throw std::runtime_error( + "parse error: node already defined: " + name); + return dest = n; + } else if (fword == "USE") { + std::string word; + s >> word; + if (node *n = data.defs[word]) + return n; + else + throw std::runtime_error( + "parse error: node is not defined: " + word); + } else + return parse_node(s, data, fword); } } // namespace vrmllib diff --git a/Tools/VRMLConverter/vrmllib/src/nodes.cpp b/Tools/VRMLConverter/vrmllib/src/nodes.cpp index efeb5b64c7d..beaa18f67c9 100644 --- a/Tools/VRMLConverter/vrmllib/src/nodes.cpp +++ b/Tools/VRMLConverter/vrmllib/src/nodes.cpp @@ -6,39 +6,39 @@ #include #define BEGIN_NODE(type) \ - namespace {\ - node_creator register_##type##_creator(#type); \ - } \ - void type::parse_attribute(const std::string &a_name, \ - std::istream &a_stream, file &a_data) \ - { + namespace {\ + node_creator register_##type##_creator(#type); \ + } \ + void type::parse_attribute(const std::string &a_name, \ + std::istream &a_stream, file &a_data) \ + { #define ATTR(d_var) \ - if (a_name == #d_var) { \ - using namespace bits; \ - return parse_value(d_var, a_stream, a_data); \ - } + if (a_name == #d_var) { \ + using namespace bits; \ + return parse_value(d_var, a_stream, a_data); \ + } #define VATTR(d_var) \ - if (a_name == #d_var) { \ - using namespace bits; \ - return parse_vector(d_var, a_stream, a_data); \ - } + if (a_name == #d_var) { \ + using namespace bits; \ + return parse_vector(d_var, a_stream, a_data); \ + } #define END_NODE \ - base_type::parse_attribute(a_name, a_stream, a_data); \ - } + base_type::parse_attribute(a_name, a_stream, a_data); \ + } #define BEGIN_DEFAULTS(type) \ - type::type() : + type::type() : #define END_DEFAULTS \ - {} + {} namespace vrmllib { namespace bits { class node_creator_base { public: - virtual ~node_creator_base() {} - virtual node *create() = 0; + virtual ~node_creator_base() {} + virtual node *create() = 0; }; std::map g_node_creators; @@ -46,8 +46,8 @@ std::map g_node_creators; template class node_creator : public node_creator_base { public: - node_creator(const char *type) { g_node_creators[type] = this; } - node *create() { return new Type; } + node_creator(const char *type) { g_node_creators[type] = this; } + node *create() { return new Type; } }; } // namespace bits @@ -56,153 +56,153 @@ using namespace bits; node *node::create_node(const std::string &type) { - node_creator_base *c = g_node_creators[type]; - - if (c) - return c->create(); - else { - std::cerr << "unknown type: " << type << std::endl; - return 0; - } + node_creator_base *c = g_node_creators[type]; + + if (c) + return c->create(); + else { + std::cerr << "unknown type: " << type << std::endl; + return 0; + } } BEGIN_NODE(grouping_node) - VATTR(children) + VATTR(children) END_NODE BEGIN_DEFAULTS(Transform) - translation(0,0,0), - center(0,0,0), - scale(1,1,1) + translation(0,0,0), + center(0,0,0), + scale(1,1,1) END_DEFAULTS BEGIN_NODE(Transform) - ATTR(translation) - ATTR(rotation) - ATTR(center) - ATTR(scale) - ATTR(scaleOrientation) + ATTR(translation) + ATTR(rotation) + ATTR(center) + ATTR(scale) + ATTR(scaleOrientation) END_NODE BEGIN_NODE(Group) END_NODE BEGIN_DEFAULTS(Shape) - appearance(0), - geometry(0) + appearance(0), + geometry(0) END_DEFAULTS BEGIN_NODE(Shape) - ATTR(appearance) - ATTR(geometry) + ATTR(appearance) + ATTR(geometry) END_NODE BEGIN_DEFAULTS(Switch) - whichChoice(0) + whichChoice(0) END_DEFAULTS BEGIN_NODE(Switch) - VATTR(choice) - ATTR(whichChoice) + VATTR(choice) + ATTR(whichChoice) END_NODE BEGIN_DEFAULTS(Viewpoint) - fieldOfView(0.785398), - position(0,0,10) + fieldOfView(0.785398), + position(0,0,10) END_DEFAULTS BEGIN_NODE(Viewpoint) - ATTR(fieldOfView) - ATTR(orientation) - ATTR(position) - ATTR(description) + ATTR(fieldOfView) + ATTR(orientation) + ATTR(position) + ATTR(description) END_NODE BEGIN_DEFAULTS(Appearance) - material(0), - texture(0) + material(0), + texture(0) END_DEFAULTS BEGIN_NODE(Appearance) - ATTR(material) - ATTR(texture) + ATTR(material) + ATTR(texture) END_NODE BEGIN_NODE(WorldInfo) - ATTR(title) - VATTR(info) + ATTR(title) + VATTR(info) END_NODE BEGIN_DEFAULTS(Material) - diffuseColor(204,204,204), - specularColor(0,0,0), - emissiveColor(0,0,0), - ambientIntensity(0.2), - shininess(0.2), - transparency(0) + diffuseColor(204,204,204), + specularColor(0,0,0), + emissiveColor(0,0,0), + ambientIntensity(0.2), + shininess(0.2), + transparency(0) END_DEFAULTS BEGIN_NODE(Material) - ATTR(diffuseColor) - ATTR(specularColor) - ATTR(emissiveColor) - ATTR(ambientIntensity) - ATTR(shininess) - ATTR(transparency) + ATTR(diffuseColor) + ATTR(specularColor) + ATTR(emissiveColor) + ATTR(ambientIntensity) + ATTR(shininess) + ATTR(transparency) END_NODE BEGIN_DEFAULTS(IndexedFaceSet) - solid(true), - convex(true), - ccw(true), - normalPerVertex(true), - colorPerVertex(true), - coord(0), - normal(0), - texCoord(0), - color(0) + solid(true), + convex(true), + ccw(true), + normalPerVertex(true), + colorPerVertex(true), + coord(0), + normal(0), + texCoord(0), + color(0) END_DEFAULTS BEGIN_NODE(IndexedFaceSet) - ATTR(solid) - ATTR(convex) - ATTR(ccw) - ATTR(normalPerVertex) - ATTR(colorPerVertex) - ATTR(coord) - ATTR(color) - ATTR(normal) - ATTR(texCoord) - VATTR(coordIndex) - VATTR(texCoordIndex) - VATTR(normalIndex) - VATTR(colorIndex) + ATTR(solid) + ATTR(convex) + ATTR(ccw) + ATTR(normalPerVertex) + ATTR(colorPerVertex) + ATTR(coord) + ATTR(color) + ATTR(normal) + ATTR(texCoord) + VATTR(coordIndex) + VATTR(texCoordIndex) + VATTR(normalIndex) + VATTR(colorIndex) END_NODE BEGIN_NODE(Coordinate) - VATTR(point) + VATTR(point) END_NODE BEGIN_NODE(Color) - VATTR(color) + VATTR(color) END_NODE BEGIN_NODE(Box) - ATTR(size) + ATTR(size) END_NODE BEGIN_NODE(Sphere) - ATTR(radius) + ATTR(radius) END_NODE BEGIN_NODE(TextureCoordinate) - VATTR(point) + VATTR(point) END_NODE BEGIN_NODE(Normal) - VATTR(vector) + VATTR(vector) END_NODE BEGIN_DEFAULTS(ImageTexture) - repeatS(true), repeatT(true) + repeatS(true), repeatT(true) END_DEFAULTS BEGIN_NODE(ImageTexture) - VATTR(url) - ATTR(repeatS) - ATTR(repeatT) + VATTR(url) + ATTR(repeatS) + ATTR(repeatT) END_NODE } // namespace vrmllib diff --git a/Tools/VRMLConverter/vrmllib/src/types.cpp b/Tools/VRMLConverter/vrmllib/src/types.cpp index 5c18caa401a..b15e5a40bec 100644 --- a/Tools/VRMLConverter/vrmllib/src/types.cpp +++ b/Tools/VRMLConverter/vrmllib/src/types.cpp @@ -5,53 +5,53 @@ namespace bits { void parse_value(bool &b, std::istream &s, file &) { - std::string t; - s >> t; - if (t == "TRUE") - b = true; - else if (t == "FALSE") - b = false; - else - throw std::runtime_error("parse error: expected TRUE or FALSE, got: " + t); + std::string t; + s >> t; + if (t == "TRUE") + b = true; + else if (t == "FALSE") + b = false; + else + throw std::runtime_error("parse error: expected TRUE or FALSE, got: " + t); } void parse_value(std::string &str, std::istream &s, file &) { - char c = 0; - s >> c; - - if (c != '"') { - s.putback(c); - throw std::runtime_error(std::string("expected start of string (\"), got: ") + c); - } - str.erase(); - c = 0; - while (s.get(c) && c != '"') str += c; - - if (c != '"') { - throw std::runtime_error(std::string("expected end of string (\"), got: ") + c); - } + char c = 0; + s >> c; + + if (c != '"') { + s.putback(c); + throw std::runtime_error(std::string("expected start of string (\"), got: ") + c); + } + str.erase(); + c = 0; + while (s.get(c) && c != '"') str += c; + + if (c != '"') { + throw std::runtime_error(std::string("expected end of string (\"), got: ") + c); + } } void parse_value(vec3 &v, std::istream &s, file &) { - s >> v.x >> v.y >> v.z; + s >> v.x >> v.y >> v.z; } void parse_value(col3 &v, std::istream &s, file &) { - s >> v.r >> v.g >> v.b; + s >> v.r >> v.g >> v.b; } void parse_value(vec2 &v, std::istream &s, file &) { - s >> v.x >> v.y; + s >> v.x >> v.y; } void parse_value(rot &r, std::istream &s, file &f) { - parse_value(r.vector, s, f); - s >> r.radians; + parse_value(r.vector, s, f); + s >> r.radians; } } // namespace bits diff --git a/Tools/XMLConverter/include/OgreXMLMeshSerializer.h b/Tools/XMLConverter/include/OgreXMLMeshSerializer.h index 2d30b9e9afe..e32687bb9a9 100644 --- a/Tools/XMLConverter/include/OgreXMLMeshSerializer.h +++ b/Tools/XMLConverter/include/OgreXMLMeshSerializer.h @@ -54,7 +54,7 @@ namespace Ogre { virtual ~XMLMeshSerializer(); /** Imports a Mesh from the given XML file. @param filename The name of the file to import, expected to be in XML format. - @param colourElementType The vertex element to use for packed colours + @param colourElementType The vertex element to use for packed colours @param pMesh The pre-created Mesh object to be populated. */ void importMesh(const String& filename, VertexElementType colourElementType, Mesh* pMesh); @@ -67,7 +67,7 @@ namespace Ogre { TiXmlDocument* mXMLDoc; // State for import Mesh* mMesh; - VertexElementType mColourElementType; + VertexElementType mColourElementType; // Internal methods void writeMesh(const Mesh* pMesh); @@ -76,16 +76,16 @@ namespace Ogre { void writeSkeletonLink(TiXmlElement* mMeshNode, const String& skelName); void writeBoneAssignment(TiXmlElement* mBoneAssignNode, const VertexBoneAssignment* assign); void writeTextureAliases(TiXmlElement* mSubmeshesNode, const SubMesh* s); - void writeLodInfo(TiXmlElement* mMeshNode, const Mesh* pMesh); - void writeLodUsageManual(TiXmlElement* usageNode, unsigned short levelNum, - const MeshLodUsage& usage); - void writeLodUsageGenerated(TiXmlElement* usageNode, unsigned short levelNum, - const MeshLodUsage& usage, const Mesh* pMesh); + void writeLodInfo(TiXmlElement* mMeshNode, const Mesh* pMesh); + void writeLodUsageManual(TiXmlElement* usageNode, unsigned short levelNum, + const MeshLodUsage& usage); + void writeLodUsageGenerated(TiXmlElement* usageNode, unsigned short levelNum, + const MeshLodUsage& usage, const Mesh* pMesh); void writeSubMeshNames(TiXmlElement* mMeshNode, const Mesh* m); - void writePoses(TiXmlElement* meshNode, const Mesh* m); - void writeAnimations(TiXmlElement* meshNode, const Mesh* m); - void writeMorphKeyFrames(TiXmlElement* trackNode, const VertexAnimationTrack* track); - void writePoseKeyFrames(TiXmlElement* trackNode, const VertexAnimationTrack* track); + void writePoses(TiXmlElement* meshNode, const Mesh* m); + void writeAnimations(TiXmlElement* meshNode, const Mesh* m); + void writeMorphKeyFrames(TiXmlElement* trackNode, const VertexAnimationTrack* track); + void writePoseKeyFrames(TiXmlElement* trackNode, const VertexAnimationTrack* track); void writeExtremes(TiXmlElement* mMeshNode, const Mesh* m); void readSubMeshes(TiXmlElement* mSubmeshesNode); @@ -94,16 +94,16 @@ namespace Ogre { void readBoneAssignments(TiXmlElement* mBoneAssignmentsNode); void readBoneAssignments(TiXmlElement* mBoneAssignmentsNode, SubMesh* sm); void readTextureAliases(TiXmlElement* mTextureAliasesNode, SubMesh* sm); - void readLodInfo(TiXmlElement* lodNode); - void readLodUsageManual(TiXmlElement* manualNode, unsigned short index); - void readLodUsageGenerated(TiXmlElement* genNode, unsigned short index); - void readSubMeshNames(TiXmlElement* mMeshNamesNode, Mesh* sm); - void readPoses(TiXmlElement* posesNode, Mesh *m); - void readAnimations(TiXmlElement* mAnimationsNode, Mesh *m); - void readTracks(TiXmlElement* tracksNode, Mesh *m, Animation* anim); - void readMorphKeyFrames(TiXmlElement* keyframesNode, VertexAnimationTrack* track, - size_t vertexCount); - void readPoseKeyFrames(TiXmlElement* keyframesNode, VertexAnimationTrack* track); + void readLodInfo(TiXmlElement* lodNode); + void readLodUsageManual(TiXmlElement* manualNode, unsigned short index); + void readLodUsageGenerated(TiXmlElement* genNode, unsigned short index); + void readSubMeshNames(TiXmlElement* mMeshNamesNode, Mesh* sm); + void readPoses(TiXmlElement* posesNode, Mesh *m); + void readAnimations(TiXmlElement* mAnimationsNode, Mesh *m); + void readTracks(TiXmlElement* tracksNode, Mesh *m, Animation* anim); + void readMorphKeyFrames(TiXmlElement* keyframesNode, VertexAnimationTrack* track, + size_t vertexCount); + void readPoseKeyFrames(TiXmlElement* keyframesNode, VertexAnimationTrack* track); void readExtremes(TiXmlElement* extremesNode, Mesh *m); }; } diff --git a/Tools/XMLConverter/include/OgreXMLSkeletonSerializer.h b/Tools/XMLConverter/include/OgreXMLSkeletonSerializer.h index e85c1dd3758..910f45cfcad 100644 --- a/Tools/XMLConverter/include/OgreXMLSkeletonSerializer.h +++ b/Tools/XMLConverter/include/OgreXMLSkeletonSerializer.h @@ -71,17 +71,17 @@ namespace Ogre { void writeBoneParent(TiXmlElement* boneHierarchyNode, String boneName , String parentName); void writeAnimation(TiXmlElement* animsNode, const Animation* anim); void writeAnimationTrack(TiXmlElement* tracksNode, - const NodeAnimationTrack* track); + const NodeAnimationTrack* track); void writeKeyFrame(TiXmlElement* keysNode, const TransformKeyFrame* key); - void writeSkeletonAnimationLink(TiXmlElement* linksNode, - const LinkedSkeletonAnimationSource& link); - - void readBones(Skeleton* skel, TiXmlElement* mBonesNode); - void readBones2(Skeleton* skel, TiXmlElement* mBonesNode); - void createHierarchy(Skeleton* skel, TiXmlElement* mHierNode); - void readKeyFrames(NodeAnimationTrack* track, TiXmlElement* mKeyfNode); - void readAnimations(Skeleton* skel, TiXmlElement* mAnimNode) ; - void readSkeletonAnimationLinks(Skeleton* skel, TiXmlElement* linksNode); + void writeSkeletonAnimationLink(TiXmlElement* linksNode, + const LinkedSkeletonAnimationSource& link); + + void readBones(Skeleton* skel, TiXmlElement* mBonesNode); + void readBones2(Skeleton* skel, TiXmlElement* mBonesNode); + void createHierarchy(Skeleton* skel, TiXmlElement* mHierNode); + void readKeyFrames(NodeAnimationTrack* track, TiXmlElement* mKeyfNode); + void readAnimations(Skeleton* skel, TiXmlElement* mAnimNode) ; + void readSkeletonAnimationLinks(Skeleton* skel, TiXmlElement* linksNode); }; diff --git a/Tools/XMLConverter/include/tinystr.h b/Tools/XMLConverter/include/tinystr.h index 3c2aa9d54da..93a543a0615 100644 --- a/Tools/XMLConverter/include/tinystr.h +++ b/Tools/XMLConverter/include/tinystr.h @@ -42,18 +42,18 @@ distribution. #include #include -/* The support for explicit isn't that universal, and it isn't really - required - it is used to check that the TiXmlString class isn't incorrectly - used. Be nice to old compilers and macro it here: +/* The support for explicit isn't that universal, and it isn't really + required - it is used to check that the TiXmlString class isn't incorrectly + used. Be nice to old compilers and macro it here: */ #if defined(_MSC_VER) && (_MSC_VER >= 1200 ) - // Microsoft visual studio, version 6 and higher. - #define TIXML_EXPLICIT explicit + // Microsoft visual studio, version 6 and higher. + #define TIXML_EXPLICIT explicit #elif defined(__GNUC__) && (__GNUC__ >= 3 ) - // GCC version 3 and higher.s - #define TIXML_EXPLICIT explicit + // GCC version 3 and higher.s + #define TIXML_EXPLICIT explicit #else - #define TIXML_EXPLICIT + #define TIXML_EXPLICIT #endif @@ -67,213 +67,213 @@ distribution. class TiXmlString { public : - // The size type used - typedef size_t size_type; - - // Error value for find primitive - static const size_type npos; // = -1; - - - // TiXmlString empty constructor - TiXmlString () : rep_(&nullrep_) - { - } - - // TiXmlString copy constructor - TiXmlString ( const TiXmlString & copy) : rep_(0) - { - init(copy.length()); - memcpy(start(), copy.data(), length()); - } - - // TiXmlString constructor, based on a string - TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) - { - init( static_cast( strlen(copy) )); - memcpy(start(), copy, length()); - } - - // TiXmlString constructor, based on a string - TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) - { - init(len); - memcpy(start(), str, len); - } - - // TiXmlString destructor - ~TiXmlString () - { - quit(); - } - - // = operator - TiXmlString& operator = (const char * copy) - { - return assign( copy, (size_type)strlen(copy)); - } - - // = operator - TiXmlString& operator = (const TiXmlString & copy) - { - return assign(copy.start(), copy.length()); - } - - - // += operator. Maps to append - TiXmlString& operator += (const char * suffix) - { - return append(suffix, static_cast( strlen(suffix) )); - } - - // += operator. Maps to append - TiXmlString& operator += (char single) - { - return append(&single, 1); - } - - // += operator. Maps to append - TiXmlString& operator += (const TiXmlString & suffix) - { - return append(suffix.data(), suffix.length()); - } - - - // Convert a TiXmlString into a null-terminated char * - const char * c_str () const { return rep_->str; } - - // Convert a TiXmlString into a char * (need not be null terminated). - const char * data () const { return rep_->str; } - - // Return the length of a TiXmlString - size_type length () const { return rep_->size; } - - // Alias for length() - size_type size () const { return rep_->size; } - - // Checks if a TiXmlString is empty - bool empty () const { return rep_->size == 0; } - - // Return capacity of string - size_type capacity () const { return rep_->capacity; } - - - // single char extraction - const char& at (size_type index) const - { - assert( index < length() ); - return rep_->str[ index ]; - } - - // [] operator - char& operator [] (size_type index) const - { - assert( index < length() ); - return rep_->str[ index ]; - } - - // find a char in a string. Return TiXmlString::npos if not found - size_type find (char lookup) const - { - return find(lookup, 0); - } - - // find a char in a string from an offset. Return TiXmlString::npos if not found - size_type find (char tofind, size_type offset) const - { - if (offset >= length()) return npos; - - for (const char* p = c_str() + offset; *p != '\0'; ++p) - { - if (*p == tofind) return static_cast< size_type >( p - c_str() ); - } - return npos; - } - - void clear () - { - //Lee: - //The original was just too strange, though correct: - // TiXmlString().swap(*this); - //Instead use the quit & re-init: - quit(); - init(0,0); - } - - /* Function to reserve a big amount of data when we know we'll need it. Be aware that this - function DOES NOT clear the content of the TiXmlString if any exists. - */ - void reserve (size_type cap); - - TiXmlString& assign (const char* str, size_type len); - - TiXmlString& append (const char* str, size_type len); - - void swap (TiXmlString& other) - { - Rep* r = rep_; - rep_ = other.rep_; - other.rep_ = r; - } + // The size type used + typedef size_t size_type; + + // Error value for find primitive + static const size_type npos; // = -1; + + + // TiXmlString empty constructor + TiXmlString () : rep_(&nullrep_) + { + } + + // TiXmlString copy constructor + TiXmlString ( const TiXmlString & copy) : rep_(0) + { + init(copy.length()); + memcpy(start(), copy.data(), length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) + { + init( static_cast( strlen(copy) )); + memcpy(start(), copy, length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) + { + init(len); + memcpy(start(), str, len); + } + + // TiXmlString destructor + ~TiXmlString () + { + quit(); + } + + // = operator + TiXmlString& operator = (const char * copy) + { + return assign( copy, (size_type)strlen(copy)); + } + + // = operator + TiXmlString& operator = (const TiXmlString & copy) + { + return assign(copy.start(), copy.length()); + } + + + // += operator. Maps to append + TiXmlString& operator += (const char * suffix) + { + return append(suffix, static_cast( strlen(suffix) )); + } + + // += operator. Maps to append + TiXmlString& operator += (char single) + { + return append(&single, 1); + } + + // += operator. Maps to append + TiXmlString& operator += (const TiXmlString & suffix) + { + return append(suffix.data(), suffix.length()); + } + + + // Convert a TiXmlString into a null-terminated char * + const char * c_str () const { return rep_->str; } + + // Convert a TiXmlString into a char * (need not be null terminated). + const char * data () const { return rep_->str; } + + // Return the length of a TiXmlString + size_type length () const { return rep_->size; } + + // Alias for length() + size_type size () const { return rep_->size; } + + // Checks if a TiXmlString is empty + bool empty () const { return rep_->size == 0; } + + // Return capacity of string + size_type capacity () const { return rep_->capacity; } + + + // single char extraction + const char& at (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // [] operator + char& operator [] (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // find a char in a string. Return TiXmlString::npos if not found + size_type find (char lookup) const + { + return find(lookup, 0); + } + + // find a char in a string from an offset. Return TiXmlString::npos if not found + size_type find (char tofind, size_type offset) const + { + if (offset >= length()) return npos; + + for (const char* p = c_str() + offset; *p != '\0'; ++p) + { + if (*p == tofind) return static_cast< size_type >( p - c_str() ); + } + return npos; + } + + void clear () + { + //Lee: + //The original was just too strange, though correct: + // TiXmlString().swap(*this); + //Instead use the quit & re-init: + quit(); + init(0,0); + } + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function DOES NOT clear the content of the TiXmlString if any exists. + */ + void reserve (size_type cap); + + TiXmlString& assign (const char* str, size_type len); + + TiXmlString& append (const char* str, size_type len); + + void swap (TiXmlString& other) + { + Rep* r = rep_; + rep_ = other.rep_; + other.rep_ = r; + } private: - void init(size_type sz) { init(sz, sz); } - void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } - char* start() const { return rep_->str; } - char* finish() const { return rep_->str + rep_->size; } - - struct Rep - { - size_type size, capacity; - char str[1]; - }; - - void init(size_type sz, size_type cap) - { - if (cap) - { - // Lee: the original form: - // rep_ = static_cast(operator new(sizeof(Rep) + cap)); - // doesn't work in some cases of new being overloaded. Switching - // to the normal allocation, although use an 'int' for systems - // that are overly picky about structure alignment. - const size_type bytesNeeded = sizeof(Rep) + cap; - const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); - rep_ = reinterpret_cast( new int[ intsNeeded ] ); - - rep_->str[ rep_->size = sz ] = '\0'; - rep_->capacity = cap; - } - else - { - rep_ = &nullrep_; - } - } - - void quit() - { - if (rep_ != &nullrep_) - { - // The rep_ is really an array of ints. (see the allocator, above). - // Cast it back before delete, so the compiler won't incorrectly call destructors. - delete [] ( reinterpret_cast( rep_ ) ); - } - } - - Rep * rep_; - static Rep nullrep_; + void init(size_type sz) { init(sz, sz); } + void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } + char* start() const { return rep_->str; } + char* finish() const { return rep_->str + rep_->size; } + + struct Rep + { + size_type size, capacity; + char str[1]; + }; + + void init(size_type sz, size_type cap) + { + if (cap) + { + // Lee: the original form: + // rep_ = static_cast(operator new(sizeof(Rep) + cap)); + // doesn't work in some cases of new being overloaded. Switching + // to the normal allocation, although use an 'int' for systems + // that are overly picky about structure alignment. + const size_type bytesNeeded = sizeof(Rep) + cap; + const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); + rep_ = reinterpret_cast( new int[ intsNeeded ] ); + + rep_->str[ rep_->size = sz ] = '\0'; + rep_->capacity = cap; + } + else + { + rep_ = &nullrep_; + } + } + + void quit() + { + if (rep_ != &nullrep_) + { + // The rep_ is really an array of ints. (see the allocator, above). + // Cast it back before delete, so the compiler won't incorrectly call destructors. + delete [] ( reinterpret_cast( rep_ ) ); + } + } + + Rep * rep_; + static Rep nullrep_; } ; inline bool operator == (const TiXmlString & a, const TiXmlString & b) { - return ( a.length() == b.length() ) // optimization on some platforms - && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare + return ( a.length() == b.length() ) // optimization on some platforms + && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare } inline bool operator < (const TiXmlString & a, const TiXmlString & b) { - return strcmp(a.c_str(), b.c_str()) < 0; + return strcmp(a.c_str(), b.c_str()) < 0; } inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } @@ -299,21 +299,21 @@ class TiXmlOutStream : public TiXmlString { public : - // TiXmlOutStream << operator. - TiXmlOutStream & operator << (const TiXmlString & in) - { - *this += in; - return *this; - } + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const TiXmlString & in) + { + *this += in; + return *this; + } - // TiXmlOutStream << operator. - TiXmlOutStream & operator << (const char * in) - { - *this += in; - return *this; - } + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const char * in) + { + *this += in; + return *this; + } } ; -#endif // TIXML_STRING_INCLUDED -#endif // TIXML_USE_STL +#endif // TIXML_STRING_INCLUDED +#endif // TIXML_USE_STL diff --git a/Tools/XMLConverter/include/tinyxml.h b/Tools/XMLConverter/include/tinyxml.h index 3c53dd7de1f..20f81a8fe86 100644 --- a/Tools/XMLConverter/include/tinyxml.h +++ b/Tools/XMLConverter/include/tinyxml.h @@ -45,13 +45,13 @@ distribution. #endif #ifdef TIXML_USE_STL - #include - #include - #include -#define TIXML_STRING Ogre::String + #include + #include + #include +#define TIXML_STRING Ogre::String #else - #include "tinystr.h" - #define TIXML_STRING TiXmlString + #include "tinystr.h" + #define TIXML_STRING TiXmlString #endif // Deprecated library function hell. Compilers want to use the @@ -61,22 +61,22 @@ distribution. #define TIXML_SAFE #ifdef TIXML_SAFE - #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - // Microsoft visual studio, version 2005 and higher. - #define TIXML_SNPRINTF _snprintf_s - #define TIXML_SNSCANF _snscanf_s - #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) - // Microsoft visual studio, version 6 and higher. - //#pragma message( "Using _sn* functions." ) - #define TIXML_SNPRINTF _snprintf - #define TIXML_SNSCANF _snscanf - #elif defined(__GNUC__) && (__GNUC__ >= 3 ) - // GCC version 3 and higher.s - //#warning( "Using sn* functions." ) - #define TIXML_SNPRINTF snprintf - #define TIXML_SNSCANF snscanf - #endif -#endif + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + // Microsoft visual studio, version 2005 and higher. + #define TIXML_SNPRINTF _snprintf_s + #define TIXML_SNSCANF _snscanf_s + #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + //#pragma message( "Using _sn* functions." ) + #define TIXML_SNPRINTF _snprintf + #define TIXML_SNSCANF _snscanf + #elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_SNSCANF snscanf + #endif +#endif class TiXmlDocument; class TiXmlElement; @@ -91,1080 +91,1080 @@ const int TIXML_MAJOR_VERSION = 2; const int TIXML_MINOR_VERSION = 5; const int TIXML_PATCH_VERSION = 2; -/* Internal structure for tracking location of items - in the XML file. +/* Internal structure for tracking location of items + in the XML file. */ struct TiXmlCursor { - TiXmlCursor() { Clear(); } - void Clear() { row = col = -1; } + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } - int row; // 0 based. - int col; // 0 based. + int row; // 0 based. + int col; // 0 based. }; /** - If you call the Accept() method, it requires being passed a TiXmlVisitor - class to handle callbacks. For nodes that contain other nodes (Document, Element) - you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves - are simple called with Visit(). + If you call the Accept() method, it requires being passed a TiXmlVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves + are simple called with Visit(). - If you return 'true' from a Visit method, recursive parsing will continue. If you return - false, no children of this node or its sibilings will be Visited. + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its sibilings will be Visited. - All flavors of Visit methods have a default implementation that returns 'true' (continue - visiting). You need to only override methods that are interesting to you. + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. - Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. + Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. - You should never change the document from a callback. + You should never change the document from a callback. - @sa TiXmlNode::Accept() + @sa TiXmlNode::Accept() */ class TiXmlVisitor { public: - virtual ~TiXmlVisitor() {} - - /// Visit a document. - virtual bool VisitEnter( const TiXmlDocument& doc ) { return true; } - /// Visit a document. - virtual bool VisitExit( const TiXmlDocument& doc ) { return true; } - - /// Visit an element. - virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) { return true; } - /// Visit an element. - virtual bool VisitExit( const TiXmlElement& element ) { return true; } - - /// Visit a declaration - virtual bool Visit( const TiXmlDeclaration& declaration ) { return true; } - /// Visit a text node - virtual bool Visit( const TiXmlText& text ) { return true; } - /// Visit a comment node - virtual bool Visit( const TiXmlComment& comment ) { return true; } - /// Visit an unknow node - virtual bool Visit( const TiXmlUnknown& unknown ) { return true; } + virtual ~TiXmlVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const TiXmlDocument& doc ) { return true; } + /// Visit a document. + virtual bool VisitExit( const TiXmlDocument& doc ) { return true; } + + /// Visit an element. + virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) { return true; } + /// Visit an element. + virtual bool VisitExit( const TiXmlElement& element ) { return true; } + + /// Visit a declaration + virtual bool Visit( const TiXmlDeclaration& declaration ) { return true; } + /// Visit a text node + virtual bool Visit( const TiXmlText& text ) { return true; } + /// Visit a comment node + virtual bool Visit( const TiXmlComment& comment ) { return true; } + /// Visit an unknow node + virtual bool Visit( const TiXmlUnknown& unknown ) { return true; } }; // Only used by Attribute::Query functions enum { - TIXML_SUCCESS, - TIXML_NO_ATTRIBUTE, - TIXML_WRONG_TYPE + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE }; // Used by the parsing routines. enum TiXmlEncoding { - TIXML_ENCODING_UNKNOWN, - TIXML_ENCODING_UTF8, - TIXML_ENCODING_LEGACY + TIXML_ENCODING_UNKNOWN, + TIXML_ENCODING_UTF8, + TIXML_ENCODING_LEGACY }; const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; /** TiXmlBase is a base class for every class in TinyXml. - It does little except to establish that TinyXml classes - can be printed and provide some utility functions. - - In XML, the document and elements can contain - other elements and other types of nodes. - - @verbatim - A Document can contain: Element (container or leaf) - Comment (leaf) - Unknown (leaf) - Declaration( leaf ) - - An Element can contain: Element (container or leaf) - Text (leaf) - Attributes (not on tree) - Comment (leaf) - Unknown (leaf) - - A Decleration contains: Attributes (not on tree) - @endverbatim + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim */ class TiXmlBase { - friend class TiXmlNode; - friend class TiXmlElement; - friend class TiXmlDocument; + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; public: - TiXmlBase() : userData(0) {} - virtual ~TiXmlBase() {} - - /** All TinyXml classes can print themselves to a filestream - or the string class (TiXmlString in non-STL mode, TIXML_STRING - in STL mode.) Either or both cfile and str can be null. - - This is a formatted print, and will insert - tabs and newlines. - - (For an unformatted stream, use the << operator.) - */ - virtual void Print( FILE* cfile, int depth ) const = 0; - - /** The world does not agree on whether white space should be kept or - not. In order to make everyone happy, these global, static functions - are provided to set whether or not TinyXml will condense all white space - into a single space or not. The default is to condense. Note changing this - value is not thread safe. - */ - static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } - - /// Return the current white space setting. - static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } - - /** Return the position, in the original source file, of this node or attribute. - The row and column are 1-based. (That is the first row and first column is - 1,1). If the returns values are 0 or less, then the parser does not have - a row and column value. - - Generally, the row and column value will be set when the TiXmlDocument::Load(), - TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set - when the DOM was created from operator>>. - - The values reflect the initial load. Once the DOM is modified programmatically - (by adding or changing nodes and attributes) the new values will NOT update to - reflect changes in the document. - - There is a minor performance cost to computing the row and column. Computation - can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. - - @sa TiXmlDocument::SetTabSize() - */ - int Row() const { return location.row + 1; } - int Column() const { return location.col + 1; } ///< See Row() - - void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. - void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. - const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. - - // Table that returs, for a given lead byte, the total number of bytes - // in the UTF-8 sequence. - static const int utf8ByteTable[256]; - - virtual const char* Parse( const char* p, - TiXmlParsingData* data, - TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; - - enum - { - TIXML_NO_ERROR = 0, - TIXML_ERROR, - TIXML_ERROR_OPENING_FILE, - TIXML_ERROR_OUT_OF_MEMORY, - TIXML_ERROR_PARSING_ELEMENT, - TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, - TIXML_ERROR_READING_ELEMENT_VALUE, - TIXML_ERROR_READING_ATTRIBUTES, - TIXML_ERROR_PARSING_EMPTY, - TIXML_ERROR_READING_END_TAG, - TIXML_ERROR_PARSING_UNKNOWN, - TIXML_ERROR_PARSING_COMMENT, - TIXML_ERROR_PARSING_DECLARATION, - TIXML_ERROR_DOCUMENT_EMPTY, - TIXML_ERROR_EMBEDDED_NULL, - TIXML_ERROR_PARSING_CDATA, - TIXML_ERROR_DOCUMENT_TOP_ONLY, - - TIXML_ERROR_STRING_COUNT - }; + TiXmlBase() : userData(0) {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream + or the string class (TiXmlString in non-STL mode, TIXML_STRING + in STL mode.) Either or both cfile and str can be null. + + This is a formatted print, and will insert + tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + value is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + + void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. + void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. + const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. + + // Table that returs, for a given lead byte, the total number of bytes + // in the UTF-8 sequence. + static const int utf8ByteTable[256]; + + virtual const char* Parse( const char* p, + TiXmlParsingData* data, + TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_OUT_OF_MEMORY, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + TIXML_ERROR_EMBEDDED_NULL, + TIXML_ERROR_PARSING_CDATA, + TIXML_ERROR_DOCUMENT_TOP_ONLY, + + TIXML_ERROR_STRING_COUNT + }; protected: - static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); - inline static bool IsWhiteSpace( char c ) - { - return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); - } - inline static bool IsWhiteSpace( int c ) - { - if ( c < 256 ) - return IsWhiteSpace( (char) c ); - return false; // Again, only truly correct for English/Latin...but usually works. - } - - #ifdef TIXML_USE_STL - static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); - static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); - #endif - - /* Reads an XML name into the string provided. Returns - a pointer just past the last character of the name, - or 0 if the function has an error. - */ - static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); - - /* Reads text. Returns a pointer past the given end tag. - Wickedly complex options, but it keeps the (sensitive) code in one place. - */ - static const char* ReadText( const char* in, // where to start - TIXML_STRING* text, // the string read - bool ignoreWhiteSpace, // whether to keep the white space - const char* endTag, // what ends this text - bool ignoreCase, // whether to ignore case in the end tag - TiXmlEncoding encoding ); // the current encoding - - // If an entity has been found, transform it into a character. - static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); - - // Get a character, while interpreting entities. - // The length can be from 0 to 4 bytes. - inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) - { - assert( p ); - if ( encoding == TIXML_ENCODING_UTF8 ) - { - *length = utf8ByteTable[ *((const unsigned char*)p) ]; - assert( *length >= 0 && *length < 5 ); - } - else - { - *length = 1; - } - - if ( *length == 1 ) - { - if ( *p == '&' ) - return GetEntity( p, _value, length, encoding ); - *_value = *p; - return p+1; - } - else if ( *length ) - { - //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), - // and the null terminator isn't needed - for( int i=0; p[i] && i<*length; ++i ) { - _value[i] = p[i]; - } - return p + (*length); - } - else - { - // Not valid text. - return 0; - } - } - - // Puts a string to a stream, expanding entities as it goes. - // Note this should not contian the '<', '>', etc, or they will be transformed into entities! - static void PutString( const TIXML_STRING& str, TIXML_STRING* out ); - - // Return true if the next characters in the stream are any of the endTag sequences. - // Ignore case only works for english, and should only be relied on when comparing - // to English words: StringEqual( p, "version", true ) is fine. - static bool StringEqual( const char* p, - const char* endTag, - bool ignoreCase, - TiXmlEncoding encoding ); - - static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; - - TiXmlCursor location; + static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + } + inline static bool IsWhiteSpace( int c ) + { + if ( c < 256 ) + return IsWhiteSpace( (char) c ); + return false; // Again, only truly correct for English/Latin...but usually works. + } + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); + static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXML_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase, // whether to ignore case in the end tag + TiXmlEncoding encoding ); // the current encoding + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); + + // Get a character, while interpreting entities. + // The length can be from 0 to 4 bytes. + inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) + { + assert( p ); + if ( encoding == TIXML_ENCODING_UTF8 ) + { + *length = utf8ByteTable[ *((const unsigned char*)p) ]; + assert( *length >= 0 && *length < 5 ); + } + else + { + *length = 1; + } + + if ( *length == 1 ) + { + if ( *p == '&' ) + return GetEntity( p, _value, length, encoding ); + *_value = *p; + return p+1; + } + else if ( *length ) + { + //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), + // and the null terminator isn't needed + for( int i=0; p[i] && i<*length; ++i ) { + _value[i] = p[i]; + } + return p + (*length); + } + else + { + // Not valid text. + return 0; + } + } + + // Puts a string to a stream, expanding entities as it goes. + // Note this should not contian the '<', '>', etc, or they will be transformed into entities! + static void PutString( const TIXML_STRING& str, TIXML_STRING* out ); + + // Return true if the next characters in the stream are any of the endTag sequences. + // Ignore case only works for english, and should only be relied on when comparing + // to English words: StringEqual( p, "version", true ) is fine. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase, + TiXmlEncoding encoding ); + + static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; /// Field containing a generic user pointer - void* userData; - - // None of these methods are reliable for any language except English. - // Good for approximation, not great for accuracy. - static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); - static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); - inline static int ToLower( int v, TiXmlEncoding encoding ) - { - if ( encoding == TIXML_ENCODING_UTF8 ) - { - if ( v < 128 ) return tolower( v ); - return v; - } - else - { - return tolower( v ); - } - } - static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + void* userData; + + // None of these methods are reliable for any language except English. + // Good for approximation, not great for accuracy. + static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); + static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); + inline static int ToLower( int v, TiXmlEncoding encoding ) + { + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( v < 128 ) return tolower( v ); + return v; + } + else + { + return tolower( v ); + } + } + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); private: - TiXmlBase( const TiXmlBase& ); // not implemented. - void operator=( const TiXmlBase& base ); // not allowed. - - struct Entity - { - const char* str; - unsigned int strLength; - char chr; - }; - enum - { - NUM_ENTITY = 5, - MAX_ENTITY_LENGTH = 6 - - }; - static Entity entity[ NUM_ENTITY ]; - static bool condenseWhiteSpace; + TiXmlBase( const TiXmlBase& ); // not implemented. + void operator=( const TiXmlBase& base ); // not allowed. + + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; }; /** The parent class for everything in the Document Object Model. - (Except for attributes). - Nodes have siblings, a parent, and children. A node can be - in a document, or stand on its own. The type of a TiXmlNode - can be queried, and it can be cast to its more defined type. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. */ class TiXmlNode : public TiXmlBase { - friend class TiXmlDocument; - friend class TiXmlElement; + friend class TiXmlDocument; + friend class TiXmlElement; public: - #ifdef TIXML_USE_STL - - /** An input stream operator, for every class. Tolerant of newlines and - formatting, but doesn't expect them. - */ - friend std::istream& operator >> (std::istream& in, TiXmlNode& base); - - /** An output stream operator, for every class. Note that this outputs - without any newlines or formatting, as opposed to Print(), which - includes tabs and new lines. - - The operator<< and operator>> are not completely symmetric. Writing - a node to a stream is very well defined. You'll get a nice stream - of output, without any extra whitespace or newlines. - - But reading is not as well defined. (As it always is.) If you create - a TiXmlElement (for example) and read that from an input stream, - the text needs to define an element or junk will result. This is - true of all input streams, but it's worth keeping in mind. - - A TiXmlDocument will read nodes until it reads a root element, and - all the children of that root element. - */ - friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); - - /// Appends the XML node or attribute to a TIXML_STRING. - friend TIXML_STRING& operator<< (TIXML_STRING& out, const TiXmlNode& base ); - - #endif - - /** The types of XML nodes supported by TinyXml. (All the - unsupported types are picked up by UNKNOWN.) - */ - enum NodeType - { - DOCUMENT, - ELEMENT, - COMMENT, - UNKNOWN, - TEXT, - DECLARATION, - TYPECOUNT - }; - - virtual ~TiXmlNode(); - - /** The meaning of 'value' changes for the specific type of - TiXmlNode. - @verbatim - Document: filename of the xml file - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - - The subclasses will wrap this function. - */ - const char *Value() const { return value.c_str (); } + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a TIXML_STRING. + friend TIXML_STRING& operator<< (TIXML_STRING& out, const TiXmlNode& base ); + + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + DOCUMENT, + ELEMENT, + COMMENT, + UNKNOWN, + TEXT, + DECLARATION, + TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char *Value() const { return value.c_str (); } #ifdef TIXML_USE_STL - /** Return Value() as a TIXML_STRING. If you only use STL, - this is more efficient than calling Value(). - Only available in STL mode. - */ - const TIXML_STRING& ValueStr() const { return value; } - #endif - - /** Changes the value of the node. Defined as: - @verbatim - Document: filename of the xml file - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - */ - void SetValue(const char * _value) { value = _value;} + /** Return Value() as a TIXML_STRING. If you only use STL, + this is more efficient than calling Value(). + Only available in STL mode. + */ + const TIXML_STRING& ValueStr() const { return value; } + #endif + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} #ifdef TIXML_USE_STL - /// STL TIXML_STRING form. - void SetValue( const TIXML_STRING& _value ) { value = _value; } - #endif - - /// Delete all the children of this node. Does not affect 'this'. - void Clear(); - - /// One step up the DOM. - TiXmlNode* Parent() { return parent; } - const TiXmlNode* Parent() const { return parent; } - - const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. - TiXmlNode* FirstChild() { return firstChild; } - const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. - /// The first child of this node with the matching 'value'. Will be null if none found. - TiXmlNode* FirstChild( const char * _value ) { - // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) - // call the method, cast the return back to non-const. - return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); - } - const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. - TiXmlNode* LastChild() { return lastChild; } - - const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. - TiXmlNode* LastChild( const char * _value ) { - return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); - } + /// STL TIXML_STRING form. + void SetValue( const TIXML_STRING& _value ) { value = _value; } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() { return parent; } + const TiXmlNode* Parent() const { return parent; } + + const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild() { return firstChild; } + const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + /// The first child of this node with the matching 'value'. Will be null if none found. + TiXmlNode* FirstChild( const char * _value ) { + // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) + // call the method, cast the return back to non-const. + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); + } + const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild() { return lastChild; } + + const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + TiXmlNode* LastChild( const char * _value ) { + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); + } #ifdef TIXML_USE_STL - const TiXmlNode* FirstChild( const TIXML_STRING& _value ) const { return FirstChild (_value.c_str ()); } ///< STL TIXML_STRING form. - TiXmlNode* FirstChild( const TIXML_STRING& _value ) { return FirstChild (_value.c_str ()); } ///< STL TIXML_STRING form. - const TiXmlNode* LastChild( const TIXML_STRING& _value ) const { return LastChild (_value.c_str ()); } ///< STL TIXML_STRING form. - TiXmlNode* LastChild( const TIXML_STRING& _value ) { return LastChild (_value.c_str ()); } ///< STL TIXML_STRING form. - #endif - - /** An alternate way to walk the children of a node. - One way to iterate over nodes is: - @verbatim - for( child = parent->FirstChild(); child; child = child->NextSibling() ) - @endverbatim - - IterateChildren does the same thing with the syntax: - @verbatim - child = 0; - while( child = parent->IterateChildren( child ) ) - @endverbatim - - IterateChildren takes the previous child as input and finds - the next one. If the previous child is null, it returns the - first. IterateChildren will return null when done. - */ - const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; - TiXmlNode* IterateChildren( const TiXmlNode* previous ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); - } - - /// This flavor of IterateChildren searches for children with a particular 'value' - const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; - TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); - } + const TiXmlNode* FirstChild( const TIXML_STRING& _value ) const { return FirstChild (_value.c_str ()); } ///< STL TIXML_STRING form. + TiXmlNode* FirstChild( const TIXML_STRING& _value ) { return FirstChild (_value.c_str ()); } ///< STL TIXML_STRING form. + const TiXmlNode* LastChild( const TIXML_STRING& _value ) const { return LastChild (_value.c_str ()); } ///< STL TIXML_STRING form. + TiXmlNode* LastChild( const TIXML_STRING& _value ) { return LastChild (_value.c_str ()); } ///< STL TIXML_STRING form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); + } + + /// This flavor of IterateChildren searches for children with a particular 'value' + const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); + } #ifdef TIXML_USE_STL - const TiXmlNode* IterateChildren( const TIXML_STRING& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL TIXML_STRING form. - TiXmlNode* IterateChildren( const TIXML_STRING& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL TIXML_STRING form. - #endif + const TiXmlNode* IterateChildren( const TIXML_STRING& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL TIXML_STRING form. + TiXmlNode* IterateChildren( const TIXML_STRING& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL TIXML_STRING form. + #endif - /** Add a new node related to this. Adds a child past the LastChild. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); - /** Add a new node related to this. Adds a child past the LastChild. + /** Add a new node related to this. Adds a child past the LastChild. - NOTE: the node to be added is passed by pointer, and will be - henceforth owned (and deleted) by tinyXml. This method is efficient - and avoids an extra copy, but should be used with care as it - uses a different memory model than the other insert functions. + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. - @sa InsertEndChild - */ - TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); - /** Add a new node related to this. Adds a child before the specified child. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); - /** Add a new node related to this. Adds a child after the specified child. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); - /** Replace a child of this node. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); - /// Delete a child of this node. - bool RemoveChild( TiXmlNode* removeThis ); + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); - /// Navigate to a sibling node. - const TiXmlNode* PreviousSibling() const { return prev; } - TiXmlNode* PreviousSibling() { return prev; } + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling() const { return prev; } + TiXmlNode* PreviousSibling() { return prev; } - /// Navigate to a sibling node. - const TiXmlNode* PreviousSibling( const char * ) const; - TiXmlNode* PreviousSibling( const char *_prev ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); - } + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling( const char * ) const; + TiXmlNode* PreviousSibling( const char *_prev ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); + } #ifdef TIXML_USE_STL - const TiXmlNode* PreviousSibling( const TIXML_STRING& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL TIXML_STRING form. - TiXmlNode* PreviousSibling( const TIXML_STRING& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL TIXML_STRING form. - const TiXmlNode* NextSibling( const TIXML_STRING& _value) const { return NextSibling (_value.c_str ()); } ///< STL TIXML_STRING form. - TiXmlNode* NextSibling( const TIXML_STRING& _value) { return NextSibling (_value.c_str ()); } ///< STL TIXML_STRING form. - #endif - - /// Navigate to a sibling node. - const TiXmlNode* NextSibling() const { return next; } - TiXmlNode* NextSibling() { return next; } - - /// Navigate to a sibling node with the given 'value'. - const TiXmlNode* NextSibling( const char * ) const; - TiXmlNode* NextSibling( const char* _next ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); - } - - /** Convenience function to get through elements. - Calls NextSibling and ToElement. Will skip all non-Element - nodes. Returns 0 if there is not another element. - */ - const TiXmlElement* NextSiblingElement() const; - TiXmlElement* NextSiblingElement() { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); - } - - /** Convenience function to get through elements. - Calls NextSibling and ToElement. Will skip all non-Element - nodes. Returns 0 if there is not another element. - */ - const TiXmlElement* NextSiblingElement( const char * ) const; - TiXmlElement* NextSiblingElement( const char *_next ) { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); - } + const TiXmlNode* PreviousSibling( const TIXML_STRING& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL TIXML_STRING form. + TiXmlNode* PreviousSibling( const TIXML_STRING& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL TIXML_STRING form. + const TiXmlNode* NextSibling( const TIXML_STRING& _value) const { return NextSibling (_value.c_str ()); } ///< STL TIXML_STRING form. + TiXmlNode* NextSibling( const TIXML_STRING& _value) { return NextSibling (_value.c_str ()); } ///< STL TIXML_STRING form. + #endif + + /// Navigate to a sibling node. + const TiXmlNode* NextSibling() const { return next; } + TiXmlNode* NextSibling() { return next; } + + /// Navigate to a sibling node with the given 'value'. + const TiXmlNode* NextSibling( const char * ) const; + TiXmlNode* NextSibling( const char* _next ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement() const; + TiXmlElement* NextSiblingElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement( const char * ) const; + TiXmlElement* NextSiblingElement( const char *_next ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); + } #ifdef TIXML_USE_STL - const TiXmlElement* NextSiblingElement( const TIXML_STRING& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL TIXML_STRING form. - TiXmlElement* NextSiblingElement( const TIXML_STRING& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL TIXML_STRING form. - #endif - - /// Convenience function to get through elements. - const TiXmlElement* FirstChildElement() const; - TiXmlElement* FirstChildElement() { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); - } - - /// Convenience function to get through elements. - const TiXmlElement* FirstChildElement( const char * _value ) const; - TiXmlElement* FirstChildElement( const char * _value ) { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); - } + const TiXmlElement* NextSiblingElement( const TIXML_STRING& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL TIXML_STRING form. + TiXmlElement* NextSiblingElement( const TIXML_STRING& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL TIXML_STRING form. + #endif + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement() const; + TiXmlElement* FirstChildElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); + } + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement( const char * _value ) const; + TiXmlElement* FirstChildElement( const char * _value ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); + } #ifdef TIXML_USE_STL - const TiXmlElement* FirstChildElement( const TIXML_STRING& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL TIXML_STRING form. - TiXmlElement* FirstChildElement( const TIXML_STRING& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL TIXML_STRING form. - #endif - - /** Query the type (as an enumerated value, above) of this node. - The possible types are: DOCUMENT, ELEMENT, COMMENT, - UNKNOWN, TEXT, and DECLARATION. - */ - int Type() const { return type; } - - /** Return a pointer to the Document this node lives in. - Returns null if not in a document. - */ - const TiXmlDocument* GetDocument() const; - TiXmlDocument* GetDocument() { - return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); - } - - /// Returns true if this node has no children. - bool NoChildren() const { return !firstChild; } - - virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - - virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - - /** Create an exact duplicate of this node and return it. The memory must be deleted - by the caller. - */ - virtual TiXmlNode* Clone() const = 0; - - /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the - XML tree will be conditionally visited and the host will be called back - via the TiXmlVisitor interface. - - This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse - the XML for the callbacks, so the performance of TinyXML is unchanged by using this - interface versus any other.) - - The interface has been based on ideas from: - - - http://www.saxproject.org/ - - http://c2.com/cgi/wiki?HierarchicalVisitorPattern - - Which are both good references for "visiting". - - An example of using Accept(): - @verbatim - TiXmlPrinter printer; - tinyxmlDoc.Accept( &printer ); - const char* xmlcstr = printer.CStr(); - @endverbatim - */ - virtual bool Accept( TiXmlVisitor* visitor ) const = 0; + const TiXmlElement* FirstChildElement( const TIXML_STRING& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL TIXML_STRING form. + TiXmlElement* FirstChildElement( const TIXML_STRING& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL TIXML_STRING form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: DOCUMENT, ELEMENT, COMMENT, + UNKNOWN, TEXT, and DECLARATION. + */ + int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + const TiXmlDocument* GetDocument() const; + TiXmlDocument* GetDocument() { + return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); + } + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + /** Create an exact duplicate of this node and return it. The memory must be deleted + by the caller. + */ + virtual TiXmlNode* Clone() const = 0; + + /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the TiXmlVisitor interface. + + This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + TiXmlPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( TiXmlVisitor* visitor ) const = 0; protected: - TiXmlNode( NodeType _type ); + TiXmlNode( NodeType _type ); - // Copy to the allocated object. Shared functionality between Clone, Copy constructor, - // and the assignment operator. - void CopyTo( TiXmlNode* target ) const; + // Copy to the allocated object. Shared functionality between Clone, Copy constructor, + // and the assignment operator. + void CopyTo( TiXmlNode* target ) const; - #ifdef TIXML_USE_STL - // The real work of the input operator. - virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; - #endif + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; + #endif - // Figure out what is at *p, and parse it. Returns null if it is not an xml node. - TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); - TiXmlNode* parent; - NodeType type; + TiXmlNode* parent; + NodeType type; - TiXmlNode* firstChild; - TiXmlNode* lastChild; + TiXmlNode* firstChild; + TiXmlNode* lastChild; - TIXML_STRING value; + TIXML_STRING value; - TiXmlNode* prev; - TiXmlNode* next; + TiXmlNode* prev; + TiXmlNode* next; private: - TiXmlNode( const TiXmlNode& ); // not implemented. - void operator=( const TiXmlNode& base ); // not allowed. + TiXmlNode( const TiXmlNode& ); // not implemented. + void operator=( const TiXmlNode& base ); // not allowed. }; /** An attribute is a name-value pair. Elements have an arbitrary - number of attributes, each with a unique name. + number of attributes, each with a unique name. - @note The attributes are not TiXmlNodes, since they are not - part of the tinyXML document object model. There are other - suggested ways to look at this problem. + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. */ class TiXmlAttribute : public TiXmlBase { - friend class TiXmlAttributeSet; + friend class TiXmlAttributeSet; public: - /// Construct an empty attribute. - TiXmlAttribute() : TiXmlBase() - { - document = 0; - prev = next = 0; - } - - #ifdef TIXML_USE_STL - /// TIXML_STRING constructor. - TiXmlAttribute( const TIXML_STRING& _name, const TIXML_STRING& _value ) - { - name = _name; - value = _value; - document = 0; - prev = next = 0; - } - #endif - - /// Construct an attribute with a name and value. - TiXmlAttribute( const char * _name, const char * _value ) - { - name = _name; - value = _value; - document = 0; - prev = next = 0; - } - - const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. - const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. - #ifdef TIXML_USE_STL - const TIXML_STRING& ValueStr() const { return value; } ///< Return the value of this attribute. - #endif - int IntValue() const; ///< Return the value of this attribute, converted to an integer. - double DoubleValue() const; ///< Return the value of this attribute, converted to a double. - - // Get the tinyxml string representation - const TIXML_STRING& NameTStr() const { return name; } - - /** QueryIntValue examines the value string. It is an alternative to the - IntValue() method with richer error checking. - If the value is an integer, it is stored in 'value' and - the call returns TIXML_SUCCESS. If it is not - an integer, it returns TIXML_WRONG_TYPE. - - A specialized but useful call. Note that for success it returns 0, - which is the opposite of almost all other TinyXml calls. - */ - int QueryIntValue( int* _value ) const; - /// QueryDoubleValue examines the value string. See QueryIntValue(). - int QueryDoubleValue( double* _value ) const; - - void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. - void SetValue( const char* _value ) { value = _value; } ///< Set the value. - - void SetIntValue( int _value ); ///< Set the value from an integer. - void SetDoubleValue( double _value ); ///< Set the value from a double. + /// Construct an empty attribute. + TiXmlAttribute() : TiXmlBase() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// TIXML_STRING constructor. + TiXmlAttribute( const TIXML_STRING& _name, const TIXML_STRING& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. + #ifdef TIXML_USE_STL + const TIXML_STRING& ValueStr() const { return value; } ///< Return the value of this attribute. + #endif + int IntValue() const; ///< Return the value of this attribute, converted to an integer. + double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + // Get the tinyxml string representation + const TIXML_STRING& NameTStr() const { return name; } + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* _value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* _value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int _value ); ///< Set the value from an integer. + void SetDoubleValue( double _value ); ///< Set the value from a double. #ifdef TIXML_USE_STL - /// STL TIXML_STRING form. - void SetName( const TIXML_STRING& _name ) { name = _name; } - /// STL TIXML_STRING form. - void SetValue( const TIXML_STRING& _value ) { value = _value; } - #endif - - /// Get the next sibling attribute in the DOM. Returns null at end. - const TiXmlAttribute* Next() const; - TiXmlAttribute* Next() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); - } - - /// Get the previous sibling attribute in the DOM. Returns null at beginning. - const TiXmlAttribute* Previous() const; - TiXmlAttribute* Previous() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); - } - - bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } - bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } - bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } - - /* Attribute parsing starts: first letter of the name - returns: the next char after the value end quote - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - // Prints this Attribute to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const { - Print( cfile, depth, 0 ); - } - void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - - // [internal use] - // Set the document pointer so the attribute can report errors. - void SetDocument( TiXmlDocument* doc ) { document = doc; } + /// STL TIXML_STRING form. + void SetName( const TIXML_STRING& _name ) { name = _name; } + /// STL TIXML_STRING form. + void SetValue( const TIXML_STRING& _value ) { value = _value; } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + const TiXmlAttribute* Next() const; + TiXmlAttribute* Next() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); + } + + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + const TiXmlAttribute* Previous() const; + TiXmlAttribute* Previous() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); + } + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* Attribute parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + // Prints this Attribute to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } private: - TiXmlAttribute( const TiXmlAttribute& ); // not implemented. - void operator=( const TiXmlAttribute& base ); // not allowed. - - TiXmlDocument* document; // A pointer back to a document, for error reporting. - TIXML_STRING name; - TIXML_STRING value; - TiXmlAttribute* prev; - TiXmlAttribute* next; + TiXmlAttribute( const TiXmlAttribute& ); // not implemented. + void operator=( const TiXmlAttribute& base ); // not allowed. + + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; }; -/* A class used to manage a group of attributes. - It is only used internally, both by the ELEMENT and the DECLARATION. - - The set can be changed transparent to the Element and Declaration - classes that use it, but NOT transparent to the Attribute - which has to implement a next() and previous() method. Which makes - it a bit problematic and prevents the use of STL. +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. - This version is implemented with circular lists because: - - I like circular lists - - it demonstrates some independence from the (typical) doubly linked list. + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. */ class TiXmlAttributeSet { public: - TiXmlAttributeSet(); - ~TiXmlAttributeSet(); + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); - void Add( TiXmlAttribute* attribute ); - void Remove( TiXmlAttribute* attribute ); + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); - const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } - TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } - const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } - TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } - const TiXmlAttribute* Find( const char* _name ) const; - TiXmlAttribute* Find( const char* _name ) { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); - } - #ifdef TIXML_USE_STL - const TiXmlAttribute* Find( const TIXML_STRING& _name ) const; - TiXmlAttribute* Find( const TIXML_STRING& _name ) { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); - } + const TiXmlAttribute* Find( const char* _name ) const; + TiXmlAttribute* Find( const char* _name ) { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); + } + #ifdef TIXML_USE_STL + const TiXmlAttribute* Find( const TIXML_STRING& _name ) const; + TiXmlAttribute* Find( const TIXML_STRING& _name ) { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); + } - #endif + #endif private: - //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), - //*ME: this class must be also use a hidden/disabled copy-constructor !!! - TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed - void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) + //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), + //*ME: this class must be also use a hidden/disabled copy-constructor !!! + TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed + void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) - TiXmlAttribute sentinel; + TiXmlAttribute sentinel; }; /** The element is a container class. It has a value, the element name, - and can contain other elements, text, comments, and unknowns. - Elements also contain an arbitrary number of attributes. + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. */ class TiXmlElement : public TiXmlNode { public: - /// Construct an element. - TiXmlElement (const char * in_value); - - #ifdef TIXML_USE_STL - /// TIXML_STRING constructor. - TiXmlElement( const TIXML_STRING& _value ); - #endif - - TiXmlElement( const TiXmlElement& ); - - void operator=( const TiXmlElement& base ); - - virtual ~TiXmlElement(); - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - */ - const char* Attribute( const char* name ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - If the attribute exists and can be converted to an integer, - the integer value will be put in the return 'i', if 'i' - is non-null. - */ - const char* Attribute( const char* name, int* i ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - If the attribute exists and can be converted to an double, - the double value will be put in the return 'd', if 'd' - is non-null. - */ - const char* Attribute( const char* name, double* d ) const; - - /** QueryIntAttribute examines the attribute - it is an alternative to the - Attribute() method with richer error checking. - If the attribute is an integer, it is stored in 'value' and - the call returns TIXML_SUCCESS. If it is not - an integer, it returns TIXML_WRONG_TYPE. If the attribute - does not exist, then TIXML_NO_ATTRIBUTE is returned. - */ - int QueryIntAttribute( const char* name, int* _value ) const; - /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). - int QueryDoubleAttribute( const char* name, double* _value ) const; - /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). - int QueryFloatAttribute( const char* name, float* _value ) const { - double d; - int result = QueryDoubleAttribute( name, &d ); - if ( result == TIXML_SUCCESS ) { - *_value = (float)d; - } - return result; - } + /// Construct an element. + TiXmlElement (const char * in_value); + + #ifdef TIXML_USE_STL + /// TIXML_STRING constructor. + TiXmlElement( const TIXML_STRING& _value ); + #endif + + TiXmlElement( const TiXmlElement& ); + + void operator=( const TiXmlElement& base ); + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* _value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* _value ) const; + /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). + int QueryFloatAttribute( const char* name, float* _value ) const { + double d; + int result = QueryDoubleAttribute( name, &d ); + if ( result == TIXML_SUCCESS ) { + *_value = (float)d; + } + return result; + } #ifdef TIXML_USE_STL - /** Template form of the attribute query which will try to read the - attribute into the specified type. Very easy, very powerful, but - be careful to make sure to call this with the correct type. - - @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE - */ - template< typename T > int QueryValueAttribute( const TIXML_STRING& name, T* outValue ) const - { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - - Ogre::StringStream sstream( node->ValueStr() ); - sstream >> *outValue; - if ( !sstream.fail() ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; - } - #endif - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetAttribute( const char* name, const char * _value ); + /** Template form of the attribute query which will try to read the + attribute into the specified type. Very easy, very powerful, but + be careful to make sure to call this with the correct type. + + @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE + */ + template< typename T > int QueryValueAttribute( const TIXML_STRING& name, T* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + Ogre::StringStream sstream( node->ValueStr() ); + sstream >> *outValue; + if ( !sstream.fail() ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; + } + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * _value ); #ifdef TIXML_USE_STL - const TIXML_STRING* Attribute( const TIXML_STRING& name ) const; - const TIXML_STRING* Attribute( const TIXML_STRING& name, int* i ) const; - const TIXML_STRING* Attribute( const TIXML_STRING& name, double* d ) const; - int QueryIntAttribute( const TIXML_STRING& name, int* _value ) const; - int QueryDoubleAttribute( const TIXML_STRING& name, double* _value ) const; - - /// STL TIXML_STRING form. - void SetAttribute( const TIXML_STRING& name, const TIXML_STRING& _value ); - ///< STL TIXML_STRING form. - void SetAttribute( const TIXML_STRING& name, int _value ); - #endif - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetAttribute( const char * name, int value ); - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetDoubleAttribute( const char * name, double value ); - - /** Deletes an attribute with the given name. - */ - void RemoveAttribute( const char * name ); + const TIXML_STRING* Attribute( const TIXML_STRING& name ) const; + const TIXML_STRING* Attribute( const TIXML_STRING& name, int* i ) const; + const TIXML_STRING* Attribute( const TIXML_STRING& name, double* d ) const; + int QueryIntAttribute( const TIXML_STRING& name, int* _value ) const; + int QueryDoubleAttribute( const TIXML_STRING& name, double* _value ) const; + + /// STL TIXML_STRING form. + void SetAttribute( const TIXML_STRING& name, const TIXML_STRING& _value ); + ///< STL TIXML_STRING form. + void SetAttribute( const TIXML_STRING& name, int _value ); + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetDoubleAttribute( const char * name, double value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); #ifdef TIXML_USE_STL - void RemoveAttribute( const TIXML_STRING& name ) { RemoveAttribute (name.c_str ()); } ///< STL TIXML_STRING form. - #endif - - const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. - TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } - const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. - TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, GetText() is limited compared to getting the TiXmlText child - and accessing it directly. - - If the first child of 'this' is a TiXmlText, the GetText() - returns the character string of the Text node, else null is returned. - - This is a convenient method for getting the text of simple contained text: - @verbatim - This is text - const char* str = fooElement->GetText(); - @endverbatim - - 'str' will be a pointer to "This is text". - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - This is text - @endverbatim - - then the value of str would be null. The first child node isn't a text node, it is - another element. From this XML: - @verbatim - This is text - @endverbatim - GetText() will return "This is ". - - WARNING: GetText() accesses a child node - don't become confused with the - similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are - safe type casts on the referenced node. - */ - const char* GetText() const; - - /// Creates a new Element and returns it - the returned element is a copy. - virtual TiXmlNode* Clone() const; - // Print the Element to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /* Attribtue parsing starts: next char past '<' - returns: next char past '>' - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; + void RemoveAttribute( const TIXML_STRING& name ) { RemoveAttribute (name.c_str ()); } ///< STL TIXML_STRING form. + #endif + + const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } + const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the TiXmlText child + and accessing it directly. + + If the first child of 'this' is a TiXmlText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + + WARNING: GetText() accesses a child node - don't become confused with the + similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are + safe type casts on the referenced node. + */ + const char* GetText() const; + + /// Creates a new Element and returns it - the returned element is a copy. + virtual TiXmlNode* Clone() const; + // Print the Element to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; protected: - void CopyTo( TiXmlElement* target ) const; - void ClearThis(); // like clear, but initializes 'this' object as well + void CopyTo( TiXmlElement* target ) const; + void ClearThis(); // like clear, but initializes 'this' object as well - // Used to be public [internal use] - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - /* [internal use] - Reads the "value" of the element -- another element, or text. - This should terminate with the current end tag. - */ - const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); private: - TiXmlAttributeSet attributeSet; + TiXmlAttributeSet attributeSet; }; -/** An XML comment. +/** An XML comment. */ class TiXmlComment : public TiXmlNode { public: - /// Constructs an empty comment. - TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} - /// Construct a comment from text. - TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { - SetValue( _value ); - } - TiXmlComment( const TiXmlComment& ); - void operator=( const TiXmlComment& base ); - - virtual ~TiXmlComment() {} - - /// Returns a copy of this Comment. - virtual TiXmlNode* Clone() const; - // Write this Comment to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /* Attribtue parsing starts: at the ! of the !-- - returns: next char past '>' - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} + /// Construct a comment from text. + TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { + SetValue( _value ); + } + TiXmlComment( const TiXmlComment& ); + void operator=( const TiXmlComment& base ); + + virtual ~TiXmlComment() {} + + /// Returns a copy of this Comment. + virtual TiXmlNode* Clone() const; + // Write this Comment to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; protected: - void CopyTo( TiXmlComment* target ) const; + void CopyTo( TiXmlComment* target ) const; - // used to be public - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif -// virtual void StreamOut( TIXML_OSTREAM * out ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif +// virtual void StreamOut( TIXML_OSTREAM * out ) const; private: @@ -1172,181 +1172,181 @@ class TiXmlComment : public TiXmlNode /** XML text. A text node can have 2 ways to output the next. "normal" output - and CDATA. It will default to the mode it was parsed from the XML file and - you generally want to leave it alone, but you can change the output mode with - SetCDATA() and query it with CDATA(). + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCDATA() and query it with CDATA(). */ class TiXmlText : public TiXmlNode { - friend class TiXmlElement; + friend class TiXmlElement; public: - /** Constructor for text element. By default, it is treated as - normal, encoded text. If you want it be output as a CDATA text - element, set the parameter _cdata to 'true' - */ - TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) - { - SetValue( initValue ); - cdata = false; - } - virtual ~TiXmlText() {} - - #ifdef TIXML_USE_STL - /// Constructor. - TiXmlText( const TIXML_STRING& initValue ) : TiXmlNode (TiXmlNode::TEXT) - { - SetValue( initValue ); - cdata = false; - } - #endif - - TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } - void operator=( const TiXmlText& base ) { base.CopyTo( this ); } - - // Write this text object to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /// Queries whether this represents text using a CDATA section. - bool CDATA() const { return cdata; } - /// Turns on or off a CDATA representation of text. - void SetCDATA( bool _cdata ) { cdata = _cdata; } - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; + /** Constructor for text element. By default, it is treated as + normal, encoded text. If you want it be output as a CDATA text + element, set the parameter _cdata to 'true' + */ + TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const TIXML_STRING& initValue ) : TiXmlNode (TiXmlNode::TEXT) + { + SetValue( initValue ); + cdata = false; + } + #endif + + TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } + void operator=( const TiXmlText& base ) { base.CopyTo( this ); } + + // Write this text object to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /// Queries whether this represents text using a CDATA section. + bool CDATA() const { return cdata; } + /// Turns on or off a CDATA representation of text. + void SetCDATA( bool _cdata ) { cdata = _cdata; } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; protected : - /// [internal use] Creates a new Element and returns it. - virtual TiXmlNode* Clone() const; - void CopyTo( TiXmlText* target ) const; + /// [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + void CopyTo( TiXmlText* target ) const; - bool Blank() const; // returns true if all white space and new lines - // [internal use] - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif + bool Blank() const; // returns true if all white space and new lines + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif private: - bool cdata; // true if this should be input and output as a CDATA style text element + bool cdata; // true if this should be input and output as a CDATA style text element }; /** In correct XML the declaration is the first entry in the file. - @verbatim - - @endverbatim + @verbatim + + @endverbatim - TinyXml will happily read or write files without a declaration, - however. There are 3 possible attributes to the declaration: - version, encoding, and standalone. + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. - Note: In this version of the code, the attributes are - handled as special cases, not generic attributes, simply - because there can only be at most 3 and they are always the same. + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. */ class TiXmlDeclaration : public TiXmlNode { public: - /// Construct an empty declaration. - TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} #ifdef TIXML_USE_STL - /// Constructor. - TiXmlDeclaration( const TIXML_STRING& _version, - const TIXML_STRING& _encoding, - const TIXML_STRING& _standalone ); + /// Constructor. + TiXmlDeclaration( const TIXML_STRING& _version, + const TIXML_STRING& _encoding, + const TIXML_STRING& _standalone ); #endif - /// Construct. - TiXmlDeclaration( const char* _version, - const char* _encoding, - const char* _standalone ); + /// Construct. + TiXmlDeclaration( const char* _version, + const char* _encoding, + const char* _standalone ); - TiXmlDeclaration( const TiXmlDeclaration& copy ); - void operator=( const TiXmlDeclaration& copy ); + TiXmlDeclaration( const TiXmlDeclaration& copy ); + void operator=( const TiXmlDeclaration& copy ); - virtual ~TiXmlDeclaration() {} + virtual ~TiXmlDeclaration() {} - /// Version. Will return an empty string if none was found. - const char *Version() const { return version.c_str (); } - /// Encoding. Will return an empty string if none was found. - const char *Encoding() const { return encoding.c_str (); } - /// Is this a standalone document? - const char *Standalone() const { return standalone.c_str (); } + /// Version. Will return an empty string if none was found. + const char *Version() const { return version.c_str (); } + /// Encoding. Will return an empty string if none was found. + const char *Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char *Standalone() const { return standalone.c_str (); } - /// Creates a copy of this Declaration and returns it. - virtual TiXmlNode* Clone() const; - // Print this declaration to a FILE stream. - virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - virtual void Print( FILE* cfile, int depth ) const { - Print( cfile, depth, 0 ); - } + /// Creates a copy of this Declaration and returns it. + virtual TiXmlNode* Clone() const; + // Print this declaration to a FILE stream. + virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; protected: - void CopyTo( TiXmlDeclaration* target ) const; - // used to be public - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif + void CopyTo( TiXmlDeclaration* target ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif private: - TIXML_STRING version; - TIXML_STRING encoding; - TIXML_STRING standalone; + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; }; /** Any tag that tinyXml doesn't recognize is saved as an - unknown. It is a tag of text, but should not be modified. - It will be written back to the XML, unchanged, when the file - is saved. + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. - DTD tags get thrown into TiXmlUnknowns. + DTD tags get thrown into TiXmlUnknowns. */ class TiXmlUnknown : public TiXmlNode { public: - TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} - virtual ~TiXmlUnknown() {} + TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} + virtual ~TiXmlUnknown() {} - TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } - void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } + TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } + void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } - /// Creates a copy of this Unknown and returns it. - virtual TiXmlNode* Clone() const; - // Print this Unknown to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; + /// Creates a copy of this Unknown and returns it. + virtual TiXmlNode* Clone() const; + // Print this Unknown to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; protected: - void CopyTo( TiXmlUnknown* target ) const; + void CopyTo( TiXmlUnknown* target ) const; - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif private: @@ -1354,418 +1354,418 @@ class TiXmlUnknown : public TiXmlNode /** Always the top level node. A document binds together all the - XML pieces. It can be saved, loaded, and printed to the screen. - The 'value' of a document node is the xml file name. + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. */ class TiXmlDocument : public TiXmlNode { public: - /// Create an empty document, that has no name. - TiXmlDocument(); - /// Create a document with a name. The name of the document is also the filename of the xml. - TiXmlDocument( const char * documentName ); - - #ifdef TIXML_USE_STL - /// Constructor. - TiXmlDocument( const TIXML_STRING& documentName ); - #endif - - TiXmlDocument( const TiXmlDocument& copy ); - void operator=( const TiXmlDocument& copy ); - - virtual ~TiXmlDocument() {} - - /** Load a file using the current document value. - Returns true if successful. Will delete any existing - document data before loading. - */ - bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the current document value. Returns true if successful. - bool SaveFile() const; - /// Load a file using the given filename. Returns true if successful. - bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the given filename. Returns true if successful. - bool SaveFile( const char * filename ) const; - /** Load a file using the given FILE*. Returns true if successful. Note that this method - doesn't stream - the entire object pointed at by the FILE* - will be interpreted as an XML file. TinyXML doesn't stream in XML from the current - file location. Streaming may be added in the future. - */ - bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the given FILE*. Returns true if successful. - bool SaveFile( FILE* ) const; - - #ifdef TIXML_USE_STL - bool LoadFile( const TIXML_STRING& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL TIXML_STRING version. - { -// StringToBuffer f( filename ); -// return ( f.buffer && LoadFile( f.buffer, encoding )); - return LoadFile( filename.c_str(), encoding ); - } - bool SaveFile( const TIXML_STRING& filename ) const ///< STL TIXML_STRING version. - { -// StringToBuffer f( filename ); -// return ( f.buffer && SaveFile( f.buffer )); - return SaveFile( filename.c_str() ); - } - #endif - - /** Parse the given null terminated block of xml data. Passing in an encoding to this - method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml - to use that encoding, regardless of what TinyXml might otherwise try to detect. - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - - /** Get the root element -- the only top level element -- of the document. - In well formed XML, there should only be one. TinyXml is tolerant of - multiple elements at the document level. - */ - const TiXmlElement* RootElement() const { return FirstChildElement(); } - TiXmlElement* RootElement() { return FirstChildElement(); } - - /** If an error occurs, Error will be set to true. Also, - - The ErrorId() will contain the integer identifier of the error (not generally useful) - - The ErrorDesc() method will return the name of the error. (very useful) - - The ErrorRow() and ErrorCol() will return the location of the error (if known) - */ - bool Error() const { return error; } - - /// Contains a textual (english) description of the error if one occurs. - const char * ErrorDesc() const { return errorDesc.c_str (); } - - /** Generally, you probably want the error string ( ErrorDesc() ). But if you - prefer the ErrorId, this function will fetch it. - */ - int ErrorId() const { return errorId; } - - /** Returns the location (if known) of the error. The first column is column 1, - and the first row is row 1. A value of 0 means the row and column wasn't applicable - (memory errors, for example, have no row/column) or the parser lost the error. (An - error in the error reporting, in that case.) - - @sa SetTabSize, Row, Column - */ - int ErrorRow() const { return errorLocation.row+1; } - int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() - - /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) - to report the correct values for row and column. It does not change the output - or input in any way. - - By calling this method, with a tab size - greater than 0, the row and column of each node and attribute is stored - when the file is loaded. Very useful for tracking the DOM back in to - the source file. - - The tab size is required for calculating the location of nodes. If not - set, the default of 4 is used. The tabsize is set per document. Setting - the tabsize to 0 disables row/column tracking. - - Note that row and column tracking is not supported when using operator>>. - - The tab size needs to be enabled before the parse or load. Correct usage: - @verbatim - TiXmlDocument doc; - doc.SetTabSize( 8 ); - doc.Load( "myfile.xml" ); - @endverbatim - - @sa Row, Column - */ - void SetTabSize( int _tabsize ) { tabsize = _tabsize; } - - int TabSize() const { return tabsize; } - - /** If you have handled the error, it can be reset with this call. The error - state is automatically cleared if you Parse a new XML block. - */ - void ClearError() { error = false; - errorId = 0; - errorDesc = ""; - errorLocation.row = errorLocation.col = 0; - //errorLocation.last = 0; - } - - /** Write the document to standard out using formatted printing ("pretty print"). */ - void Print() const { Print( stdout, 0 ); } - - /* Write the document to a string using formatted printing ("pretty print"). This - will allocate a character array (new char[]) and return it as a pointer. The - calling code pust call delete[] on the return char* to avoid a memory leak. - */ - //char* PrintToMemory() const; - - /// Print this Document to a FILE stream. - virtual void Print( FILE* cfile, int depth = 0 ) const; - // [internal use] - void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); - - virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const char * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const TIXML_STRING& documentName ); + #endif + + TiXmlDocument( const TiXmlDocument& copy ); + void operator=( const TiXmlDocument& copy ); + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + /** Load a file using the given FILE*. Returns true if successful. Note that this method + doesn't stream - the entire object pointed at by the FILE* + will be interpreted as an XML file. TinyXML doesn't stream in XML from the current + file location. Streaming may be added in the future. + */ + bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given FILE*. Returns true if successful. + bool SaveFile( FILE* ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const TIXML_STRING& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL TIXML_STRING version. + { +// StringToBuffer f( filename ); +// return ( f.buffer && LoadFile( f.buffer, encoding )); + return LoadFile( filename.c_str(), encoding ); + } + bool SaveFile( const TIXML_STRING& filename ) const ///< STL TIXML_STRING version. + { +// StringToBuffer f( filename ); +// return ( f.buffer && SaveFile( f.buffer )); + return SaveFile( filename.c_str() ); + } + #endif + + /** Parse the given null terminated block of xml data. Passing in an encoding to this + method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml + to use that encoding, regardless of what TinyXml might otherwise try to detect. + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + const TiXmlElement* RootElement() const { return FirstChildElement(); } + TiXmlElement* RootElement() { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() const { return errorLocation.row+1; } + int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) + to report the correct values for row and column. It does not change the output + or input in any way. + + By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Write the document to standard out using formatted printing ("pretty print"). */ + void Print() const { Print( stdout, 0 ); } + + /* Write the document to a string using formatted printing ("pretty print"). This + will allocate a character array (new char[]) and return it as a pointer. The + calling code pust call delete[] on the return char* to avoid a memory leak. + */ + //char* PrintToMemory() const; + + /// Print this Document to a FILE stream. + virtual void Print( FILE* cfile, int depth = 0 ) const; + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + + virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; protected : - // [internal use] - virtual TiXmlNode* Clone() const; - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif private: - void CopyTo( TiXmlDocument* target ) const; - - bool error; - int errorId; - TIXML_STRING errorDesc; - int tabsize; - TiXmlCursor errorLocation; - bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. + void CopyTo( TiXmlDocument* target ) const; + + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; + bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. }; /** - A TiXmlHandle is a class that wraps a node pointer with null checks; this is - an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml - DOM structure. It is a separate utility class. - - Take an example: - @verbatim - - - - - - - @endverbatim - - Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very - easy to write a *lot* of code that looks like: - - @verbatim - TiXmlElement* root = document.FirstChildElement( "Document" ); - if ( root ) - { - TiXmlElement* element = root->FirstChildElement( "Element" ); - if ( element ) - { - TiXmlElement* child = element->FirstChildElement( "Child" ); - if ( child ) - { - TiXmlElement* child2 = child->NextSiblingElement( "Child" ); - if ( child2 ) - { - // Finally do something useful. - @endverbatim - - And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity - of such code. A TiXmlHandle checks for null pointers so it is perfectly safe - and correct to use: - - @verbatim - TiXmlHandle docHandle( &document ); - TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); - if ( child2 ) - { - // do something useful - @endverbatim - - Which is MUCH more concise and useful. - - It is also safe to copy handles - internally they are nothing more than node pointers. - @verbatim - TiXmlHandle handleCopy = handle; - @endverbatim - - What they should not be used for is iteration: - - @verbatim - int i=0; - while ( true ) - { - TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); - if ( !child ) - break; - // do something - ++i; - } - @endverbatim - - It seems reasonable, but it is in fact two embedded while loops. The Child method is - a linear walk to find the element, so this code would iterate much more than it needs - to. Instead, prefer: - - @verbatim - TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); - - for( child; child; child=child->NextSiblingElement() ) - { - // do something - } - @endverbatim + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim */ class TiXmlHandle { public: - /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } - /// Copy constructor - TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } - TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } - - /// Return a handle to the first child node. - TiXmlHandle FirstChild() const; - /// Return a handle to the first child node with the given name. - TiXmlHandle FirstChild( const char * value ) const; - /// Return a handle to the first child element. - TiXmlHandle FirstChildElement() const; - /// Return a handle to the first child element with the given name. - TiXmlHandle FirstChildElement( const char * value ) const; - - /** Return a handle to the "index" child with the given name. - The first child is 0, the second 1, etc. - */ - TiXmlHandle Child( const char* value, int index ) const; - /** Return a handle to the "index" child. - The first child is 0, the second 1, etc. - */ - TiXmlHandle Child( int index ) const; - /** Return a handle to the "index" child element with the given name. - The first child element is 0, the second 1, etc. Note that only TiXmlElements - are indexed: other types are not counted. - */ - TiXmlHandle ChildElement( const char* value, int index ) const; - /** Return a handle to the "index" child element. - The first child element is 0, the second 1, etc. Note that only TiXmlElements - are indexed: other types are not counted. - */ - TiXmlHandle ChildElement( int index ) const; - - #ifdef TIXML_USE_STL - TiXmlHandle FirstChild( const TIXML_STRING& _value ) const { return FirstChild( _value.c_str() ); } - TiXmlHandle FirstChildElement( const TIXML_STRING& _value ) const { return FirstChildElement( _value.c_str() ); } - - TiXmlHandle Child( const TIXML_STRING& _value, int index ) const { return Child( _value.c_str(), index ); } - TiXmlHandle ChildElement( const TIXML_STRING& _value, int index ) const { return ChildElement( _value.c_str(), index ); } - #endif - - /** Return the handle as a TiXmlNode. This may return null. - */ - TiXmlNode* ToNode() const { return node; } - /** Return the handle as a TiXmlElement. This may return null. - */ - TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } - /** Return the handle as a TiXmlText. This may return null. - */ - TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } - /** Return the handle as a TiXmlUnknown. This may return null. - */ - TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } - - /** @deprecated use ToNode. - Return the handle as a TiXmlNode. This may return null. - */ - TiXmlNode* Node() const { return ToNode(); } - /** @deprecated use ToElement. - Return the handle as a TiXmlElement. This may return null. - */ - TiXmlElement* Element() const { return ToElement(); } - /** @deprecated use ToText() - Return the handle as a TiXmlText. This may return null. - */ - TiXmlText* Text() const { return ToText(); } - /** @deprecated use ToUnknown() - Return the handle as a TiXmlUnknown. This may return null. - */ - TiXmlUnknown* Unknown() const { return ToUnknown(); } + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const TIXML_STRING& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const TIXML_STRING& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const TIXML_STRING& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const TIXML_STRING& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /** Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* ToNode() const { return node; } + /** Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /** Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + /** Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + + /** @deprecated use ToNode. + Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* Node() const { return ToNode(); } + /** @deprecated use ToElement. + Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* Element() const { return ToElement(); } + /** @deprecated use ToText() + Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* Text() const { return ToText(); } + /** @deprecated use ToUnknown() + Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* Unknown() const { return ToUnknown(); } private: - TiXmlNode* node; + TiXmlNode* node; }; /** Print to memory functionality. The TiXmlPrinter is useful when you need to: - -# Print to memory (especially in non-STL mode) - -# Control formatting (line endings, etc.) + -# Print to memory (especially in non-STL mode) + -# Control formatting (line endings, etc.) - When constructed, the TiXmlPrinter is in its default "pretty printing" mode. - Before calling Accept() you can call methods to control the printing - of the XML document. After TiXmlNode::Accept() is called, the printed document can - be accessed via the CStr(), Str(), and Size() methods. + When constructed, the TiXmlPrinter is in its default "pretty printing" mode. + Before calling Accept() you can call methods to control the printing + of the XML document. After TiXmlNode::Accept() is called, the printed document can + be accessed via the CStr(), Str(), and Size() methods. - TiXmlPrinter uses the Visitor API. - @verbatim - TiXmlPrinter printer; - printer.SetIndent( "\t" ); + TiXmlPrinter uses the Visitor API. + @verbatim + TiXmlPrinter printer; + printer.SetIndent( "\t" ); - doc.Accept( &printer ); - fprintf( stdout, "%s", printer.CStr() ); - @endverbatim + doc.Accept( &printer ); + fprintf( stdout, "%s", printer.CStr() ); + @endverbatim */ class TiXmlPrinter : public TiXmlVisitor { public: - TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), - buffer(), indent( " " ), lineBreak( "\n" ) {} - - virtual bool VisitEnter( const TiXmlDocument& doc ); - virtual bool VisitExit( const TiXmlDocument& doc ); - - virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); - virtual bool VisitExit( const TiXmlElement& element ); - - virtual bool Visit( const TiXmlDeclaration& declaration ); - virtual bool Visit( const TiXmlText& text ); - virtual bool Visit( const TiXmlComment& comment ); - virtual bool Visit( const TiXmlUnknown& unknown ); - - /** Set the indent characters for printing. By default 4 spaces - but tab (\t) is also useful, or null/empty string for no indentation. - */ - void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } - /// Query the indention string. - const char* Indent() { return indent.c_str(); } - /** Set the line breaking string. By default set to newline (\n). - Some operating systems prefer other characters, or can be - set to the null/empty string for no indenation. - */ - void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } - /// Query the current line breaking string. - const char* LineBreak() { return lineBreak.c_str(); } - - /** Switch over to "stream printing" which is the most dense formatting without - linebreaks. Common when the XML is needed for network transmission. - */ - void SetStreamPrinting() { indent = ""; - lineBreak = ""; - } - /// Return the result. - const char* CStr() { return buffer.c_str(); } - /// Return the length of the result string. - size_t Size() { return buffer.size(); } - - #ifdef TIXML_USE_STL - /// Return the result. - const TIXML_STRING& Str() { return buffer; } - #endif + TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), + buffer(), indent( " " ), lineBreak( "\n" ) {} + + virtual bool VisitEnter( const TiXmlDocument& doc ); + virtual bool VisitExit( const TiXmlDocument& doc ); + + virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); + virtual bool VisitExit( const TiXmlElement& element ); + + virtual bool Visit( const TiXmlDeclaration& declaration ); + virtual bool Visit( const TiXmlText& text ); + virtual bool Visit( const TiXmlComment& comment ); + virtual bool Visit( const TiXmlUnknown& unknown ); + + /** Set the indent characters for printing. By default 4 spaces + but tab (\t) is also useful, or null/empty string for no indentation. + */ + void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } + /// Query the indention string. + const char* Indent() { return indent.c_str(); } + /** Set the line breaking string. By default set to newline (\n). + Some operating systems prefer other characters, or can be + set to the null/empty string for no indenation. + */ + void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } + /// Query the current line breaking string. + const char* LineBreak() { return lineBreak.c_str(); } + + /** Switch over to "stream printing" which is the most dense formatting without + linebreaks. Common when the XML is needed for network transmission. + */ + void SetStreamPrinting() { indent = ""; + lineBreak = ""; + } + /// Return the result. + const char* CStr() { return buffer.c_str(); } + /// Return the length of the result string. + size_t Size() { return buffer.size(); } + + #ifdef TIXML_USE_STL + /// Return the result. + const TIXML_STRING& Str() { return buffer; } + #endif private: - void DoIndent() { - for( int i=0; iLoadFile(); @@ -92,32 +92,32 @@ namespace Ogre { if (elem) readBoneAssignments(elem); - //Lod - elem = rootElem->FirstChildElement("levelofdetail"); - if (elem) - readLodInfo(elem); + //Lod + elem = rootElem->FirstChildElement("levelofdetail"); + if (elem) + readLodInfo(elem); - // submesh names - elem = rootElem->FirstChildElement("submeshnames"); - if (elem) - readSubMeshNames(elem, mMesh); + // submesh names + elem = rootElem->FirstChildElement("submeshnames"); + if (elem) + readSubMeshNames(elem, mMesh); - // submesh extremes - elem = rootElem->FirstChildElement("extremes"); - if (elem) - readExtremes(elem, mMesh); + // submesh extremes + elem = rootElem->FirstChildElement("extremes"); + if (elem) + readExtremes(elem, mMesh); - // poses - elem = rootElem->FirstChildElement("poses"); - if (elem) - readPoses(elem, mMesh); + // poses + elem = rootElem->FirstChildElement("poses"); + if (elem) + readPoses(elem, mMesh); - // animations - elem = rootElem->FirstChildElement("animations"); - if (elem) - readAnimations(elem, mMesh); + // animations + elem = rootElem->FirstChildElement("animations"); + if (elem) + readAnimations(elem, mMesh); - delete mXMLDoc; + delete mXMLDoc; LogManager::getSingleton().logMessage("XMLMeshSerializer import successful."); @@ -160,12 +160,12 @@ namespace Ogre { { TiXmlElement* rootNode = mXMLDoc->RootElement(); // Write geometry - if (pMesh->sharedVertexData) - { - TiXmlElement* geomNode = - rootNode->InsertEndChild(TiXmlElement("sharedgeometry"))->ToElement(); - writeGeometry(geomNode, pMesh->sharedVertexData); - } + if (pMesh->sharedVertexData) + { + TiXmlElement* geomNode = + rootNode->InsertEndChild(TiXmlElement("sharedgeometry"))->ToElement(); + writeGeometry(geomNode, pMesh->sharedVertexData); + } // Write Submeshes TiXmlElement* subMeshesNode = @@ -195,25 +195,25 @@ namespace Ogre { while (bi.hasMoreElements()) { - const VertexBoneAssignment& assign = bi.getNext(); + const VertexBoneAssignment& assign = bi.getNext(); writeBoneAssignment(boneAssignNode, &assign); } LogManager::getSingleton().logMessage("Shared geometry bone assignments exported."); } } - if (pMesh->getNumLodLevels() > 1) - { + if (pMesh->getNumLodLevels() > 1) + { LogManager::getSingleton().logMessage("Exporting LOD information..."); - writeLodInfo(rootNode, pMesh); + writeLodInfo(rootNode, pMesh); LogManager::getSingleton().logMessage("LOD information exported."); - } + } // Write submesh names writeSubMeshNames(rootNode, pMesh); - // Write poses - writePoses(rootNode, pMesh); - // Write animations - writeAnimations(rootNode, pMesh); + // Write poses + writePoses(rootNode, pMesh); + // Write animations + writeAnimations(rootNode, pMesh); // Write extremes writeExtremes(rootNode, pMesh); } @@ -231,8 +231,8 @@ namespace Ogre { subMeshNode->SetAttribute("usesharedvertices", StringConverter::toString(s->useSharedVertices) ); // bool use32BitIndexes - bool use32BitIndexes = (!s->indexData->indexBuffer.isNull() && - s->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT); + bool use32BitIndexes = (!s->indexData->indexBuffer.isNull() && + s->indexData->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT); subMeshNode->SetAttribute("use32bitindexes", StringConverter::toString( use32BitIndexes )); @@ -265,76 +265,76 @@ namespace Ogre { TiXmlElement* facesNode = subMeshNode->InsertEndChild(TiXmlElement("faces"))->ToElement(); switch(s->operationType) - { - case RenderOperation::OT_TRIANGLE_LIST: - // tri list - numFaces = s->indexData->indexCount / 3; - - break; - case RenderOperation::OT_LINE_LIST: - numFaces = s->indexData->indexCount / 2; - - break; - case RenderOperation::OT_TRIANGLE_FAN: - case RenderOperation::OT_TRIANGLE_STRIP: - // triangle fan or triangle strip - numFaces = s->indexData->indexCount - 2; - - break; - default: - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, - "Unsupported render operation type", - __FUNCTION__); - } + { + case RenderOperation::OT_TRIANGLE_LIST: + // tri list + numFaces = s->indexData->indexCount / 3; + + break; + case RenderOperation::OT_LINE_LIST: + numFaces = s->indexData->indexCount / 2; + + break; + case RenderOperation::OT_TRIANGLE_FAN: + case RenderOperation::OT_TRIANGLE_STRIP: + // triangle fan or triangle strip + numFaces = s->indexData->indexCount - 2; + + break; + default: + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, + "Unsupported render operation type", + __FUNCTION__); + } facesNode->SetAttribute("count", StringConverter::toString(numFaces)); // Write each face in turn size_t i; - unsigned int* pInt = 0; - unsigned short* pShort = 0; - HardwareIndexBufferSharedPtr ibuf = s->indexData->indexBuffer; - if (use32BitIndexes) - { - pInt = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - } - else - { - pShort = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - } + unsigned int* pInt = 0; + unsigned short* pShort = 0; + HardwareIndexBufferSharedPtr ibuf = s->indexData->indexBuffer; + if (use32BitIndexes) + { + pInt = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + } + else + { + pShort = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + } for (i = 0; i < numFaces; ++i) { TiXmlElement* faceNode = facesNode->InsertEndChild(TiXmlElement("face"))->ToElement(); - if (use32BitIndexes) - { - faceNode->SetAttribute("v1", StringConverter::toString(*pInt++)); - if(s->operationType == RenderOperation::OT_LINE_LIST) - { - faceNode->SetAttribute("v2", StringConverter::toString(*pInt++)); - } + if (use32BitIndexes) + { + faceNode->SetAttribute("v1", StringConverter::toString(*pInt++)); + if(s->operationType == RenderOperation::OT_LINE_LIST) + { + faceNode->SetAttribute("v2", StringConverter::toString(*pInt++)); + } /// Only need all 3 vertex indices if trilist or first face - else if (s->operationType == RenderOperation::OT_TRIANGLE_LIST || i == 0) + else if (s->operationType == RenderOperation::OT_TRIANGLE_LIST || i == 0) + { + faceNode->SetAttribute("v2", StringConverter::toString(*pInt++)); + faceNode->SetAttribute("v3", StringConverter::toString(*pInt++)); + } + } + else + { + faceNode->SetAttribute("v1", StringConverter::toString(*pShort++)); + if(s->operationType == RenderOperation::OT_LINE_LIST) { - faceNode->SetAttribute("v2", StringConverter::toString(*pInt++)); - faceNode->SetAttribute("v3", StringConverter::toString(*pInt++)); + faceNode->SetAttribute("v2", StringConverter::toString(*pShort++)); } - } - else - { - faceNode->SetAttribute("v1", StringConverter::toString(*pShort++)); - if(s->operationType == RenderOperation::OT_LINE_LIST) - { - faceNode->SetAttribute("v2", StringConverter::toString(*pShort++)); - } /// Only need all 3 vertex indices if trilist or first face else if (s->operationType == RenderOperation::OT_TRIANGLE_LIST || i == 0) { - faceNode->SetAttribute("v2", StringConverter::toString(*pShort++)); - faceNode->SetAttribute("v3", StringConverter::toString(*pShort++)); + faceNode->SetAttribute("v2", StringConverter::toString(*pShort++)); + faceNode->SetAttribute("v3", StringConverter::toString(*pShort++)); } - } + } } } @@ -359,7 +359,7 @@ namespace Ogre { subMeshNode->InsertEndChild(TiXmlElement("boneassignments"))->ToElement(); while (bi.hasMoreElements()) { - const VertexBoneAssignment& assign = bi.getNext(); + const VertexBoneAssignment& assign = bi.getNext(); writeBoneAssignment(boneAssignNode, &assign); } } @@ -376,104 +376,104 @@ namespace Ogre { // Set num verts on parent mParentNode->SetAttribute("vertexcount", StringConverter::toString(vertexData->vertexCount)); - VertexDeclaration* decl = vertexData->vertexDeclaration; - VertexBufferBinding* bind = vertexData->vertexBufferBinding; - - VertexBufferBinding::VertexBufferBindingMap::const_iterator b, bend; - bend = bind->getBindings().end(); - // Iterate over buffers - for(b = bind->getBindings().begin(); b != bend; ++b) - { - vbNode = mParentNode->InsertEndChild(TiXmlElement("vertexbuffer"))->ToElement(); - const HardwareVertexBufferSharedPtr vbuf = b->second; - unsigned short bufferIdx = b->first; - // Get all the elements that relate to this buffer - VertexDeclaration::VertexElementList elems = decl->findElementsBySource(bufferIdx); - VertexDeclaration::VertexElementList::iterator i, iend; - iend = elems.end(); - - // Set up the data access for this buffer (lock read-only) - unsigned char* pVert; - float* pFloat; - uint16* pShort; - uint8* pChar; - ARGB* pColour; - - pVert = static_cast( - vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + VertexDeclaration* decl = vertexData->vertexDeclaration; + VertexBufferBinding* bind = vertexData->vertexBufferBinding; + + VertexBufferBinding::VertexBufferBindingMap::const_iterator b, bend; + bend = bind->getBindings().end(); + // Iterate over buffers + for(b = bind->getBindings().begin(); b != bend; ++b) + { + vbNode = mParentNode->InsertEndChild(TiXmlElement("vertexbuffer"))->ToElement(); + const HardwareVertexBufferSharedPtr vbuf = b->second; + unsigned short bufferIdx = b->first; + // Get all the elements that relate to this buffer + VertexDeclaration::VertexElementList elems = decl->findElementsBySource(bufferIdx); + VertexDeclaration::VertexElementList::iterator i, iend; + iend = elems.end(); + + // Set up the data access for this buffer (lock read-only) + unsigned char* pVert; + float* pFloat; + uint16* pShort; + uint8* pChar; + ARGB* pColour; + + pVert = static_cast( + vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); // Skim over the elements to set up the general data unsigned short numTextureCoords = 0; - for (i = elems.begin(); i != iend; ++i) - { - VertexElement& elem = *i; - switch(elem.getSemantic()) - { - case VES_POSITION: - vbNode->SetAttribute("positions","true"); + for (i = elems.begin(); i != iend; ++i) + { + VertexElement& elem = *i; + switch(elem.getSemantic()) + { + case VES_POSITION: + vbNode->SetAttribute("positions","true"); + break; + case VES_NORMAL: + vbNode->SetAttribute("normals","true"); + break; + case VES_TANGENT: + vbNode->SetAttribute("tangents","true"); + if (elem.getType() == VET_FLOAT4) + { + vbNode->SetAttribute("tangent_dimensions", "4"); + } break; - case VES_NORMAL: - vbNode->SetAttribute("normals","true"); + case VES_BINORMAL: + vbNode->SetAttribute("binormals","true"); break; - case VES_TANGENT: - vbNode->SetAttribute("tangents","true"); - if (elem.getType() == VET_FLOAT4) - { - vbNode->SetAttribute("tangent_dimensions", "4"); - } - break; - case VES_BINORMAL: - vbNode->SetAttribute("binormals","true"); - break; - case VES_DIFFUSE: - vbNode->SetAttribute("colours_diffuse","true"); + case VES_DIFFUSE: + vbNode->SetAttribute("colours_diffuse","true"); break; - case VES_SPECULAR: - vbNode->SetAttribute("colours_specular","true"); + case VES_SPECULAR: + vbNode->SetAttribute("colours_specular","true"); break; case VES_TEXTURE_COORDINATES: - { - const char *type = "float2"; - switch (elem.getType()) - { - case VET_FLOAT1: - type = "float1"; - break; - case VET_FLOAT2: - type = "float2"; - break; - case VET_FLOAT3: - type = "float3"; - break; - case VET_FLOAT4: - type = "float4"; - break; - case VET_COLOUR: - case VET_COLOUR_ARGB: - case VET_COLOUR_ABGR: - type = "colour"; - break; - case VET_SHORT1: - type = "short1"; - break; - case VET_SHORT2: - type = "short2"; - break; - case VET_SHORT3: - type = "short3"; - break; - case VET_SHORT4: - type = "short4"; - break; - case VET_UBYTE4: - type = "ubyte4"; - break; - } - vbNode->SetAttribute( - "texture_coord_dimensions_" + StringConverter::toString(numTextureCoords), type); - ++numTextureCoords; - } - break; + { + const char *type = "float2"; + switch (elem.getType()) + { + case VET_FLOAT1: + type = "float1"; + break; + case VET_FLOAT2: + type = "float2"; + break; + case VET_FLOAT3: + type = "float3"; + break; + case VET_FLOAT4: + type = "float4"; + break; + case VET_COLOUR: + case VET_COLOUR_ARGB: + case VET_COLOUR_ABGR: + type = "colour"; + break; + case VET_SHORT1: + type = "short1"; + break; + case VET_SHORT2: + type = "short2"; + break; + case VET_SHORT3: + type = "short3"; + break; + case VET_SHORT4: + type = "short4"; + break; + case VET_UBYTE4: + type = "ubyte4"; + break; + } + vbNode->SetAttribute( + "texture_coord_dimensions_" + StringConverter::toString(numTextureCoords), type); + ++numTextureCoords; + } + break; default: break; @@ -485,161 +485,161 @@ namespace Ogre { StringConverter::toString(numTextureCoords)); } - // For each vertex - for (size_t v = 0; v < vertexData->vertexCount; ++v) - { + // For each vertex + for (size_t v = 0; v < vertexData->vertexCount; ++v) + { vertexNode = vbNode->InsertEndChild(TiXmlElement("vertex"))->ToElement(); - // Iterate over the elements - for (i = elems.begin(); i != iend; ++i) - { - VertexElement& elem = *i; - switch(elem.getSemantic()) - { - case VES_POSITION: - elem.baseVertexPointerToElement(pVert, &pFloat); - dataNode = - vertexNode->InsertEndChild(TiXmlElement("position"))->ToElement(); - dataNode->SetAttribute("x", StringConverter::toString(pFloat[0])); - dataNode->SetAttribute("y", StringConverter::toString(pFloat[1])); - dataNode->SetAttribute("z", StringConverter::toString(pFloat[2])); - break; - case VES_NORMAL: - elem.baseVertexPointerToElement(pVert, &pFloat); - dataNode = - vertexNode->InsertEndChild(TiXmlElement("normal"))->ToElement(); - dataNode->SetAttribute("x", StringConverter::toString(pFloat[0])); - dataNode->SetAttribute("y", StringConverter::toString(pFloat[1])); - dataNode->SetAttribute("z", StringConverter::toString(pFloat[2])); - break; - case VES_TANGENT: - elem.baseVertexPointerToElement(pVert, &pFloat); - dataNode = - vertexNode->InsertEndChild(TiXmlElement("tangent"))->ToElement(); - dataNode->SetAttribute("x", StringConverter::toString(pFloat[0])); - dataNode->SetAttribute("y", StringConverter::toString(pFloat[1])); - dataNode->SetAttribute("z", StringConverter::toString(pFloat[2])); - if (elem.getType() == VET_FLOAT4) - { - dataNode->SetAttribute("w", StringConverter::toString(pFloat[3])); - } - break; - case VES_BINORMAL: - elem.baseVertexPointerToElement(pVert, &pFloat); - dataNode = - vertexNode->InsertEndChild(TiXmlElement("binormal"))->ToElement(); - dataNode->SetAttribute("x", StringConverter::toString(pFloat[0])); - dataNode->SetAttribute("y", StringConverter::toString(pFloat[1])); - dataNode->SetAttribute("z", StringConverter::toString(pFloat[2])); - break; - case VES_DIFFUSE: - elem.baseVertexPointerToElement(pVert, &pColour); - dataNode = - vertexNode->InsertEndChild(TiXmlElement("colour_diffuse"))->ToElement(); - { - ARGB rc = *pColour++; - ColourValue cv; - cv.b = (rc & 0xFF) / 255.0f; rc >>= 8; - cv.g = (rc & 0xFF) / 255.0f; rc >>= 8; - cv.r = (rc & 0xFF) / 255.0f; rc >>= 8; - cv.a = (rc & 0xFF) / 255.0f; + // Iterate over the elements + for (i = elems.begin(); i != iend; ++i) + { + VertexElement& elem = *i; + switch(elem.getSemantic()) + { + case VES_POSITION: + elem.baseVertexPointerToElement(pVert, &pFloat); + dataNode = + vertexNode->InsertEndChild(TiXmlElement("position"))->ToElement(); + dataNode->SetAttribute("x", StringConverter::toString(pFloat[0])); + dataNode->SetAttribute("y", StringConverter::toString(pFloat[1])); + dataNode->SetAttribute("z", StringConverter::toString(pFloat[2])); + break; + case VES_NORMAL: + elem.baseVertexPointerToElement(pVert, &pFloat); + dataNode = + vertexNode->InsertEndChild(TiXmlElement("normal"))->ToElement(); + dataNode->SetAttribute("x", StringConverter::toString(pFloat[0])); + dataNode->SetAttribute("y", StringConverter::toString(pFloat[1])); + dataNode->SetAttribute("z", StringConverter::toString(pFloat[2])); + break; + case VES_TANGENT: + elem.baseVertexPointerToElement(pVert, &pFloat); + dataNode = + vertexNode->InsertEndChild(TiXmlElement("tangent"))->ToElement(); + dataNode->SetAttribute("x", StringConverter::toString(pFloat[0])); + dataNode->SetAttribute("y", StringConverter::toString(pFloat[1])); + dataNode->SetAttribute("z", StringConverter::toString(pFloat[2])); + if (elem.getType() == VET_FLOAT4) + { + dataNode->SetAttribute("w", StringConverter::toString(pFloat[3])); + } + break; + case VES_BINORMAL: + elem.baseVertexPointerToElement(pVert, &pFloat); + dataNode = + vertexNode->InsertEndChild(TiXmlElement("binormal"))->ToElement(); + dataNode->SetAttribute("x", StringConverter::toString(pFloat[0])); + dataNode->SetAttribute("y", StringConverter::toString(pFloat[1])); + dataNode->SetAttribute("z", StringConverter::toString(pFloat[2])); + break; + case VES_DIFFUSE: + elem.baseVertexPointerToElement(pVert, &pColour); + dataNode = + vertexNode->InsertEndChild(TiXmlElement("colour_diffuse"))->ToElement(); + { + ARGB rc = *pColour++; + ColourValue cv; + cv.b = (rc & 0xFF) / 255.0f; rc >>= 8; + cv.g = (rc & 0xFF) / 255.0f; rc >>= 8; + cv.r = (rc & 0xFF) / 255.0f; rc >>= 8; + cv.a = (rc & 0xFF) / 255.0f; + dataNode->SetAttribute("value", StringConverter::toString(cv)); + } + break; + case VES_SPECULAR: + elem.baseVertexPointerToElement(pVert, &pColour); + dataNode = + vertexNode->InsertEndChild(TiXmlElement("colour_specular"))->ToElement(); + { + ARGB rc = *pColour++; + ColourValue cv; + cv.b = (rc & 0xFF) / 255.0f; rc >>= 8; + cv.g = (rc & 0xFF) / 255.0f; rc >>= 8; + cv.r = (rc & 0xFF) / 255.0f; rc >>= 8; + cv.a = (rc & 0xFF) / 255.0f; dataNode->SetAttribute("value", StringConverter::toString(cv)); - } - break; - case VES_SPECULAR: - elem.baseVertexPointerToElement(pVert, &pColour); - dataNode = - vertexNode->InsertEndChild(TiXmlElement("colour_specular"))->ToElement(); - { - ARGB rc = *pColour++; - ColourValue cv; - cv.b = (rc & 0xFF) / 255.0f; rc >>= 8; - cv.g = (rc & 0xFF) / 255.0f; rc >>= 8; - cv.r = (rc & 0xFF) / 255.0f; rc >>= 8; - cv.a = (rc & 0xFF) / 255.0f; - dataNode->SetAttribute("value", StringConverter::toString(cv)); - } - break; - case VES_TEXTURE_COORDINATES: - dataNode = - vertexNode->InsertEndChild(TiXmlElement("texcoord"))->ToElement(); - - switch(elem.getType()) + } + break; + case VES_TEXTURE_COORDINATES: + dataNode = + vertexNode->InsertEndChild(TiXmlElement("texcoord"))->ToElement(); + + switch(elem.getType()) { case VET_FLOAT1: elem.baseVertexPointerToElement(pVert, &pFloat); - dataNode->SetAttribute("u", StringConverter::toString(*pFloat++)); + dataNode->SetAttribute("u", StringConverter::toString(*pFloat++)); break; case VET_FLOAT2: elem.baseVertexPointerToElement(pVert, &pFloat); - dataNode->SetAttribute("u", StringConverter::toString(*pFloat++)); - dataNode->SetAttribute("v", StringConverter::toString(*pFloat++)); + dataNode->SetAttribute("u", StringConverter::toString(*pFloat++)); + dataNode->SetAttribute("v", StringConverter::toString(*pFloat++)); break; case VET_FLOAT3: elem.baseVertexPointerToElement(pVert, &pFloat); - dataNode->SetAttribute("u", StringConverter::toString(*pFloat++)); - dataNode->SetAttribute("v", StringConverter::toString(*pFloat++)); - dataNode->SetAttribute("w", StringConverter::toString(*pFloat++)); + dataNode->SetAttribute("u", StringConverter::toString(*pFloat++)); + dataNode->SetAttribute("v", StringConverter::toString(*pFloat++)); + dataNode->SetAttribute("w", StringConverter::toString(*pFloat++)); break; case VET_FLOAT4: elem.baseVertexPointerToElement(pVert, &pFloat); - dataNode->SetAttribute("u", StringConverter::toString(*pFloat++)); - dataNode->SetAttribute("v", StringConverter::toString(*pFloat++)); - dataNode->SetAttribute("w", StringConverter::toString(*pFloat++)); - dataNode->SetAttribute("x", StringConverter::toString(*pFloat++)); + dataNode->SetAttribute("u", StringConverter::toString(*pFloat++)); + dataNode->SetAttribute("v", StringConverter::toString(*pFloat++)); + dataNode->SetAttribute("w", StringConverter::toString(*pFloat++)); + dataNode->SetAttribute("x", StringConverter::toString(*pFloat++)); break; case VET_SHORT1: elem.baseVertexPointerToElement(pVert, &pShort); - dataNode->SetAttribute("u", StringConverter::toString(*pShort++ / 65535.0f)); + dataNode->SetAttribute("u", StringConverter::toString(*pShort++ / 65535.0f)); break; case VET_SHORT2: elem.baseVertexPointerToElement(pVert, &pShort); - dataNode->SetAttribute("u", StringConverter::toString(*pShort++ / 65535.0f)); - dataNode->SetAttribute("v", StringConverter::toString(*pShort++ / 65535.0f)); + dataNode->SetAttribute("u", StringConverter::toString(*pShort++ / 65535.0f)); + dataNode->SetAttribute("v", StringConverter::toString(*pShort++ / 65535.0f)); break; case VET_SHORT3: elem.baseVertexPointerToElement(pVert, &pShort); - dataNode->SetAttribute("u", StringConverter::toString(*pShort++ / 65535.0f)); - dataNode->SetAttribute("v", StringConverter::toString(*pShort++ / 65535.0f)); - dataNode->SetAttribute("w", StringConverter::toString(*pShort++ / 65535.0f)); + dataNode->SetAttribute("u", StringConverter::toString(*pShort++ / 65535.0f)); + dataNode->SetAttribute("v", StringConverter::toString(*pShort++ / 65535.0f)); + dataNode->SetAttribute("w", StringConverter::toString(*pShort++ / 65535.0f)); break; case VET_SHORT4: elem.baseVertexPointerToElement(pVert, &pShort); - dataNode->SetAttribute("u", StringConverter::toString(*pShort++ / 65535.0f)); - dataNode->SetAttribute("v", StringConverter::toString(*pShort++ / 65535.0f)); - dataNode->SetAttribute("w", StringConverter::toString(*pShort++ / 65535.0f)); - dataNode->SetAttribute("x", StringConverter::toString(*pShort++ / 65535.0f)); + dataNode->SetAttribute("u", StringConverter::toString(*pShort++ / 65535.0f)); + dataNode->SetAttribute("v", StringConverter::toString(*pShort++ / 65535.0f)); + dataNode->SetAttribute("w", StringConverter::toString(*pShort++ / 65535.0f)); + dataNode->SetAttribute("x", StringConverter::toString(*pShort++ / 65535.0f)); break; case VET_COLOUR: case VET_COLOUR_ARGB: case VET_COLOUR_ABGR: elem.baseVertexPointerToElement(pVert, &pColour); { ARGB rc = *pColour++; ColourValue cv; - cv.b = (rc & 0xFF) / 255.0f; rc >>= 8; - cv.g = (rc & 0xFF) / 255.0f; rc >>= 8; - cv.r = (rc & 0xFF) / 255.0f; rc >>= 8; + cv.b = (rc & 0xFF) / 255.0f; rc >>= 8; + cv.g = (rc & 0xFF) / 255.0f; rc >>= 8; + cv.r = (rc & 0xFF) / 255.0f; rc >>= 8; cv.a = (rc & 0xFF) / 255.0f; dataNode->SetAttribute("u", StringConverter::toString(cv)); } break; case VET_UBYTE4: elem.baseVertexPointerToElement(pVert, &pChar); - dataNode->SetAttribute("u", StringConverter::toString(*pChar++ / 255.0f)); - dataNode->SetAttribute("v", StringConverter::toString(*pChar++ / 255.0f)); - dataNode->SetAttribute("w", StringConverter::toString(*pChar++ / 255.0f)); - dataNode->SetAttribute("x", StringConverter::toString(*pChar++ / 255.0f)); + dataNode->SetAttribute("u", StringConverter::toString(*pChar++ / 255.0f)); + dataNode->SetAttribute("v", StringConverter::toString(*pChar++ / 255.0f)); + dataNode->SetAttribute("w", StringConverter::toString(*pChar++ / 255.0f)); + dataNode->SetAttribute("x", StringConverter::toString(*pChar++ / 255.0f)); break; } - break; + break; default: break; - } - } - pVert += vbuf->getVertexSize(); - } - vbuf->unlock(); - } + } + } + pVert += vbuf->getVertexSize(); + } + vbuf->unlock(); + } } //--------------------------------------------------------------------- @@ -693,7 +693,7 @@ namespace Ogre { void XMLMeshSerializer::readSubMeshes(TiXmlElement* mSubmeshesNode) { LogManager::getSingleton().logMessage("Reading submeshes..."); - assert(mMesh->getNumSubMeshes() == 0); + assert(mMesh->getNumSubMeshes() == 0); for (TiXmlElement* smElem = mSubmeshesNode->FirstChildElement(); smElem != 0; smElem = smElem->NextSiblingElement()) { @@ -759,94 +759,94 @@ namespace Ogre { const char *claimedCount_ = faces->Attribute("count"); if (claimedCount_ && StringConverter::parseInt(claimedCount_)!=actualCount) { - LogManager::getSingleton().stream() - << "WARNING: face count (" << actualCount << ") " << - "is not as claimed (" << claimedCount_ << ")"; + LogManager::getSingleton().stream() + << "WARNING: face count (" << actualCount << ") " << + "is not as claimed (" << claimedCount_ << ")"; } if (actualCount > 0) - { - // Faces - switch(sm->operationType) - { - case RenderOperation::OT_TRIANGLE_LIST: - // tri list - sm->indexData->indexCount = actualCount * 3; - - break; - case RenderOperation::OT_LINE_LIST: - sm->indexData->indexCount = actualCount * 2; - - break; - case RenderOperation::OT_TRIANGLE_FAN: - case RenderOperation::OT_TRIANGLE_STRIP: - // triangle fan or triangle strip - sm->indexData->indexCount = actualCount + 2; - - break; - default: - OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "operationType not implemented", - __FUNCTION__); - } - - // Allocate space - HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). - createIndexBuffer( - use32BitIndexes? HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT, - sm->indexData->indexCount, - HardwareBuffer::HBU_DYNAMIC, - false); - sm->indexData->indexBuffer = ibuf; - unsigned int *pInt = 0; - unsigned short *pShort = 0; - if (use32BitIndexes) - { - pInt = static_cast( - ibuf->lock(HardwareBuffer::HBL_DISCARD)); - } - else - { - pShort = static_cast( - ibuf->lock(HardwareBuffer::HBL_DISCARD)); - } - TiXmlElement* faceElem; - bool firstTri = true; - for (faceElem = faces->FirstChildElement(); - faceElem != 0; faceElem = faceElem->NextSiblingElement()) - { - if (use32BitIndexes) - { - *pInt++ = StringConverter::parseInt(faceElem->Attribute("v1")); - if(sm->operationType == RenderOperation::OT_LINE_LIST) - { - *pInt++ = StringConverter::parseInt(faceElem->Attribute("v2")); - } - // only need all 3 vertices if it's a trilist or first tri - else if (sm->operationType == RenderOperation::OT_TRIANGLE_LIST || firstTri) - { - *pInt++ = StringConverter::parseInt(faceElem->Attribute("v2")); - *pInt++ = StringConverter::parseInt(faceElem->Attribute("v3")); - } - } - else - { - *pShort++ = StringConverter::parseInt(faceElem->Attribute("v1")); - if(sm->operationType == RenderOperation::OT_LINE_LIST) - { - *pShort++ = StringConverter::parseInt(faceElem->Attribute("v2")); - } - // only need all 3 vertices if it's a trilist or first tri - else if (sm->operationType == RenderOperation::OT_TRIANGLE_LIST || firstTri) - { - *pShort++ = StringConverter::parseInt(faceElem->Attribute("v2")); - *pShort++ = StringConverter::parseInt(faceElem->Attribute("v3")); - } - } - firstTri = false; - } - ibuf->unlock(); - } + { + // Faces + switch(sm->operationType) + { + case RenderOperation::OT_TRIANGLE_LIST: + // tri list + sm->indexData->indexCount = actualCount * 3; + + break; + case RenderOperation::OT_LINE_LIST: + sm->indexData->indexCount = actualCount * 2; + + break; + case RenderOperation::OT_TRIANGLE_FAN: + case RenderOperation::OT_TRIANGLE_STRIP: + // triangle fan or triangle strip + sm->indexData->indexCount = actualCount + 2; + + break; + default: + OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "operationType not implemented", + __FUNCTION__); + } + + // Allocate space + HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). + createIndexBuffer( + use32BitIndexes? HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT, + sm->indexData->indexCount, + HardwareBuffer::HBU_DYNAMIC, + false); + sm->indexData->indexBuffer = ibuf; + unsigned int *pInt = 0; + unsigned short *pShort = 0; + if (use32BitIndexes) + { + pInt = static_cast( + ibuf->lock(HardwareBuffer::HBL_DISCARD)); + } + else + { + pShort = static_cast( + ibuf->lock(HardwareBuffer::HBL_DISCARD)); + } + TiXmlElement* faceElem; + bool firstTri = true; + for (faceElem = faces->FirstChildElement(); + faceElem != 0; faceElem = faceElem->NextSiblingElement()) + { + if (use32BitIndexes) + { + *pInt++ = StringConverter::parseInt(faceElem->Attribute("v1")); + if(sm->operationType == RenderOperation::OT_LINE_LIST) + { + *pInt++ = StringConverter::parseInt(faceElem->Attribute("v2")); + } + // only need all 3 vertices if it's a trilist or first tri + else if (sm->operationType == RenderOperation::OT_TRIANGLE_LIST || firstTri) + { + *pInt++ = StringConverter::parseInt(faceElem->Attribute("v2")); + *pInt++ = StringConverter::parseInt(faceElem->Attribute("v3")); + } + } + else + { + *pShort++ = StringConverter::parseInt(faceElem->Attribute("v1")); + if(sm->operationType == RenderOperation::OT_LINE_LIST) + { + *pShort++ = StringConverter::parseInt(faceElem->Attribute("v2")); + } + // only need all 3 vertices if it's a trilist or first tri + else if (sm->operationType == RenderOperation::OT_TRIANGLE_LIST || firstTri) + { + *pShort++ = StringConverter::parseInt(faceElem->Attribute("v2")); + *pShort++ = StringConverter::parseInt(faceElem->Attribute("v3")); + } + } + firstTri = false; + } + ibuf->unlock(); + } } // Geometry @@ -926,29 +926,29 @@ namespace Ogre { decl->addElement(bufCount, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); } - attrib = vbElem->Attribute("tangents"); - if (attrib && StringConverter::parseBool(attrib)) - { - VertexElementType tangentType = VET_FLOAT3; - attrib = vbElem->Attribute("tangent_dimensions"); - if (attrib) - { - unsigned int dims = StringConverter::parseUnsignedInt(attrib); - if (dims == 4) - tangentType = VET_FLOAT4; - } - - // Add element - decl->addElement(bufCount, offset, tangentType, VES_TANGENT); - offset += VertexElement::getTypeSize(tangentType); - } - attrib = vbElem->Attribute("binormals"); - if (attrib && StringConverter::parseBool(attrib)) - { - // Add element - decl->addElement(bufCount, offset, VET_FLOAT3, VES_BINORMAL); - offset += VertexElement::getTypeSize(VET_FLOAT3); - } + attrib = vbElem->Attribute("tangents"); + if (attrib && StringConverter::parseBool(attrib)) + { + VertexElementType tangentType = VET_FLOAT3; + attrib = vbElem->Attribute("tangent_dimensions"); + if (attrib) + { + unsigned int dims = StringConverter::parseUnsignedInt(attrib); + if (dims == 4) + tangentType = VET_FLOAT4; + } + + // Add element + decl->addElement(bufCount, offset, tangentType, VES_TANGENT); + offset += VertexElement::getTypeSize(tangentType); + } + attrib = vbElem->Attribute("binormals"); + if (attrib && StringConverter::parseBool(attrib)) + { + // Add element + decl->addElement(bufCount, offset, VET_FLOAT3, VES_BINORMAL); + offset += VertexElement::getTypeSize(VET_FLOAT3); + } attrib = vbElem->Attribute("colours_diffuse"); if (attrib && StringConverter::parseBool(attrib)) { @@ -971,54 +971,54 @@ namespace Ogre { { // NB set is local to this buffer, but will be translated into a // global set number across all vertex buffers - StringStream str; - str << "texture_coord_dimensions_" << tx; + StringStream str; + str << "texture_coord_dimensions_" << tx; attrib = vbElem->Attribute(str.str().c_str()); VertexElementType vtype = VET_FLOAT2; // Default - if (attrib) - { - if (!::strcmp(attrib,"1")) - vtype = VET_FLOAT1; - else if (!::strcmp(attrib,"2")) - vtype = VET_FLOAT2; - else if (!::strcmp(attrib,"3")) - vtype = VET_FLOAT3; - else if (!::strcmp(attrib,"4")) - vtype = VET_FLOAT4; - else if (!::strcmp(attrib,"float1")) - vtype = VET_FLOAT1; - else if (!::strcmp(attrib,"float2")) - vtype = VET_FLOAT2; - else if (!::strcmp(attrib,"float3")) - vtype = VET_FLOAT3; - else if (!::strcmp(attrib,"float4")) - vtype = VET_FLOAT4; - else if (!::strcmp(attrib,"short1")) - vtype = VET_SHORT1; - else if (!::strcmp(attrib,"short2")) - vtype = VET_SHORT2; - else if (!::strcmp(attrib,"short3")) - vtype = VET_SHORT3; - else if (!::strcmp(attrib,"short4")) - vtype = VET_SHORT4; - else if (!::strcmp(attrib,"ubyte4")) - vtype = VET_UBYTE4; - else if (!::strcmp(attrib,"colour")) - vtype = VET_COLOUR; - else if (!::strcmp(attrib,"colour_argb")) - vtype = VET_COLOUR_ARGB; - else if (!::strcmp(attrib,"colour_abgr")) - vtype = VET_COLOUR_ABGR; - else - { - std::cerr << "ERROR: Did not recognise texture_coord_dimensions value of \""<addElement(bufCount, offset, vtype, - VES_TEXTURE_COORDINATES, totalTexCoords++); - offset += VertexElement::getTypeSize(vtype); + if (attrib) + { + if (!::strcmp(attrib,"1")) + vtype = VET_FLOAT1; + else if (!::strcmp(attrib,"2")) + vtype = VET_FLOAT2; + else if (!::strcmp(attrib,"3")) + vtype = VET_FLOAT3; + else if (!::strcmp(attrib,"4")) + vtype = VET_FLOAT4; + else if (!::strcmp(attrib,"float1")) + vtype = VET_FLOAT1; + else if (!::strcmp(attrib,"float2")) + vtype = VET_FLOAT2; + else if (!::strcmp(attrib,"float3")) + vtype = VET_FLOAT3; + else if (!::strcmp(attrib,"float4")) + vtype = VET_FLOAT4; + else if (!::strcmp(attrib,"short1")) + vtype = VET_SHORT1; + else if (!::strcmp(attrib,"short2")) + vtype = VET_SHORT2; + else if (!::strcmp(attrib,"short3")) + vtype = VET_SHORT3; + else if (!::strcmp(attrib,"short4")) + vtype = VET_SHORT4; + else if (!::strcmp(attrib,"ubyte4")) + vtype = VET_UBYTE4; + else if (!::strcmp(attrib,"colour")) + vtype = VET_COLOUR; + else if (!::strcmp(attrib,"colour_argb")) + vtype = VET_COLOUR_ARGB; + else if (!::strcmp(attrib,"colour_abgr")) + vtype = VET_COLOUR_ABGR; + else + { + std::cerr << "ERROR: Did not recognise texture_coord_dimensions value of \""<addElement(bufCount, offset, vtype, + VES_TEXTURE_COORDINATES, totalTexCoords++); + offset += VertexElement::getTypeSize(vtype); } } @@ -1030,9 +1030,9 @@ namespace Ogre { } if (claimedVertexCount_ && actualVertexCount!=claimedVertexCount) { - LogManager::getSingleton().stream() - << "WARNING: vertex count (" << actualVertexCount - << ") is not as claimed (" << claimedVertexCount_ << ")"; + LogManager::getSingleton().stream() + << "WARNING: vertex count (" << actualVertexCount + << ") is not as claimed (" << claimedVertexCount_ << ")"; } vertexData->vertexCount = actualVertexCount; @@ -1115,43 +1115,43 @@ namespace Ogre { *pFloat++ = StringConverter::parseReal( xmlElem->Attribute("z")); break; - case VES_TANGENT: - xmlElem = vertexElem->FirstChildElement("tangent"); - if (!xmlElem) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing element.", - "XMLSerializer::readGeometry"); - } - elem.baseVertexPointerToElement(pVert, &pFloat); - - *pFloat++ = StringConverter::parseReal( - xmlElem->Attribute("x")); - *pFloat++ = StringConverter::parseReal( - xmlElem->Attribute("y")); - *pFloat++ = StringConverter::parseReal( - xmlElem->Attribute("z")); - if (elem.getType() == VET_FLOAT4) - { - *pFloat++ = StringConverter::parseReal( - xmlElem->Attribute("w")); - } - break; - case VES_BINORMAL: - xmlElem = vertexElem->FirstChildElement("binormal"); - if (!xmlElem) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing element.", - "XMLSerializer::readGeometry"); - } - elem.baseVertexPointerToElement(pVert, &pFloat); - - *pFloat++ = StringConverter::parseReal( - xmlElem->Attribute("x")); - *pFloat++ = StringConverter::parseReal( - xmlElem->Attribute("y")); - *pFloat++ = StringConverter::parseReal( - xmlElem->Attribute("z")); - break; + case VES_TANGENT: + xmlElem = vertexElem->FirstChildElement("tangent"); + if (!xmlElem) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing element.", + "XMLSerializer::readGeometry"); + } + elem.baseVertexPointerToElement(pVert, &pFloat); + + *pFloat++ = StringConverter::parseReal( + xmlElem->Attribute("x")); + *pFloat++ = StringConverter::parseReal( + xmlElem->Attribute("y")); + *pFloat++ = StringConverter::parseReal( + xmlElem->Attribute("z")); + if (elem.getType() == VET_FLOAT4) + { + *pFloat++ = StringConverter::parseReal( + xmlElem->Attribute("w")); + } + break; + case VES_BINORMAL: + xmlElem = vertexElem->FirstChildElement("binormal"); + if (!xmlElem) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing element.", + "XMLSerializer::readGeometry"); + } + elem.baseVertexPointerToElement(pVert, &pFloat); + + *pFloat++ = StringConverter::parseReal( + xmlElem->Attribute("x")); + *pFloat++ = StringConverter::parseReal( + xmlElem->Attribute("y")); + *pFloat++ = StringConverter::parseReal( + xmlElem->Attribute("z")); + break; case VES_DIFFUSE: xmlElem = vertexElem->FirstChildElement("colour_diffuse"); if (!xmlElem) @@ -1160,12 +1160,12 @@ namespace Ogre { "XMLSerializer::readGeometry"); } elem.baseVertexPointerToElement(pVert, &pCol); - { - ColourValue cv; - cv = StringConverter::parseColourValue( - xmlElem->Attribute("value")); - *pCol++ = VertexElement::convertColourValue(cv, mColourElementType); - } + { + ColourValue cv; + cv = StringConverter::parseColourValue( + xmlElem->Attribute("value")); + *pCol++ = VertexElement::convertColourValue(cv, mColourElementType); + } break; case VES_SPECULAR: xmlElem = vertexElem->FirstChildElement("colour_specular"); @@ -1175,12 +1175,12 @@ namespace Ogre { "XMLSerializer::readGeometry"); } elem.baseVertexPointerToElement(pVert, &pCol); - { - ColourValue cv; - cv = StringConverter::parseColourValue( - xmlElem->Attribute("value")); - *pCol++ = VertexElement::convertColourValue(cv, mColourElementType); - } + { + ColourValue cv; + cv = StringConverter::parseColourValue( + xmlElem->Attribute("value")); + *pCol++ = VertexElement::convertColourValue(cv, mColourElementType); + } break; case VES_TEXTURE_COORDINATES: if (!texCoordElem) @@ -1198,123 +1198,123 @@ namespace Ogre { OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing element.", "XMLSerializer::readGeometry"); } - // Record the latest texture coord entry - texCoordElem = xmlElem; + // Record the latest texture coord entry + texCoordElem = xmlElem; if (!xmlElem->Attribute("u")) OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'u' attribute not found.", "XMLMeshSerializer::readGeometry"); // depending on type, pack appropriately, can process colour channels separately which is a bonus - switch (elem.getType()) - { - case VET_FLOAT1: - elem.baseVertexPointerToElement(pVert, &pFloat); - *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("u")); - break; - - case VET_FLOAT2: - if (!xmlElem->Attribute("v")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); - elem.baseVertexPointerToElement(pVert, &pFloat); - *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("u")); - *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("v")); - break; - - case VET_FLOAT3: - if (!xmlElem->Attribute("v")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); - if (!xmlElem->Attribute("w")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'w' attribute not found.", "XMLMeshSerializer::readGeometry"); - elem.baseVertexPointerToElement(pVert, &pFloat); - *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("u")); - *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("v")); - *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("w")); - break; - - case VET_FLOAT4: - if (!xmlElem->Attribute("v")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); - if (!xmlElem->Attribute("w")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'w' attribute not found.", "XMLMeshSerializer::readGeometry"); - if (!xmlElem->Attribute("x")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'x' attribute not found.", "XMLMeshSerializer::readGeometry"); - elem.baseVertexPointerToElement(pVert, &pFloat); - *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("u")); - *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("v")); - *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("w")); - *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("x")); - break; - - case VET_SHORT1: - elem.baseVertexPointerToElement(pVert, &pShort); - *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("u"))); - break; - - case VET_SHORT2: - if (!xmlElem->Attribute("v")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); - elem.baseVertexPointerToElement(pVert, &pShort); - *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("u"))); - *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("v"))); - break; - - case VET_SHORT3: - if (!xmlElem->Attribute("v")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); - if (!xmlElem->Attribute("w")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'w' attribute not found.", "XMLMeshSerializer::readGeometry"); - elem.baseVertexPointerToElement(pVert, &pShort); - *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("u"))); - *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("v"))); - *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("w"))); - break; - - case VET_SHORT4: - if (!xmlElem->Attribute("v")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); - if (!xmlElem->Attribute("w")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'w' attribute not found.", "XMLMeshSerializer::readGeometry"); - if (!xmlElem->Attribute("x")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'x' attribute not found.", "XMLMeshSerializer::readGeometry"); - elem.baseVertexPointerToElement(pVert, &pShort); - *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("u"))); - *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("v"))); - *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("w"))); - *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("x"))); - break; - - case VET_UBYTE4: - if (!xmlElem->Attribute("v")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); - if (!xmlElem->Attribute("w")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'w' attribute not found.", "XMLMeshSerializer::readGeometry"); - if (!xmlElem->Attribute("x")) - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'x' attribute not found.", "XMLMeshSerializer::readGeometry"); - elem.baseVertexPointerToElement(pVert, &pChar); - // round off instead of just truncating -- avoids magnifying rounding errors - *pChar++ = static_cast(0.5f + 255.0f * StringConverter::parseReal(xmlElem->Attribute("u"))); - *pChar++ = static_cast(0.5f + 255.0f * StringConverter::parseReal(xmlElem->Attribute("v"))); - *pChar++ = static_cast(0.5f + 255.0f * StringConverter::parseReal(xmlElem->Attribute("w"))); - *pChar++ = static_cast(0.5f + 255.0f * StringConverter::parseReal(xmlElem->Attribute("x"))); - break; - - case VET_COLOUR: - { - elem.baseVertexPointerToElement(pVert, &pCol); - ColourValue cv = StringConverter::parseColourValue(xmlElem->Attribute("u")); - *pCol++ = VertexElement::convertColourValue(cv, mColourElementType); - } - break; - - case VET_COLOUR_ARGB: - case VET_COLOUR_ABGR: - { - elem.baseVertexPointerToElement(pVert, &pCol); - ColourValue cv = StringConverter::parseColourValue(xmlElem->Attribute("u")); - *pCol++ = VertexElement::convertColourValue(cv, elem.getType()); - } - break; - } + switch (elem.getType()) + { + case VET_FLOAT1: + elem.baseVertexPointerToElement(pVert, &pFloat); + *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("u")); + break; + + case VET_FLOAT2: + if (!xmlElem->Attribute("v")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); + elem.baseVertexPointerToElement(pVert, &pFloat); + *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("u")); + *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("v")); + break; + + case VET_FLOAT3: + if (!xmlElem->Attribute("v")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); + if (!xmlElem->Attribute("w")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'w' attribute not found.", "XMLMeshSerializer::readGeometry"); + elem.baseVertexPointerToElement(pVert, &pFloat); + *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("u")); + *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("v")); + *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("w")); + break; + + case VET_FLOAT4: + if (!xmlElem->Attribute("v")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); + if (!xmlElem->Attribute("w")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'w' attribute not found.", "XMLMeshSerializer::readGeometry"); + if (!xmlElem->Attribute("x")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'x' attribute not found.", "XMLMeshSerializer::readGeometry"); + elem.baseVertexPointerToElement(pVert, &pFloat); + *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("u")); + *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("v")); + *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("w")); + *pFloat++ = StringConverter::parseReal(xmlElem->Attribute("x")); + break; + + case VET_SHORT1: + elem.baseVertexPointerToElement(pVert, &pShort); + *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("u"))); + break; + + case VET_SHORT2: + if (!xmlElem->Attribute("v")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); + elem.baseVertexPointerToElement(pVert, &pShort); + *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("u"))); + *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("v"))); + break; + + case VET_SHORT3: + if (!xmlElem->Attribute("v")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); + if (!xmlElem->Attribute("w")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'w' attribute not found.", "XMLMeshSerializer::readGeometry"); + elem.baseVertexPointerToElement(pVert, &pShort); + *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("u"))); + *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("v"))); + *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("w"))); + break; + + case VET_SHORT4: + if (!xmlElem->Attribute("v")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); + if (!xmlElem->Attribute("w")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'w' attribute not found.", "XMLMeshSerializer::readGeometry"); + if (!xmlElem->Attribute("x")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'x' attribute not found.", "XMLMeshSerializer::readGeometry"); + elem.baseVertexPointerToElement(pVert, &pShort); + *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("u"))); + *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("v"))); + *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("w"))); + *pShort++ = static_cast(65535.0f * StringConverter::parseReal(xmlElem->Attribute("x"))); + break; + + case VET_UBYTE4: + if (!xmlElem->Attribute("v")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'v' attribute not found.", "XMLMeshSerializer::readGeometry"); + if (!xmlElem->Attribute("w")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'w' attribute not found.", "XMLMeshSerializer::readGeometry"); + if (!xmlElem->Attribute("x")) + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Texcoord 'x' attribute not found.", "XMLMeshSerializer::readGeometry"); + elem.baseVertexPointerToElement(pVert, &pChar); + // round off instead of just truncating -- avoids magnifying rounding errors + *pChar++ = static_cast(0.5f + 255.0f * StringConverter::parseReal(xmlElem->Attribute("u"))); + *pChar++ = static_cast(0.5f + 255.0f * StringConverter::parseReal(xmlElem->Attribute("v"))); + *pChar++ = static_cast(0.5f + 255.0f * StringConverter::parseReal(xmlElem->Attribute("w"))); + *pChar++ = static_cast(0.5f + 255.0f * StringConverter::parseReal(xmlElem->Attribute("x"))); + break; + + case VET_COLOUR: + { + elem.baseVertexPointerToElement(pVert, &pCol); + ColourValue cv = StringConverter::parseColourValue(xmlElem->Attribute("u")); + *pCol++ = VertexElement::convertColourValue(cv, mColourElementType); + } + break; + + case VET_COLOUR_ARGB: + case VET_COLOUR_ABGR: + { + elem.baseVertexPointerToElement(pVert, &pCol); + ColourValue cv = StringConverter::parseColourValue(xmlElem->Attribute("u")); + *pCol++ = VertexElement::convertColourValue(cv, elem.getType()); + } + break; + } break; default: @@ -1332,7 +1332,7 @@ namespace Ogre { Real currRadius = mMesh->getBoundingSphereRadius(); if (currBox.isNull()) { - //do not pad the bounding box + //do not pad the bounding box mMesh->_setBounds(AxisAlignedBox(min, max), false); mMesh->_setBoundingSphereRadius(Math::Sqrt(maxSquaredRadius)); } @@ -1340,7 +1340,7 @@ namespace Ogre { { AxisAlignedBox newBox(min, max); newBox.merge(currBox); - //do not pad the bounding box + //do not pad the bounding box mMesh->_setBounds(newBox, false); mMesh->_setBoundingSphereRadius(std::max(Math::Sqrt(maxSquaredRadius), currRadius)); } @@ -1396,22 +1396,22 @@ namespace Ogre { LogManager::getSingleton().logMessage("Texture aliases done."); } //--------------------------------------------------------------------- - void XMLMeshSerializer::readSubMeshNames(TiXmlElement* mMeshNamesNode, Mesh *sm) - { - LogManager::getSingleton().logMessage("Reading mesh names..."); - - // Iterate over all children (vertexboneassignment entries) - for (TiXmlElement* elem = mMeshNamesNode->FirstChildElement(); - elem != 0; elem = elem->NextSiblingElement()) - { - String meshName = elem->Attribute("name"); - int index = StringConverter::parseInt(elem->Attribute("index")); - - sm->nameSubMesh(meshName, index); - } - - LogManager::getSingleton().logMessage("Mesh names done."); - } + void XMLMeshSerializer::readSubMeshNames(TiXmlElement* mMeshNamesNode, Mesh *sm) + { + LogManager::getSingleton().logMessage("Reading mesh names..."); + + // Iterate over all children (vertexboneassignment entries) + for (TiXmlElement* elem = mMeshNamesNode->FirstChildElement(); + elem != 0; elem = elem->NextSiblingElement()) + { + String meshName = elem->Attribute("name"); + int index = StringConverter::parseInt(elem->Attribute("index")); + + sm->nameSubMesh(meshName, index); + } + + LogManager::getSingleton().logMessage("Mesh names done."); + } //--------------------------------------------------------------------- void XMLMeshSerializer::readBoneAssignments(TiXmlElement* mBoneAssignmentsNode, SubMesh* sm) { @@ -1433,33 +1433,33 @@ namespace Ogre { LogManager::getSingleton().logMessage("Bone assignments done."); } //--------------------------------------------------------------------- - void XMLMeshSerializer::writeLodInfo(TiXmlElement* mMeshNode, const Mesh* pMesh) - { + void XMLMeshSerializer::writeLodInfo(TiXmlElement* mMeshNode, const Mesh* pMesh) + { TiXmlElement* lodNode = mMeshNode->InsertEndChild(TiXmlElement("levelofdetail"))->ToElement(); const LodStrategy *strategy = pMesh->getLodStrategy(); - unsigned short numLvls = pMesh->getNumLodLevels(); - bool manual = pMesh->hasManualLodLevel(); + unsigned short numLvls = pMesh->getNumLodLevels(); + bool manual = pMesh->hasManualLodLevel(); lodNode->SetAttribute("strategy", strategy->getName()); - lodNode->SetAttribute("numlevels", StringConverter::toString(numLvls)); - lodNode->SetAttribute("manual", StringConverter::toString(manual)); - - // Iterate from level 1, not 0 (full detail) - for (unsigned short i = 1; i < numLvls; ++i) - { - const MeshLodUsage& usage = pMesh->getLodLevel(i); - if (pMesh->_isManualLodLevel(i)) - { - writeLodUsageManual(lodNode, i, usage); - } - else - { - writeLodUsageGenerated(lodNode, i, usage, pMesh); - } - } - - } + lodNode->SetAttribute("numlevels", StringConverter::toString(numLvls)); + lodNode->SetAttribute("manual", StringConverter::toString(manual)); + + // Iterate from level 1, not 0 (full detail) + for (unsigned short i = 1; i < numLvls; ++i) + { + const MeshLodUsage& usage = pMesh->getLodLevel(i); + if (pMesh->_isManualLodLevel(i)) + { + writeLodUsageManual(lodNode, i, usage); + } + else + { + writeLodUsageGenerated(lodNode, i, usage, pMesh); + } + } + + } //--------------------------------------------------------------------- void XMLMeshSerializer::writeSubMeshNames(TiXmlElement* mMeshNode, const Mesh* m) { @@ -1483,166 +1483,166 @@ namespace Ogre { } //--------------------------------------------------------------------- - void XMLMeshSerializer::writeLodUsageManual(TiXmlElement* usageNode, - unsigned short levelNum, const MeshLodUsage& usage) - { - TiXmlElement* manualNode = - usageNode->InsertEndChild(TiXmlElement("lodmanual"))->ToElement(); + void XMLMeshSerializer::writeLodUsageManual(TiXmlElement* usageNode, + unsigned short levelNum, const MeshLodUsage& usage) + { + TiXmlElement* manualNode = + usageNode->InsertEndChild(TiXmlElement("lodmanual"))->ToElement(); - manualNode->SetAttribute("value", + manualNode->SetAttribute("value", StringConverter::toString(usage.userValue)); - manualNode->SetAttribute("meshname", usage.manualName); + manualNode->SetAttribute("meshname", usage.manualName); - } - //--------------------------------------------------------------------- - void XMLMeshSerializer::writeLodUsageGenerated(TiXmlElement* usageNode, - unsigned short levelNum, const MeshLodUsage& usage, - const Mesh* pMesh) - { - TiXmlElement* generatedNode = - usageNode->InsertEndChild(TiXmlElement("lodgenerated"))->ToElement(); - generatedNode->SetAttribute("value", - StringConverter::toString(usage.userValue)); - - // Iterate over submeshes at this level - unsigned short numsubs = pMesh->getNumSubMeshes(); - - for (unsigned short subi = 0; subi < numsubs; ++subi) - { - TiXmlElement* subNode = - generatedNode->InsertEndChild(TiXmlElement("lodfacelist"))->ToElement(); - SubMesh* sub = pMesh->getSubMesh(subi); - subNode->SetAttribute("submeshindex", StringConverter::toString(subi)); - // NB level - 1 because SubMeshes don't store the first index in geometry - IndexData* facedata = sub->mLodFaceList[levelNum - 1]; - subNode->SetAttribute("numfaces", StringConverter::toString(facedata->indexCount / 3)); - - if (facedata->indexCount > 0) - { - // Write each face in turn - bool use32BitIndexes = (facedata->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT); - - // Write each face in turn - unsigned int* pInt = 0; - unsigned short* pShort = 0; - HardwareIndexBufferSharedPtr ibuf = facedata->indexBuffer; - if (use32BitIndexes) - { - pInt = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - pInt += facedata->indexStart; - } - else - { - pShort = static_cast( - ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); - pShort += facedata->indexStart; - } - - for (size_t f = 0; f < facedata->indexCount; f += 3) - { - TiXmlElement* faceNode = - subNode->InsertEndChild(TiXmlElement("face"))->ToElement(); - if (use32BitIndexes) - { - faceNode->SetAttribute("v1", StringConverter::toString(*pInt++)); - faceNode->SetAttribute("v2", StringConverter::toString(*pInt++)); - faceNode->SetAttribute("v3", StringConverter::toString(*pInt++)); - } - else - { - faceNode->SetAttribute("v1", StringConverter::toString(*pShort++)); - faceNode->SetAttribute("v2", StringConverter::toString(*pShort++)); - faceNode->SetAttribute("v3", StringConverter::toString(*pShort++)); - } - - } - } - - } - - } + } //--------------------------------------------------------------------- - void XMLMeshSerializer::writeExtremes(TiXmlElement* mMeshNode, const Mesh* m) - { - TiXmlElement* extremesNode = NULL; - ushort submeshCount = m->getNumSubMeshes(); - for (int idx = 0; idx < submeshCount; ++idx) - { - SubMesh *sm = m->getSubMesh(idx); - if (sm->extremityPoints.empty()) - continue; // do nothing - - if (!extremesNode) - extremesNode = mMeshNode->InsertEndChild(TiXmlElement("extremes"))->ToElement(); - - TiXmlElement* submeshNode = - extremesNode->InsertEndChild(TiXmlElement("submesh_extremes"))->ToElement(); - - submeshNode->SetAttribute("index", StringConverter::toString(idx)); - - for (vector::type::const_iterator v = sm->extremityPoints.begin (); - v != sm->extremityPoints.end (); ++v) - { - TiXmlElement* vert = submeshNode->InsertEndChild( - TiXmlElement("position"))->ToElement(); - vert->SetAttribute("x", StringConverter::toString(v->x)); - vert->SetAttribute("y", StringConverter::toString(v->y)); - vert->SetAttribute("z", StringConverter::toString(v->z)); - } - } - } - //--------------------------------------------------------------------- - void XMLMeshSerializer::readLodInfo(TiXmlElement* lodNode) - { - - LogManager::getSingleton().logMessage("Parsing LOD information..."); + void XMLMeshSerializer::writeLodUsageGenerated(TiXmlElement* usageNode, + unsigned short levelNum, const MeshLodUsage& usage, + const Mesh* pMesh) + { + TiXmlElement* generatedNode = + usageNode->InsertEndChild(TiXmlElement("lodgenerated"))->ToElement(); + generatedNode->SetAttribute("value", + StringConverter::toString(usage.userValue)); - const char* val = lodNode->Attribute("strategy"); - // This attribute is optional to maintain backwards compatibility - if (val) + // Iterate over submeshes at this level + unsigned short numsubs = pMesh->getNumSubMeshes(); + + for (unsigned short subi = 0; subi < numsubs; ++subi) { - String strategyName = val; - LodStrategy *strategy = LodStrategyManager::getSingleton().getStrategy(strategyName); - mMesh->setLodStrategy(strategy); - } + TiXmlElement* subNode = + generatedNode->InsertEndChild(TiXmlElement("lodfacelist"))->ToElement(); + SubMesh* sub = pMesh->getSubMesh(subi); + subNode->SetAttribute("submeshindex", StringConverter::toString(subi)); + // NB level - 1 because SubMeshes don't store the first index in geometry + IndexData* facedata = sub->mLodFaceList[levelNum - 1]; + subNode->SetAttribute("numfaces", StringConverter::toString(facedata->indexCount / 3)); + + if (facedata->indexCount > 0) + { + // Write each face in turn + bool use32BitIndexes = (facedata->indexBuffer->getType() == HardwareIndexBuffer::IT_32BIT); + + // Write each face in turn + unsigned int* pInt = 0; + unsigned short* pShort = 0; + HardwareIndexBufferSharedPtr ibuf = facedata->indexBuffer; + if (use32BitIndexes) + { + pInt = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + pInt += facedata->indexStart; + } + else + { + pShort = static_cast( + ibuf->lock(HardwareBuffer::HBL_READ_ONLY)); + pShort += facedata->indexStart; + } + + for (size_t f = 0; f < facedata->indexCount; f += 3) + { + TiXmlElement* faceNode = + subNode->InsertEndChild(TiXmlElement("face"))->ToElement(); + if (use32BitIndexes) + { + faceNode->SetAttribute("v1", StringConverter::toString(*pInt++)); + faceNode->SetAttribute("v2", StringConverter::toString(*pInt++)); + faceNode->SetAttribute("v3", StringConverter::toString(*pInt++)); + } + else + { + faceNode->SetAttribute("v1", StringConverter::toString(*pShort++)); + faceNode->SetAttribute("v2", StringConverter::toString(*pShort++)); + faceNode->SetAttribute("v3", StringConverter::toString(*pShort++)); + } - val = lodNode->Attribute("numlevels"); - unsigned short numLevels = static_cast( - StringConverter::parseUnsignedInt(val)); - - val = lodNode->Attribute("manual"); - StringConverter::parseBool(val); - - // Set up the basic structures - mMesh->_setLodInfo(numLevels); - - // Parse the detail, start from 1 (the first sub-level of detail) - unsigned short i = 1; - TiXmlElement* usageElem = lodNode->FirstChildElement(); - while (usageElem) - { - if (usageElem->ValueStr() == "lodmanual") - { - readLodUsageManual(usageElem, i); - - } - else if (usageElem->ValueStr() == "lodgenerated") - { - readLodUsageGenerated(usageElem, i); - } - usageElem = usageElem->NextSiblingElement(); - ++i; - } - - LogManager::getSingleton().logMessage("LOD information done."); - - } - //--------------------------------------------------------------------- - void XMLMeshSerializer::readLodUsageManual(TiXmlElement* manualNode, unsigned short index) - { - MeshLodUsage usage; - const char* val = manualNode->Attribute("value"); + } + } + + } + + } + //--------------------------------------------------------------------- + void XMLMeshSerializer::writeExtremes(TiXmlElement* mMeshNode, const Mesh* m) + { + TiXmlElement* extremesNode = NULL; + ushort submeshCount = m->getNumSubMeshes(); + for (int idx = 0; idx < submeshCount; ++idx) + { + SubMesh *sm = m->getSubMesh(idx); + if (sm->extremityPoints.empty()) + continue; // do nothing + + if (!extremesNode) + extremesNode = mMeshNode->InsertEndChild(TiXmlElement("extremes"))->ToElement(); + + TiXmlElement* submeshNode = + extremesNode->InsertEndChild(TiXmlElement("submesh_extremes"))->ToElement(); + + submeshNode->SetAttribute("index", StringConverter::toString(idx)); + + for (vector::type::const_iterator v = sm->extremityPoints.begin (); + v != sm->extremityPoints.end (); ++v) + { + TiXmlElement* vert = submeshNode->InsertEndChild( + TiXmlElement("position"))->ToElement(); + vert->SetAttribute("x", StringConverter::toString(v->x)); + vert->SetAttribute("y", StringConverter::toString(v->y)); + vert->SetAttribute("z", StringConverter::toString(v->z)); + } + } + } + //--------------------------------------------------------------------- + void XMLMeshSerializer::readLodInfo(TiXmlElement* lodNode) + { + + LogManager::getSingleton().logMessage("Parsing LOD information..."); + + const char* val = lodNode->Attribute("strategy"); + // This attribute is optional to maintain backwards compatibility + if (val) + { + String strategyName = val; + LodStrategy *strategy = LodStrategyManager::getSingleton().getStrategy(strategyName); + mMesh->setLodStrategy(strategy); + } + + val = lodNode->Attribute("numlevels"); + unsigned short numLevels = static_cast( + StringConverter::parseUnsignedInt(val)); + + val = lodNode->Attribute("manual"); + StringConverter::parseBool(val); + + // Set up the basic structures + mMesh->_setLodInfo(numLevels); + + // Parse the detail, start from 1 (the first sub-level of detail) + unsigned short i = 1; + TiXmlElement* usageElem = lodNode->FirstChildElement(); + while (usageElem) + { + if (usageElem->ValueStr() == "lodmanual") + { + readLodUsageManual(usageElem, i); + + } + else if (usageElem->ValueStr() == "lodgenerated") + { + readLodUsageGenerated(usageElem, i); + } + usageElem = usageElem->NextSiblingElement(); + ++i; + } + + LogManager::getSingleton().logMessage("LOD information done."); + + } + //--------------------------------------------------------------------- + void XMLMeshSerializer::readLodUsageManual(TiXmlElement* manualNode, unsigned short index) + { + MeshLodUsage usage; + const char* val = manualNode->Attribute("value"); // If value attribute not found check for old name if (!val) @@ -1650,32 +1650,32 @@ namespace Ogre { val = manualNode->Attribute("fromdepthsquared"); if (val) LogManager::getSingleton().logMessage("WARNING: 'fromdepthsquared' attribute has been renamed to 'value'."); - // user values are non-squared - usage.userValue = Math::Sqrt(StringConverter::parseReal(val)); + // user values are non-squared + usage.userValue = Math::Sqrt(StringConverter::parseReal(val)); + } + else + { + usage.userValue = StringConverter::parseReal(val); } - else - { - usage.userValue = StringConverter::parseReal(val); - } - usage.value = mMesh->getLodStrategy()->transformUserValue(usage.userValue); - usage.manualName = manualNode->Attribute("meshname"); + usage.value = mMesh->getLodStrategy()->transformUserValue(usage.userValue); + usage.manualName = manualNode->Attribute("meshname"); usage.edgeData = NULL; - // Generate for mixed - ushort numSubs, i; - numSubs = mMesh->getNumSubMeshes(); - for (i = 0; i < numSubs; ++i) - { - SubMesh* sm = mMesh->getSubMesh(i); - sm->mLodFaceList[index - 1] = OGRE_NEW IndexData(); - } - mMesh->_setLodUsage(index, usage); - } + // Generate for mixed + ushort numSubs, i; + numSubs = mMesh->getNumSubMeshes(); + for (i = 0; i < numSubs; ++i) + { + SubMesh* sm = mMesh->getSubMesh(i); + sm->mLodFaceList[index - 1] = OGRE_NEW IndexData(); + } + mMesh->_setLodUsage(index, usage); + } //--------------------------------------------------------------------- - void XMLMeshSerializer::readLodUsageGenerated(TiXmlElement* genNode, unsigned short index) - { - MeshLodUsage usage; - const char* val = genNode->Attribute("value"); + void XMLMeshSerializer::readLodUsageGenerated(TiXmlElement* genNode, unsigned short index) + { + MeshLodUsage usage; + const char* val = genNode->Attribute("value"); // If value attribute not found check for old name if (!val) @@ -1683,635 +1683,635 @@ namespace Ogre { val = genNode->Attribute("fromdepthsquared"); if (val) LogManager::getSingleton().logMessage("WARNING: 'fromdepthsquared' attribute has been renamed to 'value'."); - // user values are non-squared - usage.userValue = Math::Sqrt(StringConverter::parseReal(val)); - } - else - { - usage.userValue = StringConverter::parseReal(val); - } - usage.value = mMesh->getLodStrategy()->transformUserValue(usage.userValue); - usage.manualMesh.setNull(); - usage.manualName = ""; + // user values are non-squared + usage.userValue = Math::Sqrt(StringConverter::parseReal(val)); + } + else + { + usage.userValue = StringConverter::parseReal(val); + } + usage.value = mMesh->getLodStrategy()->transformUserValue(usage.userValue); + usage.manualMesh.setNull(); + usage.manualName = ""; usage.edgeData = NULL; - mMesh->_setLodUsage(index, usage); - - // Read submesh face lists - TiXmlElement* faceListElem = genNode->FirstChildElement("lodfacelist"); - HardwareIndexBufferSharedPtr ibuf; - while (faceListElem) - { - val = faceListElem->Attribute("submeshindex"); - unsigned short subidx = StringConverter::parseUnsignedInt(val); - val = faceListElem->Attribute("numfaces"); - unsigned short numFaces = StringConverter::parseUnsignedInt(val); - if (numFaces) - { - // use of 32bit indexes depends on submesh - HardwareIndexBuffer::IndexType itype = - mMesh->getSubMesh(subidx)->indexData->indexBuffer->getType(); - bool use32bitindexes = (itype == HardwareIndexBuffer::IT_32BIT); - - // Assign memory: this will be deleted by the submesh - ibuf = HardwareBufferManager::getSingleton(). - createIndexBuffer( - itype, numFaces * 3, HardwareBuffer::HBU_STATIC_WRITE_ONLY); - - unsigned short *pShort = 0; - unsigned int *pInt = 0; - if (use32bitindexes) - { - pInt = static_cast( - ibuf->lock(HardwareBuffer::HBL_DISCARD)); - } - else - { - pShort = static_cast( - ibuf->lock(HardwareBuffer::HBL_DISCARD)); - } - TiXmlElement* faceElem = faceListElem->FirstChildElement("face"); - for (unsigned int face = 0; face < numFaces; ++face, faceElem = faceElem->NextSiblingElement()) - { - if (use32bitindexes) - { - val = faceElem->Attribute("v1"); - *pInt++ = StringConverter::parseUnsignedInt(val); - val = faceElem->Attribute("v2"); - *pInt++ = StringConverter::parseUnsignedInt(val); - val = faceElem->Attribute("v3"); - *pInt++ = StringConverter::parseUnsignedInt(val); - } - else - { - val = faceElem->Attribute("v1"); - *pShort++ = StringConverter::parseUnsignedInt(val); - val = faceElem->Attribute("v2"); - *pShort++ = StringConverter::parseUnsignedInt(val); - val = faceElem->Attribute("v3"); - *pShort++ = StringConverter::parseUnsignedInt(val); - } - - } - - ibuf->unlock(); - } - IndexData* facedata = new IndexData(); // will be deleted by SubMesh - facedata->indexCount = numFaces * 3; + mMesh->_setLodUsage(index, usage); + + // Read submesh face lists + TiXmlElement* faceListElem = genNode->FirstChildElement("lodfacelist"); + HardwareIndexBufferSharedPtr ibuf; + while (faceListElem) + { + val = faceListElem->Attribute("submeshindex"); + unsigned short subidx = StringConverter::parseUnsignedInt(val); + val = faceListElem->Attribute("numfaces"); + unsigned short numFaces = StringConverter::parseUnsignedInt(val); + if (numFaces) + { + // use of 32bit indexes depends on submesh + HardwareIndexBuffer::IndexType itype = + mMesh->getSubMesh(subidx)->indexData->indexBuffer->getType(); + bool use32bitindexes = (itype == HardwareIndexBuffer::IT_32BIT); + + // Assign memory: this will be deleted by the submesh + ibuf = HardwareBufferManager::getSingleton(). + createIndexBuffer( + itype, numFaces * 3, HardwareBuffer::HBU_STATIC_WRITE_ONLY); + + unsigned short *pShort = 0; + unsigned int *pInt = 0; + if (use32bitindexes) + { + pInt = static_cast( + ibuf->lock(HardwareBuffer::HBL_DISCARD)); + } + else + { + pShort = static_cast( + ibuf->lock(HardwareBuffer::HBL_DISCARD)); + } + TiXmlElement* faceElem = faceListElem->FirstChildElement("face"); + for (unsigned int face = 0; face < numFaces; ++face, faceElem = faceElem->NextSiblingElement()) + { + if (use32bitindexes) + { + val = faceElem->Attribute("v1"); + *pInt++ = StringConverter::parseUnsignedInt(val); + val = faceElem->Attribute("v2"); + *pInt++ = StringConverter::parseUnsignedInt(val); + val = faceElem->Attribute("v3"); + *pInt++ = StringConverter::parseUnsignedInt(val); + } + else + { + val = faceElem->Attribute("v1"); + *pShort++ = StringConverter::parseUnsignedInt(val); + val = faceElem->Attribute("v2"); + *pShort++ = StringConverter::parseUnsignedInt(val); + val = faceElem->Attribute("v3"); + *pShort++ = StringConverter::parseUnsignedInt(val); + } + + } + + ibuf->unlock(); + } + IndexData* facedata = new IndexData(); // will be deleted by SubMesh + facedata->indexCount = numFaces * 3; facedata->indexStart = 0; facedata->indexBuffer = ibuf; - mMesh->_setSubMeshLodFaceList(subidx, index, facedata); + mMesh->_setSubMeshLodFaceList(subidx, index, facedata); + + faceListElem = faceListElem->NextSiblingElement(); + } + + } + //----------------------------------------------------------------------------- + void XMLMeshSerializer::readExtremes(TiXmlElement* extremesNode, Mesh *m) + { + LogManager::getSingleton().logMessage("Reading extremes..."); + + // Iterate over all children (submesh_extreme list) + for (TiXmlElement* elem = extremesNode->FirstChildElement(); + elem != 0; elem = elem->NextSiblingElement()) + { + int index = StringConverter::parseInt(elem->Attribute("index")); + + SubMesh *sm = m->getSubMesh(index); + sm->extremityPoints.clear (); + for (TiXmlElement* vert = elem->FirstChildElement(); + vert != 0; vert = vert->NextSiblingElement()) + { + Vector3 v; + v.x = StringConverter::parseReal(vert->Attribute("x")); + v.y = StringConverter::parseReal(vert->Attribute("y")); + v.z = StringConverter::parseReal(vert->Attribute("z")); + sm->extremityPoints.push_back (v); + } + } + + LogManager::getSingleton().logMessage("Extremes done."); + } + //----------------------------------------------------------------------------- + void XMLMeshSerializer::readPoses(TiXmlElement* posesNode, Mesh *m) + { + TiXmlElement* poseNode = posesNode->FirstChildElement("pose"); + + while (poseNode) + { + const char* target = poseNode->Attribute("target"); + if (!target) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Required attribute 'target' missing on pose", + "XMLMeshSerializer::readPoses"); + } + unsigned short targetID; + if(String(target) == "mesh") + { + targetID = 0; + } + else + { + // submesh, get index + const char* val = poseNode->Attribute("index"); + if (!val) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Required attribute 'index' missing on pose", + "XMLMeshSerializer::readPoses"); + } + unsigned short submeshIndex = static_cast( + StringConverter::parseUnsignedInt(val)); + + targetID = submeshIndex + 1; + } + + String name; + const char* val = poseNode->Attribute("name"); + if (val) + name = val; + Pose* pose = m->createPose(targetID, name); + + TiXmlElement* poseOffsetNode = poseNode->FirstChildElement("poseoffset"); + while (poseOffsetNode) + { + uint index = StringConverter::parseUnsignedInt( + poseOffsetNode->Attribute("index")); + Vector3 offset; + offset.x = StringConverter::parseReal(poseOffsetNode->Attribute("x")); + offset.y = StringConverter::parseReal(poseOffsetNode->Attribute("y")); + offset.z = StringConverter::parseReal(poseOffsetNode->Attribute("z")); + + if (poseOffsetNode->Attribute("nx") && + poseOffsetNode->Attribute("ny") && + poseOffsetNode->Attribute("nz")) + { + Vector3 normal; + normal.x = StringConverter::parseReal(poseOffsetNode->Attribute("nx")); + normal.y = StringConverter::parseReal(poseOffsetNode->Attribute("ny")); + normal.z = StringConverter::parseReal(poseOffsetNode->Attribute("nz")); + pose->addVertex(index, offset, normal); + + } + else + { + pose->addVertex(index, offset); + } + + poseOffsetNode = poseOffsetNode->NextSiblingElement(); + + } + + poseNode = poseNode->NextSiblingElement(); + + } + + + } + //----------------------------------------------------------------------------- + void XMLMeshSerializer::readAnimations(TiXmlElement* mAnimationsNode, Mesh *pMesh) + { + TiXmlElement* animElem = mAnimationsNode->FirstChildElement("animation"); + while (animElem) + { + String name = animElem->Attribute("name"); + const char* charLen = animElem->Attribute("length"); + Real len = StringConverter::parseReal(charLen); + + Animation* anim = pMesh->createAnimation(name, len); + + TiXmlElement* baseInfoNode = animElem->FirstChildElement("baseinfo"); + if (baseInfoNode) + { + String baseName = baseInfoNode->Attribute("baseanimationname"); + Real baseTime = StringConverter::parseReal(baseInfoNode->Attribute("basekeyframetime")); + anim->setUseBaseKeyFrame(true, baseTime, baseName); + } + + TiXmlElement* tracksNode = animElem->FirstChildElement("tracks"); + if (tracksNode) + { + readTracks(tracksNode, pMesh, anim); + } + + animElem = animElem->NextSiblingElement(); + + } + + + } + //----------------------------------------------------------------------------- + void XMLMeshSerializer::readTracks(TiXmlElement* tracksNode, Mesh *m, Animation* anim) + { + TiXmlElement* trackNode = tracksNode->FirstChildElement("track"); + while (trackNode) + { + String target = trackNode->Attribute("target"); + unsigned short targetID; + VertexData* vertexData = 0; + if(target == "mesh") + { + targetID = 0; + vertexData = m->sharedVertexData; + } + else + { + // submesh, get index + const char* val = trackNode->Attribute("index"); + if (!val) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Required attribute 'index' missing on submesh track", + "XMLMeshSerializer::readTracks"); + } + unsigned short submeshIndex = static_cast( + StringConverter::parseUnsignedInt(val)); + + targetID = submeshIndex + 1; + vertexData = m->getSubMesh(submeshIndex)->vertexData; + + } + + if (!vertexData) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Track cannot be created for " + target + " since VertexData " + "does not exist at the specified index", + "XMLMeshSerializer::readTracks"); + } + + // Get type + VertexAnimationType animType = VAT_NONE; + String strAnimType = trackNode->Attribute("type"); + if (strAnimType == "morph") + { + animType = VAT_MORPH; + } + else if (strAnimType == "pose") + { + animType = VAT_POSE; + } + else + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Unrecognised animation track type '" + strAnimType + "'", + "XMLMeshSerializer::readTracks"); + } + + // Create track + VertexAnimationTrack* track = + anim->createVertexTrack(targetID, vertexData, animType); + + TiXmlElement* keyframesNode = trackNode->FirstChildElement("keyframes"); + if (keyframesNode) + { + if (track->getAnimationType() == VAT_MORPH) + { + readMorphKeyFrames(keyframesNode, track, vertexData->vertexCount); + } + else // VAT_POSE + { + readPoseKeyFrames(keyframesNode, track); + } + } + + trackNode = trackNode->NextSiblingElement(); + } + } + //----------------------------------------------------------------------------- + void XMLMeshSerializer::readMorphKeyFrames(TiXmlElement* keyframesNode, + VertexAnimationTrack* track, size_t vertexCount) + { + TiXmlElement* keyNode = keyframesNode->FirstChildElement("keyframe"); + while (keyNode) + { + const char* val = keyNode->Attribute("time"); + if (!val) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Required attribute 'time' missing on keyframe", + "XMLMeshSerializer::readKeyFrames"); + } + Real time = StringConverter::parseReal(val); + + VertexMorphKeyFrame* kf = track->createVertexMorphKeyFrame(time); + + bool includesNormals = keyNode->FirstChildElement("normal") != 0; + + size_t vertexSize = sizeof(float) * (includesNormals ? 6 : 3); + // create a vertex buffer + HardwareVertexBufferSharedPtr vbuf = + HardwareBufferManager::getSingleton().createVertexBuffer( + vertexSize, vertexCount, + HardwareBuffer::HBU_STATIC, true); + + float* pFloat = static_cast( + vbuf->lock(HardwareBuffer::HBL_DISCARD)); + + + TiXmlElement* posNode = keyNode->FirstChildElement("position"); + TiXmlElement* normNode = keyNode->FirstChildElement("normal"); + for (size_t v = 0; v < vertexCount; ++v) + { + if (!posNode) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Not enough 'position' elements under keyframe", + "XMLMeshSerializer::readKeyFrames"); + + } + + *pFloat++ = StringConverter::parseReal( + posNode->Attribute("x")); + *pFloat++ = StringConverter::parseReal( + posNode->Attribute("y")); + *pFloat++ = StringConverter::parseReal( + posNode->Attribute("z")); + + if (includesNormals) + { + if (!normNode) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Not enough 'normal' elements under keyframe", + "XMLMeshSerializer::readKeyFrames"); + + } + + *pFloat++ = StringConverter::parseReal( + normNode->Attribute("x")); + *pFloat++ = StringConverter::parseReal( + normNode->Attribute("y")); + *pFloat++ = StringConverter::parseReal( + normNode->Attribute("z")); + normNode = normNode->NextSiblingElement("normal"); + } + + + posNode = posNode->NextSiblingElement("position"); + } + + vbuf->unlock(); + + kf->setVertexBuffer(vbuf); + + + keyNode = keyNode->NextSiblingElement(); + } + + + } + //----------------------------------------------------------------------------- + void XMLMeshSerializer::readPoseKeyFrames(TiXmlElement* keyframesNode, VertexAnimationTrack* track) + { + TiXmlElement* keyNode = keyframesNode->FirstChildElement("keyframe"); + while (keyNode) + { + const char* val = keyNode->Attribute("time"); + if (!val) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Required attribute 'time' missing on keyframe", + "XMLMeshSerializer::readKeyFrames"); + } + Real time = StringConverter::parseReal(val); + + VertexPoseKeyFrame* kf = track->createVertexPoseKeyFrame(time); + + // Read all pose references + TiXmlElement* poseRefNode = keyNode->FirstChildElement("poseref"); + while (poseRefNode) + { + const char* attr = poseRefNode->Attribute("poseindex"); + if (!attr) + { + OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, + "Required attribute 'poseindex' missing on poseref", + "XMLMeshSerializer::readPoseKeyFrames"); + } + unsigned short poseIndex = StringConverter::parseUnsignedInt(attr); + Real influence = 1.0f; + attr = poseRefNode->Attribute("influence"); + if (attr) + { + influence = StringConverter::parseReal(attr); + } + + kf->addPoseReference(poseIndex, influence); + + poseRefNode = poseRefNode->NextSiblingElement(); + } + + keyNode = keyNode->NextSiblingElement(); + } + + } + //----------------------------------------------------------------------------- + void XMLMeshSerializer::writePoses(TiXmlElement* meshNode, const Mesh* m) + { + if (m->getPoseCount() == 0) + return; + + TiXmlElement* posesNode = + meshNode->InsertEndChild(TiXmlElement("poses"))->ToElement(); + + Mesh::ConstPoseIterator poseIt = m->getPoseIterator(); + while (poseIt.hasMoreElements()) + { + const Pose* pose = poseIt.getNext(); + TiXmlElement* poseNode = + posesNode->InsertEndChild(TiXmlElement("pose"))->ToElement(); + unsigned short target = pose->getTarget(); + if (target == 0) + { + // Main mesh + poseNode->SetAttribute("target", "mesh"); + } + else + { + // Submesh - rebase index + poseNode->SetAttribute("target", "submesh"); + poseNode->SetAttribute("index", + StringConverter::toString(target - 1)); + } + poseNode->SetAttribute("name", pose->getName()); + + bool includesNormals = !pose->getNormals().empty(); + + Pose::ConstVertexOffsetIterator vit = pose->getVertexOffsetIterator(); + Pose::ConstNormalsIterator nit = pose->getNormalsIterator(); + while (vit.hasMoreElements()) + { + TiXmlElement* poseOffsetElement = poseNode->InsertEndChild( + TiXmlElement("poseoffset"))->ToElement(); + + poseOffsetElement->SetAttribute("index", + StringConverter::toString(vit.peekNextKey())); + + Vector3 offset = vit.getNext(); + poseOffsetElement->SetAttribute("x", StringConverter::toString(offset.x)); + poseOffsetElement->SetAttribute("y", StringConverter::toString(offset.y)); + poseOffsetElement->SetAttribute("z", StringConverter::toString(offset.z)); + + if (includesNormals) + { + Vector3 normal = nit.getNext(); + poseOffsetElement->SetAttribute("nx", StringConverter::toString(normal.x)); + poseOffsetElement->SetAttribute("ny", StringConverter::toString(normal.y)); + poseOffsetElement->SetAttribute("nz", StringConverter::toString(normal.z)); + } + + + + + } + + } + + } + //----------------------------------------------------------------------------- + void XMLMeshSerializer::writeAnimations(TiXmlElement* meshNode, const Mesh* m) + { + // Skip if no animation + if (!m->hasVertexAnimation()) + return; + + TiXmlElement* animationsNode = + meshNode->InsertEndChild(TiXmlElement("animations"))->ToElement(); + + for (unsigned short a = 0; a < m->getNumAnimations(); ++a) + { + Animation* anim = m->getAnimation(a); + + TiXmlElement* animNode = + animationsNode->InsertEndChild(TiXmlElement("animation"))->ToElement(); + animNode->SetAttribute("name", anim->getName()); + animNode->SetAttribute("length", + StringConverter::toString(anim->getLength())); + + // Optional base keyframe information + if (anim->getUseBaseKeyFrame()) + { + TiXmlElement* baseInfoNode = + animNode->InsertEndChild(TiXmlElement("baseinfo"))->ToElement(); + baseInfoNode->SetAttribute("baseanimationname", anim->getBaseKeyFrameAnimationName()); + baseInfoNode->SetAttribute("basekeyframetime", StringConverter::toString(anim->getBaseKeyFrameTime())); + } + + TiXmlElement* tracksNode = + animNode->InsertEndChild(TiXmlElement("tracks"))->ToElement(); + Animation::VertexTrackIterator iter = anim->getVertexTrackIterator(); + while(iter.hasMoreElements()) + { + const VertexAnimationTrack* track = iter.getNext(); + TiXmlElement* trackNode = + tracksNode->InsertEndChild(TiXmlElement("track"))->ToElement(); + + unsigned short targetID = track->getHandle(); + if (targetID == 0) + { + trackNode->SetAttribute("target", "mesh"); + } + else + { + trackNode->SetAttribute("target", "submesh"); + trackNode->SetAttribute("index", + StringConverter::toString(targetID-1)); + } + + if (track->getAnimationType() == VAT_MORPH) + { + trackNode->SetAttribute("type", "morph"); + writeMorphKeyFrames(trackNode, track); + } + else + { + trackNode->SetAttribute("type", "pose"); + writePoseKeyFrames(trackNode, track); + } + + + } + } - faceListElem = faceListElem->NextSiblingElement(); - } - } - //----------------------------------------------------------------------------- - void XMLMeshSerializer::readExtremes(TiXmlElement* extremesNode, Mesh *m) - { - LogManager::getSingleton().logMessage("Reading extremes..."); - - // Iterate over all children (submesh_extreme list) - for (TiXmlElement* elem = extremesNode->FirstChildElement(); - elem != 0; elem = elem->NextSiblingElement()) - { - int index = StringConverter::parseInt(elem->Attribute("index")); - - SubMesh *sm = m->getSubMesh(index); - sm->extremityPoints.clear (); - for (TiXmlElement* vert = elem->FirstChildElement(); - vert != 0; vert = vert->NextSiblingElement()) - { - Vector3 v; - v.x = StringConverter::parseReal(vert->Attribute("x")); - v.y = StringConverter::parseReal(vert->Attribute("y")); - v.z = StringConverter::parseReal(vert->Attribute("z")); - sm->extremityPoints.push_back (v); - } - } - - LogManager::getSingleton().logMessage("Extremes done."); - } - //----------------------------------------------------------------------------- - void XMLMeshSerializer::readPoses(TiXmlElement* posesNode, Mesh *m) - { - TiXmlElement* poseNode = posesNode->FirstChildElement("pose"); - - while (poseNode) - { - const char* target = poseNode->Attribute("target"); - if (!target) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Required attribute 'target' missing on pose", - "XMLMeshSerializer::readPoses"); - } - unsigned short targetID; - if(String(target) == "mesh") - { - targetID = 0; - } - else - { - // submesh, get index - const char* val = poseNode->Attribute("index"); - if (!val) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Required attribute 'index' missing on pose", - "XMLMeshSerializer::readPoses"); - } - unsigned short submeshIndex = static_cast( - StringConverter::parseUnsignedInt(val)); - - targetID = submeshIndex + 1; - } - - String name; - const char* val = poseNode->Attribute("name"); - if (val) - name = val; - Pose* pose = m->createPose(targetID, name); - - TiXmlElement* poseOffsetNode = poseNode->FirstChildElement("poseoffset"); - while (poseOffsetNode) - { - uint index = StringConverter::parseUnsignedInt( - poseOffsetNode->Attribute("index")); - Vector3 offset; - offset.x = StringConverter::parseReal(poseOffsetNode->Attribute("x")); - offset.y = StringConverter::parseReal(poseOffsetNode->Attribute("y")); - offset.z = StringConverter::parseReal(poseOffsetNode->Attribute("z")); - - if (poseOffsetNode->Attribute("nx") && - poseOffsetNode->Attribute("ny") && - poseOffsetNode->Attribute("nz")) - { - Vector3 normal; - normal.x = StringConverter::parseReal(poseOffsetNode->Attribute("nx")); - normal.y = StringConverter::parseReal(poseOffsetNode->Attribute("ny")); - normal.z = StringConverter::parseReal(poseOffsetNode->Attribute("nz")); - pose->addVertex(index, offset, normal); - - } - else - { - pose->addVertex(index, offset); - } - - poseOffsetNode = poseOffsetNode->NextSiblingElement(); - - } - - poseNode = poseNode->NextSiblingElement(); - - } - - - } - //----------------------------------------------------------------------------- - void XMLMeshSerializer::readAnimations(TiXmlElement* mAnimationsNode, Mesh *pMesh) - { - TiXmlElement* animElem = mAnimationsNode->FirstChildElement("animation"); - while (animElem) - { - String name = animElem->Attribute("name"); - const char* charLen = animElem->Attribute("length"); - Real len = StringConverter::parseReal(charLen); - - Animation* anim = pMesh->createAnimation(name, len); - - TiXmlElement* baseInfoNode = animElem->FirstChildElement("baseinfo"); - if (baseInfoNode) - { - String baseName = baseInfoNode->Attribute("baseanimationname"); - Real baseTime = StringConverter::parseReal(baseInfoNode->Attribute("basekeyframetime")); - anim->setUseBaseKeyFrame(true, baseTime, baseName); - } - - TiXmlElement* tracksNode = animElem->FirstChildElement("tracks"); - if (tracksNode) - { - readTracks(tracksNode, pMesh, anim); - } - - animElem = animElem->NextSiblingElement(); - - } - - - } - //----------------------------------------------------------------------------- - void XMLMeshSerializer::readTracks(TiXmlElement* tracksNode, Mesh *m, Animation* anim) - { - TiXmlElement* trackNode = tracksNode->FirstChildElement("track"); - while (trackNode) - { - String target = trackNode->Attribute("target"); - unsigned short targetID; - VertexData* vertexData = 0; - if(target == "mesh") - { - targetID = 0; - vertexData = m->sharedVertexData; - } - else - { - // submesh, get index - const char* val = trackNode->Attribute("index"); - if (!val) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Required attribute 'index' missing on submesh track", - "XMLMeshSerializer::readTracks"); - } - unsigned short submeshIndex = static_cast( - StringConverter::parseUnsignedInt(val)); - - targetID = submeshIndex + 1; - vertexData = m->getSubMesh(submeshIndex)->vertexData; - - } - - if (!vertexData) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Track cannot be created for " + target + " since VertexData " - "does not exist at the specified index", - "XMLMeshSerializer::readTracks"); - } - - // Get type - VertexAnimationType animType = VAT_NONE; - String strAnimType = trackNode->Attribute("type"); - if (strAnimType == "morph") - { - animType = VAT_MORPH; - } - else if (strAnimType == "pose") - { - animType = VAT_POSE; - } - else - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Unrecognised animation track type '" + strAnimType + "'", - "XMLMeshSerializer::readTracks"); - } - - // Create track - VertexAnimationTrack* track = - anim->createVertexTrack(targetID, vertexData, animType); - - TiXmlElement* keyframesNode = trackNode->FirstChildElement("keyframes"); - if (keyframesNode) - { - if (track->getAnimationType() == VAT_MORPH) - { - readMorphKeyFrames(keyframesNode, track, vertexData->vertexCount); - } - else // VAT_POSE - { - readPoseKeyFrames(keyframesNode, track); - } - } - - trackNode = trackNode->NextSiblingElement(); - } - } - //----------------------------------------------------------------------------- - void XMLMeshSerializer::readMorphKeyFrames(TiXmlElement* keyframesNode, - VertexAnimationTrack* track, size_t vertexCount) - { - TiXmlElement* keyNode = keyframesNode->FirstChildElement("keyframe"); - while (keyNode) - { - const char* val = keyNode->Attribute("time"); - if (!val) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Required attribute 'time' missing on keyframe", - "XMLMeshSerializer::readKeyFrames"); - } - Real time = StringConverter::parseReal(val); - - VertexMorphKeyFrame* kf = track->createVertexMorphKeyFrame(time); - - bool includesNormals = keyNode->FirstChildElement("normal") != 0; - - size_t vertexSize = sizeof(float) * (includesNormals ? 6 : 3); - // create a vertex buffer - HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - vertexSize, vertexCount, - HardwareBuffer::HBU_STATIC, true); - - float* pFloat = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD)); - - - TiXmlElement* posNode = keyNode->FirstChildElement("position"); - TiXmlElement* normNode = keyNode->FirstChildElement("normal"); - for (size_t v = 0; v < vertexCount; ++v) - { - if (!posNode) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Not enough 'position' elements under keyframe", - "XMLMeshSerializer::readKeyFrames"); - - } - - *pFloat++ = StringConverter::parseReal( - posNode->Attribute("x")); - *pFloat++ = StringConverter::parseReal( - posNode->Attribute("y")); - *pFloat++ = StringConverter::parseReal( - posNode->Attribute("z")); - - if (includesNormals) - { - if (!normNode) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Not enough 'normal' elements under keyframe", - "XMLMeshSerializer::readKeyFrames"); - - } - - *pFloat++ = StringConverter::parseReal( - normNode->Attribute("x")); - *pFloat++ = StringConverter::parseReal( - normNode->Attribute("y")); - *pFloat++ = StringConverter::parseReal( - normNode->Attribute("z")); - normNode = normNode->NextSiblingElement("normal"); - } - - - posNode = posNode->NextSiblingElement("position"); - } - - vbuf->unlock(); - - kf->setVertexBuffer(vbuf); - - - keyNode = keyNode->NextSiblingElement(); - } - - - } - //----------------------------------------------------------------------------- - void XMLMeshSerializer::readPoseKeyFrames(TiXmlElement* keyframesNode, VertexAnimationTrack* track) - { - TiXmlElement* keyNode = keyframesNode->FirstChildElement("keyframe"); - while (keyNode) - { - const char* val = keyNode->Attribute("time"); - if (!val) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Required attribute 'time' missing on keyframe", - "XMLMeshSerializer::readKeyFrames"); - } - Real time = StringConverter::parseReal(val); - - VertexPoseKeyFrame* kf = track->createVertexPoseKeyFrame(time); - - // Read all pose references - TiXmlElement* poseRefNode = keyNode->FirstChildElement("poseref"); - while (poseRefNode) - { - const char* attr = poseRefNode->Attribute("poseindex"); - if (!attr) - { - OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, - "Required attribute 'poseindex' missing on poseref", - "XMLMeshSerializer::readPoseKeyFrames"); - } - unsigned short poseIndex = StringConverter::parseUnsignedInt(attr); - Real influence = 1.0f; - attr = poseRefNode->Attribute("influence"); - if (attr) - { - influence = StringConverter::parseReal(attr); - } - - kf->addPoseReference(poseIndex, influence); - - poseRefNode = poseRefNode->NextSiblingElement(); - } - - keyNode = keyNode->NextSiblingElement(); - } - - } - //----------------------------------------------------------------------------- - void XMLMeshSerializer::writePoses(TiXmlElement* meshNode, const Mesh* m) - { - if (m->getPoseCount() == 0) - return; - - TiXmlElement* posesNode = - meshNode->InsertEndChild(TiXmlElement("poses"))->ToElement(); - - Mesh::ConstPoseIterator poseIt = m->getPoseIterator(); - while (poseIt.hasMoreElements()) - { - const Pose* pose = poseIt.getNext(); - TiXmlElement* poseNode = - posesNode->InsertEndChild(TiXmlElement("pose"))->ToElement(); - unsigned short target = pose->getTarget(); - if (target == 0) - { - // Main mesh - poseNode->SetAttribute("target", "mesh"); - } - else - { - // Submesh - rebase index - poseNode->SetAttribute("target", "submesh"); - poseNode->SetAttribute("index", - StringConverter::toString(target - 1)); - } - poseNode->SetAttribute("name", pose->getName()); - - bool includesNormals = !pose->getNormals().empty(); - - Pose::ConstVertexOffsetIterator vit = pose->getVertexOffsetIterator(); - Pose::ConstNormalsIterator nit = pose->getNormalsIterator(); - while (vit.hasMoreElements()) - { - TiXmlElement* poseOffsetElement = poseNode->InsertEndChild( - TiXmlElement("poseoffset"))->ToElement(); - - poseOffsetElement->SetAttribute("index", - StringConverter::toString(vit.peekNextKey())); - - Vector3 offset = vit.getNext(); - poseOffsetElement->SetAttribute("x", StringConverter::toString(offset.x)); - poseOffsetElement->SetAttribute("y", StringConverter::toString(offset.y)); - poseOffsetElement->SetAttribute("z", StringConverter::toString(offset.z)); - - if (includesNormals) - { - Vector3 normal = nit.getNext(); - poseOffsetElement->SetAttribute("nx", StringConverter::toString(normal.x)); - poseOffsetElement->SetAttribute("ny", StringConverter::toString(normal.y)); - poseOffsetElement->SetAttribute("nz", StringConverter::toString(normal.z)); - } - - - - - } - - } - - } - //----------------------------------------------------------------------------- - void XMLMeshSerializer::writeAnimations(TiXmlElement* meshNode, const Mesh* m) - { - // Skip if no animation - if (!m->hasVertexAnimation()) - return; - - TiXmlElement* animationsNode = - meshNode->InsertEndChild(TiXmlElement("animations"))->ToElement(); - - for (unsigned short a = 0; a < m->getNumAnimations(); ++a) - { - Animation* anim = m->getAnimation(a); - - TiXmlElement* animNode = - animationsNode->InsertEndChild(TiXmlElement("animation"))->ToElement(); - animNode->SetAttribute("name", anim->getName()); - animNode->SetAttribute("length", - StringConverter::toString(anim->getLength())); - - // Optional base keyframe information - if (anim->getUseBaseKeyFrame()) - { - TiXmlElement* baseInfoNode = - animNode->InsertEndChild(TiXmlElement("baseinfo"))->ToElement(); - baseInfoNode->SetAttribute("baseanimationname", anim->getBaseKeyFrameAnimationName()); - baseInfoNode->SetAttribute("basekeyframetime", StringConverter::toString(anim->getBaseKeyFrameTime())); - } - - TiXmlElement* tracksNode = - animNode->InsertEndChild(TiXmlElement("tracks"))->ToElement(); - Animation::VertexTrackIterator iter = anim->getVertexTrackIterator(); - while(iter.hasMoreElements()) - { - const VertexAnimationTrack* track = iter.getNext(); - TiXmlElement* trackNode = - tracksNode->InsertEndChild(TiXmlElement("track"))->ToElement(); - - unsigned short targetID = track->getHandle(); - if (targetID == 0) - { - trackNode->SetAttribute("target", "mesh"); - } - else - { - trackNode->SetAttribute("target", "submesh"); - trackNode->SetAttribute("index", - StringConverter::toString(targetID-1)); - } - - if (track->getAnimationType() == VAT_MORPH) - { - trackNode->SetAttribute("type", "morph"); - writeMorphKeyFrames(trackNode, track); - } - else - { - trackNode->SetAttribute("type", "pose"); - writePoseKeyFrames(trackNode, track); - } - - - } - } - - - } - //----------------------------------------------------------------------------- - void XMLMeshSerializer::writeMorphKeyFrames(TiXmlElement* trackNode, const VertexAnimationTrack* track) - { - TiXmlElement* keyframesNode = - trackNode->InsertEndChild(TiXmlElement("keyframes"))->ToElement(); - - size_t vertexCount = track->getAssociatedVertexData()->vertexCount; - - for (unsigned short k = 0; k < track->getNumKeyFrames(); ++k) - { - VertexMorphKeyFrame* kf = track->getVertexMorphKeyFrame(k); - TiXmlElement* keyNode = - keyframesNode->InsertEndChild(TiXmlElement("keyframe"))->ToElement(); - keyNode->SetAttribute("time", - StringConverter::toString(kf->getTime())); - - HardwareVertexBufferSharedPtr vbuf = kf->getVertexBuffer(); - - bool includesNormals = vbuf->getVertexSize() > (sizeof(float) * 3); - - float* pFloat = static_cast( - vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); - - for (size_t v = 0; v < vertexCount; ++v) - { - TiXmlElement* posNode = - keyNode->InsertEndChild(TiXmlElement("position"))->ToElement(); - posNode->SetAttribute("x", StringConverter::toString(*pFloat++)); - posNode->SetAttribute("y", StringConverter::toString(*pFloat++)); - posNode->SetAttribute("z", StringConverter::toString(*pFloat++)); - - if (includesNormals) - { - TiXmlElement* normNode = - keyNode->InsertEndChild(TiXmlElement("normal"))->ToElement(); - normNode->SetAttribute("x", StringConverter::toString(*pFloat++)); - normNode->SetAttribute("y", StringConverter::toString(*pFloat++)); - normNode->SetAttribute("z", StringConverter::toString(*pFloat++)); - } - } - - } - } - //----------------------------------------------------------------------------- - void XMLMeshSerializer::writePoseKeyFrames(TiXmlElement* trackNode, const VertexAnimationTrack* track) - { - TiXmlElement* keyframesNode = - trackNode->InsertEndChild(TiXmlElement("keyframes"))->ToElement(); - - for (unsigned short k = 0; k < track->getNumKeyFrames(); ++k) - { - VertexPoseKeyFrame* kf = track->getVertexPoseKeyFrame(k); - TiXmlElement* keyNode = - keyframesNode->InsertEndChild(TiXmlElement("keyframe"))->ToElement(); - keyNode->SetAttribute("time", - StringConverter::toString(kf->getTime())); - - VertexPoseKeyFrame::PoseRefIterator poseIt = kf->getPoseReferenceIterator(); - while (poseIt.hasMoreElements()) - { - const VertexPoseKeyFrame::PoseRef& poseRef = poseIt.getNext(); - TiXmlElement* poseRefNode = - keyNode->InsertEndChild(TiXmlElement("poseref"))->ToElement(); - - poseRefNode->SetAttribute("poseindex", - StringConverter::toString(poseRef.poseIndex)); - poseRefNode->SetAttribute("influence", - StringConverter::toString(poseRef.influence)); - - } - - } - - - } + } + //----------------------------------------------------------------------------- + void XMLMeshSerializer::writeMorphKeyFrames(TiXmlElement* trackNode, const VertexAnimationTrack* track) + { + TiXmlElement* keyframesNode = + trackNode->InsertEndChild(TiXmlElement("keyframes"))->ToElement(); + + size_t vertexCount = track->getAssociatedVertexData()->vertexCount; + + for (unsigned short k = 0; k < track->getNumKeyFrames(); ++k) + { + VertexMorphKeyFrame* kf = track->getVertexMorphKeyFrame(k); + TiXmlElement* keyNode = + keyframesNode->InsertEndChild(TiXmlElement("keyframe"))->ToElement(); + keyNode->SetAttribute("time", + StringConverter::toString(kf->getTime())); + + HardwareVertexBufferSharedPtr vbuf = kf->getVertexBuffer(); + + bool includesNormals = vbuf->getVertexSize() > (sizeof(float) * 3); + + float* pFloat = static_cast( + vbuf->lock(HardwareBuffer::HBL_READ_ONLY)); + + for (size_t v = 0; v < vertexCount; ++v) + { + TiXmlElement* posNode = + keyNode->InsertEndChild(TiXmlElement("position"))->ToElement(); + posNode->SetAttribute("x", StringConverter::toString(*pFloat++)); + posNode->SetAttribute("y", StringConverter::toString(*pFloat++)); + posNode->SetAttribute("z", StringConverter::toString(*pFloat++)); + + if (includesNormals) + { + TiXmlElement* normNode = + keyNode->InsertEndChild(TiXmlElement("normal"))->ToElement(); + normNode->SetAttribute("x", StringConverter::toString(*pFloat++)); + normNode->SetAttribute("y", StringConverter::toString(*pFloat++)); + normNode->SetAttribute("z", StringConverter::toString(*pFloat++)); + } + } + + } + } + //----------------------------------------------------------------------------- + void XMLMeshSerializer::writePoseKeyFrames(TiXmlElement* trackNode, const VertexAnimationTrack* track) + { + TiXmlElement* keyframesNode = + trackNode->InsertEndChild(TiXmlElement("keyframes"))->ToElement(); + + for (unsigned short k = 0; k < track->getNumKeyFrames(); ++k) + { + VertexPoseKeyFrame* kf = track->getVertexPoseKeyFrame(k); + TiXmlElement* keyNode = + keyframesNode->InsertEndChild(TiXmlElement("keyframe"))->ToElement(); + keyNode->SetAttribute("time", + StringConverter::toString(kf->getTime())); + + VertexPoseKeyFrame::PoseRefIterator poseIt = kf->getPoseReferenceIterator(); + while (poseIt.hasMoreElements()) + { + const VertexPoseKeyFrame::PoseRef& poseRef = poseIt.getNext(); + TiXmlElement* poseRefNode = + keyNode->InsertEndChild(TiXmlElement("poseref"))->ToElement(); + + poseRefNode->SetAttribute("poseindex", + StringConverter::toString(poseRef.poseIndex)); + poseRefNode->SetAttribute("influence", + StringConverter::toString(poseRef.influence)); + + } + + } + + + } diff --git a/Tools/XMLConverter/src/OgreXMLSkeletonSerializer.cpp b/Tools/XMLConverter/src/OgreXMLSkeletonSerializer.cpp index 7d699289a2b..65c7d61b109 100644 --- a/Tools/XMLConverter/src/OgreXMLSkeletonSerializer.cpp +++ b/Tools/XMLConverter/src/OgreXMLSkeletonSerializer.cpp @@ -53,110 +53,110 @@ namespace Ogre { //--------------------------------------------------------------------- void XMLSkeletonSerializer::importSkeleton(const String& filename, Skeleton* pSkeleton) - { - LogManager::getSingleton().logMessage("XMLSkeletonSerializer: reading XML data from " + filename + "..."); + { + LogManager::getSingleton().logMessage("XMLSkeletonSerializer: reading XML data from " + filename + "..."); - mXMLDoc = new TiXmlDocument(filename); + mXMLDoc = new TiXmlDocument(filename); mXMLDoc->LoadFile(); - TiXmlElement* elem; + TiXmlElement* elem; TiXmlElement* rootElem = mXMLDoc->RootElement(); - - // Optional blend mode - const char* blendModeStr = rootElem->Attribute("blendmode"); - if (blendModeStr) - { - if (String(blendModeStr) == "cumulative") - pSkeleton->setBlendMode(ANIMBLEND_CUMULATIVE); - else - pSkeleton->setBlendMode(ANIMBLEND_AVERAGE); - - } - + + // Optional blend mode + const char* blendModeStr = rootElem->Attribute("blendmode"); + if (blendModeStr) + { + if (String(blendModeStr) == "cumulative") + pSkeleton->setBlendMode(ANIMBLEND_CUMULATIVE); + else + pSkeleton->setBlendMode(ANIMBLEND_AVERAGE); + + } + // Bones elem = rootElem->FirstChildElement("bones"); if (elem) - { - readBones(pSkeleton, elem); - elem = rootElem->FirstChildElement("bonehierarchy"); - - if (elem) - { - createHierarchy(pSkeleton, elem) ; - elem = rootElem->FirstChildElement("bones"); - if (elem) - { - readBones2(pSkeleton, elem); - elem = rootElem->FirstChildElement("animations"); - if (elem) - { - readAnimations(pSkeleton, elem); - } - elem = rootElem->FirstChildElement("animationlinks"); - if (elem) - { - readSkeletonAnimationLinks(pSkeleton, elem); - } - } - } - } - LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Finished. Running SkeletonSerializer..." ); + { + readBones(pSkeleton, elem); + elem = rootElem->FirstChildElement("bonehierarchy"); + + if (elem) + { + createHierarchy(pSkeleton, elem) ; + elem = rootElem->FirstChildElement("bones"); + if (elem) + { + readBones2(pSkeleton, elem); + elem = rootElem->FirstChildElement("animations"); + if (elem) + { + readAnimations(pSkeleton, elem); + } + elem = rootElem->FirstChildElement("animationlinks"); + if (elem) + { + readSkeletonAnimationLinks(pSkeleton, elem); + } + } + } + } + LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Finished. Running SkeletonSerializer..." ); } - + - //--------------------------------------------------------------------- - // sets names - void XMLSkeletonSerializer::readBones(Skeleton* skel, TiXmlElement* mBonesNode) + //--------------------------------------------------------------------- + // sets names + void XMLSkeletonSerializer::readBones(Skeleton* skel, TiXmlElement* mBonesNode) { LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Bones name..."); - - Quaternion quat ; + + Quaternion quat ; for (TiXmlElement* bonElem = mBonesNode->FirstChildElement(); bonElem != 0; bonElem = bonElem->NextSiblingElement()) { String name = bonElem->Attribute("name"); - int id = StringConverter::parseInt(bonElem->Attribute("id")); - skel->createBone(name,id) ; + int id = StringConverter::parseInt(bonElem->Attribute("id")); + skel->createBone(name,id) ; } } - // --------------------------------------------------------- - // set positions and orientations. - void XMLSkeletonSerializer::readBones2(Skeleton* skel, TiXmlElement* mBonesNode) + // --------------------------------------------------------- + // set positions and orientations. + void XMLSkeletonSerializer::readBones2(Skeleton* skel, TiXmlElement* mBonesNode) { LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Bones data..."); - - Bone* btmp ; - Quaternion quat ; + + Bone* btmp ; + Quaternion quat ; for (TiXmlElement* bonElem = mBonesNode->FirstChildElement(); bonElem != 0; bonElem = bonElem->NextSiblingElement()) { String name = bonElem->Attribute("name"); -// int id = StringConverter::parseInt(bonElem->Attribute("id")); +// int id = StringConverter::parseInt(bonElem->Attribute("id")); - TiXmlElement* posElem = bonElem->FirstChildElement("position"); - TiXmlElement* rotElem = bonElem->FirstChildElement("rotation"); - TiXmlElement* axisElem = rotElem->FirstChildElement("axis"); + TiXmlElement* posElem = bonElem->FirstChildElement("position"); + TiXmlElement* rotElem = bonElem->FirstChildElement("rotation"); + TiXmlElement* axisElem = rotElem->FirstChildElement("axis"); TiXmlElement* scaleElem = bonElem->FirstChildElement("scale"); - - Vector3 pos; - Vector3 axis; - Radian angle ; + + Vector3 pos; + Vector3 axis; + Radian angle ; Vector3 scale; - pos.x = StringConverter::parseReal(posElem->Attribute("x")); - pos.y = StringConverter::parseReal(posElem->Attribute("y")); - pos.z = StringConverter::parseReal(posElem->Attribute("z")); - - angle = Radian(StringConverter::parseReal(rotElem->Attribute("angle"))); + pos.x = StringConverter::parseReal(posElem->Attribute("x")); + pos.y = StringConverter::parseReal(posElem->Attribute("y")); + pos.z = StringConverter::parseReal(posElem->Attribute("z")); + + angle = Radian(StringConverter::parseReal(rotElem->Attribute("angle"))); - axis.x = StringConverter::parseReal(axisElem->Attribute("x")); - axis.y = StringConverter::parseReal(axisElem->Attribute("y")); - axis.z = StringConverter::parseReal(axisElem->Attribute("z")); - + axis.x = StringConverter::parseReal(axisElem->Attribute("x")); + axis.y = StringConverter::parseReal(axisElem->Attribute("y")); + axis.z = StringConverter::parseReal(axisElem->Attribute("z")); + // Optional scale if (scaleElem) { @@ -194,114 +194,114 @@ namespace Ogre { scale = Vector3::UNIT_SCALE; } - /*LogManager::getSingleton().logMessage("bone " + name + " : position(" - + StringConverter::toString(pos.x) + "," + StringConverter::toString(pos.y) + "," + StringConverter::toString(pos.z) + ")" - + " - angle: " + StringConverter::toString(angle) +" - axe: " - + StringConverter::toString(axis.x) + "," + StringConverter::toString(axis.y) + "," + StringConverter::toString(axis.z) ); - */ - - btmp = skel->getBone(name) ; - - btmp -> setPosition(pos); - quat.FromAngleAxis(angle,axis); - btmp -> setOrientation(quat) ; + /*LogManager::getSingleton().logMessage("bone " + name + " : position(" + + StringConverter::toString(pos.x) + "," + StringConverter::toString(pos.y) + "," + StringConverter::toString(pos.z) + ")" + + " - angle: " + StringConverter::toString(angle) +" - axe: " + + StringConverter::toString(axis.x) + "," + StringConverter::toString(axis.y) + "," + StringConverter::toString(axis.z) ); + */ + + btmp = skel->getBone(name) ; + + btmp -> setPosition(pos); + quat.FromAngleAxis(angle,axis); + btmp -> setOrientation(quat) ; btmp -> setScale(scale); } // bones } - //------------------------------------------------------------------- - void XMLSkeletonSerializer::createHierarchy(Skeleton* skel, TiXmlElement* mHierNode) { - - LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Hierarchy data..."); - - Bone* bone ; - Bone* parent ; - String boneName ; - String parentName ; - - for (TiXmlElement* hierElem = mHierNode->FirstChildElement() ; hierElem != 0; hierElem = hierElem->NextSiblingElement()) + //------------------------------------------------------------------- + void XMLSkeletonSerializer::createHierarchy(Skeleton* skel, TiXmlElement* mHierNode) { + + LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Hierarchy data..."); + + Bone* bone ; + Bone* parent ; + String boneName ; + String parentName ; + + for (TiXmlElement* hierElem = mHierNode->FirstChildElement() ; hierElem != 0; hierElem = hierElem->NextSiblingElement()) { - boneName = hierElem->Attribute("bone"); - parentName = hierElem->Attribute("parent"); - bone = skel->getBone(boneName); - parent = skel->getBone(parentName); - parent ->addChild(bone) ; - //LogManager::getSingleton().logMessage("XMLSkeletonSerialiser: lien: " + parent->getName() + "->" + bone->getName()); - - } - } - //--------------------------------------------------------------------- - void XMLSkeletonSerializer::readAnimations(Skeleton* skel, TiXmlElement* mAnimNode) { - - Animation * anim ; - NodeAnimationTrack * track ; - LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Animations data..."); - - for (TiXmlElement* animElem = mAnimNode->FirstChildElement("animation"); animElem != 0; animElem = animElem->NextSiblingElement()) + boneName = hierElem->Attribute("bone"); + parentName = hierElem->Attribute("parent"); + bone = skel->getBone(boneName); + parent = skel->getBone(parentName); + parent ->addChild(bone) ; + //LogManager::getSingleton().logMessage("XMLSkeletonSerialiser: lien: " + parent->getName() + "->" + bone->getName()); + + } + } + //--------------------------------------------------------------------- + void XMLSkeletonSerializer::readAnimations(Skeleton* skel, TiXmlElement* mAnimNode) { + + Animation * anim ; + NodeAnimationTrack * track ; + LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Animations data..."); + + for (TiXmlElement* animElem = mAnimNode->FirstChildElement("animation"); animElem != 0; animElem = animElem->NextSiblingElement()) { String name = animElem->Attribute("name"); - Real length = StringConverter::parseReal(animElem->Attribute("length")); - anim = skel->createAnimation(name,length); - anim->setInterpolationMode(Animation::IM_LINEAR) ; - - - //LogManager::getSingleton().logMessage("Animation: nom: " + name + " et longueur: " - // + StringConverter::toString(length) ); - TiXmlElement* baseInfoNode = animElem->FirstChildElement("baseinfo"); - if (baseInfoNode) - { - String baseName = baseInfoNode->Attribute("baseanimationname"); - Real baseTime = StringConverter::parseReal(baseInfoNode->Attribute("basekeyframetime")); - anim->setUseBaseKeyFrame(true, baseTime, baseName); - } - - - - // lecture des tracks - int trackIndex = 0; - TiXmlElement* tracksNode = animElem->FirstChildElement("tracks"); - - for (TiXmlElement* trackElem = tracksNode->FirstChildElement("track"); trackElem != 0; trackElem = trackElem->NextSiblingElement()) - { - String boneName = trackElem->Attribute("bone"); - - //LogManager::getSingleton().logMessage("Track sur le bone: " + boneName ); - - track = anim->createNodeTrack(trackIndex++,skel->getBone(boneName)); - readKeyFrames(track, trackElem->FirstChildElement("keyframes")); - } - - } - - - } - //--------------------------------------------------------------------- - void XMLSkeletonSerializer::readKeyFrames(NodeAnimationTrack* track, TiXmlElement* mKeyfNode) { - - TransformKeyFrame* kf ; - Quaternion q ; - - for (TiXmlElement* keyfElem = mKeyfNode->FirstChildElement("keyframe"); keyfElem != 0; keyfElem = keyfElem->NextSiblingElement()) + Real length = StringConverter::parseReal(animElem->Attribute("length")); + anim = skel->createAnimation(name,length); + anim->setInterpolationMode(Animation::IM_LINEAR) ; + + + //LogManager::getSingleton().logMessage("Animation: nom: " + name + " et longueur: " + // + StringConverter::toString(length) ); + TiXmlElement* baseInfoNode = animElem->FirstChildElement("baseinfo"); + if (baseInfoNode) + { + String baseName = baseInfoNode->Attribute("baseanimationname"); + Real baseTime = StringConverter::parseReal(baseInfoNode->Attribute("basekeyframetime")); + anim->setUseBaseKeyFrame(true, baseTime, baseName); + } + + + + // lecture des tracks + int trackIndex = 0; + TiXmlElement* tracksNode = animElem->FirstChildElement("tracks"); + + for (TiXmlElement* trackElem = tracksNode->FirstChildElement("track"); trackElem != 0; trackElem = trackElem->NextSiblingElement()) + { + String boneName = trackElem->Attribute("bone"); + + //LogManager::getSingleton().logMessage("Track sur le bone: " + boneName ); + + track = anim->createNodeTrack(trackIndex++,skel->getBone(boneName)); + readKeyFrames(track, trackElem->FirstChildElement("keyframes")); + } + + } + + + } + //--------------------------------------------------------------------- + void XMLSkeletonSerializer::readKeyFrames(NodeAnimationTrack* track, TiXmlElement* mKeyfNode) { + + TransformKeyFrame* kf ; + Quaternion q ; + + for (TiXmlElement* keyfElem = mKeyfNode->FirstChildElement("keyframe"); keyfElem != 0; keyfElem = keyfElem->NextSiblingElement()) { - Vector3 trans; - Vector3 axis; - Radian angle; - Real time; + Vector3 trans; + Vector3 axis; + Radian angle; + Real time; // Get time and create keyframe - time = StringConverter::parseReal(keyfElem->Attribute("time")); - kf = track->createNodeKeyFrame(time); + time = StringConverter::parseReal(keyfElem->Attribute("time")); + kf = track->createNodeKeyFrame(time); // Optional translate - TiXmlElement* transElem = keyfElem->FirstChildElement("translate"); + TiXmlElement* transElem = keyfElem->FirstChildElement("translate"); if (transElem) { - trans.x = StringConverter::parseReal(transElem->Attribute("x")); - trans.y = StringConverter::parseReal(transElem->Attribute("y")); - trans.z = StringConverter::parseReal(transElem->Attribute("z")); - kf->setTranslate(trans) ; + trans.x = StringConverter::parseReal(transElem->Attribute("x")); + trans.y = StringConverter::parseReal(transElem->Attribute("y")); + trans.z = StringConverter::parseReal(transElem->Attribute("z")); + kf->setTranslate(trans) ; } // Optional rotate - TiXmlElement* rotElem = keyfElem->FirstChildElement("rotate"); + TiXmlElement* rotElem = keyfElem->FirstChildElement("rotate"); if (rotElem) { TiXmlElement* axisElem = rotElem->FirstChildElement("axis"); @@ -310,31 +310,31 @@ namespace Ogre { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Missing 'axis' element " "expected under parent 'rotate'", "MXLSkeletonSerializer::readKeyFrames"); } - angle = Radian(StringConverter::parseReal(rotElem->Attribute("angle"))); + angle = Radian(StringConverter::parseReal(rotElem->Attribute("angle"))); - axis.x = StringConverter::parseReal(axisElem->Attribute("x")); - axis.y = StringConverter::parseReal(axisElem->Attribute("y")); - axis.z = StringConverter::parseReal(axisElem->Attribute("z")); + axis.x = StringConverter::parseReal(axisElem->Attribute("x")); + axis.y = StringConverter::parseReal(axisElem->Attribute("y")); + axis.z = StringConverter::parseReal(axisElem->Attribute("z")); - q.FromAngleAxis(angle,axis); - kf->setRotation(q) ; + q.FromAngleAxis(angle,axis); + kf->setRotation(q) ; } // Optional scale - TiXmlElement* scaleElem = keyfElem->FirstChildElement("scale"); + TiXmlElement* scaleElem = keyfElem->FirstChildElement("scale"); if (scaleElem) { // Uniform scale or per axis? - const char* factorAttrib = scaleElem->Attribute("factor"); - if (factorAttrib) - { - // Uniform scale - Real factor = StringConverter::parseReal(factorAttrib); - kf->setScale(Vector3(factor, factor, factor)); - } - else - { - // axis scale + const char* factorAttrib = scaleElem->Attribute("factor"); + if (factorAttrib) + { + // Uniform scale + Real factor = StringConverter::parseReal(factorAttrib); + kf->setScale(Vector3(factor, factor, factor)); + } + else + { + // axis scale Real xs = 1.0f, ys = 1.0f, zs=1.0f; const char* factorString = scaleElem->Attribute("x"); if(factorString) @@ -351,28 +351,28 @@ namespace Ogre { { zs = StringConverter::parseReal(factorString); } - kf->setScale(Vector3(xs, ys, zs)); - - } + kf->setScale(Vector3(xs, ys, zs)); + + } } - - /* - LogManager::getSingleton().logMessage("Keyframe: translation(" - + StringConverter::toString(trans.x) + "," + StringConverter::toString(trans.y) + "," + StringConverter::toString(trans.z) + ")" - + " - angle: " + StringConverter::toString(angle) +" - axe: " - + StringConverter::toString(axis.x) + "," + StringConverter::toString(axis.y) + "," + StringConverter::toString(axis.z) ); - */ - + + /* + LogManager::getSingleton().logMessage("Keyframe: translation(" + + StringConverter::toString(trans.x) + "," + StringConverter::toString(trans.y) + "," + StringConverter::toString(trans.z) + ")" + + " - angle: " + StringConverter::toString(angle) +" - axe: " + + StringConverter::toString(axis.x) + "," + StringConverter::toString(axis.y) + "," + StringConverter::toString(axis.z) ); + */ + - } - } + } + } //--------------------------------------------------------------------- void XMLSkeletonSerializer::exportSkeleton(const Skeleton* pSkeleton, const String& filename) { - + LogManager::getSingleton().logMessage("XMLSkeletonSerializer writing " " skeleton data to " + filename + "..."); @@ -387,10 +387,10 @@ namespace Ogre { LogManager::getSingleton().logMessage("Exporting bones.."); writeSkeleton(pSkeleton); LogManager::getSingleton().logMessage("Bones exported."); - + // Write all animations unsigned short numAnims = pSkeleton->getNumAnimations(); - String msg = "Exporting animations, count=" + StringConverter::toString(numAnims); + String msg = "Exporting animations, count=" + StringConverter::toString(numAnims); LogManager::getSingleton().logMessage(msg); TiXmlElement* animsNode = @@ -406,20 +406,20 @@ namespace Ogre { } - // Write links - Skeleton::LinkedSkeletonAnimSourceIterator linkIt = - pSkeleton->getLinkedSkeletonAnimationSourceIterator(); - if (linkIt.hasMoreElements()) - { - LogManager::getSingleton().logMessage("Exporting animation links."); - TiXmlElement* linksNode = - rootNode->InsertEndChild(TiXmlElement("animationlinks"))->ToElement(); - while(linkIt.hasMoreElements()) - { - const LinkedSkeletonAnimationSource& link = linkIt.getNext(); - writeSkeletonAnimationLink(linksNode, link); - } - } + // Write links + Skeleton::LinkedSkeletonAnimSourceIterator linkIt = + pSkeleton->getLinkedSkeletonAnimationSourceIterator(); + if (linkIt.hasMoreElements()) + { + LogManager::getSingleton().logMessage("Exporting animation links."); + TiXmlElement* linksNode = + rootNode->InsertEndChild(TiXmlElement("animationlinks"))->ToElement(); + while(linkIt.hasMoreElements()) + { + const LinkedSkeletonAnimationSource& link = linkIt.getNext(); + writeSkeletonAnimationLink(linksNode, link); + } + } LogManager::getSingleton().logMessage("DOM populated, writing XML file.."); @@ -440,20 +440,20 @@ namespace Ogre { void XMLSkeletonSerializer::writeSkeleton(const Skeleton* pSkel) { TiXmlElement* rootNode = mXMLDoc->RootElement(); - - // Blend mode - String blendModeStr = pSkel->getBlendMode() == ANIMBLEND_CUMULATIVE ? "cumulative" : "average"; - rootNode->SetAttribute("blendmode", blendModeStr); + + // Blend mode + String blendModeStr = pSkel->getBlendMode() == ANIMBLEND_CUMULATIVE ? "cumulative" : "average"; + rootNode->SetAttribute("blendmode", blendModeStr); TiXmlElement* bonesElem = rootNode->InsertEndChild(TiXmlElement("bones"))->ToElement(); unsigned short numBones = pSkel->getNumBones(); - LogManager::getSingleton().logMessage("There are " + StringConverter::toString(numBones) + " bones."); + LogManager::getSingleton().logMessage("There are " + StringConverter::toString(numBones) + " bones."); unsigned short i; for (i = 0; i < numBones; ++i) { - LogManager::getSingleton().logMessage(" Exporting Bone number " + StringConverter::toString(i)); + LogManager::getSingleton().logMessage(" Exporting Bone number " + StringConverter::toString(i)); Bone* pBone = pSkel->getBone(i); writeBone(bonesElem, pBone); } @@ -464,9 +464,9 @@ namespace Ogre { for (i = 0; i < numBones; ++i) { Bone* pBone = pSkel->getBone(i); - String name = pBone->getName() ; + String name = pBone->getName() ; - if ((pBone->getParent())!=NULL) // root bone + if ((pBone->getParent())!=NULL) // root bone { Bone* pParent = (Bone*)pBone->getParent(); writeBoneParent(hierElem, name, pParent->getName()); @@ -523,10 +523,10 @@ namespace Ogre { } //--------------------------------------------------------------------- - // - // Modifications effectuées: - // - // on stoque les noms et pas les Id. c'est plus lisibles. + // + // Modifications effectuées: + // + // on stoque les noms et pas les Id. c'est plus lisibles. void XMLSkeletonSerializer::writeBoneParent(TiXmlElement* boneHierarchyNode, @@ -534,12 +534,12 @@ namespace Ogre { { TiXmlElement* boneParentNode = boneHierarchyNode->InsertEndChild(TiXmlElement("boneparent"))->ToElement(); - /* - boneParentNode->SetAttribute("boneid", StringConverter::toString(boneId)); + /* + boneParentNode->SetAttribute("boneid", StringConverter::toString(boneId)); boneParentNode->SetAttribute("parentid", StringConverter::toString(parentId)); - */ - // Modifications: on stoque les noms./ - boneParentNode->SetAttribute("bone", boneName); + */ + // Modifications: on stoque les noms./ + boneParentNode->SetAttribute("bone", boneName); boneParentNode->SetAttribute("parent", parentName); } @@ -552,15 +552,15 @@ namespace Ogre { animNode->SetAttribute("name", anim->getName()); animNode->SetAttribute("length", StringConverter::toString(anim->getLength())); - - // Optional base keyframe information - if (anim->getUseBaseKeyFrame()) - { - TiXmlElement* baseInfoNode = - animNode->InsertEndChild(TiXmlElement("baseinfo"))->ToElement(); - baseInfoNode->SetAttribute("baseanimationname", anim->getBaseKeyFrameAnimationName()); - baseInfoNode->SetAttribute("basekeyframetime", StringConverter::toString(anim->getBaseKeyFrameTime())); - } + + // Optional base keyframe information + if (anim->getUseBaseKeyFrame()) + { + TiXmlElement* baseInfoNode = + animNode->InsertEndChild(TiXmlElement("baseinfo"))->ToElement(); + baseInfoNode->SetAttribute("baseanimationname", anim->getBaseKeyFrameAnimationName()); + baseInfoNode->SetAttribute("basekeyframetime", StringConverter::toString(anim->getBaseKeyFrameTime())); + } // Write all tracks TiXmlElement* tracksNode = @@ -584,7 +584,7 @@ namespace Ogre { // unsigned short boneIndex : Index of bone to apply to Bone* bone = (Bone*)track->getAssociatedNode(); //unsigned short boneid = bone->getHandle(); - String boneName = bone->getName(); + String boneName = bone->getName(); trackNode->SetAttribute("bone", boneName); // Write all keyframes @@ -597,7 +597,7 @@ namespace Ogre { } //--------------------------------------------------------------------- void XMLSkeletonSerializer::writeKeyFrame(TiXmlElement* keysNode, - const TransformKeyFrame* key) + const TransformKeyFrame* key) { TiXmlElement* keyNode = keysNode->InsertEndChild(TiXmlElement("keyframe"))->ToElement(); @@ -637,40 +637,40 @@ namespace Ogre { } //--------------------------------------------------------------------- - void XMLSkeletonSerializer::writeSkeletonAnimationLink(TiXmlElement* linksNode, - const LinkedSkeletonAnimationSource& link) - { - TiXmlElement* linkNode = - linksNode->InsertEndChild(TiXmlElement("animationlink"))->ToElement(); - linkNode->SetAttribute("skeletonName", link.skeletonName); - linkNode->SetAttribute("scale", StringConverter::toString(link.scale)); - - } - //--------------------------------------------------------------------- - void XMLSkeletonSerializer::readSkeletonAnimationLinks(Skeleton* skel, - TiXmlElement* linksNode) - { - LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Animations links..."); - - for (TiXmlElement* linkElem = linksNode->FirstChildElement("animationlink"); - linkElem != 0; linkElem = linkElem->NextSiblingElement()) - { - String skelName = linkElem->Attribute("skeletonName"); - const char* strScale = linkElem->Attribute("scale"); - Real scale; - // Scale optional - if (strScale == 0) - { - scale = 1.0f; - } - else - { - scale = StringConverter::parseReal(strScale); - } - skel->addLinkedSkeletonAnimationSource(skelName, scale); - - } - } + void XMLSkeletonSerializer::writeSkeletonAnimationLink(TiXmlElement* linksNode, + const LinkedSkeletonAnimationSource& link) + { + TiXmlElement* linkNode = + linksNode->InsertEndChild(TiXmlElement("animationlink"))->ToElement(); + linkNode->SetAttribute("skeletonName", link.skeletonName); + linkNode->SetAttribute("scale", StringConverter::toString(link.scale)); + + } + //--------------------------------------------------------------------- + void XMLSkeletonSerializer::readSkeletonAnimationLinks(Skeleton* skel, + TiXmlElement* linksNode) + { + LogManager::getSingleton().logMessage("XMLSkeletonSerializer: Reading Animations links..."); + + for (TiXmlElement* linkElem = linksNode->FirstChildElement("animationlink"); + linkElem != 0; linkElem = linkElem->NextSiblingElement()) + { + String skelName = linkElem->Attribute("skeletonName"); + const char* strScale = linkElem->Attribute("scale"); + Real scale; + // Scale optional + if (strScale == 0) + { + scale = 1.0f; + } + else + { + scale = StringConverter::parseReal(strScale); + } + skel->addLinkedSkeletonAnimationSource(skelName, scale); + + } + } } diff --git a/Tools/XMLConverter/src/main.cpp b/Tools/XMLConverter/src/main.cpp index f0af5b730a1..a694d129c0e 100644 --- a/Tools/XMLConverter/src/main.cpp +++ b/Tools/XMLConverter/src/main.cpp @@ -60,21 +60,21 @@ struct XmlOptions //Real lodPercent; // Deprecated //size_t lodFixed; // Deprecated size_t nuextremityPoints; - size_t mergeTexcoordResult; - size_t mergeTexcoordToDestroy; + size_t mergeTexcoordResult; + size_t mergeTexcoordToDestroy; bool usePercent; //bool generateEdgeLists; // Deprecated //bool generateTangents; // Deprecated - VertexElementSemantic tangentSemantic; - bool tangentUseParity; - bool tangentSplitMirrored; - bool tangentSplitRotated; + VertexElementSemantic tangentSemantic; + bool tangentUseParity; + bool tangentSplitMirrored; + bool tangentSplitRotated; bool reorganiseBuffers; - bool optimiseAnimations; - bool quietMode; - bool d3d; - bool gl; - Serializer::Endian endian; + bool optimiseAnimations; + bool quietMode; + bool d3d; + bool gl; + Serializer::Endian endian; }; void help(void) @@ -83,17 +83,17 @@ void help(void) cout << endl << "OgreXMLConvert: Converts data between XML and OGRE binary formats." << endl; cout << "Provided for OGRE by Steve Streeting" << endl << endl; cout << "Usage: OgreXMLConverter [options] sourcefile [destfile] " << endl; - cout << endl << "Available options:" << endl; - cout << "-merge [n0,n1] = Merge texcoordn0 with texcoordn1. The , separator must be" << endl; - cout << " present, otherwise only n0 is provided assuming n1 = n0+1;" << endl; - cout << " n0 and n1 must be in the same buffer source & adjacent" << endl; - cout << " to each other for the merge to work." << endl; + cout << endl << "Available options:" << endl; + cout << "-merge [n0,n1] = Merge texcoordn0 with texcoordn1. The , separator must be" << endl; + cout << " present, otherwise only n0 is provided assuming n1 = n0+1;" << endl; + cout << " n0 and n1 must be in the same buffer source & adjacent" << endl; + cout << " to each other for the merge to work." << endl; cout << "-o = DON'T optimise out redundant tracks & keyframes" << endl; - cout << "-d3d = Prefer D3D packed colour formats (default on Windows)" << endl; - cout << "-gl = Prefer GL packed colour formats (default on non-Windows)" << endl; - cout << "-E endian = Set endian mode 'big' 'little' or 'native' (default)" << endl; - cout << "-x num = Generate no more than num eXtremes for every submesh (default 0)" << endl; - cout << "-q = Quiet mode, less output" << endl; + cout << "-d3d = Prefer D3D packed colour formats (default on Windows)" << endl; + cout << "-gl = Prefer GL packed colour formats (default on non-Windows)" << endl; + cout << "-E endian = Set endian mode 'big' 'little' or 'native' (default)" << endl; + cout << "-x num = Generate no more than num eXtremes for every submesh (default 0)" << endl; + cout << "-q = Quiet mode, less output" << endl; cout << "-log filename = name of the log file (default: 'OgreXMLConverter.log')" << endl; cout << "sourcefile = name of file to convert" << endl; cout << "destfile = optional name of file to write to. If you don't" << endl; @@ -116,19 +116,19 @@ XmlOptions parseArgs(int numArgs, char **args) //opts.lodPercent = 20; //opts.numLods = 0; opts.nuextremityPoints = 0; - opts.mergeTexcoordResult = 0; - opts.mergeTexcoordToDestroy = 0; + opts.mergeTexcoordResult = 0; + opts.mergeTexcoordToDestroy = 0; opts.usePercent = true; //opts.generateEdgeLists = true; //opts.generateTangents = false; - //opts.tangentSemantic = VES_TANGENT; - //opts.tangentUseParity = false; - //opts.tangentSplitMirrored = false; - //opts.tangentSplitRotated = false; + //opts.tangentSemantic = VES_TANGENT; + //opts.tangentUseParity = false; + //opts.tangentSplitMirrored = false; + //opts.tangentSplitRotated = false; //opts.reorganiseBuffers = true; - opts.optimiseAnimations = true; + opts.optimiseAnimations = true; opts.quietMode = false; - opts.endian = Serializer::ENDIAN_NATIVE; + opts.endian = Serializer::ENDIAN_NATIVE; // ignore program name char* source = 0; @@ -142,13 +142,13 @@ XmlOptions parseArgs(int numArgs, char **args) //unOpt["-e"] = false; unOpt["-r"] = false; //unOpt["-t"] = false; - unOpt["-tm"] = false; - unOpt["-tr"] = false; + unOpt["-tm"] = false; + unOpt["-tr"] = false; unOpt["-o"] = false; - unOpt["-q"] = false; - unOpt["-d3d"] = false; - unOpt["-gl"] = false; - unOpt["-h"] = false; + unOpt["-q"] = false; + unOpt["-d3d"] = false; + unOpt["-gl"] = false; + unOpt["-h"] = false; //binOpt["-l"] = ""; binOpt["-v"] = ""; //binOpt["-s"] = "Distance"; @@ -157,26 +157,26 @@ XmlOptions parseArgs(int numArgs, char **args) binOpt["-E"] = ""; binOpt["-x"] = ""; binOpt["-log"] = "OgreXMLConverter.log"; - binOpt["-td"] = ""; - binOpt["-ts"] = ""; - binOpt["-merge"] = "0,0"; + binOpt["-td"] = ""; + binOpt["-ts"] = ""; + binOpt["-merge"] = "0,0"; int startIndex = findCommandLineOpts(numArgs, args, unOpt, binOpt); UnaryOptionList::iterator ui; BinaryOptionList::iterator bi; ui = unOpt.find("-h"); - if (ui->second) - { - help(); + if (ui->second) + { + help(); exit(1); - } + } - ui = unOpt.find("-q"); - if (ui->second) - { - opts.quietMode = true; - } + ui = unOpt.find("-q"); + if (ui->second) + { + opts.quietMode = true; + } ui = unOpt.find("-o"); if (ui->second) @@ -184,36 +184,36 @@ XmlOptions parseArgs(int numArgs, char **args) opts.optimiseAnimations = false; } - bi = binOpt.find("-merge"); + bi = binOpt.find("-merge"); if (!bi->second.empty()) { - String::size_type separator = bi->second.find_first_of( "," ); - if( separator == String::npos ) - { - //Input format was "-merge 2" - //Assume we want to merge 2 with 3 - opts.mergeTexcoordResult = StringConverter::parseInt( bi->second, 0 ); - opts.mergeTexcoordToDestroy = opts.mergeTexcoordResult + 1; - } - else if( separator + 1 < bi->second.size() ) - { - //Input format was "-merge 1,2" - //We want to merge 1 with 2 - opts.mergeTexcoordResult = StringConverter::parseInt( - bi->second.substr( 0, separator ), 0 ); - opts.mergeTexcoordToDestroy = StringConverter::parseInt( - bi->second.substr( separator+1, - bi->second.size() ), 1 ); - } + String::size_type separator = bi->second.find_first_of( "," ); + if( separator == String::npos ) + { + //Input format was "-merge 2" + //Assume we want to merge 2 with 3 + opts.mergeTexcoordResult = StringConverter::parseInt( bi->second, 0 ); + opts.mergeTexcoordToDestroy = opts.mergeTexcoordResult + 1; + } + else if( separator + 1 < bi->second.size() ) + { + //Input format was "-merge 1,2" + //We want to merge 1 with 2 + opts.mergeTexcoordResult = StringConverter::parseInt( + bi->second.substr( 0, separator ), 0 ); + opts.mergeTexcoordToDestroy = StringConverter::parseInt( + bi->second.substr( separator+1, + bi->second.size() ), 1 ); + } + } + else + { + //Very rare to reach here. + //Input format was "-merge" + //Assume we want to merge 0 with 1 + opts.mergeTexcoordResult = 0; + opts.mergeTexcoordResult = 1; } - else - { - //Very rare to reach here. - //Input format was "-merge" - //Assume we want to merge 0 with 1 - opts.mergeTexcoordResult = 0; - opts.mergeTexcoordResult = 1; - } bi = binOpt.find("-x"); if (!bi->second.empty()) @@ -238,18 +238,18 @@ XmlOptions parseArgs(int numArgs, char **args) opts.endian = Serializer::ENDIAN_NATIVE; } - ui = unOpt.find("-d3d"); - if (ui->second) - { - opts.d3d = true; - } + ui = unOpt.find("-d3d"); + if (ui->second) + { + opts.d3d = true; + } - ui = unOpt.find("-gl"); - if (ui->second) - { - opts.gl = true; - opts.d3d = false; - } + ui = unOpt.find("-gl"); + if (ui->second) + { + opts.gl = true; + opts.d3d = false; + } // Source / dest if (numArgs > startIndex) @@ -270,9 +270,9 @@ XmlOptions parseArgs(int numArgs, char **args) } // Work out what kind of conversion this is opts.source = source; - Ogre::vector::type srcparts = StringUtil::split(opts.source, "."); + Ogre::vector::type srcparts = StringUtil::split(opts.source, "."); String& ext = srcparts.back(); - StringUtil::toLowerCase(ext); + StringUtil::toLowerCase(ext); opts.sourceExt = ext; if (!dest) @@ -294,13 +294,13 @@ XmlOptions parseArgs(int numArgs, char **args) { opts.dest = dest; } - Ogre::vector::type dstparts = StringUtil::split(opts.dest, "."); + Ogre::vector::type dstparts = StringUtil::split(opts.dest, "."); ext = dstparts.back(); - StringUtil::toLowerCase(ext); + StringUtil::toLowerCase(ext); opts.destExt = ext; if (!opts.quietMode) - { + { cout << endl; cout << "-- OPTIONS --" << endl; cout << "source file = " << opts.source << endl; @@ -308,11 +308,11 @@ XmlOptions parseArgs(int numArgs, char **args) cout << "log file = " << opts.logFile << endl; if (opts.nuextremityPoints) cout << "Generate extremes per submesh = " << opts.nuextremityPoints << endl; - cout << " semantic = " << (opts.tangentSemantic == VES_TANGENT? "TANGENT" : "TEXCOORD") << endl; - cout << " parity = " << opts.tangentUseParity << endl; - cout << " split mirror = " << opts.tangentSplitMirrored << endl; - cout << " split rotated = " << opts.tangentSplitRotated << endl; - + cout << " semantic = " << (opts.tangentSemantic == VES_TANGENT? "TANGENT" : "TEXCOORD") << endl; + cout << " parity = " << opts.tangentUseParity << endl; + cout << " split mirror = " << opts.tangentSplitMirrored << endl; + cout << " split rotated = " << opts.tangentSplitRotated << endl; + cout << "-- END OPTIONS --" << endl; cout << endl; } @@ -382,17 +382,17 @@ void XMLToBinary(XmlOptions opts) delete doc; MeshPtr newMesh = MeshManager::getSingleton().createManual("conversion", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - VertexElementType colourElementType; - if (opts.d3d) - colourElementType = VET_COLOUR_ARGB; - else - colourElementType = VET_COLOUR_ABGR; + VertexElementType colourElementType; + if (opts.d3d) + colourElementType = VET_COLOUR_ARGB; + else + colourElementType = VET_COLOUR_ABGR; xmlMeshSerializer->importMesh(opts.source, colourElementType, newMesh.getPointer()); // Re-jig the buffers? - // Make sure animation types are up to date first - newMesh->_determineAnimationTypes(); + // Make sure animation types are up to date first + newMesh->_determineAnimationTypes(); if (opts.reorganiseBuffers) { logMgr->logMessage("Reorganising vertex buffers to automatic layout..."); @@ -419,7 +419,7 @@ void XMLToBinary(XmlOptions opts) SubMesh* sm = smIt.getNext(); if (!sm->useSharedVertices) { - const bool hasVertexAnim = sm->getVertexAnimationType() != Ogre::VAT_NONE; + const bool hasVertexAnim = sm->getVertexAnimationType() != Ogre::VAT_NONE; // Automatic VertexDeclaration* newDcl = @@ -438,10 +438,10 @@ void XMLToBinary(XmlOptions opts) } - if( opts.mergeTexcoordResult != opts.mergeTexcoordToDestroy ) - { - newMesh->mergeAdjacentTexcoords( opts.mergeTexcoordResult, opts.mergeTexcoordToDestroy ); - } + if( opts.mergeTexcoordResult != opts.mergeTexcoordToDestroy ) + { + newMesh->mergeAdjacentTexcoords( opts.mergeTexcoordResult, opts.mergeTexcoordToDestroy ); + } if (opts.nuextremityPoints) { @@ -464,10 +464,10 @@ void XMLToBinary(XmlOptions opts) SkeletonPtr newSkel = SkeletonManager::getSingleton().create("conversion", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); xmlSkeletonSerializer->importSkeleton(opts.source, newSkel.getPointer()); - if (opts.optimiseAnimations) - { - newSkel->optimiseAllAnimations(); - } + if (opts.optimiseAnimations) + { + newSkel->optimiseAllAnimations(); + } skeletonSerializer->exportSkeleton(newSkel.getPointer(), opts.dest, SKELETON_VERSION_LATEST, opts.endian); // Clean up the conversion skeleton @@ -486,10 +486,10 @@ void skeletonToXML(XmlOptions opts) std::ifstream ifs; ifs.open(opts.source.c_str(), std::ios_base::in | std::ios_base::binary); if (ifs.bad()) - { - cout << "Unable to load file " << opts.source << endl; - exit(1); - } + { + cout << "Unable to load file " << opts.source << endl; + exit(1); + } SkeletonPtr skel = SkeletonManager::getSingleton().create("conversion", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); @@ -512,62 +512,62 @@ int main(int numargs, char** args) return -1; } - // Assume success - int retCode = 0; + // Assume success + int retCode = 0; - try - { - logMgr = new LogManager(); + try + { + logMgr = new LogManager(); // this log catches output from the parseArgs call and routes it to stdout only - logMgr->createLog("Temporary log", false, true, true); + logMgr->createLog("Temporary log", false, true, true); - XmlOptions opts = parseArgs(numargs, args); + XmlOptions opts = parseArgs(numargs, args); // use the log specified by the cmdline params logMgr->setDefaultLog(logMgr->createLog(opts.logFile, false, !opts.quietMode)); // get rid of the temporary log as we use the new log now - logMgr->destroyLog("Temporary log"); + logMgr->destroyLog("Temporary log"); - rgm = new ResourceGroupManager(); - mth = new Math(); + rgm = new ResourceGroupManager(); + mth = new Math(); lodMgr = new LodStrategyManager(); - meshMgr = new MeshManager(); - matMgr = new MaterialManager(); - matMgr->initialise(); - skelMgr = new SkeletonManager(); - meshSerializer = new MeshSerializer(); - xmlMeshSerializer = new XMLMeshSerializer(); - skeletonSerializer = new SkeletonSerializer(); - xmlSkeletonSerializer = new XMLSkeletonSerializer(); - bufferManager = new DefaultHardwareBufferManager(); // needed because we don't have a rendersystem - - - - if (opts.sourceExt == "mesh") - { - meshToXML(opts); - } - else if (opts.sourceExt == "skeleton") - { - skeletonToXML(opts); - } - else if (opts.sourceExt == "xml") - { - XMLToBinary(opts); - } - else - { - cout << "Unknown input type.\n"; - retCode = 1; - } - - } - catch(Exception& e) - { - cerr << "FATAL ERROR: " << e.getDescription() << std::endl; - cerr << "ABORTING!" << std::endl; - retCode = 1; - } + meshMgr = new MeshManager(); + matMgr = new MaterialManager(); + matMgr->initialise(); + skelMgr = new SkeletonManager(); + meshSerializer = new MeshSerializer(); + xmlMeshSerializer = new XMLMeshSerializer(); + skeletonSerializer = new SkeletonSerializer(); + xmlSkeletonSerializer = new XMLSkeletonSerializer(); + bufferManager = new DefaultHardwareBufferManager(); // needed because we don't have a rendersystem + + + + if (opts.sourceExt == "mesh") + { + meshToXML(opts); + } + else if (opts.sourceExt == "skeleton") + { + skeletonToXML(opts); + } + else if (opts.sourceExt == "xml") + { + XMLToBinary(opts); + } + else + { + cout << "Unknown input type.\n"; + retCode = 1; + } + + } + catch(Exception& e) + { + cerr << "FATAL ERROR: " << e.getDescription() << std::endl; + cerr << "ABORTING!" << std::endl; + retCode = 1; + } Pass::processPendingPassUpdates(); // make sure passes are cleaned up @@ -578,7 +578,7 @@ int main(int numargs, char** args) delete skelMgr; delete matMgr; delete meshMgr; - delete bufferManager; + delete bufferManager; delete lodMgr; delete mth; delete rgm; diff --git a/Tools/XMLConverter/src/tinystr.cpp b/Tools/XMLConverter/src/tinystr.cpp index 12850e99d8f..c505e1afa94 100644 --- a/Tools/XMLConverter/src/tinystr.cpp +++ b/Tools/XMLConverter/src/tinystr.cpp @@ -41,76 +41,76 @@ TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, '\0' }; void TiXmlString::reserve (size_type cap) { - if (cap > capacity()) - { - TiXmlString tmp; - tmp.init(length(), cap); - memcpy(tmp.start(), data(), length()); - swap(tmp); - } + if (cap > capacity()) + { + TiXmlString tmp; + tmp.init(length(), cap); + memcpy(tmp.start(), data(), length()); + swap(tmp); + } } TiXmlString& TiXmlString::assign(const char* str, size_type len) { - size_type cap = capacity(); - if (len > cap || cap > 3*(len + 8)) - { - TiXmlString tmp; - tmp.init(len); - memcpy(tmp.start(), str, len); - swap(tmp); - } - else - { - memmove(start(), str, len); - set_size(len); - } - return *this; + size_type cap = capacity(); + if (len > cap || cap > 3*(len + 8)) + { + TiXmlString tmp; + tmp.init(len); + memcpy(tmp.start(), str, len); + swap(tmp); + } + else + { + memmove(start(), str, len); + set_size(len); + } + return *this; } TiXmlString& TiXmlString::append(const char* str, size_type len) { - size_type newsize = length() + len; - if (newsize > capacity()) - { - reserve (newsize + capacity()); - } - memmove(finish(), str, len); - set_size(newsize); - return *this; + size_type newsize = length() + len; + if (newsize > capacity()) + { + reserve (newsize + capacity()); + } + memmove(finish(), str, len); + set_size(newsize); + return *this; } TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) { - TiXmlString tmp; - tmp.reserve(a.length() + b.length()); - tmp += a; - tmp += b; - return tmp; + TiXmlString tmp; + tmp.reserve(a.length() + b.length()); + tmp += a; + tmp += b; + return tmp; } TiXmlString operator + (const TiXmlString & a, const char* b) { - TiXmlString tmp; - TiXmlString::size_type b_len = static_cast( strlen(b) ); - tmp.reserve(a.length() + b_len); - tmp += a; - tmp.append(b, b_len); - return tmp; + TiXmlString tmp; + TiXmlString::size_type b_len = static_cast( strlen(b) ); + tmp.reserve(a.length() + b_len); + tmp += a; + tmp.append(b, b_len); + return tmp; } TiXmlString operator + (const char* a, const TiXmlString & b) { - TiXmlString tmp; - TiXmlString::size_type a_len = static_cast( strlen(a) ); - tmp.reserve(a_len + b.length()); - tmp.append(a, a_len); - tmp += b; - return tmp; + TiXmlString tmp; + TiXmlString::size_type a_len = static_cast( strlen(a) ); + tmp.reserve(a_len + b.length()); + tmp.append(a, a_len); + tmp += b; + return tmp; } -#endif // TIXML_USE_STL +#endif // TIXML_USE_STL diff --git a/Tools/XMLConverter/src/tinyxml.cpp b/Tools/XMLConverter/src/tinyxml.cpp index 7278bd8469a..df888d6c0e4 100644 --- a/Tools/XMLConverter/src/tinyxml.cpp +++ b/Tools/XMLConverter/src/tinyxml.cpp @@ -36,651 +36,651 @@ bool TiXmlBase::condenseWhiteSpace = true; void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString ) { - int i=0; - - while( i<(int)str.length() ) - { - unsigned char c = (unsigned char) str[i]; - - if ( c == '&' - && i < ( (int)str.length() - 2 ) - && str[i+1] == '#' - && str[i+2] == 'x' ) - { - // Hexadecimal character reference. - // Pass through unchanged. - // © -- copyright symbol, for example. - // - // The -1 is a bug fix from Rob Laveaux. It keeps - // an overflow from happening if there is no ';'. - // There are actually 2 ways to exit this loop - - // while fails (error case) and break (semicolon found). - // However, there is no mechanism (currently) for - // this function to return an error. - while ( i<(int)str.length()-1 ) - { - outString->append( str.c_str() + i, 1 ); - ++i; - if ( str[i] == ';' ) - break; - } - } - else if ( c == '&' ) - { - outString->append( entity[0].str, entity[0].strLength ); - ++i; - } - else if ( c == '<' ) - { - outString->append( entity[1].str, entity[1].strLength ); - ++i; - } - else if ( c == '>' ) - { - outString->append( entity[2].str, entity[2].strLength ); - ++i; - } - else if ( c == '\"' ) - { - outString->append( entity[3].str, entity[3].strLength ); - ++i; - } - else if ( c == '\'' ) - { - outString->append( entity[4].str, entity[4].strLength ); - ++i; - } - else if ( c < 32 ) - { - // Easy pass at non-alpha/numeric/symbol - // Below 32 is symbolic. - char buf[ 32 ]; - - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); - #else - sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); - #endif - - //*ME: warning C4267: convert 'size_t' to 'int' - //*ME: Int-Cast to make compiler happy ... - outString->append( buf, (int)strlen( buf ) ); - ++i; - } - else - { - //char realc = (char) c; - //outString->append( &realc, 1 ); - *outString += (char) c; // somewhat more efficient function call. - ++i; - } - } + int i=0; + + while( i<(int)str.length() ) + { + unsigned char c = (unsigned char) str[i]; + + if ( c == '&' + && i < ( (int)str.length() - 2 ) + && str[i+1] == '#' + && str[i+2] == 'x' ) + { + // Hexadecimal character reference. + // Pass through unchanged. + // © -- copyright symbol, for example. + // + // The -1 is a bug fix from Rob Laveaux. It keeps + // an overflow from happening if there is no ';'. + // There are actually 2 ways to exit this loop - + // while fails (error case) and break (semicolon found). + // However, there is no mechanism (currently) for + // this function to return an error. + while ( i<(int)str.length()-1 ) + { + outString->append( str.c_str() + i, 1 ); + ++i; + if ( str[i] == ';' ) + break; + } + } + else if ( c == '&' ) + { + outString->append( entity[0].str, entity[0].strLength ); + ++i; + } + else if ( c == '<' ) + { + outString->append( entity[1].str, entity[1].strLength ); + ++i; + } + else if ( c == '>' ) + { + outString->append( entity[2].str, entity[2].strLength ); + ++i; + } + else if ( c == '\"' ) + { + outString->append( entity[3].str, entity[3].strLength ); + ++i; + } + else if ( c == '\'' ) + { + outString->append( entity[4].str, entity[4].strLength ); + ++i; + } + else if ( c < 32 ) + { + // Easy pass at non-alpha/numeric/symbol + // Below 32 is symbolic. + char buf[ 32 ]; + + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); + #else + sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); + #endif + + //*ME: warning C4267: convert 'size_t' to 'int' + //*ME: Int-Cast to make compiler happy ... + outString->append( buf, (int)strlen( buf ) ); + ++i; + } + else + { + //char realc = (char) c; + //outString->append( &realc, 1 ); + *outString += (char) c; // somewhat more efficient function call. + ++i; + } + } } TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() { - parent = 0; - type = _type; - firstChild = 0; - lastChild = 0; - prev = 0; - next = 0; + parent = 0; + type = _type; + firstChild = 0; + lastChild = 0; + prev = 0; + next = 0; } TiXmlNode::~TiXmlNode() { - TiXmlNode* node = firstChild; - TiXmlNode* temp = 0; + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; - while ( node ) - { - temp = node; - node = node->next; - delete temp; - } + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } } void TiXmlNode::CopyTo( TiXmlNode* target ) const { - target->SetValue (value.c_str() ); - target->userData = userData; + target->SetValue (value.c_str() ); + target->userData = userData; } void TiXmlNode::Clear() { - TiXmlNode* node = firstChild; - TiXmlNode* temp = 0; + TiXmlNode* node = firstChild; + TiXmlNode* temp = 0; - while ( node ) - { - temp = node; - node = node->next; - delete temp; - } + while ( node ) + { + temp = node; + node = node->next; + delete temp; + } - firstChild = 0; - lastChild = 0; + firstChild = 0; + lastChild = 0; } TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) { - assert( node->parent == 0 || node->parent == this ); - assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); + assert( node->parent == 0 || node->parent == this ); + assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); - if ( node->Type() == TiXmlNode::DOCUMENT ) - { - delete node; - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } + if ( node->Type() == TiXmlNode::DOCUMENT ) + { + delete node; + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } - node->parent = this; + node->parent = this; - node->prev = lastChild; - node->next = 0; + node->prev = lastChild; + node->next = 0; - if ( lastChild ) - lastChild->next = node; - else - firstChild = node; // it was an empty list. + if ( lastChild ) + lastChild->next = node; + else + firstChild = node; // it was an empty list. - lastChild = node; - return node; + lastChild = node; + return node; } TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) { - if ( addThis.Type() == TiXmlNode::DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; + if ( addThis.Type() == TiXmlNode::DOCUMENT ) + { + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; - return LinkEndChild( node ); + return LinkEndChild( node ); } TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) -{ - if ( !beforeThis || beforeThis->parent != this ) { - return 0; - } - if ( addThis.Type() == TiXmlNode::DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - node->parent = this; - - node->next = beforeThis; - node->prev = beforeThis->prev; - if ( beforeThis->prev ) - { - beforeThis->prev->next = node; - } - else - { - assert( firstChild == beforeThis ); - firstChild = node; - } - beforeThis->prev = node; - return node; +{ + if ( !beforeThis || beforeThis->parent != this ) { + return 0; + } + if ( addThis.Type() == TiXmlNode::DOCUMENT ) + { + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->next = beforeThis; + node->prev = beforeThis->prev; + if ( beforeThis->prev ) + { + beforeThis->prev->next = node; + } + else + { + assert( firstChild == beforeThis ); + firstChild = node; + } + beforeThis->prev = node; + return node; } TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) { - if ( !afterThis || afterThis->parent != this ) { - return 0; - } - if ( addThis.Type() == TiXmlNode::DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - node->parent = this; - - node->prev = afterThis; - node->next = afterThis->next; - if ( afterThis->next ) - { - afterThis->next->prev = node; - } - else - { - assert( lastChild == afterThis ); - lastChild = node; - } - afterThis->next = node; - return node; + if ( !afterThis || afterThis->parent != this ) { + return 0; + } + if ( addThis.Type() == TiXmlNode::DOCUMENT ) + { + if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + TiXmlNode* node = addThis.Clone(); + if ( !node ) + return 0; + node->parent = this; + + node->prev = afterThis; + node->next = afterThis->next; + if ( afterThis->next ) + { + afterThis->next->prev = node; + } + else + { + assert( lastChild == afterThis ); + lastChild = node; + } + afterThis->next = node; + return node; } TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) { - if ( replaceThis->parent != this ) - return 0; + if ( replaceThis->parent != this ) + return 0; - TiXmlNode* node = withThis.Clone(); - if ( !node ) - return 0; + TiXmlNode* node = withThis.Clone(); + if ( !node ) + return 0; - node->next = replaceThis->next; - node->prev = replaceThis->prev; + node->next = replaceThis->next; + node->prev = replaceThis->prev; - if ( replaceThis->next ) - replaceThis->next->prev = node; - else - lastChild = node; + if ( replaceThis->next ) + replaceThis->next->prev = node; + else + lastChild = node; - if ( replaceThis->prev ) - replaceThis->prev->next = node; - else - firstChild = node; + if ( replaceThis->prev ) + replaceThis->prev->next = node; + else + firstChild = node; - delete replaceThis; - node->parent = this; - return node; + delete replaceThis; + node->parent = this; + return node; } bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) { - if ( removeThis->parent != this ) - { - assert( 0 ); - return false; - } + if ( removeThis->parent != this ) + { + assert( 0 ); + return false; + } - if ( removeThis->next ) - removeThis->next->prev = removeThis->prev; - else - lastChild = removeThis->prev; + if ( removeThis->next ) + removeThis->next->prev = removeThis->prev; + else + lastChild = removeThis->prev; - if ( removeThis->prev ) - removeThis->prev->next = removeThis->next; - else - firstChild = removeThis->next; + if ( removeThis->prev ) + removeThis->prev->next = removeThis->next; + else + firstChild = removeThis->next; - delete removeThis; - return true; + delete removeThis; + return true; } const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const { - const TiXmlNode* node; - for ( node = firstChild; node; node = node->next ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; + const TiXmlNode* node; + for ( node = firstChild; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; } const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const { - const TiXmlNode* node; - for ( node = lastChild; node; node = node->prev ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; + const TiXmlNode* node; + for ( node = lastChild; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; } const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const { - if ( !previous ) - { - return FirstChild(); - } - else - { - assert( previous->parent == this ); - return previous->NextSibling(); - } + if ( !previous ) + { + return FirstChild(); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling(); + } } const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const { - if ( !previous ) - { - return FirstChild( val ); - } - else - { - assert( previous->parent == this ); - return previous->NextSibling( val ); - } + if ( !previous ) + { + return FirstChild( val ); + } + else + { + assert( previous->parent == this ); + return previous->NextSibling( val ); + } } const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const { - const TiXmlNode* node; - for ( node = next; node; node = node->next ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; + const TiXmlNode* node; + for ( node = next; node; node = node->next ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; } const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const { - const TiXmlNode* node; - for ( node = prev; node; node = node->prev ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; + const TiXmlNode* node; + for ( node = prev; node; node = node->prev ) + { + if ( strcmp( node->Value(), _value ) == 0 ) + return node; + } + return 0; } void TiXmlElement::RemoveAttribute( const char * name ) { #ifdef TIXML_USE_STL - TIXML_STRING str( name ); - TiXmlAttribute* node = attributeSet.Find( str ); - #else - TiXmlAttribute* node = attributeSet.Find( name ); - #endif - if ( node ) - { - attributeSet.Remove( node ); - delete node; - } + TIXML_STRING str( name ); + TiXmlAttribute* node = attributeSet.Find( str ); + #else + TiXmlAttribute* node = attributeSet.Find( name ); + #endif + if ( node ) + { + attributeSet.Remove( node ); + delete node; + } } const TiXmlElement* TiXmlNode::FirstChildElement() const { - const TiXmlNode* node; + const TiXmlNode* node; - for ( node = FirstChild(); - node; - node = node->NextSibling() ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; + for ( node = FirstChild(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; } const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const { - const TiXmlNode* node; + const TiXmlNode* node; - for ( node = FirstChild( _value ); - node; - node = node->NextSibling( _value ) ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; + for ( node = FirstChild( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; } const TiXmlElement* TiXmlNode::NextSiblingElement() const { - const TiXmlNode* node; + const TiXmlNode* node; - for ( node = NextSibling(); - node; - node = node->NextSibling() ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; + for ( node = NextSibling(); + node; + node = node->NextSibling() ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; } const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const { - const TiXmlNode* node; + const TiXmlNode* node; - for ( node = NextSibling( _value ); - node; - node = node->NextSibling( _value ) ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; + for ( node = NextSibling( _value ); + node; + node = node->NextSibling( _value ) ) + { + if ( node->ToElement() ) + return node->ToElement(); + } + return 0; } const TiXmlDocument* TiXmlNode::GetDocument() const { - const TiXmlNode* node; + const TiXmlNode* node; - for( node = this; node; node = node->parent ) - { - if ( node->ToDocument() ) - return node->ToDocument(); - } - return 0; + for( node = this; node; node = node->parent ) + { + if ( node->ToDocument() ) + return node->ToDocument(); + } + return 0; } TiXmlElement::TiXmlElement (const char * _value) - : TiXmlNode( TiXmlNode::ELEMENT ) + : TiXmlNode( TiXmlNode::ELEMENT ) { - firstChild = lastChild = 0; - value = _value; + firstChild = lastChild = 0; + value = _value; } #ifdef TIXML_USE_STL TiXmlElement::TiXmlElement( const TIXML_STRING& _value ) - : TiXmlNode( TiXmlNode::ELEMENT ) + : TiXmlNode( TiXmlNode::ELEMENT ) { - firstChild = lastChild = 0; - value = _value; + firstChild = lastChild = 0; + value = _value; } #endif TiXmlElement::TiXmlElement( const TiXmlElement& copy) - : TiXmlNode( TiXmlNode::ELEMENT ) + : TiXmlNode( TiXmlNode::ELEMENT ) { - firstChild = lastChild = 0; - copy.CopyTo( this ); + firstChild = lastChild = 0; + copy.CopyTo( this ); } void TiXmlElement::operator=( const TiXmlElement& base ) { - ClearThis(); - base.CopyTo( this ); + ClearThis(); + base.CopyTo( this ); } TiXmlElement::~TiXmlElement() { - ClearThis(); + ClearThis(); } void TiXmlElement::ClearThis() { - Clear(); - while( attributeSet.First() ) - { - TiXmlAttribute* node = attributeSet.First(); - attributeSet.Remove( node ); - delete node; - } + Clear(); + while( attributeSet.First() ) + { + TiXmlAttribute* node = attributeSet.First(); + attributeSet.Remove( node ); + delete node; + } } const char* TiXmlElement::Attribute( const char* name ) const { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( node ) - return node->Value(); - return 0; + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + return node->Value(); + return 0; } #ifdef TIXML_USE_STL const TIXML_STRING* TiXmlElement::Attribute( const TIXML_STRING& name ) const { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( node ) - return &node->ValueStr(); - return 0; + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + return &node->ValueStr(); + return 0; } #endif const char* TiXmlElement::Attribute( const char* name, int* i ) const { - const char* s = Attribute( name ); - if ( i ) - { - if ( s ) { - *i = atoi( s ); - } - else { - *i = 0; - } - } - return s; + const char* s = Attribute( name ); + if ( i ) + { + if ( s ) { + *i = atoi( s ); + } + else { + *i = 0; + } + } + return s; } #ifdef TIXML_USE_STL const TIXML_STRING* TiXmlElement::Attribute( const TIXML_STRING& name, int* i ) const { - const TIXML_STRING* s = Attribute( name ); - if ( i ) - { - if ( s ) { - *i = atoi( s->c_str() ); - } - else { - *i = 0; - } - } - return s; + const TIXML_STRING* s = Attribute( name ); + if ( i ) + { + if ( s ) { + *i = atoi( s->c_str() ); + } + else { + *i = 0; + } + } + return s; } #endif const char* TiXmlElement::Attribute( const char* name, double* d ) const { - const char* s = Attribute( name ); - if ( d ) - { - if ( s ) { - *d = atof( s ); - } - else { - *d = 0; - } - } - return s; + const char* s = Attribute( name ); + if ( d ) + { + if ( s ) { + *d = atof( s ); + } + else { + *d = 0; + } + } + return s; } #ifdef TIXML_USE_STL const TIXML_STRING* TiXmlElement::Attribute( const TIXML_STRING& name, double* d ) const { - const TIXML_STRING* s = Attribute( name ); - if ( d ) - { - if ( s ) { - *d = atof( s->c_str() ); - } - else { - *d = 0; - } - } - return s; + const TIXML_STRING* s = Attribute( name ); + if ( d ) + { + if ( s ) { + *d = atof( s->c_str() ); + } + else { + *d = 0; + } + } + return s; } #endif int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryIntValue( ival ); + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryIntValue( ival ); } #ifdef TIXML_USE_STL int TiXmlElement::QueryIntAttribute( const TIXML_STRING& name, int* ival ) const { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryIntValue( ival ); + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryIntValue( ival ); } #endif int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryDoubleValue( dval ); + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryDoubleValue( dval ); } #ifdef TIXML_USE_STL int TiXmlElement::QueryDoubleAttribute( const TIXML_STRING& name, double* dval ) const { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryDoubleValue( dval ); + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + return node->QueryDoubleValue( dval ); } #endif void TiXmlElement::SetAttribute( const char * name, int val ) -{ - char buf[64]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%d", val ); - #else - sprintf( buf, "%d", val ); - #endif - SetAttribute( name, buf ); +{ + char buf[64]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%d", val ); + #else + sprintf( buf, "%d", val ); + #endif + SetAttribute( name, buf ); } #ifdef TIXML_USE_STL void TiXmlElement::SetAttribute( const TIXML_STRING& name, int val ) -{ +{ Ogre::StringStream oss; oss << val; SetAttribute( name, oss.str().c_str() ); @@ -689,866 +689,866 @@ void TiXmlElement::SetAttribute( const TIXML_STRING& name, int val ) void TiXmlElement::SetDoubleAttribute( const char * name, double val ) -{ - char buf[256]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%f", val ); - #else - sprintf( buf, "%f", val ); - #endif - SetAttribute( name, buf ); +{ + char buf[256]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%f", val ); + #else + sprintf( buf, "%f", val ); + #endif + SetAttribute( name, buf ); } void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) { #ifdef TIXML_USE_STL - TIXML_STRING _name( cname ); - TIXML_STRING _value( cvalue ); - #else - const char* _name = cname; - const char* _value = cvalue; - #endif - - TiXmlAttribute* node = attributeSet.Find( _name ); - if ( node ) - { - node->SetValue( _value ); - return; - } - - TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue ); - if ( attrib ) - { - attributeSet.Add( attrib ); - } - else - { - TiXmlDocument* document = GetDocument(); - if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); - } + TIXML_STRING _name( cname ); + TIXML_STRING _value( cvalue ); + #else + const char* _name = cname; + const char* _value = cvalue; + #endif + + TiXmlAttribute* node = attributeSet.Find( _name ); + if ( node ) + { + node->SetValue( _value ); + return; + } + + TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocument* document = GetDocument(); + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); + } } #ifdef TIXML_USE_STL void TiXmlElement::SetAttribute( const TIXML_STRING& name, const TIXML_STRING& _value ) { - TiXmlAttribute* node = attributeSet.Find( name ); - if ( node ) - { - node->SetValue( _value ); - return; - } - - TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); - if ( attrib ) - { - attributeSet.Add( attrib ); - } - else - { - TiXmlDocument* document = GetDocument(); - if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); - } + TiXmlAttribute* node = attributeSet.Find( name ); + if ( node ) + { + node->SetValue( _value ); + return; + } + + TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); + if ( attrib ) + { + attributeSet.Add( attrib ); + } + else + { + TiXmlDocument* document = GetDocument(); + if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); + } } #endif void TiXmlElement::Print( FILE* cfile, int depth ) const { - int i; - assert( cfile ); - for ( i=0; iNext() ) - { - fprintf( cfile, " " ); - attrib->Print( cfile, depth ); - } - - // There are 3 different formatting approaches: - // 1) An element without children is printed as a node - // 2) An element with only a text child is printed as text - // 3) An element with children is printed on multiple lines. - TiXmlNode* node; - if ( !firstChild ) - { - fprintf( cfile, " />" ); - } - else if ( firstChild == lastChild && firstChild->ToText() ) - { - fprintf( cfile, ">" ); - firstChild->Print( cfile, depth + 1 ); - fprintf( cfile, "", value.c_str() ); - } - else - { - fprintf( cfile, ">" ); - - for ( node = firstChild; node; node=node->NextSibling() ) - { - if ( !node->ToText() ) - { - fprintf( cfile, "\n" ); - } - node->Print( cfile, depth+1 ); - } - fprintf( cfile, "\n" ); - for( i=0; i", value.c_str() ); - } + int i; + assert( cfile ); + for ( i=0; iNext() ) + { + fprintf( cfile, " " ); + attrib->Print( cfile, depth ); + } + + // There are 3 different formatting approaches: + // 1) An element without children is printed as a node + // 2) An element with only a text child is printed as text + // 3) An element with children is printed on multiple lines. + TiXmlNode* node; + if ( !firstChild ) + { + fprintf( cfile, " />" ); + } + else if ( firstChild == lastChild && firstChild->ToText() ) + { + fprintf( cfile, ">" ); + firstChild->Print( cfile, depth + 1 ); + fprintf( cfile, "", value.c_str() ); + } + else + { + fprintf( cfile, ">" ); + + for ( node = firstChild; node; node=node->NextSibling() ) + { + if ( !node->ToText() ) + { + fprintf( cfile, "\n" ); + } + node->Print( cfile, depth+1 ); + } + fprintf( cfile, "\n" ); + for( i=0; i", value.c_str() ); + } } void TiXmlElement::CopyTo( TiXmlElement* target ) const { - // superclass: - TiXmlNode::CopyTo( target ); + // superclass: + TiXmlNode::CopyTo( target ); - // Element class: - // Clone the attributes, then clone the children. - const TiXmlAttribute* attribute = 0; - for( attribute = attributeSet.First(); - attribute; - attribute = attribute->Next() ) - { - target->SetAttribute( attribute->Name(), attribute->Value() ); - } + // Element class: + // Clone the attributes, then clone the children. + const TiXmlAttribute* attribute = 0; + for( attribute = attributeSet.First(); + attribute; + attribute = attribute->Next() ) + { + target->SetAttribute( attribute->Name(), attribute->Value() ); + } - TiXmlNode* node = 0; - for ( node = firstChild; node; node = node->NextSibling() ) - { - target->LinkEndChild( node->Clone() ); - } + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } } bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const { - if ( visitor->VisitEnter( *this, attributeSet.First() ) ) - { - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - if ( !node->Accept( visitor ) ) - break; - } - } - return visitor->VisitExit( *this ); + if ( visitor->VisitEnter( *this, attributeSet.First() ) ) + { + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + if ( !node->Accept( visitor ) ) + break; + } + } + return visitor->VisitExit( *this ); } TiXmlNode* TiXmlElement::Clone() const { - TiXmlElement* clone = new TiXmlElement( Value() ); - if ( !clone ) - return 0; + TiXmlElement* clone = new TiXmlElement( Value() ); + if ( !clone ) + return 0; - CopyTo( clone ); - return clone; + CopyTo( clone ); + return clone; } const char* TiXmlElement::GetText() const { - const TiXmlNode* child = this->FirstChild(); - if ( child ) { - const TiXmlText* childText = child->ToText(); - if ( childText ) { - return childText->Value(); - } - } - return 0; + const TiXmlNode* child = this->FirstChild(); + if ( child ) { + const TiXmlText* childText = child->ToText(); + if ( childText ) { + return childText->Value(); + } + } + return 0; } TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) { - tabsize = 4; - useMicrosoftBOM = false; - ClearError(); + tabsize = 4; + useMicrosoftBOM = false; + ClearError(); } TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) { - tabsize = 4; - useMicrosoftBOM = false; - value = documentName; - ClearError(); + tabsize = 4; + useMicrosoftBOM = false; + value = documentName; + ClearError(); } #ifdef TIXML_USE_STL TiXmlDocument::TiXmlDocument( const TIXML_STRING& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) { - tabsize = 4; - useMicrosoftBOM = false; + tabsize = 4; + useMicrosoftBOM = false; value = documentName; - ClearError(); + ClearError(); } #endif TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) { - copy.CopyTo( this ); + copy.CopyTo( this ); } void TiXmlDocument::operator=( const TiXmlDocument& copy ) { - Clear(); - copy.CopyTo( this ); + Clear(); + copy.CopyTo( this ); } bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) { - // See STL_STRING_BUG below. - //StringToBuffer buf( value ); + // See STL_STRING_BUG below. + //StringToBuffer buf( value ); - return LoadFile( Value(), encoding ); + return LoadFile( Value(), encoding ); } bool TiXmlDocument::SaveFile() const { - // See STL_STRING_BUG below. -// StringToBuffer buf( value ); + // See STL_STRING_BUG below. +// StringToBuffer buf( value ); // -// if ( buf.buffer && SaveFile( buf.buffer ) ) -// return true; +// if ( buf.buffer && SaveFile( buf.buffer ) ) +// return true; // -// return false; - return SaveFile( Value() ); +// return false; + return SaveFile( Value() ); } bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) { - // There was a really terrifying little bug here. The code: - // value = filename - // in the STL case, cause the assignment method of the TIXML_STRING to - // be called. What is strange, is that the TIXML_STRING had the same - // address as it's c_str() method, and so bad things happen. Looks - // like a bug in the Microsoft STL implementation. - // Add an extra string to avoid the crash. - TIXML_STRING filename( _filename ); - value = filename; - - // reading in binary mode so that tinyxml can normalize the EOL - FILE* file = fopen( value.c_str (), "rb" ); - - if ( file ) - { - bool result = LoadFile( file, encoding ); - fclose( file ); - return result; - } - else - { - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } + // There was a really terrifying little bug here. The code: + // value = filename + // in the STL case, cause the assignment method of the TIXML_STRING to + // be called. What is strange, is that the TIXML_STRING had the same + // address as it's c_str() method, and so bad things happen. Looks + // like a bug in the Microsoft STL implementation. + // Add an extra string to avoid the crash. + TIXML_STRING filename( _filename ); + value = filename; + + // reading in binary mode so that tinyxml can normalize the EOL + FILE* file = fopen( value.c_str (), "rb" ); + + if ( file ) + { + bool result = LoadFile( file, encoding ); + fclose( file ); + return result; + } + else + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } } bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) { - if ( !file ) - { - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // Delete the existing data: - Clear(); - location.Clear(); - - // Get the file size, so we can pre-allocate the string. HUGE speed impact. - long length = 0; - fseek( file, 0, SEEK_END ); - length = ftell( file ); - fseek( file, 0, SEEK_SET ); - - // Strange case, but good to handle up front. - if ( length == 0 ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // If we have a file, assume it is all one big XML file, and read it in. - // The document parser may decide the document ends sooner than the entire file, however. - TIXML_STRING data; - data.reserve( length ); - - // Subtle bug here. TinyXml did use fgets. But from the XML spec: - // 2.11 End-of-Line Handling - // - // - // ...the XML processor MUST behave as if it normalized all line breaks in external - // parsed entities (including the document entity) on input, before parsing, by translating - // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to - // a single #xA character. - // - // - // It is not clear fgets does that, and certainly isn't clear it works cross platform. - // Generally, you expect fgets to translate from the convention of the OS to the c/unix - // convention, and not work generally. - - /* - while( fgets( buf, sizeof(buf), file ) ) - { - data += buf; - } - */ - - char* buf = new char[ length+1 ]; - buf[0] = 0; - - if ( fread( buf, length, 1, file ) != 1 ) { - delete [] buf; - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - const char* lastPos = buf; - const char* p = buf; - - buf[length] = 0; - while( *p ) { - assert( p < (buf+length) ); - if ( *p == 0xa ) { - // Newline character. No special rules for this. Append all the characters - // since the last string, and include the newline. - data.append( lastPos, (p-lastPos+1) ); // append, include the newline - ++p; // move past the newline - lastPos = p; // and point to the new buffer (may be 0) - assert( p <= (buf+length) ); - } - else if ( *p == 0xd ) { - // Carriage return. Append what we have so far, then - // handle moving forward in the buffer. - if ( (p-lastPos) > 0 ) { - data.append( lastPos, p-lastPos ); // do not add the CR - } - data += (char)0xa; // a proper newline - - if ( *(p+1) == 0xa ) { - // Carriage return - new line sequence - p += 2; - lastPos = p; - assert( p <= (buf+length) ); - } - else { - // it was followed by something else...that is presumably characters again. - ++p; - lastPos = p; - assert( p <= (buf+length) ); - } - } - else { - ++p; - } - } - // Handle any left over characters. - if ( p-lastPos ) { - data.append( lastPos, p-lastPos ); - } - delete [] buf; - buf = 0; - - Parse( data.c_str(), 0, encoding ); - - if ( Error() ) + if ( !file ) + { + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // Delete the existing data: + Clear(); + location.Clear(); + + // Get the file size, so we can pre-allocate the string. HUGE speed impact. + long length = 0; + fseek( file, 0, SEEK_END ); + length = ftell( file ); + fseek( file, 0, SEEK_SET ); + + // Strange case, but good to handle up front. + if ( length == 0 ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + // If we have a file, assume it is all one big XML file, and read it in. + // The document parser may decide the document ends sooner than the entire file, however. + TIXML_STRING data; + data.reserve( length ); + + // Subtle bug here. TinyXml did use fgets. But from the XML spec: + // 2.11 End-of-Line Handling + // + // + // ...the XML processor MUST behave as if it normalized all line breaks in external + // parsed entities (including the document entity) on input, before parsing, by translating + // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to + // a single #xA character. + // + // + // It is not clear fgets does that, and certainly isn't clear it works cross platform. + // Generally, you expect fgets to translate from the convention of the OS to the c/unix + // convention, and not work generally. + + /* + while( fgets( buf, sizeof(buf), file ) ) + { + data += buf; + } + */ + + char* buf = new char[ length+1 ]; + buf[0] = 0; + + if ( fread( buf, length, 1, file ) != 1 ) { + delete [] buf; + SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); + return false; + } + + const char* lastPos = buf; + const char* p = buf; + + buf[length] = 0; + while( *p ) { + assert( p < (buf+length) ); + if ( *p == 0xa ) { + // Newline character. No special rules for this. Append all the characters + // since the last string, and include the newline. + data.append( lastPos, (p-lastPos+1) ); // append, include the newline + ++p; // move past the newline + lastPos = p; // and point to the new buffer (may be 0) + assert( p <= (buf+length) ); + } + else if ( *p == 0xd ) { + // Carriage return. Append what we have so far, then + // handle moving forward in the buffer. + if ( (p-lastPos) > 0 ) { + data.append( lastPos, p-lastPos ); // do not add the CR + } + data += (char)0xa; // a proper newline + + if ( *(p+1) == 0xa ) { + // Carriage return - new line sequence + p += 2; + lastPos = p; + assert( p <= (buf+length) ); + } + else { + // it was followed by something else...that is presumably characters again. + ++p; + lastPos = p; + assert( p <= (buf+length) ); + } + } + else { + ++p; + } + } + // Handle any left over characters. + if ( p-lastPos ) { + data.append( lastPos, p-lastPos ); + } + delete [] buf; + buf = 0; + + Parse( data.c_str(), 0, encoding ); + + if ( Error() ) return false; else - return true; + return true; } bool TiXmlDocument::SaveFile( const char * filename ) const { - // The old c stuff lives on... - FILE* fp = fopen( filename, "w" ); - if ( fp ) - { - bool result = SaveFile( fp ); - fclose( fp ); - return result; - } - return false; + // The old c stuff lives on... + FILE* fp = fopen( filename, "w" ); + if ( fp ) + { + bool result = SaveFile( fp ); + fclose( fp ); + return result; + } + return false; } bool TiXmlDocument::SaveFile( FILE* fp ) const { - if ( useMicrosoftBOM ) - { - const unsigned char TIXML_UTF_LEAD_0 = 0xefU; - const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; - const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; + if ( useMicrosoftBOM ) + { + const unsigned char TIXML_UTF_LEAD_0 = 0xefU; + const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; + const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - fputc( TIXML_UTF_LEAD_0, fp ); - fputc( TIXML_UTF_LEAD_1, fp ); - fputc( TIXML_UTF_LEAD_2, fp ); - } - Print( fp, 0 ); - return (ferror(fp) == 0); + fputc( TIXML_UTF_LEAD_0, fp ); + fputc( TIXML_UTF_LEAD_1, fp ); + fputc( TIXML_UTF_LEAD_2, fp ); + } + Print( fp, 0 ); + return (ferror(fp) == 0); } void TiXmlDocument::CopyTo( TiXmlDocument* target ) const { - TiXmlNode::CopyTo( target ); + TiXmlNode::CopyTo( target ); - target->error = error; - target->errorDesc = errorDesc.c_str (); + target->error = error; + target->errorDesc = errorDesc.c_str (); - TiXmlNode* node = 0; - for ( node = firstChild; node; node = node->NextSibling() ) - { - target->LinkEndChild( node->Clone() ); - } + TiXmlNode* node = 0; + for ( node = firstChild; node; node = node->NextSibling() ) + { + target->LinkEndChild( node->Clone() ); + } } TiXmlNode* TiXmlDocument::Clone() const { - TiXmlDocument* clone = new TiXmlDocument(); - if ( !clone ) - return 0; + TiXmlDocument* clone = new TiXmlDocument(); + if ( !clone ) + return 0; - CopyTo( clone ); - return clone; + CopyTo( clone ); + return clone; } void TiXmlDocument::Print( FILE* cfile, int depth ) const { - assert( cfile ); - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - node->Print( cfile, depth ); - fprintf( cfile, "\n" ); - } + assert( cfile ); + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + node->Print( cfile, depth ); + fprintf( cfile, "\n" ); + } } bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const { - if ( visitor->VisitEnter( *this ) ) - { - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - if ( !node->Accept( visitor ) ) - break; - } - } - return visitor->VisitExit( *this ); + if ( visitor->VisitEnter( *this ) ) + { + for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) + { + if ( !node->Accept( visitor ) ) + break; + } + } + return visitor->VisitExit( *this ); } const TiXmlAttribute* TiXmlAttribute::Next() const { - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( next->value.empty() && next->name.empty() ) - return 0; - return next; + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; } /* TiXmlAttribute* TiXmlAttribute::Next() { - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( next->value.empty() && next->name.empty() ) - return 0; - return next; + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( next->value.empty() && next->name.empty() ) + return 0; + return next; } */ const TiXmlAttribute* TiXmlAttribute::Previous() const { - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( prev->value.empty() && prev->name.empty() ) - return 0; - return prev; + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; } /* TiXmlAttribute* TiXmlAttribute::Previous() { - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( prev->value.empty() && prev->name.empty() ) - return 0; - return prev; + // We are using knowledge of the sentinel. The sentinel + // have a value or name. + if ( prev->value.empty() && prev->name.empty() ) + return 0; + return prev; } */ void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const { - TIXML_STRING n, v; + TIXML_STRING n, v; - PutString( name, &n ); - PutString( value, &v ); + PutString( name, &n ); + PutString( value, &v ); - if (value.find ('\"') == TIXML_STRING::npos) { - if ( cfile ) { - fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); - } - if ( str ) { - (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; - } - } - else { - if ( cfile ) { - fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); - } - if ( str ) { - (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; - } - } + if (value.find ('\"') == TIXML_STRING::npos) { + if ( cfile ) { + fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); + } + if ( str ) { + (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\""; + } + } + else { + if ( cfile ) { + fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); + } + if ( str ) { + (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'"; + } + } } int TiXmlAttribute::QueryIntValue( int* ival ) const { - if ( sscanf( value.c_str(), "%d", ival ) == 1 ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; + if ( sscanf( value.c_str(), "%d", ival ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; } int TiXmlAttribute::QueryDoubleValue( double* dval ) const { - if ( sscanf( value.c_str(), "%lf", dval ) == 1 ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; + if ( sscanf( value.c_str(), "%lf", dval ) == 1 ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; } void TiXmlAttribute::SetIntValue( int _value ) { - char buf [64]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); - #else - sprintf (buf, "%d", _value); - #endif - SetValue (buf); + char buf [64]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); + #else + sprintf (buf, "%d", _value); + #endif + SetValue (buf); } void TiXmlAttribute::SetDoubleValue( double _value ) { - char buf [256]; - #if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value); - #else - sprintf (buf, "%lf", _value); - #endif - SetValue (buf); + char buf [256]; + #if defined(TIXML_SNPRINTF) + TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value); + #else + sprintf (buf, "%lf", _value); + #endif + SetValue (buf); } int TiXmlAttribute::IntValue() const { - return atoi (value.c_str ()); + return atoi (value.c_str ()); } double TiXmlAttribute::DoubleValue() const { - return atof (value.c_str ()); + return atof (value.c_str ()); } TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) { - copy.CopyTo( this ); + copy.CopyTo( this ); } void TiXmlComment::operator=( const TiXmlComment& base ) { - Clear(); - base.CopyTo( this ); + Clear(); + base.CopyTo( this ); } void TiXmlComment::Print( FILE* cfile, int depth ) const { - assert( cfile ); - for ( int i=0; i", value.c_str() ); + assert( cfile ); + for ( int i=0; i", value.c_str() ); } void TiXmlComment::CopyTo( TiXmlComment* target ) const { - TiXmlNode::CopyTo( target ); + TiXmlNode::CopyTo( target ); } bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const { - return visitor->Visit( *this ); + return visitor->Visit( *this ); } TiXmlNode* TiXmlComment::Clone() const { - TiXmlComment* clone = new TiXmlComment(); + TiXmlComment* clone = new TiXmlComment(); - if ( !clone ) - return 0; + if ( !clone ) + return 0; - CopyTo( clone ); - return clone; + CopyTo( clone ); + return clone; } void TiXmlText::Print( FILE* cfile, int depth ) const { - assert( cfile ); - if ( cdata ) - { - int i; - fprintf( cfile, "\n" ); - for ( i=0; i\n", value.c_str() ); // unformatted output - } - else - { - TIXML_STRING buffer; - PutString( value, &buffer ); - fprintf( cfile, "%s", buffer.c_str() ); - } + assert( cfile ); + if ( cdata ) + { + int i; + fprintf( cfile, "\n" ); + for ( i=0; i\n", value.c_str() ); // unformatted output + } + else + { + TIXML_STRING buffer; + PutString( value, &buffer ); + fprintf( cfile, "%s", buffer.c_str() ); + } } void TiXmlText::CopyTo( TiXmlText* target ) const { - TiXmlNode::CopyTo( target ); - target->cdata = cdata; + TiXmlNode::CopyTo( target ); + target->cdata = cdata; } bool TiXmlText::Accept( TiXmlVisitor* visitor ) const { - return visitor->Visit( *this ); + return visitor->Visit( *this ); } TiXmlNode* TiXmlText::Clone() const -{ - TiXmlText* clone = 0; - clone = new TiXmlText( "" ); +{ + TiXmlText* clone = 0; + clone = new TiXmlText( "" ); - if ( !clone ) - return 0; + if ( !clone ) + return 0; - CopyTo( clone ); - return clone; + CopyTo( clone ); + return clone; } TiXmlDeclaration::TiXmlDeclaration( const char * _version, - const char * _encoding, - const char * _standalone ) - : TiXmlNode( TiXmlNode::DECLARATION ) + const char * _encoding, + const char * _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) { - version = _version; - encoding = _encoding; - standalone = _standalone; + version = _version; + encoding = _encoding; + standalone = _standalone; } #ifdef TIXML_USE_STL -TiXmlDeclaration::TiXmlDeclaration( const TIXML_STRING& _version, - const TIXML_STRING& _encoding, - const TIXML_STRING& _standalone ) - : TiXmlNode( TiXmlNode::DECLARATION ) +TiXmlDeclaration::TiXmlDeclaration( const TIXML_STRING& _version, + const TIXML_STRING& _encoding, + const TIXML_STRING& _standalone ) + : TiXmlNode( TiXmlNode::DECLARATION ) { - version = _version; - encoding = _encoding; - standalone = _standalone; + version = _version; + encoding = _encoding; + standalone = _standalone; } #endif TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) - : TiXmlNode( TiXmlNode::DECLARATION ) + : TiXmlNode( TiXmlNode::DECLARATION ) { - copy.CopyTo( this ); + copy.CopyTo( this ); } void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) { - Clear(); - copy.CopyTo( this ); + Clear(); + copy.CopyTo( this ); } void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const { - if ( cfile ) fprintf( cfile, "" ); - if ( str ) (*str) += "?>"; + if ( !version.empty() ) { + if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ()); + if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; } + } + if ( !encoding.empty() ) { + if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ()); + if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; } + } + if ( !standalone.empty() ) { + if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ()); + if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; } + } + if ( cfile ) fprintf( cfile, "?>" ); + if ( str ) (*str) += "?>"; } void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const { - TiXmlNode::CopyTo( target ); + TiXmlNode::CopyTo( target ); - target->version = version; - target->encoding = encoding; - target->standalone = standalone; + target->version = version; + target->encoding = encoding; + target->standalone = standalone; } bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const { - return visitor->Visit( *this ); + return visitor->Visit( *this ); } TiXmlNode* TiXmlDeclaration::Clone() const -{ - TiXmlDeclaration* clone = new TiXmlDeclaration(); +{ + TiXmlDeclaration* clone = new TiXmlDeclaration(); - if ( !clone ) - return 0; + if ( !clone ) + return 0; - CopyTo( clone ); - return clone; + CopyTo( clone ); + return clone; } void TiXmlUnknown::Print( FILE* cfile, int depth ) const { - for ( int i=0; i", value.c_str() ); + for ( int i=0; i", value.c_str() ); } void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const { - TiXmlNode::CopyTo( target ); + TiXmlNode::CopyTo( target ); } bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const { - return visitor->Visit( *this ); + return visitor->Visit( *this ); } TiXmlNode* TiXmlUnknown::Clone() const { - TiXmlUnknown* clone = new TiXmlUnknown(); + TiXmlUnknown* clone = new TiXmlUnknown(); - if ( !clone ) - return 0; + if ( !clone ) + return 0; - CopyTo( clone ); - return clone; + CopyTo( clone ); + return clone; } TiXmlAttributeSet::TiXmlAttributeSet() { - sentinel.next = &sentinel; - sentinel.prev = &sentinel; + sentinel.next = &sentinel; + sentinel.prev = &sentinel; } TiXmlAttributeSet::~TiXmlAttributeSet() { - assert( sentinel.next == &sentinel ); - assert( sentinel.prev == &sentinel ); + assert( sentinel.next == &sentinel ); + assert( sentinel.prev == &sentinel ); } void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) { #ifdef TIXML_USE_STL - assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. - #else - assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. - #endif + assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. + #else + assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. + #endif - addMe->next = &sentinel; - addMe->prev = sentinel.prev; + addMe->next = &sentinel; + addMe->prev = sentinel.prev; - sentinel.prev->next = addMe; - sentinel.prev = addMe; + sentinel.prev->next = addMe; + sentinel.prev = addMe; } void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) { - TiXmlAttribute* node; + TiXmlAttribute* node; - for( node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node == removeMe ) - { - node->prev->next = node->next; - node->next->prev = node->prev; - node->next = 0; - node->prev = 0; - return; - } - } - assert( 0 ); // we tried to remove a non-linked attribute. + for( node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node == removeMe ) + { + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + return; + } + } + assert( 0 ); // we tried to remove a non-linked attribute. } #ifdef TIXML_USE_STL const TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name ) const { - for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node->name == name ) - return node; - } - return 0; + for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; } /* -TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name ) +TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name ) { - for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node->name == name ) - return node; - } - return 0; + for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( node->name == name ) + return node; + } + return 0; } */ #endif @@ -1556,311 +1556,311 @@ TiXmlAttribute* TiXmlAttributeSet::Find( const TIXML_STRING& name ) const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const { - for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( strcmp( node->name.c_str(), name ) == 0 ) - return node; - } - return 0; + for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( strcmp( node->name.c_str(), name ) == 0 ) + return node; + } + return 0; } /* -TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) +TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) { - for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( strcmp( node->name.c_str(), name ) == 0 ) - return node; - } - return 0; + for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) + { + if ( strcmp( node->name.c_str(), name ) == 0 ) + return node; + } + return 0; } */ -#ifdef TIXML_USE_STL +#ifdef TIXML_USE_STL std::istream& operator>> (std::istream & in, TiXmlNode & base) { - TIXML_STRING tag; - tag.reserve( 8 * 1000 ); - base.StreamIn( &in, &tag ); + TIXML_STRING tag; + tag.reserve( 8 * 1000 ); + base.StreamIn( &in, &tag ); - base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); - return in; + base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); + return in; } #endif -#ifdef TIXML_USE_STL +#ifdef TIXML_USE_STL std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) { - TiXmlPrinter printer; - printer.SetStreamPrinting(); - base.Accept( &printer ); - out << printer.Str(); + TiXmlPrinter printer; + printer.SetStreamPrinting(); + base.Accept( &printer ); + out << printer.Str(); - return out; + return out; } TIXML_STRING& operator<< (TIXML_STRING& out, const TiXmlNode& base ) { - TiXmlPrinter printer; - printer.SetStreamPrinting(); - base.Accept( &printer ); - out.append( printer.Str() ); + TiXmlPrinter printer; + printer.SetStreamPrinting(); + base.Accept( &printer ); + out.append( printer.Str() ); - return out; + return out; } #endif TiXmlHandle TiXmlHandle::FirstChild() const { - if ( node ) - { - TiXmlNode* child = node->FirstChild(); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); + if ( node ) + { + TiXmlNode* child = node->FirstChild(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const { - if ( node ) - { - TiXmlNode* child = node->FirstChild( value ); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); + if ( node ) + { + TiXmlNode* child = node->FirstChild( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::FirstChildElement() const { - if ( node ) - { - TiXmlElement* child = node->FirstChildElement(); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); + if ( node ) + { + TiXmlElement* child = node->FirstChildElement(); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const { - if ( node ) - { - TiXmlElement* child = node->FirstChildElement( value ); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); + if ( node ) + { + TiXmlElement* child = node->FirstChildElement( value ); + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::Child( int count ) const { - if ( node ) - { - int i; - TiXmlNode* child = node->FirstChild(); - for ( i=0; - child && iNextSibling(), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild(); + for ( i=0; + child && iNextSibling(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const { - if ( node ) - { - int i; - TiXmlNode* child = node->FirstChild( value ); - for ( i=0; - child && iNextSibling( value ), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); + if ( node ) + { + int i; + TiXmlNode* child = node->FirstChild( value ); + for ( i=0; + child && iNextSibling( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::ChildElement( int count ) const { - if ( node ) - { - int i; - TiXmlElement* child = node->FirstChildElement(); - for ( i=0; - child && iNextSiblingElement(), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement(); + for ( i=0; + child && iNextSiblingElement(), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); } TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const { - if ( node ) - { - int i; - TiXmlElement* child = node->FirstChildElement( value ); - for ( i=0; - child && iNextSiblingElement( value ), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); + if ( node ) + { + int i; + TiXmlElement* child = node->FirstChildElement( value ); + for ( i=0; + child && iNextSiblingElement( value ), ++i ) + { + // nothing + } + if ( child ) + return TiXmlHandle( child ); + } + return TiXmlHandle( 0 ); } bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) { - return true; + return true; } bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) { - return true; + return true; } bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) { - DoIndent(); - buffer += "<"; - buffer += element.Value(); - - for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) - { - buffer += " "; - attrib->Print( 0, 0, &buffer ); - } - - if ( !element.FirstChild() ) - { - buffer += " />"; - DoLineBreak(); - } - else - { - buffer += ">"; - if ( element.FirstChild()->ToText() - && element.LastChild() == element.FirstChild() - && element.FirstChild()->ToText()->CDATA() == false ) - { - simpleTextPrint = true; - // no DoLineBreak()! - } - else - { - DoLineBreak(); - } - } - ++depth; - return true; + DoIndent(); + buffer += "<"; + buffer += element.Value(); + + for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) + { + buffer += " "; + attrib->Print( 0, 0, &buffer ); + } + + if ( !element.FirstChild() ) + { + buffer += " />"; + DoLineBreak(); + } + else + { + buffer += ">"; + if ( element.FirstChild()->ToText() + && element.LastChild() == element.FirstChild() + && element.FirstChild()->ToText()->CDATA() == false ) + { + simpleTextPrint = true; + // no DoLineBreak()! + } + else + { + DoLineBreak(); + } + } + ++depth; + return true; } bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) { - --depth; - if ( !element.FirstChild() ) - { - // nothing. - } - else - { - if ( simpleTextPrint ) - { - simpleTextPrint = false; - } - else - { - DoIndent(); - } - buffer += ""; - DoLineBreak(); - } - return true; + --depth; + if ( !element.FirstChild() ) + { + // nothing. + } + else + { + if ( simpleTextPrint ) + { + simpleTextPrint = false; + } + else + { + DoIndent(); + } + buffer += ""; + DoLineBreak(); + } + return true; } bool TiXmlPrinter::Visit( const TiXmlText& text ) { - if ( text.CDATA() ) - { - DoIndent(); - buffer += ""; - DoLineBreak(); - } - else if ( simpleTextPrint ) - { - buffer += text.Value(); - } - else - { - DoIndent(); - buffer += text.Value(); - DoLineBreak(); - } - return true; + if ( text.CDATA() ) + { + DoIndent(); + buffer += ""; + DoLineBreak(); + } + else if ( simpleTextPrint ) + { + buffer += text.Value(); + } + else + { + DoIndent(); + buffer += text.Value(); + DoLineBreak(); + } + return true; } bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) { - DoIndent(); - declaration.Print( 0, 0, &buffer ); - DoLineBreak(); - return true; + DoIndent(); + declaration.Print( 0, 0, &buffer ); + DoLineBreak(); + return true; } bool TiXmlPrinter::Visit( const TiXmlComment& comment ) { - DoIndent(); - buffer += ""; - DoLineBreak(); - return true; + DoIndent(); + buffer += ""; + DoLineBreak(); + return true; } bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) { - DoIndent(); - buffer += "<"; - buffer += unknown.Value(); - buffer += ">"; - DoLineBreak(); - return true; + DoIndent(); + buffer += "<"; + buffer += unknown.Value(); + buffer += ">"; + DoLineBreak(); + return true; } diff --git a/Tools/XMLConverter/src/tinyxmlerror.cpp b/Tools/XMLConverter/src/tinyxmlerror.cpp index d24f63b2e5c..1612b80f776 100644 --- a/Tools/XMLConverter/src/tinyxmlerror.cpp +++ b/Tools/XMLConverter/src/tinyxmlerror.cpp @@ -33,21 +33,21 @@ distribution. const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = { - "No error", - "Error", - "Failed to open file", - "Memory allocation failed.", - "Error parsing Element.", - "Failed to read Element name", - "Error reading Element value.", - "Error reading Attributes.", - "Error: empty tag.", - "Error reading end tag.", - "Error parsing Unknown.", - "Error parsing Comment.", - "Error parsing Declaration.", - "Error document empty.", - "Error null (0) or unexpected EOF found in input stream.", - "Error parsing CDATA.", - "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.", + "No error", + "Error", + "Failed to open file", + "Memory allocation failed.", + "Error parsing Element.", + "Failed to read Element name", + "Error reading Element value.", + "Error reading Attributes.", + "Error: empty tag.", + "Error reading end tag.", + "Error parsing Unknown.", + "Error parsing Comment.", + "Error parsing Declaration.", + "Error document empty.", + "Error null (0) or unexpected EOF found in input stream.", + "Error parsing CDATA.", + "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.", }; diff --git a/Tools/XMLConverter/src/tinyxmlparser.cpp b/Tools/XMLConverter/src/tinyxmlparser.cpp index bb4fdd7ea41..33a42e4b2b5 100644 --- a/Tools/XMLConverter/src/tinyxmlparser.cpp +++ b/Tools/XMLConverter/src/tinyxmlparser.cpp @@ -29,37 +29,37 @@ distribution. //#define DEBUG_PARSER #if defined( DEBUG_PARSER ) -# if defined( DEBUG ) && defined( _MSC_VER ) +# if defined( DEBUG ) && defined( _MSC_VER ) # define WIN32_LEAN_AND_MEAN # define NOMINMAX // required to stop windows.h messing up std::min -# include -# define TIXML_LOG OutputDebugString -# else -# define TIXML_LOG printf -# endif +# include +# define TIXML_LOG OutputDebugString +# else +# define TIXML_LOG printf +# endif #endif // Note tha "PutString" hardcodes the same list. This // is less flexible than it appears. Changing the entries -// or order will break putstring. +// or order will break putstring. TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = { - { "&", 5, '&' }, - { "<", 4, '<' }, - { ">", 4, '>' }, - { """, 6, '\"' }, - { "'", 6, '\'' } + { "&", 5, '&' }, + { "<", 4, '<' }, + { ">", 4, '>' }, + { """, 6, '\"' }, + { "'", 6, '\'' } }; // Bunch of unicode info at: -// http://www.unicode.org/faq/utf_bom.html +// http://www.unicode.org/faq/utf_bom.html // Including the basic of this table, which determines the #bytes in the // sequence from the lead byte. 1 placed for invalid sequences -- // although the result will be junk, pass it through as much as possible. -// Beware of the non-characters in UTF-8: -// ef bb bf (Microsoft "lead bytes") -// ef bf be -// ef bf bf +// Beware of the non-characters in UTF-8: +// ef bb bf (Microsoft "lead bytes") +// ef bf be +// ef bf bf const unsigned char TIXML_UTF_LEAD_0 = 0xefU; const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; @@ -67,333 +67,333 @@ const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; const int TiXmlBase::utf8ByteTable[256] = { - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 - 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte - 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte + 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid }; void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) { - const unsigned long BYTE_MASK = 0xBF; - const unsigned long BYTE_MARK = 0x80; - const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - - if (input < 0x80) - *length = 1; - else if ( input < 0x800 ) - *length = 2; - else if ( input < 0x10000 ) - *length = 3; - else if ( input < 0x200000 ) - *length = 4; - else - { *length = 0; return; } // This code won't covert this correctly anyway. - - output += *length; - - // Scary scary fall throughs. - switch (*length) - { - case 4: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 3: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 2: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 1: - --output; - *output = (char)(input | FIRST_BYTE_MARK[*length]); - } + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + + if (input < 0x80) + *length = 1; + else if ( input < 0x800 ) + *length = 2; + else if ( input < 0x10000 ) + *length = 3; + else if ( input < 0x200000 ) + *length = 4; + else + { *length = 0; return; } // This code won't covert this correctly anyway. + + output += *length; + + // Scary scary fall throughs. + switch (*length) + { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + } } /*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) { - // This will only work for low-ascii, everything else is assumed to be a valid - // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very - // conservative approach. - -// if ( encoding == TIXML_ENCODING_UTF8 ) -// { - if ( anyByte < 127 ) - return isalpha( anyByte ); - else - return 1; // What else to do? The unicode set is huge...get the english ones right. -// } -// else -// { -// return isalpha( anyByte ); -// } + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalpha( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalpha( anyByte ); +// } } /*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) { - // This will only work for low-ascii, everything else is assumed to be a valid - // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very - // conservative approach. - -// if ( encoding == TIXML_ENCODING_UTF8 ) -// { - if ( anyByte < 127 ) - return isalnum( anyByte ); - else - return 1; // What else to do? The unicode set is huge...get the english ones right. -// } -// else -// { -// return isalnum( anyByte ); -// } + // This will only work for low-ascii, everything else is assumed to be a valid + // letter. I'm not sure this is the best approach, but it is quite tricky trying + // to figure out alhabetical vs. not across encoding. So take a very + // conservative approach. + +// if ( encoding == TIXML_ENCODING_UTF8 ) +// { + if ( anyByte < 127 ) + return isalnum( anyByte ); + else + return 1; // What else to do? The unicode set is huge...get the english ones right. +// } +// else +// { +// return isalnum( anyByte ); +// } } class TiXmlParsingData { - friend class TiXmlDocument; + friend class TiXmlDocument; public: - void Stamp( const char* now, TiXmlEncoding encoding ); + void Stamp( const char* now, TiXmlEncoding encoding ); - const TiXmlCursor& Cursor() { return cursor; } + const TiXmlCursor& Cursor() { return cursor; } private: - // Only used by the document! - TiXmlParsingData( const char* start, int _tabsize, int row, int col ) - { - assert( start ); - stamp = start; - tabsize = _tabsize; - cursor.row = row; - cursor.col = col; - } - - TiXmlCursor cursor; - const char* stamp; - int tabsize; + // Only used by the document! + TiXmlParsingData( const char* start, int _tabsize, int row, int col ) + { + assert( start ); + stamp = start; + tabsize = _tabsize; + cursor.row = row; + cursor.col = col; + } + + TiXmlCursor cursor; + const char* stamp; + int tabsize; }; void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) { - assert( now ); - - // Do nothing if the tabsize is 0. - if ( tabsize < 1 ) - { - return; - } - - // Get the current row, column. - int row = cursor.row; - int col = cursor.col; - const char* p = stamp; - assert( p ); - - while ( p < now ) - { - // Treat p as unsigned, so we have a happy compiler. - const unsigned char* pU = (const unsigned char*)p; - - // Code contributed by Fletcher Dunn: (modified by lee) - switch (*pU) { - case 0: - // We *should* never get here, but in case we do, don't - // advance past the terminating null character, ever - return; - - case '\r': - // bump down to the next line - ++row; - col = 0; - // Eat the character - ++p; - - // Check for \r\n sequence, and treat this as a single character - if (*p == '\n') { - ++p; - } - break; - - case '\n': - // bump down to the next line - ++row; - col = 0; - - // Eat the character - ++p; - - // Check for \n\r sequence, and treat this as a single - // character. (Yes, this bizarre thing does occur still - // on some arcane platforms...) - if (*p == '\r') { - ++p; - } - break; - - case '\t': - // Eat the character - ++p; - - // Skip to next tab stop - col = (col / tabsize + 1) * tabsize; - break; - - case TIXML_UTF_LEAD_0: - if ( encoding == TIXML_ENCODING_UTF8 ) - { - if ( *(p+1) && *(p+2) ) - { - // In these cases, don't advance the column. These are - // 0-width spaces. - if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) - p += 3; - else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) - p += 3; - else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) - p += 3; - else - { p +=3; ++col; } // A normal character. - } - } - else - { - ++p; - ++col; - } - break; - - default: - if ( encoding == TIXML_ENCODING_UTF8 ) - { - // Eat the 1 to 4 byte utf8 character. - int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; - if ( step == 0 ) - step = 1; // Error case from bad encoding, but handle gracefully. - p += step; - - // Just advance one column, of course. - ++col; - } - else - { - ++p; - ++col; - } - break; - } - } - cursor.row = row; - cursor.col = col; - assert( cursor.row >= -1 ); - assert( cursor.col >= -1 ); - stamp = p; - assert( stamp ); + assert( now ); + + // Do nothing if the tabsize is 0. + if ( tabsize < 1 ) + { + return; + } + + // Get the current row, column. + int row = cursor.row; + int col = cursor.col; + const char* p = stamp; + assert( p ); + + while ( p < now ) + { + // Treat p as unsigned, so we have a happy compiler. + const unsigned char* pU = (const unsigned char*)p; + + // Code contributed by Fletcher Dunn: (modified by lee) + switch (*pU) { + case 0: + // We *should* never get here, but in case we do, don't + // advance past the terminating null character, ever + return; + + case '\r': + // bump down to the next line + ++row; + col = 0; + // Eat the character + ++p; + + // Check for \r\n sequence, and treat this as a single character + if (*p == '\n') { + ++p; + } + break; + + case '\n': + // bump down to the next line + ++row; + col = 0; + + // Eat the character + ++p; + + // Check for \n\r sequence, and treat this as a single + // character. (Yes, this bizarre thing does occur still + // on some arcane platforms...) + if (*p == '\r') { + ++p; + } + break; + + case '\t': + // Eat the character + ++p; + + // Skip to next tab stop + col = (col / tabsize + 1) * tabsize; + break; + + case TIXML_UTF_LEAD_0: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( *(p+1) && *(p+2) ) + { + // In these cases, don't advance the column. These are + // 0-width spaces. + if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) + p += 3; + else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) + p += 3; + else + { p +=3; ++col; } // A normal character. + } + } + else + { + ++p; + ++col; + } + break; + + default: + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // Eat the 1 to 4 byte utf8 character. + int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; + if ( step == 0 ) + step = 1; // Error case from bad encoding, but handle gracefully. + p += step; + + // Just advance one column, of course. + ++col; + } + else + { + ++p; + ++col; + } + break; + } + } + cursor.row = row; + cursor.col = col; + assert( cursor.row >= -1 ); + assert( cursor.col >= -1 ); + stamp = p; + assert( stamp ); } const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) { - if ( !p || !*p ) - { - return 0; - } - if ( encoding == TIXML_ENCODING_UTF8 ) - { - while ( *p ) - { - const unsigned char* pU = (const unsigned char*)p; - - // Skip the stupid Microsoft UTF-8 Byte order marks - if ( *(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==TIXML_UTF_LEAD_1 - && *(pU+2)==TIXML_UTF_LEAD_2 ) - { - p += 3; - continue; - } - else if(*(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==0xbfU - && *(pU+2)==0xbeU ) - { - p += 3; - continue; - } - else if(*(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==0xbfU - && *(pU+2)==0xbfU ) - { - p += 3; - continue; - } - - if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. - ++p; - else - break; - } - } - else - { - while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) - ++p; - } - - return p; + if ( !p || !*p ) + { + return 0; + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + while ( *p ) + { + const unsigned char* pU = (const unsigned char*)p; + + // Skip the stupid Microsoft UTF-8 Byte order marks + if ( *(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==TIXML_UTF_LEAD_1 + && *(pU+2)==TIXML_UTF_LEAD_2 ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbeU ) + { + p += 3; + continue; + } + else if(*(pU+0)==TIXML_UTF_LEAD_0 + && *(pU+1)==0xbfU + && *(pU+2)==0xbfU ) + { + p += 3; + continue; + } + + if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. + ++p; + else + break; + } + } + else + { + while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) + ++p; + } + + return p; } #ifdef TIXML_USE_STL /*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) { - for( ;; ) - { - if ( !in->good() ) return false; + for( ;; ) + { + if ( !in->good() ) return false; - int c = in->peek(); - // At this scope, we can't get to a document. So fail silently. - if ( !IsWhiteSpace( c ) || c <= 0 ) - return true; + int c = in->peek(); + // At this scope, we can't get to a document. So fail silently. + if ( !IsWhiteSpace( c ) || c <= 0 ) + return true; - *tag += (char) in->get(); - } + *tag += (char) in->get(); + } } /*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) { - //assert( character > 0 && character < 128 ); // else it won't work in utf-8 - while ( in->good() ) - { - int c = in->peek(); - if ( c == character ) - return true; - if ( c <= 0 ) // Silent failure: can't get document at this scope - return false; - - in->get(); - *tag += (char) c; - } - return false; + //assert( character > 0 && character < 128 ); // else it won't work in utf-8 + while ( in->good() ) + { + int c = in->peek(); + if ( c == character ) + return true; + if ( c <= 0 ) // Silent failure: can't get document at this scope + return false; + + in->get(); + *tag += (char) c; + } + return false; } #endif @@ -402,1207 +402,1207 @@ const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) // const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) { - // Oddly, not supported on some comilers, - //name->clear(); - // So use this: - *name = ""; - assert( p ); - - // Names start with letters or underscores. - // Of course, in unicode, tinyxml has no idea what a letter *is*. The - // algorithm is generous. - // - // After that, they can be letters, underscores, numbers, - // hyphens, or colons. (Colons are valid ony for namespaces, - // but tinyxml can't tell namespaces from names.) - if ( p && *p - && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) - { - const char* start = p; - while( p && *p - && ( IsAlphaNum( (unsigned char ) *p, encoding ) - || *p == '_' - || *p == '-' - || *p == '.' - || *p == ':' ) ) - { - //(*name) += *p; // expensive - ++p; - } - if ( p-start > 0 ) { - name->assign( start, p-start ); - } - return p; - } - return 0; + // Oddly, not supported on some comilers, + //name->clear(); + // So use this: + *name = ""; + assert( p ); + + // Names start with letters or underscores. + // Of course, in unicode, tinyxml has no idea what a letter *is*. The + // algorithm is generous. + // + // After that, they can be letters, underscores, numbers, + // hyphens, or colons. (Colons are valid ony for namespaces, + // but tinyxml can't tell namespaces from names.) + if ( p && *p + && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) + { + const char* start = p; + while( p && *p + && ( IsAlphaNum( (unsigned char ) *p, encoding ) + || *p == '_' + || *p == '-' + || *p == '.' + || *p == ':' ) ) + { + //(*name) += *p; // expensive + ++p; + } + if ( p-start > 0 ) { + name->assign( start, p-start ); + } + return p; + } + return 0; } const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) { - // Presume an entity, and pull it out. + // Presume an entity, and pull it out. TIXML_STRING ent; - int i; - *length = 0; - - if ( *(p+1) && *(p+1) == '#' && *(p+2) ) - { - unsigned long ucs = 0; - ptrdiff_t delta = 0; - unsigned mult = 1; - - if ( *(p+2) == 'x' ) - { - // Hexadecimal. - if ( !*(p+3) ) return 0; - - const char* q = p+3; - q = strchr( q, ';' ); - - if ( !q || !*q ) return 0; - - delta = q-p; - --q; - - while ( *q != 'x' ) - { - if ( *q >= '0' && *q <= '9' ) - ucs += mult * (*q - '0'); - else if ( *q >= 'a' && *q <= 'f' ) - ucs += mult * (*q - 'a' + 10); - else if ( *q >= 'A' && *q <= 'F' ) - ucs += mult * (*q - 'A' + 10 ); - else - return 0; - mult *= 16; - --q; - } - } - else - { - // Decimal. - if ( !*(p+2) ) return 0; - - const char* q = p+2; - q = strchr( q, ';' ); - - if ( !q || !*q ) return 0; - - delta = q-p; - --q; - - while ( *q != '#' ) - { - if ( *q >= '0' && *q <= '9' ) - ucs += mult * (*q - '0'); - else - return 0; - mult *= 10; - --q; - } - } - if ( encoding == TIXML_ENCODING_UTF8 ) - { - // convert the UCS to UTF-8 - ConvertUTF32ToUTF8( ucs, value, length ); - } - else - { - *value = (char)ucs; - *length = 1; - } - return p + delta + 1; - } - - // Now try to match it. - for( i=0; i= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else if ( *q >= 'a' && *q <= 'f' ) + ucs += mult * (*q - 'a' + 10); + else if ( *q >= 'A' && *q <= 'F' ) + ucs += mult * (*q - 'A' + 10 ); + else + return 0; + mult *= 16; + --q; + } + } + else + { + // Decimal. + if ( !*(p+2) ) return 0; + + const char* q = p+2; + q = strchr( q, ';' ); + + if ( !q || !*q ) return 0; + + delta = q-p; + --q; + + while ( *q != '#' ) + { + if ( *q >= '0' && *q <= '9' ) + ucs += mult * (*q - '0'); + else + return 0; + mult *= 10; + --q; + } + } + if ( encoding == TIXML_ENCODING_UTF8 ) + { + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8( ucs, value, length ); + } + else + { + *value = (char)ucs; + *length = 1; + } + return p + delta + 1; + } + + // Now try to match it. + for( i=0; iappend( cArr, len ); - } - } - else - { - bool whitespace = false; - - // Remove leading white space: - p = SkipWhiteSpace( p, encoding ); - while ( p && *p - && !StringEqual( p, endTag, caseInsensitive, encoding ) ) - { - if ( *p == '\r' || *p == '\n' ) - { - whitespace = true; - ++p; - } - else if ( IsWhiteSpace( *p ) ) - { - whitespace = true; - ++p; - } - else - { - // If we've found whitespace, add it before the - // new character. Any whitespace just becomes a space. - if ( whitespace ) - { - (*text) += ' '; - whitespace = false; - } - int len; - char cArr[4] = { 0, 0, 0, 0 }; - p = GetChar( p, cArr, &len, encoding ); - if ( len == 1 ) - (*text) += cArr[0]; // more efficient - else - text->append( cArr, len ); - } - } - } - if ( p ) - p += strlen( endTag ); - return p; + if ( !trimWhiteSpace // certain tags always keep whitespace + || !condenseWhiteSpace ) // if true, whitespace is always kept + { + // Keep all the white space. + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive, encoding ) + ) + { + int len; + char cArr[4] = { 0, 0, 0, 0 }; + p = GetChar( p, cArr, &len, encoding ); + text->append( cArr, len ); + } + } + else + { + bool whitespace = false; + + // Remove leading white space: + p = SkipWhiteSpace( p, encoding ); + while ( p && *p + && !StringEqual( p, endTag, caseInsensitive, encoding ) ) + { + if ( *p == '\r' || *p == '\n' ) + { + whitespace = true; + ++p; + } + else if ( IsWhiteSpace( *p ) ) + { + whitespace = true; + ++p; + } + else + { + // If we've found whitespace, add it before the + // new character. Any whitespace just becomes a space. + if ( whitespace ) + { + (*text) += ' '; + whitespace = false; + } + int len; + char cArr[4] = { 0, 0, 0, 0 }; + p = GetChar( p, cArr, &len, encoding ); + if ( len == 1 ) + (*text) += cArr[0]; // more efficient + else + text->append( cArr, len ); + } + } + } + if ( p ) + p += strlen( endTag ); + return p; } #ifdef TIXML_USE_STL void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) { - // The basic issue with a document is that we don't know what we're - // streaming. Read something presumed to be a tag (and hope), then - // identify it, and call the appropriate stream method on the tag. - // - // This "pre-streaming" will never read the closing ">" so the - // sub-tag can orient itself. - - if ( !StreamTo( in, '<', tag ) ) - { - SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - while ( in->good() ) - { - int tagIndex = (int) tag->length(); - while ( in->good() && in->peek() != '>' ) - { - int c = in->get(); - if ( c <= 0 ) - { - SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - break; - } - (*tag) += (char) c; - } - - if ( in->good() ) - { - // We now have something we presume to be a node of - // some sort. Identify it, and call the node to - // continue streaming. - TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); - - if ( node ) - { - node->StreamIn( in, tag ); - bool isElement = node->ToElement() != 0; - delete node; - node = 0; - - // If this is the root element, we're done. Parsing will be - // done by the >> operator. - if ( isElement ) - { - return; - } - } - else - { - SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - } - } - // We should have returned sooner. - SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); + // The basic issue with a document is that we don't know what we're + // streaming. Read something presumed to be a tag (and hope), then + // identify it, and call the appropriate stream method on the tag. + // + // This "pre-streaming" will never read the closing ">" so the + // sub-tag can orient itself. + + if ( !StreamTo( in, '<', tag ) ) + { + SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + while ( in->good() ) + { + int tagIndex = (int) tag->length(); + while ( in->good() && in->peek() != '>' ) + { + int c = in->get(); + if ( c <= 0 ) + { + SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + break; + } + (*tag) += (char) c; + } + + if ( in->good() ) + { + // We now have something we presume to be a node of + // some sort. Identify it, and call the node to + // continue streaming. + TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); + + if ( node ) + { + node->StreamIn( in, tag ); + bool isElement = node->ToElement() != 0; + delete node; + node = 0; + + // If this is the root element, we're done. Parsing will be + // done by the >> operator. + if ( isElement ) + { + return; + } + } + else + { + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + } + } + // We should have returned sooner. + SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); } #endif const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) { - ClearError(); - - // Parse away, at the document level. Since a document - // contains nothing but other tags, most of what happens - // here is skipping white space. - if ( !p || !*p ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - // Note that, for a document, this needs to come - // before the while space skip, so that parsing - // starts from the pointer we are given. - location.Clear(); - if ( prevData ) - { - location.row = prevData->cursor.row; - location.col = prevData->cursor.col; - } - else - { - location.row = 0; - location.col = 0; - } - TiXmlParsingData data( p, TabSize(), location.row, location.col ); - location = data.Cursor(); - - if ( encoding == TIXML_ENCODING_UNKNOWN ) - { - // Check for the Microsoft UTF-8 lead bytes. - const unsigned char* pU = (const unsigned char*)p; - if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 - && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 - && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) - { - encoding = TIXML_ENCODING_UTF8; - useMicrosoftBOM = true; - } - } + ClearError(); + + // Parse away, at the document level. Since a document + // contains nothing but other tags, most of what happens + // here is skipping white space. + if ( !p || !*p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + // Note that, for a document, this needs to come + // before the while space skip, so that parsing + // starts from the pointer we are given. + location.Clear(); + if ( prevData ) + { + location.row = prevData->cursor.row; + location.col = prevData->cursor.col; + } + else + { + location.row = 0; + location.col = 0; + } + TiXmlParsingData data( p, TabSize(), location.row, location.col ); + location = data.Cursor(); + + if ( encoding == TIXML_ENCODING_UNKNOWN ) + { + // Check for the Microsoft UTF-8 lead bytes. + const unsigned char* pU = (const unsigned char*)p; + if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 + && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 + && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) + { + encoding = TIXML_ENCODING_UTF8; + useMicrosoftBOM = true; + } + } p = SkipWhiteSpace( p, encoding ); - if ( !p ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - while ( p && *p ) - { - TiXmlNode* node = Identify( p, encoding ); - if ( node ) - { - p = node->Parse( p, &data, encoding ); - LinkEndChild( node ); - } - else - { - break; - } - - // Did we get encoding info? - if ( encoding == TIXML_ENCODING_UNKNOWN - && node->ToDeclaration() ) - { - TiXmlDeclaration* dec = node->ToDeclaration(); - const char* enc = dec->Encoding(); - assert( enc ); - - if ( *enc == 0 ) - encoding = TIXML_ENCODING_UTF8; - else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) - encoding = TIXML_ENCODING_UTF8; - else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) - encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice - else - encoding = TIXML_ENCODING_LEGACY; - } - - p = SkipWhiteSpace( p, encoding ); - } - - // Was this empty? - if ( !firstChild ) { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); - return 0; - } - - // All is well. - return p; + if ( !p ) + { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); + return 0; + } + + while ( p && *p ) + { + TiXmlNode* node = Identify( p, encoding ); + if ( node ) + { + p = node->Parse( p, &data, encoding ); + LinkEndChild( node ); + } + else + { + break; + } + + // Did we get encoding info? + if ( encoding == TIXML_ENCODING_UNKNOWN + && node->ToDeclaration() ) + { + TiXmlDeclaration* dec = node->ToDeclaration(); + const char* enc = dec->Encoding(); + assert( enc ); + + if ( *enc == 0 ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; + else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) + encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice + else + encoding = TIXML_ENCODING_LEGACY; + } + + p = SkipWhiteSpace( p, encoding ); + } + + // Was this empty? + if ( !firstChild ) { + SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); + return 0; + } + + // All is well. + return p; } void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - // The first error in a chain is more accurate - don't set again! - if ( error ) - return; - - assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); - error = true; - errorId = err; - errorDesc = errorString[ errorId ]; - - errorLocation.Clear(); - if ( pError && data ) - { - data->Stamp( pError, encoding ); - errorLocation = data->Cursor(); - } +{ + // The first error in a chain is more accurate - don't set again! + if ( error ) + return; + + assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); + error = true; + errorId = err; + errorDesc = errorString[ errorId ]; + + errorLocation.Clear(); + if ( pError && data ) + { + data->Stamp( pError, encoding ); + errorLocation = data->Cursor(); + } } TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) { - TiXmlNode* returnNode = 0; - - p = SkipWhiteSpace( p, encoding ); - if( !p || !*p || *p != '<' ) - { - return 0; - } - - TiXmlDocument* doc = GetDocument(); - p = SkipWhiteSpace( p, encoding ); - - if ( !p || !*p ) - { - return 0; - } - - // What is this thing? - // - Elements start with a letter or underscore, but xml is reserved. - // - Comments: "; - - if ( !StringEqual( p, startTag, false, encoding ) ) - { - document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); - return 0; - } - p += strlen( startTag ); - p = ReadText( p, &value, false, endTag, false, encoding ); - return p; + TiXmlDocument* document = GetDocument(); + value = ""; + + p = SkipWhiteSpace( p, encoding ); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + const char* startTag = ""; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + p = ReadText( p, &value, false, endTag, false, encoding ); + return p; } const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) { - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) return 0; - -// int tabsize = 4; -// if ( document ) -// tabsize = document->TabSize(); - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - // Read the name, the '=' and the value. - const char* pErr = p; - p = ReadName( p, &name, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); - return 0; - } - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p || *p != '=' ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - - ++p; // skip '=' - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - - const char* end; - const char SINGLE_QUOTE = '\''; - const char DOUBLE_QUOTE = '\"'; - - if ( *p == SINGLE_QUOTE ) - { - ++p; - end = "\'"; // single quote in string - p = ReadText( p, &value, false, end, false, encoding ); - } - else if ( *p == DOUBLE_QUOTE ) - { - ++p; - end = "\""; // double quote in string - p = ReadText( p, &value, false, end, false, encoding ); - } - else - { - // All attribute values should be in single or double quotes. - // But this is such a common error that the parser will try - // its best, even without them. - value = ""; - while ( p && *p // existence - && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace - && *p != '/' && *p != '>' ) // tag end - { - if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { - // [ 1451649 ] Attribute values with trailing quotes not handled correctly - // We did not have an opening quote but seem to have a - // closing one. Give up and throw an error. - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - value += *p; - ++p; - } - } - return p; + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) return 0; + +// int tabsize = 4; +// if ( document ) +// tabsize = document->TabSize(); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + // Read the name, the '=' and the value. + const char* pErr = p; + p = ReadName( p, &name, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); + return 0; + } + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p || *p != '=' ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + ++p; // skip '=' + p = SkipWhiteSpace( p, encoding ); + if ( !p || !*p ) + { + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + + const char* end; + const char SINGLE_QUOTE = '\''; + const char DOUBLE_QUOTE = '\"'; + + if ( *p == SINGLE_QUOTE ) + { + ++p; + end = "\'"; // single quote in string + p = ReadText( p, &value, false, end, false, encoding ); + } + else if ( *p == DOUBLE_QUOTE ) + { + ++p; + end = "\""; // double quote in string + p = ReadText( p, &value, false, end, false, encoding ); + } + else + { + // All attribute values should be in single or double quotes. + // But this is such a common error that the parser will try + // its best, even without them. + value = ""; + while ( p && *p // existence + && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace + && *p != '/' && *p != '>' ) // tag end + { + if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) { + // [ 1451649 ] Attribute values with trailing quotes not handled correctly + // We did not have an opening quote but seem to have a + // closing one. Give up and throw an error. + if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); + return 0; + } + value += *p; + ++p; + } + } + return p; } #ifdef TIXML_USE_STL void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) { - while ( in->good() ) - { - int c = in->peek(); - if ( !cdata && (c == '<' ) ) - { - return; - } - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - (*tag) += (char) c; - in->get(); // "commits" the peek made above - - if ( cdata && c == '>' && tag->size() >= 3 ) { - size_t len = tag->size(); - if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { - // terminator of cdata. - return; - } - } - } + while ( in->good() ) + { + int c = in->peek(); + if ( !cdata && (c == '<' ) ) + { + return; + } + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + + (*tag) += (char) c; + in->get(); // "commits" the peek made above + + if ( cdata && c == '>' && tag->size() >= 3 ) { + size_t len = tag->size(); + if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) { + // terminator of cdata. + return; + } + } + } } #endif const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) { - value = ""; - TiXmlDocument* document = GetDocument(); - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - - const char* const startTag = ""; - - if ( cdata || StringEqual( p, startTag, false, encoding ) ) - { - cdata = true; - - if ( !StringEqual( p, startTag, false, encoding ) ) - { - document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); - return 0; - } - p += strlen( startTag ); - - // Keep all the white space, ignore the encoding, etc. - while ( p && *p - && !StringEqual( p, endTag, false, encoding ) - ) - { - value += *p; - ++p; - } - - TIXML_STRING dummy; - p = ReadText( p, &dummy, false, endTag, false, encoding ); - return p; - } - else - { - bool ignoreWhite = true; - - const char* end = "<"; - p = ReadText( p, &value, ignoreWhite, end, false, encoding ); - if ( p ) - return p-1; // don't truncate the '<' - return 0; - } + value = ""; + TiXmlDocument* document = GetDocument(); + + if ( data ) + { + data->Stamp( p, encoding ); + location = data->Cursor(); + } + + const char* const startTag = ""; + + if ( cdata || StringEqual( p, startTag, false, encoding ) ) + { + cdata = true; + + if ( !StringEqual( p, startTag, false, encoding ) ) + { + document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); + return 0; + } + p += strlen( startTag ); + + // Keep all the white space, ignore the encoding, etc. + while ( p && *p + && !StringEqual( p, endTag, false, encoding ) + ) + { + value += *p; + ++p; + } + + TIXML_STRING dummy; + p = ReadText( p, &dummy, false, endTag, false, encoding ); + return p; + } + else + { + bool ignoreWhite = true; + + const char* end = "<"; + p = ReadText( p, &value, ignoreWhite, end, false, encoding ); + if ( p ) + return p-1; // don't truncate the '<' + return 0; + } } #ifdef TIXML_USE_STL void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) { - while ( in->good() ) - { - int c = in->get(); - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - (*tag) += (char) c; - - if ( c == '>' ) - { - // All is well. - return; - } - } + while ( in->good() ) + { + int c = in->get(); + if ( c <= 0 ) + { + TiXmlDocument* document = GetDocument(); + if ( document ) + document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); + return; + } + (*tag) += (char) c; + + if ( c == '>' ) + { + // All is well. + return; + } + } } #endif const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) { - p = SkipWhiteSpace( p, _encoding ); - // Find the beginning, find the end, and look for - // the stuff in-between. - TiXmlDocument* document = GetDocument(); - if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); - return 0; - } - if ( data ) - { - data->Stamp( p, _encoding ); - location = data->Cursor(); - } - p += 5; - - version = ""; - encoding = ""; - standalone = ""; - - while ( p && *p ) - { - if ( *p == '>' ) - { - ++p; - return p; - } - - p = SkipWhiteSpace( p, _encoding ); - if ( StringEqual( p, "version", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - version = attrib.Value(); - } - else if ( StringEqual( p, "encoding", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - encoding = attrib.Value(); - } - else if ( StringEqual( p, "standalone", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - standalone = attrib.Value(); - } - else - { - // Read over whatever it is. - while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) - ++p; - } - } - return 0; + p = SkipWhiteSpace( p, _encoding ); + // Find the beginning, find the end, and look for + // the stuff in-between. + TiXmlDocument* document = GetDocument(); + if ( !p || !*p || !StringEqual( p, "SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); + return 0; + } + if ( data ) + { + data->Stamp( p, _encoding ); + location = data->Cursor(); + } + p += 5; + + version = ""; + encoding = ""; + standalone = ""; + + while ( p && *p ) + { + if ( *p == '>' ) + { + ++p; + return p; + } + + p = SkipWhiteSpace( p, _encoding ); + if ( StringEqual( p, "version", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + version = attrib.Value(); + } + else if ( StringEqual( p, "encoding", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + encoding = attrib.Value(); + } + else if ( StringEqual( p, "standalone", true, _encoding ) ) + { + TiXmlAttribute attrib; + p = attrib.Parse( p, data, _encoding ); + standalone = attrib.Value(); + } + else + { + // Read over whatever it is. + while( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) + ++p; + } + } + return 0; } bool TiXmlText::Blank() const { - for ( unsigned i=0; i - { - protected: - XSI::ProgressBar mProgressBar; - size_t mNumberOfStages; - size_t mProgress; - - public: - ProgressManager(size_t numberOfStages); - virtual ~ProgressManager(); - - void progress(void); - - static ProgressManager& getSingleton(void); - static ProgressManager* getSingletonPtr(void); - - }; - - enum XSITrackType - { - XTT_POS_X = 0, - XTT_POS_Y = 1, - XTT_POS_Z = 2, - XTT_ROT_X = 3, - XTT_ROT_Y = 4, - XTT_ROT_Z = 5, - XTT_SCL_X = 6, - XTT_SCL_Y = 7, - XTT_SCL_Z = 8, - XTT_COUNT = 9 - }; - /** An entry for a Deformer - need original index because this will be boneID */ - class DeformerEntry - { - public: - unsigned short boneID; - XSI::X3DObject obj; - String parentName; - StringVector childNames; - bool hasVertexAssignments; - bool parentIsChainEndEffector; - bool hasAnyTracks; - Bone* pBone; - bool ikSample; - double ikSampleInterval; - XSI::MATH::CTransformation initialXform; - // lists of action source items (probably only one per param?) - XSI::AnimationSourceItem xsiTrack[XTT_COUNT]; - - DeformerEntry(unsigned short theboneID, XSI::X3DObject& theobj) - :boneID(theboneID), obj(theobj), hasVertexAssignments(false), - parentIsChainEndEffector(false), hasAnyTracks(false), pBone(0) - - { - } - - }; - /// Map from deformer name to deformer entry - typedef std::map DeformerMap; - - - /** An entry for animation; allows the userto split the timeline into - multiple separate animations. - */ - struct AnimationEntry - { - String animationName; - long startFrame; - long endFrame; - double ikSampleInterval; // skeletal only - }; - /// List of animations - typedef std::list AnimationList; - - /** Record of an XSI GL shader material. */ - struct MaterialEntry - { - String name; - XSI::Shader xsiShader; - }; - /// Map from material name to material entry - typedef std::map MaterialMap; - - /** Record of XSI details that are to become a pass */ - struct PassEntry - { - XSI::CRefArray shaders; - }; - typedef std::deque PassQueue; - - /// Map from texture projection name to index - typedef std::map TextureProjectionMap; - - /** Platform-independent file copy (destination folder must exist) - Maybe use Boost::filesystem if this gets out of hand - */ - void copyFile(const String& src, const String& dest); + class ProgressManager : public Singleton + { + protected: + XSI::ProgressBar mProgressBar; + size_t mNumberOfStages; + size_t mProgress; + + public: + ProgressManager(size_t numberOfStages); + virtual ~ProgressManager(); + + void progress(void); + + static ProgressManager& getSingleton(void); + static ProgressManager* getSingletonPtr(void); + + }; + + enum XSITrackType + { + XTT_POS_X = 0, + XTT_POS_Y = 1, + XTT_POS_Z = 2, + XTT_ROT_X = 3, + XTT_ROT_Y = 4, + XTT_ROT_Z = 5, + XTT_SCL_X = 6, + XTT_SCL_Y = 7, + XTT_SCL_Z = 8, + XTT_COUNT = 9 + }; + /** An entry for a Deformer - need original index because this will be boneID */ + class DeformerEntry + { + public: + unsigned short boneID; + XSI::X3DObject obj; + String parentName; + StringVector childNames; + bool hasVertexAssignments; + bool parentIsChainEndEffector; + bool hasAnyTracks; + Bone* pBone; + bool ikSample; + double ikSampleInterval; + XSI::MATH::CTransformation initialXform; + // lists of action source items (probably only one per param?) + XSI::AnimationSourceItem xsiTrack[XTT_COUNT]; + + DeformerEntry(unsigned short theboneID, XSI::X3DObject& theobj) + :boneID(theboneID), obj(theobj), hasVertexAssignments(false), + parentIsChainEndEffector(false), hasAnyTracks(false), pBone(0) + + { + } + + }; + /// Map from deformer name to deformer entry + typedef std::map DeformerMap; + + + /** An entry for animation; allows the userto split the timeline into + multiple separate animations. + */ + struct AnimationEntry + { + String animationName; + long startFrame; + long endFrame; + double ikSampleInterval; // skeletal only + }; + /// List of animations + typedef std::list AnimationList; + + /** Record of an XSI GL shader material. */ + struct MaterialEntry + { + String name; + XSI::Shader xsiShader; + }; + /// Map from material name to material entry + typedef std::map MaterialMap; + + /** Record of XSI details that are to become a pass */ + struct PassEntry + { + XSI::CRefArray shaders; + }; + typedef std::deque PassQueue; + + /// Map from texture projection name to index + typedef std::map TextureProjectionMap; + + /** Platform-independent file copy (destination folder must exist) + Maybe use Boost::filesystem if this gets out of hand + */ + void copyFile(const String& src, const String& dest); } #endif diff --git a/Tools/XSIExport/include/OgreXSIMaterialExporter.h b/Tools/XSIExport/include/OgreXSIMaterialExporter.h index 0fcf2928330..4b994e23dcf 100644 --- a/Tools/XSIExport/include/OgreXSIMaterialExporter.h +++ b/Tools/XSIExport/include/OgreXSIMaterialExporter.h @@ -34,73 +34,73 @@ THE SOFTWARE. namespace Ogre { - class XsiMaterialExporter - { - public: - XsiMaterialExporter(); - virtual ~XsiMaterialExporter(); - - /** Export a set of XSI materials to a material script. - @param materials List of materials to export - @param filename Name of the script file to create - @param copyTextures Whether to copy any textures used into the same - folder as the material script. - */ - void exportMaterials(MaterialMap& materials, TextureProjectionMap& texProjMap, - const String& filename, bool copyTextures); - protected: - MaterialSerializer mMatSerializer; - - typedef std::multimap TextureUnitTargetMap; - /// Map of target id -> texture unit to match up tex transforms - TextureUnitTargetMap mTextureUnitTargetMap; - /// Pass queue, used to invert ordering - PassQueue mPassQueue; - /// Texture projection map - TextureProjectionMap mTextureProjectionMap; - - - // Export a single material - void exportMaterial(MaterialEntry* matEntry, bool copyTextures, - const String& texturePath); - /// Fill in all the details of a pass - void populatePass(Pass* pass, XSI::Shader& xsishader); - /// Fill in the texture units - note this won't pick up transforms yet - void populatePassTextures(Pass* pass, PassEntry* passEntry, - bool copyTextures, const String& texturePath); - /// Find any texture transforms and hook them up via 'target' - void populatePassTextureTransforms(Pass* pass, XSI::Shader& xsishader); - /// Populate basic rejection parameters for the pass - void populatePassDepthCull(Pass* pass, XSI::Shader& xsishader); - /// Populate lighting parameters for the pass - void populatePassLighting(Pass* pass, XSI::Shader& xsishader); - /// Populate scene blending parameters for the pass - void populatePassSceneBlend(Pass* pass, XSI::Shader& xsishader); - void populatePassCgPrograms(Pass* pass, XSI::Shader& xsishader); - void populatePassHLSLPrograms(Pass* pass, XSI::Shader& xsishader); - void populatePassD3DAssemblerPrograms(Pass* pass, XSI::Shader& xsishader); - void populateOGLFiltering(TextureUnitState* tex, XSI::Shader& xsishader); - void populateDXFiltering(TextureUnitState* tex, XSI::Shader& xsishader); - - - // Utility method to get texture coord set from tspace_id name - unsigned short getTextureCoordIndex(const String& tspace); - - /// Add a 2D texture from a shader - TextureUnitState* add2DTexture(Pass* pass, XSI::Shader& shader, - bool copyTextures, const String& targetFolder); - /// Add a cubic texture from a shader - TextureUnitState* addCubicTexture(Pass* pass, XSI::Shader& shader, - bool copyTextures, const String& targetFolder); - - - void clearPassQueue(void); - - SceneBlendFactor convertSceneBlend(short xsiVal); - TextureUnitState::TextureAddressingMode convertAddressingMode(short xsiVal); - void convertTexGenOGL(TextureUnitState* tex, long xsiVal, XSI::Shader& shader); - void convertTexGenDX(TextureUnitState* tex, long xsiVal, XSI::Shader& shader); - }; + class XsiMaterialExporter + { + public: + XsiMaterialExporter(); + virtual ~XsiMaterialExporter(); + + /** Export a set of XSI materials to a material script. + @param materials List of materials to export + @param filename Name of the script file to create + @param copyTextures Whether to copy any textures used into the same + folder as the material script. + */ + void exportMaterials(MaterialMap& materials, TextureProjectionMap& texProjMap, + const String& filename, bool copyTextures); + protected: + MaterialSerializer mMatSerializer; + + typedef std::multimap TextureUnitTargetMap; + /// Map of target id -> texture unit to match up tex transforms + TextureUnitTargetMap mTextureUnitTargetMap; + /// Pass queue, used to invert ordering + PassQueue mPassQueue; + /// Texture projection map + TextureProjectionMap mTextureProjectionMap; + + + // Export a single material + void exportMaterial(MaterialEntry* matEntry, bool copyTextures, + const String& texturePath); + /// Fill in all the details of a pass + void populatePass(Pass* pass, XSI::Shader& xsishader); + /// Fill in the texture units - note this won't pick up transforms yet + void populatePassTextures(Pass* pass, PassEntry* passEntry, + bool copyTextures, const String& texturePath); + /// Find any texture transforms and hook them up via 'target' + void populatePassTextureTransforms(Pass* pass, XSI::Shader& xsishader); + /// Populate basic rejection parameters for the pass + void populatePassDepthCull(Pass* pass, XSI::Shader& xsishader); + /// Populate lighting parameters for the pass + void populatePassLighting(Pass* pass, XSI::Shader& xsishader); + /// Populate scene blending parameters for the pass + void populatePassSceneBlend(Pass* pass, XSI::Shader& xsishader); + void populatePassCgPrograms(Pass* pass, XSI::Shader& xsishader); + void populatePassHLSLPrograms(Pass* pass, XSI::Shader& xsishader); + void populatePassD3DAssemblerPrograms(Pass* pass, XSI::Shader& xsishader); + void populateOGLFiltering(TextureUnitState* tex, XSI::Shader& xsishader); + void populateDXFiltering(TextureUnitState* tex, XSI::Shader& xsishader); + + + // Utility method to get texture coord set from tspace_id name + unsigned short getTextureCoordIndex(const String& tspace); + + /// Add a 2D texture from a shader + TextureUnitState* add2DTexture(Pass* pass, XSI::Shader& shader, + bool copyTextures, const String& targetFolder); + /// Add a cubic texture from a shader + TextureUnitState* addCubicTexture(Pass* pass, XSI::Shader& shader, + bool copyTextures, const String& targetFolder); + + + void clearPassQueue(void); + + SceneBlendFactor convertSceneBlend(short xsiVal); + TextureUnitState::TextureAddressingMode convertAddressingMode(short xsiVal); + void convertTexGenOGL(TextureUnitState* tex, long xsiVal, XSI::Shader& shader); + void convertTexGenDX(TextureUnitState* tex, long xsiVal, XSI::Shader& shader); + }; } #endif diff --git a/Tools/XSIExport/include/OgreXSIMeshExporter.h b/Tools/XSIExport/include/OgreXSIMeshExporter.h index 344b63e6b14..73ed057c4fc 100644 --- a/Tools/XSIExport/include/OgreXSIMeshExporter.h +++ b/Tools/XSIExport/include/OgreXSIMeshExporter.h @@ -60,53 +60,53 @@ namespace Ogre { XsiMeshExporter(); virtual ~XsiMeshExporter(); - struct LodData - { - Mesh::LodValueList distances; - ProgressiveMesh::VertexReductionQuota quota; - Real reductionValue; - }; + struct LodData + { + Mesh::LodValueList distances; + ProgressiveMesh::VertexReductionQuota quota; + Real reductionValue; + }; - + - - /** Build an OGRe mesh ready for export. + + /** Build an OGRe mesh ready for export. @remarks Every PolygonMesh object is exported as a different SubMesh. Other object types are ignored. - @param mergeSubMeshes Whether to merge submeshes with the same material - @param exportChildren Whether to cascade down each objects children + @param mergeSubMeshes Whether to merge submeshes with the same material + @param exportChildren Whether to cascade down each objects children @param edgeLists Whether to calculate edge lists @param tangents Whether to calculate tangents - @param animList List of animations in use (of any type) - @param materialPrefix Prefix to give all materials - @param lod LOD generation parameters (if required) - @param skeletonName Name of the skeleton to link to if animated - @returns List of deformers (bones) which were found whilst exporting (if - skeletonName was provided) which can be used to determine the skeleton. + @param animList List of animations in use (of any type) + @param materialPrefix Prefix to give all materials + @param lod LOD generation parameters (if required) + @param skeletonName Name of the skeleton to link to if animated + @returns List of deformers (bones) which were found whilst exporting (if + skeletonName was provided) which can be used to determine the skeleton. */ DeformerMap& buildMeshForExport( bool mergeSubMeshes, bool exportChildren, bool edgeLists, - bool tangents, VertexElementSemantic tangentSemantic, bool tangentsSplitMirrored, bool tangentsSplitRotated, bool tangentsUseParity, - bool vertexAnimation, AnimationList& animList, Real fps, const String& materialPrefix = BLANKSTRING, - LodData* lod = 0, const String& skeletonName = ""); - - /** Perform final export of built mesh. - @param fileName Target file name - @param skelAABB AABB of skeleton bones as found in animation, to pad - final bounds of mesh. - */ - void exportMesh(const String& fileName, const AxisAlignedBox& skelAABB); - - /** Get a list of materials which were located during the last call - * to exportMesh. - */ - MaterialMap& getMaterials(void); - - /** Get the map from texture projection names to uv indexes. */ - TextureProjectionMap& getTextureProjectionMap(void); + bool tangents, VertexElementSemantic tangentSemantic, bool tangentsSplitMirrored, bool tangentsSplitRotated, bool tangentsUseParity, + bool vertexAnimation, AnimationList& animList, Real fps, const String& materialPrefix = BLANKSTRING, + LodData* lod = 0, const String& skeletonName = ""); + + /** Perform final export of built mesh. + @param fileName Target file name + @param skelAABB AABB of skeleton bones as found in animation, to pad + final bounds of mesh. + */ + void exportMesh(const String& fileName, const AxisAlignedBox& skelAABB); + + /** Get a list of materials which were located during the last call + * to exportMesh. + */ + MaterialMap& getMaterials(void); + + /** Get the map from texture projection names to uv indexes. */ + TextureProjectionMap& getTextureProjectionMap(void); protected: - MeshPtr mMesh; + MeshPtr mMesh; // XSI Objects XSI::Application mXsiApp; /** This struct represents a unique vertex, identified from a unique @@ -128,216 +128,216 @@ namespace Ogre { }; typedef std::vector UniqueVertexList; - // dynamic index list; 32-bit until we know the max vertex index - typedef std::vector IndexList; - - /** An entry for a PolygonMesh - need the parent X3DObject too */ - class PolygonMeshEntry - { - public: - XSI::CString name; - XSI::MATH::CTransformation transform; - XSI::CGeometryAccessor geometry; - - - PolygonMeshEntry(XSI::CString _name, XSI::MATH::CTransformation _transform, XSI::CGeometryAccessor _geometry) - : name(_name) - , transform(_transform) - , geometry(_geometry) - { - } - - }; - /// ordering function, required for set - struct PolygonMeshEntryLess - { - bool operator()(PolygonMeshEntry* lhs, PolygonMeshEntry* rhs) - { - // can't name objects the same in XSI, so use that - return XSItoOgre(lhs->name) < XSItoOgre(rhs->name); - } - }; - - /** Set of polygon mesh objects we're going to process - * Use a set to avoid exporting the same object twice when manually selected - * and as a child of a selected object. - */ - typedef std::set PolygonMeshList; - PolygonMeshList mXsiPolygonMeshList; - - - - /// List of deformers we've found whilst parsing the objects - DeformerMap mXsiDeformerMap; - /// LIst of materials we've found whilst parsing the objects - MaterialMap mXsiMaterialMap; - /// Map from texture projection names to uv index - TextureProjectionMap mTextureProjectionMap; - /// Material prefix - String mMaterialPrefix; - - - /// Build a list of PolygonMesh instances from selection - void buildPolygonMeshList(bool includeChildren); - /// Tidy up - void cleanupPolygonMeshList(void); - /// Recursive method to locate PolygonMeshes - void findPolygonMeshes(XSI::X3DObject& x3dObj, bool recurse); - /// Build the mesh - void buildMesh(Mesh* pMesh, bool mergeSubmeshes, bool lookForBoneAssignments, - bool vertexAnimation, AnimationList& animList, Real fps); - /// Process a single PolygonMesh into one or more ProtoSubMeshes - void processPolygonMesh(Mesh* pMesh, PolygonMeshEntry* pm, bool lookForBoneAssignments, unsigned short progressUpdates); - /// Find deformers and bone assignments - void processBoneAssignments(Mesh* pMesh, PolygonMeshEntry* pm); - /// Find shape keys for a given mesh - void processShapeKeys(Mesh* pMesh, PolygonMeshEntry* pm); - - /// Tidy up - void cleanupDeformerMap(void); - void cleanupMaterialMap(void); - - typedef std::map IndexRemap; - /** Working area which will become a submesh once we've finished figuring - out what goes in there. - */ - struct ProtoSubMesh - { - // Name of the submesh (may be blank if we're merging) - String name; - // Material name - String materialName; - // unique vertex list - UniqueVertexList uniqueVertices; - // Defines number of texture coord sets and their dimensions - std::vector textureCoordDimensions; - // Vertex colours? - bool hasVertexColours; - // Last polymesh entry added to this proto - PolygonMeshEntry* lastMeshEntry; - // Index offset for last polymesh entry - size_t lastMeshIndexOffset; - // index list - IndexList indices; - // map of polygon mesh -> position index offset (only > 0 when submeshes merged) - typedef std::map PolygonMeshOffsetMap; - PolygonMeshOffsetMap polygonMeshOffsetMap; - // map original position index (+any PM offset) -> first real instance in this one - IndexRemap posIndexRemap; - Mesh::VertexBoneAssignmentList boneAssignments; - /// By-value pose list, build up ready for transfer later - std::list poseList; - /// List of XSI shape keys which are being used in this proto - XSI::CRefArray shapeKeys; - - ProtoSubMesh() : lastMeshEntry(0), lastMeshIndexOffset(0) {} - - - }; - - /// Global shape key to pose mapping - struct ShapeKeyToPoseEntry - { - XSI::CRef shapeKey; - size_t poseIndex; - size_t targetHandle; - - }; - typedef std::list ShapeKeyMapping; - ShapeKeyMapping mShapeKeyMapping; - - struct ShapeClipEntry - { - XSI::Clip clip; - ShapeKeyToPoseEntry* keytoPose; - long startFrame; - long endFrame; - long originalStartFrame; // in case clamped - }; - typedef std::list ShapeClipList; - - - /// List of ProtoSubMeshes that use the same material but are not geometrically compatible - typedef std::list ProtoSubMeshList; - - /// List of proto submeshes by material - typedef std::map MaterialProtoSubMeshMap; - - /// List of proto submeshes by material - MaterialProtoSubMeshMap mMaterialProtoSubmeshMap; - - /// List of deviant proto submeshes by polygon index (clusters) - typedef std::map PolygonToProtoSubMeshList; - - /// List of deviant proto submeshes by polygon index (clusters) - PolygonToProtoSubMeshList mPolygonToProtoSubMeshList; - - // Holds PolygonMesh texture coord information - typedef std::vector TextureCoordDimensionList; - - // Holds PolygonMesh sampler-ordered UV information - typedef std::vector SamplerSetList; - - /// Export the current list of proto submeshes, and clear list - void exportProtoSubMeshes(Mesh* pMesh); + // dynamic index list; 32-bit until we know the max vertex index + typedef std::vector IndexList; + + /** An entry for a PolygonMesh - need the parent X3DObject too */ + class PolygonMeshEntry + { + public: + XSI::CString name; + XSI::MATH::CTransformation transform; + XSI::CGeometryAccessor geometry; + + + PolygonMeshEntry(XSI::CString _name, XSI::MATH::CTransformation _transform, XSI::CGeometryAccessor _geometry) + : name(_name) + , transform(_transform) + , geometry(_geometry) + { + } + + }; + /// ordering function, required for set + struct PolygonMeshEntryLess + { + bool operator()(PolygonMeshEntry* lhs, PolygonMeshEntry* rhs) + { + // can't name objects the same in XSI, so use that + return XSItoOgre(lhs->name) < XSItoOgre(rhs->name); + } + }; + + /** Set of polygon mesh objects we're going to process + * Use a set to avoid exporting the same object twice when manually selected + * and as a child of a selected object. + */ + typedef std::set PolygonMeshList; + PolygonMeshList mXsiPolygonMeshList; + + + + /// List of deformers we've found whilst parsing the objects + DeformerMap mXsiDeformerMap; + /// LIst of materials we've found whilst parsing the objects + MaterialMap mXsiMaterialMap; + /// Map from texture projection names to uv index + TextureProjectionMap mTextureProjectionMap; + /// Material prefix + String mMaterialPrefix; + + + /// Build a list of PolygonMesh instances from selection + void buildPolygonMeshList(bool includeChildren); + /// Tidy up + void cleanupPolygonMeshList(void); + /// Recursive method to locate PolygonMeshes + void findPolygonMeshes(XSI::X3DObject& x3dObj, bool recurse); + /// Build the mesh + void buildMesh(Mesh* pMesh, bool mergeSubmeshes, bool lookForBoneAssignments, + bool vertexAnimation, AnimationList& animList, Real fps); + /// Process a single PolygonMesh into one or more ProtoSubMeshes + void processPolygonMesh(Mesh* pMesh, PolygonMeshEntry* pm, bool lookForBoneAssignments, unsigned short progressUpdates); + /// Find deformers and bone assignments + void processBoneAssignments(Mesh* pMesh, PolygonMeshEntry* pm); + /// Find shape keys for a given mesh + void processShapeKeys(Mesh* pMesh, PolygonMeshEntry* pm); + + /// Tidy up + void cleanupDeformerMap(void); + void cleanupMaterialMap(void); + + typedef std::map IndexRemap; + /** Working area which will become a submesh once we've finished figuring + out what goes in there. + */ + struct ProtoSubMesh + { + // Name of the submesh (may be blank if we're merging) + String name; + // Material name + String materialName; + // unique vertex list + UniqueVertexList uniqueVertices; + // Defines number of texture coord sets and their dimensions + std::vector textureCoordDimensions; + // Vertex colours? + bool hasVertexColours; + // Last polymesh entry added to this proto + PolygonMeshEntry* lastMeshEntry; + // Index offset for last polymesh entry + size_t lastMeshIndexOffset; + // index list + IndexList indices; + // map of polygon mesh -> position index offset (only > 0 when submeshes merged) + typedef std::map PolygonMeshOffsetMap; + PolygonMeshOffsetMap polygonMeshOffsetMap; + // map original position index (+any PM offset) -> first real instance in this one + IndexRemap posIndexRemap; + Mesh::VertexBoneAssignmentList boneAssignments; + /// By-value pose list, build up ready for transfer later + std::list poseList; + /// List of XSI shape keys which are being used in this proto + XSI::CRefArray shapeKeys; + + ProtoSubMesh() : lastMeshEntry(0), lastMeshIndexOffset(0) {} + + + }; + + /// Global shape key to pose mapping + struct ShapeKeyToPoseEntry + { + XSI::CRef shapeKey; + size_t poseIndex; + size_t targetHandle; + + }; + typedef std::list ShapeKeyMapping; + ShapeKeyMapping mShapeKeyMapping; + + struct ShapeClipEntry + { + XSI::Clip clip; + ShapeKeyToPoseEntry* keytoPose; + long startFrame; + long endFrame; + long originalStartFrame; // in case clamped + }; + typedef std::list ShapeClipList; + + + /// List of ProtoSubMeshes that use the same material but are not geometrically compatible + typedef std::list ProtoSubMeshList; + + /// List of proto submeshes by material + typedef std::map MaterialProtoSubMeshMap; + + /// List of proto submeshes by material + MaterialProtoSubMeshMap mMaterialProtoSubmeshMap; + + /// List of deviant proto submeshes by polygon index (clusters) + typedef std::map PolygonToProtoSubMeshList; + + /// List of deviant proto submeshes by polygon index (clusters) + PolygonToProtoSubMeshList mPolygonToProtoSubMeshList; + + // Holds PolygonMesh texture coord information + typedef std::vector TextureCoordDimensionList; + + // Holds PolygonMesh sampler-ordered UV information + typedef std::vector SamplerSetList; + + /// Export the current list of proto submeshes, and clear list + void exportProtoSubMeshes(Mesh* pMesh); /// Export a single ProtoSubMesh void exportProtoSubMesh(Mesh* pMesh, ProtoSubMesh* proto); - /// Export vertex animations - void exportAnimations(Mesh* pMesh, AnimationList& animList, Real fps); - /// Build a list of all shape clips - void buildShapeClipList(ShapeClipList& listToPopulate); - /// Build a list of all shape clips in a container - void buildShapeClipList(XSI::ClipContainer& container, ShapeClipList& listToPopulate); - /// Build a derived clip list for just a specific submesh, and a list of keys to sample - void deriveShapeClipAndKeyframeList(ushort targetIndex, - AnimationEntry& animEntry, ShapeClipList& inClipList, - ShapeClipList& outClipList, std::set& keyFrameList); - /// Retrieve a ProtoSubMesh for the given material name - /// (creates if required, validates if re-using) - ProtoSubMesh* createOrRetrieveProtoSubMesh(const String& materialName, - const String& name, TextureCoordDimensionList& texCoordDims, - bool hasVertexColours); + /// Export vertex animations + void exportAnimations(Mesh* pMesh, AnimationList& animList, Real fps); + /// Build a list of all shape clips + void buildShapeClipList(ShapeClipList& listToPopulate); + /// Build a list of all shape clips in a container + void buildShapeClipList(XSI::ClipContainer& container, ShapeClipList& listToPopulate); + /// Build a derived clip list for just a specific submesh, and a list of keys to sample + void deriveShapeClipAndKeyframeList(ushort targetIndex, + AnimationEntry& animEntry, ShapeClipList& inClipList, + ShapeClipList& outClipList, std::set& keyFrameList); + /// Retrieve a ProtoSubMesh for the given material name + /// (creates if required, validates if re-using) + ProtoSubMesh* createOrRetrieveProtoSubMesh(const String& materialName, + const String& name, TextureCoordDimensionList& texCoordDims, + bool hasVertexColours); /** Try to look up an existing vertex with the same information, or create a new one. @remarks - Note that we buid up the list of unique position indexes that are - actually used by each ProtoSubMesh as we go. When new positions - are found, they are added and a remap entry created to take account - of the fact that there may be extra vertices created in between, or - there may be gaps due to clusters meaning not every position is - used by every ProtoSubMesh. When an existing entry is found, we - compare the vertex data, and if it differs, create a new vertex and - 'chain' it to the previous instances of this position index through - nextIndex. This means that every position vertex has a single - remapped starting point in the per-ProtoSubMesh vertex list, and a - unidirectional linked list of variants of that vertex where other - components differ. + Note that we buid up the list of unique position indexes that are + actually used by each ProtoSubMesh as we go. When new positions + are found, they are added and a remap entry created to take account + of the fact that there may be extra vertices created in between, or + there may be gaps due to clusters meaning not every position is + used by every ProtoSubMesh. When an existing entry is found, we + compare the vertex data, and if it differs, create a new vertex and + 'chain' it to the previous instances of this position index through + nextIndex. This means that every position vertex has a single + remapped starting point in the per-ProtoSubMesh vertex list, and a + unidirectional linked list of variants of that vertex where other + components differ. @par Note that this re-uses as many vertices as possible, and also places every unique vertex in it's final index in one pass, so the return - value from this method can be used as an adjusted vertex index. + value from this method can be used as an adjusted vertex index. @returns The index of the unique vertex */ size_t createOrRetrieveUniqueVertex(ProtoSubMesh* proto, - size_t positionIndex, bool positionIndexIsOriginal, - const UniqueVertex& vertex); + size_t positionIndex, bool positionIndexIsOriginal, + const UniqueVertex& vertex); /** Templatised method for writing indexes */ template void writeIndexes(T* buf, IndexList& indexes); /** Create and fill a vertex buffer */ void createVertexBuffer(VertexData* vd, unsigned short bufIdx, - UniqueVertexList& uniqueVertexList); + UniqueVertexList& uniqueVertexList); - /** Find out the sampler indices for the given triangle */ - void deriveSamplerIndices(const XSI::Triangle& tri, const XSI::PolygonFace& face, - size_t* samplerIndices); - /** Get a single sampler index */ - size_t getSamplerIndex(const XSI::Facet &f, const XSI::Point &p); + /** Find out the sampler indices for the given triangle */ + void deriveSamplerIndices(const XSI::Triangle& tri, const XSI::PolygonFace& face, + size_t* samplerIndices); + /** Get a single sampler index */ + size_t getSamplerIndex(const XSI::Facet &f, const XSI::Point &p); - /** Register the use of a given XSI material. */ - void registerMaterial(const String& name, XSI::Material mat); + /** Register the use of a given XSI material. */ + void registerMaterial(const String& name, XSI::Material mat); }; diff --git a/Tools/XSIExport/include/OgreXSISkeletonExporter.h b/Tools/XSIExport/include/OgreXSISkeletonExporter.h index daf31bf9f56..05bcd472230 100644 --- a/Tools/XSIExport/include/OgreXSISkeletonExporter.h +++ b/Tools/XSIExport/include/OgreXSISkeletonExporter.h @@ -42,70 +42,70 @@ THE SOFTWARE. namespace Ogre { - /** Class for performing a skeleton export from XSI. - */ - class XsiSkeletonExporter - { - public: - XsiSkeletonExporter(); - virtual ~XsiSkeletonExporter(); - - - /** Export a skeleton to the provided filename. - @param skeletonFileName The file name to export to - @param deformers The list of deformers (bones) found during mesh traversal - @param framesPerSecond The number of frames per second - @param animList List of animation splits - @returns AABB derived from bone animations, should be used to pad mesh bounds - */ - const AxisAlignedBox& exportSkeleton(const String& skeletonFileName, - DeformerMap& deformers, float framesPerSecond, - AnimationList& animList); - protected: - // XSI Objects - XSI::Application mXsiApp; - XSI::X3DObject mXsiSceneRoot; - std::map mXSITrackTypeNames; - // Lower-case version of deformer map (XSI seems to be case insensitive and - // some animations rely on that!) - DeformerMap mLowerCaseDeformerMap; - // Actions created as part of IK sampling, will be deleted afterward - XSI::CStringArray mIKSampledAnimations; - AxisAlignedBox mAABB; - - /// Build the bone hierarchy from a simple list of bones - void buildBoneHierarchy(Skeleton* pSkeleton, DeformerMap& deformers, - AnimationList& animList); - /** Link the current bone with it's parent - */ - void linkBoneWithParent(DeformerEntry* deformer, - DeformerMap& deformers, std::list& deformerList); - /** Validate and create a bone, or eliminate the current bone if it - has no animated parameters - */ - void validateAsBone(Skeleton* pSkeleton, DeformerEntry* deformer, - DeformerMap& deformers, std::list& deformerList, - AnimationList& animList); - /// Process an action source - void processActionSource(const XSI::ActionSource& source, DeformerMap& deformers); - /// Bake animations - void createAnimations(Skeleton* pSkel, DeformerMap& deformers, - float framesPerSecond, AnimationList& animList, AxisAlignedBox& AABBPadding); - /// Bake animation tracks by sampling - void createAnimationTracksSampled(Animation* pAnim, AnimationEntry& animEntry, - DeformerMap& deformers, float fps, AxisAlignedBox& AABBPadding); - - void cleanup(void); - void copyDeformerMap(DeformerMap& deformers); - /// Get deformer from passed in map or lower case version - DeformerEntry* getDeformer(const String& name, DeformerMap& deformers); - // Sample all bones, and also sample max global bone position for AABB padding - void sampleAllBones(DeformerMap& deformers, - std::vector deformerTracks, double frame, - Real time, float fps, AxisAlignedBox& AABBPadding); - void establishInitialTransforms(DeformerMap& deformers); - - }; + /** Class for performing a skeleton export from XSI. + */ + class XsiSkeletonExporter + { + public: + XsiSkeletonExporter(); + virtual ~XsiSkeletonExporter(); + + + /** Export a skeleton to the provided filename. + @param skeletonFileName The file name to export to + @param deformers The list of deformers (bones) found during mesh traversal + @param framesPerSecond The number of frames per second + @param animList List of animation splits + @returns AABB derived from bone animations, should be used to pad mesh bounds + */ + const AxisAlignedBox& exportSkeleton(const String& skeletonFileName, + DeformerMap& deformers, float framesPerSecond, + AnimationList& animList); + protected: + // XSI Objects + XSI::Application mXsiApp; + XSI::X3DObject mXsiSceneRoot; + std::map mXSITrackTypeNames; + // Lower-case version of deformer map (XSI seems to be case insensitive and + // some animations rely on that!) + DeformerMap mLowerCaseDeformerMap; + // Actions created as part of IK sampling, will be deleted afterward + XSI::CStringArray mIKSampledAnimations; + AxisAlignedBox mAABB; + + /// Build the bone hierarchy from a simple list of bones + void buildBoneHierarchy(Skeleton* pSkeleton, DeformerMap& deformers, + AnimationList& animList); + /** Link the current bone with it's parent + */ + void linkBoneWithParent(DeformerEntry* deformer, + DeformerMap& deformers, std::list& deformerList); + /** Validate and create a bone, or eliminate the current bone if it + has no animated parameters + */ + void validateAsBone(Skeleton* pSkeleton, DeformerEntry* deformer, + DeformerMap& deformers, std::list& deformerList, + AnimationList& animList); + /// Process an action source + void processActionSource(const XSI::ActionSource& source, DeformerMap& deformers); + /// Bake animations + void createAnimations(Skeleton* pSkel, DeformerMap& deformers, + float framesPerSecond, AnimationList& animList, AxisAlignedBox& AABBPadding); + /// Bake animation tracks by sampling + void createAnimationTracksSampled(Animation* pAnim, AnimationEntry& animEntry, + DeformerMap& deformers, float fps, AxisAlignedBox& AABBPadding); + + void cleanup(void); + void copyDeformerMap(DeformerMap& deformers); + /// Get deformer from passed in map or lower case version + DeformerEntry* getDeformer(const String& name, DeformerMap& deformers); + // Sample all bones, and also sample max global bone position for AABB padding + void sampleAllBones(DeformerMap& deformers, + std::vector deformerTracks, double frame, + Real time, float fps, AxisAlignedBox& AABBPadding); + void establishInitialTransforms(DeformerMap& deformers); + + }; diff --git a/Tools/XSIExport/src/OgreXSIExport.cpp b/Tools/XSIExport/src/OgreXSIExport.cpp index a6fb374e815..7a614a0bb47 100644 --- a/Tools/XSIExport/src/OgreXSIExport.cpp +++ b/Tools/XSIExport/src/OgreXSIExport.cpp @@ -125,27 +125,27 @@ extern "C" /** Registers the export command, the menu item, and the option dialog */ CStatus XSILoadPlugin( XSI::PluginRegistrar& registrar ) { - registrar.PutAuthor( L"Steve Streeting" ); - registrar.PutName( L"OGRE Exporter Plugin" ); + registrar.PutAuthor( L"Steve Streeting" ); + registrar.PutName( L"OGRE Exporter Plugin" ); registrar.PutVersion( 1, 0 ); registrar.PutURL(L"http://www.ogre3d.org"); - // register the mesh export command - registrar.RegisterCommand( L"OgreMeshExportCommand", L"OgreMeshExportCommand" ); + // register the mesh export command + registrar.RegisterCommand( L"OgreMeshExportCommand", L"OgreMeshExportCommand" ); // register the menu under File > Export - registrar.RegisterMenu(siMenuMainFileExportID, L"OgreMeshExportMenu", false, false); + registrar.RegisterMenu(siMenuMainFileExportID, L"OgreMeshExportMenu", false, false); - // register the export dialog properties factory - registrar.RegisterProperty( L"OgreMeshExportOptions" ); + // register the export dialog properties factory + registrar.RegisterProperty( L"OgreMeshExportOptions" ); #ifdef _DEBUG Application app; app.LogMessage( registrar.GetName() + L" has been loaded."); #endif - return XSI::CStatus::OK; + return XSI::CStatus::OK; } #ifdef unix @@ -156,10 +156,10 @@ XSI::CStatus XSIUnloadPlugin( const XSI::PluginRegistrar& registrar ) { #ifdef _DEBUG Application app; - app.LogMessage(registrar.GetName() + L" has been unloaded."); + app.LogMessage(registrar.GetName() + L" has been unloaded."); #endif - return XSI::CStatus::OK; + return XSI::CStatus::OK; } #ifdef unix @@ -168,38 +168,38 @@ extern "C" /** Defines the arguments to the export command */ XSI::CStatus OgreMeshExportCommand_Init( const XSI::CRef& context ) { - Context ctx(context); - Command cmd(ctx.GetSource()); + Context ctx(context); + Command cmd(ctx.GetSource()); - Application app; - app.LogMessage( L"Defining: " + cmd.GetName() ); + Application app; + app.LogMessage( L"Defining: " + cmd.GetName() ); - ArgumentArray args = cmd.GetArguments(); + ArgumentArray args = cmd.GetArguments(); - args.Add( L"targetMeshFileName", L"c:/default.mesh" ); - args.Add( L"mergeSubmeshes", L"true" ); - args.Add( L"exportChildren", L"true" ); - args.Add( L"calculateEdgeLists", L"true" ); + args.Add( L"targetMeshFileName", L"c:/default.mesh" ); + args.Add( L"mergeSubmeshes", L"true" ); + args.Add( L"exportChildren", L"true" ); + args.Add( L"calculateEdgeLists", L"true" ); args.Add( L"calculateTangents", L"false" ); - args.Add( L"tangentSemantic", L"true" ); - args.Add( L"tangentsSplitMirrored", L"false" ); - args.Add( L"tangentsSplitRotated", L"false" ); - args.Add( L"tangentsUseParity", L"false" ); - args.Add( L"numLodLevels", L"0" ); - args.Add( L"lodDistanceIncrement", L"2000" ); - args.Add( L"lodQuota", L"true" ); - args.Add( L"lodReduction", L"50" ); - args.Add( L"exportMaterials", L"true" ); - args.Add( L"targetMaterialFileName", L"c:/default.material" ); - args.Add( L"materialPrefix", L"" ); - args.Add( L"copyTextures", L"true" ); - args.Add( L"exportVertexAnimation", L"true" ); - args.Add( L"exportSkeleton", L"true" ); - args.Add( L"targetSkeletonFilename", L"c:/default.skeleton" ); - args.Add( L"fps", L"24" ); - args.Add( L"animationList", L"" ); - - return XSI::CStatus::OK; + args.Add( L"tangentSemantic", L"true" ); + args.Add( L"tangentsSplitMirrored", L"false" ); + args.Add( L"tangentsSplitRotated", L"false" ); + args.Add( L"tangentsUseParity", L"false" ); + args.Add( L"numLodLevels", L"0" ); + args.Add( L"lodDistanceIncrement", L"2000" ); + args.Add( L"lodQuota", L"true" ); + args.Add( L"lodReduction", L"50" ); + args.Add( L"exportMaterials", L"true" ); + args.Add( L"targetMaterialFileName", L"c:/default.material" ); + args.Add( L"materialPrefix", L"" ); + args.Add( L"copyTextures", L"true" ); + args.Add( L"exportVertexAnimation", L"true" ); + args.Add( L"exportSkeleton", L"true" ); + args.Add( L"targetSkeletonFilename", L"c:/default.skeleton" ); + args.Add( L"fps", L"24" ); + args.Add( L"animationList", L"" ); + + return XSI::CStatus::OK; } #ifdef unix @@ -211,228 +211,228 @@ extern "C" */ XSI::CStatus OgreMeshExportCommand_Execute( XSI::CRef& in_context ) { - Application app; - Context ctxt(in_context); - CValueArray args = ctxt.GetAttribute( L"Arguments" ); + Application app; + Context ctxt(in_context); + CValueArray args = ctxt.GetAttribute( L"Arguments" ); #ifdef _DEBUG - for (long i=0; i 0) - { - float distanceInc = args[10]; - - bool quota = args[11]; - - float reduction = args[12]; - - lodData = new Ogre::XsiMeshExporter::LodData; - float currentInc = distanceInc; - for (int l = 0; l < numlods; ++l) - { - lodData->distances.push_back(currentInc); - currentInc += distanceInc; - } - lodData->quota = (quota == true) ? - Ogre::ProgressiveMesh::VRQ_PROPORTIONAL : Ogre::ProgressiveMesh::VRQ_CONSTANT; - if (lodData->quota == Ogre::ProgressiveMesh::VRQ_PROPORTIONAL) - lodData->reductionValue = reduction * 0.01; - else - lodData->reductionValue = reduction; - - } - - bool exportMaterials = args[13]; - bool copyTextures = args[16]; - bool exportVertexAnimation = args[17]; - bool exportSkeleton = args[18]; - - // create singletons - Ogre::ResourceGroupManager rgm; - Ogre::MeshManager meshMgr; - Ogre::SkeletonManager skelMgr; - Ogre::MaterialManager matMgr; - Ogre::DefaultHardwareBufferManager hardwareBufMgr; - Ogre::LodStrategyManager lodStrategyBufMgr; - - - // determine number of exportsteps - size_t numSteps = 3 + OGRE_XSI_NUM_MESH_STEPS; - if (numlods > 0) - numSteps++; - if (edgeLists) - numSteps++; - if (tangents) - numSteps++; - if (exportSkeleton) - numSteps += 3; - - Ogre::ProgressManager progressMgr(numSteps); - - // Any material prefix? We need that for mesh linking too - Ogre::String materialPrefix = XSItoOgre(XSI::CString(args[15])); - - float fps = args[20]; - if (fps == 0.0f) - { - OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, - "You must supply a valid value for 'FPS'", - "OGRE Export"); - } - - Ogre::AnimationList selAnimList; - if (exportSkeleton || exportVertexAnimation) - { - - GridData gd(args[21]); - for (int a = 0; a < gd.GetRowCount(); ++a) - { - if (gd.GetCell(ANIMATION_LIST_EXPORT_COL, a) == true) - { - Ogre::AnimationEntry ae; - ae.animationName = XSItoOgre(XSI::CString(gd.GetCell(ANIMATION_LIST_NAME_COL, a))); - ae.ikSampleInterval = gd.GetCell(ANIMATION_LIST_IKFREQ_COL, a); - ae.startFrame = (LONG)gd.GetCell(ANIMATION_LIST_START_COL, a); - ae.endFrame = (LONG)gd.GetCell(ANIMATION_LIST_END_COL, a); - selAnimList.push_back(ae); - } - } - } - - if (exportSkeleton) - { - Ogre::String skeletonFileName = XSItoOgre(XSI::CString(args[19])); - if (skeletonFileName.empty()) - { - OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, - "You must supply a skeleton file name", - "OGRE Exporter"); - } - - // fix any omission of '.skeleton' - if (!Ogre::StringUtil::endsWith(skeletonFileName, ".skeleton")) - { - skeletonFileName += ".skeleton"; - } - - // Truncate the skeleton filename to just the name (no path) - Ogre::String skelName = skeletonFileName; - int pos = skeletonFileName.find_last_of("\\"); - if (pos == Ogre::String::npos) - { - pos = skeletonFileName.find_last_of("/"); - } - if (pos != Ogre::String::npos) - { - skelName = skelName.substr(pos+1, skelName.size() - pos - 1); - } - - - // Do the mesh - Ogre::DeformerMap& deformers = - meshExporter.buildMeshForExport(mergeSubmeshes, - exportChildren, edgeLists, tangents, tangentSemantic, - tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity, - exportVertexAnimation, selAnimList, fps, materialPrefix, - lodData, skelName); - // do the skeleton - const Ogre::AxisAlignedBox& skelAABB = - skelExporter.exportSkeleton(skeletonFileName, deformers, fps, selAnimList); - - // Do final mesh export - meshExporter.exportMesh(meshFileName, skelAABB); - } - else - { - Ogre::AxisAlignedBox nullbb; - // No skeleton - meshExporter.buildMeshForExport(mergeSubmeshes, - exportChildren, edgeLists, tangents, tangentSemantic, - tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity, - exportVertexAnimation, selAnimList, fps, materialPrefix, lodData); - meshExporter.exportMesh(meshFileName, nullbb); - } - - - delete lodData; - - // Do we want to export materials too? - if (exportMaterials) - { - Ogre::String materialFileName = XSItoOgre(XSI::CString(args[14])); - // fix any omission of '.material' - if (!Ogre::StringUtil::endsWith(materialFileName, ".material")) - { - materialFileName += ".material"; - } - - Ogre::XsiMaterialExporter matExporter; - try - { - matExporter.exportMaterials(meshExporter.getMaterials(), - meshExporter.getTextureProjectionMap(), - materialFileName, copyTextures); - } - catch (Ogre::Exception& e) - { - // ignore, non-fatal and will be in log - } - } - } - catch (Ogre::Exception& e) - { - // Will already have been logged to the Ogre log manager - // Tell XSI - app.LogMessage(OgretoXSI(e.getDescription()), XSI::siFatalMsg); - app.LogMessage(OgretoXSI(e.getFullDescription()), XSI::siInfoMsg); - } - - return st; + if ( args.GetCount() != 22 ) + { + // Arguments of the command might not be properly registered + return CStatus::InvalidArgument ; + } + + Ogre::LogManager logMgr; + logMgr.createLog("OgreXSIExporter.log", true); + CString msg(L"OGRE Exporter Version "); + msg += OGRE_XSI_EXPORTER_VERSION; + LogOgreAndXSI(msg); + + CStatus st(CStatus::OK); + + try + { + Ogre::XsiMeshExporter meshExporter; + Ogre::XsiSkeletonExporter skelExporter; + + Ogre::String meshFileName = XSItoOgre(XSI::CString(args[0])); + if (meshFileName.empty()) + { + OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, + "You must supply a mesh file name", + "OGRE Exporter"); + } + + bool mergeSubmeshes = args[1]; + bool exportChildren = args[2]; + bool edgeLists = args[3]; + bool tangents = args[4]; + bool tangentSem = args[5]; + Ogre::VertexElementSemantic tangentSemantic = (tangentSem == true)? + Ogre::VES_TANGENT : Ogre::VES_TEXTURE_COORDINATES; + + bool tangentsSplitMirrored = args[6]; + bool tangentsSplitRotated = args[7]; + bool tangentsUseParity = args[8]; + long numlods = (LONG)args[9]; + Ogre::XsiMeshExporter::LodData* lodData = 0; + if (numlods > 0) + { + float distanceInc = args[10]; + + bool quota = args[11]; + + float reduction = args[12]; + + lodData = new Ogre::XsiMeshExporter::LodData; + float currentInc = distanceInc; + for (int l = 0; l < numlods; ++l) + { + lodData->distances.push_back(currentInc); + currentInc += distanceInc; + } + lodData->quota = (quota == true) ? + Ogre::ProgressiveMesh::VRQ_PROPORTIONAL : Ogre::ProgressiveMesh::VRQ_CONSTANT; + if (lodData->quota == Ogre::ProgressiveMesh::VRQ_PROPORTIONAL) + lodData->reductionValue = reduction * 0.01; + else + lodData->reductionValue = reduction; + + } + + bool exportMaterials = args[13]; + bool copyTextures = args[16]; + bool exportVertexAnimation = args[17]; + bool exportSkeleton = args[18]; + + // create singletons + Ogre::ResourceGroupManager rgm; + Ogre::MeshManager meshMgr; + Ogre::SkeletonManager skelMgr; + Ogre::MaterialManager matMgr; + Ogre::DefaultHardwareBufferManager hardwareBufMgr; + Ogre::LodStrategyManager lodStrategyBufMgr; + + + // determine number of exportsteps + size_t numSteps = 3 + OGRE_XSI_NUM_MESH_STEPS; + if (numlods > 0) + numSteps++; + if (edgeLists) + numSteps++; + if (tangents) + numSteps++; + if (exportSkeleton) + numSteps += 3; + + Ogre::ProgressManager progressMgr(numSteps); + + // Any material prefix? We need that for mesh linking too + Ogre::String materialPrefix = XSItoOgre(XSI::CString(args[15])); + + float fps = args[20]; + if (fps == 0.0f) + { + OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, + "You must supply a valid value for 'FPS'", + "OGRE Export"); + } + + Ogre::AnimationList selAnimList; + if (exportSkeleton || exportVertexAnimation) + { + + GridData gd(args[21]); + for (int a = 0; a < gd.GetRowCount(); ++a) + { + if (gd.GetCell(ANIMATION_LIST_EXPORT_COL, a) == true) + { + Ogre::AnimationEntry ae; + ae.animationName = XSItoOgre(XSI::CString(gd.GetCell(ANIMATION_LIST_NAME_COL, a))); + ae.ikSampleInterval = gd.GetCell(ANIMATION_LIST_IKFREQ_COL, a); + ae.startFrame = (LONG)gd.GetCell(ANIMATION_LIST_START_COL, a); + ae.endFrame = (LONG)gd.GetCell(ANIMATION_LIST_END_COL, a); + selAnimList.push_back(ae); + } + } + } + + if (exportSkeleton) + { + Ogre::String skeletonFileName = XSItoOgre(XSI::CString(args[19])); + if (skeletonFileName.empty()) + { + OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, + "You must supply a skeleton file name", + "OGRE Exporter"); + } + + // fix any omission of '.skeleton' + if (!Ogre::StringUtil::endsWith(skeletonFileName, ".skeleton")) + { + skeletonFileName += ".skeleton"; + } + + // Truncate the skeleton filename to just the name (no path) + Ogre::String skelName = skeletonFileName; + int pos = skeletonFileName.find_last_of("\\"); + if (pos == Ogre::String::npos) + { + pos = skeletonFileName.find_last_of("/"); + } + if (pos != Ogre::String::npos) + { + skelName = skelName.substr(pos+1, skelName.size() - pos - 1); + } + + + // Do the mesh + Ogre::DeformerMap& deformers = + meshExporter.buildMeshForExport(mergeSubmeshes, + exportChildren, edgeLists, tangents, tangentSemantic, + tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity, + exportVertexAnimation, selAnimList, fps, materialPrefix, + lodData, skelName); + // do the skeleton + const Ogre::AxisAlignedBox& skelAABB = + skelExporter.exportSkeleton(skeletonFileName, deformers, fps, selAnimList); + + // Do final mesh export + meshExporter.exportMesh(meshFileName, skelAABB); + } + else + { + Ogre::AxisAlignedBox nullbb; + // No skeleton + meshExporter.buildMeshForExport(mergeSubmeshes, + exportChildren, edgeLists, tangents, tangentSemantic, + tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity, + exportVertexAnimation, selAnimList, fps, materialPrefix, lodData); + meshExporter.exportMesh(meshFileName, nullbb); + } + + + delete lodData; + + // Do we want to export materials too? + if (exportMaterials) + { + Ogre::String materialFileName = XSItoOgre(XSI::CString(args[14])); + // fix any omission of '.material' + if (!Ogre::StringUtil::endsWith(materialFileName, ".material")) + { + materialFileName += ".material"; + } + + Ogre::XsiMaterialExporter matExporter; + try + { + matExporter.exportMaterials(meshExporter.getMaterials(), + meshExporter.getTextureProjectionMap(), + materialFileName, copyTextures); + } + catch (Ogre::Exception& e) + { + // ignore, non-fatal and will be in log + } + } + } + catch (Ogre::Exception& e) + { + // Will already have been logged to the Ogre log manager + // Tell XSI + app.LogMessage(OgretoXSI(e.getDescription()), XSI::siFatalMsg); + app.LogMessage(OgretoXSI(e.getFullDescription()), XSI::siInfoMsg); + } + + return st; return XSI::CStatus::OK; } @@ -444,14 +444,14 @@ extern "C" /** Defines the menu text and the event callback to execute (OnOgreMeshExportMenu) */ XSI::CStatus OgreMeshExportMenu_Init( XSI::CRef& in_ref ) { - Context ctxt = in_ref; - Menu menu = ctxt.GetSource(); + Context ctxt = in_ref; + Menu menu = ctxt.GetSource(); - CStatus st; - MenuItem item; - menu.AddCallbackItem(L"OGRE Mesh / Skeleton...", L"OnOgreMeshExportMenu", item); + CStatus st; + MenuItem item; + menu.AddCallbackItem(L"OGRE Mesh / Skeleton...", L"OnOgreMeshExportMenu", item); - return CStatus::OK; + return CStatus::OK; } CString exportPropertyDialogName = L"OgreMeshExportOptions"; @@ -464,264 +464,264 @@ extern "C" in a modal dialog. If it wasn't cancelled, performs an export. */ XSI::CStatus OnOgreMeshExportMenu( XSI::CRef& in_ref ) -{ - Ogre::LogManager logMgr; - logMgr.createLog("OgreXSIExporter.log", true); - CString msg(L"OGRE Exporter Version "); - msg += OGRE_XSI_EXPORTER_VERSION; - LogOgreAndXSI(msg); - - Application app; - CStatus st(CStatus::OK); - Property prop = app.GetActiveSceneRoot().GetProperties().GetItem(exportPropertyDialogName); - if (prop.IsValid()) - { - // Check version number - CString currVersion(prop.GetParameterValue(L"version")); - if (!currVersion.IsEqualNoCase(OGRE_XSI_EXPORTER_VERSION)) - { - DeleteObj(exportPropertyDialogName); - prop.ResetObject(); - } - } - if (!prop.IsValid()) - { - prop = app.GetActiveSceneRoot().AddProperty(exportPropertyDialogName); - prop.PutParameterValue(L"version", CString(OGRE_XSI_EXPORTER_VERSION)); - } - - try - { - // Popup Returns true if the command was cancelled otherwise it returns false. - CStatus ret = Popup(exportPropertyDialogName,CValue(),L"OGRE Mesh / Skeleton Export",((LONG)siModal),true); - if (ret == CStatus::OK) - { - Ogre::XsiMeshExporter meshExporter; - Ogre::XsiSkeletonExporter skelExporter; - - // retrieve the parameters - Parameter param = prop.GetParameters().GetItem(L"objectName"); - CString objectName = param.GetValue(); - param = prop.GetParameters().GetItem( L"targetMeshFileName" ); - Ogre::String meshFileName = XSItoOgre(XSI::CString(param.GetValue())); - if (meshFileName.empty()) - { - OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, - "You must supply a mesh file name", - "OGRE Exporter"); - } - // fix any omission of '.mesh' - if (!Ogre::StringUtil::endsWith(meshFileName, ".mesh")) - { - meshFileName += ".mesh"; - } - param = prop.GetParameters().GetItem( L"mergeSubmeshes" ); - bool mergeSubmeshes = param.GetValue(); - param = prop.GetParameters().GetItem( L"exportChildren" ); - bool exportChildren = param.GetValue(); - param = prop.GetParameters().GetItem( L"calculateEdgeLists" ); - bool edgeLists = param.GetValue(); - param = prop.GetParameters().GetItem( L"calculateTangents" ); - bool tangents = param.GetValue(); - param = prop.GetParameters().GetItem( L"tangentSemantic" ); - CString tangentSemStr = param.GetValue(); - Ogre::VertexElementSemantic tangentSemantic = (tangentSemStr == L"t")? - Ogre::VES_TANGENT : Ogre::VES_TEXTURE_COORDINATES; - param = prop.GetParameters().GetItem( L"tangentsSplitMirrored" ); - bool tangentsSplitMirrored = param.GetValue(); - param = prop.GetParameters().GetItem( L"tangentsSplitRotated" ); - bool tangentsSplitRotated = param.GetValue(); - param = prop.GetParameters().GetItem( L"tangentsUseParity" ); - bool tangentsUseParity = param.GetValue(); - param = prop.GetParameters().GetItem( L"numLodLevels" ); - long numlods = (LONG)param.GetValue(); - Ogre::XsiMeshExporter::LodData* lodData = 0; - if (numlods > 0) - { - param = prop.GetParameters().GetItem( L"lodDistanceIncrement" ); - float distanceInc = param.GetValue(); - - param = prop.GetParameters().GetItem(L"lodQuota"); - CString quota = param.GetValue(); - - param = prop.GetParameters().GetItem(L"lodReduction"); - float reduction = param.GetValue(); - - lodData = new Ogre::XsiMeshExporter::LodData; - float currentInc = distanceInc; - for (int l = 0; l < numlods; ++l) - { - lodData->distances.push_back(currentInc); - currentInc += distanceInc; - } - lodData->quota = (quota == L"p") ? - Ogre::ProgressiveMesh::VRQ_PROPORTIONAL : Ogre::ProgressiveMesh::VRQ_CONSTANT; - if (lodData->quota == Ogre::ProgressiveMesh::VRQ_PROPORTIONAL) - lodData->reductionValue = reduction * 0.01; - else - lodData->reductionValue = reduction; - - } - - param = prop.GetParameters().GetItem( L"exportSkeleton" ); - bool exportSkeleton = param.GetValue(); - param = prop.GetParameters().GetItem( L"exportVertexAnimation" ); - bool exportVertexAnimation = param.GetValue(); - param = prop.GetParameters().GetItem( L"exportMaterials" ); - bool exportMaterials = param.GetValue(); - param = prop.GetParameters().GetItem( L"copyTextures" ); - bool copyTextures = param.GetValue(); - - // create singletons - Ogre::ResourceGroupManager rgm; - Ogre::MeshManager meshMgr; - Ogre::SkeletonManager skelMgr; - Ogre::MaterialManager matMgr; - Ogre::DefaultHardwareBufferManager hardwareBufMgr; - Ogre::LodStrategyManager lodStrategyBufMgr; - - - // determine number of exportsteps - size_t numSteps = 3 + OGRE_XSI_NUM_MESH_STEPS; - if (numlods > 0) - numSteps++; - if (edgeLists) - numSteps++; - if (tangents) - numSteps++; - if (exportSkeleton) - numSteps += 3; - - Ogre::ProgressManager progressMgr(numSteps); - - // Any material prefix? We need that for mesh linking too - param = prop.GetParameters().GetItem( L"materialPrefix" ); - Ogre::String materialPrefix = XSItoOgre(XSI::CString(param.GetValue())); - - param = prop.GetParameters().GetItem( L"fps" ); - float fps = param.GetValue(); - if (fps == 0.0f) - { - OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, - "You must supply a valid value for 'FPS'", - "OGRE Export"); - } - - Ogre::AnimationList selAnimList; - if (exportSkeleton || exportVertexAnimation) - { - - param = prop.GetParameters().GetItem( L"animationList" ); - GridData gd(param.GetValue()); - for (int a = 0; a < gd.GetRowCount(); ++a) - { - if (gd.GetCell(ANIMATION_LIST_EXPORT_COL, a) == true) - { - Ogre::AnimationEntry ae; - ae.animationName = XSItoOgre(XSI::CString(gd.GetCell(ANIMATION_LIST_NAME_COL, a))); - ae.ikSampleInterval = gd.GetCell(ANIMATION_LIST_IKFREQ_COL, a); - ae.startFrame = (LONG)gd.GetCell(ANIMATION_LIST_START_COL, a); - ae.endFrame = (LONG)gd.GetCell(ANIMATION_LIST_END_COL, a); - selAnimList.push_back(ae); - } - } - } - - if (exportSkeleton) - { - param = prop.GetParameters().GetItem( L"targetSkeletonFileName" ); - Ogre::String skeletonFileName = XSItoOgre(XSI::CString(param.GetValue())); - if (skeletonFileName.empty()) - { - OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, - "You must supply a skeleton file name", - "OGRE Exporter"); - } - - // fix any omission of '.skeleton' - if (!Ogre::StringUtil::endsWith(skeletonFileName, ".skeleton")) - { - skeletonFileName += ".skeleton"; - } - - // Truncate the skeleton filename to just the name (no path) - Ogre::String skelName = skeletonFileName; - int pos = skeletonFileName.find_last_of("\\"); - if (pos == Ogre::String::npos) - { - pos = skeletonFileName.find_last_of("/"); - } - if (pos != Ogre::String::npos) - { - skelName = skelName.substr(pos+1, skelName.size() - pos - 1); - } - - - // Do the mesh - Ogre::DeformerMap& deformers = - meshExporter.buildMeshForExport(mergeSubmeshes, - exportChildren, edgeLists, tangents, tangentSemantic, - tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity, - exportVertexAnimation, selAnimList, fps, materialPrefix, - lodData, skelName); - // do the skeleton - const Ogre::AxisAlignedBox& skelAABB = - skelExporter.exportSkeleton(skeletonFileName, deformers, fps, selAnimList); - - // Do final mesh export - meshExporter.exportMesh(meshFileName, skelAABB); - } - else - { - Ogre::AxisAlignedBox nullbb; - // No skeleton - meshExporter.buildMeshForExport(mergeSubmeshes, - exportChildren, edgeLists, tangents, tangentSemantic, - tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity, - exportVertexAnimation, selAnimList, fps, materialPrefix, lodData); - meshExporter.exportMesh(meshFileName, nullbb); - } - - - delete lodData; - - // Do we want to export materials too? - if (exportMaterials) - { - param = prop.GetParameters().GetItem( L"targetMaterialFileName" ); - Ogre::String materialFileName = XSItoOgre(XSI::CString(param.GetValue())); - // fix any omission of '.material' - if (!Ogre::StringUtil::endsWith(materialFileName, ".material")) - { - materialFileName += ".material"; - } - - Ogre::XsiMaterialExporter matExporter; - try - { - matExporter.exportMaterials(meshExporter.getMaterials(), - meshExporter.getTextureProjectionMap(), - materialFileName, copyTextures); - } - catch (Ogre::Exception& e) - { - // ignore, non-fatal and will be in log - } - } - - } - - } - catch (Ogre::Exception& e) - { - // Will already have been logged to the Ogre log manager - // Tell XSI - app.LogMessage(OgretoXSI(e.getDescription()), XSI::siFatalMsg); - app.LogMessage(OgretoXSI(e.getFullDescription()), XSI::siInfoMsg); - } - - //DeleteObj( L"OgreMeshExportOptions" ); - return st; +{ + Ogre::LogManager logMgr; + logMgr.createLog("OgreXSIExporter.log", true); + CString msg(L"OGRE Exporter Version "); + msg += OGRE_XSI_EXPORTER_VERSION; + LogOgreAndXSI(msg); + + Application app; + CStatus st(CStatus::OK); + Property prop = app.GetActiveSceneRoot().GetProperties().GetItem(exportPropertyDialogName); + if (prop.IsValid()) + { + // Check version number + CString currVersion(prop.GetParameterValue(L"version")); + if (!currVersion.IsEqualNoCase(OGRE_XSI_EXPORTER_VERSION)) + { + DeleteObj(exportPropertyDialogName); + prop.ResetObject(); + } + } + if (!prop.IsValid()) + { + prop = app.GetActiveSceneRoot().AddProperty(exportPropertyDialogName); + prop.PutParameterValue(L"version", CString(OGRE_XSI_EXPORTER_VERSION)); + } + + try + { + // Popup Returns true if the command was cancelled otherwise it returns false. + CStatus ret = Popup(exportPropertyDialogName,CValue(),L"OGRE Mesh / Skeleton Export",((LONG)siModal),true); + if (ret == CStatus::OK) + { + Ogre::XsiMeshExporter meshExporter; + Ogre::XsiSkeletonExporter skelExporter; + + // retrieve the parameters + Parameter param = prop.GetParameters().GetItem(L"objectName"); + CString objectName = param.GetValue(); + param = prop.GetParameters().GetItem( L"targetMeshFileName" ); + Ogre::String meshFileName = XSItoOgre(XSI::CString(param.GetValue())); + if (meshFileName.empty()) + { + OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, + "You must supply a mesh file name", + "OGRE Exporter"); + } + // fix any omission of '.mesh' + if (!Ogre::StringUtil::endsWith(meshFileName, ".mesh")) + { + meshFileName += ".mesh"; + } + param = prop.GetParameters().GetItem( L"mergeSubmeshes" ); + bool mergeSubmeshes = param.GetValue(); + param = prop.GetParameters().GetItem( L"exportChildren" ); + bool exportChildren = param.GetValue(); + param = prop.GetParameters().GetItem( L"calculateEdgeLists" ); + bool edgeLists = param.GetValue(); + param = prop.GetParameters().GetItem( L"calculateTangents" ); + bool tangents = param.GetValue(); + param = prop.GetParameters().GetItem( L"tangentSemantic" ); + CString tangentSemStr = param.GetValue(); + Ogre::VertexElementSemantic tangentSemantic = (tangentSemStr == L"t")? + Ogre::VES_TANGENT : Ogre::VES_TEXTURE_COORDINATES; + param = prop.GetParameters().GetItem( L"tangentsSplitMirrored" ); + bool tangentsSplitMirrored = param.GetValue(); + param = prop.GetParameters().GetItem( L"tangentsSplitRotated" ); + bool tangentsSplitRotated = param.GetValue(); + param = prop.GetParameters().GetItem( L"tangentsUseParity" ); + bool tangentsUseParity = param.GetValue(); + param = prop.GetParameters().GetItem( L"numLodLevels" ); + long numlods = (LONG)param.GetValue(); + Ogre::XsiMeshExporter::LodData* lodData = 0; + if (numlods > 0) + { + param = prop.GetParameters().GetItem( L"lodDistanceIncrement" ); + float distanceInc = param.GetValue(); + + param = prop.GetParameters().GetItem(L"lodQuota"); + CString quota = param.GetValue(); + + param = prop.GetParameters().GetItem(L"lodReduction"); + float reduction = param.GetValue(); + + lodData = new Ogre::XsiMeshExporter::LodData; + float currentInc = distanceInc; + for (int l = 0; l < numlods; ++l) + { + lodData->distances.push_back(currentInc); + currentInc += distanceInc; + } + lodData->quota = (quota == L"p") ? + Ogre::ProgressiveMesh::VRQ_PROPORTIONAL : Ogre::ProgressiveMesh::VRQ_CONSTANT; + if (lodData->quota == Ogre::ProgressiveMesh::VRQ_PROPORTIONAL) + lodData->reductionValue = reduction * 0.01; + else + lodData->reductionValue = reduction; + + } + + param = prop.GetParameters().GetItem( L"exportSkeleton" ); + bool exportSkeleton = param.GetValue(); + param = prop.GetParameters().GetItem( L"exportVertexAnimation" ); + bool exportVertexAnimation = param.GetValue(); + param = prop.GetParameters().GetItem( L"exportMaterials" ); + bool exportMaterials = param.GetValue(); + param = prop.GetParameters().GetItem( L"copyTextures" ); + bool copyTextures = param.GetValue(); + + // create singletons + Ogre::ResourceGroupManager rgm; + Ogre::MeshManager meshMgr; + Ogre::SkeletonManager skelMgr; + Ogre::MaterialManager matMgr; + Ogre::DefaultHardwareBufferManager hardwareBufMgr; + Ogre::LodStrategyManager lodStrategyBufMgr; + + + // determine number of exportsteps + size_t numSteps = 3 + OGRE_XSI_NUM_MESH_STEPS; + if (numlods > 0) + numSteps++; + if (edgeLists) + numSteps++; + if (tangents) + numSteps++; + if (exportSkeleton) + numSteps += 3; + + Ogre::ProgressManager progressMgr(numSteps); + + // Any material prefix? We need that for mesh linking too + param = prop.GetParameters().GetItem( L"materialPrefix" ); + Ogre::String materialPrefix = XSItoOgre(XSI::CString(param.GetValue())); + + param = prop.GetParameters().GetItem( L"fps" ); + float fps = param.GetValue(); + if (fps == 0.0f) + { + OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, + "You must supply a valid value for 'FPS'", + "OGRE Export"); + } + + Ogre::AnimationList selAnimList; + if (exportSkeleton || exportVertexAnimation) + { + + param = prop.GetParameters().GetItem( L"animationList" ); + GridData gd(param.GetValue()); + for (int a = 0; a < gd.GetRowCount(); ++a) + { + if (gd.GetCell(ANIMATION_LIST_EXPORT_COL, a) == true) + { + Ogre::AnimationEntry ae; + ae.animationName = XSItoOgre(XSI::CString(gd.GetCell(ANIMATION_LIST_NAME_COL, a))); + ae.ikSampleInterval = gd.GetCell(ANIMATION_LIST_IKFREQ_COL, a); + ae.startFrame = (LONG)gd.GetCell(ANIMATION_LIST_START_COL, a); + ae.endFrame = (LONG)gd.GetCell(ANIMATION_LIST_END_COL, a); + selAnimList.push_back(ae); + } + } + } + + if (exportSkeleton) + { + param = prop.GetParameters().GetItem( L"targetSkeletonFileName" ); + Ogre::String skeletonFileName = XSItoOgre(XSI::CString(param.GetValue())); + if (skeletonFileName.empty()) + { + OGRE_EXCEPT(Ogre::Exception::ERR_INVALIDPARAMS, + "You must supply a skeleton file name", + "OGRE Exporter"); + } + + // fix any omission of '.skeleton' + if (!Ogre::StringUtil::endsWith(skeletonFileName, ".skeleton")) + { + skeletonFileName += ".skeleton"; + } + + // Truncate the skeleton filename to just the name (no path) + Ogre::String skelName = skeletonFileName; + int pos = skeletonFileName.find_last_of("\\"); + if (pos == Ogre::String::npos) + { + pos = skeletonFileName.find_last_of("/"); + } + if (pos != Ogre::String::npos) + { + skelName = skelName.substr(pos+1, skelName.size() - pos - 1); + } + + + // Do the mesh + Ogre::DeformerMap& deformers = + meshExporter.buildMeshForExport(mergeSubmeshes, + exportChildren, edgeLists, tangents, tangentSemantic, + tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity, + exportVertexAnimation, selAnimList, fps, materialPrefix, + lodData, skelName); + // do the skeleton + const Ogre::AxisAlignedBox& skelAABB = + skelExporter.exportSkeleton(skeletonFileName, deformers, fps, selAnimList); + + // Do final mesh export + meshExporter.exportMesh(meshFileName, skelAABB); + } + else + { + Ogre::AxisAlignedBox nullbb; + // No skeleton + meshExporter.buildMeshForExport(mergeSubmeshes, + exportChildren, edgeLists, tangents, tangentSemantic, + tangentsSplitMirrored, tangentsSplitRotated, tangentsUseParity, + exportVertexAnimation, selAnimList, fps, materialPrefix, lodData); + meshExporter.exportMesh(meshFileName, nullbb); + } + + + delete lodData; + + // Do we want to export materials too? + if (exportMaterials) + { + param = prop.GetParameters().GetItem( L"targetMaterialFileName" ); + Ogre::String materialFileName = XSItoOgre(XSI::CString(param.GetValue())); + // fix any omission of '.material' + if (!Ogre::StringUtil::endsWith(materialFileName, ".material")) + { + materialFileName += ".material"; + } + + Ogre::XsiMaterialExporter matExporter; + try + { + matExporter.exportMaterials(meshExporter.getMaterials(), + meshExporter.getTextureProjectionMap(), + materialFileName, copyTextures); + } + catch (Ogre::Exception& e) + { + // ignore, non-fatal and will be in log + } + } + + } + + } + catch (Ogre::Exception& e) + { + // Will already have been logged to the Ogre log manager + // Tell XSI + app.LogMessage(OgretoXSI(e.getDescription()), XSI::siFatalMsg); + app.LogMessage(OgretoXSI(e.getFullDescription()), XSI::siInfoMsg); + } + + //DeleteObj( L"OgreMeshExportOptions" ); + return st; } @@ -731,130 +731,130 @@ extern "C" /** Defines the persistable parameters on the options dialog */ CStatus OgreMeshExportOptions_Define( const CRef & in_Ctx ) { - // Here is where we add all the parameters to the - // Custom Property. This will be called each time - // an new instance of the Custom Property is called. - // It is not called when an persisted Custom Property is loaded. + // Here is where we add all the parameters to the + // Custom Property. This will be called each time + // an new instance of the Custom Property is called. + // It is not called when an persisted Custom Property is loaded. Application app ; - CustomProperty prop = Context(in_Ctx).GetSource(); - Parameter param ; - - // Default capabilities for most of these parameters - int caps = siPersistable ; - CValue nullValue; // Used for arguments we don't want to set - - prop.AddParameter( - L"version",CValue::siString, caps, - L"Version", L"", - nullValue, param) ; - prop.AddParameter( + CustomProperty prop = Context(in_Ctx).GetSource(); + Parameter param ; + + // Default capabilities for most of these parameters + int caps = siPersistable ; + CValue nullValue; // Used for arguments we don't want to set + + prop.AddParameter( + L"version",CValue::siString, caps, + L"Version", L"", + nullValue, param) ; + prop.AddParameter( L"objectName",CValue::siString, caps, L"Object Name", L"", - nullValue, param) ; - prop.AddParameter( - L"objects",CValue::siRefArray, caps, - L"Collection of selected objects", L"", - nullValue, param) ; - prop.AddParameter( + nullValue, param) ; + prop.AddParameter( + L"objects",CValue::siRefArray, caps, + L"Collection of selected objects", L"", + nullValue, param) ; + prop.AddParameter( L"targetMeshFileName",CValue::siString, caps, - L"Mesh Filename", L"", - nullValue, param) ; - prop.AddParameter( - L"mergeSubmeshes",CValue::siBool, caps, - L"Merge objects with same material?", - L"If false, a separate named SubMesh will be created for every PolygonMesh " - L"preserving your model divisions. If true, the exporter will merge all " - L"PolygonMesh objects with the same material, which is more efficient, but " - L"does not preserve your modelling divisions.", - CValue(true), param) ; - prop.AddParameter( - L"exportChildren",CValue::siBool, caps, - L"Export Children", - L"If true, children of all selected objects will be exported.", - CValue(true), param) ; - prop.AddParameter( + L"Mesh Filename", L"", + nullValue, param) ; + prop.AddParameter( + L"mergeSubmeshes",CValue::siBool, caps, + L"Merge objects with same material?", + L"If false, a separate named SubMesh will be created for every PolygonMesh " + L"preserving your model divisions. If true, the exporter will merge all " + L"PolygonMesh objects with the same material, which is more efficient, but " + L"does not preserve your modelling divisions.", + CValue(true), param) ; + prop.AddParameter( + L"exportChildren",CValue::siBool, caps, + L"Export Children", + L"If true, children of all selected objects will be exported.", + CValue(true), param) ; + prop.AddParameter( L"calculateEdgeLists",CValue::siBool, caps, L"Calculate Edge Lists (stencil shadows)", L"", - CValue(true), param) ; - prop.AddParameter( + CValue(true), param) ; + prop.AddParameter( L"calculateTangents",CValue::siBool, caps, L"Calculate Tangents (normal mapping)", L"", - CValue(false), param) ; - prop.AddParameter( - L"tangentSemantic",CValue::siString, caps, - L"Tangent Semantic", L"", - L"t", param) ; - prop.AddParameter( - L"tangentsSplitMirrored",CValue::siBool, caps, - L"Split tangents at UV mirror", L"", - CValue(false), param) ; - prop.AddParameter( - L"tangentsSplitRotated",CValue::siBool, caps, - L"Split tangents at UV rotation", L"", - CValue(false), param) ; - prop.AddParameter( - L"tangentsUseParity",CValue::siBool, caps, - L"4D Tangents", L"", - CValue(false), param) ; - prop.AddParameter( - L"numLodLevels",CValue::siInt2, caps, - L"Levels of Detail", L"", - (LONG)0, param) ; - prop.AddParameter( - L"lodDistanceIncrement",CValue::siFloat, caps, - L"Distance Increment", L"", - (LONG)2000, //default - (LONG)1, // hard min - (LONG)1000000, // hard max - (LONG)50, // suggested min - (LONG)10000, // suggested max - param) ; - prop.AddParameter( - L"lodQuota",CValue::siString, caps, - L"Reduction Style", L"", - L"p", param) ; - prop.AddParameter( - L"lodReduction",CValue::siFloat, caps, - L"Reduction Value", L"", - CValue(50.0f), param) ; - prop.AddParameter( + CValue(false), param) ; + prop.AddParameter( + L"tangentSemantic",CValue::siString, caps, + L"Tangent Semantic", L"", + L"t", param) ; + prop.AddParameter( + L"tangentsSplitMirrored",CValue::siBool, caps, + L"Split tangents at UV mirror", L"", + CValue(false), param) ; + prop.AddParameter( + L"tangentsSplitRotated",CValue::siBool, caps, + L"Split tangents at UV rotation", L"", + CValue(false), param) ; + prop.AddParameter( + L"tangentsUseParity",CValue::siBool, caps, + L"4D Tangents", L"", + CValue(false), param) ; + prop.AddParameter( + L"numLodLevels",CValue::siInt2, caps, + L"Levels of Detail", L"", + (LONG)0, param) ; + prop.AddParameter( + L"lodDistanceIncrement",CValue::siFloat, caps, + L"Distance Increment", L"", + (LONG)2000, //default + (LONG)1, // hard min + (LONG)1000000, // hard max + (LONG)50, // suggested min + (LONG)10000, // suggested max + param) ; + prop.AddParameter( + L"lodQuota",CValue::siString, caps, + L"Reduction Style", L"", + L"p", param) ; + prop.AddParameter( + L"lodReduction",CValue::siFloat, caps, + L"Reduction Value", L"", + CValue(50.0f), param) ; + prop.AddParameter( L"exportSkeleton",CValue::siBool, caps, L"Export Skeleton", L"", - CValue(true), param) ; - prop.AddParameter( - L"exportVertexAnimation",CValue::siBool, caps, - L"Export Vertex Animation", L"", - CValue(true), param) ; - prop.AddParameter( + CValue(true), param) ; + prop.AddParameter( + L"exportVertexAnimation",CValue::siBool, caps, + L"Export Vertex Animation", L"", + CValue(true), param) ; + prop.AddParameter( L"targetSkeletonFileName",CValue::siString, caps, L"Skeleton Filename", L"", - nullValue, param) ; + nullValue, param) ; prop.AddParameter( L"fps",CValue::siInt2, caps, L"Frames per second", L"", - (LONG)24, param) ; - prop.AddGridParameter(L"animationList"); - prop.AddParameter( - L"exportMaterials", CValue::siBool, caps, - L"Export Materials", L"", - CValue(true), param); - prop.AddParameter( - L"copyTextures", CValue::siBool, caps, - L"Copy Textures To Folder", L"", - CValue(true), param); - prop.AddParameter( + (LONG)24, param) ; + prop.AddGridParameter(L"animationList"); + prop.AddParameter( + L"exportMaterials", CValue::siBool, caps, + L"Export Materials", L"", + CValue(true), param); + prop.AddParameter( + L"copyTextures", CValue::siBool, caps, + L"Copy Textures To Folder", L"", + CValue(true), param); + prop.AddParameter( L"targetMaterialFileName",CValue::siString, caps, L"Material Filename", L"", - nullValue, param) ; - prop.AddParameter( - L"materialPrefix",CValue::siString, caps, - L"Material Prefix", L"", - nullValue, param) ; - + nullValue, param) ; + prop.AddParameter( + L"materialPrefix",CValue::siString, caps, + L"Material Prefix", L"", + nullValue, param) ; + - return CStatus::OK; + return CStatus::OK; } #ifdef unix @@ -863,93 +863,93 @@ extern "C" /** Defines the visual layout of the options dialog */ CStatus OgreMeshExportOptions_DefineLayout( const CRef & in_Ctx ) { - // XSI will call this to define the visual appearance of the CustomProperty - // The layout is shared between all instances of the CustomProperty - // and is CACHED!!!. You can force the code to re-execute by using the - // XSIUtils.Reload feature, or right-clicking the property page and selecting 'Refresh' + // XSI will call this to define the visual appearance of the CustomProperty + // The layout is shared between all instances of the CustomProperty + // and is CACHED!!!. You can force the code to re-execute by using the + // XSIUtils.Reload feature, or right-clicking the property page and selecting 'Refresh' - PPGLayout oLayout = Context( in_Ctx ).GetSource() ; - PPGItem item ; + PPGLayout oLayout = Context( in_Ctx ).GetSource() ; + PPGItem item ; - oLayout.Clear() ; + oLayout.Clear() ; - // Mesh tab - oLayout.AddTab(L"Basic"); + // Mesh tab + oLayout.AddTab(L"Basic"); // Object - oLayout.AddGroup(L"Object(s) to export"); - item = oLayout.AddItem(L"objectName"); + oLayout.AddGroup(L"Object(s) to export"); + item = oLayout.AddItem(L"objectName"); item.PutAttribute( siUINoLabel, true ); - oLayout.EndGroup(); - - oLayout.AddGroup(L"Mesh"); + oLayout.EndGroup(); + + oLayout.AddGroup(L"Mesh"); item = oLayout.AddItem(L"targetMeshFileName", L"Target", siControlFilePath); - item.PutAttribute( siUINoLabel, true ); - item.PutAttribute( siUIFileFilter, L"OGRE Mesh format (*.mesh)|*.mesh|All Files (*.*)|*.*||" ); - item = oLayout.AddItem(L"mergeSubmeshes") ; - item = oLayout.AddItem(L"exportChildren") ; + item.PutAttribute( siUINoLabel, true ); + item.PutAttribute( siUIFileFilter, L"OGRE Mesh format (*.mesh)|*.mesh|All Files (*.*)|*.*||" ); + item = oLayout.AddItem(L"mergeSubmeshes") ; + item = oLayout.AddItem(L"exportChildren") ; item = oLayout.AddItem(L"calculateEdgeLists"); item = oLayout.AddItem(L"calculateTangents"); - CValueArray tangentVals; - tangentVals.Add(L"Tangent"); - tangentVals.Add(L"t"); - tangentVals.Add(L"Texture Coords"); - tangentVals.Add(L"uvw"); - item = oLayout.AddEnumControl(L"tangentSemantic", tangentVals, L"Tangent Semantic", XSI::siControlCombo); - item = oLayout.AddItem(L"tangentsSplitMirrored"); - item = oLayout.AddItem(L"tangentsSplitRotated"); - item = oLayout.AddItem(L"tangentsUseParity"); - oLayout.AddGroup(L"Level of Detail Reduction"); + CValueArray tangentVals; + tangentVals.Add(L"Tangent"); + tangentVals.Add(L"t"); + tangentVals.Add(L"Texture Coords"); + tangentVals.Add(L"uvw"); + item = oLayout.AddEnumControl(L"tangentSemantic", tangentVals, L"Tangent Semantic", XSI::siControlCombo); + item = oLayout.AddItem(L"tangentsSplitMirrored"); + item = oLayout.AddItem(L"tangentsSplitRotated"); + item = oLayout.AddItem(L"tangentsUseParity"); + oLayout.AddGroup(L"Level of Detail Reduction"); item = oLayout.AddItem(L"numLodLevels"); - item = oLayout.AddItem(L"lodDistanceIncrement"); - CValueArray vals; - vals.Add(L"Percentage"); - vals.Add(L"p"); - vals.Add(L"Constant"); - vals.Add(L"c"); - item = oLayout.AddEnumControl(L"lodQuota", vals, L"Quota", XSI::siControlCombo); - item = oLayout.AddItem(L"lodReduction"); - oLayout.EndGroup(); - oLayout.EndGroup(); - - oLayout.AddTab(L"Materials"); - // Material Tab + item = oLayout.AddItem(L"lodDistanceIncrement"); + CValueArray vals; + vals.Add(L"Percentage"); + vals.Add(L"p"); + vals.Add(L"Constant"); + vals.Add(L"c"); + item = oLayout.AddEnumControl(L"lodQuota", vals, L"Quota", XSI::siControlCombo); + item = oLayout.AddItem(L"lodReduction"); + oLayout.EndGroup(); + oLayout.EndGroup(); + + oLayout.AddTab(L"Materials"); + // Material Tab item = oLayout.AddItem(L"exportMaterials") ; item = oLayout.AddItem(L"targetMaterialFileName", L"Target", siControlFilePath) ; - item.PutAttribute( siUINoLabel, true ); - item.PutAttribute( siUIFileFilter, L"OGRE Material script (*.material)|*.material|All Files (*.*)|*.*||" ); - item = oLayout.AddItem(L"materialPrefix"); + item.PutAttribute( siUINoLabel, true ); + item.PutAttribute( siUIFileFilter, L"OGRE Material script (*.material)|*.material|All Files (*.*)|*.*||" ); + item = oLayout.AddItem(L"materialPrefix"); item = oLayout.AddItem(L"copyTextures"); - - - // Skeleton Tab - oLayout.AddTab(L"Animation"); + + + // Skeleton Tab + oLayout.AddTab(L"Animation"); - item = oLayout.AddItem(L"exportVertexAnimation"); - item = oLayout.AddItem(L"exportSkeleton"); - item = oLayout.AddItem(L"targetSkeletonFileName", L"Target", siControlFilePath); - item.PutAttribute( siUINoLabel, true ); - item.PutAttribute( siUIFileFilter, L"OGRE Skeleton format (*.skeleton)|*.skeleton|All Files (*.*)|*.*||" ); - item = oLayout.AddItem(L"fps"); + item = oLayout.AddItem(L"exportVertexAnimation"); + item = oLayout.AddItem(L"exportSkeleton"); + item = oLayout.AddItem(L"targetSkeletonFileName", L"Target", siControlFilePath); + item.PutAttribute( siUINoLabel, true ); + item.PutAttribute( siUIFileFilter, L"OGRE Skeleton format (*.skeleton)|*.skeleton|All Files (*.*)|*.*||" ); + item = oLayout.AddItem(L"fps"); - oLayout.AddGroup(L"Animations"); - item = oLayout.AddItem(L"animationList", L"Animations", siControlGrid); - item.PutAttribute( siUINoLabel, true ); - item.PutAttribute(siUIGridColumnWidths, L"0:15:250:30:30:75"); - item.PutAttribute(siUIGridHideRowHeader, true); + oLayout.AddGroup(L"Animations"); + item = oLayout.AddItem(L"animationList", L"Animations", siControlGrid); + item.PutAttribute( siUINoLabel, true ); + item.PutAttribute(siUIGridColumnWidths, L"0:15:250:30:30:75"); + item.PutAttribute(siUIGridHideRowHeader, true); - oLayout.AddRow(); - item = oLayout.AddButton(L"refreshAnimation", L"Refresh"); - item = oLayout.AddButton(L"addAnimation", L"Add"); - item = oLayout.AddButton(L"removeAnimation", L"Remove"); - oLayout.EndRow(); - oLayout.EndGroup(); + oLayout.AddRow(); + item = oLayout.AddButton(L"refreshAnimation", L"Refresh"); + item = oLayout.AddButton(L"addAnimation", L"Add"); + item = oLayout.AddButton(L"removeAnimation", L"Remove"); + oLayout.EndRow(); + oLayout.EndGroup(); - // Make animatino name read-only (not any more) - //item.PutAttribute(siUIGridReadOnlyColumns, L"1:0:0:0"); + // Make animatino name read-only (not any more) + //item.PutAttribute(siUIGridReadOnlyColumns, L"1:0:0:0"); @@ -957,47 +957,47 @@ CStatus OgreMeshExportOptions_DefineLayout( const CRef & in_Ctx ) - return CStatus::OK; + return CStatus::OK; } bool hasSkeleton(X3DObject& si, bool recurse) { - if (si.GetEnvelopes().GetCount() > 0) - { - return true; - } - - if (recurse) - { - - CRefArray children = si.GetChildren(); - - for(long i = 0; i < children.GetCount(); i++) - { - X3DObject child(children[i]); - bool ret = hasSkeleton(child, recurse); - if (ret) - return ret; - } - } - - return false; - + if (si.GetEnvelopes().GetCount() > 0) + { + return true; + } + + if (recurse) + { + + CRefArray children = si.GetChildren(); + + for(long i = 0; i < children.GetCount(); i++) + { + X3DObject child(children[i]); + bool ret = hasSkeleton(child, recurse); + if (ret) + return ret; + } + } + + return false; + } bool hasSkeleton(Selection& sel, bool recurse) { - // iterate over selection - for (int i = 0; i < sel.GetCount(); ++i) - { - X3DObject obj(sel[i]); - bool ret = hasSkeleton(obj, recurse); - if (ret) - return ret; - } - - return false; + // iterate over selection + for (int i = 0; i < sel.GetCount(); ++i) + { + X3DObject obj(sel[i]); + bool ret = hasSkeleton(obj, recurse); + if (ret) + return ret; + } + + return false; } @@ -1005,116 +1005,116 @@ bool hasSkeleton(Selection& sel, bool recurse) void findAnimations(XSI::Model& model, Ogre::AnimationList& animList) { - if (model.HasMixer()) - { - // Scan the mixer for all clips - // At this point we're only interested in the top-level and do not - // cascade into all clip containers, since we're interested in the - // top-level timeline splits - XSI::Mixer mixer = model.GetMixer(); - CRefArray clips = mixer.GetClips(); - for (int c = 0; c < clips.GetCount(); ++c) - { - XSI::Clip clip(clips[c]); - XSI::CString clipType = clip.GetType(); - if (clipType == siClipAnimationType || - clipType == siClipShapeType || - clipType == siClipAnimCompoundType || // nested fcurves - clipType == siClipShapeCompoundType) // nested shape - { - XSI::TimeControl timeControl = clip.GetTimeControl(); - Ogre::AnimationEntry anim; - anim.animationName = XSItoOgre(clip.GetName()); - anim.startFrame = timeControl.GetStartOffset(); - long length = (1.0 / timeControl.GetScale()) * - (timeControl.GetClipOut() - timeControl.GetClipIn() + 1); - anim.endFrame = anim.startFrame + length - 1; - anim.ikSampleInterval = 5.0f; - animList.push_back(anim); - - } - - } - - } + if (model.HasMixer()) + { + // Scan the mixer for all clips + // At this point we're only interested in the top-level and do not + // cascade into all clip containers, since we're interested in the + // top-level timeline splits + XSI::Mixer mixer = model.GetMixer(); + CRefArray clips = mixer.GetClips(); + for (int c = 0; c < clips.GetCount(); ++c) + { + XSI::Clip clip(clips[c]); + XSI::CString clipType = clip.GetType(); + if (clipType == siClipAnimationType || + clipType == siClipShapeType || + clipType == siClipAnimCompoundType || // nested fcurves + clipType == siClipShapeCompoundType) // nested shape + { + XSI::TimeControl timeControl = clip.GetTimeControl(); + Ogre::AnimationEntry anim; + anim.animationName = XSItoOgre(clip.GetName()); + anim.startFrame = timeControl.GetStartOffset(); + long length = (1.0 / timeControl.GetScale()) * + (timeControl.GetClipOut() - timeControl.GetClipIn() + 1); + anim.endFrame = anim.startFrame + length - 1; + anim.ikSampleInterval = 5.0f; + animList.push_back(anim); + + } + + } + + } } void getAnimations(XSI::Model& root, Ogre::AnimationList& animList) { - animList.clear(); - - findAnimations(root, animList); - - // Find all children (recursively) - XSI::CRefArray children = root.FindChildren(L"", siModelType, XSI::CStringArray()); - for (int c = 0; c < children.GetCount(); ++c) - { - XSI::Model child(children[c]); - findAnimations(child, animList); - } - - // Now iterate over the list and eliminate overlapping elements - for (Ogre::AnimationList::iterator i = animList.begin(); - i != animList.end(); ++i) - { - Ogre::AnimationList::iterator j = i; - ++j; - for (; j != animList.end();) - { - bool remove = false; - if (j->startFrame <= i->endFrame && j->endFrame >= i->startFrame) - { - // Merge this one into i, extend boundaries - remove = true; - i->startFrame = std::min(j->startFrame, i->startFrame); - i->endFrame = std::max(j->endFrame, i->endFrame); - } - if (remove) - { - j = animList.erase(j); - } - else - { - ++j; - } - } - } + animList.clear(); + + findAnimations(root, animList); + + // Find all children (recursively) + XSI::CRefArray children = root.FindChildren(L"", siModelType, XSI::CStringArray()); + for (int c = 0; c < children.GetCount(); ++c) + { + XSI::Model child(children[c]); + findAnimations(child, animList); + } + + // Now iterate over the list and eliminate overlapping elements + for (Ogre::AnimationList::iterator i = animList.begin(); + i != animList.end(); ++i) + { + Ogre::AnimationList::iterator j = i; + ++j; + for (; j != animList.end();) + { + bool remove = false; + if (j->startFrame <= i->endFrame && j->endFrame >= i->startFrame) + { + // Merge this one into i, extend boundaries + remove = true; + i->startFrame = std::min(j->startFrame, i->startFrame); + i->endFrame = std::max(j->endFrame, i->endFrame); + } + if (remove) + { + j = animList.erase(j); + } + else + { + ++j; + } + } + } } void populateAnimationsList(XSI::GridData gd) { - // 5 columns - gd.PutColumnCount(5); - - // Export column is a check box - gd.PutColumnType(ANIMATION_LIST_EXPORT_COL, siColumnBool); - - // Labels - gd.PutColumnLabel(ANIMATION_LIST_EXPORT_COL, L""); - gd.PutColumnLabel(ANIMATION_LIST_NAME_COL, L"Name"); - gd.PutColumnLabel(ANIMATION_LIST_START_COL, L"Start"); - gd.PutColumnLabel(ANIMATION_LIST_END_COL, L"End"); - gd.PutColumnLabel(ANIMATION_LIST_IKFREQ_COL, L"Sample Freq"); - - - Application app; - Model appRoot(app.GetActiveSceneRoot()); - getAnimations(appRoot, animList); - gd.PutRowCount(animList.size()); - long row = 0; - for (Ogre::AnimationList::iterator a = animList.begin(); - a != animList.end(); ++a, ++row) - { - gd.PutCell(ANIMATION_LIST_NAME_COL, row, OgretoXSI(a->animationName)); - // default to export - gd.PutCell(ANIMATION_LIST_EXPORT_COL, row, true); - gd.PutCell(ANIMATION_LIST_START_COL, row, CValue((LONG)a->startFrame)); - gd.PutCell(ANIMATION_LIST_END_COL, row, CValue((LONG)a->endFrame)); - gd.PutCell(ANIMATION_LIST_IKFREQ_COL, row, a->ikSampleInterval); - } + // 5 columns + gd.PutColumnCount(5); + + // Export column is a check box + gd.PutColumnType(ANIMATION_LIST_EXPORT_COL, siColumnBool); + + // Labels + gd.PutColumnLabel(ANIMATION_LIST_EXPORT_COL, L""); + gd.PutColumnLabel(ANIMATION_LIST_NAME_COL, L"Name"); + gd.PutColumnLabel(ANIMATION_LIST_START_COL, L"Start"); + gd.PutColumnLabel(ANIMATION_LIST_END_COL, L"End"); + gd.PutColumnLabel(ANIMATION_LIST_IKFREQ_COL, L"Sample Freq"); + + + Application app; + Model appRoot(app.GetActiveSceneRoot()); + getAnimations(appRoot, animList); + gd.PutRowCount(animList.size()); + long row = 0; + for (Ogre::AnimationList::iterator a = animList.begin(); + a != animList.end(); ++a, ++row) + { + gd.PutCell(ANIMATION_LIST_NAME_COL, row, OgretoXSI(a->animationName)); + // default to export + gd.PutCell(ANIMATION_LIST_EXPORT_COL, row, true); + gd.PutCell(ANIMATION_LIST_START_COL, row, CValue((LONG)a->startFrame)); + gd.PutCell(ANIMATION_LIST_END_COL, row, CValue((LONG)a->endFrame)); + gd.PutCell(ANIMATION_LIST_IKFREQ_COL, row, a->ikSampleInterval); + } } @@ -1124,273 +1124,273 @@ extern "C" /** Event handler for when the options dialog is interacted with */ CStatus OgreMeshExportOptions_PPGEvent( const CRef& io_Ctx ) { - // This callback is called when events happen in the user interface - // This is where you implement the "logic" code. + // This callback is called when events happen in the user interface + // This is where you implement the "logic" code. - Application app ; - static bool hasSkel = false; + Application app ; + static bool hasSkel = false; - PPGEventContext ctx( io_Ctx ) ; + PPGEventContext ctx( io_Ctx ) ; - PPGEventContext::PPGEvent eventID = ctx.GetEventID() ; + PPGEventContext::PPGEvent eventID = ctx.GetEventID() ; - CustomProperty prop = ctx.GetSource() ; - Parameter objectNameParam = prop.GetParameters().GetItem( L"objectName" ) ; + CustomProperty prop = ctx.GetSource() ; + Parameter objectNameParam = prop.GetParameters().GetItem( L"objectName" ) ; // On open dialog if ( eventID == PPGEventContext::siOnInit ) - { - CString theObjectName; + { + CString theObjectName; // Pre-populate object with currently selected item(s) - Selection sel(app.GetSelection()); - if (sel.GetCount() > 0) - { - CString val; - for (int i = 0; i < sel.GetCount(); ++i) - { - CString thisName = SIObject(sel[i]).GetName(); - val += thisName; - theObjectName += thisName; - if (i < sel.GetCount() - 1) - { - val += L", "; - theObjectName += L"_"; - } - } - prop.PutParameterValue(L"objectName", val); - } - else - { - // no selection, assume entire scene - prop.PutParameterValue(L"objectName", CString(L"[Entire Scene]")); - } + Selection sel(app.GetSelection()); + if (sel.GetCount() > 0) + { + CString val; + for (int i = 0; i < sel.GetCount(); ++i) + { + CString thisName = SIObject(sel[i]).GetName(); + val += thisName; + theObjectName += thisName; + if (i < sel.GetCount() - 1) + { + val += L", "; + theObjectName += L"_"; + } + } + prop.PutParameterValue(L"objectName", val); + } + else + { + // no selection, assume entire scene + prop.PutParameterValue(L"objectName", CString(L"[Entire Scene]")); + } // Make the selection read-only - objectNameParam.PutCapabilityFlag( siReadOnly, true ); - - // Default mesh name - if (prop.GetParameterValue(L"targetMeshFileName") == L"") - { - // default name - prop.PutParameterValue(L"targetMeshFileName", theObjectName + L".mesh"); - } - - // Default material name - if (prop.GetParameterValue(L"targetMaterialFileName") == L"") - { - // default name - prop.PutParameterValue(L"targetMaterialFileName", theObjectName + L".material"); - } - - // default the frame rate to that selected in animation panel - prop.PutParameterValue(L"fps", CTime().GetFrameRate()); - - // enable / disable the skeleton export based on envelopes - if (!hasSkeleton(sel, true)) - { - prop.PutParameterValue(L"exportSkeleton", false); - Parameter param = prop.GetParameters().GetItem(L"exportSkeleton"); - param.PutCapabilityFlag(siReadOnly, true); - param = prop.GetParameters().GetItem(L"targetSkeletonFileName"); - param.PutCapabilityFlag(siReadOnly, true); - hasSkel = false; - } - else - { - prop.PutParameterValue(L"exportSkeleton", true); - Parameter param = prop.GetParameters().GetItem(L"exportSkeleton"); - param.PutCapabilityFlag(siReadOnly, false); - param = prop.GetParameters().GetItem(L"targetSkeletonFileName"); - param.PutCapabilityFlag(siReadOnly, false); - - if (prop.GetParameterValue(L"targetSkeletonFileName") == L"") - { - // default name - prop.PutParameterValue(L"targetSkeletonFileName", theObjectName + L".skeleton"); - } - hasSkel = true; - } - // value of param is a griddata object - // initialise it with all detected animations if it's empty - Parameter param = prop.GetParameters().GetItem(L"animationList"); - GridData gd(param.GetValue()); - if (gd.GetRowCount() == 0 || gd.GetCell(0,0) == L"No data has been set") - { - populateAnimationsList(gd); - } - - } + objectNameParam.PutCapabilityFlag( siReadOnly, true ); + + // Default mesh name + if (prop.GetParameterValue(L"targetMeshFileName") == L"") + { + // default name + prop.PutParameterValue(L"targetMeshFileName", theObjectName + L".mesh"); + } + + // Default material name + if (prop.GetParameterValue(L"targetMaterialFileName") == L"") + { + // default name + prop.PutParameterValue(L"targetMaterialFileName", theObjectName + L".material"); + } + + // default the frame rate to that selected in animation panel + prop.PutParameterValue(L"fps", CTime().GetFrameRate()); + + // enable / disable the skeleton export based on envelopes + if (!hasSkeleton(sel, true)) + { + prop.PutParameterValue(L"exportSkeleton", false); + Parameter param = prop.GetParameters().GetItem(L"exportSkeleton"); + param.PutCapabilityFlag(siReadOnly, true); + param = prop.GetParameters().GetItem(L"targetSkeletonFileName"); + param.PutCapabilityFlag(siReadOnly, true); + hasSkel = false; + } + else + { + prop.PutParameterValue(L"exportSkeleton", true); + Parameter param = prop.GetParameters().GetItem(L"exportSkeleton"); + param.PutCapabilityFlag(siReadOnly, false); + param = prop.GetParameters().GetItem(L"targetSkeletonFileName"); + param.PutCapabilityFlag(siReadOnly, false); + + if (prop.GetParameterValue(L"targetSkeletonFileName") == L"") + { + // default name + prop.PutParameterValue(L"targetSkeletonFileName", theObjectName + L".skeleton"); + } + hasSkel = true; + } + // value of param is a griddata object + // initialise it with all detected animations if it's empty + Parameter param = prop.GetParameters().GetItem(L"animationList"); + GridData gd(param.GetValue()); + if (gd.GetRowCount() == 0 || gd.GetCell(0,0) == L"No data has been set") + { + populateAnimationsList(gd); + } + + } // On clicking a button - else if ( eventID == PPGEventContext::siButtonClicked ) - { - CValue buttonPressed = ctx.GetAttribute( L"Button" ); + else if ( eventID == PPGEventContext::siButtonClicked ) + { + CValue buttonPressed = ctx.GetAttribute( L"Button" ); // Clicked the refresh animation button - if ( buttonPressed.GetAsText() == L"refreshAnimation" ) - { - LONG btn; - CStatus ret = app.GetUIToolkit().MsgBox( - L"Are you sure you want to lose the current contents " - L"of the animations list and to refresh it from mixers?", - siMsgYesNo, - L"Confirm", - btn); - if (btn == 6) - { - Parameter param = prop.GetParameters().GetItem(L"animationList"); - GridData gd(param.GetValue()); - populateAnimationsList(gd); - } - - } - else if( buttonPressed.GetAsText() == L"addAnimation" ) - { - Parameter param = prop.GetParameters().GetItem(L"animationList"); - GridData gd(param.GetValue()); - - gd.PutRowCount(gd.GetRowCount() + 1); - // default export to true and sample rate - gd.PutCell(ANIMATION_LIST_EXPORT_COL, gd.GetRowCount()-1, true); - gd.PutCell(ANIMATION_LIST_IKFREQ_COL, gd.GetRowCount()-1, (LONG)5); - } - else if( buttonPressed.GetAsText() == L"removeAnimation" ) - { - Parameter param = prop.GetParameters().GetItem(L"animationList"); - GridData gd(param.GetValue()); - GridWidget gw = gd.GetGridWidget(); - - // cell-level selection, so have to search for selection in every cell - long selRow = -1; - for (long row = 0; row < gd.GetRowCount() && selRow == -1; ++row) - { - for (long col = 0; col < gd.GetColumnCount() && selRow == -1; ++col) - { - if (gw.IsCellSelected(col, row)) - { - selRow = row; - } - } - } - - if (selRow != -1) - { - LONG btn; - CStatus ret = app.GetUIToolkit().MsgBox( - L"Are you sure you want to remove this animation entry?", - siMsgYesNo, - L"Confirm", - btn); - if (btn == 6) - { - // Move all the contents up one - for (long row = selRow; row < gd.GetRowCount(); ++row) - { - for (long col = 0; col < gd.GetColumnCount(); ++col) - { - gd.PutCell(col, row, gd.GetCell(col, row+1)); - } - } - // remove last row - gd.PutRowCount(gd.GetRowCount() - 1); - } - - } - - } - } + if ( buttonPressed.GetAsText() == L"refreshAnimation" ) + { + LONG btn; + CStatus ret = app.GetUIToolkit().MsgBox( + L"Are you sure you want to lose the current contents " + L"of the animations list and to refresh it from mixers?", + siMsgYesNo, + L"Confirm", + btn); + if (btn == 6) + { + Parameter param = prop.GetParameters().GetItem(L"animationList"); + GridData gd(param.GetValue()); + populateAnimationsList(gd); + } + + } + else if( buttonPressed.GetAsText() == L"addAnimation" ) + { + Parameter param = prop.GetParameters().GetItem(L"animationList"); + GridData gd(param.GetValue()); + + gd.PutRowCount(gd.GetRowCount() + 1); + // default export to true and sample rate + gd.PutCell(ANIMATION_LIST_EXPORT_COL, gd.GetRowCount()-1, true); + gd.PutCell(ANIMATION_LIST_IKFREQ_COL, gd.GetRowCount()-1, (LONG)5); + } + else if( buttonPressed.GetAsText() == L"removeAnimation" ) + { + Parameter param = prop.GetParameters().GetItem(L"animationList"); + GridData gd(param.GetValue()); + GridWidget gw = gd.GetGridWidget(); + + // cell-level selection, so have to search for selection in every cell + long selRow = -1; + for (long row = 0; row < gd.GetRowCount() && selRow == -1; ++row) + { + for (long col = 0; col < gd.GetColumnCount() && selRow == -1; ++col) + { + if (gw.IsCellSelected(col, row)) + { + selRow = row; + } + } + } + + if (selRow != -1) + { + LONG btn; + CStatus ret = app.GetUIToolkit().MsgBox( + L"Are you sure you want to remove this animation entry?", + siMsgYesNo, + L"Confirm", + btn); + if (btn == 6) + { + // Move all the contents up one + for (long row = selRow; row < gd.GetRowCount(); ++row) + { + for (long col = 0; col < gd.GetColumnCount(); ++col) + { + gd.PutCell(col, row, gd.GetCell(col, row+1)); + } + } + // remove last row + gd.PutRowCount(gd.GetRowCount() - 1); + } + + } + + } + } // Changed a parameter - else if ( eventID == PPGEventContext::siParameterChange ) - { - Parameter changed = ctx.GetSource() ; - CustomProperty prop = changed.GetParent() ; - CString paramName = changed.GetScriptName() ; + else if ( eventID == PPGEventContext::siParameterChange ) + { + Parameter changed = ctx.GetSource() ; + CustomProperty prop = changed.GetParent() ; + CString paramName = changed.GetScriptName() ; // Check paramName against parameter names, perform custom onChanged event - if (paramName == L"targetMeshFileName") - { - // Default skeleton & material name - Ogre::String meshName = XSItoOgre(XSI::CString(changed.GetValue())); - if (hasSkel) - { - Ogre::String skelName = meshName; - if (Ogre::StringUtil::endsWith(skelName, ".mesh")) - { - skelName = skelName.substr(0, skelName.size() - 5) + ".skeleton"; - } - CString xsiSkelName = OgretoXSI(skelName); - prop.PutParameterValue(L"targetSkeletonFileName", xsiSkelName); - } - // default material script name - Ogre::String matName = meshName; - if (Ogre::StringUtil::endsWith(matName, ".mesh")) - { - matName = matName.substr(0, matName.size() - 5) + ".material"; - } - CString xsiMatName = OgretoXSI(matName); - prop.PutParameterValue(L"targetMaterialFileName", xsiMatName); - - - } - } - - - return CStatus::OK; + if (paramName == L"targetMeshFileName") + { + // Default skeleton & material name + Ogre::String meshName = XSItoOgre(XSI::CString(changed.GetValue())); + if (hasSkel) + { + Ogre::String skelName = meshName; + if (Ogre::StringUtil::endsWith(skelName, ".mesh")) + { + skelName = skelName.substr(0, skelName.size() - 5) + ".skeleton"; + } + CString xsiSkelName = OgretoXSI(skelName); + prop.PutParameterValue(L"targetSkeletonFileName", xsiSkelName); + } + // default material script name + Ogre::String matName = meshName; + if (Ogre::StringUtil::endsWith(matName, ".mesh")) + { + matName = matName.substr(0, matName.size() - 5) + ".material"; + } + CString xsiMatName = OgretoXSI(matName); + prop.PutParameterValue(L"targetMaterialFileName", xsiMatName); + + + } + } + + + return CStatus::OK; } CString GetUserSelectedObject() { - Application app; - Model root(app.GetActiveSceneRoot()); - CStringArray emptyArray; - CRefArray cRefArray = root.FindChildren( L"", L"", emptyArray, true ); - - CStringArray nameArray(cRefArray.GetCount()); - for ( long i=0; i < cRefArray.GetCount(); i++ ) - { - nameArray[i] = SIObject(cRefArray[i]).GetName(); - } - //todo qsort the nameArray - - // Using the COMAPIHandler for creating a "XSIDial.XSIDialog" - CComAPIHandler xsidialog; - xsidialog.CreateInstance( L"XSIDial.XSIDialog"); - CValue index; - CValueArray args(cRefArray.GetCount()); - for (long y=0; y < cRefArray.GetCount(); y++) - args[y]=nameArray[y]; - - xsidialog.Call(L"Combo",index,L"Select Item",args ); - - long ind = (LONG)index; - return args[ind]; + Application app; + Model root(app.GetActiveSceneRoot()); + CStringArray emptyArray; + CRefArray cRefArray = root.FindChildren( L"", L"", emptyArray, true ); + + CStringArray nameArray(cRefArray.GetCount()); + for ( long i=0; i < cRefArray.GetCount(); i++ ) + { + nameArray[i] = SIObject(cRefArray[i]).GetName(); + } + //todo qsort the nameArray + + // Using the COMAPIHandler for creating a "XSIDial.XSIDialog" + CComAPIHandler xsidialog; + xsidialog.CreateInstance( L"XSIDial.XSIDialog"); + CValue index; + CValueArray args(cRefArray.GetCount()); + for (long y=0; y < cRefArray.GetCount(); y++) + args[y]=nameArray[y]; + + xsidialog.Call(L"Combo",index,L"Select Item",args ); + + long ind = (LONG)index; + return args[ind]; } CStatus Popup( const CString& in_inputobjs, const CString& in_keywords, const CString& in_title, const CValue& /*number*/ in_mode, bool in_throw ) { - Application app; - CValueArray args(5); - CValue retval; - long i(0); + Application app; + CValueArray args(5); + CValue retval; + long i(0); - args[i++]= in_inputobjs; - args[i++]= in_keywords; - args[i++]= in_title; - args[i++]= in_mode; - args[i++]= in_throw; + args[i++]= in_inputobjs; + args[i++]= in_keywords; + args[i++]= in_title; + args[i++]= in_mode; + args[i++]= in_throw; - return app.ExecuteCommand( L"InspectObj", args, retval ); + return app.ExecuteCommand( L"InspectObj", args, retval ); } void DeleteObj( const CValue& in_inputobj ) { - Application app; - CValueArray args(1); - CValue retval; - long i(0); + Application app; + CValueArray args(1); + CValue retval; + long i(0); - args[i++]= in_inputobj; + args[i++]= in_inputobj; - CStatus st = app.ExecuteCommand( L"DeleteObj", args, retval ); + CStatus st = app.ExecuteCommand( L"DeleteObj", args, retval ); - return; + return; } diff --git a/Tools/XSIExport/src/OgreXSIHelper.cpp b/Tools/XSIExport/src/OgreXSIHelper.cpp index e2ad7c0bb48..0099af1ef6a 100644 --- a/Tools/XSIExport/src/OgreXSIHelper.cpp +++ b/Tools/XSIExport/src/OgreXSIHelper.cpp @@ -30,68 +30,68 @@ THE SOFTWARE. namespace Ogre { - //----------------------------------------------------------------------- - void copyFile(const String& src, const String& dst) - { - std::ifstream in(src.c_str(), std::ios::in | std::ios::binary); - std::ofstream out(dst.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); - - if (!in || !out) - { - LogOgreAndXSI("Unable to copy texture '" + src + "' to '" + dst + "'"); - return; - } - - char tmpBuf[2048]; - - while (!in.eof()) - { - in.read(tmpBuf, 2048); - - std::streamsize c = in.gcount(); - - out.write(tmpBuf, c); - - } - - in.close(); - out.close(); - - - - } - //----------------------------------------------------------------------- - template<> ProgressManager* Singleton::msSingleton = 0; - ProgressManager* ProgressManager::getSingletonPtr(void) - { - return msSingleton; - } - ProgressManager& ProgressManager::getSingleton(void) - { - assert( msSingleton ); return ( *msSingleton ); - } - //----------------------------------------------------------------------------- - ProgressManager::ProgressManager(size_t numberOfStages) - :mNumberOfStages(numberOfStages), mProgress(0) - { - XSI::Application app; - - mProgressBar = app.GetUIToolkit().GetProgressBar(); - mProgressBar.PutMaximum(numberOfStages); - mProgressBar.PutStep(1); - mProgressBar.PutVisible(true); - mProgressBar.PutCaption(L"Exporting"); - } - //----------------------------------------------------------------------------- - ProgressManager::~ProgressManager() - { - } - //----------------------------------------------------------------------------- - void ProgressManager::progress(void) - { - ++mProgress; - mProgressBar.Increment(); - - } + //----------------------------------------------------------------------- + void copyFile(const String& src, const String& dst) + { + std::ifstream in(src.c_str(), std::ios::in | std::ios::binary); + std::ofstream out(dst.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + + if (!in || !out) + { + LogOgreAndXSI("Unable to copy texture '" + src + "' to '" + dst + "'"); + return; + } + + char tmpBuf[2048]; + + while (!in.eof()) + { + in.read(tmpBuf, 2048); + + std::streamsize c = in.gcount(); + + out.write(tmpBuf, c); + + } + + in.close(); + out.close(); + + + + } + //----------------------------------------------------------------------- + template<> ProgressManager* Singleton::msSingleton = 0; + ProgressManager* ProgressManager::getSingletonPtr(void) + { + return msSingleton; + } + ProgressManager& ProgressManager::getSingleton(void) + { + assert( msSingleton ); return ( *msSingleton ); + } + //----------------------------------------------------------------------------- + ProgressManager::ProgressManager(size_t numberOfStages) + :mNumberOfStages(numberOfStages), mProgress(0) + { + XSI::Application app; + + mProgressBar = app.GetUIToolkit().GetProgressBar(); + mProgressBar.PutMaximum(numberOfStages); + mProgressBar.PutStep(1); + mProgressBar.PutVisible(true); + mProgressBar.PutCaption(L"Exporting"); + } + //----------------------------------------------------------------------------- + ProgressManager::~ProgressManager() + { + } + //----------------------------------------------------------------------------- + void ProgressManager::progress(void) + { + ++mProgress; + mProgressBar.Increment(); + + } } \ No newline at end of file diff --git a/Tools/XSIExport/src/OgreXSIMaterialExporter.cpp b/Tools/XSIExport/src/OgreXSIMaterialExporter.cpp index 39383940ba9..239d6012fde 100644 --- a/Tools/XSIExport/src/OgreXSIMaterialExporter.cpp +++ b/Tools/XSIExport/src/OgreXSIMaterialExporter.cpp @@ -39,948 +39,948 @@ THE SOFTWARE. namespace Ogre { - //------------------------------------------------------------------------- - XsiMaterialExporter::XsiMaterialExporter() - { - - } - //------------------------------------------------------------------------- - XsiMaterialExporter::~XsiMaterialExporter() - { - clearPassQueue(); - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::exportMaterials(MaterialMap& materials, - TextureProjectionMap& texProjMap, const String& filename, - bool copyTextures) - { - LogOgreAndXSI("** Begin OGRE Material Export **"); - - mTextureProjectionMap = texProjMap; - - String texturePath; - if (copyTextures) - { - // derive the texture path - String::size_type pos = filename.find_last_of("\\"); - if (pos == String::npos) - { - pos = filename.find_last_of("/"); - } - if (pos != String::npos) - { - texturePath = filename.substr(0, pos + 1); - } - } - - mMatSerializer.clearQueue(); - - for (MaterialMap::iterator m = materials.begin(); m != materials.end(); ++m) - { - exportMaterial(m->second, copyTextures, texturePath); - } - - mMatSerializer.exportQueued(filename); - - LogOgreAndXSI("** OGRE Material Export Complete **"); - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::exportMaterial(MaterialEntry* matEntry, - bool copyTextures, const String& texturePath) - { - LogOgreAndXSI("Exporting " + matEntry->name); - - MaterialPtr mat = MaterialManager::getSingleton().create( - matEntry->name, - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - Technique* t = mat->createTechnique(); - - // collect the passes into our queue - // XSI stores passes in reverse order, so invert them - clearPassQueue(); - XSI::Shader shader(matEntry->xsiShader); - PassEntry* passEntry = new PassEntry(); - mPassQueue.push_front(passEntry); - while (1) - { - passEntry->shaders.Add(shader); - - XSI::CRef source = shader.GetParameter(L"previous").GetSource(); - if(!source.IsValid() || !source.IsA(XSI::siShaderID)) - { - // finish - break; - } - - shader = XSI::Shader(source); - // If we find a 'blending' parameter, we're on a new pass - if (shader.GetParameter(L"blending").IsValid()) - { - passEntry = new PassEntry(); - mPassQueue.push_front(passEntry); // push front to invert order - } - } - - - // Now go through each pass and create OGRE version - for (PassQueue::iterator p = mPassQueue.begin(); p != mPassQueue.end(); ++p) - { - PassEntry* passEntry = *p; - Pass* pass = t->createPass(); - LogOgreAndXSI("Added Pass"); - - // Need to pre-populate pass textures to match up transforms - populatePassTextures(pass, passEntry, copyTextures, texturePath); - // Do the rest - for (int s = 0; s < passEntry->shaders.GetCount(); ++s) - { - XSI::Shader shader(passEntry->shaders[s]); - populatePass(pass, shader); - } - - } - - - mMatSerializer.queueForExport(mat); - - - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::clearPassQueue(void) - { - for (PassQueue::iterator i = mPassQueue.begin(); i != mPassQueue.end(); ++i) - { - delete *i; - } - mPassQueue.clear(); - - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populatePass(Pass* pass, XSI::Shader& xsishader) - { - populatePassDepthCull(pass, xsishader); - populatePassSceneBlend(pass, xsishader); - populatePassLighting(pass, xsishader); - populatePassTextureTransforms(pass, xsishader); - populatePassCgPrograms(pass, xsishader); - populatePassHLSLPrograms(pass, xsishader); - populatePassD3DAssemblerPrograms(pass, xsishader); - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populatePassCgPrograms(Pass* pass, - XSI::Shader& xsishader) - { - XSI::Parameter param = xsishader.GetParameter(L"Cg_Program"); - if (param.IsValid()) - { - // TODO - // XSI can't reference external files which makes it v.difficult to - // re-use shaders - mod XSI plugin? - } - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populatePassHLSLPrograms(Pass* pass, - XSI::Shader& xsishader) - { - XSI::Parameter param = xsishader.GetParameter(L"HLSL_Program"); - if (param.IsValid()) - { - // TODO - // XSI can't reference external files which makes it v.difficult to - // re-use shaders - mod XSI plugin? - } - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populatePassD3DAssemblerPrograms(Pass* pass, - XSI::Shader& xsishader) - { - XSI::Parameter param = xsishader.GetParameter(L"Vertex_Shader"); - if (param.IsValid()) - { - // TODO - // XSI can't reference external files which makes it v.difficult to - // re-use shaders - mod XSI plugin? - } - param = xsishader.GetParameter(L"Pixel_Shader"); - if (param.IsValid()) - { - // TODO - // XSI can't reference external files which makes it v.difficult to - // re-use shaders - mod XSI plugin? - } - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populatePassDepthCull(Pass* pass, - XSI::Shader& xsishader) - { - XSI::Parameter param = xsishader.GetParameter(L"cullingmode"); - if (param.IsValid()) - { - short xsiCull = param.GetValue(); - switch (xsiCull) - { - case 0: - pass->setCullingMode(CULL_NONE); - pass->setManualCullingMode(MANUAL_CULL_NONE); - break; - case 1: - pass->setCullingMode(CULL_CLOCKWISE); - pass->setManualCullingMode(MANUAL_CULL_BACK); - break; - case 2: - pass->setCullingMode(CULL_ANTICLOCKWISE); - pass->setManualCullingMode(MANUAL_CULL_FRONT); - break; - - }; - } - - param = xsishader.GetParameter(L"depthtest"); - if (param.IsValid()) - { - bool depthTest = param.GetValue(); - pass->setDepthCheckEnabled(depthTest); - } - param = xsishader.GetParameter(L"depthwrite"); - if (param.IsValid()) - { - bool depthWrite = param.GetValue(); - pass->setDepthWriteEnabled(depthWrite); - } - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populatePassSceneBlend(Pass* pass, - XSI::Shader& xsishader) - { - XSI::Parameter param = xsishader.GetParameter(L"blending"); - if (param.IsValid() && (bool)param.GetValue()) - { - SceneBlendFactor src = SBF_ONE; - SceneBlendFactor dst = SBF_ONE; - - param = xsishader.GetParameter(L"srcblendingfunction"); - if (param.IsValid()) - { - src = convertSceneBlend(param.GetValue()); - } - param = xsishader.GetParameter(L"dstblendingfunction"); - if (param.IsValid()) - { - dst = convertSceneBlend(param.GetValue()); - } - - pass->setSceneBlending(src, dst); - } - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populatePassLighting(Pass* pass, - XSI::Shader& xsishader) - { - XSI::Parameter param = xsishader.GetParameter(L"Enable_Lighting"); - if (param.IsValid()) - { - pass->setLightingEnabled(param.GetValue()); - - ColourValue tmpColour; - xsishader.GetColorParameterValue(L"Ambient", tmpColour.r, tmpColour.g, - tmpColour.b, tmpColour.a); - pass->setAmbient(tmpColour); - xsishader.GetColorParameterValue(L"Diffuse", tmpColour.r, tmpColour.g, - tmpColour.b, tmpColour.a); - pass->setDiffuse(tmpColour); - xsishader.GetColorParameterValue(L"Emissive", tmpColour.r, tmpColour.g, - tmpColour.b, tmpColour.a); - pass->setSelfIllumination(tmpColour); - xsishader.GetColorParameterValue(L"Specular", tmpColour.r, tmpColour.g, - tmpColour.b, tmpColour.a); - pass->setSpecular(tmpColour); - - pass->setShininess(xsishader.GetParameter(L"Shininess").GetValue()); - } - - - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populatePassTextures(Pass* pass, - PassEntry* passEntry, bool copyTextures, const String& targetFolder) - { - // We need to search all shaders back to the point we would change - // passes, and add all the textures. This is because we don't know - // where in the shaders the texture transforms might be, since they - // are linked via 'target' not by being on the same object. - mTextureUnitTargetMap.clear(); - - for (int s = 0; s < passEntry->shaders.GetCount(); ++s) - { - XSI::Shader shader(passEntry->shaders[s]); - TextureUnitState* tex = 0; - - String progID = XSItoOgre(shader.GetProgID()); - if (progID.find("OGL13Texture") != String::npos || - progID.find("DXTexture") != String::npos || - progID.find("OGLCom") != String::npos) - { - if (!shader.GetParameter(L"bottom").IsValid()) - { - tex = add2DTexture(pass, shader, copyTextures, targetFolder); - } - else if (shader.GetParameter(L"bottom").IsValid()) - { - tex = addCubicTexture(pass, shader, copyTextures, targetFolder); - } - } - else - { - continue; // not a texture so skip the rest - } - - - // texture coordinate set - XSI::Parameter param = shader.GetParameter(L"tspace_id"); - if (param.IsValid()) - { - // this is a name, need to look up index - tex->setTextureCoordSet( - getTextureCoordIndex(XSItoOgre(XSI::CString(param.GetValue())))); - } - - // filtering & anisotropy - // DX and GL shaders deal differently - if (progID.find("OGL") != String::npos) - { - populateOGLFiltering(tex, shader); - } - else if (progID.find("DX") != String::npos) - { - populateDXFiltering(tex, shader); - } - - // colour operation - param = shader.GetParameter(L"modulation"); - if (param.IsValid()) - { - long colourop = ((LONG)param.GetValue()); - switch (colourop) - { - case 0: - // modulate - tex->setColourOperation(LBO_MODULATE); - break; - case 1: - // decal - tex->setColourOperation(LBO_ALPHA_BLEND); - break; - case 2: - // blend - tex->setColourOperation(LBO_MODULATE); - break; - case 3: - // replace - tex->setColourOperation(LBO_REPLACE); - break; - case 4: - // add - tex->setColourOperation(LBO_ADD); - break; - } - - } - - - - } - } - //------------------------------------------------------------------------- - TextureUnitState* XsiMaterialExporter::add2DTexture(Pass* pass, XSI::Shader& shader, - bool copyTextures, const String& targetFolder) - { - // create texture unit state and map from target incase future xforms - TextureUnitState* tex = pass->createTextureUnitState(); - - XSI::Parameter param = shader.GetParameter(L"target"); // OGL - if (!param.IsValid()) - param = shader.GetParameter(L"Texture_Target"); // DX - - long target = ((LONG)param.GetValue()); - mTextureUnitTargetMap.insert( - TextureUnitTargetMap::value_type(target, tex)); - - // Get image - XSI::CRef src = shader.GetParameter(L"Texture").GetSource(); - if (!src.IsValid() || !src.IsA(XSI::siImageClipID)) - { - // Try Texture_1 (OGL Combined) - src = shader.GetParameter(L"Texture_1").GetSource(); - - } - if (src.IsValid() && src.IsA(XSI::siImageClipID)) - { - XSI::ImageClip imgClip(src); - String srcTextureName = - XSItoOgre(XSI::CString(imgClip.GetParameter(L"SourceFileName").GetValue())); - - String::size_type pos = srcTextureName.find_last_of("\\"); - if (pos == String::npos) - { - pos = srcTextureName.find_last_of("/"); - } - String textureName = - srcTextureName.substr(pos+1, srcTextureName.size() - pos - 1); - String destTextureName = targetFolder + textureName; - - // copy texture if required - if (copyTextures) - { - copyFile(srcTextureName, destTextureName); - } - - LogOgreAndXSI("Adding texture " + textureName); - tex->setTextureName(textureName); - - } - - return tex; - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populateOGLFiltering(TextureUnitState* tex, - XSI::Shader& shader) - { - FilterOptions minFilter, mipFilter, magFilter; - minFilter = FO_LINEAR; - magFilter = FO_LINEAR; - mipFilter = FO_POINT; - XSI::Parameter param = shader.GetParameter(L"minfilter"); - if (param.IsValid()) - { - // XSI OGL shader uses minfilter to determine mip too - long filt = ((LONG)param.GetValue()); - switch(filt) - { - case 0: - minFilter = FO_POINT; - mipFilter = FO_NONE; - break; - case 1: - minFilter = FO_LINEAR; - mipFilter = FO_NONE; - break; - case 2: - minFilter = FO_POINT; - mipFilter = FO_POINT; - break; - case 3: - minFilter = FO_POINT; - mipFilter = FO_LINEAR; - break; - case 4: - minFilter = FO_LINEAR; - mipFilter = FO_POINT; - break; - case 5: - minFilter = FO_LINEAR; - mipFilter = FO_LINEAR; - break; - }; - - } - param = shader.GetParameter(L"magfilter"); - if (param.IsValid()) - { - long filt = ((LONG)param.GetValue()); - switch(filt) - { - case 0: - magFilter = FO_POINT; - break; - case 1: - magFilter = FO_LINEAR; - break; - }; - } - - param = shader.GetParameter(L"anisotropy"); - if (param.IsValid()) - { - long aniso = ((LONG)param.GetValue()); - if (aniso > 1) - { - // No specific aniso filtering option, so upgrade linear -> aniso - if (minFilter == FO_LINEAR) - minFilter = FO_ANISOTROPIC; - if (magFilter == FO_LINEAR) - magFilter = FO_ANISOTROPIC; - } - tex->setTextureAnisotropy(aniso); - } - - tex->setTextureFiltering(minFilter, magFilter, mipFilter); - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populateDXFiltering(TextureUnitState* tex, - XSI::Shader& shader) - { - FilterOptions minFilter, mipFilter, magFilter; - minFilter = FO_LINEAR; - magFilter = FO_LINEAR; - mipFilter = FO_POINT; - XSI::Parameter param = shader.GetParameter(L"minfilter"); - if (param.IsValid()) - { - // XSI DX shader has min/mag and mip, and has more options - long filt = ((LONG)param.GetValue()); - switch(filt) - { - case 0: - minFilter = FO_NONE; - break; - case 1: - minFilter = FO_POINT; - break; - case 2: - minFilter = FO_LINEAR; - break; - case 3: - case 4: // we don't support cubic/gaussian, use aniso - case 5: - minFilter = FO_ANISOTROPIC; - break; - }; - } - param = shader.GetParameter(L"magfilter"); - if (param.IsValid()) - { - // XSI DX shader has mag/mag and mip, and has more options - long filt = ((LONG)param.GetValue()); - switch(filt) - { - case 0: - magFilter = FO_NONE; - break; - case 1: - magFilter = FO_POINT; - break; - case 2: - magFilter = FO_LINEAR; - break; - case 3: - case 4: // we don't support cubic/gaussian, use aniso - case 5: - magFilter = FO_ANISOTROPIC; - break; - }; - } - param = shader.GetParameter(L"mipfilter"); - if (param.IsValid()) - { - // XSI DX shader has mip/mag and mip, and has more options - long filt = ((LONG)param.GetValue()); - switch(filt) - { - case 0: - mipFilter = FO_NONE; - break; - case 1: - mipFilter = FO_POINT; - break; - case 2: - mipFilter = FO_LINEAR; - break; - case 3: - case 4: // we don't support cubic/gaussian, use aniso - case 5: - mipFilter = FO_ANISOTROPIC; - break; - }; - } - // Aniso - param = shader.GetParameter(L"anisotropy"); - if (param.IsValid()) - { - long aniso = ((LONG)param.GetValue()); - tex->setTextureAnisotropy(aniso); - } - - tex->setTextureFiltering(minFilter, magFilter, mipFilter); - } - //------------------------------------------------------------------------- - TextureUnitState* XsiMaterialExporter::addCubicTexture(Pass* pass, XSI::Shader& shader, - bool copyTextures, const String& targetFolder) - { - // create texture unit state and map from target incase future xforms - TextureUnitState* tex = pass->createTextureUnitState(); - - XSI::Parameter param = shader.GetParameter(L"target"); // OGL - if (!param.IsValid()) - param = shader.GetParameter(L"Texture_Target"); // DX - - long target = ((LONG)param.GetValue()); - mTextureUnitTargetMap.insert( - TextureUnitTargetMap::value_type(target, tex)); - - // Get images - wchar_t* cubeFaceName[6] = { - L"front", L"back", L"top", L"bottom", L"left", L"right" }; - - String finalNames[6]; - - - for (int face = 0; face < 6; ++face) - { - XSI::CRef src = shader.GetParameter(cubeFaceName[face]).GetSource(); - if (src.IsValid() && src.IsA(XSI::siImageClipID)) - { - XSI::ImageClip imgClip(src); - String srcTextureName = - XSItoOgre(XSI::CString(imgClip.GetParameter(L"SourceFileName").GetValue())); - - String::size_type pos = srcTextureName.find_last_of("\\"); - if (pos == String::npos) - { - pos = srcTextureName.find_last_of("/"); - } - finalNames[face] = - srcTextureName.substr(pos+1, srcTextureName.size() - pos - 1); - String destTextureName = targetFolder + finalNames[face]; - - // copy texture if required - if (copyTextures) - { - copyFile(srcTextureName, destTextureName); - } - - - LogOgreAndXSI("Cubemap face: " + srcTextureName); - } - } - - LogOgreAndXSI("Adding cubic texture"); - // Cannot do combinedUVW for now, DevIL can't write DDS cubemap so - // go for separates (user can modify) - tex->setCubicTextureName(finalNames, false); - - return tex; - - } - //------------------------------------------------------------------------- - unsigned short XsiMaterialExporter::getTextureCoordIndex(const String& tspace) - { - TextureProjectionMap::iterator i = mTextureProjectionMap.find(tspace); - if (i != mTextureProjectionMap.end()) - { - return i->second; - } - else - { - // default - return 0; - } - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::populatePassTextureTransforms(Pass* pass, - XSI::Shader& shader) - { - // TODO - // Check we have the right object - XSI::Parameter param = shader.GetParameter(L"wrap_u"); - if (param.IsValid()) - { - - // addressing mode - TextureUnitState::UVWAddressingMode uvwadd; - uvwadd.u = convertAddressingMode(param.GetValue()); - // default other dimensions incase not supplied - uvwadd.v = uvwadd.u; - uvwadd.w = uvwadd.u; - - param = shader.GetParameter(L"wrap_v"); - if (param.IsValid()) - { - uvwadd.v = convertAddressingMode(param.GetValue()); - } - param = shader.GetParameter(L"wrap_w"); - if (param.IsValid()) - { - uvwadd.w = convertAddressingMode(param.GetValue()); - } - - // transform - bool usexform = false; - Matrix4 xform = Matrix4::IDENTITY; - param = shader.GetParameter(L"Transform"); - if (param.IsValid() && (bool)param.GetValue()) - { - Quaternion qx, qy, qz, qfinal; - qx.FromAngleAxis(Degree(shader.GetParameter(L"rotx").GetValue()), - Vector3::UNIT_X); - qy.FromAngleAxis(Degree(shader.GetParameter(L"roty").GetValue()), - Vector3::UNIT_Y); - qz.FromAngleAxis(Degree(shader.GetParameter(L"rotz").GetValue()), - Vector3::UNIT_Z); - qfinal = qx * qy * qz; - - Vector3 trans; - trans.x = shader.GetParameter(L"trsx").GetValue(); - trans.y = shader.GetParameter(L"trsy").GetValue(); - trans.z = shader.GetParameter(L"trsz").GetValue(); - - Matrix3 rot3x3, scale3x3; - qfinal.ToRotationMatrix(rot3x3); - scale3x3 = Matrix3::ZERO; - scale3x3[0][0] = shader.GetParameter(L"sclx").GetValue(); - scale3x3[1][1] = shader.GetParameter(L"scly").GetValue(); - scale3x3[2][2] = shader.GetParameter(L"sclz").GetValue(); - - xform = rot3x3 * scale3x3; - xform.setTrans(trans); - usexform = true; - - } - - - // Look up texture unit(s) that are using this target - long target = ((LONG)shader.GetParameter(L"Texture_Target").GetValue()); - TextureUnitTargetMap::iterator i = mTextureUnitTargetMap.find(target); - while (i != mTextureUnitTargetMap.end() && i->first == target) - { - TextureUnitState* tex = i->second; - tex->setTextureAddressingMode(uvwadd); - if (usexform) - tex->setTextureTransform(xform); - - // texgen (not texcoord_index as in OGRE!) - // Can turn into 2 different calls - param = shader.GetParameter(L"texcoord_index"); - if (param.IsValid()) - { - long e = ((LONG)param.GetValue()); - if (e != 0) - { - // Not Explicit - // details differ per DX/OGL - if (XSItoOgre(shader.GetProgID()).find("DX") != String::npos) - { - convertTexGenDX(tex, e, shader); - } - else - { - convertTexGenOGL(tex, e, shader); - } - - } - - } - ++i; - } - - - - - } - param = shader.GetParameter(L"Additive_Transform"); - if (param.IsValid()) - { - unsigned short target = shader.GetParameter(L"Texture_Coord_ID").GetValue(); - if (pass->getNumTextureUnitStates() > target) - { - TextureUnitState* tex = pass->getTextureUnitState(target); - - long uvType = ((LONG)shader.GetParameter(L"UV_Type").GetValue()); - if (uvType != 0) - { - double val1 = shader.GetParameter(L"Val1").GetValue(); - double val2 = shader.GetParameter(L"Val2").GetValue(); - long wave = ((LONG)shader.GetParameter(L"Wave").GetValue()); - WaveformType wft; - switch (wave) - { - case 1: - wft = WFT_SINE; - break; - case 2: - wft = WFT_TRIANGLE; - break; - case 3: - wft = WFT_SQUARE; - break; - case 4: - wft = WFT_SAWTOOTH; - break; - case 5: - wft = WFT_INVERSE_SAWTOOTH; - break; - } - double base = shader.GetParameter(L"Base").GetValue(); - double amp = shader.GetParameter(L"Amplitude").GetValue(); - double phase = shader.GetParameter(L"Phase").GetValue(); - double freq = shader.GetParameter(L"Frequency").GetValue(); - - switch(uvType) - { - case 1: - // translate - tex->setTextureScroll(val1, val2); - break; - case 2: - // rotate - tex->setTextureRotate(Degree(val1)); - break; - case 3: - // scale - tex->setTextureScale(val1, val2); - break; - case 4: - // scroll - if (wave != 0) - { - tex->setTransformAnimation(TextureUnitState::TT_TRANSLATE_U, - wft, base, freq, phase, amp); - tex->setTransformAnimation(TextureUnitState::TT_TRANSLATE_V, - wft, base, freq, phase, amp); - } - else - { - tex->setScrollAnimation(val1, val2); - } - break; - case 5: - // turn - if (wave != 0) - { - tex->setTransformAnimation(TextureUnitState::TT_ROTATE, - wft, base, freq, phase, amp); - } - else - { - tex->setRotateAnimation(val1 / 360.0f); - } - break; - case 6: - // stretch (only wave) - if (wave != 0) - { - tex->setTransformAnimation(TextureUnitState::TT_SCALE_U, - wft, base, freq, phase, amp); - tex->setTransformAnimation(TextureUnitState::TT_SCALE_V, - wft, base, freq, phase, amp); - } - break; - - } - } - } - - } - - // if more than one entry for the same target is found, it is ok for the - // latter to take precedence since this is what happens in XSI. - - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::convertTexGenOGL(TextureUnitState* tex, - long xsiVal, XSI::Shader& shader) - { - switch(xsiVal) - { - // no 0 - case 1: - // Object linear - tex->setEnvironmentMap(true, TextureUnitState::ENV_PLANAR); - break; - case 2: - // Eye linear (texture projection) - tex->setProjectiveTexturing(true); - break; - case 3: - // Sphere map - tex->setEnvironmentMap(true, TextureUnitState::ENV_CURVED); - break; - case 4: - // Reflection map - tex->setEnvironmentMap(true, TextureUnitState::ENV_REFLECTION); - break; - case 5: - // Normal map - tex->setEnvironmentMap(true, TextureUnitState::ENV_NORMAL); - break; - - }; - } - //------------------------------------------------------------------------- - void XsiMaterialExporter::convertTexGenDX(TextureUnitState* tex, - long xsiVal, XSI::Shader& shader) - { - switch(xsiVal) - { - // no 0 - case 1: - // Normal in camera space - tex->setEnvironmentMap(true, TextureUnitState::ENV_CURVED); - break; - case 2: - // Position in camera space - tex->setEnvironmentMap(true, TextureUnitState::ENV_PLANAR); - break; - case 3: - // Reflection vector in camera space - tex->setEnvironmentMap(true, TextureUnitState::ENV_REFLECTION); - break; - - }; - } - //------------------------------------------------------------------------- - TextureUnitState::TextureAddressingMode - XsiMaterialExporter::convertAddressingMode(short xsiVal) - { - // same for OGL and DX - switch(xsiVal) - { - case 0: - return TextureUnitState::TAM_WRAP; - case 1: - return TextureUnitState::TAM_MIRROR; - case 2: - return TextureUnitState::TAM_CLAMP; - case 3: - // border? - return TextureUnitState::TAM_CLAMP; - case 4: - // mirror once - return TextureUnitState::TAM_MIRROR; - case 5: - // clamp to edge - return TextureUnitState::TAM_CLAMP; - - }; - - // Keep compiler happy - return TextureUnitState::TAM_WRAP; - } - //------------------------------------------------------------------------- - SceneBlendFactor XsiMaterialExporter::convertSceneBlend(short xsiVal) - { - switch(xsiVal) - { - case 0: - return SBF_ZERO; - case 1: - return SBF_ONE; - case 2: - return SBF_DEST_COLOUR; - case 3: - return SBF_ONE_MINUS_DEST_COLOUR; - case 4: - return SBF_SOURCE_ALPHA; - case 5: - return SBF_ONE_MINUS_SOURCE_ALPHA; - case 6: - return SBF_DEST_ALPHA; - case 7: - return SBF_ONE_MINUS_DEST_ALPHA; - }; - - return SBF_ZERO; - - } + //------------------------------------------------------------------------- + XsiMaterialExporter::XsiMaterialExporter() + { + + } + //------------------------------------------------------------------------- + XsiMaterialExporter::~XsiMaterialExporter() + { + clearPassQueue(); + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::exportMaterials(MaterialMap& materials, + TextureProjectionMap& texProjMap, const String& filename, + bool copyTextures) + { + LogOgreAndXSI("** Begin OGRE Material Export **"); + + mTextureProjectionMap = texProjMap; + + String texturePath; + if (copyTextures) + { + // derive the texture path + String::size_type pos = filename.find_last_of("\\"); + if (pos == String::npos) + { + pos = filename.find_last_of("/"); + } + if (pos != String::npos) + { + texturePath = filename.substr(0, pos + 1); + } + } + + mMatSerializer.clearQueue(); + + for (MaterialMap::iterator m = materials.begin(); m != materials.end(); ++m) + { + exportMaterial(m->second, copyTextures, texturePath); + } + + mMatSerializer.exportQueued(filename); + + LogOgreAndXSI("** OGRE Material Export Complete **"); + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::exportMaterial(MaterialEntry* matEntry, + bool copyTextures, const String& texturePath) + { + LogOgreAndXSI("Exporting " + matEntry->name); + + MaterialPtr mat = MaterialManager::getSingleton().create( + matEntry->name, + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + Technique* t = mat->createTechnique(); + + // collect the passes into our queue + // XSI stores passes in reverse order, so invert them + clearPassQueue(); + XSI::Shader shader(matEntry->xsiShader); + PassEntry* passEntry = new PassEntry(); + mPassQueue.push_front(passEntry); + while (1) + { + passEntry->shaders.Add(shader); + + XSI::CRef source = shader.GetParameter(L"previous").GetSource(); + if(!source.IsValid() || !source.IsA(XSI::siShaderID)) + { + // finish + break; + } + + shader = XSI::Shader(source); + // If we find a 'blending' parameter, we're on a new pass + if (shader.GetParameter(L"blending").IsValid()) + { + passEntry = new PassEntry(); + mPassQueue.push_front(passEntry); // push front to invert order + } + } + + + // Now go through each pass and create OGRE version + for (PassQueue::iterator p = mPassQueue.begin(); p != mPassQueue.end(); ++p) + { + PassEntry* passEntry = *p; + Pass* pass = t->createPass(); + LogOgreAndXSI("Added Pass"); + + // Need to pre-populate pass textures to match up transforms + populatePassTextures(pass, passEntry, copyTextures, texturePath); + // Do the rest + for (int s = 0; s < passEntry->shaders.GetCount(); ++s) + { + XSI::Shader shader(passEntry->shaders[s]); + populatePass(pass, shader); + } + + } + + + mMatSerializer.queueForExport(mat); + + + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::clearPassQueue(void) + { + for (PassQueue::iterator i = mPassQueue.begin(); i != mPassQueue.end(); ++i) + { + delete *i; + } + mPassQueue.clear(); + + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populatePass(Pass* pass, XSI::Shader& xsishader) + { + populatePassDepthCull(pass, xsishader); + populatePassSceneBlend(pass, xsishader); + populatePassLighting(pass, xsishader); + populatePassTextureTransforms(pass, xsishader); + populatePassCgPrograms(pass, xsishader); + populatePassHLSLPrograms(pass, xsishader); + populatePassD3DAssemblerPrograms(pass, xsishader); + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populatePassCgPrograms(Pass* pass, + XSI::Shader& xsishader) + { + XSI::Parameter param = xsishader.GetParameter(L"Cg_Program"); + if (param.IsValid()) + { + // TODO + // XSI can't reference external files which makes it v.difficult to + // re-use shaders - mod XSI plugin? + } + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populatePassHLSLPrograms(Pass* pass, + XSI::Shader& xsishader) + { + XSI::Parameter param = xsishader.GetParameter(L"HLSL_Program"); + if (param.IsValid()) + { + // TODO + // XSI can't reference external files which makes it v.difficult to + // re-use shaders - mod XSI plugin? + } + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populatePassD3DAssemblerPrograms(Pass* pass, + XSI::Shader& xsishader) + { + XSI::Parameter param = xsishader.GetParameter(L"Vertex_Shader"); + if (param.IsValid()) + { + // TODO + // XSI can't reference external files which makes it v.difficult to + // re-use shaders - mod XSI plugin? + } + param = xsishader.GetParameter(L"Pixel_Shader"); + if (param.IsValid()) + { + // TODO + // XSI can't reference external files which makes it v.difficult to + // re-use shaders - mod XSI plugin? + } + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populatePassDepthCull(Pass* pass, + XSI::Shader& xsishader) + { + XSI::Parameter param = xsishader.GetParameter(L"cullingmode"); + if (param.IsValid()) + { + short xsiCull = param.GetValue(); + switch (xsiCull) + { + case 0: + pass->setCullingMode(CULL_NONE); + pass->setManualCullingMode(MANUAL_CULL_NONE); + break; + case 1: + pass->setCullingMode(CULL_CLOCKWISE); + pass->setManualCullingMode(MANUAL_CULL_BACK); + break; + case 2: + pass->setCullingMode(CULL_ANTICLOCKWISE); + pass->setManualCullingMode(MANUAL_CULL_FRONT); + break; + + }; + } + + param = xsishader.GetParameter(L"depthtest"); + if (param.IsValid()) + { + bool depthTest = param.GetValue(); + pass->setDepthCheckEnabled(depthTest); + } + param = xsishader.GetParameter(L"depthwrite"); + if (param.IsValid()) + { + bool depthWrite = param.GetValue(); + pass->setDepthWriteEnabled(depthWrite); + } + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populatePassSceneBlend(Pass* pass, + XSI::Shader& xsishader) + { + XSI::Parameter param = xsishader.GetParameter(L"blending"); + if (param.IsValid() && (bool)param.GetValue()) + { + SceneBlendFactor src = SBF_ONE; + SceneBlendFactor dst = SBF_ONE; + + param = xsishader.GetParameter(L"srcblendingfunction"); + if (param.IsValid()) + { + src = convertSceneBlend(param.GetValue()); + } + param = xsishader.GetParameter(L"dstblendingfunction"); + if (param.IsValid()) + { + dst = convertSceneBlend(param.GetValue()); + } + + pass->setSceneBlending(src, dst); + } + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populatePassLighting(Pass* pass, + XSI::Shader& xsishader) + { + XSI::Parameter param = xsishader.GetParameter(L"Enable_Lighting"); + if (param.IsValid()) + { + pass->setLightingEnabled(param.GetValue()); + + ColourValue tmpColour; + xsishader.GetColorParameterValue(L"Ambient", tmpColour.r, tmpColour.g, + tmpColour.b, tmpColour.a); + pass->setAmbient(tmpColour); + xsishader.GetColorParameterValue(L"Diffuse", tmpColour.r, tmpColour.g, + tmpColour.b, tmpColour.a); + pass->setDiffuse(tmpColour); + xsishader.GetColorParameterValue(L"Emissive", tmpColour.r, tmpColour.g, + tmpColour.b, tmpColour.a); + pass->setSelfIllumination(tmpColour); + xsishader.GetColorParameterValue(L"Specular", tmpColour.r, tmpColour.g, + tmpColour.b, tmpColour.a); + pass->setSpecular(tmpColour); + + pass->setShininess(xsishader.GetParameter(L"Shininess").GetValue()); + } + + + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populatePassTextures(Pass* pass, + PassEntry* passEntry, bool copyTextures, const String& targetFolder) + { + // We need to search all shaders back to the point we would change + // passes, and add all the textures. This is because we don't know + // where in the shaders the texture transforms might be, since they + // are linked via 'target' not by being on the same object. + mTextureUnitTargetMap.clear(); + + for (int s = 0; s < passEntry->shaders.GetCount(); ++s) + { + XSI::Shader shader(passEntry->shaders[s]); + TextureUnitState* tex = 0; + + String progID = XSItoOgre(shader.GetProgID()); + if (progID.find("OGL13Texture") != String::npos || + progID.find("DXTexture") != String::npos || + progID.find("OGLCom") != String::npos) + { + if (!shader.GetParameter(L"bottom").IsValid()) + { + tex = add2DTexture(pass, shader, copyTextures, targetFolder); + } + else if (shader.GetParameter(L"bottom").IsValid()) + { + tex = addCubicTexture(pass, shader, copyTextures, targetFolder); + } + } + else + { + continue; // not a texture so skip the rest + } + + + // texture coordinate set + XSI::Parameter param = shader.GetParameter(L"tspace_id"); + if (param.IsValid()) + { + // this is a name, need to look up index + tex->setTextureCoordSet( + getTextureCoordIndex(XSItoOgre(XSI::CString(param.GetValue())))); + } + + // filtering & anisotropy + // DX and GL shaders deal differently + if (progID.find("OGL") != String::npos) + { + populateOGLFiltering(tex, shader); + } + else if (progID.find("DX") != String::npos) + { + populateDXFiltering(tex, shader); + } + + // colour operation + param = shader.GetParameter(L"modulation"); + if (param.IsValid()) + { + long colourop = ((LONG)param.GetValue()); + switch (colourop) + { + case 0: + // modulate + tex->setColourOperation(LBO_MODULATE); + break; + case 1: + // decal + tex->setColourOperation(LBO_ALPHA_BLEND); + break; + case 2: + // blend + tex->setColourOperation(LBO_MODULATE); + break; + case 3: + // replace + tex->setColourOperation(LBO_REPLACE); + break; + case 4: + // add + tex->setColourOperation(LBO_ADD); + break; + } + + } + + + + } + } + //------------------------------------------------------------------------- + TextureUnitState* XsiMaterialExporter::add2DTexture(Pass* pass, XSI::Shader& shader, + bool copyTextures, const String& targetFolder) + { + // create texture unit state and map from target incase future xforms + TextureUnitState* tex = pass->createTextureUnitState(); + + XSI::Parameter param = shader.GetParameter(L"target"); // OGL + if (!param.IsValid()) + param = shader.GetParameter(L"Texture_Target"); // DX + + long target = ((LONG)param.GetValue()); + mTextureUnitTargetMap.insert( + TextureUnitTargetMap::value_type(target, tex)); + + // Get image + XSI::CRef src = shader.GetParameter(L"Texture").GetSource(); + if (!src.IsValid() || !src.IsA(XSI::siImageClipID)) + { + // Try Texture_1 (OGL Combined) + src = shader.GetParameter(L"Texture_1").GetSource(); + + } + if (src.IsValid() && src.IsA(XSI::siImageClipID)) + { + XSI::ImageClip imgClip(src); + String srcTextureName = + XSItoOgre(XSI::CString(imgClip.GetParameter(L"SourceFileName").GetValue())); + + String::size_type pos = srcTextureName.find_last_of("\\"); + if (pos == String::npos) + { + pos = srcTextureName.find_last_of("/"); + } + String textureName = + srcTextureName.substr(pos+1, srcTextureName.size() - pos - 1); + String destTextureName = targetFolder + textureName; + + // copy texture if required + if (copyTextures) + { + copyFile(srcTextureName, destTextureName); + } + + LogOgreAndXSI("Adding texture " + textureName); + tex->setTextureName(textureName); + + } + + return tex; + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populateOGLFiltering(TextureUnitState* tex, + XSI::Shader& shader) + { + FilterOptions minFilter, mipFilter, magFilter; + minFilter = FO_LINEAR; + magFilter = FO_LINEAR; + mipFilter = FO_POINT; + XSI::Parameter param = shader.GetParameter(L"minfilter"); + if (param.IsValid()) + { + // XSI OGL shader uses minfilter to determine mip too + long filt = ((LONG)param.GetValue()); + switch(filt) + { + case 0: + minFilter = FO_POINT; + mipFilter = FO_NONE; + break; + case 1: + minFilter = FO_LINEAR; + mipFilter = FO_NONE; + break; + case 2: + minFilter = FO_POINT; + mipFilter = FO_POINT; + break; + case 3: + minFilter = FO_POINT; + mipFilter = FO_LINEAR; + break; + case 4: + minFilter = FO_LINEAR; + mipFilter = FO_POINT; + break; + case 5: + minFilter = FO_LINEAR; + mipFilter = FO_LINEAR; + break; + }; + + } + param = shader.GetParameter(L"magfilter"); + if (param.IsValid()) + { + long filt = ((LONG)param.GetValue()); + switch(filt) + { + case 0: + magFilter = FO_POINT; + break; + case 1: + magFilter = FO_LINEAR; + break; + }; + } + + param = shader.GetParameter(L"anisotropy"); + if (param.IsValid()) + { + long aniso = ((LONG)param.GetValue()); + if (aniso > 1) + { + // No specific aniso filtering option, so upgrade linear -> aniso + if (minFilter == FO_LINEAR) + minFilter = FO_ANISOTROPIC; + if (magFilter == FO_LINEAR) + magFilter = FO_ANISOTROPIC; + } + tex->setTextureAnisotropy(aniso); + } + + tex->setTextureFiltering(minFilter, magFilter, mipFilter); + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populateDXFiltering(TextureUnitState* tex, + XSI::Shader& shader) + { + FilterOptions minFilter, mipFilter, magFilter; + minFilter = FO_LINEAR; + magFilter = FO_LINEAR; + mipFilter = FO_POINT; + XSI::Parameter param = shader.GetParameter(L"minfilter"); + if (param.IsValid()) + { + // XSI DX shader has min/mag and mip, and has more options + long filt = ((LONG)param.GetValue()); + switch(filt) + { + case 0: + minFilter = FO_NONE; + break; + case 1: + minFilter = FO_POINT; + break; + case 2: + minFilter = FO_LINEAR; + break; + case 3: + case 4: // we don't support cubic/gaussian, use aniso + case 5: + minFilter = FO_ANISOTROPIC; + break; + }; + } + param = shader.GetParameter(L"magfilter"); + if (param.IsValid()) + { + // XSI DX shader has mag/mag and mip, and has more options + long filt = ((LONG)param.GetValue()); + switch(filt) + { + case 0: + magFilter = FO_NONE; + break; + case 1: + magFilter = FO_POINT; + break; + case 2: + magFilter = FO_LINEAR; + break; + case 3: + case 4: // we don't support cubic/gaussian, use aniso + case 5: + magFilter = FO_ANISOTROPIC; + break; + }; + } + param = shader.GetParameter(L"mipfilter"); + if (param.IsValid()) + { + // XSI DX shader has mip/mag and mip, and has more options + long filt = ((LONG)param.GetValue()); + switch(filt) + { + case 0: + mipFilter = FO_NONE; + break; + case 1: + mipFilter = FO_POINT; + break; + case 2: + mipFilter = FO_LINEAR; + break; + case 3: + case 4: // we don't support cubic/gaussian, use aniso + case 5: + mipFilter = FO_ANISOTROPIC; + break; + }; + } + // Aniso + param = shader.GetParameter(L"anisotropy"); + if (param.IsValid()) + { + long aniso = ((LONG)param.GetValue()); + tex->setTextureAnisotropy(aniso); + } + + tex->setTextureFiltering(minFilter, magFilter, mipFilter); + } + //------------------------------------------------------------------------- + TextureUnitState* XsiMaterialExporter::addCubicTexture(Pass* pass, XSI::Shader& shader, + bool copyTextures, const String& targetFolder) + { + // create texture unit state and map from target incase future xforms + TextureUnitState* tex = pass->createTextureUnitState(); + + XSI::Parameter param = shader.GetParameter(L"target"); // OGL + if (!param.IsValid()) + param = shader.GetParameter(L"Texture_Target"); // DX + + long target = ((LONG)param.GetValue()); + mTextureUnitTargetMap.insert( + TextureUnitTargetMap::value_type(target, tex)); + + // Get images + wchar_t* cubeFaceName[6] = { + L"front", L"back", L"top", L"bottom", L"left", L"right" }; + + String finalNames[6]; + + + for (int face = 0; face < 6; ++face) + { + XSI::CRef src = shader.GetParameter(cubeFaceName[face]).GetSource(); + if (src.IsValid() && src.IsA(XSI::siImageClipID)) + { + XSI::ImageClip imgClip(src); + String srcTextureName = + XSItoOgre(XSI::CString(imgClip.GetParameter(L"SourceFileName").GetValue())); + + String::size_type pos = srcTextureName.find_last_of("\\"); + if (pos == String::npos) + { + pos = srcTextureName.find_last_of("/"); + } + finalNames[face] = + srcTextureName.substr(pos+1, srcTextureName.size() - pos - 1); + String destTextureName = targetFolder + finalNames[face]; + + // copy texture if required + if (copyTextures) + { + copyFile(srcTextureName, destTextureName); + } + + + LogOgreAndXSI("Cubemap face: " + srcTextureName); + } + } + + LogOgreAndXSI("Adding cubic texture"); + // Cannot do combinedUVW for now, DevIL can't write DDS cubemap so + // go for separates (user can modify) + tex->setCubicTextureName(finalNames, false); + + return tex; + + } + //------------------------------------------------------------------------- + unsigned short XsiMaterialExporter::getTextureCoordIndex(const String& tspace) + { + TextureProjectionMap::iterator i = mTextureProjectionMap.find(tspace); + if (i != mTextureProjectionMap.end()) + { + return i->second; + } + else + { + // default + return 0; + } + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::populatePassTextureTransforms(Pass* pass, + XSI::Shader& shader) + { + // TODO + // Check we have the right object + XSI::Parameter param = shader.GetParameter(L"wrap_u"); + if (param.IsValid()) + { + + // addressing mode + TextureUnitState::UVWAddressingMode uvwadd; + uvwadd.u = convertAddressingMode(param.GetValue()); + // default other dimensions incase not supplied + uvwadd.v = uvwadd.u; + uvwadd.w = uvwadd.u; + + param = shader.GetParameter(L"wrap_v"); + if (param.IsValid()) + { + uvwadd.v = convertAddressingMode(param.GetValue()); + } + param = shader.GetParameter(L"wrap_w"); + if (param.IsValid()) + { + uvwadd.w = convertAddressingMode(param.GetValue()); + } + + // transform + bool usexform = false; + Matrix4 xform = Matrix4::IDENTITY; + param = shader.GetParameter(L"Transform"); + if (param.IsValid() && (bool)param.GetValue()) + { + Quaternion qx, qy, qz, qfinal; + qx.FromAngleAxis(Degree(shader.GetParameter(L"rotx").GetValue()), + Vector3::UNIT_X); + qy.FromAngleAxis(Degree(shader.GetParameter(L"roty").GetValue()), + Vector3::UNIT_Y); + qz.FromAngleAxis(Degree(shader.GetParameter(L"rotz").GetValue()), + Vector3::UNIT_Z); + qfinal = qx * qy * qz; + + Vector3 trans; + trans.x = shader.GetParameter(L"trsx").GetValue(); + trans.y = shader.GetParameter(L"trsy").GetValue(); + trans.z = shader.GetParameter(L"trsz").GetValue(); + + Matrix3 rot3x3, scale3x3; + qfinal.ToRotationMatrix(rot3x3); + scale3x3 = Matrix3::ZERO; + scale3x3[0][0] = shader.GetParameter(L"sclx").GetValue(); + scale3x3[1][1] = shader.GetParameter(L"scly").GetValue(); + scale3x3[2][2] = shader.GetParameter(L"sclz").GetValue(); + + xform = rot3x3 * scale3x3; + xform.setTrans(trans); + usexform = true; + + } + + + // Look up texture unit(s) that are using this target + long target = ((LONG)shader.GetParameter(L"Texture_Target").GetValue()); + TextureUnitTargetMap::iterator i = mTextureUnitTargetMap.find(target); + while (i != mTextureUnitTargetMap.end() && i->first == target) + { + TextureUnitState* tex = i->second; + tex->setTextureAddressingMode(uvwadd); + if (usexform) + tex->setTextureTransform(xform); + + // texgen (not texcoord_index as in OGRE!) + // Can turn into 2 different calls + param = shader.GetParameter(L"texcoord_index"); + if (param.IsValid()) + { + long e = ((LONG)param.GetValue()); + if (e != 0) + { + // Not Explicit + // details differ per DX/OGL + if (XSItoOgre(shader.GetProgID()).find("DX") != String::npos) + { + convertTexGenDX(tex, e, shader); + } + else + { + convertTexGenOGL(tex, e, shader); + } + + } + + } + ++i; + } + + + + + } + param = shader.GetParameter(L"Additive_Transform"); + if (param.IsValid()) + { + unsigned short target = shader.GetParameter(L"Texture_Coord_ID").GetValue(); + if (pass->getNumTextureUnitStates() > target) + { + TextureUnitState* tex = pass->getTextureUnitState(target); + + long uvType = ((LONG)shader.GetParameter(L"UV_Type").GetValue()); + if (uvType != 0) + { + double val1 = shader.GetParameter(L"Val1").GetValue(); + double val2 = shader.GetParameter(L"Val2").GetValue(); + long wave = ((LONG)shader.GetParameter(L"Wave").GetValue()); + WaveformType wft; + switch (wave) + { + case 1: + wft = WFT_SINE; + break; + case 2: + wft = WFT_TRIANGLE; + break; + case 3: + wft = WFT_SQUARE; + break; + case 4: + wft = WFT_SAWTOOTH; + break; + case 5: + wft = WFT_INVERSE_SAWTOOTH; + break; + } + double base = shader.GetParameter(L"Base").GetValue(); + double amp = shader.GetParameter(L"Amplitude").GetValue(); + double phase = shader.GetParameter(L"Phase").GetValue(); + double freq = shader.GetParameter(L"Frequency").GetValue(); + + switch(uvType) + { + case 1: + // translate + tex->setTextureScroll(val1, val2); + break; + case 2: + // rotate + tex->setTextureRotate(Degree(val1)); + break; + case 3: + // scale + tex->setTextureScale(val1, val2); + break; + case 4: + // scroll + if (wave != 0) + { + tex->setTransformAnimation(TextureUnitState::TT_TRANSLATE_U, + wft, base, freq, phase, amp); + tex->setTransformAnimation(TextureUnitState::TT_TRANSLATE_V, + wft, base, freq, phase, amp); + } + else + { + tex->setScrollAnimation(val1, val2); + } + break; + case 5: + // turn + if (wave != 0) + { + tex->setTransformAnimation(TextureUnitState::TT_ROTATE, + wft, base, freq, phase, amp); + } + else + { + tex->setRotateAnimation(val1 / 360.0f); + } + break; + case 6: + // stretch (only wave) + if (wave != 0) + { + tex->setTransformAnimation(TextureUnitState::TT_SCALE_U, + wft, base, freq, phase, amp); + tex->setTransformAnimation(TextureUnitState::TT_SCALE_V, + wft, base, freq, phase, amp); + } + break; + + } + } + } + + } + + // if more than one entry for the same target is found, it is ok for the + // latter to take precedence since this is what happens in XSI. + + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::convertTexGenOGL(TextureUnitState* tex, + long xsiVal, XSI::Shader& shader) + { + switch(xsiVal) + { + // no 0 + case 1: + // Object linear + tex->setEnvironmentMap(true, TextureUnitState::ENV_PLANAR); + break; + case 2: + // Eye linear (texture projection) + tex->setProjectiveTexturing(true); + break; + case 3: + // Sphere map + tex->setEnvironmentMap(true, TextureUnitState::ENV_CURVED); + break; + case 4: + // Reflection map + tex->setEnvironmentMap(true, TextureUnitState::ENV_REFLECTION); + break; + case 5: + // Normal map + tex->setEnvironmentMap(true, TextureUnitState::ENV_NORMAL); + break; + + }; + } + //------------------------------------------------------------------------- + void XsiMaterialExporter::convertTexGenDX(TextureUnitState* tex, + long xsiVal, XSI::Shader& shader) + { + switch(xsiVal) + { + // no 0 + case 1: + // Normal in camera space + tex->setEnvironmentMap(true, TextureUnitState::ENV_CURVED); + break; + case 2: + // Position in camera space + tex->setEnvironmentMap(true, TextureUnitState::ENV_PLANAR); + break; + case 3: + // Reflection vector in camera space + tex->setEnvironmentMap(true, TextureUnitState::ENV_REFLECTION); + break; + + }; + } + //------------------------------------------------------------------------- + TextureUnitState::TextureAddressingMode + XsiMaterialExporter::convertAddressingMode(short xsiVal) + { + // same for OGL and DX + switch(xsiVal) + { + case 0: + return TextureUnitState::TAM_WRAP; + case 1: + return TextureUnitState::TAM_MIRROR; + case 2: + return TextureUnitState::TAM_CLAMP; + case 3: + // border? + return TextureUnitState::TAM_CLAMP; + case 4: + // mirror once + return TextureUnitState::TAM_MIRROR; + case 5: + // clamp to edge + return TextureUnitState::TAM_CLAMP; + + }; + + // Keep compiler happy + return TextureUnitState::TAM_WRAP; + } + //------------------------------------------------------------------------- + SceneBlendFactor XsiMaterialExporter::convertSceneBlend(short xsiVal) + { + switch(xsiVal) + { + case 0: + return SBF_ZERO; + case 1: + return SBF_ONE; + case 2: + return SBF_DEST_COLOUR; + case 3: + return SBF_ONE_MINUS_DEST_COLOUR; + case 4: + return SBF_SOURCE_ALPHA; + case 5: + return SBF_ONE_MINUS_SOURCE_ALPHA; + case 6: + return SBF_DEST_ALPHA; + case 7: + return SBF_ONE_MINUS_DEST_ALPHA; + }; + + return SBF_ZERO; + + } } diff --git a/Tools/XSIExport/src/OgreXSIMeshExporter.cpp b/Tools/XSIExport/src/OgreXSIMeshExporter.cpp index 32af3616c85..02ac767044c 100644 --- a/Tools/XSIExport/src/OgreXSIMeshExporter.cpp +++ b/Tools/XSIExport/src/OgreXSIMeshExporter.cpp @@ -99,64 +99,64 @@ namespace Ogre { //----------------------------------------------------------------------- XsiMeshExporter::~XsiMeshExporter() { - /// Tidy up - cleanupDeformerMap(); - cleanupMaterialMap(); + /// Tidy up + cleanupDeformerMap(); + cleanupMaterialMap(); } //----------------------------------------------------------------------- - DeformerMap& XsiMeshExporter::buildMeshForExport( - bool mergeSubMeshes, bool exportChildren, - bool edgeLists, bool tangents, VertexElementSemantic tangentSemantic, - bool tangentsSplitMirrored, bool tangentsSplitRotated, bool tangentsUseParity, - bool vertexAnimation, AnimationList& animList, Real fps, const String& materialPrefix, - LodData* lod, const String& skeletonName) + DeformerMap& XsiMeshExporter::buildMeshForExport( + bool mergeSubMeshes, bool exportChildren, + bool edgeLists, bool tangents, VertexElementSemantic tangentSemantic, + bool tangentsSplitMirrored, bool tangentsSplitRotated, bool tangentsUseParity, + bool vertexAnimation, AnimationList& animList, Real fps, const String& materialPrefix, + LodData* lod, const String& skeletonName) { - LogOgreAndXSI(L"** Begin OGRE Mesh Export **"); + LogOgreAndXSI(L"** Begin OGRE Mesh Export **"); // Derive the scene root X3DObject sceneRoot(mXsiApp.GetActiveSceneRoot()); // Construct mesh mMesh = MeshManager::getSingleton().createManual("XSIExport", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - mMaterialPrefix = materialPrefix; + mMaterialPrefix = materialPrefix; - cleanupDeformerMap(); - cleanupMaterialMap(); - mShapeKeyMapping.clear(); + cleanupDeformerMap(); + cleanupMaterialMap(); + mShapeKeyMapping.clear(); - // Find all PolygonMesh objects - buildPolygonMeshList(exportChildren); - // progress report - ProgressManager::getSingleton().progress(); + // Find all PolygonMesh objects + buildPolygonMeshList(exportChildren); + // progress report + ProgressManager::getSingleton().progress(); - // notify of skeleton beforehand - if (!skeletonName.empty()) - { - mMesh->setSkeletonName(skeletonName); - } + // notify of skeleton beforehand + if (!skeletonName.empty()) + { + mMesh->setSkeletonName(skeletonName); + } - // write the data into a mesh - buildMesh(mMesh.getPointer(), mergeSubMeshes, !skeletonName.empty(), - vertexAnimation, animList, fps); + // write the data into a mesh + buildMesh(mMesh.getPointer(), mergeSubMeshes, !skeletonName.empty(), + vertexAnimation, animList, fps); - // progress report - ProgressManager::getSingleton().progress(); + // progress report + ProgressManager::getSingleton().progress(); - if (lod) - { - ProgressiveMesh::generateLodLevels(mMesh.get(), lod->distances, lod->quota, lod->reductionValue); - // progress report - ProgressManager::getSingleton().progress(); - } + if (lod) + { + ProgressiveMesh::generateLodLevels(mMesh.get(), lod->distances, lod->quota, lod->reductionValue); + // progress report + ProgressManager::getSingleton().progress(); + } if(edgeLists) { LogOgreAndXSI(L"Calculating edge lists"); mMesh->buildEdgeList(); - // progress report - ProgressManager::getSingleton().progress(); + // progress report + ProgressManager::getSingleton().progress(); } if(tangents) @@ -166,951 +166,951 @@ namespace Ogre { if (!mMesh->suggestTangentVectorBuildParams(tangentSemantic, src, dest)) { mMesh->buildTangentVectors(tangentSemantic, src, dest, tangentsSplitMirrored, - tangentsSplitRotated, tangentsUseParity); + tangentsSplitRotated, tangentsUseParity); } else { LogOgreAndXSI(L"Could not derive tangents parameters"); } - // progress report - ProgressManager::getSingleton().progress(); + // progress report + ProgressManager::getSingleton().progress(); } - cleanupPolygonMeshList(); + cleanupPolygonMeshList(); + + LogOgreAndXSI(L"** OGRE Mesh Export Complete **"); + + return mXsiDeformerMap; + } + //----------------------------------------------------------------------- + void XsiMeshExporter::exportMesh(const String& fileName, const AxisAlignedBox& skelAABB) + { + + // Pad bounds + AxisAlignedBox currBounds = mMesh->getBounds(); + currBounds.merge(skelAABB); + mMesh->_setBounds(currBounds, false); + + MeshSerializer serializer; + serializer.exportMesh(mMesh.getPointer(), fileName); + + // progress report + ProgressManager::getSingleton().progress(); + + mMesh.setNull(); + + + } + //----------------------------------------------------------------------- + MaterialMap& XsiMeshExporter::getMaterials(void) + { + return mXsiMaterialMap; + } + //----------------------------------------------------------------------- + TextureProjectionMap& XsiMeshExporter::getTextureProjectionMap(void) + { + return mTextureProjectionMap; + } + //----------------------------------------------------------------------- + void XsiMeshExporter::buildMesh(Mesh* pMesh, bool mergeSubmeshes, + bool lookForBoneAssignments, bool vertexAnimation, AnimationList& animList, + Real fps) + { + /* Iterate over the list of polygon meshes that we've already located. + For each one: + If we're not merging submeshes, bake any protosubmeshes built + into the mesh and clear the protosubmesh list + Scan the clusters for 'poly' clusters (which can contain material + discrepancies). Any that use a different material should be + noted in the polycluster list + Build ProtoSubMeshes by iterating over the triangles in the mesh, + building the list of UniqueVertices against the material as we + go. We check each triangle to see if the polygon index is in + the list of polyclusters & if so it goes into the other lists + + Finally, we bake any remaining protosubmeshes into submeshes. + */ + // Calculate the number of progress updates each mesh must raise + float progPerMesh = (float)OGRE_XSI_NUM_MESH_STEPS / (float)(mXsiPolygonMeshList.size()); + float currProg = 0.0f; + for (PolygonMeshList::iterator pm = mXsiPolygonMeshList.begin(); + pm != mXsiPolygonMeshList.end(); ++pm) + { + currProg += progPerMesh; + unsigned short progUpdates = (unsigned short)currProg; + currProg -= progUpdates; + // build contents of this polymesh into ProtoSubMesh(es) + processPolygonMesh(pMesh, *pm, lookForBoneAssignments, progUpdates); - LogOgreAndXSI(L"** OGRE Mesh Export Complete **"); + if (!mergeSubmeshes) + { + // export out at the end of every PolygonMesh + exportProtoSubMeshes(pMesh); + } + } + if (mergeSubmeshes) + { + // export out the combined result + exportProtoSubMeshes(pMesh); + } - return mXsiDeformerMap; + if (vertexAnimation) + { + exportAnimations(pMesh, animList, fps); + } } - //----------------------------------------------------------------------- - void XsiMeshExporter::exportMesh(const String& fileName, const AxisAlignedBox& skelAABB) - { - - // Pad bounds - AxisAlignedBox currBounds = mMesh->getBounds(); - currBounds.merge(skelAABB); - mMesh->_setBounds(currBounds, false); - - MeshSerializer serializer; - serializer.exportMesh(mMesh.getPointer(), fileName); - - // progress report - ProgressManager::getSingleton().progress(); - - mMesh.setNull(); - - - } - //----------------------------------------------------------------------- - MaterialMap& XsiMeshExporter::getMaterials(void) - { - return mXsiMaterialMap; - } - //----------------------------------------------------------------------- - TextureProjectionMap& XsiMeshExporter::getTextureProjectionMap(void) - { - return mTextureProjectionMap; - } - //----------------------------------------------------------------------- - void XsiMeshExporter::buildMesh(Mesh* pMesh, bool mergeSubmeshes, - bool lookForBoneAssignments, bool vertexAnimation, AnimationList& animList, - Real fps) - { - /* Iterate over the list of polygon meshes that we've already located. - For each one: - If we're not merging submeshes, bake any protosubmeshes built - into the mesh and clear the protosubmesh list - Scan the clusters for 'poly' clusters (which can contain material - discrepancies). Any that use a different material should be - noted in the polycluster list - Build ProtoSubMeshes by iterating over the triangles in the mesh, - building the list of UniqueVertices against the material as we - go. We check each triangle to see if the polygon index is in - the list of polyclusters & if so it goes into the other lists - - Finally, we bake any remaining protosubmeshes into submeshes. - */ - // Calculate the number of progress updates each mesh must raise - float progPerMesh = (float)OGRE_XSI_NUM_MESH_STEPS / (float)(mXsiPolygonMeshList.size()); - float currProg = 0.0f; - for (PolygonMeshList::iterator pm = mXsiPolygonMeshList.begin(); - pm != mXsiPolygonMeshList.end(); ++pm) - { - currProg += progPerMesh; - unsigned short progUpdates = (unsigned short)currProg; - currProg -= progUpdates; - // build contents of this polymesh into ProtoSubMesh(es) - processPolygonMesh(pMesh, *pm, lookForBoneAssignments, progUpdates); - - if (!mergeSubmeshes) - { - // export out at the end of every PolygonMesh - exportProtoSubMeshes(pMesh); - } - } - if (mergeSubmeshes) - { - // export out the combined result - exportProtoSubMeshes(pMesh); - } - - if (vertexAnimation) - { - exportAnimations(pMesh, animList, fps); - } - } - //----------------------------------------------------------------------- - XsiMeshExporter::ProtoSubMesh* XsiMeshExporter::createOrRetrieveProtoSubMesh( - const String& materialName, const String& name, - TextureCoordDimensionList& texCoordDims, bool hasVertexColours) - { - bool createNew = true; - ProtoSubMesh* ret = 0; - ProtoSubMeshList* protoList = 0; - - MaterialProtoSubMeshMap::iterator pi = mMaterialProtoSubmeshMap.find(materialName); - if (pi == mMaterialProtoSubmeshMap.end()) - { - protoList = new ProtoSubMeshList(); - mMaterialProtoSubmeshMap[materialName] = protoList; - } - else - { - // Iterate over the protos with the same material - protoList = pi->second; - - for (ProtoSubMeshList::iterator psi = protoList->begin(); psi != protoList->end(); ++psi) - { - ProtoSubMesh* candidate = *psi; - // Check format is compatible - if (candidate->textureCoordDimensions.size() != texCoordDims.size()) - { - continue; - } - if (candidate->hasVertexColours != hasVertexColours) - { - continue; - } - - bool compat = true; - std::vector::iterator t = texCoordDims.begin(); - std::vector::iterator u = candidate->textureCoordDimensions.begin(); - for (;t != texCoordDims.end(); ++t,++u) - { - if (*t != *u) - { - compat = false; - break; - } - } - - if (compat) - { - createNew = false; - ret = candidate; - break; - } - } - } - - if (createNew) - { - ret = new ProtoSubMesh(); - protoList->push_back(ret); - ret->materialName = materialName; - ret->name = name; - ret->textureCoordDimensions = texCoordDims; - ret->hasVertexColours = hasVertexColours; - } - - return ret; - - } - //----------------------------------------------------------------------- - void XsiMeshExporter::processPolygonMesh(Mesh* pMesh, PolygonMeshEntry* xsiMesh, - bool lookForBoneAssignments, unsigned short progressUpdates) - { - CRefArray uvs = xsiMesh->geometry.GetUVs(); - - StringStream msg; - msg << "-- " << XSItoOgre(xsiMesh->name) << " --" << std::endl; - msg << "Points: " << xsiMesh->geometry.GetVertexCount() << std::endl; - msg << "Triangles: " << xsiMesh->geometry.GetTriangleCount() << std::endl; - msg << "Normals: " << xsiMesh->geometry.GetNodeCount() << std::endl; - msg << "Num UVs: " << uvs.GetCount() << std::endl; - String str = msg.str(); - LogOgreAndXSI(str); - - if (uvs.GetCount() > OGRE_MAX_TEXTURE_COORD_SETS) - { - // too many texture coordinates! - StringStream str; - str << "PolygonMesh '" << XSItoOgre(xsiMesh->name) - << "' has too many texture coordinate sets (" - << uvs.GetCount() - << "); the limit is " << OGRE_MAX_TEXTURE_COORD_SETS; - - OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, str.str(), - "XsiMeshExporter::processPolygonMesh"); - } - - // Collect texture coordinates data - TextureCoordDimensionList textureCoordDimensions; - SamplerSetList samplerSets; - textureCoordDimensions.reserve(uvs.GetCount()); - samplerSets.reserve(uvs.GetCount()); - for (int i = 0; i < uvs.GetCount(); ++ i) - { - Vector3* samplerUVs = new Vector3[xsiMesh->geometry.GetNodeCount()]; - samplerSets.push_back(samplerUVs); - - ClusterProperty uvProp = uvs[i]; - CFloatArray uvValues; - uvProp.GetValues(uvValues); - - String textureProjectionName = XSItoOgre(uvProp.GetName()); - mTextureProjectionMap[textureProjectionName] = i; - - int usedDims = 0; - for (int j = 0; j < xsiMesh->geometry.GetNodeCount(); ++j) - { - if ((samplerUVs[j].x = uvValues[j * 3]) != 0) - usedDims |= 1; //u - if ((samplerUVs[j].y = 1.0f - uvValues[j * 3 + 1]) != 0) - usedDims |= 2; //v (invert) - if ((samplerUVs[j].z = uvValues[j * 3 + 2]) != 0) - usedDims |= 4; //w - } - - if (usedDims & 4) // w - textureCoordDimensions.push_back(3); - else if (usedDims & 2) // v - textureCoordDimensions.push_back(2); - else // u - textureCoordDimensions.push_back(1); - } - - - // Save transforms - MATH::CTransformation xsiTransform = xsiMesh->transform; - MATH::CTransformation rotTrans; - rotTrans.SetRotation(xsiTransform.GetRotation()); - - // Bounds calculation - Real squaredRadius = 0.0f; - Vector3 min, max; - bool first = true; - - UniqueVertex vertex; - - - float progPerTri = (float)progressUpdates / xsiMesh->geometry.GetTriangleCount(); - float prog = 0.0f; - - CLongArray polygonTriangleIndices; - xsiMesh->geometry.GetPolygonTriangleIndices(polygonTriangleIndices); - - CLongArray triangleVertexIndices; - xsiMesh->geometry.GetTriangleVertexIndices(triangleVertexIndices); - - CDoubleArray vertexPositions; - xsiMesh->geometry.GetVertexPositions(vertexPositions); - - CRefArray vertexColours = xsiMesh->geometry.GetVertexColors(); - bool hasVertexColours = vertexColours.GetCount() > 0? true : false; - CFloatArray vertexColoursValues; - if (hasVertexColours) - { - ClusterProperty c = vertexColours[0]; - c.GetValues(vertexColoursValues); - } - - CFloatArray nodeNormals; - xsiMesh->geometry.GetNodeNormals(nodeNormals); - - CLongArray triangleNodeIndices; - xsiMesh->geometry.GetTriangleNodeIndices(triangleNodeIndices); - - CLongArray polygonMaterialIndices; - xsiMesh->geometry.GetPolygonMaterialIndices(polygonMaterialIndices); - - CRefArray materials = xsiMesh->geometry.GetMaterials(); - - ProtoSubMesh** materialToProtoSubMesh = new ProtoSubMesh*[materials.GetCount()]; - for (LONG i = 0; i < materials.GetCount(); ++ i) - materialToProtoSubMesh[i] = 0; - - CRefArray polygonClusters = xsiMesh->geometry.GetClusters(siClusterPolygonType); - - // Test for hidden polygons - XSI::CBitArray hiddenPolygons(xsiMesh->geometry.GetPolygonCount()); - for (LONG c = 0; c < polygonClusters.GetCount(); ++ c) - { - XSI::Cluster cluster = XSI::Cluster(polygonClusters[c]); - XSI::CRef clsvisibility; - - if (cluster.GetProperties().Find(L"clsvisibility", clsvisibility) == CStatus::OK) - { - Property p(clsvisibility); - if (!p.GetParameterValue(L"viewvis")) - { - XSI::CBitArray clusterPolys; - cluster.GetGeometryElementFlags(clusterPolys); - hiddenPolygons.Or(clusterPolys); - } - } - } - - // Iterate through all the triangles - for (long t = 0; t < xsiMesh->geometry.GetTriangleCount(); ++t) - { - // Skip the triangle if it relates to a hidden polygon - if (hiddenPolygons[polygonTriangleIndices[t]]) - continue; - - LONG polygonIndex = polygonTriangleIndices[t]; - LONG materialIndex = polygonMaterialIndices[polygonIndex]; - ProtoSubMesh* currentProto = materialToProtoSubMesh[materialIndex]; - - // Do we already have a protosubmesh for the material of this triangle? - if (!currentProto) - { - CString SubMeshName = xsiMesh->name; - - XSI::Material m(materials[materialIndex]); - - // Use the name of the cluster as the submesh name - for (LONG c = 0; c < polygonClusters.GetCount(); ++ c) - { - XSI::Cluster cluster = XSI::Cluster(polygonClusters[c]); - if (cluster.GetMaterial().GetName() == m.GetName()) - { - LONG out_clusterIndex; - cluster.FindIndex(polygonIndex, out_clusterIndex); - if (out_clusterIndex != -1) - { - SubMeshName = cluster.GetName(); - break; - } - } - } - - currentProto = materialToProtoSubMesh[materialIndex] = createOrRetrieveProtoSubMesh( - mMaterialPrefix + XSItoOgre(m.GetName()), - XSItoOgre(SubMeshName), - textureCoordDimensions, - hasVertexColours); - } - - // has this mesh been used in this proto before? if not set offset - size_t positionIndexOffset; - if (currentProto->lastMeshEntry == xsiMesh) - { - positionIndexOffset = currentProto->lastMeshIndexOffset; - } - else - { - // first time this has been used - // since we assume we 100% process each polygon mesh before the next, - // just use last pointer since faster in this section - currentProto->lastMeshEntry = xsiMesh; - positionIndexOffset = currentProto->indices.size(); - currentProto->lastMeshIndexOffset = positionIndexOffset; - // Also have to store this for future reference - currentProto->polygonMeshOffsetMap[xsiMesh] = positionIndexOffset; - } - + //----------------------------------------------------------------------- + XsiMeshExporter::ProtoSubMesh* XsiMeshExporter::createOrRetrieveProtoSubMesh( + const String& materialName, const String& name, + TextureCoordDimensionList& texCoordDims, bool hasVertexColours) + { + bool createNew = true; + ProtoSubMesh* ret = 0; + ProtoSubMeshList* protoList = 0; + + MaterialProtoSubMeshMap::iterator pi = mMaterialProtoSubmeshMap.find(materialName); + if (pi == mMaterialProtoSubmeshMap.end()) + { + protoList = new ProtoSubMeshList(); + mMaterialProtoSubmeshMap[materialName] = protoList; + } + else + { + // Iterate over the protos with the same material + protoList = pi->second; + + for (ProtoSubMeshList::iterator psi = protoList->begin(); psi != protoList->end(); ++psi) + { + ProtoSubMesh* candidate = *psi; + // Check format is compatible + if (candidate->textureCoordDimensions.size() != texCoordDims.size()) + { + continue; + } + if (candidate->hasVertexColours != hasVertexColours) + { + continue; + } + + bool compat = true; + std::vector::iterator t = texCoordDims.begin(); + std::vector::iterator u = candidate->textureCoordDimensions.begin(); + for (;t != texCoordDims.end(); ++t,++u) + { + if (*t != *u) + { + compat = false; + break; + } + } + + if (compat) + { + createNew = false; + ret = candidate; + break; + } + } + } + + if (createNew) + { + ret = new ProtoSubMesh(); + protoList->push_back(ret); + ret->materialName = materialName; + ret->name = name; + ret->textureCoordDimensions = texCoordDims; + ret->hasVertexColours = hasVertexColours; + } + + return ret; + + } + //----------------------------------------------------------------------- + void XsiMeshExporter::processPolygonMesh(Mesh* pMesh, PolygonMeshEntry* xsiMesh, + bool lookForBoneAssignments, unsigned short progressUpdates) + { + CRefArray uvs = xsiMesh->geometry.GetUVs(); + + StringStream msg; + msg << "-- " << XSItoOgre(xsiMesh->name) << " --" << std::endl; + msg << "Points: " << xsiMesh->geometry.GetVertexCount() << std::endl; + msg << "Triangles: " << xsiMesh->geometry.GetTriangleCount() << std::endl; + msg << "Normals: " << xsiMesh->geometry.GetNodeCount() << std::endl; + msg << "Num UVs: " << uvs.GetCount() << std::endl; + String str = msg.str(); + LogOgreAndXSI(str); + + if (uvs.GetCount() > OGRE_MAX_TEXTURE_COORD_SETS) + { + // too many texture coordinates! + StringStream str; + str << "PolygonMesh '" << XSItoOgre(xsiMesh->name) + << "' has too many texture coordinate sets (" + << uvs.GetCount() + << "); the limit is " << OGRE_MAX_TEXTURE_COORD_SETS; + + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, str.str(), + "XsiMeshExporter::processPolygonMesh"); + } + + // Collect texture coordinates data + TextureCoordDimensionList textureCoordDimensions; + SamplerSetList samplerSets; + textureCoordDimensions.reserve(uvs.GetCount()); + samplerSets.reserve(uvs.GetCount()); + for (int i = 0; i < uvs.GetCount(); ++ i) + { + Vector3* samplerUVs = new Vector3[xsiMesh->geometry.GetNodeCount()]; + samplerSets.push_back(samplerUVs); + + ClusterProperty uvProp = uvs[i]; + CFloatArray uvValues; + uvProp.GetValues(uvValues); + + String textureProjectionName = XSItoOgre(uvProp.GetName()); + mTextureProjectionMap[textureProjectionName] = i; + + int usedDims = 0; + for (int j = 0; j < xsiMesh->geometry.GetNodeCount(); ++j) + { + if ((samplerUVs[j].x = uvValues[j * 3]) != 0) + usedDims |= 1; //u + if ((samplerUVs[j].y = 1.0f - uvValues[j * 3 + 1]) != 0) + usedDims |= 2; //v (invert) + if ((samplerUVs[j].z = uvValues[j * 3 + 2]) != 0) + usedDims |= 4; //w + } + + if (usedDims & 4) // w + textureCoordDimensions.push_back(3); + else if (usedDims & 2) // v + textureCoordDimensions.push_back(2); + else // u + textureCoordDimensions.push_back(1); + } + + + // Save transforms + MATH::CTransformation xsiTransform = xsiMesh->transform; + MATH::CTransformation rotTrans; + rotTrans.SetRotation(xsiTransform.GetRotation()); + + // Bounds calculation + Real squaredRadius = 0.0f; + Vector3 min, max; + bool first = true; + + UniqueVertex vertex; + + + float progPerTri = (float)progressUpdates / xsiMesh->geometry.GetTriangleCount(); + float prog = 0.0f; + + CLongArray polygonTriangleIndices; + xsiMesh->geometry.GetPolygonTriangleIndices(polygonTriangleIndices); + + CLongArray triangleVertexIndices; + xsiMesh->geometry.GetTriangleVertexIndices(triangleVertexIndices); + + CDoubleArray vertexPositions; + xsiMesh->geometry.GetVertexPositions(vertexPositions); + + CRefArray vertexColours = xsiMesh->geometry.GetVertexColors(); + bool hasVertexColours = vertexColours.GetCount() > 0? true : false; + CFloatArray vertexColoursValues; + if (hasVertexColours) + { + ClusterProperty c = vertexColours[0]; + c.GetValues(vertexColoursValues); + } + + CFloatArray nodeNormals; + xsiMesh->geometry.GetNodeNormals(nodeNormals); + + CLongArray triangleNodeIndices; + xsiMesh->geometry.GetTriangleNodeIndices(triangleNodeIndices); + + CLongArray polygonMaterialIndices; + xsiMesh->geometry.GetPolygonMaterialIndices(polygonMaterialIndices); + + CRefArray materials = xsiMesh->geometry.GetMaterials(); + + ProtoSubMesh** materialToProtoSubMesh = new ProtoSubMesh*[materials.GetCount()]; + for (LONG i = 0; i < materials.GetCount(); ++ i) + materialToProtoSubMesh[i] = 0; + + CRefArray polygonClusters = xsiMesh->geometry.GetClusters(siClusterPolygonType); + + // Test for hidden polygons + XSI::CBitArray hiddenPolygons(xsiMesh->geometry.GetPolygonCount()); + for (LONG c = 0; c < polygonClusters.GetCount(); ++ c) + { + XSI::Cluster cluster = XSI::Cluster(polygonClusters[c]); + XSI::CRef clsvisibility; + + if (cluster.GetProperties().Find(L"clsvisibility", clsvisibility) == CStatus::OK) + { + Property p(clsvisibility); + if (!p.GetParameterValue(L"viewvis")) + { + XSI::CBitArray clusterPolys; + cluster.GetGeometryElementFlags(clusterPolys); + hiddenPolygons.Or(clusterPolys); + } + } + } + + // Iterate through all the triangles + for (long t = 0; t < xsiMesh->geometry.GetTriangleCount(); ++t) + { + // Skip the triangle if it relates to a hidden polygon + if (hiddenPolygons[polygonTriangleIndices[t]]) + continue; + + LONG polygonIndex = polygonTriangleIndices[t]; + LONG materialIndex = polygonMaterialIndices[polygonIndex]; + ProtoSubMesh* currentProto = materialToProtoSubMesh[materialIndex]; + + // Do we already have a protosubmesh for the material of this triangle? + if (!currentProto) + { + CString SubMeshName = xsiMesh->name; + + XSI::Material m(materials[materialIndex]); + + // Use the name of the cluster as the submesh name + for (LONG c = 0; c < polygonClusters.GetCount(); ++ c) + { + XSI::Cluster cluster = XSI::Cluster(polygonClusters[c]); + if (cluster.GetMaterial().GetName() == m.GetName()) + { + LONG out_clusterIndex; + cluster.FindIndex(polygonIndex, out_clusterIndex); + if (out_clusterIndex != -1) + { + SubMeshName = cluster.GetName(); + break; + } + } + } + + currentProto = materialToProtoSubMesh[materialIndex] = createOrRetrieveProtoSubMesh( + mMaterialPrefix + XSItoOgre(m.GetName()), + XSItoOgre(SubMeshName), + textureCoordDimensions, + hasVertexColours); + } + + // has this mesh been used in this proto before? if not set offset + size_t positionIndexOffset; + if (currentProto->lastMeshEntry == xsiMesh) + { + positionIndexOffset = currentProto->lastMeshIndexOffset; + } + else + { + // first time this has been used + // since we assume we 100% process each polygon mesh before the next, + // just use last pointer since faster in this section + currentProto->lastMeshEntry = xsiMesh; + positionIndexOffset = currentProto->indices.size(); + currentProto->lastMeshIndexOffset = positionIndexOffset; + // Also have to store this for future reference + currentProto->polygonMeshOffsetMap[xsiMesh] = positionIndexOffset; + } + for (long p = 0; p < 3; ++p) { - LONG posIndex = triangleVertexIndices[t * 3 + p]; // unique position index - - // Get position - MATH::CVector3 xsipos(vertexPositions[posIndex * 3], - vertexPositions[posIndex * 3 + 1], - vertexPositions[posIndex * 3 + 2]); - - // Apply global SRT - xsipos.MulByTransformationInPlace(xsiTransform); - vertex.position = XSItoOgre(xsipos); - - // Get normal - MATH::CVector3 xsinorm(nodeNormals[triangleNodeIndices[t * 3 + p] * 3], - nodeNormals[triangleNodeIndices[t * 3 + p] * 3 + 1], - nodeNormals[triangleNodeIndices[t * 3 + p] * 3 + 2]); - - // Apply global rotation - xsinorm *= rotTrans; - vertex.normal = XSItoOgre(xsinorm); - - for (size_t i = 0; i < textureCoordDimensions.size(); ++i) - { - // sampler indices can correctly dereference to sampler-order - // uv sets we built earlier - vertex.uv[i] = (samplerSets[i])[triangleNodeIndices[t * 3 + p]]; - } + LONG posIndex = triangleVertexIndices[t * 3 + p]; // unique position index + + // Get position + MATH::CVector3 xsipos(vertexPositions[posIndex * 3], + vertexPositions[posIndex * 3 + 1], + vertexPositions[posIndex * 3 + 2]); + + // Apply global SRT + xsipos.MulByTransformationInPlace(xsiTransform); + vertex.position = XSItoOgre(xsipos); + + // Get normal + MATH::CVector3 xsinorm(nodeNormals[triangleNodeIndices[t * 3 + p] * 3], + nodeNormals[triangleNodeIndices[t * 3 + p] * 3 + 1], + nodeNormals[triangleNodeIndices[t * 3 + p] * 3 + 2]); + + // Apply global rotation + xsinorm *= rotTrans; + vertex.normal = XSItoOgre(xsinorm); + + for (size_t i = 0; i < textureCoordDimensions.size(); ++i) + { + // sampler indices can correctly dereference to sampler-order + // uv sets we built earlier + vertex.uv[i] = (samplerSets[i])[triangleNodeIndices[t * 3 + p]]; + } + + if (hasVertexColours) + { + vertex.colour = XSItoOgre(CVertexColor((unsigned char)(vertexColoursValues[posIndex * 4] * 255), + (unsigned char)(vertexColoursValues[posIndex * 4 + 1] * 255), + (unsigned char)(vertexColoursValues[posIndex * 4 + 2] * 255), + (unsigned char)(vertexColoursValues[posIndex * 4 + 3] * 255))); + } + + // adjust index per offset, this makes position indices unique + // per polymesh in teh same protosubmesh + posIndex += positionIndexOffset; + + size_t index = createOrRetrieveUniqueVertex( + currentProto, posIndex, true, vertex); + currentProto->indices.push_back(index); + + // bounds + if (first) + { + squaredRadius = vertex.position.squaredLength(); + min = max = vertex.position; + first = false; + } + else + { + squaredRadius = + std::max(squaredRadius, vertex.position.squaredLength()); + min.makeFloor(vertex.position); + max.makeCeil(vertex.position); + } + } + + // Progress + prog += progPerTri; + while (prog >= 1.0f) + { + ProgressManager::getSingleton().progress(); + prog -= 1.0f; + } + + } + + // Merge bounds + AxisAlignedBox box; + box.setExtents(min, max); + box.merge(pMesh->getBounds()); + pMesh->_setBounds(box, false); + pMesh->_setBoundingSphereRadius( + std::max( + pMesh->getBoundingSphereRadius(), + Math::Sqrt(squaredRadius))); + + // Deal with any bone assignments + if (lookForBoneAssignments) + { + processBoneAssignments(pMesh, xsiMesh); + } + + // process any shape keys + processShapeKeys(pMesh, xsiMesh); + + // free temp UV data now + for(SamplerSetList::iterator s = samplerSets.begin(); + s != samplerSets.end(); ++s) + { + // init sampler points + delete [] *s; + } + samplerSets.clear(); + textureCoordDimensions.clear(); + } + //----------------------------------------------------------------------- + void XsiMeshExporter::processBoneAssignments(Mesh* pMesh, PolygonMeshEntry* xsiMesh) + { + // We have to iterate over the clusters which have envelope assignments + // then, for each protosubmesh which uses this polymesh, we need to create + // a bone assignment for each deformer, not forgetting to add one for + // each duplicated copy of this vertex too + // We build up a global list of deformers as we go which will get passed + // back to the top-level caller to build a skeleton from later + CRefArray clusterRefArray; + // Filter to 'vertex' types + xsiMesh->geometry.GetClusters().Filter( + siVertexCluster,CStringArray(),L"",clusterRefArray); + + + + for(int i = 0; i < clusterRefArray.GetCount(); ++i) + { + Cluster cluster(clusterRefArray[i]); + + CRefArray envelopes = cluster.GetEnvelopes(); + for (int e = 0; e < envelopes.GetCount(); ++e) + { + Envelope envelope(envelopes[e]); + + // Get mapping from cluster element index to geometry position index + CLongArray derefArray = envelope.GetElements(CTime().GetTime()).GetArray(); + + CRefArray deformers = envelope.GetDeformers(); + for (int d = 0; d < deformers.GetCount(); ++d) + { + X3DObject deformer(deformers[d]); + // Has this deformer been allocated a boneID already? + String deformerName = XSItoOgre(deformer.GetName()); + DeformerMap::iterator di = + mXsiDeformerMap.find(deformerName); + DeformerEntry* deformerEntry; + bool newDeformerEntry = false; + bool atLeastOneAssignment = false; + if (di == mXsiDeformerMap.end()) + { + deformerEntry = new DeformerEntry(mXsiDeformerMap.size(), deformer); + deformerEntry->hasVertexAssignments = true; + newDeformerEntry = true; + } + else + { + deformerEntry = di->second; + } + + // Get the weights for this deformer + CDoubleArray weights = + envelope.GetDeformerWeights(deformer, CTime().GetTime()); + // Weights are in order of cluster elements, we need to dereference + // those to the original point index using the cluster element array + for (int w = 0; w < weights.GetCount(); ++w) + { + size_t positionIndex = derefArray[w]; + float weight = weights[w]; + // Skip zero weights + if (weight == 0.0f) + continue; + + // Locate ProtoSubMeshes which use this mesh + for (MaterialProtoSubMeshMap::iterator mi = mMaterialProtoSubmeshMap.begin(); + mi != mMaterialProtoSubmeshMap.end(); ++mi) + { + for (ProtoSubMeshList::iterator psi = mi->second->begin(); + psi != mi->second->end(); ++psi) + { + ProtoSubMesh* ps = *psi; + ProtoSubMesh::PolygonMeshOffsetMap::iterator poli = + ps->polygonMeshOffsetMap.find(xsiMesh); + if (poli != ps->polygonMeshOffsetMap.end()) + { + // adjust index based on merging + size_t adjIndex = positionIndex + poli->second; + // look up real index + // If it doesn't exist, it's probably on a seam + // between clusters and we can safely skip it + IndexRemap::iterator remi = ps->posIndexRemap.find(adjIndex); + if (remi != ps->posIndexRemap.end()) + { + + size_t vertIndex = remi->second; + bool moreVerts = true; + // add UniqueVertex and clones + while (moreVerts) + { + UniqueVertex& vertex = ps->uniqueVertices[vertIndex]; + VertexBoneAssignment vba; + vba.boneIndex = deformerEntry->boneID; + vba.vertexIndex = vertIndex; + vba.weight = weight; + ps->boneAssignments.insert( + Mesh::VertexBoneAssignmentList::value_type(vertIndex, vba)); + atLeastOneAssignment = true; + + if (vertex.nextIndex == 0) + { + moreVerts = false; + } + else + { + vertIndex = vertex.nextIndex; + } + } + } + + } + } + + } + + + + } + + // Only add new deformer if we actually had any assignments + if (newDeformerEntry && atLeastOneAssignment) + { + mXsiDeformerMap[deformerName] = deformerEntry; + } + + + + + } - if (hasVertexColours) - { - vertex.colour = XSItoOgre(CVertexColor((unsigned char)(vertexColoursValues[posIndex * 4] * 255), - (unsigned char)(vertexColoursValues[posIndex * 4 + 1] * 255), - (unsigned char)(vertexColoursValues[posIndex * 4 + 2] * 255), - (unsigned char)(vertexColoursValues[posIndex * 4 + 3] * 255))); - } - - // adjust index per offset, this makes position indices unique - // per polymesh in teh same protosubmesh - posIndex += positionIndexOffset; - - size_t index = createOrRetrieveUniqueVertex( - currentProto, posIndex, true, vertex); - currentProto->indices.push_back(index); - - // bounds - if (first) - { - squaredRadius = vertex.position.squaredLength(); - min = max = vertex.position; - first = false; - } - else - { - squaredRadius = - std::max(squaredRadius, vertex.position.squaredLength()); - min.makeFloor(vertex.position); - max.makeCeil(vertex.position); - } - } - - // Progress - prog += progPerTri; - while (prog >= 1.0f) - { - ProgressManager::getSingleton().progress(); - prog -= 1.0f; - } - - } - - // Merge bounds - AxisAlignedBox box; - box.setExtents(min, max); - box.merge(pMesh->getBounds()); - pMesh->_setBounds(box, false); - pMesh->_setBoundingSphereRadius( - std::max( - pMesh->getBoundingSphereRadius(), - Math::Sqrt(squaredRadius))); - - // Deal with any bone assignments - if (lookForBoneAssignments) - { - processBoneAssignments(pMesh, xsiMesh); - } - - // process any shape keys - processShapeKeys(pMesh, xsiMesh); - - // free temp UV data now - for(SamplerSetList::iterator s = samplerSets.begin(); - s != samplerSets.end(); ++s) - { - // init sampler points - delete [] *s; - } - samplerSets.clear(); - textureCoordDimensions.clear(); - } - //----------------------------------------------------------------------- - void XsiMeshExporter::processBoneAssignments(Mesh* pMesh, PolygonMeshEntry* xsiMesh) - { - // We have to iterate over the clusters which have envelope assignments - // then, for each protosubmesh which uses this polymesh, we need to create - // a bone assignment for each deformer, not forgetting to add one for - // each duplicated copy of this vertex too - // We build up a global list of deformers as we go which will get passed - // back to the top-level caller to build a skeleton from later - CRefArray clusterRefArray; - // Filter to 'vertex' types - xsiMesh->geometry.GetClusters().Filter( - siVertexCluster,CStringArray(),L"",clusterRefArray); - - - - for(int i = 0; i < clusterRefArray.GetCount(); ++i) - { - Cluster cluster(clusterRefArray[i]); - - CRefArray envelopes = cluster.GetEnvelopes(); - for (int e = 0; e < envelopes.GetCount(); ++e) - { - Envelope envelope(envelopes[e]); - - // Get mapping from cluster element index to geometry position index - CLongArray derefArray = envelope.GetElements(CTime().GetTime()).GetArray(); - - CRefArray deformers = envelope.GetDeformers(); - for (int d = 0; d < deformers.GetCount(); ++d) - { - X3DObject deformer(deformers[d]); - // Has this deformer been allocated a boneID already? - String deformerName = XSItoOgre(deformer.GetName()); - DeformerMap::iterator di = - mXsiDeformerMap.find(deformerName); - DeformerEntry* deformerEntry; - bool newDeformerEntry = false; - bool atLeastOneAssignment = false; - if (di == mXsiDeformerMap.end()) - { - deformerEntry = new DeformerEntry(mXsiDeformerMap.size(), deformer); - deformerEntry->hasVertexAssignments = true; - newDeformerEntry = true; - } - else - { - deformerEntry = di->second; - } - - // Get the weights for this deformer - CDoubleArray weights = - envelope.GetDeformerWeights(deformer, CTime().GetTime()); - // Weights are in order of cluster elements, we need to dereference - // those to the original point index using the cluster element array - for (int w = 0; w < weights.GetCount(); ++w) - { - size_t positionIndex = derefArray[w]; - float weight = weights[w]; - // Skip zero weights - if (weight == 0.0f) - continue; - - // Locate ProtoSubMeshes which use this mesh - for (MaterialProtoSubMeshMap::iterator mi = mMaterialProtoSubmeshMap.begin(); - mi != mMaterialProtoSubmeshMap.end(); ++mi) - { - for (ProtoSubMeshList::iterator psi = mi->second->begin(); - psi != mi->second->end(); ++psi) - { - ProtoSubMesh* ps = *psi; - ProtoSubMesh::PolygonMeshOffsetMap::iterator poli = - ps->polygonMeshOffsetMap.find(xsiMesh); - if (poli != ps->polygonMeshOffsetMap.end()) - { - // adjust index based on merging - size_t adjIndex = positionIndex + poli->second; - // look up real index - // If it doesn't exist, it's probably on a seam - // between clusters and we can safely skip it - IndexRemap::iterator remi = ps->posIndexRemap.find(adjIndex); - if (remi != ps->posIndexRemap.end()) - { - - size_t vertIndex = remi->second; - bool moreVerts = true; - // add UniqueVertex and clones - while (moreVerts) - { - UniqueVertex& vertex = ps->uniqueVertices[vertIndex]; - VertexBoneAssignment vba; - vba.boneIndex = deformerEntry->boneID; - vba.vertexIndex = vertIndex; - vba.weight = weight; - ps->boneAssignments.insert( - Mesh::VertexBoneAssignmentList::value_type(vertIndex, vba)); - atLeastOneAssignment = true; - - if (vertex.nextIndex == 0) - { - moreVerts = false; - } - else - { - vertIndex = vertex.nextIndex; - } - } - } - - } - } - - } - - - - } - - // Only add new deformer if we actually had any assignments - if (newDeformerEntry && atLeastOneAssignment) - { - mXsiDeformerMap[deformerName] = deformerEntry; - } - - - - - } - - - } - } - - - } - //----------------------------------------------------------------------- - void XsiMeshExporter::processShapeKeys(Mesh* pMesh, PolygonMeshEntry* xsiMesh) - { - CRefArray shapeKeys = xsiMesh->geometry.GetShapeKeys(); - - for (int i = 0; i < shapeKeys.GetCount(); ++ i) - { - ShapeKey shapeKey = shapeKeys[i]; - LogOgreAndXSI("Found shape key " + XSItoOgre(shapeKey.GetName())); - - // Locate ProtoSubMeshes which use this mesh - for (MaterialProtoSubMeshMap::iterator mi = mMaterialProtoSubmeshMap.begin(); - mi != mMaterialProtoSubmeshMap.end(); ++mi) - { - for (ProtoSubMeshList::iterator psi = mi->second->begin(); - psi != mi->second->end(); ++psi) - { - ProtoSubMesh* ps = *psi; - ProtoSubMesh::PolygonMeshOffsetMap::iterator poli = - ps->polygonMeshOffsetMap.find(xsiMesh); - if (poli != ps->polygonMeshOffsetMap.end()) - { - // remap from mesh vertex index to proto vertex index - size_t indexAdjustment = poli->second; - - // Create a new pose, target is implied by proto, final - // index to be determined later including merging - Pose pose(0, XSItoOgre(shapeKey.GetName())); - - CBitArray affectedPoints; - CFloatArray shapeValues; - shapeKey.GetValues(shapeValues, affectedPoints); // automatically converted to object relative reference mode - - // Iterate per vertex affected - LONG idxPoint = affectedPoints.GetIterator(); - while (affectedPoints.GetNextTrueBit(idxPoint) ) - { - // Now get offset - Vector3 offset(shapeValues[idxPoint * 3], shapeValues[idxPoint * 3 + 1], shapeValues[idxPoint * 3 + 2]); - - // Skip zero offsets - if (offset == Vector3::ZERO) - continue; - - // Convert to world space - MATH::CVector3 off(offset.x, offset.y, offset.z); - off.MulByTransformationInPlace(xsiMesh->transform); - offset = XSItoOgre(off); - - // adjust index based on merging - size_t adjIndex = idxPoint + indexAdjustment; - - // look up real index - // If it doesn't exist, it's probably on a seam - // between clusters and we can safely skip it - IndexRemap::iterator remi = ps->posIndexRemap.find(adjIndex); - if (remi != ps->posIndexRemap.end()) - { - size_t vertIndex = remi->second; - bool moreVerts = true; - - // add UniqueVertex and clones - while (moreVerts) - { - UniqueVertex& vertex = ps->uniqueVertices[vertIndex]; - - // Create a vertex pose entry - pose.addVertex(vertIndex, offset); - - if (vertex.nextIndex == 0) - { - moreVerts = false; - } - else - { - vertIndex = vertex.nextIndex; - } - } // more duplicate verts - } // found remap? - } // for each vertex affected - - // Add pose to proto - ps->poseList.push_back(pose); - - // record that we used this shape key - ps->shapeKeys.Add(shapeKey); - } // proto found? - } // for each proto - } - } - } - //----------------------------------------------------------------------- - void XsiMeshExporter::buildShapeClipList(ShapeClipList& listToPopulate) - { - // Process all mixers - Model root = mXsiApp.GetActiveSceneRoot(); - if (root.HasMixer()) - { - XSI::Mixer mixer = root.GetMixer(); - buildShapeClipList(mixer, listToPopulate); - } - - // Get all child models (recursive) - CRefArray models = root.GetModels(); - for (int m = 0; m < models.GetCount(); ++m) - { - Model model(models[m]); - if (model.HasMixer()) - { - XSI::Mixer mixer = root.GetMixer(); - buildShapeClipList(mixer, listToPopulate); - } - } - - } - //----------------------------------------------------------------------- - void XsiMeshExporter::buildShapeClipList(ClipContainer& container, - ShapeClipList& listToPopulate) - { - CRefArray clips = container.GetClips(); - for (int c = 0; c < clips.GetCount(); ++c) - { - if (clips[c].IsA(siClipContainerID)) - { - ClipContainer container(clips[c]); - // cascade - buildShapeClipList(container, listToPopulate); - } - else - { - - XSI::Clip clip(clips[c]); - XSI::CString clipType = clip.GetType(); - if (clip.GetType() == siClipShapeType) - { - XSI::TimeControl timeControl = clip.GetTimeControl(); - ShapeClipEntry sce; - sce.clip = clip; - sce.startFrame = sce.originalStartFrame = timeControl.GetStartOffset(); - long length = (1.0 / timeControl.GetScale()) * - (timeControl.GetClipOut() - timeControl.GetClipIn() + 1); - sce.endFrame = sce.startFrame + length - 1; - - // Find link to shape - sce.keytoPose = 0; - ActionSource source(clip.GetSource()); - CRefArray sourceItems = source.GetItems(); - assert (sourceItems.GetCount() == 1 && "More than one source item on shape clip!"); - AnimationSourceItem sourceItem(sourceItems[0]); - // Source is the shape key - // Locate this in the list we built while building poses - for (ShapeKeyMapping::iterator skm = mShapeKeyMapping.begin(); - skm != mShapeKeyMapping.end(); ++skm) - { - ShapeKeyToPoseEntry& mapping = *skm; - if(mapping.shapeKey == sourceItem.GetSource()) - { - // bingo - sce.keytoPose = &(*skm); - } - } - - listToPopulate.push_back(sce); - - } - } - - } - - - } - //----------------------------------------------------------------------- - void XsiMeshExporter::exportAnimations(Mesh* pMesh, AnimationList& animList, - Real fps) - { - ShapeClipList clipList; - buildShapeClipList(clipList); - // Add all animations - for (AnimationList::iterator i = animList.begin(); i != animList.end(); ++i) - { - // For each animation, we want to search for all shape clips using a - // shape key which has been used - AnimationEntry& animEntry = *i; - Animation* anim = 0; - - // Iterate per submesh since we want to collect a track per submesh - // Iterate over the 'target index' which is submesh index + 1 - for (ushort targetIndex = 1; targetIndex <= pMesh->getNumSubMeshes(); ++targetIndex) - { - // find all shape clips for this submesh overlapping this time period - // we'll clamp the clip too - ShapeClipList submeshClipList; - std::set keyframeList; - - deriveShapeClipAndKeyframeList(targetIndex, animEntry, clipList, - submeshClipList, keyframeList); - - if (!submeshClipList.empty()) - { - - // Create animation if we haven't already - if (!anim) - { - Real len = (float)(animEntry.endFrame - animEntry.startFrame + 1) / fps; - anim = pMesh->createAnimation(animEntry.animationName, len); - } - - // Create track - VertexAnimationTrack* track = - anim->createVertexTrack(targetIndex, VAT_POSE); - - // Now sample all the clips on all the keyframes - for (std::set::iterator k = keyframeList.begin(); - k != keyframeList.end(); ++k) - { - // Create a key - long frameNum = *k; - Real keyTime = (float)(frameNum - animEntry.startFrame) / fps; - VertexPoseKeyFrame* keyFrame = - track->createVertexPoseKeyFrame(keyTime); - - // Sample all the clips - for (ShapeClipList::iterator c = submeshClipList.begin(); - c != submeshClipList.end(); ++c) - { - ShapeClipEntry& sce = *c; - if(frameNum >= sce.startFrame && - frameNum <= sce.endFrame) - { - - // map the keyframe number to a local number - long localFrameNum = frameNum - sce.originalStartFrame * - sce.clip.GetTimeControl().GetScale(); - - // sample pose influences - // Iterate over the animated parameters, find a 'weight' fcurve entry - bool fcurveFound = false; - CRefArray params = sce.clip.GetAnimatedParameters(); - for (int p = 0; p < params.GetCount(); ++p) - { - Parameter param(params[p]); - if (param.GetSource().IsA(siFCurveID)) - { - fcurveFound = true; - FCurve fcurve(param.GetSource()); - CValue val = fcurve.Eval(localFrameNum); - if ((float)val != 0.0f) - { - keyFrame->addPoseReference( - sce.keytoPose->poseIndex, val); - } - - } - } - - if (!fcurveFound) - { - // No fcurves, so just assume 1.0 weight since that's - // how XSI deals with it - keyFrame->addPoseReference(sce.keytoPose->poseIndex, 1.0f); - - } - } - } - } - - } - - } - } - - } - //----------------------------------------------------------------------- - void XsiMeshExporter::deriveShapeClipAndKeyframeList(ushort targetIndex, - AnimationEntry& animEntry, ShapeClipList& inClipList, - ShapeClipList& outClipList, std::set& keyFrameList) - { - for (ShapeClipList::iterator sci = inClipList.begin(); - sci != inClipList.end(); ++sci) - { - ShapeClipEntry& sce = *sci; - - if (sce.startFrame <= animEntry.endFrame && - sce.endFrame >= animEntry.startFrame && - sce.keytoPose->targetHandle == targetIndex) - { - // Clip overlaps with the animation sampling area and - // applies to this submesh - ShapeClipEntry newClipEntry; - newClipEntry.originalStartFrame = sce.startFrame; - newClipEntry.startFrame = std::max(sce.startFrame, animEntry.startFrame); - newClipEntry.endFrame = std::min(sce.endFrame, animEntry.endFrame); - newClipEntry.clip = sce.clip; - newClipEntry.keytoPose = sce.keytoPose; - outClipList.push_back(newClipEntry); - - // Iterate over the animated parameters, find a 'weight' fcurve entry - CRefArray params = sce.clip.GetAnimatedParameters(); - for (int p = 0; p < params.GetCount(); ++p) - { - Parameter param(params[p]); - if (param.GetSource().IsA(siFCurveID)) - { - FCurve fcurve(param.GetSource()); - CRefArray keys = fcurve.GetKeys(); - for (int k = 0; k < keys.GetCount(); ++k) - { - FCurveKey key(keys[k]); - // convert from key time to global frame number - CTime time = key.GetTime(); - long frameNum = (long)((double)(time.GetTime() + sce.startFrame) - / sce.clip.GetTimeControl().GetScale()); - keyFrameList.insert(frameNum); - } - - - } - } - - } - } - // Always sample start & end frames - keyFrameList.insert(animEntry.startFrame); - keyFrameList.insert(animEntry.endFrame); - - } - //----------------------------------------------------------------------- - void XsiMeshExporter::exportProtoSubMeshes(Mesh* pMesh) - { - // Take the list of ProtoSubMesh instances and bake a SubMesh per - // instance, then clear the list - - for (MaterialProtoSubMeshMap::iterator mi = mMaterialProtoSubmeshMap.begin(); - mi != mMaterialProtoSubmeshMap.end(); ++mi) - { - for (ProtoSubMeshList::iterator psi = mi->second->begin(); - psi != mi->second->end(); ++psi) - { - // export each one - exportProtoSubMesh(pMesh, *psi); - - // free it - delete *psi; - } - // delete proto list - delete mi->second; - } - mMaterialProtoSubmeshMap.clear(); - } - //----------------------------------------------------------------------- - void XsiMeshExporter::exportProtoSubMesh(Mesh* pMesh, ProtoSubMesh* proto) - { - // Skip protos which have ended up empty - if (proto->indices.empty()) - return; + + } + } + + + } + //----------------------------------------------------------------------- + void XsiMeshExporter::processShapeKeys(Mesh* pMesh, PolygonMeshEntry* xsiMesh) + { + CRefArray shapeKeys = xsiMesh->geometry.GetShapeKeys(); + + for (int i = 0; i < shapeKeys.GetCount(); ++ i) + { + ShapeKey shapeKey = shapeKeys[i]; + LogOgreAndXSI("Found shape key " + XSItoOgre(shapeKey.GetName())); + + // Locate ProtoSubMeshes which use this mesh + for (MaterialProtoSubMeshMap::iterator mi = mMaterialProtoSubmeshMap.begin(); + mi != mMaterialProtoSubmeshMap.end(); ++mi) + { + for (ProtoSubMeshList::iterator psi = mi->second->begin(); + psi != mi->second->end(); ++psi) + { + ProtoSubMesh* ps = *psi; + ProtoSubMesh::PolygonMeshOffsetMap::iterator poli = + ps->polygonMeshOffsetMap.find(xsiMesh); + if (poli != ps->polygonMeshOffsetMap.end()) + { + // remap from mesh vertex index to proto vertex index + size_t indexAdjustment = poli->second; + + // Create a new pose, target is implied by proto, final + // index to be determined later including merging + Pose pose(0, XSItoOgre(shapeKey.GetName())); + + CBitArray affectedPoints; + CFloatArray shapeValues; + shapeKey.GetValues(shapeValues, affectedPoints); // automatically converted to object relative reference mode + + // Iterate per vertex affected + LONG idxPoint = affectedPoints.GetIterator(); + while (affectedPoints.GetNextTrueBit(idxPoint) ) + { + // Now get offset + Vector3 offset(shapeValues[idxPoint * 3], shapeValues[idxPoint * 3 + 1], shapeValues[idxPoint * 3 + 2]); + + // Skip zero offsets + if (offset == Vector3::ZERO) + continue; + + // Convert to world space + MATH::CVector3 off(offset.x, offset.y, offset.z); + off.MulByTransformationInPlace(xsiMesh->transform); + offset = XSItoOgre(off); + + // adjust index based on merging + size_t adjIndex = idxPoint + indexAdjustment; + + // look up real index + // If it doesn't exist, it's probably on a seam + // between clusters and we can safely skip it + IndexRemap::iterator remi = ps->posIndexRemap.find(adjIndex); + if (remi != ps->posIndexRemap.end()) + { + size_t vertIndex = remi->second; + bool moreVerts = true; + + // add UniqueVertex and clones + while (moreVerts) + { + UniqueVertex& vertex = ps->uniqueVertices[vertIndex]; + + // Create a vertex pose entry + pose.addVertex(vertIndex, offset); + + if (vertex.nextIndex == 0) + { + moreVerts = false; + } + else + { + vertIndex = vertex.nextIndex; + } + } // more duplicate verts + } // found remap? + } // for each vertex affected + + // Add pose to proto + ps->poseList.push_back(pose); + + // record that we used this shape key + ps->shapeKeys.Add(shapeKey); + } // proto found? + } // for each proto + } + } + } + //----------------------------------------------------------------------- + void XsiMeshExporter::buildShapeClipList(ShapeClipList& listToPopulate) + { + // Process all mixers + Model root = mXsiApp.GetActiveSceneRoot(); + if (root.HasMixer()) + { + XSI::Mixer mixer = root.GetMixer(); + buildShapeClipList(mixer, listToPopulate); + } + + // Get all child models (recursive) + CRefArray models = root.GetModels(); + for (int m = 0; m < models.GetCount(); ++m) + { + Model model(models[m]); + if (model.HasMixer()) + { + XSI::Mixer mixer = root.GetMixer(); + buildShapeClipList(mixer, listToPopulate); + } + } + + } + //----------------------------------------------------------------------- + void XsiMeshExporter::buildShapeClipList(ClipContainer& container, + ShapeClipList& listToPopulate) + { + CRefArray clips = container.GetClips(); + for (int c = 0; c < clips.GetCount(); ++c) + { + if (clips[c].IsA(siClipContainerID)) + { + ClipContainer container(clips[c]); + // cascade + buildShapeClipList(container, listToPopulate); + } + else + { + + XSI::Clip clip(clips[c]); + XSI::CString clipType = clip.GetType(); + if (clip.GetType() == siClipShapeType) + { + XSI::TimeControl timeControl = clip.GetTimeControl(); + ShapeClipEntry sce; + sce.clip = clip; + sce.startFrame = sce.originalStartFrame = timeControl.GetStartOffset(); + long length = (1.0 / timeControl.GetScale()) * + (timeControl.GetClipOut() - timeControl.GetClipIn() + 1); + sce.endFrame = sce.startFrame + length - 1; + + // Find link to shape + sce.keytoPose = 0; + ActionSource source(clip.GetSource()); + CRefArray sourceItems = source.GetItems(); + assert (sourceItems.GetCount() == 1 && "More than one source item on shape clip!"); + AnimationSourceItem sourceItem(sourceItems[0]); + // Source is the shape key + // Locate this in the list we built while building poses + for (ShapeKeyMapping::iterator skm = mShapeKeyMapping.begin(); + skm != mShapeKeyMapping.end(); ++skm) + { + ShapeKeyToPoseEntry& mapping = *skm; + if(mapping.shapeKey == sourceItem.GetSource()) + { + // bingo + sce.keytoPose = &(*skm); + } + } + + listToPopulate.push_back(sce); + + } + } + + } + + + } + //----------------------------------------------------------------------- + void XsiMeshExporter::exportAnimations(Mesh* pMesh, AnimationList& animList, + Real fps) + { + ShapeClipList clipList; + buildShapeClipList(clipList); + // Add all animations + for (AnimationList::iterator i = animList.begin(); i != animList.end(); ++i) + { + // For each animation, we want to search for all shape clips using a + // shape key which has been used + AnimationEntry& animEntry = *i; + Animation* anim = 0; + + // Iterate per submesh since we want to collect a track per submesh + // Iterate over the 'target index' which is submesh index + 1 + for (ushort targetIndex = 1; targetIndex <= pMesh->getNumSubMeshes(); ++targetIndex) + { + // find all shape clips for this submesh overlapping this time period + // we'll clamp the clip too + ShapeClipList submeshClipList; + std::set keyframeList; + + deriveShapeClipAndKeyframeList(targetIndex, animEntry, clipList, + submeshClipList, keyframeList); + + if (!submeshClipList.empty()) + { + + // Create animation if we haven't already + if (!anim) + { + Real len = (float)(animEntry.endFrame - animEntry.startFrame + 1) / fps; + anim = pMesh->createAnimation(animEntry.animationName, len); + } + + // Create track + VertexAnimationTrack* track = + anim->createVertexTrack(targetIndex, VAT_POSE); + + // Now sample all the clips on all the keyframes + for (std::set::iterator k = keyframeList.begin(); + k != keyframeList.end(); ++k) + { + // Create a key + long frameNum = *k; + Real keyTime = (float)(frameNum - animEntry.startFrame) / fps; + VertexPoseKeyFrame* keyFrame = + track->createVertexPoseKeyFrame(keyTime); + + // Sample all the clips + for (ShapeClipList::iterator c = submeshClipList.begin(); + c != submeshClipList.end(); ++c) + { + ShapeClipEntry& sce = *c; + if(frameNum >= sce.startFrame && + frameNum <= sce.endFrame) + { + + // map the keyframe number to a local number + long localFrameNum = frameNum - sce.originalStartFrame * + sce.clip.GetTimeControl().GetScale(); + + // sample pose influences + // Iterate over the animated parameters, find a 'weight' fcurve entry + bool fcurveFound = false; + CRefArray params = sce.clip.GetAnimatedParameters(); + for (int p = 0; p < params.GetCount(); ++p) + { + Parameter param(params[p]); + if (param.GetSource().IsA(siFCurveID)) + { + fcurveFound = true; + FCurve fcurve(param.GetSource()); + CValue val = fcurve.Eval(localFrameNum); + if ((float)val != 0.0f) + { + keyFrame->addPoseReference( + sce.keytoPose->poseIndex, val); + } + + } + } + + if (!fcurveFound) + { + // No fcurves, so just assume 1.0 weight since that's + // how XSI deals with it + keyFrame->addPoseReference(sce.keytoPose->poseIndex, 1.0f); + + } + } + } + } + + } + + } + } + + } + //----------------------------------------------------------------------- + void XsiMeshExporter::deriveShapeClipAndKeyframeList(ushort targetIndex, + AnimationEntry& animEntry, ShapeClipList& inClipList, + ShapeClipList& outClipList, std::set& keyFrameList) + { + for (ShapeClipList::iterator sci = inClipList.begin(); + sci != inClipList.end(); ++sci) + { + ShapeClipEntry& sce = *sci; + + if (sce.startFrame <= animEntry.endFrame && + sce.endFrame >= animEntry.startFrame && + sce.keytoPose->targetHandle == targetIndex) + { + // Clip overlaps with the animation sampling area and + // applies to this submesh + ShapeClipEntry newClipEntry; + newClipEntry.originalStartFrame = sce.startFrame; + newClipEntry.startFrame = std::max(sce.startFrame, animEntry.startFrame); + newClipEntry.endFrame = std::min(sce.endFrame, animEntry.endFrame); + newClipEntry.clip = sce.clip; + newClipEntry.keytoPose = sce.keytoPose; + outClipList.push_back(newClipEntry); + + // Iterate over the animated parameters, find a 'weight' fcurve entry + CRefArray params = sce.clip.GetAnimatedParameters(); + for (int p = 0; p < params.GetCount(); ++p) + { + Parameter param(params[p]); + if (param.GetSource().IsA(siFCurveID)) + { + FCurve fcurve(param.GetSource()); + CRefArray keys = fcurve.GetKeys(); + for (int k = 0; k < keys.GetCount(); ++k) + { + FCurveKey key(keys[k]); + // convert from key time to global frame number + CTime time = key.GetTime(); + long frameNum = (long)((double)(time.GetTime() + sce.startFrame) + / sce.clip.GetTimeControl().GetScale()); + keyFrameList.insert(frameNum); + } + + + } + } + + } + } + // Always sample start & end frames + keyFrameList.insert(animEntry.startFrame); + keyFrameList.insert(animEntry.endFrame); + + } + //----------------------------------------------------------------------- + void XsiMeshExporter::exportProtoSubMeshes(Mesh* pMesh) + { + // Take the list of ProtoSubMesh instances and bake a SubMesh per + // instance, then clear the list + + for (MaterialProtoSubMeshMap::iterator mi = mMaterialProtoSubmeshMap.begin(); + mi != mMaterialProtoSubmeshMap.end(); ++mi) + { + for (ProtoSubMeshList::iterator psi = mi->second->begin(); + psi != mi->second->end(); ++psi) + { + // export each one + exportProtoSubMesh(pMesh, *psi); + + // free it + delete *psi; + } + // delete proto list + delete mi->second; + } + mMaterialProtoSubmeshMap.clear(); + } + //----------------------------------------------------------------------- + void XsiMeshExporter::exportProtoSubMesh(Mesh* pMesh, ProtoSubMesh* proto) + { + // Skip protos which have ended up empty + if (proto->indices.empty()) + return; SubMesh* sm = 0; if (proto->name.empty()) @@ -1131,8 +1131,8 @@ namespace Ogre { sm->vertexData = new VertexData(); // always do triangle list sm->indexData->indexCount = proto->indices.size(); - - sm->vertexData->vertexCount = proto->uniqueVertices.size(); + + sm->vertexData->vertexCount = proto->uniqueVertices.size(); // Determine index size bool use32BitIndexes = false; if (proto->uniqueVertices.size() > 65536) @@ -1164,15 +1164,15 @@ namespace Ogre { // define vertex declaration unsigned buf = 0; size_t offset = 0; - // always add position and normal + // always add position and normal sm->vertexData->vertexDeclaration->addElement(buf, offset, VET_FLOAT3, VES_POSITION); offset += VertexElement::getTypeSize(VET_FLOAT3); - // Split vertex data after position if poses present - if (!proto->poseList.empty()) - { - buf++; - offset = 0; - } + // Split vertex data after position if poses present + if (!proto->poseList.empty()) + { + buf++; + offset = 0; + } sm->vertexData->vertexDeclaration->addElement(buf, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); // split vertex data here if animated @@ -1181,7 +1181,7 @@ namespace Ogre { buf++; offset = 0; } - // Optional vertex colour + // Optional vertex colour if(proto->hasVertexColours) { sm->vertexData->vertexDeclaration->addElement(buf, offset, VET_COLOUR, VES_DIFFUSE); @@ -1190,11 +1190,11 @@ namespace Ogre { // Define UVs for (unsigned short uvi = 0; uvi < proto->textureCoordDimensions.size(); ++uvi) { - VertexElementType uvType = - VertexElement::multiplyTypeCount( - VET_FLOAT1, proto->textureCoordDimensions[uvi]); + VertexElementType uvType = + VertexElement::multiplyTypeCount( + VET_FLOAT1, proto->textureCoordDimensions[uvi]); sm->vertexData->vertexDeclaration->addElement( - buf, offset, uvType, VES_TEXTURE_COORDINATES, uvi); + buf, offset, uvType, VES_TEXTURE_COORDINATES, uvi); offset += VertexElement::getTypeSize(uvType); } @@ -1204,232 +1204,232 @@ namespace Ogre { createVertexBuffer(sm->vertexData, b, proto->uniqueVertices); } - // deal with any bone assignments - if (!proto->boneAssignments.empty()) - { - // rationalise first (normalises and strips out any excessive bones) - sm->parent->_rationaliseBoneAssignments( - sm->vertexData->vertexCount, proto->boneAssignments); - - for (Mesh::VertexBoneAssignmentList::iterator bi = proto->boneAssignments.begin(); - bi != proto->boneAssignments.end(); ++bi) - { - sm->addBoneAssignment(bi->second); - } - } - - // poses - // derive target index (current submesh index + 1 since 0 is shared geom) - ushort targetIndex = pMesh->getNumSubMeshes(); - ushort sk = 0; - for (std::list::iterator pi = proto->poseList.begin(); - pi != proto->poseList.end(); ++pi, ++sk) - { - Pose* pose = pMesh->createPose(targetIndex, pi->getName()); - Pose::VertexOffsetIterator vertIt = - pi->getVertexOffsetIterator(); - while (vertIt.hasMoreElements()) - { - pose->addVertex(vertIt.peekNextKey(), vertIt.peekNextValue()); - vertIt.getNext(); - } - - // record shape key to pose mapping for animation later - ShapeKeyToPoseEntry se; - se.shapeKey = proto->shapeKeys[sk]; - se.poseIndex = pMesh->getPoseCount() - 1; - se.targetHandle = targetIndex; - mShapeKeyMapping.push_back(se); - - } - - } - //----------------------------------------------------------------------- - void XsiMeshExporter::buildPolygonMeshList(bool includeChildren) - { - Selection sel(mXsiApp.GetSelection()); - if (sel.GetCount() == 0) - { - // Whole scene - // Derive the scene root - X3DObject sceneRoot(mXsiApp.GetActiveSceneRoot()); - findPolygonMeshes(sceneRoot, true); - } - else - { - // iterate over selection - for (int i = 0; i < sel.GetCount(); ++i) - { - X3DObject obj(sel[i]); - findPolygonMeshes(obj,includeChildren); - } - } - } - //----------------------------------------------------------------------- - void XsiMeshExporter::findPolygonMeshes(X3DObject& x3dObj, bool recurse) - { - // Check validity of current object - if (!x3dObj.IsValid()) - { - OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, - "Invalid X3DObject found", - "XsiMeshExporter::exportX3DObject"); - } - // Log a message in script window - CString name = x3dObj.GetName() ; - LogOgreAndXSI(L"-- Traversing " + name) ; - - - // locate any geometry - if (!x3dObj.IsA(siCameraID) && - !x3dObj.IsA(siLightID) && - !x3dObj.IsA(siNullID) && - !x3dObj.IsA(siModelID)) - { - Primitive prim(x3dObj.GetActivePrimitive()); - if (prim.IsValid()) - { - Geometry geom(prim.GetGeometry()); - if (geom.GetRef().GetClassID() == siPolygonMeshID) - { - // Find the current level of subdivision - LONG subd = 0; - XSI::CRef geomapprox; - if (x3dObj.GetProperties().Find(L"geomapprox", geomapprox) == CStatus::OK) - { - Property p(geomapprox); - subd = p.GetParameterValue(L"gapproxmosl"); - } - - // add it to the list - PolygonMesh pmesh(geom); - mXsiPolygonMeshList.insert( - new PolygonMeshEntry(x3dObj.GetName(), x3dObj.GetKinematics().GetGlobal().GetTransform(), pmesh.GetGeometryAccessor(siConstructionModeSecondaryShape, siCatmullClark, subd))); - - LogOgreAndXSI(L"-- Queueing " + name) ; - } - } - - } - - // Cascade into children - if (recurse) - { - CRefArray children = x3dObj.GetChildren(); - - for(long i = 0; i < children.GetCount(); i++) - { - X3DObject childObj = children[i]; - findPolygonMeshes(childObj, recurse); - } - } - - } + // deal with any bone assignments + if (!proto->boneAssignments.empty()) + { + // rationalise first (normalises and strips out any excessive bones) + sm->parent->_rationaliseBoneAssignments( + sm->vertexData->vertexCount, proto->boneAssignments); + + for (Mesh::VertexBoneAssignmentList::iterator bi = proto->boneAssignments.begin(); + bi != proto->boneAssignments.end(); ++bi) + { + sm->addBoneAssignment(bi->second); + } + } + + // poses + // derive target index (current submesh index + 1 since 0 is shared geom) + ushort targetIndex = pMesh->getNumSubMeshes(); + ushort sk = 0; + for (std::list::iterator pi = proto->poseList.begin(); + pi != proto->poseList.end(); ++pi, ++sk) + { + Pose* pose = pMesh->createPose(targetIndex, pi->getName()); + Pose::VertexOffsetIterator vertIt = + pi->getVertexOffsetIterator(); + while (vertIt.hasMoreElements()) + { + pose->addVertex(vertIt.peekNextKey(), vertIt.peekNextValue()); + vertIt.getNext(); + } + + // record shape key to pose mapping for animation later + ShapeKeyToPoseEntry se; + se.shapeKey = proto->shapeKeys[sk]; + se.poseIndex = pMesh->getPoseCount() - 1; + se.targetHandle = targetIndex; + mShapeKeyMapping.push_back(se); + + } + + } + //----------------------------------------------------------------------- + void XsiMeshExporter::buildPolygonMeshList(bool includeChildren) + { + Selection sel(mXsiApp.GetSelection()); + if (sel.GetCount() == 0) + { + // Whole scene + // Derive the scene root + X3DObject sceneRoot(mXsiApp.GetActiveSceneRoot()); + findPolygonMeshes(sceneRoot, true); + } + else + { + // iterate over selection + for (int i = 0; i < sel.GetCount(); ++i) + { + X3DObject obj(sel[i]); + findPolygonMeshes(obj,includeChildren); + } + } + } + //----------------------------------------------------------------------- + void XsiMeshExporter::findPolygonMeshes(X3DObject& x3dObj, bool recurse) + { + // Check validity of current object + if (!x3dObj.IsValid()) + { + OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, + "Invalid X3DObject found", + "XsiMeshExporter::exportX3DObject"); + } + // Log a message in script window + CString name = x3dObj.GetName() ; + LogOgreAndXSI(L"-- Traversing " + name) ; + + + // locate any geometry + if (!x3dObj.IsA(siCameraID) && + !x3dObj.IsA(siLightID) && + !x3dObj.IsA(siNullID) && + !x3dObj.IsA(siModelID)) + { + Primitive prim(x3dObj.GetActivePrimitive()); + if (prim.IsValid()) + { + Geometry geom(prim.GetGeometry()); + if (geom.GetRef().GetClassID() == siPolygonMeshID) + { + // Find the current level of subdivision + LONG subd = 0; + XSI::CRef geomapprox; + if (x3dObj.GetProperties().Find(L"geomapprox", geomapprox) == CStatus::OK) + { + Property p(geomapprox); + subd = p.GetParameterValue(L"gapproxmosl"); + } + + // add it to the list + PolygonMesh pmesh(geom); + mXsiPolygonMeshList.insert( + new PolygonMeshEntry(x3dObj.GetName(), x3dObj.GetKinematics().GetGlobal().GetTransform(), pmesh.GetGeometryAccessor(siConstructionModeSecondaryShape, siCatmullClark, subd))); + + LogOgreAndXSI(L"-- Queueing " + name) ; + } + } + + } + + // Cascade into children + if (recurse) + { + CRefArray children = x3dObj.GetChildren(); + + for(long i = 0; i < children.GetCount(); i++) + { + X3DObject childObj = children[i]; + findPolygonMeshes(childObj, recurse); + } + } + + } + //----------------------------------------------------------------------- + void XsiMeshExporter::cleanupPolygonMeshList(void) + { + for (PolygonMeshList::iterator pm = mXsiPolygonMeshList.begin(); + pm != mXsiPolygonMeshList.end(); ++pm) + { + delete *pm; + } + mXsiPolygonMeshList.clear(); + } + //----------------------------------------------------------------------- + void XsiMeshExporter::cleanupDeformerMap(void) + { + for (DeformerMap::iterator d = mXsiDeformerMap.begin(); + d != mXsiDeformerMap.end(); ++d) + { + delete d->second; + } + mXsiDeformerMap.clear(); + } + //----------------------------------------------------------------------- + void XsiMeshExporter::cleanupMaterialMap(void) + { + for (MaterialMap::iterator d = mXsiMaterialMap.begin(); + d != mXsiMaterialMap.end(); ++d) + { + delete d->second; + } + mXsiMaterialMap.clear(); + } + //----------------------------------------------------------------------- + void XsiMeshExporter::deriveSamplerIndices(const Triangle& tri, + const PolygonFace& face, size_t* samplerIndices) + { + //We want to find what is the SampleIndex associated with 3 + //vertex in a Triangle + CPointRefArray facePoints = face.GetPoints(); + + //Get the position of the 3 vertex in the triangle + MATH::CVector3Array triPos = tri.GetPositionArray(); + + //Get the position of the N Points in the polygon + MATH::CVector3Array facePos = facePoints.GetPositionArray(); + + //To know if the 3 vertex have a point in the same position + bool found[3]; + found[0] = false; + found[1] = false; + found[2] = false; + + int p,t; + //For the 3 triangle vertices + for(t=0; t<3 ; t++) + { //for each polygon point + for(p=0; psecond; - } - mXsiDeformerMap.clear(); - } - //----------------------------------------------------------------------- - void XsiMeshExporter::cleanupMaterialMap(void) - { - for (MaterialMap::iterator d = mXsiMaterialMap.begin(); - d != mXsiMaterialMap.end(); ++d) - { - delete d->second; - } - mXsiMaterialMap.clear(); - } - //----------------------------------------------------------------------- - void XsiMeshExporter::deriveSamplerIndices(const Triangle& tri, - const PolygonFace& face, size_t* samplerIndices) - { - //We want to find what is the SampleIndex associated with 3 - //vertex in a Triangle - CPointRefArray facePoints = face.GetPoints(); - - //Get the position of the 3 vertex in the triangle - MATH::CVector3Array triPos = tri.GetPositionArray(); - - //Get the position of the N Points in the polygon - MATH::CVector3Array facePos = facePoints.GetPositionArray(); - - //To know if the 3 vertex have a point in the same position - bool found[3]; - found[0] = false; - found[1] = false; - found[2] = false; - - int p,t; - //For the 3 triangle vertices - for(t=0; t<3 ; t++) - { //for each polygon point - for(p=0; p void XsiMeshExporter::writeIndexes(T* buf, IndexList& indexes) @@ -1443,21 +1443,21 @@ namespace Ogre { } //----------------------------------------------------------------------- void XsiMeshExporter::createVertexBuffer(VertexData* vd, - unsigned short bufIdx, UniqueVertexList& uniqueVertexList) + unsigned short bufIdx, UniqueVertexList& uniqueVertexList) { HardwareVertexBufferSharedPtr vbuf = - HardwareBufferManager::getSingleton().createVertexBuffer( - vd->vertexDeclaration->getVertexSize(bufIdx), - vd->vertexCount, - HardwareBuffer::HBU_STATIC_WRITE_ONLY); + HardwareBufferManager::getSingleton().createVertexBuffer( + vd->vertexDeclaration->getVertexSize(bufIdx), + vd->vertexCount, + HardwareBuffer::HBU_STATIC_WRITE_ONLY); vd->vertexBufferBinding->setBinding(bufIdx, vbuf); size_t vertexSize = vd->vertexDeclaration->getVertexSize(bufIdx); char* pBase = static_cast( - vbuf->lock(HardwareBuffer::HBL_DISCARD)); + vbuf->lock(HardwareBuffer::HBL_DISCARD)); VertexDeclaration::VertexElementList elems = - vd->vertexDeclaration->findElementsBySource(bufIdx); + vd->vertexDeclaration->findElementsBySource(bufIdx); VertexDeclaration::VertexElementList::iterator ei, eiend; eiend = elems.end(); float* pFloat; @@ -1490,11 +1490,11 @@ namespace Ogre { break; case VES_TEXTURE_COORDINATES: elem.baseVertexPointerToElement(pBase, &pFloat); - for (int t = 0; t < VertexElement::getTypeCount(elem.getType()); ++t) - { - Real val = srci->uv[elem.getIndex()][t]; - *pFloat++ = val; - } + for (int t = 0; t < VertexElement::getTypeCount(elem.getType()); ++t) + { + Real val = srci->uv[elem.getIndex()][t]; + *pFloat++ = val; + } break; } } @@ -1505,90 +1505,90 @@ namespace Ogre { } //----------------------------------------------------------------------- size_t XsiMeshExporter::createOrRetrieveUniqueVertex( - ProtoSubMesh* proto, size_t positionIndex, - bool positionIndexIsOriginal, const UniqueVertex& vertex) + ProtoSubMesh* proto, size_t positionIndex, + bool positionIndexIsOriginal, const UniqueVertex& vertex) { - size_t lookupIndex; - if (positionIndexIsOriginal) - { - // look up the original index - IndexRemap::iterator remapi = - proto->posIndexRemap.find(positionIndex); - if (remapi == proto->posIndexRemap.end()) - { - // not found, add - size_t realIndex = proto->uniqueVertices.size(); - // add remap entry so we can find this again - proto->posIndexRemap[positionIndex] = realIndex; - proto->uniqueVertices.push_back(vertex); - return realIndex; - } - else - { - // Found existing mapping - lookupIndex = remapi->second; - } - } - else - { - // Not an original index, index is real - lookupIndex = positionIndex; - } - - // If we get here, either the position isn't an original index (ie - // we've already found that it doesn't match, and have cascaded) - // or there is an existing entry - // Get existing - UniqueVertex& orig = proto->uniqueVertices[lookupIndex]; - // Compare, do we have the same details? - if (orig == vertex) - { - // ok, they match - return lookupIndex; - } - else - { - // no match, go to next or create new - if (orig.nextIndex) - { - // cascade to the next candidate (which is a real index, not an original) + size_t lookupIndex; + if (positionIndexIsOriginal) + { + // look up the original index + IndexRemap::iterator remapi = + proto->posIndexRemap.find(positionIndex); + if (remapi == proto->posIndexRemap.end()) + { + // not found, add + size_t realIndex = proto->uniqueVertices.size(); + // add remap entry so we can find this again + proto->posIndexRemap[positionIndex] = realIndex; + proto->uniqueVertices.push_back(vertex); + return realIndex; + } + else + { + // Found existing mapping + lookupIndex = remapi->second; + } + } + else + { + // Not an original index, index is real + lookupIndex = positionIndex; + } + + // If we get here, either the position isn't an original index (ie + // we've already found that it doesn't match, and have cascaded) + // or there is an existing entry + // Get existing + UniqueVertex& orig = proto->uniqueVertices[lookupIndex]; + // Compare, do we have the same details? + if (orig == vertex) + { + // ok, they match + return lookupIndex; + } + else + { + // no match, go to next or create new + if (orig.nextIndex) + { + // cascade to the next candidate (which is a real index, not an original) return createOrRetrieveUniqueVertex( - proto, orig.nextIndex, false, vertex); + proto, orig.nextIndex, false, vertex); } - else - { - // No more cascades to check, must be a new one - // get new index - size_t realIndex = proto->uniqueVertices.size(); - orig.nextIndex = realIndex; - // create new (NB invalidates 'orig' reference) + else + { + // No more cascades to check, must be a new one + // get new index + size_t realIndex = proto->uniqueVertices.size(); + orig.nextIndex = realIndex; + // create new (NB invalidates 'orig' reference) proto->uniqueVertices.push_back(vertex); - // note, don't add to remap, that's only for finding the - // first entry, nextIndex is used to chain to the others + // note, don't add to remap, that's only for finding the + // first entry, nextIndex is used to chain to the others - return realIndex; - } - } + return realIndex; + } + } } //----------------------------------------------------------------------- - void XsiMeshExporter::registerMaterial(const String& name, - XSI::Material mat) - { - // Check we have a real-time shader based material first - XSI::Parameter rtParam = mat.GetParameter(L"RealTime"); - - if(rtParam.GetSource().IsValid() && - rtParam.GetSource().IsA(XSI::siShaderID)) - { - MaterialMap::iterator i = mXsiMaterialMap.find(name); - if (i == mXsiMaterialMap.end()) - { - // Add this one to the list - MaterialEntry* matEntry = new MaterialEntry(); - matEntry->name = name; - matEntry->xsiShader = XSI::Shader(rtParam.GetSource()); - mXsiMaterialMap[name] = matEntry; - } - } - } + void XsiMeshExporter::registerMaterial(const String& name, + XSI::Material mat) + { + // Check we have a real-time shader based material first + XSI::Parameter rtParam = mat.GetParameter(L"RealTime"); + + if(rtParam.GetSource().IsValid() && + rtParam.GetSource().IsA(XSI::siShaderID)) + { + MaterialMap::iterator i = mXsiMaterialMap.find(name); + if (i == mXsiMaterialMap.end()) + { + // Add this one to the list + MaterialEntry* matEntry = new MaterialEntry(); + matEntry->name = name; + matEntry->xsiShader = XSI::Shader(rtParam.GetSource()); + mXsiMaterialMap[name] = matEntry; + } + } + } } diff --git a/Tools/XSIExport/src/OgreXSISkeletonExporter.cpp b/Tools/XSIExport/src/OgreXSISkeletonExporter.cpp index 9154e144b6c..782de2836e2 100644 --- a/Tools/XSIExport/src/OgreXSISkeletonExporter.cpp +++ b/Tools/XSIExport/src/OgreXSISkeletonExporter.cpp @@ -61,487 +61,487 @@ using namespace XSI; namespace Ogre { - //----------------------------------------------------------------------------- - XsiSkeletonExporter::XsiSkeletonExporter() - { - mXsiSceneRoot = X3DObject(mXsiApp.GetActiveSceneRoot()); - mXSITrackTypeNames["posx"] = XTT_POS_X; - mXSITrackTypeNames["posy"] = XTT_POS_Y; - mXSITrackTypeNames["posz"] = XTT_POS_Z; - mXSITrackTypeNames["rotx"] = XTT_ROT_X; - mXSITrackTypeNames["roty"] = XTT_ROT_Y; - mXSITrackTypeNames["rotz"] = XTT_ROT_Z; - mXSITrackTypeNames["sclx"] = XTT_SCL_X; - mXSITrackTypeNames["scly"] = XTT_SCL_Y; - mXSITrackTypeNames["sclz"] = XTT_SCL_Z; - } - //----------------------------------------------------------------------------- - XsiSkeletonExporter::~XsiSkeletonExporter() - { - } - //----------------------------------------------------------------------------- - const AxisAlignedBox& XsiSkeletonExporter::exportSkeleton(const String& skeletonFileName, - DeformerMap& deformers, float framesPerSecond, AnimationList& animList) - { - LogOgreAndXSI(L"** Begin OGRE Skeleton Export **"); - - copyDeformerMap(deformers); - - SkeletonPtr skeleton = SkeletonManager::getSingleton().create("export", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); - // construct the hierarchy - buildBoneHierarchy(skeleton.get(), deformers, animList); - - // progress report - ProgressManager::getSingleton().progress(); - - establishInitialTransforms(deformers); - - // create animations - mAABB.setNull(); - createAnimations(skeleton.get(), deformers, framesPerSecond, animList, mAABB); - // progress report - ProgressManager::getSingleton().progress(); - - // Optimise - skeleton->optimiseAllAnimations(); - - SkeletonSerializer ser; - ser.exportSkeleton(skeleton.get(), skeletonFileName); - // progress report - ProgressManager::getSingleton().progress(); - - LogOgreAndXSI(L"** OGRE Skeleton Export Complete **"); - - cleanup(); - - return mAABB; - - } - //----------------------------------------------------------------------------- - void XsiSkeletonExporter::copyDeformerMap(DeformerMap& deformers) - { - // Make lower-case version - // some XSI animations appear to like to use case insensitive references :( - for (DeformerMap::iterator i = deformers.begin(); i != deformers.end(); ++i) - { - DeformerEntry* deformer = i->second; - String name = XSItoOgre(deformer->obj.GetName()); - StringUtil::toLowerCase(name); - mLowerCaseDeformerMap[name] = deformer; - } - } - //----------------------------------------------------------------------------- - void XsiSkeletonExporter::buildBoneHierarchy(Skeleton* pSkeleton, - DeformerMap& deformers, AnimationList& animList) - { - /// Copy all entries from map into a list so iterators won't get invalidated - std::list deformerList; - LogOgreAndXSI(L"-- Bones with vertex assignments:"); - for (DeformerMap::iterator i = deformers.begin(); i != deformers.end(); ++i) - { - DeformerEntry* deformer = i->second; - deformerList.push_back(deformer); - LogOgreAndXSI(deformer->obj.GetName()); - } - - /* XSI allows you to use any object at all as a bone, not just chain elements. - A typical choice is a hierarchy of nulls, for example. In order to - build a skeleton hierarchy which represents the actual one, we need - to find the relationships between all the deformers that we found. - - Well do this by navigating up the scene tree from each bone, looking for - a match in the existing bone list or creating a new one where we need it - to reach the root. We add bones even if they're not assigned vertices - because the animation may depend on them. If the - traversal hits the scene root this bone is clearly a root bone - (there may be more than one). - */ - for (std::list::iterator i = deformerList.begin(); i != deformerList.end(); ++i) - { - DeformerEntry* deformer = *i; - if (deformer->parentName.empty()) - { - linkBoneWithParent(deformer, deformers, deformerList); - } - } - - // Now eliminate all bones without any animated kine parameters - // Need to do this after we've determined all relationships - for (std::list::iterator i = deformerList.begin(); i != deformerList.end(); ++i) - { - DeformerEntry* deformer = *i; - validateAsBone(pSkeleton, deformer, deformers, deformerList, animList); - } - - // Now link - for (DeformerMap::iterator i = deformers.begin(); i != deformers.end(); ++i) - { - DeformerEntry* deformer = i->second; - - // link to parent - if (!deformer->parentName.empty()) - { - DeformerEntry* parent = getDeformer(deformer->parentName, deformers); - assert (parent && "Parent not found"); - assert (deformer->pBone && "Child bone not created"); - assert(parent->pBone && "Parent bone not created"); - parent->pBone->addChild(deformer->pBone); - - } - } - - } - //----------------------------------------------------------------------------- - DeformerEntry* XsiSkeletonExporter::getDeformer(const String& name, - DeformerMap& deformers) - { - // Look in case sensitive list first - DeformerMap::iterator i = deformers.find(name); - if (i == deformers.end()) - { - String lcaseName = name; - StringUtil::toLowerCase(lcaseName); - i = mLowerCaseDeformerMap.find(lcaseName); - if (i == mLowerCaseDeformerMap.end()) - { - return 0; - } - else - { - return i->second; - } - } - else - { - return i->second; - } - - } - //----------------------------------------------------------------------------- - void XsiSkeletonExporter::linkBoneWithParent(DeformerEntry* child, - DeformerMap& deformers, std::list& deformerList) - { - X3DObject parent(child->obj.GetParent()); - String childName = XSItoOgre(child->obj.GetName()); - - if (child->obj == mXsiSceneRoot /* safety check for start node */) - return; - - // Check for parenting by a chain end effector - // These are sneaky little buggers - we actually want to attach the - // child to the end of the final bone in the chain - if (parent.IsA(XSI::siChainEffectorID)) - { - ChainEffector effector(parent); - CRefArray chainBones = effector.GetRoot().GetBones(); - // get the last - parent = chainBones[chainBones.GetCount()-1]; - child->parentIsChainEndEffector = true; - - } - // is the parent the scene root? - if (parent == mXsiSceneRoot) - { - // we hit the root node - } - else - { - - String parentName = XSItoOgre(parent.GetName()); - // Otherwise, check to see if the parent is in the deformer list - DeformerEntry* parentDeformer = getDeformer(parentName, deformers); - if (!parentDeformer) - { - // not found, create entry for parent - parentDeformer = new DeformerEntry(deformers.size(), parent); - deformers[parentName] = parentDeformer; - deformerList.push_back(parentDeformer); - LogOgreAndXSI(CString(L"Added ") + parent.GetName() + - CString(L" as a parent of ") + child->obj.GetName() ); - } - - // Link child entry with parent (not bone yet) - // link child to parent by name - child->parentName = parentName; - parentDeformer->childNames.push_back(childName); - - - - - } - - } - //----------------------------------------------------------------------------- - void XsiSkeletonExporter::validateAsBone(Skeleton* pSkeleton, - DeformerEntry* deformer, - DeformerMap& deformers, std::list& deformerList, - AnimationList& animList) - { - /* The purpose of this method is to find out whether a node in the - bone hierarchy is animated, and if not, to eliminate it and propagate - it's static transform contribution to it's children. - We do this because it's quite easy in XSI to build deep bone chains - with intermediate points that are only used for manipulation. We - don't want to include all of those. - */ - - // TODO - - - // if we weren't static, create bone - if (!deformer->pBone) - { - String name = XSItoOgre(deformer->obj.GetName()); - deformer->pBone = pSkeleton->createBone(name, deformer->boneID); - MATH::CTransformation trans; - - if (deformer->parentName.empty()) - { - // set transform on bone to global transform since no parents - trans = deformer->obj.GetKinematics().GetGlobal().GetTransform(); - } - else - { - // set transform on bone to local transform (since child) - trans = deformer->obj.GetKinematics().GetLocal().GetTransform(); - } - deformer->pBone->setPosition(XSItoOgre(trans.GetTranslation())); - deformer->pBone->setOrientation(XSItoOgre(trans.GetRotation().GetQuaternion())); - deformer->pBone->setScale(XSItoOgre(trans.GetScaling())); - - // special case a bone which is parented by a chain end - if (deformer->parentIsChainEndEffector) - { - ChainEffector effector(deformer->obj.GetParent()); - CRefArray chainBones = effector.GetRoot().GetBones(); - // get the last - X3DObject endBone = chainBones[chainBones.GetCount()-1]; - // offset along X the length of the bone - double boneLen = endBone.GetParameterValue(L"Length"); - deformer->pBone->setPosition( - deformer->pBone->getPosition() + Vector3::UNIT_X * boneLen); - } - - } - - } - //----------------------------------------------------------------------------- - void XsiSkeletonExporter::processActionSource(const XSI::ActionSource& actSource, - DeformerMap& deformers) - { - // Clear existing deformer links - for(DeformerMap::iterator di = deformers.begin(); di != deformers.end(); ++di) - { - for (int tt = XTT_POS_X; tt < XTT_COUNT; ++tt) - { - di->second->xsiTrack[tt].ResetObject(); - } - } - // Get all the items - CRefArray items = actSource.GetItems(); - for (int i = 0; i < items.GetCount(); ++i) - { - XSI::AnimationSourceItem item = items[i]; - - // Check the target - String target = XSItoOgre(item.GetTarget()); - size_t firstDotPos = target.find_first_of("."); - size_t lastDotPos = target.find_last_of("."); - if (firstDotPos != String::npos && lastDotPos != String::npos) - { - String targetName = target.substr(0, firstDotPos); - String paramName = target.substr(lastDotPos+1, - target.size() - lastDotPos - 1); - // locate deformer - DeformerEntry* deformer = getDeformer(targetName, deformers); - if (deformer) - { - // determine parameter - std::map::iterator pi = mXSITrackTypeNames.find(paramName); - if (pi != mXSITrackTypeNames.end()) - { - deformer->xsiTrack[pi->second] = item; - deformer->hasAnyTracks = true; - } - } - } - - } - } - //----------------------------------------------------------------------------- - void XsiSkeletonExporter::createAnimations(Skeleton* pSkel, - DeformerMap& deformers, float fps, AnimationList& animList, AxisAlignedBox& AABBPadding) - { - for (AnimationList::iterator ai = animList.begin(); ai != animList.end(); ++ai) - { - AnimationEntry& animEntry = *ai; - - // Note that we don't know if this time period includes bone animation - // but we sample it anyway just in case; animation optimisation will - // eliminate anything that's redundant - // A little wasteful perhaps, but it's the only guaranteed way to pick - // up all the potentially derived effects on deformers - - float animLength = (float)(animEntry.endFrame - animEntry.startFrame) / fps; - StringStream str; - str << "Creating animation " << animEntry.animationName << - " with length " << animLength << " seconds"; - LogOgreAndXSI(str.str()); - Animation* anim = pSkel->createAnimation(animEntry.animationName, animLength); - - createAnimationTracksSampled(anim, animEntry, deformers, fps, AABBPadding); - - } - } - //----------------------------------------------------------------------------- - void XsiSkeletonExporter::createAnimationTracksSampled(Animation* pAnim, - AnimationEntry& animEntry, DeformerMap& deformers, float fps, AxisAlignedBox& AABBPadding) - { - - // Create all tracks first - std::vector deformerTracks; - deformerTracks.resize(deformers.size()); - for (DeformerMap::iterator di = deformers.begin(); di != deformers.end(); ++di) - { - DeformerEntry* deformer = di->second; - NodeAnimationTrack* track = pAnim->createNodeTrack(deformer->boneID, deformer->pBone); - deformerTracks[deformer->boneID] = track; - } - - // Iterate over frames, keying as we go - long numFrames = animEntry.endFrame - animEntry.startFrame; - if (animEntry.ikSampleInterval == 0) - { - // Don't allow zero samplign frequency - infinite loop! - animEntry.ikSampleInterval = 5.0f; - } - - // Sample all bones from start to before the end frame - for (long frame = animEntry.startFrame; frame < animEntry.endFrame; - frame += animEntry.ikSampleInterval) - { - Real time = (float)(frame - animEntry.startFrame) / fps; - sampleAllBones(deformers, deformerTracks, frame, time, fps, AABBPadding); - - } - // sample final frame (must be guaranteed to be done) - Real time = (float)(animEntry.endFrame - animEntry.startFrame) / fps; - sampleAllBones(deformers, deformerTracks, animEntry.endFrame, time, fps, AABBPadding); - - - } - //----------------------------------------------------------------------------- - void XsiSkeletonExporter::establishInitialTransforms(DeformerMap& deformers) - { - for (DeformerMap::iterator di = deformers.begin(); di != deformers.end(); ++di) - { - DeformerEntry* deformer = di->second; - if (deformer->pBone->getParent() == 0) - { - // Based on global - deformer->initialXform = - deformer->obj.GetKinematics().GetGlobal().GetTransform(); - } - else - { - // Based on local - deformer->initialXform = - deformer->obj.GetKinematics().GetLocal().GetTransform(); - } - - } - } - //----------------------------------------------------------------------------- - void XsiSkeletonExporter::sampleAllBones(DeformerMap& deformers, - std::vector deformerTracks, double frame, - Real time, float fps, AxisAlignedBox& AABBPadding) - { - CValueArray args; - CValue dummy; - args.Resize(2); - // set the playcontrol - args[0] = L"PlayControl.Key"; - args[1] = frame; - mXsiApp.ExecuteCommand(L"SetValue", args, dummy); - args[0] = L"PlayControl.Current"; - mXsiApp.ExecuteCommand(L"SetValue", args, dummy); - - // Refresh - mXsiApp.ExecuteCommand(L"Refresh", CValueArray(), dummy); - // Sample all bones - for (DeformerMap::iterator di = deformers.begin(); di != deformers.end(); ++di) - { - DeformerEntry* deformer = di->second; - NodeAnimationTrack* track = deformerTracks[deformer->boneID]; - - double initposx, initposy, initposz; - deformer->initialXform.GetTranslationValues(initposx, initposy, initposz); - double initrotx, initroty, initrotz; - deformer->initialXform.GetRotation().GetXYZAngles(initrotx, initroty, initrotz); - double initsclx, initscly, initsclz; - deformer->initialXform.GetScalingValues(initsclx, initscly, initsclz); - XSI::MATH::CMatrix4 invTrans = deformer->initialXform.GetMatrix4(); - invTrans.InvertInPlace(); - - XSI::MATH::CTransformation transformation; - if (deformer->pBone->getParent() == 0) - { - // Based on global - transformation = - deformer->obj.GetKinematics().GetGlobal().GetTransform(); - } - else - { - // Based on local - transformation = - deformer->obj.GetKinematics().GetLocal().GetTransform(); - } - - double posx, posy, posz; - transformation.GetTranslationValues(posx, posy, posz); - double sclx, scly, sclz; - transformation.GetScalingValues(sclx, scly, sclz); - - // Make relative to initial - XSI::MATH::CMatrix4 transformationMatrix = transformation.GetMatrix4(); - transformationMatrix.MulInPlace(invTrans); - transformation.SetMatrix4(transformationMatrix); - - // create keyframe - TransformKeyFrame* kf = track->createNodeKeyFrame(time); - // not sure why inverted transform doesn't work for position, but it doesn't - // I thought XSI used same transform order as OGRE - kf->setTranslate(Vector3(posx - initposx, posy - initposy, posz - initposz)); - kf->setRotation(XSItoOgre(transformation.GetRotationQuaternion())); - kf->setScale(Vector3(sclx / initsclx, scly / initscly, sclz / initsclz)); - - // Derive AABB of bone positions, for padding animated mesh AABB - XSI::MATH::CVector3 bonePos = - deformer->obj.GetKinematics().GetGlobal().GetTransform().GetTranslation(); - AABBPadding.merge(XSItoOgre(bonePos)); - - - - } - - } - //----------------------------------------------------------------------------- - void XsiSkeletonExporter::cleanup(void) - { - - mLowerCaseDeformerMap.clear(); - - CValueArray args; - CValue dummy; - args.Resize(1); - - for (int i = 0; i < mIKSampledAnimations.GetCount(); ++i) - { - args[0] = mIKSampledAnimations[i]; - mXsiApp.ExecuteCommand(L"DeleteObj", args, dummy); - } - mIKSampledAnimations.Clear(); - - } + //----------------------------------------------------------------------------- + XsiSkeletonExporter::XsiSkeletonExporter() + { + mXsiSceneRoot = X3DObject(mXsiApp.GetActiveSceneRoot()); + mXSITrackTypeNames["posx"] = XTT_POS_X; + mXSITrackTypeNames["posy"] = XTT_POS_Y; + mXSITrackTypeNames["posz"] = XTT_POS_Z; + mXSITrackTypeNames["rotx"] = XTT_ROT_X; + mXSITrackTypeNames["roty"] = XTT_ROT_Y; + mXSITrackTypeNames["rotz"] = XTT_ROT_Z; + mXSITrackTypeNames["sclx"] = XTT_SCL_X; + mXSITrackTypeNames["scly"] = XTT_SCL_Y; + mXSITrackTypeNames["sclz"] = XTT_SCL_Z; + } + //----------------------------------------------------------------------------- + XsiSkeletonExporter::~XsiSkeletonExporter() + { + } + //----------------------------------------------------------------------------- + const AxisAlignedBox& XsiSkeletonExporter::exportSkeleton(const String& skeletonFileName, + DeformerMap& deformers, float framesPerSecond, AnimationList& animList) + { + LogOgreAndXSI(L"** Begin OGRE Skeleton Export **"); + + copyDeformerMap(deformers); + + SkeletonPtr skeleton = SkeletonManager::getSingleton().create("export", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + // construct the hierarchy + buildBoneHierarchy(skeleton.get(), deformers, animList); + + // progress report + ProgressManager::getSingleton().progress(); + + establishInitialTransforms(deformers); + + // create animations + mAABB.setNull(); + createAnimations(skeleton.get(), deformers, framesPerSecond, animList, mAABB); + // progress report + ProgressManager::getSingleton().progress(); + + // Optimise + skeleton->optimiseAllAnimations(); + + SkeletonSerializer ser; + ser.exportSkeleton(skeleton.get(), skeletonFileName); + // progress report + ProgressManager::getSingleton().progress(); + + LogOgreAndXSI(L"** OGRE Skeleton Export Complete **"); + + cleanup(); + + return mAABB; + + } + //----------------------------------------------------------------------------- + void XsiSkeletonExporter::copyDeformerMap(DeformerMap& deformers) + { + // Make lower-case version + // some XSI animations appear to like to use case insensitive references :( + for (DeformerMap::iterator i = deformers.begin(); i != deformers.end(); ++i) + { + DeformerEntry* deformer = i->second; + String name = XSItoOgre(deformer->obj.GetName()); + StringUtil::toLowerCase(name); + mLowerCaseDeformerMap[name] = deformer; + } + } + //----------------------------------------------------------------------------- + void XsiSkeletonExporter::buildBoneHierarchy(Skeleton* pSkeleton, + DeformerMap& deformers, AnimationList& animList) + { + /// Copy all entries from map into a list so iterators won't get invalidated + std::list deformerList; + LogOgreAndXSI(L"-- Bones with vertex assignments:"); + for (DeformerMap::iterator i = deformers.begin(); i != deformers.end(); ++i) + { + DeformerEntry* deformer = i->second; + deformerList.push_back(deformer); + LogOgreAndXSI(deformer->obj.GetName()); + } + + /* XSI allows you to use any object at all as a bone, not just chain elements. + A typical choice is a hierarchy of nulls, for example. In order to + build a skeleton hierarchy which represents the actual one, we need + to find the relationships between all the deformers that we found. + + Well do this by navigating up the scene tree from each bone, looking for + a match in the existing bone list or creating a new one where we need it + to reach the root. We add bones even if they're not assigned vertices + because the animation may depend on them. If the + traversal hits the scene root this bone is clearly a root bone + (there may be more than one). + */ + for (std::list::iterator i = deformerList.begin(); i != deformerList.end(); ++i) + { + DeformerEntry* deformer = *i; + if (deformer->parentName.empty()) + { + linkBoneWithParent(deformer, deformers, deformerList); + } + } + + // Now eliminate all bones without any animated kine parameters + // Need to do this after we've determined all relationships + for (std::list::iterator i = deformerList.begin(); i != deformerList.end(); ++i) + { + DeformerEntry* deformer = *i; + validateAsBone(pSkeleton, deformer, deformers, deformerList, animList); + } + + // Now link + for (DeformerMap::iterator i = deformers.begin(); i != deformers.end(); ++i) + { + DeformerEntry* deformer = i->second; + + // link to parent + if (!deformer->parentName.empty()) + { + DeformerEntry* parent = getDeformer(deformer->parentName, deformers); + assert (parent && "Parent not found"); + assert (deformer->pBone && "Child bone not created"); + assert(parent->pBone && "Parent bone not created"); + parent->pBone->addChild(deformer->pBone); + + } + } + + } + //----------------------------------------------------------------------------- + DeformerEntry* XsiSkeletonExporter::getDeformer(const String& name, + DeformerMap& deformers) + { + // Look in case sensitive list first + DeformerMap::iterator i = deformers.find(name); + if (i == deformers.end()) + { + String lcaseName = name; + StringUtil::toLowerCase(lcaseName); + i = mLowerCaseDeformerMap.find(lcaseName); + if (i == mLowerCaseDeformerMap.end()) + { + return 0; + } + else + { + return i->second; + } + } + else + { + return i->second; + } + + } + //----------------------------------------------------------------------------- + void XsiSkeletonExporter::linkBoneWithParent(DeformerEntry* child, + DeformerMap& deformers, std::list& deformerList) + { + X3DObject parent(child->obj.GetParent()); + String childName = XSItoOgre(child->obj.GetName()); + + if (child->obj == mXsiSceneRoot /* safety check for start node */) + return; + + // Check for parenting by a chain end effector + // These are sneaky little buggers - we actually want to attach the + // child to the end of the final bone in the chain + if (parent.IsA(XSI::siChainEffectorID)) + { + ChainEffector effector(parent); + CRefArray chainBones = effector.GetRoot().GetBones(); + // get the last + parent = chainBones[chainBones.GetCount()-1]; + child->parentIsChainEndEffector = true; + + } + // is the parent the scene root? + if (parent == mXsiSceneRoot) + { + // we hit the root node + } + else + { + + String parentName = XSItoOgre(parent.GetName()); + // Otherwise, check to see if the parent is in the deformer list + DeformerEntry* parentDeformer = getDeformer(parentName, deformers); + if (!parentDeformer) + { + // not found, create entry for parent + parentDeformer = new DeformerEntry(deformers.size(), parent); + deformers[parentName] = parentDeformer; + deformerList.push_back(parentDeformer); + LogOgreAndXSI(CString(L"Added ") + parent.GetName() + + CString(L" as a parent of ") + child->obj.GetName() ); + } + + // Link child entry with parent (not bone yet) + // link child to parent by name + child->parentName = parentName; + parentDeformer->childNames.push_back(childName); + + + + + } + + } + //----------------------------------------------------------------------------- + void XsiSkeletonExporter::validateAsBone(Skeleton* pSkeleton, + DeformerEntry* deformer, + DeformerMap& deformers, std::list& deformerList, + AnimationList& animList) + { + /* The purpose of this method is to find out whether a node in the + bone hierarchy is animated, and if not, to eliminate it and propagate + it's static transform contribution to it's children. + We do this because it's quite easy in XSI to build deep bone chains + with intermediate points that are only used for manipulation. We + don't want to include all of those. + */ + + // TODO + + + // if we weren't static, create bone + if (!deformer->pBone) + { + String name = XSItoOgre(deformer->obj.GetName()); + deformer->pBone = pSkeleton->createBone(name, deformer->boneID); + MATH::CTransformation trans; + + if (deformer->parentName.empty()) + { + // set transform on bone to global transform since no parents + trans = deformer->obj.GetKinematics().GetGlobal().GetTransform(); + } + else + { + // set transform on bone to local transform (since child) + trans = deformer->obj.GetKinematics().GetLocal().GetTransform(); + } + deformer->pBone->setPosition(XSItoOgre(trans.GetTranslation())); + deformer->pBone->setOrientation(XSItoOgre(trans.GetRotation().GetQuaternion())); + deformer->pBone->setScale(XSItoOgre(trans.GetScaling())); + + // special case a bone which is parented by a chain end + if (deformer->parentIsChainEndEffector) + { + ChainEffector effector(deformer->obj.GetParent()); + CRefArray chainBones = effector.GetRoot().GetBones(); + // get the last + X3DObject endBone = chainBones[chainBones.GetCount()-1]; + // offset along X the length of the bone + double boneLen = endBone.GetParameterValue(L"Length"); + deformer->pBone->setPosition( + deformer->pBone->getPosition() + Vector3::UNIT_X * boneLen); + } + + } + + } + //----------------------------------------------------------------------------- + void XsiSkeletonExporter::processActionSource(const XSI::ActionSource& actSource, + DeformerMap& deformers) + { + // Clear existing deformer links + for(DeformerMap::iterator di = deformers.begin(); di != deformers.end(); ++di) + { + for (int tt = XTT_POS_X; tt < XTT_COUNT; ++tt) + { + di->second->xsiTrack[tt].ResetObject(); + } + } + // Get all the items + CRefArray items = actSource.GetItems(); + for (int i = 0; i < items.GetCount(); ++i) + { + XSI::AnimationSourceItem item = items[i]; + + // Check the target + String target = XSItoOgre(item.GetTarget()); + size_t firstDotPos = target.find_first_of("."); + size_t lastDotPos = target.find_last_of("."); + if (firstDotPos != String::npos && lastDotPos != String::npos) + { + String targetName = target.substr(0, firstDotPos); + String paramName = target.substr(lastDotPos+1, + target.size() - lastDotPos - 1); + // locate deformer + DeformerEntry* deformer = getDeformer(targetName, deformers); + if (deformer) + { + // determine parameter + std::map::iterator pi = mXSITrackTypeNames.find(paramName); + if (pi != mXSITrackTypeNames.end()) + { + deformer->xsiTrack[pi->second] = item; + deformer->hasAnyTracks = true; + } + } + } + + } + } + //----------------------------------------------------------------------------- + void XsiSkeletonExporter::createAnimations(Skeleton* pSkel, + DeformerMap& deformers, float fps, AnimationList& animList, AxisAlignedBox& AABBPadding) + { + for (AnimationList::iterator ai = animList.begin(); ai != animList.end(); ++ai) + { + AnimationEntry& animEntry = *ai; + + // Note that we don't know if this time period includes bone animation + // but we sample it anyway just in case; animation optimisation will + // eliminate anything that's redundant + // A little wasteful perhaps, but it's the only guaranteed way to pick + // up all the potentially derived effects on deformers + + float animLength = (float)(animEntry.endFrame - animEntry.startFrame) / fps; + StringStream str; + str << "Creating animation " << animEntry.animationName << + " with length " << animLength << " seconds"; + LogOgreAndXSI(str.str()); + Animation* anim = pSkel->createAnimation(animEntry.animationName, animLength); + + createAnimationTracksSampled(anim, animEntry, deformers, fps, AABBPadding); + + } + } + //----------------------------------------------------------------------------- + void XsiSkeletonExporter::createAnimationTracksSampled(Animation* pAnim, + AnimationEntry& animEntry, DeformerMap& deformers, float fps, AxisAlignedBox& AABBPadding) + { + + // Create all tracks first + std::vector deformerTracks; + deformerTracks.resize(deformers.size()); + for (DeformerMap::iterator di = deformers.begin(); di != deformers.end(); ++di) + { + DeformerEntry* deformer = di->second; + NodeAnimationTrack* track = pAnim->createNodeTrack(deformer->boneID, deformer->pBone); + deformerTracks[deformer->boneID] = track; + } + + // Iterate over frames, keying as we go + long numFrames = animEntry.endFrame - animEntry.startFrame; + if (animEntry.ikSampleInterval == 0) + { + // Don't allow zero samplign frequency - infinite loop! + animEntry.ikSampleInterval = 5.0f; + } + + // Sample all bones from start to before the end frame + for (long frame = animEntry.startFrame; frame < animEntry.endFrame; + frame += animEntry.ikSampleInterval) + { + Real time = (float)(frame - animEntry.startFrame) / fps; + sampleAllBones(deformers, deformerTracks, frame, time, fps, AABBPadding); + + } + // sample final frame (must be guaranteed to be done) + Real time = (float)(animEntry.endFrame - animEntry.startFrame) / fps; + sampleAllBones(deformers, deformerTracks, animEntry.endFrame, time, fps, AABBPadding); + + + } + //----------------------------------------------------------------------------- + void XsiSkeletonExporter::establishInitialTransforms(DeformerMap& deformers) + { + for (DeformerMap::iterator di = deformers.begin(); di != deformers.end(); ++di) + { + DeformerEntry* deformer = di->second; + if (deformer->pBone->getParent() == 0) + { + // Based on global + deformer->initialXform = + deformer->obj.GetKinematics().GetGlobal().GetTransform(); + } + else + { + // Based on local + deformer->initialXform = + deformer->obj.GetKinematics().GetLocal().GetTransform(); + } + + } + } + //----------------------------------------------------------------------------- + void XsiSkeletonExporter::sampleAllBones(DeformerMap& deformers, + std::vector deformerTracks, double frame, + Real time, float fps, AxisAlignedBox& AABBPadding) + { + CValueArray args; + CValue dummy; + args.Resize(2); + // set the playcontrol + args[0] = L"PlayControl.Key"; + args[1] = frame; + mXsiApp.ExecuteCommand(L"SetValue", args, dummy); + args[0] = L"PlayControl.Current"; + mXsiApp.ExecuteCommand(L"SetValue", args, dummy); + + // Refresh + mXsiApp.ExecuteCommand(L"Refresh", CValueArray(), dummy); + // Sample all bones + for (DeformerMap::iterator di = deformers.begin(); di != deformers.end(); ++di) + { + DeformerEntry* deformer = di->second; + NodeAnimationTrack* track = deformerTracks[deformer->boneID]; + + double initposx, initposy, initposz; + deformer->initialXform.GetTranslationValues(initposx, initposy, initposz); + double initrotx, initroty, initrotz; + deformer->initialXform.GetRotation().GetXYZAngles(initrotx, initroty, initrotz); + double initsclx, initscly, initsclz; + deformer->initialXform.GetScalingValues(initsclx, initscly, initsclz); + XSI::MATH::CMatrix4 invTrans = deformer->initialXform.GetMatrix4(); + invTrans.InvertInPlace(); + + XSI::MATH::CTransformation transformation; + if (deformer->pBone->getParent() == 0) + { + // Based on global + transformation = + deformer->obj.GetKinematics().GetGlobal().GetTransform(); + } + else + { + // Based on local + transformation = + deformer->obj.GetKinematics().GetLocal().GetTransform(); + } + + double posx, posy, posz; + transformation.GetTranslationValues(posx, posy, posz); + double sclx, scly, sclz; + transformation.GetScalingValues(sclx, scly, sclz); + + // Make relative to initial + XSI::MATH::CMatrix4 transformationMatrix = transformation.GetMatrix4(); + transformationMatrix.MulInPlace(invTrans); + transformation.SetMatrix4(transformationMatrix); + + // create keyframe + TransformKeyFrame* kf = track->createNodeKeyFrame(time); + // not sure why inverted transform doesn't work for position, but it doesn't + // I thought XSI used same transform order as OGRE + kf->setTranslate(Vector3(posx - initposx, posy - initposy, posz - initposz)); + kf->setRotation(XSItoOgre(transformation.GetRotationQuaternion())); + kf->setScale(Vector3(sclx / initsclx, scly / initscly, sclz / initsclz)); + + // Derive AABB of bone positions, for padding animated mesh AABB + XSI::MATH::CVector3 bonePos = + deformer->obj.GetKinematics().GetGlobal().GetTransform().GetTranslation(); + AABBPadding.merge(XSItoOgre(bonePos)); + + + + } + + } + //----------------------------------------------------------------------------- + void XsiSkeletonExporter::cleanup(void) + { + + mLowerCaseDeformerMap.clear(); + + CValueArray args; + CValue dummy; + args.Resize(1); + + for (int i = 0; i < mIKSampledAnimations.GetCount(); ++i) + { + args[0] = mIKSampledAnimations[i]; + mXsiApp.ExecuteCommand(L"DeleteObj", args, dummy); + } + mIKSampledAnimations.Clear(); + + } } diff --git a/Tools/dotXSIConverter/include/Exporter.h b/Tools/dotXSIConverter/include/Exporter.h index 13d9c2ac670..7692a8ef8c2 100644 --- a/Tools/dotXSIConverter/include/Exporter.h +++ b/Tools/dotXSIConverter/include/Exporter.h @@ -25,7 +25,7 @@ class Exporter { void exportMesh(std::string fileName, std::string skelName); /* Function to perform an export to Ogre .skeleton. */ void exportBones(std::string fileName); - + protected: /* Internal recursive method for exporting a node in the scene */ void exportCSLModel(Ogre::Mesh* pMesh, CSLModel* XSIModel); @@ -35,7 +35,7 @@ class Exporter { void recurseBones(Skeleton* pSkel, CSLModel* XSIModel); /* Exports animation tracks */ void exportAnim(Skeleton* pSkel, CSLModel* XSIModel); - + /* XSI Scene */ CSLModel* SceneRoot; int boneCount; diff --git a/Tools/dotXSIConverter/src/Exporter.cpp b/Tools/dotXSIConverter/src/Exporter.cpp index c6a34351a91..bc78e55ecad 100644 --- a/Tools/dotXSIConverter/src/Exporter.cpp +++ b/Tools/dotXSIConverter/src/Exporter.cpp @@ -87,7 +87,7 @@ void Exporter::exportCSLModel(Mesh* pMesh, CSLModel* XSIModel) { if (XSIModel->GetPrimitiveType() == CSLTemplate::SI_MESH) exportSubMesh(pMesh, (CSLMesh *) XSIModel->Primitive()); - + CSLModel* *l_childrenList = XSIModel->GetChildrenList(); // Loop through all children @@ -102,7 +102,7 @@ void Exporter::exportSubMesh(Mesh *pMesh, CSLMesh* XSIMesh) { SubMesh* sm = 0; sm = pMesh->createSubMesh(XSIMesh->GetName()); - + // HACK: No materials exporter yet, I hard coded this, wrong as hell, but did it anyway // For now, I'm just creating the materials file manually. sm->setMaterialName("Examples/Woman"); @@ -152,7 +152,7 @@ void Exporter::exportSubMesh(Mesh *pMesh, CSLMesh* XSIMesh) // We are assuming 1 UV -- in our files, number of UV's = number of Normals vertex.uv[0] = Vector2(uv.GetX(), (1 - uv.GetY())); - + if (hasVertexColors) vertex.color = triArray->GetColorIndicesPtr()[t*3+p]; size_t index = createOrRetrieveUniqueVertex(triArray->GetVertexIndicesPtr()[t*3+p], vertex); @@ -195,7 +195,7 @@ void Exporter::exportSubMesh(Mesh *pMesh, CSLMesh* XSIMesh) sm->vertexData->vertexDeclaration->addElement(buf, offset, VET_FLOAT3, VES_NORMAL); offset += VertexElement::getTypeSize(VET_FLOAT3); // TODO: Split Vertex Data if animated - + if (hasVertexColors) { sm->vertexData->vertexDeclaration->addElement(buf, offset, VET_COLOUR, VES_DIFFUSE); @@ -238,7 +238,7 @@ void Exporter::exportSubMesh(Mesh *pMesh, CSLMesh* XSIMesh) pMesh->_setBounds(box); pMesh->_setBoundingSphereRadius(std::max(pMesh->getBoundingSphereRadius(), Math::Sqrt(squaredRadius))); - + // Get Envelope list for this submesh CSLEnvelope** envelopes = XSIMesh->ParentModel()->GetEnvelopeList(); CSLEnvelope* env = 0; @@ -257,9 +257,9 @@ void Exporter::exportSubMesh(Mesh *pMesh, CSLMesh* XSIMesh) continue; break; } - + SLVertexWeight* wtList = env->GetVertexWeightListPtr(); - + // Go through all collocated vertices, assigning the same weights to each. // All the dotXSI files I've seen normalize the weights to 100, so for now // I'm just dividing by 100. TODO: Insert code to handle normalization @@ -280,7 +280,7 @@ void Exporter::exportSubMesh(Mesh *pMesh, CSLMesh* XSIMesh) } } } - + // Last step here is to reorganise the vertex buffers VertexDeclaration* newDecl = sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(true); @@ -288,7 +288,7 @@ void Exporter::exportSubMesh(Mesh *pMesh, CSLMesh* XSIMesh) for (size_t u = 0; u <= newDecl->getMaxSource(); ++u) bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY); sm->vertexData->reorganiseBuffers(newDecl, bufferUsages); -} +} //----------------------------------------------------------------------------- template @@ -406,15 +406,15 @@ size_t Exporter::createOrRetrieveUniqueVertex(size_t originalPositionIndex, cons //------------------------------------------------------------------------------ void Exporter::exportBones(std::string fileName) -{ +{ // Construct skeleton SkeletonPtr pSkel = SkeletonManager::getSingleton().create( fileName, ResourceGroupManager:: DEFAULT_RESOURCE_GROUP_NAME, true); - - // Recursively traverse the bone tree + + // Recursively traverse the bone tree root = false; recurseBones(pSkel.getPointer(), SceneRoot); - + // Export animations exportAnim(pSkel.getPointer(), SceneRoot); @@ -427,7 +427,7 @@ void Exporter::exportBones(std::string fileName) void Exporter::recurseBones(Skeleton* pSkel, CSLModel* XSIModel) { CSIBCVector3D vec3d; - + // A plethora of logical expressions to ensure that the root null and // its children are the only ones that will enter this if block. Eliminates // any extraneous nulls not related to the skeleton. @@ -443,7 +443,7 @@ void Exporter::recurseBones(Skeleton* pSkel, CSLModel* XSIModel) vec3d = XSIModel->Transform()->GetTranslation(); Vector3 bonePos(vec3d.GetX(), vec3d.GetY(), vec3d.GetZ()); ogreBone->setPosition(bonePos); - + // Yes, we are converting Euler angles to quaternions, at risk of gimbal lock. // This is because XSI doesn't export quaternions, except through the animation // mixer and action FCurves. It's possible to get a 3x3 Rotation matrix, which @@ -458,13 +458,13 @@ void Exporter::recurseBones(Skeleton* pSkel, CSLModel* XSIModel) qfinal = qz * qy * qx; ogreBone->setOrientation(qfinal); ++boneCount; - + if ((boneCount > 1) && (XSIModel->ParentModel()->GetPrimitiveType() == CSLTemplate::SI_NULL_OBJECT)) { pSkel->getBone(XSIModel->ParentModel()->GetName())->addChild(ogreBone); } - } - + } + CSLModel* *l_childrenList = XSIModel->GetChildrenList(); // Loop through all children @@ -481,13 +481,13 @@ void Exporter::exportAnim(Skeleton* pSkel, CSLModel* XSIModel) CSLTransform* initial; CSLTransform* keyfr = 0; CSIBCMatrix4x4 initmat, invinitmat, keyfmat, newmat; - + // Timing conversions from XSI frames to OGRE time in seconds float frameRate = XSIModel->Scene()->SceneInfo()->GetFrameRate(); float lengthInFrames = XSIModel->Scene()->SceneInfo()->GetEnd() - XSIModel->Scene()->SceneInfo()->GetStart(); float realTime = lengthInFrames / frameRate; - + // HACK: You'd want to assign the correct name to your particular animation. Animation *ogreanim = pSkel->createAnimation("Jump", realTime ); @@ -512,13 +512,13 @@ void Exporter::exportAnim(Skeleton* pSkel, CSLModel* XSIModel) CSLLinearKey* tranx = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_TRANSLATION_X)->GetLinearKeyListPtr(); CSLLinearKey* trany = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_TRANSLATION_Y)->GetLinearKeyListPtr(); CSLLinearKey* tranz = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_TRANSLATION_Z)->GetLinearKeyListPtr(); - + // Set up the bind pose matrix and take inverse initial = XSIbone->Transform(); initial->ComputeLocalMatrix(); initmat = initial->GetMatrix(); initmat.GetInverse(invinitmat); - + for (int currKeyIdx = 0; currKeyIdx < numKeys; ++currKeyIdx) { // Create keyframe @@ -532,7 +532,7 @@ void Exporter::exportAnim(Skeleton* pSkel, CSLModel* XSIModel) keyfr->SetTranslation(CSIBCVector3D(tranx[currKeyIdx].m_fValue, trany[currKeyIdx].m_fValue, tranz[currKeyIdx].m_fValue)); keyfr->ComputeLocalMatrix(); keyfmat = keyfr->GetMatrix(); - + // Inverse bind pose matrix * keyframe transformation matrix invinitmat.Multiply(keyfmat, newmat); CSIBCVector3D kfSca, kfRot, kfPos; @@ -562,7 +562,7 @@ int main(int argc, char *argv[]) std::cout << "Ex: exporter example.xsi example\n"; return (0); } - + // Ogre Singletons logMgr = new LogManager(); logMgr->createLog("XSIOgreExport"); @@ -576,10 +576,10 @@ int main(int argc, char *argv[]) std::string fn(argv[2]); std::string meshFileName = fn + ".mesh"; std::string skelFileName = fn + ".skeleton"; - + // Continue if valid dotXSI file, end gracefully if not if (Scene.Open(argv[1]) == SI_SUCCESS) - { + { Scene.Read(); Exporter * e = new Exporter(Scene.Root()); e->exportBones(skelFileName); diff --git a/Tools/rcapsdump/src/main.cpp b/Tools/rcapsdump/src/main.cpp index d88e713b6d6..37ad6c7ee7d 100644 --- a/Tools/rcapsdump/src/main.cpp +++ b/Tools/rcapsdump/src/main.cpp @@ -49,47 +49,47 @@ void help(void) void setUpGLRenderSystemOptions(Ogre::RenderSystem* rs) { - using namespace Ogre; - ConfigOptionMap options = rs->getConfigOptions(); - // set default options - // this should work on every semi-normal system - rs->setConfigOption(String("Colour Depth"), String("32")); - rs->setConfigOption(String("FSAA"), String("0")); - rs->setConfigOption(String("Full Screen"), String("No")); - rs->setConfigOption(String("VSync"), String("No")); - rs->setConfigOption(String("Video Mode"), String("800 x 600")); - - // use the best RTT - ConfigOption optionRTT = options["RTT Preferred Mode"]; - - if(find(optionRTT.possibleValues.begin(), optionRTT.possibleValues.end(), "FBO") != optionRTT.possibleValues.end()) - { - rs->setConfigOption(String("RTT Preferred Mode"), String("FBO")); - } - else if(find(optionRTT.possibleValues.begin(), optionRTT.possibleValues.end(), "PBuffer") != optionRTT.possibleValues.end()) - { - rs->setConfigOption(String("RTT Preferred Mode"), String("PBuffer")); - } - else - rs->setConfigOption(String("RTT Preferred Mode"), String("Copy")); + using namespace Ogre; + ConfigOptionMap options = rs->getConfigOptions(); + // set default options + // this should work on every semi-normal system + rs->setConfigOption(String("Colour Depth"), String("32")); + rs->setConfigOption(String("FSAA"), String("0")); + rs->setConfigOption(String("Full Screen"), String("No")); + rs->setConfigOption(String("VSync"), String("No")); + rs->setConfigOption(String("Video Mode"), String("800 x 600")); + + // use the best RTT + ConfigOption optionRTT = options["RTT Preferred Mode"]; + + if(find(optionRTT.possibleValues.begin(), optionRTT.possibleValues.end(), "FBO") != optionRTT.possibleValues.end()) + { + rs->setConfigOption(String("RTT Preferred Mode"), String("FBO")); + } + else if(find(optionRTT.possibleValues.begin(), optionRTT.possibleValues.end(), "PBuffer") != optionRTT.possibleValues.end()) + { + rs->setConfigOption(String("RTT Preferred Mode"), String("PBuffer")); + } + else + rs->setConfigOption(String("RTT Preferred Mode"), String("Copy")); } void setUpD3D9RenderSystemOptions(Ogre::RenderSystem* rs) { - using namespace Ogre; - ConfigOptionMap options = rs->getConfigOptions(); - // set default options - // this should work on every semi-normal system - rs->setConfigOption(String("Anti aliasing"), String("None")); - rs->setConfigOption(String("Full Screen"), String("No")); - rs->setConfigOption(String("VSync"), String("No")); - rs->setConfigOption(String("Video Mode"), String("800 x 600 @ 32-bit colour")); - - // pick first available device - ConfigOption optionDevice = options["Rendering Device"]; - - rs->setConfigOption(optionDevice.name, optionDevice.currentValue); + using namespace Ogre; + ConfigOptionMap options = rs->getConfigOptions(); + // set default options + // this should work on every semi-normal system + rs->setConfigOption(String("Anti aliasing"), String("None")); + rs->setConfigOption(String("Full Screen"), String("No")); + rs->setConfigOption(String("VSync"), String("No")); + rs->setConfigOption(String("Video Mode"), String("800 x 600 @ 32-bit colour")); + + // pick first available device + ConfigOption optionDevice = options["Rendering Device"]; + + rs->setConfigOption(optionDevice.name, optionDevice.currentValue); } @@ -112,9 +112,9 @@ int main(int numargs, char** args) if(rsGL) { setUpGLRenderSystemOptions(rsGL); - root->setRenderSystem(rsGL); - root->initialise(true, "OGRE rcapsdump GL Window"); - glCaps = const_cast(rsGL->getCapabilities()); + root->setRenderSystem(rsGL); + root->initialise(true, "OGRE rcapsdump GL Window"); + glCaps = const_cast(rsGL->getCapabilities()); } if(glCaps) { @@ -129,9 +129,9 @@ int main(int numargs, char** args) if(rsD3D9) { setUpD3D9RenderSystemOptions(rsD3D9); - root->setRenderSystem(rsD3D9); - root->initialise(true, "OGRE rcapsdump D3D9 Window"); - d3d9Caps = const_cast(rsD3D9->getCapabilities()); + root->setRenderSystem(rsD3D9); + root->initialise(true, "OGRE rcapsdump D3D9 Window"); + d3d9Caps = const_cast(rsD3D9->getCapabilities()); } if(d3d9Caps) {
      KeyType/ValuesDefaultDescriptionNotes
      titleAny stringRenderTarget nameThe title of the window that will appear in the title bar 
      colourDepth16, 32Desktop depthColour depth of the resulting rendering window; only applies if fullScreenWin32 Specific
      leftPositive integersCentredScreen x coordinate from left 
      topPositive integersCentredScreen y coordinate from left 
      depthBuffertrue, falsetrueUse depth bufferDirectX9 specific
      externalWindowHandleWin32: HWND as integer
      + GLX: poslong:posint:poslong (display*:screen:windowHandle) or poslong:posint:poslong:poslong (display*:screen:windowHandle:XVisualInfo*)
      OS X: WindowRef for Carbon or NSWindow for Cocoa address as an integer iOS: UIWindow address as an integer
      0 (none)External window handle, for embedding the OGRE render in an existing window 
      externalGLControltrue, falsefalseLet the external window control OpenGL i.e. don't select a pixel format for the window, - do not change v-sync and do not swap buffer. When set to true, the calling application - is responsible of OpenGL initialization and buffer swapping. It should also create an - OpenGL context for its own rendering, Ogre will create one for its use. Then the calling - application must also enable Ogre OpenGL context before calling any Ogre function and - restore its OpenGL context after these calls.OpenGL specific
      externalGLContextContext as Unsigned Long0 (create own context)Use an externally created GL contextOpenGL Specific
      parentWindowHandleWin32: HWND as integer
      - GLX: poslong:posint:poslong (display*:screen:windowHandle) or poslong:posint:poslong:poslong (display*:screen:windowHandle:XVisualInfo*)
      0 (none)Parent window handle, for embedding the OGRE in a child of an external window 
      macAPIString: "cocoa" or "carbon""carbon"Specifies the type of rendering window on the Mac Platform.0 (none)External window handle, for embedding the OGRE render in an existing window 
      externalGLControltrue, falsefalseLet the external window control OpenGL i.e. don't select a pixel format for the window, + do not change v-sync and do not swap buffer. When set to true, the calling application + is responsible of OpenGL initialization and buffer swapping. It should also create an + OpenGL context for its own rendering, Ogre will create one for its use. Then the calling + application must also enable Ogre OpenGL context before calling any Ogre function and + restore its OpenGL context after these calls.OpenGL specific
      externalGLContextContext as Unsigned Long0 (create own context)Use an externally created GL contextOpenGL Specific
      parentWindowHandleWin32: HWND as integer
      + GLX: poslong:posint:poslong (display*:screen:windowHandle) or poslong:posint:poslong:poslong (display*:screen:windowHandle:XVisualInfo*)
      0 (none)Parent window handle, for embedding the OGRE in a child of an external window 
      macAPIString: "cocoa" or "carbon""carbon"Specifies the type of rendering window on the Mac Platform. Mac OS X Specific 
      macAPICocoaUseNSViewbool "true" or "false""false"On the Mac platform the most diffused method to embed OGRE in a custom application is to use Interface Builder - and add to the interface an instance of OgreView. - The pointer to this instance is then used as "externalWindowHandle". - However, there are cases where you are NOT using Interface Builder and you get the Cocoa NSView* of an existing interface. - For example, this is happens when you want to render into a Java/AWT interface. - In short, by setting this flag to "true" the Ogre::Root::createRenderWindow interprets the "externalWindowHandle" as a NSView* - instead of an OgreView*. See OgreOSXCocoaView.h/mm. -  
      macAPICocoaUseNSViewbool "true" or "false""false"On the Mac platform the most diffused method to embed OGRE in a custom application is to use Interface Builder + and add to the interface an instance of OgreView. + The pointer to this instance is then used as "externalWindowHandle". + However, there are cases where you are NOT using Interface Builder and you get the Cocoa NSView* of an existing interface. + For example, this is happens when you want to render into a Java/AWT interface. + In short, by setting this flag to "true" the Ogre::Root::createRenderWindow interprets the "externalWindowHandle" as a NSView* + instead of an OgreView*. See OgreOSXCocoaView.h/mm. + Mac OS X Specific 
       
      contentScalingFactor Positive Float greater than 1.0 iOS Specific  
      externalViewHandle UIView pointer as an integer 
      FSAAPositive integer (usually 0, 2, 4, 8, 16)0Full screen antialiasing factor 
      FSAAHintDepends on RenderSystem and hardware. Currently supports:
      - "Quality": on systems that have an option to prefer higher AA quality over speed, use it
      BlankFull screen antialiasing hint 
      displayFrequencyRefresh rate in Hertz (e.g. 60, 75, 100)Desktop vsync rateDisplay frequency rate, for fullscreen mode 
      vsynctrue, falsefalseSynchronize buffer swaps to monitor vsync, eliminating tearing at the expense of a fixed frame rate 
      vsyncInterval1, 2, 3, 41If vsync is enabled, the minimum number of vertical blanks that should occur between renders. - For example if vsync is enabled, the refresh rate is 60 and this is set to 2, then the - frame rate will be locked at 30. 
      bordernone, fixed, resizeresizeThe type of window border (in windowed mode) 
      outerDimensionstrue, falsefalseWhether the width/height is expressed as the size of the - outer window, rather than the content area 
      useNVPerfHUDtrue, falsefalseEnable the use of nVidia NVPerfHUD 
      gammatrue, falsefalseEnable hardware conversion from linear colour space to gamma - colour space on rendering to the window. 
      enableDoubleClicktrue, falsefalseEnable the window to keep track and transmit double click messages.Win32 Specific
      FSAAPositive integer (usually 0, 2, 4, 8, 16)0Full screen antialiasing factor 
      FSAAHintDepends on RenderSystem and hardware. Currently supports:
      + "Quality": on systems that have an option to prefer higher AA quality over speed, use it
      BlankFull screen antialiasing hint 
      displayFrequencyRefresh rate in Hertz (e.g. 60, 75, 100)Desktop vsync rateDisplay frequency rate, for fullscreen mode 
      vsynctrue, falsefalseSynchronize buffer swaps to monitor vsync, eliminating tearing at the expense of a fixed frame rate 
      vsyncInterval1, 2, 3, 41If vsync is enabled, the minimum number of vertical blanks that should occur between renders. + For example if vsync is enabled, the refresh rate is 60 and this is set to 2, then the + frame rate will be locked at 30. 
      bordernone, fixed, resizeresizeThe type of window border (in windowed mode) 
      outerDimensionstrue, falsefalseWhether the width/height is expressed as the size of the + outer window, rather than the content area 
      useNVPerfHUDtrue, falsefalseEnable the use of nVidia NVPerfHUD 
      gammatrue, falsefalseEnable hardware conversion from linear colour space to gamma + colour space on rendering to the window. 
      enableDoubleClicktrue, falsefalseEnable the window to keep track and transmit double click messages.Win32 Specific